Retired Document
Important: This sample code may not represent best practices for current development. The project may use deprecated symbols and illustrate technologies and techniques that are no longer recommended.
SurfaceGeometry.c
/* |
* SufaceGeometry.c |
* Carbon OpenGL |
* |
* Created by Geoff Stahl. |
Copyright: Copyright © 2002-2003 Apple Computer, Inc., All Rights Reserved |
Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple Computer, Inc. |
("Apple") in consideration of your agreement to the following terms, and your |
use, installation, modification or redistribution of this Apple software |
constitutes acceptance of these terms. If you do not agree with these terms, |
please do not use, install, modify or redistribute this Apple software. |
In consideration of your agreement to abide by the following terms, and subject |
to these terms, Apple grants you a personal, non-exclusive license, under AppleÕs |
copyrights in this original Apple software (the "Apple Software"), to use, |
reproduce, modify and redistribute the Apple Software, with or without |
modifications, in source and/or binary forms; provided that if you redistribute |
the Apple Software in its entirety and without modifications, you must retain |
this notice and the following text and disclaimers in all such redistributions of |
the Apple Software. Neither the name, trademarks, service marks or logos of |
Apple Computer, Inc. may be used to endorse or promote products derived from the |
Apple Software without specific prior written permission from Apple. Except as |
expressly stated in this notice, no other rights or licenses, express or implied, |
are granted by Apple herein, including but not limited to any patent rights that |
may be infringed by your derivative works or by other works in which the Apple |
Software may be incorporated. |
The Apple Software is provided by Apple on an "AS IS" basis. APPLE MAKES NO |
WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED |
WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND OPERATION ALONE OR IN |
COMBINATION WITH YOUR PRODUCTS. |
IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL OR |
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE |
GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION |
OF THE APPLE SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF CONTRACT, TORT |
(INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN |
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
* |
*/ |
/* Uses techniques described by Paul Bourke 1999 - 2002 */ |
/* Tranguloid Trefoil and other example surfaces by Roger Bagula see <http://astronomy.swin.edu.au/~pbourke/surfaces/> */ |
#include <math.h> |
#include <stdio.h> |
#include <stdlib.h> |
#include "SurfaceGeometry.h" |
#define TWOPI 6.283185307179586476925287 |
#define PI 3.141592653589793238462643 |
typedef struct { |
GLfloat x,y,z; |
} recVec; |
typedef struct { |
GLfloat r,g,b; |
} recColor; |
typedef struct { |
GLfloat s,t; |
} recTexCoord; |
/* Code based on work by Paul Bourke */ |
// globals for apps to use |
// info |
char gSurfName[256] = ""; |
char gSurfCredit[256] = ""; |
char gSurfX[256] = ""; |
char gSurfY[256] = ""; |
char gSurfZ[256] = ""; |
char gSurfRange[256] = ""; |
// simple cube data |
GLint cube_num_vertices = 8; |
GLfloat cube_vertices [8][3] = { |
{1.0, 1.0, 1.0}, {1.0, -1.0, 1.0}, {-1.0, -1.0, 1.0}, {-1.0, 1.0, 1.0}, |
{1.0, 1.0, -1.0}, {1.0, -1.0, -1.0}, {-1.0, -1.0, -1.0}, {-1.0, 1.0, -1.0} }; |
GLfloat cube_vertex_colors [8][3] = { |
{1.0, 1.0, 1.0}, {1.0, 1.0, 0.0}, {0.0, 1.0, 0.0}, {0.0, 1.0, 1.0}, |
{1.0, 0.0, 1.0}, {1.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 1.0} }; |
GLint cube_num_faces = 6; |
short cube_faces [6][4] = { |
{3, 2, 1, 0}, {2, 3, 7, 6}, {0, 1, 5, 4}, {3, 0, 4, 7}, {1, 2, 6, 5}, {4, 5, 6, 7} }; |
GLfloat cube_texCoords [2][4] = { |
{0.0, 0.0, 1.0, 1.0}, {0.0, 1.0, 1.0, 0.0} }; |
recColor getColor(GLfloat v, GLfloat vmin, GLfloat vmax, int type) |
{ |
double dv,vmid; |
recColor c = {1.0,1.0,1.0}; |
recColor c1,c2,c3; |
double ratio; |
if (v < vmin) |
v = vmin; |
if (v > vmax) |
v = vmax; |
dv = vmax - vmin; |
switch (type) { |
case 0: |
c.r = 1.0f; |
c.b = 1.0f; |
c.g = 1.0f; |
break; |
case 1: |
if (v < (vmin + 0.25 * dv)) { |
c.r = 0; |
c.g = 4 * (v - vmin) / dv; |
c.b = 1; |
} else if (v < (vmin + 0.5 * dv)) { |
c.r = 0; |
c.g = 1; |
c.b = 1 + 4 * (vmin + 0.25 * dv - v) / dv; |
} else if (v < (vmin + 0.75 * dv)) { |
c.r = 4 * (v - vmin - 0.5 * dv) / dv; |
c.g = 1; |
c.b = 0; |
} else { |
c.r = 1; |
c.g = 1 + 4 * (vmin + 0.75 * dv - v) / dv; |
c.b = 0; |
} |
break; |
case 2: |
c.r = (v - vmin) / dv; |
c.g = 0; |
c.b = (vmax - v) / dv; |
break; |
case 3: |
c.r = (v - vmin) / dv; |
c.b = c.r; |
c.g = c.r; |
break; |
case 4: |
if (v < (vmin + dv / 6.0)) { |
c.r = 1; |
c.g = 6 * (v - vmin) / dv; |
c.b = 0; |
} else if (v < (vmin + 2.0 * dv / 6.0)) { |
c.r = 1 + 6 * (vmin + dv / 6.0 - v) / dv; |
c.g = 1; |
c.b = 0; |
} else if (v < (vmin + 3.0 * dv / 6.0)) { |
c.r = 0; |
c.g = 1; |
c.b = 6 * (v - vmin - 2.0 * dv / 6.0) / dv; |
} else if (v < (vmin + 4.0 * dv / 6.0)) { |
c.r = 0; |
c.g = 1 + 6 * (vmin + 3.0 * dv / 6.0 - v) / dv; |
c.b = 1; |
} else if (v < (vmin + 5.0 * dv / 6.0)) { |
c.r = 6 * (v - vmin - 4.0 * dv / 6.0) / dv; |
c.g = 0; |
c.b = 1; |
} else { |
c.r = 1; |
c.g = 0; |
c.b = 1 + 6 * (vmin + 5.0 * dv / 6.0 - v) / dv; |
} |
break; |
case 5: |
c.r = (v - vmin) / (vmax - vmin); |
c.g = 1; |
c.b = 0; |
break; |
case 6: |
c.r = (v - vmin) / (vmax - vmin); |
c.g = (vmax - v) / (vmax - vmin); |
c.b = c.r; |
break; |
case 7: |
if (v < (vmin + 0.25 * dv)) { |
c.r = 0; |
c.g = 4 * (v - vmin) / dv; |
c.b = 1 - c.g; |
} else if (v < (vmin + 0.5 * dv)) { |
c.r = 4 * (v - vmin - 0.25 * dv) / dv; |
c.g = 1 - c.r; |
c.b = 0; |
} else if (v < (vmin + 0.75 * dv)) { |
c.g = 4 * (v - vmin - 0.5 * dv) / dv; |
c.r = 1 - c.g; |
c.b = 0; |
} else { |
c.r = 0; |
c.b = 4 * (v - vmin - 0.75 * dv) / dv; |
c.g = 1 - c.b; |
} |
break; |
case 8: |
if (v < (vmin + 0.5 * dv)) { |
c.r = 2 * (v - vmin) / dv; |
c.g = c.r; |
c.b = c.r; |
} else { |
c.r = 1 - 2 * (v - vmin - 0.5 * dv) / dv; |
c.g = c.r; |
c.b = c.r; |
} |
break; |
case 9: |
if (v < (vmin + dv / 3)) { |
c.b = 3 * (v - vmin) / dv; |
c.g = 0; |
c.r = 1 - c.b; |
} else if (v < (vmin + 2 * dv / 3)) { |
c.r = 0; |
c.g = 3 * (v - vmin - dv / 3) / dv; |
c.b = 1; |
} else { |
c.r = 3 * (v - vmin - 2 * dv / 3) / dv; |
c.g = 1 - c.r; |
c.b = 1; |
} |
break; |
case 10: |
if (v < (vmin + 0.2 * dv)) { |
c.r = 0; |
c.g = 5 * (v - vmin) / dv; |
c.b = 1; |
} else if (v < (vmin + 0.4 * dv)) { |
c.r = 0; |
c.g = 1; |
c.b = 1 + 5 * (vmin + 0.2 * dv - v) / dv; |
} else if (v < (vmin + 0.6 * dv)) { |
c.r = 5 * (v - vmin - 0.4 * dv) / dv; |
c.g = 1; |
c.b = 0; |
} else if (v < (vmin + 0.8 * dv)) { |
c.r = 1; |
c.g = 1 - 5 * (v - vmin - 0.6 * dv) / dv; |
c.b = 0; |
} else { |
c.r = 1; |
c.g = 5 * (v - vmin - 0.8 * dv) / dv; |
c.b = 5 * (v - vmin - 0.8 * dv) / dv; |
} |
break; |
case 11: |
c1.r = 200 / 255.0; c1.g = 60 / 255.0; c1.b = 0 / 255.0; |
c2.r = 250 / 255.0; c2.g = 160 / 255.0; c2.b = 110 / 255.0; |
c.r = (c2.r - c1.r) * (v - vmin) / dv + c1.r; |
c.g = (c2.g - c1.g) * (v - vmin) / dv + c1.g; |
c.b = (c2.b - c1.b) * (v - vmin) / dv + c1.b; |
break; |
case 12: |
c1.r = 55 / 255.0; c1.g = 55 / 255.0; c1.b = 45 / 255.0; |
c2.r = 200 / 255.0; c2.g = 60 / 255.0; c2.b = 0 / 255.0; |
// c2.r = 235 / 255.0; c2.g = 90 / 255.0; c2.b = 30 / 255.0; |
c3.r = 250 / 255.0; c3.g = 160 / 255.0; c3.b = 110 / 255.0; |
ratio = 0.4; |
vmid = vmin + ratio * dv; |
if (v < vmid) { |
c.r = (c2.r - c1.r) * (v - vmin) / (ratio*dv) + c1.r; |
c.g = (c2.g - c1.g) * (v - vmin) / (ratio*dv) + c1.g; |
c.b = (c2.b - c1.b) * (v - vmin) / (ratio*dv) + c1.b; |
} else { |
c.r = (c3.r - c2.r) * (v - vmid) / ((1-ratio)*dv) + c2.r; |
c.g = (c3.g - c2.g) * (v - vmid) / ((1-ratio)*dv) + c2.g; |
c.b = (c3.b - c2.b) * (v - vmid) / ((1-ratio)*dv) + c2.b; |
} |
break; |
case 13: |
c1.r = 0 / 255.0; c1.g = 255 / 255.0; c1.b = 0 / 255.0; |
c2.r = 255 / 255.0; c2.g = 150 / 255.0; c2.b = 0 / 255.0; |
c3.r = 255 / 255.0; c3.g = 250 / 255.0; c3.b = 240 / 255.0; |
ratio = 0.3; |
vmid = vmin + ratio * dv; |
if (v < vmid) { |
c.r = (c2.r - c1.r) * (v - vmin) / (ratio*dv) + c1.r; |
c.g = (c2.g - c1.g) * (v - vmin) / (ratio*dv) + c1.g; |
c.b = (c2.b - c1.b) * (v - vmin) / (ratio*dv) + c1.b; |
} else { |
c.r = (c3.r - c2.r) * (v - vmid) / ((1-ratio)*dv) + c2.r; |
c.g = (c3.g - c2.g) * (v - vmid) / ((1-ratio)*dv) + c2.g; |
c.b = (c3.b - c2.b) * (v - vmid) / ((1-ratio)*dv) + c2.b; |
} |
break; |
case 14: |
c.r = 1; |
c.g = 1 - (v - vmin) / dv; |
c.b = 0; |
break; |
case 15: |
if (v < (vmin + 0.25 * dv)) { |
c.r = 0; |
c.g = 4 * (v - vmin) / dv; |
c.b = 1; |
} else if (v < (vmin + 0.5 * dv)) { |
c.r = 0; |
c.g = 1; |
c.b = 1 - 4 * (v - vmin - 0.25 * dv) / dv; |
} else if (v < (vmin + 0.75 * dv)) { |
c.r = 4 * (v - vmin - 0.5 * dv) / dv; |
c.g = 1; |
c.b = 0; |
} else { |
c.r = 1; |
c.g = 1; |
c.b = 4 * (v - vmin - 0.75 * dv) / dv; |
} |
break; |
case 16: |
if (v < (vmin + 0.5 * dv)) { |
c.r = 0.0; |
c.g = 2 * (v - vmin) / dv; |
c.b = 1 - 2 * (v - vmin) / dv; |
} else { |
c.r = 2 * (v - vmin - 0.5 * dv) / dv; |
c.g = 1 - 2 * (v - vmin - 0.5 * dv) / dv; |
c.b = 0.0; |
} |
break; |
case 17: |
if (v < (vmin + 0.5 * dv)) { |
c.r = 1.0; |
c.g = 1 - 2 * (v - vmin) / dv; |
c.b = 2 * (v - vmin) / dv; |
} else { |
c.r = 1 - 2 * (v - vmin - 0.5 * dv) / dv; |
c.g = 2 * (v - vmin - 0.5 * dv) / dv; |
c.b = 1.0; |
} |
break; |
case 18: |
c.r = 0; |
c.g = (v - vmin) / (vmax - vmin); |
c.b = 1; |
break; |
case 19: |
c.r = (v - vmin) / (vmax - vmin); |
c.g = c.r; |
c.b = 1; |
break; |
case 20: |
c1.r = 0 / 255.0; c1.g = 160 / 255.0; c1.b = 0 / 255.0; |
c2.r = 180 / 255.0; c2.g = 220 / 255.0; c2.b = 0 / 255.0; |
c3.r = 250 / 255.0; c3.g = 220 / 255.0; c3.b = 170 / 255.0; |
ratio = 0.3; |
vmid = vmin + ratio * dv; |
if (v < vmid) { |
c.r = (c2.r - c1.r) * (v - vmin) / (ratio*dv) + c1.r; |
c.g = (c2.g - c1.g) * (v - vmin) / (ratio*dv) + c1.g; |
c.b = (c2.b - c1.b) * (v - vmin) / (ratio*dv) + c1.b; |
} else { |
c.r = (c3.r - c2.r) * (v - vmid) / ((1-ratio)*dv) + c2.r; |
c.g = (c3.g - c2.g) * (v - vmid) / ((1-ratio)*dv) + c2.g; |
c.b = (c3.b - c2.b) * (v - vmid) / ((1-ratio)*dv) + c2.b; |
} |
break; |
} |
return(c); |
} |
void normalise(recVec *p) |
{ |
double length; |
length = sqrt(p->x * p->x + p->y * p->y + p->z * p->z); |
if (length != 0) { |
p->x /= length; |
p->y /= length; |
p->z /= length; |
} else { |
p->x = 0; |
p->y = 0; |
p->z = 0; |
} |
} |
recVec CalcNormal(recVec p,recVec p1,recVec p2) |
{ |
recVec n,pa,pb; |
pa.x = p1.x - p.x; |
pa.y = p1.y - p.y; |
pa.z = p1.z - p.z; |
pb.x = p2.x - p.x; |
pb.y = p2.y - p.y; |
pb.z = p2.z - p.z; |
normalise(&pa); |
normalise(&pb); |
n.x = pa.y * pb.z - pa.z * pb.y; |
n.y = pa.z * pb.x - pa.x * pb.z; |
n.z = pa.x * pb.y - pa.y * pb.x; |
normalise(&n); |
return(n); |
} |
// expects u & v (-PI to PI) |
recVec Eval(double u, double v, int type) |
{ |
recVec p; |
double temp; |
switch (type) { |
case kTranguloidTrefoil: |
p.x = sin(3*u) * 2 / (2 + cos(v)); |
p.y = (sin(u) + 2 * sin(2*u)) * 2 / (2 + cos(v + TWOPI / 3)); |
p.z = (cos(u) - 2 * cos(2*u)) * (2 + cos(v)) * (2 + cos(v + TWOPI/3))/4; |
break; |
case kTriaxialTritorus: |
p.x = 2.0 * sin (u) * (1 + cos (v)); |
p.y = 2.0 * sin (u + 2 * PI / 3) * (1 + cos (v + 2 * PI / 3)); |
p.z = 2.0 * sin (u + 4 * PI / 3) * (1 + cos (v + 4 * PI / 3)); |
break; |
case kStilettoSurface: |
// reverse u and v for better distribution or points |
temp = u; |
u = v + PI; v = (temp + PI) / 2.0; // convert to: 0 <= u <= 2 pi, 0 <= v <= 2 pi |
p.x = 4.0 * (2.0 + cos(u)) * pow(cos(v), 3.0) * sin(v); |
p.y = 4.0 * (2.0 + cos(u+TWOPI/3.0)) * pow (cos(v+TWOPI/3.0), 2.0) * pow (sin(v+TWOPI/3.0), 2.0); |
p.z = 4.0 * -(2.0 + cos(u-TWOPI/3.0)) * pow (cos(v+TWOPI/3.0), 2.0) * pow (sin(v+TWOPI/3.0), 2.0); |
break; |
case kSlippersSurface: |
temp = u; |
u = v + PI * 2; v = temp + PI; // convert to: 0 <= u <= 4 pi, 0 <= v <= 2 pi |
p.x = 4.0 * (2 + cos (u)) * pow (cos (v), 3) * sin(v); |
p.y = 4.0 * (2 + cos (u + TWOPI / 3)) * pow (cos (TWOPI / 3 + v), 2) * pow (sin (TWOPI / 3 + v), 2); |
p.z = 4.0 * -(2 + cos (u - TWOPI / 3)) * pow (cos (TWOPI / 3 - v), 2) * pow (sin (TWOPI / 3 - v), 3); |
break; |
case kMaedersOwl: |
u = (u + PI) * 2; v = (v + PI) / TWOPI; // convert to: 0 <= u <= 4 pi, 0 <= v <= 1 |
p.x = 3.0 * v * cos(u) - 0.5 * v * v * cos(2 * u); |
p.y = 3.0 * -v * sin(u) - 0.5 * v * v * sin(2 * u); |
p.z = 3.0 * 4 * pow(v,1.5) * cos(1.5 * u) / 3; |
break; |
default: |
p.x = 0.0; |
p.y = 0.0; |
p.z = 0.0; |
break; |
} |
return(p); |
} |
void GetStrings (unsigned int surface, char ** strName, char ** strAuthor, char ** strX, char ** strY, char ** strZ, char ** strRange) |
{ |
static char strings[6][6][256] = {{"Color Cube", |
" ", |
" ", |
" ", |
" ", |
" "}, |
{"Tranguloid Trefoil", |
"by Roger Bagula", |
"x = 2 sin(3 u) / (2 + cos(v))", |
"y = 2 (sin(u) + 2 sin(2 u)) / (2 + cos(v + 2 pi / 3))", |
"z = (cos(u) - 2 cos(2 u)) (2 + cos(v)) (2 + cos(v + 2 pi / 3)) / 4", |
"-pi <= u <= pi, -pi <= v <= pi"}, |
{"Triaxial Tritorus", |
"by Roger Bagula", |
"x = sin(u) (1 + cos(v))", |
"y = sin(u + 2pi / 3) (1 + cos(v + 2pi / 3))", |
"z = z = sin(u + 4pi / 3) (1 + cos(v + 4pi / 3))", |
"0 <= u <= 2 pi, 0 <= v <= 2 pi"}, |
{"Stiletto Surface", |
"by Roger Bagula", |
"x = (2 + cos(u)) cos(v)^3 sin(v)", |
"y = (2 + cos(u + 2pi /3)) cos(v + 2pi / 3)^2 sin(v + 2pi / 3)^2", |
"z = -(2 + cos(u - 2pi / 3)) cos(v + 2pi / 3)^2 sin(v + 2pi / 3)^2", |
"0 <= u <= 2 pi, 0 <= v <= 2 pi"}, |
{"Slippers Surface", |
"by Roger Bagula", |
"x = (2 + cos(u)) cos(v)^3 sin(v)", |
"y = (2 + cos(u + 2pi / 3)) cos(2pi / 3 + v)^2 sin(2pi / 3 + v)^2", |
"z = -(2 + cos(u - 2pi / 3)) cos(2pi / 3 - v)^2 sin(2pi / 3 - v)^3", |
"0 <= u <= 2 pi, 0 <= v <= 2 pi"}, |
{"Maeder's Owl", |
"by R. Maeder", |
"x = v cos(u) - 0.5 v^2 cos(2 u)", |
"y = - v sin(u) - 0.5 v^2 sin(2 u)", |
"z = 4 v^1.5 cos(3 u / 2) / 3", |
"0 <= u <= 4 pi, 0 <= v <= 1"}}; |
*strName = strings[surface][0]; |
*strAuthor = strings[surface][1]; |
*strX = strings[surface][2]; |
*strY = strings[surface][3]; |
*strZ = strings[surface][4]; |
*strRange = strings[surface][5]; |
} |
// special case cube for test purposes |
void BuildCube (GLuint * polyList, GLuint * lineList, GLuint * pointList, int colorScheme) |
{ |
float fSize = 2.0f; |
long f, i; |
*polyList = glGenLists (1); |
glNewList(*polyList, GL_COMPILE); |
glBegin (GL_QUADS); |
for (f = 0; f < cube_num_faces; f++) |
for (i = 0; i < 4; i++) { |
if (colorScheme) |
glColor3f (cube_vertex_colors[cube_faces[f][i]][0], cube_vertex_colors[cube_faces[f][i]][1], cube_vertex_colors[cube_faces[f][i]][2]); |
else |
glColor3f (1.0f, 1.0f, 1.0f); |
glTexCoord2f (cube_texCoords [0][i], cube_texCoords [1][i]); |
glVertex3f(cube_vertices[cube_faces[f][i]][0] * fSize, cube_vertices[cube_faces[f][i]][1] * fSize, cube_vertices[cube_faces[f][i]][2] * fSize); |
} |
glEnd (); |
glColor3f (0.0, 0.0, 0.0); |
for (f = 0; f < cube_num_faces; f++) { |
glBegin (GL_LINE_LOOP); |
for (i = 0; i < 4; i++) |
glVertex3f(cube_vertices[cube_faces[f][i]][0] * fSize, cube_vertices[cube_faces[f][i]][1] * fSize, cube_vertices[cube_faces[f][i]][2] * fSize); |
glEnd (); |
} |
glEndList (); |
*lineList = glGenLists (1); |
glNewList(*lineList, GL_COMPILE); |
glColor3f (1.0, 1.0, 1.0); |
for (f = 0; f < cube_num_faces; f++) { |
glBegin (GL_LINE_LOOP); |
for (i = 0; i < 4; i++) |
glVertex3f(cube_vertices[cube_faces[f][i]][0] * fSize, cube_vertices[cube_faces[f][i]][1] * fSize, cube_vertices[cube_faces[f][i]][2] * fSize); |
glEnd (); |
} |
glEndList (); |
*pointList = glGenLists (1); |
glNewList(*pointList, GL_COMPILE); |
glColor3f (1.0, 1.0, 1.0); |
for (f = 0; f < cube_num_vertices; f++) { |
glBegin (GL_POINTS); |
glVertex3f(cube_vertices[f][0] * fSize, cube_vertices[f][1] * fSize, cube_vertices[f][2] * fSize); |
glEnd (); |
} |
glEndList (); |
} |
void BuildGeometry (unsigned int surface, unsigned int colorScheme, unsigned int subdivisions, unsigned int xyRatio, |
GLuint * polyList, GLuint * lineList, GLuint * pointList) |
{ |
long i,j, index; |
long maxI = subdivisions * xyRatio, maxJ = subdivisions; |
double u, v, delta=0.001; |
recVec p1,p2; |
recVec *vertexPos = NULL,*vertexNormal = NULL; |
recColor *vertexColor = NULL; |
recTexCoord *vertexTexCoord = NULL; |
// set valid surface and color scheme |
surface %= kSurfaces; |
colorScheme %= kColorSchemes; |
// delete existing list |
if (*polyList) |
glDeleteLists (*polyList, 1); |
if (*lineList) |
glDeleteLists (*lineList, 1); |
if (*pointList) |
glDeleteLists (*pointList, 1); |
*polyList = *lineList = *pointList = 0; |
if (surface == kCube) // build the standard color cube (disregard color, subdivisions, and xyRatio) |
BuildCube (polyList, lineList, pointList, colorScheme); |
else { |
// build buffers |
vertexPos = (recVec*) malloc ((maxI) * (maxJ) * sizeof (recVec)); |
if (vertexNormal) |
free (vertexNormal); |
vertexNormal = (recVec*) malloc ((maxI) * (maxJ) * sizeof (recVec)); |
if (vertexColor) |
free (vertexColor); |
vertexColor = (recColor*) malloc ((maxI) * (maxJ) * sizeof (recColor)); |
if (vertexTexCoord) |
free (vertexTexCoord); |
vertexTexCoord = (recTexCoord*) malloc ((maxI) * (maxJ) * sizeof (recTexCoord)); |
if (!vertexPos || !vertexNormal || !vertexColor || !vertexTexCoord) |
return; |
// build surface |
for (i = 0; i < maxI; i++) { |
for (j = 0; j < maxJ; j++) { |
index = i * maxJ + j; |
u = -PI + (i % maxI) * TWOPI / maxI; |
v = -PI + (j % maxJ) * TWOPI / maxJ; |
vertexPos[index] = Eval(u,v, surface); |
p1 = Eval(u + delta, v, surface); |
p2 = Eval(u, v + delta, surface); |
vertexNormal[index] = CalcNormal(vertexPos[index],p1,p2); |
vertexColor[index] = getColor(u, -PI, PI, colorScheme); |
vertexTexCoord[index].s = (float) i * 5.0f / (float) maxI; |
vertexTexCoord[index].t = (float) j * 1.0f/ (float) maxJ; |
} |
} |
*polyList = glGenLists (1); |
glNewList(*polyList, GL_COMPILE); |
for (i=0; i< maxI; i++) { |
glBegin(GL_TRIANGLE_STRIP); |
for (j = 0; j <= maxJ; j++) { |
index = (i % maxI) * maxJ + (j % maxJ); |
glColor3fv (&vertexColor[index].r); |
glNormal3fv (&vertexNormal[index].x); |
glTexCoord2fv (&vertexTexCoord[index].s); |
glVertex3fv (&vertexPos[index].x); |
index = ((i + 1) % maxI) * maxJ + (j % maxJ); |
glColor3fv (&vertexColor[index].r); |
glNormal3fv (&vertexNormal[index].x); |
glTexCoord2fv (&vertexTexCoord[index].s); |
glVertex3fv (&vertexPos[index].x); |
// index = ((i - 1) % maxI) * maxJ + (j % maxJ); |
} |
glEnd (); |
} |
glEndList (); |
*lineList = glGenLists (1); |
glNewList(*lineList, GL_COMPILE); |
for (i=0; i< maxI; i++) { |
glBegin(GL_LINE_STRIP); |
for (j = 0; j < maxJ; j++) { |
index = i * maxJ + j; |
glColor3fv (&vertexColor[index].r); |
glVertex3fv (&vertexPos[index].x); |
} |
index = i * maxJ + 0; |
glColor3fv (&vertexColor[index].r); |
glVertex3fv (&vertexPos[index].x); |
glEnd (); |
} |
for (j=0; j< maxJ; j++) { |
glBegin(GL_LINE_STRIP); |
for (i = 0; i < maxI; i++) { |
index = i * maxJ + j; |
glColor3fv (&vertexColor[index].r); |
glVertex3fv (&vertexPos[index].x); |
} |
index = 0 + j; |
glColor3fv (&vertexColor[index].r); |
glVertex3fv (&vertexPos[index].x); |
glEnd (); |
} |
glEndList (); |
*pointList = glGenLists (1); |
glNewList(*pointList, GL_COMPILE); |
glBegin(GL_POINTS); |
for (i=0; i< maxI; i++) { |
for (j = 0; j < maxJ; j++) { |
index = i * maxJ + j; |
glColor3fv (&vertexColor[index].r); |
glVertex3fv (&vertexPos[index].x); |
} |
} |
glEnd (); |
glEndList (); |
free (vertexPos); |
free (vertexNormal); |
free (vertexColor); |
} |
} |
Copyright © 2004 Apple Computer, Inc. All Rights Reserved. Terms of Use | Privacy Policy | Updated: 2004-03-26