blinking-teapot is an UBO demo. --- src/glsl/CMakeLists.txt | 1 + src/glsl/Makefile.am | 2 + src/glsl/blinking-teapot.c | 233 +++++++++++++++++++++++++++++++++++++++++ src/glsl/blinking-teapot.frag | 31 ++++++ src/glsl/blinking-teapot.vert | 16 +++ 5 files changed, 283 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..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/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 _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/mesa-dev