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