Win32: do not use pre-transformed vertices in D3D

Using pre-transformed vertices bypasses vertex shaders, which
prevented some of the cg shaders to run correctly.
This commit is contained in:
OV2 2011-03-06 00:48:54 +01:00
parent 82fe0f7819
commit 8f63cb0cea
3 changed files with 64 additions and 28 deletions

View File

@ -284,10 +284,14 @@ bool CDirect3D::Initialize(HWND hWnd)
DXTRACE_ERR_MSGBOX(TEXT("Error setting cg device"), hr); DXTRACE_ERR_MSGBOX(TEXT("Error setting cg device"), hr);
} }
pDevice->SetRenderState(D3DRS_LIGHTING, FALSE);
pDevice->Clear(0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0, 0, 0), 1.0f, 0); pDevice->Clear(0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0, 0, 0), 1.0f, 0);
init_done = true; init_done = true;
SetViewport();
ApplyDisplayChanges(); ApplyDisplayChanges();
return true; return true;
@ -405,8 +409,25 @@ bool CDirect3D::SetShaderCG(const TCHAR *file)
} }
if(cgVertexProgram) { if(cgVertexProgram) {
hr = cgD3D9LoadProgram(cgVertexProgram,false,0); hr = cgD3D9LoadProgram(cgVertexProgram,true,0);
hr = cgD3D9BindProgram(cgVertexProgram); hr = cgD3D9BindProgram(cgVertexProgram);
D3DXMATRIX matWorld;
D3DXMATRIX matView;
D3DXMATRIX matProj;
D3DXMATRIX mvp;
pDevice->GetTransform(D3DTS_WORLD,&matWorld);
pDevice->GetTransform(D3DTS_VIEW,&matView);
pDevice->GetTransform(D3DTS_PROJECTION,&matProj);
mvp = matWorld * matView * matProj;
D3DXMatrixTranspose(&mvp,&mvp);
CGparameter cgpModelViewProj = cgGetNamedParameter(cgVertexProgram, "modelViewProj");
if(cgpModelViewProj)
cgD3D9SetUniformMatrix(cgpModelViewProj,&mvp);
} }
if(cgFragmentProgram) { if(cgFragmentProgram) {
hr = cgD3D9LoadProgram(cgFragmentProgram,false,0); hr = cgD3D9LoadProgram(cgFragmentProgram,false,0);
@ -613,7 +634,7 @@ void CDirect3D::SetShaderVars()
} }
} }
} else if(shader_type == D3D_SHADER_CG) { } else if(shader_type == D3D_SHADER_CG) {
D3DXMATRIX mvpMat;
D3DXVECTOR2 videoSize; D3DXVECTOR2 videoSize;
D3DXVECTOR2 textureSize; D3DXVECTOR2 textureSize;
D3DXVECTOR2 outputSize; D3DXVECTOR2 outputSize;
@ -623,13 +644,6 @@ void CDirect3D::SetShaderVars()
outputSize.x = GUI.Stretch?(float)dPresentParams.BackBufferWidth:(float)afterRenderWidth; outputSize.x = GUI.Stretch?(float)dPresentParams.BackBufferWidth:(float)afterRenderWidth;
outputSize.y = GUI.Stretch?(float)dPresentParams.BackBufferHeight:(float)afterRenderHeight; outputSize.y = GUI.Stretch?(float)dPresentParams.BackBufferHeight:(float)afterRenderHeight;
D3DXMatrixIdentity(&mvpMat);
CGparameter cgpModelViewProj = cgGetNamedParameter(cgVertexProgram, "modelViewProj");
if(cgpModelViewProj)
cgD3D9SetUniformMatrix(cgpModelViewProj,&mvpMat);
#define setProgramUniform(program,varname,floats)\ #define setProgramUniform(program,varname,floats)\
{\ {\
CGparameter cgp = cgGetNamedParameter(program, varname);\ CGparameter cgp = cgGetNamedParameter(program, varname);\
@ -703,11 +717,11 @@ void CDirect3D::Render(SSurface Src)
drawSurface->UnlockRect(0); drawSurface->UnlockRect(0);
} }
//if the output size of the render method changes we need new vertices //if the output size of the render method changes we need to update the viewport
if(afterRenderHeight != dstRect.bottom || afterRenderWidth != dstRect.right) { if(afterRenderHeight != dstRect.bottom || afterRenderWidth != dstRect.right) {
afterRenderHeight = dstRect.bottom; afterRenderHeight = dstRect.bottom;
afterRenderWidth = dstRect.right; afterRenderWidth = dstRect.right;
SetupVertices(); SetViewport();
} }
if(!GUI.Stretch||GUI.AspectRatio) if(!GUI.Stretch||GUI.AspectRatio)
@ -719,13 +733,13 @@ void CDirect3D::Render(SSurface Src)
pDevice->SetFVF(FVF_COORDS_TEX); pDevice->SetFVF(FVF_COORDS_TEX);
pDevice->SetStreamSource(0,vertexBuffer,0,sizeof(VERTEX)); pDevice->SetStreamSource(0,vertexBuffer,0,sizeof(VERTEX));
SetShaderVars();
if(shader_type == D3D_SHADER_CG) { if(shader_type == D3D_SHADER_CG) {
cgD3D9BindProgram(cgFragmentProgram); cgD3D9BindProgram(cgFragmentProgram);
cgD3D9BindProgram(cgVertexProgram); cgD3D9BindProgram(cgVertexProgram);
} }
SetShaderVars();
if (shader_type == D3D_SHADER_HLSL) { if (shader_type == D3D_SHADER_HLSL) {
UINT passes; UINT passes;
@ -839,26 +853,45 @@ calculates the vertex coordinates
*/ */
void CDirect3D::SetupVertices() void CDirect3D::SetupVertices()
{ {
RECT drawRect;
void *pLockedVertexBuffer; void *pLockedVertexBuffer;
drawRect = CalculateDisplayRect(afterRenderWidth,afterRenderHeight,dPresentParams.BackBufferWidth,dPresentParams.BackBufferHeight);
float tX = (float)afterRenderWidth / (float)quadTextureSize; float tX = (float)afterRenderWidth / (float)quadTextureSize;
float tY = (float)afterRenderHeight / (float)quadTextureSize; float tY = (float)afterRenderHeight / (float)quadTextureSize;
//we need to substract -0.5 from the x/y coordinates to match texture with pixel space triangleStripVertices[0] = VERTEX(0.0f,0.0f,0.0f,0.0f,tY);
//see http://msdn.microsoft.com/en-us/library/bb219690(VS.85).aspx triangleStripVertices[1] = VERTEX(0.0f,1.0f,0.0f,0.0f,0.0f);
triangleStripVertices[0] = VERTEX((float)drawRect.left - 0.5f,(float)drawRect.bottom - 0.5f,0.0f,1.0f,0.0f,tY); triangleStripVertices[2] = VERTEX(1.0f,0.0f,0.0f,tX,tY);
triangleStripVertices[1] = VERTEX((float)drawRect.left - 0.5f,(float)drawRect.top - 0.5f,0.0f,1.0f,0.0f,0.0f); triangleStripVertices[3] = VERTEX(1.0f,1.0f,0.0f,tX,0.0f);
triangleStripVertices[2] = VERTEX((float)drawRect.right - 0.5f,(float)drawRect.bottom - 0.5f,0.0f,1.0f,tX,tY);
triangleStripVertices[3] = VERTEX((float)drawRect.right - 0.5f,(float)drawRect.top - 0.5f,0.0f,1.0f,tX,0.0f);
HRESULT hr = vertexBuffer->Lock(0,0,&pLockedVertexBuffer,NULL); HRESULT hr = vertexBuffer->Lock(0,0,&pLockedVertexBuffer,NULL);
memcpy(pLockedVertexBuffer,triangleStripVertices,sizeof(triangleStripVertices)); memcpy(pLockedVertexBuffer,triangleStripVertices,sizeof(triangleStripVertices));
vertexBuffer->Unlock(); vertexBuffer->Unlock();
} }
void CDirect3D::SetViewport()
{
D3DXMATRIX matIdentity;
D3DXMATRIX matProjection;
D3DXMatrixOrthoOffCenterLH(&matProjection,0.0f,1.0f,0.0f,1.0f,0.0f,1.0f);
D3DXMatrixIdentity(&matIdentity);
pDevice->SetTransform(D3DTS_WORLD,&matIdentity);
pDevice->SetTransform(D3DTS_VIEW,&matIdentity);
pDevice->SetTransform(D3DTS_PROJECTION,&matProjection);
RECT drawRect = CalculateDisplayRect(afterRenderWidth,afterRenderHeight,dPresentParams.BackBufferWidth,dPresentParams.BackBufferHeight);
D3DVIEWPORT9 viewport;
viewport.X = drawRect.left;
viewport.Y = drawRect.top;
viewport.Height = drawRect.bottom - drawRect.top;
viewport.Width = drawRect.right - drawRect.left;
viewport.MinZ = 0.0f;
viewport.MaxZ = 1.0f;
HRESULT hr = pDevice->SetViewport(&viewport);
SetupVertices();
}
/* CDirect3D::ChangeRenderSize /* CDirect3D::ChangeRenderSize
determines if we need to reset the device (if the size changed) determines if we need to reset the device (if the size changed)
called with (0,0) whenever we want new settings to take effect called with (0,0) whenever we want new settings to take effect
@ -879,7 +912,8 @@ bool CDirect3D::ChangeRenderSize(unsigned int newWidth, unsigned int newHeight)
if(!ResetDevice()) if(!ResetDevice())
return false; return false;
SetupVertices();
SetViewport();
return true; return true;
} }
@ -938,6 +972,8 @@ bool CDirect3D::ResetDevice()
pDevice->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_POINT); pDevice->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
} }
pDevice->SetRenderState(D3DRS_LIGHTING, FALSE);
pDevice->Clear(0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0, 0, 0), 1.0f, 0); pDevice->Clear(0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0, 0, 0), 1.0f, 0);
//recreate the surface //recreate the surface

View File

@ -190,15 +190,14 @@
#include "wsnes9x.h" #include "wsnes9x.h"
#include "IS9xDisplayOutput.h" #include "IS9xDisplayOutput.h"
#define FVF_COORDS_TEX D3DFVF_XYZRHW | D3DFVF_TEX1 #define FVF_COORDS_TEX D3DFVF_XYZ | D3DFVF_TEX1
typedef struct _VERTEX { typedef struct _VERTEX {
float x, y, z; float x, y, z;
float rhw;
float tx, ty; float tx, ty;
_VERTEX() {} _VERTEX() {}
_VERTEX(float x,float y,float z,float rhw,float tx,float ty) { _VERTEX(float x,float y,float z,float tx,float ty) {
this->x=x;this->y=y;this->z=z;this->rhw=rhw;this->tx=tx;this->ty=ty; this->x=x;this->y=y;this->z=z;this->tx=tx;this->ty=ty;
} }
} VERTEX; //our custom vertex with a constuctor for easier assignment } VERTEX; //our custom vertex with a constuctor for easier assignment
@ -226,6 +225,7 @@ private:
CGcontext cgContext; CGcontext cgContext;
CGprogram cgVertexProgram, cgFragmentProgram; CGprogram cgVertexProgram, cgFragmentProgram;
current_d3d_shader_type shader_type; current_d3d_shader_type shader_type;
float shaderTimer; float shaderTimer;
int shaderTimeStart; int shaderTimeStart;
int shaderTimeElapsed; int shaderTimeElapsed;
@ -234,6 +234,7 @@ private:
void CreateDrawSurface(); void CreateDrawSurface();
void DestroyDrawSurface(); void DestroyDrawSurface();
bool ChangeDrawSurfaceSize(unsigned int scale); bool ChangeDrawSurfaceSize(unsigned int scale);
void SetViewport();
void SetupVertices(); void SetupVertices();
bool ResetDevice(); bool ResetDevice();
void SetShaderVars(); void SetShaderVars();

View File

@ -343,7 +343,6 @@ bool COpenGL::ApplyDisplayChanges(void)
RECT windowSize; RECT windowSize;
GetClientRect(hWnd,&windowSize); GetClientRect(hWnd,&windowSize);
ChangeRenderSize(windowSize.right,windowSize.bottom); ChangeRenderSize(windowSize.right,windowSize.bottom);
SetupVertices();
return true; return true;
} }