C++ OpenGL渲染在Linux机器上不工作(windows渲染)--可能与cmake脚本有关(请参阅更新)
我正在使用OpenGL开发一个自制的图形引擎。我使用C++、CGube、GLW和WxWIDGET。到现在为止,我只是在一台windows机器上工作,一切都很好。现在我尝试移植到linux。现在的问题是,除了渲染之外,一切似乎都正常。我使用了一个非常简单的着色器:C++ OpenGL渲染在Linux机器上不工作(windows渲染)--可能与cmake脚本有关(请参阅更新),c++,linux,opengl,C++,Linux,Opengl,我正在使用OpenGL开发一个自制的图形引擎。我使用C++、CGube、GLW和WxWIDGET。到现在为止,我只是在一台windows机器上工作,一切都很好。现在我尝试移植到linux。现在的问题是,除了渲染之外,一切似乎都正常。我使用了一个非常简单的着色器: #VERTEX // ---------------------------------------------- #version 430 core layout (location = 0) in vec3 VertexPosit
#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的检查,但没有得到任何结果。着色器的编译似乎按预期工作,程序运行时没有任何异常或其他问题,除了缺少输出。我还在另一个线程中读到了同样的问题发生在操作系统上。问题是,有一个对GlenableVertexAttributeArray的调用没有VAO边界。但我不是这样。以下是我如何生成对象的代码片段:
// 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上构建的是动态的。我不确定这是否与使用的LIB有关。也许有一些不见了,但我希望链接者会对此抱怨。我还检查了OpenGL使用的是哪个GPU,因为我也有一个板载芯片组,但输出显示的是正确的。到目前为止,我还不知道可能是什么问题。也许有人发现了一个错误,这个错误与Windows无关,而与linux无关。如果您需要其他代码片段,请告诉我。希望你能帮助我
-------------------更新--------------------------
我将在这里列出任何建议解决方案的结果,这样你就不必阅读所有帖子及其评论
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存储库中的libs解决的。现在我复制了企鹅的例子并编写了一个cmake文件。我这里也有同样的问题,除了那只失踪的企鹅,一切似乎都正常。所以我猜问题出在我的cmake脚本的某个地方,与程序本身无关
以下是脚本(忽略最小wxWidgets示例的2个命令):
更新2
现在我99%确定它与我的cmake脚本有关。我切换回我自己的构建wxWidgets。有了它(3.1版),我可以用提供的makefile构建penguin示例,如果我运行程序,我可以看到penguin。如果我用上面显示的cmake脚本构建相同的文件,所有的东西都会编译,但是企鹅不见了
那么我在我的cmake文件中做错了什么?少了什么?也许有人可以复制脚本并在自己的机器上试用?如果它在Windows上运行,但在Linux上不运行,那么您的驱动程序可能无法运行该OGL版本。 您使用哪个wxWidgets版本?在WX3.0之前,只有OGL2.1可用。在WX3.1中,OGL版本仅受操作系统驱动程序的限制,但您应该询问计划使用的版本。
您测试过wxWidgets OGL示例吗?这真的是所有的顶点着色器吗?我自己没有使用过Glew或wxWidgets,所以我不知道它们在编译之前是否会在某个地方插入额外的代码,但我假设在某个地方有一个“in-vec3 VertexExposition”
不要期望顶点属性的位置始终相同,除非通过使用“链接前”或“顶点着色器”中的布局限定符将它们放置在固定位置。用于让glEnableVertexAttribArray和glVertexAttribPointer确切知道它们在哪里。如果您试图渲染的内容在Windows上工作,这可能就是问题所在。wxWidgets的当前版本是3.0.2。(Ubuntu)。我运行的唯一示例是企鹅示例,它很好。但我认为这是一个基于老OGL版本的安静的老样本。如果您认为其中一个依赖于当前的OGL版本,我将尝试其他版本。当我使用OpenGL命令获取当前着色语言版本时,它显示为4.5。我不完全确定,但我认为如果驱动程序工作不正常,它应该显示一个旧版本,或者不显示?在wxWidgets应用程序中获取当前的OGL版本。返回的版本取决于上下文创建。OGL上下文创建及其选项在wx 3.1使用的glGetString(GL_版本)中已更改,并返回4.5.0 NVIDIA 370.28。在原始帖子中添加了一个更新部分,在那里你可以看到我尝试了什么以及结果如何。这里也列出了一些其他的结果。嗨,不,这不是整个着色器,我已经编写了一个小的预处理器,它处理包括,所以我不必在每个着色器中重复代码。就是懒得复制包含的内容。我将编辑它,并把包括的行到开始后。这是我的错。但是我已经为我的着色器编写了一个小的预处理器,它允许我通过使用includes等重用代码。它还自动包含Version指令。我把它添加到原来的帖子中,以避免将来的烦恼。谢谢你,不用担心。我现在过时的评论。
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})