diff options
Diffstat (limited to 'drivers/gles3/rasterizer_storage_gles3.cpp')
-rw-r--r-- | drivers/gles3/rasterizer_storage_gles3.cpp | 241 |
1 files changed, 131 insertions, 110 deletions
diff --git a/drivers/gles3/rasterizer_storage_gles3.cpp b/drivers/gles3/rasterizer_storage_gles3.cpp index ed4be1cb3d..526b4ab9ce 100644 --- a/drivers/gles3/rasterizer_storage_gles3.cpp +++ b/drivers/gles3/rasterizer_storage_gles3.cpp @@ -3038,7 +3038,7 @@ Rect3 RasterizerStorageGLES3::mesh_get_aabb(RID p_mesh, RID p_skeleton) const { int sbs = sk->size; ERR_CONTINUE(bs > sbs); - float *skb = sk->bones.ptr(); + const float *texture = sk->skel_texture.ptr(); bool first = true; if (sk->use_2d) { @@ -3047,16 +3047,18 @@ Rect3 RasterizerStorageGLES3::mesh_get_aabb(RID p_mesh, RID p_skeleton) const { if (!skused[j]) continue; - float *dataptr = &skb[8 * j]; + + int base_ofs = ((j / 256) * 256) * 2 * 4 + (j % 256) * 4; Transform mtx; - mtx.basis.elements[0][0] = dataptr[0]; - mtx.basis.elements[0][1] = dataptr[1]; - mtx.origin[0] = dataptr[3]; - mtx.basis.elements[1][0] = dataptr[4]; - mtx.basis.elements[1][1] = dataptr[5]; - mtx.origin[1] = dataptr[7]; + mtx.basis[0].x=texture[base_ofs+0]; + mtx.basis[0].y=texture[base_ofs+1]; + mtx.origin.x=texture[base_ofs+3]; + base_ofs+=256*4; + mtx.basis[1].x=texture[base_ofs+0]; + mtx.basis[1].y=texture[base_ofs+1]; + mtx.origin.y=texture[base_ofs+3]; Rect3 baabb = mtx.xform(skbones[j]); if (first) { @@ -3072,21 +3074,24 @@ Rect3 RasterizerStorageGLES3::mesh_get_aabb(RID p_mesh, RID p_skeleton) const { if (!skused[j]) continue; - float *dataptr = &skb[12 * j]; + int base_ofs = ((j / 256) * 256) * 3 * 4 + (j % 256) * 4; Transform mtx; - mtx.basis.elements[0][0] = dataptr[0]; - mtx.basis.elements[0][1] = dataptr[1]; - mtx.basis.elements[0][2] = dataptr[2]; - mtx.origin.x = dataptr[3]; - mtx.basis.elements[1][0] = dataptr[4]; - mtx.basis.elements[1][1] = dataptr[5]; - mtx.basis.elements[1][2] = dataptr[6]; - mtx.origin.y = dataptr[7]; - mtx.basis.elements[2][0] = dataptr[8]; - mtx.basis.elements[2][1] = dataptr[9]; - mtx.basis.elements[2][2] = dataptr[10]; - mtx.origin.z = dataptr[11]; + + mtx.basis[0].x=texture[base_ofs+0]; + mtx.basis[0].y=texture[base_ofs+1]; + mtx.basis[0].z=texture[base_ofs+2]; + mtx.origin.x=texture[base_ofs+3]; + base_ofs+=256*4; + mtx.basis[1].x=texture[base_ofs+0]; + mtx.basis[1].y=texture[base_ofs+1]; + mtx.basis[1].z=texture[base_ofs+2]; + mtx.origin.y=texture[base_ofs+3]; + base_ofs+=256*4; + mtx.basis[2].x=texture[base_ofs+0]; + mtx.basis[2].y=texture[base_ofs+1]; + mtx.basis[2].z=texture[base_ofs+2]; + mtx.origin.z=texture[base_ofs+3]; Rect3 baabb = mtx.xform(skbones[j]); if (first) { @@ -3921,6 +3926,9 @@ RID RasterizerStorageGLES3::immediate_get_material(RID p_immediate) const { RID RasterizerStorageGLES3::skeleton_create() { Skeleton *skeleton = memnew(Skeleton); + + glGenTextures(1,&skeleton->texture); + return skeleton_owner.make_rid(skeleton); } @@ -3933,49 +3941,28 @@ void RasterizerStorageGLES3::skeleton_allocate(RID p_skeleton, int p_bones, bool 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; - } + skeleton->size=p_bones; + skeleton->use_2d=p_2d_skeleton; + int height = p_bones/256; + if (p_bones%256) + height++; + + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D,skeleton->texture); + + if (skeleton->use_2d) { + skeleton->skel_texture.resize(256*height*2*4); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32F, 256, height*2, 0, GL_RGBA, GL_FLOAT, NULL); } 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; - } + skeleton->skel_texture.resize(256*height*3*4); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32F, 256, height*3, 0, GL_RGBA, GL_FLOAT, NULL); } - 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); - } + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); if (!skeleton->update_list.in_list()) { skeleton_update_list.add(&skeleton->update_list); @@ -3997,19 +3984,25 @@ void RasterizerStorageGLES3::skeleton_bone_set_transform(RID p_skeleton, int p_b 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; + float *texture = skeleton->skel_texture.ptr(); + + int base_ofs = ((p_bone / 256) * 256) * 3 * 4 + (p_bone % 256) * 4; + + texture[base_ofs+0]=p_transform.basis[0].x; + texture[base_ofs+1]=p_transform.basis[0].y; + texture[base_ofs+2]=p_transform.basis[0].z; + texture[base_ofs+3]=p_transform.origin.x; + base_ofs+=256*4; + texture[base_ofs+0]=p_transform.basis[1].x; + texture[base_ofs+1]=p_transform.basis[1].y; + texture[base_ofs+2]=p_transform.basis[1].z; + texture[base_ofs+3]=p_transform.origin.y; + base_ofs+=256*4; + texture[base_ofs+0]=p_transform.basis[2].x; + texture[base_ofs+1]=p_transform.basis[2].y; + texture[base_ofs+2]=p_transform.basis[2].z; + texture[base_ofs+3]=p_transform.origin.z; + if (!skeleton->update_list.in_list()) { skeleton_update_list.add(&skeleton->update_list); @@ -4024,22 +4017,30 @@ Transform RasterizerStorageGLES3::skeleton_bone_get_transform(RID p_skeleton, in 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; + const float *texture = skeleton->skel_texture.ptr(); + + Transform ret; + + int base_ofs = ((p_bone / 256) * 256) * 3 * 4 + (p_bone % 256) * 4; + + ret.basis[0].x=texture[base_ofs+0]; + ret.basis[0].y=texture[base_ofs+1]; + ret.basis[0].z=texture[base_ofs+2]; + ret.origin.x=texture[base_ofs+3]; + base_ofs+=256*4; + ret.basis[1].x=texture[base_ofs+0]; + ret.basis[1].y=texture[base_ofs+1]; + ret.basis[1].z=texture[base_ofs+2]; + ret.origin.y=texture[base_ofs+3]; + base_ofs+=256*4; + ret.basis[2].x=texture[base_ofs+0]; + ret.basis[2].y=texture[base_ofs+1]; + ret.basis[2].z=texture[base_ofs+2]; + ret.origin.z=texture[base_ofs+3]; + + + return ret; + } void RasterizerStorageGLES3::skeleton_bone_set_transform_2d(RID p_skeleton, int p_bone, const Transform2D &p_transform) { @@ -4049,15 +4050,20 @@ void RasterizerStorageGLES3::skeleton_bone_set_transform_2d(RID p_skeleton, int 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]; + float *texture = skeleton->skel_texture.ptr(); + + int base_ofs = ((p_bone / 256) * 256) * 2 * 4 + (p_bone % 256) * 4; + + texture[base_ofs+0]=p_transform[0][0]; + texture[base_ofs+1]=p_transform[1][0]; + texture[base_ofs+2]=0; + texture[base_ofs+3]=p_transform[2][0]; + base_ofs+=256*4; + texture[base_ofs+0]=p_transform[0][1]; + texture[base_ofs+1]=p_transform[1][1]; + texture[base_ofs+2]=0; + texture[base_ofs+3]=p_transform[2][1]; + if (!skeleton->update_list.in_list()) { skeleton_update_list.add(&skeleton->update_list); @@ -4071,28 +4077,41 @@ Transform2D RasterizerStorageGLES3::skeleton_bone_get_transform_2d(RID p_skeleto ERR_FAIL_INDEX_V(p_bone, skeleton->size, Transform2D()); ERR_FAIL_COND_V(!skeleton->use_2d, Transform2D()); - Transform2D mtx; + const float *texture = skeleton->skel_texture.ptr(); + + Transform2D ret; + + int base_ofs = ((p_bone / 256) * 256) * 2 * 4 + (p_bone % 256) * 4; - 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]; + ret[0][0]=texture[base_ofs+0]; + ret[1][0]=texture[base_ofs+1]; + ret[2][0]=texture[base_ofs+3]; + base_ofs+=256*4; + ret[0][1]=texture[base_ofs+0]; + ret[1][1]=texture[base_ofs+1]; + ret[2][1]=texture[base_ofs+3]; - return mtx; + return ret; } void RasterizerStorageGLES3::update_dirty_skeletons() { + glActiveTexture(GL_TEXTURE0); + 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); + + + + int height = skeleton->size/256; + if (skeleton->size%256) + height++; + + + glBindTexture(GL_TEXTURE_2D,skeleton->texture); + glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 256,height*(skeleton->use_2d?2:3), GL_RGBA, GL_FLOAT, skeleton->skel_texture.ptr()); } for (Set<RasterizerScene::InstanceBase *>::Element *E = skeleton->instances.front(); E; E = E->next()) { @@ -5957,6 +5976,8 @@ bool RasterizerStorageGLES3::free(RID p_rid) { } skeleton_allocate(p_rid, 0, false); + + glDeleteTextures(1,&skeleton->texture); skeleton_owner.free(p_rid); memdelete(skeleton); |