]> git.mxchange.org Git - simgear.git/blob - simgear/sky/sphere.cxx
Changes by David Megginson.
[simgear.git] / simgear / sky / sphere.cxx
1 // sphere.cxx -- build an ssg sphere object
2 //
3 // Pulled straight out of MesaGLU/quadratic.c
4 //
5 // Original gluSphere code is Copyright (C) 1999-2000  Brian Paul and
6 // licensed under the GPL
7 //
8 // This program is free software; you can redistribute it and/or
9 // modify it under the terms of the GNU General Public License as
10 // published by the Free Software Foundation; either version 2 of the
11 // License, or (at your option) any later version.
12 //
13 // This program is distributed in the hope that it will be useful, but
14 // WITHOUT ANY WARRANTY; without even the implied warranty of
15 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16 // General Public License for more details.
17 //
18 // You should have received a copy of the GNU General Public License
19 // along with this program; if not, write to the Free Software
20 // Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 //
22 // $Id$
23
24
25 #ifdef HAVE_CONFIG_H
26 #  include <config.h>
27 #endif
28
29 #include <plib/ssg.h>
30
31
32 // return a sphere object as an ssgBranch
33 ssgBranch *ssgMakeSphere( ssgSimpleState *state, ssgColourArray *cl,
34                           double radius, int slices, int stacks,
35                           ssgCallback predraw, ssgCallback postdraw )
36 {
37     float rho, drho, theta, dtheta;
38     float x, y, z;
39     float s, t, ds, dt;
40     int i, j, imin, imax;
41     float nsign = 1.0;
42     ssgBranch *sphere = new ssgBranch;
43     sgVec2 vec2;
44     sgVec3 vec3;
45
46     // handle cl whether it is preinitialized or not
47     if ( cl == NULL ) {
48         // create a new array if needed
49         cl = new ssgColourArray( 1 );
50     }
51
52     sgVec4 color;
53     sgSetVec4( color, 1.0, 1.0, 1.0, 1.0 );
54
55     if ( cl->getNum() > 1 ) {
56         cl->removeAll();
57         cl->add( color );
58     } else if ( cl->getNum() == 0 ) {
59         cl->add( color );
60     } else {
61         // accept value as given to us in
62     }
63
64     drho = M_PI / (float) stacks;
65     dtheta = 2.0 * M_PI / (float) slices;
66
67     /* texturing: s goes from 0.0/0.25/0.5/0.75/1.0 at +y/+x/-y/-x/+y
68        axis t goes from -1.0/+1.0 at z = -radius/+radius (linear along
69        longitudes) cannot use triangle fan on texturing (s coord. at
70        top/bottom tip varies) */
71
72     ds = 1.0 / slices;
73     dt = 1.0 / stacks;
74     t = 1.0;  /* because loop now runs from 0 */
75     imin = 0;
76     imax = stacks;
77
78     /* build slices as quad strips */
79     for ( i = imin; i < imax; i++ ) {
80         ssgVertexArray   *vl = new ssgVertexArray();
81         ssgNormalArray   *nl = new ssgNormalArray();
82         ssgTexCoordArray *tl = new ssgTexCoordArray();
83
84         rho = i * drho;
85         s = 0.0;
86         for ( j = 0; j <= slices; j++ ) {
87             theta = (j == slices) ? 0.0 : j * dtheta;
88             x = -sin(theta) * sin(rho);
89             y = cos(theta) * sin(rho);
90             z = nsign * cos(rho);
91
92             // glNormal3f( x*nsign, y*nsign, z*nsign );
93             sgSetVec3( vec3, x*nsign, y*nsign, z*nsign );
94             sgNormalizeVec3( vec3 );
95             nl->add( vec3 );
96
97             // glTexCoord2f(s,t);
98             sgSetVec2( vec2, s, t );
99             tl->add( vec2 );
100
101             // glVertex3f( x*radius, y*radius, z*radius );
102             sgSetVec3( vec3, x*radius, y*radius, z*radius );
103             vl->add( vec3 );
104
105             x = -sin(theta) * sin(rho+drho);
106             y = cos(theta) * sin(rho+drho);
107             z = nsign * cos(rho+drho);
108
109             // glNormal3f( x*nsign, y*nsign, z*nsign );
110             sgSetVec3( vec3, x*nsign, y*nsign, z*nsign );
111             sgNormalizeVec3( vec3 );
112             nl->add( vec3 );
113
114             // glTexCoord2f(s,t-dt);
115             sgSetVec2( vec2, s, t-dt );
116             tl->add( vec2 );
117             s += ds;
118
119             // glVertex3f( x*radius, y*radius, z*radius );
120             sgSetVec3( vec3, x*radius, y*radius, z*radius );
121             vl->add( vec3 );
122         }
123
124         ssgLeaf *slice = 
125             new ssgVtxTable ( GL_TRIANGLE_STRIP, vl, nl, tl, cl );
126         slice->setState( state );
127         slice->setCallback( SSG_CALLBACK_PREDRAW, predraw );
128         slice->setCallback( SSG_CALLBACK_POSTDRAW, postdraw );
129
130         sphere->addKid( slice );
131
132         t -= dt;
133     }
134
135     return sphere;
136 }