2016-09-28 3 views
0

В настоящее время я изучаю WebGL и Javascript. Назначение требует от меня создания нескольких форм с использованием WebGL, и для них все будут разными цветами, однако я не могу понять, как установить его так, чтобы каждая фигура имела свой собственный цвет.WebGL Drawing Multiple Shapes of Different Color

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

Однако, я не могу понять, как сделать так, что он хранит значение для каждой фигуры, которую я пытаюсь сделать. Я думал, что, делая это случайным образом меняя цвета перед рисованием каждый раз, это решило бы это, но это было не так. Любое понимание этого было бы высоко оценено.

спасибо.

+0

[Последний пример на этой странице рисует прямоугольники в случайных цветах] (http://webglfundamentals.org/ webgl/lessons/webgl-fundamentals.html) – gman

+0

Спасибо за это, однако, мне трудно определить, какая часть делает это так, чтобы каждый нарисованный объект был другого цвета, что было моей проблемой. – Zach

+0

Nevermind, я понял это! Спасибо, это немного помогло. – 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