我正在学习WebGL并坚持理解如何将数据传递给属性。
drawArrays:没有缓冲区绑定到enabled属性 这是我得到的警告,但如果我禁用了一个vertexAttrib
gl.disableVertexAttribArray(positionAttributeLocation)
,此警告消失,但屏幕上仍然没有任何内容。
我做错了什么?
这是我的着色器。
const vsSource = `
attribute vec4 a_position;
attribute vec4 a_color;
varying vec4 v_color;
void main() {
gl_Position = a_position;
v_color = a_color;
}
`;
const fsSource = `
precision mediump float;
varying vec4 v_color;
void main() {
gl_FragColor = v_color;
}
`;
接下来我的步骤: 1)获得gl上下文
const canvas = document.querySelector('#glCanvas');
gl = canvas.getContext('webgl');
2)创建着色器
function createShader(type, source) {
var shader = gl.createShader(type); // create shader
gl.shaderSource(shader, source); // set to shader his code
gl.compileShader(shader); // compile shader
var success = gl.getShaderParameter(shader, gl.COMPILE_STATUS);
if (success) {
return shader;
}
console.log(gl.getShaderInfoLog(shader));
gl.deleteShader(shader);
}
const vShader = createShader(gl.VERTEX_SHADER, vsSource)
const fShader = createShader(gl.FRAGMENT_SHADER, fsSource)
3)创建一个程序并附加着色器,将它们链接
var program = gl.createProgram();
checkGlError()
gl.attachShader(program, vShader);
gl.attachShader(program, fShader);
gl.linkProgram(program);
if ( !gl.getProgramParameter(program, gl.LINK_STATUS) ) {
var info = gl.getProgramInfoLog(program);
throw 'Could not compile WebGL program. \n\n' + info;
}
4)获取对属性的引用
var positionAttributeLocation = gl.getAttribLocation(program, "a_position");
var colorAttributeLocation = gl.getAttribLocation(program, "a_color");
5)创建缓冲区并绑定数据
var positionBuffer = gl.createBuffer()
gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer)
setRectangle(gl)
var colorBuffer = gl.createBuffer()
gl.bindBuffer(gl.ARRAY_BUFFER, colorBuffer)
setColors(gl)
function setRectangle(gl) {
let x = randomFloat()
let y = randomFloat()
let width = randomFloat()
let height = randomFloat()
let x1 = x;
let x2 = x + width;
let y1 = y;
let y2 = y + height;
let positions = [
x1, y1,
x2, y1,
x1, y2,
x1, y2,
x2, y1,
x2, y2
]
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(positions), gl.STATIC_DRAW)
}
function setColors(gl) {
var r1 = Math.random();
var b1 = Math.random();
var g1 = Math.random();
var r2 = Math.random();
var b2 = Math.random();
var g2 = Math.random();
gl.bufferData(
gl.ARRAY_BUFFER,
new Float32Array(
[ r1, b1, g1, 1,
r1, b1, g1, 1,
r1, b1, g1, 1,
r2, b2, g2, 1,
r2, b2, g2, 1,
r2, b2, g2, 1]),
gl.STATIC_DRAW);
}
6)绘制场景
gl.viewport(0,0,gl.canvas.width,gl.canvas.height)
gl.clearColor(78/255.0,159/255.0,255/255.0,1.0)
gl.clear(gl.COLOR_BUFFER_BIT)
gl.useProgram(program)
gl.enableVertexAttribArray(positionAttributeLocation)
gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer)
var size = 2
var type = gl.FLOAT
var normalize = false
var stride = 0
var offset = 0
gl.vertexAttribPointer(
positionBuffer,
size,
type,
normalize,
stride,
offset)
gl.enableVertexAttribArray(colorAttributeLocation)
gl.bindBuffer(gl.ARRAY_BUFFER, colorBuffer)
var size = 4
var type = gl.FLOAT
var normalize = false
var stride = 0
var offset = 0
gl.vertexAttribPointer(
colorBuffer,
size,
type,
normalize,
stride,
offset)
let verticiesCounter = 6;
var drawingOffset = 0;
gl.drawArrays(gl.TRIANGLES, drawingOffset , verticiesCounter)
答案 0 :(得分:1)
vertexAttribPointer
的第一个参数必须是通用顶点属性的索引,而不是缓冲区对象。
注意,vertexAttribPointer
指定通用顶点属性的数据,因此必须在某处指定索引。
如果命名缓冲区对象绑定到目标ARRAY_BUFFER
,则此缓冲区中的数据是数据源。
请参阅OpenGL ES glVertexAttribPointer
和WebGL Specification; 5.13.10 Uniforms and attributes
这意味着您必须像这样更改代码:
gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer)
gl.vertexAttribPointer(
positionAttributeLocation, // instead of positionBuffer
size,
type,
normalize,
stride,
offset)
.....
gl.bindBuffer(gl.ARRAY_BUFFER, colorBuffer)
gl.vertexAttribPointer(
colorAttributeLocation, // instead of colorBuffer
size,
type,
normalize,
stride,
offset)