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

Brian Paul brianp at vmware.com
Mon Nov 14 07:11:06 PST 2011


On 11/12/2011 04:49 PM, vlj wrote:
>     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>

It would be best to use glew (#include <GL/glew.h>) instead of 
directly using glext.h


> +
> +#include<malloc.h>
> +#include<fcntl.h>
> +#include<string.h>
> +#include<sys/types.h>
> +#include<unistd.h>

Are all those unix headers needed?  It would be nice if the program 
would run on Windows too.


> +
> +
> +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;
> +}

There's a lot of extraneous whitespace in that function and the 
indentation isn't consistent with the rest of the code.  Maybe just 
run 'indent' on the whole thing.


> +
> +char *VertexShaderSource, *FragmentShaderSource;
> +
> +// mouse controls

Use C-style /* */ comments to avoid warnings with some compilers.


> +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); \
> +    } \
> +    }

This macro isn't used anywhere.


> +// 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, };

All those vars could be declared static, and some const.


> +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;

Put all declarations before code to avoid warnings.


> +
> +	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;
> +	}

Why are you doing this check here?  init_opengl() was already called 
in main().


> +
> +	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

This filename is too generic.  It should be something like 
blinking-teapot.frag.  Same thing for the vertex shader.

-Brian


More information about the mesa-dev mailing list