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

vlj vljn at ovi.com
Sat Nov 12 15:49:38 PST 2011


   blinking-teapot is an UBO demo.
---
 src/glsl/CMakeLists.txt    |    1 +
 src/glsl/Makefile.am       |    2 +
 src/glsl/blinking-teapot.c |  233 ++++++++++++++++++++++++++++++++++++++++++++
 src/glsl/shader.frag       |   31 ++++++
 src/glsl/shader.vert       |   16 +++
 5 files changed, 283 insertions(+), 0 deletions(-)
 create mode 100644 src/glsl/blinking-teapot.c
 create mode 100644 src/glsl/shader.frag
 create mode 100644 src/glsl/shader.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..c7f0319
--- /dev/null
+++ b/src/glsl/blinking-teapot.c
@@ -0,0 +1,233 @@
+/**
+ * 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>
+#define GL_GLEXT_PROTOTYPES 1
+#define GLX_GLXEXT_PROTOTYPES 1
+#include <GL/gl.h>
+#include <GL/freeglut.h>
+#include <GL/glx.h>
+#include <GL/glext.h>
+
+#include <malloc.h>
+#include <fcntl.h>
+#include <string.h>
+#include <sys/types.h>
+#include <unistd.h>
+ 
+ 
+char *textFileRead(char *fn) {
+ 
+ 
+	FILE *fp;
+	char *content = NULL;
+ 
+	int f,count;
+	f = open(fn, O_RDONLY);
+ 
+	count = lseek(f, 0, SEEK_END);
+ 
+	close(f);
+ 
+	if (fn != NULL) {
+		fp = fopen(fn,"rt");
+ 
+		if (fp != NULL) {
+ 
+ 
+			if (count > 0) {
+				content = (char *)malloc(sizeof(char) * (count+1));
+				count = fread(content,sizeof(char),count,fp);
+				content[count] = '\0';
+			}
+			fclose(fp);
+		}
+	}
+	return content;
+}
+
+char *VertexShaderSource, *FragmentShaderSource;
+
+// mouse controls
+int mouse_old_x, mouse_old_y;
+int mouse_buttons = 0;
+float rotate_x = 0.0, rotate_y = 0.0;
+float translate_z = -2.0;
+
+#define glError() { \
+    GLenum err = glGetError(); \
+    while (err != GL_NO_ERROR) { \
+    printf("glError: %s caught at %s:%u", \
+           (char*)gluErrorString(err), __FILE__, __LINE__); \
+    err = glGetError(); \
+    exit(-1); \
+    } \
+    }
+
+// globals
+int initialized = 0;
+unsigned int window_width = 640;
+unsigned int window_height = 480;
+
+float delta = 0.01;
+GLfloat wf, hf;
+
+//uniform names
+const GLchar* names[] = { "SurfaceColor", "WarmColor", "CoolColor",
+		"DiffuseWarm", "DiffuseCool" };
+static GLuint buffer_id, uniformBlockIndex, uindex, vshad_id, fshad_id, prog_id;
+static char* vs_file = "shader.vert";
+static char* fs_file = "shader.frag";
+
+GLsizei uniformBlockSize;
+GLint singleSize;
+GLint offset;
+
+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, };
+
+void reshape(int w, int h) {
+	window_width = w;
+	window_height = h;
+	wf = (GLfloat) window_width;
+	hf = (GLfloat) window_height;
+	glMatrixMode( GL_PROJECTION);
+	glLoadIdentity();
+	gluPerspective(60.0, wf / hf, 0.1, 100.0);
+}
+
+static
+void init_opengl() {
+	initialized = 1;
+	reshape(window_width, window_height);
+
+	VertexShaderSource = textFileRead("shader.vert");
+	FragmentShaderSource = textFileRead("shader.frag");
+
+	const char * VS = VertexShaderSource;
+	const char * FS = FragmentShaderSource;
+
+	vshad_id = glCreateShader(GL_VERTEX_SHADER);
+	glShaderSource(vshad_id, 1, &VS, 0);
+
+	fshad_id = glCreateShader(GL_FRAGMENT_SHADER);
+	glShaderSource(fshad_id, 1, &FS, NULL);
+
+	glCompileShader(vshad_id);
+	glCompileShader(fshad_id);
+
+	prog_id = glCreateProgram();
+	glAttachShader(prog_id, vshad_id);
+	glAttachShader(prog_id, fshad_id);
+	glLinkProgram(prog_id);
+
+	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, window_width, window_height);
+	glBufferData(GL_UNIFORM_BUFFER, 80, colors, GL_DYNAMIC_DRAW);
+}
+
+void render() {
+	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, &colors[8]);
+
+	glFrontFace( GL_CW);
+	glutSolidTeapot(0.6);
+	glFrontFace( GL_CCW);
+	glutSwapBuffers();
+	glutPostRedisplay();
+
+	int nColor = 8;
+	colors[nColor] += delta;
+
+	if (colors[nColor] > 1.0) {
+		delta = -0.01;
+	}
+
+	if (colors[nColor] < 0.0) {
+		delta = +0.01;
+	}
+
+}
+
+void display() {
+	if (!initialized) {
+		init_opengl();
+		initialized = 1;
+	}
+
+	render();
+}
+
+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();
+}
+
+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;
+}
+
+int main(int argc, char** argv) {
+	glutInit(&argc, argv);
+	glutInitWindowSize(400, 400);
+	glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH);
+	glutCreateWindow("UBO Example");
+	// register callbacks
+	glutDisplayFunc(display);
+	//glutKeyboardFunc( keyboard);
+	glutMouseFunc(mouse);
+	glutMotionFunc(motion);
+	init_opengl();
+	glutMainLoop();
+	return 0;
+}
diff --git a/src/glsl/shader.frag b/src/glsl/shader.frag
new file mode 100644
index 0000000..0db060b
--- /dev/null
+++ b/src/glsl/shader.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/shader.vert b/src/glsl/shader.vert
new file mode 100644
index 0000000..397d733
--- /dev/null
+++ b/src/glsl/shader.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