搞砸了球体

时间:2011-11-12 14:51:46

标签: c++ opengl

我正在尝试使用此处的最后一个算法绘制球体:http://paulbourke.net/miscellaneous/sphere_cylinder/。使用八面体。

这是我的算法:

struct Vertex {

    GLdouble position[3];
    GLfloat color[3];
    GLdouble normal[3];
};

struct XYZ {
    GLdouble x;
    GLdouble y;
    GLdouble z;
};

struct FACET3 {
    XYZ p1;
    XYZ p2;
    XYZ p3;
};

Vertex sphere_vertices_new[512];
FACET3 facet[512];

以上只是一些声明。

下面我计算所有内容,然后绘制线条:

void Normalise(XYZ *p_input)
{
    double magnitude = 0;
    magnitude = sqrt((p_input->x * p_input->x )+ (p_input->y * p_input->y) + (p_input->z * p_input->z));
    p_input->x = p_input->x / magnitude;
    p_input->y = p_input->y / magnitude;
    p_input->z = p_input->z / magnitude;

}

int CreateNSphere(FACET3 *f,int iterations)
{

   int i,it;
   double a;
   XYZ p[6] = {0,0,1,  0,0,-1,  -1,-1,0,  1,-1,0,  1,1,0, -1,1,0};
   XYZ pa,pb,pc;
   int nt = 0,ntold;

   /* Create the level 0 object */
   a = 1 / sqrt(2.0);
   for (i=0;i<6;i++) {
      p[i].x *= a;
      p[i].y *= a;
   }
   f[0].p1 = p[0]; f[0].p2 = p[3]; f[0].p3 = p[4];
   f[1].p1 = p[0]; f[1].p2 = p[4]; f[1].p3 = p[5];
   f[2].p1 = p[0]; f[2].p2 = p[5]; f[2].p3 = p[2];
   f[3].p1 = p[0]; f[3].p2 = p[2]; f[3].p3 = p[3];
   f[4].p1 = p[1]; f[4].p2 = p[4]; f[4].p3 = p[3];
   f[5].p1 = p[1]; f[5].p2 = p[5]; f[5].p3 = p[4];
   f[6].p1 = p[1]; f[6].p2 = p[2]; f[6].p3 = p[5];
   f[7].p1 = p[1]; f[7].p2 = p[3]; f[7].p3 = p[2];
   nt = 8;

   if (iterations < 1)
      return(nt);

   /* Bisect each edge and move to the surface of a unit sphere */
   for (it=0;it<iterations;it++) {

      ntold = nt;

      for (i=0;i<ntold;i++) {

         pa.x = (f[i].p1.x + f[i].p2.x) / 2;
         pa.y = (f[i].p1.y + f[i].p2.y) / 2;
         pa.z = (f[i].p1.z + f[i].p2.z) / 2;
         pb.x = (f[i].p2.x + f[i].p3.x) / 2;
         pb.y = (f[i].p2.y + f[i].p3.y) / 2;
         pb.z = (f[i].p2.z + f[i].p3.z) / 2;
         pc.x = (f[i].p3.x + f[i].p1.x) / 2;
         pc.y = (f[i].p3.y + f[i].p1.y) / 2;
         pc.z = (f[i].p3.z + f[i].p1.z) / 2;

         Normalise(&pa);
         Normalise(&pb);
         Normalise(&pc);

         f[nt].p1 = f[i].p1; f[nt].p2 = pa; f[nt].p3 = pc; 
         nt++;

         f[nt].p1 = pa; f[nt].p2 = f[i].p2; f[nt].p3 = pb; 
         nt++;

         f[nt].p1 = pb; f[nt].p2 = f[i].p3; f[nt].p3 = pc; 
         nt++;

         f[i].p1 = pa;
         f[i].p2 = pb;
         f[i].p3 = pc;
      }
   }

   return(nt);
}

void facet_to_vertex(FACET3 *f)
{
    int i=0;
    int a,b,c;
    int k=0;

    for (i=0;i<512;i++)
    {
        sphere_vertices_new[i].color[0] = 1.f;
        sphere_vertices_new[i].color[1] = 1.f;
        sphere_vertices_new[i].color[2] = 1.f;

    }

    for (i=0;i<512;i++)
    {
        //printf("The vertices (x,y,z) for facet %d are: V_1 =  x:%f , y:%f, z:%f. \n", i, f[i].p1.x, f[i].p1.y, f[i].p1.z);
        //printf("The vertices (x,y,z) for facet %d are: V_2 =  x:%f , y:%f, z:%f. \n", i, f[i].p2.x, f[i].p2.y, f[i].p2.z);
        //printf("The vertices (x,y,z) for facet %d are: V_3 =  x:%f , y:%f, z:%f. \n", i, f[i].p3.x, f[i].p3.y, f[i].p3.z);

        //For V_1   
        a=k;                                        
        sphere_vertices_new[a].position[0] = f[i].p2.x;
        sphere_vertices_new[a].position[1] = f[i].p2.y;     
        sphere_vertices_new[a].position[2] = f[i].p2.z; 
        printf(">>>%d \n", a);

                //For V_2
        b=k+1;
        sphere_vertices_new[b].position[0] = f[i].p1.y;
        sphere_vertices_new[b].position[1] = f[i].p1.y;
        sphere_vertices_new[b].position[2] = f[i].p1.y;
        printf(">>>%d \n", b);

                //For V_3
        c=k+2;
        sphere_vertices_new[c].position[0] = f[i].p3.z;
        sphere_vertices_new[c].position[1] = f[i].p3.z;
        sphere_vertices_new[c].position[2] = f[i].p3.z;     
        printf(">>>%d \n", c);
        k++;

    }


}

主要问题在于“facet_to_vertex”方法。我从构面中提取信息,然后在“sphere_vertices_new”数组中传递它。问题是如果我使用“GL_POINTS”它似乎是一个球体。但是当我使用GL_LINES,GL_LINE_STRIP或GL_TRIANGLES时,一切都搞砸了。

使用积分:

enter image description here

使用行:

enter image description here

编辑:绘图代码:

void SetupGemetry() {

    /* Allocate and assign One Vertex Buffer Object to our handle */
    glGenBuffers(1, &vbo);

    /* Bind our VBO as being the active buffer and storing vertex attributes (coordinates + colors) */
    glBindBuffer(GL_ARRAY_BUFFER, vbo);

    //MY CODE glBufferData...!!!!!!!!!!!!!!!!!!!!!!
    glBufferData ( GL_ARRAY_BUFFER, 512 * sizeof ( struct Vertex ), sphere_vertices_new, GL_STATIC_DRAW );

    /* Enable attribute index 0 as being used */
    glEnableVertexAttribArray( 0 );

    //MY CODE glVertexAttribPointer...! for the Sphere Vertices
    glVertexAttribPointer ( ( GLuint ) 0, 3, GL_DOUBLE, GL_FALSE, sizeof ( struct Vertex ), ( const GLvoid* ) offsetof
    (struct Vertex ,position) );    

    /* Enable attribute index 1 as being used */
    glEnableVertexAttribArray ( 1 );/* Bind our second VBO as being the active buffer and storing vertex attributes(colors) */

    /* Specify that our color data is going into attribute index 1, and contains three floats per vertex */
    /* Note stride = sizeof ( struct Vertex ) and pointer = ( const GLvoid* ) ( 3 * sizeof ( GLdouble ) ) i.e. the size
    (in bytes) occupied by the first attribute (position) */
    glVertexAttribPointer ( ( GLuint ) 1, 3, GL_FLOAT, GL_FALSE, sizeof ( struct Vertex ), ( const GLvoid* )
    offsetof(struct Vertex,color) );    
    }

void SetupShaders(void){

    /* Read our shaders into the appropriate buffers */
    vertexsource = filetobuf("tutorial3.vert");
    fragmentsource = filetobuf("tutorial3.frag");

    /* Assign our handles a "name" to new shader objects */
    vertexshader = glCreateShader(GL_VERTEX_SHADER);
    fragmentshader = glCreateShader(GL_FRAGMENT_SHADER);

    /* Associate the source code buffers with each handle */
    glShaderSource(vertexshader, 1, (const GLchar**)&vertexsource, 0);
    glShaderSource(fragmentshader, 1, (const GLchar**)&fragmentsource, 0);

    /* Compile our shader objects */
    glCompileShader(vertexshader);
    glCompileShader(fragmentshader);

    /* Assign our program handle a "name" */
    shaderprogram = glCreateProgram();
    glAttachShader(shaderprogram, vertexshader);/* Attach our shaders to our program */
    glAttachShader(shaderprogram, fragmentshader);

    /* Bind attribute 0 (coordinates) to in_Position and attribute 1 (colors) to in_Color*/
    glBindAttribLocation(shaderprogram, 0, "in_Position"); 
    glBindAttribLocation(shaderprogram, 1, "in_Color");
    //pass the normal to vertex shader  
    glBindAttribLocation(shaderprogram, 2, "in_Normal");

    /* Link our program, and set it as being actively used */
    glLinkProgram(shaderprogram);
    glUseProgram(shaderprogram);

}

void Render(int i) {

    GLfloat angle;

    //PROJECTION
    glm::mat4 Projection = glm::perspective(45.0f, 1.0f, 0.1f, 100.0f);
    angle = (GLfloat) (i/50 % 360); //to dia gia nan pio argo
    //printf("Angle: >>>> %f, \n", angle);  

    //VIEW
    glm::mat4 View = glm::mat4(1.);
    View = glm::translate(View, glm::vec3(0.f, 0.f, -4.0f)); // x, y, z position ? 
    View = glm::rotate(View, angle * -1.0f, glm::vec3(1.f, 0.f, 0.f));
    View = glm::rotate(View, angle * 0.5f, glm::vec3(0.f, 1.f, 0.f));
    View = glm::rotate(View, angle * 0.5f, glm::vec3(0.f, 0.f, 1.f));

    //MODEL
    glm::mat4 Model = glm::mat4(1.0);
    glm::mat4 MVP = Projection * View * Model;
    glUniformMatrix4fv(glGetUniformLocation(shaderprogram, "MVP_matrix"), 1, GL_FALSE, glm::value_ptr(MVP));

    //Transfer additional information to the vertex shader //mycode
    glm::mat4 MV = Model * View;
    glUniformMatrix4fv(glGetUniformLocation(shaderprogram, "MV_matrix"), 1, GL_FALSE, glm::value_ptr(MV));

    /* Bind our modelmatrix variable to be a uniform called mvpmatrix in our shaderprogram */
    glClearColor(0.0, 0.0, 0.0, 1.0);/* Make our background black */
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    glDrawArrays(GL_LINES, 0, 512);

}

0 个答案:

没有答案