Browse Source

Fixes for image binding

rdb 11 years ago
parent
commit
a726ccf303

+ 10 - 0
panda/src/glstuff/glGraphicsStateGuardian_src.cxx

@@ -1733,6 +1733,16 @@ reset() {
         << "ARB_multi_bind advertised as supported by OpenGL runtime, but could not get pointers to extension function.\n";
     }
   }
+
+  if (is_at_least_gl_version(4, 3) || has_extension("GL_ARB_internalformat_query2")) {
+    _glGetInternalformativ = (PFNGLGETINTERNALFORMATIVPROC)
+      get_extension_func("glGetInternalformativ");
+
+    if (_glGetInternalformativ == NULL) {
+      GLCAT.warning()
+        << "ARB_internalformat_query2 advertised as supported by OpenGL runtime, but could not get pointers to extension function.\n";
+    }
+  }
 #endif
 
 #ifndef OPENGLES

+ 2 - 0
panda/src/glstuff/glGraphicsStateGuardian_src.h

@@ -178,6 +178,7 @@ typedef void (APIENTRYP PFNGLBINDIMAGETEXTURESPROC) (GLuint first, GLsizei count
 typedef void (APIENTRYP PFNGLDISPATCHCOMPUTEPROC) (GLuint num_groups_x, GLuint num_groups_y, GLuint num_groups_z);
 typedef void (APIENTRYP PFNGLMEMORYBARRIERPROC) (GLbitfield barriers);
 typedef void (APIENTRYP PFNGLGETPROGRAMBINARYPROC) (GLuint program, GLsizei bufsize, GLsizei *length, GLenum *binaryFormat, void *binary);
+typedef void (APIENTRYP PFNGLGETINTERNALFORMATIVPROC) (GLenum target, GLenum internalformat, GLenum pname, GLsizei bufSize, GLint *params); 
 #endif  // OPENGLES
 #endif  // __EDG__
 
@@ -707,6 +708,7 @@ public:
   PFNGLDISPATCHCOMPUTEPROC _glDispatchCompute;
   PFNGLMEMORYBARRIERPROC _glMemoryBarrier;
   PFNGLGETPROGRAMBINARYPROC _glGetProgramBinary;
+  PFNGLGETINTERNALFORMATIVPROC _glGetInternalformativ;
 #endif  // OPENGLES
 
   GLenum _edge_clamp;

+ 50 - 49
panda/src/glstuff/glShaderContext_src.cxx

@@ -1099,6 +1099,56 @@ update_shader_texture_bindings(ShaderContext *prev) {
     return;
   }
 
+#ifndef OPENGLES
+  // First bind all the 'image units'; a bit of an esoteric OpenGL feature right now.
+  int num_image_units = min(_glsl_img_inputs.size(), (size_t)_glgsg->_max_image_units);
+
+  if (num_image_units > 0) {
+    GLuint *multi_img = NULL;
+    // If we support multi-bind, prepare an array.
+    if (_glgsg->_supports_multi_bind) {
+      multi_img = new GLuint[num_image_units];
+    }
+
+    for (int i = 0; i < num_image_units; ++i) {
+      const InternalName *name = _glsl_img_inputs[i];
+      Texture *tex = _glgsg->_target_shader->get_shader_input_texture(name);
+
+      GLuint gl_tex = 0;
+      if (tex != NULL) {
+        int view = _glgsg->get_current_tex_view_offset();
+
+        CLP(TextureContext) *gtc = DCAST(CLP(TextureContext), tex->prepare_now(view, _glgsg->_prepared_objects, _glgsg));
+        if (gtc != (TextureContext*)NULL) {
+          gl_tex = gtc->_index;
+          _glgsg->update_texture(gtc, true);
+        }
+      }
+
+      if (multi_img != NULL) {
+        // Put in array so we can multi-bind later.
+        multi_img[i] = gl_tex;
+
+      } else {
+        // We don't support multi-bind, so bind now in the same way that multi-bind would have done it.
+        if (gl_tex == 0) {
+          _glgsg->_glBindImageTexture(i, 0, 0, GL_FALSE, 0, GL_READ_ONLY, GL_R8);
+        } else {
+          //TODO: automatically convert to sized type instead of plain GL_RGBA
+          // If a base type is used, it will crash.
+          GLint internal_format = _glgsg->get_internal_image_format(tex);
+          _glgsg->_glBindImageTexture(i, gl_tex, 0, GL_TRUE, 0, GL_READ_WRITE, internal_format);
+        }
+      }
+    }
+
+    if (multi_img != NULL) {
+      _glgsg->_glBindImageTextures(0, num_image_units, multi_img);
+      delete[] multi_img;
+    }
+  }
+#endif
+
   // We get the TextureAttrib directly from the _target_rs, not the
   // filtered TextureAttrib in _target_texture.
   const TextureAttrib *texattrib = DCAST(TextureAttrib, _glgsg->_target_rs->get_attrib_def(TextureAttrib::get_class_slot()));
@@ -1157,55 +1207,6 @@ update_shader_texture_bindings(ShaderContext *prev) {
     }
   }
 
-#ifndef OPENGLES
-  // Now bind all the 'image units'; a bit of an esoteric OpenGL feature right now.
-  int num_image_units = min(_glsl_img_inputs.size(), (size_t)_glgsg->_max_image_units);
-
-  if (num_image_units > 0) {
-    GLuint *multi_img = NULL;
-    // If we support multi-bind, prepare an array.
-    if (_glgsg->_supports_multi_bind && num_image_units > 1) {
-      multi_img = new GLuint[num_image_units];
-    }
-
-    for (int i = 0; i < num_image_units; ++i) {
-      const InternalName *name = _glsl_img_inputs[i];
-      Texture *tex = _glgsg->_target_shader->get_shader_input_texture(name);
-
-      GLuint gl_tex = 0;
-      if (tex != NULL) {
-        int view = _glgsg->get_current_tex_view_offset();
-
-        CLP(TextureContext) *gtc = DCAST(CLP(TextureContext), tex->prepare_now(view, _glgsg->_prepared_objects, _glgsg));
-        if (gtc != (TextureContext*)NULL) {
-          gl_tex = gtc->_index;
-          _glgsg->update_texture(gtc, true);
-        }
-      }
-
-      if (multi_img != NULL) {
-        // Put in array so we can multi-bind later.
-        multi_img[i] = gl_tex;
-
-      } else {
-        // We don't support multi-bind, so bind now in the same way that multi-bind would have done it.
-        if (gl_tex == 0) {
-          _glgsg->_glBindImageTexture(i, 0, 0, GL_FALSE, 0, GL_READ_ONLY, GL_R8);
-        } else {
-          //TODO: automatically convert to sized type instead of plain GL_RGBA
-          GLint internal_format = _glgsg->get_internal_image_format(tex);
-          _glgsg->_glBindImageTexture(i, gl_tex, 0, GL_TRUE, 0, GL_READ_WRITE, internal_format);
-        }
-      }
-    }
-
-    if (multi_img != NULL) {
-      _glgsg->_glBindImageTextures(0, num_image_units, multi_img);
-      delete[] multi_img;
-    }
-  }
-#endif
-
   _glgsg->report_my_gl_errors();
 }