mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-02 18:03:56 -04:00
Support hardware skinning in GLSL
This commit is contained in:
parent
269b4eac27
commit
419eadb859
@ -37,14 +37,14 @@ StandardMunger(GraphicsStateGuardianBase *gsg, const RenderState *state,
|
||||
StateMunger(gsg),
|
||||
_num_components(num_components),
|
||||
_numeric_type(numeric_type),
|
||||
_contents(contents)
|
||||
_contents(contents),
|
||||
_munge_color(false),
|
||||
_munge_color_scale(false),
|
||||
_auto_shader(false),
|
||||
_shader_skinning(false)
|
||||
{
|
||||
_render_mode = DCAST(RenderModeAttrib, state->get_attrib(RenderModeAttrib::get_class_slot()));
|
||||
|
||||
_munge_color = false;
|
||||
_munge_color_scale = false;
|
||||
_auto_shader = false;
|
||||
|
||||
if (!get_gsg()->get_runtime_color_scale()) {
|
||||
// We might need to munge the colors.
|
||||
const ColorAttrib *color_attrib = (const ColorAttrib *)
|
||||
@ -98,6 +98,9 @@ StandardMunger(GraphicsStateGuardianBase *gsg, const RenderState *state,
|
||||
if (shader_attrib->auto_shader()) {
|
||||
_auto_shader = true;
|
||||
}
|
||||
if (shader_attrib->get_flag(ShaderAttrib::F_hardware_skinning)) {
|
||||
_shader_skinning = true;
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
@ -128,9 +131,12 @@ munge_data_impl(const GeomVertexData *data) {
|
||||
}
|
||||
|
||||
GeomVertexAnimationSpec animation = new_data->get_format()->get_animation();
|
||||
if (hardware_animated_vertices &&
|
||||
animation.get_animation_type() == AT_panda &&
|
||||
new_data->get_slider_table() == (SliderTable *)NULL) {
|
||||
if (_shader_skinning) {
|
||||
animation.set_hardware(4, true);
|
||||
|
||||
} else if (hardware_animated_vertices &&
|
||||
animation.get_animation_type() == AT_panda &&
|
||||
new_data->get_slider_table() == (SliderTable *)NULL) {
|
||||
// Maybe we can animate the vertices with hardware.
|
||||
const TransformBlendTable *table = new_data->get_transform_blend_table();
|
||||
if (table != (TransformBlendTable *)NULL &&
|
||||
@ -161,7 +167,7 @@ munge_data_impl(const GeomVertexData *data) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
CPT(GeomVertexFormat) orig_format = new_data->get_format();
|
||||
CPT(GeomVertexFormat) new_format = munge_format(orig_format, animation);
|
||||
|
||||
@ -306,7 +312,9 @@ compare_to_impl(const GeomMunger *other) const {
|
||||
return compare;
|
||||
}
|
||||
}
|
||||
|
||||
if (_shader_skinning != om->_shader_skinning) {
|
||||
return (int)_shader_skinning - (int)om->_shader_skinning;
|
||||
}
|
||||
if (_auto_shader != om->_auto_shader) {
|
||||
return (int)_auto_shader - (int)om->_auto_shader;
|
||||
}
|
||||
@ -345,6 +353,9 @@ geom_compare_to_impl(const GeomMunger *other) const {
|
||||
return compare;
|
||||
}
|
||||
}
|
||||
if (_shader_skinning != om->_shader_skinning) {
|
||||
return (int)_shader_skinning - (int)om->_shader_skinning;
|
||||
}
|
||||
|
||||
return StateMunger::geom_compare_to_impl(other);
|
||||
}
|
||||
|
@ -60,6 +60,7 @@ private:
|
||||
bool _munge_color;
|
||||
bool _munge_color_scale;
|
||||
bool _auto_shader;
|
||||
bool _shader_skinning;
|
||||
|
||||
LColor _color;
|
||||
LVecBase4 _color_scale;
|
||||
|
@ -158,7 +158,7 @@ munge_format_impl(const GeomVertexFormat *orig,
|
||||
if (animation.get_num_transforms() > 1) {
|
||||
PT(GeomVertexArrayFormat) new_array_format = new GeomVertexArrayFormat;
|
||||
new_array_format->add_column
|
||||
(InternalName::get_transform_weight(), animation.get_num_transforms() - 1,
|
||||
(InternalName::get_transform_weight(), animation.get_num_transforms(),
|
||||
NT_stdfloat, C_other);
|
||||
|
||||
if (animation.get_indexed_transforms()) {
|
||||
|
@ -3275,11 +3275,11 @@ begin_draw_primitives(const GeomPipelineReader *geom_reader,
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef OPENGLES
|
||||
const GeomVertexAnimationSpec &animation =
|
||||
_data_reader->get_format()->get_animation();
|
||||
bool hardware_animation = (animation.get_animation_type() == Geom::AT_hardware);
|
||||
#ifndef OPENGLES
|
||||
if (hardware_animation) {
|
||||
if (hardware_animation && _current_shader_context == NULL) {
|
||||
// Set up the transform matrices for vertex blending.
|
||||
nassertr(_supports_vertex_blend, false);
|
||||
glEnable(GL_VERTEX_BLEND_ARB);
|
||||
@ -3361,6 +3361,8 @@ begin_draw_primitives(const GeomPipelineReader *geom_reader,
|
||||
GLPf(LoadMatrix)(_internal_transform->get_mat().get_data());
|
||||
}
|
||||
}
|
||||
#else
|
||||
const bool hardware_animation = false;
|
||||
#endif
|
||||
|
||||
#ifndef OPENGLES_2
|
||||
|
@ -211,6 +211,8 @@ CLP(ShaderContext)(CLP(GraphicsStateGuardian) *glgsg, Shader *s) : ShaderContext
|
||||
_uses_standard_vertex_arrays = false;
|
||||
_has_divisor = false;
|
||||
_color_attrib_index = -1;
|
||||
_transform_table_index = -1;
|
||||
_slider_table_index = -1;
|
||||
_validated = !gl_validate_shaders;
|
||||
|
||||
nassertv(s->get_language() == Shader::SL_GLSL);
|
||||
@ -883,6 +885,26 @@ reflect_uniform(int i, char *name_buffer, GLsizei name_buflen) {
|
||||
_shader->_mat_spec.push_back(bind);
|
||||
return;
|
||||
}
|
||||
if (noprefix == "TransformTable") {
|
||||
if (param_type != GL_FLOAT_MAT4) {
|
||||
GLCAT.error()
|
||||
<< "p3d_TransformTable should be uniform mat4\n";
|
||||
return;
|
||||
}
|
||||
_transform_table_index = p;
|
||||
_transform_table_size = param_size;
|
||||
return;
|
||||
}
|
||||
if (noprefix == "SliderTable") {
|
||||
if (param_type != GL_FLOAT) {
|
||||
GLCAT.error()
|
||||
<< "p3d_SliderTable should be uniform float\n";
|
||||
return;
|
||||
}
|
||||
_slider_table_index = p;
|
||||
_slider_table_size = param_size;
|
||||
return;
|
||||
}
|
||||
GLCAT.error() << "Unrecognized uniform name '" << param_name << "'!\n";
|
||||
return;
|
||||
|
||||
@ -1586,6 +1608,58 @@ issue_parameters(int altered) {
|
||||
_glgsg->report_my_gl_errors();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GLShaderContext::update_transform_table
|
||||
// Access: Public
|
||||
// Description: Changes the active transform table, used for hardware
|
||||
// skinning.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void CLP(ShaderContext)::
|
||||
update_transform_table(const TransformTable *table) {
|
||||
LMatrix4f *matrices = (LMatrix4f *)alloca(_transform_table_size * 64);
|
||||
|
||||
int i = 0;
|
||||
if (table != NULL) {
|
||||
int num_transforms = min(_transform_table_size, table->get_num_transforms());
|
||||
for (; i < num_transforms; ++i) {
|
||||
#ifdef STDFLOAT_DOUBLE
|
||||
LMatrix4 matrix;
|
||||
table->get_transform(i)->get_matrix(matrix);
|
||||
matrices[i] = LCAST(float, matrix);
|
||||
#else
|
||||
table->get_transform(i)->get_matrix(matrices[i]);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
for (; i < _transform_table_size; ++i) {
|
||||
matrices[i] = LMatrix4f::ident_mat();
|
||||
}
|
||||
|
||||
_glgsg->_glUniformMatrix4fv(_transform_table_index, _transform_table_size,
|
||||
GL_FALSE, (float *)matrices);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GLShaderContext::update_slider_table
|
||||
// Access: Public
|
||||
// Description: Changes the active slider table, used for hardware
|
||||
// skinning.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void CLP(ShaderContext)::
|
||||
update_slider_table(const SliderTable *table) {
|
||||
float *sliders = (float *)alloca(_slider_table_size * 4);
|
||||
memset(sliders, 0, _slider_table_size * 4);
|
||||
|
||||
if (table != NULL) {
|
||||
int num_sliders = min(_slider_table_size, table->get_num_sliders());
|
||||
for (int i = 0; i < num_sliders; ++i) {
|
||||
sliders[i] = table->get_slider(i)->get_slider();
|
||||
}
|
||||
}
|
||||
|
||||
_glgsg->_glUniform1fv(_slider_table_index, _slider_table_size, sliders);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GLShaderContext::disable_shader_vertex_arrays
|
||||
// Access: Public
|
||||
@ -1717,6 +1791,16 @@ update_shader_vertex_arrays(ShaderContext *prev, bool force) {
|
||||
}
|
||||
}
|
||||
|
||||
if (_transform_table_index >= 0) {
|
||||
const TransformTable *table = _glgsg->_data_reader->get_transform_table();
|
||||
update_transform_table(table);
|
||||
}
|
||||
|
||||
if (_slider_table_index >= 0) {
|
||||
const SliderTable *table = _glgsg->_data_reader->get_slider_table();
|
||||
update_slider_table(table);
|
||||
}
|
||||
|
||||
_glgsg->report_my_gl_errors();
|
||||
|
||||
return true;
|
||||
|
@ -48,6 +48,8 @@ public:
|
||||
void bind(bool reissue_parameters = true);
|
||||
void unbind();
|
||||
void issue_parameters(int altered);
|
||||
void update_transform_table(const TransformTable *table);
|
||||
void update_slider_table(const SliderTable *table);
|
||||
void disable_shader_vertex_arrays();
|
||||
bool update_shader_vertex_arrays(ShaderContext *prev, bool force);
|
||||
void disable_shader_texture_bindings();
|
||||
@ -74,6 +76,10 @@ private:
|
||||
//ParamContexts _params;
|
||||
|
||||
GLint _color_attrib_index;
|
||||
GLint _transform_table_index;
|
||||
GLint _slider_table_index;
|
||||
GLsizei _transform_table_size;
|
||||
GLsizei _slider_table_size;
|
||||
pmap<GLint, GLuint64> _glsl_uniform_handles;
|
||||
|
||||
struct ImageInput {
|
||||
|
@ -48,6 +48,7 @@ PUBLISHED:
|
||||
enum {
|
||||
F_disable_alpha_write = 0, // Suppress writes to color buffer alpha channel.
|
||||
F_subsume_alpha_test = 1, // Shader promises to subsume the alpha test using TEXKILL
|
||||
F_hardware_skinning = 2, // Shader needs pre-animated vertices
|
||||
};
|
||||
|
||||
INLINE bool has_shader() const;
|
||||
|
Loading…
x
Reference in New Issue
Block a user