Merge branch 'blender2.7'
[blender.git] / source / blender / gpu / intern / gpu_buffers.c
1 /*
2  * ***** BEGIN GPL LICENSE BLOCK *****
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License
6  * as published by the Free Software Foundation; either version 2
7  * of the License, or (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software Foundation,
16  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17  *
18  * The Original Code is Copyright (C) 2005 Blender Foundation.
19  * All rights reserved.
20  *
21  * The Original Code is: all of this file.
22  *
23  * Contributor(s): Brecht Van Lommel.
24  *
25  * ***** END GPL LICENSE BLOCK *****
26  */
27
28 /** \file blender/gpu/intern/gpu_buffers.c
29  *  \ingroup gpu
30  *
31  * Mesh drawing using OpenGL VBO (Vertex Buffer Objects)
32  */
33
34 #include <limits.h>
35 #include <stddef.h>
36 #include <string.h>
37
38 #include "MEM_guardedalloc.h"
39
40 #include "BLI_bitmap.h"
41 #include "BLI_math.h"
42 #include "BLI_utildefines.h"
43 #include "BLI_ghash.h"
44 #include "BLI_threads.h"
45
46 #include "DNA_meshdata_types.h"
47
48 #include "BKE_ccg.h"
49 #include "BKE_DerivedMesh.h"
50 #include "BKE_paint.h"
51 #include "BKE_mesh.h"
52 #include "BKE_pbvh.h"
53
54 #include "GPU_buffers.h"
55 #include "GPU_draw.h"
56 #include "GPU_immediate.h"
57 #include "GPU_batch.h"
58
59 #include "bmesh.h"
60
61 /* XXX: the rest of the code in this file is used for optimized PBVH
62  * drawing and doesn't interact at all with the buffer code above */
63
64 struct GPU_PBVH_Buffers {
65         GPUIndexBuf *index_buf, *index_buf_fast;
66         GPUVertBuf *vert_buf;
67
68         GPUBatch *triangles;
69         GPUBatch *triangles_fast;
70
71         /* mesh pointers in case buffer allocation fails */
72         const MPoly *mpoly;
73         const MLoop *mloop;
74         const MLoopTri *looptri;
75         const MVert *mvert;
76
77         const int *face_indices;
78         int        face_indices_len;
79
80         /* grid pointers */
81         CCGKey gridkey;
82         CCGElem **grids;
83         const DMFlagMat *grid_flag_mats;
84         BLI_bitmap * const *grid_hidden;
85         const int *grid_indices;
86         int totgrid;
87         bool has_hidden;
88         bool is_index_buf_global;  /* Means index_buf uses global bvh's grid_common_gpu_buffer, **DO NOT** free it! */
89
90         bool use_bmesh;
91
92         uint tot_tri, tot_quad;
93
94         /* The PBVH ensures that either all faces in the node are
95          * smooth-shaded or all faces are flat-shaded */
96         bool smooth;
97
98         bool show_mask;
99 };
100
101 static struct {
102         uint pos, nor, msk;
103 } g_vbo_id = {0};
104
105 /* Allocates a non-initialized buffer to be sent to GPU.
106  * Return is false it indicates that the memory map failed. */
107 static bool gpu_pbvh_vert_buf_data_set(GPU_PBVH_Buffers *buffers, uint vert_len)
108 {
109         if (buffers->vert_buf == NULL) {
110                 /* Initialize vertex buffer */
111                 /* match 'VertexBufferFormat' */
112
113                 static GPUVertFormat format = {0};
114                 if (format.attr_len == 0) {
115                         g_vbo_id.pos = GPU_vertformat_attr_add(&format, "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT);
116                         g_vbo_id.nor = GPU_vertformat_attr_add(&format, "nor", GPU_COMP_I16, 3, GPU_FETCH_INT_TO_FLOAT_UNIT);
117                         g_vbo_id.msk = GPU_vertformat_attr_add(&format, "msk", GPU_COMP_F32, 1, GPU_FETCH_FLOAT);
118                 }
119 #if 0
120                 buffers->vert_buf = GPU_vertbuf_create_with_format_ex(&format, GPU_USAGE_DYNAMIC);
121                 GPU_vertbuf_data_alloc(buffers->vert_buf, vert_len);
122         }
123         else if (vert_len != buffers->vert_buf->vertex_len) {
124                 GPU_vertbuf_data_resize(buffers->vert_buf, vert_len);
125         }
126 #else
127                 buffers->vert_buf = GPU_vertbuf_create_with_format_ex(&format, GPU_USAGE_STATIC);
128         }
129         GPU_vertbuf_data_alloc(buffers->vert_buf, vert_len);
130 #endif
131         return buffers->vert_buf->data != NULL;
132 }
133
134 static void gpu_pbvh_batch_init(GPU_PBVH_Buffers *buffers, GPUPrimType prim)
135 {
136         /* force flushing to the GPU */
137         if (buffers->vert_buf->data) {
138                 GPU_vertbuf_use(buffers->vert_buf);
139         }
140
141         if (buffers->triangles == NULL) {
142                 buffers->triangles = GPU_batch_create(
143                         prim, buffers->vert_buf,
144                         /* can be NULL */
145                         buffers->index_buf);
146         }
147
148         if ((buffers->triangles_fast == NULL) && buffers->index_buf_fast) {
149                 buffers->triangles_fast = GPU_batch_create(
150                         prim, buffers->vert_buf,
151                         buffers->index_buf_fast);
152         }
153 }
154
155 void GPU_pbvh_mesh_buffers_update(
156         GPU_PBVH_Buffers *buffers, const MVert *mvert,
157         const int *vert_indices, int totvert, const float *vmask,
158         const int (*face_vert_indices)[3],
159         const int update_flags)
160 {
161         const bool show_mask = (update_flags & GPU_PBVH_BUFFERS_SHOW_MASK) != 0;
162         bool empty_mask = true;
163
164         {
165                 int totelem = (buffers->smooth ? totvert : (buffers->tot_tri * 3));
166
167                 /* Build VBO */
168                 if (gpu_pbvh_vert_buf_data_set(buffers, totelem)) {
169                         /* Vertex data is shared if smooth-shaded, but separate
170                          * copies are made for flat shading because normals
171                          * shouldn't be shared. */
172                         if (buffers->smooth) {
173                                 for (uint i = 0; i < totvert; ++i) {
174                                         const MVert *v = &mvert[vert_indices[i]];
175                                         GPU_vertbuf_attr_set(buffers->vert_buf, g_vbo_id.pos, i, v->co);
176                                         GPU_vertbuf_attr_set(buffers->vert_buf, g_vbo_id.nor, i, v->no);
177                                 }
178
179                                 if (vmask && show_mask) {
180                                         for (uint i = 0; i < buffers->face_indices_len; i++) {
181                                                 const MLoopTri *lt = &buffers->looptri[buffers->face_indices[i]];
182                                                 for (uint j = 0; j < 3; j++) {
183                                                         int vidx = face_vert_indices[i][j];
184                                                         int v_index = buffers->mloop[lt->tri[j]].v;
185                                                         float fmask = vmask[v_index];
186                                                         GPU_vertbuf_attr_set(buffers->vert_buf, g_vbo_id.msk, vidx, &fmask);
187                                                         empty_mask = empty_mask && (fmask == 0.0f);
188                                                 }
189                                         }
190                                 }
191                         }
192                         else {
193                                 /* calculate normal for each polygon only once */
194                                 uint mpoly_prev = UINT_MAX;
195                                 short no[3];
196                                 int vbo_index = 0;
197
198                                 for (uint i = 0; i < buffers->face_indices_len; i++) {
199                                         const MLoopTri *lt = &buffers->looptri[buffers->face_indices[i]];
200                                         const uint vtri[3] = {
201                                             buffers->mloop[lt->tri[0]].v,
202                                             buffers->mloop[lt->tri[1]].v,
203                                             buffers->mloop[lt->tri[2]].v,
204                                         };
205
206                                         if (paint_is_face_hidden(lt, mvert, buffers->mloop))
207                                                 continue;
208
209                                         /* Face normal and mask */
210                                         if (lt->poly != mpoly_prev) {
211                                                 const MPoly *mp = &buffers->mpoly[lt->poly];
212                                                 float fno[3];
213                                                 BKE_mesh_calc_poly_normal(mp, &buffers->mloop[mp->loopstart], mvert, fno);
214                                                 normal_float_to_short_v3(no, fno);
215                                                 mpoly_prev = lt->poly;
216                                         }
217
218                                         float fmask = 0.0f;
219                                         if (vmask && show_mask) {
220                                                 fmask = (vmask[vtri[0]] + vmask[vtri[1]] + vmask[vtri[2]]) / 3.0f;
221                                         }
222
223                                         for (uint j = 0; j < 3; j++) {
224                                                 const MVert *v = &mvert[vtri[j]];
225
226                                                 GPU_vertbuf_attr_set(buffers->vert_buf, g_vbo_id.pos, vbo_index, v->co);
227                                                 GPU_vertbuf_attr_set(buffers->vert_buf, g_vbo_id.nor, vbo_index, no);
228                                                 GPU_vertbuf_attr_set(buffers->vert_buf, g_vbo_id.msk, vbo_index, &fmask);
229
230                                                 vbo_index++;
231                                         }
232
233                                         empty_mask = empty_mask && (fmask == 0.0f);
234                                 }
235                         }
236
237                         gpu_pbvh_batch_init(buffers, GPU_PRIM_TRIS);
238                 }
239         }
240
241         buffers->show_mask = !empty_mask;
242         buffers->mvert = mvert;
243 }
244
245 GPU_PBVH_Buffers *GPU_pbvh_mesh_buffers_build(
246         const int (*face_vert_indices)[3],
247         const MPoly *mpoly, const MLoop *mloop, const MLoopTri *looptri,
248         const MVert *mvert,
249         const int *face_indices,
250         const int  face_indices_len)
251 {
252         GPU_PBVH_Buffers *buffers;
253         int i, tottri;
254
255         buffers = MEM_callocN(sizeof(GPU_PBVH_Buffers), "GPU_Buffers");
256
257         /* smooth or flat for all */
258 #if 0
259         buffers->smooth = mpoly[looptri[face_indices[0]].poly].flag & ME_SMOOTH;
260 #else
261         /* for DrawManager we dont support mixed smooth/flat */
262         buffers->smooth = (mpoly[0].flag & ME_SMOOTH) != 0;
263 #endif
264
265         buffers->show_mask = false;
266
267         /* Count the number of visible triangles */
268         for (i = 0, tottri = 0; i < face_indices_len; ++i) {
269                 const MLoopTri *lt = &looptri[face_indices[i]];
270                 if (!paint_is_face_hidden(lt, mvert, mloop))
271                         tottri++;
272         }
273
274         if (tottri == 0) {
275                 buffers->tot_tri = 0;
276
277                 buffers->mpoly = mpoly;
278                 buffers->mloop = mloop;
279                 buffers->looptri = looptri;
280                 buffers->face_indices = face_indices;
281                 buffers->face_indices_len = 0;
282
283                 return buffers;
284         }
285
286         /* An element index buffer is used for smooth shading, but flat
287          * shading requires separate vertex normals so an index buffer is
288          * can't be used there. */
289         if (buffers->smooth) {
290                 /* Fill the triangle buffer */
291                 buffers->index_buf = NULL;
292                 GPUIndexBufBuilder elb;
293                 GPU_indexbuf_init(&elb, GPU_PRIM_TRIS, tottri, INT_MAX);
294
295                 for (i = 0; i < face_indices_len; ++i) {
296                         const MLoopTri *lt = &looptri[face_indices[i]];
297
298                         /* Skip hidden faces */
299                         if (paint_is_face_hidden(lt, mvert, mloop))
300                                 continue;
301
302                         GPU_indexbuf_add_tri_verts(&elb, UNPACK3(face_vert_indices[i]));
303                 }
304                 buffers->index_buf = GPU_indexbuf_build(&elb);
305         }
306         else {
307                 if (!buffers->is_index_buf_global) {
308                         GPU_INDEXBUF_DISCARD_SAFE(buffers->index_buf);
309                 }
310                 buffers->index_buf = NULL;
311                 buffers->is_index_buf_global = false;
312         }
313
314         buffers->tot_tri = tottri;
315
316         buffers->mpoly = mpoly;
317         buffers->mloop = mloop;
318         buffers->looptri = looptri;
319
320         buffers->face_indices = face_indices;
321         buffers->face_indices_len = face_indices_len;
322
323         return buffers;
324 }
325
326 static void gpu_pbvh_grid_fill_fast_buffer(GPU_PBVH_Buffers *buffers, int totgrid, int gridsize)
327 {
328         GPUIndexBufBuilder elb;
329         if (buffers->smooth) {
330                 GPU_indexbuf_init(&elb, GPU_PRIM_TRIS, 6 * totgrid, INT_MAX);
331                 for (int i = 0; i < totgrid; i++) {
332                         GPU_indexbuf_add_generic_vert(&elb, i * gridsize * gridsize + gridsize - 1);
333                         GPU_indexbuf_add_generic_vert(&elb, i * gridsize * gridsize);
334                         GPU_indexbuf_add_generic_vert(&elb, (i + 1) * gridsize * gridsize - gridsize);
335                         GPU_indexbuf_add_generic_vert(&elb, (i + 1) * gridsize * gridsize - 1);
336                         GPU_indexbuf_add_generic_vert(&elb, i * gridsize * gridsize + gridsize - 1);
337                         GPU_indexbuf_add_generic_vert(&elb, (i + 1) * gridsize * gridsize - gridsize);
338                 }
339         }
340         else {
341                 GPU_indexbuf_init_ex(&elb, GPU_PRIM_TRI_STRIP, 5 * totgrid, INT_MAX, true);
342                 uint vbo_index_offset = 0;
343                 for (int i = 0; i < totgrid; i++) {
344                         uint grid_indices[4] = {0, 0, 0, 0};
345                         for (int j = 0; j < gridsize - 1; j++) {
346                                 for (int k = 0; k < gridsize - 1; k++) {
347                                         const bool is_row_start = (k == 0);
348                                         const bool is_row_end = (k == gridsize - 2);
349                                         const bool is_grid_start = (j == 0);
350                                         const bool is_grid_end = (j == gridsize - 2);
351                                         const bool is_first_grid = (i == 0);
352                                         const bool is_last_grid = (i == totgrid - 1);
353
354                                         if (is_row_start && !(is_grid_start && is_first_grid)) {
355                                                 vbo_index_offset += 1;
356                                         }
357
358                                         if (is_grid_start && is_row_start) {
359                                                 grid_indices[0] = vbo_index_offset + 0;
360                                         }
361                                         else if (is_grid_start && is_row_end) {
362                                                 grid_indices[1] = vbo_index_offset + 2;
363                                         }
364                                         else if (is_grid_end && is_row_start) {
365                                                 grid_indices[2] = vbo_index_offset + 1;
366                                         }
367                                         else if (is_grid_end && is_row_end) {
368                                                 grid_indices[3] = vbo_index_offset + 3;
369                                         }
370                                         vbo_index_offset += 4;
371
372                                         if (is_row_end && !(is_grid_end && is_last_grid)) {
373                                                 vbo_index_offset += 1;
374                                         }
375                                 }
376                         }
377                         GPU_indexbuf_add_generic_vert(&elb, grid_indices[1]);
378                         GPU_indexbuf_add_generic_vert(&elb, grid_indices[0]);
379                         GPU_indexbuf_add_generic_vert(&elb, grid_indices[3]);
380                         GPU_indexbuf_add_generic_vert(&elb, grid_indices[2]);
381                         GPU_indexbuf_add_primitive_restart(&elb);
382                 }
383         }
384         buffers->index_buf_fast = GPU_indexbuf_build(&elb);
385 }
386
387 void GPU_pbvh_grid_buffers_update(
388         GPU_PBVH_Buffers *buffers, CCGElem **grids,
389         const DMFlagMat *grid_flag_mats, int *grid_indices,
390         int totgrid, const CCGKey *key,
391         const int update_flags)
392 {
393         const bool show_mask = (update_flags & GPU_PBVH_BUFFERS_SHOW_MASK) != 0;
394         bool empty_mask = true;
395         int i, j, k, x, y;
396
397         buffers->smooth = grid_flag_mats[grid_indices[0]].flag & ME_SMOOTH;
398
399         /* Build VBO */
400         const int has_mask = key->has_mask;
401
402         uint vert_count = totgrid * key->grid_area;
403
404         if (!buffers->smooth) {
405                 vert_count = totgrid * (key->grid_size - 1) * (key->grid_size - 1) * 4;
406                 /* Count strip restart verts (2 verts between each row and grid) */
407                 vert_count += ((totgrid - 1) + totgrid * (key->grid_size - 2)) * 2;
408         }
409
410         if (buffers->smooth && buffers->index_buf == NULL) {
411                 /* Not sure if really needed.  */
412                 GPU_BATCH_DISCARD_SAFE(buffers->triangles_fast);
413                 GPU_INDEXBUF_DISCARD_SAFE(buffers->index_buf_fast);
414         }
415         else if (!buffers->smooth && buffers->index_buf != NULL) {
416                 /* Discard unnecessary index buffers. */
417                 GPU_BATCH_DISCARD_SAFE(buffers->triangles);
418                 GPU_BATCH_DISCARD_SAFE(buffers->triangles_fast);
419                 GPU_INDEXBUF_DISCARD_SAFE(buffers->index_buf);
420                 GPU_INDEXBUF_DISCARD_SAFE(buffers->index_buf_fast);
421         }
422
423         if (buffers->index_buf_fast == NULL) {
424                 gpu_pbvh_grid_fill_fast_buffer(buffers, totgrid, key->grid_size);
425         }
426
427         uint vbo_index_offset = 0;
428         /* Build VBO */
429         if (gpu_pbvh_vert_buf_data_set(buffers, vert_count)) {
430                 for (i = 0; i < totgrid; ++i) {
431                         CCGElem *grid = grids[grid_indices[i]];
432                         int vbo_index = vbo_index_offset;
433
434                         if (buffers->smooth) {
435                                 for (y = 0; y < key->grid_size; y++) {
436                                         for (x = 0; x < key->grid_size; x++) {
437                                                 CCGElem *elem = CCG_grid_elem(key, grid, x, y);
438                                                 GPU_vertbuf_attr_set(buffers->vert_buf, g_vbo_id.pos, vbo_index, CCG_elem_co(key, elem));
439
440                                                 short no_short[3];
441                                                 normal_float_to_short_v3(no_short, CCG_elem_no(key, elem));
442                                                 GPU_vertbuf_attr_set(buffers->vert_buf, g_vbo_id.nor, vbo_index, no_short);
443
444                                                 if (has_mask && show_mask) {
445                                                         float fmask = *CCG_elem_mask(key, elem);
446                                                         GPU_vertbuf_attr_set(buffers->vert_buf, g_vbo_id.msk, vbo_index, &fmask);
447                                                         empty_mask = empty_mask && (fmask == 0.0f);
448                                                 }
449                                                 vbo_index += 1;
450                                         }
451                                 }
452                                 vbo_index_offset += key->grid_area;
453                         }
454                         else {
455                                 for (j = 0; j < key->grid_size - 1; j++) {
456                                         for (k = 0; k < key->grid_size - 1; k++) {
457                                                 const bool is_row_start = (k == 0);
458                                                 const bool is_row_end = (k == key->grid_size - 2);
459                                                 const bool is_grid_start = (j == 0);
460                                                 const bool is_grid_end = (j == key->grid_size - 2);
461                                                 const bool is_first_grid = (i == 0);
462                                                 const bool is_last_grid = (i == totgrid - 1);
463
464                                                 CCGElem *elems[4] = {
465                                                         CCG_grid_elem(key, grid, k, j + 1),
466                                                         CCG_grid_elem(key, grid, k + 1, j + 1),
467                                                         CCG_grid_elem(key, grid, k + 1, j),
468                                                         CCG_grid_elem(key, grid, k, j)
469                                                 };
470                                                 float *co[4] = {
471                                                     CCG_elem_co(key, elems[0]),
472                                                     CCG_elem_co(key, elems[1]),
473                                                     CCG_elem_co(key, elems[2]),
474                                                     CCG_elem_co(key, elems[3])
475                                                 };
476
477                                                 float fno[3];
478                                                 short no_short[3];
479                                                 normal_quad_v3(fno, co[0], co[1], co[2], co[3]);
480                                                 normal_float_to_short_v3(no_short, fno);
481
482                                                 if (is_row_start && !(is_grid_start && is_first_grid)) {
483                                                         /* Duplicate first vert
484                                                          * (only pos is needed since the triangle will be degenerate) */
485                                                         GPU_vertbuf_attr_set(buffers->vert_buf, g_vbo_id.pos, vbo_index, co[3]);
486                                                         vbo_index += 1;
487                                                         vbo_index_offset += 1;
488                                                 }
489
490                                                 /* Note indices orders (3, 0, 2, 1); we are drawing a triangle strip. */
491                                                 GPU_vertbuf_attr_set(buffers->vert_buf, g_vbo_id.pos, vbo_index, co[3]);
492                                                 GPU_vertbuf_attr_set(buffers->vert_buf, g_vbo_id.nor, vbo_index, no_short);
493                                                 GPU_vertbuf_attr_set(buffers->vert_buf, g_vbo_id.pos, vbo_index + 1, co[0]);
494                                                 GPU_vertbuf_attr_set(buffers->vert_buf, g_vbo_id.nor, vbo_index + 1, no_short);
495                                                 GPU_vertbuf_attr_set(buffers->vert_buf, g_vbo_id.pos, vbo_index + 2, co[2]);
496                                                 GPU_vertbuf_attr_set(buffers->vert_buf, g_vbo_id.nor, vbo_index + 2, no_short);
497                                                 GPU_vertbuf_attr_set(buffers->vert_buf, g_vbo_id.pos, vbo_index + 3, co[1]);
498                                                 GPU_vertbuf_attr_set(buffers->vert_buf, g_vbo_id.nor, vbo_index + 3, no_short);
499
500                                                 if (has_mask && show_mask) {
501                                                         float fmask = (*CCG_elem_mask(key, elems[0]) +
502                                                                        *CCG_elem_mask(key, elems[1]) +
503                                                                        *CCG_elem_mask(key, elems[2]) +
504                                                                        *CCG_elem_mask(key, elems[3])) * 0.25f;
505                                                         GPU_vertbuf_attr_set(buffers->vert_buf, g_vbo_id.msk, vbo_index, &fmask);
506                                                         GPU_vertbuf_attr_set(buffers->vert_buf, g_vbo_id.msk, vbo_index + 1, &fmask);
507                                                         GPU_vertbuf_attr_set(buffers->vert_buf, g_vbo_id.msk, vbo_index + 2, &fmask);
508                                                         GPU_vertbuf_attr_set(buffers->vert_buf, g_vbo_id.msk, vbo_index + 3, &fmask);
509                                                         empty_mask = empty_mask && (fmask == 0.0f);
510                                                 }
511
512                                                 if (is_row_end && !(is_grid_end && is_last_grid)) {
513                                                         /* Duplicate last vert
514                                                          * (only pos is needed since the triangle will be degenerate) */
515                                                         GPU_vertbuf_attr_set(buffers->vert_buf, g_vbo_id.pos, vbo_index + 4, co[1]);
516                                                         vbo_index += 1;
517                                                         vbo_index_offset += 1;
518                                                 }
519
520                                                 vbo_index += 4;
521                                         }
522                                 }
523                                 vbo_index_offset += (key->grid_size - 1) * (key->grid_size - 1) * 4;
524                         }
525                 }
526
527                 gpu_pbvh_batch_init(buffers, buffers->smooth ? GPU_PRIM_TRIS : GPU_PRIM_TRI_STRIP);
528         }
529
530         buffers->grids = grids;
531         buffers->grid_indices = grid_indices;
532         buffers->totgrid = totgrid;
533         buffers->grid_flag_mats = grid_flag_mats;
534         buffers->gridkey = *key;
535         buffers->show_mask = !empty_mask;
536
537         //printf("node updated %p\n", buffers);
538 }
539
540 /* Build the element array buffer of grid indices using either
541  * ushorts or uints. */
542 #define FILL_QUAD_BUFFER(max_vert_, tot_quad_, buffer_)                 \
543         {                                                                   \
544                 int offset = 0;                                                 \
545                 int i, j, k;                                                    \
546                                                                         \
547                 GPUIndexBufBuilder elb;                                         \
548                 GPU_indexbuf_init(                                              \
549                        &elb, GPU_PRIM_TRIS, tot_quad_ * 2, max_vert_);          \
550                                                                         \
551                 /* Fill the buffer */                                           \
552                 for (i = 0; i < totgrid; ++i) {                                 \
553                         BLI_bitmap *gh = NULL;                                      \
554                         if (grid_hidden)                                            \
555                                 gh = grid_hidden[(grid_indices)[i]];                    \
556                                                                         \
557                         for (j = 0; j < gridsize - 1; ++j) {                        \
558                                 for (k = 0; k < gridsize - 1; ++k) {                    \
559                                         /* Skip hidden grid face */                         \
560                                         if (gh && paint_is_grid_face_hidden(                \
561                                                 gh, gridsize, k, j))                        \
562                                         {                                                   \
563                                                 continue;                                       \
564                                         }                                                   \
565                                         GPU_indexbuf_add_generic_vert(&elb, offset + j * gridsize + k + 1); \
566                                         GPU_indexbuf_add_generic_vert(&elb, offset + j * gridsize + k);    \
567                                         GPU_indexbuf_add_generic_vert(&elb, offset + (j + 1) * gridsize + k); \
568                                                                         \
569                                         GPU_indexbuf_add_generic_vert(&elb, offset + (j + 1) * gridsize + k + 1); \
570                                         GPU_indexbuf_add_generic_vert(&elb, offset + j * gridsize + k + 1); \
571                                         GPU_indexbuf_add_generic_vert(&elb, offset + (j + 1) * gridsize + k); \
572                                 }                                                       \
573                         }                                                           \
574                                                                         \
575                         offset += gridsize * gridsize;                              \
576                 }                                                               \
577                 buffer_ = GPU_indexbuf_build(&elb);                             \
578         } (void)0
579 /* end FILL_QUAD_BUFFER */
580
581 static GPUIndexBuf *gpu_get_grid_buffer(
582         int gridsize, uint *totquad,
583         /* remove this arg  when GPU gets base-vertex support! */
584         int totgrid)
585 {
586         /* used in the FILL_QUAD_BUFFER macro */
587         BLI_bitmap * const *grid_hidden = NULL;
588         const int *grid_indices = NULL;
589
590         /* Build new VBO */
591         *totquad = (gridsize - 1) * (gridsize - 1) * totgrid;
592         int max_vert = gridsize * gridsize * totgrid;
593
594         GPUIndexBuf *mres_buffer;
595         FILL_QUAD_BUFFER(max_vert, *totquad, mres_buffer);
596
597         return mres_buffer;
598 }
599
600 GPU_PBVH_Buffers *GPU_pbvh_grid_buffers_build(
601         int *grid_indices, int totgrid, BLI_bitmap **grid_hidden, int gridsize, const CCGKey *UNUSED(key))
602 {
603         GPU_PBVH_Buffers *buffers;
604         int totquad;
605         int fully_visible_totquad = (gridsize - 1) * (gridsize - 1) * totgrid;
606
607         buffers = MEM_callocN(sizeof(GPU_PBVH_Buffers), "GPU_Buffers");
608         buffers->grid_hidden = grid_hidden;
609         buffers->totgrid = totgrid;
610
611         buffers->show_mask = false;
612
613         /* Count the number of quads */
614         totquad = BKE_pbvh_count_grid_quads(grid_hidden, grid_indices, totgrid, gridsize);
615
616         /* totally hidden node, return here to avoid BufferData with zero below. */
617         if (totquad == 0)
618                 return buffers;
619
620         /* TODO(fclem) this needs a bit of cleanup. It's only needed for smooth grids.
621          * Could be moved to the update function somehow. */
622         if (totquad == fully_visible_totquad) {
623                 buffers->index_buf = gpu_get_grid_buffer(gridsize, &buffers->tot_quad, totgrid);
624                 buffers->has_hidden = false;
625                 buffers->is_index_buf_global = false;
626         }
627         else {
628                 uint max_vert = totgrid * gridsize * gridsize;
629                 buffers->tot_quad = totquad;
630
631                 FILL_QUAD_BUFFER(max_vert, totquad, buffers->index_buf);
632
633                 buffers->has_hidden = false;
634                 buffers->is_index_buf_global = false;
635         }
636
637         return buffers;
638 }
639
640 #undef FILL_QUAD_BUFFER
641
642 /* Output a BMVert into a VertexBufferFormat array
643  *
644  * The vertex is skipped if hidden, otherwise the output goes into
645  * index '*v_index' in the 'vert_data' array and '*v_index' is
646  * incremented.
647  */
648 static void gpu_bmesh_vert_to_buffer_copy__gwn(
649         BMVert *v,
650         GPUVertBuf *vert_buf,
651         int *v_index,
652         const float fno[3],
653         const float *fmask,
654         const int cd_vert_mask_offset,
655         const bool show_mask,
656         bool *empty_mask)
657 {
658         if (!BM_elem_flag_test(v, BM_ELEM_HIDDEN)) {
659
660                 /* Set coord, normal, and mask */
661                 GPU_vertbuf_attr_set(vert_buf, g_vbo_id.pos, *v_index, v->co);
662
663                 short no_short[3];
664                 normal_float_to_short_v3(no_short, fno ? fno : v->no);
665                 GPU_vertbuf_attr_set(vert_buf, g_vbo_id.nor, *v_index, no_short);
666
667                 if (show_mask) {
668                         float effective_mask = fmask ? *fmask
669                                                      : BM_ELEM_CD_GET_FLOAT(v, cd_vert_mask_offset);
670                         GPU_vertbuf_attr_set(vert_buf, g_vbo_id.msk, *v_index, &effective_mask);
671                         *empty_mask = *empty_mask && (effective_mask == 0.0f);
672                 }
673
674                 /* Assign index for use in the triangle index buffer */
675                 /* note: caller must set:  bm->elem_index_dirty |= BM_VERT; */
676                 BM_elem_index_set(v, (*v_index)); /* set_dirty! */
677
678                 (*v_index)++;
679         }
680 }
681
682 /* Return the total number of vertices that don't have BM_ELEM_HIDDEN set */
683 static int gpu_bmesh_vert_visible_count(GSet *bm_unique_verts,
684                                         GSet *bm_other_verts)
685 {
686         GSetIterator gs_iter;
687         int totvert = 0;
688
689         GSET_ITER (gs_iter, bm_unique_verts) {
690                 BMVert *v = BLI_gsetIterator_getKey(&gs_iter);
691                 if (!BM_elem_flag_test(v, BM_ELEM_HIDDEN))
692                         totvert++;
693         }
694         GSET_ITER (gs_iter, bm_other_verts) {
695                 BMVert *v = BLI_gsetIterator_getKey(&gs_iter);
696                 if (!BM_elem_flag_test(v, BM_ELEM_HIDDEN))
697                         totvert++;
698         }
699
700         return totvert;
701 }
702
703 /* Return the total number of visible faces */
704 static int gpu_bmesh_face_visible_count(GSet *bm_faces)
705 {
706         GSetIterator gh_iter;
707         int totface = 0;
708
709         GSET_ITER (gh_iter, bm_faces) {
710                 BMFace *f = BLI_gsetIterator_getKey(&gh_iter);
711
712                 if (!BM_elem_flag_test(f, BM_ELEM_HIDDEN))
713                         totface++;
714         }
715
716         return totface;
717 }
718
719 /* Creates a vertex buffer (coordinate, normal, color) and, if smooth
720  * shading, an element index buffer. */
721 void GPU_pbvh_bmesh_buffers_update(
722         GPU_PBVH_Buffers *buffers,
723         BMesh *bm,
724         GSet *bm_faces,
725         GSet *bm_unique_verts,
726         GSet *bm_other_verts,
727         const int update_flags)
728 {
729         const bool show_mask = (update_flags & GPU_PBVH_BUFFERS_SHOW_MASK) != 0;
730         int tottri, totvert, maxvert = 0;
731         bool empty_mask = true;
732
733         /* TODO, make mask layer optional for bmesh buffer */
734         const int cd_vert_mask_offset = CustomData_get_offset(&bm->vdata, CD_PAINT_MASK);
735
736         /* Count visible triangles */
737         tottri = gpu_bmesh_face_visible_count(bm_faces);
738
739         if (buffers->smooth) {
740                 /* Smooth needs to recreate index buffer, so we have to invalidate the batch. */
741                 GPU_BATCH_DISCARD_SAFE(buffers->triangles);
742                 /* Count visible vertices */
743                 totvert = gpu_bmesh_vert_visible_count(bm_unique_verts, bm_other_verts);
744         }
745         else {
746                 totvert = tottri * 3;
747         }
748
749         if (!tottri) {
750                 buffers->tot_tri = 0;
751                 return;
752         }
753
754         /* Fill vertex buffer */
755         if (gpu_pbvh_vert_buf_data_set(buffers, totvert)) {
756                 int v_index = 0;
757
758                 if (buffers->smooth) {
759                         GSetIterator gs_iter;
760
761                         /* Vertices get an index assigned for use in the triangle
762                          * index buffer */
763                         bm->elem_index_dirty |= BM_VERT;
764
765                         GSET_ITER (gs_iter, bm_unique_verts) {
766                                 gpu_bmesh_vert_to_buffer_copy__gwn(
767                                         BLI_gsetIterator_getKey(&gs_iter),
768                                         buffers->vert_buf, &v_index, NULL, NULL,
769                                         cd_vert_mask_offset,
770                                         show_mask, &empty_mask);
771                         }
772
773                         GSET_ITER (gs_iter, bm_other_verts) {
774                                 gpu_bmesh_vert_to_buffer_copy__gwn(
775                                         BLI_gsetIterator_getKey(&gs_iter),
776                                         buffers->vert_buf, &v_index, NULL, NULL,
777                                         cd_vert_mask_offset,
778                                         show_mask, &empty_mask);
779                         }
780
781                         maxvert = v_index;
782                 }
783                 else {
784                         GSetIterator gs_iter;
785
786                         GSET_ITER (gs_iter, bm_faces) {
787                                 BMFace *f = BLI_gsetIterator_getKey(&gs_iter);
788
789                                 BLI_assert(f->len == 3);
790
791                                 if (!BM_elem_flag_test(f, BM_ELEM_HIDDEN)) {
792                                         BMVert *v[3];
793                                         float fmask = 0.0f;
794                                         int i;
795
796 #if 0
797                                         BM_iter_as_array(bm, BM_VERTS_OF_FACE, f, (void **)v, 3);
798 #endif
799                                         BM_face_as_array_vert_tri(f, v);
800
801                                         /* Average mask value */
802                                         for (i = 0; i < 3; i++) {
803                                                 fmask += BM_ELEM_CD_GET_FLOAT(v[i], cd_vert_mask_offset);
804                                         }
805                                         fmask /= 3.0f;
806
807                                         for (i = 0; i < 3; i++) {
808                                                 gpu_bmesh_vert_to_buffer_copy__gwn(
809                                                         v[i], buffers->vert_buf,
810                                                         &v_index, f->no, &fmask,
811                                                         cd_vert_mask_offset,
812                                                         show_mask, &empty_mask);
813                                         }
814                                 }
815                         }
816
817                         buffers->tot_tri = tottri;
818                 }
819
820                 /* gpu_bmesh_vert_to_buffer_copy sets dirty index values */
821                 bm->elem_index_dirty |= BM_VERT;
822         }
823         else {
824                 /* Memory map failed */
825                 return;
826         }
827
828         if (buffers->smooth) {
829                 /* Fill the triangle buffer */
830                 buffers->index_buf = NULL;
831                 GPUIndexBufBuilder elb;
832                 GPU_indexbuf_init(&elb, GPU_PRIM_TRIS, tottri, maxvert);
833
834                 /* Initialize triangle index buffer */
835                 buffers->is_index_buf_global = false;
836
837                 /* Fill triangle index buffer */
838
839                 {
840                         GSetIterator gs_iter;
841
842                         GSET_ITER (gs_iter, bm_faces) {
843                                 BMFace *f = BLI_gsetIterator_getKey(&gs_iter);
844
845                                 if (!BM_elem_flag_test(f, BM_ELEM_HIDDEN)) {
846                                         BMVert *v[3];
847
848                                         BM_face_as_array_vert_tri(f, v);
849                                         GPU_indexbuf_add_tri_verts(
850                                                 &elb, BM_elem_index_get(v[0]), BM_elem_index_get(v[1]), BM_elem_index_get(v[2]));
851                                 }
852                         }
853
854                         buffers->tot_tri = tottri;
855
856                         if (buffers->index_buf == NULL) {
857                                 buffers->index_buf = GPU_indexbuf_build(&elb);
858                         }
859                         else {
860                                 GPU_indexbuf_build_in_place(&elb, buffers->index_buf);
861                         }
862                 }
863         }
864         else if (buffers->index_buf) {
865                 if (!buffers->is_index_buf_global) {
866                         GPU_INDEXBUF_DISCARD_SAFE(buffers->index_buf);
867                 }
868                 buffers->index_buf = NULL;
869                 buffers->is_index_buf_global = false;
870         }
871
872         buffers->show_mask = !empty_mask;
873
874         gpu_pbvh_batch_init(buffers, GPU_PRIM_TRIS);
875 }
876
877 GPU_PBVH_Buffers *GPU_pbvh_bmesh_buffers_build(bool smooth_shading)
878 {
879         GPU_PBVH_Buffers *buffers;
880
881         buffers = MEM_callocN(sizeof(GPU_PBVH_Buffers), "GPU_Buffers");
882         buffers->use_bmesh = true;
883         buffers->smooth = smooth_shading;
884         buffers->show_mask = true;
885
886         return buffers;
887 }
888
889 GPUBatch *GPU_pbvh_buffers_batch_get(GPU_PBVH_Buffers *buffers, bool fast)
890 {
891         return (fast && buffers->triangles_fast) ?
892                 buffers->triangles_fast : buffers->triangles;
893 }
894
895 bool GPU_pbvh_buffers_has_mask(GPU_PBVH_Buffers *buffers)
896 {
897         return buffers->show_mask;
898 }
899
900 void GPU_pbvh_buffers_free(GPU_PBVH_Buffers *buffers)
901 {
902         if (buffers) {
903                 GPU_BATCH_DISCARD_SAFE(buffers->triangles);
904                 GPU_BATCH_DISCARD_SAFE(buffers->triangles_fast);
905                 if (!buffers->is_index_buf_global) {
906                         GPU_INDEXBUF_DISCARD_SAFE(buffers->index_buf);
907                 }
908                 GPU_INDEXBUF_DISCARD_SAFE(buffers->index_buf_fast);
909                 GPU_VERTBUF_DISCARD_SAFE(buffers->vert_buf);
910
911                 MEM_freeN(buffers);
912         }
913 }
914
915 /* debug function, draws the pbvh BB */
916 void GPU_pbvh_BB_draw(float min[3], float max[3], bool leaf, uint pos)
917 {
918         if (leaf)
919                 immUniformColor4f(0.0, 1.0, 0.0, 0.5);
920         else
921                 immUniformColor4f(1.0, 0.0, 0.0, 0.5);
922
923         /* TODO(merwin): revisit this after we have mutable VertexBuffers
924          * could keep a static batch & index buffer, change the VBO contents per draw
925          */
926
927         immBegin(GPU_PRIM_LINES, 24);
928
929         /* top */
930         immVertex3f(pos, min[0], min[1], max[2]);
931         immVertex3f(pos, min[0], max[1], max[2]);
932
933         immVertex3f(pos, min[0], max[1], max[2]);
934         immVertex3f(pos, max[0], max[1], max[2]);
935
936         immVertex3f(pos, max[0], max[1], max[2]);
937         immVertex3f(pos, max[0], min[1], max[2]);
938
939         immVertex3f(pos, max[0], min[1], max[2]);
940         immVertex3f(pos, min[0], min[1], max[2]);
941
942         /* bottom */
943         immVertex3f(pos, min[0], min[1], min[2]);
944         immVertex3f(pos, min[0], max[1], min[2]);
945
946         immVertex3f(pos, min[0], max[1], min[2]);
947         immVertex3f(pos, max[0], max[1], min[2]);
948
949         immVertex3f(pos, max[0], max[1], min[2]);
950         immVertex3f(pos, max[0], min[1], min[2]);
951
952         immVertex3f(pos, max[0], min[1], min[2]);
953         immVertex3f(pos, min[0], min[1], min[2]);
954
955         /* sides */
956         immVertex3f(pos, min[0], min[1], min[2]);
957         immVertex3f(pos, min[0], min[1], max[2]);
958
959         immVertex3f(pos, min[0], max[1], min[2]);
960         immVertex3f(pos, min[0], max[1], max[2]);
961
962         immVertex3f(pos, max[0], max[1], min[2]);
963         immVertex3f(pos, max[0], max[1], max[2]);
964
965         immVertex3f(pos, max[0], min[1], min[2]);
966         immVertex3f(pos, max[0], min[1], max[2]);
967
968         immEnd();
969 }
970
971 void GPU_pbvh_fix_linking()
972 {
973 }