Browse Source

preliminary version

aignacio_sf 20 years ago
parent
commit
4c14e47297
2 changed files with 551 additions and 0 deletions
  1. 458 0
      panda/src/dxgsg9/wdxGraphicsBuffer9.cxx
  2. 93 0
      panda/src/dxgsg9/wdxGraphicsBuffer9.h

+ 458 - 0
panda/src/dxgsg9/wdxGraphicsBuffer9.cxx

@@ -0,0 +1,458 @@
+// Filename: wdxGraphicsBuffer9.cxx
+// Created by:  drose (08Feb04)
+//
+////////////////////////////////////////////////////////////////////
+//
+// PANDA 3D SOFTWARE
+// Copyright (c) 2001 - 2005, Disney Enterprises, Inc.  All rights reserved
+//
+// All use of this software is subject to the terms of the Panda 3d
+// Software license.  You should have received a copy of this license
+// along with this source code; you will also find a current copy of
+// the license at http://etc.cmu.edu/panda3d/docs/license/ .
+//
+// To contact the maintainers of this program write to
+// [email protected] .
+//
+////////////////////////////////////////////////////////////////////
+
+#include "wdxGraphicsPipe9.h"
+#include "wdxGraphicsBuffer9.h"
+#include "pStatTimer.h"
+
+
+TypeHandle wdxGraphicsBuffer9::_type_handle;
+
+
+////////////////////////////////////////////////////////////////////
+//     Function: wdxGraphicsBuffer9::Constructor
+//       Access: Public
+//  Description:
+////////////////////////////////////////////////////////////////////
+wdxGraphicsBuffer9::
+wdxGraphicsBuffer9(GraphicsPipe *pipe, GraphicsStateGuardian *gsg,
+                  const string &name,
+                  int x_size, int y_size) :
+  GraphicsBuffer(pipe, gsg, name, x_size, y_size)
+{
+  // initialize all class members
+  _cube_map_index = -1;
+  _back_buffer = NULL;
+  _z_stencil_buffer = NULL;
+
+  // Since the pbuffer never gets flipped, we get screenshots from the
+  // same buffer we draw into.
+  _screenshot_buffer_type = _draw_buffer_type;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: wdxGraphicsBuffer9::Destructor
+//       Access: Public, Virtual
+//  Description:
+////////////////////////////////////////////////////////////////////
+wdxGraphicsBuffer9::
+~wdxGraphicsBuffer9() {
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: wdxGraphicsBuffer9::begin_frame
+//       Access: Public, Virtual
+//  Description: This function will be called within the draw thread
+//               before beginning rendering for a given frame.  It
+//               should do whatever setup is required, and return true
+//               if the frame should be rendered, or false if it
+//               should be skipped.
+////////////////////////////////////////////////////////////////////
+bool wdxGraphicsBuffer9::
+begin_frame() {
+  if (_gsg == (GraphicsStateGuardian *)NULL) {
+    return false;
+  }
+
+  DXGraphicsStateGuardian9 *dxgsg;
+  DCAST_INTO_R(dxgsg, _gsg, false);
+
+  return GraphicsBuffer::begin_frame();
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: wglGraphicsStateGuardian::begin_render_texture
+//       Access: Public, Virtual
+//  Description: If the GraphicsOutput supports direct render-to-texture,
+//               and if any setup needs to be done during begin_frame,
+//               then the setup code should go here.  Any textures that
+//               can not be rendered to directly should be reflagged
+//               as RTM_copy_texture.
+////////////////////////////////////////////////////////////////////
+void wdxGraphicsBuffer9::
+begin_render_texture() {
+  DXGraphicsStateGuardian9 *dxgsg;
+  DCAST_INTO_V(dxgsg, _gsg);
+
+HRESULT hr;
+bool state;
+int render_target_index;
+
+  state = false;
+  render_target_index = 0;
+
+  // save render context
+  hr = dxgsg -> _d3d_device -> GetRenderTarget (render_target_index, &_back_buffer);
+  if (SUCCEEDED (hr)) {
+    hr = dxgsg -> _d3d_device -> GetDepthStencilSurface (&_z_stencil_buffer);
+    if (SUCCEEDED (hr)) {
+      state = TRUE;
+    }
+  }
+  // set render context
+  if (state && _dx_texture_context9)
+  {
+
+  int tex_index;
+  DXTextureContext9 *dx_texture_context9;
+
+// **** ??? assume 0
+  tex_index = 0;
+
+  Texture *tex = get_texture(tex_index);
+
+// ***** ??? CAST
+
+  dx_texture_context9 = _dx_texture_context9;
+
+    UINT mipmap_level;
+
+    mipmap_level = 0;
+    _direct_3d_surface = NULL;
+
+IDirect3DTexture9 *direct_3d_texture;
+
+direct_3d_texture = dx_texture_context9 -> _d3d_2d_texture;
+
+    if (direct_3d_texture) {
+      hr = direct_3d_texture -> GetSurfaceLevel (mipmap_level, &_direct_3d_surface);
+      if (SUCCEEDED (hr)) {
+        hr = dxgsg -> _d3d_device -> SetRenderTarget (render_target_index, _direct_3d_surface);
+        if (SUCCEEDED (hr)) {
+
+        }
+      }
+    }
+
+IDirect3DCubeTexture9 *direct_3d_cube_texture;
+
+direct_3d_cube_texture = dx_texture_context9 -> _d3d_cube_texture;
+
+    if (direct_3d_cube_texture) {
+
+// ***** check for legal cubemap index
+
+      hr = direct_3d_cube_texture -> GetCubeMapSurface ((D3DCUBEMAP_FACES) _cube_map_index, mipmap_level, &_direct_3d_surface);
+      if (SUCCEEDED (hr)) {
+        hr = dxgsg -> _d3d_device -> SetRenderTarget (render_target_index, _direct_3d_surface);
+        if (SUCCEEDED (hr)) {
+
+        }
+      }
+    }
+  }
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: GraphicsOutput::end_render_texture
+//       Access: Public, Virtual
+//  Description: If the GraphicsOutput supports direct render-to-texture,
+//               and if any setup needs to be done during end_frame,
+//               then the setup code should go here.  Any textures that
+//               could not be rendered to directly should be reflagged
+//               as RTM_copy_texture.
+////////////////////////////////////////////////////////////////////
+void wdxGraphicsBuffer9::
+end_render_texture() {
+  DXGraphicsStateGuardian9 *dxgsg;
+  DCAST_INTO_V(dxgsg, _gsg);
+
+  // Find the color texture, if there is one. That one can be bound to
+  // the framebuffer.  All others must be marked RTM_copy_to_texture.
+
+  int tex_index = -1;
+  for (int i=0; i<count_textures(); i++) {
+    if (get_rtm_mode(i) == RTM_bind_or_copy) {
+      if ((get_texture(i)->get_format() != Texture::F_depth_component)&&
+          (get_texture(i)->get_format() != Texture::F_stencil_index)&&
+          (tex_index < 0)) {
+        tex_index = i;
+      } else {
+        _textures[i]._rtm_mode = RTM_copy_texture;
+      }
+    }
+  }
+
+// ???
+  if (tex_index >= 0) {
+    Texture *tex = get_texture(tex_index);
+    TextureContext *tc = tex->prepare_now(_gsg->get_prepared_objects(), _gsg);
+    nassertv(tc != (TextureContext *)NULL);
+  }
+
+  // restore render context
+  HRESULT hr;
+  int render_target_index;
+  render_target_index = 0;
+
+  if (_back_buffer) {
+    hr = dxgsg -> _d3d_device -> SetRenderTarget (render_target_index, _back_buffer);
+    if (SUCCEEDED (hr)) {
+      _back_buffer -> Release ( );
+    }
+    _back_buffer = NULL;
+  }
+  if (_z_stencil_buffer) {
+    hr = dxgsg -> _d3d_device -> SetDepthStencilSurface (_z_stencil_buffer);
+    if (SUCCEEDED (hr)) {
+      _z_stencil_buffer -> Release ( );
+    }
+    _z_stencil_buffer = NULL;
+  }
+  if (_direct_3d_surface) {
+    _direct_3d_surface -> Release ( );
+    _direct_3d_surface = NULL;
+  }
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: wdxGraphicsBuffer9::select_cube_map
+//       Access: Public, Virtual
+//  Description: Called internally when the window is in
+//               render-to-a-texture mode and we are in the process of
+//               rendering the six faces of a cube map.  This should
+//               do whatever needs to be done to switch the buffer to
+//               the indicated face.
+////////////////////////////////////////////////////////////////////
+void wdxGraphicsBuffer9::
+select_cube_map(int cube_map_index) {
+  DXGraphicsStateGuardian9 *dxgsg;
+  DCAST_INTO_V(dxgsg, _gsg);
+
+  _cube_map_index = cube_map_index;
+
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: wdxGraphicsBuffer9::make_current
+//       Access: Public, Virtual
+//  Description: This function will be called within the draw thread
+//               during begin_frame() to ensure the graphics context
+//               is ready for drawing.
+////////////////////////////////////////////////////////////////////
+void wdxGraphicsBuffer9::
+make_current() {
+  PStatTimer timer(_make_current_pcollector);
+
+  DXGraphicsStateGuardian9 *dxgsg;
+  DCAST_INTO_V(dxgsg, _gsg);
+
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: wdxGraphicsBuffer9::release_gsg
+//       Access: Public, Virtual
+//  Description: Releases the current GSG pointer, if it is currently
+//               held, and resets the GSG to NULL.  The window will be
+//               permanently unable to render; this is normally called
+//               only just before destroying the window.  This should
+//               only be called from within the draw thread.
+////////////////////////////////////////////////////////////////////
+void wdxGraphicsBuffer9::
+release_gsg() {
+  GraphicsBuffer::release_gsg();
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: wdxGraphicsBuffer9::process_events
+//       Access: Public, Virtual
+//  Description: Do whatever processing is necessary to ensure that
+//               the window responds to user events.  Also, honor any
+//               requests recently made via request_properties()
+//
+//               This function is called only within the window
+//               thread.
+////////////////////////////////////////////////////////////////////
+void wdxGraphicsBuffer9::
+process_events() {
+  GraphicsBuffer::process_events();
+
+  MSG msg;
+
+  // Handle all the messages on the queue in a row.  Some of these
+  // might be for another window, but they will get dispatched
+  // appropriately.
+  while (PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE)) {
+    process_1_event();
+  }
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: wdxGraphicsBuffer9::close_buffer
+//       Access: Protected, Virtual
+//  Description: Closes the buffer right now.  Called from the window
+//               thread.
+////////////////////////////////////////////////////////////////////
+void wdxGraphicsBuffer9::
+close_buffer() {
+  if (_gsg != (GraphicsStateGuardian *)NULL) {
+    DXGraphicsStateGuardian9 *dxgsg;
+    DCAST_INTO_V(dxgsg, _gsg);
+
+// ***** release render texture
+
+
+
+  }
+
+  _cube_map_index = -1;
+
+  _is_valid = false;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: wdxGraphicsBuffer9::open_buffer
+//       Access: Protected, Virtual
+//  Description: Opens the window right now.  Called from the window
+//               thread.  Returns true if the window is successfully
+//               opened, or false if there was a problem.
+////////////////////////////////////////////////////////////////////
+bool wdxGraphicsBuffer9::
+open_buffer() {
+  DXGraphicsStateGuardian9 *dxgsg;
+  DCAST_INTO_R(dxgsg, _gsg, false);
+
+  // create texture
+  int tex_index;
+  UINT texture_depth;
+  DXTextureContext9 *dx_texture_context9;
+
+// **** ??? assume 0
+  tex_index = 0;
+  texture_depth = 1;
+
+  Texture *tex = get_texture(tex_index);
+  TextureContext *tc = tex->prepare_now(_gsg->get_prepared_objects(), _gsg);
+
+// free managed texture ???
+
+
+
+// ***** ??? CAST
+  dx_texture_context9 = (DXTextureContext9 *) tc;
+
+// cache dx_texture_context9
+_dx_texture_context9 = dx_texture_context9;
+
+  // create render texture
+  create_render_texture (get_x_size ( ), get_y_size ( ), texture_depth,
+    dxgsg -> _render_to_texture_d3d_format, dx_texture_context9,
+    dxgsg -> _d3d_device);
+
+  dx_texture_context9 -> _d3d_format = dxgsg -> _render_to_texture_d3d_format;
+
+  _is_valid = true;
+
+  return true;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: wdxGraphicsBuffer9::process_1_event
+//       Access: Private, Static
+//  Description: Handles one event from the message queue.
+////////////////////////////////////////////////////////////////////
+void wdxGraphicsBuffer9::
+process_1_event() {
+  MSG msg;
+
+  if (!GetMessage(&msg, NULL, 0, 0)) {
+    // WM_QUIT received.  We need a cleaner way to deal with this.
+    //    DestroyAllWindows(false);
+    exit(msg.wParam);  // this will invoke AtExitFn
+  }
+
+  // Translate virtual key messages
+  TranslateMessage(&msg);
+  // Call window_proc
+  DispatchMessage(&msg);
+}
+
+
+bool wdxGraphicsBuffer9::
+create_render_texture (UINT texture_width, UINT texture_height, UINT texture_depth, D3DFORMAT texture_format, DXTextureContext9 *dx_texture_context9, IDirect3DDevice9 *direct_3d_device)
+{
+  bool state;
+  HRESULT hr;
+  DWORD usage;
+  D3DPOOL pool;
+  UINT mip_level_count;
+  D3DFORMAT pixel_format;
+  int texture_type;
+
+  state = false;
+
+  texture_type = dx_texture_context9 -> _texture -> get_texture_type ( );
+
+  // assume 1 mip level
+  mip_level_count = 1;
+
+  // REQUIRED pool and usage
+  pool = D3DPOOL_DEFAULT;
+  usage = D3DUSAGE_RENDERTARGET;
+
+// ???
+// usage |= D3DUSAGE_DYNAMIC;
+
+  pixel_format = texture_format;
+
+  switch (texture_type)
+  {
+    case Texture::TT_2d_texture:
+        hr = direct_3d_device->CreateTexture
+        (texture_width, texture_height, mip_level_count, usage,
+        pixel_format, pool, &dx_texture_context9 -> _d3d_2d_texture, NULL);
+        dx_texture_context9 -> _d3d_texture = dx_texture_context9 -> _d3d_2d_texture;
+        break;
+
+    case Texture::TT_3d_texture:
+        hr = direct_3d_device->CreateVolumeTexture
+        (texture_width, texture_height, texture_depth, mip_level_count, usage,
+        pixel_format, pool, &dx_texture_context9 -> _d3d_volume_texture, NULL);
+        dx_texture_context9 -> _d3d_texture = dx_texture_context9 -> _d3d_volume_texture;
+        break;
+
+    case Texture::TT_cube_map:
+        hr = direct_3d_device->CreateCubeTexture
+        (texture_width, mip_level_count, usage,
+        pixel_format, pool, &dx_texture_context9 -> _d3d_cube_texture, NULL);
+        dx_texture_context9 -> _d3d_texture = dx_texture_context9 -> _d3d_cube_texture;
+        break;
+
+    default:
+        break;
+  }
+
+  if (FAILED(hr)) {
+    dxgsg9_cat.error()
+      << "create_render_texture failed" << D3DERRORSTRING(hr);
+  }
+  else {
+    state = true;
+  }
+
+  return state;
+}
+
+// ISSUES:
+    // check size issues
+        // original frame buffer width, height
+    // render to texure format
+    // bind / set texture with which texture stage
+    // LOST DEVICE case for D3DPOOL_DEFAULT buffers
+    // CheckDepthStencilMatch
+    // ? check D3DCAPS2_DYNAMICTEXTURES

+ 93 - 0
panda/src/dxgsg9/wdxGraphicsBuffer9.h

@@ -0,0 +1,93 @@
+// Filename: wdxGraphicsBuffer9.h
+// Created by:  drose (08Feb04)
+//
+////////////////////////////////////////////////////////////////////
+//
+// PANDA 3D SOFTWARE
+// Copyright (c) 2001 - 2005, Disney Enterprises, Inc.  All rights reserved
+//
+// All use of this software is subject to the terms of the Panda 3d
+// Software license.  You should have received a copy of this license
+// along with this source code; you will also find a current copy of
+// the license at http://etc.cmu.edu/panda3d/docs/license/ .
+//
+// To contact the maintainers of this program write to
+// [email protected] .
+//
+////////////////////////////////////////////////////////////////////
+
+#ifndef wdxGraphicsBuffer9_H
+#define wdxGraphicsBuffer9_H
+
+#include "pandabase.h"
+#include "graphicsBuffer.h"
+#include "dxgsg9base.h"
+
+
+////////////////////////////////////////////////////////////////////
+//       Class : wdxGraphicsBuffer9
+// Description : An offscreen render buffer.  In OpenGL under Windows,
+//               this simply renders into a window that is never made
+//               visible.  There's a Windows interface for rendering
+//               into a DIB, but this puts restrictions on the kind of
+//               pixelformat we can use, and thus makes it difficult
+//               to support one GSG rendering into an offscreen buffer
+//               and also into a window.
+////////////////////////////////////////////////////////////////////
+class EXPCL_PANDADX wdxGraphicsBuffer9 : public GraphicsBuffer {
+public:
+  wdxGraphicsBuffer9(GraphicsPipe *pipe, GraphicsStateGuardian *gsg,
+                    const string &name,
+                    int x_size, int y_size);
+  virtual ~wdxGraphicsBuffer9();
+
+  virtual bool begin_frame();
+  virtual void select_cube_map(int cube_map_index);
+
+  virtual void make_current();
+  virtual void release_gsg();
+
+  virtual void begin_render_texture();
+  virtual void end_render_texture();
+
+  virtual void process_events();
+
+protected:
+  virtual void close_buffer();
+  virtual bool open_buffer();
+
+private:
+  static void process_1_event();
+
+  int _cube_map_index;
+  IDirect3DSurface9 *_back_buffer;
+  IDirect3DSurface9 *_z_stencil_buffer;
+  IDirect3DSurface9 *_direct_3d_surface;
+  DXTextureContext9 *_dx_texture_context9;
+
+public:
+  static TypeHandle get_class_type() {
+    return _type_handle;
+  }
+  static void init_type() {
+    GraphicsBuffer::init_type();
+    register_type(_type_handle, "wdxGraphicsBuffer9",
+                  GraphicsBuffer::get_class_type());
+  }
+  virtual TypeHandle get_type() const {
+    return get_class_type();
+  }
+  virtual TypeHandle force_init_type() {init_type(); return get_class_type();}
+
+  bool create_render_texture (UINT texture_width, UINT texture_height, UINT texture_depth, D3DFORMAT texture_format, DXTextureContext9 *dx_texture_context9, IDirect3DDevice9 *direct_3d_device);
+
+private:
+  static TypeHandle _type_handle;
+
+  friend class DXGraphicsStateGuardian9;
+  friend class DXTextureContext9;
+};
+
+// #include "wdxGraphicsBuffer9.I"
+
+#endif