From b3ea9ee787f611405ace47e82ceffee9350c222b Mon Sep 17 00:00:00 2001 From: dfighter1985 Date: Thu, 8 Aug 2013 20:25:26 +0200 Subject: [PATCH] Implemented shader and program object classes. --HG-- branch : gsoc2013-dfighter --- .../OpenGL3/driver_glsl_pixel_program.h | 8 +-- .../3d/driver/OpenGL3/driver_glsl_program.cpp | 59 +++++++++++++++++ .../3d/driver/OpenGL3/driver_glsl_program.h | 15 +++++ .../OpenGL3/driver_glsl_shader_base.cpp | 64 +++++++++++++++++++ .../driver/OpenGL3/driver_glsl_shader_base.h | 51 +++++++++++++++ .../OpenGL3/driver_glsl_vertex_program.cpp | 3 +- .../OpenGL3/driver_glsl_vertex_program.h | 9 ++- .../nel/src/3d/driver/OpenGL3/driver_opengl.h | 2 + .../driver/OpenGL3/driver_opengl_program.cpp | 36 +++++++++++ 9 files changed, 236 insertions(+), 11 deletions(-) create mode 100644 code/nel/src/3d/driver/OpenGL3/driver_glsl_shader_base.cpp create mode 100644 code/nel/src/3d/driver/OpenGL3/driver_glsl_shader_base.h create mode 100644 code/nel/src/3d/driver/OpenGL3/driver_opengl_program.cpp diff --git a/code/nel/src/3d/driver/OpenGL3/driver_glsl_pixel_program.h b/code/nel/src/3d/driver/OpenGL3/driver_glsl_pixel_program.h index 3c38047e9..ddb188251 100644 --- a/code/nel/src/3d/driver/OpenGL3/driver_glsl_pixel_program.h +++ b/code/nel/src/3d/driver/OpenGL3/driver_glsl_pixel_program.h @@ -18,17 +18,15 @@ #ifndef GLSL_PIXEL_PROGRAM_H #define GLSL_PIXEL_PROGRAM_H +#include "driver_glsl_shader_base.h" + namespace NL3D { - class CGLSLPixelProgram + class CGLSLPixelProgram : public CGLSLShaderBase { public: CGLSLPixelProgram(); ~CGLSLPixelProgram(); - unsigned int getShaderId() const{ return shaderId; } - - private: - unsigned int shaderId; }; } diff --git a/code/nel/src/3d/driver/OpenGL3/driver_glsl_program.cpp b/code/nel/src/3d/driver/OpenGL3/driver_glsl_program.cpp index 9b6b0f840..36e400b0d 100644 --- a/code/nel/src/3d/driver/OpenGL3/driver_glsl_program.cpp +++ b/code/nel/src/3d/driver/OpenGL3/driver_glsl_program.cpp @@ -16,23 +16,82 @@ #include "driver_glsl_program.h" +#include "driver_glsl_shader_base.h" #include "stdopengl.h" #include "driver_opengl_extension.h" +#define MAX_PROGRAM_LINK_ERROR_LOG 1024 + namespace NL3D { CGLSLProgram::CGLSLProgram() { programId = nglCreateProgram(); nlassert( programId != 0 ); + linked = false; } CGLSLProgram::~CGLSLProgram() { nglDeleteProgram( programId ); + deleteShaders(); programId = 0; } + + bool CGLSLProgram::attachShader( CGLSLShaderBase *shader ) + { + if( !shader->isCompiled() ) + return false; + + std::vector< CGLSLShaderBase* >::const_iterator itr = + std::find( attachedShaders.begin(), attachedShaders.end(), shader ); + if( itr != attachedShaders.end() ) + return false; + + nglAttachShader( programId, shader->getShaderId() ); + GLenum error = glGetError(); + + if( error != 0 ) + return false; + + attachedShaders.push_back( shader ); + + return true; + } + + bool CGLSLProgram::link( std::string &log ) + { + if( attachedShaders.empty() ) + return false; + + nglLinkProgram( programId ); + + GLint ok; + nglGetProgramiv( programId, GL_LINK_STATUS, &ok ); + if( ok == 0 ) + { + char errorLog[ MAX_PROGRAM_LINK_ERROR_LOG ]; + nglGetProgramInfoLog( programId, MAX_PROGRAM_LINK_ERROR_LOG, NULL, errorLog ); + log.assign( errorLog ); + return false; + } + + linked = true; + + return true; + } + + + void CGLSLProgram::deleteShaders() + { + std::vector< CGLSLShaderBase* >::iterator itr = attachedShaders.begin(); + while( itr != attachedShaders.end() ) + { + delete *itr; + ++itr; + } + } } diff --git a/code/nel/src/3d/driver/OpenGL3/driver_glsl_program.h b/code/nel/src/3d/driver/OpenGL3/driver_glsl_program.h index b98928e86..d066ab040 100644 --- a/code/nel/src/3d/driver/OpenGL3/driver_glsl_program.h +++ b/code/nel/src/3d/driver/OpenGL3/driver_glsl_program.h @@ -18,18 +18,33 @@ #ifndef GLSL_PROGRAM_H #define GLSL_PROGRAM_H +#include +#include + namespace NL3D { + class CGLSLShaderBase; + + /// Wrapper class for OpenGL shader program object class CGLSLProgram { public: CGLSLProgram(); ~CGLSLProgram(); + bool attachShader( CGLSLShaderBase *shader ); + bool link( std::string &log ); + unsigned int getProgramId() const{ return programId; } + bool isLinked() const{ return linked; } private: + void deleteShaders(); + unsigned int programId; + bool linked; + + std::vector< CGLSLShaderBase* > attachedShaders; }; } diff --git a/code/nel/src/3d/driver/OpenGL3/driver_glsl_shader_base.cpp b/code/nel/src/3d/driver/OpenGL3/driver_glsl_shader_base.cpp new file mode 100644 index 000000000..daaf9a3d7 --- /dev/null +++ b/code/nel/src/3d/driver/OpenGL3/driver_glsl_shader_base.cpp @@ -0,0 +1,64 @@ +// NeL - MMORPG Framework +// 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 . + + +#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 != 0 ) + { + char infoLog[ MAX_SHADER_COMPILE_INFOLOG ]; + nglGetShaderInfoLog( shaderId, MAX_SHADER_COMPILE_INFOLOG, NULL, infoLog ); + log.assign( infoLog ); + return false; + } + + compiled = true; + + return true; + } + +} + + + + diff --git a/code/nel/src/3d/driver/OpenGL3/driver_glsl_shader_base.h b/code/nel/src/3d/driver/OpenGL3/driver_glsl_shader_base.h new file mode 100644 index 000000000..96d946935 --- /dev/null +++ b/code/nel/src/3d/driver/OpenGL3/driver_glsl_shader_base.h @@ -0,0 +1,51 @@ +// NeL - MMORPG Framework +// 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 . + + +#ifndef GLSL_SHADER_BASE_H +#define GLSL_SHADER_BASE_H + +namespace NL3D +{ + /// Base class for OpenGL shader objects + class CGLSLShaderBase + { + public: + CGLSLShaderBase(){ + shaderId = 0; + compiled = false; + } + + virtual ~CGLSLShaderBase(){} + + void shaderSource( const char *source ); + bool compile( std::string &log ); + + unsigned int getShaderId() const{ return shaderId; } + bool isCompiled() const{ return compiled; } + + protected: + unsigned int shaderId; + + private: + bool compiled; + }; +} + + +#endif + + diff --git a/code/nel/src/3d/driver/OpenGL3/driver_glsl_vertex_program.cpp b/code/nel/src/3d/driver/OpenGL3/driver_glsl_vertex_program.cpp index 174476407..1f871593b 100644 --- a/code/nel/src/3d/driver/OpenGL3/driver_glsl_vertex_program.cpp +++ b/code/nel/src/3d/driver/OpenGL3/driver_glsl_vertex_program.cpp @@ -21,7 +21,8 @@ namespace NL3D { - CGLSLVertexProgram::CGLSLVertexProgram() + CGLSLVertexProgram::CGLSLVertexProgram() : + CGLSLShaderBase() { shaderId = nglCreateShader( GL_VERTEX_SHADER ); nlassert( shaderId != 0 ); diff --git a/code/nel/src/3d/driver/OpenGL3/driver_glsl_vertex_program.h b/code/nel/src/3d/driver/OpenGL3/driver_glsl_vertex_program.h index e633558c9..108f03b77 100644 --- a/code/nel/src/3d/driver/OpenGL3/driver_glsl_vertex_program.h +++ b/code/nel/src/3d/driver/OpenGL3/driver_glsl_vertex_program.h @@ -18,17 +18,16 @@ #ifndef GLSL_VERTEX_PROGRAM_H #define GLSL_VERTEX_PROGRAM_H +#include "driver_glsl_shader_base.h" +#include + namespace NL3D { - class CGLSLVertexProgram + class CGLSLVertexProgram : public CGLSLShaderBase { public: CGLSLVertexProgram(); ~CGLSLVertexProgram(); - unsigned int getShaderId() const{ return shaderId; } - - private: - unsigned int shaderId; }; } diff --git a/code/nel/src/3d/driver/OpenGL3/driver_opengl.h b/code/nel/src/3d/driver/OpenGL3/driver_opengl.h index 3b977f874..cb4c3e852 100644 --- a/code/nel/src/3d/driver/OpenGL3/driver_opengl.h +++ b/code/nel/src/3d/driver/OpenGL3/driver_opengl.h @@ -102,6 +102,7 @@ class CDriverGL3; class IVertexArrayRange; class IVertexBufferHardGL; class COcclusionQueryGL3; +class CGLSLProgram; void displayGLError(GLenum error); @@ -1275,6 +1276,7 @@ private: /// \name Vertex program implementation // @{ bool activeARBVertexProgram (CVertexProgram *program); + bool activeGLSLProgram( CGLSLProgram *program ); //@} diff --git a/code/nel/src/3d/driver/OpenGL3/driver_opengl_program.cpp b/code/nel/src/3d/driver/OpenGL3/driver_opengl_program.cpp new file mode 100644 index 000000000..ec3da6c8d --- /dev/null +++ b/code/nel/src/3d/driver/OpenGL3/driver_opengl_program.cpp @@ -0,0 +1,36 @@ +#include "driver_opengl.h" +#include "driver_glsl_program.h" + +namespace NL3D +{ + bool CDriverGL3::activeGLSLProgram( CGLSLProgram *program ) + { + if( !program ) + { + _VertexProgramEnabled = false; + return true; + } + + if( program->isLinked() ) + return false; + + nglValidateProgram( program->getProgramId() ); + + GLint ok; + nglGetProgramiv( program->getProgramId(), GL_VALIDATE_STATUS, &ok ); + if( ok != GL_TRUE ) + return false; + + nglUseProgram( program->getProgramId() ); + + GLenum error = glGetError(); + if( error != GL_NO_ERROR ) + return false; + + _VertexProgramEnabled = true; + + return true; + } +} + +