diff options
author | Brian Paul <brian.paul@tungstengraphics.com> | 2008-11-04 16:56:59 -0700 |
---|---|---|
committer | Brian Paul <brian.paul@tungstengraphics.com> | 2008-11-04 16:56:59 -0700 |
commit | aab429c8df228271786890691a43786baf091b37 (patch) | |
tree | d8b66a8071a7c803e0d6f77dae2054cfcea10143 | |
parent | 6c8274078d08e5d87c993603b9bfcdf1ffa51278 (diff) |
added glsl/skinning.c test to test matrix blending/weighting
-rw-r--r-- | progs/glsl/Makefile | 8 | ||||
-rw-r--r-- | progs/glsl/multitex.frag | 24 | ||||
-rw-r--r-- | progs/glsl/skinning.c | 280 | ||||
-rw-r--r-- | progs/glsl/skinning.frag | 6 | ||||
-rw-r--r-- | progs/glsl/skinning.vert | 24 |
5 files changed, 340 insertions, 2 deletions
diff --git a/progs/glsl/Makefile b/progs/glsl/Makefile index 850b6bdbd..41d584991 100644 --- a/progs/glsl/Makefile +++ b/progs/glsl/Makefile @@ -20,6 +20,7 @@ PROGS = \ noise \ points \ pointcoord \ + skinning \ texdemo1 \ toyball \ twoside \ @@ -140,6 +141,13 @@ pointcoord: pointcoord.o readtex.o shaderutil.o $(CC) -I$(INCDIR) $(CFLAGS) $(LDFLAGS) pointcoord.o readtex.o shaderutil.o $(LIBS) -o $@ +skinning.o: skinning.c readtex.h extfuncs.h shaderutil.h + $(CC) -c -I$(INCDIR) $(CFLAGS) skinning.c + +skinning: skinning.o readtex.o shaderutil.o + $(CC) -I$(INCDIR) $(CFLAGS) $(LDFLAGS) skinning.o readtex.o shaderutil.o $(LIBS) -o $@ + + texdemo1.o: texdemo1.c readtex.h extfuncs.h shaderutil.h $(CC) -c -I$(INCDIR) $(CFLAGS) texdemo1.c diff --git a/progs/glsl/multitex.frag b/progs/glsl/multitex.frag index a2633ceba..61ef95f3f 100644 --- a/progs/glsl/multitex.frag +++ b/progs/glsl/multitex.frag @@ -7,9 +7,29 @@ uniform sampler2D tex1; uniform sampler2D tex2; -void main() +vec4 sample(sampler2D t, vec2 coord) +{ + return texture2D(t, coord); +} + +void main0() { vec4 t1 = texture2D(tex1, gl_TexCoord[0].xy); - vec4 t2 = texture2D(tex2, gl_TexCoord[1].xy); + //vec4 t1 = sample(tex1, gl_TexCoord[0].xy); + //vec4 t2 = texture2D(tex2, gl_TexCoord[1].xy); + vec4 t2 = sample(tex2, gl_TexCoord[0].xy); gl_FragColor = mix(t1, t2, t2.w); } + +void main() +{ + vec4 t1 = sample(tex1, gl_TexCoord[0].xy); + vec4 t2 = sample(tex2, gl_TexCoord[0].xy); + gl_FragColor = t1 + t2; +} +/* + 0: MOV SAMPLER[0].x, SAMPLER[0]; + 1: MOV TEMP[1], INPUT[4]; + 2: TEX OUTPUT[0], TEMP[1], texture[0], 2D; + 3: END +*/ diff --git a/progs/glsl/skinning.c b/progs/glsl/skinning.c new file mode 100644 index 000000000..8a65d0667 --- /dev/null +++ b/progs/glsl/skinning.c @@ -0,0 +1,280 @@ +/** + * Vertex "skinning" example. + * The idea is there are multiple modeling matrices applied to every + * vertex. Weighting values in [0,1] control the influence of each + * matrix on each vertex. + * + * 4 Nov 2008 + */ + +#include <assert.h> +#include <string.h> +#include <stdio.h> +#include <stdlib.h> +#include <math.h> +#include <GL/gl.h> +#include <GL/glut.h> +#include <GL/glext.h> +#include "extfuncs.h" +#include "shaderutil.h" + + +static char *FragProgFile = "skinning.frag"; +static char *VertProgFile = "skinning.vert"; + +/* program/shader objects */ +static GLuint fragShader; +static GLuint vertShader; +static GLuint program; + + +static GLint win = 0; +static GLboolean Anim = GL_TRUE; +static GLboolean WireFrame = GL_TRUE; +static GLfloat xRot = 0.0f, yRot = 90.0f, zRot = 0.0f; + +#define NUM_MATS 2 + +static GLfloat Matrices[NUM_MATS][16]; +static GLint uMat0, uMat1; +static GLint WeightAttr; + + +static void +Idle(void) +{ + yRot = 90 + glutGet(GLUT_ELAPSED_TIME) * 0.005; + glutPostRedisplay(); +} + + +static void +Cylinder(GLfloat length, GLfloat radius, GLint slices, GLint stacks) +{ + float dw = 1.0 / (stacks - 1); + float dz = length / stacks; + int i, j; + + for (j = 0; j < stacks; j++) { + float w0 = j * dw; + float z0 = j * dz; + + glBegin(GL_TRIANGLE_STRIP); + for (i = 0; i < slices; i++) { + float a = (float) i / (slices - 1) * M_PI * 2.0; + float x = radius * cos(a); + float y = radius * sin(a); + glVertexAttrib1f_func(WeightAttr, w0); + glNormal3f(x, y, 0.0); + glVertex3f(x, y, z0); + + glVertexAttrib1f_func(WeightAttr, w0 + dw); + glNormal3f(x, y, 0.0); + glVertex3f(x, y, z0 + dz); + } + glEnd(); + } +} + + +/** + * Update/animate the two matrices. One rotates, the other scales. + */ +static void +UpdateMatrices(void) +{ + GLfloat t = glutGet(GLUT_ELAPSED_TIME) * 0.0025; + GLfloat scale = 0.5 * (1.1 + sin(0.5 * t)); + GLfloat rot = cos(t) * 90.0; + + glPushMatrix(); + glLoadIdentity(); + glScalef(1.0, scale, 1.0); + glGetFloatv(GL_MODELVIEW_MATRIX, Matrices[0]); + glPopMatrix(); + + glPushMatrix(); + glLoadIdentity(); + glRotatef(rot, 0, 0, 1); + glGetFloatv(GL_MODELVIEW_MATRIX, Matrices[1]); + glPopMatrix(); +} + + +static void +Redisplay(void) +{ + UpdateMatrices(); + + glUniformMatrix4fv_func(uMat0, 1, GL_FALSE, Matrices[0]); + glUniformMatrix4fv_func(uMat1, 1, GL_FALSE, Matrices[1]); + + if (WireFrame) + glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); + else + glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); + + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + glPushMatrix(); + glRotatef(xRot, 1.0f, 0.0f, 0.0f); + glRotatef(yRot, 0.0f, 1.0f, 0.0f); + glRotatef(zRot, 0.0f, 0.0f, 1.0f); + + glPushMatrix(); + glTranslatef(0, 0, -2.5); + Cylinder(5.0, 1.0, 10, 20); + glPopMatrix(); + + glPopMatrix(); + + glutSwapBuffers(); +} + + +static void +Reshape(int width, int height) +{ + glViewport(0, 0, width, height); + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + glFrustum(-1.0, 1.0, -1.0, 1.0, 5.0, 25.0); + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + glTranslatef(0.0f, 0.0f, -15.0f); +} + + +static void +CleanUp(void) +{ + glDeleteShader_func(fragShader); + glDeleteShader_func(vertShader); + glDeleteProgram_func(program); + glutDestroyWindow(win); +} + + +static void +Key(unsigned char key, int x, int y) +{ + const GLfloat step = 2.0; + (void) x; + (void) y; + + switch(key) { + case 'a': + Anim = !Anim; + if (Anim) + glutIdleFunc(Idle); + else + glutIdleFunc(NULL); + break; + case 'w': + WireFrame = !WireFrame; + break; + case 'z': + zRot += step; + break; + case 'Z': + zRot -= step; + break; + case 27: + CleanUp(); + exit(0); + break; + } + glutPostRedisplay(); +} + + +static void +SpecialKey(int key, int x, int y) +{ + const GLfloat step = 2.0; + + (void) x; + (void) y; + + switch(key) { + case GLUT_KEY_UP: + xRot += step; + break; + case GLUT_KEY_DOWN: + xRot -= step; + break; + case GLUT_KEY_LEFT: + yRot -= step; + break; + case GLUT_KEY_RIGHT: + yRot += step; + break; + } + glutPostRedisplay(); +} + + + +static void +Init(void) +{ + if (!ShadersSupported()) + exit(1); + + GetExtensionFuncs(); + + vertShader = CompileShaderFile(GL_VERTEX_SHADER, VertProgFile); + fragShader = CompileShaderFile(GL_FRAGMENT_SHADER, FragProgFile); + program = LinkShaders(vertShader, fragShader); + + glUseProgram_func(program); + + uMat0 = glGetUniformLocation_func(program, "mat0"); + uMat1 = glGetUniformLocation_func(program, "mat1"); + + WeightAttr = glGetAttribLocation_func(program, "weight"); + + assert(glGetError() == 0); + + glClearColor(0.4f, 0.4f, 0.8f, 0.0f); + + glEnable(GL_DEPTH_TEST); + + glColor3f(1, 0, 0); +} + + +static void +ParseOptions(int argc, char *argv[]) +{ + int i; + for (i = 1; i < argc; i++) { + if (strcmp(argv[i], "-fs") == 0) { + FragProgFile = argv[i+1]; + } + else if (strcmp(argv[i], "-vs") == 0) { + VertProgFile = argv[i+1]; + } + } +} + + +int +main(int argc, char *argv[]) +{ + glutInit(&argc, argv); + glutInitWindowSize(500, 500); + glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH); + win = glutCreateWindow(argv[0]); + glutReshapeFunc(Reshape); + glutKeyboardFunc(Key); + glutSpecialFunc(SpecialKey); + glutDisplayFunc(Redisplay); + ParseOptions(argc, argv); + Init(); + if (Anim) + glutIdleFunc(Idle); + glutMainLoop(); + return 0; +} + diff --git a/progs/glsl/skinning.frag b/progs/glsl/skinning.frag new file mode 100644 index 000000000..9053755a8 --- /dev/null +++ b/progs/glsl/skinning.frag @@ -0,0 +1,6 @@ +// color pass-through + +void main() +{ + gl_FragColor = gl_Color; +} diff --git a/progs/glsl/skinning.vert b/progs/glsl/skinning.vert new file mode 100644 index 000000000..28970eee5 --- /dev/null +++ b/progs/glsl/skinning.vert @@ -0,0 +1,24 @@ +// Vertex weighting/blendin shader +// Brian Paul +// 4 Nov 2008 + +uniform mat4 mat0, mat1; +attribute float weight; + +void main() +{ + // simple diffuse shading + // Note that we should really transform the normal vector along with + // the postion below... someday. + vec3 lightVec = vec3(0, 0, 1); + vec3 norm = gl_NormalMatrix * gl_Normal; + float dot = 0.2 + max(0.0, dot(norm, lightVec)); + gl_FrontColor = vec4(dot); + + // compute sum of weighted transformations + vec4 pos0 = mat0 * gl_Vertex; + vec4 pos1 = mat1 * gl_Vertex; + vec4 pos = mix(pos0, pos1, weight); + + gl_Position = gl_ModelViewProjectionMatrix * pos; +} |