为什么这里不画三角形?

Why isn't this drawing a triangle?

我不知道为什么我的 WebGL 代码没有在屏幕上绘制一个简单的三角形,而且我不确定如何调试它。 着色器能够编译,所以我相信这不是问题。

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>

你能给我指出正确的方向吗?几个小时以来,我一直在努力找出问题...

使用gl.LINE_LOOP代替gl.LINES

gl.drawArrays(gl.LINES, 0, 3)

gl.drawArrays(gl.LINE_LOOP, 0, 3)

gl.LINES 用于线段,其中 2 个顶点定义一条线。 gl.LINE_LOOP 用于从最后一个顶点到第一个顶点有连接的线带。参见 Primitives


您需要创建一个 Vertex Array Object when you using a WebGL 2.0 上下文:

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)

实际上您是在白色背景上绘制一个白色矩形。更改片段着色器中的颜色:

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>