summaryrefslogtreecommitdiff
path: root/drivers/gles2/rasterizer_scene_gles2.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gles2/rasterizer_scene_gles2.cpp')
-rw-r--r--drivers/gles2/rasterizer_scene_gles2.cpp171
1 files changed, 95 insertions, 76 deletions
diff --git a/drivers/gles2/rasterizer_scene_gles2.cpp b/drivers/gles2/rasterizer_scene_gles2.cpp
index 6bcda62e7f..c433886545 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 */
@@ -53,6 +53,11 @@
#endif
#endif
+#if !defined(GLES_OVER_GL)
+#define GL_TEXTURE_2D_ARRAY 0x8C1A
+#define GL_TEXTURE_3D 0x806F
+#endif
+
static const GLenum _cube_side_enum[6] = {
GL_TEXTURE_CUBE_MAP_NEGATIVE_X,
@@ -365,7 +370,7 @@ bool RasterizerSceneGLES2::shadow_atlas_update_light(RID p_atlas, RID p_light_in
// it is take but invalid, so we can take it
shadow_atlas->shadow_owners.erase(sh->owner);
- LightInstance *sli = light_instance_owner.get(sh->owner);
+ LightInstance *sli = light_instance_owner.getornull(sh->owner);
sli->shadow_atlases.erase(p_atlas);
}
@@ -407,7 +412,7 @@ bool RasterizerSceneGLES2::shadow_atlas_update_light(RID p_atlas, RID p_light_in
// it is take but invalid, so we can take it
shadow_atlas->shadow_owners.erase(sh->owner);
- LightInstance *sli = light_instance_owner.get(sh->owner);
+ LightInstance *sli = light_instance_owner.getornull(sh->owner);
sli->shadow_atlases.erase(p_atlas);
}
@@ -557,15 +562,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 +582,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);
@@ -998,7 +976,7 @@ void RasterizerSceneGLES2::_add_geometry(RasterizerStorageGLES2::Geometry *p_geo
}
if (!material) {
- material = storage->material_owner.getptr(default_material);
+ material = storage->material_owner.getornull(default_material);
}
ERR_FAIL_COND(!material);
@@ -1045,10 +1023,10 @@ void RasterizerSceneGLES2::_add_geometry_with_material(RasterizerStorageGLES2::G
if (!p_material->shader->spatial.uses_alpha_scissor && !p_material->shader->spatial.writes_modelview_or_projection && !p_material->shader->spatial.uses_vertex && !p_material->shader->spatial.uses_discard && p_material->shader->spatial.depth_draw_mode != RasterizerStorageGLES2::Shader::Spatial::DEPTH_DRAW_ALPHA_PREPASS) {
//shader does not use discard and does not write a vertex position, use generic material
if (p_instance->cast_shadows == VS::SHADOW_CASTING_SETTING_DOUBLE_SIDED) {
- p_material = storage->material_owner.getptr(!p_shadow_pass && p_material->shader->spatial.uses_world_coordinates ? default_worldcoord_material_twosided : default_material_twosided);
+ p_material = storage->material_owner.getornull(!p_shadow_pass && p_material->shader->spatial.uses_world_coordinates ? default_worldcoord_material_twosided : default_material_twosided);
mirror = false;
} else {
- p_material = storage->material_owner.getptr(!p_shadow_pass && p_material->shader->spatial.uses_world_coordinates ? default_worldcoord_material : default_material);
+ p_material = storage->material_owner.getornull(!p_shadow_pass && p_material->shader->spatial.uses_world_coordinates ? default_worldcoord_material : default_material);
}
}
@@ -1169,7 +1147,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
}
@@ -1264,13 +1242,13 @@ void RasterizerSceneGLES2::_fill_render_list(InstanceBase **p_cull_result, int p
} break;
case VS::INSTANCE_MULTIMESH: {
- RasterizerStorageGLES2::MultiMesh *multi_mesh = storage->multimesh_owner.getptr(instance->base);
+ RasterizerStorageGLES2::MultiMesh *multi_mesh = storage->multimesh_owner.getornull(instance->base);
ERR_CONTINUE(!multi_mesh);
if (multi_mesh->size == 0 || multi_mesh->visible_instances == 0)
continue;
- RasterizerStorageGLES2::Mesh *mesh = storage->mesh_owner.getptr(multi_mesh->mesh);
+ RasterizerStorageGLES2::Mesh *mesh = storage->mesh_owner.getornull(multi_mesh->mesh);
if (!mesh)
continue;
@@ -1283,7 +1261,7 @@ void RasterizerSceneGLES2::_fill_render_list(InstanceBase **p_cull_result, int p
} break;
case VS::INSTANCE_IMMEDIATE: {
- RasterizerStorageGLES2::Immediate *im = storage->immediate_owner.getptr(instance->base);
+ RasterizerStorageGLES2::Immediate *im = storage->immediate_owner.getornull(instance->base);
ERR_CONTINUE(!im);
_add_geometry(im, instance, NULL, -1, p_depth_pass, p_shadow_pass);
@@ -1370,6 +1348,7 @@ bool RasterizerSceneGLES2::_setup_material(RasterizerStorageGLES2::Material *p_m
const Pair<StringName, RID> *textures = p_material->textures.ptr();
const ShaderLanguage::ShaderNode::Uniform::Hint *texture_hints = p_material->shader->texture_hints.ptr();
+ const ShaderLanguage::DataType *texture_types = p_material->shader->texture_types.ptr();
state.scene_shader.set_uniform(SceneShaderGLES2::SKELETON_TEXTURE_SIZE, p_skeleton_tex_size);
@@ -1383,22 +1362,66 @@ bool RasterizerSceneGLES2::_setup_material(RasterizerStorageGLES2::Material *p_m
if (!t) {
- switch (texture_hints[i]) {
- case ShaderLanguage::ShaderNode::Uniform::HINT_BLACK_ALBEDO:
- case ShaderLanguage::ShaderNode::Uniform::HINT_BLACK: {
- glBindTexture(GL_TEXTURE_2D, storage->resources.black_tex);
+ GLenum target = GL_TEXTURE_2D;
+ GLuint tex = 0;
+ switch (texture_types[i]) {
+ case ShaderLanguage::TYPE_ISAMPLER2D:
+ case ShaderLanguage::TYPE_USAMPLER2D:
+ case ShaderLanguage::TYPE_SAMPLER2D: {
+
+ switch (texture_hints[i]) {
+ case ShaderLanguage::ShaderNode::Uniform::HINT_BLACK_ALBEDO:
+ case ShaderLanguage::ShaderNode::Uniform::HINT_BLACK: {
+ tex = storage->resources.black_tex;
+ } break;
+ case ShaderLanguage::ShaderNode::Uniform::HINT_ANISO: {
+ tex = storage->resources.aniso_tex;
+ } break;
+ case ShaderLanguage::ShaderNode::Uniform::HINT_NORMAL: {
+ tex = storage->resources.normal_tex;
+ } break;
+ default: {
+ tex = storage->resources.white_tex;
+ } break;
+ }
+
} break;
- case ShaderLanguage::ShaderNode::Uniform::HINT_ANISO: {
- glBindTexture(GL_TEXTURE_2D, storage->resources.aniso_tex);
+
+ case ShaderLanguage::TYPE_SAMPLERCUBE: {
+ // TODO
} break;
- case ShaderLanguage::ShaderNode::Uniform::HINT_NORMAL: {
- glBindTexture(GL_TEXTURE_2D, storage->resources.normal_tex);
+
+ case ShaderLanguage::TYPE_ISAMPLER3D:
+ case ShaderLanguage::TYPE_USAMPLER3D:
+ case ShaderLanguage::TYPE_SAMPLER3D: {
+
+ target = GL_TEXTURE_3D;
+ tex = storage->resources.white_tex_3d;
+
+ //switch (texture_hints[i]) {
+ // TODO
+ //}
+
} break;
- default: {
- glBindTexture(GL_TEXTURE_2D, storage->resources.white_tex);
+
+ case ShaderLanguage::TYPE_ISAMPLER2DARRAY:
+ case ShaderLanguage::TYPE_USAMPLER2DARRAY:
+ case ShaderLanguage::TYPE_SAMPLER2DARRAY: {
+
+ target = GL_TEXTURE_2D_ARRAY;
+ tex = storage->resources.white_tex_array;
+
+ //switch (texture_hints[i]) {
+ // TODO
+ //}
+
} break;
+
+ default: {
+ }
}
+ glBindTexture(target, tex);
continue;
}
@@ -1477,7 +1500,7 @@ void RasterizerSceneGLES2::_setup_geometry(RenderList::Element *p_element, Raste
//use transform buffer workflow
ERR_FAIL_COND(p_skeleton->use_2d);
- PoolVector<float> &transform_buffer = storage->resources.skeleton_transform_cpu_buffer;
+ Vector<float> &transform_buffer = storage->resources.skeleton_transform_cpu_buffer;
if (!s->attribs[VS::ARRAY_BONES].enabled || !s->attribs[VS::ARRAY_WEIGHTS].enabled) {
break; // the whole instance has a skeleton, but this surface is not affected by it.
@@ -1494,10 +1517,10 @@ void RasterizerSceneGLES2::_setup_geometry(RenderList::Element *p_element, Raste
const size_t bone_weight_stride = s->attribs[VS::ARRAY_WEIGHTS].stride;
{
- PoolVector<float>::Write write = transform_buffer.write();
+ float *write = transform_buffer.ptrw();
float *buffer = write.ptr();
- PoolVector<uint8_t>::Read vertex_array_read = s->data.read();
+ const uint8_t *vertex_array_read = s->data.ptr();
const uint8_t *vertex_data = vertex_array_read.ptr();
for (int i = 0; i < s->array_len; i++) {
@@ -1766,7 +1789,7 @@ void RasterizerSceneGLES2::_render_geometry(RenderList::Element *p_element) {
storage->info.render.vertices_count += vertices;
if (c.texture.is_valid() && storage->texture_owner.owns(c.texture)) {
- RasterizerStorageGLES2::Texture *t = storage->texture_owner.get(c.texture);
+ RasterizerStorageGLES2::Texture *t = storage->texture_owner.getornull(c.texture);
if (t->redraw_if_visible) {
VisualServerRaster::redraw_request();
@@ -1869,7 +1892,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 +1977,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 +2363,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 +2708,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 +2723,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);
@@ -3137,9 +3156,9 @@ void RasterizerSceneGLES2::_post_process(Environment *env, const CameraMatrix &p
}
}
- state.tonemap_shader.set_conditional(TonemapShaderGLES2::USE_GLOW_SCREEN, env->glow_blend_mode == VS::GLOW_BLEND_MODE_SCREEN);
- state.tonemap_shader.set_conditional(TonemapShaderGLES2::USE_GLOW_SOFTLIGHT, env->glow_blend_mode == VS::GLOW_BLEND_MODE_SOFTLIGHT);
- state.tonemap_shader.set_conditional(TonemapShaderGLES2::USE_GLOW_REPLACE, env->glow_blend_mode == VS::GLOW_BLEND_MODE_REPLACE);
+ state.tonemap_shader.set_conditional(TonemapShaderGLES2::USE_GLOW_SCREEN, env->glow_blend_mode == VS::ENV_GLOW_BLEND_MODE_SCREEN);
+ state.tonemap_shader.set_conditional(TonemapShaderGLES2::USE_GLOW_SOFTLIGHT, env->glow_blend_mode == VS::ENV_GLOW_BLEND_MODE_SOFTLIGHT);
+ state.tonemap_shader.set_conditional(TonemapShaderGLES2::USE_GLOW_REPLACE, env->glow_blend_mode == VS::ENV_GLOW_BLEND_MODE_REPLACE);
}
//Adjustments
@@ -3329,6 +3348,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
@@ -3355,13 +3375,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);
}
@@ -3855,11 +3874,11 @@ bool RasterizerSceneGLES2::free(RID p_rid) {
if (light_instance_owner.owns(p_rid)) {
- LightInstance *light_instance = light_instance_owner.getptr(p_rid);
+ LightInstance *light_instance = light_instance_owner.getornull(p_rid);
//remove from shadow atlases..
for (Set<RID>::Element *E = light_instance->shadow_atlases.front(); E; E = E->next()) {
- ShadowAtlas *shadow_atlas = shadow_atlas_owner.get(E->get());
+ ShadowAtlas *shadow_atlas = shadow_atlas_owner.getornull(E->get());
ERR_CONTINUE(!shadow_atlas->shadow_owners.has(p_rid));
uint32_t key = shadow_atlas->shadow_owners[p_rid];
uint32_t q = (key >> ShadowAtlas::QUADRANT_SHIFT) & 0x3;
@@ -3874,13 +3893,13 @@ bool RasterizerSceneGLES2::free(RID p_rid) {
} else if (shadow_atlas_owner.owns(p_rid)) {
- ShadowAtlas *shadow_atlas = shadow_atlas_owner.get(p_rid);
+ ShadowAtlas *shadow_atlas = shadow_atlas_owner.getornull(p_rid);
shadow_atlas_set_size(p_rid, 0);
shadow_atlas_owner.free(p_rid);
memdelete(shadow_atlas);
} else if (reflection_probe_instance_owner.owns(p_rid)) {
- ReflectionProbeInstance *reflection_instance = reflection_probe_instance_owner.get(p_rid);
+ ReflectionProbeInstance *reflection_instance = reflection_probe_instance_owner.getornull(p_rid);
for (int i = 0; i < 6; i++) {
glDeleteFramebuffers(1, &reflection_instance->fbo[i]);