Browse Source

add glxGraphicsBuffer

David Rose 22 years ago
parent
commit
fbca2647f9

+ 5 - 4
panda/src/glxdisplay/Sources.pp

@@ -11,13 +11,14 @@
 
   #define SOURCES \
     config_glxdisplay.cxx config_glxdisplay.h \
-    glxGraphicsPipe.I glxGraphicsPipe.cxx \
-    glxGraphicsPipe.h glxGraphicsWindow.I glxGraphicsWindow.cxx \
+    glxGraphicsBuffer.h glxGraphicsBuffer.I glxGraphicsBuffer.cxx \
+    glxGraphicsPipe.I glxGraphicsPipe.cxx glxGraphicsPipe.h \
+    glxGraphicsWindow.h glxGraphicsWindow.I glxGraphicsWindow.cxx \
     glxGraphicsStateGuardian.h glxGraphicsStateGuardian.I \
-    glxGraphicsStateGuardian.cxx \
-    glxGraphicsWindow.h
+    glxGraphicsStateGuardian.cxx
 
   #define INSTALL_HEADERS \
+    glxGraphicsBuffer.I glxGraphicsBuffer.h \
     glxGraphicsPipe.I glxGraphicsPipe.h \
     glxGraphicsWindow.I glxGraphicsWindow.h
 

+ 2 - 0
panda/src/glxdisplay/config_glxdisplay.cxx

@@ -17,6 +17,7 @@
 ////////////////////////////////////////////////////////////////////
 
 #include "config_glxdisplay.h"
+#include "glxGraphicsBuffer.h"
 #include "glxGraphicsPipe.h"
 #include "glxGraphicsWindow.h"
 #include "glxGraphicsStateGuardian.h"
@@ -46,6 +47,7 @@ init_libglxdisplay() {
   }
   initialized = true;
 
+  glxGraphicsBuffer::init_type();
   glxGraphicsPipe::init_type();
   glxGraphicsWindow::init_type();
   glxGraphicsStateGuardian::init_type();

+ 18 - 0
panda/src/glxdisplay/glxGraphicsBuffer.I

@@ -0,0 +1,18 @@
+// Filename: glxGraphicsBuffer.I
+// Created by:  drose (09Feb04)
+//
+////////////////////////////////////////////////////////////////////
+//
+// PANDA 3D SOFTWARE
+// Copyright (c) 2001, 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://www.panda3d.org/license.txt .
+//
+// To contact the maintainers of this program write to
+// [email protected] .
+//
+////////////////////////////////////////////////////////////////////
+

+ 193 - 0
panda/src/glxdisplay/glxGraphicsBuffer.cxx

@@ -0,0 +1,193 @@
+// Filename: glxGraphicsBuffer.cxx
+// Created by:  drose (09Feb04)
+//
+////////////////////////////////////////////////////////////////////
+//
+// PANDA 3D SOFTWARE
+// Copyright (c) 2001, 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://www.panda3d.org/license.txt .
+//
+// To contact the maintainers of this program write to
+// [email protected] .
+//
+////////////////////////////////////////////////////////////////////
+
+#include "glxGraphicsBuffer.h"
+#include "glxGraphicsStateGuardian.h"
+#include "config_glxdisplay.h"
+#include "glxGraphicsPipe.h"
+
+#include "graphicsPipe.h"
+#include "keyboardButton.h"
+#include "mouseButton.h"
+#include "glGraphicsStateGuardian.h"
+#include "clockObject.h"
+
+#include <errno.h>
+#include <sys/time.h>
+#include <X11/keysym.h>
+#include <X11/Xutil.h>
+
+TypeHandle glxGraphicsBuffer::_type_handle;
+
+////////////////////////////////////////////////////////////////////
+//     Function: glxGraphicsBuffer::Constructor
+//       Access: Public
+//  Description:
+////////////////////////////////////////////////////////////////////
+glxGraphicsBuffer::
+glxGraphicsBuffer(GraphicsPipe *pipe, GraphicsStateGuardian *gsg,
+                  int x_size, int y_size, bool want_texture) :
+  GraphicsBuffer(pipe, gsg, x_size, y_size, want_texture) 
+{
+  glxGraphicsPipe *glx_pipe;
+  DCAST_INTO_V(glx_pipe, _pipe);
+  _display = glx_pipe->get_display();
+  _pbuffer = None;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: glxGraphicsBuffer::Destructor
+//       Access: Public, Virtual
+//  Description:
+////////////////////////////////////////////////////////////////////
+glxGraphicsBuffer::
+~glxGraphicsBuffer() {
+  nassertv(_pbuffer == None);
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: glxGraphicsBuffer::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 glxGraphicsBuffer::
+make_current() {
+  glxGraphicsStateGuardian *glxgsg;
+  DCAST_INTO_V(glxgsg, _gsg);
+  glXMakeCurrent(_display, _pbuffer, glxgsg->_context);
+
+  // Now that we have made the context current to a window, we can
+  // reset the GSG state if this is the first time it has been used.
+  // (We can't just call reset() when we construct the GSG, because
+  // reset() requires having a current context.)
+  glxgsg->reset_if_new();
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: glxGraphicsBuffer::release_gsg
+//       Access: Public
+//  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 glxGraphicsBuffer::
+release_gsg() {
+  glXMakeCurrent(_display, None, NULL);
+  GraphicsBuffer::release_gsg();
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: glxGraphicsBuffer::begin_flip
+//       Access: Public, Virtual
+//  Description: This function will be called within the draw thread
+//               after end_frame() has been called on all windows, to
+//               initiate the exchange of the front and back buffers.
+//
+//               This should instruct the window to prepare for the
+//               flip at the next video sync, but it should not wait.
+//
+//               We have the two separate functions, begin_flip() and
+//               end_flip(), to make it easier to flip all of the
+//               windows at the same time.
+////////////////////////////////////////////////////////////////////
+void glxGraphicsBuffer::
+begin_flip() {
+  if (_gsg != (GraphicsStateGuardian *)NULL) {
+    make_current();
+
+    if (has_texture()) {
+      // Use glCopyTexImage2D to copy the framebuffer to the texture.
+      // This appears to be the only way to "render to a texture" in
+      // OpenGL; there's no interface to make the offscreen buffer
+      // itself be a texture.
+      DisplayRegion dr(_x_size, _y_size);
+      get_texture()->copy(_gsg, &dr, _gsg->get_render_buffer(RenderBuffer::T_back));
+    }
+
+    glXSwapBuffers(_display, _pbuffer);
+  }
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: glxGraphicsBuffer::close_buffer
+//       Access: Protected, Virtual
+//  Description: Closes the buffer right now.  Called from the window
+//               thread.
+////////////////////////////////////////////////////////////////////
+void glxGraphicsBuffer::
+close_buffer() {
+  if (_pbuffer != None) {
+    glXDestroyPbuffer(_display, _pbuffer);
+    _pbuffer = None;
+  }
+
+  _is_valid = false;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: glxGraphicsBuffer::open_buffer
+//       Access: Protected, Virtual
+//  Description: Opens the buffer right now.  Called from the window
+//               thread.  Returns true if the buffer is successfully
+//               opened, or false if there was a problem.
+////////////////////////////////////////////////////////////////////
+bool glxGraphicsBuffer::
+open_buffer() {
+  glxGraphicsPipe *glx_pipe;
+  DCAST_INTO_R(glx_pipe, _pipe, false);
+  glxGraphicsStateGuardian *glxgsg;
+  DCAST_INTO_R(glxgsg, _gsg, false);
+
+  static const int max_attrib_list = 32;
+  int attrib_list[max_attrib_list];
+  int n=0;
+
+#ifdef GLX_VERSION_1_3
+  // The official GLX 1.3 version passes in the size in the attrib
+  // list.
+  attrib_list[n++] = GLX_PBUFFER_WIDTH;
+  attrib_list[n++] = _x_size;
+  attrib_list[n++] = GLX_PBUFFER_HEIGHT;
+  attrib_list[n++] = _y_size;
+
+  nassertr(n < max_attrib_list, false);
+  attrib_list[n] = (int)None;
+  _pbuffer = glXCreatePbuffer(glxgsg->_display, glxgsg->_fbconfig,
+                              attrib_list);
+
+#else
+  // The pre-GLX 1.3 version passed in the size in the parameter list.
+  nassertr(n < max_attrib_list, false);
+  attrib_list[n] = (int)None;
+  _pbuffer = glXCreateGLXPbufferSGIX(glxgsg->_display, glxgsg->_fbconfig,
+                                     _x_size, _y_size, attrib_list);
+#endif
+
+  if (_pbuffer == None) {
+    glxdisplay_cat.error()
+      << "failed to create GLX pbuffer.\n";
+    return false;
+  }
+
+  _is_valid = true;
+  return true;
+}

+ 72 - 0
panda/src/glxdisplay/glxGraphicsBuffer.h

@@ -0,0 +1,72 @@
+// Filename: glxGraphicsBuffer.h
+// Created by:  drose (09Feb04)
+//
+////////////////////////////////////////////////////////////////////
+//
+// PANDA 3D SOFTWARE
+// Copyright (c) 2001, 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://www.panda3d.org/license.txt .
+//
+// To contact the maintainers of this program write to
+// [email protected] .
+//
+////////////////////////////////////////////////////////////////////
+
+#ifndef GLXGRAPHICSBUFFER_H
+#define GLXGRAPHICSBUFFER_H
+
+#include "pandabase.h"
+
+#include "glxGraphicsPipe.h"
+#include "graphicsBuffer.h"
+
+////////////////////////////////////////////////////////////////////
+//       Class : glxGraphicsBuffer
+// Description : An offscreen buffer in the GLX environment.  This
+//               creates a GLXPbuffer.
+////////////////////////////////////////////////////////////////////
+class glxGraphicsBuffer : public GraphicsBuffer {
+public:
+  glxGraphicsBuffer(GraphicsPipe *pipe, GraphicsStateGuardian *gsg,
+                    int x_size, int y_size, bool want_texture);
+
+  virtual ~glxGraphicsBuffer();
+
+  virtual void make_current();
+  virtual void release_gsg();
+
+  virtual void begin_flip();
+
+protected:
+  virtual void close_buffer();
+  virtual bool open_buffer();
+
+private:
+  Display *_display;
+  GLXPbuffer _pbuffer;
+
+public:
+  static TypeHandle get_class_type() {
+    return _type_handle;
+  }
+  static void init_type() {
+    GraphicsBuffer::init_type();
+    register_type(_type_handle, "glxGraphicsBuffer",
+                  GraphicsBuffer::get_class_type());
+  }
+  virtual TypeHandle get_type() const {
+    return get_class_type();
+  }
+  virtual TypeHandle force_init_type() {init_type(); return get_class_type();}
+
+private:
+  static TypeHandle _type_handle;
+};
+
+#include "glxGraphicsBuffer.I"
+
+#endif

+ 15 - 0
panda/src/glxdisplay/glxGraphicsPipe.cxx

@@ -18,6 +18,7 @@
 
 #include "glxGraphicsPipe.h"
 #include "glxGraphicsWindow.h"
+#include "glxGraphicsBuffer.h"
 #include "glxGraphicsStateGuardian.h"
 #include "config_glxdisplay.h"
 #include "frameBufferProperties.h"
@@ -200,6 +201,20 @@ make_window(GraphicsStateGuardian *gsg) {
   return new glxGraphicsWindow(this, gsg);
 }
 
+////////////////////////////////////////////////////////////////////
+//     Function: glxGraphicsPipe::make_buffer
+//       Access: Protected, Virtual
+//  Description: Creates a new offscreen buffer on the pipe, if possible.
+////////////////////////////////////////////////////////////////////
+PT(GraphicsBuffer) glxGraphicsPipe::
+make_buffer(GraphicsStateGuardian *gsg, int x_size, int y_size, bool want_texture) {
+  if (!_is_valid) {
+    return NULL;
+  }
+
+  return new glxGraphicsBuffer(this, gsg, x_size, y_size, want_texture);
+}
+
 ////////////////////////////////////////////////////////////////////
 //     Function: glxGraphicsPipe::choose_fbconfig
 //       Access: Private

+ 2 - 0
panda/src/glxdisplay/glxGraphicsPipe.h

@@ -79,6 +79,8 @@ public:
 protected:
   virtual PT(GraphicsStateGuardian) make_gsg(const FrameBufferProperties &properties);
   virtual PT(GraphicsWindow) make_window(GraphicsStateGuardian *gsg);
+  virtual PT(GraphicsBuffer) make_buffer(GraphicsStateGuardian *gsg, 
+                                         int x_size, int y_size, bool want_texture);
 
 private:
   GLXFBConfig choose_fbconfig(FrameBufferProperties &properties) const;