Browse Source

dx points and point sprites

David Rose 20 years ago
parent
commit
a4677868e2

+ 9 - 0
panda/src/display/standardMunger.cxx

@@ -161,8 +161,17 @@ munge_geom_impl(CPT(qpGeom) &geom, CPT(qpGeomVertexData) &vertex_data) {
       geom = geom->decompose();
       geom = geom->decompose();
     }
     }
     if ((unsupported_bits & qpGeom::GR_shade_model_bits) != 0) {
     if ((unsupported_bits & qpGeom::GR_shade_model_bits) != 0) {
+      // Rotate the vertices to account for different shade-model
+      // expectations (e.g. SM_flat_last_vertex to
+      // SM_flat_first_vertex)
       geom = geom->rotate();
       geom = geom->rotate();
     }
     }
+    if ((unsupported_bits & qpGeom::GR_indexed_bits) != 0) {
+      // Convert indexed geometry to nonindexed geometry.
+      PT(qpGeom) new_geom = new qpGeom(*geom);
+      new_geom->make_nonindexed(false);
+      geom = new_geom;
+    }
   }
   }
 
 
   return true;
   return true;

+ 92 - 46
panda/src/dxgsg8/dxGraphicsStateGuardian8.cxx

@@ -55,6 +55,8 @@
 #include "qpgeomTristrips.h"
 #include "qpgeomTristrips.h"
 #include "qpgeomTrifans.h"
 #include "qpgeomTrifans.h"
 #include "qpgeomLines.h"
 #include "qpgeomLines.h"
+#include "qpgeomLinestrips.h"
+#include "qpgeomPoints.h"
 #include "qpGeomVertexReader.h"
 #include "qpGeomVertexReader.h"
 #include "dxGeomMunger8.h"
 #include "dxGeomMunger8.h"
 #include "config_gobj.h"
 #include "config_gobj.h"
@@ -223,7 +225,13 @@ DXGraphicsStateGuardian8(const FrameBufferProperties &properties) :
   // they copy framebuffer-to-texture.  Ok.
   // they copy framebuffer-to-texture.  Ok.
   _copy_texture_inverted = true;
   _copy_texture_inverted = true;
 
 
+  // D3DRS_POINTSPRITEENABLE doesn't seem to support remapping the
+  // texture coordinates via a texture matrix, a fatal flaw.  Without
+  // that support, we don't advertise this capability, and fall back
+  // to always generating quads for textured sprites.
   _supported_geom_rendering = 
   _supported_geom_rendering = 
+    qpGeom::GR_point | qpGeom::GR_point_uniform_size | 
+    qpGeom::GR_point_perspective | /* qpGeom::GR_point_sprite |*/
     qpGeom::GR_triangle_strip | qpGeom::GR_triangle_fan |
     qpGeom::GR_triangle_strip | qpGeom::GR_triangle_fan |
     qpGeom::GR_flat_first_vertex;
     qpGeom::GR_flat_first_vertex;
 }
 }
@@ -401,8 +409,7 @@ dx_init(void) {
     _fog_enabled = false;
     _fog_enabled = false;
     _pD3DDevice->SetRenderState(D3DRS_FOGENABLE, _fog_enabled);
     _pD3DDevice->SetRenderState(D3DRS_FOGENABLE, _fog_enabled);
 
 
-    _current_projection_mat = LMatrix4f::ident_mat();
-    _projection_mat_stack_count = 0;
+    _projection_mat = LMatrix4f::ident_mat();
     _has_scene_graph_color = false;
     _has_scene_graph_color = false;
 
 
     // Apply a default material when materials are turned off.
     // Apply a default material when materials are turned off.
@@ -663,6 +670,7 @@ prepare_display_region() {
   if (_current_display_region == (DisplayRegion*)0L) {
   if (_current_display_region == (DisplayRegion*)0L) {
     dxgsg8_cat.error()
     dxgsg8_cat.error()
       << "Invalid NULL display region in prepare_display_region()\n";
       << "Invalid NULL display region in prepare_display_region()\n";
+
   } else if (_current_display_region != _actual_display_region) {
   } else if (_current_display_region != _actual_display_region) {
     _actual_display_region = _current_display_region;
     _actual_display_region = _current_display_region;
     
     
@@ -719,7 +727,7 @@ prepare_lens() {
   }
   }
 
 
   // Start with the projection matrix from the lens.
   // Start with the projection matrix from the lens.
-  const LMatrix4f &projection_mat = _current_lens->get_projection_mat();
+  const LMatrix4f &lens_mat = _current_lens->get_projection_mat();
 
 
   // The projection matrix must always be left-handed Y-up internally,
   // The projection matrix must always be left-handed Y-up internally,
   // to match DirectX's convention, even if our coordinate system of
   // to match DirectX's convention, even if our coordinate system of
@@ -736,19 +744,18 @@ prepare_lens() {
      0, 0, 0.5, 0,
      0, 0, 0.5, 0,
      0, 0, 0.5, 1);
      0, 0, 0.5, 1);
   
   
-  LMatrix4f new_projection_mat =
-    convert_mat * projection_mat * rescale_mat;
+  _projection_mat = convert_mat * lens_mat * rescale_mat;
 
 
   if (_scene_setup->get_inverted()) {
   if (_scene_setup->get_inverted()) {
     // If the scene is supposed to be inverted, then invert the
     // If the scene is supposed to be inverted, then invert the
     // projection matrix.
     // projection matrix.
     static LMatrix4f invert_mat = LMatrix4f::scale_mat(1.0f, -1.0f, 1.0f);
     static LMatrix4f invert_mat = LMatrix4f::scale_mat(1.0f, -1.0f, 1.0f);
-    new_projection_mat *= invert_mat;
+    _projection_mat *= invert_mat;
   }
   }
 
 
   HRESULT hr = 
   HRESULT hr = 
     _pD3DDevice->SetTransform(D3DTS_PROJECTION,
     _pD3DDevice->SetTransform(D3DTS_PROJECTION,
-                              (D3DMATRIX*)new_projection_mat.get_data());
+                              (D3DMATRIX*)_projection_mat.get_data());
   return SUCCEEDED(hr);
   return SUCCEEDED(hr);
 }
 }
 
 
@@ -3095,6 +3102,48 @@ draw_lines(const qpGeomLines *primitive) {
   }
   }
 }
 }
 
 
+////////////////////////////////////////////////////////////////////
+//     Function: DXGraphicsStateGuardian8::draw_linestrips
+//       Access: Public, Virtual
+//  Description: Draws a series of line strips.
+////////////////////////////////////////////////////////////////////
+void DXGraphicsStateGuardian8::
+draw_linestrips(const qpGeomLinestrips *primitive) {
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: DXGraphicsStateGuardian8::draw_points
+//       Access: Public, Virtual
+//  Description: Draws a series of disconnected points.
+////////////////////////////////////////////////////////////////////
+void DXGraphicsStateGuardian8::
+draw_points(const qpGeomPoints *primitive) {
+  _vertices_other_pcollector.add_level(primitive->get_num_vertices());
+  _primitive_batches_other_pcollector.add_level(1);
+
+  // The munger should have protected us from indexed points--DirectX
+  // doesn't support them.
+  nassertv(!primitive->is_indexed());
+
+  if (_active_vbuffer != NULL) {
+    // Nonindexed, vbuffers.
+    _pD3DDevice->DrawPrimitive
+      (D3DPT_POINTLIST, 
+       primitive->get_first_vertex(), 
+       primitive->get_num_primitives());
+    
+  } else {
+    // Nonindexed, client arrays.
+    int stride = _vertex_data->get_format()->get_array(0)->get_stride();
+    unsigned int first_vertex = primitive->get_first_vertex();
+    _pD3DDevice->DrawPrimitiveUP
+      (D3DPT_POINTLIST, 
+       primitive->get_num_primitives(), 
+       _vertex_data->get_array(0)->get_data() + stride * first_vertex, 
+       stride);
+  }
+}
+
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 //     Function: DXGraphicsStateGuardian8::end_draw_primitives()
 //     Function: DXGraphicsStateGuardian8::end_draw_primitives()
 //       Access: Public, Virtual
 //       Access: Public, Virtual
@@ -3887,47 +3936,23 @@ issue_tex_matrix(const TexMatrixAttrib *attrib) {
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 void DXGraphicsStateGuardian8::
 void DXGraphicsStateGuardian8::
 issue_tex_gen(const TexGenAttrib *attrib) {
 issue_tex_gen(const TexGenAttrib *attrib) {
-  /*
-   * Automatically generate texture coordinates for stage 0.
-   * Use the wrap mode from the texture coordinate set at index 1.
-   */
-  DO_PSTATS_STUFF(_texture_state_pcollector.add_level(1));
-  if (attrib->is_empty()) {
-
-    //enable_texturing(false);
-    // reset the texcoordindex lookup to 0
-    //_pD3DDevice->SetTransform(D3DTS_TEXTURE0, (D3DMATRIX *)dm.get_data());
-    //_pD3DDevice->SetTextureStageState(0, D3DTSS_TEXTURETRANSFORMFLAGS, 0);
-    _pD3DDevice->SetTextureStageState( 0, D3DTSS_TEXCOORDINDEX, 0);
+  TexGenAttrib::Mode mode = attrib->get_mode(TextureStage::get_default());
+  switch (mode) {
+  case TexGenAttrib::M_off:
+    _pD3DDevice->SetTextureStageState(0, D3DTSS_TEXCOORDINDEX, 0);
+    _pD3DDevice->SetRenderState(D3DRS_POINTSPRITEENABLE, FALSE);
+    break;
 
 
-  } else if (attrib->get_mode(TextureStage::get_default()) == TexGenAttrib::M_eye_sphere_map) {
+  case TexGenAttrib::M_eye_sphere_map:
+    _pD3DDevice->SetTextureStageState(0, D3DTSS_TEXCOORDINDEX,
+                                      D3DTSS_TCI_CAMERASPACEREFLECTIONVECTOR);
+    _pD3DDevice->SetRenderState(D3DRS_POINTSPRITEENABLE, FALSE);
+    break;
 
 
-#if 0
-    // best reflection on a sphere is achieved by camera space normals in directx
-    _pD3DDevice->SetTextureStageState( 0, D3DTSS_TEXCOORDINDEX,
-                                       D3DTSS_TCI_CAMERASPACENORMAL);
-    // We have set up the texture matrix to scale and translate the
-    // texture coordinates to get from camera space (-1, +1) to
-    // texture space (0,1)
-    LMatrix4f dm(0.5f, 0.0f, 0.0f, 0.0f,
-                 0.0f, 0.5f, 0.0f, 0.0f,
-                 0.0f, 0.0f, 1.0f, 0.0f,
-                 0.5f, 0.5f, 0.0f, 1.0f);
-#else
-    // since this is a reflection map, we want the camera space
-    // reflection vector. A close approximation of the asin(theta)/pi
-    // + 0.5 is achieved by the following matrix
-    _pD3DDevice->SetTextureStageState( 0, D3DTSS_TEXCOORDINDEX,
-                                       D3DTSS_TCI_CAMERASPACEREFLECTIONVECTOR);
-    LMatrix4f dm(0.33f, 0.0f, 0.0f, 0.0f,
-                 0.0f, 0.33f, 0.0f, 0.0f,
-                 0.0f, 0.0f, 1.0f, 0.0f,
-                 0.5f, 0.5f, 0.0f, 1.0f);
-#endif
-    _pD3DDevice->SetTransform(D3DTS_TEXTURE0, (D3DMATRIX *)dm.get_data());
-    _pD3DDevice->SetTextureStageState(0, D3DTSS_TEXTURETRANSFORMFLAGS, 
-                                          D3DTTFF_COUNT2);
-    //_pD3DDevice->SetRenderState(D3DRS_LOCALVIEWER, false);
+  case TexGenAttrib::M_point_sprite:
+    _pD3DDevice->SetTextureStageState(0, D3DTSS_TEXCOORDINDEX, 0);
+    _pD3DDevice->SetRenderState(D3DRS_POINTSPRITEENABLE, TRUE);
+    break;
   }
   }
 }
 }
 
 
@@ -4015,6 +4040,27 @@ issue_render_mode(const RenderModeAttrib *attrib) {
       << "Unknown render mode " << (int)mode << endl;
       << "Unknown render mode " << (int)mode << endl;
   }
   }
 
 
+  // This might also specify the point size.
+  float point_size = attrib->get_thickness();
+  _pD3DDevice->SetRenderState(D3DRS_POINTSIZE, *((DWORD*)&point_size));
+
+  if (attrib->get_perspective()) {
+    _pD3DDevice->SetRenderState(D3DRS_POINTSCALEENABLE, TRUE);
+
+    LVector3f height(0.0f, point_size, 1.0f);
+    height = height * _projection_mat;
+    float s = height[1] / point_size;
+
+    float zero = 0.0f;
+    float one_over_s2 = 1.0f / (s * s);
+    _pD3DDevice->SetRenderState(D3DRS_POINTSCALE_A, *((DWORD*)&zero));
+    _pD3DDevice->SetRenderState(D3DRS_POINTSCALE_B, *((DWORD*)&zero));
+    _pD3DDevice->SetRenderState(D3DRS_POINTSCALE_C, *((DWORD*)&one_over_s2));
+
+  } else {
+    _pD3DDevice->SetRenderState(D3DRS_POINTSCALEENABLE, FALSE);
+  }
+
   _current_fill_mode = mode;
   _current_fill_mode = mode;
 }
 }
  
  

+ 4 - 2
panda/src/dxgsg8/dxGraphicsStateGuardian8.h

@@ -100,6 +100,8 @@ public:
   virtual void draw_tristrips(const qpGeomTristrips *primitive);
   virtual void draw_tristrips(const qpGeomTristrips *primitive);
   virtual void draw_trifans(const qpGeomTrifans *primitive);
   virtual void draw_trifans(const qpGeomTrifans *primitive);
   virtual void draw_lines(const qpGeomLines *primitive);
   virtual void draw_lines(const qpGeomLines *primitive);
+  virtual void draw_linestrips(const qpGeomLinestrips *primitive);
+  virtual void draw_points(const qpGeomPoints *primitive);
   virtual void end_draw_primitives();
   virtual void end_draw_primitives();
 
 
   virtual TextureContext *prepare_texture(Texture *tex);
   virtual TextureContext *prepare_texture(Texture *tex);
@@ -326,8 +328,8 @@ protected:
   D3DTEXTUREFILTERTYPE _CurTexMagFilter,_CurTexMinFilter,_CurTexMipFilter;
   D3DTEXTUREFILTERTYPE _CurTexMagFilter,_CurTexMinFilter,_CurTexMipFilter;
   DWORD _CurTexAnisoDegree;
   DWORD _CurTexAnisoDegree;
   Texture::WrapMode _CurTexWrapModeU,_CurTexWrapModeV;
   Texture::WrapMode _CurTexWrapModeU,_CurTexWrapModeV;
-  LMatrix4f _current_projection_mat;
-  int _projection_mat_stack_count;
+
+  LMatrix4f _projection_mat;
 
 
   CPT(DisplayRegion) _actual_display_region;
   CPT(DisplayRegion) _actual_display_region;
   const DXVertexBufferContext8 *_active_vbuffer;
   const DXVertexBufferContext8 *_active_vbuffer;

+ 3 - 5
panda/src/glstuff/glGraphicsStateGuardian_src.cxx

@@ -371,6 +371,7 @@ reset() {
   report_extensions();
   report_extensions();
 
 
   _supported_geom_rendering = 
   _supported_geom_rendering = 
+    qpGeom::GR_indexed_point |
     qpGeom::GR_point | qpGeom::GR_point_uniform_size |
     qpGeom::GR_point | qpGeom::GR_point_uniform_size |
     qpGeom::GR_triangle_strip | qpGeom::GR_triangle_fan |
     qpGeom::GR_triangle_strip | qpGeom::GR_triangle_fan |
     qpGeom::GR_flat_last_vertex;
     qpGeom::GR_flat_last_vertex;
@@ -520,9 +521,6 @@ reset() {
   _supports_cube_map = 
   _supports_cube_map = 
     has_extension("GL_ARB_texture_cube_map") || is_at_least_version(1, 3);
     has_extension("GL_ARB_texture_cube_map") || is_at_least_version(1, 3);
 
 
-  _supports_rescale_normal = 
-    has_extension("GL_EXT_rescale_normal") || is_at_least_version(1, 2);
-
   _supports_bgr = 
   _supports_bgr = 
     has_extension("GL_EXT_bgra") || is_at_least_version(1, 2);
     has_extension("GL_EXT_bgra") || is_at_least_version(1, 2);
   _supports_rescale_normal = 
   _supports_rescale_normal = 
@@ -976,6 +974,8 @@ prepare_display_region() {
 
 
     int l, b, w, h;
     int l, b, w, h;
     _actual_display_region->get_region_pixels(l, b, w, h);
     _actual_display_region->get_region_pixels(l, b, w, h);
+    _viewport_width = w;
+    _viewport_height = h;
     GLint x = GLint(l);
     GLint x = GLint(l);
     GLint y = GLint(b);
     GLint y = GLint(b);
     GLsizei width = GLsizei(w);
     GLsizei width = GLsizei(w);
@@ -984,8 +984,6 @@ prepare_display_region() {
     enable_scissor(true);
     enable_scissor(true);
     GLP(Scissor)(x, y, width, height);
     GLP(Scissor)(x, y, width, height);
     GLP(Viewport)(x, y, width, height);
     GLP(Viewport)(x, y, width, height);
-    _viewport_width = width;
-    _viewport_height = height;
   }
   }
   report_my_gl_errors();
   report_my_gl_errors();
 
 

+ 2 - 1
panda/src/pgraph/cullableObject.cxx

@@ -54,7 +54,8 @@ munge_geom(GraphicsStateGuardianBase *gsg,
       int geom_rendering = _state->get_geom_rendering(qpgeom->get_geom_rendering());
       int geom_rendering = _state->get_geom_rendering(qpgeom->get_geom_rendering());
 
 
       GraphicsStateGuardianBase *gsg = traverser->get_gsg();
       GraphicsStateGuardianBase *gsg = traverser->get_gsg();
-      if ((geom_rendering & ~gsg->get_supported_geom_rendering() & qpGeom::GR_point_bits) != 0) {
+      int unsupported_bits = geom_rendering & ~gsg->get_supported_geom_rendering();
+      if ((unsupported_bits & qpGeom::GR_point_bits) != 0) {
         // The GSG doesn't support rendering these fancy points
         // The GSG doesn't support rendering these fancy points
         // directly; we have to render them in software instead.
         // directly; we have to render them in software instead.
         // Munge them into quads.  This will replace the _geom and
         // Munge them into quads.  This will replace the _geom and