예제 #1
0
void glActiveTexture(GLenum texture)
{
#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
#ifndef QT_OPENGL_ES
    if (!qtav_glActiveTexture)
        qtavResolveActiveTexture();
    if (!qtav_glActiveTexture)
        return;
    qtav_glActiveTexture(texture);
#else
    ::glActiveTexture(texture);
#endif //QT_OPENGL_ES
#else
    QOpenGLContext::currentContext()->functions()->glActiveTexture(texture);
#endif
}
예제 #2
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();
}