Skeletons are working now.
This commit is contained in:
parent
a2505542ff
commit
70d095d8f2
|
@ -124,6 +124,7 @@ void RasterizerGLES3::begin_frame(){
|
||||||
storage->frame.time[3]=Math::fmod(time_total,60);
|
storage->frame.time[3]=Math::fmod(time_total,60);
|
||||||
storage->frame.count++;
|
storage->frame.count++;
|
||||||
|
|
||||||
|
storage->update_dirty_skeletons();
|
||||||
storage->update_dirty_shaders();
|
storage->update_dirty_shaders();
|
||||||
storage->update_dirty_materials();
|
storage->update_dirty_materials();
|
||||||
scene->iteration();
|
scene->iteration();
|
||||||
|
|
|
@ -1329,6 +1329,7 @@ void RasterizerSceneGLES3::_render_list(RenderList::Element **p_elements,int p_e
|
||||||
int current_blend_mode=-1;
|
int current_blend_mode=-1;
|
||||||
|
|
||||||
int prev_shading=-1;
|
int prev_shading=-1;
|
||||||
|
RID prev_skeleton;
|
||||||
|
|
||||||
state.scene_shader.set_conditional(SceneShaderGLES3::SHADELESS,true); //by default unshaded (easier to set)
|
state.scene_shader.set_conditional(SceneShaderGLES3::SHADELESS,true); //by default unshaded (easier to set)
|
||||||
|
|
||||||
|
@ -1338,6 +1339,7 @@ void RasterizerSceneGLES3::_render_list(RenderList::Element **p_elements,int p_e
|
||||||
|
|
||||||
RenderList::Element *e = p_elements[i];
|
RenderList::Element *e = p_elements[i];
|
||||||
RasterizerStorageGLES3::Material* material= e->material;
|
RasterizerStorageGLES3::Material* material= e->material;
|
||||||
|
RID skeleton = e->instance->skeleton;
|
||||||
|
|
||||||
bool rebind=first;
|
bool rebind=first;
|
||||||
|
|
||||||
|
@ -1466,6 +1468,18 @@ void RasterizerSceneGLES3::_render_list(RenderList::Element **p_elements,int p_e
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (prev_skeleton!=skeleton) {
|
||||||
|
if (prev_skeleton.is_valid() != skeleton.is_valid()) {
|
||||||
|
state.scene_shader.set_conditional(SceneShaderGLES3::USE_SKELETON,skeleton.is_valid());
|
||||||
|
rebind=true;
|
||||||
|
}
|
||||||
|
if (skeleton.is_valid()) {
|
||||||
|
RasterizerStorageGLES3::Skeleton *sk = storage->skeleton_owner.getornull(skeleton);
|
||||||
|
if (sk->size) {
|
||||||
|
glBindBufferBase(GL_UNIFORM_BUFFER,7,sk->ubo);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (material!=prev_material || rebind) {
|
if (material!=prev_material || rebind) {
|
||||||
|
|
||||||
|
@ -1495,6 +1509,7 @@ void RasterizerSceneGLES3::_render_list(RenderList::Element **p_elements,int p_e
|
||||||
prev_base_type=e->instance->base_type;
|
prev_base_type=e->instance->base_type;
|
||||||
prev_geometry=e->geometry;
|
prev_geometry=e->geometry;
|
||||||
prev_shading=shading;
|
prev_shading=shading;
|
||||||
|
prev_skeleton=skeleton;
|
||||||
first=false;
|
first=false;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1504,6 +1519,7 @@ void RasterizerSceneGLES3::_render_list(RenderList::Element **p_elements,int p_e
|
||||||
glFrontFace(GL_CW);
|
glFrontFace(GL_CW);
|
||||||
glBindVertexArray(0);
|
glBindVertexArray(0);
|
||||||
|
|
||||||
|
state.scene_shader.set_conditional(SceneShaderGLES3::USE_SKELETON,false);
|
||||||
state.scene_shader.set_conditional(SceneShaderGLES3::USE_RADIANCE_MAP,false);
|
state.scene_shader.set_conditional(SceneShaderGLES3::USE_RADIANCE_MAP,false);
|
||||||
state.scene_shader.set_conditional(SceneShaderGLES3::USE_FORWARD_LIGHTING,false);
|
state.scene_shader.set_conditional(SceneShaderGLES3::USE_FORWARD_LIGHTING,false);
|
||||||
state.scene_shader.set_conditional(SceneShaderGLES3::USE_LIGHT_DIRECTIONAL,false);
|
state.scene_shader.set_conditional(SceneShaderGLES3::USE_LIGHT_DIRECTIONAL,false);
|
||||||
|
@ -3469,6 +3485,10 @@ void RasterizerSceneGLES3::initialize() {
|
||||||
|
|
||||||
state.scene_shader.add_custom_define("#define MAX_REFLECTION_DATA_STRUCTS "+itos(state.max_ubo_reflections)+"\n");
|
state.scene_shader.add_custom_define("#define MAX_REFLECTION_DATA_STRUCTS "+itos(state.max_ubo_reflections)+"\n");
|
||||||
|
|
||||||
|
state.max_skeleton_bones=max_ubo_size/(12*sizeof(float));
|
||||||
|
state.scene_shader.add_custom_define("#define MAX_SKELETON_BONES "+itos(state.max_skeleton_bones)+"\n");
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
GLOBAL_DEF("rendering/gles3/shadow_filter_mode",1);
|
GLOBAL_DEF("rendering/gles3/shadow_filter_mode",1);
|
||||||
|
|
|
@ -98,6 +98,7 @@ public:
|
||||||
int max_ubo_lights;
|
int max_ubo_lights;
|
||||||
int max_forward_lights_per_object;
|
int max_forward_lights_per_object;
|
||||||
int max_ubo_reflections;
|
int max_ubo_reflections;
|
||||||
|
int max_skeleton_bones;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -2416,12 +2416,15 @@ void RasterizerStorageGLES3::mesh_add_surface(RID p_mesh,uint32_t p_format,VS::P
|
||||||
if (! (p_format&(1<<i) ) ) {
|
if (! (p_format&(1<<i) ) ) {
|
||||||
attribs[i].enabled=false;
|
attribs[i].enabled=false;
|
||||||
morph_attribs[i].enabled=false;
|
morph_attribs[i].enabled=false;
|
||||||
|
attribs[i].integer=false;
|
||||||
|
morph_attribs[i].integer=false;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
attribs[i].enabled=true;
|
attribs[i].enabled=true;
|
||||||
attribs[i].offset=stride;
|
attribs[i].offset=stride;
|
||||||
attribs[i].index=i;
|
attribs[i].index=i;
|
||||||
|
attribs[i].integer=false;
|
||||||
|
|
||||||
if (has_morph) {
|
if (has_morph) {
|
||||||
morph_attribs[i].enabled=true;
|
morph_attribs[i].enabled=true;
|
||||||
|
@ -2573,21 +2576,16 @@ void RasterizerStorageGLES3::mesh_add_surface(RID p_mesh,uint32_t p_format,VS::P
|
||||||
|
|
||||||
attribs[i].size=4;
|
attribs[i].size=4;
|
||||||
|
|
||||||
if (p_format&VS::ARRAY_COMPRESS_BONES) {
|
if (p_format&VS::ARRAY_FLAG_USE_16_BIT_BONES) {
|
||||||
|
|
||||||
if (p_format&VS::ARRAY_FLAG_USE_16_BIT_BONES) {
|
|
||||||
attribs[i].type=GL_UNSIGNED_SHORT;
|
|
||||||
stride+=8;
|
|
||||||
} else {
|
|
||||||
attribs[i].type=GL_UNSIGNED_BYTE;
|
|
||||||
stride+=4;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
attribs[i].type=GL_UNSIGNED_SHORT;
|
attribs[i].type=GL_UNSIGNED_SHORT;
|
||||||
stride+=8;
|
stride+=8;
|
||||||
|
} else {
|
||||||
|
attribs[i].type=GL_UNSIGNED_BYTE;
|
||||||
|
stride+=4;
|
||||||
}
|
}
|
||||||
|
|
||||||
attribs[i].normalized=GL_FALSE;
|
attribs[i].normalized=GL_FALSE;
|
||||||
|
attribs[i].integer=true;
|
||||||
|
|
||||||
if (has_morph) {
|
if (has_morph) {
|
||||||
morph_attribs[i].normalized=GL_FALSE;
|
morph_attribs[i].normalized=GL_FALSE;
|
||||||
|
@ -2727,7 +2725,11 @@ void RasterizerStorageGLES3::mesh_add_surface(RID p_mesh,uint32_t p_format,VS::P
|
||||||
if (!attribs[i].enabled)
|
if (!attribs[i].enabled)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
glVertexAttribPointer(attribs[i].index,attribs[i].size,attribs[i].type,attribs[i].normalized,attribs[i].stride,((uint8_t*)0)+attribs[i].offset);
|
if (attribs[i].integer) {
|
||||||
|
glVertexAttribIPointer(attribs[i].index,attribs[i].size,attribs[i].type,attribs[i].stride,((uint8_t*)0)+attribs[i].offset);
|
||||||
|
} else {
|
||||||
|
glVertexAttribPointer(attribs[i].index,attribs[i].size,attribs[i].type,attribs[i].normalized,attribs[i].stride,((uint8_t*)0)+attribs[i].offset);
|
||||||
|
}
|
||||||
glEnableVertexAttribArray(attribs[i].index);
|
glEnableVertexAttribArray(attribs[i].index);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -2765,7 +2767,11 @@ void RasterizerStorageGLES3::mesh_add_surface(RID p_mesh,uint32_t p_format,VS::P
|
||||||
if (!attribs[i].enabled)
|
if (!attribs[i].enabled)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
glVertexAttribPointer(attribs[i].index,attribs[i].size,attribs[i].type,attribs[i].normalized,attribs[i].stride,((uint8_t*)0)+attribs[i].offset);
|
if (attribs[i].integer) {
|
||||||
|
glVertexAttribIPointer(attribs[i].index,attribs[i].size,attribs[i].type,attribs[i].stride,((uint8_t*)0)+attribs[i].offset);
|
||||||
|
} else {
|
||||||
|
glVertexAttribPointer(attribs[i].index,attribs[i].size,attribs[i].type,attribs[i].normalized,attribs[i].stride,((uint8_t*)0)+attribs[i].offset);
|
||||||
|
}
|
||||||
glEnableVertexAttribArray(attribs[i].index);
|
glEnableVertexAttribArray(attribs[i].index);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -3270,31 +3276,196 @@ RID RasterizerStorageGLES3::immediate_get_material(RID p_immediate) const{
|
||||||
|
|
||||||
RID RasterizerStorageGLES3::skeleton_create(){
|
RID RasterizerStorageGLES3::skeleton_create(){
|
||||||
|
|
||||||
return RID();
|
Skeleton *skeleton = memnew( Skeleton );
|
||||||
|
return skeleton_owner.make_rid(skeleton);
|
||||||
}
|
}
|
||||||
|
|
||||||
void RasterizerStorageGLES3::skeleton_allocate(RID p_skeleton,int p_bones,bool p_2d_skeleton){
|
void RasterizerStorageGLES3::skeleton_allocate(RID p_skeleton,int p_bones,bool p_2d_skeleton){
|
||||||
|
|
||||||
|
Skeleton *skeleton = skeleton_owner.getornull(p_skeleton);
|
||||||
|
ERR_FAIL_COND(!skeleton);
|
||||||
|
ERR_FAIL_COND(p_bones<0);
|
||||||
|
|
||||||
|
if (skeleton->size==p_bones && skeleton->use_2d==p_2d_skeleton)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (skeleton->ubo) {
|
||||||
|
glDeleteBuffers(1,&skeleton->ubo);
|
||||||
|
skeleton->ubo=0;
|
||||||
|
}
|
||||||
|
|
||||||
|
skeleton->size=p_bones;
|
||||||
|
if (p_2d_skeleton) {
|
||||||
|
skeleton->bones.resize(p_bones*8);
|
||||||
|
for(int i=0;i<skeleton->bones.size();i+=8) {
|
||||||
|
skeleton->bones[i+0]=1;
|
||||||
|
skeleton->bones[i+1]=0;
|
||||||
|
skeleton->bones[i+2]=0;
|
||||||
|
skeleton->bones[i+3]=0;
|
||||||
|
skeleton->bones[i+4]=0;
|
||||||
|
skeleton->bones[i+5]=1;
|
||||||
|
skeleton->bones[i+6]=0;
|
||||||
|
skeleton->bones[i+7]=0;
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
skeleton->bones.resize(p_bones*12);
|
||||||
|
for(int i=0;i<skeleton->bones.size();i+=12) {
|
||||||
|
skeleton->bones[i+0]=1;
|
||||||
|
skeleton->bones[i+1]=0;
|
||||||
|
skeleton->bones[i+2]=0;
|
||||||
|
skeleton->bones[i+3]=0;
|
||||||
|
skeleton->bones[i+4]=0;
|
||||||
|
skeleton->bones[i+5]=1;
|
||||||
|
skeleton->bones[i+6]=0;
|
||||||
|
skeleton->bones[i+7]=0;
|
||||||
|
skeleton->bones[i+8]=0;
|
||||||
|
skeleton->bones[i+9]=0;
|
||||||
|
skeleton->bones[i+10]=1;
|
||||||
|
skeleton->bones[i+11]=0;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
if (p_bones) {
|
||||||
|
glGenBuffers(1, &skeleton->ubo);
|
||||||
|
glBindBuffer(GL_UNIFORM_BUFFER, skeleton->ubo);
|
||||||
|
glBufferData(GL_UNIFORM_BUFFER, skeleton->bones.size()*sizeof(float), NULL, GL_DYNAMIC_DRAW);
|
||||||
|
glBindBuffer(GL_UNIFORM_BUFFER, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!skeleton->update_list.in_list()) {
|
||||||
|
skeleton_update_list.add(&skeleton->update_list);
|
||||||
|
}
|
||||||
|
|
||||||
|
skeleton->instance_change_notify();
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
int RasterizerStorageGLES3::skeleton_get_bone_count(RID p_skeleton) const{
|
int RasterizerStorageGLES3::skeleton_get_bone_count(RID p_skeleton) const{
|
||||||
|
|
||||||
return 0;
|
Skeleton *skeleton = skeleton_owner.getornull(p_skeleton);
|
||||||
|
ERR_FAIL_COND_V(!skeleton,0);
|
||||||
|
|
||||||
|
return skeleton->size;
|
||||||
}
|
}
|
||||||
|
|
||||||
void RasterizerStorageGLES3::skeleton_bone_set_transform(RID p_skeleton,int p_bone, const Transform& p_transform){
|
void RasterizerStorageGLES3::skeleton_bone_set_transform(RID p_skeleton,int p_bone, const Transform& p_transform){
|
||||||
|
|
||||||
|
Skeleton *skeleton = skeleton_owner.getornull(p_skeleton);
|
||||||
|
|
||||||
|
ERR_FAIL_COND(!skeleton);
|
||||||
|
ERR_FAIL_INDEX(p_bone,skeleton->size);
|
||||||
|
ERR_FAIL_COND(skeleton->use_2d);
|
||||||
|
|
||||||
|
float * bones = skeleton->bones.ptr();
|
||||||
|
bones[p_bone*12+ 0]=p_transform.basis.elements[0][0];
|
||||||
|
bones[p_bone*12+ 1]=p_transform.basis.elements[0][1];
|
||||||
|
bones[p_bone*12+ 2]=p_transform.basis.elements[0][2];
|
||||||
|
bones[p_bone*12+ 3]=p_transform.origin.x;
|
||||||
|
bones[p_bone*12+ 4]=p_transform.basis.elements[1][0];
|
||||||
|
bones[p_bone*12+ 5]=p_transform.basis.elements[1][1];
|
||||||
|
bones[p_bone*12+ 6]=p_transform.basis.elements[1][2];
|
||||||
|
bones[p_bone*12+ 7]=p_transform.origin.y;
|
||||||
|
bones[p_bone*12+ 8]=p_transform.basis.elements[2][0];
|
||||||
|
bones[p_bone*12+ 9]=p_transform.basis.elements[2][1];
|
||||||
|
bones[p_bone*12+10]=p_transform.basis.elements[2][2];
|
||||||
|
bones[p_bone*12+11]=p_transform.origin.z;
|
||||||
|
|
||||||
|
if (!skeleton->update_list.in_list()) {
|
||||||
|
skeleton_update_list.add(&skeleton->update_list);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Transform RasterizerStorageGLES3::skeleton_bone_get_transform(RID p_skeleton,int p_bone) const{
|
Transform RasterizerStorageGLES3::skeleton_bone_get_transform(RID p_skeleton,int p_bone) const{
|
||||||
|
|
||||||
return Transform();
|
Skeleton *skeleton = skeleton_owner.getornull(p_skeleton);
|
||||||
|
|
||||||
|
ERR_FAIL_COND_V(!skeleton,Transform());
|
||||||
|
ERR_FAIL_INDEX_V(p_bone,skeleton->size,Transform());
|
||||||
|
ERR_FAIL_COND_V(skeleton->use_2d,Transform());
|
||||||
|
|
||||||
|
float * bones = skeleton->bones.ptr();
|
||||||
|
Transform mtx;
|
||||||
|
mtx.basis.elements[0][0]=bones[p_bone*12+ 0];
|
||||||
|
mtx.basis.elements[0][1]=bones[p_bone*12+ 1];
|
||||||
|
mtx.basis.elements[0][2]=bones[p_bone*12+ 2];
|
||||||
|
mtx.origin.x=bones[p_bone*12+ 3];
|
||||||
|
mtx.basis.elements[1][0]=bones[p_bone*12+ 4];
|
||||||
|
mtx.basis.elements[1][1]=bones[p_bone*12+ 5];
|
||||||
|
mtx.basis.elements[1][2]=bones[p_bone*12+ 6];
|
||||||
|
mtx.origin.y=bones[p_bone*12+ 7];
|
||||||
|
mtx.basis.elements[2][0]=bones[p_bone*12+ 8];
|
||||||
|
mtx.basis.elements[2][1]=bones[p_bone*12+ 9];
|
||||||
|
mtx.basis.elements[2][2]=bones[p_bone*12+10];
|
||||||
|
mtx.origin.z=bones[p_bone*12+11];
|
||||||
|
|
||||||
|
return mtx;
|
||||||
}
|
}
|
||||||
void RasterizerStorageGLES3::skeleton_bone_set_transform_2d(RID p_skeleton,int p_bone, const Matrix32& p_transform){
|
void RasterizerStorageGLES3::skeleton_bone_set_transform_2d(RID p_skeleton,int p_bone, const Matrix32& p_transform){
|
||||||
|
|
||||||
|
Skeleton *skeleton = skeleton_owner.getornull(p_skeleton);
|
||||||
|
|
||||||
|
ERR_FAIL_COND(!skeleton);
|
||||||
|
ERR_FAIL_INDEX(p_bone,skeleton->size);
|
||||||
|
ERR_FAIL_COND(!skeleton->use_2d);
|
||||||
|
|
||||||
|
float * bones = skeleton->bones.ptr();
|
||||||
|
bones[p_bone*12+ 0]=p_transform.elements[0][0];
|
||||||
|
bones[p_bone*12+ 1]=p_transform.elements[1][0];
|
||||||
|
bones[p_bone*12+ 2]=0;
|
||||||
|
bones[p_bone*12+ 3]=p_transform.elements[2][0];
|
||||||
|
bones[p_bone*12+ 4]=p_transform.elements[0][1];
|
||||||
|
bones[p_bone*12+ 5]=p_transform.elements[1][1];
|
||||||
|
bones[p_bone*12+ 6]=0;
|
||||||
|
bones[p_bone*12+ 7]=p_transform.elements[2][1];
|
||||||
|
|
||||||
|
if (!skeleton->update_list.in_list()) {
|
||||||
|
skeleton_update_list.add(&skeleton->update_list);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
Matrix32 RasterizerStorageGLES3::skeleton_bone_get_transform_2d(RID p_skeleton,int p_bone) const{
|
Matrix32 RasterizerStorageGLES3::skeleton_bone_get_transform_2d(RID p_skeleton,int p_bone) const{
|
||||||
|
|
||||||
return Matrix32();
|
Skeleton *skeleton = skeleton_owner.getornull(p_skeleton);
|
||||||
|
|
||||||
|
|
||||||
|
ERR_FAIL_COND_V(!skeleton,Matrix32());
|
||||||
|
ERR_FAIL_INDEX_V(p_bone,skeleton->size,Matrix32());
|
||||||
|
ERR_FAIL_COND_V(!skeleton->use_2d,Matrix32());
|
||||||
|
|
||||||
|
Matrix32 mtx;
|
||||||
|
|
||||||
|
float * bones = skeleton->bones.ptr();
|
||||||
|
mtx.elements[0][0]=bones[p_bone*12+ 0];
|
||||||
|
mtx.elements[1][0]=bones[p_bone*12+ 1];
|
||||||
|
mtx.elements[2][0]=bones[p_bone*12+ 3];
|
||||||
|
mtx.elements[0][1]=bones[p_bone*12+ 4];
|
||||||
|
mtx.elements[1][1]=bones[p_bone*12+ 5];
|
||||||
|
mtx.elements[2][1]=bones[p_bone*12+ 7];
|
||||||
|
|
||||||
|
return mtx;
|
||||||
|
}
|
||||||
|
|
||||||
|
void RasterizerStorageGLES3::update_dirty_skeletons() {
|
||||||
|
|
||||||
|
while(skeleton_update_list.first()) {
|
||||||
|
|
||||||
|
Skeleton *skeleton = skeleton_update_list.first()->self();
|
||||||
|
if (skeleton->size) {
|
||||||
|
glBindBuffer(GL_UNIFORM_BUFFER, skeleton->ubo);
|
||||||
|
glBufferSubData(GL_UNIFORM_BUFFER,0,skeleton->bones.size()*sizeof(float),skeleton->bones.ptr());
|
||||||
|
glBindBuffer(GL_UNIFORM_BUFFER, 0);
|
||||||
|
}
|
||||||
|
skeleton->instance_change_notify();
|
||||||
|
|
||||||
|
skeleton_update_list.remove(skeleton_update_list.first());
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Light API */
|
/* Light API */
|
||||||
|
@ -3795,7 +3966,12 @@ void RasterizerStorageGLES3::instance_add_dependency(RID p_base,RasterizerScene:
|
||||||
ERR_FAIL_COND(!inst);
|
ERR_FAIL_COND(!inst);
|
||||||
} break;
|
} break;
|
||||||
default: {
|
default: {
|
||||||
ERR_FAIL();
|
if (skeleton_owner.owns(p_base)) {
|
||||||
|
inst=skeleton_owner.getornull(p_base);
|
||||||
|
}
|
||||||
|
if (!inst) {
|
||||||
|
ERR_FAIL();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3821,7 +3997,12 @@ void RasterizerStorageGLES3::instance_remove_dependency(RID p_base,RasterizerSce
|
||||||
ERR_FAIL_COND(!inst);
|
ERR_FAIL_COND(!inst);
|
||||||
} break;
|
} break;
|
||||||
default: {
|
default: {
|
||||||
ERR_FAIL();
|
if (skeleton_owner.owns(p_base)) {
|
||||||
|
inst=skeleton_owner.getornull(p_base);
|
||||||
|
}
|
||||||
|
if (!inst) {
|
||||||
|
ERR_FAIL();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4378,6 +4559,17 @@ bool RasterizerStorageGLES3::free(RID p_rid){
|
||||||
material_owner.free(p_rid);
|
material_owner.free(p_rid);
|
||||||
memdelete(material);
|
memdelete(material);
|
||||||
|
|
||||||
|
} else if (skeleton_owner.owns(p_rid)) {
|
||||||
|
|
||||||
|
// delete the texture
|
||||||
|
Skeleton *skeleton = skeleton_owner.get(p_rid);
|
||||||
|
if (skeleton->update_list.in_list()) {
|
||||||
|
skeleton_update_list.remove(&skeleton->update_list);
|
||||||
|
}
|
||||||
|
skeleton_allocate(p_rid,0,false);
|
||||||
|
skeleton_owner.free(p_rid);
|
||||||
|
memdelete(skeleton);
|
||||||
|
|
||||||
} else if (mesh_owner.owns(p_rid)) {
|
} else if (mesh_owner.owns(p_rid)) {
|
||||||
|
|
||||||
// delete the texture
|
// delete the texture
|
||||||
|
|
|
@ -465,6 +465,7 @@ public:
|
||||||
struct Attrib {
|
struct Attrib {
|
||||||
|
|
||||||
bool enabled;
|
bool enabled;
|
||||||
|
bool integer;
|
||||||
GLuint index;
|
GLuint index;
|
||||||
GLint size;
|
GLint size;
|
||||||
GLenum type;
|
GLenum type;
|
||||||
|
@ -632,6 +633,26 @@ public:
|
||||||
|
|
||||||
/* SKELETON API */
|
/* SKELETON API */
|
||||||
|
|
||||||
|
struct Skeleton : Instantiable {
|
||||||
|
int size;
|
||||||
|
bool use_2d;
|
||||||
|
Vector<float> bones; //4x3 or 4x2 depending on what is needed
|
||||||
|
GLuint ubo;
|
||||||
|
SelfList<Skeleton> update_list;
|
||||||
|
|
||||||
|
Skeleton() : update_list(this) {
|
||||||
|
size=0;
|
||||||
|
use_2d=false;
|
||||||
|
ubo=0;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
mutable RID_Owner<Skeleton> skeleton_owner;
|
||||||
|
|
||||||
|
SelfList<Skeleton>::List skeleton_update_list;
|
||||||
|
|
||||||
|
void update_dirty_skeletons();
|
||||||
|
|
||||||
virtual RID skeleton_create();
|
virtual RID skeleton_create();
|
||||||
virtual void skeleton_allocate(RID p_skeleton,int p_bones,bool p_2d_skeleton=false);
|
virtual void skeleton_allocate(RID p_skeleton,int p_bones,bool p_2d_skeleton=false);
|
||||||
virtual int skeleton_get_bone_count(RID p_skeleton) const;
|
virtual int skeleton_get_bone_count(RID p_skeleton) const;
|
||||||
|
|
|
@ -22,17 +22,27 @@ ARRAY_INDEX=8,
|
||||||
|
|
||||||
layout(location=0) in highp vec4 vertex_attrib;
|
layout(location=0) in highp vec4 vertex_attrib;
|
||||||
layout(location=1) in vec3 normal_attrib;
|
layout(location=1) in vec3 normal_attrib;
|
||||||
|
#if defined(ENABLE_TANGENT_INTERP) || defined(ENABLE_NORMALMAP) || defined(LIGHT_USE_ANISOTROPY)
|
||||||
layout(location=2) in vec4 tangent_attrib;
|
layout(location=2) in vec4 tangent_attrib;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(ENABLE_COLOR_INTERP)
|
||||||
layout(location=3) in vec4 color_attrib;
|
layout(location=3) in vec4 color_attrib;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(ENABLE_UV_INTERP)
|
||||||
layout(location=4) in vec2 uv_attrib;
|
layout(location=4) in vec2 uv_attrib;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(ENABLE_UV2_INTERP)
|
||||||
layout(location=5) in vec2 uv2_attrib;
|
layout(location=5) in vec2 uv2_attrib;
|
||||||
|
#endif
|
||||||
|
|
||||||
uniform float normal_mult;
|
uniform float normal_mult;
|
||||||
|
|
||||||
#ifdef USE_SKELETON
|
#ifdef USE_SKELETON
|
||||||
layout(location=6) mediump ivec4 bone_indices; // attrib:6
|
layout(location=6) in ivec4 bone_indices; // attrib:6
|
||||||
layout(location=7) mediump vec4 bone_weights; // attrib:7
|
layout(location=7) in vec4 bone_weights; // attrib:7
|
||||||
uniform highp sampler2D skeleton_matrices;
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef USE_ATTRIBUTE_INSTANCING
|
#ifdef USE_ATTRIBUTE_INSTANCING
|
||||||
|
@ -140,6 +150,15 @@ out highp float dp_clip;
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef USE_SKELETON
|
||||||
|
|
||||||
|
layout(std140) uniform SkeletonData { //ubo:7
|
||||||
|
|
||||||
|
mat3x4 skeleton[MAX_SKELETON_BONES];
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
|
|
||||||
highp vec4 vertex = vertex_attrib; // vec4(vertex_attrib.xyz * data_attrib.x,1.0);
|
highp vec4 vertex = vertex_attrib; // vec4(vertex_attrib.xyz * data_attrib.x,1.0);
|
||||||
|
@ -152,23 +171,25 @@ void main() {
|
||||||
float binormalf = tangent_attrib.a;
|
float binormalf = tangent_attrib.a;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#ifdef USE_SKELETON
|
#ifdef USE_SKELETON
|
||||||
|
|
||||||
{
|
{
|
||||||
//skeleton transform
|
//skeleton transform
|
||||||
highp mat4 m=mat4(texture2D(skeleton_matrices,vec2((bone_indices.x*3.0+0.0)*skeltex_pixel_size,0.0)),texture2D(skeleton_matrices,vec2((bone_indices.x*3.0+1.0)*skeltex_pixel_size,0.0)),texture2D(skeleton_matrices,vec2((bone_indices.x*3.0+2.0)*skeltex_pixel_size,0.0)),vec4(0.0,0.0,0.0,1.0))*bone_weights.x;
|
highp mat3x4 m=skeleton[bone_indices.x]*bone_weights.x;
|
||||||
m+=mat4(texture2D(skeleton_matrices,vec2((bone_indices.y*3.0+0.0)*skeltex_pixel_size,0.0)),texture2D(skeleton_matrices,vec2((bone_indices.y*3.0+1.0)*skeltex_pixel_size,0.0)),texture2D(skeleton_matrices,vec2((bone_indices.y*3.0+2.0)*skeltex_pixel_size,0.0)),vec4(0.0,0.0,0.0,1.0))*bone_weights.y;
|
m+=skeleton[bone_indices.y]*bone_weights.y;
|
||||||
m+=mat4(texture2D(skeleton_matrices,vec2((bone_indices.z*3.0+0.0)*skeltex_pixel_size,0.0)),texture2D(skeleton_matrices,vec2((bone_indices.z*3.0+1.0)*skeltex_pixel_size,0.0)),texture2D(skeleton_matrices,vec2((bone_indices.z*3.0+2.0)*skeltex_pixel_size,0.0)),vec4(0.0,0.0,0.0,1.0))*bone_weights.z;
|
m+=skeleton[bone_indices.z]*bone_weights.z;
|
||||||
m+=mat4(texture2D(skeleton_matrices,vec2((bone_indices.w*3.0+0.0)*skeltex_pixel_size,0.0)),texture2D(skeleton_matrices,vec2((bone_indices.w*3.0+1.0)*skeltex_pixel_size,0.0)),texture2D(skeleton_matrices,vec2((bone_indices.w*3.0+2.0)*skeltex_pixel_size,0.0)),vec4(0.0,0.0,0.0,1.0))*bone_weights.w;
|
m+=skeleton[bone_indices.w]*bone_weights.w;
|
||||||
|
|
||||||
vertex = vertex_in * m;
|
vertex.xyz = vertex * m;
|
||||||
normal = (vec4(normal,0.0) * m).xyz;
|
|
||||||
|
normal = vec4(normal,0.0) * m;
|
||||||
#if defined(ENABLE_TANGENT_INTERP) || defined(ENABLE_NORMALMAP) || defined(LIGHT_USE_ANISOTROPY)
|
#if defined(ENABLE_TANGENT_INTERP) || defined(ENABLE_NORMALMAP) || defined(LIGHT_USE_ANISOTROPY)
|
||||||
tangent = (vec4(tangent,0.0) * m).xyz;
|
tangent.xyz = vec4(tangent.xyz,0.0) * mn;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
#endif // USE_SKELETON1
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if !defined(SKIP_TRANSFORM_USED)
|
#if !defined(SKIP_TRANSFORM_USED)
|
||||||
|
|
||||||
|
|
|
@ -1007,12 +1007,26 @@ void VisualServer::mesh_add_surface_from_arrays(RID p_mesh,PrimitiveType p_primi
|
||||||
} break;
|
} break;
|
||||||
case VS::ARRAY_BONES: {
|
case VS::ARRAY_BONES: {
|
||||||
|
|
||||||
if (p_compress_format&ARRAY_FLAG_USE_16_BIT_BONES) {
|
DVector<int> bones = p_arrays[VS::ARRAY_BONES];
|
||||||
elem_size=sizeof(uint32_t);
|
int max_bone=0;
|
||||||
} else {
|
|
||||||
elem_size=sizeof(uint16_t)*4;
|
{
|
||||||
|
int bc = bones.size();
|
||||||
|
DVector<int>::Read r=bones.read();
|
||||||
|
for(int j=0;j<bc;j++) {
|
||||||
|
max_bone=MAX(r[j],max_bone);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (max_bone > 255) {
|
||||||
|
p_compress_format|=ARRAY_FLAG_USE_16_BIT_BONES;
|
||||||
|
elem_size=sizeof(uint16_t)*4;
|
||||||
|
} else {
|
||||||
|
p_compress_format&=~ARRAY_FLAG_USE_16_BIT_BONES;
|
||||||
|
elem_size=sizeof(uint32_t);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
} break;
|
} break;
|
||||||
case VS::ARRAY_INDEX: {
|
case VS::ARRAY_INDEX: {
|
||||||
|
|
||||||
|
@ -1043,7 +1057,7 @@ void VisualServer::mesh_add_surface_from_arrays(RID p_mesh,PrimitiveType p_primi
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t mask = (1<<ARRAY_MAX)-1;
|
uint32_t mask = (1<<ARRAY_MAX)-1;
|
||||||
format|=~mask&p_compress_format; //make the full format
|
format|=(~mask)&p_compress_format; //make the full format
|
||||||
|
|
||||||
|
|
||||||
int array_size = total_elem_size * array_len;
|
int array_size = total_elem_size * array_len;
|
||||||
|
|
|
@ -220,7 +220,7 @@ public:
|
||||||
ARRAY_FLAG_USE_2D_VERTICES=ARRAY_COMPRESS_INDEX<<1,
|
ARRAY_FLAG_USE_2D_VERTICES=ARRAY_COMPRESS_INDEX<<1,
|
||||||
ARRAY_FLAG_USE_16_BIT_BONES=ARRAY_COMPRESS_INDEX<<2,
|
ARRAY_FLAG_USE_16_BIT_BONES=ARRAY_COMPRESS_INDEX<<2,
|
||||||
|
|
||||||
ARRAY_COMPRESS_DEFAULT=ARRAY_COMPRESS_VERTEX|ARRAY_COMPRESS_NORMAL|ARRAY_COMPRESS_TANGENT|ARRAY_COMPRESS_COLOR|ARRAY_COMPRESS_TEX_UV|ARRAY_COMPRESS_TEX_UV2|ARRAY_COMPRESS_BONES|ARRAY_COMPRESS_WEIGHTS|ARRAY_COMPRESS_INDEX
|
ARRAY_COMPRESS_DEFAULT=ARRAY_COMPRESS_VERTEX|ARRAY_COMPRESS_NORMAL|ARRAY_COMPRESS_TANGENT|ARRAY_COMPRESS_COLOR|ARRAY_COMPRESS_TEX_UV|ARRAY_COMPRESS_TEX_UV2|ARRAY_COMPRESS_WEIGHTS
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue