Render the eye textures.

This commit is contained in:
Andrzej Kapolka 2013-09-25 13:47:03 -07:00
parent 4567b8afdf
commit 9a16d44a47
7 changed files with 60 additions and 18 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 862 KiB

View file

@ -27,6 +27,14 @@ BlendFace::~BlendFace() {
deleteGeometry();
}
GLuint BlendFace::_eyeTextureID = 0;
void BlendFace::init() {
if (_eyeTextureID == 0) {
_eyeTextureID = Application::getInstance()->getTextureCache()->getFileTextureID("resources/images/eye.png");
}
}
bool BlendFace::render(float alpha) {
if (_meshIDs.isEmpty()) {
return false;
@ -67,11 +75,14 @@ bool BlendFace::render(float alpha) {
glm::quat rotation = glm::inverse(orientation) * _owningHead->getEyeRotation(orientation *
(mesh.pivot * scale + MODEL_TRANSLATION) + _owningHead->getPosition());
glm::vec3 rotationAxis = glm::axis(rotation);
glRotatef(glm::angle(rotation), rotationAxis.x, rotationAxis.y, rotationAxis.z);
glRotatef(glm::angle(-rotation), rotationAxis.x, rotationAxis.y, rotationAxis.z);
glTranslatef(-mesh.pivot.x, -mesh.pivot.y, -mesh.pivot.z);
// use texture coordinates only for the eye, for now
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glBindTexture(GL_TEXTURE_2D, _eyeTextureID);
glEnable(GL_TEXTURE_2D);
}
// all meshes after the first are white
@ -117,6 +128,8 @@ bool BlendFace::render(float alpha) {
if (mesh.isEye) {
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
glBindTexture(GL_TEXTURE_2D, 0);
glDisable(GL_TEXTURE_2D);
glPopMatrix();
}
}

View file

@ -30,6 +30,7 @@ public:
bool isActive() const { return !_meshIDs.isEmpty(); }
void init();
bool render(float alpha);
Q_INVOKABLE void setModelURL(const QUrl& url);
@ -57,6 +58,8 @@ private:
FBXGeometry _geometry;
QVector<glm::vec3> _blendedVertices;
QVector<glm::vec3> _blendedNormals;
static GLuint _eyeTextureID;
};
#endif /* defined(__interface__BlendFace__) */

View file

@ -6,8 +6,6 @@
#include <glm/gtx/quaternion.hpp>
#include <QImage>
#include <NodeList.h>
#include "Application.h"
@ -105,16 +103,14 @@ void Head::init() {
_irisProgram.setUniformValue("texture", 0);
_eyePositionLocation = _irisProgram.uniformLocation("eyePosition");
QImage image = QImage(IRIS_TEXTURE_FILENAME).convertToFormat(QImage::Format_ARGB32);
glGenTextures(1, &_irisTextureID);
_irisTextureID = Application::getInstance()->getTextureCache()->getFileTextureID(IRIS_TEXTURE_FILENAME);
glBindTexture(GL_TEXTURE_2D, _irisTextureID);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, image.width(), image.height(), 1, GL_BGRA, GL_UNSIGNED_BYTE, image.constBits());
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);
}
_blendFace.init();
}
void Head::reset() {

View file

@ -295,8 +295,10 @@ FBXGeometry extractFBXGeometry(const FBXNode& node) {
if (object.properties.at(2) == "Mesh") {
FBXMesh mesh;
QVector<glm::vec3> normals;
QVector<int> polygonIndices;
QVector<glm::vec3> normals;
QVector<glm::vec2> texCoords;
QVector<int> texCoordIndices;
foreach (const FBXNode& data, object.children) {
if (data.name == "Vertices") {
mesh.vertices = createVec3Vector(data.properties.at(0).value<QVector<double> >());
@ -311,27 +313,28 @@ FBXGeometry extractFBXGeometry(const FBXNode& node) {
}
}
} else if (data.name == "LayerElementUV" && data.properties.at(0).toInt() == 0) {
QVector<glm::vec2> texCoords;
QVector<int> indices;
foreach (const FBXNode& subdata, data.children) {
if (subdata.name == "UV") {
texCoords = createVec2Vector(subdata.properties.at(0).value<QVector<double> >());
} else if (subdata.name == "UVIndex") {
indices = data.properties.at(0).value<QVector<int> >();
texCoordIndices = subdata.properties.at(0).value<QVector<int> >();
}
}
foreach (int index, indices) {
mesh.texCoords.append(texCoords.at(index));
}
}
}
// the (base) normals correspond to the polygon indices, for some reason
// the (base) normals and tex coords correspond to the polygon indices, for some reason
mesh.normals.resize(mesh.vertices.size());
mesh.texCoords.resize(mesh.vertices.size());
for (int i = 0, n = polygonIndices.size(); i < n; i++) {
int index = polygonIndices.at(i);
mesh.normals[index < 0 ? (-index - 1) : index] = normals[i];
index = (index < 0) ? (-index - 1) : index;
mesh.normals[index] = normals.at(i);
int texCoordIndex = texCoordIndices.at(i);
if (texCoordIndex >= 0) {
mesh.texCoords[index] = texCoords.at(texCoordIndex);
}
}
// convert the polygons to quads and triangles

View file

@ -24,6 +24,9 @@ TextureCache::~TextureCache() {
if (_permutationNormalTextureID != 0) {
glDeleteTextures(1, &_permutationNormalTextureID);
}
foreach (GLuint id, _fileTextureIDs) {
glDeleteTextures(1, &id);
}
if (_primaryFramebufferObject != NULL) {
delete _primaryFramebufferObject;
glDeleteTextures(1, &_primaryDepthTextureID);
@ -62,6 +65,24 @@ GLuint TextureCache::getPermutationNormalTextureID() {
return _permutationNormalTextureID;
}
GLuint TextureCache::getFileTextureID(const QString& filename) {
GLuint id = _fileTextureIDs.value(filename);
if (id == 0) {
switchToResourcesParentIfRequired();
QImage image = QImage(filename).convertToFormat(QImage::Format_ARGB32);
glGenTextures(1, &id);
glBindTexture(GL_TEXTURE_2D, id);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, image.width(), image.height(), 1,
GL_BGRA, GL_UNSIGNED_BYTE, image.constBits());
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glBindTexture(GL_TEXTURE_2D, 0);
_fileTextureIDs.insert(filename, id);
}
return id;
}
QOpenGLFramebufferObject* TextureCache::getPrimaryFramebufferObject() {
if (_primaryFramebufferObject == NULL) {
_primaryFramebufferObject = createFramebufferObject();

View file

@ -9,6 +9,7 @@
#ifndef __interface__TextureCache__
#define __interface__TextureCache__
#include <QHash>
#include <QObject>
#include "InterfaceConfig.h"
@ -27,6 +28,9 @@ public:
/// the second, a set of random unit vectors to be used as noise gradients.
GLuint getPermutationNormalTextureID();
/// Returns the ID of a texture containing the contents of the specified file, loading it if necessary.
GLuint getFileTextureID(const QString& filename);
/// Returns a pointer to the primary framebuffer object. This render target includes a depth component, and is
/// used for scene rendering.
QOpenGLFramebufferObject* getPrimaryFramebufferObject();
@ -50,6 +54,8 @@ private:
GLuint _permutationNormalTextureID;
QHash<QString, GLuint> _fileTextureIDs;
GLuint _primaryDepthTextureID;
QOpenGLFramebufferObject* _primaryFramebufferObject;
QOpenGLFramebufferObject* _secondaryFramebufferObject;