From e401663459e9f49d57fa66917b1b5cbd386f6732 Mon Sep 17 00:00:00 2001 From: Andrzej Kapolka Date: Thu, 13 Jun 2013 15:58:49 -0700 Subject: [PATCH] Added per-pixel specular highlight to irises. --- interface/resources/shaders/iris.frag | 21 ++++++++++++ interface/resources/shaders/iris.vert | 20 +++++++++++ interface/src/Head.cpp | 49 ++++++++++++++++----------- interface/src/Head.h | 2 ++ 4 files changed, 72 insertions(+), 20 deletions(-) create mode 100644 interface/resources/shaders/iris.frag create mode 100644 interface/resources/shaders/iris.vert diff --git a/interface/resources/shaders/iris.frag b/interface/resources/shaders/iris.frag new file mode 100644 index 0000000000..2f5b06d6c6 --- /dev/null +++ b/interface/resources/shaders/iris.frag @@ -0,0 +1,21 @@ +#version 120 + +// +// iris.frag +// fragment shader +// +// Created by Andrzej Kapolka on 6/13/13. +// Copyright (c) 2013 High Fidelity, Inc. All rights reserved. +// + +// the iris texture +uniform sampler2D texture; + +// the interpolated normal +varying vec4 normal; + +void main(void) { + 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); +} diff --git a/interface/resources/shaders/iris.vert b/interface/resources/shaders/iris.vert new file mode 100644 index 0000000000..83602f3e99 --- /dev/null +++ b/interface/resources/shaders/iris.vert @@ -0,0 +1,20 @@ +#version 120 + +// +// iris.vert +// vertex shader +// +// Created by Andrzej Kapolka on 6/13/13. +// Copyright (c) 2013 High Fidelity, Inc. All rights reserved. +// + +// the interpolated normal +varying vec4 normal; + +void main(void) { + 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))); + gl_TexCoord[0] = gl_MultiTexCoord0; + gl_Position = ftransform(); +} diff --git a/interface/src/Head.cpp b/interface/src/Head.cpp index b8f89fbde6..bba9269b73 100644 --- a/interface/src/Head.cpp +++ b/interface/src/Head.cpp @@ -8,13 +8,13 @@ #include +#include + #include "Application.h" #include "Avatar.h" #include "Head.h" #include "Util.h" -#include -#include -#include +#include "renderer/ProgramObject.h" using namespace std; @@ -39,7 +39,8 @@ const float IRIS_RADIUS = 0.007; const float IRIS_PROTRUSION = 0.0145f; const char IRIS_TEXTURE_FILENAME[] = "resources/images/iris.png"; -GLuint Head::_irisTextureID = 0; +ProgramObject* Head::_irisProgram = 0; +GLuint Head::_irisTextureID; Head::Head(Avatar* owningAvatar) : HeadData((AvatarData*)owningAvatar), @@ -76,8 +77,15 @@ Head::Head(Avatar* owningAvatar) : } void Head::init() { - if (_irisTextureID == 0) { + if (_irisProgram == 0) { switchToResourcesParentIfRequired(); + _irisProgram = new ProgramObject(); + _irisProgram->addShaderFromSourceFile(QGLShader::Vertex, "resources/shaders/iris.vert"); + _irisProgram->addShaderFromSourceFile(QGLShader::Fragment, "resources/shaders/iris.frag"); + _irisProgram->link(); + + _irisProgram->setUniformValue("texture", 0); + QImage image = QImage(IRIS_TEXTURE_FILENAME).convertToFormat(QImage::Format_RGB888); glGenTextures(1, &_irisTextureID); @@ -483,12 +491,11 @@ void Head::renderEyeBrows() { void Head::renderEyeBalls() { - // setup the texutre to be used on each iris + // setup the texture to be used on each iris GLUquadric* irisQuadric = gluNewQuadric(); gluQuadricTexture(irisQuadric, GL_TRUE); gluQuadricOrientation(irisQuadric, GLU_OUTSIDE); - glBindTexture(GL_TEXTURE_2D, _irisTextureID); // render white ball of left eyeball glPushMatrix(); @@ -497,6 +504,17 @@ void Head::renderEyeBalls() { gluSphere(irisQuadric, EYEBALL_RADIUS, 30, 30); glPopMatrix(); + //render white ball of right eyeball + glPushMatrix(); + glColor3fv(EYEBALL_COLOR); + glTranslatef(_rightEyePosition.x, _rightEyePosition.y, _rightEyePosition.z); + gluSphere(irisQuadric, EYEBALL_RADIUS, 30, 30); + glPopMatrix(); + + _irisProgram->bind(); + glBindTexture(GL_TEXTURE_2D, _irisTextureID); + glEnable(GL_TEXTURE_2D); + glm::vec3 front = getFrontDirection(); // render left iris @@ -529,20 +547,11 @@ void Head::renderEyeBalls() { glTranslatef( 0.0f, -IRIS_PROTRUSION, 0.0f);//push the iris out a bit (otherwise - inside of eyeball!) glScalef( 1.0f, 0.5f, 1.0f); // flatten the iris - glEnable(GL_TEXTURE_2D); gluSphere(irisQuadric, IRIS_RADIUS, 15, 15); - glDisable(GL_TEXTURE_2D); glPopMatrix(); } glPopMatrix(); - //render white ball of right eyeball - glPushMatrix(); - glColor3fv(EYEBALL_COLOR); - glTranslatef(_rightEyePosition.x, _rightEyePosition.y, _rightEyePosition.z); - gluSphere(irisQuadric, EYEBALL_RADIUS, 30, 30); - glPopMatrix(); - // render right iris glPushMatrix(); { glTranslatef(_rightEyePosition.x, _rightEyePosition.y, _rightEyePosition.z); //translate to eyeball position @@ -574,17 +583,17 @@ void Head::renderEyeBalls() { glTranslatef( 0.0f, -IRIS_PROTRUSION, 0.0f);//push the iris out a bit (otherwise - inside of eyeball!) glScalef( 1.0f, 0.5f, 1.0f); // flatten the iris - glEnable(GL_TEXTURE_2D); gluSphere(irisQuadric, IRIS_RADIUS, 15, 15); - glDisable(GL_TEXTURE_2D); glPopMatrix(); } + _irisProgram->release(); + glBindTexture(GL_TEXTURE_2D, 0); + glDisable(GL_TEXTURE_2D); + // delete the iris quadric now that we're done with it gluDeleteQuadric(irisQuadric); glPopMatrix(); - - glBindTexture(GL_TEXTURE_2D, 0); } void Head::renderLookatVectors(glm::vec3 leftEyePosition, glm::vec3 rightEyePosition, glm::vec3 lookatPosition) { diff --git a/interface/src/Head.h b/interface/src/Head.h index 2deb638eff..6d0f7819e4 100644 --- a/interface/src/Head.h +++ b/interface/src/Head.h @@ -26,6 +26,7 @@ enum eyeContactTargets const int NUM_HAIR_TUFTS = 4; class Avatar; +class ProgramObject; class Head : public HeadData { public: @@ -105,6 +106,7 @@ private: glm::vec3* _mohawkTriangleFan; glm::vec3* _mohawkColors; + static ProgramObject* _irisProgram; static GLuint _irisTextureID; // private methods