diff options
Diffstat (limited to 'drivers/gles2')
-rw-r--r-- | drivers/gles2/rasterizer_canvas_gles2.cpp | 24 | ||||
-rw-r--r-- | drivers/gles2/rasterizer_gles2.cpp | 9 | ||||
-rw-r--r-- | drivers/gles2/rasterizer_gles2.h | 2 | ||||
-rw-r--r-- | drivers/gles2/rasterizer_scene_gles2.cpp | 42 | ||||
-rw-r--r-- | drivers/gles2/rasterizer_storage_gles2.cpp | 268 | ||||
-rw-r--r-- | drivers/gles2/rasterizer_storage_gles2.h | 13 | ||||
-rw-r--r-- | drivers/gles2/shaders/canvas.glsl | 13 | ||||
-rw-r--r-- | drivers/gles2/shaders/cubemap_filter.glsl | 8 | ||||
-rw-r--r-- | drivers/gles2/shaders/scene.glsl | 13 |
9 files changed, 309 insertions, 83 deletions
diff --git a/drivers/gles2/rasterizer_canvas_gles2.cpp b/drivers/gles2/rasterizer_canvas_gles2.cpp index 3671679b49..9eb159cb31 100644 --- a/drivers/gles2/rasterizer_canvas_gles2.cpp +++ b/drivers/gles2/rasterizer_canvas_gles2.cpp @@ -288,14 +288,14 @@ void RasterizerCanvasGLES2::_draw_polygon(const int *p_indices, int p_index_coun } 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, GL_FALSE, sizeof(Color), ((uint8_t *)0) + buffer_ofs); + glVertexAttribPointer(VS::ARRAY_COLOR, 4, GL_FLOAT, GL_FALSE, sizeof(Color), CAST_INT_TO_UCHAR_PTR(buffer_ofs)); buffer_ofs += sizeof(Color) * p_vertex_count; } 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, GL_FALSE, sizeof(Vector2), ((uint8_t *)0) + buffer_ofs); + glVertexAttribPointer(VS::ARRAY_TEX_UV, 2, GL_FLOAT, GL_FALSE, sizeof(Vector2), CAST_INT_TO_UCHAR_PTR(buffer_ofs)); buffer_ofs += sizeof(Vector2) * p_vertex_count; } else { glDisableVertexAttribArray(VS::ARRAY_TEX_UV); @@ -304,12 +304,12 @@ void RasterizerCanvasGLES2::_draw_polygon(const int *p_indices, int p_index_coun if (p_weights && p_bones) { 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, GL_FALSE, sizeof(float) * 4, ((uint8_t *)0) + buffer_ofs); + glVertexAttribPointer(VS::ARRAY_WEIGHTS, 4, GL_FLOAT, GL_FALSE, sizeof(float) * 4, CAST_INT_TO_UCHAR_PTR(buffer_ofs)); buffer_ofs += sizeof(float) * 4 * p_vertex_count; 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, GL_FALSE, sizeof(int) * 4, ((uint8_t *)0) + buffer_ofs); + glVertexAttribPointer(VS::ARRAY_BONES, 4, GL_UNSIGNED_INT, GL_FALSE, sizeof(int) * 4, CAST_INT_TO_UCHAR_PTR(buffer_ofs)); buffer_ofs += sizeof(int) * 4 * p_vertex_count; } else { @@ -342,7 +342,7 @@ void RasterizerCanvasGLES2::_draw_generic(GLuint p_primitive, int p_vertex_count glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(Vector2) * p_vertex_count, p_vertices); glEnableVertexAttribArray(VS::ARRAY_VERTEX); - glVertexAttribPointer(VS::ARRAY_VERTEX, 2, GL_FLOAT, GL_FALSE, sizeof(Vector2), (uint8_t *)0); + glVertexAttribPointer(VS::ARRAY_VERTEX, 2, GL_FLOAT, GL_FALSE, sizeof(Vector2), NULL); buffer_ofs += sizeof(Vector2) * p_vertex_count; if (p_singlecolor) { @@ -355,14 +355,14 @@ void RasterizerCanvasGLES2::_draw_generic(GLuint p_primitive, int p_vertex_count } 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, GL_FALSE, sizeof(Color), ((uint8_t *)0) + buffer_ofs); + glVertexAttribPointer(VS::ARRAY_COLOR, 4, GL_FLOAT, GL_FALSE, sizeof(Color), CAST_INT_TO_UCHAR_PTR(buffer_ofs)); buffer_ofs += sizeof(Color) * p_vertex_count; } 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, GL_FALSE, sizeof(Vector2), ((uint8_t *)0) + buffer_ofs); + glVertexAttribPointer(VS::ARRAY_TEX_UV, 2, GL_FLOAT, GL_FALSE, sizeof(Vector2), CAST_INT_TO_UCHAR_PTR(buffer_ofs)); } else { glDisableVertexAttribArray(VS::ARRAY_TEX_UV); } @@ -419,12 +419,12 @@ void RasterizerCanvasGLES2::_draw_gui_primitive(int p_points, const Vector2 *p_v glVertexAttribPointer(VS::ARRAY_VERTEX, 2, GL_FLOAT, GL_FALSE, stride * sizeof(float), NULL); if (p_colors) { - glVertexAttribPointer(VS::ARRAY_COLOR, 4, GL_FLOAT, GL_FALSE, stride * sizeof(float), (uint8_t *)0 + color_offset * sizeof(float)); + glVertexAttribPointer(VS::ARRAY_COLOR, 4, GL_FLOAT, GL_FALSE, stride * sizeof(float), CAST_INT_TO_UCHAR_PTR(color_offset * sizeof(float))); glEnableVertexAttribArray(VS::ARRAY_COLOR); } if (p_uvs) { - glVertexAttribPointer(VS::ARRAY_TEX_UV, 2, GL_FLOAT, GL_FALSE, stride * sizeof(float), (uint8_t *)0 + uv_offset * sizeof(float)); + glVertexAttribPointer(VS::ARRAY_TEX_UV, 2, GL_FLOAT, GL_FALSE, stride * sizeof(float), CAST_INT_TO_UCHAR_PTR(uv_offset * sizeof(float))); glEnableVertexAttribArray(VS::ARRAY_TEX_UV); } @@ -840,7 +840,7 @@ void RasterizerCanvasGLES2::_canvas_item_render_commands(Item *p_item, Item *cur glEnableVertexAttribArray(VS::ARRAY_TEX_UV); glVertexAttribPointer(VS::ARRAY_VERTEX, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float), NULL); - glVertexAttribPointer(VS::ARRAY_TEX_UV, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float), (uint8_t *)0 + (sizeof(float) * 2)); + glVertexAttribPointer(VS::ARRAY_TEX_UV, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float), CAST_INT_TO_UCHAR_PTR((sizeof(float) * 2))); glDrawElements(GL_TRIANGLES, 18 * 3 - (np->draw_center ? 0 : 6), GL_UNSIGNED_BYTE, NULL); @@ -932,7 +932,7 @@ void RasterizerCanvasGLES2::_canvas_item_render_commands(Item *p_item, Item *cur for (int k = 0; k < VS::ARRAY_MAX - 1; k++) { if (s->attribs[k].enabled) { glEnableVertexAttribArray(k); - glVertexAttribPointer(s->attribs[k].index, s->attribs[k].size, s->attribs[k].type, s->attribs[k].normalized, s->attribs[k].stride, (uint8_t *)0 + s->attribs[k].offset); + glVertexAttribPointer(s->attribs[k].index, s->attribs[k].size, s->attribs[k].type, s->attribs[k].normalized, s->attribs[k].stride, CAST_INT_TO_UCHAR_PTR(s->attribs[k].offset)); } else { glDisableVertexAttribArray(k); switch (k) { @@ -1021,7 +1021,7 @@ void RasterizerCanvasGLES2::_canvas_item_render_commands(Item *p_item, Item *cur for (int k = 0; k < VS::ARRAY_MAX - 1; k++) { if (s->attribs[k].enabled) { glEnableVertexAttribArray(k); - glVertexAttribPointer(s->attribs[k].index, s->attribs[k].size, s->attribs[k].type, s->attribs[k].normalized, s->attribs[k].stride, (uint8_t *)0 + s->attribs[k].offset); + glVertexAttribPointer(s->attribs[k].index, s->attribs[k].size, s->attribs[k].type, s->attribs[k].normalized, s->attribs[k].stride, CAST_INT_TO_UCHAR_PTR(s->attribs[k].offset)); } else { glDisableVertexAttribArray(k); switch (k) { diff --git a/drivers/gles2/rasterizer_gles2.cpp b/drivers/gles2/rasterizer_gles2.cpp index 71b826d689..d3c6b041a8 100644 --- a/drivers/gles2/rasterizer_gles2.cpp +++ b/drivers/gles2/rasterizer_gles2.cpp @@ -32,7 +32,6 @@ #include "core/os/os.h" #include "core/project_settings.h" -#include "drivers/gl_context/context_gl.h" #define _EXT_DEBUG_OUTPUT_SYNCHRONOUS_ARB 0x8242 #define _EXT_DEBUG_NEXT_LOGGED_MESSAGE_LENGTH_ARB 0x8243 @@ -321,7 +320,7 @@ void RasterizerGLES2::set_current_render_target(RID p_render_target) { } } -void RasterizerGLES2::restore_render_target() { +void RasterizerGLES2::restore_render_target(bool p_3d_was_drawn) { ERR_FAIL_COND(storage->frame.current_rt == NULL); RasterizerStorageGLES2::RenderTarget *rt = storage->frame.current_rt; glBindFramebuffer(GL_FRAMEBUFFER, rt->fbo); @@ -410,7 +409,11 @@ void RasterizerGLES2::blit_render_target_to_screen(RID p_render_target, const Re glDisable(GL_BLEND); glBindFramebuffer(GL_FRAMEBUFFER, RasterizerStorageGLES2::system_fbo); glActiveTexture(GL_TEXTURE0 + storage->config.max_texture_image_units - 1); - glBindTexture(GL_TEXTURE_2D, rt->color); + if (rt->external.fbo != 0) { + glBindTexture(GL_TEXTURE_2D, rt->external.color); + } else { + glBindTexture(GL_TEXTURE_2D, rt->color); + } // TODO normals diff --git a/drivers/gles2/rasterizer_gles2.h b/drivers/gles2/rasterizer_gles2.h index ed4eeb84d2..eeed86e263 100644 --- a/drivers/gles2/rasterizer_gles2.h +++ b/drivers/gles2/rasterizer_gles2.h @@ -56,7 +56,7 @@ public: virtual void initialize(); virtual void begin_frame(double frame_step); virtual void set_current_render_target(RID p_render_target); - virtual void restore_render_target(); + virtual void restore_render_target(bool p_3d_was_drawn); virtual void clear_render_target(const Color &p_color); virtual void blit_render_target_to_screen(RID p_render_target, const Rect2 &p_screen_rect, int p_screen = 0); virtual void output_lens_distorted_to_screen(RID p_render_target, const Rect2 &p_screen_rect, float p_k1, float p_k2, const Vector2 &p_eye_center, float p_oversample); diff --git a/drivers/gles2/rasterizer_scene_gles2.cpp b/drivers/gles2/rasterizer_scene_gles2.cpp index 5e006b7527..c996078ba6 100644 --- a/drivers/gles2/rasterizer_scene_gles2.cpp +++ b/drivers/gles2/rasterizer_scene_gles2.cpp @@ -635,7 +635,7 @@ bool RasterizerSceneGLES2::reflection_probe_instance_postprocess_step(RID p_inst for (int i = 0; i < 6; i++) { glBindFramebuffer(GL_FRAMEBUFFER, rpi->fbo[i]); glViewport(0, 0, size, size); - glCopyTexImage2D(_cube_side_enum[i], 0, GL_RGB, 0, 0, size, size, 0); + glCopyTexSubImage2D(_cube_side_enum[i], 0, 0, 0, 0, 0, size, size); } //do filtering //vdc cache @@ -672,7 +672,7 @@ bool RasterizerSceneGLES2::reflection_probe_instance_postprocess_step(RID p_inst storage->shaders.cubemap_filter.set_uniform(CubemapFilterShaderGLES2::Z_FLIP, false); glDrawArrays(GL_TRIANGLE_FAN, 0, 4); - glCopyTexImage2D(_cube_side_enum[i], lod, GL_RGB, 0, 0, size, size, 0); + glCopyTexSubImage2D(_cube_side_enum[i], lod, 0, 0, 0, 0, size, size); } size >>= 1; @@ -1358,7 +1358,7 @@ void RasterizerSceneGLES2::_setup_geometry(RenderList::Element *p_element, Raste for (int i = 0; i < VS::ARRAY_MAX - 1; i++) { if (s->attribs[i].enabled) { glEnableVertexAttribArray(i); - glVertexAttribPointer(s->attribs[i].index, s->attribs[i].size, s->attribs[i].type, s->attribs[i].normalized, s->attribs[i].stride, (uint8_t *)0 + s->attribs[i].offset); + glVertexAttribPointer(s->attribs[i].index, s->attribs[i].size, s->attribs[i].type, s->attribs[i].normalized, s->attribs[i].stride, CAST_INT_TO_UCHAR_PTR(s->attribs[i].offset)); } else { glDisableVertexAttribArray(i); switch (i) { @@ -1519,7 +1519,7 @@ void RasterizerSceneGLES2::_setup_geometry(RenderList::Element *p_element, Raste for (int i = 0; i < VS::ARRAY_MAX - 1; i++) { if (s->attribs[i].enabled) { glEnableVertexAttribArray(i); - glVertexAttribPointer(s->attribs[i].index, s->attribs[i].size, s->attribs[i].type, s->attribs[i].normalized, s->attribs[i].stride, (uint8_t *)0 + s->attribs[i].offset); + glVertexAttribPointer(s->attribs[i].index, s->attribs[i].size, s->attribs[i].type, s->attribs[i].normalized, s->attribs[i].stride, CAST_INT_TO_UCHAR_PTR(s->attribs[i].offset)); } else { glDisableVertexAttribArray(i); switch (i) { @@ -1566,8 +1566,10 @@ void RasterizerSceneGLES2::_render_geometry(RenderList::Element *p_element) { if (s->index_array_len > 0) { glDrawElements(gl_primitive[s->primitive], s->index_array_len, (s->array_len >= (1 << 16)) ? GL_UNSIGNED_INT : GL_UNSIGNED_SHORT, 0); + storage->info.render.vertices_count += s->index_array_len; } else { glDrawArrays(gl_primitive[s->primitive], 0, s->array_len); + storage->info.render.vertices_count += s->array_len; } /* if (p_element->instance->skeleton.is_valid() && s->attribs[VS::ARRAY_BONES].enabled && s->attribs[VS::ARRAY_WEIGHTS].enabled) { @@ -1637,8 +1639,10 @@ void RasterizerSceneGLES2::_render_geometry(RenderList::Element *p_element) { if (s->index_array_len > 0) { glDrawElements(gl_primitive[s->primitive], s->index_array_len, (s->array_len >= (1 << 16)) ? GL_UNSIGNED_INT : GL_UNSIGNED_SHORT, 0); + storage->info.render.vertices_count += s->index_array_len; } else { glDrawArrays(gl_primitive[s->primitive], 0, s->array_len); + storage->info.render.vertices_count += s->array_len; } } @@ -1698,7 +1702,7 @@ void RasterizerSceneGLES2::_render_geometry(RenderList::Element *p_element) { if (!c.normals.empty()) { glEnableVertexAttribArray(VS::ARRAY_NORMAL); glBufferSubData(GL_ARRAY_BUFFER, buf_ofs, sizeof(Vector3) * vertices, c.normals.ptr()); - glVertexAttribPointer(VS::ARRAY_NORMAL, 3, GL_FLOAT, GL_FALSE, sizeof(Vector3), ((uint8_t *)NULL) + buf_ofs); + glVertexAttribPointer(VS::ARRAY_NORMAL, 3, GL_FLOAT, GL_FALSE, sizeof(Vector3), CAST_INT_TO_UCHAR_PTR(buf_ofs)); buf_ofs += sizeof(Vector3) * vertices; } else { glDisableVertexAttribArray(VS::ARRAY_NORMAL); @@ -1707,7 +1711,7 @@ void RasterizerSceneGLES2::_render_geometry(RenderList::Element *p_element) { if (!c.tangents.empty()) { glEnableVertexAttribArray(VS::ARRAY_TANGENT); glBufferSubData(GL_ARRAY_BUFFER, buf_ofs, sizeof(Plane) * vertices, c.tangents.ptr()); - glVertexAttribPointer(VS::ARRAY_TANGENT, 4, GL_FLOAT, GL_FALSE, sizeof(Plane), ((uint8_t *)NULL) + buf_ofs); + glVertexAttribPointer(VS::ARRAY_TANGENT, 4, GL_FLOAT, GL_FALSE, sizeof(Plane), CAST_INT_TO_UCHAR_PTR(buf_ofs)); buf_ofs += sizeof(Plane) * vertices; } else { glDisableVertexAttribArray(VS::ARRAY_TANGENT); @@ -1716,7 +1720,7 @@ void RasterizerSceneGLES2::_render_geometry(RenderList::Element *p_element) { if (!c.colors.empty()) { glEnableVertexAttribArray(VS::ARRAY_COLOR); glBufferSubData(GL_ARRAY_BUFFER, buf_ofs, sizeof(Color) * vertices, c.colors.ptr()); - glVertexAttribPointer(VS::ARRAY_COLOR, 4, GL_FLOAT, GL_FALSE, sizeof(Color), ((uint8_t *)NULL) + buf_ofs); + glVertexAttribPointer(VS::ARRAY_COLOR, 4, GL_FLOAT, GL_FALSE, sizeof(Color), CAST_INT_TO_UCHAR_PTR(buf_ofs)); buf_ofs += sizeof(Color) * vertices; } else { glDisableVertexAttribArray(VS::ARRAY_COLOR); @@ -1725,7 +1729,7 @@ void RasterizerSceneGLES2::_render_geometry(RenderList::Element *p_element) { if (!c.uvs.empty()) { glEnableVertexAttribArray(VS::ARRAY_TEX_UV); glBufferSubData(GL_ARRAY_BUFFER, buf_ofs, sizeof(Vector2) * vertices, c.uvs.ptr()); - glVertexAttribPointer(VS::ARRAY_TEX_UV, 2, GL_FLOAT, GL_FALSE, sizeof(Vector2), ((uint8_t *)NULL) + buf_ofs); + glVertexAttribPointer(VS::ARRAY_TEX_UV, 2, GL_FLOAT, GL_FALSE, sizeof(Vector2), CAST_INT_TO_UCHAR_PTR(buf_ofs)); buf_ofs += sizeof(Vector2) * vertices; } else { glDisableVertexAttribArray(VS::ARRAY_TEX_UV); @@ -1734,7 +1738,7 @@ void RasterizerSceneGLES2::_render_geometry(RenderList::Element *p_element) { if (!c.uv2s.empty()) { glEnableVertexAttribArray(VS::ARRAY_TEX_UV2); glBufferSubData(GL_ARRAY_BUFFER, buf_ofs, sizeof(Vector2) * vertices, c.uv2s.ptr()); - glVertexAttribPointer(VS::ARRAY_TEX_UV2, 2, GL_FLOAT, GL_FALSE, sizeof(Vector2), ((uint8_t *)NULL) + buf_ofs); + glVertexAttribPointer(VS::ARRAY_TEX_UV2, 2, GL_FLOAT, GL_FALSE, sizeof(Vector2), CAST_INT_TO_UCHAR_PTR(buf_ofs)); buf_ofs += sizeof(Vector2) * vertices; } else { glDisableVertexAttribArray(VS::ARRAY_TEX_UV2); @@ -1742,7 +1746,7 @@ void RasterizerSceneGLES2::_render_geometry(RenderList::Element *p_element) { glEnableVertexAttribArray(VS::ARRAY_VERTEX); glBufferSubData(GL_ARRAY_BUFFER, buf_ofs, sizeof(Vector3) * vertices, c.vertices.ptr()); - glVertexAttribPointer(VS::ARRAY_VERTEX, 3, GL_FLOAT, GL_FALSE, sizeof(Vector3), ((uint8_t *)NULL) + buf_ofs); + glVertexAttribPointer(VS::ARRAY_VERTEX, 3, GL_FLOAT, GL_FALSE, sizeof(Vector3), CAST_INT_TO_UCHAR_PTR(buf_ofs)); glDrawArrays(gl_primitive[c.primitive], 0, c.vertices.size()); } @@ -2182,6 +2186,8 @@ void RasterizerSceneGLES2::_render_render_list(RenderList::Element **p_elements, float lightmap_energy = 1.0; bool prev_use_lightmap_capture = false; + storage->info.render.draw_call_count += p_element_count; + for (int i = 0; i < p_element_count; i++) { RenderList::Element *e = p_elements[i]; @@ -2389,11 +2395,17 @@ void RasterizerSceneGLES2::_render_render_list(RenderList::Element **p_elements, if (e->owner != prev_owner || e->geometry != prev_geometry || skeleton != prev_skeleton) { _setup_geometry(e, skeleton); + storage->info.render.surface_switch_count++; } bool shader_rebind = false; if (rebind || material != prev_material) { + + storage->info.render.material_switch_count++; shader_rebind = _setup_material(material, p_reverse_cull, p_alpha_pass, Size2i(skeleton ? skeleton->size * 3 : 0, 0)); + if (shader_rebind) { + storage->info.render.shader_rebind_count++; + } } if (i == 0 || shader_rebind) { //first time must rebind @@ -2598,7 +2610,7 @@ void RasterizerSceneGLES2::_draw_sky(RasterizerStorageGLES2::Sky *p_sky, const C // bind sky vertex array.... glVertexAttribPointer(VS::ARRAY_VERTEX, 3, GL_FLOAT, GL_FALSE, sizeof(Vector3) * 2, 0); - glVertexAttribPointer(VS::ARRAY_TEX_UV, 3, GL_FLOAT, GL_FALSE, sizeof(Vector3) * 2, ((uint8_t *)NULL) + sizeof(Vector3)); + glVertexAttribPointer(VS::ARRAY_TEX_UV, 3, GL_FLOAT, GL_FALSE, sizeof(Vector3) * 2, CAST_INT_TO_UCHAR_PTR(sizeof(Vector3))); glEnableVertexAttribArray(VS::ARRAY_VERTEX); glEnableVertexAttribArray(VS::ARRAY_TEX_UV); @@ -2637,6 +2649,8 @@ void RasterizerSceneGLES2::render_scene(const Transform &p_cam_transform, const Transform cam_transform = p_cam_transform; + storage->info.render.object_count += p_cull_count; + GLuint current_fb = 0; Environment *env = NULL; @@ -2667,7 +2681,11 @@ void RasterizerSceneGLES2::render_scene(const Transform &p_cam_transform, const } else { state.render_no_shadows = false; - current_fb = storage->frame.current_rt->fbo; + if (storage->frame.current_rt->external.fbo != 0) { + current_fb = storage->frame.current_rt->external.fbo; + } else { + current_fb = storage->frame.current_rt->fbo; + } env = environment_owner.getornull(p_environment); viewport_width = storage->frame.current_rt->width; diff --git a/drivers/gles2/rasterizer_storage_gles2.cpp b/drivers/gles2/rasterizer_storage_gles2.cpp index 11ab8438df..b051c7d811 100644 --- a/drivers/gles2/rasterizer_storage_gles2.cpp +++ b/drivers/gles2/rasterizer_storage_gles2.cpp @@ -84,7 +84,7 @@ GLuint RasterizerStorageGLES2::system_fbo = 0; void RasterizerStorageGLES2::bind_quad_array() const { glBindBuffer(GL_ARRAY_BUFFER, resources.quadie); glVertexAttribPointer(VS::ARRAY_VERTEX, 2, GL_FLOAT, GL_FALSE, sizeof(float) * 4, 0); - glVertexAttribPointer(VS::ARRAY_TEX_UV, 2, GL_FLOAT, GL_FALSE, sizeof(float) * 4, ((uint8_t *)NULL) + 8); + glVertexAttribPointer(VS::ARRAY_TEX_UV, 2, GL_FLOAT, GL_FALSE, sizeof(float) * 4, CAST_INT_TO_UCHAR_PTR(8)); glEnableVertexAttribArray(VS::ARRAY_VERTEX); glEnableVertexAttribArray(VS::ARRAY_TEX_UV); @@ -120,9 +120,13 @@ Ref<Image> RasterizerStorageGLES2::_get_gl_image_and_format(const Ref<Image> &p_ } break; case Image::FORMAT_RG8: { - - ERR_EXPLAIN("RG texture not supported"); - ERR_FAIL_V(image); + ERR_PRINT("RG texture not supported, converting to RGB8."); + if (image.is_valid()) + image->convert(Image::FORMAT_RGB8); + r_real_format = Image::FORMAT_RGB8; + r_gl_internal_format = GL_RGB; + r_gl_format = GL_RGB; + r_gl_type = GL_UNSIGNED_BYTE; } break; case Image::FORMAT_RGB8: { @@ -155,42 +159,57 @@ Ref<Image> RasterizerStorageGLES2::_get_gl_image_and_format(const Ref<Image> &p_ } break; case Image::FORMAT_RF: { if (!config.float_texture_supported) { - ERR_EXPLAIN("R float texture not supported"); - ERR_FAIL_V(image); + ERR_PRINT("R float texture not supported, converting to RGB8."); + if (image.is_valid()) + image->convert(Image::FORMAT_RGB8); + r_real_format = Image::FORMAT_RGB8; + r_gl_internal_format = GL_RGB; + r_gl_format = GL_RGB; + r_gl_type = GL_UNSIGNED_BYTE; + } else { + r_gl_internal_format = GL_ALPHA; + r_gl_format = GL_ALPHA; + r_gl_type = GL_FLOAT; } - - r_gl_internal_format = GL_ALPHA; - r_gl_format = GL_ALPHA; - r_gl_type = GL_FLOAT; } break; case Image::FORMAT_RGF: { - ERR_EXPLAIN("RG float texture not supported"); - ERR_FAIL_V(image); - + ERR_PRINT("RG float texture not supported, converting to RGB8."); + if (image.is_valid()) + image->convert(Image::FORMAT_RGB8); + r_real_format = Image::FORMAT_RGB8; + r_gl_internal_format = GL_RGB; + r_gl_format = GL_RGB; + r_gl_type = GL_UNSIGNED_BYTE; } break; case Image::FORMAT_RGBF: { if (!config.float_texture_supported) { - - ERR_EXPLAIN("RGB float texture not supported"); - ERR_FAIL_V(image); + ERR_PRINT("RGB float texture not supported, converting to RGB8."); + if (image.is_valid()) + image->convert(Image::FORMAT_RGB8); + r_real_format = Image::FORMAT_RGB8; + r_gl_internal_format = GL_RGB; + r_gl_format = GL_RGB; + r_gl_type = GL_UNSIGNED_BYTE; + } else { + r_gl_internal_format = GL_RGB; + r_gl_format = GL_RGB; + r_gl_type = GL_FLOAT; } - - r_gl_internal_format = GL_RGB; - r_gl_format = GL_RGB; - r_gl_type = GL_FLOAT; - } break; case Image::FORMAT_RGBAF: { if (!config.float_texture_supported) { - - ERR_EXPLAIN("RGBA float texture not supported"); - ERR_FAIL_V(image); + ERR_PRINT("RGBA float texture not supported, converting to RGBA8."); + if (image.is_valid()) + image->convert(Image::FORMAT_RGBA8); + r_real_format = Image::FORMAT_RGBA8; + r_gl_internal_format = GL_RGBA; + r_gl_format = GL_RGBA; + r_gl_type = GL_UNSIGNED_BYTE; + } else { + r_gl_internal_format = GL_RGBA; + r_gl_format = GL_RGBA; + r_gl_type = GL_FLOAT; } - - r_gl_internal_format = GL_RGBA; - r_gl_format = GL_RGBA; - r_gl_type = GL_FLOAT; - } break; case Image::FORMAT_RH: { need_decompress = true; @@ -1137,7 +1156,7 @@ void RasterizerStorageGLES2::sky_set_texture(RID p_sky, RID p_panorama, int p_ra glGenTextures(1, &sky->radiance); glBindTexture(GL_TEXTURE_CUBE_MAP, sky->radiance); - int size = p_radiance_size / 4; //divide by four because its a cubemap (this is an approximation because GLES3 uses a dual paraboloid) + int size = p_radiance_size / 2; //divide by two because its a cubemap (this is an approximation because GLES3 uses a dual paraboloid) GLenum internal_format = GL_RGB; GLenum format = GL_RGB; @@ -1176,18 +1195,20 @@ void RasterizerStorageGLES2::sky_set_texture(RID p_sky, RID p_panorama, int p_ra int mipmaps = 6; int lod = 0; int mm_level = mipmaps; - size = p_radiance_size; + size = p_radiance_size / 2; shaders.cubemap_filter.set_conditional(CubemapFilterShaderGLES2::USE_SOURCE_PANORAMA, true); shaders.cubemap_filter.set_conditional(CubemapFilterShaderGLES2::USE_DIRECT_WRITE, true); shaders.cubemap_filter.bind(); // third, render to the framebuffer using separate textures, then copy to mipmaps while (size >= 1) { + //make framebuffer size the texture size, need to use a separate texture for compatibility glActiveTexture(GL_TEXTURE3); glBindTexture(GL_TEXTURE_2D, resources.mipmap_blur_color); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, size, size, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL); glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, resources.mipmap_blur_color, 0); + if (lod == 1) { //bind panorama for smaller lods @@ -1213,7 +1234,7 @@ void RasterizerStorageGLES2::sky_set_texture(RID p_sky, RID p_panorama, int p_ra glDrawArrays(GL_TRIANGLE_FAN, 0, 4); - glCopyTexImage2D(_cube_side_enum[i], lod, GL_RGB, 0, 0, size, size, 0); + glCopyTexSubImage2D(_cube_side_enum[i], lod, 0, 0, 0, 0, size, size); } size >>= 1; @@ -4643,6 +4664,23 @@ void RasterizerStorageGLES2::_render_target_clear(RenderTarget *rt) { rt->fbo = 0; } + if (rt->external.fbo != 0) { + // free this + glDeleteFramebuffers(1, &rt->external.fbo); + + // clean up our texture + Texture *t = texture_owner.get(rt->external.texture); + t->alloc_height = 0; + t->alloc_width = 0; + t->width = 0; + t->height = 0; + t->active = false; + texture_owner.free(rt->external.texture); + memdelete(t); + + rt->external.fbo = 0; + } + if (rt->depth) { if (config.support_depth_texture) { glDeleteTextures(1, &rt->depth); @@ -4721,7 +4759,108 @@ RID RasterizerStorageGLES2::render_target_get_texture(RID p_render_target) const RenderTarget *rt = render_target_owner.getornull(p_render_target); ERR_FAIL_COND_V(!rt, RID()); - return rt->texture; + if (rt->external.fbo == 0) { + return rt->texture; + } else { + return rt->external.texture; + } +} + +void RasterizerStorageGLES2::render_target_set_external_texture(RID p_render_target, unsigned int p_texture_id) { + RenderTarget *rt = render_target_owner.getornull(p_render_target); + ERR_FAIL_COND(!rt); + + if (p_texture_id == 0) { + if (rt->external.fbo != 0) { + // free this + glDeleteFramebuffers(1, &rt->external.fbo); + + // clean up our texture + Texture *t = texture_owner.get(rt->external.texture); + t->alloc_height = 0; + t->alloc_width = 0; + t->width = 0; + t->height = 0; + t->active = false; + texture_owner.free(rt->external.texture); + memdelete(t); + + rt->external.fbo = 0; + rt->external.color = 0; + } + } else { + Texture *t; + + if (rt->external.fbo == 0) { + // create our fbo + glGenFramebuffers(1, &rt->external.fbo); + glBindFramebuffer(GL_FRAMEBUFFER, rt->external.fbo); + + // allocate a texture + t = memnew(Texture); + + t->type = VS::TEXTURE_TYPE_2D; + t->flags = 0; + t->width = 0; + t->height = 0; + t->alloc_height = 0; + t->alloc_width = 0; + t->format = Image::FORMAT_RGBA8; + t->target = GL_TEXTURE_2D; + t->gl_format_cache = 0; + t->gl_internal_format_cache = 0; + t->gl_type_cache = 0; + t->data_size = 0; + t->compressed = false; + t->srgb = false; + t->total_data_size = 0; + t->ignore_mipmaps = false; + t->mipmaps = 1; + t->active = true; + t->tex_id = 0; + t->render_target = rt; + + rt->external.texture = texture_owner.make_rid(t); + } else { + // bind our frame buffer + glBindFramebuffer(GL_FRAMEBUFFER, rt->external.fbo); + + // find our texture + t = texture_owner.get(rt->external.texture); + } + + // set our texture + t->tex_id = p_texture_id; + rt->external.color = p_texture_id; + + // size shouldn't be different + t->width = rt->width; + t->height = rt->height; + t->alloc_height = rt->width; + t->alloc_width = rt->height; + + // is there a point to setting the internal formats? we don't know them.. + + // set our texture as the destination for our framebuffer + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, p_texture_id, 0); + + // seeing we're rendering into this directly, better also use our depth buffer, just use our existing one :) + if (config.support_depth_texture) { + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, rt->depth, 0); + } else { + glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, rt->depth); + } + + // check status and unbind + GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER); + glBindFramebuffer(GL_FRAMEBUFFER, RasterizerStorageGLES2::system_fbo); + + if (status != GL_FRAMEBUFFER_COMPLETE) { + printf("framebuffer fail, status: %x\n", status); + } + + ERR_FAIL_COND(status != GL_FRAMEBUFFER_COMPLETE); + } } void RasterizerStorageGLES2::render_target_set_flag(RID p_render_target, RenderTargetFlags p_flag, bool p_value) { @@ -4731,6 +4870,7 @@ void RasterizerStorageGLES2::render_target_set_flag(RID p_render_target, RenderT rt->flags[p_flag] = p_value; switch (p_flag) { + case RENDER_TARGET_TRANSPARENT: case RENDER_TARGET_HDR: case RENDER_TARGET_NO_3D: case RENDER_TARGET_NO_SAMPLING: @@ -5186,18 +5326,72 @@ void RasterizerStorageGLES2::set_debug_generate_wireframes(bool p_generate) { } void RasterizerStorageGLES2::render_info_begin_capture() { + + info.snap = info.render; } void RasterizerStorageGLES2::render_info_end_capture() { + + info.snap.object_count = info.render.object_count - info.snap.object_count; + info.snap.draw_call_count = info.render.draw_call_count - info.snap.draw_call_count; + info.snap.material_switch_count = info.render.material_switch_count - info.snap.material_switch_count; + info.snap.surface_switch_count = info.render.surface_switch_count - info.snap.surface_switch_count; + info.snap.shader_rebind_count = info.render.shader_rebind_count - info.snap.shader_rebind_count; + info.snap.vertices_count = info.render.vertices_count - info.snap.vertices_count; } int RasterizerStorageGLES2::get_captured_render_info(VS::RenderInfo p_info) { - return get_render_info(p_info); + switch (p_info) { + case VS::INFO_OBJECTS_IN_FRAME: { + return info.snap.object_count; + } break; + case VS::INFO_VERTICES_IN_FRAME: { + return info.snap.vertices_count; + } break; + case VS::INFO_MATERIAL_CHANGES_IN_FRAME: { + return info.snap.material_switch_count; + } break; + case VS::INFO_SHADER_CHANGES_IN_FRAME: { + return info.snap.shader_rebind_count; + } break; + case VS::INFO_SURFACE_CHANGES_IN_FRAME: { + return info.snap.surface_switch_count; + } break; + case VS::INFO_DRAW_CALLS_IN_FRAME: { + return info.snap.draw_call_count; + } break; + default: { + return get_render_info(p_info); + } + } } int RasterizerStorageGLES2::get_render_info(VS::RenderInfo p_info) { - return 0; + switch (p_info) { + case VS::INFO_OBJECTS_IN_FRAME: + return info.render_final.object_count; + case VS::INFO_VERTICES_IN_FRAME: + return info.render_final.vertices_count; + case VS::INFO_MATERIAL_CHANGES_IN_FRAME: + return info.render_final.material_switch_count; + case VS::INFO_SHADER_CHANGES_IN_FRAME: + return info.render_final.shader_rebind_count; + case VS::INFO_SURFACE_CHANGES_IN_FRAME: + return info.render_final.surface_switch_count; + case VS::INFO_DRAW_CALLS_IN_FRAME: + return info.render_final.draw_call_count; + case VS::INFO_USAGE_VIDEO_MEM_TOTAL: + return 0; //no idea + case VS::INFO_VIDEO_MEM_USED: + return info.vertex_mem + info.texture_mem; + case VS::INFO_TEXTURE_MEM_USED: + return info.texture_mem; + case VS::INFO_VERTEX_MEM_USED: + return info.vertex_mem; + default: + return 0; //no idea either + } } void RasterizerStorageGLES2::initialize() { @@ -5466,7 +5660,9 @@ void RasterizerStorageGLES2::initialize() { #ifdef GLES_OVER_GL //this needs to be enabled manually in OpenGL 2.1 - glEnable(_EXT_TEXTURE_CUBE_MAP_SEAMLESS); + if (config.extensions.has("GL_ARB_seamless_cube_map")) { + glEnable(_EXT_TEXTURE_CUBE_MAP_SEAMLESS); + } glEnable(GL_POINT_SPRITE); glEnable(GL_VERTEX_PROGRAM_POINT_SIZE); #endif diff --git a/drivers/gles2/rasterizer_storage_gles2.h b/drivers/gles2/rasterizer_storage_gles2.h index 8f5565c96f..2ac68fa47a 100644 --- a/drivers/gles2/rasterizer_storage_gles2.h +++ b/drivers/gles2/rasterizer_storage_gles2.h @@ -94,6 +94,7 @@ public: GLuint depth_internalformat; GLuint depth_type; + } config; struct Resources { @@ -1155,6 +1156,16 @@ public: Effect copy_screen_effect; + struct External { + GLuint fbo; + GLuint color; + RID texture; + + External() : + fbo(0) { + } + } external; + int width, height; bool flags[RENDER_TARGET_FLAG_MAX]; @@ -1175,6 +1186,7 @@ public: for (int i = 0; i < RENDER_TARGET_FLAG_MAX; ++i) { flags[i] = false; } + external.fbo = 0; } }; @@ -1186,6 +1198,7 @@ public: virtual RID render_target_create(); virtual void render_target_set_size(RID p_render_target, int p_width, int p_height); virtual RID render_target_get_texture(RID p_render_target) const; + virtual void render_target_set_external_texture(RID p_render_target, unsigned int p_texture_id); virtual void render_target_set_flag(RID p_render_target, RenderTargetFlags p_flag, bool p_value); virtual bool render_target_was_used(RID p_render_target); diff --git a/drivers/gles2/shaders/canvas.glsl b/drivers/gles2/shaders/canvas.glsl index b13801946f..7ba2856216 100644 --- a/drivers/gles2/shaders/canvas.glsl +++ b/drivers/gles2/shaders/canvas.glsl @@ -162,6 +162,9 @@ VERTEX_SHADER_CODE #ifdef USE_PIXEL_SNAP outvec.xy = floor(outvec + 0.5).xy; + // precision issue on some hardware creates artifacts within texture + // offset uv by a small amount to avoid + uv += 1e-5; #endif #ifdef USE_SKELETON @@ -217,29 +220,25 @@ VERTEX_SHADER_CODE /* clang-format off */ [fragment] +// texture2DLodEXT and textureCubeLodEXT are fragment shader specific. +// Do not copy these defines in the vertex section. #ifndef USE_GLES_OVER_GL - #ifdef GL_EXT_shader_texture_lod #extension GL_EXT_shader_texture_lod : enable #define texture2DLod(img, coord, lod) texture2DLodEXT(img, coord, lod) #define textureCubeLod(img, coord, lod) textureCubeLodEXT(img, coord, lod) #endif - -#endif +#endif // !USE_GLES_OVER_GL #ifdef GL_ARB_shader_texture_lod #extension GL_ARB_shader_texture_lod : enable #endif - #if !defined(GL_EXT_shader_texture_lod) && !defined(GL_ARB_shader_texture_lod) #define texture2DLod(img, coord, lod) texture2D(img, coord, lod) #define textureCubeLod(img, coord, lod) textureCube(img, coord, lod) #endif - - - #ifdef USE_GLES_OVER_GL #define lowp #define mediump diff --git a/drivers/gles2/shaders/cubemap_filter.glsl b/drivers/gles2/shaders/cubemap_filter.glsl index a6902836ed..db3d8b3a1b 100644 --- a/drivers/gles2/shaders/cubemap_filter.glsl +++ b/drivers/gles2/shaders/cubemap_filter.glsl @@ -25,15 +25,15 @@ void main() { /* clang-format off */ [fragment] +// texture2DLodEXT and textureCubeLodEXT are fragment shader specific. +// Do not copy these defines in the vertex section. #ifndef USE_GLES_OVER_GL - #ifdef GL_EXT_shader_texture_lod #extension GL_EXT_shader_texture_lod : enable #define texture2DLod(img, coord, lod) texture2DLodEXT(img, coord, lod) #define textureCubeLod(img, coord, lod) textureCubeLodEXT(img, coord, lod) #endif - -#endif +#endif // !USE_GLES_OVER_GL #ifdef GL_ARB_shader_texture_lod #extension GL_ARB_shader_texture_lod : enable @@ -44,8 +44,6 @@ void main() { #define textureCubeLod(img, coord, lod) textureCube(img, coord, lod) #endif - - #ifdef USE_GLES_OVER_GL #define lowp #define mediump diff --git a/drivers/gles2/shaders/scene.glsl b/drivers/gles2/shaders/scene.glsl index e3c6966e21..5d21c679ba 100644 --- a/drivers/gles2/shaders/scene.glsl +++ b/drivers/gles2/shaders/scene.glsl @@ -415,7 +415,6 @@ void main() { world_matrix = world_matrix * bone_transform; } - #endif #ifdef USE_INSTANCING @@ -676,15 +675,15 @@ VERTEX_SHADER_CODE /* clang-format off */ [fragment] +// texture2DLodEXT and textureCubeLodEXT are fragment shader specific. +// Do not copy these defines in the vertex section. #ifndef USE_GLES_OVER_GL - #ifdef GL_EXT_shader_texture_lod #extension GL_EXT_shader_texture_lod : enable #define texture2DLod(img, coord, lod) texture2DLodEXT(img, coord, lod) #define textureCubeLod(img, coord, lod) textureCubeLodEXT(img, coord, lod) #endif - -#endif +#endif // !USE_GLES_OVER_GL #ifdef GL_ARB_shader_texture_lod #extension GL_ARB_shader_texture_lod : enable @@ -695,9 +694,6 @@ VERTEX_SHADER_CODE #define textureCubeLod(img, coord, lod) textureCube(img, coord, lod) #endif - - - #ifdef USE_GLES_OVER_GL #define lowp #define mediump @@ -1470,6 +1466,9 @@ void main() { float anisotropy = 0.0; vec2 anisotropy_flow = vec2(1.0, 0.0); float sss_strength = 0.0; //unused + // gl_FragDepth is not available in GLES2, so writing to DEPTH is not converted to gl_FragDepth by Godot compiler resulting in a + // compile error because DEPTH is not a variable. + float m_DEPTH = 0.0; float alpha = 1.0; float side = 1.0; |