ShapeKey ShapeEntityRenderer::getShapeKey() {
    auto mat = _materials.find("0");
    if (mat != _materials.end() && mat->second.shouldUpdate()) {
        RenderPipelines::updateMultiMaterial(mat->second);
    }

    if (mat != _materials.end() && useMaterialPipeline(mat->second)) {
        graphics::MaterialKey drawMaterialKey = mat->second.getMaterialKey();

        bool isTranslucent = drawMaterialKey.isTranslucent();
        bool hasTangents = drawMaterialKey.isNormalMap();
        bool hasLightmap = drawMaterialKey.isLightmapMap();
        bool isUnlit = drawMaterialKey.isUnlit();

        ShapeKey::Builder builder;
        builder.withMaterial();

        if (isTranslucent) {
            builder.withTranslucent();
        }
        if (hasTangents) {
            builder.withTangents();
        }
        if (hasLightmap) {
            builder.withLightmap();
        }
        if (isUnlit) {
            builder.withUnlit();
        }

        if (_primitiveMode == PrimitiveMode::LINES) {
            builder.withWireframe();
        }

        return builder.build();
    } else {
        ShapeKey::Builder builder;
        bool proceduralReady = resultWithReadLock<bool>([&] {
            return _procedural.isReady();
        });
        if (proceduralReady) {
            builder.withOwnPipeline();
        }
        if (isTransparent()) {
            builder.withTranslucent();
        }

        if (_primitiveMode == PrimitiveMode::LINES) {
            builder.withWireframe();
        }
        return builder.build();
    }
}
void DrawForward::run(const RenderContextPointer& renderContext, const Inputs& inputs) {
    RenderArgs* args = renderContext->args;

    const auto& inItems = inputs.get0();
    const auto& lightingModel = inputs.get1();

    gpu::doInBatch(args->_context, [&](gpu::Batch& batch) {
        args->_batch = &batch;


        // Setup projection
        glm::mat4 projMat;
        Transform viewMat;
        args->getViewFrustum().evalProjectionMatrix(projMat);
        args->getViewFrustum().evalViewTransform(viewMat);
        batch.setProjectionTransform(projMat);
        batch.setViewTransform(viewMat);
        batch.setModelTransform(Transform());

        // Setup lighting model for all items;
        batch.setUniformBuffer(render::ShapePipeline::Slot::LIGHTING_MODEL, lightingModel->getParametersBuffer());

        // From the lighting model define a global shapeKey ORED with individiual keys
        ShapeKey::Builder keyBuilder;
        if (lightingModel->isWireframeEnabled()) {
            keyBuilder.withWireframe();
        }
        ShapeKey globalKey = keyBuilder.build();
        args->_globalShapeKey = globalKey._flags.to_ulong();

        // Render items
        renderStateSortShapes(renderContext, _shapePlumber, inItems, -1, globalKey);

        args->_batch = nullptr;
        args->_globalShapeKey = 0;
    });
}
Example #3
0
ShapeKey ModelMeshPartPayload::getShapeKey() const {
    assert(_model->isLoaded());
    const FBXGeometry& geometry = _model->getFBXGeometry();
    const auto& networkMeshes = _model->getGeometry()->getGeometry()->getMeshes();

    // guard against partially loaded meshes
    if (_meshIndex >= (int)networkMeshes.size() || _meshIndex >= (int)geometry.meshes.size() || _meshIndex >= (int)_model->_meshStates.size()) {
        return ShapeKey::Builder::invalid();
    }

    const FBXMesh& mesh = geometry.meshes.at(_meshIndex);

    // if our index is ever out of range for either meshes or networkMeshes, then skip it, and set our _meshGroupsKnown
    // to false to rebuild out mesh groups.
    if (_meshIndex < 0 || _meshIndex >= (int)networkMeshes.size() || _meshIndex > geometry.meshes.size()) {
        _model->_meshGroupsKnown = false; // regenerate these lists next time around.
        _model->_readyWhenAdded = false; // in case any of our users are using scenes
        _model->invalidCalculatedMeshBoxes(); // if we have to reload, we need to assume our mesh boxes are all invalid
        return ShapeKey::Builder::invalid();
    }


    int vertexCount = mesh.vertices.size();
    if (vertexCount == 0) {
        // sanity check
        return ShapeKey::Builder::invalid(); // FIXME
    }


    model::MaterialKey drawMaterialKey;
    if (_drawMaterial) {
        drawMaterialKey = _drawMaterial->getKey();
    }

    bool isTranslucent = drawMaterialKey.isTranslucent();
    bool hasTangents = drawMaterialKey.isNormalMap() && !mesh.tangents.isEmpty();
    bool hasSpecular = drawMaterialKey.isMetallicMap();
    bool hasLightmap = drawMaterialKey.isLightmapMap();
    bool isUnlit = drawMaterialKey.isUnlit();

    bool isSkinned = _isSkinned;
    bool wireframe = _model->isWireframe();

    if (wireframe) {
        isTranslucent = hasTangents = hasSpecular = hasLightmap = isSkinned = false;
    }

    ShapeKey::Builder builder;
    if (isTranslucent) {
        builder.withTranslucent();
    }
    if (hasTangents) {
        builder.withTangents();
    }
    if (hasSpecular) {
        builder.withSpecular();
    }
    if (hasLightmap) {
        builder.withLightmap();
    }
    if (isUnlit) {
        builder.withUnlit();
    }
    if (isSkinned) {
        builder.withSkinned();
    }
    if (wireframe) {
        builder.withWireframe();
    }
    return builder.build();
}
Example #4
0
ShapeKey ModelMeshPartPayload::getShapeKey() const {

    // guard against partially loaded meshes
    ModelPointer model = _model.lock();
    if (!model || !model->isLoaded() || !model->getGeometry()) {
        return ShapeKey::Builder::invalid();
    }

    const FBXGeometry& geometry = model->getFBXGeometry();
    const auto& networkMeshes = model->getGeometry()->getMeshes();

    // guard against partially loaded meshes
    if (_meshIndex >= (int)networkMeshes.size() || _meshIndex >= (int)geometry.meshes.size() || _meshIndex >= (int)model->_meshStates.size()) {
        return ShapeKey::Builder::invalid();
    }

    const FBXMesh& mesh = geometry.meshes.at(_meshIndex);

    // if our index is ever out of range for either meshes or networkMeshes, then skip it, and set our _meshGroupsKnown
    // to false to rebuild out mesh groups.
    if (_meshIndex < 0 || _meshIndex >= (int)networkMeshes.size() || _meshIndex > geometry.meshes.size()) {
        model->_needsFixupInScene = true; // trigger remove/add cycle
        model->invalidCalculatedMeshBoxes(); // if we have to reload, we need to assume our mesh boxes are all invalid
        return ShapeKey::Builder::invalid();
    }


    int vertexCount = mesh.vertices.size();
    if (vertexCount == 0) {
        // sanity check
        return ShapeKey::Builder::invalid(); // FIXME
    }


    model::MaterialKey drawMaterialKey;
    if (_drawMaterial) {
        drawMaterialKey = _drawMaterial->getKey();
    }

    bool isTranslucent = drawMaterialKey.isTranslucent();
    bool hasTangents = drawMaterialKey.isNormalMap() && !mesh.tangents.isEmpty();
    bool hasSpecular = drawMaterialKey.isMetallicMap();
    bool hasLightmap = drawMaterialKey.isLightmapMap();
    bool isUnlit = drawMaterialKey.isUnlit();

    bool isSkinned = _isSkinned;
    bool wireframe = model->isWireframe();

    if (wireframe) {
        isTranslucent = hasTangents = hasSpecular = hasLightmap = isSkinned = false;
    }

    ShapeKey::Builder builder;
    builder.withMaterial();

    if (isTranslucent || _fadeState != FADE_COMPLETE) {
        builder.withTranslucent();
    }
    if (hasTangents) {
        builder.withTangents();
    }
    if (hasSpecular) {
        builder.withSpecular();
    }
    if (hasLightmap) {
        builder.withLightmap();
    }
    if (isUnlit) {
        builder.withUnlit();
    }
    if (isSkinned) {
        builder.withSkinned();
    }
    if (wireframe) {
        builder.withWireframe();
    }
    return builder.build();
}