diff --git a/panda/src/glstuff/glGraphicsBuffer_src.cxx b/panda/src/glstuff/glGraphicsBuffer_src.cxx index cb1451ebe7..40a6d4fdcc 100644 --- a/panda/src/glstuff/glGraphicsBuffer_src.cxx +++ b/panda/src/glstuff/glGraphicsBuffer_src.cxx @@ -1062,6 +1062,7 @@ attach_tex(int layer, int view, Texture *attach, GLenum attachpoint) { #ifndef OPENGLES if (_rb_size_z != 1) { // Bind all of the layers of the texture. + nassertv(glgsg->_glFramebufferTexture != NULL); glgsg->_glFramebufferTexture(GL_FRAMEBUFFER_EXT, attachpoint, gtc->_index, 0); return; diff --git a/panda/src/glstuff/glGraphicsStateGuardian_src.cxx b/panda/src/glstuff/glGraphicsStateGuardian_src.cxx index 476e1af9f1..20bc4c2ae8 100644 --- a/panda/src/glstuff/glGraphicsStateGuardian_src.cxx +++ b/panda/src/glstuff/glGraphicsStateGuardian_src.cxx @@ -814,13 +814,22 @@ reset() { _supports_2d_texture_array = false; #ifndef OPENGLES - _supports_2d_texture_array = has_extension("GL_EXT_texture_array"); - if (_supports_2d_texture_array) { + if (is_at_least_gl_version(3, 0)) { + _supports_2d_texture_array = true; + + _glFramebufferTextureLayer = (PFNGLFRAMEBUFFERTEXTURELAYERPROC) + get_extension_func("glFramebufferTextureLayer"); + + } else if (has_extension("GL_EXT_texture_array")) { + _supports_2d_texture_array = true; + _glFramebufferTextureLayer = (PFNGLFRAMEBUFFERTEXTURELAYERPROC) get_extension_func("glFramebufferTextureLayerEXT"); - } else { - // ARB_geometry_shader4 also provides a version. - _glFramebufferTextureLayer = NULL; + } + + if (_supports_2d_texture_array && _glFramebufferTextureLayer == NULL) { + GLCAT.warning() + << "Texture arrays advertised as supported by OpenGL runtime, but could not get pointer to glFramebufferTextureLayer function.\n"; } #endif @@ -1316,20 +1325,40 @@ reset() { #endif // HAVE_CG -#ifdef OPENGLES_2 +#if defined(OPENGLES_1) + _supports_glsl = false; + _supports_geometry_shaders = false; + _supports_tessellation_shaders = false; +#elif defined(OPENGLES) _supports_glsl = true; _supports_geometry_shaders = false; _supports_tessellation_shaders = false; #else - #ifdef OPENGLES_1 - _supports_glsl = false; + _supports_glsl = is_at_least_gl_version(2, 0) || has_extension("GL_ARB_shading_language_100"); + _supports_tessellation_shaders = is_at_least_gl_version(4, 0) || has_extension("GL_ARB_tessellation_shader"); + + if (is_at_least_gl_version(3, 2)) { + _supports_geometry_shaders = true; + _glFramebufferTexture = (PFNGLFRAMEBUFFERTEXTUREARBPROC) + get_extension_func("glFramebufferTexture"); + + } else if (has_extension("GL_ARB_geometry_shader4")) { + _supports_geometry_shaders = true; + _glFramebufferTexture = (PFNGLFRAMEBUFFERTEXTUREARBPROC) + get_extension_func("glFramebufferTextureARB"); + _glProgramParameteri = (PFNGLPROGRAMPARAMETERIPROC) + get_extension_func("glProgramParameteriARB"); + + } else if (has_extension("GL_EXT_geometry_shader4")) { + _supports_geometry_shaders = true; + _glFramebufferTexture = NULL; + _glProgramParameteri = (PFNGLPROGRAMPARAMETERIPROC) + get_extension_func("glProgramParameteriEXT"); + + } else { _supports_geometry_shaders = false; - _supports_tessellation_shaders = false; - #else - _supports_glsl = is_at_least_gl_version(2, 0) || has_extension("GL_ARB_shading_language_100"); - _supports_geometry_shaders = is_at_least_gl_version(3, 2) || has_extension("GL_ARB_geometry_shader4"); - _supports_tessellation_shaders = is_at_least_gl_version(4, 0) || has_extension("GL_ARB_tessellation_shader"); - #endif + _glFramebufferTexture = NULL; + } #endif _shader_caps._supports_glsl = _supports_glsl; @@ -1435,17 +1464,6 @@ reset() { _glVertexAttribLPointer = NULL; } - if (_supports_geometry_shaders) { - _glProgramParameteri = (PFNGLPROGRAMPARAMETERIPROC) - get_extension_func("glProgramParameteri"); - _glFramebufferTexture = (PFNGLFRAMEBUFFERTEXTUREARBPROC) - get_extension_func("glFramebufferTextureARB"); - - if (_glFramebufferTextureLayer == NULL) { - _glFramebufferTextureLayer = (PFNGLFRAMEBUFFERTEXTURELAYERPROC) - get_extension_func("glFramebufferTextureLayerARB"); - } - } if (_supports_tessellation_shaders) { _glPatchParameteri = (PFNGLPATCHPARAMETERIPROC) get_extension_func("glPatchParameteri"); @@ -1611,7 +1629,7 @@ reset() { _glDrawElementsInstanced = (PFNGLDRAWELEMENTSINSTANCEDPROC) get_extension_func("glDrawElementsInstancedARB"); _supports_geometry_instancing = true; - + } else if (has_extension("GL_EXT_draw_instanced")) { _glDrawArraysInstanced = (PFNGLDRAWARRAYSINSTANCEDPROC) get_extension_func("glDrawArraysInstancedEXT"); @@ -2290,8 +2308,10 @@ reset() { if (is_at_least_gl_version(4, 1) || has_extension("GL_ARB_get_program_binary")) { _glGetProgramBinary = (PFNGLGETPROGRAMBINARYPROC) get_extension_func("glGetProgramBinary"); + _glProgramParameteri = (PFNGLPROGRAMPARAMETERIPROC) + get_extension_func("glProgramParameteri"); - if (_glGetProgramBinary != NULL) { + if (_glGetProgramBinary != NULL && _glProgramParameteri != NULL) { _supports_get_program_binary = true; } } diff --git a/panda/src/glstuff/glShaderContext_src.cxx b/panda/src/glstuff/glShaderContext_src.cxx index f2f0bd8a27..4602f60e7a 100644 --- a/panda/src/glstuff/glShaderContext_src.cxx +++ b/panda/src/glstuff/glShaderContext_src.cxx @@ -280,18 +280,29 @@ CLP(ShaderContext)(CLP(GraphicsStateGuardian) *glgsg, Shader *s) : ShaderContext return; } - // Create a buffer the size of the longest uniform name. + // Create a buffer the size of the longest uniform name. Note + // that Intel HD drivers report values that are too low. GLint name_buflen = 0; _glgsg->_glGetProgramiv(_glsl_program, GL_ACTIVE_UNIFORM_MAX_LENGTH, &name_buflen); - char* name_buffer = (char *)alloca(max(64, name_buflen)); + name_buflen = max(64, name_buflen); + char *name_buffer = (char *)alloca(name_buflen); #ifndef OPENGLES // Get the used uniform blocks. if (_glgsg->_supports_uniform_buffers) { - GLint block_count, block_maxlength; + GLint block_count = 0, block_maxlength = 0; _glgsg->_glGetProgramiv(_glsl_program, GL_ACTIVE_UNIFORM_BLOCKS, &block_count); - _glgsg->_glGetProgramiv(_glsl_program, GL_ACTIVE_UNIFORM_BLOCK_MAX_NAME_LENGTH, &block_maxlength); - char *block_name_cstr = (char *)alloca(max(64, block_maxlength)); + + // Intel HD drivers report GL_INVALID_ENUM here. They reportedly + // fixed it, but I don't know in which driver version the fix is. + if (_glgsg->_gl_vendor != "Intel") { + _glgsg->_glGetProgramiv(_glsl_program, GL_ACTIVE_UNIFORM_BLOCK_MAX_NAME_LENGTH, &block_maxlength); + block_maxlength = max(64, block_maxlength); + } else { + block_maxlength = 1024; + } + + char *block_name_cstr = (char *)alloca(block_maxlength); for (int i = 0; i < block_count; ++i) { block_name_cstr[0] = 0; @@ -319,7 +330,8 @@ CLP(ShaderContext)(CLP(GraphicsStateGuardian) *glgsg, Shader *s) : ShaderContext // Now we've processed the uniforms, we'll process the attribs. _glgsg->_glGetProgramiv(_glsl_program, GL_ACTIVE_ATTRIBUTES, ¶m_count); _glgsg->_glGetProgramiv(_glsl_program, GL_ACTIVE_ATTRIBUTE_MAX_LENGTH, &name_buflen); - name_buffer = (char *)alloca(max(64, name_buflen)); + name_buflen = max(64, name_buflen); + name_buffer = (char *)alloca(name_buflen); _shader->_var_spec.clear(); for (int i = 0; i < param_count; ++i) { @@ -2442,13 +2454,13 @@ glsl_compile_and_link() { if (!_shader->get_text(Shader::ST_geometry).empty()) { valid &= glsl_compile_shader(Shader::ST_geometry); - // Set the vertex output limit to the maximum. - // This is slow, but it is probably reasonable to require - // the user to override this in his shader using layout(). - nassertr(_glgsg->_glProgramParameteri != NULL, false); - GLint max_vertices; - glGetIntegerv(GL_MAX_GEOMETRY_OUTPUT_VERTICES, &max_vertices); - _glgsg->_glProgramParameteri(_glsl_program, GL_GEOMETRY_VERTICES_OUT_ARB, max_vertices); + //XXX Actually, it turns out that this is unavailable in the core + // version of geometry shaders. Probably no need to bother with it. + + //nassertr(_glgsg->_glProgramParameteri != NULL, false); + //GLint max_vertices; + //glGetIntegerv(GL_MAX_GEOMETRY_OUTPUT_VERTICES, &max_vertices); + //_glgsg->_glProgramParameteri(_glsl_program, GL_GEOMETRY_VERTICES_OUT_ARB, max_vertices); } #endif