]> git.tdb.fi Git - libs/gl.git/blob - source/sphere.cpp
Add geometry builder for sphere
[libs/gl.git] / source / sphere.cpp
1 #include <cmath>
2 #include "primitivebuilder.h"
3 #include "sphere.h"
4
5 namespace Msp {
6 namespace GL {
7
8 UvSphereBuilder::UvSphereBuilder(float r, unsigned s, unsigned n):
9         radius(r),
10         segments(s),
11         rings(n)
12 {
13         if(segments<3)
14                 segments = 3;
15
16         if(rings==0)
17                 rings = (segments+1)/2;
18         else if(rings<2)
19                 rings = 2;
20 }
21
22 void UvSphereBuilder::build(PrimitiveBuilder &builder) const
23 {
24         float u_scale = 1.0f/segments;
25         float v_scale = 1.0f/rings;
26         adjust_texture_scale(u_scale, v_scale, radius*M_PI*2, radius*M_PI);
27
28         for(unsigned i=0; i<=rings; ++i)
29         {
30                 float av = i*M_PI/rings-M_PI/2;
31                 float cv = cos(av);
32                 float sv = sin(av);
33
34                 for(unsigned j=0; j<=segments; ++j)
35                 {
36                         float au = j*M_PI*2/segments;
37                         float cu = cos(au);
38                         float su = sin(au);
39
40                         builder.normal(cv*cu, cv*su, sv);
41                         builder.texcoord(j*u_scale, i*v_scale);
42                         if(generate_tbn)
43                         {
44                                 builder.tangent(-su, cu, 0);
45                                 builder.binormal(-sv*cu, -sv*su, cv);
46                         }
47                         builder.vertex(cv*cu*radius, cv*su*radius, sv*radius);
48                 }
49         }
50
51         builder.begin(TRIANGLES);
52         for(unsigned j=0; j<segments; ++j)
53         {
54                 builder.element(j);
55                 builder.element(segments+2+j);
56                 builder.element(segments+1+j);
57         }
58         unsigned top = (rings+1)*(segments+1)-1;
59         for(unsigned j=0; j<segments; ++j)
60         {
61                 builder.element(top-j);
62                 builder.element(top-(segments+2+j));
63                 builder.element(top-(segments+1+j));
64         }
65         builder.end();
66
67         for(unsigned i=1; i<rings; ++i)
68         {
69                 builder.begin(TRIANGLE_STRIP);
70                 unsigned base = i*(segments+1);
71                 for(unsigned j=0; j<=segments; ++j)
72                 {
73                         builder.element(base+segments+1+j);
74                         builder.element(base+j);
75                 }
76                 builder.end();
77         }
78 }
79
80 } // namespace GL
81 } // namespace Msp