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

Surface copy to backbuffer?

Started by DragonGeo2 Sep 10, 2006 at 6:36 PM 9 replies 5k views
Original Post
DragonGeo2
DragonGeo2
I've run into a little snag in my program. When I create a surface in memory, and put the image I want into that surface, and export that surface to a file, the surface works fine. The problem is, when I try to copy the surface onto the backbuffer, and flip the backbuffer to the screen, nothing is rendered. Can someone help me here? I'm almost positive I just made a simple mistake.

// This is the surface I want to draw onto the backbuffer
LPDIRECT3DSURFACE9 TheSurface;

// We use Direct3D to create the surface in memory...
D3D_Device->CreateOffscreenPlainSurface(g_Width, g_Height, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &TheSurface, NULL);

// We make a locked rect so we can lock the surface and write to it
D3DLOCKED_RECT TheLockedRect;

// We lock the surface
TheSurface->LockRect(&TheLockedRect, NULL, NULL);

// We write to the surface using the data generated in the previous (not shown here) function
memcpy(TheLockedRect.pBits, PixelGrid, g_Width * g_Height * sizeof(Pixel));

// We unlock the surface
TheSurface->UnlockRect();

// We save the surface to a file - Note: I know that everything up to this point was successful, because the file output looks correct
D3DXSaveSurfaceToFile("Surface.bmp", D3DXIFF_BMP, TheSurface, NULL, NULL);

// Now we're going to draw the surface onto the backbuffer
D3D_Device->BeginScene();
D3D_Device->Clear(0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0,0,0), 1.0f, 0);

// We have the backbuffer surface...
LPDIRECT3DSURFACE9 Backbuffer;

// We get the back buffer surface
D3D_Device->GetBackBuffer(0, 0, D3DBACKBUFFER_TYPE_MONO, &Backbuffer);

// We update the back buffer data with the data from the other surface
D3D_Device->UpdateSurface(TheSurface, NULL, Backbuffer, NULL);

// We flip the back buffer onto the screen
D3D_Device->Present(NULL, NULL, NULL, NULL);

// Scene is over - I SHOULD see the flipped backbuffer, but I don't
D3D_Device->EndScene();

DragonGeo2
DragonGeo2
Hmmm, alright, if nobody can help me with my specific program example, could someone then please post a tutorial or sample program that demonstrates surface to backbuffer copying?
Scet
Scet
Present should come after EndScene. Plus I don't understand why you're doing this, there are much better ways of displaying things then copying directly to the backbuffer.
Goku17c
Goku17c
What you need to do is look into the direct x sprite interface. You load pictures in as textures, and trasnform them, and draw them that way.

Take a gander into that and all your problems will be solved.

Also, the begin scene and end scene come before and after respectively, and present is after everything.



//example
//these would be only done once
IDirect3DTexture9 *Tex;
HR(D3DXCreateTextureFromFile(gd3dDevice, "BitMapName.bmp", /*texture*/&Tex));


//These would be done inside the loop somewere
// Clear the backbuffer and depth buffer.
HR(gd3dDevice->Clear(0, 0, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0));

// Turn on the alpha test.
HR(gd3dDevice->SetRenderState(D3DRS_ALPHATESTENABLE, true));

// Set gc orientation.
D3DXMATRIX R;

D3DXMatrixRotationY(&R, 0.0f);

HR(Sprite->SetTransform(&R));

HR(Sprite->Draw(Tex, &gcRECT, &gcCenter, &gcPos, D3DCOLOR_XRGB(255, 255, 255)));

HR(Sprite->Flush());

// Turn off the alpha test.
HR(gd3dDevice->SetRenderState(D3DRS_ALPHATESTENABLE, false));



Any questions?
Adam Hamilton
Adam Hamilton
Quote:
Original post by Scet
Present should come after EndScene. Plus I don't understand why you're doing this, there are much better ways of displaying things then copying directly to the backbuffer.


True that Present should come after an EndScene but the last time I checked, this is a beginners forum and being that DragonGeo2 is most probably a beginner, he/she is using this method to display a background image on his/her back buffer.
DragonGeo2
DragonGeo2
Quote:
Original post by Adam Hamilton
Quote:
Original post by Scet
Present should come after EndScene. Plus I don't understand why you're doing this, there are much better ways of displaying things then copying directly to the backbuffer.


True that Present should come after an EndScene but the last time I checked, this is a beginners forum and being that DragonGeo2 is most probably a beginner, he/she is using this method to display a background image on his/her back buffer.


Yes I am, and right now, my backbuffer appears to be blank (do I have to lock and unlock the backbuffer when using UpdateSurface() ?) I'm not sure why, but could somebody help me here?
Adam Hamilton
Adam Hamilton
As Scet pointed out in his earlier post. You need to Present the scene after the call to EndScene() like this

// Now we're going to draw the surface onto the backbufferD3D_Device->BeginScene();D3D_Device->Clear(0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0,0,0), 1.0f, 0);// We have the backbuffer surface...LPDIRECT3DSURFACE9 Backbuffer;// We get the back buffer surfaceD3D_Device->GetBackBuffer(0, 0, D3DBACKBUFFER_TYPE_MONO, &Backbuffer);// We update the back buffer data with the data from the other surfaceD3D_Device->UpdateSurface(TheSurface, NULL, Backbuffer, NULL);////////////////////////////// Here is the change.////// First EndScene()/// Second Present()// Scene is over - I SHOULD see the flipped backbuffer, but I don'tD3D_Device->EndScene();// We flip the back buffer onto the screenD3D_Device->Present(NULL, NULL, NULL, NULL);

Scet
Scet
Quote:
Original post by Adam Hamilton
last time I checked, this is a beginners forum and being that DragonGeo2 is most probably a beginner, he/she is using this method to display a background image on his/her back buffer.


Yeah I know what he's trying to do, but I don't see anything wrong with recommending a better method. Copying surfaces to the backbuffer may have worked in DirectDraw, but it isn't considered the "proper" way of doing things in Direct3D. He should be using textures and the sprite interface/textured quads to display images, like in Goku17c's example.
Adam Hamilton
Adam Hamilton
So tell me what happens when you want to load in an 800x600 image when your video card can't support power of 2 sized textures?
Scet
Scet
Quote:
Original post by Adam Hamilton
So tell me what happens when you want to load in an 800x600 image when your video card can't support power of 2 sized textures?


1) Buy a video card that isn't 6 years old.

2) Turn image filtering off so that the image is padded, not stretched. Then tell the sprite interface to only draw the area from (0,0) to (800,600).

Edit: Forgot to add that with the sprite interface/textured quads you get hardware scaling, rotation, translation, blending and recoloring. Try doing that with plain old surface copying.

[Edited by - Scet on September 12, 2006 8:07:50 PM]
Adam Hamilton
Adam Hamilton
But why would I want stretching, rotation, etc. for a simple background?

Look my my point is is that you can do it either way. There isn't a "non-proper" way to do it (unless you do it wrong [smile]). If I had a completely different graphic file format for example then no D3DX interface function will be able to decode my own format and I would be forced to use the lock/copy/unlock method so would you be saying that using a custom format is not considered proper?

I'm sorry if I'm being really picky about this but you can't just say that something isn't "proper" cause you are not using a method implemented by D3DX.

For example, DirectX provides a Vector and Matrix class but I'm sure you're not going to tell everyone that it isn't "proper" to use their own implementation of a vector and matrix.

Regarding the buying of newer video cards, I don't think that newer cards would support any sized textures for the reason that their access would be slower than powers of 2 sized textures and I don't see them supporting two because you can jam pack a 2^n texture with lots of texture and waste very little memory so I think vendors would be mad to support any sized textures. (However this is me thinking that there is a surface dedicated to textures and a general purpose surface but I could be really wrong and that all surfaces are created with a 2^n size)

Topic Locked

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

Sign in to reply to this topic.