132001f49Smrg/** 232001f49Smrg * blinking-teapot demo. It displays a teapot whose color go from blue to pink. 332001f49Smrg * The color variation is handled by uniform buffer object. 432001f49Smrg * Sources mostly from http://www.jotschi.de/?p=427 which uses UBO SPEC example 532001f49Smrg * 632001f49Smrg * Vincent Lejeune 2011 732001f49Smrg */ 832001f49Smrg 932001f49Smrg#include <stdio.h> 1032001f49Smrg#include <stdlib.h> 1132001f49Smrg#include <string.h> 1232001f49Smrg#include <GL/glew.h> 1332001f49Smrg#include "glut_wrap.h" 1432001f49Smrg#include "shaderutil.h" 1532001f49Smrg 1632001f49Smrg 1732001f49Smrgstatic int mouse_old_x, mouse_old_y; 1832001f49Smrgstatic int mouse_buttons = 0; 1932001f49Smrgstatic float rotate_x = 0.0, rotate_y = 0.0; 2032001f49Smrgstatic float translate_z = -2.0; 2132001f49Smrg 2232001f49Smrgstatic float delta = 0.01; 2332001f49Smrgstatic GLfloat wf, hf; 2432001f49Smrg 2532001f49Smrg 2632001f49Smrgstatic const GLchar *names[] = { "SurfaceColor", "WarmColor", "CoolColor", 2732001f49Smrg "DiffuseWarm", "DiffuseCool" 2832001f49Smrg}; 2932001f49Smrg 3032001f49Smrgstatic GLuint buffer_id, uniformBlockIndex, uindex, vshad_id, fshad_id, 3132001f49Smrg prog_id; 3232001f49Smrg 3332001f49Smrgstatic GLsizei uniformBlockSize; 3432001f49Smrgstatic GLint singleSize; 3532001f49Smrgstatic GLint offset; 3632001f49Smrg 3732001f49Smrgstatic const GLfloat colors[] = 3832001f49Smrg { 0.45, 0.45, 1, 1, 0.45, 0.45, 1, 1, 0.75, 0.75, 0.75, 1, 3932001f49Smrg 0.0, 0.0, 1.0, 1, 0.0, 1.0, 0.0, 1, 4032001f49Smrg}; 4132001f49Smrg 4232001f49Smrgstatic GLfloat teapot_color = 1; 4332001f49Smrg 4432001f49Smrgstatic void 4532001f49Smrgreshape (int w, int h) 4632001f49Smrg{ 4732001f49Smrg wf = (GLfloat) w; 4832001f49Smrg hf = (GLfloat) h; 4932001f49Smrg glMatrixMode (GL_PROJECTION); 5032001f49Smrg glLoadIdentity (); 5132001f49Smrg gluPerspective (60.0, wf / hf, 0.1, 100.0); 5232001f49Smrg} 5332001f49Smrg 5432001f49Smrgstatic void 5532001f49Smrginit_opengl (void) 5632001f49Smrg{ 5732001f49Smrg 5832001f49Smrg if (!ShadersSupported ()) 5932001f49Smrg exit (1); 6032001f49Smrg 6132001f49Smrg if (!glutExtensionSupported("GL_ARB_uniform_buffer_object")) { 6232001f49Smrg printf("GL_ARB_uniform_buffer_object is required.\n"); 6332001f49Smrg exit(1); 6432001f49Smrg } 6532001f49Smrg 6632001f49Smrg vshad_id = CompileShaderFile (GL_VERTEX_SHADER, "blinking-teapot.vert"); 6732001f49Smrg fshad_id = CompileShaderFile (GL_FRAGMENT_SHADER, "blinking-teapot.frag"); 6832001f49Smrg prog_id = LinkShaders (vshad_id, fshad_id); 6932001f49Smrg 7032001f49Smrg UseProgram (prog_id); 7132001f49Smrg 7232001f49Smrg reshape (680, 400); 7332001f49Smrg 7432001f49Smrg glGenBuffers (1, &buffer_id); 7532001f49Smrg 7632001f49Smrg glBindBuffer (GL_UNIFORM_BUFFER, buffer_id); 7732001f49Smrg glBufferData (GL_UNIFORM_BUFFER, uniformBlockSize, NULL, GL_DYNAMIC_DRAW); 7832001f49Smrg 7932001f49Smrg glBindBufferBase (GL_UNIFORM_BUFFER, 0, buffer_id); 8032001f49Smrg glUniformBlockBinding (prog_id, uniformBlockIndex, 0); 8132001f49Smrg 8232001f49Smrg glGetUniformIndices (prog_id, 1, &names[2], &uindex); 8332001f49Smrg 8432001f49Smrg glGetActiveUniformsiv (prog_id, 1, &uindex, GL_UNIFORM_OFFSET, &offset); 8532001f49Smrg glGetActiveUniformsiv (prog_id, 1, &uindex, GL_UNIFORM_SIZE, &singleSize); 8632001f49Smrg 8732001f49Smrg glViewport (0, 0, 680, 400); 8832001f49Smrg glBufferData (GL_UNIFORM_BUFFER, 80, colors, GL_DYNAMIC_DRAW); 8932001f49Smrg} 9032001f49Smrg 9132001f49Smrgstatic void 9232001f49Smrgrender (void) 9332001f49Smrg{ 9432001f49Smrg glClearColor (0.0, 0.0, 0.0, 0.0); 9532001f49Smrg glClear (GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT); 9632001f49Smrg glUseProgram (prog_id); 9732001f49Smrg glEnable (GL_DEPTH_TEST); 9832001f49Smrg 9932001f49Smrg glMatrixMode (GL_MODELVIEW); 10032001f49Smrg glLoadIdentity (); 10132001f49Smrg glTranslatef (0.0, 0.0, translate_z); 10232001f49Smrg glRotatef (rotate_x, 1.0, 0.0, 0.0); 10332001f49Smrg glRotatef (rotate_y, 0.0, 1.0, 0.0); 10432001f49Smrg glColor3f (1.0, 1.0, 1.0); 10532001f49Smrg 10632001f49Smrg glBindBuffer (GL_UNIFORM_BUFFER, buffer_id); 10732001f49Smrg glBufferSubData (GL_UNIFORM_BUFFER, offset, 4 * singleSize, &teapot_color); 10832001f49Smrg 10932001f49Smrg glFrontFace (GL_CW); 11032001f49Smrg glutSolidTeapot (0.6); 11132001f49Smrg glFrontFace (GL_CCW); 11232001f49Smrg glutSwapBuffers (); 11332001f49Smrg glutPostRedisplay (); 11432001f49Smrg 11532001f49Smrg teapot_color += delta; 11632001f49Smrg 11732001f49Smrg if (teapot_color > 1.0) 11832001f49Smrg { 11932001f49Smrg delta = -0.01; 12032001f49Smrg } 12132001f49Smrg 12232001f49Smrg if (teapot_color < 0.0) 12332001f49Smrg { 12432001f49Smrg delta = +0.01; 12532001f49Smrg } 12632001f49Smrg 12732001f49Smrg} 12832001f49Smrg 12932001f49Smrgstatic void 13032001f49Smrgmouse (int button, int state, int x, int y) 13132001f49Smrg{ 13232001f49Smrg if (state == GLUT_DOWN) 13332001f49Smrg { 13432001f49Smrg mouse_buttons |= 1 << button; 13532001f49Smrg } 13632001f49Smrg else if (state == GLUT_UP) 13732001f49Smrg { 13832001f49Smrg mouse_buttons = 0; 13932001f49Smrg } 14032001f49Smrg 14132001f49Smrg mouse_old_x = x; 14232001f49Smrg mouse_old_y = y; 14332001f49Smrg glutPostRedisplay (); 14432001f49Smrg} 14532001f49Smrg 14632001f49Smrgstatic void 14732001f49Smrgmotion (int x, int y) 14832001f49Smrg{ 14932001f49Smrg float dx, dy; 15032001f49Smrg dx = x - mouse_old_x; 15132001f49Smrg dy = y - mouse_old_y; 15232001f49Smrg 15332001f49Smrg if (mouse_buttons & 1) 15432001f49Smrg { 15532001f49Smrg rotate_x += dy * 0.2; 15632001f49Smrg rotate_y += dx * 0.2; 15732001f49Smrg } 15832001f49Smrg else if (mouse_buttons & 4) 15932001f49Smrg { 16032001f49Smrg translate_z += dy * 0.01; 16132001f49Smrg } 16232001f49Smrg 16332001f49Smrg mouse_old_x = x; 16432001f49Smrg mouse_old_y = y; 16532001f49Smrg} 16632001f49Smrg 16732001f49Smrgint 16832001f49Smrgmain (int argc, char **argv) 16932001f49Smrg{ 17032001f49Smrg glutInit (&argc, argv); 17132001f49Smrg glutInitWindowSize (400, 400); 17232001f49Smrg glutInitDisplayMode (GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH); 17332001f49Smrg glutCreateWindow ("UBO Example"); 17432001f49Smrg 17532001f49Smrg glutDisplayFunc (render); 17632001f49Smrg glutMouseFunc (mouse); 17732001f49Smrg glutMotionFunc (motion); 17832001f49Smrg glewInit (); 17932001f49Smrg init_opengl (); 18032001f49Smrg glutMainLoop (); 18132001f49Smrg return 0; 18232001f49Smrg} 183