mirror of
https://github.com/overte-org/overte.git
synced 2025-04-20 03:24:00 +02:00
Merge pull request #7028 from zzmp/fix/overlay
Add transparency and layering for overlays sam is doing it
This commit is contained in:
commit
e61636e8a7
46 changed files with 814 additions and 364 deletions
|
@ -105,7 +105,6 @@ void Circle3DOverlay::render(RenderArgs* args) {
|
|||
auto transform = _transform;
|
||||
transform.postScale(glm::vec3(getDimensions(), 1.0f));
|
||||
batch.setModelTransform(transform);
|
||||
DependencyManager::get<GeometryCache>()->bindSimpleProgram(batch, false, false);
|
||||
|
||||
// for our overlay, is solid means we draw a ring between the inner and outer radius of the circle, otherwise
|
||||
// we just draw a line...
|
||||
|
@ -278,6 +277,14 @@ void Circle3DOverlay::render(RenderArgs* args) {
|
|||
}
|
||||
}
|
||||
|
||||
const render::ShapeKey Circle3DOverlay::getShapeKey() {
|
||||
auto builder = render::ShapeKey::Builder().withoutCullFace();
|
||||
if (getAlpha() != 1.0f) {
|
||||
builder.withTranslucent();
|
||||
}
|
||||
return builder.build();
|
||||
}
|
||||
|
||||
void Circle3DOverlay::setProperties(const QScriptValue &properties) {
|
||||
Planar3DOverlay::setProperties(properties);
|
||||
|
||||
|
|
|
@ -25,6 +25,7 @@ public:
|
|||
Circle3DOverlay(const Circle3DOverlay* circle3DOverlay);
|
||||
|
||||
virtual void render(RenderArgs* args);
|
||||
virtual const render::ShapeKey getShapeKey() override;
|
||||
virtual void setProperties(const QScriptValue& properties);
|
||||
virtual QScriptValue getProperty(const QString& property);
|
||||
|
||||
|
|
|
@ -46,22 +46,17 @@ void Cube3DOverlay::render(RenderArgs* args) {
|
|||
Transform transform;
|
||||
transform.setTranslation(position);
|
||||
transform.setRotation(rotation);
|
||||
if (_isSolid) {
|
||||
// if (_borderSize > 0) {
|
||||
// // Draw a cube at a larger size behind the main cube, creating
|
||||
// // a border effect.
|
||||
// // Disable writing to the depth mask so that the "border" cube will not
|
||||
// // occlude the main cube. This means the border could be covered by
|
||||
// // overlays that are further back and drawn later, but this is good
|
||||
// // enough for the use-case.
|
||||
// transform.setScale(dimensions * _borderSize);
|
||||
// batch->setModelTransform(transform);
|
||||
// DependencyManager::get<GeometryCache>()->renderSolidCube(*batch, 1.0f, glm::vec4(1.0f, 1.0f, 1.0f, alpha));
|
||||
// }
|
||||
|
||||
auto geometryCache = DependencyManager::get<GeometryCache>();
|
||||
auto pipeline = args->_pipeline;
|
||||
if (!pipeline) {
|
||||
pipeline = geometryCache->getShapePipeline();
|
||||
}
|
||||
|
||||
if (_isSolid) {
|
||||
transform.setScale(dimensions);
|
||||
batch->setModelTransform(transform);
|
||||
DependencyManager::get<GeometryCache>()->renderSolidCubeInstance(*batch, cubeColor);
|
||||
geometryCache->renderSolidCubeInstance(*batch, cubeColor, pipeline);
|
||||
} else {
|
||||
|
||||
if (getIsDashedLine()) {
|
||||
|
@ -79,8 +74,6 @@ void Cube3DOverlay::render(RenderArgs* args) {
|
|||
glm::vec3 topLeftFar(-halfDimensions.x, halfDimensions.y, halfDimensions.z);
|
||||
glm::vec3 topRightFar(halfDimensions.x, halfDimensions.y, halfDimensions.z);
|
||||
|
||||
auto geometryCache = DependencyManager::get<GeometryCache>();
|
||||
|
||||
geometryCache->renderDashedLine(*batch, bottomLeftNear, bottomRightNear, cubeColor);
|
||||
geometryCache->renderDashedLine(*batch, bottomRightNear, bottomRightFar, cubeColor);
|
||||
geometryCache->renderDashedLine(*batch, bottomRightFar, bottomLeftFar, cubeColor);
|
||||
|
@ -99,12 +92,20 @@ void Cube3DOverlay::render(RenderArgs* args) {
|
|||
} else {
|
||||
transform.setScale(dimensions);
|
||||
batch->setModelTransform(transform);
|
||||
DependencyManager::get<GeometryCache>()->renderWireCubeInstance(*batch, cubeColor);
|
||||
geometryCache->renderWireCubeInstance(*batch, cubeColor, pipeline);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const render::ShapeKey Cube3DOverlay::getShapeKey() {
|
||||
auto builder = render::ShapeKey::Builder();
|
||||
if (getAlpha() != 1.0f) {
|
||||
builder.withTranslucent();
|
||||
}
|
||||
return builder.build();
|
||||
}
|
||||
|
||||
Cube3DOverlay* Cube3DOverlay::createClone() const {
|
||||
return new Cube3DOverlay(this);
|
||||
}
|
||||
|
|
|
@ -24,6 +24,7 @@ public:
|
|||
Cube3DOverlay(const Cube3DOverlay* cube3DOverlay);
|
||||
|
||||
virtual void render(RenderArgs* args);
|
||||
virtual const render::ShapeKey getShapeKey() override;
|
||||
|
||||
virtual Cube3DOverlay* createClone() const;
|
||||
|
||||
|
|
|
@ -93,6 +93,14 @@ void Grid3DOverlay::render(RenderArgs* args) {
|
|||
}
|
||||
}
|
||||
|
||||
const render::ShapeKey Grid3DOverlay::getShapeKey() {
|
||||
auto builder = render::ShapeKey::Builder();
|
||||
if (getAlpha() != 1.0f) {
|
||||
builder.withTranslucent();
|
||||
}
|
||||
return builder.build();
|
||||
}
|
||||
|
||||
void Grid3DOverlay::setProperties(const QScriptValue& properties) {
|
||||
Planar3DOverlay::setProperties(properties);
|
||||
|
||||
|
|
|
@ -25,6 +25,7 @@ public:
|
|||
Grid3DOverlay(const Grid3DOverlay* grid3DOverlay);
|
||||
|
||||
virtual void render(RenderArgs* args);
|
||||
virtual const render::ShapeKey getShapeKey() override;
|
||||
virtual void setProperties(const QScriptValue& properties);
|
||||
virtual QScriptValue getProperty(const QString& property);
|
||||
|
||||
|
|
|
@ -95,7 +95,6 @@ void Image3DOverlay::render(RenderArgs* args) {
|
|||
batch->setModelTransform(transform);
|
||||
batch->setResourceTexture(0, _texture->getGPUTexture());
|
||||
|
||||
DependencyManager::get<GeometryCache>()->bindSimpleProgram(*batch, true, false, _emissive, true);
|
||||
DependencyManager::get<GeometryCache>()->renderQuad(
|
||||
*batch, topLeft, bottomRight, texCoordTopLeft, texCoordBottomRight,
|
||||
glm::vec4(color.red / MAX_COLOR, color.green / MAX_COLOR, color.blue / MAX_COLOR, alpha)
|
||||
|
@ -104,6 +103,17 @@ void Image3DOverlay::render(RenderArgs* args) {
|
|||
batch->setResourceTexture(0, args->_whiteTexture); // restore default white color after me
|
||||
}
|
||||
|
||||
const render::ShapeKey Image3DOverlay::getShapeKey() {
|
||||
auto builder = render::ShapeKey::Builder().withoutCullFace().withDepthBias();
|
||||
if (_emissive) {
|
||||
builder.withEmissive();
|
||||
}
|
||||
if (getAlpha() != 1.0f) {
|
||||
builder.withTranslucent();
|
||||
}
|
||||
return builder.build();
|
||||
}
|
||||
|
||||
void Image3DOverlay::setProperties(const QScriptValue &properties) {
|
||||
Billboard3DOverlay::setProperties(properties);
|
||||
|
||||
|
|
|
@ -31,6 +31,8 @@ public:
|
|||
|
||||
virtual void update(float deltatime);
|
||||
|
||||
virtual const render::ShapeKey getShapeKey() override;
|
||||
|
||||
// setters
|
||||
void setURL(const QString& url);
|
||||
void setClipFromSource(const QRect& bounds) { _fromImage = bounds; }
|
||||
|
|
|
@ -53,7 +53,6 @@ void Line3DOverlay::render(RenderArgs* args) {
|
|||
auto batch = args->_batch;
|
||||
if (batch) {
|
||||
batch->setModelTransform(_transform);
|
||||
DependencyManager::get<GeometryCache>()->bindSimpleProgram(*batch);
|
||||
|
||||
if (getIsDashedLine()) {
|
||||
// TODO: add support for color to renderDashedLine()
|
||||
|
@ -64,6 +63,14 @@ void Line3DOverlay::render(RenderArgs* args) {
|
|||
}
|
||||
}
|
||||
|
||||
const render::ShapeKey Line3DOverlay::getShapeKey() {
|
||||
auto builder = render::ShapeKey::Builder();
|
||||
if (getAlpha() != 1.0f) {
|
||||
builder.withTranslucent();
|
||||
}
|
||||
return builder.build();
|
||||
}
|
||||
|
||||
void Line3DOverlay::setProperties(const QScriptValue& properties) {
|
||||
Base3DOverlay::setProperties(properties);
|
||||
|
||||
|
|
|
@ -24,6 +24,7 @@ public:
|
|||
Line3DOverlay(const Line3DOverlay* line3DOverlay);
|
||||
~Line3DOverlay();
|
||||
virtual void render(RenderArgs* args);
|
||||
virtual const render::ShapeKey getShapeKey() override;
|
||||
virtual AABox getBounds() const;
|
||||
|
||||
// getters
|
||||
|
|
|
@ -44,6 +44,8 @@ public:
|
|||
virtual bool addToScene(Overlay::Pointer overlay, std::shared_ptr<render::Scene> scene, render::PendingChanges& pendingChanges);
|
||||
virtual void removeFromScene(Overlay::Pointer overlay, std::shared_ptr<render::Scene> scene, render::PendingChanges& pendingChanges);
|
||||
|
||||
virtual const render::ShapeKey getShapeKey() { return render::ShapeKey::Builder::ownPipeline(); }
|
||||
|
||||
// getters
|
||||
virtual QString getType() const = 0;
|
||||
virtual bool is3D() const = 0;
|
||||
|
@ -119,6 +121,7 @@ namespace render {
|
|||
template <> const Item::Bound payloadGetBound(const Overlay::Pointer& overlay);
|
||||
template <> int payloadGetLayer(const Overlay::Pointer& overlay);
|
||||
template <> void payloadRender(const Overlay::Pointer& overlay, RenderArgs* args);
|
||||
template <> const ShapeKey shapeGetShapeKey(const Overlay::Pointer& overlay);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -35,15 +35,18 @@
|
|||
|
||||
namespace render {
|
||||
template <> const ItemKey payloadGetKey(const Overlay::Pointer& overlay) {
|
||||
auto builder = ItemKey::Builder().withTypeShape();
|
||||
if (overlay->is3D() && !std::dynamic_pointer_cast<Base3DOverlay>(overlay)->getDrawOnHUD()) {
|
||||
if (std::dynamic_pointer_cast<Base3DOverlay>(overlay)->getDrawInFront()) {
|
||||
return ItemKey::Builder().withTypeShape().withLayered().build();
|
||||
} else {
|
||||
return ItemKey::Builder::opaqueShape();
|
||||
builder.withLayered();
|
||||
}
|
||||
if (overlay->getAlpha() != 1.0f) {
|
||||
builder.withTransparent();
|
||||
}
|
||||
} else {
|
||||
return ItemKey::Builder().withTypeShape().withViewSpace().build();
|
||||
builder.withViewSpace();
|
||||
}
|
||||
return builder.build();
|
||||
}
|
||||
template <> const Item::Bound payloadGetBound(const Overlay::Pointer& overlay) {
|
||||
return overlay->getBounds();
|
||||
|
@ -80,4 +83,7 @@ namespace render {
|
|||
}
|
||||
}
|
||||
}
|
||||
template <> const ShapeKey shapeGetShapeKey(const Overlay::Pointer& overlay) {
|
||||
return overlay->getShapeKey();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -88,6 +88,14 @@ void Rectangle3DOverlay::render(RenderArgs* args) {
|
|||
}
|
||||
}
|
||||
|
||||
const render::ShapeKey Rectangle3DOverlay::getShapeKey() {
|
||||
auto builder = render::ShapeKey::Builder();
|
||||
if (getAlpha() != 1.0f) {
|
||||
builder.withTranslucent();
|
||||
}
|
||||
return builder.build();
|
||||
}
|
||||
|
||||
void Rectangle3DOverlay::setProperties(const QScriptValue &properties) {
|
||||
Planar3DOverlay::setProperties(properties);
|
||||
}
|
||||
|
|
|
@ -24,6 +24,7 @@ public:
|
|||
Rectangle3DOverlay(const Rectangle3DOverlay* rectangle3DOverlay);
|
||||
~Rectangle3DOverlay();
|
||||
virtual void render(RenderArgs* args);
|
||||
virtual const render::ShapeKey getShapeKey() override;
|
||||
virtual void setProperties(const QScriptValue& properties);
|
||||
|
||||
virtual Rectangle3DOverlay* createClone() const;
|
||||
|
|
|
@ -42,14 +42,29 @@ void Sphere3DOverlay::render(RenderArgs* args) {
|
|||
Transform transform = _transform;
|
||||
transform.postScale(getDimensions() * SPHERE_OVERLAY_SCALE);
|
||||
batch->setModelTransform(transform);
|
||||
|
||||
auto geometryCache = DependencyManager::get<GeometryCache>();
|
||||
auto pipeline = args->_pipeline;
|
||||
if (!pipeline) {
|
||||
pipeline = geometryCache->getShapePipeline();
|
||||
}
|
||||
|
||||
if (_isSolid) {
|
||||
DependencyManager::get<GeometryCache>()->renderSolidSphereInstance(*batch, sphereColor);
|
||||
geometryCache->renderSolidSphereInstance(*batch, sphereColor, pipeline);
|
||||
} else {
|
||||
DependencyManager::get<GeometryCache>()->renderWireSphereInstance(*batch, sphereColor);
|
||||
geometryCache->renderWireSphereInstance(*batch, sphereColor, pipeline);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const render::ShapeKey Sphere3DOverlay::getShapeKey() {
|
||||
auto builder = render::ShapeKey::Builder();
|
||||
if (getAlpha() != 1.0f) {
|
||||
builder.withTranslucent();
|
||||
}
|
||||
return builder.build();
|
||||
}
|
||||
|
||||
Sphere3DOverlay* Sphere3DOverlay::createClone() const {
|
||||
return new Sphere3DOverlay(this);
|
||||
}
|
||||
|
|
|
@ -24,6 +24,7 @@ public:
|
|||
Sphere3DOverlay(const Sphere3DOverlay* Sphere3DOverlay);
|
||||
|
||||
virtual void render(RenderArgs* args);
|
||||
virtual const render::ShapeKey getShapeKey() override;
|
||||
|
||||
virtual Sphere3DOverlay* createClone() const;
|
||||
};
|
||||
|
|
|
@ -8,8 +8,10 @@
|
|||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
|
||||
#include "Text3DOverlay.h"
|
||||
|
||||
#include <TextureCache.h>
|
||||
#include <GeometryCache.h>
|
||||
#include <RegisteredMetaTypes.h>
|
||||
#include <RenderDeferredTask.h>
|
||||
|
@ -34,6 +36,7 @@ Text3DOverlay::Text3DOverlay() :
|
|||
_bottomMargin(DEFAULT_MARGIN)
|
||||
{
|
||||
_textRenderer = TextRenderer3D::getInstance(SANS_FONT_FAMILY, FIXED_FONT_POINT_SIZE);
|
||||
_alpha = _backgroundAlpha;
|
||||
}
|
||||
|
||||
Text3DOverlay::Text3DOverlay(const Text3DOverlay* text3DOverlay) :
|
||||
|
@ -47,7 +50,8 @@ Text3DOverlay::Text3DOverlay(const Text3DOverlay* text3DOverlay) :
|
|||
_rightMargin(text3DOverlay->_rightMargin),
|
||||
_bottomMargin(text3DOverlay->_bottomMargin)
|
||||
{
|
||||
_textRenderer = TextRenderer3D::getInstance(SANS_FONT_FAMILY, FIXED_FONT_POINT_SIZE);
|
||||
_textRenderer = TextRenderer3D::getInstance(SANS_FONT_FAMILY, FIXED_FONT_POINT_SIZE);
|
||||
_alpha = _backgroundAlpha;
|
||||
}
|
||||
|
||||
Text3DOverlay::~Text3DOverlay() {
|
||||
|
@ -100,7 +104,6 @@ void Text3DOverlay::render(RenderArgs* args) {
|
|||
|
||||
glm::vec3 topLeft(-halfDimensions.x, -halfDimensions.y, SLIGHTLY_BEHIND);
|
||||
glm::vec3 bottomRight(halfDimensions.x, halfDimensions.y, SLIGHTLY_BEHIND);
|
||||
DependencyManager::get<GeometryCache>()->bindSimpleProgram(batch, false, true, false, true);
|
||||
DependencyManager::get<GeometryCache>()->renderQuad(batch, topLeft, bottomRight, quadColor);
|
||||
|
||||
// Same font properties as textSize()
|
||||
|
@ -120,7 +123,15 @@ void Text3DOverlay::render(RenderArgs* args) {
|
|||
|
||||
glm::vec4 textColor = { _color.red / MAX_COLOR, _color.green / MAX_COLOR,
|
||||
_color.blue / MAX_COLOR, getAlpha() };
|
||||
_textRenderer->draw(batch, 0, 0, _text, textColor);
|
||||
_textRenderer->draw(batch, 0, 0, _text, textColor, glm::vec2(-1.0f), getDrawInFront());
|
||||
}
|
||||
|
||||
const render::ShapeKey Text3DOverlay::getShapeKey() {
|
||||
auto builder = render::ShapeKey::Builder();
|
||||
if (getAlpha() != 1.0f) {
|
||||
builder.withTranslucent();
|
||||
}
|
||||
return builder.build();
|
||||
}
|
||||
|
||||
void Text3DOverlay::setProperties(const QScriptValue& properties) {
|
||||
|
@ -145,6 +156,7 @@ void Text3DOverlay::setProperties(const QScriptValue& properties) {
|
|||
|
||||
if (properties.property("backgroundAlpha").isValid()) {
|
||||
_backgroundAlpha = properties.property("backgroundAlpha").toVariant().toFloat();
|
||||
_alpha = _backgroundAlpha;
|
||||
}
|
||||
|
||||
if (properties.property("lineHeight").isValid()) {
|
||||
|
|
|
@ -31,6 +31,8 @@ public:
|
|||
|
||||
virtual void update(float deltatime);
|
||||
|
||||
virtual const render::ShapeKey getShapeKey() override;
|
||||
|
||||
// getters
|
||||
const QString& getText() const { return _text; }
|
||||
float getLineHeight() const { return _lineHeight; }
|
||||
|
@ -72,5 +74,4 @@ private:
|
|||
float _bottomMargin;
|
||||
};
|
||||
|
||||
|
||||
#endif // hifi_Text3DOverlay_h
|
||||
|
|
|
@ -34,7 +34,7 @@ public:
|
|||
|
||||
protected:
|
||||
// Centered local bounding box
|
||||
AABox _localBoundingBox;
|
||||
AABox _localBoundingBox{ vec3(0.0f), 1.0f };
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -101,11 +101,18 @@ void Web3DOverlay::render(RenderArgs* args) {
|
|||
}
|
||||
|
||||
batch.setModelTransform(transform);
|
||||
DependencyManager::get<GeometryCache>()->bindSimpleProgram(batch, true, false, false, true);
|
||||
DependencyManager::get<GeometryCache>()->renderQuad(batch, halfSize * -1.0f, halfSize, vec2(0), vec2(1), color);
|
||||
batch.setResourceTexture(0, args->_whiteTexture); // restore default white color after me
|
||||
}
|
||||
|
||||
const render::ShapeKey Web3DOverlay::getShapeKey() {
|
||||
auto builder = render::ShapeKey::Builder().withoutCullFace().withDepthBias();
|
||||
if (getAlpha() != 1.0f) {
|
||||
builder.withTranslucent();
|
||||
}
|
||||
return builder.build();
|
||||
}
|
||||
|
||||
void Web3DOverlay::setProperties(const QScriptValue &properties) {
|
||||
Billboard3DOverlay::setProperties(properties);
|
||||
|
||||
|
|
|
@ -25,6 +25,7 @@ public:
|
|||
virtual ~Web3DOverlay();
|
||||
|
||||
virtual void render(RenderArgs* args);
|
||||
virtual const render::ShapeKey getShapeKey() override;
|
||||
|
||||
virtual void update(float deltatime);
|
||||
|
||||
|
|
|
@ -511,9 +511,10 @@ void DeferredLightingEffect::render(const render::RenderContextPointer& renderCo
|
|||
}
|
||||
}
|
||||
|
||||
void DeferredLightingEffect::setupTransparent(RenderArgs* args, int lightBufferUnit) {
|
||||
void DeferredLightingEffect::setupBatch(gpu::Batch& batch, int lightBufferUnit) {
|
||||
PerformanceTimer perfTimer("DLE->setupBatch()");
|
||||
auto globalLight = _allocatedLights[_globalLights.front()];
|
||||
args->_batch->setUniformBuffer(lightBufferUnit, globalLight->getSchemaBuffer());
|
||||
batch.setUniformBuffer(lightBufferUnit, globalLight->getSchemaBuffer());
|
||||
}
|
||||
|
||||
static void loadLightProgram(const char* vertSource, const char* fragSource, bool lightVolume, gpu::PipelinePointer& pipeline, LightLocationsPtr& locations) {
|
||||
|
|
|
@ -46,7 +46,7 @@ public:
|
|||
void prepare(RenderArgs* args);
|
||||
void render(const render::RenderContextPointer& renderContext);
|
||||
|
||||
void setupTransparent(RenderArgs* args, int lightBufferUnit);
|
||||
void setupBatch(gpu::Batch& batch, int lightBufferUnit);
|
||||
|
||||
// update global lighting
|
||||
void setAmbientLightMode(int preset);
|
||||
|
|
|
@ -494,10 +494,22 @@ gpu::Stream::FormatPointer& getInstancedSolidStreamFormat() {
|
|||
return INSTANCED_SOLID_STREAM_FORMAT;
|
||||
}
|
||||
|
||||
render::ShapePipelinePointer GeometryCache::_simplePipeline;
|
||||
|
||||
GeometryCache::GeometryCache() :
|
||||
_nextID(0)
|
||||
{
|
||||
buildShapes();
|
||||
GeometryCache::_simplePipeline =
|
||||
std::make_shared<render::ShapePipeline>(getSimplePipeline(), nullptr,
|
||||
[](const render::ShapePipeline&, gpu::Batch& batch) {
|
||||
// Set the defaults needed for a simple program
|
||||
batch.setResourceTexture(render::ShapePipeline::Slot::DIFFUSE_MAP,
|
||||
DependencyManager::get<TextureCache>()->getWhiteTexture());
|
||||
batch.setResourceTexture(render::ShapePipeline::Slot::NORMAL_FITTING_MAP,
|
||||
DependencyManager::get<TextureCache>()->getNormalFittingTexture());
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
GeometryCache::~GeometryCache() {
|
||||
|
@ -536,14 +548,6 @@ void GeometryCache::renderWireShapeInstances(gpu::Batch& batch, Shape shape, siz
|
|||
_shapes[shape].drawWireInstances(batch, count);
|
||||
}
|
||||
|
||||
void GeometryCache::renderCubeInstances(gpu::Batch& batch, size_t count, gpu::BufferPointer colorBuffer) {
|
||||
renderShapeInstances(batch, Cube, count, colorBuffer);
|
||||
}
|
||||
|
||||
void GeometryCache::renderWireCubeInstances(gpu::Batch& batch, size_t count, gpu::BufferPointer colorBuffer) {
|
||||
renderWireShapeInstances(batch, Cube, count, colorBuffer);
|
||||
}
|
||||
|
||||
void GeometryCache::renderCube(gpu::Batch& batch) {
|
||||
renderShape(batch, Cube);
|
||||
}
|
||||
|
@ -552,10 +556,6 @@ void GeometryCache::renderWireCube(gpu::Batch& batch) {
|
|||
renderWireShape(batch, Cube);
|
||||
}
|
||||
|
||||
void GeometryCache::renderSphereInstances(gpu::Batch& batch, size_t count, gpu::BufferPointer colorBuffer) {
|
||||
renderShapeInstances(batch, Sphere, count, colorBuffer);
|
||||
}
|
||||
|
||||
void GeometryCache::renderSphere(gpu::Batch& batch) {
|
||||
renderShape(batch, Sphere);
|
||||
}
|
||||
|
@ -756,7 +756,9 @@ void GeometryCache::updateVertices(int id, const QVector<glm::vec2>& points, con
|
|||
#endif // def WANT_DEBUG
|
||||
}
|
||||
|
||||
const int FLOATS_PER_VERTEX = 2;
|
||||
const int FLOATS_PER_VERTEX = 2 + 3; // vertices + normals
|
||||
const int NUM_POS_COORDS = 2;
|
||||
const int VERTEX_NORMAL_OFFSET = NUM_POS_COORDS * sizeof(float);
|
||||
details.isCreated = true;
|
||||
details.vertices = points.size();
|
||||
details.vertexSize = FLOATS_PER_VERTEX;
|
||||
|
@ -772,6 +774,7 @@ void GeometryCache::updateVertices(int id, const QVector<glm::vec2>& points, con
|
|||
details.stream = stream;
|
||||
|
||||
details.streamFormat->setAttribute(gpu::Stream::POSITION, 0, gpu::Element(gpu::VEC2, gpu::FLOAT, gpu::XYZ), 0);
|
||||
details.streamFormat->setAttribute(gpu::Stream::NORMAL, 0, gpu::Element(gpu::VEC3, gpu::FLOAT, gpu::XYZ), VERTEX_NORMAL_OFFSET);
|
||||
details.streamFormat->setAttribute(gpu::Stream::COLOR, 1, gpu::Element(gpu::VEC4, gpu::NUINT8, gpu::RGBA));
|
||||
|
||||
details.stream->addBuffer(details.verticesBuffer, 0, details.streamFormat->getChannels().at(0)._stride);
|
||||
|
@ -791,9 +794,13 @@ void GeometryCache::updateVertices(int id, const QVector<glm::vec2>& points, con
|
|||
int* colorData = new int[details.vertices];
|
||||
int* colorDataAt = colorData;
|
||||
|
||||
const glm::vec3 NORMAL(0.0f, 0.0f, 1.0f);
|
||||
foreach (const glm::vec2& point, points) {
|
||||
*(vertex++) = point.x;
|
||||
*(vertex++) = point.y;
|
||||
*(vertex++) = NORMAL.x;
|
||||
*(vertex++) = NORMAL.y;
|
||||
*(vertex++) = NORMAL.z;
|
||||
|
||||
*(colorDataAt++) = compactColor;
|
||||
}
|
||||
|
@ -817,7 +824,9 @@ void GeometryCache::updateVertices(int id, const QVector<glm::vec3>& points, con
|
|||
#endif // def WANT_DEBUG
|
||||
}
|
||||
|
||||
const int FLOATS_PER_VERTEX = 3;
|
||||
const int FLOATS_PER_VERTEX = 3 + 3; // vertices + normals
|
||||
const int NUM_POS_COORDS = 3;
|
||||
const int VERTEX_NORMAL_OFFSET = NUM_POS_COORDS * sizeof(float);
|
||||
details.isCreated = true;
|
||||
details.vertices = points.size();
|
||||
details.vertexSize = FLOATS_PER_VERTEX;
|
||||
|
@ -833,6 +842,7 @@ void GeometryCache::updateVertices(int id, const QVector<glm::vec3>& points, con
|
|||
details.stream = stream;
|
||||
|
||||
details.streamFormat->setAttribute(gpu::Stream::POSITION, 0, gpu::Element(gpu::VEC3, gpu::FLOAT, gpu::XYZ), 0);
|
||||
details.streamFormat->setAttribute(gpu::Stream::NORMAL, 0, gpu::Element(gpu::VEC3, gpu::FLOAT, gpu::XYZ), VERTEX_NORMAL_OFFSET);
|
||||
details.streamFormat->setAttribute(gpu::Stream::COLOR, 1, gpu::Element(gpu::VEC4, gpu::NUINT8, gpu::RGBA));
|
||||
|
||||
details.stream->addBuffer(details.verticesBuffer, 0, details.streamFormat->getChannels().at(0)._stride);
|
||||
|
@ -852,10 +862,14 @@ void GeometryCache::updateVertices(int id, const QVector<glm::vec3>& points, con
|
|||
int* colorData = new int[details.vertices];
|
||||
int* colorDataAt = colorData;
|
||||
|
||||
const glm::vec3 NORMAL(0.0f, 0.0f, 1.0f);
|
||||
foreach (const glm::vec3& point, points) {
|
||||
*(vertex++) = point.x;
|
||||
*(vertex++) = point.y;
|
||||
*(vertex++) = point.z;
|
||||
*(vertex++) = NORMAL.x;
|
||||
*(vertex++) = NORMAL.y;
|
||||
*(vertex++) = NORMAL.z;
|
||||
|
||||
*(colorDataAt++) = compactColor;
|
||||
}
|
||||
|
@ -880,7 +894,11 @@ void GeometryCache::updateVertices(int id, const QVector<glm::vec3>& points, con
|
|||
#endif // def WANT_DEBUG
|
||||
}
|
||||
|
||||
const int FLOATS_PER_VERTEX = 5;
|
||||
const int FLOATS_PER_VERTEX = 3 + 3 + 2; // vertices + normals + tex coords
|
||||
const int NUM_POS_COORDS = 3;
|
||||
const int NUM_NORMAL_COORDS = 3;
|
||||
const int VERTEX_NORMAL_OFFSET = NUM_POS_COORDS * sizeof(float);
|
||||
const int VERTEX_TEX_OFFSET = VERTEX_NORMAL_OFFSET + NUM_NORMAL_COORDS * sizeof(float);
|
||||
details.isCreated = true;
|
||||
details.vertices = points.size();
|
||||
details.vertexSize = FLOATS_PER_VERTEX;
|
||||
|
@ -896,7 +914,8 @@ void GeometryCache::updateVertices(int id, const QVector<glm::vec3>& points, con
|
|||
details.stream = stream;
|
||||
|
||||
details.streamFormat->setAttribute(gpu::Stream::POSITION, 0, gpu::Element(gpu::VEC3, gpu::FLOAT, gpu::XYZ), 0);
|
||||
details.streamFormat->setAttribute(gpu::Stream::TEXCOORD, 0, gpu::Element(gpu::VEC2, gpu::FLOAT, gpu::UV), 3 * sizeof(float));
|
||||
details.streamFormat->setAttribute(gpu::Stream::NORMAL, 0, gpu::Element(gpu::VEC3, gpu::FLOAT, gpu::XYZ), VERTEX_NORMAL_OFFSET);
|
||||
details.streamFormat->setAttribute(gpu::Stream::TEXCOORD, 0, gpu::Element(gpu::VEC2, gpu::FLOAT, gpu::UV), VERTEX_TEX_OFFSET);
|
||||
details.streamFormat->setAttribute(gpu::Stream::COLOR, 1, gpu::Element(gpu::VEC4, gpu::NUINT8, gpu::RGBA));
|
||||
|
||||
details.stream->addBuffer(details.verticesBuffer, 0, details.streamFormat->getChannels().at(0)._stride);
|
||||
|
@ -918,12 +937,16 @@ void GeometryCache::updateVertices(int id, const QVector<glm::vec3>& points, con
|
|||
int* colorData = new int[details.vertices];
|
||||
int* colorDataAt = colorData;
|
||||
|
||||
const glm::vec3 NORMAL(0.0f, 0.0f, 1.0f);
|
||||
for (int i = 0; i < points.size(); i++) {
|
||||
glm::vec3 point = points[i];
|
||||
glm::vec2 texCoord = texCoords[i];
|
||||
*(vertex++) = point.x;
|
||||
*(vertex++) = point.y;
|
||||
*(vertex++) = point.z;
|
||||
*(vertex++) = NORMAL.x;
|
||||
*(vertex++) = NORMAL.y;
|
||||
*(vertex++) = NORMAL.z;
|
||||
*(vertex++) = texCoord.x;
|
||||
*(vertex++) = texCoord.y;
|
||||
|
||||
|
@ -1073,8 +1096,10 @@ void GeometryCache::renderQuad(gpu::Batch& batch, const glm::vec2& minCorner, co
|
|||
#endif // def WANT_DEBUG
|
||||
}
|
||||
|
||||
const int FLOATS_PER_VERTEX = 2; // vertices
|
||||
const int FLOATS_PER_VERTEX = 2 + 3; // vertices + normals
|
||||
const int VERTICES = 4; // 1 quad = 4 vertices
|
||||
const int NUM_POS_COORDS = 2;
|
||||
const int VERTEX_NORMAL_OFFSET = NUM_POS_COORDS * sizeof(float);
|
||||
|
||||
if (!details.isCreated) {
|
||||
|
||||
|
@ -1093,17 +1118,19 @@ void GeometryCache::renderQuad(gpu::Batch& batch, const glm::vec2& minCorner, co
|
|||
details.stream = stream;
|
||||
|
||||
details.streamFormat->setAttribute(gpu::Stream::POSITION, 0, gpu::Element(gpu::VEC2, gpu::FLOAT, gpu::XYZ), 0);
|
||||
details.streamFormat->setAttribute(gpu::Stream::NORMAL, 0, gpu::Element(gpu::VEC3, gpu::FLOAT, gpu::XYZ), VERTEX_NORMAL_OFFSET);
|
||||
details.streamFormat->setAttribute(gpu::Stream::COLOR, 1, gpu::Element(gpu::VEC4, gpu::NUINT8, 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);
|
||||
|
||||
|
||||
const glm::vec3 NORMAL(0.0f, 0.0f, 1.0f);
|
||||
float vertexBuffer[VERTICES * FLOATS_PER_VERTEX] = {
|
||||
minCorner.x, minCorner.y,
|
||||
maxCorner.x, minCorner.y,
|
||||
minCorner.x, maxCorner.y,
|
||||
maxCorner.x, maxCorner.y,
|
||||
minCorner.x, minCorner.y, NORMAL.x, NORMAL.y, NORMAL.z,
|
||||
maxCorner.x, minCorner.y, NORMAL.x, NORMAL.y, NORMAL.z,
|
||||
minCorner.x, maxCorner.y, NORMAL.x, NORMAL.y, NORMAL.z,
|
||||
maxCorner.x, maxCorner.y, NORMAL.x, NORMAL.y, NORMAL.z,
|
||||
};
|
||||
|
||||
const int NUM_COLOR_SCALARS_PER_QUAD = 4;
|
||||
|
@ -1158,10 +1185,12 @@ void GeometryCache::renderQuad(gpu::Batch& batch, const glm::vec2& minCorner, co
|
|||
#endif // def WANT_DEBUG
|
||||
}
|
||||
|
||||
const int FLOATS_PER_VERTEX = 2 * 2; // text coords & vertices
|
||||
const int FLOATS_PER_VERTEX = 2 + 3 + 2; // vertices + normals + tex coords
|
||||
const int VERTICES = 4; // 1 quad = 4 vertices
|
||||
const int NUM_POS_COORDS = 2;
|
||||
const int VERTEX_TEXCOORD_OFFSET = NUM_POS_COORDS * sizeof(float);
|
||||
const int NUM_NORMAL_COORDS = 3;
|
||||
const int VERTEX_NORMAL_OFFSET = NUM_POS_COORDS * sizeof(float);
|
||||
const int VERTEX_TEXCOORD_OFFSET = VERTEX_NORMAL_OFFSET + NUM_NORMAL_COORDS * sizeof(float);
|
||||
|
||||
if (!details.isCreated) {
|
||||
|
||||
|
@ -1181,7 +1210,9 @@ void GeometryCache::renderQuad(gpu::Batch& batch, const glm::vec2& minCorner, co
|
|||
details.streamFormat = streamFormat;
|
||||
details.stream = stream;
|
||||
|
||||
// zzmp: fix the normal across all renderQuad
|
||||
details.streamFormat->setAttribute(gpu::Stream::POSITION, 0, gpu::Element(gpu::VEC2, gpu::FLOAT, gpu::XYZ), 0);
|
||||
details.streamFormat->setAttribute(gpu::Stream::NORMAL, 0, gpu::Element(gpu::VEC3, gpu::FLOAT, gpu::XYZ), VERTEX_NORMAL_OFFSET);
|
||||
details.streamFormat->setAttribute(gpu::Stream::TEXCOORD, 0, gpu::Element(gpu::VEC2, gpu::FLOAT, gpu::UV), VERTEX_TEXCOORD_OFFSET);
|
||||
details.streamFormat->setAttribute(gpu::Stream::COLOR, 1, gpu::Element(gpu::VEC4, gpu::NUINT8, gpu::RGBA));
|
||||
|
||||
|
@ -1189,11 +1220,12 @@ void GeometryCache::renderQuad(gpu::Batch& batch, const glm::vec2& minCorner, co
|
|||
details.stream->addBuffer(details.colorBuffer, 0, details.streamFormat->getChannels().at(1)._stride);
|
||||
|
||||
|
||||
const glm::vec3 NORMAL(0.0f, 0.0f, 1.0f);
|
||||
float vertexBuffer[VERTICES * FLOATS_PER_VERTEX] = {
|
||||
minCorner.x, minCorner.y, texCoordMinCorner.x, texCoordMinCorner.y,
|
||||
maxCorner.x, minCorner.y, texCoordMaxCorner.x, texCoordMinCorner.y,
|
||||
minCorner.x, maxCorner.y, texCoordMinCorner.x, texCoordMaxCorner.y,
|
||||
maxCorner.x, maxCorner.y, texCoordMaxCorner.x, texCoordMaxCorner.y,
|
||||
minCorner.x, minCorner.y, NORMAL.x, NORMAL.y, NORMAL.z, texCoordMinCorner.x, texCoordMinCorner.y,
|
||||
maxCorner.x, minCorner.y, NORMAL.x, NORMAL.y, NORMAL.z, texCoordMaxCorner.x, texCoordMinCorner.y,
|
||||
minCorner.x, maxCorner.y, NORMAL.x, NORMAL.y, NORMAL.z, texCoordMinCorner.x, texCoordMaxCorner.y,
|
||||
maxCorner.x, maxCorner.y, NORMAL.x, NORMAL.y, NORMAL.z, texCoordMaxCorner.x, texCoordMaxCorner.y,
|
||||
};
|
||||
|
||||
|
||||
|
@ -1235,8 +1267,10 @@ void GeometryCache::renderQuad(gpu::Batch& batch, const glm::vec3& minCorner, co
|
|||
#endif // def WANT_DEBUG
|
||||
}
|
||||
|
||||
const int FLOATS_PER_VERTEX = 3; // vertices
|
||||
const int FLOATS_PER_VERTEX = 3 + 3; // vertices + normals
|
||||
const int VERTICES = 4; // 1 quad = 4 vertices
|
||||
const int NUM_POS_COORDS = 3;
|
||||
const int VERTEX_NORMAL_OFFSET = NUM_POS_COORDS * sizeof(float);
|
||||
|
||||
if (!details.isCreated) {
|
||||
|
||||
|
@ -1257,17 +1291,19 @@ void GeometryCache::renderQuad(gpu::Batch& batch, const glm::vec3& minCorner, co
|
|||
details.stream = stream;
|
||||
|
||||
details.streamFormat->setAttribute(gpu::Stream::POSITION, 0, gpu::Element(gpu::VEC3, gpu::FLOAT, gpu::XYZ), 0);
|
||||
details.streamFormat->setAttribute(gpu::Stream::NORMAL, 0, gpu::Element(gpu::VEC3, gpu::FLOAT, gpu::XYZ), VERTEX_NORMAL_OFFSET);
|
||||
details.streamFormat->setAttribute(gpu::Stream::COLOR, 1, gpu::Element(gpu::VEC4, gpu::NUINT8, 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);
|
||||
|
||||
|
||||
const glm::vec3 NORMAL(0.0f, 0.0f, 1.0f);
|
||||
float vertexBuffer[VERTICES * FLOATS_PER_VERTEX] = {
|
||||
minCorner.x, minCorner.y, minCorner.z,
|
||||
maxCorner.x, minCorner.y, minCorner.z,
|
||||
minCorner.x, maxCorner.y, maxCorner.z,
|
||||
maxCorner.x, maxCorner.y, maxCorner.z,
|
||||
minCorner.x, minCorner.y, minCorner.z, NORMAL.x, NORMAL.y, NORMAL.z,
|
||||
maxCorner.x, minCorner.y, minCorner.z, NORMAL.x, NORMAL.y, NORMAL.z,
|
||||
minCorner.x, maxCorner.y, maxCorner.z, NORMAL.x, NORMAL.y, NORMAL.z,
|
||||
maxCorner.x, maxCorner.y, maxCorner.z, NORMAL.x, NORMAL.y, NORMAL.z,
|
||||
};
|
||||
|
||||
const int NUM_COLOR_SCALARS_PER_QUAD = 4;
|
||||
|
@ -1327,10 +1363,13 @@ void GeometryCache::renderQuad(gpu::Batch& batch, const glm::vec3& topLeft, cons
|
|||
#endif // def WANT_DEBUG
|
||||
}
|
||||
|
||||
const int FLOATS_PER_VERTEX = 3 + 2; // 3d vertices + text coords
|
||||
const int FLOATS_PER_VERTEX = 3 + 3 + 2; // vertices + normals + tex coords
|
||||
const int VERTICES = 4; // 1 quad = 4 vertices
|
||||
const int NUM_POS_COORDS = 3;
|
||||
const int VERTEX_TEXCOORD_OFFSET = NUM_POS_COORDS * sizeof(float);
|
||||
const int NUM_NORMAL_COORDS = 3;
|
||||
const int VERTEX_NORMAL_OFFSET = NUM_POS_COORDS * sizeof(float);
|
||||
const int VERTEX_TEXCOORD_OFFSET = VERTEX_NORMAL_OFFSET + NUM_NORMAL_COORDS * sizeof(float);
|
||||
|
||||
|
||||
if (!details.isCreated) {
|
||||
|
||||
|
@ -1349,6 +1388,7 @@ void GeometryCache::renderQuad(gpu::Batch& batch, const glm::vec3& topLeft, cons
|
|||
details.stream = stream;
|
||||
|
||||
details.streamFormat->setAttribute(gpu::Stream::POSITION, 0, gpu::Element(gpu::VEC3, gpu::FLOAT, gpu::XYZ), 0);
|
||||
details.streamFormat->setAttribute(gpu::Stream::NORMAL, 0, gpu::Element(gpu::VEC3, gpu::FLOAT, gpu::XYZ), VERTEX_NORMAL_OFFSET);
|
||||
details.streamFormat->setAttribute(gpu::Stream::TEXCOORD, 0, gpu::Element(gpu::VEC2, gpu::FLOAT, gpu::UV), VERTEX_TEXCOORD_OFFSET);
|
||||
details.streamFormat->setAttribute(gpu::Stream::COLOR, 1, gpu::Element(gpu::VEC4, gpu::NUINT8, gpu::RGBA));
|
||||
|
||||
|
@ -1356,12 +1396,13 @@ void GeometryCache::renderQuad(gpu::Batch& batch, const glm::vec3& topLeft, cons
|
|||
details.stream->addBuffer(details.colorBuffer, 0, details.streamFormat->getChannels().at(1)._stride);
|
||||
|
||||
|
||||
const glm::vec3 NORMAL(0.0f, 0.0f, 1.0f);
|
||||
float vertexBuffer[VERTICES * FLOATS_PER_VERTEX] = {
|
||||
bottomLeft.x, bottomLeft.y, bottomLeft.z, texCoordBottomLeft.x, texCoordBottomLeft.y,
|
||||
bottomRight.x, bottomRight.y, bottomRight.z, texCoordBottomRight.x, texCoordBottomRight.y,
|
||||
topLeft.x, topLeft.y, topLeft.z, texCoordTopLeft.x, texCoordTopLeft.y,
|
||||
topRight.x, topRight.y, topRight.z, texCoordTopRight.x, texCoordTopRight.y,
|
||||
};
|
||||
bottomLeft.x, bottomLeft.y, bottomLeft.z, NORMAL.x, NORMAL.y, NORMAL.z, texCoordBottomLeft.x, texCoordBottomLeft.y,
|
||||
bottomRight.x, bottomRight.y, bottomRight.z, NORMAL.x, NORMAL.y, NORMAL.z, texCoordBottomRight.x, texCoordBottomRight.y,
|
||||
topLeft.x, topLeft.y, topLeft.z, NORMAL.x, NORMAL.y, NORMAL.z, texCoordTopLeft.x, texCoordTopLeft.y,
|
||||
topRight.x, topRight.y, topRight.z, NORMAL.x, NORMAL.y, NORMAL.z, texCoordTopRight.x, texCoordTopRight.y,
|
||||
};
|
||||
|
||||
const int NUM_COLOR_SCALARS_PER_QUAD = 4;
|
||||
int compactColor = ((int(color.x * 255.0f) & 0xFF)) |
|
||||
|
@ -1414,7 +1455,9 @@ void GeometryCache::renderDashedLine(gpu::Batch& batch, const glm::vec3& start,
|
|||
glm::vec3 dashVector = segmentVector / SEGMENT_LENGTH * dash_length;
|
||||
glm::vec3 gapVector = segmentVector / SEGMENT_LENGTH * gap_length;
|
||||
|
||||
const int FLOATS_PER_VERTEX = 3;
|
||||
const int FLOATS_PER_VERTEX = 3 + 3; // vertices + normals
|
||||
const int NUM_POS_COORDS = 3;
|
||||
const int VERTEX_NORMAL_OFFSET = NUM_POS_COORDS * sizeof(float);
|
||||
details.vertices = (segmentCountFloor + 1) * 2;
|
||||
details.vertexSize = FLOATS_PER_VERTEX;
|
||||
details.isCreated = true;
|
||||
|
@ -1430,6 +1473,7 @@ void GeometryCache::renderDashedLine(gpu::Batch& batch, const glm::vec3& start,
|
|||
details.stream = stream;
|
||||
|
||||
details.streamFormat->setAttribute(gpu::Stream::POSITION, 0, gpu::Element(gpu::VEC3, gpu::FLOAT, gpu::XYZ), 0);
|
||||
details.streamFormat->setAttribute(gpu::Stream::NORMAL, 0, gpu::Element(gpu::VEC3, gpu::FLOAT, gpu::XYZ), VERTEX_NORMAL_OFFSET);
|
||||
details.streamFormat->setAttribute(gpu::Stream::COLOR, 1, gpu::Element(gpu::VEC4, gpu::NUINT8, gpu::RGBA));
|
||||
|
||||
details.stream->addBuffer(details.verticesBuffer, 0, details.streamFormat->getChannels().at(0)._stride);
|
||||
|
@ -1441,10 +1485,14 @@ void GeometryCache::renderDashedLine(gpu::Batch& batch, const glm::vec3& start,
|
|||
float* vertexData = new float[details.vertices * FLOATS_PER_VERTEX];
|
||||
float* vertex = vertexData;
|
||||
|
||||
const glm::vec3 NORMAL(1.0f, 0.0f, 0.0f);
|
||||
glm::vec3 point = start;
|
||||
*(vertex++) = point.x;
|
||||
*(vertex++) = point.y;
|
||||
*(vertex++) = point.z;
|
||||
*(vertex++) = NORMAL.x;
|
||||
*(vertex++) = NORMAL.y;
|
||||
*(vertex++) = NORMAL.z;
|
||||
*(colorDataAt++) = compactColor;
|
||||
|
||||
for (int i = 0; i < segmentCountFloor; i++) {
|
||||
|
@ -1452,17 +1500,26 @@ void GeometryCache::renderDashedLine(gpu::Batch& batch, const glm::vec3& start,
|
|||
*(vertex++) = point.x;
|
||||
*(vertex++) = point.y;
|
||||
*(vertex++) = point.z;
|
||||
*(vertex++) = NORMAL.x;
|
||||
*(vertex++) = NORMAL.y;
|
||||
*(vertex++) = NORMAL.z;
|
||||
*(colorDataAt++) = compactColor;
|
||||
|
||||
point += gapVector;
|
||||
*(vertex++) = point.x;
|
||||
*(vertex++) = point.y;
|
||||
*(vertex++) = point.z;
|
||||
*(vertex++) = NORMAL.x;
|
||||
*(vertex++) = NORMAL.y;
|
||||
*(vertex++) = NORMAL.z;
|
||||
*(colorDataAt++) = compactColor;
|
||||
}
|
||||
*(vertex++) = end.x;
|
||||
*(vertex++) = end.y;
|
||||
*(vertex++) = end.z;
|
||||
*(vertex++) = NORMAL.x;
|
||||
*(vertex++) = NORMAL.y;
|
||||
*(vertex++) = NORMAL.z;
|
||||
*(colorDataAt++) = compactColor;
|
||||
|
||||
details.verticesBuffer->append(sizeof(float) * FLOATS_PER_VERTEX * details.vertices, (gpu::Byte*) vertexData);
|
||||
|
@ -1569,7 +1626,9 @@ void GeometryCache::renderLine(gpu::Batch& batch, const glm::vec3& p1, const glm
|
|||
#endif // def WANT_DEBUG
|
||||
}
|
||||
|
||||
const int FLOATS_PER_VERTEX = 3;
|
||||
const int FLOATS_PER_VERTEX = 3 + 3; // vertices + normals
|
||||
const int NUM_POS_COORDS = 3;
|
||||
const int VERTEX_NORMAL_OFFSET = NUM_POS_COORDS * sizeof(float);
|
||||
const int vertices = 2;
|
||||
if (!details.isCreated) {
|
||||
|
||||
|
@ -1588,13 +1647,16 @@ void GeometryCache::renderLine(gpu::Batch& batch, const glm::vec3& p1, const glm
|
|||
details.stream = stream;
|
||||
|
||||
details.streamFormat->setAttribute(gpu::Stream::POSITION, 0, gpu::Element(gpu::VEC3, gpu::FLOAT, gpu::XYZ), 0);
|
||||
details.streamFormat->setAttribute(gpu::Stream::NORMAL, 0, gpu::Element(gpu::VEC3, gpu::FLOAT, gpu::XYZ), VERTEX_NORMAL_OFFSET);
|
||||
details.streamFormat->setAttribute(gpu::Stream::COLOR, 1, gpu::Element(gpu::VEC4, gpu::NUINT8, 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);
|
||||
|
||||
|
||||
float vertexBuffer[vertices * FLOATS_PER_VERTEX] = { p1.x, p1.y, p1.z, p2.x, p2.y, p2.z };
|
||||
const glm::vec3 NORMAL(1.0f, 0.0f, 0.0f);
|
||||
float vertexBuffer[vertices * FLOATS_PER_VERTEX] = {
|
||||
p1.x, p1.y, p1.z, NORMAL.x, NORMAL.y, NORMAL.z,
|
||||
p2.x, p2.y, p2.z, NORMAL.x, NORMAL.y, NORMAL.z};
|
||||
|
||||
const int NUM_COLOR_SCALARS = 2;
|
||||
int colors[NUM_COLOR_SCALARS] = { compactColor1, compactColor2 };
|
||||
|
@ -1781,7 +1843,23 @@ inline bool operator==(const SimpleProgramKey& a, const SimpleProgramKey& b) {
|
|||
return a.getRaw() == b.getRaw();
|
||||
}
|
||||
|
||||
gpu::PipelinePointer GeometryCache::getPipeline(SimpleProgramKey config) {
|
||||
void GeometryCache::bindSimpleProgram(gpu::Batch& batch, bool textured, bool culled, bool emissive, bool depthBiased) {
|
||||
batch.setPipeline(getSimplePipeline(textured, culled, emissive, depthBiased));
|
||||
|
||||
// If not textured, set a default diffuse map
|
||||
if (!textured) {
|
||||
batch.setResourceTexture(render::ShapePipeline::Slot::DIFFUSE_MAP,
|
||||
DependencyManager::get<TextureCache>()->getWhiteTexture());
|
||||
}
|
||||
// Set a default normal map
|
||||
batch.setResourceTexture(render::ShapePipeline::Slot::NORMAL_FITTING_MAP,
|
||||
DependencyManager::get<TextureCache>()->getNormalFittingTexture());
|
||||
}
|
||||
|
||||
gpu::PipelinePointer GeometryCache::getSimplePipeline(bool textured, bool culled, bool emissive, bool depthBiased) {
|
||||
SimpleProgramKey config{textured, culled, emissive, depthBiased};
|
||||
|
||||
// Compile the shaders
|
||||
static std::once_flag once;
|
||||
std::call_once(once, [&]() {
|
||||
auto VS = gpu::Shader::createVertex(std::string(simple_vert));
|
||||
|
@ -1796,13 +1874,14 @@ gpu::PipelinePointer GeometryCache::getPipeline(SimpleProgramKey config) {
|
|||
gpu::Shader::makeProgram(*_simpleShader, slotBindings);
|
||||
gpu::Shader::makeProgram(*_emissiveShader, slotBindings);
|
||||
});
|
||||
|
||||
|
||||
|
||||
// If the pipeline already exists, return it
|
||||
auto it = _simplePrograms.find(config);
|
||||
if (it != _simplePrograms.end()) {
|
||||
return it.value();
|
||||
}
|
||||
|
||||
|
||||
// If the pipeline did not exist, make it
|
||||
auto state = std::make_shared<gpu::State>();
|
||||
if (config.isCulled()) {
|
||||
state->setCullMode(gpu::State::CULL_BACK);
|
||||
|
@ -1815,33 +1894,15 @@ gpu::PipelinePointer GeometryCache::getPipeline(SimpleProgramKey config) {
|
|||
state->setDepthBiasSlopeScale(1.0f);
|
||||
}
|
||||
state->setBlendFunction(false,
|
||||
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);
|
||||
|
||||
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);
|
||||
|
||||
gpu::ShaderPointer program = (config.isEmissive()) ? _emissiveShader : _simpleShader;
|
||||
gpu::PipelinePointer pipeline = gpu::Pipeline::create(program, state);
|
||||
_simplePrograms.insert(config, pipeline);
|
||||
return pipeline;
|
||||
}
|
||||
|
||||
gpu::PipelinePointer GeometryCache::bindSimpleProgram(gpu::Batch& batch, bool textured, bool culled,
|
||||
bool emissive, bool depthBias) {
|
||||
SimpleProgramKey config{textured, culled, emissive, depthBias};
|
||||
gpu::PipelinePointer pipeline = getPipeline(config);
|
||||
batch.setPipeline(pipeline);
|
||||
|
||||
gpu::ShaderPointer program = (config.isEmissive()) ? _emissiveShader : _simpleShader;
|
||||
|
||||
if (!config.isTextured()) {
|
||||
// If it is not textured, bind white texture and keep using textured pipeline
|
||||
batch.setResourceTexture(0, DependencyManager::get<TextureCache>()->getWhiteTexture());
|
||||
}
|
||||
|
||||
batch.setResourceTexture(render::ShapePipeline::Slot::NORMAL_FITTING_MAP,
|
||||
DependencyManager::get<TextureCache>()->getNormalFittingTexture());
|
||||
return pipeline;
|
||||
}
|
||||
|
||||
uint32_t toCompactColor(const glm::vec4& color) {
|
||||
uint32_t compactColor = ((int(color.x * 255.0f) & 0xFF)) |
|
||||
((int(color.y * 255.0f) & 0xFF) << 8) |
|
||||
|
@ -1852,46 +1913,51 @@ uint32_t toCompactColor(const glm::vec4& color) {
|
|||
|
||||
static const size_t INSTANCE_COLOR_BUFFER = 0;
|
||||
|
||||
template <typename F>
|
||||
void renderInstances(const std::string& name, gpu::Batch& batch, const glm::vec4& color, F f) {
|
||||
void renderInstances(const std::string& name, gpu::Batch& batch, const glm::vec4& color, bool isWire,
|
||||
const render::ShapePipelinePointer& pipeline, GeometryCache::Shape shape) {
|
||||
// Add pipeline to name
|
||||
std::string instanceName = name + std::to_string(std::hash<render::ShapePipelinePointer>()(pipeline));
|
||||
|
||||
// Add color to named buffer
|
||||
{
|
||||
gpu::BufferPointer instanceColorBuffer = batch.getNamedBuffer(name, INSTANCE_COLOR_BUFFER);
|
||||
gpu::BufferPointer instanceColorBuffer = batch.getNamedBuffer(instanceName, INSTANCE_COLOR_BUFFER);
|
||||
auto compactColor = toCompactColor(color);
|
||||
instanceColorBuffer->append(compactColor);
|
||||
}
|
||||
|
||||
batch.setupNamedCalls(name, [f](gpu::Batch& batch, gpu::Batch::NamedBatchData& data) {
|
||||
DependencyManager::get<GeometryCache>()->bindSimpleProgram(batch);
|
||||
f(batch, data);
|
||||
|
||||
// Add call to named buffer
|
||||
batch.setupNamedCalls(instanceName, [isWire, pipeline, shape](gpu::Batch& batch, gpu::Batch::NamedBatchData& data) {
|
||||
batch.setPipeline(pipeline->pipeline);
|
||||
pipeline->prepare(batch);
|
||||
|
||||
if (isWire) {
|
||||
DependencyManager::get<GeometryCache>()->renderWireShapeInstances(batch, shape, data.count(), data.buffers[INSTANCE_COLOR_BUFFER]);
|
||||
} else {
|
||||
DependencyManager::get<GeometryCache>()->renderShapeInstances(batch, shape, data.count(), data.buffers[INSTANCE_COLOR_BUFFER]);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void GeometryCache::renderSolidSphereInstance(gpu::Batch& batch, const glm::vec4& color) {
|
||||
void GeometryCache::renderSolidSphereInstance(gpu::Batch& batch, const glm::vec4& color, const render::ShapePipelinePointer& pipeline) {
|
||||
static const std::string INSTANCE_NAME = __FUNCTION__;
|
||||
renderInstances(INSTANCE_NAME, batch, color, [](gpu::Batch& batch, gpu::Batch::NamedBatchData& data) {
|
||||
DependencyManager::get<GeometryCache>()->renderShapeInstances(batch, GeometryCache::Sphere, data.count(),
|
||||
data.buffers[INSTANCE_COLOR_BUFFER]);
|
||||
});
|
||||
renderInstances(INSTANCE_NAME, batch, color, false, pipeline, GeometryCache::Sphere);
|
||||
}
|
||||
|
||||
void GeometryCache::renderWireSphereInstance(gpu::Batch& batch, const glm::vec4& color) {
|
||||
void GeometryCache::renderWireSphereInstance(gpu::Batch& batch, const glm::vec4& color, const render::ShapePipelinePointer& pipeline) {
|
||||
static const std::string INSTANCE_NAME = __FUNCTION__;
|
||||
renderInstances(INSTANCE_NAME, batch, color, [](gpu::Batch& batch, gpu::Batch::NamedBatchData& data) {
|
||||
DependencyManager::get<GeometryCache>()->renderWireShapeInstances(batch, GeometryCache::Sphere, data.count(),
|
||||
data.buffers[INSTANCE_COLOR_BUFFER]);
|
||||
});
|
||||
renderInstances(INSTANCE_NAME, batch, color, true, pipeline, GeometryCache::Sphere);
|
||||
}
|
||||
|
||||
// Enable this in a debug build to cause 'box' entities to iterate through all the
|
||||
// available shape types, both solid and wireframes
|
||||
//#define DEBUG_SHAPES
|
||||
|
||||
void GeometryCache::renderSolidCubeInstance(gpu::Batch& batch, const glm::vec4& color) {
|
||||
void GeometryCache::renderSolidCubeInstance(gpu::Batch& batch, const glm::vec4& color, const render::ShapePipelinePointer& pipeline) {
|
||||
static const std::string INSTANCE_NAME = __FUNCTION__;
|
||||
|
||||
#ifdef DEBUG_SHAPES
|
||||
static auto startTime = usecTimestampNow();
|
||||
renderInstances(INSTANCE_NAME, batch, color, [](gpu::Batch& batch, gpu::Batch::NamedBatchData& data) {
|
||||
renderInstances(INSTANCE_NAME, batch, color, pipeline, [](gpu::Batch& batch, gpu::Batch::NamedBatchData& data) {
|
||||
|
||||
auto usecs = usecTimestampNow();
|
||||
usecs -= startTime;
|
||||
|
@ -1916,26 +1982,17 @@ void GeometryCache::renderSolidCubeInstance(gpu::Batch& batch, const glm::vec4&
|
|||
|
||||
// For the first half second for a given shape, show the wireframe, for the second half, show the solid.
|
||||
if (fractionalSeconds > 0.5f) {
|
||||
DependencyManager::get<GeometryCache>()->renderShapeInstances(batch, shape, data.count(),
|
||||
data.buffers[INSTANCE_COLOR_BUFFER]);
|
||||
renderInstances(INSTANCE_NAME, batch, color, true, pipeline, shape);
|
||||
} else {
|
||||
DependencyManager::get<GeometryCache>()->renderWireShapeInstances(batch, shape, data.count(),
|
||||
data.buffers[INSTANCE_COLOR_BUFFER]);
|
||||
renderInstances(INSTANCE_NAME, batch, color, false, pipeline, shape);
|
||||
}
|
||||
});
|
||||
#else
|
||||
renderInstances(INSTANCE_NAME, batch, color, [](gpu::Batch& batch, gpu::Batch::NamedBatchData& data) {
|
||||
DependencyManager::get<GeometryCache>()->renderCubeInstances(batch, data.count(),
|
||||
data.buffers[INSTANCE_COLOR_BUFFER]);
|
||||
});
|
||||
renderInstances(INSTANCE_NAME, batch, color, false, pipeline, GeometryCache::Cube);
|
||||
#endif
|
||||
}
|
||||
|
||||
void GeometryCache::renderWireCubeInstance(gpu::Batch& batch, const glm::vec4& color) {
|
||||
void GeometryCache::renderWireCubeInstance(gpu::Batch& batch, const glm::vec4& color, const render::ShapePipelinePointer& pipeline) {
|
||||
static const std::string INSTANCE_NAME = __FUNCTION__;
|
||||
renderInstances(INSTANCE_NAME, batch, color, [](gpu::Batch& batch, gpu::Batch::NamedBatchData& data) {
|
||||
DependencyManager::get<GeometryCache>()->renderWireCubeInstances(batch, data.count(),
|
||||
data.buffers[INSTANCE_COLOR_BUFFER]);
|
||||
});
|
||||
renderInstances(INSTANCE_NAME, batch, color, true, pipeline, GeometryCache::Cube);
|
||||
}
|
||||
|
||||
|
|
|
@ -150,45 +150,55 @@ public:
|
|||
static const int UNKNOWN_ID;
|
||||
|
||||
|
||||
/// Sets up the state necessary to render static untextured geometry with the simple program.
|
||||
gpu::PipelinePointer bindSimpleProgram(gpu::Batch& batch, bool textured = false, bool culled = true,
|
||||
bool emissive = false, bool depthBias = false);
|
||||
// Bind the pipeline and get the state to render static geometry
|
||||
void bindSimpleProgram(gpu::Batch& batch, bool textured = false, bool culled = true,
|
||||
bool emissive = false, bool depthBias = false);
|
||||
// Get the pipeline to render static geometry
|
||||
gpu::PipelinePointer getSimplePipeline(bool textured = false, bool culled = true,
|
||||
bool emissive = false, bool depthBias = false);
|
||||
render::ShapePipelinePointer getShapePipeline() { return GeometryCache::_simplePipeline; }
|
||||
|
||||
void renderSolidSphereInstance(gpu::Batch& batch, const glm::vec4& color);
|
||||
void renderSolidSphereInstance(gpu::Batch& batch, const glm::vec3& color) {
|
||||
renderSolidSphereInstance(batch, glm::vec4(color, 1.0));
|
||||
}
|
||||
|
||||
void renderWireSphereInstance(gpu::Batch& batch, const glm::vec4& color);
|
||||
void renderWireSphereInstance(gpu::Batch& batch, const glm::vec3& color) {
|
||||
renderWireSphereInstance(batch, glm::vec4(color, 1.0));
|
||||
}
|
||||
|
||||
void renderSolidCubeInstance(gpu::Batch& batch, const glm::vec4& color);
|
||||
void renderSolidCubeInstance(gpu::Batch& batch, const glm::vec3& color) {
|
||||
renderSolidCubeInstance(batch, glm::vec4(color, 1.0));
|
||||
}
|
||||
|
||||
void renderWireCubeInstance(gpu::Batch& batch, const glm::vec4& color);
|
||||
void renderWireCubeInstance(gpu::Batch& batch, const glm::vec3& color) {
|
||||
renderWireCubeInstance(batch, glm::vec4(color, 1.0));
|
||||
}
|
||||
|
||||
|
||||
// Static (instanced) geometry
|
||||
void renderShapeInstances(gpu::Batch& batch, Shape shape, size_t count, gpu::BufferPointer& colorBuffer);
|
||||
void renderWireShapeInstances(gpu::Batch& batch, Shape shape, size_t count, gpu::BufferPointer& colorBuffer);
|
||||
|
||||
void renderSolidSphereInstance(gpu::Batch& batch, const glm::vec4& color,
|
||||
const render::ShapePipelinePointer& pipeline = _simplePipeline);
|
||||
void renderSolidSphereInstance(gpu::Batch& batch, const glm::vec3& color,
|
||||
const render::ShapePipelinePointer& pipeline = _simplePipeline) {
|
||||
renderSolidSphereInstance(batch, glm::vec4(color, 1.0f), pipeline);
|
||||
}
|
||||
|
||||
void renderWireSphereInstance(gpu::Batch& batch, const glm::vec4& color,
|
||||
const render::ShapePipelinePointer& pipeline = _simplePipeline);
|
||||
void renderWireSphereInstance(gpu::Batch& batch, const glm::vec3& color,
|
||||
const render::ShapePipelinePointer& pipeline = _simplePipeline) {
|
||||
renderWireSphereInstance(batch, glm::vec4(color, 1.0f), pipeline);
|
||||
}
|
||||
|
||||
void renderSolidCubeInstance(gpu::Batch& batch, const glm::vec4& color,
|
||||
const render::ShapePipelinePointer& pipeline = _simplePipeline);
|
||||
void renderSolidCubeInstance(gpu::Batch& batch, const glm::vec3& color,
|
||||
const render::ShapePipelinePointer& pipeline = _simplePipeline) {
|
||||
renderSolidCubeInstance(batch, glm::vec4(color, 1.0f), pipeline);
|
||||
}
|
||||
|
||||
void renderWireCubeInstance(gpu::Batch& batch, const glm::vec4& color,
|
||||
const render::ShapePipelinePointer& pipeline = _simplePipeline);
|
||||
void renderWireCubeInstance(gpu::Batch& batch, const glm::vec3& color,
|
||||
const render::ShapePipelinePointer& pipeline = _simplePipeline) {
|
||||
renderWireCubeInstance(batch, glm::vec4(color, 1.0f), pipeline);
|
||||
}
|
||||
|
||||
// Dynamic geometry
|
||||
void renderShape(gpu::Batch& batch, Shape shape);
|
||||
void renderWireShape(gpu::Batch& batch, Shape shape);
|
||||
size_t getShapeTriangleCount(Shape shape);
|
||||
|
||||
void renderCubeInstances(gpu::Batch& batch, size_t count, gpu::BufferPointer colorBuffer);
|
||||
void renderWireCubeInstances(gpu::Batch& batch, size_t count, gpu::BufferPointer colorBuffer);
|
||||
void renderCube(gpu::Batch& batch);
|
||||
void renderWireCube(gpu::Batch& batch);
|
||||
size_t getCubeTriangleCount();
|
||||
|
||||
void renderSphereInstances(gpu::Batch& batch, size_t count, gpu::BufferPointer colorBuffer);
|
||||
void renderWireSphereInstances(gpu::Batch& batch, size_t count, gpu::BufferPointer colorBuffer);
|
||||
void renderSphere(gpu::Batch& batch);
|
||||
void renderWireSphere(gpu::Batch& batch);
|
||||
size_t getSphereTriangleCount();
|
||||
|
@ -364,11 +374,9 @@ private:
|
|||
|
||||
QHash<QUrl, QWeakPointer<NetworkGeometry> > _networkGeometry;
|
||||
|
||||
|
||||
gpu::PipelinePointer getPipeline(SimpleProgramKey config);
|
||||
|
||||
gpu::ShaderPointer _simpleShader;
|
||||
gpu::ShaderPointer _emissiveShader;
|
||||
static render::ShapePipelinePointer _simplePipeline;
|
||||
QHash<SimpleProgramKey, gpu::PipelinePointer> _simplePrograms;
|
||||
};
|
||||
|
||||
|
|
|
@ -225,8 +225,6 @@ void MeshPartPayload::render(RenderArgs* args) const {
|
|||
|
||||
gpu::Batch& batch = *(args->_batch);
|
||||
|
||||
ShapeKey key = getShapeKey();
|
||||
|
||||
auto locations = args->_pipeline->locations;
|
||||
assert(locations);
|
||||
|
||||
|
@ -239,13 +237,6 @@ void MeshPartPayload::render(RenderArgs* args) const {
|
|||
// apply material properties
|
||||
bindMaterial(batch, locations);
|
||||
|
||||
|
||||
// TODO: We should be able to do that just in the renderTransparentJob
|
||||
if (key.isTranslucent() && locations->lightBufferUnit >= 0) {
|
||||
PerformanceTimer perfTimer("DLE->setupTransparent()");
|
||||
|
||||
DependencyManager::get<DeferredLightingEffect>()->setupTransparent(args, locations->lightBufferUnit);
|
||||
}
|
||||
if (args) {
|
||||
args->_details._materialSwitches++;
|
||||
}
|
||||
|
@ -475,8 +466,7 @@ void ModelMeshPartPayload::render(RenderArgs* args) const {
|
|||
|
||||
gpu::Batch& batch = *(args->_batch);
|
||||
|
||||
ShapeKey key = getShapeKey();
|
||||
if (!key.isValid()) {
|
||||
if (!getShapeKey().isValid()) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -517,13 +507,6 @@ void ModelMeshPartPayload::render(RenderArgs* args) const {
|
|||
// apply material properties
|
||||
bindMaterial(batch, locations);
|
||||
|
||||
|
||||
// TODO: We should be able to do that just in the renderTransparentJob
|
||||
if (key.isTranslucent() && locations->lightBufferUnit >= 0) {
|
||||
PerformanceTimer perfTimer("DLE->setupTransparent()");
|
||||
|
||||
DependencyManager::get<DeferredLightingEffect>()->setupTransparent(args, locations->lightBufferUnit);
|
||||
}
|
||||
if (args) {
|
||||
args->_details._materialSwitches++;
|
||||
}
|
||||
|
|
|
@ -104,7 +104,8 @@ RenderDeferredTask::RenderDeferredTask(CullFunctor cullFunctor) {
|
|||
addJob<DrawStatus>("DrawStatus", opaques, DrawStatus(statusIconMap));
|
||||
}
|
||||
|
||||
addJob<DrawOverlay3D>("DrawOverlay3D");
|
||||
addJob<DrawOverlay3D>("DrawOverlay3DOpaque", ItemFilter::Builder::opaqueShape().withLayered());
|
||||
addJob<DrawOverlay3D>("DrawOverlay3DTransparent", ItemFilter::Builder::transparentShape().withLayered());
|
||||
|
||||
addJob<HitEffect>("HitEffect");
|
||||
|
||||
|
@ -156,7 +157,7 @@ void DrawDeferred::run(const SceneContextPointer& sceneContext, const RenderCont
|
|||
});
|
||||
}
|
||||
|
||||
DrawOverlay3D::DrawOverlay3D() : _shapePlumber{ std::make_shared<ShapePlumber>() } {
|
||||
DrawOverlay3D::DrawOverlay3D(ItemFilter filter) : _filter{ filter }, _shapePlumber{ std::make_shared<ShapePlumber>() } {
|
||||
initOverlay3DPipelines(*_shapePlumber);
|
||||
}
|
||||
|
||||
|
@ -166,7 +167,7 @@ void DrawOverlay3D::run(const SceneContextPointer& sceneContext, const RenderCon
|
|||
|
||||
// render backgrounds
|
||||
auto& scene = sceneContext->_scene;
|
||||
auto& items = scene->getMasterBucket().at(ItemFilter::Builder::opaqueShape().withLayered());
|
||||
auto& items = scene->getMasterBucket().at(_filter);
|
||||
|
||||
auto config = std::static_pointer_cast<Config>(renderContext->jobConfig);
|
||||
|
||||
|
@ -179,7 +180,6 @@ void DrawOverlay3D::run(const SceneContextPointer& sceneContext, const RenderCon
|
|||
}
|
||||
}
|
||||
config->numItems = (int)inItems.size();
|
||||
config->numDrawn = (int)inItems.size();
|
||||
|
||||
if (!inItems.empty()) {
|
||||
RenderArgs* args = renderContext->args;
|
||||
|
|
|
@ -87,14 +87,11 @@ public:
|
|||
class DrawOverlay3DConfig : public render::Job::Config {
|
||||
Q_OBJECT
|
||||
Q_PROPERTY(int numItems READ getNumItems)
|
||||
Q_PROPERTY(int numDrawn READ getNumDrawn)
|
||||
Q_PROPERTY(int maxDrawn MEMBER maxDrawn NOTIFY dirty)
|
||||
public:
|
||||
int getNumItems() { return numItems; }
|
||||
int getNumDrawn() { return numDrawn; }
|
||||
|
||||
int numItems{ 0 };
|
||||
int numDrawn{ 0 };
|
||||
int maxDrawn{ -1 };
|
||||
signals:
|
||||
void dirty();
|
||||
|
@ -105,12 +102,13 @@ public:
|
|||
using Config = DrawOverlay3DConfig;
|
||||
using JobModel = render::Job::Model<DrawOverlay3D, Config>;
|
||||
|
||||
DrawOverlay3D();
|
||||
DrawOverlay3D(render::ItemFilter filter);
|
||||
|
||||
void configure(const Config& config) { _maxDrawn = config.maxDrawn; }
|
||||
void run(const render::SceneContextPointer& sceneContext, const render::RenderContextPointer& renderContext);
|
||||
|
||||
protected:
|
||||
render::ItemFilter _filter;
|
||||
render::ShapePlumberPointer _shapePlumber;
|
||||
int _maxDrawn; // initialized by Config
|
||||
};
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
#include <gpu/Context.h>
|
||||
#include <gpu/StandardShaderLib.h>
|
||||
|
||||
#include "DeferredLightingEffect.h"
|
||||
#include "TextureCache.h"
|
||||
#include "render/DrawTask.h"
|
||||
|
||||
|
@ -26,6 +27,7 @@
|
|||
#include "skin_model_normal_map_vert.h"
|
||||
|
||||
#include "model_frag.h"
|
||||
#include "model_emissive_frag.h"
|
||||
#include "model_shadow_frag.h"
|
||||
#include "model_normal_map_frag.h"
|
||||
#include "model_normal_specular_map_frag.h"
|
||||
|
@ -35,9 +37,13 @@
|
|||
#include "model_lightmap_normal_specular_map_frag.h"
|
||||
#include "model_lightmap_specular_map_frag.h"
|
||||
#include "model_translucent_frag.h"
|
||||
#include "model_translucent_emissive_frag.h"
|
||||
|
||||
#include "overlay3D_vert.h"
|
||||
#include "overlay3D_frag.h"
|
||||
#include "overlay3D_translucent_frag.h"
|
||||
#include "overlay3D_emissive_frag.h"
|
||||
#include "overlay3D_translucent_emissive_frag.h"
|
||||
|
||||
#include "drawOpaqueStencil_frag.h"
|
||||
|
||||
|
@ -58,22 +64,85 @@ void initStencilPipeline(gpu::PipelinePointer& pipeline) {
|
|||
pipeline = gpu::Pipeline::create(program, state);
|
||||
}
|
||||
|
||||
void initOverlay3DPipelines(ShapePlumber& plumber) {
|
||||
auto vs = gpu::Shader::createVertex(std::string(overlay3D_vert));
|
||||
auto ps = gpu::Shader::createPixel(std::string(overlay3D_frag));
|
||||
auto program = gpu::Shader::createProgram(vs, ps);
|
||||
|
||||
auto opaqueState = std::make_shared<gpu::State>();
|
||||
opaqueState->setDepthTest(false);
|
||||
opaqueState->setBlendFunction(false);
|
||||
|
||||
plumber.addPipeline(ShapeKey::Filter::Builder().withOpaque(), program, opaqueState);
|
||||
gpu::BufferView getDefaultMaterialBuffer() {
|
||||
model::Material::Schema schema;
|
||||
schema._diffuse = vec3(1.0f);
|
||||
schema._opacity = 1.0f;
|
||||
schema._metallic = vec3(0.1f);
|
||||
schema._gloss = 10.0f;
|
||||
return gpu::BufferView(std::make_shared<gpu::Buffer>(sizeof(model::Material::Schema), (const gpu::Byte*) &schema));
|
||||
}
|
||||
|
||||
void pipelineBatchSetter(const ShapePipeline& pipeline, gpu::Batch& batch) {
|
||||
if (pipeline.locations->normalFittingMapUnit > -1) {
|
||||
batch.setResourceTexture(pipeline.locations->normalFittingMapUnit,
|
||||
DependencyManager::get<TextureCache>()->getNormalFittingTexture());
|
||||
void batchSetter(const ShapePipeline& pipeline, gpu::Batch& batch) {
|
||||
// Set a default diffuse map
|
||||
batch.setResourceTexture(render::ShapePipeline::Slot::DIFFUSE_MAP,
|
||||
DependencyManager::get<TextureCache>()->getWhiteTexture());
|
||||
// Set a default normal map
|
||||
batch.setResourceTexture(render::ShapePipeline::Slot::NORMAL_FITTING_MAP,
|
||||
DependencyManager::get<TextureCache>()->getNormalFittingTexture());
|
||||
// Set default coordinates
|
||||
if (pipeline.locations->texcoordMatrices >= 0) {
|
||||
static const glm::mat4 TEX_COORDS[2];
|
||||
batch._glUniformMatrix4fv(pipeline.locations->texcoordMatrices, 2, false, (const float*)&TEX_COORDS);
|
||||
}
|
||||
// Set a default material
|
||||
if (pipeline.locations->materialBufferUnit >= 0) {
|
||||
static const gpu::BufferView OPAQUE_SCHEMA_BUFFER = getDefaultMaterialBuffer();
|
||||
batch.setUniformBuffer(ShapePipeline::Slot::MATERIAL_GPU, OPAQUE_SCHEMA_BUFFER);
|
||||
}
|
||||
}
|
||||
|
||||
void lightBatchSetter(const ShapePipeline& pipeline, gpu::Batch& batch) {
|
||||
batchSetter(pipeline, batch);
|
||||
// Set the light
|
||||
if (pipeline.locations->lightBufferUnit >= 0) {
|
||||
DependencyManager::get<DeferredLightingEffect>()->setupBatch(batch, pipeline.locations->lightBufferUnit);
|
||||
}
|
||||
}
|
||||
|
||||
void initOverlay3DPipelines(ShapePlumber& plumber) {
|
||||
auto vertex = gpu::Shader::createVertex(std::string(overlay3D_vert));
|
||||
auto pixel = gpu::Shader::createPixel(std::string(overlay3D_frag));
|
||||
auto pixelTranslucent = gpu::Shader::createPixel(std::string(overlay3D_translucent_frag));
|
||||
auto pixelEmissive = gpu::Shader::createPixel(std::string(overlay3D_emissive_frag));
|
||||
auto pixelTranslucentEmissive = gpu::Shader::createPixel(std::string(overlay3D_translucent_emissive_frag));
|
||||
|
||||
auto opaqueProgram = gpu::Shader::createProgram(vertex, pixel);
|
||||
auto translucentProgram = gpu::Shader::createProgram(vertex, pixelTranslucent);
|
||||
auto emissiveOpaqueProgram = gpu::Shader::createProgram(vertex, pixelEmissive);
|
||||
auto emissiveTranslucentProgram = gpu::Shader::createProgram(vertex, pixelTranslucentEmissive);
|
||||
|
||||
for (int i = 0; i < 8; i++) {
|
||||
bool isCulled = (i & 1);
|
||||
bool isBiased = (i & 2);
|
||||
bool isOpaque = (i & 4);
|
||||
|
||||
auto state = std::make_shared<gpu::State>();
|
||||
state->setDepthTest(false);
|
||||
state->setCullMode(isCulled ? gpu::State::CULL_BACK : gpu::State::CULL_NONE);
|
||||
if (isBiased) {
|
||||
state->setDepthBias(1.0f);
|
||||
state->setDepthBiasSlopeScale(1.0f);
|
||||
}
|
||||
if (isOpaque) {
|
||||
// Soft edges
|
||||
state->setBlendFunction(true,
|
||||
gpu::State::SRC_ALPHA, gpu::State::BLEND_OP_ADD, gpu::State::INV_SRC_ALPHA);
|
||||
} else {
|
||||
state->setBlendFunction(true,
|
||||
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);
|
||||
}
|
||||
|
||||
ShapeKey::Filter::Builder builder;
|
||||
isCulled ? builder.withCullFace() : builder.withoutCullFace();
|
||||
isBiased ? builder.withDepthBias() : builder.withoutDepthBias();
|
||||
isOpaque ? builder.withOpaque() : builder.withTranslucent();
|
||||
|
||||
auto simpleProgram = isOpaque ? opaqueProgram : translucentProgram;
|
||||
auto emissiveProgram = isOpaque ? emissiveOpaqueProgram : emissiveTranslucentProgram;
|
||||
plumber.addPipeline(builder.withoutEmissive().build(), simpleProgram, state, &lightBatchSetter);
|
||||
plumber.addPipeline(builder.withEmissive().build(), emissiveProgram, state, &batchSetter);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -82,31 +151,43 @@ void initDeferredPipelines(render::ShapePlumber& plumber) {
|
|||
using ShaderPointer = gpu::ShaderPointer;
|
||||
|
||||
auto addPipeline = [&plumber](const Key& key, const ShaderPointer& vertexShader, const ShaderPointer& pixelShader) {
|
||||
auto state = std::make_shared<gpu::State>();
|
||||
|
||||
// Cull backface
|
||||
state->setCullMode(gpu::State::CULL_BACK);
|
||||
|
||||
// Z test depends on transparency
|
||||
state->setDepthTest(true, !key.isTranslucent(), gpu::LESS_EQUAL);
|
||||
|
||||
// Blend if transparent
|
||||
state->setBlendFunction(key.isTranslucent(),
|
||||
// For transparency, keep the highlight intensity
|
||||
gpu::State::ONE, gpu::State::BLEND_OP_ADD, gpu::State::INV_SRC_ALPHA,
|
||||
gpu::State::FACTOR_ALPHA, gpu::State::BLEND_OP_ADD, gpu::State::ONE);
|
||||
// These keyvalues' pipelines will be added by this lamdba in addition to the key passed
|
||||
assert(!key.isWireFrame());
|
||||
assert(!key.isDepthBiased());
|
||||
assert(key.isCullFace());
|
||||
|
||||
ShaderPointer program = gpu::Shader::createProgram(vertexShader, pixelShader);
|
||||
plumber.addPipeline(key, program, state, &pipelineBatchSetter);
|
||||
|
||||
// Add a wireframe version
|
||||
if (!key.isWireFrame()) {
|
||||
auto wireFrameKey = Key::Builder(key).withWireframe();
|
||||
auto wireFrameState = std::make_shared<gpu::State>(state->getValues());
|
||||
for (int i = 0; i < 8; i++) {
|
||||
bool isCulled = (i & 1);
|
||||
bool isBiased = (i & 2);
|
||||
bool isWireframed = (i & 4);
|
||||
|
||||
wireFrameState->setFillMode(gpu::State::FILL_LINE);
|
||||
ShapeKey::Builder builder(key);
|
||||
auto state = std::make_shared<gpu::State>();
|
||||
|
||||
plumber.addPipeline(wireFrameKey, program, wireFrameState, &pipelineBatchSetter);
|
||||
// Depth test depends on transparency
|
||||
state->setDepthTest(true, !key.isTranslucent(), gpu::LESS_EQUAL);
|
||||
state->setBlendFunction(key.isTranslucent(),
|
||||
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 (!isCulled) {
|
||||
builder.withoutCullFace();
|
||||
}
|
||||
state->setCullMode(isCulled ? gpu::State::CULL_BACK : gpu::State::CULL_NONE);
|
||||
if (isWireframed) {
|
||||
builder.withWireframe();
|
||||
state->setFillMode(gpu::State::FILL_LINE);
|
||||
}
|
||||
if (isBiased) {
|
||||
builder.withDepthBias();
|
||||
state->setDepthBias(1.0f);
|
||||
state->setDepthBiasSlopeScale(1.0f);
|
||||
}
|
||||
|
||||
plumber.addPipeline(builder.build(), program, state,
|
||||
key.isTranslucent() ? &lightBatchSetter : &batchSetter);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -122,113 +203,99 @@ void initDeferredPipelines(render::ShapePlumber& plumber) {
|
|||
|
||||
// Pixel shaders
|
||||
auto modelPixel = gpu::Shader::createPixel(std::string(model_frag));
|
||||
auto modelEmissivePixel = gpu::Shader::createPixel(std::string(model_emissive_frag));
|
||||
auto modelNormalMapPixel = gpu::Shader::createPixel(std::string(model_normal_map_frag));
|
||||
auto modelSpecularMapPixel = gpu::Shader::createPixel(std::string(model_specular_map_frag));
|
||||
auto modelNormalSpecularMapPixel = gpu::Shader::createPixel(std::string(model_normal_specular_map_frag));
|
||||
auto modelTranslucentPixel = gpu::Shader::createPixel(std::string(model_translucent_frag));
|
||||
auto modelTranslucentEmissivePixel = gpu::Shader::createPixel(std::string(model_translucent_emissive_frag));
|
||||
auto modelShadowPixel = gpu::Shader::createPixel(std::string(model_shadow_frag));
|
||||
auto modelLightmapPixel = gpu::Shader::createPixel(std::string(model_lightmap_frag));
|
||||
auto modelLightmapNormalMapPixel = gpu::Shader::createPixel(std::string(model_lightmap_normal_map_frag));
|
||||
auto modelLightmapSpecularMapPixel = gpu::Shader::createPixel(std::string(model_lightmap_specular_map_frag));
|
||||
auto modelLightmapNormalSpecularMapPixel = gpu::Shader::createPixel(std::string(model_lightmap_normal_specular_map_frag));
|
||||
|
||||
// Fill the pipelineLib
|
||||
// TODO: Refactor this to use a filter
|
||||
// Opaques
|
||||
addPipeline(
|
||||
Key::Builder(),
|
||||
modelVertex, modelPixel);
|
||||
|
||||
addPipeline(
|
||||
Key::Builder().withEmissive(),
|
||||
modelVertex, modelEmissivePixel);
|
||||
addPipeline(
|
||||
Key::Builder().withTangents(),
|
||||
modelNormalMapVertex, modelNormalMapPixel);
|
||||
|
||||
addPipeline(
|
||||
Key::Builder().withSpecular(),
|
||||
modelVertex, modelSpecularMapPixel);
|
||||
|
||||
addPipeline(
|
||||
Key::Builder().withTangents().withSpecular(),
|
||||
modelNormalMapVertex, modelNormalSpecularMapPixel);
|
||||
|
||||
|
||||
// Translucents
|
||||
addPipeline(
|
||||
Key::Builder().withTranslucent(),
|
||||
modelVertex, modelTranslucentPixel);
|
||||
// FIXME Ignore lightmap for translucents meshpart
|
||||
addPipeline(
|
||||
Key::Builder().withTranslucent().withEmissive(),
|
||||
modelVertex, modelTranslucentEmissivePixel);
|
||||
addPipeline(
|
||||
Key::Builder().withTranslucent().withTangents(),
|
||||
modelNormalMapVertex, modelTranslucentPixel);
|
||||
addPipeline(
|
||||
Key::Builder().withTranslucent().withSpecular(),
|
||||
modelVertex, modelTranslucentPixel);
|
||||
addPipeline(
|
||||
Key::Builder().withTranslucent().withTangents().withSpecular(),
|
||||
modelNormalMapVertex, modelTranslucentPixel);
|
||||
addPipeline(
|
||||
// FIXME: Ignore lightmap for translucents meshpart
|
||||
Key::Builder().withTranslucent().withLightmap(),
|
||||
modelVertex, modelTranslucentPixel);
|
||||
|
||||
addPipeline(
|
||||
Key::Builder().withTangents().withTranslucent(),
|
||||
modelNormalMapVertex, modelTranslucentPixel);
|
||||
|
||||
addPipeline(
|
||||
Key::Builder().withSpecular().withTranslucent(),
|
||||
modelVertex, modelTranslucentPixel);
|
||||
|
||||
addPipeline(
|
||||
Key::Builder().withTangents().withSpecular().withTranslucent(),
|
||||
modelNormalMapVertex, modelTranslucentPixel);
|
||||
|
||||
|
||||
// Lightmapped
|
||||
addPipeline(
|
||||
Key::Builder().withLightmap(),
|
||||
modelLightmapVertex, modelLightmapPixel);
|
||||
|
||||
addPipeline(
|
||||
Key::Builder().withLightmap().withTangents(),
|
||||
modelLightmapNormalMapVertex, modelLightmapNormalMapPixel);
|
||||
|
||||
addPipeline(
|
||||
Key::Builder().withLightmap().withSpecular(),
|
||||
modelLightmapVertex, modelLightmapSpecularMapPixel);
|
||||
|
||||
addPipeline(
|
||||
Key::Builder().withLightmap().withTangents().withSpecular(),
|
||||
modelLightmapNormalMapVertex, modelLightmapNormalSpecularMapPixel);
|
||||
|
||||
|
||||
// Skinned
|
||||
addPipeline(
|
||||
Key::Builder().withSkinned(),
|
||||
skinModelVertex, modelPixel);
|
||||
|
||||
addPipeline(
|
||||
Key::Builder().withSkinned().withTangents(),
|
||||
skinModelNormalMapVertex, modelNormalMapPixel);
|
||||
|
||||
addPipeline(
|
||||
Key::Builder().withSkinned().withSpecular(),
|
||||
skinModelVertex, modelSpecularMapPixel);
|
||||
|
||||
addPipeline(
|
||||
Key::Builder().withSkinned().withTangents().withSpecular(),
|
||||
skinModelNormalMapVertex, modelNormalSpecularMapPixel);
|
||||
|
||||
|
||||
// Skinned and Translucent
|
||||
addPipeline(
|
||||
Key::Builder().withSkinned().withTranslucent(),
|
||||
skinModelVertex, modelTranslucentPixel);
|
||||
|
||||
addPipeline(
|
||||
Key::Builder().withSkinned().withTangents().withTranslucent(),
|
||||
Key::Builder().withSkinned().withTranslucent().withTangents(),
|
||||
skinModelNormalMapVertex, modelTranslucentPixel);
|
||||
|
||||
addPipeline(
|
||||
Key::Builder().withSkinned().withSpecular().withTranslucent(),
|
||||
Key::Builder().withSkinned().withTranslucent().withSpecular(),
|
||||
skinModelVertex, modelTranslucentPixel);
|
||||
|
||||
addPipeline(
|
||||
Key::Builder().withSkinned().withTangents().withSpecular().withTranslucent(),
|
||||
Key::Builder().withSkinned().withTranslucent().withTangents().withSpecular(),
|
||||
skinModelNormalMapVertex, modelTranslucentPixel);
|
||||
|
||||
|
||||
// Depth-only
|
||||
addPipeline(
|
||||
Key::Builder().withDepthOnly(),
|
||||
modelShadowVertex, modelShadowPixel);
|
||||
|
||||
|
||||
addPipeline(
|
||||
Key::Builder().withSkinned().withDepthOnly(),
|
||||
skinModelShadowVertex, modelShadowPixel);
|
||||
}
|
||||
|
||||
|
|
|
@ -72,12 +72,12 @@ float TextRenderer3D::getFontSize() const {
|
|||
}
|
||||
|
||||
void TextRenderer3D::draw(gpu::Batch& batch, float x, float y, const QString& str, const glm::vec4& color,
|
||||
const glm::vec2& bounds) {
|
||||
const glm::vec2& bounds, bool layered) {
|
||||
// The font does all the OpenGL work
|
||||
if (_font) {
|
||||
// Cache color so that the pointer stays valid.
|
||||
_color = color;
|
||||
_font->drawString(batch, x, y, str, &_color, _effectType, bounds);
|
||||
_font->drawString(batch, x, y, str, &_color, _effectType, bounds, layered);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -40,7 +40,7 @@ public:
|
|||
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));
|
||||
const glm::vec2& bounds = glm::vec2(-1.0f), bool layered = false);
|
||||
|
||||
private:
|
||||
TextRenderer3D(const char* family, float pointSize, int weight = -1, bool italic = false,
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<@include gpu/Config.slh@>
|
||||
<$VERSION_HEADER$>
|
||||
// Generated on <$_SCRIBE_DATE$>
|
||||
// model.vert
|
||||
// model.slv
|
||||
// vertex shader
|
||||
//
|
||||
// Created by Andrzej Kapolka on 10/14/13.
|
||||
|
@ -17,19 +17,18 @@
|
|||
<$declareStandardTransform()$>
|
||||
|
||||
const int MAX_TEXCOORDS = 2;
|
||||
|
||||
uniform mat4 texcoordMatrices[MAX_TEXCOORDS];
|
||||
|
||||
out vec3 _color;
|
||||
out float _alpha;
|
||||
out vec2 _texCoord0;
|
||||
out vec4 _position;
|
||||
out vec3 _normal;
|
||||
out vec3 _color;
|
||||
out vec2 _texCoord0;
|
||||
|
||||
void main(void) {
|
||||
// pass along the diffuse color in linear space
|
||||
_color = colorToLinearRGB(inColor.xyz);
|
||||
_alpha = inColor.w;
|
||||
|
||||
// and the texture coordinates
|
||||
_texCoord0 = (texcoordMatrices[0] * vec4(inTexCoord0.st, 0.0, 1.0)).st;
|
||||
|
||||
// standard transform
|
||||
|
|
38
libraries/render-utils/src/model_emissive.slf
Normal file
38
libraries/render-utils/src/model_emissive.slf
Normal file
|
@ -0,0 +1,38 @@
|
|||
<@include gpu/Config.slh@>
|
||||
<$VERSION_HEADER$>
|
||||
// Generated on <$_SCRIBE_DATE$>
|
||||
//
|
||||
// model_emissive.frag
|
||||
// fragment shader
|
||||
//
|
||||
// Created by Zach Pomerantz on 2/3/2016.
|
||||
// Copyright 2016 High Fidelity, Inc.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
<@include DeferredBufferWrite.slh@>
|
||||
<@include model/Material.slh@>
|
||||
|
||||
uniform sampler2D diffuseMap;
|
||||
|
||||
in vec2 _texCoord0;
|
||||
in vec3 _normal;
|
||||
in vec3 _color;
|
||||
in float _alpha;
|
||||
|
||||
void main(void) {
|
||||
vec4 texel = texture(diffuseMap, _texCoord0);
|
||||
|
||||
Material mat = getMaterial();
|
||||
vec3 fragColor = getMaterialDiffuse(mat) * texel.rgb * _color;
|
||||
|
||||
packDeferredFragmentLightmap(
|
||||
normalize(_normal),
|
||||
texel.a,
|
||||
vec3(1.0),
|
||||
getMaterialSpecular(mat),
|
||||
getMaterialShininess(mat),
|
||||
fragColor);
|
||||
}
|
|
@ -11,39 +11,14 @@
|
|||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
<@include model/Material.slh@>
|
||||
|
||||
// Everything about global lighting
|
||||
|
||||
<@include DeferredLighting.slh@>
|
||||
<@include gpu/Transform.slh@>
|
||||
<$declareStandardCameraTransform()$>
|
||||
|
||||
|
||||
// Everything about light
|
||||
<@include model/Light.slh@>
|
||||
|
||||
// The view Matrix
|
||||
//uniform mat4 invViewMat;
|
||||
|
||||
vec4 evalNormalColor(vec3 dir, float opacity) {
|
||||
bool isX = (abs(dir.x) > 0.99);
|
||||
bool isY = (abs(dir.y) > 0.99);
|
||||
bool isZ = (abs(dir.z) > 0.99);
|
||||
if (isX || isY || isZ) {
|
||||
bool negX = (dir.x < -0.995);
|
||||
bool negY = (dir.y < -0.995);
|
||||
bool negZ = (dir.z < -0.995);
|
||||
|
||||
if (negX || negY || negZ) {
|
||||
return vec4(float(isX), float(isY), float(isZ), 0.2);
|
||||
} else {
|
||||
return vec4(float(isX), float(isY), float(isZ), 1.0);
|
||||
}
|
||||
}
|
||||
|
||||
return vec4(0.5 * dir + vec3(0.5), opacity);
|
||||
}
|
||||
<@include gpu/Transform.slh@>
|
||||
<$declareStandardCameraTransform()$>
|
||||
|
||||
vec4 evalGlobalColor(float shadowAttenuation, vec3 position, vec3 normal, vec3 diffuse, vec3 specular, float gloss, float opacity) {
|
||||
|
||||
|
@ -60,42 +35,37 @@ vec4 evalGlobalColor(float shadowAttenuation, vec3 position, vec3 normal, vec3 d
|
|||
|
||||
vec4 shading = evalFragShading(fragNormal, -getLightDirection(light), fragEyeDir, specular, gloss);
|
||||
|
||||
color += vec3(opacity * diffuse + shading.rgb) * shading.w * shadowAttenuation * getLightColor(light) * getLightIntensity(light);
|
||||
color += vec3(diffuse * shading.w * opacity + shading.rgb) * shadowAttenuation * getLightColor(light) * getLightIntensity(light);
|
||||
|
||||
//return vec4(color, opacity);
|
||||
return vec4(color, opacity);
|
||||
//return vec4(diffuse.rgb, opacity);
|
||||
//return evalNormalColor(fragEyeDir, opacity);
|
||||
}
|
||||
|
||||
// the diffuse texture
|
||||
uniform sampler2D diffuseMap;
|
||||
|
||||
in vec4 _position;
|
||||
in vec2 _texCoord0;
|
||||
in vec4 _position;
|
||||
in vec3 _normal;
|
||||
in vec3 _color;
|
||||
in float _alpha;
|
||||
|
||||
out vec4 _fragColor;
|
||||
|
||||
void main(void) {
|
||||
vec3 fragPosition = _position.xyz;
|
||||
|
||||
// Fetch diffuse map
|
||||
vec4 diffuse = texture(diffuseMap, _texCoord0);
|
||||
|
||||
Material mat = getMaterial();
|
||||
vec3 fragPosition = _position.xyz;
|
||||
vec3 fragNormal = normalize(_normal);
|
||||
float fragOpacity = getMaterialOpacity(mat) * diffuse.a;
|
||||
vec3 fragDiffuse = getMaterialDiffuse(mat) * diffuse.rgb * _color;
|
||||
vec3 fragSpecular = getMaterialSpecular(mat);
|
||||
float fragGloss = getMaterialShininess(mat);
|
||||
float fragGloss = getMaterialShininess(mat) / 128;
|
||||
float fragOpacity = getMaterialOpacity(mat) * diffuse.a * _alpha;
|
||||
|
||||
_fragColor = evalGlobalColor(1.0,
|
||||
fragPosition,
|
||||
fragNormal,
|
||||
fragDiffuse,
|
||||
fragSpecular,
|
||||
fragGloss,
|
||||
fragOpacity);
|
||||
fragPosition,
|
||||
fragNormal,
|
||||
fragDiffuse,
|
||||
fragSpecular,
|
||||
fragGloss,
|
||||
fragOpacity);
|
||||
}
|
||||
|
|
33
libraries/render-utils/src/model_translucent_emissive.slf
Normal file
33
libraries/render-utils/src/model_translucent_emissive.slf
Normal file
|
@ -0,0 +1,33 @@
|
|||
<@include gpu/Config.slh@>
|
||||
<$VERSION_HEADER$>
|
||||
// Generated on <$_SCRIBE_DATE$>
|
||||
//
|
||||
// model_translucent_emissive.frag
|
||||
// fragment shader
|
||||
//
|
||||
// Created by Zach Pomerantz on 2/3/2016.
|
||||
// Copyright 2016 High Fidelity, Inc.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
<@include model/Material.slh@>
|
||||
|
||||
uniform sampler2D diffuseMap;
|
||||
|
||||
in vec2 _texCoord0;
|
||||
in vec3 _color;
|
||||
in float _alpha;
|
||||
|
||||
out vec4 _fragColor;
|
||||
|
||||
void main(void) {
|
||||
vec4 diffuse = texture(diffuseMap, _texCoord0);
|
||||
|
||||
Material mat = getMaterial();
|
||||
vec3 fragColor = getMaterialDiffuse(mat) * diffuse.rgb * _color;
|
||||
float fragOpacity = getMaterialOpacity(mat) * diffuse.a * _alpha;
|
||||
|
||||
_fragColor = vec4(fragColor, fragOpacity);
|
||||
}
|
|
@ -1,7 +1,7 @@
|
|||
<@include gpu/Config.slh@>
|
||||
<$VERSION_HEADER$>
|
||||
// Generated on <$_SCRIBE_DATE$>
|
||||
// model.frag
|
||||
// overlay3D.slf
|
||||
// fragment shader
|
||||
//
|
||||
// Created by Sam Gateau on 6/16/15.
|
||||
|
@ -11,20 +11,64 @@
|
|||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
uniform sampler2D diffuseMap;
|
||||
<@include DeferredLighting.slh@>
|
||||
<@include model/Light.slh@>
|
||||
|
||||
in vec2 varTexcoord;
|
||||
<@include gpu/Transform.slh@>
|
||||
<$declareStandardCameraTransform()$>
|
||||
|
||||
in vec3 varEyeNormal;
|
||||
vec4 evalGlobalColor(float shadowAttenuation, vec3 position, vec3 normal, vec3 diffuse, vec3 specular, float gloss, float opacity) {
|
||||
|
||||
in vec4 varColor;
|
||||
out vec4 outFragColor;
|
||||
// Need the light now
|
||||
Light light = getLight();
|
||||
TransformCamera cam = getTransformCamera();
|
||||
vec3 fragNormal;
|
||||
<$transformEyeToWorldDir(cam, normal, fragNormal)$>
|
||||
vec3 fragEyeVectorView = normalize(-position);
|
||||
vec3 fragEyeDir;
|
||||
<$transformEyeToWorldDir(cam, fragEyeVectorView, fragEyeDir)$>
|
||||
|
||||
vec3 color = opacity * diffuse.rgb * getLightColor(light) * getLightAmbientIntensity(light);
|
||||
|
||||
vec4 shading = evalFragShading(fragNormal, -getLightDirection(light), fragEyeDir, specular, gloss);
|
||||
|
||||
color += vec3(diffuse * shading.w * opacity + shading.rgb) * shadowAttenuation * getLightColor(light) * getLightIntensity(light);
|
||||
|
||||
return vec4(color, opacity);
|
||||
}
|
||||
|
||||
uniform sampler2D originalTexture;
|
||||
|
||||
in vec2 _texCoord0;
|
||||
in vec4 _position;
|
||||
in vec3 _normal;
|
||||
in vec3 _color;
|
||||
in float _alpha;
|
||||
|
||||
out vec4 _fragColor;
|
||||
|
||||
void main(void) {
|
||||
vec4 diffuse = texture(diffuseMap, varTexcoord.st);
|
||||
if (diffuse.a < 0.5) {
|
||||
vec4 diffuse = texture(originalTexture, _texCoord0);
|
||||
|
||||
vec3 fragPosition = _position.xyz;
|
||||
vec3 fragNormal = normalize(_normal);
|
||||
vec3 fragDiffuse = diffuse.rgb * _color;
|
||||
vec3 fragSpecular = vec3(0.1);
|
||||
float fragGloss = 10.0 / 128.0;
|
||||
float fragOpacity = diffuse.a;
|
||||
|
||||
if (fragOpacity <= 0.1) {
|
||||
discard;
|
||||
}
|
||||
outFragColor = vec4(varColor * diffuse);
|
||||
|
||||
vec4 color = evalGlobalColor(1.0,
|
||||
fragPosition,
|
||||
fragNormal,
|
||||
fragDiffuse,
|
||||
fragSpecular,
|
||||
fragGloss,
|
||||
fragOpacity);
|
||||
|
||||
// Apply standard tone mapping
|
||||
_fragColor = vec4(pow(color.xyz, vec3(1.0 / 2.2)), color.w);
|
||||
}
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
<$VERSION_HEADER$>
|
||||
// Generated on <$_SCRIBE_DATE$>
|
||||
// overlay3D.slv
|
||||
// vertex shader
|
||||
//
|
||||
// Created by Sam Gateau on 6/16/15.
|
||||
// Copyright 2015 High Fidelity, Inc.
|
||||
|
@ -15,25 +16,21 @@
|
|||
<@include gpu/Transform.slh@>
|
||||
<$declareStandardTransform()$>
|
||||
|
||||
out vec2 varTexcoord;
|
||||
|
||||
// interpolated eye position
|
||||
out vec4 varEyePosition;
|
||||
|
||||
// the interpolated normal
|
||||
out vec3 varEyeNormal;
|
||||
|
||||
out vec4 varColor;
|
||||
out vec3 _color;
|
||||
out float _alpha;
|
||||
out vec2 _texCoord0;
|
||||
out vec4 _position;
|
||||
out vec3 _normal;
|
||||
|
||||
void main(void) {
|
||||
varTexcoord = inTexCoord0.xy;
|
||||
_color = colorToLinearRGB(inColor.xyz);
|
||||
_alpha = inColor.w;
|
||||
|
||||
// pass along the color
|
||||
varColor = colorToLinearRGBA(inColor);
|
||||
_texCoord0 = inTexCoord0.st;
|
||||
|
||||
// standard transform
|
||||
TransformCamera cam = getTransformCamera();
|
||||
TransformObject obj = getTransformObject();
|
||||
<$transformModelToEyeAndClipPos(cam, obj, inPosition, varEyePosition, gl_Position)$>
|
||||
<$transformModelToEyeDir(cam, obj, inNormal.xyz, varEyeNormal.xyz)$>
|
||||
<$transformModelToEyeAndClipPos(cam, obj, inPosition, _position, gl_Position)$>
|
||||
<$transformModelToEyeDir(cam, obj, inNormal.xyz, _normal)$>
|
||||
}
|
||||
|
|
32
libraries/render-utils/src/overlay3D_emissive.slf
Normal file
32
libraries/render-utils/src/overlay3D_emissive.slf
Normal file
|
@ -0,0 +1,32 @@
|
|||
<@include gpu/Config.slh@>
|
||||
<$VERSION_HEADER$>
|
||||
// Generated on <$_SCRIBE_DATE$>
|
||||
//
|
||||
// overlay3D_emissive.frag
|
||||
// fragment shader
|
||||
//
|
||||
// Created by Zach Pomerantz on 2/2/2016.
|
||||
// Copyright 2016 High Fidelity, Inc.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
uniform sampler2D originalTexture;
|
||||
|
||||
in vec2 _texCoord0;
|
||||
in vec3 _color;
|
||||
|
||||
out vec4 _fragColor;
|
||||
|
||||
void main(void) {
|
||||
vec4 diffuse = texture(originalTexture, _texCoord0);
|
||||
|
||||
if (diffuse.a <= 0.1) {
|
||||
discard;
|
||||
}
|
||||
vec4 color = vec4(diffuse.rgb * _color, diffuse.a);
|
||||
|
||||
// Apply standard tone mapping
|
||||
_fragColor = vec4(pow(color.xyz, vec3(1.0 / 2.2)), color.w);
|
||||
}
|
71
libraries/render-utils/src/overlay3D_translucent.slf
Normal file
71
libraries/render-utils/src/overlay3D_translucent.slf
Normal file
|
@ -0,0 +1,71 @@
|
|||
<@include gpu/Config.slh@>
|
||||
<$VERSION_HEADER$>
|
||||
// Generated on <$_SCRIBE_DATE$>
|
||||
//
|
||||
// overlay3D_translucent.slf
|
||||
// fragment shader
|
||||
//
|
||||
// Created by Sam Gateau on 6/16/15.
|
||||
// Copyright 2015 High Fidelity, Inc.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
<@include DeferredLighting.slh@>
|
||||
<@include model/Light.slh@>
|
||||
|
||||
<@include gpu/Transform.slh@>
|
||||
<$declareStandardCameraTransform()$>
|
||||
|
||||
vec4 evalGlobalColor(float shadowAttenuation, vec3 position, vec3 normal, vec3 diffuse, vec3 specular, float gloss, float opacity) {
|
||||
|
||||
// Need the light now
|
||||
Light light = getLight();
|
||||
TransformCamera cam = getTransformCamera();
|
||||
vec3 fragNormal;
|
||||
<$transformEyeToWorldDir(cam, normal, fragNormal)$>
|
||||
vec3 fragEyeVectorView = normalize(-position);
|
||||
vec3 fragEyeDir;
|
||||
<$transformEyeToWorldDir(cam, fragEyeVectorView, fragEyeDir)$>
|
||||
|
||||
vec3 color = opacity * diffuse.rgb * getLightColor(light) * getLightAmbientIntensity(light);
|
||||
|
||||
vec4 shading = evalFragShading(fragNormal, -getLightDirection(light), fragEyeDir, specular, gloss);
|
||||
|
||||
color += vec3(diffuse * shading.w * opacity + shading.rgb) * shadowAttenuation * getLightColor(light) * getLightIntensity(light);
|
||||
|
||||
return vec4(color, opacity);
|
||||
}
|
||||
|
||||
uniform sampler2D originalTexture;
|
||||
|
||||
in vec2 _texCoord0;
|
||||
in vec4 _position;
|
||||
in vec3 _normal;
|
||||
in vec3 _color;
|
||||
in float _alpha;
|
||||
|
||||
out vec4 _fragColor;
|
||||
|
||||
void main(void) {
|
||||
vec4 diffuse = texture(originalTexture, _texCoord0);
|
||||
|
||||
vec3 fragPosition = _position.xyz;
|
||||
vec3 fragNormal = normalize(_normal);
|
||||
vec3 fragDiffuse = diffuse.rgb * _color;
|
||||
vec3 fragSpecular = vec3(0.1);
|
||||
float fragGloss = 10.0 / 128.0;
|
||||
float fragOpacity = diffuse.a * _alpha;
|
||||
|
||||
vec4 color = evalGlobalColor(1.0,
|
||||
fragPosition,
|
||||
fragNormal,
|
||||
fragDiffuse,
|
||||
fragSpecular,
|
||||
fragGloss,
|
||||
fragOpacity);
|
||||
|
||||
// Apply standard tone mapping
|
||||
_fragColor = vec4(pow(color.xyz, vec3(1.0 / 2.2)), color.w);
|
||||
}
|
|
@ -0,0 +1,27 @@
|
|||
<@include gpu/Config.slh@>
|
||||
<$VERSION_HEADER$>
|
||||
// Generated on <$_SCRIBE_DATE$>
|
||||
//
|
||||
// overlay3D_translucent_emissive.frag
|
||||
// fragment shader
|
||||
//
|
||||
// Created by Zach Pomerantz on 2/2/2016.
|
||||
// Copyright 2016 High Fidelity, Inc.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
uniform sampler2D originalTexture;
|
||||
|
||||
in vec2 _texCoord0;
|
||||
in vec3 _color;
|
||||
in float _alpha;
|
||||
|
||||
out vec4 _fragColor;
|
||||
|
||||
void main(void) {
|
||||
vec4 diffuse = texture(originalTexture, _texCoord0);
|
||||
|
||||
_fragColor = vec4(diffuse.rgb * _color, diffuse.a * _alpha);
|
||||
}
|
|
@ -234,6 +234,10 @@ void Font::setupGPU() {
|
|||
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);
|
||||
_pipeline = gpu::Pipeline::create(program, state);
|
||||
|
||||
auto layeredState = std::make_shared<gpu::State>(state->getValues());
|
||||
layeredState->setDepthTest(false);
|
||||
_layeredPipeline = gpu::Pipeline::create(program, layeredState);
|
||||
}
|
||||
|
||||
// Sanity checks
|
||||
|
@ -336,7 +340,7 @@ void Font::rebuildVertices(float x, float y, const QString& str, const glm::vec2
|
|||
}
|
||||
|
||||
void Font::drawString(gpu::Batch& batch, float x, float y, const QString& str, const glm::vec4* color,
|
||||
EffectType effectType, const glm::vec2& bounds) {
|
||||
EffectType effectType, const glm::vec2& bounds, bool layered) {
|
||||
if (str == "") {
|
||||
return;
|
||||
}
|
||||
|
@ -347,7 +351,7 @@ void Font::drawString(gpu::Batch& batch, float x, float y, const QString& str, c
|
|||
|
||||
setupGPU();
|
||||
|
||||
batch.setPipeline(_pipeline);
|
||||
batch.setPipeline(layered ? _layeredPipeline : _pipeline);
|
||||
batch.setResourceTexture(_fontLoc, _texture);
|
||||
batch._glUniform1i(_outlineLoc, (effectType == OUTLINE_EFFECT));
|
||||
batch._glUniform4fv(_colorLoc, 1, (const float*)color);
|
||||
|
|
|
@ -27,7 +27,7 @@ public:
|
|||
// Render string to batch
|
||||
void drawString(gpu::Batch& batch, float x, float y, const QString& str,
|
||||
const glm::vec4* color, EffectType effectType,
|
||||
const glm::vec2& bound);
|
||||
const glm::vec2& bound, bool layered = false);
|
||||
|
||||
static Font* load(QIODevice& fontFile);
|
||||
static Font* load(const QString& family);
|
||||
|
@ -61,6 +61,7 @@ private:
|
|||
|
||||
// gpu structures
|
||||
gpu::PipelinePointer _pipeline;
|
||||
gpu::PipelinePointer _layeredPipeline;
|
||||
gpu::TexturePointer _texture;
|
||||
gpu::Stream::FormatPointer _format;
|
||||
gpu::BufferPointer _verticesBuffer;
|
||||
|
|
|
@ -143,6 +143,7 @@ void renderShape(RenderArgs* args, const ShapePlumberPointer& shapeContext, cons
|
|||
if (args->_pipeline) {
|
||||
item.render(args);
|
||||
}
|
||||
args->_pipeline = nullptr;
|
||||
} else if (key.hasOwnPipeline()) {
|
||||
item.render(args);
|
||||
} else {
|
||||
|
|
|
@ -17,6 +17,12 @@
|
|||
|
||||
using namespace render;
|
||||
|
||||
void ShapePipeline::prepare(gpu::Batch& batch) {
|
||||
if (batchSetter) {
|
||||
batchSetter(*this, batch);
|
||||
}
|
||||
}
|
||||
|
||||
ShapeKey::Filter::Builder::Builder() {
|
||||
_mask.set(OWN_PIPELINE);
|
||||
_mask.set(INVALID);
|
||||
|
@ -90,13 +96,13 @@ const ShapePipelinePointer ShapePlumber::pickPipeline(RenderArgs* args, const Ke
|
|||
PipelinePointer shapePipeline(pipelineIterator->second);
|
||||
auto& batch = args->_batch;
|
||||
|
||||
// Setup the one pipeline (to rule them all)
|
||||
batch->setPipeline(shapePipeline->pipeline);
|
||||
|
||||
// Run the pipeline's BatchSetter on the passed in batch
|
||||
if (shapePipeline->batchSetter) {
|
||||
shapePipeline->batchSetter(*shapePipeline, *batch);
|
||||
}
|
||||
|
||||
// Setup the one pipeline (to rule them all)
|
||||
batch->setPipeline(shapePipeline->pipeline);
|
||||
|
||||
return shapePipeline;
|
||||
}
|
||||
|
|
|
@ -28,7 +28,9 @@ public:
|
|||
SKINNED,
|
||||
STEREO,
|
||||
DEPTH_ONLY,
|
||||
DEPTH_BIAS,
|
||||
WIREFRAME,
|
||||
NO_CULL_FACE,
|
||||
|
||||
OWN_PIPELINE,
|
||||
INVALID,
|
||||
|
@ -39,7 +41,7 @@ public:
|
|||
|
||||
Flags _flags;
|
||||
|
||||
ShapeKey() : _flags{0} {}
|
||||
ShapeKey() : _flags{ 0 } {}
|
||||
ShapeKey(const Flags& flags) : _flags{flags} {}
|
||||
|
||||
class Builder {
|
||||
|
@ -57,7 +59,9 @@ public:
|
|||
Builder& withSkinned() { _flags.set(SKINNED); return (*this); }
|
||||
Builder& withStereo() { _flags.set(STEREO); return (*this); }
|
||||
Builder& withDepthOnly() { _flags.set(DEPTH_ONLY); return (*this); }
|
||||
Builder& withDepthBias() { _flags.set(DEPTH_BIAS); return (*this); }
|
||||
Builder& withWireframe() { _flags.set(WIREFRAME); return (*this); }
|
||||
Builder& withoutCullFace() { _flags.set(NO_CULL_FACE); return (*this); }
|
||||
|
||||
Builder& withOwnPipeline() { _flags.set(OWN_PIPELINE); return (*this); }
|
||||
Builder& invalidate() { _flags.set(INVALID); return (*this); }
|
||||
|
@ -107,9 +111,15 @@ public:
|
|||
Builder& withDepthOnly() { _flags.set(DEPTH_ONLY); _mask.set(DEPTH_ONLY); return (*this); }
|
||||
Builder& withoutDepthOnly() { _flags.reset(DEPTH_ONLY); _mask.set(DEPTH_ONLY); return (*this); }
|
||||
|
||||
Builder& withDepthBias() { _flags.set(DEPTH_BIAS); _mask.set(DEPTH_BIAS); return (*this); }
|
||||
Builder& withoutDepthBias() { _flags.reset(DEPTH_BIAS); _mask.set(DEPTH_BIAS); return (*this); }
|
||||
|
||||
Builder& withWireframe() { _flags.set(WIREFRAME); _mask.set(WIREFRAME); return (*this); }
|
||||
Builder& withoutWireframe() { _flags.reset(WIREFRAME); _mask.set(WIREFRAME); return (*this); }
|
||||
|
||||
Builder& withCullFace() { _flags.reset(NO_CULL_FACE); _mask.set(NO_CULL_FACE); return (*this); }
|
||||
Builder& withoutCullFace() { _flags.set(NO_CULL_FACE); _mask.set(NO_CULL_FACE); return (*this); }
|
||||
|
||||
protected:
|
||||
friend class Filter;
|
||||
Flags _flags{0};
|
||||
|
@ -130,7 +140,9 @@ public:
|
|||
bool isSkinned() const { return _flags[SKINNED]; }
|
||||
bool isStereo() const { return _flags[STEREO]; }
|
||||
bool isDepthOnly() const { return _flags[DEPTH_ONLY]; }
|
||||
bool isDepthBiased() const { return _flags[DEPTH_BIAS]; }
|
||||
bool isWireFrame() const { return _flags[WIREFRAME]; }
|
||||
bool isCullFace() const { return !_flags[NO_CULL_FACE]; }
|
||||
|
||||
bool hasOwnPipeline() const { return _flags[OWN_PIPELINE]; }
|
||||
bool isValid() const { return !_flags[INVALID]; }
|
||||
|
@ -150,21 +162,23 @@ public:
|
|||
};
|
||||
};
|
||||
|
||||
inline QDebug operator<<(QDebug debug, const ShapeKey& renderKey) {
|
||||
if (renderKey.isValid()) {
|
||||
if (renderKey.hasOwnPipeline()) {
|
||||
inline QDebug operator<<(QDebug debug, const ShapeKey& key) {
|
||||
if (key.isValid()) {
|
||||
if (key.hasOwnPipeline()) {
|
||||
debug << "[ShapeKey: OWN_PIPELINE]";
|
||||
} else {
|
||||
debug << "[ShapeKey:"
|
||||
<< "hasLightmap:" << renderKey.hasLightmap()
|
||||
<< "hasTangents:" << renderKey.hasTangents()
|
||||
<< "hasSpecular:" << renderKey.hasSpecular()
|
||||
<< "hasEmissive:" << renderKey.hasEmissive()
|
||||
<< "isTranslucent:" << renderKey.isTranslucent()
|
||||
<< "isSkinned:" << renderKey.isSkinned()
|
||||
<< "isStereo:" << renderKey.isStereo()
|
||||
<< "isDepthOnly:" << renderKey.isDepthOnly()
|
||||
<< "isWireFrame:" << renderKey.isWireFrame()
|
||||
<< "hasLightmap:" << key.hasLightmap()
|
||||
<< "hasTangents:" << key.hasTangents()
|
||||
<< "hasSpecular:" << key.hasSpecular()
|
||||
<< "hasEmissive:" << key.hasEmissive()
|
||||
<< "isTranslucent:" << key.isTranslucent()
|
||||
<< "isSkinned:" << key.isSkinned()
|
||||
<< "isStereo:" << key.isStereo()
|
||||
<< "isDepthOnly:" << key.isDepthOnly()
|
||||
<< "isDepthBiased:" << key.isDepthBiased()
|
||||
<< "isWireFrame:" << key.isWireFrame()
|
||||
<< "isCullFace:" << key.isCullFace()
|
||||
<< "]";
|
||||
}
|
||||
} else {
|
||||
|
@ -209,6 +223,10 @@ public:
|
|||
ShapePipeline(gpu::PipelinePointer pipeline, LocationsPointer locations, BatchSetter batchSetter) :
|
||||
pipeline(pipeline), locations(locations), batchSetter(batchSetter) {}
|
||||
|
||||
// Normally, a pipeline is accessed thorugh pickPipeline. If it needs to be set manually,
|
||||
// after calling setPipeline this method should be called to prepare the pipeline with default buffers.
|
||||
void prepare(gpu::Batch& batch);
|
||||
|
||||
gpu::PipelinePointer pipeline;
|
||||
std::shared_ptr<Locations> locations;
|
||||
|
||||
|
|
|
@ -239,6 +239,7 @@ public:
|
|||
}
|
||||
}
|
||||
|
||||
auto pipeline = geometryCache->getSimplePipeline();
|
||||
for (auto& transform : transforms) {
|
||||
batch.setModelTransform(transform);
|
||||
batch.setupNamedCalls(GRID_INSTANCE, [=](gpu::Batch& batch, gpu::Batch::NamedBatchData& data) {
|
||||
|
|
Loading…
Reference in a new issue