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:
authorDalai Felinto <dfelinto@gmail.com>2017-01-25 11:16:29 +0300
committerDalai Felinto <dfelinto@gmail.com>2017-01-25 12:01:48 +0300
commit99cfad6a015715a090fa2e1d808196dd1a02b390 (patch)
tree60fe28d57fe7881ac31f2028c666a4067d24f6f9 /source/blender
parent5be2a62ca3c93add06e606c05592f7f4a1530ddd (diff)
Convert MBC_ API to Mesh (instead of derived mesh) and move it to mesh_render
This includes a few fixes in the MBC_ api. The idea here is for this to be the only interface the render engines will deal with for the meshes. If we need to expose special options for sculpting engine we refactor this accordingly. But for now we are shaping this in a per-case base. Note: * We still need to hook up to the depsgraph to force clear/update of batch_cache when mesh changes (I'm waiting for Sergey Sharybin's depsgraph update for this though) * Also ideally we could/should use BMesh directly instead of DerivedMesh, but this will do for now. Note 2: In the end I renamed the `BKE_mesh_render` functions to `static mesh_render`. We can re-expose them as BKE_* later once we need it. Reviewers: merwin Subscribers: fclem Differential Revision: https://developer.blender.org/D2476
Diffstat (limited to 'source/blender')
-rw-r--r--source/blender/blenkernel/BKE_DerivedMesh.h7
-rw-r--r--source/blender/blenkernel/BKE_mesh_render.h42
-rw-r--r--source/blender/blenkernel/CMakeLists.txt2
-rw-r--r--source/blender/blenkernel/intern/DerivedMesh.c13
-rw-r--r--source/blender/blenkernel/intern/mesh.c4
-rw-r--r--source/blender/blenkernel/intern/mesh_render.c619
-rw-r--r--source/blender/editors/space_view3d/drawobject.c360
-rw-r--r--source/blender/gpu/gawain/batch.h2
-rw-r--r--source/blender/makesdna/DNA_mesh_types.h1
9 files changed, 685 insertions, 365 deletions
diff --git a/source/blender/blenkernel/BKE_DerivedMesh.h b/source/blender/blenkernel/BKE_DerivedMesh.h
index 059f7309cf5..784c76bffd3 100644
--- a/source/blender/blenkernel/BKE_DerivedMesh.h
+++ b/source/blender/blenkernel/BKE_DerivedMesh.h
@@ -145,10 +145,6 @@ typedef DMDrawOption (*DMSetDrawOptions)(void *userData, int index);
typedef DMDrawOption (*DMSetDrawOptionsMappedTex)(void *userData, int origindex, int mat_nr);
typedef DMDrawOption (*DMSetDrawOptionsTex)(struct MTexPoly *mtexpoly, const bool has_vcol, int matnr);
-/* Cleanup callback type */
-typedef void (*DMCleanupBatchCache)(void *batchCache);
-void DM_set_batch_cleanup_callback(DMCleanupBatchCache);
-
typedef enum DMDrawFlag {
DM_DRAW_USE_COLORS = (1 << 0),
DM_DRAW_ALWAYS_SMOOTH = (1 << 1),
@@ -176,6 +172,8 @@ typedef enum DMDirtyFlag {
/* check this with modifier dependsOnNormals callback to see if normals need recalculation */
DM_DIRTY_NORMALS = 1 << 2,
+
+ DM_MESH_BATCH_CACHE = 1 << 3,
} DMDirtyFlag;
typedef struct DerivedMesh DerivedMesh;
@@ -187,7 +185,6 @@ struct DerivedMesh {
int deformedOnly; /* set by modifier stack if only deformed from original */
BVHCache *bvhCache;
struct GPUDrawObject *drawObject;
- void *batchCache;
DerivedMeshType type;
float auto_bump_scale;
DMDirtyFlag dirty;
diff --git a/source/blender/blenkernel/BKE_mesh_render.h b/source/blender/blenkernel/BKE_mesh_render.h
new file mode 100644
index 00000000000..8a2b3f9d9ec
--- /dev/null
+++ b/source/blender/blenkernel/BKE_mesh_render.h
@@ -0,0 +1,42 @@
+/*
+ * ***** 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.
+ *
+ * Contributor(s): Blender Foundation, Mike Erwin, Dalai Felinto
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+#ifndef __BKE_MESH_RENDER_H__
+#define __BKE_MESH_RENDER_H__
+
+/** \file BKE_mesh_render.h
+ * \ingroup bke
+ */
+
+struct Batch;
+struct Mesh;
+
+void BKE_mesh_batch_cache_free(struct Mesh *me);
+struct Batch *BKE_mesh_batch_cache_get_all_edges(struct Mesh *me);
+struct Batch *BKE_mesh_batch_cache_get_all_triangles(struct Mesh *me);
+struct Batch *BKE_mesh_batch_cache_get_all_verts(struct Mesh *me);
+struct Batch *BKE_mesh_batch_cache_get_fancy_edges(struct Mesh *me);
+struct Batch *BKE_mesh_batch_cache_get_overlay_edges(struct Mesh *me);
+
+#endif /* __BKE_MESH_RENDER_H__ */
diff --git a/source/blender/blenkernel/CMakeLists.txt b/source/blender/blenkernel/CMakeLists.txt
index 2ccbed58b04..f3bab55b47d 100644
--- a/source/blender/blenkernel/CMakeLists.txt
+++ b/source/blender/blenkernel/CMakeLists.txt
@@ -133,6 +133,7 @@ set(SRC
intern/mesh_evaluate.c
intern/mesh_mapping.c
intern/mesh_remap.c
+ intern/mesh_render.c
intern/mesh_validate.c
intern/modifier.c
intern/modifiers_bmesh.c
@@ -257,6 +258,7 @@ set(SRC
BKE_mesh.h
BKE_mesh_mapping.h
BKE_mesh_remap.h
+ BKE_mesh_render.h
BKE_modifier.h
BKE_movieclip.h
BKE_multires.h
diff --git a/source/blender/blenkernel/intern/DerivedMesh.c b/source/blender/blenkernel/intern/DerivedMesh.c
index fb0087aefac..e0bbe345fc4 100644
--- a/source/blender/blenkernel/intern/DerivedMesh.c
+++ b/source/blender/blenkernel/intern/DerivedMesh.c
@@ -260,12 +260,6 @@ static CustomData *dm_getPolyCData(DerivedMesh *dm)
return &dm->polyData;
}
-static DMCleanupBatchCache cleanupBatchCache = NULL;
-void DM_set_batch_cleanup_callback(DMCleanupBatchCache func)
-{
- cleanupBatchCache = func;
-}
-
/**
* Utility function to initialize a DerivedMesh's function pointers to
* the default implementation (for those functions which have a default)
@@ -324,8 +318,6 @@ void DM_init(
DM_init_funcs(dm);
- dm->batchCache = NULL; /* necessary? dm->drawObject is not set to NULL yet it works fine */
-
dm->needsFree = 1;
dm->auto_bump_scale = -1.0f;
dm->dirty = 0;
@@ -385,10 +377,7 @@ int DM_release(DerivedMesh *dm)
if (dm->needsFree) {
bvhcache_free(&dm->bvhCache);
GPU_drawobject_free(dm);
- if (dm->batchCache && cleanupBatchCache) {
- cleanupBatchCache(dm->batchCache);
- dm->batchCache = NULL;
- }
+
CustomData_free(&dm->vertData, dm->numVertData);
CustomData_free(&dm->edgeData, dm->numEdgeData);
CustomData_free(&dm->faceData, dm->numTessFaceData);
diff --git a/source/blender/blenkernel/intern/mesh.c b/source/blender/blenkernel/intern/mesh.c
index af02e02b017..134173580ae 100644
--- a/source/blender/blenkernel/intern/mesh.c
+++ b/source/blender/blenkernel/intern/mesh.c
@@ -48,6 +48,7 @@
#include "BKE_DerivedMesh.h"
#include "BKE_global.h"
#include "BKE_mesh.h"
+#include "BKE_mesh_render.h"
#include "BKE_displist.h"
#include "BKE_library.h"
#include "BKE_library_query.h"
@@ -435,6 +436,8 @@ void BKE_mesh_free(Mesh *me)
{
BKE_animdata_free(&me->id, false);
+ BKE_mesh_batch_cache_free(me);
+
CustomData_free(&me->vdata, me->totvert);
CustomData_free(&me->edata, me->totedge);
CustomData_free(&me->fdata, me->totface);
@@ -522,6 +525,7 @@ Mesh *BKE_mesh_copy(Main *bmain, Mesh *me)
BKE_mesh_update_customdata_pointers(men, do_tessface);
men->edit_btmesh = NULL;
+ men->batch_cache = NULL;
men->mselect = MEM_dupallocN(men->mselect);
men->bb = MEM_dupallocN(men->bb);
diff --git a/source/blender/blenkernel/intern/mesh_render.c b/source/blender/blenkernel/intern/mesh_render.c
new file mode 100644
index 00000000000..f90783a3dbb
--- /dev/null
+++ b/source/blender/blenkernel/intern/mesh_render.c
@@ -0,0 +1,619 @@
+/*
+ * ***** 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.
+ *
+ * Contributor(s): Blender Foundation, Mike Erwin, Dalai Felinto
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file blender/blenkernel/intern/mesh_render.c
+ * \ingroup bke
+ *
+ * \brief Mesh API for render engines
+ */
+
+#include "MEM_guardedalloc.h"
+
+#include "DNA_mesh_types.h"
+#include "DNA_meshdata_types.h"
+
+#include "BKE_customdata.h"
+#include "BKE_depsgraph.h"
+#include "BKE_DerivedMesh.h"
+#include "BKE_editmesh.h"
+#include "BKE_mesh.h"
+#include "BKE_mesh_render.h"
+
+#include "GPU_batch.h"
+
+/* ---------------------------------------------------------------------- */
+/* Mesh Interface */
+
+#define MESH_RENDER_FUNCTION(func_name) \
+ if (me->edit_btmesh) { \
+ return mesh_bmesh_##func_name(me); \
+ } \
+ else { \
+ return mesh_struct_##func_name(me); \
+ }
+
+
+/* Mesh Implementation */
+
+static int mesh_struct_get_num_edges(Mesh *me)
+{
+ return me->totedge;
+}
+
+static int mesh_struct_get_num_verts(Mesh *me)
+{
+ return me->totvert;
+}
+
+static int mesh_struct_get_num_faces(Mesh *me)
+{
+ BKE_mesh_tessface_ensure(me);
+ return me->totface;
+}
+
+static int mesh_struct_get_num_polys(Mesh *me)
+{
+ return me->totpoly;
+}
+
+static MEdge *mesh_struct_get_array_edge(Mesh *me)
+{
+ return CustomData_get_layer(&me->edata, CD_MEDGE);
+}
+
+static MFace *mesh_struct_get_array_face(Mesh *me)
+{
+ BKE_mesh_tessface_ensure(me);
+ return CustomData_get_layer(&me->fdata, CD_MFACE);
+}
+
+static MLoop *mesh_struct_get_array_loop(Mesh *me)
+{
+ return me->mloop;
+}
+
+static MPoly *mesh_struct_get_array_poly(Mesh *me)
+{
+ return me->mpoly;
+}
+
+static MVert *mesh_struct_get_array_vert(Mesh *me)
+{
+ return CustomData_get_layer(&me->vdata, CD_MVERT);
+}
+
+/* BMesh Implementation */
+
+/* NOTE: we may want to get rid of Derived Mesh and
+ * access BMesh directly */
+
+static int mesh_bmesh_get_num_verts(Mesh *me)
+{
+ BMEditMesh *bm = me->edit_btmesh;
+ DerivedMesh *dm = bm->derivedFinal;
+ return dm->getNumVerts(dm);
+}
+
+static int mesh_bmesh_get_num_edges(Mesh *me)
+{
+ BMEditMesh *bm = me->edit_btmesh;
+ DerivedMesh *dm = bm->derivedFinal;
+ return dm->getNumEdges(dm);
+}
+
+static int mesh_bmesh_get_num_faces(Mesh *me)
+{
+ BMEditMesh *bm = me->edit_btmesh;
+ DerivedMesh *dm = bm->derivedFinal;
+ return dm->getNumTessFaces(dm);
+}
+
+static int mesh_bmesh_get_num_polys(Mesh *me)
+{
+ BMEditMesh *bm = me->edit_btmesh;
+ DerivedMesh *dm = bm->derivedFinal;
+ return dm->getNumPolys(dm);
+}
+
+static MEdge *mesh_bmesh_get_array_edge(Mesh *me)
+{
+ BMEditMesh *bm = me->edit_btmesh;
+ DerivedMesh *dm = bm->derivedFinal;
+ return dm->getEdgeArray(dm);
+}
+
+static MFace *mesh_bmesh_get_array_face(Mesh *me)
+{
+ BMEditMesh *bm = me->edit_btmesh;
+ DerivedMesh *dm = bm->derivedFinal;
+ return dm->getTessFaceArray(dm);
+}
+
+static MLoop *mesh_bmesh_get_array_loop(Mesh *me)
+{
+ BMEditMesh *bm = me->edit_btmesh;
+ DerivedMesh *dm = bm->derivedFinal;
+ return dm->getLoopArray(dm);
+}
+
+static MPoly *mesh_bmesh_get_array_poly(Mesh *me)
+{
+ BMEditMesh *bm = me->edit_btmesh;
+ DerivedMesh *dm = bm->derivedFinal;
+ return dm->getPolyArray(dm);
+}
+
+static MVert *mesh_bmesh_get_array_vert(Mesh *me)
+{
+ BMEditMesh *bm = me->edit_btmesh;
+ DerivedMesh *dm = bm->derivedFinal;
+ return dm->getVertArray(dm);
+}
+
+/* Mesh API */
+
+static int mesh_render_get_num_edges(Mesh *me)
+{
+ MESH_RENDER_FUNCTION(get_num_edges);
+}
+
+static int mesh_render_get_num_faces(Mesh *me)
+{
+ MESH_RENDER_FUNCTION(get_num_faces);
+}
+
+static int mesh_render_get_num_polys(Mesh *me)
+{
+ MESH_RENDER_FUNCTION(get_num_polys);
+}
+
+static int mesh_render_get_num_verts(Mesh *me)
+{
+ MESH_RENDER_FUNCTION(get_num_verts);
+}
+
+static MEdge *mesh_render_get_array_edge(Mesh *me)
+{
+ MESH_RENDER_FUNCTION(get_array_edge);
+}
+
+static MFace *mesh_render_get_array_face(Mesh *me)
+{
+ MESH_RENDER_FUNCTION(get_array_face);
+}
+
+static MLoop *mesh_render_get_array_loop(Mesh *me)
+{
+ MESH_RENDER_FUNCTION(get_array_loop);
+}
+
+static MPoly *mesh_render_get_array_poly(Mesh *me)
+{
+ MESH_RENDER_FUNCTION(get_array_poly);
+}
+
+static MVert *mesh_render_get_array_vert(Mesh *me)
+{
+ MESH_RENDER_FUNCTION(get_array_vert);
+}
+
+/* ---------------------------------------------------------------------- */
+/* Mesh Batch Cache */
+
+typedef struct MeshBatchCache {
+ VertexBuffer *pos_in_order;
+ ElementList *edges_in_order;
+ ElementList *triangles_in_order;
+
+ Batch *all_verts;
+ Batch *all_edges;
+ Batch *all_triangles;
+
+ Batch *fancy_edges; /* owns its vertex buffer (not shared) */
+ Batch *overlay_edges; /* owns its vertex buffer */
+
+ /* TODO: settings, before DEPSGRAPH update */
+ int tot_edges;
+ int tot_faces;
+ int tot_polys;
+ int tot_verts;
+ bool is_editmode;
+} MeshBatchCache;
+
+static bool mesh_batch_cache_valid(Mesh *me)
+{
+ MeshBatchCache *cache = me->batch_cache;
+
+ if (cache == NULL) {
+ return false;
+ }
+
+ if (cache->is_editmode != (me->edit_btmesh != NULL)) {
+ return false;
+ }
+
+ if (cache->is_editmode) {
+ DerivedMesh *dm = me->edit_btmesh->derivedFinal;
+ if ((dm->dirty & DM_MESH_BATCH_CACHE) == 0) {
+ return false;
+ }
+ }
+
+ /* TODO: temporary check, waiting for depsgraph update */
+ if ((cache->tot_edges != mesh_render_get_num_edges(me)) ||
+ (cache->tot_faces != mesh_render_get_num_faces(me)) ||
+ (cache->tot_polys != mesh_render_get_num_polys(me)) ||
+ (cache->tot_verts != mesh_render_get_num_verts(me)))
+ {
+ return false;
+ }
+
+ return true;
+}
+
+static void mesh_batch_cache_init(Mesh *me)
+{
+ MeshBatchCache *cache = me->batch_cache;
+ cache->is_editmode = me->edit_btmesh != NULL;
+
+ cache->tot_edges = mesh_render_get_num_edges(me);
+ cache->tot_faces = mesh_render_get_num_faces(me);
+ cache->tot_polys = mesh_render_get_num_polys(me);
+ cache->tot_verts = mesh_render_get_num_verts(me);
+
+ if (cache->is_editmode) {
+ DerivedMesh *dm = me->edit_btmesh->derivedFinal;
+ dm->dirty |= DM_MESH_BATCH_CACHE;
+ }
+}
+
+static MeshBatchCache *mesh_batch_cache_get(Mesh *me)
+{
+ if (!mesh_batch_cache_valid(me)) {
+ BKE_mesh_batch_cache_free(me);
+ me->batch_cache = MEM_callocN(sizeof(MeshBatchCache), "MeshBatchCache");
+ mesh_batch_cache_init(me);
+ }
+ return me->batch_cache;
+}
+
+static VertexBuffer *mesh_batch_cache_get_pos_in_order(Mesh *me)
+{
+ MeshBatchCache *cache = mesh_batch_cache_get(me);
+
+ if (cache->pos_in_order == NULL) {
+ static VertexFormat format = { 0 };
+ static unsigned pos_id;
+ if (format.attrib_ct == 0) {
+ /* initialize vertex format */
+ pos_id = add_attrib(&format, "pos", GL_FLOAT, 3, KEEP_FLOAT);
+ }
+
+ const int vertex_ct = mesh_render_get_num_verts(me);
+ const MVert *verts = mesh_render_get_array_vert(me);
+
+ cache->pos_in_order = VertexBuffer_create_with_format(&format);
+ VertexBuffer_allocate_data(cache->pos_in_order, vertex_ct);
+#if 0
+ const unsigned stride = (verts + 1) - verts; /* or sizeof(MVert) */
+ fillAttribStride(cache->pos_in_order, pos_id, stride, &verts[0].co);
+#else
+ for (int i = 0; i < vertex_ct; ++i) {
+ setAttrib(cache->pos_in_order, pos_id, i, &verts[i].co);
+ }
+#endif
+ }
+
+ return cache->pos_in_order;
+}
+
+static ElementList *mesh_batch_cache_get_edges_in_order(Mesh *me)
+{
+ MeshBatchCache *cache = mesh_batch_cache_get(me);
+
+ if (cache->edges_in_order == NULL) {
+ const int vertex_ct = mesh_render_get_num_verts(me);
+ const int edge_ct = mesh_render_get_num_edges(me);
+ const MEdge *edges = mesh_render_get_array_edge(me);
+
+ ElementListBuilder elb;
+ ElementListBuilder_init(&elb, GL_LINES, edge_ct, vertex_ct);
+ for (int i = 0; i < edge_ct; ++i) {
+ const MEdge *edge = edges + i;
+ add_line_vertices(&elb, edge->v1, edge->v2);
+ }
+ cache->edges_in_order = ElementList_build(&elb);
+ }
+
+ return cache->edges_in_order;
+}
+
+static ElementList *mesh_batch_cache_get_triangles_in_order(Mesh *me)
+{
+ MeshBatchCache *cache = mesh_batch_cache_get(me);
+
+ if (cache->triangles_in_order == NULL) {
+ const int vertex_ct = mesh_render_get_num_verts(me);
+ const int tessface_ct = mesh_render_get_num_faces(me);
+ MFace *tessfaces = mesh_render_get_array_face(me);
+
+ ElementListBuilder elb;
+ ElementListBuilder_init(&elb, GL_TRIANGLES, tessface_ct * 2, vertex_ct); /* up to 2 triangles per tessface */
+ for (int i = 0; i < tessface_ct; ++i) {
+ const MFace *tess = tessfaces + i;
+ add_triangle_vertices(&elb, tess->v1, tess->v2, tess->v3);
+
+ if (tess->v4) {
+ add_triangle_vertices(&elb, tess->v1, tess->v3, tess->v4);
+ }
+ }
+ cache->triangles_in_order = ElementList_build(&elb);
+ }
+
+ /* NOTE: we are reallocating, it would be interesting to reallocating the memory once we
+ * know the exactly triangle count (like in BKE_mesh_batch_cache_get_overlay_edges) */
+
+ return cache->triangles_in_order;
+}
+
+void BKE_mesh_batch_cache_free(Mesh *me)
+{
+ MeshBatchCache *cache = me->batch_cache;
+ if (!cache) {
+ return;
+ }
+
+ if (cache->all_verts) Batch_discard(cache->all_verts);
+ if (cache->all_edges) Batch_discard(cache->all_edges);
+ if (cache->all_triangles) Batch_discard(cache->all_triangles);
+
+ if (cache->pos_in_order) VertexBuffer_discard(cache->pos_in_order);
+ if (cache->edges_in_order) ElementList_discard(cache->edges_in_order);
+ if (cache->triangles_in_order) ElementList_discard(cache->triangles_in_order);
+
+ if (cache->fancy_edges) {
+ Batch_discard_all(cache->fancy_edges);
+ }
+
+ if (cache->overlay_edges) {
+ Batch_discard_all(cache->overlay_edges);
+ }
+
+ MEM_freeN(cache);
+ me->batch_cache = NULL;
+}
+
+Batch *BKE_mesh_batch_cache_get_all_edges(Mesh *me)
+{
+ MeshBatchCache *cache = mesh_batch_cache_get(me);
+
+ if (cache->all_edges == NULL) {
+ /* create batch from Mesh */
+ cache->all_edges = Batch_create(GL_LINES, mesh_batch_cache_get_pos_in_order(me), mesh_batch_cache_get_edges_in_order(me));
+ }
+
+ return cache->all_edges;
+}
+
+Batch *BKE_mesh_batch_cache_get_all_triangles(Mesh *me)
+{
+ MeshBatchCache *cache = mesh_batch_cache_get(me);
+
+ if (cache->all_triangles == NULL) {
+ /* create batch from DM */
+ cache->all_triangles = Batch_create(GL_TRIANGLES, mesh_batch_cache_get_pos_in_order(me), mesh_batch_cache_get_triangles_in_order(me));
+ }
+
+ return cache->all_triangles;
+}
+
+Batch *BKE_mesh_batch_cache_get_all_verts(Mesh *me)
+{
+ MeshBatchCache *cache = mesh_batch_cache_get(me);
+
+ if (cache->all_verts == NULL) {
+ /* create batch from DM */
+ cache->all_verts = Batch_create(GL_POINTS, mesh_batch_cache_get_pos_in_order(me), NULL);
+ Batch_set_builtin_program(cache->all_verts, GPU_SHADER_3D_POINT_FIXED_SIZE_UNIFORM_COLOR);
+ }
+
+ return cache->all_verts;
+}
+
+Batch *BKE_mesh_batch_cache_get_fancy_edges(Mesh *me)
+{
+ MeshBatchCache *cache = mesh_batch_cache_get(me);
+
+ if (cache->fancy_edges == NULL) {
+ /* create batch from DM */
+ static VertexFormat format = { 0 };
+ static unsigned pos_id, n1_id, n2_id;
+ if (format.attrib_ct == 0) {
+ /* initialize vertex format */
+ pos_id = add_attrib(&format, "pos", COMP_F32, 3, KEEP_FLOAT);
+
+#if USE_10_10_10 /* takes 1/3 the space */
+ n1_id = add_attrib(&format, "N1", COMP_I10, 3, NORMALIZE_INT_TO_FLOAT);
+ n2_id = add_attrib(&format, "N2", COMP_I10, 3, NORMALIZE_INT_TO_FLOAT);
+#else
+ n1_id = add_attrib(&format, "N1", COMP_F32, 3, KEEP_FLOAT);
+ n2_id = add_attrib(&format, "N2", COMP_F32, 3, KEEP_FLOAT);
+#endif
+ }
+ VertexBuffer *vbo = VertexBuffer_create_with_format(&format);
+
+ const MVert *verts = mesh_render_get_array_vert(me);
+ const MEdge *edges = mesh_render_get_array_edge(me);
+ const MPoly *polys = mesh_render_get_array_poly(me);
+ const MLoop *loops = mesh_render_get_array_loop(me);
+ const int edge_ct = mesh_render_get_num_edges(me);
+ const int poly_ct = mesh_render_get_num_polys(me);
+
+ /* need normal of each face, and which faces are adjacent to each edge */
+ typedef struct {
+ int count;
+ int face_index[2];
+ } AdjacentFaces;
+
+ float (*face_normal)[3] = MEM_mallocN(poly_ct * 3 * sizeof(float), "face_normal");
+ AdjacentFaces *adj_faces = MEM_callocN(edge_ct * sizeof(AdjacentFaces), "adj_faces");
+
+ for (int i = 0; i < poly_ct; ++i) {
+ const MPoly *poly = polys + i;
+
+ BKE_mesh_calc_poly_normal(poly, loops + poly->loopstart, verts, face_normal[i]);
+
+ for (int j = poly->loopstart; j < (poly->loopstart + poly->totloop); ++j) {
+ AdjacentFaces *adj = adj_faces + loops[j].e;
+ if (adj->count < 2)
+ adj->face_index[adj->count] = i;
+ adj->count++;
+ }
+ }
+
+ const int vertex_ct = edge_ct * 2; /* these are GL_LINE verts, not mesh verts */
+ VertexBuffer_allocate_data(vbo, vertex_ct);
+ for (int i = 0; i < edge_ct; ++i) {
+ const MEdge *edge = edges + i;
+ const AdjacentFaces *adj = adj_faces + i;
+
+#if USE_10_10_10
+ PackedNormal n1value = { .x = 0, .y = 0, .z = +511 };
+ PackedNormal n2value = { .x = 0, .y = 0, .z = -511 };
+
+ if (adj->count == 2) {
+ n1value = convert_i10_v3(face_normal[adj->face_index[0]]);
+ n2value = convert_i10_v3(face_normal[adj->face_index[1]]);
+ }
+
+ const PackedNormal *n1 = &n1value;
+ const PackedNormal *n2 = &n2value;
+#else
+ const float dummy1[3] = { 0.0f, 0.0f, +1.0f };
+ const float dummy2[3] = { 0.0f, 0.0f, -1.0f };
+
+ const float *n1 = (adj->count == 2) ? face_normal[adj->face_index[0]] : dummy1;
+ const float *n2 = (adj->count == 2) ? face_normal[adj->face_index[1]] : dummy2;
+#endif
+
+ setAttrib(vbo, pos_id, 2 * i, &verts[edge->v1].co);
+ setAttrib(vbo, n1_id, 2 * i, n1);
+ setAttrib(vbo, n2_id, 2 * i, n2);
+
+ setAttrib(vbo, pos_id, 2 * i + 1, &verts[edge->v2].co);
+ setAttrib(vbo, n1_id, 2 * i + 1, n1);
+ setAttrib(vbo, n2_id, 2 * i + 1, n2);
+ }
+
+ MEM_freeN(adj_faces);
+ MEM_freeN(face_normal);
+
+ cache->fancy_edges = Batch_create(GL_LINES, vbo, NULL);
+ }
+
+ return cache->fancy_edges;
+}
+
+static bool edge_is_real(const MEdge *edges, int edge_ct, int v1, int v2)
+{
+ /* TODO: same thing, except not ridiculously slow */
+
+ for (int e = 0; e < edge_ct; ++e) {
+ const MEdge *edge = edges + e;
+ if ((edge->v1 == v1 && edge->v2 == v2) || (edge->v1 == v2 && edge->v2 == v1)) {
+ return true;
+ }
+ }
+
+ return false;
+}
+
+static void add_overlay_tri(
+ VertexBuffer *vbo, unsigned pos_id, unsigned edgeMod_id, const MVert *verts,
+ const MEdge *edges, int edge_ct, int v1, int v2, int v3, int base_vert_idx)
+{
+ const float edgeMods[2] = { 0.0f, 1.0f };
+
+ const float *pos = verts[v1].co;
+ setAttrib(vbo, pos_id, base_vert_idx + 0, pos);
+ setAttrib(vbo, edgeMod_id, base_vert_idx + 0, edgeMods + (edge_is_real(edges, edge_ct, v2, v3) ? 1 : 0));
+
+ pos = verts[v2].co;
+ setAttrib(vbo, pos_id, base_vert_idx + 1, pos);
+ setAttrib(vbo, edgeMod_id, base_vert_idx + 1, edgeMods + (edge_is_real(edges, edge_ct, v3, v1) ? 1 : 0));
+
+ pos = verts[v3].co;
+ setAttrib(vbo, pos_id, base_vert_idx + 2, pos);
+ setAttrib(vbo, edgeMod_id, base_vert_idx + 2, edgeMods + (edge_is_real(edges, edge_ct, v1, v2) ? 1 : 0));
+}
+
+Batch *BKE_mesh_batch_cache_get_overlay_edges(Mesh *me)
+{
+ MeshBatchCache *cache = mesh_batch_cache_get(me);
+
+ if (cache->overlay_edges == NULL) {
+ /* create batch from DM */
+ static VertexFormat format = { 0 };
+ static unsigned pos_id, edgeMod_id;
+
+ if (format.attrib_ct == 0) {
+ /* initialize vertex format */
+ pos_id = add_attrib(&format, "pos", GL_FLOAT, 3, KEEP_FLOAT);
+ edgeMod_id = add_attrib(&format, "edgeWidthModulator", GL_FLOAT, 1, KEEP_FLOAT);
+ }
+ VertexBuffer *vbo = VertexBuffer_create_with_format(&format);
+
+ const int edge_ct = mesh_render_get_num_edges(me);
+ const int tessface_ct = mesh_render_get_num_faces(me);
+ const MVert *verts = mesh_render_get_array_vert(me);
+ const MEdge *edges = mesh_render_get_array_edge(me);
+ const MFace *tessfaces = mesh_render_get_array_face(me);
+
+ VertexBuffer_allocate_data(vbo, tessface_ct * 6); /* up to 2 triangles per tessface */
+
+ int gpu_vert_idx = 0;
+ for (int i = 0; i < tessface_ct; ++i) {
+ const MFace *tess = tessfaces + i;
+ add_overlay_tri(vbo, pos_id, edgeMod_id, verts, edges, edge_ct, tess->v1, tess->v2, tess->v3, gpu_vert_idx);
+ gpu_vert_idx += 3;
+ /* tessface can be triangle or quad */
+ if (tess->v4) {
+ add_overlay_tri(vbo, pos_id, edgeMod_id, verts, edges, edge_ct, tess->v3, tess->v2, tess->v4, gpu_vert_idx);
+ gpu_vert_idx += 3;
+ }
+ }
+
+ /* in some cases all the faces are quad, so no need to reallocate */
+ if (vbo->vertex_ct != gpu_vert_idx) {
+ VertexBuffer_resize_data(vbo, gpu_vert_idx);
+ }
+
+ cache->overlay_edges = Batch_create(GL_TRIANGLES, vbo, NULL);
+ }
+
+ return cache->overlay_edges;
+}
+
+#undef MESH_RENDER_FUNCTION
diff --git a/source/blender/editors/space_view3d/drawobject.c b/source/blender/editors/space_view3d/drawobject.c
index b00a7346e59..1692d3a7372 100644
--- a/source/blender/editors/space_view3d/drawobject.c
+++ b/source/blender/editors/space_view3d/drawobject.c
@@ -65,6 +65,7 @@
#include "BKE_lattice.h"
#include "BKE_main.h"
#include "BKE_mesh.h"
+#include "BKE_mesh_render.h"
#include "BKE_material.h"
#include "BKE_mball.h"
#include "BKE_modifier.h"
@@ -214,340 +215,6 @@ typedef struct drawBMSelect_userData {
bool select;
} drawBMSelect_userData;
-typedef struct {
- VertexBuffer *pos_in_order;
- ElementList *edges_in_order;
- ElementList *triangles_in_order;
-
- Batch *all_verts;
- Batch *all_edges;
- Batch *all_triangles;
-
- Batch *fancy_edges; /* owns its vertex buffer (not shared) */
- Batch *overlay_edges; /* owns its vertex buffer */
-} MeshBatchCache;
-
-static void MBC_discard(MeshBatchCache *cache)
-{
- if (cache->all_verts) Batch_discard(cache->all_verts);
- if (cache->all_edges) Batch_discard(cache->all_edges);
- if (cache->all_triangles) Batch_discard(cache->all_triangles);
-
- if (cache->pos_in_order) VertexBuffer_discard(cache->pos_in_order);
- if (cache->edges_in_order) ElementList_discard(cache->edges_in_order);
- if (cache->triangles_in_order) ElementList_discard(cache->triangles_in_order);
-
- if (cache->fancy_edges) {
- Batch_discard_all(cache->fancy_edges);
- }
-
- if (cache->overlay_edges) {
- Batch_discard_all(cache->overlay_edges);
- }
-
- MEM_freeN(cache);
-}
-
-static MeshBatchCache *MBC_get(DerivedMesh *dm)
-{
- if (dm->batchCache == NULL) {
- /* create cache */
- dm->batchCache = MEM_callocN(sizeof(MeshBatchCache), "MeshBatchCache");
- /* init everything to 0 is ok for now */
-
-
- /* tell DerivedMesh how to clean up these caches (just once) */
- /* TODO: find a better place for this w/out exposing internals to DM */
- /* TODO (long term): replace DM with something less messy */
- static bool first = true;
- if (first) {
- DM_set_batch_cleanup_callback((DMCleanupBatchCache)MBC_discard);
- first = false;
- }
- }
-
- return dm->batchCache;
-}
-
-static VertexBuffer *MBC_get_pos_in_order(DerivedMesh *dm)
-{
- MeshBatchCache *cache = MBC_get(dm);
-
- if (cache->pos_in_order == NULL) {
- static VertexFormat format = { 0 };
- static unsigned pos_id;
- if (format.attrib_ct == 0) {
- /* initialize vertex format */
- pos_id = add_attrib(&format, "pos", GL_FLOAT, 3, KEEP_FLOAT);
- }
-
- const int vertex_ct = dm->getNumVerts(dm);
- const MVert *verts = dm->getVertArray(dm);
- const unsigned stride = (verts + 1) - verts; /* or sizeof(MVert) */
-
- cache->pos_in_order = VertexBuffer_create_with_format(&format);
- VertexBuffer_allocate_data(cache->pos_in_order, vertex_ct);
-#if 0
- fillAttribStride(cache->pos_in_order, pos_id, stride, &verts[0].co);
-#else
- for (int i = 0; i < vertex_ct; ++i) {
- setAttrib(cache->pos_in_order, pos_id, i, &verts[i].co);
- }
-#endif
- }
-
- return cache->pos_in_order;
-}
-
-static Batch *MBC_get_all_verts(DerivedMesh *dm)
-{
- MeshBatchCache *cache = MBC_get(dm);
-
- if (cache->all_verts == NULL) {
- /* create batch from DM */
- cache->all_verts = Batch_create(GL_POINTS, MBC_get_pos_in_order(dm), NULL);
- Batch_set_builtin_program(cache->all_verts, GPU_SHADER_3D_POINT_FIXED_SIZE_UNIFORM_COLOR);
- }
-
- return cache->all_verts;
-}
-
-static ElementList *MBC_get_edges_in_order(DerivedMesh *dm)
-{
- MeshBatchCache *cache = MBC_get(dm);
-
- if (cache->edges_in_order == NULL) {
- const int vertex_ct = dm->getNumVerts(dm);
- const int edge_ct = dm->getNumEdges(dm);
- const MEdge *edges = dm->getEdgeArray(dm);
- ElementListBuilder elb;
- ElementListBuilder_init(&elb, GL_LINES, edge_ct, vertex_ct);
- for (int i = 0; i < edge_ct; ++i) {
- const MEdge *edge = edges + i;
- add_line_vertices(&elb, edge->v1, edge->v2);
- }
- cache->edges_in_order = ElementList_build(&elb);
- }
-
- return cache->edges_in_order;
-}
-
-static ElementList *MBC_get_triangles_in_order(DerivedMesh *dm)
-{
- MeshBatchCache *cache = MBC_get(dm);
-
- if (cache->triangles_in_order == NULL) {
- const int vertex_ct = dm->getNumVerts(dm);
- const int tessface_ct = dm->getNumTessFaces(dm);
- const MFace *tessfaces = dm->getTessFaceArray(dm);
- ElementListBuilder elb;
- ElementListBuilder_init(&elb, GL_TRIANGLES, tessface_ct, vertex_ct);
- for (int i = 0; i < tessface_ct; ++i) {
- const MFace *tess = tessfaces + i;
- add_triangle_vertices(&elb, tess->v1, tess->v2, tess->v3);
- /* tessface can be triangle or quad */
- if (tess->v4) {
- add_triangle_vertices(&elb, tess->v3, tess->v2, tess->v4);
- }
- }
- cache->triangles_in_order = ElementList_build(&elb);
- }
-
- return cache->triangles_in_order;
-}
-
-static Batch *MBC_get_all_edges(DerivedMesh *dm)
-{
- MeshBatchCache *cache = MBC_get(dm);
-
- if (cache->all_edges == NULL) {
- /* create batch from DM */
- cache->all_edges = Batch_create(GL_LINES, MBC_get_pos_in_order(dm), MBC_get_edges_in_order(dm));
- }
-
- return cache->all_edges;
-}
-
-static Batch *MBC_get_all_triangles(DerivedMesh *dm)
-{
- MeshBatchCache *cache = MBC_get(dm);
-
- if (cache->all_triangles == NULL) {
- /* create batch from DM */
- cache->all_triangles = Batch_create(GL_TRIANGLES, MBC_get_pos_in_order(dm), MBC_get_triangles_in_order(dm));
- }
-
- return cache->all_triangles;
-}
-
-static Batch *MBC_get_fancy_edges(DerivedMesh *dm)
-{
- MeshBatchCache *cache = MBC_get(dm);
-
- if (cache->fancy_edges == NULL) {
- /* create batch from DM */
- static VertexFormat format = { 0 };
- static unsigned pos_id, n1_id, n2_id;
- if (format.attrib_ct == 0) {
- /* initialize vertex format */
- pos_id = add_attrib(&format, "pos", COMP_F32, 3, KEEP_FLOAT);
-
-#if USE_10_10_10 /* takes 1/3 the space */
- n1_id = add_attrib(&format, "N1", COMP_I10, 3, NORMALIZE_INT_TO_FLOAT);
- n2_id = add_attrib(&format, "N2", COMP_I10, 3, NORMALIZE_INT_TO_FLOAT);
-#else
- n1_id = add_attrib(&format, "N1", COMP_F32, 3, KEEP_FLOAT);
- n2_id = add_attrib(&format, "N2", COMP_F32, 3, KEEP_FLOAT);
-#endif
- }
- VertexBuffer *vbo = VertexBuffer_create_with_format(&format);
-
- const MVert *verts = dm->getVertArray(dm);
- const MEdge *edges = dm->getEdgeArray(dm);
- const MPoly *polys = dm->getPolyArray(dm);
- const MLoop *loops = dm->getLoopArray(dm);
- const int edge_ct = dm->getNumEdges(dm);
- const int poly_ct = dm->getNumPolys(dm);
-
- /* need normal of each face, and which faces are adjacent to each edge */
- typedef struct {
- int count;
- int face_index[2];
- } AdjacentFaces;
-
- float (*face_normal)[3] = MEM_mallocN(poly_ct * 3 * sizeof(float), "face_normal");
- AdjacentFaces *adj_faces = MEM_callocN(edge_ct * sizeof(AdjacentFaces), "adj_faces");
-
- for (int i = 0; i < poly_ct; ++i) {
- const MPoly *poly = polys + i;
-
- BKE_mesh_calc_poly_normal(poly, loops + poly->loopstart, verts, face_normal[i]);
-
- for (int j = poly->loopstart; j < (poly->loopstart + poly->totloop); ++j) {
- AdjacentFaces *adj = adj_faces + loops[j].e;
- if (adj->count < 2)
- adj->face_index[adj->count] = i;
- adj->count++;
- }
- }
-
- const int vertex_ct = edge_ct * 2; /* these are GL_LINE verts, not mesh verts */
- VertexBuffer_allocate_data(vbo, vertex_ct);
- for (int i = 0; i < edge_ct; ++i) {
- const MEdge *edge = edges + i;
- const AdjacentFaces *adj = adj_faces + i;
-
-#if USE_10_10_10
- PackedNormal n1value = { .x = 0, .y = 0, .z = +511 };
- PackedNormal n2value = { .x = 0, .y = 0, .z = -511 };
-
- if (adj->count == 2) {
- n1value = convert_i10_v3(face_normal[adj->face_index[0]]);
- n2value = convert_i10_v3(face_normal[adj->face_index[1]]);
- }
-
- const PackedNormal *n1 = &n1value;
- const PackedNormal *n2 = &n2value;
-#else
- const float dummy1[3] = { 0.0f, 0.0f, +1.0f };
- const float dummy2[3] = { 0.0f, 0.0f, -1.0f };
-
- const float *n1 = (adj->count == 2) ? face_normal[adj->face_index[0]] : dummy1;
- const float *n2 = (adj->count == 2) ? face_normal[adj->face_index[1]] : dummy2;
-#endif
-
- setAttrib(vbo, pos_id, 2 * i, &verts[edge->v1].co);
- setAttrib(vbo, n1_id, 2 * i, n1);
- setAttrib(vbo, n2_id, 2 * i, n2);
-
- setAttrib(vbo, pos_id, 2 * i + 1, &verts[edge->v2].co);
- setAttrib(vbo, n1_id, 2 * i + 1, n1);
- setAttrib(vbo, n2_id, 2 * i + 1, n2);
- }
-
- MEM_freeN(adj_faces);
- MEM_freeN(face_normal);
-
- cache->fancy_edges = Batch_create(GL_LINES, vbo, NULL);
- }
-
- return cache->fancy_edges;
-}
-
-static bool edge_is_real(const MEdge *edges, int edge_ct, int v1, int v2)
-{
- /* TODO: same thing, except not ridiculously slow */
-
- for (int e = 0; e < edge_ct; ++e) {
- const MEdge *edge = edges + e;
- if ((edge->v1 == v1 && edge->v2 == v2) || (edge->v1 == v2 && edge->v2 == v1)) {
- return true;
- }
- }
-
- return false;
-}
-
-static void add_overlay_tri(VertexBuffer *vbo, unsigned pos_id, unsigned edgeMod_id, const MVert *verts, const MEdge *edges, int edge_ct, int v1, int v2, int v3, int base_vert_idx)
-{
- const float edgeMods[2] = { 0.0f, 1.0f };
-
- const float *pos = verts[v1].co;
- setAttrib(vbo, pos_id, base_vert_idx + 0, pos);
- setAttrib(vbo, edgeMod_id, base_vert_idx + 0, edgeMods + (edge_is_real(edges, edge_ct, v2, v3) ? 1 : 0));
-
- pos = verts[v2].co;
- setAttrib(vbo, pos_id, base_vert_idx + 1, pos);
- setAttrib(vbo, edgeMod_id, base_vert_idx + 1, edgeMods + (edge_is_real(edges, edge_ct, v3, v1) ? 1 : 0));
-
- pos = verts[v3].co;
- setAttrib(vbo, pos_id, base_vert_idx + 2, pos);
- setAttrib(vbo, edgeMod_id, base_vert_idx + 2, edgeMods + (edge_is_real(edges, edge_ct, v1, v2) ? 1 : 0));
-}
-
-static Batch *MBC_get_overlay_edges(DerivedMesh *dm)
-{
- MeshBatchCache *cache = MBC_get(dm);
-
- if (cache->overlay_edges == NULL) {
- /* create batch from DM */
- static VertexFormat format = { 0 };
- static unsigned pos_id, edgeMod_id;
- if (format.attrib_ct == 0) {
- /* initialize vertex format */
- pos_id = add_attrib(&format, "pos", GL_FLOAT, 3, KEEP_FLOAT);
- edgeMod_id = add_attrib(&format, "edgeWidthModulator", GL_FLOAT, 1, KEEP_FLOAT);
- }
- VertexBuffer *vbo = VertexBuffer_create_with_format(&format);
-
- const int vertex_ct = dm->getNumVerts(dm);
- const int edge_ct = dm->getNumEdges(dm);
- const int tessface_ct = dm->getNumTessFaces(dm);
- const MVert *verts = dm->getVertArray(dm);
- const MEdge *edges = dm->getEdgeArray(dm);
- const MFace *tessfaces = dm->getTessFaceArray(dm);
-
- VertexBuffer_allocate_data(vbo, tessface_ct * 6); /* up to 2 triangles per tessface */
-
- int gpu_vert_idx = 0;
- for (int i = 0; i < tessface_ct; ++i) {
- const MFace *tess = tessfaces + i;
- add_overlay_tri(vbo, pos_id, edgeMod_id, verts, edges, edge_ct, tess->v1, tess->v2, tess->v3, gpu_vert_idx);
- gpu_vert_idx += 3;
- /* tessface can be triangle or quad */
- if (tess->v4) {
- add_overlay_tri(vbo, pos_id, edgeMod_id, verts, edges, edge_ct, tess->v3, tess->v2, tess->v4, gpu_vert_idx);
- gpu_vert_idx += 3;
- }
- }
-
- VertexBuffer_resize_data(vbo, gpu_vert_idx);
-
- cache->overlay_edges = Batch_create(GL_TRIANGLES, vbo, NULL);
- }
-
- return cache->overlay_edges;
-}
static void drawcube_size(float size, unsigned pos);
static void drawcircle_size(float size, unsigned pos);
@@ -4370,11 +4037,10 @@ static void draw_em_fancy(Scene *scene, ARegion *ar, View3D *v3d,
}
static void draw_em_fancy_new(Scene *UNUSED(scene), ARegion *ar, View3D *UNUSED(v3d),
- Object *UNUSED(ob), BMEditMesh *UNUSED(em), DerivedMesh *cageDM, DerivedMesh *UNUSED(finalDM), const char UNUSED(dt))
+ Object *UNUSED(ob), Mesh *me, BMEditMesh *UNUSED(em), DerivedMesh *UNUSED(cageDM), DerivedMesh *UNUSED(finalDM), const char UNUSED(dt))
{
/* for now... something simple! */
-
- Batch *surface = MBC_get_all_triangles(cageDM);
+ Batch *surface = BKE_mesh_batch_cache_get_all_triangles(me);
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LEQUAL);
@@ -4408,7 +4074,7 @@ static void draw_em_fancy_new(Scene *UNUSED(scene), ARegion *ar, View3D *UNUSED(
Batch_draw(surface);
if (GLEW_VERSION_3_2) {
- Batch *overlay = MBC_get_overlay_edges(cageDM);
+ Batch *overlay = BKE_mesh_batch_cache_get_overlay_edges(me);
Batch_set_builtin_program(overlay, GPU_SHADER_EDGES_OVERLAY);
Batch_Uniform2f(overlay, "viewportSize", ar->winx, ar->winy);
Batch_draw(overlay);
@@ -4426,7 +4092,7 @@ static void draw_em_fancy_new(Scene *UNUSED(scene), ARegion *ar, View3D *UNUSED(
#endif
}
else {
- Batch *edges = MBC_get_all_edges(cageDM);
+ Batch *edges = BKE_mesh_batch_cache_get_all_edges(me);
Batch_set_builtin_program(edges, GPU_SHADER_3D_UNIFORM_COLOR);
Batch_Uniform4f(edges, "color", 0.0f, 0.0f, 0.0f, 1.0f);
glEnable(GL_LINE_SMOOTH);
@@ -4436,7 +4102,7 @@ static void draw_em_fancy_new(Scene *UNUSED(scene), ARegion *ar, View3D *UNUSED(
}
#if 0 /* looks good even without points */
- Batch *verts = MBC_get_all_verts(cageDM);
+ Batch *verts = MBC_get_all_verts(me);
glEnable(GL_BLEND);
Batch_set_builtin_program(verts, GPU_SHADER_3D_POINT_UNIFORM_SIZE_UNIFORM_COLOR_SMOOTH);
@@ -4474,7 +4140,7 @@ void draw_mesh_object_outline(View3D *v3d, Object *ob, DerivedMesh *dm) /* LEGAC
}
}
-static void draw_mesh_object_outline_new(View3D *v3d, RegionView3D *rv3d, Object *ob, DerivedMesh *dm, const bool is_active)
+static void draw_mesh_object_outline_new(View3D *v3d, RegionView3D *rv3d, Object *ob, Mesh *me, const bool is_active)
{
if ((v3d->transp == false) && /* not when we draw the transparent pass */
(ob->mode & OB_MODE_ALL_PAINT) == false) /* not when painting (its distracting) - campbell */
@@ -4486,7 +4152,7 @@ static void draw_mesh_object_outline_new(View3D *v3d, RegionView3D *rv3d, Object
UI_GetThemeColor4fv((is_active ? TH_ACTIVE : TH_SELECT), outline_color);
#if 1 /* new version that draws only silhouette edges */
- Batch *fancy_edges = MBC_get_fancy_edges(dm);
+ Batch *fancy_edges = BKE_mesh_batch_cache_get_fancy_edges(me);
if (rv3d->persp == RV3D_ORTHO) {
Batch_set_builtin_program(fancy_edges, GPU_SHADER_EDGES_FRONT_BACK_ORTHO);
@@ -5009,7 +4675,7 @@ static void draw_mesh_fancy_new(Scene *scene, ARegion *ar, View3D *v3d, RegionVi
#if 1 /* fancy wireframes */
- Batch *fancy_edges = MBC_get_fancy_edges(dm);
+ Batch *fancy_edges = BKE_mesh_batch_cache_get_fancy_edges(me);
if (rv3d->persp == RV3D_ORTHO) {
Batch_set_builtin_program(fancy_edges, GPU_SHADER_EDGES_FRONT_BACK_ORTHO);
@@ -5069,7 +4735,7 @@ static void draw_mesh_fancy_new(Scene *scene, ARegion *ar, View3D *v3d, RegionVi
!(G.f & G_PICKSEL || (draw_flags & DRAW_FACE_SELECT)) &&
(draw_wire == OBDRAW_WIRE_OFF))
{
- draw_mesh_object_outline_new(v3d, rv3d, ob, dm, (ob == OBACT));
+ draw_mesh_object_outline_new(v3d, rv3d, ob, me, (ob == OBACT));
}
if (draw_glsl_material(scene, ob, v3d, dt) && !(draw_flags & DRAW_MODIFIERS_PREVIEW)) {
@@ -5136,7 +4802,7 @@ static void draw_mesh_fancy_new(Scene *scene, ARegion *ar, View3D *v3d, RegionVi
(draw_wire == OBDRAW_WIRE_OFF) &&
(ob->sculpt == NULL))
{
- draw_mesh_object_outline_new(v3d, rv3d, ob, dm, (ob == OBACT));
+ draw_mesh_object_outline_new(v3d, rv3d, ob, me, (ob == OBACT));
}
/* materials arent compatible with vertex colors */
@@ -5161,7 +4827,7 @@ static void draw_mesh_fancy_new(Scene *scene, ARegion *ar, View3D *v3d, RegionVi
(ob->sculpt == NULL))
{
/* TODO: move this into a separate pass */
- draw_mesh_object_outline_new(v3d, rv3d, ob, dm, (ob == OBACT));
+ draw_mesh_object_outline_new(v3d, rv3d, ob, me, (ob == OBACT));
}
glFrontFace((ob->transflag & OB_NEG_SCALE) ? GL_CW : GL_CCW);
@@ -5310,7 +4976,7 @@ static bool draw_mesh_object_new(Scene *scene, ARegion *ar, View3D *v3d, RegionV
GPU_begin_object_materials(v3d, rv3d, scene, ob, glsl, NULL);
}
- draw_em_fancy_new(scene, ar, v3d, ob, em, cageDM, finalDM, dt);
+ draw_em_fancy_new(scene, ar, v3d, ob, me, em, cageDM, finalDM, dt);
if (use_material) {
GPU_end_object_materials();
diff --git a/source/blender/gpu/gawain/batch.h b/source/blender/gpu/gawain/batch.h
index c2768377a96..932ee182703 100644
--- a/source/blender/gpu/gawain/batch.h
+++ b/source/blender/gpu/gawain/batch.h
@@ -21,7 +21,7 @@ typedef enum {
READY_TO_DRAW
} BatchPhase;
-typedef struct {
+typedef struct Batch{
// geometry
VertexBuffer* verts;
ElementList* elem; // NULL if element list not needed
diff --git a/source/blender/makesdna/DNA_mesh_types.h b/source/blender/makesdna/DNA_mesh_types.h
index 39e56925903..15ea3d4d37a 100644
--- a/source/blender/makesdna/DNA_mesh_types.h
+++ b/source/blender/makesdna/DNA_mesh_types.h
@@ -127,6 +127,7 @@ typedef struct Mesh {
short totcol;
struct Multires *mr DNA_DEPRECATED; /* deprecated multiresolution modeling data, only keep for loading old files */
+ void *batch_cache;
} Mesh;
/* deprecated by MTFace, only here for file reading */