added glsl/skinning.c test to test matrix blending/weighting
This commit is contained in:
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
*/
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
// color pass-through
|
||||
|
||||
void main()
|
||||
{
|
||||
gl_FragColor = gl_Color;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
Reference in New Issue
Block a user