-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathosucone.cpp
121 lines (97 loc) · 2.75 KB
/
osucone.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <math.h>
#include <ctype.h>
#include <GL/gl.h>
#ifndef F_PI
#define F_PI ((float)(M_PI))
#define F_2_PI ((float)(2.f*F_PI))
#define F_PI_2 ((float)(F_PI/2.f))
#endif
inline
void
_DrawConeLatLng( int ilat, int ilng, int numlats, int numlngs, float radbot, float radtop, float height )
{
float t = (float)ilat / (float)(numlats-1);
float y = t * height;
float rad = t * radtop + ( 1.f - t ) * radbot;
float lng = -F_PI + 2.f * F_PI * (float)ilng / (float)(numlngs-1);
float x = cosf( lng );
float z = -sinf( lng );
float s = (float)ilng / (float)(numlngs-1);
glTexCoord2f( s, t );
float n[3] = { height*x, radbot - radtop, height*z };
Unit( n, n );
glNormal3fv( n );
glVertex3f( rad * x, y,rad * z );
}
void
OsuCone( float radBot, float radTop, float height, int slices, int stacks )
{
// sanity check:
radBot = (float)fabs( (double)radBot );
radTop = (float)fabs( (double)radTop );
slices = abs( slices );
stacks = abs( stacks );
if( slices < 4 ) slices = 4;
if( stacks < 4 ) stacks = 4;
// gracefully handle degenerate case:
if( radBot == 0. && radTop == 0. )
{
glBegin( GL_LINES );
glTexCoord2f( 0., 0. );
glNormal3f( 0., -1., 0. );
glVertex3f( 0., 0., 0. );
glTexCoord2f( 0., 1. );
glNormal3f( 0., 1., 0. );
glVertex3f( 0., height, 0. );
glEnd( );
return;
}
int numLngs = slices;
int numLats = stacks;
// draw the sides:
for( int ilat = 0; ilat < numLats-1; ilat++ )
{
glBegin( GL_TRIANGLE_STRIP );
_DrawConeLatLng( ilat+0, 0, numLats, numLngs, radBot, radTop, height );
_DrawConeLatLng( ilat+1, 0, numLats, numLngs, radBot, radTop, height );
for( int ilng = 1; ilng < numLngs; ilng++ )
{
_DrawConeLatLng( ilat+0, ilng, numLats, numLngs, radBot, radTop, height );
_DrawConeLatLng( ilat+1, ilng, numLats, numLngs, radBot, radTop, height );
}
glEnd( );
}
// draw the bottom circle:
if( radBot != 0. )
{
glBegin( GL_TRIANGLES );
for( int ilng = numLngs-1; ilng >= 0; ilng-- )
{
_DrawConeLatLng( 0, ilng+1, numLats, numLngs, radBot, radTop, height );
_DrawConeLatLng( 0, ilng+0, numLats, numLngs, radBot, radTop, height );
float s = (float)ilng / (float)(numLngs-1);
glTexCoord2f( s, 0. );
glNormal3f( 0., -1., 0. );
glVertex3f( 0., 0., 0. );
}
glEnd( );
}
// draw the top circle:
if( radTop != 0. )
{
glBegin( GL_TRIANGLES );
for( int ilng = 0; ilng < numLngs-1; ilng++ )
{
float s = (float)ilng / (float)(numLngs-1);
glTexCoord2f( s, 1. );
glNormal3f( 0., 1., 0. );
glVertex3f( 0., height, 0. );
_DrawConeLatLng( numLats-1, ilng+0, numLats, numLngs, radBot, radTop, height );
_DrawConeLatLng( numLats-1, ilng+1, numLats, numLngs, radBot, radTop, height );
}
glEnd( );
}
}