Opengl知识点

1.Opengl大多数是由显卡商编写的,通常Bug通过升级显卡来解决。
2.老版的Opengl采用 立即渲染模式 Immediate Mode 固定渲染管线 简单,易理解,但不灵活。新版3.3版本以后的采用核心渲染模式 灵活效率,但不容易理解。
3.扩展新的特性或者是渲染优化通过扩展来实现。
4.状态机可以说Opengl本身就是一个状态机,一系列的变量来描述Opengl如何运行,Opengl的状态通常称为Context (上下文)。通常通过设置选项,操作缓冲区来改变状态。
5.对象是指一些选项的集合,表示Opengl状态的子集。(可以通过一个对象代表绘图窗口)
6.命名规则gl
7.通过创建上下文context用于显示窗口。通过GLFW(针对opengl的c语言库)创建窗口。
8.链接把库连接到工程中。
9.GLEW库分为静态和动态,静态不需要单独的文件,单独发布,但是可执行文件大,升级的话必须重新编译。动态的,代码与二进制文件分离。静态链接用到头文件GLEW_STATIC #include<GL/glew.h>
10.通过glfw实列化窗口,通过glew管理函数指针。
11.视口viewport。
12.缓冲区通常以双缓冲区的方法来渲染应用程序。缓冲区用来保存最终输出的图像,缓冲区保存着所有的渲染指令,当所有的渲染指令完成后,交换缓冲区。
13.输入通过GLFW的回调函数。
14.在Opengl中所有的物体都在3D空间中,而屏幕上却是2D像素数组。而图形渲染管线就是将3D坐标转化为2D屏幕像素数组。它分为两个大阶段,首先将3D坐标转化为2D坐标,然后再将2D坐标转化为2D像素。
15.GPU上每一个渲染管线,运行自己的小程序,从而在图形渲染管线快速处理数据,这些小程序就叫着色器(shader),有的着色器允许开发者自己配置,从而使我们可一控制图形渲染管线的特定部分(顶点着色器,片段着色器),因为他们在GPU上,所以减少了cpu的时间。
16.图形渲染管线,分为好几个部分,顶点着色器(对顶点进行操作,比如位移矩阵,产生光照坐标,产生贴图坐标),图元装配(将点配置成图元三角形),几何着色器(构成新的图元),光栅化(把图元映射为屏幕上的像素),片段着色器(计算最终的颜色),ALPHA测试blend混合(渲染物体前后)。
17.VBO(顶点缓冲对象)绑定后任何的缓冲调用,都会调用当前配置的缓冲,里边可以存大量的顶点信息。
18.EBO(索引缓冲对象)用来储存索引,通过索引来确定绘制哪些点。
19.VAO(顶点数组对象)可以像顶点缓冲对象那样被绑定,VAO相当持有从VBO解析(这里说的解析通过函数glVertexAttribPointe和glEnableVertexAttribArray)出来的数据(顶点属性)的引用,相当于arrary buffer target,arrary buffer只能操作一个VAO 和 VBO
20.渲染至少需要顶点和片段着色器。
21.着色器程序,把着色器合并program。
22.编译着色器,编译着色器的源码,因为我们是储存在一个c的字符串中,要向opengl解释这些数据,所以要编译创建一个不同类型的shader来编译。
23.顶点着色器的值输入可以通过vao的形式,也可以通过uniform的形式
24.shader两个着色器交互通过设置相同的字段通过in和out来建立联系。
25.opengl绘制一个简单的模型过程
在这里插入图片描述

着色器

1.在opengl中编写着色器的语言是GLSL,一个着色器由以下几个部分组成,开头的版本,输入输出的变量,uniform,和main函数。
2.GLSL数据类型分为,基本的float,int,和容器(容器又分为向量vector和矩阵matrix)。
3.输入到顶点着色器的变量叫做顶点属性,可以通过vao和uniform(cpu直接向着色器输入数据的方式)两种形式一共有16个位置,每个位置可以容纳最多四个分量。
4.如果Opengl最终输出的图片为黑白色的,那么说明片段着色器没有输出变量。
5.uniform在着色其中声明完没有值,要在着色器外的程序中为他赋值,1.先通过glGetUniformLocation获得它在着色器程序的位置。2.glUniform4f修改值。
6.编写自己的着色器类,通过外部的文件加载在这里插入图片描述
1.把文件流读取到缓冲中,转化为字符串流,然后在把字符串流转化为字符串,字符串在转换为OpenGL可识别的字符指针。2.编译着色器3.写着色器程序。(PS:检查着色器是否有错)

纹理

纹理是(what)一个2d的图片,(why)可以增加物体的细节,(how)用uv(纹理坐标),指定那个顶点对应那个纹理坐标。
环绕方式超出纹理坐标的化它会有几种情况,重复,镜像,边缘拉伸,边缘取色。
纹理过滤(what)将纹理像素映射到纹理坐标上。(why)物体很大,但是纹理的分辨率很低。(how)两种过滤方式临近过滤(就近取色)和线性过滤(取周边的颜色,然后进行插值运算)。
多级渐远纹理(mipmap)(what)根据原纹理产生一系列的纹理图像,每一个纹理的大小是前一个的1/2.(why)在远处产生的纹理片段很小,如果是高分辨率的纹理这样很难在其中取色。(how)glGenerateMipmap(GL_TEXTURE_2D)
加载纹理的步骤用到stbimage库,1.图片加载2.设置贴图缓冲3.向顶点发送uv信息和图片信息4.操作缓冲加载图片。
1.设置贴图缓冲

unsigned int TexBufferA;
	glGenTextures(1, &TexBufferA);
	glActiveTexture(GL_TEXTURE0);
	glBindTexture(GL_TEXTURE_2D, TexBufferA);

2.图片加载

int width, height, nrChannel;
	unsigned char *data = stbi_load("bird.jpg", &width, &height, &nrChannel, 0);
	if (data)
	{
		glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, data);
		glGenerateMipmap(GL_TEXTURE_2D);
	}
	else
	{
		printf("load image error");
	}

	stbi_image_free(data);

3.顶点的信息,shader接收这些信息并处理。

GLfloat vertices[] = {
		//     ---- 位置 ----       ---- 颜色 ----     - 纹理坐标 -
		0.5f,  0.5f, 0.0f,   1.0f, 0.0f, 0.0f,   1.0f, 1.0f,   // 右上
		0.5f, -0.5f, 0.0f,   0.0f, 1.0f, 0.0f,   1.0f, 0.0f,   // 右下
		-0.5f, -0.5f, 0.0f,   0.0f, 0.0f, 1.0f,   0.0f, 0.0f,   // 左下
		-0.5f,  0.5f, 0.0f,   1.0f, 1.0f, 0.0f,   0.0f, 1.0f    // 左上
	};
	glVertexAttribPointer(6, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)0); //链接顶点位置属性,如何向opengl解释这些顶点数据
	glEnableVertexAttribArray(6);

	glVertexAttribPointer(7, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)(3 * sizeof(float))); //链接顶点颜色属性,如何向opengl解释这些顶点数据
	glEnableVertexAttribArray(7);

	glVertexAttribPointer(8, 2, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)(6 * sizeof(float))); //链接顶点uv属性,如何向opengl解释这些顶点数据
	glEnableVertexAttribArray(8);

顶点

#version 330 core													 
layout(location = 6) in vec3 aPos;							
layout(location = 7) in vec3 aColor;
layout(location = 8) in vec2 texCoord;

out vec4 vertexColor;   
out vec2 TexCoord;

uniform mat4 transform;

void main(){
gl_Position = transform*vec4(aPos.x, aPos.y, aPos.z, 1.0);//顶点着色器的输出
vertexColor = vec4(aColor.x,aColor.y,aColor.z,1.0);
TexCoord = texCoord;
}

片段

#version 330 core						
in vec4 vertexColor;     
in vec2 TexCoord;

uniform sampler2D ourTexture;
uniform	sampler2D ourTexture2;
         
out vec4 fragmentcolor;				
	void main()
	{					
		fragmentcolor = texture(ourTexture,TexCoord)*texture(ourTexture2,TexCoord);
	} 

4.操作缓冲加载图片

		glActiveTexture(GL_TEXTURE0);
		glBindTexture(GL_TEXTURE_2D, TexBufferA);
		glActiveTexture(GL_TEXTURE3);
		glBindTexture(GL_TEXTURE_2D, TexBufferB); 
		
		glUniform1i(glGetUniformLocation(myShader->ID, "ourTexture"), 0);//根据不同的位置纹理单元激活不同的纹理单元。
		glUniform1i(glGetUniformLocation(myShader->ID, "ourTexture2"), 3);

纹理单元一次使用多个纹理,用uniform来传输,总共有16个。(how)先赋值给采样器,然后在外边激活,绑定
在这里插入图片描述

纹理采样Sampler2D(what)GLSL供纹理对象使用的类型。

变换

向量的计算
向量加标量,对应分量分别计算
向量相加,分量相加。
向量相乘,分为点成和叉乘,点乘等于向量的模乘以夹角的余弦,叉乘是求出垂直于两个向量所在平面的法向量,如何确定叉乘的法向量方向,a乘b(前乘后) 前向量为右手的食指方向,后向量为中指的方向,大拇指为法向量的方向。在这里插入图片描述

矩阵Matrix
向量是 空间上的几何关系,而矩阵是代数,是解决向量问题的工具。
矩阵的计算
矩阵加减乘除标量,各个分量一次相计算。
矩阵相乘,条件左行等于右列,不满足交换律。(how)行列相乘
在这里插入图片描述
在这里插入图片描述

单位i矩阵,对角线为1其他为o的矩阵,任何向量×单位矩阵都等于它本身。

在这里插入图片描述
矩阵的缩放
把单位矩阵的值改为对应的缩放比例然后和向量进行相乘。
在这里插入图片描述
矩阵的位移
修改最后一列的值为位移的值
在这里插入图片描述
齐次坐标
向量的w分量叫做齐次坐标,当齐次坐标为1的时候才能对坐标进行缩放和位移,如果齐次坐标为0,那么他就是个方向向量,不能通过矩阵来位移和缩放

向量的旋转
在这里插入图片描述
以上按每个步骤进行依次旋转会造成,万向节死锁所以推出了以下公式
在这里插入图片描述
向量和矩阵的混合运算
如果我们要对向量进行缩放和位移那么我们可以写一个位移矩阵,和一个缩放矩阵,然后把他们两个相乘,他们不满足交换律,他们的顺序很重要。在向量的变换操作时,一定要注意,先缩放,在旋转,在位移,而组合矩阵的顺序是相反的。
在这里插入图片描述

在这里插入图片描述
就比如这个是先对坐标进行缩放,然后再进行,位移,但是写法是从左到右,读法从右到左
GLM
在opengl中我们通过glm库的引入来实现向量和矩阵的运算

坐标系统

在opengl中顶点属性经过顶点着色器之后所有的坐标都会变成标准化设备坐标,在这个期间要经过几个不同的坐标系转换,而正好用到我们上一节所用到的矩阵。要想让坐标转化为我们需要的坐标系只需要生成对应的矩阵即可。

在这里插入图片描述

投影矩阵根据w齐次坐标是否固定分为正投影和透视投影。他的工作流程分为,先确定一个范围,然后将范围外的坐标剔除,然后将坐标xyz除以w分量(透视投影的模式下)将坐标由四维坐标转化为标准化设备坐标。

相机

弧度,从圆心发出两条方向不同的射线,与圆相交AB两点。那么AB就是弧长,弧长所对的角就是弧度,1弧度等于,弧长等于圆的半径所对的弧度。

欧拉角
欧拉角分为三个俯仰角(pitch),偏航角(Yaw),滚转角(Roll)
在这里插入图片描述
我们可以根据这个设置相机forward向量

在这里插入图片描述
设置一个相机步骤,本质就是让所有的顶点通过改变视口矩阵来实现相机,而改变视口矩阵的方法是就是我们自己创建一个坐标系,通过让每一个顶点乘这个矩阵就可以将所有的顶点转化到我们想要的坐标中,而glm库里的函数正好有lookat,lookat通过三个参数位置,目标和世界的up向量来设置。
在这里插入图片描述
记住第二个参数一定要加上position的位置,如果不加的话他会一直望向target方向。

鼠标输入,首先隐藏光标,编写鼠标移动的方法(FPS游戏的视角改变步骤),写回调函数执行编写的鼠标方法。

FPS游戏的视角改变步骤,设置上一帧与这一帧的偏移,偏移添加到俯仰角和偏航角,限制俯仰角和偏航角,计算方向向量。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值