Ion
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
texture.cc
Go to the documentation of this file.
1 
18 #include <memory>
19 
20 #include "ion/base/datacontainer.h"
21 #include "ion/gfx/node.h"
22 #include "ion/gfx/renderer.h"
23 #include "ion/gfx/sampler.h"
25 #include "ion/gfx/shaderprogram.h"
26 #include "ion/gfx/shape.h"
27 #include "ion/gfx/statetable.h"
28 #include "ion/gfx/texture.h"
29 #include "ion/gfx/uniform.h"
31 #include "ion/math/angle.h"
32 #include "ion/math/matrix.h"
33 #include "ion/math/range.h"
35 #include "ion/math/vector.h"
36 
38 #include "GL/freeglut.h"
39 
40 namespace {
41 
43 
48 
49 
50 struct GlobalState {
51  int window_width;
52  int window_height;
53  ion::gfx::NodePtr scene_root;
54  ion::gfx::RendererPtr renderer;
55 };
56 
57 static std::unique_ptr<GlobalState> s_global_state;
58 
60 
65 
66 
67 static const char* kVertexShaderString = (
68  "uniform mat4 uProjectionMatrix;\n"
69  "uniform mat4 uModelviewMatrix;\n"
70  "uniform mat4 uTextureMatrix;\n"
71  "attribute vec3 aVertex;\n"
72  "attribute vec2 aTexCoords;\n"
73  "varying vec3 vPosition;\n"
74  "varying vec2 vTexCoords;\n"
75  "\n"
76  "void main(void) {\n"
77  " vTexCoords = (uTextureMatrix * vec4(aTexCoords, 0., 1.)).st;\n"
78  " vPosition = aVertex;\n"
79  " gl_Position = uProjectionMatrix * uModelviewMatrix *\n"
80  " vec4(aVertex, 1.);\n"
81  "}\n");
82 
83 static const char* kFragmentShaderString = (
84  "#ifdef GL_ES\n"
85  "#ifdef GL_FRAGMENT_PRECISION_HIGH\n"
86  "precision highp float;\n"
87  "#else\n"
88  "precision mediump float;\n"
89  "#endif\n"
90  "#endif\n"
91  "\n"
92  "uniform sampler2D uSampler;\n"
93  "uniform float uWaveFrequency;\n"
94  "varying vec3 vPosition;\n"
95  "varying vec2 vTexCoords;\n"
96  "\n"
97  "void main(void) {\n"
98  " float nx = sin(uWaveFrequency * radians(90.) * vPosition.x);\n"
99  " vec3 normal = normalize(vec3(nx, 0., .5));\n"
100  " vec3 dir_to_light = normalize(vec3(1., 2., 10.));\n"
101  " float intensity = max(0.0, dot(dir_to_light, normal));\n"
102  " gl_FragColor = intensity * texture2D(uSampler, vTexCoords);\n"
103  "}\n");
104 
106 
111 
112 
113 static const ion::math::Matrix4f BuildTextureRotationMatrix(float degrees) {
114  return
115  ion::math::TranslationMatrix(ion::math::Vector3f(.5f, .5f, 0.f)) *
117  ion::math::Vector3f::AxisZ(),
118  ion::math::Anglef::FromDegrees(degrees)) *
119  ion::math::TranslationMatrix(ion::math::Vector3f(-.5f, -.5f, 0.f));
120 }
121 
122 static ion::gfx::TexturePtr BuildTexture() {
124  static const int kWidth = 2;
125  static const int kHeight = 2;
126  static const int kRowSize = kWidth * 3;
127  static const uint8 pixels[kHeight * kRowSize] = {
128  0xee, 0x22, 0xee, 0x00, 0x55, 0xdd, // Bottom row : magenta, blue.
129  0x00, 0xdd, 0xaa, 0xdd, 0xcc, 0x33, // Top row: green, yellow.
130  };
131 
133  ion::base::DataContainerPtr data_container =
134  ion::base::DataContainer::CreateAndCopy<uint8>(
135  pixels, sizeof(pixels), true, ion::base::AllocatorPtr());
136  image->Set(ion::gfx::Image::kRgb888, kWidth, kHeight, data_container);
137 
141  sampler->SetWrapS(ion::gfx::Sampler::kClampToEdge);
142  sampler->SetWrapT(ion::gfx::Sampler::kClampToEdge);
143 
145  texture->SetImage(0U, image);
146  texture->SetSampler(sampler);
147  return texture;
148 }
149 
150 static const ion::gfx::NodePtr BuildGraph(int window_width, int window_height) {
152 
155  rect_spec.size.Set(2.f, 2.f);
156  root->AddShape(ion::gfxutils::BuildRectangleShape(rect_spec));
157 
158  ion::gfx::StateTablePtr state_table(
159  new ion::gfx::StateTable(window_width, window_height));
160  state_table->SetViewport(
161  ion::math::Range2i::BuildWithSize(ion::math::Point2i(0, 0),
162  ion::math::Vector2i(window_width,
163  window_height)));
164  state_table->SetClearColor(ion::math::Vector4f(0.3f, 0.3f, 0.5f, 1.0f));
165  state_table->SetClearDepthValue(1.f);
166  state_table->Enable(ion::gfx::StateTable::kDepthTest, true);
167  state_table->Enable(ion::gfx::StateTable::kCullFace, true);
168  root->SetStateTable(state_table);
169 
171  reg->IncludeGlobalRegistry();
173  "uTextureMatrix", ion::gfx::kMatrix4x4Uniform,
174  "Matrix applied to texture coordinates"));
176  "uSampler", ion::gfx::kTextureUniform,
177  "Texture sampler"));
179  "uWaveFrequency", ion::gfx::kFloatUniform,
180  "Frequency of the sine wave applied to the rectangle normal"));
181  root->SetShaderProgram(
183  "Example shader", reg, kVertexShaderString,
184  kFragmentShaderString, ion::base::AllocatorPtr()));
185 
186  const ion::math::Matrix4f proj(1.732f, 0.0f, 0.0f, 0.0f,
187  0.0f, 1.732f, 0.0f, 0.0f,
188  0.0f, 0.0f, -1.905f, -13.798f,
189  0.0f, 0.0f, -1.0f, 0.0f);
190  const ion::math::Matrix4f view(1.0f, 0.0f, 0.0f, 0.0f,
191  0.0f, 1.0f, 0.0f, 0.0f,
192  0.0f, 0.0f, 1.0f, -5.0f,
193  0.0f, 0.0f, 0.0f, 1.0f);
194  const ion::math::Matrix4f tex_mtx = BuildTextureRotationMatrix(30.f);
195 
196  root->AddUniform(reg->Create<ion::gfx::Uniform>("uProjectionMatrix", proj));
197  root->AddUniform(reg->Create<ion::gfx::Uniform>("uModelviewMatrix", view));
198  root->AddUniform(reg->Create<ion::gfx::Uniform>("uTextureMatrix", tex_mtx));
199  root->AddUniform(reg->Create<ion::gfx::Uniform>("uWaveFrequency", 5.f));
200  root->AddUniform(reg->Create<ion::gfx::Uniform>("uSampler", BuildTexture()));
201 
202  return root;
203 }
204 
206 
211 
212 
213 static void Resize(int w, int h) {
214  s_global_state->window_width = w;
215  s_global_state->window_height = h;
216  glutPostRedisplay();
217 }
218 
219 static void Render() {
220  if (s_global_state.get())
221  s_global_state->renderer->DrawScene(s_global_state->scene_root);
222  glutSwapBuffers();
223 }
224 
225 static void Update() {
226  glutPostRedisplay();
227 }
228 
229 static void Keyboard(unsigned char key, int x, int y) {
230  glutPostRedisplay();
231 }
232 
233 static void KeyboardUp(unsigned char key, int x, int y) {
234  switch (key) {
235  case 27: // Escape.
236  s_global_state.reset(NULL);
237  glutLeaveMainLoop();
238  break;
239  }
240  glutPostRedisplay();
241 }
242 
243 } // anonymous namespace
244 
246 
251 
252 
253 int main(int argc, char* argv[]) {
254  glutInit(&argc, argv);
255 
256  s_global_state.reset(new GlobalState);
257  s_global_state->window_width = s_global_state->window_height = 800;
258  s_global_state->scene_root = BuildGraph(s_global_state->window_width,
259  s_global_state->window_height);
260 
261  glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE | GLUT_DEPTH | GLUT_MULTISAMPLE);
262  glutSetOption(GLUT_MULTISAMPLE, 16);
263  glutInitWindowSize(s_global_state->window_width,
264  s_global_state->window_height);
265 
266  glutCreateWindow("Ion texture example");
267  glutDisplayFunc(Render);
268  glutReshapeFunc(Resize);
269  glutKeyboardFunc(Keyboard);
270  glutKeyboardUpFunc(KeyboardUp);
271  glutIdleFunc(Update);
272 
275  s_global_state->renderer.Reset(new ion::gfx::Renderer(graphics_manager));
276 
277  glutMainLoop();
278 }
GraphicsManager manages the graphics library for an application.
A Texture object represents the image data and mipmaps associated with a single texture.
Definition: texture.h:264
This struct is stored for each registered ShaderInput.
const Matrix< 4, T > RotationMatrixAxisAngleH(const Vector< 3, T > &axis, const Angle< T > &angle)
Returns a 4x4 Matrix representing a 3D rotation specified as axis and angle.
A Uniform instance represents a uniform shader argument.
Definition: uniform.h:76
Scalar types.
Definition: uniform.h:39
An Image represents 2D image data that can be used in a texture supplied to a shader.
Definition: image.h:35
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.
const Grid & image
The original monochrome image data, as doubles (0 - 1).
Definition: sdfutils.cc:90
TexturePtr texture
The Texture to add sub-image data to.
Definition: fontimage.cc:107
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: texture.cc:253
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
A Sampler object represents texture parameters that control how texture data is accessed in shaders...
Definition: sampler.h:29