[Bf-blender-cvs] [ddb1d56] blender2.8: Gawain: geometry batches (unfinished)

Mike Erwin noreply at git.blender.org
Tue Sep 13 08:56:58 CEST 2016


Commit: ddb1d5648dbd6d5be8b7fd9df4d122e6df5b5ce3
Author: Mike Erwin
Date:   Tue Sep 13 02:41:43 2016 -0400
Branches: blender2.8
https://developer.blender.org/rBddb1d5648dbd6d5be8b7fd9df4d122e6df5b5ce3

Gawain: geometry batches (unfinished)

Vertex Buffer to store vertex attribute data.
Element List (AKA Index Buffer) to select which vertices to use.
Batch combines these into an object that can be built once then drawn
many times.

Porting over from the C++ version… Most of this C code is compiled but
unused. Some of it is not even compiled. Committing now in case I’m
lost at sea.

===================================================================

M	source/blender/gpu/CMakeLists.txt
A	source/blender/gpu/GPU_batch.h
A	source/blender/gpu/gawain/batch.c
A	source/blender/gpu/gawain/batch.h
A	source/blender/gpu/gawain/element.c
A	source/blender/gpu/gawain/element.h
A	source/blender/gpu/gawain/vertex_buffer.c
A	source/blender/gpu/gawain/vertex_buffer.h

===================================================================

diff --git a/source/blender/gpu/CMakeLists.txt b/source/blender/gpu/CMakeLists.txt
index 33ebb92..99ce3eb 100644
--- a/source/blender/gpu/CMakeLists.txt
+++ b/source/blender/gpu/CMakeLists.txt
@@ -63,8 +63,12 @@ set(SRC
 	gawain/attrib_binding.c
 	gawain/attrib_binding.h
 	gawain/common.h
+	gawain/element.c
+	gawain/element.h
 	gawain/immediate.c
 	gawain/immediate.h
+	gawain/vertex_buffer.c
+	gawain/vertex_buffer.h
 	gawain/vertex_format.c
 	gawain/vertex_format.h
 
diff --git a/source/blender/gpu/GPU_batch.h b/source/blender/gpu/GPU_batch.h
new file mode 100644
index 0000000..10b00c3
--- /dev/null
+++ b/source/blender/gpu/GPU_batch.h
@@ -0,0 +1,33 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version. 
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2016 Blender Foundation.
+ * All rights reserved.
+ *
+ * 
+ * Contributor(s): Mike Erwin
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/* Batched geometry rendering is powered by the Gawain library.
+ * This file contains any additions or modifications specific to Blender.
+ */
+
+#pragma once
+
+#include "gawain/batch.h"
diff --git a/source/blender/gpu/gawain/batch.c b/source/blender/gpu/gawain/batch.c
new file mode 100644
index 0000000..3934d35
--- /dev/null
+++ b/source/blender/gpu/gawain/batch.c
@@ -0,0 +1,18 @@
+
+// Gawain geometry batch
+//
+// This code is part of the Gawain library, with modifications
+// specific to integration with Blender.
+//
+// Copyright 2016 Mike Erwin
+//
+// This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of
+// the MPL was not distributed with this file, You can obtain one at https://mozilla.org/MPL/2.0/.
+
+#include "batch.h"
+
+// BasicBatches
+// Vertex buffer with 3D pos only
+// Index buffer for edges (lines)
+// Index buffer for surface (triangles)
+// glGenBuffers(3,xxx)
diff --git a/source/blender/gpu/gawain/batch.h b/source/blender/gpu/gawain/batch.h
new file mode 100644
index 0000000..9625d66
--- /dev/null
+++ b/source/blender/gpu/gawain/batch.h
@@ -0,0 +1,135 @@
+
+// Gawain geometry batch
+//
+// This code is part of the Gawain library, with modifications
+// specific to integration with Blender.
+//
+// Copyright 2016 Mike Erwin
+//
+// This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of
+// the MPL was not distributed with this file, You can obtain one at https://mozilla.org/MPL/2.0/.
+
+#pragma once
+
+#include "vertex_buffer.h"
+#include "element.h"
+#include "attrib_binding.h"
+
+// How will this API be used?
+// create batch
+// ...
+// profit!
+
+// TODO: finalize Batch struct design & usage, pare down this file
+
+typedef struct {
+	VertexBuffer; // format is fixed at "vec3 pos"
+	ElementList line_elem;
+	ElementList triangle_elem;
+	GLuint vao_id;
+	GLenum prev_prim; // did most recent draw use GL_POINTS, GL_LINES or GL_TRIANGLES?
+} BasicBatch;
+
+// How to do this without replicating code?
+
+typedef struct {
+	VertexBuffer* verts;
+	ElementList* elem; // <-- NULL if element list not needed
+	GLenum prim_type;
+	GLuint vao_id;
+	GLuint bound_program;
+	AttribBinding attrib_binding;
+} Batch;
+
+// We often need a batch with its own data, to be created and discarded together.
+// WithOwn variants reduce number of system allocations.
+
+typedef struct {
+	Batch batch;
+	VertexBuffer verts; // link batch.verts to this
+} BatchWithOwnVertexBuffer;
+
+typedef struct {
+	Batch batch;
+	ElementList elem; // link batch.elem to this
+} BatchWithOwnElementList;
+
+typedef struct {
+	Batch batch;
+	ElementList elem; // link batch.elem to this
+	VertexBuffer verts; // link batch.verts to this
+} BatchWithOwnVertexBufferAndElementList;
+
+Batch* create_BatchWithOwnVertexBuffer(GLenum prim_type, VertexFormat*, unsigned v_ct, ElementList*);
+Batch* create_BatchWithOwnElementList(GLenum prim_type, VertexBuffer*, unsigned prim_ct);
+Batch* create_BatchWithOwnVertexBufferAndElementList(GLenum prim_type, VertexFormat*, unsigned v_ct, unsigned prim_ct);
+// verts: shared, own
+// elem: none, shared, own
+Batch* create_BatchInGeneral(GLenum prim_type, VertexBufferStuff, ElementListStuff);
+
+typedef struct {
+	// geometry
+	GLenum prim_type;
+	VertexBuffer verts;
+	ElementList elem; // <-- elem.index_ct = 0 if element list not needed
+
+	// book-keeping
+	GLuint vao_id; // <-- remembers all vertex state (array buffer, element buffer, attrib bindings)
+	// wait a sec... I thought VAO held attrib bindings but not currently bound array buffer.
+	// That's fine but verify that VAO holds *element* buffer binding.
+	// Verified: ELEMENT_ARRAY_BUFFER_BINDING is part of VAO state.
+	// VERTEX_ATTRIB_ARRAY_BUFFER_BINDING is too, per vertex attrib. Currently bound ARRAY_BUFFER is not.
+	// Does APPLE_vertex_array_object also include ELEMENT_ARRAY_BUFFER_BINDING?
+	// The extension spec refers only to APPLE_element_array, so.. maybe, maybe not?
+	// Will have to test during development, maybe alter behavior for APPLE_LEGACY. Can strip out this
+	// platform-specific cruft for Blender, keep it for legacy Gawain.
+
+	// state
+	GLuint bound_program;
+	AttribBinding attrib_binding;
+} Batch;
+
+typedef struct {
+	Batch* batch;
+} BatchBuilder;
+
+// One batch can be drawn with multiple shaders, as long as those shaders' inputs
+// are compatible with the batch's vertex format.
+
+// Can multiple batches share a VertexBuffer? Use ref count?
+
+// BasicBatch
+// Create one VertexBuffer from an object's verts (3D position only)
+// Shader must depend only on position + uniforms: uniform color, depth only, or object ID.
+// - draw verts via DrawArrays
+// - draw lines via DrawElements (can have 2 element lists: true face edges, triangulated edges)
+// - draw faces via DrawElements (raw triangles, not polygon faces)
+// This is very 3D-mesh-modeling specific. I'm investigating what Gawain needs to allow/expose
+// to meet Blender's needs, possibly other programs' needs.
+
+Batch* BatchPlease(GLenum prim_type, unsigned prim_ct, unsigned v_ct);
+//                   GL_TRIANGLES   12 triangles that share 8 vertices
+
+// Is there ever a reason to index GL_POINTS? nothing comes to mind...
+// (later) ok now that I'm thinking straight, *of course* you can draw
+// indexed POINTS. Only some verts from the buffer will be drawn. I was
+// just limiting my thinking to immediate needs. Batched needs.
+
+Batch* batch = BatchPlease(GL_TRIANGLES, 12, 8);
+unsigned pos = add_attrib(batch->verts.format, "pos", GL_FLOAT, 3, KEEP_FLOAT);
+pack(batch->verts->format); // or ...
+finalize(batch); // <-- packs vertex format, allocates vertex buffer
+
+Batch* create_Batch(GLenum prim_type, VertexBuffer*, ElementList*);
+
+// and don't forget
+Batch* immBeginBatch(GLenum prim_type, unsigned v_ct);
+// use standard immFunctions after this. immEnd will finalize the batch instead
+// of drawing.
+
+typedef enum {
+	READY_TO_FORMAT,
+	READY_TO_BUILD,
+	BUILDING, BUILDING_IMM, // choose one
+	READY_TO_DRAW
+} BatchPhase;
diff --git a/source/blender/gpu/gawain/element.c b/source/blender/gpu/gawain/element.c
new file mode 100644
index 0000000..0ec31f6
--- /dev/null
+++ b/source/blender/gpu/gawain/element.c
@@ -0,0 +1,253 @@
+
+// Gawain element list (AKA index buffer)
+//
+// This code is part of the Gawain library, with modifications
+// specific to integration with Blender.
+//
+// Copyright 2016 Mike Erwin
+//
+// This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of
+// the MPL was not distributed with this file, You can obtain one at https://mozilla.org/MPL/2.0/.
+
+#include "element.h"
+#include <stdlib.h>
+
+#define KEEP_SINGLE_COPY 1
+
+unsigned ElementList_size(const ElementList* elem)
+	{
+	switch (elem->index_type)
+		{
+		case GL_UNSIGNED_BYTE: return elem->index_ct * sizeof(GLubyte);
+		case GL_UNSIGNED_SHORT: return elem->index_ct * sizeof(GLushort);
+		case GL_UNSIGNED_INT: return elem->index_ct * sizeof(GLuint);
+		}
+
+	return 0;
+	}
+
+void ElementList_use(ElementList* elem)
+	{
+	if (elem->vbo_id)
+		glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, elem->vbo_id);
+	else
+		{
+		glGenBuffers(1, &elem->vbo_id);
+		glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, elem->vbo_id);
+		// fill with delicious data & send to GPU the first time only
+		glBufferData(GL_ELEMENT_ARRAY_BUFFER, ElementList_size(elem), elem->data, GL_STATIC_DRAW);
+
+#if KEEP_SINGLE_COPY
+		// now that GL has a copy, discard original
+		free(elem->data);
+		elem->data = NULL;
+#endif
+		}
+	}
+
+void ElementList_done_using()
+	{
+	glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
+	}
+
+void init_ElementListBuilder(ElementListBuilder* builder, GLenum prim_type, unsigned prim_ct, unsigned vertex_ct)
+	{
+	unsigned verts_per_prim;
+	switch (prim_type)
+		{
+		case GL_POINTS:
+			verts_per_prim = 1;
+			break;
+		case GL_LINES:
+			verts_per_prim = 2;
+			break;
+		case GL_TRIANGLES:
+			verts_per_prim = 3;
+			break;
+		default:
+			assert(false);
+		}
+
+	builder->max_allowed_index = vertex_ct - 1;
+	builder->max_index_ct = prim_ct * verts_per_prim;
+	builder->index_ct = 0; // start empty
+	builder->prim_type = prim_type;
+	builder->data = calloc(builder->max_index_ct, sizeof(unsigned));
+	}
+
+void add_generic_vertex(ElementListBuilder* builder, unsigned v)
+	{
+#if TRUST_NO_ONE
+	assert(builder->data != NULL);
+	assert(builder->index_ct < builder->max_index_ct);
+	assert(v <= builder->max_allowed_index);
+#endif
+
+	builder->data[builder->index_ct++] = v;
+	}
+
+void add_point_vertex(ElementListBuilder*

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list