Selaa lähdekoodia

Support for TexMatrix and projected textures

rdb 16 vuotta sitten
vanhempi
sitoutus
d1f9183119

+ 43 - 17
panda/src/pgraphnodes/shaderGenerator.cxx

@@ -232,7 +232,9 @@ analyze_renderstate(const RenderState *rs) {
   }
   }
 
 
   // See if there is a normal map, height map, gloss map, or glow map.
   // See if there is a normal map, height map, gloss map, or glow map.
-
+  // Also check if anything has TexGen.
+  
+  const TexGenAttrib *tex_gen = DCAST(TexGenAttrib, rs->get_attrib_def(TexGenAttrib::get_class_slot()));
   for (int i=0; i<_num_textures; i++) {
   for (int i=0; i<_num_textures; i++) {
     TextureStage *stage = texture->get_on_stage(i);
     TextureStage *stage = texture->get_on_stage(i);
     TextureStage::Mode mode = stage->get_mode();
     TextureStage::Mode mode = stage->get_mode();
@@ -254,6 +256,11 @@ analyze_renderstate(const RenderState *rs) {
     if (mode == TextureStage::M_normal_height) {
     if (mode == TextureStage::M_normal_height) {
       _map_height_in_alpha = true;
       _map_height_in_alpha = true;
     }
     }
+    if (tex_gen->has_stage(stage)) {
+      if (tex_gen->get_mode(stage) == TexGenAttrib::M_world_position) {
+        _need_worldspace_pos = true;
+      }
+    }
   }
   }
 
 
   // Determine whether lighting is needed.
   // Determine whether lighting is needed.
@@ -355,17 +362,11 @@ analyze_renderstate(const RenderState *rs) {
 
 
   const ClipPlaneAttrib *clip_plane = DCAST(ClipPlaneAttrib, rs->get_attrib_def(ClipPlaneAttrib::get_class_slot()));
   const ClipPlaneAttrib *clip_plane = DCAST(ClipPlaneAttrib, rs->get_attrib_def(ClipPlaneAttrib::get_class_slot()));
   _num_clip_planes = clip_plane->get_num_on_planes();
   _num_clip_planes = clip_plane->get_num_on_planes();
+  if (_num_clip_planes > 0) {
+    _need_worldspace_pos = true;
+  }
 
 
   // Check for unimplemented features and issue warnings.
   // Check for unimplemented features and issue warnings.
-
-  const TexMatrixAttrib *tex_matrix = DCAST(TexMatrixAttrib, rs->get_attrib_def(TexMatrixAttrib::get_class_slot()));
-  if (!tex_matrix->is_empty()) {
-    pgraph_cat.error() << "Shader Generator does not support TexMatrix yet.\n";
-  }
-  const TexGenAttrib *tex_gen = DCAST(TexGenAttrib, rs->get_attrib_def(TexGenAttrib::get_class_slot()));
-  if (!tex_gen->is_empty()) {
-    pgraph_cat.error() << "Shader Generator does not support TexGen yet.\n";
-  }
   const FogAttrib *fog = DCAST(FogAttrib, rs->get_attrib_def(FogAttrib::get_class_slot()));
   const FogAttrib *fog = DCAST(FogAttrib, rs->get_attrib_def(FogAttrib::get_class_slot()));
   if (!fog->is_off()) {
   if (!fog->is_off()) {
     pgraph_cat.error() << "Shader Generator does not support Fog yet.\n";
     pgraph_cat.error() << "Shader Generator does not support Fog yet.\n";
@@ -407,6 +408,7 @@ clear_analysis() {
   _out_aux_glow     = false;
   _out_aux_glow     = false;
   _out_aux_any      = false;
   _out_aux_any      = false;
   _material = (Material*)NULL;
   _material = (Material*)NULL;
+  _need_worldspace_pos = false;
   _need_material_props = false;
   _need_material_props = false;
   _alights.clear();
   _alights.clear();
   _dlights.clear();
   _dlights.clear();
@@ -518,12 +520,12 @@ update_shadow_buffer(NodePath light_np) {
 //               - color scale attrib
 //               - color scale attrib
 //               - light ramps (for cartoon shading)
 //               - light ramps (for cartoon shading)
 //               - shadow mapping
 //               - shadow mapping
+//               - texgen
+//               - texmatrix
 //
 //
 //               Not yet supported:
 //               Not yet supported:
 //               - 3D textures, cube textures
 //               - 3D textures, cube textures
 //               - dot3_rgb and dot3_rgba combine modes
 //               - dot3_rgb and dot3_rgba combine modes
-//               - texgen
-//               - texmatrix
 //               - fog
 //               - fog
 //
 //
 //               Potential optimizations
 //               Potential optimizations
@@ -574,7 +576,7 @@ synthesize_shader(const RenderState *rs) {
     text << "\t in float4 vtx_color : COLOR,\n";
     text << "\t in float4 vtx_color : COLOR,\n";
     text << "\t out float4 l_color : COLOR,\n";
     text << "\t out float4 l_color : COLOR,\n";
   }
   }
-  if (_num_clip_planes > 0) {
+  if (_need_worldspace_pos > 0) {
     text << "\t out float4 l_worldpos,\n";
     text << "\t out float4 l_worldpos,\n";
     text << "\t uniform float4x4 trans_model_to_world,\n";
     text << "\t uniform float4x4 trans_model_to_world,\n";
   }
   }
@@ -635,18 +637,43 @@ synthesize_shader(const RenderState *rs) {
     text << "\t in float4 vtx_normal : " << normal_vreg << ",\n";
     text << "\t in float4 vtx_normal : " << normal_vreg << ",\n";
     text << "\t out float4 l_normal : " << normal_freg << ",\n";
     text << "\t out float4 l_normal : " << normal_freg << ",\n";
   }
   }
-
+  const TextureAttrib *texture = DCAST(TextureAttrib, rs->get_attrib_def(TextureAttrib::get_class_slot()));
+  const TexMatrixAttrib *tex_matrix = DCAST(TexMatrixAttrib, rs->get_attrib_def(TexMatrixAttrib::get_class_slot()));
+  if (texture != NULL && tex_matrix != NULL && !tex_matrix->is_empty()) {
+    for (int i=0; i<_num_textures; i++) {
+      if (tex_matrix->has_stage(texture->get_on_stage(i))) {
+        text << "\t uniform float4x4 texmat_" << i << ",\n";
+      }
+    }
+  }
   text << "\t float4 vtx_position : POSITION,\n";
   text << "\t float4 vtx_position : POSITION,\n";
   text << "\t out float4 l_position : POSITION,\n";
   text << "\t out float4 l_position : POSITION,\n";
   text << "\t uniform float4x4 mat_modelproj\n";
   text << "\t uniform float4x4 mat_modelproj\n";
   text << ") {\n";
   text << ") {\n";
 
 
   text << "\t l_position = mul(mat_modelproj, vtx_position);\n";
   text << "\t l_position = mul(mat_modelproj, vtx_position);\n";
-  if (_num_clip_planes > 0) {
+  if (_need_worldspace_pos) {
     text << "\t l_worldpos = mul(trans_model_to_world, vtx_position);\n";
     text << "\t l_worldpos = mul(trans_model_to_world, vtx_position);\n";
   }
   }
+  // Now load in / generate the texture coordinates for each stage. If it has a TexMatrixAttrib, also transform it.
   for (int i=0; i<_num_textures; i++) {
   for (int i=0; i<_num_textures; i++) {
-    text << "\t l_texcoord" << i << " = vtx_texcoord" << i << ";\n";
+    TextureStage *stage = texture->get_on_stage(i);
+    const TexGenAttrib *tex_gen = DCAST(TexGenAttrib, rs->get_attrib_def(TexGenAttrib::get_class_slot()));
+    if (tex_gen != NULL && tex_gen->has_stage(stage)) {
+      switch (tex_gen->get_mode(stage)) {
+        case TexGenAttrib::M_world_position:
+          text << "\t l_texcoord" << i << " = l_worldpos;\n";
+          break;
+        default:
+          pgraph_cat.error() << "Unsupported TexGenAttrib mode\n";
+      }
+    } else {
+      text << "\t l_texcoord" << i << " = vtx_texcoord" << i << ";\n";
+    }
+    if (tex_matrix != NULL && tex_matrix->has_stage(stage)) {
+      text << "\t l_texcoord" << i << " = mul(texmat_" << i << ", l_texcoord" << i << ");\n";
+      text << "\t l_texcoord" << i << ".xyz /= l_texcoord" << i << ".w;\n";
+    }
   }
   }
   if (_vertex_colors) {
   if (_vertex_colors) {
     text << "\t l_color = vtx_color;\n";
     text << "\t l_color = vtx_color;\n";
@@ -1035,7 +1062,6 @@ synthesize_shader(const RenderState *rs) {
   }
   }
 
 
   text << "\t float4 primary_color = result;\n";
   text << "\t float4 primary_color = result;\n";
-  const TextureAttrib *texture = DCAST(TextureAttrib, rs->get_attrib_def(TextureAttrib::get_class_slot()));
   bool have_saved_result = false;
   bool have_saved_result = false;
   for (int i=0; i<_num_textures; i++) {
   for (int i=0; i<_num_textures; i++) {
     TextureStage *stage = texture->get_on_stage(i);
     TextureStage *stage = texture->get_on_stage(i);

+ 1 - 0
panda/src/pgraphnodes/shaderGenerator.h

@@ -135,6 +135,7 @@ protected:
   int _num_clip_planes;
   int _num_clip_planes;
   bool _use_shadow_filter;
   bool _use_shadow_filter;
 
 
+  bool _need_worldspace_pos;
   bool _need_material_props;
   bool _need_material_props;
 
 
   void analyze_renderstate(const RenderState *rs);
   void analyze_renderstate(const RenderState *rs);