diff options
Diffstat (limited to 'drivers/gles2')
-rw-r--r-- | drivers/gles2/rasterizer_canvas_gles2.cpp | 2 | ||||
-rw-r--r-- | drivers/gles2/rasterizer_gles2.cpp | 4 | ||||
-rw-r--r-- | drivers/gles2/rasterizer_gles2.h | 2 | ||||
-rw-r--r-- | drivers/gles2/rasterizer_scene_gles2.cpp | 96 | ||||
-rw-r--r-- | drivers/gles2/rasterizer_scene_gles2.h | 4 | ||||
-rw-r--r-- | drivers/gles2/rasterizer_storage_gles2.cpp | 34 | ||||
-rw-r--r-- | drivers/gles2/rasterizer_storage_gles2.h | 1 | ||||
-rw-r--r-- | drivers/gles2/shader_compiler_gles2.cpp | 15 | ||||
-rw-r--r-- | drivers/gles2/shader_gles2.h | 2 | ||||
-rw-r--r-- | drivers/gles2/shaders/canvas.glsl | 5 | ||||
-rw-r--r-- | drivers/gles2/shaders/copy.glsl | 29 |
11 files changed, 178 insertions, 16 deletions
diff --git a/drivers/gles2/rasterizer_canvas_gles2.cpp b/drivers/gles2/rasterizer_canvas_gles2.cpp index ee722e9d6c..b82186162d 100644 --- a/drivers/gles2/rasterizer_canvas_gles2.cpp +++ b/drivers/gles2/rasterizer_canvas_gles2.cpp @@ -1081,6 +1081,8 @@ void RasterizerCanvasGLES2::_canvas_item_render_commands(Item *p_item, Item *cur } 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) { diff --git a/drivers/gles2/rasterizer_gles2.cpp b/drivers/gles2/rasterizer_gles2.cpp index f49f52e47b..cbd0e4a5d5 100644 --- a/drivers/gles2/rasterizer_gles2.cpp +++ b/drivers/gles2/rasterizer_gles2.cpp @@ -338,7 +338,7 @@ void RasterizerGLES2::clear_render_target(const Color &p_color) { storage->frame.clear_request_color = p_color; } -void RasterizerGLES2::set_boot_image(const Ref<Image> &p_image, const Color &p_color, bool p_scale) { +void RasterizerGLES2::set_boot_image(const Ref<Image> &p_image, const Color &p_color, bool p_scale, bool p_use_filter) { if (p_image.is_null() || p_image->empty()) return; @@ -360,7 +360,7 @@ void RasterizerGLES2::set_boot_image(const Ref<Image> &p_image, const Color &p_c canvas->canvas_begin(); RID texture = storage->texture_create(); - storage->texture_allocate(texture, p_image->get_width(), p_image->get_height(), 0, p_image->get_format(), VS::TEXTURE_TYPE_2D, VS::TEXTURE_FLAG_FILTER); + storage->texture_allocate(texture, p_image->get_width(), p_image->get_height(), 0, p_image->get_format(), VS::TEXTURE_TYPE_2D, p_use_filter ? VS::TEXTURE_FLAG_FILTER : 0); storage->texture_set_data(texture, p_image); Rect2 imgrect(0, 0, p_image->get_width(), p_image->get_height()); diff --git a/drivers/gles2/rasterizer_gles2.h b/drivers/gles2/rasterizer_gles2.h index eeed86e263..4d0d961ae4 100644 --- a/drivers/gles2/rasterizer_gles2.h +++ b/drivers/gles2/rasterizer_gles2.h @@ -51,7 +51,7 @@ public: virtual RasterizerCanvas *get_canvas(); virtual RasterizerScene *get_scene(); - virtual void set_boot_image(const Ref<Image> &p_image, const Color &p_color, bool p_scale); + virtual void set_boot_image(const Ref<Image> &p_image, const Color &p_color, bool p_scale, bool p_use_filter = true); virtual void initialize(); virtual void begin_frame(double frame_step); diff --git a/drivers/gles2/rasterizer_scene_gles2.cpp b/drivers/gles2/rasterizer_scene_gles2.cpp index 50cb39b13f..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); @@ -2261,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; @@ -2281,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; } @@ -2843,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); @@ -2855,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; } @@ -2891,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; @@ -2919,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 @@ -2931,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 } @@ -2972,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 } diff --git a/drivers/gles2/rasterizer_scene_gles2.h b/drivers/gles2/rasterizer_scene_gles2.h index d5a691d0b9..c95385eb24 100644 --- a/drivers/gles2/rasterizer_scene_gles2.h +++ b/drivers/gles2/rasterizer_scene_gles2.h @@ -354,6 +354,8 @@ public: float bg_energy; float sky_ambient; + int camera_feed_id; + Color ambient_color; float ambient_energy; float ambient_sky_contribution; @@ -381,6 +383,7 @@ public: sky_custom_fov(0.0), bg_energy(1.0), sky_ambient(0), + camera_feed_id(0), ambient_energy(1.0), ambient_sky_contribution(0.0), canvas_max_layer(0), @@ -413,6 +416,7 @@ public: virtual void environment_set_bg_energy(RID p_env, float p_energy); virtual void environment_set_canvas_max_layer(RID p_env, int p_max_layer); virtual void environment_set_ambient_light(RID p_env, const Color &p_color, float p_energy = 1.0, float p_sky_contribution = 0.0); + virtual void environment_set_camera_feed_id(RID p_env, int p_camera_feed_id); virtual void environment_set_dof_blur_near(RID p_env, bool p_enable, float p_distance, float p_transition, float p_amount, VS::EnvironmentDOFBlurQuality p_quality); virtual void environment_set_dof_blur_far(RID p_env, bool p_enable, float p_distance, float p_transition, float p_amount, VS::EnvironmentDOFBlurQuality p_quality); diff --git a/drivers/gles2/rasterizer_storage_gles2.cpp b/drivers/gles2/rasterizer_storage_gles2.cpp index c610f31bc1..418be136b8 100644 --- a/drivers/gles2/rasterizer_storage_gles2.cpp +++ b/drivers/gles2/rasterizer_storage_gles2.cpp @@ -91,7 +91,7 @@ GLuint RasterizerStorageGLES2::system_fbo = 0; //void *glRenderbufferStorageMultisampleAPPLE; //void *glResolveMultisampleFramebufferAPPLE; #define glRenderbufferStorageMultisample glRenderbufferStorageMultisampleAPPLE -#else +#elif ANDROID_ENABLED #include <GLES2/gl2ext.h> PFNGLRENDERBUFFERSTORAGEMULTISAMPLEEXTPROC glRenderbufferStorageMultisampleEXT; @@ -968,6 +968,15 @@ uint32_t RasterizerStorageGLES2::texture_get_texid(RID p_texture) const { return texture->tex_id; } +void RasterizerStorageGLES2::texture_bind(RID p_texture, uint32_t p_texture_no) { + Texture *texture = texture_owner.getornull(p_texture); + + ERR_FAIL_COND(!texture); + + glActiveTexture(GL_TEXTURE0 + p_texture_no); + glBindTexture(texture->target, texture->tex_id); +} + uint32_t RasterizerStorageGLES2::texture_get_width(RID p_texture) const { Texture *texture = texture_owner.getornull(p_texture); @@ -2418,6 +2427,18 @@ void RasterizerStorageGLES2::mesh_add_surface(RID p_mesh, uint32_t p_format, VS: } surface->data = array; surface->index_data = p_index_array; +#else + // Even on non-tools builds, a copy of the surface->data is needed in certain circumstances. + // Rigged meshes using the USE_SKELETON_SOFTWARE path need to read bone data + // from surface->data. + + // if USE_SKELETON_SOFTWARE is active + if (!config.float_texture_supported) { + // if this geometry is used specifically for skinning + if (p_format & (VS::ARRAY_FORMAT_BONES | VS::ARRAY_FORMAT_WEIGHTS)) + surface->data = array; + } + // An alternative is to always make a copy of surface->data. #endif surface->total_data_size += surface->array_byte_size + surface->index_array_byte_size; @@ -4688,6 +4709,7 @@ void RasterizerStorageGLES2::_render_target_allocate(RenderTarget *rt) { /* BACK FBO */ /* For MSAA */ +#ifndef JAVASCRIPT_ENABLED if (rt->msaa != VS::VIEWPORT_MSAA_DISABLED && config.multisample_supported) { rt->multisample_active = true; @@ -4719,7 +4741,7 @@ void RasterizerStorageGLES2::_render_target_allocate(RenderTarget *rt) { glRenderbufferStorageMultisample(GL_RENDERBUFFER, msaa, color_internal_format, rt->width, rt->height); glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, rt->multisample_color); -#else +#elif ANDROID_ENABLED // Render to a texture in android glGenTextures(1, &rt->multisample_color); glBindTexture(GL_TEXTURE_2D, rt->multisample_color); @@ -4743,7 +4765,9 @@ void RasterizerStorageGLES2::_render_target_allocate(RenderTarget *rt) { glBindRenderbuffer(GL_RENDERBUFFER, 0); - } else { + } else +#endif + { rt->multisample_active = false; } @@ -5602,11 +5626,11 @@ void RasterizerStorageGLES2::initialize() { //Manually load extensions for android and ios #ifdef IPHONE_ENABLED - + // appears that IPhone doesn't need to dlopen TODO: test this rigorously before removing //void *gles2_lib = dlopen(NULL, RTLD_LAZY); //glRenderbufferStorageMultisampleAPPLE = dlsym(gles2_lib, "glRenderbufferStorageMultisampleAPPLE"); //glResolveMultisampleFramebufferAPPLE = dlsym(gles2_lib, "glResolveMultisampleFramebufferAPPLE"); -#else +#elif ANDROID_ENABLED void *gles2_lib = dlopen("libGLESv2.so", RTLD_LAZY); glRenderbufferStorageMultisampleEXT = (PFNGLRENDERBUFFERSTORAGEMULTISAMPLEEXTPROC)dlsym(gles2_lib, "glRenderbufferStorageMultisampleEXT"); diff --git a/drivers/gles2/rasterizer_storage_gles2.h b/drivers/gles2/rasterizer_storage_gles2.h index af57aa3d9b..d139697b86 100644 --- a/drivers/gles2/rasterizer_storage_gles2.h +++ b/drivers/gles2/rasterizer_storage_gles2.h @@ -350,6 +350,7 @@ public: virtual uint32_t texture_get_height(RID p_texture) const; virtual uint32_t texture_get_depth(RID p_texture) const; virtual void texture_set_size_override(RID p_texture, int p_width, int p_height, int p_depth); + virtual void texture_bind(RID p_texture, uint32_t p_texture_no); virtual void texture_set_path(RID p_texture, const String &p_path); virtual String texture_get_path(RID p_texture) const; diff --git a/drivers/gles2/shader_compiler_gles2.cpp b/drivers/gles2/shader_compiler_gles2.cpp index 9778d39a21..b48b93944c 100644 --- a/drivers/gles2/shader_compiler_gles2.cpp +++ b/drivers/gles2/shader_compiler_gles2.cpp @@ -361,6 +361,21 @@ String ShaderCompilerGLES2::_dump_node_code(SL::Node *p_node, int p_level, Gener fragment_global += final_code; } + // constants + + for (Map<StringName, SL::ShaderNode::Constant>::Element *E = snode->constants.front(); E; E = E->next()) { + String gcode; + gcode += "const "; + gcode += _prestr(E->get().precision); + gcode += _typestr(E->get().type); + gcode += " " + _mkid(E->key()); + gcode += "="; + gcode += _dump_node_code(E->get().initializer, p_level, r_gen_code, p_actions, p_default_actions, p_assigning); + gcode += ";\n"; + vertex_global += gcode; + fragment_global += gcode; + } + // functions Map<StringName, String> function_code; diff --git a/drivers/gles2/shader_gles2.h b/drivers/gles2/shader_gles2.h index ebea40e10e..2456a83d35 100644 --- a/drivers/gles2/shader_gles2.h +++ b/drivers/gles2/shader_gles2.h @@ -1,4 +1,4 @@ -/*************************************************************************/ +/*************************************************************************/ /* shader_gles2.h */ /*************************************************************************/ /* This file is part of: */ diff --git a/drivers/gles2/shaders/canvas.glsl b/drivers/gles2/shaders/canvas.glsl index 7dce784f52..0818942b0a 100644 --- a/drivers/gles2/shaders/canvas.glsl +++ b/drivers/gles2/shaders/canvas.glsl @@ -112,7 +112,12 @@ void main() { #ifdef USE_INSTANCING mat4 extra_matrix_instance = extra_matrix * transpose(mat4(instance_xform0, instance_xform1, instance_xform2, vec4(0.0, 0.0, 0.0, 1.0))); color *= instance_color; + +#ifdef USE_INSTANCE_CUSTOM vec4 instance_custom = instance_custom_data; +#else + vec4 instance_custom = vec4(0.0); +#endif #else mat4 extra_matrix_instance = extra_matrix; diff --git a/drivers/gles2/shaders/copy.glsl b/drivers/gles2/shaders/copy.glsl index 931b3f3708..195db7c45f 100644 --- a/drivers/gles2/shaders/copy.glsl +++ b/drivers/gles2/shaders/copy.glsl @@ -28,8 +28,15 @@ varying vec2 uv_interp; #endif varying vec2 uv2_interp; +// These definitions are here because the shader-wrapper builder does +// not understand `#elif defined()` +#ifdef USE_DISPLAY_TRANSFORM +#endif + #ifdef USE_COPY_SECTION uniform highp vec4 copy_section; +#elif defined(USE_DISPLAY_TRANSFORM) +uniform highp mat4 display_transform; #endif void main() { @@ -48,6 +55,8 @@ void main() { #ifdef USE_COPY_SECTION uv_interp = copy_section.xy + uv_interp * copy_section.zw; gl_Position.xy = (copy_section.xy + (gl_Position.xy * 0.5 + 0.5) * copy_section.zw) * 2.0 - 1.0; +#elif defined(USE_DISPLAY_TRANSFORM) + uv_interp = (display_transform * vec4(uv_in, 1.0, 1.0)).xy; #endif } @@ -88,6 +97,10 @@ uniform samplerCube source_cube; // texunit:0 uniform sampler2D source; // texunit:0 #endif +#ifdef SEP_CBCR_TEXTURE +uniform sampler2D CbCr; //texunit:1 +#endif + varying vec2 uv2_interp; #ifdef USE_MULTIPLIER @@ -145,10 +158,26 @@ void main() { #elif defined(USE_CUBEMAP) vec4 color = textureCube(source_cube, normalize(cube_interp)); +#elif defined(SEP_CBCR_TEXTURE) + vec4 color; + color.r = texture2D(source, uv_interp).r; + color.gb = texture2D(CbCr, uv_interp).rg - vec2(0.5, 0.5); + color.a = 1.0; #else vec4 color = texture2D(source, uv_interp); #endif +#ifdef YCBCR_TO_RGB + // YCbCr -> RGB conversion + + // Using BT.601, which is the standard for SDTV is provided as a reference + color.rgb = mat3( + vec3(1.00000, 1.00000, 1.00000), + vec3(0.00000, -0.34413, 1.77200), + vec3(1.40200, -0.71414, 0.00000)) * + color.rgb; +#endif + #ifdef USE_NO_ALPHA color.a = 1.0; #endif |