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.cpp319
1 files changed, 234 insertions, 85 deletions
diff --git a/drivers/gles2/rasterizer_scene_gles2.cpp b/drivers/gles2/rasterizer_scene_gles2.cpp
index 2c52895bda..3c8822175d 100644
--- a/drivers/gles2/rasterizer_scene_gles2.cpp
+++ b/drivers/gles2/rasterizer_scene_gles2.cpp
@@ -42,8 +42,6 @@
#define glClearDepth glClearDepthf
#endif
-#define _DEPTH_COMPONENT24_OES 0x81A6
-
static const GLenum _cube_side_enum[6] = {
GL_TEXTURE_CUBE_MAP_NEGATIVE_X,
@@ -62,6 +60,7 @@ RID RasterizerSceneGLES2::shadow_atlas_create() {
ShadowAtlas *shadow_atlas = memnew(ShadowAtlas);
shadow_atlas->fbo = 0;
shadow_atlas->depth = 0;
+ shadow_atlas->color = 0;
shadow_atlas->size = 0;
shadow_atlas->smallest_subdiv = 0;
@@ -84,11 +83,19 @@ void RasterizerSceneGLES2::shadow_atlas_set_size(RID p_atlas, int p_size) {
// erase the old atlast
if (shadow_atlas->fbo) {
- glDeleteTextures(1, &shadow_atlas->depth);
+ if (storage->config.use_rgba_3d_shadows) {
+ glDeleteRenderbuffers(1, &shadow_atlas->depth);
+ } else {
+ glDeleteTextures(1, &shadow_atlas->depth);
+ }
glDeleteFramebuffers(1, &shadow_atlas->fbo);
+ if (shadow_atlas->color) {
+ glDeleteTextures(1, &shadow_atlas->color);
+ }
shadow_atlas->fbo = 0;
shadow_atlas->depth = 0;
+ shadow_atlas->color = 0;
}
// erase shadow atlast references from lights
@@ -108,17 +115,36 @@ void RasterizerSceneGLES2::shadow_atlas_set_size(RID p_atlas, int p_size) {
// create a depth texture
glActiveTexture(GL_TEXTURE0);
- glGenTextures(1, &shadow_atlas->depth);
- glBindTexture(GL_TEXTURE_2D, shadow_atlas->depth);
- glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, shadow_atlas->size, shadow_atlas->size, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, NULL);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+ if (storage->config.use_rgba_3d_shadows) {
+
+ //maximum compatibility, renderbuffer and RGBA shadow
+ glGenRenderbuffers(1, &shadow_atlas->depth);
+ glBindRenderbuffer(GL_RENDERBUFFER, directional_shadow.depth);
+ glRenderbufferStorage(GL_RENDERBUFFER, storage->config.depth_internalformat, shadow_atlas->size, shadow_atlas->size);
+ glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, shadow_atlas->depth);
+
+ glGenTextures(1, &shadow_atlas->color);
+ glBindTexture(GL_TEXTURE_2D, shadow_atlas->color);
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, shadow_atlas->size, shadow_atlas->size, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+ glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+ glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+ glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, shadow_atlas->color, 0);
+ } else {
+ //just depth texture
+ glGenTextures(1, &shadow_atlas->depth);
+ glBindTexture(GL_TEXTURE_2D, shadow_atlas->depth);
+ glTexImage2D(GL_TEXTURE_2D, 0, storage->config.depth_internalformat, shadow_atlas->size, shadow_atlas->size, 0, GL_DEPTH_COMPONENT, storage->config.depth_type, NULL);
- glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, shadow_atlas->depth, 0);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+ glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, shadow_atlas->depth, 0);
+ }
glViewport(0, 0, shadow_atlas->size, shadow_atlas->size);
glDepthMask(GL_TRUE);
@@ -143,7 +169,7 @@ void RasterizerSceneGLES2::shadow_atlas_set_quadrant_subdivision(RID p_atlas, in
subdiv = int(Math::sqrt((float)subdiv));
- if (shadow_atlas->quadrants[p_quadrant].shadows.size() == subdiv)
+ if (shadow_atlas->quadrants[p_quadrant].shadows.size() == (int)subdiv)
return;
// erase all data from the quadrant
@@ -459,10 +485,11 @@ RID RasterizerSceneGLES2::reflection_probe_instance_create(RID p_probe) {
for (int i = 0; i < 6; i++) {
glGenFramebuffers(1, &rpi->fbo[i]);
+ glGenTextures(1, &rpi->color[i]);
}
- glGenFramebuffers(1, &rpi->fbo_blur);
glGenRenderbuffers(1, &rpi->depth);
+
rpi->cubemap = 0;
//glGenTextures(1, &rpi->cubemap);
@@ -510,9 +537,14 @@ bool RasterizerSceneGLES2::reflection_probe_instance_begin_render(RID p_instance
GLenum type = GL_UNSIGNED_BYTE;
glActiveTexture(GL_TEXTURE0);
+
+ glBindRenderbuffer(GL_RENDERBUFFER, rpi->depth);
+ glRenderbufferStorage(GL_RENDERBUFFER, storage->config.depth_internalformat, size, size);
+
if (rpi->cubemap != 0) {
glDeleteTextures(1, &rpi->cubemap);
}
+
glGenTextures(1, &rpi->cubemap);
glBindTexture(GL_TEXTURE_CUBE_MAP, rpi->cubemap);
#if 1
@@ -523,17 +555,15 @@ bool RasterizerSceneGLES2::reflection_probe_instance_begin_render(RID p_instance
glGenerateMipmap(GL_TEXTURE_CUBE_MAP);
- glBindRenderbuffer(GL_RENDERBUFFER, rpi->depth); //resize depth buffer
-#ifdef JAVASCRIPT_ENABLED
- glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, size, size);
-#else
- glRenderbufferStorage(GL_RENDERBUFFER, _DEPTH_COMPONENT24_OES, size, size);
-#endif
-
+ //Generate framebuffers for rendering
for (int i = 0; i < 6; i++) {
glBindFramebuffer(GL_FRAMEBUFFER, rpi->fbo[i]);
- glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, _cube_side_enum[i], rpi->cubemap, 0);
+ glBindTexture(GL_TEXTURE_2D, rpi->color[i]);
+ glTexImage2D(GL_TEXTURE_2D, 0, internal_format, size, size, 0, format, type, NULL);
+ glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, rpi->color[i], 0);
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, rpi->depth);
+ GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
+ ERR_CONTINUE(status != GL_FRAMEBUFFER_COMPLETE);
}
#else
@@ -550,8 +580,6 @@ bool RasterizerSceneGLES2::reflection_probe_instance_begin_render(RID p_instance
//adjust framebuffer
glBindFramebuffer(GL_FRAMEBUFFER, rpi->fbo[i]);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, _cube_side_enum[i], rpi->cubemap, 0);
- glBindRenderbuffer(GL_RENDERBUFFER, rpi->depth);
- glRenderbufferStorage(GL_RENDERBUFFER, _DEPTH_COMPONENT24_OES, size, size);
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, rpi->depth);
#ifdef DEBUG_ENABLED
@@ -570,6 +598,8 @@ bool RasterizerSceneGLES2::reflection_probe_instance_begin_render(RID p_instance
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);
+
+ glBindFramebuffer(GL_FRAMEBUFFER, RasterizerStorageGLES2::system_fbo);
}
return true;
@@ -579,6 +609,7 @@ bool RasterizerSceneGLES2::reflection_probe_instance_postprocess_step(RID p_inst
ReflectionProbeInstance *rpi = reflection_probe_instance_owner.getornull(p_instance);
ERR_FAIL_COND_V(!rpi, false);
+ ERR_FAIL_COND_V(rpi->current_resolution == 0, false);
int size = rpi->probe_ptr->resolution;
@@ -596,16 +627,23 @@ bool RasterizerSceneGLES2::reflection_probe_instance_postprocess_step(RID p_inst
}
}
+ glActiveTexture(GL_TEXTURE0);
+ glBindTexture(GL_TEXTURE_CUBE_MAP, rpi->cubemap);
+ glTexParameterf(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR); //use linear, no mipmaps so it does not read from what is being written to
+
+ //first of all, copy rendered textures to cubemap
+ for (int i = 0; i < 6; i++) {
+ glBindFramebuffer(GL_FRAMEBUFFER, rpi->fbo[i]);
+ glViewport(0, 0, size, size);
+ glCopyTexSubImage2D(_cube_side_enum[i], 0, 0, 0, 0, 0, size, size);
+ }
+ //do filtering
//vdc cache
glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, storage->resources.radical_inverse_vdc_cache_tex);
- glBindFramebuffer(GL_FRAMEBUFFER, rpi->fbo_blur);
// now render to the framebuffer, mipmap level for mipmap level
int lod = 1;
- glActiveTexture(GL_TEXTURE0);
- glBindTexture(GL_TEXTURE_CUBE_MAP, rpi->cubemap);
- glTexParameterf(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR); //use linear, no mipmaps so it does not read from what is being written to
size >>= 1;
int mipmaps = 6;
@@ -613,13 +651,20 @@ bool RasterizerSceneGLES2::reflection_probe_instance_postprocess_step(RID p_inst
storage->shaders.cubemap_filter.set_conditional(CubemapFilterShaderGLES2::USE_SOURCE_PANORAMA, false);
storage->shaders.cubemap_filter.bind();
+ glBindFramebuffer(GL_FRAMEBUFFER, storage->resources.mipmap_blur_fbo);
+
//blur
while (size >= 1) {
+ glActiveTexture(GL_TEXTURE3);
+ glBindTexture(GL_TEXTURE_2D, storage->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, storage->resources.mipmap_blur_color, 0);
+ glViewport(0, 0, size, size);
+ glActiveTexture(GL_TEXTURE0);
+
for (int i = 0; i < 6; i++) {
- glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, _cube_side_enum[i], rpi->cubemap, lod);
- glViewport(0, 0, size, size);
storage->bind_quad_array();
storage->shaders.cubemap_filter.set_uniform(CubemapFilterShaderGLES2::FACE_ID, i);
float roughness = CLAMP(lod / (float)(mipmaps - 1), 0, 1);
@@ -627,6 +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);
+ glCopyTexSubImage2D(_cube_side_enum[i], lod, 0, 0, 0, 0, size, size);
}
size >>= 1;
@@ -635,9 +681,14 @@ bool RasterizerSceneGLES2::reflection_probe_instance_postprocess_step(RID p_inst
}
// restore ranges
-
+ glActiveTexture(GL_TEXTURE0);
glTexParameterf(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
- glBindFramebuffer(GL_FRAMEBUFFER, 0);
+ glBindTexture(GL_TEXTURE_2D, 0);
+ glActiveTexture(GL_TEXTURE3); //back to panorama
+ glBindTexture(GL_TEXTURE_2D, 0);
+ glActiveTexture(GL_TEXTURE1);
+ glBindTexture(GL_TEXTURE_2D, 0);
+ glBindFramebuffer(GL_FRAMEBUFFER, RasterizerStorageGLES2::system_fbo);
return true;
}
@@ -1120,10 +1171,10 @@ void RasterizerSceneGLES2::_fill_render_list(InstanceBase **p_cull_result, int p
int num_surfaces = mesh->surfaces.size();
- for (int i = 0; i < num_surfaces; i++) {
- int material_index = instance->materials[i].is_valid() ? i : -1;
+ for (int j = 0; j < num_surfaces; j++) {
+ int material_index = instance->materials[j].is_valid() ? j : -1;
- RasterizerStorageGLES2::Surface *surface = mesh->surfaces[i];
+ RasterizerStorageGLES2::Surface *surface = mesh->surfaces[j];
_add_geometry(surface, instance, NULL, material_index, p_depth_pass, p_shadow_pass);
}
@@ -1143,8 +1194,8 @@ void RasterizerSceneGLES2::_fill_render_list(InstanceBase **p_cull_result, int p
int ssize = mesh->surfaces.size();
- for (int i = 0; i < ssize; i++) {
- RasterizerStorageGLES2::Surface *s = mesh->surfaces[i];
+ for (int j = 0; j < ssize; j++) {
+ RasterizerStorageGLES2::Surface *s = mesh->surfaces[j];
_add_geometry(s, instance, multi_mesh, -1, p_depth_pass, p_shadow_pass);
}
} break;
@@ -1178,9 +1229,19 @@ bool RasterizerSceneGLES2::_setup_material(RasterizerStorageGLES2::Material *p_m
state.scene_shader.set_custom_shader(p_material->shader->custom_code_id);
+ if (p_material->shader->spatial.uses_screen_texture && storage->frame.current_rt) {
+ glActiveTexture(GL_TEXTURE0 + storage->config.max_texture_image_units - 4);
+ glBindTexture(GL_TEXTURE_2D, storage->frame.current_rt->copy_screen_effect.color);
+ }
+
+ if (p_material->shader->spatial.uses_depth_texture && storage->frame.current_rt) {
+ glActiveTexture(GL_TEXTURE0 + storage->config.max_texture_image_units - 4);
+ glBindTexture(GL_TEXTURE_2D, storage->frame.current_rt->depth);
+ }
+
bool shader_rebind = state.scene_shader.bind();
- if (p_material->shader->spatial.no_depth_test) {
+ if (p_material->shader->spatial.no_depth_test || p_material->shader->spatial.uses_depth_texture) {
glDisable(GL_DEPTH_TEST);
} else {
glEnable(GL_DEPTH_TEST);
@@ -1190,19 +1251,16 @@ bool RasterizerSceneGLES2::_setup_material(RasterizerStorageGLES2::Material *p_m
case RasterizerStorageGLES2::Shader::Spatial::DEPTH_DRAW_ALPHA_PREPASS:
case RasterizerStorageGLES2::Shader::Spatial::DEPTH_DRAW_OPAQUE: {
- glDepthMask(!p_alpha_pass);
+ glDepthMask(!p_alpha_pass && !p_material->shader->spatial.uses_depth_texture);
} break;
case RasterizerStorageGLES2::Shader::Spatial::DEPTH_DRAW_ALWAYS: {
- glDepthMask(GL_TRUE);
+ glDepthMask(GL_TRUE && !p_material->shader->spatial.uses_depth_texture);
} break;
case RasterizerStorageGLES2::Shader::Spatial::DEPTH_DRAW_NEVER: {
glDepthMask(GL_FALSE);
} break;
}
- // TODO whyyyyy????
- p_reverse_cull = true;
-
switch (p_material->shader->spatial.cull_mode) {
case RasterizerStorageGLES2::Shader::Spatial::CULL_MODE_DISABLED: {
glDisable(GL_CULL_FACE);
@@ -1219,9 +1277,9 @@ bool RasterizerSceneGLES2::_setup_material(RasterizerStorageGLES2::Material *p_m
}
int tc = p_material->textures.size();
- Pair<StringName, RID> *textures = p_material->textures.ptrw();
+ const Pair<StringName, RID> *textures = p_material->textures.ptr();
- ShaderLanguage::ShaderNode::Uniform::Hint *texture_hints = p_material->shader->texture_hints.ptrw();
+ const ShaderLanguage::ShaderNode::Uniform::Hint *texture_hints = p_material->shader->texture_hints.ptr();
state.scene_shader.set_uniform(SceneShaderGLES2::SKELETON_TEXTURE_SIZE, p_skeleton_tex_size);
@@ -1254,12 +1312,12 @@ bool RasterizerSceneGLES2::_setup_material(RasterizerStorageGLES2::Material *p_m
continue;
}
- t = t->get_ptr();
-
if (t->redraw_if_visible) { //must check before proxy because this is often used with proxies
VisualServerRaster::redraw_request();
}
+ t = t->get_ptr();
+
#ifdef TOOLS_ENABLED
if (t->detect_3d) {
t->detect_3d(t->detect_3d_ud);
@@ -1300,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) {
@@ -1461,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) {
@@ -1508,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) {
@@ -1564,6 +1624,8 @@ void RasterizerSceneGLES2::_render_geometry(RenderList::Element *p_element) {
} else {
glVertexAttrib4fv(INSTANCE_ATTRIB_BASE + 3, buffer + color_ofs);
}
+ } else {
+ glVertexAttrib4f(INSTANCE_ATTRIB_BASE + 3, 1.0, 1.0, 1.0, 1.0);
}
if (multi_mesh->custom_data_floats) {
@@ -1577,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;
}
}
@@ -1611,11 +1675,10 @@ void RasterizerSceneGLES2::_render_geometry(RenderList::Element *p_element) {
if (c.texture.is_valid() && storage->texture_owner.owns(c.texture)) {
RasterizerStorageGLES2::Texture *t = storage->texture_owner.get(c.texture);
- t = t->get_ptr();
-
if (t->redraw_if_visible) {
VisualServerRaster::redraw_request();
}
+ t = t->get_ptr();
#ifdef TOOLS_ENABLED
if (t->detect_3d) {
@@ -1639,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);
@@ -1648,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);
@@ -1657,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);
@@ -1666,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);
@@ -1675,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);
@@ -1683,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());
}
@@ -1742,7 +1805,11 @@ void RasterizerSceneGLES2::_setup_light_type(LightInstance *p_light, ShadowAtlas
if (!state.render_no_shadows && p_light->light_ptr->shadow) {
state.scene_shader.set_conditional(SceneShaderGLES2::USE_SHADOW, true);
glActiveTexture(GL_TEXTURE0 + storage->config.max_texture_image_units - 3);
- glBindTexture(GL_TEXTURE_2D, directional_shadow.depth);
+ if (storage->config.use_rgba_3d_shadows) {
+ glBindTexture(GL_TEXTURE_2D, directional_shadow.color);
+ } else {
+ glBindTexture(GL_TEXTURE_2D, directional_shadow.depth);
+ }
state.scene_shader.set_conditional(SceneShaderGLES2::SHADOW_MODE_PCF_5, shadow_filter_mode == SHADOW_FILTER_PCF5);
state.scene_shader.set_conditional(SceneShaderGLES2::SHADOW_MODE_PCF_13, shadow_filter_mode == SHADOW_FILTER_PCF13);
}
@@ -1754,7 +1821,11 @@ void RasterizerSceneGLES2::_setup_light_type(LightInstance *p_light, ShadowAtlas
if (!state.render_no_shadows && shadow_atlas && p_light->light_ptr->shadow) {
state.scene_shader.set_conditional(SceneShaderGLES2::USE_SHADOW, true);
glActiveTexture(GL_TEXTURE0 + storage->config.max_texture_image_units - 3);
- glBindTexture(GL_TEXTURE_2D, shadow_atlas->depth);
+ if (storage->config.use_rgba_3d_shadows) {
+ glBindTexture(GL_TEXTURE_2D, shadow_atlas->color);
+ } else {
+ glBindTexture(GL_TEXTURE_2D, shadow_atlas->depth);
+ }
state.scene_shader.set_conditional(SceneShaderGLES2::SHADOW_MODE_PCF_5, shadow_filter_mode == SHADOW_FILTER_PCF5);
state.scene_shader.set_conditional(SceneShaderGLES2::SHADOW_MODE_PCF_13, shadow_filter_mode == SHADOW_FILTER_PCF13);
}
@@ -1765,7 +1836,11 @@ void RasterizerSceneGLES2::_setup_light_type(LightInstance *p_light, ShadowAtlas
if (!state.render_no_shadows && shadow_atlas && p_light->light_ptr->shadow) {
state.scene_shader.set_conditional(SceneShaderGLES2::USE_SHADOW, true);
glActiveTexture(GL_TEXTURE0 + storage->config.max_texture_image_units - 3);
- glBindTexture(GL_TEXTURE_2D, shadow_atlas->depth);
+ if (storage->config.use_rgba_3d_shadows) {
+ glBindTexture(GL_TEXTURE_2D, shadow_atlas->color);
+ } else {
+ glBindTexture(GL_TEXTURE_2D, shadow_atlas->depth);
+ }
state.scene_shader.set_conditional(SceneShaderGLES2::SHADOW_MODE_PCF_5, shadow_filter_mode == SHADOW_FILTER_PCF5);
state.scene_shader.set_conditional(SceneShaderGLES2::SHADOW_MODE_PCF_13, shadow_filter_mode == SHADOW_FILTER_PCF13);
}
@@ -1786,6 +1861,9 @@ 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);
+
//specific parameters
switch (light_ptr->type) {
@@ -2029,7 +2107,7 @@ void RasterizerSceneGLES2::_setup_refprobes(ReflectionProbeInstance *p_refprobe1
state.scene_shader.set_uniform(SceneShaderGLES2::REFPROBE2_USE_BOX_PROJECT, p_refprobe2->probe_ptr->box_projection);
state.scene_shader.set_uniform(SceneShaderGLES2::REFPROBE2_BOX_EXTENTS, p_refprobe2->probe_ptr->extents);
state.scene_shader.set_uniform(SceneShaderGLES2::REFPROBE2_BOX_OFFSET, p_refprobe2->probe_ptr->origin_offset);
- state.scene_shader.set_uniform(SceneShaderGLES2::REFPROBE2_EXTERIOR, !p_refprobe2->probe_ptr->interior);
+ state.scene_shader.set_uniform(SceneShaderGLES2::REFPROBE2_EXTERIOR, p_refprobe2->probe_ptr->interior);
state.scene_shader.set_uniform(SceneShaderGLES2::REFPROBE2_INTENSITY, p_refprobe2->probe_ptr->intensity);
Color ambient;
@@ -2108,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];
@@ -2315,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
@@ -2337,7 +2423,7 @@ void RasterizerSceneGLES2::_render_render_list(RenderList::Element **p_elements,
Transform sky_orientation(p_env->sky_orientation, Vector3(0.0, 0.0, 0.0));
state.scene_shader.set_uniform(SceneShaderGLES2::RADIANCE_INVERSE_XFORM, sky_orientation.affine_inverse() * p_view_transform);
} else {
- // would be a bit weird if we dont have this...
+ // would be a bit weird if we don't have this...
state.scene_shader.set_uniform(SceneShaderGLES2::RADIANCE_INVERSE_XFORM, p_view_transform);
}
}
@@ -2352,7 +2438,7 @@ void RasterizerSceneGLES2::_render_render_list(RenderList::Element **p_elements,
} else {
state.scene_shader.set_uniform(SceneShaderGLES2::BG_ENERGY, 1.0);
state.scene_shader.set_uniform(SceneShaderGLES2::AMBIENT_SKY_CONTRIBUTION, 1.0);
- state.scene_shader.set_uniform(SceneShaderGLES2::AMBIENT_COLOR, Color(1.0, 1.0, 1.0, 1.0));
+ state.scene_shader.set_uniform(SceneShaderGLES2::AMBIENT_COLOR, state.default_ambient);
state.scene_shader.set_uniform(SceneShaderGLES2::AMBIENT_ENERGY, 1.0);
}
@@ -2412,6 +2498,12 @@ void RasterizerSceneGLES2::_render_render_list(RenderList::Element **p_elements,
state.scene_shader.set_uniform(SceneShaderGLES2::WORLD_TRANSFORM, e->instance->transform);
+ if (skeleton) {
+ state.scene_shader.set_uniform(SceneShaderGLES2::SKELETON_IN_WORLD_COORDS, skeleton->use_world_transform);
+ state.scene_shader.set_uniform(SceneShaderGLES2::SKELETON_TRANSFORM, skeleton->world_transform);
+ state.scene_shader.set_uniform(SceneShaderGLES2::SKELETON_TRANSFORM_INVERSE, skeleton->world_transform_inverse);
+ }
+
if (use_lightmap_capture) { //this is per instance, must be set always if present
glUniform4fv(state.scene_shader.get_uniform_location(SceneShaderGLES2::LIGHTMAP_CAPTURES), 12, (const GLfloat *)e->instance->lightmap_capture_data.ptr());
state.scene_shader.set_uniform(SceneShaderGLES2::LIGHTMAP_CAPTURE_SKY, false);
@@ -2448,6 +2540,7 @@ void RasterizerSceneGLES2::_render_render_list(RenderList::Element **p_elements,
state.scene_shader.set_conditional(SceneShaderGLES2::FOG_DEPTH_ENABLED, false);
state.scene_shader.set_conditional(SceneShaderGLES2::FOG_HEIGHT_ENABLED, false);
state.scene_shader.set_conditional(SceneShaderGLES2::USE_RADIANCE_MAP, false);
+ state.scene_shader.set_conditional(SceneShaderGLES2::USE_DEPTH_PREPASS, false);
}
void RasterizerSceneGLES2::_draw_sky(RasterizerStorageGLES2::Sky *p_sky, const CameraMatrix &p_projection, const Transform &p_transform, bool p_vflip, float p_custom_fov, float p_energy, const Basis &p_sky_orientation) {
@@ -2464,7 +2557,6 @@ void RasterizerSceneGLES2::_draw_sky(RasterizerStorageGLES2::Sky *p_sky, const C
glDisable(GL_CULL_FACE);
glDisable(GL_BLEND);
glDepthFunc(GL_LEQUAL);
- glColorMask(1, 1, 1, 1);
// Camera
CameraMatrix camera;
@@ -2518,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);
@@ -2555,11 +2647,21 @@ void RasterizerSceneGLES2::_draw_sky(RasterizerStorageGLES2::Sky *p_sky, const C
void RasterizerSceneGLES2::render_scene(const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, InstanceBase **p_cull_result, int p_cull_count, RID *p_light_cull_result, int p_light_cull_count, RID *p_reflection_probe_cull_result, int p_reflection_probe_cull_count, RID p_environment, RID p_shadow_atlas, RID p_reflection_atlas, RID p_reflection_probe, int p_reflection_probe_pass) {
+ Transform cam_transform = p_cam_transform;
+
+ storage->info.render.object_count += p_cull_count;
+
GLuint current_fb = 0;
Environment *env = NULL;
int viewport_width, viewport_height;
bool probe_interior = false;
+ bool reverse_cull = false;
+
+ if (storage->frame.current_rt && storage->frame.current_rt->flags[RasterizerStorage::RENDER_TARGET_VFLIP]) {
+ cam_transform.basis.set_axis(1, -cam_transform.basis.get_axis(1));
+ reverse_cull = true;
+ }
if (p_reflection_probe.is_valid()) {
ReflectionProbeInstance *probe = reflection_probe_instance_owner.getornull(p_reflection_probe);
@@ -2586,6 +2688,7 @@ void RasterizerSceneGLES2::render_scene(const Transform &p_cam_transform, const
viewport_height = storage->frame.current_rt->height;
}
+ state.used_screen_texture = false;
state.viewport_size.x = viewport_width;
state.viewport_size.y = viewport_height;
state.screen_pixel_size.x = 1.0 / viewport_width;
@@ -2594,7 +2697,7 @@ void RasterizerSceneGLES2::render_scene(const Transform &p_cam_transform, const
//push back the directional lights
if (p_light_cull_count) {
- //harcoded limit of 256 lights
+ //hardcoded limit of 256 lights
render_light_instance_count = MIN(RenderList::MAX_LIGHTS, p_light_cull_count);
render_light_instances = (LightInstance **)alloca(sizeof(LightInstance *) * render_light_instance_count);
render_directional_lights = 0;
@@ -2608,7 +2711,7 @@ void RasterizerSceneGLES2::render_scene(const Transform &p_cam_transform, const
if (light->light_ptr->type == VS::LIGHT_DIRECTIONAL) {
render_directional_lights++;
- //as goin in reverse, directional lights are always first anyway
+ //as going in reverse, directional lights are always first anyway
}
light->light_index = index;
@@ -2657,7 +2760,7 @@ void RasterizerSceneGLES2::render_scene(const Transform &p_cam_transform, const
// clear color
- Color clear_color(0, 0, 0, 0);
+ Color clear_color(0, 0, 0, 1);
if (storage->frame.current_rt && storage->frame.current_rt->flags[RasterizerStorage::RENDER_TARGET_TRANSPARENT]) {
clear_color = Color(0, 0, 0, 0);
@@ -2678,6 +2781,8 @@ void RasterizerSceneGLES2::render_scene(const Transform &p_cam_transform, const
glClearColor(clear_color.r, clear_color.g, clear_color.b, clear_color.a);
}
+ state.default_ambient = Color(clear_color.r, clear_color.g, clear_color.b, 1.0);
+
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glVertexAttrib4f(VS::ARRAY_COLOR, 1, 1, 1, 1);
@@ -2709,18 +2814,23 @@ void RasterizerSceneGLES2::render_scene(const Transform &p_cam_transform, const
if (env && env->bg_mode == VS::ENV_BG_SKY && (!storage->frame.current_rt || !storage->frame.current_rt->flags[RasterizerStorage::RENDER_TARGET_TRANSPARENT])) {
if (sky && sky->panorama.is_valid()) {
- _draw_sky(sky, p_cam_projection, p_cam_transform, false, env->sky_custom_fov, env->bg_energy, env->sky_orientation);
+ _draw_sky(sky, p_cam_projection, cam_transform, false, env->sky_custom_fov, env->bg_energy, env->sky_orientation);
}
}
if (probe_interior) {
env_radiance_tex = 0; //do not use radiance texture on interiors
+ state.default_ambient = Color(0, 0, 0, 1); //black as default ambient for interior
}
// render opaque things first
render_list.sort_by_key(false);
- _render_render_list(render_list.elements, render_list.element_count, p_cam_transform, p_cam_projection, p_shadow_atlas, env, env_radiance_tex, 0.0, 0.0, false, false, false);
+ _render_render_list(render_list.elements, render_list.element_count, cam_transform, p_cam_projection, p_shadow_atlas, env, env_radiance_tex, 0.0, 0.0, reverse_cull, false, false);
+ if (storage->frame.current_rt && state.used_screen_texture) {
+ //copy screen texture
+ storage->canvas->_copy_screen(Rect2());
+ }
// alpha pass
glBlendEquation(GL_FUNC_ADD);
@@ -2728,7 +2838,7 @@ void RasterizerSceneGLES2::render_scene(const Transform &p_cam_transform, const
render_list.sort_by_depth(true);
- _render_render_list(&render_list.elements[render_list.max_elements - render_list.alpha_element_count], render_list.alpha_element_count, p_cam_transform, p_cam_projection, p_shadow_atlas, env, env_radiance_tex, 0.0, 0.0, false, true, false);
+ _render_render_list(&render_list.elements[render_list.max_elements - render_list.alpha_element_count], render_list.alpha_element_count, cam_transform, p_cam_projection, p_shadow_atlas, env, env_radiance_tex, 0.0, 0.0, reverse_cull, true, false);
glDisable(GL_DEPTH_TEST);
@@ -2899,7 +3009,7 @@ void RasterizerSceneGLES2::render_shadow(RID p_light, RID p_shadow_atlas, int p_
if (light->type == VS::LIGHT_OMNI) {
// cubemap only
- if (light->omni_shadow_mode == VS::LIGHT_OMNI_SHADOW_CUBE && storage->config.support_write_depth) {
+ if (light->omni_shadow_mode == VS::LIGHT_OMNI_SHADOW_CUBE && storage->config.support_shadow_cubemaps) {
int cubemap_index = shadow_cubemaps.size() - 1;
// find an appropriate cubemap to render to
@@ -2968,7 +3078,9 @@ void RasterizerSceneGLES2::render_shadow(RID p_light, RID p_shadow_atlas, int p_
glBindFramebuffer(GL_FRAMEBUFFER, fbo);
glDepthMask(GL_TRUE);
- glColorMask(0, 0, 0, 0);
+ if (!storage->config.use_rgba_3d_shadows) {
+ glColorMask(0, 0, 0, 0);
+ }
if (custom_vp_size) {
glViewport(0, 0, custom_vp_size, custom_vp_size);
@@ -2995,7 +3107,7 @@ void RasterizerSceneGLES2::render_shadow(RID p_light, RID p_shadow_atlas, int p_
state.scene_shader.set_conditional(SceneShaderGLES2::RENDER_DEPTH_DUAL_PARABOLOID, false);
// convert cubemap to dual paraboloid if needed
- if (light->type == VS::LIGHT_OMNI && (light->omni_shadow_mode == VS::LIGHT_OMNI_SHADOW_CUBE && storage->config.support_write_depth) && p_pass == 5) {
+ if (light->type == VS::LIGHT_OMNI && (light->omni_shadow_mode == VS::LIGHT_OMNI_SHADOW_CUBE && storage->config.support_shadow_cubemaps) && p_pass == 5) {
ShadowAtlas *shadow_atlas = shadow_atlas_owner.getornull(p_shadow_atlas);
glBindFramebuffer(GL_FRAMEBUFFER, shadow_atlas->fbo);
@@ -3041,8 +3153,12 @@ void RasterizerSceneGLES2::render_shadow(RID p_light, RID p_shadow_atlas, int p_
}
}
- glViewport(0, 0, storage->frame.current_rt->width, storage->frame.current_rt->height);
- glColorMask(1, 1, 1, 1);
+ if (storage->frame.current_rt) {
+ glViewport(0, 0, storage->frame.current_rt->width, storage->frame.current_rt->height);
+ }
+ if (!storage->config.use_rgba_3d_shadows) {
+ glColorMask(1, 1, 1, 1);
+ }
}
void RasterizerSceneGLES2::set_scene_pass(uint64_t p_pass) {
@@ -3080,6 +3196,16 @@ bool RasterizerSceneGLES2::free(RID p_rid) {
ReflectionProbeInstance *reflection_instance = reflection_probe_instance_owner.get(p_rid);
+ for (int i = 0; i < 6; i++) {
+ glDeleteFramebuffers(1, &reflection_instance->fbo[i]);
+ glDeleteTextures(1, &reflection_instance->color[i]);
+ }
+
+ if (reflection_instance->cubemap != 0) {
+ glDeleteTextures(1, &reflection_instance->cubemap);
+ }
+ glDeleteRenderbuffers(1, &reflection_instance->depth);
+
reflection_probe_release_atlas_index(p_rid);
reflection_probe_instance_owner.free(p_rid);
memdelete(reflection_instance);
@@ -3096,6 +3222,8 @@ void RasterizerSceneGLES2::set_debug_draw_mode(VS::ViewportDebugDraw p_debug_dra
void RasterizerSceneGLES2::initialize() {
state.scene_shader.init();
+
+ state.scene_shader.set_conditional(SceneShaderGLES2::USE_RGBA_SHADOWS, storage->config.use_rgba_3d_shadows);
state.cube_to_dp_shader.init();
render_list.init();
@@ -3157,7 +3285,7 @@ void RasterizerSceneGLES2::initialize() {
}
// cubemaps for shadows
- if (storage->config.support_write_depth) { //not going to be used
+ if (storage->config.support_shadow_cubemaps) { //not going to be used
int max_shadow_cubemap_sampler_size = 512;
int cube_size = max_shadow_cubemap_sampler_size;
@@ -3174,7 +3302,8 @@ void RasterizerSceneGLES2::initialize() {
glBindTexture(GL_TEXTURE_CUBE_MAP, cube.cubemap);
for (int i = 0; i < 6; i++) {
- glTexImage2D(_cube_side_enum[i], 0, GL_DEPTH_COMPONENT, cube_size, cube_size, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, NULL);
+
+ glTexImage2D(_cube_side_enum[i], 0, storage->config.depth_internalformat, cube_size, cube_size, 0, GL_DEPTH_COMPONENT, storage->config.depth_type, NULL);
}
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
@@ -3205,17 +3334,35 @@ void RasterizerSceneGLES2::initialize() {
glGenFramebuffers(1, &directional_shadow.fbo);
glBindFramebuffer(GL_FRAMEBUFFER, directional_shadow.fbo);
- glGenTextures(1, &directional_shadow.depth);
- glBindTexture(GL_TEXTURE_2D, directional_shadow.depth);
+ if (storage->config.use_rgba_3d_shadows) {
+ //maximum compatibility, renderbuffer and RGBA shadow
+ glGenRenderbuffers(1, &directional_shadow.depth);
+ glBindRenderbuffer(GL_RENDERBUFFER, directional_shadow.depth);
+ glRenderbufferStorage(GL_RENDERBUFFER, storage->config.depth_internalformat, directional_shadow.size, directional_shadow.size);
+ glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, directional_shadow.depth);
+
+ glGenTextures(1, &directional_shadow.color);
+ glBindTexture(GL_TEXTURE_2D, directional_shadow.color);
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, directional_shadow.size, directional_shadow.size, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+ glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+ glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+ glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, directional_shadow.color, 0);
+ } else {
+ //just a depth buffer
+ glGenTextures(1, &directional_shadow.depth);
+ glBindTexture(GL_TEXTURE_2D, directional_shadow.depth);
- glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, directional_shadow.size, directional_shadow.size, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, NULL);
+ glTexImage2D(GL_TEXTURE_2D, 0, storage->config.depth_internalformat, directional_shadow.size, directional_shadow.size, 0, GL_DEPTH_COMPONENT, storage->config.depth_type, NULL);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
- glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, directional_shadow.depth, 0);
+ glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, directional_shadow.depth, 0);
+ }
GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
if (status != GL_FRAMEBUFFER_COMPLETE) {
@@ -3224,6 +3371,8 @@ void RasterizerSceneGLES2::initialize() {
}
shadow_filter_mode = SHADOW_FILTER_NEAREST;
+
+ glFrontFace(GL_CW);
}
void RasterizerSceneGLES2::iteration() {