Uniforms/constants aren't shared in D3D, let's not pretend they are.

This commit is contained in:
Henrik Rydgard 2014-09-10 12:40:15 +02:00
parent 6fa1872163
commit 14c8733def
2 changed files with 200 additions and 185 deletions

View File

@ -65,9 +65,16 @@ PSShader::PSShader(const char *code, bool useHWTransform) : failed_(false), useH
if (shader)
shader->Release();
shader = NULL;
return;
} else {
DEBUG_LOG(G3D, "Compiled shader:\n%s\n", (const char *)code);
}
u_tex = GetConstantByName("tex");
u_texenv = GetConstantByName("u_texenv");
u_fogcolor = GetConstantByName("u_fogcolor");
u_alphacolorref = GetConstantByName("u_alphacolorref");
u_alphacolormask = GetConstantByName("u_alphacolormask");
}
PSShader::~PSShader() {
@ -78,7 +85,7 @@ PSShader::~PSShader() {
shader->Release();
}
VSShader::VSShader(const char *code, bool useHWTransform) : failed_(false), useHWTransform_(useHWTransform) {
VSShader::VSShader(const char *code, int vertType, bool useHWTransform) : failed_(false), useHWTransform_(useHWTransform) {
source_ = code;
#ifdef SHADERLOG
OutputDebugString(ConvertUTF8ToWString(code).c_str());
@ -106,49 +113,19 @@ VSShader::VSShader(const char *code, bool useHWTransform) : failed_(false), useH
if (shader)
shader->Release();
shader = NULL;
return;
} else {
DEBUG_LOG(G3D, "Compiled shader:\n%s\n", (const char *)code);
}
}
VSShader::~VSShader() {
pD3Ddevice->SetVertexShader(NULL);
if (constant)
constant->Release();
if (shader)
shader->Release();
}
// Helper
D3DXHANDLE LinkedShaderDX9::GetConstantByName(LPCSTR pName) {
D3DXHANDLE ret = NULL;
if ((ret = m_fs->constant->GetConstantByName(NULL, pName)) != NULL) {
} else if ((ret = m_vs->constant->GetConstantByName(NULL, pName)) != NULL) {}
return ret;
}
LinkedShaderDX9::LinkedShaderDX9(VSShader *vs, PSShader *fs, u32 vertType, bool useHWTransform)
:dirtyUniforms(0), useHWTransform_(useHWTransform) {
INFO_LOG(G3D, "Linked shader: vs %i fs %i", (int)vs->shader, (int)fs->shader);
m_vs = vs;
m_fs = fs;
u_tex = GetConstantByName("tex");
u_proj = GetConstantByName("u_proj");
u_proj_through = GetConstantByName("u_proj_through");
u_texenv = GetConstantByName("u_texenv");
u_fogcolor = GetConstantByName("u_fogcolor");
u_fogcoef = GetConstantByName("u_fogcoef");
u_alphacolorref = GetConstantByName("u_alphacolorref");
u_alphacolormask = GetConstantByName("u_alphacolormask");
u_proj = GetConstantByName("u_proj");
u_proj_through = GetConstantByName("u_proj_through");
// Transform
u_view = GetConstantByName("u_view");
u_world = GetConstantByName("u_world");
u_texmtx = GetConstantByName("u_texmtx");
u_view = GetConstantByName("u_view");
u_world = GetConstantByName("u_world");
u_texmtx = GetConstantByName("u_texmtx");
u_fogcoef = GetConstantByName("u_fogcoef");
if (vertTypeGetWeightMask(vertType) != 0)
numBones = TranslateNumBonesDX9(vertTypeGetNumBoneWeights(vertType));
@ -166,12 +143,12 @@ LinkedShaderDX9::LinkedShaderDX9(VSShader *vs, PSShader *fs, u32 vertType, bool
#endif
// Lighting, texturing
u_ambient = GetConstantByName("u_ambient");
u_ambient = GetConstantByName("u_ambient");
u_matambientalpha = GetConstantByName("u_matambientalpha");
u_matdiffuse = GetConstantByName("u_matdiffuse");
u_matspecular = GetConstantByName("u_matspecular");
u_matemissive = GetConstantByName("u_matemissive");
u_uvscaleoffset = GetConstantByName("u_uvscaleoffset");
u_matdiffuse = GetConstantByName("u_matdiffuse");
u_matspecular = GetConstantByName("u_matspecular");
u_matemissive = GetConstantByName("u_matemissive");
u_uvscaleoffset = GetConstantByName("u_uvscaleoffset");
for (int i = 0; i < 4; i++) {
char temp[64];
@ -192,6 +169,34 @@ LinkedShaderDX9::LinkedShaderDX9(VSShader *vs, PSShader *fs, u32 vertType, bool
sprintf(temp, "u_lightspecular%i", i);
u_lightspecular[i] = GetConstantByName(temp);
}
}
VSShader::~VSShader() {
pD3Ddevice->SetVertexShader(NULL);
if (constant)
constant->Release();
if (shader)
shader->Release();
}
// Helper
D3DXHANDLE PSShader::GetConstantByName(LPCSTR pName) {
return constant->GetConstantByName(NULL, pName);
}
// Helper
D3DXHANDLE VSShader::GetConstantByName(LPCSTR pName) {
return constant->GetConstantByName(NULL, pName);
}
LinkedShaderDX9::LinkedShaderDX9(VSShader *vs, PSShader *fs, u32 vertType, bool useHWTransform)
:dirtyUniforms(0), useHWTransform_(useHWTransform) {
INFO_LOG(G3D, "Linked shader: vs %i fs %i", (int)vs->shader, (int)fs->shader);
m_vs = vs;
m_fs = fs;
//glUseProgram(program);
@ -209,21 +214,21 @@ LinkedShaderDX9::~LinkedShaderDX9() {
// glDeleteProgram(program);
}
void LinkedShaderDX9::SetFloatArray(D3DXHANDLE uniform, const float* pArray, int len) {
if (m_fs->constant->SetFloatArray(pD3Ddevice, uniform, pArray, len) == D3D_OK);
else
m_vs->constant->SetFloatArray(pD3Ddevice, uniform, pArray, len);
void VSShader::SetFloatArray(D3DXHANDLE uniform, const float* pArray, int len) {
constant->SetFloatArray(pD3Ddevice, uniform, pArray, len);
}
void LinkedShaderDX9::SetFloat(D3DXHANDLE uniform, float value) {
if (m_fs->constant->SetFloat(pD3Ddevice, uniform, value) == D3D_OK);
else
m_vs->constant->SetFloat(pD3Ddevice, uniform, value);
void PSShader::SetFloatArray(D3DXHANDLE uniform, const float* pArray, int len) {
constant->SetFloatArray(pD3Ddevice, uniform, pArray, len);
}
void VSShader::SetFloat(D3DXHANDLE uniform, float value) {
constant->SetFloat(pD3Ddevice, uniform, value);
}
// Utility
void LinkedShaderDX9::SetColorUniform3(D3DXHANDLE uniform, u32 color) {
void VSShader::SetColorUniform3(D3DXHANDLE uniform, u32 color) {
const float col[4] = {
((color & 0xFF)) / 255.0f,
((color & 0xFF00) >> 8) / 255.0f,
@ -232,14 +237,23 @@ void LinkedShaderDX9::SetColorUniform3(D3DXHANDLE uniform, u32 color) {
SetFloatArray(uniform, col, 4);
}
void LinkedShaderDX9::SetFloat24Uniform3(D3DXHANDLE uniform, const u32 data[3]) {
void PSShader::SetColorUniform3(D3DXHANDLE uniform, u32 color) {
const float col[4] = {
((color & 0xFF)) / 255.0f,
((color & 0xFF00) >> 8) / 255.0f,
((color & 0xFF0000) >> 16) / 255.0f
};
SetFloatArray(uniform, col, 4);
}
void VSShader::SetFloat24Uniform3(D3DXHANDLE uniform, const u32 data[3]) {
const u32 col[4] = {
data[0] >> 8, data[1] >> 8, data[2] >> 8,
};
SetFloatArray(uniform, (const float *)&col[0], 4);
}
void LinkedShaderDX9::SetColorUniform3Alpha(D3DXHANDLE uniform, u32 color, u8 alpha) {
void VSShader::SetColorUniform3Alpha(D3DXHANDLE uniform, u32 color, u8 alpha) {
const float col[4] = {
((color & 0xFF)) / 255.0f,
((color & 0xFF00) >> 8) / 255.0f,
@ -249,7 +263,7 @@ void LinkedShaderDX9::SetColorUniform3Alpha(D3DXHANDLE uniform, u32 color, u8 al
SetFloatArray(uniform, col, 4);
}
void LinkedShaderDX9::SetColorUniform3Alpha255(D3DXHANDLE uniform, u32 color, u8 alpha) {
void PSShader::SetColorUniform3Alpha255(D3DXHANDLE uniform, u32 color, u8 alpha) {
const float col[4] = {
(float)((color & 0xFF)),
(float)((color & 0xFF00) >> 8),
@ -259,7 +273,7 @@ void LinkedShaderDX9::SetColorUniform3Alpha255(D3DXHANDLE uniform, u32 color, u8
SetFloatArray(uniform, col, 4);
}
void LinkedShaderDX9::SetColorUniform3ExtraFloat(D3DXHANDLE uniform, u32 color, float extra) {
void VSShader::SetColorUniform3ExtraFloat(D3DXHANDLE uniform, u32 color, float extra) {
const float col[4] = {
((color & 0xFF)) / 255.0f,
((color & 0xFF00) >> 8) / 255.0f,
@ -270,15 +284,15 @@ void LinkedShaderDX9::SetColorUniform3ExtraFloat(D3DXHANDLE uniform, u32 color,
}
// Utility
void LinkedShaderDX9::SetMatrix4x3(D3DXHANDLE uniform, const float *m4x3) {
void VSShader::SetMatrix4x3(D3DXHANDLE uniform, const float *m4x3) {
float m4x4[16];
ConvertMatrix4x3To4x4(m4x4, m4x3);
m_vs->constant->SetMatrix(pD3Ddevice, uniform, (D3DXMATRIX*)m4x4);
constant->SetMatrix(pD3Ddevice, uniform, (D3DXMATRIX*)m4x4);
}
void LinkedShaderDX9::SetMatrix(D3DXHANDLE uniform, const float* pMatrix) {
void VSShader::SetMatrix(D3DXHANDLE uniform, const float* pMatrix) {
D3DXMATRIX * pDxMat = (D3DXMATRIX*)pMatrix;
m_vs->constant->SetMatrix(pD3Ddevice, uniform, pDxMat);
constant->SetMatrix(pD3Ddevice, uniform, pDxMat);
}
// Depth in ogl is between -1;1 we need between 0;1 and optionally reverse it
@ -290,6 +304,14 @@ void ConvertProjMatrixToD3D(Matrix4x4 & in, bool invert) {
in = in * s * t;
}
void LinkedShaderDX9::updateUniforms() {
if (dirtyUniforms) {
m_fs->updateUniforms(dirtyUniforms);
m_vs->updateUniforms(dirtyUniforms);
dirtyUniforms = 0;
}
}
void LinkedShaderDX9::use() {
updateUniforms();
@ -297,14 +319,22 @@ void LinkedShaderDX9::use() {
pD3Ddevice->SetVertexShader(m_vs->shader);
}
void LinkedShaderDX9::stop() {
void PSShader::updateUniforms(int dirtyUniforms) {
if (u_texenv != 0 && (dirtyUniforms & DIRTY_TEXENV)) {
SetColorUniform3(u_texenv, gstate.texenvcolor);
}
if (u_alphacolorref != 0 && (dirtyUniforms & DIRTY_ALPHACOLORREF)) {
SetColorUniform3Alpha255(u_alphacolorref, gstate.getColorTestRef(), gstate.getAlphaTestRef());
}
if (u_alphacolormask != 0 && (dirtyUniforms & DIRTY_ALPHACOLORMASK)) {
SetColorUniform3(u_alphacolormask, gstate.colortestmask);
}
if (u_fogcolor != 0 && (dirtyUniforms & DIRTY_FOGCOLOR)) {
SetColorUniform3(u_fogcolor, gstate.fogcolor);
}
}
void LinkedShaderDX9::updateUniforms() {
if (!dirtyUniforms)
return;
void VSShader::updateUniforms(int dirtyUniforms) {
// Update any dirty uniforms before we draw
if (u_proj != 0 && (dirtyUniforms & DIRTY_PROJMATRIX)) {
Matrix4x4 flippedMatrix;
@ -323,8 +353,7 @@ void LinkedShaderDX9::updateUniforms() {
SetMatrix(u_proj, flippedMatrix.getReadPtr());
}
if (u_proj_through != 0 && (dirtyUniforms & DIRTY_PROJTHROUGHMATRIX))
{
if (u_proj_through != 0 && (dirtyUniforms & DIRTY_PROJTHROUGHMATRIX)) {
Matrix4x4 proj_through;
proj_through.setOrtho(0.0f, gstate_c.curRTWidth, gstate_c.curRTHeight, 0, 0, 1);
@ -332,57 +361,6 @@ void LinkedShaderDX9::updateUniforms() {
SetMatrix(u_proj_through, proj_through.getReadPtr());
}
if (u_texenv != 0 && (dirtyUniforms & DIRTY_TEXENV)) {
SetColorUniform3(u_texenv, gstate.texenvcolor);
}
if (u_alphacolorref != 0 && (dirtyUniforms & DIRTY_ALPHACOLORREF)) {
SetColorUniform3Alpha255(u_alphacolorref, gstate.getColorTestRef(), gstate.getAlphaTestRef());
}
if (u_alphacolormask != 0 && (dirtyUniforms & DIRTY_ALPHACOLORMASK)) {
SetColorUniform3(u_alphacolormask, gstate.colortestmask);
}
if (u_fogcolor != 0 && (dirtyUniforms & DIRTY_FOGCOLOR)) {
SetColorUniform3(u_fogcolor, gstate.fogcolor);
}
if (u_fogcoef != 0 && (dirtyUniforms & DIRTY_FOGCOEF)) {
const float fogcoef[2] = {
getFloat24(gstate.fog1),
getFloat24(gstate.fog2),
};
SetFloatArray(u_fogcoef, fogcoef, 2);
}
// Texturing
if (u_uvscaleoffset != 0 && (dirtyUniforms & DIRTY_UVSCALEOFFSET)) {
float uvscaleoff[4];
if (gstate.isModeThrough()) {
// We never get here because we don't use HW transform with through mode.
// Although - why don't we?
uvscaleoff[0] = gstate_c.uv.uScale / gstate_c.curTextureWidth;
uvscaleoff[1] = gstate_c.uv.vScale / gstate_c.curTextureHeight;
uvscaleoff[2] = gstate_c.uv.uOff / gstate_c.curTextureWidth;
uvscaleoff[3] = gstate_c.uv.vOff / gstate_c.curTextureHeight;
} else {
int w = gstate.getTextureWidth(0);
int h = gstate.getTextureHeight(0);
float widthFactor = (float)w / (float)gstate_c.curTextureWidth;
float heightFactor = (float)h / (float)gstate_c.curTextureHeight;
// Not sure what GE_TEXMAP_UNKNOWN is, but seen in Riviera. Treating the same as GE_TEXMAP_TEXTURE_COORDS works.
if (gstate.getUVGenMode() == GE_TEXMAP_TEXTURE_COORDS || gstate.getUVGenMode() == GE_TEXMAP_UNKNOWN) {
uvscaleoff[0] = gstate_c.uv.uScale * widthFactor;
uvscaleoff[1] = gstate_c.uv.vScale * heightFactor;
uvscaleoff[2] = gstate_c.uv.uOff * widthFactor;
uvscaleoff[3] = gstate_c.uv.vOff * heightFactor;
} else {
uvscaleoff[0] = widthFactor;
uvscaleoff[1] = heightFactor;
uvscaleoff[2] = 0.0f;
uvscaleoff[3] = 0.0f;
}
}
SetFloatArray(u_uvscaleoffset, uvscaleoff, 4);
}
// Transform
if (u_world != 0 && (dirtyUniforms & DIRTY_WORLDMATRIX)) {
SetMatrix4x3(u_world, gstate.worldMatrix);
@ -393,7 +371,13 @@ void LinkedShaderDX9::updateUniforms() {
if (u_texmtx != 0 && (dirtyUniforms & DIRTY_TEXMATRIX)) {
SetMatrix4x3(u_texmtx, gstate.tgenMatrix);
}
if (u_fogcoef != 0 && (dirtyUniforms & DIRTY_FOGCOEF)) {
const float fogcoef[2] = {
getFloat24(gstate.fog1),
getFloat24(gstate.fog2),
};
SetFloatArray(u_fogcoef, fogcoef, 2);
}
// TODO: Could even set all bones in one go if they're all dirty.
#ifdef USE_BONE_ARRAY
if (u_bone != 0) {
@ -431,6 +415,37 @@ void LinkedShaderDX9::updateUniforms() {
}
#endif
// Texturing
if (u_uvscaleoffset != 0 && (dirtyUniforms & DIRTY_UVSCALEOFFSET)) {
float uvscaleoff[4];
if (gstate.isModeThrough()) {
// We never get here because we don't use HW transform with through mode.
// Although - why don't we?
uvscaleoff[0] = gstate_c.uv.uScale / gstate_c.curTextureWidth;
uvscaleoff[1] = gstate_c.uv.vScale / gstate_c.curTextureHeight;
uvscaleoff[2] = gstate_c.uv.uOff / gstate_c.curTextureWidth;
uvscaleoff[3] = gstate_c.uv.vOff / gstate_c.curTextureHeight;
} else {
int w = gstate.getTextureWidth(0);
int h = gstate.getTextureHeight(0);
float widthFactor = (float)w / (float)gstate_c.curTextureWidth;
float heightFactor = (float)h / (float)gstate_c.curTextureHeight;
// Not sure what GE_TEXMAP_UNKNOWN is, but seen in Riviera. Treating the same as GE_TEXMAP_TEXTURE_COORDS works.
if (gstate.getUVGenMode() == GE_TEXMAP_TEXTURE_COORDS || gstate.getUVGenMode() == GE_TEXMAP_UNKNOWN) {
uvscaleoff[0] = gstate_c.uv.uScale * widthFactor;
uvscaleoff[1] = gstate_c.uv.vScale * heightFactor;
uvscaleoff[2] = gstate_c.uv.uOff * widthFactor;
uvscaleoff[3] = gstate_c.uv.vOff * heightFactor;
} else {
uvscaleoff[0] = widthFactor;
uvscaleoff[1] = heightFactor;
uvscaleoff[2] = 0.0f;
uvscaleoff[3] = 0.0f;
}
}
SetFloatArray(u_uvscaleoffset, uvscaleoff, 4);
}
// Lighting
if (u_ambient != 0 && (dirtyUniforms & DIRTY_AMBIENT)) {
SetColorUniform3Alpha(u_ambient, gstate.ambientcolor, gstate.getAmbientA());
@ -475,8 +490,6 @@ void LinkedShaderDX9::updateUniforms() {
if (u_lightspecular[i] != 0) SetColorUniform3(u_lightspecular[i], gstate.lcolor[i * 3 + 2]);
}
}
dirtyUniforms = 0;
}
ShaderManagerDX9::ShaderManagerDX9() : lastShader_(NULL), globalDirty_(0xFFFFFFFF), shaderSwitchDirty_(0) {
@ -521,8 +534,6 @@ void ShaderManagerDX9::DirtyShader() {
}
void ShaderManagerDX9::DirtyLastShader() { // disables vertex arrays
if (lastShader_)
lastShader_->stop();
lastShader_ = 0;
}
@ -548,11 +559,6 @@ LinkedShaderDX9 *ShaderManagerDX9::ApplyShader(int prim, u32 vertType) {
return lastShader_; // Already all set.
}
if (lastShader_ != 0) {
// There was a previous shader and we're switching.
lastShader_->stop();
}
lastVSID_ = VSID;
lastFSID_ = FSID;
@ -561,7 +567,7 @@ LinkedShaderDX9 *ShaderManagerDX9::ApplyShader(int prim, u32 vertType) {
if (vsIter == vsCache_.end()) {
// Vertex shader not in cache. Let's compile it.
GenerateVertexShaderDX9(prim, codeBuffer_, useHWTransform);
vs = new VSShader(codeBuffer_, useHWTransform);
vs = new VSShader(codeBuffer_, vertType, useHWTransform);
if (vs->Failed()) {
ERROR_LOG(HLE, "Shader compilation failed, falling back to software transform");
@ -574,7 +580,7 @@ LinkedShaderDX9 *ShaderManagerDX9::ApplyShader(int prim, u32 vertType) {
// Can still work with software transform.
GenerateVertexShaderDX9(prim, codeBuffer_, false);
vs = new VSShader(codeBuffer_, false);
vs = new VSShader(codeBuffer_, vertType, false);
}
vsCache_[VSID] = vs;

View File

@ -46,26 +46,12 @@ enum {
class LinkedShaderDX9
{
protected:
// Helper
D3DXHANDLE GetConstantByName(LPCSTR pName);
void SetMatrix4x3(D3DXHANDLE uniform, const float *m4x3);
void SetColorUniform3(D3DXHANDLE uniform, u32 color);
void SetColorUniform3ExtraFloat(D3DXHANDLE uniform, u32 color, float extra);
void SetColorUniform3Alpha(D3DXHANDLE uniform, u32 color, u8 alpha);
void SetColorUniform3Alpha255(D3DXHANDLE uniform, u32 color, u8 alpha);
void SetMatrix(D3DXHANDLE uniform, const float* pMatrix);
void SetFloatArray(D3DXHANDLE uniform, const float* pArray, int len);
void SetFloat(D3DXHANDLE uniform, float value);
void SetFloat24Uniform3(D3DXHANDLE uniform, const u32 data[3]);
public:
LinkedShaderDX9(VSShader *vs, PSShader *fs, u32 vertType, bool useHWTransform);
~LinkedShaderDX9();
void use();
void stop();
void updateUniforms();
void use();
// Set to false if the VS failed, happens on Mali-400 a lot for complex shaders.
bool useHWTransform_;
@ -86,44 +72,6 @@ public:
D3DXHANDLE a_normal;
D3DXHANDLE a_weight0123;
D3DXHANDLE a_weight4567;
D3DXHANDLE u_tex;
D3DXHANDLE u_proj;
D3DXHANDLE u_proj_through;
D3DXHANDLE u_texenv;
D3DXHANDLE u_view;
D3DXHANDLE u_texmtx;
D3DXHANDLE u_world;
#ifdef USE_BONE_ARRAY
D3DXHANDLE u_bone; // array, size is numBones
#else
D3DXHANDLE u_bone[8];
#endif
int numBones;
// Fragment processing inputs
D3DXHANDLE u_alphacolorref;
D3DXHANDLE u_alphacolormask;
D3DXHANDLE u_fogcolor;
D3DXHANDLE u_fogcoef;
// Texturing
D3DXHANDLE u_uvscaleoffset;
// Lighting
D3DXHANDLE u_ambient;
D3DXHANDLE u_matambientalpha;
D3DXHANDLE u_matdiffuse;
D3DXHANDLE u_matspecular;
D3DXHANDLE u_matemissive;
D3DXHANDLE u_lightpos[4];
D3DXHANDLE u_lightdir[4];
D3DXHANDLE u_lightatt[4]; // attenuation
D3DXHANDLE u_lightangle[4]; // spotlight cone angle (cosine)
D3DXHANDLE u_lightspotCoef[4]; // spotlight dropoff
D3DXHANDLE u_lightdiffuse[4]; // each light consist of vec4[3]
D3DXHANDLE u_lightspecular[4]; // attenuation
D3DXHANDLE u_lightambient[4]; // attenuation
};
// Will reach 32 bits soon :P
@ -177,17 +125,33 @@ public:
bool Failed() const { return failed_; }
bool UseHWTransform() const { return useHWTransform_; }
void updateUniforms(int dirtyUniforms);
void SetFloatArray(D3DXHANDLE uniform, const float* pArray, int len);
void SetColorUniform3Alpha255(D3DXHANDLE uniform, u32 color, u8 alpha);
void SetColorUniform3(D3DXHANDLE uniform, u32 color);
D3DXHANDLE GetConstantByName(LPCSTR pName);
LPDIRECT3DPIXELSHADER9 shader;
LPD3DXCONSTANTTABLE constant;
protected:
std::string source_;
bool failed_;
bool useHWTransform_;
D3DXHANDLE u_tex;
D3DXHANDLE u_texenv;
// Fragment processing inputs
D3DXHANDLE u_alphacolorref;
D3DXHANDLE u_alphacolormask;
D3DXHANDLE u_fogcolor;
};
class VSShader {
public:
VSShader(const char *code, bool useHWTransform);
VSShader(const char *code, int vertType, bool useHWTransform);
~VSShader();
const std::string &source() const { return source_; }
@ -195,12 +159,57 @@ public:
bool Failed() const { return failed_; }
bool UseHWTransform() const { return useHWTransform_; }
void updateUniforms(int dirtyUniforms);
void SetMatrix4x3(D3DXHANDLE uniform, const float *m4x3);
void SetColorUniform3(D3DXHANDLE uniform, u32 color);
void SetColorUniform3ExtraFloat(D3DXHANDLE uniform, u32 color, float extra);
void SetColorUniform3Alpha(D3DXHANDLE uniform, u32 color, u8 alpha);
void SetMatrix(D3DXHANDLE uniform, const float* pMatrix);
void SetFloatArray(D3DXHANDLE uniform, const float* pArray, int len);
void SetFloat(D3DXHANDLE uniform, float value);
void SetFloat24Uniform3(D3DXHANDLE uniform, const u32 data[3]);
D3DXHANDLE GetConstantByName(LPCSTR pName);
LPDIRECT3DVERTEXSHADER9 shader;
LPD3DXCONSTANTTABLE constant;
protected:
std::string source_;
bool failed_;
bool useHWTransform_;
// Transform
D3DXHANDLE u_view;
D3DXHANDLE u_texmtx;
D3DXHANDLE u_world;
D3DXHANDLE u_proj;
D3DXHANDLE u_proj_through;
#ifdef USE_BONE_ARRAY
D3DXHANDLE u_bone; // array, size is numBones
#else
D3DXHANDLE u_bone[8];
#endif
int numBones;
D3DXHANDLE u_fogcoef;
// Texturing
D3DXHANDLE u_uvscaleoffset;
// Lighting
D3DXHANDLE u_ambient;
D3DXHANDLE u_matambientalpha;
D3DXHANDLE u_matdiffuse;
D3DXHANDLE u_matspecular;
D3DXHANDLE u_matemissive;
D3DXHANDLE u_lightpos[4];
D3DXHANDLE u_lightdir[4];
D3DXHANDLE u_lightatt[4]; // attenuation
D3DXHANDLE u_lightangle[4]; // spotlight cone angle (cosine)
D3DXHANDLE u_lightspotCoef[4]; // spotlight dropoff
D3DXHANDLE u_lightdiffuse[4]; // each light consist of vec4[3]
D3DXHANDLE u_lightspecular[4]; // attenuation
D3DXHANDLE u_lightambient[4]; // attenuation
};
class ShaderManagerDX9