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(); 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) { bool BlendFace::render(float alpha) {
if (_meshIDs.isEmpty()) { if (_meshIDs.isEmpty()) {
return false; return false;
@ -67,11 +75,14 @@ bool BlendFace::render(float alpha) {
glm::quat rotation = glm::inverse(orientation) * _owningHead->getEyeRotation(orientation * glm::quat rotation = glm::inverse(orientation) * _owningHead->getEyeRotation(orientation *
(mesh.pivot * scale + MODEL_TRANSLATION) + _owningHead->getPosition()); (mesh.pivot * scale + MODEL_TRANSLATION) + _owningHead->getPosition());
glm::vec3 rotationAxis = glm::axis(rotation); 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); glTranslatef(-mesh.pivot.x, -mesh.pivot.y, -mesh.pivot.z);
// use texture coordinates only for the eye, for now // use texture coordinates only for the eye, for now
glEnableClientState(GL_TEXTURE_COORD_ARRAY); glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glBindTexture(GL_TEXTURE_2D, _eyeTextureID);
glEnable(GL_TEXTURE_2D);
} }
// all meshes after the first are white // all meshes after the first are white
@ -117,6 +128,8 @@ bool BlendFace::render(float alpha) {
if (mesh.isEye) { if (mesh.isEye) {
glDisableClientState(GL_TEXTURE_COORD_ARRAY); glDisableClientState(GL_TEXTURE_COORD_ARRAY);
glBindTexture(GL_TEXTURE_2D, 0);
glDisable(GL_TEXTURE_2D);
glPopMatrix(); glPopMatrix();
} }
} }

View file

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

View file

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

View file

@ -295,8 +295,10 @@ FBXGeometry extractFBXGeometry(const FBXNode& node) {
if (object.properties.at(2) == "Mesh") { if (object.properties.at(2) == "Mesh") {
FBXMesh mesh; FBXMesh mesh;
QVector<glm::vec3> normals;
QVector<int> polygonIndices; QVector<int> polygonIndices;
QVector<glm::vec3> normals;
QVector<glm::vec2> texCoords;
QVector<int> texCoordIndices;
foreach (const FBXNode& data, object.children) { foreach (const FBXNode& data, object.children) {
if (data.name == "Vertices") { if (data.name == "Vertices") {
mesh.vertices = createVec3Vector(data.properties.at(0).value<QVector<double> >()); 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) { } else if (data.name == "LayerElementUV" && data.properties.at(0).toInt() == 0) {
QVector<glm::vec2> texCoords;
QVector<int> indices;
foreach (const FBXNode& subdata, data.children) { foreach (const FBXNode& subdata, data.children) {
if (subdata.name == "UV") { if (subdata.name == "UV") {
texCoords = createVec2Vector(subdata.properties.at(0).value<QVector<double> >()); texCoords = createVec2Vector(subdata.properties.at(0).value<QVector<double> >());
} else if (subdata.name == "UVIndex") { } 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.normals.resize(mesh.vertices.size());
mesh.texCoords.resize(mesh.vertices.size());
for (int i = 0, n = polygonIndices.size(); i < n; i++) { for (int i = 0, n = polygonIndices.size(); i < n; i++) {
int index = polygonIndices.at(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 // convert the polygons to quads and triangles

View file

@ -24,6 +24,9 @@ TextureCache::~TextureCache() {
if (_permutationNormalTextureID != 0) { if (_permutationNormalTextureID != 0) {
glDeleteTextures(1, &_permutationNormalTextureID); glDeleteTextures(1, &_permutationNormalTextureID);
} }
foreach (GLuint id, _fileTextureIDs) {
glDeleteTextures(1, &id);
}
if (_primaryFramebufferObject != NULL) { if (_primaryFramebufferObject != NULL) {
delete _primaryFramebufferObject; delete _primaryFramebufferObject;
glDeleteTextures(1, &_primaryDepthTextureID); glDeleteTextures(1, &_primaryDepthTextureID);
@ -62,6 +65,24 @@ GLuint TextureCache::getPermutationNormalTextureID() {
return _permutationNormalTextureID; 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() { QOpenGLFramebufferObject* TextureCache::getPrimaryFramebufferObject() {
if (_primaryFramebufferObject == NULL) { if (_primaryFramebufferObject == NULL) {
_primaryFramebufferObject = createFramebufferObject(); _primaryFramebufferObject = createFramebufferObject();

View file

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