5

LearnOpenGL环境搭建

 2 years ago
source link: https://www.kirito41dd.cn/learn-opengl-env/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

LearnOpenGL环境搭建

 2021-12-12  约 3671 字   预计阅读 8 分钟 

2020年2月春节期间我刷完过一遍LearnOpenGL,这是一个很好的入门openGL良心教程,一直没时间记录。最近打游戏荒废了好久,刚好换了电脑,重新装下环境顺便记录下LearnOpenGL的环境搭建。

教程中使用的环境是Visual Studios + CMake + MSVC,我没用过也没安装过Visual Studio。所以我选择的环境是vscode + CMake + MinGW-w64,在linux直接gcc就行了,mac用gcc、clang都可以。这样的好处是在win、linux、mac上都能搭建这套环境。

我的系统是win,因为要打游戏(

  • vscode 就不多说了,用其他编辑器/IDE也行

mingw-w64

编译器肯定是必须的,我没用过msvc,只用过gcc,mingw-w64就是win上的gcc。

  • 下载地址:https://www.mingw-w64.org/downloads/

  • 双击打开,选择native windows,x86_64,如果是32位系统则选i686。设置好安装目录 https://blog-1256556944.file.myqcloud.com/public/mingw-install.png

  • 直接点process安装 https://blog-1256556944.file.myqcloud.com/public/mingw-install2.png

  • 完成后,安装目录的bin文件夹里就有gcc了 https://blog-1256556944.file.myqcloud.com/public/mingw-install3.png

  • 最后吧bin目录添加到系统环境变量PATH里:此电脑-属性-高级系统设置-环境变量-PATH-添加D:\app\mingw-w64\bin

cmake

c++在编译的时候,需要引用各种头文件,链接这个那个的各种动态库、静态库。项目复杂的时候编译会很麻烦,cmake相当于一个构建系统,用不怎么简洁的语法,描述如何编译目标,帮我们生成makefile文件,自动编译项目。

  • 下载地址:https://cmake.org/download/,选择.msi安装
  • 一路点next,安装路径无所谓,记得加入PATH就行 https://blog-1256556944.file.myqcloud.com/public/cmake-install.png
  • 完事检查下安装成功
    https://blog-1256556944.file.myqcloud.com/public/cmake-install2.png

依赖库安装

需要用到以下库:

  • GLFW - 负责创建OpenGL上下文并显示窗口
  • GLAD - 查找openGL函数指针

在画出出色的效果之前,首先要做的就是创建一个OpenGL上下文(Context)和一个用于显示的窗口。然而,这些操作在每个系统上都是不一样的,OpenGL有目的地从这些操作抽象(Abstract)出去。这意味着我们不得不自己处理创建窗口,定义OpenGL上下文以及处理用户输入。

GLFW就是帮我们在不同平台做这个事情

  • 获取源代码:www.glfw.org/download.html,下载source package
  • 记得看看官方编译指南https://www.glfw.org/docs/latest/compile.html
  • 解压后进入目录 https://blog-1256556944.file.myqcloud.com/public/GLFW-install.png
  • 在此目录执行cmake -S . -B build -G "MinGW Makefiles" -DBUILD_SHARED_LIBS=ON,其中-S指定源码所在目录,-B指定构建/输出目录,-G指定我们是给MinGW生产makefile,最后一个参数是告诉CMake,我们要动态库 https://blog-1256556944.file.myqcloud.com/public/GLFW-install2.png
  • 最后,进入build/目录,执行mingw32-make.exe -j4-j4指定我们用4个cpu核心,注意由于我们装的mingw,所以make命令变成了mingw32-make.exe https://blog-1256556944.file.myqcloud.com/public/GLFW-install3.png
  • 完事后我们就得到了lib文件 https://blog-1256556944.file.myqcloud.com/public/GLFW-install4.png
  • GLFW就编译完了,关键目录只有两个
    • 头文件path\to\glfw-3.3.6\include
    • lib文件path\to\glfw-3.3.6\build\src
  • path\to\glfw-3.3.6\build目录执行mingw32-make.exe install(需要管理员权限),文件会被安装到C:/Program Files (x86)/GLFW/
  • 最后手动复制glfw3.dllC:\Windows\System32下,不然运行程序会报找不到dll,其他库类似

OpenGL只是一个标准/规范,具体的实现是由驱动开发商针对特定显卡实现的。由于OpenGL驱动版本众多,它大多数函数的位置都无法在编译时确定下来,需要在运行时查询。

GLAD会帮我们找到函数位置

  • 使用在线服务定制我们需要的源代码:https://glad.dav1d.de/ https://blog-1256556944.file.myqcloud.com/public/GLAD.png
  • 下载解压后,include目录里是俩头文件,src目录里面就一个glad.c
  • 这个glad.c后面会直接和程序一起参与编译

到这里就可以创建项目了

建立一个名为LearnOpenGL的文件夹作为项目根目录。整个项目结构是这样的:

  • root(LearnOpenGL)
    • CMakeLists.txt - cmake构建文件
    • cmake/modules/ - 存放cmake自动查找库的find文件
    • include/ - 存放头文件
    • src/ - 存放源代码

可以参考:https://github.com/kirito41dd/LearnOpenGL

先给出目录细节再详细说,所有参与文件如下:

  • CMakeLists.txt - cmake构建文件
  • cmake/modules/ - 存放cmake自动查找库的find文件
    • FindGLFW3.cmake - 负责自动查找glfw的头文件路径和lib路径
  • include/ - 存放头文件
    • glad.c - 把安装GLAD时的文件复制过来
    • glad/ - 安装GLAD时的头文件目录,复制过来
      • glad.h
    • KHR/ - 安装GLAD时的头文件目录,复制过来
      • khrplatform.h
  • src/ - 存放源代码
    • start/ - 存放LearnOpenGL教程第一部分源码
      • CMakeLists.txt - 子目录构建文件
      • HelloWindow.cpp - 创建窗口示例程序

1.主CMakeLists.txt

根目录下的CMakeLists.txt文件是引导cmake的入口,主要做一些项目设置,和头文件,lib等查找工作,详细如下:

cmake_minimum_required(VERSION 2.9) # 指定cmake最小版本

project(learnopengl) # 设置项目名

# 依赖环境
# ------------------------------------------------------------------------------
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake/modules/")
find_package(GLFW3 REQUIRED)
include_directories(${GLFW3_INCLUDE_DIR})
add_library(glad include/glad.c)
# ------------------------------------------------------------------------------

include_directories(./include) # 添加头文件搜索目录

# 子目录
add_subdirectory(src/start) # 子目录也会有CMakeLists.txt文件,环境是相通的

主要来看依赖环境部分:

set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake/modules/") 这句是往CMAKE_MODULE_PATH里追加一个目录, 这些目录里存放着各种find文件,命名为Find${LIB}.cmake

find_package(GLFW3 REQUIRED)表示调用FindGLFW3.cmake查找GLFW3的头文件和lib,而且是必须找到,否则构建终止。 如果找到了,会设置GLFW3_XXX等一系列变量

include_directories(${GLFW3_INCLUDE_DIR}),find执行成功才会执行这句,变量GLFW3_INCLUDE_DIR里存放着GLFW头文件的路径,然后添加头文件搜索目录

add_library(glad include/glad.c)声明一个名为glad的lib,后面可以指定链接它,glad.c就会参与编译

2.FindGLFW.cmake

看下项目里GLFW的搜索文件cmake/modules/FindGLFW3.cmake,这个文件可以在网上找到很多例子,cmake本身也会预装很多find文件。

set( _glfw3_HEADER_SEARCH_DIRS
"/usr/include"
"/usr/local/include"
"${CMAKE_SOURCE_DIR}/includes"
"C:/Program Files (x86)/glfw/include" 
"C:/Program Files (x86)/GLFW/include") # 注意这里,就是我们安装的目录
set( _glfw3_LIB_SEARCH_DIRS
"/usr/lib"
"/usr/local/lib"
"${CMAKE_SOURCE_DIR}/lib"
"C:/Program Files (x86)/glfw/lib-msvc110"
"C:/Program Files (x86)/GLFW/lib") # 注意这里

# Check environment for root search directory
set( _glfw3_ENV_ROOT $ENV{GLFW3_ROOT} )
if( NOT GLFW3_ROOT AND _glfw3_ENV_ROOT )
	set(GLFW3_ROOT ${_glfw3_ENV_ROOT} )
endif()

# Put user specified location at beginning of search
if( GLFW3_ROOT )
	list( INSERT _glfw3_HEADER_SEARCH_DIRS 0 "${GLFW3_ROOT}/include" )
	list( INSERT _glfw3_LIB_SEARCH_DIRS 0 "${GLFW3_ROOT}/lib" )
endif()

# Search for the header
FIND_PATH(GLFW3_INCLUDE_DIR "GLFW/glfw3.h" # 头文件目录的变量
PATHS ${_glfw3_HEADER_SEARCH_DIRS} )

# Search for the library
FIND_LIBRARY(GLFW3_LIBRARY NAMES glfw3 glfw glfw3dll
PATHS ${_glfw3_LIB_SEARCH_DIRS} )
INCLUDE(FindPackageHandleStandardArgs)
FIND_PACKAGE_HANDLE_STANDARD_ARGS(GLFW3 DEFAULT_MSG
GLFW3_LIBRARY GLFW3_INCLUDE_DIR) # 注意这里


IF(GLFW3_FOUND)
	IF(NOT GLFW3_FIND_QUIETLY)
	MESSAGE(STATUS "Found ASSIMP: ${GLFW3_LIBRARY}")
	ENDIF(NOT GLFW3_FIND_QUIETLY)
ELSE(GLFW3_FOUND)
	IF(GLFW3_FIND_REQUIRED)
	MESSAGE(FATAL_ERROR "Could not find GLFW3")
	ENDIF(GLFW3_FIND_REQUIRED)
ENDIF(GLFW3_FOUND)

3.创建窗口

这里和LearnOpenGL里教的一样了就,src/start/HelloWindow.cpp

// 你好,窗口
#include <iostream>
#include <glad/glad.h>
#include <GLFW/glfw3.h>
#include <stdlib.h>


using namespace std;

void framebuffer_size_callback(GLFWwindow* window, int width, int height);

void processInput(GLFWwindow *window);

int main()
{
    cout << "hellow" << endl;
    glfwInit(); // 初始化库
    glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); // 配置主版本号
    glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3); // 配置次版本号
    glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); // 使用核心模式
    //glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE); // Mac OS X 使用

    // 创建一个窗口
    GLFWwindow* window = glfwCreateWindow(800, 600, "LearnOpenGL", NULL, NULL);
    if (window == NULL)
    {
        std::cout << "Failed to create GLFW window" << std::endl;
        glfwTerminate();
        return -1;
    }
    glfwMakeContextCurrent(window); // 设置为当前上下文

    // glad
    // GLAD是用来管理OpenGL的函数指针的,所以在调用任何OpenGL的函数之前我们需要初始化GLAD。
    if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress))
    {
        std::cout << "Failed to initialize GLAD" << std::endl;
        return -1;
    }

    // 设置窗口的维度
    // glViewport函数前两个参数控制窗口左下角的位置。第三个和第四个参数控制渲染窗口的宽度和高度(像素)。
    glViewport(0, 0, 800, 600);

    // 设置一个回调,当用户改变窗口的大小的时候,视口也应该被调整。
    glfwSetFramebufferSizeCallback(window, framebuffer_size_callback);

    // 渲染循环 render loop
    while(!glfwWindowShouldClose(window))
    {
        processInput(window); // 处理输入

        glClearColor(0.2f, 0.3f, 0.3f, 1.0f); // 设置清空屏幕所用的颜色
        glClear(GL_COLOR_BUFFER_BIT); // 清除颜色缓冲之后,整个颜色缓冲都会被填充为glClearColor里所设置的颜色

        glfwSwapBuffers(window); // 交换颜色缓冲(它是一个储存着GLFW窗口每一个像素颜色值的大缓冲)
        glfwPollEvents(); // 函数检查有没有触发什么事件(比如键盘输入、鼠标移动等)、更新窗口状态,并调用对应的回调函数(可以通过回调方法手动设置)。
    }

    // 释放之前分配的资源
    glfwTerminate();
    return 0;
}

void framebuffer_size_callback(GLFWwindow* window, int width, int height)
{
    glViewport(0, 0, width, height);
}

void processInput(GLFWwindow *window)
{
    // 如果按下 esc , 窗口在下次循环将会退出
    if(glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS)
        glfwSetWindowShouldClose(window, true);
}

4.子CMakeLists.txt

最后来写下src/start目录里的CMakeLists.txt,来告诉cmake如何编译上面的cpp文件:

# 你好,窗口
add_executable(HelloWindow HelloWindow.cpp) # 添加可执行程序
target_link_libraries(HelloWindow ${GLFW3_LIBRARY} glad) # 链接lib glfw glad.c

回到项目根目录执行:cmake -S . -B build/ -G"MinGW Makefiles"

进入build目录执行:mingw32-make.exe

编译结束后,在build/src/start/目录里能看到名为HelloWindow.exe的可执行程序,恭喜

https://blog-1256556944.file.myqcloud.com/public/HelloWindow.png

三角形也可以画出来了,具体跟着教程走吧 https://blog-1256556944.file.myqcloud.com/public/HelloTrigger.png

希望你也能通关,终点等你。

(依赖库安装还没写完,待续。。。


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK