Plotting a pixel in directx9

Started by
12 comments, last by DarkZoulz 18 years, 12 months ago
I'd like to plot a pixel on screen with directx 9. I know about the GetBackBuffer() function, but when I try to write to the backbuffer surface pointer I get a memory error.

	//	Set device parameters.
	D3DPRESENT_PARAMETERS d3dpp;
	ZeroMemory(&d3dpp, sizeof(d3dpp));

	d3dpp.hDeviceWindow = hWnd;
	d3dpp.BackBufferCount = 1;
	d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE;
	d3dpp.SwapEffect = D3DSWAPEFFECT_FLIP;
	d3dpp.BackBufferFormat = D3DFMT_X8R8G8B8;
	d3dpp.Flags = D3DPRESENTFLAG_LOCKABLE_BACKBUFFER;
	d3dpp.Windowed = true;
	d3dpp.EnableAutoDepthStencil = false;

	//	Create device.
	m_pD3D->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hWnd, D3DCREATE_HARDWARE_VERTEXPROCESSING, &d3dpp, &m_pDevice);

	m_pDevice->GetBackBuffer(0, 0, D3DBACKBUFFER_TYPE_MONO, &m_pBackBuffer);



	m_pDevice->Clear(0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0, 0, 0), 0, 0);
	m_pDevice->BeginScene();
	m_pBackBuffer->LockRect(&m_bbRect, NULL, D3DLOCK_DONOTWAIT);

	D3DCOLOR	*pPixelData = (D3DCOLOR*)m_bbRect.pBits;
	pPixelData[x + (y * m_bbRect.Pitch)] = D3DCOLOR_XRGB(255, 255, 255); // Crashes...

	m_pBackBuffer->UnlockRect();
	m_pDevice->EndScene();
	m_pDevice->Present(NULL, NULL, 0, NULL);


Advertisement
Even if you can get DMA working, you're going to slaughter performance. Updating video memory in this way is painful at best, especially if you're dealing with "core data" such a depth buffer/render target. [sad]

Have you considered using a list of TLVerticies rendered as a D3DPT_POINTLIST? I've used similar before waaay back in D3D8.0 days to render a scatter-graph [smile]

Jack

<hr align="left" width="25%" />
Jack Hoxley <small>[</small><small> Forum FAQ | Revised FAQ | MVP Profile | Developer Journal ]</small>

Performance doesn't really matter that much in this case. I'm only going to use it for a simple AI chasing/evading algorithm where pixels chase or evade eachother.

Instead of dusting of old DirectDraw, I thought i'd try doing it in D3D.
You might be best off using a dynamic texture, and locking the texture surface every frame to edit it, and then unlocking and rendering it. Look up LockRect() for more info. Also, locking it for read/write access can slow performance. I don't know if the dynamic usage alleviates that, but if not, you might want to create an off screen surface (probably in D3DPOOL_SCRATCH, I believe), use that for all your reading/writing, and then just use LoadSurfaceFromMemory() or StretchRect() or UpdateSurface() or some appropriate call to update your dynamic texture each frame.
"We should have a great fewer disputes in the world if words were taken for what they are, the signs of our ideas only, and not for things themselves." - John Locke
Problem is, you aren't really - you're applying DirectDraw methodologies to a Direct3D interface, which is basically the worst of both worlds [smile]

You'd be better off doing something like this:

float fVertex[4] = { pixelX, pixelY, 0.f, *((float*)&pixelARGB) };m_pDevice->SetFVF(D3DFVF_XYZRHW | D3DFVF_DIFFUSE);m_pDevice->DrawPrimitiveUP(D3DPT_POINTLIST, 1, fVertex, 16);

Richard "Superpig" Fine - saving pigs from untimely fates - Microsoft DirectX MVP 2006/2007/2008/2009
"Shaders are not meant to do everything. Of course you can try to use it for everything, but it's like playing football using cabbage." - MickeyMouse

Just getting a pointer to the backbuffer surface and locking/unlocking it every frame (just like you do in directdraw) is really slow (and I mean like 1 frame per second) when doing it with direct3d?
Yepyep, very slow indeed! :) Also, note the following from the DX SDK documentation (the LockRect method):

Quote:
A multisample back buffer cannot be locked.

This method cannot retrieve data from a surface that is is contained by a texture resource created with D3DUSAGE_RENDERTARGET because such a texture must be assigned to D3DPOOL_DEFAULT memory and is therefore not lockable. In this case, use instead IDirect3DDevice9::GetRenderTargetData to copy texture data from device memory to system memory.


Copying from device memory to system memory will be SLOW, and then you'll have to copy back to device memory in order to display anything again. I reckon you'd probably be better off drawing a pointlist as suggested by previous posters, but hey it's upto you! :D
thats strange one in our class did you make a 3d software engine one of the best in the class using pointer to d3d backbuffer.

hum he said it was all about 1 flag dont rember.

But i can ask him for you if you wish? =)
-Truth is out there-
DarkZouls, could you give us a bit more info about the memory error you're getting, is it just an "Access violation accessing blah blah" type error? Have you tried using the D3D Debug runtime (check this in the DirectX section of Control Panel) to see if it gives you any warnings or errors?

Athos, when I say "very slow" I'm just meaning relative to rendering a pointlist or textured triangles, I don't mean "so slow it's unusable/unplayable". I guess the fastest way of plotting pixels manually would be to have a copy of a texture in both system & video memory, do your updates to the system-memory copy then upload it to the graphics card whenever it was changed, then render a fullscreen quad using that texture. But I'm sure even doing the v. slow "backbuffer->System memory, edit backbuffer, then copy back to video card" would give playable framerates on modern computers (assuming you weren't doing insanely complex software rendering or in very high-res). But it would certainly be interesting to hear more about your classmate's renderer, since that is the topic of this thread. :)
aha ok then i messed the posts up =).

It was a school assignment for us in school to write software engines. and one did use d3d while most did use ddraw. Was more to see how a 3d engine was in hardware then making anything useble with it. Allthough a few in the class did make a demo and showed it up on a lan party ( who ofcource dissed the engine since thay mostly consited of gamers who didnt understand what the programmers had done. ( Had texturing and normalmapping and such in software )

-Truth is out there-

This topic is closed to new replies.

Advertisement