From d7747685b3841442f1c60570f12e4bbb0bfd3a0a Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Tue, 23 Nov 2010 14:50:31 +0000 Subject: [PATCH] From Holger Helmich, Tessellation shader support --- include/osg/GL2Extensions | 52 +++++++++++++++++++++++++++++++++++ include/osg/PrimitiveSet | 3 +- include/osg/Program | 14 ++++++++++ include/osg/Shader | 6 +++- src/osg/GL2Extensions.cpp | 33 ++++++++++++++++++++++ src/osg/PrimitiveSet.cpp | 2 ++ src/osg/Program.cpp | 56 +++++++++++++++++++++++++++++++++++--- src/osg/Shader.cpp | 10 +++++-- src/osg/ShaderComposer.cpp | 13 +++++++++ 9 files changed, 181 insertions(+), 8 deletions(-) diff --git a/include/osg/GL2Extensions b/include/osg/GL2Extensions index 8d139101d..5135403c4 100644 --- a/include/osg/GL2Extensions +++ b/include/osg/GL2Extensions @@ -3,6 +3,7 @@ * Copyright (C) 2004-2005 Nathan Cournia * Copyright (C) 2007 Art Tevs * Copyright (C) 2008 Zebra Imaging + * Copyright (C) 2010 VIRES Simulationstechnologie GmbH * * This application is open source and may be redistributed and/or modified * freely and without restriction, both in commercial and non commercial @@ -15,6 +16,7 @@ /* file: include/osg/GL2Extensions * author: Mike Weiblen 2008-01-02 + * Holger Helmich 2010-10-21 */ #ifndef OSG_GL2EXTENSIONS @@ -178,6 +180,42 @@ typedef char GLchar; #define GL_PROGRAM_POINT_SIZE_EXT 0x8642 #endif +// ARB_tesselation_shader +#ifndef GL_TESS_EVALUATION_SHADER +#define GL_PATCHES 0x000E +#define GL_PATCH_VERTICES 0x8E72 +#define GL_PATCH_DEFAULT_INNER_LEVEL 0x8E73 +#define GL_PATCH_DEFAULT_OUTER_LEVEL 0x8E74 +#define GL_MAX_PATCH_VERTICES 0x8E7D +#define GL_MAX_TESS_GEN_LEVEL 0x8E7E +#define GL_MAX_TESS_CONTROL_UNIFORM_COMPONENTS 0x8E7F +#define GL_MAX_TESS_EVALUATION_UNIFORM_COMPONENTS 0x8E80 +#define GL_MAX_TESS_CONTROL_TEXTURE_IMAGE_UNITS 0x8E81 +#define GL_MAX_MAX_TESS_EVALUATION_TEXTURE_IMAGE_UNITS 0x8E82 +#define GL_MAX_MAX_TESS_CONTROL_OUTPUT_COMPONENTS 0x8E83 +#define GL_MAX_MAX_TESS_PATCH_COMPONENTS 0x8E84 +#define GL_MAX_MAX_TESS_CONTROL_TOTAL_OUTPUT_COMPONENTS 0x8E85 +#define GL_MAX_MAX_TESS_EVALUATION_OUTPUT_COMPONENTS 0x8E86 +#define GL_MAX_MAX_TESS_CONTROL_UNIFORM_BLOCKS 0x8E89 +#define GL_MAX_MAX_TESS_EVALUATION_UNIFORM_BLOCKS 0x8E8A +#define GL_MAX_MAX_TESS_CONTROL_INPUT_COMPONENTS 0x886C +#define GL_MAX_MAX_TESS_EVALUATION_INPUT_COMPONENTS 0x886D +#define GL_MAX_MAX_COMBINED_TESS_CONTROL_UNIFORM_COMPONENTS 0x8E1E +#define GL_MAX_MAX_COMBINED_TESS_EVALUATION_UNIFORM_COMPONENTS 0x8E1F +#define GL_TESS_EVALUATION_SHADER 0x8E87 +#define GL_TESS_CONTROL_SHADER 0x8E88 +#define GL_TESS_CONTROL_OUTPUT_VERTICES 0x8E75 +#define GL_TESS_GEN_MODE 0x8E76 +#define GL_TESS_GEN_SPACING 0x8E77 +#define GL_TESS_GEN_VERTEX_ORDER 0x8E78 +#define GL_TESS_GEN_POINT_MODE 0x8E79 +#define GL_ISOLINES 0x8E7A +#define GL_FRACTIONAL_ODD 0x8E7B +#define GL_FRACTIONAL_EVEN 0x8E7C +#define GL_UNIFORM_BLOCK_REFERENCED_BY_TESS_CONTROL_SHADER 0x84F0 +#define GL_UNIFORM_BLOCK_REFERENCED_BY_TESS_EVALUATION_SHADER 0x84F1 +#endif + // EXT_gpu_shader4 #ifndef GL_INT_SAMPLER_2D_EXT #define GL_SAMPLER_1D_ARRAY_EXT 0x8DC0 @@ -243,6 +281,9 @@ class OSG_EXPORT GL2Extensions : public osg::Referenced void setGeometryShader4Supported(bool flag) { _isGeometryShader4Supported = flag; } bool isGeometryShader4Supported() const { return _isGeometryShader4Supported; } + void setTessellationShadersSupported(bool flag) { _areTessellationShadersSupported = flag; } + bool areTessellationShadersSupported() const { return _areTessellationShadersSupported; } + void setGpuShader4Supported(bool flag) { _isGpuShader4Supported = flag; } bool isGpuShader4Supported() const { return _isGpuShader4Supported; } @@ -375,6 +416,10 @@ class OSG_EXPORT GL2Extensions : public osg::Referenced void glFramebufferTextureLayer( GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer ) const; void glFramebufferTextureFace( GLenum target, GLenum attachment, GLuint texture, GLint level, GLenum face ) const; + // ARB_tessellation_shader + void glPatchParameteri(GLenum pname, GLint value) const; + void glPatchParameterfv(GLenum pname, const GLfloat *values) const; + // EXT_gpu_shader4 void glGetUniformuiv( GLuint program, GLint location, GLuint *params ) const; void glBindFragDataLocation( GLuint program, GLuint color, const GLchar *name ) const; @@ -399,6 +444,7 @@ class OSG_EXPORT GL2Extensions : public osg::Referenced bool _isFragmentShaderSupported; bool _isLanguage100Supported; bool _isGeometryShader4Supported; + bool _areTessellationShadersSupported; bool _isGpuShader4Supported; typedef void (GL_APIENTRY * BlendEquationSeparateProc)(GLenum modeRGB, GLenum modeAlpha); @@ -507,6 +553,8 @@ class OSG_EXPORT GL2Extensions : public osg::Referenced typedef void (GL_APIENTRY * FramebufferTextureProc)( GLenum target, GLenum attachment, GLuint texture, GLint level ); typedef void (GL_APIENTRY * FramebufferTextureLayerProc)( GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer ); typedef void (GL_APIENTRY * FramebufferTextureFaceProc)( GLenum target, GLenum attachment, GLuint texture, GLint level, GLenum face ); + typedef void (GL_APIENTRY * PatchParameteriProc)( GLenum pname, GLint value ); + typedef void (GL_APIENTRY * PatchParameterfvProc)( GLenum pname, const GLfloat* values ); typedef void (GL_APIENTRY * GetUniformuivProc)( GLuint program, GLint location, GLuint* params ); typedef void (GL_APIENTRY * BindFragDataLocationProc)( GLuint program, GLuint color, const GLchar* name ); typedef GLint (GL_APIENTRY * GetFragDataLocationProc)( GLuint program, const GLchar* name ); @@ -633,6 +681,10 @@ class OSG_EXPORT GL2Extensions : public osg::Referenced FramebufferTextureLayerProc _glFramebufferTextureLayer; FramebufferTextureFaceProc _glFramebufferTextureFace; + // ARB_tesselation_shader + PatchParameteriProc _glPatchParameteri; + PatchParameterfvProc _glPatchParameterfv; + // EXT_gpu_shader4 GetUniformuivProc _glGetUniformuiv; BindFragDataLocationProc _glBindFragDataLocation; diff --git a/include/osg/PrimitiveSet b/include/osg/PrimitiveSet index 39bbc5534..1d51f454a 100644 --- a/include/osg/PrimitiveSet +++ b/include/osg/PrimitiveSet @@ -177,7 +177,8 @@ class OSG_EXPORT PrimitiveSet : public BufferData LINES_ADJACENCY = GL_LINES_ADJACENCY_EXT, LINE_STRIP_ADJACENCY = GL_LINE_STRIP_ADJACENCY_EXT, TRIANGLES_ADJACENCY = GL_TRIANGLES_ADJACENCY_EXT, - TRIANGLE_STRIP_ADJACENCY = GL_TRIANGLE_STRIP_ADJACENCY_EXT + TRIANGLE_STRIP_ADJACENCY = GL_TRIANGLE_STRIP_ADJACENCY_EXT, + PATCHES = GL_PATCHES }; PrimitiveSet(Type primType=PrimitiveType,GLenum mode=0, int numInstances=0): diff --git a/include/osg/Program b/include/osg/Program index 08aaf7404..a9c87e07b 100644 --- a/include/osg/Program +++ b/include/osg/Program @@ -2,6 +2,7 @@ * Copyright (C) 2003-2005 3Dlabs Inc. Ltd. * Copyright (C) 2004-2005 Nathan Cournia * Copyright (C) 2008 Zebra Imaging + * Copyright (C) 2010 Vires Simulationstechnologie GmbH * * This application is open source and may be redistributed and/or modified * freely and without restriction, both in commercial and non commercial @@ -14,6 +15,7 @@ /* file: include/osg/Program * author: Mike Weiblen 2008-01-02 + * Holger Helmich 2010-10-21 */ #ifndef OSG_PROGRAM @@ -96,6 +98,9 @@ class OSG_EXPORT Program : public osg::StateAttribute void setParameter( GLenum pname, GLint value ); GLint getParameter( GLenum pname ) const; + void setParameterfv( GLenum pname, const GLfloat* value ); + const GLfloat* getParameterfv( GLenum pname ) const; + /** Add an attribute location binding. */ void addBindAttribLocation( const std::string& name, GLuint index ); @@ -275,8 +280,17 @@ class OSG_EXPORT Program : public osg::StateAttribute GLint _geometryInputType; GLint _geometryOutputType; + /** Parameter maintained with glPatchParameteri */ + GLint _patchVertices; + + /** Parameter maintained with glPatchParameterfv */ + // todo add tessellation default level + //GLfloat _patchDefaultInnerLevel[2]; + //GLfloat _patchDefaultOuterLevel[4]; + private: Program& operator=(const Program&); // disallowed + }; } diff --git a/include/osg/Shader b/include/osg/Shader index d9fd6aef9..5587f34a7 100644 --- a/include/osg/Shader +++ b/include/osg/Shader @@ -2,6 +2,7 @@ * Copyright (C) 2003-2005 3Dlabs Inc. Ltd. * Copyright (C) 2004-2005 Nathan Cournia * Copyright (C) 2008 Zebra Imaging + * Copyright (C) 2010 VIRES Simulationstechnologie GmbH * * This application is open source and may be redistributed and/or modified * freely and without restriction, both in commercial and non commercial @@ -14,6 +15,7 @@ /* file: include/osg/Shader * author: Mike Weiblen 2008-01-02 + * Holger Helmich 2010-10-21 */ #ifndef OSG_SHADER @@ -86,8 +88,10 @@ class OSG_EXPORT Shader : public osg::Object enum Type { VERTEX = GL_VERTEX_SHADER, - FRAGMENT = GL_FRAGMENT_SHADER, + TESSCONTROL = GL_TESS_CONTROL_SHADER, + TESSEVALUATION = GL_TESS_EVALUATION_SHADER, GEOMETRY = GL_GEOMETRY_SHADER_EXT, + FRAGMENT = GL_FRAGMENT_SHADER, UNDEFINED = -1 }; diff --git a/src/osg/GL2Extensions.cpp b/src/osg/GL2Extensions.cpp index ae544fa44..32d4f76a1 100644 --- a/src/osg/GL2Extensions.cpp +++ b/src/osg/GL2Extensions.cpp @@ -302,6 +302,10 @@ void GL2Extensions::lowestCommonDenominator(const GL2Extensions& rhs) if (!rhs._glFramebufferTextureLayer) _glFramebufferTextureLayer = 0; if (!rhs._glFramebufferTextureFace) _glFramebufferTextureFace = 0; + // ARB_tessellation_shader + if (!rhs._glPatchParameteri) _glPatchParameteri = 0; + if (!rhs._glPatchParameterfv) _glPatchParameterfv = 0; + // EXT_gpu_shader4 if (!rhs._glGetUniformuiv) _glGetUniformuiv = 0; if (!rhs._glBindFragDataLocation) _glBindFragDataLocation = 0; @@ -337,6 +341,7 @@ void GL2Extensions::setupGL2Extensions(unsigned int contextID) _isLanguage100Supported = shadersBuiltIn || osg::isGLExtensionSupported(contextID,"GL_ARB_shading_language_100"); _isGeometryShader4Supported = osg::isGLExtensionSupported(contextID,"GL_EXT_geometry_shader4"); _isGpuShader4Supported = osg::isGLExtensionSupported(contextID,"GL_EXT_gpu_shader4"); + _areTessellationShadersSupported = osg::isGLExtensionSupported(contextID, "GL_ARB_tessellation_shader"); if( isGlslSupported() ) { @@ -470,6 +475,10 @@ void GL2Extensions::setupGL2Extensions(unsigned int contextID) setGLExtensionFuncPtr(_glFramebufferTextureLayer, "glFramebufferTextureLayer", "glFramebufferTextureLayerEXT" ); setGLExtensionFuncPtr(_glFramebufferTextureFace, "glFramebufferTextureFace", "glFramebufferTextureFaceEXT" ); + // ARB_tesselation_shader + setGLExtensionFuncPtr(_glPatchParameteri, "glPatchParameteri" ); + setGLExtensionFuncPtr(_glPatchParameterfv, "glPatchParameterfv"); + // EXT_gpu_shader4 setGLExtensionFuncPtr(_glGetUniformuiv, "glGetUniformuiv", "glGetUniformuivEXT" ); setGLExtensionFuncPtr(_glBindFragDataLocation, "glBindFragDataLocation", "glBindFragDataLocationEXT" ); @@ -1973,6 +1982,30 @@ void GL2Extensions::glFramebufferTextureFace( GLenum target, GLenum attachment, } } +void GL2Extensions::glPatchParameteri( GLenum pname, GLint value ) const +{ + if (_glPatchParameteri) + { + + _glPatchParameteri( pname, value ); + } + else + { + NotSupported( "glPatchParameteri" ); + } +} +void GL2Extensions::glPatchParameterfv( GLenum pname, const GLfloat* values ) const +{ + if (_glPatchParameterfv) + { + + _glPatchParameterfv( pname, values ); + } + else + { + NotSupported( "glPatchParameterfv" ); + } +} void GL2Extensions::glGetUniformuiv( GLuint program, GLint location, GLuint* params ) const { diff --git a/src/osg/PrimitiveSet.cpp b/src/osg/PrimitiveSet.cpp index 728e30e4d..09b981e2b 100644 --- a/src/osg/PrimitiveSet.cpp +++ b/src/osg/PrimitiveSet.cpp @@ -30,6 +30,7 @@ unsigned int PrimitiveSet::getNumPrimitives() const case(TRIANGLE_STRIP): case(TRIANGLE_FAN): case(QUAD_STRIP): + case(PATCHES): case(POLYGON): return 1; } return 0; @@ -84,6 +85,7 @@ unsigned int DrawArrayLengths::getNumPrimitives() const case(TRIANGLE_STRIP): case(TRIANGLE_FAN): case(QUAD_STRIP): + case(PATCHES): case(POLYGON): return size(); } return 0; diff --git a/src/osg/Program.cpp b/src/osg/Program.cpp index c50bc58a7..38768caf1 100644 --- a/src/osg/Program.cpp +++ b/src/osg/Program.cpp @@ -2,6 +2,7 @@ * Copyright (C) 2003-2005 3Dlabs Inc. Ltd. * Copyright (C) 2004-2005 Nathan Cournia * Copyright (C) 2008 Zebra Imaging + * Copyright (C) 2010 VIRES Simulationstechnologie GmbH * * This application is open source and may be redistributed and/or modified * freely and without restriction, both in commercial and non commercial @@ -15,6 +16,7 @@ /* file: src/osg/Program.cpp * author: Mike Weiblen 2008-01-19 + * Holger Helmich 2010-10-21 */ #include @@ -97,7 +99,8 @@ void Program::discardDeletedGlPrograms(unsigned int contextID) Program::Program() : _geometryVerticesOut(1), _geometryInputType(GL_TRIANGLES), - _geometryOutputType(GL_TRIANGLE_STRIP) + _geometryOutputType(GL_TRIANGLE_STRIP), + _patchVertices(3) { } @@ -125,6 +128,8 @@ Program::Program(const Program& rhs, const osg::CopyOp& copyop): _geometryVerticesOut = rhs._geometryVerticesOut; _geometryInputType = rhs._geometryInputType; _geometryOutputType = rhs._geometryOutputType; + + _patchVertices = rhs._patchVertices; } @@ -159,6 +164,9 @@ int Program::compare(const osg::StateAttribute& sa) const if( _geometryOutputType < rhs._geometryOutputType ) return -1; if( rhs._geometryOutputType < _geometryOutputType ) return 1; + if( _patchVertices < rhs._patchVertices ) return -1; + if( rhs._patchVertices < _patchVertices ) return 1; + ShaderList::const_iterator litr=_shaderList.begin(); ShaderList::const_iterator ritr=rhs._shaderList.begin(); for(; @@ -299,7 +307,11 @@ void Program::setParameter( GLenum pname, GLint value ) break; case GL_GEOMETRY_OUTPUT_TYPE_EXT: _geometryOutputType = value; - dirtyProgram(); // needed? + //dirtyProgram(); // needed? + break; + case GL_PATCH_VERTICES: + _patchVertices = value; + dirtyProgram(); break; default: OSG_WARN << "setParameter invalid param " << pname << std::endl; @@ -307,6 +319,35 @@ void Program::setParameter( GLenum pname, GLint value ) } } +void Program::setParameterfv( GLenum pname, const GLfloat* value ) +{ + switch( pname ) + { + // todo tessellation default level + case GL_PATCH_DEFAULT_INNER_LEVEL: + break; + case GL_PATCH_DEFAULT_OUTER_LEVEL: + break; + default: + OSG_WARN << "setParameter invalid param " << pname << std::endl; + break; + } +} + +const GLfloat* Program::getParameterfv( GLenum pname ) const +{ + switch( pname ) + { + ; + // todo tessellation default level + // case GL_PATCH_DEFAULT_INNER_LEVEL: return _patchDefaultInnerLevel; + // case GL_PATCH_DEFAULT_OUTER_LEVEL: return _patchDefaultOuterLevel; + + } + OSG_WARN << "getParameter invalid param " << pname << std::endl; + return 0; +} + GLint Program::getParameter( GLenum pname ) const { switch( pname ) @@ -314,6 +355,7 @@ GLint Program::getParameter( GLenum pname ) const case GL_GEOMETRY_VERTICES_OUT_EXT: return _geometryVerticesOut; case GL_GEOMETRY_INPUT_TYPE_EXT: return _geometryInputType; case GL_GEOMETRY_OUTPUT_TYPE_EXT: return _geometryOutputType; + case GL_PATCH_VERTICES: return _patchVertices; } OSG_WARN << "getParameter invalid param " << pname << std::endl; return 0; @@ -464,14 +506,20 @@ void Program::PerContextProgram::linkProgram(osg::State& state) _extensions->glProgramParameteri( _glProgramHandle, GL_GEOMETRY_INPUT_TYPE_EXT, _program->_geometryInputType ); _extensions->glProgramParameteri( _glProgramHandle, GL_GEOMETRY_OUTPUT_TYPE_EXT, _program->_geometryOutputType ); } - + + if (_extensions->areTessellationShadersSupported() ) + { + _extensions->glPatchParameteri( GL_PATCH_VERTICES, _program->_patchVertices ); + // todo: add default tessellation level + } + // Detach removed shaders for( unsigned int i=0; i < _shadersToDetach.size(); ++i ) { _shadersToDetach[i]->detachShader( _contextID, _glProgramHandle ); } _shadersToDetach.clear(); - + // Attach new shaders for( unsigned int i=0; i < _shadersToAttach.size(); ++i ) { diff --git a/src/osg/Shader.cpp b/src/osg/Shader.cpp index 38377b0aa..ab936775d 100644 --- a/src/osg/Shader.cpp +++ b/src/osg/Shader.cpp @@ -2,6 +2,7 @@ * Copyright (C) 2003-2005 3Dlabs Inc. Ltd. * Copyright (C) 2004-2005 Nathan Cournia * Copyright (C) 2008 Zebra Imaging + * Copyright (C) 2010 VIRES Simulationstechnologie GmbH * * This application is open source and may be redistributed and/or modified * freely and without restriction, both in commercial and non commercial @@ -15,6 +16,7 @@ /* file: src/osg/Shader.cpp * author: Mike Weiblen 2008-01-02 + * Holger Helmich 2010-10-21 */ #include @@ -321,8 +323,10 @@ const char* Shader::getTypename() const switch( getType() ) { case VERTEX: return "VERTEX"; - case FRAGMENT: return "FRAGMENT"; + case TESSCONTROL: return "TESSCONTROL"; + case TESSEVALUATION: return "TESSEVALUATION"; case GEOMETRY: return "GEOMETRY"; + case FRAGMENT: return "FRAGMENT"; default: return "UNDEFINED"; } } @@ -331,8 +335,10 @@ const char* Shader::getTypename() const Shader::Type Shader::getTypeId( const std::string& tname ) { if( tname == "VERTEX" ) return VERTEX; - if( tname == "FRAGMENT" ) return FRAGMENT; + if( tname == "TESSCONTROL" ) return TESSCONTROL; + if( tname == "TESSEVALUATION") return TESSEVALUATION; if( tname == "GEOMETRY" ) return GEOMETRY; + if( tname == "FRAGMENT" ) return FRAGMENT; return UNDEFINED; } diff --git a/src/osg/ShaderComposer.cpp b/src/osg/ShaderComposer.cpp index 736606803..3389bd2ff 100644 --- a/src/osg/ShaderComposer.cpp +++ b/src/osg/ShaderComposer.cpp @@ -1,4 +1,5 @@ /* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield + * Copyright (C) 2010-10-21 VIRES Simulationstechnologie GmbH * * This library is open source and may be redistributed and/or modified under * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or @@ -11,6 +12,10 @@ * OpenSceneGraph Public License for more details. */ +/* + * mod: Holger Helmich 2010-10-21 + */ + #include #include @@ -43,6 +48,8 @@ osg::Program* ShaderComposer::getOrCreateProgram(const ShaderComponents& shaderC // strip out vertex shaders Shaders vertexShaders; + Shaders tessControlShaders; + Shaders tessEvaluationShaders; Shaders geometryShaders; Shaders fragmentShaders; @@ -62,6 +69,12 @@ osg::Program* ShaderComposer::getOrCreateProgram(const ShaderComponents& shaderC case(Shader::VERTEX): vertexShaders.push_back(shader); break; + case(Shader::TESSCONTROL): + tessControlShaders.push_back(shader); + break; + case(Shader::TESSEVALUATION): + tessEvaluationShaders.push_back(shader); + break; case(Shader::GEOMETRY): geometryShaders.push_back(shader); break;