From 42507f98523712221ab4d63499a4901eb7f1acaa Mon Sep 17 00:00:00 2001 From: David Rose Date: Fri, 27 Feb 2004 23:17:16 +0000 Subject: [PATCH] add ParasiteBuffer --- panda/src/display/Sources.pp | 3 + panda/src/display/config_display.cxx | 2 + panda/src/display/display_composite2.cxx | 1 + panda/src/display/graphicsBuffer.cxx | 3 +- panda/src/display/graphicsEngine.cxx | 49 +++++++++++++ panda/src/display/graphicsEngine.h | 2 + panda/src/display/graphicsWindow.cxx | 3 +- panda/src/display/parasiteBuffer.I | 18 +++++ panda/src/display/parasiteBuffer.cxx | 90 +++++++++++++++++++++++ panda/src/display/parasiteBuffer.h | 91 ++++++++++++++++++++++++ 10 files changed, 260 insertions(+), 2 deletions(-) create mode 100644 panda/src/display/parasiteBuffer.I create mode 100644 panda/src/display/parasiteBuffer.cxx create mode 100644 panda/src/display/parasiteBuffer.h diff --git a/panda/src/display/Sources.pp b/panda/src/display/Sources.pp index 93ef05e0f7..7e284a5b93 100644 --- a/panda/src/display/Sources.pp +++ b/panda/src/display/Sources.pp @@ -34,6 +34,7 @@ graphicsWindowInputDevice.I \ graphicsWindowInputDevice.h \ graphicsDevice.h graphicsDevice.I \ + parasiteBuffer.I parasiteBuffer.h \ windowProperties.I windowProperties.h \ hardwareChannel.I \ hardwareChannel.h \ @@ -56,6 +57,7 @@ graphicsThreadingModel.cxx \ graphicsWindow.cxx graphicsWindowInputDevice.cxx \ graphicsDevice.cxx \ + parasiteBuffer.cxx \ windowProperties.cxx \ hardwareChannel.cxx \ savedFrameBuffer.cxx @@ -81,6 +83,7 @@ graphicsThreadingModel.I graphicsThreadingModel.h \ graphicsWindowInputDevice.I graphicsWindowInputDevice.h \ graphicsDevice.I graphicsDevice.h \ + parasiteBuffer.I parasiteBuffer.h \ windowProperties.I windowProperties.h \ hardwareChannel.I hardwareChannel.h \ lensStack.I lensStack.h \ diff --git a/panda/src/display/config_display.cxx b/panda/src/display/config_display.cxx index 57a3147bb6..04a3a9c397 100644 --- a/panda/src/display/config_display.cxx +++ b/panda/src/display/config_display.cxx @@ -26,6 +26,7 @@ #include "graphicsWindow.h" #include "graphicsChannel.h" #include "graphicsLayer.h" +#include "parasiteBuffer.h" #include "hardwareChannel.h" #include "textureContext.h" #include "geomNodeContext.h" @@ -116,6 +117,7 @@ init_libdisplay() { GraphicsChannel::init_type(); GraphicsLayer::init_type(); HardwareChannel::init_type(); + ParasiteBuffer::init_type(); TextureContext::init_type(); GeomNodeContext::init_type(); GeomContext::init_type(); diff --git a/panda/src/display/display_composite2.cxx b/panda/src/display/display_composite2.cxx index a0f3fc5204..b3796ae60c 100644 --- a/panda/src/display/display_composite2.cxx +++ b/panda/src/display/display_composite2.cxx @@ -9,3 +9,4 @@ #include "graphicsWindow.cxx" #include "graphicsBuffer.cxx" #include "graphicsOutput.cxx" +#include "parasiteBuffer.cxx" diff --git a/panda/src/display/graphicsBuffer.cxx b/panda/src/display/graphicsBuffer.cxx index 22c5e0b2a9..8d4378ba66 100644 --- a/panda/src/display/graphicsBuffer.cxx +++ b/panda/src/display/graphicsBuffer.cxx @@ -38,7 +38,8 @@ GraphicsBuffer(GraphicsPipe *pipe, GraphicsStateGuardian *gsg, if (display_cat.is_debug()) { display_cat.debug() - << "Creating new offscreen buffer using GSG " << (void *)gsg << "\n"; + << "Creating new offscreen buffer " << get_name() + << " using GSG " << (void *)gsg << "\n"; } if (want_texture) { diff --git a/panda/src/display/graphicsEngine.cxx b/panda/src/display/graphicsEngine.cxx index cbf374abe7..a6270b552a 100644 --- a/panda/src/display/graphicsEngine.cxx +++ b/panda/src/display/graphicsEngine.cxx @@ -18,6 +18,7 @@ #include "graphicsEngine.h" #include "graphicsPipe.h" +#include "parasiteBuffer.h" #include "config_display.h" #include "pipeline.h" #include "drawCullHandler.h" @@ -274,6 +275,54 @@ make_buffer(GraphicsStateGuardian *gsg, const string &name, return buffer; } +//////////////////////////////////////////////////////////////////// +// Function: GraphicsEngine::make_parasite +// Access: Published +// Description: Creates a new offscreen parasite buffer based on the +// indicated host. See parasiteBuffer.h. The +// GraphicsEngine becomes the owner of the buffer; it +// will persist at least until remove_window() is called +// later. +// +// This usually returns a ParasiteBuffer object, but it +// may actually return a GraphicsWindow if show-buffers +// is configured true. +//////////////////////////////////////////////////////////////////// +GraphicsOutput *GraphicsEngine:: +make_parasite(GraphicsOutput *host, const string &name, + int sort, int x_size, int y_size) { + GraphicsStateGuardian *gsg = host->get_gsg(); + + if (show_buffers) { + GraphicsWindow *window = make_window(gsg, name, sort); + if (window != (GraphicsWindow *)NULL) { + WindowProperties props; + props.set_size(x_size, y_size); + props.set_fixed_size(true); + props.set_title(name); + window->request_properties(props); + + window->_texture = new Texture(); + window->_texture->set_name(name); + window->_copy_texture = true; + + return window; + } + } + + GraphicsThreadingModel threading_model = get_threading_model(); + nassertr(gsg != (GraphicsStateGuardian *)NULL, NULL); + nassertr(this == gsg->get_engine(), NULL); + nassertr(threading_model.get_draw_name() == + gsg->get_threading_model().get_draw_name(), NULL); + + ParasiteBuffer *buffer = new ParasiteBuffer(host, name, x_size, y_size); + buffer->_sort = sort; + do_add_window(buffer, gsg, threading_model); + + return buffer; +} + //////////////////////////////////////////////////////////////////// // Function: GraphicsEngine::remove_window // Access: Published diff --git a/panda/src/display/graphicsEngine.h b/panda/src/display/graphicsEngine.h index 89dd08f0fc..9de59d9772 100644 --- a/panda/src/display/graphicsEngine.h +++ b/panda/src/display/graphicsEngine.h @@ -79,6 +79,8 @@ PUBLISHED: GraphicsOutput *make_buffer(GraphicsStateGuardian *gsg, const string &name, int sort, int x_size, int y_size, bool want_texture); + GraphicsOutput *make_parasite(GraphicsOutput *host, const string &name, + int sort, int x_size, int y_size); bool remove_window(GraphicsOutput *window); void remove_all_windows(); diff --git a/panda/src/display/graphicsWindow.cxx b/panda/src/display/graphicsWindow.cxx index a24cb62f0b..87e5842ced 100644 --- a/panda/src/display/graphicsWindow.cxx +++ b/panda/src/display/graphicsWindow.cxx @@ -45,7 +45,8 @@ GraphicsWindow(GraphicsPipe *pipe, GraphicsStateGuardian *gsg, if (display_cat.is_debug()) { display_cat.debug() - << "Creating new window using GSG " << (void *)gsg << "\n"; + << "Creating new window " << get_name() + << " using GSG " << (void *)gsg << "\n"; } // Some default properties for windows unless specified otherwise. diff --git a/panda/src/display/parasiteBuffer.I b/panda/src/display/parasiteBuffer.I new file mode 100644 index 0000000000..f33aa05878 --- /dev/null +++ b/panda/src/display/parasiteBuffer.I @@ -0,0 +1,18 @@ +// Filename: parasiteBuffer.I +// Created by: drose (27Feb04) +// +//////////////////////////////////////////////////////////////////// +// +// PANDA 3D SOFTWARE +// Copyright (c) 2001 - 2004, 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 +// panda3d-general@lists.sourceforge.net . +// +//////////////////////////////////////////////////////////////////// + diff --git a/panda/src/display/parasiteBuffer.cxx b/panda/src/display/parasiteBuffer.cxx new file mode 100644 index 0000000000..aaded1ad1c --- /dev/null +++ b/panda/src/display/parasiteBuffer.cxx @@ -0,0 +1,90 @@ +// Filename: parasiteBuffer.cxx +// Created by: drose (27Feb04) +// +//////////////////////////////////////////////////////////////////// +// +// PANDA 3D SOFTWARE +// Copyright (c) 2001 - 2004, 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 +// panda3d-general@lists.sourceforge.net . +// +//////////////////////////////////////////////////////////////////// + + +#include "parasiteBuffer.h" + +TypeHandle ParasiteBuffer::_type_handle; + +//////////////////////////////////////////////////////////////////// +// Function: ParasiteBuffer::Constructor +// Access: Public +// Description: Normally, the ParasiteBuffer constructor is not +// called directly; these are created instead via the +// GraphicsEngine::make_parasite() function. +//////////////////////////////////////////////////////////////////// +ParasiteBuffer:: +ParasiteBuffer(GraphicsOutput *host, const string &name, + int x_size, int y_size) : + GraphicsOutput(host->get_pipe(), host->get_gsg(), name), + _host(host) +{ +#ifdef DO_MEMORY_USAGE + MemoryUsage::update_type(this, this); +#endif + + if (display_cat.is_debug()) { + display_cat.debug() + << "Creating new parasite buffer " << get_name() + << " on " << _host->get_name() << "\n"; + } + + _texture = new Texture(); + _texture->set_name(_name); + _copy_texture = true; + + _x_size = x_size; + _y_size = y_size; + _has_size = true; + + _is_valid = true; + + nassertv(_x_size < host->get_x_size() && _y_size < host->get_y_size()); +} + +//////////////////////////////////////////////////////////////////// +// Function: ParasiteBuffer::Destructor +// Access: Published, Virtual +// Description: +//////////////////////////////////////////////////////////////////// +ParasiteBuffer:: +~ParasiteBuffer() { +} + +//////////////////////////////////////////////////////////////////// +// Function: ParasiteBuffer::is_active +// Access: Published, Virtual +// Description: Returns true if the window is ready to be rendered +// into, false otherwise. +//////////////////////////////////////////////////////////////////// +bool ParasiteBuffer:: +is_active() const { + return _host->is_active(); +} + +//////////////////////////////////////////////////////////////////// +// Function: ParasiteBuffer::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 ParasiteBuffer:: +make_current() { + _host->make_current(); +} diff --git a/panda/src/display/parasiteBuffer.h b/panda/src/display/parasiteBuffer.h new file mode 100644 index 0000000000..873ce3f369 --- /dev/null +++ b/panda/src/display/parasiteBuffer.h @@ -0,0 +1,91 @@ +// Filename: parasiteBuffer.h +// Created by: drose (27Feb04) +// +//////////////////////////////////////////////////////////////////// +// +// PANDA 3D SOFTWARE +// Copyright (c) 2001 - 2004, 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 +// panda3d-general@lists.sourceforge.net . +// +//////////////////////////////////////////////////////////////////// + +#ifndef PARASITEBUFFER_H +#define PARASITEBUFFER_H + +#include "pandabase.h" + +#include "graphicsOutput.h" +#include "texture.h" +#include "pointerTo.h" + +//////////////////////////////////////////////////////////////////// +// Class : ParasiteBuffer +// Description : This is a special GraphicsOutput type that acts a lot +// like a GraphicsBuffer, effectively allowing rendering +// to an offscreen buffer, except it does not create any +// framebuffer space for itself. Instead, it renders +// into the framebuffer owned by some other +// GraphicsOutput. +// +// The x_size and y_size must therefore fit within the +// bounds of the source GraphicsOutput. +// +// Since the framebuffer will be subsequently cleared +// when the actual owner draws in it later, this only +// makes sense if we are going to copy the contents of +// the framebuffer to a texture immediately after we +// draw it. Thus, has_texture() is implicitly true for +// a ParasiteBuffer. +// +// This class is useful to render offscreen to a texture +// while preventing the waste of framebuffer memory for +// API's that are unable to render directly into a +// texture (and must render into a separate framebuffer +// first and then copy to texture). It is also the only +// way to render to a texture on API's that do not +// support offscreen rendering. +//////////////////////////////////////////////////////////////////// +class EXPCL_PANDA ParasiteBuffer : public GraphicsOutput { +public: + ParasiteBuffer(GraphicsOutput *host, const string &name, + int x_size, int y_size); + +PUBLISHED: + virtual ~ParasiteBuffer(); + + virtual bool is_active() const; + +public: + virtual void make_current(); + +private: + PT(GraphicsOutput) _host; + +public: + static TypeHandle get_class_type() { + return _type_handle; + } + static void init_type() { + GraphicsOutput::init_type(); + register_type(_type_handle, "ParasiteBuffer", + GraphicsOutput::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 "parasiteBuffer.I" + +#endif