summaryrefslogtreecommitdiff
path: root/drivers/gles3
diff options
context:
space:
mode:
authorJuan Linietsky <reduzio@gmail.com>2018-08-29 16:48:32 -0300
committerJuan Linietsky <reduzio@gmail.com>2018-08-29 16:48:55 -0300
commitcf834a22dc78950a9fba484a7f9db98da84cae59 (patch)
treeb9d2e1674b3f1a8a90771889c762ac74930344de /drivers/gles3
parent7b7f4b20cb6070b632824915033fca0d181b4c7f (diff)
Ported CPU particles to 2D
Diffstat (limited to 'drivers/gles3')
-rw-r--r--drivers/gles3/rasterizer_canvas_gles3.cpp114
1 files changed, 114 insertions, 0 deletions
diff --git a/drivers/gles3/rasterizer_canvas_gles3.cpp b/drivers/gles3/rasterizer_canvas_gles3.cpp
index 643d50797e..da87a71679 100644
--- a/drivers/gles3/rasterizer_canvas_gles3.cpp
+++ b/drivers/gles3/rasterizer_canvas_gles3.cpp
@@ -832,6 +832,120 @@ void RasterizerCanvasGLES3::_canvas_item_render_commands(Item *p_item, Item *cur
}
}
} break;
+ case Item::Command::TYPE_MULTIMESH: {
+
+ Item::CommandMultiMesh *mmesh = static_cast<Item::CommandMultiMesh *>(c);
+
+ RasterizerStorageGLES3::MultiMesh *multi_mesh = storage->multimesh_owner.getornull(mmesh->multimesh);
+
+ if (!multi_mesh)
+ break;
+
+ RasterizerStorageGLES3::Mesh *mesh_data = storage->mesh_owner.getornull(multi_mesh->mesh);
+
+ if (!mesh_data)
+ break;
+
+ RasterizerStorageGLES3::Texture *texture = _bind_canvas_texture(mmesh->texture, mmesh->normal_map);
+
+ state.canvas_shader.set_conditional(CanvasShaderGLES3::USE_INSTANCE_CUSTOM, multi_mesh->custom_data_format != VS::MULTIMESH_CUSTOM_DATA_NONE);
+ state.canvas_shader.set_conditional(CanvasShaderGLES3::USE_INSTANCING, true);
+ //reset shader and force rebind
+ state.using_texture_rect = true;
+ _set_texture_rect_mode(false);
+
+ if (texture) {
+ Size2 texpixel_size(1.0 / texture->width, 1.0 / texture->height);
+ state.canvas_shader.set_uniform(CanvasShaderGLES3::COLOR_TEXPIXEL_SIZE, texpixel_size);
+ }
+
+ int amount = MAX(multi_mesh->size, multi_mesh->visible_instances);
+
+ for (int j = 0; j < mesh_data->surfaces.size(); j++) {
+ RasterizerStorageGLES3::Surface *s = mesh_data->surfaces[j];
+ // materials are ignored in 2D meshes, could be added but many things (ie, lighting mode, reading from screen, etc) would break as they are not meant be set up at this point of drawing
+ glBindVertexArray(s->instancing_array_id);
+
+ glBindBuffer(GL_ARRAY_BUFFER, multi_mesh->buffer); //modify the buffer
+
+ int stride = (multi_mesh->xform_floats + multi_mesh->color_floats + multi_mesh->custom_data_floats) * 4;
+ glEnableVertexAttribArray(8);
+ glVertexAttribPointer(8, 4, GL_FLOAT, GL_FALSE, stride, ((uint8_t *)NULL) + 0);
+ glVertexAttribDivisor(8, 1);
+ glEnableVertexAttribArray(9);
+ glVertexAttribPointer(9, 4, GL_FLOAT, GL_FALSE, stride, ((uint8_t *)NULL) + 4 * 4);
+ glVertexAttribDivisor(9, 1);
+
+ int color_ofs;
+
+ if (multi_mesh->transform_format == VS::MULTIMESH_TRANSFORM_3D) {
+ glEnableVertexAttribArray(10);
+ glVertexAttribPointer(10, 4, GL_FLOAT, GL_FALSE, stride, ((uint8_t *)NULL) + 8 * 4);
+ glVertexAttribDivisor(10, 1);
+ color_ofs = 12 * 4;
+ } else {
+ glDisableVertexAttribArray(10);
+ glVertexAttrib4f(10, 0, 0, 1, 0);
+ color_ofs = 8 * 4;
+ }
+
+ int custom_data_ofs = color_ofs;
+
+ switch (multi_mesh->color_format) {
+
+ case VS::MULTIMESH_COLOR_NONE: {
+ glDisableVertexAttribArray(11);
+ glVertexAttrib4f(11, 1, 1, 1, 1);
+ } break;
+ case VS::MULTIMESH_COLOR_8BIT: {
+ glEnableVertexAttribArray(11);
+ glVertexAttribPointer(11, 4, GL_UNSIGNED_BYTE, GL_TRUE, stride, ((uint8_t *)NULL) + color_ofs);
+ glVertexAttribDivisor(11, 1);
+ custom_data_ofs += 4;
+
+ } break;
+ case VS::MULTIMESH_COLOR_FLOAT: {
+ glEnableVertexAttribArray(11);
+ glVertexAttribPointer(11, 4, GL_FLOAT, GL_FALSE, stride, ((uint8_t *)NULL) + color_ofs);
+ glVertexAttribDivisor(11, 1);
+ custom_data_ofs += 4 * 4;
+ } break;
+ }
+
+ switch (multi_mesh->custom_data_format) {
+
+ case VS::MULTIMESH_CUSTOM_DATA_NONE: {
+ glDisableVertexAttribArray(12);
+ glVertexAttrib4f(12, 1, 1, 1, 1);
+ } break;
+ case VS::MULTIMESH_CUSTOM_DATA_8BIT: {
+ glEnableVertexAttribArray(12);
+ glVertexAttribPointer(12, 4, GL_UNSIGNED_BYTE, GL_TRUE, stride, ((uint8_t *)NULL) + custom_data_ofs);
+ glVertexAttribDivisor(12, 1);
+
+ } break;
+ case VS::MULTIMESH_CUSTOM_DATA_FLOAT: {
+ glEnableVertexAttribArray(12);
+ glVertexAttribPointer(12, 4, GL_FLOAT, GL_FALSE, stride, ((uint8_t *)NULL) + custom_data_ofs);
+ glVertexAttribDivisor(12, 1);
+ } break;
+ }
+
+ if (s->index_array_len) {
+ glDrawElementsInstanced(gl_primitive[s->primitive], s->index_array_len, (s->array_len >= (1 << 16)) ? GL_UNSIGNED_INT : GL_UNSIGNED_SHORT, 0, amount);
+ } else {
+ glDrawArraysInstanced(gl_primitive[s->primitive], 0, s->array_len, amount);
+ }
+
+ glBindVertexArray(0);
+ }
+
+ state.canvas_shader.set_conditional(CanvasShaderGLES3::USE_INSTANCE_CUSTOM, false);
+ state.canvas_shader.set_conditional(CanvasShaderGLES3::USE_INSTANCING, false);
+ state.using_texture_rect = true;
+ _set_texture_rect_mode(false);
+
+ } break;
case Item::Command::TYPE_PARTICLES: {
Item::CommandParticles *particles_cmd = static_cast<Item::CommandParticles *>(c);