OpenGL中最简单的窗体创建和渲染(初始化GLFW、GLAD、定义视口大小和resize回调、双层缓冲、输入事件处理)

窗口的创建

初始化GLFW并进行配置

GLFW的配置说明

#include <glad/glad.h>
#include <glfw3.h>

//must include GLAD before GLFW. The include file for GLAD includes the required OpenGL headers(GL/gl.h ... )

int main() {
	glfwInit(); //initialize GLFW
	//configure the options prefixed with GLFW_
	glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
	glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
	glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
	return 0;
}

步骤:

  1. 初始化glfw
  2. 声明我们使用的OpenGL的最大和最小版本都为3
  3. 指明使用core-profile(只使用OpenGL特性的子集,没有向后兼容的功能)

要保证OpenGL是3.3版本以上的,查看OpenGL版本的软件

创建窗口对象

创建的窗口对象容纳了所有的窗口数据(初始化之后的代码段)。

	GLFWwindow* window = glfwCreateWindow(800, 600, "LearnOpenGL_0_Start", NULL, NULL);//window witdth,height,name
	if (window == NULL) {
		cout << "create window failed" << endl;
		glfwTerminate();
		return -1;
	}
	//tell GLFW to make the context of our window the main context on the current threaed
	glfwMakeContextCurrent(window);

最后一行代码的目的是让我们窗口的context成为当前线程的主context。

载入GLAD

glfwGetProcAddress根据操作系统提供函数。

	//load the address of the OpenGL pointers
	//glfwGetProcAddress defines the correct function based on which OS we're compiling for
	if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress)) {
		cout << "GLAD initializaion failed!" << endl;
	}

定义视口大小

	//define the size of the rendering window
	glViewport(0, 0, 800, 600);//position, size(in pixels)

定义并注册resize事件

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

准备engines

为了不让应用程序画一帧就关掉窗口,使用while定义render loop。

	while (!glfwWindowShouldClose(window)) {
		glfwSwapBuffers(window);
		glfwPollEvents();
	}
  1. glfwWindowShouldClose检验窗体是否被关闭
  2. glfwSwapBuffers交换颜色缓存(是一个巨大的包含GLFW窗口的每个像素颜色值的Buffer)
  3. glfwPollEvents检查是否有事件被触发(键盘、鼠标事件)

此时启动程序可以看到一个黑色的窗口持续显示。

双层缓冲(Double Buffer)

单层缓冲(single buffer)可能导致闪烁(flickering)现象。

Flickering产生的原因

输出结果图并不是即时绘制的,而是从左到右,从上到下逐像素绘制的。这就导致图还没画完就被展示给了用户,导致了artifacts。

Double Buffer 工作原理

分为前(front)缓冲和后(back)缓冲。

  1. front buffer负责给用户展示绘制的结果。
  2. 所有命令都在back buffer上执行,以进行下一帧的绘制。
  3. back buffer的命令执行完毕后,swap前后缓冲,这样就没有Flickering问题了。

关闭窗口并回收分配的资源

在main函数结束前调用glfwTerminate函数,这个函数清除了所有资源并退出应用程序。

glfwTerminate();

处理输入

在GLFW中进行输入控制,只需要使用几个GLFW的输入函数。

glfwGetKey函数返回某个按键当前是否被按压。

void processInput(GLFWwindow *window) {
	if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS) //if the button not be pressed,the function return GLFW_RELEASE.
		glfwSetWindowShouldClose(window,true);
}

上面的函数表示当按住Escape时,设置GLFW窗口关闭标志。

在准备engines的循环中,swap缓存之前,先调用一下这个函数接收输入事件。

渲染 Rendering

写渲染代码时,在render loop中放置所有的渲染命令,以在每一次帧循环时执行所有渲染命令。

		glClearColor(0.3, .6, .5, 1.0);
		glClear(GL_COLOR_BUFFER_BIT);
  1. 使用特定的颜色清空屏幕glClearColor(r,g,b,a)
  2. 指定想要清除哪种bufferglClear(GL_COLOR_BUFFER_BIT),参数枚举包括GL_COLOR_BUFFER_BIT、GL_DEPTH_BUFFER_BIT、GL_STENCTIL_BUFFER_BIT

在这里插入图片描述

glClearColor函数是一个状态设置函数,而glClear函数则是一个状态使用的函数。

完整代码

#include <glad/glad.h>
#include <glfw3.h>
#include<iostream>
//must include GLAD before GLFW. The include file for GLAD includes the required OpenGL headers(GL/gl.h ... )
using namespace std;

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

void processInput(GLFWwindow *window) {
	if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS) //if the button not be pressed,the function return GLFW_RELEASE.
		glfwSetWindowShouldClose(window,true);
}

int main() {
	glfwInit(); //initialize GLFW
	//configure the options prefixed with GLFW_
	glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
	glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
	glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
	//create the window
	GLFWwindow* window = glfwCreateWindow(800, 600, "LearnOpenGL_0_Start", NULL, NULL);//window witdth,height,name
	if (window == NULL) {
		cout << "create window failed" << endl;
		glfwTerminate();
		return -1;
	}
	//tell GLFW to make the context of our window the main context on the current threaed
	glfwMakeContextCurrent(window);

	//load the address of the OpenGL pointers
	//glfwGetProcAddress defines the correct function based on which OS we're compiling for
	if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress)) {
		cout << "GLAD initializaion failed!" << endl;
	}


	//define the size of the rendering window
	glViewport(0, 0, 800, 600);//position, size(in pixels)
	glfwSetFramebufferSizeCallback(window, framebuffer_size_callback);

	while (!glfwWindowShouldClose(window)) {		
		processInput(window);
		glClearColor(0.3, .6, .5, 1.0);
		glClear(GL_COLOR_BUFFER_BIT);
		glfwSwapBuffers(window);
		glfwPollEvents();
	}

	glfwTerminate();
	return 0;
}
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值