mirror of
https://github.com/overte-org/overte.git
synced 2025-04-08 05:52:38 +02:00
merge from upstream
This commit is contained in:
commit
021dc64789
25 changed files with 295 additions and 278 deletions
|
@ -49,7 +49,7 @@ if (WIN32)
|
|||
else ()
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra -fno-strict-aliasing -Wno-unused-parameter")
|
||||
if (CMAKE_COMPILER_IS_GNUCC OR CMAKE_COMPILER_IS_GNUCXX)
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -ggdb -Wdouble-promotion")
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -ggdb -Woverloaded-virtual -Wdouble-promotion")
|
||||
endif ()
|
||||
endif(WIN32)
|
||||
|
||||
|
|
|
@ -57,7 +57,7 @@ const float CHAT_MESSAGE_SCALE = 0.0015f;
|
|||
const float CHAT_MESSAGE_HEIGHT = 0.1f;
|
||||
const float DISPLAYNAME_FADE_TIME = 0.5f;
|
||||
const float DISPLAYNAME_FADE_FACTOR = pow(0.01f, 1.0f / DISPLAYNAME_FADE_TIME);
|
||||
const float DISPLAYNAME_ALPHA = 0.95f;
|
||||
const float DISPLAYNAME_ALPHA = 1.0f;
|
||||
const float DISPLAYNAME_BACKGROUND_ALPHA = 0.4f;
|
||||
|
||||
namespace render {
|
||||
|
@ -280,9 +280,9 @@ enum TextRendererType {
|
|||
};
|
||||
|
||||
static TextRenderer3D* textRenderer(TextRendererType type) {
|
||||
static TextRenderer3D* chatRenderer = TextRenderer3D::getInstance(SANS_FONT_FAMILY, 24, -1,
|
||||
static TextRenderer3D* chatRenderer = TextRenderer3D::getInstance(SANS_FONT_FAMILY, -1,
|
||||
false, TextRenderer3D::SHADOW_EFFECT);
|
||||
static TextRenderer3D* displayNameRenderer = TextRenderer3D::getInstance(SANS_FONT_FAMILY, 12);
|
||||
static TextRenderer3D* displayNameRenderer = TextRenderer3D::getInstance(SANS_FONT_FAMILY);
|
||||
|
||||
switch(type) {
|
||||
case CHAT:
|
||||
|
@ -323,7 +323,7 @@ void Avatar::render(RenderArgs* renderArgs, const glm::vec3& cameraPosition, boo
|
|||
_referential->update();
|
||||
}
|
||||
|
||||
auto batch = renderArgs->_batch;
|
||||
auto& batch = *renderArgs->_batch;
|
||||
|
||||
if (postLighting &&
|
||||
glm::distance(DependencyManager::get<AvatarManager>()->getMyAvatar()->getPosition(), _position) < 10.0f) {
|
||||
|
@ -354,9 +354,9 @@ void Avatar::render(RenderArgs* renderArgs, const glm::vec3& cameraPosition, boo
|
|||
Transform pointerTransform;
|
||||
pointerTransform.setTranslation(position);
|
||||
pointerTransform.setRotation(rotation);
|
||||
batch->setModelTransform(pointerTransform);
|
||||
deferredLighting->bindSimpleProgram(*batch);
|
||||
geometryCache->renderLine(*batch, glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3(0.0f, laserLength, 0.0f), laserColor);
|
||||
batch.setModelTransform(pointerTransform);
|
||||
deferredLighting->bindSimpleProgram(batch);
|
||||
geometryCache->renderLine(batch, glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3(0.0f, laserLength, 0.0f), laserColor);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -377,9 +377,9 @@ void Avatar::render(RenderArgs* renderArgs, const glm::vec3& cameraPosition, boo
|
|||
Transform pointerTransform;
|
||||
pointerTransform.setTranslation(position);
|
||||
pointerTransform.setRotation(rotation);
|
||||
batch->setModelTransform(pointerTransform);
|
||||
deferredLighting->bindSimpleProgram(*batch);
|
||||
geometryCache->renderLine(*batch, glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3(0.0f, laserLength, 0.0f), laserColor);
|
||||
batch.setModelTransform(pointerTransform);
|
||||
deferredLighting->bindSimpleProgram(batch);
|
||||
geometryCache->renderLine(batch, glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3(0.0f, laserLength, 0.0f), laserColor);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -464,8 +464,8 @@ void Avatar::render(RenderArgs* renderArgs, const glm::vec3& cameraPosition, boo
|
|||
}
|
||||
Transform transform;
|
||||
transform.setTranslation(position);
|
||||
batch->setModelTransform(transform);
|
||||
DependencyManager::get<DeferredLightingEffect>()->renderSolidSphere(*batch, LOOK_AT_INDICATOR_RADIUS
|
||||
batch.setModelTransform(transform);
|
||||
DependencyManager::get<DeferredLightingEffect>()->renderSolidSphere(batch, LOOK_AT_INDICATOR_RADIUS
|
||||
, 15, 15, LOOK_AT_INDICATOR_COLOR);
|
||||
}
|
||||
}
|
||||
|
@ -492,14 +492,14 @@ void Avatar::render(RenderArgs* renderArgs, const glm::vec3& cameraPosition, boo
|
|||
Transform transform;
|
||||
transform.setTranslation(_position);
|
||||
transform.setScale(height);
|
||||
batch->setModelTransform(transform);
|
||||
batch.setModelTransform(transform);
|
||||
|
||||
if (_voiceSphereID == GeometryCache::UNKNOWN_ID) {
|
||||
_voiceSphereID = DependencyManager::get<GeometryCache>()->allocateID();
|
||||
}
|
||||
|
||||
DependencyManager::get<DeferredLightingEffect>()->bindSimpleProgram(*batch);
|
||||
DependencyManager::get<GeometryCache>()->renderSphere(*batch, sphereRadius, 15, 15,
|
||||
DependencyManager::get<DeferredLightingEffect>()->bindSimpleProgram(batch);
|
||||
DependencyManager::get<GeometryCache>()->renderSphere(batch, sphereRadius, 15, 15,
|
||||
glm::vec4(SPHERE_COLOR[0], SPHERE_COLOR[1], SPHERE_COLOR[2], 1.0f - angle / MAX_SPHERE_ANGLE), true,
|
||||
_voiceSphereID);
|
||||
}
|
||||
|
@ -507,14 +507,12 @@ void Avatar::render(RenderArgs* renderArgs, const glm::vec3& cameraPosition, boo
|
|||
}
|
||||
|
||||
const float DISPLAYNAME_DISTANCE = 20.0f;
|
||||
setShowDisplayName(renderArgs->_renderMode == RenderArgs::NORMAL_RENDER_MODE && distanceToTarget < DISPLAYNAME_DISTANCE);
|
||||
setShowDisplayName(distanceToTarget < DISPLAYNAME_DISTANCE);
|
||||
|
||||
if (renderArgs->_renderMode != RenderArgs::NORMAL_RENDER_MODE || (isMyAvatar() &&
|
||||
Application::getInstance()->getCamera()->getMode() == CAMERA_MODE_FIRST_PERSON)) {
|
||||
return;
|
||||
auto cameraMode = Application::getInstance()->getCamera()->getMode();
|
||||
if (!isMyAvatar() || cameraMode != CAMERA_MODE_FIRST_PERSON) {
|
||||
renderDisplayName(batch, *renderArgs->_viewFrustum);
|
||||
}
|
||||
|
||||
renderDisplayName(renderArgs);
|
||||
}
|
||||
|
||||
glm::quat Avatar::computeRotationFromBodyToWorldUp(float proportion) const {
|
||||
|
@ -654,8 +652,8 @@ float Avatar::getBillboardSize() const {
|
|||
return _scale * BILLBOARD_DISTANCE * tanf(glm::radians(BILLBOARD_FIELD_OF_VIEW / 2.0f));
|
||||
}
|
||||
|
||||
glm::vec3 Avatar::getDisplayNamePosition() {
|
||||
glm::vec3 namePosition;
|
||||
glm::vec3 Avatar::getDisplayNamePosition() const {
|
||||
glm::vec3 namePosition(0.0f);
|
||||
if (getSkeletonModel().getNeckPosition(namePosition)) {
|
||||
namePosition += getBodyUpDirection() * getHeadHeight() * 1.1f;
|
||||
} else {
|
||||
|
@ -665,83 +663,73 @@ glm::vec3 Avatar::getDisplayNamePosition() {
|
|||
return namePosition;
|
||||
}
|
||||
|
||||
float Avatar::calculateDisplayNameScaleFactor(const glm::vec3& textPosition, bool inHMD) {
|
||||
|
||||
// We need to compute the scale factor such as the text remains with fixed size respect to window coordinates
|
||||
// We project a unit vector and check the difference in screen coordinates, to check which is the
|
||||
// correction scale needed
|
||||
// save the matrices for later scale correction factor
|
||||
// The up vector must be relative to the rotation current rotation matrix:
|
||||
// we set the identity
|
||||
Transform Avatar::calculateDisplayNameTransform(const ViewFrustum& frustum, float fontSize) const {
|
||||
Transform result;
|
||||
// We assume textPosition is whithin the frustum
|
||||
glm::vec3 textPosition = getDisplayNamePosition();
|
||||
|
||||
// Compute viewProjection matrix
|
||||
glm::mat4 projMat, viewMat;
|
||||
Transform view;
|
||||
frustum.evalProjectionMatrix(projMat);
|
||||
frustum.evalViewTransform(view);
|
||||
glm::mat4 viewProj = projMat * view.getInverseMatrix(viewMat);
|
||||
|
||||
// Used to determine correct scale
|
||||
glm::vec3 testPoint0 = textPosition;
|
||||
glm::vec3 testPoint1 = textPosition + (Application::getInstance()->getCamera()->getRotation() * IDENTITY_UP);
|
||||
|
||||
double textWindowHeight;
|
||||
|
||||
glm::vec3 testPoint1 = testPoint0 + glm::normalize(frustum.getUp());
|
||||
// testPoints projections
|
||||
glm::vec4 p0 = viewProj * glm::vec4(testPoint0, 1.0);
|
||||
glm::vec4 p1 = viewProj * glm::vec4(testPoint1, 1.0);
|
||||
|
||||
// TODO REMOVE vvv
|
||||
GLint viewportMatrix[4];
|
||||
glGetIntegerv(GL_VIEWPORT, viewportMatrix);
|
||||
glm::dmat4 modelViewMatrix;
|
||||
float windowSizeX = viewportMatrix[2] - viewportMatrix[0];
|
||||
float windowSizeY = viewportMatrix[3] - viewportMatrix[1];
|
||||
// TODO REMOVE ^^^
|
||||
|
||||
const float DESIRED_HIGHT_ON_SCREEN = 20; // In pixels (this is double on retinas)
|
||||
|
||||
// Projected point are between -1.0f and 1.0f, hence 0.5f * windowSizeY
|
||||
double pixelHeight = 0.5f * windowSizeY * glm::abs((p1.y / p1.w) - (p0.y / p0.w)); //
|
||||
// Handles pixel density (especially for macs retina displays)
|
||||
double devicePixelRatio = qApp->getDevicePixelRatio() * qApp->getRenderResolutionScale(); // pixels / unit
|
||||
|
||||
// Compute correct scale to apply
|
||||
float scale = DESIRED_HIGHT_ON_SCREEN / (fontSize * pixelHeight) * devicePixelRatio;
|
||||
|
||||
// Compute pixel alignment offset
|
||||
float clipToPix = 0.5f * windowSizeY / p1.w; // Got from clip to pixel coordinates
|
||||
glm::vec4 screenPos = clipToPix * p1; // in pixels coords
|
||||
glm::vec4 screenOffset = (glm::round(screenPos) - screenPos) / clipToPix; // in clip coords
|
||||
glm::vec3 worldOffset = glm::vec3(screenOffset.x, screenOffset.y, 0.0f) / (float)pixelHeight;
|
||||
|
||||
// Compute orientation
|
||||
glm::vec3 eulerAngles = ::safeEulerAngles(frustum.getOrientation());
|
||||
eulerAngles.z = 0.0f; // Cancel roll
|
||||
glm::quat orientation(eulerAngles); // back to quaternions
|
||||
|
||||
// Set transform (The order IS important)
|
||||
result.setTranslation(textPosition);
|
||||
result.setRotation(orientation); // Always face the screen
|
||||
result.postTranslate(worldOffset); // Pixel alignment
|
||||
result.setScale(scale);
|
||||
return result;
|
||||
|
||||
glm::dmat4 projectionMatrix;
|
||||
Application::getInstance()->getModelViewMatrix(&modelViewMatrix);
|
||||
Application::getInstance()->getProjectionMatrix(&projectionMatrix);
|
||||
|
||||
|
||||
glm::dvec4 p0 = modelViewMatrix * glm::dvec4(testPoint0, 1.0);
|
||||
p0 = projectionMatrix * p0;
|
||||
glm::dvec2 result0 = glm::vec2(windowSizeX * ((float)p0.x / (float)p0.w + 1.0f) * 0.5f,
|
||||
windowSizeY * ((float)p0.y / (float)p0.w + 1.0f) * 0.5f);
|
||||
|
||||
glm::dvec4 p1 = modelViewMatrix * glm::dvec4(testPoint1, 1.0);
|
||||
p1 = projectionMatrix * p1;
|
||||
glm::vec2 result1 = glm::vec2(windowSizeX * ((float)p1.x / (float)p1.w + 1.0f) * 0.5f,
|
||||
windowSizeY * ((float)p1.y / (float)p1.w + 1.0f) * 0.5f);
|
||||
textWindowHeight = fabs((double)result1.y - (double)result0.y);
|
||||
|
||||
// need to scale to compensate for the font resolution due to the device
|
||||
float scaleFactor = (float)QApplication::desktop()->windowHandle()->devicePixelRatio() *
|
||||
(((float)textWindowHeight > EPSILON) ? 1.0f / (float)textWindowHeight : 1.0f);
|
||||
if (inHMD) {
|
||||
const float HMDMODE_NAME_SCALE = 0.65f;
|
||||
scaleFactor *= HMDMODE_NAME_SCALE;
|
||||
} else {
|
||||
scaleFactor *= Application::getInstance()->getRenderResolutionScale();
|
||||
}
|
||||
return scaleFactor;
|
||||
}
|
||||
|
||||
void Avatar::renderDisplayName(RenderArgs* renderArgs) {
|
||||
auto batch = renderArgs->_batch;
|
||||
|
||||
void Avatar::renderDisplayName(gpu::Batch& batch, const ViewFrustum& frustum) const {
|
||||
bool shouldShowReceiveStats = DependencyManager::get<AvatarManager>()->shouldShowReceiveStats() && !isMyAvatar();
|
||||
|
||||
// If we have nothing to draw, or it's tottaly transparent, return
|
||||
if ((_displayName.isEmpty() && !shouldShowReceiveStats) || _displayNameAlpha == 0.0f) {
|
||||
return;
|
||||
}
|
||||
|
||||
// which viewing mode?
|
||||
bool inHMD = Application::getInstance()->isHMDMode();
|
||||
|
||||
glm::vec3 textPosition = getDisplayNamePosition();
|
||||
|
||||
// we need "always facing camera": we must remove the camera rotation from the stac
|
||||
glm::quat rotation = Application::getInstance()->getCamera()->getRotation();
|
||||
|
||||
// TODO: Fix scaling - at some point this or the text rendering changed in scale.
|
||||
float scaleFactor = calculateDisplayNameScaleFactor(textPosition, inHMD);
|
||||
scaleFactor /= 3.5f;
|
||||
|
||||
Transform textTransform;
|
||||
textTransform.setTranslation(textPosition);
|
||||
textTransform.setRotation(rotation);
|
||||
textTransform.setScale(scaleFactor);
|
||||
auto renderer = textRenderer(DISPLAYNAME);
|
||||
|
||||
// optionally render timing stats for this avatar with the display name
|
||||
QString renderedDisplayName = _displayName;
|
||||
QRect nameDynamicRect = _displayNameBoundingRect;
|
||||
|
||||
if (shouldShowReceiveStats) {
|
||||
float kilobitsPerSecond = getAverageBytesReceivedPerSecond() / (float) BYTES_PER_KILOBIT;
|
||||
|
||||
|
@ -749,42 +737,43 @@ void Avatar::renderDisplayName(RenderArgs* renderArgs) {
|
|||
if (!renderedDisplayName.isEmpty()) {
|
||||
statsFormat.prepend(" - ");
|
||||
}
|
||||
|
||||
QString statsText = statsFormat.arg(QString::number(kilobitsPerSecond, 'f', 2)).arg(getReceiveRate());
|
||||
renderedDisplayName += statsText;
|
||||
|
||||
glm::vec2 extent = textRenderer(DISPLAYNAME)->computeExtent(renderedDisplayName);
|
||||
nameDynamicRect = QRect(0, 0, (int)extent.x, (int)extent.y);
|
||||
renderedDisplayName += statsFormat.arg(QString::number(kilobitsPerSecond, 'f', 2)).arg(getReceiveRate());
|
||||
}
|
||||
|
||||
int text_x = -nameDynamicRect.width() / 2;
|
||||
int text_y = -nameDynamicRect.height() / 2;
|
||||
|
||||
// draw a gray background
|
||||
int left = text_x;
|
||||
int right = left + nameDynamicRect.width();
|
||||
int bottom = text_y;
|
||||
int top = bottom + nameDynamicRect.height();
|
||||
const int border = 8;
|
||||
bottom -= border;
|
||||
left -= border;
|
||||
top += border;
|
||||
right += border;
|
||||
|
||||
// Compute display name extent/position offset
|
||||
glm::vec2 extent = renderer->computeExtent(renderedDisplayName);
|
||||
QRect nameDynamicRect = QRect(0, 0, (int)extent.x, (int)extent.y);
|
||||
const int text_x = -nameDynamicRect.width() / 2;
|
||||
const int text_y = -nameDynamicRect.height() / 2;
|
||||
|
||||
// Compute background position/size
|
||||
static const float SLIGHTLY_BEHIND = -0.05f;
|
||||
const int border = 0.1f * nameDynamicRect.height();
|
||||
const int left = text_x - border;
|
||||
const int bottom = text_y - border;
|
||||
const int width = nameDynamicRect.width() + 2.0f * border;
|
||||
const int height = nameDynamicRect.height() + 2.0f * border;
|
||||
const int bevelDistance = 0.1f * height;
|
||||
|
||||
// Display name and background colors
|
||||
glm::vec4 textColor(0.93f, 0.93f, 0.93f, _displayNameAlpha);
|
||||
glm::vec4 backgroundColor(0.2f, 0.2f, 0.2f,
|
||||
_displayNameAlpha * DISPLAYNAME_BACKGROUND_ALPHA / DISPLAYNAME_ALPHA);
|
||||
(_displayNameAlpha / DISPLAYNAME_ALPHA) * DISPLAYNAME_BACKGROUND_ALPHA);
|
||||
|
||||
// Compute display name transform
|
||||
auto textTransform = calculateDisplayNameTransform(frustum, renderer->getFontSize());
|
||||
|
||||
// Render background slightly behind to avoid z-fighting
|
||||
auto backgroundTransform = textTransform;
|
||||
backgroundTransform.postTranslate(glm::vec3(0.0f, 0.0f, -0.001f));
|
||||
batch->setModelTransform(backgroundTransform);
|
||||
DependencyManager::get<DeferredLightingEffect>()->bindSimpleProgram(*batch);
|
||||
DependencyManager::get<GeometryCache>()->renderBevelCornersRect(*batch, left, bottom, right - left, top - bottom, 3,
|
||||
backgroundColor);
|
||||
backgroundTransform.postTranslate(glm::vec3(0.0f, 0.0f, SLIGHTLY_BEHIND));
|
||||
batch.setModelTransform(backgroundTransform);
|
||||
DependencyManager::get<DeferredLightingEffect>()->bindSimpleProgram(batch);
|
||||
DependencyManager::get<GeometryCache>()->renderBevelCornersRect(batch, left, bottom, width, height,
|
||||
bevelDistance, backgroundColor);
|
||||
// Render actual name
|
||||
QByteArray nameUTF8 = renderedDisplayName.toLocal8Bit();
|
||||
|
||||
batch->setModelTransform(textTransform);
|
||||
textRenderer(DISPLAYNAME)->draw(*batch, text_x, -text_y, nameUTF8.data(), textColor);
|
||||
batch.setModelTransform(textTransform);
|
||||
renderer->draw(batch, text_x, -text_y, nameUTF8.data(), textColor);
|
||||
}
|
||||
|
||||
bool Avatar::findRayIntersection(RayIntersectionInfo& intersection) const {
|
||||
|
@ -989,13 +978,6 @@ void Avatar::setAttachmentData(const QVector<AttachmentData>& attachmentData) {
|
|||
}
|
||||
}
|
||||
|
||||
void Avatar::setDisplayName(const QString& displayName) {
|
||||
AvatarData::setDisplayName(displayName);
|
||||
// FIXME is this a sufficient replacement for tightBoundingRect?
|
||||
glm::vec2 extent = textRenderer(DISPLAYNAME)->computeExtent(displayName);
|
||||
_displayNameBoundingRect = QRect(0, 0, (int)extent.x, (int)extent.y);
|
||||
}
|
||||
|
||||
void Avatar::setBillboard(const QByteArray& billboard) {
|
||||
AvatarData::setBillboard(billboard);
|
||||
|
||||
|
@ -1094,7 +1076,12 @@ float Avatar::getSkeletonHeight() const {
|
|||
float Avatar::getHeadHeight() const {
|
||||
Extents extents = getHead()->getFaceModel().getMeshExtents();
|
||||
if (!extents.isEmpty() && extents.isValid()) {
|
||||
return extents.maximum.y - extents.minimum.y;
|
||||
|
||||
// HACK: We have a really odd case when fading out for some models where this value explodes
|
||||
float result = extents.maximum.y - extents.minimum.y;
|
||||
if (result >= 0.0f && result < 100.0f * _scale ) {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
extents = _skeletonModel.getMeshExtents();
|
||||
|
@ -1118,7 +1105,7 @@ void Avatar::setShowDisplayName(bool showDisplayName) {
|
|||
}
|
||||
|
||||
// For myAvatar, the alpha update is not done (called in simulate for other avatars)
|
||||
if (DependencyManager::get<AvatarManager>()->getMyAvatar() == this) {
|
||||
if (isMyAvatar()) {
|
||||
if (showDisplayName) {
|
||||
_displayNameAlpha = DISPLAYNAME_ALPHA;
|
||||
} else {
|
||||
|
@ -1131,7 +1118,6 @@ void Avatar::setShowDisplayName(bool showDisplayName) {
|
|||
} else {
|
||||
_displayNameTargetAlpha = 0.0f;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// virtual
|
||||
|
|
|
@ -98,6 +98,7 @@ public:
|
|||
//getters
|
||||
bool isInitialized() const { return _initialized; }
|
||||
SkeletonModel& getSkeletonModel() { return _skeletonModel; }
|
||||
const SkeletonModel& getSkeletonModel() const { return _skeletonModel; }
|
||||
const QVector<Model*>& getAttachmentModels() const { return _attachmentModels; }
|
||||
glm::vec3 getChestPosition() const;
|
||||
float getScale() const { return _scale; }
|
||||
|
@ -131,7 +132,7 @@ public:
|
|||
/// \return whether or not the plane penetrated
|
||||
bool findPlaneCollisions(const glm::vec4& plane, CollisionList& collisions);
|
||||
|
||||
virtual bool isMyAvatar() { return false; }
|
||||
virtual bool isMyAvatar() const { return false; }
|
||||
|
||||
virtual QVector<glm::quat> getJointRotations() const;
|
||||
virtual glm::quat getJointRotation(int index) const;
|
||||
|
@ -141,7 +142,6 @@ public:
|
|||
virtual void setFaceModelURL(const QUrl& faceModelURL);
|
||||
virtual void setSkeletonModelURL(const QUrl& skeletonModelURL);
|
||||
virtual void setAttachmentData(const QVector<AttachmentData>& attachmentData);
|
||||
virtual void setDisplayName(const QString& displayName);
|
||||
virtual void setBillboard(const QByteArray& billboard);
|
||||
|
||||
void setShowDisplayName(bool showDisplayName);
|
||||
|
@ -232,10 +232,10 @@ protected:
|
|||
float getSkeletonHeight() const;
|
||||
float getHeadHeight() const;
|
||||
float getPelvisFloatingHeight() const;
|
||||
glm::vec3 getDisplayNamePosition();
|
||||
glm::vec3 getDisplayNamePosition() const;
|
||||
|
||||
float calculateDisplayNameScaleFactor(const glm::vec3& textPosition, bool inHMD);
|
||||
void renderDisplayName(RenderArgs* renderArgs);
|
||||
Transform calculateDisplayNameTransform(const ViewFrustum& frustum, float fontSize) const;
|
||||
void renderDisplayName(gpu::Batch& batch, const ViewFrustum& frustum) const;
|
||||
virtual void renderBody(RenderArgs* renderArgs, ViewFrustum* renderFrustum, bool postLighting, float glowLevel = 0.0f);
|
||||
virtual bool shouldRenderHead(const RenderArgs* renderArgs, const glm::vec3& cameraPosition) const;
|
||||
virtual void fixupModelsInScene();
|
||||
|
|
|
@ -90,7 +90,7 @@ public:
|
|||
|
||||
void relayDriveKeysToCharacterController();
|
||||
|
||||
bool isMyAvatar() { return true; }
|
||||
bool isMyAvatar() const { return true; }
|
||||
|
||||
bool isLookingAtLeftEye();
|
||||
|
||||
|
|
|
@ -52,9 +52,8 @@ AvatarData::AvatarData() :
|
|||
_headData(NULL),
|
||||
_handData(NULL),
|
||||
_faceModelURL("http://invalid.com"),
|
||||
_displayNameBoundingRect(),
|
||||
_displayNameTargetAlpha(0.0f),
|
||||
_displayNameAlpha(0.0f),
|
||||
_displayNameTargetAlpha(1.0f),
|
||||
_displayNameAlpha(1.0f),
|
||||
_billboard(),
|
||||
_errorLogExpiry(0),
|
||||
_owningAvatarMixer(),
|
||||
|
|
|
@ -163,7 +163,7 @@ public:
|
|||
AvatarData();
|
||||
virtual ~AvatarData();
|
||||
|
||||
virtual bool isMyAvatar() { return false; }
|
||||
virtual bool isMyAvatar() const { return false; }
|
||||
|
||||
const QUuid& getSessionUUID() const { return _sessionUUID; }
|
||||
|
||||
|
@ -378,7 +378,6 @@ protected:
|
|||
QVector<AttachmentData> _attachmentData;
|
||||
QString _displayName;
|
||||
|
||||
QRect _displayNameBoundingRect;
|
||||
float _displayNameTargetAlpha;
|
||||
float _displayNameAlpha;
|
||||
|
||||
|
|
|
@ -149,11 +149,7 @@ void RenderablePolyVoxEntityItem::setVoxelVolumeSize(glm::vec3 voxelVolumeSize)
|
|||
decompressVolumeData();
|
||||
}
|
||||
|
||||
void RenderablePolyVoxEntityItem::setVoxelSurfaceStyle(PolyVoxSurfaceStyle voxelSurfaceStyle) {
|
||||
if (voxelSurfaceStyle == _voxelSurfaceStyle) {
|
||||
return;
|
||||
}
|
||||
|
||||
void RenderablePolyVoxEntityItem::updateVoxelSurfaceStyle(PolyVoxSurfaceStyle voxelSurfaceStyle) {
|
||||
// if we are switching to or from "edged" we need to force a resize of _volData.
|
||||
if (voxelSurfaceStyle == SURFACE_EDGED_CUBIC ||
|
||||
_voxelSurfaceStyle == SURFACE_EDGED_CUBIC) {
|
||||
|
@ -161,10 +157,10 @@ void RenderablePolyVoxEntityItem::setVoxelSurfaceStyle(PolyVoxSurfaceStyle voxel
|
|||
delete _volData;
|
||||
}
|
||||
_volData = nullptr;
|
||||
PolyVoxEntityItem::setVoxelSurfaceStyle(voxelSurfaceStyle);
|
||||
_voxelSurfaceStyle = voxelSurfaceStyle;
|
||||
setVoxelVolumeSize(_voxelVolumeSize);
|
||||
} else {
|
||||
PolyVoxEntityItem::setVoxelSurfaceStyle(voxelSurfaceStyle);
|
||||
_voxelSurfaceStyle = voxelSurfaceStyle;
|
||||
}
|
||||
_needsModelReload = true;
|
||||
}
|
||||
|
|
|
@ -36,17 +36,15 @@ public:
|
|||
|
||||
virtual uint8_t getVoxel(int x, int y, int z);
|
||||
virtual void setVoxel(int x, int y, int z, uint8_t toValue);
|
||||
|
||||
|
||||
void updateOnCount(int x, int y, int z, uint8_t new_value);
|
||||
|
||||
void render(RenderArgs* args);
|
||||
virtual bool supportsDetailedRayIntersection() const { return true; }
|
||||
virtual bool findDetailedRayIntersection(const glm::vec3& origin, const glm::vec3& direction,
|
||||
bool& keepSearching, OctreeElement*& element, float& distance, BoxFace& face,
|
||||
bool& keepSearching, OctreeElement*& element, float& distance, BoxFace& face,
|
||||
void** intersectedObject, bool precisionPicking) const;
|
||||
|
||||
virtual void setVoxelSurfaceStyle(PolyVoxSurfaceStyle voxelSurfaceStyle);
|
||||
|
||||
void getModel();
|
||||
|
||||
virtual void setVoxelData(QByteArray voxelData);
|
||||
|
@ -74,6 +72,9 @@ public:
|
|||
|
||||
SIMPLE_RENDERABLE();
|
||||
|
||||
protected:
|
||||
virtual void updateVoxelSurfaceStyle(PolyVoxSurfaceStyle voxelSurfaceStyle);
|
||||
|
||||
private:
|
||||
// The PolyVoxEntityItem class has _voxelData which contains dimensions and compressed voxel data. The dimensions
|
||||
// may not match _voxelVolumeSize.
|
||||
|
@ -82,6 +83,7 @@ private:
|
|||
void compressVolumeData();
|
||||
void decompressVolumeData();
|
||||
|
||||
|
||||
PolyVox::SimpleVolume<uint8_t>* _volData = nullptr;
|
||||
model::Geometry _modelGeometry;
|
||||
bool _needsModelReload = true;
|
||||
|
|
|
@ -168,3 +168,10 @@ void PolyVoxEntityItem::debugDump() const {
|
|||
qCDebug(entities) << " dimensions:" << debugTreeVector(getDimensions());
|
||||
qCDebug(entities) << " getLastEdited:" << debugTime(getLastEdited(), now);
|
||||
}
|
||||
|
||||
void PolyVoxEntityItem::setVoxelSurfaceStyle(PolyVoxSurfaceStyle voxelSurfaceStyle) {
|
||||
if (voxelSurfaceStyle == _voxelSurfaceStyle) {
|
||||
return;
|
||||
}
|
||||
updateVoxelSurfaceStyle(voxelSurfaceStyle);
|
||||
}
|
||||
|
|
|
@ -61,10 +61,9 @@ class PolyVoxEntityItem : public EntityItem {
|
|||
SURFACE_EDGED_CUBIC
|
||||
};
|
||||
|
||||
virtual void setVoxelSurfaceStyle(PolyVoxSurfaceStyle voxelSurfaceStyle) { _voxelSurfaceStyle = voxelSurfaceStyle; }
|
||||
virtual void setVoxelSurfaceStyle(uint16_t voxelSurfaceStyle) {
|
||||
setVoxelSurfaceStyle((PolyVoxSurfaceStyle) voxelSurfaceStyle);
|
||||
}
|
||||
void setVoxelSurfaceStyle(PolyVoxSurfaceStyle voxelSurfaceStyle);
|
||||
// this other version of setVoxelSurfaceStyle is needed for SET_ENTITY_PROPERTY_FROM_PROPERTIES
|
||||
void setVoxelSurfaceStyle(uint16_t voxelSurfaceStyle) { setVoxelSurfaceStyle((PolyVoxSurfaceStyle) voxelSurfaceStyle); }
|
||||
virtual PolyVoxSurfaceStyle getVoxelSurfaceStyle() const { return _voxelSurfaceStyle; }
|
||||
|
||||
static const glm::vec3 DEFAULT_VOXEL_VOLUME_SIZE;
|
||||
|
@ -89,6 +88,10 @@ class PolyVoxEntityItem : public EntityItem {
|
|||
static QByteArray makeEmptyVoxelData(quint16 voxelXSize = 16, quint16 voxelYSize = 16, quint16 voxelZSize = 16);
|
||||
|
||||
protected:
|
||||
virtual void updateVoxelSurfaceStyle(PolyVoxSurfaceStyle voxelSurfaceStyle) {
|
||||
_voxelSurfaceStyle = voxelSurfaceStyle;
|
||||
}
|
||||
|
||||
glm::vec3 _voxelVolumeSize; // this is always 3 bytes
|
||||
QByteArray _voxelData;
|
||||
PolyVoxSurfaceStyle _voxelSurfaceStyle;
|
||||
|
|
|
@ -70,7 +70,7 @@ public:
|
|||
typedef Stream::Slot Slot;
|
||||
|
||||
Batch();
|
||||
Batch(const Batch& batch);
|
||||
explicit Batch(const Batch& batch);
|
||||
~Batch();
|
||||
|
||||
void clear();
|
||||
|
@ -148,6 +148,7 @@ public:
|
|||
void _glDrawBuffers(GLsizei n, const GLenum* bufs);
|
||||
|
||||
void _glUseProgram(GLuint program);
|
||||
void _glUniform1i(GLint location, GLint v0);
|
||||
void _glUniform1f(GLint location, GLfloat v0);
|
||||
void _glUniform2f(GLint location, GLfloat v0, GLfloat v1);
|
||||
void _glUniform3f(GLint location, GLfloat v0, GLfloat v1, GLfloat v2);
|
||||
|
@ -210,6 +211,7 @@ public:
|
|||
COMMAND_glDrawBuffers,
|
||||
|
||||
COMMAND_glUseProgram,
|
||||
COMMAND_glUniform1i,
|
||||
COMMAND_glUniform1f,
|
||||
COMMAND_glUniform2f,
|
||||
COMMAND_glUniform3f,
|
||||
|
|
|
@ -59,6 +59,7 @@ GLBackend::CommandCall GLBackend::_commandCalls[Batch::NUM_COMMANDS] =
|
|||
(&::gpu::GLBackend::do_glDrawBuffers),
|
||||
|
||||
(&::gpu::GLBackend::do_glUseProgram),
|
||||
(&::gpu::GLBackend::do_glUniform1i),
|
||||
(&::gpu::GLBackend::do_glUniform1f),
|
||||
(&::gpu::GLBackend::do_glUniform2f),
|
||||
(&::gpu::GLBackend::do_glUniform3f),
|
||||
|
@ -433,6 +434,28 @@ void GLBackend::do_glUseProgram(Batch& batch, uint32 paramOffset) {
|
|||
(void) CHECK_GL_ERROR();
|
||||
}
|
||||
|
||||
void Batch::_glUniform1i(GLint location, GLint v0) {
|
||||
if (location < 0) {
|
||||
return;
|
||||
}
|
||||
ADD_COMMAND_GL(glUniform1i);
|
||||
_params.push_back(v0);
|
||||
_params.push_back(location);
|
||||
|
||||
DO_IT_NOW(_glUniform1i, 1);
|
||||
}
|
||||
void GLBackend::do_glUniform1i(Batch& batch, uint32 paramOffset) {
|
||||
if (_pipeline._program == 0) {
|
||||
// We should call updatePipeline() to bind the program but we are not doing that
|
||||
// because these uniform setters are deprecated and we don;t want to create side effect
|
||||
return;
|
||||
}
|
||||
glUniform1f(
|
||||
batch._params[paramOffset + 1]._int,
|
||||
batch._params[paramOffset + 0]._int);
|
||||
(void) CHECK_GL_ERROR();
|
||||
}
|
||||
|
||||
void Batch::_glUniform1f(GLint location, GLfloat v0) {
|
||||
if (location < 0) {
|
||||
return;
|
||||
|
|
|
@ -377,6 +377,7 @@ protected:
|
|||
void do_glDrawBuffers(Batch& batch, uint32 paramOffset);
|
||||
|
||||
void do_glUseProgram(Batch& batch, uint32 paramOffset);
|
||||
void do_glUniform1i(Batch& batch, uint32 paramOffset);
|
||||
void do_glUniform1f(Batch& batch, uint32 paramOffset);
|
||||
void do_glUniform2f(Batch& batch, uint32 paramOffset);
|
||||
void do_glUniform3f(Batch& batch, uint32 paramOffset);
|
||||
|
|
|
@ -72,7 +72,7 @@ void Skybox::render(gpu::Batch& batch, const ViewFrustum& viewFrustum, const Sky
|
|||
|
||||
thePipeline = gpu::PipelinePointer(gpu::Pipeline::create(skyShader, skyState));
|
||||
|
||||
const float CLIP = 1.0;
|
||||
const float CLIP = 1.0f;
|
||||
const glm::vec2 vertices[4] = { {-CLIP, -CLIP}, {CLIP, -CLIP}, {-CLIP, CLIP}, {CLIP, CLIP}};
|
||||
theBuffer.reset(new gpu::Buffer(sizeof(vertices), (const gpu::Byte*) vertices));
|
||||
|
||||
|
@ -110,7 +110,7 @@ void Skybox::render(gpu::Batch& batch, const ViewFrustum& viewFrustum, const Sky
|
|||
} else {
|
||||
// skybox has no cubemap, just clear the color buffer
|
||||
auto color = skybox.getColor();
|
||||
batch.clearFramebuffer(gpu::Framebuffer::BUFFER_COLOR0, glm::vec4(color, 0.0f), 0.f, 0);
|
||||
batch.clearFramebuffer(gpu::Framebuffer::BUFFER_COLOR0, glm::vec4(color, 0.0f), 0.0f, 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -546,9 +546,9 @@ void ViewFrustum::printDebugDetails() const {
|
|||
|
||||
glm::vec2 ViewFrustum::projectPoint(glm::vec3 point, bool& pointInView) const {
|
||||
|
||||
glm::vec4 pointVec4 = glm::vec4(point,1);
|
||||
glm::vec4 pointVec4 = glm::vec4(point, 1.0f);
|
||||
glm::vec4 projectedPointVec4 = _ourModelViewProjectionMatrix * pointVec4;
|
||||
pointInView = (projectedPointVec4.w > 0); // math! If the w result is negative then the point is behind the viewer
|
||||
pointInView = (projectedPointVec4.w > 0.0f); // math! If the w result is negative then the point is behind the viewer
|
||||
|
||||
// what happens with w is 0???
|
||||
float x = projectedPointVec4.x / projectedPointVec4.w;
|
||||
|
|
|
@ -1,27 +1,37 @@
|
|||
set(TARGET_NAME render-utils)
|
||||
|
||||
AUTOSCRIBE_SHADER_LIB(gpu model render)
|
||||
|
||||
# pull in the resources.qrc file
|
||||
qt5_add_resources(QT_RESOURCES_FILE "${CMAKE_CURRENT_SOURCE_DIR}/res/fonts/fonts.qrc")
|
||||
|
||||
# use setup_hifi_library macro to setup our project and link appropriate Qt modules
|
||||
setup_hifi_library(Widgets OpenGL Network Qml Quick Script)
|
||||
|
||||
add_dependency_external_projects(glm)
|
||||
find_package(GLM REQUIRED)
|
||||
target_include_directories(${TARGET_NAME} PUBLIC ${GLM_INCLUDE_DIRS})
|
||||
|
||||
if (WIN32)
|
||||
if (USE_NSIGHT)
|
||||
# try to find the Nsight package and add it to the build if we find it
|
||||
find_package(NSIGHT)
|
||||
if (NSIGHT_FOUND)
|
||||
include_directories(${NSIGHT_INCLUDE_DIRS})
|
||||
add_definitions(-DNSIGHT_FOUND)
|
||||
target_link_libraries(${TARGET_NAME} "${NSIGHT_LIBRARIES}")
|
||||
endif ()
|
||||
endif()
|
||||
endif (WIN32)
|
||||
|
||||
link_hifi_libraries(animation fbx shared gpu model render)
|
||||
set(TARGET_NAME render-utils)
|
||||
|
||||
AUTOSCRIBE_SHADER_LIB(gpu model render)
|
||||
|
||||
# pull in the resources.qrc file
|
||||
qt5_add_resources(QT_RESOURCES_FILE "${CMAKE_CURRENT_SOURCE_DIR}/res/fonts/fonts.qrc")
|
||||
|
||||
# use setup_hifi_library macro to setup our project and link appropriate Qt modules
|
||||
setup_hifi_library(Widgets OpenGL Network Qml Quick Script)
|
||||
|
||||
setup_hifi_opengl()
|
||||
|
||||
add_dependency_external_projects(glm)
|
||||
find_package(GLM REQUIRED)
|
||||
target_include_directories(${TARGET_NAME} PUBLIC ${GLM_INCLUDE_DIRS})
|
||||
|
||||
if (WIN32)
|
||||
if (USE_NSIGHT)
|
||||
# try to find the Nsight package and add it to the build if we find it
|
||||
find_package(NSIGHT)
|
||||
if (NSIGHT_FOUND)
|
||||
include_directories(${NSIGHT_INCLUDE_DIRS})
|
||||
add_definitions(-DNSIGHT_FOUND)
|
||||
target_link_libraries(${TARGET_NAME} "${NSIGHT_LIBRARIES}")
|
||||
endif ()
|
||||
endif()
|
||||
|
||||
add_dependency_external_projects(boostconfig)
|
||||
find_package(BoostConfig REQUIRED)
|
||||
target_include_directories(${TARGET_NAME} PUBLIC ${BOOSTCONFIG_INCLUDE_DIRS})
|
||||
|
||||
add_dependency_external_projects(oglplus)
|
||||
find_package(OGLPLUS REQUIRED)
|
||||
target_include_directories(${TARGET_NAME} PUBLIC ${OGLPLUS_INCLUDE_DIRS})
|
||||
endif (WIN32)
|
||||
|
||||
link_hifi_libraries(animation fbx shared gpu model render)
|
||||
|
|
|
@ -1025,13 +1025,13 @@ void GeometryCache::renderBevelCornersRect(gpu::Batch& batch, int x, int y, int
|
|||
#endif // def WANT_DEBUG
|
||||
}
|
||||
|
||||
const int FLOATS_PER_VERTEX = 2; // vertices
|
||||
const int vertices = 8;
|
||||
|
||||
if (!details.isCreated) {
|
||||
|
||||
static const int FLOATS_PER_VERTEX = 2; // vertices
|
||||
static const int NUM_VERTICES = 8;
|
||||
static const int NUM_FLOATS = NUM_VERTICES * FLOATS_PER_VERTEX;
|
||||
|
||||
details.isCreated = true;
|
||||
details.vertices = vertices;
|
||||
details.vertices = NUM_VERTICES;
|
||||
details.vertexSize = FLOATS_PER_VERTEX;
|
||||
|
||||
gpu::BufferPointer verticesBuffer(new gpu::Buffer());
|
||||
|
@ -1044,62 +1044,65 @@ void GeometryCache::renderBevelCornersRect(gpu::Batch& batch, int x, int y, int
|
|||
details.streamFormat = streamFormat;
|
||||
details.stream = stream;
|
||||
|
||||
details.streamFormat->setAttribute(gpu::Stream::POSITION, 0, gpu::Element(gpu::VEC2, gpu::FLOAT, gpu::XYZ), 0);
|
||||
details.streamFormat->setAttribute(gpu::Stream::POSITION, 0, gpu::Element(gpu::VEC2, gpu::FLOAT, gpu::XYZ));
|
||||
details.streamFormat->setAttribute(gpu::Stream::COLOR, 1, gpu::Element(gpu::VEC4, gpu::UINT8, gpu::RGBA));
|
||||
|
||||
details.stream->addBuffer(details.verticesBuffer, 0, details.streamFormat->getChannels().at(0)._stride);
|
||||
details.stream->addBuffer(details.colorBuffer, 0, details.streamFormat->getChannels().at(1)._stride);
|
||||
|
||||
|
||||
int vertexPoints = vertices * FLOATS_PER_VERTEX;
|
||||
GLfloat* vertexBuffer = new GLfloat[vertexPoints]; // only vertices, no normals because we're a 2D quad
|
||||
GLfloat* vertex = vertexBuffer;
|
||||
GLfloat vertexBuffer[NUM_FLOATS]; // only vertices, no normals because we're a 2D quad
|
||||
int vertexPoint = 0;
|
||||
|
||||
// left side
|
||||
vertex[vertexPoint++] = x;
|
||||
vertex[vertexPoint++] = y + bevelDistance;
|
||||
// Triangle strip points
|
||||
// 3 ------ 5
|
||||
// / \
|
||||
// 1 7
|
||||
// | |
|
||||
// 2 8
|
||||
// \ /
|
||||
// 4 ------ 6
|
||||
|
||||
vertex[vertexPoint++] = x;
|
||||
vertex[vertexPoint++] = y + height - bevelDistance;
|
||||
|
||||
// top side
|
||||
vertex[vertexPoint++] = x + bevelDistance;
|
||||
vertex[vertexPoint++] = y + height;
|
||||
// 1
|
||||
vertexBuffer[vertexPoint++] = x;
|
||||
vertexBuffer[vertexPoint++] = y + height - bevelDistance;
|
||||
// 2
|
||||
vertexBuffer[vertexPoint++] = x;
|
||||
vertexBuffer[vertexPoint++] = y + bevelDistance;
|
||||
// 3
|
||||
vertexBuffer[vertexPoint++] = x + bevelDistance;
|
||||
vertexBuffer[vertexPoint++] = y + height;
|
||||
// 4
|
||||
vertexBuffer[vertexPoint++] = x + bevelDistance;
|
||||
vertexBuffer[vertexPoint++] = y;
|
||||
// 5
|
||||
vertexBuffer[vertexPoint++] = x + width - bevelDistance;
|
||||
vertexBuffer[vertexPoint++] = y + height;
|
||||
// 6
|
||||
vertexBuffer[vertexPoint++] = x + width - bevelDistance;
|
||||
vertexBuffer[vertexPoint++] = y;
|
||||
// 7
|
||||
vertexBuffer[vertexPoint++] = x + width;
|
||||
vertexBuffer[vertexPoint++] = y + height - bevelDistance;
|
||||
// 8
|
||||
vertexBuffer[vertexPoint++] = x + width;
|
||||
vertexBuffer[vertexPoint++] = y + bevelDistance;
|
||||
|
||||
vertex[vertexPoint++] = x + width - bevelDistance;
|
||||
vertex[vertexPoint++] = y + height;
|
||||
|
||||
// right
|
||||
vertex[vertexPoint++] = x + width;
|
||||
vertex[vertexPoint++] = y + height - bevelDistance;
|
||||
vertex[vertexPoint++] = x + width;
|
||||
vertex[vertexPoint++] = y + bevelDistance;
|
||||
|
||||
// bottom
|
||||
vertex[vertexPoint++] = x + width - bevelDistance;
|
||||
vertex[vertexPoint++] = y;
|
||||
vertex[vertexPoint++] = x +bevelDistance;
|
||||
vertex[vertexPoint++] = y;
|
||||
|
||||
const int NUM_COLOR_SCALARS_PER_QUAD = 8;
|
||||
int compactColor = ((int(color.x * 255.0f) & 0xFF)) |
|
||||
((int(color.y * 255.0f) & 0xFF) << 8) |
|
||||
((int(color.z * 255.0f) & 0xFF) << 16) |
|
||||
((int(color.w * 255.0f) & 0xFF) << 24);
|
||||
int colors[NUM_COLOR_SCALARS_PER_QUAD] = { compactColor, compactColor, compactColor, compactColor,
|
||||
compactColor, compactColor, compactColor, compactColor };
|
||||
int colors[NUM_VERTICES] = { compactColor, compactColor, compactColor, compactColor,
|
||||
compactColor, compactColor, compactColor, compactColor };
|
||||
|
||||
|
||||
details.verticesBuffer->append(sizeof(vertexBuffer), (gpu::Byte*) vertexBuffer);
|
||||
details.colorBuffer->append(sizeof(colors), (gpu::Byte*) colors);
|
||||
|
||||
delete[] vertexBuffer;
|
||||
}
|
||||
|
||||
batch.setInputFormat(details.streamFormat);
|
||||
batch.setInputStream(0, *details.stream);
|
||||
batch.draw(gpu::QUADS, 4, 0);
|
||||
batch.draw(gpu::TRIANGLE_STRIP, details.vertices, 0);
|
||||
}
|
||||
|
||||
void GeometryCache::renderQuad(const glm::vec2& minCorner, const glm::vec2& maxCorner, const glm::vec4& color, int id) {
|
||||
|
|
|
@ -30,11 +30,6 @@
|
|||
#include "GeometryCache.h"
|
||||
#include "DeferredLightingEffect.h"
|
||||
|
||||
// FIXME support the shadow effect, or remove it from the API
|
||||
// FIXME figure out how to improve the anti-aliasing on the
|
||||
// interior of the outline fonts
|
||||
const float DEFAULT_POINT_SIZE = 12;
|
||||
|
||||
// Helper functions for reading binary data from an IO device
|
||||
template<class T>
|
||||
void readStream(QIODevice& in, T& t) {
|
||||
|
@ -117,7 +112,7 @@ public:
|
|||
|
||||
// Render string to batch
|
||||
void drawString(gpu::Batch& batch, float x, float y, const QString& str,
|
||||
const glm::vec4& color, TextRenderer3D::EffectType effectType,
|
||||
const glm::vec4* color, TextRenderer3D::EffectType effectType,
|
||||
const glm::vec2& bound);
|
||||
|
||||
private:
|
||||
|
@ -367,7 +362,7 @@ void Font3D::setupGPU() {
|
|||
}
|
||||
}
|
||||
|
||||
void Font3D::drawString(gpu::Batch& batch, float x, float y, const QString& str, const glm::vec4& color,
|
||||
void Font3D::drawString(gpu::Batch& batch, float x, float y, const QString& str, const glm::vec4* color,
|
||||
TextRenderer3D::EffectType effectType, const glm::vec2& bounds) {
|
||||
if (str == "") {
|
||||
return;
|
||||
|
@ -429,39 +424,33 @@ void Font3D::drawString(gpu::Batch& batch, float x, float y, const QString& str,
|
|||
setupGPU();
|
||||
batch.setPipeline(_pipeline);
|
||||
batch.setUniformTexture(_fontLoc, _texture);
|
||||
batch._glUniform1f(_outlineLoc, (effectType == TextRenderer3D::OUTLINE_EFFECT) ? 1.0f : 0.0f);
|
||||
batch._glUniform4fv(_colorLoc, 1, (const GLfloat*)&color);
|
||||
batch._glUniform1i(_outlineLoc, (effectType == TextRenderer3D::OUTLINE_EFFECT));
|
||||
batch._glUniform4fv(_colorLoc, 1, (const GLfloat*)color);
|
||||
|
||||
batch.setInputFormat(_format);
|
||||
batch.setInputBuffer(0, _verticesBuffer, 0, _format->getChannels().at(0)._stride);
|
||||
batch.draw(gpu::QUADS, _numVertices, 0);
|
||||
}
|
||||
|
||||
TextRenderer3D* TextRenderer3D::getInstance(const char* family, float pointSize,
|
||||
int weight, bool italic, EffectType effect, int effectThickness,
|
||||
const QColor& color) {
|
||||
if (pointSize < 0) {
|
||||
pointSize = DEFAULT_POINT_SIZE;
|
||||
}
|
||||
return new TextRenderer3D(family, pointSize, weight, italic, effect,
|
||||
effectThickness, color);
|
||||
TextRenderer3D* TextRenderer3D::getInstance(const char* family,
|
||||
int weight, bool italic, EffectType effect, int effectThickness) {
|
||||
return new TextRenderer3D(family, weight, italic, effect, effectThickness);
|
||||
}
|
||||
|
||||
TextRenderer3D::TextRenderer3D(const char* family, float pointSize, int weight, bool italic,
|
||||
EffectType effect, int effectThickness, const QColor& color) :
|
||||
TextRenderer3D::TextRenderer3D(const char* family, int weight, bool italic,
|
||||
EffectType effect, int effectThickness) :
|
||||
_effectType(effect),
|
||||
_effectThickness(effectThickness),
|
||||
_color(toGlm(color)),
|
||||
_font(loadFont3D(family)) {
|
||||
if (!_font) {
|
||||
qWarning() << "Unable to load font with family " << family;
|
||||
_font = loadFont3D("Courier");
|
||||
}
|
||||
if (1 != _effectThickness) {
|
||||
qWarning() << "Effect thickness not current supported";
|
||||
qWarning() << "Effect thickness not currently supported";
|
||||
}
|
||||
if (NO_EFFECT != _effectType && OUTLINE_EFFECT != _effectType) {
|
||||
qWarning() << "Effect thickness not current supported";
|
||||
qWarning() << "Effect type not currently supported";
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -486,11 +475,9 @@ void TextRenderer3D::draw(gpu::Batch& batch, float x, float y, const QString& st
|
|||
const glm::vec2& bounds) {
|
||||
// The font does all the OpenGL work
|
||||
if (_font) {
|
||||
glm::vec4 actualColor(color);
|
||||
if (actualColor.r < 0) {
|
||||
actualColor = _color;
|
||||
}
|
||||
_font->drawString(batch, x, y, str, actualColor, _effectType, bounds);
|
||||
// Cache color so that the pointer stays valid.
|
||||
_color = color;
|
||||
_font->drawString(batch, x, y, str, &_color, _effectType, bounds);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -39,25 +39,24 @@ class Batch;
|
|||
class Font3D;
|
||||
|
||||
// TextRenderer3D is actually a fairly thin wrapper around a Font class
|
||||
// defined in the cpp file.
|
||||
// defined in the cpp file.
|
||||
class TextRenderer3D {
|
||||
public:
|
||||
enum EffectType { NO_EFFECT, SHADOW_EFFECT, OUTLINE_EFFECT };
|
||||
|
||||
static TextRenderer3D* getInstance(const char* family, float pointSize = -1, int weight = -1, bool italic = false,
|
||||
EffectType effect = NO_EFFECT, int effectThickness = 1, const QColor& color = QColor(255, 255, 255));
|
||||
|
||||
static TextRenderer3D* getInstance(const char* family, int weight = -1, bool italic = false,
|
||||
EffectType effect = NO_EFFECT, int effectThickness = 1);
|
||||
~TextRenderer3D();
|
||||
|
||||
glm::vec2 computeExtent(const QString& str) const;
|
||||
float getFontSize() const;
|
||||
float getFontSize() const; // Pixel size
|
||||
|
||||
void draw(gpu::Batch& batch, float x, float y, const QString& str, const glm::vec4& color = glm::vec4(-1.0f),
|
||||
const glm::vec2& bounds = glm::vec2(-1.0f));
|
||||
void draw(gpu::Batch& batch, float x, float y, const QString& str, const glm::vec4& color = glm::vec4(1.0f),
|
||||
const glm::vec2& bounds = glm::vec2(-1.0f));
|
||||
|
||||
private:
|
||||
TextRenderer3D(const char* family, float pointSize = -1, int weight = -1, bool italic = false,
|
||||
EffectType effect = NO_EFFECT, int effectThickness = 1, const QColor& color = QColor(255, 255, 255));
|
||||
TextRenderer3D(const char* family, int weight = -1, bool italic = false,
|
||||
EffectType effect = NO_EFFECT, int effectThickness = 1);
|
||||
|
||||
// the type of effect to apply
|
||||
const EffectType _effectType;
|
||||
|
@ -66,7 +65,7 @@ private:
|
|||
const int _effectThickness;
|
||||
|
||||
// text color
|
||||
const glm::vec4 _color;
|
||||
glm::vec4 _color;
|
||||
|
||||
Font3D* _font;
|
||||
};
|
||||
|
|
|
@ -11,18 +11,21 @@
|
|||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
|
||||
uniform sampler2D Font;
|
||||
uniform float Outline;
|
||||
uniform bool Outline;
|
||||
uniform vec4 Color;
|
||||
|
||||
const float gamma = 2.6;
|
||||
const float smoothing = 100.0;
|
||||
// the interpolated normal
|
||||
varying vec4 interpolatedNormal;
|
||||
|
||||
const float gamma = 2.2;
|
||||
const float smoothing = 64.0;
|
||||
const float interiorCutoff = 0.8;
|
||||
const float outlineExpansion = 0.2;
|
||||
|
||||
void main() {
|
||||
// retrieve signed distance
|
||||
float sdf = texture2D(Font, gl_TexCoord[0].xy).g;
|
||||
if (Outline == 1.0f) {
|
||||
if (Outline) {
|
||||
if (sdf > interiorCutoff) {
|
||||
sdf = 1.0 - sdf;
|
||||
} else {
|
||||
|
@ -31,7 +34,7 @@ void main() {
|
|||
}
|
||||
// perform adaptive anti-aliasing of the edges
|
||||
// The larger we're rendering, the less anti-aliasing we need
|
||||
float s = smoothing * length(fwidth(gl_TexCoord[0]));
|
||||
float s = smoothing * length(fwidth(gl_TexCoord[0].xy));
|
||||
float w = clamp( s, 0.0, 0.5);
|
||||
float a = smoothstep(0.5 - w, 0.5 + w, sdf);
|
||||
|
||||
|
@ -43,5 +46,7 @@ void main() {
|
|||
}
|
||||
|
||||
// final color
|
||||
gl_FragColor = vec4(Color.rgb, a);
|
||||
gl_FragData[0] = vec4(Color.rgb, Color.a * a);
|
||||
gl_FragData[1] = vec4(interpolatedNormal.xyz, 0.0) * 0.5 + vec4(0.5, 0.5, 0.5, 1.0);
|
||||
gl_FragData[2] = vec4(0.0);
|
||||
}
|
|
@ -13,6 +13,9 @@
|
|||
|
||||
<$declareStandardTransform()$>
|
||||
|
||||
// the interpolated normal
|
||||
varying vec4 interpolatedNormal;
|
||||
|
||||
void main() {
|
||||
gl_TexCoord[0] = gl_MultiTexCoord0;
|
||||
|
||||
|
@ -20,4 +23,7 @@ void main() {
|
|||
TransformCamera cam = getTransformCamera();
|
||||
TransformObject obj = getTransformObject();
|
||||
<$transformModelToClipPos(cam, obj, gl_Vertex, gl_Position)$>
|
||||
<$transformModelToEyeDir(cam, obj, gl_Normal, interpolatedNormal.xyz)$>
|
||||
|
||||
interpolatedNormal = vec4(normalize(interpolatedNormal.xyz), 0.0);
|
||||
}
|
|
@ -2,20 +2,9 @@ set(TARGET_NAME shared)
|
|||
|
||||
# use setup_hifi_library macro to setup our project and link appropriate Qt modules
|
||||
# TODO: there isn't really a good reason to have Script linked here - let's get what is requiring it out (RegisteredMetaTypes.cpp)
|
||||
setup_hifi_library(Gui Network OpenGL Script Widgets)
|
||||
|
||||
setup_hifi_opengl()
|
||||
setup_hifi_library(Gui Network Script Widgets)
|
||||
|
||||
add_dependency_external_projects(glm)
|
||||
find_package(GLM REQUIRED)
|
||||
target_include_directories(${TARGET_NAME} PUBLIC ${GLM_INCLUDE_DIRS})
|
||||
|
||||
if (WIN32)
|
||||
add_dependency_external_projects(boostconfig)
|
||||
find_package(BoostConfig REQUIRED)
|
||||
target_include_directories(${TARGET_NAME} PUBLIC ${BOOSTCONFIG_INCLUDE_DIRS})
|
||||
|
||||
add_dependency_external_projects(oglplus)
|
||||
find_package(OGLPLUS REQUIRED)
|
||||
target_include_directories(${TARGET_NAME} PUBLIC ${OGLPLUS_INCLUDE_DIRS})
|
||||
endif()
|
|
@ -29,7 +29,7 @@ inline bool isValidScale(glm::vec3 scale) {
|
|||
}
|
||||
|
||||
inline bool isValidScale(float scale) {
|
||||
bool result = scale != 0.0f;
|
||||
bool result = scale != 0.0f && !glm::isnan(scale) && !glm::isinf(scale);
|
||||
assert(result);
|
||||
return result;
|
||||
}
|
||||
|
@ -323,7 +323,7 @@ inline void Transform::setScale(const Vec3& scale) {
|
|||
}
|
||||
|
||||
inline void Transform::postScale(float scale) {
|
||||
if (isValidScale(scale) || scale == 1.0f) {
|
||||
if (!isValidScale(scale) || scale == 1.0f) {
|
||||
return;
|
||||
}
|
||||
if (isScaling()) {
|
||||
|
|
Loading…
Reference in a new issue