diff options
Diffstat (limited to 'drivers/gles2/rasterizer_scene_gles2.cpp')
| -rw-r--r-- | drivers/gles2/rasterizer_scene_gles2.cpp | 152 | 
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..a07c6832dc 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  	}  |