Screen Aligned Quads using HLSL

Started by
0 comments, last by Namethatnobodyelsetook 15 years, 8 months ago
Hey Folks, I'm currently trying to create a pseudo-sprite interface using quads but for some reason I am completely SOL. My first issue is that DX renders with the center of the screen as the origin which I'm still trying to figure an elegant way around and the second is that for some reason the proper texture isn't being displayed. From what it looks like, it seems that the sampler isn't getting the correct color (YES, I am assigning the texture and committing before I draw... Here's the code but please excuse me if it's a bit long winded for a post. /********************HERE'S THE SHADER***********************/ texture g_Texture_Tex; sampler2D g_GUISampler = sampler_state { Texture = (g_Texture_Tex); ADDRESSU = WRAP; ADDRESSV = WRAP; MAGFILTER = LINEAR; MAXANISOTROPY = 8; MINFILTER = ANISOTROPIC; MIPFILTER = LINEAR; }; struct GUI_Prime_VS_INPUT { float4 Position : POSITION0; float3 Normal : NORMAL; float2 UVs : TEXCOORD0; }; struct GUI_Prime_VS_OUTPUT { float4 Position : POSITION0; float3 Color : TEXCOORD1; float2 UVs : TEXCOORD0; }; struct GUI_Prime_PS_INPUT { float3 Color : TEXCOORD1; float2 UVs : TEXCOORD0; }; GUI_Prime_VS_OUTPUT GUI_Prime_vs_main( GUI_Prime_VS_INPUT Input: POSITION ) { GUI_Prime_VS_OUTPUT Output = (GUI_Prime_VS_OUTPUT) 0; Output.Position = float4( Input.Position.xy, 0.0f, 1.0f ); Output.Color = Input.Normal; Output.UVs = Input.UVs; return Output; } float4 GUI_Prime_ps_main( GUI_Prime_PS_INPUT Input ) : COLOR { float4 FinalColor = tex2D( g_GUISampler, Input.UVs ); FinalColor.x = FinalColor.x * Input.Color.x; FinalColor.y = FinalColor.y * Input.Color.y; FinalColor.z = FinalColor.z * Input.Color.z; return FinalColor; } technique GUI { pass Prime { CULLMODE = NONE; LIGHTING = FALSE; FILLMODE = SOLID; ALPHABLENDENABLE = TRUE; BLENDOP = ADD; DESTBLEND = INVSRCALPHA; SRCBLEND = SRCALPHA; ZWRITEENABLE = TRUE; VertexShader = compile vs_2_0 GUI_Prime_vs_main(); PixelShader = compile ps_2_0 GUI_Prime_ps_main(); } } /************************HERE'S THE RENDER CODE********************/ void RenderGUI(void) { g_pD3DDevice->BeginScene(); g_pD3DDevice->Clear(0, 0, D3DCLEAR_TARGET | D3DCLEAR_STENCIL | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0); g_pEffect->SetTechnique(g_hFXTech_GUI); UINT uiNumPasses = 0; g_pEffect->Begin(&uiNumPasses, 0); g_pEffect->BeginPass(0); { tVertex verts[4]; unsigned int iVertSize = (unsigned int)sizeof(tVertex); SAFE_RELEASE(g_pVB); g_pD3DDevice->CreateVertexBuffer(iVertSize * 6, 0, D3DFVF_XYZRHW | D3DFVF_NORMAL | D3DFVF_TEX0, D3DPOOL_DEFAULT, &g_pVB, 0); g_pD3DDevice->SetStreamSource(0, g_pVB, 0, iVertSize); g_pD3DDevice->SetVertexDeclaration(tVertex::m_pVertDecl); //for (unsigned int uiCurrSprite = (unsigned int)m_vSprites.size(); uiCurrSprite--; ) { D3DSURFACE_DESC surfaceDesc; tSprite *currSprite = new tSprite();//&m_vSprites[uiCurrSprite]; currSprite->clr = 0xFFFFFFFF; currSprite->fRot = 0.0f; currSprite->fScaleX = 1.0f; currSprite->fScaleY = 0.75f; currSprite->iPostRotX = 0; currSprite->iPostRotY = 0; currSprite->iTexID = 0; currSprite->iX = 0; currSprite->iY = 0; currSprite->subFrame.top = 0; currSprite->subFrame.bottom = 1024; currSprite->subFrame.left = 0; currSprite->subFrame.right = 1024; IDirect3DTexture9* pCurrTex = g_pTexture;//m_vTextures[currSprite->iTexID]; D3DXVECTOR3 color = D3DXVECTOR3(currSprite->clr.r, currSprite->clr.g, currSprite->clr.b); pCurrTex->GetLevelDesc(0, &surfaceDesc); g_pEffect->SetTexture(g_hFX_Texture, pCurrTex); g_pEffect->CommitChanges(); float fXPos = (float)currSprite->iX; float fYPos = (float)currSprite->iY; float fHeight = (float)surfaceDesc.Height; float fWidth = (float)surfaceDesc.Width; float fUMin = currSprite->subFrame.left / fWidth; float fUMax = currSprite->subFrame.right / fWidth; float fVMin = currSprite->subFrame.top / fHeight; float fVMax = currSprite->subFrame.bottom / fHeight; fHeight *= currSprite->fScaleY; fWidth *= currSprite->fScaleX; fXPos -= g_kScrWidth/2; fYPos -= g_kScrHeight/2; verts[0].m_v3fPosition = D3DXVECTOR3(fXPos, fHeight + fYPos, 0.0f); verts[1].m_v3fPosition = D3DXVECTOR3(fXPos, fYPos, 0.0f); verts[2].m_v3fPosition = D3DXVECTOR3(fWidth + fXPos, fYPos, 0.0f); verts[3].m_v3fPosition = D3DXVECTOR3(fWidth + fXPos, fHeight + fYPos, 0.0f); verts[0].m_v3fNormal = color; verts[1].m_v3fNormal = color; verts[2].m_v3fNormal = color; verts[3].m_v3fNormal = color; verts[0].m_v2fTexCoord = D3DXVECTOR2(fUMin, fVMax); verts[1].m_v2fTexCoord = D3DXVECTOR2(fUMin, fVMin); verts[2].m_v2fTexCoord = D3DXVECTOR2(fUMax, fVMin); verts[3].m_v2fTexCoord = D3DXVECTOR2(fUMax, fVMax); void* buffer = NULL; g_pVB->Lock(0,0, &buffer, 0); tVertex* vBuff = (tVertex*)buffer; memcpy(&vBuff[0], &verts[3], iVertSize); memcpy(&vBuff[1], &verts[0], iVertSize); memcpy(&vBuff[2], &verts[1], iVertSize); memcpy(&vBuff[3], &verts[1], iVertSize); memcpy(&vBuff[4], &verts[2], iVertSize); memcpy(&vBuff[5], &verts[3], iVertSize); g_pVB->Unlock(); g_pD3DDevice->DrawPrimitive(D3DPT_TRIANGLELIST, 0, 2); delete currSprite; } //m_vSprites.clear(); SAFE_RELEASE(g_pVB); } g_pEffect->EndPass(); g_pEffect->End(); g_pD3DDevice->EndScene(); g_pD3DDevice->Present(0, 0, 0, 0); }
Advertisement
TEX0 means 0 texture coordinates. You want TEX1.

XYZRHW means transformed coordinates. They are in pixels, and the vertex shader is not run.

You're creating your vertex buffer each frame which is never a good thing. You'll want to create a dynamic vertex buffer and just lock each frame, drawing as many sprites in one draw call as possible.

When using an FVF, data must come in a specific order. Position, normal, then texcoord. Verify your structure or class matches that order.

Instead of using new to make a sprite on the heap, then deleting it at the end of the draw, you could just make a sprite on the stack... it's faster and will delete itself.

This topic is closed to new replies.

Advertisement