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 ddb188251..cf450cb41 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 @@ -27,6 +27,9 @@ namespace NL3D public: CGLSLPixelProgram(); ~CGLSLPixelProgram(); + + bool isVertexProgram() const{ return false; } + bool isPixelProgram() const{ return true; } }; } 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 36e400b0d..ffe9d9f18 100644 --- a/code/nel/src/3d/driver/OpenGL3/driver_glsl_program.cpp +++ b/code/nel/src/3d/driver/OpenGL3/driver_glsl_program.cpp @@ -39,14 +39,17 @@ namespace NL3D programId = 0; } - bool CGLSLProgram::attachShader( CGLSLShaderBase *shader ) + bool CGLSLProgram::attachVertexProgram( CGLSLShaderBase *shader ) { + if( !shader->isVertexProgram() ) + return false; + if( !shader->isCompiled() ) return false; std::vector< CGLSLShaderBase* >::const_iterator itr = - std::find( attachedShaders.begin(), attachedShaders.end(), shader ); - if( itr != attachedShaders.end() ) + std::find( vertexPrograms.begin(), vertexPrograms.end(), shader ); + if( itr != vertexPrograms.end() ) return false; nglAttachShader( programId, shader->getShaderId() ); @@ -55,14 +58,81 @@ namespace NL3D if( error != 0 ) return false; - attachedShaders.push_back( shader ); + vertexPrograms.push_back( shader ); + + return true; + } + + bool CGLSLProgram::attachPixelProgram( CGLSLShaderBase *shader ) + { + if( !shader->isPixelProgram() ) + return false; + + if( !shader->isCompiled() ) + return false; + + std::vector< CGLSLShaderBase* >::const_iterator itr = + std::find( pixelPrograms.begin(), pixelPrograms.end(), shader ); + if( itr != pixelPrograms.end() ) + return false; + + nglAttachShader( programId, shader->getShaderId() ); + GLenum error = glGetError(); + + if( error != GL_NO_ERROR ) + return false; + + pixelPrograms.push_back( shader ); + + return true; + } + + bool CGLSLProgram::detachVertexProgram( CGLSLShaderBase *shader ) + { + if( !shader->isVertexProgram() ) + return false; + + std::vector< CGLSLShaderBase* >::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( CGLSLShaderBase *shader ) + { + if( !shader->isPixelProgram() ) + return false; + + std::vector< CGLSLShaderBase* >::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( attachedShaders.empty() ) + if( vertexPrograms.empty() || pixelPrograms.empty() ) return false; nglLinkProgram( programId ); @@ -85,8 +155,17 @@ namespace NL3D void CGLSLProgram::deleteShaders() { - std::vector< CGLSLShaderBase* >::iterator itr = attachedShaders.begin(); - while( itr != attachedShaders.end() ) + std::vector< CGLSLShaderBase* >::iterator itr; + + itr = vertexPrograms.begin(); + while( itr != vertexPrograms.end() ) + { + delete *itr; + ++itr; + } + + itr = pixelPrograms.begin(); + while( itr != pixelPrograms.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 d066ab040..502da5a9b 100644 --- a/code/nel/src/3d/driver/OpenGL3/driver_glsl_program.h +++ b/code/nel/src/3d/driver/OpenGL3/driver_glsl_program.h @@ -32,7 +32,12 @@ namespace NL3D CGLSLProgram(); ~CGLSLProgram(); - bool attachShader( CGLSLShaderBase *shader ); + bool attachVertexProgram( CGLSLShaderBase *shader ); + bool attachPixelProgram( CGLSLShaderBase *shader ); + + bool detachVertexProgram( CGLSLShaderBase *shader ); + bool detachPixelProgram( CGLSLShaderBase *shader ); + bool link( std::string &log ); unsigned int getProgramId() const{ return programId; } @@ -44,7 +49,8 @@ namespace NL3D unsigned int programId; bool linked; - std::vector< CGLSLShaderBase* > attachedShaders; + std::vector< CGLSLShaderBase* > vertexPrograms; + std::vector< CGLSLShaderBase* > pixelPrograms; }; } 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 index 96d946935..777cf0047 100644 --- a/code/nel/src/3d/driver/OpenGL3/driver_glsl_shader_base.h +++ b/code/nel/src/3d/driver/OpenGL3/driver_glsl_shader_base.h @@ -34,6 +34,9 @@ namespace NL3D void shaderSource( const char *source ); bool compile( std::string &log ); + virtual bool isVertexProgram() const = 0; + virtual bool isPixelProgram() const = 0; + unsigned int getShaderId() const{ return shaderId; } bool isCompiled() const{ return compiled; } 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 108f03b77..3e953578c 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 @@ -28,6 +28,10 @@ namespace NL3D public: CGLSLVertexProgram(); ~CGLSLVertexProgram(); + + bool isVertexProgram() const{ return true; } + bool isPixelProgram() const{ return false; } + }; } diff --git a/code/nel/src/3d/driver/OpenGL3/driver_opengl_program.cpp b/code/nel/src/3d/driver/OpenGL3/driver_opengl_program.cpp index 3c3b1cee5..3c8c6bf37 100644 --- a/code/nel/src/3d/driver/OpenGL3/driver_opengl_program.cpp +++ b/code/nel/src/3d/driver/OpenGL3/driver_opengl_program.cpp @@ -35,60 +35,60 @@ namespace NL3D } - - const char *vs = - "#version 330\n" - "in vec4 vertex;\n" - "void main( void )\n" - "{\n" - "gl_Position = vertex;\n" - "}\n"; - - const char *fs = - "#version 330\n" - "out vec4 color;\n" - "void main( void )\n" - "{\n" - "color = vec4( 1.0, 0.0, 0.0, 1.0 );\n" - "}\n"; - - bool CDriverGL3::renderRawTriangles2( CMaterial &mat, uint32 startIndex, uint32 numTris ) - { - std::string log; - - CGLSLProgram program; - CGLSLVertexProgram *vp = new CGLSLVertexProgram(); - CGLSLPixelProgram *pp = new CGLSLPixelProgram(); - - vp->shaderSource( vs ); - if( !vp->compile( log ) ) - { - nlinfo( "%s", log.c_str() ); - return false; - } - - pp->shaderSource( fs ); - if( !pp->compile( log ) ) - { - nlinfo( "%s", log.c_str() ); - return false; - } - - if( !program.attachShader( vp ) ) - return false; - - if( !program.attachShader( pp ) ) - return false; - - if( !program.link( log ) ) - { - nlinfo( "%s", log.c_str() ); - return false; - } - - if( !activeGLSLProgram( &program ) ) - return false; - + + const char *vs = + "#version 330\n" + "in vec4 vertex;\n" + "void main( void )\n" + "{\n" + "gl_Position = vertex;\n" + "}\n"; + + const char *fs = + "#version 330\n" + "out vec4 color;\n" + "void main( void )\n" + "{\n" + "color = vec4( 1.0, 0.0, 0.0, 1.0 );\n" + "}\n"; + + bool CDriverGL3::renderRawTriangles2( CMaterial &mat, uint32 startIndex, uint32 numTris ) + { + std::string log; + + CGLSLProgram program; + CGLSLVertexProgram *vp = new CGLSLVertexProgram(); + CGLSLPixelProgram *pp = new CGLSLPixelProgram(); + + vp->shaderSource( vs ); + if( !vp->compile( log ) ) + { + nlinfo( "%s", log.c_str() ); + return false; + } + + pp->shaderSource( fs ); + if( !pp->compile( log ) ) + { + nlinfo( "%s", log.c_str() ); + return false; + } + + if( !program.attachVertexProgram( vp ) ) + return false; + + if( !program.attachPixelProgram( pp ) ) + return false; + + if( !program.link( log ) ) + { + nlinfo( "%s", log.c_str() ); + return false; + } + + if( !activeGLSLProgram( &program ) ) + return false; + glDrawArrays( GL_TRIANGLES, startIndex * 3, numTris * 3 ); activeGLSLProgram( NULL );