From 48e09cda3177ca462b1af35b11f1964a7b06f490 Mon Sep 17 00:00:00 2001 From: David Rose Date: Tue, 7 Dec 2004 04:25:38 +0000 Subject: [PATCH] support GraphicsOutput::set_inverted() --- panda/src/display/config_display.cxx | 115 ++++++++------ panda/src/display/config_display.h | 27 ++-- panda/src/display/displayRegion.I | 21 --- panda/src/display/displayRegion.cxx | 34 ++++ panda/src/display/displayRegion.h | 2 +- panda/src/display/graphicsEngine.cxx | 70 +++++--- panda/src/display/graphicsEngine.h | 5 +- panda/src/display/graphicsOutput.I | 13 ++ panda/src/display/graphicsOutput.cxx | 53 ++++++- panda/src/display/graphicsOutput.h | 4 + panda/src/display/graphicsPipeSelection.cxx | 54 +++---- panda/src/display/graphicsStateGuardian.I | 149 +++++++++--------- panda/src/display/graphicsStateGuardian.cxx | 60 ++++--- panda/src/display/graphicsStateGuardian.h | 19 ++- panda/src/dxgsg7/dxGraphicsStateGuardian7.cxx | 36 ++--- panda/src/dxgsg7/dxGraphicsStateGuardian7.h | 1 - panda/src/dxgsg8/dxGraphicsStateGuardian8.cxx | 37 ++--- panda/src/dxgsg8/dxGraphicsStateGuardian8.h | 1 - panda/src/dxgsg9/dxGraphicsStateGuardian9.cxx | 37 ++--- panda/src/dxgsg9/dxGraphicsStateGuardian9.h | 1 - .../glstuff/glGraphicsStateGuardian_src.cxx | 36 ++--- .../src/glstuff/glGraphicsStateGuardian_src.h | 1 - panda/src/gobj/lens.cxx | 2 +- panda/src/pgraph/cullTraverser.I | 4 +- panda/src/pgraph/sceneSetup.I | 51 ++++++ panda/src/pgraph/sceneSetup.h | 8 + 26 files changed, 491 insertions(+), 350 deletions(-) diff --git a/panda/src/display/config_display.cxx b/panda/src/display/config_display.cxx index bdd7df7a09..9c5160b284 100644 --- a/panda/src/display/config_display.cxx +++ b/panda/src/display/config_display.cxx @@ -35,71 +35,90 @@ ConfigureFn(config_display) { init_libdisplay(); } -// This is normally true; set it false to disable view-frustum culling -// (primarily useful for debugging). -const bool view_frustum_cull = config_display.GetBool("view-frustum-cull", true); +ConfigVariableBool view_frustum_cull +("view-frustum-cull", true, + "This is normally true; set it false to disable view-frustum culling " + "(primarily useful for debugging)."); -// Set this true to show the number of unused states in the pstats -// graph for TransformState and RenderState counts. This adds a bit -// of per-frame overhead to count these things up. -const bool pstats_unused_states = config_display.GetBool("pstats-unused-states", false); +ConfigVariableBool pstats_unused_states +("pstats-unused-states", false, +"Set this true to show the number of unused states in the pstats " +"graph for TransformState and RenderState counts. This adds a bit " +"of per-frame overhead to count these things up."); -// This is the default threading model to use for new windows. Use -// empty string for single-threaded, or something like "cull/draw" for -// a 3-stage pipeline. See GraphicsEngine::set_threading_model(). // Warning! The code that uses this is currently experimental and // incomplete, and will almost certainly crash! Do not set // threading-model to anything other than its default of a // single-threaded model unless you are developing Panda's threading // system! -const string threading_model = config_display.GetString("threading-model", ""); +ConfigVariableString threading_model +("threading-model", "", + "This is the default threading model to use for new windows. Use " + "empty string for single-threaded, or something like \"cull/draw\" for " + "a 3-stage pipeline. See GraphicsEngine::set_threading_model(). " + "EXPERIMENTAL and incomplete, do not use this!"); -// This indicates the initial setting of the auto-flip flag. Set it -// true (the default) to cause render_frame() to flip all the windows -// before it returns (in single-threaded mode only), or false to wait -// until an explicit call to flip_frame() or the next render_frame(). -const bool auto_flip = config_display.GetBool("auto-flip", true); +ConfigVariableBool auto_flip +("auto-flip", true, + "This indicates the initial setting of the auto-flip flag. Set it " + "true (the default) to cause render_frame() to flip all the windows " + "before it returns (in single-threaded mode only), or false to wait " + "until an explicit call to flip_frame() or the next render_frame()."); -// Set this true to yield the timeslice at the end of the frame to be -// more polite to other applications that are trying to run. -const bool yield_timeslice = config_display.GetBool("yield-timeslice", false); +ConfigVariableBool yield_timeslice +("yield-timeslice", false, + "Set this true to yield the timeslice at the end of the frame to be " + "more polite to other applications that are trying to run."); -const string screenshot_filename = config_display.GetString("screenshot-filename", "%~p-%a-%b-%d-%H-%M-%S-%Y-%~f.%~e"); -const string screenshot_extension = config_display.GetString("screenshot-extension", "jpg"); +ConfigVariableString screenshot_filename +("screenshot-filename", "%~p-%a-%b-%d-%H-%M-%S-%Y-%~f.%~e", + "This specifies the filename pattern to be used to generate " + "screenshots captured via save_screenshot_default(). See " + "DisplayRegion::save_screenshot()." +); +ConfigVariableString screenshot_extension +("screenshot-extension", "jpg", + "This specifies the default filename extension (and therefore the " + "default image type) to be used for saving screenshots."); -// Set this true to cause offscreen GraphicsBuffers to be created as -// GraphicsWindows, if possible, so that their contents may be viewed -// interactively. Handy during development of multipass algorithms. -const bool show_buffers = config_display.GetBool("show-buffers", false); +ConfigVariableBool show_buffers +("show-buffers", false, + "Set this true to cause offscreen GraphicsBuffers to be created as " + "GraphicsWindows, if possible, so that their contents may be viewed " + "interactively. Handy during development of multipass algorithms."); -// Set this true to make GraphicsOutput::make_render_texture() try to -// create a parasite buffer before it tries to create an offscreen -// buffer. This may be desired if you know your graphics API does not -// support render-directly-to-texture and you want to minimize -// framebuffer memory. -const bool prefer_parasite_buffer = config_display.GetBool("prefer-parasite-buffer", true); +ConfigVariableBool prefer_parasite_buffer +("prefer-parasite-buffer", true, + "Set this true to make GraphicsOutput::make_render_texture() try to " + "create a parasite buffer before it tries to create an offscreen " + "buffer. This may be desired if you know your graphics API does not " + "support render-directly-to-texture and you want to minimize " + "framebuffer memory."); -// Set this true to make GraphicsOutput::make_render_texture() first -// try to create a single-buffered offscreen buffer, before falling -// back to a double-buffered one (or whatever kind the source window -// has). This is true by default to reduce waste of framebuffer -// memory, but you may get a performance benefit by setting it to -// false (since in that case the buffer can share a graphics context -// with the window). -const bool prefer_single_buffer = config_display.GetBool("prefer-single-buffer", true); +ConfigVariableBool prefer_single_buffer +("prefer-single-buffer", true, + "Set this true to make GraphicsOutput::make_render_texture() first " + "try to create a single-buffered offscreen buffer, before falling " + "back to a double-buffered one (or whatever kind the source window " + "has). This is true by default to reduce waste of framebuffer " + "memory, but you may get a performance benefit by setting it to " + "false (since in that case the buffer can share a graphics context " + "with the window)."); +ConfigVariableBool copy_texture_inverted +("copy-texture-inverted", false, + "Set this true to indicate that the GSG in use will invert textures when " + "it performs a framebuffer-to-texture copy operation, or false to indicate " + "that it does the right thing. If this is not set, the default behavior is " + "determined by the GSG's internal logic."); -// Use the variable load-display to specify the name of the default -// graphics display library or GraphicsPipe to load. It is the name -// of a shared library (or * for all libraries named in aux-display), -// optionally followed by the name of the particular GraphicsPipe -// class to create. - -// Also use the variable aux-display to name each of the graphics -// display libraries that are available on a particular platform. -// This variable may be repeated several times. +ConfigVariableBool window_inverted +("window-inverted", false, + "Set this true to create all windows with the inverted flag set, so that " + "they will render upside-down and backwards. Normally this is useful only " + "for debugging."); //////////////////////////////////////////////////////////////////// diff --git a/panda/src/display/config_display.h b/panda/src/display/config_display.h index 9255834845..19a80a8930 100644 --- a/panda/src/display/config_display.h +++ b/panda/src/display/config_display.h @@ -21,29 +21,34 @@ #include "pandabase.h" #include "notifyCategoryProxy.h" +#include "configVariableBool.h" +#include "configVariableString.h" +#include "configVariableList.h" #include "dconfig.h" -#include #include "pvector.h" ConfigureDecl(config_display, EXPCL_PANDA, EXPTP_PANDA); NotifyCategoryDecl(display, EXPCL_PANDA, EXPTP_PANDA); NotifyCategoryDecl(gsg, EXPCL_PANDA, EXPTP_PANDA); -extern const bool view_frustum_cull; -extern const bool pstats_unused_states; +extern ConfigVariableBool view_frustum_cull; +extern ConfigVariableBool pstats_unused_states; -extern const string threading_model; -extern const bool auto_flip; -extern const bool yield_timeslice; +extern ConfigVariableString threading_model; +extern ConfigVariableBool auto_flip; +extern ConfigVariableBool yield_timeslice; -extern const string screenshot_filename; -extern const string screenshot_extension; +extern ConfigVariableString screenshot_filename; +extern ConfigVariableString screenshot_extension; -extern const bool show_buffers; +extern ConfigVariableBool show_buffers; -extern const bool prefer_parasite_buffer; -extern const bool prefer_single_buffer; +extern ConfigVariableBool prefer_parasite_buffer; +extern ConfigVariableBool prefer_single_buffer; + +extern ConfigVariableBool copy_texture_inverted; +extern ConfigVariableBool window_inverted; extern EXPCL_PANDA void init_libdisplay(); diff --git a/panda/src/display/displayRegion.I b/panda/src/display/displayRegion.I index dadfb6364f..b12990c513 100644 --- a/panda/src/display/displayRegion.I +++ b/panda/src/display/displayRegion.I @@ -50,27 +50,6 @@ get_sort() const { return _sort; } -//////////////////////////////////////////////////////////////////// -// Function: DisplayRegion::do_compute_pixels -// Access: Private -// Description: The private implementation of compute_pixels, this -// assumes that we already have the lock. -//////////////////////////////////////////////////////////////////// -INLINE void DisplayRegion:: -do_compute_pixels(int x_size, int y_size) { - if (display_cat.is_debug()) { - display_cat.debug() - << "DisplayRegion::do_compute_pixels(" << x_size << ", " << y_size << ")\n"; - } - - _pl = int((_l * x_size) + 0.5); - _pr = int((_r * x_size) + 0.5); - _pb = int((_b * y_size) + 0.5); - _pt = int((_t * y_size) + 0.5); - _pbi = int(((1.0f - _b) * y_size) + 0.5); - _pti = int(((1.0f - _t) * y_size) + 0.5); -} - INLINE ostream &operator << (ostream &out, const DisplayRegion &dr) { dr.output(out); diff --git a/panda/src/display/displayRegion.cxx b/panda/src/display/displayRegion.cxx index 9a8b402b2d..046b8033a1 100644 --- a/panda/src/display/displayRegion.cxx +++ b/panda/src/display/displayRegion.cxx @@ -553,3 +553,37 @@ win_display_regions_changed() { _window->win_display_regions_changed(); } } + +//////////////////////////////////////////////////////////////////// +// Function: DisplayRegion::do_compute_pixels +// Access: Private +// Description: The private implementation of compute_pixels, this +// assumes that we already have the lock. +//////////////////////////////////////////////////////////////////// +void DisplayRegion:: +do_compute_pixels(int x_size, int y_size) { + if (display_cat.is_debug()) { + display_cat.debug() + << "DisplayRegion::do_compute_pixels(" << x_size << ", " << y_size << ")\n"; + } + + _pl = int((_l * x_size) + 0.5); + _pr = int((_r * x_size) + 0.5); + + const GraphicsOutput *win = get_window(); + nassertv(win != (GraphicsOutput *)NULL); + if (win->get_inverted()) { + // The window is inverted; compute the DisplayRegion accordingly. + _pb = int(((1.0f - _t) * y_size) + 0.5); + _pt = int(((1.0f - _b) * y_size) + 0.5); + _pbi = int((_t * y_size) + 0.5); + _pti = int((_b * y_size) + 0.5); + + } else { + // The window is normal. + _pb = int((_b * y_size) + 0.5); + _pt = int((_t * y_size) + 0.5); + _pbi = int(((1.0f - _b) * y_size) + 0.5); + _pti = int(((1.0f - _t) * y_size) + 0.5); + } +} diff --git a/panda/src/display/displayRegion.h b/panda/src/display/displayRegion.h index 79f8b1f528..9d07fc5f5a 100644 --- a/panda/src/display/displayRegion.h +++ b/panda/src/display/displayRegion.h @@ -99,7 +99,7 @@ PUBLISHED: private: void win_display_regions_changed(); - INLINE void do_compute_pixels(int x_size, int y_size); + void do_compute_pixels(int x_size, int y_size); Mutex _lock; float _l; diff --git a/panda/src/display/graphicsEngine.cxx b/panda/src/display/graphicsEngine.cxx index e04ded72ee..854d0dcb4b 100644 --- a/panda/src/display/graphicsEngine.cxx +++ b/panda/src/display/graphicsEngine.cxx @@ -30,6 +30,7 @@ #include "pStatClient.h" #include "pStatCollector.h" #include "mutexHolder.h" +#include "cullFaceAttrib.h" #include "string_utils.h" #if defined(WIN32) @@ -739,7 +740,7 @@ void GraphicsEngine:: cull_and_draw_together(GraphicsStateGuardian *gsg, DisplayRegion *dr) { nassertv(gsg != (GraphicsStateGuardian *)NULL); - PT(SceneSetup) scene_setup = setup_scene(dr->get_camera(), gsg); + PT(SceneSetup) scene_setup = setup_scene(gsg, dr); if (setup_gsg(gsg, scene_setup)) { DisplayRegionStack old_dr = gsg->push_display_region(dr); gsg->prepare_display_region(); @@ -819,7 +820,7 @@ cull_bin_draw(GraphicsStateGuardian *gsg, DisplayRegion *dr) { cull_result = new CullResult(gsg); } - PT(SceneSetup) scene_setup = setup_scene(dr->get_camera(), gsg); + PT(SceneSetup) scene_setup = setup_scene(gsg, dr); if (scene_setup != (SceneSetup *)NULL) { BinCullHandler cull_handler(cull_result); do_cull(&cull_handler, scene_setup, gsg); @@ -964,7 +965,14 @@ do_flip_frame() { // reason. //////////////////////////////////////////////////////////////////// PT(SceneSetup) GraphicsEngine:: -setup_scene(const NodePath &camera, GraphicsStateGuardian *gsg) { +setup_scene(GraphicsStateGuardian *gsg, DisplayRegion *dr) { + GraphicsOutput *window = dr->get_window(); + // The window pointer shouldn't be NULL, since we presumably got to + // this particular DisplayRegion by walking through a list on a + // window. + nassertr(window != (GraphicsOutput *)NULL, NULL); + + NodePath camera = dr->get_camera(); if (camera.is_empty()) { // No camera, no draw. return NULL; @@ -1007,18 +1015,26 @@ setup_scene(const NodePath &camera, GraphicsStateGuardian *gsg) { // The render transform is the same as the world transform, except // it is converted into the GSG's internal coordinate system. This // is the transform that the GSG will apply to all of its vertices. - CPT(TransformState) cs_transform = TransformState::make_identity(); - CoordinateSystem external_cs = gsg->get_coordinate_system(); - CoordinateSystem internal_cs = gsg->get_internal_coordinate_system(); - if (internal_cs != CS_default && internal_cs != external_cs) { - cs_transform = - TransformState::make_mat(LMatrix4f::convert_mat(external_cs, internal_cs)); + CPT(TransformState) cs_transform = gsg->get_cs_transform(); + + CPT(RenderState) initial_state = camera_node->get_initial_state(); + + if (window->get_inverted()) { + // If the window is to be inverted, we must set the inverted flag + // on the SceneSetup object, so that the GSG will be able to + // invert the projection matrix at the last minute. + scene_setup->set_inverted(true); + + // This also means we need to globally invert the sense of polygon + // vertex ordering. + initial_state = initial_state->compose(get_invert_polygon_state()); } scene_setup->set_scene_root(scene_root); scene_setup->set_camera_path(camera); scene_setup->set_camera_node(camera_node); scene_setup->set_lens(lens); + scene_setup->set_initial_state(initial_state); scene_setup->set_camera_transform(camera_transform); scene_setup->set_world_transform(world_transform); scene_setup->set_cs_transform(cs_transform); @@ -1041,7 +1057,6 @@ do_cull(CullHandler *cull_handler, SceneSetup *scene_setup, trav.set_cull_handler(cull_handler); trav.set_depth_offset_decals(gsg->depth_offset_decals()); trav.set_scene(scene_setup); - trav.set_camera_mask(scene_setup->get_camera_node()->get_camera_mask()); if (view_frustum_cull) { // If we're to be performing view-frustum culling, determine the @@ -1108,22 +1123,13 @@ setup_gsg(GraphicsStateGuardian *gsg, SceneSetup *scene_setup) { return false; } - const Lens *lens = scene_setup->get_lens(); - if (lens == (const Lens *)NULL) { - // No lens, no draw. - return false; - } - - if (!gsg->set_lens(lens)) { - // The lens is inappropriate somehow. + if (!gsg->set_scene(scene_setup)) { + // The scene or lens is inappropriate somehow. display_cat.error() - << gsg->get_type() << " cannot render with " << lens->get_type() - << "\n"; + << gsg->get_type() << " cannot render scene with specified lens.\n"; return false; } - gsg->set_scene(scene_setup); - return true; } @@ -1271,6 +1277,26 @@ terminate_threads() { _threads.clear(); } +//////////////////////////////////////////////////////////////////// +// Function: GraphicsEngine::get_invert_polygon_state +// Access: Protected, Static +// Description: Returns a RenderState for inverting the sense of +// polygon vertex ordering: if the scene graph specifies +// a clockwise ordering, this changes it to +// counterclockwise, and vice-versa. +//////////////////////////////////////////////////////////////////// +const RenderState *GraphicsEngine:: +get_invert_polygon_state() { + // Once someone asks for this pointer, we hold its reference count + // and never free it. + static CPT(RenderState) state = (const RenderState *)NULL; + if (state == (const RenderState *)NULL) { + state = RenderState::make(CullFaceAttrib::make_reverse()); + } + + return state; +} + //////////////////////////////////////////////////////////////////// // Function: GraphicsEngine::get_window_renderer // Access: Private diff --git a/panda/src/display/graphicsEngine.h b/panda/src/display/graphicsEngine.h index 8b2b4922c0..29e67d99b1 100644 --- a/panda/src/display/graphicsEngine.h +++ b/panda/src/display/graphicsEngine.h @@ -152,8 +152,7 @@ private: void do_flip_frame(); INLINE void close_gsg(GraphicsPipe *pipe, GraphicsStateGuardian *gsg); - PT(SceneSetup) setup_scene(const NodePath &camera, - GraphicsStateGuardian *gsg); + PT(SceneSetup) setup_scene(GraphicsStateGuardian *gsg, DisplayRegion *dr); void do_cull(CullHandler *cull_handler, SceneSetup *scene_setup, GraphicsStateGuardian *gsg); void do_draw(CullResult *cull_result, SceneSetup *scene_setup, @@ -167,6 +166,8 @@ private: void do_resort_windows(); void terminate_threads(); + static const RenderState *get_invert_polygon_state(); + // The WindowRenderer class records the stages of the pipeline that // each thread (including the main thread, a.k.a. "app") should // process, and the list of windows for each stage. diff --git a/panda/src/display/graphicsOutput.I b/panda/src/display/graphicsOutput.I index 786e518b1f..7c082d5c4f 100644 --- a/panda/src/display/graphicsOutput.I +++ b/panda/src/display/graphicsOutput.I @@ -188,6 +188,19 @@ get_one_shot() const { return _one_shot; } +//////////////////////////////////////////////////////////////////// +// Function: GraphicsOutput::get_inverted +// Access: Published +// Description: Returns the current setting of the inverted flag. +// When this is true, the scene is rendered into the +// window upside-down, flipped like a mirror along the X +// axis. See set_inverted(). +//////////////////////////////////////////////////////////////////// +INLINE bool GraphicsOutput:: +get_inverted() const { + return _inverted; +} + //////////////////////////////////////////////////////////////////// // Function: GraphicsOutput::clear_delete_flag // Access: Published diff --git a/panda/src/display/graphicsOutput.cxx b/panda/src/display/graphicsOutput.cxx index eb12500a61..24d1d1e9b5 100644 --- a/panda/src/display/graphicsOutput.cxx +++ b/panda/src/display/graphicsOutput.cxx @@ -25,6 +25,7 @@ #include "renderBuffer.h" #include "indirectLess.h" #include "pStatTimer.h" +#include "configVariableBool.h" TypeHandle GraphicsOutput::_type_handle; @@ -57,6 +58,7 @@ GraphicsOutput(GraphicsPipe *pipe, GraphicsStateGuardian *gsg, _sort = 0; _active = true; _one_shot = false; + _inverted = window_inverted; _delete_flag = false; int mode = gsg->get_properties().get_frame_buffer_mode(); @@ -69,6 +71,7 @@ GraphicsOutput(GraphicsPipe *pipe, GraphicsStateGuardian *gsg, // which we may use internally for full-window operations like // clear() and get_screenshot(). _default_display_region = make_display_region(0.0f, 1.0f, 0.0f, 1.0f); + _default_display_region->set_active(false); _display_regions_stale = false; @@ -131,15 +134,17 @@ GraphicsOutput:: // Function: GraphicsOutput::detach_texture // Access: Published // Description: Disassociates the texture from the GraphicsOutput. -// It will no longer be filled as the frame renders, and -// it may be used (with its current contents) as a -// texture in its own right. +// The texture will no longer be filled as the frame +// renders, and it may be used (with its current +// contents) as an ordinary texture in its own right. //////////////////////////////////////////////////////////////////// void GraphicsOutput:: detach_texture() { MutexHolder holder(_lock); _texture = NULL; _copy_texture = false; + + set_inverted(window_inverted); } //////////////////////////////////////////////////////////////////// @@ -160,6 +165,9 @@ setup_copy_texture(const string &name) { _texture->set_wrapv(Texture::WM_clamp); _copy_texture = true; + + nassertv(_gsg != (GraphicsStateGuardian *)NULL); + set_inverted(_gsg->get_copy_texture_inverted()); } //////////////////////////////////////////////////////////////////// @@ -185,6 +193,40 @@ is_active() const { return _active && is_valid(); } +//////////////////////////////////////////////////////////////////// +// Function: GraphicsOutput::set_inverted +// Access: Published +// Description: Changes the current setting of the inverted flag. +// When this is true, the scene is rendered into the +// window upside-down and backwards, that is, inverted +// as if viewed through a mirror placed on the floor. +// +// This is primarily intended to support DirectX (and a +// few buggy OpenGL graphics drivers) that perform a +// framebuffer-to-texture copy upside-down from the +// usual OpenGL (and Panda) convention. Panda will +// automatically set this flag for offscreen buffers on +// hardware that is known to do this, to compensate when +// rendering offscreen into a texture. +//////////////////////////////////////////////////////////////////// +void GraphicsOutput:: +set_inverted(bool inverted) { + if (_inverted != inverted) { + _inverted = inverted; + + if (_y_size != 0) { + // All of our DisplayRegions need to recompute their pixel + // positions now. + TotalDisplayRegions::iterator dri; + for (dri = _total_display_regions.begin(); + dri != _total_display_regions.end(); + ++dri) { + (*dri)->compute_pixels(_x_size, _y_size); + } + } + } +} + //////////////////////////////////////////////////////////////////// // Function: GraphicsOutput::set_sort // Access: Published @@ -539,8 +581,9 @@ end_frame() { nassertv(_gsg != (GraphicsStateGuardian *)NULL); _gsg->end_frame(); - // By default, we copy the framebuffer to the texture at the end of - // the frame. GraphicsBuffer objects that are set up to render + // If _copy_texture is true, it means we should copy the framebuffer + // to the GraphicsOutput's associated texture after the frame has + // rendered. GraphicsBuffer objects that are set up to render // directly into texture memory don't need to do this; they will set // _copy_texture to false. if (_copy_texture) { diff --git a/panda/src/display/graphicsOutput.h b/panda/src/display/graphicsOutput.h index 5c13c00a4c..1798391663 100644 --- a/panda/src/display/graphicsOutput.h +++ b/panda/src/display/graphicsOutput.h @@ -88,6 +88,9 @@ PUBLISHED: INLINE void set_one_shot(bool one_shot); INLINE bool get_one_shot() const; + void set_inverted(bool inverted); + INLINE bool get_inverted() const; + INLINE void clear_delete_flag(); INLINE bool get_delete_flag() const; @@ -170,6 +173,7 @@ private: protected: bool _active; bool _one_shot; + bool _inverted; bool _delete_flag; protected: diff --git a/panda/src/display/graphicsPipeSelection.cxx b/panda/src/display/graphicsPipeSelection.cxx index 8f529408eb..7bf41ab665 100644 --- a/panda/src/display/graphicsPipeSelection.cxx +++ b/panda/src/display/graphicsPipeSelection.cxx @@ -33,49 +33,41 @@ GraphicsPipeSelection *GraphicsPipeSelection::_global_ptr = NULL; //////////////////////////////////////////////////////////////////// GraphicsPipeSelection:: GraphicsPipeSelection() { - pset got_display_modules; + // We declare these variables here instead of in config_display, in + // case this constructor is running at static init time. + ConfigVariableString load_display + ("load-display", "*", + "Specify the name of the default graphics display library or " + "GraphicsPipe to load. It is the name of a shared library (or * for " + "all libraries named in aux-display), optionally followed by the " + "name of the particular GraphicsPipe class to create."); + + ConfigVariableList aux_display + ("aux-display", + "Names each of the graphics display libraries that are available on " + "a particular platform. This variable may be repeated several " + "times. These libraries will be tried one at a time if the library " + "specified by load_display cannot be loaded."); - // First get the name of the default module from the load-display - // variable. We get this explicitly from Configrc now (instead of - // retrieving it in config_display), in case this constructor is - // running at static init time. - string load_display = config_display.GetString("load-display", ""); - load_display = trim_right(load_display); - size_t space = load_display.rfind(' '); - if (space != string::npos) { - // If there's a space, it indicates the name of the GraphicsPipe - // class to prefer. - _default_pipe_name = load_display.substr(space + 1); - load_display = trim_right(load_display.substr(0, space)); - } - - // Everything else is the name of the .dll (or .so) file to load. - _default_display_module = load_display; + _default_display_module = load_display.get_word(0); + _default_pipe_name = load_display.get_word(1); if (_default_display_module == "*") { // '*' or empty string is the key for all display modules. _default_display_module = string(); } else if (!_default_display_module.empty()) { - // Don't insert a particular display more than once. - if (got_display_modules.insert(_default_display_module).second) { - _display_modules.push_back(_default_display_module); - } + _display_modules.push_back(_default_display_module); } // Also get the set of modules named in the various aux-display // Configrc variables. We'll want to know this when we call // load_modules() later. - Config::ConfigTable::Symbol disp; - config_display.GetAll("aux-display", disp); - - Config::ConfigTable::Symbol::iterator ci; - for (ci = disp.begin(); ci != disp.end(); ++ci) { - string aux_display = trim_right((*ci).Val()); - - // Don't insert a particular display more than once. - if (got_display_modules.insert(aux_display).second) { - _display_modules.push_back(aux_display); + int num_aux = aux_display.get_num_unique_values(); + for (int i = 0; i < num_aux; i++) { + string name = aux_display.get_unique_value(i); + if (name != _default_display_module) { + _display_modules.push_back(name); } } diff --git a/panda/src/display/graphicsStateGuardian.I b/panda/src/display/graphicsStateGuardian.I index e1670506db..4792724ebc 100644 --- a/panda/src/display/graphicsStateGuardian.I +++ b/panda/src/display/graphicsStateGuardian.I @@ -140,17 +140,51 @@ get_max_texture_stages() const { return _max_texture_stages; } +//////////////////////////////////////////////////////////////////// +// Function: GraphicsStateGuardian::get_copy_texture_inverted +// Access: Published +// Description: Returns true if this particular GSG has the property +// that any framebuffer-to-texture copy results in a +// texture that is upside-down and backwards from +// Panda's usual convention; that is, it copies into a +// texture from the bottom up instead of from the top +// down. +// +// If this is true, then on offscreen GraphicsBuffer +// created for the purposes of rendering into a texture +// should be created with the invert flag set true, to +// compensate. Panda will do this automatically if you +// create an offscreen buffer using +// GraphicsOutput::make_texture_buffer(). +//////////////////////////////////////////////////////////////////// +INLINE bool GraphicsStateGuardian:: +get_copy_texture_inverted() const { + // If this is set from a Config variable, that overrides. + if (copy_texture_inverted.has_value()) { + return copy_texture_inverted; + } + + // Otherwise, use whatever behavior the GSG figured for itself. + return _copy_texture_inverted; +} + //////////////////////////////////////////////////////////////////// // Function: GraphicsStateGuardian::set_scene // Access: Public // Description: Sets the SceneSetup object that indicates the initial // camera position, etc. This must be called before -// traversal begins. +// traversal begins. Returns true if the scene is +// acceptable, false if something's wrong. //////////////////////////////////////////////////////////////////// -INLINE void GraphicsStateGuardian:: +INLINE bool GraphicsStateGuardian:: set_scene(SceneSetup *scene_setup) { _scene_setup = scene_setup; + _current_lens = scene_setup->get_lens(); + if (_current_lens == (Lens *)NULL) { + return false; + } + return prepare_lens(); } //////////////////////////////////////////////////////////////////// @@ -315,10 +349,9 @@ get_current_display_region(void) const { //////////////////////////////////////////////////////////////////// // 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(). +// Description: Returns the current lens being used to render, +// according to the scene specified via the last call to +// set_scene(). //////////////////////////////////////////////////////////////////// INLINE const Lens *GraphicsStateGuardian:: get_current_lens() const { @@ -402,78 +435,6 @@ pop_frame_buffer(FrameBufferStack &node) { 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 -// Access: Public -// Description: Changes the coordinate system in effect on this -// particular gsg. Normally, this will be the default -// coordinate system, but it might be set differently at -// runtime. -//////////////////////////////////////////////////////////////////// -INLINE void GraphicsStateGuardian:: -set_coordinate_system(CoordinateSystem cs) { - _coordinate_system = cs; -} - //////////////////////////////////////////////////////////////////// // Function: GraphicsStateGuardian::get_coordinate_system // Access: Public @@ -487,6 +448,38 @@ get_coordinate_system() const { return _coordinate_system; } +//////////////////////////////////////////////////////////////////// +// Function: GraphicsStateGuardian::get_internal_coordinate_system +// Access: Public +// Description: Returns the coordinate system used internally by the +// GSG, if any one particular coordinate system is used. +// The default, CS_default, indicates that the GSG can +// use any coordinate system. +// +// If this returns other than CS_default, the +// GraphicsEngine will automatically convert all +// transforms into the indicated coordinate system. +//////////////////////////////////////////////////////////////////// +INLINE CoordinateSystem GraphicsStateGuardian:: +get_internal_coordinate_system() const { + return _coordinate_system; +} + +//////////////////////////////////////////////////////////////////// +// Function: GraphicsStateGuardian::get_cs_transform +// Access: Public +// Description: Returns a transform that converts from the GSG's +// external coordinate system (as returned by +// get_coordinate_system()) to its internal coordinate +// system (as returned by +// get_internal_coordinate_system()). This is used for +// rendering. +//////////////////////////////////////////////////////////////////// +INLINE const TransformState *GraphicsStateGuardian:: +get_cs_transform() const { + return _cs_transform; +} + //////////////////////////////////////////////////////////////////// // Function: GraphicsStateGuardian::get_light // Access: Protected diff --git a/panda/src/display/graphicsStateGuardian.cxx b/panda/src/display/graphicsStateGuardian.cxx index e1dd351f16..b2a6d71687 100644 --- a/panda/src/display/graphicsStateGuardian.cxx +++ b/panda/src/display/graphicsStateGuardian.cxx @@ -69,9 +69,14 @@ TypeHandle GraphicsStateGuardian::_type_handle; // Description: //////////////////////////////////////////////////////////////////// GraphicsStateGuardian:: -GraphicsStateGuardian(const FrameBufferProperties &properties) { - _properties = properties; - _coordinate_system = get_default_coordinate_system(); +GraphicsStateGuardian(const FrameBufferProperties &properties, + CoordinateSystem internal_coordinate_system) : + _internal_coordinate_system(internal_coordinate_system), + _properties(properties) +{ + _coordinate_system = CS_invalid; + set_coordinate_system(get_default_coordinate_system()); + _current_display_region = (DisplayRegion*)0L; _current_lens = (Lens *)NULL; _needs_reset = true; @@ -83,6 +88,10 @@ GraphicsStateGuardian(const FrameBufferProperties &properties) { // supported). A derived GSG may set this differently if it // supports multitexturing. _max_texture_stages = 1; + + // Initially, we set this to false; a GSG that knows it has this + // property should set it to true. + _copy_texture_inverted = false; } //////////////////////////////////////////////////////////////////// @@ -287,11 +296,10 @@ clear(DrawableRegion *clearable) { // 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(). +// recently specified with set_scene()) active, so +// that it will transform future rendered geometry. +// Normally this is only called from the draw process, +// and usually it is called by set_scene(). // // The return value is true if the lens is acceptable, // false if it is not. @@ -550,21 +558,31 @@ finish_decal() { } //////////////////////////////////////////////////////////////////// -// Function: GraphicsStateGuardian::get_internal_coordinate_system -// Access: Public, Virtual -// Description: Should be overridden by derived classes to return the -// coordinate system used internally by the GSG, if any -// one particular coordinate system is used. The -// default, CS_default, indicates that the GSG can use -// any coordinate system. +// Function: GraphicsStateGuardian::set_coordinate_system +// Access: Public +// Description: Changes the coordinate system in effect on this +// particular gsg. This is also called the "external" +// coordinate system, since it is the coordinate system +// used by the scene graph, external to to GSG. // -// If this returns other than CS_default, the -// GraphicsEngine will automatically convert all -// transforms into the indicated coordinate system. +// Normally, this will be the default coordinate system, +// but it might be set differently at runtime. //////////////////////////////////////////////////////////////////// -CoordinateSystem GraphicsStateGuardian:: -get_internal_coordinate_system() const { - return CS_default; +void GraphicsStateGuardian:: +set_coordinate_system(CoordinateSystem cs) { + _coordinate_system = cs; + + // Changing the external coordinate system changes the cs_transform. + if (_internal_coordinate_system == CS_default || + _internal_coordinate_system == _coordinate_system) { + _cs_transform = TransformState::make_identity(); + + } else { + _cs_transform = + TransformState::make_mat + (LMatrix4f::convert_mat(_coordinate_system, + _internal_coordinate_system)); + } } //////////////////////////////////////////////////////////////////// diff --git a/panda/src/display/graphicsStateGuardian.h b/panda/src/display/graphicsStateGuardian.h index 639d3a18be..1563081271 100644 --- a/panda/src/display/graphicsStateGuardian.h +++ b/panda/src/display/graphicsStateGuardian.h @@ -66,7 +66,8 @@ class EXPCL_PANDA GraphicsStateGuardian : public GraphicsStateGuardianBase { // Interfaces all GSGs should have // public: - GraphicsStateGuardian(const FrameBufferProperties &properties); + GraphicsStateGuardian(const FrameBufferProperties &properties, + CoordinateSystem internal_coordinate_system); virtual ~GraphicsStateGuardian(); PUBLISHED: @@ -82,9 +83,10 @@ PUBLISHED: INLINE const GraphicsThreadingModel &get_threading_model() const; INLINE int get_max_texture_stages() const; + INLINE bool get_copy_texture_inverted() const; public: - INLINE void set_scene(SceneSetup *scene_setup); + INLINE bool set_scene(SceneSetup *scene_setup); INLINE SceneSetup *get_scene() const; virtual PreparedGraphicsObjects *get_prepared_objects(); @@ -148,13 +150,11 @@ public: const DisplayRegion *dr); 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); + void set_coordinate_system(CoordinateSystem cs); INLINE CoordinateSystem get_coordinate_system() const; - virtual CoordinateSystem get_internal_coordinate_system() const; + INLINE CoordinateSystem get_internal_coordinate_system() const; + + INLINE const TransformState *get_cs_transform() const; virtual void issue_transform(const TransformState *transform); virtual void issue_color_scale(const ColorScaleAttrib *attrib); @@ -250,6 +250,8 @@ protected: int _force_normals; CoordinateSystem _coordinate_system; + CoordinateSystem _internal_coordinate_system; + CPT(TransformState) _cs_transform; Colorf _scene_graph_color; bool _has_scene_graph_color; @@ -277,6 +279,7 @@ protected: PT(PreparedGraphicsObjects) _prepared_objects; int _max_texture_stages; + bool _copy_texture_inverted; public: // Statistics diff --git a/panda/src/dxgsg7/dxGraphicsStateGuardian7.cxx b/panda/src/dxgsg7/dxGraphicsStateGuardian7.cxx index 54a2ada905..49f37117a3 100644 --- a/panda/src/dxgsg7/dxGraphicsStateGuardian7.cxx +++ b/panda/src/dxgsg7/dxGraphicsStateGuardian7.cxx @@ -229,7 +229,7 @@ set_color_clear_value(const Colorf& value) { //////////////////////////////////////////////////////////////////// DXGraphicsStateGuardian7:: DXGraphicsStateGuardian7(const FrameBufferProperties &properties) : - GraphicsStateGuardian(properties) + GraphicsStateGuardian(properties, CS_yup_left) { // allocate local buffers used during rendering @@ -776,11 +776,10 @@ prepare_display_region() { // Function: DXGraphicsStateGuardian7::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(). +// recently specified with set_scene()) active, so +// that it will transform future rendered geometry. +// Normally this is only called from the draw process, +// and usually it is called by set_scene(). // // The return value is true if the lens is acceptable, // false if it is not. @@ -816,6 +815,13 @@ prepare_lens() { LMatrix4f new_projection_mat = convert_mat * projection_mat * rescale_mat; + if (_scene_setup->get_inverted()) { + // If the scene is supposed to be inverted, then invert the + // projection matrix. + static LMatrix4f invert_mat = LMatrix4f::scale_mat(1.0f, -1.0f, 1.0f); + new_projection_mat *= invert_mat; + } + HRESULT hr = hr = _pD3DDevice->SetTransform(D3DTRANSFORMSTATE_PROJECTION, (LPD3DMATRIX)new_projection_mat.get_data()); @@ -4304,24 +4310,6 @@ depth_offset_decals() { return dx_depth_offset_decals; } -//////////////////////////////////////////////////////////////////// -// Function: DXGraphicsStateGuardian7::get_internal_coordinate_system -// Access: Public, Virtual -// Description: Should be overridden by derived classes to return the -// coordinate system used internally by the GSG, if any -// one particular coordinate system is used. The -// default, CS_default, indicates that the GSG can use -// any coordinate system. -// -// If this returns other than CS_default, the -// GraphicsEngine will automatically convert all -// transforms into the indicated coordinate system. -//////////////////////////////////////////////////////////////////// -CoordinateSystem DXGraphicsStateGuardian7:: -get_internal_coordinate_system() const { - return CS_yup_left; -} - //////////////////////////////////////////////////////////////////// // Function: DXGraphicsStateGuardian7::compute_distance_to // Access: Public, Virtual diff --git a/panda/src/dxgsg7/dxGraphicsStateGuardian7.h b/panda/src/dxgsg7/dxGraphicsStateGuardian7.h index 86c0a70a8c..03ee0cd309 100644 --- a/panda/src/dxgsg7/dxGraphicsStateGuardian7.h +++ b/panda/src/dxgsg7/dxGraphicsStateGuardian7.h @@ -133,7 +133,6 @@ public: virtual bool depth_offset_decals(); - virtual CoordinateSystem get_internal_coordinate_system() const; INLINE float compute_distance_to(const LPoint3f &point) const; virtual void set_color_clear_value(const Colorf& value); diff --git a/panda/src/dxgsg8/dxGraphicsStateGuardian8.cxx b/panda/src/dxgsg8/dxGraphicsStateGuardian8.cxx index 12c7c19fbb..d0824c999f 100644 --- a/panda/src/dxgsg8/dxGraphicsStateGuardian8.cxx +++ b/panda/src/dxgsg8/dxGraphicsStateGuardian8.cxx @@ -367,7 +367,8 @@ reset_panda_gsg(void) { //////////////////////////////////////////////////////////////////// DXGraphicsStateGuardian8:: DXGraphicsStateGuardian8(const FrameBufferProperties &properties) : - GraphicsStateGuardian(properties) { + GraphicsStateGuardian(properties, CS_yup_left) +{ reset_panda_gsg(); @@ -991,11 +992,10 @@ prepare_display_region() { // Function: DXGraphicsStateGuardian8::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(). +// recently specified with set_scene()) active, so +// that it will transform future rendered geometry. +// Normally this is only called from the draw process, +// and usually it is called by set_scene(). // // The return value is true if the lens is acceptable, // false if it is not. @@ -1031,6 +1031,13 @@ prepare_lens() { LMatrix4f new_projection_mat = convert_mat * projection_mat * rescale_mat; + if (_scene_setup->get_inverted()) { + // If the scene is supposed to be inverted, then invert the + // projection matrix. + static LMatrix4f invert_mat = LMatrix4f::scale_mat(1.0f, -1.0f, 1.0f); + new_projection_mat *= invert_mat; + } + HRESULT hr = _pD3DDevice->SetTransform(D3DTS_PROJECTION, (D3DMATRIX*)new_projection_mat.get_data()); @@ -4077,24 +4084,6 @@ depth_offset_decals() { return false; } -//////////////////////////////////////////////////////////////////// -// Function: DXGraphicsStateGuardian8::get_internal_coordinate_system -// Access: Public, Virtual -// Description: Should be overridden by derived classes to return the -// coordinate system used internally by the GSG, if any -// one particular coordinate system is used. The -// default, CS_default, indicates that the GSG can use -// any coordinate system. -// -// If this returns other than CS_default, the -// GraphicsEngine will automatically convert all -// transforms into the indicated coordinate system. -//////////////////////////////////////////////////////////////////// -CoordinateSystem DXGraphicsStateGuardian8:: -get_internal_coordinate_system() const { - return CS_yup_left; -} - //////////////////////////////////////////////////////////////////// // Function: DXGraphicsStateGuardian8::set_draw_buffer // Access: Protected diff --git a/panda/src/dxgsg8/dxGraphicsStateGuardian8.h b/panda/src/dxgsg8/dxGraphicsStateGuardian8.h index 7c51e7d73d..250692cbd6 100644 --- a/panda/src/dxgsg8/dxGraphicsStateGuardian8.h +++ b/panda/src/dxgsg8/dxGraphicsStateGuardian8.h @@ -139,7 +139,6 @@ public: virtual bool depth_offset_decals(); - virtual CoordinateSystem get_internal_coordinate_system() const; INLINE float compute_distance_to(const LPoint3f &point) const; virtual void set_color_clear_value(const Colorf& value); diff --git a/panda/src/dxgsg9/dxGraphicsStateGuardian9.cxx b/panda/src/dxgsg9/dxGraphicsStateGuardian9.cxx index 5ceede9772..7e612fb3a4 100755 --- a/panda/src/dxgsg9/dxGraphicsStateGuardian9.cxx +++ b/panda/src/dxgsg9/dxGraphicsStateGuardian9.cxx @@ -366,7 +366,8 @@ reset_panda_gsg(void) { //////////////////////////////////////////////////////////////////// DXGraphicsStateGuardian9:: DXGraphicsStateGuardian9(const FrameBufferProperties &properties) : - GraphicsStateGuardian(properties) { + GraphicsStateGuardian(properties, CS_yup_left) +{ reset_panda_gsg(); @@ -983,11 +984,10 @@ prepare_display_region() { // Function: DXGraphicsStateGuardian9::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(). +// recently specified with set_scene()) active, so +// that it will transform future rendered geometry. +// Normally this is only called from the draw process, +// and usually it is called by set_scene(). // // The return value is true if the lens is acceptable, // false if it is not. @@ -1023,6 +1023,13 @@ prepare_lens() { LMatrix4f new_projection_mat = convert_mat * projection_mat * rescale_mat; + if (_scene_setup->get_inverted()) { + // If the scene is supposed to be inverted, then invert the + // projection matrix. + static LMatrix4f invert_mat = LMatrix4f::scale_mat(1.0f, -1.0f, 1.0f); + new_projection_mat *= invert_mat; + } + HRESULT hr = _pD3DDevice->SetTransform(D3DTS_PROJECTION, (D3DMATRIX*)new_projection_mat.get_data()); @@ -4079,24 +4086,6 @@ depth_offset_decals() { return false; } -//////////////////////////////////////////////////////////////////// -// Function: DXGraphicsStateGuardian9::get_internal_coordinate_system -// Access: Public, Virtual -// Description: Should be overridden by derived classes to return the -// coordinate system used internally by the GSG, if any -// one particular coordinate system is used. The -// default, CS_default, indicates that the GSG can use -// any coordinate system. -// -// If this returns other than CS_default, the -// GraphicsEngine will automatically convert all -// transforms into the indicated coordinate system. -//////////////////////////////////////////////////////////////////// -CoordinateSystem DXGraphicsStateGuardian9:: -get_internal_coordinate_system() const { - return CS_yup_left; -} - //////////////////////////////////////////////////////////////////// // Function: DXGraphicsStateGuardian9::set_draw_buffer // Access: Protected diff --git a/panda/src/dxgsg9/dxGraphicsStateGuardian9.h b/panda/src/dxgsg9/dxGraphicsStateGuardian9.h index 8776cb1a5e..288bb167ed 100755 --- a/panda/src/dxgsg9/dxGraphicsStateGuardian9.h +++ b/panda/src/dxgsg9/dxGraphicsStateGuardian9.h @@ -140,7 +140,6 @@ public: virtual bool depth_offset_decals(); - virtual CoordinateSystem get_internal_coordinate_system() const; INLINE float compute_distance_to(const LPoint3f &point) const; virtual void set_color_clear_value(const Colorf& value); diff --git a/panda/src/glstuff/glGraphicsStateGuardian_src.cxx b/panda/src/glstuff/glGraphicsStateGuardian_src.cxx index 5c00a803cc..2346cce00f 100644 --- a/panda/src/glstuff/glGraphicsStateGuardian_src.cxx +++ b/panda/src/glstuff/glGraphicsStateGuardian_src.cxx @@ -272,7 +272,7 @@ fix_component_ordering(GLenum external_format, PixelBuffer *pb) { //////////////////////////////////////////////////////////////////// CLP(GraphicsStateGuardian):: CLP(GraphicsStateGuardian)(const FrameBufferProperties &properties) : - GraphicsStateGuardian(properties) + GraphicsStateGuardian(properties, CS_yup_right) { _error_count = 0; #ifdef HAVE_CGGL @@ -640,11 +640,10 @@ prepare_display_region() { // Function: CLP(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(). +// recently specified with set_scene()) active, so +// that it will transform future rendered geometry. +// Normally this is only called from the draw process, +// and usually it is called by set_scene(). // // The return value is true if the lens is acceptable, // false if it is not. @@ -672,6 +671,13 @@ prepare_lens() { LMatrix4f::convert_mat(CS_yup_right, _current_lens->get_coordinate_system()) * projection_mat; + if (_scene_setup->get_inverted()) { + // If the scene is supposed to be inverted, then invert the + // projection matrix. + static LMatrix4f invert_mat = LMatrix4f::scale_mat(1.0f, -1.0f, 1.0f); + new_projection_mat *= invert_mat; + } + #ifdef GSG_VERBOSE GLCAT.spam() << "glMatrixMode(GL_PROJECTION): " << new_projection_mat << endl; @@ -2822,24 +2828,6 @@ depth_offset_decals() { return CLP(depth_offset_decals); } -//////////////////////////////////////////////////////////////////// -// Function: CLP(GraphicsStateGuardian)::get_internal_coordinate_system -// Access: Public, Virtual -// Description: Should be overridden by derived classes to return the -// coordinate system used internally by the GSG, if any -// one particular coordinate system is used. The -// default, CS_default, indicates that the GSG can use -// any coordinate system. -// -// If this returns other than CS_default, the -// GraphicsEngine will automatically convert all -// transforms into the indicated coordinate system. -//////////////////////////////////////////////////////////////////// -CoordinateSystem CLP(GraphicsStateGuardian):: -get_internal_coordinate_system() const { - return CS_yup_right; -} - //////////////////////////////////////////////////////////////////// // Function: CLP(GraphicsStateGuardian)::compute_distance_to // Access: Public, Virtual diff --git a/panda/src/glstuff/glGraphicsStateGuardian_src.h b/panda/src/glstuff/glGraphicsStateGuardian_src.h index 8165e9f464..2579854ce9 100644 --- a/panda/src/glstuff/glGraphicsStateGuardian_src.h +++ b/panda/src/glstuff/glGraphicsStateGuardian_src.h @@ -134,7 +134,6 @@ public: virtual bool depth_offset_decals(); - virtual CoordinateSystem get_internal_coordinate_system() const; virtual float compute_distance_to(const LPoint3f &point) const; void print_gfx_visual(); diff --git a/panda/src/gobj/lens.cxx b/panda/src/gobj/lens.cxx index aca141a1bc..cae2456091 100644 --- a/panda/src/gobj/lens.cxx +++ b/panda/src/gobj/lens.cxx @@ -556,7 +556,7 @@ set_view_mat(const LMatrix4f &view_mat) { _lens_mat = view_mat; adjust_user_flags(UF_view_vector | UF_view_hpr | UF_iod_offset, UF_view_mat); - adjust_comp_flags(CF_lens_mat_inv | CF_view_hpr | CF_view_vector | CF_iod_offset, + adjust_comp_flags(CF_projection_mat | CF_projection_mat_inv | CF_lens_mat_inv | CF_view_hpr | CF_view_vector | CF_iod_offset, CF_lens_mat); throw_change_event(); } diff --git a/panda/src/pgraph/cullTraverser.I b/panda/src/pgraph/cullTraverser.I index cfd44a4370..9d5d3ce88f 100644 --- a/panda/src/pgraph/cullTraverser.I +++ b/panda/src/pgraph/cullTraverser.I @@ -27,10 +27,12 @@ INLINE void CullTraverser:: set_scene(SceneSetup *scene_setup) { _scene_setup = scene_setup; + _initial_state = scene_setup->get_initial_state(); + const Camera *camera = scene_setup->get_camera_node(); _tag_state_key = camera->get_tag_state_key(); _has_tag_state_key = !_tag_state_key.empty(); - _initial_state = camera->get_initial_state(); + _camera_mask = camera->get_camera_mask(); } //////////////////////////////////////////////////////////////////// diff --git a/panda/src/pgraph/sceneSetup.I b/panda/src/pgraph/sceneSetup.I index b838f46bd1..eb73240a8c 100644 --- a/panda/src/pgraph/sceneSetup.I +++ b/panda/src/pgraph/sceneSetup.I @@ -24,6 +24,8 @@ //////////////////////////////////////////////////////////////////// INLINE SceneSetup:: SceneSetup() { + _inverted = false; + _initial_state = RenderState::make_empty(); _camera_transform = TransformState::make_identity(); _world_transform = TransformState::make_identity(); _cs_transform = TransformState::make_identity(); @@ -109,6 +111,32 @@ get_lens() const { return _lens; } +//////////////////////////////////////////////////////////////////// +// Function: SceneSetup::set_inverted +// Access: Published +// Description: Changes the current setting of the inverted flag. +// When this is true, the scene is rendered into the +// window upside-down and backwards, that is, inverted +// as if viewed through a mirror placed on the floor. +//////////////////////////////////////////////////////////////////// +INLINE void SceneSetup:: +set_inverted(bool inverted) { + _inverted = inverted; +} + +//////////////////////////////////////////////////////////////////// +// Function: SceneSetup::get_inverted +// Access: Published +// Description: Returns the current setting of the inverted flag. +// When this is true, the scene is rendered into the +// window upside-down, flipped like a mirror along the X +// axis. +//////////////////////////////////////////////////////////////////// +INLINE bool SceneSetup:: +get_inverted() const { + return _inverted; +} + //////////////////////////////////////////////////////////////////// // Function: SceneSetup::get_cull_center // Access: Public @@ -126,6 +154,29 @@ get_cull_center() const { } } +//////////////////////////////////////////////////////////////////// +// Function: SceneSetup::set_initial_state +// Access: Published +// Description: Sets the initial state which is applied to all nodes +// in the scene, as if it were set at the top of the +// scene graph. +//////////////////////////////////////////////////////////////////// +INLINE void SceneSetup:: +set_initial_state(const RenderState *state) { + _initial_state = state; +} + +//////////////////////////////////////////////////////////////////// +// Function: SceneSetup::get_initial_state +// Access: Published +// Description: Returns the initial state as set by a previous call +// to set_initial_state(). +//////////////////////////////////////////////////////////////////// +INLINE const RenderState *SceneSetup:: +get_initial_state() const { + return _initial_state; +} + //////////////////////////////////////////////////////////////////// // Function: SceneSetup::set_camera_transform // Access: Public diff --git a/panda/src/pgraph/sceneSetup.h b/panda/src/pgraph/sceneSetup.h index ff78755d7e..d8a81ee361 100644 --- a/panda/src/pgraph/sceneSetup.h +++ b/panda/src/pgraph/sceneSetup.h @@ -50,8 +50,14 @@ public: INLINE void set_lens(const Lens *lens); INLINE const Lens *get_lens() const; + INLINE void set_inverted(bool inverted); + INLINE bool get_inverted() const; + INLINE const NodePath &get_cull_center() const; + INLINE void set_initial_state(const RenderState *initial_state); + INLINE const RenderState *get_initial_state() const; + INLINE void set_camera_transform(const TransformState *camera_transform); INLINE const TransformState *get_camera_transform() const; @@ -68,6 +74,8 @@ private: NodePath _camera_path; PT(Camera) _camera_node; CPT(Lens) _lens; + bool _inverted; + CPT(RenderState) _initial_state; CPT(TransformState) _camera_transform; CPT(TransformState) _world_transform; CPT(TransformState) _cs_transform;