]> git.tdb.fi Git - libs/gl.git/blob - source/cylinder.cpp
System for generating standard shaders based on flags
[libs/gl.git] / source / cylinder.cpp
1 /* $Id$
2
3 This file is part of libmspgl
4 Copyright © 2011  Mikko Rasa, Mikkosoft Productions
5 Distributed under the LGPL
6 */
7
8 #include <cmath>
9 #include "cylinder.h"
10 #include "primitivebuilder.h"
11
12 using namespace std;
13
14 namespace Msp {
15 namespace GL {
16
17 CylinderBuilder::CylinderBuilder(float r, float l, unsigned s):
18         radius(r),
19         length(l),
20         segments(s)
21 {
22         if(segments<3)
23                 segments = 3;
24 }
25
26 void CylinderBuilder::build(PrimitiveBuilder &builder) const
27 {
28         if(binormal_attr>=0)
29                 builder.attrib(binormal_attr, 0, 1, 0);
30         for(unsigned i=0; i<2; ++i)
31         {
32                 float z = (i-0.5)*length;
33                 builder.normal(0, 0, i*2.0-1.0);
34                 builder.texcoord(0.5, 0.5);
35                 if(tangent_attr>=0)
36                         builder.attrib(tangent_attr, (i ? 1 : -1), 0, 0);
37                 builder.vertex(0, 0, z);
38                 for(unsigned j=0; j<segments; ++j)
39                 {
40                         float a = j*M_PI*2/segments;
41                         float c = cos(a);
42                         float s = sin(a);
43                         builder.texcoord(0.5+(i ? 0.5 : -0.5)*c, 0.5+0.5*s);
44                         builder.vertex(radius*c, radius*s, z);
45                 }
46         }
47
48         float u_scale = 1.0/segments;
49         float v_scale = 1;
50         adjust_texture_scale(u_scale, v_scale, radius*M_PI*2, length);
51
52         if(binormal_attr>=0)
53                 builder.attrib(binormal_attr, 0, 0, 1);
54         for(unsigned i=0; i<2; ++i)
55         {
56                 float z = (i-0.5)*length;
57                 for(unsigned j=0; j<=segments; ++j)
58                 {
59                         float a = j*M_PI*2/segments;
60                         float c = cos(a);
61                         float s = sin(a);
62                         builder.normal(c, s, 0);
63                         builder.texcoord(j*u_scale, i*v_scale);
64                         if(tangent_attr>=0)
65                                 builder.attrib(tangent_attr, -s, c, 0);
66                         builder.vertex(radius*c, radius*s, z);
67                 }
68         }
69
70         unsigned base = 0;
71         for(unsigned i=0; i<2; ++i)
72         {
73                 builder.begin(TRIANGLE_FAN);
74                 builder.element(base);
75                 for(unsigned j=0; j<=segments; ++j)
76                         builder.element(base+1+j%segments);
77                 builder.end();
78
79                 base += segments+1;
80         }
81
82         builder.begin(TRIANGLE_STRIP);
83         for(unsigned j=0; j<=segments; ++j)
84         {
85                 builder.element(base+segments+1+j);
86                 builder.element(base+j);
87         }
88         builder.end();
89 }
90
91 } // namespace GL
92 } // namespace Msp