我正在使用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文件中做错了什么?少了什么东西?也许有人可以复制脚本并在他自己的机器上试用它?
答案 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上运行,则可能是问题所在。