簡體   English   中英

QT QML中的OpenGL,無法在屏幕上更新我的圖像

[英]OpenGL in QT QML, can't update my image on screen

為了將OpenGL與QML結合使用,我完全按照此處所述創建了OpenGlVideoQtQuickOpenGlVideoQtQuickRenderer類。 唯一的區別是,我添加了updateData()函數來更新緩沖區,而在此示例中,在屏幕上繪制了靜態圖像。

這是OpenGlVideoQtQuickRenderer的關鍵部分,即paint功能

void OpenGlVideoQtQuickRenderer::paint()
{
    if (this->firstRun) {
        this->firstRun = false;
        //qDebug() << "initializeGL";
        std::cout << "initializing gl" << std::endl;
        //初始化opengl (QOpenGLFunctions繼承)函數
        initializeOpenGLFunctions();

        datas[0] = new unsigned char[width*height];     //Y
        datas[1] = new unsigned char[width*height/4];   //U
        datas[2] = new unsigned char[width*height/4];   //V   

        //this->m_F  = QOpenGLContext::currentContext()->functions();

        //program加載shader(頂點和片元)腳本
        //片元(像素)
        std::cout << program.addShaderFromSourceCode(QOpenGLShader::Fragment, tString2) << std::endl;
        //頂點shader
        std::cout << program.addShaderFromSourceCode(QOpenGLShader::Vertex, vString2) << std::endl;

        //設置頂點坐標的變量
        program.bindAttributeLocation("vertexIn",A_VER);

        //設置材質坐標
        program.bindAttributeLocation("textureIn",T_VER);

        //編譯shader
        std::cout << "program.link() = " << program.link() << std::endl;

    }
    program.bind();

    //傳遞頂點和材質坐標
    //頂點
    static const GLfloat ver[] = {
        -1.0f,-1.0f,
        1.0f,-1.0f,
        -1.0f, 1.0f,
        1.0f,1.0f
    };

    //材質
    static const GLfloat tex[] = {
        0.0f, 1.0f,
        1.0f, 1.0f,
        0.0f, 0.0f,
        1.0f, 0.0f
    };

    //頂點
    glVertexAttribPointer(A_VER, 2, GL_FLOAT, 0, 0, ver);
    glEnableVertexAttribArray(A_VER);

    //材質
    glVertexAttribPointer(T_VER, 2, GL_FLOAT, 0, 0, tex);
    glEnableVertexAttribArray(T_VER);

    //glUseProgram(&program);
    //從shader獲取材質
    unis[0] = program.uniformLocation("tex_y");
    unis[1] = program.uniformLocation("tex_u");
    unis[2] = program.uniformLocation("tex_v");

    //創建材質
    glGenTextures(3, texs);

    //Y
    glBindTexture(GL_TEXTURE_2D, texs[0]);
    //放大過濾,線性插值   GL_NEAREST(效率高,但馬賽克嚴重)
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    //創建材質顯卡空間
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RED, width, height, 0, GL_RED, GL_UNSIGNED_BYTE, 0);

    //U
    glBindTexture(GL_TEXTURE_2D, texs[1]);
    //放大過濾,線性插值
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    //創建材質顯卡空間
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RED, width/2, height / 2, 0, GL_RED, GL_UNSIGNED_BYTE, 0);

    //V
    glBindTexture(GL_TEXTURE_2D, texs[2]);
    //放大過濾,線性插值
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    //創建材質顯卡空間
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RED, width / 2, height / 2, 0, GL_RED, GL_UNSIGNED_BYTE, 0);

    ///分配材質內存空間


    glActiveTexture(GL_TEXTURE0);
    glBindTexture(GL_TEXTURE_2D, texs[0]); //0層綁定到Y材質
    //修改材質內容(復制內存內容)
    glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, width, height, GL_RED, GL_UNSIGNED_BYTE, datas[0]);
    //與shader uni遍歷關聯
    glUniform1i(unis[0], 0);


    glActiveTexture(GL_TEXTURE0+1);
    glBindTexture(GL_TEXTURE_2D, texs[1]); //1層綁定到U材質
                                           //修改材質內容(復制內存內容)
    glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, width/2, height / 2, GL_RED, GL_UNSIGNED_BYTE, datas[1]);
    //與shader uni遍歷關聯
    glUniform1i(unis[1],1);


    glActiveTexture(GL_TEXTURE0+2);
    glBindTexture(GL_TEXTURE_2D, texs[2]); //2層綁定到V材質
                                           //修改材質內容(復制內存內容)
    glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, width / 2, height / 2, GL_RED, GL_UNSIGNED_BYTE, datas[2]);
    //與shader uni遍歷關聯
    glUniform1i(unis[2], 2);

    glDrawArrays(GL_TRIANGLE_STRIP,0,4);
    //this->update();

    // Not strictly needed for this example, but generally useful for when
    // mixing with raw OpenGL.
    m_window->resetOpenGLState();//COMMENT OR NOT?
}

這是我用來更新要繪制的緩沖區的函數:

void OpenGlVideoQtQuickRenderer::updateData(unsigned char**data)
{
    std::cout << "updating data..." << std::endl;
    memcpy(datas[0], data[0], width*height);
    memcpy(datas[1], data[1], width*height/4);
    memcpy(datas[2], data[2], width*height/4);
    //I should update something here

}

我唯一的問題是我看到函數updateData被新數據調用,因此緩沖區正在更新。 但是,屏幕繼續在其初始位置(綠色)。 我確定必須有一個必須調用的函數來更新所有內容。

我還有什么需要在updateDataupdateData嗎?

我嘗試了各種更新數據的方法,但是圖像仍然不會更新

            this->openGlVideoQtQuickRenderer->paint();
            if (this->openGlVideoQtQuick->window()) {
                std::cout << "window update" << std::endl;
                this->openGlVideoQtQuick->update();
                this->openGlVideoQtQuick->window()->update();
            }

但是,如果我調整屏幕大小,可以看到圖像的時間不到一秒鍾,並且圖像消失了。

如果有人想看一看的完整代碼: https : //github.com/lucaszanella/orwell/blob/2aff3b97abd88e6ec2980856718e1c8302d41616/OpenGlVideoQtQuick.cpp#L117

好吧,我試圖像您在上面看到的那樣更新窗口,但是唯一起作用的是

connect(window(), &QQuickWindow::afterRendering, this, &OpenGlVideoQtQuick::update, Qt::DirectConnection);

(而且我必須從上方關閉該更新窗口才能使此窗口正常工作)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM