2016-09-28 124 views
0

我目前正在學習WebGL和Javascript的過程。一個任務需要我使用WebGL創建多個形狀,並且它們都是不同的顏色,但是,我無法弄清楚如何設置它以便每個形狀都具有它自己的顏色。WebGL繪製不同顏色的多種形狀

// HelloTriangle.js (c) 2012 matsuda 
 
// Vertex shader program 
 
var VSHADER_SOURCE = 
 
    'attribute vec4 a_Position;\n' + 
 
    'void main() {\n' + 
 
    ' gl_Position = a_Position;\n' + 
 
    '}\n'; 
 
    
 
// Fragment shader program 
 
var FSHADER_SOURCE = 
 
    'precision mediump float;\n' + 
 
    'uniform vec4 u_FragColor;\n' + 
 
    'void main() {\n' + 
 
    ' gl_FragColor = u_FragColor;\n' + 
 
    '}\n'; 
 
    
 
function main() { 
 
    // Retrieve <canvas> element 
 
    var canvas = document.getElementById('webgl'); 
 
    
 
    // Get the rendering context for WebGL 
 
    var gl = getWebGLContext(canvas); 
 
    if (!gl) { 
 
    console.log('Failed to get the rendering context for WebGL'); 
 
    return; 
 
    } 
 
    
 
    // Initialize shaders 
 
    if (!initShaders(gl, VSHADER_SOURCE, FSHADER_SOURCE)) { 
 
    console.log('Failed to intialize shaders.'); 
 
    return; 
 
    } 
 
    
 
    // Write the positions of vertices to a vertex shader 
 
    var n = initVertexBuffers(gl); 
 
    if (n < 0) { 
 
    console.log('Failed to set the positions of the vertices'); 
 
    return; 
 
    } 
 
    
 
    // Specify the color for clearing <canvas> 
 
    gl.clearColor(0, 0, 0, 1); 
 
    
 
    // Clear <canvas> 
 
    gl.clear(gl.COLOR_BUFFER_BIT); 
 
    
 
    // Draw the rectangle 
 
    gl.drawArrays(gl.TRIANGLES, 0, 3); // Triangle One 
 
    gl.drawArrays(gl.TRIANGLES, 3, 3); // Triangle Two 
 
    gl.drawArrays(gl.TRIANGLE_FAN, 6, 6); // Triangle Fan 
 
} 
 
    
 
function randColor() // Assign Random color values 
 
{ 
 
    setR = Math.random(); 
 
    setG = Math.random(); 
 
    setB = Math.random(); 
 
} 
 
    
 
function initVertexBuffers(gl) { 
 
    var vertices = new Float32Array([ 
 
    0.1, 0.1, -0.1, -0.1, 0.1, -0.1, // First Triangle 
 
    0.15, 0.25, 0.1, 0.2, -0.1, 0.2, // Second Triangle 
 
    0.75, 0.65, 0.35, 0.25, 0.65, 0.55, 
 
    0.65, 0.25, 0.35, 0.45, 0.25, 0.15 // Triangle Fan 
 
    ]); 
 
    var n = 6; // The number of vertices 
 
    
 
    // Create a buffer object 
 
    var vertexBuffer = gl.createBuffer(); 
 
    if (!vertexBuffer) { 
 
    console.log('Failed to create the buffer object'); 
 
    return -1; 
 
    } 
 
    
 
    // Bind the buffer object to target 
 
    gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer); 
 
    // Write date into the buffer object 
 
    gl.bufferData(gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW); 
 
    
 
    var a_Position = gl.getAttribLocation(gl.program, 'a_Position'); 
 
    if (a_Position < 0) { 
 
    console.log('Failed to get the storage location of a_Position'); 
 
    return -1; 
 
    } 
 
    
 
    // Get the storage location of u_FragColor 
 
    var u_FragColor = gl.getUniformLocation(gl.program, 'u_FragColor'); 
 
    if (!u_FragColor) { 
 
    console.log('Failed to get the storage location of u_FragColor'); 
 
    return; 
 
    } 
 
    
 
    //Pass color of point to u_FragColor 
 
    randColor(); 
 
    gl.uniform4f(u_FragColor, setR, setG, setB, 1.0); 
 
    
 
    // Assign the buffer object to a_Position variable 
 
    gl.vertexAttribPointer(a_Position, 2, gl.FLOAT, false, 0, 0); 
 
    
 
    // Enable the assignment to a_Position variable 
 
    gl.enableVertexAttribArray(a_Position); 
 
    
 
    return n; 
 
}
<canvas id="webgl" width="400" height="400"> 
 
    Please use a browser that supports "canvas" 
 
</canvas> 
 

 
<script src="../lib/webgl-utils.js"></script> 
 
<script src="../lib/webgl-debug.js"></script> 
 
<script src="../lib/cuon-utils.js"></script>

我敢肯定,我應該修改代碼如下:

//Pass color of point to u_FragColor 
randColor(); 
gl.uniform4f(u_FragColor, setR, setG, setB, 1.0); 

然而,我無法弄清楚如何讓這個IT賣場我試圖繪製每個形狀的值。我認爲通過在每次繪圖之前隨機更改顏色,這可以解決問題,但事實並非如此。任何洞察到這一點將不勝感激。

謝謝。

+0

[當前頁上的最後一個示例繪製矩形在隨機顏色(http://webglfundamentals.org/ webgl/lessons/webgl-fundamentals.html) – gman

+0

謝謝你,但是,我很難確定哪個部分使得每個繪製的對象是不同的顏色,這是我的問題。 – Zach

+0

沒關係,我想通了! 謝謝,這確實有些幫助。 – Zach

回答

1

你試過了什麼?該代碼存在很多問題,並且嘗試運行它時會出錯。

首先,initShaders返回gl.program上的着色器,這使得零感。 WebGL應用程序通常具有多個着色器程序。相反,你要initShaders返回一個程序,所以你可以做這樣的事情

var program1 = initShaders(gl, vertex1ShaderSource, fragment1ShaderSource); 
var program2 = initShaders(gl, vertex2ShaderSource, fragment2ShaderSource); 
var program3 = initShaders(gl, vertex3ShaderSource, fragment3ShaderSource); 
..etc... 

接下來initVertexBuffers引用一個名爲program變量,但沒有這樣的變量存在。

initVertexBuffers正在設置制服,但您希望在開始繪製之前設置制服,而不是在初始化頂點時設置制服。

initVertexBuffers也查找屬性和統一的位置,並檢查錯誤。一方面,檢查這些類型的錯誤本身並不壞,但它會使代碼更難以用其他方式進行調試。在大多數的WebGL程序,如果你沒有錯誤,但事情並沒有出現在屏幕上做的是讓你的片段着色器返回純色

precision mediump float; 
uniform vec4 u_FragColor; 
void main() { 
    //gl_FragColor = u_FragColor; 
    gl_FragColor = vec4(1, 0, 0, 1); // return red 
} 

的第一件事,當你這樣做的WebGL將優化出unsued u_FragColor和你的代碼檢查你得到的位置爲u_FragColor將無法​​調試着色器。我想建議reading some other tutorials on WebGL

要繪製的相同形狀的多個副本的方法通常

是在初始化時間

set up program 
look up attribute locations and uniform locations 
setup vertices for shape 

在繪圖時

setup attributes for shape 
gl.useProgram(program for shape) 
for each instance of shape 
    set uniforms 
    set a matrix uniform to position and orient the shape 
    set a color uniform for the color 
    drawArrays/drawElements 

要繪製的多個不同形狀的過程通常是

初始時間

set up programs 
look up attribute locations and uniform locations 
for each shape 
    setup vertices for shape 

在繪圖時

for each shape 
    gl.useProgram(program for shape) (if different from last shape) 
    setup attributes for shape (if different from last shape) 
    set uniforms 
    set a matrix uniform to position and orient the shape 
    set a color uniform for the color 
    drawArrays/drawElements 

作爲基質用於定位和定向的形狀see this article