2017-01-10 41 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); 

的一個很酷的功能的正常的調試是,你可以使用片段着色器中的正常本身作爲輸出顏色來快速檢查它是否指向預期的方向