I don't know why my WebGL code is not drawing a simple triangle on the screen and I'm not sure how to debug it. The shaders are able to compile so I believe that's not the problem.
main.js:
const canvas = document.querySelector("#gl-canvas")
const gl = canvas.getContext('webgl2')
const consoleShaderCompilationErrors = (name, shader) => {
if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {
console.log(`${name} debug:`, gl.getShaderInfoLog(shader))
}
}
const vertexData = [
0, 0,
-0.5, 0.5,
0.5, 0.5
]
const vertexDataBuffer = gl.createBuffer()
gl.bindBuffer(gl.ARRAY_BUFFER, vertexDataBuffer)
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertexData), gl.STATIC_DRAW)
const vertexShader = gl.createShader(gl.VERTEX_SHADER)
gl.shaderSource(vertexShader, `
attribute vec3 position;
void main() {
gl_Position = vec4(position, 1);
}
`)
gl.compileShader(vertexShader)
consoleShaderCompilationErrors("vertexShader", vertexShader)
const fragmentShader = gl.createShader(gl.FRAGMENT_SHADER)
gl.shaderSource(fragmentShader, `
void main() {
gl_FragColor = vec4(1, 1, 1, 1);
}
`)
gl.compileShader(fragmentShader)
consoleShaderCompilationErrors("fragmentShader", fragmentShader)
const program = gl.createProgram()
gl.attachShader(program, vertexShader)
gl.attachShader(program, fragmentShader)
gl.linkProgram(program)
gl.useProgram(program)
const positionLocation = gl.getAttribLocation(program, "position")
gl.vertexAttribPointer(positionLocation, 2, gl.FLOAT, false, 0, 0)
gl.enableVertexAttribArray(positionLocation)
gl.drawArrays(gl.LINES, 0, 3)
index.html:
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title>Prod WebGL</title>
<style>
#gl-canvas {
border: 1px solid black;
}
</style>
<script src="./main.js" defer></script>
</head>
<body>
<canvas id="gl-canvas" width="400" height="400"></canvas>
</body>
</html>
Can you point me in the right direction? I have been trying to figure out the problems for hours now...
CodePudding user response:
Use gl.LINE_LOOP
instead of gl.LINES
:
gl.drawArrays(gl.LINES, 0, 3)
gl.drawArrays(gl.LINE_LOOP, 0, 3)
gl.LINES
is for line segments, where 2 vertices define a line. gl.LINE_LOOP
is for a line strip with a connection from the last to the first vertex. See Primitives.
You need to create a Vertex Array Object when you using a WebGL 2.0 context:
let vao = gl.createVertexArray();
gl.bindVertexArray(vao);
const vertexDataBuffer = gl.createBuffer()
gl.bindBuffer(gl.ARRAY_BUFFER, vertexDataBuffer)
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertexData), gl.STATIC_DRAW)
Actually you are drawing a white rectangle on a white background. Change the color in the fragment shader:
void main() {
gl_FragColor = vec4(1, 0, 0, 1);
}
const canvas = document.querySelector("#gl-canvas")
const gl = canvas.getContext('webgl2')
const consoleShaderCompilationErrors = (name, shader) => {
if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {
console.log(`${name} debug:`, gl.getShaderInfoLog(shader))
}
}
const vertexData = [
0, 0,
-0.5, 0.5,
0.5, 0.5
]
let vao = gl.createVertexArray();
gl.bindVertexArray(vao);
const vertexDataBuffer = gl.createBuffer()
gl.bindBuffer(gl.ARRAY_BUFFER, vertexDataBuffer)
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertexData), gl.STATIC_DRAW)
const vertexShader = gl.createShader(gl.VERTEX_SHADER)
gl.shaderSource(vertexShader, `
attribute vec3 position;
void main() {
gl_Position = vec4(position, 1);
}
`)
gl.compileShader(vertexShader)
consoleShaderCompilationErrors("vertexShader", vertexShader)
const fragmentShader = gl.createShader(gl.FRAGMENT_SHADER)
gl.shaderSource(fragmentShader, `
void main() {
gl_FragColor = vec4(1, 0, 0, 1);
}
`)
gl.compileShader(fragmentShader)
consoleShaderCompilationErrors("fragmentShader", fragmentShader)
const program = gl.createProgram()
gl.attachShader(program, vertexShader)
gl.attachShader(program, fragmentShader)
gl.linkProgram(program)
gl.useProgram(program)
const positionLocation = gl.getAttribLocation(program, "position")
gl.vertexAttribPointer(positionLocation, 2, gl.FLOAT, false, 0, 0)
gl.enableVertexAttribArray(positionLocation)
gl.drawArrays(gl.LINE_LOOP, 0, 3)
#gl-canvas {
border: 1px solid black;
}
<canvas id="gl-canvas" width="400" height="400"></canvas>