GL3: Cleanup and fix lighting state bug in pp

--HG--
branch : opengl3
hg/feature/opengl3
kaetemi 11 years ago
parent d5d82ce900
commit 75e650432f

@ -14,101 +14,17 @@
// You should have received a copy of the GNU Affero General Public License // You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>. // along with this program. If not, see <http://www.gnu.org/licenses/>.
#include "sstream" #include "stdopengl.h"
#include "driver_glsl_shader_generator.h" #include "driver_glsl_shader_generator.h"
#include <sstream>
#include "nel/3d/vertex_buffer.h" #include "nel/3d/vertex_buffer.h"
#include "driver_opengl_program.h"
#include "driver_opengl_shader_desc.h" #include "driver_opengl_shader_desc.h"
namespace
{
inline bool hasFlag(uint32 data, uint32 flag)
{
if ((data & flag) != 0)
return true;
else
return false;
}
enum AttribOffset
{
Position,
Weight,
Normal,
PrimaryColor,
SecondaryColor,
Fog,
PaletteSkin,
Empty,
TexCoord0,
TexCoord1,
TexCoord2,
TexCoord3,
TexCoord4,
TexCoord5,
TexCoord6,
TexCoord7,
NumOffsets
};
}
namespace NL3D namespace NL3D
{ {
uint16 vertexFlags[ CVertexBuffer::NumValue ] =
{
CVertexBuffer::PositionFlag,
CVertexBuffer::WeightFlag,
CVertexBuffer::NormalFlag,
CVertexBuffer::PrimaryColorFlag,
CVertexBuffer::SecondaryColorFlag,
CVertexBuffer::FogFlag,
CVertexBuffer::PaletteSkinFlag,
0,
CVertexBuffer::TexCoord0Flag,
CVertexBuffer::TexCoord1Flag,
CVertexBuffer::TexCoord2Flag,
CVertexBuffer::TexCoord3Flag,
CVertexBuffer::TexCoord4Flag,
CVertexBuffer::TexCoord5Flag,
CVertexBuffer::TexCoord6Flag,
CVertexBuffer::TexCoord7Flag
};
const char *attribNames[ CVertexBuffer::NumValue ] =
{
"position",
"weight",
"normal",
"color",
"color2",
"fog",
"paletteSkin",
"none",
"texCoord0",
"texCoord1",
"texCoord2",
"texCoord3",
"texCoord4",
"texCoord5",
"texCoord6",
"texCoord7"
};
const char *texelNames[ SHADER_MAX_TEXTURES ] =
{
"texel0",
"texel1",
"texel2",
"texel3"
};
const char *constantNames[ 4 ] =
{
"constant0",
"constant1",
"constant2",
"constant3"
};
const char *shaderNames[] = const char *shaderNames[] =
{ {
"Normal", "Normal",
@ -130,6 +46,7 @@ namespace NL3D
CGLSLShaderGenerator::~CGLSLShaderGenerator() CGLSLShaderGenerator::~CGLSLShaderGenerator()
{ {
} }
void CGLSLShaderGenerator::reset() void CGLSLShaderGenerator::reset()
@ -156,14 +73,23 @@ namespace NL3D
for (int i = Weight; i < NumOffsets; i++) for (int i = Weight; i < NumOffsets; i++)
{ {
if (hasFlag(vbFormat, vertexFlags[ i ])) if (hasFlag(vbFormat, g_VertexFlags[i]))
{ {
ss << "smooth in vec4 "; ss << "smooth in vec4 ";
ss << attribNames[ i ] << ";" << std::endl; ss << g_AttribNames[i] << ";" << std::endl;
} }
} }
ss << std::endl; ss << std::endl;
/*if (desc->lightingEnabled()) // LIGHTING DEBUG
{
generateInvalidPS();
}
else
{
generateNormalPS();
}*/
switch(material->getShader()) switch(material->getShader())
{ {
case CMaterial::Normal: case CMaterial::Normal:
@ -292,7 +218,7 @@ namespace NL3D
void CGLSLShaderGenerator::addLightUniformsFS() void CGLSLShaderGenerator::addLightUniformsFS()
{ {
for (int i = 0; i < SHADER_MAX_LIGHTS; i++) for (int i = 0; i < NL_OPENGL3_MAX_LIGHT; i++)
{ {
switch(desc->getLight(i)) switch(desc->getLight(i))
{ {
@ -364,7 +290,7 @@ namespace NL3D
ss << "void main(void)" << std::endl; ss << "void main(void)" << std::endl;
ss << "{" << std::endl; ss << "{" << std::endl;
ss << "vec4 eyePosition = modelView * v" << attribNames[ 0 ] << ";" << std::endl; ss << "vec4 eyePosition = modelView * v" << g_AttribNames[ 0 ] << ";" << std::endl;
if (desc->hasPointLight()) if (desc->hasPointLight())
ss << "ecPos4 = eyePosition;" << std::endl; ss << "ecPos4 = eyePosition;" << std::endl;
@ -378,18 +304,18 @@ namespace NL3D
ss << "vec4 t = vec4(cubeTexCoords, 1.0);" << std::endl; ss << "vec4 t = vec4(cubeTexCoords, 1.0);" << std::endl;
ss << "t = t * texMatrix0;" << std::endl; ss << "t = t * texMatrix0;" << std::endl;
ss << "cubeTexCoords = t.xyz;" << std::endl; ss << "cubeTexCoords = t.xyz;" << std::endl;
ss << "gl_Position = modelViewProjection * v" << attribNames[ 0 ] << ";" << std::endl; ss << "gl_Position = modelViewProjection * v" << g_AttribNames[ 0 ] << ";" << std::endl;
if (desc->lightingEnabled()) if (desc->lightingEnabled())
addLightsVS(); addLightsVS();
for (int i = Weight; i < NumOffsets; i++) for (int i = Weight; i < NumOffsets; i++)
{ {
if (hasFlag(vbFormat, vertexFlags[ i ])) if (hasFlag(vbFormat, g_VertexFlags[i]))
{ {
ss << attribNames[ i ]; ss << g_AttribNames[i];
ss << " = "; ss << " = ";
ss << "v" << attribNames[ i ] << ";" << std::endl; ss << "v" << g_AttribNames[i] << ";" << std::endl;
} }
} }
@ -415,15 +341,15 @@ namespace NL3D
ss << "void main(void)" << std::endl; ss << "void main(void)" << std::endl;
ss << "{" << std::endl; ss << "{" << std::endl;
ss << "gl_Position = modelViewProjection * v" << attribNames[ 0 ] << ";" << std::endl; ss << "gl_Position = modelViewProjection * v" << g_AttribNames[ 0 ] << ";" << std::endl;
for (int i = Weight; i < NumOffsets; i++) for (int i = Weight; i < NumOffsets; i++)
{ {
if (hasFlag(vbFormat, vertexFlags[ i ])) if (hasFlag(vbFormat, g_VertexFlags[i]))
{ {
ss << attribNames[ i ]; ss << g_AttribNames[i];
ss << " = "; ss << " = ";
ss << "v" << attribNames[ i ] << ";" << std::endl; ss << "v" << g_AttribNames[i] << ";" << std::endl;
} }
} }
@ -514,10 +440,101 @@ namespace NL3D
ss << "}" << std::endl; ss << "}" << std::endl;
}*/ }*/
void CGLSLShaderGenerator::generateInvalidPS()
{
/*uint sampler = 0;
for (int i = 0; i < IDRV_MAT_MAXTEXTURES; i++)
{
if (desc->getUseTexStage(i))
ss << "uniform sampler2D sampler" << sampler << ";" << std::endl;
sampler++;
}
addColor();
addConstants();
addAlphaTreshold();
addFogUniform();*/
if (desc->fogEnabled())
ss << "smooth in vec4 ecPos;" << std::endl;
ss << std::endl;
if (desc->lightingEnabled())
{
addLightUniformsFS();
addLightInsFS();
ss << std::endl;
addLightsFunctionFS();
ss << std::endl;
}
/*if (desc->fogEnabled())
addFogFunction();*/
ss << "void main(void)" << std::endl;
ss << "{" << std::endl;
/*bool textures = false;
sampler = 0;
for (int i = 0; i < IDRV_MAT_MAXTEXTURES; i++)
{
if (desc->getUseTexStage(i))
{
ss << "vec4 texel" << sampler << " = texture(sampler" << sampler << ",";
if (!desc->getUseFirstTexCoords())
ss << g_AttribNames[ TexCoord0 + i ] << ".st);";
else
ss << g_AttribNames[ TexCoord0 ] << ".st);";
ss << std::endl;
textures = true;
}
sampler++;
}
bool vertexColor = false;
if (hasFlag(vbFormat, g_VertexFlags[ PrimaryColor ]))
vertexColor = true;
if (textures && !vertexColor)
ss << "vec4 texel = vec4(1.0, 1.0, 1.0, 1.0);" << std::endl;
else
if (vertexColor)
ss << "vec4 texel = color;" << std::endl;
else
ss << "vec4 texel = vec4(0.5, 0.5, 0.5, 1.0);" << std::endl;
generateTexEnv();
// This is just an idea I had, but it seems to be working.
// Unfortunately it's not documented anywhere I looked in the GL spec, but if I don't have this modulation here,
// the Ryzom UI looks horrific.
if (vertexColor)
ss << "texel = color * texel;" << std::endl;*/
ss << "fragColor = vec4(1.0, 1.0, 1.0, 1.0);" << std::endl;
if (desc->lightingEnabled())
addLightsFS();
ss << "fragColor = fragColor + vec4(0.0, 0.25, 0.0, 0.0);" << std::endl;
/*if (desc->fogEnabled())
addFog();
addAlphaTest();*/
ss << "}" << std::endl;
}
void CGLSLShaderGenerator::generateNormalPS() void CGLSLShaderGenerator::generateNormalPS()
{ {
uint sampler = 0; uint sampler = 0;
for (int i = 0; i < SHADER_MAX_TEXTURES; i++) for (int i = 0; i < IDRV_MAT_MAXTEXTURES; i++)
{ {
if (desc->getUseTexStage(i)) if (desc->getUseTexStage(i))
ss << "uniform sampler2D sampler" << sampler << ";" << std::endl; ss << "uniform sampler2D sampler" << sampler << ";" << std::endl;
@ -552,16 +569,16 @@ namespace NL3D
bool textures = false; bool textures = false;
sampler = 0; sampler = 0;
for (int i = 0; i < SHADER_MAX_TEXTURES; i++) for (int i = 0; i < IDRV_MAT_MAXTEXTURES; i++)
{ {
if (desc->getUseTexStage(i)) if (desc->getUseTexStage(i))
{ {
ss << "vec4 texel" << sampler << " = texture(sampler" << sampler << ","; ss << "vec4 texel" << sampler << " = texture(sampler" << sampler << ",";
if (!desc->getUseFirstTexCoords()) if (!desc->getUseFirstTexCoords())
ss << attribNames[ TexCoord0 + i ] << ".st);"; ss << g_AttribNames[ TexCoord0 + i ] << ".st);";
else else
ss << attribNames[ TexCoord0 ] << ".st);"; ss << g_AttribNames[ TexCoord0 ] << ".st);";
ss << std::endl; ss << std::endl;
@ -571,7 +588,7 @@ namespace NL3D
} }
bool vertexColor = false; bool vertexColor = false;
if (hasFlag(vbFormat, vertexFlags[ PrimaryColor ])) if (hasFlag(vbFormat, g_VertexFlags[ PrimaryColor ]))
vertexColor = true; vertexColor = true;
if (textures && !vertexColor) if (textures && !vertexColor)
@ -606,7 +623,7 @@ namespace NL3D
void CGLSLShaderGenerator::generateTexEnv() void CGLSLShaderGenerator::generateTexEnv()
{ {
uint32 stage = 0; uint32 stage = 0;
for (int i = 0; i < SHADER_MAX_TEXTURES; i++) for (int i = 0; i < IDRV_MAT_MAXTEXTURES; i++)
{ {
if (desc->getUseTexStage(i)) if (desc->getUseTexStage(i))
{ {
@ -623,7 +640,7 @@ namespace NL3D
std::string arg1; std::string arg1;
std::string arg2; std::string arg2;
switch(material->_TexEnvs[ stage ].Env.OpRGB) switch(material->_TexEnvs[stage].Env.OpRGB)
{ {
case CMaterial::Replace: case CMaterial::Replace:
{ {
@ -674,7 +691,7 @@ namespace NL3D
buildArg(stage, 0, false, arg0); buildArg(stage, 0, false, arg0);
buildArg(stage, 1, false, arg1); buildArg(stage, 1, false, arg1);
std::string As = texelNames[ stage ]; std::string As = g_TexelNames[stage];
As.append(".a"); As.append(".a");
ss << "texel.rgb = " << arg0 << " * " << As << ";" << std::endl; ss << "texel.rgb = " << arg0 << " * " << As << ";" << std::endl;
@ -711,7 +728,7 @@ namespace NL3D
buildArg(stage, 0, false, arg0); buildArg(stage, 0, false, arg0);
buildArg(stage, 1, false, arg1); buildArg(stage, 1, false, arg1);
std::string As = constantNames[ stage ]; std::string As = g_ConstantNames[stage];
As.append(".a"); As.append(".a");
ss << "texel.rgb = " << arg0 << " * " << As << ";" << std::endl; ss << "texel.rgb = " << arg0 << " * " << As << ";" << std::endl;
@ -727,7 +744,7 @@ namespace NL3D
std::string arg1; std::string arg1;
std::string arg2; std::string arg2;
switch(material->_TexEnvs[ stage ].Env.OpRGB) switch(material->_TexEnvs[stage].Env.OpRGB)
{ {
case CMaterial::Replace: case CMaterial::Replace:
{ {
@ -777,7 +794,7 @@ namespace NL3D
buildArg(stage, 0, true, arg0); buildArg(stage, 0, true, arg0);
buildArg(stage, 1, true, arg1); buildArg(stage, 1, true, arg1);
std::string As = texelNames[ stage ]; std::string As = g_TexelNames[stage];
As.append(".a"); As.append(".a");
ss << "texel.a = " << arg0 << " * " << As << ";" << std::endl; ss << "texel.a = " << arg0 << " * " << As << ";" << std::endl;
@ -814,7 +831,7 @@ namespace NL3D
buildArg(stage, 0, true, arg0); buildArg(stage, 0, true, arg0);
buildArg(stage, 1, true, arg1); buildArg(stage, 1, true, arg1);
std::string As = constantNames[ stage ]; std::string As = g_ConstantNames[stage];
As.append(".a"); As.append(".a");
ss << "texel.a = " << arg0 << " * " << As << ";" << std::endl; ss << "texel.a = " << arg0 << " * " << As << ";" << std::endl;
@ -851,21 +868,21 @@ namespace NL3D
switch(op) switch(op)
{ {
case CMaterial::SrcColor: case CMaterial::SrcColor:
ds << texelNames[ stage ] << ".rgb"; ds << g_TexelNames[stage] << ".rgb";
break; break;
case CMaterial::InvSrcColor: case CMaterial::InvSrcColor:
ds << "(vec3(1.0, 1.0, 1.0) - "; ds << "(vec3(1.0, 1.0, 1.0) - ";
ds << texelNames[ stage ] << ".rgb)"; ds << g_TexelNames[stage] << ".rgb)";
break; break;
case CMaterial::SrcAlpha: case CMaterial::SrcAlpha:
ds << texelNames[ stage ] << ".a"; ds << g_TexelNames[stage] << ".a";
break; break;
case CMaterial::InvSrcAlpha: case CMaterial::InvSrcAlpha:
ds << "(1.0 - "; ds << "(1.0 - ";
ds << texelNames[ stage ] << ".a)"; ds << g_TexelNames[stage] << ".a)";
break; break;
} }
} }
@ -920,19 +937,19 @@ namespace NL3D
switch(op) switch(op)
{ {
case CMaterial::SrcColor: case CMaterial::SrcColor:
ds << constantNames[ stage ] << ".rgb"; ds << g_ConstantNames[stage] << ".rgb";
break; break;
case CMaterial::InvSrcColor: case CMaterial::InvSrcColor:
ds << "(vec3(1.0, 1.0, 1.0) - " << constantNames[ stage ] << ".rgb)"; ds << "(vec3(1.0, 1.0, 1.0) - " << g_ConstantNames[stage] << ".rgb)";
break; break;
case CMaterial::SrcAlpha: case CMaterial::SrcAlpha:
ds << constantNames[ stage ] << ".a"; ds << g_ConstantNames[stage] << ".a";
break; break;
case CMaterial::InvSrcAlpha: case CMaterial::InvSrcAlpha:
ds << "(1.0 - " << constantNames[ stage ] << ".a)"; ds << "(1.0 - " << g_ConstantNames[stage] << ".a)";
break; break;
} }
break; break;
@ -950,7 +967,7 @@ namespace NL3D
int ntextures = 0; int ntextures = 0;
for (int i = TexCoord0; i < TexCoord4; i++) for (int i = TexCoord0; i < TexCoord4; i++)
{ {
if (hasFlag(vbFormat, vertexFlags[ i ])) if (hasFlag(vbFormat, g_VertexFlags[i]))
ntextures++; ntextures++;
} }
@ -993,11 +1010,11 @@ namespace NL3D
{ {
ss << "vec4 texel" << i; ss << "vec4 texel" << i;
ss << " = texture(sampler" << i; ss << " = texture(sampler" << i;
ss << ", " << attribNames[ TexCoord1 ] << ".st);" << std::endl; ss << ", " << g_AttribNames[ TexCoord1 ] << ".st);" << std::endl;
} }
// Color map UV coords are at position 0 // Color map UV coords are at position 0
ss << "vec4 texel" << ntextures - 1 << " = texture(sampler" << ntextures - 1 << ", " << attribNames[ TexCoord0 ] << ".st);" << std::endl; ss << "vec4 texel" << ntextures - 1 << " = texture(sampler" << ntextures - 1 << ", " << g_AttribNames[ TexCoord0 ] << ".st);" << std::endl;
//ss << "vec4 texel = diffuseColor;" << std::endl; //ss << "vec4 texel = diffuseColor;" << std::endl;
//ss << "vec4 texel = vec4(1.0, 1.0, 1.0, 1.0);" << std::endl; //ss << "vec4 texel = vec4(1.0, 1.0, 1.0, 1.0);" << std::endl;
@ -1006,13 +1023,13 @@ namespace NL3D
// Lightmaps // Lightmaps
for (int i = 0; i < ntextures - 1; i++) for (int i = 0; i < ntextures - 1; i++)
{ {
ss << "texel.rgb = " << texelNames[ i ] << ".rgb * " << constantNames[ i ] << ".rgb + texel.rgb;" << std::endl; ss << "texel.rgb = " << g_TexelNames[i] << ".rgb * " << g_ConstantNames[i] << ".rgb + texel.rgb;" << std::endl;
ss << "texel.a = " << texelNames[ i ] << ".a * texel.a + texel.a;" << std::endl; ss << "texel.a = " << g_TexelNames[i] << ".a * texel.a + texel.a;" << std::endl;
} }
// Texture // Texture
ss << "texel.rgb = " << texelNames[ ntextures - 1 ] << ".rgb * texel.rgb;" << std::endl; ss << "texel.rgb = " << g_TexelNames[ ntextures - 1 ] << ".rgb * texel.rgb;" << std::endl;
ss << "texel.a = " << texelNames[ ntextures - 1] << ".a;" << std::endl; ss << "texel.a = " << g_TexelNames[ ntextures - 1] << ".a;" << std::endl;
if (material->_LightMapsMulx2) if (material->_LightMapsMulx2)
{ {

@ -124,6 +124,7 @@ namespace NL3D
/////////////////////////////////////// Pixel Shader generation /////////////////////////////////////// /////////////////////////////////////// Pixel Shader generation ///////////////////////////////////////
void generateInvalidPS();
void generateNormalPS(); void generateNormalPS();

@ -487,7 +487,7 @@ bool CDriverGL3::stretchRect(ITexture * /* srcText */, NLMISC::CRect &/* srcRect
// *************************************************************************** // ***************************************************************************
bool CDriverGL3::supportBloomEffect() const bool CDriverGL3::supportBloomEffect() const
{ {
return false; // FIXME GL3 return false; // FIXME GL3 // _Extensions.GLCore;
} }
// *************************************************************************** // ***************************************************************************
@ -1156,7 +1156,7 @@ bool CDriverGL3::supportPerPixelLighting(bool specular) const
{ {
H_AUTO_OGL(CDriverGL3_supportPerPixelLighting) H_AUTO_OGL(CDriverGL3_supportPerPixelLighting)
return _Extensions.GLCore; return false; // FIXME GL3 // _Extensions.GLCore;
} }
// *************************************************************************** // ***************************************************************************

@ -1311,9 +1311,6 @@ private:
private: private:
// The last vertex program that was setupped
NLMISC::CRefPtr<CVertexProgram> _LastSetuppedVP;
bool _ForceDXTCCompression; bool _ForceDXTCCompression;
/// Divisor for textureResize (power). /// Divisor for textureResize (power).
uint _ForceTextureResizePower; uint _ForceTextureResizePower;
@ -1351,13 +1348,13 @@ private:
uint32 ppoId; uint32 ppoId;
CVertexProgram *m_UserVertexProgram; NLMISC::CRefPtr<CVertexProgram> m_UserVertexProgram;
CGeometryProgram *m_UserGeometryProgram; NLMISC::CRefPtr<CGeometryProgram> m_UserGeometryProgram;
CPixelProgram *m_UserPixelProgram; NLMISC::CRefPtr<CPixelProgram> m_UserPixelProgram;
CVertexProgram *m_DriverVertexProgram; NLMISC::CRefPtr<CVertexProgram> m_DriverVertexProgram;
CGeometryProgram *m_DriverGeometryProgram; NLMISC::CRefPtr<CGeometryProgram> m_DriverGeometryProgram;
CPixelProgram *m_DriverPixelProgram; NLMISC::CRefPtr<CPixelProgram> m_DriverPixelProgram;
std::set<CVPBuiltin> m_VPBuiltinCache; std::set<CVPBuiltin> m_VPBuiltinCache;
CVPBuiltin m_VPBuiltinCurrent; CVPBuiltin m_VPBuiltinCurrent;

@ -200,15 +200,6 @@ void CDriverGL3::setupLightMapDynamicLighting(bool enable)
} }
} }
void CDriverGL3::disableAllLights()
{
for (int i = 0; i < MaxLight; ++i)
{
_UserLightEnable[i] = false;
touchLightVP(i);
}
}
#ifdef NL_STATIC #ifdef NL_STATIC
} // NLDRIVERGL3 } // NLDRIVERGL3
#endif #endif

@ -244,6 +244,7 @@ bool CDriverGL3::setupMaterial(CMaterial& mat)
} }
CShaderGL3* pShader; CShaderGL3* pShader;
CMaterial::TShader matShader;
GLenum glenum = GL_ZERO; GLenum glenum = GL_ZERO;
uint32 touched = mat.getTouched(); uint32 touched = mat.getTouched();
uint stage; uint stage;
@ -319,14 +320,25 @@ bool CDriverGL3::setupMaterial(CMaterial& mat)
mat.clearTouched(0xFFFFFFFF); mat.clearTouched(0xFFFFFFFF);
} }
// 2b. User supplied pixel shader overrides material
//==================================
if (m_UserPixelProgram)
{
matShader = CMaterial::Program;
}
else
{
// Now we can get the supported shader from the cache. // Now we can get the supported shader from the cache.
CMaterial::TShader matShader = pShader->SupportedShader; matShader = pShader->SupportedShader;
}
// 2b. Update more shader state
//==================================
// if the shader has changed since last time // if the shader has changed since last time
if (matShader != _CurrentMaterialSupportedShader) if (matShader != _CurrentMaterialSupportedShader)
{ {
// if old was lightmap, restore standard lighting // if old was lightmap, restore standard lighting
if (_CurrentMaterialSupportedShader==CMaterial::LightMap) if (_CurrentMaterialSupportedShader == CMaterial::LightMap)
setupLightMapDynamicLighting(false); setupLightMapDynamicLighting(false);
// if new is lightmap, setup dynamic lighting // if new is lightmap, setup dynamic lighting
@ -335,14 +347,14 @@ bool CDriverGL3::setupMaterial(CMaterial& mat)
} }
// setup the global // setup the global
_CurrentMaterialSupportedShader= matShader; _CurrentMaterialSupportedShader = matShader;
// 2. Setup / Bind Textures. // 2. Setup / Bind Textures.
//========================== //==========================
// Must setup textures each frame. (need to test if touched). // Must setup textures each frame. (need to test if touched).
// Must separate texture setup and texture activation in 2 "for"... // Must separate texture setup and texture activation in 2 "for"...
// because setupTexture() may disable all stage. // because setupTexture() may disable all stage.
if (matShader != CMaterial::Water) if (matShader != CMaterial::Water && matShader != CMaterial::Program)
{ {
for (stage=0 ; stage<inlGetNumTextStages() ; stage++) for (stage=0 ; stage<inlGetNumTextStages() ; stage++)
{ {
@ -378,6 +390,7 @@ bool CDriverGL3::setupMaterial(CMaterial& mat)
&& matShader != CMaterial::Cloud && matShader != CMaterial::Cloud
&& matShader != CMaterial::Water && matShader != CMaterial::Water
&& matShader != CMaterial::Specular && matShader != CMaterial::Specular
&& matShader != CMaterial::Program
) )
{ {
for (stage=0 ; stage<inlGetNumTextStages() ; stage++) for (stage=0 ; stage<inlGetNumTextStages() ; stage++)
@ -404,13 +417,13 @@ bool CDriverGL3::setupMaterial(CMaterial& mat)
// Double Sided Part. // Double Sided Part.
//=================== //===================
// NB: inverse state: DoubleSided <=> !CullFace. // NB: inverse state: DoubleSided <=> !CullFace.
uint32 twoSided= mat.getFlags()&IDRV_MAT_DOUBLE_SIDED; uint32 twoSided = mat.getFlags() & IDRV_MAT_DOUBLE_SIDED;
_DriverGLStates.enableCullFace(twoSided==0); _DriverGLStates.enableCullFace(twoSided == 0);
// Alpha Test Part. // Alpha Test Part.
//================= //=================
uint32 alphaTest= mat.getFlags()&IDRV_MAT_ALPHA_TEST; uint32 alphaTest = mat.getFlags() & IDRV_MAT_ALPHA_TEST;
_DriverGLStates.enableAlphaTest(alphaTest); _DriverGLStates.enableAlphaTest(alphaTest);
if (alphaTest) if (alphaTest)
{ {
@ -420,9 +433,9 @@ bool CDriverGL3::setupMaterial(CMaterial& mat)
// Bind ZBuffer Part. // Bind ZBuffer Part.
//=================== //===================
_DriverGLStates.enableZWrite(mat.getFlags()&IDRV_MAT_ZWRITE); _DriverGLStates.enableZWrite(mat.getFlags() & IDRV_MAT_ZWRITE);
_DriverGLStates.depthFunc(pShader->ZComp); _DriverGLStates.depthFunc(pShader->ZComp);
_DriverGLStates.setZBias (mat.getZBias () * _OODeltaZ); _DriverGLStates.setZBias(mat.getZBias() * _OODeltaZ);
// Bind Stencil Buffer Part. // Bind Stencil Buffer Part.
//=================== //===================
@ -436,12 +449,7 @@ bool CDriverGL3::setupMaterial(CMaterial& mat)
//===================== //=====================
// Light Part. // Light Part.
enableLightingVP(mat.getFlags() & IDRV_MAT_LIGHTING); enableLightingVP(mat.getFlags() & IDRV_MAT_LIGHTING);
if ((mat.getFlags() & IDRV_MAT_LIGHTING) == 0)
disableAllLights();
if (mat.getFlags()&IDRV_MAT_LIGHTING) if (mat.getFlags()&IDRV_MAT_LIGHTING)
{ {
_DriverGLStates.setEmissive(pShader->PackedEmissive, pShader->Emissive); _DriverGLStates.setEmissive(pShader->PackedEmissive, pShader->Emissive);
@ -454,6 +462,10 @@ bool CDriverGL3::setupMaterial(CMaterial& mat)
} }
else else
{ {
// Color unlit
// CRGBA col= mat.getColor();
// glColor4ub(col.R, col.G, col.B, col.A);
_DriverGLStates.setVertexColorLighted(false); _DriverGLStates.setVertexColorLighted(false);
} }
@ -479,7 +491,7 @@ bool CDriverGL3::setupMaterial(CMaterial& mat)
//===================================== //=====================================
// Textures user matrix // Textures user matrix
if (matShader == CMaterial::Normal) if (matShader == CMaterial::Normal || matShader == CMaterial::Program)
{ {
setupUserTextureMatrix(inlGetNumTextStages(), mat); setupUserTextureMatrix(inlGetNumTextStages(), mat);
} }

@ -15,77 +15,86 @@
// along with this program. If not, see <http://www.gnu.org/licenses/>. // along with this program. If not, see <http://www.gnu.org/licenses/>.
#include "driver_opengl.h" #include "driver_opengl.h"
#include "driver_opengl_program.h"
#include "driver_glsl_shader_generator.h" #include "driver_glsl_shader_generator.h"
#include "driver_opengl_vertex_buffer_hard.h" #include "driver_opengl_vertex_buffer_hard.h"
#include "nel/3d/dynamic_material.h" #include "nel/3d/dynamic_material.h"
#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
namespace NL3D {
#ifdef NL_STATIC
namespace NLDRIVERGL3 {
#endif
const uint16 g_VertexFlags[CVertexBuffer::NumValue] =
{
CVertexBuffer::PositionFlag,
CVertexBuffer::WeightFlag,
CVertexBuffer::NormalFlag,
CVertexBuffer::PrimaryColorFlag,
CVertexBuffer::SecondaryColorFlag,
CVertexBuffer::FogFlag,
CVertexBuffer::PaletteSkinFlag,
0,
CVertexBuffer::TexCoord0Flag,
CVertexBuffer::TexCoord1Flag,
CVertexBuffer::TexCoord2Flag,
CVertexBuffer::TexCoord3Flag,
CVertexBuffer::TexCoord4Flag,
CVertexBuffer::TexCoord5Flag,
CVertexBuffer::TexCoord6Flag,
CVertexBuffer::TexCoord7Flag
};
const char *g_AttribNames[CVertexBuffer::NumValue] =
{
"position",
"weight",
"normal",
"color",
"color2",
"fog",
"paletteSkin",
"none",
"texCoord0",
"texCoord1",
"texCoord2",
"texCoord3",
"texCoord4",
"texCoord5",
"texCoord6",
"texCoord7"
};
const char *g_TexelNames[IDRV_MAT_MAXTEXTURES] =
{
"texel0",
"texel1",
"texel2",
"texel3"
};
const char *g_ConstantNames[4] =
{ {
const char *constNames[ NL3D::IDRV_MAT_MAXTEXTURES ] =
{
"constant0", "constant0",
"constant1", "constant1",
"constant2", "constant2",
"constant3" "constant3"
}; };
uint16 vertexFlags[ NL3D::CVertexBuffer::NumValue ] =
{
NL3D::CVertexBuffer::PositionFlag,
NL3D::CVertexBuffer::WeightFlag,
NL3D::CVertexBuffer::NormalFlag,
NL3D::CVertexBuffer::PrimaryColorFlag,
NL3D::CVertexBuffer::SecondaryColorFlag,
NL3D::CVertexBuffer::FogFlag,
NL3D::CVertexBuffer::PaletteSkinFlag,
0,
NL3D::CVertexBuffer::TexCoord0Flag,
NL3D::CVertexBuffer::TexCoord1Flag,
NL3D::CVertexBuffer::TexCoord2Flag,
NL3D::CVertexBuffer::TexCoord3Flag,
NL3D::CVertexBuffer::TexCoord4Flag,
NL3D::CVertexBuffer::TexCoord5Flag,
NL3D::CVertexBuffer::TexCoord6Flag,
NL3D::CVertexBuffer::TexCoord7Flag
};
enum AttribOffset
{
Position,
Weight,
Normal,
PrimaryColor,
SecondaryColor,
Fog,
PaletteSkin,
Empty,
TexCoord0,
TexCoord1,
TexCoord2,
TexCoord3,
TexCoord4,
TexCoord5,
TexCoord6,
TexCoord7,
NumOffsets
};
}
namespace NL3D bool CDriverGL3::supportVertexProgram(CVertexProgram::TProfile profile) const
{ {
bool CDriverGL3::supportVertexProgram(CVertexProgram::TProfile profile) const
{
if (profile == IProgram::glsl330v) if (profile == IProgram::glsl330v)
return true; return true;
else else
return false; return false;
} }
bool CDriverGL3::compileVertexProgram(CVertexProgram *program) bool CDriverGL3::compileVertexProgram(CVertexProgram *program)
{ {
if (program->m_DrvInfo != NULL) if (program->m_DrvInfo != NULL)
return false; return false;
@ -140,15 +149,15 @@ namespace NL3D
program->buildInfo(src); program->buildInfo(src);
return true; return true;
} }
bool CDriverGL3::activeVertexProgram(CVertexProgram *program) bool CDriverGL3::activeVertexProgram(CVertexProgram *program)
{ {
return activeVertexProgram(program, false); return activeVertexProgram(program, false);
} }
bool CDriverGL3::activeVertexProgram(CVertexProgram *program, bool driver) bool CDriverGL3::activeVertexProgram(CVertexProgram *program, bool driver)
{ {
if (driver) nlassert(m_UserVertexProgram == NULL); if (driver) nlassert(m_UserVertexProgram == NULL);
if (m_DriverVertexProgram == program) if (m_DriverVertexProgram == program)
@ -165,30 +174,37 @@ namespace NL3D
IProgramDrvInfos *di = program->m_DrvInfo; IProgramDrvInfos *di = program->m_DrvInfo;
CVertexProgramDrvInfosGL3 *drvInfo = dynamic_cast< CVertexProgramDrvInfosGL3* >(di); CVertexProgramDrvInfosGL3 *drvInfo = dynamic_cast< CVertexProgramDrvInfosGL3* >(di);
if (drvInfo == NULL) if (drvInfo == NULL)
{
m_UserVertexProgram = NULL;
m_DriverVertexProgram = NULL;
return false; return false;
}
glGetError(); glGetError();
nglUseProgramStages(ppoId, GL_VERTEX_SHADER_BIT, drvInfo->getProgramId()); nglUseProgramStages(ppoId, GL_VERTEX_SHADER_BIT, drvInfo->getProgramId());
GLenum error = glGetError(); GLenum error = glGetError();
if (error != GL_NO_ERROR) if (error != GL_NO_ERROR)
{
m_UserVertexProgram = NULL;
m_DriverVertexProgram = NULL;
return false; return false;
}
if (!driver) m_UserVertexProgram = program; if (!driver) m_UserVertexProgram = program;
m_DriverVertexProgram = program; m_DriverVertexProgram = program;
return true; return true;
} }
bool CDriverGL3::supportPixelProgram(IProgram::TProfile profile) const bool CDriverGL3::supportPixelProgram(IProgram::TProfile profile) const
{ {
if (profile == IProgram::glsl330f) if (profile == IProgram::glsl330f)
return true; return true;
else else
return false; return false;
} }
bool CDriverGL3::compilePixelProgram(CPixelProgram *program) bool CDriverGL3::compilePixelProgram(CPixelProgram *program)
{ {
if (program->m_DrvInfo != NULL) if (program->m_DrvInfo != NULL)
return false; return false;
@ -241,15 +257,15 @@ namespace NL3D
program->buildInfo(src); program->buildInfo(src);
return true; return true;
} }
bool CDriverGL3::activePixelProgram(CPixelProgram *program) bool CDriverGL3::activePixelProgram(CPixelProgram *program)
{ {
return activePixelProgram(program, false); return activePixelProgram(program, false);
} }
bool CDriverGL3::activePixelProgram(CPixelProgram *program, bool driver) bool CDriverGL3::activePixelProgram(CPixelProgram *program, bool driver)
{ {
if (driver) nlassert(m_UserPixelProgram == NULL); if (driver) nlassert(m_UserPixelProgram == NULL);
if (m_DriverPixelProgram == program) if (m_DriverPixelProgram == program)
@ -264,28 +280,39 @@ namespace NL3D
} }
if (program->m_DrvInfo == NULL) if (program->m_DrvInfo == NULL)
{
m_UserPixelProgram = NULL;
m_DriverPixelProgram = NULL;
return false; return false;
}
IProgramDrvInfos *di = program->m_DrvInfo; IProgramDrvInfos *di = program->m_DrvInfo;
CPixelProgramDrvInfosGL3 *drvInfo = dynamic_cast< CPixelProgramDrvInfosGL3* >(di); CPixelProgramDrvInfosGL3 *drvInfo = dynamic_cast< CPixelProgramDrvInfosGL3* >(di);
if (drvInfo == NULL) if (drvInfo == NULL)
{
m_UserPixelProgram = NULL;
m_DriverPixelProgram = NULL;
return false; return false;
}
glGetError(); glGetError();
nglUseProgramStages(ppoId, GL_FRAGMENT_SHADER_BIT, drvInfo->getProgramId()); nglUseProgramStages(ppoId, GL_FRAGMENT_SHADER_BIT, drvInfo->getProgramId());
GLenum error = glGetError(); GLenum error = glGetError();
if (error != GL_NO_ERROR) if (error != GL_NO_ERROR)
{
m_UserPixelProgram = NULL;
m_DriverPixelProgram = NULL;
return false; return false;
}
if (!driver) m_UserPixelProgram = program; if (!driver) m_UserPixelProgram = program;
m_DriverPixelProgram = program; m_DriverPixelProgram = program;
return true; return true;
} }
uint32 CDriverGL3::getProgramId(TProgram program) const uint32 CDriverGL3::getProgramId(TProgram program) const
{ {
uint32 id = 0; uint32 id = 0;
switch(program) switch(program)
@ -315,10 +342,10 @@ namespace NL3D
} }
return id; return id;
} }
IProgram* CDriverGL3::getProgram(TProgram program) const IProgram* CDriverGL3::getProgram(TProgram program) const
{ {
switch(program) switch(program)
{ {
case IDriver::VertexProgram: case IDriver::VertexProgram:
@ -330,142 +357,142 @@ namespace NL3D
} }
return NULL; return NULL;
} }
int CDriverGL3::getUniformLocation(TProgram program, const char *name) int CDriverGL3::getUniformLocation(TProgram program, const char *name)
{ {
uint32 id = getProgramId(program); uint32 id = getProgramId(program);
return nglGetUniformLocation(id, name); return nglGetUniformLocation(id, name);
} }
void CDriverGL3::setUniform1f(TProgram program, uint index, float f0) void CDriverGL3::setUniform1f(TProgram program, uint index, float f0)
{ {
uint32 id = getProgramId(program); uint32 id = getProgramId(program);
nglProgramUniform1f(id, index, f0); nglProgramUniform1f(id, index, f0);
} }
void CDriverGL3::setUniform2f(TProgram program, uint index, float f0, float f1) void CDriverGL3::setUniform2f(TProgram program, uint index, float f0, float f1)
{ {
uint32 id = getProgramId(program); uint32 id = getProgramId(program);
nglProgramUniform2f(id, index, f0, f1); nglProgramUniform2f(id, index, f0, f1);
} }
void CDriverGL3::setUniform3f(TProgram program, uint index, float f0, float f1, float f2) void CDriverGL3::setUniform3f(TProgram program, uint index, float f0, float f1, float f2)
{ {
uint32 id = getProgramId(program); uint32 id = getProgramId(program);
nglProgramUniform3f(id, index, f0, f1, f2); nglProgramUniform3f(id, index, f0, f1, f2);
} }
void CDriverGL3::setUniform4f(TProgram program, uint index, float f0, float f1, float f2, float f3) void CDriverGL3::setUniform4f(TProgram program, uint index, float f0, float f1, float f2, float f3)
{ {
uint32 id = getProgramId(program); uint32 id = getProgramId(program);
nglProgramUniform4f(id, index, f0, f1, f2, f3); nglProgramUniform4f(id, index, f0, f1, f2, f3);
} }
void CDriverGL3::setUniform1i(TProgram program, uint index, sint32 i0) void CDriverGL3::setUniform1i(TProgram program, uint index, sint32 i0)
{ {
uint32 id = getProgramId(program); uint32 id = getProgramId(program);
nglProgramUniform1i(id, index, i0); nglProgramUniform1i(id, index, i0);
} }
void CDriverGL3::setUniform2i(TProgram program, uint index, sint32 i0, sint32 i1) void CDriverGL3::setUniform2i(TProgram program, uint index, sint32 i0, sint32 i1)
{ {
uint32 id = getProgramId(program); uint32 id = getProgramId(program);
nglProgramUniform2i(id, index, i0, i1); nglProgramUniform2i(id, index, i0, i1);
} }
void CDriverGL3::setUniform3i(TProgram program, uint index, sint32 i0, sint32 i1, sint32 i2) void CDriverGL3::setUniform3i(TProgram program, uint index, sint32 i0, sint32 i1, sint32 i2)
{ {
uint32 id = getProgramId(program); uint32 id = getProgramId(program);
nglProgramUniform3i(id, index, i0, i1, i2); nglProgramUniform3i(id, index, i0, i1, i2);
} }
void CDriverGL3::setUniform4i(TProgram program, uint index, sint32 i0, sint32 i1, sint32 i2, sint32 i3) void CDriverGL3::setUniform4i(TProgram program, uint index, sint32 i0, sint32 i1, sint32 i2, sint32 i3)
{ {
uint32 id = getProgramId(program); uint32 id = getProgramId(program);
nglProgramUniform4i(id, index, i0, i1, i2, i3); nglProgramUniform4i(id, index, i0, i1, i2, i3);
} }
void CDriverGL3::setUniform1ui(TProgram program, uint index, uint32 ui0) void CDriverGL3::setUniform1ui(TProgram program, uint index, uint32 ui0)
{ {
uint32 id = getProgramId(program); uint32 id = getProgramId(program);
nglProgramUniform1ui(id, index, ui0); nglProgramUniform1ui(id, index, ui0);
} }
void CDriverGL3::setUniform2ui(TProgram program, uint index, uint32 ui0, uint32 ui1) void CDriverGL3::setUniform2ui(TProgram program, uint index, uint32 ui0, uint32 ui1)
{ {
uint32 id = getProgramId(program); uint32 id = getProgramId(program);
nglProgramUniform2ui(id, index, ui0, ui1); nglProgramUniform2ui(id, index, ui0, ui1);
} }
void CDriverGL3::setUniform3ui(TProgram program, uint index, uint32 ui0, uint32 ui1, uint32 ui2) void CDriverGL3::setUniform3ui(TProgram program, uint index, uint32 ui0, uint32 ui1, uint32 ui2)
{ {
uint32 id = getProgramId(program); uint32 id = getProgramId(program);
nglProgramUniform3ui(id, index, ui0, ui1, ui2); nglProgramUniform3ui(id, index, ui0, ui1, ui2);
} }
void CDriverGL3::setUniform4ui(TProgram program, uint index, uint32 ui0, uint32 ui1, uint32 ui2, uint32 ui3) void CDriverGL3::setUniform4ui(TProgram program, uint index, uint32 ui0, uint32 ui1, uint32 ui2, uint32 ui3)
{ {
uint32 id = getProgramId(program); uint32 id = getProgramId(program);
nglProgramUniform4ui(id, index, ui0, ui1, ui2, ui3); nglProgramUniform4ui(id, index, ui0, ui1, ui2, ui3);
} }
void CDriverGL3::setUniform3f(TProgram program, uint index, const CVector &v) void CDriverGL3::setUniform3f(TProgram program, uint index, const CVector &v)
{ {
uint32 id = getProgramId(program); uint32 id = getProgramId(program);
nglProgramUniform3f(id, index, v.x, v.y, v.z); nglProgramUniform3f(id, index, v.x, v.y, v.z);
} }
void CDriverGL3::setUniform4f(TProgram program, uint index, const CVector &v, float f3) void CDriverGL3::setUniform4f(TProgram program, uint index, const CVector &v, float f3)
{ {
uint32 id = getProgramId(program); uint32 id = getProgramId(program);
nglProgramUniform4f(id, index, v.x, v.y, v.z, f3); nglProgramUniform4f(id, index, v.x, v.y, v.z, f3);
} }
void CDriverGL3::setUniform4f(TProgram program, uint index, const NLMISC::CRGBAF& rgba) void CDriverGL3::setUniform4f(TProgram program, uint index, const NLMISC::CRGBAF& rgba)
{ {
uint32 id = getProgramId(program); uint32 id = getProgramId(program);
nglProgramUniform4f(id, index, rgba.R, rgba.G, rgba.B, rgba.A); nglProgramUniform4f(id, index, rgba.R, rgba.G, rgba.B, rgba.A);
} }
void CDriverGL3::setUniform3x3f(TProgram program, uint index, const float *src) void CDriverGL3::setUniform3x3f(TProgram program, uint index, const float *src)
{ {
uint32 id = getProgramId(program); uint32 id = getProgramId(program);
nglProgramUniformMatrix3fv(id, index, 1, false, src); nglProgramUniformMatrix3fv(id, index, 1, false, src);
} }
void CDriverGL3::setUniform4x4f(TProgram program, uint index, const CMatrix &m) void CDriverGL3::setUniform4x4f(TProgram program, uint index, const CMatrix &m)
{ {
uint32 id = getProgramId(program); uint32 id = getProgramId(program);
nglProgramUniformMatrix4fv(id, index, 1, false, m.get()); nglProgramUniformMatrix4fv(id, index, 1, false, m.get());
} }
void CDriverGL3::setUniform4x4f(TProgram program, uint index, const float *src) void CDriverGL3::setUniform4x4f(TProgram program, uint index, const float *src)
{ {
uint32 id = getProgramId(program); uint32 id = getProgramId(program);
nglProgramUniformMatrix4fv(id, index, 1, false, src); nglProgramUniformMatrix4fv(id, index, 1, false, src);
} }
void CDriverGL3::setUniform4fv(TProgram program, uint index, size_t num, const float *src) void CDriverGL3::setUniform4fv(TProgram program, uint index, size_t num, const float *src)
{ {
uint32 id = getProgramId(program); uint32 id = getProgramId(program);
nglProgramUniform4fv(id, index, num, src); nglProgramUniform4fv(id, index, num, src);
} }
void CDriverGL3::setUniform4iv(TProgram program, uint index, size_t num, const sint32 *src) void CDriverGL3::setUniform4iv(TProgram program, uint index, size_t num, const sint32 *src)
{ {
uint32 id = getProgramId(program); uint32 id = getProgramId(program);
nglProgramUniform4iv(id, index, num, src); nglProgramUniform4iv(id, index, num, src);
} }
void CDriverGL3::setUniform4uiv(TProgram program, uint index, size_t num, const uint32 *src) void CDriverGL3::setUniform4uiv(TProgram program, uint index, size_t num, const uint32 *src)
{ {
uint32 id = getProgramId(program); uint32 id = getProgramId(program);
nglProgramUniform4uiv(id, index, num, src); nglProgramUniform4uiv(id, index, num, src);
} }
void CDriverGL3::setUniformMatrix(TProgram program, uint index, TMatrix matrix, TTransform transform) void CDriverGL3::setUniformMatrix(TProgram program, uint index, TMatrix matrix, TTransform transform)
{ {
uint32 id = getProgramId(program); uint32 id = getProgramId(program);
CMatrix mat; CMatrix mat;
@ -499,17 +526,17 @@ namespace NL3D
nglProgramUniformMatrix4fv(id, index, 1, false, mat.get()); nglProgramUniformMatrix4fv(id, index, 1, false, mat.get());
} }
void CDriverGL3::setUniformFog(TProgram program, uint index) void CDriverGL3::setUniformFog(TProgram program, uint index)
{ {
uint32 id = getProgramId(program); uint32 id = getProgramId(program);
const float *v = _ModelViewMatrix.get(); const float *v = _ModelViewMatrix.get();
nglProgramUniform4f(id, index, -v[ 2 ], -v[ 6 ], -v[ 10 ], -v[ 4 ]); nglProgramUniform4f(id, index, -v[ 2 ], -v[ 6 ], -v[ 10 ], -v[ 4 ]);
} }
void CDriverGL3::generateShaderDesc(CShaderDesc &desc, CMaterial &mat) void CDriverGL3::generateShaderDesc(CShaderDesc &desc, CMaterial &mat)
{ {
desc.setShaderType(mat.getShader()); desc.setShaderType(mat.getShader());
desc.setVBFlags(_CurrentVertexBufferHard->VB->getVertexFormat()); desc.setVBFlags(_CurrentVertexBufferHard->VB->getVertexFormat());
@ -522,7 +549,7 @@ namespace NL3D
{ {
bool useTextures = false; bool useTextures = false;
int maxTextures = std::min(int(SHADER_MAX_TEXTURES), int(IDRV_MAT_MAXTEXTURES)); int maxTextures = std::min(int(IDRV_MAT_MAXTEXTURES), int(IDRV_MAT_MAXTEXTURES));
for (int i = 0; i < maxTextures; i++) for (int i = 0; i < maxTextures; i++)
{ {
desc.setTexEnvMode(i, mat.getTexEnvMode(i)); desc.setTexEnvMode(i, mat.getTexEnvMode(i));
@ -530,7 +557,7 @@ namespace NL3D
for (int i = 0; i < maxTextures; i++) for (int i = 0; i < maxTextures; i++)
{ {
if (desc.hasVBFlags(vertexFlags[ TexCoord0 + i ])) if (desc.hasVBFlags(g_VertexFlags[ TexCoord0 + i ]))
{ {
desc.setUseTexStage(i, true); desc.setUseTexStage(i, true);
useTextures = true; useTextures = true;
@ -561,20 +588,24 @@ namespace NL3D
desc.setAlphaTestThreshold(mat.getAlphaTestThreshold()); desc.setAlphaTestThreshold(mat.getAlphaTestThreshold());
} }
if (fogEnabled()) if (m_VPBuiltinCurrent.Fog)
{ {
desc.setFog(true); desc.setFog(true);
desc.setFogMode(CShaderDesc::Linear); desc.setFogMode(CShaderDesc::Linear);
} }
int maxLights = std::min(int(SHADER_MAX_LIGHTS), int(MaxLight)); //bool enableLights = false;
bool enableLights = false; for (int i = 0; i < MaxLight; i++)
for (int i = 0; i < maxLights; i++)
{ {
if (!_UserLightEnable[ i ]) if (!_UserLightEnable[i])
{
desc.setLight(i, CShaderDesc::Nolight);
continue; continue;
}
//if (!_UserLightEnable[ i ])
// continue;
enableLights = true; //enableLights = true;
switch(_LightMode[ i ]) switch(_LightMode[ i ])
{ {
@ -593,18 +624,18 @@ namespace NL3D
} }
desc.setLighting(enableLights); desc.setLighting(/*enableLights && mat.isLighted() &&*/ m_VPBuiltinCurrent.Lighting);
} }
bool CDriverGL3::setupBuiltinPrograms(CMaterial &mat) bool CDriverGL3::setupBuiltinPrograms(CMaterial &mat)
{ {
return setupBuiltinVertexProgram() return setupBuiltinVertexProgram()
&& setupBuiltinPixelProgram(mat) && setupBuiltinPixelProgram(mat)
&& setupUniforms(); && setupUniforms();
} }
bool CDriverGL3::setupBuiltinVertexProgram() bool CDriverGL3::setupBuiltinVertexProgram()
{ {
if (m_UserVertexProgram) return true; if (m_UserVertexProgram) return true;
touchVertexFormatVP(); // TODO touchVertexFormatVP(); // TODO
@ -622,10 +653,10 @@ namespace NL3D
// GL3 TODO: Here we set the uniforms of the vertex program! // GL3 TODO: Here we set the uniforms of the vertex program!
return true; return true;
} }
bool CDriverGL3::setupBuiltinPixelProgram(CMaterial &mat) bool CDriverGL3::setupBuiltinPixelProgram(CMaterial &mat)
{ {
if (m_UserPixelProgram) return true; if (m_UserPixelProgram) return true;
// nlassert(!m_UserVertexProgram); // TEMP // nlassert(!m_UserVertexProgram); // TEMP
@ -749,10 +780,10 @@ namespace NL3D
} }
return true; return true;
} }
bool CDriverGL3::setupDynMatProgram(CMaterial& mat, uint pass) bool CDriverGL3::setupDynMatProgram(CMaterial& mat, uint pass)
{ {
/* /*
if ((currentProgram.vp != NULL) && (currentProgram.pp != NULL)) if ((currentProgram.vp != NULL) && (currentProgram.pp != NULL))
return true; return true;
@ -838,17 +869,17 @@ namespace NL3D
return true; return true;
*/ */
return false; return false;
} }
bool CDriverGL3::setupUniforms() bool CDriverGL3::setupUniforms()
{ {
setupUniforms(IDriver::VertexProgram); setupUniforms(IDriver::VertexProgram);
setupUniforms(IDriver::PixelProgram); setupUniforms(IDriver::PixelProgram);
return true; return true;
} }
void CDriverGL3::setupUniforms(TProgram program) void CDriverGL3::setupUniforms(TProgram program)
{ {
CMaterial &mat = *_CurrentMaterial; CMaterial &mat = *_CurrentMaterial;
IProgram *p = getProgram(program); IProgram *p = getProgram(program);
@ -942,7 +973,7 @@ namespace NL3D
} }
int maxLights = std::min(int(MaxLight), int(SHADER_MAX_LIGHTS)); int maxLights = std::min(int(MaxLight), int(NL_OPENGL3_MAX_LIGHT));
for (int i = 0; i < maxLights; i++) for (int i = 0; i < maxLights; i++)
{ {
if (!_UserLightEnable[ i ]) if (!_UserLightEnable[ i ])
@ -1064,10 +1095,10 @@ namespace NL3D
} }
} }
} }
bool CDriverGL3::initProgramPipeline() bool CDriverGL3::initProgramPipeline()
{ {
ppoId = 0; ppoId = 0;
nglGenProgramPipelines(1, &ppoId); nglGenProgramPipelines(1, &ppoId);
@ -1077,7 +1108,12 @@ namespace NL3D
nglBindProgramPipeline(ppoId); nglBindProgramPipeline(ppoId);
return true; return true;
}
} }
#ifdef NL_STATIC
} // NLDRIVERGL3
#endif
} // NL3D
/* end of file */

@ -0,0 +1,74 @@
// NeL - MMORPG Framework <http://dev.ryzom.com/projects/nel/>
// Copyright (C) 2014 by authors
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as
// published by the Free Software Foundation, either version 3 of the
// License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
#ifndef NL_DRIVER_OPENGL_PROGRAM_H
#define NL_DRIVER_OPENGL_PROGRAM_H
#include "nel/misc/types_nl.h"
namespace NL3D {
#ifdef NL_STATIC
namespace NLDRIVERGL3 {
#endif
enum TAttribOffset
{
Position,
Weight,
Normal,
PrimaryColor,
SecondaryColor,
Fog,
PaletteSkin,
Empty,
TexCoord0,
TexCoord1,
TexCoord2,
TexCoord3,
TexCoord4,
TexCoord5,
TexCoord6,
TexCoord7,
NumOffsets
};
extern const uint16 g_VertexFlags[CVertexBuffer::NumValue];
extern const char *g_AttribNames[CVertexBuffer::NumValue];
extern const char *g_TexelNames[IDRV_MAT_MAXTEXTURES];
extern const char *g_ConstantNames[4];
namespace /* anonymous */ {
inline bool hasFlag(uint32 data, uint32 flag)
{
if ((data & flag) != 0)
return true;
else
return false;
}
} /* anonymous namespace */
#ifdef NL_STATIC
} // NLDRIVERGL3
#endif
} // NL3D
#endif // NL_DRIVER_OPENGL_PROGRAM_H
/* end of file */

@ -19,9 +19,6 @@
#include "nel/misc/types_nl.h" #include "nel/misc/types_nl.h"
#define SHADER_MAX_TEXTURES 4
#define SHADER_MAX_LIGHTS 8
namespace NL3D namespace NL3D
{ {
class CVertexProgram; class CVertexProgram;
@ -86,13 +83,13 @@ namespace NL3D
}; };
CShaderDesc() { CShaderDesc() {
for (int i = 0; i < SHADER_MAX_TEXTURES; i++) for (int i = 0; i < IDRV_MAT_MAXTEXTURES; i++)
texEnvMode[ i ] = 0; texEnvMode[ i ] = 0;
for (int i = 0; i < SHADER_MAX_LIGHTS; i++) for (int i = 0; i < NL_OPENGL3_MAX_LIGHT; i++)
lightMode[ i ] = Nolight; lightMode[ i ] = Nolight;
for (int i = 0; i < SHADER_MAX_TEXTURES; i++) for (int i = 0; i < IDRV_MAT_MAXTEXTURES; i++)
useTextureStage[ i ] = false; useTextureStage[ i ] = false;
useFirstTextureCoordSet = false; useFirstTextureCoordSet = false;
noTextures = true; noTextures = true;
@ -146,18 +143,18 @@ namespace NL3D
if (useFirstTextureCoordSet != o.useFirstTextureCoordSet) if (useFirstTextureCoordSet != o.useFirstTextureCoordSet)
return false; return false;
for (int i = 0; i < SHADER_MAX_TEXTURES; i++) for (int i = 0; i < IDRV_MAT_MAXTEXTURES; i++)
if (texEnvMode[ i ] != o.texEnvMode[ i ]) if (texEnvMode[ i ] != o.texEnvMode[ i ])
return false; return false;
for (int i = 0; i < SHADER_MAX_TEXTURES; i++) for (int i = 0; i < IDRV_MAT_MAXTEXTURES; i++)
if (useTextureStage[ i ] != o.useTextureStage[ i ]) if (useTextureStage[ i ] != o.useTextureStage[ i ])
return false; return false;
} }
if (lightingEnabled()) if (lightingEnabled())
{ {
for (int i = 0; i < SHADER_MAX_LIGHTS; i++) for (int i = 0; i < NL_OPENGL3_MAX_LIGHT; i++)
if (lightMode[ i ] != o.lightMode[ i ]) if (lightMode[ i ] != o.lightMode[ i ])
return false; return false;
} }
@ -258,8 +255,8 @@ namespace NL3D
}; };
uint32 features; uint32 features;
uint32 texEnvMode[ SHADER_MAX_TEXTURES ]; uint32 texEnvMode[ IDRV_MAT_MAXTEXTURES ];
bool useTextureStage[ SHADER_MAX_TEXTURES ]; bool useTextureStage[ IDRV_MAT_MAXTEXTURES ];
bool useFirstTextureCoordSet; bool useFirstTextureCoordSet;
bool noTextures; bool noTextures;
uint32 vbFlags; uint32 vbFlags;
@ -267,7 +264,7 @@ namespace NL3D
uint32 nlightmaps; uint32 nlightmaps;
float alphaTestTreshold; float alphaTestTreshold;
uint32 fogMode; uint32 fogMode;
TLightMode lightMode[ SHADER_MAX_LIGHTS ]; TLightMode lightMode[ NL_OPENGL3_MAX_LIGHT ];
bool pointLight; bool pointLight;
SShaderPair shaderPair; SShaderPair shaderPair;

@ -26,8 +26,6 @@ namespace NL3D {
namespace NLDRIVERGL3 { namespace NLDRIVERGL3 {
#endif #endif
#define NL_OPENGL3_MAX_LIGHT 8
// *************************************************************************** // ***************************************************************************
/** /**
* Class for optimizing calls to openGL states, by caching old ones. * Class for optimizing calls to openGL states, by caching old ones.

@ -23,6 +23,7 @@
#include "nel/3d/light.h" #include "nel/3d/light.h"
#include "driver_opengl.h" #include "driver_opengl.h"
#include "driver_opengl_program.h"
#include "driver_opengl_vertex_buffer_hard.h" #include "driver_opengl_vertex_buffer_hard.h"
namespace NL3D { namespace NL3D {
@ -51,91 +52,6 @@ bool operator<(const CVPBuiltin &left, const CVPBuiltin &right)
namespace namespace
{ {
inline bool hasFlag(uint32 data, uint32 flag)
{
if ((data & flag) != 0)
return true;
else
return false;
}
enum TAttribOffset
{
Position,
Weight,
Normal,
PrimaryColor,
SecondaryColor,
Fog,
PaletteSkin,
Empty,
TexCoord0,
TexCoord1,
TexCoord2,
TexCoord3,
TexCoord4,
TexCoord5,
TexCoord6,
TexCoord7,
NumOffsets
};
const uint16 s_VertexFlags[CVertexBuffer::NumValue] =
{
CVertexBuffer::PositionFlag,
CVertexBuffer::WeightFlag,
CVertexBuffer::NormalFlag,
CVertexBuffer::PrimaryColorFlag,
CVertexBuffer::SecondaryColorFlag,
CVertexBuffer::FogFlag,
CVertexBuffer::PaletteSkinFlag,
0,
CVertexBuffer::TexCoord0Flag,
CVertexBuffer::TexCoord1Flag,
CVertexBuffer::TexCoord2Flag,
CVertexBuffer::TexCoord3Flag,
CVertexBuffer::TexCoord4Flag,
CVertexBuffer::TexCoord5Flag,
CVertexBuffer::TexCoord6Flag,
CVertexBuffer::TexCoord7Flag
};
const char *s_AttribNames[ CVertexBuffer::NumValue ] =
{
"position",
"weight",
"normal",
"color",
"color2",
"fog",
"paletteSkin",
"none",
"texCoord0",
"texCoord1",
"texCoord2",
"texCoord3",
"texCoord4",
"texCoord5",
"texCoord6",
"texCoord7"
};
const char *s_TexelNames[ SHADER_MAX_TEXTURES ] =
{
"texel0",
"texel1",
"texel2",
"texel3"
};
const char *s_ConstantNames[ 4 ] =
{
"constant0",
"constant1",
"constant2",
"constant3"
};
void vpLightUniforms(std::stringstream &ss, const CVPBuiltin &desc, int i) void vpLightUniforms(std::stringstream &ss, const CVPBuiltin &desc, int i)
{ {
switch (desc.LightMode[i]) switch (desc.LightMode[i])
@ -288,13 +204,13 @@ namespace
ss << std::endl; ss << std::endl;
for (int i = Position; i < NumOffsets; ++i) for (int i = Position; i < NumOffsets; ++i)
if (hasFlag(desc.VertexFormat, s_VertexFlags[i])) if (hasFlag(desc.VertexFormat, g_VertexFlags[i]))
ss << "layout (location = " << i << ") " << "in vec4 " << "v" << s_AttribNames[i] << ";" << std::endl; ss << "layout (location = " << i << ") " << "in vec4 " << "v" << g_AttribNames[i] << ";" << std::endl;
ss << std::endl; ss << std::endl;
for (int i = Weight; i < NumOffsets; ++i) for (int i = Weight; i < NumOffsets; ++i)
if (hasFlag(desc.VertexFormat, s_VertexFlags[i])) if (hasFlag(desc.VertexFormat, g_VertexFlags[i]))
ss << "smooth out vec4 " << s_AttribNames[i] << ";" << std::endl; ss << "smooth out vec4 " << g_AttribNames[i] << ";" << std::endl;
ss << std::endl; ss << std::endl;
// if (!useTextures) { // if (!useTextures) {
@ -327,10 +243,10 @@ namespace
ss << "void main(void)" << std::endl; ss << "void main(void)" << std::endl;
ss << "{" << std::endl; ss << "{" << std::endl;
ss << "gl_Position = modelViewProjection * " << "v" << s_AttribNames[0] << ";" << std::endl; ss << "gl_Position = modelViewProjection * " << "v" << g_AttribNames[0] << ";" << std::endl;
if (desc.Fog || desc.Lighting) if (desc.Fog || desc.Lighting)
ss << "ecPos4 = modelView * v" << s_AttribNames[0] << ";" << std::endl; ss << "ecPos4 = modelView * v" << g_AttribNames[0] << ";" << std::endl;
if (desc.Fog) if (desc.Fog)
ss << "ecPos = ecPos4;" << std::endl; ss << "ecPos = ecPos4;" << std::endl;
@ -344,9 +260,9 @@ namespace
for (int i = Weight; i < NumOffsets; i++) for (int i = Weight; i < NumOffsets; i++)
{ {
if (hasFlag(desc.VertexFormat, s_VertexFlags[i])) if (hasFlag(desc.VertexFormat, g_VertexFlags[i]))
{ {
ss << s_AttribNames[i] << " = " << "v" << s_AttribNames[i] << ";" << std::endl; ss << g_AttribNames[i] << " = " << "v" << g_AttribNames[i] << ";" << std::endl;
} }
} }

@ -62,3 +62,5 @@
#include "nel/misc/command.h" #include "nel/misc/command.h"
#include "nel/3d/driver.h" #include "nel/3d/driver.h"
#define NL_OPENGL3_MAX_LIGHT 8

Loading…
Cancel
Save