Skip to main content
gamedev.net
🔒 Locked

Rendering To Texture

Started by ministe2003 5 replies 2k views
Original Post
ministe2003
ministe2003
Hi! I'm trying to render to a texture so i can play with shaders but all I'm getting is a black screen, and I get no errors :'( this is the first time I've done this so I cant tell whats wrong so here's the relevant code: width and height are 800 and 600, they are fine, I've looked:

	D3DXCreateTexture(D3DDevice, width, height, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &renderTexture);
	renderTexture->GetSurfaceLevel(0, &renderSurface);

	//save original render target
	IDirect3DSurface9* originalRT;

	D3DDevice->GetRenderTarget(0,&originalRT);

	//set new render target - the texture
	D3DDevice->SetRenderTarget(0,renderSurface);
	
	D3DDevice->Clear(0, 0, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
	D3DDevice->BeginScene();

	//render stuff
	D3DDevice->EndScene();

	D3DXMATRIX World;
	D3DXMatrixTranslation(&World, 0.0f, 0.0f, 0.5f);

	//set original render target, the back buffer
	D3DDevice->SetRenderTarget(0,originalRT);
	D3DDevice->Clear(0, 0, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
	D3DDevice->BeginScene();

	D3DDevice->SetTransform(D3DTS_WORLD, &World);
	mat = *m_pMaterial->NoMaterial();
	D3DDevice->SetMaterial(&mat); //clear any set material
	D3DDevice->SetTexture(0,renderTexture);
	SAQuad->DrawSubset(0);
	D3DDevice->EndScene();
	D3DDevice->Present(0, 0, 0, 0);
SAQuad is supposed to be a screen aligned quad, here's the code I use to try and make it:


ID3DXMesh* CMesh::CreateScreenAlignedQuad(IDirect3DDevice9* m_pDevice, int width, int height)
{
	ID3DXMesh* Mesh = 0;
	HRESULT hr = 0;

	hr = D3DXCreateMeshFVF(
		2,					//Number of faces
		4,					//Number of vertices
		D3DXMESH_MANAGED,	//Options - Mesh will be placed the Managed memory pool
		Vertex::FVF,		//The FVF of the vertices of this mesh
		m_pDevice,			//D3D Device
		&Mesh);				//[OUT] created mesh

	if(FAILED(hr)){
		::MessageBox(0, "D3DXCreateMeshFVF() - FAILED", 0, 0);
			return 0;
	}

	// Fill in vertices of our tile
	Vertex* v = 0;
	Mesh->LockVertexBuffer(0, (void**)&v);


	// fill in the top face vertex data
				//  x		  y		  z
	v[0] = Vertex( 0.0f,	height,	0.5f,	0.0f, 1.0f, 0.0f, 0.0f, 1.0f ); //BL
	v[1] = Vertex( 0.0f,	0.0f,	0.5f,	0.0f, 1.0f, 0.0f, 0.0f, 0.0f );	//TL
	v[2] = Vertex( width,	0.0f,	0.5f,	0.0f, 1.0f, 0.0f, 1.0f, 0.0f );	//TR
	v[3] = Vertex( width,	height, 0.5f,	0.0f, 1.0f, 0.0f, 1.0f, 1.0f ); //BR

	Mesh->UnlockVertexBuffer();

	// Define the triangles of the box
	WORD* i = 0;
	Mesh->LockIndexBuffer(0, (void**)&i);

	// fill in the top face index data
	i[0] = 0; i[1] = 1; i[2] = 2;
	i[3] = 0; i[4] = 2; i[5] = 3;

	Mesh->UnlockIndexBuffer();

	// Specify the subset each triangle belongs to
	// There is just one subset
	DWORD* attributeBuffer = 0;
	Mesh->LockAttributeBuffer(0, &attributeBuffer);

	for(int a = 0; a < 2; a++)
		attributeBuffer[a] = 0;

	Mesh->UnlockAttributeBuffer();

	// Optimize the mesh to generate an attribute table.
	std::vector<DWORD> adjacencyBuffer(Mesh->GetNumFaces() * 3);
	Mesh->GenerateAdjacency(0.0f, &adjacencyBuffer[0]);

	hr = Mesh->OptimizeInplace(		
		D3DXMESHOPT_ATTRSORT |		//flag
		D3DXMESHOPT_COMPACT  |		//flag
		D3DXMESHOPT_VERTEXCACHE,	//flag
		&adjacencyBuffer[0],		//pointer to adjacency array of non optimized array
		0, 0, 0);					//not needed, so zero

	if(FAILED(hr))
	{
		::MessageBox(0, "OptimizeInplace() - FAILED", 0, 0);
		return false;
	}

	return Mesh;
}

I've no idea what's wrong, I'm getting no errors or warnings, even when I put DirectX into Debug mode. Any and all help will be gratefully received!! It's got to be something to do with my SAQuad, I tried rendering to the terrain and got this result, so it must be working... http://img256.imageshack.us/img256/3076/weird.jpg
MJP
MJP
Have you tried using PIX yet. If not, you really should! The first thing I'd do is capture a frame, and look at the contents of you render target texture immediately after you've finished rendering to it. If it has what you expect, then you know you screwed up with your quad-rendering code. If it doesn't, you know to focus on that part.
glaeken
glaeken
Is your screen quad defined in screen space (i.e. the width and height of the backbuffer)? If so, then you need to make sure that you're using the D3DFVF_XYZRHW in your fvf definition. With this you also need to set the view and proj device transforms to the Identity matrix when you draw the quad.

[Edited by - glaeken on March 27, 2009 6:24:51 PM]
ministe2003
ministe2003
Ta for that, will look into it.

I've had a dabble with PIX but have to say its pretty damn complicated and I cant find whats up with it :(
ministe2003
ministe2003
OK can anyone see anything obviously wrong with this?
//in vertex.hstruct ProjectionVertex{	float _x, _y, _z, _rhw, _u, _v;};//in game.cpp#define D3DFVF_CUSTOMVERTEX (D3DFVF_XYZRHW|D3DFVF_TEX1)...hr = D3DXCreateRenderToSurface(	D3DDevice,	width, height,	D3DFMT_X8R8G8B8,	true,	D3DFMT_D24X8,	&RTSurface);UINT usage = D3DUSAGE_RENDERTARGET|D3DUSAGE_AUTOGENMIPMAP;hr = D3DXCreateTexture(	D3DDevice,	width, height,	0,	usage,	D3DFMT_X8R8G8B8,	D3DPOOL_DEFAULT,	&TexRenderedTo);TexRenderedTo->GetSurfaceLevel(0,&Surface);D3DVIEWPORT9 vp = {0,0,width, height,0.0f,1.0f};viewport = vp;	//globalProjectionVertex v[] ={   {-1.0f, 1.0f,  0.0f, 1.0f, 0.0f, 0.0f},	//top left   {1.0f, 1.0f,  0.0f, 1.0f, 1.0f, 0.0f},	//top right   {-1.0f, -1.0f, 0.0f, 1.0f, 0.0f, 1.0f},	//bottom left   {1.0f, -1.0f, 0.0f, 1.0f, 1.0f, 1.0f},	//bottom right};D3DDevice->CreateVertexBuffer(4*sizeof(ProjectionVertex), 0,	D3DFVF_CUSTOMVERTEX, D3DPOOL_DEFAULT, &RtoTexVB, NULL);// fill the vertex buffer.VOID* pVertices;if( FAILED( RtoTexVB->Lock( 0, sizeof(v), (void**)&pVertices, 0 ) ) )    return E_FAIL;memcpy( pVertices, v, sizeof(v) );RtoTexVB->Unlock();....D3DDevice->Clear(0, 0, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);RTSurface->BeginScene(Surface, &viewport);//render everythingRTSurface->EndScene(D3DX_FILTER_NONE);D3DDevice->BeginScene();if (SUCCEEDED(R2TexShader->SetTechnique(hR2TexTech))){	D3DDevice->SetStreamSource(0, RtoTexVB, 0, sizeof(ProjectionVertex));	R2TexShader->SetTexture(hR2Tex_Texture, TexRenderedTo);	UINT numPasses;	R2TexShader->Begin(&numPasses,0);	for (UINT n=0;n<numPasses;n++)	{		R2TexShader->BeginPass(0);			D3DDevice->DrawPrimitive( D3DPT_TRIANGLESTRIP, 0, 2 );		R2TexShader->EndPass();	}	R2TexShader->End();}D3DDevice->EndScene();D3DDevice->Present(0, 0, 0, 0);


This is the result I'm getting and I don't get why!
http://yfrog.com/0c49597027j

[Edited by - ministe2003 on March 29, 2009 3:13:53 AM]
ministe2003
ministe2003
Never mind I seem to have found a fix, I looked at a directX postprocessing sample and saw in their FVF definition they had 2 lots of TexCoords:

// This is the vertex format used with the quad during post-process.struct PPVERT{    float x, y, z, rhw;    float tu, tv;       // Texcoord for post-process source    float tu2, tv2;     // Texcoord for the original scene    const static D3DVERTEXELEMENT9 Decl[4];};


so I tried the same, altered my Vertex definition a little and it seems to be working :D

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.