1
votes

I have a vertex format which are all floats, and looks like this:

POSITION  POSITION  POSITION  NORMAL  NORMAL  NORMAL  TEXCOORD TEXCOORD

I was thinking I need to draw lines from the first three floats to the next three floats, then I need to skip the next two floats and continue on. Is there any way of doing this without creating another buffer for each object that's in the correct layout?

I know I can draw just one line per draw call, and just loop over, but that is many draw calls? How is the general way normals are drawn for stuff like debugging?

Also I've thought about indexing, but indexing only helps selecting specific vertices, in this case I want to draw between two attributes of my normal vertex layout.

2

2 Answers

2
votes

This cannot be done just by setting appropriate glVertexAttribPointer, since you have to skip the texcoords. Additionally, you don't want to draw a line from position to normal, but from position to position + normal, since normals just describe a direction, not a point in space.

What you can do is to use a geometry shader. Basically, you set up two attributes, one for position, one for normal (as you would do for rendering the model) and issue a draw command with GL_POINTS primitive type. In the geometry shader you then generate a line from position to position + normal.

1
votes

Normally to draw surface normals you would set up a separate buffer or a geometry shader to do the work. Setting a separate buffer for a mesh to draw just the normals is trivial and doesn't require a draw call for every normal, all of your surface normals would be drawn in a single drawcall

Since you'll be doing it for debugging purposes, there's no need to worry too much about performance and just stick with the quicker method that gets things on screen

The way I'd personally do it depends on whether the mesh has vertex or face normals, we could for instance fill a buffer with a line for each vertex in the mesh whose offset from the vertex itself represent the normal you need to debug with the following pseudocode

var normal_buffer = [];

//tweak to your liking
var normal_length = 10.0; 

//this assumes your mesh has 2 arrays of the same length
//containing structs of vertices and normals
for(var i = 0; i < mesh.vertices.length; i++)  {
    //retrieving the normal associated with this vertex
    var nx = mesh.normals[i].x;
    var ny = mesh.normals[i].y;
    var nz = mesh.normals[i].z;

    //retrieving the vertex itself, it'll be the first point of our line
    var v1x = mesh.vertices[i].x;
    var v1y = mesh.vertices[i].y;
    var v1z = mesh.vertices[i].z;

    //second point of our line representing the normal direction
    var v2x = v1x + nx * normal_length;
    var v2y = v1y + ny * normal_length;
    var v2z = v1z + nz * normal_length;

    buffer.push(v1x, v1y, v1z, v2x, v2y, v2z);
}

You can later on proceed as normal and attach the buffer to a vertex buffer object and use whatever program you like to issue one single draw call that will draw all of your mesh normals

vertbuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, vertbuffer);
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(buffer), gl.STATIC_DRAW);

/* later on in your program */

gl.drawArrays(gl.LINES, 0, buffer.length / 3);

A cool feature of normal debugging is that you can use the normal itself in a fragment shader as an output color to quickly check if it points to the expected direction