GL3: Even more refactoring

--HG--
branch : opengl3
hg/feature/opengl3
kaetemi 11 years ago
parent 17b3fa7b55
commit 75d2bf91bf

@ -315,6 +315,8 @@ CDriverGL3::CDriverGL3()
m_DriverGeometryProgram = NULL; m_DriverGeometryProgram = NULL;
m_DriverPixelProgram = NULL; m_DriverPixelProgram = NULL;
m_VPBuiltinTouched = true;
shaderGenerator = new CGLSLShaderGenerator(); shaderGenerator = new CGLSLShaderGenerator();
usrShaderManager = new CUsrShaderManager(); usrShaderManager = new CUsrShaderManager();
@ -690,6 +692,14 @@ bool CDriverGL3::release()
m_UserGeometryProgram = NULL; m_UserGeometryProgram = NULL;
m_UserPixelProgram = NULL; m_UserPixelProgram = NULL;
// Delete all cached programs
for (std::set<CVPBuiltin>::iterator it(m_VPBuiltinCache.begin()), end(m_VPBuiltinCache.end()); it != end; ++it)
delete it->VertexProgram;
m_VPBuiltinCache.clear();
for (std::set<CPPBuiltin>::iterator it(m_PPBuiltinCache.begin()), end(m_PPBuiltinCache.end()); it != end; ++it)
delete it->PixelProgram;
m_PPBuiltinCache.clear();
// Call IDriver::release() before, to destroy textures, shaders and VBs... // Call IDriver::release() before, to destroy textures, shaders and VBs...
IDriver::release(); IDriver::release();

@ -62,6 +62,8 @@ bool operator<(const CPPBuiltin &left, const CPPBuiltin &right)
// Material state // Material state
if (left.Shader != right.Shader) if (left.Shader != right.Shader)
return left.Shader < right.Shader; return left.Shader < right.Shader;
if (left.Flags != right.Flags)
return left.Flags < right.Flags;
if (left.TextureActive != right.TextureActive) if (left.TextureActive != right.TextureActive)
return left.TextureActive < right.TextureActive; return left.TextureActive < right.TextureActive;
uint maxTex = maxTextures(left.Shader); uint maxTex = maxTextures(left.Shader);
@ -78,6 +80,8 @@ bool operator<(const CPPBuiltin &left, const CPPBuiltin &right)
// Driver state // Driver state
if (left.VertexFormat != right.VertexFormat) if (left.VertexFormat != right.VertexFormat)
return left.VertexFormat < right.VertexFormat; return left.VertexFormat < right.VertexFormat;
if (left.Lighting != right.Lighting)
return left.Lighting < right.Lighting;
if (left.Fog != right.Fog) if (left.Fog != right.Fog)
return right.Fog; return right.Fog;
@ -143,7 +147,7 @@ void ppTexEnv(std::stringstream &ss, const CPPBuiltin &desc)
break; break;
} }
case CMaterial::Diffuse: case CMaterial::Diffuse:
rgbArgVec << "diffuse"; rgbArgVec << "fragColor";
break; break;
case CMaterial::Constant: case CMaterial::Constant:
rgbArgVec << "constant" << stage; rgbArgVec << "constant" << stage;
@ -183,7 +187,7 @@ void ppTexEnv(std::stringstream &ss, const CPPBuiltin &desc)
break; break;
} }
case CMaterial::Diffuse: case CMaterial::Diffuse:
alphaArgVec << "diffuse"; alphaArgVec << "fragColor";
break; break;
case CMaterial::Constant: case CMaterial::Constant:
alphaArgVec << "constant" << stage; alphaArgVec << "constant" << stage;
@ -222,7 +226,7 @@ void ppTexEnv(std::stringstream &ss, const CPPBuiltin &desc)
break; break;
} }
case CMaterial::InterpolateDiffuse: case CMaterial::InterpolateDiffuse:
ss << "float texop" << stage << "rgbAs = diffuse.a;" << std::endl; ss << "float texop" << stage << "rgbAs = fragColor.a;" << std::endl;
break; break;
case CMaterial::InterpolateTexture: case CMaterial::InterpolateTexture:
ss << "float texop" << stage << "rgbAs = texel" << stage << ".a;" << std::endl; ss << "float texop" << stage << "rgbAs = texel" << stage << ".a;" << std::endl;
@ -268,7 +272,7 @@ void ppTexEnv(std::stringstream &ss, const CPPBuiltin &desc)
break; break;
} }
case CMaterial::InterpolateDiffuse: case CMaterial::InterpolateDiffuse:
ss << "float texop" << stage << "alphaAs = diffuse.a;" << std::endl; ss << "float texop" << stage << "alphaAs = fragColor.a;" << std::endl;
break; break;
case CMaterial::InterpolateTexture: case CMaterial::InterpolateTexture:
ss << "float texop" << stage << "alphaAs = texel" << stage << ".a;" << std::endl; ss << "float texop" << stage << "alphaAs = texel" << stage << ".a;" << std::endl;
@ -303,7 +307,7 @@ void ppTexEnv(std::stringstream &ss, const CPPBuiltin &desc)
} }
else if (stage == 0) else if (stage == 0)
{ {
ss << "vec4 texop" << stage << " = diffuse; // no active texture in stage" << std::endl; ss << "vec4 texop" << stage << " = fragColor; // no active texture in stage" << std::endl;
} }
else else
{ {
@ -315,8 +319,8 @@ void ppTexEnv(std::stringstream &ss, const CPPBuiltin &desc)
void ppSpecular(std::stringstream &ss, const CPPBuiltin &desc) void ppSpecular(std::stringstream &ss, const CPPBuiltin &desc)
{ {
ss << "vec3 specop0 = texel0.rgb * diffuse.rgb;" << std::endl; ss << "vec3 specop0 = texel0.rgb * fragColor.rgb;" << std::endl;
ss << "vec4 specop1 = vec4(texel1.rgb * texel0.a + specop0, diffuse.a);" << std::endl; ss << "vec4 specop1 = vec4(texel1.rgb * texel0.a + specop0, fragColor.a);" << std::endl;
ss << "fragColor = specop1;" << std::endl; ss << "fragColor = specop1;" << std::endl;
} }
@ -352,18 +356,25 @@ void ppGenerate(std::string &result, const CPPBuiltin &desc)
<< " sampler" << stage << ";" << std::endl; << " sampler" << stage << ";" << std::endl;
} }
} }
ss << std::endl;
// ??? // ???
ss << "uniform vec4 materialColor;" << std::endl; // ?! what is this doing in PP ss << "uniform vec4 materialColor;" << std::endl; // ?! what is this doing in PP
ss << std::endl;
// TexEnv // TexEnv
ss << "uniform vec4 constant0;" << std::endl; // todo: we can optimize this by env!... ss << "uniform vec4 constant0;" << std::endl; // FIXME: we must optimize this by texenv!...
ss << "uniform vec4 constant1;" << std::endl; ss << "uniform vec4 constant1;" << std::endl;
ss << "uniform vec4 constant2;" << std::endl; ss << "uniform vec4 constant2;" << std::endl;
ss << "uniform vec4 constant3;" << std::endl; ss << "uniform vec4 constant3;" << std::endl;
ss << std::endl;
// Alpha test // Alpha test
ss << "uniform float alphaTreshold;" << std::endl; // FIXME: only when driver state has alpha test.... oooh if (desc.Flags & IDRV_MAT_ALPHA_TEST)
{
ss << "uniform float alphaTreshold;" << std::endl;
ss << std::endl;
}
// Fog // Fog
if (desc.Fog) // FIXME: FogMode! if (desc.Fog) // FIXME: FogMode!
@ -378,74 +389,94 @@ void ppGenerate(std::string &result, const CPPBuiltin &desc)
}*/ }*/
ss << "smooth in vec4 ecPos;" << std::endl; ss << "smooth in vec4 ecPos;" << std::endl;
/*switch(desc->getFogMode())
{
case CShaderDesc::Linear:
ss << "vec4 applyFog(vec4 col)" << std::endl;
ss << "{" << std::endl;
ss << "float z = ecPos.z / ecPos.w;" << std::endl;
ss << "z = abs(z);" << std::endl;
ss << "float fogFactor = (fogEnd - z) / (fogEnd - fogStart);" << std::endl;
ss << "fogFactor = clamp(fogFactor, 0.0, 1.0);" << std::endl;
ss << "vec4 fColor = mix(fogColor, col, fogFactor);" << std::endl;
ss << "return fColor;" << std::endl;
ss << "}" << std::endl;
ss << std::endl;
break;
}*/
ss << std::endl;
} }
ss << std::endl;
/*if (desc->lightingEnabled()) if (desc.Lighting)
{ {
addLightUniformsFS(); ss << "smooth in vec4 lightColor;" << std::endl; // TODO: We probably will always have an incoming vertex color with vertex and light etc premixed.
addLightInsFS();
ss << std::endl;
addLightsFunctionFS();
ss << std::endl; ss << std::endl;
} }
if (desc->fogEnabled())
addFogFunction();*/
ss << "void main(void)" << std::endl; ss << "void main(void)" << std::endl;
ss << "{" << std::endl; ss << "{" << std::endl;
// Light color // Light color
/*ss << "vec4 diffuse = vec4(1.0, 1.0, 1.0, 1.0);" << std::endl; ss << "fragColor = vec4(1.0, 1.0, 1.0, 1.0);" << std::endl;
if (desc->lightingEnabled()) if (desc.Lighting)
{
ss << "fragColor = lightColor;" << std::endl;
ss << "fragColor.a = 1.0;" << std::endl;
}
if (hasFlag(desc.VertexFormat, g_VertexFlags[PrimaryColor])) // TODO: What about secondary color?
{ {
ss << "diffuse = applyLights(diffuse);" << std::endl; ss << "fragColor = primaryColor * fragColor;" << std::endl; // TODO: If this is the correct location, we should premultiply light and color in VS.
ss << "diffuse.a = 1.0;" << std::endl;
} }
if (hasFlag(desc->vbFlags, g_VertexFlags[PrimaryColor]))
ss << "diffuse = color * diffuse;" << std::endl; // TODO: If this is the correct location, we should premultiply light and color in VS.
bool textures = false; for (uint stage = 0; stage < maxTex; ++stage)
for (int i = 0; i < IDRV_MAT_MAXTEXTURES; i++)
{ {
if (desc->getUseTexStage(i)) if (useTex(desc, stage))
{ {
ss << "vec4 texel" << i << " = texture(sampler" << i << ", "; ss << "vec4 texel" << stage << " = texture(sampler" << stage << ", ";
if (desc->hasVBFlags(g_VertexFlags[TexCoord0 + i])) if (hasFlag(desc.VertexFormat, g_VertexFlags[TexCoord0 + stage]))
ss << g_AttribNames[TexCoord0 + i]; {
else if (desc->hasVBFlags(g_VertexFlags[TexCoord0])) ss << g_AttribNames[TexCoord0 + stage];
}
else if (hasFlag(desc.VertexFormat, g_VertexFlags[TexCoord0]))
{
ss << g_AttribNames[TexCoord0]; ss << g_AttribNames[TexCoord0];
}
else else
{ {
nlwarning("GL3: Pixel Program generated for material with coordinateless texture"); nlwarning("GL3: Pixel Program generated for material with coordinateless texture");
ss << "vec4(0.0, 0.0, 0.0, 0.0)"; ss << "vec4(0.0, 0.0, 0.0, 0.0)";
} }
ss << ((desc->textureSamplerMode[i] == SamplerCube) ? ".str);" : ".st);"); ss << ((desc.TexSamplerMode[stage] == SamplerCube) ? ".stp);" : ".st);");
ss << std::endl; ss << std::endl;
textures = true;
} }
}*/ }
/*switch (material->getShader()) switch (desc.Shader)
{ {
case CMaterial::Normal:
case CMaterial::UserColor:
ppTexEnv(ss, desc);
break;
case CMaterial::Specular: case CMaterial::Specular:
generateSpecular(); ppSpecular(ss, desc);
break; break;
default: default:
generateTexEnv(); nlwarning("GL3: Try to generate unknown shader type (%s)", s_ShaderNames[desc.Shader]);
// ss << "fragColor = vec(1.0, 0.0, 0.5, 1.0);" << std::endl;
break; break;
} }
if (desc->fogEnabled()) if (desc.Flags & IDRV_MAT_ALPHA_TEST)
addFog(); {
ss << "if (fragColor.a < alphaTreshold) discard;" << std::endl; // TODO: VERIFY < or <= ?
addAlphaTest();*/ }
// ss << "fragColor = fragColor + vec4(0.0, 0.25, 0.0, 0.0);" << std::endl;
// ss << "fragColor.b = diffuse.b;" << std::endl; if (desc.Fog)
{
ss << "fragColor = applyFog(fragColor);" << std::endl;
}
ss << "}" << std::endl; ss << "}" << std::endl;
@ -490,7 +521,7 @@ void CDriverGL3::generateBuiltinPixelProgram(CMaterial &mat)
void CPPBuiltin::checkDriverStateTouched(CDriverGL3 *driver) // MUST NOT depend on any state set by checkMaterialStateTouched void CPPBuiltin::checkDriverStateTouched(CDriverGL3 *driver) // MUST NOT depend on any state set by checkMaterialStateTouched
{ {
// Add generated texture coordinates to vertex format // Add generated texture coordinates to vertex format // TODO: Eliminate unused flags
uint16 vertexFormat = driver->m_VPBuiltinCurrent.VertexFormat; uint16 vertexFormat = driver->m_VPBuiltinCurrent.VertexFormat;
for (sint stage = 0; stage < IDRV_MAT_MAXTEXTURES; ++stage) for (sint stage = 0; stage < IDRV_MAT_MAXTEXTURES; ++stage)
if (driver->m_VPBuiltinCurrent.TexGenMode[stage] >= 0) if (driver->m_VPBuiltinCurrent.TexGenMode[stage] >= 0)
@ -502,6 +533,11 @@ void CPPBuiltin::checkDriverStateTouched(CDriverGL3 *driver) // MUST NOT depend
VertexFormat = vertexFormat; VertexFormat = vertexFormat;
Touched = true; Touched = true;
} }
if (Lighting != driver->m_VPBuiltinCurrent.Lighting)
{
Lighting = driver->m_VPBuiltinCurrent.Lighting;
Touched = true;
}
if (Fog != driver->m_VPBuiltinCurrent.Fog) if (Fog != driver->m_VPBuiltinCurrent.Fog)
{ {
Fog = driver->m_VPBuiltinCurrent.Fog; Fog = driver->m_VPBuiltinCurrent.Fog;
@ -522,6 +558,13 @@ void CPPBuiltin::checkMaterialStateTouched(CMaterial &mat) // MUST NOT depend on
Shader = shader; Shader = shader;
Touched = true; Touched = true;
} }
uint32 flags = mat.getFlags();
flags &= IDRV_MAT_ALPHA_TEST; // TODO: |= with the wanted flags from the VP when flags are added to the VP
if (Flags != flags)
{
Flags = flags;
Touched = true;
}
uint maxTex = maxTextures(shader); 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 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
{ {

@ -22,7 +22,6 @@
#include "nel/3d/usr_shader_manager.h" #include "nel/3d/usr_shader_manager.h"
#include "nel/3d/usr_shader_program.h" #include "nel/3d/usr_shader_program.h"
namespace NL3D { namespace NL3D {
#ifdef NL_STATIC #ifdef NL_STATIC
@ -54,8 +53,8 @@ const char *g_AttribNames[CVertexBuffer::NumValue] =
"position", "position",
"weight", "weight",
"normal", "normal",
"color", "primaryColor",
"color2", "secondaryColor",
"fog", "fog",
"paletteSkin", "paletteSkin",
"none", "none",

@ -36,6 +36,8 @@ static sint TexGenEyeLinear = 3; // GL_EYE_LINEAR
/// Builtin vertex program description /// Builtin vertex program description
struct CVPBuiltin struct CVPBuiltin
{ {
CVPBuiltin() : VertexProgram(NULL) { }
uint16 VertexFormat; uint16 VertexFormat;
bool Lighting; bool Lighting;
sint LightMode[NL_OPENGL3_MAX_LIGHT]; // -1 when disabled sint LightMode[NL_OPENGL3_MAX_LIGHT]; // -1 when disabled
@ -44,7 +46,7 @@ struct CVPBuiltin
bool Fog; bool Fog;
// bool VertexColorLighted; // bool VertexColorLighted;
CVertexProgram *VertexProgram; NLMISC::CRefPtr<CVertexProgram> VertexProgram;
}; };
bool operator<(const CVPBuiltin &left, const CVPBuiltin &right); bool operator<(const CVPBuiltin &left, const CVPBuiltin &right);
@ -55,15 +57,19 @@ static const uint8 SamplerCube = 1;
/// Builtin pixel program description /// Builtin pixel program description
struct CPPBuiltin struct CPPBuiltin
{ {
CPPBuiltin() : Touched(true) { }
uint16 VertexFormat; uint16 VertexFormat;
bool Lighting;
bool Fog; bool Fog;
CMaterial::TShader Shader; CMaterial::TShader Shader;
uint32 Flags;
uint8 TextureActive; uint8 TextureActive;
uint8 TexSamplerMode[IDRV_MAT_MAXTEXTURES]; uint8 TexSamplerMode[IDRV_MAT_MAXTEXTURES];
uint32 TexEnvMode[IDRV_MAT_MAXTEXTURES]; // Normal, UserColor uint32 TexEnvMode[IDRV_MAT_MAXTEXTURES]; // Normal, UserColor
CPixelProgram *PixelProgram; NLMISC::CRefPtr<CPixelProgram> PixelProgram;
bool Touched; bool Touched;

Loading…
Cancel
Save