Drawing a Fullscreen Quad

Started by
2 comments, last by jaafit 18 years ago
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]
Advertisement
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
------------------------------------------------------------Neo, the Matrix should be 16-byte aligned for better performance!
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
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]

This topic is closed to new replies.

Advertisement