//
// DXVertexShader.cpp
//
// Class to encapsulate a DX Vertex shader program
//
// Copyright 2005 Paul Higinbotham
//
#include "stdafx.h"
#include "DXVertexShader.h"
#include "DXDefines.h"
#include <stdio.h>
#include "..\..\collections\String.h"
using namespace ZGraphics;
// Private constructor. Can only create this object through the static creation method (CreateShader).
DXVertexShader::DXVertexShader()
{
m_pRenderer = 0;
m_pVertexShaderBuffer = 0;
m_pVSConstantTable = 0;
m_pVertexShader = 0;
}
DXVertexShader::~DXVertexShader()
{
m_pRenderer = 0;
SAFE_RELEASE(m_pVertexShaderBuffer);
SAFE_RELEASE(m_pVSConstantTable);
SAFE_RELEASE(m_pVertexShader);
}
// Static creation method
DXVertexShader * DXVertexShader::CreateShader(const char * szFileName, const char * szFuncName, IRenderer * pRenderer)
{
DXVertexShader * pVSShader = new DXVertexShader();
assert(pVSShader);
if ( pVSShader->_compileShader(szFileName, szFuncName, pRenderer) )
{
return pVSShader;
}
else
{
delete pVSShader;
return 0;
}
}
void DXVertexShader::SetCTMatrix(const char * szMatrixName, const Matrix4f & Matrix)
{
m_pRenderer->SetCTableMatrix(m_pVSConstantTable, szMatrixName, Matrix);
}
void DXVertexShader::SetCTVector(const char * szVectorName, const Vector4f & Vector)
{
m_pRenderer->SetCTableVector(m_pVSConstantTable, szVectorName, Vector);
}
void DXVertexShader::SetCTFloat(const char * szScalarName, float fScalar)
{
m_pRenderer->SetCTableFloat(m_pVSConstantTable, szScalarName, fScalar);
}
bool DXVertexShader::SetShader()
{
HRESULT hr = m_pRenderer->SetVertexShader(m_pVertexShader);
return (SUCCEEDED(hr));
}
void DXVertexShader::RemoveShader()
{
m_pRenderer->SetVertexShader(NULL);
}
void DXVertexShader::ReleaseShader()
{
SAFE_RELEASE(m_pVertexShader);
}
bool DXVertexShader::ReCreateShader(IRenderer * pRenderer)
{
//assert(m_pVertexShader); // Shouldn't create a shader if one already exists.
if (m_pVertexShader)
return true;
HRESULT hr = m_pRenderer->CreateVertexShader((DWORD *)m_pVertexShaderBuffer->GetBufferPointer(), &m_pVertexShader);
if (SUCCEEDED(hr))
return SetShader();
else
return false;
}
//
// Private internal method functions
//
bool DXVertexShader::_compileShader(const char * szFileName, const char * szFuncName, IRenderer * pRenderer)
{
assert(szFileName && szFuncName && pRenderer);
m_pRenderer = pRenderer;
// Compile vertex shader into shader buffer
bool bSucceeded = true;
LPD3DXBUFFER pErrorMsgs = 0;
LPCSTR szShaderProfile = m_pRenderer->GetVertexShaderProfile();
HRESULT hr;
hr = m_pRenderer->CompileShaderFromFile(szFileName, NULL, NULL, szFuncName, szShaderProfile, 0,
&m_pVertexShaderBuffer, &pErrorMsgs, &m_pVSConstantTable);
if (!SUCCEEDED(hr))
{
char szCurrDirectory[150];
char szMessage[256];
szCurrDirectory[0] = '\0';
szMessage[0] = '\0';
::GetCurrentDirectory(150, szCurrDirectory);
if (pErrorMsgs)
{
const unsigned char * pMsgs = (const unsigned char *)pErrorMsgs->GetBufferPointer();
sprintf(szMessage, "Unable to compile the vertex shader, %s, FilePath: %s\\%s, Func Name: %s, ShaderProfile: %s",
pMsgs, szCurrDirectory, szFileName, szFuncName, szShaderProfile);
}
else
{
sprintf(szMessage, "Unable to compile the vertex shader, error: %x, FilePath: %s\\%s, Func Name: %s, ShaderProfile: %s",
hr, szCurrDirectory, szFileName, szFuncName, szShaderProfile);
}
MessageBox(NULL, szMessage, "Shader Error", MB_ICONERROR | MB_OK);
bSucceeded = false;
}
SAFE_RELEASE(pErrorMsgs);
if (bSucceeded)
{
hr = m_pRenderer->CreateVertexShader((DWORD *)m_pVertexShaderBuffer->GetBufferPointer(), &m_pVertexShader);
bSucceeded = SUCCEEDED(hr);
}
if (!bSucceeded)
{
SAFE_RELEASE(m_pVertexShaderBuffer);
SAFE_RELEASE(m_pVSConstantTable);
SAFE_RELEASE(m_pVertexShader);
}
return bSucceeded;
}