连接球体顶点OpenGL

时间:2011-10-31 17:25:50

标签: c++ opengl geometry indices vertices

我正在尝试使用GL_TRIANGLES在OpenGL中渲染球体。 这是我用下面的代码得到的图像.. Bad Sphere

这应该是一个单位范围。

我从基本球体近似中导出了顶点 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);
 }

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

1 个答案:

答案 0 :(得分: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;
        }
    }
}