summaryrefslogtreecommitdiff
path: root/drivers/gles2/rasterizer_storage_gles2.cpp
diff options
context:
space:
mode:
authorJuan Linietsky <juan@godotengine.org>2019-02-25 21:46:24 -0300
committerJuan Linietsky <juan@godotengine.org>2019-02-25 21:47:29 -0300
commita32b26dfa26f2a039bf9c84b90d10666bcf785c9 (patch)
tree71ba0cf141b34b242edbe39f266ef36d6054a761 /drivers/gles2/rasterizer_storage_gles2.cpp
parent51c1d55cf9089cefbde034893b4784a5d554ddcc (diff)
Several fixes to make GLES2 on HTML5 work much better.
Changed math class error reporting to be a bit less paranoid.
Diffstat (limited to 'drivers/gles2/rasterizer_storage_gles2.cpp')
-rw-r--r--drivers/gles2/rasterizer_storage_gles2.cpp98
1 files changed, 66 insertions, 32 deletions
diff --git a/drivers/gles2/rasterizer_storage_gles2.cpp b/drivers/gles2/rasterizer_storage_gles2.cpp
index 29e125e8a2..0acbb8cf51 100644
--- a/drivers/gles2/rasterizer_storage_gles2.cpp
+++ b/drivers/gles2/rasterizer_storage_gles2.cpp
@@ -1026,18 +1026,8 @@ void RasterizerStorageGLES2::sky_set_texture(RID p_sky, RID p_panorama, int p_ra
glGenTextures(1, &sky->radiance);
glBindTexture(GL_TEXTURE_CUBE_MAP, sky->radiance);
- // Now we create a new framebuffer. The new cubemap images will be used as
- // attachements for it, so we can fill them by issuing draw calls.
- GLuint tmp_fb;
-
int size = p_radiance_size / 4; //divide by four because its a cubemap (this is an approximation because GLES3 uses a dual paraboloid)
- int lod = 0;
-
- int mipmaps = 6;
-
- int mm_level = mipmaps;
-
GLenum internal_format = GL_RGB;
GLenum format = GL_RGB;
GLenum type = GL_UNSIGNED_BYTE;
@@ -1050,6 +1040,12 @@ void RasterizerStorageGLES2::sky_set_texture(RID p_sky, RID p_panorama, int p_ra
}
glGenerateMipmap(GL_TEXTURE_CUBE_MAP);
+ //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) {
@@ -1063,39 +1059,50 @@ void RasterizerStorageGLES2::sky_set_texture(RID p_sky, RID p_panorama, int p_ra
}
#endif
//framebuffer
- glGenFramebuffers(1, &tmp_fb);
- glBindFramebuffer(GL_FRAMEBUFFER, tmp_fb);
- shaders.cubemap_filter.set_conditional(CubemapFilterShaderGLES2::USE_SOURCE_PANORAMA, texture->target == GL_TEXTURE_2D);
-
- shaders.cubemap_filter.bind();
- lod = 0;
- mm_level = mipmaps;
+ glBindFramebuffer(GL_FRAMEBUFFER, resources.mipmap_blur_fbo);
+ int mipmaps = 6;
+ int lod = 0;
+ int mm_level = mipmaps;
size = p_radiance_size;
+ shaders.cubemap_filter.set_conditional(CubemapFilterShaderGLES2::USE_SOURCE_PANORAMA, true);
+ shaders.cubemap_filter.set_conditional(CubemapFilterShaderGLES2::USE_DIRECT_WRITE, true);
+ shaders.cubemap_filter.bind();
- // now render to the framebuffer, mipmap level for mipmap level
+ // third, render to the framebuffer using separate textures, then copy to mipmaps
while (size >= 1) {
+ //make framebuffer size the texture size, need to use a separate texture for compatibility
+ glActiveTexture(GL_TEXTURE3);
+ glBindTexture(GL_TEXTURE_2D, resources.mipmap_blur_color);
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, size, size, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL);
+ glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, resources.mipmap_blur_color, 0);
+ if (lod == 1) {
+ //bind panorama for smaller lods
+
+ glActiveTexture(GL_TEXTURE0);
+ glBindTexture(GL_TEXTURE_CUBE_MAP, sky->radiance);
+ shaders.cubemap_filter.set_conditional(CubemapFilterShaderGLES2::USE_SOURCE_PANORAMA, false);
+ shaders.cubemap_filter.set_conditional(CubemapFilterShaderGLES2::USE_DIRECT_WRITE, false);
+ shaders.cubemap_filter.bind();
+ }
+ glViewport(0, 0, size, size);
+ bind_quad_array();
- for (int i = 0; i < 6; i++) {
- glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, _cube_side_enum[i], sky->radiance, lod);
-
- GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
- if (status != GL_FRAMEBUFFER_COMPLETE) {
- break; //may be too small
- }
-
- glViewport(0, 0, size, size);
+ glActiveTexture(GL_TEXTURE2); //back to panorama
- bind_quad_array();
+ for (int i = 0; i < 6; i++) {
shaders.cubemap_filter.set_uniform(CubemapFilterShaderGLES2::FACE_ID, i);
- float roughness = mm_level ? lod / (float)(mipmaps - 1) : 1;
+ float roughness = mm_level >= 0 ? lod / (float)(mipmaps - 1) : 1;
roughness = MIN(1.0, roughness); //keep max at 1
shaders.cubemap_filter.set_uniform(CubemapFilterShaderGLES2::ROUGHNESS, roughness);
+ shaders.cubemap_filter.set_uniform(CubemapFilterShaderGLES2::Z_FLIP, false);
glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
+
+ glCopyTexImage2D(_cube_side_enum[i], lod, GL_RGB, 0, 0, size, size, 0);
}
size >>= 1;
@@ -1105,16 +1112,28 @@ void RasterizerStorageGLES2::sky_set_texture(RID p_sky, RID p_panorama, int p_ra
lod++;
}
+ shaders.cubemap_filter.set_conditional(CubemapFilterShaderGLES2::USE_SOURCE_PANORAMA, false);
+ shaders.cubemap_filter.set_conditional(CubemapFilterShaderGLES2::USE_DIRECT_WRITE, false);
+
// restore ranges
+ glActiveTexture(GL_TEXTURE2); //back to panorama
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);
glTexParameterf(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+ glBindTexture(GL_TEXTURE_2D, 0);
+ glActiveTexture(GL_TEXTURE3); //back to panorama
+ glBindTexture(GL_TEXTURE_2D, 0);
+ glActiveTexture(GL_TEXTURE1);
+ glBindTexture(GL_TEXTURE_2D, 0);
+ glActiveTexture(GL_TEXTURE0);
+ glBindTexture(GL_TEXTURE_2D, 0);
+
// Framebuffer did its job. thank mr framebuffer
+ glActiveTexture(GL_TEXTURE0); //back to panorama
glBindFramebuffer(GL_FRAMEBUFFER, RasterizerStorageGLES2::system_fbo);
- glDeleteFramebuffers(1, &tmp_fb);
}
/* SHADER API */
@@ -2438,7 +2457,6 @@ AABB RasterizerStorageGLES2::mesh_surface_get_aabb(RID p_mesh, int p_surface) co
}
Vector<PoolVector<uint8_t> > RasterizerStorageGLES2::mesh_surface_get_blend_shapes(RID p_mesh, int p_surface) const {
- WARN_PRINT("GLES2 mesh_surface_get_blend_shapes is not implemented");
return Vector<PoolVector<uint8_t> >();
}
Vector<AABB> RasterizerStorageGLES2::mesh_surface_get_skeleton_aabb(RID p_mesh, int p_surface) const {
@@ -3662,6 +3680,7 @@ RID RasterizerStorageGLES2::reflection_probe_create() {
reflection_probe->intensity = 1.0;
reflection_probe->interior_ambient = Color();
reflection_probe->interior_ambient_energy = 1.0;
+ reflection_probe->interior_ambient_probe_contrib = 0.0;
reflection_probe->max_distance = 0;
reflection_probe->extents = Vector3(1, 1, 1);
reflection_probe->origin_offset = Vector3(0, 0, 0);
@@ -3747,6 +3766,7 @@ void RasterizerStorageGLES2::reflection_probe_set_as_interior(RID p_probe, bool
ERR_FAIL_COND(!reflection_probe);
reflection_probe->interior = p_enable;
+ reflection_probe->instance_change_notify(true, false);
}
void RasterizerStorageGLES2::reflection_probe_set_enable_box_projection(RID p_probe, bool p_enable) {
@@ -4962,8 +4982,10 @@ void RasterizerStorageGLES2::initialize() {
#endif
#ifdef GLES_OVER_GL
config.use_rgba_2d_shadows = false;
+ config.use_rgba_3d_shadows = false;
#else
config.use_rgba_2d_shadows = !(config.float_texture_supported && config.extensions.has("GL_EXT_texture_rg"));
+ config.use_rgba_3d_shadows = config.extensions.has("GL_OES_depth_texture");
#endif
#ifdef GLES_OVER_GL
@@ -4974,6 +4996,8 @@ void RasterizerStorageGLES2::initialize() {
#ifdef GLES_OVER_GL
config.support_write_depth = true;
+#elif defined(JAVASCRIPT_ENABLED)
+ config.support_write_depth = false;
#else
config.support_write_depth = config.extensions.has("GL_EXT_frag_depth");
#endif
@@ -4995,7 +5019,7 @@ void RasterizerStorageGLES2::initialize() {
shaders.copy.init();
shaders.cubemap_filter.init();
- bool ggx_hq = GLOBAL_GET("rendering/quality/reflections/high_quality_ggx.mobile");
+ bool ggx_hq = GLOBAL_GET("rendering/quality/reflections/high_quality_ggx");
shaders.cubemap_filter.set_conditional(CubemapFilterShaderGLES2::LOW_QUALITY, !ggx_hq);
{
@@ -5115,10 +5139,20 @@ void RasterizerStorageGLES2::initialize() {
}
glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, 512, 1, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, radical_inverse);
+ glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+ glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+ glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+ glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); //need this for proper sampling
glBindTexture(GL_TEXTURE_2D, 0);
}
+ {
+
+ glGenFramebuffers(1, &resources.mipmap_blur_fbo);
+ glGenTextures(1, &resources.mipmap_blur_color);
+ }
+
#ifdef GLES_OVER_GL
//this needs to be enabled manually in OpenGL 2.1