Ver Fonte

fix render-to-texture issue

David Rose há 17 anos atrás
pai
commit
a019d736ec

+ 1 - 2
panda/src/display/graphicsOutput.cxx

@@ -591,8 +591,7 @@ get_active_display_region(int n) const {
 //  Description: Generates a GeomVertexData for a texture card.
 ////////////////////////////////////////////////////////////////////
 PT(GeomVertexData) GraphicsOutput::
-create_texture_card_vdata(int x, int y)
-{
+create_texture_card_vdata(int x, int y) {
   float xhi = 1.0;
   float yhi = 1.0;
 

+ 8 - 6
panda/src/display/parasiteBuffer.cxx

@@ -92,12 +92,14 @@ set_size(int x, int y) {
 ////////////////////////////////////////////////////////////////////
 void ParasiteBuffer::
 set_size_and_recalc(int x, int y) {
-  if (_creation_flags & GraphicsPipe::BF_size_power_2) {
-    x = Texture::down_to_power_2(x);
-    y = Texture::down_to_power_2(y);
-  }
-  if (_creation_flags & GraphicsPipe::BF_size_square) {
-    x = y = min(x, y);
+  if (!(_creation_flags & GraphicsPipe::BF_size_track_host)) {
+    if (_creation_flags & GraphicsPipe::BF_size_power_2) {
+      x = Texture::down_to_power_2(x);
+      y = Texture::down_to_power_2(y);
+    }
+    if (_creation_flags & GraphicsPipe::BF_size_square) {
+      x = y = min(x, y);
+    }
   }
 
   GraphicsOutput::set_size_and_recalc(x, y);

+ 27 - 3
panda/src/glstuff/glGraphicsStateGuardian_src.cxx

@@ -3442,6 +3442,8 @@ framebuffer_copy_to_texture(Texture *tex, int z, const DisplayRegion *dr,
 
   GLenum target = get_texture_target(tex->get_texture_type());
   GLint internal_format = get_internal_image_format(tex);
+  int width = tex->get_x_size();
+  int height = tex->get_y_size();
 
   bool uses_mipmaps = tex->uses_mipmaps() && !CLP(ignore_mipmaps);
   if (uses_mipmaps) {
@@ -3455,8 +3457,13 @@ framebuffer_copy_to_texture(Texture *tex, int z, const DisplayRegion *dr,
   }
 
   bool new_image = needs_reload || gtc->was_image_modified();
-  if (internal_format != gtc->_internal_format) {
-    // If the internal format has changed, we need to reload the
+  if (!gtc->_already_applied ||
+      internal_format != gtc->_internal_format ||
+      uses_mipmaps != gtc->_uses_mipmaps ||
+      width != gtc->_width ||
+      height != gtc->_height ||
+      1 != gtc->_depth) {
+    // If the texture properties have changed, we need to reload the
     // image.
     new_image = true;
   }
@@ -3471,12 +3478,29 @@ framebuffer_copy_to_texture(Texture *tex, int z, const DisplayRegion *dr,
 
   if (new_image) {
     // We have to create a new image.
-    GLP(CopyTexImage2D)(target, 0, internal_format, xo, yo, w, h, 0);
+    if (w != width || h != height) {
+      // This means a two-step process, to create a texture of the
+      // appropriate size.
+      GLP(TexImage2D)(target, 0, internal_format, width, height, 0,
+                      GL_RGBA, GL_UNSIGNED_BYTE, NULL);
+      GLP(CopyTexSubImage2D)(target, 0, 0, 0, xo, yo, w, h);
+
+    } else {
+      // One-step process.
+      GLP(CopyTexImage2D)(target, 0, internal_format, xo, yo, w, h, 0);
+    }
   } else {
     // We can overlay the existing image.
     GLP(CopyTexSubImage2D)(target, 0, 0, 0, xo, yo, w, h);
   }
 
+  gtc->_already_applied = true;
+  gtc->_uses_mipmaps = uses_mipmaps;
+  gtc->_internal_format = internal_format;
+  gtc->_width = width;
+  gtc->_height = height;
+  gtc->_depth = 1;
+
   gtc->mark_loaded();
   gtc->enqueue_lru(&_prepared_objects->_graphics_memory_lru);
 

+ 5 - 0
panda/src/glstuff/glTextureContext_src.I

@@ -24,4 +24,9 @@ CLP(TextureContext)(PreparedGraphicsObjects *pgo, Texture *tex) :
 {
   _index = 0;
   _already_applied = false;
+  _uses_mipmaps = false;
+  _internal_format = 0;
+  _width = 0;
+  _height = 0;
+  _depth = 0;
 }