2011-10-31 96 views
1

我想使用GL_TRIANGLES在OpenGL中渲染一个球体。 这里是我用下面的代码得到的图像.. Bad Sphere连接球体顶点OpenGL

这应该是一个单位球体。

我都来源于基本近似球体的顶点从 wikipedia.

这里是我创建渲染单元球.. 请让我知道代码哪里我错了

void createGreenSphere(mat4 modelView){ 
    std::vector<Vertex> v; 
    int numSphereSlices = 12; 
    int numSphereSegments = 12; 
    float theta = 0; 
    float phi = 0; 
    float phiDelt = (2*PI)/numSphereSegments; 
    float thetaDelt = PI/numSphereSlices; 
    float* vertices = new float[numSphereSlices*numSphereSegments*4]; 
    float* normals = new float[numSphereSlices*numSphereSegments*4]; 
    float* colors = new float[numSphereSlices*numSphereSegments*3]; 
    int colorCnt = 0; 
    int vertCnt = 0; 
    for(int heightCnt = 0; heightCnt < numSphereSlices; heightCnt++){ 
    theta += thetaDelt; 
    phi = 0; 
    for(int widthCnt = 0; widthCnt < numSphereSegments; widthCnt++){ 
     phi += phiDelt; 
     vertices[vertCnt] = sin(theta)*cos(phi); 
     normals[vertCnt] = vertices[vertCnt]; 
     vertCnt++; 
     vertices[vertCnt] = sin(theta)*sin(phi); 
     normals[vertCnt] = vertices[vertCnt]; 
     vertCnt++; 
     vertices[vertCnt] = cos(theta); 
     normals[vertCnt] = vertices[vertCnt]; 
     vertCnt++; 
     vertices[vertCnt] = 1.0; 
     normals[vertCnt] = vertices[vertCnt]; 
     vertCnt++; 
     colors[colorCnt] = 0.0; 
     colorCnt++; 
     colors[colorCnt] = 1.0; 
     colorCnt++; 
     colors[colorCnt] = 0.0; 
     colorCnt++; 
    } 
    } 
    glBindBuffer(GL_ARRAY_BUFFER, vbo); 
    glBufferData(GL_ARRAY_BUFFER, vertCnt-1 * sizeof(float), vertices, GL_STATIC_DRAW);             
    glBindBuffer(GL_ARRAY_BUFFER, cbo); 
    glBufferData(GL_ARRAY_BUFFER, colorCnt-1 * sizeof(float), colors, GL_STREAM_DRAW);  

    glBindBuffer(GL_ARRAY_BUFFER, nbo); 
    glBufferData(GL_ARRAY_BUFFER, vertCnt-1 * sizeof(float), normals, GL_STATIC_DRAW); 

    unsigned short* indices = new unsigned short[numSphereSlices*numSphereSegments*6]; 
    int indexCnt = 0; 
    for (int i=0;i<numSphereSlices;i++){ 
    for(int j=0;j<numSphereSegments;j++){ 
     indices[indexCnt] = j + numSphereSegments*i; 
     indexCnt++; 
     indices[indexCnt] = j+1 + numSphereSegments*i; 
     indexCnt++; 
     indices[indexCnt] = numSphereSegments+j + numSphereSegments*i; 
     indexCnt++; 
     indices[indexCnt] = numSphereSegments+j+1 + numSphereSegments*i; 
     indexCnt++; 
     indices[indexCnt] = numSphereSegments+j + numSphereSegments*i; 
     indexCnt++; 
     indices[indexCnt] = j+1 + numSphereSegments*i; 
     indexCnt++; 
    } 
    } 

    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo);              
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, (numSphereSlices*numSphereSegments*6) *  sizeof(unsigned short), indices, GL_STATIC_DRAW); 

    delete [] indices; 

    glUniformMatrix4fv(u_modelMatrixLocation, 1, GL_FALSE, &modelView[0][0]); 

    glDrawElements(GL_TRIANGLES, numSphereSlices*numSphereSegments, GL_UNSIGNED_SHORT, 0); 


    glDisableVertexAttribArray(positionLocation); 
    glDisableVertexAttribArray(colorLocation); 
    glDisableVertexAttribArray(normalLocation); 
} 

我不确定问题出在创建顶点还是链接索引上。

+0

一切看起来都很好。我猜你的视图矩阵有问题。首先,尝试使用您现在使用的视图矩阵的转置。 –

+0

我不相信这是问题,我正在制作其他形状,例如立方体。 – Kyle

回答

3

复制和粘贴供您参考一些我最初编写的代码Creating a 3D sphere in Opengl using Visual C++

class SolidSphere 
{ 
protected 
    std::vector<GLfloat> vertices; 
    std::vector<GLfloat> normals; 
    std::vector<GLfloat> texcoords; 
    std::vector<GLushort> indices; 

public: 
    void SolidSphere(float radius, unsigned int rings, unsigned int sectors) 
    { 
     float const R = 1./(float)(rings-1); 
     float const S = 1./(float)(sectors-1); 
     int r, s; 

     sphere_vertices.resize(rings * sectors * 3); 
     sphere_normals.resize(rings * sectors * 3); 
     sphere_texcoords.resize(rings * sectors * 2); 
     std::vector<GLfloat>::iterator v = sphere_vertices.begin(); 
     std::vector<GLfloat>::iterator n = sphere_normals.begin(); 
     std::vector<GLfloat>::iterator t = sphere_texcoords.begin(); 
     for(r = 0; r < rings; r++) for(s = 0; s < sectors; s++) { 
       float const y = sin(-M_PI_2 + M_PI * r * R); 
       float const x = cos(2*M_PI * s * S) * sin(M_PI * r * R); 
       float const z = sin(2*M_PI * s * S) * sin(M_PI * r * R); 

       *t++ = s*S; 
       *t++ = r*R; 

       *v++ = x * radius; 
       *v++ = y * radius; 
       *v++ = z * radius; 

       *n++ = x; 
       *n++ = y; 
       *n++ = z; 
     } 

     sphere_indices.resize(rings * sectors * 4); 
     std:vector<GLushort>::iterator i = sphere_indices.begin(); 
     for(r = 0; r < rings; r++) for(s = 0; s < sectors; s++) { 
       *i++ = r * sectors + s; 
       *i++ = r * sectors + (s+1); 
       *i++ = (r+1) * sectors + (s+1); 
       *i++ = (r+1) * sectors + s; 
     } 
    } 
} 
+0

嗯,我仔细检查了我是如何创建索引的,其似乎与您的完全相同,除了有点不同之外,因为它使用的是三角形而不是四边形。以这种方式实现它,我仍然获得相同的输出。我不断思考创建顶点,但它看起来也和你一样,除了可能有点语法差异。任何其他建议? – Kyle