• Martes 16 de Abril de 2024, 21:05

Autor Tema:  Doble Buffer No Me Funciona  (Leído 2352 veces)

zeroz

  • Nuevo Miembro
  • *
  • Mensajes: 2
    • Ver Perfil
Doble Buffer No Me Funciona
« en: Lunes 9 de Junio de 2008, 11:39 »
0
hola, estoy empezando con unos tutoriales del api de windows para luego adentrarme en  las directx o winapi + c++, bueno pues en un ajercicio tengo que cargar una imagen y que siempre este en el centro aunque la pantalla cambie de tamaño, todo va bien menos el doble buffering que no consigo implementarlo, alguien sabe donde esta el error?

Código: Text
  1.  
  2. case WM_SIZE:
  3.          GetClientRect(hwnd, &coords);
  4.  
  5.          InvalidateRect(hwnd, NULL, FALSE);
  6.          break;
  7.       case WM_PAINT:
  8.          hBitmap = (HBITMAP)LoadImage(NULL, fn, IMAGE_BITMAP, ancho, alto, LR_LOADFROMFILE); //carga el bmp desde el disco
  9.          if( hBitmap == NULL )
  10.             return FALSE;
  11.                
  12.          xCenter = ((coords.right - coords.left)/2) - (bm.bmWidth/2);
  13.          yCenter = ((coords.bottom - coords.top)/2) - (bm.bmHeight/2);
  14.          hdc = BeginPaint( hwnd, &ps );  
  15.  
  16.          GetObject(hBitmap, sizeof(BITMAP), &bm);
  17.  
  18.          memDC = CreateCompatibleDC(hdc);
  19.          hBitmapBuffer = CreateCompatibleBitmap(hdc, bm.bmWidth, bm.bmHeight);
  20.  
  21.          hBitmapOld = SelectObject( memDC, hBitmapBuffer );
  22.  
  23.  
  24.          BitBlt( hdc, xCenter, yCenter, bm.bmWidth, bm.bmHeight, memDC, 0, 0, SRCCOPY );
  25.  
  26.          SelectObject( memDC, hBitmapOld );
  27.          DeleteObject( hBitmap );
  28.          EndPaint( hwnd, &ps );
  29.          DeleteObject(memDC);
  30.  
  31.          break;
  32.  
  33.  

BlackWind

  • Miembro activo
  • **
  • Mensajes: 89
    • Ver Perfil
Re: Doble Buffer No Me Funciona
« Respuesta #1 en: Sábado 14 de Junio de 2008, 19:41 »
0
el error es que porque no estas implementando el double buffering en realidad.

Solo veo que llames una vez a tu funcion de dibujo (bitblt), pero no dibujas el backbuffer al frontbuffer, es decir, te hace falta otro llamado al bitblt con el nuevo buffer.

No tengo un buen manejo de la api de win32 (prefiero allegro o sdl jeje), pero recuerda que el double buffering consiste en crear 2 buffers:
Un "backbuffer" donde dibujaras ahi todo PRIMERO.
Y luego un front buffer, donde dibujaras todo lo del backbuffer.

Si quieres seguir con esto, te recomiendo ampliamente que entres a www.gametutorials.com, donde tambien tienen tutoriales de win32 enfocados al gamedev.

saludos,

zeroz

  • Nuevo Miembro
  • *
  • Mensajes: 2
    • Ver Perfil
Re: Doble Buffer No Me Funciona
« Respuesta #2 en: Viernes 27 de Junio de 2008, 10:35 »
0
Bueno, he avanzado bastante, creo que ya si que tengo implementado el doble buffer y paso la imagen a memoria y de memoria al DC de pantalla, bueno o eso es lo que intento porque aunque me muestra la imagen, no me la centra con el stretchblt en la funcion RepintarImagen(), y ademas cuando expando la ventana se ve en negro casi todo:
Código: Text
  1.  
  2. LRESULT CALLBACK WindowFunc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
  3. {
  4.    OPENFILENAME fname;
  5.    char filename[64];
  6.    static RECT rect;
  7.  
  8.    switch(message) {
  9.       case WM_SIZE:
  10.          {
  11.  
  12.          GetClientRect(hwnd, &rect);
  13.          coords.cx = LOWORD(lParam);
  14.          coords.cy = HIWORD(lParam);
  15.  
  16.          if(hBitmap){
  17.             if (memDC) {
  18.                SelectObject(memDC, memBitmapOld);
  19.                DeleteObject(memBitmap);
  20.                DeleteDC(memDC);
  21.             }
  22.  
  23.             tempDC = GetDC(hwnd);
  24.             memDC = CreateCompatibleDC(tempDC);
  25.             memBitmap = CreateCompatibleBitmap(tempDC, coords.cx, coords.cy);
  26.             SelectObject(memDC, memBitmap); //si pongo hbitmap la pantalla no se pone negra
  27.             ReleaseDC(hwnd, hdc);
  28.  
  29.             RepintarImagen(hwnd);
  30.             }
  31.          break;
  32.          }
  33.       case WM_PAINT:
  34.          hdc = BeginPaint(hwnd, &ps);
  35.          BitBlt(hdc, 0, 0, coords.cx, coords.cy, memDC, rect.left , rect.top, SRCCOPY); //@@@ mejorar repintando solo el area invalidada
  36.          EndPaint(hwnd, &ps);
  37.          break;
  38.       case WM_COMMAND:
  39.          switch(LOWORD(wParam)) {
  40.             case IDM_OPEN:
  41.  
  42.                memset(&fname, 0, sizeof(OPENFILENAME));
  43.                fname.lStructSize = sizeof(OPENFILENAME);
  44.                fname.hwndOwner = hwnd;
  45.                fname.lpstrFilter = ("Bitmap Files (*.bmp)*.bmp");
  46.                fname.nFilterIndex = 1;
  47.                fname.lpstrFile = fn;
  48.                fname.nMaxFile = sizeof(fn);
  49.                fname.lpstrFileTitle = filename;
  50.                fname.nMaxFileTitle = sizeof(filename)-1;
  51.                fname.Flags = OFN_FILEMUSTEXIST | OFN_HIDEREADONLY;
  52.  
  53.                if(!GetOpenFileName(&fname))
  54.                   break;
  55.  
  56.                hBitmap = (HBITMAP)LoadImage(NULL, fn, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE);
  57.                GetObject(hBitmap, sizeof(BITMAP), &bm);
  58.  
  59.                RECT rect;
  60.                GetClientRect(hwnd, &rect);
  61.  
  62.                hdc = GetDC(hwnd);
  63.                memDC = CreateCompatibleDC(hdc);
  64.                SelectObject(memDC, hBitmap);
  65.                ReleaseDC(hwnd, hdc);      
  66.  
  67.                RepintarImagen(hwnd);
  68.                InvalidateRect(hwnd, &rect, TRUE);
  69.                break;
  70.          }
  71.          break;
  72.                      /*
  73.       case WM_ERASEBKGND:
  74.          return 1; */
  75.       case WM_DESTROY: //terminar el programa
  76.          if (memDC) {
  77.             SelectObject(memDC, memBitmapOld);
  78.             DeleteObject(memBitmap);
  79.             DeleteDC(memDC);
  80.          }
  81.          if (hBitmap)
  82.             DeleteObject(hBitmap);
  83.          PostQuitMessage(0);
  84.          break;
  85.  
  86.       default:
  87.          return DefWindowProc(hwnd, message, wParam, lParam);
  88.    }
  89.    return 0;
  90. }
  91.  
  92. /******************************************************************************
  93. Método: RepintarImagen
  94. Función: Actualiza el memDC con la imagen cargada, teniendo en cuenta que la imagen
  95.          debe estar centrada en la ventana.
  96.          Tambien se tiene en cuenta el scroll y el zoom.
  97. ******************************************************************************/
  98. void RepintarImagen(HWND hwnd){
  99.    HDC tempDC;
  100.    HBITMAP tempBitmapOrig;
  101.    if((bm.bmWidth > (coords.cx)) && (bm.bmHeight > (coords.cy))){
  102.       xCenter = (bm.bmWidth/2) - (coords.cx/2);
  103.       yCenter = (bm.bmHeight/2) - (coords.cy/2);
  104.    }else{
  105.       xCenter = (coords.cx/2) - (bm.bmWidth/2);
  106.       yCenter = (coords.cy/2) - (bm.bmHeight/2);
  107.    }
  108.  
  109.    tempDC = GetDC(hwnd);
  110.    tempBitmapOrig = SelectObject(tempDC, hBitmap);
  111.    StretchBlt(memDC, xCenter, yCenter, coords.cx, coords.cy, tempDC, 0,0, coords.cx, coords.cy,SRCCOPY);
  112.    SelectObject(tempDC, tempBitmapOrig);
  113.    ReleaseDC(hwnd,tempDC);
  114. }
  115.  
  116.