[Mesa-dev] [PATCH] mesa-demos: Add blinking-teapot demo.

vlj vljn at ovi.com
Thu Nov 17 05:35:26 PST 2011


   blinking-teapot is an UBO demo.
---
 src/glsl/CMakeLists.txt       |    1 +
 src/glsl/Makefile.am          |    2 +
 src/glsl/blinking-teapot.c    |  207 +++++++++++++++++++++++++++++++++++++++++
 src/glsl/blinking-teapot.frag |   31 ++++++
 src/glsl/blinking-teapot.vert |   16 +++
 5 files changed, 257 insertions(+), 0 deletions(-)
 create mode 100644 src/glsl/blinking-teapot.c
 create mode 100644 src/glsl/blinking-teapot.frag
 create mode 100644 src/glsl/blinking-teapot.vert

diff --git a/src/glsl/CMakeLists.txt b/src/glsl/CMakeLists.txt
index 11f8e37..aeaf526 100644
--- a/src/glsl/CMakeLists.txt
+++ b/src/glsl/CMakeLists.txt
@@ -24,6 +24,7 @@ set (targets
 	bitmap
 	brick
 	bump
+	blinking-teapot
 	convolutions
 	deriv
 	fragcoord
diff --git a/src/glsl/Makefile.am b/src/glsl/Makefile.am
index 5a9a802..d9b6f9b 100644
--- a/src/glsl/Makefile.am
+++ b/src/glsl/Makefile.am
@@ -37,6 +37,7 @@ bin_PROGRAMS = \
 	bitmap \
 	brick \
 	bump \
+	blinking-teapot \
 	convolutions \
 	deriv \
 	fragcoord \
@@ -77,6 +78,7 @@ bitmap_LDADD = ../util/libutil.la
 bezier_LDADD = ../util/libutil.la
 brick_LDADD = ../util/libutil.la
 bump_LDADD = ../util/libutil.la
+blinking_teapot_LDADD = ../util/libutil.la
 convolutions_LDADD = ../util/libutil.la
 deriv_LDADD = ../util/libutil.la
 geom_sprites_LDADD = ../util/libutil.la
diff --git a/src/glsl/blinking-teapot.c b/src/glsl/blinking-teapot.c
new file mode 100644
index 0000000..d15bd5b
--- /dev/null
+++ b/src/glsl/blinking-teapot.c
@@ -0,0 +1,207 @@
+/**
+ * blinking-teapot demo. It displays a teapot whose color go from blue to pink.
+ * The color variation is handled by uniform buffer object.
+ * Sources mostly from http://www.jotschi.de/?p=427 which uses UBO SPEC example
+ *
+ * Vincent Lejeune 2011
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <GL/glew.h>
+#include "glut_wrap.h"
+#include "shaderutil.h"
+
+
+static int mouse_old_x, mouse_old_y;
+static GLint win;
+static int mouse_buttons = 0;
+static float rotate_x = 0.0, rotate_y = 0.0;
+static float translate_z = -2.0;
+
+static float delta = 0.01;
+static GLfloat wf, hf;
+
+
+static const GLchar *names[] = { "SurfaceColor", "WarmColor", "CoolColor",
+  "DiffuseWarm", "DiffuseCool"
+};
+
+static GLuint buffer_id, uniformBlockIndex, uindex, vshad_id, fshad_id,
+  prog_id;
+
+static GLsizei uniformBlockSize;
+static GLint singleSize;
+static GLint offset;
+
+static const GLfloat colors[] =
+  { 0.45, 0.45, 1, 1, 0.45, 0.45, 1, 1, 0.75, 0.75, 0.75, 1,
+  0.0, 0.0, 1.0, 1, 0.0, 1.0, 0.0, 1,
+};
+
+static GLfloat teapot_color = 1;
+
+static void
+reshape (int w, int h)
+{
+  wf = (GLfloat) w;
+  hf = (GLfloat) h;
+  glMatrixMode (GL_PROJECTION);
+  glLoadIdentity ();
+  gluPerspective (60.0, wf / hf, 0.1, 100.0);
+}
+
+static void
+init_opengl (void)
+{
+
+  if (!ShadersSupported ())
+    exit (1);
+
+  if (!glutExtensionSupported ("GL_ARB_uniform_buffer_object"))
+    {
+      fprintf (stderr,
+	       "Sorry, GL_ARB_uniform_buffer_object is not supported.\n");
+      exit (1);
+    }
+
+  vshad_id = CompileShaderFile (GL_VERTEX_SHADER, "blinking-teapot.vert");
+  fshad_id = CompileShaderFile (GL_FRAGMENT_SHADER, "blinking-teapot.frag");
+  prog_id = LinkShaders (vshad_id, fshad_id);
+
+  UseProgram (prog_id);
+
+  reshape (680, 400);
+
+  glGenBuffers (1, &buffer_id);
+
+  glBindBuffer (GL_UNIFORM_BUFFER, buffer_id);
+  glBufferData (GL_UNIFORM_BUFFER, uniformBlockSize, NULL, GL_DYNAMIC_DRAW);
+
+  glBindBufferBase (GL_UNIFORM_BUFFER, 0, buffer_id);
+  glUniformBlockBinding (prog_id, uniformBlockIndex, 0);
+
+  glGetUniformIndices (prog_id, 1, &names[2], &uindex);
+
+  glGetActiveUniformsiv (prog_id, 1, &uindex, GL_UNIFORM_OFFSET, &offset);
+  glGetActiveUniformsiv (prog_id, 1, &uindex, GL_UNIFORM_SIZE, &singleSize);
+
+  glViewport (0, 0, 680, 400);
+  glBufferData (GL_UNIFORM_BUFFER, 80, colors, GL_DYNAMIC_DRAW);
+}
+
+static void
+render (void)
+{
+  glClearColor (0.0, 0.0, 0.0, 0.0);
+  glClear (GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
+  glUseProgram (prog_id);
+  glEnable (GL_DEPTH_TEST);
+
+  glMatrixMode (GL_MODELVIEW);
+  glLoadIdentity ();
+  glTranslatef (0.0, 0.0, translate_z);
+  glRotatef (rotate_x, 1.0, 0.0, 0.0);
+  glRotatef (rotate_y, 0.0, 1.0, 0.0);
+  glColor3f (1.0, 1.0, 1.0);
+
+  glBindBuffer (GL_UNIFORM_BUFFER, buffer_id);
+  glBufferSubData (GL_UNIFORM_BUFFER, offset, 4 * singleSize, &teapot_color);
+
+  glFrontFace (GL_CW);
+  glutSolidTeapot (0.6);
+  glFrontFace (GL_CCW);
+  glutSwapBuffers ();
+  glutPostRedisplay ();
+
+  teapot_color += delta;
+
+  if (teapot_color > 1.0)
+    {
+      delta = -0.01;
+    }
+
+  if (teapot_color < 0.0)
+    {
+      delta = +0.01;
+    }
+
+}
+
+static void
+mouse (int button, int state, int x, int y)
+{
+  if (state == GLUT_DOWN)
+    {
+      mouse_buttons |= 1 << button;
+    }
+  else if (state == GLUT_UP)
+    {
+      mouse_buttons = 0;
+    }
+
+  mouse_old_x = x;
+  mouse_old_y = y;
+  glutPostRedisplay ();
+}
+
+static void
+motion (int x, int y)
+{
+  float dx, dy;
+  dx = x - mouse_old_x;
+  dy = y - mouse_old_y;
+
+  if (mouse_buttons & 1)
+    {
+      rotate_x += dy * 0.2;
+      rotate_y += dx * 0.2;
+    }
+  else if (mouse_buttons & 4)
+    {
+      translate_z += dy * 0.01;
+    }
+
+  mouse_old_x = x;
+  mouse_old_y = y;
+}
+
+static void
+CleanUp (void)
+{
+  DeleteShader (fshad_id);
+  DeleteShader (vshad_id);
+  DeleteProgram (prog_id);
+  glutDestroyWindow (win);
+}
+
+
+static void
+keyboard (unsigned char key, int x, int y)
+{
+  switch (key)
+    {
+    case 27:
+      CleanUp ();
+      exit (0);
+      break;
+    }
+}
+
+int
+main (int argc, char **argv)
+{
+  glutInit (&argc, argv);
+  glutInitWindowSize (400, 400);
+  glutInitDisplayMode (GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH);
+  win = glutCreateWindow ("UBO Example");
+  glutDisplayFunc (render);
+  glutMouseFunc (mouse);
+  glutMotionFunc (motion);
+  glutKeyboardFunc (keyboard);
+  glewInit ();
+  init_opengl ();
+  glutMainLoop ();
+  return 0;
+}
diff --git a/src/glsl/blinking-teapot.frag b/src/glsl/blinking-teapot.frag
new file mode 100644
index 0000000..0db060b
--- /dev/null
+++ b/src/glsl/blinking-teapot.frag
@@ -0,0 +1,31 @@
+#extension GL_ARB_uniform_buffer_object : enable
+
+layout(std140) uniform colors0
+{
+    float DiffuseCool;
+    float DiffuseWarm;
+    vec3  SurfaceColor;
+    vec3  WarmColor;
+    vec3  CoolColor;
+    vec4  some[8];
+};
+
+varying float NdotL;
+varying vec3  ReflectVec;
+varying vec3  ViewVec;
+
+void main (void)
+{
+
+    vec3 kcool    = min(CoolColor + DiffuseCool * SurfaceColor, 1.0);
+    vec3 kwarm    = min(WarmColor + DiffuseWarm * SurfaceColor, 1.0);
+    vec3 kfinal   = mix(kcool, kwarm, NdotL);
+
+    vec3 nreflect = normalize(ReflectVec);
+    vec3 nview    = normalize(ViewVec);
+
+    float spec    = max(dot(nreflect, nview), 0.0);
+    spec          = pow(spec, 32.0);
+
+    gl_FragColor = vec4 (min(kfinal + spec, 1.0), 1.0);
+}
diff --git a/src/glsl/blinking-teapot.vert b/src/glsl/blinking-teapot.vert
new file mode 100644
index 0000000..397d733
--- /dev/null
+++ b/src/glsl/blinking-teapot.vert
@@ -0,0 +1,16 @@
+vec3 LightPosition = vec3(0.0, 10.0, 4.0); 
+ 
+varying float NdotL;
+varying vec3  ReflectVec;
+varying vec3  ViewVec;
+ 
+void main(void)
+{
+    vec3 ecPos      = vec3 (gl_ModelViewMatrix * gl_Vertex);
+    vec3 tnorm      = normalize(gl_NormalMatrix * gl_Normal);
+    vec3 lightVec   = normalize(LightPosition - ecPos);
+    ReflectVec      = normalize(reflect(-lightVec, tnorm));
+    ViewVec         = normalize(-ecPos);
+    NdotL           = (dot(lightVec, tnorm) + 1.0) * 0.5;
+    gl_Position     = ftransform();
+}
-- 
1.7.7



More information about the mesa-dev mailing list