2017-01-10 91 views
0

我有一个顶点格式,它是所有彩车,看起来像这样:如何在OpenGL中绘制曲面法线?

POSITION POSITION POSITION NORMAL NORMAL NORMAL TEXCOORD TEXCOORD 

我想我需要吸取前三彩车行未来三年的花车,然后我需要跳过下两个花车并继续。有没有办法做到这一点,而不是创建另一个缓冲区的每个对象是在正确的布局?

我知道我可以在每个绘制调用中只绘制一条线,并且只是循环,但那是很多绘制调用?通常的方法是如何绘制调试等东西?

此外,我已经想过索引,但索引只帮助选择特定的顶点,在这种情况下,我想绘制我的正常顶点布局的两个属性之间。

回答

2

这不能通过设置适当的glVertexAttribPointer来完成,因为您必须跳过texcoords。另外,由于法线只描述一个方向,而不是空间中的一个点,所以你不想画一条从positionnormal,但是从positionposition + normal的线。

你可以做的是使用几何着色器。基本上,您设置了两个属性,一个用于位置,一个用于正常(如您为渲染模型所做的那样),并发出一个带有原始类型的绘图命令。然后在几何着色器中生成一条从positionposition + normal的行。

+0

是的,我意识到了正常的+位置问题。好吧,我从来没有做过几何着色器,我会研究它。谢谢。编辑:我只是意识到,是你的方法发出每一个正常绘制的平局? – Zebrafish

0

通常要绘制表面法线,您可以设置单独的缓冲区或几何着色器来完成工作。为一个网格物体设置一个单独的缓冲区以仅仅绘制法线并不重要,并且不需要每个法线的绘制调用,所有的表面法线都将绘制在一个拉线中

既然你会这么做调试的目的,没有必要担心太多的性能,只是坚持更快的方法,让屏幕上的东西

我个人做的方式取决于网格是否有顶点或面法线,我们可以实例用网格中的每个顶点的线填充一个缓冲区,其中顶点本身的偏移量表示您需要使用以下伪代码调试的正常值

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); 
} 

以后可以正常进行和缓冲器连接到一个顶点缓冲区对象,并使用任何程序,你想发出一个单一的绘图调用,将提请所有网格法线

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); 

的一个很酷的功能的正常的调试是,你可以使用片段着色器中的正常本身作为输出颜色来快速检查它是否指向预期的方向