需要使用Qt5 Qml+;进行简单渲染的帮助吗;OpenGL

需要使用Qt5 Qml+;进行简单渲染的帮助吗;OpenGL,qt,opengl,qml,qt5,Qt,Opengl,Qml,Qt5,我需要使我的Qml视图的一部分被一些非Qt OpenGL渲染“接管”,并且我在正确显示纹理时遇到了问题,所以我想我应该在继续更复杂的代码之前画一条线并使其工作 对于那些不熟悉Qt5的人来说,整个窗口都是使用OpenGL绘制的,我正在使用QQuickWindow::beforeRendering()信号连接到Qt的OpenGL绘制机制,这意味着每次重画(每次垂直同步)都会执行我的绘制代码 我获取了Squircle示例代码()并对其进行了轻微修改,这样它就可以在屏幕的指定部分(而不是整个屏幕)中绘制

我需要使我的Qml视图的一部分被一些非Qt OpenGL渲染“接管”,并且我在正确显示纹理时遇到了问题,所以我想我应该在继续更复杂的代码之前画一条线并使其工作

对于那些不熟悉Qt5的人来说,整个窗口都是使用OpenGL绘制的,我正在使用QQuickWindow::beforeRendering()信号连接到Qt的OpenGL绘制机制,这意味着每次重画(每次垂直同步)都会执行我的绘制代码

我获取了Squircle示例代码()并对其进行了轻微修改,这样它就可以在屏幕的指定部分(而不是整个屏幕)中绘制,并且工作得非常好。然后,我修改了renderer::paint()函数,最初画三条绿线,2秒钟后画一条蓝线:

void CtRenderer::paint()
{
static int n = 0;

if (n == 0)
{
    glViewport(m_rect.x() + 10, m_rect.y() + 10, m_rect.width() - 20, m_rect.height() - 20);

    glEnable(GL_SCISSOR_TEST);
    glScissor(m_rect.x() + 10, m_rect.y() + 10, m_rect.width() - 20, m_rect.height() - 20);

    glDisable(GL_DEPTH_TEST);
    glDisable(GL_LIGHTING);

    // glClearColor(1, 0, 0, 1);
    // glClear(GL_COLOR_BUFFER_BIT);

    glLineWidth(10);
    glColor4f(0.0, 1.0, 0.0, 1);
    glBegin(GL_LINES);
    glVertex3f(0.0, 0.0, 1);        glVertex3f(1, 0.5, 1);
    glVertex3f(0.0, 0.0, 1);        glVertex3f(0.5, 0.5, 1);
    glVertex3f(0.0, 0.0, 1);        glVertex3f(0.5, 1, 1);
    glEnd();
}
else if (n == 120)
{
    glViewport(m_rect.x() + 10, m_rect.y() + 10, m_rect.width() - 20, m_rect.height() - 20);

    glEnable(GL_SCISSOR_TEST);
    glScissor(m_rect.x() + 10, m_rect.y() + 10, m_rect.width() - 20, m_rect.height() - 20);

    glDisable(GL_DEPTH_TEST);
    glDisable(GL_LIGHTING);

    // glClearColor(1, 0, 0, 1);
    // glClear(GL_COLOR_BUFFER_BIT);

    glLineWidth(10);
    glColor4f(0.0, 0.0, 1.0, 1);
    glBegin(GL_LINES);
    glVertex3f(0.0, 0.0, 1);        glVertex3f(0.4, 0.8, 1);
    glEnd();

}
n++;

return;
}`

取而代之的是三条不断闪烁的灰线,永远不会变成一条线。经过一些在线调查,我认为也许我不应该使用glBegin()/glEnd(),所以我更改了代码:

void CtRenderer::paint()
{
static bool bOnce = true;

if (bOnce)
{
    glViewport(m_rect.x() + 10, m_rect.y() + 10, m_rect.width() - 20, m_rect.height() - 20);

    glEnable(GL_SCISSOR_TEST);
    glScissor(m_rect.x() + 10, m_rect.y() + 10, m_rect.width() - 20, m_rect.height() - 20);

    float vertices[] = {-0.5f, -0.5f, 0.5f, 0.5f};

    glLineWidth(10);
    glColor4f(0.0, 1.0, 0.0, 1);

    glEnableClientState(GL_VERTEX_ARRAY);
    glVertexPointer(2, GL_FLOAT, 0, vertices);

    glDrawArrays(GL_LINES, 0, 2);

    glDisableClientState(GL_VERTEX_ARRAY);

    bOnce = false;
}

return;
}
这仍然给我一条闪烁的灰线

当我在Qt之外的一个简单的GLUT应用程序中尝试这段代码时,它工作得很好,所以它似乎是OpenGL和qt5qml之间的一些交互。下一步我能试试什么

p、 我在Linux Ubuntu上使用Qt5.3版

p、 另外,为了回应一些评论,我更新了代码,如下所示:

void dumpGlErrors(int iLine)
{
for (;;)
{
    GLenum err = glGetError();
    if (err == GL_NO_ERROR)
        return;
    std::cout << "GL error " << err << " detected in line " << iLine << std::endl;
}
}

void CtRenderer::paint()
{
glPushMatrix();

glLoadIdentity();

glViewport(m_rect.x() + 10, m_rect.y() + 10, m_rect.width() - 20, m_rect.height() - 20);

glEnable(GL_SCISSOR_TEST);
glScissor(m_rect.x() + 10, m_rect.y() + 10, m_rect.width() - 20, m_rect.height() - 20);

dumpGlErrors(__LINE__);

glClearColor(1, 0, 1, 1);       // Magenta
glClear(GL_COLOR_BUFFER_BIT);

bool bDepth = glIsEnabled(GL_DEPTH_TEST);
glDisable(GL_DEPTH_TEST);

bool bLighting = glIsEnabled(GL_LIGHTING);
glDisable(GL_LIGHTING);

bool bTexture = glIsEnabled(GL_TEXTURE_2D);
glDisable(GL_TEXTURE_2D);

dumpGlErrors(__LINE__);

float vertices[] = { -0.5f, -0.5f, 0.1f,  0.5f, 0.5f, 0.1f,  0.5f, 0.5f, 1.0f,  0.5f, -0.5f, 1.0f };
float colors[] = { 0.0f, 1.0f, 0.0f, 1.0f,  1.0f, 0.0f, 0.0f, 1.0f,  0.0f, 0.0f, 1.0f, 1.0f,  1.0f, 1.0f, 0.0f, 1.0f };

glLineWidth(10);
glColor4f(0.0, 0.0, 1.0, 1);

glEnableClientState(GL_VERTEX_ARRAY);
glVertexPointer(3, GL_FLOAT, 0, vertices);

glEnableClientState(GL_COLOR_ARRAY);
glColorPointer(4, GL_FLOAT, 0, colors);

dumpGlErrors(__LINE__);

glDrawArrays(GL_LINES, 0, 4);       // 4, not 2.

dumpGlErrors(__LINE__);

// glFlush();

glDisableClientState(GL_COLOR_ARRAY);
glDisableClientState(GL_VERTEX_ARRAY);

if (bTexture)
    glEnable(GL_TEXTURE_2D);

if (bLighting)
    glEnable(GL_LIGHTING);

if (bDepth)
    glEnable(GL_DEPTH_TEST);

glPopMatrix();

dumpGlErrors(__LINE__);

// In case somebody else calls glClear()
glClearColor(0, 1, 1, 1);       // Cyan
}
void dumpGlErrors(intiline)
{
对于(;;)
{
GLenum err=glGetError();
if(err==GL\u无错误)
返回;

std::cout使用Qt Quick,有三种方法可以混合使用OpenGL:

  • 可以在(整个)QML下绘制(请参见)
  • 您可以在(整个)QML上绘制
  • 可以提供在QML元素上绘制的OpenGL纹理(请参见)
  • 或者,您可以构建一个QWidget应用程序,并在QWidget窗口中使用OpenGL,在另一个(QML widget窗口)中使用QML

    我的结论是将OpenGL的遗留版本留在历史书中。即使它是针对那些虚拟着色器,它也可以为您节省管理任何矩阵的麻烦,并且您知道发生了什么


    PS:代码还没有经过测试,这只是Squircle代码的一个调整。如果有问题,请告诉我,但我更愿意从这段代码继续疑难解答会话。

    我发现了答案:我必须告诉Qt我正在使用旧的固定函数管道。在进行任何绘图之前进行一次函数调用可以:

    QOpenGLFunctions glFuncs(QOpenGLContext::currentContext());
    glFuncs.glUseProgram(0);
    

    您可能缺少要求代码中的
    glClear…
    部分。如果我在glScissor()后面添加“glClearColor(0,1,0,1);”和“glClear(GL_COLOR_BUFFER_BIT);”,除了闪烁的灰线,我还得到了闪烁的绿色背景。奇怪的是,绿色背景是半透明的,即使alpha到glColor是1。它看起来是半透明的,因为你的眼睛跟不上。你的问题是因为你有两个缓冲区(前和后)时,你只画了一幅画。第一次绘制调用更新后缓冲区,然后交换缓冲区,然后调用绘制,但它不会执行任何操作,因为
    if
    未通过。再次交换缓冲区,因此为黑色缓冲区。然后重新绘制,绿色+行。然后再次交换,依此类推。如果将bunce设置为n
    int
    等于0,并且if检查值低于2,则会执行此操作有关颜色的工作,认为自己有一个白线是幸运的(不是灰色的,再一次,它只是你的眼睛不能跟上)我想,
    glColor4f
    不适用于
    glDrawArrays
    。试试
    glColorPointer
    。它可以作为
    glVertexPointer
    ,但我从未使用过它,固定管道对我来说是一个奇迹。感谢你的建议,我尝试实现了它们,正如你所看到的(我编辑了我的主要帖子)结果不同,但仍然不完全正确。Squircle代码(我的绘画基于此)使用QML样式下的OpenGL。我想在OpenGL上绘制Qt项(如标签)所以#2对我来说不太好,最终我会有一个相当复杂的OpenGL渲染,我不希望转换成纹理然后返回到OpenGL(GPU和CPU之间交换太多)因此,我的问题不是我应该使用哪种混合OpenGL的方法,而是如何才能让这种特定的方法发挥作用。事实上,我现在看到你特别提到你从示例下的Squircle draw开始。你有一个#2(在qml上绘制)的示例吗?我没有发现太多。我对此感兴趣,因为我有一个场景图(也基于Squircle示例)然后是一个Qt3D渲染设置,它的
    ClearBuffer
    正在擦除我的场景图,我不知道如何将两者都显示出来,或者将我的场景图放在Qt3D的场景图上。对我之前的评论的回复:我最初尝试这个时犯了一个错误,但事实证明,这就像之前更改
    的连接一样简单eRendering
    事件到
    afterRendering
    “检查您使用的程序是否为0(默认固定管道)”。但我确实要求您检查这一点。我应该更清楚地知道要调用什么函数。不要使用固定管道->[]回顾讨论,我现在明白了!当时我不知道管道是什么,所以我对信息做不了太多。即使是我最终找到的答案,我也有点意外地发现了…我找到了一些有效的代码,它在顶部有一个神奇的函数调用,我尝试了它,它成功了。但是你对我的帮助很大我,我很高兴给你赏金!
    void SquircleRenderer::paint()
    {
        if (!m_program) {
            m_program = new QOpenGLShaderProgram();
            m_program->addShaderFromSourceCode(QOpenGLShader::Vertex,
                                               "attribute highp vec4 aVertices;"
                                               "attribute highp vec4 aColors;"
                                               "varying highp vec4 vColors;"
                                               "void main() {"
                                               "    gl_Position = aVertices;"
                                               "    vColors= aColors;"
                                               "}");
            m_program->addShaderFromSourceCode(QOpenGLShader::Fragment,
                                               "varying highp vec4 vColors;"
                                               "void main() {"
                                               "    gl_FragColor = vColors;"
                                               "}");
    
            m_program->bindAttributeLocation("aVertices", 0);
            m_program->bindAttributeLocation("aColors", 1);
            m_program->link();
    
        }
    
        m_program->bind();
    
        m_program->enableAttributeArray(0);
        m_program->enableAttributeArray(1);
    
        float vertices[] = {
            -1, -1, //Diag bottom left to top right
            1, 1,
            -1, 1, //Diag top left to bottom right
            1, -1,
            -1, 0, //Horizontal line
            1, 0
        };
        float colors[] = {
            1, 1, 0, 1, 
            1, 0, 1, 1,
            0, 1, 1, 1,
            1, 0, 0, 1,
            0, 0, 1, 1,
            0, 1, 0, 1
        };
        m_program->setAttributeArray(0, GL_FLOAT, vertices, 2); //3rd to 0, 4th to 1 by default
        m_program->setAttributeArray(1, GL_FLOAT, colors, 4); 
    
        glViewport(0, 0, m_viewportSize.width(), m_viewportSize.height());
    
        glDisable(GL_DEPTH_TEST);
    
        glClearColor(0, 0, 0, 1);
        glClear(GL_COLOR_BUFFER_BIT);
    
        //Here I draw 3 lines, reduce to 2 instead of 6 to draw only one.
        //Change second param to choose which line to draw
        glDrawArrays(GL_LINES, 0, 6);
    
        m_program->disableAttributeArray(0);
        m_program->disableAttributeArray(1);
        m_program->release();
    }
    
    QOpenGLFunctions glFuncs(QOpenGLContext::currentContext());
    glFuncs.glUseProgram(0);