OpenGL简介
首先需要明确的是,OpenGL不是什么物理引擎,也不是什么语言,而是一种规范,可以类比成是一个API,而具体的实现需要由开发者自行实现。而这一般也是由显卡的生产商实现的,所以不同平台的OpengL也有所不同。
OpenGL本身可以看成是一个巨大的状态机,可以通过状态设置函数 来改变上下文,和通过状态使用函数 来根据当前OpenGL的状态来执行一些操作。
1 2 3 4 5 6 7 8 9 10 unsigned int objectId = 0 ;glGenObject (1 , &objectId);glBindObject (GL_WINDOW_TARGET, objectId);glSetObjectOption (GL_WINDOW_TARGET, GL_OPTION_WINDOW_WIDTH, 800 );glSetObjectOption (GL_WINDOW_TARGET, GL_OPTION_WINDOW_HEIGHT, 600 );glBindObject (GL_WINDOW_TARGET, 0 );
这段代码便展示了如何创建一个对象,并将对象绑定至上下文然后进行操作的过程。
窗口创建
由于OpenGL只是一些规范,所以使用OpenGL的上下文以及用于显示渲染结果的窗口都需要我们自行去实现。这里可以使用GLFW库来进行操作。
可以从官网下载 最新的GLFW库,由于完整性所以我们选择下载源码并在本地进行编译。
这里选择用CMake进行编译,这里也可以从官网下载 最新的版本。
下载完成后可以使用CMake的GUI界面进行编译,选择好Source Code和将要存储编译好的目录后,便可以点击Configure进行编译,Generator最好使用VS的编译器,如果使用GCC或者G++可能会出现一些意想不到的错误。
编译完成后可以用VS将Sln文件打开,然后点击Build Solution,这样便可以在build/src/Debug文件夹中看到编译好的glfw3.lib了。
此时我们要做的便是将编译好的glfw3.lib链接到IDE中,这里由于我们选择的IDE是VSCode,所以和LearnOpenGL上的教程略有不同。首先要确保VScode安装了Cmake Tools插件,这可以让你快速创建一个Cmake的C++工程,之后打开CMakeLists.txt,会看到是这样的:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 cmake_minimum_required (VERSION 3.0 .0 )project (Lesson_0 VERSION 0.1 .0 LANGUAGES C CXX)include (CTest)enable_testing ()add_executable (Lesson_0 main.cpp)link_directories (D:/opengl/Libs)target_link_libraries (Lesson_0 PRIVATE D:/opengl/Libs/glfw3.l ib)include_directories ( D:/opengl/Include ) set (CPACK_PROJECT_NAME ${PROJECT_NAME})set (CPACK_PROJECT_VERSION ${PROJECT_VERSION})include (CPack)
首先通过link_directories()
命令来指导cmake找到Lib所在的位置,然后通过target_link_libraries()
来将需要倒入的静态库导入。最后还需要将头文件也导入,导入.lib只是相当于导入了.cpp文件,但是还需要.hpp头文件来让C++找到源文件,这里使用的是include_directories()
来导入。
这里推荐将LIB文件和Include文件分开存放,这样之后需要导入新的库只要分别将对应的文件放入即可,不需要再进行单独的添加。至此,GLFW的配置便结束了。
GLFW只是确立了OpenGL上下文以及窗口,但是由于OpenGL只是一个规范,所以具体的实现是显卡厂家自行实现的,所以这就导致函数的位置无法在编译时确定,所以就需要开发者在运行的时候动态搜索函数,并将其保存在一个函数指针里面。
1 2 3 4 5 6 7 typedef void (*GL_GENBUFFERS) (GLsizei, GLuint*) ;GL_GENBUFFERS glGenBuffers = (GL_GENBUFFERS)wglGetProcAddress ("glGenBuffers" ); GLuint buffer; glGenBuffers (1 , &buffer);
这个过程是很繁琐的,但是又有库可以代替我们完成这个工作,其中一个便是GLAD。
有了配置GLFW的经验,配置GLAD就很简单了,先通过GLAD的在线服务 ,这很像下载Pytorch一样,将语言设置为C/C++,API选择3.3或以上,这里选择了3.3,然后将Profile选择为Core,并确保勾上了Generate a Loader,然后便可以点击Generate来生成库文件。将生成的glad.zip下载解压后发现里面有一个glad.c文件和include文件,将include文件放入之前的Include里面,然后再将glad.c放入工程,最后别忘了用将glad.c放入add_executable()
里面,这样Glad也就配置好了。
编写代码
首先需要导入这两个头文件
1 2 #include <glad/glad.h> #include <GLFW/glfw3.h>
注意这里glad/glad.h
必须要在GLFW/glfw3.h
前面,否则会报错
这是创建窗口的完整代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 #include <iostream> #include <glad/glad.h> #include <GLFW/glfw3.h> using namespace std;void framebuffer_size_callback (GLFWwindow* window,int width,int height) ;void proccessInput (GLFWwindow*window) ;int main () { glfwInit (); glfwWindowHint (GLFW_CONTEXT_VERSION_MAJOR,3 ); glfwWindowHint (GLFW_CONTEXT_VERSION_MINOR,3 ); glfwWindowHint (GLFW_OPENGL_PROFILE,GLFW_OPENGL_CORE_PROFILE); GLFWwindow* window=glfwCreateWindow (800 ,600 ,"LearnOpenGL" ,NULL ,NULL ); if (window==NULL ){ cout<<"Failed to Create GLFW Window" <<endl; glfwTerminate (); return -1 ; } glfwMakeContextCurrent (window); if (!gladLoadGLLoader ((GLADloadproc)glfwGetProcAddress)){ cout<<"Failed to initialize GLAD" <<endl; return -1 ; } glfwSetFramebufferSizeCallback (window,framebuffer_size_callback); while (!glfwWindowShouldClose (window)){ glfwSwapBuffers (window); proccessInput (window); glClearColor (1.f ,0.f ,0.f ,1.f ); glClear (GL_COLOR_BUFFER_BIT); glfwPollEvents (); } glfwTerminate (); return 0 ; } void framebuffer_size_callback (GLFWwindow* window,int width,int height) { glViewport (0 ,0 ,width,height); } void proccessInput (GLFWwindow*window) { if (glfwGetKey (window,GLFW_KEY_ESCAPE)==GLFW_PRESS){ glfwSetWindowShouldClose (window,true ); } }