Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender/draw/intern/draw_cache_impl_displist.c')
-rw-r--r--source/blender/draw/intern/draw_cache_impl_displist.c170
1 files changed, 170 insertions, 0 deletions
diff --git a/source/blender/draw/intern/draw_cache_impl_displist.c b/source/blender/draw/intern/draw_cache_impl_displist.c
new file mode 100644
index 00000000000..e051d61d056
--- /dev/null
+++ b/source/blender/draw/intern/draw_cache_impl_displist.c
@@ -0,0 +1,170 @@
+/*
+ * ***** 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) 2017 by Blender Foundation.
+ * All rights reserved.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file draw_cache_impl_displist.c
+ * \ingroup draw
+ *
+ * \brief DispList API for render engines
+ *
+ * \note DispList may be removed soon! This is a utility for object types that use render.
+ */
+
+#include "MEM_guardedalloc.h"
+
+#include "BLI_utildefines.h"
+#include "BLI_math_vector.h"
+
+#include "DNA_curve_types.h"
+
+#include "BKE_displist.h"
+
+#include "GPU_batch.h"
+
+#include "draw_cache_impl.h" /* own include */
+
+static int dl_vert_len(const DispList *dl)
+{
+ switch (dl->type) {
+ case DL_INDEX3:
+ case DL_INDEX4:
+ return dl->nr;
+ case DL_SURF:
+ return dl->parts * dl->nr;
+ }
+ return 0;
+}
+
+static int dl_tri_len(const DispList *dl)
+{
+ switch (dl->type) {
+ case DL_INDEX3:
+ return dl->parts;
+ case DL_INDEX4:
+ return dl->parts * 2;
+ case DL_SURF:
+ return dl->totindex * 2;
+ }
+ return 0;
+}
+
+/* see: displist_get_allverts */
+static int curve_render_surface_vert_len_get(const ListBase *lb)
+{
+ int vert_len = 0;
+ for (const DispList *dl = lb->first; dl; dl = dl->next) {
+ vert_len += dl_vert_len(dl);
+ }
+ return vert_len;
+}
+
+static int curve_render_surface_tri_len_get(const ListBase *lb)
+{
+ int tri_len = 0;
+ for (const DispList *dl = lb->first; dl; dl = dl->next) {
+ tri_len += dl_tri_len(dl);
+ }
+ return tri_len;
+}
+
+Gwn_Batch *BLI_displist_batch_calc_surface(ListBase *lb)
+{
+ const int tri_len = curve_render_surface_tri_len_get(lb);
+ if (tri_len == 0) {
+ return NULL;
+ }
+
+ static Gwn_VertFormat format = { 0 };
+ static struct { uint pos, nor; } attr_id;
+ if (format.attrib_ct == 0) {
+ /* initialize vertex format */
+ attr_id.pos = GWN_vertformat_attr_add(&format, "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT);
+ attr_id.nor = GWN_vertformat_attr_add(&format, "nor", GWN_COMP_F32, 3, GWN_FETCH_FLOAT);
+ }
+
+ const int vert_len = curve_render_surface_vert_len_get(lb);
+ Gwn_VertBuf *vbo = GWN_vertbuf_create_with_format(&format);
+ {
+ const int vbo_len_capacity = vert_len;
+ int vbo_len_used = 0;
+ GWN_vertbuf_data_alloc(vbo, vbo_len_capacity);
+
+ BKE_displist_normals_add(lb);
+
+ for (const DispList *dl = lb->first; dl; dl = dl->next) {
+ const bool ndata_is_single = dl->type == DL_INDEX3;
+ if (ELEM(dl->type, DL_INDEX3, DL_INDEX4, DL_SURF)) {
+ const float *fp_co = dl->verts;
+ const float *fp_no = dl->nors;
+ const int vbo_end = vbo_len_used + dl_vert_len(dl);
+ while (vbo_len_used < vbo_end) {
+ GWN_vertbuf_attr_set(vbo, attr_id.pos, vbo_len_used, fp_co);
+ if (fp_no) {
+ GWN_vertbuf_attr_set(vbo, attr_id.nor, vbo_len_used, fp_no);
+ if (ndata_is_single == false) {
+ fp_no += 3;
+ }
+ }
+ fp_co += 3;
+ vbo_len_used += 1;
+ }
+ }
+ }
+ }
+
+ {
+ Gwn_IndexBufBuilder elb;
+ GWN_indexbuf_init(&elb, GWN_PRIM_TRIS, tri_len, vert_len);
+
+ int ofs = 0;
+ int tri_len_used = 0;
+ for (const DispList *dl = lb->first; dl; dl = dl->next) {
+ if (ELEM(dl->type, DL_INDEX3, DL_INDEX4, DL_SURF)) {
+ if (dl->type == DL_INDEX3) {
+ const int *idx = dl->index;
+ const int i_end = dl->parts;
+ for (int i = 0; i < i_end; i++) {
+ GWN_indexbuf_add_tri_verts(&elb, idx[0] + ofs, idx[1] + ofs, idx[2] + ofs);
+ tri_len_used += 1;
+ idx += 3;
+ }
+ }
+ else if (ELEM(dl->type, DL_INDEX4, DL_SURF)) {
+ const int *idx = dl->index;
+ const int i_end = dl->totindex;
+ for (int i = 0; i < i_end; i++) {
+ GWN_indexbuf_add_tri_verts(&elb, idx[0] + ofs, idx[1] + ofs, idx[2] + ofs);
+ tri_len_used += 1;
+ GWN_indexbuf_add_tri_verts(&elb, idx[0] + ofs, idx[2] + ofs, idx[3] + ofs);
+ tri_len_used += 1;
+ idx += 4;
+ }
+ }
+ ofs += dl_vert_len(dl);
+ }
+ }
+
+ return GWN_batch_create_ex(
+ GWN_PRIM_TRIS, vbo, GWN_indexbuf_build(&elb),
+ GWN_BATCH_OWNS_VBO | GWN_BATCH_OWNS_INDEX);
+ }
+}