diff options
Diffstat (limited to 'drivers/gles2')
-rw-r--r-- | drivers/gles2/rasterizer_canvas_gles2.cpp | 118 | ||||
-rw-r--r-- | drivers/gles2/rasterizer_canvas_gles2.h | 6 | ||||
-rw-r--r-- | drivers/gles2/rasterizer_gles2.cpp | 7 | ||||
-rw-r--r-- | drivers/gles2/rasterizer_gles2.h | 4 | ||||
-rw-r--r-- | drivers/gles2/rasterizer_scene_gles2.cpp | 83 | ||||
-rw-r--r-- | drivers/gles2/rasterizer_scene_gles2.h | 4 | ||||
-rw-r--r-- | drivers/gles2/rasterizer_storage_gles2.cpp | 201 | ||||
-rw-r--r-- | drivers/gles2/rasterizer_storage_gles2.h | 12 | ||||
-rw-r--r-- | drivers/gles2/shader_compiler_gles2.cpp | 29 | ||||
-rw-r--r-- | drivers/gles2/shader_compiler_gles2.h | 4 | ||||
-rw-r--r-- | drivers/gles2/shader_gles2.cpp | 4 | ||||
-rw-r--r-- | drivers/gles2/shader_gles2.h | 9 | ||||
-rw-r--r-- | drivers/gles2/shaders/canvas.glsl | 4 | ||||
-rw-r--r-- | drivers/gles2/shaders/scene.glsl | 68 |
14 files changed, 339 insertions, 214 deletions
diff --git a/drivers/gles2/rasterizer_canvas_gles2.cpp b/drivers/gles2/rasterizer_canvas_gles2.cpp index 16e5e92abd..373d3989ce 100644 --- a/drivers/gles2/rasterizer_canvas_gles2.cpp +++ b/drivers/gles2/rasterizer_canvas_gles2.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 */ @@ -291,6 +291,10 @@ RasterizerStorageGLES2::Texture *RasterizerCanvasGLES2::_bind_canvas_texture(con void RasterizerCanvasGLES2::_draw_polygon(const int *p_indices, int p_index_count, int p_vertex_count, const Vector2 *p_vertices, const Vector2 *p_uvs, const Color *p_colors, bool p_singlecolor, const float *p_weights, const int *p_bones) { 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; @@ -339,6 +343,11 @@ void RasterizerCanvasGLES2::_draw_polygon(const int *p_indices, int p_index_coun } 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 + if (storage->config.support_32_bits_indices) { //should check for glBufferSubData(GL_ELEMENT_ARRAY_BUFFER, 0, sizeof(int) * p_index_count, p_indices); glDrawElements(GL_TRIANGLES, p_index_count, GL_UNSIGNED_INT, 0); @@ -358,6 +367,10 @@ void RasterizerCanvasGLES2::_draw_polygon(const int *p_indices, int p_index_coun void RasterizerCanvasGLES2::_draw_generic(GLuint p_primitive, int p_vertex_count, const Vector2 *p_vertices, const Vector2 *p_uvs, const Color *p_colors, bool p_singlecolor) { 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; @@ -393,6 +406,66 @@ void RasterizerCanvasGLES2::_draw_generic(GLuint p_primitive, int p_vertex_count glBindBuffer(GL_ARRAY_BUFFER, 0); } +void RasterizerCanvasGLES2::_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) { + + 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; + + 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), NULL); + buffer_ofs += sizeof(Vector2) * p_vertex_count; + + 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, 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), CAST_INT_TO_UCHAR_PTR(buffer_ofs)); + buffer_ofs += sizeof(Vector2) * p_vertex_count; + } else { + glDisableVertexAttribArray(VS::ARRAY_TEX_UV); + } + + 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 + + if (storage->config.support_32_bits_indices) { //should check for + glBufferSubData(GL_ELEMENT_ARRAY_BUFFER, 0, sizeof(int) * p_index_count, p_indices); + glDrawElements(p_primitive, p_index_count, GL_UNSIGNED_INT, 0); + } else { + uint16_t *index16 = (uint16_t *)alloca(sizeof(uint16_t) * p_index_count); + for (int i = 0; i < p_index_count; i++) { + index16[i] = uint16_t(p_indices[i]); + } + glBufferSubData(GL_ELEMENT_ARRAY_BUFFER, 0, sizeof(uint16_t) * p_index_count, index16); + glDrawElements(p_primitive, p_index_count, GL_UNSIGNED_SHORT, 0); + } + + glBindBuffer(GL_ARRAY_BUFFER, 0); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); +} + void RasterizerCanvasGLES2::_draw_gui_primitive(int p_points, const Vector2 *p_vertices, const Color *p_colors, const Vector2 *p_uvs) { static const GLenum prim[5] = { GL_POINTS, GL_POINTS, GL_LINES, GL_TRIANGLES, GL_TRIANGLE_FAN }; @@ -435,6 +508,10 @@ void RasterizerCanvasGLES2::_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 glBufferSubData(GL_ARRAY_BUFFER, 0, p_points * stride * 4 * sizeof(float), buffer_data); glVertexAttribPointer(VS::ARRAY_VERTEX, 2, GL_FLOAT, GL_FALSE, stride * sizeof(float), NULL); @@ -494,10 +571,8 @@ void RasterizerCanvasGLES2::_canvas_item_render_commands(Item *p_item, Item *cur if (line->width <= 1) { Vector2 verts[2] = { - // Offset the line slightly to make sure we always draw the pixel at the from coordinate. - // Without this, corners of rectangles might be missing a pixel. (See diamond exit rule and #32657) - Vector2(Math::floor(line->from.x) + 0.5, Math::floor(line->from.y) + 0.5), - Vector2(Math::floor(line->to.x) + 0.5, Math::floor(line->to.y) + 0.5) + Vector2(line->from.x, line->from.y), + Vector2(line->to.x, line->to.y) }; #ifdef GLES_OVER_GL @@ -751,6 +826,10 @@ void RasterizerCanvasGLES2::_canvas_item_render_commands(Item *p_item, Item *cur WARN_PRINT("NinePatch without texture not supported yet in GLES2 backend, skipping."); continue; } + if (tex->width == 0 || tex->height == 0) { + WARN_PRINT("Cannot set empty texture to NinePatch."); + continue; + } Size2 texpixel_size(1.0 / tex->width, 1.0 / tex->height); @@ -885,7 +964,7 @@ void RasterizerCanvasGLES2::_canvas_item_render_commands(Item *p_item, Item *cur } glBindBuffer(GL_ARRAY_BUFFER, data.ninepatch_vertices); - glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(float) * (16 + 16) * 2, buffer); + glBufferData(GL_ARRAY_BUFFER, sizeof(float) * (16 + 16) * 2, buffer, GL_DYNAMIC_DRAW); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, data.ninepatch_elements); @@ -954,7 +1033,11 @@ void RasterizerCanvasGLES2::_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 @@ -1811,7 +1894,7 @@ void RasterizerCanvasGLES2::canvas_light_shadow_buffer_update(RID p_buffer, cons while (instance) { - RasterizerStorageGLES2::CanvasOccluder *cc = storage->canvas_occluder_owner.get(instance->polygon_buffer); + RasterizerStorageGLES2::CanvasOccluder *cc = storage->canvas_occluder_owner.getornull(instance->polygon_buffer); if (!cc || cc->len == 0 || !(p_light_mask & instance->light_mask)) { instance = instance->next; @@ -1819,9 +1902,20 @@ void RasterizerCanvasGLES2::canvas_light_shadow_buffer_update(RID p_buffer, cons } state.canvas_shadow_shader.set_uniform(CanvasShadowShaderGLES2::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: { @@ -2036,6 +2130,8 @@ void RasterizerCanvasGLES2::initialize() { glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, data.polygon_index_buffer); glBufferData(GL_ELEMENT_ARRAY_BUFFER, index_size, NULL, GL_DYNAMIC_DRAW); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); + + data.polygon_index_buffer_size = index_size; } // ninepatch buffers diff --git a/drivers/gles2/rasterizer_canvas_gles2.h b/drivers/gles2/rasterizer_canvas_gles2.h index ab636dca71..f6ae6a60c0 100644 --- a/drivers/gles2/rasterizer_canvas_gles2.h +++ b/drivers/gles2/rasterizer_canvas_gles2.h @@ -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 */ @@ -65,6 +65,7 @@ public: GLuint polygon_index_buffer; uint32_t polygon_buffer_size; + uint32_t polygon_index_buffer_size; GLuint ninepatch_vertices; GLuint ninepatch_elements; @@ -117,6 +118,7 @@ public: _FORCE_INLINE_ void _draw_gui_primitive(int p_points, const Vector2 *p_vertices, const Color *p_colors, const Vector2 *p_uvs); _FORCE_INLINE_ void _draw_polygon(const int *p_indices, int p_index_count, int p_vertex_count, const Vector2 *p_vertices, const Vector2 *p_uvs, const Color *p_colors, bool p_singlecolor, const float *p_weights = NULL, const int *p_bones = NULL); _FORCE_INLINE_ void _draw_generic(GLuint p_primitive, int p_vertex_count, const Vector2 *p_vertices, const Vector2 *p_uvs, const Color *p_colors, bool p_singlecolor); + _FORCE_INLINE_ void _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); _FORCE_INLINE_ void _canvas_item_render_commands(Item *p_item, Item *current_clip, bool &reclip, RasterizerStorageGLES2::Material *p_material); void _copy_screen(const Rect2 &p_rect); diff --git a/drivers/gles2/rasterizer_gles2.cpp b/drivers/gles2/rasterizer_gles2.cpp index cbd0e4a5d5..c4e9541a36 100644 --- a/drivers/gles2/rasterizer_gles2.cpp +++ b/drivers/gles2/rasterizer_gles2.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 */ @@ -263,8 +263,7 @@ void RasterizerGLES2::initialize() { #endif // GLES_OVER_GL #endif // CAN_DEBUG - const GLubyte *renderer = glGetString(GL_RENDERER); - print_line("OpenGL ES 2.0 Renderer: " + String((const char *)renderer)); + print_line("OpenGL ES 2.0 Renderer: " + VisualServer::get_singleton()->get_video_adapter_name()); storage->initialize(); canvas->initialize(); scene->initialize(); diff --git a/drivers/gles2/rasterizer_gles2.h b/drivers/gles2/rasterizer_gles2.h index 4d0d961ae4..9a5501f13d 100644 --- a/drivers/gles2/rasterizer_gles2.h +++ b/drivers/gles2/rasterizer_gles2.h @@ -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 */ diff --git a/drivers/gles2/rasterizer_scene_gles2.cpp b/drivers/gles2/rasterizer_scene_gles2.cpp index f712219a64..c0ba93db6a 100644 --- a/drivers/gles2/rasterizer_scene_gles2.cpp +++ b/drivers/gles2/rasterizer_scene_gles2.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 */ @@ -557,15 +557,16 @@ bool RasterizerSceneGLES2::reflection_probe_instance_begin_render(RID p_instance glGenTextures(1, &rpi->cubemap); glBindTexture(GL_TEXTURE_CUBE_MAP, rpi->cubemap); -#if 1 - //Mobile hardware (PowerVR specially) prefers this approach, the other one kills the game + + // Mobile hardware (PowerVR specially) prefers this approach, + // the previous approach with manual lod levels kills the game. for (int i = 0; i < 6; i++) { glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, internal_format, size, size, 0, format, type, NULL); } glGenerateMipmap(GL_TEXTURE_CUBE_MAP); - //Generate framebuffers for rendering + // Generate framebuffers for rendering for (int i = 0; i < 6; i++) { glBindFramebuffer(GL_FRAMEBUFFER, rpi->fbo[i]); glBindTexture(GL_TEXTURE_2D, rpi->color[i]); @@ -576,34 +577,6 @@ bool RasterizerSceneGLES2::reflection_probe_instance_begin_render(RID p_instance ERR_CONTINUE(status != GL_FRAMEBUFFER_COMPLETE); } -#else - int lod = 0; - - //the approach below is fatal for powervr - - // Set the initial (empty) mipmaps, all need to be set for this to work in GLES2, even if they won't be used later. - while (size >= 1) { - - for (int i = 0; i < 6; i++) { - glTexImage2D(_cube_side_enum[i], lod, internal_format, size, size, 0, format, type, NULL); - if (size == rpi->current_resolution) { - //adjust framebuffer - glBindFramebuffer(GL_FRAMEBUFFER, rpi->fbo[i]); - glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, _cube_side_enum[i], rpi->cubemap, 0); - glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, rpi->depth); - -#ifdef DEBUG_ENABLED - GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER); - ERR_CONTINUE(status != GL_FRAMEBUFFER_COMPLETE); -#endif - } - } - - lod++; - - size >>= 1; - } -#endif glTexParameterf(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); glTexParameterf(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameterf(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); @@ -1169,7 +1142,7 @@ void RasterizerSceneGLES2::_add_geometry_with_material(RasterizerStorageGLES2::G LightInstance *li = light_instance_owner.getornull(e->instance->light_instances[i]); - if (li->light_index >= render_light_instance_count || render_light_instances[li->light_index] != li) { + if (!li || li->light_index >= render_light_instance_count || render_light_instances[li->light_index] != li) { continue; // too many or light_index did not correspond to the light instances to be rendered } @@ -1869,7 +1842,6 @@ void RasterizerSceneGLES2::_setup_light_type(LightInstance *p_light, ShadowAtlas state.scene_shader.set_conditional(SceneShaderGLES2::LIGHT_USE_PSSM2, false); state.scene_shader.set_conditional(SceneShaderGLES2::LIGHT_USE_PSSM4, false); state.scene_shader.set_conditional(SceneShaderGLES2::LIGHT_USE_PSSM_BLEND, false); - state.scene_shader.set_conditional(SceneShaderGLES2::USE_SHADOW, false); if (!p_light) { //no light, return off return; @@ -1955,8 +1927,7 @@ void RasterizerSceneGLES2::_setup_light(LightInstance *light, ShadowAtlas *shado Color color = light_ptr->color * sign * energy * Math_PI; state.scene_shader.set_uniform(SceneShaderGLES2::LIGHT_COLOR, color); - Color shadow_color = light_ptr->shadow_color.to_linear(); - state.scene_shader.set_uniform(SceneShaderGLES2::SHADOW_COLOR, shadow_color); + state.scene_shader.set_uniform(SceneShaderGLES2::SHADOW_COLOR, light_ptr->shadow_color); //specific parameters @@ -2342,9 +2313,7 @@ void RasterizerSceneGLES2::_render_render_list(RenderList::Element **p_elements, if (accum_pass) { //accum pass force pass blend_mode = RasterizerStorageGLES2::Shader::Spatial::BLEND_MODE_ADD; - if (rebind_light && light && light->light_ptr->negative) { - glBlendEquation(GL_FUNC_REVERSE_SUBTRACT); - glBlendFunc(GL_SRC_ALPHA, GL_ONE); + if (light && light->light_ptr->negative) { blend_mode = RasterizerStorageGLES2::Shader::Spatial::BLEND_MODE_SUB; } } @@ -2689,14 +2658,14 @@ void RasterizerSceneGLES2::_draw_sky(RasterizerStorageGLES2::Sky *p_sky, const C }; if (!asymmetrical) { - float vw, vh, zn; - camera.get_viewport_size(vw, vh); + Vector2 vp_he = camera.get_viewport_half_extents(); + float zn; zn = p_projection.get_z_near(); for (int i = 0; i < 4; i++) { Vector3 uv = vertices[i * 2 + 1]; - uv.x = (uv.x * 2.0 - 1.0) * vw; - uv.y = -(uv.y * 2.0 - 1.0) * vh; + uv.x = (uv.x * 2.0 - 1.0) * vp_he.x; + uv.y = -(uv.y * 2.0 - 1.0) * vp_he.y; uv.z = -zn; vertices[i * 2 + 1] = p_transform.basis.xform(uv).normalized(); vertices[i * 2 + 1].z = -vertices[i * 2 + 1].z; @@ -2704,7 +2673,7 @@ void RasterizerSceneGLES2::_draw_sky(RasterizerStorageGLES2::Sky *p_sky, const C } glBindBuffer(GL_ARRAY_BUFFER, state.sky_verts); - glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(Vector3) * 8, vertices); + glBufferData(GL_ARRAY_BUFFER, sizeof(Vector3) * 8, vertices, GL_DYNAMIC_DRAW); // bind sky vertex array.... glVertexAttribPointer(VS::ARRAY_VERTEX, 3, GL_FLOAT, GL_FALSE, sizeof(Vector3) * 2, 0); @@ -2767,6 +2736,8 @@ void RasterizerSceneGLES2::_post_process(Environment *env, const CameraMatrix &p if (use_post_process) { next_buffer = storage->frame.current_rt->mip_maps[0].sizes[0].fbo; + } else if (storage->frame.current_rt->external.fbo != 0) { + next_buffer = storage->frame.current_rt->external.fbo; } else { // set next_buffer to front buffer so multisample blit can happen if needed next_buffer = storage->frame.current_rt->fbo; @@ -2795,9 +2766,15 @@ void RasterizerSceneGLES2::_post_process(Environment *env, const CameraMatrix &p // In GLES2 Android Blit is not available, so just copy color texture manually _copy_texture_to_buffer(storage->frame.current_rt->multisample_color, next_buffer); +#else + // TODO: any other platform not supported? this will fail.. maybe we should just call _copy_texture_to_buffer here as well? #endif } else if (use_post_process) { - _copy_texture_to_buffer(storage->frame.current_rt->color, storage->frame.current_rt->mip_maps[0].sizes[0].fbo); + if (storage->frame.current_rt->external.fbo != 0) { + _copy_texture_to_buffer(storage->frame.current_rt->external.color, storage->frame.current_rt->mip_maps[0].sizes[0].fbo); + } else { + _copy_texture_to_buffer(storage->frame.current_rt->color, storage->frame.current_rt->mip_maps[0].sizes[0].fbo); + } } if (!use_post_process) { @@ -3220,14 +3197,12 @@ void RasterizerSceneGLES2::render_scene(const Transform &p_cam_transform, const } else { state.render_no_shadows = false; - if (storage->frame.current_rt->external.fbo != 0) { + if (storage->frame.current_rt->multisample_active) { + current_fb = storage->frame.current_rt->multisample_fbo; + } else if (storage->frame.current_rt->external.fbo != 0) { current_fb = storage->frame.current_rt->external.fbo; } else { - if (storage->frame.current_rt->multisample_active) { - current_fb = storage->frame.current_rt->multisample_fbo; - } else { - current_fb = storage->frame.current_rt->fbo; - } + current_fb = storage->frame.current_rt->fbo; } env = environment_owner.getornull(p_environment); @@ -3323,6 +3298,7 @@ void RasterizerSceneGLES2::render_scene(const Transform &p_cam_transform, const glDepthMask(GL_TRUE); glClearDepth(1.0f); glEnable(GL_DEPTH_TEST); + glClear(GL_DEPTH_BUFFER_BIT); // clear color @@ -3349,13 +3325,12 @@ void RasterizerSceneGLES2::render_scene(const Transform &p_cam_transform, const if (!env || env->bg_mode != VS::ENV_BG_KEEP) { glClearColor(clear_color.r, clear_color.g, clear_color.b, clear_color.a); + glClear(GL_COLOR_BUFFER_BIT); } state.default_ambient = Color(clear_color.r, clear_color.g, clear_color.b, 1.0); state.default_bg = Color(clear_color.r, clear_color.g, clear_color.b, 1.0); - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - if (storage->frame.current_rt && storage->frame.current_rt->flags[RasterizerStorage::RENDER_TARGET_DIRECT_TO_SCREEN]) { glDisable(GL_SCISSOR_TEST); } diff --git a/drivers/gles2/rasterizer_scene_gles2.h b/drivers/gles2/rasterizer_scene_gles2.h index 7babcfeed1..74adae05aa 100644 --- a/drivers/gles2/rasterizer_scene_gles2.h +++ b/drivers/gles2/rasterizer_scene_gles2.h @@ -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 */ diff --git a/drivers/gles2/rasterizer_storage_gles2.cpp b/drivers/gles2/rasterizer_storage_gles2.cpp index 9d9bceb243..cd6a7d86c6 100644 --- a/drivers/gles2/rasterizer_storage_gles2.cpp +++ b/drivers/gles2/rasterizer_storage_gles2.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 */ @@ -85,7 +85,9 @@ GLuint RasterizerStorageGLES2::system_fbo = 0; #define glClearDepth glClearDepthf // enable extensions manually for android and ios +#ifndef UWP_ENABLED #include <dlfcn.h> // needed to load extensions +#endif #ifdef IPHONE_ENABLED @@ -93,15 +95,21 @@ GLuint RasterizerStorageGLES2::system_fbo = 0; //void *glRenderbufferStorageMultisampleAPPLE; //void *glResolveMultisampleFramebufferAPPLE; #define glRenderbufferStorageMultisample glRenderbufferStorageMultisampleAPPLE -#elif ANDROID_ENABLED +#elif defined(ANDROID_ENABLED) #include <GLES2/gl2ext.h> PFNGLRENDERBUFFERSTORAGEMULTISAMPLEEXTPROC glRenderbufferStorageMultisampleEXT; PFNGLFRAMEBUFFERTEXTURE2DMULTISAMPLEEXTPROC glFramebufferTexture2DMultisampleEXT; #define glRenderbufferStorageMultisample glRenderbufferStorageMultisampleEXT #define glFramebufferTexture2DMultisample glFramebufferTexture2DMultisampleEXT + +#elif defined(UWP_ENABLED) +#include <GLES2/gl2ext.h> +#define glRenderbufferStorageMultisample glRenderbufferStorageMultisampleANGLE +#define glFramebufferTexture2DMultisample glFramebufferTexture2DMultisampleANGLE #endif +#define GL_TEXTURE_3D 0x806F #define GL_MAX_SAMPLES 0x8D57 #endif //!GLES_OVER_GL @@ -558,11 +566,11 @@ void RasterizerStorageGLES2::texture_allocate(RID p_texture, int p_width, int p_ texture->target = GL_TEXTURE_CUBE_MAP; texture->images.resize(6); } break; - case VS::TEXTURE_TYPE_2D_ARRAY: { - texture->images.resize(p_depth_3d); - } break; + case VS::TEXTURE_TYPE_2D_ARRAY: case VS::TEXTURE_TYPE_3D: { - texture->images.resize(p_depth_3d); + texture->target = GL_TEXTURE_3D; + ERR_PRINT("3D textures and Texture Arrays are not supported in GLES2. Please switch to the GLES3 backend."); + return; } break; default: { ERR_PRINT("Unknown texture type!"); @@ -619,6 +627,10 @@ void RasterizerStorageGLES2::texture_set_data(RID p_texture, const Ref<Image> &p Texture *texture = texture_owner.getornull(p_texture); ERR_FAIL_COND(!texture); + if (texture->target == GL_TEXTURE_3D) { + // Target is set to a 3D texture or array texture, exit early to avoid spamming errors + return; + } ERR_FAIL_COND(!texture->active); ERR_FAIL_COND(texture->render_target); ERR_FAIL_COND(texture->format != p_image->get_format()); @@ -1194,32 +1206,21 @@ void RasterizerStorageGLES2::sky_set_texture(RID p_sky, RID p_panorama, int p_ra GLenum type = GL_UNSIGNED_BYTE; // Set the initial (empty) mipmaps -#if 1 - //Mobile hardware (PowerVR specially) prefers this approach, the other one kills the game + // Mobile hardware (PowerVR specially) prefers this approach, + // the previous approach with manual lod levels kills the game. for (int i = 0; i < 6; i++) { glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, internal_format, size, size, 0, format, type, NULL); } glGenerateMipmap(GL_TEXTURE_CUBE_MAP); - //no filters for now + + // No filters for now glTexParameterf(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameterf(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameterf(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameterf(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); -#else - while (size >= 1) { - - for (int i = 0; i < 6; i++) { - glTexImage2D(_cube_side_enum[i], lod, internal_format, size, size, 0, format, type, NULL); - } - - lod++; - - size >>= 1; - } -#endif - //framebuffer + // Framebuffer glBindFramebuffer(GL_FRAMEBUFFER, resources.mipmap_blur_fbo); @@ -2428,22 +2429,10 @@ void RasterizerStorageGLES2::mesh_add_surface(RID p_mesh, uint32_t p_format, VS: if (surface->blend_shape_data.size()) { ERR_PRINT_ONCE("Blend shapes are not supported in OpenGL ES 2.0"); } - surface->data = array; - surface->index_data = p_index_array; -#else - // Even on non-tools builds, a copy of the surface->data is needed in certain circumstances. - // Rigged meshes using the USE_SKELETON_SOFTWARE path need to read bone data - // from surface->data. - - // if USE_SKELETON_SOFTWARE is active - if (config.use_skeleton_software) { - // if this geometry is used specifically for skinning - if (p_format & (VS::ARRAY_FORMAT_BONES | VS::ARRAY_FORMAT_WEIGHTS)) - surface->data = array; - } - // An alternative is to always make a copy of surface->data. #endif + surface->data = array; + surface->index_data = p_index_array; surface->total_data_size += surface->array_byte_size + surface->index_array_byte_size; for (int i = 0; i < surface->skeleton_bone_used.size(); i++) { @@ -2703,6 +2692,7 @@ void RasterizerStorageGLES2::mesh_set_custom_aabb(RID p_mesh, const AABB &p_aabb ERR_FAIL_COND(!mesh); mesh->custom_aabb = p_aabb; + mesh->instance_change_notify(true, false); } AABB RasterizerStorageGLES2::mesh_get_custom_aabb(RID p_mesh) const { @@ -2867,20 +2857,20 @@ void RasterizerStorageGLES2::multimesh_allocate(RID p_multimesh, int p_instances multimesh->xform_floats = 12; } - if (multimesh->color_format == VS::MULTIMESH_COLOR_NONE) { - multimesh->color_floats = 0; - } else if (multimesh->color_format == VS::MULTIMESH_COLOR_8BIT) { + if (multimesh->color_format == VS::MULTIMESH_COLOR_8BIT) { multimesh->color_floats = 1; } else if (multimesh->color_format == VS::MULTIMESH_COLOR_FLOAT) { multimesh->color_floats = 4; + } else { + multimesh->color_floats = 0; } - if (multimesh->custom_data_format == VS::MULTIMESH_CUSTOM_DATA_NONE) { - multimesh->custom_data_floats = 0; - } else if (multimesh->custom_data_format == VS::MULTIMESH_CUSTOM_DATA_8BIT) { + if (multimesh->custom_data_format == VS::MULTIMESH_CUSTOM_DATA_8BIT) { multimesh->custom_data_floats = 1; } else if (multimesh->custom_data_format == VS::MULTIMESH_CUSTOM_DATA_FLOAT) { multimesh->custom_data_floats = 4; + } else { + multimesh->custom_data_floats = 0; } int format_floats = multimesh->color_floats + multimesh->xform_floats + multimesh->custom_data_floats; @@ -3056,6 +3046,7 @@ void RasterizerStorageGLES2::multimesh_instance_set_color(RID p_multimesh, int p ERR_FAIL_COND(!multimesh); ERR_FAIL_INDEX(p_index, multimesh->size); ERR_FAIL_COND(multimesh->color_format == VS::MULTIMESH_COLOR_NONE); + ERR_FAIL_INDEX(multimesh->color_format, VS::MULTIMESH_COLOR_MAX); int stride = multimesh->color_floats + multimesh->xform_floats + multimesh->custom_data_floats; float *dataptr = &multimesh->data.write[stride * p_index + multimesh->xform_floats]; @@ -3088,6 +3079,7 @@ void RasterizerStorageGLES2::multimesh_instance_set_custom_data(RID p_multimesh, ERR_FAIL_COND(!multimesh); ERR_FAIL_INDEX(p_index, multimesh->size); ERR_FAIL_COND(multimesh->custom_data_format == VS::MULTIMESH_CUSTOM_DATA_NONE); + ERR_FAIL_INDEX(multimesh->custom_data_format, VS::MULTIMESH_CUSTOM_DATA_MAX); int stride = multimesh->color_floats + multimesh->xform_floats + multimesh->custom_data_floats; float *dataptr = &multimesh->data.write[stride * p_index + multimesh->xform_floats + multimesh->color_floats]; @@ -3175,6 +3167,7 @@ Color RasterizerStorageGLES2::multimesh_instance_get_color(RID p_multimesh, int ERR_FAIL_COND_V(!multimesh, Color()); ERR_FAIL_INDEX_V(p_index, multimesh->size, Color()); ERR_FAIL_COND_V(multimesh->color_format == VS::MULTIMESH_COLOR_NONE, Color()); + ERR_FAIL_INDEX_V(multimesh->color_format, VS::MULTIMESH_COLOR_MAX, Color()); int stride = multimesh->color_floats + multimesh->xform_floats + multimesh->custom_data_floats; float *dataptr = &multimesh->data.write[stride * p_index + multimesh->xform_floats]; @@ -3207,6 +3200,7 @@ Color RasterizerStorageGLES2::multimesh_instance_get_custom_data(RID p_multimesh ERR_FAIL_COND_V(!multimesh, Color()); ERR_FAIL_INDEX_V(p_index, multimesh->size, Color()); ERR_FAIL_COND_V(multimesh->custom_data_format == VS::MULTIMESH_CUSTOM_DATA_NONE, Color()); + ERR_FAIL_INDEX_V(multimesh->custom_data_format, VS::MULTIMESH_CUSTOM_DATA_MAX, Color()); int stride = multimesh->color_floats + multimesh->xform_floats + multimesh->custom_data_floats; float *dataptr = &multimesh->data.write[stride * p_index + multimesh->xform_floats + multimesh->color_floats]; @@ -4583,13 +4577,24 @@ void RasterizerStorageGLES2::_render_target_allocate(RenderTarget *rt) { GLuint color_internal_format; GLuint color_format; GLuint color_type = GL_UNSIGNED_BYTE; + Image::Format image_format; if (rt->flags[RasterizerStorage::RENDER_TARGET_TRANSPARENT]) { +#ifdef GLES_OVER_GL + color_internal_format = GL_RGBA8; +#else color_internal_format = GL_RGBA; +#endif color_format = GL_RGBA; + image_format = Image::FORMAT_RGBA8; } else { +#ifdef GLES_OVER_GL + color_internal_format = GL_RGB8; +#else color_internal_format = GL_RGB; +#endif color_format = GL_RGB; + image_format = Image::FORMAT_RGB8; } rt->used_dof_blur_near = false; @@ -4646,7 +4651,7 @@ void RasterizerStorageGLES2::_render_target_allocate(RenderTarget *rt) { glGenRenderbuffers(1, &rt->depth); glBindRenderbuffer(GL_RENDERBUFFER, rt->depth); - glRenderbufferStorage(GL_RENDERBUFFER, config.depth_internalformat, rt->width, rt->height); + glRenderbufferStorage(GL_RENDERBUFFER, config.depth_buffer_internalformat, rt->width, rt->height); glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, rt->depth); } @@ -4676,10 +4681,10 @@ void RasterizerStorageGLES2::_render_target_allocate(RenderTarget *rt) { return; } - texture->format = Image::FORMAT_RGBA8; - texture->gl_format_cache = GL_RGBA; + texture->format = image_format; + texture->gl_format_cache = color_format; texture->gl_type_cache = GL_UNSIGNED_BYTE; - texture->gl_internal_format_cache = GL_RGBA; + texture->gl_internal_format_cache = color_internal_format; texture->tex_id = rt->color; texture->width = rt->width; texture->alloc_width = rt->width; @@ -4694,7 +4699,7 @@ void RasterizerStorageGLES2::_render_target_allocate(RenderTarget *rt) { /* For MSAA */ #ifndef JAVASCRIPT_ENABLED - if (rt->msaa != VS::VIEWPORT_MSAA_DISABLED && config.multisample_supported) { + if (rt->msaa >= VS::VIEWPORT_MSAA_2X && rt->msaa <= VS::VIEWPORT_MSAA_16X && config.multisample_supported) { rt->multisample_active = true; @@ -4714,7 +4719,7 @@ void RasterizerStorageGLES2::_render_target_allocate(RenderTarget *rt) { glGenRenderbuffers(1, &rt->multisample_depth); glBindRenderbuffer(GL_RENDERBUFFER, rt->multisample_depth); - glRenderbufferStorageMultisample(GL_RENDERBUFFER, msaa, config.depth_internalformat, rt->width, rt->height); + glRenderbufferStorageMultisample(GL_RENDERBUFFER, msaa, config.depth_buffer_internalformat, rt->width, rt->height); glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, rt->multisample_depth); @@ -4896,7 +4901,11 @@ void RasterizerStorageGLES2::_render_target_allocate(RenderTarget *rt) { bool used_depth = false; if (j == 0 && i == 0) { //use always - glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, rt->depth, 0); + 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); + } used_depth = true; } @@ -5090,6 +5099,11 @@ void RasterizerStorageGLES2::render_target_set_external_texture(RID p_render_tar // free this glDeleteFramebuffers(1, &rt->external.fbo); + // and this + if (rt->external.depth != 0) { + glDeleteRenderbuffers(1, &rt->external.depth); + } + // clean up our texture Texture *t = texture_owner.get(rt->external.texture); t->alloc_height = 0; @@ -5102,6 +5116,7 @@ void RasterizerStorageGLES2::render_target_set_external_texture(RID p_render_tar rt->external.fbo = 0; rt->external.color = 0; + rt->external.depth = 0; } } else { Texture *t; @@ -5136,6 +5151,7 @@ void RasterizerStorageGLES2::render_target_set_external_texture(RID p_render_tar t->render_target = rt; rt->external.texture = texture_owner.make_rid(t); + } else { // bind our frame buffer glBindFramebuffer(GL_FRAMEBUFFER, rt->external.fbo); @@ -5154,16 +5170,42 @@ void RasterizerStorageGLES2::render_target_set_external_texture(RID p_render_tar t->alloc_height = rt->width; t->alloc_width = rt->height; - // is there a point to setting the internal formats? we don't know them.. + // Switch our texture on our frame buffer +#if ANDROID_ENABLED + if (rt->msaa >= VS::VIEWPORT_MSAA_EXT_2X && rt->msaa <= VS::VIEWPORT_MSAA_EXT_4X) { + // This code only applies to the Oculus Go and Oculus Quest. Due to the the tiled nature + // of the GPU we can do a single render pass by rendering directly into our texture chains + // texture and apply MSAA as we render. + + // On any other hardware these two modes are ignored and we do not have any MSAA, + // the normal MSAA modes need to be used to enable our two pass approach + + static const int msaa_value[] = { 2, 4 }; + int msaa = msaa_value[rt->msaa - VS::VIEWPORT_MSAA_EXT_2X]; + + if (rt->external.depth == 0) { + // create a multisample depth buffer, we're not reusing Godots because Godot's didn't get created.. + glGenRenderbuffers(1, &rt->external.depth); + glBindRenderbuffer(GL_RENDERBUFFER, rt->external.depth); + glRenderbufferStorageMultisample(GL_RENDERBUFFER, msaa, config.depth_buffer_internalformat, rt->width, rt->height); + glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, rt->external.depth); + } - // set our texture as the destination for our framebuffer - glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, p_texture_id, 0); + // and set our external texture as the texture... + glFramebufferTexture2DMultisample(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, p_texture_id, 0, msaa); - // 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); + } else +#endif + { + // 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 @@ -5258,7 +5300,7 @@ RID RasterizerStorageGLES2::canvas_light_shadow_buffer_create(int p_width) { glGenRenderbuffers(1, &cls->depth); glBindRenderbuffer(GL_RENDERBUFFER, cls->depth); - glRenderbufferStorage(GL_RENDERBUFFER, config.depth_internalformat, cls->size, cls->height); + glRenderbufferStorage(GL_RENDERBUFFER, config.depth_buffer_internalformat, cls->size, cls->height); glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, cls->depth); glGenTextures(1, &cls->distance); @@ -5723,6 +5765,16 @@ int RasterizerStorageGLES2::get_render_info(VS::RenderInfo p_info) { } } +String RasterizerStorageGLES2::get_video_adapter_name() const { + + return (const char *)glGetString(GL_RENDERER); +} + +String RasterizerStorageGLES2::get_video_adapter_vendor() const { + + return (const char *)glGetString(GL_VENDOR); +} + void RasterizerStorageGLES2::initialize() { RasterizerStorageGLES2::system_fbo = 0; @@ -5739,6 +5791,8 @@ void RasterizerStorageGLES2::initialize() { config.keep_original_textures = false; config.shrink_textures_x2 = false; + config.depth_internalformat = GL_DEPTH_COMPONENT; + config.depth_type = GL_UNSIGNED_INT; #ifdef GLES_OVER_GL config.float_texture_supported = true; @@ -5746,23 +5800,32 @@ void RasterizerStorageGLES2::initialize() { config.pvrtc_supported = false; config.etc1_supported = false; config.support_npot_repeat_mipmap = true; - config.depth_internalformat = GL_DEPTH_COMPONENT; - config.depth_type = GL_UNSIGNED_INT; + config.depth_buffer_internalformat = GL_DEPTH_COMPONENT24; #else config.float_texture_supported = config.extensions.has("GL_ARB_texture_float") || config.extensions.has("GL_OES_texture_float"); config.s3tc_supported = config.extensions.has("GL_EXT_texture_compression_s3tc") || config.extensions.has("WEBGL_compressed_texture_s3tc"); config.etc1_supported = config.extensions.has("GL_OES_compressed_ETC1_RGB8_texture") || config.extensions.has("WEBGL_compressed_texture_etc1"); config.pvrtc_supported = config.extensions.has("IMG_texture_compression_pvrtc") || config.extensions.has("WEBGL_compressed_texture_pvrtc"); config.support_npot_repeat_mipmap = config.extensions.has("GL_OES_texture_npot"); - // on mobile check for 24 bit depth support + +#ifdef JAVASCRIPT_ENABLED + // RenderBuffer internal format must be 16 bits in WebGL, + // but depth_texture should default to 32 always + // if the implementation doesn't support 32, it should just quietly use 16 instead + // https://www.khronos.org/registry/webgl/extensions/WEBGL_depth_texture/ + config.depth_buffer_internalformat = GL_DEPTH_COMPONENT16; + config.depth_type = GL_UNSIGNED_INT; +#else + // on mobile check for 24 bit depth support for RenderBufferStorage if (config.extensions.has("GL_OES_depth24")) { - config.depth_internalformat = _DEPTH_COMPONENT24_OES; + config.depth_buffer_internalformat = _DEPTH_COMPONENT24_OES; config.depth_type = GL_UNSIGNED_INT; } else { - config.depth_internalformat = GL_DEPTH_COMPONENT16; + config.depth_buffer_internalformat = GL_DEPTH_COMPONENT16; config.depth_type = GL_UNSIGNED_SHORT; } #endif +#endif #ifndef GLES_OVER_GL //Manually load extensions for android and ios @@ -5838,7 +5901,7 @@ void RasterizerStorageGLES2::initialize() { GLuint depth; glGenTextures(1, &depth); glBindTexture(GL_TEXTURE_2D, depth); - glTexImage2D(GL_TEXTURE_2D, 0, config.depth_internalformat, 32, 32, 0, config.depth_internalformat, config.depth_type, NULL); + glTexImage2D(GL_TEXTURE_2D, 0, config.depth_internalformat, 32, 32, 0, GL_DEPTH_COMPONENT, config.depth_type, NULL); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); @@ -5857,8 +5920,12 @@ void RasterizerStorageGLES2::initialize() { if (status != GL_FRAMEBUFFER_COMPLETE) { // If it fails, test to see if it supports a framebuffer texture using UNSIGNED_SHORT // This is needed because many OSX devices don't support either UNSIGNED_INT or UNSIGNED_SHORT - +#ifdef GLES_OVER_GL config.depth_internalformat = GL_DEPTH_COMPONENT16; +#else + // OES_depth_texture extension only specifies GL_DEPTH_COMPONENT. + config.depth_internalformat = GL_DEPTH_COMPONENT; +#endif config.depth_type = GL_UNSIGNED_SHORT; glGenFramebuffers(1, &fbo); @@ -5866,7 +5933,7 @@ void RasterizerStorageGLES2::initialize() { glGenTextures(1, &depth); glBindTexture(GL_TEXTURE_2D, depth); - glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT16, 32, 32, 0, GL_DEPTH_COMPONENT16, GL_UNSIGNED_SHORT, NULL); + glTexImage2D(GL_TEXTURE_2D, 0, config.depth_internalformat, 32, 32, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT, NULL); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); diff --git a/drivers/gles2/rasterizer_storage_gles2.h b/drivers/gles2/rasterizer_storage_gles2.h index 27f06074ed..83697b9872 100644 --- a/drivers/gles2/rasterizer_storage_gles2.h +++ b/drivers/gles2/rasterizer_storage_gles2.h @@ -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 */ @@ -99,6 +99,7 @@ public: GLuint depth_internalformat; GLuint depth_type; + GLuint depth_buffer_internalformat; } config; @@ -1182,10 +1183,13 @@ public: struct External { GLuint fbo; GLuint color; + GLuint depth; RID texture; External() : - fbo(0) { + fbo(0), + color(0), + depth(0) { } } external; @@ -1303,6 +1307,8 @@ public: virtual int get_captured_render_info(VS::RenderInfo p_info); virtual int get_render_info(VS::RenderInfo p_info); + virtual String get_video_adapter_name() const; + virtual String get_video_adapter_vendor() const; RasterizerStorageGLES2(); }; diff --git a/drivers/gles2/shader_compiler_gles2.cpp b/drivers/gles2/shader_compiler_gles2.cpp index 7e9b6fdb82..5dec6f2fee 100644 --- a/drivers/gles2/shader_compiler_gles2.cpp +++ b/drivers/gles2/shader_compiler_gles2.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 */ @@ -80,7 +80,7 @@ static String _opstr(SL::Operator p_op) { static String _mkid(const String &p_id) { - String id = "m_" + p_id; + String id = "m_" + p_id.replace("__", "_dus_"); return id.replace("__", "_dus_"); //doubleunderscore is reserved in glsl } @@ -522,9 +522,6 @@ String ShaderCompilerGLES2::_dump_node_code(SL::Node *p_node, int p_level, Gener SL::ArrayDeclarationNode *arr_dec_node = (SL::ArrayDeclarationNode *)p_node; StringBuffer<> declaration; - if (arr_dec_node->is_const) { - declaration += "const "; - } declaration += _prestr(arr_dec_node->precision); declaration += _typestr(arr_dec_node->datatype); @@ -540,22 +537,6 @@ String ShaderCompilerGLES2::_dump_node_code(SL::Node *p_node, int p_level, Gener declaration += "["; declaration += itos(arr_dec_node->declarations[i].size); declaration += "]"; - int sz = arr_dec_node->declarations[i].initializer.size(); - if (sz > 0) { - declaration += "="; - declaration += _typestr(arr_dec_node->datatype); - declaration += "["; - declaration += itos(sz); - declaration += "]"; - declaration += "("; - for (int j = 0; j < sz; j++) { - declaration += _dump_node_code(arr_dec_node->declarations[i].initializer[j], p_level, r_gen_code, p_actions, p_default_actions, p_assigning); - if (j != sz - 1) { - declaration += ", "; - } - } - declaration += ")"; - } } code += declaration.as_string(); @@ -911,7 +892,7 @@ ShaderCompilerGLES2::ShaderCompilerGLES2() { actions[VS::SHADER_CANVAS_ITEM].renames["VERTEX"] = "outvec.xy"; actions[VS::SHADER_CANVAS_ITEM].renames["UV"] = "uv"; - actions[VS::SHADER_CANVAS_ITEM].renames["POINT_SIZE"] = "gl_PointSize"; + actions[VS::SHADER_CANVAS_ITEM].renames["POINT_SIZE"] = "point_size"; actions[VS::SHADER_CANVAS_ITEM].renames["WORLD_MATRIX"] = "modelview_matrix"; actions[VS::SHADER_CANVAS_ITEM].renames["PROJECTION_MATRIX"] = "projection_matrix"; @@ -986,7 +967,7 @@ ShaderCompilerGLES2::ShaderCompilerGLES2() { actions[VS::SHADER_SPATIAL].renames["UV"] = "uv_interp"; actions[VS::SHADER_SPATIAL].renames["UV2"] = "uv2_interp"; actions[VS::SHADER_SPATIAL].renames["COLOR"] = "color_interp"; - actions[VS::SHADER_SPATIAL].renames["POINT_SIZE"] = "gl_PointSize"; + actions[VS::SHADER_SPATIAL].renames["POINT_SIZE"] = "point_size"; // gl_InstanceID is not available in OpenGL ES 2.0 actions[VS::SHADER_SPATIAL].renames["INSTANCE_ID"] = "0"; diff --git a/drivers/gles2/shader_compiler_gles2.h b/drivers/gles2/shader_compiler_gles2.h index b8f50d6d1f..683c8bf3c4 100644 --- a/drivers/gles2/shader_compiler_gles2.h +++ b/drivers/gles2/shader_compiler_gles2.h @@ -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 */ diff --git a/drivers/gles2/shader_gles2.cpp b/drivers/gles2/shader_gles2.cpp index 58eff791ca..8bb1ef7f0f 100644 --- a/drivers/gles2/shader_gles2.cpp +++ b/drivers/gles2/shader_gles2.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 */ diff --git a/drivers/gles2/shader_gles2.h b/drivers/gles2/shader_gles2.h index 2456a83d35..f2953c9ae8 100644 --- a/drivers/gles2/shader_gles2.h +++ b/drivers/gles2/shader_gles2.h @@ -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 */ @@ -118,9 +118,12 @@ private: uint32_t code_version; bool ok; Version() { + id = 0; + vert_id = 0; + frag_id = 0; + uniform_location = NULL; code_version = 0; ok = false; - uniform_location = NULL; } }; diff --git a/drivers/gles2/shaders/canvas.glsl b/drivers/gles2/shaders/canvas.glsl index 08548ded17..afce403a9f 100644 --- a/drivers/gles2/shaders/canvas.glsl +++ b/drivers/gles2/shaders/canvas.glsl @@ -149,6 +149,8 @@ void main() { uv = uv_attrib; #endif + float point_size = 1.0; + { vec2 src_vtx = outvec.xy; /* clang-format off */ @@ -158,6 +160,8 @@ VERTEX_SHADER_CODE /* clang-format on */ } + gl_PointSize = point_size; + #if !defined(SKIP_TRANSFORM_USED) outvec = extra_matrix_instance * outvec; outvec = modelview_matrix * outvec; diff --git a/drivers/gles2/shaders/scene.glsl b/drivers/gles2/shaders/scene.glsl index e36e776881..ac7a8796a3 100644 --- a/drivers/gles2/shaders/scene.glsl +++ b/drivers/gles2/shaders/scene.glsl @@ -251,12 +251,10 @@ void light_compute( //normalized blinn always unless disabled vec3 H = normalize(V + L); float cNdotH = max(dot(N, H), 0.0); - float cVdotH = max(dot(V, H), 0.0); - float cLdotH = max(dot(L, H), 0.0); float shininess = exp2(15.0 * (1.0 - roughness) + 1.0) * 0.25; - float blinn = pow(cNdotH, shininess); + float blinn = pow(cNdotH, shininess) * cNdotL; blinn *= (shininess + 8.0) * (1.0 / (8.0 * M_PI)); - specular_brdf_NL = (blinn) / max(4.0 * cNdotV * cNdotL, 0.75); + specular_brdf_NL = blinn; #endif SRGB_APPROX(specular_brdf_NL) @@ -425,6 +423,8 @@ void main() { #define projection_matrix local_projection_matrix #define world_transform world_matrix + float point_size = 1.0; + { /* clang-format off */ @@ -433,6 +433,7 @@ VERTEX_SHADER_CODE /* clang-format on */ } + gl_PointSize = point_size; vec4 outvec = vertex; // use local coordinates @@ -1270,9 +1271,9 @@ LIGHT_SHADER_CODE //normalized blinn float shininess = exp2(15.0 * (1.0 - roughness) + 1.0) * 0.25; - float blinn = pow(cNdotH, shininess); + float blinn = pow(cNdotH, shininess) * cNdotL; blinn *= (shininess + 8.0) * (1.0 / (8.0 * M_PI)); - specular_brdf_NL = (blinn) / max(4.0 * cNdotV * cNdotL, 0.75); + specular_brdf_NL = blinn; #elif defined(SPECULAR_PHONG) @@ -1547,7 +1548,11 @@ FRAGMENT_SHADER_CODE #endif // !USE_SHADOW_TO_OPACITY #ifdef BASE_PASS - //none + + // IBL precalculations + float ndotv = clamp(dot(normal, eye_position), 0.0, 1.0); + vec3 f0 = F0(metallic, specular, albedo); + vec3 F = f0 + (max(vec3(1.0 - roughness), f0) - f0) * pow(1.0 - ndotv, 5.0); #ifdef AMBIENT_LIGHT_DISABLED ambient_light = vec3(0.0, 0.0, 0.0); @@ -1561,12 +1566,15 @@ FRAGMENT_SHADER_CODE ref_vec.z *= -1.0; specular_light = textureCubeLod(radiance_map, ref_vec, roughness * RADIANCE_MAX_LOD).xyz * bg_energy; +#ifndef USE_LIGHTMAP { vec3 ambient_dir = normalize((radiance_inverse_xform * vec4(normal, 0.0)).xyz); - vec3 env_ambient = textureCubeLod(radiance_map, ambient_dir, RADIANCE_MAX_LOD).xyz * bg_energy; + vec3 env_ambient = textureCubeLod(radiance_map, ambient_dir, 4.0).xyz * bg_energy; + env_ambient *= 1.0 - F; ambient_light = mix(ambient_color.rgb, env_ambient, ambient_sky_contribution); } +#endif #else @@ -1574,7 +1582,6 @@ FRAGMENT_SHADER_CODE specular_light = bg_color.rgb * bg_energy; #endif - #endif // AMBIENT_LIGHT_DISABLED ambient_light *= ambient_energy; @@ -1632,7 +1639,6 @@ FRAGMENT_SHADER_CODE #endif // defined(USE_REFLECTION_PROBE1) || defined(USE_REFLECTION_PROBE2) // environment BRDF approximation - { #if defined(DIFFUSE_TOON) @@ -1646,12 +1652,9 @@ FRAGMENT_SHADER_CODE const vec4 c0 = vec4(-1.0, -0.0275, -0.572, 0.022); const vec4 c1 = vec4(1.0, 0.0425, 1.04, -0.04); vec4 r = roughness * c0 + c1; - float ndotv = clamp(dot(normal, eye_position), 0.0, 1.0); float a004 = min(r.x * r.x, exp2(-9.28 * ndotv)) * r.x + r.y; vec2 env = vec2(-1.04, 1.04) * a004 + r.zw; - - vec3 f0 = F0(metallic, specular, albedo); - specular_light *= env.x * f0 + env.y; + specular_light *= env.x * F + env.y; #endif } @@ -1663,19 +1666,19 @@ FRAGMENT_SHADER_CODE #ifdef USE_LIGHTMAP_CAPTURE { - vec3 cone_dirs[12] = vec3[]( - vec3(0.0, 0.0, 1.0), - vec3(0.866025, 0.0, 0.5), - vec3(0.267617, 0.823639, 0.5), - vec3(-0.700629, 0.509037, 0.5), - vec3(-0.700629, -0.509037, 0.5), - vec3(0.267617, -0.823639, 0.5), - vec3(0.0, 0.0, -1.0), - vec3(0.866025, 0.0, -0.5), - vec3(0.267617, 0.823639, -0.5), - vec3(-0.700629, 0.509037, -0.5), - vec3(-0.700629, -0.509037, -0.5), - vec3(0.267617, -0.823639, -0.5)); + vec3 cone_dirs[12]; + cone_dirs[0] = vec3(0.0, 0.0, 1.0); + cone_dirs[1] = vec3(0.866025, 0.0, 0.5); + cone_dirs[2] = vec3(0.267617, 0.823639, 0.5); + cone_dirs[3] = vec3(-0.700629, 0.509037, 0.5); + cone_dirs[4] = vec3(-0.700629, -0.509037, 0.5); + cone_dirs[5] = vec3(0.267617, -0.823639, 0.5); + cone_dirs[6] = vec3(0.0, 0.0, -1.0); + cone_dirs[7] = vec3(0.866025, 0.0, -0.5); + cone_dirs[8] = vec3(0.267617, 0.823639, -0.5); + cone_dirs[9] = vec3(-0.700629, 0.509037, -0.5); + cone_dirs[10] = vec3(-0.700629, -0.509037, -0.5); + cone_dirs[11] = vec3(0.267617, -0.823639, -0.5); vec3 local_normal = normalize(camera_matrix * vec4(normal, 0.0)).xyz; vec4 captured = vec4(0.0); @@ -2050,17 +2053,6 @@ FRAGMENT_SHADER_CODE specular_light += specular_interp * specular_blob_intensity * light_att; diffuse_light += diffuse_interp * albedo * light_att; - // Same as above, needed for VERTEX_LIGHTING or else lights are too bright - const vec4 c0 = vec4(-1.0, -0.0275, -0.572, 0.022); - const vec4 c1 = vec4(1.0, 0.0425, 1.04, -0.04); - vec4 r = roughness * c0 + c1; - float ndotv = clamp(dot(normal, eye_position), 0.0, 1.0); - float a004 = min(r.x * r.x, exp2(-9.28 * ndotv)) * r.x + r.y; - vec2 env = vec2(-1.04, 1.04) * a004 + r.zw; - - vec3 f0 = F0(metallic, specular, albedo); - specular_light *= env.x * f0 + env.y; - #else //fragment lighting light_compute( |