Răsfoiți Sursa

support invert_uvs

David Rose 23 ani în urmă
părinte
comite
6df1adfa90

+ 7 - 0
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

+ 2 - 0
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 */

+ 2 - 0
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 =

+ 33 - 0
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

+ 11 - 3
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.

+ 5 - 1
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;