summaryrefslogtreecommitdiff
path: root/drivers/gles3/rasterizer_storage_gles3.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gles3/rasterizer_storage_gles3.cpp')
-rw-r--r--drivers/gles3/rasterizer_storage_gles3.cpp287
1 files changed, 274 insertions, 13 deletions
diff --git a/drivers/gles3/rasterizer_storage_gles3.cpp b/drivers/gles3/rasterizer_storage_gles3.cpp
index 1801260146..85331342e9 100644
--- a/drivers/gles3/rasterizer_storage_gles3.cpp
+++ b/drivers/gles3/rasterizer_storage_gles3.cpp
@@ -1072,6 +1072,14 @@ void RasterizerStorageGLES3::texture_set_detect_srgb_callback(RID p_texture, Vis
texture->detect_srgb_ud = p_userdata;
}
+void RasterizerStorageGLES3::texture_set_detect_normal_callback(RID p_texture, VisualServer::TextureDetectCallback p_callback, void *p_userdata) {
+ Texture *texture = texture_owner.get(p_texture);
+ ERR_FAIL_COND(!texture);
+
+ texture->detect_normal = p_callback;
+ texture->detect_normal_ud = p_userdata;
+}
+
RID RasterizerStorageGLES3::texture_create_radiance_cubemap(RID p_source, int p_resolution) const {
Texture *texture = texture_owner.get(p_source);
@@ -1425,6 +1433,7 @@ void RasterizerStorageGLES3::_update_shader(Shader *p_shader) const {
_shader_dirty_list.remove(&p_shader->dirty_list);
p_shader->valid = false;
+ p_shader->ubo_size = 0;
p_shader->uniforms.clear();
@@ -1547,7 +1556,11 @@ void RasterizerStorageGLES3::shader_get_param_list(RID p_shader, List<PropertyIn
for (Map<StringName, ShaderLanguage::ShaderNode::Uniform>::Element *E = shader->uniforms.front(); E; E = E->next()) {
- order[E->get().order] = E->key();
+ if (E->get().texture_order >= 0) {
+ order[E->get().texture_order + 100000] = E->key();
+ } else {
+ order[E->get().order] = E->key();
+ }
}
for (Map<int, StringName>::Element *E = order.front(); E; E = E->next()) {
@@ -2244,6 +2257,10 @@ void RasterizerStorageGLES3::_update_material(Material *material) {
if (material->shader && material->shader->dirty_list.in_list()) {
_update_shader(material->shader);
}
+
+ if (material->shader && !material->shader->valid)
+ return;
+
//update caches
{
@@ -2658,6 +2675,7 @@ void RasterizerStorageGLES3::mesh_add_surface(RID p_mesh, uint32_t p_format, VS:
surface->skeleton_bone_used.resize(surface->skeleton_bone_aabb.size());
surface->aabb = p_aabb;
surface->max_bone = p_bone_aabbs.size();
+ surface->total_data_size += surface->array_byte_size + surface->index_array_byte_size;
for (int i = 0; i < surface->skeleton_bone_used.size(); i++) {
if (surface->skeleton_bone_aabb[i].size.x < 0 || surface->skeleton_bone_aabb[i].size.y < 0 || surface->skeleton_bone_aabb[i].size.z < 0) {
@@ -2727,6 +2745,112 @@ void RasterizerStorageGLES3::mesh_add_surface(RID p_mesh, uint32_t p_format, VS:
glBindBuffer(GL_ARRAY_BUFFER, 0); //unbind
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
}
+
+#ifdef DEBUG_ENABLED
+
+ if (config.generate_wireframes && p_primitive == VS::PRIMITIVE_TRIANGLES) {
+ //generate wireframes, this is used mostly by editor
+ PoolVector<uint32_t> wf_indices;
+ int index_count;
+
+ if (p_format & VS::ARRAY_FORMAT_INDEX) {
+
+ index_count = p_index_count * 2;
+ wf_indices.resize(index_count);
+
+ PoolVector<uint8_t>::Read ir = p_index_array.read();
+ PoolVector<uint32_t>::Write wr = wf_indices.write();
+
+ if (p_vertex_count < (1 << 16)) {
+ //read 16 bit indices
+ const uint16_t *src_idx = (const uint16_t *)ir.ptr();
+ for (int i = 0; i < index_count; i += 6) {
+
+ wr[i + 0] = src_idx[i / 2];
+ wr[i + 1] = src_idx[i / 2 + 1];
+ wr[i + 2] = src_idx[i / 2 + 1];
+ wr[i + 3] = src_idx[i / 2 + 2];
+ wr[i + 4] = src_idx[i / 2 + 2];
+ wr[i + 5] = src_idx[i / 2];
+ }
+
+ } else {
+
+ //read 16 bit indices
+ const uint32_t *src_idx = (const uint32_t *)ir.ptr();
+ for (int i = 0; i < index_count; i += 6) {
+
+ wr[i + 0] = src_idx[i / 2];
+ wr[i + 1] = src_idx[i / 2 + 1];
+ wr[i + 2] = src_idx[i / 2 + 1];
+ wr[i + 3] = src_idx[i / 2 + 2];
+ wr[i + 4] = src_idx[i / 2 + 2];
+ wr[i + 5] = src_idx[i / 2];
+ }
+ }
+
+ } else {
+
+ index_count = p_vertex_count * 2;
+ wf_indices.resize(index_count);
+ PoolVector<uint32_t>::Write wr = wf_indices.write();
+ for (int i = 0; i < index_count; i += 6) {
+
+ wr[i + 0] = i / 2;
+ wr[i + 1] = i / 2 + 1;
+ wr[i + 2] = i / 2 + 1;
+ wr[i + 3] = i / 2 + 2;
+ wr[i + 4] = i / 2 + 2;
+ wr[i + 5] = i / 2;
+ }
+ }
+ {
+ PoolVector<uint32_t>::Read ir = wf_indices.read();
+
+ glGenBuffers(1, &surface->index_wireframe_id);
+ glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, surface->index_wireframe_id);
+ glBufferData(GL_ELEMENT_ARRAY_BUFFER, index_count * sizeof(uint32_t), ir.ptr(), GL_STATIC_DRAW);
+ glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); //unbind
+
+ surface->index_wireframe_len = index_count;
+ }
+
+ for (int ai = 0; ai < 2; ai++) {
+
+ if (ai == 0) {
+ //for normal draw
+ glGenVertexArrays(1, &surface->array_wireframe_id);
+ glBindVertexArray(surface->array_wireframe_id);
+ glBindBuffer(GL_ARRAY_BUFFER, surface->vertex_id);
+ } else if (ai == 1) {
+ //for instancing draw (can be changed and no one cares)
+ glGenVertexArrays(1, &surface->instancing_array_wireframe_id);
+ glBindVertexArray(surface->instancing_array_wireframe_id);
+ glBindBuffer(GL_ARRAY_BUFFER, surface->vertex_id);
+ }
+
+ for (int i = 0; i < VS::ARRAY_MAX - 1; i++) {
+
+ if (!attribs[i].enabled)
+ continue;
+
+ if (attribs[i].integer) {
+ glVertexAttribIPointer(attribs[i].index, attribs[i].size, attribs[i].type, attribs[i].stride, ((uint8_t *)0) + attribs[i].offset);
+ } else {
+ glVertexAttribPointer(attribs[i].index, attribs[i].size, attribs[i].type, attribs[i].normalized, attribs[i].stride, ((uint8_t *)0) + attribs[i].offset);
+ }
+ glEnableVertexAttribArray(attribs[i].index);
+ }
+
+ glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, surface->index_wireframe_id);
+
+ glBindVertexArray(0);
+ glBindBuffer(GL_ARRAY_BUFFER, 0); //unbind
+ glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
+ }
+ }
+
+#endif
}
{
@@ -2739,6 +2863,8 @@ void RasterizerStorageGLES3::mesh_add_surface(RID p_mesh, uint32_t p_format, VS:
PoolVector<uint8_t>::Read vr = p_blend_shapes[i].read();
+ surface->total_data_size += array_size;
+
glGenBuffers(1, &mt.vertex_id);
glBindBuffer(GL_ARRAY_BUFFER, mt.vertex_id);
glBufferData(GL_ARRAY_BUFFER, array_size, vr.ptr(), GL_STATIC_DRAW);
@@ -2770,6 +2896,8 @@ void RasterizerStorageGLES3::mesh_add_surface(RID p_mesh, uint32_t p_format, VS:
mesh->surfaces.push_back(surface);
mesh->instance_change_notify();
+
+ info.vertex_mem += surface->total_data_size;
}
void RasterizerStorageGLES3::mesh_set_blend_shape_count(RID p_mesh, int p_amount) {
@@ -2991,6 +3119,7 @@ void RasterizerStorageGLES3::mesh_remove_surface(RID p_mesh, int p_surface) {
}
glDeleteVertexArrays(1, &surface->array_id);
+ glDeleteVertexArrays(1, &surface->instancing_array_id);
for (int i = 0; i < surface->blend_shapes.size(); i++) {
@@ -2998,6 +3127,14 @@ void RasterizerStorageGLES3::mesh_remove_surface(RID p_mesh, int p_surface) {
glDeleteVertexArrays(1, &surface->blend_shapes[i].array_id);
}
+ if (surface->index_wireframe_id) {
+ glDeleteBuffers(1, &surface->index_wireframe_id);
+ glDeleteVertexArrays(1, &surface->array_wireframe_id);
+ glDeleteVertexArrays(1, &surface->instancing_array_wireframe_id);
+ }
+
+ info.vertex_mem -= surface->total_data_size;
+
mesh->instance_material_change_notify();
memdelete(surface);
@@ -4149,7 +4286,6 @@ RID RasterizerStorageGLES3::light_create(VS::LightType p_type) {
light->param[VS::LIGHT_PARAM_SHADOW_SPLIT_2_OFFSET] = 0.3;
light->param[VS::LIGHT_PARAM_SHADOW_SPLIT_3_OFFSET] = 0.6;
light->param[VS::LIGHT_PARAM_SHADOW_NORMAL_BIAS] = 0.1;
- light->param[VS::LIGHT_PARAM_SHADOW_BIAS_SPLIT_SCALE] = 0.1;
light->color = Color(1, 1, 1, 1);
light->shadow = false;
@@ -4186,8 +4322,7 @@ void RasterizerStorageGLES3::light_set_param(RID p_light, VS::LightParam p_param
case VS::LIGHT_PARAM_SHADOW_SPLIT_2_OFFSET:
case VS::LIGHT_PARAM_SHADOW_SPLIT_3_OFFSET:
case VS::LIGHT_PARAM_SHADOW_NORMAL_BIAS:
- case VS::LIGHT_PARAM_SHADOW_BIAS:
- case VS::LIGHT_PARAM_SHADOW_BIAS_SPLIT_SCALE: {
+ case VS::LIGHT_PARAM_SHADOW_BIAS: {
light->version++;
light->instance_change_notify();
@@ -5127,6 +5262,23 @@ void RasterizerStorageGLES3::particles_set_emission_transform(RID p_particles, c
particles->emission_transform = p_transform;
}
+int RasterizerStorageGLES3::particles_get_draw_passes(RID p_particles) const {
+
+ const Particles *particles = particles_owner.getornull(p_particles);
+ ERR_FAIL_COND_V(!particles, 0);
+
+ return particles->draw_passes.size();
+}
+
+RID RasterizerStorageGLES3::particles_get_draw_pass_mesh(RID p_particles, int p_pass) const {
+
+ const Particles *particles = particles_owner.getornull(p_particles);
+ ERR_FAIL_COND_V(!particles, RID());
+ ERR_FAIL_INDEX_V(p_pass, particles->draw_passes.size(), RID());
+
+ return particles->draw_passes[p_pass];
+}
+
void RasterizerStorageGLES3::_particles_process(Particles *particles, float p_delta) {
float new_phase = Math::fmod((float)particles->phase + (p_delta / particles->lifetime) * particles->speed_scale, (float)1.0);
@@ -5258,7 +5410,7 @@ void RasterizerStorageGLES3::update_particles() {
shaders.particles.bind();
shaders.particles.set_uniform(ParticlesShaderGLES3::TOTAL_PARTICLES, particles->amount);
- shaders.particles.set_uniform(ParticlesShaderGLES3::TIME, Color(frame.time[0], frame.time[1], frame.time[2], frame.time[3]));
+ shaders.particles.set_uniform(ParticlesShaderGLES3::TIME, frame.time[0]);
shaders.particles.set_uniform(ParticlesShaderGLES3::EXPLOSIVENESS, particles->explosiveness);
shaders.particles.set_uniform(ParticlesShaderGLES3::LIFETIME, particles->lifetime);
shaders.particles.set_uniform(ParticlesShaderGLES3::ATTRACTOR_COUNT, 0);
@@ -5321,13 +5473,11 @@ void RasterizerStorageGLES3::update_particles() {
particles->particle_valid_histories[0] = true;
}
+
+ particles->instance_change_notify(); //make sure shadows are updated
}
glDisable(GL_RASTERIZER_DISCARD);
-
- for (int i = 0; i < 6; i++) {
- glDisableVertexAttribArray(i);
- }
}
////////
@@ -5914,10 +6064,20 @@ void RasterizerStorageGLES3::render_target_set_flag(RID p_render_target, RenderT
default: {}
}
}
+bool RasterizerStorageGLES3::render_target_was_used(RID p_render_target) {
-bool RasterizerStorageGLES3::render_target_renedered_in_frame(RID p_render_target) {
+ RenderTarget *rt = render_target_owner.getornull(p_render_target);
+ ERR_FAIL_COND_V(!rt, false);
- return false;
+ return rt->used_in_frame;
+}
+
+void RasterizerStorageGLES3::render_target_clear_used(RID p_render_target) {
+
+ RenderTarget *rt = render_target_owner.getornull(p_render_target);
+ ERR_FAIL_COND(!rt);
+
+ rt->used_in_frame = false;
}
void RasterizerStorageGLES3::render_target_set_msaa(RID p_render_target, VS::ViewportMSAA p_msaa) {
@@ -5986,6 +6146,7 @@ RID RasterizerStorageGLES3::canvas_light_occluder_create() {
co->index_id = 0;
co->vertex_id = 0;
co->len = 0;
+ glGenVertexArrays(1, &co->array_id);
return canvas_occluder_owner.make_rid(co);
}
@@ -6057,7 +6218,7 @@ void RasterizerStorageGLES3::canvas_light_occluder_set_polylines(RID p_occluder,
if (!co->vertex_id) {
glGenBuffers(1, &co->vertex_id);
glBindBuffer(GL_ARRAY_BUFFER, co->vertex_id);
- glBufferData(GL_ARRAY_BUFFER, lc * 6 * sizeof(real_t), vw.ptr(), GL_STATIC_DRAW);
+ glBufferData(GL_ARRAY_BUFFER, lc * 6 * sizeof(real_t), vw.ptr(), GL_DYNAMIC_DRAW);
} else {
glBindBuffer(GL_ARRAY_BUFFER, co->vertex_id);
@@ -6070,7 +6231,7 @@ void RasterizerStorageGLES3::canvas_light_occluder_set_polylines(RID p_occluder,
glGenBuffers(1, &co->index_id);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, co->index_id);
- glBufferData(GL_ELEMENT_ARRAY_BUFFER, lc * 3 * sizeof(uint16_t), iw.ptr(), GL_STATIC_DRAW);
+ glBufferData(GL_ELEMENT_ARRAY_BUFFER, lc * 3 * sizeof(uint16_t), iw.ptr(), GL_DYNAMIC_DRAW);
} else {
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, co->index_id);
@@ -6080,6 +6241,12 @@ void RasterizerStorageGLES3::canvas_light_occluder_set_polylines(RID p_occluder,
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); //unbind
co->len = lc;
+ glBindVertexArray(co->array_id);
+ glBindBuffer(GL_ARRAY_BUFFER, co->vertex_id);
+ glEnableVertexAttribArray(VS::ARRAY_VERTEX);
+ glVertexAttribPointer(VS::ARRAY_VERTEX, 3, GL_FLOAT, false, 0, 0);
+ glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, co->index_id);
+ glBindVertexArray(0);
}
}
@@ -6308,6 +6475,8 @@ bool RasterizerStorageGLES3::free(RID p_rid) {
if (co->vertex_id)
glDeleteBuffers(1, &co->vertex_id);
+ glDeleteVertexArrays(1, &co->array_id);
+
canvas_occluder_owner.free(p_rid);
memdelete(co);
@@ -6345,6 +6514,97 @@ bool RasterizerStorageGLES3::has_os_feature(const String &p_feature) const {
////////////////////////////////////////////
+void RasterizerStorageGLES3::set_debug_generate_wireframes(bool p_generate) {
+
+ config.generate_wireframes = p_generate;
+}
+
+void RasterizerStorageGLES3::render_info_begin_capture() {
+
+ info.snap = info.render;
+}
+
+void RasterizerStorageGLES3::render_info_end_capture() {
+
+ info.snap.object_count = info.render.object_count - info.snap.object_count;
+ info.snap.draw_call_count = info.render.draw_call_count - info.snap.draw_call_count;
+ info.snap.material_switch_count = info.render.material_switch_count - info.snap.material_switch_count;
+ info.snap.surface_switch_count = info.render.surface_switch_count - info.snap.surface_switch_count;
+ info.snap.shader_rebind_count = info.render.shader_rebind_count - info.snap.shader_rebind_count;
+ info.snap.vertices_count = info.render.vertices_count - info.snap.vertices_count;
+}
+
+int RasterizerStorageGLES3::get_captured_render_info(VS::RenderInfo p_info) {
+
+ switch (p_info) {
+ case VS::INFO_OBJECTS_IN_FRAME: {
+
+ return info.snap.object_count;
+ } break;
+ case VS::INFO_VERTICES_IN_FRAME: {
+
+ return info.snap.vertices_count;
+ } break;
+ case VS::INFO_MATERIAL_CHANGES_IN_FRAME: {
+ return info.snap.material_switch_count;
+ } break;
+ case VS::INFO_SHADER_CHANGES_IN_FRAME: {
+ return info.snap.shader_rebind_count;
+ } break;
+ case VS::INFO_SURFACE_CHANGES_IN_FRAME: {
+ return info.snap.surface_switch_count;
+ } break;
+ case VS::INFO_DRAW_CALLS_IN_FRAME: {
+ return info.snap.draw_call_count;
+ } break;
+ default: {
+ return get_render_info(p_info);
+ }
+ }
+}
+
+int RasterizerStorageGLES3::get_render_info(VS::RenderInfo p_info) {
+
+ switch (p_info) {
+ case VS::INFO_OBJECTS_IN_FRAME: {
+
+ return info.render_final.object_count;
+ } break;
+ case VS::INFO_VERTICES_IN_FRAME: {
+
+ return info.render_final.vertices_count;
+ } break;
+ case VS::INFO_MATERIAL_CHANGES_IN_FRAME: {
+ return info.render_final.material_switch_count;
+ } break;
+ case VS::INFO_SHADER_CHANGES_IN_FRAME: {
+ return info.render_final.shader_rebind_count;
+ } break;
+ case VS::INFO_SURFACE_CHANGES_IN_FRAME: {
+ return info.render_final.surface_switch_count;
+ } break;
+ case VS::INFO_DRAW_CALLS_IN_FRAME: {
+ return info.render_final.draw_call_count;
+ } break;
+ case VS::INFO_USAGE_VIDEO_MEM_TOTAL: {
+
+ return 0; //no idea
+ } break;
+ case VS::INFO_VIDEO_MEM_USED: {
+
+ return info.vertex_mem + info.texture_mem;
+ } break;
+ case VS::INFO_TEXTURE_MEM_USED: {
+
+ return info.texture_mem;
+ } break;
+ case VS::INFO_VERTEX_MEM_USED: {
+
+ return info.vertex_mem;
+ } break;
+ }
+}
+
void RasterizerStorageGLES3::initialize() {
RasterizerStorageGLES3::system_fbo = 0;
@@ -6526,6 +6786,7 @@ void RasterizerStorageGLES3::initialize() {
frame.delta = 0;
frame.current_rt = NULL;
config.keep_original_textures = false;
+ config.generate_wireframes = false;
}
void RasterizerStorageGLES3::finalize() {