Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to render sphere using open GL, c++ and not Glut/Glu [duplicate]

Tags:

c++

opengl

I am relatively new to OpenGL and C++ in general and I've been working on a custom framework in which I am asked to render spheres. I ve done research and managed to generate a somewhat-sphere made from points. I would like if possible to reform it so I can have an actual sphere made from triangles having properties such as radius. The code I used to generate sphere made from points is as follows:

Mesh* Mesh::GenerateSphere()
{

    const int Y_SEGMENT= 10;
    const int X_SEGMENT = 20;
    //const float count;


    Mesh*m = new Mesh();
    m->numVertices = (X_SEGMENT+1)*(Y_SEGMENT+1);
    m->type = GL_POINTS;
    m->vertices = new Vector3[m->numVertices];

    //s->GenerateTriangle();
    for (int i = 0; i < Y_SEGMENT+1;i++)
    {
        float angleY = PI*i / Y_SEGMENT;
        float y = cos(angleY);
        float xz = sin(angleY);

        for (int j = 0; j < X_SEGMENT+1; j++)
        {

            float angleX = 2*PI*j / X_SEGMENT;
            float x = xz*cos(angleX);
            float z = xz*sin(angleX);
            Vector3 v(x,y,z);
            m->vertices[i * (X_SEGMENT+1)+j] = v;
        }
    }
    m->BufferData();
    return m;
}
like image 347
Jim Rod Avatar asked Nov 15 '25 11:11

Jim Rod


1 Answers

Here's some code I wrote a long, long time ago. I've drawn the areas immediately surrounding the poles with a triangle-fan and the remainder of the sphere with quad-strips. You could of course, use triangles instead of the quads, but since the pairs of triangles would still be planar, it wont look any different, unless I'm mistaken - it's been a long times since I touched anything GL.

As molbdnilo points out, you'll get a better sphere by calculating your points in a different manner. If the intention is to texture-map the sphere, you'll get better results again if you subdivide and smooth a cube, since this avoids 'pinching' around the poles. Here's a good article that discusses this: http://www.iquilezles.org/www/articles/patchedsphere/patchedsphere.htm

I should also point-out that there's a problem with the way that I either calculate the normals, or transform then when rotating - I used to get funky lighting results when looking at the sphere when it was rotated. (I think it's with the normals) Also, looking at the just code now, I'm not sure that I've computed the number of vertices required correctly - you'll have to double-check that.It appears as though I don't store verts for either of the poles in the array.

EDIT: Here's a pic of the output:

enter image description here

typedef struct {
    GLfloat x, y, z;
}vec3;

void myGlutBall(float radius, int numStacks, int numSides)
{
//    vec3 points[sides * (sides-1)];
    GLfloat curRadius, curTheta, curRho, deltaTheta, deltaRho, curX,curY,curZ;
    int curStack, curSlice, numVerts = (numStacks-1)*numSides;
    vec3 points[numVerts];
    int curVert = 0;
    int t;

    deltaTheta = (2*M_PI) / numSides;
    deltaRho = M_PI / numStacks;

        for (curStack=1; curStack<numStacks; curStack++)
        {
            curRho = (3.141/2.0) - curStack*deltaRho;
            curY = sin(curRho) * radius;
            curRadius = cos(curRho) * radius;
            for (curSlice=0; curSlice<numSides; curSlice++)
            {
                curTheta = curSlice * deltaTheta;
                curX = curRadius * cos(curTheta);
                curZ = -curRadius * sin(curTheta);
                points[curVert++] = vec3{curX,curY,curZ};
            }
        }

    // option 1 - points only
    /*
    glBegin(GL_POINTS);
    glNormal3d(0,1,0);
    glVertex3d(0,radius,0);
    for (t=0; t<numVerts; t++)
    {
        curX = points[t].x;
        curY = points[t].y;
        curZ = points[t].z;
        glNormal3d(curX, curY, curZ);
        glVertex3d(curX, curY, curZ);
    }
    glNormal3d(0,-1,0);
    glVertex3d(0,-radius,0);
    glEnd();
    */

    ///////////////////////////////
    // option 2 - solid
    ///////////////////////////////
    // part A - draw the top 'lid' (tris)
    glBegin(GL_TRIANGLE_FAN);
        glNormal3d(0,1,0);
        glVertex3d(0,radius,0);
        for (t=0; t<numSides; t++)
        {
            curX = points[t].x;
            curY = points[t].y;
            curZ = points[t].z;
            glNormal3d(curX, curY, curZ);
            glVertex3d(curX, curY, curZ);
        }
            curX = points[0].x;
            curY = points[0].y;
            curZ = points[0].z;
        glNormal3d(curX, curY, curZ);
        glVertex3d(curX, curY, curZ);
    glEnd();

    // part B - draw the 'sides' (quads)
    int vertIndex;
    for (curStack=0; curStack<numStacks-2; curStack++)
    {
        vertIndex = curStack * numSides;
        glBegin(GL_QUAD_STRIP);
            for (curSlice=0; curSlice<numSides; curSlice++)
            {
                glNormal3d(points[vertIndex+curSlice].x, points[vertIndex+curSlice].y, points[vertIndex+curSlice].z);
                glVertex3d(points[vertIndex+curSlice].x, points[vertIndex+curSlice].y, points[vertIndex+curSlice].z);

                glNormal3d(points[vertIndex+numSides+curSlice].x, points[vertIndex+numSides+curSlice].y, points[vertIndex+numSides+curSlice].z);
                glVertex3d(points[vertIndex+numSides+curSlice].x, points[vertIndex+numSides+curSlice].y, points[vertIndex+numSides+curSlice].z);
            }
            glNormal3d(points[vertIndex].x, points[vertIndex].y, points[vertIndex].z);
            glVertex3d(points[vertIndex].x, points[vertIndex].y, points[vertIndex].z);
            glNormal3d(points[vertIndex+numSides].x, points[vertIndex+numSides].y, points[vertIndex+numSides].z);
            glVertex3d(points[vertIndex+numSides].x, points[vertIndex+numSides].y, points[vertIndex+numSides].z);
        glEnd();
    }

    // part C - draw the bottom 'lid' (tris)
    glBegin(GL_TRIANGLE_FAN);
        glNormal3d(0,-1,0);
        glVertex3d(0,-radius,0);
        for (t=0; t<numSides-1; t++)
        {
            curX = points[numVerts-1-t].x;
            curY = points[numVerts-1-t].y;
            curZ = points[numVerts-1-t].z;
            glNormal3d(curX, curY, curZ);
            glVertex3d(curX, curY, curZ);
        }
            curX = points[numVerts-1].x;
            curY = points[numVerts-1].y;
            curZ = points[numVerts-1].z;
        glNormal3d(curX, curY, curZ);
        glVertex3d(curX, curY, curZ);
    glEnd();

}
like image 173
enhzflep Avatar answered Nov 17 '25 09:11

enhzflep



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!