added glsl/skinning.c test to test matrix blending/weighting

This commit is contained in:
Brian Paul
2008-11-04 16:56:59 -07:00
parent 6c8274078d
commit aab429c8df
5 changed files with 340 additions and 2 deletions
+8
View File
@@ -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
+22 -2
View File
@@ -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
*/
+280
View File
@@ -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;
}
+6
View File
@@ -0,0 +1,6 @@
// color pass-through
void main()
{
gl_FragColor = gl_Color;
}
+24
View File
@@ -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;
}