1 // sphere.cxx -- build an ssg sphere object
3 // Pulled straight out of MesaGLU/quadratic.c
5 // Original gluSphere code is Copyright (C) 1999-2000 Brian Paul and
6 // licensed under the GPL
8 // This library is free software; you can redistribute it and/or
9 // modify it under the terms of the GNU Library General Public
10 // License as published by the Free Software Foundation; either
11 // version 2 of the License, or (at your option) any later version.
13 // This library is distributed in the hope that it will be useful,
14 // but WITHOUT ANY WARRANTY; without even the implied warranty of
15 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 // Library General Public License for more details.
18 // You should have received a copy of the GNU Library General Public
19 // License along with this library; if not, write to the
20 // Free Software Foundation, Inc., 59 Temple Place - Suite 330,
21 // Boston, MA 02111-1307, USA.
26 #include <simgear/compiler.h>
27 #include <simgear/constants.h>
28 #include <simgear/debug/logstream.hxx>
36 // return a sphere object as an ssgBranch
37 ssgBranch *ssgMakeSphere( ssgSimpleState *state, ssgColourArray *cl,
38 double radius, int slices, int stacks,
39 ssgCallback predraw, ssgCallback postdraw )
41 float rho, drho, theta, dtheta;
46 ssgBranch *sphere = new ssgBranch;
50 drho = SGD_PI / (float) stacks;
51 dtheta = SGD_2PI / (float) slices;
53 /* texturing: s goes from 0.0/0.25/0.5/0.75/1.0 at +y/+x/-y/-x/+y
54 axis t goes from -1.0/+1.0 at z = -radius/+radius (linear along
55 longitudes) cannot use triangle fan on texturing (s coord. at
56 top/bottom tip varies) */
60 t = 1.0; /* because loop now runs from 0 */
64 /* build slices as quad strips */
65 for ( i = imin; i < imax; i++ ) {
66 ssgVertexArray *vl = new ssgVertexArray();
67 ssgNormalArray *nl = new ssgNormalArray();
68 ssgTexCoordArray *tl = new ssgTexCoordArray();
72 for ( j = 0; j <= slices; j++ ) {
73 theta = (j == slices) ? 0.0 : j * dtheta;
74 x = -sin(theta) * sin(rho);
75 y = cos(theta) * sin(rho);
78 // glNormal3f( x*nsign, y*nsign, z*nsign );
79 sgSetVec3( vec3, x*nsign, y*nsign, z*nsign );
80 sgNormalizeVec3( vec3 );
84 sgSetVec2( vec2, s, t );
87 // glVertex3f( x*radius, y*radius, z*radius );
88 sgSetVec3( vec3, x*radius, y*radius, z*radius );
91 x = -sin(theta) * sin(rho+drho);
92 y = cos(theta) * sin(rho+drho);
93 z = nsign * cos(rho+drho);
95 // glNormal3f( x*nsign, y*nsign, z*nsign );
96 sgSetVec3( vec3, x*nsign, y*nsign, z*nsign );
97 sgNormalizeVec3( vec3 );
100 // glTexCoord2f(s,t-dt);
101 sgSetVec2( vec2, s, t-dt );
105 // glVertex3f( x*radius, y*radius, z*radius );
106 sgSetVec3( vec3, x*radius, y*radius, z*radius );
111 new ssgVtxTable ( GL_TRIANGLE_STRIP, vl, nl, tl, cl );
113 if ( vl->getNum() != nl->getNum() ) {
114 SG_LOG( SG_EVENT, SG_ALERT, "bad sphere1");
117 if ( vl->getNum() != tl->getNum() ) {
118 SG_LOG( SG_EVENT, SG_ALERT, "bad sphere2");
121 slice->setState( state );
122 slice->setCallback( SSG_CALLBACK_PREDRAW, predraw );
123 slice->setCallback( SSG_CALLBACK_POSTDRAW, postdraw );
125 sphere->addKid( slice );