[Bf-blender-cvs] [0b83680] blender2.8: OpenGL: support for edge overlays
Mike Erwin
noreply at git.blender.org
Tue Nov 8 05:41:16 CET 2016
Commit: 0b83680d85a7e39105c94888005030538440a0a6
Author: Mike Erwin
Date: Tue Nov 8 05:06:09 2016 +0100
Branches: blender2.8
https://developer.blender.org/rB0b83680d85a7e39105c94888005030538440a0a6
OpenGL: support for edge overlays
Has some obvious opportunities for improvement. This is my second attempt. First attempt used MLoopTri and sort of worked...
===================================================================
M source/blender/editors/space_view3d/drawobject.c
===================================================================
diff --git a/source/blender/editors/space_view3d/drawobject.c b/source/blender/editors/space_view3d/drawobject.c
index bf48de3..8be3352 100644
--- a/source/blender/editors/space_view3d/drawobject.c
+++ b/source/blender/editors/space_view3d/drawobject.c
@@ -222,6 +222,7 @@ typedef struct {
Batch *all_triangles;
Batch *fancy_edges; /* owns its vertex buffer (not shared) */
+ Batch *overlay_edges; /* owns its vertex buffer */
} MeshBatchCache;
static MeshBatchCache *MBC_get(DerivedMesh *dm)
@@ -248,6 +249,10 @@ static void MBC_discard(MeshBatchCache *cache)
if (cache->fancy_edges) {
Batch_discard_all(cache->fancy_edges);
}
+
+ if (cache->overlay_edges) {
+ Batch_discard_all(cache->overlay_edges);
+ }
}
/* need to set this as DM callback:
* DM_set_batch_cleanup_callback((DMCleanupBatchCache)MBC_discard);
@@ -437,6 +442,81 @@ static Batch *MBC_get_fancy_edges(DerivedMesh *dm)
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);
static void draw_empty_sphere(float size, unsigned pos);
More information about the Bf-blender-cvs
mailing list