2 * blinking-teapot demo. It displays a teapot whose color go from blue to pink.
3 * The color variation is handled by uniform buffer object.
4 * Sources mostly from http://www.jotschi.de/?p=427 which uses UBO SPEC example
13 #include "glut_wrap.h"
14 #include "shaderutil.h"
17 static int mouse_old_x
, mouse_old_y
;
18 static int mouse_buttons
= 0;
19 static float rotate_x
= 0.0, rotate_y
= 0.0;
20 static float translate_z
= -2.0;
22 static float delta
= 0.01;
23 static GLfloat wf
, hf
;
26 static const GLchar
*names
[] = { "SurfaceColor", "WarmColor", "CoolColor",
27 "DiffuseWarm", "DiffuseCool"
30 static GLuint buffer_id
, uniformBlockIndex
, uindex
, vshad_id
, fshad_id
,
33 static GLsizei uniformBlockSize
;
34 static GLint singleSize
;
37 static const GLfloat colors
[] =
38 { 0.45, 0.45, 1, 1, 0.45, 0.45, 1, 1, 0.75, 0.75, 0.75, 1,
39 0.0, 0.0, 1.0, 1, 0.0, 1.0, 0.0, 1,
42 static GLfloat teapot_color
= 1;
45 reshape (int w
, int h
)
49 glMatrixMode (GL_PROJECTION
);
51 gluPerspective (60.0, wf
/ hf
, 0.1, 100.0);
58 if (!ShadersSupported ())
61 if (!glutExtensionSupported("GL_ARB_uniform_buffer_object")) {
62 printf("GL_ARB_uniform_buffer_object is required.\n");
66 vshad_id
= CompileShaderFile (GL_VERTEX_SHADER
, "blinking-teapot.vert");
67 fshad_id
= CompileShaderFile (GL_FRAGMENT_SHADER
, "blinking-teapot.frag");
68 prog_id
= LinkShaders (vshad_id
, fshad_id
);
74 glGenBuffers (1, &buffer_id
);
76 glBindBuffer (GL_UNIFORM_BUFFER
, buffer_id
);
77 glBufferData (GL_UNIFORM_BUFFER
, uniformBlockSize
, NULL
, GL_DYNAMIC_DRAW
);
79 glBindBufferBase (GL_UNIFORM_BUFFER
, 0, buffer_id
);
80 glUniformBlockBinding (prog_id
, uniformBlockIndex
, 0);
82 glGetUniformIndices (prog_id
, 1, &names
[2], &uindex
);
84 glGetActiveUniformsiv (prog_id
, 1, &uindex
, GL_UNIFORM_OFFSET
, &offset
);
85 glGetActiveUniformsiv (prog_id
, 1, &uindex
, GL_UNIFORM_SIZE
, &singleSize
);
87 glViewport (0, 0, 680, 400);
88 glBufferData (GL_UNIFORM_BUFFER
, 80, colors
, GL_DYNAMIC_DRAW
);
94 glClearColor (0.0, 0.0, 0.0, 0.0);
95 glClear (GL_DEPTH_BUFFER_BIT
| GL_COLOR_BUFFER_BIT
);
96 glUseProgram (prog_id
);
97 glEnable (GL_DEPTH_TEST
);
99 glMatrixMode (GL_MODELVIEW
);
101 glTranslatef (0.0, 0.0, translate_z
);
102 glRotatef (rotate_x
, 1.0, 0.0, 0.0);
103 glRotatef (rotate_y
, 0.0, 1.0, 0.0);
104 glColor3f (1.0, 1.0, 1.0);
106 glBindBuffer (GL_UNIFORM_BUFFER
, buffer_id
);
107 glBufferSubData (GL_UNIFORM_BUFFER
, offset
, 4 * singleSize
, &teapot_color
);
110 glutSolidTeapot (0.6);
111 glFrontFace (GL_CCW
);
113 glutPostRedisplay ();
115 teapot_color
+= delta
;
117 if (teapot_color
> 1.0)
122 if (teapot_color
< 0.0)
130 mouse (int button
, int state
, int x
, int y
)
132 if (state
== GLUT_DOWN
)
134 mouse_buttons
|= 1 << button
;
136 else if (state
== GLUT_UP
)
143 glutPostRedisplay ();
147 motion (int x
, int y
)
150 dx
= x
- mouse_old_x
;
151 dy
= y
- mouse_old_y
;
153 if (mouse_buttons
& 1)
155 rotate_x
+= dy
* 0.2;
156 rotate_y
+= dx
* 0.2;
158 else if (mouse_buttons
& 4)
160 translate_z
+= dy
* 0.01;
168 main (int argc
, char **argv
)
170 glutInit (&argc
, argv
);
171 glutInitWindowSize (400, 400);
172 glutInitDisplayMode (GLUT_RGB
| GLUT_DOUBLE
| GLUT_DEPTH
);
173 glutCreateWindow ("UBO Example");
175 glutDisplayFunc (render
);
176 glutMouseFunc (mouse
);
177 glutMotionFunc (motion
);