2012-01-22 26 views
0

OpenGLで球を描きます。 このプログラムは、 "SLIED = STACK"のときに球を描くことができます。 しかし、「SLIED not equal STACK」のときは機能しません。 「インデックス配列」と間違えている可能性があります。OpenGLを使って球を描く

私はVBOとDMA(Dynamic memory allocate.use flat array)を使いたいです。 しかしあなたに別の良い考えがあるなら、教えてください。

  //#pragma comment(linker, "/SUBSYSTEM:WINDOWS /ENTRY:mainCRTStartup") 
      #pragma comment(lib,"glew32.lib") 

      #include <gl/glew.h> 
      #include <math.h> 
      #include <GL/freeglut/freeglut.h> 
      #define WIDTH 640 
      #define HEIGHT 480 
      #define M_PI 3.14159265358979323846 

      float angle=0.0f; 

      //functions----------------------------------------------// 
      void Shere_dma(double radius, int nSlice, int nStack); 
      void setSphereData(double radius, int nSlice, int nStack); 
      void DrawSphereVBO(void); 
      //-------------------------------------------------------// 

      //variabless---------------------------------------------// 
      int SLICE=0; 
      int STACK=0; 

      GLuint SVboId[3]; 
      GLfloat* Svertex;//Vertex 
      GLfloat* Snormal;//Normal 
      GLfloat* Scolor; //Color 

      GLuint* indices_top; //TOP indices 
      GLuint* indices_bottom; //BOTTOM indies 
      GLuint* indices_side; //SIDE indices 
      //-------------------------------------------------------// 

      //Memory Allocate 
      void Shere_dma(double radius, int nSlice, int nStack){ 
       Svertex = new GLfloat[(nSlice+1)*(nStack+1)*3]; 
       Snormal = new GLfloat[(nSlice+1)*(nStack+1)*3]; 
       Scolor = new GLfloat[(nSlice+1)*(nStack+1)*3]; 

       indices_top = new GLuint[(nSlice+1)*(nStack+1)*3]; 
       indices_bottom = new GLuint[(nSlice+1)*(nStack+1)*3]; 
       indices_side = new GLuint[(nSlice+1)*(nStack+1)*4]; 
      } 
      //inputData 
      void setSphereData(double radius, int nSlice, int nStack){ 
       double phi; //Azimuth 
       double theta; //long 

       int coordinates=0; 
       int Slice_current_point_no=0; 
       int Slice_next_point_no=0; 

       const int x = 0; 
       const int y = 1; 
       const int z = 2; 

       const int p1 = 0; 
       const int p2 = 1; 
       const int p3 = 2; 
       const int p4 = 3; 

       //Vertex 
       for(int i = 0;i <= nSlice;i++) 
       { 
        phi = 2.0 * M_PI * (double)i/(double)nSlice; 
        for(int j = 0;j <= nStack;j++) 
        { 
         theta = M_PI * (double)j/(double)nStack; 
         Svertex[coordinates+x] = (float)(radius * sin(theta) * cos(phi)); //x 
         Svertex[coordinates+y] = (float)(radius * sin(theta) * sin(phi)); //y 
         Svertex[coordinates+z] = (float)(radius * cos(theta));    //z 

         Snormal[coordinates+x] = (float)(radius * sin(theta) * cos(phi)); //x 
         Snormal[coordinates+y] = (float)(radius * sin(theta) * sin(phi)); //y 
         Snormal[coordinates+z] = (float)(radius * cos(theta));    //z 

         Scolor[coordinates+x] = 1.0;           //x 
         Scolor[coordinates+y] = 0.0;           //y 
         Scolor[coordinates+z] = 0.0;           //z 

         coordinates += 3;   
        } 
       } 

       //TOP 
       coordinates = 0; 
       Slice_current_point_no = 0; 
       Slice_next_point_no = nSlice; 

       for(int i = 0; i < nSlice; i++){ 

        indices_top[coordinates+p1] = Slice_current_point_no; 
        indices_top[coordinates+p2] = indices_top[coordinates]+1; 
        indices_top[coordinates+p3] = Slice_next_point_no+2; 

        coordinates+=3; 
        Slice_current_point_no += nSlice+1; 
        Slice_next_point_no += nSlice+1; 
       } 

       //BOTTOM 
       coordinates =0; 
       Slice_current_point_no = 0; 
       Slice_next_point_no  = nSlice; 

       for(int i = 0; i < nSlice; i++){ 

        indices_bottom[coordinates+p1] = Slice_current_point_no+(nStack-1); 
        indices_bottom[coordinates+p2] = indices_bottom[coordinates]+1; 
        indices_bottom[coordinates+p3] = Slice_next_point_no+(nStack); 

        coordinates+=3; 
        Slice_current_point_no += nSlice+1; 
        Slice_next_point_no += nSlice+1; 
       } 
       //↓May be wrong ********************************************************************************// 
       //SIDE 
       coordinates=0; 
       Slice_current_point_no = 0; 
       Slice_next_point_no = nSlice+1; 

       for(int i=0; i < nSlice;i++){ 
        for(int j=1; j < nStack-1; j++){ 
         indices_side[coordinates+p1] = Slice_current_point_no+j; 
         indices_side[coordinates+p2] = indices_side[coordinates]+1; 
         indices_side[coordinates+p3] = Slice_next_point_no+(j+1); 
         indices_side[coordinates+p4] = Slice_next_point_no+j; 
         coordinates+=4; 
        } 
         Slice_current_point_no += nSlice+1; 
         Slice_next_point_no += nSlice+1; 
       } 
       //↑May be wrong ********************************************************************************// 
       glGenBuffers(3,&SVboId[0]); 

       //Vertex 
       glBindBuffer(GL_ARRAY_BUFFER,SVboId[0]); 
       glBufferData(GL_ARRAY_BUFFER,sizeof(GLfloat)*(nSlice+1)*(nStack+1)*3, 
        Svertex,GL_DYNAMIC_DRAW); 

       //Normal 
       glBindBuffer(GL_ARRAY_BUFFER,SVboId[1]); 
       glBufferData(GL_ARRAY_BUFFER,sizeof(GLfloat)*(nSlice+1)*(nStack+1)*3, 
        Snormal,GL_DYNAMIC_DRAW); 

       //Color 
       glBindBuffer(GL_ARRAY_BUFFER,SVboId[2]); 
       glBufferData(GL_ARRAY_BUFFER,sizeof(GLfloat)*(nSlice+1)*(nStack+1)*3, 
        Scolor,GL_STREAM_DRAW); 

      } 

      //Draw 
      void DrawSphereVBO(void) 
      { 
       int point=0; 

       //Enable 
       glEnableClientState(GL_VERTEX_ARRAY); 
       glEnableClientState(GL_NORMAL_ARRAY); 
       glEnableClientState(GL_COLOR_ARRAY); 

       //Vertex 
       glBindBuffer(GL_ARRAY_BUFFER,SVboId[0]); 
       glVertexPointer(3, GL_FLOAT, 0, 0); 

       //Normal 
       glBindBuffer(GL_ARRAY_BUFFER,SVboId[1]); 
       glNormalPointer(GL_FLOAT, 0, 0); 

       //Color 
       glBindBuffer(GL_ARRAY_BUFFER,SVboId[2]); 
       glColorPointer(3,GL_FLOAT, 0, 0); 

       //---------------------------------Draw---------------------------------------------------// 

       //TOP 
       for(int i=0; i<SLICE;i++){ 
        glDrawRangeElements(GL_TRIANGLES, point, point+2, 3, GL_UNSIGNED_INT, indices_top+i*3); 
        point+=3; 
       } 

       //BOTTOM 
       point=0; 
       for(int i=0; i<SLICE;i++){ 
        glDrawRangeElements(GL_TRIANGLES, point, point+2, 3, GL_UNSIGNED_INT, indices_bottom+i*3); 
        point+=3; 
       } 


       //↓May be wrong ********************************************************************************// 
       //SIDE 
       point=0; 
       for(int i=0; i< (SLICE*(STACK-2));i++){ 
        glDrawRangeElements(GL_QUADS, point, point+3, 4, GL_UNSIGNED_INT, indices_side+i*4); 
        point+=4; 
       } 
       //↑May be wrong ********************************************************************************// 

       //---------------------------------Draw---------------------------------------------------// 

       //Disable 
       glDisableClientState(GL_COLOR_ARRAY); 
       glDisableClientState(GL_NORMAL_ARRAY); 
       glDisableClientState(GL_VERTEX_ARRAY); 

      } 

      void display(void) 
      { 
      glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 
      glViewport(0,0,WIDTH,HEIGHT); 
      glMatrixMode(GL_PROJECTION); 
      glLoadIdentity(); 
      gluPerspective(30.0, (double)WIDTH/(double)HEIGHT, 1.0, 1000.0); 
      glMatrixMode(GL_MODELVIEW); 
      glLoadIdentity(); 
      gluLookAt(5.0, 5.0,5.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0); 

      glRotatef(angle,0.0f,1.0f,0.0f); 

      DrawSphereVBO(); 

      glutSwapBuffers(); 
      } 
      void idle(void) 
      { 
      glutPostRedisplay(); 
      angle+=0.2f; 
      } 
      void Init(){ 
      glewInit(); 
      glClearColor(1.0, 1.0, 1.0, 1.0); 
      glEnable(GL_DEPTH_TEST); 
      glColorMaterial(GL_FRONT,GL_AMBIENT_AND_DIFFUSE); 
      glEnable(GL_COLOR_MATERIAL); 
      glEnable(GL_LIGHT0); 
      glEnable(GL_LIGHTING); 
      glEnable(GL_NORMALIZE); 


      SLICE = 5; 
      STACK = 5; 
      Shere_dma(1,SLICE,STACK);  //MemoryAllocate 
      setSphereData(1,SLICE,STACK); //InputData 

      } 

      int main(int argc, char *argv[]) 
      { 
      glutInitWindowPosition(100, 100); 
      glutInitWindowSize(WIDTH, HEIGHT); 
      glutInit(&argc, argv); 
      glutCreateWindow("VBO"); 
      glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE); 
      glutDisplayFunc(display); 
      glutIdleFunc(idle); 
      Init(); 
      glutMainLoop(); 
      return 0; 
      } 

私はこのコードを参照しています。

 void drawSphere(double radius, int nSlice, int nStack) 
     { 
      int i, j; 
      double phi; // 
      double theta; //long 
      float p[31][31][3]; //Vertex 
      float *p1,*p2,*p3,*p4; 

      if(nSlice > 30) nSlice = 30; 
      if(nStack > 30) nStack = 30; 

      //Vertex 
      for(i = 0;i <= nSlice;i++) 
      { 
       phi = 2.0 * M_PI * (double)i/(double)nSlice; 
       for(j = 0;j <= nStack;j++) 
       { 
        theta = M_PI * (double)j/(double)nStack; 
        p[i][j][0] = (float)(radius * sin(theta) * cos(phi));//x 
        p[i][j][1] = (float)(radius * sin(theta) * sin(phi));//y 
        p[i][j][2] = (float)(radius * cos(theta));   //z 
       } 
      } 

      //Top(j=0) 
      for(i = 0;i < nSlice; i++) 
      { 
       p1 = p[i][0];  p2 = p[i][1]; 
       p3 = p[i+1][1]; 
       glBegin(GL_TRIANGLES); 
        glNormal3fv(p1); glVertex3fv(p1); 
        glNormal3fv(p2); glVertex3fv(p2); 
        glNormal3fv(p3); glVertex3fv(p3); 
       glEnd(); 
      } 
      //Bottom 
      j=nStack-1; 
      for(i = 0;i < nSlice; i++) 
      { 
       p1 = p[i][j];  p2 = p[i][j+1]; 
       p3 = p[i+1][j]; 
       glBegin(GL_TRIANGLES); 
        glNormal3fv(p1); glVertex3fv(p1); 
        glNormal3fv(p2); glVertex3fv(p2); 
        glNormal3fv(p3); glVertex3fv(p3); 
       glEnd(); 
      } 

      for(i = 0;i < nSlice;i++){ 
       for(j = 1;j < nStack-1; j++) 
       { 
        p1 = p[i][j];  p2 = p[i][j+1]; 
        p3 = p[i+1][j+1]; p4 = p[i+1][j]; 
        glBegin(GL_QUADS); 
         glNormal3fv(p1); glVertex3fv(p1); 
         glNormal3fv(p2); glVertex3fv(p2); 
         glNormal3fv(p3); glVertex3fv(p3); 
         glNormal3fv(p4); glVertex3fv(p4); 
        glEnd(); 
       } 
      } 
     } 

答えて

0

私は2つの角度PHI(標高)とシータ(程度)又は球の方程式を使用してを使用して、球面座標を使用してお勧めします:

x2 + y2 + z2 = r2
は、Uは一定の値のいずれかを維持し、uは置き換えるように後で増分ました2番目の値を見つけるために2番目の値。

2

私は、球体メッシュの生成に関するチュートリアルを書いています。これはソースコードには含まれていませんが、そのプロセスを説明し、遭遇する問題を説明します。チュートリアルはhttp://sol.gfxile.net/sphere/index.html

にあります。
関連する問題