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);//前两个参数控制窗口左下角的位置。第三个和第四个参数控制渲染窗口的宽度和高度(像素)
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/727500.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

服务器严重不够啊

必需采购服务器了&#xff0c;

一个比较全面实用的C#帮助类、工具类库

前言 经常会有一些同学会问为什么感觉我身边的大佬写一个功能会这么快&#xff1f;一个类似的模块大佬可能半天就搞定了&#xff0c;而我要搞一两天。其实工作久了你会发现很多常用公共的帮助类和工具类&#xff0c;如常见的Excel数据导入导出、文件操作、字符串操作、数据转换…

SpringBoot源码解读与原理分析(一)SpringBoot整体概述

文章目录 第1章 SpringBoot整体概述1.1 Spring Framework1.1.1 Spring Framework的历史1.1.2 IOC与AOP 1.2 Spring Boot与Spring Framework1.3 Spring Boot的核心特性1.4 Spring Boot的体系 第1章 SpringBoot整体概述 Spring Framework 开发团队 支持不依赖外部容器的Web应用程…

从零搭建React18.2+ReactRoute6.22+TS5+RTK2.2搭配antd5+antd-style书写All in Js完整体验项目规范

1. 使用CRA创建项目 全局设置npm淘宝镜像源 npm config set registry https://registry.npmmirror.com -g使用最新版create-react-app初始化项目结构 npx create-react-app custom-template --template typescript初始化项目之后在package.json文件中配置使用node>18.0.0…

WordPress供求插件API文档:用户登录

该文档为WordPress供求插件文档&#xff0c;详情请查看 WordPress供求插件&#xff1a;一款专注于同城生活信息发布的插件-CSDN博客文章浏览阅读67次。WordPress供求插件&#xff1a;sliver-urban-life 是一款专注于提供同城生活信息发布与查看的插件&#xff0c;该插件可以实…

首次在Java8中,使用jni调用C的dll

这次是使用C语言生成的dll 以下是在Java 8中使用JNI调用DLL的步骤清单&#xff1a; 编写Java类接口&#xff1a;创建一个Java接口&#xff0c;定义与本地方法对应的方法签名。 public interface MyNativeInterface {void nativeMethod(); }编写Java类实现&#xff1a;创建一…

windows下编译boost1.84.0库

boost系列文章目录 文章目录 boost系列文章目录前言一、boost编译二、boost使用三 、参考 前言 Boost简介 官方网址 Boost提供免费的同行评审的可移植C源代码库。 我们强调与C标准库配合良好的库。Boost库旨在广泛使用&#xff0c;并可在广泛的应用程序中使用。Boost许可证鼓…

一键打通红圈泛微,让协同办公更轻松!

客户介绍 某投资集团有限公司是一家总部位于中国深圳的多元化投资控股集团。自成立以来&#xff0c;该公司始终秉持着稳健经营、持续创新的理念&#xff0c;深耕多个领域&#xff0c;包括但不限于金融、地产、科技及文化产业等。展望未来&#xff0c;该公司将继续坚持创新驱动…

SpringBoot+Maven多环境配置模式

我这里有两个配置文件 然后在最外层的父级POM文件里面把这个两个配置文件写上 <profiles><profile><id>druid</id><properties><spring.profiles.active>druid</spring.profiles.active></properties><activation><…

算法训练day38动态规划基础Leetcode509斐波纳切数70爬楼梯746使用最小花费爬楼梯

什么是动态规划 对于动态规划问题&#xff0c;我将拆解为如下五步曲&#xff0c;这五步都搞清楚了&#xff0c;才能说把动态规划真的掌握了&#xff01; 确定dp数组&#xff08;dp table&#xff09;以及下标的含义确定递推公式dp数组如何初始化确定遍历顺序举例推导dp数组&a…

关于买手机和消费观念的小讨论

大家好&#xff0c;我是阿赵。   现在手机已经基本上是人手一台了&#xff0c;出门可以不带钱包&#xff0c;不能不带手机。阿赵我作为一个IT工作者&#xff0c;手机游戏开发者&#xff0c;这里给大家分享一下我这20多年来买手机的一些经历。   在阿赵我读大学的时候&#…

sensor_msgs::LaserScan雷达数据转换成pcl::PointXYZ数据类型

文章目录 创建工作空间、功能包功能包文件 package.xml头文件、源码文件laserscan_to_pointcloud.hlaserscan_to_pointcloud.cc 代码解读编译文件 CMakeLists.txt运行效果 截图 创建工作空间、功能包 catkin_create_pkg laserscan_to_pointcloud sensor_msgs roscpp pcl_conve…

分享关于如何解决系统设计问题的逐步框架

公司广泛采用系统设计面试&#xff0c;因为在这些面试中测试的沟通和解决问题的技能与软件工程师日常工作所需的技能相似。面试官的评估基于她如何分析一个模糊的问题以及如何逐步解决问题。测试的能力还包括她如何解释这个想法&#xff0c;与他人讨论&#xff0c;以及评估和优…

学习JAVA的第十六天(基础)

目录 双列集合 Map双列集合 遍历方式 键找值 键值对 Lambda表达式 HashMap集合 LinkedHashMap集合 TreeMap集合 可变参数 前言&#xff1a;学习JAVA的第十五天&#xff08;基础&#xff09;-CSDN博客 双列集合 特点&#xff1a; 双列集合一次需要存放一对数据&#x…

回溯算法07-子集(Java/子集问题)

.子集 题目描述 给你一个整数数组 nums &#xff0c;数组中的元素 互不相同 。返回该数组所有可能的子集&#xff08;幂集&#xff09;。解集 不能 包含重复的子集。你可以按 任意顺序 返回解集。 示例 1&#xff1a; 输入&#xff1a;nums [1,2,3] 输出&#xff1a;[[],[…

ChatGPT高效提问——说明提示技巧

ChatGPT高效提问——说明提示技巧 现在&#xff0c;让我们开始体验“说明提示技巧”&#xff08;IPT, Instructions Prompt Technique&#xff09;和如何用它生成来自ChatGPT的高质量的文本。说明提示技巧是一个通过向ChatGPT提供需要依据的具体的模型的说明来指导ChatGPT输出…

不伤耳朵的蓝牙耳机推荐,骨传导耳机选购前必知的几大要点

在目前的蓝牙耳机市场上&#xff0c;骨传导蓝牙耳机以其独特的设计和不伤耳朵的好处而受到广泛关注。骨传导蓝牙耳机通过骨头传导声音&#xff0c;无需进入耳道&#xff0c;从而减少了耳朵的不适和潜在伤害。 骨传导蓝牙耳机这种开放式的设计允许用户在享受音乐的同时&#xf…

lvs+keepalive

虚拟路由冗余协议(Virtual Router Redundancy Protocol&#xff0c;简称VRRP) VRRP能够在不改变组网的情况下&#xff0c;将多台路由器虚拟成一个虚拟路由器&#xff0c;通过配置虚拟路由器的IP地址为默认网关&#xff0c;实现网关的备份。 协议版本: VRRPv2&#xff08;常用&…

【GStreamer】basic-tutorial-4:媒体播放状态、跳转seek操作

【目录】郭老二博文之:图像视频汇总 1、示例注释 #include <gst/gst.h>typedef struct _CustomData {GstElement *playbin; /* 本例只有一个元素*/gboolean playing; /* 是否处于播放状态? */gboolean terminate;

【DevOps】4大API网关压力性能测试

【DevOps】4大API网关压力性能测试 作为DevOps服务的研发和服务提供者,我们经常会面对不同客户不同规模的需求,包括人员的激增,不同开发部署阶段的流量保证等等。 最最开始的时候,我们提供了一键安装 部署本地的单体式的SaaS软件服务,而随着时间技术的发展,我们研发和增…