This commit is contained in:
Philip Rosedale 2013-06-13 16:09:28 -07:00
commit e6e147d86a
5 changed files with 92 additions and 30 deletions

View file

@ -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);
}

View file

@ -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();
}

View file

@ -271,6 +271,7 @@ Avatar::~Avatar() {
}
void Avatar::init() {
_head.init();
_voxels.init();
_initialized = true;
}

View file

@ -5,13 +5,16 @@
// Copyright (c) 2013 High Fidelity, Inc. All rights reserved.
#include <glm/gtx/quaternion.hpp>
#include <QImage>
#include <AgentList.h>
#include "Application.h"
#include "Avatar.h"
#include "Head.h"
#include "Util.h"
#include <vector>
#include <lodepng.h>
#include <AgentList.h>
#include "renderer/ProgramObject.h"
using namespace std;
@ -36,9 +39,8 @@ const float IRIS_RADIUS = 0.007;
const float IRIS_PROTRUSION = 0.0145f;
const char IRIS_TEXTURE_FILENAME[] = "resources/images/iris.png";
unsigned int IRIS_TEXTURE_WIDTH = 768;
unsigned int IRIS_TEXTURE_HEIGHT = 498;
vector<unsigned char> irisTexture;
ProgramObject* Head::_irisProgram = 0;
GLuint Head::_irisTextureID;
Head::Head(Avatar* owningAvatar) :
HeadData((AvatarData*)owningAvatar),
@ -75,6 +77,26 @@ Head::Head(Avatar* owningAvatar) :
}
}
void Head::init() {
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);
glBindTexture(GL_TEXTURE_2D, _irisTextureID);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, image.width(), image.height(), 0, GL_RGB, GL_UNSIGNED_BYTE, image.constBits());
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glBindTexture(GL_TEXTURE_2D, 0);
}
}
void Head::reset() {
_yaw = _pitch = _roll = 0.0f;
_leanForward = _leanSideways = 0.0f;
@ -440,22 +462,11 @@ void Head::renderEyeBrows() {
void Head::renderEyeBalls() {
if (::irisTexture.size() == 0) {
switchToResourcesParentIfRequired();
unsigned error = lodepng::decode(::irisTexture, IRIS_TEXTURE_WIDTH, IRIS_TEXTURE_HEIGHT, IRIS_TEXTURE_FILENAME);
if (error != 0) {
printLog("error %u: %s\n", error, lodepng_error_text(error));
}
}
// 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);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
gluQuadricOrientation(irisQuadric, GLU_OUTSIDE);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, IRIS_TEXTURE_WIDTH, IRIS_TEXTURE_HEIGHT,
0, GL_RGBA, GL_UNSIGNED_BYTE, &::irisTexture[0]);
// render white ball of left eyeball
glPushMatrix();
@ -464,6 +475,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
@ -495,20 +517,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
@ -540,12 +553,14 @@ 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();

View file

@ -26,11 +26,13 @@ enum eyeContactTargets
const int NUM_HAIR_TUFTS = 4;
class Avatar;
class ProgramObject;
class Head : public HeadData {
public:
Head(Avatar* owningAvatar);
void init();
void reset();
void simulate(float deltaTime, bool isMine);
void render(bool lookingInMirror, float alpha);
@ -105,6 +107,9 @@ private:
glm::vec3 _saccade;
glm::vec3 _saccadeTarget;
static ProgramObject* _irisProgram;
static GLuint _irisTextureID;
// private methods
void createMohawk();
void renderHeadSphere();