mirror of
https://github.com/brl/mutter.git
synced 2024-11-29 11:30:45 -05:00
debug: Adds a COGL_DEBUG=wireframe option
This adds a COGL_DEBUG=wireframe option to visualize the underlying geometry of the primitives being drawn via Cogl. This works for triangle list, triangle fan, triangle strip and quad (internal only) primitives. It also works for indexed vertex arrays.
This commit is contained in:
parent
20a1f87628
commit
460e4b90d3
@ -77,6 +77,11 @@ OPT (RECTANGLES,
|
||||
"rectangles",
|
||||
"Outline rectangles",
|
||||
"Add wire outlines for all rectangular geometry")
|
||||
OPT (WIREFRAME,
|
||||
"Visualize",
|
||||
"wireframe",
|
||||
"Show wireframes",
|
||||
"Add wire outlines for all geometry")
|
||||
OPT (DISABLE_BATCHING,
|
||||
"Root Cause",
|
||||
"disable-batching",
|
||||
|
@ -70,7 +70,8 @@ static const GDebugKey cogl_behavioural_debug_keys[] = {
|
||||
{ "disable-arbfp", COGL_DEBUG_DISABLE_ARBFP},
|
||||
{ "disable-glsl", COGL_DEBUG_DISABLE_GLSL},
|
||||
{ "disable-blending", COGL_DEBUG_DISABLE_BLENDING},
|
||||
{ "disable-npot-textures", COGL_DEBUG_DISABLE_NPOT_TEXTURES}
|
||||
{ "disable-npot-textures", COGL_DEBUG_DISABLE_NPOT_TEXTURES},
|
||||
{ "wireframe", COGL_DEBUG_WIREFRAME}
|
||||
};
|
||||
static const int n_cogl_behavioural_debug_keys =
|
||||
G_N_ELEMENTS (cogl_behavioural_debug_keys);
|
||||
|
@ -56,7 +56,8 @@ typedef enum {
|
||||
COGL_DEBUG_DISABLE_BLENDING = 1 << 23,
|
||||
COGL_DEBUG_TEXTURE_PIXMAP = 1 << 24,
|
||||
COGL_DEBUG_BITMAP = 1 << 25,
|
||||
COGL_DEBUG_DISABLE_NPOT_TEXTURES = 1 << 26
|
||||
COGL_DEBUG_DISABLE_NPOT_TEXTURES = 1 << 26,
|
||||
COGL_DEBUG_WIREFRAME = 1 << 27
|
||||
} CoglDebugFlags;
|
||||
|
||||
#ifdef COGL_ENABLE_DEBUG
|
||||
|
@ -642,6 +642,239 @@ disable_gl_state (CoglVertexAttribute **attributes,
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef COGL_ENABLE_DEBUG
|
||||
static int
|
||||
get_index (void *indices,
|
||||
CoglIndicesType type,
|
||||
int _index)
|
||||
{
|
||||
if (!indices)
|
||||
return _index;
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case COGL_INDICES_TYPE_UNSIGNED_BYTE:
|
||||
return ((guint8 *)indices)[_index];
|
||||
case COGL_INDICES_TYPE_UNSIGNED_SHORT:
|
||||
return ((guint16 *)indices)[_index];
|
||||
case COGL_INDICES_TYPE_UNSIGNED_INT:
|
||||
return ((guint32 *)indices)[_index];
|
||||
}
|
||||
|
||||
g_return_val_if_reached (0);
|
||||
}
|
||||
|
||||
static void
|
||||
add_line (void *vertices,
|
||||
void *indices,
|
||||
CoglIndicesType indices_type,
|
||||
CoglVertexAttribute *attribute,
|
||||
int start,
|
||||
int end,
|
||||
CoglP3Vertex *lines,
|
||||
int *n_line_vertices)
|
||||
{
|
||||
int start_index = get_index (indices, indices_type, start);
|
||||
int end_index = get_index (indices, indices_type, end);
|
||||
float *v0 = (float *)((guint8 *)vertices + start_index * attribute->stride);
|
||||
float *v1 = (float *)((guint8 *)vertices + end_index * attribute->stride);
|
||||
float *o = (float *)(&lines[*n_line_vertices]);
|
||||
int i;
|
||||
|
||||
for (i = 0; i < attribute->n_components; i++)
|
||||
*(o++) = *(v0++);
|
||||
for (;i < 3; i++)
|
||||
*(o++) = 0;
|
||||
|
||||
for (i = 0; i < attribute->n_components; i++)
|
||||
*(o++) = *(v1++);
|
||||
for (;i < 3; i++)
|
||||
*(o++) = 0;
|
||||
|
||||
*n_line_vertices += 2;
|
||||
}
|
||||
|
||||
static CoglP3Vertex *
|
||||
get_wire_lines (CoglVertexAttribute *attribute,
|
||||
CoglVerticesMode mode,
|
||||
int n_vertices_in,
|
||||
int *n_vertices_out,
|
||||
CoglIndices *_indices)
|
||||
{
|
||||
CoglVertexArray *vertex_array = cogl_vertex_attribute_get_array (attribute);
|
||||
void *vertices;
|
||||
CoglIndexArray *index_array;
|
||||
void *indices;
|
||||
CoglIndicesType indices_type;
|
||||
int i;
|
||||
int n_lines;
|
||||
CoglP3Vertex *out;
|
||||
|
||||
vertices = cogl_buffer_map (COGL_BUFFER (vertex_array),
|
||||
COGL_BUFFER_ACCESS_READ, 0);
|
||||
if (_indices)
|
||||
{
|
||||
index_array = cogl_indices_get_array (_indices);
|
||||
indices = cogl_buffer_map (COGL_BUFFER (index_array),
|
||||
COGL_BUFFER_ACCESS_READ, 0);
|
||||
indices_type = cogl_indices_get_type (_indices);
|
||||
}
|
||||
else
|
||||
indices = NULL;
|
||||
|
||||
*n_vertices_out = 0;
|
||||
|
||||
if (mode == COGL_VERTICES_MODE_TRIANGLES &&
|
||||
(n_vertices_in % 3) == 0)
|
||||
{
|
||||
n_lines = n_vertices_in;
|
||||
out = g_new (CoglP3Vertex, n_lines * 2);
|
||||
for (i = 0; i < n_vertices_in; i += 3)
|
||||
{
|
||||
add_line (vertices, indices, indices_type, attribute,
|
||||
i, i+1, out, n_vertices_out);
|
||||
add_line (vertices, indices, indices_type, attribute,
|
||||
i+1, i+2, out, n_vertices_out);
|
||||
add_line (vertices, indices, indices_type, attribute,
|
||||
i+2, i, out, n_vertices_out);
|
||||
}
|
||||
}
|
||||
else if (mode == COGL_VERTICES_MODE_TRIANGLE_FAN &&
|
||||
n_vertices_in >= 3)
|
||||
{
|
||||
n_lines = 2 * n_vertices_in - 3;
|
||||
out = g_new (CoglP3Vertex, n_lines * 2);
|
||||
|
||||
add_line (vertices, indices, indices_type, attribute,
|
||||
0, 1, out, n_vertices_out);
|
||||
add_line (vertices, indices, indices_type, attribute,
|
||||
1, 2, out, n_vertices_out);
|
||||
add_line (vertices, indices, indices_type, attribute,
|
||||
0, 2, out, n_vertices_out);
|
||||
|
||||
for (i = 3; i < n_vertices_in; i++)
|
||||
{
|
||||
add_line (vertices, indices, indices_type, attribute,
|
||||
i - 1, i, out, n_vertices_out);
|
||||
add_line (vertices, indices, indices_type, attribute,
|
||||
0, i, out, n_vertices_out);
|
||||
}
|
||||
}
|
||||
else if (mode == COGL_VERTICES_MODE_TRIANGLE_STRIP &&
|
||||
n_vertices_in >= 3)
|
||||
{
|
||||
n_lines = 2 * n_vertices_in - 3;
|
||||
out = g_new (CoglP3Vertex, n_lines * 2);
|
||||
|
||||
add_line (vertices, indices, indices_type, attribute,
|
||||
0, 1, out, n_vertices_out);
|
||||
add_line (vertices, indices, indices_type, attribute,
|
||||
1, 2, out, n_vertices_out);
|
||||
add_line (vertices, indices, indices_type, attribute,
|
||||
0, 2, out, n_vertices_out);
|
||||
|
||||
for (i = 3; i < n_vertices_in; i++)
|
||||
{
|
||||
add_line (vertices, indices, indices_type, attribute,
|
||||
i - 1, i, out, n_vertices_out);
|
||||
add_line (vertices, indices, indices_type, attribute,
|
||||
i - 2, i, out, n_vertices_out);
|
||||
}
|
||||
}
|
||||
/* In the journal we are a bit sneaky and actually use GL_QUADS
|
||||
* which isn't actually a valid CoglVerticesMode! */
|
||||
#ifdef HAVE_COGL_GL
|
||||
else if (mode == GL_QUADS && (n_vertices_in % 4) == 0)
|
||||
{
|
||||
n_lines = n_vertices_in;
|
||||
out = g_new (CoglP3Vertex, n_lines * 2);
|
||||
|
||||
for (i = 0; i < n_vertices_in; i += 4)
|
||||
{
|
||||
add_line (vertices, indices, indices_type, attribute,
|
||||
i, i + 1, out, n_vertices_out);
|
||||
add_line (vertices, indices, indices_type, attribute,
|
||||
i + 1, i + 2, out, n_vertices_out);
|
||||
add_line (vertices, indices, indices_type, attribute,
|
||||
i + 2, i + 3, out, n_vertices_out);
|
||||
add_line (vertices, indices, indices_type, attribute,
|
||||
i + 3, i, out, n_vertices_out);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if (vertices)
|
||||
cogl_buffer_unmap (COGL_BUFFER (vertex_array));
|
||||
if (indices)
|
||||
cogl_buffer_unmap (COGL_BUFFER (index_array));
|
||||
return out;
|
||||
}
|
||||
|
||||
static void
|
||||
draw_wireframe (CoglVerticesMode mode,
|
||||
int first_vertex,
|
||||
int n_vertices,
|
||||
CoglVertexAttribute **attributes,
|
||||
CoglIndices *indices)
|
||||
{
|
||||
CoglVertexAttribute *position = NULL;
|
||||
int i;
|
||||
int n_line_vertices;
|
||||
static CoglPipeline *wire_pipeline;
|
||||
CoglVertexAttribute *wire_attribute[2];
|
||||
CoglP3Vertex *lines;
|
||||
CoglVertexArray *array;
|
||||
|
||||
for (i = 0; attributes[i]; i++)
|
||||
{
|
||||
if (strcmp (attributes[i]->name, "cogl_position_in") == 0)
|
||||
{
|
||||
position = attributes[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!position)
|
||||
return;
|
||||
|
||||
lines = get_wire_lines (position,
|
||||
mode,
|
||||
n_vertices,
|
||||
&n_line_vertices,
|
||||
indices);
|
||||
array = cogl_vertex_array_new (sizeof (CoglP3Vertex) * n_line_vertices,
|
||||
lines);
|
||||
wire_attribute[0] =
|
||||
cogl_vertex_attribute_new (array, "cogl_position_in",
|
||||
sizeof (CoglP3Vertex),
|
||||
0,
|
||||
3,
|
||||
COGL_VERTEX_ATTRIBUTE_TYPE_FLOAT);
|
||||
wire_attribute[1] = NULL;
|
||||
cogl_object_unref (array);
|
||||
|
||||
if (!wire_pipeline)
|
||||
{
|
||||
wire_pipeline = cogl_pipeline_new ();
|
||||
cogl_pipeline_set_color4ub (wire_pipeline,
|
||||
0x00, 0xff, 0x00, 0xff);
|
||||
}
|
||||
|
||||
cogl_push_source (wire_pipeline);
|
||||
|
||||
/* temporarily disable the wireframe to avoid recursion! */
|
||||
cogl_debug_flags &= ~COGL_DEBUG_WIREFRAME;
|
||||
_cogl_draw_vertex_attributes_array (COGL_VERTICES_MODE_LINES,
|
||||
0,
|
||||
n_line_vertices,
|
||||
wire_attribute);
|
||||
cogl_debug_flags |= COGL_DEBUG_WIREFRAME;
|
||||
|
||||
cogl_pop_source ();
|
||||
|
||||
cogl_object_unref (wire_attribute[0]);
|
||||
}
|
||||
#endif
|
||||
|
||||
static void
|
||||
_cogl_draw_vertex_attributes_array_real (CoglVerticesMode mode,
|
||||
int first_vertex,
|
||||
@ -656,6 +889,11 @@ _cogl_draw_vertex_attributes_array_real (CoglVerticesMode mode,
|
||||
/* FIXME: we shouldn't be disabling state after drawing we should
|
||||
* just disable the things not needed after enabling state. */
|
||||
disable_gl_state (attributes, source);
|
||||
|
||||
#ifdef COGL_ENABLE_DEBUG
|
||||
if (G_UNLIKELY (cogl_debug_flags & COGL_DEBUG_WIREFRAME))
|
||||
draw_wireframe (mode, first_vertex, n_vertices, attributes, NULL);
|
||||
#endif
|
||||
}
|
||||
|
||||
/* This can be used by the CoglJournal to draw attributes skipping the
|
||||
@ -798,6 +1036,11 @@ _cogl_draw_indexed_vertex_attributes_array_real (CoglVerticesMode mode,
|
||||
/* FIXME: we shouldn't be disabling state after drawing we should
|
||||
* just disable the things not needed after enabling state. */
|
||||
disable_gl_state (attributes, source);
|
||||
|
||||
#ifdef COGL_ENABLE_DEBUG
|
||||
if (G_UNLIKELY (cogl_debug_flags & COGL_DEBUG_WIREFRAME))
|
||||
draw_wireframe (mode, first_vertex, n_vertices, attributes, indices);
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
|
Loading…
Reference in New Issue
Block a user