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