Kaynağa Gözat

feat: 添加数据处理的函数介绍

NiceTry12138 9 ay önce
ebeveyn
işleme
b1f749d814
1 değiştirilmiş dosya ile 89 ekleme ve 0 silme
  1. 89 0
      图形学/OpenGL学习/OpenGLDemo.md

+ 89 - 0
图形学/OpenGL学习/OpenGLDemo.md

@@ -827,5 +827,94 @@ vec4 pos = projection * view * vec4(inPosition, 1.0);
 gl_Position = pos.xyww;
 ```
 
+### 高级数据
 
+使用 `glBufferData` 会分配一块 GPU 内存,并将数据添加到这块内存中,如果设置为 null 则只会分配,不会填充
+
+使用 `glBufferSubData` 可以填充缓冲的特定区域
+
+`glBufferSubData` 函数定义如下
+
+```cpp
+void glBufferSubData(	GLenum target,
+						GLintptr offset,
+						GLsizeiptr size,
+						const GLvoid * data);
+```
+
+`glBufferSubData` 函数使用如下
+
+```cpp
+// 创建并初始化顶点缓冲区
+GLuint VBO;
+glGenBuffers(1, &VBO);
+glBindBuffer(GL_ARRAY_BUFFER, VBO);
+float vertices[12] = { /* 初始6个顶点(每个含x,y) */ };
+glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_DYNAMIC_DRAW);
+
+// 更新第3到第4个顶点(索引2和3)
+float updatedData[4] = {0.5f, 0.5f, -0.5f, -0.5f}; // 新坐标 (x1,y1, x2,y2)
+glBufferSubData(GL_ARRAY_BUFFER, 2 * sizeof(float) * 2, sizeof(updatedData), updatedData);
+```
+
+使用 `glMapBuffer` 可以得到缓冲内存的指针,然后通过 `memcpy` 拷贝数据进去
+
+```cpp
+float data[] = {
+  0.5f, 1.0f, -0.35f
+  ...
+};
+glBindBuffer(GL_ARRAY_BUFFER, buffer);
+// 获取指针
+void *ptr = glMapBuffer(GL_ARRAY_BUFFER, GL_WRITE_ONLY);
+// 复制数据到内存
+memcpy(ptr, data, sizeof(data));
+// 记得告诉OpenGL我们不再需要这个指针了
+glUnmapBuffer(GL_ARRAY_BUFFER);
+```
+
+这里的 `glUnmapBuffer` 不是丢弃 `GL_ARRAY_BUFFER`,而是接触指针映射,即 `ptr` 指针无法映射到 GPU 内存中,继续使用 `ptr` 会导致错误
+
+> 相当于 `glUnmapBuffer` 会释放 CPU 对缓冲区内存的映射权限
+
+使用 `glCopyBufferSubData` 能够将一个缓冲目标的数据拷贝到另一个缓冲目标中
+
+```cpp
+void glCopyBufferSubData(	GLenum readTarget,
+							GLenum writeTarget,
+							GLintptr readOffset,
+							GLintptr writeOffset,
+							GLsizeiptr size);
+```
+
+> 函数定义
+
+```cpp
+// 创建两个缓冲区
+GLuint vboSrc, vboDst;
+glGenBuffers(1, &vboSrc);
+glGenBuffers(1, &vboDst);
+
+// 填充源缓冲区
+float srcData[] = { /* 顶点数据 */ };
+glBindBuffer(GL_COPY_READ_BUFFER, vboSrc);
+glBufferData(GL_COPY_READ_BUFFER, sizeof(srcData), srcData, GL_STATIC_DRAW);
+
+// 初始化目标缓冲区(大小与源相同)
+glBindBuffer(GL_COPY_WRITE_BUFFER, vboDst);
+glBufferData(GL_COPY_WRITE_BUFFER, sizeof(srcData), NULL, GL_STATIC_DRAW);
+
+// 复制整个缓冲区
+glCopyBufferSubData(
+    GL_COPY_READ_BUFFER,
+    GL_COPY_WRITE_BUFFER,
+    0, 0, sizeof(srcData)
+);
+
+// 使用目标缓冲区渲染
+glBindBuffer(GL_ARRAY_BUFFER, vboDst);
+glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, NULL);
+glDrawArrays(GL_TRIANGLES, 0, 36);
+```
+> 使用案例