webgl 实例没有显示任何内容

问题描述 投票:0回答:1

使用 twgl.js 来简化东西,但由于某种原因我收到此警告:

[.WebGL-000031BC01680600] GL_INVALID_OPERATION: Must have element array buffer bound.

屏幕上什么也没有出现。然而,使用 twgl.js 创建者的实例化示例效果非常好。目标是在屏幕上画出圆圈,每个圆圈都有自己的位置和大小。我不太使用 webgl,而且之前也没有做过实例,所以我不确定我哪里出错了

我也在用包裹

文件结构相当简单:

index.html
index.cjs
src/
 | renderer.cjs

渲染器.cjs:

const twgl = require("twgl.js")

const VERT_SHADER = `precision mediump float;

attribute vec2 points;
attribute vec2 position;
attribute float size;

uniform vec2 resolution;

void main() {
    vec2 transform = vec2((points * size + position) / resolution);
    vec2 clipSpace = transform * vec2(2.0, -2.0) - vec2(1.0, 1.0);
    gl_Position = vec4(clipSpace, 1.0, 1.0);
}`

const FRAG_SHADER = `precision mediump float;
 
void main() {
    gl_FragColor = vec4(0.19, 0.43, 0.69, 1.0);
}`


module.exports = class {
    arrays = {
        points: {
            numComponents: 2,
            data: [],
        },
        position: {
            numComponents: 2,
            data: [],
            divisor: 1,
        },
        size: {
            numComponents: 1,
            data: [],
            divisor: 1,
        }
    }

    constructor(canvas) {
        this.gl = canvas.getContext("webgl")
        twgl.addExtensionsToContext(this.gl)

        this.programInfo = twgl.createProgramInfo(this.gl, [VERT_SHADER, FRAG_SHADER])
    }

    setCircleSides(sides) {
        this.sides = sides
        const theta = 2 * Math.PI / sides

        let data = []

        // adding the vertices of the triangles in a circle
        for (let i = 0; i < sides; ++i) {
            data.push(
                0, 0,
                Math.cos(i * theta), Math.sin(i * theta),
                Math.cos((i + 1) * theta), Math.sin((i + 1) * theta),
            )
        }

        this.arrays.points.data = data
    }

    addCircle(x, y, size) {
        this.arrays.position.data.push(x, y)
        this.arrays.size.data.push(size)
    }

    updateBuffers() {
        this.bufferInfo = twgl.createBufferInfoFromArrays(this.gl, this.arrays)
        this.vertexArrayInfo = twgl.createVertexArrayInfo(this.gl, this.programInfo, this.bufferInfo)
    }

    render() {
        this.gl.canvas.width = innerWidth
        this.gl.canvas.height = innerHeight

        twgl.resizeCanvasToDisplaySize(this.gl.canvas)
        this.gl.viewport(0, 0, innerWidth, innerHeight)

        this.gl.clear(this.gl.COLOR_BUFFER_BIT | this.gl.DEPTH_BUFFER_BIT)

        const uniforms = {
            resolution: [innerWidth, innerHeight]
        }

        this.updateBuffers()

        this.gl.useProgram(this.programInfo.program)
        twgl.setBuffersAndAttributes(this.gl, this.programInfo, this.vertexArrayInfo)
        twgl.setUniforms(this.programInfo, uniforms)
        this.gl.drawElementsInstanced(this.gl.TRIANGLES, this.vertexArrayInfo.numElements, this.gl.UNSIGNED_SHORT, 0, this.arrays.size.data.length)
    }
}

index.cjs:

const Renderer = require("./src/renderer.cjs")

// using defer in the html, so it runs after elements are loaded
const canvas = document.querySelector("canvas")

function main() {
    const renderer = new Renderer(canvas)

    renderer.setCircleSides(8)

    for (let i = 0; i < 100; ++i) {
        renderer.addCircle(Math.random() * 200, Math.random() * 200, Math.random() * 10)
    }

    renderer.render()
}
main()

我尝试过的效果非常好的示例在这篇文章中:在 twgl.js 中使用实例扩展

javascript webgl twgl.js
1个回答
0
投票

您正在调用

drawElementsInstanced
,但您没有索引。致电
drawArraysInstanced

© www.soinside.com 2019 - 2024. All rights reserved.