diff --git a/interface/interface_en.ts b/interface/interface_en.ts
index 34e3614716..74ac030afc 100644
--- a/interface/interface_en.ts
+++ b/interface/interface_en.ts
@@ -14,12 +14,12 @@
-
+
Open Script
-
+
JavaScript Files (*.js)
@@ -113,18 +113,18 @@
Menu
-
+
Open .ini config file
-
-
+
+
Text files (*.ini)
-
+
Save .ini config file
diff --git a/interface/resources/shaders/model_shadow.frag b/interface/resources/shaders/model_shadow.frag
new file mode 100644
index 0000000000..bcb597b13c
--- /dev/null
+++ b/interface/resources/shaders/model_shadow.frag
@@ -0,0 +1,14 @@
+#version 120
+
+//
+// model_shadow.frag
+// fragment shader
+//
+// Created by Andrzej Kapolka on 3/24/14.
+// Copyright (c) 2014 High Fidelity, Inc. All rights reserved.
+//
+
+void main(void) {
+ // fixed color for now (we may eventually want to use texture alpha)
+ gl_FragColor = vec4(1.0, 1.0, 1.0, 1.0);
+}
diff --git a/interface/resources/shaders/model_shadow.vert b/interface/resources/shaders/model_shadow.vert
new file mode 100644
index 0000000000..ae7e871887
--- /dev/null
+++ b/interface/resources/shaders/model_shadow.vert
@@ -0,0 +1,14 @@
+#version 120
+
+//
+// model_shadow.vert
+// vertex shader
+//
+// Created by Andrzej Kapolka on 3/24/14.
+// Copyright (c) 2014 High Fidelity, Inc. All rights reserved.
+//
+
+void main(void) {
+ // just use standard pipeline transform
+ gl_Position = ftransform();
+}
diff --git a/interface/resources/shaders/skin_model_shadow.vert b/interface/resources/shaders/skin_model_shadow.vert
new file mode 100644
index 0000000000..b9ef05ad8a
--- /dev/null
+++ b/interface/resources/shaders/skin_model_shadow.vert
@@ -0,0 +1,27 @@
+#version 120
+
+//
+// skin_model_shadow.vert
+// vertex shader
+//
+// Created by Andrzej Kapolka on 3/24/14.
+// Copyright (c) 2014 High Fidelity, Inc. All rights reserved.
+//
+
+const int MAX_CLUSTERS = 128;
+const int INDICES_PER_VERTEX = 4;
+
+uniform mat4 clusterMatrices[MAX_CLUSTERS];
+
+attribute vec4 clusterIndices;
+attribute vec4 clusterWeights;
+
+void main(void) {
+ vec4 position = vec4(0.0, 0.0, 0.0, 0.0);
+ for (int i = 0; i < INDICES_PER_VERTEX; i++) {
+ mat4 clusterMatrix = clusterMatrices[int(clusterIndices[i])];
+ float clusterWeight = clusterWeights[i];
+ position += clusterMatrix * gl_Vertex * clusterWeight;
+ }
+ gl_Position = gl_ModelViewProjectionMatrix * position;
+}
diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp
index 9563cbf3b4..994423b9c4 100644
--- a/interface/src/Application.cpp
+++ b/interface/src/Application.cpp
@@ -2210,7 +2210,7 @@ void Application::updateShadowMap() {
glTranslatef(translation.x, translation.y, translation.z);
- _avatarManager.renderAvatars(true);
+ _avatarManager.renderAvatars(Avatar::SHADOW_RENDER_MODE);
_particles.render();
glPopMatrix();
@@ -2388,7 +2388,7 @@ void Application::displaySide(Camera& whichCamera, bool selfAvatarOnly) {
}
bool mirrorMode = (whichCamera.getInterpolatedMode() == CAMERA_MODE_MIRROR);
- _avatarManager.renderAvatars(mirrorMode, selfAvatarOnly);
+ _avatarManager.renderAvatars(mirrorMode ? Avatar::MIRROR_RENDER_MODE : Avatar::NORMAL_RENDER_MODE, selfAvatarOnly);
if (!selfAvatarOnly) {
// Render the world box
diff --git a/interface/src/avatar/Avatar.cpp b/interface/src/avatar/Avatar.cpp
index 75a8386ea9..2b94947928 100644
--- a/interface/src/avatar/Avatar.cpp
+++ b/interface/src/avatar/Avatar.cpp
@@ -189,10 +189,11 @@ static TextRenderer* textRenderer(TextRendererType type) {
return displayNameRenderer;
}
-void Avatar::render(const glm::vec3& cameraPosition, bool forShadowMap) {
+void Avatar::render(const glm::vec3& cameraPosition, RenderMode renderMode) {
// simple frustum check
float boundingRadius = getBillboardSize();
- if (Application::getInstance()->getViewFrustum()->sphereInFrustum(cameraPosition, boundingRadius) == ViewFrustum::OUTSIDE) {
+ if (Application::getInstance()->getViewFrustum()->sphereInFrustum(
+ cameraPosition, boundingRadius) == ViewFrustum::OUTSIDE) {
return;
}
@@ -202,11 +203,11 @@ void Avatar::render(const glm::vec3& cameraPosition, bool forShadowMap) {
{
// glow when moving far away
const float GLOW_DISTANCE = 20.0f;
- Glower glower(_moving && distanceToTarget > GLOW_DISTANCE && !forShadowMap ? 1.0f : 0.0f);
+ Glower glower(_moving && distanceToTarget > GLOW_DISTANCE && renderMode == NORMAL_RENDER_MODE ? 1.0f : 0.0f);
// render body
if (Menu::getInstance()->isOptionChecked(MenuOption::Avatars)) {
- renderBody(forShadowMap);
+ renderBody(renderMode);
}
if (Menu::getInstance()->isOptionChecked(MenuOption::RenderSkeletonCollisionProxies)) {
_skeletonModel.renderCollisionProxies(0.7f);
@@ -230,7 +231,8 @@ void Avatar::render(const glm::vec3& cameraPosition, bool forShadowMap) {
float angle = abs(angleBetween(toTarget + delta, toTarget - delta));
float sphereRadius = getHead()->getAverageLoudness() * SPHERE_LOUDNESS_SCALING;
- if (!forShadowMap && (sphereRadius > MIN_SPHERE_SIZE) && (angle < MAX_SPHERE_ANGLE) && (angle > MIN_SPHERE_ANGLE)) {
+ if (renderMode == NORMAL_RENDER_MODE && (sphereRadius > MIN_SPHERE_SIZE) &&
+ (angle < MAX_SPHERE_ANGLE) && (angle > MIN_SPHERE_ANGLE)) {
glColor4f(SPHERE_COLOR[0], SPHERE_COLOR[1], SPHERE_COLOR[2], 1.f - angle / MAX_SPHERE_ANGLE);
glPushMatrix();
glTranslatef(_position.x, _position.y, _position.z);
@@ -242,8 +244,8 @@ void Avatar::render(const glm::vec3& cameraPosition, bool forShadowMap) {
}
const float DISPLAYNAME_DISTANCE = 10.0f;
- setShowDisplayName(!forShadowMap && distanceToTarget < DISPLAYNAME_DISTANCE);
- if (forShadowMap) {
+ setShowDisplayName(renderMode == NORMAL_RENDER_MODE && distanceToTarget < DISPLAYNAME_DISTANCE);
+ if (renderMode != NORMAL_RENDER_MODE) {
return;
}
renderDisplayName();
@@ -306,17 +308,16 @@ glm::quat Avatar::computeRotationFromBodyToWorldUp(float proportion) const {
return glm::angleAxis(angle * proportion, axis);
}
-void Avatar::renderBody(bool forShadowMap) {
+void Avatar::renderBody(RenderMode renderMode) {
if (_shouldRenderBillboard || !(_skeletonModel.isRenderable() && getHead()->getFaceModel().isRenderable())) {
// render the billboard until both models are loaded
- if (forShadowMap) {
- return;
+ if (renderMode != SHADOW_RENDER_MODE) {
+ renderBillboard();
}
- renderBillboard();
return;
}
- _skeletonModel.render(1.0f);
- getHead()->render(1.0f);
+ _skeletonModel.render(1.0f, renderMode == SHADOW_RENDER_MODE);
+ getHead()->render(1.0f, renderMode == SHADOW_RENDER_MODE);
getHand()->render(false);
}
diff --git a/interface/src/avatar/Avatar.h b/interface/src/avatar/Avatar.h
index 638bff6e32..25600e0943 100755
--- a/interface/src/avatar/Avatar.h
+++ b/interface/src/avatar/Avatar.h
@@ -74,7 +74,10 @@ public:
void init();
void simulate(float deltaTime);
- virtual void render(const glm::vec3& cameraPosition, bool forShadowMap);
+
+ enum RenderMode { NORMAL_RENDER_MODE, SHADOW_RENDER_MODE, MIRROR_RENDER_MODE };
+
+ virtual void render(const glm::vec3& cameraPosition, RenderMode renderMode = NORMAL_RENDER_MODE);
//setters
void setDisplayingLookatVectors(bool displayingLookatVectors) { getHead()->setRenderLookatVectors(displayingLookatVectors); }
@@ -181,7 +184,7 @@ protected:
float getPelvisToHeadLength() const;
void renderDisplayName();
- virtual void renderBody(bool forShadowMap);
+ virtual void renderBody(RenderMode renderMode);
private:
diff --git a/interface/src/avatar/AvatarManager.cpp b/interface/src/avatar/AvatarManager.cpp
index 29b23e1f5b..9147a08dbd 100644
--- a/interface/src/avatar/AvatarManager.cpp
+++ b/interface/src/avatar/AvatarManager.cpp
@@ -72,7 +72,7 @@ void AvatarManager::updateOtherAvatars(float deltaTime) {
simulateAvatarFades(deltaTime);
}
-void AvatarManager::renderAvatars(bool forShadowMapOrMirror, bool selfAvatarOnly) {
+void AvatarManager::renderAvatars(Avatar::RenderMode renderMode, bool selfAvatarOnly) {
PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings),
"Application::renderAvatars()");
bool renderLookAtVectors = Menu::getInstance()->isOptionChecked(MenuOption::LookAtVectors);
@@ -85,13 +85,13 @@ void AvatarManager::renderAvatars(bool forShadowMapOrMirror, bool selfAvatarOnly
if (!avatar->isInitialized()) {
continue;
}
- avatar->render(cameraPosition, forShadowMapOrMirror);
+ avatar->render(cameraPosition, renderMode);
avatar->setDisplayingLookatVectors(renderLookAtVectors);
}
- renderAvatarFades(cameraPosition, forShadowMapOrMirror);
+ renderAvatarFades(cameraPosition, renderMode);
} else {
// just render myAvatar
- _myAvatar->render(cameraPosition, forShadowMapOrMirror);
+ _myAvatar->render(cameraPosition, renderMode);
_myAvatar->setDisplayingLookatVectors(renderLookAtVectors);
}
}
@@ -114,14 +114,14 @@ void AvatarManager::simulateAvatarFades(float deltaTime) {
}
}
-void AvatarManager::renderAvatarFades(const glm::vec3& cameraPosition, bool forShadowMap) {
+void AvatarManager::renderAvatarFades(const glm::vec3& cameraPosition, Avatar::RenderMode renderMode) {
// render avatar fades
- Glower glower(forShadowMap ? 0.0f : 1.0f);
+ Glower glower(renderMode == Avatar::NORMAL_RENDER_MODE ? 1.0f : 0.0f);
foreach(const AvatarSharedPointer& fadingAvatar, _avatarFades) {
Avatar* avatar = static_cast(fadingAvatar.data());
if (avatar != static_cast(_myAvatar.data())) {
- avatar->render(cameraPosition, forShadowMap);
+ avatar->render(cameraPosition, renderMode);
}
}
}
diff --git a/interface/src/avatar/AvatarManager.h b/interface/src/avatar/AvatarManager.h
index 455153b92a..06494f309c 100644
--- a/interface/src/avatar/AvatarManager.h
+++ b/interface/src/avatar/AvatarManager.h
@@ -29,7 +29,7 @@ public:
MyAvatar* getMyAvatar() { return _myAvatar.data(); }
void updateOtherAvatars(float deltaTime);
- void renderAvatars(bool forShadowMapOrMirror = false, bool selfAvatarOnly = false);
+ void renderAvatars(Avatar::RenderMode renderMode, bool selfAvatarOnly = false);
void clearOtherAvatars();
@@ -45,7 +45,7 @@ private:
void processKillAvatar(const QByteArray& datagram);
void simulateAvatarFades(float deltaTime);
- void renderAvatarFades(const glm::vec3& cameraPosition, bool forShadowMap);
+ void renderAvatarFades(const glm::vec3& cameraPosition, Avatar::RenderMode renderMode);
// virtual override
AvatarHash::iterator erase(const AvatarHash::iterator& iterator);
diff --git a/interface/src/avatar/FaceModel.cpp b/interface/src/avatar/FaceModel.cpp
index db6c3fe98d..19faa0da42 100644
--- a/interface/src/avatar/FaceModel.cpp
+++ b/interface/src/avatar/FaceModel.cpp
@@ -45,13 +45,6 @@ void FaceModel::simulate(float deltaTime) {
Model::simulate(deltaTime, true, newJointStates);
}
-bool FaceModel::render(float alpha) {
- if (!Model::render(alpha)) {
- return false;
- }
- return true;
-}
-
void FaceModel::maybeUpdateNeckRotation(const JointState& parentState, const FBXJoint& joint, JointState& state) {
// get the rotation axes in joint space and use them to adjust the rotation
glm::mat3 axes = glm::mat3_cast(_rotation);
diff --git a/interface/src/avatar/FaceModel.h b/interface/src/avatar/FaceModel.h
index d0f0f6baef..acf2d2baf4 100644
--- a/interface/src/avatar/FaceModel.h
+++ b/interface/src/avatar/FaceModel.h
@@ -22,7 +22,6 @@ public:
FaceModel(Head* owningHead);
void simulate(float deltaTime);
- bool render(float alpha);
protected:
diff --git a/interface/src/avatar/Head.cpp b/interface/src/avatar/Head.cpp
index 44001a2015..4a81df8b74 100644
--- a/interface/src/avatar/Head.cpp
+++ b/interface/src/avatar/Head.cpp
@@ -168,8 +168,8 @@ void Head::simulate(float deltaTime, bool isMine, bool billboard) {
_eyePosition = calculateAverageEyePosition();
}
-void Head::render(float alpha) {
- if (_faceModel.render(alpha) && _renderLookatVectors) {
+void Head::render(float alpha, bool forShadowMap) {
+ if (_faceModel.render(alpha, forShadowMap) && _renderLookatVectors) {
renderLookatVectors(_leftEyePosition, _rightEyePosition, _lookAtPosition);
}
}
diff --git a/interface/src/avatar/Head.h b/interface/src/avatar/Head.h
index a9ea9b4cc6..60730c8724 100644
--- a/interface/src/avatar/Head.h
+++ b/interface/src/avatar/Head.h
@@ -37,7 +37,7 @@ public:
void init();
void reset();
void simulate(float deltaTime, bool isMine, bool billboard = false);
- void render(float alpha);
+ void render(float alpha, bool forShadowMap);
void setScale(float scale);
void setPosition(glm::vec3 position) { _position = position; }
void setGravity(glm::vec3 gravity) { _gravity = gravity; }
diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp
index a6a7f22896..711e1d32c3 100644
--- a/interface/src/avatar/MyAvatar.cpp
+++ b/interface/src/avatar/MyAvatar.cpp
@@ -451,12 +451,12 @@ void MyAvatar::renderDebugBodyPoints() {
}
// virtual
-void MyAvatar::render(const glm::vec3& cameraPosition, bool forShadowMapOrMirror) {
+void MyAvatar::render(const glm::vec3& cameraPosition, RenderMode renderMode) {
// don't render if we've been asked to disable local rendering
if (!_shouldRender) {
return; // exit early
}
- Avatar::render(cameraPosition, forShadowMapOrMirror);
+ Avatar::render(cameraPosition, renderMode);
}
void MyAvatar::renderHeadMouse() const {
@@ -639,20 +639,20 @@ void MyAvatar::setSkeletonModelURL(const QUrl& skeletonModelURL) {
_billboardValid = false;
}
-void MyAvatar::renderBody(bool forceRenderHead) {
+void MyAvatar::renderBody(RenderMode renderMode) {
if (!(_skeletonModel.isRenderable() && getHead()->getFaceModel().isRenderable())) {
return; // wait until both models are loaded
}
// Render the body's voxels and head
- _skeletonModel.render(1.0f);
+ _skeletonModel.render(1.0f, renderMode == SHADOW_RENDER_MODE);
// Render head so long as the camera isn't inside it
const float RENDER_HEAD_CUTOFF_DISTANCE = 0.40f;
Camera* myCamera = Application::getInstance()->getCamera();
- if (forceRenderHead || (glm::length(myCamera->getPosition() - getHead()->calculateAverageEyePosition()) >
+ if (renderMode != NORMAL_RENDER_MODE || (glm::length(myCamera->getPosition() - getHead()->calculateAverageEyePosition()) >
RENDER_HEAD_CUTOFF_DISTANCE * _scale)) {
- getHead()->render(1.0f);
+ getHead()->render(1.0f, renderMode == SHADOW_RENDER_MODE);
}
getHand()->render(true);
}
diff --git a/interface/src/avatar/MyAvatar.h b/interface/src/avatar/MyAvatar.h
index 241286a721..cbb625aa2f 100644
--- a/interface/src/avatar/MyAvatar.h
+++ b/interface/src/avatar/MyAvatar.h
@@ -35,8 +35,8 @@ public:
void simulate(float deltaTime);
void updateFromGyros(float deltaTime);
- void render(const glm::vec3& cameraPosition, bool forShadowMapOrMirror = false);
- void renderBody(bool forceRenderHead);
+ void render(const glm::vec3& cameraPosition, RenderMode renderMode = NORMAL_RENDER_MODE);
+ void renderBody(RenderMode renderMode);
void renderDebugBodyPoints();
void renderHeadMouse() const;
diff --git a/interface/src/avatar/SkeletonModel.cpp b/interface/src/avatar/SkeletonModel.cpp
index 7173cb0b84..9e4740df15 100644
--- a/interface/src/avatar/SkeletonModel.cpp
+++ b/interface/src/avatar/SkeletonModel.cpp
@@ -62,17 +62,6 @@ void SkeletonModel::simulate(float deltaTime, bool fullUpdate) {
}
}
-bool SkeletonModel::render(float alpha) {
-
- if (_jointStates.isEmpty()) {
- return false;
- }
-
- Model::render(alpha);
-
- return true;
-}
-
void SkeletonModel::getHandShapes(int jointIndex, QVector& shapes) const {
if (jointIndex == -1) {
return;
diff --git a/interface/src/avatar/SkeletonModel.h b/interface/src/avatar/SkeletonModel.h
index 0bcbcef2ea..514b5daf1c 100644
--- a/interface/src/avatar/SkeletonModel.h
+++ b/interface/src/avatar/SkeletonModel.h
@@ -23,7 +23,6 @@ public:
SkeletonModel(Avatar* owningAvatar);
void simulate(float deltaTime, bool fullUpdate = true);
- bool render(float alpha);
/// \param jointIndex index of hand joint
/// \param shapes[out] list in which is stored pointers to hand shapes
diff --git a/interface/src/renderer/Model.cpp b/interface/src/renderer/Model.cpp
index 16b5c167d9..690b19ee5e 100644
--- a/interface/src/renderer/Model.cpp
+++ b/interface/src/renderer/Model.cpp
@@ -43,11 +43,14 @@ Model::~Model() {
ProgramObject Model::_program;
ProgramObject Model::_normalMapProgram;
+ProgramObject Model::_shadowProgram;
ProgramObject Model::_skinProgram;
ProgramObject Model::_skinNormalMapProgram;
+ProgramObject Model::_skinShadowProgram;
int Model::_normalMapTangentLocation;
Model::SkinLocations Model::_skinLocations;
Model::SkinLocations Model::_skinNormalMapLocations;
+Model::SkinLocations Model::_skinShadowLocations;
void Model::initSkinProgram(ProgramObject& program, Model::SkinLocations& locations) {
program.bind();
@@ -93,6 +96,11 @@ void Model::init() {
_normalMapTangentLocation = _normalMapProgram.attributeLocation("tangent");
_normalMapProgram.release();
+ _shadowProgram.addShaderFromSourceFile(QGLShader::Vertex, Application::resourcesPath() + "shaders/model_shadow.vert");
+ _shadowProgram.addShaderFromSourceFile(QGLShader::Fragment, Application::resourcesPath() +
+ "shaders/model_shadow.frag");
+ _shadowProgram.link();
+
_skinProgram.addShaderFromSourceFile(QGLShader::Vertex, Application::resourcesPath()
+ "shaders/skin_model.vert");
_skinProgram.addShaderFromSourceFile(QGLShader::Fragment, Application::resourcesPath()
@@ -108,6 +116,14 @@ void Model::init() {
_skinNormalMapProgram.link();
initSkinProgram(_skinNormalMapProgram, _skinNormalMapLocations);
+
+ _skinShadowProgram.addShaderFromSourceFile(QGLShader::Vertex,
+ Application::resourcesPath() + "shaders/skin_model_shadow.vert");
+ _skinShadowProgram.addShaderFromSourceFile(QGLShader::Fragment,
+ Application::resourcesPath() + "shaders/model_shadow.frag");
+ _skinShadowProgram.link();
+
+ initSkinProgram(_skinShadowProgram, _skinShadowLocations);
}
}
@@ -167,7 +183,7 @@ void Model::simulate(float deltaTime, bool fullUpdate) {
simulate(deltaTime, fullUpdate, updateGeometry());
}
-bool Model::render(float alpha) {
+bool Model::render(float alpha, bool forShadowMap) {
// render the attachments
foreach (Model* attachment, _attachments) {
attachment->render(alpha);
@@ -198,13 +214,13 @@ bool Model::render(float alpha) {
glEnable(GL_ALPHA_TEST);
glAlphaFunc(GL_GREATER, 0.5f * alpha);
- renderMeshes(alpha, false);
+ renderMeshes(alpha, forShadowMap, false);
glDisable(GL_ALPHA_TEST);
// render translucent meshes afterwards, with back face culling
- renderMeshes(alpha, true);
+ renderMeshes(alpha, forShadowMap, true);
glDisable(GL_CULL_FACE);
@@ -960,7 +976,7 @@ void Model::deleteGeometry() {
}
}
-void Model::renderMeshes(float alpha, bool translucent) {
+void Model::renderMeshes(float alpha, bool forShadowMap, bool translucent) {
const FBXGeometry& geometry = _geometry->getFBXGeometry();
const QVector& networkMeshes = _geometry->getMeshes();
@@ -985,7 +1001,12 @@ void Model::renderMeshes(float alpha, bool translucent) {
ProgramObject* program = &_program;
ProgramObject* skinProgram = &_skinProgram;
SkinLocations* skinLocations = &_skinLocations;
- if (!mesh.tangents.isEmpty()) {
+ if (forShadowMap) {
+ program = &_shadowProgram;
+ skinProgram = &_skinShadowProgram;
+ skinLocations = &_skinShadowLocations;
+
+ } else if (!mesh.tangents.isEmpty()) {
program = &_normalMapProgram;
skinProgram = &_skinNormalMapProgram;
skinLocations = &_skinNormalMapLocations;
@@ -1018,7 +1039,7 @@ void Model::renderMeshes(float alpha, bool translucent) {
}
if (mesh.blendshapes.isEmpty()) {
- if (!mesh.tangents.isEmpty()) {
+ if (!(mesh.tangents.isEmpty() || forShadowMap)) {
activeProgram->setAttributeBuffer(tangentLocation, GL_FLOAT, vertexCount * 2 * sizeof(glm::vec3), 3);
activeProgram->enableAttributeArray(tangentLocation);
}
@@ -1028,7 +1049,7 @@ void Model::renderMeshes(float alpha, bool translucent) {
(mesh.tangents.size() + mesh.colors.size()) * sizeof(glm::vec3)));
} else {
- if (!mesh.tangents.isEmpty()) {
+ if (!(mesh.tangents.isEmpty() || forShadowMap)) {
activeProgram->setAttributeBuffer(tangentLocation, GL_FLOAT, 0, 3);
activeProgram->enableAttributeArray(tangentLocation);
}
@@ -1057,31 +1078,33 @@ void Model::renderMeshes(float alpha, bool translucent) {
continue;
}
// apply material properties
- glm::vec4 diffuse = glm::vec4(part.diffuseColor, alpha);
- glm::vec4 specular = glm::vec4(part.specularColor, alpha);
- glMaterialfv(GL_FRONT, GL_AMBIENT, (const float*)&diffuse);
- glMaterialfv(GL_FRONT, GL_DIFFUSE, (const float*)&diffuse);
- glMaterialfv(GL_FRONT, GL_SPECULAR, (const float*)&specular);
- glMaterialf(GL_FRONT, GL_SHININESS, part.shininess);
-
- Texture* diffuseMap = networkPart.diffuseTexture.data();
- if (mesh.isEye) {
- if (diffuseMap) {
+ if (forShadowMap) {
+ glBindTexture(GL_TEXTURE_2D, 0);
+
+ } else {
+ glm::vec4 diffuse = glm::vec4(part.diffuseColor, alpha);
+ glm::vec4 specular = glm::vec4(part.specularColor, alpha);
+ glMaterialfv(GL_FRONT, GL_AMBIENT, (const float*)&diffuse);
+ glMaterialfv(GL_FRONT, GL_DIFFUSE, (const float*)&diffuse);
+ glMaterialfv(GL_FRONT, GL_SPECULAR, (const float*)&specular);
+ glMaterialf(GL_FRONT, GL_SHININESS, part.shininess);
+
+ Texture* diffuseMap = networkPart.diffuseTexture.data();
+ if (mesh.isEye && diffuseMap) {
diffuseMap = (_dilatedTextures[i][j] =
static_cast(diffuseMap)->getDilatedTexture(_pupilDilation)).data();
}
+ glBindTexture(GL_TEXTURE_2D, !diffuseMap ?
+ Application::getInstance()->getTextureCache()->getWhiteTextureID() : diffuseMap->getID());
+
+ if (!mesh.tangents.isEmpty()) {
+ glActiveTexture(GL_TEXTURE1);
+ Texture* normalMap = networkPart.normalTexture.data();
+ glBindTexture(GL_TEXTURE_2D, !normalMap ?
+ Application::getInstance()->getTextureCache()->getBlueTextureID() : normalMap->getID());
+ glActiveTexture(GL_TEXTURE0);
+ }
}
- glBindTexture(GL_TEXTURE_2D, !diffuseMap ?
- Application::getInstance()->getTextureCache()->getWhiteTextureID() : diffuseMap->getID());
-
- if (!mesh.tangents.isEmpty()) {
- glActiveTexture(GL_TEXTURE1);
- Texture* normalMap = networkPart.normalTexture.data();
- glBindTexture(GL_TEXTURE_2D, !normalMap ?
- Application::getInstance()->getTextureCache()->getBlueTextureID() : normalMap->getID());
- glActiveTexture(GL_TEXTURE0);
- }
-
glDrawRangeElementsEXT(GL_QUADS, 0, vertexCount - 1, part.quadIndices.size(), GL_UNSIGNED_INT, (void*)offset);
offset += part.quadIndices.size() * sizeof(int);
glDrawRangeElementsEXT(GL_TRIANGLES, 0, vertexCount - 1, part.triangleIndices.size(),
@@ -1096,7 +1119,7 @@ void Model::renderMeshes(float alpha, bool translucent) {
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
}
- if (!mesh.tangents.isEmpty()) {
+ if (!(mesh.tangents.isEmpty() || forShadowMap)) {
glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, 0);
glActiveTexture(GL_TEXTURE0);
diff --git a/interface/src/renderer/Model.h b/interface/src/renderer/Model.h
index f08a6b9fc2..b4f71f14d3 100644
--- a/interface/src/renderer/Model.h
+++ b/interface/src/renderer/Model.h
@@ -58,7 +58,7 @@ public:
void createCollisionShapes();
void updateShapePositions();
void simulate(float deltaTime, bool fullUpdate = true);
- bool render(float alpha);
+ bool render(float alpha = 1.0f, bool forShadowMap = false);
/// Sets the URL of the model to render.
/// \param fallback the URL of a fallback model to render if the requested model fails to load
@@ -261,7 +261,7 @@ private:
void applyNextGeometry();
void deleteGeometry();
- void renderMeshes(float alpha, bool translucent);
+ void renderMeshes(float alpha, bool forShadowMap, bool translucent);
QSharedPointer _baseGeometry; ///< reference required to prevent collection of base
QSharedPointer _nextBaseGeometry;
@@ -283,8 +283,10 @@ private:
static ProgramObject _program;
static ProgramObject _normalMapProgram;
+ static ProgramObject _shadowProgram;
static ProgramObject _skinProgram;
static ProgramObject _skinNormalMapProgram;
+ static ProgramObject _skinShadowProgram;
static int _normalMapTangentLocation;
@@ -298,6 +300,7 @@ private:
static SkinLocations _skinLocations;
static SkinLocations _skinNormalMapLocations;
+ static SkinLocations _skinShadowLocations;
static void initSkinProgram(ProgramObject& program, SkinLocations& locations);
static QVector createJointStates(const FBXGeometry& geometry);