2012-08-17 208 views
0

我有一個非常基本的問題。我對webgl很陌生,試圖畫一個簡單的方塊。我正在使用gl矩陣庫進行矩陣操作。在webgl中繪製一個簡單的正方形

JavaScript代碼:

squareVertexPositionBuffer = gl.createBuffer(); 
    gl.bindBuffer(gl.ARRAY_BUFFER, squareVertexPositionBuffer); 
    vertices = [ 
     0.9, 0.9, 0.0,1.0, 
     -0.9, 0.9, 0.0,1.0, 
     0.9, -0.9, 0.0,1.0, 
     -0.9, -0.9, 0.0,1.0 

    ]; 


    squareVertexPositionBuffer.itemSize = 4; 
    squareVertexPositionBuffer.numItems = 4; 

    mat4.identity(pMatrix); 
    mat4.perspective(45, gl.viewportWidth/gl.viewportHeight, 0.1, 100.0, pMatrix); 
    mat4.identity(mvMatrix); 
    mat4.translate(mvMatrix, [-1.5, 0.0, -7.0]); 

    gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertices), gl.STATIC_DRAW); 
    gl.vertexAttribPointer(shaderProgram.vertexPositionAttribute,   squareVertexPositionBuffer.itemSize, gl.FLOAT, false, 0, 0); 
    setMatrixUniforms(); 
    gl.drawArrays(gl.TRIANGLE_STRIP, 0, squareVertexPositionBuffer.numItems); 

着色器:

attribute vec3 aVertexPosition; 

uniform mat4 uMVMatrix; 
uniform mat4 uPMatrix; 

varying vec3 debug; 


void main(void) { 
    gl_Position = uPMatrix * uMVMatrix * vec4(aVertexPosition.xyz, 1.0); 
    debug = aVertexPosition; 
} 

這似乎摸出fine.Here我傳遞模型視圖和透視矩陣作爲制服的着色器程序,並乘以他們那裏的頂點座標。但是,如果在javascript中將模型視圖和透視矩陣相乘,然後將修改後的頂點傳遞給着色器,它似乎不起作用。

我無法發現錯誤。幫助高度讚賞!

+0

如果你想繪製2D檢出http://games.greggman.com/game/webgl-fundamentals/沒有必要使用2D模型視圖和投影矩陣。 – gman 2012-08-17 20:07:45

回答

2

馬上蝙蝠,我注意到幾個問題:

1)你的頂點着色器輸入屬性不匹配傳遞給vertexAttribPointer參數:

您指定的屬性是4個浮點寬,但你的頂點着色器將其指定爲vec3。這些應該是一致的。

2)我沒有看到enableVertexAttribArray一個電話,是這樣的:

gl.enableVertexAttribArray(shaderProgram.vertexPositionAttribute);

您必須啓用頂點着色器使用的頂點屬性數組。

3)從顯示的代碼 - 你只是指定一個模型矩陣(身份,翻譯)。你需要創建一個視圖矩陣。一個簡單的方法就是調用mat4.lookAt。它具有以下定義:

mat4.lookAt =函數(眼睛,中心,向上,目標寄存器)

眼是相機 中心的位置是相機正在注視 向上應始終是位置(0,1,0)

一個例子是:

眼=(0,0,1) 中心=(0,0,0)

這使照相機1個單元向下積極的Z軸,並看它的起源。

將此與您的模型矩陣相乘將爲您提供模型視圖矩陣。


有太多的代碼缺失,因此很難確定您的錯誤是否在別的地方。例如,你的片段着色器是做什麼的?


當試圖讓你的第一個原始的屏幕上,我建議禁用剔除和深度測試。如果片段輸出與清晰顏色匹配,也會隨時間改變您的清晰顏色。

約翰

+0

對於我們人類來說,使用單獨的模型和視圖矩陣很方便,但GL根本不在乎。在過去,唯一的GL矩陣是ModelView連接和投影。現在,使用可編程着色器,它沒有任何區別。他可以將四元數用於所有GL護理;只要正確的值進入「gl_Position」就很好。就我個人而言,我使用單獨的模型,視圖和投影矩陣進行編程,但是隻要我可以將它們預先乘以一個MVP。此外,片段代碼對於這個問題應該不重要,因爲它不能改變像素位置。 – sinisterchipmunk 2012-08-17 15:24:16

+1

不需要屬性和vertexAttribPointer匹配。 GL爲您不提供的任何值提供默認值。 x = 0,y = 0,z = 0,w = 1默認情況下,所以如果你在你的代碼中使用vec4並且只提供vec3和vertexAttribPointer,它就可以正常工作。 – gman 2012-08-17 20:06:10

1

在約翰的回答中列出的問題是值得研究的,但如果你得到正確的原始現在呈現話,我不認爲他們是這個問題的根本原因。

我拆我的答案分爲兩個部分,因爲我不知道所適用的情況下給你:

  • 你沒有告訴你如何構建MVP的JavaScript版本,但雙檢查你的乘法語法是否正確。應該是這樣的形式:

    mat4.multiply(p, mv, mvp); 
    

    其中p是投影矩陣,mv是模型視圖矩陣,和mvp是接收模型視圖投影矩陣(其中結果將被存儲)。

  • 類似地,如果正在左乘頂點位置本身,正確的語法是:

    mat4.multiplyVec4(mvp, vertex, transformedVertex); 
    

    其中mvp是模型觀察投影矩陣,vertex是未修飾的頂點(A vec4)和transformedVertex是一個接收vec4值將被存儲。如果您使用這種方法,則必須在將頂點數組發送到GPU之前將其頂點平面化爲單個連續的浮點數組。

    注意不要混淆mat4.multiplyVec3mat4.multiplyVec4。乘法之前,vertex的第四個組成部分應設置爲1;這樣,transformedVertex的第四個組件可以被GPU用來執行透視分割(這會自動發生,但您需要發送正確的值)。

    另請注意,如果您錯誤地將vec3屬性向下發送到GPU並且屬性實際上是vec4類型,則第四個組件默認爲1.0。這通常很方便,但如果您將這些值預乘以JavaScript,也會導致棘手的錯誤。正如John所說的,儘量保持着色器定義與JavaScript端一致;這將導致長期較少的混淆。

相關問題