From 6df1adfa90161fe8437fd5cd90ea0129be6af14e Mon Sep 17 00:00:00 2001 From: David Rose Date: Thu, 23 Jan 2003 23:36:20 +0000 Subject: [PATCH] support invert_uvs --- panda/src/distort/config_distort.cxx | 7 ++++++ panda/src/distort/config_distort.h | 2 ++ panda/src/distort/nonlinearImager.cxx | 2 ++ panda/src/distort/projectionScreen.I | 33 ++++++++++++++++++++++++++ panda/src/distort/projectionScreen.cxx | 14 ++++++++--- panda/src/distort/projectionScreen.h | 6 ++++- 6 files changed, 60 insertions(+), 4 deletions(-) diff --git a/panda/src/distort/config_distort.cxx b/panda/src/distort/config_distort.cxx index b718c2fd0d..5668ea7b6b 100644 --- a/panda/src/distort/config_distort.cxx +++ b/panda/src/distort/config_distort.cxx @@ -31,6 +31,13 @@ ConfigureFn(config_distort) { init_libdistort(); } +// Set this true to compensate for a graphics driver bug in which the +// driver inverts the image when it copies framebuffer-to-texture. +// (This bug is arguably a problem with the OpenGL spec, which seems +// to be unclear about the proper ordering of pixels in this +// operation.) +const bool project_invert_uvs = config_distort.GetBool("project-invert-uvs", false); + //////////////////////////////////////////////////////////////////// // Function: init_libdistort // Description: Initializes the library. This must be called at diff --git a/panda/src/distort/config_distort.h b/panda/src/distort/config_distort.h index e1ba1f8e06..40576143de 100644 --- a/panda/src/distort/config_distort.h +++ b/panda/src/distort/config_distort.h @@ -24,6 +24,8 @@ NotifyCategoryDecl(distort, EXPCL_PANDAFX, EXPTP_PANDAFX); +extern const bool project_invert_uvs; + extern EXPCL_PANDAFX void init_libdistort(); #endif /* CONFIG_DISTORT_H */ diff --git a/panda/src/distort/nonlinearImager.cxx b/panda/src/distort/nonlinearImager.cxx index a16008dfdb..54e93b614f 100644 --- a/panda/src/distort/nonlinearImager.cxx +++ b/panda/src/distort/nonlinearImager.cxx @@ -596,6 +596,8 @@ render_screen(GraphicsEngine *engine, NonlinearImager::Screen &screen) { nassertv(_gsg != (GraphicsStateGuardian *)NULL); + screen._screen->recompute_if_stale(); + // Make a display region of the proper size and clear it to prepare for // rendering the scene. PT(DisplayRegion) scratch_region = diff --git a/panda/src/distort/projectionScreen.I b/panda/src/distort/projectionScreen.I index a97782760b..f32b1180bc 100644 --- a/panda/src/distort/projectionScreen.I +++ b/panda/src/distort/projectionScreen.I @@ -30,6 +30,39 @@ get_projector() const { return _projector; } +//////////////////////////////////////////////////////////////////// +// Function: ProjectionScreen::set_invert_uvs +// Access: Published +// Description: Some OpenGL graphics drivers are known to invert the +// framebuffer image when they copy it to texture. +// (This is arguably a problem with the OpenGL spec, +// which seems to be unclear about the proper ordering +// of pixels in this operation.) +// +// In any case, set this true to compensate for this +// effect by inverting the UV's of the projection +// screen. The default is taken from the Configrc +// variable project-invert-uvs. +//////////////////////////////////////////////////////////////////// +INLINE void ProjectionScreen:: +set_invert_uvs(bool invert_uvs) { + _invert_uvs = invert_uvs; + _stale = true; +} + + +//////////////////////////////////////////////////////////////////// +// Function: ProjectionScreen::get_invert_uvs +// Access: Published +// Description: Returns whether this screen is compensating for a +// graphics driver inverting the framebuffer image. See +// set_invert_uvs(). +//////////////////////////////////////////////////////////////////// +INLINE bool ProjectionScreen:: +get_invert_uvs() const { + return _invert_uvs; +} + //////////////////////////////////////////////////////////////////// // Function: ProjectionScreen::set_vignette_on // Access: Published diff --git a/panda/src/distort/projectionScreen.cxx b/panda/src/distort/projectionScreen.cxx index a174a7a32f..eb61fb7b43 100644 --- a/panda/src/distort/projectionScreen.cxx +++ b/panda/src/distort/projectionScreen.cxx @@ -34,6 +34,7 @@ TypeHandle ProjectionScreen::_type_handle; ProjectionScreen:: ProjectionScreen(const string &name) : PandaNode(name) { + _invert_uvs = project_invert_uvs; _vignette_on = false; _vignette_color.set(0.0f, 0.0f, 0.0f, 1.0f); _frame_color.set(1.0f, 1.0f, 1.0f, 1.0f); @@ -335,7 +336,7 @@ recompute() { //////////////////////////////////////////////////////////////////// // Function: ProjectionScreen::recompute_if_stale -// Access: Private +// Access: Public // Description: Calls recompute() only if the relative transform // between the ProjectionScreen and the projector has // changed, or if any other relevant property has @@ -478,16 +479,23 @@ recompute_geom_node(const WorkingNodePath &np, LMatrix4f &rel_mat, //////////////////////////////////////////////////////////////////// void ProjectionScreen:: recompute_geom(Geom *geom, const LMatrix4f &rel_mat) { - static const LMatrix3f LensToUv + static const LMatrix3f lens_to_uv (0.5f, 0.0f, 0.0f, 0.0f, 0.5f, 0.0f, 0.5f, 0.5f, 1.0f); + static const LMatrix3f lens_to_uv_inverted + (0.5f, 0.0f, 0.0f, + 0.0f,-0.5f, 0.0f, + 0.5f, 0.5f, 1.0f); + PTA_TexCoordf uvs; PTA_ushort color_index; Lens *lens = _projector_node->get_lens(); nassertv(lens != (Lens *)NULL); + const LMatrix3f &to_uv = _invert_uvs ? lens_to_uv_inverted : lens_to_uv; + // Iterate through all the vertices in the Geom. int num_vertices = geom->get_num_vertices(); Geom::VertexIterator vi = geom->make_vertex_iterator(); @@ -501,7 +509,7 @@ recompute_geom(Geom *geom, const LMatrix4f &rel_mat) { // Now the lens gives us coordinates in the range [-1, 1]. // Rescale these to [0, 1]. - uvs.push_back(film * LensToUv); + uvs.push_back(film * to_uv); // If we have vignette color in effect, color the vertex according // to whether it fell in front of the lens or not. diff --git a/panda/src/distort/projectionScreen.h b/panda/src/distort/projectionScreen.h index 9fc2320135..dad9cfaac9 100644 --- a/panda/src/distort/projectionScreen.h +++ b/panda/src/distort/projectionScreen.h @@ -72,6 +72,9 @@ PUBLISHED: int num_x_verts, int num_y_verts, float distance); PT(PandaNode) make_flat_mesh(const NodePath &camera); + INLINE void set_invert_uvs(bool invert_uvs); + INLINE bool get_invert_uvs() const; + INLINE void set_vignette_on(bool vignette_on); INLINE bool get_vignette_on() const; @@ -84,9 +87,9 @@ PUBLISHED: public: INLINE const UpdateSeq &get_last_screen() const; + void recompute_if_stale(); private: - void recompute_if_stale(); void do_recompute(const NodePath &this_np); void recompute_node(const WorkingNodePath &np, LMatrix4f &rel_mat, bool &computed_rel_mat); void recompute_child(const WorkingNodePath &np, LMatrix4f &rel_mat, bool &computed_rel_mat); @@ -109,6 +112,7 @@ private: NodePath _projector; PT(LensNode) _projector_node; + bool _invert_uvs; bool _vignette_on; Colorf _vignette_color; Colorf _frame_color;