OpenGL API - glMapBuffer - 可用于获取缓存对象指针

因为有需要对网格顶点属性实时更新,所以我之前使用的 API 是:glBufferData

// method 1:
glBindBuffer(GL_ARRAY_BUFFER, vbos[(int)MeshVboType::POSITION]);
glBufferData(GL_ARRAY_BUFFER, arr->bytes_size(), arr->ptr(), _dynamic ? GL_DYNAMIC_DRAW : GL_STATIC_DRAW);
checkGLError();

但是从 API 参数可以看到,它需要获取 GL_ARRAY_BUFFER 类型缓存的指针,指定分配大小,并设置数据,并指定缓存区块是类型。

对于我们只需要更新数据来说,这个 API 做的东西过多了。


然后,我在继续学习 LearnGL 系列的过程中,法线另一对 API: glMapBuffer、glUnmapBuffer,这对 API 正式我需要的功能,我的学习项目中的代码如下:

	void Mesh::uploadPos(FixedArray<GLfloat>* arr) {
		if (!_uploaded) return;
		if (arr != _vertices) {
			assert(arr != NULL);
			DESTROY(_vertices);
			_vertices = arr;
			pos_copy_from(arr->ptrType(), arr->size());
			// 新的缓存
			// vbo
			glBindBuffer(GL_ARRAY_BUFFER, vbos[(int)MeshVboType::POSITION]);
			// pos
			glBufferData(GL_ARRAY_BUFFER, _vertices->bytes_size(), _vertices->ptr(), _dynamic ? GL_DYNAMIC_DRAW : GL_STATIC_DRAW);
			glVertexAttribPointer(pos_loc, 3, GL_FLOAT, GL_FALSE, 0, (GLvoid*)0);
			glEnableVertexAttribArray(pos_loc);
			_vertices_byte_size = _vertices->bytes_size();
			_vertices_count = _vertices->size() / 3;
			checkGLError();
		}
		else {
			// method 1:
			//glBindBuffer(GL_ARRAY_BUFFER, vbos[(int)MeshVboType::POSITION]);
			//glBufferData(GL_ARRAY_BUFFER, arr->bytes_size(), arr->ptr(), _dynamic ? GL_DYNAMIC_DRAW : GL_STATIC_DRAW);
			//checkGLError();

			// method 2:
			// 参考:https://learnopengl-cn.github.io/04%20Advanced%20OpenGL/07%20Advanced%20Data/
			// 设置当前 VB O对象
			glBindBuffer(GL_ARRAY_BUFFER, vbos[(int)MeshVboType::POSITION]);
			// 获取当前 VBO 的只写指针
			void* ptr = glMapBuffer(GL_ARRAY_BUFFER, GL_WRITE_ONLY);
			// 复制数据到内存
			memcpy(ptr, arr->ptr(), arr->bytes_size());
			// 记得告诉OpenGL我们不再需要这个指针了
			if (glUnmapBuffer(GL_ARRAY_BUFFER) != GL_TRUE) {
				std::cerr << "Mesh Update Pos Failure!\n";
			}
			checkGLError();
		}
	}

结合上下文,主要看下部的部分:

			// 参考:https://learnopengl-cn.github.io/04%20Advanced%20OpenGL/07%20Advanced%20Data/
			// 设置当前 VB O对象
			glBindBuffer(GL_ARRAY_BUFFER, vbos[(int)MeshVboType::POSITION]);
			// 获取当前 VBO 的只写指针
			void* ptr = glMapBuffer(GL_ARRAY_BUFFER, GL_WRITE_ONLY);
			// 复制数据到内存
			memcpy(ptr, arr->ptr(), arr->bytes_size());
			// 记得告诉OpenGL我们不再需要这个指针了
			if (glUnmapBuffer(GL_ARRAY_BUFFER) != GL_TRUE) {
				std::cerr << "Mesh Update Pos Failure!\n";
			}

这样我们仅仅做的是:获取 GL_ARRAY_BUFFER 缓存的 只写 指定,然后对该指针的数据更新,在告诉 OpenGL 关闭该 只写指针,非常适合我的需求。


References

  • 高级数据

你可能感兴趣的:(OpenGL,OpenGL,API,OpenGL,glMapBuffer,OpenGL,获取缓存对象指针)