我首先要说的是我是webgl的新手,几天前才拿起它用于计算机图形课程,而且我在使用dat的应用程序时遇到问题。 GUI。它应该做的是通过2次点击绘制一个矩形,并使用dat.gui控制器选择的颜色对其进行着色,但我得到的颜色是从绿色,黄色,红色和左下角是黑色的。如果我评论gl.enableVertexAttribArray(_color);矩形线都是黑色的,所以我能想到的是我没有正确存储颜色信息。如果有人能指出我的解决方案或至少解决问题,我将非常感激。 `
<html>
<body>
<canvas width="570" height="570" id="my_Canvas"></canvas>
<script src="../lib/dat.gui.js"></script>
<script>
var canvas = document.getElementById('my_Canvas');
gl = canvas.getContext('experimental-webgl');
var vertCode =
'attribute vec3 coordinates;' +
'varying vec3 vColor;' +
'attribute vec3 color;' +
'void main(void){' +
' gl_Position=vec4(coordinates, 1.0);' +
'vColor=color;' +
'}';
var vertShader = gl.createShader(gl.VERTEX_SHADER);
gl.shaderSource(vertShader, vertCode);
gl.compileShader(vertShader);
var fragCode =
'precision highp float;' +
'varying vec3 vColor;' +
'void main(void){' +
' gl_FragColor=vec4(vColor, 1.0);' +
'}';
var fragShader = gl.createShader(gl.FRAGMENT_SHADER);
gl.shaderSource(fragShader, fragCode);
gl.compileShader(fragShader);
var shaderProgram = gl.createProgram();
gl.attachShader(shaderProgram, vertShader);
gl.attachShader(shaderProgram, fragShader);
gl.linkProgram(shaderProgram);
console.log(gl.getShaderInfoLog(vertShader));
console.log(gl.getProgramInfoLog(shaderProgram));
var gui = new dat.GUI();
var colore = {
colorv: [200, 200, 0]
};
gui.addColor(colore, 'colorv');
gl.clearColor(0.5, 0.5, 0.5, 1);
gl.clear(gl.COLOR_BUFFER_BIT);
var g_indices = [0, 1, 2, 0, 1, 3];
var colors = [];
var p_counter = 0; //this counter is used to detect if the point clicked is the 2nd point
var g_counter = 0; //this is a global counter, used as a multiplier for g_points
var quad_g_counter;
var dodeca_g_counter;
var g_points = []; // the array for mousepress
var indices = [];
var vertex_buffer = gl.createBuffer();
var Index_Buffer = gl.createBuffer();
var color_Buffer = gl.createBuffer();
function click(ev, gl, canvas) {
var x = ev.clientX;
var y = ev.clientY;
var rect = ev.target.getBoundingClientRect();
x = ((x - rect.left) - canvas.height / 2) / (canvas.height / 2);
y = (canvas.width / 2 - (y - rect.top)) / (canvas.width / 2);
//store the coords in g_points array
g_points.push(x);
g_points.push(y);
g_points.push(0);
// clear <canvas>
gl.clear(gl.COLOR_BUFFER_BIT);
p_counter += 1;
if (p_counter == 2) {
//g_points
dodeca_g_counter = g_counter * 12;
g_points.push(g_points[dodeca_g_counter + 3]);
g_points.push(g_points[dodeca_g_counter + 1]);
g_points.push(0);
g_points.push(g_points[dodeca_g_counter]);
g_points.push(g_points[dodeca_g_counter + 4]);
g_points.push(0);
//indices
quad_g_counter = g_counter * 4;
indices.push(g_indices[0] + quad_g_counter);
indices.push(g_indices[1] + quad_g_counter);
indices.push(g_indices[2] + quad_g_counter);
indices.push(g_indices[3] + quad_g_counter);
indices.push(g_indices[4] + quad_g_counter);
indices.push(g_indices[5] + quad_g_counter);
//colors
for (var i = 0; i < 4; i += 1) {
colors.push(colore.colorv[0] / 255);
colors.push(colore.colorv[1] / 255);
colors.push(colore.colorv[2] / 255);
}
p_counter = 0;
g_counter += 1;
}
gl.bindBuffer(gl.ARRAY_BUFFER, vertex_buffer);
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(g_points), gl.STATIC_DRAW);
//gl.bindBuffer(gl.ARRAY_BUFFER, null);
//gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, null);
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, Index_Buffer);
gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint16Array(indices), gl.STATIC_DRAW);
//gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, null);
gl.bindBuffer(gl.ARRAY_BUFFER, color_Buffer);
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(colors), gl.STATIC_DRAW);
draw();
}
canvas.onmousedown = function(ev) {
click(ev, gl, canvas);
}
function draw() {
gl.bindBuffer(gl.ARRAY_BUFFER, vertex_buffer);
var coord = gl.getAttribLocation(shaderProgram, "coordinates");
gl.vertexAttribPointer(coord, 3, gl.FLOAT, false, 0, 0);
gl.enableVertexAttribArray(coord);
var _color = gl.getAttribLocation(shaderProgram, "color");
gl.vertexAttribPointer(_color, 3, gl.FLOAT, false, 0, 0);
gl.enableVertexAttribArray(_color);
gl.useProgram(shaderProgram);
gl.enable(gl.DEPTH_TEST);
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, Index_Buffer);
gl.viewport(0, 0, canvas.width, canvas.height);
gl.drawElements(gl.TRIANGLES, indices.length, gl.UNSIGNED_SHORT, 0);
}
</script>
</body>
</html>
&#13;
答案 0 :(得分:0)
在调用gl.vertexAttribPointer
:
var coord = gl.getAttribLocation(shaderProgram, "coordinates");
var _color = gl.getAttribLocation(shaderProgram, "color");
.....
gl.bindBuffer(gl.ARRAY_BUFFER, vertex_buffer);
gl.vertexAttribPointer(coord, 3, gl.FLOAT, false, 0, 0);
gl.enableVertexAttribArray(coord);
gl.bindBuffer(gl.ARRAY_BUFFER, color_Buffer);
gl.vertexAttribPointer(_color, 3, gl.FLOAT, false, 0, 0);
gl.enableVertexAttribArray(_color);
注意,gl.vertexAttribPointer
定义了一个引用当前绑定ARRAY_BUFFER
的通用顶点属性数据的数组。见gl.bindBuffer
。
在为"coordinates"
指定顶点属性之前,绑定vertex_buffer
。但是,如果您为color_Buffer
指定顶点属性,则不要绑定"color"
。
因此,顶点坐标缓冲区也用于颜色属性。因为颜色是从一点到另一点插值的,所以他会产生彩色线条和区域。
请参阅代码段:
var canvas = document.getElementById('my_Canvas');
gl = canvas.getContext('experimental-webgl');
var vertCode=
'attribute vec3 coordinates;' +
'varying vec3 vColor;' +
'attribute vec3 color;' +
'void main(void){' +
' gl_Position=vec4(coordinates, 1.0);' +
'vColor=color;' +
'}';
var vertShader=gl.createShader(gl.VERTEX_SHADER);
gl.shaderSource(vertShader, vertCode);
gl.compileShader(vertShader);
var fragCode=
'precision highp float;' +
'varying vec3 vColor;' +
'void main(void){' +
' gl_FragColor=vec4(vColor, 1.0);' +
'}';
var fragShader=gl.createShader(gl.FRAGMENT_SHADER);
gl.shaderSource(fragShader, fragCode);
gl.compileShader(fragShader);
var shaderProgram=gl.createProgram();
gl.attachShader(shaderProgram, vertShader);
gl.attachShader(shaderProgram, fragShader);
gl.linkProgram(shaderProgram);
console.log(gl.getShaderInfoLog(vertShader));
console.log(gl.getProgramInfoLog(shaderProgram));
//var gui = new dat.GUI();
var colore={
colorv: [200,200,0]
};
//gui.addColor(colore, 'colorv');
gl.clearColor(0.5, 0.5, 0.5, 1);
gl.clear(gl.COLOR_BUFFER_BIT);
var g_indices=[0,1,2,0,1,3];
var colors=[];
var p_counter=0; //this counter is used to detect if the point clicked is the 2nd point
var g_counter=0; //this is a global counter, used as a multiplier for g_points
var quad_g_counter;
var dodeca_g_counter;
var g_points = []; // the array for mousepress
var indices=[];
var vertex_buffer=gl.createBuffer();
var Index_Buffer=gl.createBuffer();
var color_Buffer=gl.createBuffer();
function click(ev,gl,canvas){
var x = ev.clientX;
var y = ev.clientY;
var rect = ev.target.getBoundingClientRect();
x = ((x - rect.left) - canvas.height/2)/(canvas.height/2);
y = (canvas.width/2 - (y - rect.top))/(canvas.width/2);
//store the coords in g_points array
g_points.push(x);g_points.push(y); g_points.push(0);
// clear <canvas>
gl.clear(gl.COLOR_BUFFER_BIT);
p_counter+=1;
if(p_counter==2){
//g_points
dodeca_g_counter=g_counter*12;
g_points.push(g_points[dodeca_g_counter+3]);g_points.push(g_points[dodeca_g_counter+1]);g_points.push(0);
g_points.push(g_points[dodeca_g_counter]);g_points.push(g_points[dodeca_g_counter+4]);g_points.push(0);
//indices
quad_g_counter=g_counter*4;
indices.push(g_indices[0]+quad_g_counter);indices.push(g_indices[1]+quad_g_counter);
indices.push(g_indices[2]+quad_g_counter);indices.push(g_indices[3]+quad_g_counter);
indices.push(g_indices[4]+quad_g_counter);indices.push(g_indices[5]+quad_g_counter);
//colors
for(var i=0; i<4; i+=1){
colors.push(colore.colorv[0]/255);colors.push(colore.colorv[1]/255);
colors.push(colore.colorv[2]/255);
}
p_counter=0;
g_counter+=1;
}
gl.bindBuffer(gl.ARRAY_BUFFER, vertex_buffer);
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(g_points), gl.STATIC_DRAW);
//gl.bindBuffer(gl.ARRAY_BUFFER, null);
//gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, null);
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, Index_Buffer);
gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint16Array(indices), gl.STATIC_DRAW);
//gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, null);
gl.bindBuffer(gl.ARRAY_BUFFER, color_Buffer);
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(colors), gl.STATIC_DRAW);
draw();
}
canvas.onmousedown = function(ev) {click(ev,gl,canvas);}
function draw(){
gl.bindBuffer(gl.ARRAY_BUFFER, vertex_buffer);
var coord=gl.getAttribLocation(shaderProgram, "coordinates");
gl.vertexAttribPointer(coord, 3, gl.FLOAT, false, 0, 0);
gl.enableVertexAttribArray(coord);
gl.bindBuffer(gl.ARRAY_BUFFER, color_Buffer);
var _color=gl.getAttribLocation(shaderProgram, "color");
gl.vertexAttribPointer(_color, 3, gl.FLOAT, false, 0,0);
gl.enableVertexAttribArray(_color);
gl.useProgram(shaderProgram);
gl.enable(gl.DEPTH_TEST);
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, Index_Buffer);
gl.viewport(0, 0, canvas.width, canvas.height);
gl.drawElements(gl.TRIANGLES, indices.length, gl.UNSIGNED_SHORT, 0);
}
&#13;
<canvas width="570" height="570" id="my_Canvas"></canvas>
&#13;