私が取り組んでいる webgl/typescript プロジェクトの opengl で球体をレンダリングするいくつかの 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);
}
結果のスクリーンショット:
前もって感謝します