integrate more new-scene-graph stuff

This commit is contained in:
David Rose 2002-02-26 00:07:26 +00:00
parent 46a06c40f0
commit 6a8b0b3913
48 changed files with 1463 additions and 140 deletions

View File

@ -4,28 +4,38 @@
#begin lib_target #begin lib_target
#define TARGET display #define TARGET display
#define LOCAL_LIBS \ #define LOCAL_LIBS \
putil gsgbase gobj linmath graph mathutil sgraph \ pgraph putil gsgbase gobj linmath graph mathutil sgraph \
pstatclient pstatclient
#define COMBINED_SOURCES $[TARGET]_composite1.cxx $[TARGET]_composite2.cxx #define COMBINED_SOURCES $[TARGET]_composite1.cxx $[TARGET]_composite2.cxx
#define SOURCES \ #define SOURCES \
config_display.h displayRegion.I displayRegion.h \ config_display.h displayRegion.I displayRegion.h \
displayRegionStack.I \
displayRegionStack.h \
drawCullHandler.h drawCullHandler.I \
frameBufferStack.I frameBufferStack.h \
geomContext.I geomContext.h geomNodeContext.I geomNodeContext.h \ geomContext.I geomContext.h geomNodeContext.I geomNodeContext.h \
graphicsChannel.I graphicsChannel.h graphicsLayer.I \ graphicsChannel.I graphicsChannel.h \
graphicsEngine.I graphicsEngine.h \
graphicsLayer.I \
graphicsLayer.h graphicsPipe.I graphicsPipe.N graphicsPipe.h \ graphicsLayer.h graphicsPipe.I graphicsPipe.N graphicsPipe.h \
graphicsStateGuardian.I graphicsStateGuardian.N \ graphicsStateGuardian.I graphicsStateGuardian.N \
graphicsStateGuardian.h graphicsWindow.I graphicsWindow.N \ graphicsStateGuardian.h graphicsWindow.I graphicsWindow.N \
graphicsWindow.h graphicsWindowInputDevice.I \ graphicsWindow.h graphicsWindowInputDevice.I \
graphicsWindowInputDevice.h hardwareChannel.I \ graphicsWindowInputDevice.h hardwareChannel.I \
hardwareChannel.h interactiveGraphicsPipe.I \ hardwareChannel.h interactiveGraphicsPipe.I \
interactiveGraphicsPipe.h noninteractiveGraphicsPipe.I \ interactiveGraphicsPipe.h \
lensStack.I lensStack.h \
noninteractiveGraphicsPipe.I \
noninteractiveGraphicsPipe.h pipeSpec.I pipeSpec.h \ noninteractiveGraphicsPipe.h pipeSpec.I pipeSpec.h \
savedFrameBuffer.I savedFrameBuffer.h savedFrameBuffer.I savedFrameBuffer.h
#define INCLUDED_SOURCES \ #define INCLUDED_SOURCES \
config_display.cxx displayRegion.cxx \ config_display.cxx displayRegion.cxx \
drawCullHandler.cxx \
geomContext.cxx geomNodeContext.cxx graphicsChannel.cxx \ geomContext.cxx geomNodeContext.cxx graphicsChannel.cxx \
graphicsEngine.cxx \
graphicsLayer.cxx graphicsPipe.cxx graphicsStateGuardian.cxx \ graphicsLayer.cxx graphicsPipe.cxx graphicsStateGuardian.cxx \
graphicsWindow.cxx graphicsWindowInputDevice.cxx \ graphicsWindow.cxx graphicsWindowInputDevice.cxx \
hardwareChannel.cxx interactiveGraphicsPipe.cxx \ hardwareChannel.cxx interactiveGraphicsPipe.cxx \
@ -35,14 +45,20 @@
#define INSTALL_HEADERS \ #define INSTALL_HEADERS \
config_display.h \ config_display.h \
displayRegion.I displayRegion.h displayRegionStack.I \ displayRegion.I displayRegion.h displayRegionStack.I \
displayRegionStack.h frameBufferStack.I frameBufferStack.h \ displayRegionStack.h \
drawCullHandler.h drawCullHandler.I \
frameBufferStack.I frameBufferStack.h \
geomContext.I geomContext.h geomNodeContext.I geomNodeContext.h \ geomContext.I geomContext.h geomNodeContext.I geomNodeContext.h \
graphicsChannel.I graphicsChannel.h graphicsLayer.I graphicsLayer.h \ graphicsChannel.I graphicsChannel.h \
graphicsEngine.I graphicsEngine.h \
graphicsLayer.I graphicsLayer.h \
graphicsPipe.I graphicsPipe.h graphicsStateGuardian.I \ graphicsPipe.I graphicsPipe.h graphicsStateGuardian.I \
graphicsStateGuardian.h graphicsWindow.I graphicsWindow.h \ graphicsStateGuardian.h graphicsWindow.I graphicsWindow.h \
graphicsWindowInputDevice.I graphicsWindowInputDevice.h \ graphicsWindowInputDevice.I graphicsWindowInputDevice.h \
hardwareChannel.I hardwareChannel.h interactiveGraphicsPipe.I \ hardwareChannel.I hardwareChannel.h interactiveGraphicsPipe.I \
interactiveGraphicsPipe.h noninteractiveGraphicsPipe.I \ interactiveGraphicsPipe.h \
lensStack.I lensStack.h \
noninteractiveGraphicsPipe.I \
noninteractiveGraphicsPipe.h pipeSpec.I pipeSpec.h renderBuffer.h \ noninteractiveGraphicsPipe.h pipeSpec.I pipeSpec.h renderBuffer.h \
savedFrameBuffer.I savedFrameBuffer.h savedFrameBuffer.I savedFrameBuffer.h

View File

@ -140,7 +140,10 @@ get_cull_frustum() const {
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
INLINE void DisplayRegion:: INLINE void DisplayRegion::
set_active(bool active) { set_active(bool active) {
if (active != _active) {
_active = active; _active = active;
win_display_regions_changed();
}
} }
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////

View File

@ -21,9 +21,9 @@
#include "graphicsChannel.h" #include "graphicsChannel.h"
#include "graphicsWindow.h" #include "graphicsWindow.h"
#include "config_display.h" #include "config_display.h"
#include "displayRegion.h" #include "displayRegion.h"
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
// Function: DisplayRegion::Constructor // Function: DisplayRegion::Constructor
// Access: Public // Access: Public
@ -193,3 +193,18 @@ output(ostream &out) const {
<< ")=pixels(" << _pl << " " << _pr << " " << _pb << " " << _pt << ")=pixels(" << _pl << " " << _pr << " " << _pb << " " << _pt
<< ")"; << ")";
} }
////////////////////////////////////////////////////////////////////
// Function: DisplayRegion::win_display_regions_changed
// Access: Public
// Description: Intended to be called when the active state on a
// nested channel or layer or display region changes,
// forcing the window to recompute its list of active
// display regions.
////////////////////////////////////////////////////////////////////
void DisplayRegion::
win_display_regions_changed() {
if (_layer != (GraphicsLayer *)NULL) {
_layer->win_display_regions_changed();
}
}

View File

@ -35,6 +35,7 @@ class GraphicsLayer;
class GraphicsChannel; class GraphicsChannel;
class GraphicsWindow; class GraphicsWindow;
class GraphicsPipe; class GraphicsPipe;
class CullHandler;
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
// Class : DisplayRegion // Class : DisplayRegion
@ -80,6 +81,9 @@ PUBLISHED:
void output(ostream &out) const; void output(ostream &out) const;
public:
void win_display_regions_changed();
protected: protected:
float _l; float _l;

View File

@ -1,8 +1,10 @@
#include "displayRegion.cxx" #include "displayRegion.cxx"
#include "drawCullHandler.cxx"
#include "geomContext.cxx" #include "geomContext.cxx"
#include "geomNodeContext.cxx" #include "geomNodeContext.cxx"
#include "graphicsChannel.cxx" #include "graphicsChannel.cxx"
#include "graphicsEngine.cxx"
#include "graphicsLayer.cxx" #include "graphicsLayer.cxx"
#include "graphicsPipe.cxx" #include "graphicsPipe.cxx"
#include "graphicsStateGuardian.cxx" #include "graphicsStateGuardian.cxx"

View File

@ -0,0 +1,29 @@
// Filename: drawCullHandler.I
// Created by: drose (25Feb02)
//
////////////////////////////////////////////////////////////////////
//
// 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 .
//
////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////
// Function: DrawCullHandler::Constructor
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
INLINE DrawCullHandler::
DrawCullHandler(GraphicsStateGuardian *gsg) :
_gsg(gsg)
{
}

View File

@ -0,0 +1,36 @@
// Filename: drawCullHandler.cxx
// Created by: drose (25Feb02)
//
////////////////////////////////////////////////////////////////////
//
// 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 "drawCullHandler.h"
#include "geom.h"
#include "renderState.h"
#include "graphicsStateGuardian.h"
////////////////////////////////////////////////////////////////////
// Function: DrawCullHandler::record_geom
// Access: Public, Virtual
// Description: This callback function is intended to be overridden
// by a derived class. This is called as each Geom is
// discovered by the CullTraverser.
////////////////////////////////////////////////////////////////////
void DrawCullHandler::
record_geom(Geom *geom, const RenderState *state) {
_gsg->set_state(state);
geom->draw(_gsg);
}

View File

@ -0,0 +1,56 @@
// Filename: drawCullHandler.h
// Created by: drose (25Feb02)
//
////////////////////////////////////////////////////////////////////
//
// 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 DRAWCULLHANDLER_H
#define DRAWCULLHANDLER_H
#include "pandabase.h"
#include "cullHandler.h"
class GraphicsStateGuardian;
////////////////////////////////////////////////////////////////////
// Class : DrawCullHandler
// Description : This special kind of CullHandler immediately draws
// its contents as soon as it receives them. This draws
// geometry immediately as it is encountered in the
// scene graph by cull, mixing the draw and cull
// traversals into one traversal, and prohibiting state
// sorting. However, it has somewhat lower overhead
// than separating out draw and cull, if state sorting
// and multiprocessing are not required.
////////////////////////////////////////////////////////////////////
class EXPCL_PANDA DrawCullHandler : public CullHandler {
public:
INLINE DrawCullHandler(GraphicsStateGuardian *gsg);
// virtual void begin_decal();
virtual void record_geom(Geom *geom, const RenderState *state);
// virtual void push_decal();
// virtual void pop_decal();
private:
GraphicsStateGuardian *_gsg;
};
#include "drawCullHandler.I"
#endif

View File

@ -16,6 +16,7 @@
// //
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
// Function: GraphicsChannel::set_active // Function: GraphicsChannel::set_active
// Access: Public // Access: Public
@ -24,7 +25,10 @@
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
INLINE void GraphicsChannel:: INLINE void GraphicsChannel::
set_active(bool active) { set_active(bool active) {
if (active != _is_active) {
_is_active = active; _is_active = active;
win_display_regions_changed();
}
} }
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////

View File

@ -226,3 +226,18 @@ window_resized(int x, int y) {
(*li)->channel_resized(x, y); (*li)->channel_resized(x, y);
} }
} }
////////////////////////////////////////////////////////////////////
// Function: GraphicsChannel::win_display_regions_changed
// Access: Public
// Description: Intended to be called when the active state on a
// nested channel or layer or display region changes,
// forcing the window to recompute its list of active
// display regions.
////////////////////////////////////////////////////////////////////
void GraphicsChannel::
win_display_regions_changed() {
if (_window != (GraphicsWindow *)NULL) {
_window->win_display_regions_changed();
}
}

View File

@ -36,6 +36,7 @@
class GraphicsChannel; class GraphicsChannel;
class GraphicsPipe; class GraphicsPipe;
class GraphicsWindow; class GraphicsWindow;
class CullHandler;
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
// Class : GraphicsChannel // Class : GraphicsChannel
@ -67,6 +68,8 @@ PUBLISHED:
public: public:
virtual void window_resized(int x, int y); virtual void window_resized(int x, int y);
void win_display_regions_changed();
PUBLISHED: PUBLISHED:
INLINE void set_active(bool active); INLINE void set_active(bool active);
INLINE bool is_active() const; INLINE bool is_active() const;

View File

@ -0,0 +1,18 @@
// Filename: graphicsEngine.I
// Created by: drose (24Feb02)
//
////////////////////////////////////////////////////////////////////
//
// 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,156 @@
// Filename: graphicsEngine.cxx
// Created by: drose (24Feb02)
//
////////////////////////////////////////////////////////////////////
//
// 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 "graphicsEngine.h"
#include "pipeline.h"
#include "drawCullHandler.h"
#include "qpcullTraverser.h"
////////////////////////////////////////////////////////////////////
// Function: GraphicsEngine::Constructor
// Access: Published
// Description: Creates a new GraphicsEngine object. The Pipeline is
// normally left to default to NULL, which indicates the
// global render pipeline, but it may be any Pipeline
// you choose.
////////////////////////////////////////////////////////////////////
GraphicsEngine::
GraphicsEngine(Pipeline *pipeline) :
_pipeline(pipeline)
{
if (_pipeline == (Pipeline *)NULL) {
_pipeline = Pipeline::get_render_pipeline();
}
}
////////////////////////////////////////////////////////////////////
// Function: GraphicsEngine::add_window
// Access: Published
// Description: Adds a new window to the set of windows that will be
// processed when render_frame() is called. This also
// increments the reference count to the window.
////////////////////////////////////////////////////////////////////
void GraphicsEngine::
add_window(GraphicsWindow *window) {
_windows.insert(window);
}
////////////////////////////////////////////////////////////////////
// Function: GraphicsEngine::remove_window
// Access: Published
// Description: Removes the indicated window from the set of windows
// that will be processed when render_frame() is called.
// This also decrements the reference count to the
// window, allowing the window to be destructed if there
// are no other references to it.
//
// The return value is true if the window was removed,
// false if it was not found.
////////////////////////////////////////////////////////////////////
bool GraphicsEngine::
remove_window(GraphicsWindow *window) {
size_t count = _windows.erase(window);
return (count != 0);
}
////////////////////////////////////////////////////////////////////
// Function: GraphicsEngine::render_frame
// Access: Published
// Description: Renders the next frame in all the registered windows,
// and flips all of the frame buffers.
////////////////////////////////////////////////////////////////////
void GraphicsEngine::
render_frame() {
cull_and_draw_together();
}
////////////////////////////////////////////////////////////////////
// Function: GraphicsEngine::cull_and_draw_together
// Access: Private
// Description: An implementation of render_frame() that renders the
// frame with a DrawCullHandler, to cull and draw all
// windows in the same pass.
////////////////////////////////////////////////////////////////////
void GraphicsEngine::
cull_and_draw_together() {
Windows::iterator wi;
for (wi = _windows.begin(); wi != _windows.end(); ++wi) {
GraphicsWindow *win = (*wi);
win->clear();
int num_display_regions = win->get_num_display_regions();
for (int i = 0; i < num_display_regions; i++) {
DisplayRegion *dr = win->get_display_region(i);
cull_and_draw_together(win, dr);
}
win->flip();
}
}
////////////////////////////////////////////////////////////////////
// Function: GraphicsEngine::cull_and_draw_together
// Access: Private
// Description: An implementation of render_frame() that renders the
// frame with a DrawCullHandler, to cull and draw all
// windows in the same pass.
////////////////////////////////////////////////////////////////////
void GraphicsEngine::
cull_and_draw_together(GraphicsWindow *win, DisplayRegion *dr) {
Camera *camera = dr->get_camera();
if (camera == (Camera *)NULL || !camera->is_active()) {
// No camera, no draw.
return;
}
Lens *lens = camera->get_lens();
if (lens == (Lens *)NULL) {
// No lens, no draw.
return;
}
PandaNode *scene = camera->get_qpscene();
if (scene == (PandaNode *)NULL) {
// No scene, no draw.
return;
}
GraphicsStateGuardian *gsg = win->get_gsg();
nassertv(gsg != (GraphicsStateGuardian *)NULL);
if (!gsg->set_lens(lens)) {
// The lens is inappropriate somehow.
display_cat.error()
<< gsg->get_type() << " cannot render with " << lens->get_type()
<< "\n";
return;
}
DrawCullHandler cull_handler(gsg);
qpCullTraverser trav;
trav.set_cull_handler(&cull_handler);
// Here we should figure out the world transform: the camera's
// inverse transform.
DisplayRegionStack old_dr = gsg->push_display_region(dr);
gsg->prepare_display_region();
trav.traverse(scene);
gsg->pop_display_region(old_dr);
}

View File

@ -0,0 +1,66 @@
// Filename: graphicsEngine.h
// Created by: drose (24Feb02)
//
////////////////////////////////////////////////////////////////////
//
// 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 GRAPHICSENGINE_H
#define GRAPHICSENGINE_H
#include "pandabase.h"
#include "graphicsWindow.h"
#include "pointerTo.h"
#include "pset.h"
class Pipeline;
class DisplayRegion;
////////////////////////////////////////////////////////////////////
// Class : GraphicsEngine
// Description : This class is the main interface to controlling the
// render process. There is typically only one
// GraphicsEngine in an application, and it synchronizes
// rendering to all all of the active windows; although
// it is possible to have multiple GraphicsEngine
// objects if multiple synchronicity groups are
// required.
//
// The GraphicsEngine is responsible for managing the
// cull and draw processes. The application simply
// calls engine->render_frame() and considers it done.
////////////////////////////////////////////////////////////////////
class EXPCL_PANDA GraphicsEngine : public Namable {
PUBLISHED:
GraphicsEngine(Pipeline *pipeline = NULL);
void add_window(GraphicsWindow *window);
bool remove_window(GraphicsWindow *window);
void render_frame();
private:
void cull_and_draw_together();
void cull_and_draw_together(GraphicsWindow *win, DisplayRegion *dr);
Pipeline *_pipeline;
typedef pset<PT(GraphicsWindow)> Windows;
Windows _windows;
};
#include "graphicsEngine.I"
#endif

View File

@ -18,7 +18,7 @@
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
// Function: GraphicsLayer::get_channel // Function: GraphicsLayer::get_channel
// Access: Public // Access: Published
// Description: Returns the GraphicsChannel that this layer is // Description: Returns the GraphicsChannel that this layer is
// associated with. It is possible that the // associated with. It is possible that the
// GraphicsChannel might have been deleted while an // GraphicsChannel might have been deleted while an
@ -33,18 +33,21 @@ get_channel() const {
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
// Function: GraphicsLayer::set_active // Function: GraphicsLayer::set_active
// Access: Public // Access: Published
// Description: Sets the active flag on the layer. If the layer // Description: Sets the active flag on the layer. If the layer
// is marked as inactive, nothing will be rendered. // is marked as inactive, nothing will be rendered.
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
INLINE void GraphicsLayer:: INLINE void GraphicsLayer::
set_active(bool active) { set_active(bool active) {
if (active != _is_active) {
_is_active = active; _is_active = active;
win_display_regions_changed();
}
} }
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
// Function: GraphicsLayer::is_active // Function: GraphicsLayer::is_active
// Access: Public // Access: Published
// Description: Returns the active flag on the layer. // Description: Returns the active flag on the layer.
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
INLINE bool GraphicsLayer:: INLINE bool GraphicsLayer::

View File

@ -93,6 +93,7 @@ GraphicsLayer::
++dri) { ++dri) {
(*dri)->_layer = NULL; (*dri)->_layer = NULL;
} }
win_display_regions_changed();
// We don't need to remove ourself from the channel's list of // We don't need to remove ourself from the channel's list of
// layers. We must have already been removed, or we wouldn't be // layers. We must have already been removed, or we wouldn't be
@ -113,6 +114,7 @@ make_display_region() {
dr->compute_pixels(win->get_width(), win->get_height()); dr->compute_pixels(win->get_width(), win->get_height());
} }
_display_regions.push_back(dr); _display_regions.push_back(dr);
win_display_regions_changed();
return dr; return dr;
} }
@ -131,6 +133,7 @@ make_display_region(float l, float r, float b, float t) {
dr->compute_pixels(win->get_width(), win->get_height()); dr->compute_pixels(win->get_width(), win->get_height());
} }
_display_regions.push_back(dr); _display_regions.push_back(dr);
win_display_regions_changed();
return dr; return dr;
} }
@ -169,6 +172,7 @@ remove_dr(int index) {
nassertv(index >= 0 && index < (int)_display_regions.size()); nassertv(index >= 0 && index < (int)_display_regions.size());
_display_regions[index]->_layer = NULL; _display_regions[index]->_layer = NULL;
_display_regions.erase(_display_regions.begin() + index); _display_regions.erase(_display_regions.begin() + index);
win_display_regions_changed();
} }
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
@ -190,6 +194,7 @@ remove_dr(DisplayRegion *display_region) {
if (dri != _display_regions.end()) { if (dri != _display_regions.end()) {
display_region->_layer = NULL; display_region->_layer = NULL;
_display_regions.erase(dri); _display_regions.erase(dri);
win_display_regions_changed();
return true; return true;
} }
return false; return false;
@ -238,3 +243,18 @@ channel_resized(int x, int y) {
(*dri)->compute_pixels(x, y); (*dri)->compute_pixels(x, y);
} }
} }
////////////////////////////////////////////////////////////////////
// Function: GraphicsLayer::win_display_regions_changed
// Access: Public
// Description: Intended to be called when the active state on a
// nested channel or layer or display region changes,
// forcing the window to recompute its list of active
// display regions.
////////////////////////////////////////////////////////////////////
void GraphicsLayer::
win_display_regions_changed() {
if (_channel != (GraphicsChannel *)NULL) {
_channel->win_display_regions_changed();
}
}

View File

@ -37,6 +37,7 @@
class GraphicsChannel; class GraphicsChannel;
class GraphicsWindow; class GraphicsWindow;
class GraphicsPipe; class GraphicsPipe;
class CullHandler;
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
// Class : GraphicsLayer // Class : GraphicsLayer
@ -74,6 +75,8 @@ PUBLISHED:
public: public:
void channel_resized(int x, int y); void channel_resized(int x, int y);
void win_display_regions_changed();
PUBLISHED: PUBLISHED:
INLINE void set_active(bool active); INLINE void set_active(bool active);
INLINE bool is_active() const; INLINE bool is_active() const;
@ -109,6 +112,7 @@ private:
static TypeHandle _type_handle; static TypeHandle _type_handle;
friend class GraphicsChannel; friend class GraphicsChannel;
friend class GraphicsWindow;
}; };
#include "graphicsLayer.I" #include "graphicsLayer.I"

View File

@ -16,7 +16,6 @@
// //
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
#include <notify.h>
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
// Function: GraphicsStateGuardian::StateInfo::Constructor // Function: GraphicsStateGuardian::StateInfo::Constructor
@ -114,6 +113,37 @@ set_state(const AllTransitionsWrapper &new_state) {
set_state(new_state.get_transitions()); set_state(new_state.get_transitions());
} }
////////////////////////////////////////////////////////////////////
// Function: GraphicsStateGuardian::modify_state
// Access: Public
// Description: Applies the attributes indicated in the state set to
// the current state, and issues the changes to the
// graphics hardware.
//
// Any transitions not mentioned are left unchanged.
////////////////////////////////////////////////////////////////////
INLINE void GraphicsStateGuardian::
modify_state(const RenderState *state) {
_qpstate = _qpstate->issue_delta_modify(state, this);
}
////////////////////////////////////////////////////////////////////
// Function: GraphicsStateGuardian::set_state
// Access: Public
// Description: Applies the attributes indicated in the state set to
// the current state, and issues the changes to the
// graphics hardware.
//
// The state is taken to be a complete description of
// what the graphics state should be; any transitions
// not mentioned are implicitly reset to their initial
// values.
////////////////////////////////////////////////////////////////////
INLINE void GraphicsStateGuardian::
set_state(const RenderState *state) {
_qpstate = _qpstate->issue_delta_set(state, this);
}
/* /*
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
// Function: GraphicsStateGuardian::get_state // Function: GraphicsStateGuardian::get_state
@ -168,6 +198,19 @@ get_current_display_region(void) const {
return _current_display_region; return _current_display_region;
} }
////////////////////////////////////////////////////////////////////
// Function: GraphicsStateGuardian::get_current_lens
// Access: Public
// Description: Returns the current lens being rendered with, as set
// by the last call to push_lens() (or restored by
// pop_lens()). This lens will be made active (if it is
// not already) by a call to prepare_lens().
////////////////////////////////////////////////////////////////////
INLINE const Lens *GraphicsStateGuardian::
get_current_lens() const {
return _current_lens;
}
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
// Function: GraphicsStateGuardian::push_display_region // Function: GraphicsStateGuardian::push_display_region
// Access: Public // Access: Public
@ -245,6 +288,65 @@ pop_frame_buffer(FrameBufferStack &node) {
node._stack_level = -1; node._stack_level = -1;
} }
////////////////////////////////////////////////////////////////////
// Function: GraphicsStateGuardian::push_lens
// Access: Public
// Description: Saves the current lens information and sets up a new
// lens for rendering. The return value from this
// function must eventually be passed to a matching
// pop_lens() call.
//
// The new lens will not actually be made active for
// rendering until the next call to prepare_lens().
// This is a state-changing optimization.
////////////////////////////////////////////////////////////////////
INLINE LensStack GraphicsStateGuardian::
push_lens(const Lens *lens) {
LensStack old;
old._lens = _current_lens;
old._stack_level = _lens_stack_level;
_lens_stack_level++;
_current_lens = lens;
return old;
}
////////////////////////////////////////////////////////////////////
// Function: GraphicsStateGuardian::pop_lens
// Access: Public
// Description: Restores the lens previously in effect, before the
// matching call to push_lens().
//
// The newly-restored lens will not actually be made
// active for rendering until the next call to
// prepare_lens(). This is a state-changing
// optimization.
////////////////////////////////////////////////////////////////////
INLINE void GraphicsStateGuardian::
pop_lens(LensStack &node) {
nassertv(_lens_stack_level > 0);
_lens_stack_level--;
nassertv(node._stack_level == _lens_stack_level);
_current_lens = node._lens;
node._stack_level = -1;
}
////////////////////////////////////////////////////////////////////
// Function: GraphicsStateGuardian::set_lens
// Access: Public
// Description: Sets a new lens for rendering without bothering to
// push or pop. This replaces the lens most recently
// pushed, if any. There is no need to call
// prepare_lens() following this call.
//
// The return value is true if the lens is acceptable,
// false if it is not.
////////////////////////////////////////////////////////////////////
INLINE bool GraphicsStateGuardian::
set_lens(const Lens *lens) {
_current_lens = lens;
return prepare_lens();
}
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
// Function: GraphicsStateGuardian::set_coordinate_system // Function: GraphicsStateGuardian::set_coordinate_system
// Access: Public // Access: Public

View File

@ -21,6 +21,7 @@
#include "config_display.h" #include "config_display.h"
#include "textureContext.h" #include "textureContext.h"
#include "renderBuffer.h" #include "renderBuffer.h"
#include "colorAttrib.h"
#include "clockObject.h" #include "clockObject.h"
#include "geomNode.h" #include "geomNode.h"
@ -93,6 +94,7 @@ GraphicsStateGuardian(GraphicsWindow *win) {
_win = win; _win = win;
_coordinate_system = default_coordinate_system; _coordinate_system = default_coordinate_system;
_current_display_region = (DisplayRegion*)0L; _current_display_region = (DisplayRegion*)0L;
_current_lens = (Lens *)NULL;
reset(); reset();
} }
@ -115,8 +117,10 @@ void GraphicsStateGuardian::
reset() { reset() {
_display_region_stack_level = 0; _display_region_stack_level = 0;
_frame_buffer_stack_level = 0; _frame_buffer_stack_level = 0;
_lens_stack_level = 0;
_state.clear(); _state.clear();
_qpstate = RenderState::make_empty();
_buffer_mask = 0; _buffer_mask = 0;
_color_clear_value.set(gsg_clear_r, gsg_clear_g, gsg_clear_b, 0.0); _color_clear_value.set(gsg_clear_r, gsg_clear_g, gsg_clear_b, 0.0);
@ -125,6 +129,17 @@ reset() {
_accum_clear_value.set(0.0, 0.0, 0.0, 0.0); _accum_clear_value.set(0.0, 0.0, 0.0, 0.0);
_clear_buffer_type = RenderBuffer::T_back | RenderBuffer::T_depth; _clear_buffer_type = RenderBuffer::T_back | RenderBuffer::T_depth;
_normals_enabled = false; _normals_enabled = false;
//Color and alpha transform variables
_color_transform_enabled = false;
_alpha_transform_enabled = false;
_current_color_mat = LMatrix4f::ident_mat();
_current_alpha_offset = 0;
_current_alpha_scale = 1;
_has_scene_graph_color = false;
_issued_color_stale = false;
_vertex_colors_enabled = true;
} }
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
@ -761,6 +776,47 @@ void GraphicsStateGuardian::
release_geom(GeomContext *) { release_geom(GeomContext *) {
} }
////////////////////////////////////////////////////////////////////
// Function: GraphicsStateGuardian::clear_framebuffer
// Access: Public, Virtual
// Description: Erases the contents of the framebuffer, according to
// _clear_buffer_type, which is set by
// enable_frame_clear().
//
// This is used to prepare the framebuffer for drawing
// a new frame.
////////////////////////////////////////////////////////////////////
void GraphicsStateGuardian::
clear_framebuffer() {
if (_clear_buffer_type != 0) {
PT(DisplayRegion) win_dr =
_win->make_scratch_display_region(_win->get_width(), _win->get_height());
nassertv(win_dr != (DisplayRegion*)NULL);
DisplayRegionStack old_dr = push_display_region(win_dr);
prepare_display_region();
clear(get_render_buffer(_clear_buffer_type));
pop_display_region(old_dr);
}
}
////////////////////////////////////////////////////////////////////
// Function: GraphicsStateGuardian::prepare_lens
// Access: Public, Virtual
// Description: Makes the current lens (whichever lens was most
// recently specified with push_lens()) active, so that
// it will transform future rendered geometry. Normally
// this is only called from the draw process, and
// usually it is called immediately after a call to
// push_lens().
//
// The return value is true if the lens is acceptable,
// false if it is not.
////////////////////////////////////////////////////////////////////
bool GraphicsStateGuardian::
prepare_lens() {
return false;
}
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
// Function: GraphicsStateGuardian::wants_normals // Function: GraphicsStateGuardian::wants_normals
// Access: Public, Virtual // Access: Public, Virtual
@ -784,11 +840,12 @@ wants_texcoords() const {
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
// Function: GraphicsStateGuardian::wants_colors // Function: GraphicsStateGuardian::wants_colors
// Access: Public, Virtual // Access: Public, Virtual
// Description: // Description: Returns true if the GSG should issue geometry color
// commands, false otherwise.
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
bool GraphicsStateGuardian:: bool GraphicsStateGuardian::
wants_colors() const { wants_colors() const {
return false; return _vertex_colors_enabled;
} }
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
@ -822,6 +879,49 @@ void GraphicsStateGuardian::
end_decal(GeomNode *) { end_decal(GeomNode *) {
} }
////////////////////////////////////////////////////////////////////
// Function: GraphicsStateGuardian::issue_color
// Access: Public, Virtual
// Description: This method is defined in the base class because it
// is likely that this functionality will be used for
// all (or at least most) kinds of
// GraphicsStateGuardians--it's not specific to any one
// rendering backend.
//
// The ColorAttribute just changes the interpretation of
// the color on the vertices, and fiddles with
// _vertex_colors_enabled, etc.
////////////////////////////////////////////////////////////////////
void GraphicsStateGuardian::
issue_color(const ColorAttrib *attrib) {
switch (attrib->get_color_type()) {
case ColorAttrib::T_flat:
// Color attribute flat: it specifies a scene graph color that
// overrides the vertex color.
_scene_graph_color = attrib->get_color();
_has_scene_graph_color = true;
_vertex_colors_enabled = false;
_issued_color_stale = true;
break;
case ColorAttrib::T_off:
// Color attribute off: it specifies that no scene graph color is
// in effect, and vertex color is not important either.
_has_scene_graph_color = false;
_issued_color_stale = false;
_vertex_colors_enabled = false;
break;
case ColorAttrib::T_vertex:
// Color attribute vertex: it specifies that vertex color should
// be revealed.
_has_scene_graph_color = false;
_issued_color_stale = false;
_vertex_colors_enabled = true;
break;
}
}
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
// Function: GraphicsStateGuardian::mark_prepared_texture // Function: GraphicsStateGuardian::mark_prepared_texture
// Access: Protected // Access: Protected

View File

@ -24,6 +24,7 @@
#include "savedFrameBuffer.h" #include "savedFrameBuffer.h"
#include "frameBufferStack.h" #include "frameBufferStack.h"
#include "displayRegionStack.h" #include "displayRegionStack.h"
#include "lensStack.h"
#include "graphicsStateGuardianBase.h" #include "graphicsStateGuardianBase.h"
#include "nodeTransition.h" #include "nodeTransition.h"
@ -34,7 +35,9 @@
#include "renderTraverser.h" #include "renderTraverser.h"
#include "pStatCollector.h" #include "pStatCollector.h"
#include "allTransitionsWrapper.h" #include "allTransitionsWrapper.h"
#include "renderState.h"
#include "notify.h"
#include "pvector.h" #include "pvector.h"
class AllTransitionsWrapper; class AllTransitionsWrapper;
@ -101,8 +104,10 @@ public:
virtual void clear(const RenderBuffer &buffer)=0; virtual void clear(const RenderBuffer &buffer)=0;
virtual void clear(const RenderBuffer &buffer, const DisplayRegion* region)=0; virtual void clear(const RenderBuffer &buffer, const DisplayRegion* region)=0;
virtual void clear_framebuffer();
virtual void prepare_display_region()=0; virtual void prepare_display_region()=0;
virtual bool prepare_lens();
virtual void render_frame()=0; virtual void render_frame()=0;
virtual void render_scene(Node *root, LensNode *projnode)=0; virtual void render_scene(Node *root, LensNode *projnode)=0;
@ -119,27 +124,32 @@ public:
// These functions will be queried by the GeomIssuer to determine if // These functions will be queried by the GeomIssuer to determine if
// it should issue normals, texcoords, and/or colors, based on the // it should issue normals, texcoords, and/or colors, based on the
// GSG's current state. // GSG's current state.
virtual bool wants_normals(void) const; virtual bool wants_normals() const;
virtual bool wants_texcoords(void) const; virtual bool wants_texcoords() const;
virtual bool wants_colors(void) const; virtual bool wants_colors() const;
virtual void begin_decal(GeomNode *base_geom, AllTransitionsWrapper &attrib); virtual void begin_decal(GeomNode *base_geom, AllTransitionsWrapper &attrib);
virtual void end_decal(GeomNode *base_geom); virtual void end_decal(GeomNode *base_geom);
virtual void reset(); virtual void reset();
// *** QP
void modify_state(const NodeTransitions &new_state); void modify_state(const NodeTransitions &new_state);
// void modify_state(const NodeTransitionCache &new_state); // void modify_state(const NodeTransitionCache &new_state);
void set_state(const NodeTransitionCache &new_state); void set_state(const NodeTransitionCache &new_state);
INLINE void set_state(const AllTransitionsWrapper &new_state); INLINE void set_state(const AllTransitionsWrapper &new_state);
// INLINE const NodeTransitionCache *get_state() const; // INLINE const NodeTransitionCache *get_state() const;
INLINE void modify_state(const RenderState *state);
INLINE void set_state(const RenderState *state);
RenderBuffer get_render_buffer(int buffer_type); RenderBuffer get_render_buffer(int buffer_type);
INLINE LensNode *get_current_camera(void) const ; INLINE LensNode *get_current_camera(void) const ;
INLINE const Node* get_current_root_node(void) const; INLINE const Node* get_current_root_node(void) const;
INLINE const DisplayRegion *get_current_display_region(void) const; INLINE const DisplayRegion *get_current_display_region(void) const;
INLINE const Lens *get_current_lens() const;
INLINE DisplayRegionStack push_display_region(const DisplayRegion *dr); INLINE DisplayRegionStack push_display_region(const DisplayRegion *dr);
INLINE void pop_display_region(DisplayRegionStack &node); INLINE void pop_display_region(DisplayRegionStack &node);
@ -147,6 +157,10 @@ public:
const DisplayRegion *dr); const DisplayRegion *dr);
INLINE void pop_frame_buffer(FrameBufferStack &node); INLINE void pop_frame_buffer(FrameBufferStack &node);
INLINE LensStack push_lens(const Lens *lens);
INLINE void pop_lens(LensStack &stack);
INLINE bool set_lens(const Lens *lens);
INLINE void set_coordinate_system(CoordinateSystem cs); INLINE void set_coordinate_system(CoordinateSystem cs);
INLINE CoordinateSystem get_coordinate_system() const; INLINE CoordinateSystem get_coordinate_system() const;
@ -159,6 +173,8 @@ public:
INLINE void clear_cached_state(void) { _state.clear(); }; INLINE void clear_cached_state(void) { _state.clear(); };
virtual void issue_color(const ColorAttrib *attrib);
protected: protected:
virtual PT(SavedFrameBuffer) save_frame_buffer(const RenderBuffer &buffer, virtual PT(SavedFrameBuffer) save_frame_buffer(const RenderBuffer &buffer,
CPT(DisplayRegion) dr)=0; CPT(DisplayRegion) dr)=0;
@ -207,6 +223,8 @@ protected:
typedef pvector<StateInfo> State; typedef pvector<StateInfo> State;
State _state; State _state;
CPT(RenderState) _qpstate;
int _buffer_mask; int _buffer_mask;
Colorf _color_clear_value; Colorf _color_clear_value;
float _depth_clear_value; float _depth_clear_value;
@ -216,6 +234,7 @@ protected:
int _display_region_stack_level; int _display_region_stack_level;
int _frame_buffer_stack_level; int _frame_buffer_stack_level;
int _lens_stack_level;
GraphicsWindow *_win; GraphicsWindow *_win;
PT(RenderTraverser) _render_traverser; PT(RenderTraverser) _render_traverser;
@ -225,11 +244,24 @@ protected:
LensNode *_current_camera; LensNode *_current_camera;
CPT(DisplayRegion) _current_display_region; CPT(DisplayRegion) _current_display_region;
CPT(Lens) _current_lens;
// This is used by wants_normals() // This is used by wants_normals()
bool _normals_enabled; bool _normals_enabled;
CoordinateSystem _coordinate_system; CoordinateSystem _coordinate_system;
Colorf _scene_graph_color;
bool _has_scene_graph_color;
bool _issued_color_stale;
bool _vertex_colors_enabled;
bool _color_transform_enabled;
bool _alpha_transform_enabled;
LMatrix4f _current_color_mat;
float _current_alpha_offset;
float _current_alpha_scale;
public: public:
// Statistics // Statistics
static PStatCollector _total_texusage_pcollector; static PStatCollector _total_texusage_pcollector;

View File

@ -418,6 +418,19 @@ render_and_update() {
update(); update();
} }
////////////////////////////////////////////////////////////////////
// Function: GraphicsWindow::win_display_regions_changed
// Access: Public
// Description: Intended to be called when the active state on a
// nested channel or layer or display region changes,
// forcing the window to recompute its list of active
// display regions.
////////////////////////////////////////////////////////////////////
INLINE void GraphicsWindow::
win_display_regions_changed() {
_display_regions_stale = true;
}
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
// Function: GraphicsWindow::set_sync // Function: GraphicsWindow::set_sync
// Access: Public // Access: Public
@ -441,3 +454,45 @@ get_sync() const {
return _is_synced; return _is_synced;
} }
////////////////////////////////////////////////////////////////////
// Function: GraphicsWindow::get_num_display_regions
// Access: Published
// Description: Returns the number of active DisplayRegions that have
// been created within the various layers and channels
// of the window.
////////////////////////////////////////////////////////////////////
INLINE int GraphicsWindow::
get_num_display_regions() const {
determine_display_regions();
return _display_regions.size();
}
////////////////////////////////////////////////////////////////////
// Function: GraphicsWindow::get_display_region
// Access: Published
// Description: Returns the nth active DisplayRegion of those that
// have been created within the various layers and
// channels of the window.
////////////////////////////////////////////////////////////////////
INLINE DisplayRegion *GraphicsWindow::
get_display_region(int n) const {
determine_display_regions();
nassertr(n >= 0 && n < (int)_display_regions.size(), NULL);
return _display_regions[n];
}
////////////////////////////////////////////////////////////////////
// Function: GraphicsWindow::determine_display_regions
// Access: Private
// Description: Recomputes the list of active DisplayRegions within
// the window, if they have changed recently.
////////////////////////////////////////////////////////////////////
INLINE void GraphicsWindow::
determine_display_regions() const {
// This function isn't strictly speaking const, but we pretend it is
// because it only updates a transparent cache value.
if (_display_regions_stale) {
((GraphicsWindow *)this)->do_determine_display_regions();
}
}

View File

@ -142,6 +142,7 @@ GraphicsWindow(GraphicsPipe *pipe) : Configurable() {
_idle_callback = NULL; _idle_callback = NULL;
_frame_number = 0; _frame_number = 0;
_is_synced = false; _is_synced = false;
_display_regions_stale = false;
} }
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
@ -350,6 +351,40 @@ declare_channel(int index, GraphicsChannel *chan) {
_channels[index] = chan; _channels[index] = chan;
} }
////////////////////////////////////////////////////////////////////
// Function: GraphicsWindow::do_determine_display_regions
// Access: Private
// Description: Recomputes the list of active DisplayRegions within
// the window.
////////////////////////////////////////////////////////////////////
void GraphicsWindow::
do_determine_display_regions() {
_display_regions.clear();
Channels::const_iterator ci;
for (ci = _channels.begin(); ci != _channels.end(); ++ci) {
GraphicsChannel *chan = (*ci);
if (chan->is_active()) {
GraphicsChannel::GraphicsLayers::const_iterator li;
for (li = chan->_layers.begin(); li != chan->_layers.end(); ++li) {
GraphicsLayer *layer = (*li);
if (layer->is_active()) {
GraphicsLayer::DisplayRegions::const_iterator dri;
for (dri = layer->_display_regions.begin();
dri != layer->_display_regions.end();
++dri) {
DisplayRegion *dr = (*dri);
if (dr->is_active()) {
_display_regions.push_back(dr);
}
}
}
}
}
}
_display_regions_stale = false;
}
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
// Function: GraphicsWindow::register_draw_function // Function: GraphicsWindow::register_draw_function
// Access: Public, Virtual // Access: Public, Virtual
@ -413,6 +448,33 @@ void GraphicsWindow::
update() { update() {
} }
////////////////////////////////////////////////////////////////////
// Function: GraphicsWindow::clear
// Access: Public
// Description: Invokes the GSG to clear the entire contents of the
// window prior to drawing into it. This is normally
// called only by the draw process at the beginning of
// the frame.
////////////////////////////////////////////////////////////////////
void GraphicsWindow::
clear() {
_gsg->clear_framebuffer();
}
////////////////////////////////////////////////////////////////////
// Function: GraphicsWindow::flip
// Access: Public, Virtual
// Description: Flips the back buffer and front buffer, or does
// whatever other processing is appropriate, after the
// frame has been completely drawn. Normally this is
// only called by the draw process between frames, in
// sync with all the other windows.
////////////////////////////////////////////////////////////////////
void GraphicsWindow::
flip() {
end_frame();
}
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
// Function: GraphicsWindow::begin_frame // Function: GraphicsWindow::begin_frame
// Access: Public, Virtual // Access: Public, Virtual

View File

@ -63,6 +63,7 @@ enum WindowModeType
class GraphicsPipe; class GraphicsPipe;
class GraphicsWindow; class GraphicsWindow;
class CullHandler;
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
// Class : GraphicsWindow // Class : GraphicsWindow
@ -109,14 +110,10 @@ public:
public: public:
GraphicsWindow(GraphicsPipe*); GraphicsWindow(GraphicsPipe*);
#ifdef WIN32_VC
GraphicsWindow(GraphicsPipe*, const Properties&); GraphicsWindow(GraphicsPipe*, const Properties&);
#else
GraphicsWindow(GraphicsPipe*, const GraphicsWindow::Properties&);
#endif
virtual ~GraphicsWindow(); virtual ~GraphicsWindow();
INLINE const GraphicsWindow::Properties& get_properties() const; INLINE const Properties& get_properties() const;
PUBLISHED: PUBLISHED:
INLINE int get_width() const; INLINE int get_width() const;
@ -191,17 +188,24 @@ PUBLISHED:
virtual void register_draw_function(GraphicsWindow::vfn); virtual void register_draw_function(GraphicsWindow::vfn);
virtual void register_idle_function(GraphicsWindow::vfn); virtual void register_idle_function(GraphicsWindow::vfn);
// Old-style scene graph rendering (will be phased out eventually).
virtual void main_loop(); virtual void main_loop();
virtual bool supports_update() const; virtual bool supports_update() const;
virtual void update(); virtual void update();
INLINE void render_and_update(); INLINE void render_and_update();
public: public:
// New-style scene graph rendering (not yet complete).
void clear();
virtual void flip();
virtual void begin_frame(); virtual void begin_frame();
virtual void end_frame(); virtual void end_frame();
virtual void deactivate_window(void); virtual void deactivate_window(void);
virtual void reactivate_window(void); virtual void reactivate_window(void);
INLINE void win_display_regions_changed();
// Statistics // Statistics
static PStatCollector _app_pcollector; static PStatCollector _app_pcollector;
static PStatCollector _show_code_pcollector; static PStatCollector _show_code_pcollector;
@ -241,13 +245,23 @@ PUBLISHED:
int get_max_channel_index() const; int get_max_channel_index() const;
bool is_channel_defined(int index) const; bool is_channel_defined(int index) const;
INLINE int get_num_display_regions() const;
INLINE DisplayRegion *get_display_region(int n) const;
protected: protected:
void declare_channel(int index, GraphicsChannel *chan); void declare_channel(int index, GraphicsChannel *chan);
private: private:
INLINE void determine_display_regions() const;
void do_determine_display_regions();
typedef pvector< PT(GraphicsChannel) > Channels; typedef pvector< PT(GraphicsChannel) > Channels;
Channels _channels; Channels _channels;
typedef pvector<DisplayRegion *> DisplayRegions;
DisplayRegions _display_regions;
bool _display_regions_stale;
public: public:
// factory stuff // factory stuff

View File

@ -0,0 +1,61 @@
// Filename: lensStack.I
// Created by: drose (25Feb02)
//
////////////////////////////////////////////////////////////////////
//
// 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 .
//
////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////
// Function: LensStack::Constructor
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
INLINE LensStack::
LensStack() {
_stack_level = -1;
}
////////////////////////////////////////////////////////////////////
// Function: LensStack::Destructor
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
INLINE LensStack::
~LensStack() {
}
////////////////////////////////////////////////////////////////////
// Function: LensStack::Copy Constructor
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
INLINE LensStack::
LensStack(const LensStack &copy) :
_lens(copy._lens),
_stack_level(copy._stack_level)
{
}
////////////////////////////////////////////////////////////////////
// Function: LensStack::Copy Operator
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
INLINE void LensStack::
operator =(const LensStack &copy) {
_lens = copy._lens;
_stack_level = copy._stack_level;
}

View File

@ -0,0 +1,50 @@
// Filename: lensStack.h
// Created by: drose (25Feb02)
//
////////////////////////////////////////////////////////////////////
//
// 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 LENSSTACK_H
#define LENSSTACK_H
#include <pandabase.h>
#include "lens.h"
class GraphicsStateGuardian;
////////////////////////////////////////////////////////////////////
// Class : LensStack
// Description : An instance of this kind of object is returned by
// GraphicsStateGuardian::push_lens(). It holds the
// information needed to restore the previous display
// region in the subsequent matching call to pop_lens().
////////////////////////////////////////////////////////////////////
class LensStack {
public:
INLINE LensStack();
INLINE ~LensStack();
INLINE LensStack(const LensStack &copy);
INLINE void operator =(const LensStack &copy);
private:
CPT(Lens) _lens;
int _stack_level;
friend class GraphicsStateGuardian;
};
#include "lensStack.I"
#endif

View File

@ -65,6 +65,7 @@
#include "stencilTransition.h" #include "stencilTransition.h"
#include "pointShapeTransition.h" #include "pointShapeTransition.h"
#include "polygonOffsetTransition.h" #include "polygonOffsetTransition.h"
#include "textureAttrib.h"
#include "clockObject.h" #include "clockObject.h"
#include "string_utils.h" #include "string_utils.h"
#include "dcast.h" #include "dcast.h"
@ -300,17 +301,6 @@ reset() {
_current_projection_mat = LMatrix4f::ident_mat(); _current_projection_mat = LMatrix4f::ident_mat();
_projection_mat_stack_count = 0; _projection_mat_stack_count = 0;
//Color and alpha transform variables
_color_transform_enabled = false;
_alpha_transform_enabled = false;
_current_color_mat = LMatrix4f::ident_mat();
_current_alpha_offset = 0;
_current_alpha_scale = 1;
_has_scene_graph_color = false;
_issued_color_stale = false;
_vertex_colors_enabled = true;
// Make sure the GL state matches all of our initial attribute // Make sure the GL state matches all of our initial attribute
// states. // states.
PT(DepthTestTransition) dta = new DepthTestTransition; PT(DepthTestTransition) dta = new DepthTestTransition;
@ -462,6 +452,51 @@ prepare_display_region() {
} }
} }
////////////////////////////////////////////////////////////////////
// Function: GLGraphicsStateGuardian::prepare_lens
// Access: Public, Virtual
// Description: Makes the current lens (whichever lens was most
// recently specified with push_lens()) active, so that
// it will transform future rendered geometry. Normally
// this is only called from the draw process, and
// usually it is called immediately after a call to
// push_lens().
//
// The return value is true if the lens is acceptable,
// false if it is not.
////////////////////////////////////////////////////////////////////
bool GLGraphicsStateGuardian::
prepare_lens() {
if (_current_lens == (Lens *)NULL) {
return false;
}
if (!_current_lens->is_linear()) {
return false;
}
const LMatrix4f &projection_mat = _current_lens->get_projection_mat();
// The projection matrix must always be right-handed Y-up, even if
// our coordinate system of choice is otherwise, because certain GL
// calls (specifically glTexGen(GL_SPHERE_MAP)) assume this kind of
// a coordinate system. Sigh. In order to implement a Z-up (or
// other arbitrary) coordinate system, we'll use a Y-up projection
// matrix, and store the conversion to our coordinate system of
// choice in the modelview matrix.
LMatrix4f new_projection_mat =
LMatrix4f::convert_mat(CS_yup_right, _current_lens->get_coordinate_system()) *
projection_mat;
#ifdef GSG_VERBOSE
glgsg_cat.debug()
<< "glMatrixMode(GL_PROJECTION): " << new_projection_mat << endl;
#endif
glMatrixMode(GL_PROJECTION);
glLoadMatrixf(new_projection_mat.get_data());
return true;
}
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
@ -498,16 +533,8 @@ render_frame() {
clear_attribute(TextureTransition::get_class_type()); clear_attribute(TextureTransition::get_class_type());
#endif #endif
if (_clear_buffer_type != 0) {
// First, clear the entire window. // First, clear the entire window.
PT(DisplayRegion) win_dr = clear_framebuffer();
_win->make_scratch_display_region(_win->get_width(), _win->get_height());
nassertv(win_dr != (DisplayRegion*)NULL);
DisplayRegionStack old_dr = push_display_region(win_dr);
prepare_display_region();
clear(get_render_buffer(_clear_buffer_type));
pop_display_region(old_dr);
}
// Now render each of our layers in order. // Now render each of our layers in order.
int max_channel_index = _win->get_max_channel_index(); int max_channel_index = _win->get_max_channel_index();
@ -624,38 +651,16 @@ render_subgraph(RenderTraverser *traverser,
// activate(); // activate();
Lens *lens = projnode->get_lens(); Lens *lens = projnode->get_lens();
if (!lens->is_linear()) { LensNode *old_camera = _current_camera;
_current_camera = projnode;
LensStack lens_stack = push_lens(lens);
if (!prepare_lens()) {
glgsg_cat.error() glgsg_cat.error()
<< "Cannot render with a nonlinear lens!\n"; << "Cannot render with a nonlinear lens!\n";
return; return;
} }
LensNode *old_camera = _current_camera;
_current_camera = projnode;
LMatrix4f old_projection_mat = _current_projection_mat;
const LMatrix4f &projection_mat = lens->get_projection_mat();
// The projection matrix must always be right-handed Y-up, even if
// our coordinate system of choice is otherwise, because certain GL
// calls (specifically glTexGen(GL_SPHERE_MAP)) assume this kind of
// a coordinate system. Sigh. In order to implement a Z-up (or
// other arbitrary) coordinate system, we'll use a Y-up projection
// matrix, and store the conversion to our coordinate system of
// choice in the modelview matrix.
_current_projection_mat =
LMatrix4f::convert_mat(CS_yup_right, lens->get_coordinate_system()) *
projection_mat;
_projection_mat_stack_count++;
// We load the projection matrix directly.
#ifdef GSG_VERBOSE
glgsg_cat.debug()
<< "glMatrixMode(GL_PROJECTION): " << _current_projection_mat << endl;
#endif
glMatrixMode(GL_PROJECTION);
glLoadMatrixf(_current_projection_mat.get_data());
// We infer the modelview matrix by doing a wrt on the lens // We infer the modelview matrix by doing a wrt on the lens
// node. // node.
LMatrix4f modelview_mat; LMatrix4f modelview_mat;
@ -677,18 +682,8 @@ render_subgraph(RenderTraverser *traverser,
render_subgraph(traverser, subgraph, sub_trans); render_subgraph(traverser, subgraph, sub_trans);
_current_camera = old_camera; _current_camera = old_camera;
_current_projection_mat = old_projection_mat;
_projection_mat_stack_count--;
pop_lens(lens_stack);
// We must now restore the projection matrix from before. We could
// do a push/pop matrix, but OpenGL doesn't promise more than 2
// levels in the projection matrix stack, so we'd better do it in
// the CPU.
if (_projection_mat_stack_count > 0) {
glMatrixMode(GL_PROJECTION);
glLoadMatrixf(_current_projection_mat.get_data());
}
} }
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
@ -3420,6 +3415,24 @@ issue_polygon_offset(const PolygonOffsetTransition *attrib) {
report_errors(); report_errors();
} }
////////////////////////////////////////////////////////////////////
// Function: GLGraphicsStateGuardian::issue_texture
// Access: Public, Virtual
// Description:
////////////////////////////////////////////////////////////////////
void GLGraphicsStateGuardian::
issue_texture(const TextureAttrib *attrib) {
if (attrib->is_off()) {
enable_texturing(false);
} else {
enable_texturing(true);
Texture *tex = attrib->get_texture();
nassertv(tex != (Texture *)NULL);
tex->apply(this);
}
report_errors();
}
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
// Function: GLGraphicsStateGuardian::wants_normals // Function: GLGraphicsStateGuardian::wants_normals
// Access: Public, Virtual // Access: Public, Virtual
@ -3440,17 +3453,6 @@ wants_texcoords() const {
return _texturing_enabled; return _texturing_enabled;
} }
////////////////////////////////////////////////////////////////////
// Function: GLGraphicsStateGuardian::wants_colors
// Access: Public, Virtual
// Description: Returns true if the GSG should issue geometry color
// commands, false otherwise.
////////////////////////////////////////////////////////////////////
bool GLGraphicsStateGuardian::
wants_colors() const {
return _vertex_colors_enabled;
}
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
// Function: GLGraphicsStateGuardian::begin_decal // Function: GLGraphicsStateGuardian::begin_decal
// Access: Public, Virtual // Access: Public, Virtual

View File

@ -74,6 +74,7 @@ public:
virtual void clear(const RenderBuffer &buffer, const DisplayRegion* region); virtual void clear(const RenderBuffer &buffer, const DisplayRegion* region);
virtual void prepare_display_region(); virtual void prepare_display_region();
virtual bool prepare_lens();
virtual void render_frame(); virtual void render_frame();
virtual void render_scene(Node *root, LensNode *projnode); virtual void render_scene(Node *root, LensNode *projnode);
@ -155,9 +156,10 @@ public:
virtual void issue_point_shape(const PointShapeTransition *attrib); virtual void issue_point_shape(const PointShapeTransition *attrib);
virtual void issue_polygon_offset(const PolygonOffsetTransition *attrib); virtual void issue_polygon_offset(const PolygonOffsetTransition *attrib);
virtual void issue_texture(const TextureAttrib *attrib);
virtual bool wants_normals(void) const; virtual bool wants_normals(void) const;
virtual bool wants_texcoords(void) const; virtual bool wants_texcoords(void) const;
virtual bool wants_colors(void) const;
virtual void begin_decal(GeomNode *base_geom, AllTransitionsWrapper &attrib); virtual void begin_decal(GeomNode *base_geom, AllTransitionsWrapper &attrib);
virtual void end_decal(GeomNode *base_geom); virtual void end_decal(GeomNode *base_geom);
@ -326,8 +328,6 @@ protected:
bool _dithering_enabled; bool _dithering_enabled;
bool _alpha_test_enabled; bool _alpha_test_enabled;
bool _polygon_offset_enabled; bool _polygon_offset_enabled;
bool _color_transform_enabled;
bool _alpha_transform_enabled;
int _decal_level; int _decal_level;
class LightInfo { class LightInfo {
@ -353,15 +353,6 @@ protected:
CPT(DisplayRegion) _actual_display_region; CPT(DisplayRegion) _actual_display_region;
LMatrix4f _current_color_mat;
float _current_alpha_offset;
float _current_alpha_scale;
Colorf _scene_graph_color;
bool _has_scene_graph_color;
bool _issued_color_stale;
bool _vertex_colors_enabled;
int _pass_number; int _pass_number;
public: public:

View File

@ -75,6 +75,9 @@ class LinesmoothTransition;
class PointShapeTransition; class PointShapeTransition;
class PolygonOffsetTransition; class PolygonOffsetTransition;
class TextureAttrib;
class ColorAttrib;
class Node; class Node;
class GeomNode; class GeomNode;
class PointLight; class PointLight;
@ -188,6 +191,9 @@ public:
virtual void issue_point_shape(const PointShapeTransition *) { } virtual void issue_point_shape(const PointShapeTransition *) { }
virtual void issue_polygon_offset(const PolygonOffsetTransition *) { } virtual void issue_polygon_offset(const PolygonOffsetTransition *) { }
virtual void issue_texture(const TextureAttrib *) { }
virtual void issue_color(const ColorAttrib *) { }
PUBLISHED: PUBLISHED:
static TypeHandle get_class_type() { static TypeHandle get_class_type() {
return _type_handle; return _type_handle;

View File

@ -1,6 +1,6 @@
#define OTHER_LIBS interrogatedb:c dconfig:c dtoolconfig:m \ #define OTHER_LIBS interrogatedb:c dconfig:c dtoolconfig:m \
dtoolutil:c dtoolbase:c dtool:m dtoolutil:c dtoolbase:c dtool:m
#define LOCAL_LIBS gobj putil graph linmath express pandabase #define LOCAL_LIBS gsgbase gobj putil graph linmath express pandabase
#begin lib_target #begin lib_target
#define TARGET pgraph #define TARGET pgraph

View File

@ -17,6 +17,7 @@
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
#include "colorAttrib.h" #include "colorAttrib.h"
#include "graphicsStateGuardianBase.h"
#include "dcast.h" #include "dcast.h"
#include "bamReader.h" #include "bamReader.h"
#include "bamWriter.h" #include "bamWriter.h"
@ -63,6 +64,20 @@ make_off() {
return return_new(attrib); return return_new(attrib);
} }
////////////////////////////////////////////////////////////////////
// Function: ColorAttrib::issue
// Access: Public, Virtual
// Description: Calls the appropriate method on the indicated GSG
// to issue the graphics commands appropriate to the
// given attribute. This is normally called
// (indirectly) only from
// GraphicsStateGuardian::set_state() or modify_state().
////////////////////////////////////////////////////////////////////
void ColorAttrib::
issue(GraphicsStateGuardianBase *gsg) const {
gsg->issue_color(this);
}
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
// Function: ColorAttrib::output // Function: ColorAttrib::output
// Access: Public, Virtual // Access: Public, Virtual

View File

@ -48,6 +48,7 @@ PUBLISHED:
INLINE const Colorf &get_color() const; INLINE const Colorf &get_color() const;
public: public:
virtual void issue(GraphicsStateGuardianBase *gsg) const;
virtual void output(ostream &out) const; virtual void output(ostream &out) const;
protected: protected:

View File

@ -21,7 +21,7 @@
#include "renderState.h" #include "renderState.h"
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
// Function: CullHandler::found_geom // Function: CullHandler::record_geom
// Access: Public, Virtual // Access: Public, Virtual
// Description: This callback function is intended to be overridden // Description: This callback function is intended to be overridden
// by a derived class. This is called as each Geom is // by a derived class. This is called as each Geom is
@ -31,6 +31,6 @@
// it's not intended to be used except for debugging. // it's not intended to be used except for debugging.
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
void CullHandler:: void CullHandler::
found_geom(Geom *geom, const RenderState *state) { record_geom(Geom *geom, const RenderState *state) {
cerr << *geom << " " << *state << "\n"; cerr << *geom << " " << *state << "\n";
} }

View File

@ -29,11 +29,14 @@ class RenderState;
// Description : This defines the abstract interface for an object // Description : This defines the abstract interface for an object
// that receives Geoms identified by the CullTraverser. // that receives Geoms identified by the CullTraverser.
// By itself, it's not a particularly useful class; to // By itself, it's not a particularly useful class; to
// use it, derive from it and redefine found_geom(). // use it, derive from it and redefine record_geom().
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
class EXPCL_PANDA CullHandler { class EXPCL_PANDA CullHandler {
public: public:
virtual void found_geom(Geom *geom, const RenderState *state); // virtual void begin_decal();
virtual void record_geom(Geom *geom, const RenderState *state);
// virtual void push_decal();
// virtual void pop_decal();
}; };
#endif #endif

View File

@ -187,14 +187,14 @@ get_child(int n) const {
} }
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
// Function: PandaNode::get_sort // Function: PandaNode::get_child_sort
// Access: Published // Access: Published
// Description: Returns the sort index of the nth child node of this // Description: Returns the sort index of the nth child node of this
// node (that is, the number that was passed to // node (that is, the number that was passed to
// add_child()). See get_num_children(). // add_child()). See get_num_children().
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
INLINE int PandaNode:: INLINE int PandaNode::
get_sort(int n) const { get_child_sort(int n) const {
CDReader cdata(_cycler); CDReader cdata(_cycler);
nassertr(n >= 0 && n < (int)cdata->_down.size(), -1); nassertr(n >= 0 && n < (int)cdata->_down.size(), -1);
return cdata->_down[n].get_sort(); return cdata->_down[n].get_sort();

View File

@ -55,13 +55,21 @@ PUBLISHED:
INLINE int get_num_children() const; INLINE int get_num_children() const;
INLINE PandaNode *get_child(int n) const; INLINE PandaNode *get_child(int n) const;
INLINE int get_sort(int n) const; INLINE int get_child_sort(int n) const;
int find_child(PandaNode *node) const; int find_child(PandaNode *node) const;
int add_child(PandaNode *child, int sort = 0); int add_child(PandaNode *child, int sort = 0);
void remove_child(int n); void remove_child(int n);
bool remove_child(PandaNode *child); bool remove_child(PandaNode *child);
/*
bool stash_child(PandaNode *child);
bool unstash_child(PandaNode *child);
INLINE int get_num_stashed() const;
INLINE PandaNode *get_stashed(int n) const;
INLINE PandaNode *get_stashed_sort(int n) const;
*/
void remove_all_children(); void remove_all_children();
INLINE void set_attrib(const RenderAttrib *attrib, int override = 0); INLINE void set_attrib(const RenderAttrib *attrib, int override = 0);

View File

@ -42,23 +42,11 @@ Pipeline::
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
// Function: Pipeline::cycle // Function: Pipeline::cycle
// Access: Public // Access: Public, Virtual
// Description: Flows all the pipeline data down to the next stage. // Description: Flows all the pipeline data down to the next stage.
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
void Pipeline:: void Pipeline::
cycle() { cycle() {
pre_cycle();
}
////////////////////////////////////////////////////////////////////
// Function: Pipeline::pre_cycle
// Access: Protected, Virtual
// Description: A callback function intended to be overridden by a
// derived class to perform whatever operations should
// be done before cycling the pipeline.
////////////////////////////////////////////////////////////////////
void Pipeline::
pre_cycle() {
} }
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////

View File

@ -42,10 +42,7 @@ public:
INLINE static Pipeline *get_render_pipeline(); INLINE static Pipeline *get_render_pipeline();
void cycle(); virtual void cycle();
protected:
virtual void pre_cycle();
private: private:
static void make_render_pipeline(); static void make_render_pipeline();

View File

@ -104,7 +104,7 @@ r_traverse(PandaNode *node, const RenderState *state, int flags) {
Geom *geom = geom_node->get_geom(i); Geom *geom = geom_node->get_geom(i);
CPT(RenderState) geom_state = CPT(RenderState) geom_state =
next_state->compose(geom_node->get_geom_state(i)); next_state->compose(geom_node->get_geom_state(i));
_cull_handler->found_geom(geom, geom_state); _cull_handler->record_geom(geom, geom_state);
} }
} }

View File

@ -32,6 +32,27 @@ compose(const RenderAttrib *other) const {
return compose_impl(other); return compose_impl(other);
} }
////////////////////////////////////////////////////////////////////
// Function: RenderAttrib::invert_compose
// Access: Public
// Description: Returns a new RenderAttrib object that represents the
// composition of the inverse of this attrib with the
// other attrib. In most cases, this is the same as the
// other attrib; !a compose b produces b. Some kinds of
// attributes, like a TextureTransform, for instance,
// might produce a new result: !a compose b produces c.
//
// This is similar to compose() except that the source
// attrib is inverted first. This is used to compute
// the relative attribute for one node as viewed from
// some other node, which is especially useful for
// transform-type attributes.
////////////////////////////////////////////////////////////////////
INLINE CPT(RenderAttrib) RenderAttrib::
invert_compose(const RenderAttrib *other) const {
return invert_compose_impl(other);
}
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
// Function: RenderAttrib::make_default // Function: RenderAttrib::make_default
// Access: Public // Access: Public

View File

@ -68,8 +68,21 @@ RenderAttrib::
} }
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
// Function: RenderAttrib::output // Function: RenderAttrib::issue
// Access: Public, Virtual // Access: Public, Virtual
// Description: Calls the appropriate method on the indicated GSG
// to issue the graphics commands appropriate to the
// given attribute. This is normally called
// (indirectly) only from
// GraphicsStateGuardian::set_state() or modify_state().
////////////////////////////////////////////////////////////////////
void RenderAttrib::
issue(GraphicsStateGuardianBase *) const {
}
////////////////////////////////////////////////////////////////////
// Function: RenderAttrib::output
// Access: Published, Virtual
// Description: // Description:
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
void RenderAttrib:: void RenderAttrib::
@ -79,7 +92,7 @@ output(ostream &out) const {
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
// Function: RenderAttrib::write // Function: RenderAttrib::write
// Access: Public, Virtual // Access: Published, Virtual
// Description: // Description:
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
void RenderAttrib:: void RenderAttrib::
@ -167,6 +180,20 @@ compose_impl(const RenderAttrib *other) const {
return other; return other;
} }
////////////////////////////////////////////////////////////////////
// Function: RenderAttrib::invert_compose_impl
// Access: Protected, Virtual
// Description: Intended to be overridden by derived RenderAttrib
// types to specify how two consecutive RenderAttrib
// objects of the same type interact.
//
// See invert_compose() and compose_impl().
////////////////////////////////////////////////////////////////////
CPT(RenderAttrib) RenderAttrib::
invert_compose_impl(const RenderAttrib *other) const {
return other;
}
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
// Function: RenderAttrib::make_default_impl // Function: RenderAttrib::make_default_impl
// Access: Protected, Virtual // Access: Protected, Virtual

View File

@ -26,6 +26,8 @@
#include "pointerTo.h" #include "pointerTo.h"
#include "pset.h" #include "pset.h"
class GraphicsStateGuardianBase;
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
// Class : RenderAttrib // Class : RenderAttrib
// Description : This is the base class for a number of render // Description : This is the base class for a number of render
@ -54,8 +56,10 @@ public:
virtual ~RenderAttrib(); virtual ~RenderAttrib();
INLINE CPT(RenderAttrib) compose(const RenderAttrib *other) const; INLINE CPT(RenderAttrib) compose(const RenderAttrib *other) const;
INLINE CPT(RenderAttrib) invert_compose(const RenderAttrib *other) const;
INLINE CPT(RenderAttrib) make_default() const; INLINE CPT(RenderAttrib) make_default() const;
INLINE int compare_to(const RenderAttrib &other) const; INLINE int compare_to(const RenderAttrib &other) const;
virtual void issue(GraphicsStateGuardianBase *gsg) const;
PUBLISHED: PUBLISHED:
virtual void output(ostream &out) const; virtual void output(ostream &out) const;
@ -66,6 +70,7 @@ protected:
virtual int compare_to_impl(const RenderAttrib *other) const; virtual int compare_to_impl(const RenderAttrib *other) const;
virtual CPT(RenderAttrib) compose_impl(const RenderAttrib *other) const; virtual CPT(RenderAttrib) compose_impl(const RenderAttrib *other) const;
virtual CPT(RenderAttrib) invert_compose_impl(const RenderAttrib *other) const;
virtual RenderAttrib *make_default_impl() const=0; virtual RenderAttrib *make_default_impl() const=0;
private: private:

View File

@ -121,6 +121,18 @@ RenderState::
++ci; ++ci;
} }
// A similar bit of code for the invert cache.
ci = _invert_composition_cache.begin();
while (ci != _invert_composition_cache.end()) {
{
PT(RenderState) other = (RenderState *)(*ci).first;
Composition comp = (*ci).second;
nassertv(other != (const RenderState *)this);
other->_invert_composition_cache.erase(this);
}
++ci;
}
// Also, if we called compose(this) at some point and the return // Also, if we called compose(this) at some point and the return
// value was something other than this, we need to decrement the // value was something other than this, we need to decrement the
// associated reference count. // associated reference count.
@ -270,8 +282,6 @@ compose(const RenderState *other) const {
// but we pretend that it is because it's only a cache which is // but we pretend that it is because it's only a cache which is
// transparent to the rest of the interface. // transparent to the rest of the interface.
cerr << "composing " << *this << " with " << *other << "\n";
// We handle empty state (identity) as a trivial special case. // We handle empty state (identity) as a trivial special case.
if (is_empty()) { if (is_empty()) {
return other; return other;
@ -330,6 +340,68 @@ compose(const RenderState *other) const {
((RenderState *)other)->_composition_cache[this]._result = NULL; ((RenderState *)other)->_composition_cache[this]._result = NULL;
((RenderState *)this)->_composition_cache[other]._result = result; ((RenderState *)this)->_composition_cache[other]._result = result;
return result;
}
////////////////////////////////////////////////////////////////////
// Function: RenderState::invert_compose
// Access: Published
// Description: Returns a new RenderState object that represents the
// composition of this state's inverse with the other
// state.
//
// This is similar to compose(), but is particularly
// useful for computing the relative state of a node as
// viewed from some other node.
////////////////////////////////////////////////////////////////////
CPT(RenderState) RenderState::
invert_compose(const RenderState *other) const {
// This method isn't strictly const, because it updates the cache,
// but we pretend that it is because it's only a cache which is
// transparent to the rest of the interface.
cerr << "invert composing " << *this << " with " << *other << "\n";
// We handle empty state (identity) as a trivial special case.
if (is_empty()) {
return other;
}
// Unlike compose(), the case of other->is_empty() is not quite as
// trivial for invert_compose().
if (other == this) {
// a->invert_compose(a) always produces identity.
return make_empty();
}
// Is this composition already cached?
CompositionCache::const_iterator ci = _invert_composition_cache.find(other);
if (ci != _invert_composition_cache.end()) {
const Composition &comp = (*ci).second;
if (comp._result == (const RenderState *)NULL) {
// Well, it wasn't cached already, but we already had an entry
// (probably created for the reverse direction), so use the same
// entry to store the new result.
((Composition &)comp)._result = do_invert_compose(other);
}
// Here's the cache!
cerr << " returning cached result " << (void *)comp._result.p() << "\n";
return comp._result;
}
// We need to make a new cache entry, both in this object and in the
// other object. We make both records so the other RenderState
// object will know to delete the entry from this object when it
// destructs, and vice-versa.
// The cache entry in this object is the only one that indicates the
// result; the other will be NULL for now.
CPT(RenderState) result = do_invert_compose(other);
// We store them in this order, on the off-chance that other is the
// same as this, a degenerate case which is still worth supporting.
((RenderState *)other)->_invert_composition_cache[this]._result = NULL;
((RenderState *)this)->_invert_composition_cache[other]._result = result;
cerr << " returning new result " << (void *)result.p() << "\n"; cerr << " returning new result " << (void *)result.p() << "\n";
return result; return result;
} }
@ -396,7 +468,7 @@ remove(TypeHandle type) const {
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
// Function: RenderState::output // Function: RenderState::output
// Access: Public, Virtual // Access: Published, Virtual
// Description: // Description:
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
void RenderState:: void RenderState::
@ -417,7 +489,7 @@ output(ostream &out) const {
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
// Function: RenderState::write // Function: RenderState::write
// Access: Public, Virtual // Access: Published, Virtual
// Description: // Description:
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
void RenderState:: void RenderState::
@ -430,6 +502,149 @@ write(ostream &out, int indent_level) const {
} }
} }
////////////////////////////////////////////////////////////////////
// Function: RenderState::issue_delta_modify
// Access: Public
// Description: This is intended to be called only from
// GraphicsStateGuardian::modify_state(). It calls
// issue() for each attribute given in the other state
// that differs from the current state (which is assumed
// to represent the GSG's current state). Returns the
// RenderState representing the newly composed result.
////////////////////////////////////////////////////////////////////
CPT(RenderState) RenderState::
issue_delta_modify(const RenderState *other,
GraphicsStateGuardianBase *gsg) const {
if (other == this) {
// If the state doesn't change, that's a trivial special case.
return other;
}
// First, build a new Attributes member that represents the union of
// this one and that one.
Attributes::const_iterator ai = _attributes.begin();
Attributes::const_iterator bi = other->_attributes.begin();
// Create a new RenderState that will hold the result.
RenderState *new_state = new RenderState;
back_insert_iterator<Attributes> result =
back_inserter(new_state->_attributes);
bool any_changed = false;
while (ai != _attributes.end() && bi != other->_attributes.end()) {
if ((*ai) < (*bi)) {
// Here is an attribute that we have in the original, which is
// not present in the secondary. Leave it alone.
*result = *ai;
++ai;
++result;
} else if ((*bi) < (*ai)) {
// Here is a new attribute we have in the secondary, that was
// not present in the original. Issue the new one, and save it.
(*bi)._attrib->issue(gsg);
*result = *bi;
++bi;
++result;
any_changed = true;
} else {
// Here is an attribute we have in both. Issue the new one if
// it's different, and save it.
if ((*ai)._attrib != (*bi)._attrib) {
any_changed = true;
(*bi)._attrib->issue(gsg);
}
*result = *bi;
++ai;
++bi;
++result;
}
}
while (ai != _attributes.end()) {
*result = *ai;
++ai;
++result;
}
while (bi != other->_attributes.end()) {
(*bi)._attrib->issue(gsg);
*result = *bi;
++bi;
++result;
any_changed = true;
}
if (any_changed) {
return return_new(new_state);
} else {
delete new_state;
return other;
}
}
////////////////////////////////////////////////////////////////////
// Function: RenderState::issue_delta_set
// Access: Public
// Description: This is intended to be called only from
// GraphicsStateGuardian::set_state(). It calls issue()
// for each attribute given in the other state that
// differs from the current state (which is assumed to
// represent the GSG's current state). Returns the
// RenderState representing the newly composed result
// (which will be the same as other).
////////////////////////////////////////////////////////////////////
CPT(RenderState) RenderState::
issue_delta_set(const RenderState *other,
GraphicsStateGuardianBase *gsg) const {
if (other->is_empty()) {
// If the other state is empty, that's a trivial special case.
return this;
}
// We don't need to build a new RenderState, because the return
// value will be exactly other.
Attributes::const_iterator ai = _attributes.begin();
Attributes::const_iterator bi = other->_attributes.begin();
while (ai != _attributes.end() && bi != other->_attributes.end()) {
if ((*ai) < (*bi)) {
// Here is an attribute that we have in the original, which is
// not present in the secondary. Issue the default state instead.
(*ai)._attrib->make_default()->issue(gsg);
++ai;
} else if ((*bi) < (*ai)) {
// Here is a new attribute we have in the secondary, that was
// not present in the original. Issue the new one.
(*bi)._attrib->issue(gsg);
++bi;
} else {
// Here is an attribute we have in both. Issue the new one if
// it's different.
if ((*ai)._attrib != (*bi)._attrib) {
(*bi)._attrib->issue(gsg);
}
++ai;
++bi;
}
}
while (ai != _attributes.end()) {
(*ai)._attrib->make_default()->issue(gsg);
++ai;
}
while (bi != other->_attributes.end()) {
(*bi)._attrib->issue(gsg);
++bi;
}
return other;
}
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
// Function: RenderState::return_new // Function: RenderState::return_new
// Access: Private, Static // Access: Private, Static
@ -513,7 +728,7 @@ do_compose(const RenderState *other) const {
} else if (b._override < a._override) { } else if (b._override < a._override) {
// A overrides. // A overrides.
*result = *bi; *result = *ai;
} else { } else {
// No, they're equivalent, so compose them. // No, they're equivalent, so compose them.
@ -540,6 +755,59 @@ do_compose(const RenderState *other) const {
return return_new(new_state); return return_new(new_state);
} }
////////////////////////////////////////////////////////////////////
// Function: RenderState::do_invert_compose
// Access: Private
// Description: The private implemention of invert_compose().
////////////////////////////////////////////////////////////////////
CPT(RenderState) RenderState::
do_invert_compose(const RenderState *other) const {
Attributes::const_iterator ai = _attributes.begin();
Attributes::const_iterator bi = other->_attributes.begin();
// Create a new RenderState that will hold the result.
RenderState *new_state = new RenderState;
back_insert_iterator<Attributes> result =
back_inserter(new_state->_attributes);
while (ai != _attributes.end() && bi != other->_attributes.end()) {
if ((*ai) < (*bi)) {
// Here is an attribute that we have in the original, which is
// not present in the secondary.
*result = Attribute((*ai)._attrib->invert_compose((*ai)._attrib->make_default()), 0);
++ai;
++result;
} else if ((*bi) < (*ai)) {
// Here is a new attribute we have in the secondary, that was
// not present in the original.
*result = *bi;
++bi;
++result;
} else {
// Here is an attribute we have in both. In this case, override
// is meaningless.
*result = Attribute((*ai)._attrib->invert_compose((*bi)._attrib), (*bi)._override);
++ai;
++bi;
++result;
}
}
while (ai != _attributes.end()) {
*result = Attribute((*ai)._attrib->invert_compose((*ai)._attrib->make_default()), 0);
++ai;
++result;
}
while (bi != other->_attributes.end()) {
*result = *bi;
++bi;
++result;
}
return return_new(new_state);
}
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
// Function: RenderState::register_with_read_factory // Function: RenderState::register_with_read_factory
// Access: Public, Static // Access: Public, Static

View File

@ -27,6 +27,8 @@
#include "indirectLess.h" #include "indirectLess.h"
#include "ordered_vector.h" #include "ordered_vector.h"
class GraphicsStateGuardianBase;
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
// Class : RenderState // Class : RenderState
// Description : This represents a unique collection of RenderAttrib // Description : This represents a unique collection of RenderAttrib
@ -73,6 +75,7 @@ PUBLISHED:
const RenderAttrib *attrib4, int override = 0); const RenderAttrib *attrib4, int override = 0);
CPT(RenderState) compose(const RenderState *other) const; CPT(RenderState) compose(const RenderState *other) const;
CPT(RenderState) invert_compose(const RenderState *other) const;
CPT(RenderState) add(const RenderAttrib *attrib, int override = 0) const; CPT(RenderState) add(const RenderAttrib *attrib, int override = 0) const;
CPT(RenderState) remove(TypeHandle type) const; CPT(RenderState) remove(TypeHandle type) const;
@ -80,9 +83,16 @@ PUBLISHED:
void output(ostream &out) const; void output(ostream &out) const;
void write(ostream &out, int indent_level) const; void write(ostream &out, int indent_level) const;
public:
CPT(RenderState) issue_delta_modify(const RenderState *other,
GraphicsStateGuardianBase *gsg) const;
CPT(RenderState) issue_delta_set(const RenderState *other,
GraphicsStateGuardianBase *gsg) const;
private: private:
static CPT(RenderState) return_new(RenderState *state); static CPT(RenderState) return_new(RenderState *state);
CPT(RenderState) do_compose(const RenderState *other) const; CPT(RenderState) do_compose(const RenderState *other) const;
CPT(RenderState) do_invert_compose(const RenderState *other) const;
private: private:
typedef pset<const RenderState *, IndirectLess<RenderState> > States; typedef pset<const RenderState *, IndirectLess<RenderState> > States;
@ -106,8 +116,9 @@ private:
typedef pmap<const RenderState *, Composition> CompositionCache; typedef pmap<const RenderState *, Composition> CompositionCache;
CompositionCache _composition_cache; CompositionCache _composition_cache;
CompositionCache _invert_composition_cache;
// This pointer is used to cache the result of compose(this). This // Thise pointer is used to cache the result of compose(this). This
// has to be a special case, because we have to handle the reference // has to be a special case, because we have to handle the reference
// counts carefully so that we don't leak. Most of the time, the // counts carefully so that we don't leak. Most of the time, the
// result of compose(this) is this, which should not be reference // result of compose(this) is this, which should not be reference

View File

@ -17,6 +17,7 @@
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
#include "textureAttrib.h" #include "textureAttrib.h"
#include "graphicsStateGuardianBase.h"
#include "bamReader.h" #include "bamReader.h"
#include "bamWriter.h" #include "bamWriter.h"
#include "datagram.h" #include "datagram.h"
@ -49,6 +50,20 @@ make_off() {
return return_new(attrib); return return_new(attrib);
} }
////////////////////////////////////////////////////////////////////
// Function: TextureAttrib::issue
// Access: Public, Virtual
// Description: Calls the appropriate method on the indicated GSG
// to issue the graphics commands appropriate to the
// given attribute. This is normally called
// (indirectly) only from
// GraphicsStateGuardian::set_state() or modify_state().
////////////////////////////////////////////////////////////////////
void TextureAttrib::
issue(GraphicsStateGuardianBase *gsg) const {
gsg->issue_texture(this);
}
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
// Function: TextureAttrib::output // Function: TextureAttrib::output
// Access: Public, Virtual // Access: Public, Virtual

View File

@ -42,6 +42,7 @@ PUBLISHED:
INLINE Texture *get_texture() const; INLINE Texture *get_texture() const;
public: public:
virtual void issue(GraphicsStateGuardianBase *gsg) const;
virtual void output(ostream &out) const; virtual void output(ostream &out) const;
protected: protected:

View File

@ -62,3 +62,27 @@ INLINE Node *Camera::
get_scene() const { get_scene() const {
return _scene; return _scene;
} }
////////////////////////////////////////////////////////////////////
// Function: Camera::set_qpscene
// Access: Public
// Description: Sets the scene that will be rendered by the camera.
// This is normally the root node of a scene graph,
// typically a node called 'render', although it could
// represent the root of any subgraph.
////////////////////////////////////////////////////////////////////
INLINE void Camera::
set_qpscene(PandaNode *scene) {
_qpscene = scene;
}
////////////////////////////////////////////////////////////////////
// Function: Camera::get_qpscene
// Access: Public
// Description: Returns the scene that will be rendered by the
// camera. See set_qpscene().
////////////////////////////////////////////////////////////////////
INLINE PandaNode *Camera::
get_qpscene() const {
return _qpscene;
}

View File

@ -28,6 +28,7 @@
#include "pvector.h" #include "pvector.h"
class DisplayRegion; class DisplayRegion;
class PandaNode;
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
// Class : Camera // Class : Camera
@ -56,6 +57,9 @@ PUBLISHED:
INLINE void set_scene(Node *scene); INLINE void set_scene(Node *scene);
INLINE Node *get_scene() const; INLINE Node *get_scene() const;
INLINE void set_qpscene(PandaNode *scene);
INLINE PandaNode *get_qpscene() const;
int get_num_drs() const; int get_num_drs() const;
DisplayRegion *get_dr(int index) const; DisplayRegion *get_dr(int index) const;
@ -65,6 +69,7 @@ private:
bool _active; bool _active;
PT_Node _scene; PT_Node _scene;
PandaNode *_qpscene;
typedef pvector<DisplayRegion *> DisplayRegions; typedef pvector<DisplayRegion *> DisplayRegions;
DisplayRegions _display_regions; DisplayRegions _display_regions;

View File

@ -26,6 +26,15 @@
#end bin_target #end bin_target
#begin test_bin_target
#define TARGET pview
#define SOURCES \
pview.cxx
#define LOCAL_LIBS pgraph $[LOCAL_LIBS]
#end test_bin_target
#begin test_bin_target #begin test_bin_target
#define TARGET open_window #define TARGET open_window