Jump to content
  • Advertisement
Sign in to follow this  
howie_007

Trying to use shader with 3DXSPRITE

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

If you intended to correct an error in the post then please contact us.

Recommended Posts

I almost have it working but something is not right. From what I see, it looks like the quad that renders the post process buffer to the back buffer is stretched real big. So All I see are solid flickering colors.

This is the function to render the post process buffer to the back buffer via 3DXSPRITE. I refer to it as the display buffer. The below code works fine if I pull out the shader code and just have 3DXSPRITE do it's thing.


void CGameWnd::RenderPostProcessToDisplayBuffer()
{
// Set the display surface as the render target
CXWindow::Instance().SetDisplaySurfaceAsRenderTarget();

// Clear the buffers that are in use (depth, target and stencil buffer)
CXWindow::Instance().ClearBuffers();

CXWindow::Instance().GetXDevice()->SetRenderState( D3DRS_ZWRITEENABLE, false );
CXWindow::Instance().GetXDevice()->SetRenderState( D3DRS_ZENABLE, false );

// Test code for now to force the shader effect and technique
CShader::Instance().SetEffectAndTechnique( string("post_process"), string("nullEffect") );

// Set the projection matrix
D3DXMATRIX mtxViewProj;
D3DXMatrixOrthoOffCenterLH(&mtxViewProj, 0.0f, CXWindow::Instance().GetBufferWidth(),
CXWindow::Instance().GetBufferHeight(), 0.0f, 0.0f, 1.0f);

CShader::Instance().SetEffectValue(string("worldviewproj"), mtxViewProj );

// Create an identity matrix to pass to SetTransform
CMatrix matrix;
D3DXMATRIX mat( matrix.GetMatrix() );

// The 0 specifies that ID3DXEffect::Begin and ID3DXEffect::End will
// save and restore all state modified by the effect.
UINT uPasses;
CShader::Instance().GetActiveShader()->Begin( &uPasses, 0 );

// Beging 2d sprite rendering
CXWindow::Instance().GetXSprite()->Begin(0);//D3DXSPRITE_OBJECTSPACE D3DXSPRITE_DO_NOT_ADDREF_TEXTURE);

for( UINT uPass = 0; uPass < uPasses; ++uPass )
{
CShader::Instance().GetActiveShader()->BeginPass( uPass );

CXWindow::Instance().GetXSprite()->SetTransform( &mat );
CXWindow::Instance().GetXSprite()->Draw( CXWindow::Instance().GetPostProcessBufferTexture(), NULL, NULL, NULL, 0xFFFFFFFF );

CShader::Instance().GetActiveShader()->EndPass();
}

CXWindow::Instance().GetXSprite()->End();
CShader::Instance().GetActiveShader()->End();

CXWindow::Instance().GetXDevice()->SetRenderState( D3DRS_ZWRITEENABLE, true );
CXWindow::Instance().GetXDevice()->SetRenderState( D3DRS_ZENABLE, true );

} // RenderPostProcessToDisplayBuffer

Here's the very simple shader I'm trying to get to work.


//-----------------------------------------------------------------------------
// #defines
//-----------------------------------------------------------------------------

float3 luminanceConv = { 0.2125f, 0.7154f, 0.0721f };


//-----------------------------------------------------------------------------
// Global Variables
//-----------------------------------------------------------------------------

// Pos only camera view matrix
float4x4 worldviewproj : WORLDVIEWPROJ;


//-----------------------------------------------------------------------------
// Texture samplers
//-----------------------------------------------------------------------------

// Can just get the texture from the register
sampler postProcessTextSampler : register(s0);


//-----------------------------------------------------------------------------
// Vertex shader for projecting full screen quad coordinates
//-----------------------------------------------------------------------------
float4 v_projectFullScreenQuad( float4 pos : POSITION0 ) : POSITION0
{
return mul( pos, worldviewproj );

// test code to verify shader is being called
//return float4(0,0,0,1);
}

//-----------------------------------------------------------------------------
// Point Radius light shader function
//-----------------------------------------------------------------------------
float4 p_passThrough( float2 uv0 : TEXCOORD0 ) : COLOR0
{
return tex2D( postProcessTextSampler, uv0 );

// test code to verify shader is being called
//return float4(1,0,0,1);
}

//-----------------------------------------------------------------------------
// Point Radius light shader function
//-----------------------------------------------------------------------------
float4 p_convertToMonochrome( float2 uv0 : TEXCOORD0 ) : COLOR0
{
return dot( (float3)tex2D( postProcessTextSampler, uv0 ), luminanceConv );
}

//-----------------------------------------------------------------------------
// Effects
//-----------------------------------------------------------------------------

technique nullEffect
{
pass p0
{
VertexShader = compile vs_3_0 v_projectFullScreenQuad();
PixelShader = compile ps_3_0 p_passThrough();
}
}

technique convertToMonochrome
{
pass p0
{
VertexShader = compile vs_3_0 v_projectFullScreenQuad();
PixelShader = compile ps_3_0 p_convertToMonochrome();
}
}

From my tests I can see the shader is being called. Any ideas?

Share this post


Link to post
Share on other sites
Advertisement
never mind. I found an example of doing this with "DrawPrimitive". For some reason I though it would be harder that way. Been fighting 3DXSPRITE all morning and the "DrawPrimitive" way only took a few minutes to setup and get working. All is good now.

Share this post


Link to post
Share on other sites
The D3DX sprite class draws sprites using pre-transformed vertex positions that are already in screen space, and those don't work right with a vertex shader. Just making your own quad and drawing that is the better way to do it. Just be mindful of the whole half-pixel-offset thing.

Share this post


Link to post
Share on other sites

Just be mindful of the whole half-pixel-offset thing.

That would explain the "post process" using -0.5f in spots. Below is some code from the DirectX example.


//
// Set up our quad
//
PPVERT Quad[4] =
{
{ -0.5f, -0.5f, 1.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f },
{ pd3dsdBackBuffer->Width - 0.5f, -0.5, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f, 0.0f },
{ -0.5, pd3dsdBackBuffer->Height - 0.5f, 1.0f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f },
{ pd3dsdBackBuffer->Width - 0.5f, pd3dsdBackBuffer->Height - 0.5f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f }
};

Would it make any sense to replace 3DXSPRITE stuff with a similar approach? Would it be faster?

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!