diff --git a/panda/src/glstuff/glGraphicsBuffer_src.cxx b/panda/src/glstuff/glGraphicsBuffer_src.cxx index dd9b1e1348..46ac9a7ba6 100644 --- a/panda/src/glstuff/glGraphicsBuffer_src.cxx +++ b/panda/src/glstuff/glGraphicsBuffer_src.cxx @@ -409,20 +409,19 @@ rebuild_bitplanes() { // Now create the FBO's. _have_any_color = false; - _fbo.reserve(num_fbos); - for (int layer = 0; layer < num_fbos; ++layer) { - if (layer >= _fbo.size()) { - _fbo.push_back(0); - } + if (num_fbos > _fbo.size()) { + // Generate more FBO handles. + int start = _fbo.size(); + _fbo.resize(num_fbos, 0); + glgsg->_glGenFramebuffers(num_fbos - start, &_fbo[start]); + } + + for (int layer = 0; layer < num_fbos; ++layer) { // Bind the FBO if (_fbo[layer] == 0) { - glgsg->_glGenFramebuffers(1, &_fbo[layer]); - - if (_fbo[layer] == 0) { - report_my_gl_errors(); - return; - } + report_my_gl_errors(); + return; } glgsg->bind_fbo(_fbo[layer]); @@ -1118,11 +1117,7 @@ generate_mipmaps() { CLP(TextureContext) *gtc = *it; if (gtc->_generate_mipmaps) { - glgsg->_state_texture = 0; - glgsg->update_texture(gtc, true); - glgsg->apply_texture(gtc); - glgsg->_glGenerateMipmap(gtc->_target); - glBindTexture(gtc->_target, 0); + glgsg->generate_mipmaps(gtc); } } diff --git a/panda/src/glstuff/glGraphicsStateGuardian_src.cxx b/panda/src/glstuff/glGraphicsStateGuardian_src.cxx index 8d375e9dc4..bd797c249f 100644 --- a/panda/src/glstuff/glGraphicsStateGuardian_src.cxx +++ b/panda/src/glstuff/glGraphicsStateGuardian_src.cxx @@ -1877,6 +1877,15 @@ reset() { #endif // OPENGLES #endif +#ifndef OPENGLES + if (is_at_least_gl_version(4, 5) || has_extension("GL_ARB_direct_state_access")) { + _glGenerateTextureMipmap = (PFNGLGENERATETEXTUREMIPMAPPROC) + get_extension_func("glGenerateTextureMipmap"); + } else { + _glGenerateTextureMipmap = NULL; + } +#endif + _supports_framebuffer_multisample = false; if ( has_extension("GL_EXT_framebuffer_multisample") ) { _supports_framebuffer_multisample = true; @@ -11760,6 +11769,31 @@ upload_texture_image(CLP(TextureContext) *gtc, bool needs_reload, return true; } +//////////////////////////////////////////////////////////////////// +// Function: GLGraphicsStateGuardian::generate_mipmaps +// Access: Protected +// Description: Causes mipmaps to be generated for an uploaded +// texture. +//////////////////////////////////////////////////////////////////// +void CLP(GraphicsStateGuardian):: +generate_mipmaps(CLP(TextureContext) *gtc) { +#ifndef OPENGLES + if (_glGenerateTextureMipmap != NULL) { + // OpenGL 4.5 offers an easy way to do this without binding. + _glGenerateTextureMipmap(gtc->_index); + return; + } +#endif + + if (_glGenerateMipmap != NULL) { + _state_texture = 0; + update_texture(gtc, true); + apply_texture(gtc); + _glGenerateMipmap(gtc->_target); + glBindTexture(gtc->_target, 0); + } +} + //////////////////////////////////////////////////////////////////// // Function: GLGraphicsStateGuardian::upload_simple_texture // Access: Protected diff --git a/panda/src/glstuff/glGraphicsStateGuardian_src.h b/panda/src/glstuff/glGraphicsStateGuardian_src.h index 62df6fe84c..7d5f796140 100644 --- a/panda/src/glstuff/glGraphicsStateGuardian_src.h +++ b/panda/src/glstuff/glGraphicsStateGuardian_src.h @@ -546,6 +546,7 @@ protected: GLenum component_type, bool one_page_only, int z, Texture::CompressionMode image_compression); + void generate_mipmaps(CLP(TextureContext) *gtc); bool upload_simple_texture(CLP(TextureContext) *gtc); size_t get_texture_memory_size(CLP(TextureContext) *gtc); @@ -794,6 +795,10 @@ public: PFNGLGENERATEMIPMAPEXTPROC _glGenerateMipmap; PFNGLBINDPROGRAMARBPROC _glBindProgram; +#ifndef OPENGLES + PFNGLGENERATETEXTUREMIPMAPPROC _glGenerateTextureMipmap; +#endif + bool _supports_framebuffer_multisample; bool _supports_framebuffer_multisample_coverage_nv; INLINE bool get_supports_framebuffer_multisample();