Mac上OpenGL红宝书例程环境适配

参考:OpenGL编程指南第8版(红宝书)
参考:https://github.com/badousuan/openGLredBook9th
(Owed by: 春夜喜雨 http://blog.csdn.net/chunyexiyu)

使用Mac环境:Mojave 10.14

1. 背景介绍:

OpenGL编程指南中的例子有许多,在使用的时候,可以从书中对应的官网下载例程,下载编译&构建使用。
官网对应的地址:http://opengl-redbook.com/ 官网中放的有例程所在的git地址和提供zip包下载。

不过对于Mac电脑来说,下载下来的包却不完全能匹配上,主要有两个原因:

  1. Mac系统中的OpenGL版本是4.1版本,而对应的例程是OpenGL version 4.5版本的。
  2. CMakeLists.txt中的配置主要针对win32和linux等进行配置的,而mac和linux并不相同,使用linux的配置有一定的问题。

2. 研究探索

首先参考安装了cmake(glew/glfw/freeglut这几个不需要安装)
https://blog.csdn.net/chunyexiyu/article/details/89063590
之后就是不断的发现并处理错误。

编译构建顺序是,进入目录后通过cmake创建makefile,然后执行make
cmake .
make
也可指定单独make某个例子
make 01-triangles

遇到的问题有:

a. fatal error: #include

这个问题的原因是在MacOS中,OpenGL的目录是Framework的名称OpenGL,和Linux不同,需要手动修改头文件。
方法一:
替换./include/LoadShaders.h中的 GL/gl.h 为 OpenGL/gl.h
方法二:
从系统中找出gl.h,放入到./include/GL/中
例如这个位置:

/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/System/Library/Frameworks/OpenGL.framework/Versions/A/Headers/gl.h

方法三:
在include/GL目录中新建一个gl.h,内容为

#include “OpenGL/gl.h”

b. error goto: jump bypasses variable

jump bypasses variable,goto跳转时,把同级变量的定义初始化跳过去了(同级:在同一层{}内)
处理这个问题的方法也有两个:
方法一:在makefile中添加编译选项,把该错误注释掉—这种方法我暂未去查找使用,对编译选项感兴趣的可以去查查用哪个编译选项。
方法二:把下面的变量定义初始化等处理放入{}内,从而让它们不位于同一层次。

例如这个错误对应的文件vdds.cpp中,把goto以下变量初始化部分大括号括起来—从line605-644行。

c. error timeval: forward declaration of timeval

timeval相当于未定义,解决方法,添加定义
vapp.h中添加
#include

d. error: memset/memcpy

未包含定义,添加定义
lib/vbm.cpp, src/10-fur/10-fur.cpp中添加
#include

e. ld: library not found for -lGL

链接含库文件时,使用-lGL有问题:这是因为在Mac中,对于OpenGL采用的是framework的包含形式,包含的语句应该采用 -framework OpenGL
修改文件CMakeLists.txt第25行,修改为

elseif (UNIX)
    if (APPLE)
        set(COMMON_LIBS vermilion ${OPENGL_LIBRARIES} glfw ${GLFW_LIBRARIES} stdc++ "-framework OpenGL")
    else()
        set(COMMON_LIBS vermilion ${OPENGL_LIBRARIES} glfw ${GLFW_LIBRARIES} GL rt dl) 
    endif()

f. error std::sqrt

sqrt未定义,添加定义
在include/mat.h添加
#include

g. error: #version 430 core\n

这个问题的原因是在于这一行未能和上面的标示符号连接起来导致的,把
#version 430往前挪一行即可
在 src/12-particlesimulator/12-particlesimulator.cpp 行113,修改为
STRINGIZE(#version 430 core\n

h. 运行时报错:Segmentation fault: 11

其中一个例子:
make 01-triangles 构建出了文件./bin/01-triangles_d
执行时报错:
Segmentation fault: 11
查看崩溃报告能看出崩溃在01-triangles.cpp:37

Thread 0 Crashed:: Dispatch queue: com.apple.main-thread
0   ???                           	000000000000000000 0 + 0
1   01-triangles_d                	0x000000010e6bfcea init() + 186 (01-triangles.cpp:37)
2   01-triangles_d                	0x000000010e6bff90 main + 96 (01-triangles.cpp:98)
3   libdyld.dylib                 	0x00007fff76e48ed9 start + 1

而这一行的代码是:
glCreateBuffers( NumBuffers, Buffers );
崩溃原因是这一行的函数为空指针,glCreateBuffers为OpenGL4.5版本新加的函数,所以在4.1版本下不存在的。
修改方法,使用glGenBuffers来替换glCreateBuffers。还有函数glBufferStorage修改为glBufferData,第四个参数修改为GL_STATIC_DRAW。

类似的函数可以通过在gl3wInit–>get_proc打点找出来所有加载失败的函数,共有206个:
glDrawArraysInstancedBaseInstance, glDrawElementsInstancedBaseInstance, glDrawElementsInstancedBaseVertexBaseInstance, glGetActiveAtomicCounterBufferiv, glBindImageTexture, glMemoryBarrier, glDrawTransformFeedbackInstanced, glDrawTransformFeedbackStreamInstanced, glClearBufferData, glClearBufferSubData, glDispatchCompute, glDispatchComputeIndirect, glCopyImageSubData, glFramebufferParameteri, glGetFramebufferParameteriv, glGetInternalformati64v, glInvalidateTexSubImage, glInvalidateTexImage, glInvalidateBufferSubData, glInvalidateBufferData, glInvalidateFramebuffer, glInvalidateSubFramebuffer, glMultiDrawArraysIndirect, glMultiDrawElementsIndirect, glGetProgramInterfaceiv, glGetProgramResourceIndex, glGetProgramResourceName, glGetProgramResourceiv, glGetProgramResourceLocation, glGetProgramResourceLocationIndex, glShaderStorageBlockBinding, glTexBufferRange, glTexStorage2DMultisample, glTexStorage3DMultisample, glTextureView, glBindVertexBuffer, glVertexAttribFormat, glVertexAttribIFormat, glVertexAttribLFormat, glVertexAttribBinding, glVertexBindingDivisor, glDebugMessageControl, glDebugMessageInsert, glDebugMessageCallback, glGetDebugMessageLog, glPushDebugGroup, glPopDebugGroup, glObjectLabel, glGetObjectLabel, glObjectPtrLabel, glGetObjectPtrLabel, glBufferStorage, glClearTexImage, glClearTexSubImage, glBindBuffersBase, glBindBuffersRange, glBindTextures, glBindSamplers, glBindImageTextures, glBindVertexBuffers, glClipControl, glCreateTransformFeedbacks, glTransformFeedbackBufferBase, glTransformFeedbackBufferRange, glGetTransformFeedbackiv, glGetTransformFeedbacki_v, glGetTransformFeedbacki64_v, glCreateBuffers, glNamedBufferStorage, glNamedBufferData, glNamedBufferSubData, glCopyNamedBufferSubData, glClearNamedBufferData, glClearNamedBufferSubData, glMapNamedBuffer, glMapNamedBufferRange, glUnmapNamedBuffer, glFlushMappedNamedBufferRange, glGetNamedBufferParameteriv, glGetNamedBufferParameteri64v, glGetNamedBufferPointerv, glGetNamedBufferSubData, glCreateFramebuffers, glNamedFramebufferRenderbuffer, glNamedFramebufferParameteri, glNamedFramebufferTexture, glNamedFramebufferTextureLayer, glNamedFramebufferDrawBuffer, glNamedFramebufferDrawBuffers, glNamedFramebufferReadBuffer, glInvalidateNamedFramebufferData, glInvalidateNamedFramebufferSubData, glClearNamedFramebufferiv, glClearNamedFramebufferuiv, glClearNamedFramebufferfv, glClearNamedFramebufferfi, glBlitNamedFramebuffer, glCheckNamedFramebufferStatus, glGetNamedFramebufferParameteriv, glGetNamedFramebufferAttachmentParameteriv, glCreateRenderbuffers, glNamedRenderbufferStorage, glNamedRenderbufferStorageMultisample, glGetNamedRenderbufferParameteriv, glCreateTextures, glTextureBuffer, glTextureBufferRange, glTextureStorage1D, glTextureStorage2D, glTextureStorage3D, glTextureStorage2DMultisample, glTextureStorage3DMultisample, glTextureSubImage1D, glTextureSubImage2D, glTextureSubImage3D, glCompressedTextureSubImage1D, glCompressedTextureSubImage2D, glCompressedTextureSubImage3D, glCopyTextureSubImage1D, glCopyTextureSubImage2D, glCopyTextureSubImage3D, glTextureParameterf, glTextureParameterfv, glTextureParameteri, glTextureParameterIiv, glTextureParameterIuiv, glTextureParameteriv, glGenerateTextureMipmap, glBindTextureUnit, glGetTextureImage, glGetCompressedTextureImage, glGetTextureLevelParameterfv, glGetTextureLevelParameteriv, glGetTextureParameterfv, glGetTextureParameterIiv, glGetTextureParameterIuiv, glGetTextureParameteriv, glCreateVertexArrays, glDisableVertexArrayAttrib, glEnableVertexArrayAttrib, glVertexArrayElementBuffer, glVertexArrayVertexBuffer, glVertexArrayVertexBuffers, glVertexArrayAttribBinding, glVertexArrayAttribFormat, glVertexArrayAttribIFormat, glVertexArrayAttribLFormat, glVertexArrayBindingDivisor, glGetVertexArrayiv, glGetVertexArrayIndexediv, glGetVertexArrayIndexed64iv, glCreateSamplers, glCreateProgramPipelines, glCreateQueries, glGetQueryBufferObjecti64v, glGetQueryBufferObjectiv, glGetQueryBufferObjectui64v, glGetQueryBufferObjectuiv, glMemoryBarrierByRegion, glGetTextureSubImage, glGetCompressedTextureSubImage, glGetGraphicsResetStatus, glGetnCompressedTexImage, glGetnTexImage, glGetnUniformdv, glGetnUniformfv, glGetnUniformiv, glGetnUniformuiv, glReadnPixels, glTextureBarrier, glGetTextureHandleARB, glGetTextureSamplerHandleARB, glMakeTextureHandleResidentARB, glMakeTextureHandleNonResidentARB, glGetImageHandleARB, glMakeImageHandleResidentARB, glMakeImageHandleNonResidentARB, glUniformHandleui64ARB, glUniformHandleui64vARB, glProgramUniformHandleui64ARB, glProgramUniformHandleui64vARB, glIsTextureHandleResidentARB, glIsImageHandleResidentARB, glVertexAttribL1ui64ARB, glVertexAttribL1ui64vARB, glGetVertexAttribLui64vARB, glCreateSyncFromCLeventARB, glDispatchComputeGroupSizeARB, glDebugMessageControlARB, glDebugMessageInsertARB, glDebugMessageCallbackARB, glGetDebugMessageLogARB, glMultiDrawArraysIndirectCountARB, glMultiDrawElementsIndirectCountARB, glGetGraphicsResetStatusARB, glGetnTexImageARB, glReadnPixelsARB, glGetnCompressedTexImageARB, glGetnUniformfvARB, glGetnUniformivARB, glGetnUniformuivARB, glGetnUniformdvARB, glBufferPageCommitmentARB, glNamedBufferPageCommitmentEXT, glNamedBufferPageCommitmentARB

k. 运行时未报错,但屏幕不显示图形

例如运行
./01-triangles_d

  1. 首先,需要在bin目录下运行,因为依赖的shader位于media目录下,且使用的相对路径
  2. 其次,shader的版本需要在410以下,而./media/shaders/triangles/triangles.frag版本写的是450,需要修改为410或400
  3. 最后,代码中也需要稍作修改,在main函数中的glfwInit()之后,添加代码glfwWindowHint的几个设置。
    这几个参数用来设置使用内核OpenGL3.2版本的兼容模式,因为在Mac下,缺省版本是低于这个版本的。
    glfwInit();
    glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
    glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
    glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); 
    glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 2); 

修改后,运行显示的结果:
./01-triangles_d
Mac上OpenGL红宝书例程环境适配_第1张图片

3. 从Github上下载适配Mac版样例

在Mac电脑上,使用红宝书学习使用OpenGL,大家都不会是第一个,自然的,在github上有做这种修改的同学:
下面的这个地址,就是一个同学对红宝书中的样例源码进行修改,适配Mac环境
https://github.com/badousuan/openGLredBook9th

我试用了,是基本可用的,自己研究的时候,也借鉴了里面的修改方法,建议下载使用。

另外问题都是相通的,如果遇到问题的话,可以参考上面的问题分析来解决。

(Owed by: 春夜喜雨 http://blog.csdn.net/chunyexiyu)

你可能感兴趣的:(OpenGL,Mac,OpenGL)