summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--drivers/gles3/rasterizer_scene_gles3.cpp243
-rw-r--r--drivers/gles3/rasterizer_scene_gles3.h9
-rw-r--r--drivers/gles3/rasterizer_storage_gles3.cpp118
-rw-r--r--drivers/gles3/rasterizer_storage_gles3.h14
-rw-r--r--editor/editor_node.cpp1
-rw-r--r--editor/plugins/spatial_editor_plugin.cpp108
-rw-r--r--editor/plugins/spatial_editor_plugin.h9
-rw-r--r--scene/main/viewport.cpp36
-rw-r--r--scene/main/viewport.h27
-rw-r--r--servers/visual/rasterizer.h3
-rw-r--r--servers/visual/visual_server_raster.cpp5
-rw-r--r--servers/visual/visual_server_raster.h6
-rw-r--r--servers/visual/visual_server_viewport.cpp21
-rw-r--r--servers/visual/visual_server_viewport.h10
-rw-r--r--servers/visual/visual_server_wrap_mt.h5
-rw-r--r--servers/visual_server.h24
16 files changed, 437 insertions, 202 deletions
diff --git a/drivers/gles3/rasterizer_scene_gles3.cpp b/drivers/gles3/rasterizer_scene_gles3.cpp
index 7152b49d27..8d8c5e556b 100644
--- a/drivers/gles3/rasterizer_scene_gles3.cpp
+++ b/drivers/gles3/rasterizer_scene_gles3.cpp
@@ -1290,8 +1290,11 @@ void RasterizerSceneGLES3::_setup_geometry(RenderList::Element *e, const Transfo
storage->mesh_render_blend_shapes(s, e->instance->blend_values.ptr());
//rebind shader
state.scene_shader.bind();
+#ifdef DEBUG_ENABLED
+ } else if (state.debug_draw == VS::VIEWPORT_DEBUG_DRAW_WIREFRAME && s->array_wireframe_id) {
+ glBindVertexArray(s->array_wireframe_id); // everything is so easy nowadays
+#endif
} else {
-
glBindVertexArray(s->array_id); // everything is so easy nowadays
}
@@ -1301,7 +1304,16 @@ void RasterizerSceneGLES3::_setup_geometry(RenderList::Element *e, const Transfo
RasterizerStorageGLES3::MultiMesh *multi_mesh = static_cast<RasterizerStorageGLES3::MultiMesh *>(e->owner);
RasterizerStorageGLES3::Surface *s = static_cast<RasterizerStorageGLES3::Surface *>(e->geometry);
- glBindVertexArray(s->instancing_array_id); // use the instancing array ID
+#ifdef DEBUG_ENABLED
+ if (state.debug_draw == VS::VIEWPORT_DEBUG_DRAW_WIREFRAME && s->instancing_array_wireframe_id) {
+
+ glBindVertexArray(s->instancing_array_wireframe_id); // use the instancing array ID
+ } else
+#endif
+ {
+ glBindVertexArray(s->instancing_array_id); // use the instancing array ID
+ }
+
glBindBuffer(GL_ARRAY_BUFFER, multi_mesh->buffer); //modify the buffer
int stride = (multi_mesh->xform_floats + multi_mesh->color_floats) * 4;
@@ -1366,13 +1378,26 @@ void RasterizerSceneGLES3::_setup_geometry(RenderList::Element *e, const Transfo
sorter.sort(particle_array, particles->amount);
glUnmapBuffer(GL_ARRAY_BUFFER);
+#ifdef DEBUG_ENABLED
+ if (state.debug_draw == VS::VIEWPORT_DEBUG_DRAW_WIREFRAME && s->instancing_array_wireframe_id) {
+ glBindVertexArray(s->instancing_array_wireframe_id); // use the wireframe instancing array ID
+ } else
+#endif
+ {
- glBindVertexArray(s->instancing_array_id); // use the instancing array ID
+ glBindVertexArray(s->instancing_array_id); // use the instancing array ID
+ }
glBindBuffer(GL_ARRAY_BUFFER, particles->particle_buffer_histories[1]); //modify the buffer
} else {
-
- glBindVertexArray(s->instancing_array_id); // use the instancing array ID
+#ifdef DEBUG_ENABLED
+ if (state.debug_draw == VS::VIEWPORT_DEBUG_DRAW_WIREFRAME && s->instancing_array_wireframe_id) {
+ glBindVertexArray(s->instancing_array_wireframe_id); // use the wireframe instancing array ID
+ } else
+#endif
+ {
+ glBindVertexArray(s->instancing_array_id); // use the instancing array ID
+ }
glBindBuffer(GL_ARRAY_BUFFER, particles->particle_buffers[0]); //modify the buffer
}
@@ -1421,7 +1446,15 @@ void RasterizerSceneGLES3::_render_geometry(RenderList::Element *e) {
RasterizerStorageGLES3::Surface *s = static_cast<RasterizerStorageGLES3::Surface *>(e->geometry);
- if (s->index_array_len > 0) {
+#ifdef DEBUG_ENABLED
+
+ if (state.debug_draw == VS::VIEWPORT_DEBUG_DRAW_WIREFRAME && s->array_wireframe_id) {
+
+ glDrawElements(GL_LINES, s->index_wireframe_len, GL_UNSIGNED_INT, 0);
+ storage->info.render_vertices_count += s->index_array_len;
+ } else
+#endif
+ if (s->index_array_len > 0) {
glDrawElements(gl_primitive[s->primitive], s->index_array_len, (s->array_len >= (1 << 16)) ? GL_UNSIGNED_INT : GL_UNSIGNED_SHORT, 0);
@@ -1442,7 +1475,15 @@ void RasterizerSceneGLES3::_render_geometry(RenderList::Element *e) {
int amount = MAX(multi_mesh->size, multi_mesh->visible_instances);
- if (s->index_array_len > 0) {
+#ifdef DEBUG_ENABLED
+
+ if (state.debug_draw == VS::VIEWPORT_DEBUG_DRAW_WIREFRAME && s->array_wireframe_id) {
+
+ glDrawElementsInstanced(GL_LINES, s->index_wireframe_len, GL_UNSIGNED_INT, 0, amount);
+ storage->info.render_vertices_count += s->index_array_len * amount;
+ } else
+#endif
+ if (s->index_array_len > 0) {
glDrawElementsInstanced(gl_primitive[s->primitive], s->index_array_len, (s->array_len >= (1 << 16)) ? GL_UNSIGNED_INT : GL_UNSIGNED_SHORT, 0, amount);
@@ -1600,8 +1641,15 @@ void RasterizerSceneGLES3::_render_geometry(RenderList::Element *e) {
glEnableVertexAttribArray(12); //custom
glVertexAttribPointer(12, 4, GL_FLOAT, GL_FALSE, stride, ((uint8_t *)NULL) + stride * split + sizeof(float) * 4 * 2);
glVertexAttribDivisor(12, 1);
+#ifdef DEBUG_ENABLED
- if (s->index_array_len > 0) {
+ if (state.debug_draw == VS::VIEWPORT_DEBUG_DRAW_WIREFRAME && s->array_wireframe_id) {
+
+ glDrawElementsInstanced(GL_LINES, s->index_wireframe_len, GL_UNSIGNED_INT, 0, amount - split);
+ storage->info.render_vertices_count += s->index_array_len * (amount - split);
+ } else
+#endif
+ if (s->index_array_len > 0) {
glDrawElementsInstanced(gl_primitive[s->primitive], s->index_array_len, (s->array_len >= (1 << 16)) ? GL_UNSIGNED_INT : GL_UNSIGNED_SHORT, 0, amount - split);
@@ -1631,8 +1679,15 @@ void RasterizerSceneGLES3::_render_geometry(RenderList::Element *e) {
glEnableVertexAttribArray(12); //custom
glVertexAttribPointer(12, 4, GL_FLOAT, GL_FALSE, stride, ((uint8_t *)NULL) + sizeof(float) * 4 * 2);
glVertexAttribDivisor(12, 1);
+#ifdef DEBUG_ENABLED
- if (s->index_array_len > 0) {
+ if (state.debug_draw == VS::VIEWPORT_DEBUG_DRAW_WIREFRAME && s->array_wireframe_id) {
+
+ glDrawElementsInstanced(GL_LINES, s->index_wireframe_len, GL_UNSIGNED_INT, 0, split);
+ storage->info.render_vertices_count += s->index_array_len * split;
+ } else
+#endif
+ if (s->index_array_len > 0) {
glDrawElementsInstanced(gl_primitive[s->primitive], s->index_array_len, (s->array_len >= (1 << 16)) ? GL_UNSIGNED_INT : GL_UNSIGNED_SHORT, 0, split);
@@ -1648,7 +1703,15 @@ void RasterizerSceneGLES3::_render_geometry(RenderList::Element *e) {
} else {
- if (s->index_array_len > 0) {
+#ifdef DEBUG_ENABLED
+
+ if (state.debug_draw == VS::VIEWPORT_DEBUG_DRAW_WIREFRAME && s->array_wireframe_id) {
+
+ glDrawElementsInstanced(GL_LINES, s->index_wireframe_len, GL_UNSIGNED_INT, 0, amount);
+ storage->info.render_vertices_count += s->index_array_len * amount;
+ } else
+#endif
+ if (s->index_array_len > 0) {
glDrawElementsInstanced(gl_primitive[s->primitive], s->index_array_len, (s->array_len >= (1 << 16)) ? GL_UNSIGNED_INT : GL_UNSIGNED_SHORT, 0, amount);
@@ -2034,6 +2097,10 @@ void RasterizerSceneGLES3::_add_geometry(RasterizerStorageGLES3::Geometry *p_geo
RasterizerStorageGLES3::Material *m = NULL;
RID m_src = p_instance->material_override.is_valid() ? p_instance->material_override : (p_material >= 0 ? p_instance->materials[p_material] : p_geometry->material);
+ if (state.debug_draw == VS::VIEWPORT_DEBUG_DRAW_OVERDRAW) {
+ m_src = default_overdraw_material;
+ }
+
/*
#ifdef DEBUG_ENABLED
if (current_debug==VS::SCENARIO_DEBUG_OVERDRAW) {
@@ -2152,7 +2219,7 @@ void RasterizerSceneGLES3::_add_geometry(RasterizerStorageGLES3::Geometry *p_geo
//e->light_type=0xFF; // no lights!
- if (shadow || m->shader->spatial.unshaded /*|| current_debug==VS::SCENARIO_DEBUG_SHADELESS*/) {
+ if (shadow || m->shader->spatial.unshaded || state.debug_draw == VS::VIEWPORT_DEBUG_DRAW_UNSHADED) {
e->sort_key |= RenderList::SORT_KEY_UNSHADED_FLAG;
}
@@ -3789,7 +3856,7 @@ void RasterizerSceneGLES3::render_scene(const Transform &p_cam_transform, const
state.used_contact_shadows = true;
- if (storage->frame.current_rt && true) { //detect with state.used_contact_shadows too
+ if (storage->frame.current_rt && state.debug_draw != VS::VIEWPORT_DEBUG_DRAW_OVERDRAW) { //detect with state.used_contact_shadows too
//pre z pass
glDisable(GL_BLEND);
@@ -3880,6 +3947,7 @@ void RasterizerSceneGLES3::render_scene(const Transform &p_cam_transform, const
//effects disabled and transparency also prevent using MRTs
use_mrt = use_mrt && !storage->frame.current_rt->flags[RasterizerStorage::RENDER_TARGET_TRANSPARENT];
use_mrt = use_mrt && !storage->frame.current_rt->flags[RasterizerStorage::RENDER_TARGET_NO_3D_EFFECTS];
+ use_mrt = use_mrt && state.debug_draw != VS::VIEWPORT_DEBUG_DRAW_OVERDRAW;
glViewport(0, 0, storage->frame.current_rt->width, storage->frame.current_rt->height);
@@ -3928,7 +3996,10 @@ void RasterizerSceneGLES3::render_scene(const Transform &p_cam_transform, const
RasterizerStorageGLES3::Sky *sky = NULL;
GLuint env_radiance_tex = 0;
- if (storage->frame.current_rt->flags[RasterizerStorage::RENDER_TARGET_TRANSPARENT]) {
+ if (state.debug_draw == VS::VIEWPORT_DEBUG_DRAW_OVERDRAW) {
+ clear_color = Color(0, 0, 0, 0);
+ storage->frame.clear_request = false;
+ } else if (storage->frame.current_rt->flags[RasterizerStorage::RENDER_TARGET_TRANSPARENT]) {
clear_color = Color(0, 0, 0, 0);
} else if (!env || env->bg_mode == VS::ENV_BG_CLEAR_COLOR) {
@@ -3992,7 +4063,7 @@ void RasterizerSceneGLES3::render_scene(const Transform &p_cam_transform, const
glDrawBuffers(1, &gldb);
}
- if (env && env->bg_mode == VS::ENV_BG_SKY && !storage->frame.current_rt->flags[RasterizerStorage::RENDER_TARGET_TRANSPARENT]) {
+ if (env && env->bg_mode == VS::ENV_BG_SKY && !storage->frame.current_rt->flags[RasterizerStorage::RENDER_TARGET_TRANSPARENT] && state.debug_draw != VS::VIEWPORT_DEBUG_DRAW_OVERDRAW) {
/*
if (use_mrt) {
@@ -4554,136 +4625,39 @@ bool RasterizerSceneGLES3::free(RID p_rid) {
return true;
}
-// http://holger.dammertz.org/stuff/notes_HammersleyOnHemisphere.html
-static _FORCE_INLINE_ float radicalInverse_VdC(uint32_t bits) {
- bits = (bits << 16u) | (bits >> 16u);
- bits = ((bits & 0x55555555u) << 1u) | ((bits & 0xAAAAAAAAu) >> 1u);
- bits = ((bits & 0x33333333u) << 2u) | ((bits & 0xCCCCCCCCu) >> 2u);
- bits = ((bits & 0x0F0F0F0Fu) << 4u) | ((bits & 0xF0F0F0F0u) >> 4u);
- bits = ((bits & 0x00FF00FFu) << 8u) | ((bits & 0xFF00FF00u) >> 8u);
- return float(bits) * 2.3283064365386963e-10f; // / 0x100000000
-}
-
-static _FORCE_INLINE_ Vector2 Hammersley(uint32_t i, uint32_t N) {
- return Vector2(float(i) / float(N), radicalInverse_VdC(i));
-}
-
-static _FORCE_INLINE_ Vector3 ImportanceSampleGGX(Vector2 Xi, float Roughness, Vector3 N) {
- float a = Roughness * Roughness; // DISNEY'S ROUGHNESS [see Burley'12 siggraph]
-
- // Compute distribution direction
- float Phi = 2.0f * Math_PI * Xi.x;
- float CosTheta = Math::sqrt((float)(1.0f - Xi.y) / (1.0f + (a * a - 1.0f) * Xi.y));
- float SinTheta = Math::sqrt((float)Math::abs(1.0f - CosTheta * CosTheta));
-
- // Convert to spherical direction
- Vector3 H;
- H.x = SinTheta * Math::cos(Phi);
- H.y = SinTheta * Math::sin(Phi);
- H.z = CosTheta;
-
- Vector3 UpVector = Math::abs(N.z) < 0.999 ? Vector3(0.0, 0.0, 1.0) : Vector3(1.0, 0.0, 0.0);
- Vector3 TangentX = UpVector.cross(N);
- TangentX.normalize();
- Vector3 TangentY = N.cross(TangentX);
-
- // Tangent to world space
- return TangentX * H.x + TangentY * H.y + N * H.z;
-}
+void RasterizerSceneGLES3::set_debug_draw_mode(VS::ViewportDebugDraw p_debug_draw) {
-static _FORCE_INLINE_ float GGX(float NdotV, float a) {
- float k = a / 2.0;
- return NdotV / (NdotV * (1.0 - k) + k);
+ state.debug_draw = p_debug_draw;
}
-// http://graphicrants.blogspot.com.au/2013/08/specular-brdf-reference.html
-float _FORCE_INLINE_ G_Smith(float a, float nDotV, float nDotL) {
- return GGX(nDotL, a * a) * GGX(nDotV, a * a);
-}
-
-void RasterizerSceneGLES3::_generate_brdf() {
-
- int brdf_size = GLOBAL_DEF("rendering/gles3/brdf_texture_size", 64);
-
- PoolVector<uint8_t> brdf;
- brdf.resize(brdf_size * brdf_size * 2);
-
- PoolVector<uint8_t>::Write w = brdf.write();
-
- for (int i = 0; i < brdf_size; i++) {
- for (int j = 0; j < brdf_size; j++) {
-
- float Roughness = float(j) / (brdf_size - 1);
- float NoV = float(i + 1) / (brdf_size); //avoid storing nov0
-
- Vector3 V;
- V.x = Math::sqrt(1.0f - NoV * NoV);
- V.y = 0.0;
- V.z = NoV;
-
- Vector3 N = Vector3(0.0, 0.0, 1.0);
-
- float A = 0;
- float B = 0;
-
- for (int s = 0; s < 512; s++) {
-
- Vector2 xi = Hammersley(s, 512);
- Vector3 H = ImportanceSampleGGX(xi, Roughness, N);
- Vector3 L = 2.0 * V.dot(H) * H - V;
+void RasterizerSceneGLES3::initialize() {
- float NoL = CLAMP(L.z, 0.0, 1.0);
- float NoH = CLAMP(H.z, 0.0, 1.0);
- float VoH = CLAMP(V.dot(H), 0.0, 1.0);
+ render_pass = 0;
- if (NoL > 0.0) {
- float G = G_Smith(Roughness, NoV, NoL);
- float G_Vis = G * VoH / (NoH * NoV);
- float Fc = pow(1.0 - VoH, 5.0);
+ state.scene_shader.init();
- A += (1.0 - Fc) * G_Vis;
- B += Fc * G_Vis;
- }
- }
+ {
+ //default material and shader
- A /= 512.0;
- B /= 512.0;
+ default_shader = storage->shader_create();
+ storage->shader_set_code(default_shader, "shader_type spatial;\n");
+ default_material = storage->material_create();
+ storage->material_set_shader(default_material, default_shader);
- int tofs = ((brdf_size - j - 1) * brdf_size + i) * 2;
- w[tofs + 0] = CLAMP(A * 255, 0, 255);
- w[tofs + 1] = CLAMP(B * 255, 0, 255);
- }
+ default_shader_twosided = storage->shader_create();
+ default_material_twosided = storage->material_create();
+ storage->shader_set_code(default_shader_twosided, "shader_type spatial; render_mode cull_disabled;\n");
+ storage->material_set_shader(default_material_twosided, default_shader_twosided);
}
- //set up brdf texture
-
- glGenTextures(1, &state.brdf_texture);
-
- glActiveTexture(GL_TEXTURE0);
- glBindTexture(GL_TEXTURE_2D, state.brdf_texture);
- glTexImage2D(GL_TEXTURE_2D, 0, GL_RG8, brdf_size, brdf_size, 0, GL_RG, GL_UNSIGNED_BYTE, w.ptr());
- glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
- glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
- glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
- glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
- glBindTexture(GL_TEXTURE_2D, 0);
-}
-
-void RasterizerSceneGLES3::initialize() {
-
- render_pass = 0;
-
- state.scene_shader.init();
-
- default_shader = storage->shader_create();
- storage->shader_set_code(default_shader, "shader_type spatial;\n");
- default_material = storage->material_create();
- storage->material_set_shader(default_material, default_shader);
+ {
+ //default material and shader
- default_shader_twosided = storage->shader_create();
- default_material_twosided = storage->material_create();
- storage->shader_set_code(default_shader_twosided, "shader_type spatial; render_mode cull_disabled;\n");
- storage->material_set_shader(default_material_twosided, default_shader_twosided);
+ default_overdraw_shader = storage->shader_create();
+ storage->shader_set_code(default_overdraw_shader, "shader_type spatial;\nrender_mode blend_add,unshaded;\n void fragment() { ALBEDO=vec3(0.4,0.8,0.8); ALPHA=0.2; }");
+ default_overdraw_material = storage->material_create();
+ storage->material_set_shader(default_overdraw_material, default_overdraw_shader);
+ }
glGenBuffers(1, &state.scene_ubo);
glBindBuffer(GL_UNIFORM_BUFFER, state.scene_ubo);
@@ -4721,7 +4695,6 @@ void RasterizerSceneGLES3::initialize() {
}
render_list.init();
state.cube_to_dp_shader.init();
- _generate_brdf();
shadow_atlas_realloc_tolerance_msec = 500;
@@ -4968,6 +4941,8 @@ void RasterizerSceneGLES3::initialize() {
GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
ERR_CONTINUE(status != GL_FRAMEBUFFER_COMPLETE);
}
+
+ state.debug_draw = VS::VIEWPORT_DEBUG_DRAW_DISABLED;
}
void RasterizerSceneGLES3::iteration() {
diff --git a/drivers/gles3/rasterizer_scene_gles3.h b/drivers/gles3/rasterizer_scene_gles3.h
index 55d314a800..59b8e3fb35 100644
--- a/drivers/gles3/rasterizer_scene_gles3.h
+++ b/drivers/gles3/rasterizer_scene_gles3.h
@@ -77,6 +77,9 @@ public:
RID default_shader;
RID default_shader_twosided;
+ RID default_overdraw_material;
+ RID default_overdraw_shader;
+
RasterizerStorageGLES3 *storage;
Vector<RasterizerStorageGLES3::RenderTarget::Exposure> exposure_shrink;
@@ -152,8 +155,6 @@ public:
GLuint env_radiance_ubo;
- GLuint brdf_texture;
-
GLuint sky_verts;
GLuint sky_array;
@@ -187,6 +188,7 @@ public:
bool used_sss;
bool used_screen_texture;
+ VS::ViewportDebugDraw debug_draw;
} state;
/* SHADOW ATLAS API */
@@ -783,9 +785,8 @@ public:
virtual void render_shadow(RID p_light, RID p_shadow_atlas, int p_pass, InstanceBase **p_cull_result, int p_cull_count);
virtual bool free(RID p_rid);
- void _generate_brdf();
-
virtual void set_scene_pass(uint64_t p_pass);
+ virtual void set_debug_draw_mode(VS::ViewportDebugDraw p_debug_draw);
void iteration();
void initialize();
diff --git a/drivers/gles3/rasterizer_storage_gles3.cpp b/drivers/gles3/rasterizer_storage_gles3.cpp
index 1801260146..1250e55748 100644
--- a/drivers/gles3/rasterizer_storage_gles3.cpp
+++ b/drivers/gles3/rasterizer_storage_gles3.cpp
@@ -2727,6 +2727,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
}
{
@@ -2998,6 +3104,12 @@ 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);
+ }
+
mesh->instance_material_change_notify();
memdelete(surface);
@@ -6345,6 +6457,11 @@ 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::initialize() {
RasterizerStorageGLES3::system_fbo = 0;
@@ -6526,6 +6643,7 @@ void RasterizerStorageGLES3::initialize() {
frame.delta = 0;
frame.current_rt = NULL;
config.keep_original_textures = false;
+ config.generate_wireframes = false;
}
void RasterizerStorageGLES3::finalize() {
diff --git a/drivers/gles3/rasterizer_storage_gles3.h b/drivers/gles3/rasterizer_storage_gles3.h
index 9af342301c..d16fa99c2a 100644
--- a/drivers/gles3/rasterizer_storage_gles3.h
+++ b/drivers/gles3/rasterizer_storage_gles3.h
@@ -84,6 +84,8 @@ public:
int max_texture_image_units;
int max_texture_size;
+ bool generate_wireframes;
+
Set<String> extensions;
bool keep_original_textures;
@@ -537,6 +539,11 @@ public:
GLuint vertex_id;
GLuint index_id;
+ GLuint index_wireframe_id;
+ GLuint array_wireframe_id;
+ GLuint instancing_array_wireframe_id;
+ int index_wireframe_len;
+
Vector<Rect3> skeleton_bone_aabb;
Vector<bool> skeleton_bone_used;
@@ -581,6 +588,11 @@ public:
primitive = VS::PRIMITIVE_POINTS;
index_array_len = 0;
active = false;
+
+ index_wireframe_id = 0;
+ array_wireframe_id = 0;
+ instancing_array_wireframe_id = 0;
+ index_wireframe_len = 0;
}
~Surface() {
@@ -1283,6 +1295,8 @@ public:
virtual void update_dirty_resources();
+ virtual void set_debug_generate_wireframes(bool p_generate);
+
RasterizerStorageGLES3();
};
diff --git a/editor/editor_node.cpp b/editor/editor_node.cpp
index 9d6c599a4e..8fa9cbdc1c 100644
--- a/editor/editor_node.cpp
+++ b/editor/editor_node.cpp
@@ -4878,6 +4878,7 @@ EditorNode::EditorNode() {
Resource::_get_local_scene_func = _resource_get_edited_scene;
VisualServer::get_singleton()->textures_keep_original(true);
+ VisualServer::get_singleton()->set_debug_generate_wireframes(true);
EditorHelp::generate_doc(); //before any editor classes are crated
SceneState::set_disable_placeholders(true);
diff --git a/editor/plugins/spatial_editor_plugin.cpp b/editor/plugins/spatial_editor_plugin.cpp
index 2648b45e9c..e7d7ba05d8 100644
--- a/editor/plugins/spatial_editor_plugin.cpp
+++ b/editor/plugins/spatial_editor_plugin.cpp
@@ -1997,6 +1997,45 @@ void SpatialEditorViewport::_menu_option(int p_option) {
view_menu->get_popup()->set_item_checked(idx, current);
} break;
+ case VIEW_DISPLAY_NORMAL: {
+
+ viewport->set_debug_draw(Viewport::DEBUG_DRAW_DISABLED);
+
+ view_menu->get_popup()->set_item_checked(view_menu->get_popup()->get_item_index(VIEW_DISPLAY_NORMAL), true);
+ view_menu->get_popup()->set_item_checked(view_menu->get_popup()->get_item_index(VIEW_DISPLAY_WIREFRAME), false);
+ view_menu->get_popup()->set_item_checked(view_menu->get_popup()->get_item_index(VIEW_DISPLAY_OVERDRAW), false);
+ view_menu->get_popup()->set_item_checked(view_menu->get_popup()->get_item_index(VIEW_DISPLAY_SHADELESS), false);
+
+ } break;
+ case VIEW_DISPLAY_WIREFRAME: {
+
+ viewport->set_debug_draw(Viewport::DEBUG_DRAW_WIREFRAME);
+ view_menu->get_popup()->set_item_checked(view_menu->get_popup()->get_item_index(VIEW_DISPLAY_NORMAL), false);
+ view_menu->get_popup()->set_item_checked(view_menu->get_popup()->get_item_index(VIEW_DISPLAY_WIREFRAME), true);
+ view_menu->get_popup()->set_item_checked(view_menu->get_popup()->get_item_index(VIEW_DISPLAY_OVERDRAW), false);
+ view_menu->get_popup()->set_item_checked(view_menu->get_popup()->get_item_index(VIEW_DISPLAY_SHADELESS), false);
+
+ } break;
+ case VIEW_DISPLAY_OVERDRAW: {
+
+ viewport->set_debug_draw(Viewport::DEBUG_DRAW_OVERDRAW);
+ VisualServer::get_singleton()->scenario_set_debug(get_tree()->get_root()->get_world()->get_scenario(), VisualServer::SCENARIO_DEBUG_OVERDRAW);
+ view_menu->get_popup()->set_item_checked(view_menu->get_popup()->get_item_index(VIEW_DISPLAY_NORMAL), false);
+ view_menu->get_popup()->set_item_checked(view_menu->get_popup()->get_item_index(VIEW_DISPLAY_WIREFRAME), false);
+ view_menu->get_popup()->set_item_checked(view_menu->get_popup()->get_item_index(VIEW_DISPLAY_OVERDRAW), true);
+ view_menu->get_popup()->set_item_checked(view_menu->get_popup()->get_item_index(VIEW_DISPLAY_SHADELESS), false);
+
+ } break;
+ case VIEW_DISPLAY_SHADELESS: {
+
+ viewport->set_debug_draw(Viewport::DEBUG_DRAW_UNSHADED);
+ VisualServer::get_singleton()->scenario_set_debug(get_tree()->get_root()->get_world()->get_scenario(), VisualServer::SCENARIO_DEBUG_SHADELESS);
+ view_menu->get_popup()->set_item_checked(view_menu->get_popup()->get_item_index(VIEW_DISPLAY_NORMAL), false);
+ view_menu->get_popup()->set_item_checked(view_menu->get_popup()->get_item_index(VIEW_DISPLAY_WIREFRAME), false);
+ view_menu->get_popup()->set_item_checked(view_menu->get_popup()->get_item_index(VIEW_DISPLAY_OVERDRAW), false);
+ view_menu->get_popup()->set_item_checked(view_menu->get_popup()->get_item_index(VIEW_DISPLAY_SHADELESS), true);
+
+ } break;
}
}
@@ -2296,12 +2335,18 @@ SpatialEditorViewport::SpatialEditorViewport(SpatialEditor *p_spatial_editor, Ed
view_menu->get_popup()->add_check_item(TTR("Orthogonal") + " (" + ED_GET_SHORTCUT("spatial_editor/switch_perspective_orthogonal")->get_as_text() + ")", VIEW_ORTHOGONAL);
view_menu->get_popup()->set_item_checked(view_menu->get_popup()->get_item_index(VIEW_PERSPECTIVE), true);
view_menu->get_popup()->add_separator();
- view_menu->get_popup()->add_check_shortcut(ED_SHORTCUT("spatial_editor/view_environment", TTR("Environment")), VIEW_ENVIRONMENT);
+ view_menu->get_popup()->add_check_shortcut(ED_SHORTCUT("spatial_editor/view_display_normal", TTR("Display Normal")), VIEW_DISPLAY_NORMAL);
+ view_menu->get_popup()->add_check_shortcut(ED_SHORTCUT("spatial_editor/view_display_wireframe", TTR("Display Wireframe")), VIEW_DISPLAY_WIREFRAME);
+ view_menu->get_popup()->add_check_shortcut(ED_SHORTCUT("spatial_editor/view_display_overdraw", TTR("Display Overdraw")), VIEW_DISPLAY_OVERDRAW);
+ view_menu->get_popup()->add_check_shortcut(ED_SHORTCUT("spatial_editor/view_display_unshaded", TTR("Display Unshaded")), VIEW_DISPLAY_SHADELESS);
+ view_menu->get_popup()->set_item_checked(view_menu->get_popup()->get_item_index(VIEW_DISPLAY_NORMAL), true);
+ view_menu->get_popup()->add_separator();
+ view_menu->get_popup()->add_check_shortcut(ED_SHORTCUT("spatial_editor/view_environment", TTR("View Environment")), VIEW_ENVIRONMENT);
+ view_menu->get_popup()->add_check_shortcut(ED_SHORTCUT("spatial_editor/view_gizmos", TTR("View Gizmos")), VIEW_GIZMOS);
+ view_menu->get_popup()->add_check_shortcut(ED_SHORTCUT("spatial_editor/view_information", TTR("View Information")), VIEW_INFORMATION);
view_menu->get_popup()->set_item_checked(view_menu->get_popup()->get_item_index(VIEW_ENVIRONMENT), true);
view_menu->get_popup()->add_separator();
view_menu->get_popup()->add_check_shortcut(ED_SHORTCUT("spatial_editor/view_audio_listener", TTR("Audio Listener")), VIEW_AUDIO_LISTENER);
- view_menu->get_popup()->add_separator();
- view_menu->get_popup()->add_check_shortcut(ED_SHORTCUT("spatial_editor/view_gizmos", TTR("Gizmos")), VIEW_GIZMOS);
view_menu->get_popup()->set_item_checked(view_menu->get_popup()->get_item_index(VIEW_GIZMOS), true);
view_menu->get_popup()->add_separator();
@@ -3088,43 +3133,6 @@ void SpatialEditor::_menu_item_pressed(int p_option) {
view_menu->get_popup()->set_item_checked(view_menu->get_popup()->get_item_index(MENU_VIEW_USE_3_VIEWPORTS_ALT), false);
} break;
- case MENU_VIEW_DISPLAY_NORMAL: {
-
- VisualServer::get_singleton()->scenario_set_debug(get_tree()->get_root()->get_world()->get_scenario(), VisualServer::SCENARIO_DEBUG_DISABLED);
-
- view_menu->get_popup()->set_item_checked(view_menu->get_popup()->get_item_index(MENU_VIEW_DISPLAY_NORMAL), true);
- view_menu->get_popup()->set_item_checked(view_menu->get_popup()->get_item_index(MENU_VIEW_DISPLAY_WIREFRAME), false);
- view_menu->get_popup()->set_item_checked(view_menu->get_popup()->get_item_index(MENU_VIEW_DISPLAY_OVERDRAW), false);
- view_menu->get_popup()->set_item_checked(view_menu->get_popup()->get_item_index(MENU_VIEW_DISPLAY_SHADELESS), false);
-
- } break;
- case MENU_VIEW_DISPLAY_WIREFRAME: {
-
- VisualServer::get_singleton()->scenario_set_debug(get_tree()->get_root()->get_world()->get_scenario(), VisualServer::SCENARIO_DEBUG_WIREFRAME);
- view_menu->get_popup()->set_item_checked(view_menu->get_popup()->get_item_index(MENU_VIEW_DISPLAY_NORMAL), false);
- view_menu->get_popup()->set_item_checked(view_menu->get_popup()->get_item_index(MENU_VIEW_DISPLAY_WIREFRAME), true);
- view_menu->get_popup()->set_item_checked(view_menu->get_popup()->get_item_index(MENU_VIEW_DISPLAY_OVERDRAW), false);
- view_menu->get_popup()->set_item_checked(view_menu->get_popup()->get_item_index(MENU_VIEW_DISPLAY_SHADELESS), false);
-
- } break;
- case MENU_VIEW_DISPLAY_OVERDRAW: {
-
- VisualServer::get_singleton()->scenario_set_debug(get_tree()->get_root()->get_world()->get_scenario(), VisualServer::SCENARIO_DEBUG_OVERDRAW);
- view_menu->get_popup()->set_item_checked(view_menu->get_popup()->get_item_index(MENU_VIEW_DISPLAY_NORMAL), false);
- view_menu->get_popup()->set_item_checked(view_menu->get_popup()->get_item_index(MENU_VIEW_DISPLAY_WIREFRAME), false);
- view_menu->get_popup()->set_item_checked(view_menu->get_popup()->get_item_index(MENU_VIEW_DISPLAY_OVERDRAW), true);
- view_menu->get_popup()->set_item_checked(view_menu->get_popup()->get_item_index(MENU_VIEW_DISPLAY_SHADELESS), false);
-
- } break;
- case MENU_VIEW_DISPLAY_SHADELESS: {
-
- VisualServer::get_singleton()->scenario_set_debug(get_tree()->get_root()->get_world()->get_scenario(), VisualServer::SCENARIO_DEBUG_SHADELESS);
- view_menu->get_popup()->set_item_checked(view_menu->get_popup()->get_item_index(MENU_VIEW_DISPLAY_NORMAL), false);
- view_menu->get_popup()->set_item_checked(view_menu->get_popup()->get_item_index(MENU_VIEW_DISPLAY_WIREFRAME), false);
- view_menu->get_popup()->set_item_checked(view_menu->get_popup()->get_item_index(MENU_VIEW_DISPLAY_OVERDRAW), false);
- view_menu->get_popup()->set_item_checked(view_menu->get_popup()->get_item_index(MENU_VIEW_DISPLAY_SHADELESS), true);
-
- } break;
case MENU_VIEW_ORIGIN: {
bool is_checked = view_menu->get_popup()->is_item_checked(view_menu->get_popup()->get_item_index(p_option));
@@ -3473,17 +3481,6 @@ void SpatialEditor::_unhandled_key_input(Ref<InputEvent> p_event) {
else if (ED_IS_SHORTCUT("spatial_editor/tool_scale", p_event))
_menu_item_pressed(MENU_TOOL_SCALE);
-
- else if (ED_IS_SHORTCUT("spatial_editor/display_wireframe", p_event)) {
- if (k->get_shift() || k->get_control() || k->get_command())
- return;
-
- if (view_menu->get_popup()->is_item_checked(view_menu->get_popup()->get_item_index(MENU_VIEW_DISPLAY_WIREFRAME))) {
- _menu_item_pressed(MENU_VIEW_DISPLAY_NORMAL);
- } else {
- _menu_item_pressed(MENU_VIEW_DISPLAY_WIREFRAME);
- }
- }
}
}
}
@@ -3650,9 +3647,6 @@ void SpatialEditor::clear() {
viewports[i]->reset();
}
- _menu_item_pressed(MENU_VIEW_USE_1_VIEWPORT);
- _menu_item_pressed(MENU_VIEW_DISPLAY_NORMAL);
-
VisualServer::get_singleton()->instance_set_visible(origin_instance, true);
view_menu->get_popup()->set_item_checked(view_menu->get_popup()->get_item_index(MENU_VIEW_ORIGIN), true);
for (int i = 0; i < 3; ++i) {
@@ -3797,17 +3791,11 @@ SpatialEditor::SpatialEditor(EditorNode *p_editor) {
p->add_check_shortcut(ED_SHORTCUT("spatial_editor/4_viewports", TTR("4 Viewports"), KEY_MASK_CMD + KEY_4), MENU_VIEW_USE_4_VIEWPORTS);
p->add_separator();
- p->add_check_shortcut(ED_SHORTCUT("spatial_editor/display_normal", TTR("Display Normal")), MENU_VIEW_DISPLAY_NORMAL);
- p->add_check_shortcut(ED_SHORTCUT("spatial_editor/display_wireframe", TTR("Display Wireframe")), MENU_VIEW_DISPLAY_WIREFRAME);
- p->add_check_shortcut(ED_SHORTCUT("spatial_editor/display_overdraw", TTR("Display Overdraw")), MENU_VIEW_DISPLAY_OVERDRAW);
- p->add_check_shortcut(ED_SHORTCUT("spatial_editor/display_shadeless", TTR("Display Shadeless")), MENU_VIEW_DISPLAY_SHADELESS);
- p->add_separator();
p->add_check_shortcut(ED_SHORTCUT("spatial_editor/view_origin", TTR("View Origin")), MENU_VIEW_ORIGIN);
p->add_check_shortcut(ED_SHORTCUT("spatial_editor/view_grid", TTR("View Grid")), MENU_VIEW_GRID);
p->add_separator();
p->add_shortcut(ED_SHORTCUT("spatial_editor/settings", TTR("Settings")), MENU_VIEW_CAMERA_SETTINGS);
- p->set_item_checked(p->get_item_index(MENU_VIEW_DISPLAY_NORMAL), true);
p->set_item_checked(p->get_item_index(MENU_VIEW_ORIGIN), true);
p->set_item_checked(p->get_item_index(MENU_VIEW_GRID), true);
diff --git a/editor/plugins/spatial_editor_plugin.h b/editor/plugins/spatial_editor_plugin.h
index d96e6090f0..4a770311ac 100644
--- a/editor/plugins/spatial_editor_plugin.h
+++ b/editor/plugins/spatial_editor_plugin.h
@@ -84,6 +84,11 @@ class SpatialEditorViewport : public Control {
VIEW_ORTHOGONAL,
VIEW_AUDIO_LISTENER,
VIEW_GIZMOS,
+ VIEW_INFORMATION,
+ VIEW_DISPLAY_NORMAL,
+ VIEW_DISPLAY_WIREFRAME,
+ VIEW_DISPLAY_OVERDRAW,
+ VIEW_DISPLAY_SHADELESS,
};
public:
@@ -416,10 +421,6 @@ private:
MENU_VIEW_USE_3_VIEWPORTS,
MENU_VIEW_USE_3_VIEWPORTS_ALT,
MENU_VIEW_USE_4_VIEWPORTS,
- MENU_VIEW_DISPLAY_NORMAL,
- MENU_VIEW_DISPLAY_WIREFRAME,
- MENU_VIEW_DISPLAY_OVERDRAW,
- MENU_VIEW_DISPLAY_SHADELESS,
MENU_VIEW_ORIGIN,
MENU_VIEW_GRID,
MENU_VIEW_CAMERA_SETTINGS,
diff --git a/scene/main/viewport.cpp b/scene/main/viewport.cpp
index 95fad83a28..763cac2af4 100644
--- a/scene/main/viewport.cpp
+++ b/scene/main/viewport.cpp
@@ -2530,6 +2530,22 @@ Viewport::Usage Viewport::get_usage() const {
return usage;
}
+void Viewport::set_debug_draw(DebugDraw p_debug_draw) {
+
+ debug_draw = p_debug_draw;
+ VS::get_singleton()->viewport_set_debug_draw(viewport, VS::ViewportDebugDraw(p_debug_draw));
+}
+
+Viewport::DebugDraw Viewport::get_debug_draw() const {
+
+ return debug_draw;
+}
+
+int Viewport::get_render_info(RenderInfo p_info) {
+
+ return VS::get_singleton()->viewport_get_render_info(viewport, VS::ViewportRenderInfo(p_info));
+}
+
void Viewport::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_size", "size"), &Viewport::set_size);
@@ -2586,6 +2602,11 @@ void Viewport::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_usage", "usage"), &Viewport::set_usage);
ClassDB::bind_method(D_METHOD("get_usage"), &Viewport::get_usage);
+ ClassDB::bind_method(D_METHOD("set_debug_draw", "debug_draw"), &Viewport::set_debug_draw);
+ ClassDB::bind_method(D_METHOD("get_debug_draw"), &Viewport::get_debug_draw);
+
+ ClassDB::bind_method(D_METHOD("get_render_info", "info"), &Viewport::get_render_info);
+
ClassDB::bind_method(D_METHOD("get_texture:ViewportTexture"), &Viewport::get_texture);
ClassDB::bind_method(D_METHOD("set_physics_object_picking", "enable"), &Viewport::set_physics_object_picking);
@@ -2640,6 +2661,7 @@ void Viewport::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "hdr"), "set_hdr", "get_hdr");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "disable_3d"), "set_disable_3d", "is_3d_disabled");
ADD_PROPERTY(PropertyInfo(Variant::INT, "usage", PROPERTY_HINT_ENUM, "2D,2D No-Sampling,3D,3D No-Effects"), "set_usage", "get_usage");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "debug_draw", PROPERTY_HINT_ENUM, "Disabled,Unshaded,Overdraw,Wireframe"), "set_debug_draw", "get_debug_draw");
ADD_GROUP("Render Target", "render_target_");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "render_target_v_flip"), "set_vflip", "get_vflip");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "render_target_clear_on_new_frame"), "set_clear_on_new_frame", "get_clear_on_new_frame");
@@ -2674,6 +2696,19 @@ void Viewport::_bind_methods() {
BIND_CONSTANT(SHADOW_ATLAS_QUADRANT_SUBDIV_1024);
BIND_CONSTANT(SHADOW_ATLAS_QUADRANT_SUBDIV_MAX);
+ BIND_CONSTANT(RENDER_INFO_OBJECTS_IN_FRAME);
+ BIND_CONSTANT(RENDER_INFO_VERTICES_IN_FRAME);
+ BIND_CONSTANT(RENDER_INFO_MATERIAL_CHANGES_IN_FRAME);
+ BIND_CONSTANT(RENDER_INFO_SHADER_CHANGES_IN_FRAME);
+ BIND_CONSTANT(RENDER_INFO_SURFACE_CHANGES_IN_FRAME);
+ BIND_CONSTANT(RENDER_INFO_DRAW_CALLS_IN_FRAME);
+ BIND_CONSTANT(RENDER_INFO_MAX);
+
+ BIND_CONSTANT(DEBUG_DRAW_DISABLED);
+ BIND_CONSTANT(DEBUG_DRAW_UNSHADED);
+ BIND_CONSTANT(DEBUG_DRAW_OVERDRAW);
+ BIND_CONSTANT(DEBUG_DRAW_WIREFRAME);
+
BIND_CONSTANT(MSAA_DISABLED);
BIND_CONSTANT(MSAA_2X);
BIND_CONSTANT(MSAA_4X);
@@ -2750,6 +2785,7 @@ Viewport::Viewport() {
hdr = false;
usage = USAGE_3D;
+ debug_draw = DEBUG_DRAW_DISABLED;
}
Viewport::~Viewport() {
diff --git a/scene/main/viewport.h b/scene/main/viewport.h
index e619199424..378055bef5 100644
--- a/scene/main/viewport.h
+++ b/scene/main/viewport.h
@@ -122,6 +122,24 @@ public:
USAGE_3D_NO_EFFECTS,
};
+ enum RenderInfo {
+
+ RENDER_INFO_OBJECTS_IN_FRAME,
+ RENDER_INFO_VERTICES_IN_FRAME,
+ RENDER_INFO_MATERIAL_CHANGES_IN_FRAME,
+ RENDER_INFO_SHADER_CHANGES_IN_FRAME,
+ RENDER_INFO_SURFACE_CHANGES_IN_FRAME,
+ RENDER_INFO_DRAW_CALLS_IN_FRAME,
+ RENDER_INFO_MAX
+ };
+
+ enum DebugDraw {
+ DEBUG_DRAW_DISABLED,
+ DEBUG_DRAW_UNSHADED,
+ DEBUG_DRAW_OVERDRAW,
+ DEBUG_DRAW_WIREFRAME,
+ };
+
private:
friend class ViewportTexture;
@@ -204,6 +222,8 @@ private:
RID texture_rid;
uint32_t texture_flags;
+ DebugDraw debug_draw;
+
Usage usage;
int shadow_atlas_size;
@@ -430,6 +450,11 @@ public:
void set_usage(Usage p_usage);
Usage get_usage() const;
+ void set_debug_draw(DebugDraw p_debug_draw);
+ DebugDraw get_debug_draw() const;
+
+ int get_render_info(RenderInfo p_info);
+
Viewport();
~Viewport();
};
@@ -438,5 +463,7 @@ VARIANT_ENUM_CAST(Viewport::UpdateMode);
VARIANT_ENUM_CAST(Viewport::ShadowAtlasQuadrantSubdiv);
VARIANT_ENUM_CAST(Viewport::MSAA);
VARIANT_ENUM_CAST(Viewport::Usage);
+VARIANT_ENUM_CAST(Viewport::DebugDraw);
+VARIANT_ENUM_CAST(Viewport::RenderInfo);
#endif
diff --git a/servers/visual/rasterizer.h b/servers/visual/rasterizer.h
index 236e8b4a0f..87cf6eed8c 100644
--- a/servers/visual/rasterizer.h
+++ b/servers/visual/rasterizer.h
@@ -155,6 +155,7 @@ public:
virtual void render_shadow(RID p_light, RID p_shadow_atlas, int p_pass, InstanceBase **p_cull_result, int p_cull_count) = 0;
virtual void set_scene_pass(uint64_t p_pass) = 0;
+ virtual void set_debug_draw_mode(VS::ViewportDebugDraw p_debug_draw) = 0;
virtual bool free(RID p_rid) = 0;
@@ -498,6 +499,8 @@ public:
virtual void update_dirty_resources() = 0;
+ virtual void set_debug_generate_wireframes(bool p_generate) = 0;
+
static RasterizerStorage *base_singleton;
RasterizerStorage();
virtual ~RasterizerStorage() {}
diff --git a/servers/visual/visual_server_raster.cpp b/servers/visual/visual_server_raster.cpp
index c4f22fdc0b..93c3793819 100644
--- a/servers/visual/visual_server_raster.cpp
+++ b/servers/visual/visual_server_raster.cpp
@@ -175,6 +175,11 @@ bool VisualServerRaster::has_os_feature(const String &p_feature) const {
return VSG::storage->has_os_feature(p_feature);
}
+void VisualServerRaster::set_debug_generate_wireframes(bool p_generate) {
+
+ VSG::storage->set_debug_generate_wireframes(p_generate);
+}
+
VisualServerRaster::VisualServerRaster() {
VSG::canvas = memnew(VisualServerCanvas);
diff --git a/servers/visual/visual_server_raster.h b/servers/visual/visual_server_raster.h
index f37c4735c7..b4b43a31be 100644
--- a/servers/visual/visual_server_raster.h
+++ b/servers/visual/visual_server_raster.h
@@ -595,6 +595,8 @@ public:
m_r m_name(m_type1 arg1) { return BINDBASE->m_name(arg1); }
#define BIND1RC(m_r, m_name, m_type1) \
m_r m_name(m_type1 arg1) const { return BINDBASE->m_name(arg1); }
+#define BIND2R(m_r, m_name, m_type1, m_type2) \
+ m_r m_name(m_type1 arg1, m_type2 arg2) { return BINDBASE->m_name(arg1, arg2); }
#define BIND2RC(m_r, m_name, m_type1, m_type2) \
m_r m_name(m_type1 arg1, m_type2 arg2) const { return BINDBASE->m_name(arg1, arg2); }
#define BIND3RC(m_r, m_name, m_type1, m_type2, m_type3) \
@@ -932,6 +934,9 @@ public:
BIND2(viewport_set_hdr, RID, bool)
BIND2(viewport_set_usage, RID, ViewportUsage)
+ BIND2R(int, viewport_get_render_info, RID, ViewportRenderInfo)
+ BIND2(viewport_set_debug_draw, RID, ViewportDebugDraw)
+
/* ENVIRONMENT API */
#undef BINDBASE
@@ -1130,6 +1135,7 @@ public:
virtual bool has_feature(Features p_feature) const;
virtual bool has_os_feature(const String &p_feature) const;
+ virtual void set_debug_generate_wireframes(bool p_generate);
VisualServerRaster();
~VisualServerRaster();
diff --git a/servers/visual/visual_server_viewport.cpp b/servers/visual/visual_server_viewport.cpp
index 3292d3feb4..9ab56894e9 100644
--- a/servers/visual/visual_server_viewport.cpp
+++ b/servers/visual/visual_server_viewport.cpp
@@ -272,6 +272,9 @@ void VisualServerViewport::draw_viewports() {
continue;
VSG::rasterizer->set_current_render_target(vp->render_target);
+
+ VSG::scene_render->set_debug_draw_mode(vp->debug_draw);
+
_draw_viewport(vp);
if (vp->viewport_to_screen_rect != Rect2()) {
@@ -283,6 +286,7 @@ void VisualServerViewport::draw_viewports() {
if (vp->update_mode == VS::VIEWPORT_UPDATE_ONCE) {
vp->update_mode = VS::VIEWPORT_UPDATE_DISABLED;
}
+ VSG::scene_render->set_debug_draw_mode(VS::VIEWPORT_DEBUG_DRAW_DISABLED);
}
}
@@ -557,6 +561,23 @@ void VisualServerViewport::viewport_set_usage(RID p_viewport, VS::ViewportUsage
}
}
+int VisualServerViewport::viewport_get_render_info(RID p_viewport, VS::ViewportRenderInfo p_info) {
+
+ ERR_FAIL_INDEX_V(p_info, VS::VIEWPORT_RENDER_INFO_MAX, -1);
+ Viewport *viewport = viewport_owner.getornull(p_viewport);
+ ERR_FAIL_COND_V(!viewport, -1);
+
+ return viewport->render_info[p_info];
+}
+
+void VisualServerViewport::viewport_set_debug_draw(RID p_viewport, VS::ViewportDebugDraw p_draw) {
+
+ Viewport *viewport = viewport_owner.getornull(p_viewport);
+ ERR_FAIL_COND(!viewport);
+
+ viewport->debug_draw = p_draw;
+}
+
bool VisualServerViewport::free(RID p_rid) {
if (viewport_owner.owns(p_rid)) {
diff --git a/servers/visual/visual_server_viewport.h b/servers/visual/visual_server_viewport.h
index ad3bfe9cb8..4d46e39b77 100644
--- a/servers/visual/visual_server_viewport.h
+++ b/servers/visual/visual_server_viewport.h
@@ -64,6 +64,9 @@ public:
RID shadow_atlas;
int shadow_atlas_size;
+ int render_info[VS::VIEWPORT_RENDER_INFO_MAX];
+ VS::ViewportDebugDraw debug_draw;
+
VS::ViewportClearMode clear_mode;
bool rendered_in_prev_frame;
@@ -103,6 +106,10 @@ public:
shadow_atlas_size = 0;
disable_3d = false;
disable_3d_by_usage = false;
+ debug_draw = VS::VIEWPORT_DEBUG_DRAW_DISABLED;
+ for (int i = 0; i < VS::VIEWPORT_RENDER_INFO_MAX; i++) {
+ render_info[i] = 0;
+ }
}
};
@@ -168,6 +175,9 @@ public:
void viewport_set_hdr(RID p_viewport, bool p_enabled);
void viewport_set_usage(RID p_viewport, VS::ViewportUsage p_usage);
+ virtual int viewport_get_render_info(RID p_viewport, VS::ViewportRenderInfo p_info);
+ virtual void viewport_set_debug_draw(RID p_viewport, VS::ViewportDebugDraw p_draw);
+
void draw_viewports();
bool free(RID p_rid);
diff --git a/servers/visual/visual_server_wrap_mt.h b/servers/visual/visual_server_wrap_mt.h
index 7653bf740a..d4f43ac396 100644
--- a/servers/visual/visual_server_wrap_mt.h
+++ b/servers/visual/visual_server_wrap_mt.h
@@ -372,6 +372,9 @@ public:
FUNC2(viewport_set_hdr, RID, bool)
FUNC2(viewport_set_usage, RID, ViewportUsage)
+ FUNC2R(int, viewport_get_render_info, RID, ViewportRenderInfo)
+ FUNC2(viewport_set_debug_draw, RID, ViewportDebugDraw)
+
/* ENVIRONMENT API */
FUNC0R(RID, environment_create)
@@ -552,6 +555,8 @@ public:
FUNC0R(RID, get_test_cube)
+ FUNC1(set_debug_generate_wireframes, bool)
+
virtual bool has_feature(Features p_feature) const { return visual_server->has_feature(p_feature); }
virtual bool has_os_feature(const String &p_feature) const { return visual_server->has_os_feature(p_feature); }
diff --git a/servers/visual_server.h b/servers/visual_server.h
index c7637007b3..3290a460a1 100644
--- a/servers/visual_server.h
+++ b/servers/visual_server.h
@@ -590,6 +590,28 @@ public:
virtual void viewport_set_hdr(RID p_viewport, bool p_enabled) = 0;
virtual void viewport_set_usage(RID p_viewport, ViewportUsage p_usage) = 0;
+ enum ViewportRenderInfo {
+
+ VIEWPORT_RENDER_INFO_OBJECTS_IN_FRAME,
+ VIEWPORT_RENDER_INFO_VERTICES_IN_FRAME,
+ VIEWPORT_RENDER_INFO_MATERIAL_CHANGES_IN_FRAME,
+ VIEWPORT_RENDER_INFO_SHADER_CHANGES_IN_FRAME,
+ VIEWPORT_RENDER_INFO_SURFACE_CHANGES_IN_FRAME,
+ VIEWPORT_RENDER_INFO_DRAW_CALLS_IN_FRAME,
+ VIEWPORT_RENDER_INFO_MAX
+ };
+
+ virtual int viewport_get_render_info(RID p_viewport, ViewportRenderInfo p_info) = 0;
+
+ enum ViewportDebugDraw {
+ VIEWPORT_DEBUG_DRAW_DISABLED,
+ VIEWPORT_DEBUG_DRAW_UNSHADED,
+ VIEWPORT_DEBUG_DRAW_OVERDRAW,
+ VIEWPORT_DEBUG_DRAW_WIREFRAME,
+ };
+
+ virtual void viewport_set_debug_draw(RID p_viewport, ViewportDebugDraw p_draw) = 0;
+
/* ENVIRONMENT API */
virtual RID environment_create() = 0;
@@ -912,6 +934,8 @@ public:
virtual bool has_os_feature(const String &p_feature) const = 0;
+ virtual void set_debug_generate_wireframes(bool p_generate) = 0;
+
VisualServer();
virtual ~VisualServer();
};