2016-09-28 123 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