无法在WebGL和Typescript中渲染球体

时间:2013-04-03 01:31:25

标签: webgl typescript

我已经移植了一些c代码,这些代码在opengl中为我正在处理的webgl / typescript项目渲染一个球体,但它没有正确渲染。我比较了c和ts版本之间的索引和顶点,它们似乎匹配。代码如下:

constructor(ctx: WebGLRenderingContext, stacks:number, 
                slices:number, scale: number){
    var vertices: number[] = [];
    var normals: number[] = [];
    var indices: number[] = [];

    var ii: number;
    var jj: number;
    var v: number;
    var u: number;

    normals.push(0, 0, 1);
    vertices.push(0, 0, scale);

    for (ii = 0; ii < slices; ++ii) {
        indices.push(0);
        indices.push(ii + 1);
    }
    indices.push(0);
    indices.push(1);

    for (ii = 1; ii < stacks; ++ii) {
        v = ii / stacks;
        for (jj = 0; jj < slices; ++jj) {
            u = jj / slices;
            normals.push.apply(normals, this.shapeNormal(u, v));
            vertices.push.apply(vertices, this.shapeVertex(scale, u, v));

            indices.push((ii - 1) * slices + (jj + 1));
            var index_offset: number = ((ii + 1) === stacks) ? 0 : jj;
            var second: number = ii * slices + (index_offset + 1);
            //console.log("Offset: " + String(index_offset) + " Value: " + String(second));
            indices.push(second);
        }
        indices.push((ii - 1) * slices + 1);
        indices.push(ii * slices + 1);
    }

    normals.push(0, 0, -1);
    vertices.push(0, 0, -scale);

    //console.log("Theoretical vertices: " + String(3 * (2 + slices * (stacks - 1))));

    //initialise vbos
    console.log("Vertices: " + String(vertices.length / 3));
    for(var l = 0; l < vertices.length; l += 3)
        console.log(vertices[l].toFixed(6) + " " + vertices[l+1].toFixed(6) + " " + vertices[l+2].toFixed(6));
    this.vertices = new VertexBufferObject(ctx, 3, vertices.length / 3);
    //console.log("Normals: " + String(normals.length));
    this.normals = new VertexBufferObject(ctx, 3, normals.length / 3);
    console.log("Indices: " + String(indices.length) + " " + indices.toString());
    this.indices = new VertexBufferObject(ctx, 1, indices.length);

    //populate vbo
    ctx.enableVertexAttribArray(0);
    ctx.bindBuffer(ctx.ARRAY_BUFFER, this.vertices.buffer);
    ctx.bufferData(ctx.ARRAY_BUFFER, new Float32Array(vertices), ctx.STATIC_DRAW);

    ctx.enableVertexAttribArray(1);
    ctx.bindBuffer(ctx.ARRAY_BUFFER, this.normals.buffer); 
    ctx.bufferData(ctx.ARRAY_BUFFER, new Float32Array(normals), ctx.STATIC_DRAW);

    ctx.bindBuffer(ctx.ELEMENT_ARRAY_BUFFER, this.indices.buffer);
    ctx.bufferData(ctx.ELEMENT_ARRAY_BUFFER, new Uint16Array(indices), 
                        ctx.STATIC_DRAW);

    ctx.bindBuffer(ctx.ARRAY_BUFFER, null);
    ctx.bindBuffer(ctx.ELEMENT_ARRAY_BUFFER, null);

    ctx.disableVertexAttribArray(0);
    ctx.disableVertexAttribArray(1);

    this.ctx = ctx;
}

private shapeVertex(r: number, u: number, v: number): number[] {
    /* Use maths rather than physics spherical coordinate convention */
    var theta: number = u * 2.0 * Math.PI;
    var phi: number = v * Math.PI;

    var vert: number[] = [
        r * Math.cos(theta) * Math.sin(phi),
        r * Math.sin(theta) * Math.sin(phi),
        r * Math.cos(phi)
    ];

    return vert;
}

private shapeNormal(u: number, v: number): number[] {
    /* Use maths rather than physics spherical coordinate convention */
    var theta: number = u * 2.0 * Math.PI;
    var phi: number = v * Math.PI;

    var norm: number[] = [
        Math.cos(theta) * Math.sin(phi),
        Math.sin(theta) * Math.sin(phi),
        Math.cos(phi)
    ];

    var mag: number = Math.sqrt(norm[0] * norm[0] + norm[1] * norm[1] + norm[2] * norm[2]);

    norm[0] /= mag;
    norm[1] /= mag;
    norm[2] /= mag;

    return norm;
}

public draw(shaderProgram: ShaderProgram): void {
    //bind and draw vbo's
    this.ctx.enableVertexAttribArray(0);
    this.ctx.bindBuffer(this.ctx.ARRAY_BUFFER, this.vertices.buffer);
    this.ctx.vertexAttribPointer(shaderProgram.attributes.position, 
                        this.vertices.itemSize, this.ctx.FLOAT, false, 0, 0);

    this.ctx.enableVertexAttribArray(1);
    this.ctx.bindBuffer(this.ctx.ARRAY_BUFFER, this.normals.buffer);
    this.ctx.vertexAttribPointer(shaderProgram.attributes.normal, 
                        this.normals.itemSize, this.ctx.FLOAT, false, 0, 0);

    this.ctx.bindBuffer(this.ctx.ELEMENT_ARRAY_BUFFER, this.indices.buffer);
    this.ctx.drawElements(this.ctx.TRIANGLES, this.indices.numItems, 
                        this.ctx.UNSIGNED_SHORT, 0);

    this.ctx.bindBuffer(this.ctx.ELEMENT_ARRAY_BUFFER, null);
    this.ctx.bindBuffer(this.ctx.ARRAY_BUFFER, null);

    this.ctx.disableVertexAttribArray(0);
    this.ctx.disableVertexAttribArray(1);
}

以及结果的屏幕截图:

Broken Sphere

提前谢谢

1 个答案:

答案 0 :(得分:0)

由于TypeScript只是Javascript的一部分,因此您的问题可能与Javascript处理代码计算的方式有关。

我不确定您的代码,因为您没有提供原始来源。 假设您的代码正确无误,您可能会遇到floating point approximation error