# Issues reading a render target on the CPU (GPGPU)

This topic is 3136 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

## Recommended Posts

I'm implementing a vegetation rendering system just like from GPU Gems 2: Toward Photorealism in Virtual Botany. To pick points to "plant" vegetation, I render the terrain in blocks that correspond to the cells I want, i.e. blocks of planting points just like in GPU Gems 2. I have a working shader that finds planting points and outputs 1 for planting points and 0 for non-planting points. The problem I'm having though, is when I try to read the texture on the CPU I get complete garbage. Here is the source code for reading the texture:
gd3dDevice->CreateOffscreenPlainSurface(256, 256, D3DFMT_X8R8G8B8, D3DPOOL_SYSTEMMEM, &mOffscreenCPUSurface, NULL);
...
D3DLOCKED_RECT lock;

IDirect3DSurface9* tempRT = 0;
gd3dDevice->GetRenderTarget(0, &tempRT);
gd3dDevice->SetRenderTarget(0, mTopSurf);
gd3dDevice->GetRenderTargetData(mTopSurf, mOffscreenCPUSurface);
gd3dDevice->SetRenderTarget(0, tempRT);

const BYTE* src = (const BYTE*)lock.pBits;
int pixelsPrinted = 0;
char tempStr[50];
DWORD r, g, b, a;

for( int y = 255; y >= 0; --y )
{
const DWORD* srcPtr = (const DWORD*)src;
for(int x = 0; x <= 256; ++x)
{
DWORD argbCol = *srcPtr;
r = argbCol & 0xFF000000;
g = (argbCol & 0x00FF0000) << 8;
b = (argbCol & 0x0000FF00) << 16;
a = (argbCol & 0x000000FF) << 24;
sprintf_s(tempStr, 50, "(%u, %u, %u, %u)", r, g, b, a);
MessageBox(NULL, tempStr, "", MB_OK);

pixelsPrinted++;
if(pixelsPrinted > 3) break;

++srcPtr;
}

if(pixelsPrinted > 3) break;

src += lock.Pitch;
}

mOffscreenCPUSurface->UnlockRect();


Whenever I run this code, I always get (4278190080, 0, 0, 0). I then wrote a function that "MessageBoxes" every single bit one at a time, and I read 20 pixels to see that every single bit is zero. Can someone please help me read the render target, Thanks, Mikfig

##### Share on other sites
4278190080 is 0xFF000000. Because you're shifting left, for a reason beyond my understanding, you'll always get 000000 at the end. I think you're also reading the components in a reverse order (which would happen if you're using D3D9, which describes the formats in a little endian way). The value is probably r=0, g=0, b=0, a=255.

##### Share on other sites
Ok, I am now reading the texture just fine, but I found out that it is stored as BGR instead of RGB. So now I have to figure out how to undue perspective divide and what not because I need the world space position that corresponds with each pixel. Considering that the Z coord is discarded, I put z / zfarplane in the G channel. I know that I have to get the x/y coords from screen space and then somehow get the world space coordinates with the inverse view/projection transform. However, I have no idea how to do this...

Any advice would be greatly appreciated,
Thanks,
mikfig

##### Share on other sites
Quote:
 Original post by mikfigOk, I am now reading the texture just fine, but I found out that it is stored as BGR instead of RGB. So now I have to figure out how to undue perspective divide and what not because I need the world space position that corresponds with each pixel. Considering that the Z coord is discarded, I put z / zfarplane in the G channel. I know that I have to get the x/y coords from screen space and then somehow get the world space coordinates with the inverse view/projection transform. However, I have no idea how to do this...

Luckily for you, I come armed with blog posts. [smile]

http://mynameismjp.wordpress.com/2009/03/10/reconstructing-position-from-depth/

##### Share on other sites
You rock my world MJP :D

Just one question:

I am reconstructing the world space position on the CPU, and I'm assuming that out_vFrustumCornerWS (from the Reconstructing Position From Depth, Continued article) is interpolated between VS/PS to give the pixel's equivalent position on the far clipping plane.

So to get that I have to do something like bicubic interpolation of the frustum corner positions, right? And if so, I'm unsure what points I would interpolate between unless it is reasonable to assume that the corners of the render target texture are equivalent to the corners of the frustum.

Thanks a ton,
mikfig