Archived

This topic is now archived and is closed to further replies.

okonomiyaki

Render-to-texture not working

Recommended Posts

I''m baffled to say the least! I hope someone else has experienced this before. I shade my terrain with Shadow Maps, and that requires a render-to-texture pass of the terrain. This worked fine for a long time! But the problem was I wrote my code sloppily and it was inefficient, so I decided to clean up my code and I changed around a lot of things. Nothing is drastically different except that things are moved around, like all the vertex shaders that apply to the terrain are in the terrain class instead my application class, etc. After doing all that though, my render-to-texture technique stopped working. It does render to a texture, but the terrain is all white and the background is blue. I even switched shaders so that my main buffer would show what the render-to-texture was rendering, and in-game in the real viewport it looks fine (depth-shaded terrain). But the texture still comes out as white and blue. I can add a little "window" in-game showing the current texture that has been rendered to, and even then nothing is coming out on the terrain. The background is supposed to be blue, but the terrain is supposed to be black and fade to white. I see this when I switch my vieport to it but not on the texture. Anyone know the problem? Thanks!

Share this post


Link to post
Share on other sites
It is hard to trouble shoot with such little information, but I will just shoot you with some questions:

Is the texture that you are rendering to a power of 2, has the D3DUSAGE_RENDERTARGET usage flag set and created in the DEFAULT_POOL?

Are you using the D3DXCreateRenderToSurface interface?

This is code that I use to get mine working. Maybe you can find something that I am doing that you are not:

// Create the render texture as a power of 2
if (FAILED(D3DXCreateTexture(m_lpD3DDevice, m_bFullscreen ? 512 : 256, m_bFullscreen ? 512 : 256, 1, D3DUSAGE_RENDERTARGET, m_d3dpp.BackBufferFormat, D3DPOOL_DEFAULT, &m_pTexture)))
{
m_Network.SendClientErrorMessage(m_nName, "Couldn''t create render texture!");
return FALSE;
}

D3DSURFACE_DESC desc;
m_pTexture->GetSurfaceLevel(0, &m_pRenderSurface);
m_pRenderSurface->GetDesc(&desc);

// Create the render to surface interface with out a depth buffer
if (FAILED(D3DXCreateRenderToSurface(m_lpD3DDevice, desc.Width, desc.Height, desc.Format,
TRUE, (D3DFORMAT)m_dwDepthStencilFormat, &m_pRenderToSurface)))
{
m_Network.SendClientErrorMessage(m_nName, "Failed creating the render to texture interface!");
return FALSE;
}

// Set up the small viewport
// Width and height is currently set in the config file
m_ViewportSS.Width = (m_dwWidth / 4.0f) + 1; m_ViewportSS.Height = (m_dwHeight / 4.0f) + 1;
m_ViewportSS.MinZ = 0.0f; m_ViewportSS.MaxZ = 1.0f;
m_ViewportSS.X = 0; m_ViewportSS.Y = 0;

// Clear the surface alpha to 0 so that it does not bleed into a "blurry" background
// this is possible because of the avoidance of blurring in a non-blurred texel
if (SUCCEEDED(m_pRenderToSurface->BeginScene(m_pRenderSurface, &m_ViewportSS)))
{
m_lpD3DDevice->Clear(0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, m_BackgroundColor, 1.0f, 0);
m_pRenderToSurface->EndScene(0);
}

Share this post


Link to post
Share on other sites
Thanks a lot for your help. Sorry I didn't go into much more detail, I didn't want to just post code and tell somebody to go through it. I'll explain it a little better now though
I do basically everything you do, except I do not use the D3DXCreateRenderToSurface interface. I just grab the surface from the texture with GetSurfaceLevel.

This the code I use to set it all up:

//Setup the viewport for shadow mapping

shad_view.X = 0;
shad_view.Y = 0;
shad_view.Width = DBUFFER;
shad_view.Height = DBUFFER;
shad_view.MinZ = 0.0f;
shad_view.MaxZ = 1.0f;

GameInfo::PushText("Creating new render targets for shadow mapping");
//Create the depth buffer

if(FAILED(D3DXCreateTexture(gDevice, DBUFFER, DBUFFER, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &depths))) {
MB("Error creating the depths texture!");
ExitThread(0);
}
GameInfo::loading_progress += 1;

//Create the Z buffer

if(FAILED(gDevice->CreateDepthStencilSurface(DBUFFER, DBUFFER, D3DFMT_D24S8, D3DMULTISAMPLE_NONE, 0, TRUE, &newZBuffer, NULL))) {
MB("Error creating new depth stencil surface!");
ExitThread(0);
}
GameInfo::loading_progress += 1;

//Create the render surface

if(FAILED(depths->GetSurfaceLevel(0, &newRender))) {
MB("Error getting the surface level of depths texture!");
ExitThread(0);
}
GameInfo::loading_progress += 1;


Nothin' special, I have all the flags set as far as I know. It must be something with how the previous objects are being drawn, because the only thing different this time around is how I draw my scene. Every object is still drawn the same way though.

This is the code I use for rendering to texture:

void Terrain::DrawShadowMap() {

D3DXMatrixLookAtLH(&matLight, &(D3DXVECTOR3)GameInfo::lightPos, &(D3DXVECTOR3)(GameInfo::lightPos + GameInfo::lightDir), &D3DXVECTOR3(0.0f, 1.0f, 0.0f));
transformed_light = GameInfo::matWorld*matLight*GameInfo::matProj;
D3DXMatrixTranspose(&transformed_light, &transformed_light); //real time movement


gDevice->SetRenderTarget(0, newRender);
gDevice->SetDepthStencilSurface(newZBuffer);
gDevice->SetViewport(&shad_view);

gDevice->Clear(0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, D3DCOLOR_XRGB(0,0,100), 1.0f, 0);

gDevice->SetVertexShader(Vlight);
gDevice->SetVertexDeclaration(RegDec);
gDevice->SetVertexShaderConstantF(10, (float*)transformed_light, 4);
gDevice->SetVertexShaderConstantF(25, (float*)&D3DXVECTOR4(2*k/5.5f, 0.0f, 0.0f, 0.0f), 1);

LodMaster->Render(0);

}


LodMaster is a pointer to a ChunkedLOD structure. 0 is telling it just to draw the lowest level of detail.
I don't think it has anything to do with actually rendering the terrain, I can see that it looks fine when I switch my main view to the shadow map light-rendering view (the one that should be going on the texture). It's just doing something weird when actually writing the texture. The DBUFFER variable is 1024, so yes, it's a power of 2.

Maybe I should update and try the D3DXCreateRenderToSurface interface.

[edited by - okonomiyaki on August 14, 2003 2:49:47 PM]

Share this post


Link to post
Share on other sites