mirror of
https://github.com/overte-org/overte.git
synced 2025-08-08 10:37:35 +02:00
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:
commit
a39b0313c9
11 changed files with 43 additions and 28 deletions
|
@ -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
|
||||||
|
|
|
@ -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()) {
|
||||||
|
|
|
@ -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); }
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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();
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
|
|
@ -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()) {
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue