Creating a faux 'Pick Buffer'

Started by
2 comments, last by Supernat02 19 years, 6 months ago
Hey guys, I'm new, been lurking, yada yada yada... Anyways, I'm a convert from OpenGL to Direct3D, and am in the process of learning how to port over several methods I used to use. One of them was a method of rendering out a 'Pick Buffer' of sorts. The basic way it worked was that whenever the scene was changed (Or, for efficiency reasons, stopped changing), the scene was rendered again into an off-screen buffer with textures and lights disabled, with each object possessing an individual color. Whenever the mouse was clicked, the pixel at the mouse location would be retreived from the buffer and linked to an object in an indexed table to retrieve the object that was clicked on. It had some flaws I'll admit, like the limited number of objects (Although at roughly 16.7 million possible colors/objects that's somewhat ignorable) and the neccesity of re-rendering the scene into a 32-bit render buffer which is constantly read from, but for the purposes of an editor it works fine and provides superior flexibility of how the pick objects work (Z-correct, pixel accurate and the ability to artificially expand small objects like verticies and lines for easy clickin'). Now, the thing is I have no idea how to handle this in Direct3D, due to its mesh-oriented structure (As far as I understand it). I'm having trouble getting my head around how to draw an object {That already has seperate vertex colors) as one big, flat, solid colored shape without having to lock the vertex buffers, alter them, then switch them back to their original settings. Is this even possible, or will I have to use the more time-honored technique of picking with rays? If possible, I'd like to avoid using hardware pixel/vertex shaders, mainly for compatibility reasons. Thanks for your time, guys. -Nick London
Advertisement
Yes, you can do it without modifying the vertex buffers. The vertex color (DIFFUSE color part anyway) is only used when the proper texture stage settings are set. You can disable the use of that and tell the video card to use a constant for the color (which is where you will put your value at of course).

// InitializationSetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_CONSTANT);SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_DISABLE);SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_CONSTANT);SetTextureStageState(1, D3DTSS_ALHPAOP, D3DTOP_DISABLE);SetRenderState(D3DRS_ALPHATESTENABLE, FALSE);SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE);for (int x=0; x < NumMeshes; x++){  SetTextureStageState(0, D3DTSS_CONSTANT, Mesh[x]->DWORDColorIdentifier);  Mesh[x]->Render();}


Since there's only one constant available per texture stage, you can't use the same constant to set the texture color to one thing and force the alpha value to 100%. So, we just let alpha be what alpha is and disable it completely.

Hope this is what you're looking for.

EDIT: This is only viable for DirectX 9.0 and up I believe. There is a way to do it with DirectX 8, which I can tell you if you need to. I'll just have to go find the info.

Chris
Chris ByersMicrosoft DirectX MVP - 2005
Fantastic, that's exactly what I was looking for. :)

A D3D8 version isn't really needed, but it might be nice to know in case I ever decide to make a DX8 version of the renderer. Dont want to put you to too much trouble though, so just a point in the right direction would be great.

Thanks!

-Nick
Simon posted this a while back:

"For older versions of DirectX if you only need a single constant for the whole blend you can use D3DTA_TFACTOR and set the constant value with the D3DRS_TEXTUREFACTOR render state."

Chris
Chris ByersMicrosoft DirectX MVP - 2005

This topic is closed to new replies.

Advertisement