diff --git a/code/nel/src/3d/driver/opengl3/driver_glsl_shader_generator.cpp b/code/nel/src/3d/driver/opengl3/driver_glsl_shader_generator.cpp index 810a7b1ff..4d6e48a15 100644 --- a/code/nel/src/3d/driver/opengl3/driver_glsl_shader_generator.cpp +++ b/code/nel/src/3d/driver/opengl3/driver_glsl_shader_generator.cpp @@ -827,16 +827,8 @@ namespace NL3D void CGLSLShaderGenerator::generateSpecular() { - /*s << "vec4 texel;" << std::endl; - ss << "texel.rgb = texel0.rgb * diffuseColor.rgb;" << std::endl; - ss << "texel.a = texel0.a;" << std::endl; - ss << "texel.rgb = texel1.rgb * texel.a + texel.rgb;" << std::endl; - ss << "texel.a = texel1.a;" << std::endl;*/ - - // FIXME GL3 SPECULAR: VERIFY IF THIS WORKS - ss << "vec3 specop0 = texel0.rgb * diffuse.rgb;" << std::endl; - ss << "vec4 specop1 = vec4(texel1.rgb * texel0.a + specop0, texel0.a);" << std::endl; + ss << "vec4 specop1 = vec4(texel1.rgb * texel0.a + specop0, diffuse.a);" << std::endl; ss << "fragColor = specop1;" << std::endl; } diff --git a/code/nel/src/3d/driver/opengl3/driver_opengl.h b/code/nel/src/3d/driver/opengl3/driver_opengl.h index 979d5e8f2..5157097f5 100644 --- a/code/nel/src/3d/driver/opengl3/driver_opengl.h +++ b/code/nel/src/3d/driver/opengl3/driver_opengl.h @@ -214,7 +214,7 @@ public: // *************************************************************************** -class CShaderGL3 : public IMaterialDrvInfos +class CMaterialDrvInfosGL3 : public IMaterialDrvInfos { public: GLenum SrcBlend; @@ -234,7 +234,10 @@ public: // The supported Shader type. CMaterial::TShader SupportedShader; - CShaderGL3(IDriver *drv, ItMatDrvInfoPtrList it) : IMaterialDrvInfos(drv, it) {} + // PP builtin + CPPBuiltin PPBuiltin; + + CMaterialDrvInfosGL3(IDriver *drv, ItMatDrvInfoPtrList it) : IMaterialDrvInfos(drv, it) {} }; @@ -393,6 +396,8 @@ public: void touchVertexFormatVP(); void setTexGenModeVP(uint stage, sint mode); + void generateBuiltinPixelProgram(CMaterial &mat); + virtual void startSpecularBatch(); virtual void endSpecularBatch(); @@ -1345,6 +1350,9 @@ private: NLMISC::CRefPtr m_DriverGeometryProgram; NLMISC::CRefPtr m_DriverPixelProgram; + friend class CPPBuiltin; + std::set m_PPBuiltinCache; + std::set m_VPBuiltinCache; CVPBuiltin m_VPBuiltinCurrent; bool m_VPBuiltinTouched; diff --git a/code/nel/src/3d/driver/opengl3/driver_opengl_material.cpp b/code/nel/src/3d/driver/opengl3/driver_opengl_material.cpp index a49056f02..f6941e80c 100644 --- a/code/nel/src/3d/driver/opengl3/driver_opengl_material.cpp +++ b/code/nel/src/3d/driver/opengl3/driver_opengl_material.cpp @@ -243,7 +243,7 @@ bool CDriverGL3::setupMaterial(CMaterial& mat) return true; } - CShaderGL3* pShader; + CMaterialDrvInfosGL3* pShader; CMaterial::TShader matShader; GLenum glenum = GL_ZERO; uint32 touched = mat.getTouched(); @@ -260,12 +260,12 @@ bool CDriverGL3::setupMaterial(CMaterial& mat) // insert into driver list. (so it is deleted when driver is deleted). ItMatDrvInfoPtrList it= _MatDrvInfos.insert(_MatDrvInfos.end(), (NL3D::IMaterialDrvInfos*)NULL); // create and set iterator, for future deletion. - *it= mat._MatDrvInfo= new CShaderGL3(this, it); + *it= mat._MatDrvInfo= new CMaterialDrvInfosGL3(this, it); // Must create all OpenGL shader states. touched= IDRV_TOUCHED_ALL; } - pShader=static_cast((IMaterialDrvInfos*)(mat._MatDrvInfo)); + pShader=static_cast((IMaterialDrvInfos*)(mat._MatDrvInfo)); // 1. Setup modified fields of material. //===================================== diff --git a/code/nel/src/3d/driver/opengl3/driver_opengl_pixel_program.cpp b/code/nel/src/3d/driver/opengl3/driver_opengl_pixel_program.cpp new file mode 100644 index 000000000..e5c703144 --- /dev/null +++ b/code/nel/src/3d/driver/opengl3/driver_opengl_pixel_program.cpp @@ -0,0 +1,114 @@ +// NeL - MMORPG Framework +// 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 . + +#include "stdopengl.h" + +#include + +#include "nel/3d/vertex_program.h" +#include "nel/3d/light.h" + +#include "driver_opengl.h" +#include "driver_opengl_program.h" +#include "driver_opengl_vertex_buffer_hard.h" + +namespace NL3D { + +#ifdef NL_STATIC +namespace NLDRIVERGL3 { +#endif + +bool operator<(const CPPBuiltin &left, const CPPBuiltin &right) +{ + // Material state + + // Driver state + if (left.VertexFormat != right.VertexFormat) + return left.VertexFormat < right.VertexFormat; + if (left.Fog != right.Fog) + return right.Fog; + + return false; +} + +namespace /* anonymous */ { + +void ppGenerate(std::string &result, CPPBuiltin &desc) +{ + +} + +} /* anonymous namespace */ + +void CDriverGL3::generateBuiltinPixelProgram(CMaterial &mat) +{ + CMaterialDrvInfosGL3 *matDrv = static_cast((IMaterialDrvInfos *)(mat._MatDrvInfo)); + nlassert(matDrv); + + std::set::iterator it = m_PPBuiltinCache.find(matDrv->PPBuiltin); + if (it != m_PPBuiltinCache.end()) + { + matDrv->PPBuiltin.PixelProgram = it->PixelProgram; + return; + } + + std::string result; + ppGenerate(result, matDrv->PPBuiltin); + + CPixelProgram *program = new CPixelProgram(); + IProgram::CSource *src = new IProgram::CSource(); + src->Profile = IProgram::glsl330f; + src->DisplayName = "Builtin Pixel Program (" + NLMISC::toString(m_PPBuiltinCache.size()) + ")"; + src->setSource(result); + program->addSource(src); + + nldebug("GL3: Generate '%s'", src->DisplayName.c_str()); + + if (!compilePixelProgram(program)) + { + delete program; + program = NULL; + } + + matDrv->PPBuiltin.PixelProgram = program; + m_PPBuiltinCache.insert(matDrv->PPBuiltin); +} + +void CPPBuiltin::checkDriverStateTouched(CDriverGL3 *driver) +{ + if (VertexFormat != driver->m_VPBuiltinCurrent.VertexFormat) + { + VertexFormat = driver->m_VPBuiltinCurrent.VertexFormat; + Touched = true; + } + if (Fog != driver->m_VPBuiltinCurrent.Fog) + { + Fog = driver->m_VPBuiltinCurrent.Fog; + Touched = true; + } +} + +void CPPBuiltin::checkMaterialStateTouched(CMaterial &mat) +{ + +} + +#ifdef NL_STATIC +} // NLDRIVERGL3 +#endif + +} // NL3D + diff --git a/code/nel/src/3d/driver/opengl3/driver_opengl_program.h b/code/nel/src/3d/driver/opengl3/driver_opengl_program.h index 8e5f96163..2a50af642 100644 --- a/code/nel/src/3d/driver/opengl3/driver_opengl_program.h +++ b/code/nel/src/3d/driver/opengl3/driver_opengl_program.h @@ -25,6 +25,8 @@ namespace NL3D { namespace NLDRIVERGL3 { #endif +class CDriverGL3; + static sint TexGenDisabled = -1; static sint TexGenReflectionMap = 0; // GL_REFLECTION_MAP_ARB static sint TexGenSphereMap = 1; // GL_SPHERE_MAP @@ -47,6 +49,22 @@ struct CVPBuiltin bool operator<(const CVPBuiltin &left, const CVPBuiltin &right); +/// Builtin pixel program description +struct CPPBuiltin +{ + uint16 VertexFormat; + bool Fog; + + CPixelProgram *PixelProgram; + + bool Touched; + + void checkDriverStateTouched(CDriverGL3 *driver); + void checkMaterialStateTouched(CMaterial &mat); +}; + +bool operator<(const CPPBuiltin &left, const CPPBuiltin &right); + enum TAttribOffset { Position, diff --git a/code/nel/src/3d/driver/opengl3/driver_opengl_vertex_program.cpp b/code/nel/src/3d/driver/opengl3/driver_opengl_vertex_program.cpp index cea622efc..63dc923b4 100644 --- a/code/nel/src/3d/driver/opengl3/driver_opengl_vertex_program.cpp +++ b/code/nel/src/3d/driver/opengl3/driver_opengl_vertex_program.cpp @@ -54,231 +54,227 @@ bool operator<(const CVPBuiltin &left, const CVPBuiltin &right) return false; } -namespace +namespace /* anonymous */ { + +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]) - { - case CLight::DirectionalLight: - ss << "uniform vec3 light" << i << "DirOrPos;" << std::endl; - ss << "uniform vec4 light" << i << "ColDiff;" << std::endl; - //ss << "uniform vec4 light" << i << "ColAmb;" << std::endl; - ss << "uniform vec4 light" << i << "ColSpec;" << std::endl; - ss << "uniform float light" << i << "Shininess;" << std::endl; - break; - case CLight::PointLight: - ss << "uniform vec3 light" << i << "DirOrPos;" << std::endl; - ss << "uniform vec4 light" << i << "ColDiff;" << std::endl; - //ss << "uniform vec4 light" << i << "ColAmb;" << std::endl; - ss << "uniform vec4 light" << i << "ColSpec;" << std::endl; - ss << "uniform float light" << i << "Shininess;" << std::endl; - ss << "uniform float light" << i << "ConstAttn;" << std::endl; - ss << "uniform float light" << i << "LinAttn;" << std::endl; - ss << "uniform float light" << i << "QuadAttn;" << std::endl; - break; - } + case CLight::DirectionalLight: + ss << "uniform vec3 light" << i << "DirOrPos;" << std::endl; + ss << "uniform vec4 light" << i << "ColDiff;" << std::endl; + //ss << "uniform vec4 light" << i << "ColAmb;" << std::endl; + ss << "uniform vec4 light" << i << "ColSpec;" << std::endl; + ss << "uniform float light" << i << "Shininess;" << std::endl; + break; + case CLight::PointLight: + ss << "uniform vec3 light" << i << "DirOrPos;" << std::endl; + ss << "uniform vec4 light" << i << "ColDiff;" << std::endl; + //ss << "uniform vec4 light" << i << "ColAmb;" << std::endl; + ss << "uniform vec4 light" << i << "ColSpec;" << std::endl; + ss << "uniform float light" << i << "Shininess;" << std::endl; + ss << "uniform float light" << i << "ConstAttn;" << std::endl; + ss << "uniform float light" << i << "LinAttn;" << std::endl; + ss << "uniform float light" << i << "QuadAttn;" << std::endl; + break; } +} - void vpLightFunctions(std::stringstream &ss, const CVPBuiltin &desc, int i) +void vpLightFunctions(std::stringstream &ss, const CVPBuiltin &desc, int i) +{ + switch (desc.LightMode[i]) { - switch (desc.LightMode[i]) - { - case CLight::DirectionalLight: - ss << "float getIntensity" << i << "(vec3 normal3, vec3 lightDir)" << std::endl; - ss << "{" << std::endl; - ss << "float angle = dot(lightDir, normal3);" << std::endl; - ss << "angle = max(0.0, angle);" << std::endl; - ss << "return angle;" << std::endl; - ss << "}" << std::endl; - ss << std::endl; - - ss << "float getSpecIntensity" << i << "(vec3 normal3, vec3 lightDir)" << std::endl; - ss << "{" << std::endl; - ss << "vec3 halfVector = normalize(lightDir + normal3);" << std::endl; - ss << "float angle = dot(normal3, halfVector);" << std::endl; - ss << "angle = max(0.0, angle);" << std::endl; - ss << "float si = pow(angle, light" << i << "Shininess);" << std::endl; - ss << "return si;" << std::endl; - ss << "}" << std::endl; - ss << std::endl; - - ss << "vec4 getLight" << i << "Color()" << std::endl; - ss << "{" << std::endl; - ss << "vec4 lightDir4 = viewMatrix * vec4(light" << i << "DirOrPos, 1.0);" << std::endl; - ss << "vec3 lightDir = lightDir4.xyz / lightDir4.w;" << std::endl; - ss << "lightDir = normalize(lightDir);" << std::endl; - ss << "vec3 normal3 = vnormal.xyz / vnormal.w;" << std::endl; - ss << "normal3 = normalMatrix * normal3;" << std::endl; - ss << "normal3 = normalize(normal3);" << std::endl; - - ss << "vec4 lc = getIntensity" << i << "(normal3, lightDir) * light" << i << "ColDiff + "; - ss << "getSpecIntensity" << i << "(normal3, lightDir) * light" << i << "ColSpec;" << std::endl; - - // ss << "return vec4(0.0, 0.0, 0.0, 0.0);" << std::endl; // DISABLE DIR LIGHT - - ss << "return lc;" << std::endl; - ss << "}" << std::endl; - ss << std::endl; - break; - case CLight::PointLight: - ss << "float getIntensity" << i << "(vec3 normal3, vec3 direction3)" << std::endl; - ss << "{" << std::endl; - ss << "float angle = dot(direction3, normal3);" << std::endl; - ss << "angle = max(0.0, angle);" << std::endl; - ss << "return angle;" << std::endl; - ss << "}" << std::endl; - ss << std::endl; - - ss << "float getSpecIntensity" << i << "(vec3 normal3, vec3 direction3)" << std::endl; - ss << "{" << std::endl; - ss << "vec3 halfVector = normalize(direction3 + normal3);" << std::endl; - ss << "float angle = dot(normal3, halfVector);" << std::endl; - ss << "angle = max(0.0, angle);" << std::endl; - ss << "float si = pow(angle, light" << i << "Shininess);" << std::endl; - ss << "return si;" << std::endl; - ss << "}" << std::endl; - ss << std::endl; - - ss << "vec4 getLight" << i << "Color()" << std::endl; - ss << "{" << std::endl; - ss << "vec3 ecPos3 = ecPos4.xyz / ecPos4.w;" << std::endl; - ss << "vec4 lightPos4 = viewMatrix * vec4(light" << i << "DirOrPos, 1.0);" << std::endl; - ss << "vec3 lightPos = lightPos4.xyz / lightPos4.w;" << std::endl; - ss << "vec3 lightDirection = lightPos - ecPos3;" << std::endl; - ss << "float lightDistance = length(lightDirection);" << std::endl; - ss << "lightDirection = normalize(lightDirection);" << std::endl; - - ss << "float attenuation = light" << i << "ConstAttn + "; - ss << "light" << i << "LinAttn * lightDistance +"; - ss << "light" << i << "QuadAttn * lightDistance * lightDistance;" << std::endl; - // ss << "attenuation = max(attenuation, 1.0);" << std::endl; // TEST - - ss << "vec3 normal3 = vnormal.xyz / vnormal.w;" << std::endl; - ss << "normal3 = normalMatrix * normal3;" << std::endl; - ss << "normal3 = normalize(normal3);" << std::endl; - - ss << "vec4 lc = getIntensity" << i << "(normal3, lightDirection) * light" << i << "ColDiff + "; - ss << "getSpecIntensity" << i << "(normal3, lightDirection) * light" << i << "ColSpec;" << std::endl; - - ss << "lc = lc / attenuation;" << std::endl; - - // ss << "return vec4(0.0, 0.0, 0.0, 0.0);" << std::endl; // DISABLE POINT LIGHT - - ss << "return lc;" << std::endl; - ss << "}" << std::endl; - ss << std::endl; - break; - } - } + case CLight::DirectionalLight: + ss << "float getIntensity" << i << "(vec3 normal3, vec3 lightDir)" << std::endl; + ss << "{" << std::endl; + ss << "float angle = dot(lightDir, normal3);" << std::endl; + ss << "angle = max(0.0, angle);" << std::endl; + ss << "return angle;" << std::endl; + ss << "}" << std::endl; + ss << std::endl; - void vsLighting(std::stringstream &ss, const CVPBuiltin &desc, int i) - { + ss << "float getSpecIntensity" << i << "(vec3 normal3, vec3 lightDir)" << std::endl; + ss << "{" << std::endl; + ss << "vec3 halfVector = normalize(lightDir + normal3);" << std::endl; + ss << "float angle = dot(normal3, halfVector);" << std::endl; + ss << "angle = max(0.0, angle);" << std::endl; + ss << "float si = pow(angle, light" << i << "Shininess);" << std::endl; + ss << "return si;" << std::endl; + ss << "}" << std::endl; + ss << std::endl; - } + ss << "vec4 getLight" << i << "Color()" << std::endl; + ss << "{" << std::endl; + ss << "vec4 lightDir4 = viewMatrix * vec4(light" << i << "DirOrPos, 1.0);" << std::endl; + ss << "vec3 lightDir = lightDir4.xyz / lightDir4.w;" << std::endl; + ss << "lightDir = normalize(lightDir);" << std::endl; + ss << "vec3 normal3 = vnormal.xyz / vnormal.w;" << std::endl; + ss << "normal3 = normalMatrix * normal3;" << std::endl; + ss << "normal3 = normalize(normal3);" << std::endl; - void vpGenerate(std::string &result, const CVPBuiltin &desc) - { - std::stringstream ss; - ss << "// Builtin Vertex Shader" << std::endl; + ss << "vec4 lc = getIntensity" << i << "(normal3, lightDir) * light" << i << "ColDiff + "; + ss << "getSpecIntensity" << i << "(normal3, lightDir) * light" << i << "ColSpec;" << std::endl; + + // ss << "return vec4(0.0, 0.0, 0.0, 0.0);" << std::endl; // DISABLE DIR LIGHT + + ss << "return lc;" << std::endl; + ss << "}" << std::endl; ss << std::endl; - ss << "#version 330" << std::endl; - ss << "#extension GL_ARB_separate_shader_objects : enable" << std::endl; - ss << "out gl_PerVertex" << std::endl; + break; + case CLight::PointLight: + ss << "float getIntensity" << i << "(vec3 normal3, vec3 direction3)" << std::endl; ss << "{" << std::endl; - ss << "vec4 gl_Position;" << std::endl; - ss << "};" << std::endl; - ss << std::endl; - ss << "uniform mat4 modelViewProjection;" << std::endl; + ss << "float angle = dot(direction3, normal3);" << std::endl; + ss << "angle = max(0.0, angle);" << std::endl; + ss << "return angle;" << std::endl; + ss << "}" << std::endl; ss << std::endl; - for (int i = Position; i < NumOffsets; ++i) - if (hasFlag(desc.VertexFormat, g_VertexFlags[i])) - ss << "layout (location = " << i << ") " << "in vec4 " << "v" << g_AttribNames[i] << ";" << std::endl; + ss << "float getSpecIntensity" << i << "(vec3 normal3, vec3 direction3)" << std::endl; + ss << "{" << std::endl; + ss << "vec3 halfVector = normalize(direction3 + normal3);" << std::endl; + ss << "float angle = dot(normal3, halfVector);" << std::endl; + ss << "angle = max(0.0, angle);" << std::endl; + ss << "float si = pow(angle, light" << i << "Shininess);" << std::endl; + ss << "return si;" << std::endl; + ss << "}" << std::endl; ss << std::endl; - for (int i = Weight; i < NumOffsets; ++i) - if (hasFlag(desc.VertexFormat, g_VertexFlags[i])) - ss << "smooth out vec4 " << g_AttribNames[i] << "; // vertex buffer" << std::endl; - ss << std::endl; + ss << "vec4 getLight" << i << "Color()" << std::endl; + ss << "{" << std::endl; + ss << "vec3 ecPos3 = ecPos4.xyz / ecPos4.w;" << std::endl; + ss << "vec4 lightPos4 = viewMatrix * vec4(light" << i << "DirOrPos, 1.0);" << std::endl; + ss << "vec3 lightPos = lightPos4.xyz / lightPos4.w;" << std::endl; + ss << "vec3 lightDirection = lightPos - ecPos3;" << std::endl; + ss << "float lightDistance = length(lightDirection);" << std::endl; + ss << "lightDirection = normalize(lightDirection);" << std::endl; - // For now shader will fail to compile if both texgen and vertex buffer tex coord are provided! This is by design. - for (int i = 0; i < IDRV_MAT_MAXTEXTURES; ++i) - if (desc.TexGenMode[i] >= 0) - ss << "smooth out vec4 texCoord" << i << "; // texgen (not implemented)" << std::endl; - ss << std::endl; + ss << "float attenuation = light" << i << "ConstAttn + "; + ss << "light" << i << "LinAttn * lightDistance +"; + ss << "light" << i << "QuadAttn * lightDistance * lightDistance;" << std::endl; + // ss << "attenuation = max(attenuation, 1.0);" << std::endl; // TEST - // TODO: Texgen parameters + ss << "vec3 normal3 = vnormal.xyz / vnormal.w;" << std::endl; + ss << "normal3 = normalMatrix * normal3;" << std::endl; + ss << "normal3 = normalize(normal3);" << std::endl; - // Ambient color of all lights is precalculated and added with self illumination, and multiplied with the material ambient. - if (desc.Lighting) - ss << "uniform vec4 selfIllumination;" << std::endl; + ss << "vec4 lc = getIntensity" << i << "(normal3, lightDirection) * light" << i << "ColDiff + "; + ss << "getSpecIntensity" << i << "(normal3, lightDirection) * light" << i << "ColSpec;" << std::endl; - if (desc.Fog || desc.Lighting) - ss << "uniform mat4 modelView;" << std::endl; - if (desc.Lighting) - ss << "uniform mat4 viewMatrix;" << std::endl; - if (desc.Fog || desc.Lighting) - ss << "vec4 ecPos4;" << std::endl; - if (desc.Fog) - ss << "smooth out vec4 ecPos;" << std::endl; + ss << "lc = lc / attenuation;" << std::endl; + + // ss << "return vec4(0.0, 0.0, 0.0, 0.0);" << std::endl; // DISABLE POINT LIGHT + + ss << "return lc;" << std::endl; + ss << "}" << std::endl; ss << std::endl; + break; + } +} - if (desc.Lighting) - { - ss << "uniform mat3 normalMatrix;" << std::endl; - for (int i = 0; i < NL_OPENGL3_MAX_LIGHT; ++i) - vpLightUniforms(ss, desc, i); - ss << "smooth out vec4 lightColor;" << std::endl; - ss << std::endl; - - for (int i = 0; i < NL_OPENGL3_MAX_LIGHT; ++i) - vpLightFunctions(ss, desc, i); - ss << std::endl; - } - - ss << "void main(void)" << std::endl; - ss << "{" << std::endl; - ss << "gl_Position = modelViewProjection * " << "v" << g_AttribNames[0] << ";" << std::endl; +void vpGenerate(std::string &result, const CVPBuiltin &desc) +{ + std::stringstream ss; + ss << "// Builtin Vertex Shader" << std::endl; + ss << std::endl; + ss << "#version 330" << std::endl; + ss << "#extension GL_ARB_separate_shader_objects : enable" << std::endl; + ss << "out gl_PerVertex" << std::endl; + ss << "{" << std::endl; + ss << "vec4 gl_Position;" << std::endl; + ss << "};" << std::endl; + ss << std::endl; + ss << "uniform mat4 modelViewProjection;" << std::endl; + ss << std::endl; + + for (int i = Position; i < NumOffsets; ++i) + if (hasFlag(desc.VertexFormat, g_VertexFlags[i])) + ss << "layout (location = " << i << ") " << "in vec4 " << "v" << g_AttribNames[i] << ";" << std::endl; + ss << std::endl; + + for (int i = Weight; i < NumOffsets; ++i) + if (hasFlag(desc.VertexFormat, g_VertexFlags[i])) + ss << "smooth out vec4 " << g_AttribNames[i] << "; // vertex buffer" << std::endl; + ss << std::endl; + + // For now shader will fail to compile if both texgen and vertex buffer tex coord are provided! This is by design. + for (int i = 0; i < IDRV_MAT_MAXTEXTURES; ++i) + if (desc.TexGenMode[i] >= 0) + ss << "smooth out vec4 texCoord" << i << "; // texgen (not implemented)" << std::endl; + ss << std::endl; + + // TODO: Texgen parameters + + // Ambient color of all lights is precalculated and added with self illumination, and multiplied with the material ambient. + if (desc.Lighting) + ss << "uniform vec4 selfIllumination;" << std::endl; + + if (desc.Fog || desc.Lighting) + ss << "uniform mat4 modelView;" << std::endl; + if (desc.Lighting) + ss << "uniform mat4 viewMatrix;" << std::endl; + if (desc.Fog || desc.Lighting) + ss << "vec4 ecPos4;" << std::endl; + if (desc.Fog) + ss << "smooth out vec4 ecPos;" << std::endl; + ss << std::endl; + + if (desc.Lighting) + { + ss << "uniform mat3 normalMatrix;" << std::endl; + for (int i = 0; i < NL_OPENGL3_MAX_LIGHT; ++i) + vpLightUniforms(ss, desc, i); + ss << "smooth out vec4 lightColor;" << std::endl; + ss << std::endl; + + for (int i = 0; i < NL_OPENGL3_MAX_LIGHT; ++i) + vpLightFunctions(ss, desc, i); + ss << std::endl; + } - if (desc.Fog || desc.Lighting) - ss << "ecPos4 = modelView * v" << g_AttribNames[0] << ";" << std::endl; - if (desc.Fog) - ss << "ecPos = ecPos4;" << std::endl; + ss << "void main(void)" << std::endl; + ss << "{" << std::endl; + ss << "gl_Position = modelViewProjection * " << "v" << g_AttribNames[0] << ";" << std::endl; - if (desc.Lighting) - { - ss << "lightColor = vec4(0.0, 0.0, 0.0, 1.0);" << std::endl; - for (int i = 0; i < NL_OPENGL3_MAX_LIGHT; i++) - if (desc.LightMode[i] == CLight::DirectionalLight || desc.LightMode[i] == CLight::PointLight) - ss << "lightColor = lightColor + getLight" << i << "Color();" << std::endl; - ss << "lightColor = lightColor + selfIllumination;" << std::endl; - //ss << "lightColor = selfIllumination;" << std::endl; // DEBUG - ss << "lightColor.a = 1.0;" << std::endl; // ... - } + if (desc.Fog || desc.Lighting) + ss << "ecPos4 = modelView * v" << g_AttribNames[0] << ";" << std::endl; + if (desc.Fog) + ss << "ecPos = ecPos4;" << std::endl; - for (int i = Weight; i < NumOffsets; i++) - { - if (hasFlag(desc.VertexFormat, g_VertexFlags[i])) - { - ss << g_AttribNames[i] << " = " << "v" << g_AttribNames[i] << ";" << std::endl; - } - } + if (desc.Lighting) + { + ss << "lightColor = vec4(0.0, 0.0, 0.0, 1.0);" << std::endl; + for (int i = 0; i < NL_OPENGL3_MAX_LIGHT; i++) + if (desc.LightMode[i] == CLight::DirectionalLight || desc.LightMode[i] == CLight::PointLight) + ss << "lightColor = lightColor + getLight" << i << "Color();" << std::endl; + ss << "lightColor = lightColor + selfIllumination;" << std::endl; + //ss << "lightColor = selfIllumination;" << std::endl; // DEBUG + ss << "lightColor.a = 1.0;" << std::endl; // ... + } - for (int i = 0; i < IDRV_MAT_MAXTEXTURES; ++i) + for (int i = Weight; i < NumOffsets; i++) + { + if (hasFlag(desc.VertexFormat, g_VertexFlags[i])) { - if (desc.TexGenMode[i] >= 0) - ss << "texCoord" << i << " = vec4(0.0, 0.0, 0.0, 0.0);" << std::endl; - - // FIXME GL3 SPECULAR: TEXGEN REFLECTION CUBE - // TODO: Texgen calculation + ss << g_AttribNames[i] << " = " << "v" << g_AttribNames[i] << ";" << std::endl; } + } - ss << "}" << std::endl; - result = ss.str(); + for (int i = 0; i < IDRV_MAT_MAXTEXTURES; ++i) + { + if (desc.TexGenMode[i] >= 0) + ss << "texCoord" << i << " = vec4(0.0, 0.0, 0.0, 0.0);" << std::endl; + + // FIXME GL3 SPECULAR: TEXGEN REFLECTION CUBE + // TODO: Texgen calculation } + + ss << "}" << std::endl; + result = ss.str(); } +} /* anonymous namespace */ + void CDriverGL3::generateBuiltinVertexProgram() { std::set::iterator it = m_VPBuiltinCache.find(m_VPBuiltinCurrent);