Пример #1
0
void
ViewerGL::Implementation::getPolygonTextureCoordinates(const QPolygonF & polygonPoints,
                                                       const RectD & texRect,
                                                       QPolygonF & texCoords)
{
    texCoords.resize( polygonPoints.size() );
    for (int i = 0; i < polygonPoints.size(); ++i) {
        const QPointF & polygonPoint = polygonPoints.at(i);
        QPointF texCoord;
        texCoord.setX( (polygonPoint.x() - texRect.x1) / texRect.width() ); // * (right - left));
        texCoord.setY( (polygonPoint.y() - texRect.y1) / texRect.height() ); // * (top - bottom));
        texCoords[i] = texCoord;
    }
}
// The size of the current project in canonical coordinates.
// The size of a project is a sub set of the kOfxImageEffectPropProjectExtent. For example a
// project may be a PAL SD project, but only be a letter-box within that. The project size is
// the size of this sub window.
void
OfxImageEffectInstance::getProjectSize(double & xSize,
                                       double & ySize) const
{
    Format f;
    _ofxEffectInstance->getRenderFormat(&f);
    RectI pixelF;
    pixelF.x1 = f.x1;
    pixelF.x2 = f.x2;
    pixelF.y1 = f.y1;
    pixelF.y2 = f.y2;
    RectD canonicalF;
    pixelF.toCanonical_noClipping(0, f.getPixelAspectRatio(), &canonicalF);
    xSize = canonicalF.width();
    ySize = canonicalF.height();
}
Пример #3
0
void
Double_Knob::normalize(int dimension,
                       double time,
                       double* value) const
{
    EffectInstance* effect = dynamic_cast<EffectInstance*>( getHolder() );
    
    assert(effect);
    if (!effect) {
        // coverity[dead_error_line]
        return;
    }
    RectD rod;
    getInputRoD(effect,time,rod);
    if (dimension == 0) {
        *value /= rod.width();
    } else if (dimension == 1) {
        *value /= rod.height();
    }
}
Пример #4
0
// 0___1___2___3
// |  /|  /|  /|
// | / | / | / |
// |/  |/  |/  |
// 4---5---6----7
// |  /|  /|  /|
// | / | / | / |
// |/  |/  |/  |
// 8---9--10--11
// |  /|  /|  /|
// | / | / | / |
// |/  |/  |/  |
// 12--13--14--15
void
ViewerGL::Implementation::drawRenderingVAO(unsigned int mipMapLevel,
                                           int textureIndex,
                                           ViewerGL::DrawPolygonModeEnum polygonMode,
                                           bool background)
{
    // always running in the main thread
    assert( qApp && qApp->thread() == QThread::currentThread() );
    assert( QGLContext::currentContext() == _this->context() );

    bool useShader = _this->getBitDepth() != eImageBitDepthByte;


    ///the texture rectangle in image coordinates. The values in it are multiples of tile size.
    ///
    const TextureRect &roiRounded = this->displayTextures[textureIndex].texture->getTextureRect();
    const TextureRect& roiNotRounded = this->displayTextures[textureIndex].roiNotRoundedToTileSize;

    ///This is the coordinates in the image being rendered where datas are valid, this is in pixel coordinates
    ///at the time we initialize it but we will convert it later to canonical coordinates. See 1)
    const double par = roiRounded.par;
    RectD canonicalRoIRoundedToTileSize;
    roiRounded.toCanonical_noClipping(mipMapLevel, par /*, rod*/, &canonicalRoIRoundedToTileSize);

    RectD canonicalRoINotRounded;
    roiNotRounded.toCanonical_noClipping(mipMapLevel, par, &canonicalRoINotRounded);

    ///the RoD of the image in canonical coords.
    RectD rod = _this->getRoD(textureIndex);

    bool clipToDisplayWindow;
    {
        QMutexLocker l(&this->clipToDisplayWindowMutex);
        clipToDisplayWindow = this->clipToDisplayWindow;
    }
    RectD rectClippedToRoI(canonicalRoIRoundedToTileSize);
    rectClippedToRoI.intersect(rod, &rectClippedToRoI);


    if (clipToDisplayWindow) {
        RectD canonicalProjectFormat;
        this->getProjectFormatCanonical(canonicalProjectFormat);
        rod.intersect(canonicalProjectFormat, &rod);
        rectClippedToRoI.intersect(canonicalProjectFormat, &rectClippedToRoI);
    }

    


    //if user RoI is enabled, clip the rod to that roi
    bool userRoiEnabled;
    {
        QMutexLocker l(&this->userRoIMutex);
        userRoiEnabled = this->userRoIEnabled;
    }


    ////The texture real size (r.w,r.h) might be slightly bigger than the actual
    ////pixel coordinates bounds r.x1,r.x2 r.y1 r.y2 because we clipped these bounds against the bounds
    ////in the ViewerInstance::renderViewer function. That means we need to draw actually only the part of
    ////the texture that contains the bounds.
    ////Notice that r.w and r.h are scaled to the closest Po2 of the current scaling factor, so we need to scale it up
    ////So it is in the same coordinates as the bounds.
    ///Edit: we no longer divide by the closestPo2 since the viewer now computes images at lower resolution by itself, the drawing
    ///doesn't need to be scaled.

    if (userRoiEnabled) {
        {
            QMutexLocker l(&this->userRoIMutex);
            //if the userRoI isn't intersecting the rod, just don't render anything
            if ( !rod.intersect(this->userRoI, &rod) ) {
                return;
            }
        }
        rectClippedToRoI.intersect(rod, &rectClippedToRoI);
        //clipTexCoords<RectD>(canonicalTexRect,rectClippedToRoI,texBottom,texTop,texLeft,texRight);
    }

    if (polygonMode != eDrawPolygonModeWhole) {
        /// draw only  the plane defined by the wipe handle
        QPolygonF polygonPoints, polygonTexCoords;
        RectD floatRectClippedToRoI;
        floatRectClippedToRoI.x1 = rectClippedToRoI.x1;
        floatRectClippedToRoI.y1 = rectClippedToRoI.y1;
        floatRectClippedToRoI.x2 = rectClippedToRoI.x2;
        floatRectClippedToRoI.y2 = rectClippedToRoI.y2;
        Implementation::WipePolygonEnum polyType = this->getWipePolygon(floatRectClippedToRoI, polygonMode == eDrawPolygonModeWipeRight, &polygonPoints);

        if (polyType == Implementation::eWipePolygonEmpty) {
            ///don't draw anything
            return;
        } else if (polyType == Implementation::eWipePolygonPartial) {
            this->getPolygonTextureCoordinates(polygonPoints, canonicalRoIRoundedToTileSize, polygonTexCoords);

            this->bindTextureAndActivateShader(textureIndex, useShader);

            GL_GPU::glBegin(GL_POLYGON);
            for (int i = 0; i < polygonTexCoords.size(); ++i) {
                const QPointF & tCoord = polygonTexCoords[i];
                const QPointF & vCoord = polygonPoints[i];
                GL_GPU::glTexCoord2d( tCoord.x(), tCoord.y() );
                GL_GPU::glVertex2d( vCoord.x(), vCoord.y() );
            }
            GL_GPU::glEnd();

            this->unbindTextureAndReleaseShader(useShader);
        } else {
            ///draw the all polygon as usual
            polygonMode = eDrawPolygonModeWhole;
        }
    }

    if (polygonMode == eDrawPolygonModeWhole) {
        const double pixelCenterOffset = 0.5;
        // draw vertices at the center of the first and last pixel in the texture, with the same texture coordinates
        rectClippedToRoI.x1 += pixelCenterOffset * par;
        rectClippedToRoI.x2 -= pixelCenterOffset * par;
        rectClippedToRoI.y1 += pixelCenterOffset;
        rectClippedToRoI.y2 -= pixelCenterOffset;
        ///Vertices are in canonical coords
        GLfloat vertices[32] = {
            (GLfloat)rod.left(), (GLfloat)rod.top(),    //0
            (GLfloat)rectClippedToRoI.x1 + pixelCenterOffset, (GLfloat)rod.top(),          //1
            (GLfloat)rectClippedToRoI.x2 - pixelCenterOffset, (GLfloat)rod.top(),    //2
            (GLfloat)rod.right(), (GLfloat)rod.top(),   //3
            (GLfloat)rod.left(), (GLfloat)rectClippedToRoI.y2 - pixelCenterOffset, //4
            (GLfloat)rectClippedToRoI.x1,  (GLfloat)rectClippedToRoI.y2,       //5
            (GLfloat)rectClippedToRoI.x2,  (GLfloat)rectClippedToRoI.y2, //6
            (GLfloat)rod.right(), (GLfloat)rectClippedToRoI.y2, //7
            (GLfloat)rod.left(), (GLfloat)rectClippedToRoI.y1,        //8
            (GLfloat)rectClippedToRoI.x1,  (GLfloat)rectClippedToRoI.y1,             //9
            (GLfloat)rectClippedToRoI.x2,  (GLfloat)rectClippedToRoI.y1,       //10
            (GLfloat)rod.right(), (GLfloat)rectClippedToRoI.y1,       //11
            (GLfloat)rod.left(), (GLfloat)rod.bottom(), //12
            (GLfloat)rectClippedToRoI.x1,  (GLfloat)rod.bottom(),       //13
            (GLfloat)rectClippedToRoI.x2,  (GLfloat)rod.bottom(), //14
            (GLfloat)rod.right(), (GLfloat)rod.bottom() //15
        };

        //        GLfloat texBottom =  0;
        //        GLfloat texTop =  (GLfloat)(r.y2 - r.y1)  / (GLfloat)(r.h /** r.closestPo2*/);
        //        GLfloat texLeft = 0;
        //        GLfloat texRight = (GLfloat)(r.x2 - r.x1)  / (GLfloat)(r.w /** r.closestPo2*/);
        GLfloat texBottom = (GLfloat)(rectClippedToRoI.y1 - canonicalRoIRoundedToTileSize.y1)  / canonicalRoIRoundedToTileSize.height();
        GLfloat texTop = (GLfloat)(rectClippedToRoI.y2 - canonicalRoIRoundedToTileSize.y1)  / canonicalRoIRoundedToTileSize.height();
        GLfloat texLeft = (GLfloat)(rectClippedToRoI.x1 - canonicalRoIRoundedToTileSize.x1)  / canonicalRoIRoundedToTileSize.width();
        GLfloat texRight = (GLfloat)(rectClippedToRoI.x2 - canonicalRoIRoundedToTileSize.x1)  / canonicalRoIRoundedToTileSize.width();
        GLfloat renderingTextureCoordinates[32] = {
            texLeft, texTop,   //0
            texLeft, texTop,   //1
            texRight, texTop,  //2
            texRight, texTop,   //3
            texLeft, texTop,   //4
            texLeft, texTop,   //5
            texRight, texTop,   //6
            texRight, texTop,   //7
            texLeft, texBottom,   //8
            texLeft, texBottom,   //9
            texRight, texBottom,    //10
            texRight, texBottom,   //11
            texLeft, texBottom,   // 12
            texLeft, texBottom,   //13
            texRight, texBottom,   //14
            texRight, texBottom    //15
        };


        if ( background && this->viewerTab->isCheckerboardEnabled() && (polygonMode != eDrawPolygonModeWipeRight) ) {
            bool isblend = GL_GPU::glIsEnabled(GL_BLEND);
            if (isblend) {
                GL_GPU::glDisable(GL_BLEND);
            }
            this->drawCheckerboardTexture(rod);
            if (isblend) {
                GL_GPU::glEnable(GL_BLEND);
            }
        }

        this->bindTextureAndActivateShader(textureIndex, useShader);

        glCheckError(GL_GPU);

        GL_GPU::glBindBuffer(GL_ARRAY_BUFFER, this->vboVerticesId);
        GL_GPU::glBufferSubData(GL_ARRAY_BUFFER, 0, 32 * sizeof(GLfloat), vertices);
        GL_GPU::glEnableClientState(GL_VERTEX_ARRAY);
        GL_GPU::glVertexPointer(2, GL_FLOAT, 0, 0);

        GL_GPU::glBindBuffer(GL_ARRAY_BUFFER, this->vboTexturesId);
        GL_GPU::glBufferSubData(GL_ARRAY_BUFFER, 0, 32 * sizeof(GLfloat), renderingTextureCoordinates);
        GL_GPU::glClientActiveTexture(GL_TEXTURE0);
        GL_GPU::glEnableClientState(GL_TEXTURE_COORD_ARRAY);
        GL_GPU::glTexCoordPointer(2, GL_FLOAT, 0, 0);

        GL_GPU::glDisableClientState(GL_COLOR_ARRAY);

        GL_GPU::glBindBuffer(GL_ARRAY_BUFFER, 0);

        GL_GPU::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, this->iboTriangleStripId);
        GL_GPU::glDrawElements(GL_TRIANGLE_STRIP, 28, GL_UNSIGNED_BYTE, 0);
        glCheckErrorIgnoreOSXBug(GL_GPU);

        GL_GPU::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
        GL_GPU::glDisableClientState(GL_VERTEX_ARRAY);
        GL_GPU::glDisableClientState(GL_TEXTURE_COORD_ARRAY);
        glCheckError(GL_GPU);

        this->unbindTextureAndReleaseShader(useShader);
    }
} // drawRenderingVAO