Use separate shaders in the OpenGL3 driver.

--HG--
branch : gsoc2013-dfighter
hg/feature/gsoc2013-dfighter
dfighter1985 11 years ago
parent ace1b5386b
commit 32e814ecb6

@ -1036,35 +1036,35 @@ public:
/// Creates a new Pixel program /// Creates a new Pixel program
virtual IProgram* createPixelProgram() const { return NULL; } virtual IProgram* createPixelProgram() const { return NULL; }
/// Returns the location of the specified uniform, or -1 if it's not found /// Returns the location of the specified uniform in the specified program type ( vertex, pixel, etc ), or -1 if it's not found
virtual int getUniformLocation( const char *name ){ return -1; } virtual int getUniformLocation( uint32 programType, const char *name ){ return -1; }
/// Sets a single float uniform /// Sets a single float uniform
virtual void setUniform1f( uint index, float f ){} virtual void setUniform1f( uint32 programType, uint index, float f ){}
/// Sets 4 floats uniform value ( vector ) /// Sets 4 floats uniform value ( vector )
virtual void setUniform4f( uint index, float f1, float f2, float f3, float f4 ){} virtual void setUniform4f( uint32 programType, uint index, float f1, float f2, float f3, float f4 ){}
/// Sets a single integer uniform value /// Sets a single integer uniform value
virtual void setUniform1i( uint index, int i ){} virtual void setUniform1i( uint32 programType, uint index, int i ){}
/// Sets a 4 integer uniform value ( vector ) /// Sets a 4 integer uniform value ( vector )
virtual void setUniform4i( uint index, int i1, int i2, int i3, int i4 ){} virtual void setUniform4i( uint32 programType, uint index, int i1, int i2, int i3, int i4 ){}
/// Sets a single unsigned integer uniform value /// Sets a single unsigned integer uniform value
virtual void setUniform1u( uint index, uint u ){} virtual void setUniform1u( uint32 programType, uint index, uint u ){}
/// Sets a 4 unsigned integer uniform value /// Sets a 4 unsigned integer uniform value
virtual void setUniform4u( uint index, uint u1, uint u2, uint u3, uint u4 ){} virtual void setUniform4u( uint32 programType, uint index, uint u1, uint u2, uint u3, uint u4 ){}
/// Sets a 2x2 float matrix uniform value ( column major order ) /// Sets a 2x2 float matrix uniform value ( column major order )
virtual void setUniformMatrix2fv( uint index, uint count, bool transpose, const float *values ){} virtual void setUniformMatrix2fv( uint32 programType, uint index, uint count, bool transpose, const float *values ){}
/// Sets a 3x3 float matrix uniform value ( column major order ) /// Sets a 3x3 float matrix uniform value ( column major order )
virtual void setUniformMatrix3fv( uint index, uint count, bool transpose, const float *values ){} virtual void setUniformMatrix3fv( uint32 programType, uint index, uint count, bool transpose, const float *values ){}
/// Sets a 4x4 float matrix uniform value ( column major order ) /// Sets a 4x4 float matrix uniform value ( column major order )
virtual void setUniformMatrix4fv( uint index, uint count, bool transpose, const float *values ){} virtual void setUniformMatrix4fv( uint32 programType, uint index, uint count, bool transpose, const float *values ){}
/** /**
* Setup constant values. * Setup constant values.

@ -26,55 +26,131 @@ namespace NL3D
class IProgram class IProgram
{ {
public: public:
enum EProgramType enum TProgramType
{ {
INVALID_PROGRAM,
VERTEX_PROGRAM, VERTEX_PROGRAM,
PIXEL_PROGRAM, PIXEL_PROGRAM,
GEOMETRY_PROGRAM, GEOMETRY_PROGRAM
UNKNOWN_PROGRAM };
enum EUniform
{
MVPMatrix,
MVMatrix,
NormalMatrix,
TexMatrix0,
TexMatrix1,
TexMatrix2,
TexMatrix3,
Constant0,
Constant1,
Constant2,
Constant3,
Diffuse,
Color,
Sampler0,
Sampler1,
Sampler2,
Sampler3,
AlphaTreshold,
FogStart,
FogEnd,
FogColor,
FogDensity,
Light0Dir,
Light1Dir,
Light2Dir,
Light3Dir,
Light4Dir,
Light5Dir,
Light6Dir,
Light7Dir,
Light0ColDiff,
Light1ColDiff,
Light2ColDiff,
Light3ColDiff,
Light4ColDiff,
Light5ColDiff,
Light6ColDiff,
Light7ColDiff,
Light0ColAmb,
Light1ColAmb,
Light2ColAmb,
Light3ColAmb,
Light4ColAmb,
Light5ColAmb,
Light6ColAmb,
Light7ColAmb,
Light0ColSpec,
Light1ColSpec,
Light2ColSpec,
Light3ColSpec,
Light4ColSpec,
Light5ColSpec,
Light6ColSpec,
Light7ColSpec,
Light0Shininess,
Light1Shininess,
Light2Shininess,
Light3Shininess,
Light4Shininess,
Light5Shininess,
Light6Shininess,
Light7Shininess,
Light0Pos,
Light1Pos,
Light2Pos,
Light3Pos,
Light4Pos,
Light5Pos,
Light6Pos,
Light7Pos,
Light0ConstAttn,
Light1ConstAttn,
Light2ConstAttn,
Light3ConstAttn,
Light4ConstAttn,
Light5ConstAttn,
Light6ConstAttn,
Light7ConstAttn,
Light0LinAttn,
Light1LinAttn,
Light2LinAttn,
Light3LinAttn,
Light4LinAttn,
Light5LinAttn,
Light6LinAttn,
Light7LinAttn,
Light0QuadAttn,
Light1QuadAttn,
Light2QuadAttn,
Light3QuadAttn,
Light4QuadAttn,
Light5QuadAttn,
Light6QuadAttn,
Light7QuadAttn,
NUM_UNIFORMS
}; };
IProgram(){ IProgram(){
shaderId = 0; type = INVALID_PROGRAM;
compiled = false;
type = UNKNOWN_PROGRAM;
} }
virtual ~IProgram(){} virtual ~IProgram(){}
virtual void shaderSource( const char *source ) = 0; void setSource( const char *source ){ src.assign( source ); }
const std::string& getSource() const{ return src; }
virtual bool compile( std::string &log ) = 0;
unsigned int getShaderId() const{ return shaderId; }
bool isCompiled() const{ return compiled; } virtual void cacheUniforms() = 0;
virtual int getUniformIndex( uint32 id ) const = 0;
bool isVertexProgram() const{ TProgramType getType() const{ return type; }
if( type == VERTEX_PROGRAM )
return true;
else
return false;
}
bool isPixelProgram() const{
if( type == PIXEL_PROGRAM )
return true;
else
return false;
}
bool isGeometryProgram() const{
if( type == GEOMETRY_PROGRAM )
return true;
else
return false;
}
protected: protected:
unsigned int shaderId; std::string src;
bool compiled; static const char *uniformNames[ NUM_UNIFORMS ];
EProgramType type; TProgramType type;
}; };
} }

@ -1,161 +0,0 @@
// NeL - MMORPG Framework <http://dev.ryzom.com/projects/nel/>
// Copyright (C) 2010 Winch Gate Property Limited
//
// 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 I_PROGRAM_OBJECT_H
#define I_PROGRAM_OBJECT_H
namespace NL3D
{
class IProgram;
class IProgramObject
{
public:
enum EUniform
{
MVPMatrix,
MVMatrix,
NormalMatrix,
TexMatrix0,
TexMatrix1,
TexMatrix2,
TexMatrix3,
Constant0,
Constant1,
Constant2,
Constant3,
Diffuse,
Color,
Sampler0,
Sampler1,
Sampler2,
Sampler3,
AlphaTreshold,
FogStart,
FogEnd,
FogColor,
FogDensity,
Light0Dir,
Light1Dir,
Light2Dir,
Light3Dir,
Light4Dir,
Light5Dir,
Light6Dir,
Light7Dir,
Light0ColDiff,
Light1ColDiff,
Light2ColDiff,
Light3ColDiff,
Light4ColDiff,
Light5ColDiff,
Light6ColDiff,
Light7ColDiff,
Light0ColAmb,
Light1ColAmb,
Light2ColAmb,
Light3ColAmb,
Light4ColAmb,
Light5ColAmb,
Light6ColAmb,
Light7ColAmb,
Light0ColSpec,
Light1ColSpec,
Light2ColSpec,
Light3ColSpec,
Light4ColSpec,
Light5ColSpec,
Light6ColSpec,
Light7ColSpec,
Light0Shininess,
Light1Shininess,
Light2Shininess,
Light3Shininess,
Light4Shininess,
Light5Shininess,
Light6Shininess,
Light7Shininess,
Light0Pos,
Light1Pos,
Light2Pos,
Light3Pos,
Light4Pos,
Light5Pos,
Light6Pos,
Light7Pos,
Light0ConstAttn,
Light1ConstAttn,
Light2ConstAttn,
Light3ConstAttn,
Light4ConstAttn,
Light5ConstAttn,
Light6ConstAttn,
Light7ConstAttn,
Light0LinAttn,
Light1LinAttn,
Light2LinAttn,
Light3LinAttn,
Light4LinAttn,
Light5LinAttn,
Light6LinAttn,
Light7LinAttn,
Light0QuadAttn,
Light1QuadAttn,
Light2QuadAttn,
Light3QuadAttn,
Light4QuadAttn,
Light5QuadAttn,
Light6QuadAttn,
Light7QuadAttn,
NUM_UNIFORMS
};
IProgramObject(){}
virtual ~IProgramObject(){}
virtual bool attachVertexProgram( IProgram *shader ) = 0;
virtual bool attachPixelProgram( IProgram *shader ) = 0;
virtual bool detachVertexProgram( IProgram *shader ) = 0;
virtual bool detachPixelProgram( IProgram *shader ) = 0;
unsigned int getProgramId() const{ return programId; }
virtual bool link( std::string &log ) = 0;
virtual bool validate( std::string &log ) = 0;
virtual void cacheUniformIndices() = 0;
virtual int getUniformIndex( EUniform uniform ) = 0;
bool isLinked() const{ return linked; }
protected:
unsigned int programId;
bool linked;
};
}
#endif

@ -21,16 +21,16 @@
namespace NL3D namespace NL3D
{ {
CGLSLPixelProgram::CGLSLPixelProgram() CGLSLPixelProgram::CGLSLPixelProgram() :
CGLSLProgram()
{ {
type = PIXEL_PROGRAM; type = PIXEL_PROGRAM;
shaderId = nglCreateShader( GL_FRAGMENT_SHADER );
nlassert( shaderId != 0 );
} }
CGLSLPixelProgram::~CGLSLPixelProgram() CGLSLPixelProgram::~CGLSLPixelProgram()
{ {
nglDeleteShader( shaderId ); if( programId != 0 )
nglDeleteProgram( programId );
} }
} }

@ -18,11 +18,11 @@
#ifndef GLSL_PIXEL_PROGRAM_H #ifndef GLSL_PIXEL_PROGRAM_H
#define GLSL_PIXEL_PROGRAM_H #define GLSL_PIXEL_PROGRAM_H
#include "driver_glsl_shader_base.h" #include "driver_glsl_program.h"
namespace NL3D namespace NL3D
{ {
class CGLSLPixelProgram : public CGLSLShaderBase class CGLSLPixelProgram : public CGLSLProgram
{ {
public: public:
CGLSLPixelProgram(); CGLSLPixelProgram();

@ -16,296 +16,32 @@
#include "driver_glsl_program.h" #include "driver_glsl_program.h"
#include "nel/3d/i_program_object.h" #include <algorithm>
#include "driver_glsl_shader_base.h"
#include "stdopengl.h"
#include "driver_opengl_extension.h" #include "driver_opengl_extension.h"
#define MAX_PROGRAM_LOG 1024
namespace NL3D namespace NL3D
{ {
CGLSLProgram::CGLSLProgram() : CGLSLProgram::CGLSLProgram() :
IProgramObject() IProgram()
{ {
programId = nglCreateProgram();
nlassert( programId != 0 );
linked = false;
std::fill( uniformIndices, uniformIndices + NUM_UNIFORMS, -1 ); std::fill( uniformIndices, uniformIndices + NUM_UNIFORMS, -1 );
}
CGLSLProgram::~CGLSLProgram()
{
nglDeleteProgram( programId );
deleteShaders();
programId = 0; programId = 0;
} }
bool CGLSLProgram::attachVertexProgram( IProgram *shader ) CGLSLProgram::~CGLSLProgram()
{
if( !shader->isVertexProgram() )
return false;
if( !shader->isCompiled() )
return false;
std::vector< IProgram* >::const_iterator itr =
std::find( vertexPrograms.begin(), vertexPrograms.end(), shader );
if( itr != vertexPrograms.end() )
return false;
glGetError();
nglAttachShader( programId, shader->getShaderId() );
GLenum error = glGetError();
if( error != 0 )
return false;
vertexPrograms.push_back( shader );
return true;
}
bool CGLSLProgram::attachPixelProgram( IProgram *shader )
{
if( !shader->isPixelProgram() )
return false;
if( !shader->isCompiled() )
return false;
std::vector< IProgram* >::const_iterator itr =
std::find( pixelPrograms.begin(), pixelPrograms.end(), shader );
if( itr != pixelPrograms.end() )
return false;
glGetError();
nglAttachShader( programId, shader->getShaderId() );
GLenum error = glGetError();
if( error != GL_NO_ERROR )
return false;
pixelPrograms.push_back( shader );
return true;
}
bool CGLSLProgram::detachVertexProgram( IProgram *shader )
{
if( !shader->isVertexProgram() )
return false;
std::vector< IProgram* >::iterator itr =
std::find( vertexPrograms.begin(), vertexPrograms.end(), shader );
if( itr == vertexPrograms.end() )
return false;
nglDetachShader( programId, shader->getShaderId() );
GLenum error = glGetError();
if( error != GL_NO_ERROR )
return false;
vertexPrograms.erase( itr );
return true;
}
bool CGLSLProgram::detachPixelProgram( IProgram *shader )
{
if( !shader->isPixelProgram() )
return false;
std::vector< IProgram* >::iterator itr =
std::find( pixelPrograms.begin(), pixelPrograms.end(), shader );
if( itr == pixelPrograms.end() )
return false;
nglDetachShader( programId, shader->getShaderId() );
GLenum error = glGetError();
if( error != GL_NO_ERROR )
return false;
pixelPrograms.erase( itr );
return true;
}
bool CGLSLProgram::link( std::string &log )
{
if( vertexPrograms.empty() || pixelPrograms.empty() )
return false;
nglLinkProgram( programId );
GLint ok;
nglGetProgramiv( programId, GL_LINK_STATUS, &ok );
if( ok == 0 )
{
char errorLog[ MAX_PROGRAM_LOG ];
nglGetProgramInfoLog( programId, MAX_PROGRAM_LOG, NULL, errorLog );
log.assign( errorLog );
return false;
}
linked = true;
return true;
}
bool CGLSLProgram::validate( std::string &log )
{ {
nglValidateProgram( programId );
GLint ok;
nglGetProgramiv( programId, GL_VALIDATE_STATUS, &ok );
if( ok != GL_TRUE )
{
char errorLog[ MAX_PROGRAM_LOG ];
nglGetProgramInfoLog( programId, MAX_PROGRAM_LOG, NULL, errorLog );
log.assign( errorLog );
return false;
}
return true;
} }
const char *uniformNames[ CGLSLProgram::NUM_UNIFORMS ] = void CGLSLProgram::cacheUniforms()
{
"mvpMatrix",
"mvMatrix",
"normalMatrix",
"texMatrix0",
"texMatrix1",
"texMatrix2",
"texMatrix3",
"constant0",
"constant1",
"constant2",
"constant3",
"diffuse",
"mcolor",
"sampler0",
"sampler1",
"sampler2",
"sampler3",
"alphaTreshold",
"fogStart",
"fogEnd",
"fogColor",
"fogDensity",
"light0Dir",
"light1Dir",
"light2Dir",
"light3Dir",
"light4Dir",
"light5Dir",
"light6Dir",
"light7Dir",
"light0ColDiff",
"light1ColDiff",
"light2ColDiff",
"light3ColDiff",
"light4ColDiff",
"light5ColDiff",
"light6ColDiff",
"light7ColDiff",
"light0ColAmb",
"light1ColAmb",
"light2ColAmb",
"light3ColAmb",
"light4ColAmb",
"light5ColAmb",
"light6ColAmb",
"light7ColAmb",
"light0ColSpec",
"light1ColSpec",
"light2ColSpec",
"light3ColSpec",
"light4ColSpec",
"light5ColSpec",
"light6ColSpec",
"light7ColSpec",
"light0Shininess",
"light1Shininess",
"light2Shininess",
"light3Shininess",
"light4Shininess",
"light5Shininess",
"light6Shininess",
"light7Shininess",
"light0Pos",
"light1Pos",
"light2Pos",
"light3Pos",
"light4Pos",
"light5Pos",
"light6Pos",
"light7Pos",
"light0ConstAttn",
"light1ConstAttn",
"light2ConstAttn",
"light3ConstAttn",
"light4ConstAttn",
"light5ConstAttn",
"light6ConstAttn",
"light7ConstAttn",
"light0LinAttn",
"light1LinAttn",
"light2LinAttn",
"light3LinAttn",
"light4LinAttn",
"light5LinAttn",
"light6LinAttn",
"light7LinAttn",
"light0QuadAttn",
"light1QuadAttn",
"light2QuadAttn",
"light3QuadAttn",
"light4QuadAttn",
"light5QuadAttn",
"light6QuadAttn",
"light7QuadAttn"
};
void CGLSLProgram::cacheUniformIndices()
{ {
nlassert( programId != 0 ); nlassert( programId != 0 );
for( int i = MVPMatrix; i < NUM_UNIFORMS; i++ ) for( int i = 0; i < NUM_UNIFORMS; i++ )
{ {
uniformIndices[ i ] = nglGetUniformLocation( programId, uniformNames[ i ] ); uniformIndices[ i ] = nglGetUniformLocation( programId, uniformNames[ i ] );
} }
} }
int CGLSLProgram::getUniformIndex( EUniform uniform )
{
nlassert( uniform < NUM_UNIFORMS );
return uniformIndices[ uniform ];
}
void CGLSLProgram::deleteShaders()
{
std::vector< IProgram* >::iterator itr;
itr = vertexPrograms.begin();
while( itr != vertexPrograms.end() )
{
delete *itr;
++itr;
}
itr = pixelPrograms.begin();
while( itr != pixelPrograms.end() )
{
delete *itr;
++itr;
}
}
} }

@ -18,41 +18,28 @@
#ifndef GLSL_PROGRAM_H #ifndef GLSL_PROGRAM_H
#define GLSL_PROGRAM_H #define GLSL_PROGRAM_H
#include <vector> #include "nel/3d/i_program.h"
#include <string>
#include "nel/3d/i_program_object.h"
namespace NL3D namespace NL3D
{ {
/// Wrapper class for OpenGL shader program object /// Wrapper class for OpenGL shader program object
class CGLSLProgram : public IProgramObject class CGLSLProgram : public IProgram
{ {
public: public:
CGLSLProgram(); CGLSLProgram();
~CGLSLProgram(); ~CGLSLProgram();
bool attachVertexProgram( IProgram *shader ); unsigned int getProgramId() const{ return programId; }
bool attachPixelProgram( IProgram *shader ); void setProgramId( unsigned int Id ){ programId = Id; }
bool detachVertexProgram( IProgram *shader ); void cacheUniforms();
bool detachPixelProgram( IProgram *shader ); int getUniformIndex( uint32 id ) const{ return uniformIndices[ id ]; }
bool link( std::string &log );
bool validate( std::string &log );
void cacheUniformIndices();
int getUniformIndex( EUniform uniform );
private:
void deleteShaders();
protected:
unsigned int programId;
int uniformIndices[ NUM_UNIFORMS ]; int uniformIndices[ NUM_UNIFORMS ];
std::vector< IProgram* > vertexPrograms;
std::vector< IProgram* > pixelPrograms;
}; };
} }
#endif #endif

@ -1,64 +0,0 @@
// NeL - MMORPG Framework <http://dev.ryzom.com/projects/nel/>
// Copyright (C) 2010 Winch Gate Property Limited
//
// 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/>.
#include "driver_glsl_shader_base.h"
#include "stdopengl.h"
#include "driver_opengl_extension.h"
#define MAX_SHADER_COMPILE_INFOLOG 1024
namespace NL3D
{
void CGLSLShaderBase::shaderSource( const char *source )
{
nlassert( shaderId != 0 );
const GLchar *p[1];
p[ 0 ] = source;
GLint lengths[ 1 ];
lengths[ 0 ] = strlen( source );
nglShaderSource( shaderId, 1, p, lengths );
}
bool CGLSLShaderBase::compile( std::string &log )
{
nglCompileShader( shaderId );
GLint ok;
nglGetShaderiv( shaderId, GL_COMPILE_STATUS, &ok );
if( ok != GL_TRUE )
{
char infoLog[ MAX_SHADER_COMPILE_INFOLOG ];
nglGetShaderInfoLog( shaderId, MAX_SHADER_COMPILE_INFOLOG, NULL, infoLog );
log.assign( infoLog );
return false;
}
compiled = true;
return true;
}
}

@ -1,41 +0,0 @@
// NeL - MMORPG Framework <http://dev.ryzom.com/projects/nel/>
// Copyright (C) 2010 Winch Gate Property Limited
//
// 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 GLSL_SHADER_BASE_H
#define GLSL_SHADER_BASE_H
#include "nel/3d/i_program.h"
namespace NL3D
{
/// Base class for OpenGL shader objects
class CGLSLShaderBase : public IProgram
{
public:
CGLSLShaderBase() : IProgram(){}
~CGLSLShaderBase(){}
void shaderSource( const char *source );
bool compile( std::string &log );
};
}
#endif

@ -149,6 +149,12 @@ namespace NL3D
ss << std::endl; ss << std::endl;
ss << "#version 330" << 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 mvpMatrix;" << std::endl; ss << "uniform mat4 mvpMatrix;" << std::endl;
ss << std::endl; ss << std::endl;

@ -22,15 +22,14 @@
namespace NL3D namespace NL3D
{ {
CGLSLVertexProgram::CGLSLVertexProgram() : CGLSLVertexProgram::CGLSLVertexProgram() :
CGLSLShaderBase() CGLSLProgram()
{ {
type = VERTEX_PROGRAM; type = VERTEX_PROGRAM;
shaderId = nglCreateShader( GL_VERTEX_SHADER );
nlassert( shaderId != 0 );
} }
CGLSLVertexProgram::~CGLSLVertexProgram() CGLSLVertexProgram::~CGLSLVertexProgram()
{ {
nglDeleteShader( shaderId ); if( programId != 0 )
nglDeleteProgram( programId );
} }
} }

@ -18,12 +18,12 @@
#ifndef GLSL_VERTEX_PROGRAM_H #ifndef GLSL_VERTEX_PROGRAM_H
#define GLSL_VERTEX_PROGRAM_H #define GLSL_VERTEX_PROGRAM_H
#include "driver_glsl_shader_base.h" #include "driver_glsl_program.h"
#include <string> #include <string>
namespace NL3D namespace NL3D
{ {
class CGLSLVertexProgram : public CGLSLShaderBase class CGLSLVertexProgram : public CGLSLProgram
{ {
public: public:
CGLSLVertexProgram(); CGLSLVertexProgram();

@ -320,8 +320,11 @@ CDriverGL3::CDriverGL3()
_TextureTargetCubeFace = 0; _TextureTargetCubeFace = 0;
_TextureTargetUpload = false; _TextureTargetUpload = false;
currentProgram = NULL; vertexProgram = NULL;
dynMatProgram = NULL; pixelProgram = NULL;
dynMatVP = NULL;
dynMatPP = NULL;
shaderGenerator = new CGLSLShaderGenerator(); shaderGenerator = new CGLSLShaderGenerator();
usrShaderManager = new CUsrShaderManager(); usrShaderManager = new CUsrShaderManager();
@ -329,7 +332,6 @@ CDriverGL3::CDriverGL3()
CUsrShaderLoader loader; CUsrShaderLoader loader;
loader.setManager( usrShaderManager ); loader.setManager( usrShaderManager );
loader.loadShaders( "./shaders" ); loader.loadShaders( "./shaders" );
} }
// *************************************************************************** // ***************************************************************************
@ -339,11 +341,16 @@ CDriverGL3::~CDriverGL3()
release(); release();
currentProgram = NULL; vertexProgram = NULL;
pixelProgram = NULL;
if( dynMatVP != NULL )
delete dynMatVP;
dynMatVP = NULL;
if( dynMatProgram != NULL ) if( dynMatPP != NULL )
delete dynMatProgram; delete dynMatPP;
dynMatProgram = NULL; dynMatPP = NULL;
delete shaderGenerator; delete shaderGenerator;
shaderGenerator = NULL; shaderGenerator = NULL;
@ -504,6 +511,12 @@ bool CDriverGL3::setupDisplay()
// Reset the vbl interval // Reset the vbl interval
setSwapVBLInterval(_Interval); setSwapVBLInterval(_Interval);
if( !initPipeline() )
{
nlinfo( "Failed to create Pipeline Object" );
nlassert( false );
}
return true; return true;
} }
@ -620,8 +633,6 @@ bool CDriverGL3::swapBuffers()
H_AUTO_OGL(CDriverGL3_swapBuffers) H_AUTO_OGL(CDriverGL3_swapBuffers)
++ _SwapBufferCounter; ++ _SwapBufferCounter;
// Reset texture shaders
activeVertexProgram(NULL);
#ifdef NL_OS_WINDOWS #ifdef NL_OS_WINDOWS
if (_EventEmitter.getNumEmitters() > 1) // is direct input running ? if (_EventEmitter.getNumEmitters() > 1) // is direct input running ?

@ -19,8 +19,6 @@
#include "nel/misc/types_nl.h" #include "nel/misc/types_nl.h"
#define GLSL
//#define NL_PROFILE_DRIVER_OGL //#define NL_PROFILE_DRIVER_OGL
#ifdef NL_PROFILE_DRIVER_OGL #ifdef NL_PROFILE_DRIVER_OGL
# define H_AUTO_OGL(label) H_AUTO(label) # define H_AUTO_OGL(label) H_AUTO(label)
@ -282,6 +280,10 @@ public:
class CGLSLShaderGenerator; class CGLSLShaderGenerator;
class CUsrShaderManager; class CUsrShaderManager;
class CGLSLProgram;
class CGLSLVertexProgram;
class CGLSLPixelProgram;
// *************************************************************************** // ***************************************************************************
class CDriverGL3 : public IDriver class CDriverGL3 : public IDriver
{ {
@ -381,7 +383,8 @@ public:
void generateShaderDesc(CShaderDesc &desc, CMaterial &mat); void generateShaderDesc(CShaderDesc &desc, CMaterial &mat);
bool setupProgram(CMaterial& mat); bool setupProgram(CMaterial& mat);
bool setupDynMatProgram(CMaterial& mat, uint pass); bool setupDynMatProgram(CMaterial& mat, uint pass);
void setupUniforms(CMaterial& mat); void setupUniforms();
void setupUniforms( CGLSLProgram *program );
virtual void startSpecularBatch(); virtual void startSpecularBatch();
virtual void endSpecularBatch(); virtual void endSpecularBatch();
@ -443,7 +446,6 @@ public:
virtual bool renderRawPoints(CMaterial& Mat, uint32 startIndex, uint32 numPoints); virtual bool renderRawPoints(CMaterial& Mat, uint32 startIndex, uint32 numPoints);
virtual bool renderRawLines(CMaterial& Mat, uint32 startIndex, uint32 numLines); virtual bool renderRawLines(CMaterial& Mat, uint32 startIndex, uint32 numLines);
virtual bool renderRawTriangles(CMaterial& Mat, uint32 startIndex, uint32 numTris); virtual bool renderRawTriangles(CMaterial& Mat, uint32 startIndex, uint32 numTris);
virtual bool renderRawTriangles2( CMaterial &mat, uint32 startVertex, uint32 numTri );
virtual bool renderRawQuads(CMaterial& Mat, uint32 startIndex, uint32 numQuads); virtual bool renderRawQuads(CMaterial& Mat, uint32 startIndex, uint32 numQuads);
// //
virtual bool renderLinesWithIndexOffset(CMaterial& /* mat */, uint32 /* firstIndex */, uint32 /* nlines */, uint /* indexOffset */) { nlassertex(0, (UNSUPPORTED_INDEX_OFFSET_MSG)); return false; } virtual bool renderLinesWithIndexOffset(CMaterial& /* mat */, uint32 /* firstIndex */, uint32 /* nlines */, uint /* indexOffset */) { nlassertex(0, (UNSUPPORTED_INDEX_OFFSET_MSG)); return false; }
@ -1223,23 +1225,28 @@ private:
bool isVertexProgramSupported () const{ return true; } bool isVertexProgramSupported () const{ return true; }
bool isVertexProgramEmulated () const{ return false; } bool isVertexProgramEmulated () const{ return false; }
bool activeVertexProgram (CVertexProgram *program){ return true; }; bool activeVertexProgram (CVertexProgram *program){ return true; };
bool activeProgramObject( IProgramObject *program );
IProgramObject* createProgramObject() const; bool compileVertexProgram( CGLSLVertexProgram *program );
bool activeVertexProgram( CGLSLVertexProgram *program );
bool compilePixelProgram( CGLSLPixelProgram *program );
bool activePixelProgram( CGLSLPixelProgram *program );
IProgram* createVertexProgram() const; IProgram* createVertexProgram() const;
IProgram* createPixelProgram() const; IProgram* createPixelProgram() const;
int getUniformLocation( const char *name ); int getUniformLocation( uint32 programType, const char *name );
void setUniform1f( uint index, float f ); void setUniform1f( uint32 programType, uint index, float f );
void setUniform3f( uint index, float f1, float f2, float f3 ); void setUniform3f( uint32 programType, uint index, float f1, float f2, float f3 );
void setUniform4f( uint index, float f1, float f2, float f3, float f4 ); void setUniform4f( uint32 programType, uint index, float f1, float f2, float f3, float f4 );
void setUniform1i( uint index, int i ); void setUniform1i( uint32 programType, uint index, int i );
void setUniform4i( uint index, int i1, int i2, int i3, int i4 ); void setUniform4i( uint32 programType, uint index, int i1, int i2, int i3, int i4 );
void setUniform1u( uint index, uint u ); void setUniform1u( uint32 programType, uint index, uint u );
void setUniform4u( uint index, uint u1, uint u2, uint u3, uint u4 ); void setUniform4u( uint32 programType, uint index, uint u1, uint u2, uint u3, uint u4 );
void setUniformMatrix2fv( uint index, uint count, bool transpose, const float *values ); void setUniformMatrix2fv( uint32 programType, uint index, uint count, bool transpose, const float *values );
void setUniformMatrix3fv( uint index, uint count, bool transpose, const float *values ); void setUniformMatrix3fv( uint32 programType, uint index, uint count, bool transpose, const float *values );
void setUniformMatrix4fv( uint index, uint count, bool transpose, const float *values ); void setUniformMatrix4fv( uint32 programType, uint index, uint count, bool transpose, const float *values );
void setConstant (uint index, float, float, float, float){} void setConstant (uint index, float, float, float, float){}
void setConstant (uint index, double, double, double, double){} void setConstant (uint index, double, double, double, double){}
@ -1306,11 +1313,14 @@ private:
CGLSLShaderGenerator *shaderGenerator; CGLSLShaderGenerator *shaderGenerator;
CUsrShaderManager *usrShaderManager; CUsrShaderManager *usrShaderManager;
/// The program that is currently used bool initPipeline();
IProgramObject *currentProgram;
uint32 ppoId;
CGLSLVertexProgram *vertexProgram;
CGLSLPixelProgram *pixelProgram;
/// The current user shader program CGLSLVertexProgram *dynMatVP;
IProgramObject *dynMatProgram; CGLSLPixelProgram *dynMatPP;
// init EMBM settings (set each stage to modify the next) // init EMBM settings (set each stage to modify the next)
void initEMBM(); void initEMBM();

@ -20,8 +20,9 @@
#include "nel/3d/texture_mem.h" #include "nel/3d/texture_mem.h"
#include "nel/3d/texture_bump.h" #include "nel/3d/texture_bump.h"
#include "nel/3d/material.h" #include "nel/3d/material.h"
#include "nel/3d/i_program_object.h"
#include "nel/3d/dynamic_material.h" #include "nel/3d/dynamic_material.h"
#include "driver_glsl_vertex_program.h"
#include "driver_glsl_pixel_program.h"
namespace NL3D { namespace NL3D {
@ -603,78 +604,92 @@ bool CDriverGL3::setupDynMatPass( uint pass )
CDynMaterial *m = _CurrentMaterial->getDynMat(); CDynMaterial *m = _CurrentMaterial->getDynMat();
SRenderPass *p = m->getPass( pass ); SRenderPass *p = m->getPass( pass );
for( uint32 i = 0; i < p->count(); i++ ) CGLSLProgram *currentProgram;
uint32 type;
CGLSLProgram* programs[ 2 ];
programs[ 0 ] = vertexProgram;
programs[ 1 ] = pixelProgram;
for( uint32 j = 0; j < 2; j++ )
{ {
const SDynMaterialProp *prop = p->getProperty( i ); currentProgram = programs[ j ];
int loc = nglGetUniformLocation( currentProgram->getProgramId(), prop->prop.c_str() ); type = currentProgram->getType();
if( loc == -1 )
continue;
switch( prop->type ) for( uint32 i = 0; i < p->count(); i++ )
{ {
case SDynMaterialProp::Float: const SDynMaterialProp *prop = p->getProperty( i );
setUniform1f( loc, prop->value.toFloat() ); int loc = nglGetUniformLocation( currentProgram->getProgramId(), prop->prop.c_str() );
break; if( loc == -1 )
continue;
case SDynMaterialProp::Int: switch( prop->type )
setUniform1i( loc, prop->value.toInt() ); {
break; case SDynMaterialProp::Float:
setUniform1f( type, loc, prop->value.toFloat() );
break;
case SDynMaterialProp::Uint: case SDynMaterialProp::Int:
setUniform1u( loc, prop->value.toUInt() ); setUniform1i( type, loc, prop->value.toInt() );
break; break;
case SDynMaterialProp::Color: case SDynMaterialProp::Uint:
{ setUniform1u( type, loc, prop->value.toUInt() );
float v[ 4 ]; break;
prop->value.getVector4( v );
for( int j = 0; j < 4; j++ ) case SDynMaterialProp::Color:
v[ j ] = v[ j ] / 255.0f; {
float v[ 4 ];
prop->value.getVector4( v );
setUniform4f( loc, v[ 0 ], v[ 1 ], v[ 2 ], v[ 3 ] ); for( int j = 0; j < 4; j++ )
} v[ j ] = v[ j ] / 255.0f;
break;
case SDynMaterialProp::Vector4: setUniform4f( type, loc, v[ 0 ], v[ 1 ], v[ 2 ], v[ 3 ] );
{ }
float v[ 4 ]; break;
prop->value.getVector4( v );
setUniform4f( loc, v[ 0 ], v[ 1 ], v[ 2 ], v[ 3 ] );
}
break;
case SDynMaterialProp::Matrix4: case SDynMaterialProp::Vector4:
{ {
float m[ 16 ]; float v[ 4 ];
prop->value.getMatrix4( m ); prop->value.getVector4( v );
setUniformMatrix4fv( loc, 1, false, m ); setUniform4f( type, loc, v[ 0 ], v[ 1 ], v[ 2 ], v[ 3 ] );
}
break;
case SDynMaterialProp::Matrix4:
{
float m[ 16 ];
prop->value.getMatrix4( m );
setUniformMatrix4fv( type, loc, 1, false, m );
break;
}
case SDynMaterialProp::Texture:
break; break;
} }
}
////////////////////////////////// Set up some standard uniforms //////////////////////////////////
case SDynMaterialProp::Texture: int loc = -1;
break; loc = nglGetUniformLocation( currentProgram->getProgramId(), "mvpMatrix" );
if( loc != -1 )
{
CMatrix mat = _GLProjMat * _ModelViewMatrix;
setUniformMatrix4fv( type, loc, 1, false, mat.get() );
} }
}
////////////////////////////////// Set up some standard uniforms ////////////////////////////////// loc = nglGetUniformLocation( currentProgram->getProgramId(), "mvMatrix" );
if( loc != -1 )
{
setUniformMatrix4fv( type, loc, 1, false, _ModelViewMatrix.get() );
}
int loc = -1; ////////////////////////////////////////////////////////////////////////////////////////////////////
loc = nglGetUniformLocation( currentProgram->getProgramId(), "mvpMatrix" );
if( loc != -1 )
{
CMatrix mat = _GLProjMat * _ModelViewMatrix;
setUniformMatrix4fv( loc, 1, false, mat.get() );
}
loc = nglGetUniformLocation( currentProgram->getProgramId(), "mvMatrix" );
if( loc != -1 )
{
setUniformMatrix4fv( loc, 1, false, _ModelViewMatrix.get() );
} }
////////////////////////////////////////////////////////////////////////////////////////////////////
return true; return true;
} }
@ -685,12 +700,12 @@ void CDriverGL3::setupNormalPass()
for( int i = 0; i < IDRV_MAT_MAXTEXTURES; i++ ) for( int i = 0; i < IDRV_MAT_MAXTEXTURES; i++ )
{ {
// Set constant // Set constant
int cl = currentProgram->getUniformIndex( IProgramObject::EUniform( IProgramObject::Constant0 + i ) ); int cl = pixelProgram->getUniformIndex( IProgram::EUniform( IProgram::Constant0 + i ) );
if( cl != -1 ) if( cl != -1 )
{ {
GLfloat glCol[ 4 ]; GLfloat glCol[ 4 ];
convColor( mat._TexEnvs[ i ].ConstantColor, glCol ); convColor( mat._TexEnvs[ i ].ConstantColor, glCol );
setUniform4f( cl, glCol[ 0 ], glCol[ 1 ], glCol[ 2 ], glCol[ 3 ] ); setUniform4f( IProgram::PIXEL_PROGRAM, cl, glCol[ 0 ], glCol[ 1 ], glCol[ 2 ], glCol[ 3 ] );
} }
// Set texture // Set texture
@ -698,11 +713,11 @@ void CDriverGL3::setupNormalPass()
if( t == NULL ) if( t == NULL )
continue; continue;
int index = currentProgram->getUniformIndex( IProgramObject::EUniform( IProgramObject::Sampler0 + i ) ); int index = pixelProgram->getUniformIndex( IProgram::EUniform( IProgram::Sampler0 + i ) );
if( index == -1 ) if( index == -1 )
continue; continue;
setUniform1i( index, i ); setUniform1i( IProgram::PIXEL_PROGRAM, index, i );
} }
} }
@ -879,18 +894,18 @@ void CDriverGL3::setupLightMapPass(uint pass)
// setup constant color with Lightmap factor. // setup constant color with Lightmap factor.
stdEnv.ConstantColor=lmapFactor; stdEnv.ConstantColor=lmapFactor;
int cl = currentProgram->getUniformIndex( IProgramObject::EUniform( IProgramObject::Constant0 + stage ) ); int cl = pixelProgram->getUniformIndex( IProgram::EUniform( IProgram::Constant0 + stage ) );
if( cl != -1 ) if( cl != -1 )
{ {
GLfloat glCol[ 4 ]; GLfloat glCol[ 4 ];
convColor( lmapFactor, glCol ); convColor( lmapFactor, glCol );
setUniform4f( cl, glCol[ 0 ], glCol[ 1 ], glCol[ 2 ], glCol[ 3 ] ); setUniform4f( IProgram::PIXEL_PROGRAM, cl, glCol[ 0 ], glCol[ 1 ], glCol[ 2 ], glCol[ 3 ] );
} }
int tl = currentProgram->getUniformIndex( IProgramObject::EUniform( IProgramObject::Sampler0 + stage ) ); int tl = pixelProgram->getUniformIndex( IProgram::EUniform( IProgram::Sampler0 + stage ) );
if( tl != -1 ) if( tl != -1 )
{ {
setUniform1i( tl, stage ); setUniform1i( IProgram::PIXEL_PROGRAM, tl, stage );
} }
activateTexEnvColor(stage, stdEnv); activateTexEnvColor(stage, stdEnv);
@ -928,10 +943,10 @@ void CDriverGL3::setupLightMapPass(uint pass)
_DriverGLStates.activeTextureARB(stage); _DriverGLStates.activeTextureARB(stage);
_DriverGLStates.setTexGenMode(stage, 0); _DriverGLStates.setTexGenMode(stage, 0);
int tl = currentProgram->getUniformIndex( IProgramObject::EUniform( IProgramObject::Sampler0 + stage ) ); int tl = pixelProgram->getUniformIndex( IProgram::EUniform( IProgram::Sampler0 + stage ) );
if( tl != -1 ) if( tl != -1 )
{ {
setUniform1i( tl, stage ); setUniform1i( IProgram::PIXEL_PROGRAM, tl, stage );
} }
} }
@ -1124,22 +1139,22 @@ void CDriverGL3::setupSpecularPass(uint pass)
return; return;
} }
int sl0 = currentProgram->getUniformIndex( IProgramObject::Sampler0 ); int sl0 = pixelProgram->getUniformIndex( IProgram::Sampler0 );
if( sl0 != -1 ) if( sl0 != -1 )
{ {
setUniform1i( sl0, 0 ); setUniform1i( IProgram::PIXEL_PROGRAM, sl0, 0 );
} }
int sl1 = currentProgram->getUniformIndex( IProgramObject::Sampler1 ); int sl1 = pixelProgram->getUniformIndex( IProgram::Sampler1 );
if( sl1 != -1 ) if( sl1 != -1 )
{ {
setUniform1i( sl1, 1 ); setUniform1i( IProgram::PIXEL_PROGRAM, sl1, 1 );
} }
int tml = currentProgram->getUniformIndex( IProgramObject::TexMatrix0 ); int tml = pixelProgram->getUniformIndex( IProgram::TexMatrix0 );
if( tml != -1 ) if( tml != -1 )
{ {
setUniformMatrix4fv( tml, 1, false, _UserTexMat[ 1 ].get() ); setUniformMatrix4fv( IProgram::PIXEL_PROGRAM, tml, 1, false, _UserTexMat[ 1 ].get() );
} }
{ {

@ -14,14 +14,12 @@
// 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 "driver_opengl.h" #include "driver_opengl.h"
#include "driver_glsl_program.h" #include "driver_glsl_program.h"
#include "driver_glsl_vertex_program.h" #include "driver_glsl_vertex_program.h"
#include "driver_glsl_pixel_program.h" #include "driver_glsl_pixel_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/i_program_object.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"
@ -40,32 +38,109 @@ namespace
namespace NL3D namespace NL3D
{ {
bool CDriverGL3::activeProgramObject( IProgramObject *program ) bool CDriverGL3::compileVertexProgram( CGLSLVertexProgram *program )
{ {
if( !program ) // Already compiled
{ if( program->getProgramId() != 0 )
currentProgram = NULL;
return true; return true;
const char *s = program->getSource().c_str();
glGetError();
unsigned int id = nglCreateShaderProgramv( GL_VERTEX_SHADER, 1, &s );
if( id == 0 )
return false;
GLint ok;
nglGetProgramiv( id, GL_LINK_STATUS, &ok );
if( ok == 0 )
{
char errorLog[ 1024 ];
nglGetProgramInfoLog( id, 1024, NULL, errorLog );
nlinfo( "%s", errorLog );
return false;
} }
if( !program->isLinked() )
GLenum error = glGetError();
if( error != GL_NO_ERROR )
return false; return false;
nglUseProgram( program->getProgramId() ); program->setProgramId( id );
return true;
}
bool CDriverGL3::activeVertexProgram( CGLSLVertexProgram *program )
{
if( program->getProgramId() == 0 )
return false;
glGetError();
nglUseProgramStages( ppoId, GL_VERTEX_SHADER_BIT, program->getProgramId() );
GLenum error = glGetError(); GLenum error = glGetError();
if( error != GL_NO_ERROR ) if( error != GL_NO_ERROR )
{
return false; return false;
}
currentProgram = program; vertexProgram = program;
return true; return true;
} }
bool CDriverGL3::compilePixelProgram( CGLSLPixelProgram *program )
{
// Already compiled
if( program->getProgramId() != 0 )
return true;
const char *s = program->getSource().c_str();
glGetError();
unsigned int id = nglCreateShaderProgramv( GL_FRAGMENT_SHADER, 1, &s );
if( id == 0 )
return false;
GLint ok;
nglGetProgramiv( id, GL_LINK_STATUS, &ok );
if( ok == 0 )
{
char errorLog[ 1024 ];
nglGetProgramInfoLog( id, 1024, NULL, errorLog );
nlinfo( "%s", errorLog );
return false;
}
GLenum error = glGetError();
if( error != GL_NO_ERROR )
return false;
IProgramObject* CDriverGL3::createProgramObject() const program->setProgramId( id );
return true;
}
bool CDriverGL3::activePixelProgram( CGLSLPixelProgram *program )
{ {
return new CGLSLProgram(); if( program->getProgramId() == 0 )
return false;
glGetError();
nglUseProgramStages( ppoId, GL_FRAGMENT_SHADER_BIT, program->getProgramId() );
GLenum error = glGetError();
if( error != GL_NO_ERROR )
{
return false;
}
pixelProgram = program;
return true;
} }
IProgram* CDriverGL3::createVertexProgram() const IProgram* CDriverGL3::createVertexProgram() const
@ -78,70 +153,213 @@ namespace NL3D
return new CGLSLPixelProgram(); return new CGLSLPixelProgram();
} }
int CDriverGL3::getUniformLocation( const char *name ) int CDriverGL3::getUniformLocation( uint32 programType, const char *name )
{ {
if( currentProgram == NULL ) switch( programType )
return -1; {
case IProgram::VERTEX_PROGRAM:
nlassert( vertexProgram != NULL );
return nglGetUniformLocation( vertexProgram->getProgramId(), name );
break;
case IProgram::PIXEL_PROGRAM:
nlassert( pixelProgram != NULL );
return nglGetUniformLocation( pixelProgram->getProgramId(), name );
break;
}
return nglGetUniformLocation( currentProgram->getProgramId(), name ); return -1;
} }
void CDriverGL3::setUniform1f( uint index, float f ) void CDriverGL3::setUniform1f( uint32 programType, uint index, float f )
{ {
nglUniform1f( index, f ); switch( programType )
} {
case IProgram::VERTEX_PROGRAM:
void CDriverGL3::setUniform3f( uint index, float f1, float f2, float f3 ) nlassert( vertexProgram != NULL );
{ nglProgramUniform1f( vertexProgram->getProgramId(), index, f );
nglUniform3f( index, f1, f2, f3 ); break;
case IProgram::PIXEL_PROGRAM:
nlassert( pixelProgram != NULL );
nglProgramUniform1f( pixelProgram->getProgramId(), index, f );
break;
default:
nlassert( false );
break;
}
} }
void CDriverGL3::setUniform4f( uint index, float f1, float f2, float f3, float f4 ) void CDriverGL3::setUniform3f( uint32 programType, uint index, float f1, float f2, float f3 )
{ {
nglUniform4f( index, f1, f2, f3, f4 ); switch( programType )
{
case IProgram::VERTEX_PROGRAM:
nlassert( vertexProgram != NULL );
nglProgramUniform3f( vertexProgram->getProgramId(), index, f1, f2, f3 );
break;
case IProgram::PIXEL_PROGRAM:
nlassert( pixelProgram != NULL );
nglProgramUniform3f( pixelProgram->getProgramId(), index, f1, f2, f3 );
break;
default:
nlassert( false );
break;
}
} }
void CDriverGL3::setUniform1i( uint index, int i ) void CDriverGL3::setUniform4f( uint32 programType, uint index, float f1, float f2, float f3, float f4 )
{ {
nglUniform1i( index, i ); switch( programType )
{
case IProgram::VERTEX_PROGRAM:
nlassert( vertexProgram != NULL );
nglProgramUniform4f( vertexProgram->getProgramId(), index, f1, f2, f3, f4 );
break;
case IProgram::PIXEL_PROGRAM:
nlassert( pixelProgram != NULL );
nglProgramUniform4f( pixelProgram->getProgramId(), index, f1, f2, f3, f4 );
break;
default:
nlassert( false );
break;
}
} }
void CDriverGL3::setUniform4i( uint index, int i1, int i2, int i3, int i4 ) void CDriverGL3::setUniform1i( uint32 programType, uint index, int i )
{ {
nglUniform4i( index, i1, i2, i3, i4 ); switch( programType )
{
case IProgram::VERTEX_PROGRAM:
nlassert( vertexProgram != NULL );
nglProgramUniform1i( vertexProgram->getProgramId(), index, i );
break;
case IProgram::PIXEL_PROGRAM:
nlassert( pixelProgram != NULL );
nglProgramUniform1i( pixelProgram->getProgramId(), index, i );
break;
default:
nlassert( false );
break;
}
} }
void CDriverGL3::setUniform1u( uint index, uint u ) void CDriverGL3::setUniform4i( uint32 programType, uint index, int i1, int i2, int i3, int i4 )
{ {
nglUniform1ui( index, u ); switch( programType )
{
case IProgram::VERTEX_PROGRAM:
nlassert( vertexProgram != NULL );
nglProgramUniform4i( vertexProgram->getProgramId(), index, i1, i2, i3, i4 );
break;
case IProgram::PIXEL_PROGRAM:
nlassert( pixelProgram != NULL );
nglProgramUniform4i( pixelProgram->getProgramId(), index, i1, i2, i3, i4 );
break;
default:
nlassert( false );
break;
}
} }
void CDriverGL3::setUniform4u( uint index, uint u1, uint u2, uint u3, uint u4 ) void CDriverGL3::setUniform1u( uint32 programType, uint index, uint u )
{ {
nglUniform4ui( index, u1, u2, u3, u4 ); switch( programType )
{
case IProgram::VERTEX_PROGRAM:
nlassert( vertexProgram != NULL );
nglProgramUniform1ui( vertexProgram->getProgramId(), index, u );
break;
case IProgram::PIXEL_PROGRAM:
nlassert( pixelProgram != NULL );
nglProgramUniform1ui( pixelProgram->getProgramId(), index, u );
break;
default:
nlassert( false );
break;
}
} }
void CDriverGL3::setUniformMatrix2fv( uint index, uint count, bool transpose, const float *values ) void CDriverGL3::setUniform4u( uint32 programType, uint index, uint u1, uint u2, uint u3, uint u4 )
{ {
nglUniformMatrix2fv( index, count, transpose, values ); switch( programType )
{
case IProgram::VERTEX_PROGRAM:
nlassert( vertexProgram != NULL );
nglProgramUniform4ui( vertexProgram->getProgramId(), index, u1, u2, u3, u4 );
break;
case IProgram::PIXEL_PROGRAM:
nlassert( pixelProgram != NULL );
nglProgramUniform4ui( pixelProgram->getProgramId(), index, u1, u2, u3, u4 );
break;
default:
nlassert( false );
break;
}
} }
void CDriverGL3::setUniformMatrix3fv( uint index, uint count, bool transpose, const float *values ) void CDriverGL3::setUniformMatrix2fv( uint32 programType, uint index, uint count, bool transpose, const float *values )
{ {
nglUniformMatrix3fv( index, count, transpose, values ); switch( programType )
{
case IProgram::VERTEX_PROGRAM:
nlassert( vertexProgram != NULL );
nglProgramUniformMatrix2fv( vertexProgram->getProgramId(), index, count, transpose, values );
break;
case IProgram::PIXEL_PROGRAM:
nlassert( pixelProgram != NULL );
nglProgramUniformMatrix2fv( pixelProgram->getProgramId(), index, count, transpose, values );
break;
default:
nlassert( false );
break;
}
} }
void CDriverGL3::setUniformMatrix4fv( uint index, uint count, bool transpose, const float *values ) void CDriverGL3::setUniformMatrix3fv( uint32 programType, uint index, uint count, bool transpose, const float *values )
{ {
nglUniformMatrix4fv( index, count, transpose, values ); switch( programType )
{
case IProgram::VERTEX_PROGRAM:
nlassert( vertexProgram != NULL );
nglProgramUniformMatrix3fv( vertexProgram->getProgramId(), index, count, transpose, values );
break;
case IProgram::PIXEL_PROGRAM:
nlassert( pixelProgram != NULL );
nglProgramUniformMatrix3fv( pixelProgram->getProgramId(), index, count, transpose, values );
break;
default:
nlassert( false );
break;
}
} }
bool CDriverGL3::renderRawTriangles2( CMaterial &mat, uint32 startIndex, uint32 numTris ) void CDriverGL3::setUniformMatrix4fv( uint32 programType, uint index, uint count, bool transpose, const float *values )
{ {
glDrawArrays( GL_TRIANGLES, startIndex * 3, numTris * 3 ); switch( programType )
{
return true; case IProgram::VERTEX_PROGRAM:
nlassert( vertexProgram != NULL );
nglProgramUniformMatrix4fv( vertexProgram->getProgramId(), index, count, transpose, values );
break;
case IProgram::PIXEL_PROGRAM:
nlassert( pixelProgram != NULL );
nglProgramUniformMatrix4fv( pixelProgram->getProgramId(), index, count, transpose, values );
break;
default:
nlassert( false );
break;
}
} }
void CDriverGL3::generateShaderDesc( CShaderDesc &desc, CMaterial &mat ) void CDriverGL3::generateShaderDesc( CShaderDesc &desc, CMaterial &mat )
@ -210,19 +428,22 @@ namespace NL3D
if( mat.getDynMat() != NULL ) if( mat.getDynMat() != NULL )
return true; return true;
IProgram *vp = NULL; CGLSLVertexProgram *vp = NULL;
IProgram *pp = NULL; CGLSLPixelProgram *pp = NULL;
IProgramObject *p = NULL; SShaderPair sp;
CShaderDesc desc; CShaderDesc desc;
generateShaderDesc( desc, mat ); generateShaderDesc( desc, mat );
p = shaderCache.findShader( desc ); sp = shaderCache.findShader( desc );
if( p != NULL ) if( !sp.empty() )
{ {
if( !activeProgramObject( p ) ) if( !activeVertexProgram( sp.vp ) )
return false;
if( !activePixelProgram( sp.pp ) )
return false; return false;
} }
else else
@ -237,52 +458,53 @@ namespace NL3D
shaderGenerator->generateVS( vs ); shaderGenerator->generateVS( vs );
shaderGenerator->generatePS( ps ); shaderGenerator->generatePS( ps );
vp = createVertexProgram(); vp = new CGLSLVertexProgram();
std::string log; vp->setSource( vs.c_str() );
if( !compileVertexProgram( vp ) )
vp->shaderSource( vs.c_str() );
if( !vp->compile( log ) )
{ {
delete vp; delete vp;
vp = NULL; vp = NULL;
nlinfo( "%s", log.c_str() );
return false; return false;
} }
pp = createPixelProgram(); pp = new CGLSLPixelProgram();
pp->shaderSource( ps.c_str() ); pp->setSource( ps.c_str() );
if( !pp->compile( log ) ) if( !compilePixelProgram( pp ) )
{ {
delete vp; delete vp;
vp = NULL; vp = NULL;
delete pp; delete pp;
pp = NULL; pp = NULL;
nlinfo( "%s", log.c_str() );
return false; return false;
} }
p = createProgramObject(); if( !activeVertexProgram( vp ) )
p->attachVertexProgram( vp );
p->attachPixelProgram( pp );
if( !p->link( log ) )
{ {
delete vp;
vp = NULL; vp = NULL;
delete pp;
pp = NULL; pp = NULL;
delete p;
p = NULL;
nlinfo( "%s", log.c_str() );
return false; return false;
} }
if( !activeProgramObject( p ) ) if( !activePixelProgram( pp ) )
{
delete vp;
vp = NULL;
delete pp;
pp = NULL;
return false; return false;
}
p->cacheUniformIndices(); vp->cacheUniforms();
desc.setProgram( p ); pp->cacheUniforms();
sp.vp = vp;
sp.pp = pp;
desc.setShaders( sp );
shaderCache.cacheShader( desc ); shaderCache.cacheShader( desc );
} }
setupUniforms( mat ); setupUniforms();
return true; return true;
} }
@ -299,90 +521,103 @@ namespace NL3D
if( !usrShaderManager->getShader( shaderRef, &prg ) ) if( !usrShaderManager->getShader( shaderRef, &prg ) )
return false; return false;
IProgramObject *p = createProgramObject(); CGLSLVertexProgram *vp = new CGLSLVertexProgram();
IProgram *vp = createVertexProgram(); CGLSLPixelProgram *pp = new CGLSLPixelProgram();
IProgram *pp = createPixelProgram();
std::string shaderSource; std::string shaderSource;
std::string log; std::string log;
prg.getVP( shaderSource ); prg.getVP( shaderSource );
vp->shaderSource( shaderSource.c_str() ); vp->setSource( shaderSource.c_str() );
if( !vp->compile( log ) ) if( !compileVertexProgram( vp ) )
{ {
delete vp; delete vp;
delete pp; delete pp;
delete p;
return false; return false;
} }
prg.getFP( shaderSource ); prg.getFP( shaderSource );
pp->shaderSource( shaderSource.c_str() ); pp->setSource( shaderSource.c_str() );
if( !pp->compile( log ) ) if( !compilePixelProgram( pp ) )
{ {
delete vp; delete vp;
delete pp; delete pp;
delete p;
return false; return false;
} }
p->attachVertexProgram( vp ); if( !activeVertexProgram( vp ) )
p->attachPixelProgram( pp );
if( !p->link( log ) )
{ {
delete p; delete vp;
delete pp;
return false; return false;
} }
if( !activeProgramObject( p ) ) if( !activePixelProgram( pp ) )
{ {
delete p; delete vp;
delete pp;
return false; return false;
} }
if( dynMatProgram != NULL ) if( dynMatVP != NULL )
delete dynMatProgram; delete dynMatVP;
dynMatProgram = p; dynMatVP = vp;
if( dynMatPP != NULL )
delete dynMatPP;
dynMatPP = pp;
vp->cacheUniforms();
pp->cacheUniforms();
return true; return true;
} }
void CDriverGL3::setupUniforms( CMaterial& mat ) void CDriverGL3::setupUniforms()
{
setupUniforms( vertexProgram );
setupUniforms( pixelProgram );
}
void CDriverGL3::setupUniforms( CGLSLProgram *program )
{ {
int mvpIndex = currentProgram->getUniformIndex( IProgramObject::MVPMatrix ); CMaterial &mat = *_CurrentMaterial;
CGLSLProgram *currentProgram = program;
uint32 type = program->getType();
int mvpIndex = currentProgram->getUniformIndex( IProgram::MVPMatrix );
if( mvpIndex != -1 ) if( mvpIndex != -1 )
{ {
CMatrix mat = _GLProjMat * _ModelViewMatrix; CMatrix mat = _GLProjMat * _ModelViewMatrix;
setUniformMatrix4fv( mvpIndex, 1, false, mat.get() ); setUniformMatrix4fv( type, mvpIndex, 1, false, mat.get() );
} }
int mvIndex = currentProgram->getUniformIndex( IProgramObject::MVMatrix ); int mvIndex = currentProgram->getUniformIndex( IProgram::MVMatrix );
if( mvIndex != -1 ) if( mvIndex != -1 )
{ {
setUniformMatrix4fv( mvIndex, 1, false, _ModelViewMatrix.get() ); setUniformMatrix4fv( type, mvIndex, 1, false, _ModelViewMatrix.get() );
} }
/* /*
int nmIdx = currentProgram->getUniformIndex( IProgramObject::NormalMatrix ); int nmIdx = currentProgram->getUniformIndex( IProgram::NormalMatrix );
if( nmIdx != -1 ) if( nmIdx != -1 )
{ {
} }
*/ */
int fogStartIdx = currentProgram->getUniformIndex( IProgramObject::FogStart ); int fogStartIdx = currentProgram->getUniformIndex( IProgram::FogStart );
if( fogStartIdx != -1 ) if( fogStartIdx != -1 )
{ {
setUniform1f( fogStartIdx, getFogStart() ); setUniform1f( type, fogStartIdx, getFogStart() );
} }
int fogEndIdx = currentProgram->getUniformIndex( IProgramObject::FogEnd ); int fogEndIdx = currentProgram->getUniformIndex( IProgram::FogEnd );
if( fogEndIdx != -1 ) if( fogEndIdx != -1 )
{ {
setUniform1f( fogEndIdx, getFogEnd() ); setUniform1f( type, fogEndIdx, getFogEnd() );
} }
int fogColorIdx = currentProgram->getUniformIndex( IProgramObject::FogColor ); int fogColorIdx = currentProgram->getUniformIndex( IProgram::FogColor );
if( fogColorIdx != -1 ) if( fogColorIdx != -1 )
{ {
GLfloat glCol[ 4 ]; GLfloat glCol[ 4 ];
@ -391,10 +626,10 @@ namespace NL3D
glCol[ 1 ] = col.G / 255.0f; glCol[ 1 ] = col.G / 255.0f;
glCol[ 2 ] = col.B / 255.0f; glCol[ 2 ] = col.B / 255.0f;
glCol[ 3 ] = col.A / 255.0f; glCol[ 3 ] = col.A / 255.0f;
setUniform4f( fogColorIdx, glCol[ 0 ], glCol[ 1 ], glCol[ 2 ], glCol[ 3 ] ); setUniform4f( type, fogColorIdx, glCol[ 0 ], glCol[ 1 ], glCol[ 2 ], glCol[ 3 ] );
} }
int colorIndex = currentProgram->getUniformIndex( IProgramObject::Color ); int colorIndex = currentProgram->getUniformIndex( IProgram::Color );
if( colorIndex != -1 ) if( colorIndex != -1 )
{ {
GLfloat glCol[ 4 ]; GLfloat glCol[ 4 ];
@ -404,10 +639,10 @@ namespace NL3D
glCol[ 2 ] = col.B / 255.0f; glCol[ 2 ] = col.B / 255.0f;
glCol[ 3 ] = col.A / 255.0f; glCol[ 3 ] = col.A / 255.0f;
setUniform4f( colorIndex, glCol[ 0 ], glCol[ 1 ], glCol[ 2 ], glCol[ 3 ] ); setUniform4f( type, colorIndex, glCol[ 0 ], glCol[ 1 ], glCol[ 2 ], glCol[ 3 ] );
} }
int diffuseIndex = currentProgram->getUniformIndex( IProgramObject::Diffuse ); int diffuseIndex = currentProgram->getUniformIndex( IProgram::Diffuse );
if( diffuseIndex != -1 ) if( diffuseIndex != -1 )
{ {
GLfloat glCol[ 4 ]; GLfloat glCol[ 4 ];
@ -417,7 +652,7 @@ namespace NL3D
glCol[ 2 ] = col.B / 255.0f; glCol[ 2 ] = col.B / 255.0f;
glCol[ 3 ] = col.A / 255.0f; glCol[ 3 ] = col.A / 255.0f;
setUniform4f( diffuseIndex, glCol[ 0 ], glCol[ 1 ], glCol[ 2 ], glCol[ 3 ] ); setUniform4f( type, diffuseIndex, glCol[ 0 ], glCol[ 1 ], glCol[ 2 ], glCol[ 3 ] );
} }
@ -428,25 +663,25 @@ namespace NL3D
continue; continue;
////////////////// Temporary insanity /////////////////////////////// ////////////////// Temporary insanity ///////////////////////////////
if( _LightMode[ i ] != CLight::DirectionalLight && _LightMode[ i ] != CLight::PointLight ) if( ( _LightMode[ i ] != CLight::DirectionalLight ) && ( _LightMode[ i ] != CLight::PointLight ) )
continue; continue;
////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////
int ld = currentProgram->getUniformIndex( IProgramObject::EUniform( IProgramObject::Light0Dir + i ) ); int ld = currentProgram->getUniformIndex( IProgram::EUniform( IProgram::Light0Dir + i ) );
if( ld != -1 ) if( ld != -1 )
{ {
CVector v = _UserLight[ i ].getDirection(); CVector v = _UserLight[ i ].getDirection();
setUniform3f( ld, v.x, v.y, v.z ); setUniform3f( type, ld, v.x, v.y, v.z );
} }
int lp = currentProgram->getUniformIndex( IProgramObject::EUniform( IProgramObject::Light0Pos + i ) ); int lp = currentProgram->getUniformIndex( IProgram::EUniform( IProgram::Light0Pos + i ) );
if( lp != -1 ) if( lp != -1 )
{ {
CVector v = _UserLight[ i ].getPosition(); CVector v = _UserLight[ i ].getPosition();
setUniform3f( lp, v.x, v.y, v.z ); setUniform3f( type, lp, v.x, v.y, v.z );
} }
int ldc = currentProgram->getUniformIndex( IProgramObject::EUniform( IProgramObject::Light0ColDiff + i ) ); int ldc = currentProgram->getUniformIndex( IProgram::EUniform( IProgram::Light0ColDiff + i ) );
if( ldc != -1 ) if( ldc != -1 )
{ {
GLfloat glCol[ 4 ]; GLfloat glCol[ 4 ];
@ -455,10 +690,10 @@ namespace NL3D
glCol[ 1 ] = col.G / 255.0f; glCol[ 1 ] = col.G / 255.0f;
glCol[ 2 ] = col.B / 255.0f; glCol[ 2 ] = col.B / 255.0f;
glCol[ 3 ] = col.A / 255.0f; glCol[ 3 ] = col.A / 255.0f;
setUniform4f( ldc, glCol[ 0 ], glCol[ 1 ], glCol[ 2 ], glCol[ 3 ] ); setUniform4f( type, ldc, glCol[ 0 ], glCol[ 1 ], glCol[ 2 ], glCol[ 3 ] );
} }
int lsc = currentProgram->getUniformIndex( IProgramObject::EUniform( IProgramObject::Light0ColSpec + i ) ); int lsc = currentProgram->getUniformIndex( IProgram::EUniform( IProgram::Light0ColSpec + i ) );
if( lsc != -1 ) if( lsc != -1 )
{ {
GLfloat glCol[ 4 ]; GLfloat glCol[ 4 ];
@ -467,16 +702,16 @@ namespace NL3D
glCol[ 1 ] = col.G / 255.0f; glCol[ 1 ] = col.G / 255.0f;
glCol[ 2 ] = col.B / 255.0f; glCol[ 2 ] = col.B / 255.0f;
glCol[ 3 ] = col.A / 255.0f; glCol[ 3 ] = col.A / 255.0f;
setUniform4f( lsc, glCol[ 0 ], glCol[ 1 ], glCol[ 2 ], glCol[ 3 ] ); setUniform4f( type, lsc, glCol[ 0 ], glCol[ 1 ], glCol[ 2 ], glCol[ 3 ] );
} }
int shl = currentProgram->getUniformIndex( IProgramObject::EUniform( IProgramObject::Light0Shininess + i ) ); int shl = currentProgram->getUniformIndex( IProgram::EUniform( IProgram::Light0Shininess + i ) );
if( shl != -1 ) if( shl != -1 )
{ {
setUniform1f( shl, mat.getShininess() ); setUniform1f( type, shl, mat.getShininess() );
} }
int lac = currentProgram->getUniformIndex( IProgramObject::EUniform( IProgramObject::Light0ColAmb + i ) ); int lac = currentProgram->getUniformIndex( IProgram::EUniform( IProgram::Light0ColAmb + i ) );
if( lac != -1 ) if( lac != -1 )
{ {
GLfloat glCol[ 4 ]; GLfloat glCol[ 4 ];
@ -490,25 +725,25 @@ namespace NL3D
glCol[ 1 ] = col.G / 255.0f; glCol[ 1 ] = col.G / 255.0f;
glCol[ 2 ] = col.B / 255.0f; glCol[ 2 ] = col.B / 255.0f;
glCol[ 3 ] = col.A / 255.0f; glCol[ 3 ] = col.A / 255.0f;
setUniform4f( lac, glCol[ 0 ], glCol[ 1 ], glCol[ 2 ], glCol[ 3 ] ); setUniform4f( type, lac, glCol[ 0 ], glCol[ 1 ], glCol[ 2 ], glCol[ 3 ] );
} }
int lca = currentProgram->getUniformIndex( IProgramObject::EUniform( IProgramObject::Light0ConstAttn + i ) ); int lca = currentProgram->getUniformIndex( IProgram::EUniform( IProgram::Light0ConstAttn + i ) );
if( lca != -1 ) if( lca != -1 )
{ {
setUniform1f( lca, _UserLight[ i ].getConstantAttenuation() ); setUniform1f( type, lca, _UserLight[ i ].getConstantAttenuation() );
} }
int lla = currentProgram->getUniformIndex( IProgramObject::EUniform( IProgramObject::Light0LinAttn + i ) ); int lla = currentProgram->getUniformIndex( IProgram::EUniform( IProgram::Light0LinAttn + i ) );
if( lla != -1 ) if( lla != -1 )
{ {
setUniform1f( lla, _UserLight[ i ].getLinearAttenuation() ); setUniform1f( type, lla, _UserLight[ i ].getLinearAttenuation() );
} }
int lqa = currentProgram->getUniformIndex( IProgramObject::EUniform( IProgramObject::Light0QuadAttn + i ) ); int lqa = currentProgram->getUniformIndex( IProgram::EUniform( IProgram::Light0QuadAttn + i ) );
if( lqa != -1 ) if( lqa != -1 )
{ {
setUniform1f( lqa, _UserLight[ i ].getQuadraticAttenuation() ); setUniform1f( type, lqa, _UserLight[ i ].getQuadraticAttenuation() );
} }
} }
@ -519,7 +754,7 @@ namespace NL3D
for( int i = 0; i < IDRV_MAT_MAXTEXTURES; i++ ) for( int i = 0; i < IDRV_MAT_MAXTEXTURES; i++ )
{ {
int cl = currentProgram->getUniformIndex( IProgramObject::EUniform( IProgramObject::Constant0 + i ) ); int cl = currentProgram->getUniformIndex( IProgram::EUniform( IProgram::Constant0 + i ) );
if( cl != -1 ) if( cl != -1 )
{ {
CRGBA col = mat._TexEnvs[ i ].ConstantColor; CRGBA col = mat._TexEnvs[ i ].ConstantColor;
@ -529,14 +764,25 @@ namespace NL3D
glCol[ 2 ] = col.B / 255.0f; glCol[ 2 ] = col.B / 255.0f;
glCol[ 3 ] = col.A / 255.0f; glCol[ 3 ] = col.A / 255.0f;
setUniform4f( cl, glCol[ 0 ], glCol[ 1 ], glCol[ 2 ], glCol[ 3 ] ); setUniform4f( type, cl, glCol[ 0 ], glCol[ 1 ], glCol[ 2 ], glCol[ 3 ] );
} }
} }
} }
} }
bool CDriverGL3::initPipeline()
{
ppoId = 0;
nglGenProgramPipelines( 1, &ppoId );
if( ppoId == 0 )
return false;
nglBindProgramPipeline( ppoId );
return true;
}
} }

@ -28,15 +28,15 @@ namespace NL3D
clearCache(); clearCache();
} }
IProgramObject* CShaderCache::findShader( const CShaderDesc &desc ) const SShaderPair CShaderCache::findShader( const CShaderDesc &desc ) const
{ {
for( int i = 0; i < shaders.size(); i++ ) for( int i = 0; i < shaders.size(); i++ )
{ {
if( shaders[ i ] == desc ) if( shaders[ i ] == desc )
return shaders[ i ].getProgram(); return shaders[ i ].getShaders();
} }
return NULL; return SShaderPair();
} }
void CShaderCache::cacheShader( CShaderDesc &desc ) void CShaderCache::cacheShader( CShaderDesc &desc )
@ -49,8 +49,10 @@ namespace NL3D
std::vector< CShaderDesc >::iterator itr = shaders.begin(); std::vector< CShaderDesc >::iterator itr = shaders.begin();
while( itr != shaders.end() ) while( itr != shaders.end() )
{ {
IProgramObject *p = itr->getProgram(); SShaderPair sp;
delete p; sp = itr->getShaders();
delete sp.vp;
delete sp.pp;
++itr; ++itr;
} }

@ -31,7 +31,7 @@ namespace NL3D
~CShaderCache(); ~CShaderCache();
/// Checks if there's a shader cached that was generated from the specified descriptor /// Checks if there's a shader cached that was generated from the specified descriptor
IProgramObject* findShader( const CShaderDesc &desc ) const; SShaderPair findShader( const CShaderDesc &desc ) const;
/// Caches a shader with the specified descriptor as key /// Caches a shader with the specified descriptor as key
void cacheShader( CShaderDesc &desc ); void cacheShader( CShaderDesc &desc );

@ -24,7 +24,33 @@
namespace NL3D namespace NL3D
{ {
class IProgramObject; class CGLSLVertexProgram;
class CGLSLPixelProgram;
struct SShaderPair
{
SShaderPair()
{
vp = NULL;
pp = NULL;
}
~SShaderPair()
{
vp = NULL;
pp = NULL;
}
bool empty() const{
if( ( vp == NULL ) && ( pp == NULL ) )
return true;
else
return false;
}
CGLSLVertexProgram *vp;
CGLSLPixelProgram *pp;
};
class CShaderDesc class CShaderDesc
{ {
@ -68,7 +94,6 @@ namespace NL3D
features = None; features = None;
shaderType = Normal; shaderType = Normal;
program = NULL;
vbFlags = 0; vbFlags = 0;
nlightmaps = 0; nlightmaps = 0;
alphaTestTreshold = 0.5f; alphaTestTreshold = 0.5f;
@ -128,7 +153,6 @@ namespace NL3D
void setTexEnvMode( uint32 index, uint32 mode ){ texEnvMode[ index ] = mode; } void setTexEnvMode( uint32 index, uint32 mode ){ texEnvMode[ index ] = mode; }
void setVBFlags( uint32 flags ){ vbFlags = flags; } void setVBFlags( uint32 flags ){ vbFlags = flags; }
void setShaderType( uint32 type ){ shaderType = type; } void setShaderType( uint32 type ){ shaderType = type; }
void setProgram( IProgramObject *p ){ program = p; }
void setNLightMaps( uint32 n ){ nlightmaps = n; } void setNLightMaps( uint32 n ){ nlightmaps = n; }
void setAlphaTest( bool b ) void setAlphaTest( bool b )
@ -188,7 +212,8 @@ namespace NL3D
bool hasPointLight() const{ return pointLight; } bool hasPointLight() const{ return pointLight; }
IProgramObject* getProgram() const{ return program; } void setShaders( SShaderPair sp ){ shaderPair = sp; }
SShaderPair getShaders() const{ return shaderPair; }
private: private:
@ -210,7 +235,7 @@ namespace NL3D
TLightMode lightMode[ SHADER_MAX_LIGHTS ]; TLightMode lightMode[ SHADER_MAX_LIGHTS ];
bool pointLight; bool pointLight;
IProgramObject *program; SShaderPair shaderPair;
}; };
} }

@ -0,0 +1,120 @@
// NeL - MMORPG Framework <http://dev.ryzom.com/projects/nel/>
// Copyright (C) 2010 Winch Gate Property Limited
//
// 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/>.
#include "nel/3d/i_program.h"
namespace NL3D
{
const char *IProgram::uniformNames[ NUM_UNIFORMS ] =
{
"mvpMatrix",
"mvMatrix",
"normalMatrix",
"texMatrix0",
"texMatrix1",
"texMatrix2",
"texMatrix3",
"constant0",
"constant1",
"constant2",
"constant3",
"diffuse",
"mcolor",
"sampler0",
"sampler1",
"sampler2",
"sampler3",
"alphaTreshold",
"fogStart",
"fogEnd",
"fogColor",
"fogDensity",
"light0Dir",
"light1Dir",
"light2Dir",
"light3Dir",
"light4Dir",
"light5Dir",
"light6Dir",
"light7Dir",
"light0ColDiff",
"light1ColDiff",
"light2ColDiff",
"light3ColDiff",
"light4ColDiff",
"light5ColDiff",
"light6ColDiff",
"light7ColDiff",
"light0ColAmb",
"light1ColAmb",
"light2ColAmb",
"light3ColAmb",
"light4ColAmb",
"light5ColAmb",
"light6ColAmb",
"light7ColAmb",
"light0ColSpec",
"light1ColSpec",
"light2ColSpec",
"light3ColSpec",
"light4ColSpec",
"light5ColSpec",
"light6ColSpec",
"light7ColSpec",
"light0Shininess",
"light1Shininess",
"light2Shininess",
"light3Shininess",
"light4Shininess",
"light5Shininess",
"light6Shininess",
"light7Shininess",
"light0Pos",
"light1Pos",
"light2Pos",
"light3Pos",
"light4Pos",
"light5Pos",
"light6Pos",
"light7Pos",
"light0ConstAttn",
"light1ConstAttn",
"light2ConstAttn",
"light3ConstAttn",
"light4ConstAttn",
"light5ConstAttn",
"light6ConstAttn",
"light7ConstAttn",
"light0LinAttn",
"light1LinAttn",
"light2LinAttn",
"light3LinAttn",
"light4LinAttn",
"light5LinAttn",
"light6LinAttn",
"light7LinAttn",
"light0QuadAttn",
"light1QuadAttn",
"light2QuadAttn",
"light3QuadAttn",
"light4QuadAttn",
"light5QuadAttn",
"light6QuadAttn",
"light7QuadAttn"
};
}

@ -27,7 +27,6 @@
#include "nel/3d/u_light.h" #include "nel/3d/u_light.h"
#include "nel/3d/u_3d_mouse_listener.h" #include "nel/3d/u_3d_mouse_listener.h"
#include "nel/3d/i_program.h" #include "nel/3d/i_program.h"
#include "nel/3d/i_program_object.h"
#include "nel/misc/i_xml.h" #include "nel/misc/i_xml.h"
#include "nel/misc/o_xml.h" #include "nel/misc/o_xml.h"
#include "nel/misc/file.h" #include "nel/misc/file.h"

Loading…
Cancel
Save