901a0f4b43cf057872a752960e30678a2a980b24
[libs/gl.git] / source / builders / cylinder.cpp
1 #define _USE_MATH_DEFINES
2 #include <cmath>
3 #include "cylinder.h"
4 #include "primitivebuilder.h"
5
6 using namespace std;
7
8 namespace Msp {
9 namespace GL {
10
11 CylinderBuilder::CylinderBuilder(float r, float l, unsigned s):
12         radius(r),
13         length(l),
14         segments(s)
15 {
16         if(segments<3)
17                 segments = 3;
18 }
19
20 void CylinderBuilder::build(PrimitiveBuilder &builder) const
21 {
22         if(generate_tbn)
23                 builder.binormal(0, 1, 0);
24         for(unsigned i=0; i<2; ++i)
25         {
26                 float z = (i-0.5)*length;
27                 builder.normal(0, 0, i*2.0-1.0);
28                 builder.texcoord(0.5, 0.5);
29                 if(generate_tbn)
30                         builder.tangent((i ? 1 : -1), 0, 0);
31                 builder.vertex(0, 0, z);
32                 for(unsigned j=0; j<segments; ++j)
33                 {
34                         float a = j*M_PI*2/segments;
35                         float c = cos(a);
36                         float s = sin(a);
37                         builder.texcoord(0.5+(i ? 0.5 : -0.5)*c, 0.5+0.5*s);
38                         builder.vertex(radius*c, radius*s, z);
39                 }
40         }
41
42         float u_scale = 1.0/segments;
43         float v_scale = 1;
44         adjust_texture_scale(u_scale, v_scale, radius*M_PI*2, length);
45
46         if(generate_tbn)
47                 builder.binormal(0, 0, 1);
48         for(unsigned i=0; i<2; ++i)
49         {
50                 float z = (i-0.5)*length;
51                 for(unsigned j=0; j<=segments; ++j)
52                 {
53                         float a = j*M_PI*2/segments;
54                         float c = cos(a);
55                         float s = sin(a);
56                         builder.normal(c, s, 0);
57                         builder.texcoord(j*u_scale, i*v_scale);
58                         if(generate_tbn)
59                                 builder.tangent(-s, c, 0);
60                         builder.vertex(radius*c, radius*s, z);
61                 }
62         }
63
64         unsigned base = 0;
65         for(unsigned i=0; i<2; ++i)
66         {
67                 builder.begin(TRIANGLE_FAN);
68                 builder.element(base);
69                 for(unsigned j=0; j<=segments; ++j)
70                         builder.element(base+1+j%segments);
71                 builder.end();
72
73                 base += segments+1;
74         }
75
76         builder.begin(TRIANGLE_STRIP);
77         for(unsigned j=0; j<=segments; ++j)
78         {
79                 builder.element(base+segments+1+j);
80                 builder.element(base+j);
81         }
82         builder.end();
83 }
84
85 } // namespace GL
86 } // namespace Msp