summaryrefslogtreecommitdiff
path: root/servers/visual/rasterizer/rasterizer_canvas_rd.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'servers/visual/rasterizer/rasterizer_canvas_rd.cpp')
-rw-r--r--servers/visual/rasterizer/rasterizer_canvas_rd.cpp866
1 files changed, 570 insertions, 296 deletions
diff --git a/servers/visual/rasterizer/rasterizer_canvas_rd.cpp b/servers/visual/rasterizer/rasterizer_canvas_rd.cpp
index 61f3c1ffa1..eef127eeeb 100644
--- a/servers/visual/rasterizer/rasterizer_canvas_rd.cpp
+++ b/servers/visual/rasterizer/rasterizer_canvas_rd.cpp
@@ -1,5 +1,5 @@
#include "rasterizer_canvas_rd.h"
-
+#include "core/math/math_funcs.h"
void RasterizerCanvasRD::_update_transform_2d_to_mat4(const Transform2D &p_transform, float *p_mat4) {
p_mat4[0] = p_transform.elements[0][0];
@@ -33,6 +33,16 @@ void RasterizerCanvasRD::_update_transform_2d_to_mat2x4(const Transform2D &p_tra
p_mat2x4[7] = p_transform.elements[2][1];
}
+void RasterizerCanvasRD::_update_transform_2d_to_mat2x3(const Transform2D &p_transform, float *p_mat2x3) {
+
+ p_mat2x3[0] = p_transform.elements[0][0];
+ p_mat2x3[1] = p_transform.elements[0][1];
+ p_mat2x3[2] = p_transform.elements[1][0];
+ p_mat2x3[3] = p_transform.elements[1][1];
+ p_mat2x3[4] = p_transform.elements[2][0];
+ p_mat2x3[5] = p_transform.elements[2][1];
+}
+
void RasterizerCanvasRD::_update_transform_to_mat4(const Transform &p_transform, float *p_mat4) {
p_mat4[0] = p_transform.basis.elements[0][0];
@@ -53,6 +63,70 @@ void RasterizerCanvasRD::_update_transform_to_mat4(const Transform &p_transform,
p_mat4[15] = 1;
}
+RID RasterizerCanvasRD::_create_texture_binding(RID p_texture, RID p_normalmap, RID p_specular, VisualServer::CanvasItemTextureFilter p_filter, VisualServer::CanvasItemTextureRepeat p_repeat, RID p_multimesh) {
+
+ Vector<RD::Uniform> uniform_set;
+
+ { // COLOR TEXTURE
+ RD::Uniform u;
+ u.type = RD::UNIFORM_TYPE_TEXTURE;
+ u.binding = 1;
+ RID texture = storage->texture_get_rd_texture(p_texture);
+ if (!texture.is_valid()) {
+ //use default white texture
+ texture = default_textures.white_texture;
+ }
+ u.ids.push_back(texture);
+ uniform_set.push_back(u);
+ }
+
+ { // NORMAL TEXTURE
+ RD::Uniform u;
+ u.type = RD::UNIFORM_TYPE_TEXTURE;
+ u.binding = 2;
+ RID texture = storage->texture_get_rd_texture(p_normalmap);
+ if (!texture.is_valid()) {
+ //use default normal texture
+ texture = default_textures.normal_texture;
+ }
+ u.ids.push_back(texture);
+ uniform_set.push_back(u);
+ }
+
+ { // SPECULAR TEXTURE
+ RD::Uniform u;
+ u.type = RD::UNIFORM_TYPE_TEXTURE;
+ u.binding = 3;
+ RID texture = storage->texture_get_rd_texture(p_specular);
+ if (!texture.is_valid()) {
+ //use default white texture
+ texture = default_textures.white_texture;
+ }
+ u.ids.push_back(texture);
+ uniform_set.push_back(u);
+ }
+
+ { // SAMPLER
+ RD::Uniform u;
+ u.type = RD::UNIFORM_TYPE_SAMPLER;
+ u.binding = 4;
+ RID sampler = default_samplers.samplers[p_filter][p_repeat];
+ ERR_FAIL_COND_V(sampler.is_null(), RID());
+ u.ids.push_back(sampler);
+ uniform_set.push_back(u);
+ }
+
+ { // MULTIMESH TEXTURE BUFFER
+ RD::Uniform u;
+ u.type = RD::UNIFORM_TYPE_TEXTURE_BUFFER;
+ u.binding = 5;
+ u.ids.push_back(default_textures.default_multimesh_tb);
+ uniform_set.push_back(u);
+ }
+
+ return RD::get_singleton()->uniform_set_create(uniform_set, shader.default_version_rd_shader, 0);
+}
+
RasterizerCanvas::TextureBindingID RasterizerCanvasRD::request_texture_binding(RID p_texture, RID p_normalmap, RID p_specular, VisualServer::CanvasItemTextureFilter p_filter, VisualServer::CanvasItemTextureRepeat p_repeat, RID p_multimesh) {
if (p_filter == VS::CANVAS_ITEM_TEXTURE_FILTER_DEFAULT) {
@@ -99,77 +173,7 @@ RasterizerCanvas::TextureBindingID RasterizerCanvasRD::request_texture_binding(R
}
if (binding->uniform_set.is_null() || !RD::get_singleton()->uniform_set_is_valid(binding->uniform_set)) {
- //needs to be re-created
-
- /* from GLSL:
- layout(set = 0, binding = 1) uniform texture2D color_texture;
- layout(set = 0, binding = 2) uniform texture2D normal_texture;
- layout(set = 0, binding = 3) uniform texture2D specular_texture;
- layout(set = 0, binding = 4) uniform sampler texture_sampler;
-
- layout(set = 0, binding = 5) uniform textureBuffer instancing_buffer;
- */
-
- Vector<RD::Uniform> uniform_set;
-
- { // COLOR TEXTURE
- RD::Uniform u;
- u.type = RD::UNIFORM_TYPE_TEXTURE;
- u.binding = 1;
- RID texture = storage->texture_get_rd_texture(p_texture);
- if (!texture.is_valid()) {
- //use default white texture
- texture = default_textures.white_texture;
- }
- u.ids.push_back(texture);
- uniform_set.push_back(u);
- }
-
- { // NORMAL TEXTURE
- RD::Uniform u;
- u.type = RD::UNIFORM_TYPE_TEXTURE;
- u.binding = 2;
- RID texture = storage->texture_get_rd_texture(p_normalmap);
- if (!texture.is_valid()) {
- //use default normal texture
- texture = default_textures.normal_texture;
- }
- u.ids.push_back(texture);
- uniform_set.push_back(u);
- }
-
- { // SPECULAR TEXTURE
- RD::Uniform u;
- u.type = RD::UNIFORM_TYPE_TEXTURE;
- u.binding = 3;
- RID texture = storage->texture_get_rd_texture(p_specular);
- if (!texture.is_valid()) {
- //use default white texture
- texture = default_textures.white_texture;
- }
- u.ids.push_back(texture);
- uniform_set.push_back(u);
- }
-
- { // SAMPLER
- RD::Uniform u;
- u.type = RD::UNIFORM_TYPE_SAMPLER;
- u.binding = 4;
- RID sampler = default_samplers.samplers[p_filter][p_repeat];
- ERR_FAIL_COND_V(sampler.is_null(), 0);
- u.ids.push_back(sampler);
- uniform_set.push_back(u);
- }
-
- { // MULTIMESH TEXTURE BUFFER
- RD::Uniform u;
- u.type = RD::UNIFORM_TYPE_TEXTURE_BUFFER;
- u.binding = 5;
- u.ids.push_back(default_textures.default_multimesh_tb);
- uniform_set.push_back(u);
- }
-
- binding->uniform_set = RD::get_singleton()->uniform_set_create(uniform_set, shader.default_version_rd_shader, 0);
+ binding->uniform_set = _create_texture_binding(p_texture, p_normalmap, p_specular, p_filter, p_repeat, p_multimesh);
}
return id;
@@ -191,7 +195,7 @@ void RasterizerCanvasRD::_dispose_bindings() {
while (bindings.to_dispose_list.first()) {
TextureBinding *binding = bindings.to_dispose_list.first()->self();
- if (binding->uniform_set.is_null() || !RD::get_singleton()->uniform_set_is_valid(binding->uniform_set)) {
+ if (binding->uniform_set.is_valid() && RD::get_singleton()->uniform_set_is_valid(binding->uniform_set)) {
RD::get_singleton()->free(binding->uniform_set);
}
@@ -202,14 +206,302 @@ void RasterizerCanvasRD::_dispose_bindings() {
}
}
-void RasterizerCanvasRD::_render_item(RD::DrawListID p_draw_list, const Item *p_item, RenderTargetFormat p_render_target_format, RD::TextureSamples p_samples, const Color &p_modulate, const Transform2D &p_canvas_transform_inverse) {
+RasterizerCanvas::PolygonID RasterizerCanvasRD::request_polygon(const Vector<int> &p_indices, const Vector<Point2> &p_points, const Vector<Color> &p_colors, const Vector<Point2> &p_uvs, const Vector<int> &p_bones, const Vector<float> &p_weights) {
+
+ // Care must be taken to generate array formats
+ // in ways where they could be reused, so we will
+ // put single-occuring elements first, and repeated
+ // elements later. This way the generated formats are
+ // the same no matter the length of the arrays.
+ // This dramatically reduces the amount of pipeline objects
+ // that need to be created for these formats.
+
+ uint32_t vertex_count = p_points.size();
+ uint32_t base_offset = 0;
+ uint32_t stride = 2; //vertices always repeat
+ if ((uint32_t)p_colors.size() == vertex_count) {
+ stride += 4;
+ } else {
+ base_offset += 4;
+ }
+ if ((uint32_t)p_uvs.size() == vertex_count) {
+ stride += 2;
+ } else {
+ base_offset += 2;
+ }
+ if ((uint32_t)p_bones.size() == vertex_count * 4) {
+ stride += 4;
+ } else {
+ base_offset += 4;
+ }
+ if ((uint32_t)p_weights.size() == vertex_count * 4) {
+ stride += 4;
+ } else {
+ base_offset += 4;
+ }
+
+ uint32_t buffer_size = base_offset + stride * p_points.size();
+
+ PoolVector<uint8_t> polygon_buffer;
+ polygon_buffer.resize(buffer_size * sizeof(float));
+ Vector<RD::VertexDescription> descriptions;
+ descriptions.resize(5);
+
+ {
+ PoolVector<uint8_t>::Read r = polygon_buffer.read();
+ float *fptr = (float *)r.ptr();
+ uint32_t *uptr = (uint32_t *)r.ptr();
+ uint32_t single_offset = 0;
+
+ { //vertices
+ RD::VertexDescription vd;
+ vd.format = RD::DATA_FORMAT_R32G32_SFLOAT;
+ vd.offset = base_offset * sizeof(float);
+ vd.location = VS::ARRAY_VERTEX;
+ vd.stride = stride * sizeof(float);
+
+ descriptions.write[0] = vd;
+
+ const Vector2 *points_ptr = p_points.ptr();
+
+ for (uint32_t i = 0; i < vertex_count; i++) {
+ fptr[base_offset + i * stride + 0] = points_ptr[i].x;
+ fptr[base_offset + i * stride + 1] = points_ptr[i].y;
+ }
+
+ base_offset += 2;
+ }
+
+ //colors
+ if ((uint32_t)p_colors.size() == vertex_count) {
+ RD::VertexDescription vd;
+ vd.format = RD::DATA_FORMAT_R32G32B32A32_SFLOAT;
+ vd.offset = base_offset * sizeof(float);
+ vd.location = VS::ARRAY_COLOR;
+ vd.stride = stride * sizeof(float);
+
+ descriptions.write[1] = vd;
+
+ const Color *color_ptr = p_colors.ptr();
+
+ for (uint32_t i = 0; i < vertex_count; i++) {
+ fptr[base_offset + i * stride + 0] = color_ptr[i].r;
+ fptr[base_offset + i * stride + 1] = color_ptr[i].g;
+ fptr[base_offset + i * stride + 2] = color_ptr[i].b;
+ fptr[base_offset + i * stride + 3] = color_ptr[i].a;
+ }
+ base_offset += 4;
+ } else {
+ RD::VertexDescription vd;
+ vd.format = RD::DATA_FORMAT_R32G32B32A32_SFLOAT;
+ vd.offset = single_offset * sizeof(float);
+ vd.location = VS::ARRAY_COLOR;
+ vd.stride = 0;
+
+ descriptions.write[1] = vd;
+
+ Color color = p_colors.size() ? p_colors[0] : Color(1, 1, 1, 1);
+ fptr[single_offset + 0] = color.r;
+ fptr[single_offset + 1] = color.g;
+ fptr[single_offset + 2] = color.b;
+ fptr[single_offset + 3] = color.a;
+
+ single_offset += 4;
+ }
+
+ //uvs
+ if ((uint32_t)p_uvs.size() == vertex_count) {
+ RD::VertexDescription vd;
+ vd.format = RD::DATA_FORMAT_R32G32_SFLOAT;
+ vd.offset = base_offset * sizeof(float);
+ vd.location = VS::ARRAY_TEX_UV;
+ vd.stride = stride * sizeof(float);
+
+ descriptions.write[2] = vd;
+
+ const Vector2 *uv_ptr = p_uvs.ptr();
+
+ for (uint32_t i = 0; i < vertex_count; i++) {
+ fptr[base_offset + i * stride + 0] = uv_ptr[i].x;
+ fptr[base_offset + i * stride + 1] = uv_ptr[i].y;
+ }
+ base_offset += 2;
+ } else {
+ RD::VertexDescription vd;
+ vd.format = RD::DATA_FORMAT_R32G32_SFLOAT;
+ vd.offset = single_offset * sizeof(float);
+ vd.location = VS::ARRAY_TEX_UV;
+ vd.stride = 0;
+
+ descriptions.write[2] = vd;
+
+ Vector2 uv;
+ fptr[single_offset + 0] = uv.x;
+ fptr[single_offset + 1] = uv.y;
+
+ single_offset += 2;
+ }
+
+ //bones
+ if ((uint32_t)p_indices.size() == vertex_count * 4) {
+ RD::VertexDescription vd;
+ vd.format = RD::DATA_FORMAT_R32G32B32A32_UINT;
+ vd.offset = base_offset * sizeof(float);
+ vd.location = VS::ARRAY_BONES;
+ vd.stride = stride * sizeof(float);
+
+ descriptions.write[3] = vd;
+
+ const int *bone_ptr = p_bones.ptr();
+
+ for (uint32_t i = 0; i < vertex_count; i++) {
+ uptr[base_offset + i * stride + 0] = bone_ptr[i * 4 + 0];
+ uptr[base_offset + i * stride + 1] = bone_ptr[i * 4 + 1];
+ uptr[base_offset + i * stride + 2] = bone_ptr[i * 4 + 2];
+ uptr[base_offset + i * stride + 3] = bone_ptr[i * 4 + 3];
+ }
+
+ base_offset += 4;
+ } else {
+ RD::VertexDescription vd;
+ vd.format = RD::DATA_FORMAT_R32G32B32A32_UINT;
+ vd.offset = single_offset * sizeof(float);
+ vd.location = VS::ARRAY_BONES;
+ vd.stride = 0;
+
+ descriptions.write[3] = vd;
+
+ uptr[single_offset + 0] = 0;
+ uptr[single_offset + 1] = 0;
+ uptr[single_offset + 2] = 0;
+ uptr[single_offset + 3] = 0;
+ single_offset += 4;
+ }
+
+ //bones
+ if ((uint32_t)p_weights.size() == vertex_count * 4) {
+ RD::VertexDescription vd;
+ vd.format = RD::DATA_FORMAT_R32G32B32A32_SFLOAT;
+ vd.offset = base_offset * sizeof(float);
+ vd.location = VS::ARRAY_WEIGHTS;
+ vd.stride = stride * sizeof(float);
+
+ descriptions.write[4] = vd;
+
+ const float *weight_ptr = p_weights.ptr();
+
+ for (uint32_t i = 0; i < vertex_count; i++) {
+ fptr[base_offset + i * stride + 0] = weight_ptr[i * 4 + 0];
+ fptr[base_offset + i * stride + 1] = weight_ptr[i * 4 + 1];
+ fptr[base_offset + i * stride + 2] = weight_ptr[i * 4 + 2];
+ fptr[base_offset + i * stride + 3] = weight_ptr[i * 4 + 3];
+ }
+
+ base_offset += 4;
+ } else {
+ RD::VertexDescription vd;
+ vd.format = RD::DATA_FORMAT_R32G32B32A32_SFLOAT;
+ vd.offset = single_offset * sizeof(float);
+ vd.location = VS::ARRAY_WEIGHTS;
+ vd.stride = 0;
+
+ descriptions.write[4] = vd;
+
+ fptr[single_offset + 0] = 0.0;
+ fptr[single_offset + 1] = 0.0;
+ fptr[single_offset + 2] = 0.0;
+ fptr[single_offset + 3] = 0.0;
+ single_offset += 4;
+ }
+
+ //check that everything is as it should be
+ ERR_FAIL_COND_V(single_offset != (base_offset - stride), 0);
+ ERR_FAIL_COND_V(((base_offset - stride) + stride * vertex_count) != buffer_size, 0);
+ }
+
+ RD::VertexFormatID vertex_id = RD::get_singleton()->vertex_format_create(descriptions);
+ ERR_FAIL_COND_V(vertex_id == RD::INVALID_ID, 0);
+
+ PolygonBuffers pb;
+ pb.vertex_buffer = RD::get_singleton()->vertex_buffer_create(polygon_buffer.size(), polygon_buffer);
+ Vector<RID> buffers;
+ buffers.resize(descriptions.size());
+ for (int i = 0; i < descriptions.size(); i++) {
+ buffers.write[i] = pb.vertex_buffer;
+ }
+ pb.vertex_array = RD::get_singleton()->vertex_array_create(p_points.size(), vertex_id, buffers);
+
+ if (p_indices.size()) {
+ //create indices, as indices were requested
+ PoolVector<uint8_t> index_buffer;
+ index_buffer.resize(p_indices.size() * sizeof(int32_t));
+ {
+ PoolVector<uint8_t>::Write w = index_buffer.write();
+ copymem(w.ptr(), p_indices.ptr(), sizeof(int32_t) * p_indices.size());
+ }
+ pb.index_buffer = RD::get_singleton()->index_buffer_create(p_indices.size(), RD::INDEX_BUFFER_FORMAT_UINT32, index_buffer);
+ pb.indices = RD::get_singleton()->index_array_create(pb.index_buffer, 0, p_indices.size());
+ }
+
+ pb.vertex_format_id = vertex_id;
+
+ PolygonID id = polygon_buffers.last_id++;
+
+ polygon_buffers.polygons[id] = pb;
+
+ return id;
+}
+
+void RasterizerCanvasRD::free_polygon(PolygonID p_polygon) {
+
+ PolygonBuffers *pb_ptr = polygon_buffers.polygons.getptr(p_polygon);
+ ERR_FAIL_COND(!pb_ptr);
+
+ PolygonBuffers &pb = *pb_ptr;
+
+ if (pb.indices.is_valid()) {
+ RD::get_singleton()->free(pb.indices);
+ }
+ if (pb.index_buffer.is_valid()) {
+ RD::get_singleton()->free(pb.index_buffer);
+ }
+
+ RD::get_singleton()->free(pb.vertex_array);
+ RD::get_singleton()->free(pb.vertex_buffer);
+
+ polygon_buffers.polygons.erase(p_polygon);
+}
+
+Size2i RasterizerCanvasRD::_bind_texture_binding(TextureBindingID p_binding, RD::DrawListID p_draw_list) {
+
+ TextureBinding **texture_binding_ptr = bindings.texture_bindings.getptr(p_binding);
+ ERR_FAIL_COND_V(!texture_binding_ptr, Size2i());
+ TextureBinding *texture_binding = *texture_binding_ptr;
+
+ if (!RD::get_singleton()->uniform_set_is_valid(texture_binding->uniform_set)) {
+ //texture may have changed (erased or replaced, see if we can fix)
+ texture_binding->uniform_set = _create_texture_binding(texture_binding->key.texture, texture_binding->key.normalmap, texture_binding->key.specular, texture_binding->key.texture_filter, texture_binding->key.texture_repeat, texture_binding->key.multimesh);
+ ERR_FAIL_COND_V(!texture_binding->uniform_set.is_valid(), Size2i(1, 1));
+ }
+
+ RD::get_singleton()->draw_list_bind_uniform_set(p_draw_list, texture_binding->uniform_set, 0);
+ if (texture_binding->key.texture.is_valid()) {
+ return storage->texture_2d_get_size(texture_binding->key.texture);
+ } else {
+ return Size2i(1, 1);
+ }
+}
+
+////////////////////
+void RasterizerCanvasRD::_render_item(RD::DrawListID p_draw_list, const Item *p_item, RenderTargetFormat p_render_target_format, RD::TextureSamples p_samples, const Color &p_modulate, const Transform2D &p_canvas_transform_inverse, Item *&current_clip) {
int cc = p_item->commands.size();
const Item::Command *const *commands = p_item->commands.ptr();
//create an empty push constant
PushConstant push_constant;
- _update_transform_2d_to_mat2x4(p_canvas_transform_inverse * p_item->final_transform, push_constant.world);
+ Transform2D base_transform = p_canvas_transform_inverse * p_item->final_transform;
+ _update_transform_2d_to_mat2x3(base_transform, push_constant.world);
for (int i = 0; i < 4; i++) {
push_constant.modulation[i] = 0;
push_constant.ninepatch_margins[i] = 0;
@@ -226,120 +518,14 @@ void RasterizerCanvasRD::_render_item(RD::DrawListID p_draw_list, const Item *p_
PipelineVariants *pipeline_variants = &shader.pipeline_variants;
+ bool reclip = false;
+
for (int i = 0; i < cc; i++) {
const Item::Command *c = commands[i];
push_constant.flags = 0; //reset on each command for sanity
switch (c->type) {
-#if 0
- case Item::Command::TYPE_LINE: {
-
- Item::CommandLine *line = static_cast<Item::CommandLine *>(c);
- _set_texture_rect_mode(false);
-
- _bind_canvas_texture(RID(), RID());
-
- glVertexAttrib4f(VS::ARRAY_COLOR, line->color.r, line->color.g, line->color.b, line->color.a);
-
- if (line->width <= 1) {
- Vector2 verts[2] = {
- Vector2(line->from.x, line->from.y),
- Vector2(line->to.x, line->to.y)
- };
-
-#ifdef GLES_OVER_GL
- if (line->antialiased)
- glEnable(GL_LINE_SMOOTH);
-#endif
- //glLineWidth(line->width);
- _draw_gui_primitive(2, verts, NULL, NULL);
-
-#ifdef GLES_OVER_GL
- if (line->antialiased)
- glDisable(GL_LINE_SMOOTH);
-#endif
- } else {
- //thicker line
-
- Vector2 t = (line->from - line->to).normalized().tangent() * line->width * 0.5;
-
- Vector2 verts[4] = {
- line->from - t,
- line->from + t,
- line->to + t,
- line->to - t,
- };
-
- //glLineWidth(line->width);
- _draw_gui_primitive(4, verts, NULL, NULL);
-#ifdef GLES_OVER_GL
- if (line->antialiased) {
- glEnable(GL_LINE_SMOOTH);
- for (int j = 0; j < 4; j++) {
- Vector2 vertsl[2] = {
- verts[j],
- verts[(j + 1) % 4],
- };
- _draw_gui_primitive(2, vertsl, NULL, NULL);
- }
- glDisable(GL_LINE_SMOOTH);
- }
-#endif
- }
-
- } break;
- case Item::Command::TYPE_POLYLINE: {
-
- Item::CommandPolyLine *pline = static_cast<Item::CommandPolyLine *>(c);
- _set_texture_rect_mode(false);
-
- _bind_canvas_texture(RID(), RID());
-
- if (pline->triangles.size()) {
-
- _draw_generic(GL_TRIANGLE_STRIP, pline->triangles.size(), pline->triangles.ptr(), NULL, pline->triangle_colors.ptr(), pline->triangle_colors.size() == 1);
-#ifdef GLES_OVER_GL
- glEnable(GL_LINE_SMOOTH);
- if (pline->multiline) {
- //needs to be different
- } else {
- _draw_generic(GL_LINE_LOOP, pline->lines.size(), pline->lines.ptr(), NULL, pline->line_colors.ptr(), pline->line_colors.size() == 1);
- }
- glDisable(GL_LINE_SMOOTH);
-#endif
- } else {
-
-#ifdef GLES_OVER_GL
- if (pline->antialiased)
- glEnable(GL_LINE_SMOOTH);
-#endif
-
- if (pline->multiline) {
- int todo = pline->lines.size() / 2;
- int max_per_call = data.polygon_buffer_size / (sizeof(real_t) * 4);
- int offset = 0;
-
- while (todo) {
- int to_draw = MIN(max_per_call, todo);
- _draw_generic(GL_LINES, to_draw * 2, &pline->lines.ptr()[offset], NULL, pline->line_colors.size() == 1 ? pline->line_colors.ptr() : &pline->line_colors.ptr()[offset], pline->line_colors.size() == 1);
- todo -= to_draw;
- offset += to_draw * 2;
- }
-
- } else {
-
- _draw_generic(GL_LINE_STRIP, pline->lines.size(), pline->lines.ptr(), NULL, pline->line_colors.ptr(), pline->line_colors.size() == 1);
- }
-
-#ifdef GLES_OVER_GL
- if (pline->antialiased)
- glDisable(GL_LINE_SMOOTH);
-#endif
- }
-
- } break;
-#endif
case Item::Command::TYPE_RECT: {
const Item::CommandRect *rect = static_cast<const Item::CommandRect *>(c);
@@ -354,18 +540,9 @@ void RasterizerCanvasRD::_render_item(RD::DrawListID p_draw_list, const Item *p_
Size2 texpixel_size;
{
- TextureBinding **texture_binding_ptr = bindings.texture_bindings.getptr(rect->texture_binding.binding_id);
- ERR_CONTINUE(!texture_binding_ptr);
- TextureBinding *texture_binding = *texture_binding_ptr;
-
- RD::get_singleton()->draw_list_bind_uniform_set(p_draw_list, texture_binding->uniform_set, 0);
- if (texture_binding->key.texture.is_valid()) {
- Size2i tex_size = storage->texture_2d_get_size(texture_binding->key.texture);
- if (tex_size.x != 0 && tex_size.y != 0) {
- texpixel_size.x = 1.0 / tex_size.x;
- texpixel_size.y = 1.0 / tex_size.y;
- }
- }
+ texpixel_size = _bind_texture_binding(rect->texture_binding.binding_id, p_draw_list);
+ texpixel_size.x = 1.0 / texpixel_size.x;
+ texpixel_size.y = 1.0 / texpixel_size.y;
}
Rect2 src_rect;
@@ -457,17 +634,9 @@ void RasterizerCanvasRD::_render_item(RD::DrawListID p_draw_list, const Item *p_
Size2 texpixel_size;
{
- TextureBinding **texture_binding_ptr = bindings.texture_bindings.getptr(np->texture_binding.binding_id);
- ERR_CONTINUE(!texture_binding_ptr);
- TextureBinding *texture_binding = *texture_binding_ptr;
- RD::get_singleton()->draw_list_bind_uniform_set(p_draw_list, texture_binding->uniform_set, 0);
- if (texture_binding->key.texture.is_valid()) {
- Size2i tex_size = storage->texture_2d_get_size(texture_binding->key.texture);
- if (tex_size.x != 0 && tex_size.y != 0) {
- texpixel_size.x = 1.0 / tex_size.x;
- texpixel_size.y = 1.0 / tex_size.y;
- }
- }
+ texpixel_size = _bind_texture_binding(np->texture_binding.binding_id, p_draw_list);
+ texpixel_size.x = 1.0 / texpixel_size.x;
+ texpixel_size.y = 1.0 / texpixel_size.y;
}
Rect2 src_rect;
@@ -491,7 +660,7 @@ void RasterizerCanvasRD::_render_item(RD::DrawListID p_draw_list, const Item *p_
push_constant.modulation[0] = np->color.r * p_modulate.r;
push_constant.modulation[1] = np->color.g * p_modulate.g;
push_constant.modulation[2] = np->color.b * p_modulate.b;
- push_constant.modulation[3] = np->color.a;
+ push_constant.modulation[3] = np->color.a * p_modulate.a;
push_constant.src_rect[0] = src_rect.position.x;
push_constant.src_rect[1] = src_rect.position.y;
@@ -523,54 +692,92 @@ void RasterizerCanvasRD::_render_item(RD::DrawListID p_draw_list, const Item *p_
RD::get_singleton()->draw_list_draw(p_draw_list, true);
} break;
-#if 0
-case Item::Command::TYPE_PRIMITIVE : {
+ case Item::Command::TYPE_POLYGON: {
- Item::CommandPrimitive *primitive = static_cast<Item::CommandPrimitive *>(c);
- _set_texture_rect_mode(false);
+ const Item::CommandPolygon *polygon = static_cast<const Item::CommandPolygon *>(c);
+
+ PolygonBuffers *pb = polygon_buffers.polygons.getptr(polygon->polygon.polygon_id);
+ ERR_CONTINUE(!pb);
+ //bind pipeline
+ {
+ static const PipelineVariant variant[VS::PRIMITIVE_MAX] = { PIPELINE_VARIANT_ATTRIBUTE_POINTS, PIPELINE_VARIANT_ATTRIBUTE_LINES, PIPELINE_VARIANT_ATTRIBUTE_TRIANGLES };
+ ERR_CONTINUE(polygon->primitive < 0 || polygon->primitive >= VS::PRIMITIVE_MAX);
+ RID pipeline = pipeline_variants->variants[p_render_target_format][variant[polygon->primitive]].get_render_pipeline(pb->vertex_format_id, p_samples);
+ RD::get_singleton()->draw_list_bind_render_pipeline(p_draw_list, pipeline);
+ }
- ERR_CONTINUE(primitive->points.size() < 1);
+ if (polygon->primitive == VS::PRIMITIVE_LINES) {
+ //not supported in most hardware, so pointless
+ //RD::get_singleton()->draw_list_set_line_width(p_draw_list, polygon->line_width);
+ }
- RasterizerStorageGLES3::Texture *texture = _bind_canvas_texture(primitive->texture, primitive->normal_map);
+ //bind textures
- if (texture) {
- Size2 texpixel_size(1.0 / texture->width, 1.0 / texture->height);
- state.canvas_shader.set_uniform(CanvasShaderGLES3::COLOR_TEXPIXEL_SIZE, texpixel_size);
+ Size2 texpixel_size;
+ {
+ texpixel_size = _bind_texture_binding(polygon->texture_binding.binding_id, p_draw_list);
+ texpixel_size.x = 1.0 / texpixel_size.x;
+ texpixel_size.y = 1.0 / texpixel_size.y;
}
- if (primitive->colors.size() == 1 && primitive->points.size() > 1) {
- Color col = primitive->colors[0];
- glVertexAttrib4f(VS::ARRAY_COLOR, col.r, col.g, col.b, col.a);
+ push_constant.modulation[0] = p_modulate.r;
+ push_constant.modulation[1] = p_modulate.g;
+ push_constant.modulation[2] = p_modulate.b;
+ push_constant.modulation[3] = p_modulate.a;
- } else if (primitive->colors.empty()) {
- glVertexAttrib4f(VS::ARRAY_COLOR, 1, 1, 1, 1);
+ for (int j = 0; j < 4; j++) {
+ push_constant.src_rect[j] = 0;
+ push_constant.dst_rect[j] = 0;
+ push_constant.ninepatch_margins[j] = 0;
}
- _draw_gui_primitive(primitive->points.size(), primitive->points.ptr(), primitive->colors.ptr(), primitive->uvs.ptr());
+ push_constant.color_texture_pixel_size[0] = texpixel_size.x;
+ push_constant.color_texture_pixel_size[1] = texpixel_size.y;
+
+ RD::get_singleton()->draw_list_set_push_constant(p_draw_list, &push_constant, sizeof(PushConstant));
+ RD::get_singleton()->draw_list_bind_vertex_array(p_draw_list, pb->vertex_array);
+ if (pb->indices.is_valid()) {
+ RD::get_singleton()->draw_list_bind_index_array(p_draw_list, pb->indices);
+ }
+ RD::get_singleton()->draw_list_draw(p_draw_list, pb->indices.is_valid());
} break;
- case Item::Command::TYPE_POLYGON: {
+ case Item::Command::TYPE_PRIMITIVE: {
- Item::CommandPolygon *polygon = static_cast<Item::CommandPolygon *>(c);
- _set_texture_rect_mode(false);
+ const Item::CommandPrimitive *primitive = static_cast<const Item::CommandPrimitive *>(c);
- RasterizerStorageGLES3::Texture *texture = _bind_canvas_texture(polygon->texture, polygon->normal_map);
+ //bind pipeline
+ {
+ static const PipelineVariant variant[4] = { PIPELINE_VARIANT_PRIMITIVE_POINTS, PIPELINE_VARIANT_PRIMITIVE_LINES, PIPELINE_VARIANT_PRIMITIVE_TRIANGLES, PIPELINE_VARIANT_PRIMITIVE_TRIANGLES };
+ ERR_CONTINUE(primitive->point_count == 0 || primitive->point_count > 4);
+ RID pipeline = pipeline_variants->variants[p_render_target_format][variant[primitive->point_count - 1]].get_render_pipeline(RD::INVALID_ID, p_samples);
+ RD::get_singleton()->draw_list_bind_render_pipeline(p_draw_list, pipeline);
+ }
- if (texture) {
- Size2 texpixel_size(1.0 / texture->width, 1.0 / texture->height);
- state.canvas_shader.set_uniform(CanvasShaderGLES3::COLOR_TEXPIXEL_SIZE, texpixel_size);
+ //bind textures
+
+ {
+ _bind_texture_binding(primitive->texture_binding.binding_id, p_draw_list);
}
- _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);
- _draw_generic(GL_LINE_LOOP, polygon->points.size(), polygon->points.ptr(), polygon->uvs.ptr(), polygon->colors.ptr(), polygon->colors.size() == 1);
- glDisable(GL_LINE_SMOOTH);
+ for (uint32_t j = 0; j < primitive->point_count; j++) {
+ push_constant.points[j * 2 + 0] = primitive->points[j].x;
+ push_constant.points[j * 2 + 1] = primitive->points[j].y;
+ push_constant.uvs[j * 2 + 0] = primitive->uvs[j].x;
+ push_constant.uvs[j * 2 + 1] = primitive->uvs[j].y;
+ Color col = primitive->colors[j] * p_modulate;
+ push_constant.colors[j * 2 + 0] = (uint32_t(Math::make_half_float(col.g)) << 16) | Math::make_half_float(col.r);
+ push_constant.colors[j * 2 + 1] = (uint32_t(Math::make_half_float(col.a)) << 16) | Math::make_half_float(col.b);
}
-#endif
+ RD::get_singleton()->draw_list_set_push_constant(p_draw_list, &push_constant, sizeof(PushConstant));
+
+ RD::get_singleton()->draw_list_bind_index_array(p_draw_list, primitive_arrays.index_array[primitive->point_count - 1]);
+
+ RD::get_singleton()->draw_list_draw(p_draw_list, true);
} break;
+
+#if 0
case Item::Command::TYPE_MESH: {
Item::CommandMesh *mesh = static_cast<Item::CommandMesh *>(c);
@@ -850,70 +1057,43 @@ case Item::Command::TYPE_PRIMITIVE : {
_set_texture_rect_mode(false);
} break;
- case Item::Command::TYPE_CIRCLE: {
-
- _set_texture_rect_mode(false);
-
- Item::CommandCircle *circle = static_cast<Item::CommandCircle *>(c);
- static const int numpoints = 32;
- Vector2 points[numpoints + 1];
- points[numpoints] = circle->pos;
- int indices[numpoints * 3];
-
- for (int j = 0; j < numpoints; j++) {
-
- points[j] = circle->pos + Vector2(Math::sin(j * Math_PI * 2.0 / numpoints), Math::cos(j * Math_PI * 2.0 / numpoints)) * circle->radius;
- indices[j * 3 + 0] = j;
- indices[j * 3 + 1] = (j + 1) % numpoints;
- indices[j * 3 + 2] = numpoints;
- }
-
- _bind_canvas_texture(RID(), RID());
- _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);
- } break;
+#endif
case Item::Command::TYPE_TRANSFORM: {
- Item::CommandTransform *transform = static_cast<Item::CommandTransform *>(c);
- state.extra_matrix = transform->xform;
- state.canvas_shader.set_uniform(CanvasShaderGLES3::EXTRA_MATRIX, state.extra_matrix);
+ const Item::CommandTransform *transform = static_cast<const Item::CommandTransform *>(c);
+ base_transform = base_transform * transform->xform;
+ _update_transform_2d_to_mat2x3(base_transform, push_constant.world);
} break;
case Item::Command::TYPE_CLIP_IGNORE: {
- Item::CommandClipIgnore *ci = static_cast<Item::CommandClipIgnore *>(c);
+ const Item::CommandClipIgnore *ci = static_cast<const Item::CommandClipIgnore *>(c);
if (current_clip) {
if (ci->ignore != reclip) {
- if (ci->ignore) {
- glDisable(GL_SCISSOR_TEST);
+ if (ci->ignore) {
+ RD::get_singleton()->draw_list_disable_scissor(p_draw_list);
reclip = true;
} else {
- glEnable(GL_SCISSOR_TEST);
- //glScissor(viewport.x+current_clip->final_clip_rect.pos.x,viewport.y+ (viewport.height-(current_clip->final_clip_rect.pos.y+current_clip->final_clip_rect.size.height)),
- //current_clip->final_clip_rect.size.width,current_clip->final_clip_rect.size.height);
- int y = storage->frame.current_rt->height - (current_clip->final_clip_rect.position.y + current_clip->final_clip_rect.size.y);
- if (storage->frame.current_rt->flags[RasterizerStorage::RENDER_TARGET_VFLIP])
- y = current_clip->final_clip_rect.position.y;
-
- glScissor(current_clip->final_clip_rect.position.x, y, current_clip->final_clip_rect.size.x, current_clip->final_clip_rect.size.y);
-
+ RD::get_singleton()->draw_list_enable_scissor(p_draw_list, current_clip->final_clip_rect);
reclip = false;
}
}
}
} break;
-#endif
}
}
+
+ if (current_clip && reclip) {
+ //will make it re-enable clipping if needed afterwards
+ current_clip = NULL;
+ }
}
-void RasterizerCanvasRD::_render_items(RID p_to_render_target, bool p_clear, const Color &p_clear_color, int p_item_count, const Color &p_modulate, const Transform2D &p_transform) {
+void RasterizerCanvasRD::_render_items(RID p_to_render_target, int p_item_count, const Color &p_modulate, const Transform2D &p_transform) {
Item *current_clip = NULL;
@@ -923,12 +1103,15 @@ void RasterizerCanvasRD::_render_items(RID p_to_render_target, bool p_clear, con
RID framebuffer = storage->render_target_get_rd_framebuffer(p_to_render_target);
Vector<Color> clear_colors;
- if (p_clear) {
- clear_colors.push_back(p_clear_color);
+ bool clear = false;
+ if (storage->render_target_is_clear_requested(p_to_render_target)) {
+ clear = true;
+ clear_colors.push_back(storage->render_target_get_clear_request_color(p_to_render_target));
+ storage->render_target_disable_clear_request(p_to_render_target);
}
#warning TODO obtain from framebuffer format eventually when this is implemented
RD::TextureSamples texture_samples = RD::TEXTURE_SAMPLES_1;
- RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(framebuffer, p_clear ? RD::INITIAL_ACTION_CLEAR : RD::INITIAL_ACTION_KEEP_COLOR, RD::FINAL_ACTION_READ_COLOR_DISCARD_DEPTH, clear_colors);
+ RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(framebuffer, clear ? RD::INITIAL_ACTION_CLEAR : RD::INITIAL_ACTION_KEEP_COLOR, RD::FINAL_ACTION_READ_COLOR_DISCARD_DEPTH, clear_colors);
RD::get_singleton()->draw_list_bind_uniform_set(draw_list, state.canvas_state_uniform_set, 3);
@@ -953,10 +1136,10 @@ void RasterizerCanvasRD::_render_items(RID p_to_render_target, bool p_clear, con
if (false) { //not skeleton
- RD::get_singleton()->draw_list_bind_uniform_set(draw_list, shader.default_material_uniform_set, 1);
+ RD::get_singleton()->draw_list_bind_uniform_set(draw_list, shader.default_skeleton_uniform_set, 1);
}
- _render_item(draw_list, ci, render_target_format, texture_samples, p_modulate, canvas_transform_inverse);
+ _render_item(draw_list, ci, render_target_format, texture_samples, p_modulate, canvas_transform_inverse, current_clip);
}
RD::get_singleton()->draw_list_end();
@@ -979,7 +1162,7 @@ void RasterizerCanvasRD::_update_canvas_state_uniform_set() {
state.canvas_state_uniform_set = RD::get_singleton()->uniform_set_create(uniforms, shader.default_version_rd_shader, 3); // uses index 3
}
-void RasterizerCanvasRD::canvas_render_items(RID p_to_render_target, bool p_clear, const Color &p_clear_color, Item *p_item_list, const Color &p_modulate, Light *p_light_list, const Transform2D &p_canvas_transform) {
+void RasterizerCanvasRD::canvas_render_items(RID p_to_render_target, Item *p_item_list, const Color &p_modulate, Light *p_light_list, const Transform2D &p_canvas_transform) {
int item_count = 0;
@@ -1008,10 +1191,9 @@ void RasterizerCanvasRD::canvas_render_items(RID p_to_render_target, bool p_clea
bool backbuffer_copy = ci->copy_back_buffer; // || shader uses SCREEN_TEXTURE
if (!ci->next || backbuffer_copy || item_count == MAX_RENDER_ITEMS - 1) {
- _render_items(p_to_render_target, p_clear, p_clear_color, item_count, p_modulate, p_canvas_transform);
+ _render_items(p_to_render_target, item_count, p_modulate, p_canvas_transform);
//then reset
item_count = 0;
- p_clear = false;
}
if (ci->copy_back_buffer) {
@@ -1170,8 +1352,10 @@ RasterizerCanvasRD::RasterizerCanvasRD(RasterizerStorageRD *p_storage) {
Vector<String> variants;
variants.push_back(""); //none by default is first variant
variants.push_back("#define USE_NINEPATCH\n"); //ninepatch is the second variant
- variants.push_back("#define USE_VERTEX_ARRAYS\n"); //vertex arrays is the last variant
- variants.push_back("#define USE_POINT_SIZE\n"); //for point drawing
+ variants.push_back("#define USE_PRIMITIVE\n"); //primitve is the third
+ variants.push_back("#define USE_PRIMITIVE\n#define USE_POINT_SIZE\n"); //points need point size
+ variants.push_back("#define USE_ATTRIBUTES\n"); // attributes for vertex arrays
+ variants.push_back("#define USE_ATTRIBUTES\n#define USE_POINT_SIZE\n"); //attributes with point size
shader.canvas_shader.initialize(variants);
shader.default_version = shader.canvas_shader.version_create();
@@ -1195,11 +1379,29 @@ RasterizerCanvasRD::RasterizerCanvasRD(RasterizerStorageRD *p_storage) {
for (int i = 0; i < RENDER_TARGET_FORMAT_MAX; i++) {
RD::FramebufferFormatID fb_format = shader.framebuffer_formats[i];
for (int j = 0; j < PIPELINE_VARIANT_MAX; j++) {
- RD::RenderPrimitive primitive[PIPELINE_VARIANT_MAX] = { RD::RENDER_PRIMITIVE_TRIANGLES, RD::RENDER_PRIMITIVE_TRIANGLES, RD::RENDER_PRIMITIVE_TRIANGLES, RD::RENDER_PRIMITIVE_LINES, RD::RENDER_PRIMITIVE_POINTS };
- ShaderVariant shader_variants[PIPELINE_VARIANT_MAX] = { SHADER_VARIANT_QUAD, SHADER_VARIANT_NINEPATCH, SHADER_VARIANT_VERTICES, SHADER_VARIANT_VERTICES, SHADER_VARIANT_POINTS };
+ RD::RenderPrimitive primitive[PIPELINE_VARIANT_MAX] = {
+ RD::RENDER_PRIMITIVE_TRIANGLES,
+ RD::RENDER_PRIMITIVE_TRIANGLES,
+ RD::RENDER_PRIMITIVE_TRIANGLES,
+ RD::RENDER_PRIMITIVE_LINES,
+ RD::RENDER_PRIMITIVE_POINTS,
+ RD::RENDER_PRIMITIVE_TRIANGLES,
+ RD::RENDER_PRIMITIVE_LINES,
+ RD::RENDER_PRIMITIVE_POINTS,
+ };
+ ShaderVariant shader_variants[PIPELINE_VARIANT_MAX] = {
+ SHADER_VARIANT_QUAD,
+ SHADER_VARIANT_NINEPATCH,
+ SHADER_VARIANT_PRIMITIVE,
+ SHADER_VARIANT_PRIMITIVE,
+ SHADER_VARIANT_PRIMITIVE_POINTS,
+ SHADER_VARIANT_ATTRIBUTES,
+ SHADER_VARIANT_ATTRIBUTES,
+ SHADER_VARIANT_ATTRIBUTES_POINTS
+ };
RID shader_variant = shader.canvas_shader.version_get_shader(shader.default_version, shader_variants[j]);
- shader.pipeline_variants.variants[i][j].setup(shader_variant, fb_format, primitive[j], RD::PipelineRasterizationState(), RD::PipelineMultisampleState(), RD::PipelineDepthStencilState(), RD::PipelineColorBlendState::create_blend(), j == PIPELINE_VARIANT_LINES ? RD::DYNAMIC_STATE_LINE_WIDTH : 0);
+ shader.pipeline_variants.variants[i][j].setup(shader_variant, fb_format, primitive[j], RD::PipelineRasterizationState(), RD::PipelineMultisampleState(), RD::PipelineDepthStencilState(), RD::PipelineColorBlendState::create_blend(), 0);
}
}
@@ -1216,6 +1418,11 @@ RasterizerCanvasRD::RasterizerCanvasRD(RasterizerStorageRD *p_storage) {
}
}
+ {
+ //polygon buffers
+ polygon_buffers.last_id = 1;
+ }
+
{ // default index buffer
PoolVector<uint8_t> pv;
@@ -1230,17 +1437,24 @@ RasterizerCanvasRD::RasterizerCanvasRD(RasterizerStorageRD *p_storage) {
p32[4] = 2;
p32[5] = 3;
}
- RID index_buffer = RD::get_singleton()->index_buffer_create(6, RenderingDevice::INDEX_BUFFER_FORMAT_UINT32, pv);
- shader.quad_index_array = RD::get_singleton()->index_array_create(index_buffer, 0, 6);
+ shader.quad_index_buffer = RD::get_singleton()->index_buffer_create(6, RenderingDevice::INDEX_BUFFER_FORMAT_UINT32, pv);
+ shader.quad_index_array = RD::get_singleton()->index_array_create(shader.quad_index_buffer, 0, 6);
+ }
+
+ { //primitive
+ primitive_arrays.index_array[0] = shader.quad_index_array = RD::get_singleton()->index_array_create(shader.quad_index_buffer, 0, 1);
+ primitive_arrays.index_array[1] = shader.quad_index_array = RD::get_singleton()->index_array_create(shader.quad_index_buffer, 0, 2);
+ primitive_arrays.index_array[2] = shader.quad_index_array = RD::get_singleton()->index_array_create(shader.quad_index_buffer, 0, 3);
+ primitive_arrays.index_array[3] = shader.quad_index_array = RD::get_singleton()->index_array_create(shader.quad_index_buffer, 0, 6);
}
{ //default skeleton buffer
- shader.default_material_skeleton_uniform = RD::get_singleton()->uniform_buffer_create(sizeof(SkeletonUniform));
+ shader.default_skeleton_uniform = RD::get_singleton()->uniform_buffer_create(sizeof(SkeletonUniform));
SkeletonUniform su;
_update_transform_2d_to_mat4(Transform2D(), su.skeleton_inverse);
_update_transform_2d_to_mat4(Transform2D(), su.skeleton_transform);
- RD::get_singleton()->buffer_update(shader.default_material_skeleton_uniform, 0, sizeof(SkeletonUniform), &su);
+ RD::get_singleton()->buffer_update(shader.default_skeleton_uniform, 0, sizeof(SkeletonUniform), &su);
}
{ //default material uniform set
@@ -1248,7 +1462,7 @@ RasterizerCanvasRD::RasterizerCanvasRD(RasterizerStorageRD *p_storage) {
RD::Uniform u;
u.type = RD::UNIFORM_TYPE_UNIFORM_BUFFER;
u.binding = 2;
- u.ids.push_back(shader.default_material_skeleton_uniform);
+ u.ids.push_back(shader.default_skeleton_uniform);
default_material_uniforms.push_back(u);
u.ids.clear();
@@ -1257,8 +1471,68 @@ RasterizerCanvasRD::RasterizerCanvasRD(RasterizerStorageRD *p_storage) {
u.ids.push_back(default_textures.default_multimesh_tb);
default_material_uniforms.push_back(u);
- shader.default_material_uniform_set = RD::get_singleton()->uniform_set_create(default_material_uniforms, shader.default_version_rd_shader, 1);
+ shader.default_skeleton_uniform_set = RD::get_singleton()->uniform_set_create(default_material_uniforms, shader.canvas_shader.version_get_shader(shader.default_version, SHADER_VARIANT_ATTRIBUTES), 2);
}
ERR_FAIL_COND(sizeof(PushConstant) != 128);
}
+
+RasterizerCanvasRD::~RasterizerCanvasRD() {
+
+ //canvas state
+
+ if (state.canvas_state_buffer.is_valid()) {
+ RD::get_singleton()->free(state.canvas_state_buffer);
+ }
+
+ if (state.canvas_state_uniform_set.is_valid() && RD::get_singleton()->uniform_set_is_valid(state.canvas_state_uniform_set)) {
+ RD::get_singleton()->free(state.canvas_state_uniform_set);
+ }
+
+ //bindings
+ {
+
+ free_texture_binding(bindings.default_empty);
+
+ //dispose pending
+ _dispose_bindings();
+ //anything remains?
+ if (bindings.texture_bindings.size()) {
+ ERR_PRINT("Some texture bindings were not properly freed (leaked canvasitems?");
+ const TextureBindingID *key = NULL;
+ while ((key = bindings.texture_bindings.next(key))) {
+ TextureBinding *tb = bindings.texture_bindings[*key];
+ tb->reference_count = 1;
+ free_texture_binding(*key);
+ }
+ //dispose pending
+ _dispose_bindings();
+ }
+ }
+
+ //shaders
+
+ RD::get_singleton()->free(shader.default_skeleton_uniform_set);
+ RD::get_singleton()->free(shader.default_skeleton_uniform);
+ shader.canvas_shader.version_free(shader.default_version);
+
+ //buffers
+ RD::get_singleton()->free(shader.quad_index_array);
+ RD::get_singleton()->free(shader.quad_index_buffer);
+
+ //pipelines don't need freeing, they are all gone after shaders are gone
+
+ //samplers
+ for (int i = 1; i < VS::CANVAS_ITEM_TEXTURE_FILTER_MAX; i++) {
+ for (int j = 1; j < VS::CANVAS_ITEM_TEXTURE_REPEAT_MAX; j++) {
+ RD::get_singleton()->free(default_samplers.samplers[i][j]);
+ }
+ }
+
+ //textures
+ RD::get_singleton()->free(default_textures.white_texture);
+ RD::get_singleton()->free(default_textures.black_texture);
+ RD::get_singleton()->free(default_textures.normal_texture);
+ RD::get_singleton()->free(default_textures.aniso_texture);
+ RD::get_singleton()->free(default_textures.default_multimesh_tb);
+}