OpenGL学习笔记1——搭建OpenGL的环境和创建第一个窗口

最近开始学习一些计算机图形学的知识,先是看了会慕课。然后就开始做第一个OpenGL的程序。一开始也没看太懂,后来去b站看了看傅老师(傅老师真是宝藏)的OpenGL的视频,又看了另一篇的博客。终于是把这个给弄出来了。
顺便也发现了一个学习OpenGL的网站,以及它的英文原网页

1 配置环境

1.1简单介绍

GLFW

GLFW是一个专门针对OpenGL的C语言库,它提供了一些渲染物体所需的最低限度的接口。它允许用户创建OpenGL上下文,定义窗口参数以及处理用户输入。

在GLFW中我们需要获得的就是glfw3.lib以及include中的一些头文件。

CMake

CMake是一个工程文件生成工具。用户可以使用预定义好的CMake脚本,根据自己的选择(像是Visual Studio, Code::Blocks, Eclipse)生成不同IDE的工程文件。

GLAD

GLAD是用来访问OpenGL规范接口的第三方库。

1.2 开始配置

我这里主要是按照LearnOpengGL里面的流程。

  1. 下载GLFW的源代码包
    这里选择选择下载Source package
    GWLF网页截图
    首先在网页上下载32位的GLFW(一定是32位,因为据说64位的就是用不了)。这里其实下载SourcePackage(源文件)或者binaries(编译好的二进制文件)都可以。傅老师的教程下载的就是二进制的文件,而LearnOpengGL里面是下载的源文件。如果是源文件的话就需要先编译一下来获得我们需要的 glfw3.lib。
    下载下来之后是一个压缩包,可以解压到一个自己喜欢的地方。里面的东西如下。
    在这里插入图片描述

  2. 下载CMake
    在这里下载32位的,也是一个压缩包,解压到喜欢的地方。

  3. 用CMake给GLFW创建一个vs2017的工程
    在Cmake的bin目录里面有个“cmake-gui.exe”,打开之后是
    CMAKE
    然后在“Where is the source code”中选择GLFW所在的目录文件夹,“Where to build the binaires”就是输出的路径,可以自己选一个地方,比如说可以在GLFW的目录里面新建一个“build”文件夹作为输出目录。
    然后点击左下角的 Configure 按钮会出现一个对话框,然后在“Specify the generator for this project”下拉菜单中选择对应的IDE,比如我用的是vs2017那就选择“Visual Studio 15 2017”,下面选项保持默认。
    cmake
    然后点击Finish按钮。
    cmake
    此时画面中间是红色的,再点一下Configure,然后再点一下Generate按钮生成。
    等待完成之后我们就可以在刚才设置的输出目录里面找到我们导出的项目了。如下:
    生成的项目

  4. 用vs2017编译出glfw32.lib
    用vs2017打开刚才生成的GLFW.sln,在这里点击生成解决方案。生成解决方案
    然后就可以看到在项目目录的src\Debug内看到生成的“glfw3.lib”文件了。

  5. 创建文件夹放置各种文件
    我们需要让IDE找到这些头文件和库文件,需要告诉IDE在哪里找。我们可以直接告诉IDE去刚才我们生成出文件的地方找,这没有问题。但是这样不方便我们的管理,而且会比较麻烦。所以我们可以创建一个文件夹,把我们用到的头文件库文件放在一起。这样就可以很方便的管理了。
    比如我在D盘中新建一个OpenGL文件夹,在这个文件夹中分别创建include和libs文件夹。把刚才生成的glfw3.lib放到libs文件夹中,然后同样的把glfw目录底下的include中的内容复制到我们创建的include文件夹中

  6. 使用GLAD
    下面这里直接复制LearnOpenGL上的话好了

因为OpenGL只是一个标准/规范,具体的实现是由驱动开发商针对特定显卡实现的。由于OpenGL驱动版本众多,它大多数函数的位置都无法在编译时确定下来,需要在运行时查询。所以任务就落在了开发者身上,开发者需要在运行时获取函数地址并将其保存在一个函数指针中供以后使用。取得地址的方法因平台而异,在Windows上会是类似这样:
// 定义函数原型
typedef void (GL_GENBUFFERS) (GLsizei, GLuint);
// 找到正确的函数并赋值给函数指针
GL_GENBUFFERS glGenBuffers = (GL_GENBUFFERS)wglGetProcAddress(“glGenBuffers”);
// 现在函数可以被正常调用了
GLuint buffer;
glGenBuffers(1, &buffer);
你可以看到代码非常复杂,而且很繁琐,我们需要对每个可能使用的函数都要重复这个过程。幸运的是,有些库能简化此过程,其中GLAD是目前最新,也是最流行的库。
配置GLAD
GLAD是一个开源的库,它能解决我们上面提到的那个繁琐的问题。GLAD的配置与大多数的开源库有些许的不同,GLAD使用了一个在线服务。在这里我们能够告诉GLAD需要定义的OpenGL版本,并且根据这个版本加载所有相关的OpenGL函数。
打开GLAD的在线服务,将语言(Language)设置为C/C++,在API选项中,选择3.3以上的OpenGL(gl)版本(我们的教程中将使用3.3版本,但更新的版本也能正常工作)。之后将模式(Profile)设置为Core,并且保证生成加载器(Generate a loader)的选项是选中的。现在可以先(暂时)忽略拓展(Extensions)中的内容。都选择完之后,点击生成(Generate)按钮来生成库文件。

在网页内选好选项之后点击Generate,
GLAD
然后会生成一个压缩包,点击一下就可以下载。
GLAD
下载下来之后里面有一个src和include文件夹。同样的把这个include文件夹里面的内容放到刚才我们自己创建的include文件夹里面。src中的glad.c待会要放到项目中。
此时的include文件夹是这样的:
文件内容
(一直找不到以这种结构查看文件的方法,只好导到Unity里面截图了。只是为了清楚的看到有什么文件)
GLFW文件夹是在GLFW的压缩包内的include中复制过来的,glad和KHR文件夹是在GLAD生成的压缩包中的include中复制过来的。

  1. 用vs2017创建一个空的cpp项目
  2. 引用头文件和库文件
    打开项目->属性。
    项目属性
    然后分别在“VC++目录”中的 “包含目录” 和 “库目录” 中添加include和libs的路径(就是前面所提到的自己创建的两个文件夹,我这里是放在D盘的OpenGL下的)。
    设置
    除了在“VC++目录”中设置,也可以分别到“C/C++目录”中的常规和“连接器”中的常规里面设置,他们之间的去边可以参看一下《包含目录、库目录、附加包含目录、附加库目录、附加依赖项之详解》。但是只需要在“VC++目录”中设置就够了,因为在这里是全局的。
    然后在“连接器->输入”里面添加glfw3.lib的名字。
    设置
    怎么添加上述内容就不多说了,懒得再截几张图。可以直接添加文字,也可以点击右边的小箭头在对话框里面添加。
    顺便说一下把最上面那一栏“配置”和“平台”都改成“所有配置”和“所有平台”,这样就对所有项目都生效了。(这个不太确定是不是)
    不要忘了把刚才GLAD生成的src里面的glad.c放进来源文件,不然运行就会报错。
    glad
  3. 检查
    创建一个main.cpp,复上以下代码运行看看成不成功。
#include <glad/glad.h>
#include <GLFW/glfw3.h>
const unsigned int SCR_WIDTH = 800;
const unsigned int SCR_HEIGHT = 600;
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(SCR_WIDTH, SCR_HEIGHT, "HelloWorld", NULL, NULL);
	//创建窗口 
	return 0;
}

2 第一个简单的窗口

#include <glad/glad.h>
#include <GLFW/glfw3.h>
#include <iostream>
using namespace std;

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

int main() {
	glfwInit();// 初始化GLFW
	/*glfwWindowHint用来配置GLFW,第一个参数是选项名,第二个参数是这个选项的值*/
	glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);// 将主版本号设为3(因为用的OpenGL版本是3.3)
	glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);// 将此版本号设为3
	glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);// 使用核心模式
	//glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);如果是MAC OS X系统需要加上这句

	/*创建窗口对象*/
	GLFWwindow* window = glfwCreateWindow(800, 600, "OpengGL_Testing", nullptr, nullptr);// 设置窗口大小、名字
	if (window == nullptr) {
		cout << "创建窗口失败" << endl;
		glfwTerminate();// 销毁所有剩余的窗口和游标
		return -1;
	}
	glfwMakeContextCurrent(window);// 设置当前的上下文(OpenGL是一个庞大的状态机,其状态被称为上下文)

	/*使用GLAD管理指针*/
	if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress)) {
		cout << "初始化GLAD失败" << endl;
		return -1;
	}

	/*设置视口,告诉OpenGL渲染窗口的尺寸大小*/
	glViewport(0, 0, 800, 600);// 前两个是窗口左下角的位置,后两个是宽和高

	/*告诉GLFW,每次窗口调用的时候使用framebuffer_size_callback函数*/
	glfwSetFramebufferSizeCallback(window, framebuffer_size_callback);

	/*渲染循环*/
	// glfwWindowShouldClose用来检查window是否被要求退出
	while (!glfwWindowShouldClose(window)) {
		glfwSwapBuffers(window); // 交换颜色缓冲
		glfwPollEvents(); // 检查有没有触发事件(比如键盘输入、鼠标移动等等),更新窗口状态,并调用对应的回调函数
	}

	/*释放资源*/
	glfwTerminate();

	return 0;
}

// 回调函数,窗口大小改变的时候也应该改变视口的大小
void framebuffer_size_callback(GLFWwindow* window, int width, int height) {
	// 不知道这个window有什么作用
	glViewport(0, 0, 800, 600);
}

如果没有什么问题的话,就会创建一个800*600的名字为OpenGL_Testing的黑色窗口。
窗口
再加上按键输入的检测和用颜色清空屏幕,最后的代码如下。

#include <glad/glad.h>
#include <GLFW/glfw3.h>
#include <iostream>
using namespace std;

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

int main() {
	glfwInit();// 初始化GLFW
	/*glfwWindowHint用来配置GLFW,第一个参数是选项名,第二个参数是这个选项的值*/
	glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);// 将主版本号设为3(因为用的OpenGL版本是3.3)
	glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);// 将此版本号设为3
	glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);// 使用核心模式
	//glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);如果是MAC OS X系统需要加上这句

	/*创建窗口对象*/
	GLFWwindow* window = glfwCreateWindow(800, 600, "OpengGL_Testing", nullptr, nullptr);// 设置窗口大小、名字
	if (window == nullptr) {
		cout << "创建窗口失败" << endl;
		glfwTerminate();// 销毁所有剩余的窗口和游标
		return -1;
	}
	glfwMakeContextCurrent(window);// 设置当前的上下文(OpenGL是一个庞大的状态机,其状态被称为上下文)

	/*使用GLAD管理指针*/
	if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress)) {
		cout << "初始化GLAD失败" << endl;
		return -1;
	}

	/*设置视口,告诉OpenGL渲染窗口的尺寸大小*/
	glViewport(0, 0, 800, 600);// 前两个是窗口左下角的位置,后两个是宽和高

	/*告诉GLFW,每次窗口调用的时候使用framebuffer_size_callback函数*/
	glfwSetFramebufferSizeCallback(window, framebuffer_size_callback);

	/*渲染循环*/
	// glfwWindowShouldClose用来检查window是否被要求退出
	while (!glfwWindowShouldClose(window)) {
		processInput(window); // 处理输入

		/*渲染操作*/
		glClearColor(0.2f, 0.3f, 0.3f, 1.0f);// 用颜色清空屏幕
		glClear(GL_COLOR_BUFFER_BIT);// 清空一个缓冲位的缓冲(还不太理解)

		glfwSwapBuffers(window); // 交换颜色缓冲
		glfwPollEvents(); // 检查有没有触发事件(比如键盘输入、鼠标移动等等),更新窗口状态,并调用对应的回调函数
	}

	/*释放资源*/
	glfwTerminate();

	return 0;
}

// 回调函数,窗口大小改变的时候也应该改变视口的大小
void framebuffer_size_callback(GLFWwindow* window, int width, int height) {
	// 不知道这个window有什么作用
	glViewport(0, 0, 800, 600);
}

// 处理输入
void processInput(GLFWwindow* window) {
	if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS)// 判断是否按下Esc
		glfwSetWindowShouldClose(window, true);// 将窗口设置为需要关闭
}

此时的运行效果是如图所示,并且按下键盘上的Esc也可以关闭窗口。
运行

3 遇到的问题

一开始运行的时候遇到这样的问题,其实是忘记把glad.c放入项目的问题。把它放进来就好了。
问题1
error LNK2001: 无法解析的外部符号 _glad_glViewport

还有遇到过window就创建失败的,后来发现是设置主次版本号的时候没有设置对。

  • 4
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,关于绘制多边形,我会为您提供一些OpenGL学习笔记。 首先,我们需要了解一下OpenGL绘制多边形的基本流程。OpenGL绘制多边形的过程包括三个基本步骤:指定顶点数据、指定绘制方式和执行绘制。 指定顶点数据:在OpenGL中,我们可以使用glVertex等函数来指定多边形的顶点。例如,如果我们要绘制一个三角形,我们可以使用以下代码: ``` glBegin(GL_TRIANGLES); glVertex3f(0.0f, 1.0f, 0.0f); glVertex3f(-1.0f, -1.0f, 0.0f); glVertex3f(1.0f, -1.0f, 0.0f); glEnd(); ``` 其中,glBegin和glEnd函数用来指定绘制的方式,GL_TRIANGLES表示绘制三角形。glVertex3f函数用来指定三角形的三个顶点,每个顶点由三个坐标值组成。 指定绘制方式:OpenGL支持多种绘制方式,例如GL_TRIANGLES、GL_TRIANGLE_STRIP、GL_TRIANGLE_FAN等。在上面的代码中,我们使用了GL_TRIANGLES来指定绘制三角形的方式。 执行绘制:最后,我们需要调用glDrawArrays函数来执行绘制。例如,如果我们要绘制一个三角形,我们可以使用以下代码: ``` glDrawArrays(GL_TRIANGLES, 0, 3); ``` 其中,GL_TRIANGLES表示绘制三角形的方式,0表示顶点数组的起始位置,3表示顶点的数量。 以上就是OpenGL绘制多边形的基本流程,下面我们来看一下如何绘制着色多边形。 绘制着色多边形的过程与绘制普通多边形的过程基本相同,只需要在绘制前调用glColor函数来指定颜色即可。例如,如果我们要绘制一个红色的三角形,我们可以使用以下代码: ``` glBegin(GL_TRIANGLES); glColor3f(1.0f, 0.0f, 0.0f); // 指定颜色为红色 glVertex3f(0.0f, 1.0f, 0.0f); glVertex3f(-1.0f, -1.0f, 0.0f); glVertex3f(1.0f, -1.0f, 0.0f); glEnd(); ``` 其中,glColor3f函数用来指定颜色,三个参数分别表示红、绿、蓝三个颜色通道的值,取值范围为0到1。 希望以上内容能够帮助到您。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值