Learn OpenGL 01
OpenGL的定义
一般它被认为是一个API(Application Programming Interface, 应用程序编程接口),包含了一系列可以操作图形、图像的函数。然而,OpenGL本身并不是一个API,它仅仅是一个由Khronos组织制定并维护的规范(Specification)。
OpenGL规范严格规定了每个函数该如何执行,以及它们的输出值。至于内部具体每个函数是如何实现(Implement)的,将由OpenGL库的开发者自行决定(译注:这里开发者是指编写OpenGL库的人)。因为OpenGL规范并没有规定实现的细节,具体的OpenGL库允许使用不同的实现,只要其功能和结果与规范相匹配(亦即,作为用户不会感受到功能上的差异)。
实际的OpenGL库的开发者通常是显卡的生产商。你购买的显卡所支持的OpenGL版本都为这个系列的显卡专门开发的。
核心模式与立即渲染模式
早期的OpenGL使用立即渲染模式(Immediate mode,也就是固定渲染管线),这个模式下绘制图形很方便。OpenGL的大多数功能都被库隐藏起来,开发者很少有控制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本质上是个大状态机,就能更容易理解它的大部分特性。
环境准备
GLFW是一个专门针对OpenGL的C语言库,它提供了一些渲染物体所需的最低限度的接口。它允许用户创建OpenGL上下文、定义窗口参数以及处理用户输入
GLAD库是一个用于OpenGL加载和管理的工具库,它简化了在运行时获取OpenGL函数地址的过程。通过GLAD,开发者可以轻松地管理OpenGL函数,并且无需手动编写复杂的函数地址获取代码。
创建窗口
对重要的函数都进行了注释
#include <glad/glad.h>
#include <GLFW/glfw3.h>
#include <iostream>void framebuffer_size_callback(GLFWwindow* window, int width, int height);
void processInput(GLFWwindow* window);// settings
const unsigned int SCR_WIDTH = 800;
const unsigned int SCR_HEIGHT = 600;int main()
{// glfw: initialize and configure// ------------------------------glfwInit();//初始化GLFWglfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);//设置主版本号为3glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);//设置次版本号为3glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);//使用OPENGL的核心模式// glfw window creation// --------------------//前两个参数是宽度和高度,第三个参数是名称,第四个参数指定窗口所在的监视器(显示器),如果为 NULL,则窗口会被创建在默认的主监视器上。第五个参数指定与新创建的上下文共享资源的窗口,如果为 NULL,则表示不与其他窗口共享。GLFWwindow* window = glfwCreateWindow(SCR_WIDTH, SCR_HEIGHT, "LearnOpenGL", NULL, NULL);if (window == NULL){std::cout << "Failed to create GLFW window" << std::endl;glfwTerminate();return -1;}glfwMakeContextCurrent(window);//将渲染上下文(OpenGL context)与窗口相关联glfwSetFramebufferSizeCallback(window, framebuffer_size_callback);//窗口大小被调整的时候回调framebuffer_size_callback// glad: load all OpenGL function pointers// ---------------------------------------if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress))//通过 GLAD 加载和初始化 OpenGL 函数指针{std::cout << "Failed to initialize GLAD" << std::endl;return -1;}// render loop// -----------while (!glfwWindowShouldClose(window))//每次循环的开始前检查一次GLFW是否被要求退出{// input// -----processInput(window);glClearColor(0.2f, 0.3f, 0.3f, 1.0f);//置清空屏幕所用的颜色glClear(GL_COLOR_BUFFER_BIT); //清空屏幕的颜色缓冲// glfw: swap buffers and poll IO events (keys pressed/released, mouse moved etc.)// -------------------------------------------------------------------------------glfwSwapBuffers(window);//交换颜色缓冲glfwPollEvents();//函数检查有没有触发什么事件(比如键盘输入、鼠标移动等)、更新窗口状态,并调用对应的回调函数(可以通过回调方法手动设置)。}// glfw: terminate, clearing all previously allocated GLFW resources.// ------------------------------------------------------------------glfwTerminate();//释放 GLFW 库所占用的资源return 0;
}// process all input: query GLFW whether relevant keys are pressed/released this frame and react accordingly
// ---------------------------------------------------------------------------------------------------------
void processInput(GLFWwindow* window)
{if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS)//检测是否按下返回键glfwSetWindowShouldClose(window, true);
}// glfw: whenever the window size changed (by OS or user resize) this callback function executes
// ---------------------------------------------------------------------------------------------
void framebuffer_size_callback(GLFWwindow* window, int width, int height)
{// make sure the viewport matches the new window dimensions; note that width and // height will be significantly larger than specified on retina displays.glViewport(0, 0, width, height);//前两个参数控制窗口左下角的位置。第三个和第四个参数控制渲染窗口的宽度和高度(像素)
}
相关文章:
Learn OpenGL 01
OpenGL的定义 一般它被认为是一个API(Application Programming Interface, 应用程序编程接口),包含了一系列可以操作图形、图像的函数。然而,OpenGL本身并不是一个API,它仅仅是一个由Khronos组织制定并维护的规范(Specification)。 OpenGL规…...

Java开发从入门到精通(一):Java的基础语法进阶
Java大数据开发和安全开发 (一)Java注释符1.1 单行注释 //1.2 多行注释 /* */1.3 文档注释 /** */1.4 各种注释区别1.5 注释的特点1.5 注释的快捷键 (二)Java的字面量(三)Java的变量3.1 认识变量3.2 为什么…...

【C++从0到王者】第五十一站:B+树
文章目录 一、B树1.B树的概念2.B树的特性3.B树的插入的过程4.总结 二、B*树1. B*树的概念2.B*树的分裂 三、总结四、B树系列和哈希和平衡搜索树作对比五、B树的一些应用1.索引2.MySQL索引3.MyISAM2.InnoDB 一、B树 1.B树的概念 B树是B树的变形,是在B树基础上优化的…...

Spring Cloud 面试题及答案整理,最新面试题
Spring Cloud中断路器的原理及其作用是什么? Spring Cloud断路器的原理和作用基于以下几个关键点: 1、故障隔离机制: 在微服务架构中,断路器作为一种故障隔离机制,当某个服务实例出现问题时,断路器会“断…...

使用Kali搭建钓鱼网站教程
一、前言 使用kali工具一分钟制作出和目标网站一模一样的钓鱼网站。目标用户使用钓鱼网站登录自己的账号,账号密码将被自动劫持。 二、钓鱼网站的制作过程 1.在虚拟机VMvare中登录kali linux 2.准备一个目标网址 3.在kail中搜索使用工具 4.在弹出的选项中选择第一…...

《TCP/IP详解 卷一》第15章 TCP数据流与窗口管理
目录 15.1 引言 15.2 交互式通信 15.3 延时确认 15.4 Nagle 算法 15.4.1 延时ACK与Nagle算法结合 15.4.2 禁用Nagle算法 15.5 流量控制与窗口管理 15.5.1 滑动窗口 15.5.2 零窗口与TCP持续计时器 15.5.3 糊涂窗口综合征 15.5.4 大容量缓存与自动调优 15.6 紧急机制…...
ContentType类型总结
ContentType类型总结 Content-Type是一个HTTP头部字段,用于指示资源的媒体类型(MIME类型),以及可选的字符集和编码方式。它告诉浏览器或其他客户端如何解释接收到的数据。以下是一些常见的Content-Type类型及其用途: t…...

基于脚手架创建vue工程
环境要求: node.js:前端项目的运行环境 npm:javascript的包管理器 vue cli:项目脚手架 忘了自己有没有安装可以通过在黑窗口输入命令看一下 node -v npm -v 这里出现版本号就说明已经安装了 安装脚手架的命令:npm i vue/cli -g 创建vue基础工程 1.在一个没…...
【Http】OSI 和 TCP/IP,OSI,TCP/IP为什么网络要分层?
目录 OSI 和 TCP/IP OSI TCP/IP 为什么网络要分层? OSI 和 TCP/IP OSI 
STM32(5) GPIO(2)输出
1.点亮LED 1.1 推挽接法和开漏接法 要想点亮LED,有两种接法 推挽接法: 向寄存器写1,引脚输出高电平,LED点亮;向寄存器写0,引脚输出低电平,LED熄灭。 开漏接法: 向寄存器写0&…...

shell脚本一键部署docker
Docker介绍 Docker 是一个开源的平台,用于开发、交付和运行应用程序。它利用容器化技术,可以帮助开发人员更轻松地打包应用程序及其依赖项,并将其部署到任何环境中,无论是开发工作站、数据中心还是云中。以下是 Docker 的一些关键…...
vue2实现拖拽排序效果
1、首先下载 vuedraggable 插件 npm i -S vuedraggable2、使用方法 <template><div><div style"display: flex; justify-content: center; align-items: center"><div style"width: 120px; height: 60px; line-height: 60px; text-align…...
数据结构实验:二叉排序树
题目描述 对应给定的一个序列可以唯一确定一棵二叉排序树。然而,一棵给定的二叉排序树却可以由多种不同的序列得到。例如分别按照序列{3,1,4}和{3,4,1}插入初始为空的二叉排序树,都得到一样的结果。你的任务书对于输入的各种序列,判断它们是否…...
Java类加载流程?
Java类加载过程是指将.class文件中的字节码数据加载到内存中,并生成对应的Class对象的过程。Java类加载器(ClassLoader)负责执行这个任务。Java类加载过程主要包括以下几个步骤: 加载(Loading):…...
Docker从0到1的开始【入门篇】
Docker是一种流行的容器化平台,它允许开发人员将应用程序及其所有依赖项打包到一个标准化的单元中,从而实现快速部署和可移植性。在本文中,我们将列出一些常用的Docker命令,以帮助您更好地了解和使用Docker。 1. 安装Docker 要安…...

@ResponseStatus
目录 概述: 用途: 参数: 注意事项: 自定义异常类: 底层原理: 概述: 在 Spring MVC 中,我们有很多方法来设置 HTTP 响应的状态码其中最直接的方法:使用 ResponseSt…...

高效加载大文件(pandas+dask)
一、仅用pd加载大文件(iterator、chunksize) 要使用Pandas进行高效加载超大文件,我们通常会利用其内置的分块(chunk)处理功能。不过,请注意,Pandas本身并不支持多线程读取文件;它更倾向于单线程中进行块处理…...

游戏引擎分层简介
游戏引擎分层架构(自上而下) 工具层(Tool Layer) 在一个现代游戏引擎中,我们最先看到的可能不是复杂的代码,而是各种各样的编辑器,利用这些编辑器,我们可以制作设计关卡、角色、动画…...
向爬虫而生---Redis 探究篇6<Redis的Bigkey问题介绍>
前言: 随着数据规模的增长,Redis的BigKey问题也开始显现。 BigKey问题主要指的是存储了大量数据的key,这可能给Redis的性能和可用性带来负面影响。当一个key的数据量过大时,会占用宝贵的内存资源,拖慢Redis的响应速度。此外,存储和恢复这些BigKey也会变得困难和耗时,增…...

【开源物联网平台】FastBee认证方式和MQTT主题设计
🌈 个人主页:帐篷Li 🔥 系列专栏:FastBee物联网开源项目 💪🏻 专注于简单,易用,可拓展,低成本商业化的AIOT物联网解决方案 目录 一、接入步骤 1.1 设备认证 1.2 设备交…...
脑机新手指南(八):OpenBCI_GUI:从环境搭建到数据可视化(下)
一、数据处理与分析实战 (一)实时滤波与参数调整 基础滤波操作 60Hz 工频滤波:勾选界面右侧 “60Hz” 复选框,可有效抑制电网干扰(适用于北美地区,欧洲用户可调整为 50Hz)。 平滑处理&…...

JavaScript 中的 ES|QL:利用 Apache Arrow 工具
作者:来自 Elastic Jeffrey Rengifo 学习如何将 ES|QL 与 JavaScript 的 Apache Arrow 客户端工具一起使用。 想获得 Elastic 认证吗?了解下一期 Elasticsearch Engineer 培训的时间吧! Elasticsearch 拥有众多新功能,助你为自己…...

【JVM】- 内存结构
引言 JVM:Java Virtual Machine 定义:Java虚拟机,Java二进制字节码的运行环境好处: 一次编写,到处运行自动内存管理,垃圾回收的功能数组下标越界检查(会抛异常,不会覆盖到其他代码…...

Spring数据访问模块设计
前面我们已经完成了IoC和web模块的设计,聪明的码友立马就知道了,该到数据访问模块了,要不就这俩玩个6啊,查库势在必行,至此,它来了。 一、核心设计理念 1、痛点在哪 应用离不开数据(数据库、No…...

Selenium常用函数介绍
目录 一,元素定位 1.1 cssSeector 1.2 xpath 二,操作测试对象 三,窗口 3.1 案例 3.2 窗口切换 3.3 窗口大小 3.4 屏幕截图 3.5 关闭窗口 四,弹窗 五,等待 六,导航 七,文件上传 …...
CSS | transition 和 transform的用处和区别
省流总结: transform用于变换/变形,transition是动画控制器 transform 用来对元素进行变形,常见的操作如下,它是立即生效的样式变形属性。 旋转 rotate(角度deg)、平移 translateX(像素px)、缩放 scale(倍数)、倾斜 skewX(角度…...

wpf在image控件上快速显示内存图像
wpf在image控件上快速显示内存图像https://www.cnblogs.com/haodafeng/p/10431387.html 如果你在寻找能够快速在image控件刷新大图像(比如分辨率3000*3000的图像)的办法,尤其是想把内存中的裸数据(只有图像的数据,不包…...

在 Spring Boot 中使用 JSP
jsp? 好多年没用了。重新整一下 还费了点时间,记录一下。 项目结构: pom: <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org/POM/4.0.0" xmlns:xsi"http://ww…...
uniapp 实现腾讯云IM群文件上传下载功能
UniApp 集成腾讯云IM实现群文件上传下载功能全攻略 一、功能背景与技术选型 在团队协作场景中,群文件共享是核心需求之一。本文将介绍如何基于腾讯云IMCOS,在uniapp中实现: 群内文件上传/下载文件元数据管理下载进度追踪跨平台文件预览 二…...
SQL Server 触发器调用存储过程实现发送 HTTP 请求
文章目录 需求分析解决第 1 步:前置条件,启用 OLE 自动化方式 1:使用 SQL 实现启用 OLE 自动化方式 2:Sql Server 2005启动OLE自动化方式 3:Sql Server 2008启动OLE自动化第 2 步:创建存储过程第 3 步:创建触发器扩展 - 如何调试?第 1 步:登录 SQL Server 2008第 2 步…...