소스 검색

feat: 添加 blender 混合的解释

NiceTry12138 10 달 전
부모
커밋
5ad2200c94

+ 1 - 0
.gitignore

@@ -1,4 +1,5 @@
 Debug
 x64
 .vs
+.idea
 node_modules

BIN
图形学/OpenGL学习/Image/020.png


BIN
图形学/OpenGL学习/Image/021.png


+ 57 - 6
图形学/OpenGL学习/README.md

@@ -621,10 +621,6 @@ float positions[] = {
 | --- | --- |
 | ![](Image/011.png) | ![](Image/012.png) |
 
-```cpp
-GLuint =
-```
-
 一般来说
 
 1. 创建索引缓冲区:首先,你需要使用 `glGenBuffers` 创建一个缓冲区对象
@@ -649,6 +645,8 @@ while (!glfwWindowShouldClose(window))
 }
 ```
 
+`glDrawElements` 最后一个参数 `const GLvoid * indices` 表示相对于当前绑定的 `GL_ELEMENT_ARRAY_BUFFER` 的数据地址偏移
+
 ## OpenGL 的错误信息
 
 ```cpp
@@ -1345,6 +1343,59 @@ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
 | --- | --- |
 | ![](Image/018.png) | ![](Image/019.png) |
 
-## END
+### 关于混合
+
+之前的代码,需要开启混合,否则会出现问题
+
+什么是混合?
+
+混合就是在渲染一部分或者完全**透明**的东西时,应该怎么做
+
+默认情况下, `OpenGL` 不执行任何混合,它只把目标渲染成不透明的东西
+
+混合决定了如何将输出颜色与目标缓冲区已经存在的颜色结合起来
+
+![](Image/020.png)
+
+> 图片中蓝色区域为半透明,红色为底色
+
+那么上述图片中
+
+- 蓝色是从片段着色器中输出的颜色,所以说是**输出颜色**,也称 `Source`
+- 目标缓冲区是要绘制蓝色方块的区域
+
+如何将两种颜色结合起来?
+
+`OpenGL` 提供三种方法
+
+1. 启用和禁用
+   - `glEnable` 和 `glDisable` 来启用/禁用 `GL_BLEND` 混合
+   - 默认情况下没有开启 `GL_BLEND`,也就不会混合
+2. 使用 `glBlendFunc`,用于如何将两种颜色混合在一起
+   - 接收一个 `src` 和 `dest` 的参数
+   - [glBendFunc](https://docs.gl/gl4/glBlendFunc) 中有详细介绍函数参数的作用
+   - 默认第一个参数 `sfactor` (`src factor`)取值为 `GL_ONE` 也就是全覆盖,所以上述案例中,默认情况蓝色会直接覆盖红色
+   - 默认第二个参数 `dfactor` (`desc factor`) 取值为 `GL_ZERO` 也就是完全丢失,所以上述案例中,默认情况红色被完全抛弃
+
+![](Image/021.png)
+
+默认情况下,`sfactor` 是 `GL_ONE`,`dfactor` 是 `GL_ZERO`,那么最终得到的结果就是 `src` * 1 + `dest` * 0 
+
+```cpp
+glEnable(GL_BLEND);
+glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+```
+
+## 数学计算
+
+使用 `glm` 作为项目的数学库
+
+在游戏运行过程中,除了大部分 UI 绘制在屏幕空间之外,剩下的物体都是在世界空间下,它们具有 3D 坐标,需要将这些物体映射到 2D 的屏幕空间内
+
+这里就涉及到一个 **投影矩阵** 的计算
+
+比如,项目是一个 2D 项目,可以使用正交矩阵进行坐标转换,将 3D 坐标转换到 2D 的屏幕空间
+
+如果项目是一个 3D 项目,一般使用透视矩阵进行坐标转换,将 3D 坐标转换到 2D 的屏幕空间,这是因为 3D 游戏需要近大远小的表现效果
+
 
-工作需要,后续改为 `Direct` 学习

+ 3 - 1
图形学/OpenGL学习/src/OpenGLStudy/OpenGLStudy/res/shader/Vertex.vert

@@ -6,7 +6,9 @@ layout(location = 1) in vec2 texCoord;
 out vec2 v_TexCoord;
 out vec4 v_Position;
 
+uniform mat4 u_MVP;
+
 void main() {
-	gl_Position = position;
+	gl_Position = u_MVP * position;
 	v_TexCoord = texCoord;
 }

+ 9 - 2
图形学/OpenGL学习/src/OpenGLStudy/OpenGLStudy/src/Application.cpp

@@ -12,9 +12,12 @@
 #include "Renderer.h"
 #include "Texture.h"
 
+#include "vendor/glm/glm.hpp"
+#include "vendor/glm/gtc/matrix_transform.hpp"
+
 int main(void)
 {
-	GLFWwindow* window;
+	GLFWwindow* window = nullptr;
 
 	/* Initialize the library */
 	if (!glfwInit())
@@ -42,6 +45,9 @@ int main(void)
 
 	std::cout << glGetString(GL_VERSION) << std::endl;
 
+	// 设定宽高是 640, 480 比例是 4:3 
+	glm::mat4 proj = glm::ortho(-4.0f, 4.0f, -3.0f, 3.0f, -1.0f, 1.0f);
+
 	{
 		float positions[] = {
 			-0.5f, -0.5f, 0.0f, 0.0f,
@@ -55,7 +61,7 @@ int main(void)
 			2, 3, 0
 		};
 
-		//glEnable(GL_BLEND);
+		glEnable(GL_BLEND);
 		glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
 
 		VertexArray va;
@@ -76,6 +82,7 @@ int main(void)
 		auto shader = Shader("res/shader/Vertex.vert", "res/shader/Fragment.frag");
 		shader.Bind();
 		shader.SetUniform1i("u_Texture", 0);
+		shader.SetUniformMat4f("u_MVP", proj);
 
 		// 清除所有绑定关系
 		va.Unbind();

+ 6 - 0
图形学/OpenGL学习/src/OpenGLStudy/OpenGLStudy/src/Shader.cpp

@@ -37,6 +37,12 @@ void Shader::SetUniform1i(const std::string& name, int v0)
 	GL_CALL(glUniform1i(location, v0));
 }
 
+void Shader::SetUniformMat4f(const std::string& name, const glm::mat4& inMat4)
+{
+	GLint location = GetUniformLocation(name);
+	GL_CALL(glUniformMatrix4fv(location, 1, GL_FALSE, &inMat4[0][0]));
+}
+
 GLint Shader::GetUniformLocation(const std::string& name)
 {
 	if (m_Locations.find(name) != m_Locations.end()) {

+ 4 - 1
图形学/OpenGL学习/src/OpenGLStudy/OpenGLStudy/src/Shader.h

@@ -3,6 +3,8 @@
 #include <string>
 #include <unordered_map>
 
+#include "vendor/glm/glm.hpp"
+
 class Shader
 {
 private:
@@ -10,7 +12,7 @@ private:
 	std::string m_FragmentFilePath;
 	GLuint m_ShaderId;
 
-	// »º´æ uniform µÄ Location
+	// 缓存 uniform 的 Location
 	std::unordered_map<std::string, GLint> m_Locations;
 
 public:
@@ -22,6 +24,7 @@ public:
 
 	void SetUniform4f(const std::string& name, float v0, float v1, float v2, float v3);
 	void SetUniform1i(const std::string& name, int v0);
+	void SetUniformMat4f(const std::string& name, const glm::mat4& inMat4);
 		
 private:
 	GLint GetUniformLocation(const std::string& name);

+ 2 - 2
图形学/OpenGL学习/src/OpenGLStudy/OpenGLStudy/src/Texture.h

@@ -7,14 +7,14 @@ private:
 	GLuint m_RenderID = 0;
 	std::string m_FilePath;
 	GLubyte* m_LocalBuffer{ nullptr };
-	// BPP Bit Per Pixel 表示每个像素的位数, 24bit-color 通常由三通道颜色组成;32bit-color 通常由四通道颜色组成
+	// BPP Bit Per Pixel 琛ㄧず姣忎釜鍍忕礌鐨勪綅鏁帮紝 24bit-color 閫氬父鐢变笁閫氶亾棰滆壊缁勬垚锛�32bit-color 閫氬父鐢卞洓閫氶亾棰滆壊缁勬垚
 	int m_Width = 0, m_Height = 0, m_BPP = 0;
 
 public:
 	Texture(const std::string& filePath);
 	~Texture();
 	
-	// slot 用与绑定插槽
+	// slot 鐢ㄤ笌缁戝畾鎻掓Ы
 	void Bind(unsigned int slot = 0) const;
 	void Unbind() const;