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.cpp152
1 files changed, 127 insertions, 25 deletions
diff --git a/drivers/gles2/rasterizer_scene_gles2.cpp b/drivers/gles2/rasterizer_scene_gles2.cpp
index 268b0f1c90..ea29af7d9e 100644
--- a/drivers/gles2/rasterizer_scene_gles2.cpp
+++ b/drivers/gles2/rasterizer_scene_gles2.cpp
@@ -36,6 +36,7 @@
#include "core/project_settings.h"
#include "core/vmap.h"
#include "rasterizer_canvas_gles2.h"
+#include "servers/camera/camera_feed.h"
#include "servers/visual/visual_server_raster.h"
#ifndef GLES_OVER_GL
@@ -769,6 +770,13 @@ void RasterizerSceneGLES2::environment_set_ambient_light(RID p_env, const Color
env->ambient_sky_contribution = p_sky_contribution;
}
+void RasterizerSceneGLES2::environment_set_camera_feed_id(RID p_env, int p_camera_feed_id) {
+ Environment *env = environment_owner.getornull(p_env);
+ ERR_FAIL_COND(!env);
+
+ env->camera_feed_id = p_camera_feed_id;
+}
+
void RasterizerSceneGLES2::environment_set_dof_blur_far(RID p_env, bool p_enable, float p_distance, float p_transition, float p_amount, VS::EnvironmentDOFBlurQuality p_quality) {
Environment *env = environment_owner.getornull(p_env);
ERR_FAIL_COND(!env);
@@ -1027,6 +1035,7 @@ void RasterizerSceneGLES2::_add_geometry_with_material(RasterizerStorageGLES2::G
e->light_index = RenderList::MAX_LIGHTS;
e->use_accum_ptr = &e->use_accum;
e->instancing = (e->instance->base_type == VS::INSTANCE_MULTIMESH) ? 1 : 0;
+ e->front_facing = false;
if (e->geometry->last_pass != render_pass) {
e->geometry->last_pass = render_pass;
@@ -1046,6 +1055,10 @@ void RasterizerSceneGLES2::_add_geometry_with_material(RasterizerStorageGLES2::G
e->material_index = e->material->index;
+ if (mirror) {
+ e->front_facing = true;
+ }
+
e->refprobe_0_index = RenderList::MAX_REFLECTION_PROBES; //refprobe disabled by default
e->refprobe_1_index = RenderList::MAX_REFLECTION_PROBES; //refprobe disabled by default
@@ -1257,7 +1270,29 @@ static const GLenum gl_primitive[] = {
GL_TRIANGLE_FAN
};
-bool RasterizerSceneGLES2::_setup_material(RasterizerStorageGLES2::Material *p_material, bool p_reverse_cull, bool p_alpha_pass, Size2i p_skeleton_tex_size) {
+void RasterizerSceneGLES2::_set_cull(bool p_front, bool p_disabled, bool p_reverse_cull) {
+
+ bool front = p_front;
+ if (p_reverse_cull)
+ front = !front;
+
+ if (p_disabled != state.cull_disabled) {
+ if (p_disabled)
+ glDisable(GL_CULL_FACE);
+ else
+ glEnable(GL_CULL_FACE);
+
+ state.cull_disabled = p_disabled;
+ }
+
+ if (front != state.cull_front) {
+
+ glCullFace(front ? GL_FRONT : GL_BACK);
+ state.cull_front = front;
+ }
+}
+
+bool RasterizerSceneGLES2::_setup_material(RasterizerStorageGLES2::Material *p_material, bool p_alpha_pass, Size2i p_skeleton_tex_size) {
// material parameters
@@ -1295,21 +1330,6 @@ bool RasterizerSceneGLES2::_setup_material(RasterizerStorageGLES2::Material *p_m
} break;
}
- switch (p_material->shader->spatial.cull_mode) {
- case RasterizerStorageGLES2::Shader::Spatial::CULL_MODE_DISABLED: {
- glDisable(GL_CULL_FACE);
- } break;
-
- case RasterizerStorageGLES2::Shader::Spatial::CULL_MODE_BACK: {
- glEnable(GL_CULL_FACE);
- glCullFace(p_reverse_cull ? GL_FRONT : GL_BACK);
- } break;
- case RasterizerStorageGLES2::Shader::Spatial::CULL_MODE_FRONT: {
- glEnable(GL_CULL_FACE);
- glCullFace(p_reverse_cull ? GL_BACK : GL_FRONT);
- } break;
- }
-
int tc = p_material->textures.size();
const Pair<StringName, RID> *textures = p_material->textures.ptr();
@@ -2202,6 +2222,11 @@ void RasterizerSceneGLES2::_render_render_list(RenderList::Element **p_elements,
int prev_blend_mode = -2; //will always catch the first go
+ state.cull_front = false;
+ state.cull_disabled = false;
+ glCullFace(GL_BACK);
+ glEnable(GL_CULL_FACE);
+
if (p_alpha_pass) {
glEnable(GL_BLEND);
} else {
@@ -2244,7 +2269,7 @@ void RasterizerSceneGLES2::_render_render_list(RenderList::Element **p_elements,
bool rebind_reflection = false;
bool rebind_lightmap = false;
- if (!p_shadow) {
+ if (!p_shadow && material->shader) {
bool unshaded = material->shader->spatial.unshaded;
@@ -2264,7 +2289,7 @@ void RasterizerSceneGLES2::_render_render_list(RenderList::Element **p_elements,
bool depth_prepass = false;
- if (!p_alpha_pass && material->shader && material->shader->spatial.depth_draw_mode == RasterizerStorageGLES2::Shader::Spatial::DEPTH_DRAW_ALPHA_PREPASS) {
+ if (!p_alpha_pass && material->shader->spatial.depth_draw_mode == RasterizerStorageGLES2::Shader::Spatial::DEPTH_DRAW_ALPHA_PREPASS) {
depth_prepass = true;
}
@@ -2441,12 +2466,14 @@ void RasterizerSceneGLES2::_render_render_list(RenderList::Element **p_elements,
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));
+ shader_rebind = _setup_material(material, p_alpha_pass, Size2i(skeleton ? skeleton->size * 3 : 0, 0));
if (shader_rebind) {
storage->info.render.shader_rebind_count++;
}
}
+ _set_cull(e->front_facing, material->shader->spatial.cull_mode == RasterizerStorageGLES2::Shader::Spatial::CULL_MODE_DISABLED, p_reverse_cull);
+
if (i == 0 || shader_rebind) { //first time must rebind
if (p_shadow) {
@@ -2695,7 +2722,8 @@ void RasterizerSceneGLES2::render_scene(const Transform &p_cam_transform, const
Environment *env = NULL;
int viewport_width, viewport_height;
- int viewport_x, viewport_y;
+ int viewport_x = 0;
+ int viewport_y = 0;
bool probe_interior = false;
bool reverse_cull = false;
@@ -2823,6 +2851,7 @@ void RasterizerSceneGLES2::render_scene(const Transform &p_cam_transform, const
// clear color
Color clear_color(0, 0, 0, 1);
+ Ref<CameraFeed> feed;
if (storage->frame.current_rt && storage->frame.current_rt->flags[RasterizerStorage::RENDER_TARGET_TRANSPARENT]) {
clear_color = Color(0, 0, 0, 0);
@@ -2835,6 +2864,9 @@ void RasterizerSceneGLES2::render_scene(const Transform &p_cam_transform, const
} else if (env->bg_mode == VS::ENV_BG_CANVAS || env->bg_mode == VS::ENV_BG_COLOR || env->bg_mode == VS::ENV_BG_COLOR_SKY) {
clear_color = env->bg_color;
storage->frame.clear_request = false;
+ } else if (env->bg_mode == VS::ENV_BG_CAMERA_FEED) {
+ feed = CameraServer::get_singleton()->get_feed_by_id(env->camera_feed_id);
+ storage->frame.clear_request = false;
} else {
storage->frame.clear_request = false;
}
@@ -2871,7 +2903,66 @@ void RasterizerSceneGLES2::render_scene(const Transform &p_cam_transform, const
env_radiance_tex = sky->radiance;
}
} break;
+ case VS::ENV_BG_CAMERA_FEED: {
+ if (feed.is_valid() && (feed->get_base_width() > 0) && (feed->get_base_height() > 0)) {
+ // copy our camera feed to our background
+
+ glDisable(GL_BLEND);
+ glDepthMask(GL_FALSE);
+ glDisable(GL_DEPTH_TEST);
+ glDisable(GL_CULL_FACE);
+
+ storage->shaders.copy.set_conditional(CopyShaderGLES2::USE_NO_ALPHA, true);
+ storage->shaders.copy.set_conditional(CopyShaderGLES2::USE_DISPLAY_TRANSFORM, true);
+
+ if (feed->get_datatype() == CameraFeed::FEED_RGB) {
+ RID camera_RGBA = feed->get_texture(CameraServer::FEED_RGBA_IMAGE);
+
+ VS::get_singleton()->texture_bind(camera_RGBA, 0);
+
+ } else if (feed->get_datatype() == CameraFeed::FEED_YCBCR) {
+ RID camera_YCbCr = feed->get_texture(CameraServer::FEED_YCBCR_IMAGE);
+
+ VS::get_singleton()->texture_bind(camera_YCbCr, 0);
+
+ storage->shaders.copy.set_conditional(CopyShaderGLES2::YCBCR_TO_RGB, true);
+
+ } else if (feed->get_datatype() == CameraFeed::FEED_YCBCR_SEP) {
+ RID camera_Y = feed->get_texture(CameraServer::FEED_Y_IMAGE);
+ RID camera_CbCr = feed->get_texture(CameraServer::FEED_CBCR_IMAGE);
+ VS::get_singleton()->texture_bind(camera_Y, 0);
+ VS::get_singleton()->texture_bind(camera_CbCr, 1);
+
+ storage->shaders.copy.set_conditional(CopyShaderGLES2::SEP_CBCR_TEXTURE, true);
+ storage->shaders.copy.set_conditional(CopyShaderGLES2::YCBCR_TO_RGB, true);
+ };
+
+ storage->shaders.copy.bind();
+ storage->shaders.copy.set_uniform(CopyShaderGLES2::DISPLAY_TRANSFORM, feed->get_transform());
+
+ storage->bind_quad_array();
+ glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
+ glDisableVertexAttribArray(VS::ARRAY_VERTEX);
+ glDisableVertexAttribArray(VS::ARRAY_TEX_UV);
+ glBindBuffer(GL_ARRAY_BUFFER, 0);
+
+ // turn off everything used
+ storage->shaders.copy.set_conditional(CopyShaderGLES2::SEP_CBCR_TEXTURE, false);
+ storage->shaders.copy.set_conditional(CopyShaderGLES2::YCBCR_TO_RGB, false);
+ storage->shaders.copy.set_conditional(CopyShaderGLES2::USE_NO_ALPHA, false);
+ storage->shaders.copy.set_conditional(CopyShaderGLES2::USE_DISPLAY_TRANSFORM, false);
+
+ //restore
+ glEnable(GL_BLEND);
+ glDepthMask(GL_TRUE);
+ glEnable(GL_DEPTH_TEST);
+ glEnable(GL_CULL_FACE);
+ } else {
+ // don't have a feed, just show greenscreen :)
+ clear_color = Color(0.0, 1.0, 0.0, 1.0);
+ }
+ } break;
default: {
// FIXME: implement other background modes
} break;
@@ -2899,7 +2990,7 @@ void RasterizerSceneGLES2::render_scene(const Transform &p_cam_transform, const
if (storage->frame.current_rt && state.used_screen_texture) {
//copy screen texture
- if (storage->frame.current_rt && storage->frame.current_rt->multisample_active) {
+ if (storage->frame.current_rt->multisample_active) {
// Resolve framebuffer to front buffer before copying
#ifdef GLES_OVER_GL
@@ -2911,14 +3002,16 @@ void RasterizerSceneGLES2::render_scene(const Transform &p_cam_transform, const
glBindFramebuffer(GL_READ_FRAMEBUFFER, 0);
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
#elif IPHONE_ENABLED
+
glBindFramebuffer(GL_READ_FRAMEBUFFER, storage->frame.current_rt->multisample_fbo);
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, storage->frame.current_rt->fbo);
glResolveMultisampleFramebufferAPPLE();
glBindFramebuffer(GL_READ_FRAMEBUFFER, 0);
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
-#else
- // In GLES2 Blit is not available, so just copy color texture manually
+#elif ANDROID_ENABLED
+
+ // In GLES2 AndroidBlit is not available, so just copy color texture manually
_copy_texture_to_front_buffer(storage->frame.current_rt->multisample_color);
#endif
}
@@ -2952,8 +3045,17 @@ void RasterizerSceneGLES2::render_scene(const Transform &p_cam_transform, const
glBindFramebuffer(GL_READ_FRAMEBUFFER, 0);
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
-#else
- // In GLES2 Blit is not available, so just copy color texture manually
+#elif IPHONE_ENABLED
+
+ glBindFramebuffer(GL_READ_FRAMEBUFFER, storage->frame.current_rt->multisample_fbo);
+ glBindFramebuffer(GL_DRAW_FRAMEBUFFER, storage->frame.current_rt->fbo);
+ glResolveMultisampleFramebufferAPPLE();
+
+ glBindFramebuffer(GL_READ_FRAMEBUFFER, 0);
+ glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
+#elif ANDROID_ENABLED
+
+ // In GLES2 Android Blit is not available, so just copy color texture manually
_copy_texture_to_front_buffer(storage->frame.current_rt->multisample_color);
#endif
}