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/editors
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/editors')
-rw-r--r--source/blender/editors/space_view3d/drawobject.c360
1 files changed, 13 insertions, 347 deletions
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();