Commit a1a32038 authored by Jan Möbius's avatar Jan Möbius

Merge branch 'featurePickingShaderCompatibility' into 'master'

Feature picking shader compatibility

Closes #18

See merge request !88
parents 2b6a6259 60e9b3eb
......@@ -19,6 +19,7 @@
- <b>ACG</b>
- Clamp shininess in Materialnode (caused GL Errors)
- Better Material support in Materialnode (emissive and refractive materials)
- Use ShaderGenerator for picking shaders
- <b>Plugins</b>
- File-OBJ
- Read emissive and refractive materials
......
// returns picking ids of faces in a n-poly mesh
#version 150
#include "colortranslator.glsl"
uniform int pickFaceOffset;
uniform isamplerBuffer triToFaceMap; // maps: triangle id in draw buffer -> face id in input buffer
out vec4 outPickID;
void main()
{
int faceID = texelFetch(triToFaceMap, gl_PrimitiveID).x;
// faceID = gl_PrimitiveID; // debug mode: skip reading from texture-buffer
int pickID = pickFaceOffset + faceID;
outPickID = IntToColor(pickID);
}
\ No newline at end of file
outFragment = IntToColor(pickID);
}
// returns picking ids of vertices
#version 150
in vec4 vertexPickID;
out vec4 outPickID;
void main()
{
outPickID = vertexPickID;
outFragment = vertexPickID;
}
// returns picking ids of vertices
#version 150
#include "colortranslator.glsl"
uniform int pickVertexOffset;
out vec4 outPickID;
void main()
{
int vertexID = gl_PrimitiveID + pickVertexOffset;
outPickID = IntToColor(vertexID);
outFragment = IntToColor(vertexID);
}
// returns picking ids of vertices
#version 150
#include "colortranslator.glsl"
uniform mat4 mWVP;
uniform int pickVertexOffset;
//uniform isamplerBuffer vboToInputMap; // maps: vertex id in draw buffer -> vertex id in input buffer
in vec4 inPosition;
out vec4 vertexPickID;
void main()
......
// picking - all fragments have the same pick id
#version 150
uniform vec4 color;
out vec4 outColor;
void main()
{
outColor = color;
outFragment = color;
}
#version 150
uniform mat4 mWVP;
in vec4 inPosition;
void main()
{
gl_Position = mWVP * vec4(inPosition.xyz, 1);
......
......@@ -96,7 +96,9 @@ DrawMeshT<Mesh>::DrawMeshT(Mesh& _mesh)
updatePerHalfedgeBuffers_(1)
{
pickVertexMethod_ = 1;
//today (4.5.2018) the picking shader which uses a textureBuffer, also uses gl_PrimitiveID
// since it is only supported since glslversion 150 we can just check for openGLVersion 3.2
pickVertexMethod_ = openGLVersionTest(3,2) ? 1 : 0;
pickVertexShader_ = 0;
pickFaceShader_ = 0;
......@@ -1621,18 +1623,12 @@ void DrawMeshT<Mesh>::updatePickingVertices_opt(ACG::GLState& _state)
rebuild();
}
if(ACG::compatibilityProfile())
pickVertexMethod_ = 1; // no texture buffers supported during compilation
if (numVerts_)
{
// upload vbo id->openmesh id lookup-table to texture buffer
if (pickVertexMethod_ == 0)
{
if(!ACG::compatibilityProfile())
{
std::vector<int> forwardMap(numVerts_, 0);
for (int i = 0; i < (int)numVerts_; ++i)
......@@ -1642,7 +1638,6 @@ void DrawMeshT<Mesh>::updatePickingVertices_opt(ACG::GLState& _state)
forwardMap[vboIdx] = i;
}
pickVertexMapTBO_.setBufferData(sizeof(int) * numVerts_, &forwardMap[0], GL_R32I, GL_STATIC_DRAW);
}
}
else
......@@ -1665,22 +1660,21 @@ void DrawMeshT<Mesh>::updatePickingVertices_opt(ACG::GLState& _state)
template <class Mesh>
bool ACG::DrawMeshT<Mesh>::supportsPickingVertices_opt()
{
// load and compile picking shader
// load once directly from files:
// if (!pickVertexShader_)
// {
// if (pickVertexMethod_ == 0)
// pickVertexShader_ = GLSL::loadProgram("Picking/pick_vertices_vs.glsl", "Picking/pick_vertices_fs.glsl");
// else
// pickVertexShader_ = GLSL::loadProgram("Picking/vertex.glsl", "Picking/pick_vertices_fs2.glsl");
// }
// load and compile picking shader if necessary
// use shaderGenDesc to generate shaders for better shader compatibility
static ShaderGenDesc desc;
// load from cache
if (pickVertexMethod_ == 0)
pickVertexShader_ = ShaderCache::getInstance()->getProgram("Picking/pick_vertices_vs.glsl", "Picking/pick_vertices_fs.glsl", 0, false);
{
desc.fragmentTemplateFile = "Picking/pick_vertices_fs.glsl";
desc.vertexTemplateFile = "Picking/pick_vertices_vs.glsl";
}
else
pickVertexShader_ = ShaderCache::getInstance()->getProgram("Picking/vertex.glsl", "Picking/pick_vertices_fs2.glsl", 0, false);
{
desc.fragmentTemplateFile = "Picking/pick_vertices_fs2.glsl";
desc.vertexTemplateFile = "Picking/vertex.glsl";
}
pickVertexShader_ = ShaderCache::getInstance()->getProgram(&desc,nullptr);
// check link status
return pickVertexShader_ && pickVertexShader_->isLinked();
......@@ -1728,8 +1722,7 @@ void ACG::DrawMeshT<Mesh>::drawPickingVertices_opt( const GLMatrixf& _mvp, size_
if (pickVertexMethod_ == 0)
{
pickVertexShader_->setUniform("vboToInputMap", 0);
if(!ACG::compatibilityProfile())
pickVertexMap_opt()->bind(GL_TEXTURE0);
pickVertexMap_opt()->bind(GL_TEXTURE0);
}
pickVertexShader_->setUniform("mWVP", _mvp);
......@@ -1959,7 +1952,10 @@ template <class Mesh>
bool ACG::DrawMeshT<Mesh>::supportsPickingEdges_opt()
{
// fetch picking shader from cache (edge picking uses same shader as vertex picking)
pickEdgeShader_ = ShaderCache::getInstance()->getProgram("Picking/vertex.glsl", "Picking/pick_vertices_fs2.glsl", 0, false);
static ShaderGenDesc desc;
desc.vertexTemplateFile = "Picking/vertex.glsl" ;
desc.fragmentTemplateFile = "Picking/pick_vertices_fs2.glsl" ;
pickEdgeShader_ = ShaderCache::getInstance()->getProgram(&desc, nullptr);
// check link status
return pickEdgeShader_ && pickEdgeShader_->isLinked();
......@@ -2088,7 +2084,10 @@ bool ACG::DrawMeshT<Mesh>::supportsPickingFaces_opt()
return false;
// fetch picking shader from cache
pickFaceShader_ = ShaderCache::getInstance()->getProgram("Picking/vertex.glsl", "Picking/pick_face.glsl", 0, false);
static ShaderGenDesc desc;
desc.vertexTemplateFile = "Picking/vertex.glsl";
desc.fragmentTemplateFile = "Picking/pick_face.glsl";
pickFaceShader_ = ShaderCache::getInstance()->getProgram(&desc, nullptr);
// check link status
return pickFaceShader_ && pickFaceShader_->isLinked();
......@@ -2145,8 +2144,7 @@ void ACG::DrawMeshT<Mesh>::drawPickingFaces_opt( const GLMatrixf& _mvp, size_t _
pickFaceShader_->setUniform("pickFaceOffset", static_cast<GLint>(_pickOffset));
pickFaceShader_->setUniform("triToFaceMap", 0);
if(!ACG::compatibilityProfile())
pickFaceTriangleMap_opt()->bind(GL_TEXTURE0);
pickFaceTriangleMap_opt()->bind(GL_TEXTURE0);
pickFaceShader_->setUniform("mWVP", _mvp);
......
......@@ -921,7 +921,7 @@ void ShaderProgGenerator::init( const ShaderGenDesc* _desc, ShaderModifier* cons
desc_ = *_desc;
// We need at least version 3.2 or higher to support geometry shaders
if ( !ACG::openGLVersion(3,2) )
if ( !ACG::openGLVersionTest(3,2) )
{
if (!desc_.geometryTemplateFile.isEmpty())
std::cerr << "Warning: removing geometry shader from ShaderDesc" << std::endl;
......@@ -930,7 +930,7 @@ void ShaderProgGenerator::init( const ShaderGenDesc* _desc, ShaderModifier* cons
}
// We need at least version 4.0 or higher to support tessellation
if ( !ACG::openGLVersion(4, 0) )
if ( !ACG::openGLVersionTest(4, 0) )
{
if (!desc_.tessControlTemplateFile.isEmpty() || !desc_.tessEvaluationTemplateFile.isEmpty())
std::cerr << "Warning: removing tessellation shader from ShaderDesc" << std::endl;
......
......@@ -110,6 +110,19 @@ public:
{
for ( unsigned int i = 0 ; i < SG_MAX_SHADER_LIGHTS ; ++i)
lightTypes[i] = SG_LIGHT_DIRECTIONAL;
if(!ACG::openGLVersionTest(3,2)) // version 140 or less
{
if(!ACG::openGLVersionTest(3,1)) // assume version 130
{ // less is not supported
version = 130;
if(ACG::checkExtensionSupported("EXT_texture_buffer"))
macros.append("#extension GL_EXT_texture_buffer: enable");
}
else // version 140 texture buffer is part of spec
{
version = 140;
}
}
}
//In case, something crashes with the light types, try this hammer ;-)
......
......@@ -468,7 +468,14 @@ void VertexDeclaration::activateShaderPipeline(GLSL::Program* _prog) const
if (supportsInstancedArrays())
{
glVertexAttribDivisor(loc, pElem->divisor_);
if( openGLVersionTest(3,3) )
{
glVertexAttribDivisor(loc, pElem->divisor_);
}
else
{
glVertexAttribDivisorARB(loc, pElem->divisor_);
}
}
else if (pElem->divisor_)
std::cerr << "error: VertexDeclaration::activateShaderPipeline - instanced arrays not supported by gpu!" << std::endl;
......@@ -500,7 +507,14 @@ void VertexDeclaration::deactivateShaderPipeline( GLSL::Program* _prog ) const
if (supportsInstancedArrays() && pElem->divisor_)
{
glVertexAttribDivisor(loc, 0);
if( openGLVersionTest(3,3) )
{
glVertexAttribDivisor(loc, 0);
}
else
{
glVertexAttribDivisorARB(loc, 0);
}
}
}
}
......
......@@ -126,7 +126,7 @@ bool checkExtensionSupported( const std::string& _extension ) {
/** Check if OpenGL Version is greater or equal than the given values
*/
bool openGLVersion( const int _major, const int _minor ) {
bool openGLVersion( const int _major, const int _minor, bool _verbose ) {
// Read OpenGL Version string
std::string glVersionString = (const char*)glGetString(GL_VERSION);
......@@ -148,8 +148,11 @@ bool openGLVersion( const int _major, const int _minor ) {
stream >> minor;
if ( (_major > major) || ( (_major == major) && (_minor > minor)) ) {
std::cerr << "OpenGL Version check failed. Required : " << _major << "." << _minor << std::endl;
std::cerr << "OpenGL Version check failed. Available : " << major << "." << minor << std::endl;
if(_verbose)
{
std::cerr << "OpenGL Version check failed. Required : " << _major << "." << _minor << std::endl;
std::cerr << "OpenGL Version check failed. Available : " << major << "." << minor << std::endl;
}
return false;
}
......
......@@ -269,7 +269,12 @@ bool ACGDLLEXPORT checkExtensionSupported( const std::string& _extension ) ;
/** Check if OpenGL Version is greater or equal than the given values
*/
bool ACGDLLEXPORT openGLVersion( const int _major, const int _minor );
bool ACGDLLEXPORT openGLVersion( const int _major, const int _minor, bool verbose = true );
/** Test if OpenGL Version is greater or equal than the given values
* No output is generated, if the OpenGL version is less than the tested value
*/
inline bool ACGDLLEXPORT openGLVersionTest( const int _major, const int _minor ){return openGLVersion(_major, _minor, false);}
/// Store opengl core profile setting
void ACGDLLEXPORT compatibilityProfile(bool _compatProfile);
......
......@@ -188,7 +188,7 @@ bool Texture::supportsTextureBuffer()
if (status < 0)
{
// core in version 3.0
status = checkExtensionSupported("ARB_texture_buffer_object") || openGLVersion(3,0);
status = checkExtensionSupported("EXT_texture_buffer") || openGLVersion(3,1);
}
return status > 0;
......
......@@ -697,7 +697,10 @@ CoordsysNode::pick(GLState& _state, PickTarget _target)
GLSL::Program* pickShader = 0;
if (!fixedFunctionGL)
{
pickShader = ShaderCache::getInstance()->getProgram("Picking/vertex.glsl", "Picking/single_color_fs.glsl");
static ShaderGenDesc desc;
desc.fragmentTemplateFile = "Picking/single_color_fs.glsl";
desc.vertexTemplateFile = "Picking/vertex.glsl";
pickShader = ShaderCache::getInstance()->getProgram(&desc, nullptr);
if (!pickShader)
return;
......
......@@ -1215,9 +1215,10 @@ pick_vertices(GLState& _state, bool _front)
// 1 -> render mesh with picking shader (optimized, add. mem alloc: none for point-clouds, otherwise 4 bytes per openmesh vertex on gpu)
int pickImplementationMethod = 0;
// use optimized picking if supported
// use optimized picking if supported (the function actually checks whether the shader was linked and bound)
// which shader should be used only depends on the available OpenGL version
if (drawMesh_->supportsPickingVertices_opt())
pickImplementationMethod = 1;
pickImplementationMethod = openGLVersionTest(3,2) ? 1 : 0;
if (_state.color_picking () ) {
......@@ -1320,7 +1321,7 @@ pick_edges(GLState& _state, bool _front)
// use optimized picking if supported
if (drawMesh_->supportsPickingEdges_opt())
pickImplementationMethod = 1;
pickImplementationMethod = openGLVersionTest(3,2) ? 1 : 0;
if ( updateEdgePicking_ || _state.pick_current_index () != edgePickingBaseIndex_) {
if (pickImplementationMethod == 0)
......@@ -1398,7 +1399,7 @@ pick_faces(GLState& _state)
// use optimized picking if supported
if (drawMesh_->supportsPickingFaces_opt())
pickImplementationMethod = 1;
pickImplementationMethod = openGLVersionTest(3,2) ? 1 : 0;
// pickImplementationMethod = 0;
......@@ -1501,12 +1502,9 @@ pick_any(GLState& _state)
// 1 -> render mesh with picking shader (optimized, add. mem alloc: none [ shared memory with optimized vertex,edge,face picking ])
int pickImplementationMethod = 0;
if(!_state.compatibilityProfile())
pickImplementationMethod = 1;
// use optimized picking if supported
if (drawMesh_->supportsPickingAny_opt())
pickImplementationMethod = 1;
pickImplementationMethod = openGLVersionTest(3,2) ? 1 : 0;
if ( updateAnyPicking_ || _state.pick_current_index () != anyPickingBaseIndex_) {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment