瀏覽代碼

fix framebuffer_copy_to_texture

Not very efficient since it copies the entire render target to system memory
and then copies the rectangle to the texture, but there does not seem to
be another way for DX9.
aignacio_sf 20 年之前
父節點
當前提交
dd024406b1
共有 1 個文件被更改,包括 48 次插入8 次删除
  1. 48 8
      panda/src/dxgsg9/dxGraphicsStateGuardian9.cxx

+ 48 - 8
panda/src/dxgsg9/dxGraphicsStateGuardian9.cxx

@@ -1412,12 +1412,14 @@ framebuffer_copy_to_texture(Texture *tex, int z, const DisplayRegion *dr,
   DWORD render_target_index;
   IDirect3DSurface9 *render_target;
 
-/* ***** DX9 GetRenderTarget (render_target_index, ) */
-render_target_index = 0;
+  /* ***** DX9 GetRenderTarget, assume only one render target so index = 0 */
+  render_target_index = 0;
 
   hr = _d3d_device->GetRenderTarget(render_target_index, &render_target);
   if (FAILED(hr)) {
-    dxgsg9_cat.error() << "GetRenderTgt failed in copy_texture" << D3DERRORSTRING(hr);
+    dxgsg9_cat.error()
+      << "GetRenderTarget failed in framebuffer_copy_to_texture"
+      << D3DERRORSTRING(hr);
     SAFE_RELEASE(tex_level_0);
     return;
   }
@@ -1429,15 +1431,53 @@ render_target_index = 0;
   src_rect.top = yo;
   src_rect.bottom = yo+h;
 
-  // now copy from fb to tex
-
-/* ***** DX9 CopyRects */
+//  THE DX8 WAY
 //  hr = _d3d_device->CopyRects(render_target, &src_rect, 1, tex_level_0, 0);
-   hr = -1;
+
+//  THE DX9 WAY, this is not efficient since it copies the entire render
+//    target to system memory and then copies the rectangle to the texture
+
+  // create a surface in system memory that is a duplicate of the render target
+  D3DPOOL pool;
+  IDirect3DSurface9 *temp_surface = NULL;
+  D3DSURFACE_DESC surface_description;
+
+  render_target -> GetDesc (&surface_description);
+
+  pool = D3DPOOL_SYSTEMMEM;
+  hr = _d3d_device->CreateOffscreenPlainSurface(
+         surface_description.Width,
+         surface_description.Height,
+         surface_description.Format,
+         pool,
+         &temp_surface,
+         NULL);
+  if (FAILED(hr)) {
+    dxgsg9_cat.error()
+      << "CreateOffscreenPlainSurface failed in framebuffer_copy_to_texture"
+      << D3DERRORSTRING(hr);
+    return;
+  }
+
+  // this copies the entire render target into system memory
+  hr = _d3d_device -> GetRenderTargetData (render_target, temp_surface);
+
+  if (FAILED(hr)) {
+    dxgsg9_cat.error() << "GetRenderTargetData failed" << D3DERRORSTRING(hr);
+    RELEASE(temp_surface, dxgsg9, "temp_surface", RELEASE_ONCE);
+    return;
+  }
+
+  // copy system memory version to texture
+  DXTextureContext9::d3d_surface_to_texture(src_rect, temp_surface,
+              false, tex, z);
+
+  RELEASE(temp_surface, dxgsg9, "temp_surface", RELEASE_ONCE);
 
   if (FAILED(hr)) {
     dxgsg9_cat.error()
-      << "CopyRects failed in copy_texture" << D3DERRORSTRING(hr);
+      << "CopyRects failed in framebuffer_copy_to_texture"
+      << D3DERRORSTRING(hr);
   }
 
   SAFE_RELEASE(render_target);