diff options
Diffstat (limited to 'drivers/gles3/rasterizer_storage_gles3.cpp')
-rw-r--r-- | drivers/gles3/rasterizer_storage_gles3.cpp | 287 |
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() { |