gizmos have materials, working on images

This commit is contained in:
HifiExperiments 2021-02-23 20:54:57 -08:00
parent c869554d46
commit 25e4f59d55
8 changed files with 286 additions and 148 deletions

View file

@ -29,6 +29,8 @@
#include "RenderableZoneEntityItem.h"
#include "RenderableMaterialEntityItem.h"
#include "RenderPipelines.h"
using namespace render;
using namespace render::entities;
@ -149,10 +151,11 @@ Item::Bound EntityRenderer::getBound(RenderArgs* args) {
}
ShapeKey EntityRenderer::getShapeKey() {
ShapeKey::Builder builder = ShapeKey::Builder().withOwnPipeline();
if (_primitiveMode == PrimitiveMode::LINES) {
return ShapeKey::Builder().withOwnPipeline().withWireframe();
builder.withWireframe();
}
return ShapeKey::Builder().withOwnPipeline();
return builder.build();
}
render::hifi::Tag EntityRenderer::getTagMask() const {
@ -365,6 +368,7 @@ bool EntityRenderer::needsRenderUpdate() const {
if (_prevIsTransparent != isTransparent()) {
return true;
}
return needsRenderUpdateFromEntity(_entity);
}
@ -486,6 +490,170 @@ void EntityRenderer::removeMaterial(graphics::MaterialPointer material, const st
emit requestRenderUpdate();
}
EntityRenderer::Pipeline EntityRenderer::getPipelineType(const graphics::MultiMaterial& materials) {
if (materials.top().material && materials.top().material->isProcedural() && materials.top().material->isReady()) {
return Pipeline::PROCEDURAL;
}
graphics::MaterialKey drawMaterialKey = materials.getMaterialKey();
if (drawMaterialKey.isEmissive() || drawMaterialKey.isUnlit() || drawMaterialKey.isMetallic() || drawMaterialKey.isScattering()) {
return Pipeline::MATERIAL;
}
// If the material is using any map, we need to use a material ShapeKey
for (int i = 0; i < graphics::Material::MapChannel::NUM_MAP_CHANNELS; i++) {
if (drawMaterialKey.isMapChannel(graphics::Material::MapChannel(i))) {
return Pipeline::MATERIAL;
}
}
return Pipeline::SIMPLE;
}
bool EntityRenderer::needsRenderUpdateFromMaterials() const {
MaterialMap::const_iterator materials;
{
std::lock_guard<std::mutex> lock(_materialsLock);
materials = _materials.find("0");
if (materials == _materials.cend()) {
return false;
}
}
if (materials->second.shouldUpdate()) {
return true;
}
if (materials->second.top().material && materials->second.top().material->isProcedural() && materials->second.top().material->isReady()) {
auto procedural = std::static_pointer_cast<graphics::ProceduralMaterial>(materials->second.top().material);
if (procedural->isFading()) {
return true;
}
}
return false;
}
void EntityRenderer::updateMaterials(bool baseMaterialChanged) {
MaterialMap::iterator materials;
{
std::lock_guard<std::mutex> lock(_materialsLock);
materials = _materials.find("0");
if (materials == _materials.end()) {
return;
}
}
if (baseMaterialChanged) {
materials->second.setNeedsUpdate(true);
}
bool requestUpdate = false;
if (materials->second.top().material && materials->second.top().material->isProcedural() && materials->second.top().material->isReady()) {
auto procedural = std::static_pointer_cast<graphics::ProceduralMaterial>(materials->second.top().material);
if (procedural->isFading()) {
procedural->setIsFading(Interpolate::calculateFadeRatio(procedural->getFadeStartTime()) < 1.0f);
requestUpdate = true;
}
}
if (materials->second.shouldUpdate()) {
RenderPipelines::updateMultiMaterial(materials->second);
requestUpdate = true;
}
if (requestUpdate) {
emit requestRenderUpdate();
}
}
bool EntityRenderer::materialsTransparent() const {
MaterialMap::const_iterator materials;
{
std::lock_guard<std::mutex> lock(_materialsLock);
materials = _materials.find("0");
if (materials == _materials.cend()) {
return false;
}
}
if (materials->second.top().material) {
if (materials->second.top().material->isProcedural() && materials->second.top().material->isReady()) {
auto procedural = std::static_pointer_cast<graphics::ProceduralMaterial>(materials->second.top().material);
if (procedural->isFading()) {
return true;
}
}
if (materials->second.getMaterialKey().isTranslucent()) {
return true;
}
}
return false;
}
Item::Bound EntityRenderer::getMaterialBound(RenderArgs* args) {
MaterialMap::iterator materials;
{
std::lock_guard<std::mutex> lock(_materialsLock);
materials = _materials.find("0");
if (materials == _materials.end()) {
return EntityRenderer::getBound(args);
}
}
if (materials->second.top().material && materials->second.top().material->isProcedural() && materials->second.top().material->isReady()) {
auto procedural = std::static_pointer_cast<graphics::ProceduralMaterial>(materials->second.top().material);
if (procedural->hasVertexShader() && procedural->hasBoundOperator()) {
return procedural->getBound(args);
}
}
return EntityRenderer::getBound(args);
}
EntityRenderer::MaterialMap::iterator EntityRenderer::getAndUpdateMaterials() {
std::lock_guard<std::mutex> lock(_materialsLock);
auto materials = _materials.find("0");
if (materials != _materials.end() && materials->second.shouldUpdate()) {
RenderPipelines::updateMultiMaterial(materials->second);
}
return materials;
}
void EntityRenderer::updateShapeKeyBuilderFromMaterials(ShapeKey::Builder& builder, MaterialMap::iterator materials) const {
{
std::lock_guard<std::mutex> lock(_materialsLock);
if (materials == _materials.end()) {
return;
}
}
builder.withCullFaceMode(materials->second.getCullFaceMode());
auto pipelineType = getPipelineType(materials->second);
if (pipelineType == Pipeline::MATERIAL) {
builder.withMaterial();
graphics::MaterialKey drawMaterialKey = materials->second.getMaterialKey();
if (drawMaterialKey.isNormalMap()) {
builder.withTangents();
}
if (drawMaterialKey.isLightMap()) {
builder.withLightMap();
}
if (drawMaterialKey.isUnlit()) {
builder.withUnlit();
}
} else if (pipelineType == Pipeline::PROCEDURAL) {
builder.withOwnPipeline();
}
}
glm::vec4 EntityRenderer::calculatePulseColor(const glm::vec4& color, const PulsePropertyGroup& pulseProperties, quint64 start) {
if (pulseProperties.getPeriod() == 0.0f || (pulseProperties.getColorMode() == PulseMode::NONE && pulseProperties.getAlphaMode() == PulseMode::NONE)) {
return color;

View file

@ -55,8 +55,14 @@ public:
const uint64_t& getUpdateTime() const { return _updateTime; }
enum class Pipeline {
SIMPLE,
MATERIAL,
PROCEDURAL
};
virtual void addMaterial(graphics::MaterialLayer material, const std::string& parentMaterialName);
virtual void removeMaterial(graphics::MaterialPointer material, const std::string& parentMaterialName);
static Pipeline getPipelineType(const graphics::MultiMaterial& materials);
virtual scriptable::ScriptableModelBase getScriptableModel() override { return scriptable::ScriptableModelBase(); }
@ -119,6 +125,15 @@ protected:
static void makeStatusGetters(const EntityItemPointer& entity, Item::Status::Getters& statusGetters);
const Transform& getModelTransform() const;
// Shared methods for entities that support materials
using MaterialMap = std::unordered_map<std::string, graphics::MultiMaterial>;
bool needsRenderUpdateFromMaterials() const;
void updateMaterials(bool baseMaterialChanged = false);
bool materialsTransparent() const;
Item::Bound getMaterialBound(RenderArgs* args);
MaterialMap::iterator getAndUpdateMaterials();
void updateShapeKeyBuilderFromMaterials(ShapeKey::Builder& builder, MaterialMap::iterator materials) const;
Item::Bound _bound;
SharedSoundPointer _collisionSound;
QUuid _changeHandlerId;
@ -139,8 +154,8 @@ protected:
bool _moving { false };
Transform _renderTransform;
std::unordered_map<std::string, graphics::MultiMaterial> _materials;
std::mutex _materialsLock;
MaterialMap _materials;
mutable std::mutex _materialsLock;
quint64 _created;

View file

@ -11,10 +11,15 @@
#include <DependencyManager.h>
#include <GeometryCache.h>
#include "RenderPipelines.h"
using namespace render;
using namespace render::entities;
GizmoEntityRenderer::GizmoEntityRenderer(const EntityItemPointer& entity) : Parent(entity) {}
GizmoEntityRenderer::GizmoEntityRenderer(const EntityItemPointer& entity) : Parent(entity) {
_material->setCullFaceMode(graphics::MaterialKey::CullFaceMode::CULL_NONE);
addMaterial(graphics::MaterialLayer(_material, 0), "0");
}
GizmoEntityRenderer::~GizmoEntityRenderer() {
auto geometryCache = DependencyManager::get<GeometryCache>();
@ -31,12 +36,8 @@ GizmoEntityRenderer::~GizmoEntityRenderer() {
}
}
bool GizmoEntityRenderer::isTransparent() const {
bool ringTransparent = _gizmoType == GizmoType::RING && (_ringProperties.getInnerStartAlpha() < 1.0f ||
_ringProperties.getInnerEndAlpha() < 1.0f || _ringProperties.getOuterStartAlpha() < 1.0f ||
_ringProperties.getOuterEndAlpha() < 1.0f);
return Parent::isTransparent() || ringTransparent;
bool GizmoEntityRenderer::needsRenderUpdate() const {
return needsRenderUpdateFromMaterials() || Parent::needsRenderUpdate();
}
void GizmoEntityRenderer::doRenderUpdateSynchronousTyped(const ScenePointer& scene, Transaction& transaction, const TypedEntityPointer& entity) {
@ -193,10 +194,20 @@ void GizmoEntityRenderer::doRenderUpdateAsynchronousTyped(const TypedEntityPoint
}
}
}
updateMaterials();
}
bool GizmoEntityRenderer::isTransparent() const {
bool ringTransparent = _gizmoType == GizmoType::RING && (_ringProperties.getInnerStartAlpha() < 1.0f ||
_ringProperties.getInnerEndAlpha() < 1.0f || _ringProperties.getOuterStartAlpha() < 1.0f ||
_ringProperties.getOuterEndAlpha() < 1.0f);
return ringTransparent || Parent::isTransparent() || materialsTransparent();
}
Item::Bound GizmoEntityRenderer::getBound(RenderArgs* args) {
auto bound = Parent::getBound(args);
auto bound = Parent::getMaterialBound(args);
if (_ringProperties.getHasTickMarks()) {
glm::vec3 scale = bound.getScale();
for (int i = 0; i < 3; i += 2) {
@ -221,12 +232,19 @@ Item::Bound GizmoEntityRenderer::getBound(RenderArgs* args) {
ShapeKey GizmoEntityRenderer::getShapeKey() {
auto builder = render::ShapeKey::Builder().withoutCullFace();
auto mat = getAndUpdateMaterials();
if (isTransparent()) {
builder.withTranslucent();
}
if (_primitiveMode == PrimitiveMode::LINES) {
builder.withUnlit().withDepthBias();
builder.withUnlit().withDepthBias().withWireframe();
}
updateShapeKeyBuilderFromMaterials(builder, mat);
return builder.build();
}
@ -249,15 +267,32 @@ void GizmoEntityRenderer::doRender(RenderArgs* args) {
transparent = isTransparent();
});
graphics::MultiMaterial materials;
{
std::lock_guard<std::mutex> lock(_materialsLock);
materials = _materials["0"];
}
bool wireframe = render::ShapeKey(args->_globalShapeKey).isWireframe() || _primitiveMode == PrimitiveMode::LINES;
bool forward = _renderLayer != RenderLayer::WORLD || args->_renderMethod == Args::RenderMethod::FORWARD;
geometryCache->bindSimpleProgram(batch, false, transparent, wireframe, true, true, forward, graphics::MaterialKey::CULL_NONE);
//geometryCache->bindSimpleProgram(batch, false, transparent, wireframe, true, true, forward, materials.getCullFaceMode());
transform.setRotation(BillboardModeHelpers::getBillboardRotation(transform.getTranslation(), transform.getRotation(), _billboardMode,
args->_renderMode == RenderArgs::RenderMode::SHADOW_RENDER_MODE ? BillboardModeHelpers::getPrimaryViewFrustumPosition() : args->getViewFrustum().getPosition(), true));
batch.setModelTransform(transform);
Pipeline pipelineType = getPipelineType(materials);
if (pipelineType == Pipeline::PROCEDURAL) {
auto procedural = std::static_pointer_cast<graphics::ProceduralMaterial>(materials.top().material);
transparent |= procedural->isFading();
procedural->prepare(batch, transform.getTranslation(), transform.getScale(), transform.getRotation(), _created, ProceduralProgramKey(transparent));
} else {
if (RenderPipelines::bindMaterials(materials, batch, args->_renderMode, args->_enableTexturing)) {
args->_details._materialSwitches++;
}
}
// Background circle
geometryCache->renderVertices(batch, wireframe ? gpu::LINE_STRIP : _solidPrimitive, _ringGeometryID);

View file

@ -13,6 +13,8 @@
#include <GizmoEntityItem.h>
#include <procedural/Procedural.h>
namespace render { namespace entities {
class GizmoEntityRenderer : public TypedEntityRenderer<GizmoEntityItem> {
@ -29,10 +31,12 @@ protected:
bool isTransparent() const override;
private:
virtual bool needsRenderUpdate() const override;
virtual void doRenderUpdateSynchronousTyped(const ScenePointer& scene, Transaction& transaction, const TypedEntityPointer& entity) override;
virtual void doRenderUpdateAsynchronousTyped(const TypedEntityPointer& entity) override;
virtual void doRender(RenderArgs* args) override;
std::shared_ptr<graphics::ProceduralMaterial> _material { std::make_shared<graphics::ProceduralMaterial>() };
GizmoType _gizmoType { UNSET_GIZMO_TYPE };
RingGizmoPropertyGroup _ringProperties;
PrimitiveMode _prevPrimitiveMode;

View file

@ -25,8 +25,8 @@ ImageEntityRenderer::~ImageEntityRenderer() {
}
}
bool ImageEntityRenderer::isTransparent() const {
return Parent::isTransparent() || (_textureIsLoaded && _texture->getGPUTexture() && _texture->getGPUTexture()->getUsage().isAlpha()) || _alpha < 1.0f || _pulseProperties.getAlphaMode() != PulseMode::NONE;
bool ImageEntityRenderer::needsRenderUpdate() const {
return needsRenderUpdateFromMaterials() || Parent::needsRenderUpdate();
}
void ImageEntityRenderer::doRenderUpdateSynchronousTyped(const ScenePointer& scene, Transaction& transaction, const TypedEntityPointer& entity) {
@ -63,6 +63,18 @@ void ImageEntityRenderer::doRenderUpdateAsynchronousTyped(const TypedEntityPoint
emit requestRenderUpdate();
}
_textureIsLoaded = _texture && (_texture->isLoaded() || _texture->isFailed());
updateMaterials();
}
bool ImageEntityRenderer::isTransparent() const {
bool imageTransparent = _alpha < 1.0f || _pulseProperties.getAlphaMode() != PulseMode::NONE ||
(_textureIsLoaded && _texture->getGPUTexture() && _texture->getGPUTexture()->getUsage().isAlpha());
return imageTransparent || Parent::isTransparent() || materialsTransparent();
}
Item::Bound ImageEntityRenderer::getBound(RenderArgs* args) {
return Parent::getMaterialBound(args);
}
ShapeKey ImageEntityRenderer::getShapeKey() {

View file

@ -23,11 +23,13 @@ public:
~ImageEntityRenderer();
protected:
Item::Bound getBound(RenderArgs* args) override;
ShapeKey getShapeKey() override;
bool isTransparent() const override;
private:
virtual bool needsRenderUpdate() const override;
virtual void doRenderUpdateSynchronousTyped(const ScenePointer& scene, Transaction& transaction, const TypedEntityPointer& entity) override;
virtual void doRenderUpdateAsynchronousTyped(const TypedEntityPointer& entity) override;
virtual void doRender(RenderArgs* args) override;

View file

@ -29,26 +29,7 @@ ShapeEntityRenderer::ShapeEntityRenderer(const EntityItemPointer& entity) : Pare
}
bool ShapeEntityRenderer::needsRenderUpdate() const {
if (resultWithReadLock<bool>([&] {
auto mat = _materials.find("0");
if (mat != _materials.end() && mat->second.top().material && mat->second.top().material->isProcedural() &&
mat->second.top().material->isReady()) {
auto procedural = std::static_pointer_cast<graphics::ProceduralMaterial>(mat->second.top().material);
if (procedural->isFading()) {
return true;
}
}
if (mat != _materials.end() && mat->second.shouldUpdate()) {
return true;
}
return false;
})) {
return true;
}
return Parent::needsRenderUpdate();
return needsRenderUpdateFromMaterials() || Parent::needsRenderUpdate();
}
void ShapeEntityRenderer::doRenderUpdateSynchronousTyped(const ScenePointer& scene, Transaction& transaction, const TypedEntityPointer& entity) {
@ -94,81 +75,21 @@ void ShapeEntityRenderer::doRenderUpdateAsynchronousTyped(const TypedEntityPoint
materialChanged = true;
}
withReadLock([&] {
auto materials = _materials.find("0");
if (materials != _materials.end()) {
if (materialChanged) {
materials->second.setNeedsUpdate(true);
}
bool requestUpdate = false;
if (materials->second.top().material && materials->second.top().material->isProcedural() && materials->second.top().material->isReady()) {
auto procedural = std::static_pointer_cast<graphics::ProceduralMaterial>(materials->second.top().material);
if (procedural->isFading()) {
procedural->setIsFading(Interpolate::calculateFadeRatio(procedural->getFadeStartTime()) < 1.0f);
requestUpdate = true;
}
}
if (materials->second.shouldUpdate()) {
RenderPipelines::updateMultiMaterial(materials->second);
requestUpdate = true;
}
if (requestUpdate) {
emit requestRenderUpdate();
}
}
});
updateMaterials(materialChanged);
}
bool ShapeEntityRenderer::isTransparent() const {
if (_pulseProperties.getAlphaMode() != PulseMode::NONE) {
return true;
}
auto mat = _materials.find("0");
if (mat != _materials.end() && mat->second.top().material) {
if (mat->second.top().material->isProcedural() && mat->second.top().material->isReady()) {
auto procedural = std::static_pointer_cast<graphics::ProceduralMaterial>(mat->second.top().material);
if (procedural->isFading()) {
return true;
}
}
if (mat->second.getMaterialKey().isTranslucent()) {
return true;
}
}
return Parent::isTransparent();
return _pulseProperties.getAlphaMode() != PulseMode::NONE || Parent::isTransparent() || materialsTransparent();
}
ShapeEntityRenderer::Pipeline ShapeEntityRenderer::getPipelineType(const graphics::MultiMaterial& materials) const {
if (materials.top().material && materials.top().material->isProcedural() && materials.top().material->isReady()) {
return Pipeline::PROCEDURAL;
}
graphics::MaterialKey drawMaterialKey = materials.getMaterialKey();
if (drawMaterialKey.isEmissive() || drawMaterialKey.isUnlit() || drawMaterialKey.isMetallic() || drawMaterialKey.isScattering()) {
return Pipeline::MATERIAL;
}
// If the material is using any map, we need to use a material ShapeKey
for (int i = 0; i < graphics::Material::MapChannel::NUM_MAP_CHANNELS; i++) {
if (drawMaterialKey.isMapChannel(graphics::Material::MapChannel(i))) {
return Pipeline::MATERIAL;
}
}
return Pipeline::SIMPLE;
Item::Bound ShapeEntityRenderer::getBound(RenderArgs* args) {
return Parent::getMaterialBound(args);
}
ShapeKey ShapeEntityRenderer::getShapeKey() {
ShapeKey::Builder builder;
auto mat = _materials.find("0");
if (mat != _materials.end() && mat->second.shouldUpdate()) {
RenderPipelines::updateMultiMaterial(mat->second);
}
auto mat = getAndUpdateMaterials();
if (isTransparent()) {
builder.withTranslucent();
@ -178,71 +99,46 @@ ShapeKey ShapeEntityRenderer::getShapeKey() {
builder.withWireframe();
}
auto pipelineType = getPipelineType(mat->second);
if (pipelineType == Pipeline::MATERIAL) {
builder.withMaterial();
graphics::MaterialKey drawMaterialKey = mat->second.getMaterialKey();
if (drawMaterialKey.isNormalMap()) {
builder.withTangents();
}
if (drawMaterialKey.isLightMap()) {
builder.withLightMap();
}
if (drawMaterialKey.isUnlit()) {
builder.withUnlit();
}
builder.withCullFaceMode(mat->second.getCullFaceMode());
} else if (pipelineType == Pipeline::PROCEDURAL) {
builder.withOwnPipeline();
}
updateShapeKeyBuilderFromMaterials(builder, mat);
return builder.build();
}
Item::Bound ShapeEntityRenderer::getBound(RenderArgs* args) {
auto mat = _materials.find("0");
if (mat != _materials.end() && mat->second.top().material && mat->second.top().material->isProcedural() &&
mat->second.top().material->isReady()) {
auto procedural = std::static_pointer_cast<graphics::ProceduralMaterial>(mat->second.top().material);
if (procedural->hasVertexShader() && procedural->hasBoundOperator()) {
return procedural->getBound(args);
}
}
return Parent::getBound(args);
}
void ShapeEntityRenderer::doRender(RenderArgs* args) {
PerformanceTimer perfTimer("RenderableShapeEntityItem::render");
Q_ASSERT(args->_batch);
gpu::Batch& batch = *args->_batch;
graphics::MultiMaterial materials;
auto geometryCache = DependencyManager::get<GeometryCache>();
GeometryCache::Shape geometryShape = geometryCache->getShapeForEntityShape(_shape);
glm::vec4 outColor;
Pipeline pipelineType;
Transform transform;
withReadLock([&] {
transform = _renderTransform;
materials = _materials["0"];
pipelineType = getPipelineType(materials);
auto& schema = materials.getSchemaBuffer().get<graphics::MultiMaterial::Schema>();
outColor = glm::vec4(ColorUtils::tosRGBVec3(schema._albedo), schema._opacity);
});
graphics::MultiMaterial materials;
{
std::lock_guard<std::mutex> lock(_materialsLock);
materials = _materials["0"];
}
auto& schema = materials.getSchemaBuffer().get<graphics::MultiMaterial::Schema>();
glm::vec4 outColor = glm::vec4(ColorUtils::tosRGBVec3(schema._albedo), schema._opacity);
outColor = EntityRenderer::calculatePulseColor(outColor, _pulseProperties, _created);
if (outColor.a == 0.0f) {
return;
}
bool wireframe = render::ShapeKey(args->_globalShapeKey).isWireframe() || _primitiveMode == PrimitiveMode::LINES;
transform.setRotation(BillboardModeHelpers::getBillboardRotation(transform.getTranslation(), transform.getRotation(), _billboardMode,
args->_renderMode == RenderArgs::RenderMode::SHADOW_RENDER_MODE ? BillboardModeHelpers::getPrimaryViewFrustumPosition() : args->getViewFrustum().getPosition(),
_shape < entity::Shape::Cube || _shape > entity::Shape::Icosahedron));
batch.setModelTransform(transform);
Pipeline pipelineType = getPipelineType(materials);
if (pipelineType == Pipeline::PROCEDURAL) {
auto procedural = std::static_pointer_cast<graphics::ProceduralMaterial>(materials.top().material);
outColor = procedural->getColor(outColor);
@ -251,7 +147,7 @@ void ShapeEntityRenderer::doRender(RenderArgs* args) {
procedural->prepare(batch, _position, _dimensions, _orientation, _created, ProceduralProgramKey(outColor.a < 1.0f));
});
if (render::ShapeKey(args->_globalShapeKey).isWireframe() || _primitiveMode == PrimitiveMode::LINES) {
if (wireframe) {
geometryCache->renderWireShape(batch, geometryShape, outColor);
} else {
geometryCache->renderShape(batch, geometryShape, outColor);
@ -259,12 +155,21 @@ void ShapeEntityRenderer::doRender(RenderArgs* args) {
} else if (pipelineType == Pipeline::SIMPLE) {
// FIXME, support instanced multi-shape rendering using multidraw indirect
outColor.a *= _isFading ? Interpolate::calculateFadeRatio(_fadeStartTime) : 1.0f;
render::ShapePipelinePointer pipeline = geometryCache->getShapePipelinePointer(outColor.a < 1.0f, false,
_renderLayer != RenderLayer::WORLD || args->_renderMethod == Args::RenderMethod::FORWARD, materials.top().material->getCullFaceMode());
if (render::ShapeKey(args->_globalShapeKey).isWireframe() || _primitiveMode == PrimitiveMode::LINES) {
geometryCache->renderWireShapeInstance(args, batch, geometryShape, outColor, pipeline);
bool forward = _renderLayer != RenderLayer::WORLD || args->_renderMethod == Args::RenderMethod::FORWARD;
if (outColor.a >= 1.0f) {
render::ShapePipelinePointer pipeline = geometryCache->getShapePipelinePointer(false, wireframe,
forward, materials.top().material->getCullFaceMode());
if (wireframe) {
geometryCache->renderWireShapeInstance(args, batch, geometryShape, outColor, pipeline);
} else {
geometryCache->renderSolidShapeInstance(args, batch, geometryShape, outColor, pipeline);
}
} else {
geometryCache->renderSolidShapeInstance(args, batch, geometryShape, outColor, pipeline);
if (wireframe) {
geometryCache->renderWireShape(batch, geometryShape, outColor);
} else {
geometryCache->renderShape(batch, geometryShape, outColor);
}
}
} else {
if (RenderPipelines::bindMaterials(materials, batch, args->_renderMode, args->_enableTexturing)) {

View file

@ -35,9 +35,6 @@ private:
virtual void doRender(RenderArgs* args) override;
virtual bool isTransparent() const override;
enum Pipeline { SIMPLE, MATERIAL, PROCEDURAL };
Pipeline getPipelineType(const graphics::MultiMaterial& materials) const;
QString _proceduralData;
entity::Shape _shape { entity::Sphere };