Skip to main content
GameDev.net gamedev.net
🔒 Locked

Loading Bitmaps into DirectX

Started by Utwo May 19, 2003 at 10:07 PM 7 replies 1.3k views
Original Post
Utwo
Utwo
I'm about to go postal here. This has been a problem for about 2 weeks now. It's such a simple thing. You can hardly make a 2D game without doing it. Why is it so hard for me? ARRGH! Anyway, I followed this tutorial exactly. In fact, I copied and pasted the code right into my project. Everything compiles fine. The only change I had to make to the code was to cast the return value of LoadImage to an (HBITMAP). But that's it. It compiles fine. I use the code to load the bitmap into an offscreen surface and then I blit it to the screen buffer, and then flip the page. But instead of it doing what its supposed to do, when it runs I simply get a blank screen (along with all the junk that was on the back buffer. Has anyone had a similar problem with those functions? Is there something wrong with the code you see there? I'll supply the code for my program as well:
    
// INCLUDES ////////////////////////////////////////////////////////////////////



#include <windows.h>

#include <windowsx.h>

#include <initguid.h>


#include <ddraw.h>

#include "resource.h"

// DEFINES /////////////////////////////////////////////////////////////////////



#define WIN32_LEAN_AND_MEAN

#define INITGUID

// CONSTANTS & GLOBALS /////////////////////////////////////////////////////////



HWND hwnd;


LPDIRECTDRAW  lpdd  = NULL;

LPDIRECTDRAW7 lpdd7 = NULL;


LPDIRECTDRAWSURFACE7 lpddsprimary   = NULL;

LPDIRECTDRAWSURFACE7 lpddssecondary = NULL;

LPDIRECTDRAWSURFACE7 lpddstitle     = NULL;

LPDIRECTDRAWSURFACE7 lpddsmenu      = NULL;

LPDIRECTDRAWSURFACE7 lpddsgame      = NULL;








// MACROS //////////////////////////////////////////////////////////////////////



#define KEYDOWN(vk_code) ((GetAsyncKeyState(vk_code) & 0x8000) ? 1 : 0)

#define KEYUP(vk_code) ((GetAsyncKeyState(vk_code) & 0x8000) ? 0 : 1)


// PROTOTYPES //////////////////////////////////////////////////////////////////



LRESULT CALLBACK WinProc(HWND, UINT, WPARAM, LPARAM);

int Game_Init();

int Game_Shutdown();

int Game_Main();


// These functions will load a bitmap from a resource into a new offscreen surface.


void CreateBitmapSurface(LPDIRECTDRAWSURFACE7 lpSurface, char *fname, int xs, int ys);

void DrawHBitmap(IDirectDrawSurface7 *lpSurface, HBITMAP hBitmap, int x, int y, int width, int height);

void CreateSurface(LPDIRECTDRAWSURFACE7 *lpSource, int xs, int ys);




////////////////////////////////////////////////////////////////////////////////

//                              END OF HEADER                                 //

////////////////////////////////////////////////////////////////////////////////

//                                                                            //

//                              ŽŽ          ŽŽ                                //

//                                ŽŽ      ŽŽ                                  //

//                              ŽŽŽŽŽŽŽŽŽŽŽŽŽŽ                                //

//                            ŽŽŽŽ  ŽŽŽŽŽŽ  ŽŽŽŽ                              //

//                          ŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽ                            //

//                          ŽŽ  ŽŽŽŽŽŽŽŽŽŽŽŽŽŽ  ŽŽ                            //

//                          ŽŽ  ŽŽ          ŽŽ  ŽŽ                            //

//                                ŽŽŽŽ  ŽŽŽŽ                                  //

//                                                                            //

////////////////////////////////////////////////////////////////////////////////


int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd)
{

 // Structures for window class and messages


 MSG msg;
 WNDCLASSEX wndclass;
 
 
 // Define window class.

 
    wndclass.cbSize		    = sizeof(WNDCLASSEX);
    wndclass.style		    = CS_VREDRAW | CS_HREDRAW | CS_OWNDC | CS_DBLCLKS;
    wndclass.lpfnWndProc	= WinProc;
    wndclass.cbClsExtra		= 0;
    wndclass.cbWndExtra		= 0;
    wndclass.hInstance		= hInstance;
    wndclass.hIcon		    = LoadIcon(NULL, IDI_APPLICATION);
    wndclass.hCursor		= LoadCursor(NULL, IDC_ARROW);
    wndclass.hbrBackground	= (HBRUSH)GetStockObject(BLACK_BRUSH);
    wndclass.lpszMenuName	= NULL;
    wndclass.lpszClassName	= "winclass1";
    wndclass.hIconSm		= LoadIcon(NULL, IDI_APPLICATION);
    
    
    
    
    
    
    
 // Resgister class, create and show window.    

    
 if(!RegisterClassEx(&wndclass))
 {

  MessageBox(NULL, "Class registration failed.", "Error", MB_OK);

 }

 if(!(hwnd = CreateWindowEx(0, "winclass1", "Super Metris", WS_POPUP, 50, 50, 640, 480, NULL, NULL, hInstance, NULL)))
 {

  MessageBox(NULL, "Window creation failed.", "Error", MB_OK);

 }

 ShowWindow(hwnd, nShowCmd);
 
 
 
 
 
 
 
 // Initialize program, enter game loop, and shut down game

 
 Game_Init();
 
 while(1)
 {

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

   if(msg.message == WM_QUIT) { break; } // end if


   TranslateMessage(&msg);

   DispatchMessage(&msg);

  } // end if


  Game_Main();
  
 } // end while

 
 Game_Shutdown();
 
     
 return 0;            



} // end WINMAIN 

































// Callback Procedure

LRESULT CALLBACK WinProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam)
{

 switch(msg)
 {

    case WM_CLOSE : {

                   Game_Shutdown();
                   PostQuitMessage(0);

                  }

 }

 return (DefWindowProc(hwnd,msg,wparam,lparam));

}


































int Game_Init()
{

 // Create the DirectDraw object

 if(FAILED(DirectDrawCreate(NULL, &lpdd, NULL)))
 {
 
  MessageBox(NULL, "Failed to create DirectDraw object.", "Error", MB_OK);
 
 }
 
 // Use DirectDraw object to create DirectDraw7 object

 if(FAILED(lpdd->QueryInterface(IID_IDirectDraw7, (LPVOID *)&lpdd7)))
 {
 
  MessageBox(NULL, "Failed to create DirectDraw 7 object.", "Error", MB_OK);
 
 }
 
 
 
 // Release DirectDraw object

 lpdd->Release();
 lpdd = NULL;
 
 
 
 
 // Set Cooperative Level

 if(FAILED(lpdd7->SetCooperativeLevel(hwnd, DDSCL_FULLSCREEN | DDSCL_ALLOWREBOOT | DDSCL_EXCLUSIVE | DDSCL_ALLOWMODEX)))
 {
 
  MessageBox(NULL, "Failed to set cooperation level.", "Error", MB_OK); 
 
 }
 
 
 // Set Display Mode

 if(FAILED(lpdd7->SetDisplayMode(800,600,32,0,0)))
 {
 
  MessageBox(NULL, "Failed to set display mode.", "Error", MB_OK);
 
 }
 
 
 // Create Primary Surface

 DDSURFACEDESC2 ddsd;                                   // surface description

 ZeroMemory(&ddsd, sizeof(ddsd));                       // clear DDSD's memory

 ddsd.dwSize = sizeof(ddsd);                            // Size of DDSD

 ddsd.dwFlags = DDSD_CAPS | DDSD_BACKBUFFERCOUNT;       // Which flags we're specifying

 ddsd.dwBackBufferCount = 1;
 ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE | DDSCAPS_COMPLEX | 
                                DDSCAPS_FLIP;           // Make PRIMARY, COMPLEX, FLIPABLE surface

 
 if(FAILED(lpdd7->CreateSurface(&ddsd, &lpddsprimary, NULL)))
 {
 
  MessageBox(NULL, "Failed to create primary surface.", "Error", MB_OK);
 
 }
 
 
 // Get secondary surface and assign to lpddssecondary.

 
 ddsd.ddsCaps.dwCaps = DDSCAPS_BACKBUFFER;
 
 if(FAILED(lpddsprimary->GetAttachedSurface(&ddsd.ddsCaps, &lpddssecondary)))
 {
 
 MessageBox(NULL, "Failed to create secondary surface.", "Error", MB_OK); 
 
 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 CreateBitmapSurface(lpddstitle, "C:/0progproj/DirectX/utwo.bmp", 300, 300);
 
  
 RECT source;
 RECT dest;
 
 source.left   = 0;
 source.top    = 0;
 source.right  = 300;
 source.bottom = 300;
 
 dest.left   = 0;
 dest.top    = 300;
 dest.right  = 300;
 dest.bottom = 300; 
 
 
 
 lpddssecondary->Blt(&dest, lpddstitle, &source, DDBLT_WAIT, NULL);


 
 
 lpddsprimary->Flip(NULL, DDFLIP_WAIT);
 
 
 
 
}
































int Game_Shutdown()
{

 if(lpdd7)
 {
 
  lpdd7->Release();
  lpdd7 = NULL;
 
 }
 
 if(lpddsprimary)
 {

  lpddsprimary->Release();
  lpddsprimary = NULL;

 }
 
 if(lpddssecondary)
 {

  lpddssecondary->Release();
  lpddssecondary = NULL;

 }
 
 if(lpddstitle)
 {

  lpddstitle->Release();
  lpddstitle = NULL;

 }
 
 if(lpddsmenu)
 {

  lpddsmenu->Release();
  lpddsmenu = NULL;

 }
 
 if(lpddsgame)
 {

  lpddsgame->Release();
  lpddsgame = NULL;

 }
 

 return 1;

}

































int Game_Main()
{

 if(KEYDOWN(VK_UP))
 {
 
  Game_Shutdown();
  PostQuitMessage(0);
 
 }

}

































void CreateSurface(LPDIRECTDRAWSURFACE7 *lpSource, int xs, int ys) 
{ 

 DDSURFACEDESC2 ddsd; 
 ZeroMemory(&ddsd, sizeof(ddsd)); 
 ddsd.dwSize = sizeof(ddsd); 
 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT; 
 ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN; 
 ddsd.dwWidth = xs; 
 ddsd.dwHeight = ys; 

 lpdd7->CreateSurface(&ddsd, lpSource, NULL); 

} 













void DrawHBitmap(IDirectDrawSurface7 *lpSurface, HBITMAP hBitmap, int x, int y, int width, int height) 
{ 

 HDC hdcImage; 
 HDC hdc; 
 BITMAP bm; 
 
 if (lpSurface == NULL || hBitmap == NULL) return; 
 
 lpSurface->Restore(); 
 
 hdcImage = CreateCompatibleDC(NULL); 
 
 SelectObject(hdcImage, hBitmap); 
 
 GetObject(hBitmap, sizeof(bm), &bm); 
 
 width = width == 0 ? bm.bmWidth : width; 
 height = height == 0 ? bm.bmHeight : height; 
 
 lpSurface->GetDC(&hdc); 
 
 BitBlt(hdc, x, y, width, height, hdcImage, 0, 0, SRCCOPY); 
 
 lpSurface->ReleaseDC(hdc); 
 DeleteDC(hdcImage); 
 
} 











void CreateBitmapSurface(LPDIRECTDRAWSURFACE7 lpSurface, char *fname, int xs, int ys) 
{ 

 HBITMAP hBitmap; 
 
 CreateSurface(&lpSurface, xs, ys); 
 
 hBitmap = (HBITMAP)LoadImage(NULL, fname, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE); 
 
 DrawHBitmap(lpSurface, hBitmap, 0, 0, xs, ys); 
 
 DeleteObject(hBitmap); 
 
} 
    
[edited by - utwo on May 19, 2003 11:08:23 PM]
---signature---" Actually, at the time, I didn't give a damn about the FoxNews issue... just that you would come swooping in with your Super Mith cape flapping behind you and debunk it just because it didn't happen in your living room." - InnocuousFox
Doolwind
Doolwind
I can''t copy your code and run it myself as there are no line breaks, can you give a link to the file possibly??

From what I can tell your game main isn''t doing anything, try sticking your blt and flip into the game main rather than init method.

Doolwind
Utwo
Utwo
Here''s the code.

Sorry about the line breaks. Let me know if you need any more information.

I tried putting the blit and the flip in Game_Main, and it does the same thing. Actually, since Game_Main is inside the main game loop, it now does it a bazillion times a second.

Thanks for taking to time to help, even if you won''t be able to figure it out.
---signature---" Actually, at the time, I didn't give a damn about the FoxNews issue... just that you would come swooping in with your Super Mith cape flapping behind you and debunk it just because it didn't happen in your living room." - InnocuousFox
Doolwind
Doolwind
ok, for starters, your blt is failing. Have a look into why this is happening and I''ll have a look for a bit too, I have an asp.net assignment due though so I can''t spend too much time sorry.

Doolwind
Doolwind
Doolwind
And the error from the blt is:
DDERR_INVALIDPARAMS

Change the fourth param to:
(DDBLT_WAIT | DDBLT_KEYSRC)

This will stop that error, but the image is still not displayed....

I am not sure if I am getting those error because I am running DX8 or not, but have a look at that anyway.

The other thing is your destination rect, should it be

dest.left = 0;
dest.top = 300;
dest.right = 300;
dest.bottom = 600;

rather than dest.botto = 300;??

Doolwind
Utwo
Utwo
Yes, you''re right about the destination rect. I actually had .top as 0 and .bottom as 300, and got the same result. I later changed the .top to 300 for God knows what reason. I can''t remember.

I changed the fourth parameter as you said and it''s still not working. Thanks for helping with what you could. I don''t want to cut into your assignment time any more.
---signature---" Actually, at the time, I didn't give a damn about the FoxNews issue... just that you would come swooping in with your Super Mith cape flapping behind you and debunk it just because it didn't happen in your living room." - InnocuousFox
Utwo
Utwo
May I ask how you checked for the error, exactly? I know that you can store the result in an HRESULT, but how do I display it on the screen?
---signature---" Actually, at the time, I didn't give a damn about the FoxNews issue... just that you would come swooping in with your Super Mith cape flapping behind you and debunk it just because it didn't happen in your living room." - InnocuousFox
Doolwind
Doolwind
That was a slow process. All I did was put a switch statement on the HRESULT and check it against all the possibile values.

Doolwind
Aface
Aface
There is a function to get the error string automatically

D3DXGetErrorString

the ddraw one is

DXGetErrorString8

look it up, as it is much easier than having to switch.

aface





edit -> added the dx8 version

[edited by - aface on May 20, 2003 7:07:54 PM]

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.