Merge pull request #2216 from ey6es/master

Generate mipmaps for avatar textures, fix shadows (don't render display names into the shadow map).
This commit is contained in:
Philip Rosedale 2014-03-05 18:18:23 -08:00
commit a39b0313c9
11 changed files with 43 additions and 28 deletions

View file

@ -2383,8 +2383,8 @@ void Application::displaySide(Camera& whichCamera, bool selfAvatarOnly) {
glMaterialfv(GL_FRONT, GL_SPECULAR, WHITE_SPECULAR_COLOR); glMaterialfv(GL_FRONT, GL_SPECULAR, WHITE_SPECULAR_COLOR);
} }
bool forceRenderMyHead = (whichCamera.getInterpolatedMode() == CAMERA_MODE_MIRROR); bool mirrorMode = (whichCamera.getInterpolatedMode() == CAMERA_MODE_MIRROR);
_avatarManager.renderAvatars(forceRenderMyHead, selfAvatarOnly); _avatarManager.renderAvatars(mirrorMode, selfAvatarOnly);
if (!selfAvatarOnly) { if (!selfAvatarOnly) {
// Render the world box // Render the world box

View file

@ -201,7 +201,7 @@ static TextRenderer* textRenderer(TextRendererType type) {
return displayNameRenderer; return displayNameRenderer;
} }
void Avatar::render() { void Avatar::render(bool forShadowMap) {
glm::vec3 toTarget = _position - Application::getInstance()->getAvatar()->getPosition(); glm::vec3 toTarget = _position - Application::getInstance()->getAvatar()->getPosition();
float lengthToTarget = glm::length(toTarget); float lengthToTarget = glm::length(toTarget);
@ -209,7 +209,7 @@ void Avatar::render() {
// glow when moving in the distance // glow when moving in the distance
const float GLOW_DISTANCE = 5.0f; const float GLOW_DISTANCE = 5.0f;
Glower glower(_moving && lengthToTarget > GLOW_DISTANCE ? 1.0f : 0.0f); Glower glower(_moving && lengthToTarget > GLOW_DISTANCE && !forShadowMap ? 1.0f : 0.0f);
// render body // render body
if (Menu::getInstance()->isOptionChecked(MenuOption::RenderSkeletonCollisionProxies)) { if (Menu::getInstance()->isOptionChecked(MenuOption::RenderSkeletonCollisionProxies)) {
@ -233,7 +233,7 @@ void Avatar::render() {
float angle = abs(angleBetween(toTarget + delta, toTarget - delta)); float angle = abs(angleBetween(toTarget + delta, toTarget - delta));
float sphereRadius = getHead()->getAverageLoudness() * SPHERE_LOUDNESS_SCALING; float sphereRadius = getHead()->getAverageLoudness() * SPHERE_LOUDNESS_SCALING;
if ((sphereRadius > MIN_SPHERE_SIZE) && (angle < MAX_SPHERE_ANGLE) && (angle > MIN_SPHERE_ANGLE)) { if (!forShadowMap && (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); glColor4f(SPHERE_COLOR[0], SPHERE_COLOR[1], SPHERE_COLOR[2], 1.f - angle / MAX_SPHERE_ANGLE);
glPushMatrix(); glPushMatrix();
glTranslatef(_position.x, _position.y, _position.z); glTranslatef(_position.x, _position.y, _position.z);
@ -243,7 +243,10 @@ void Avatar::render() {
} }
} }
const float DISPLAYNAME_DISTANCE = 10.0f; const float DISPLAYNAME_DISTANCE = 10.0f;
setShowDisplayName(lengthToTarget < DISPLAYNAME_DISTANCE); setShowDisplayName(!forShadowMap && lengthToTarget < DISPLAYNAME_DISTANCE);
if (forShadowMap) {
return;
}
renderDisplayName(); renderDisplayName();
if (!_chatMessage.empty()) { if (!_chatMessage.empty()) {

View file

@ -74,7 +74,7 @@ public:
void init(); void init();
void simulate(float deltaTime); void simulate(float deltaTime);
void render(); void render(bool forShadowMap = false);
//setters //setters
void setDisplayingLookatVectors(bool displayingLookatVectors) { getHead()->setRenderLookatVectors(displayingLookatVectors); } void setDisplayingLookatVectors(bool displayingLookatVectors) { getHead()->setRenderLookatVectors(displayingLookatVectors); }

View file

@ -69,7 +69,7 @@ void AvatarManager::updateOtherAvatars(float deltaTime) {
simulateAvatarFades(deltaTime); simulateAvatarFades(deltaTime);
} }
void AvatarManager::renderAvatars(bool forceRenderMyHead, bool selfAvatarOnly) { void AvatarManager::renderAvatars(bool forShadowMapOrMirror, bool selfAvatarOnly) {
PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings), PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings),
"Application::renderAvatars()"); "Application::renderAvatars()");
bool renderLookAtVectors = Menu::getInstance()->isOptionChecked(MenuOption::LookAtVectors); bool renderLookAtVectors = Menu::getInstance()->isOptionChecked(MenuOption::LookAtVectors);
@ -83,16 +83,16 @@ void AvatarManager::renderAvatars(bool forceRenderMyHead, bool selfAvatarOnly) {
avatar->init(); avatar->init();
} }
if (avatar == static_cast<Avatar*>(_myAvatar.data())) { if (avatar == static_cast<Avatar*>(_myAvatar.data())) {
_myAvatar->render(forceRenderMyHead); _myAvatar->render(forShadowMapOrMirror);
} else { } else {
avatar->render(); avatar->render(forShadowMapOrMirror);
} }
avatar->setDisplayingLookatVectors(renderLookAtVectors); avatar->setDisplayingLookatVectors(renderLookAtVectors);
} }
renderAvatarFades(); renderAvatarFades(forShadowMapOrMirror);
} else { } else {
// just render myAvatar // just render myAvatar
_myAvatar->render(forceRenderMyHead, true); _myAvatar->render(forShadowMapOrMirror);
_myAvatar->setDisplayingLookatVectors(renderLookAtVectors); _myAvatar->setDisplayingLookatVectors(renderLookAtVectors);
} }
} }
@ -115,13 +115,13 @@ void AvatarManager::simulateAvatarFades(float deltaTime) {
} }
} }
void AvatarManager::renderAvatarFades() { void AvatarManager::renderAvatarFades(bool forShadowMap) {
// render avatar fades // render avatar fades
Glower glower; Glower glower(forShadowMap ? 0.0f : 1.0f);
foreach(const AvatarSharedPointer& fadingAvatar, _avatarFades) { foreach(const AvatarSharedPointer& fadingAvatar, _avatarFades) {
Avatar* avatar = static_cast<Avatar*>(fadingAvatar.data()); Avatar* avatar = static_cast<Avatar*>(fadingAvatar.data());
avatar->render(); avatar->render(forShadowMap);
} }
} }

View file

@ -29,7 +29,7 @@ public:
MyAvatar* getMyAvatar() { return _myAvatar.data(); } MyAvatar* getMyAvatar() { return _myAvatar.data(); }
void updateOtherAvatars(float deltaTime); void updateOtherAvatars(float deltaTime);
void renderAvatars(bool forceRenderMyHead, bool selfAvatarOnly = false); void renderAvatars(bool forShadowMapOrMirror = false, bool selfAvatarOnly = false);
void clearOtherAvatars(); void clearOtherAvatars();
@ -45,7 +45,7 @@ private:
void processKillAvatar(const QByteArray& datagram); void processKillAvatar(const QByteArray& datagram);
void simulateAvatarFades(float deltaTime); void simulateAvatarFades(float deltaTime);
void renderAvatarFades(); void renderAvatarFades(bool forShadowMap);
// virtual override // virtual override
AvatarHash::iterator erase(const AvatarHash::iterator& iterator); AvatarHash::iterator erase(const AvatarHash::iterator& iterator);

View file

@ -452,14 +452,14 @@ void MyAvatar::renderDebugBodyPoints() {
} }
void MyAvatar::render(bool forceRenderHead, bool avatarOnly) { void MyAvatar::render(bool forShadowMapOrMirror) {
// don't render if we've been asked to disable local rendering // don't render if we've been asked to disable local rendering
if (!_shouldRender) { if (!_shouldRender) {
return; // exit early return; // exit early
} }
if (Menu::getInstance()->isOptionChecked(MenuOption::Avatars)) { if (Menu::getInstance()->isOptionChecked(MenuOption::Avatars)) {
renderBody(forceRenderHead); renderBody(forShadowMapOrMirror);
} }
// render body // render body
if (Menu::getInstance()->isOptionChecked(MenuOption::RenderSkeletonCollisionProxies)) { if (Menu::getInstance()->isOptionChecked(MenuOption::RenderSkeletonCollisionProxies)) {
@ -468,8 +468,8 @@ void MyAvatar::render(bool forceRenderHead, bool avatarOnly) {
if (Menu::getInstance()->isOptionChecked(MenuOption::RenderHeadCollisionProxies)) { if (Menu::getInstance()->isOptionChecked(MenuOption::RenderHeadCollisionProxies)) {
getHead()->getFaceModel().renderCollisionProxies(0.8f); getHead()->getFaceModel().renderCollisionProxies(0.8f);
} }
setShowDisplayName(!avatarOnly); setShowDisplayName(!forShadowMapOrMirror);
if (avatarOnly) { if (forShadowMapOrMirror) {
return; return;
} }
renderDisplayName(); renderDisplayName();

View file

@ -35,7 +35,7 @@ public:
void simulate(float deltaTime); void simulate(float deltaTime);
void updateFromGyros(float deltaTime); void updateFromGyros(float deltaTime);
void render(bool forceRenderHead, bool avatarOnly = false); void render(bool forShadowMapOrMirror = false);
void renderDebugBodyPoints(); void renderDebugBodyPoints();
void renderHeadMouse() const; void renderHeadMouse() const;

View file

@ -343,7 +343,14 @@ QSharedPointer<NetworkGeometry> NetworkGeometry::getLODOrFallback(float distance
// if we previously selected a different distance, make sure we've moved far enough to justify switching // if we previously selected a different distance, make sure we've moved far enough to justify switching
const float HYSTERESIS_PROPORTION = 0.1f; const float HYSTERESIS_PROPORTION = 0.1f;
if (glm::abs(distance - qMax(hysteresis, lodDistance)) / fabsf(hysteresis - lodDistance) < HYSTERESIS_PROPORTION) { if (glm::abs(distance - qMax(hysteresis, lodDistance)) / fabsf(hysteresis - lodDistance) < HYSTERESIS_PROPORTION) {
return getLODOrFallback(hysteresis, hysteresis); lod = _lodParent;
lodDistance = 0.0f;
it = _lods.upperBound(hysteresis);
if (it != _lods.constBegin()) {
it = it - 1;
lod = it.value();
lodDistance = it.key();
}
} }
} }
if (lod->isLoaded()) { if (lod->isLoaded()) {

View file

@ -467,6 +467,7 @@ void Model::setURL(const QUrl& url, const QUrl& fallback, bool retainCurrent, bo
// if so instructed, keep the current geometry until the new one is loaded // if so instructed, keep the current geometry until the new one is loaded
_nextBaseGeometry = _nextGeometry = Application::getInstance()->getGeometryCache()->getGeometry(url, fallback, delayLoad); _nextBaseGeometry = _nextGeometry = Application::getInstance()->getGeometryCache()->getGeometry(url, fallback, delayLoad);
_nextLODHysteresis = NetworkGeometry::NO_HYSTERESIS;
if (!retainCurrent || !isActive() || _nextGeometry->isLoaded()) { if (!retainCurrent || !isActive() || _nextGeometry->isLoaded()) {
applyNextGeometry(); applyNextGeometry();
} }
@ -850,7 +851,7 @@ void Model::applyCollision(CollisionInfo& collision) {
QVector<Model::JointState> Model::updateGeometry(bool delayLoad) { QVector<Model::JointState> Model::updateGeometry(bool delayLoad) {
QVector<JointState> newJointStates; QVector<JointState> newJointStates;
if (_nextGeometry) { if (_nextGeometry) {
_nextGeometry = _nextGeometry->getLODOrFallback(_lodDistance, _lodHysteresis, delayLoad); _nextGeometry = _nextGeometry->getLODOrFallback(_lodDistance, _nextLODHysteresis, delayLoad);
if (!delayLoad) { if (!delayLoad) {
_nextGeometry->setLoadPriority(this, -_lodDistance); _nextGeometry->setLoadPriority(this, -_lodDistance);
_nextGeometry->ensureLoading(); _nextGeometry->ensureLoading();
@ -893,7 +894,7 @@ void Model::applyNextGeometry() {
// delete our local geometry and custom textures // delete our local geometry and custom textures
deleteGeometry(); deleteGeometry();
_dilatedTextures.clear(); _dilatedTextures.clear();
_lodHysteresis = NetworkGeometry::NO_HYSTERESIS; _lodHysteresis = _nextLODHysteresis;
// we retain a reference to the base geometry so that its reference count doesn't fall to zero // we retain a reference to the base geometry so that its reference count doesn't fall to zero
_baseGeometry = _nextBaseGeometry; _baseGeometry = _nextBaseGeometry;

View file

@ -259,6 +259,7 @@ private:
QSharedPointer<NetworkGeometry> _nextGeometry; QSharedPointer<NetworkGeometry> _nextGeometry;
float _lodDistance; float _lodDistance;
float _lodHysteresis; float _lodHysteresis;
float _nextLODHysteresis;
float _pupilDilation; float _pupilDilation;
std::vector<float> _blendshapeCoefficients; std::vector<float> _blendshapeCoefficients;

View file

@ -113,7 +113,8 @@ GLuint TextureCache::getFileTextureID(const QString& filename) {
glBindTexture(GL_TEXTURE_2D, id); glBindTexture(GL_TEXTURE_2D, id);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, image.width(), image.height(), 1, glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, image.width(), image.height(), 1,
GL_BGRA, GL_UNSIGNED_BYTE, image.constBits()); GL_BGRA, GL_UNSIGNED_BYTE, image.constBits());
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glGenerateMipmap(GL_TEXTURE_2D);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
glBindTexture(GL_TEXTURE_2D, 0); glBindTexture(GL_TEXTURE_2D, 0);
_fileTextureIDs.insert(filename, id); _fileTextureIDs.insert(filename, id);
@ -335,7 +336,8 @@ void NetworkTexture::setImage(const QImage& image, const glm::vec4& averageColor
glBindTexture(GL_TEXTURE_2D, getID()); glBindTexture(GL_TEXTURE_2D, getID());
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, image.width(), image.height(), 1, glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, image.width(), image.height(), 1,
GL_BGRA, GL_UNSIGNED_BYTE, image.constBits()); GL_BGRA, GL_UNSIGNED_BYTE, image.constBits());
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glGenerateMipmap(GL_TEXTURE_2D);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
glBindTexture(GL_TEXTURE_2D, 0); glBindTexture(GL_TEXTURE_2D, 0);
} }
@ -388,7 +390,8 @@ QSharedPointer<Texture> DilatableNetworkTexture::getDilatedTexture(float dilatio
glBindTexture(GL_TEXTURE_2D, texture->getID()); glBindTexture(GL_TEXTURE_2D, texture->getID());
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, dilatedImage.width(), dilatedImage.height(), 1, glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, dilatedImage.width(), dilatedImage.height(), 1,
GL_BGRA, GL_UNSIGNED_BYTE, dilatedImage.constBits()); GL_BGRA, GL_UNSIGNED_BYTE, dilatedImage.constBits());
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glGenerateMipmap(GL_TEXTURE_2D);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
glBindTexture(GL_TEXTURE_2D, 0); glBindTexture(GL_TEXTURE_2D, 0);
} }