【问题标题】:OpenGL renders triangle instead of quad [closed]OpenGL渲染三角形而不是四边形[关闭]
【发布时间】:2017-09-18 14:20:06
【问题描述】:

我目前正在尝试将纹理渲染为全屏 QWindow (Qt 5.9.1)。
由于纹理都是黑色的,我想通过告诉片段着色器将所有像素渲染为红色来确保索引是正确的,但显然这里发生了错误。
我在屏幕的左上角得到一个红色三角形而不是四边形。
我看不到我的代码所犯的错误,所以请您查看我的代码。
还有什么可能是只获得黑色纹理的原因,即使我使用glTexImage2D 上传的纹理看起来很好并且glGetError 中没有错误。
提前致谢。

OpenGL上下文和QWindow的初始化:

int i;
for( i=0;i<QApplication::screens().size();i++ )
{
    if(QApplication::screens().at(i)->name().compare(szScreenName)==0)
        break;
}
if(i==QApplication::screens().size())
    i--;

setGeometry(QApplication::screens().at(i)->availableGeometry());
showFullScreen();

setSurfaceType(QWindow::OpenGLSurface);
QSurfaceFormat fmt;
fmt.setSwapBehavior(QSurfaceFormat::SingleBuffer);
fmt.setRenderableType(QSurfaceFormat::OpenGLES);
setFormat(fmt);
_pContext = new QOpenGLContext(this);
_pContext->setFormat(fmt);
//_pContext->setShareContext(QOpenGLContext::globalShareContext());
_pContext->create();

QObject::connect( this, &DLP::postRenderSignal, this, &DLP::render );

_pContext->makeCurrent(this);
initializeOpenGLFunctions();

//_pTexManager = new TextureManager(QOpenGLContext::globalShareContext()->functions());
_pTexManager = new TextureManager(this);

char* szVertexShader =                          "#version 110\n"
                                                "attribute vec4 a_Position;\n"
                                                "attribute vec2 a_TexCoord;\n"
                                                "varying   vec2 v_TexCoord;\n"
                                                "void main()\n"
                                                "{\n"
                                                "    gl_Position = a_Position;\n"
                                                "    v_TexCoord = a_TexCoord;\n"
                                                "}\n";
char* szFragmentShader =                        "#version 110\n"
                                                "precision mediump float;\n"
                                                "varying vec2 v_TexCoord;\n"
                                                "uniform sampler2D u_Texture;\n"
                                                "void main()\n"
                                                "{\n"
                                                "    gl_FragColor = vec4(1.0,0.0,0.0,1.0);//texture2D( u_Texture, v_TexCoord );\n"
                                                "}\n";

//_nProgram = linkShader(QOpenGLContext::globalShareContext()->functions(), szVertexShader, szFragmentShader);
_nProgram = linkShader(this, szVertexShader, szFragmentShader);

if(_nProgram!=0)
{
    _nShaderSamplerLoc = glGetUniformLocation(_nProgram,"u_Texture");
    _nShaderTextureLoc = glGetAttribLocation(_nProgram,"a_TexCoord");
    _nShaderPositionLoc = glGetAttribLocation(_nProgram,"a_Position");
}

glGenBuffers(2, _pBuffers );

static const unsigned short pIndexData[] = { 0, 1, 2, 3 };
glBindBuffer(GL_ARRAY_BUFFER, _pBuffers[1]);
glBufferData(GL_ARRAY_BUFFER, sizeof(pIndexData), pIndexData, GL_STATIC_DRAW);

static const float pPosBuffer[20] = {
        -1,   1,   0,    0, 0,
         1,   1,   0,    1, 0,
        -1,  -1,   0,    0, 1,
         1   -1,   0,    1, 1,
};
glBindBuffer(GL_ARRAY_BUFFER, _pBuffers[0]);
glBufferData(GL_ARRAY_BUFFER, 20*4, pPosBuffer, GL_STATIC_DRAW);

渲染代码(DLP::render):

if (!isExposed() || !_pContext)
    return;

_pContext->makeCurrent(this);

glClearColor(0.0, 0.0, 0.0, 1.0);
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT);
glViewport(0,0,m_nWidth,m_nHeight);

glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

glUseProgram(_nProgram);

glBindBuffer(GL_ARRAY_BUFFER, _pBuffers[0]);
// Load the vertex position
glVertexAttribPointer(_nShaderPositionLoc, 3, GL_FLOAT, false, 5 * 4, (void*)0);
glEnableVertexAttribArray(_nShaderPositionLoc);
// Load the texture coordinate
//glVertexAttribPointer(_nShaderTextureLoc, 2, GL_FLOAT, false, 5 * 4, (void*)(3 * 4));
//glEnableVertexAttribArray(_nShaderTextureLoc);

glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, _pTexManager->getTexture(key));
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glUniform1i(_nShaderSamplerLoc, 0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _pBuffers[1]);
glDrawElements(GL_TRIANGLE_STRIP, 4, GL_UNSIGNED_SHORT, 0);
glDisableVertexAttribArray(_nShaderPositionLoc);
//glDisableVertexAttribArray(_nShaderTextureLoc);

glFinish();

_pContext->swapBuffers(this);



编辑:
此外,仅当我在 Qt 中有多个 OpenGL 上下文时才会发生此问题,例如4 个 Framebuffer 对象,QML Scenegraph 和这个 QWindow,所以 Qt 如何处理 OpenGL 上下文可能是个问题。

【问题讨论】:

  • 在黑暗中快速拍摄...您的glDawElements,不应该使用GL_TRIANGLE_STRIP 而不是GL_TRIANGLES吗?因为GL_TRIANGLES 期望每个三角形有 3 个顶点,而您只给它 4 个(第一个为 3 个,最后一个为 1 个)?一个条带将使用前一个顶点中的 2 个?
  • 你说得对,我没有更新那个代码段。 GL_TRIANGLE_STRIP 的错误仍然存​​在。
  • 我认为你的顶点顺序是错误的。你从右上到左下。您需要底部,左侧 -> 顶部,左侧 -> 底部,右侧 -> 右上角 - 之字形。
  • 更改顶点顺序没有帮助。我有一种感觉,Qt 弄乱了 opengl 状态机,因此它不能正常工作。我让它在一个配置中完美运行,我只有一个 opengl 上下文,当我有多个上下文时,我遇到了所描述的问题。
  • @Krustenkaese Qt 不能为你搞乱任何状态,但你可以;)。更好地检查 Edge 上面所说的内容。

标签: c++ qt opengl


【解决方案1】:

好的,问题解决了:
显然我的纹理数据有一些问题,它确实有奇怪的 alpha 数据,所以启用混合功能后它不会渲染纹理。 此外,矩形未正确呈现的原因是其中一个索引中的符号错误。
顺便说一句:Vogl 是查看 OpenGL 状态机以调试应用程序的非常有用的工具。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-04-08
    • 1970-01-01
    • 2020-04-05
    • 2017-02-04
    • 2021-06-29
    • 1970-01-01
    相关资源
    最近更新 更多