OpenGL学习笔记_简介_环境配置_创建一个窗口实例

3 篇文章 0 订阅

一. 基本概念

OpenGL

本身并不是一个API,它仅仅是一个由Khronos组织制定并维护的规范(Specification)OpenGL规范并没有规定实现的细节,具体的OpenGL库允许使用不同的实现,实际的OpenGL库的开发者通常是显卡的生产商。

图形渲染管线

OpenGL中的顶点、像素等数据需要通过不同阶段的处理,才能产生最后的可视图像,就像是工厂里的生产线,称为图形渲染管线。

状态机

OpenGL自身是一个巨大的状态机(State Machine):一系列的变量描述OpenGL此刻应当如何运行。OpenGL的状态通常被称为OpenGL上下文(Context)。我们通常使用如下途径去更改OpenGL状态:设置选项,操作缓冲。最后,我们使用当前OpenGL上下文来渲染。

假设当我们想告诉OpenGL去画线段而不是三角形的时候,我们通过改变一些上下文变量来改变OpenGL状态,从而告诉OpenGL如何去绘图。一旦我们改变了OpenGL的状态为绘制线段,下一个绘制命令就会画出线段而不是三角形。

当使用OpenGL的时候,我们会遇到一些状态设置函数(State-changing Function),这类函数将会改变上下文。以及状态使用函数(State-using Function),这类函数会根据当前OpenGL的状态执行一些操作。只要你记住OpenGL本质上是个大状态机,就能更容易理解它的大部分特性。

对象

OpenGL库是用C语言写的,同时也支持多种语言的派生,但其内核仍是一个C库。由于C的一些语言结构不易被翻译到其它的高级语言,因此OpenGL开发的时候引入了一些抽象层。对象(Object)”就是其中一个。

OpenGL中一个对象是指一些选项的集合,它代表OpenGL状态的一个子集。比如,我们可以用一个对象来代表绘图窗口的设置,之后我们就可以设置它的大小、支持的颜色位数等等。可以把对象看做一个C风格的结构体(Struct)

// OpenGL的状态
struct OpenGL_Context {
    ...
    object* object_Window_Target;
    ...    
};
// 创建对象
unsigned int objectId = 0;
glGenObject(1, &objectId);

// 绑定对象至上下文
glBindObject(GL_WINDOW_TARGET, objectId);

// 设置当前绑定到 GL_WINDOW_TARGET 的对象的一些选项
glSetObjectOption(GL_WINDOW_TARGET, GL_OPTION_WINDOW_WIDTH, 800);
glSetObjectOption(GL_WINDOW_TARGET, GL_OPTION_WINDOW_HEIGHT, 600);

// 将上下文对象设回默认
glBindObject(GL_WINDOW_TARGET, 0);

这一小段代码展现了你以后使用OpenGL时常见的工作流。我们首先创建一个对象,然后用一个id保存它的引用(实际数据被储存在后台)。然后我们将对象绑定至上下文的目标位置(例子中窗口对象目标的位置被定义成GL_WINDOW_TARGET)。接下来我们设置窗口的选项。最后我们将目标位置的对象id设回0解绑这个对象。设置的选项将被保存在objectId所引用的对象中,一旦我们重新绑定这个对象到GL_WINDOW_TARGET位置,这些选项就会重新生效。

使用对象的一个好处是在程序中,我们不止可以定义一个对象,并设置它们的选项,每个对象都可以是不同的设置。在我们执行一个使用OpenGL状态的操作的时候,只需要绑定含有需要的设置的对象即可。比如说我们有一些作为3D模型数据(一栋房子或一个人物)的容器对象,在我们想绘制其中任何一个模型的时候,只需绑定一个包含对应模型数据的对象就可以了(当然,我们需要先创建并设置对象的选项)。拥有数个这样的对象允许我们指定多个模型,在想画其中任何一个的时候,直接将对应的对象绑定上去,便不需要再重复设置选项了。

几个常用库

创建在OpenGL之上,提供了OpenGL本身没有的功能:

1)libGL*:原生库,随OpenGL一起发布

2)GLU*实用库,随OpenGL一起发布

3)GLUT:(OpenGL Utility Toolkit)实用工具库,老(OpenGL 1.0的基本函数功能标准,90年代),不建议使用,跨平台,提供基本的窗口功能(窗口操作函数,窗口初始化、窗口大小、窗口位置等函数;回调函数:响应刷新消息、键盘消息、鼠标消息、定时器函数等);创建复杂的三维物体;菜单函数;程序运行函数。gult对应的开源实现是freegult。

freeglut glut*:glut的开源实现,完全兼容glut,算glut的代替品,但是bug较多,所以下面的glfw应运而生

4)GLUI:C++界面库,它提供了buttons, checkboxes, radio buttons, 等常用控件,以及OPENGL支持。GLUI界面系统依赖于GLUT来处理窗口、和鼠标管理等,而绘制部分采用OPENGL绘制

5)GLFW:( 轻量级Light Weight、开源、跨平台的library,新技术)是一个专门针对OpenGL的C语言库,它提供了一些渲染物体所需的最低限度的接口。支持OpenGL及OpenGL ES;它允许用户创建OpenGL上下文,定义窗口参数以及处理用户输入等;除了跨平台必要做的事情都没有做;开发目的是用于替代glut

6)GL3W*:核心文件加载库,获取OpenGL核心配置文件规范所提供功能的最简方法

7)GLEE:(GL Easy Extension library),OpenGL的一个免费跨平台扩展加载库。它提供了对OpenGL功能的无缝支持,支持版本3.0和近400个扩展。

8)GLEW: (OpenGL Extension Wrangler Library)跨平台的C++扩展库,(OpenGL2.0之后的一个工具函数)它的出现是为了方便的管理平台与OpenGL版本不匹配,以及方便的解决不同显卡特有的硬件接口支持(glew跨平台)简化平台代码繁琐的调用;只要包含一个glew.h头文件,你就能使用gl,glu,glext,wgl,glx的全 部函数。(目前最通用的库,,github上面一直在维护更新)

9)GLAD:(目前最新的库)是glew的升级版。用哪个都行。就是glew比较老,glad比较新。基于官方规格的多语言GL、GLES、EGL、GLX、WGL装载机/生成器。一般结合GLFW使用(GLAD是用来管理OpenGL的函数指针的---gladLoadGLLoader((GLADloadproc)glfwGetProcAddress))。

 

OpenGL Performer

由SGI开发并可以在IRIX、Linux和Microsoft Windows的一些版本上使用,构建于OpenGL,可以创建实时可视化仿真程序。

当开发者需要使用最新的OpenGL扩展时,他们往往需要使用GLEW或者是GLEE库提供的功能,可以在程序的运行期判断当前硬件是否支持相关的扩展,防止程序崩溃甚至造成硬件损坏。

OpenGL ES (OpenGL for Embedded Systems)

是 OpenGL 三维图形 API 的子集,针对手机、PDA和游戏主机等嵌入式设备而设计。在OpenGL ES的世界里,没有四边形、多边形,无论多复杂的图形都是由点、线和三角形组成的,也去除了glBegin/glEnd等方法。

二. 创建一个实例窗口代码

配置环境

     VS配置OpenGL开发环境 GLFW库和GLAD库的配置:https://blog.csdn.net/qq_37338983/article/details/78997179

参考文档 

     https://learnopengl-cn.github.io/01%20Getting%20started/03%20Hello%20Window/

代码实例

#include <stdio.h>
#include <iostream>
#include <glad/glad.h> 
#include <GLFW\glfw3.h>

//定义一个回调函数(Callback Function),
void framebuffer_size_callback(GLFWwindow* window, int width, int height);

//处理所有的输入,查询GLFW是否按下或者释放了此帧的相关键,并做出相应的反应
void processInput(GLFWwindow *window);

int main(){

	//初始化、配置GLFW
	glfwInit();
	glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
	glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);

	//告诉GLFW我们使用的是核心模式(Core-profile)。
	//意味着我们只能使用OpenGL功能的一个子集(没有我们已不再需要的向后兼容特性)
	glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);

	//创建一个窗口对象,这个窗口对象存放了所有和窗口相关的数据,
	//而且会被GLFW的其他函数频繁地用到。
	GLFWwindow *window = glfwCreateWindow(800,600,"a GLFW window",NULL,NULL);
	if (window == NULL)
	{
		std::cout << "Failed to create GLFW window" << std::endl;
		glfwTerminate();
		return -1;
	}

	//通知GLFW将我们窗口的上下文设置为当前线程的主上下文
	glfwMakeContextCurrent(window);

	//给GLAD传入了用来加载系统相关的OpenGL函数指针地址的函数。
	//GLFW给我们的是glfwGetProcAddress,它根据我们编译的系统定义了正确的函数。
	if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress))
	{
		std::cout << "Failed to initialize GLAD" << std::endl;
		return -1;
	}
	
	//对窗口注册一个回调函数(Callback Function),
	//它会在每次窗口大小被调整的时候被调用。
	glfwSetFramebufferSizeCallback(window, framebuffer_size_callback);

	//渲染循环(Render Loop),它能在我们让GLFW退出前一直保持运行。
		//glfwWindowShouldClose函数,在我们每次循环的开始前,检查一次GLFW是否被要求退出,
		//如果是的话该函数返回true然后渲染循环便结束了,之后为我们就可以关闭应用程序了。
	while (!glfwWindowShouldClose(window))
	{
		//处理所有的输入
		processInput(window);

		// 渲染指令
		// TO-DO:...

		//一个状态设置函数,用来设置清空屏幕所用的颜色
		glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
		//一个状态使用的函数,它使用了当前的状态,清除成指定的颜色。
		glClear(GL_COLOR_BUFFER_BIT);

		//glfwSwapBuffers函数会交换颜色缓冲(它是一个储存着GLFW窗口每一个像素颜色值的大缓冲),
		//它在这一迭代中被用来绘制,并且将会作为输出,显示在屏幕上。
		glfwSwapBuffers(window);

		//glfwPollEvents函数,检查有没有触发什么事件(比如键盘输入、鼠标移动等)、更新窗口状态,
		//并调用对应的回调函数(可以通过回调方法手动设置)。
		glfwPollEvents();
	}

	std::cout<< "hello world"<<std::endl;	

	//释放/删除之前的分配的所有资源
	glfwTerminate();

	return 0;
}

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)
		glfwSetWindowShouldClose(window, true);
	//TO-DO:添加其他按键处理代码
}

效果

三. 参考

opengl主要功能介绍 - 全文:http://www.elecfans.com/emb/603138_a.html

LearnOpenGL CN:https://learnopengl-cn.github.io/01%20Getting%20started/01%20OpenGL/

OpenGL,glut,glew,glfw,mesa等:https://blog.csdn.net/taozhi20084525/article/details/42804879

OpenGL 关于旧版glut和新版本glfw和glad的环境配置https://blog.csdn.net/weixin_42513339/article/details/82860004

VS配置OpenGL开发环境:GLFW库和GLAD库的配置:https://blog.csdn.net/qq_37338983/article/details/78997179

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

惊鸿一博

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值