コード例 #1
0
void ApplicationOverlay::renderDomainConnectionStatusBorder(RenderArgs* renderArgs) {
    auto geometryCache = DependencyManager::get<GeometryCache>();
    static std::once_flag once;
    std::call_once(once, [&] {
        QVector<vec2> points;
        static const float B = 0.99f;
        points.push_back(vec2(-B));
        points.push_back(vec2(B, -B));
        points.push_back(vec2(B));
        points.push_back(vec2(-B, B));
        points.push_back(vec2(-B));
        geometryCache->updateVertices(_domainStatusBorder, points, CONNECTION_STATUS_BORDER_COLOR);
    });
    auto nodeList = DependencyManager::get<NodeList>();
    if (nodeList && !nodeList->getDomainHandler().isConnected()) {
        gpu::Batch& batch = *renderArgs->_batch;
        auto geometryCache = DependencyManager::get<GeometryCache>();
        geometryCache->useSimpleDrawPipeline(batch);
        batch.setProjectionTransform(mat4());
        batch.setModelTransform(Transform());
        batch.setViewTransform(Transform());
        batch.setResourceTexture(0, DependencyManager::get<TextureCache>()->getWhiteTexture());
        // FIXME: THe line width of CONNECTION_STATUS_BORDER_LINE_WIDTH is not supported anymore, we ll need a workaround

        // TODO animate the disconnect border for some excitement while not connected?
        //double usecs = usecTimestampNow();
        //double secs = usecs / 1000000.0;
        //float scaleAmount = 1.0f + (0.01f * sin(secs * 5.0f));
        //batch.setModelTransform(glm::scale(mat4(), vec3(scaleAmount)));

        geometryCache->renderVertices(batch, gpu::LINE_STRIP, _domainStatusBorder);
    }
}
コード例 #2
0
ファイル: SkeletonModel.cpp プロジェクト: Dreckinfeuer/hifi
void SkeletonModel::renderJointConstraints(gpu::Batch& batch, int jointIndex) {
    if (jointIndex == -1 || jointIndex >= _jointStates.size()) {
        return;
    }
    const FBXGeometry& geometry = _geometry->getFBXGeometry();
    const float BASE_DIRECTION_SIZE = 0.3f;
    float directionSize = BASE_DIRECTION_SIZE * extractUniformScale(_scale);
    batch._glLineWidth(3.0f);
    do {
        const FBXJoint& joint = geometry.joints.at(jointIndex);
        const JointState& jointState = _jointStates.at(jointIndex);
        glm::vec3 position = _rotation * jointState.getPosition() + _translation;
        glm::quat parentRotation = (joint.parentIndex == -1) ? _rotation : _rotation * _jointStates.at(joint.parentIndex).getRotation();
        float fanScale = directionSize * 0.75f;
        
        Transform transform = Transform();
        transform.setTranslation(position);
        transform.setRotation(parentRotation);
        transform.setScale(fanScale);
        batch.setModelTransform(transform);
        
        const int AXIS_COUNT = 3;

        auto geometryCache = DependencyManager::get<GeometryCache>();

        for (int i = 0; i < AXIS_COUNT; i++) {
            if (joint.rotationMin[i] <= -PI + EPSILON && joint.rotationMax[i] >= PI - EPSILON) {
                continue; // unconstrained
            }
            glm::vec3 axis;
            axis[i] = 1.0f;
            
            glm::vec3 otherAxis;
            if (i == 0) {
                otherAxis.y = 1.0f;
            } else {
                otherAxis.x = 1.0f;
            }
            glm::vec4 color(otherAxis.r, otherAxis.g, otherAxis.b, 0.75f);

            QVector<glm::vec3> points;
            points << glm::vec3(0.0f, 0.0f, 0.0f);
            const int FAN_SEGMENTS = 16;
            for (int j = 0; j < FAN_SEGMENTS; j++) {
                glm::vec3 rotated = glm::angleAxis(glm::mix(joint.rotationMin[i], joint.rotationMax[i],
                    (float)j / (FAN_SEGMENTS - 1)), axis) * otherAxis;
                points << rotated;
            }
            // TODO: this is really inefficient constantly recreating these vertices buffers. It would be
            // better if the skeleton model cached these buffers for each of the joints they are rendering
            geometryCache->updateVertices(_triangleFanID, points, color);
            geometryCache->renderVertices(batch, gpu::TRIANGLE_FAN, _triangleFanID);
            
        }
        
        renderOrientationDirections(jointIndex, position, _rotation * jointState.getRotation(), directionSize);
        jointIndex = joint.parentIndex;
        
    } while (jointIndex != -1 && geometry.joints.at(jointIndex).isFree);
}
コード例 #3
0
void Rectangle3DOverlay::render(RenderArgs* args) {
    if (!_visible) {
        return; // do nothing if we're not visible
    }

    float alpha = getAlpha();
    xColor color = getColor();
    const float MAX_COLOR = 255.0f;
    glm::vec4 rectangleColor(color.red / MAX_COLOR, color.green / MAX_COLOR, color.blue / MAX_COLOR, alpha);

    glm::vec3 position = getPosition();
    glm::vec2 dimensions = getDimensions();
    glm::vec2 halfDimensions = dimensions * 0.5f;
    glm::quat rotation = getRotation();

    auto batch = args->_batch;

    if (batch) {
        Transform transform;
        transform.setTranslation(position);
        transform.setRotation(rotation);

        batch->setModelTransform(transform);
        auto geometryCache = DependencyManager::get<GeometryCache>();

        if (getIsSolid()) {
            glm::vec3 topLeft(-halfDimensions.x, -halfDimensions.y, 0.0f);
            glm::vec3 bottomRight(halfDimensions.x, halfDimensions.y, 0.0f);
            geometryCache->bindSimpleProgram(*batch);
            geometryCache->renderQuad(*batch, topLeft, bottomRight, rectangleColor);
        } else {
            geometryCache->bindSimpleProgram(*batch, false, false, false, true, true);
            if (getIsDashedLine()) {
                glm::vec3 point1(-halfDimensions.x, -halfDimensions.y, 0.0f);
                glm::vec3 point2(halfDimensions.x, -halfDimensions.y, 0.0f);
                glm::vec3 point3(halfDimensions.x, halfDimensions.y, 0.0f);
                glm::vec3 point4(-halfDimensions.x, halfDimensions.y, 0.0f);

                geometryCache->renderDashedLine(*batch, point1, point2, rectangleColor);
                geometryCache->renderDashedLine(*batch, point2, point3, rectangleColor);
                geometryCache->renderDashedLine(*batch, point3, point4, rectangleColor);
                geometryCache->renderDashedLine(*batch, point4, point1, rectangleColor);
            } else {
                if (halfDimensions != _previousHalfDimensions) {
                    QVector<glm::vec3> border;
                    border << glm::vec3(-halfDimensions.x, -halfDimensions.y, 0.0f);
                    border << glm::vec3(halfDimensions.x, -halfDimensions.y, 0.0f);
                    border << glm::vec3(halfDimensions.x, halfDimensions.y, 0.0f);
                    border << glm::vec3(-halfDimensions.x, halfDimensions.y, 0.0f);
                    border << glm::vec3(-halfDimensions.x, -halfDimensions.y, 0.0f);
                    geometryCache->updateVertices(_geometryCacheID, border, rectangleColor);

                    _previousHalfDimensions = halfDimensions;
                }
                geometryCache->renderVertices(*batch, gpu::LINE_STRIP, _geometryCacheID);
            }
        }
    }
}
コード例 #4
0
ファイル: AudioScope.cpp プロジェクト: Dreckinfeuer/hifi
void AudioScope::renderLineStrip(gpu::Batch& batch, int id, const glm::vec4& color, int x, int y, int n, int offset, const QByteArray* byteArray) {

    int16_t sample;
    int16_t* samples = ((int16_t*) byteArray->data()) + offset;
    int numSamplesToAverage = _framesPerScope / DEFAULT_FRAMES_PER_SCOPE;
    int count = (n - offset) / numSamplesToAverage;
    int remainder = (n - offset) % numSamplesToAverage;
    y += SCOPE_HEIGHT / 2;
    
    auto geometryCache = DependencyManager::get<GeometryCache>();

    QVector<glm::vec2> points;
    

    // Compute and draw the sample averages from the offset position
    for (int i = count; --i >= 0; ) {
        sample = 0;
        for (int j = numSamplesToAverage; --j >= 0; ) {
            sample += *samples++;
        }
        sample /= numSamplesToAverage;
        points << glm::vec2(x++, y - sample);
    }

    // Compute and draw the sample average across the wrap boundary
    if (remainder != 0) {
        sample = 0;
        for (int j = remainder; --j >= 0; ) {
            sample += *samples++;
        }
    
        samples = (int16_t*) byteArray->data();

        for (int j = numSamplesToAverage - remainder; --j >= 0; ) {
            sample += *samples++;
        }
        sample /= numSamplesToAverage;
        points << glm::vec2(x++, y - sample);
    } else {
        samples = (int16_t*) byteArray->data();
    }

    // Compute and draw the sample average from the beginning to the offset
    count = (offset - remainder) / numSamplesToAverage;
    for (int i = count; --i >= 0; ) {
        sample = 0;
        for (int j = numSamplesToAverage; --j >= 0; ) {
            sample += *samples++;
        }
        sample /= numSamplesToAverage;
        points << glm::vec2(x++, y - sample);
    }
    
    
    geometryCache->updateVertices(id, points, color);
    geometryCache->renderVertices(batch, gpu::LINE_STRIP, id);
}
コード例 #5
0
ファイル: Circle3DOverlay.cpp プロジェクト: MarcelEdward/hifi
void Circle3DOverlay::render(RenderArgs* args) {
    if (!_visible) {
        return; // do nothing if we're not visible
    }

    float alpha = getAlpha();

    if (alpha == 0.0f) {
        return; // do nothing if our alpha is 0, we're not visible
    }

    // Create the circle in the coordinates origin
    float outerRadius = getOuterRadius();
    float innerRadius = getInnerRadius(); // only used in solid case
    float startAt = getStartAt();
    float endAt = getEndAt();

    bool geometryChanged = (startAt != _lastStartAt || endAt != _lastEndAt ||
                                innerRadius != _lastInnerRadius || outerRadius != _lastOuterRadius);


    const float FULL_CIRCLE = 360.0f;
    const float SLICES = 180.0f;  // The amount of segment to create the circle
    const float SLICE_ANGLE = FULL_CIRCLE / SLICES;

    //const int slices = 15;
    xColor colorX = getColor();
    const float MAX_COLOR = 255.0f;
    glm::vec4 color(colorX.red / MAX_COLOR, colorX.green / MAX_COLOR, colorX.blue / MAX_COLOR, alpha);

    bool colorChanged = colorX.red != _lastColor.red || colorX.green != _lastColor.green || colorX.blue != _lastColor.blue;
    _lastColor = colorX;

    auto geometryCache = DependencyManager::get<GeometryCache>();
    
    Q_ASSERT(args->_batch);
    auto& batch = *args->_batch;
    batch._glLineWidth(_lineWidth);
    
    auto transform = _transform;
    transform.postScale(glm::vec3(getDimensions(), 1.0f));
    batch.setModelTransform(transform);
    DependencyManager::get<DeferredLightingEffect>()->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...
    if (getIsSolid()) {
        if (_quadVerticesID == GeometryCache::UNKNOWN_ID) {
            _quadVerticesID = geometryCache->allocateID();
        }
        
        if (geometryChanged || colorChanged) {
            
            QVector<glm::vec2> points;
            
            float angle = startAt;
            float angleInRadians = glm::radians(angle);
            glm::vec2 mostRecentInnerPoint(cosf(angleInRadians) * innerRadius, sinf(angleInRadians) * innerRadius);
            glm::vec2 mostRecentOuterPoint(cosf(angleInRadians) * outerRadius, sinf(angleInRadians) * outerRadius);
            
            while (angle < endAt) {
                angleInRadians = glm::radians(angle);
                glm::vec2 thisInnerPoint(cosf(angleInRadians) * innerRadius, sinf(angleInRadians) * innerRadius);
                glm::vec2 thisOuterPoint(cosf(angleInRadians) * outerRadius, sinf(angleInRadians) * outerRadius);
                
                points << mostRecentInnerPoint << mostRecentOuterPoint << thisOuterPoint; // first triangle
                points << mostRecentInnerPoint << thisInnerPoint << thisOuterPoint; // second triangle
                
                angle += SLICE_ANGLE;

                mostRecentInnerPoint = thisInnerPoint;
                mostRecentOuterPoint = thisOuterPoint;
            }
            
            // get the last slice portion....
            angle = endAt;
            angleInRadians = glm::radians(angle);
            glm::vec2 lastInnerPoint(cosf(angleInRadians) * innerRadius, sinf(angleInRadians) * innerRadius);
            glm::vec2 lastOuterPoint(cosf(angleInRadians) * outerRadius, sinf(angleInRadians) * outerRadius);

            points << mostRecentInnerPoint << mostRecentOuterPoint << lastOuterPoint; // first triangle
            points << mostRecentInnerPoint << lastInnerPoint << lastOuterPoint; // second triangle
            
            geometryCache->updateVertices(_quadVerticesID, points, color);
        }
        
        geometryCache->renderVertices(batch, gpu::TRIANGLES, _quadVerticesID);
        
    } else {
        if (_lineVerticesID == GeometryCache::UNKNOWN_ID) {
            _lineVerticesID = geometryCache->allocateID();
        }
        
        if (geometryChanged || colorChanged) {
            QVector<glm::vec2> points;
            
            float angle = startAt;
            float angleInRadians = glm::radians(angle);
            glm::vec2 firstPoint(cosf(angleInRadians) * outerRadius, sinf(angleInRadians) * outerRadius);
            points << firstPoint;
            
            while (angle < endAt) {
                angle += SLICE_ANGLE;
                angleInRadians = glm::radians(angle);
                glm::vec2 thisPoint(cosf(angleInRadians) * outerRadius, sinf(angleInRadians) * outerRadius);
                points << thisPoint;
                
                if (getIsDashedLine()) {
                    angle += SLICE_ANGLE / 2.0f; // short gap
                    angleInRadians = glm::radians(angle);
                    glm::vec2 dashStartPoint(cosf(angleInRadians) * outerRadius, sinf(angleInRadians) * outerRadius);
                    points << dashStartPoint;
                }
            }
            
            // get the last slice portion....
            angle = endAt;
            angleInRadians = glm::radians(angle);
            glm::vec2 lastPoint(cosf(angleInRadians) * outerRadius, sinf(angleInRadians) * outerRadius);
            points << lastPoint;
            
            geometryCache->updateVertices(_lineVerticesID, points, color);
        }
        
        if (getIsDashedLine()) {
            geometryCache->renderVertices(batch, gpu::LINES, _lineVerticesID);
        } else {
            geometryCache->renderVertices(batch, gpu::LINE_STRIP, _lineVerticesID);
        }
    }
    
    // draw our tick marks
    // 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...
    if (getHasTickMarks()) {
        
        if (_majorTicksVerticesID == GeometryCache::UNKNOWN_ID) {
            _majorTicksVerticesID = geometryCache->allocateID();
        }
        if (_minorTicksVerticesID == GeometryCache::UNKNOWN_ID) {
            _minorTicksVerticesID = geometryCache->allocateID();
        }
        
        if (geometryChanged) {
            QVector<glm::vec2> majorPoints;
            QVector<glm::vec2> minorPoints;
            
            // draw our major tick marks
            if (getMajorTickMarksAngle() > 0.0f && getMajorTickMarksLength() != 0.0f) {
                
                float tickMarkAngle = getMajorTickMarksAngle();
                float angle = startAt - fmodf(startAt, tickMarkAngle) + tickMarkAngle;
                float angleInRadians = glm::radians(angle);
                float tickMarkLength = getMajorTickMarksLength();
                float startRadius = (tickMarkLength > 0.0f) ? innerRadius : outerRadius;
                float endRadius = startRadius + tickMarkLength;
                
                while (angle <= endAt) {
                    angleInRadians = glm::radians(angle);
                    
                    glm::vec2 thisPointA(cosf(angleInRadians) * startRadius, sinf(angleInRadians) * startRadius);
                    glm::vec2 thisPointB(cosf(angleInRadians) * endRadius, sinf(angleInRadians) * endRadius);
                    
                    majorPoints << thisPointA << thisPointB;
                    
                    angle += tickMarkAngle;
                }
            }
            
            // draw our minor tick marks
            if (getMinorTickMarksAngle() > 0.0f && getMinorTickMarksLength() != 0.0f) {
                
                float tickMarkAngle = getMinorTickMarksAngle();
                float angle = startAt - fmodf(startAt, tickMarkAngle) + tickMarkAngle;
                float angleInRadians = glm::radians(angle);
                float tickMarkLength = getMinorTickMarksLength();
                float startRadius = (tickMarkLength > 0.0f) ? innerRadius : outerRadius;
                float endRadius = startRadius + tickMarkLength;
                
                while (angle <= endAt) {
                    angleInRadians = glm::radians(angle);
                    
                    glm::vec2 thisPointA(cosf(angleInRadians) * startRadius, sinf(angleInRadians) * startRadius);
                    glm::vec2 thisPointB(cosf(angleInRadians) * endRadius, sinf(angleInRadians) * endRadius);
                    
                    minorPoints << thisPointA << thisPointB;
                    
                    angle += tickMarkAngle;
                }
            }
            
            xColor majorColorX = getMajorTickMarksColor();
            glm::vec4 majorColor(majorColorX.red / MAX_COLOR, majorColorX.green / MAX_COLOR, majorColorX.blue / MAX_COLOR, alpha);
            
            geometryCache->updateVertices(_majorTicksVerticesID, majorPoints, majorColor);
            
            xColor minorColorX = getMinorTickMarksColor();
            glm::vec4 minorColor(minorColorX.red / MAX_COLOR, minorColorX.green / MAX_COLOR, minorColorX.blue / MAX_COLOR, alpha);
            
            geometryCache->updateVertices(_minorTicksVerticesID, minorPoints, minorColor);
        }
        
        geometryCache->renderVertices(batch, gpu::LINES, _majorTicksVerticesID);
        
        geometryCache->renderVertices(batch, gpu::LINES, _minorTicksVerticesID);
    }
    
    if (geometryChanged) {
        _lastStartAt = startAt;
        _lastEndAt = endAt;
        _lastInnerRadius = innerRadius;
        _lastOuterRadius = outerRadius;
    }
}
コード例 #6
0
//Renders a small magnification of the currently bound texture at the coordinates
void ApplicationCompositor::renderMagnifier(gpu::Batch& batch, const glm::vec2& magPos, float sizeMult, bool showBorder) {
    if (!_magnifier) {
        return;
    }
    auto canvasSize = qApp->getCanvasSize();
    
    const int widgetWidth = canvasSize.x;
    const int widgetHeight = canvasSize.y;
    
    const float halfWidth = (MAGNIFY_WIDTH / _textureAspectRatio) * sizeMult / 2.0f;
    const float halfHeight = MAGNIFY_HEIGHT * sizeMult / 2.0f;
    // Magnification Texture Coordinates
    const float magnifyULeft = (magPos.x - halfWidth) / (float)widgetWidth;
    const float magnifyURight = (magPos.x + halfWidth) / (float)widgetWidth;
    const float magnifyVTop = 1.0f - (magPos.y - halfHeight) / (float)widgetHeight;
    const float magnifyVBottom = 1.0f - (magPos.y + halfHeight) / (float)widgetHeight;
    
    const float newHalfWidth = halfWidth * MAGNIFY_MULT;
    const float newHalfHeight = halfHeight * MAGNIFY_MULT;
    //Get yaw / pitch value for the corners
    const glm::vec2 topLeftYawPitch = overlayToSpherical(glm::vec2(magPos.x - newHalfWidth,
                                                                   magPos.y - newHalfHeight));
    const glm::vec2 bottomRightYawPitch = overlayToSpherical(glm::vec2(magPos.x + newHalfWidth,
                                                                       magPos.y + newHalfHeight));
    
    const glm::vec3 bottomLeft = getPoint(topLeftYawPitch.x, bottomRightYawPitch.y);
    const glm::vec3 bottomRight = getPoint(bottomRightYawPitch.x, bottomRightYawPitch.y);
    const glm::vec3 topLeft = getPoint(topLeftYawPitch.x, topLeftYawPitch.y);
    const glm::vec3 topRight = getPoint(bottomRightYawPitch.x, topLeftYawPitch.y);

    auto geometryCache = DependencyManager::get<GeometryCache>();

    if (bottomLeft != _previousMagnifierBottomLeft || bottomRight != _previousMagnifierBottomRight
        || topLeft != _previousMagnifierTopLeft || topRight != _previousMagnifierTopRight) {
        QVector<glm::vec3> border;
        border << topLeft;
        border << bottomLeft;
        border << bottomRight;
        border << topRight;
        border << topLeft;
        geometryCache->updateVertices(_magnifierBorder, border, glm::vec4(1.0f, 0.0f, 0.0f, _alpha));

        _previousMagnifierBottomLeft = bottomLeft;
        _previousMagnifierBottomRight = bottomRight;
        _previousMagnifierTopLeft = topLeft;
        _previousMagnifierTopRight = topRight;
    }
    
    glPushMatrix(); {
        if (showBorder) {
            glDisable(GL_TEXTURE_2D);
            glLineWidth(1.0f);
            //Outer Line
            geometryCache->renderVertices(gpu::LINE_STRIP, _magnifierBorder);
            glEnable(GL_TEXTURE_2D);
        }
        glm::vec4 magnifierColor = { 1.0f, 1.0f, 1.0f, _alpha };

        DependencyManager::get<GeometryCache>()->renderQuad(bottomLeft, bottomRight, topRight, topLeft,
                                                    glm::vec2(magnifyULeft, magnifyVBottom), 
                                                    glm::vec2(magnifyURight, magnifyVBottom), 
                                                    glm::vec2(magnifyURight, magnifyVTop), 
                                                    glm::vec2(magnifyULeft, magnifyVTop),
                                                    magnifierColor, _magnifierQuad);
        
    } glPopMatrix();
}
コード例 #7
0
void Circle3DOverlay::render(RenderArgs* args) {
    if (!_visible) {
        return; // do nothing if we're not visible
    }

    float alpha = getAlpha();
    if (alpha == 0.0f) {
        return; // do nothing if our alpha is 0, we're not visible
    }

    bool geometryChanged = _dirty;
    _dirty = false;

    const float FULL_CIRCLE = 360.0f;
    const float SLICES = 180.0f;  // The amount of segment to create the circle
    const float SLICE_ANGLE = FULL_CIRCLE / SLICES;
    const float MAX_COLOR = 255.0f;

    auto geometryCache = DependencyManager::get<GeometryCache>();

    Q_ASSERT(args->_batch);
    auto& batch = *args->_batch;
    if (args->_pipeline) {
        batch.setPipeline(args->_pipeline->pipeline);
    }

    // FIXME: THe line width of _lineWidth is not supported anymore, we ll need a workaround

    auto transform = getTransform();
    transform.postScale(glm::vec3(getDimensions(), 1.0f));
    batch.setModelTransform(transform);

    // 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...
    if (getIsSolid()) {
        if (!_quadVerticesID) {
            _quadVerticesID = geometryCache->allocateID();
        }

        if (geometryChanged) {
            QVector<glm::vec2> points;
            QVector<glm::vec4> colors;

            float pulseLevel = updatePulse();
            vec4 pulseModifier = vec4(1);
            if (_alphaPulse != 0.0f) {
                pulseModifier.a = (_alphaPulse >= 0.0f) ? pulseLevel : (1.0f - pulseLevel);
            }
            if (_colorPulse != 0.0f) {
                float pulseValue = (_colorPulse >= 0.0f) ? pulseLevel : (1.0f - pulseLevel);
                pulseModifier = vec4(vec3(pulseValue), pulseModifier.a);
            }
            vec4 innerStartColor = vec4(toGlm(_innerStartColor), _innerStartAlpha) * pulseModifier;
            vec4 outerStartColor = vec4(toGlm(_outerStartColor), _outerStartAlpha) * pulseModifier;
            vec4 innerEndColor = vec4(toGlm(_innerEndColor), _innerEndAlpha) * pulseModifier;
            vec4 outerEndColor = vec4(toGlm(_outerEndColor), _outerEndAlpha) * pulseModifier;

            if (_innerRadius <= 0) {
                _solidPrimitive = gpu::TRIANGLE_FAN;
                points << vec2();
                colors << innerStartColor;
                for (float angle = _startAt; angle <= _endAt; angle += SLICE_ANGLE) {
                    float range = (angle - _startAt) / (_endAt - _startAt);
                    float angleRadians = glm::radians(angle);
                    points << glm::vec2(cosf(angleRadians) * _outerRadius, sinf(angleRadians) * _outerRadius);
                    colors << glm::mix(outerStartColor, outerEndColor, range);
                }
            } else {
                _solidPrimitive = gpu::TRIANGLE_STRIP;
                for (float angle = _startAt; angle <= _endAt; angle += SLICE_ANGLE) {
                    float range = (angle - _startAt) / (_endAt - _startAt);

                    float angleRadians = glm::radians(angle);
                    points << glm::vec2(cosf(angleRadians) * _innerRadius, sinf(angleRadians) * _innerRadius);
                    colors << glm::mix(innerStartColor, innerEndColor, range);

                    points << glm::vec2(cosf(angleRadians) * _outerRadius, sinf(angleRadians) * _outerRadius);
                    colors << glm::mix(outerStartColor, outerEndColor, range);
                }
            }
            geometryCache->updateVertices(_quadVerticesID, points, colors);
        }
        
        geometryCache->renderVertices(batch, _solidPrimitive, _quadVerticesID);
        
    } else {
        if (!_lineVerticesID) {
            _lineVerticesID = geometryCache->allocateID();
        }
        
        if (geometryChanged) {
            QVector<glm::vec2> points;
            
            float angle = _startAt;
            float angleInRadians = glm::radians(angle);
            glm::vec2 firstPoint(cosf(angleInRadians) * _outerRadius, sinf(angleInRadians) * _outerRadius);
            points << firstPoint;
            
            while (angle < _endAt) {
                angle += SLICE_ANGLE;
                angleInRadians = glm::radians(angle);
                glm::vec2 thisPoint(cosf(angleInRadians) * _outerRadius, sinf(angleInRadians) * _outerRadius);
                points << thisPoint;
                
                if (getIsDashedLine()) {
                    angle += SLICE_ANGLE / 2.0f; // short gap
                    angleInRadians = glm::radians(angle);
                    glm::vec2 dashStartPoint(cosf(angleInRadians) * _outerRadius, sinf(angleInRadians) * _outerRadius);
                    points << dashStartPoint;
                }
            }
            
            // get the last slice portion....
            angle = _endAt;
            angleInRadians = glm::radians(angle);
            glm::vec2 lastPoint(cosf(angleInRadians) * _outerRadius, sinf(angleInRadians) * _outerRadius);
            points << lastPoint;
            geometryCache->updateVertices(_lineVerticesID, points, vec4(toGlm(getColor()), getAlpha()));
        }
        
        if (getIsDashedLine()) {
            geometryCache->renderVertices(batch, gpu::LINES, _lineVerticesID);
        } else {
            geometryCache->renderVertices(batch, gpu::LINE_STRIP, _lineVerticesID);
        }
    }
    
    // draw our tick marks
    // 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...
    if (getHasTickMarks()) {
        
        if (_majorTicksVerticesID == GeometryCache::UNKNOWN_ID) {
            _majorTicksVerticesID = geometryCache->allocateID();
        }
        if (_minorTicksVerticesID == GeometryCache::UNKNOWN_ID) {
            _minorTicksVerticesID = geometryCache->allocateID();
        }
        
        if (geometryChanged) {
            QVector<glm::vec2> majorPoints;
            QVector<glm::vec2> minorPoints;
            
            // draw our major tick marks
            if (getMajorTickMarksAngle() > 0.0f && getMajorTickMarksLength() != 0.0f) {
                
                float tickMarkAngle = getMajorTickMarksAngle();
                float angle = _startAt - fmodf(_startAt, tickMarkAngle) + tickMarkAngle;
                float angleInRadians = glm::radians(angle);
                float tickMarkLength = getMajorTickMarksLength();
                float startRadius = (tickMarkLength > 0.0f) ? _innerRadius : _outerRadius;
                float endRadius = startRadius + tickMarkLength;
                
                while (angle <= _endAt) {
                    angleInRadians = glm::radians(angle);
                    
                    glm::vec2 thisPointA(cosf(angleInRadians) * startRadius, sinf(angleInRadians) * startRadius);
                    glm::vec2 thisPointB(cosf(angleInRadians) * endRadius, sinf(angleInRadians) * endRadius);
                    
                    majorPoints << thisPointA << thisPointB;
                    
                    angle += tickMarkAngle;
                }
            }
            
            // draw our minor tick marks
            if (getMinorTickMarksAngle() > 0.0f && getMinorTickMarksLength() != 0.0f) {
                
                float tickMarkAngle = getMinorTickMarksAngle();
                float angle = _startAt - fmodf(_startAt, tickMarkAngle) + tickMarkAngle;
                float angleInRadians = glm::radians(angle);
                float tickMarkLength = getMinorTickMarksLength();
                float startRadius = (tickMarkLength > 0.0f) ? _innerRadius : _outerRadius;
                float endRadius = startRadius + tickMarkLength;
                
                while (angle <= _endAt) {
                    angleInRadians = glm::radians(angle);
                    
                    glm::vec2 thisPointA(cosf(angleInRadians) * startRadius, sinf(angleInRadians) * startRadius);
                    glm::vec2 thisPointB(cosf(angleInRadians) * endRadius, sinf(angleInRadians) * endRadius);
                    
                    minorPoints << thisPointA << thisPointB;
                    
                    angle += tickMarkAngle;
                }
            }
            
            xColor majorColorX = getMajorTickMarksColor();
            glm::vec4 majorColor(majorColorX.red / MAX_COLOR, majorColorX.green / MAX_COLOR, majorColorX.blue / MAX_COLOR, alpha);
            
            geometryCache->updateVertices(_majorTicksVerticesID, majorPoints, majorColor);
            
            xColor minorColorX = getMinorTickMarksColor();
            glm::vec4 minorColor(minorColorX.red / MAX_COLOR, minorColorX.green / MAX_COLOR, minorColorX.blue / MAX_COLOR, alpha);
            
            geometryCache->updateVertices(_minorTicksVerticesID, minorPoints, minorColor);
        }
        
        geometryCache->renderVertices(batch, gpu::LINES, _majorTicksVerticesID);
        
        geometryCache->renderVertices(batch, gpu::LINES, _minorTicksVerticesID);
    }
}
コード例 #8
0
ファイル: Rectangle3DOverlay.cpp プロジェクト: jsundman/hifi
void Rectangle3DOverlay::render(RenderArgs* args) {
    if (!_visible) {
        return; // do nothing if we're not visible
    }
    
    float alpha = getAlpha();
    xColor color = getColor();
    const float MAX_COLOR = 255.0f;
    glm::vec4 rectangleColor(color.red / MAX_COLOR, color.green / MAX_COLOR, color.blue / MAX_COLOR, alpha);

    glm::vec3 position = getPosition();
    glm::vec3 center = getCenter();
    glm::vec2 dimensions = getDimensions();
    glm::vec2 halfDimensions = dimensions * 0.5f;
    glm::quat rotation = getRotation();

    auto batch = args->_batch;

    if (batch) {
        Transform transform;
        transform.setTranslation(position);
        transform.setRotation(rotation);

        batch->setModelTransform(transform);

        if (getIsSolid()) {
            glm::vec3 topLeft(-halfDimensions.x, -halfDimensions.y, 0.0f);
            glm::vec3 bottomRight(halfDimensions.x, halfDimensions.y, 0.0f);
            DependencyManager::get<GeometryCache>()->renderQuad(*batch, topLeft, bottomRight, rectangleColor);
        } else {
            auto geometryCache = DependencyManager::get<GeometryCache>();
            if (getIsDashedLine()) {
                glm::vec3 point1(-halfDimensions.x, -halfDimensions.y, 0.0f);
                glm::vec3 point2(halfDimensions.x, -halfDimensions.y, 0.0f);
                glm::vec3 point3(halfDimensions.x, halfDimensions.y, 0.0f);
                glm::vec3 point4(-halfDimensions.x, halfDimensions.y, 0.0f);
            
                geometryCache->renderDashedLine(*batch, point1, point2, rectangleColor);
                geometryCache->renderDashedLine(*batch, point2, point3, rectangleColor);
                geometryCache->renderDashedLine(*batch, point3, point4, rectangleColor);
                geometryCache->renderDashedLine(*batch, point4, point1, rectangleColor);
            } else {
                if (halfDimensions != _previousHalfDimensions) {
                    QVector<glm::vec3> border;
                    border << glm::vec3(-halfDimensions.x, -halfDimensions.y, 0.0f);
                    border << glm::vec3(halfDimensions.x, -halfDimensions.y, 0.0f);
                    border << glm::vec3(halfDimensions.x, halfDimensions.y, 0.0f);
                    border << glm::vec3(-halfDimensions.x, halfDimensions.y, 0.0f);
                    border << glm::vec3(-halfDimensions.x, -halfDimensions.y, 0.0f);
                    geometryCache->updateVertices(_geometryCacheID, border, rectangleColor);

                    _previousHalfDimensions = halfDimensions;
                }
                geometryCache->renderVertices(*batch, gpu::LINE_STRIP, _geometryCacheID);
            }
        }
    } else {
        glDisable(GL_LIGHTING);
        
        float glowLevel = getGlowLevel();
        Glower* glower = NULL;
        if (glowLevel > 0.0f) {
            glower = new Glower(glowLevel);
        }

        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, 1.0f);

                glLineWidth(_lineWidth);

                auto geometryCache = DependencyManager::get<GeometryCache>();
                
                // for our overlay, is solid means we draw a solid "filled" rectangle otherwise we just draw a border line...
                if (getIsSolid()) {
                    glm::vec3 topLeft(-halfDimensions.x, -halfDimensions.y, 0.0f);
                    glm::vec3 bottomRight(halfDimensions.x, halfDimensions.y, 0.0f);
                    DependencyManager::get<GeometryCache>()->renderQuad(topLeft, bottomRight, rectangleColor);
                } else {
                    if (getIsDashedLine()) {

                        glm::vec3 point1(-halfDimensions.x, -halfDimensions.y, 0.0f);
                        glm::vec3 point2(halfDimensions.x, -halfDimensions.y, 0.0f);
                        glm::vec3 point3(halfDimensions.x, halfDimensions.y, 0.0f);
                        glm::vec3 point4(-halfDimensions.x, halfDimensions.y, 0.0f);
                    
                        geometryCache->renderDashedLine(point1, point2, rectangleColor);
                        geometryCache->renderDashedLine(point2, point3, rectangleColor);
                        geometryCache->renderDashedLine(point3, point4, rectangleColor);
                        geometryCache->renderDashedLine(point4, point1, rectangleColor);

                    } else {
                    
                        if (halfDimensions != _previousHalfDimensions) {
                            QVector<glm::vec3> border;
                            border << glm::vec3(-halfDimensions.x, -halfDimensions.y, 0.0f);
                            border << glm::vec3(halfDimensions.x, -halfDimensions.y, 0.0f);
                            border << glm::vec3(halfDimensions.x, halfDimensions.y, 0.0f);
                            border << glm::vec3(-halfDimensions.x, halfDimensions.y, 0.0f);
                            border << glm::vec3(-halfDimensions.x, -halfDimensions.y, 0.0f);
                            geometryCache->updateVertices(_geometryCacheID, border, rectangleColor);

                            _previousHalfDimensions = halfDimensions;
                            
                        }
                        geometryCache->renderVertices(gpu::LINE_STRIP, _geometryCacheID);
                    }
                }
     
            glPopMatrix();
        glPopMatrix();
        
        if (glower) {
            delete glower;
        }
    }
}
コード例 #9
0
ファイル: Circle3DOverlay.cpp プロジェクト: ey6es/hifi
void Circle3DOverlay::render(RenderArgs* args) {
    if (!_visible) {
        return; // do nothing if we're not visible
    }

    float alpha = getAlpha();

    if (alpha == 0.0) {
        return; // do nothing if our alpha is 0, we're not visible
    }
    
    // Create the circle in the coordinates origin
    float outerRadius = getOuterRadius();
    float innerRadius = getInnerRadius(); // only used in solid case
    float startAt = getStartAt();
    float endAt = getEndAt();
    
    bool geometryChanged = (startAt != _lastStartAt || endAt != _lastEndAt ||
                                innerRadius != _lastInnerRadius || outerRadius != _lastOuterRadius);

    
    const float FULL_CIRCLE = 360.0f;
    const float SLICES = 180.0f;  // The amount of segment to create the circle
    const float SLICE_ANGLE = FULL_CIRCLE / SLICES;

    //const int slices = 15;
    xColor color = getColor();
    const float MAX_COLOR = 255.0f;
    glColor4f(color.red / MAX_COLOR, color.green / MAX_COLOR, color.blue / MAX_COLOR, alpha);


    glDisable(GL_LIGHTING);
    
    glm::vec3 position = getPosition();
    glm::vec3 center = getCenter();
    glm::vec2 dimensions = getDimensions();
    glm::quat rotation = getRotation();

    float glowLevel = getGlowLevel();
    Glower* glower = NULL;
    if (glowLevel > 0.0f) {
        glower = new Glower(glowLevel);
    }

    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, 1.0f);

            glLineWidth(_lineWidth);

            auto geometryCache = DependencyManager::get<GeometryCache>();
            
            // 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...
            if (getIsSolid()) {
                if (_quadVerticesID == GeometryCache::UNKNOWN_ID) {
                    _quadVerticesID = geometryCache->allocateID();
                }
                
                if (geometryChanged) {
                    
                    QVector<glm::vec2> points;

                    float angle = startAt;
                    float angleInRadians = glm::radians(angle);
                    glm::vec2 firstInnerPoint(cos(angleInRadians) * innerRadius, sin(angleInRadians) * innerRadius);
                    glm::vec2 firstOuterPoint(cos(angleInRadians) * outerRadius, sin(angleInRadians) * outerRadius);

                    points << firstInnerPoint << firstOuterPoint;

                    while (angle < endAt) {
                        angleInRadians = glm::radians(angle);
                        glm::vec2 thisInnerPoint(cos(angleInRadians) * innerRadius, sin(angleInRadians) * innerRadius);
                        glm::vec2 thisOuterPoint(cos(angleInRadians) * outerRadius, sin(angleInRadians) * outerRadius);

                        points << thisOuterPoint << thisInnerPoint;
                
                        angle += SLICE_ANGLE;
                    }
            
                    // get the last slice portion....
                    angle = endAt;
                    angleInRadians = glm::radians(angle);
                    glm::vec2 lastInnerPoint(cos(angleInRadians) * innerRadius, sin(angleInRadians) * innerRadius);
                    glm::vec2 lastOuterPoint(cos(angleInRadians) * outerRadius, sin(angleInRadians) * outerRadius);
            
                    points << lastOuterPoint << lastInnerPoint;

                    geometryCache->updateVertices(_quadVerticesID, points);
                }
                
                geometryCache->renderVertices(GL_QUAD_STRIP, _quadVerticesID);

            } else {
                if (_lineVerticesID == GeometryCache::UNKNOWN_ID) {
                    _lineVerticesID = geometryCache->allocateID();
                }

                if (geometryChanged) {
                    QVector<glm::vec2> points;
                    
                    float angle = startAt;
                    float angleInRadians = glm::radians(angle);
                    glm::vec2 firstPoint(cos(angleInRadians) * outerRadius, sin(angleInRadians) * outerRadius);
                    points << firstPoint;

                    while (angle < endAt) {
                        angle += SLICE_ANGLE;
                        angleInRadians = glm::radians(angle);
                        glm::vec2 thisPoint(cos(angleInRadians) * outerRadius, sin(angleInRadians) * outerRadius);
                        points << thisPoint;

                        if (getIsDashedLine()) {
                            angle += SLICE_ANGLE / 2.0f; // short gap
                            angleInRadians = glm::radians(angle);
                            glm::vec2 dashStartPoint(cos(angleInRadians) * outerRadius, sin(angleInRadians) * outerRadius);
                            points << dashStartPoint;
                        }
                    }
            
                    // get the last slice portion....
                    angle = endAt;
                    angleInRadians = glm::radians(angle);
                    glm::vec2 lastPoint(cos(angleInRadians) * outerRadius, sin(angleInRadians) * outerRadius);
                    points << lastPoint;

                    geometryCache->updateVertices(_lineVerticesID, points);
                }

                if (getIsDashedLine()) {
                    geometryCache->renderVertices(GL_LINES, _lineVerticesID);
                } else {
                    geometryCache->renderVertices(GL_LINE_STRIP, _lineVerticesID);
                }
            }
            
            // draw our tick marks
            // 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...
            if (getHasTickMarks()) {

                if (_majorTicksVerticesID == GeometryCache::UNKNOWN_ID) {
                    _majorTicksVerticesID = geometryCache->allocateID();
                }
                if (_minorTicksVerticesID == GeometryCache::UNKNOWN_ID) {
                    _minorTicksVerticesID = geometryCache->allocateID();
                }

                if (geometryChanged) {
                    QVector<glm::vec2> majorPoints;
                    QVector<glm::vec2> minorPoints;

                    // draw our major tick marks
                    if (getMajorTickMarksAngle() > 0.0f && getMajorTickMarksLength() != 0.0f) {
                
                        float tickMarkAngle = getMajorTickMarksAngle();
                        float angle = startAt - fmod(startAt, tickMarkAngle) + tickMarkAngle; 
                        float angleInRadians = glm::radians(angle);
                        float tickMarkLength = getMajorTickMarksLength();
                        float startRadius = (tickMarkLength > 0.0f) ? innerRadius : outerRadius;
                        float endRadius = startRadius + tickMarkLength;

                        while (angle <= endAt) {
                            angleInRadians = glm::radians(angle);

                            glm::vec2 thisPointA(cos(angleInRadians) * startRadius, sin(angleInRadians) * startRadius);
                            glm::vec2 thisPointB(cos(angleInRadians) * endRadius, sin(angleInRadians) * endRadius);

                            majorPoints << thisPointA << thisPointB;
                
                            angle += tickMarkAngle;
                        }
                    }

                    // draw our minor tick marks
                    if (getMinorTickMarksAngle() > 0.0f && getMinorTickMarksLength() != 0.0f) {
                
                        float tickMarkAngle = getMinorTickMarksAngle();
                        float angle = startAt - fmod(startAt, tickMarkAngle) + tickMarkAngle; 
                        float angleInRadians = glm::radians(angle);
                        float tickMarkLength = getMinorTickMarksLength();
                        float startRadius = (tickMarkLength > 0.0f) ? innerRadius : outerRadius;
                        float endRadius = startRadius + tickMarkLength;

                        while (angle <= endAt) {
                            angleInRadians = glm::radians(angle);

                            glm::vec2 thisPointA(cos(angleInRadians) * startRadius, sin(angleInRadians) * startRadius);
                            glm::vec2 thisPointB(cos(angleInRadians) * endRadius, sin(angleInRadians) * endRadius);

                            minorPoints << thisPointA << thisPointB;
                
                            angle += tickMarkAngle;
                        }
                    }

                    geometryCache->updateVertices(_majorTicksVerticesID, majorPoints);
                    geometryCache->updateVertices(_minorTicksVerticesID, minorPoints);
                }

                xColor majorColor = getMajorTickMarksColor();
                glColor4f(majorColor.red / MAX_COLOR, majorColor.green / MAX_COLOR, majorColor.blue / MAX_COLOR, alpha);
                geometryCache->renderVertices(GL_LINES, _majorTicksVerticesID);

                xColor minorColor = getMinorTickMarksColor();
                glColor4f(minorColor.red / MAX_COLOR, minorColor.green / MAX_COLOR, minorColor.blue / MAX_COLOR, alpha);
                geometryCache->renderVertices(GL_LINES, _minorTicksVerticesID);
            }
            
 
        glPopMatrix();
    glPopMatrix();
    
    if (geometryChanged) {
        _lastStartAt = startAt;
        _lastEndAt = endAt;
        _lastInnerRadius = innerRadius;
        _lastOuterRadius = outerRadius;
    }
    
    if (glower) {
        delete glower;
    }
}