diff --git a/code/nel/src/3d/driver/opengl3/driver_opengl.h b/code/nel/src/3d/driver/opengl3/driver_opengl.h index b77de1792..b9b176ed9 100644 --- a/code/nel/src/3d/driver/opengl3/driver_opengl.h +++ b/code/nel/src/3d/driver/opengl3/driver_opengl.h @@ -276,6 +276,20 @@ public: void setupIndexBuffer(CIndexBuffer &vb); }; +/// Builtin vertex program description +struct CVPBuiltin +{ + uint16 VertexFormat; + bool Lighting; + sint LightMode[NL_OPENGL3_MAX_LIGHT]; // -1 when disabled + bool Fog; + bool VertexColorLighted; + + CVertexProgram *VertexProgram; +}; + +bool operator<(const CVPBuiltin &left, const CVPBuiltin &right); + class CGLSLShaderGenerator; class CUsrShaderManager; @@ -377,11 +391,15 @@ public: virtual bool setupMaterial(CMaterial& mat); void generateShaderDesc(CShaderDesc &desc, CMaterial &mat); - bool setupProgram(CMaterial& mat); + bool setupBuiltinPrograms(CMaterial& mat); + bool setupBuiltinVertexProgram(); + bool setupBuiltinPixelProgram(CMaterial& mat); bool setupDynMatProgram(CMaterial& mat, uint pass); - void setupUniforms(); + bool setupUniforms(); void setupUniforms(TProgram program); + CVertexProgram *generateBuiltinVertexProgram(); + virtual void startSpecularBatch(); virtual void endSpecularBatch(); @@ -1337,6 +1355,8 @@ private: CGeometryProgram *m_DriverGeometryProgram; CPixelProgram *m_DriverPixelProgram; + std::set m_VPBuiltinCache; + // init EMBM settings (set each stage to modify the next) void initEMBM(); 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 4db864c68..83ad2387d 100644 --- a/code/nel/src/3d/driver/opengl3/driver_opengl_material.cpp +++ b/code/nel/src/3d/driver/opengl3/driver_opengl_material.cpp @@ -437,7 +437,7 @@ bool CDriverGL3::setupMaterial(CMaterial& mat) // Light Part. - // _DriverGLStates.enableLighting(mat.getFlags()&IDRV_MAT_LIGHTING); // FIXME GL3 VERTEX PROGRAM + _DriverGLStates.enableLighting(mat.getFlags() & IDRV_MAT_LIGHTING); if ((mat.getFlags() & IDRV_MAT_LIGHTING) == 0) disableAllLights(); @@ -490,8 +490,7 @@ bool CDriverGL3::setupMaterial(CMaterial& mat) // 5. Set up the program // ===================== - bool programOK = setupProgram(mat); - return programOK; + return setupBuiltinPrograms(mat); } // *************************************************************************** @@ -782,7 +781,7 @@ sint CDriverGL3::beginLightMapMultiPass () computeLightMapInfos (mat); // always enable lighting for lightmap (because of dynamic light) - // _DriverGLStates.enableLighting(true); // FIXME GL3 VERTEX PROGRAM + _DriverGLStates.enableLighting(true); // if the dynamic lightmap light has changed since the last render (should not happen), resetup // normal way is that setupLightMapDynamicLighting() is called in setupMaterial() if shader different from prec diff --git a/code/nel/src/3d/driver/opengl3/driver_opengl_program.cpp b/code/nel/src/3d/driver/opengl3/driver_opengl_program.cpp index 7583282bf..6ee0ff24e 100644 --- a/code/nel/src/3d/driver/opengl3/driver_opengl_program.cpp +++ b/code/nel/src/3d/driver/opengl3/driver_opengl_program.cpp @@ -590,16 +590,39 @@ namespace NL3D desc.setLighting(enableLights); } + bool CDriverGL3::setupBuiltinPrograms(CMaterial &mat) + { + return setupBuiltinVertexProgram() + && setupBuiltinPixelProgram(mat) + && setupUniforms(); + } + + bool CDriverGL3::setupBuiltinVertexProgram() + { + if (m_UserVertexProgram) return true; + + CVertexProgram *vertexProgram = generateBuiltinVertexProgram(); + nlassert(vertexProgram); + + if (!activeVertexProgram(vertexProgram, true)) + return false; + + // GL3 TODO: Here we set the uniforms of the vertex program! + + return true; + } - bool CDriverGL3::setupProgram(CMaterial &mat) + bool CDriverGL3::setupBuiltinPixelProgram(CMaterial &mat) { + if (m_UserPixelProgram) return true; + // nlassert(!m_UserVertexProgram); // TEMP // nlassert(!m_UserPixelProgram); // TEMP if (mat.getDynMat() != NULL) return true; - CVertexProgram *vp = NULL; + // CVertexProgram *vp = NULL; // REMOVED CPixelProgram *pp = NULL; SShaderPair sp; @@ -613,11 +636,11 @@ namespace NL3D // Yes we have! if (!sp.empty()) { - if (m_UserVertexProgram == NULL) + /*if (m_UserVertexProgram == NULL) { if (!activeVertexProgram(sp.vp, true)) return false; - } + }*/ if (m_UserPixelProgram == NULL) { @@ -628,7 +651,7 @@ namespace NL3D // No we need to generate it now else { - std::string vs; + // std::string vs; std::string ps; bool cacheShaders = true; @@ -638,7 +661,7 @@ namespace NL3D shaderGenerator->setShaderDesc(&desc); // If we don't already have a vertex program attached, we'll generate it now - if (m_UserVertexProgram == NULL) + /* if (m_UserVertexProgram == NULL) { shaderGenerator->generateVS(vs); vp = new CVertexProgram(); @@ -666,6 +689,7 @@ namespace NL3D } else cacheShaders = false; + */ // If we don't already have a pixel program attached, we'll generate it now if (m_UserPixelProgram == NULL) @@ -682,8 +706,8 @@ namespace NL3D if (!compilePixelProgram(pp)) { - delete vp; - vp = NULL; + // delete vp; + // vp = NULL; delete pp; pp = NULL; return false; @@ -691,8 +715,8 @@ namespace NL3D if (!activePixelProgram(pp, true)) { - delete vp; - vp = NULL; + // delete vp; + // vp = NULL; delete pp; pp = NULL; return false; @@ -705,15 +729,13 @@ namespace NL3D // If we already have a shader attached we won't cache this shaderpair, since we didn't generate it if (cacheShaders) { - sp.vp = vp; + sp.vp = NULL; sp.pp = pp; desc.setShaders(sp); shaderCache.cacheShader(desc); } } - setupUniforms(); - return true; } @@ -806,11 +828,11 @@ namespace NL3D return false; } - - void CDriverGL3::setupUniforms() + bool CDriverGL3::setupUniforms() { setupUniforms(IDriver::VertexProgram); setupUniforms(IDriver::PixelProgram); + return true; } void CDriverGL3::setupUniforms(TProgram program) diff --git a/code/nel/src/3d/driver/opengl3/driver_opengl_states.cpp b/code/nel/src/3d/driver/opengl3/driver_opengl_states.cpp index 9af9d0881..5ac3caa80 100644 --- a/code/nel/src/3d/driver/opengl3/driver_opengl_states.cpp +++ b/code/nel/src/3d/driver/opengl3/driver_opengl_states.cpp @@ -76,6 +76,7 @@ void CDriverGLStates3::forceDefaults(uint nbStages) _CurBlend = false; _CurCullFace = true; _CurAlphaTest = false; + _CurLighting = false; _CurZWrite = true; _CurStencilTest =false; @@ -228,6 +229,14 @@ void CDriverGLStates3::enableAlphaTest(uint enable) } } +// *************************************************************************** +void CDriverGLStates3::enableLighting(uint enable) +{ + H_AUTO_OGL(CDriverGLStates3_enableLighting) + + _CurLighting = (enable != 0); +} + // *************************************************************************** void CDriverGLStates3::enableZWrite(uint enable) { diff --git a/code/nel/src/3d/driver/opengl3/driver_opengl_states.h b/code/nel/src/3d/driver/opengl3/driver_opengl_states.h index df39a3625..b608ece31 100644 --- a/code/nel/src/3d/driver/opengl3/driver_opengl_states.h +++ b/code/nel/src/3d/driver/opengl3/driver_opengl_states.h @@ -85,10 +85,14 @@ public: // @{ void enableBlend(uint enable); void enableFog(uint enable); + bool isFogEnabled() const { return _CurFog; } void enableCullFace(uint enable); /// enable and set good AlphaFunc. void enableAlphaTest(uint enable); void enableZWrite(uint enable); + // overall lighting enabled + void enableLighting(uint enable); + bool isLightingEnabled() const { return _CurLighting; } /// enable/disable stencil test void enableStencilTest(bool enable); bool isStencilTestEnabled() const { return _CurStencilTest; } @@ -164,6 +168,7 @@ private: bool _CurFog; bool _CurCullFace; bool _CurAlphaTest; + bool _CurLighting; bool _CurZWrite; bool _CurStencilTest; 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 new file mode 100644 index 000000000..b5bd738d6 --- /dev/null +++ b/code/nel/src/3d/driver/opengl3/driver_opengl_vertex_program.cpp @@ -0,0 +1,401 @@ +// 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 "driver_opengl_vertex_program.h" + +#include + +#include "nel/3d/vertex_program.h" +#include "nel/3d/light.h" + +#include "driver_opengl.h" +#include "driver_opengl_vertex_buffer_hard.h" + +namespace NL3D { + +#ifdef NL_STATIC +namespace NLDRIVERGL3 { +#endif + +bool operator<(const CVPBuiltin &left, const CVPBuiltin &right) +{ + if (left.VertexFormat != right.VertexFormat) + return left.VertexFormat < right.VertexFormat; + if (left.Lighting != right.Lighting) + return right.Lighting; + if (left.Lighting) + for (sint i = 0; i < NL_OPENGL3_MAX_LIGHT; ++i) + if (left.LightMode[i] != right.LightMode[i]) + return left.LightMode[i] < right.LightMode[i]; + if (left.Fog != right.Fog) + return right.Fog; + if (left.VertexColorLighted != right.VertexColorLighted) + return right.VertexColorLighted; + + return false; +} + +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) + { + 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; + } + } + + void vpLightFunctions(std::stringstream &ss, const CVPBuiltin &desc, int 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; + + //if (desc->useTextures() || (material->getShader() == CMaterial::LightMap)) + //{ + ss << "vec4 lc = getIntensity" << i << "(normal3, lightDir) * light" << i << "ColDiff + "; + ss << "getSpecIntensity" << i << "(normal3, lightDir) * light" << i << "ColSpec + "; + ss << "light" << i << "ColAmb;" << std::endl; + //} // FIXME: Ambient color is not correctly implemented + /*else + { + ss << "vec4 lc = getIntensity" << num << "(normal3, lightDir) * light" << num << "ColDiff * diffuseColor + "; + ss << "getSpecIntensity" << num << "(normal3, lightDir) * light" << num << "ColSpec * specularColor + "; + ss << "light" << num << "ColAmb * ambientColor;" << std::endl; + }*/ + + 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 << "vec3 normal3 = vnormal.xyz / vnormal.w;" << std::endl; + ss << "normal3 = normalMatrix * normal3;" << std::endl; + ss << "normal3 = normalize(normal3);" << std::endl; + + /*if (desc->useTextures() || (material->getShader() == CMaterial::LightMap)) + {*/ + ss << "vec4 lc = getIntensity" << i << "(normal3, lightDirection) * light" << i << "ColDiff + "; + ss << "getSpecIntensity" << i << "(normal3, lightDirection) * light" << i << "ColSpec + "; + ss << "light" << i << "ColAmb;" << std::endl; + // FIXME: Ambient stuff + /*} + else + { + ss << "vec4 lc = getIntensity" << num << "(normal3, lightDirection) * light" << num << "ColDiff * diffuseColor+ "; + ss << "getSpecIntensity" << num << "(normal3, lightDirection) * light" << num << "ColSpec * specularColor + "; + ss << "light" << num << "ColAmb * ambientColor;" << std::endl; + }*/ + + ss << "lc = lc / attenuation;" << std::endl; + ss << "return lc;" << std::endl; + ss << "}" << std::endl; + ss << std::endl; + break; + } + } + + void vsLighting(std::stringstream &ss, const CVPBuiltin &desc, int i) + { + + } + + 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, s_VertexFlags[i])) + ss << "layout (location = " << i << ") " << "in vec4 " << "v" << s_AttribNames[i] << ";" << std::endl; + ss << std::endl; + + for (int i = Weight; i < NumOffsets; ++i) + if (hasFlag(desc.VertexFormat, s_VertexFlags[i])) + ss << "smooth out vec4 " << s_AttribNames[i] << ";" << std::endl; + ss << std::endl; + + // if (!useTextures) { + ss << "uniform vec4 ambientColor;" << std::endl; + ss << "uniform vec4 diffuseColor;" << std::endl; + ss << "uniform vec4 specularColor;" << 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; + } + + ss << "void main(void)" << std::endl; + ss << "{" << std::endl; + ss << "gl_Position = modelViewProjection * " << "v" << s_AttribNames[0] << ";" << std::endl; + + if (desc.Fog || desc.Lighting) + ss << "ecPos4 = modelView * v" << s_AttribNames[0] << ";" << std::endl; + if (desc.Fog) + ss << "ecPos = ecPos4;" << 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; + } + + for (int i = Weight; i < NumOffsets; i++) + { + if (hasFlag(desc.VertexFormat, s_VertexFlags[i])) + { + ss << s_AttribNames[i] << " = " << "v" << s_AttribNames[i] << ";" << std::endl; + } + } + + ss << "}" << std::endl; + result = ss.str(); + } +} + +CVertexProgram *CDriverGL3::generateBuiltinVertexProgram() +{ + CVPBuiltin desc; + desc.VertexFormat = _CurrentVertexBufferHard->VB->getVertexFormat(); + desc.Fog = _DriverGLStates.isFogEnabled(); + desc.Lighting = _DriverGLStates.isLightingEnabled(); + if (desc.Lighting) + for (sint i = 0; i < MaxLight; ++i) + desc.LightMode[i] = _UserLightEnable[i] ? _LightMode[i] : -1; + desc.VertexColorLighted = false; // _DriverGLStates._VertexColorLighted; + + std::set::iterator it = m_VPBuiltinCache.find(desc); + if (it != m_VPBuiltinCache.end()) + return it->VertexProgram; + + std::string result; + vpGenerate(result, desc); + + CVertexProgram *vertexProgram = new CVertexProgram(); + IProgram::CSource *src = new IProgram::CSource(); + src->Profile = IProgram::glsl330v; + src->DisplayName = "Builtin Vertex Program (" + NLMISC::toString(m_VPBuiltinCache.size()) + ")"; + src->setSource(result); + vertexProgram->addSource(src); + + nldebug("GL3: Generate '%s'", src->DisplayName.c_str()); + + if (!compileVertexProgram(vertexProgram)) + { + delete vertexProgram; vertexProgram = NULL; + } + + desc.VertexProgram = vertexProgram; + m_VPBuiltinCache.insert(desc); + + return desc.VertexProgram; +} + +#ifdef NL_STATIC +} // NLDRIVERGL3 +#endif + +} // NL3D + diff --git a/code/nel/src/3d/driver/opengl3/driver_opengl_vertex_program.h b/code/nel/src/3d/driver/opengl3/driver_opengl_vertex_program.h new file mode 100644 index 000000000..070c25e5c --- /dev/null +++ b/code/nel/src/3d/driver/opengl3/driver_opengl_vertex_program.h @@ -0,0 +1,61 @@ +// 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 . + +#ifndef NL_DRIVER_OPENGL_VERTEX_PROGRAM_H +#define NL_DRIVER_OPENGL_VERTEX_PROGRAM_H + +#include "nel/misc/types_nl.h" + +namespace NL3D { + +class CVertexProgram; + +#ifdef NL_STATIC +namespace NLDRIVERGL3 { +#endif + +class CDriverGL3; + +// The default vertex program +class CDriverGL3VertexProgramDefault +{ + struct CDesc + { + + }; + +public: + CDriverGL3VertexProgramDefault(); + ~CDriverGL3VertexProgramDefault(); + + void setDriver(CDriverGL3 *driver); + + CVertexProgram *generate(); + +private: + CDriverGL3 *m_Driver; + +}; + +#ifdef NL_STATIC +} // NLDRIVERGL3 +#endif + +} // NL3D + +#endif // NL_DRIVER_OPENGL_VERTEX_PROGRAM_H + +/* end of file */