用MinGW编译《OpenGL超级宝典 SuperBibe 5th》(OpenGL蓝皮书) 示例代码

回复
头像
523066680
Administrator
Administrator
帖子: 573
注册时间: 2016年07月19日 12:14
联系:

用MinGW编译《OpenGL超级宝典 SuperBibe 5th》(OpenGL蓝皮书) 示例代码

帖子 523066680 »

以下内容以及方法均参考自老外在stackoverflow上的回答,建议看看原文,因为他告诉你解决问题的思路而不只是结果。
opengl-superbible-5th-edition-set-up-problems

我将其整理修改成了用MINGW配合命令行进行编译的方法,不涉及code::blocks

1. 还未安装MinGW的,去官网下一个,我这里用的是第三方的安装包 TDM-GCC32位下载地址

2. 到 http://freeglut.sourceforge.net/ 下载最新版本的 freeglut,写此文章时的版本是freeglut-2.8.1.tar.gz
  • a. 解压freeglut-2.8.1.tar.gz 得到 freeglut-2.8.1目录,复制到C盘,打开命令行,输入 "cd /d c:\freeglut-2.8.1\src"
    b. 执行"gcc -O2 -c -DFREEGLUT_STATIC *.c -I../include"
    c. 执行"ar rcs libfreeglut32_static.a *.o" 生成 libfreeglut32_static.a,编译过程可能出现警告,但是只要生成了.a文件,就拿来用吧
    d. 在freeglut-2.8.1 目录下建立 lib 文件夹,将生成的 libfreeglut32_static.a 复制进去
3. 到OpenGL超级宝典 官方网站下载源码包 SB5.zip
  • a. 解压,里面有4个目录,freeglut, linux, visualstudio 以及 src。 进入src,复制GLTools目录到C盘,打开命令行,"cd /d c:\GLTools"
    b. 执行 "g++ -c *.cpp -I../include" (和之前freeglut类似,进行编译、链接、生成静态资源库。)
    c. 执行 "ar rcs libGLTools.a *.o"
    d. 在C:\GLTools下 建立lib目录,将 libGLTools.a 复制进去,即:C:\GLTools\lib\libGLTools.a
    e. 同样是在GLTools目录,执行 "g++ -c glew.c -I../include" 然后 "ar rcs libglew.a glew.o" ,复制libglew.a 到 C:\GLTools\lib\目录
照理说这里就已经把所有的静态链接库都生成好了,分别是:
  • C:\freeglut-2.8.1\lib\libfreeglut32_static.a
    C:\GLTools\lib\libglew.a
    C:\GLTools\lib\libGLTools.a
现在尝试编译蓝皮书第二章的示例 Trangle.cpp ,需要把刚生成的3个库文件以及对应目录添加到编译选项中去
写成g++语句会很长,所以写到 Makefile 文件
  • MAIN = Triangle
    LIBDIRS = -LC:/freeglut-2.8.1/lib -LC:/GLTools/lib
    INCDIRS = -IC:/freeglut-2.8.1/include -IC:/GLTools/include

    CC = g++
    LIBS = -lGLTools -lglew -lfreeglut32_static

    $(MAIN):
    ${CC} $(INCDIRS) $(CFLAGS) -o ${MAIN} ${MAIN}.c $(LIBDIRS) $(LIBS)
打开命令行,进入相同目录,敲入 mingw32-make
提示:error: 'GLAPI' does not name a type,解决方法,在#include <GLTools.h>之后加入
#define GLAPI extern
  • // Triangle.cpp
    // Our first OpenGL program that will just draw a triangle on the screen.

    #include <GLTools.h> // OpenGL toolkit
    #define GLAPI extern
    #include <GLShaderManager.h> // Shader Manager Class

    #ifdef __APPLE__
    #include <glut/glut.h> // OS X version of GLUT
    #else
    #define FREEGLUT_STATIC
    #include <GL/glut.h> // Windows FreeGlut equivalent
    #endif
再次执行mingw32-make ,提示undefined reference to `glViewport@16',修改Makefile
LIBS 增加 -lopengl32 ,之后编译还会遇到几次类似的函数未定义的问题,找到它们对应的库,并增加到 LIBS 的链接中去。
最后的Makefile是这样的
  • MAIN = Triangle
    LIBDIRS = -LC:/freeglut-2.8.1/lib -LC:/GLTools/lib
    INCDIRS = -IC:/freeglut-2.8.1/include -IC:/GLTools/include

    CC = g++
    LIBS = -lGLTools -lglew -lfreeglut32_static -lwinmm -lgdi32 -lopengl32

    $(MAIN):
    ${CC} $(INCDIRS) $(CFLAGS) -o ${MAIN} ${MAIN}.c $(LIBDIRS) $(LIBS)
再次执行 mingw32-make ,没有错误提示,看看目录下是否已经生成 Triangle.exe ?

注:以上方法本人在winxp以及WIN7 64位平台均测试过没有问题。

==========================================================================================================
以上某些步骤,错误解决的具体思路,请看英文原文或者2楼的详细翻译
头像
523066680
Administrator
Administrator
帖子: 573
注册时间: 2016年07月19日 12:14
联系:

原文翻译 - Code::block 配置方案

帖子 523066680 »

原文:opengl-superbible-5th-edition-set-up-problems
以下是翻译内容,其中路径部分在使用MSYS时斜杠是/,在使用cmd的时候斜杠应改为\ 。 另,不当之处,欢迎批评指正!

在编译《OpenGL超级宝典 第5版》第二章的Triangle示例代码时遇到了和你一样的问题。并且同样是使用 Code::Blocks + MinGW 。经过
不懈的努力,已经基本得到解决。

现在从头开始,第一件事就是设置正确的环境,配置 freeglut 以及 GLTools 库。

在这之前请安装好最新版本的MinGW,以及MSYS(其实不一定要MSYS,CMD也可以)。然后检查环境变量%path%是否已经包含了
C:/MinGW/bin。还要有个文件解压工具比如7z

设置 freeglut-2.6.0(现在已经是2.8.1),首先从源代码中编译出静态资源库。
  1. http://freeglut.sourceforge.net/ 下载最新版本
  2. 在C:盘建立 libs 文件夹,复制并解压 freeglut-2.6.0.tar.gz 文件
  3. 运行 MSYS (c:/MinGW/msys/1.0/msys.bat)。
  4. 输入"cd /c/libs/freeglut-2.6.0/src" 并按Enter以进入对应目录。
  5. 执行"gcc -O2 -c -DFREEGLUT_STATIC *.c -I../include"
    其中-O为优化选项,(这里优化级别为2);-DFREEGLUT_STATIC 定义宏,使它能够通过源码中的#ifdef 检验;
    并且从相应的从 "../include" 目录中寻找头文件
  6. 执行 "ar rcs libfreeglut32_static.a *.o"
    ar是一个编译静态库(.a文件)的工具,该命令从之前编译好的.o文件创建libfreeglut32_static.a
  7. 接着在 c:/libs/freeglut-2.6.0 目录下建立 lib 文件夹。然后把刚刚建立的.a文件复制过来。确切的位置是:
    "c:/libs/freeglut-2.6.0/lib/libfreeglut32_static.a"
以下链接解释了MinGW编译freeglut的一些细节。
<http://pinyotae.blogspot.com/2010/05/bu ... mingw.html>

在我们设置GLTools之前,为了确保freeglut能够正常运转:
  1. 打开Code::Blocks, 关掉任何打开的其他项目。进入"Settings->Compiler and Debugger" 然后打开 "Search Dierctory" (搜索目录)
    标签,在编译器 - 包含目录中,增加:"c:/libs/freeglut-2.6.0/include/"
    在链接库的目录列表中,添加: "c:/libs/freeglut-2.6.0/lib/"
  2. 建立新的项目,新建test.cpp文件,内容为 int main (){return 0;}
  3. 编译。(没问题对吧?)
  4. 在前面添加
    #define FREEGLUT_STATIC
    #include <GL/glut.h>
  5. 再次编译,编译失败。
  6. 在 Project->"Build Options" 选项点击右键,确定你选的是整个项目的选项,而不是debug或者release目标。移到 Linker 选项,增
    加链接库"freeglut32_static"
  7. 尝试编译,再次失败。编译器提示 "undefined reference to" 错误,列出一大堆函数,复制其中的第一个函数,去谷歌搜索解决办法
    ,通常前面几个结果会告诉你这些函数的功能,但更重要的是告诉你它们来自哪些库文件。
  8. 通过搜索,得出类似 xxxxx.lib 这样的库的名称,把这些库添加到链接库目录的列表中
  9. 再次尝试编译,又失败了。重复 第7、第8 步骤,直到编译通过为止。最后总结:为了能够让freeglut正常运转,必须添加 "Winmm",
    "Gdi32" 以及 "Opengl32" 库
  10. 再次编译。test.exe 终于出来了!

OK,现在我们有了可供使用的freeglut,继续。首先尝试重新建立GLTools库,来自SB5的独家Lib
  1. 从SuperBibe5官网下载下来的源代码压缩包中,应该包含4个文件夹:freeglut, linux, visualstudio 以及 src。进入src目录,复制
    GLTools文件夹到 C:/libs (之前建立的)目录中
  2. 在 libs/GLTools 目录中建立 lib 文件夹。此时应该有3个目录:/include. /src 以及 /lib
  3. 再次运行 MSYS (或者CMD),输入 "cd /c/libs/GLTools/src" 并回车
  4. 就像之前配置freeglut 的时候一样,我们要集合所有工具的代码,并将其链接到同一个库文件中。执行"g++ -c *.cpp -I../include
    ",然后执行 "ar rcs libGLTools.a *.o"。
  5. 将生成的 libGLTools.a 复制到 "c:/libs/GLTools/lib"
  6. 对 glew 做同样的事情,执行 "g++ -c glew.c -I../include" 然后 "ar rcs libglew.a glew.o"
  7. 在Code::Blocks中,打开 "Settings->Compiler and Debugger",选择 "Search Directory" 标签。在Compiler 中添加 "c:/libs/GL
    Tools/include。在Linker中添加"c:/libs/GLTools/lib/"
  8. 重新打开项目,在test.cpp前面添加 #include <GLTools.h> 然后尝试编译。这个时候出现一些这样的错误提示:
    "'GLAPI' does not name a type"。原因是,某些代码位置并没有定义 GLAPI,或者定义不正确

    这是值得探讨的,如果你从未这样探索库文件(我就没有,这是一次很好的实践)。打开 "freeglut-2.6.0/include/GL/glut.h",
    就会发现它只是简单的包含了freeglut_std.h,而 freeglut_std.h 里面有一堆预定义指令。

    在MinGW/include目录中搜索 包含字符 "GLAPI" 的文件(或者使用命令 grep "GLAPI" *.h),得出结果为:GL/gl.h, GL/glu.h,打开
    gl.h 并找出相关的段落。

    可以看到一段相关的代码:
    /* GLAPI, part 1 (use WINGDIAPI, if defined) */
    #if defined(__WIN32__) && defined(WINGDIAPI)
    # define GLAPI WINGDIAPI
    #endif

    /* GLAPI, part 2 */
    #if !defined(GLAPI)
    # if defined(_MSC_VER) /* Microsoft Visual C++ */
    # define GLAPI __declspec(dllimport)
    # elif defined(__LCC__) && defined(__WIN32__) /* LCC-Win32 */
    # define GLAPI __stdcall
    # else /* Others (e.g. MinGW, Cygwin, non-win32) */
    # define GLAPI extern
    # endif
    #endif
    现在要做的就是把其中最可能执行的部分提取出来,
    freeglut_std.h 并没有定义WINGDIAPI,所以跳过第一段代码,然后在第二段中寻找答案,#define GLAPI extern 就是我们要的东西。
    (因为注释写着 /* Others (e.g. MinGW, Cygwin ... )

    看起来似乎是这么回事:GLTools的一个头文件搞错了一些东西(对我们来说)

    现在理清顺序:
    GLTools.h没有用到GLAPI,但是包含了<windows.h>和<GL/glew.h> <GL/gl.h>,glew.h中有不少关于GLAPI的定义,这些定义告诉我们,GLAPI应该
    定义为extern,所以最直接的办法就是直接在test.cpp中加入#define GLAPI extern, 顺序为
    #include <GLTools.h>

    #define FREEGLUT_STATIC
    #define GLAPI extern
    #include <GL/glut.h>
    再一次编译,再一次失败,但这次得到了不一样的错误提示。所以我们得继续调试……

    额…… 这次编译没有任何问题。Just kidding( :oh_no )。别高兴,我们还没有正式引用GLTools中的任何函数,编译通过纯属正常。借着
    刚才的运气继续添加头文件 <GLShaderManager.h> ,然后编译,并且没有任何错误提示。
OK, 几乎快要成功了。现在完善test.cpp,在mian函数之前添加
GLBatch triangleBatch;
GLShaderManager shaderManager;
编译的时候出现一些"undefined references" (未定义)字样的错误提示,打开编译选项,把之前的几个还没加入的库链接进去(GLTools)
然后出现一小堆glew函数的"undefined references"提示

Wee! So exciting.(……)现在添加glew库到编译选项中,我们学到了新的东西:你必须记得链接那些和头文件对应的库文件。
这点对我们以后建立别的什么项目的时候很有帮助。

当我们需要用到freeglut,它依赖于winmm, gdi32 以及opengl32;
我们还需要用到GLTools,其依赖于glew库,而glew库又依赖于opengl32,链接他们的顺序应该为:
freeglut, GLTools, glew, winmm, gdi32 and opengl32. 让我们试试这样的顺序是否正确:
哈!没有任何错误提示。Damn I'm good (not really :( ). (这句照搬)
OK,现在我们设置好了环境,复制并编译Triangle.cpp文件,没有任何错误。

我在两台电脑上试过了这个方法并成功编译。相信以上步骤足以解决Code::Blocks+MinGW编译SB5示例代码过程所遇到的所有问题。
回复

在线用户

正浏览此版面之用户: 没有注册用户 和 0 访客