Basic 3D rendering

This commit is contained in:
clayjohn 2022-05-10 10:02:44 -07:00
parent 2bf8831dd6
commit 652adcd5bf
31 changed files with 1786 additions and 377 deletions

View file

@ -82,11 +82,6 @@ public:
RENDER_SEPARATE_THREAD
};
enum RenderMainThreadMode {
RENDER_MAIN_THREAD_ONLY,
RENDER_ANY_THREAD,
};
protected:
friend class Main;
// Needed by tests to setup command-line args.
@ -94,7 +89,6 @@ protected:
HasServerFeatureCallback has_server_feature_callback = nullptr;
RenderThreadMode _render_thread_mode = RENDER_THREAD_SAFE;
RenderMainThreadMode _render_main_thread_mode = RENDER_ANY_THREAD;
// Functions used by Main to initialize/deinitialize the OS.
void add_logger(Logger *p_logger);
@ -258,8 +252,6 @@ public:
virtual uint64_t get_free_static_memory() const;
RenderThreadMode get_render_thread_mode() const { return _render_thread_mode; }
RenderMainThreadMode get_render_main_thread_mode() const { return _render_main_thread_mode; }
void set_render_main_thread_mode(RenderMainThreadMode p_thread_mode) { _render_main_thread_mode = p_thread_mode; }
virtual String get_locale() const;
String get_locale_language() const;

View file

@ -1557,18 +1557,6 @@
[b]Note:[/b] This property is only read when the project starts. To change the physics FPS at runtime, set [member Engine.physics_ticks_per_second] instead.
[b]Note:[/b] Only 8 physics ticks may be simulated per rendered frame at most. If more than 8 physics ticks have to be simulated per rendered frame to keep up with rendering, the game will appear to slow down (even if [code]delta[/code] is used consistently in physics calculations). Therefore, it is recommended not to increase [member physics/common/physics_ticks_per_second] above 240. Otherwise, the game will slow down when the rendering framerate goes below 30 FPS.
</member>
<member name="rendering/2d/opengl/batching_send_null" type="int" setter="" getter="" default="0">
</member>
<member name="rendering/2d/opengl/batching_stream" type="int" setter="" getter="" default="0">
</member>
<member name="rendering/2d/opengl/legacy_orphan_buffers" type="int" setter="" getter="" default="0">
</member>
<member name="rendering/2d/opengl/legacy_stream" type="int" setter="" getter="" default="0">
</member>
<member name="rendering/2d/options/ninepatch_mode" type="int" setter="" getter="" default="1">
</member>
<member name="rendering/2d/options/use_software_skinning" type="bool" setter="" getter="" default="true">
</member>
<member name="rendering/2d/sdf/oversize" type="int" setter="" getter="" default="1">
</member>
<member name="rendering/2d/sdf/scale" type="int" setter="" getter="" default="1">
@ -1594,32 +1582,6 @@
</member>
<member name="rendering/anti_aliasing/screen_space_roughness_limiter/limit" type="float" setter="" getter="" default="0.18">
</member>
<member name="rendering/batching/debug/diagnose_frame" type="bool" setter="" getter="" default="false">
</member>
<member name="rendering/batching/debug/flash_batching" type="bool" setter="" getter="" default="false">
</member>
<member name="rendering/batching/lights/max_join_items" type="int" setter="" getter="" default="32">
</member>
<member name="rendering/batching/lights/scissor_area_threshold" type="float" setter="" getter="" default="1.0">
</member>
<member name="rendering/batching/options/single_rect_fallback" type="bool" setter="" getter="" default="false">
</member>
<member name="rendering/batching/options/use_batching" type="bool" setter="" getter="" default="false">
</member>
<member name="rendering/batching/options/use_batching_in_editor" type="bool" setter="" getter="" default="false">
</member>
<member name="rendering/batching/parameters/batch_buffer_size" type="int" setter="" getter="" default="16384">
</member>
<member name="rendering/batching/parameters/colored_vertex_format_threshold" type="float" setter="" getter="" default="0.25">
</member>
<member name="rendering/batching/parameters/item_reordering_lookahead" type="int" setter="" getter="" default="4">
</member>
<member name="rendering/batching/parameters/max_join_item_commands" type="int" setter="" getter="" default="16">
</member>
<member name="rendering/batching/precision/uv_contract" type="bool" setter="" getter="" default="false">
</member>
<member name="rendering/batching/precision/uv_contract_amount" type="int" setter="" getter="" default="100">
</member>
<member name="rendering/camera/depth_of_field/depth_of_field_bokeh_quality" type="int" setter="" getter="" default="1">
Sets the quality of the depth of field effect. Higher quality takes more samples, which is slower but looks smoother.
</member>
@ -1629,13 +1591,16 @@
<member name="rendering/camera/depth_of_field/depth_of_field_use_jitter" type="bool" setter="" getter="" default="false">
If [code]true[/code], jitters DOF samples to make effect slightly blurrier and hide lines created from low sample rates. This can result in a slightly grainy appearance when used with a low number of samples.
</member>
<member name="rendering/driver/depth_prepass/disable_for_vendors" type="String" setter="" getter="" default="&quot;PowerVR,Mali,Adreno,Apple&quot;">
Disables [member rendering/driver/depth_prepass/enable] conditionally for certain venders. By default, disables the depth prepass for mobile devices as mobile devices do not benefit from the depth prepass due to their unique architecture.
</member>
<member name="rendering/driver/depth_prepass/enable" type="bool" setter="" getter="" default="true">
If [code]true[/code], performs a previous depth pass before rendering 3D materials. This increases performance significantly in scenes with high overdraw, when complex materials and lighting are used. However, in scenes with few occluded surfaces, the depth prepass may reduce performance. If your game is viewed from a fixed angle that makes it easy to avoid overdraw (such as top-down or side-scrolling perspective), consider disabling the depth prepass to improve performance. This setting can be changed at run-time to optimize performance depending on the scene currently being viewed.
[b]Note:[/b] Only supported when using the Vulkan Clustered backend (not Vulkan Mobile or OpenGL). When using Vulkan Mobile or OpenGL, there is no depth prepass performed.
[b]Note:[/b] Only supported when using the Vulkan Clustered backend or the OpenGL backend. When using Vulkan Mobile there is no depth prepass performed.
</member>
<member name="rendering/driver/driver_name" type="String" setter="" getter="" default="&quot;vulkan&quot;">
The video driver to use.
[b]Note:[/b] OpenGL support is currently incomplete. Only basic 2D rendering is supported, and single-window mode is required for correct operation.
[b]Note:[/b] OpenGL support is currently incomplete. Only basic rendering is supported.
[b]Note:[/b] The backend in use can be overridden at runtime via the [code]--rendering-driver[/code] command line argument.
[b]FIXME:[/b] No longer valid after DisplayServer split:
In such cases, this property is not updated, so use [code]OS.get_current_video_driver[/code] to query it at run-time.
@ -1715,10 +1680,6 @@
<member name="rendering/environment/volumetric_fog/volume_size" type="int" setter="" getter="" default="64">
Base size used to determine size of froxel buffer in the camera X-axis and Y-axis. The final size is scaled by the aspect ratio of the screen, so actual values may differ from what is set. Set a larger size for more detailed fog, set a smaller size for better performance.
</member>
<member name="rendering/gles2/compatibility/disable_half_float" type="bool" setter="" getter="" default="false">
</member>
<member name="rendering/gles2/compatibility/enable_high_float.Android" type="bool" setter="" getter="" default="false">
</member>
<member name="rendering/global_illumination/gi/use_half_resolution" type="bool" setter="" getter="" default="false">
If [code]true[/code], renders [VoxelGI] and SDFGI ([member Environment.sdfgi_enabled]) buffers at halved resolution (e.g. 960×540 when the viewport size is 1920×1080). This improves performance significantly when VoxelGI or SDFGI is enabled, at the cost of artifacts that may be visible on polygon edges. The loss in quality becomes less noticeable as the viewport resolution increases. [LightmapGI] rendering is not affected by this setting.
[b]Note:[/b] This property is only read when the project starts. To set half-resolution GI at run-time, call [method RenderingServer.gi_set_use_half_resolution] instead.
@ -1761,6 +1722,15 @@
</member>
<member name="rendering/limits/global_shader_variables/buffer_size" type="int" setter="" getter="" default="65536">
</member>
<member name="rendering/limits/opengl/max_lights_per_object" type="int" setter="" getter="" default="8">
Max number of lights renderable per object. This is further limited by hardware support. Setting this low will slightly reduce memory usage, may decrease shader compile times, and may result in faster rendering on low-end, mobile, or web devices.
</member>
<member name="rendering/limits/opengl/max_renderable_elements" type="int" setter="" getter="" default="65536">
Max amount of elements renderable in a frame. If more elements than this are visible per frame, they will not be drawn. Keep in mind elements refer to mesh surfaces and not meshes themselves. Setting this low will slightly reduce memory usage and may decrease shader compile times, particularly on web. For most uses, the default value is suitable, but consider lowering as much as possible on web export.
</member>
<member name="rendering/limits/opengl/max_renderable_lights" type="int" setter="" getter="" default="256">
Max number of lights renderable in a frame. If more lights than this number are used, they will be ignored. Setting this low will slightly reduce memory usage and may decrease shader compile times, particularly on web. For most uses, the default value is suitable, but consider lowering as much as possible on web export.
</member>
<member name="rendering/limits/spatial_indexer/threaded_cull_minimum_instances" type="int" setter="" getter="" default="1000">
</member>
<member name="rendering/limits/spatial_indexer/update_iterations_per_frame" type="int" setter="" getter="" default="10">

View file

@ -179,12 +179,12 @@ void RasterizerCanvasGLES3::canvas_render_items(RID p_to_render_target, Item *p_
//print_line("w: " + itos(ssize.width) + " s: " + rtos(canvas_scale));
state_buffer.tex_to_sdf = 1.0 / ((canvas_scale.x + canvas_scale.y) * 0.5);
glBindBufferBase(GL_UNIFORM_BUFFER, BASE_UNIFORM_BUFFER_OBJECT, state.canvas_state_buffer);
glBindBufferBase(GL_UNIFORM_BUFFER, BASE_UNIFORM_LOCATION, state.canvas_state_buffer);
glBufferData(GL_UNIFORM_BUFFER, sizeof(StateBuffer), &state_buffer, GL_STREAM_DRAW);
GLuint global_buffer = material_storage->global_variables_get_uniform_buffer();
glBindBufferBase(GL_UNIFORM_BUFFER, GLOBAL_UNIFORM_BUFFER_OBJECT, global_buffer);
glBindBufferBase(GL_UNIFORM_BUFFER, GLOBAL_UNIFORM_LOCATION, global_buffer);
glBindBuffer(GL_UNIFORM_BUFFER, 0);
}
@ -522,7 +522,7 @@ void RasterizerCanvasGLES3::_render_item(RID p_render_target, const Item *p_item
}
}
glBindBufferBase(GL_UNIFORM_BUFFER, INSTANCE_UNIFORM_BUFFER_OBJECT, state.canvas_instance_data_buffers[state.current_buffer]);
glBindBufferBase(GL_UNIFORM_BUFFER, INSTANCE_UNIFORM_LOCATION, state.canvas_instance_data_buffers[state.current_buffer]);
#ifdef JAVASCRIPT_ENABLED
//WebGL 2.0 does not support mapping buffers, so use slow glBufferData instead
glBufferData(GL_UNIFORM_BUFFER, sizeof(InstanceData), &state.instance_data_array[0], GL_DYNAMIC_DRAW);
@ -728,7 +728,7 @@ void RasterizerCanvasGLES3::_render_batch(uint32_t &r_index) {
}
}
glBindBufferBase(GL_UNIFORM_BUFFER, INSTANCE_UNIFORM_BUFFER_OBJECT, state.canvas_instance_data_buffers[state.current_buffer]);
glBindBufferBase(GL_UNIFORM_BUFFER, INSTANCE_UNIFORM_LOCATION, state.canvas_instance_data_buffers[state.current_buffer]);
#ifdef JAVASCRIPT_ENABLED
//WebGL 2.0 does not support mapping buffers, so use slow glBufferData instead
glBufferData(GL_UNIFORM_BUFFER, sizeof(InstanceData) * r_index, state.instance_data_array, GL_DYNAMIC_DRAW);

View file

@ -97,13 +97,12 @@ class RasterizerCanvasGLES3 : public RendererCanvasRender {
};
public:
//TODO move to Material storage
enum {
BASE_UNIFORM_BUFFER_OBJECT = 0,
GLOBAL_UNIFORM_BUFFER_OBJECT = 1,
LIGHT_UNIFORM_BUFFER_OBJECT = 2,
INSTANCE_UNIFORM_BUFFER_OBJECT = 3,
MATERIAL_UNIFORM_BUFFER_OBJECT = 4,
BASE_UNIFORM_LOCATION = 0,
GLOBAL_UNIFORM_LOCATION = 1,
LIGHT_UNIFORM_LOCATION = 2,
INSTANCE_UNIFORM_LOCATION = 3,
MATERIAL_UNIFORM_LOCATION = 4,
};
struct StateBuffer {

View file

@ -268,10 +268,6 @@ RasterizerGLES3::RasterizerGLES3() {
storage = memnew(RasterizerStorageGLES3);
canvas = memnew(RasterizerCanvasGLES3(storage));
scene = memnew(RasterizerSceneGLES3(storage));
texture_storage->set_main_thread_id(Thread::get_caller_id());
// make sure the OS knows to only access the renderer from the main thread
OS::get_singleton()->set_render_main_thread_mode(OS::RENDER_MAIN_THREAD_ONLY);
}
RasterizerGLES3::~RasterizerGLES3() {

File diff suppressed because it is too large Load diff

View file

@ -34,6 +34,7 @@
#ifdef GLES3_ENABLED
#include "core/math/camera_matrix.h"
#include "core/templates/paged_allocator.h"
#include "core/templates/rid_owner.h"
#include "core/templates/self_list.h"
#include "rasterizer_storage_gles3.h"
@ -44,13 +45,47 @@
#include "shader_gles3.h"
#include "shaders/sky.glsl.gen.h"
// Copied from renderer_scene_render_rd
enum RenderListType {
RENDER_LIST_OPAQUE, //used for opaque objects
RENDER_LIST_ALPHA, //used for transparent objects
RENDER_LIST_SECONDARY, //used for shadows and other objects
RENDER_LIST_MAX
};
enum PassMode {
PASS_MODE_COLOR,
PASS_MODE_COLOR_TRANSPARENT,
PASS_MODE_COLOR_ADDITIVE,
PASS_MODE_SHADOW,
PASS_MODE_DEPTH,
};
// These should share as much as possible with SkyUniform Location
enum SceneUniformLocation {
SCENE_TONEMAP_UNIFORM_LOCATION,
SCENE_GLOBALS_UNIFORM_LOCATION,
SCENE_DATA_UNIFORM_LOCATION,
SCENE_MATERIAL_UNIFORM_LOCATION,
SCENE_RADIANCE_UNIFORM_LOCATION,
SCENE_OMNILIGHT_UNIFORM_LOCATION,
SCENE_SPOTLIGHT_UNIFORM_LOCATION,
};
enum SkyUniformLocation {
SKY_TONEMAP_UNIFORM_LOCATION,
SKY_GLOBALS_UNIFORM_LOCATION,
SKY_SCENE_DATA_UNIFORM_LOCATION,
SKY_DIRECTIONAL_LIGHT_UNIFORM_LOCATION,
SKY_MATERIAL_UNIFORM_LOCATION,
};
struct RenderDataGLES3 {
RID render_buffers = RID();
bool transparent_bg = false;
Transform3D cam_transform = Transform3D();
CameraMatrix cam_projection = CameraMatrix();
bool cam_ortogonal = false;
bool cam_orthogonal = false;
// For stereo rendering
uint32_t view_count = 1;
@ -110,6 +145,305 @@ private:
RID default_shader;
} scene_globals;
struct SceneState {
struct UBO {
float projection_matrix[16];
float inv_projection_matrix[16];
float inv_view_matrix[16];
float view_matrix[16];
float viewport_size[2];
float screen_pixel_size[2];
float ambient_light_color_energy[4];
float ambient_color_sky_mix;
uint32_t ambient_flags;
uint32_t material_uv2_mode;
float opaque_prepass_threshold;
//bool use_ambient_light;
//bool use_ambient_cubemap;
//bool use_reflection_cubemap;
float radiance_inverse_xform[12];
uint32_t directional_light_count;
float z_far;
float z_near;
uint32_t pancake_shadows;
uint32_t fog_enabled;
float fog_density;
float fog_height;
float fog_height_density;
float fog_light_color[3];
float fog_sun_scatter;
float fog_aerial_perspective;
float time;
uint32_t pad[2];
};
static_assert(sizeof(UBO) % 16 == 0, "Scene UBO size must be a multiple of 16 bytes");
struct TonemapUBO {
float exposure = 1.0;
float white = 1.0;
int32_t tonemapper = 0;
int32_t pad = 0;
};
static_assert(sizeof(TonemapUBO) % 16 == 0, "Tonemap UBO size must be a multiple of 16 bytes");
UBO ubo;
GLuint ubo_buffer = 0;
GLuint tonemap_buffer = 0;
bool used_depth_prepass = false;
GLES3::SceneShaderData::BlendMode current_blend_mode = GLES3::SceneShaderData::BLEND_MODE_MIX;
GLES3::SceneShaderData::DepthDraw current_depth_draw = GLES3::SceneShaderData::DEPTH_DRAW_OPAQUE;
GLES3::SceneShaderData::DepthTest current_depth_test = GLES3::SceneShaderData::DEPTH_TEST_DISABLED;
GLES3::SceneShaderData::Cull cull_mode = GLES3::SceneShaderData::CULL_BACK;
bool texscreen_copied = false;
bool used_screen_texture = false;
bool used_normal_texture = false;
bool used_depth_texture = false;
} scene_state;
struct GeometryInstanceGLES3;
// Cached data for drawing surfaces
struct GeometryInstanceSurface {
enum {
FLAG_PASS_DEPTH = 1,
FLAG_PASS_OPAQUE = 2,
FLAG_PASS_ALPHA = 4,
FLAG_PASS_SHADOW = 8,
FLAG_USES_SHARED_SHADOW_MATERIAL = 128,
FLAG_USES_SCREEN_TEXTURE = 2048,
FLAG_USES_DEPTH_TEXTURE = 4096,
FLAG_USES_NORMAL_TEXTURE = 8192,
FLAG_USES_DOUBLE_SIDED_SHADOWS = 16384,
};
union {
struct {
uint64_t lod_index : 8;
uint64_t surface_index : 8;
uint64_t geometry_id : 32;
uint64_t material_id_low : 16;
uint64_t material_id_hi : 16;
uint64_t shader_id : 32;
uint64_t uses_softshadow : 1;
uint64_t uses_projector : 1;
uint64_t uses_forward_gi : 1;
uint64_t uses_lightmap : 1;
uint64_t depth_layer : 4;
uint64_t priority : 8;
};
struct {
uint64_t sort_key1;
uint64_t sort_key2;
};
} sort;
RS::PrimitiveType primitive = RS::PRIMITIVE_MAX;
uint32_t flags = 0;
uint32_t surface_index = 0;
uint32_t lod_index = 0;
void *surface = nullptr;
GLES3::SceneShaderData *shader = nullptr;
GLES3::SceneMaterialData *material = nullptr;
void *surface_shadow = nullptr;
GLES3::SceneShaderData *shader_shadow = nullptr;
GLES3::SceneMaterialData *material_shadow = nullptr;
GeometryInstanceSurface *next = nullptr;
GeometryInstanceGLES3 *owner = nullptr;
};
struct GeometryInstanceGLES3 : public GeometryInstance {
//used during rendering
bool mirror = false;
bool non_uniform_scale = false;
float lod_bias = 0.0;
float lod_model_scale = 1.0;
AABB transformed_aabb; //needed for LOD
float depth = 0;
uint32_t flags_cache = 0;
bool store_transform_cache = true;
int32_t shader_parameters_offset = -1;
uint32_t layer_mask = 1;
uint32_t instance_count = 0;
RID mesh_instance;
bool can_sdfgi = false;
bool using_projectors = false;
bool using_softshadows = false;
bool fade_near = false;
float fade_near_begin = 0;
float fade_near_end = 0;
bool fade_far = false;
float fade_far_begin = 0;
float fade_far_end = 0;
float force_alpha = 1.0;
float parent_fade_alpha = 1.0;
uint32_t omni_light_count = 0;
uint32_t omni_lights[8];
uint32_t spot_light_count = 0;
uint32_t spot_lights[8];
//used during setup
uint32_t base_flags = 0;
Transform3D transform;
GeometryInstanceSurface *surface_caches = nullptr;
SelfList<GeometryInstanceGLES3> dirty_list_element;
struct Data {
//data used less often goes into regular heap
RID base;
RS::InstanceType base_type;
RID skeleton;
Vector<RID> surface_materials;
RID material_override;
RID material_overlay;
AABB aabb;
bool use_dynamic_gi = false;
bool use_baked_light = false;
bool cast_double_sided_shadows = false;
bool mirror = false;
bool dirty_dependencies = false;
RendererStorage::DependencyTracker dependency_tracker;
};
Data *data = nullptr;
GeometryInstanceGLES3() :
dirty_list_element(this) {}
};
enum {
INSTANCE_DATA_FLAGS_NON_UNIFORM_SCALE = 1 << 5,
INSTANCE_DATA_FLAG_USE_GI_BUFFERS = 1 << 6,
INSTANCE_DATA_FLAG_USE_LIGHTMAP_CAPTURE = 1 << 8,
INSTANCE_DATA_FLAG_USE_LIGHTMAP = 1 << 9,
INSTANCE_DATA_FLAG_USE_SH_LIGHTMAP = 1 << 10,
INSTANCE_DATA_FLAG_USE_VOXEL_GI = 1 << 11,
INSTANCE_DATA_FLAG_MULTIMESH = 1 << 12,
INSTANCE_DATA_FLAG_MULTIMESH_FORMAT_2D = 1 << 13,
INSTANCE_DATA_FLAG_MULTIMESH_HAS_COLOR = 1 << 14,
INSTANCE_DATA_FLAG_MULTIMESH_HAS_CUSTOM_DATA = 1 << 15,
};
static void _geometry_instance_dependency_changed(RendererStorage::DependencyChangedNotification p_notification, RendererStorage::DependencyTracker *p_tracker);
static void _geometry_instance_dependency_deleted(const RID &p_dependency, RendererStorage::DependencyTracker *p_tracker);
SelfList<GeometryInstanceGLES3>::List geometry_instance_dirty_list;
// Use PagedAllocator instead of RID to maximize performance
PagedAllocator<GeometryInstanceGLES3> geometry_instance_alloc;
PagedAllocator<GeometryInstanceSurface> geometry_instance_surface_alloc;
void _geometry_instance_add_surface_with_material(GeometryInstanceGLES3 *ginstance, uint32_t p_surface, GLES3::SceneMaterialData *p_material, uint32_t p_material_id, uint32_t p_shader_id, RID p_mesh);
void _geometry_instance_add_surface_with_material_chain(GeometryInstanceGLES3 *ginstance, uint32_t p_surface, GLES3::SceneMaterialData *p_material, RID p_mat_src, RID p_mesh);
void _geometry_instance_add_surface(GeometryInstanceGLES3 *ginstance, uint32_t p_surface, RID p_material, RID p_mesh);
void _geometry_instance_mark_dirty(GeometryInstance *p_geometry_instance);
void _geometry_instance_update(GeometryInstance *p_geometry_instance);
void _update_dirty_geometry_instances();
struct RenderListParameters {
GeometryInstanceSurface **elements = nullptr;
int element_count = 0;
bool reverse_cull = false;
uint32_t spec_constant_base_flags = 0;
bool force_wireframe = false;
Plane lod_plane;
float lod_distance_multiplier = 0.0;
float screen_mesh_lod_threshold = 0.0;
RenderListParameters(GeometryInstanceSurface **p_elements, int p_element_count, bool p_reverse_cull, uint32_t p_spec_constant_base_flags, bool p_force_wireframe = false, const Plane &p_lod_plane = Plane(), float p_lod_distance_multiplier = 0.0, float p_screen_mesh_lod_threshold = 0.0) {
elements = p_elements;
element_count = p_element_count;
reverse_cull = p_reverse_cull;
spec_constant_base_flags = p_spec_constant_base_flags;
force_wireframe = p_force_wireframe;
lod_plane = p_lod_plane;
lod_distance_multiplier = p_lod_distance_multiplier;
screen_mesh_lod_threshold = p_screen_mesh_lod_threshold;
}
};
struct RenderList {
LocalVector<GeometryInstanceSurface *> elements;
void clear() {
elements.clear();
}
//should eventually be replaced by radix
struct SortByKey {
_FORCE_INLINE_ bool operator()(const GeometryInstanceSurface *A, const GeometryInstanceSurface *B) const {
return (A->sort.sort_key2 == B->sort.sort_key2) ? (A->sort.sort_key1 < B->sort.sort_key1) : (A->sort.sort_key2 < B->sort.sort_key2);
}
};
void sort_by_key() {
SortArray<GeometryInstanceSurface *, SortByKey> sorter;
sorter.sort(elements.ptr(), elements.size());
}
void sort_by_key_range(uint32_t p_from, uint32_t p_size) {
SortArray<GeometryInstanceSurface *, SortByKey> sorter;
sorter.sort(elements.ptr() + p_from, p_size);
}
struct SortByDepth {
_FORCE_INLINE_ bool operator()(const GeometryInstanceSurface *A, const GeometryInstanceSurface *B) const {
return (A->owner->depth < B->owner->depth);
}
};
void sort_by_depth() { //used for shadows
SortArray<GeometryInstanceSurface *, SortByDepth> sorter;
sorter.sort(elements.ptr(), elements.size());
}
struct SortByReverseDepthAndPriority {
_FORCE_INLINE_ bool operator()(const GeometryInstanceSurface *A, const GeometryInstanceSurface *B) const {
return (A->sort.priority == B->sort.priority) ? (A->owner->depth > B->owner->depth) : (A->sort.priority < B->sort.priority);
}
};
void sort_by_reverse_depth_and_priority() { //used for alpha
SortArray<GeometryInstanceSurface *, SortByReverseDepthAndPriority> sorter;
sorter.sort(elements.ptr(), elements.size());
}
_FORCE_INLINE_ void add_element(GeometryInstanceSurface *p_element) {
elements.push_back(p_element);
}
};
RenderList render_list[RENDER_LIST_MAX];
void _setup_environment(const RenderDataGLES3 *p_render_data, bool p_no_fog, const Size2i &p_screen_size, bool p_flip_y, const Color &p_default_bg_color, bool p_pancake_shadows);
void _fill_render_list(RenderListType p_render_list, const RenderDataGLES3 *p_render_data, PassMode p_pass_mode, bool p_append = false);
template <PassMode p_pass_mode>
_FORCE_INLINE_ void _render_list_template(RenderListParameters *p_params, const RenderDataGLES3 *p_render_data, uint32_t p_from_element, uint32_t p_to_element, bool p_alpha_pass = false);
protected:
double time;
double time_step = 0;
@ -125,6 +459,8 @@ protected:
//bool use_debanding = false;
//uint32_t view_count = 1;
bool is_transparent = false;
RID render_target;
GLuint internal_texture = 0; // Used for rendering when post effects are enabled
GLuint depth_texture = 0; // Main depth texture
@ -391,9 +727,15 @@ public:
/* SDFGI UPDATE */
void sdfgi_update(RID p_render_buffers, RID p_environment, const Vector3 &p_world_position) override {}
int sdfgi_get_pending_region_count(RID p_render_buffers) const override { return 0; }
AABB sdfgi_get_pending_region_bounds(RID p_render_buffers, int p_region) const override { return AABB(); }
uint32_t sdfgi_get_pending_region_cascade(RID p_render_buffers, int p_region) const override { return 0; }
int sdfgi_get_pending_region_count(RID p_render_buffers) const override {
return 0;
}
AABB sdfgi_get_pending_region_bounds(RID p_render_buffers, int p_region) const override {
return AABB();
}
uint32_t sdfgi_get_pending_region_cascade(RID p_render_buffers, int p_region) const override {
return 0;
}
/* SKY API */

View file

@ -344,9 +344,10 @@ void RasterizerStorageGLES3::canvas_light_occluder_set_polylines(RID p_occluder,
RS::InstanceType RasterizerStorageGLES3::get_base_type(RID p_rid) const {
if (GLES3::MeshStorage::get_singleton()->owns_mesh(p_rid)) {
return RS::INSTANCE_MESH;
}
if (GLES3::MeshStorage::get_singleton()->owns_multimesh(p_rid)) {
} else if (GLES3::MeshStorage::get_singleton()->owns_multimesh(p_rid)) {
return RS::INSTANCE_MULTIMESH;
} else if (GLES3::LightStorage::get_singleton()->owns_light(p_rid)) {
return RS::INSTANCE_LIGHT;
}
return RS::INSTANCE_NONE;
}
@ -376,19 +377,14 @@ bool RasterizerStorageGLES3::free(RID p_rid) {
} else if (GLES3::MeshStorage::get_singleton()->owns_mesh_instance(p_rid)) {
GLES3::MeshStorage::get_singleton()->mesh_instance_free(p_rid);
return true;
} else if (GLES3::LightStorage::get_singleton()->owns_light(p_rid)) {
GLES3::LightStorage::get_singleton()->light_free(p_rid);
return true;
} else {
return false;
}
/*
} else if (light_owner.owns(p_rid)) {
Light *light = light_owner.get_or_null(p_rid);
light->instance_remove_deps();
light_owner.free(p_rid);
memdelete(light);
return true;
} else if (reflection_probe_owner.owns(p_rid)) {
else if (reflection_probe_owner.owns(p_rid)) {
// delete the texture
ReflectionProbe *reflection_probe = reflection_probe_owner.get_or_null(p_rid);
reflection_probe->instance_remove_deps();

View file

@ -41,6 +41,7 @@
#include "servers/rendering/shader_compiler.h"
#include "servers/rendering/shader_language.h"
#include "storage/config.h"
#include "storage/light_storage.h"
#include "storage/material_storage.h"
#include "storage/mesh_storage.h"
#include "storage/texture_storage.h"
@ -55,6 +56,48 @@ public:
GLES3::Config *config = nullptr;
static _FORCE_INLINE_ void store_transform(const Transform3D &p_mtx, float *p_array) {
p_array[0] = p_mtx.basis.rows[0][0];
p_array[1] = p_mtx.basis.rows[1][0];
p_array[2] = p_mtx.basis.rows[2][0];
p_array[3] = 0;
p_array[4] = p_mtx.basis.rows[0][1];
p_array[5] = p_mtx.basis.rows[1][1];
p_array[6] = p_mtx.basis.rows[2][1];
p_array[7] = 0;
p_array[8] = p_mtx.basis.rows[0][2];
p_array[9] = p_mtx.basis.rows[1][2];
p_array[10] = p_mtx.basis.rows[2][2];
p_array[11] = 0;
p_array[12] = p_mtx.origin.x;
p_array[13] = p_mtx.origin.y;
p_array[14] = p_mtx.origin.z;
p_array[15] = 1;
}
static _FORCE_INLINE_ void store_transform_3x3(const Basis &p_mtx, float *p_array) {
p_array[0] = p_mtx.rows[0][0];
p_array[1] = p_mtx.rows[1][0];
p_array[2] = p_mtx.rows[2][0];
p_array[3] = 0;
p_array[4] = p_mtx.rows[0][1];
p_array[5] = p_mtx.rows[1][1];
p_array[6] = p_mtx.rows[2][1];
p_array[7] = 0;
p_array[8] = p_mtx.rows[0][2];
p_array[9] = p_mtx.rows[1][2];
p_array[10] = p_mtx.rows[2][2];
p_array[11] = 0;
}
static _FORCE_INLINE_ void store_camera(const CameraMatrix &p_mtx, float *p_array) {
for (int i = 0; i < 4; i++) {
for (int j = 0; j < 4; j++) {
p_array[i * 4 + j] = p_mtx.matrix[i][j];
}
}
}
struct Resources {
GLuint mipmap_blur_fbo;
GLuint mipmap_blur_color;

View file

@ -171,6 +171,15 @@ void ShaderGLES3::_build_variant_code(StringBuilder &builder, uint32_t p_variant
}
builder.append("\n"); //make sure defines begin at newline
// Default to highp precision unless specified otherwise.
builder.append("precision highp float;\n");
builder.append("precision highp int;\n");
#ifndef GLES_OVER_GL
builder.append("precision highp sampler2D;\n");
builder.append("precision highp samplerCube;\n");
builder.append("precision highp sampler2DArray;\n");
#endif
for (uint32_t i = 0; i < p_template.chunks.size(); i++) {
const StageTemplate::Chunk &chunk = p_template.chunks[i];
switch (chunk.type) {

View file

@ -218,6 +218,7 @@ protected:
ERR_FAIL_INDEX_V(p_which, uniform_count, -1);
Version *version = version_owner.get_or_null(p_version);
ERR_FAIL_COND_V(!version, -1);
ERR_FAIL_INDEX_V(p_variant, int(version->variants.size()), -1);
return version->variants[p_variant].lookup_ptr(p_specialization)->uniform_location[p_which];
}

View file

@ -518,8 +518,8 @@ void main() {
float px_size = max(0.5 * dot((vec2(px_range) / msdf_size), dest_size), 1.0);
float d = msdf_median(msdf_sample.r, msdf_sample.g, msdf_sample.b, msdf_sample.a) - 0.5;
if (outline_thickness > 0) {
float cr = clamp(outline_thickness, 0.0, px_range / 2) / px_range;
if (outline_thickness > 0.0) {
float cr = clamp(outline_thickness, 0.0, px_range / 2.0) / px_range;
float a = clamp((d + cr) * px_size, 0.0, 1.0);
color.a = a * color.a;
} else {
@ -710,8 +710,8 @@ void main() {
vec2 pos_rot = pos_norm * mat2(vec2(0.7071067811865476, -0.7071067811865476), vec2(0.7071067811865476, 0.7071067811865476)); //is there a faster way to 45 degrees rot?
float tex_ofs;
float distance;
if (pos_rot.y > 0) {
if (pos_rot.x > 0) {
if (pos_rot.y > 0.0) {
if (pos_rot.x > 0.0) {
tex_ofs = pos_box.y * 0.125 + 0.125;
distance = shadow_pos.x;
} else {
@ -719,7 +719,7 @@ void main() {
distance = shadow_pos.y;
}
} else {
if (pos_rot.x < 0) {
if (pos_rot.x < 0.0) {
tex_ofs = pos_box.y * -0.125 + (0.5 + 0.125);
distance = -shadow_pos.x;
} else {

View file

@ -20,13 +20,19 @@ USE_LIGHT_POSITIONAL = false
#include "stdlib_inc.glsl"
#if !defined(MODE_RENDER_DEPTH) || defined(TANGENT_USED) || defined(NORMAL_MAP_USED) || defined(LIGHT_ANISOTROPY_USED) ||defined(LIGHT_CLEARCOAT_USED)
#ifndef NORMAL_USED
#define NORMAL_USED
#endif
#endif
/*
from RenderingServer:
ARRAY_VERTEX = 0, // RG32F or RGB32F (depending on 2D bit)
ARRAY_NORMAL = 1, // A2B10G10R10, A is ignored.
ARRAY_TANGENT = 2, // A2B10G10R10, A flips sign of binormal.
ARRAY_COLOR = 3, // RGBA8
ARRAY_TEX_UV = 4, // RG32F
ARRAY_TANGENT = 2, // A2B10G10R10, A flips sign of binormal.
ARRAY_NORMAL = 1, // A2B10G10R10, A is ignored.
ARRAY_TEX_UV2 = 5, // RG32F
ARRAY_CUSTOM0 = 6, // Depends on ArrayCustomFormat.
ARRAY_CUSTOM1 = 7,
@ -40,7 +46,7 @@ ARRAY_MAX = 13
/* INPUT ATTRIBS */
layout(location = 0) in vec3 vertex_attrib;
layout(location = 0) in highp vec3 vertex_attrib;
/* clang-format on */
#ifdef NORMAL_USED
@ -79,19 +85,23 @@ layout(location = 8) in vec4 custom2_attrib;
layout(location = 9) in vec4 custom3_attrib;
#endif
#if defined(BONES_USED) || defined(USE_PARTICLE_TRAILS)
#if defined(BONES_USED)
layout(location = 10) in uvec4 bone_attrib;
#endif
#if defined(WEIGHTS_USED) || defined(USE_PARTICLE_TRAILS)
#if defined(WEIGHTS_USED)
layout(location = 11) in vec4 weight_attrib;
#endif
layout(std140) uniform SceneData { // ubo:3
mat4 projection_matrix;
mat4 inv_projection_matrix;
mat4 inv_view_matrix;
mat4 view_matrix;
layout(std140) uniform GlobalVariableData { //ubo:1
vec4 global_variables[MAX_GLOBAL_VARIABLES];
};
layout(std140) uniform SceneData { // ubo:2
highp mat4 projection_matrix;
highp mat4 inv_projection_matrix;
highp mat4 inv_view_matrix;
highp mat4 view_matrix;
vec2 viewport_size;
vec2 screen_pixel_size;
@ -143,15 +153,15 @@ out highp vec3 vertex_interp;
out vec3 normal_interp;
#endif
#if defined(ENABLE_COLOR_INTERP)
#if defined(COLOR_USED)
out vec4 color_interp;
#endif
#if defined(ENABLE_UV_INTERP)
#if defined(UV_USED)
out vec2 uv_interp;
#endif
#if defined(ENABLE_UV2_INTERP)
#if defined(UV2_USED)
out vec2 uv2_interp;
#else
#ifdef USE_LIGHTMAP
@ -159,15 +169,15 @@ out vec2 uv2_interp;
#endif
#endif
#if defined(ENABLE_TANGENT_INTERP) || defined(ENABLE_NORMALMAP) || defined(LIGHT_USE_ANISOTROPY)
#if defined(TANGENT_USED) || defined(ENABLE_NORMALMAP) || defined(LIGHT_USE_ANISOTROPY)
out vec3 tangent_interp;
out vec3 binormal_interp;
#endif
#if defined(USE_MATERIAL)
#if defined(MATERIAL_UNIFORMS_USED)
/* clang-format off */
layout(std140) uniform UniformData { // ubo:1
layout(std140) uniform MaterialUniforms { // ubo:3
#MATERIAL_UNIFORMS
@ -194,31 +204,31 @@ void main() {
#ifdef NORMAL_USED
vec3 normal = normal_attrib * 2.0 - 1.0;
#endif
mat3 model_normal_matrix = mat3(model_matrix);
highp mat3 model_normal_matrix = mat3(model_matrix);
#if defined(ENABLE_TANGENT_INTERP) || defined(ENABLE_NORMALMAP) || defined(LIGHT_USE_ANISOTROPY)
#if defined(TANGENT_USED) || defined(ENABLE_NORMALMAP) || defined(LIGHT_USE_ANISOTROPY)
vec3 tangent;
float binormalf;
tangent = normal_tangent_attrib.xyz;
binormalf = normal_tangent_attrib.a;
#endif
#if defined(ENABLE_COLOR_INTERP)
#if defined(COLOR_USED)
color_interp = color_attrib;
#endif
#if defined(ENABLE_TANGENT_INTERP) || defined(ENABLE_NORMALMAP) || defined(LIGHT_USE_ANISOTROPY)
#if defined(TANGENT_USED) || defined(ENABLE_NORMALMAP) || defined(LIGHT_USE_ANISOTROPY)
vec3 binormal = normalize(cross(normal, tangent) * binormalf);
#endif
#if defined(ENABLE_UV_INTERP)
#if defined(UV_USED)
uv_interp = uv_attrib;
#endif
#ifdef USE_LIGHTMAP
uv2_interp = lightmap_uv_rect.zw * uv2_attrib + lightmap_uv_rect.xy;
#else
#if defined(ENABLE_UV2_INTERP)
#if defined(UV2_USED)
uv2_interp = uv2_attrib;
#endif
#endif
@ -226,8 +236,8 @@ void main() {
#if defined(OVERRIDE_POSITION)
highp vec4 position;
#endif
mat4 projection_matrix = scene_data.projection_matrix;
mat4 inv_projection_matrix = scene_data.inv_projection_matrix;
highp mat4 projection_matrix = scene_data.projection_matrix;
highp mat4 inv_projection_matrix = scene_data.inv_projection_matrix;
vec4 instance_custom = vec4(0.0);
@ -250,8 +260,8 @@ void main() {
float roughness = 1.0;
mat4 modelview = scene_data.view_matrix * model_matrix;
mat3 modelview_normal = mat3(scene_data.view_matrix) * model_normal_matrix;
highp mat4 modelview = scene_data.view_matrix * model_matrix;
highp mat3 modelview_normal = mat3(scene_data.view_matrix) * model_normal_matrix;
float point_size = 1.0;
@ -296,7 +306,7 @@ void main() {
normal_interp = normal;
#endif
#if defined(ENABLE_TANGENT_INTERP) || defined(ENABLE_NORMALMAP) || defined(LIGHT_USE_ANISOTROPY)
#if defined(TANGENT_USED) || defined(ENABLE_NORMALMAP) || defined(LIGHT_USE_ANISOTROPY)
tangent_interp = tangent;
binormal_interp = binormal;
#endif
@ -327,7 +337,7 @@ void main() {
#define SPECULAR_SCHLICK_GGX
#endif
#if !defined(MODE_RENDER_DEPTH) || defined(TANGENT_USED) || defined(NORMAL_MAP_USED) || defined(LIGHT_ANISOTROPY_USED)
#if !defined(MODE_RENDER_DEPTH) || defined(TANGENT_USED) || defined(NORMAL_MAP_USED) || defined(LIGHT_ANISOTROPY_USED) ||defined(LIGHT_CLEARCOAT_USED)
#ifndef NORMAL_USED
#define NORMAL_USED
#endif
@ -351,19 +361,19 @@ uniform highp mat4 world_transform;
/* clang-format on */
#define M_PI 3.14159265359
#define SHADER_IS_SRGB false
#define SHADER_IS_SRGB true
/* Varyings */
#if defined(ENABLE_COLOR_INTERP)
#if defined(COLOR_USED)
in vec4 color_interp;
#endif
#if defined(ENABLE_UV_INTERP)
#if defined(UV_USED)
in vec2 uv_interp;
#endif
#if defined(ENABLE_UV2_INTERP)
#if defined(UV2_USED)
in vec2 uv2_interp;
#else
#ifdef USE_LIGHTMAP
@ -371,19 +381,22 @@ in vec2 uv2_interp;
#endif
#endif
#if defined(ENABLE_TANGENT_INTERP) || defined(ENABLE_NORMALMAP) || defined(LIGHT_USE_ANISOTROPY)
#if defined(TANGENT_USED) || defined(ENABLE_NORMALMAP) || defined(LIGHT_USE_ANISOTROPY)
in vec3 tangent_interp;
in vec3 binormal_interp;
#endif
in highp vec3 vertex_interp;
#ifdef NORMAL_USED
in vec3 normal_interp;
#endif
in highp vec3 vertex_interp;
/* PBR CHANNELS */
#ifdef USE_RADIANCE_MAP
layout(std140) uniform Radiance { // ubo:2
layout(std140) uniform Radiance { // ubo:4
mat4 radiance_inverse_xform;
float radiance_ambient_contribution;
@ -405,12 +418,16 @@ vec3 textureDualParaboloid(sampler2D p_tex, vec3 p_vec, float p_roughness) {
#endif
/* Material Uniforms */
layout(std140) uniform GlobalVariableData { //ubo:1
vec4 global_variables[MAX_GLOBAL_VARIABLES];
};
#if defined(USE_MATERIAL)
/* Material Uniforms */
#if defined(MATERIAL_UNIFORMS_USED)
/* clang-format off */
layout(std140) uniform UniformData {
layout(std140) uniform MaterialUniforms { // ubo:3
#MATERIAL_UNIFORMS
@ -419,11 +436,11 @@ layout(std140) uniform UniformData {
#endif
layout(std140) uniform SceneData { // ubo:3
mat4 projection_matrix;
mat4 inv_projection_matrix;
mat4 inv_view_matrix;
mat4 view_matrix;
layout(std140) uniform SceneData { // ubo:2
highp mat4 projection_matrix;
highp mat4 inv_projection_matrix;
highp mat4 inv_view_matrix;
highp mat4 view_matrix;
vec2 viewport_size;
vec2 screen_pixel_size;
@ -501,12 +518,12 @@ struct LightData { //this structure needs to be as packed as possible
bool shadow_enabled;
};
layout(std140) uniform OmniLightData { // ubo:4
layout(std140) uniform OmniLightData { // ubo:5
LightData omni_lights[MAX_LIGHT_DATA_STRUCTS];
};
layout(std140) uniform SpotLightData { // ubo:5
layout(std140) uniform SpotLightData { // ubo:6
LightData spot_lights[MAX_LIGHT_DATA_STRUCTS];
};

View file

@ -12,23 +12,14 @@ mode_cubemap_quarter_res = #define USE_CUBEMAP_PASS \n#define USE_QUARTER_RES_PA
#[vertex]
#ifdef USE_GLES_OVER_GL
#define lowp
#define mediump
#define highp
#else
precision highp float;
precision highp int;
#endif
out vec2 uv_interp;
/* clang-format on */
void main() {
// One big triangle to cover the whole screen
vec2 base_arr[3] = vec2[](vec2(-1.0, -1.0), vec2(-1.0, 3.0), vec2(3.0, -1.0));
vec2 base_arr[3] = vec2[](vec2(-1.0, -1.0), vec2(3.0, -1.0), vec2(-1.0, 3.0));
uv_interp = base_arr[gl_VertexID];
gl_Position = vec4(uv_interp, 0.0, 1.0);
gl_Position = vec4(uv_interp, 1.0, 1.0);
}
/* clang-format off */
@ -36,20 +27,6 @@ void main() {
#define M_PI 3.14159265359
#ifdef USE_GLES_OVER_GL
#define lowp
#define mediump
#define highp
#else
#if defined(USE_HIGHP_PRECISION)
precision highp float;
precision highp int;
#else
precision mediump float;
precision mediump int;
#endif
#endif
#include "tonemap_inc.glsl"
in vec2 uv_interp;
@ -65,22 +42,22 @@ uniform sampler2D half_res; //texunit:-2
uniform sampler2D quarter_res; //texunit:-3
#endif
layout(std140) uniform SceneData { //ubo:0
float pad1;
float pad2;
};
layout(std140) uniform GlobalVariableData { //ubo:1
vec4 global_variables[MAX_GLOBAL_VARIABLES];
};
layout(std140) uniform SceneData { //ubo:2
float pad1;
float pad2;
};
struct DirectionalLightData {
vec4 direction_energy;
vec4 color_size;
bool enabled;
};
layout(std140) uniform DirectionalLights { //ubo:2
layout(std140) uniform DirectionalLights { //ubo:3
DirectionalLightData data[MAX_DIRECTIONAL_LIGHT_DATA_STRUCTS];
}
directional_lights;
@ -88,7 +65,7 @@ directional_lights;
/* clang-format off */
#ifdef MATERIAL_UNIFORMS_USED
layout(std140) uniform MaterialUniforms{ //ubo:3
layout(std140) uniform MaterialUniforms{ //ubo:4
#MATERIAL_UNIFORMS

View file

@ -1,5 +1,6 @@
#ifdef USE_GLES_OVER_GL
// Floating point pack/unpack functions are part of the GLSL ES 300 specification used by web and mobile.
uint float2half(uint f) {
return ((f >> uint(16)) & uint(0x8000)) |
((((f & uint(0x7f800000)) - uint(0x38000000)) >> uint(13)) & uint(0x7c00)) |
@ -37,6 +38,7 @@ vec2 unpackSnorm2x16(uint p) {
vec2 v = vec2(float(p & uint(0xffff)), float(p >> uint(16)));
return clamp((v - 32767.0) * vec2(0.00003051851), vec2(-1.0), vec2(1.0));
}
#endif
uint packUnorm4x8(vec4 v) {
uvec4 uv = uvec4(round(clamp(v, vec4(0.0), vec4(1.0)) * 255.0));
@ -56,4 +58,3 @@ vec4 unpackSnorm4x8(uint p) {
vec4 v = vec4(float(p & uint(0xffff)), float((p >> uint(8)) & uint(0xffff)), float((p >> uint(16)) & uint(0xffff)), float(p >> uint(24)));
return clamp((v - vec4(127.0)) * vec4(0.00787401574), vec4(-1.0), vec4(1.0));
}
#endif

View file

@ -10,10 +10,12 @@ uniform sampler3D source_color_correction; //texunit:-1
#endif
#endif
// These could be grouped into some form of SceneData UBO along with time, will have to test performance though
uniform int tonemapper;
uniform float exposure;
uniform float white;
layout(std140) uniform TonemapData { //ubo:0
float exposure;
float white;
int tonemapper;
int pad;
};
vec3 apply_bcs(vec3 color, vec3 bcs) {
color = mix(vec3(0.0), color, bcs.x);

View file

@ -120,16 +120,6 @@ Config::Config() {
support_write_depth = extensions.has("GL_EXT_frag_depth");
#endif
support_half_float_vertices = true;
//every platform should support this except web, iOS has issues with their support, so add option to disable
#ifdef JAVASCRIPT_ENABLED
support_half_float_vertices = false;
#endif
bool disable_half_float = false; //GLOBAL_GET("rendering/opengl/compatibility/disable_half_float");
if (disable_half_float) {
support_half_float_vertices = false;
}
//picky requirements for these
support_shadow_cubemaps = support_write_depth && support_depth_cubemaps;
// the use skeleton software path should be used if either float texture is not supported,
@ -149,6 +139,27 @@ Config::Config() {
force_vertex_shading = false; //GLOBAL_GET("rendering/quality/shading/force_vertex_shading");
use_nearest_mip_filter = GLOBAL_GET("rendering/textures/default_filters/use_nearest_mipmap_filter");
use_depth_prepass = bool(GLOBAL_GET("rendering/driver/depth_prepass/enable"));
if (use_depth_prepass) {
String vendors = GLOBAL_GET("rendering/driver/depth_prepass/disable_for_vendors");
Vector<String> vendor_match = vendors.split(",");
String renderer = (const char *)glGetString(GL_RENDERER);
for (int i = 0; i < vendor_match.size(); i++) {
String v = vendor_match[i].strip_edges();
if (v == String()) {
continue;
}
if (renderer.findn(v) != -1) {
use_depth_prepass = false;
}
}
}
max_renderable_elements = GLOBAL_GET("rendering/limits/opengl/max_renderable_elements");
max_renderable_lights = GLOBAL_GET("rendering/limits/opengl/max_renderable_lights");
max_lights_per_object = GLOBAL_GET("rendering/limits/opengl/max_lights_per_object");
}
Config::~Config() {

View file

@ -58,6 +58,9 @@ public:
int max_texture_image_units = 0;
int max_texture_size = 0;
int max_uniform_buffer_size = 0;
int max_renderable_elements = 0;
int max_renderable_lights = 0;
int max_lights_per_object = 0;
// TODO implement wireframe in OpenGL
// bool generate_wireframes;
@ -82,7 +85,6 @@ public:
bool support_32_bits_indices = false;
bool support_write_depth = false;
bool support_half_float_vertices = false;
bool support_npot_repeat_mipmap = false;
bool support_depth_cubemaps = false;
bool support_shadow_cubemaps = false;
@ -97,6 +99,8 @@ public:
// so the user can switch orphaning off for them.
bool should_orphan = true;
bool use_depth_prepass = true;
static Config *get_singleton() { return singleton; };
Config();

View file

@ -43,7 +43,7 @@ using namespace GLES3;
///////////////////////////////////////////////////////////////////////////
// UBI helper functions
_FORCE_INLINE_ static void _fill_std140_variant_ubo_value(ShaderLanguage::DataType type, int p_array_size, const Variant &value, uint8_t *data, bool p_linear_color) {
_FORCE_INLINE_ static void _fill_std140_variant_ubo_value(ShaderLanguage::DataType type, int p_array_size, const Variant &value, uint8_t *data) {
switch (type) {
case ShaderLanguage::TYPE_BOOL: {
uint32_t *gui = (uint32_t *)data;
@ -399,9 +399,6 @@ _FORCE_INLINE_ static void _fill_std140_variant_ubo_value(ShaderLanguage::DataTy
for (int i = 0, j = 0; i < p_array_size; i++, j += 4) {
if (i < s) {
Color color = a[i];
if (p_linear_color) {
color = color.srgb_to_linear();
}
gui[j] = color.r;
gui[j + 1] = color.g;
gui[j + 2] = color.b;
@ -433,10 +430,6 @@ _FORCE_INLINE_ static void _fill_std140_variant_ubo_value(ShaderLanguage::DataTy
if (value.get_type() == Variant::COLOR) {
Color v = value;
if (p_linear_color) {
v = v.srgb_to_linear();
}
gui[0] = v.r;
gui[1] = v.g;
gui[2] = v.b;
@ -459,9 +452,6 @@ _FORCE_INLINE_ static void _fill_std140_variant_ubo_value(ShaderLanguage::DataTy
for (int i = 0, j = 0; i < p_array_size; i++, j += 4) {
if (i < s) {
Color color = a[i];
if (p_linear_color) {
color = color.srgb_to_linear();
}
gui[j] = color.r;
gui[j + 1] = color.g;
gui[j + 2] = color.b;
@ -496,10 +486,6 @@ _FORCE_INLINE_ static void _fill_std140_variant_ubo_value(ShaderLanguage::DataTy
if (value.get_type() == Variant::COLOR) {
Color v = value;
if (p_linear_color) {
v = v.srgb_to_linear();
}
gui[0] = v.r;
gui[1] = v.g;
gui[2] = v.b;
@ -987,7 +973,7 @@ void MaterialData::update_uniform_buffer(const Map<StringName, ShaderLanguage::S
if (V) {
//user provided
_fill_std140_variant_ubo_value(E.value.type, E.value.array_size, V->get(), data, p_use_linear_color);
_fill_std140_variant_ubo_value(E.value.type, E.value.array_size, V->get(), data);
} else if (E.value.default_value.size()) {
//default value
@ -997,7 +983,7 @@ void MaterialData::update_uniform_buffer(const Map<StringName, ShaderLanguage::S
//zero because it was not provided
if ((E.value.type == ShaderLanguage::TYPE_VEC3 || E.value.type == ShaderLanguage::TYPE_VEC4) && E.value.hint == ShaderLanguage::ShaderNode::Uniform::HINT_COLOR) {
//colors must be set as black, with alpha as 1.0
_fill_std140_variant_ubo_value(E.value.type, E.value.array_size, Color(0, 0, 0, 1), data, p_use_linear_color);
_fill_std140_variant_ubo_value(E.value.type, E.value.array_size, Color(0, 0, 0, 1), data);
} else {
//else just zero it out
_fill_std140_ubo_empty(E.value.type, E.value.array_size, data);
@ -1883,7 +1869,7 @@ void MaterialStorage::_global_variable_store_in_buffer(int32_t p_index, RS::Glob
bv.w = v.a;
GlobalVariables::Value &bv_linear = global_variables.buffer_values[p_index + 1];
v = v.srgb_to_linear();
//v = v.srgb_to_linear();
bv_linear.x = v.r;
bv_linear.y = v.g;
bv_linear.z = v.b;
@ -2322,7 +2308,7 @@ void MaterialStorage::global_variables_instance_update(RID p_instance, int p_ind
pos += p_index;
_fill_std140_variant_ubo_value(datatype, 0, p_value, (uint8_t *)&global_variables.buffer_values[pos], true); //instances always use linear color in this renderer
_fill_std140_variant_ubo_value(datatype, 0, p_value, (uint8_t *)&global_variables.buffer_values[pos]);
_global_variable_mark_buffer_dirty(pos, 1);
}
@ -2929,7 +2915,7 @@ void CanvasMaterialData::update_parameters(const Map<StringName, Variant> &p_par
void CanvasMaterialData::bind_uniforms() {
// Bind Material Uniforms
glBindBufferBase(GL_UNIFORM_BUFFER, RasterizerCanvasGLES3::MATERIAL_UNIFORM_BUFFER_OBJECT, uniform_buffer);
glBindBufferBase(GL_UNIFORM_BUFFER, RasterizerCanvasGLES3::MATERIAL_UNIFORM_LOCATION, uniform_buffer);
RID *textures = texture_cache.ptrw();
ShaderCompiler::GeneratedCode::Texture *texture_uniforms = shader_data->texture_uniforms.ptrw();
@ -3162,7 +3148,7 @@ GLES3::MaterialData *GLES3::_create_sky_material_func(ShaderData *p_shader) {
void SkyMaterialData::bind_uniforms() {
// Bind Material Uniforms
glBindBufferBase(GL_UNIFORM_BUFFER, 3, uniform_buffer);
glBindBufferBase(GL_UNIFORM_BUFFER, SKY_MATERIAL_UNIFORM_LOCATION, uniform_buffer);
RID *textures = texture_cache.ptrw();
ShaderCompiler::GeneratedCode::Texture *texture_uniforms = shader_data->texture_uniforms.ptrw();
@ -3278,6 +3264,18 @@ void SceneShaderData::set_code(const String &p_code) {
actions.write_flag_pointers["VERTEX"] = &uses_vertex;
actions.write_flag_pointers["POSITION"] = &uses_position;
actions.usage_flag_pointers["TANGENT"] = &uses_tangent;
actions.usage_flag_pointers["BINORMAL"] = &uses_tangent;
actions.usage_flag_pointers["COLOR"] = &uses_color;
actions.usage_flag_pointers["UV"] = &uses_uv;
actions.usage_flag_pointers["UV2"] = &uses_uv2;
actions.usage_flag_pointers["CUSTOM0"] = &uses_custom0;
actions.usage_flag_pointers["CUSTOM1"] = &uses_custom1;
actions.usage_flag_pointers["CUSTOM2"] = &uses_custom2;
actions.usage_flag_pointers["CUSTOM3"] = &uses_custom3;
actions.usage_flag_pointers["BONE_INDICES"] = &uses_bones;
actions.usage_flag_pointers["BONE_WEIGHTS"] = &uses_weights;
actions.uniforms = &uniforms;
Error err = MaterialStorage::get_singleton()->shaders.compiler_scene.compile(RS::SHADER_SPATIAL, code, &actions, path, gen_code);
@ -3292,6 +3290,17 @@ void SceneShaderData::set_code(const String &p_code) {
cull_mode = Cull(cull_modei);
blend_mode = BlendMode(blend_modei);
alpha_antialiasing_mode = AlphaAntiAliasing(alpha_antialiasing_modei);
vertex_input_mask = uint32_t(uses_normal);
vertex_input_mask |= uses_tangent << 1;
vertex_input_mask |= uses_color << 2;
vertex_input_mask |= uses_uv << 3;
vertex_input_mask |= uses_uv2 << 4;
vertex_input_mask |= uses_custom0 << 5;
vertex_input_mask |= uses_custom1 << 6;
vertex_input_mask |= uses_custom2 << 7;
vertex_input_mask |= uses_custom3 << 8;
vertex_input_mask |= uses_bones << 9;
vertex_input_mask |= uses_weights << 10;
#if 0
print_line("**compiling shader:");
@ -3455,7 +3464,7 @@ GLES3::MaterialData *GLES3::_create_scene_material_func(ShaderData *p_shader) {
void SceneMaterialData::bind_uniforms() {
// Bind Material Uniforms
glBindBufferBase(GL_UNIFORM_BUFFER, 3, uniform_buffer);
glBindBufferBase(GL_UNIFORM_BUFFER, SCENE_MATERIAL_UNIFORM_LOCATION, uniform_buffer);
RID *textures = texture_cache.ptrw();
ShaderCompiler::GeneratedCode::Texture *texture_uniforms = shader_data->texture_uniforms.ptrw();

View file

@ -279,14 +279,6 @@ struct SceneShaderData : public ShaderData {
CULL_BACK
};
enum CullVariant {
CULL_VARIANT_NORMAL,
CULL_VARIANT_REVERSED,
CULL_VARIANT_DOUBLE_SIDED,
CULL_VARIANT_MAX
};
enum AlphaAntiAliasing {
ALPHA_ANTIALIASING_OFF,
ALPHA_ANTIALIASING_ALPHA_TO_COVERAGE,
@ -335,6 +327,18 @@ struct SceneShaderData : public ShaderData {
bool uses_time;
bool writes_modelview_or_projection;
bool uses_world_coordinates;
bool uses_tangent;
bool uses_color;
bool uses_uv;
bool uses_uv2;
bool uses_custom0;
bool uses_custom1;
bool uses_custom2;
bool uses_custom3;
bool uses_bones;
bool uses_weights;
uint32_t vertex_input_mask = 0;
uint64_t last_pass = 0;
uint32_t index = 0;

View file

@ -194,6 +194,7 @@ void MeshStorage::mesh_add_surface(RID p_mesh, const RS::SurfaceData &p_surface)
glBindBuffer(GL_ARRAY_BUFFER, s->attribute_buffer);
glBufferData(GL_ARRAY_BUFFER, p_surface.attribute_data.size(), p_surface.attribute_data.ptr(), (s->format & RS::ARRAY_FLAG_USE_DYNAMIC_UPDATE) ? GL_DYNAMIC_DRAW : GL_STATIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, 0); //unbind
s->attribute_buffer_size = p_surface.attribute_data.size();
}
if (p_surface.skin_data.size()) {
glGenBuffers(1, &s->skin_buffer);
@ -216,6 +217,7 @@ void MeshStorage::mesh_add_surface(RID p_mesh, const RS::SurfaceData &p_surface)
glBufferData(GL_ELEMENT_ARRAY_BUFFER, p_surface.index_data.size(), p_surface.index_data.ptr(), GL_STATIC_DRAW);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); //unbind
s->index_count = p_surface.index_count;
s->index_buffer_size = p_surface.index_data.size();
if (p_surface.lods.size()) {
s->lods = memnew_arr(Mesh::Surface::LOD, p_surface.lods.size());
@ -323,7 +325,97 @@ RID MeshStorage::mesh_surface_get_material(RID p_mesh, int p_surface) const {
}
RS::SurfaceData MeshStorage::mesh_get_surface(RID p_mesh, int p_surface) const {
return RS::SurfaceData();
Mesh *mesh = mesh_owner.get_or_null(p_mesh);
ERR_FAIL_COND_V(!mesh, RS::SurfaceData());
ERR_FAIL_UNSIGNED_INDEX_V((uint32_t)p_surface, mesh->surface_count, RS::SurfaceData());
Mesh::Surface &s = *mesh->surfaces[p_surface];
RS::SurfaceData sd;
sd.format = s.format;
{
Vector<uint8_t> ret;
ret.resize(s.vertex_buffer_size);
glBindBuffer(GL_ARRAY_BUFFER, s.vertex_buffer);
#if defined(__EMSCRIPTEN__)
{
uint8_t *w = ret.ptrw();
glGetBufferSubData(GL_ARRAY_BUFFER, 0, s.vertex_buffer_size, w);
}
#else
void *data = glMapBufferRange(GL_ARRAY_BUFFER, 0, s.vertex_buffer_size, GL_MAP_READ_BIT);
ERR_FAIL_NULL_V(data, RS::SurfaceData());
{
uint8_t *w = ret.ptrw();
memcpy(w, data, s.vertex_buffer_size);
}
glUnmapBuffer(GL_ARRAY_BUFFER);
#endif
sd.vertex_data = ret;
}
if (s.attribute_buffer != 0) {
Vector<uint8_t> ret;
ret.resize(s.attribute_buffer_size);
glBindBuffer(GL_ARRAY_BUFFER, s.attribute_buffer);
#if defined(__EMSCRIPTEN__)
{
uint8_t *w = ret.ptrw();
glGetBufferSubData(GL_ARRAY_BUFFER, 0, s.attribute_buffer_size, w);
}
#else
void *data = glMapBufferRange(GL_ARRAY_BUFFER, 0, s.attribute_buffer_size, GL_MAP_READ_BIT);
ERR_FAIL_NULL_V(data, RS::SurfaceData());
{
uint8_t *w = ret.ptrw();
memcpy(w, data, s.attribute_buffer_size);
}
glUnmapBuffer(GL_ARRAY_BUFFER);
#endif
sd.attribute_data = ret;
}
sd.vertex_count = s.vertex_count;
sd.index_count = s.index_count;
sd.primitive = s.primitive;
if (sd.index_count) {
Vector<uint8_t> ret;
ret.resize(s.index_buffer_size);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, s.index_buffer);
#if defined(__EMSCRIPTEN__)
{
uint8_t *w = ret.ptrw();
glGetBufferSubData(GL_ELEMENT_ARRAY_BUFFER, 0, s.index_buffer_size, w);
}
#else
void *data = glMapBufferRange(GL_ELEMENT_ARRAY_BUFFER, 0, s.index_buffer_size, GL_MAP_READ_BIT);
ERR_FAIL_NULL_V(data, RS::SurfaceData());
{
uint8_t *w = ret.ptrw();
memcpy(w, data, s.index_buffer_size);
}
glUnmapBuffer(GL_ELEMENT_ARRAY_BUFFER);
#endif
sd.index_data = ret;
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
}
sd.aabb = s.aabb;
for (uint32_t i = 0; i < s.lod_count; i++) {
RS::SurfaceData::LOD lod;
lod.edge_length = s.lods[i].edge_length;
//lod.index_data = RD::get_singleton()->buffer_get_data(s.lods[i].index_buffer);
sd.lods.push_back(lod);
}
sd.bone_aabbs = s.bone_aabbs;
glBindBuffer(GL_ARRAY_BUFFER, 0);
return sd;
}
int MeshStorage::mesh_get_surface_count(RID p_mesh) const {
@ -496,7 +588,6 @@ void MeshStorage::mesh_clear(RID p_mesh) {
if (s.index_buffer != 0) {
glDeleteBuffers(1, &s.index_buffer);
glDeleteVertexArrays(1, &s.index_array);
}
memdelete(mesh->surfaces[i]);
}
@ -553,14 +644,14 @@ void MeshStorage::_mesh_surface_generate_version_for_input_mask(Mesh::Surface::V
case RS::ARRAY_NORMAL: {
attribs[i].offset = vertex_stride;
// Will need to change to accommodate octahedral compression
attribs[i].size = 1;
attribs[i].size = 4;
attribs[i].type = GL_UNSIGNED_INT_2_10_10_10_REV;
vertex_stride += sizeof(float);
attribs[i].normalized = GL_TRUE;
} break;
case RS::ARRAY_TANGENT: {
attribs[i].offset = vertex_stride;
attribs[i].size = 1;
attribs[i].size = 4;
attribs[i].type = GL_UNSIGNED_INT_2_10_10_10_REV;
vertex_stride += sizeof(float);
attribs[i].normalized = GL_TRUE;
@ -629,14 +720,17 @@ void MeshStorage::_mesh_surface_generate_version_for_input_mask(Mesh::Surface::V
continue;
}
if (i <= RS::ARRAY_TANGENT) {
attribs[i].stride = vertex_stride;
if (mis) {
glBindBuffer(GL_ARRAY_BUFFER, mis->vertex_buffer);
} else {
glBindBuffer(GL_ARRAY_BUFFER, s->vertex_buffer);
}
} else if (i <= RS::ARRAY_CUSTOM3) {
attribs[i].stride = attributes_stride;
glBindBuffer(GL_ARRAY_BUFFER, s->attribute_buffer);
} else {
attribs[i].stride = skin_stride;
glBindBuffer(GL_ARRAY_BUFFER, s->skin_buffer);
}
@ -645,7 +739,7 @@ void MeshStorage::_mesh_surface_generate_version_for_input_mask(Mesh::Surface::V
} else {
glVertexAttribPointer(i, attribs[i].size, attribs[i].type, attribs[i].normalized, attribs[i].stride, CAST_INT_TO_UCHAR_PTR(attribs[i].offset));
}
glEnableVertexAttribArray(attribs[i].index);
glEnableVertexAttribArray(i);
}
// Do not bind index here as we want to switch between index buffers for LOD

View file

@ -54,7 +54,6 @@ struct Mesh {
struct Attrib {
bool enabled;
bool integer;
GLuint index;
GLint size;
GLenum type;
GLboolean normalized;
@ -69,6 +68,7 @@ struct Mesh {
GLuint skin_buffer = 0;
uint32_t vertex_count = 0;
uint32_t vertex_buffer_size = 0;
uint32_t attribute_buffer_size = 0;
uint32_t skin_buffer_size = 0;
// Cache vertex arrays so they can be created
@ -84,8 +84,8 @@ struct Mesh {
uint32_t version_count = 0;
GLuint index_buffer = 0;
GLuint index_array = 0;
uint32_t index_count = 0;
uint32_t index_buffer_size = 0;
struct LOD {
float edge_length = 0.0;
@ -357,6 +357,12 @@ public:
}
}
_FORCE_INLINE_ GLenum mesh_surface_get_index_type(void *p_surface) const {
Mesh::Surface *s = reinterpret_cast<Mesh::Surface *>(p_surface);
return s->vertex_count <= 65536 ? GL_UNSIGNED_SHORT : GL_UNSIGNED_INT;
}
// Use this to cache Vertex Array Objects so they are only generated once
_FORCE_INLINE_ void mesh_surface_get_vertex_arrays_and_format(void *p_surface, uint32_t p_input_mask, GLuint &r_vertex_array_gl) {
Mesh::Surface *s = reinterpret_cast<Mesh::Surface *>(p_surface);

View file

@ -62,8 +62,9 @@ TextureStorage::TextureStorage() {
Ref<Image> image;
image.instantiate();
image->create(4, 4, false, Image::FORMAT_RGBA8);
image->create(4, 4, true, Image::FORMAT_RGBA8);
image->fill(Color(1, 1, 1, 1));
image->generate_mipmaps();
default_gl_textures[DEFAULT_GL_TEXTURE_WHITE] = texture_allocate();
texture_2d_initialize(default_gl_textures[DEFAULT_GL_TEXTURE_WHITE], image);
@ -92,8 +93,9 @@ TextureStorage::TextureStorage() {
{ // black
Ref<Image> image;
image.instantiate();
image->create(4, 4, false, Image::FORMAT_RGBA8);
image->create(4, 4, true, Image::FORMAT_RGBA8);
image->fill(Color(0, 0, 0, 1));
image->generate_mipmaps();
default_gl_textures[DEFAULT_GL_TEXTURE_BLACK] = texture_allocate();
texture_2d_initialize(default_gl_textures[DEFAULT_GL_TEXTURE_BLACK], image);
@ -117,8 +119,9 @@ TextureStorage::TextureStorage() {
{
Ref<Image> image;
image.instantiate();
image->create(4, 4, false, Image::FORMAT_RGBA8);
image->create(4, 4, true, Image::FORMAT_RGBA8);
image->fill(Color(0.5, 0.5, 1, 1));
image->generate_mipmaps();
default_gl_textures[DEFAULT_GL_TEXTURE_NORMAL] = texture_allocate();
texture_2d_initialize(default_gl_textures[DEFAULT_GL_TEXTURE_NORMAL], image);
@ -127,8 +130,9 @@ TextureStorage::TextureStorage() {
{
Ref<Image> image;
image.instantiate();
image->create(4, 4, false, Image::FORMAT_RGBA8);
image->create(4, 4, true, Image::FORMAT_RGBA8);
image->fill(Color(1.0, 0.5, 1, 1));
image->generate_mipmaps();
default_gl_textures[DEFAULT_GL_TEXTURE_ANISO] = texture_allocate();
texture_2d_initialize(default_gl_textures[DEFAULT_GL_TEXTURE_ANISO], image);
@ -189,18 +193,7 @@ TextureStorage::~TextureStorage() {
}
}
void TextureStorage::set_main_thread_id(Thread::ID p_id) {
_main_thread_id = p_id;
}
bool TextureStorage::_is_main_thread() {
//#if defined DEBUG_ENABLED && defined TOOLS_ENABLED
// must be called from main thread in OpenGL
bool is_main_thread = _main_thread_id == Thread::get_caller_id();
//#endif
return is_main_thread;
}
//TODO, move back to storage
bool TextureStorage::can_create_resources_async() const {
return false;
}
@ -644,10 +637,14 @@ void TextureStorage::texture_2d_initialize(RID p_texture, const Ref<Image> &p_im
Texture texture;
texture.width = p_image->get_width();
texture.height = p_image->get_height();
texture.alloc_width = texture.width;
texture.alloc_height = texture.height;
texture.mipmaps = p_image->get_mipmap_count();
texture.format = p_image->get_format();
texture.type = Texture::TYPE_2D;
texture.target = GL_TEXTURE_2D;
texture.image_cache_2d = p_image; //TODO, remove this once texture_2d_get is implemented
_get_gl_image_and_format(Ref<Image>(), texture.format, 0, texture.real_format, texture.gl_format_cache, texture.gl_internal_format_cache, texture.gl_type_cache, texture.compressed, false);
//texture.total_data_size = p_image->get_image_data_size(); // verify that this returns size in bytes
texture.active = true;
glGenTextures(1, &texture.tex_id);
texture_owner.initialize_rid(p_texture, texture);
@ -740,49 +737,66 @@ void TextureStorage::texture_3d_placeholder_initialize(RID p_texture) {
}
Ref<Image> TextureStorage::texture_2d_get(RID p_texture) const {
Texture *tex = texture_owner.get_or_null(p_texture);
ERR_FAIL_COND_V(!tex, Ref<Image>());
Texture *texture = texture_owner.get_or_null(p_texture);
ERR_FAIL_COND_V(!texture, Ref<Image>());
#ifdef TOOLS_ENABLED
if (tex->image_cache_2d.is_valid() && !tex->is_render_target) {
return tex->image_cache_2d;
if (texture->image_cache_2d.is_valid() && !texture->is_render_target) {
return texture->image_cache_2d;
}
#endif
/*
#ifdef TOOLS_ENABLED
if (tex->image_cache_2d.is_valid()) {
return tex->image_cache_2d;
#ifdef GLES_OVER_GL
// OpenGL 3.3 supports glGetTexImage which is faster and simpler than glReadPixels.
Vector<uint8_t> data;
int data_size = Image::get_image_data_size(texture->alloc_width, texture->alloc_height, texture->real_format, texture->mipmaps > 1);
data.resize(data_size * 2); //add some memory at the end, just in case for buggy drivers
uint8_t *w = data.ptrw();
glActiveTexture(GL_TEXTURE0);
glBindTexture(texture->target, texture->tex_id);
glBindBuffer(GL_PIXEL_PACK_BUFFER, 0);
for (int i = 0; i < texture->mipmaps; i++) {
int ofs = Image::get_image_mipmap_offset(texture->alloc_width, texture->alloc_height, texture->real_format, i);
if (texture->compressed) {
glPixelStorei(GL_PACK_ALIGNMENT, 4);
glGetCompressedTexImage(texture->target, i, &w[ofs]);
} else {
glPixelStorei(GL_PACK_ALIGNMENT, 1);
glGetTexImage(texture->target, i, texture->gl_format_cache, texture->gl_type_cache, &w[ofs]);
}
}
#endif
Vector<uint8_t> data = RD::get_singleton()->texture_get_data(tex->rd_texture, 0);
data.resize(data_size);
ERR_FAIL_COND_V(data.size() == 0, Ref<Image>());
Ref<Image> image;
image.instance();
image->create(tex->width, tex->height, tex->mipmaps > 1, tex->validated_format, data);
ERR_FAIL_COND_V(image->empty(), Ref<Image>());
if (tex->format != tex->validated_format) {
image->convert(tex->format);
image.instantiate();
image->create(texture->width, texture->height, texture->mipmaps > 1, texture->real_format, data);
ERR_FAIL_COND_V(image->is_empty(), Ref<Image>());
if (texture->format != texture->real_format) {
image->convert(texture->format);
}
#else
// Support for Web and Mobile will come later.
Ref<Image> image;
#endif
#ifdef TOOLS_ENABLED
if (Engine::get_singleton()->is_editor_hint()) {
tex->image_cache_2d = image;
if (Engine::get_singleton()->is_editor_hint() && !texture->is_render_target) {
texture->image_cache_2d = image;
}
#endif
*/
/*
#ifdef TOOLS_ENABLED
if (Engine::get_singleton()->is_editor_hint() && !tex->is_render_target) {
tex->image_cache_2d = image;
}
#endif
*/
// return image;
return Ref<Image>();
return image;
}
void TextureStorage::texture_replace(RID p_texture, RID p_by_texture) {
@ -1357,6 +1371,9 @@ void TextureStorage::_update_render_target(RenderTarget *rt) {
}
texture->format = rt->image_format;
texture->real_format = rt->image_format;
texture->type = Texture::TYPE_2D;
texture->target = GL_TEXTURE_2D;
texture->gl_format_cache = rt->color_format;
texture->gl_type_cache = GL_UNSIGNED_BYTE;
texture->gl_internal_format_cache = rt->color_internal_format;

View file

@ -141,6 +141,7 @@ struct Texture {
int alloc_width = 0;
int alloc_height = 0;
Image::Format format = Image::FORMAT_R8;
Image::Format real_format = Image::FORMAT_R8;
enum Type {
TYPE_2D,
@ -370,9 +371,6 @@ private:
RID default_gl_textures[DEFAULT_GL_TEXTURE_MAX];
Thread::ID _main_thread_id = 0;
bool _is_main_thread();
/* Canvas Texture API */
RID_Owner<CanvasTexture, true> canvas_texture_owner;
@ -440,8 +438,6 @@ public:
};
bool owns_texture(RID p_rid) { return texture_owner.owns(p_rid); };
void set_main_thread_id(Thread::ID p_id);
virtual bool can_create_resources_async() const override;
RID texture_create();

View file

@ -623,8 +623,6 @@ void EditorNode::_notification(int p_what) {
ResourceImporterTexture::get_singleton()->update_imports();
// if using a main thread only renderer, we need to update the resource previews
EditorResourcePreview::get_singleton()->update();
} break;
case NOTIFICATION_ENTER_TREE: {

View file

@ -430,12 +430,8 @@ void EditorResourcePreview::check_for_invalidation(const String &p_path) {
}
void EditorResourcePreview::start() {
if (OS::get_singleton()->get_render_main_thread_mode() == OS::RENDER_ANY_THREAD) {
ERR_FAIL_COND_MSG(thread.is_started(), "Thread already started.");
thread.start(_thread_func, this);
} else {
_mainthread_only = true;
}
ERR_FAIL_COND_MSG(thread.is_started(), "Thread already started.");
thread.start(_thread_func, this);
}
void EditorResourcePreview::stop() {
@ -458,18 +454,3 @@ EditorResourcePreview::EditorResourcePreview() {
EditorResourcePreview::~EditorResourcePreview() {
stop();
}
void EditorResourcePreview::update() {
if (!_mainthread_only) {
return;
}
if (!exit.is_set()) {
// no need to even lock the mutex if the size is zero
// there is no problem if queue.size() is wrong, even if
// there was a race condition.
if (queue.size()) {
_iterate();
}
}
}

View file

@ -81,11 +81,6 @@ class EditorResourcePreview : public Node {
SafeFlag exit;
SafeFlag exited;
// when running from GLES, we want to run the previews
// in the main thread using an update, rather than create
// a separate thread
bool _mainthread_only = false;
struct Item {
Ref<Texture2D> preview;
Ref<Texture2D> small_preview;
@ -125,9 +120,6 @@ public:
void start();
void stop();
// for single threaded mode
void update();
EditorResourcePreview();
~EditorResourcePreview();
};

View file

@ -4112,13 +4112,13 @@ void DisplayServerX11::process_events() {
void DisplayServerX11::release_rendering_thread() {
#if defined(GLES3_ENABLED)
// gl_manager->release_current();
gl_manager->release_current();
#endif
}
void DisplayServerX11::make_rendering_thread() {
#if defined(GLES3_ENABLED)
// gl_manager->make_current();
gl_manager->make_current();
#endif
}

View file

@ -1096,7 +1096,6 @@ void Environment::_validate_property(PropertyInfo &property) const {
static const char *high_end_prefixes[] = {
"auto_exposure_",
"tonemap_",
"ssr_",
"ssao_",
nullptr

View file

@ -50,4 +50,34 @@ struct ReflectionData {
// notes: for ambientblend, use distance to edge to blend between already existing global environment
};
uv_scale1
struct DirectionalLightData {
mediump vec3 direction;
mediump float energy;
mediump vec3 color;
mediump float size;
mediump float specular;
uint mask;
highp float softshadow_angle;
highp float soft_shadow_scale;
bool blend_splits;
bool shadow_enabled;
highp float fade_from;
highp float fade_to;
uvec2 pad;
uint bake_mode;
mediump float shadow_volumetric_fog_fade;
highp vec4 shadow_bias;
highp vec4 shadow_normal_bias;
highp vec4 shadow_transmittance_bias;
highp vec4 shadow_z_range;
highp vec4 shadow_range_begin;
highp vec4 shadow_split_offsets;
highp mat4 shadow_matrix1;
highp mat4 shadow_matrix2;
highp mat4 shadow_matrix3;
highp mat4 shadow_matrix4;
highp vec2 uv_scale1;
highp vec2 uv_scale2;
highp vec2 uv_scale3;
highp vec2 uv_scale4;
};

View file

@ -2885,6 +2885,7 @@ RenderingServer::RenderingServer() {
GLOBAL_DEF("rendering/shading/overrides/force_lambert_over_burley.mobile", true);
GLOBAL_DEF("rendering/driver/depth_prepass/enable", true);
GLOBAL_DEF("rendering/driver/depth_prepass/disable_for_vendors", "PowerVR,Mali,Adreno,Apple");
GLOBAL_DEF_RST("rendering/textures/default_filters/use_nearest_mipmap_filter", false);
GLOBAL_DEF_RST("rendering/textures/default_filters/anisotropic_filtering_level", 2);
@ -3002,44 +3003,15 @@ RenderingServer::RenderingServer() {
GLOBAL_DEF("rendering/limits/cluster_builder/max_clustered_elements", 512);
ProjectSettings::get_singleton()->set_custom_property_info("rendering/limits/cluster_builder/max_clustered_elements", PropertyInfo(Variant::FLOAT, "rendering/limits/cluster_builder/max_clustered_elements", PROPERTY_HINT_RANGE, "32,8192,1"));
// OpenGL limits
GLOBAL_DEF_RST("rendering/limits/opengl/max_renderable_elements", 65536);
ProjectSettings::get_singleton()->set_custom_property_info("rendering/limits/opengl/max_renderable_elements", PropertyInfo(Variant::INT, "rendering/limits/opengl/max_renderable_elements", PROPERTY_HINT_RANGE, "1024,65536,1"));
GLOBAL_DEF_RST("rendering/limits/opengl/max_renderable_lights", 256);
ProjectSettings::get_singleton()->set_custom_property_info("rendering/limits/opengl/max_renderable_lights", PropertyInfo(Variant::INT, "rendering/limits/opengl/max_renderable_lights", PROPERTY_HINT_RANGE, "16,4096,1"));
GLOBAL_DEF_RST("rendering/limits/opengl/max_lights_per_object", 8);
ProjectSettings::get_singleton()->set_custom_property_info("rendering/limits/opengl/max_lights_per_object", PropertyInfo(Variant::INT, "rendering/limits/opengl/max_lights_per_object", PROPERTY_HINT_RANGE, "2,1024,1"));
GLOBAL_DEF_RST_BASIC("xr/shaders/enabled", false);
GLOBAL_DEF_RST("rendering/2d/options/use_software_skinning", true);
GLOBAL_DEF_RST("rendering/2d/options/ninepatch_mode", 1);
ProjectSettings::get_singleton()->set_custom_property_info("rendering/2d/options/ninepatch_mode", PropertyInfo(Variant::INT, "rendering/2d/options/ninepatch_mode", PROPERTY_HINT_ENUM, "Fixed,Scaling"));
GLOBAL_DEF_RST("rendering/2d/opengl/batching_send_null", 0);
ProjectSettings::get_singleton()->set_custom_property_info("rendering/2d/opengl/batching_send_null", PropertyInfo(Variant::INT, "rendering/2d/opengl/batching_send_null", PROPERTY_HINT_ENUM, "Default (On),Off,On"));
GLOBAL_DEF_RST("rendering/2d/opengl/batching_stream", 0);
ProjectSettings::get_singleton()->set_custom_property_info("rendering/2d/opengl/batching_stream", PropertyInfo(Variant::INT, "rendering/2d/opengl/batching_stream", PROPERTY_HINT_ENUM, "Default (Off),Off,On"));
GLOBAL_DEF_RST("rendering/2d/opengl/legacy_orphan_buffers", 0);
ProjectSettings::get_singleton()->set_custom_property_info("rendering/2d/opengl/legacy_orphan_buffers", PropertyInfo(Variant::INT, "rendering/2d/opengl/legacy_orphan_buffers", PROPERTY_HINT_ENUM, "Default (On),Off,On"));
GLOBAL_DEF_RST("rendering/2d/opengl/legacy_stream", 0);
ProjectSettings::get_singleton()->set_custom_property_info("rendering/2d/opengl/legacy_stream", PropertyInfo(Variant::INT, "rendering/2d/opengl/legacy_stream", PROPERTY_HINT_ENUM, "Default (On),Off,On"));
GLOBAL_DEF("rendering/batching/options/use_batching", false);
GLOBAL_DEF_RST("rendering/batching/options/use_batching_in_editor", false);
GLOBAL_DEF("rendering/batching/options/single_rect_fallback", false);
GLOBAL_DEF("rendering/batching/parameters/max_join_item_commands", 16);
GLOBAL_DEF("rendering/batching/parameters/colored_vertex_format_threshold", 0.25f);
GLOBAL_DEF("rendering/batching/lights/scissor_area_threshold", 1.0f);
GLOBAL_DEF("rendering/batching/lights/max_join_items", 32);
GLOBAL_DEF("rendering/batching/parameters/batch_buffer_size", 16384);
GLOBAL_DEF("rendering/batching/parameters/item_reordering_lookahead", 4);
GLOBAL_DEF("rendering/batching/debug/flash_batching", false);
GLOBAL_DEF("rendering/batching/debug/diagnose_frame", false);
GLOBAL_DEF("rendering/gles2/compatibility/disable_half_float", false);
GLOBAL_DEF("rendering/gles2/compatibility/enable_high_float.Android", false);
GLOBAL_DEF("rendering/batching/precision/uv_contract", false);
GLOBAL_DEF("rendering/batching/precision/uv_contract_amount", 100);
ProjectSettings::get_singleton()->set_custom_property_info("rendering/batching/parameters/max_join_item_commands", PropertyInfo(Variant::INT, "rendering/batching/parameters/max_join_item_commands", PROPERTY_HINT_RANGE, "0,65535"));
ProjectSettings::get_singleton()->set_custom_property_info("rendering/batching/parameters/colored_vertex_format_threshold", PropertyInfo(Variant::FLOAT, "rendering/batching/parameters/colored_vertex_format_threshold", PROPERTY_HINT_RANGE, "0.0,1.0,0.01"));
ProjectSettings::get_singleton()->set_custom_property_info("rendering/batching/parameters/batch_buffer_size", PropertyInfo(Variant::INT, "rendering/batching/parameters/batch_buffer_size", PROPERTY_HINT_RANGE, "1024,65535,1024"));
ProjectSettings::get_singleton()->set_custom_property_info("rendering/batching/lights/scissor_area_threshold", PropertyInfo(Variant::FLOAT, "rendering/batching/lights/scissor_area_threshold", PROPERTY_HINT_RANGE, "0.0,1.0"));
ProjectSettings::get_singleton()->set_custom_property_info("rendering/batching/lights/max_join_items", PropertyInfo(Variant::INT, "rendering/batching/lights/max_join_items", PROPERTY_HINT_RANGE, "0,512"));
ProjectSettings::get_singleton()->set_custom_property_info("rendering/batching/parameters/item_reordering_lookahead", PropertyInfo(Variant::INT, "rendering/batching/parameters/item_reordering_lookahead", PROPERTY_HINT_RANGE, "0,256"));
ProjectSettings::get_singleton()->set_custom_property_info("rendering/batching/precision/uv_contract_amount", PropertyInfo(Variant::INT, "rendering/batching/precision/uv_contract_amount", PROPERTY_HINT_RANGE, "0,10000"));
}
RenderingServer::~RenderingServer() {