OpenGL渲染无法在Linux机器上运行(Windows渲染)---可能与cmake脚本有关(请参阅更新)

时间:2016-12-03 16:15:33

标签: c++ linux opengl

我正在使用OpenGL开发自制图形引擎。我使用c ++,cmake,glew和wxWidgets。直到现在我只是在一台Windows机器上工作,一切都很好。现在我尝试移植到linux。现在的问题是,除渲染外,一切似乎都有效。我使用了一个非常简单的着色器:

#VERTEX // ----------------------------------------------
#version 430 core

layout (location = 0) in vec3 VertexPosition;
layout (location = 1) in vec3 VertexNormal;
layout (location = 2) in vec2 VertexTexCoord;

void main()
{
    gl_Position         = vec4(VertexPosition,1.0);
}



#FRAGMENT // --------------------------------------------

#version 430 core

out vec4 FragColor;

void main()
{
    FragColor = vec4(1.0,0.0,0.0,1.0);  
}

在Windows上,我可以渲染一个简单的红色方块,没有任何问题。在Linux上,没有,只有清晰的颜色(禁用背面剔除)。我还尝试每帧切换清晰的颜色,以查看上下文是否正确绑定并且交换正在工作。我得到了预期的闪烁屏幕,所以上下文和丢失掉期不是问题。我还插入了GLErrors的检查,但没有。着色器的编译似乎按预期工作,程序运行没有任何异常或其他问题,除了缺少输出。我还在另一个线程中读到了OS上发生同样的问题。问题是,没有VAO绑定就调用了glEnableVertexAttribArray。但对我来说情况并非如此。以下是我生成对象的代码片段:

// Create VAO
    glGenVertexArrays(1, &pVAOHandle_r);
    glBindVertexArray(pVAOHandle_r);

    // Create VBO
    glGenBuffers(1, &pVBOHandle_r);
    glBindBuffer(GL_ARRAY_BUFFER, pVBOHandle_r);

    // Transfer data
    glBufferData(GL_ARRAY_BUFFER, NumVertexAttribFloats * pVertices_cr.size() * sizeof(F32), VertexArray.data(), GL_STATIC_DRAW);


    // Set Attributes
    glEnableVertexAttribArray(0);
    glVertexAttribPointer(0,
                          3,
                          GL_FLOAT,
                          GL_FALSE,
                          NumVertexAttribFloats * sizeof(GLfloat),
                          0);

    U16 AttribNumber = 1;
    GLuint Offset = 12;

    if(pVertices_cr[0]->HasNormal())
    {
        glEnableVertexAttribArray(AttribNumber);
        glVertexAttribPointer(AttribNumber,
                              3,
                              GL_FLOAT,
                              GL_FALSE,
                              NumVertexAttribFloats * sizeof(GLfloat),
                              (void*)Offset);
        ++AttribNumber;
        Offset += 12;
    }
    if(pVertices_cr[0]->HasColor())
    {
        glEnableVertexAttribArray(AttribNumber);
        glVertexAttribPointer(AttribNumber,
                              4,
                              GL_FLOAT,
                              GL_FALSE,
                              NumVertexAttribFloats * sizeof(GLfloat),
                              (void*)Offset);
        ++AttribNumber;
        Offset += 16;
    }
    if(pVertices_cr[0]->HasTexCoord())
    {
        glEnableVertexAttribArray(AttribNumber);
        glVertexAttribPointer(AttribNumber,
                              2,
                              GL_FLOAT,
                              GL_FALSE,
                              NumVertexAttribFloats * sizeof(GLfloat),
                              (void*)Offset);
        ++AttribNumber;
        Offset+=8;
    }

这里是渲染调用:

    glBindVertexArray(mVertexMeshReference.GetVAO());
//  glBindBuffer(GL_ARRAY_BUFFER,mVertexMeshReference.GetVBO());
    glBindTexture(GL_TEXTURE_2D, mTextureReference.GetHandle());

    glDrawArrays(mVertexMeshReference.GetGLPrimitiveType(),
                 0,
                 mVertexMeshReference.GetNumPrimitives() * mVertexMeshReference.GetNumPrimitiveVertices());

我不确定是否必须再次绑定VBO,所以我测试了它,没有什么区别。

还有一个区别:在Windows上我动态地构建静态和Linux。我不确定它是否与使用过的库有关。也许有些人遗失了,但我希望链接器会抱怨它。我还检查了哪个GPU OpenGL正在使用,因为我也有一个板载芯片组,但输出显示正确的。到目前为止,我不知道可能是什么问题。也许有人发现了一个错误,这在Windows上与Linux无关。如果您需要其他代码段,请告诉我们。希望你能帮帮我。

-------------------更新-------------------------- < / p>

我会在此列出所有建议解决方案的结果,这样您就不需要阅读所有帖子及其评论。

OpenGL的输出:

   glGetString(GL_VENDOR) = NVIDIA Corporation
   glGetString(GL_RENDERER) = GeForce GTX 980M/PCIe/SSE2
   glGetString(GL_SHADING_LANGUAGE_VERSION) = 4.50 NVIDIA
   glGetString(GL_VERSION) = 4.5.0 NVIDIA 370.28

发现样品有同样的问题! 在其中一条评论中,我说样本正在运行。我错了。当我使用自己构建的wxWidgets时,他们工作。但是我的wxWidgets设置和cmake的其他问题是通过使用ubuntu存储库中的lib解决的。现在我复制了企鹅示例并编写了一个cmake文件。我在这里遇到了同样的问题,除了企鹅之外,一切似乎都有效。所以我猜这个问题出现在我的cmake脚本中,并且与程序本身无关。

这是脚本(忽略最小wxWidgets示例的2个命令):

 PROJECT(Sample)
CMAKE_MINIMUM_REQUIRED(VERSION 2.8)
SET(CMAKE_VERBOSE_MAKEFILE ON)


SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=gnu++14 -Wall  -Wno-long-long -pedantic -D__WXGTK__")

find_package(wxWidgets COMPONENTS gl core base REQUIRED)
FIND_PACKAGE(OpenGL)
include(${wxWidgets_USE_FILE})

add_executable(Minimal
   minimal.cpp)

target_link_libraries(Minimal ${wxWidgets_LIBRARIES})

add_executable(Penguin
   opengl/penguin/penguin.cpp
   opengl/penguin/dxfrenderer.cpp
   opengl/penguin/penguin_trackball.o)

LINK_DIRECTORIES(opengl/penguin)

target_link_libraries(Penguin
    ${wxWidgets_LIBRARIES}
    ${OPENGL_gl_LIBRARY}
    ${OPENGL_glu_LIBRARY})

更新2

现在我99%确定它与我的cmake脚本有关。我切换回自己构建的wxWidgets。有了它(3.1版),我可以使用提供的makefile构建企鹅样本,如果我运行程序,我可以看到企鹅。如果我使用上面显示的cmake脚本构建相同的文件,那么everthing编译,但企鹅丢失了!

那我在cmake文件中做错了什么?少了什么东西?也许有人可以复制脚本并在他自己的机器上试用它?

2 个答案:

答案 0 :(得分:0)

如果它在Windows上运行但在Linux上运行,则可能是您的驱动程序无法运行该OGL版本。

您使用哪个wxWidgets版本?在wx 3.0之前,只有OGL 2.1可用。对于wx 3.1,OGL版本仅受操作系统驱动程序的限制,但您应该询问您计划使用的版本。

您是否测试了wxWidgets OGL样本?

答案 1 :(得分:0)

这真的是所有的顶点着色器吗?我自己还没有使用Glew或wxWidgets,所以我不知道他们是否在编译之前在某处插入了额外的代码,但我认为在vec3中有一个&#34; VertexPosition&#34;某处。

永远不要指望顶点属性的位置始终相同,除非您在链接之前使用glBindAttribLocation或在顶点着色器中使用布局限定符将它们放在固定位置。使用glGetAttribLocation让glEnableVertexAttribArray和glVertexAttribPointer知道它们的位置。如果您尝试渲染的内容在Windows上运行,则可能是问题所在。