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
virtual IProgram* createPixelProgram() const { return NULL; }
/// Returns the location of the specified uniform, or -1 if it's not found
virtual int getUniformLocation( const char *name ){ return -1; }
/// 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( uint32 programType, const char *name ){ return -1; }
/// 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 )
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
virtual void setUniform1i( uint index, int i ){}
virtual void setUniform1i( uint32 programType, uint index, int i ){}
/// 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
virtual void setUniform1u( uint index, uint u ){}
virtual void setUniform1u( uint32 programType, uint index, uint u ){}
/// 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 )
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 )
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 )
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.

@ -26,55 +26,131 @@ namespace NL3D
class IProgram
{
public:
enum EProgramType
enum TProgramType
{
INVALID_PROGRAM,
VERTEX_PROGRAM,
PIXEL_PROGRAM,
GEOMETRY_PROGRAM,
UNKNOWN_PROGRAM
GEOMETRY_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(){
shaderId = 0;
compiled = false;
type = UNKNOWN_PROGRAM;
type = INVALID_PROGRAM;
}
virtual ~IProgram(){}
virtual void shaderSource( const char *source ) = 0;
virtual bool compile( std::string &log ) = 0;
unsigned int getShaderId() const{ return shaderId; }
void setSource( const char *source ){ src.assign( source ); }
const std::string& getSource() const{ return src; }
bool isCompiled() const{ return compiled; }
virtual void cacheUniforms() = 0;
virtual int getUniformIndex( uint32 id ) const = 0;
bool isVertexProgram() const{
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;
}
TProgramType getType() const{ return type; }
protected:
unsigned int shaderId;
bool compiled;
EProgramType type;
std::string src;
static const char *uniformNames[ NUM_UNIFORMS ];
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
{
CGLSLPixelProgram::CGLSLPixelProgram()
CGLSLPixelProgram::CGLSLPixelProgram() :
CGLSLProgram()
{
type = PIXEL_PROGRAM;
shaderId = nglCreateShader( GL_FRAGMENT_SHADER );
nlassert( shaderId != 0 );
}
CGLSLPixelProgram::~CGLSLPixelProgram()
{
nglDeleteShader( shaderId );
if( programId != 0 )
nglDeleteProgram( programId );
}
}

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

@ -16,296 +16,32 @@
#include "driver_glsl_program.h"
#include "nel/3d/i_program_object.h"
#include "driver_glsl_shader_base.h"
#include "stdopengl.h"
#include <algorithm>
#include "driver_opengl_extension.h"
#define MAX_PROGRAM_LOG 1024
namespace NL3D
{
CGLSLProgram::CGLSLProgram() :
IProgramObject()
IProgram()
{
programId = nglCreateProgram();
nlassert( programId != 0 );
linked = false;
std::fill( uniformIndices, uniformIndices + NUM_UNIFORMS, -1 );
}
CGLSLProgram::~CGLSLProgram()
{
nglDeleteProgram( programId );
deleteShaders();
programId = 0;
}
bool CGLSLProgram::attachVertexProgram( IProgram *shader )
{
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 )
CGLSLProgram::~CGLSLProgram()
{
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 ] =
{
"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()
void CGLSLProgram::cacheUniforms()
{
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 ] );
}
}
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
#define GLSL_PROGRAM_H
#include <vector>
#include <string>
#include "nel/3d/i_program_object.h"
#include "nel/3d/i_program.h"
namespace NL3D
{
/// Wrapper class for OpenGL shader program object
class CGLSLProgram : public IProgramObject
class CGLSLProgram : public IProgram
{
public:
CGLSLProgram();
~CGLSLProgram();
bool attachVertexProgram( IProgram *shader );
bool attachPixelProgram( IProgram *shader );
unsigned int getProgramId() const{ return programId; }
void setProgramId( unsigned int Id ){ programId = Id; }
bool detachVertexProgram( IProgram *shader );
bool detachPixelProgram( IProgram *shader );
bool link( std::string &log );
bool validate( std::string &log );
void cacheUniformIndices();
int getUniformIndex( EUniform uniform );
private:
void deleteShaders();
void cacheUniforms();
int getUniformIndex( uint32 id ) const{ return uniformIndices[ id ]; }
protected:
unsigned int programId;
int uniformIndices[ NUM_UNIFORMS ];
std::vector< IProgram* > vertexPrograms;
std::vector< IProgram* > pixelPrograms;
};
}
#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 << "#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 << std::endl;

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

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

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

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

@ -20,8 +20,9 @@
#include "nel/3d/texture_mem.h"
#include "nel/3d/texture_bump.h"
#include "nel/3d/material.h"
#include "nel/3d/i_program_object.h"
#include "nel/3d/dynamic_material.h"
#include "driver_glsl_vertex_program.h"
#include "driver_glsl_pixel_program.h"
namespace NL3D {
@ -603,78 +604,92 @@ bool CDriverGL3::setupDynMatPass( uint pass )
CDynMaterial *m = _CurrentMaterial->getDynMat();
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 );
int loc = nglGetUniformLocation( currentProgram->getProgramId(), prop->prop.c_str() );
if( loc == -1 )
continue;
currentProgram = programs[ j ];
type = currentProgram->getType();
switch( prop->type )
for( uint32 i = 0; i < p->count(); i++ )
{
case SDynMaterialProp::Float:
setUniform1f( loc, prop->value.toFloat() );
break;
const SDynMaterialProp *prop = p->getProperty( i );
int loc = nglGetUniformLocation( currentProgram->getProgramId(), prop->prop.c_str() );
if( loc == -1 )
continue;
case SDynMaterialProp::Int:
setUniform1i( loc, prop->value.toInt() );
break;
switch( prop->type )
{
case SDynMaterialProp::Float:
setUniform1f( type, loc, prop->value.toFloat() );
break;
case SDynMaterialProp::Uint:
setUniform1u( loc, prop->value.toUInt() );
break;
case SDynMaterialProp::Int:
setUniform1i( type, loc, prop->value.toInt() );
break;
case SDynMaterialProp::Color:
{
float v[ 4 ];
prop->value.getVector4( v );
case SDynMaterialProp::Uint:
setUniform1u( type, loc, prop->value.toUInt() );
break;
case SDynMaterialProp::Color:
{
float v[ 4 ];
prop->value.getVector4( v );
for( int j = 0; j < 4; j++ )
v[ j ] = v[ j ] / 255.0f;
for( int j = 0; j < 4; j++ )
v[ j ] = v[ j ] / 255.0f;
setUniform4f( loc, v[ 0 ], v[ 1 ], v[ 2 ], v[ 3 ] );
}
break;
setUniform4f( type, loc, v[ 0 ], v[ 1 ], v[ 2 ], v[ 3 ] );
}
break;
case SDynMaterialProp::Vector4:
{
float v[ 4 ];
prop->value.getVector4( v );
setUniform4f( loc, v[ 0 ], v[ 1 ], v[ 2 ], v[ 3 ] );
}
break;
case SDynMaterialProp::Vector4:
{
float v[ 4 ];
prop->value.getVector4( v );
setUniform4f( type, loc, v[ 0 ], v[ 1 ], v[ 2 ], v[ 3 ] );
}
break;
case SDynMaterialProp::Matrix4:
{
float m[ 16 ];
prop->value.getMatrix4( m );
setUniformMatrix4fv( loc, 1, false, m );
case SDynMaterialProp::Matrix4:
{
float m[ 16 ];
prop->value.getMatrix4( m );
setUniformMatrix4fv( type, loc, 1, false, m );
break;
}
case SDynMaterialProp::Texture:
break;
}
}
////////////////////////////////// Set up some standard uniforms //////////////////////////////////
case SDynMaterialProp::Texture:
break;
int loc = -1;
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;
}
@ -685,12 +700,12 @@ void CDriverGL3::setupNormalPass()
for( int i = 0; i < IDRV_MAT_MAXTEXTURES; i++ )
{
// Set constant
int cl = currentProgram->getUniformIndex( IProgramObject::EUniform( IProgramObject::Constant0 + i ) );
int cl = pixelProgram->getUniformIndex( IProgram::EUniform( IProgram::Constant0 + i ) );
if( cl != -1 )
{
GLfloat glCol[ 4 ];
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
@ -698,11 +713,11 @@ void CDriverGL3::setupNormalPass()
if( t == NULL )
continue;
int index = currentProgram->getUniformIndex( IProgramObject::EUniform( IProgramObject::Sampler0 + i ) );
int index = pixelProgram->getUniformIndex( IProgram::EUniform( IProgram::Sampler0 + i ) );
if( index == -1 )
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.
stdEnv.ConstantColor=lmapFactor;
int cl = currentProgram->getUniformIndex( IProgramObject::EUniform( IProgramObject::Constant0 + stage ) );
int cl = pixelProgram->getUniformIndex( IProgram::EUniform( IProgram::Constant0 + stage ) );
if( cl != -1 )
{
GLfloat glCol[ 4 ];
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 )
{
setUniform1i( tl, stage );
setUniform1i( IProgram::PIXEL_PROGRAM, tl, stage );
}
activateTexEnvColor(stage, stdEnv);
@ -928,10 +943,10 @@ void CDriverGL3::setupLightMapPass(uint pass)
_DriverGLStates.activeTextureARB(stage);
_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 )
{
setUniform1i( tl, stage );
setUniform1i( IProgram::PIXEL_PROGRAM, tl, stage );
}
}
@ -1124,22 +1139,22 @@ void CDriverGL3::setupSpecularPass(uint pass)
return;
}
int sl0 = currentProgram->getUniformIndex( IProgramObject::Sampler0 );
int sl0 = pixelProgram->getUniformIndex( IProgram::Sampler0 );
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 )
{
setUniform1i( sl1, 1 );
setUniform1i( IProgram::PIXEL_PROGRAM, sl1, 1 );
}
int tml = currentProgram->getUniformIndex( IProgramObject::TexMatrix0 );
int tml = pixelProgram->getUniformIndex( IProgram::TexMatrix0 );
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
// along with this program. If not, see <http://www.gnu.org/licenses/>.
#include "driver_opengl.h"
#include "driver_glsl_program.h"
#include "driver_glsl_vertex_program.h"
#include "driver_glsl_pixel_program.h"
#include "driver_glsl_shader_generator.h"
#include "driver_opengl_vertex_buffer_hard.h"
#include "nel/3d/i_program_object.h"
#include "nel/3d/dynamic_material.h"
#include "nel/3d/usr_shader_manager.h"
#include "nel/3d/usr_shader_program.h"
@ -40,32 +38,109 @@ namespace
namespace NL3D
{
bool CDriverGL3::activeProgramObject( IProgramObject *program )
bool CDriverGL3::compileVertexProgram( CGLSLVertexProgram *program )
{
if( !program )
{
currentProgram = NULL;
// Already compiled
if( program->getProgramId() != 0 )
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;
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();
if( error != GL_NO_ERROR )
{
return false;
}
currentProgram = program;
vertexProgram = program;
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
@ -78,70 +153,213 @@ namespace NL3D
return new CGLSLPixelProgram();
}
int CDriverGL3::getUniformLocation( const char *name )
int CDriverGL3::getUniformLocation( uint32 programType, const char *name )
{
if( currentProgram == NULL )
return -1;
switch( programType )
{
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 );
}
void CDriverGL3::setUniform3f( uint index, float f1, float f2, float f3 )
{
nglUniform3f( index, f1, f2, f3 );
switch( programType )
{
case IProgram::VERTEX_PROGRAM:
nlassert( vertexProgram != NULL );
nglProgramUniform1f( vertexProgram->getProgramId(), index, f );
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 );
return true;
switch( programType )
{
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 )
@ -210,19 +428,22 @@ namespace NL3D
if( mat.getDynMat() != NULL )
return true;
IProgram *vp = NULL;
IProgram *pp = NULL;
IProgramObject *p = NULL;
CGLSLVertexProgram *vp = NULL;
CGLSLPixelProgram *pp = NULL;
SShaderPair sp;
CShaderDesc desc;
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;
}
else
@ -237,52 +458,53 @@ namespace NL3D
shaderGenerator->generateVS( vs );
shaderGenerator->generatePS( ps );
vp = createVertexProgram();
std::string log;
vp->shaderSource( vs.c_str() );
if( !vp->compile( log ) )
vp = new CGLSLVertexProgram();
vp->setSource( vs.c_str() );
if( !compileVertexProgram( vp ) )
{
delete vp;
vp = NULL;
nlinfo( "%s", log.c_str() );
return false;
}
pp = createPixelProgram();
pp->shaderSource( ps.c_str() );
if( !pp->compile( log ) )
pp = new CGLSLPixelProgram();
pp->setSource( ps.c_str() );
if( !compilePixelProgram( pp ) )
{
delete vp;
vp = NULL;
delete pp;
pp = NULL;
nlinfo( "%s", log.c_str() );
return false;
}
p = createProgramObject();
p->attachVertexProgram( vp );
p->attachPixelProgram( pp );
if( !p->link( log ) )
if( !activeVertexProgram( vp ) )
{
delete vp;
vp = NULL;
delete pp;
pp = NULL;
delete p;
p = NULL;
nlinfo( "%s", log.c_str() );
return false;
}
if( !activeProgramObject( p ) )
if( !activePixelProgram( pp ) )
{
delete vp;
vp = NULL;
delete pp;
pp = NULL;
return false;
}
p->cacheUniformIndices();
desc.setProgram( p );
vp->cacheUniforms();
pp->cacheUniforms();
sp.vp = vp;
sp.pp = pp;
desc.setShaders( sp );
shaderCache.cacheShader( desc );
}
setupUniforms( mat );
setupUniforms();
return true;
}
@ -299,90 +521,103 @@ namespace NL3D
if( !usrShaderManager->getShader( shaderRef, &prg ) )
return false;
IProgramObject *p = createProgramObject();
IProgram *vp = createVertexProgram();
IProgram *pp = createPixelProgram();
CGLSLVertexProgram *vp = new CGLSLVertexProgram();
CGLSLPixelProgram *pp = new CGLSLPixelProgram();
std::string shaderSource;
std::string log;
prg.getVP( shaderSource );
vp->shaderSource( shaderSource.c_str() );
if( !vp->compile( log ) )
vp->setSource( shaderSource.c_str() );
if( !compileVertexProgram( vp ) )
{
delete vp;
delete pp;
delete p;
return false;
}
prg.getFP( shaderSource );
pp->shaderSource( shaderSource.c_str() );
if( !pp->compile( log ) )
pp->setSource( shaderSource.c_str() );
if( !compilePixelProgram( pp ) )
{
delete vp;
delete pp;
delete p;
return false;
}
p->attachVertexProgram( vp );
p->attachPixelProgram( pp );
if( !p->link( log ) )
if( !activeVertexProgram( vp ) )
{
delete p;
delete vp;
delete pp;
return false;
}
if( !activeProgramObject( p ) )
if( !activePixelProgram( pp ) )
{
delete p;
delete vp;
delete pp;
return false;
}
if( dynMatProgram != NULL )
delete dynMatProgram;
dynMatProgram = p;
if( dynMatVP != NULL )
delete dynMatVP;
dynMatVP = vp;
if( dynMatPP != NULL )
delete dynMatPP;
dynMatPP = pp;
vp->cacheUniforms();
pp->cacheUniforms();
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 )
{
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 )
{
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 )
{
}
*/
int fogStartIdx = currentProgram->getUniformIndex( IProgramObject::FogStart );
int fogStartIdx = currentProgram->getUniformIndex( IProgram::FogStart );
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 )
{
setUniform1f( fogEndIdx, getFogEnd() );
setUniform1f( type, fogEndIdx, getFogEnd() );
}
int fogColorIdx = currentProgram->getUniformIndex( IProgramObject::FogColor );
int fogColorIdx = currentProgram->getUniformIndex( IProgram::FogColor );
if( fogColorIdx != -1 )
{
GLfloat glCol[ 4 ];
@ -391,10 +626,10 @@ namespace NL3D
glCol[ 1 ] = col.G / 255.0f;
glCol[ 2 ] = col.B / 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 )
{
GLfloat glCol[ 4 ];
@ -404,10 +639,10 @@ namespace NL3D
glCol[ 2 ] = col.B / 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 )
{
GLfloat glCol[ 4 ];
@ -417,7 +652,7 @@ namespace NL3D
glCol[ 2 ] = col.B / 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;
////////////////// Temporary insanity ///////////////////////////////
if( _LightMode[ i ] != CLight::DirectionalLight && _LightMode[ i ] != CLight::PointLight )
if( ( _LightMode[ i ] != CLight::DirectionalLight ) && ( _LightMode[ i ] != CLight::PointLight ) )
continue;
//////////////////////////////////////////////////////////////////////
int ld = currentProgram->getUniformIndex( IProgramObject::EUniform( IProgramObject::Light0Dir + i ) );
int ld = currentProgram->getUniformIndex( IProgram::EUniform( IProgram::Light0Dir + i ) );
if( ld != -1 )
{
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 )
{
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 )
{
GLfloat glCol[ 4 ];
@ -455,10 +690,10 @@ namespace NL3D
glCol[ 1 ] = col.G / 255.0f;
glCol[ 2 ] = col.B / 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 )
{
GLfloat glCol[ 4 ];
@ -467,16 +702,16 @@ namespace NL3D
glCol[ 1 ] = col.G / 255.0f;
glCol[ 2 ] = col.B / 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 )
{
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 )
{
GLfloat glCol[ 4 ];
@ -490,25 +725,25 @@ namespace NL3D
glCol[ 1 ] = col.G / 255.0f;
glCol[ 2 ] = col.B / 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 )
{
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 )
{
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 )
{
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++ )
{
int cl = currentProgram->getUniformIndex( IProgramObject::EUniform( IProgramObject::Constant0 + i ) );
int cl = currentProgram->getUniformIndex( IProgram::EUniform( IProgram::Constant0 + i ) );
if( cl != -1 )
{
CRGBA col = mat._TexEnvs[ i ].ConstantColor;
@ -529,14 +764,25 @@ namespace NL3D
glCol[ 2 ] = col.B / 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();
}
IProgramObject* CShaderCache::findShader( const CShaderDesc &desc ) const
SShaderPair CShaderCache::findShader( const CShaderDesc &desc ) const
{
for( int i = 0; i < shaders.size(); i++ )
{
if( shaders[ i ] == desc )
return shaders[ i ].getProgram();
return shaders[ i ].getShaders();
}
return NULL;
return SShaderPair();
}
void CShaderCache::cacheShader( CShaderDesc &desc )
@ -49,8 +49,10 @@ namespace NL3D
std::vector< CShaderDesc >::iterator itr = shaders.begin();
while( itr != shaders.end() )
{
IProgramObject *p = itr->getProgram();
delete p;
SShaderPair sp;
sp = itr->getShaders();
delete sp.vp;
delete sp.pp;
++itr;
}

@ -31,7 +31,7 @@ namespace NL3D
~CShaderCache();
/// 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
void cacheShader( CShaderDesc &desc );

@ -24,7 +24,33 @@
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
{
@ -68,7 +94,6 @@ namespace NL3D
features = None;
shaderType = Normal;
program = NULL;
vbFlags = 0;
nlightmaps = 0;
alphaTestTreshold = 0.5f;
@ -128,7 +153,6 @@ namespace NL3D
void setTexEnvMode( uint32 index, uint32 mode ){ texEnvMode[ index ] = mode; }
void setVBFlags( uint32 flags ){ vbFlags = flags; }
void setShaderType( uint32 type ){ shaderType = type; }
void setProgram( IProgramObject *p ){ program = p; }
void setNLightMaps( uint32 n ){ nlightmaps = n; }
void setAlphaTest( bool b )
@ -188,7 +212,8 @@ namespace NL3D
bool hasPointLight() const{ return pointLight; }
IProgramObject* getProgram() const{ return program; }
void setShaders( SShaderPair sp ){ shaderPair = sp; }
SShaderPair getShaders() const{ return shaderPair; }
private:
@ -210,7 +235,7 @@ namespace NL3D
TLightMode lightMode[ SHADER_MAX_LIGHTS ];
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_3d_mouse_listener.h"
#include "nel/3d/i_program.h"
#include "nel/3d/i_program_object.h"
#include "nel/misc/i_xml.h"
#include "nel/misc/o_xml.h"
#include "nel/misc/file.h"

Loading…
Cancel
Save