Пример #1
0
void GLWidgetRenderer2::drawFrame()
{
    DPTR_D(GLWidgetRenderer2);
    QRect roi = realROI();
    //d.glv.render(QRectF(-1, 1, 2, -2), roi, d.matrix);
    // QRectF() means the whole viewport
    d.glv.render(QRectF(), roi, d.matrix);
}
Пример #2
0
void OpenGLRendererBase::drawFrame()
{
    DPTR_D(OpenGLRendererBase);
    QRect roi = realROI();
    //d.glv.render(QRectF(-1, 1, 2, -2), roi, d.matrix);
    // QRectF() means the whole viewport
    d.glv.render(QRectF(), roi, d.matrix);
}
Пример #3
0
void GraphicsItemRenderer::drawFrame()
{
    DPTR_D(GraphicsItemRenderer);
    if (!d.painter)
        return;
    if (d.checkGL()) {
        d.glv.render(boundingRect(), realROI(), d.matrix*sceneTransform());
        return;
    }
    QPainterRenderer::drawFrame();
}
Пример #4
0
void OpenGLRendererBase::drawFrame()
{
    DPTR_D(OpenGLRendererBase);
    QRect roi = realROI();
    //d.glv.render(QRectF(-1, 1, 2, -2), roi, d.matrix);
    // QRectF() means the whole viewport
    if (d.frame_changed) {
        d.glv.setCurrentFrame(d.video_frame);
        d.frame_changed = false;
    }
    d.glv.render(QRectF(), roi, d.matrix);
}
Пример #5
0
void GraphicsItemRenderer::drawFrame()
{
    DPTR_D(GraphicsItemRenderer);
    if (!d.painter)
        return;
    if (d.checkGL()) {
        d.glv.render(boundingRect(), realROI(), d.matrix*sceneTransform());
        return;
    }
    //fill background color only when the displayed frame rect not equas to renderer's
    if (d.image.isNull()) {
        //TODO: when setInSize()?
        d.image = QImage(rendererSize(), QImage::Format_RGB32);
        d.image.fill(Qt::black); //maemo 4.7.0: QImage.fill(uint)
    }
    const QRect roi = realROI();
    //assume that the image data is already scaled to out_size(NOT renderer size!)
    if (roi.size() == d.out_rect.size()) {
        d.painter->drawImage(d.out_rect.topLeft(), d.image, roi);
    } else {
        d.painter->drawImage(d.out_rect, d.image, roi);
    }
}
Пример #6
0
void XVRenderer::drawFrame()
{
    DPTR_D(XVRenderer);
    QRect roi = realROI();
    if (!d.use_shm)
        XvPutImage(d.display, d.xv_port, winId(), d.gc, d.xv_image
                   , roi.x(), roi.y(), roi.width(), roi.height()
                   , d.out_rect.x(), d.out_rect.y(), d.out_rect.width(), d.out_rect.height());
    else
        XvShmPutImage(d.display, d.xv_port, winId(), d.gc, d.xv_image
                      , roi.x(), roi.y(), roi.width(), roi.height()
                      , d.out_rect.x(), d.out_rect.y(), d.out_rect.width(), d.out_rect.height()
                      , false /*true: send event*/);
}
Пример #7
0
bool QQuickItemRenderer::receiveFrame(const VideoFrame &frame)
{
    DPTR_D(QQuickItemRenderer);
    d.video_frame = frame;
    if (!isOpenGL()) {
        d.image = QImage((uchar*)frame.constBits(), frame.width(), frame.height(), frame.bytesPerLine(), frame.imageFormat());
        QRect r = realROI();
        if (r != QRect(0, 0, frame.width(), frame.height()))
            d.image = d.image.copy(r);
    }
    d.frame_changed = true;
//    update();  // why update slow? because of calling in a different thread?
    //QMetaObject::invokeMethod(this, "update"); // slower than directly postEvent
    QCoreApplication::postEvent(this, new QEvent(QEvent::User));
    return true;
}
Пример #8
0
void Direct2DRenderer::drawFrame()
{
    DPTR_D(Direct2DRenderer);
    D2D1_RECT_F out_rect = {
        (FLOAT)d.out_rect.left(),
        (FLOAT)d.out_rect.top(),
        (FLOAT)d.out_rect.right(),
        (FLOAT)d.out_rect.bottom()
    };
    QRect roi = realROI();
    D2D1_RECT_F roi_d2d = {
        (FLOAT)roi.left(),
        (FLOAT)roi.top(),
        (FLOAT)roi.right(),
        (FLOAT)roi.bottom()
    };
    //d.render_target->SetTransform
    d.render_target->DrawBitmap(d.bitmap
                                , &out_rect
                                , 1 //opacity
                                , d.interpolation
                                , &roi_d2d);
}
Пример #9
0
void GLWidgetRenderer::drawFrame()
{
    DPTR_D(GLWidgetRenderer);
    QRect roi = realROI();
    d.upload(roi);

    // shader program may not ready before upload
    if (d.hasGLSL) {
#if NO_QGL_SHADER
        glUseProgram(d.program); //for glUniform
#else
        d.shader_program->bind();
#endif //NO_QGL_SHADER
    }
    glDisable(GL_DEPTH_TEST);
    const int nb_planes = d.video_frame.planeCount(); //number of texture id
    // all texture ids should be binded when renderering even for packed plane!
    for (int i = 0; i < nb_planes; ++i) {
        glActiveTexture(GL_TEXTURE0 + i);
        glEnable(GL_TEXTURE_2D);
        glBindTexture(GL_TEXTURE_2D, d.textures[i]); //we've bind 0 after upload()
        // use glUniform1i to swap planes. swap uv: i => (3-i)%3
        // TODO: in shader, use uniform sample2D u_Texture[], and use glUniform1iv(u_Texture, 3, {...})
#if NO_QGL_SHADER
        glUniform1i(d.u_Texture[i], i);
#else
        d.shader_program->setUniformValue(d.u_Texture[i], (GLint)i);
#endif
    }
    if (nb_planes < d.u_Texture.size()) {
        for (int i = nb_planes; i < d.u_Texture.size(); ++i) {
#if NO_QGL_SHADER
            glUniform1i(d.u_Texture[i], nb_planes - 1);
#else
            d.shader_program->setUniformValue(d.u_Texture[i], (GLint)(nb_planes - 1));
#endif
        }
    }
    //TODO: compute kTexCoords only if roi changed
#if ROI_TEXCOORDS
/*!
  tex coords: ROI/frameRect()*effective_tex_width_ratio
*/
    const GLfloat kTexCoords[] = {
            (GLfloat)roi.x()*(GLfloat)d.effective_tex_width_ratio/(GLfloat)d.video_frame.width(), (GLfloat)roi.y()/(GLfloat)d.video_frame.height(),
            (GLfloat)(roi.x() + roi.width())*(GLfloat)d.effective_tex_width_ratio/(GLfloat)d.video_frame.width(), (GLfloat)roi.y()/(GLfloat)d.video_frame.height(),
            (GLfloat)(roi.x() + roi.width())*(GLfloat)d.effective_tex_width_ratio/(GLfloat)d.video_frame.width(), (GLfloat)(roi.y()+roi.height())/(GLfloat)d.video_frame.height(),
            (GLfloat)roi.x()*(GLfloat)d.effective_tex_width_ratio/(GLfloat)d.video_frame.width(), (GLfloat)(roi.y()+roi.height())/(GLfloat)d.video_frame.height(),
    };
///        glVertexAttribPointer(d.a_TexCoords, 2, GL_FLOAT, GL_FALSE, 0, kTexCoords);
///        glEnableVertexAttribArray(d.a_TexCoords);
#else
    const GLfloat kTexCoords[] = {
            0, 0,
            1, 0,
            1, 1,
            0, 1,
    };
#endif //ROI_TEXCOORDS
#ifndef QT_OPENGL_ES_2
    //GL_XXX may not defined in ES2. so macro is required
    if (!d.hasGLSL) {
        //qpainter will reset gl state, so need glMatrixMode and clear color(in drawBackground())
        //TODO: study what state will be reset
        glMatrixMode(GL_PROJECTION);
        glLoadIdentity();
        glMatrixMode(GL_MODELVIEW);
        glLoadIdentity();

        glPushMatrix();
        d.setupAspectRatio(); //TODO: can we avoid calling this every time but only in resize event?
        glVertexPointer(2, GL_FLOAT, 0, kVertices);
        glEnableClientState(GL_VERTEX_ARRAY);
        glTexCoordPointer(2, GL_FLOAT, 0, kTexCoords);
        glEnableClientState(GL_TEXTURE_COORD_ARRAY);
        glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
        glDisableClientState(GL_TEXTURE_COORD_ARRAY);
        glDisableClientState(GL_VERTEX_ARRAY);
        glPopMatrix();
    }
#endif //QT_OPENGL_ES_2
    if (d.hasGLSL) {
        d.setupAspectRatio(); //TODO: can we avoid calling this every time but only in resize event?
        //qpainter need. TODO: VBO?
#if NO_QGL_SHADER
        glVertexAttribPointer(d.a_Position, 2, GL_FLOAT, GL_FALSE, 0, kVertices);
        glEnableVertexAttribArray(d.a_Position);
        glVertexAttribPointer(d.a_TexCoords, 2, GL_FLOAT, GL_FALSE, 0, kTexCoords);
        glEnableVertexAttribArray(d.a_TexCoords);
#else
        d.shader_program->setAttributeArray(d.a_Position, GL_FLOAT, kVertices, 2);
        d.shader_program->enableAttributeArray(d.a_Position);
        d.shader_program->setAttributeArray(d.a_TexCoords, GL_FLOAT, kTexCoords, 2);
        d.shader_program->enableAttributeArray(d.a_TexCoords);
#endif
        /*
         * in Qt4 QMatrix4x4 stores qreal (double), while GLfloat may be float
         * QShaderProgram deal with this case. But compares sizeof(QMatrix4x4) and (GLfloat)*16
         * which seems not correct because QMatrix4x4 has a flag var
         */
        GLfloat *mat = (GLfloat*)d.colorTransform.matrixRef().data();
        GLfloat glm[16];
#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
        if (sizeof(qreal) != sizeof(GLfloat)) {
#else
        if (sizeof(float) != sizeof(GLfloat)) {
#endif
            d.colorTransform.matrixData(glm);
            mat = glm;
        }
        //QMatrix4x4 stores value in Column-major order to match OpenGL. so transpose is not required in glUniformMatrix4fv

#if NO_QGL_SHADER
        glUniformMatrix4fv(d.u_colorMatrix, 1, GL_FALSE, mat);
#else
       d.shader_program->setUniformValue(d.u_colorMatrix, d.colorTransform.matrixRef());
#endif
        glDrawArrays(GL_TRIANGLE_FAN, 0, 4);

#if NO_QGL_SHADER
        glUseProgram(0);
        glDisableVertexAttribArray(d.a_TexCoords);
        glDisableVertexAttribArray(d.a_Position);
#else
        d.shader_program->release();
        d.shader_program->disableAttributeArray(d.a_TexCoords);
        d.shader_program->disableAttributeArray(d.a_Position);
#endif
    }

    for (int i = 0; i < d.textures.size(); ++i) {
        //glActiveTexture: gl functions apply on texture i
        glActiveTexture(GL_TEXTURE0 + i);
        glDisable(GL_TEXTURE_2D);
    }
}

void GLWidgetRenderer::initializeGL()
{
    DPTR_D(GLWidgetRenderer);
    makeCurrent();
    //const QByteArray extensions(reinterpret_cast<const char *>(glGetString(GL_EXTENSIONS)));
    d.hasGLSL = QGLShaderProgram::hasOpenGLShaderPrograms();
    qDebug("OpenGL version: %d.%d  hasGLSL: %d", format().majorVersion(), format().minorVersion(), d.hasGLSL);
#if QTAV_HAVE(QGLFUNCTIONS)
    initializeGLFunctions();
    d.initializeGLFunctions();
#endif //QTAV_HAVE(QGLFUNCTIONS)
    qtavResolveActiveTexture();
    glEnable(GL_TEXTURE_2D);
    if (!d.hasGLSL) {
#ifndef QT_OPENGL_ES_2
        glShadeModel(GL_SMOOTH); //setupQuality?
        glClearDepth(1.0f);
#endif //QT_OPENGL_ES_2
    }
    else {
        d.initWithContext(context());
    }
    glClearColor(0.0, 0.0, 0.0, 0.0);
    d.setupQuality();
}
Пример #10
0
void GLWidgetRenderer::drawFrame()
{
    DPTR_D(GLWidgetRenderer);
#ifdef QT_OPENGL_ES_2
#define FMT_INTERNAL GL_BGRA //why BGRA?
#define FMT GL_BGRA
    glUseProgram(d.program); //qpainter need
    glActiveTexture(GL_TEXTURE0); //TODO: can remove??
    glUniform1i(d.tex_location, 0);
#else //QT_OPENGL_ES_2
#define FMT_INTERNAL GL_RGBA //why? why 3 works?
#define FMT GL_BGRA
#endif //QT_OPENGL_ES_2
    glBindTexture(GL_TEXTURE_2D, d.texture);
    d.setupQuality();
    QRect roi = realROI();
    //uploading part of image eats less gpu memory, but may be more cpu(gles)
    //FIXME: more cpu usage then qpainter. FBO, VBO?
#define ROI_TEXCOORDS 1
    if (ROI_TEXCOORDS || roi.size() == d.video_frame.size()) {
        glTexImage2D(GL_TEXTURE_2D
                     , 0                //level
                     , FMT_INTERNAL               //internal format. 4? why GL_RGBA? GL_RGB?
                     , d.video_frame.width(), d.video_frame.height()
                     , 0                //border, ES not support
                     , FMT          //format, must the same as internal format?
                     , GL_UNSIGNED_BYTE
                     , d.video_frame.bits());
    } else {
#ifdef GL_UNPACK_ROW_LENGTH
// http://stackoverflow.com/questions/205522/opengl-subtexturing
        glPixelStorei(GL_UNPACK_ROW_LENGTH, d.video_frame.width());
        //glPixelStorei or compute pointer
        glPixelStorei(GL_UNPACK_SKIP_PIXELS, roi.x());
        glPixelStorei(GL_UNPACK_SKIP_ROWS, roi.y());
        glTexImage2D(GL_TEXTURE_2D, 0, FMT_INTERNAL, roi.width(), roi.height(), 0, FMT, GL_UNSIGNED_BYTE, d.video_frame.bits());
        glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
        glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
        glPixelStorei(GL_UNPACK_SKIP_ROWS, 0);
#else // GL ES
//define it? or any efficient way?
        glTexImage2D(GL_TEXTURE_2D, 0, FMT_INTERNAL, roi.width(), roi.height(), 0, FMT, GL_UNSIGNED_BYTE, NULL);
        // how to use only 1 call?
        //glTexSubImage2D(GL_TEXTURE_2D, 0, roi.x(), roi.y(), roi.width(), roi.height(), FMT, GL_UNSIGNED_BYTE, d.data.constData());
        for(int y = 0; y < roi.height(); y++) {
            char *row = (char*)d.video_frame.bits() + ((y + roi.y())*d.video_frame.width() + roi.x()) * 4;
            glTexSubImage2D(GL_TEXTURE_2D, 0, 0, y, roi.width(), 1, FMT, GL_UNSIGNED_BYTE, row);
        }
#endif //GL_UNPACK_ROW_LENGTH
    }
    //TODO: compute kTexCoords only if roi changed
#if ROI_TEXCOORDS
    const GLfloat kTexCoords[] = {
        (GLfloat)roi.x()/(GLfloat)d.video_frame.width(), (GLfloat)roi.y()/(GLfloat)d.video_frame.height(),
        (GLfloat)(roi.x() + roi.width())/(GLfloat)d.video_frame.width(), (GLfloat)roi.y()/(GLfloat)d.video_frame.height(),
        (GLfloat)(roi.x() + roi.width())/(GLfloat)d.video_frame.width(), (GLfloat)(roi.y()+roi.height())/(GLfloat)d.video_frame.height(),
        (GLfloat)roi.x()/(GLfloat)d.video_frame.width(), (GLfloat)(roi.y()+roi.height())/(GLfloat)d.video_frame.height(),
    };
///        glVertexAttribPointer(d.tex_coords_location, 2, GL_FLOAT, GL_FALSE, 0, kTexCoords);
///        glEnableVertexAttribArray(d.tex_coords_location);
#else
    const GLfloat kTexCoords[] = {
        0, 0,
        1, 0,
        1, 1,
        0, 1,
    };
#endif //ROI_TEXCOORDS
#ifndef QT_OPENGL_ES_2
    //qpainter will reset gl state, so need glMatrixMode and clear color(in drawBackground())
    //TODO: study what state will be reset
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();

    glPushMatrix();
    d.setupAspectRatio(); //TODO: can we avoid calling this every time but only in resize event?
    glVertexPointer(2, GL_FLOAT, 0, kVertices);
    glEnableClientState(GL_VERTEX_ARRAY);
    glTexCoordPointer(2, GL_FLOAT, 0, kTexCoords);
    glEnableClientState(GL_TEXTURE_COORD_ARRAY);
    glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
    glDisableClientState(GL_TEXTURE_COORD_ARRAY);
    glDisableClientState(GL_VERTEX_ARRAY);
    glPopMatrix();
#else //QT_OPENGL_ES_2
    d.setupAspectRatio(); //TODO: can we avoid calling this every time but only in resize event?
    //qpainter need. TODO: VBO?
    glVertexAttribPointer(d.position_location, 2, GL_FLOAT, GL_FALSE, 0, kVertices);
    glEnableVertexAttribArray(d.position_location);
    glVertexAttribPointer(d.tex_coords_location, 2, GL_FLOAT, GL_FALSE, 0, kTexCoords);
    glEnableVertexAttribArray(d.tex_coords_location);

    glDrawArrays(GL_TRIANGLE_FAN, 0, 4);

    glDisableVertexAttribArray(d.tex_coords_location);
    glDisableVertexAttribArray(d.position_location);
#endif //QT_OPENGL_ES_2
}