This topic is 4812 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

Recommended Posts

Hi, I am trying to load a BMP into an offscreen, DirectDraw7 surface. This is the code i'm using functions:
///Create Surface///////////////////////////////////////////////////////////
//Creats any size surface
//////////////////////////////////////////////////////////////////////////
void MercuryEngine::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_CKSRCBLT;
ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_VIDEOMEMORY;
ddsd.dwWidth = xs;
ddsd.dwHeight = ys;
ddsd.ddckCKSrcBlt.dwColorSpaceLowValue = _RGB32BIT(0,0,32,0);
ddsd.ddckCKSrcBlt.dwColorSpaceHighValue = _RGB32BIT(0,0,32,0);
lpdd->CreateSurface(&ddsd, lpSource, NULL);
}

/////DrawHBitmap/////////////////////////////////////////////////////
// Blts a bitmap to surface
////////////////////////////////////////////////////////////////////////////
void MercuryEngine::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);
}

// Creats a bitmap surface
//////////////////////////////////////////////////
void MercuryEngine::CreateBitmapSurface(LPDIRECTDRAWSURFACE7 lpSurface, char *fname, int xs, int ys)
{
HBITMAP hBitmap;

this->CreateSurface(&lpSurface, xs, ys);

this->DrawHBitmap(lpSurface, hBitmap, 0, 0, xs, ys);
DeleteObject(hBitmap);
}

LPDIRECTDRAW7 lpdd;  //version 7.0 main
DDSURFACEDESC2 ddsd; //primary surface descriptor
LPDIRECTDRAWSURFACE7 DDprimary; //DX primary surface
LPDIRECTDRAWSURFACE7 DDback; //DX BACK surface
LPDIRECTDRAWSURFACE7 DDback_sprite; //DX BACK surface
DDBLTFX ddbltfx; //blt effect
RECT dest_rect; //dest rectangle
RECT src_rect; //source rectangle
RECT clipper_rect[1] = {0,0,799,599}; //fullscrenn clipping area

LPDIRECTDRAWCLIPPER DDclipper; //DD clipper

MercuryEngine GameEngine; //Main Game engine
...
...
...
...

creat our stuff:
// create IDirectDraw interface 7.0 object and test for error
if (FAILED(DirectDrawCreateEx(NULL, (void **)&lpdd, IID_IDirectDraw7, NULL)))
Application->MessageBoxA("Error: Can't initialize DirectDraw 7","Error",MB_OK);

// set cooperation to fullscreen
lpdd->SetCooperativeLevel(Handle, DDSCL_FULLSCREEN | DDSCL_ALLOWMODEX | DDSCL_EXCLUSIVE | DDSCL_ALLOWREBOOT);

//set display mode
// 800x600x8bit color
lpdd->SetDisplayMode(800,600,32,0,0);

//M\$ says clean out our struct
memset(&ddsd,0, sizeof(ddsd));

//tell DirectX the size of ddsd
ddsd.dwSize = sizeof(ddsd);

//tell DX what valid data we will be giving it
ddsd.dwFlags = DDSD_CAPS | DDSD_BACKBUFFERCOUNT;

//backbuffer count
ddsd.dwBackBufferCount = 1;

//complex , flipable
ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE | DDSCAPS_COMPLEX | DDSCAPS_FLIP;

//now create the primary surface
if(FAILED(lpdd->CreateSurface(&ddsd,&DDprimary,NULL)))
Application->MessageBoxA("Error: Can't creat primary surface","Error", MB_OK);

ddsd.ddsCaps.dwCaps = DDSCAPS_BACKBUFFER;

//atach backbuffer
if(FAILED(DDprimary->GetAttachedSurface(&ddsd.ddsCaps, &DDback)));

//creat clipper
DDclipper = GameEngine.DDCrClipper(DDback,1,clipper_rect);

//set rect properties
dest_rect.left   = 0;
dest_rect.top    = 0;
dest_rect.right  = 799;
dest_rect.bottom = 599;

//set rect properties
src_rect.left   = 0;
src_rect.top    = 0;
src_rect.right  = 799;
src_rect.bottom = 599;


then blt:
//clean us out..
memset(&ddsd,0,sizeof(ddsd));
ddsd.dwSize = sizeof(ddsd);

//lock the surface
DDback->Lock(NULL,&ddsd,DDLOCK_SURFACEMEMORYPTR | DDLOCK_WAIT, NULL);

DDBLTFX ddbltfx;

//clean us out..
memset(&ddbltfx,0,sizeof(ddbltfx));
ddbltfx.dwSize = sizeof(ddbltfx);

//set the dwFillColor to desired color
ddbltfx.dwFillColor = clBlack;

DDback->Blt(NULL,       //ptr to des rect
NULL,       //ptr to src surface
NULL,       //ptr to src rect
DDBLT_COLORFILL | DDBLT_WAIT,   //fill and wait
&ddbltfx);  //ptr to DDBLTFX structure

DDback->Blt(&dest_rect,DDback_sprite,&src_rect,DDBLT_WAIT, NULL);

//unlock the surface
DDback->Unlock(NULL);


All i get is a flickery screen. No lvl2.bmp showing! I've posted this before, but all I got was "use D3D". Well i don't want to use it for certain reasons. So, in directdraw, what am I doing wrong? Thanks Sigma [Edited by - Coder on October 10, 2004 10:57:06 PM]

anyone?

Share on other sites
Yeah, it seems noone here cares about DirectDraw. I never manage to get an answer to DirectDraw questions here so i just have to work things out myself or search the 'net really hard to find the information i need.

Luckily for you though i think i might know whats wrong :)

I don't think Blt operations work with locked surfaces, basically you lock a surface so that you can access the surface memory and put something in it (for example to load an image or to plot pixels on the surface or whatever). So try removing the calls to Lock() and Unlock() before and after the blt and let me know how it goes :)

Share on other sites
Indeed. Replacing a half dozen lengthy loading functions with D3DXCreateTextureFromFile() is bound to decrease even the most stalwart DDraw fans.

Share on other sites
Quote:
 Original post by DarkEvilOneYeah, it seems noone here cares about DirectDraw. I never manage to get an answer to DirectDraw questions here so i just have to work things out myself or search the 'net really hard to find the information i need.Luckily for you though i think i might know whats wrong :)I don't think Blt operations work with locked surfaces, basically you lock a surface so that you can access the surface memory and put something in it (for example to load an image or to plot pixels on the surface or whatever). So try removing the calls to Lock() and Unlock() before and after the blt and let me know how it goes :)

Well, I got rid of the lock/unlock around
DDBLTFX ddbltfx; //clean us out..memset(&ddbltfx,0,sizeof(ddbltfx));ddbltfx.dwSize = sizeof(ddbltfx); //set the dwFillColor to desired color ddbltfx.dwFillColor = clBlack; //ready to blt to surfaceDDback->Blt(NULL,       //ptr to des rect                  NULL,       //ptr to src surface                  NULL,       //ptr to src rect                  DDBLT_COLORFILL | DDBLT_WAIT,   //fill and wait                  &ddbltfx);  //ptr to DDBLTFX structureDDback->Blt(&dest_rect,DDback_sprite,&src_rect,DDBLT_WAIT, NULL);

and now my color fill works, but still no bitmap!

Share on other sites
I don't have much time right now, i'm about to leave for college so i'll take a better look at your code later.

For now could you try loading the bitmap using the functions found in ddutil.h? If that makes it work then theres a problem with your bitmap loading code (sometimes it can be really hard to notice tiny differences in pieces of code that will stop things working). If it still doesn't work then it is more likely to be a problem with your drawing code.

One other thing that you could try, in your blitting code you pass &src_rect to the Blt function but the only place i see src_rect setup is in the DirectDraw initialization code where you set it to the screen dimensions. I'm not sure but DirectDraw might not like it if the source blit rectangle is bigger than the source surface or the destination blit rectangle is bigger than the source rectangle. Again i'm not 100% sure of this but it might be worth checking out :)

Share on other sites
I'll post my DirectDraw bitmap loader later...

Share on other sites
Quote:
 Original post by TelastynIndeed. Replacing a half dozen lengthy loading functions with D3DXCreateTextureFromFile() is bound to decrease even the most stalwart DDraw fans.

LOL! You just got told.

Seriously though, stop doing DirectDraw IMMEDIATELY. Now start doing Direct3D. It's faster, *easier*, and supported.

Share on other sites
It might help you understand what's failing if you check the return values from IDirectDrawSurface7::Blt.

Can the lpDDBltFx parameter be NULL or do you always have to pass a valid pointer even if your flags indicate it's not necessary for the blit?

Share on other sites
Quote:
Original post by Anonymous Poster
Quote:
 Original post by TelastynIndeed. Replacing a half dozen lengthy loading functions with D3DXCreateTextureFromFile() is bound to decrease even the most stalwart DDraw fans.

LOL! You just got told.

Seriously though, stop doing DirectDraw IMMEDIATELY. Now start doing Direct3D. It's faster, *easier*, and supported.

eh? I was not being malicious. Just making an observation. Given the tone of the OP and the shape of the code, I'd wager that D3D is unavailable to them as they're working with an existing codebase.

My appologies if it sounded malicious, I was a bit snarky due to some other posts yesterday.

Share on other sites
Thats ok. I'm learning DirectDraw because thats what my book is on. After I do my shitty 2D project, I'll upgrade to D3D, and learn that. You just have to take it one step at a time! ;) I"ll try some of the other suggestions now. If you could ppost that code Anonymous Poster, i'd be very gratful!

Share on other sites
Alright, well I threw a if() around the BLT function (the bitmap one) and its coming back saying that its failed.....

Share on other sites
What is the HRESULT being returned (in hex please) when Blt fails?

Share on other sites
erm..honestly not sure how I would get that. Anyideas how I would find that out? Everytime I put a break into my code, the app crashs. Guess DX doesn't like being broken...;)

Share on other sites
Im not so sure, but you can also query for another DirectDraw Interface. Like the interface for version 4 or 6. If you need to know how, Ill tell ya.

Share on other sites
If the function returns an HRESULT and you put an if around it, it SHOULD fail since S_OK = 0. So the function call actually is working.

To get the actual code try this:

HRESULT hr = Blt(...);
char buf[16];
sprintf(buf, "%x\n", hr);
MessageBox(NULL, buf, "HRESULT returned from Blt", MB_OK);

That should give you the error code (in hex), je croix.

Share on other sites
Hello

Well I really suggest you take a deep look at the CDX library (http://www.cdxlib.com/), it is a set of well documented and easy to follow DirectX wrapper classes and best of all, comes with FULL SOURCE CODE!. I learned a lot from it.

Hope it helps you.
Oscar

Share on other sites
Quote:
 Original post by ms291052If the function returns an HRESULT and you put an if around it, it SHOULD fail since S_OK = 0. So the function call actually is working.To get the actual code try this:HRESULT hr = Blt(...);char buf[16];sprintf(buf, "%x\n", hr);MessageBox(NULL, buf, "HRESULT returned from Blt", MB_OK);That should give you the error code (in hex), je croix.

 Got it thx for the code: 80070057 does this help?

I tried using the code from the ddutil.cpp/.h files, and *that* function comes back false. So the bitmap isn't even loading...

Share on other sites
HRESULT: 0x80070057 (2147942487)
Name: E_INVALIDARG
Description: An invalid parameter was passed to the returning function
Severity code: Failed
Facility Code: FACILITY_WIN32 (7)
Error Code: 0x0057 (87)

One or more of the parameters you're passing to Blt is wrong.

Share on other sites
1) Are you 100% sure the creation and loading of the bitmap from DDback_sprite is being loaded ok (filenames, formats, your loading code, etc ?). Check those error return codes for all DirectDraw and GDI calls!

2) As an experiment try taking DDSCAPS_VIDEOMEMORY out of your MercuryEngine::CreateSurface function.

3) Are you 100% certain that the bitmap being loaded is 800x600 and your surface is being created at that size? If it's smaller, then you could get the errors you've posted.

4) With DirectDraw (and D3D for that matter), it's a really good idea to make your application/engine work in windowed mode. In windowed mode you have easy access to the debugger window so can single step and see watches on variables etc. Get your application working first, then move to fullscreen, then fix any fullscreen issues (lost surfaces etc).

Share on other sites
Well like I said, when I try using the Bitmap load functions from ddutil.cpp/h, the bitmap isn't loaded... But i don't know why...

LPDIRECTDRAW7 lpdd;  //version 7.0 main......if(FAILED(DDback_sprite = DDLoadBitmap(lpdd,"E:\\MyDocs\\Chris\\Programing\\DirectX\\MERC Engine\\lvl2.bmp",800,600)));        {         Application->MessageBoxA("DDLoadBitmap Failed","BOOM",MB_OK);         Application->Terminate();        }

Share on other sites
You can't use the FAILED macro to test the return value of DDLoadBitmap. It isn't returning an HRESULT, it's returning an IDirectDrawSurface7*.

From ddutil.h:

IDirectDrawSurface7 *DDLoadBitmap(IDirectDraw7 *pdd, LPCSTR szBitmap, int dx, int dy);

If DDLoadBitmap were failing and return NULL, the FAILED macro would interpret this as DD_OK (which is defined as 0) and would think the call actually succeeded.

Share on other sites
OMFG! Finally got it! O.o I changed that code, but how to you test for a fail? I tried a few things, but each one kept conplaing, reporting a fail of the load. I got frustrated and made a new BMP file (the one I was using worked in other apps) and POOF! It loaded just like that. I was so choked! Thank you all for your help, I really appreciate it!

Sigma

Share on other sites

This topic is 4812 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

Create an account

Register a new account

• Forum Statistics

• Total Topics
628736
• Total Posts
2984458

• 9
• 25
• 11
• 10
• 16