Browse Source

finish up GL vertex buffer code

jp9000 12 năm trước cách đây
mục cha
commit
0a4592a414

+ 16 - 0
libobs-opengl/gl-helpers.c

@@ -79,3 +79,19 @@ bool gl_copy_texture(struct gs_device *device,
 
 	return success;
 }
+
+bool gl_create_buffer(GLuint *buffer, GLsizeiptr size, const GLvoid *data,
+		GLenum usage)
+{
+	bool success;
+	if (!gl_gen_buffers(1, buffer))
+		return false;
+	if (!gl_bind_buffer(GL_ARRAY_BUFFER, *buffer))
+		return false;
+
+	glBufferData(GL_ARRAY_BUFFER, size, data, usage);
+	success = gl_success("glBufferData");
+
+	gl_bind_buffer(GL_ARRAY_BUFFER, 0);
+	return success;
+}

+ 15 - 0
libobs-opengl/gl-helpers.h

@@ -48,6 +48,12 @@ static inline bool gl_bind_texture(GLenum target, GLuint texture)
 	return gl_success("glBindTexture");
 }
 
+static inline void gl_delete_textures(GLsizei num_buffers, GLuint *buffers)
+{
+	glDeleteTextures(num_buffers, buffers);
+	gl_success("glDeleteTextures");
+}
+
 static inline bool gl_gen_buffers(GLsizei num_buffers, GLuint *buffers)
 {
 	glGenBuffers(num_buffers, buffers);
@@ -60,6 +66,12 @@ static inline bool gl_bind_buffer(GLenum target, GLuint buffer)
 	return gl_success("glBindBuffer");
 }
 
+static inline void gl_delete_buffers(GLsizei num_buffers, GLuint *buffers)
+{
+	glDeleteBuffers(num_buffers, buffers);
+	gl_success("glDeleteBuffers");
+}
+
 static inline bool gl_bind_renderbuffer(GLenum target, GLuint buffer)
 {
 	glBindRenderbuffer(target, buffer);
@@ -75,4 +87,7 @@ extern bool gl_copy_texture(struct gs_device *device,
                             GLuint dst, GLenum dst_target,
                             uint32_t width, uint32_t height);
 
+extern bool gl_create_buffer(GLuint *buffer, GLsizeiptr size,
+		const GLvoid *data, GLenum usage);
+
 #endif

+ 5 - 9
libobs-opengl/gl-stagesurf.c

@@ -90,15 +90,11 @@ stagesurf_t device_create_stagesurface(device_t device, uint32_t width,
 void stagesurface_destroy(stagesurf_t stagesurf)
 {
 	if (stagesurf) {
-		if (stagesurf->pack_buffer) {
-			glDeleteBuffers(1, &stagesurf->pack_buffer);
-			gl_success("glDeleteBuffers");
-		}
-
-		if (stagesurf->texture) {
-			glDeleteTextures(1, &stagesurf->texture);
-			gl_success("glDeleteTextures");
-		}
+		if (stagesurf->pack_buffer)
+			gl_delete_buffers(1, &stagesurf->pack_buffer);
+
+		if (stagesurf->texture)
+			gl_delete_textures(1, &stagesurf->texture);
 
 		bfree(stagesurf);
 	}

+ 2 - 4
libobs-opengl/gl-subsystem.h

@@ -228,10 +228,8 @@ struct gs_vertex_buffer {
 	DARRAY(GLuint)       uv_buffers;
 
 	device_t             device;
-	bool                 dyanmic;
-	struct vb_data       *vbd;
-	size_t               num_verts;
-	DARRAY(size_t)       uv_sizes;
+	bool                 dynamic;
+	struct vb_data       *data;
 };
 
 struct gs_texture {

+ 4 - 8
libobs-opengl/gl-texture2d.c

@@ -116,15 +116,11 @@ void texture_destroy(texture_t tex)
 	if (!is_texture_2d(tex, "texture_destroy"))
 		return;
 
-	if (tex->is_dynamic && tex2d->unpack_buffer) {
-		glDeleteBuffers(1, &tex2d->unpack_buffer);
-		gl_success("glDeleteBuffers");
-	}
+	if (tex->is_dynamic && tex2d->unpack_buffer)
+		gl_delete_buffers(1, &tex2d->unpack_buffer);
 
-	if (tex->texture) {
-		glDeleteTextures(1, &tex->texture);
-		gl_success("glDeleteTextures");
-	}
+	if (tex->texture)
+		gl_delete_textures(1, &tex->texture);
 
 	bfree(tex);
 }

+ 153 - 3
libobs-opengl/gl-vertexbuffer.c

@@ -15,21 +15,171 @@
     along with this program.  If not, see <http://www.gnu.org/licenses/>.
 ******************************************************************************/
 
+#include "graphics/vec3.h"
 #include "gl-subsystem.h"
 
+static bool update_buffer(GLuint buffer, void *data, size_t size)
+{
+	void *ptr;
+	bool success = true;
+
+	if (!gl_bind_buffer(GL_ARRAY_BUFFER, buffer))
+		return false;
+
+	ptr = glMapBuffer(GL_ARRAY_BUFFER, GL_WRITE_ONLY);
+	success = gl_success("glMapBuffer");
+	if (success && ptr) {
+		memcpy(ptr, data, size);
+		glUnmapBuffer(GL_ARRAY_BUFFER);
+	}
+
+	gl_bind_buffer(GL_ARRAY_BUFFER, 0);
+	return success;
+}
+
+static bool init_vb(struct gs_vertex_buffer *vb)
+{
+	GLenum usage = vb->dynamic ? GL_DYNAMIC_COPY : GL_STATIC_DRAW;
+	size_t i;
+
+	if (!gl_create_buffer(&vb->vertex_buffer,
+				vb->data->num * sizeof(struct vec3),
+				vb->data->points, usage))
+		return false;
+
+	if (vb->data->normals) {
+		if (!gl_create_buffer(&vb->normal_buffer,
+					vb->data->num * sizeof(struct vec3),
+					vb->data->normals, usage))
+			return false;
+	}
+
+	if (vb->data->tangents) {
+		if (!gl_create_buffer(&vb->tangent_buffer,
+					vb->data->num * sizeof(struct vec3),
+					vb->data->tangents, usage))
+			return false;
+	}
+
+	if (vb->data->colors) {
+		if (!gl_create_buffer(&vb->color_buffer,
+					vb->data->num * sizeof(uint32_t),
+					vb->data->colors, usage))
+			return false;
+	}
+
+	da_reserve(vb->uv_buffers, vb->data->num_tex);
+
+	for (i = 0; i < vb->data->num_tex; i++) {
+		GLuint tex_buffer;
+		struct tvertarray *tv = vb->data->tvarray+i;
+		size_t size = vb->data->num * sizeof(float) * tv->width;
+
+		if (!gl_create_buffer(&tex_buffer, size, tv->array, usage))
+			return false;
+
+		da_push_back(vb->uv_buffers, &tex_buffer);
+	}
+
+	if (!vb->dynamic) {
+		vbdata_destroy(vb->data);
+		vb->data = NULL;
+	}
+
+	return true;
+}
+
 vertbuffer_t device_create_vertexbuffer(device_t device,
 		struct vb_data *data, uint32_t flags)
 {
+	struct gs_vertex_buffer *vb = bmalloc(sizeof(struct gs_vertex_buffer));
+	memset(vb, 0, sizeof(struct gs_vertex_buffer));
+
+	vb->data      = data;
+	vb->dynamic   = flags & GS_DYNAMIC;
+
+	if (!init_vb(vb)) {
+		blog(LOG_ERROR, "device_create_vertexbuffer (GL) failed");
+		vertexbuffer_destroy(vb);
+		return NULL;
+	}
+
+	return vb;
 }
 
-void vertexbuffer_destroy(vertbuffer_t vertbuffer)
+void vertexbuffer_destroy(vertbuffer_t vb)
 {
+	if (vb) {
+		if (vb->vertex_buffer)
+			gl_delete_buffers(1, &vb->vertex_buffer);
+
+		if (vb->normal_buffer)
+			gl_delete_buffers(1, &vb->normal_buffer);
+
+		if (vb->tangent_buffer)
+			gl_delete_buffers(1, &vb->tangent_buffer);
+
+		if (vb->color_buffer)
+			gl_delete_buffers(1, &vb->color_buffer);
+
+		if (vb->uv_buffers.num)
+			gl_delete_buffers((GLsizei)vb->uv_buffers.num,
+					vb->uv_buffers.array);
+
+		da_free(vb->uv_buffers);
+		vbdata_destroy(vb->data);
+
+		bfree(vb);
+	}
 }
 
-void vertexbuffer_flush(vertbuffer_t vertbuffer, bool rebuild)
+void vertexbuffer_flush(vertbuffer_t vb, bool rebuild)
 {
+	size_t i;
+
+	if (!vb->dynamic) {
+		blog(LOG_ERROR, "vertex buffer is not dynamic");
+		goto failed;
+	}
+
+	if (!update_buffer(vb->vertex_buffer, vb->data->points,
+				vb->data->num * sizeof(struct vec3)))
+		goto failed;
+
+	if (vb->normal_buffer) {
+		if (!update_buffer(vb->normal_buffer, vb->data->normals,
+					vb->data->num * sizeof(struct vec3)))
+			goto failed;
+	}
+
+	if (vb->tangent_buffer) {
+		if (!update_buffer(vb->tangent_buffer, vb->data->tangents,
+					vb->data->num * sizeof(struct vec3)))
+			goto failed;
+	}
+
+	if (vb->color_buffer) {
+		if (!update_buffer(vb->color_buffer, vb->data->colors,
+					vb->data->num * sizeof(uint32_t)))
+			goto failed;
+	}
+
+	for (i = 0; i < vb->data->num_tex; i++) {
+		GLuint buffer = vb->uv_buffers.array[i];
+		struct tvertarray *tv = vb->data->tvarray+i;
+		size_t size = vb->data->num * tv->width * sizeof(float);
+
+		if (!update_buffer(buffer, tv->array, size))
+			goto failed;
+	}
+
+	return;
+
+failed:
+	blog(LOG_ERROR, "vertexbuffer_flush (GL) failed");
 }
 
-struct vb_data *vertexbuffer_getdata(vertbuffer_t vertbuffer)
+struct vb_data *vertexbuffer_getdata(vertbuffer_t vb)
 {
+	return vb->data;
 }

+ 1 - 0
vs/2010/libobs-opengl/libobs-opengl.vcxproj

@@ -168,6 +168,7 @@
     <ClCompile Include="..\..\..\libobs-opengl\gl-subsystem.c" />
     <ClCompile Include="..\..\..\libobs-opengl\gl-texture2d.c" />
     <ClCompile Include="..\..\..\libobs-opengl\gl-texturecube.c" />
+    <ClCompile Include="..\..\..\libobs-opengl\gl-vertexbuffer.c" />
     <ClCompile Include="..\..\..\libobs-opengl\gl-windows.c" />
     <ClCompile Include="..\..\..\libobs-opengl\gl-zstencil.c" />
   </ItemGroup>

+ 3 - 0
vs/2010/libobs-opengl/libobs-opengl.vcxproj.filters

@@ -56,5 +56,8 @@
     <ClCompile Include="..\..\..\libobs-opengl\gl-stagesurf.c">
       <Filter>Source Files</Filter>
     </ClCompile>
+    <ClCompile Include="..\..\..\libobs-opengl\gl-vertexbuffer.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
   </ItemGroup>
 </Project>