1/** 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 5 * 6 * Vincent Lejeune 2011 7 */ 8 9#include <stdio.h> 10#include <stdlib.h> 11#include <string.h> 12#include <GL/glew.h> 13#include "glut_wrap.h" 14#include "shaderutil.h" 15 16 17static int mouse_old_x, mouse_old_y; 18static int mouse_buttons = 0; 19static float rotate_x = 0.0, rotate_y = 0.0; 20static float translate_z = -2.0; 21 22static float delta = 0.01; 23static GLfloat wf, hf; 24 25 26static const GLchar *names[] = { "SurfaceColor", "WarmColor", "CoolColor", 27 "DiffuseWarm", "DiffuseCool" 28}; 29 30static GLuint buffer_id, uniformBlockIndex, uindex, vshad_id, fshad_id, 31 prog_id; 32 33static GLsizei uniformBlockSize; 34static GLint singleSize; 35static GLint offset; 36 37static 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, 40}; 41 42static GLfloat teapot_color = 1; 43 44static void 45reshape (int w, int h) 46{ 47 wf = (GLfloat) w; 48 hf = (GLfloat) h; 49 glMatrixMode (GL_PROJECTION); 50 glLoadIdentity (); 51 gluPerspective (60.0, wf / hf, 0.1, 100.0); 52} 53 54static void 55init_opengl (void) 56{ 57 58 if (!ShadersSupported ()) 59 exit (1); 60 61 if (!glutExtensionSupported("GL_ARB_uniform_buffer_object")) { 62 printf("GL_ARB_uniform_buffer_object is required.\n"); 63 exit(1); 64 } 65 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); 69 70 UseProgram (prog_id); 71 72 reshape (680, 400); 73 74 glGenBuffers (1, &buffer_id); 75 76 glBindBuffer (GL_UNIFORM_BUFFER, buffer_id); 77 glBufferData (GL_UNIFORM_BUFFER, uniformBlockSize, NULL, GL_DYNAMIC_DRAW); 78 79 glBindBufferBase (GL_UNIFORM_BUFFER, 0, buffer_id); 80 glUniformBlockBinding (prog_id, uniformBlockIndex, 0); 81 82 glGetUniformIndices (prog_id, 1, &names[2], &uindex); 83 84 glGetActiveUniformsiv (prog_id, 1, &uindex, GL_UNIFORM_OFFSET, &offset); 85 glGetActiveUniformsiv (prog_id, 1, &uindex, GL_UNIFORM_SIZE, &singleSize); 86 87 glViewport (0, 0, 680, 400); 88 glBufferData (GL_UNIFORM_BUFFER, 80, colors, GL_DYNAMIC_DRAW); 89} 90 91static void 92render (void) 93{ 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); 98 99 glMatrixMode (GL_MODELVIEW); 100 glLoadIdentity (); 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); 105 106 glBindBuffer (GL_UNIFORM_BUFFER, buffer_id); 107 glBufferSubData (GL_UNIFORM_BUFFER, offset, 4 * singleSize, &teapot_color); 108 109 glFrontFace (GL_CW); 110 glutSolidTeapot (0.6); 111 glFrontFace (GL_CCW); 112 glutSwapBuffers (); 113 glutPostRedisplay (); 114 115 teapot_color += delta; 116 117 if (teapot_color > 1.0) 118 { 119 delta = -0.01; 120 } 121 122 if (teapot_color < 0.0) 123 { 124 delta = +0.01; 125 } 126 127} 128 129static void 130mouse (int button, int state, int x, int y) 131{ 132 if (state == GLUT_DOWN) 133 { 134 mouse_buttons |= 1 << button; 135 } 136 else if (state == GLUT_UP) 137 { 138 mouse_buttons = 0; 139 } 140 141 mouse_old_x = x; 142 mouse_old_y = y; 143 glutPostRedisplay (); 144} 145 146static void 147motion (int x, int y) 148{ 149 float dx, dy; 150 dx = x - mouse_old_x; 151 dy = y - mouse_old_y; 152 153 if (mouse_buttons & 1) 154 { 155 rotate_x += dy * 0.2; 156 rotate_y += dx * 0.2; 157 } 158 else if (mouse_buttons & 4) 159 { 160 translate_z += dy * 0.01; 161 } 162 163 mouse_old_x = x; 164 mouse_old_y = y; 165} 166 167int 168main (int argc, char **argv) 169{ 170 glutInit (&argc, argv); 171 glutInitWindowSize (400, 400); 172 glutInitDisplayMode (GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH); 173 glutCreateWindow ("UBO Example"); 174 175 glutDisplayFunc (render); 176 glutMouseFunc (mouse); 177 glutMotionFunc (motion); 178 glewInit (); 179 init_opengl (); 180 glutMainLoop (); 181 return 0; 182} 183