Merge pull request #539 from ey6es/master

Better iris texture, fixed iris rotations.
This commit is contained in:
ZappoMan 2013-06-14 16:53:47 -07:00
commit 17ea2d0d0d
5 changed files with 51 additions and 46 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 152 KiB

After

Width:  |  Height:  |  Size: 71 KiB

View file

@ -15,7 +15,10 @@ uniform sampler2D texture;
varying vec4 normal; varying vec4 normal;
void main(void) { void main(void) {
// compute the specular component (sans exponent) based on the normal OpenGL lighting model
float specular = max(0.0, dot(normalize(gl_LightSource[0].position + vec4(0.0, 0.0, 1.0, 0.0)), normalize(normal))); float specular = max(0.0, dot(normalize(gl_LightSource[0].position + vec4(0.0, 0.0, 1.0, 0.0)), normalize(normal)));
gl_FragColor = vec4(gl_Color.rgb * texture2D(texture, gl_TexCoord[0].st).rgb +
pow(specular, gl_FrontMaterial.shininess) * gl_FrontLightProduct[0].specular.rgb, 1.0); // modulate texture by diffuse color and add specular contribution
gl_FragColor = gl_Color * texture2D(texture, gl_TexCoord[0].st) +
pow(specular, gl_FrontMaterial.shininess) * gl_FrontLightProduct[0].specular;
} }

View file

@ -11,10 +11,23 @@
// the interpolated normal // the interpolated normal
varying vec4 normal; varying vec4 normal;
// the ratio of the indices of refraction
const float refractionEta = 0.75;
void main(void) { void main(void) {
// transform and store the normal for interpolation
normal = normalize(gl_ModelViewMatrix * vec4(gl_Normal, 0.0)); normal = normalize(gl_ModelViewMatrix * vec4(gl_Normal, 0.0));
gl_FrontColor = gl_Color * (gl_LightModel.ambient + gl_LightSource[0].ambient +
gl_LightSource[0].diffuse * max(0.0, dot(normal, gl_LightSource[0].position))); // compute standard diffuse lighting per-vertex
gl_TexCoord[0] = gl_MultiTexCoord0; gl_FrontColor = vec4(gl_Color.rgb * (gl_LightModel.ambient.rgb + gl_LightSource[0].ambient.rgb +
gl_LightSource[0].diffuse.rgb * max(0.0, dot(normal, gl_LightSource[0].position))), gl_Color.a);
// compute the texture coordinate based on where refracted vector hits z=0 in model space
vec4 incidence = normalize(gl_Vertex - gl_ModelViewMatrixInverse * vec4(0.0, 0.0, 0.0, 1.0));
vec4 refracted = refract(incidence, normalize(vec4(gl_Normal, 0.0)), refractionEta);
gl_TexCoord[0] = (gl_Vertex - (gl_Vertex.z / refracted.z) * refracted) + vec4(0.5, 0.5, 0.0, 0.0);
// use standard pipeline transform
gl_Position = ftransform(); gl_Position = ftransform();
} }

View file

@ -87,12 +87,14 @@ void Head::init() {
_irisProgram->setUniformValue("texture", 0); _irisProgram->setUniformValue("texture", 0);
QImage image = QImage(IRIS_TEXTURE_FILENAME).convertToFormat(QImage::Format_RGB888); QImage image = QImage(IRIS_TEXTURE_FILENAME).convertToFormat(QImage::Format_ARGB32);
glGenTextures(1, &_irisTextureID); glGenTextures(1, &_irisTextureID);
glBindTexture(GL_TEXTURE_2D, _irisTextureID); glBindTexture(GL_TEXTURE_2D, _irisTextureID);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, image.width(), image.height(), 0, GL_RGB, GL_UNSIGNED_BYTE, image.constBits()); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, image.width(), image.height(), 1, GL_BGRA, GL_UNSIGNED_BYTE, image.constBits());
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
glBindTexture(GL_TEXTURE_2D, 0); glBindTexture(GL_TEXTURE_2D, 0);
} }
} }
@ -462,73 +464,60 @@ void Head::renderEyeBrows() {
void Head::renderEyeBalls() { void Head::renderEyeBalls() {
// setup the texture to be used on each iris
GLUquadric* irisQuadric = gluNewQuadric();
gluQuadricTexture(irisQuadric, GL_TRUE);
gluQuadricOrientation(irisQuadric, GLU_OUTSIDE);
// render white ball of left eyeball // render white ball of left eyeball
glPushMatrix(); glPushMatrix();
glColor3fv(EYEBALL_COLOR); glColor3fv(EYEBALL_COLOR);
glTranslatef(_leftEyePosition.x, _leftEyePosition.y, _leftEyePosition.z); glTranslatef(_leftEyePosition.x, _leftEyePosition.y, _leftEyePosition.z);
gluSphere(irisQuadric, EYEBALL_RADIUS, 30, 30); glutSolidSphere(EYEBALL_RADIUS, 30, 30);
glPopMatrix(); glPopMatrix();
//render white ball of right eyeball //render white ball of right eyeball
glPushMatrix(); glPushMatrix();
glColor3fv(EYEBALL_COLOR); glColor3fv(EYEBALL_COLOR);
glTranslatef(_rightEyePosition.x, _rightEyePosition.y, _rightEyePosition.z); glTranslatef(_rightEyePosition.x, _rightEyePosition.y, _rightEyePosition.z);
gluSphere(irisQuadric, EYEBALL_RADIUS, 30, 30); glutSolidSphere(EYEBALL_RADIUS, 30, 30);
glPopMatrix(); glPopMatrix();
_irisProgram->bind(); _irisProgram->bind();
glBindTexture(GL_TEXTURE_2D, _irisTextureID); glBindTexture(GL_TEXTURE_2D, _irisTextureID);
glEnable(GL_TEXTURE_2D); glEnable(GL_TEXTURE_2D);
glm::vec3 front = getFrontDirection(); glm::quat orientation = getOrientation();
glm::vec3 front = orientation * IDENTITY_FRONT;
// render left iris // render left iris
glPushMatrix(); { glPushMatrix(); {
glTranslatef(_leftEyePosition.x, _leftEyePosition.y, _leftEyePosition.z); //translate to eyeball position glTranslatef(_leftEyePosition.x, _leftEyePosition.y, _leftEyePosition.z); //translate to eyeball position
glPushMatrix();
//rotate the eyeball to aim towards the lookat position //rotate the eyeball to aim towards the lookat position
glm::vec3 targetLookatAxis = glm::normalize(_lookAtPosition + _saccade - _leftEyePosition); glm::vec3 targetLookatVector = _lookAtPosition + _saccade - _leftEyePosition;
glm::vec3 rotationAxis = glm::cross(targetLookatAxis, IDENTITY_UP); glm::quat rotation = rotationBetween(front, targetLookatVector) * orientation;
float angle = 180.0f - angleBetween(targetLookatAxis, IDENTITY_UP); glm::vec3 rotationAxis = glm::axis(rotation);
glRotatef(angle, rotationAxis.x, rotationAxis.y, rotationAxis.z); glRotatef(glm::angle(rotation), rotationAxis.x, rotationAxis.y, rotationAxis.z);
glRotatef(180.0, 0.0f, 1.0f, 0.0f); //adjust roll to correct after previous rotations glTranslatef(0.0f, 0.0f, -IRIS_PROTRUSION);
glTranslatef( 0.0f, -IRIS_PROTRUSION, 0.0f); glScalef(IRIS_RADIUS * 2.0f, IRIS_RADIUS * 2.0f, IRIS_RADIUS); // flatten the iris
glScalef( 1.0f, 0.5f, 1.0f); // flatten the iris glutSolidSphere(0.5f, 15, 15);
gluSphere(irisQuadric, IRIS_RADIUS, 15, 15);
glPopMatrix();
} }
glPopMatrix(); glPopMatrix();
// render right iris // render right iris
glPushMatrix(); { glPushMatrix(); {
glTranslatef(_rightEyePosition.x, _rightEyePosition.y, _rightEyePosition.z); //translate to eyeball position glTranslatef(_rightEyePosition.x, _rightEyePosition.y, _rightEyePosition.z); //translate to eyeball position
glPushMatrix();
//rotate the eyeball to aim towards the lookat position //rotate the eyeball to aim towards the lookat position
glm::vec3 targetLookatAxis = glm::normalize(_lookAtPosition + _saccade - _rightEyePosition); glm::vec3 targetLookatVector = _lookAtPosition + _saccade - _rightEyePosition;
glm::vec3 rotationAxis = glm::cross(targetLookatAxis, IDENTITY_UP); glm::quat rotation = rotationBetween(front, targetLookatVector) * orientation;
float angle = 180.0f - angleBetween(targetLookatAxis, IDENTITY_UP); glm::vec3 rotationAxis = glm::axis(rotation);
glRotatef(angle, rotationAxis.x, rotationAxis.y, rotationAxis.z); glRotatef(glm::angle(rotation), rotationAxis.x, rotationAxis.y, rotationAxis.z);
glRotatef(180.0f, 0.0f, 1.0f, 0.0f); //adjust roll to correct after previous rotations glTranslatef(0.0f, 0.0f, -IRIS_PROTRUSION);
glTranslatef( 0.0f, -IRIS_PROTRUSION, 0.0f); glScalef(IRIS_RADIUS * 2.0f, IRIS_RADIUS * 2.0f, IRIS_RADIUS); // flatten the iris
glScalef( 1.0f, 0.5f, 1.0f); // flatten the iris glutSolidSphere(0.5f, 15, 15);
gluSphere(irisQuadric, IRIS_RADIUS, 15, 15);
glPopMatrix();
} }
glPopMatrix();
_irisProgram->release(); _irisProgram->release();
glBindTexture(GL_TEXTURE_2D, 0); glBindTexture(GL_TEXTURE_2D, 0);
glDisable(GL_TEXTURE_2D); glDisable(GL_TEXTURE_2D);
// delete the iris quadric now that we're done with it
gluDeleteQuadric(irisQuadric);
glPopMatrix();
} }
void Head::renderLookatVectors(glm::vec3 leftEyePosition, glm::vec3 rightEyePosition, glm::vec3 lookatPosition) { void Head::renderLookatVectors(glm::vec3 leftEyePosition, glm::vec3 rightEyePosition, glm::vec3 lookatPosition) {

View file

@ -85,7 +85,7 @@ glm::quat rotationBetween(const glm::vec3& v1, const glm::vec3& v2) {
if (isnan(angle) || angle < EPSILON) { if (isnan(angle) || angle < EPSILON) {
return glm::quat(); return glm::quat();
} }
glm::vec3 axis = glm::cross(v1, v2); glm::vec3 axis;
if (angle > 179.99f) { // 180 degree rotation; must use another axis if (angle > 179.99f) { // 180 degree rotation; must use another axis
axis = glm::cross(v1, glm::vec3(1.0f, 0.0f, 0.0f)); axis = glm::cross(v1, glm::vec3(1.0f, 0.0f, 0.0f));
float axisLength = glm::length(axis); float axisLength = glm::length(axis);