Reputation: 965
I am trying to port some OpenGL code to WebGL2 and I have some problems with Uniform Buffers. Everything I render with the shader the buffer is attached to is no longer displayed. I get no errors or warnings in the console. This is my code:
var data = new Float32Array(1);
data[0] = 1.0;
var uniformBuffer = gl.createBuffer();
gl.bindBuffer(gl.UNIFORM_BUFFER, uniformBuffer);
gl.bufferData(gl.UNIFORM_BUFFER, 4, gl.STATIC_DRAW);
gl.bindBufferRange(gl.UNIFORM_BUFFER, 0, uniformBuffer, 0, 4);
gl.uniformBlockBinding(mapShader.getProgram(), gl.getUniformBlockIndex(mapShader.getProgram(), "test"), 0);
gl.bindBuffer(gl.UNIFORM_BUFFER, uniformBuffer);
gl.bufferSubData(gl.UNIFORM_BUFFER, 0, data);
gl.bindBuffer(gl.UNIFORM_BUFFER, null);
Once I add this to my shader the problems I described earlier appear:
layout (std140) uniform test {
float testFloat;
};
Upvotes: 1
Views: 1765
Reputation:
Next time please be kind and save us from having to manually make a repo! Thanks 🙇♂️
When I run your code in Chrome I get
:GL_INVALID_OPERATION : glDrawArrays: uniform buffers : buffer or buffer range at index 0 not large enough
The problem is there are padding and alignment issues
See the spec section 2.12.6.4
Changing your buffer and range size to 16 and it works. Also note there are alignment requirements for valid offsets to BindBufferRange
you can look up with gl.getParameter(gl.UNIFORM_BUFFER_OFFSET_ALIGNMENT)
const gl = document.querySelector('canvas').getContext('webgl2');
const vs = `#version 300 es
void main() {
gl_PointSize = 100.0;
gl_Position = vec4(0, 0, 0, 1);
}
`;
const fs = `#version 300 es
precision highp float;
layout (std140) uniform test {
float testFloat;
};
out vec4 outColor;
void main() {
outColor = vec4(testFloat, 0, 0, 1);
}
`;
const prg = twgl.createProgram(gl, [vs, fs]);
gl.useProgram(prg);
const mapShader = {
getProgram: _ => prg,
};
var data = new Float32Array(1);
data[0] = 1.0;
var uniformBuffer = gl.createBuffer();
gl.bindBuffer(gl.UNIFORM_BUFFER, uniformBuffer);
gl.bufferData(gl.UNIFORM_BUFFER, 16, gl.STATIC_DRAW);
gl.bindBufferRange(gl.UNIFORM_BUFFER, 0, uniformBuffer, 0, 16);
gl.uniformBlockBinding(mapShader.getProgram(), gl.getUniformBlockIndex(mapShader.getProgram(), "test"), 0);
gl.bindBuffer(gl.UNIFORM_BUFFER, uniformBuffer);
gl.bufferSubData(gl.UNIFORM_BUFFER, 0, data);
gl.bindBuffer(gl.UNIFORM_BUFFER, null);
gl.drawArrays(gl.POINTS, 0, 1);
<script src="https://twgljs.org/dist/4.x/twgl.min.js"></script>
<canvas></canvas>
Upvotes: 3