示例#1
0
void RenderableZoneEntityItem::render(RenderArgs* args) {
    if (_drawZoneBoundaries) {
        switch (getShapeType()) {
            case SHAPE_TYPE_COMPOUND: {
                updateGeometry();
                
                if (_model && _model->isActive()) {
                    PerformanceTimer perfTimer("zone->renderCompound");
                    glPushMatrix();
                    _model->renderInScene(getLocalRenderAlpha(), args);
                    glPopMatrix();
                }
                break;
            }
            case SHAPE_TYPE_BOX:
            case SHAPE_TYPE_SPHERE: {
                PerformanceTimer perfTimer("zone->renderPrimitive");
                glm::vec3 position = getPosition();
                glm::vec3 center = getCenter();
                glm::vec3 dimensions = getDimensions();
                glm::quat rotation = getRotation();
                
                glm::vec4 DEFAULT_COLOR(1.0f, 1.0f, 1.0f, getLocalRenderAlpha());
                
                glPushMatrix(); {
                    glTranslatef(position.x, position.y, position.z);
                    glm::vec3 axis = glm::axis(rotation);
                    glRotatef(glm::degrees(glm::angle(rotation)), axis.x, axis.y, axis.z);
                    glPushMatrix(); {
                        glm::vec3 positionToCenter = center - position;
                        glTranslatef(positionToCenter.x, positionToCenter.y, positionToCenter.z);
                        glScalef(dimensions.x, dimensions.y, dimensions.z);
                        
                        auto deferredLightingEffect = DependencyManager::get<DeferredLightingEffect>();
                        
                        if (getShapeType() == SHAPE_TYPE_SPHERE) {
                            const int SLICES = 15;
                            const int STACKS = 15;
                            deferredLightingEffect->renderWireSphere(0.5f, SLICES, STACKS, DEFAULT_COLOR);
                        } else {
                            deferredLightingEffect->renderWireCube(1.0f, DEFAULT_COLOR);
                        }
                    } glPopMatrix();
                } glPopMatrix();
                break;
            }
            default:
                // Not handled
                break;
        }
    }
}
示例#2
0
void RenderableBoxEntityItem::render(RenderArgs* args) {
    PerformanceTimer perfTimer("RenderableBoxEntityItem::render");
    assert(getType() == EntityTypes::Box);
    glm::vec3 position = getPositionInMeters();
    glm::vec3 center = getCenter() * (float)TREE_SCALE;
    glm::vec3 dimensions = getDimensions() * (float)TREE_SCALE;
    glm::quat rotation = getRotation();

    const float MAX_COLOR = 255.0f;

    glColor4f(getColor()[RED_INDEX] / MAX_COLOR, getColor()[GREEN_INDEX] / MAX_COLOR, 
                    getColor()[BLUE_INDEX] / MAX_COLOR, getLocalRenderAlpha());

    glPushMatrix();
        glTranslatef(position.x, position.y, position.z);
        glm::vec3 axis = glm::axis(rotation);
        glRotatef(glm::degrees(glm::angle(rotation)), axis.x, axis.y, axis.z);
        glPushMatrix();
            glm::vec3 positionToCenter = center - position;
            glTranslatef(positionToCenter.x, positionToCenter.y, positionToCenter.z);
            glScalef(dimensions.x, dimensions.y, dimensions.z);
            DependencyManager::get<DeferredLightingEffect>()->renderSolidCube(1.0f);
        glPopMatrix();
    glPopMatrix();

};
void RenderableBoxEntityItem::render(RenderArgs* args) {
    PerformanceTimer perfTimer("RenderableBoxEntityItem::render");
    Q_ASSERT(getType() == EntityTypes::Box);
    Q_ASSERT(args->_batch);

    if (!_procedural) {
        _procedural.reset(new Procedural(this->getUserData()));
        _procedural->_vertexSource = simple_vert;
        _procedural->_fragmentSource = simple_frag;
        _procedural->_state->setCullMode(gpu::State::CULL_NONE);
        _procedural->_state->setDepthTest(true, true, gpu::LESS_EQUAL);
        _procedural->_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::Batch& batch = *args->_batch;
    glm::vec4 cubeColor(toGlm(getXColor()), getLocalRenderAlpha());

    if (_procedural->ready()) {
        batch.setModelTransform(getTransformToCenter()); // we want to include the scale as well
        _procedural->prepare(batch, this->getDimensions());
        auto color = _procedural->getColor(cubeColor);
        batch._glColor4f(color.r, color.g, color.b, color.a);
        DependencyManager::get<GeometryCache>()->renderCube(batch);
    } else {
        DependencyManager::get<DeferredLightingEffect>()->renderSolidCubeInstance(batch, getTransformToCenter(), cubeColor);
    }

    RenderableDebugableEntityItem::render(this, args);
};
bool RenderableShapeEntityItem::isTransparent() {
    if (_procedural && _procedural->isFading()) {
        float isFading = Interpolate::calculateFadeRatio(_procedural->getFadeStartTime()) < 1.0f;
        _procedural->setIsFading(isFading);
        return isFading;
    } else {
        return getLocalRenderAlpha() < 1.0f || EntityItem::isTransparent();
    }
}
void RenderableShapeEntityItem::render(RenderArgs* args) {
    PerformanceTimer perfTimer("RenderableShapeEntityItem::render");
    //Q_ASSERT(getType() == EntityTypes::Shape);
    Q_ASSERT(args->_batch);
    checkFading();

    if (!_procedural) {
        _procedural.reset(new Procedural(getUserData()));
        _procedural->_vertexSource = simple_vert;
        _procedural->_fragmentSource = simple_frag;
        _procedural->_opaqueState->setCullMode(gpu::State::CULL_NONE);
        _procedural->_opaqueState->setDepthTest(true, true, gpu::LESS_EQUAL);
        PrepareStencil::testMaskDrawShape(*_procedural->_opaqueState);
        _procedural->_opaqueState->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::Batch& batch = *args->_batch;
    glm::vec4 color(toGlm(getXColor()), getLocalRenderAlpha());
    bool success;
    Transform modelTransform = getTransformToCenter(success);
    if (!success) {
        return;
    }
    if (_shape == entity::Sphere) {
        modelTransform.postScale(SPHERE_ENTITY_SCALE);
    }
    batch.setModelTransform(modelTransform); // use a transform with scale, rotation, registration point and translation
    if (_procedural->ready()) {
        _procedural->prepare(batch, getPosition(), getDimensions(), getOrientation());
        auto outColor = _procedural->getColor(color);
        outColor.a *= _procedural->isFading() ? Interpolate::calculateFadeRatio(_procedural->getFadeStartTime()) : 1.0f;
        batch._glColor4f(outColor.r, outColor.g, outColor.b, outColor.a);
        if (render::ShapeKey(args->_globalShapeKey).isWireframe()) {
            DependencyManager::get<GeometryCache>()->renderWireShape(batch, MAPPING[_shape]);
        } else {
            DependencyManager::get<GeometryCache>()->renderShape(batch, MAPPING[_shape]);
        }
    } else {
        // FIXME, support instanced multi-shape rendering using multidraw indirect
        color.a *= _isFading ? Interpolate::calculateFadeRatio(_fadeStartTime) : 1.0f;
        auto geometryCache = DependencyManager::get<GeometryCache>();
        auto pipeline = color.a < 1.0f ? geometryCache->getTransparentShapePipeline() : geometryCache->getOpaqueShapePipeline();
        
        if (render::ShapeKey(args->_globalShapeKey).isWireframe()) {
            geometryCache->renderWireShapeInstance(args, batch, MAPPING[_shape], color, pipeline);
        } else {
            geometryCache->renderSolidShapeInstance(args, batch, MAPPING[_shape], color, pipeline);
        }
    }

    static const auto triCount = DependencyManager::get<GeometryCache>()->getShapeTriangleCount(MAPPING[_shape]);
    args->_details._trianglesRendered += (int)triCount;
}
void RenderableLineEntityItem::updateGeometry() {
    auto geometryCache = DependencyManager::get<GeometryCache>();
    if (_lineVerticesID == GeometryCache::UNKNOWN_ID) {
        _lineVerticesID = geometryCache ->allocateID();
    }
    if (_pointsChanged) {
        glm::vec4 lineColor(toGlm(getXColor()), getLocalRenderAlpha());
        geometryCache->updateVertices(_lineVerticesID, getLinePoints(), lineColor);
        _pointsChanged = false;
    }
}
void RenderableParticleEffectEntityItem::updateQuads(RenderArgs* args, bool textured) {
    float particleRadius = getParticleRadius();
    glm::vec4 particleColor(toGlm(getXColor()), getLocalRenderAlpha());
    
    glm::vec3 upOffset = args->_viewFrustum->getUp() * particleRadius;
    glm::vec3 rightOffset = args->_viewFrustum->getRight() * particleRadius;
    
    QVector<glm::vec3> vertices;
    QVector<glm::vec3> positions;
    QVector<glm::vec2> textureCoords;
    vertices.reserve(getLivingParticleCount() * VERTS_PER_PARTICLE);
    
    if (textured) {
        textureCoords.reserve(getLivingParticleCount() * VERTS_PER_PARTICLE);
    }
    positions.reserve(getLivingParticleCount());
   
    
    for (quint32 i = _particleHeadIndex; i != _particleTailIndex; i = (i + 1) % _maxParticles) {
        positions.append(_particlePositions[i]);
        if (textured) {        
            textureCoords.append(glm::vec2(0, 1));
            textureCoords.append(glm::vec2(1, 1));
            textureCoords.append(glm::vec2(1, 0));
            textureCoords.append(glm::vec2(0, 0));
        }
    }
        
    // sort particles back to front
    ::zSortAxis = args->_viewFrustum->getDirection();
    qSort(positions.begin(), positions.end(), zSort);
    
    for (int i = 0; i < positions.size(); i++) {
        glm::vec3 pos = (textured) ? positions[i] : _particlePositions[i];

        // generate corners of quad aligned to face the camera.
        vertices.append(pos + rightOffset + upOffset);
        vertices.append(pos - rightOffset + upOffset);
        vertices.append(pos - rightOffset - upOffset);
        vertices.append(pos + rightOffset - upOffset);
   
    }
    
    if (textured) {
        DependencyManager::get<GeometryCache>()->updateVertices(_cacheID, vertices, textureCoords, particleColor);
    } else {
        DependencyManager::get<GeometryCache>()->updateVertices(_cacheID, vertices, particleColor);
    }
}
示例#8
0
void RenderableLineEntityItem::render(RenderArgs* args) {
    PerformanceTimer perfTimer("RenderableLineEntityItem::render");
    assert(getType() == EntityTypes::Line);
    glm::vec3 position = getPosition();
    glm::vec3 dimensions = getDimensions();
    glm::quat rotation = getRotation();
    glm::vec4 lineColor(toGlm(getXColor()), getLocalRenderAlpha());
    glPushMatrix();
        glTranslatef(position.x, position.y, position.z);
        glm::vec3 axis = glm::axis(rotation);
        glRotatef(glm::degrees(glm::angle(rotation)), axis.x, axis.y, axis.z);
        glm::vec3 p1 = {0.0f, 0.0f, 0.0f};
        glm::vec3& p2 = dimensions;
        DependencyManager::get<DeferredLightingEffect>()->renderLine(p1, p2, lineColor, lineColor);
    glPopMatrix();
    RenderableDebugableEntityItem::render(this, args);
};
示例#9
0
void RenderableBoxEntityItem::render(RenderArgs* args) {
    PerformanceTimer perfTimer("RenderableBoxEntityItem::render");
    Q_ASSERT(getType() == EntityTypes::Box);
    Q_ASSERT(args->_batch);
    gpu::Batch& batch = *args->_batch;
    batch.setModelTransform(getTransformToCenter()); // we want to include the scale as well
    
    if (!_procedural) {
        _procedural.reset(new ProceduralInfo(this));
    }

    if (_procedural->ready()) {
        _procedural->prepare(batch);
        DependencyManager::get<GeometryCache>()->renderUnitCube(batch);
    } else {
        glm::vec4 cubeColor(toGlm(getXColor()), getLocalRenderAlpha());
        DependencyManager::get<DeferredLightingEffect>()->renderSolidCube(batch, 1.0f, cubeColor);
    }

    RenderableDebugableEntityItem::render(this, args);
};
示例#10
0
void RenderableBoxEntityItem::render(RenderArgs* args) {
    PerformanceTimer perfTimer("RenderableBoxEntityItem::render");
    assert(getType() == EntityTypes::Box);
    glm::vec3 position = getPosition();
    glm::vec3 center = getCenter();
    glm::vec3 dimensions = getDimensions();
    glm::quat rotation = getRotation();

    const float MAX_COLOR = 255.0f;

    glm::vec4 cubeColor(getColor()[RED_INDEX] / MAX_COLOR, getColor()[GREEN_INDEX] / MAX_COLOR,
                    getColor()[BLUE_INDEX] / MAX_COLOR, getLocalRenderAlpha());


    bool debugSimulationOwnership = args->_debugFlags & RenderArgs::RENDER_DEBUG_SIMULATION_OWNERSHIP;
    bool highlightSimulationOwnership = false;
    if (debugSimulationOwnership) {
        auto nodeList = DependencyManager::get<NodeList>();
        const QUuid& myNodeID = nodeList->getSessionUUID();
        highlightSimulationOwnership = (getSimulatorID() == myNodeID);
    }

    glPushMatrix();
        glTranslatef(position.x, position.y, position.z);
        glm::vec3 axis = glm::axis(rotation);
        glRotatef(glm::degrees(glm::angle(rotation)), axis.x, axis.y, axis.z);
        glPushMatrix();
            glm::vec3 positionToCenter = center - position;
            glTranslatef(positionToCenter.x, positionToCenter.y, positionToCenter.z);
            glScalef(dimensions.x, dimensions.y, dimensions.z);
            if (highlightSimulationOwnership) {
                DependencyManager::get<DeferredLightingEffect>()->renderWireCube(1.0f, cubeColor);
            } else {
                DependencyManager::get<DeferredLightingEffect>()->renderSolidCube(1.0f, cubeColor);
            }
        glPopMatrix();
    glPopMatrix();

    RenderableDebugableEntityItem::render(this, args);
};
void RenderableBoxEntityItem::render(RenderArgs* args) {
    PerformanceTimer perfTimer("RenderableBoxEntityItem::render");
    Q_ASSERT(getType() == EntityTypes::Box);
    Q_ASSERT(args->_batch);


    if (!_procedural) {
        _procedural.reset(new Procedural(this->getUserData()));
        _procedural->_vertexSource = simple_vert;
        _procedural->_fragmentSource = simple_frag;
        _procedural->_state->setCullMode(gpu::State::CULL_NONE);
        _procedural->_state->setDepthTest(true, true, gpu::LESS_EQUAL);
        _procedural->_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::Batch& batch = *args->_batch;
    glm::vec4 cubeColor(toGlm(getXColor()), getLocalRenderAlpha());

    bool success;
    auto transToCenter = getTransformToCenter(success);
    if (!success) {
        return;
    }

    batch.setModelTransform(transToCenter); // we want to include the scale as well
    if (_procedural->ready()) {
        _procedural->prepare(batch, getPosition(), getDimensions());
        auto color = _procedural->getColor(cubeColor);
        batch._glColor4f(color.r, color.g, color.b, color.a);
        DependencyManager::get<GeometryCache>()->renderCube(batch);
    } else {
        DependencyManager::get<GeometryCache>()->renderSolidCubeInstance(batch, cubeColor);
    }
    static const auto triCount = DependencyManager::get<GeometryCache>()->getCubeTriangleCount();
    args->_details._trianglesRendered += (int)triCount;
}
void RenderableParticleEffectEntityItem::updateRenderItem() {
    if (!_scene) {
        return;
    }

    // make a copy of each particle's details
    std::vector<ParticleDetails> particleDetails;
    particleDetails.reserve(getLivingParticleCount());
    for (quint32 i = _particleHeadIndex; i != _particleTailIndex; i = (i + 1) % _maxParticles) {
        auto xcolor = _particleColors[i];
        auto alpha = (uint8_t)(glm::clamp(_particleAlphas[i] * getLocalRenderAlpha(), 0.0f, 1.0f) * 255.0f);
        auto rgba = toRGBA(xcolor.red, xcolor.green, xcolor.blue, alpha);
        particleDetails.push_back(ParticleDetails(_particlePositions[i], _particleRadiuses[i], rgba));
    }

    // sort particles back to front
    // NOTE: this is view frustum might be one frame out of date.
    auto frustum = AbstractViewStateInterface::instance()->getCurrentViewFrustum();
    ::zSortAxis = frustum->getDirection();
    qSort(particleDetails.begin(), particleDetails.end(), zSort);

    // allocate vertices
    _vertices.clear();

    // build vertices from particle positions and radiuses
    glm::vec3 frustumPosition = frustum->getPosition();
    for (auto&& particle : particleDetails) {
        glm::vec3 particleDirection = particle.position - frustumPosition;
        glm::vec3 right = glm::normalize(glm::cross(glm::vec3(0.0f, 1.0f, 0.0f), particleDirection));
        glm::vec3 up = glm::normalize(glm::cross(right, particleDirection));

        glm::vec3 upOffset = up * particle.radius;
        glm::vec3 rightOffset = right * particle.radius;
        // generate corners of quad aligned to face the camera.
        _vertices.emplace_back(particle.position + rightOffset + upOffset, glm::vec2(1.0f, 1.0f), particle.rgba);
        _vertices.emplace_back(particle.position - rightOffset + upOffset, glm::vec2(0.0f, 1.0f), particle.rgba);
        _vertices.emplace_back(particle.position - rightOffset - upOffset, glm::vec2(0.0f, 0.0f), particle.rgba);
        _vertices.emplace_back(particle.position + rightOffset - upOffset, glm::vec2(1.0f, 0.0f), particle.rgba);
    }

    render::PendingChanges pendingChanges;
    pendingChanges.updateItem<ParticlePayload>(_renderItemId, [this](ParticlePayload& payload) {
        // update vertex buffer
        auto vertexBuffer = payload.getVertexBuffer();
        size_t numBytes = sizeof(Vertex) * _vertices.size();

        if (numBytes == 0) {
            vertexBuffer->resize(0);
            auto indexBuffer = payload.getIndexBuffer();
            indexBuffer->resize(0);
            return;
        }

        vertexBuffer->resize(numBytes);
        gpu::Byte* data = vertexBuffer->editData();
        memcpy(data, &(_vertices[0]), numBytes);

        // FIXME, don't update index buffer if num particles has not changed.
        // update index buffer
        auto indexBuffer = payload.getIndexBuffer();
        const size_t NUM_VERTS_PER_PARTICLE = 4;
        const size_t NUM_INDICES_PER_PARTICLE = 6;
        auto numQuads = (_vertices.size() / NUM_VERTS_PER_PARTICLE);
        numBytes = sizeof(uint16_t) * numQuads * NUM_INDICES_PER_PARTICLE;
        indexBuffer->resize(numBytes);
        data = indexBuffer->editData();
        auto indexPtr = reinterpret_cast<uint16_t*>(data);
        for (size_t i = 0; i < numQuads; ++i) {
            indexPtr[i * NUM_INDICES_PER_PARTICLE + 0] = i * NUM_VERTS_PER_PARTICLE + 0;
            indexPtr[i * NUM_INDICES_PER_PARTICLE + 1] = i * NUM_VERTS_PER_PARTICLE + 1;
            indexPtr[i * NUM_INDICES_PER_PARTICLE + 2] = i * NUM_VERTS_PER_PARTICLE + 3;
            indexPtr[i * NUM_INDICES_PER_PARTICLE + 3] = i * NUM_VERTS_PER_PARTICLE + 1;
            indexPtr[i * NUM_INDICES_PER_PARTICLE + 4] = i * NUM_VERTS_PER_PARTICLE + 2;
            indexPtr[i * NUM_INDICES_PER_PARTICLE + 5] = i * NUM_VERTS_PER_PARTICLE + 3;
        }

        // update transform
        glm::quat rot = _transform.getRotation();
        glm::vec3 pos = _transform.getTranslation();
        Transform t;
        t.setRotation(rot);
        payload.setModelTransform(t);

        // transform _particleMinBound and _particleMaxBound corners into world coords
        glm::vec3 d = _particleMaxBound - _particleMinBound;
        const size_t NUM_BOX_CORNERS = 8;
        glm::vec3 corners[NUM_BOX_CORNERS] = {
            pos + rot * (_particleMinBound + glm::vec3(0.0f, 0.0f, 0.0f)),
            pos + rot * (_particleMinBound + glm::vec3(d.x, 0.0f, 0.0f)),
            pos + rot * (_particleMinBound + glm::vec3(0.0f, d.y, 0.0f)),
            pos + rot * (_particleMinBound + glm::vec3(d.x, d.y, 0.0f)),
            pos + rot * (_particleMinBound + glm::vec3(0.0f, 0.0f, d.z)),
            pos + rot * (_particleMinBound + glm::vec3(d.x, 0.0f, d.z)),
            pos + rot * (_particleMinBound + glm::vec3(0.0f, d.y, d.z)),
            pos + rot * (_particleMinBound + glm::vec3(d.x, d.y, d.z))
        };
        glm::vec3 min(FLT_MAX, FLT_MAX, FLT_MAX);
        glm::vec3 max = -min;
        for (size_t i = 0; i < NUM_BOX_CORNERS; i++) {
            min.x = std::min(min.x, corners[i].x);
            min.y = std::min(min.y, corners[i].y);
            min.z = std::min(min.z, corners[i].z);
            max.x = std::max(max.x, corners[i].x);
            max.y = std::max(max.y, corners[i].y);
            max.z = std::max(max.z, corners[i].z);
        }
        AABox bound(min, max - min);
        payload.setBound(bound);

        bool textured = _texture && _texture->isLoaded();
        if (textured) {
            payload.setTexture(_texture->getGPUTexture());
            payload.setPipeline(_texturedPipeline);
        } else {
            payload.setTexture(nullptr);
            payload.setPipeline(_untexturedPipeline);
        }
    });

    _scene->enqueuePendingChanges(pendingChanges);
}
void RenderableModelEntityItem::render(RenderArgs* args) {
    PerformanceTimer perfTimer("RMEIrender");
    assert(getType() == EntityTypes::Model);
    
    bool drawAsModel = hasModel();

    glm::vec3 position = getPosition() * (float)TREE_SCALE;
    float size = getSize() * (float)TREE_SCALE;
    glm::vec3 dimensions = getDimensions() * (float)TREE_SCALE;
    
    if (drawAsModel) {
        glPushMatrix();
        {
            float alpha = getLocalRenderAlpha();

            if (!_model || _needsModelReload) {
                // TODO: this getModel() appears to be about 3% of model render time. We should optimize
                PerformanceTimer perfTimer("getModel");
                EntityTreeRenderer* renderer = static_cast<EntityTreeRenderer*>(args->_renderer);
                getModel(renderer);
            }
            
            if (_model) {
                // handle animations..
                if (hasAnimation()) {
                    if (!jointsMapped()) {
                        QStringList modelJointNames = _model->getJointNames();
                        mapJoints(modelJointNames);
                    }

                    if (jointsMapped()) {
                        QVector<glm::quat> frameData = getAnimationFrame();
                        for (int i = 0; i < frameData.size(); i++) {
                            _model->setJointState(i, true, frameData[i]);
                        }
                    }
                }

                glm::quat rotation = getRotation();
                if (needsSimulation() && _model->isActive()) {
                    _model->setScaleToFit(true, dimensions);
                    _model->setSnapModelToRegistrationPoint(true, getRegistrationPoint());
                    _model->setRotation(rotation);
                    _model->setTranslation(position);
                    
                    // make sure to simulate so everything gets set up correctly for rendering
                    {
                        PerformanceTimer perfTimer("_model->simulate");
                        _model->simulate(0.0f);
                    }
                    _needsInitialSimulation = false;
                }

                // TODO: should we allow entityItems to have alpha on their models?
                Model::RenderMode modelRenderMode = args->_renderMode == OctreeRenderer::SHADOW_RENDER_MODE 
                                                        ? Model::SHADOW_RENDER_MODE : Model::DEFAULT_RENDER_MODE;
        
                if (_model->isActive()) {
                    // TODO: this is the majority of model render time. And rendering of a cube model vs the basic Box render
                    // is significantly more expensive. Is there a way to call this that doesn't cost us as much? 
                    PerformanceTimer perfTimer("model->render");
                    _model->render(alpha, modelRenderMode, args);
                } else {
                    // if we couldn't get a model, then just draw a cube
                    glColor3ub(getColor()[RED_INDEX],getColor()[GREEN_INDEX],getColor()[BLUE_INDEX]);
                    glPushMatrix();
                        glTranslatef(position.x, position.y, position.z);
                        Application::getInstance()->getDeferredLightingEffect()->renderWireCube(size);
                    glPopMatrix();
                }
            } else {
                // if we couldn't get a model, then just draw a cube
                glColor3ub(getColor()[RED_INDEX],getColor()[GREEN_INDEX],getColor()[BLUE_INDEX]);
                glPushMatrix();
                    glTranslatef(position.x, position.y, position.z);
                    Application::getInstance()->getDeferredLightingEffect()->renderWireCube(size);
                glPopMatrix();
            }
        }
        glPopMatrix();
    } else {
        glColor3ub(getColor()[RED_INDEX],getColor()[GREEN_INDEX],getColor()[BLUE_INDEX]);
        glPushMatrix();
        glTranslatef(position.x, position.y, position.z);
        Application::getInstance()->getDeferredLightingEffect()->renderWireCube(size);
        glPopMatrix();
    }
}
示例#14
0
void RenderableBoxEntityItem::render(RenderArgs* args) {
    PerformanceTimer perfTimer("RenderableBoxEntityItem::render");
    assert(getType() == EntityTypes::Box);
    glm::vec3 position = getPositionInMeters();
    glm::vec3 center = getCenter() * (float)TREE_SCALE;
    glm::vec3 dimensions = getDimensions() * (float)TREE_SCALE;
    glm::vec3 halfDimensions = dimensions / 2.0f;
    glm::quat rotation = getRotation();

    const bool useGlutCube = true;
    const float MAX_COLOR = 255.0f;

    if (useGlutCube) {
        glColor4f(getColor()[RED_INDEX] / MAX_COLOR, getColor()[GREEN_INDEX] / MAX_COLOR, 
                        getColor()[BLUE_INDEX] / MAX_COLOR, getLocalRenderAlpha());

        glPushMatrix();
            glTranslatef(position.x, position.y, position.z);
            glm::vec3 axis = glm::axis(rotation);
            glRotatef(glm::degrees(glm::angle(rotation)), axis.x, axis.y, axis.z);
            glPushMatrix();
                glm::vec3 positionToCenter = center - position;
                glTranslatef(positionToCenter.x, positionToCenter.y, positionToCenter.z);
                glScalef(dimensions.x, dimensions.y, dimensions.z);
                Application::getInstance()->getDeferredLightingEffect()->renderSolidCube(1.0f);
            glPopMatrix();
        glPopMatrix();
    } else {
        static GLfloat vertices[] = { 1, 1, 1,  -1, 1, 1,  -1,-1, 1,   1,-1, 1,   // v0,v1,v2,v3 (front)
                                      1, 1, 1,   1,-1, 1,   1,-1,-1,   1, 1,-1,   // v0,v3,v4,v5 (right)
                                      1, 1, 1,   1, 1,-1,  -1, 1,-1,  -1, 1, 1,   // v0,v5,v6,v1 (top)
                                     -1, 1, 1,  -1, 1,-1,  -1,-1,-1,  -1,-1, 1,   // v1,v6,v7,v2 (left)
                                     -1,-1,-1,   1,-1,-1,   1,-1, 1,  -1,-1, 1,   // v7,v4,v3,v2 (bottom)
                                      1,-1,-1,  -1,-1,-1,  -1, 1,-1,   1, 1,-1 }; // v4,v7,v6,v5 (back)

        // normal array
        static GLfloat normals[]  = { 0, 0, 1,   0, 0, 1,   0, 0, 1,   0, 0, 1,   // v0,v1,v2,v3 (front)
                                    1, 0, 0,   1, 0, 0,   1, 0, 0,   1, 0, 0,   // v0,v3,v4,v5 (right)
                                    0, 1, 0,   0, 1, 0,   0, 1, 0,   0, 1, 0,   // v0,v5,v6,v1 (top)
                                   -1, 0, 0,  -1, 0, 0,  -1, 0, 0,  -1, 0, 0,   // v1,v6,v7,v2 (left)
                                    0,-1, 0,   0,-1, 0,   0,-1, 0,   0,-1, 0,   // v7,v4,v3,v2 (bottom)
                                    0, 0,-1,   0, 0,-1,   0, 0,-1,   0, 0,-1 }; // v4,v7,v6,v5 (back)

        // index array of vertex array for glDrawElements() & glDrawRangeElement()
        static GLubyte indices[]  = { 0, 1, 2,   2, 3, 0,      // front
                                      4, 5, 6,   6, 7, 4,      // right
                                      8, 9,10,  10,11, 8,      // top
                                     12,13,14,  14,15,12,      // left
                                     16,17,18,  18,19,16,      // bottom
                                     20,21,22,  22,23,20 };    // back



        glEnableClientState(GL_NORMAL_ARRAY);
        glEnableClientState(GL_VERTEX_ARRAY);
        glNormalPointer(GL_FLOAT, 0, normals);
        glVertexPointer(3, GL_FLOAT, 0, vertices);

        glColor4f(getColor()[RED_INDEX] / MAX_COLOR, getColor()[GREEN_INDEX] / MAX_COLOR, 
                        getColor()[BLUE_INDEX] / MAX_COLOR, getLocalRenderAlpha());
        
        Application::getInstance()->getDeferredLightingEffect()->bindSimpleProgram();
        
        glPushMatrix();
            glTranslatef(position.x, position.y, position.z);
            glm::vec3 axis = glm::axis(rotation);
            glRotatef(glm::degrees(glm::angle(rotation)), axis.x, axis.y, axis.z);
            glPushMatrix();
                glm::vec3 positionToCenter = center - position;
                glTranslatef(positionToCenter.x, positionToCenter.y, positionToCenter.z);
                // we need to do half the size because the geometry in the VBOs are from -1,-1,-1 to 1,1,1 
                glScalef(halfDimensions.x, halfDimensions.y, halfDimensions.z);
                glDrawElements(GL_TRIANGLES, 36, GL_UNSIGNED_BYTE, indices);
            glPopMatrix();
        glPopMatrix();

        Application::getInstance()->getDeferredLightingEffect()->releaseSimpleProgram();
        
        glDisableClientState(GL_VERTEX_ARRAY);  // disable vertex arrays
        glDisableClientState(GL_NORMAL_ARRAY);
    }    
};
void RenderableModelEntityItem::render(RenderArgs* args) {
    PerformanceTimer perfTimer("RMEIrender");
    assert(getType() == EntityTypes::Model);
    
    bool drawAsModel = hasModel();

    glm::vec3 position = getPosition();
    glm::vec3 dimensions = getDimensions();
    float size = glm::length(dimensions);

    bool highlightSimulationOwnership = false;
    if (args->_debugFlags & RenderArgs::RENDER_DEBUG_SIMULATION_OWNERSHIP) {
        auto nodeList = DependencyManager::get<NodeList>();
        const QUuid& myNodeID = nodeList->getSessionUUID();
        highlightSimulationOwnership = (getSimulatorID() == myNodeID);
    }

    if (drawAsModel && !highlightSimulationOwnership) {
        remapTextures();
        glPushMatrix();
        {
            float alpha = getLocalRenderAlpha();

            if (!_model || _needsModelReload) {
                // TODO: this getModel() appears to be about 3% of model render time. We should optimize
                PerformanceTimer perfTimer("getModel");
                EntityTreeRenderer* renderer = static_cast<EntityTreeRenderer*>(args->_renderer);
                getModel(renderer);
            }
            
            if (_model) {
                // handle animations..
                if (hasAnimation()) {
                    if (!jointsMapped()) {
                        QStringList modelJointNames = _model->getJointNames();
                        mapJoints(modelJointNames);
                    }

                    if (jointsMapped()) {
                        QVector<glm::quat> frameData = getAnimationFrame();
                        for (int i = 0; i < frameData.size(); i++) {
                            _model->setJointState(i, true, frameData[i]);
                        }
                    }
                }

                glm::quat rotation = getRotation();
                bool movingOrAnimating = isMoving() || isAnimatingSomething();
                if ((movingOrAnimating || _needsInitialSimulation) && _model->isActive()) {
                    _model->setScaleToFit(true, dimensions);
                    _model->setSnapModelToRegistrationPoint(true, getRegistrationPoint());
                    _model->setRotation(rotation);
                    _model->setTranslation(position);
                    
                    // make sure to simulate so everything gets set up correctly for rendering
                    {
                        PerformanceTimer perfTimer("_model->simulate");
                        _model->simulate(0.0f);
                    }
                    _needsInitialSimulation = false;
                }

                if (_model->isActive()) {
                    // TODO: this is the majority of model render time. And rendering of a cube model vs the basic Box render
                    // is significantly more expensive. Is there a way to call this that doesn't cost us as much? 
                    PerformanceTimer perfTimer("model->render");
                    // filter out if not needed to render
                    if (args && (args->_renderMode == RenderArgs::SHADOW_RENDER_MODE)) {
                        if (movingOrAnimating) {
                            _model->renderInScene(alpha, args);
                        }
                    } else {
                        _model->renderInScene(alpha, args);
                    }
                } else {
                    // if we couldn't get a model, then just draw a cube
                    glm::vec4 color(getColor()[RED_INDEX]/255, getColor()[GREEN_INDEX]/255, getColor()[BLUE_INDEX]/255, 1.0f);
                    glPushMatrix();
                        glTranslatef(position.x, position.y, position.z);
                        DependencyManager::get<DeferredLightingEffect>()->renderWireCube(size, color);
                    glPopMatrix();
                }
            } else {
                // if we couldn't get a model, then just draw a cube
                glm::vec4 color(getColor()[RED_INDEX]/255, getColor()[GREEN_INDEX]/255, getColor()[BLUE_INDEX]/255, 1.0f);
                glPushMatrix();
                    glTranslatef(position.x, position.y, position.z);
                    DependencyManager::get<DeferredLightingEffect>()->renderWireCube(size, color);
                glPopMatrix();
            }
        }
        glPopMatrix();
    } else {
        glm::vec4 color(getColor()[RED_INDEX]/255, getColor()[GREEN_INDEX]/255, getColor()[BLUE_INDEX]/255, 1.0f);
        glPushMatrix();
        glTranslatef(position.x, position.y, position.z);
        DependencyManager::get<DeferredLightingEffect>()->renderWireCube(size, color);
        glPopMatrix();
    }
}