diff options
Diffstat (limited to 'drivers/gles3/rasterizer_canvas_gles3.cpp')
-rw-r--r-- | drivers/gles3/rasterizer_canvas_gles3.cpp | 143 |
1 files changed, 131 insertions, 12 deletions
diff --git a/drivers/gles3/rasterizer_canvas_gles3.cpp b/drivers/gles3/rasterizer_canvas_gles3.cpp index edffe852a2..b7b31c66aa 100644 --- a/drivers/gles3/rasterizer_canvas_gles3.cpp +++ b/drivers/gles3/rasterizer_canvas_gles3.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -128,7 +128,7 @@ void RasterizerCanvasGLES3::light_internal_update(RID p_rid, Light *p_light) { li->ubo_data.shadow_distance_mult = (p_light->radius_cache * 1.1); glBindBuffer(GL_UNIFORM_BUFFER, li->ubo); - glBufferSubData(GL_UNIFORM_BUFFER, 0, sizeof(LightInternal::UBOData), &li->ubo_data); + glBufferData(GL_UNIFORM_BUFFER, sizeof(LightInternal::UBOData), &li->ubo_data, GL_DYNAMIC_DRAW); glBindBuffer(GL_UNIFORM_BUFFER, 0); } @@ -326,6 +326,11 @@ void RasterizerCanvasGLES3::_draw_polygon(const int *p_indices, int p_index_coun glBindVertexArray(data.polygon_buffer_pointer_array); glBindBuffer(GL_ARRAY_BUFFER, data.polygon_buffer); +#ifndef GLES_OVER_GL + // Orphan the buffer to avoid CPU/GPU sync points caused by glBufferSubData + glBufferData(GL_ARRAY_BUFFER, data.polygon_buffer_size, NULL, GL_DYNAMIC_DRAW); +#endif + uint32_t buffer_ofs = 0; //vertex @@ -396,6 +401,10 @@ void RasterizerCanvasGLES3::_draw_polygon(const int *p_indices, int p_index_coun //bind the indices buffer. glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, data.polygon_index_buffer); +#ifndef GLES_OVER_GL + // Orphan the buffer to avoid CPU/GPU sync points caused by glBufferSubData + glBufferData(GL_ELEMENT_ARRAY_BUFFER, data.polygon_index_buffer_size, NULL, GL_DYNAMIC_DRAW); +#endif glBufferSubData(GL_ELEMENT_ARRAY_BUFFER, 0, sizeof(int) * p_index_count, p_indices); //draw the triangles. @@ -410,6 +419,7 @@ void RasterizerCanvasGLES3::_draw_polygon(const int *p_indices, int p_index_coun } glBindVertexArray(0); + glBindBuffer(GL_ARRAY_BUFFER, 0); } void RasterizerCanvasGLES3::_draw_generic(GLuint p_primitive, int p_vertex_count, const Vector2 *p_vertices, const Vector2 *p_uvs, const Color *p_colors, bool p_singlecolor) { @@ -417,6 +427,11 @@ void RasterizerCanvasGLES3::_draw_generic(GLuint p_primitive, int p_vertex_count glBindVertexArray(data.polygon_buffer_pointer_array); glBindBuffer(GL_ARRAY_BUFFER, data.polygon_buffer); +#ifndef GLES_OVER_GL + // Orphan the buffer to avoid CPU/GPU sync points caused by glBufferSubData + glBufferData(GL_ARRAY_BUFFER, data.polygon_buffer_size, NULL, GL_DYNAMIC_DRAW); +#endif + uint32_t buffer_ofs = 0; //vertex @@ -457,6 +472,80 @@ void RasterizerCanvasGLES3::_draw_generic(GLuint p_primitive, int p_vertex_count storage->frame.canvas_draw_commands++; glBindVertexArray(0); + glBindBuffer(GL_ARRAY_BUFFER, 0); +} + +void RasterizerCanvasGLES3::_draw_generic_indices(GLuint p_primitive, 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) { + + glBindVertexArray(data.polygon_buffer_pointer_array); + glBindBuffer(GL_ARRAY_BUFFER, data.polygon_buffer); + +#ifndef GLES_OVER_GL + // Orphan the buffer to avoid CPU/GPU sync points caused by glBufferSubData + glBufferData(GL_ARRAY_BUFFER, data.polygon_buffer_size, NULL, GL_DYNAMIC_DRAW); +#endif + + uint32_t buffer_ofs = 0; + + //vertex + 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), CAST_INT_TO_UCHAR_PTR(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); + Color m = *p_colors; + glVertexAttrib4f(VS::ARRAY_COLOR, m.r, m.g, m.b, m.a); + } else if (!p_colors) { + glDisableVertexAttribArray(VS::ARRAY_COLOR); + glVertexAttrib4f(VS::ARRAY_COLOR, 1, 1, 1, 1); + } else { + + glBufferSubData(GL_ARRAY_BUFFER, buffer_ofs, sizeof(Color) * p_vertex_count, p_colors); + glEnableVertexAttribArray(VS::ARRAY_COLOR); + glVertexAttribPointer(VS::ARRAY_COLOR, 4, GL_FLOAT, false, sizeof(Color), CAST_INT_TO_UCHAR_PTR(buffer_ofs)); + 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); + glEnableVertexAttribArray(VS::ARRAY_TEX_UV); + glVertexAttribPointer(VS::ARRAY_TEX_UV, 2, GL_FLOAT, false, sizeof(Vector2), CAST_INT_TO_UCHAR_PTR(buffer_ofs)); + buffer_ofs += sizeof(Vector2) * p_vertex_count; + + } else { + glDisableVertexAttribArray(VS::ARRAY_TEX_UV); + } + +#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); +#ifndef GLES_OVER_GL + // Orphan the buffer to avoid CPU/GPU sync points caused by glBufferSubData + glBufferData(GL_ELEMENT_ARRAY_BUFFER, data.polygon_index_buffer_size, NULL, GL_DYNAMIC_DRAW); +#endif + glBufferSubData(GL_ELEMENT_ARRAY_BUFFER, 0, sizeof(int) * p_index_count, p_indices); + + //draw the triangles. + glDrawElements(p_primitive, p_index_count, GL_UNSIGNED_INT, 0); + + storage->frame.canvas_draw_commands++; + + glBindVertexArray(0); + glBindBuffer(GL_ARRAY_BUFFER, 0); } void RasterizerCanvasGLES3::_draw_gui_primitive(int p_points, const Vector2 *p_vertices, const Color *p_colors, const Vector2 *p_uvs) { @@ -508,6 +597,11 @@ void RasterizerCanvasGLES3::_draw_gui_primitive(int p_points, const Vector2 *p_v } glBindBuffer(GL_ARRAY_BUFFER, data.polygon_buffer); +#ifndef GLES_OVER_GL + // Orphan the buffer to avoid CPU/GPU sync points caused by glBufferSubData + glBufferData(GL_ARRAY_BUFFER, data.polygon_buffer_size, NULL, GL_DYNAMIC_DRAW); +#endif + //TODO the below call may need to be replaced with: glBufferSubData(GL_ARRAY_BUFFER, 0, p_points * stride * 4 * sizeof(float), &b[0]); glBufferSubData(GL_ARRAY_BUFFER, 0, p_points * stride * 4, &b[0]); glBindVertexArray(data.polygon_buffer_quad_arrays[version]); glDrawArrays(prim[p_points], 0, p_points); @@ -807,7 +901,11 @@ void RasterizerCanvasGLES3::_canvas_item_render_commands(Item *p_item, Item *cur #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); + if (polygon->antialiasing_use_indices) { + _draw_generic_indices(GL_LINE_STRIP, polygon->indices.ptr(), polygon->count, polygon->points.size(), polygon->points.ptr(), polygon->uvs.ptr(), polygon->colors.ptr(), polygon->colors.size() == 1); + } else { + _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); } #endif @@ -914,6 +1012,7 @@ void RasterizerCanvasGLES3::_canvas_item_render_commands(Item *p_item, Item *cur switch (multi_mesh->color_format) { + case VS::MULTIMESH_COLOR_MAX: case VS::MULTIMESH_COLOR_NONE: { glDisableVertexAttribArray(11); glVertexAttrib4f(11, 1, 1, 1, 1); @@ -935,6 +1034,7 @@ void RasterizerCanvasGLES3::_canvas_item_render_commands(Item *p_item, Item *cur switch (multi_mesh->custom_data_format) { + case VS::MULTIMESH_CUSTOM_DATA_MAX: case VS::MULTIMESH_CUSTOM_DATA_NONE: { glDisableVertexAttribArray(12); glVertexAttrib4f(12, 1, 1, 1, 1); @@ -1319,11 +1419,9 @@ void RasterizerCanvasGLES3::canvas_render_items(Item *p_item_list, int p_z, cons } if (skeleton) { - glActiveTexture(GL_TEXTURE0 + storage->config.max_texture_image_units - 1); + glActiveTexture(GL_TEXTURE0 + storage->config.max_texture_image_units - 4); glBindTexture(GL_TEXTURE_2D, skeleton->texture); state.using_skeleton = true; - state.canvas_shader.set_uniform(CanvasShaderGLES3::SKELETON_TRANSFORM, state.skeleton_transform); - state.canvas_shader.set_uniform(CanvasShaderGLES3::SKELETON_TRANSFORM_INVERSE, state.skeleton_transform_inverse); } else { state.using_skeleton = false; } @@ -1510,6 +1608,11 @@ void RasterizerCanvasGLES3::canvas_render_items(Item *p_item_list, int p_z, cons state.final_transform = ci->final_transform; state.extra_matrix = Transform2D(); + 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); + } + 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); @@ -1580,7 +1683,6 @@ void RasterizerCanvasGLES3::canvas_render_items(Item *p_item_list, int p_z, cons bool light_rebind = state.canvas_shader.bind(); if (light_rebind) { - 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, Transform2D()); @@ -1589,6 +1691,10 @@ void RasterizerCanvasGLES3::canvas_render_items(Item *p_item_list, int p_z, cons } else { state.canvas_shader.set_uniform(CanvasShaderGLES3::SCREEN_PIXEL_SIZE, Vector2(1.0, 1.0)); } + 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); + } } glBindBufferBase(GL_UNIFORM_BUFFER, 1, static_cast<LightInternal *>(light->light_internal.get_data())->ubo); @@ -1785,7 +1891,7 @@ void RasterizerCanvasGLES3::canvas_light_shadow_buffer_update(RID p_buffer, cons while (instance) { - RasterizerStorageGLES3::CanvasOccluder *cc = storage->canvas_occluder_owner.get(instance->polygon_buffer); + RasterizerStorageGLES3::CanvasOccluder *cc = storage->canvas_occluder_owner.getornull(instance->polygon_buffer); if (!cc || cc->len == 0 || !(p_light_mask & instance->light_mask)) { instance = instance->next; @@ -1793,9 +1899,20 @@ void RasterizerCanvasGLES3::canvas_light_shadow_buffer_update(RID p_buffer, cons } state.canvas_shadow_shader.set_uniform(CanvasShadowShaderGLES3::WORLD_MATRIX, instance->xform_cache); - if (cull != instance->cull_cache) { - cull = instance->cull_cache; + VS::CanvasOccluderPolygonCullMode transformed_cull_cache = instance->cull_cache; + + if (transformed_cull_cache != VS::CANVAS_OCCLUDER_POLYGON_CULL_DISABLED && + (p_light_xform.basis_determinant() * instance->xform_cache.basis_determinant()) < 0) { + transformed_cull_cache = + transformed_cull_cache == VS::CANVAS_OCCLUDER_POLYGON_CULL_CLOCKWISE ? + VS::CANVAS_OCCLUDER_POLYGON_CULL_COUNTER_CLOCKWISE : + VS::CANVAS_OCCLUDER_POLYGON_CULL_CLOCKWISE; + } + + if (cull != transformed_cull_cache) { + + cull = transformed_cull_cache; switch (cull) { case VS::CANVAS_OCCLUDER_POLYGON_CULL_DISABLED: { @@ -1882,7 +1999,7 @@ void RasterizerCanvasGLES3::reset_canvas() { state.canvas_item_ubo_data.time = storage->frame.time[0]; glBindBuffer(GL_UNIFORM_BUFFER, state.canvas_item_ubo); - glBufferSubData(GL_UNIFORM_BUFFER, 0, sizeof(CanvasItemUBO), &state.canvas_item_ubo_data); + glBufferData(GL_UNIFORM_BUFFER, sizeof(CanvasItemUBO), &state.canvas_item_ubo_data, GL_DYNAMIC_DRAW); glBindBuffer(GL_UNIFORM_BUFFER, 0); state.canvas_texscreen_used = false; @@ -2109,6 +2226,8 @@ void RasterizerCanvasGLES3::initialize() { glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, data.polygon_index_buffer); glBufferData(GL_ELEMENT_ARRAY_BUFFER, index_size, NULL, GL_DYNAMIC_DRAW); //allocate max size glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); + + data.polygon_index_buffer_size = index_size; } store_transform(Transform(), state.canvas_item_ubo_data.projection_matrix); |