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:
-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 */