4 * Freeglut geometry rendering methods.
6 * Copyright (c) 1999-2000 Pawel W. Olszta. All Rights Reserved.
7 * Written by Pawel W. Olszta, <olszta@sourceforge.net>
8 * Creation date: Fri Dec 3 1999
10 * Permission is hereby granted, free of charge, to any person obtaining a
11 * copy of this software and associated documentation files (the "Software"),
12 * to deal in the Software without restriction, including without limitation
13 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
14 * and/or sell copies of the Software, and to permit persons to whom the
15 * Software is furnished to do so, subject to the following conditions:
17 * The above copyright notice and this permission notice shall be included
18 * in all copies or substantial portions of the Software.
20 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
21 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
23 * PAWEL W. OLSZTA BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
24 * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
25 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
32 #define G_LOG_DOMAIN "freeglut-geometry"
34 #include "../include/GL/freeglut.h"
35 #include "../include/GL/freeglut_internal.h"
38 * TODO BEFORE THE STABLE RELEASE:
40 * Following functions have been contributed by Andreas Umbach. I modified
41 * them a bit to make them use GLib (for memory allocation).
43 * glutWireCube() -- could add normal vectors so that lighting works
44 * glutSolidCube() -- OK
45 * glutWireSphere() -- OK
46 * glutSolidSphere() -- OK
48 * Following functions have been implemented by me:
50 * glutWireCone() -- looks OK
51 * glutSolidCone() -- normals are missing, there are holes in the thing
53 * Those functions need to be implemented, as nothing has been done yet.
54 * For now all of them draw a wire or solid cube, just to mark their presence.
58 * glutWireDodecahedron() --
59 * glutSolidDodecahedron() --
60 * glutWireOctahedron() --
61 * glutSolidOctahedron() --
62 * glutWireTetrahedron() --
63 * glutSolidTetrahedron() --
64 * glutWireIcosahedron() --
65 * glutSolidIcosahedron() --
69 /* -- INTERFACE FUNCTIONS -------------------------------------------------- */
72 * Draws a wireframed cube. Code contributed by Andreas Umbach <marvin@dataway.ch>
74 void FGAPIENTRY glutWireCube( GLdouble dSize )
76 float size = (float) dSize * 0.5f;
78 # define V(a,b,c) glVertex3f( a size, b size, c size );
81 * PWO: I dared to convert the code to use macros...
83 glBegin( GL_LINE_LOOP ); V(-,-,+); V(+,-,+); V(+,+,+); V(-,+,+); glEnd();
84 glBegin( GL_LINE_LOOP ); V(-,-,-); V(-,+,-); V(+,+,-); V(+,-,-); glEnd();
86 V(-,-,+); V(-,-,-); V(-,+,+); V(-,+,-);
87 V(+,-,+); V(+,-,-); V(+,+,+); V(+,+,-);
94 * Draws a solid cube. Code contributed by Andreas Umbach <marvin@dataway.ch>
96 void FGAPIENTRY glutSolidCube( GLdouble dSize )
98 float size = (float) dSize * 0.5f;
100 # define V(a,b,c) glVertex3f( a size, b size, c size );
101 # define N(a,b,c) glNormal3f( a, b, c );
104 * PWO: Again, I dared to convert the code to use macros...
107 N( 1, 0, 0); V(+,-,+); V(+,-,-); V(+,+,-); V(+,+,+);
108 N( 0, 1, 0); V(+,+,+); V(+,+,-); V(-,+,-); V(-,+,+);
109 N( 0, 0, 1); V(+,+,+); V(-,+,+); V(-,-,+); V(+,-,+);
110 N(-1, 0, 0); V(-,-,+); V(-,+,+); V(-,+,-); V(-,-,-);
111 N( 0,-1, 0); V(-,-,+); V(-,-,-); V(+,-,-); V(+,-,+);
112 N( 0, 0,-1); V(-,-,-); V(-,+,-); V(+,+,-); V(+,-,-);
120 * Draws a wire sphere. Code contributed by Andreas Umbach <marvin@dataway.ch>
122 void FGAPIENTRY glutWireSphere( GLdouble dRadius, GLint slices, GLint stacks )
124 float radius = (float) dRadius, phi, psi, dpsi, dphi;
129 * Allocate the vertices array
131 vertex = calloc( sizeof(float), 3 * slices * (stacks - 1) );
134 glScalef( radius, radius, radius );
136 dpsi = M_PI / (stacks + 1);
137 dphi = 2 * M_PI / slices;
140 for( j=0; j<stacks-1; j++ )
144 for( i=0; i<slices; i++ )
146 *(vertex + 3 * j * slices + 3 * i + 0) = sin( phi ) * sin( psi );
147 *(vertex + 3 * j * slices + 3 * i + 1) = cos( phi ) * sin( psi );
148 *(vertex + 3 * j * slices + 3 * i + 2) = cos( psi );
150 glVertex3fv( vertex + 3 * j * slices + 3 * i );
156 for( i=0; i<slices; i++ )
158 glBegin( GL_LINE_STRIP );
159 glNormal3f( 0, 0, 1 );
160 glVertex3f( 0, 0, 1 );
162 for( j=0; j<stacks - 1; j++ )
164 glNormal3fv( vertex + 3 * j * slices + 3 * i );
165 glVertex3fv( vertex + 3 * j * slices + 3 * i );
168 glNormal3f(0, 0, -1);
169 glVertex3f(0, 0, -1);
173 for( j=0; j<stacks-1; j++ )
175 glBegin(GL_LINE_LOOP);
177 for( i=0; i<slices; i++ )
179 glNormal3fv( vertex + 3 * j * slices + 3 * i );
180 glVertex3fv( vertex + 3 * j * slices + 3 * i );
191 * Draws a solid sphere. Code contributed by Andreas Umbach <marvin@dataway.ch>
193 void FGAPIENTRY glutSolidSphere( GLdouble dRadius, GLint slices, GLint stacks )
195 float radius = (float) dRadius, phi, psi, dpsi, dphi;
196 float *next, *tmp, *row;
200 //glScalef( radius, radius, radius );
202 row = calloc( sizeof(float), slices * 3 );
203 next = calloc( sizeof(float), slices * 3 );
205 dpsi = M_PI / (stacks + 1);
206 dphi = 2 * M_PI / slices;
210 /* init first line + do polar cap */
211 glBegin( GL_TRIANGLE_FAN );
212 glNormal3f( 0, 0, 1 );
213 glVertex3f( 0, 0, radius );
215 for( i=0; i<slices; i++ )
217 row[ i * 3 + 0 ] = sin( phi ) * sin( psi );
218 row[ i * 3 + 1 ] = cos( phi ) * sin( psi );
219 row[ i * 3 + 2 ] = cos( psi );
221 glNormal3fv( row + 3 * i );
223 radius * *(row + 3 * i + 0),
224 radius * *(row + 3 * i + 1),
225 radius * *(row + 3 * i + 2)
232 glVertex3f( radius * *(row + 0), radius * *(row + 1), radius * *(row + 2) );
235 for( j=0; j<stacks-1; j++ )
241 glBegin( GL_QUAD_STRIP );
243 /* glBegin(GL_LINE_LOOP); */
244 for( i=0; i<slices; i++ )
246 next[ i * 3 + 0 ] = sin( phi ) * sin( psi );
247 next[ i * 3 + 1 ] = cos( phi ) * sin( psi );
248 next[ i * 3 + 2 ] = cos( psi );
250 glNormal3fv( row + i * 3 );
252 radius * *(row + 3 * i + 0),
253 radius * *(row + 3 * i + 1),
254 radius * *(row + 3 * i + 2)
257 glNormal3fv( next + i * 3 );
259 radius * *(next + 3 * i + 0),
260 radius * *(next + 3 * i + 1),
261 radius * *(next + 3 * i + 2)
268 glVertex3f( radius * *(row + 0), radius * *(row + 1), radius * *(row + 2) );
270 glVertex3f( radius * *(next + 0), radius * *(next + 1), radius * *(next + 2) );
279 glBegin( GL_TRIANGLE_FAN );
280 glNormal3f( 0, 0, -1 );
281 glVertex3f( 0, 0, -radius );
283 glVertex3f( radius * *(row + 0), radius * *(row + 1), radius * *(row + 2) );
285 for( i=slices-1; i>=0; i-- )
287 glNormal3fv(row + 3 * i);
289 radius * *(row + 3 * i + 0),
290 radius * *(row + 3 * i + 1),
291 radius * *(row + 3 * i + 2)
305 void FGAPIENTRY glutWireCone( GLdouble base, GLdouble height, GLint slices, GLint stacks )
307 float alt = (float) height / (float) (stacks + 1);
308 float angle = (float) M_PI / (float) slices * 2.0f;
309 float slope = (float) tan( height / base );
310 float* vertices = NULL;
314 * We need 'slices' points on a circle
316 vertices = calloc( sizeof(float), 2 * (slices + 1) );
318 for( i=0; i<slices+1; i++ )
320 vertices[ i*2 + 0 ] = cos( angle * i );
321 vertices[ i*2 + 1 ] = sin( angle * i );
325 * First the cone's bottom...
327 for( i=0; i<slices; i++ )
329 float scl = height / slope;
331 glBegin( GL_LINE_LOOP );
332 glNormal3f( 0, 0, -1 );
333 glVertex3f( vertices[ (i+0)*2+0 ] * scl, vertices[ (i+0)*2+1 ] * scl, 0 );
334 glVertex3f( vertices[ (i+1)*2+0 ] * scl, vertices[ (i+1)*2+1 ] * scl, 0 );
335 glVertex3f( 0, 0, 0 );
340 * Then all the stacks between the bottom and the top
342 * ekhm jak wektor normalny z trojkata?
344 for( i=0; i<stacks; i++ )
346 float alt_a = i * alt, alt_b = (i + 1) * alt;
347 float scl_a = (height - alt_a) / slope;
348 float scl_b = (height - alt_b) / slope;
350 for( j=0; j<slices; j++ )
352 glBegin( GL_LINE_LOOP );
353 glVertex3f( vertices[(j+0)*2+0] * scl_a, vertices[(j+0)*2+1] * scl_a, alt_a );
354 glVertex3f( vertices[(j+1)*2+0] * scl_a, vertices[(j+1)*2+1] * scl_a, alt_a );
355 glVertex3f( vertices[(j+0)*2+0] * scl_b, vertices[(j+0)*2+1] * scl_b, alt_b );
358 glBegin( GL_LINE_LOOP );
359 glVertex3f( vertices[(j+0)*2+0] * scl_b, vertices[(j+0)*2+1] * scl_b, alt_b );
360 glVertex3f( vertices[(j+1)*2+0] * scl_b, vertices[(j+1)*2+1] * scl_b, alt_b );
361 glVertex3f( vertices[(j+1)*2+0] * scl_a, vertices[(j+1)*2+1] * scl_a, alt_a );
367 * Finally have the top part drawn...
369 for( i=0; i<slices; i++ )
371 float scl = alt / slope;
373 glBegin( GL_LINE_LOOP );
374 glVertex3f( vertices[ (i+0)*2+0 ] * scl, vertices[ (i+0)*2+1 ] * scl, height - alt );
375 glVertex3f( vertices[ (i+1)*2+0 ] * scl, vertices[ (i+1)*2+1 ] * scl, height - alt );
376 glVertex3f( 0, 0, height );
384 void FGAPIENTRY glutSolidCone( GLdouble base, GLdouble height, GLint slices, GLint stacks )
386 float alt = (float) height / (float) (stacks + 1);
387 float angle = (float) M_PI / (float) slices * 2.0f;
388 float slope = (float) tan( height / base );
389 float* vertices = NULL;
393 * We need 'slices' points on a circle
395 vertices = calloc( sizeof(float), 2 * (slices + 1) );
397 for( i=0; i<slices+1; i++ )
399 vertices[ i*2 + 0 ] = cos( angle * i );
400 vertices[ i*2 + 1 ] = sin( angle * i );
404 * First the cone's bottom...
406 for( i=0; i<slices; i++ )
408 float scl = height / slope;
410 glBegin( GL_TRIANGLES );
411 glNormal3f( 0, 0, -1 );
412 glVertex3f( vertices[ (i+0)*2+0 ] * scl, vertices[ (i+0)*2+1 ] * scl, 0 );
413 glVertex3f( vertices[ (i+1)*2+0 ] * scl, vertices[ (i+1)*2+1 ] * scl, 0 );
414 glVertex3f( 0, 0, 0 );
419 * Then all the stacks between the bottom and the top
421 * ekhm jak wektor normalny z trojkata?
423 for( i=0; i<stacks; i++ )
425 float alt_a = i * alt, alt_b = (i + 1) * alt;
426 float scl_a = (height - alt_a) / slope;
427 float scl_b = (height - alt_b) / slope;
429 for( j=0; j<slices; j++ )
431 glBegin( GL_TRIANGLES );
432 glVertex3f( vertices[(j+0)*2+0] * scl_a, vertices[(j+0)*2+1] * scl_a, alt_a );
433 glVertex3f( vertices[(j+1)*2+0] * scl_a, vertices[(j+1)*2+1] * scl_a, alt_a );
434 glVertex3f( vertices[(j+0)*2+0] * scl_b, vertices[(j+0)*2+1] * scl_b, alt_b );
437 glBegin( GL_TRIANGLES );
438 glVertex3f( vertices[(j+1)*2+0] * scl_a, vertices[(j+1)*2+1] * scl_a, alt_a );
439 glVertex3f( vertices[(j+1)*2+0] * scl_b, vertices[(j+1)*2+1] * scl_b, alt_b );
440 glVertex3f( vertices[(j+0)*2+0] * scl_b, vertices[(j+0)*2+1] * scl_b, alt_b );
446 * Finally have the top part drawn...
448 for( i=0; i<slices; i++ )
450 float scl = alt / slope;
452 glBegin( GL_TRIANGLES );
453 glVertex3f( vertices[ (i+0)*2+0 ] * scl, vertices[ (i+0)*2+1 ] * scl, height - alt );
454 glVertex3f( vertices[ (i+1)*2+0 ] * scl, vertices[ (i+1)*2+1 ] * scl, height - alt );
455 glVertex3f( 0, 0, height );
463 void FGAPIENTRY glutWireTorus( GLdouble dInnerRadius, GLdouble dOuterRadius, GLint nSides, GLint nRings )
465 glutWireSphere( dOuterRadius, 5, 5 );
471 void FGAPIENTRY glutSolidTorus( GLdouble dInnerRadius, GLdouble dOuterRadius, GLint nSides, GLint nRings )
473 glutSolidSphere( dOuterRadius, 5, 5 );
479 void FGAPIENTRY glutWireDodecahedron( void )
481 glutWireSphere( 1.0, 5, 5 );
487 void FGAPIENTRY glutSolidDodecahedron( void )
489 glutSolidSphere( 1.0, 5, 5 );
495 void FGAPIENTRY glutWireOctahedron( void )
497 glutWireSphere( 1.0, 5, 5 );
503 void FGAPIENTRY glutSolidOctahedron( void )
505 glutSolidSphere( 1.0, 5, 5 );
511 void FGAPIENTRY glutWireTetrahedron( void )
513 glutWireSphere( 1.0, 5, 5 );
519 void FGAPIENTRY glutSolidTetrahedron( void )
521 glutSolidSphere( 1.0, 5, 5 );
527 void FGAPIENTRY glutWireIcosahedron( void )
529 glutWireSphere( 1.0, 5, 5 );
535 void FGAPIENTRY glutSolidIcosahedron( void )
537 glutSolidSphere( 1.0, 5, 5 );
540 /*** END OF FILE ***/