Sign in to follow this  
jaafit

Drawing a Fullscreen Quad

Recommended Posts

I'm trying to draw a full-screen, textured quad using the same method as the PostProcess sample that came with DX9SDK. My code must be missing something though, because whenever I run it all I get is the green/red flashing indicating that nothing is being drawn. What I have is:

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];
	};
const D3DVERTEXELEMENT9 PPVERT::Decl[4] =
	{
		{ 0, 0,  D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITIONT, 0 },
		{ 0, 16, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,  0 },
		{ 0, 24, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,  1 },
		D3DDECL_END()
	};
	
void DXViewport::RenderPostProcessQuad()
	{
	float width = GetViewportWidthPixels();
	float height = GetViewportHeightPixels();
	
	PPVERT quad[4] =
		{
			{ -0.5f,      -0.5f,			1.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f },
			{ width-0.5f, -0.5,			1.0f, 1.0f, 1.0f, 0.0f, 1.0f, 0.0f },
			{ -0.5,       height-0.5f, 1.0f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f },
			{ width-0.5f, height-0.5f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f }
		};
		
	IDirect3DVertexDeclaration9* pVertDeclPP;
	gpDXDevice->m_pDeviceLow->CreateVertexDeclaration( PPVERT::Decl, &pVertDeclPP );
	gpDXDevice->m_pDeviceLow->SetVertexDeclaration( pVertDeclPP );
	
	gpDXDevice->m_pDeviceLow->DrawPrimitiveUP(D3DPT_TRIANGLESTRIP, 2, quad, sizeof(PPVERT));   
	SAFE_RELEASE(pVertDeclPP);
	}

If I don't use RenderPostProcessQuad and instead use a function I made, it works but it's not accurate so I would rather use RenderPostProcessQuad. What am I missing? [Edited by - jaafit on April 5, 2006 11:38:58 AM]

Share this post


Link to post
Share on other sites
Hi,

use my code (you have to adjust it at some places to fit your environment, eg. modify includes, use your own satet guard, or the device itself to set render states - but don't forget to reset them afterwards):

ScreenAlignedQuad.hpp

#pragma once

#include "DirectXCommon.hpp"

namespace DX
{
class ScreenAlignedQuad {
private:
IDIRECT3DVERTEXBUFFER* m_vertexBuffer;
bool m_isValid;
IDirect3DDevice9* m_pd3dDevice;

public:
ScreenAlignedQuad();
~ScreenAlignedQuad();

bool IsValid() { return(m_isValid); }
void Create(IDirect3DDevice9* p_pd3dDevice, int p_width, int p_height);
void Render();
void Release();
};

} // namespace DX




ScreenAlignedQuad.cpp

#include "stdafx_DXM.h"

#include "ScreenAlignedQuad.hpp"
#include "dxutil.h"

namespace DX
{

//-----------------------------------------------------------------------------
ScreenAlignedQuad::ScreenAlignedQuad()
{
m_isValid = false;
m_vertexBuffer = NULL;
}

//-----------------------------------------------------------------------------
ScreenAlignedQuad::~ScreenAlignedQuad()
{
if (IsValid()) {
Release();
}
}

//-----------------------------------------------------------------------------
void ScreenAlignedQuad::Create(IDirect3DDevice9* p_pd3dDevice, int p_width, int p_height)
{
m_pd3dDevice = p_pd3dDevice;

HRESULT hr;
hr = m_pd3dDevice->CreateVertexBuffer(6 * sizeof(VertexXYZCT), 0, D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_TEX1, D3DPOOL_MANAGED, &m_vertexBuffer, NULL);
if (hr != D3D_OK)
return;

if (m_vertexBuffer == NULL)
return;

void* vbVertices = NULL;
if (FAILED(m_vertexBuffer->Lock(0, 6 * sizeof(VertexXYZCT), &vbVertices, 0)))
throw CCException("DirectX error in drawing screen aligned quad");

VertexXYZCT* vertices = (VertexXYZCT*) vbVertices;

float startX = -1.0;
float endX = 1.0;
float startY = 1.0;
float endY = -1.0;
float startU = 0.5 / p_width;
float endU = 1.0 + 0.5 / p_width;
float startV = 0.5 / p_height;
float endV = 1.0 + 0.5 / p_height;

vertices[0].pos = D3DXVECTOR3(startX, startY, 1.0);
vertices[0].tu = startU; vertices[0].tv = startV;
vertices[0].color = D3DCOLOR_RGBA(255, 255, 255, 255);

vertices[1].pos = D3DXVECTOR3(endX, startY, 1.0);
vertices[1].tu = endU; vertices[1].tv = startV;
vertices[1].color = D3DCOLOR_RGBA(255, 255, 255, 255);

vertices[2].pos = D3DXVECTOR3(endX, endY, 1.0);
vertices[2].tu = endU; vertices[2].tv = endV;
vertices[2].color = D3DCOLOR_RGBA(255, 255, 255, 255);

vertices[3].pos = D3DXVECTOR3(startX, startY, 1.0);
vertices[3].tu = startU; vertices[3].tv = startV;
vertices[3].color = D3DCOLOR_RGBA(255, 255, 255, 255);

vertices[4].pos = D3DXVECTOR3(endX, endY, 1.0);
vertices[4].tu = endU; vertices[4].tv = endV;
vertices[4].color = D3DCOLOR_RGBA(255, 255, 255, 255);

vertices[5].pos = D3DXVECTOR3(startX, endY, 1.0);
vertices[5].tu = startU; vertices[5].tv = endV;
vertices[5].color = D3DCOLOR_RGBA(255, 255, 255, 255);

m_vertexBuffer->Unlock();

m_isValid = true;
}

//-----------------------------------------------------------------------------
void ScreenAlignedQuad::Render()
{
CCASSERT(IsValid());

CD3DStateGuard guard(m_pd3dDevice);

D3DXMATRIX identity;
m_pd3dDevice->SetTransform(D3DTS_WORLD, D3DXMatrixIdentity(&identity));
guard.SetTransform(D3DTS_VIEW, &identity);
guard.SetTransform(D3DTS_PROJECTION, &identity);
guard.SetRenderState(D3DRS_LIGHTING, FALSE);
guard.SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE);
guard.SetRenderState(D3DRS_ZENABLE, FALSE);
guard.SetRenderState(D3DRS_ZWRITEENABLE, FALSE);
guard.SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE);

m_pd3dDevice->SetFVF(FVF_VertexXYZCT);
m_pd3dDevice->SetStreamSource(0, m_vertexBuffer, 0, sizeof(VertexXYZCT));
m_pd3dDevice->DrawPrimitive(D3DPT_TRIANGLELIST, 0, 2);
}

//-----------------------------------------------------------------------------
void ScreenAlignedQuad::Release()
{
SAFE_RELEASE(m_vertexBuffer);
}


} // namespace DX



kp

Share this post


Link to post
Share on other sites
I guess you should look into vertex declarations and their use. Your vertex declaration seems to contain the vertices themselves, while the declaration should describe the layout of one vertex, so that the GPU might know where to get the position, texcoords and so on from the incoming vertex. A vertex declaration should look something like this:


D3DVERTEXELEMENT9 dwDecl3[] =
{
{0, 0, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT,
D3DDECLUSAGE_POSITIONT, 0},
{0, 16, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT,
D3DDECLUSAGE_TEXCOORD, 0},
{0, 24, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT,
D3DDECLUSAGE_TEXCOORD, 1},
D3DDECL_END()
};


Please note that this vertex declaration is just a guess quickly stitched together with the help of the DX SDK documentation, which you should have a look at. Also note that your coordinates with D3DDECLUSAGE_POSITIONT (transformed position) should range from [0,0] to [viewport.width, viewport.height], so you might want to change those in your code.

Hope this helped

Share this post


Link to post
Share on other sites
I do have that in my code but when I was editing my post I replaced the wrong section with my vertex data. (oops!) I've updated my post now to what it really looks like.

After trying random stuff, I think I found the answer. I was missing these render states:

gpDXDevice->m_pDeviceLow->SetTextureStageState( 0, D3DTSS_COLORARG1, D3DTA_TEXTURE );
gpDXDevice->m_pDeviceLow->SetTextureStageState( 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1 );
gpDXDevice->m_pDeviceLow->SetTextureStageState( 1, D3DTSS_COLOROP, D3DTOP_DISABLE );
gpDXDevice->m_pDeviceLow->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE);


CULLMODE was not in the PostProcess example so I thought I didn't need it, but I think the reason I do need it is that another part of my app is setting CULLMODE to something else.

[Edited by - jaafit on April 5, 2006 2:41:12 PM]

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this