add glxGraphicsBuffer

This commit is contained in:
David Rose 2004-02-09 18:47:57 +00:00
parent 82c77e5715
commit fbca2647f9
7 changed files with 307 additions and 4 deletions

View File

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

View File

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

View File

@ -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
// panda3d@yahoogroups.com .
//
////////////////////////////////////////////////////////////////////

View File

@ -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
// panda3d@yahoogroups.com .
//
////////////////////////////////////////////////////////////////////
#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;
}

View File

@ -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
// panda3d@yahoogroups.com .
//
////////////////////////////////////////////////////////////////////
#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

View File

@ -18,6 +18,7 @@
#include "glxGraphicsPipe.h" #include "glxGraphicsPipe.h"
#include "glxGraphicsWindow.h" #include "glxGraphicsWindow.h"
#include "glxGraphicsBuffer.h"
#include "glxGraphicsStateGuardian.h" #include "glxGraphicsStateGuardian.h"
#include "config_glxdisplay.h" #include "config_glxdisplay.h"
#include "frameBufferProperties.h" #include "frameBufferProperties.h"
@ -200,6 +201,20 @@ make_window(GraphicsStateGuardian *gsg) {
return new glxGraphicsWindow(this, 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 // Function: glxGraphicsPipe::choose_fbconfig
// Access: Private // Access: Private

View File

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