Ion
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
hierarchy.cc
Go to the documentation of this file.
1 
18 #include <memory>
19 
20 #include "ion/gfx/node.h"
21 #include "ion/gfx/renderer.h"
23 #include "ion/gfx/shaderprogram.h"
24 #include "ion/gfx/shape.h"
25 #include "ion/gfx/statetable.h"
26 #include "ion/gfx/uniform.h"
28 #include "ion/math/matrix.h"
29 #include "ion/math/range.h"
31 #include "ion/math/vector.h"
32 
34 #include "GL/freeglut.h"
35 
36 namespace {
37 
39 
44 
45 
46 struct GlobalState {
47  int window_width;
48  int window_height;
49  ion::gfx::NodePtr scene_root;
50  ion::gfx::RendererPtr renderer;
51 };
52 
53 static std::unique_ptr<GlobalState> s_global_state;
54 
56 
61 
62 
63 static const char* kNode1VertexShaderString = (
64  "uniform mat4 uProjectionMatrix;\n"
65  "uniform mat4 uModelviewMatrix;\n"
66  "uniform vec4 uTopColor;\n"
67  "uniform vec4 uBottomColor;\n"
68  "attribute vec3 aVertex;\n"
69  "attribute vec3 aNormal;\n"
70  "varying vec3 vNormal;\n"
71  "varying vec4 vColor;\n"
72  "\n"
73  "void main(void) {\n"
74  " vNormal = aNormal;\n"
75  " vColor = mix(uBottomColor, uTopColor, .5 * (1. + aVertex.y));\n"
76  " gl_Position = uProjectionMatrix * uModelviewMatrix *\n"
77  " vec4(aVertex, 1.);\n"
78  "}\n");
79 
80 static const char* kNode1FragmentShaderString = (
81  "#ifdef GL_ES\n"
82  "#ifdef GL_FRAGMENT_PRECISION_HIGH\n"
83  "precision highp float;\n"
84  "#else\n"
85  "precision mediump float;\n"
86  "#endif\n"
87  "#endif\n"
88  "\n"
89  "varying vec3 vNormal;\n"
90  "varying vec4 vColor;\n"
91  "\n"
92  "void main(void) {\n"
93  " vec3 normal = normalize(vNormal);\n"
94  " vec3 dir_to_light = normalize(vec3(1., 4., 8.));\n"
95  " float intensity = min(1., abs(dot(dir_to_light, normal)));\n"
96  " gl_FragColor = intensity * vColor;\n"
97  "}\n");
98 
99 static const char* kNode3VertexShaderString = (
100  "uniform mat4 uProjectionMatrix;\n"
101  "uniform mat4 uModelviewMatrix;\n"
102  "attribute vec3 aVertex;\n"
103  "attribute vec3 aNormal;\n"
104  "varying vec3 vNormal;\n"
105  "\n"
106  "void main(void) {\n"
107  " vNormal = aNormal;\n"
108  " gl_Position = uProjectionMatrix * uModelviewMatrix *\n"
109  " vec4(aVertex, 1.);\n"
110  "}\n");
111 
112 static const char* kNode3FragmentShaderString = (
113  "#ifdef GL_ES\n"
114  "#ifdef GL_FRAGMENT_PRECISION_HIGH\n"
115  "precision highp float;\n"
116  "#else\n"
117  "precision mediump float;\n"
118  "#endif\n"
119  "#endif\n"
120  "\n"
121  "uniform vec4 uBaseColor;\n"
122  "uniform vec3 uOpenDirection;\n"
123  "varying vec3 vNormal;\n"
124  "\n"
125  "void main(void) {\n"
126  " vec3 normal = normalize(vNormal);\n"
127  " if (dot(vNormal, uOpenDirection) > .9)\n"
128  " discard;\n"
129  " vec3 dir_to_light = normalize(vec3(1., 1., 2.));\n"
130  " float intensity = min(1., abs(dot(dir_to_light, normal)));\n"
131  " gl_FragColor = intensity * uBaseColor;\n"
132  "}\n");
133 
135 
140 
141 
142 static const ion::gfx::NodePtr BuildNode1(int window_width, int window_height) {
144 
145  ion::gfxutils::EllipsoidSpec sphere_spec;
147  sphere_spec.size.Set(2.f, 2.f, 2.f);
148  node1->AddShape(ion::gfxutils::BuildEllipsoidShape(sphere_spec));
149 
150  ion::gfx::StateTablePtr state_table(
151  new ion::gfx::StateTable(window_width, window_height));
152  state_table->SetViewport(
153  ion::math::Range2i::BuildWithSize(ion::math::Point2i(0, 0),
154  ion::math::Vector2i(window_width,
155  window_height)));
156  state_table->SetClearColor(ion::math::Vector4f(0.3f, 0.3f, 0.5f, 1.0f));
157  state_table->SetClearDepthValue(1.f);
158  state_table->Enable(ion::gfx::StateTable::kDepthTest, true);
159  state_table->Enable(ion::gfx::StateTable::kCullFace, true);
160  node1->SetStateTable(state_table);
161 
163  reg->IncludeGlobalRegistry();
165  "uTopColor", ion::gfx::kFloatVector4Uniform,
166  "Color at the top of the rectangle"));
168  "uBottomColor", ion::gfx::kFloatVector4Uniform,
169  "Color at the bottom of the rectangle"));
170  node1->SetShaderProgram(
172  "Node1 shader", reg, kNode1VertexShaderString,
173  kNode1FragmentShaderString, ion::base::AllocatorPtr()));
174 
175  const ion::math::Matrix4f proj =
176  ion::math::PerspectiveMatrixFromView(ion::math::Anglef::FromDegrees(60.f),
177  1.f, .1f, 10.f);
178  const ion::math::Matrix4f view =
179  ion::math::LookAtMatrixFromCenter(ion::math::Point3f(1.f, 1.f, 6.f),
180  ion::math::Point3f(0.f, -1.f, 0.f),
181  ion::math::Vector3f::AxisY());
182  node1->AddUniform(reg->Create<ion::gfx::Uniform>("uProjectionMatrix", proj));
183  node1->AddUniform(reg->Create<ion::gfx::Uniform>("uModelviewMatrix", view));
184  node1->AddUniform(reg->Create<ion::gfx::Uniform>(
185  "uTopColor", ion::math::Vector4f(1.f, .2f, .2f, 1.f)));
186  node1->AddUniform(reg->Create<ion::gfx::Uniform>(
187  "uBottomColor", ion::math::Vector4f(.2f, 1.f, 1.f, 1.f)));
188 
189  return node1;
190 }
191 
192 static const ion::gfx::NodePtr BuildNode2(
195 
196  ion::gfxutils::BoxSpec box_spec;
198  box_spec.size.Set(3.f, 2.f, 1.f);
199  node2->AddShape(ion::gfxutils::BuildBoxShape(box_spec));
200 
202  state_table->SetCullFaceMode(ion::gfx::StateTable::kCullFront);
203  node2->SetStateTable(state_table);
204 
205  node2->AddUniform(reg->Create<ion::gfx::Uniform>(
206  "uTopColor", ion::math::Vector4f(.9f, .9f, .2f, 1.f)));
207  node2->AddUniform(reg->Create<ion::gfx::Uniform>(
208  "uBottomColor", ion::math::Vector4f(.9f, .1f, .9f, 1.f)));
209  node2->AddUniform(reg->Create<ion::gfx::Uniform>(
210  "uModelviewMatrix",
211  ion::math::TranslationMatrix(ion::math::Point3f(-2.f, -3.f, 0.f))));
212 
213  return node2;
214 }
215 
216 static const ion::gfx::NodePtr BuildNode3() {
218 
219  ion::gfxutils::CylinderSpec cylinder_spec;
221  cylinder_spec.height = 2.f;
222  node3->AddShape(ion::gfxutils::BuildCylinderShape(cylinder_spec));
223 
225  reg->IncludeGlobalRegistry();
227  "uOpenDirection", ion::gfx::kFloatVector3Uniform,
228  "Surface normal direction near cut-out"));
229  node3->SetShaderProgram(
231  "Node3 shader", reg, kNode3VertexShaderString,
232  kNode3FragmentShaderString, ion::base::AllocatorPtr()));
233 
234  node3->AddUniform(reg->Create<ion::gfx::Uniform>(
235  "uModelviewMatrix",
236  ion::math::TranslationMatrix(ion::math::Point3f(2.f, -3.f, 0.f))));
237  node3->AddUniform(reg->Create<ion::gfx::Uniform>(
238  "uBaseColor", ion::math::Vector4f(.9f, .9f, .7f, 1.f)));
239  node3->AddUniform(reg->Create<ion::gfx::Uniform>(
240  "uOpenDirection", ion::math::Vector3f::AxisZ()));
241 
242  return node3;
243 }
244 
245 static const ion::gfx::NodePtr BuildGraph(int window_width, int window_height) {
246  ion::gfx::NodePtr node1 = BuildNode1(window_width, window_height);
247  node1->AddChild(BuildNode2(node1->GetShaderProgram()->GetRegistry()));
248  node1->AddChild(BuildNode3());
249  return node1;
250 }
251 
253 
258 
259 
260 static void Resize(int w, int h) {
261  s_global_state->window_width = w;
262  s_global_state->window_height = h;
263  glutPostRedisplay();
264 }
265 
266 static void Render() {
267  if (s_global_state.get())
268  s_global_state->renderer->DrawScene(s_global_state->scene_root);
269  glutSwapBuffers();
270 }
271 
272 static void Update() {
273  glutPostRedisplay();
274 }
275 
276 static void Keyboard(unsigned char key, int x, int y) {
277  glutPostRedisplay();
278 }
279 
280 static void KeyboardUp(unsigned char key, int x, int y) {
281  switch (key) {
282  case 27: // Escape.
283  s_global_state.reset(NULL);
284  glutLeaveMainLoop();
285  break;
286  }
287  glutPostRedisplay();
288 }
289 
290 } // anonymous namespace
291 
293 
298 
299 
300 int main(int argc, char* argv[]) {
301  glutInit(&argc, argv);
302 
303  s_global_state.reset(new GlobalState);
304  s_global_state->window_width = s_global_state->window_height = 800;
305  s_global_state->scene_root = BuildGraph(s_global_state->window_width,
306  s_global_state->window_height);
307 
308  glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE | GLUT_DEPTH | GLUT_MULTISAMPLE);
309  glutSetOption(GLUT_MULTISAMPLE, 16);
310  glutInitWindowSize(s_global_state->window_width,
311  s_global_state->window_height);
312 
313  glutCreateWindow("Ion hierarchy example");
314  glutDisplayFunc(Render);
315  glutReshapeFunc(Resize);
316  glutKeyboardFunc(Keyboard);
317  glutKeyboardUpFunc(KeyboardUp);
318  glutIdleFunc(Update);
319 
322  s_global_state->renderer.Reset(new ion::gfx::Renderer(graphics_manager));
323 
324  glutMainLoop();
325 }
GraphicsManager manages the graphics library for an application.
int main(int argc, char *argv[])
Mainline.
Definition: hierarchy.cc:300
This struct is stored for each registered ShaderInput.
A Uniform instance represents a uniform shader argument.
Definition: uniform.h:76
const gfx::ShapePtr BuildEllipsoidShape(const EllipsoidSpec &spec)
Builds and returns a Shape representing an axis-aligned ellipsoid.
Definition: shapeutils.cc:1320
ION_API const Matrix< 4, T > LookAtMatrixFromCenter(const Point< 3, T > &eye, const Point< 3, T > &center, const Vector< 3, T > &up)
View matrices.
const gfx::ShapePtr BuildCylinderShape(const CylinderSpec &spec)
Builds and returns a Shape representing an axis-aligned cylinder.
Definition: shapeutils.cc:1330
A ShaderInputRegistry is used to manage a collection of shader inputs to a specific ShaderProgram (bo...
The Matrix class defines a square N-dimensional matrix.
Definition: matrix.h:35
const Matrix< Dimension+1, T > TranslationMatrix(const VectorBase< Dimension, T > &t)
Affine transformation matrices.
ION_API const Matrix< 4, T > PerspectiveMatrixFromView(const Angle< T > &fovy, T aspect, T z_near, T z_far)
Returns a 4x4 perspective projection matrix based on the given parameters, which follow the conventio...
const gfx::ShapePtr BuildBoxShape(const BoxSpec &spec)
Builds and returns a Shape representing an axis-aligned box.
Definition: shapeutils.cc:1310
static const ShaderProgramPtr BuildFromStrings(const std::string &id_string, const ShaderInputRegistryPtr &registry_ptr, const std::string &vertex_shader_string, const std::string &fragment_shader_string, const base::AllocatorPtr &allocator)
Convenience function that builds and returns a new ShaderProgram instance that uses the given ShaderI...
math::Vector3f size
Definition: shapeutils.h:209
A StateTable represents a collection of graphical state items that affect OpenGL rendering.
Definition: statetable.h:48
A Node instance represents a node in a scene graph.
Definition: node.h:45
A SharedPtr is a smart shared pointer to an instance of some class that implements reference counting...
Definition: sharedptr.h:60
The Renderer class handles rendering ION scene graphs using OpenGL.
Definition: renderer.h:50