diff --git a/panda/src/display/graphicsStateGuardian.I b/panda/src/display/graphicsStateGuardian.I index 8a3a5b6f5b..0db5ceeeb6 100644 --- a/panda/src/display/graphicsStateGuardian.I +++ b/panda/src/display/graphicsStateGuardian.I @@ -772,6 +772,17 @@ get_supports_glsl() const { return _supports_glsl; } +//////////////////////////////////////////////////////////////////// +// Function: GraphicsStateGuardian::get_supports_hlsl +// Access: Published +// Description: Returns true if this particular GSG supports +// HLSL shaders. +//////////////////////////////////////////////////////////////////// +INLINE bool GraphicsStateGuardian:: +get_supports_hlsl() const { + return _supports_hlsl; +} + //////////////////////////////////////////////////////////////////// // Function: GraphicsStateGuardian::get_supports_stencil // Access: Published diff --git a/panda/src/display/graphicsStateGuardian.cxx b/panda/src/display/graphicsStateGuardian.cxx index cde94080cd..9ccb360443 100644 --- a/panda/src/display/graphicsStateGuardian.cxx +++ b/panda/src/display/graphicsStateGuardian.cxx @@ -240,6 +240,7 @@ GraphicsStateGuardian(CoordinateSystem internal_coordinate_system, _supports_geometry_shaders = false; _supports_tessellation_shaders = false; _supports_glsl = false; + _supports_hlsl = false; _supports_stencil = false; _supports_stencil_wrap = false; diff --git a/panda/src/display/graphicsStateGuardian.h b/panda/src/display/graphicsStateGuardian.h index 50ef6f0f2d..fccee6ca8f 100644 --- a/panda/src/display/graphicsStateGuardian.h +++ b/panda/src/display/graphicsStateGuardian.h @@ -157,6 +157,7 @@ PUBLISHED: INLINE bool get_supports_tessellation_shaders() const; INLINE bool get_supports_compute_shaders() const; INLINE bool get_supports_glsl() const; + INLINE bool get_supports_hlsl() const; INLINE bool get_supports_stencil() const; INLINE bool get_supports_two_sided_stencil() const; INLINE bool get_supports_geometry_instancing() const; @@ -532,6 +533,7 @@ protected: bool _supports_tessellation_shaders; bool _supports_compute_shaders; bool _supports_glsl; + bool _supports_hlsl; bool _supports_framebuffer_multisample; bool _supports_framebuffer_blit; diff --git a/panda/src/dxgsg9/dxGraphicsStateGuardian9.cxx b/panda/src/dxgsg9/dxGraphicsStateGuardian9.cxx index d3a16f00c2..244044412f 100644 --- a/panda/src/dxgsg9/dxGraphicsStateGuardian9.cxx +++ b/panda/src/dxgsg9/dxGraphicsStateGuardian9.cxx @@ -2339,6 +2339,8 @@ reset() { _pixel_shader_version_major = D3DSHADER_VERSION_MAJOR (d3d_caps.PixelShaderVersion); _pixel_shader_version_minor = D3DSHADER_VERSION_MINOR (d3d_caps.PixelShaderVersion); + _supports_hlsl = (_pixel_shader_version_major != 0); + _vertex_shader_profile = (char *) D3DXGetVertexShaderProfile (_d3d_device); _pixel_shader_profile = (char *) D3DXGetPixelShaderProfile (_d3d_device); diff --git a/panda/src/gobj/shader.h b/panda/src/gobj/shader.h index c5b8a3095b..250b7915c7 100644 --- a/panda/src/gobj/shader.h +++ b/panda/src/gobj/shader.h @@ -52,7 +52,8 @@ PUBLISHED: enum ShaderLanguage { SL_none, SL_Cg, - SL_GLSL + SL_GLSL, + SL_HLSL, }; enum ShaderType { diff --git a/panda/src/gsgbase/graphicsStateGuardianBase.h b/panda/src/gsgbase/graphicsStateGuardianBase.h index 436c169ee0..8cbccf25a3 100644 --- a/panda/src/gsgbase/graphicsStateGuardianBase.h +++ b/panda/src/gsgbase/graphicsStateGuardianBase.h @@ -128,6 +128,8 @@ PUBLISHED: virtual bool get_supports_texture_srgb() const=0; + virtual bool get_supports_hlsl() const=0; + public: // These are some general interface functions; they're defined here // mainly to make it easy to call these from code in some directory diff --git a/panda/src/pgraphnodes/shaderGenerator.cxx b/panda/src/pgraphnodes/shaderGenerator.cxx index bb08db38a6..56527b0298 100644 --- a/panda/src/pgraphnodes/shaderGenerator.cxx +++ b/panda/src/pgraphnodes/shaderGenerator.cxx @@ -59,6 +59,15 @@ TypeHandle ShaderGenerator::_type_handle; ShaderGenerator:: ShaderGenerator(GraphicsStateGuardianBase *gsg, GraphicsOutputBase *host) : _gsg(gsg), _host(host) { + + // The ATTR# input semantics seem to map to generic vertex attributes + // in both arbvp1 and glslv, which behave more consistently. However, + // they don't exist in Direct3D 9. Use this silly little check for now. +#ifdef _WIN32 + _use_generic_attr = !gsg->get_supports_hlsl(); +#else + _use_generic_attr = false; +#endif } //////////////////////////////////////////////////////////////////// @@ -92,25 +101,42 @@ reset_register_allocator() { //////////////////////////////////////////////////////////////////// const char *ShaderGenerator:: alloc_vreg() { - // The ATTR# input sseem to map to generic vertex attributes in - // both arbvp1 and glslv, which behave more consistently. - switch (_vtregs_used) { - case 0: _vtregs_used += 1; return "ATTR8"; - case 1: _vtregs_used += 1; return "ATTR9"; - case 2: _vtregs_used += 1; return "ATTR10"; - case 3: _vtregs_used += 1; return "ATTR11"; - case 4: _vtregs_used += 1; return "ATTR12"; - case 5: _vtregs_used += 1; return "ATTR13"; - case 6: _vtregs_used += 1; return "ATTR14"; - case 7: _vtregs_used += 1; return "ATTR15"; - } - switch (_vcregs_used) { - case 0: _vcregs_used += 1; return "ATTR3"; - case 1: _vcregs_used += 1; return "ATTR4"; - case 2: _vcregs_used += 1; return "ATTR5"; - case 3: _vcregs_used += 1; return "ATTR6"; - case 4: _vcregs_used += 1; return "ATTR7"; - case 5: _vcregs_used += 1; return "ATTR1"; + if (_use_generic_attr) { + // OpenGL case. + switch (_vtregs_used) { + case 0: _vtregs_used += 1; return "ATTR8"; + case 1: _vtregs_used += 1; return "ATTR9"; + case 2: _vtregs_used += 1; return "ATTR10"; + case 3: _vtregs_used += 1; return "ATTR11"; + case 4: _vtregs_used += 1; return "ATTR12"; + case 5: _vtregs_used += 1; return "ATTR13"; + case 6: _vtregs_used += 1; return "ATTR14"; + case 7: _vtregs_used += 1; return "ATTR15"; + } + switch (_vcregs_used) { + case 0: _vcregs_used += 1; return "ATTR3"; + case 1: _vcregs_used += 1; return "ATTR4"; + case 2: _vcregs_used += 1; return "ATTR5"; + case 3: _vcregs_used += 1; return "ATTR6"; + case 4: _vcregs_used += 1; return "ATTR7"; + case 5: _vcregs_used += 1; return "ATTR1"; + } + } else { + // DirectX 9 case. + switch (_vtregs_used) { + case 0: _vtregs_used += 1; return "TEXCOORD0"; + case 1: _vtregs_used += 1; return "TEXCOORD1"; + case 2: _vtregs_used += 1; return "TEXCOORD2"; + case 3: _vtregs_used += 1; return "TEXCOORD3"; + case 4: _vtregs_used += 1; return "TEXCOORD4"; + case 5: _vtregs_used += 1; return "TEXCOORD5"; + case 6: _vtregs_used += 1; return "TEXCOORD6"; + case 7: _vtregs_used += 1; return "TEXCOORD7"; + } + switch (_vcregs_used) { + case 0: _vcregs_used += 1; return "COLOR0"; + case 1: _vcregs_used += 1; return "COLOR1"; + } } // These don't exist in arbvp1, though they're reportedly // supported by other profiles. @@ -656,8 +682,25 @@ synthesize_shader(const RenderState *rs, const GeomVertexAnimationSpec &anim) { const char *eye_normal_freg = 0; const char *hpos_freg = 0; + const char *position_vreg; + const char *transform_weight_vreg = 0; + const char *normal_vreg; + const char *color_vreg = 0; + const char *transform_index_vreg = 0; + + if (_use_generic_attr) { + position_vreg = "ATTR0"; + transform_weight_vreg = "ATTR1"; + normal_vreg = "ATTR2"; + transform_index_vreg = "ATTR7"; + } else { + position_vreg = "POSITION"; + normal_vreg = "NORMAL"; + } + if (_vertex_colors) { // Reserve COLOR0 + color_vreg = _use_generic_attr ? "ATTR3" : "COLOR0"; _vcregs_used = 1; _fcregs_used = 1; } @@ -714,7 +757,7 @@ synthesize_shader(const RenderState *rs, const GeomVertexAnimationSpec &anim) { } } if (_vertex_colors) { - text << "\t in float4 vtx_color : ATTR3,\n"; + text << "\t in float4 vtx_color : " << color_vreg << ",\n"; text << "\t out float4 l_color : COLOR0,\n"; } if (_need_world_position || _need_world_normal) { @@ -741,7 +784,7 @@ synthesize_shader(const RenderState *rs, const GeomVertexAnimationSpec &anim) { text << "\t out float4 l_eye_normal : " << eye_normal_freg << ",\n"; } if (_map_index_height >= 0 || _need_world_normal || _need_eye_normal) { - text << "\t in float3 vtx_normal : ATTR2,\n"; + text << "\t in float3 vtx_normal : " << normal_vreg << ",\n"; } if (_map_index_height >= 0) { text << "\t uniform float4 mspos_view,\n"; @@ -781,13 +824,19 @@ synthesize_shader(const RenderState *rs, const GeomVertexAnimationSpec &anim) { } else { num_transforms = anim.get_num_transforms(); } + if (transform_weight_vreg == NULL) { + transform_weight_vreg = alloc_vreg(); + } + if (transform_index_vreg == NULL) { + transform_index_vreg = alloc_vreg(); + } text << "\t uniform float4x4 tbl_transforms[" << num_transforms << "],\n"; - text << "\t in float4 vtx_transform_weight : ATTR1,\n"; + text << "\t in float4 vtx_transform_weight : " << transform_weight_vreg << ",\n"; if (anim.get_indexed_transforms()) { - text << "\t in uint4 vtx_transform_index : ATTR7,\n"; + text << "\t in uint4 vtx_transform_index : " << transform_index_vreg << ",\n"; } } - text << "\t in float4 vtx_position : ATTR0,\n"; + text << "\t in float4 vtx_position : " << position_vreg << ",\n"; text << "\t out float4 l_position : POSITION,\n"; text << "\t uniform float4x4 mat_modelproj\n"; text << ") {\n"; diff --git a/panda/src/pgraphnodes/shaderGenerator.h b/panda/src/pgraphnodes/shaderGenerator.h index 146f115d9a..f10115b970 100644 --- a/panda/src/pgraphnodes/shaderGenerator.h +++ b/panda/src/pgraphnodes/shaderGenerator.h @@ -86,6 +86,7 @@ protected: // Shader register allocation: + bool _use_generic_attr; int _vcregs_used; int _fcregs_used; int _vtregs_used;