Results 1 to 9 of 9
  1. #1
    Join Date
    May 2002
    Location
    UK
    Posts
    2,807

    Quick solution for making a sphere in OpenGL

    Hi,

    I'm currently working through the OpenGL VTMs (I've just got to the point where I've made the controls but haven't started on the particle engine).

    Anyway, I need to write a simulation program for my physics work, and I'm confident about almost all of it, except for making a sphere.

    I need to create a sphere, but I haven't got to the point where I could import a model of a sphere from Maya etc., and the only OpenGL code I could find on the internet used TWOPI and PID2 (whatever they are? lol) which my compiler didn't like, and I don't know how to implement.

    So, I was wondering,
    does anyone have a quick solution that I could use for making a simple sphere (texture mapped or not, prefferably texture mapped but it isn't vital). If I can specify a position then that would be good, but if I can't then I can simply use the modelview matrix and translate that around.

    If not, then what about getting the TWOPI and PID2 functionality to work... any ideas?

    Sorry if this sounds disjointed, I've gotta rush this to get out to lunch, lol.

    Thanks in advance,
    Steve

  2. #2
    Join Date
    Oct 2002
    Location
    Leicester, UK
    Posts
    3,335
    Forget the username, call me Keith

  3. #3
    Join Date
    Apr 2002
    Location
    Ottawa, Ont CANADA
    Posts
    224
    if you are using GLUT it is pretty easy


    Code:
    void glutSolidSphere(GLdouble radius,
                         GLint slices, GLint stacks);
    void glutWireSphere(GLdouble radius,
                        GLint slices, GLint stacks);

    radius
    The radius of the sphere.
    slices
    The number of subdivisions around the Z axis (similar to lines of longitude).
    stacks
    The number of subdivisions along the Z axis (similar to lines of latitude).

    Description

    Renders a sphere centered at the modeling coordinates origin of the specified radius. The sphere is subdivided around the Z axis into slices and along the Z axis into stacks.
    "Real programmers don't document. If it was hard to write, it should be hard to understand."



  4. #4
    Join Date
    May 2002
    Location
    UK
    Posts
    2,807
    keithathaide: Thanks for the code, that's the exact code I'd found earlier, which I'd really like to use, but can't because of the TWOPI and PID2 functionality, which I dunno how to get to work. Any ideas?

    zero_signal_69: I'm unfortunately not using GLUT, although I may well move over to GLUT if I can't make a sphere any other way.
    I think there might be a way to make a sphere using GLu, so I'm gonna look into that.

    Thanks for the replies,
    Steve

    EDIT:

    yup, it can be done with glu. Thanks to zero_signal for suggesting GLUT, that jogged my memory of the glu functions.

    Awesome, onto the serious programming now
    Last edited by stevetwist; 10-25-2005 at 09:12 AM.

  5. #5
    Join Date
    Jun 2003
    Location
    Trier, Germany
    Posts
    1,349
    TWOPI = 6,2831... (=2*Pi)

    PID2 = 1,57079... (=Pi/2)
    they can be defined either as globales or as preprocessor constants, whichever you prefer.

    remember that creating a sphere is nothing more than doing a transformation from spherical to cartesian coordinates

    anyway, stay with keiths tutorial (and try to really understand it!) and you'll be perfectly happy.

    if you're not familiar with the concept of spherical coordinates, you should check this article before starting.
    Last edited by ComicSansMS; 10-25-2005 at 09:44 AM.

  6. #6
    Join Date
    May 2002
    Location
    UK
    Posts
    2,807
    thanks ComicSansMS

    I was thinking that TWOPI etc. were functions like Sin or something. Now I get it (doh! hehe).

    Thanks for the link, I'll give that a thorough read.



    I managed to get a sphere using glu and it was all going so well, except for the physics part of my simulation. Remind me not to forget about momentum again, lol, I managed to have my sphere bouncing off the water surface rather than being slowed down by it, because I forgot about its momentum. AHHH! This is hurting my brain.... back to work

    here's a screenshot of my little app doing its thang:
    Attached Thumbnails Attached Thumbnails Click image for larger version. 

Name:	buoyancySim.jpg 
Views:	4178 
Size:	188.6 KB 
ID:	43679  

  7. #7
    Join Date
    Jan 2004
    Location
    South Pole
    Posts
    1,514
    Sorry I'm a little late, but..

    I just wanted to mention that you can also make a nice looking sphere by subdividing an icosahedron (complex 20-sided regular polyhedron, the more you subdivide it, the closer it gets to a smooth a sphere..) Have you seen the Epcot Center sphere thing in Disney World? It looks like that.

    Here's the code, based on the code in the OpenGL red book (chapter 2, the example at the end):
    Code:
    #include <math.h>
    
    #define X .525731112119133606 
    #define Z .850650808352039932
    
    static GLfloat vdata[12][3] = {    
        {-X, 0.0, Z}, {X, 0.0, Z}, {-X, 0.0, -Z}, {X, 0.0, -Z},    
        {0.0, Z, X}, {0.0, Z, -X}, {0.0, -Z, X}, {0.0, -Z, -X},    
        {Z, X, 0.0}, {-Z, X, 0.0}, {Z, -X, 0.0}, {-Z, -X, 0.0} 
    };
    static GLuint tindices[20][3] = { 
        {0,4,1}, {0,9,4}, {9,5,4}, {4,5,8}, {4,8,1},    
        {8,10,1}, {8,3,10}, {5,3,8}, {5,2,3}, {2,7,3},    
        {7,10,3}, {7,6,10}, {7,11,6}, {11,0,6}, {0,1,6}, 
        {6,1,10}, {9,0,11}, {9,11,2}, {9,2,5}, {7,2,11} };
    
    void normalize(GLfloat *a) {
        GLfloat d=sqrt(a[0]*a[0]+a[1]*a[1]+a[2]*a[2]);
        a[0]/=d; a[1]/=d; a[2]/=d;
    }
    
    void drawtri(GLfloat *a, GLfloat *b, GLfloat *c, int div, float r) {
        if (div<=0) {
            glNormal3fv(a); glVertex3f(a[0]*r, a[1]*r, a[2]*r);
            glNormal3fv(b); glVertex3f(b[0]*r, b[1]*r, b[2]*r);
            glNormal3fv(c); glVertex3f(c[0]*r, c[1]*r, c[2]*r);
        } else {
            GLfloat ab[3], ac[3], bc[3];
            for (int i=0;i<3;i++) {
                ab[i]=(a[i]+b[i])/2;
                ac[i]=(a[i]+c[i])/2;
                bc[i]=(b[i]+c[i])/2;
            }
            normalize(ab); normalize(ac); normalize(bc);
            drawtri(a, ab, ac, div-1, r);
            drawtri(b, bc, ab, div-1, r);
            drawtri(c, ac, bc, div-1, r);
            drawtri(ab, bc, ac, div-1, r);  //<--Comment this line and sphere looks really cool!
        }  
    }
    
    void drawsphere(int ndiv, float radius=1.0) {
        glBegin(GL_TRIANGLES);
        for (int i=0;i<20;i++)
            drawtri(vdata[tindices[i][0]], vdata[tindices[i][1]], vdata[tindices[i][2]], ndiv, radius);
        glEnd();
    }
    Call drawsphere with ndiv as the number of subdivisions, and of course the radius.

    As indicated in the code above, if you comment the fourth drawtri, the fourth subtriangle doesn't get drawn, and you get a cool serpinski-like pattern. Definitely try it out!
    Last edited by halma; 10-31-2005 at 03:59 PM.

  8. #8
    Join Date
    May 2002
    Location
    UK
    Posts
    2,807
    Awesome

    Thanks, I'll try it out, just for fun. It'll be interesting to try and work out how it works aswell.

  9. #9
    Join Date
    Jan 2004
    Location
    South Pole
    Posts
    1,514
    Nothing really special about how and why it works.. Here's a basic overview (don't read if you want to figure it out yourself):

    An icosahedron consists of 12 vertices and 20 triangle faces. vdata contains the coordinates of the 12 vertices, and tindices contains the indices of the vertices for each of the 20 triangle faces. You can draw the faces as they are, or, you could subdivide the triangles. Subdividing works by breaking each triangle into 4 triangles: you draw a new vertex at the center of each of the triangle's edges, and you connect these three together. You also normalize the new vertices (make them so that their distance from the center is 1 (or r), so that they lie on the sphere). The great thing about spheres is that the vertex coordinates are the same as the vertex normals, you just multiply by r (the radius). Subdivision works recursively through the drawtri function.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •