Ion
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
shaders.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"
30 #include "ion/math/vector.h"
31 
33 #include "GL/freeglut.h"
34 
35 namespace {
36 
38 
43 
44 
45 struct GlobalState {
46  int window_width;
47  int window_height;
48  ion::gfx::NodePtr scene_root;
49  ion::gfx::RendererPtr renderer;
50 };
51 
52 static std::unique_ptr<GlobalState> s_global_state;
53 
55 
60 
61 
62 static const char* kVertexShaderString = (
63  "uniform mat4 uProjectionMatrix;\n"
64  "uniform mat4 uModelviewMatrix;\n"
65  "uniform vec4 uTopColor;\n"
66  "uniform vec4 uBottomColor;\n"
67  "attribute vec3 aVertex;\n"
68  "varying vec3 vPosition;\n"
69  "varying vec4 vColor;\n"
70  "\n"
71  "void main(void) {\n"
72  " vPosition = aVertex;\n"
73  " vColor = mix(uBottomColor, uTopColor, .5 * (1. + vPosition.y));\n"
74  " gl_Position = uProjectionMatrix * uModelviewMatrix *\n"
75  " vec4(aVertex, 1.);\n"
76  "}\n");
77 
78 static const char* kFragmentShaderString = (
79  "#ifdef GL_ES\n"
80  "#ifdef GL_FRAGMENT_PRECISION_HIGH\n"
81  "precision highp float;\n"
82  "#else\n"
83  "precision mediump float;\n"
84  "#endif\n"
85  "#endif\n"
86  "\n"
87  "uniform float uWaveFrequency;\n"
88  "varying vec3 vPosition;\n"
89  "varying vec4 vColor;\n"
90  "\n"
91  "void main(void) {\n"
92  " float nx = sin(uWaveFrequency * radians(90.) * vPosition.x);\n"
93  " vec3 normal = normalize(vec3(nx, 0., .5));\n"
94  " vec3 dir_to_light = normalize(vec3(1., 2., 10.));\n"
95  " float intensity = max(0.0, dot(dir_to_light, normal));\n"
96  " gl_FragColor = intensity * vColor;\n"
97  "}\n");
98 
100 
105 
106 
107 static const ion::gfx::NodePtr BuildGraph(int window_width, int window_height) {
109 
112  rect_spec.size.Set(2.f, 2.f);
113  root->AddShape(ion::gfxutils::BuildRectangleShape(rect_spec));
114 
115  ion::gfx::StateTablePtr state_table(
116  new ion::gfx::StateTable(window_width, window_height));
117  state_table->SetViewport(
118  ion::math::Range2i::BuildWithSize(ion::math::Point2i(0, 0),
119  ion::math::Vector2i(window_width,
120  window_height)));
121  state_table->SetClearColor(ion::math::Vector4f(0.3f, 0.3f, 0.5f, 1.0f));
122  state_table->SetClearDepthValue(1.f);
123  state_table->Enable(ion::gfx::StateTable::kDepthTest, true);
124  state_table->Enable(ion::gfx::StateTable::kCullFace, true);
125  root->SetStateTable(state_table);
126 
128  reg->IncludeGlobalRegistry();
130  "uTopColor", ion::gfx::kFloatVector4Uniform,
131  "Color at the top of the rectangle"));
133  "uBottomColor", ion::gfx::kFloatVector4Uniform,
134  "Color at the bottom of the rectangle"));
136  "uWaveFrequency", ion::gfx::kFloatUniform,
137  "Frequency of the sine wave applied to the rectangle normal"));
138  root->SetShaderProgram(
140  "Example shader", reg, kVertexShaderString,
141  kFragmentShaderString, ion::base::AllocatorPtr()));
142 
143  const ion::math::Matrix4f proj(1.732f, 0.0f, 0.0f, 0.0f,
144  0.0f, 1.732f, 0.0f, 0.0f,
145  0.0f, 0.0f, -1.905f, -13.798f,
146  0.0f, 0.0f, -1.0f, 0.0f);
147  const ion::math::Matrix4f view(1.0f, 0.0f, 0.0f, 0.0f,
148  0.0f, 1.0f, 0.0f, 0.0f,
149  0.0f, 0.0f, 1.0f, -5.0f,
150  0.0f, 0.0f, 0.0f, 1.0f);
151  root->AddUniform(reg->Create<ion::gfx::Uniform>("uProjectionMatrix", proj));
152  root->AddUniform(reg->Create<ion::gfx::Uniform>("uModelviewMatrix", view));
153  root->AddUniform(reg->Create<ion::gfx::Uniform>(
154  "uTopColor", ion::math::Vector4f(1.f, .5f, .5f, 1.f)));
155  root->AddUniform(reg->Create<ion::gfx::Uniform>(
156  "uBottomColor", ion::math::Vector4f(.5f, .5f, 1.f, 1.f)));
157  root->AddUniform(reg->Create<ion::gfx::Uniform>("uWaveFrequency", 5.f));
158 
159  return root;
160 }
161 
163 
168 
169 
170 static void Resize(int w, int h) {
171  s_global_state->window_width = w;
172  s_global_state->window_height = h;
173  glutPostRedisplay();
174 }
175 
176 static void Render() {
177  if (s_global_state.get())
178  s_global_state->renderer->DrawScene(s_global_state->scene_root);
179  glutSwapBuffers();
180 }
181 
182 static void Update() {
183  glutPostRedisplay();
184 }
185 
186 static void Keyboard(unsigned char key, int x, int y) {
187  glutPostRedisplay();
188 }
189 
190 static void KeyboardUp(unsigned char key, int x, int y) {
191  switch (key) {
192  case 27: // Escape.
193  s_global_state.reset(NULL);
194  glutLeaveMainLoop();
195  break;
196  }
197  glutPostRedisplay();
198 }
199 
200 } // anonymous namespace
201 
203 
208 
209 
210 int main(int argc, char* argv[]) {
211  glutInit(&argc, argv);
212 
213  s_global_state.reset(new GlobalState);
214  s_global_state->window_width = s_global_state->window_height = 800;
215  s_global_state->scene_root = BuildGraph(s_global_state->window_width,
216  s_global_state->window_height);
217 
218  glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE | GLUT_DEPTH | GLUT_MULTISAMPLE);
219  glutSetOption(GLUT_MULTISAMPLE, 16);
220  glutInitWindowSize(s_global_state->window_width,
221  s_global_state->window_height);
222 
223  glutCreateWindow("Ion shaders example");
224  glutDisplayFunc(Render);
225  glutReshapeFunc(Resize);
226  glutKeyboardFunc(Keyboard);
227  glutKeyboardUpFunc(KeyboardUp);
228  glutIdleFunc(Update);
229 
232  s_global_state->renderer.Reset(new ion::gfx::Renderer(graphics_manager));
233 
234  glutMainLoop();
235 }
GraphicsManager manages the graphics library for an application.
This struct is stored for each registered ShaderInput.
A Uniform instance represents a uniform shader argument.
Definition: uniform.h:76
Scalar types.
Definition: uniform.h:39
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
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...
int main(int argc, char *argv[])
Mainline.
Definition: shaders.cc:210
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
const gfx::ShapePtr BuildRectangleShape(const RectangleSpec &spec)
Builds and returns a Shape representing a rectangle in one of the principal Cartesian planes...
Definition: shapeutils.cc:1290
The Renderer class handles rendering ION scene graphs using OpenGL.
Definition: renderer.h:50