目录
1. 安装Visual Studio2019
直接官网安装community版,选择安装以下功能。
2. 前期准备
2.1 各种库的区别
- glut (OpenGL Utility Toolkit)
OpenGL工具库 OpenGL Utility Toolkit。OpenGL的基本库,但是很久不更新了,版本太老,不推荐使用。 - freeglut
freeglut完全兼容glut,是glut的代替品。bug比较多,稳定性不好,据说freeglut 3.0版本比其它版本稳定。 - glew (The OpenGL Extension Wrangler Library)
glew包含了OpenGL所需的核心。是对底层OpenGL接口的封装,可以让代码跨平台。 - glfw (Graphics Library Framework)
GLFW的开发目的是用于替代glut。它是一个轻量级的,开源的,跨平台的library。提供简单的API,用于创建窗口、上下文和表面,接收输入和事件。glfw也相当于一个额外的库,是freeglut和glut的替代。 - glad
glad是glew的升级版。用哪个都行,就是glew比较老,glad比较新。 - glm (OpenGL Mathematics)
基于GLSL的一个数学库。 - SDL
SDL是跨平台的多媒体库,旨在提供对音频,键盘,鼠标,操纵杆等的低级访问。是一款基于桌面操作系统、功能强大、调用方便的底层3D图形库。 SDL处理输入,窗口创建,图像加载以及OpenGL无法处理的其他一些功能。
一般来说,使用“glew+freeglut”,“glew+glfw”,“glad+glfw”。
本文选择最新的库,安装glad+glfw,同时安装glm和SDL。
2.2 安装cmake
为了防止后期出现乱七八糟的问题,还是下载源码编译后使用。
官网下载cmake。
运行cmake-gui.exe
3. OpenGL安装
3.1 配置glfw
-
官网下载源码
-
在解压后的glfw-3.3.3目录下创建一个文件夹build
-
打开cmake,选择源文件地址和build目标地址
-
点击configure,确定使用vs16 2019进行生成,然后点击finish。此处在32位下生成,也可选择64位,只需要保持前后一致即可。(不过建议使用32位)
-
configure完成后,点击generate
-
在build文件下找到GLFW.sln,双击使用vs2019打开。
-
生成解决方案
结果如下:
- 新建文件夹opengl(随便什么地方),在其中新建两个文件夹,一个用来放源文件(include),一个用来放链接库(lib)。
- 将\glfw-3.3.3\build\src\Debug中的glfw3.lib文件移动到\openg\lib目录下
- 将\glfw-3.3.3\include中的GLFW文件夹移动到\opengl\include目录下
3.2 配置glad
-
打开glad的网站,选择以下选项,然后点击generate来生成。
-
下载glad.zip
-
解压后,将include文件夹下的内容放到之前创建的\opengl\include目录下,将src文件夹下的文件放在\opengl\include目录下。
3.3 配置glm
-
进入官网,点击download进入github
-
下载最新版zip文件
-
将glm文件复制到/opengl/include文件夹下
3.4 配置SDL
- 官网下载
- 移动文件
- 将\SDL2-2.0.14\include文件夹移动到/opengl/include,并重命名为SDL
- 将\SDL2-2.0.14\lib\x86下的文件(除了dll文件)移动到/opengl/lib
- 将\SDL2-2.0.14\lib\x86\SDL2.dll文件复制到C:\Windows\SysWOW64目录下
3.5 配置VS
这种配置方法一劳永逸,每次创建新的项目不需要重新配置。
-
打开视图中的属性管理器
-
右击 Debug | win32,选择属性。(因为之前glfw是在win32环境下编译的)
- 选择VC++ 目录,添加包含目录/opengl/include和/opengl/include/SDL,添加库目录/opengl/lib。
-
选择链接器->输入,在附加依赖项中添加
opengl32.lib
glfw3.lib
SDL2.lib
SDL2main.lib -
将glad.c添加到项目中
4. 测试
4.1 测试glad和glfw
#include<glad/glad.h>
#include<GLFW/glfw3.h>
#include<iostream>
using namespace std;
const int WIN_WIDTH = 800, WIN_HEIGHT = 600;
void framebuffer_size_callback(GLFWwindow* window, int width, int height)
{
// 前两个参数控制窗口左下角的位置
glViewport(0, 0, WIN_WIDTH, WIN_HEIGHT);
}
void processInput(GLFWwindow* window)
{
if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS)
{
glfwSetWindowShouldClose(window, true);
}
}
int main()
{
glfwInit();
// 设置版本
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
// 使用核心模式(只使用OpenGL功能的一个子集)
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
GLFWwindow* window = glfwCreateWindow(WIN_WIDTH, WIN_HEIGHT, "LearnOpenGL", NULL, NULL);
if (window == NULL) {
cout << "Failed to create GLFW window" << endl;
glfwTerminate();
return -1;
}
glfwMakeContextCurrent(window);
// GLAD是用来管理OpenGL函数指针的,在调用任何OpenGL函数前需要初始化GLAD
if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress))
{
cout << "Fail to initialize GLAD" << endl;
return -1;
}
// 当调整窗口大小时,调用callback函数修改视口
glfwSetFramebufferSizeCallback(window, framebuffer_size_callback);
// 每次循环开始检查GLFW是否被要求退出
while (!glfwWindowShouldClose(window)) {
processInput(window);
// 状态设置,设置清空屏幕所用的颜色
glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
// 状态使用,使用特定颜色清空屏幕
glClear(GL_COLOR_BUFFER_BIT);
// 检查触发事件并调用对应的回调函数
glfwPollEvents();
// 交换颜色缓冲,被用来绘制并作为输出显示在屏幕上
glfwSwapBuffers(window);
}
// 释放之前分配的资源
glfwTerminate();
return 0;
}
得到一个蓝绿色的窗口。
4.2 测试SDL
// Example program:
// Using SDL2 to create an application window
#include "SDL.h"
#include <stdio.h>
int main(int argc, char* argv[]) {
SDL_Window *window; // Declare a pointer
// 07-14-2018: Modified by ZDH
// SDL_Init(SDL_INIT_VIDEO); // Initialize SDL2
SDL_Init(SDL_INIT_EVERYTHING); // Initialize SDL2
// Create an application window with the following settings:
window = SDL_CreateWindow(
"An SDL2 window", // window title
SDL_WINDOWPOS_UNDEFINED, // initial x position
SDL_WINDOWPOS_UNDEFINED, // initial y position
640, // width, in pixels
480, // height, in pixels
SDL_WINDOW_OPENGL // flags - see below
);
// Check that the window was successfully created
if (window == NULL) {
// In the case that the window could not be made...
printf("Could not create window: %s\n", SDL_GetError());
return 1;
}
// The window is open: could enter program loop here (see SDL_PollEvent())
SDL_Delay(3000); // Pause execution for 3000 milliseconds, for example
// Close and destroy the window
SDL_DestroyWindow(window);
// Clean up
SDL_Quit();
return 0;
}
得到一个空白的窗口。
注意使用SDL时,main函数的参数必须写出来,控制台工程创建的main函数 int main()与SDL库的main函数不一样。
int main(int argc, char* argv[])