Sign in to follow this  
Simononon

DirectX Offscreen Buffer (C++)

Recommended Posts

Simononon    100
I'm trying to use Direct3D 9 to render to an offscreen buffer without a context, so that I can retrieve the colour of each pixel to convert to ASCII and render in a console window. Currently I have the following code (using GDI's SetPixel to test the output):
#include <windows.h>
#include <d3d9.h>

int main(int argc, char *argv[])
{
	IDirect3D9 *pD3D9 = Direct3DCreate9(D3D_SDK_VERSION);

	HWND hWnd = GetConsoleWindow();
	D3DPRESENT_PARAMETERS d3dpp = { 0 };
	d3dpp.BackBufferWidth = 640;
	d3dpp.BackBufferHeight = 300;
	d3dpp.BackBufferCount = 1;

	IDirect3DDevice9 *pD3DDevice9 = NULL;
	pD3D9->CreateDevice(
		D3DADAPTER_DEFAULT,
		D3DDEVTYPE_NULLREF,
		hWnd,
		D3DCREATE_HARDWARE_VERTEXPROCESSING,
		&d3dpp,
		&pD3DDevice9
	);

	IDirect3DSurface9 *pBackBuffer = NULL;
	pD3DDevice9->GetBackBuffer(
		0,
		0,
		D3DBACKBUFFER_TYPE_MONO,
		&pBackBuffer
	);

	IDirect3DSurface9 *pSurface = NULL;
	pD3DDevice9->CreateOffscreenPlainSurface(
		640,
		300,
		D3DFMT_X8R8G8B8,
		D3DPOOL_SYSTEMMEM,
		&pSurface,
		NULL
	);

	D3DLOCKED_RECT rect;
	HDC hdc = GetDC(hWnd);

	while(true)
	{
		pD3DDevice9->Clear(
			0,
			NULL,
			D3DCLEAR_TARGET,
			D3DCOLOR_XRGB(255, 255, 255),
			1.f,
			0
		);

		pD3DDevice9->BeginScene();
		pD3DDevice9->EndScene();

		pD3DDevice9->GetRenderTargetData(pBackBuffer, pSurface);
		pSurface->LockRect(
			&rect,
			NULL,
			D3DLOCK_NO_DIRTY_UPDATE | D3DLOCK_READONLY	
		);

		for(int y = 0; y < 300; y++)
		{
			for(int x = 0; x < 640; x++)
			{
				D3DCOLOR Color = ((D3DCOLOR *)rect.pBits)[y * (rect.Pitch / sizeof(int)) + x];
				SetPixel(hdc, x, y, Color);
			}
		}

		pSurface->UnlockRect();
	}

	ReleaseDC(hWnd, hdc);

	pBackBuffer->Release();
	pSurface->Release();

	pD3DDevice9->Release();
	pD3D9->Release();

	return 0;
}
It doesn't seem to be working, however, as the D3DCOLOR Color is always 0 regardless of what colour the screen is cleared to. Is this possible? If so, what am I doing wrong?

Share this post


Link to post
Share on other sites
Simononon    100
Quote:
Original post by Aqua Costa
Read this: http://www.gamedev.net/community/forums/topic.asp?topic_id=553732


Thanks - though I just realised GetBackBuffer is returning a null pointer:

	IDirect3D9 *pD3D9 = Direct3DCreate9(D3D_SDK_VERSION);

HWND hWnd = GetConsoleWindow();
D3DPRESENT_PARAMETERS d3dpp = { 0 };
d3dpp.BackBufferWidth = 640;
d3dpp.BackBufferHeight = 300;
d3dpp.BackBufferCount = 1;
d3dpp.Flags = D3DPRESENTFLAG_LOCKABLE_BACKBUFFER;

IDirect3DDevice9 *pD3DDevice9 = NULL;
pD3D9->CreateDevice(
D3DADAPTER_DEFAULT,
D3DDEVTYPE_NULLREF,
hWnd,
D3DCREATE_HARDWARE_VERTEXPROCESSING,
&d3dpp,
&pD3DDevice9
);

IDirect3DSurface9 *pBackBuffer = NULL;
pD3DDevice9->GetBackBuffer(
0,
0,
D3DBACKBUFFER_TYPE_MONO,
&pBackBuffer
);


any ideas why?

Share this post


Link to post
Share on other sites
Simononon    100
Quote:
Original post by Mike.Popoloski
You're creating a null reference device. I'm not sure on the specifics of what that entails, but I wouldn't expect much of the rendering structure to get initialized along with it.


I thought this might be the problem, but using any other D3DDEVTYPE (HAL, REF, SW) results in a null device, presumably because the window handle is to a console window.

Will I have to make a dummy window instead?

Share this post


Link to post
Share on other sites
Zoner    232
Quote:
Original post by Simononon
Quote:
Original post by Mike.Popoloski
You're creating a null reference device. I'm not sure on the specifics of what that entails, but I wouldn't expect much of the rendering structure to get initialized along with it.


I thought this might be the problem, but using any other D3DDEVTYPE (HAL, REF, SW) results in a null device, presumably because the window handle is to a console window.

Will I have to make a dummy window instead?


You have to have a a window and a windows message pump, as d3d abuses the message pump to do some internal things (maybe fixed in d3d10, but its been true for 9 and previous forever)

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this