Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

calculating a sphere in opengl

I want to calculate all the vertices needed and connect them with lines, so I eventually come up with a sphere. How many ways are there to do it? And also the lines between the vertices, will be straight; how can I make them "curved" I know that I can use glutWireSphere(), but I am interested in actually calculating the vertices. A way that I thought about it, was to put all the vertices manually in an array, but I guess that is not the way it's done.

like image 477
Trt Trt Avatar asked Oct 30 '11 18:10

Trt Trt


3 Answers

Copy and Pasting some code I originally wrote in 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;
        }
    }

    void draw(GLfloat x, GLfloat y, GLfloat z)
    {
        glMatrixMode(GL_MODELVIEW);
        glPushMatrix();
        glTranslatef(x,y,z);

        glEnableClientState(GL_VERTEX_ARRAY);
        glEnableClientState(GL_NORMAL_ARRAY);
        glEnableClientState(GL_TEXTURE_COORD_ARRAY);

        glVertexPointer(3, GL_FLOAT, 0, &sphere_vertices[0]);
        glNormalPointer(GL_FLOAT, 0, &sphere_normals[0]);
        glTexCoordPointer(2, GL_FLOAT, 0, &sphere_texcoords[0]);
        glDrawElements(GL_QUADS, sphere_indices.size()/4, GL_UNSIGNED_SHORT, sphere_indices);
        glPopMatrix();
    }
}

how can I make them "curved"

You can't. All OpenGL primitives are "affine", i.e. planar or straight. Curvature is emulated by drawing short, straight sections with sufficient resolution.

like image 79
datenwolf Avatar answered Oct 07 '22 01:10

datenwolf


There's more than one way to do this: a) icosphere generation and b)UV sphere generation. There may be more methods to do this. Some googling got me this excellent post on icosphere generation. I couldn't find UV sphere generation method though.

like image 25
balajeerc Avatar answered Oct 07 '22 02:10

balajeerc


Paul Bourke actually has a nice introduction to sphere generation. And as for curved lines, there is no such thing in OpenGL. You can only make them appear curved by adding more intermediate connected points.

like image 30
Bart Avatar answered Oct 07 '22 01:10

Bart