Tucano  0.1
A library for rapid prototyping with modern OpenGL and GLSL
cylinder.hpp
Go to the documentation of this file.
1 
23 #ifndef __CYLINDER__
24 #define __CYLINDER__
25 
26 #include <tucano/mesh.hpp>
27 #include <Eigen/Dense>
28 #include <cmath>
29 
30 namespace Tucano
31 {
32 
33 namespace Shapes
34 {
35 
37 const string cylinder_fragment_code = "\n"
38  "#version 430\n"
39  "in vec4 color;\n"
40  "in vec3 normal;\n"
41  "in vec4 vert;\n"
42  "out vec4 out_Color;\n"
43  "uniform mat4 lightViewMatrix;\n"
44  "uniform int with_cap;\n"
45  "void main(void)\n"
46  "{\n"
47  " vec3 eyeDirection = -normalize(vert.xyz);\n"
48  " if (with_cap == 1 && dot(normal, eyeDirection) < 0.0) discard;\n"
49  " vec3 lightDirection = (lightViewMatrix * vec4(0.0, 0.0, 1.0, 0.0)).xyz;\n"
50  " lightDirection = normalize(lightDirection);\n"
51  " vec3 lightReflection = reflect(-lightDirection, normal);\n"
52  " float shininess = 100.0;\n"
53  " vec4 ambientLight = color * 0.4;\n"
54  " vec4 diffuseLight = color * 0.6 * max(dot(lightDirection, normal),0.0);\n"
55  " vec4 specularLight = vec4(1.0) * max(pow(dot(lightReflection, eyeDirection), shininess),0.0);\n"
56  " out_Color = vec4(ambientLight.xyz + diffuseLight.xyz + specularLight.xyz, color.w);\n"
57  "}\n";
58 
60 const string cylinder_vertex_code = "\n"
61  "#version 430\n"
62  "in vec4 in_Position;\n"
63  "in vec4 in_Normal;\n"
64  "out vec4 color;\n"
65  "out vec3 normal;\n"
66  "out vec4 vert;\n"
67  "uniform mat4 modelMatrix;\n"
68  "uniform mat4 viewMatrix;\n"
69  "uniform mat4 projectionMatrix;\n"
70  "uniform vec4 in_Color;\n"
71  "void main(void)\n"
72  "{\n"
73  " mat4 modelViewMatrix = viewMatrix * modelMatrix;\n"
74  " mat4 normalMatrix = transpose(inverse(modelViewMatrix));\n"
75  " normal = normalize(vec3(normalMatrix * vec4(in_Normal.xyz,0.0)).xyz);\n"
76  " vert = modelViewMatrix * in_Position;\n"
77  " gl_Position = projectionMatrix * modelViewMatrix * in_Position;\n"
78  " color = in_Color;\n"
79  "}\n";
80 
81 
85 class Cylinder : public Tucano::Mesh {
86 
87 private:
88 
91 
93  float cylinder_height = 2.0;
94 
96  float cylinder_radius = 1.0;
97 
99  bool with_cap = true;
100 
101 public:
102 
106  Cylinder(float r = 1.0, float h = 2.0, int subs_xy = 32, int subs_z = 8, bool cap = true)
107  {
108  with_cap = cap;
110  cylinder_radius = r;
111  cylinder_height = h;
112  createGeometry(subs_xy, subs_z);
113 
114  setColor(Eigen::Vector4f(0.0, 0.48, 1.0, 1.0));
115 
116  cylinder_shader.setShaderName("cylinderShader");
117  cylinder_shader.initializeFromStrings(cylinder_vertex_code, cylinder_fragment_code);
118 
119  #ifdef TUCANODEBUG
120  Tucano::Misc::errorCheckFunc(__FILE__, __LINE__, "cylinder constructor");
121  #endif
122  }
123 
127  void render (const Tucano::Camera& camera, const Tucano::Camera& light)
128  {
129  Eigen::Vector4f viewport = camera.getViewport();
130  glViewport(viewport[0], viewport[1], viewport[2], viewport[3]);
131 
132  cylinder_shader.bind();
133 
134  cylinder_shader.setUniform("modelMatrix", model_matrix);
135  cylinder_shader.setUniform("viewMatrix", camera.getViewMatrix());
136  cylinder_shader.setUniform("projectionMatrix", camera.getProjectionMatrix());
137  cylinder_shader.setUniform("lightViewMatrix", light.getViewMatrix());
138  cylinder_shader.setUniform("in_Color", default_color);
139  cylinder_shader.setUniform("with_cap", (int)with_cap);
140 
141  this->setAttributeLocation(&cylinder_shader);
142 
143  this->bindBuffers();
144  this->renderElements();
145  this->unbindBuffers();
146 
147  cylinder_shader.unbind();
148 
149  #ifdef TUCANODEBUG
150  Misc::errorCheckFunc(__FILE__, __LINE__);
151  #endif
152 
153  }
154 
158  float getHeight (void)
159  {
160  return cylinder_height;
161  }
162 
166  float getRadius (void)
167  {
168  return cylinder_radius;
169  }
170 
171 private:
172 
173 
180  void createGeometry (int subs_xy, int subs_z)
181  {
182 
183  vector< Eigen::Vector4f > vert;
184  vector< Eigen::Vector3f > norm;
185  vector< GLuint > faces;
186 
187  float x, y, theta;
188 
189  // create vertices for rings
190  for (int j = 0; j <= subs_z + 1; ++j)
191  {
192  float z = j * (cylinder_height / (float)(subs_z+1));
193  for (int i = 0; i < subs_xy; ++i)
194  {
195  theta = 2.0*M_PI*i/(float)subs_xy;
196  x = sin(theta)*cylinder_radius;
197  y = cos(theta)*cylinder_radius;
198  vert.push_back(Eigen::Vector4f(x, y, z, 1.0));
199  norm.push_back(Eigen::Vector3f(x, y, 0.0));
200  }
201  }
202 
203  // create a face with every three vertices between two rings
204  // every vertice creates a tringle with two vertices from lower ring and top ring, and another with two vertices from top ring and one from lower
205  for (int j = 0; j <= subs_z; ++j)
206  {
207  for (int i = 0; i < subs_xy; ++i)
208  {
209  faces.push_back(i + j*subs_xy); // current vertex
210  faces.push_back(i + (j+1)*subs_xy); // same vertex on lower ring
211  faces.push_back(((i+1)%subs_xy) + (j+1)*subs_xy); // next vertex on lower ring
212  faces.push_back((i+subs_xy-1)%subs_xy + j*subs_xy); // previous vertex on current ring
213  faces.push_back(i + (j+1)*subs_xy); // same vertex on lower ring
214  faces.push_back(i + j*subs_xy); // current vertex
215  }
216  }
217 
218  if (with_cap)
219  {
220  // create top cap
221  vert.push_back(Eigen::Vector4f(0.0, 0.0, cylinder_height, 1.0));
222  norm.push_back(Eigen::Vector3f(0.0, 0.0, 1.0));
223  int center_index = vert.size()-1;
224  int offset = vert.size();
225  for (int i = 0; i < subs_xy; ++i)
226  {
227  theta = 2.0*M_PI*i/(float)subs_xy;
228  x = sin(theta)*cylinder_radius;
229  y = cos(theta)*cylinder_radius;
230  vert.push_back(Eigen::Vector4f(x, y, cylinder_height, 1.0));
231  norm.push_back(Eigen::Vector3f(0.0, 0.0, 1.0));
232  }
233 
234  for (int i = 0; i < subs_xy; ++i)
235  {
236  faces.push_back(i+offset);
237  faces.push_back((i+1)%(subs_xy) + offset);
238  faces.push_back(center_index);
239  }
240  // create bottom cap
241  vert.push_back(Eigen::Vector4f(0.0, 0.0, 0.0, 1.0));
242  norm.push_back(Eigen::Vector3f(0.0, 0.0, -1.0));
243  center_index = vert.size()-1;
244  offset = vert.size();
245  for (int i = 0; i < subs_xy; ++i)
246  {
247  theta = 2.0*M_PI*i/(float)subs_xy;
248  x = sin(theta)*cylinder_radius;
249  y = cos(theta)*cylinder_radius;
250  vert.push_back(Eigen::Vector4f(x, y, 0.0, 1.0));
251  norm.push_back(Eigen::Vector3f(0.0, 0.0, -1.0));
252  }
253 
254  for (int i = 0; i < subs_xy; ++i)
255  {
256  faces.push_back(i+offset);
257  faces.push_back(center_index);
258  faces.push_back((i+1)%(subs_xy) + offset);
259  }
260  }
261 
262  loadVertices(vert);
263  loadNormals(norm);
264  loadIndices(faces);
265 
267 
268  }
269 
270 };
271 }
272 }
273 #endif
void loadNormals(vector< Eigen::Vector3f > &norm)
Load normals (x,y,z) as a vertex attribute.
Definition: mesh.hpp:384
const string cylinder_vertex_code
Default vertex shader for rendering cylinder.
Definition: cylinder.hpp:60
float cylinder_height
Cylinder cylinder_height.
Definition: cylinder.hpp:93
void getViewMatrix(GLdouble *matrix)
Return the modelview matrix as a GLdouble array.
Definition: camera.hpp:126
float getHeight(void)
Returns cylinder cylinder_height.
Definition: cylinder.hpp:158
Eigen::Vector4f default_color
Default color.
Definition: model.hpp:36
void getProjectionMatrix(GLdouble *matrix)
Return the projection matrix as a GLdouble array.
Definition: camera.hpp:142
Definition: bufferobject.hpp:34
float getRadius(void)
Returns cylinder cylinder_radius.
Definition: cylinder.hpp:166
void setShaderName(string name)
Sets the shader name, very useful for debugging.
Definition: shader.hpp:329
A Shader object represents one GLSL program.
Definition: shader.hpp:45
void setColor(const Eigen::Vector4f &color)
Sets the default color of the model.
Definition: model.hpp:65
void errorCheckFunc(std::string file, int line, std::string message="")
GL error check method.
Definition: misc.hpp:53
void initializeFromStrings(string in_vertex_code, string in_fragment_code, string in_geometry_code="", string in_tessellation_evaluation_code="", string in_tessellation_control_code="")
Initializes shader directly from string, no files.
Definition: shader.hpp:589
void loadIndices(vector< GLuint > &ind)
Load indices into indices array.
Definition: mesh.hpp:448
void createGeometry(int subs_xy, int subs_z)
Define cylinder geometry.
Definition: cylinder.hpp:180
float cylinder_radius
Cylinder cylinder_radius.
Definition: cylinder.hpp:96
void setDefaultAttribLocations(void)
Sets default attribute locations. vertex coords -> location 0 normals -> location 1 colors -> locatio...
Definition: mesh.hpp:474
void resetModelMatrix(void)
Resets the model matrix.
Definition: model.hpp:159
void unbind(void)
Disables the shader program.
Definition: shader.hpp:1184
Tucano::Shader cylinder_shader
Shader to render cylinder.
Definition: cylinder.hpp:90
A simple cylinder shape.
Definition: cylinder.hpp:85
void render(const Tucano::Camera &camera, const Tucano::Camera &light)
Render cylinder.
Definition: cylinder.hpp:127
Eigen::Affine3f model_matrix
Model matrix, holds information about the models location and orientation.
Definition: model.hpp:21
virtual void unbindBuffers(void)
Unbinds all buffers.
Definition: mesh.hpp:702
Cylinder(float r=1.0, float h=2.0, int subs_xy=32, int subs_z=8, bool cap=true)
Default Constructor.
Definition: cylinder.hpp:106
void loadVertices(vector< Eigen::Vector4f > &vert)
Load vertices (x,y,z,w) and creates appropriate vertex attribute. The default attribute name is "in_P...
Definition: mesh.hpp:312
void bind(void)
Enables the shader program for usage.
Definition: shader.hpp:1176
virtual void renderElements(void)
Call the draw method for rendering triangles. This method requires that a index buffer has been creat...
Definition: mesh.hpp:726
const string cylinder_fragment_code
Default fragment shader for rendering cylinder.
Definition: cylinder.hpp:37
virtual void bindBuffers(void)
Binds all buffers.
Definition: mesh.hpp:677
A common Mesh, usually containing triagles or points.
Definition: mesh.hpp:194
Defines an abstract camera with a projection and view matrices.
Definition: camera.hpp:37
void setAttributeLocation(Shader *shader)
Automatically sets the attribute locations for a given Shader.
Definition: mesh.hpp:541
Eigen::Vector4f getViewport(void) const
Returns the viewport coordinates.
Definition: camera.hpp:246
bool with_cap
flag to create or not caps
Definition: cylinder.hpp:99
void setUniform(GLint location, GLint a, GLint b, GLint c, GLint d)
Sets an uniform integer 4D vector (ivec4) given a location and the vector values. ...
Definition: shader.hpp:1258