【问题标题】:Draw a sphere using sectors and stack WebGL使用扇区绘制球体并堆叠 WebGL
【发布时间】:2019-11-04 06:33:48
【问题描述】:

我正在尝试使用扇区和堆栈算法绘制一个球体,但它什么也没输出,也不知道问题出在哪里。有什么帮助吗?

我按字面意思实现了算法:http://www.songho.ca/opengl/gl_sphere.html

除了 colouredShpere 函数外,一切都运行良好

这是我运行此功能时出现的照片:

您可以在以下位置找到完整代码:https://drive.google.com/open?id=1dnnkk1w7oq4O7hPTMeGRkyELwi4tcl5X

let mesh = createMesh(gl);

const PI = 3.1415926;
const r = 1.0;
const stackCount = 16;
const sectorCount = 16;

let x : number;
let y : number;
let z : number; 
let xy : number;

let vertices: number[] = new Array();
let normals : number[] = new Array();
let texCoords : number[] = new Array();

let nx: number;
let ny: number;
let nz: number; 
let lengthInv: number;
lengthInv = 1.0 / r;
let s: number;
let t: number;

let sectorStep = 2 * PI / sectorCount;
let stackStep = PI / stackCount;
let sectorAngle : number;
let stackAngle : number;

for(let i = 0; i<=stackCount; i++) {
    stackAngle = PI/2 - i*stackStep; //-90 to +90
    xy = r*Math.cos(stackAngle);
    z = r*Math.sin(stackAngle);

    for(let j = 0; j<=sectorCount; j++) {
        sectorAngle = j*sectorAngle; //0 to 360

        x = xy*Math.cos(sectorAngle);
        y = xy*Math.sin(sectorAngle);
        vertices.push(x);
        vertices.push(y);
        vertices.push(z);

        nx = x * lengthInv;
        ny = y * lengthInv;
        nz = z * lengthInv;
        normals.push(nx);
        normals.push(ny);
        normals.push(nz);

        // vertex tex coord (s, t) range between [0, 1]
        s = j / sectorCount;
        t = i / stackCount;
        texCoords.push(s);
        texCoords.push(t);
    }

}

// generate CCW index list of sphere triangles
// indices
//  k1--k1+1
//  |  / |
//  | /  |
//  k2--k2+1
let indices: number[] = new Array();
let k1 : number;
let k2 : number;
for(let i = 0; i<stackCount; i++) {
    k1 = i * (sectorCount + 1); //frist stack
    k2 = k1 + sectorCount + 1; //second stack
    for(let j = 0; j<sectorCount; j++) {
        //k1, k2, k1+1
        if(i != 0) {
            indices.push(k1);
            indices.push(k2);
            indices.push(k1+1);
        }

        //k1+1, k2, k2+1
        if(i != (stackCount-1)) {
            indices.push(k1+1);
            indices.push(k2);
            indices.push(k2+1);
        }
    }
}

mesh.setBufferData("positions", new Float32Array(vertices), gl.STATIC_DRAW);
//mesh.setBufferData("colors", new Uint8Array(), gl.STATIC_DRAW);
mesh.setElementsData(new Uint32Array(indices), gl.STATIC_DRAW);

//mesh.setBufferData("colors", new Uint8Array(), gl.STATIC_DRAW);
return mesh;

【问题讨论】:

    标签: webgl


    【解决方案1】:

    建议:学习如何使用console.log和浏览器的debugger

    我没有检查您的代码是否真的有效,但我确实在您上面发布的内容的底部添加了这些行

    console.log(vertices);
    console.log(indices);
    

    我看到的是

    所有那些NaN 值显然是错误的

    单步执行代码来到这一行

    sectorAngle = j*sectorAngle; //0 to 360
    

    这是生成NaN 的地方

    与您链接到的文章不匹配

    sectorAngle = j * sectorStep;           // starting from 0 to 2pi
    

    这是否是我不知道的唯一问题,但如果还有更多问题,请使用console.log 和调试器来帮助查找问题。使代码更易于调试的一种方法是将 stackCountsectorCount 分别设置为 4 和 2 之类的小值,然后您应该知道所有值应该是什么,并且可以与得到的值进行比较。

    【讨论】:

    • 谢谢。这正是我注意到的,所以我编辑了代码,终于成功了!
    【解决方案2】:

    如果有人有兴趣了解解决方案,这是经过一些改进后的代码: `

    let mesh = createMesh(gl);
    const PI = 3.1415926;
    const r = 1.0;
    
    let vertices = [];
    let colors  = [];
    
    for(let i = 0; i<=verticalResolution; ++i) {
        let theta = i * Math.PI / verticalResolution; //-90 to 90
        let sinTheta = Math.sin(theta);
        let cosTheta = Math.cos(theta);
    
        for(let j = 0; j<=horizontalResolution; ++j) {
            let phi = j * 2 * Math.PI / horizontalResolution; //0 to 360
            let sinPhi = Math.sin(phi);
            let cosPhi = Math.cos(phi);
    
            let x = sinTheta*cosPhi;
            let y = cosTheta;
            let z = sinTheta*sinPhi;
    
            vertices.push(r*x);
            vertices.push(r*y);
            vertices.push(r*z);
    
            colors.push((x+1)/2*255);
            colors.push((y+1)/2*255);
            colors.push((z+1)/2*255);
            colors.push(255);
        }
    
    }
    
    // generate CCW index list of sphere triangles
    // indices
    //  k1--k1+1
    //  |  / |
    //  | /  |
    //  k2--k2+1
    let indices = [];
    for(let i = 0; i<verticalResolution; ++i) {
        for(let j = 0; j<horizontalResolution; ++j) {
            let first = (i * (horizontalResolution + 1)) + j;
            let second = first + horizontalResolution + 1;
    
            indices.push(first);
            indices.push(second);
            indices.push(first+1);
    
            indices.push(second);
            indices.push(second+1);
            indices.push(first+1);
        }
    }
    
    mesh.setBufferData("positions", new Float32Array(vertices), gl.STATIC_DRAW);
    mesh.setBufferData("colors", new Uint8Array(colors), gl.STATIC_DRAW);
    mesh.setElementsData(new Uint32Array(indices), gl.STATIC_DRAW);
    return mesh;`
    

    Output of the code

    【讨论】:

      猜你喜欢
      • 2012-05-19
      • 2016-08-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-02-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多