Re: Direct3D Surface Question
- From: Eyal Teler <et@xxxxxxxxxxxxxxx>
- Date: Tue, 13 Dec 2005 23:43:32 +0200
Yes, BeginScene/EndScene are simply needed.
D3DPRESENTFLAG_LOCKABLE_BACKBUFFER is not needed, since you're not locking the back buffer, but your own offscreen buffer which you then copy to it. (Which I think is better, since it allows the card to arrange the back buffer the way it wants.)
As for timing, just time the rendering yourself and see if it's fast enough. As I said, I think that current CPUs and GPUs should be up to the task. But you'll have to check that with the hardware you're aiming for.
One more thing you might want to change is filling the memory before the lock and not during it. It's generally a good practice to do most work outside the lock.
Eyal
Bryan Parkoff wrote:
Eyal,
It is almost done. I have revised my source code. You claim that it is slow to allocate and deallocate Pixels and BackBuffer. I have moved them into Initialize() and Terminate() functions. Please explain what BeginScene() and EndScene() functions are for. Is it like to lock for rendering before it starts to execute Present(...) function? LockRect(...) function is needed to stay in Run() function to work by updating pixel by pixel before UpdateSurface(...) function is executed to display the screen.
You said that Direct3D has 60fps, but Run() function should be executed 60 times per second in real timing for TV game. It has emulated 6502 CPU. It needs to count 17030 video cycles. Run() function detects if it is greater than 17030 video cycles, then Run() function is executed to update the change of pixel by pixel to the screen. 17030 times 60 vertical Hz to be equal approximately 1 MHz of CPU timing.
Do you think that Run() function is perfect for satisfied performance? If I try to remove BeginScene() and EndScene() function, the result is still the same because there is only one UpdateSurface(...) function.
Can you please verify to see if D3DPRESENT_PARAMETERS D3D_PP has correct configuration? Please make sure if "D3D_PP.Flags = D3DPRESENTFLAG_LOCKABLE_BACKBUFFER" is correct. If it is all correct, I want to say thank you very much for helping. I appreciate to share with you. Here is my source code below.
DWORD* Pixels = NULL; LPDIRECT3D9 D3D = NULL; LPDIRECT3DDEVICE9 D3D_Device = NULL; LPDIRECT3DSURFACE9 FrontBuffer = NULL; LPDIRECT3DSURFACE9 BackBuffer = NULL;
unsigned char Color_Select = 0x80;
HRESULT Initialize(HWND hWnd) { D3D = Direct3DCreate9(D3D_SDK_VERSION);
if (D3D == NULL) { MessageBox(hWnd, "Error initializing Direct3D", "Error", MB_OK); return E_FAIL; }
UINT AdapterModeCount = D3D->GetAdapterModeCount(D3DADAPTER_DEFAULT, D3DFMT_X8R8G8B8);
D3DDISPLAYMODE Mode; ZeroMemory(&Mode, sizeof(Mode));
for (UINT Count = 0; Count < AdapterModeCount; ++Count)
{
D3D->EnumAdapterModes(D3DADAPTER_DEFAULT, D3DFMT_X8R8G8B8, Count, &Mode);
if ((Mode.Width == 640) && (Mode.Height == 480) && (Mode.RefreshRate == 60))
break;
}
if ((Mode.Width != 640) || (Mode.Height != 480) || (Mode.RefreshRate != 60))
return E_FAIL;
D3DPRESENT_PARAMETERS D3D_PP; ZeroMemory(&D3D_PP, sizeof(D3D_PP));
D3D_PP.BackBufferWidth = Mode.Width; D3D_PP.BackBufferHeight = Mode.Height; D3D_PP.BackBufferFormat = D3DFMT_X8R8G8B8; D3D_PP.BackBufferCount = 1; D3D_PP.MultiSampleType = D3DMULTISAMPLE_NONE; D3D_PP.MultiSampleQuality = 0; D3D_PP.SwapEffect = D3DSWAPEFFECT_DISCARD; D3D_PP.hDeviceWindow = hWnd; D3D_PP.Windowed = FALSE; D3D_PP.EnableAutoDepthStencil = FALSE; D3D_PP.Flags = D3DPRESENTFLAG_LOCKABLE_BACKBUFFER; D3D_PP.FullScreen_RefreshRateInHz = Mode.RefreshRate; D3D_PP.PresentationInterval = D3DPRESENT_INTERVAL_ONE;
D3D->CreateDevice( D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hWnd, D3DCREATE_HARDWARE_VERTEXPROCESSING, &D3D_PP, &D3D_Device );
if (D3D_Device == NULL)
{
MessageBox(hWnd, "Error creating Direct3D device", "Error", MB_OK);
return E_FAIL;
}
HRESULT Result;
Result = D3D_Device->CreateOffscreenPlainSurface( Mode.Width, Mode.Height, D3DFMT_X8R8G8B8, D3DPOOL_SYSTEMMEM, &FrontBuffer, NULL );
if (FAILED(Result)) { MessageBox(hWnd, "FrontBuffer failed.", "Error", MB_OK); return E_FAIL; }
D3D_Device->GetBackBuffer (0, 0, D3DBACKBUFFER_TYPE_MONO, &BackBuffer);
Pixels = new DWORD[307200];
if (Pixels == NULL) return E_FAIL;
return S_OK; }
void Terminate(void) { if (Pixels != NULL) delete [] Pixels;
if (BackBuffer != NULL) BackBuffer->Release();
if (FrontBuffer != NULL) FrontBuffer->Release();
if (D3D_Device != NULL) D3D_Device->Release();
if (D3D != NULL) D3D->Release(); }
void Run(void) { D3DLOCKED_RECT lr;
FrontBuffer->LockRect(&lr, NULL, 0);
FillMemory(Pixels, 1228800, Color_Select);
CopyMemory(lr.pBits, Pixels, 1228800);
FrontBuffer->UnlockRect();
if (SUCCEEDED(D3D_Device->BeginScene())) { D3D_Device->UpdateSurface(FrontBuffer, NULL, BackBuffer, NULL); D3D_Device->EndScene(); } D3D_Device->Present( NULL, NULL, NULL, NULL ); }
Bryan Parkoff
.
- Follow-Ups:
- Re: Direct3D Surface Question
- From: Bryan Parkoff
- Re: Direct3D Surface Question
- References:
- Direct3D Surface Question
- From: Bryan Parkoff
- Re: Direct3D Surface Question
- From: Eyal Teler
- Re: Direct3D Surface Question
- From: Bryan Parkoff
- Re: Direct3D Surface Question
- From: Eyal Teler
- Re: Direct3D Surface Question
- From: Bryan Parkoff
- Direct3D Surface Question
- Prev by Date: Re: Why break some of the SDK?
- Next by Date: Re: Draping vector on terrain
- Previous by thread: Re: Direct3D Surface Question
- Next by thread: Re: Direct3D Surface Question
- Index(es):
Relevant Pages
|