mirror of
https://github.com/Armored-Dragon/overte.git
synced 2025-03-11 16:13:16 +01:00
mirrors on models + text
This commit is contained in:
parent
093cf29778
commit
a630a6f9c9
17 changed files with 142 additions and 54 deletions
|
@ -2479,6 +2479,7 @@ Application::Application(
|
|||
copyViewFrustum(viewFrustum);
|
||||
return viewFrustum.getPosition();
|
||||
});
|
||||
MirrorModeHelpers::setComputeMirrorViewOperator(EntityRenderer::computeMirrorViewOperator);
|
||||
|
||||
DependencyManager::get<UsersScriptingInterface>()->setKickConfirmationOperator([this] (const QUuid& nodeID, unsigned int banFlags) { userKickConfirmation(nodeID, banFlags); });
|
||||
|
||||
|
|
|
@ -1120,7 +1120,7 @@ void Avatar::renderDisplayName(gpu::Batch& batch, const ViewFrustum& view, const
|
|||
batch.setModelTransform(textTransform);
|
||||
{
|
||||
PROFILE_RANGE_BATCH(batch, __FUNCTION__":renderText");
|
||||
displayNameRenderer->draw(batch, text_x, -text_y, glm::vec2(-1.0f), nameUTF8.data(), textColor, true, forward);
|
||||
displayNameRenderer->draw(batch, { nameUTF8.data(), textColor, { text_x, -text_y }, glm::vec2(-1.0f), forward });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -237,7 +237,11 @@ void EntityRenderer::computeMirrorView(ViewFrustum& viewFrustum) const {
|
|||
mirrorMode = _mirrorMode;
|
||||
portalExitID = _portalExitID;
|
||||
});
|
||||
computeMirrorViewOperator(viewFrustum, inPropertiesPosition, inPropertiesRotation, mirrorMode, portalExitID);
|
||||
}
|
||||
|
||||
void EntityRenderer::computeMirrorViewOperator(ViewFrustum& viewFrustum, const glm::vec3& inPropertiesPosition, const glm::quat& inPropertiesRotation,
|
||||
MirrorMode mirrorMode, const QUuid& portalExitID) {
|
||||
glm::mat4 inToWorld = glm::translate(inPropertiesPosition) * glm::mat4_cast(inPropertiesRotation);
|
||||
glm::mat4 worldToIn = glm::inverse(inToWorld);
|
||||
|
||||
|
@ -284,6 +288,7 @@ void EntityRenderer::computeMirrorView(ViewFrustum& viewFrustum) const {
|
|||
glm::vec3 cameraSpacePosition = glm::inverse(view) * glm::vec4(outPropertiesPosition, 1.0f);
|
||||
glm::vec3 cameraSpaceNormal = glm::transpose(view) * (outPropertiesRotation * glm::vec4(0, 0, -1, 0));
|
||||
glm::vec4 clipPlane = glm::vec4(cameraSpaceNormal, -glm::dot(cameraSpaceNormal, cameraSpacePosition));
|
||||
// Make sure we pick the direction facing away from us
|
||||
if (clipPlane.w > 0.0f) {
|
||||
clipPlane *= -1.0f;
|
||||
}
|
||||
|
|
|
@ -76,6 +76,8 @@ public:
|
|||
virtual Item::Bound getBound(RenderArgs* args) override;
|
||||
bool passesZoneOcclusionTest(const std::unordered_set<QUuid>& containingZones) const override;
|
||||
void computeMirrorView(ViewFrustum& viewFrustum) const override;
|
||||
static void computeMirrorViewOperator(ViewFrustum& viewFrustum, const glm::vec3& inPropertiesPosition, const glm::quat& inPropertiesRotation,
|
||||
MirrorMode mirrorMode, const QUuid& portalExitID);
|
||||
|
||||
protected:
|
||||
virtual bool needsRenderUpdateFromEntity() const final { return needsRenderUpdateFromEntity(_entity); }
|
||||
|
|
|
@ -1085,10 +1085,6 @@ void ModelEntityRenderer::setKey(bool didVisualGeometryRequestSucceed, const Mod
|
|||
builder.withSubMetaCulled();
|
||||
}
|
||||
|
||||
if (_mirrorMode == MirrorMode::MIRROR || (_mirrorMode == MirrorMode::PORTAL && !_portalExitID.isNull())) {
|
||||
builder.withMirror();
|
||||
}
|
||||
|
||||
if (didVisualGeometryRequestSucceed) {
|
||||
_itemKey = builder.build();
|
||||
} else {
|
||||
|
|
|
@ -181,7 +181,7 @@ void TextEntityRenderer::doRender(RenderArgs* args) {
|
|||
}
|
||||
|
||||
auto geometryCache = DependencyManager::get<GeometryCache>();
|
||||
if (pipelineType == Pipeline::SIMPLE) {
|
||||
if (pipelineType == Pipeline::SIMPLE || pipelineType == Pipeline::MIRROR) {
|
||||
geometryCache->renderQuad(batch, glm::vec2(-0.5f), glm::vec2(0.5f), backgroundColor, _geometryID);
|
||||
} else {
|
||||
geometryCache->renderQuad(batch, glm::vec2(-0.5f), glm::vec2(0.5f), glm::vec2(0.0f), glm::vec2(1.0f), backgroundColor, _geometryID);
|
||||
|
@ -261,6 +261,10 @@ ItemKey entities::TextPayload::getKey() const {
|
|||
builder.withInvisible();
|
||||
}
|
||||
|
||||
if (textRenderable->_mirrorMode == MirrorMode::MIRROR || (textRenderable->_mirrorMode == MirrorMode::PORTAL && !textRenderable->_portalExitID.isNull())) {
|
||||
builder.withMirror();
|
||||
}
|
||||
|
||||
return builder;
|
||||
}
|
||||
}
|
||||
|
@ -312,6 +316,16 @@ bool entities::TextPayload::passesZoneOcclusionTest(const std::unordered_set<QUu
|
|||
return false;
|
||||
}
|
||||
|
||||
void entities::TextPayload::computeMirrorView(ViewFrustum& viewFrustum) const {
|
||||
auto entityTreeRenderer = DependencyManager::get<EntityTreeRenderer>();
|
||||
if (entityTreeRenderer) {
|
||||
auto renderable = entityTreeRenderer->renderableForEntityId(_entityID);
|
||||
if (renderable) {
|
||||
return renderable->computeMirrorView(viewFrustum);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void entities::TextPayload::render(RenderArgs* args) {
|
||||
PerformanceTimer perfTimer("TextPayload::render");
|
||||
Q_ASSERT(args->_batch);
|
||||
|
@ -336,12 +350,15 @@ void entities::TextPayload::render(RenderArgs* args) {
|
|||
glm::vec3 dimensions;
|
||||
|
||||
glm::vec4 textColor;
|
||||
bool mirror;
|
||||
textRenderable->withReadLock([&] {
|
||||
transform = textRenderable->_renderTransform;
|
||||
dimensions = textRenderable->_dimensions;
|
||||
|
||||
float fadeRatio = textRenderable->_isFading ? Interpolate::calculateFadeRatio(textRenderable->_fadeStartTime) : 1.0f;
|
||||
textColor = glm::vec4(textRenderable->_textColor, fadeRatio * textRenderable->_textAlpha);
|
||||
|
||||
mirror = textRenderable->_mirrorMode == MirrorMode::MIRROR || (textRenderable->_mirrorMode == MirrorMode::PORTAL && !textRenderable->_portalExitID.isNull());
|
||||
});
|
||||
|
||||
bool forward = textRenderable->_renderLayer != RenderLayer::WORLD || args->_renderMethod == render::Args::FORWARD;
|
||||
|
@ -363,9 +380,8 @@ void entities::TextPayload::render(RenderArgs* args) {
|
|||
batch.setModelTransform(transform);
|
||||
|
||||
glm::vec2 bounds = glm::vec2(dimensions.x - (textRenderable->_leftMargin + textRenderable->_rightMargin), dimensions.y - (textRenderable->_topMargin + textRenderable->_bottomMargin));
|
||||
textRenderer->draw(batch, textRenderable->_leftMargin / scale, -textRenderable->_topMargin / scale, bounds / scale, scale,
|
||||
textRenderable->_text, textRenderable->_font, textColor, effectColor, textRenderable->_effectThickness, textRenderable->_effect,
|
||||
textRenderable->_alignment, textRenderable->_unlit, forward);
|
||||
textRenderer->draw(batch, textRenderable->_font, { textRenderable->_text, textColor, effectColor, { textRenderable->_leftMargin / scale, -textRenderable->_topMargin / scale },
|
||||
bounds / scale, scale, textRenderable->_effectThickness, textRenderable->_effect, textRenderable->_alignment, textRenderable->_unlit, forward, mirror });
|
||||
}
|
||||
|
||||
namespace render {
|
||||
|
@ -401,4 +417,10 @@ template <> bool payloadPassesZoneOcclusionTest(const entities::TextPayload::Poi
|
|||
return false;
|
||||
}
|
||||
|
||||
template <> void payloadComputeMirrorView(const entities::TextPayload::Pointer& payload, ViewFrustum& viewFrustum) {
|
||||
if (payload) {
|
||||
payload->computeMirrorView(viewFrustum);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -101,6 +101,7 @@ public:
|
|||
ShapeKey getShapeKey() const;
|
||||
void render(RenderArgs* args);
|
||||
bool passesZoneOcclusionTest(const std::unordered_set<QUuid>& containingZones) const;
|
||||
void computeMirrorView(ViewFrustum& viewFrustum) const;
|
||||
|
||||
protected:
|
||||
QUuid _entityID;
|
||||
|
@ -117,6 +118,7 @@ namespace render {
|
|||
template <> const ShapeKey shapeGetShapeKey(const entities::TextPayload::Pointer& payload);
|
||||
template <> void payloadRender(const entities::TextPayload::Pointer& payload, RenderArgs* args);
|
||||
template <> bool payloadPassesZoneOcclusionTest(const entities::TextPayload::Pointer& payload, const std::unordered_set<QUuid>& containingZones);
|
||||
template <> void payloadComputeMirrorView(const entities::TextPayload::Pointer& payload, ViewFrustum& viewFrustum);
|
||||
}
|
||||
|
||||
#endif // hifi_RenderableTextEntityItem_h
|
||||
|
|
|
@ -221,6 +221,10 @@ void ModelMeshPartPayload::updateKey(const render::ItemKey& key) {
|
|||
builder.withSubMetaCulled();
|
||||
}
|
||||
|
||||
if (_mirrorMode == MirrorMode::MIRROR || (_mirrorMode == MirrorMode::PORTAL && !_portalExitID.isNull())) {
|
||||
builder.withMirror();
|
||||
}
|
||||
|
||||
_itemKey = builder.build();
|
||||
}
|
||||
|
||||
|
@ -349,7 +353,7 @@ void ModelMeshPartPayload::render(RenderArgs* args) {
|
|||
procedural->prepare(batch, transform.getTranslation(), transform.getScale(), transform.getRotation(), _created,
|
||||
ProceduralProgramKey(outColor.a < 1.0f, _shapeKey.isDeformed(), _shapeKey.isDualQuatSkinned()));
|
||||
batch._glColor4f(outColor.r, outColor.g, outColor.b, outColor.a);
|
||||
} else {
|
||||
} else if (!_itemKey.isMirror()) {
|
||||
// apply material properties
|
||||
if (RenderPipelines::bindMaterials(_drawMaterials, batch, args->_renderMode, args->_enableTexturing)) {
|
||||
args->_details._materialSwitches++;
|
||||
|
@ -381,7 +385,9 @@ bool ModelMeshPartPayload::passesZoneOcclusionTest(const std::unordered_set<QUui
|
|||
}
|
||||
|
||||
void ModelMeshPartPayload::computeMirrorView(ViewFrustum& viewFrustum) const {
|
||||
return;
|
||||
Transform transform = _parentTransform;
|
||||
transform = transform.worldTransform(_localTransform);
|
||||
MirrorModeHelpers::computeMirrorView(viewFrustum, transform.getTranslation(), transform.getRotation(), _mirrorMode, _portalExitID);
|
||||
}
|
||||
|
||||
void ModelMeshPartPayload::setBlendshapeBuffer(const std::unordered_map<int, gpu::BufferPointer>& blendshapeBuffers, const QVector<int>& blendedMeshSizes) {
|
||||
|
|
|
@ -1078,9 +1078,11 @@ void Model::setMirrorMode(MirrorMode mirrorMode, const render::ScenePointer& sce
|
|||
}
|
||||
|
||||
render::Transaction transaction;
|
||||
auto renderItemsKey = _renderItemKeyGlobalFlags;
|
||||
for (auto item : _modelMeshRenderItemIDs) {
|
||||
transaction.updateItem<ModelMeshPartPayload>(item, [mirrorMode](ModelMeshPartPayload& data) {
|
||||
transaction.updateItem<ModelMeshPartPayload>(item, [mirrorMode, renderItemsKey](ModelMeshPartPayload& data) {
|
||||
data.setMirrorMode(mirrorMode);
|
||||
data.updateKey(renderItemsKey);
|
||||
});
|
||||
}
|
||||
scene->enqueueTransaction(transaction);
|
||||
|
@ -1096,9 +1098,11 @@ void Model::setPortalExitID(const QUuid& portalExitID, const render::ScenePointe
|
|||
}
|
||||
|
||||
render::Transaction transaction;
|
||||
auto renderItemsKey = _renderItemKeyGlobalFlags;
|
||||
for (auto item : _modelMeshRenderItemIDs) {
|
||||
transaction.updateItem<ModelMeshPartPayload>(item, [portalExitID](ModelMeshPartPayload& data) {
|
||||
transaction.updateItem<ModelMeshPartPayload>(item, [portalExitID, renderItemsKey](ModelMeshPartPayload& data) {
|
||||
data.setPortalExitID(portalExitID);
|
||||
data.updateKey(renderItemsKey);
|
||||
});
|
||||
}
|
||||
scene->enqueueTransaction(transaction);
|
||||
|
|
|
@ -40,21 +40,18 @@ float TextRenderer3D::getFontSize() const {
|
|||
return 0.0f;
|
||||
}
|
||||
|
||||
void TextRenderer3D::draw(gpu::Batch& batch, float x, float y, const glm::vec2& bounds,
|
||||
const QString& str, const glm::vec4& color, bool unlit, bool forward) {
|
||||
void TextRenderer3D::draw(gpu::Batch& batch, const Font::DrawProps& props) {
|
||||
if (_font) {
|
||||
_font->drawString(batch, _drawInfo, str, color, glm::vec3(0.0f), 0, TextEffect::NO_EFFECT, TextAlignment::LEFT, { x, y }, bounds, 1.0f, unlit, forward);
|
||||
_font->drawString(batch, _drawInfo, props);
|
||||
}
|
||||
}
|
||||
|
||||
void TextRenderer3D::draw(gpu::Batch& batch, float x, float y, const glm::vec2& bounds, float scale,
|
||||
const QString& str, const QString& font, const glm::vec4& color, const glm::vec3& effectColor,
|
||||
float effectThickness, TextEffect effect, TextAlignment alignment, bool unlit, bool forward) {
|
||||
void TextRenderer3D::draw(gpu::Batch& batch, const QString& font, const Font::DrawProps& props) {
|
||||
if (font != _family) {
|
||||
_family = font;
|
||||
_font = Font::load(_family);
|
||||
}
|
||||
if (_font) {
|
||||
_font->drawString(batch, _drawInfo, str, color, effectColor, effectThickness, effect, alignment, { x, y }, bounds, scale, unlit, forward);
|
||||
_font->drawString(batch, _drawInfo, props);
|
||||
}
|
||||
}
|
|
@ -26,12 +26,9 @@ public:
|
|||
|
||||
glm::vec2 computeExtent(const QString& str) const;
|
||||
float getFontSize() const; // Pixel size
|
||||
|
||||
void draw(gpu::Batch& batch, float x, float y, const glm::vec2& bounds,
|
||||
const QString& str, const glm::vec4& color, bool unlit, bool forward);
|
||||
void draw(gpu::Batch& batch, float x, float y, const glm::vec2& bounds, float scale,
|
||||
const QString& str, const QString& font, const glm::vec4& color, const glm::vec3& effectColor,
|
||||
float effectThickness, TextEffect effect, TextAlignment alignment, bool unlit, bool forward);
|
||||
|
||||
void draw(gpu::Batch& batch, const Font::DrawProps& props);
|
||||
void draw(gpu::Batch& batch, const QString& font, const Font::DrawProps& props);
|
||||
|
||||
private:
|
||||
TextRenderer3D(const char* family);
|
||||
|
|
|
@ -1 +1 @@
|
|||
DEFINES (translucent unlit:f)/forward
|
||||
DEFINES (translucent unlit:f)/forward mirror:f
|
|
@ -41,6 +41,12 @@ layout(location=RENDER_UTILS_ATTR_TEXCOORD01) in vec4 _texCoord01;
|
|||
#define _texCoord1 _texCoord01.zw
|
||||
layout(location=RENDER_UTILS_ATTR_FADE1) flat in vec4 _glyphBounds; // we're reusing the fade texcoord locations here
|
||||
|
||||
<@if HIFI_USE_MIRROR@>
|
||||
<@include graphics/ShaderConstants.h@>
|
||||
|
||||
LAYOUT(binding=GRAPHICS_TEXTURE_MATERIAL_MIRROR) uniform sampler2D mirrorMap;
|
||||
<@endif@>
|
||||
|
||||
void main() {
|
||||
vec4 color = evalSDFSuperSampled(_texCoord0, _glyphBounds);
|
||||
|
||||
|
@ -51,13 +57,17 @@ void main() {
|
|||
}
|
||||
<@endif@>
|
||||
|
||||
<@if HIFI_USE_MIRROR@>
|
||||
color.rgb = texelFetch(mirrorMap, ivec2(gl_FragCoord.xy), 0).rgb;
|
||||
<@endif@>
|
||||
|
||||
<@if HIFI_USE_UNLIT@>
|
||||
<@if HIFI_USE_TRANSLUCENT or HIFI_USE_FORWARD@>
|
||||
_fragColor0 = vec4(color.rgb * isUnlitEnabled(), color.a);
|
||||
_fragColor0 = vec4(color.rgb * isUnlitEnabled(), 1.0);
|
||||
<@else@>
|
||||
packDeferredFragmentUnlit(
|
||||
normalize(_normalWS),
|
||||
color.a,
|
||||
1.0,
|
||||
color.rgb);
|
||||
<@endif@>
|
||||
<@else@>
|
||||
|
|
|
@ -29,7 +29,7 @@
|
|||
|
||||
static std::mutex fontMutex;
|
||||
|
||||
std::map<std::tuple<bool, bool, bool>, gpu::PipelinePointer> Font::_pipelines;
|
||||
std::map<std::tuple<bool, bool, bool, bool>, gpu::PipelinePointer> Font::_pipelines;
|
||||
gpu::Stream::FormatPointer Font::_format;
|
||||
|
||||
struct TextureVertex {
|
||||
|
@ -277,6 +277,7 @@ void Font::setupGPU() {
|
|||
if (_pipelines.empty()) {
|
||||
using namespace shader::render_utils::program;
|
||||
|
||||
// transparent, unlit, forward
|
||||
static const std::vector<std::tuple<bool, bool, bool, uint32_t>> keys = {
|
||||
std::make_tuple(false, false, false, sdf_text3D), std::make_tuple(true, false, false, sdf_text3D_translucent),
|
||||
std::make_tuple(false, true, false, sdf_text3D_unlit), std::make_tuple(true, true, false, sdf_text3D_translucent_unlit),
|
||||
|
@ -284,18 +285,23 @@ void Font::setupGPU() {
|
|||
std::make_tuple(false, true, true, sdf_text3D_translucent_unlit/*sdf_text3D_unlit_forward*/), std::make_tuple(true, true, true, sdf_text3D_translucent_unlit/*sdf_text3D_translucent_unlit_forward*/)
|
||||
};
|
||||
for (auto& key : keys) {
|
||||
bool transparent = std::get<0>(key);
|
||||
bool unlit = std::get<1>(key);
|
||||
bool forward = std::get<2>(key);
|
||||
|
||||
auto state = std::make_shared<gpu::State>();
|
||||
state->setCullMode(gpu::State::CULL_BACK);
|
||||
state->setDepthTest(true, !std::get<0>(key), gpu::LESS_EQUAL);
|
||||
state->setBlendFunction(std::get<0>(key),
|
||||
state->setDepthTest(true, !transparent, gpu::LESS_EQUAL);
|
||||
state->setBlendFunction(transparent,
|
||||
gpu::State::SRC_ALPHA, gpu::State::BLEND_OP_ADD, gpu::State::INV_SRC_ALPHA,
|
||||
gpu::State::FACTOR_ALPHA, gpu::State::BLEND_OP_ADD, gpu::State::ONE);
|
||||
if (std::get<0>(key)) {
|
||||
if (transparent) {
|
||||
PrepareStencil::testMask(*state);
|
||||
} else {
|
||||
PrepareStencil::testMaskDrawShape(*state);
|
||||
}
|
||||
_pipelines[std::make_tuple(std::get<0>(key), std::get<1>(key), std::get<2>(key))] = gpu::Pipeline::create(gpu::Shader::createProgram(std::get<3>(key)), state);
|
||||
_pipelines[std::make_tuple(transparent, unlit, forward, false)] = gpu::Pipeline::create(gpu::Shader::createProgram(std::get<3>(key)), state);
|
||||
_pipelines[std::make_tuple(transparent, unlit, forward, true)] = gpu::Pipeline::create(gpu::Shader::createProgram(forward ? sdf_text3D_forward_mirror : sdf_text3D_mirror), state);
|
||||
}
|
||||
|
||||
// Sanity checks
|
||||
|
@ -444,32 +450,30 @@ void Font::buildVertices(Font::DrawInfo& drawInfo, const QString& str, const glm
|
|||
}
|
||||
}
|
||||
|
||||
void Font::drawString(gpu::Batch& batch, Font::DrawInfo& drawInfo, const QString& str, const glm::vec4& color,
|
||||
const glm::vec3& effectColor, float effectThickness, TextEffect effect, TextAlignment alignment,
|
||||
const glm::vec2& origin, const glm::vec2& bounds, float scale, bool unlit, bool forward) {
|
||||
if (!_loaded || str == "") {
|
||||
void Font::drawString(gpu::Batch& batch, Font::DrawInfo& drawInfo, const DrawProps& props) {
|
||||
if (!_loaded || props.str == "") {
|
||||
return;
|
||||
}
|
||||
|
||||
int textEffect = (int)effect;
|
||||
int textEffect = (int)props.effect;
|
||||
const int SHADOW_EFFECT = (int)TextEffect::SHADOW_EFFECT;
|
||||
|
||||
// If we're switching to or from shadow effect mode, we need to rebuild the vertices
|
||||
if (str != drawInfo.string || bounds != drawInfo.bounds || origin != drawInfo.origin || alignment != _alignment ||
|
||||
if (props.str != drawInfo.string || props.bounds != drawInfo.bounds || props.origin != drawInfo.origin || props.alignment != _alignment ||
|
||||
(drawInfo.params.effect != textEffect && (textEffect == SHADOW_EFFECT || drawInfo.params.effect == SHADOW_EFFECT)) ||
|
||||
(textEffect == SHADOW_EFFECT && scale != _scale)) {
|
||||
_scale = scale;
|
||||
_alignment = alignment;
|
||||
buildVertices(drawInfo, str, origin, bounds, scale, textEffect == SHADOW_EFFECT, alignment);
|
||||
(textEffect == SHADOW_EFFECT && props.scale != _scale)) {
|
||||
_scale = props.scale;
|
||||
_alignment = props.alignment;
|
||||
buildVertices(drawInfo, props.str, props.origin, props.bounds, props.scale, textEffect == SHADOW_EFFECT, props.alignment);
|
||||
}
|
||||
|
||||
setupGPU();
|
||||
|
||||
if (!drawInfo.paramsBuffer || drawInfo.params.color != color || drawInfo.params.effectColor != effectColor ||
|
||||
drawInfo.params.effectThickness != effectThickness || drawInfo.params.effect != textEffect) {
|
||||
drawInfo.params.color = color;
|
||||
drawInfo.params.effectColor = effectColor;
|
||||
drawInfo.params.effectThickness = effectThickness;
|
||||
if (!drawInfo.paramsBuffer || drawInfo.params.color != props.color || drawInfo.params.effectColor != props.effectColor ||
|
||||
drawInfo.params.effectThickness != props.effectThickness || drawInfo.params.effect != textEffect) {
|
||||
drawInfo.params.color = props.color;
|
||||
drawInfo.params.effectColor = props.effectColor;
|
||||
drawInfo.params.effectThickness = props.effectThickness;
|
||||
drawInfo.params.effect = textEffect;
|
||||
|
||||
// need the gamma corrected color here
|
||||
|
@ -484,7 +488,7 @@ void Font::drawString(gpu::Batch& batch, Font::DrawInfo& drawInfo, const QString
|
|||
drawInfo.paramsBuffer->setSubData(0, sizeof(DrawParams), (const gpu::Byte*)&gpuDrawParams);
|
||||
}
|
||||
|
||||
batch.setPipeline(_pipelines[std::make_tuple(color.a < 1.0f, unlit, forward)]);
|
||||
batch.setPipeline(_pipelines[std::make_tuple(props.color.a < 1.0f, props.unlit, props.forward, props.mirror)]);
|
||||
batch.setInputFormat(_format);
|
||||
batch.setInputBuffer(0, drawInfo.verticesBuffer, 0, _format->getChannels().at(0)._stride);
|
||||
batch.setResourceTexture(render_utils::slot::texture::TextFont, _texture);
|
||||
|
|
|
@ -57,10 +57,30 @@ public:
|
|||
glm::vec2 computeExtent(const QString& str) const;
|
||||
float getFontSize() const { return _fontSize; }
|
||||
|
||||
struct DrawProps {
|
||||
DrawProps(const QString& str, const glm::vec4& color, const glm::vec3& effectColor, const glm::vec2& origin, const glm::vec2& bounds,
|
||||
float scale, float effectThickness, TextEffect effect, TextAlignment alignment, bool unlit, bool forward, bool mirror) :
|
||||
str(str), color(color), effectColor(effectColor), origin(origin), bounds(bounds), scale(scale), effectThickness(effectThickness),
|
||||
effect(effect), alignment(alignment), unlit(unlit), forward(forward), mirror(mirror) {}
|
||||
DrawProps(const QString& str, const glm::vec4& color, const glm::vec2& origin, const glm::vec2& bounds, bool forward) :
|
||||
str(str), color(color), origin(origin), bounds(bounds), forward(forward) {}
|
||||
|
||||
const QString& str;
|
||||
const glm::vec4& color;
|
||||
const glm::vec3& effectColor { glm::vec3(0.0f) };
|
||||
const glm::vec2& origin;
|
||||
const glm::vec2& bounds;
|
||||
float scale { 1.0f };
|
||||
float effectThickness { 0.0f };
|
||||
TextEffect effect { TextEffect::NO_EFFECT };
|
||||
TextAlignment alignment { TextAlignment::LEFT };
|
||||
bool unlit = true;
|
||||
bool forward;
|
||||
bool mirror = false;
|
||||
};
|
||||
|
||||
// Render string to batch
|
||||
void drawString(gpu::Batch& batch, DrawInfo& drawInfo, const QString& str, const glm::vec4& color,
|
||||
const glm::vec3& effectColor, float effectThickness, TextEffect effect, TextAlignment alignment,
|
||||
const glm::vec2& origin, const glm::vec2& bound, float scale, bool unlit, bool forward);
|
||||
void drawString(gpu::Batch& batch, DrawInfo& drawInfo, const DrawProps& props);
|
||||
|
||||
static Pointer load(const QString& family);
|
||||
|
||||
|
@ -105,7 +125,7 @@ private:
|
|||
gpu::TexturePointer _texture;
|
||||
gpu::BufferStreamPointer _stream;
|
||||
|
||||
static std::map<std::tuple<bool, bool, bool>, gpu::PipelinePointer> _pipelines;
|
||||
static std::map<std::tuple<bool, bool, bool, bool>, gpu::PipelinePointer> _pipelines;
|
||||
static gpu::Stream::FormatPointer _format;
|
||||
};
|
||||
|
||||
|
|
|
@ -15,6 +15,8 @@ const char* MirrorModeNames[] = {
|
|||
};
|
||||
|
||||
static const size_t MIRROR_MODE_NAMES = (sizeof(MirrorModeNames) / sizeof(MirrorModeNames[0]));
|
||||
std::function<void(ViewFrustum&, const glm::vec3&, const glm::quat&, MirrorMode, const QUuid&)> MirrorModeHelpers::_computeMirrorViewOperator =
|
||||
[](ViewFrustum&, const glm::vec3&, const glm::quat&, MirrorMode, const QUuid&) { return; };
|
||||
|
||||
QString MirrorModeHelpers::getNameForMirrorMode(MirrorMode mode) {
|
||||
if (((int)mode <= 0) || ((int)mode >= (int)MIRROR_MODE_NAMES)) {
|
||||
|
@ -23,3 +25,12 @@ QString MirrorModeHelpers::getNameForMirrorMode(MirrorMode mode) {
|
|||
|
||||
return MirrorModeNames[(int)mode];
|
||||
}
|
||||
|
||||
void MirrorModeHelpers::setComputeMirrorViewOperator(std::function<void(ViewFrustum&, const glm::vec3&, const glm::quat&, MirrorMode, const QUuid&)> computeMirrorViewOperator) {
|
||||
_computeMirrorViewOperator = computeMirrorViewOperator;
|
||||
}
|
||||
|
||||
void MirrorModeHelpers::computeMirrorView(ViewFrustum& viewFrustum, const glm::vec3& inPropertiesPosition, const glm::quat& inPropertiesRotation,
|
||||
MirrorMode mirrorMode, const QUuid& portalExitID) {
|
||||
_computeMirrorViewOperator(viewFrustum, inPropertiesPosition, inPropertiesRotation, mirrorMode, portalExitID);
|
||||
}
|
|
@ -9,8 +9,12 @@
|
|||
#ifndef hifi_MirrorMode_h
|
||||
#define hifi_MirrorMode_h
|
||||
|
||||
#include <functional>
|
||||
|
||||
#include "QString"
|
||||
|
||||
#include "ViewFrustum.h"
|
||||
|
||||
/*@jsdoc
|
||||
* <p>If an entity is rendered as a mirror, a portal, or normally.</p>
|
||||
* <table>
|
||||
|
@ -35,6 +39,13 @@ enum class MirrorMode {
|
|||
class MirrorModeHelpers {
|
||||
public:
|
||||
static QString getNameForMirrorMode(MirrorMode mode);
|
||||
|
||||
static void setComputeMirrorViewOperator(std::function<void(ViewFrustum&, const glm::vec3&, const glm::quat&, MirrorMode, const QUuid&)> computeMirrorViewOperator);
|
||||
static void computeMirrorView(ViewFrustum& viewFrustum, const glm::vec3& inPropertiesPosition, const glm::quat& inPropertiesRotation,
|
||||
MirrorMode mirrorMode, const QUuid& portalExitID);
|
||||
|
||||
private:
|
||||
static std::function<void(ViewFrustum&, const glm::vec3&, const glm::quat&, MirrorMode, const QUuid&)> _computeMirrorViewOperator;
|
||||
};
|
||||
|
||||
#endif // hifi_MirrorMode_h
|
||||
|
|
Loading…
Reference in a new issue