0

我已经移植了一些在 opengl 中为我正在处理的 webgl/typescript 项目渲染球体的 c 代码,但是它不能正确渲染。我比较了 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);
}

和结果截图:

破碎的球体

先感谢您

4

1 回答 1

0

由于 TypeScript 只是 Javascript 的替代品,因此您的问题可能与 Javascript 如何处理您的代码计算有关。

我不确定您的代码,因为您没有提供原始来源。假设您的代码是正确的,您可能会遇到浮点近似错误

于 2013-04-05T15:39:29.757 回答