GL3: Further refactor

--HG--
branch : opengl3
hg/feature/opengl3
kaetemi 11 years ago
parent a13d39e9f4
commit 5002eea62a

@ -317,7 +317,7 @@ bool CDriverGL3::setupMaterial(CMaterial& mat)
}
// Optimize: reset all flags at the end.
mat.clearTouched(0xFFFFFFFF);
// mat.clearTouched(0xFFFFFFFF); // FIXME GL3 THIS IS NOW DONE IN GENERATE OF PP DESC, THIS NEED RESTRUCTURING
}
// 2b. User supplied pixel shader overrides material

@ -31,9 +31,52 @@ namespace NL3D {
namespace NLDRIVERGL3 {
#endif
namespace /* anonymous */ {
CMaterial::TShader getSupportedShader(CMaterial::TShader shader)
{
switch (shader)
{
case CMaterial::UserColor:
case CMaterial::Normal:
case CMaterial::Specular:
return shader;
default:
return CMaterial::Normal;
}
}
uint maxTextures(CMaterial::TShader shader)
{
switch (shader)
{
case CMaterial::Specular:
return 2;
default:
return IDRV_MAT_MAXTEXTURES;
}
}
bool useTexEnv(CMaterial::TShader shader)
{
return shader == CMaterial::Normal
|| shader == CMaterial::UserColor;
}
} /* anonymous namespace */
bool operator<(const CPPBuiltin &left, const CPPBuiltin &right)
{
// Material state
if (left.Shader != right.Shader)
return left.Shader < right.Shader;
if (left.TextureActive != right.TextureActive)
return left.TextureActive < right.TextureActive;
uint maxTex = maxTextures(left.Shader);
if (useTexEnv(left.Shader))
for (uint stage = 0; stage < maxTex; ++stage)
if (left.TexEnvMode[stage] != right.TexEnvMode[stage])
return left.TexEnvMode[stage] < right.TexEnvMode[stage];
// Driver state
if (left.VertexFormat != right.VertexFormat)
@ -45,7 +88,219 @@ bool operator<(const CPPBuiltin &left, const CPPBuiltin &right)
}
namespace /* anonymous */ {
bool useTex(CPPBuiltin &desc, uint stage)
{
return (desc.TextureActive & (1 << stage)) != 0;
}
void ppTexEnv(std::stringstream &ss, CPPBuiltin &desc)
{
uint maxTex = maxTextures(desc.Shader);
CMaterial::CTexEnv texEnv;
for (uint stage = 0; stage < maxTex; ++stage)
{
if (useTex(desc, stage))
{
texEnv.EnvPacked = desc.TexEnvMode[stage];
for (uint arg = 0; arg < 3; ++arg)
{
// Texop arg
ss << "vec4 texop" << stage << "arg" << arg << ";" << std::endl;
// RGB
uint rgbArg = texEnv.getColorArg(arg);
uint rgbOp = texEnv.getColorOperand(arg);
std::stringstream rgbArgVec;
switch (rgbArg)
{
case CMaterial::Texture:
rgbArgVec << "texel" << stage;
break;
case CMaterial::Previous:
if (stage > 0)
{
rgbArgVec << "texop" << (stage - 1);
break;
}
case CMaterial::Diffuse:
rgbArgVec << "diffuse";
break;
case CMaterial::Constant:
rgbArgVec << "constant" << stage;
break;
}
ss << "texop" << stage << "arg" << arg << ".rgb = ";
switch (rgbOp) // SrcColor=0, InvSrcColor, SrcAlpha, InvSrcAlpha
{
case CMaterial::SrcColor:
ss << rgbArgVec.str() << ".rgb";
break;
case CMaterial::InvSrcColor:
ss << "vec3(1.0, 1.0, 1.0) - " << rgbArgVec.str() << ".rgb";
break;
case CMaterial::SrcAlpha:
ss << rgbArgVec.str() << ".aaa";
break;
case CMaterial::InvSrcAlpha:
ss << "(1.0 - " << rgbArgVec.str() << ").aaa";
break;
}
ss << ";" << std::endl;
// Alpha
uint alphaArg = texEnv.getAlphaArg(arg);
uint alphaOp = texEnv.getAlphaOperand(arg);
std::stringstream alphaArgVec;
switch (alphaArg)
{
case CMaterial::Texture:
alphaArgVec << "texel" << stage;
break;
case CMaterial::Previous:
if (stage > 0)
{
alphaArgVec << "texop" << (stage - 1);
break;
}
case CMaterial::Diffuse:
alphaArgVec << "diffuse";
break;
case CMaterial::Constant:
alphaArgVec << "constant" << stage;
break;
}
ss << "texop" << stage << "arg" << arg << ".a = ";
switch (alphaOp) // SrcColor=0, InvSrcColor, SrcAlpha, InvSrcAlpha
{
case CMaterial::SrcColor:
ss << alphaArgVec.str() << ".r";
break;
case CMaterial::InvSrcColor:
ss << "1.0 - " << alphaArgVec.str() << ".r";
break;
case CMaterial::SrcAlpha:
ss << alphaArgVec.str() << ".a";
break;
case CMaterial::InvSrcAlpha:
ss << "1.0 - " << alphaArgVec.str() << ".a";
break;
}
ss << ";" << std::endl;
}
ss << "vec4 texop" << stage << ";" << std::endl;
// RGB
switch (texEnv.Env.OpRGB)
{
case CMaterial::InterpolateConstant:
ss << "float texop" << stage << "rgbAs = constant" << stage << ".a;" << std::endl;
break;
case CMaterial::InterpolatePrevious:
if (stage > 0)
{
ss << "float texop" << stage << "rgbAs = texop" << stage << ".a;" << std::endl;
break;
}
case CMaterial::InterpolateDiffuse:
ss << "float texop" << stage << "rgbAs = diffuse.a;" << std::endl;
break;
case CMaterial::InterpolateTexture:
ss << "float texop" << stage << "rgbAs = texel" << stage << ".a;" << std::endl;
break;
}
ss << "texop" << stage << ".rgb = ";
switch (texEnv.Env.OpRGB)
{
case CMaterial::Replace:
ss << "texop" << stage << "arg0.rgb";
break;
case CMaterial::Modulate:
ss << "texop" << stage << "arg0.rgb * texop" << stage << "arg1.rgb";
break;
case CMaterial::Add:
ss << "texop" << stage << "arg0.rgb + texop" << stage << "arg1.rgb";
break;
case CMaterial::AddSigned:
ss << "texop" << stage << "arg0.rgb + texop" << stage << "arg1.rgb - vec3(0.5, 0.5, 0.5)";
break;
case CMaterial::InterpolateConstant:
case CMaterial::InterpolateDiffuse:
case CMaterial::InterpolatePrevious:
case CMaterial::InterpolateTexture:
ss << "texop" << stage << "arg0.rgb * texop" << stage << "rgbAs + texop" << stage << "arg1.rgb * (1.0 - texop" << stage << "rgbAs)";
break;
case CMaterial::Mad:
ss << "texop" << stage << "arg0.rgb * texop" << stage << "arg1.rgb + texop" << stage << "arg2.rgb";
break;
}
ss << ";" << std::endl;
// Alpha
switch (texEnv.Env.OpAlpha)
{
case CMaterial::InterpolateConstant:
ss << "float texop" << stage << "alphaAs = constant" << stage << ".a;" << std::endl;
break;
case CMaterial::InterpolatePrevious:
if (stage > 0)
{
ss << "float texop" << stage << "alphaAs = texop" << stage << ".a;" << std::endl;
break;
}
case CMaterial::InterpolateDiffuse:
ss << "float texop" << stage << "alphaAs = diffuse.a;" << std::endl;
break;
case CMaterial::InterpolateTexture:
ss << "float texop" << stage << "alphaAs = texel" << stage << ".a;" << std::endl;
break;
}
ss << "texop" << stage << ".a = ";
switch (texEnv.Env.OpAlpha)
{
case CMaterial::Replace:
ss << "texop" << stage << "arg0.a";
break;
case CMaterial::Modulate:
ss << "texop" << stage << "arg0.a * texop" << stage << "arg1.a";
break;
case CMaterial::Add:
ss << "texop" << stage << "arg0.a + texop" << stage << "arg1.a";
break;
case CMaterial::AddSigned:
ss << "texop" << stage << "arg0.a + texop" << stage << "arg1.a - 0.5";
break;
case CMaterial::InterpolateConstant:
case CMaterial::InterpolateDiffuse:
case CMaterial::InterpolatePrevious:
case CMaterial::InterpolateTexture:
ss << "texop" << stage << "arg0.a * texop" << stage << "rgbAs + texop" << stage << "arg1.a * (1.0 - texop" << stage << "rgbAs)";
break;
case CMaterial::Mad:
ss << "texop" << stage << "arg0.a * texop" << stage << "arg1.a + texop" << stage << "arg2.a";
break;
}
ss << ";" << std::endl;
}
else if (stage == 0)
{
ss << "vec4 texop" << stage << " = diffuse; // no active texture in stage" << std::endl;
}
else
{
ss << "vec4 texop" << stage << " = texop" << (stage - 1) << "; // no active texture in stage" << std::endl;
}
}
ss << "fragColor = texop" << (maxTex - 1) << ";" << std::endl;
}
void ppSpecular(std::stringstream &ss, CPPBuiltin &desc)
{
ss << "vec3 specop0 = texel0.rgb * diffuse.rgb;" << std::endl;
ss << "vec4 specop1 = vec4(texel1.rgb * texel0.a + specop0, diffuse.a);" << std::endl;
ss << "fragColor = specop1;" << std::endl;
}
void ppGenerate(std::string &result, CPPBuiltin &desc)
{
@ -87,11 +342,18 @@ void CDriverGL3::generateBuiltinPixelProgram(CMaterial &mat)
m_PPBuiltinCache.insert(matDrv->PPBuiltin);
}
void CPPBuiltin::checkDriverStateTouched(CDriverGL3 *driver)
void CPPBuiltin::checkDriverStateTouched(CDriverGL3 *driver) // MUST NOT depend on any state set by checkMaterialStateTouched
{
if (VertexFormat != driver->m_VPBuiltinCurrent.VertexFormat)
// Add generated texture coordinates to vertex format
uint16 vertexFormat = driver->m_VPBuiltinCurrent.VertexFormat;
for (sint stage = 0; stage < IDRV_MAT_MAXTEXTURES; ++stage)
if (driver->m_VPBuiltinCurrent.TexGenMode[stage] >= 0)
vertexFormat |= g_VertexFlags[TexCoord0 + stage];
// Compare values
if (VertexFormat != vertexFormat)
{
VertexFormat = driver->m_VPBuiltinCurrent.VertexFormat;
VertexFormat = vertexFormat;
Touched = true;
}
if (Fog != driver->m_VPBuiltinCurrent.Fog)
@ -101,9 +363,43 @@ void CPPBuiltin::checkDriverStateTouched(CDriverGL3 *driver)
}
}
void CPPBuiltin::checkMaterialStateTouched(CMaterial &mat)
void CPPBuiltin::checkMaterialStateTouched(CMaterial &mat) // MUST NOT depend on any state set by checkDriverStateTouched
{
// Optimize
uint32 touched = !PixelProgram ? IDRV_TOUCHED_ALL : mat.getTouched();
if (touched == 0) return;
// Compare values
CMaterial::TShader shader = getSupportedShader(mat.getShader());
if (Shader != shader)
{
Shader = shader;
Touched = true;
}
uint maxTex = maxTextures(shader);
if (touched & IDRV_TOUCHED_ALLTEX) // Note: There is a case where textures are provided where no texture coordinates are provided, this is handled gracefully by the pixel program generation (it will use a vec(0) texture coordinate). The inverse is an optimization issue.
{
uint8 textureActive = 0x00;
for (uint i = 0; i < maxTex; ++i)
if (mat.getTexture(i))
textureActive |= (1 << i);
TextureActive = textureActive;
Touched = true;
}
if (useTexEnv(shader) && (touched & IDRV_TOUCHED_TEXENV))
{
for (uint stage = 0; stage < maxTex; ++stage)
{
if (TexEnvMode[stage] != mat.getTexEnvMode(stage))
{
TexEnvMode[stage] = mat.getTexEnvMode(stage);
Touched = true;
}
}
}
// Optimize
mat.clearTouched(0xFFFFFFFF);
}
#ifdef NL_STATIC

@ -691,6 +691,28 @@ bool CDriverGL3::setupBuiltinPixelProgram(CMaterial &mat)
{
if (m_UserPixelProgram) return true;
CMaterialDrvInfosGL3 *matDrv = static_cast<CMaterialDrvInfosGL3 *>((IMaterialDrvInfos *)(mat._MatDrvInfo));
nlassert(matDrv);
matDrv->PPBuiltin.checkDriverStateTouched(this);
matDrv->PPBuiltin.checkMaterialStateTouched(mat);
if (matDrv->PPBuiltin.Touched)
{
generateBuiltinPixelProgram(mat);
nlassert(matDrv->PPBuiltin.PixelProgram);
matDrv->PPBuiltin.Touched = false;
}
if (!activePixelProgram(matDrv->PPBuiltin.PixelProgram, true))
return false;
// GL3 TODO: Here we set the uniforms of the vertex program!
return true;
#if 0
// nlassert(!m_UserVertexProgram); // TEMP
// nlassert(!m_UserPixelProgram); // TEMP
@ -811,6 +833,7 @@ bool CDriverGL3::setupBuiltinPixelProgram(CMaterial &mat)
}
return true;
#endif
}
bool CDriverGL3::setupDynMatProgram(CMaterial& mat, uint pass)

@ -55,6 +55,10 @@ struct CPPBuiltin
uint16 VertexFormat;
bool Fog;
CMaterial::TShader Shader;
uint8 TextureActive;
uint32 TexEnvMode[IDRV_MAT_MAXTEXTURES]; // Normal, UserColor
CPixelProgram *PixelProgram;
bool Touched;

Loading…
Cancel
Save