summaryrefslogtreecommitdiff
path: root/drivers/gles3
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gles3')
-rw-r--r--drivers/gles3/rasterizer_canvas_gles3.cpp86
-rw-r--r--drivers/gles3/rasterizer_canvas_gles3.h5
-rw-r--r--drivers/gles3/rasterizer_gles3.cpp2
-rw-r--r--drivers/gles3/rasterizer_storage_gles3.cpp11
-rw-r--r--drivers/gles3/rasterizer_storage_gles3.h2
-rw-r--r--drivers/gles3/shaders/canvas.glsl58
6 files changed, 156 insertions, 8 deletions
diff --git a/drivers/gles3/rasterizer_canvas_gles3.cpp b/drivers/gles3/rasterizer_canvas_gles3.cpp
index c33fdaa355..b221a41893 100644
--- a/drivers/gles3/rasterizer_canvas_gles3.cpp
+++ b/drivers/gles3/rasterizer_canvas_gles3.cpp
@@ -160,6 +160,7 @@ void RasterizerCanvasGLES3::canvas_begin() {
state.canvas_shader.set_conditional(CanvasShaderGLES3::SHADOW_FILTER_PCF13, false);
state.canvas_shader.set_conditional(CanvasShaderGLES3::USE_DISTANCE_FIELD, false);
state.canvas_shader.set_conditional(CanvasShaderGLES3::USE_NINEPATCH, false);
+ state.canvas_shader.set_conditional(CanvasShaderGLES3::USE_SKELETON, false);
state.canvas_shader.set_custom_shader(0);
state.canvas_shader.bind();
@@ -180,6 +181,7 @@ void RasterizerCanvasGLES3::canvas_begin() {
glBindVertexArray(data.canvas_quad_array);
state.using_texture_rect = true;
state.using_ninepatch = false;
+ state.using_skeleton = false;
}
void RasterizerCanvasGLES3::canvas_end() {
@@ -284,6 +286,10 @@ void RasterizerCanvasGLES3::_set_texture_rect_mode(bool p_enable, bool p_ninepat
state.canvas_shader.set_uniform(CanvasShaderGLES3::FINAL_MODULATE, state.canvas_item_modulate);
state.canvas_shader.set_uniform(CanvasShaderGLES3::MODELVIEW_MATRIX, state.final_transform);
state.canvas_shader.set_uniform(CanvasShaderGLES3::EXTRA_MATRIX, state.extra_matrix);
+ if (state.using_skeleton) {
+ state.canvas_shader.set_uniform(CanvasShaderGLES3::SKELETON_TRANSFORM, state.skeleton_transform);
+ state.canvas_shader.set_uniform(CanvasShaderGLES3::SKELETON_TRANSFORM_INVERSE, state.skeleton_transform_inverse);
+ }
if (storage->frame.current_rt) {
state.canvas_shader.set_uniform(CanvasShaderGLES3::SCREEN_PIXEL_SIZE, Vector2(1.0 / storage->frame.current_rt->width, 1.0 / storage->frame.current_rt->height));
} else {
@@ -293,7 +299,7 @@ void RasterizerCanvasGLES3::_set_texture_rect_mode(bool p_enable, bool p_ninepat
state.using_ninepatch = p_ninepatch;
}
-void RasterizerCanvasGLES3::_draw_polygon(const int *p_indices, int p_index_count, int p_vertex_count, const Vector2 *p_vertices, const Vector2 *p_uvs, const Color *p_colors, bool p_singlecolor) {
+void RasterizerCanvasGLES3::_draw_polygon(const int *p_indices, int p_index_count, int p_vertex_count, const Vector2 *p_vertices, const Vector2 *p_uvs, const Color *p_colors, bool p_singlecolor, const int *p_bones, const float *p_weights) {
glBindVertexArray(data.polygon_buffer_pointer_array);
glBindBuffer(GL_ARRAY_BUFFER, data.polygon_buffer);
@@ -301,11 +307,17 @@ void RasterizerCanvasGLES3::_draw_polygon(const int *p_indices, int p_index_coun
uint32_t buffer_ofs = 0;
//vertex
+#ifdef DEBUG_ENABLED
+ ERR_FAIL_COND(buffer_ofs > data.polygon_buffer_size);
+#endif
glBufferSubData(GL_ARRAY_BUFFER, buffer_ofs, sizeof(Vector2) * p_vertex_count, p_vertices);
glEnableVertexAttribArray(VS::ARRAY_VERTEX);
glVertexAttribPointer(VS::ARRAY_VERTEX, 2, GL_FLOAT, false, sizeof(Vector2), ((uint8_t *)0) + buffer_ofs);
buffer_ofs += sizeof(Vector2) * p_vertex_count;
//color
+#ifdef DEBUG_ENABLED
+ ERR_FAIL_COND(buffer_ofs > data.polygon_buffer_size);
+#endif
if (p_singlecolor) {
glDisableVertexAttribArray(VS::ARRAY_COLOR);
@@ -322,6 +334,10 @@ void RasterizerCanvasGLES3::_draw_polygon(const int *p_indices, int p_index_coun
buffer_ofs += sizeof(Color) * p_vertex_count;
}
+#ifdef DEBUG_ENABLED
+ ERR_FAIL_COND(buffer_ofs > data.polygon_buffer_size);
+#endif
+
if (p_uvs) {
glBufferSubData(GL_ARRAY_BUFFER, buffer_ofs, sizeof(Vector2) * p_vertex_count, p_uvs);
@@ -333,6 +349,32 @@ void RasterizerCanvasGLES3::_draw_polygon(const int *p_indices, int p_index_coun
glDisableVertexAttribArray(VS::ARRAY_TEX_UV);
}
+#ifdef DEBUG_ENABLED
+ ERR_FAIL_COND(buffer_ofs > data.polygon_buffer_size);
+#endif
+
+ if (p_bones && p_weights) {
+
+ glBufferSubData(GL_ARRAY_BUFFER, buffer_ofs, sizeof(int) * 4 * p_vertex_count, p_bones);
+ glEnableVertexAttribArray(VS::ARRAY_BONES);
+ //glVertexAttribPointer(VS::ARRAY_BONES, 4, GL_UNSIGNED_INT, false, sizeof(int) * 4, ((uint8_t *)0) + buffer_ofs);
+ glVertexAttribIPointer(VS::ARRAY_BONES, 4, GL_UNSIGNED_INT, sizeof(int) * 4, ((uint8_t *)0) + buffer_ofs);
+ buffer_ofs += sizeof(int) * 4 * p_vertex_count;
+
+ glBufferSubData(GL_ARRAY_BUFFER, buffer_ofs, sizeof(float) * 4 * p_vertex_count, p_weights);
+ glEnableVertexAttribArray(VS::ARRAY_WEIGHTS);
+ glVertexAttribPointer(VS::ARRAY_WEIGHTS, 4, GL_FLOAT, false, sizeof(float) * 4, ((uint8_t *)0) + buffer_ofs);
+ buffer_ofs += sizeof(float) * 4 * p_vertex_count;
+
+ } else if (state.using_skeleton) {
+ glVertexAttribI4ui(VS::ARRAY_BONES, 0, 0, 0, 0);
+ glVertexAttrib4f(VS::ARRAY_WEIGHTS, 0, 0, 0, 0);
+ }
+
+#ifdef DEBUG_ENABLED
+ ERR_FAIL_COND(buffer_ofs > data.polygon_buffer_size);
+#endif
+
//bind the indices buffer.
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, data.polygon_index_buffer);
glBufferSubData(GL_ELEMENT_ARRAY_BUFFER, 0, sizeof(int) * p_index_count, p_indices);
@@ -342,6 +384,12 @@ void RasterizerCanvasGLES3::_draw_polygon(const int *p_indices, int p_index_coun
storage->frame.canvas_draw_commands++;
+ if (p_bones && p_weights) {
+ //not used so often, so disable when used
+ glDisableVertexAttribArray(VS::ARRAY_BONES);
+ glDisableVertexAttribArray(VS::ARRAY_WEIGHTS);
+ }
+
glBindVertexArray(0);
}
@@ -735,7 +783,8 @@ void RasterizerCanvasGLES3::_canvas_item_render_commands(Item *p_item, Item *cur
Size2 texpixel_size(1.0 / texture->width, 1.0 / texture->height);
state.canvas_shader.set_uniform(CanvasShaderGLES3::COLOR_TEXPIXEL_SIZE, texpixel_size);
}
- _draw_polygon(polygon->indices.ptr(), polygon->count, polygon->points.size(), polygon->points.ptr(), polygon->uvs.ptr(), polygon->colors.ptr(), polygon->colors.size() == 1);
+
+ _draw_polygon(polygon->indices.ptr(), polygon->count, polygon->points.size(), polygon->points.ptr(), polygon->uvs.ptr(), polygon->colors.ptr(), polygon->colors.size() == 1, polygon->bones.ptr(), polygon->weights.ptr());
#ifdef GLES_OVER_GL
if (polygon->antialiased) {
glEnable(GL_LINE_SMOOTH);
@@ -921,7 +970,7 @@ void RasterizerCanvasGLES3::_canvas_item_render_commands(Item *p_item, Item *cur
}
_bind_canvas_texture(RID(), RID());
- _draw_polygon(indices, numpoints * 3, numpoints + 1, points, NULL, &circle->color, true);
+ _draw_polygon(indices, numpoints * 3, numpoints + 1, points, NULL, &circle->color, true, NULL, NULL);
//_draw_polygon(numpoints*3,indices,points,NULL,&circle->color,RID(),true);
//canvas_draw_circle(circle->indices.size(),circle->indices.ptr(),circle->points.ptr(),circle->uvs.ptr(),circle->colors.ptr(),circle->texture,circle->colors.size()==1);
@@ -1068,6 +1117,7 @@ void RasterizerCanvasGLES3::canvas_render_items(Item *p_item_list, int p_z, cons
RID canvas_last_material;
bool prev_distance_field = false;
+ bool prev_use_skeleton = false;
while (p_item_list) {
@@ -1106,6 +1156,36 @@ void RasterizerCanvasGLES3::canvas_render_items(Item *p_item_list, int p_z, cons
}
}
+ RasterizerStorageGLES3::Skeleton *skeleton = NULL;
+
+ {
+ //skeleton handling
+ if (ci->skeleton.is_valid()) {
+ skeleton = storage->skeleton_owner.getornull(ci->skeleton);
+ if (!skeleton->use_2d) {
+ skeleton = NULL;
+ } else {
+ state.skeleton_transform = p_transform * skeleton->base_transform_2d;
+ state.skeleton_transform_inverse = state.skeleton_transform.affine_inverse();
+ }
+ }
+
+ bool use_skeleton = skeleton != NULL;
+ if (prev_use_skeleton != use_skeleton) {
+ rebind_shader = true;
+ state.canvas_shader.set_conditional(CanvasShaderGLES3::USE_SKELETON, use_skeleton);
+ prev_use_skeleton = use_skeleton;
+ }
+
+ if (skeleton) {
+ glActiveTexture(GL_TEXTURE0 + storage->config.max_texture_image_units - 1);
+ glBindTexture(GL_TEXTURE_2D, skeleton->texture);
+ state.using_skeleton = true;
+ } else {
+ state.using_skeleton = false;
+ }
+ }
+
//begin rect
Item *material_owner = ci->material_owner ? ci->material_owner : ci;
diff --git a/drivers/gles3/rasterizer_canvas_gles3.h b/drivers/gles3/rasterizer_canvas_gles3.h
index 1dc17f98d5..bfaf1fdb4b 100644
--- a/drivers/gles3/rasterizer_canvas_gles3.h
+++ b/drivers/gles3/rasterizer_canvas_gles3.h
@@ -84,6 +84,9 @@ public:
Color canvas_item_modulate;
Transform2D extra_matrix;
Transform2D final_transform;
+ bool using_skeleton;
+ Transform2D skeleton_transform;
+ Transform2D skeleton_transform_inverse;
} state;
@@ -123,7 +126,7 @@ public:
_FORCE_INLINE_ RasterizerStorageGLES3::Texture *_bind_canvas_texture(const RID &p_texture, const RID &p_normal_map);
_FORCE_INLINE_ void _draw_gui_primitive(int p_points, const Vector2 *p_vertices, const Color *p_colors, const Vector2 *p_uvs);
- _FORCE_INLINE_ void _draw_polygon(const int *p_indices, int p_index_count, int p_vertex_count, const Vector2 *p_vertices, const Vector2 *p_uvs, const Color *p_colors, bool p_singlecolor);
+ _FORCE_INLINE_ void _draw_polygon(const int *p_indices, int p_index_count, int p_vertex_count, const Vector2 *p_vertices, const Vector2 *p_uvs, const Color *p_colors, bool p_singlecolor, const int *p_bones, const float *p_weights);
_FORCE_INLINE_ void _draw_generic(GLuint p_primitive, int p_vertex_count, const Vector2 *p_vertices, const Vector2 *p_uvs, const Color *p_colors, bool p_singlecolor);
_FORCE_INLINE_ void _canvas_item_render_commands(Item *p_item, Item *current_clip, bool &reclip);
diff --git a/drivers/gles3/rasterizer_gles3.cpp b/drivers/gles3/rasterizer_gles3.cpp
index ca39d9f966..0fb69494f4 100644
--- a/drivers/gles3/rasterizer_gles3.cpp
+++ b/drivers/gles3/rasterizer_gles3.cpp
@@ -111,8 +111,6 @@ static void GLAPIENTRY _gl_debug_print(GLenum source, GLenum type, GLuint id, GL
strcpy(debType, "Portability");
else if (type == _EXT_DEBUG_TYPE_PERFORMANCE_ARB)
strcpy(debType, "Performance");
- else if (type == _EXT_DEBUG_TYPE_OTHER_ARB)
- strcpy(debType, "Other");
if (severity == _EXT_DEBUG_SEVERITY_HIGH_ARB)
strcpy(debSev, "High");
diff --git a/drivers/gles3/rasterizer_storage_gles3.cpp b/drivers/gles3/rasterizer_storage_gles3.cpp
index f91ed35331..77ac962e37 100644
--- a/drivers/gles3/rasterizer_storage_gles3.cpp
+++ b/drivers/gles3/rasterizer_storage_gles3.cpp
@@ -1912,7 +1912,7 @@ void RasterizerStorageGLES3::material_set_param(RID p_material, const StringName
Variant RasterizerStorageGLES3::material_get_param(RID p_material, const StringName &p_param) const {
const Material *material = material_owner.get(p_material);
- ERR_FAIL_COND_V(!material, RID());
+ ERR_FAIL_COND_V(!material, Variant());
if (material->params.has(p_param))
return material->params[p_param];
@@ -4496,6 +4496,15 @@ Transform2D RasterizerStorageGLES3::skeleton_bone_get_transform_2d(RID p_skeleto
return ret;
}
+void RasterizerStorageGLES3::skeleton_set_base_transform_2d(RID p_skeleton, const Transform2D &p_base_transform) {
+
+ Skeleton *skeleton = skeleton_owner.getornull(p_skeleton);
+
+ ERR_FAIL_COND(!skeleton->use_2d);
+
+ skeleton->base_transform_2d = p_base_transform;
+}
+
void RasterizerStorageGLES3::update_dirty_skeletons() {
glActiveTexture(GL_TEXTURE0);
diff --git a/drivers/gles3/rasterizer_storage_gles3.h b/drivers/gles3/rasterizer_storage_gles3.h
index ef2b247266..def6eaa167 100644
--- a/drivers/gles3/rasterizer_storage_gles3.h
+++ b/drivers/gles3/rasterizer_storage_gles3.h
@@ -868,6 +868,7 @@ public:
GLuint texture;
SelfList<Skeleton> update_list;
Set<RasterizerScene::InstanceBase *> instances; //instances using skeleton
+ Transform2D base_transform_2d;
Skeleton() :
update_list(this) {
@@ -891,6 +892,7 @@ public:
virtual Transform skeleton_bone_get_transform(RID p_skeleton, int p_bone) const;
virtual void skeleton_bone_set_transform_2d(RID p_skeleton, int p_bone, const Transform2D &p_transform);
virtual Transform2D skeleton_bone_get_transform_2d(RID p_skeleton, int p_bone) const;
+ virtual void skeleton_set_base_transform_2d(RID p_skeleton, const Transform2D &p_base_transform);
/* Light API */
diff --git a/drivers/gles3/shaders/canvas.glsl b/drivers/gles3/shaders/canvas.glsl
index 3bbeb1149d..326aab4c7c 100644
--- a/drivers/gles3/shaders/canvas.glsl
+++ b/drivers/gles3/shaders/canvas.glsl
@@ -4,6 +4,11 @@
layout(location=0) in highp vec2 vertex;
layout(location=3) in vec4 color_attrib;
+#ifdef USE_SKELETON
+layout(location=6) in uvec4 bone_indices; // attrib:6
+layout(location=7) in vec4 bone_weights; // attrib:7
+#endif
+
#ifdef USE_TEXTURE_RECT
uniform vec4 dst_rect;
@@ -51,6 +56,12 @@ out highp vec2 pixel_size_interp;
#endif
+#ifdef USE_SKELETON
+uniform mediump sampler2D skeleton_texture; // texunit:-1
+uniform highp mat4 skeleton_transform;
+uniform highp mat4 skeleton_transform_inverse;
+#endif
+
#ifdef USE_LIGHTING
layout(std140) uniform LightData { //ubo:1
@@ -75,7 +86,6 @@ out vec4 light_uv_interp;
out vec4 local_rot;
-
#ifdef USE_SHADOWS
out highp vec2 pos;
#endif
@@ -101,6 +111,7 @@ MATERIAL_UNIFORMS
#endif
+
VERTEX_SHADER_GLOBALS
void main() {
@@ -146,6 +157,7 @@ void main() {
#endif
+
#define extra_matrix extra_matrix2
{
@@ -175,6 +187,49 @@ VERTEX_SHADER_CODE
#endif
+#ifdef USE_SKELETON
+
+ if (bone_weights!=vec4(0.0)){ //must be a valid bone
+ //skeleton transform
+
+ ivec4 bone_indicesi = ivec4(bone_indices);
+
+ ivec2 tex_ofs = ivec2( bone_indicesi.x%256, (bone_indicesi.x/256)*2 );
+
+ highp mat2x4 m = mat2x4(
+ texelFetch(skeleton_texture,tex_ofs,0),
+ texelFetch(skeleton_texture,tex_ofs+ivec2(0,1),0)
+ ) * bone_weights.x;
+
+ tex_ofs = ivec2( bone_indicesi.y%256, (bone_indicesi.y/256)*2 );
+
+ m+= mat2x4(
+ texelFetch(skeleton_texture,tex_ofs,0),
+ texelFetch(skeleton_texture,tex_ofs+ivec2(0,1),0)
+ ) * bone_weights.y;
+
+ tex_ofs = ivec2( bone_indicesi.z%256, (bone_indicesi.z/256)*2 );
+
+ m+= mat2x4(
+ texelFetch(skeleton_texture,tex_ofs,0),
+ texelFetch(skeleton_texture,tex_ofs+ivec2(0,1),0)
+ ) * bone_weights.z;
+
+
+ tex_ofs = ivec2( bone_indicesi.w%256, (bone_indicesi.w/256)*2 );
+
+ m+= mat2x4(
+ texelFetch(skeleton_texture,tex_ofs,0),
+ texelFetch(skeleton_texture,tex_ofs+ivec2(0,1),0)
+ ) * bone_weights.w;
+
+ mat4 bone_matrix = skeleton_transform * transpose(mat4(m[0],m[1],vec4(0.0,0.0,1.0,0.0),vec4(0.0,0.0,0.0,1.0))) * skeleton_transform_inverse;
+
+ outvec = bone_matrix * outvec;
+ }
+
+#endif
+
gl_Position = projection_matrix * outvec;
#ifdef USE_LIGHTING
@@ -207,6 +262,7 @@ uniform mediump sampler2D color_texture; // texunit:0
uniform highp vec2 color_texpixel_size;
uniform mediump sampler2D normal_texture; // texunit:1
+
in highp vec2 uv_interp;
in mediump vec4 color_interp;