mirror of
https://github.com/panda3d/panda3d.git
synced 2025-09-29 16:20:11 -04:00
ShaderGenerator: Fix support for hardware point sprites
In gp5fp and glslf profiles, we can rely on per-fragment point coordinates to be available, otherwise we have to emulate support by calculating it from the fragment pixel coordinates
This commit is contained in:
parent
6cb074e5c8
commit
4b992105e1
@ -3679,7 +3679,7 @@ ensure_generated_shader(const RenderState *state) {
|
|||||||
if (!_supports_basic_shaders) {
|
if (!_supports_basic_shaders) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
_shader_generator = new ShaderGenerator(this);
|
_shader_generator = new ShaderGenerator(_shader_caps, _supports_shadow_filter);
|
||||||
}
|
}
|
||||||
if (state->_generated_shader == nullptr ||
|
if (state->_generated_shader == nullptr ||
|
||||||
state->_generated_shader_seq != _generated_shader_seq) {
|
state->_generated_shader_seq != _generated_shader_seq) {
|
||||||
|
@ -73,13 +73,33 @@ pack_combine(TextureStage::CombineSource src0, TextureStage::CombineOperand op0,
|
|||||||
static PStatCollector lookup_collector("*:Munge:ShaderGen:Lookup");
|
static PStatCollector lookup_collector("*:Munge:ShaderGen:Lookup");
|
||||||
static PStatCollector synthesize_collector("*:Munge:ShaderGen:Synthesize");
|
static PStatCollector synthesize_collector("*:Munge:ShaderGen:Synthesize");
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a ShaderGenerator. This has no state, except possibly to cache
|
||||||
|
* certain results. The given parameters contain information about the
|
||||||
|
* capabilities of the target for which the shader will be compiled.
|
||||||
|
*/
|
||||||
|
ShaderGenerator::
|
||||||
|
ShaderGenerator(const Shader::ShaderCaps &caps, bool use_shadow_filter) :
|
||||||
|
_use_shadow_filter(use_shadow_filter) {
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
// Check matches all OpenGL profiles
|
||||||
|
_use_generic_attr = (caps._active_vprofile <= 6151 || caps._active_vprofile >= 7000);
|
||||||
|
#else
|
||||||
|
_use_generic_attr = true;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Matches gp5fp and glslf profiles
|
||||||
|
_use_pointcoord = (caps._active_fprofile == 7017 || caps._active_fprofile == 7008);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a ShaderGenerator. This has no state, except possibly to cache
|
* Create a ShaderGenerator. This has no state, except possibly to cache
|
||||||
* certain results. The parameter that must be passed is the GSG to which the
|
* certain results. The parameter that must be passed is the GSG to which the
|
||||||
* shader generator belongs.
|
* shader generator belongs.
|
||||||
*/
|
*/
|
||||||
ShaderGenerator::
|
ShaderGenerator::
|
||||||
ShaderGenerator(const GraphicsStateGuardianBase *gsg) {
|
ShaderGenerator(const GraphicsStateGuardianBase *gsg) : _use_pointcoord(false) {
|
||||||
// The ATTR# input semantics seem to map to generic vertex attributes in
|
// The ATTR# input semantics seem to map to generic vertex attributes in
|
||||||
// both arbvp1 and glslv, which behave more consistently. However, they
|
// both arbvp1 and glslv, which behave more consistently. However, they
|
||||||
// don't exist in Direct3D 9. Use this silly little check for now.
|
// don't exist in Direct3D 9. Use this silly little check for now.
|
||||||
@ -717,6 +737,7 @@ synthesize_shader(const RenderState *rs, const GeomVertexAnimationSpec &anim) {
|
|||||||
const char *eye_position_freg = nullptr;
|
const char *eye_position_freg = nullptr;
|
||||||
const char *eye_normal_freg = nullptr;
|
const char *eye_normal_freg = nullptr;
|
||||||
const char *hpos_freg = nullptr;
|
const char *hpos_freg = nullptr;
|
||||||
|
const char *pointcoord_freg = nullptr;
|
||||||
|
|
||||||
const char *position_vreg;
|
const char *position_vreg;
|
||||||
const char *transform_weight_vreg = nullptr;
|
const char *transform_weight_vreg = nullptr;
|
||||||
@ -762,6 +783,7 @@ synthesize_shader(const RenderState *rs, const GeomVertexAnimationSpec &anim) {
|
|||||||
bool need_eye_normal = !key._lights.empty() || ((key._outputs & AuxBitplaneAttrib::ABO_aux_normal) != 0);
|
bool need_eye_normal = !key._lights.empty() || ((key._outputs & AuxBitplaneAttrib::ABO_aux_normal) != 0);
|
||||||
bool need_tangents = ((key._texture_flags & ShaderKey::TF_map_normal) != 0);
|
bool need_tangents = ((key._texture_flags & ShaderKey::TF_map_normal) != 0);
|
||||||
bool need_point_size = (key._fog_mode & 0x10000) != 0;
|
bool need_point_size = (key._fog_mode & 0x10000) != 0;
|
||||||
|
bool need_point_coord = false;
|
||||||
|
|
||||||
// If we have binormal/tangent and eye position, we can pack eye normal in
|
// If we have binormal/tangent and eye position, we can pack eye normal in
|
||||||
// the w channels of the others.
|
// the w channels of the others.
|
||||||
@ -817,6 +839,9 @@ synthesize_shader(const RenderState *rs, const GeomVertexAnimationSpec &anim) {
|
|||||||
case TexGenAttrib::M_eye_position:
|
case TexGenAttrib::M_eye_position:
|
||||||
need_eye_position = true;
|
need_eye_position = true;
|
||||||
break;
|
break;
|
||||||
|
case TexGenAttrib::M_point_sprite:
|
||||||
|
need_point_coord = true;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -947,6 +972,13 @@ synthesize_shader(const RenderState *rs, const GeomVertexAnimationSpec &anim) {
|
|||||||
text << "\t uniform float3 attr_pointparams,\n";
|
text << "\t uniform float3 attr_pointparams,\n";
|
||||||
text << "\t out float l_point_size : PSIZE,\n";
|
text << "\t out float l_point_size : PSIZE,\n";
|
||||||
}
|
}
|
||||||
|
if (need_point_coord && !_use_pointcoord) {
|
||||||
|
if (!need_point_size) {
|
||||||
|
text << "\t uniform float3 attr_pointparams,\n";
|
||||||
|
}
|
||||||
|
pointcoord_freg = alloc_freg();
|
||||||
|
text << "\t out float3 l_pointcoord : " << pointcoord_freg << ",\n";
|
||||||
|
}
|
||||||
text << "\t in float4 vtx_position : " << position_vreg << ",\n";
|
text << "\t in float4 vtx_position : " << position_vreg << ",\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";
|
||||||
@ -996,6 +1028,14 @@ synthesize_shader(const RenderState *rs, const GeomVertexAnimationSpec &anim) {
|
|||||||
if (need_point_size) {
|
if (need_point_size) {
|
||||||
text << "\t l_point_size = attr_pointparams.y + attr_pointparams.z / length(l_eye_position.xyz);\n";
|
text << "\t l_point_size = attr_pointparams.y + attr_pointparams.z / length(l_eye_position.xyz);\n";
|
||||||
}
|
}
|
||||||
|
if (need_point_coord && !_use_pointcoord) {
|
||||||
|
if (need_point_size) {
|
||||||
|
text << "\t l_pointcoord = float3(l_position.xy / (2.0f * l_position.w) + float2(0.5f, 0.5f), 1.0f / l_point_size);\n";
|
||||||
|
} else {
|
||||||
|
// Static point size (non-perspective points)
|
||||||
|
text << "\t l_pointcoord = float3(l_position.xy / (2.0f * l_position.w) + float2(0.5f, 0.5f), 1.0f / attr_pointparams.x);\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pmap<const InternalName *, const char *>::const_iterator it;
|
pmap<const InternalName *, const char *>::const_iterator it;
|
||||||
for (it = texcoord_fregs.begin(); it != texcoord_fregs.end(); ++it) {
|
for (it = texcoord_fregs.begin(); it != texcoord_fregs.end(); ++it) {
|
||||||
@ -1047,6 +1087,17 @@ synthesize_shader(const RenderState *rs, const GeomVertexAnimationSpec &anim) {
|
|||||||
text << "\t in uniform float4 attr_fog,\n";
|
text << "\t in uniform float4 attr_fog,\n";
|
||||||
text << "\t in uniform float4 attr_fogcolor,\n";
|
text << "\t in uniform float4 attr_fogcolor,\n";
|
||||||
}
|
}
|
||||||
|
if (need_point_coord) {
|
||||||
|
if (_use_pointcoord) {
|
||||||
|
// In OpenGL, we have point coordinates available in glslf and gp5fp.
|
||||||
|
text << "\t in float2 l_pointcoord : POINTCOORD,\n";
|
||||||
|
} else {
|
||||||
|
// In DirectX 9, we need to calculate them from the fragment coordinates.
|
||||||
|
text << "\t in float3 l_pointcoord : " << pointcoord_freg << ",\n";
|
||||||
|
text << "\t in float2 l_fragcoord : WPOS,\n";
|
||||||
|
text << "\t in uniform float2 sys_windowsize,\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
if (need_world_position) {
|
if (need_world_position) {
|
||||||
text << "\t in float4 l_world_position : " << world_position_freg << ",\n";
|
text << "\t in float4 l_world_position : " << world_position_freg << ",\n";
|
||||||
}
|
}
|
||||||
@ -1207,6 +1258,16 @@ synthesize_shader(const RenderState *rs, const GeomVertexAnimationSpec &anim) {
|
|||||||
case TexGenAttrib::M_eye_position:
|
case TexGenAttrib::M_eye_position:
|
||||||
text << "\t float4 texcoord" << i << " = float4(l_eye_position.xyz, 1.0f);\n";
|
text << "\t float4 texcoord" << i << " = float4(l_eye_position.xyz, 1.0f);\n";
|
||||||
break;
|
break;
|
||||||
|
case TexGenAttrib::M_point_sprite:
|
||||||
|
if (_use_pointcoord) {
|
||||||
|
text << "\t float4 texcoord" << i << " = float4(l_pointcoord, 0.0f, 1.0f);\n";
|
||||||
|
} else {
|
||||||
|
if (!_use_generic_attr) {
|
||||||
|
text << "\t l_fragcoord.y = sys_windowsize.y - l_fragcoord.y;\n";
|
||||||
|
}
|
||||||
|
text << "\t float4 texcoord" << i << " = float4((l_fragcoord - l_pointcoord.xy * sys_windowsize) * l_pointcoord.z * float2(1.0f, -1.0f) - float2(0.5f, 0.5f), 0.0f, 1.0f);\n";
|
||||||
|
}
|
||||||
|
break;
|
||||||
case TexGenAttrib::M_constant:
|
case TexGenAttrib::M_constant:
|
||||||
text << "\t float4 texcoord" << i << " = texconst_" << i << ";\n";
|
text << "\t float4 texcoord" << i << " = texconst_" << i << ";\n";
|
||||||
break;
|
break;
|
||||||
|
@ -64,6 +64,9 @@ class GeomVertexAnimationSpec;
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
class EXPCL_PANDA_PGRAPHNODES ShaderGenerator : public TypedReferenceCount {
|
class EXPCL_PANDA_PGRAPHNODES ShaderGenerator : public TypedReferenceCount {
|
||||||
|
public:
|
||||||
|
ShaderGenerator(const Shader::ShaderCaps &caps, bool use_shadow_filter);
|
||||||
|
|
||||||
PUBLISHED:
|
PUBLISHED:
|
||||||
ShaderGenerator(const GraphicsStateGuardianBase *gsg);
|
ShaderGenerator(const GraphicsStateGuardianBase *gsg);
|
||||||
virtual ~ShaderGenerator();
|
virtual ~ShaderGenerator();
|
||||||
@ -76,7 +79,8 @@ PUBLISHED:
|
|||||||
protected:
|
protected:
|
||||||
// Shader register allocation:
|
// Shader register allocation:
|
||||||
|
|
||||||
bool _use_generic_attr;
|
bool _use_generic_attr : 1;
|
||||||
|
bool _use_pointcoord : 1;
|
||||||
int _vcregs_used;
|
int _vcregs_used;
|
||||||
int _fcregs_used;
|
int _fcregs_used;
|
||||||
int _vtregs_used;
|
int _vtregs_used;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user