diff options
author | BastiaanOlij <mux213@gmail.com> | 2017-08-21 00:17:24 +1000 |
---|---|---|
committer | Bastiaan Olij <mux213@gmail.com> | 2019-06-15 21:30:32 +1000 |
commit | 02ea99129e8f3882914431374c60a7d80c5146e1 (patch) | |
tree | 6e41adaa70a2d5a3441ba6c1d455d9b63ea8c1de /drivers/gles3/rasterizer_scene_gles3.cpp | |
parent | 0a3c21d999559617cc9cdfe261d631e6d1267374 (diff) |
Adding a new Camera Server implementation to Godot.
This is a new singleton where camera sources such as webcams or cameras on a mobile phone can register themselves with the Server.
Other parts of Godot can interact with this to obtain images from the camera as textures.
This work includes additions to the Visual Server to use this functionality to present the camera image in the background. This is specifically targetted at AR applications.
Diffstat (limited to 'drivers/gles3/rasterizer_scene_gles3.cpp')
-rw-r--r-- | drivers/gles3/rasterizer_scene_gles3.cpp | 68 |
1 files changed, 68 insertions, 0 deletions
diff --git a/drivers/gles3/rasterizer_scene_gles3.cpp b/drivers/gles3/rasterizer_scene_gles3.cpp index 7e02f2f3f5..7acb8a22bc 100644 --- a/drivers/gles3/rasterizer_scene_gles3.cpp +++ b/drivers/gles3/rasterizer_scene_gles3.cpp @@ -34,6 +34,7 @@ #include "core/os/os.h" #include "core/project_settings.h" #include "rasterizer_canvas_gles3.h" +#include "servers/camera/camera_feed.h" #include "servers/visual/visual_server_raster.h" #ifndef GLES_OVER_GL @@ -830,6 +831,12 @@ void RasterizerSceneGLES3::environment_set_ambient_light(RID p_env, const Color env->ambient_energy = p_energy; env->ambient_sky_contribution = p_sky_contribution; } +void RasterizerSceneGLES3::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 RasterizerSceneGLES3::environment_set_dof_blur_far(RID p_env, bool p_enable, float p_distance, float p_transition, float p_amount, VS::EnvironmentDOFBlurQuality p_quality) { @@ -4342,6 +4349,7 @@ void RasterizerSceneGLES3::render_scene(const Transform &p_cam_transform, const Color clear_color(0, 0, 0, 0); RasterizerStorageGLES3::Sky *sky = NULL; + Ref<CameraFeed> feed; GLuint env_radiance_tex = 0; if (state.debug_draw == VS::VIEWPORT_DEBUG_DRAW_OVERDRAW) { @@ -4376,6 +4384,9 @@ void RasterizerSceneGLES3::render_scene(const Transform &p_cam_transform, const clear_color = env->bg_color.to_linear(); 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; } @@ -4426,6 +4437,63 @@ void RasterizerSceneGLES3::render_scene(const Transform &p_cam_transform, const glEnable(GL_DEPTH_TEST); glEnable(GL_CULL_FACE); 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(CopyShaderGLES3::USE_DISPLAY_TRANSFORM, true); + storage->shaders.copy.set_conditional(CopyShaderGLES3::DISABLE_ALPHA, true); + storage->shaders.copy.set_conditional(CopyShaderGLES3::SRGB_TO_LINEAR, 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(CopyShaderGLES3::YCBCR_TO_SRGB, 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(CopyShaderGLES3::SEP_CBCR_TEXTURE, true); + storage->shaders.copy.set_conditional(CopyShaderGLES3::YCBCR_TO_SRGB, true); + }; + + storage->shaders.copy.bind(); + storage->shaders.copy.set_uniform(CopyShaderGLES3::DISPLAY_TRANSFORM, feed->get_transform()); + + _copy_screen(true, true); + + //turn off everything used + storage->shaders.copy.set_conditional(CopyShaderGLES3::USE_DISPLAY_TRANSFORM, false); + storage->shaders.copy.set_conditional(CopyShaderGLES3::DISABLE_ALPHA, false); + storage->shaders.copy.set_conditional(CopyShaderGLES3::SRGB_TO_LINEAR, false); + storage->shaders.copy.set_conditional(CopyShaderGLES3::SEP_CBCR_TEXTURE, false); + storage->shaders.copy.set_conditional(CopyShaderGLES3::YCBCR_TO_SRGB, 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: { } } |