Stratos: Punto de Encuentro de Desarrolladores

¡Bienvenido a Stratos!

Acceder

Foros





Pregunta Tonta DirectDraw

Iniciado por SrDurden, 20 de Junio de 2003, 07:16:07 PM

« anterior - próximo »

SrDurden

                                Hola!

Estoy empezando a programar en DirectDraw con el Tutorial Game Programming Genesis, y tengo una duda:

Cuando cargas un bitmap en pantalla, o pones un pixel por pantalla, es normal que desaparezca de immediato?

Es que si no lo pongo en el bucle principal (con lo que me realiza la operación de carga de un bitmap todo el rato) no me da tiempo ni a verlo..

En teoría no tendrían que quedar escritos en pantalla?

Pongo el código por si puede ayudar en algo, a lo mejor es que me he equivocado en alguna cosa  :oops:

Si véis alguna cosa mal o que no esté demasiado bien, por favor, no dudéis en decirmelo!  :ojo:



.

.

.

DDSURFACEDESC2 ddsd;

LPDIRECTDRAWSURFACE7 lpddsPrimary=NULL;



INIT_DXSTRUCT(ddsd);



ddsd.dwFlags=DDSD_CAPS | DDSD_BACKBUFFERCOUNT;

ddsd.dwBackBufferCount=1;

ddsd.ddsCaps.dwCaps=DDSCAPS_PRIMARYSURFACE |

     DDSCAPS_COMPLEX |

     DDSCAPS_FLIP |

     DDSCAPS_VIDEOMEMORY;

   



if (FAILED(lpdd->CreateSurface(&ddsd,&lpddsPrimary,NULL)))

{

  MessageBox(hwnd, "ERROR CODE CSURFACE 1",

  "Creando Surface.", MB_YESNO | MB_ICONQUESTION |

  MB_DEFBUTTON2);

  ReleaseLpdd(lpdd);

  return(0);

}





  LPDIRECTDRAWSURFACE7 lpddsBack = NULL;



  ddsd.ddsCaps.dwCaps= DDSCAPS_BACKBUFFER;



if (FAILED(lpddsPrimary->GetAttachedSurface(&ddsd.ddsCaps,&lpddsBack)))

   {

  MessageBox(hwnd, "ERROR CODE GASURFACE PRIMARY 1",

  "Get Attached Error.", MB_YESNO | MB_ICONQUESTION |

  MB_DEFBUTTON2);

  ReleaseLpdd(lpdd);

  return(0);

}



   

// En casa utilizo el modo 555!!!







while(1)

{

 

 if (PeekMessage(&msg,NULL,0,0,PM_REMOVE))

 {

  if (msg.message == WM_QUIT) break;

  TranslateMessage(&msg);

  DispatchMessage(&msg);

 }



 if (KEYSTATE(VK_ESCAPE)) PostMessage(hwnd, WM_CLOSE, 0, 0);



 LoadBitmapResource(lpddsPrimary,15,15,0);

}



   ReleaseLpdd(lpdd);



   



return(msg.wParam);

}



void ReleaseLpdd(LPDIRECTDRAW7 &lpdd)

{

lpdd->Release();

lpdd=NULL;

}



inline void PlotPixel16(int x, int y, USHORT color, USHORT* buffer, int nPitch)

{

buffer[y*nPitch + x] = color;

}



int LoadBitmapResource(LPDIRECTDRAWSURFACE7 lpdds, int xDest, int yDest, int nResID)

{

 HDC hSrcDC;           // source DC - memory device context

 HDC hDestDC;          // destination DC - surface device context

 HBITMAP hbitmap;      // handle to the bitmap resource

 BITMAP bmp;           // structure for bitmap info

 int nHeight, nWidth;  // bitmap dimensions



 // first load the bitmap resource

 if ((hbitmap = (HBITMAP)LoadImage(hInstance, "damaris.bmp",

                                   IMAGE_BITMAP, 0, 0,

                                   LR_CREATEDIBSECTION | LR_LOADFROMFILE)) == NULL)

   return(FALSE);



 // create a DC for the bitmap to use

 if ((hSrcDC = CreateCompatibleDC(NULL)) == NULL)

   return(FALSE);



 // select the bitmap into the DC

 if (SelectObject(hSrcDC, hbitmap) == NULL)

 {

   DeleteDC(hSrcDC);

   return(FALSE);

 }



 // get image dimensions

 if (GetObject(hbitmap, sizeof(BITMAP), &bmp) == 0)

 {

   DeleteDC(hSrcDC);

   return(FALSE);

 }



 nWidth = bmp.bmWidth;

 nHeight = bmp.bmHeight;



 // retrieve surface DC

 if (FAILED(lpdds->GetDC(&hDestDC)))

 {

   DeleteDC(hSrcDC);

   return(FALSE);

 }



 // copy image from one DC to the other

 if (BitBlt(hDestDC, xDest, yDest, nWidth, nHeight, hSrcDC, 0, 0,

            SRCCOPY) == NULL)

 {

   lpdds->ReleaseDC(hDestDC);

   DeleteDC(hSrcDC);

   return(FALSE);

 }



 // kill the device contexts

 lpdds->ReleaseDC(hDestDC);

 DeleteDC(hSrcDC);



 // return success

 return(TRUE);

}



La función LoadBitmapResource la he modificado un pelín (simplemente he cambiado la funcion LoadImage) para que me cargue una imagen del disco duro y no una imagen del resource.

Saludotes y muchas gracias,

SrDurden 8)                                

SrDurden

                                Ui, simplemente era que lo tenía que poner dentro del bucle de mensajes, no?

Es que acabo de añadir unas cositas para que se mueva la foto por pantalla, y al moverla quedaba el "rastro" de la imagen.

Pero ahora tengo otra pregunta: Porqué al cabo de un rato de haber estado moviendo la imagen ya no me ha dejado moverla más?

No elimino memoría por alguna parte?
Y que pasa si no la elimino? Que pasa tb si al salir del programa no hago los releases?

En teoría se quedaría la zona de memoria reservada, pero al cerrar el ordenador esta zona se liberaría, no?
Supongo que lo único que puede pasar es que el ordenador al salir vaya más lento pq disponga de menos memoría  :ojo:

El código que he añadido es este:



while(1)

{

 

 if (PeekMessage(&msg,NULL,0,0,PM_REMOVE))

 {

  if (msg.message == WM_QUIT) break;

  TranslateMessage(&msg);

  DispatchMessage(&msg);

 }



 if (KEYSTATE(VK_ESCAPE)) PostMessage(hwnd, WM_CLOSE, 0, 0);

 if (KEYSTATE(VK_UP)) fotoy=fotoy-2;

 if (KEYSTATE(VK_DOWN)) fotoy=fotoy+2;

 if (KEYSTATE(VK_RIGHT)) fotox=fotox+2;

 if (KEYSTATE(VK_LEFT)) fotox=fotox-2;



 LoadBitmapResource(lpddsPrimary,fotox,fotoy,0);

}



Y otra pregunta.. ¿Por qué al salir del programa me aparece la ventana del Visual C++ 6.0 sin maximizar, cuando está maximizada? Tengo que apretar a minimizar y luego otra vez a maximizar para que se quede normal..
Es por algo que hago o es por culpa de razones ocultas típicas de windows?  8O

Muchas gracias,

SrDurden 8)                                

HgH

                               

while(1)

{

 

 if (PeekMessage(&msg,NULL,0,0,PM_REMOVE))

 {

  if (msg.message == WM_QUIT) break;

  TranslateMessage(&msg);

  DispatchMessage(&msg);

 }



 if (KEYSTATE(VK_ESCAPE)) PostMessage(hwnd, WM_CLOSE, 0, 0);

 if (KEYSTATE(VK_UP)) fotoy=fotoy-2;

 if (KEYSTATE(VK_DOWN)) fotoy=fotoy+2;

 if (KEYSTATE(VK_RIGHT)) fotox=fotox+2;

 if (KEYSTATE(VK_LEFT)) fotox=fotox-2;



 LoadBitmapResource(lpddsPrimary,fotox,fotoy,0);

}



SrDurden, estás haciendo una carga de un bitmap por cada vuelta de bucle, lo que posiblemente, al rato de estar funcionando te vas a quedar sin memoria. No necesitas cargarlo cada vez que lo vayas a dibujar.
Cárgalo (con LoadImage) sólo una vez, antes de entrar en el bucle de mensajes.
Dentro del bucle, dibujalo en pantalla (BitBlt).
Cuando salgas del bucle, deberás hacer un DeleteObject para liberar los recursos que consume el LoadImage.

Por otra parte... ¿por que mezclas GDI con DirectX?

Saludetes                                
gH _ TLOTB
..................
"No queremos estar obligados, por nada ni nadie, a pensar sólo en lo que es más comercial. Siempre seremos, antes que nada, programadores"

- Equipo de Zigurat -

Loover

                                Y a tu pregunta de que pasa sino haces el realese al salir... pues que el SO al matar el proceso liberará toda la memoria que este consumía, con lo que el resultado es el mismo. Pero es recomendable que aún así los pongas, por dos cosas: porque queda mejor y porque es una buena costumbre a la hora de evitar memory leaks en otras partes del código.                                
IndieLib Libreria 2.5d utilizando aceleración por hardware para la programación de juegos 2d.
Indie Rover The monkeys are reading!

SrDurden

                                Hola!

Muchas gracias por contestar ;P

Por otra parte... ¿por que mezclas GDI con DirectX?


Ah, pero hay otra manera?  :oops:

Es que estoy en el capítulo 6 del Genesis y están mezclando DirectX con GDI.. Entonces hay alguna manera de cargar un bitmap con DirectDraw? Como?

Jejeje, lo de cargar la foto a cada vuelta del bucle es verdad, es que pensaba que al hacer el ReleaseDC y los DeleteDC ya lo eliminaba todo y solo quedaba la foto en pantalla..

Por otro lado,

memory leaks

Memory leaks es falta de memoria, no? Hay alguna manera de saber los objetos creados en memoria dinamica, los que he eliminado, los que faltan por eliminar, etc.. etc.. ?

Muchas gracias,

SrDurden 8)                                

HgH

                               
CitarHola!
Muchas gracias por contestar ;P
De nada hombre. :D
Citar
Por otra parte... ¿por que mezclas GDI con DirectX?
Ah, pero hay otra manera?  :oops:  
Desde luego. Si no recuerdo mal (hace ya algún tiempo que no uso Dx7), para directdraw, hay un método llamado BltFast (o FastBlt), que era para copiar surfaces. Lo que no recuerdo si el método colgaba del objeto Surface.

Citar
Es que estoy en el capítulo 6 del Genesis y están mezclando DirectX con GDI.. Entonces hay alguna manera de cargar un bitmap con DirectDraw? Como?
Mira en la ayuda del SDK, a ver si entonces existían funciones tal como D3DXLoadSurfaceFromFile, D3DXLoadSurfaceFromResource, etc (a lo mejor los nombres pueden haber cambiado)

Citar
Memory leaks es falta de memoria, no? Hay alguna manera de saber los objetos creados en memoria dinamica, los que he eliminado, los que faltan por eliminar, etc.. etc.. ?
Memory Leaks, son cachos de memoria sin liberar, pero que no son usables al estar reservados por otro proceso. Esto es lo que se produce al no liberar correctamente los recursos que reservas.

Lo mejor que puedes hacer para evitar todo esto, es hacerte tu propio manager de memoria. Manten tu una lista de la memoria que has reservado, la que te falta por liberar, etc...  Busca por ahí "Memory management"

Citar
Muchas gracias,
Muchas de nadas ;)

Saludillos                                
gH _ TLOTB
..................
"No queremos estar obligados, por nada ni nadie, a pensar sólo en lo que es más comercial. Siempre seremos, antes que nada, programadores"

- Equipo de Zigurat -






Stratos es un servicio gratuito, cuyos costes se cubren en parte con la publicidad.
Por favor, desactiva el bloqueador de anuncios en esta web para ayudar a que siga adelante.
Muchísimas gracias.