Merge branch 'master' into blender2.8
[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 "GPU_glew.h"
39
40 #include "MEM_guardedalloc.h"
41
42 #include "BLI_bitmap.h"
43 #include "BLI_math.h"
44 #include "BLI_utildefines.h"
45 #include "BLI_ghash.h"
46 #include "BLI_threads.h"
47
48 #include "DNA_meshdata_types.h"
49
50 #include "BKE_ccg.h"
51 #include "BKE_DerivedMesh.h"
52 #include "BKE_paint.h"
53 #include "BKE_mesh.h"
54 #include "BKE_pbvh.h"
55
56 #include "DNA_userdef_types.h"
57
58 #include "GPU_buffers.h"
59 #include "GPU_draw.h"
60 #include "GPU_basic_shader.h"
61
62 #include "bmesh.h"
63
64 typedef enum {
65         GPU_BUFFER_VERTEX_STATE = (1 << 0),
66         GPU_BUFFER_NORMAL_STATE = (1 << 1),
67         GPU_BUFFER_TEXCOORD_UNIT_0_STATE = (1 << 2),
68         GPU_BUFFER_TEXCOORD_UNIT_2_STATE = (1 << 3),
69         GPU_BUFFER_COLOR_STATE = (1 << 4),
70         GPU_BUFFER_ELEMENT_STATE = (1 << 5),
71 } GPUBufferState;
72
73 typedef struct {
74         GLenum gl_buffer_type;
75         int num_components; /* number of data components for one vertex */
76 } GPUBufferTypeSettings;
77
78
79 static size_t gpu_buffer_size_from_type(DerivedMesh *dm, GPUBufferType type);
80
81 const GPUBufferTypeSettings gpu_buffer_type_settings[] = {
82     /* vertex */
83     {GL_ARRAY_BUFFER, 3},
84     /* normal */
85     {GL_ARRAY_BUFFER, 4}, /* we copy 3 shorts per normal but we add a fourth for alignment */
86     /* mcol */
87     {GL_ARRAY_BUFFER, 3},
88     /* uv */
89     {GL_ARRAY_BUFFER, 2},
90     /* uv for texpaint */
91     {GL_ARRAY_BUFFER, 4},
92     /* edge */
93     {GL_ELEMENT_ARRAY_BUFFER, 2},
94     /* uv edge */
95     {GL_ELEMENT_ARRAY_BUFFER, 4},
96     /* triangles, 1 point since we are allocating from tottriangle points, which account for all points */
97     {GL_ELEMENT_ARRAY_BUFFER, 1},
98 };
99
100 #define MAX_GPU_ATTRIB_DATA 32
101
102 #define BUFFER_OFFSET(n) ((GLubyte *)NULL + (n))
103
104 static GPUBufferState GLStates = 0;
105 static GPUAttrib attribData[MAX_GPU_ATTRIB_DATA] = { { -1, 0, 0 } };
106
107 static ThreadMutex buffer_mutex = BLI_MUTEX_INITIALIZER;
108
109 /* multires global buffer, can be used for many grids having the same grid size */
110 typedef struct GridCommonGPUBuffer {
111         GPUBuffer *mres_buffer;
112         int mres_prev_gridsize;
113         GLenum mres_prev_index_type;
114         unsigned mres_prev_totquad;
115 } GridCommonGPUBuffer;
116
117 void GPU_buffer_material_finalize(GPUDrawObject *gdo, GPUBufferMaterial *matinfo, int totmat)
118 {
119         int i, curmat, curelement;
120
121         /* count the number of materials used by this DerivedMesh */
122         for (i = 0; i < totmat; i++) {
123                 if (matinfo[i].totelements > 0)
124                         gdo->totmaterial++;
125         }
126
127         /* allocate an array of materials used by this DerivedMesh */
128         gdo->materials = MEM_mallocN(sizeof(GPUBufferMaterial) * gdo->totmaterial,
129                                      "GPUDrawObject.materials");
130
131         /* initialize the materials array */
132         for (i = 0, curmat = 0, curelement = 0; i < totmat; i++) {
133                 if (matinfo[i].totelements > 0) {
134                         gdo->materials[curmat] = matinfo[i];
135                         gdo->materials[curmat].start = curelement;
136                         gdo->materials[curmat].mat_nr = i;
137                         gdo->materials[curmat].polys = MEM_mallocN(sizeof(int) * matinfo[i].totpolys, "GPUBufferMaterial.polys");
138
139                         curelement += matinfo[i].totelements;
140                         curmat++;
141                 }
142         }
143
144         MEM_freeN(matinfo);
145 }
146
147
148 /* stores recently-deleted buffers so that new buffers won't have to
149  * be recreated as often
150  *
151  * only one instance of this pool is created, stored in
152  * gpu_buffer_pool
153  *
154  * note that the number of buffers in the pool is usually limited to
155  * MAX_FREE_GPU_BUFFERS, but this limit may be exceeded temporarily
156  * when a GPUBuffer is released outside the main thread; due to OpenGL
157  * restrictions it cannot be immediately released
158  */
159 typedef struct GPUBufferPool {
160         /* number of allocated buffers stored */
161         int totbuf;
162         /* actual allocated length of the arrays */
163         int maxsize;
164         GPUBuffer **buffers;
165 } GPUBufferPool;
166 #define MAX_FREE_GPU_BUFFERS 8
167
168 /* create a new GPUBufferPool */
169 static GPUBufferPool *gpu_buffer_pool_new(void)
170 {
171         GPUBufferPool *pool;
172
173         pool = MEM_callocN(sizeof(GPUBufferPool), "GPUBuffer_Pool");
174
175         pool->maxsize = MAX_FREE_GPU_BUFFERS;
176         pool->buffers = MEM_mallocN(sizeof(*pool->buffers) * pool->maxsize,
177                                     "GPUBufferPool.buffers");
178         return pool;
179 }
180
181 /* remove a GPUBuffer from the pool (does not free the GPUBuffer) */
182 static void gpu_buffer_pool_remove_index(GPUBufferPool *pool, int index)
183 {
184         int i;
185
186         if (!pool || index < 0 || index >= pool->totbuf)
187                 return;
188
189         /* shift entries down, overwriting the buffer at `index' */
190         for (i = index; i < pool->totbuf - 1; i++)
191                 pool->buffers[i] = pool->buffers[i + 1];
192
193         /* clear the last entry */
194         if (pool->totbuf > 0)
195                 pool->buffers[pool->totbuf - 1] = NULL;
196
197         pool->totbuf--;
198 }
199
200 /* delete the last entry in the pool */
201 static void gpu_buffer_pool_delete_last(GPUBufferPool *pool)
202 {
203         GPUBuffer *last;
204
205         if (pool->totbuf <= 0)
206                 return;
207
208         /* get the last entry */
209         if (!(last = pool->buffers[pool->totbuf - 1]))
210                 return;
211
212         /* delete the buffer's data */
213         glDeleteBuffers(1, &last->id);
214
215         /* delete the buffer and remove from pool */
216         MEM_freeN(last);
217         pool->totbuf--;
218         pool->buffers[pool->totbuf] = NULL;
219 }
220
221 /* free a GPUBufferPool; also frees the data in the pool's
222  * GPUBuffers */
223 static void gpu_buffer_pool_free(GPUBufferPool *pool)
224 {
225         if (!pool)
226                 return;
227         
228         while (pool->totbuf)
229                 gpu_buffer_pool_delete_last(pool);
230
231         MEM_freeN(pool->buffers);
232         MEM_freeN(pool);
233 }
234
235 static void gpu_buffer_pool_free_unused(GPUBufferPool *pool)
236 {
237         if (!pool)
238                 return;
239
240         BLI_mutex_lock(&buffer_mutex);
241         
242         while (pool->totbuf)
243                 gpu_buffer_pool_delete_last(pool);
244
245         BLI_mutex_unlock(&buffer_mutex);
246 }
247
248 static GPUBufferPool *gpu_buffer_pool = NULL;
249 static GPUBufferPool *gpu_get_global_buffer_pool(void)
250 {
251         /* initialize the pool */
252         if (!gpu_buffer_pool)
253                 gpu_buffer_pool = gpu_buffer_pool_new();
254
255         return gpu_buffer_pool;
256 }
257
258 void GPU_global_buffer_pool_free(void)
259 {
260         gpu_buffer_pool_free(gpu_buffer_pool);
261         gpu_buffer_pool = NULL;
262 }
263
264 void GPU_global_buffer_pool_free_unused(void)
265 {
266         gpu_buffer_pool_free_unused(gpu_buffer_pool);
267 }
268
269 /* get a GPUBuffer of at least `size' bytes; uses one from the buffer
270  * pool if possible, otherwise creates a new one
271  *
272  * Thread-unsafe version for internal usage only.
273  */
274 static GPUBuffer *gpu_buffer_alloc_intern(size_t size)
275 {
276         GPUBufferPool *pool;
277         GPUBuffer *buf;
278         int i, bestfit = -1;
279         size_t bufsize;
280
281         /* bad case, leads to leak of buf since buf->pointer will allocate
282          * NULL, leading to return without cleanup. In any case better detect early
283          * psy-fi */
284         if (size == 0)
285                 return NULL;
286
287         pool = gpu_get_global_buffer_pool();
288
289         /* not sure if this buffer pool code has been profiled much,
290          * seems to me that the graphics driver and system memory
291          * management might do this stuff anyway. --nicholas
292          */
293
294         /* check the global buffer pool for a recently-deleted buffer
295          * that is at least as big as the request, but not more than
296          * twice as big */
297         for (i = 0; i < pool->totbuf; i++) {
298                 bufsize = pool->buffers[i]->size;
299                 
300                 /* check for an exact size match */
301                 if (bufsize == size) {
302                         bestfit = i;
303                         break;
304                 }
305                 /* smaller buffers won't fit data and buffers at least
306                  * twice as big are a waste of memory */
307                 else if (bufsize > size && size > (bufsize / 2)) {
308                         /* is it closer to the required size than the
309                          * last appropriate buffer found. try to save
310                          * memory */
311                         if (bestfit == -1 || pool->buffers[bestfit]->size > bufsize) {
312                                 bestfit = i;
313                         }
314                 }
315         }
316
317         /* if an acceptable buffer was found in the pool, remove it
318          * from the pool and return it */
319         if (bestfit != -1) {
320                 buf = pool->buffers[bestfit];
321                 gpu_buffer_pool_remove_index(pool, bestfit);
322                 return buf;
323         }
324
325         /* no acceptable buffer found in the pool, create a new one */
326         buf = MEM_callocN(sizeof(GPUBuffer), "GPUBuffer");
327         buf->size = size;
328
329         glGenBuffers(1, &buf->id);
330         glBindBuffer(GL_ARRAY_BUFFER, buf->id);
331         glBufferData(GL_ARRAY_BUFFER, size, NULL, GL_STATIC_DRAW);
332         glBindBuffer(GL_ARRAY_BUFFER, 0);
333
334         return buf;
335 }
336
337 /* Same as above, but safe for threading. */
338 GPUBuffer *GPU_buffer_alloc(size_t size)
339 {
340         GPUBuffer *buffer;
341
342         if (size == 0) {
343                 /* Early out, no lock needed in this case. */
344                 return NULL;
345         }
346
347         BLI_mutex_lock(&buffer_mutex);
348         buffer = gpu_buffer_alloc_intern(size);
349         BLI_mutex_unlock(&buffer_mutex);
350
351         return buffer;
352 }
353
354 /* release a GPUBuffer; does not free the actual buffer or its data,
355  * but rather moves it to the pool of recently-freed buffers for
356  * possible re-use
357  *
358  * Thread-unsafe version for internal usage only.
359  */
360 static void gpu_buffer_free_intern(GPUBuffer *buffer)
361 {
362         GPUBufferPool *pool;
363         int i;
364
365         if (!buffer)
366                 return;
367
368         pool = gpu_get_global_buffer_pool();
369
370         /* free the last used buffer in the queue if no more space, but only
371          * if we are in the main thread. for e.g. rendering or baking it can
372          * happen that we are in other thread and can't call OpenGL, in that
373          * case cleanup will be done GPU_buffer_pool_free_unused */
374         if (BLI_thread_is_main()) {
375                 /* in main thread, safe to decrease size of pool back
376                  * down to MAX_FREE_GPU_BUFFERS */
377                 while (pool->totbuf >= MAX_FREE_GPU_BUFFERS)
378                         gpu_buffer_pool_delete_last(pool);
379         }
380         else {
381                 /* outside of main thread, can't safely delete the
382                  * buffer, so increase pool size */
383                 if (pool->maxsize == pool->totbuf) {
384                         pool->maxsize += MAX_FREE_GPU_BUFFERS;
385                         pool->buffers = MEM_reallocN(pool->buffers,
386                                                      sizeof(GPUBuffer *) * pool->maxsize);
387                 }
388         }
389
390         /* shift pool entries up by one */
391         for (i = pool->totbuf; i > 0; i--)
392                 pool->buffers[i] = pool->buffers[i - 1];
393
394         /* insert the buffer into the beginning of the pool */
395         pool->buffers[0] = buffer;
396         pool->totbuf++;
397 }
398
399 /* Same as above, but safe for threading. */
400 void GPU_buffer_free(GPUBuffer *buffer)
401 {
402         if (!buffer) {
403                 /* Early output, no need to lock in this case, */
404                 return;
405         }
406
407         BLI_mutex_lock(&buffer_mutex);
408         gpu_buffer_free_intern(buffer);
409         BLI_mutex_unlock(&buffer_mutex);
410 }
411
412 void GPU_drawobject_free(DerivedMesh *dm)
413 {
414         GPUDrawObject *gdo;
415         int i;
416
417         if (!dm || !(gdo = dm->drawObject))
418                 return;
419
420         for (i = 0; i < gdo->totmaterial; i++) {
421                 if (gdo->materials[i].polys)
422                         MEM_freeN(gdo->materials[i].polys);
423         }
424
425         MEM_freeN(gdo->materials);
426         if (gdo->vert_points)
427                 MEM_freeN(gdo->vert_points);
428 #ifdef USE_GPU_POINT_LINK
429         MEM_freeN(gdo->vert_points_mem);
430 #endif
431         GPU_buffer_free(gdo->points);
432         GPU_buffer_free(gdo->normals);
433         GPU_buffer_free(gdo->uv);
434         GPU_buffer_free(gdo->uv_tex);
435         GPU_buffer_free(gdo->colors);
436         GPU_buffer_free(gdo->edges);
437         GPU_buffer_free(gdo->uvedges);
438         GPU_buffer_free(gdo->triangles);
439
440         MEM_freeN(gdo);
441         dm->drawObject = NULL;
442 }
443
444 static GPUBuffer *gpu_try_realloc(GPUBufferPool *pool, GPUBuffer *buffer, size_t size)
445 {
446         /* try freeing an entry from the pool
447          * and reallocating the buffer */
448         gpu_buffer_free_intern(buffer);
449
450         buffer = NULL;
451
452         while (pool->totbuf && !buffer) {
453                 gpu_buffer_pool_delete_last(pool);
454                 buffer = gpu_buffer_alloc_intern(size);
455         }
456
457         return buffer;
458 }
459
460 static GPUBuffer *gpu_buffer_setup(DerivedMesh *dm, GPUDrawObject *object,
461                                    int type, void *user, GPUBuffer *buffer)
462 {
463         GPUBufferPool *pool;
464         float *varray;
465         int *mat_orig_to_new;
466         int i;
467         const GPUBufferTypeSettings *ts = &gpu_buffer_type_settings[type];
468         GLenum target = ts->gl_buffer_type;
469         size_t size = gpu_buffer_size_from_type(dm, type);
470         GLboolean uploaded;
471
472         pool = gpu_get_global_buffer_pool();
473
474         BLI_mutex_lock(&buffer_mutex);
475
476         /* alloc a GPUBuffer; fall back to legacy mode on failure */
477         if (!buffer) {
478                 if (!(buffer = gpu_buffer_alloc_intern(size))) {
479                         BLI_mutex_unlock(&buffer_mutex);
480                         return NULL;
481                 }
482         }
483
484         mat_orig_to_new = MEM_mallocN(sizeof(*mat_orig_to_new) * dm->totmat,
485                                       "GPU_buffer_setup.mat_orig_to_new");
486         for (i = 0; i < object->totmaterial; i++) {
487                 /* map from original material index to new
488                  * GPUBufferMaterial index */
489                 mat_orig_to_new[object->materials[i].mat_nr] = i;
490         }
491
492         /* bind the buffer and discard previous data,
493          * avoids stalling gpu */
494         glBindBuffer(target, buffer->id);
495         glBufferData(target, buffer->size, NULL, GL_STATIC_DRAW);
496
497         /* attempt to map the buffer */
498         if (!(varray = glMapBuffer(target, GL_WRITE_ONLY))) {
499                 buffer = gpu_try_realloc(pool, buffer, size);
500
501                 /* allocation still failed; unfortunately we need to exit */
502                 if (!(buffer && (varray = glMapBuffer(target, GL_WRITE_ONLY)))) {
503                         if (buffer)
504                                 gpu_buffer_free_intern(buffer);
505                         BLI_mutex_unlock(&buffer_mutex);
506                         return NULL;
507                 }
508         }
509
510         uploaded = GL_FALSE;
511
512         /* attempt to upload the data to the VBO */
513         while (uploaded == GL_FALSE) {
514                 dm->copy_gpu_data(dm, type, varray, mat_orig_to_new, user);
515                 /* glUnmapBuffer returns GL_FALSE if
516                  * the data store is corrupted; retry
517                  * in that case */
518                 uploaded = glUnmapBuffer(target);
519         }
520         glBindBuffer(target, 0);
521
522         MEM_freeN(mat_orig_to_new);
523
524         BLI_mutex_unlock(&buffer_mutex);
525
526         return buffer;
527 }
528
529 /* get the GPUDrawObject buffer associated with a type */
530 static GPUBuffer **gpu_drawobject_buffer_from_type(GPUDrawObject *gdo, GPUBufferType type)
531 {
532         switch (type) {
533                 case GPU_BUFFER_VERTEX:
534                         return &gdo->points;
535                 case GPU_BUFFER_NORMAL:
536                         return &gdo->normals;
537                 case GPU_BUFFER_COLOR:
538                         return &gdo->colors;
539                 case GPU_BUFFER_UV:
540                         return &gdo->uv;
541                 case GPU_BUFFER_UV_TEXPAINT:
542                         return &gdo->uv_tex;
543                 case GPU_BUFFER_EDGE:
544                         return &gdo->edges;
545                 case GPU_BUFFER_UVEDGE:
546                         return &gdo->uvedges;
547                 case GPU_BUFFER_TRIANGLES:
548                         return &gdo->triangles;
549                 default:
550                         return NULL;
551         }
552 }
553
554 /* get the amount of space to allocate for a buffer of a particular type */
555 static size_t gpu_buffer_size_from_type(DerivedMesh *dm, GPUBufferType type)
556 {
557         const int components = gpu_buffer_type_settings[type].num_components;
558         switch (type) {
559                 case GPU_BUFFER_VERTEX:
560                         return sizeof(float) * components * (dm->drawObject->tot_loop_verts + dm->drawObject->tot_loose_point);
561                 case GPU_BUFFER_NORMAL:
562                         return sizeof(short) * components * dm->drawObject->tot_loop_verts;
563                 case GPU_BUFFER_COLOR:
564                         return sizeof(char) * components * dm->drawObject->tot_loop_verts;
565                 case GPU_BUFFER_UV:
566                         return sizeof(float) * components * dm->drawObject->tot_loop_verts;
567                 case GPU_BUFFER_UV_TEXPAINT:
568                         return sizeof(float) * components * dm->drawObject->tot_loop_verts;
569                 case GPU_BUFFER_EDGE:
570                         return sizeof(int) * components * dm->drawObject->totedge;
571                 case GPU_BUFFER_UVEDGE:
572                         return sizeof(int) * components * dm->drawObject->tot_loop_verts;
573                 case GPU_BUFFER_TRIANGLES:
574                         return sizeof(int) * components * dm->drawObject->tot_triangle_point;
575                 default:
576                         return -1;
577         }
578 }
579
580 /* call gpu_buffer_setup with settings for a particular type of buffer */
581 static GPUBuffer *gpu_buffer_setup_type(DerivedMesh *dm, GPUBufferType type, GPUBuffer *buf)
582 {
583         void *user_data = NULL;
584
585         /* special handling for MCol and UV buffers */
586         if (type == GPU_BUFFER_COLOR) {
587                 if (!(user_data = DM_get_loop_data_layer(dm, dm->drawObject->colType)))
588                         return NULL;
589         }
590         else if (ELEM(type, GPU_BUFFER_UV, GPU_BUFFER_UV_TEXPAINT)) {
591                 if (!DM_get_loop_data_layer(dm, CD_MLOOPUV))
592                         return NULL;
593         }
594
595         buf = gpu_buffer_setup(dm, dm->drawObject, type, user_data, buf);
596
597         return buf;
598 }
599
600 /* get the buffer of `type', initializing the GPUDrawObject and
601  * buffer if needed */
602 static GPUBuffer *gpu_buffer_setup_common(DerivedMesh *dm, GPUBufferType type, bool update)
603 {
604         GPUBuffer **buf;
605
606         if (!dm->drawObject)
607                 dm->drawObject = dm->gpuObjectNew(dm);
608
609         buf = gpu_drawobject_buffer_from_type(dm->drawObject, type);
610         if (!(*buf))
611                 *buf = gpu_buffer_setup_type(dm, type, NULL);
612         else if (update)
613                 *buf = gpu_buffer_setup_type(dm, type, *buf);
614
615         return *buf;
616 }
617
618 void GPU_vertex_setup(DerivedMesh *dm)
619 {
620         if (!gpu_buffer_setup_common(dm, GPU_BUFFER_VERTEX, false))
621                 return;
622
623         glEnableClientState(GL_VERTEX_ARRAY);
624         glBindBuffer(GL_ARRAY_BUFFER, dm->drawObject->points->id);
625         glVertexPointer(3, GL_FLOAT, 0, 0);
626         
627         GLStates |= GPU_BUFFER_VERTEX_STATE;
628 }
629
630 void GPU_normal_setup(DerivedMesh *dm)
631 {
632         if (!gpu_buffer_setup_common(dm, GPU_BUFFER_NORMAL, false))
633                 return;
634
635         glEnableClientState(GL_NORMAL_ARRAY);
636         glBindBuffer(GL_ARRAY_BUFFER, dm->drawObject->normals->id);
637         glNormalPointer(GL_SHORT, 4 * sizeof(short), 0);
638
639         GLStates |= GPU_BUFFER_NORMAL_STATE;
640 }
641
642 void GPU_uv_setup(DerivedMesh *dm)
643 {
644         if (!gpu_buffer_setup_common(dm, GPU_BUFFER_UV, false))
645                 return;
646
647         glEnableClientState(GL_TEXTURE_COORD_ARRAY);
648         glBindBuffer(GL_ARRAY_BUFFER, dm->drawObject->uv->id);
649         glTexCoordPointer(2, GL_FLOAT, 0, 0);
650
651         GLStates |= GPU_BUFFER_TEXCOORD_UNIT_0_STATE;
652 }
653
654 void GPU_texpaint_uv_setup(DerivedMesh *dm)
655 {
656         if (!gpu_buffer_setup_common(dm, GPU_BUFFER_UV_TEXPAINT, false))
657                 return;
658
659         glEnableClientState(GL_TEXTURE_COORD_ARRAY);
660         glBindBuffer(GL_ARRAY_BUFFER, dm->drawObject->uv_tex->id);
661         glTexCoordPointer(2, GL_FLOAT, 4 * sizeof(float), 0);
662         glClientActiveTexture(GL_TEXTURE2);
663         glEnableClientState(GL_TEXTURE_COORD_ARRAY);
664         glTexCoordPointer(2, GL_FLOAT, 4 * sizeof(float), BUFFER_OFFSET(2 * sizeof(float)));
665         glClientActiveTexture(GL_TEXTURE0);
666
667         GLStates |= GPU_BUFFER_TEXCOORD_UNIT_0_STATE | GPU_BUFFER_TEXCOORD_UNIT_2_STATE;
668 }
669
670
671 void GPU_color_setup(DerivedMesh *dm, int colType)
672 {
673         bool update = false;
674
675         if (!dm->drawObject) {
676                 /* XXX Not really nice, but we need a valid gpu draw object to set the colType...
677                  *     Else we would have to add a new param to gpu_buffer_setup_common. */
678                 dm->drawObject = dm->gpuObjectNew(dm);
679                 dm->dirty &= ~DM_DIRTY_MCOL_UPDATE_DRAW;
680                 dm->drawObject->colType = colType;
681         }
682         /* In paint mode, dm may stay the same during stroke, however we still want to update colors!
683          * Also check in case we changed color type (i.e. which MCol cdlayer we use). */
684         else if ((dm->dirty & DM_DIRTY_MCOL_UPDATE_DRAW) || (colType != dm->drawObject->colType)) {
685                 update = true;
686                 dm->dirty &= ~DM_DIRTY_MCOL_UPDATE_DRAW;
687                 dm->drawObject->colType = colType;
688         }
689
690         if (!gpu_buffer_setup_common(dm, GPU_BUFFER_COLOR, update))
691                 return;
692
693         glEnableClientState(GL_COLOR_ARRAY);
694         glBindBuffer(GL_ARRAY_BUFFER, dm->drawObject->colors->id);
695         glColorPointer(3, GL_UNSIGNED_BYTE, 0, 0);
696
697         GLStates |= GPU_BUFFER_COLOR_STATE;
698 }
699
700 void GPU_buffer_bind_as_color(GPUBuffer *buffer)
701 {
702         glEnableClientState(GL_COLOR_ARRAY);
703         glBindBuffer(GL_ARRAY_BUFFER, buffer->id);
704         glColorPointer(4, GL_UNSIGNED_BYTE, 0, 0);
705
706         GLStates |= GPU_BUFFER_COLOR_STATE;
707 }
708
709
710 void GPU_edge_setup(DerivedMesh *dm)
711 {
712         if (!gpu_buffer_setup_common(dm, GPU_BUFFER_EDGE, false))
713                 return;
714
715         if (!gpu_buffer_setup_common(dm, GPU_BUFFER_VERTEX, false))
716                 return;
717
718         glEnableClientState(GL_VERTEX_ARRAY);
719         glBindBuffer(GL_ARRAY_BUFFER, dm->drawObject->points->id);
720         glVertexPointer(3, GL_FLOAT, 0, 0);
721         
722         glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, dm->drawObject->edges->id);
723
724         GLStates |= (GPU_BUFFER_VERTEX_STATE | GPU_BUFFER_ELEMENT_STATE);
725 }
726
727 void GPU_uvedge_setup(DerivedMesh *dm)
728 {
729         if (!gpu_buffer_setup_common(dm, GPU_BUFFER_UVEDGE, false))
730                 return;
731
732         glEnableClientState(GL_VERTEX_ARRAY);
733         glBindBuffer(GL_ARRAY_BUFFER, dm->drawObject->uvedges->id);
734         glVertexPointer(2, GL_FLOAT, 0, 0);
735         
736         GLStates |= GPU_BUFFER_VERTEX_STATE;
737 }
738
739 void GPU_triangle_setup(struct DerivedMesh *dm)
740 {
741         if (!gpu_buffer_setup_common(dm, GPU_BUFFER_TRIANGLES, false))
742                 return;
743
744         glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, dm->drawObject->triangles->id);
745         GLStates |= GPU_BUFFER_ELEMENT_STATE;
746 }
747
748 static int GPU_typesize(int type)
749 {
750         switch (type) {
751                 case GL_FLOAT:
752                         return sizeof(float);
753                 case GL_INT:
754                         return sizeof(int);
755                 case GL_UNSIGNED_INT:
756                         return sizeof(unsigned int);
757                 case GL_BYTE:
758                         return sizeof(char);
759                 case GL_UNSIGNED_BYTE:
760                         return sizeof(unsigned char);
761                 default:
762                         return 0;
763         }
764 }
765
766 int GPU_attrib_element_size(GPUAttrib data[], int numdata)
767 {
768         int i, elementsize = 0;
769
770         for (i = 0; i < numdata; i++) {
771                 int typesize = GPU_typesize(data[i].type);
772                 if (typesize != 0)
773                         elementsize += typesize * data[i].size;
774         }
775         return elementsize;
776 }
777
778 void GPU_interleaved_attrib_setup(GPUBuffer *buffer, GPUAttrib data[], int numdata, int element_size)
779 {
780         int i;
781         int elementsize;
782         size_t offset = 0;
783
784         for (i = 0; i < MAX_GPU_ATTRIB_DATA; i++) {
785                 if (attribData[i].index != -1) {
786                         glDisableVertexAttribArray(attribData[i].index);
787                 }
788                 else
789                         break;
790         }
791         if (element_size == 0)
792                 elementsize = GPU_attrib_element_size(data, numdata);
793         else
794                 elementsize = element_size;
795
796         glBindBuffer(GL_ARRAY_BUFFER, buffer->id);
797         
798         for (i = 0; i < numdata; i++) {
799                 glEnableVertexAttribArray(data[i].index);
800                 int info = 0;
801                 if (data[i].type == GL_UNSIGNED_BYTE) {
802                         info |= GPU_ATTR_INFO_SRGB;
803                 }
804                 glUniform1i(data[i].info_index, info);
805
806                 glVertexAttribPointer(data[i].index, data[i].size, data[i].type,
807                                          GL_TRUE, elementsize, BUFFER_OFFSET(offset));
808                 offset += data[i].size * GPU_typesize(data[i].type);
809                 
810                 attribData[i].index = data[i].index;
811                 attribData[i].size = data[i].size;
812                 attribData[i].type = data[i].type;
813         }
814         
815         attribData[numdata].index = -1; 
816 }
817
818 void GPU_interleaved_attrib_unbind(void)
819 {
820         int i;
821         for (i = 0; i < MAX_GPU_ATTRIB_DATA; i++) {
822                 if (attribData[i].index != -1) {
823                         glDisableVertexAttribArray(attribData[i].index);
824                 }
825                 else
826                         break;
827         }
828         attribData[0].index = -1;
829 }
830
831 void GPU_buffers_unbind(void)
832 {
833         int i;
834
835         if (GLStates & GPU_BUFFER_VERTEX_STATE)
836                 glDisableClientState(GL_VERTEX_ARRAY);
837         if (GLStates & GPU_BUFFER_NORMAL_STATE)
838                 glDisableClientState(GL_NORMAL_ARRAY);
839         if (GLStates & GPU_BUFFER_TEXCOORD_UNIT_0_STATE)
840                 glDisableClientState(GL_TEXTURE_COORD_ARRAY);
841         if (GLStates & GPU_BUFFER_TEXCOORD_UNIT_2_STATE) {
842                 glClientActiveTexture(GL_TEXTURE2);
843                 glDisableClientState(GL_TEXTURE_COORD_ARRAY);
844                 glClientActiveTexture(GL_TEXTURE0);
845         }
846         if (GLStates & GPU_BUFFER_COLOR_STATE)
847                 glDisableClientState(GL_COLOR_ARRAY);
848         if (GLStates & GPU_BUFFER_ELEMENT_STATE)
849                 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
850
851         GLStates &= ~(GPU_BUFFER_VERTEX_STATE | GPU_BUFFER_NORMAL_STATE |
852                       GPU_BUFFER_TEXCOORD_UNIT_0_STATE | GPU_BUFFER_TEXCOORD_UNIT_2_STATE |
853                       GPU_BUFFER_COLOR_STATE | GPU_BUFFER_ELEMENT_STATE);
854
855         for (i = 0; i < MAX_GPU_ATTRIB_DATA; i++) {
856                 if (attribData[i].index != -1) {
857                         glDisableVertexAttribArray(attribData[i].index);
858                 }
859                 else
860                         break;
861         }
862         attribData[0].index = -1;
863
864         glBindBuffer(GL_ARRAY_BUFFER, 0);
865 }
866
867 void GPU_color_switch(int mode)
868 {
869         if (mode) {
870                 if (!(GLStates & GPU_BUFFER_COLOR_STATE))
871                         glEnableClientState(GL_COLOR_ARRAY);
872                 GLStates |= GPU_BUFFER_COLOR_STATE;
873         }
874         else {
875                 if (GLStates & GPU_BUFFER_COLOR_STATE)
876                         glDisableClientState(GL_COLOR_ARRAY);
877                 GLStates &= ~GPU_BUFFER_COLOR_STATE;
878         }
879 }
880
881 static int gpu_binding_type_gl[] =
882 {
883         GL_ARRAY_BUFFER,
884         GL_ELEMENT_ARRAY_BUFFER
885 };
886
887 void *GPU_buffer_lock(GPUBuffer *buffer, GPUBindingType binding)
888 {
889         float *varray;
890         int bindtypegl;
891
892         if (!buffer)
893                 return 0;
894
895         bindtypegl = gpu_binding_type_gl[binding];
896         glBindBuffer(bindtypegl, buffer->id);
897         varray = glMapBuffer(bindtypegl, GL_WRITE_ONLY);
898         return varray;
899 }
900
901 void *GPU_buffer_lock_stream(GPUBuffer *buffer, GPUBindingType binding)
902 {
903         float *varray;
904         int bindtypegl;
905
906         if (!buffer)
907                 return 0;
908
909         bindtypegl = gpu_binding_type_gl[binding];
910         glBindBuffer(bindtypegl, buffer->id);
911         /* discard previous data, avoid stalling gpu */
912         glBufferData(bindtypegl, buffer->size, 0, GL_STREAM_DRAW);
913         varray = glMapBuffer(bindtypegl, GL_WRITE_ONLY);
914         return varray;
915 }
916
917 void GPU_buffer_unlock(GPUBuffer *UNUSED(buffer), GPUBindingType binding)
918 {
919         int bindtypegl = gpu_binding_type_gl[binding];
920         /* note: this operation can fail, could return
921                  * an error code from this function? */
922         glUnmapBuffer(bindtypegl);
923         glBindBuffer(bindtypegl, 0);
924 }
925
926 void GPU_buffer_bind(GPUBuffer *buffer, GPUBindingType binding)
927 {
928         int bindtypegl = gpu_binding_type_gl[binding];
929         glBindBuffer(bindtypegl, buffer->id);
930 }
931
932 void GPU_buffer_unbind(GPUBuffer *UNUSED(buffer), GPUBindingType binding)
933 {
934         int bindtypegl = gpu_binding_type_gl[binding];
935         glBindBuffer(bindtypegl, 0);
936 }
937
938 /* used for drawing edges */
939 void GPU_buffer_draw_elements(GPUBuffer *UNUSED(elements), unsigned int mode, int start, int count)
940 {
941         glDrawElements(mode, count, GL_UNSIGNED_INT, BUFFER_OFFSET(start * sizeof(unsigned int)));
942 }
943
944
945 /* XXX: the rest of the code in this file is used for optimized PBVH
946  * drawing and doesn't interact at all with the buffer code above */
947
948 /* Convenience struct for building the VBO. */
949 typedef struct {
950         float co[3];
951         short no[3];
952
953         /* inserting this to align the 'color' field to a four-byte
954          * boundary; drastically increases viewport performance on my
955          * drivers (Gallium/Radeon) --nicholasbishop */
956         char pad[2];
957         
958         unsigned char color[3];
959 } VertexBufferFormat;
960
961 struct GPU_PBVH_Buffers {
962         /* opengl buffer handles */
963         GPUBuffer *vert_buf, *index_buf, *index_buf_fast;
964         GLenum index_type;
965
966         int *baseelemarray;
967         void **baseindex;
968
969         /* mesh pointers in case buffer allocation fails */
970         const MPoly *mpoly;
971         const MLoop *mloop;
972         const MLoopTri *looptri;
973         const MVert *mvert;
974
975         const int *face_indices;
976         int        face_indices_len;
977         const float *vmask;
978
979         /* grid pointers */
980         CCGKey gridkey;
981         CCGElem **grids;
982         const DMFlagMat *grid_flag_mats;
983         BLI_bitmap * const *grid_hidden;
984         const int *grid_indices;
985         int totgrid;
986         bool has_hidden;
987         bool is_index_buf_global;  /* Means index_buf uses global bvh's grid_common_gpu_buffer, **DO NOT** free it! */
988
989         bool use_bmesh;
990
991         unsigned int tot_tri, tot_quad;
992
993         /* The PBVH ensures that either all faces in the node are
994          * smooth-shaded or all faces are flat-shaded */
995         bool smooth;
996
997         bool show_diffuse_color;
998         bool use_matcaps;
999         float diffuse_color[4];
1000 };
1001
1002 static float gpu_color_from_mask(float mask)
1003 {
1004         return 1.0f - mask * 0.75f;
1005 }
1006
1007 static void gpu_color_from_mask_copy(float mask, const float diffuse_color[4], unsigned char out[3])
1008 {
1009         float mask_color;
1010
1011         mask_color = gpu_color_from_mask(mask) * 255.0f;
1012
1013         out[0] = diffuse_color[0] * mask_color;
1014         out[1] = diffuse_color[1] * mask_color;
1015         out[2] = diffuse_color[2] * mask_color;
1016 }
1017
1018 static void gpu_color_from_mask_quad_copy(const CCGKey *key,
1019                                           CCGElem *a, CCGElem *b,
1020                                           CCGElem *c, CCGElem *d,
1021                                           const float *diffuse_color,
1022                                           unsigned char out[3])
1023 {
1024         float mask_color =
1025             gpu_color_from_mask((*CCG_elem_mask(key, a) +
1026                                  *CCG_elem_mask(key, b) +
1027                                  *CCG_elem_mask(key, c) +
1028                                  *CCG_elem_mask(key, d)) * 0.25f) * 255.0f;
1029
1030         out[0] = diffuse_color[0] * mask_color;
1031         out[1] = diffuse_color[1] * mask_color;
1032         out[2] = diffuse_color[2] * mask_color;
1033 }
1034
1035 void GPU_update_mesh_pbvh_buffers(
1036         GPU_PBVH_Buffers *buffers, const MVert *mvert,
1037         const int *vert_indices, int totvert, const float *vmask,
1038         const int (*face_vert_indices)[4], bool show_diffuse_color)
1039 {
1040         VertexBufferFormat *vert_data;
1041         int i, j;
1042
1043         buffers->vmask = vmask;
1044         buffers->show_diffuse_color = show_diffuse_color;
1045         buffers->use_matcaps = GPU_material_use_matcaps_get();
1046
1047         {
1048                 int totelem = (buffers->smooth ? totvert : (buffers->tot_tri * 3));
1049                 float diffuse_color[4] = {0.8f, 0.8f, 0.8f, 0.8f};
1050
1051                 if (buffers->use_matcaps)
1052                         diffuse_color[0] = diffuse_color[1] = diffuse_color[2] = 1.0;
1053                 else if (show_diffuse_color) {
1054                         const MLoopTri *lt = &buffers->looptri[buffers->face_indices[0]];
1055                         const MPoly *mp = &buffers->mpoly[lt->poly];
1056
1057                         GPU_material_diffuse_get(mp->mat_nr + 1, diffuse_color);
1058                 }
1059
1060                 copy_v4_v4(buffers->diffuse_color, diffuse_color);
1061
1062                 /* Build VBO */
1063                 if (buffers->vert_buf)
1064                         GPU_buffer_free(buffers->vert_buf);
1065                 buffers->vert_buf = GPU_buffer_alloc(sizeof(VertexBufferFormat) * totelem);
1066                 vert_data = GPU_buffer_lock(buffers->vert_buf, GPU_BINDING_ARRAY);
1067
1068                 if (vert_data) {
1069                         /* Vertex data is shared if smooth-shaded, but separate
1070                          * copies are made for flat shading because normals
1071                          * shouldn't be shared. */
1072                         if (buffers->smooth) {
1073                                 for (i = 0; i < totvert; ++i) {
1074                                         const MVert *v = &mvert[vert_indices[i]];
1075                                         VertexBufferFormat *out = vert_data + i;
1076
1077                                         copy_v3_v3(out->co, v->co);
1078                                         memcpy(out->no, v->no, sizeof(short) * 3);
1079                                 }
1080
1081 #define UPDATE_VERTEX(face, vertex, index, diffuse_color) \
1082                                 { \
1083                                         VertexBufferFormat *out = vert_data + face_vert_indices[face][index]; \
1084                                         if (vmask) \
1085                                                 gpu_color_from_mask_copy(vmask[vertex], diffuse_color, out->color); \
1086                                         else \
1087                                                 rgb_float_to_uchar(out->color, diffuse_color); \
1088                                 } (void)0
1089
1090                                 for (i = 0; i < buffers->face_indices_len; i++) {
1091                                         const MLoopTri *lt = &buffers->looptri[buffers->face_indices[i]];
1092                                         const unsigned int vtri[3] = {
1093                                             buffers->mloop[lt->tri[0]].v,
1094                                             buffers->mloop[lt->tri[1]].v,
1095                                             buffers->mloop[lt->tri[2]].v,
1096                                         };
1097
1098                                         UPDATE_VERTEX(i, vtri[0], 0, diffuse_color);
1099                                         UPDATE_VERTEX(i, vtri[1], 1, diffuse_color);
1100                                         UPDATE_VERTEX(i, vtri[2], 2, diffuse_color);
1101                                 }
1102 #undef UPDATE_VERTEX
1103                         }
1104                         else {
1105                                 /* calculate normal for each polygon only once */
1106                                 unsigned int mpoly_prev = UINT_MAX;
1107                                 short no[3];
1108
1109                                 for (i = 0; i < buffers->face_indices_len; ++i) {
1110                                         const MLoopTri *lt = &buffers->looptri[buffers->face_indices[i]];
1111                                         const unsigned int vtri[3] = {
1112                                             buffers->mloop[lt->tri[0]].v,
1113                                             buffers->mloop[lt->tri[1]].v,
1114                                             buffers->mloop[lt->tri[2]].v,
1115                                         };
1116
1117                                         float fmask;
1118
1119                                         if (paint_is_face_hidden(lt, mvert, buffers->mloop))
1120                                                 continue;
1121
1122                                         /* Face normal and mask */
1123                                         if (lt->poly != mpoly_prev) {
1124                                                 const MPoly *mp = &buffers->mpoly[lt->poly];
1125                                                 float fno[3];
1126                                                 BKE_mesh_calc_poly_normal(mp, &buffers->mloop[mp->loopstart], mvert, fno);
1127                                                 normal_float_to_short_v3(no, fno);
1128                                                 mpoly_prev = lt->poly;
1129                                         }
1130
1131                                         if (vmask) {
1132                                                 fmask = (vmask[vtri[0]] +
1133                                                          vmask[vtri[1]] +
1134                                                          vmask[vtri[2]]) / 3.0f;
1135                                         }
1136
1137                                         for (j = 0; j < 3; j++) {
1138                                                 const MVert *v = &mvert[vtri[j]];
1139                                                 VertexBufferFormat *out = vert_data;
1140
1141                                                 copy_v3_v3(out->co, v->co);
1142                                                 copy_v3_v3_short(out->no, no);
1143
1144                                                 if (vmask)
1145                                                         gpu_color_from_mask_copy(fmask, diffuse_color, out->color);
1146                                                 else
1147                                                         rgb_float_to_uchar(out->color, diffuse_color);
1148
1149                                                 vert_data++;
1150                                         }
1151                                 }
1152                         }
1153
1154                         GPU_buffer_unlock(buffers->vert_buf, GPU_BINDING_ARRAY);
1155                 }
1156                 else {
1157                         GPU_buffer_free(buffers->vert_buf);
1158                         buffers->vert_buf = NULL;
1159                 }
1160         }
1161
1162         buffers->mvert = mvert;
1163 }
1164
1165 GPU_PBVH_Buffers *GPU_build_mesh_pbvh_buffers(
1166         const int (*face_vert_indices)[4],
1167         const MPoly *mpoly, const MLoop *mloop, const MLoopTri *looptri,
1168         const MVert *mvert,
1169         const int *face_indices,
1170         const int  face_indices_len)
1171 {
1172         GPU_PBVH_Buffers *buffers;
1173         unsigned short *tri_data;
1174         int i, j, tottri;
1175
1176         buffers = MEM_callocN(sizeof(GPU_PBVH_Buffers), "GPU_Buffers");
1177         buffers->index_type = GL_UNSIGNED_SHORT;
1178         buffers->smooth = mpoly[looptri[face_indices[0]].poly].flag & ME_SMOOTH;
1179
1180         buffers->show_diffuse_color = false;
1181         buffers->use_matcaps = false;
1182
1183         /* Count the number of visible triangles */
1184         for (i = 0, tottri = 0; i < face_indices_len; ++i) {
1185                 const MLoopTri *lt = &looptri[face_indices[i]];
1186                 if (!paint_is_face_hidden(lt, mvert, mloop))
1187                         tottri++;
1188         }
1189
1190         if (tottri == 0) {
1191                 buffers->tot_tri = 0;
1192
1193                 buffers->mpoly = mpoly;
1194                 buffers->mloop = mloop;
1195                 buffers->looptri = looptri;
1196                 buffers->face_indices = face_indices;
1197                 buffers->face_indices_len = 0;
1198
1199                 return buffers;
1200         }
1201
1202         /* An element index buffer is used for smooth shading, but flat
1203          * shading requires separate vertex normals so an index buffer is
1204          * can't be used there. */
1205         if (buffers->smooth) {
1206                 buffers->index_buf = GPU_buffer_alloc(sizeof(unsigned short) * tottri * 3);
1207                 buffers->is_index_buf_global = false;
1208         }
1209
1210         if (buffers->index_buf) {
1211                 /* Fill the triangle buffer */
1212                 tri_data = GPU_buffer_lock(buffers->index_buf, GPU_BINDING_INDEX);
1213                 if (tri_data) {
1214                         for (i = 0; i < face_indices_len; ++i) {
1215                                 const MLoopTri *lt = &looptri[face_indices[i]];
1216
1217                                 /* Skip hidden faces */
1218                                 if (paint_is_face_hidden(lt, mvert, mloop))
1219                                         continue;
1220
1221                                 for (j = 0; j < 3; ++j) {
1222                                         *tri_data = face_vert_indices[i][j];
1223                                         tri_data++;
1224                                 }
1225                         }
1226                         GPU_buffer_unlock(buffers->index_buf, GPU_BINDING_INDEX);
1227                 }
1228                 else {
1229                         if (!buffers->is_index_buf_global) {
1230                                 GPU_buffer_free(buffers->index_buf);
1231                         }
1232                         buffers->index_buf = NULL;
1233                         buffers->is_index_buf_global = false;
1234                 }
1235         }
1236
1237         buffers->tot_tri = tottri;
1238
1239         buffers->mpoly = mpoly;
1240         buffers->mloop = mloop;
1241         buffers->looptri = looptri;
1242
1243         buffers->face_indices = face_indices;
1244         buffers->face_indices_len = face_indices_len;
1245
1246         return buffers;
1247 }
1248
1249 void GPU_update_grid_pbvh_buffers(GPU_PBVH_Buffers *buffers, CCGElem **grids,
1250                                   const DMFlagMat *grid_flag_mats, int *grid_indices,
1251                                   int totgrid, const CCGKey *key, bool show_diffuse_color)
1252 {
1253         VertexBufferFormat *vert_data;
1254         int i, j, k, x, y;
1255
1256         buffers->show_diffuse_color = show_diffuse_color;
1257         buffers->use_matcaps = GPU_material_use_matcaps_get();
1258         buffers->smooth = grid_flag_mats[grid_indices[0]].flag & ME_SMOOTH;
1259
1260         /* Build VBO */
1261         if (buffers->vert_buf) {
1262                 const int has_mask = key->has_mask;
1263                 float diffuse_color[4] = {0.8f, 0.8f, 0.8f, 1.0f};
1264
1265                 if (buffers->use_matcaps)
1266                         diffuse_color[0] = diffuse_color[1] = diffuse_color[2] = 1.0;
1267                 else if (show_diffuse_color) {
1268                         const DMFlagMat *flags = &grid_flag_mats[grid_indices[0]];
1269
1270                         GPU_material_diffuse_get(flags->mat_nr + 1, diffuse_color);
1271                 }
1272
1273                 copy_v4_v4(buffers->diffuse_color, diffuse_color);
1274
1275                 vert_data = GPU_buffer_lock_stream(buffers->vert_buf, GPU_BINDING_ARRAY);
1276                 if (vert_data) {
1277                         for (i = 0; i < totgrid; ++i) {
1278                                 VertexBufferFormat *vd = vert_data;
1279                                 CCGElem *grid = grids[grid_indices[i]];
1280
1281                                 for (y = 0; y < key->grid_size; y++) {
1282                                         for (x = 0; x < key->grid_size; x++) {
1283                                                 CCGElem *elem = CCG_grid_elem(key, grid, x, y);
1284                                                 
1285                                                 copy_v3_v3(vd->co, CCG_elem_co(key, elem));
1286                                                 if (buffers->smooth) {
1287                                                         normal_float_to_short_v3(vd->no, CCG_elem_no(key, elem));
1288
1289                                                         if (has_mask) {
1290                                                                 gpu_color_from_mask_copy(*CCG_elem_mask(key, elem),
1291                                                                                          diffuse_color, vd->color);
1292                                                         }
1293                                                 }
1294                                                 vd++;
1295                                         }
1296                                 }
1297                                 
1298                                 if (!buffers->smooth) {
1299                                         /* for flat shading, recalc normals and set the last vertex of
1300                                          * each triangle in the index buffer to have the flat normal as
1301                                          * that is what opengl will use */
1302                                         for (j = 0; j < key->grid_size - 1; j++) {
1303                                                 for (k = 0; k < key->grid_size - 1; k++) {
1304                                                         CCGElem *elems[4] = {
1305                                                                 CCG_grid_elem(key, grid, k, j + 1),
1306                                                                 CCG_grid_elem(key, grid, k + 1, j + 1),
1307                                                                 CCG_grid_elem(key, grid, k + 1, j),
1308                                                                 CCG_grid_elem(key, grid, k, j)
1309                                                         };
1310                                                         float fno[3];
1311
1312                                                         normal_quad_v3(fno,
1313                                                                        CCG_elem_co(key, elems[0]),
1314                                                                        CCG_elem_co(key, elems[1]),
1315                                                                        CCG_elem_co(key, elems[2]),
1316                                                                        CCG_elem_co(key, elems[3]));
1317
1318                                                         vd = vert_data + (j + 1) * key->grid_size + k;
1319                                                         normal_float_to_short_v3(vd->no, fno);
1320
1321                                                         if (has_mask) {
1322                                                                 gpu_color_from_mask_quad_copy(key,
1323                                                                                               elems[0],
1324                                                                                               elems[1],
1325                                                                                               elems[2],
1326                                                                                               elems[3],
1327                                                                                               diffuse_color,
1328                                                                                               vd->color);
1329                                                         }
1330                                                 }
1331                                         }
1332                                 }
1333
1334                                 vert_data += key->grid_area;
1335                         }
1336
1337                         GPU_buffer_unlock(buffers->vert_buf, GPU_BINDING_ARRAY);
1338                 }
1339                 else {
1340                         GPU_buffer_free(buffers->vert_buf);
1341                         buffers->vert_buf = NULL;
1342                 }
1343         }
1344
1345         buffers->grids = grids;
1346         buffers->grid_indices = grid_indices;
1347         buffers->totgrid = totgrid;
1348         buffers->grid_flag_mats = grid_flag_mats;
1349         buffers->gridkey = *key;
1350
1351         //printf("node updated %p\n", buffers);
1352 }
1353
1354 /* Build the element array buffer of grid indices using either
1355  * unsigned shorts or unsigned ints. */
1356 #define FILL_QUAD_BUFFER(type_, tot_quad_, buffer_)                     \
1357     {                                                                   \
1358         type_ *tri_data;                                                \
1359         int offset = 0;                                                 \
1360         int i, j, k;                                                    \
1361         buffer_ = GPU_buffer_alloc(sizeof(type_) * (tot_quad_) * 6);    \
1362                                                                         \
1363         /* Fill the buffer */                                           \
1364         tri_data = GPU_buffer_lock(buffer_, GPU_BINDING_INDEX);         \
1365         if (tri_data) {                                                 \
1366             for (i = 0; i < totgrid; ++i) {                             \
1367                 BLI_bitmap *gh = NULL;                                  \
1368                 if (grid_hidden)                                        \
1369                     gh = grid_hidden[(grid_indices)[i]];                \
1370                                                                         \
1371                 for (j = 0; j < gridsize - 1; ++j) {                    \
1372                     for (k = 0; k < gridsize - 1; ++k) {                \
1373                         /* Skip hidden grid face */                     \
1374                         if (gh &&                                       \
1375                             paint_is_grid_face_hidden(gh,               \
1376                                                       gridsize, k, j))  \
1377                             continue;                                    \
1378                                                                           \
1379                         *(tri_data++) = offset + j * gridsize + k + 1;     \
1380                         *(tri_data++) = offset + j * gridsize + k;          \
1381                         *(tri_data++) = offset + (j + 1) * gridsize + k;     \
1382                                                                              \
1383                         *(tri_data++) = offset + (j + 1) * gridsize + k + 1; \
1384                         *(tri_data++) = offset + j * gridsize + k + 1;       \
1385                         *(tri_data++) = offset + (j + 1) * gridsize + k;    \
1386                     }                                                      \
1387                 }                                                         \
1388                                                                          \
1389                 offset += gridsize * gridsize;                          \
1390             }                                                           \
1391             GPU_buffer_unlock(buffer_, GPU_BINDING_INDEX);                         \
1392         }                                                               \
1393         else {                                                          \
1394             GPU_buffer_free(buffer_);                                   \
1395             (buffer_) = NULL;                                           \
1396         }                                                               \
1397     } (void)0
1398 /* end FILL_QUAD_BUFFER */
1399
1400 static GPUBuffer *gpu_get_grid_buffer(
1401         int gridsize, GLenum *index_type, unsigned *totquad, GridCommonGPUBuffer **grid_common_gpu_buffer)
1402 {
1403         /* used in the FILL_QUAD_BUFFER macro */
1404         BLI_bitmap * const *grid_hidden = NULL;
1405         const int *grid_indices = NULL;
1406         int totgrid = 1;
1407
1408         GridCommonGPUBuffer *gridbuff = *grid_common_gpu_buffer;
1409
1410         if (gridbuff == NULL) {
1411                 *grid_common_gpu_buffer = gridbuff = MEM_mallocN(sizeof(GridCommonGPUBuffer), __func__);
1412                 gridbuff->mres_buffer = NULL;
1413                 gridbuff->mres_prev_gridsize = -1;
1414                 gridbuff->mres_prev_index_type = 0;
1415                 gridbuff->mres_prev_totquad = 0;
1416         }
1417
1418         /* VBO is already built */
1419         if (gridbuff->mres_buffer && gridbuff->mres_prev_gridsize == gridsize) {
1420                 *index_type = gridbuff->mres_prev_index_type;
1421                 *totquad = gridbuff->mres_prev_totquad;
1422                 return gridbuff->mres_buffer;
1423         }
1424         /* we can't reuse old, delete the existing buffer */
1425         else if (gridbuff->mres_buffer) {
1426                 GPU_buffer_free(gridbuff->mres_buffer);
1427         }
1428
1429         /* Build new VBO */
1430         *totquad = (gridsize - 1) * (gridsize - 1);
1431
1432         if (gridsize * gridsize < USHRT_MAX) {
1433                 *index_type = GL_UNSIGNED_SHORT;
1434                 FILL_QUAD_BUFFER(unsigned short, *totquad, gridbuff->mres_buffer);
1435         }
1436         else {
1437                 *index_type = GL_UNSIGNED_INT;
1438                 FILL_QUAD_BUFFER(unsigned int, *totquad, gridbuff->mres_buffer);
1439         }
1440
1441         gridbuff->mres_prev_gridsize = gridsize;
1442         gridbuff->mres_prev_index_type = *index_type;
1443         gridbuff->mres_prev_totquad = *totquad;
1444         return gridbuff->mres_buffer;
1445 }
1446
1447 #define FILL_FAST_BUFFER(type_) \
1448 { \
1449         type_ *buffer; \
1450         buffers->index_buf_fast = GPU_buffer_alloc(sizeof(type_) * 6 * totgrid); \
1451         buffer = GPU_buffer_lock(buffers->index_buf_fast, GPU_BINDING_INDEX); \
1452         if (buffer) { \
1453                 int i; \
1454                 for (i = 0; i < totgrid; i++) { \
1455                         int currentquad = i * 6; \
1456                         buffer[currentquad]     = i * gridsize * gridsize + gridsize - 1; \
1457                         buffer[currentquad + 1] = i * gridsize * gridsize; \
1458                         buffer[currentquad + 2] = (i + 1) * gridsize * gridsize - gridsize; \
1459                         buffer[currentquad + 3] = (i + 1) * gridsize * gridsize - 1; \
1460                         buffer[currentquad + 4] = i * gridsize * gridsize + gridsize - 1; \
1461                         buffer[currentquad + 5] = (i + 1) * gridsize * gridsize - gridsize; \
1462                 } \
1463                 GPU_buffer_unlock(buffers->index_buf_fast, GPU_BINDING_INDEX); \
1464         } \
1465         else { \
1466                 GPU_buffer_free(buffers->index_buf_fast); \
1467                 buffers->index_buf_fast = NULL; \
1468         } \
1469 } (void)0
1470
1471 GPU_PBVH_Buffers *GPU_build_grid_pbvh_buffers(
1472         int *grid_indices, int totgrid, BLI_bitmap **grid_hidden, int gridsize, const CCGKey *key,
1473         GridCommonGPUBuffer **grid_common_gpu_buffer)
1474 {
1475         GPU_PBVH_Buffers *buffers;
1476         int totquad;
1477         int fully_visible_totquad = (gridsize - 1) * (gridsize - 1) * totgrid;
1478
1479         buffers = MEM_callocN(sizeof(GPU_PBVH_Buffers), "GPU_Buffers");
1480         buffers->grid_hidden = grid_hidden;
1481         buffers->totgrid = totgrid;
1482
1483         buffers->show_diffuse_color = false;
1484         buffers->use_matcaps = false;
1485
1486         /* Count the number of quads */
1487         totquad = BKE_pbvh_count_grid_quads(grid_hidden, grid_indices, totgrid, gridsize);
1488
1489         /* totally hidden node, return here to avoid BufferData with zero below. */
1490         if (totquad == 0)
1491                 return buffers;
1492
1493         /* create and fill indices of the fast buffer too */
1494         if (totgrid * gridsize * gridsize < USHRT_MAX) {
1495                 FILL_FAST_BUFFER(unsigned short);
1496         }
1497         else {
1498                 FILL_FAST_BUFFER(unsigned int);
1499         }
1500
1501         if (totquad == fully_visible_totquad) {
1502                 buffers->index_buf = gpu_get_grid_buffer(
1503                                          gridsize, &buffers->index_type, &buffers->tot_quad, grid_common_gpu_buffer);
1504                 buffers->has_hidden = false;
1505                 buffers->is_index_buf_global = true;
1506         }
1507         else {
1508                 buffers->tot_quad = totquad;
1509
1510                 if (totgrid * gridsize * gridsize < USHRT_MAX) {
1511                         buffers->index_type = GL_UNSIGNED_SHORT;
1512                         FILL_QUAD_BUFFER(unsigned short, totquad, buffers->index_buf);
1513                 }
1514                 else {
1515                         buffers->index_type = GL_UNSIGNED_INT;
1516                         FILL_QUAD_BUFFER(unsigned int, totquad, buffers->index_buf);
1517                 }
1518
1519                 buffers->has_hidden = true;
1520                 buffers->is_index_buf_global = false;
1521         }
1522
1523         /* Build coord/normal VBO */
1524         if (buffers->index_buf)
1525                 buffers->vert_buf = GPU_buffer_alloc(sizeof(VertexBufferFormat) * totgrid * key->grid_area);
1526
1527         if (GLEW_ARB_draw_elements_base_vertex /* 3.2 */) {
1528                 int i;
1529                 buffers->baseelemarray = MEM_mallocN(sizeof(int) * totgrid * 2, "GPU_PBVH_Buffers.baseelemarray");
1530                 buffers->baseindex = MEM_mallocN(sizeof(void *) * totgrid, "GPU_PBVH_Buffers.baseindex");
1531                 for (i = 0; i < totgrid; i++) {
1532                         buffers->baseelemarray[i] = buffers->tot_quad * 6;
1533                         buffers->baseelemarray[i + totgrid] = i * key->grid_area;
1534                         buffers->baseindex[i] = NULL;
1535                 }
1536         }
1537
1538         return buffers;
1539 }
1540
1541 #undef FILL_QUAD_BUFFER
1542
1543 /* Output a BMVert into a VertexBufferFormat array
1544  *
1545  * The vertex is skipped if hidden, otherwise the output goes into
1546  * index '*v_index' in the 'vert_data' array and '*v_index' is
1547  * incremented.
1548  */
1549 static void gpu_bmesh_vert_to_buffer_copy(BMVert *v,
1550                                           VertexBufferFormat *vert_data,
1551                                           int *v_index,
1552                                           const float fno[3],
1553                                           const float *fmask,
1554                                           const int cd_vert_mask_offset,
1555                                           const float diffuse_color[4])
1556 {
1557         if (!BM_elem_flag_test(v, BM_ELEM_HIDDEN)) {
1558                 VertexBufferFormat *vd = &vert_data[*v_index];
1559
1560                 /* Set coord, normal, and mask */
1561                 copy_v3_v3(vd->co, v->co);
1562                 normal_float_to_short_v3(vd->no, fno ? fno : v->no);
1563
1564                 gpu_color_from_mask_copy(
1565                         fmask ? *fmask :
1566                                 BM_ELEM_CD_GET_FLOAT(v, cd_vert_mask_offset),
1567                         diffuse_color,
1568                         vd->color);
1569
1570                 /* Assign index for use in the triangle index buffer */
1571                 /* note: caller must set:  bm->elem_index_dirty |= BM_VERT; */
1572                 BM_elem_index_set(v, (*v_index)); /* set_dirty! */
1573
1574                 (*v_index)++;
1575         }
1576 }
1577
1578 /* Return the total number of vertices that don't have BM_ELEM_HIDDEN set */
1579 static int gpu_bmesh_vert_visible_count(GSet *bm_unique_verts,
1580                                         GSet *bm_other_verts)
1581 {
1582         GSetIterator gs_iter;
1583         int totvert = 0;
1584
1585         GSET_ITER (gs_iter, bm_unique_verts) {
1586                 BMVert *v = BLI_gsetIterator_getKey(&gs_iter);
1587                 if (!BM_elem_flag_test(v, BM_ELEM_HIDDEN))
1588                         totvert++;
1589         }
1590         GSET_ITER (gs_iter, bm_other_verts) {
1591                 BMVert *v = BLI_gsetIterator_getKey(&gs_iter);
1592                 if (!BM_elem_flag_test(v, BM_ELEM_HIDDEN))
1593                         totvert++;
1594         }
1595
1596         return totvert;
1597 }
1598
1599 /* Return the total number of visible faces */
1600 static int gpu_bmesh_face_visible_count(GSet *bm_faces)
1601 {
1602         GSetIterator gh_iter;
1603         int totface = 0;
1604
1605         GSET_ITER (gh_iter, bm_faces) {
1606                 BMFace *f = BLI_gsetIterator_getKey(&gh_iter);
1607
1608                 if (!BM_elem_flag_test(f, BM_ELEM_HIDDEN))
1609                         totface++;
1610         }
1611
1612         return totface;
1613 }
1614
1615 /* Creates a vertex buffer (coordinate, normal, color) and, if smooth
1616  * shading, an element index buffer. */
1617 void GPU_update_bmesh_pbvh_buffers(GPU_PBVH_Buffers *buffers,
1618                                    BMesh *bm,
1619                                    GSet *bm_faces,
1620                                    GSet *bm_unique_verts,
1621                                    GSet *bm_other_verts,
1622                                    bool show_diffuse_color)
1623 {
1624         VertexBufferFormat *vert_data;
1625         void *tri_data;
1626         int tottri, totvert, maxvert = 0;
1627         float diffuse_color[4] = {0.8f, 0.8f, 0.8f, 1.0f};
1628
1629         /* TODO, make mask layer optional for bmesh buffer */
1630         const int cd_vert_mask_offset = CustomData_get_offset(&bm->vdata, CD_PAINT_MASK);
1631
1632         buffers->show_diffuse_color = show_diffuse_color;
1633         buffers->use_matcaps = GPU_material_use_matcaps_get();
1634
1635         /* Count visible triangles */
1636         tottri = gpu_bmesh_face_visible_count(bm_faces);
1637
1638         if (buffers->smooth) {
1639                 /* Count visible vertices */
1640                 totvert = gpu_bmesh_vert_visible_count(bm_unique_verts, bm_other_verts);
1641         }
1642         else
1643                 totvert = tottri * 3;
1644
1645         if (!tottri) {
1646                 buffers->tot_tri = 0;
1647                 return;
1648         }
1649
1650         if (buffers->use_matcaps)
1651                 diffuse_color[0] = diffuse_color[1] = diffuse_color[2] = 1.0;
1652         else if (show_diffuse_color) {
1653                 /* due to dynamic nature of dyntopo, only get first material */
1654                 GSetIterator gs_iter;
1655                 BMFace *f;
1656                 BLI_gsetIterator_init(&gs_iter, bm_faces);
1657                 f = BLI_gsetIterator_getKey(&gs_iter);
1658                 GPU_material_diffuse_get(f->mat_nr + 1, diffuse_color);
1659         }
1660
1661         copy_v4_v4(buffers->diffuse_color, diffuse_color);
1662
1663         /* Initialize vertex buffer */
1664         if (buffers->vert_buf)
1665                 GPU_buffer_free(buffers->vert_buf);
1666         buffers->vert_buf = GPU_buffer_alloc(sizeof(VertexBufferFormat) * totvert);
1667
1668         /* Fill vertex buffer */
1669         vert_data = GPU_buffer_lock(buffers->vert_buf, GPU_BINDING_ARRAY);
1670         if (vert_data) {
1671                 int v_index = 0;
1672
1673                 if (buffers->smooth) {
1674                         GSetIterator gs_iter;
1675
1676                         /* Vertices get an index assigned for use in the triangle
1677                          * index buffer */
1678                         bm->elem_index_dirty |= BM_VERT;
1679
1680                         GSET_ITER (gs_iter, bm_unique_verts) {
1681                                 gpu_bmesh_vert_to_buffer_copy(BLI_gsetIterator_getKey(&gs_iter),
1682                                                               vert_data, &v_index, NULL, NULL,
1683                                                               cd_vert_mask_offset, diffuse_color);
1684                         }
1685
1686                         GSET_ITER (gs_iter, bm_other_verts) {
1687                                 gpu_bmesh_vert_to_buffer_copy(BLI_gsetIterator_getKey(&gs_iter),
1688                                                               vert_data, &v_index, NULL, NULL,
1689                                                               cd_vert_mask_offset, diffuse_color);
1690                         }
1691
1692                         maxvert = v_index;
1693                 }
1694                 else {
1695                         GSetIterator gs_iter;
1696
1697                         GSET_ITER (gs_iter, bm_faces) {
1698                                 BMFace *f = BLI_gsetIterator_getKey(&gs_iter);
1699
1700                                 BLI_assert(f->len == 3);
1701
1702                                 if (!BM_elem_flag_test(f, BM_ELEM_HIDDEN)) {
1703                                         BMVert *v[3];
1704                                         float fmask = 0;
1705                                         int i;
1706
1707 #if 0
1708                                         BM_iter_as_array(bm, BM_VERTS_OF_FACE, f, (void**)v, 3);
1709 #endif
1710                                         BM_face_as_array_vert_tri(f, v);
1711
1712                                         /* Average mask value */
1713                                         for (i = 0; i < 3; i++) {
1714                                                 fmask += BM_ELEM_CD_GET_FLOAT(v[i], cd_vert_mask_offset);
1715                                         }
1716                                         fmask /= 3.0f;
1717                                         
1718                                         for (i = 0; i < 3; i++) {
1719                                                 gpu_bmesh_vert_to_buffer_copy(v[i], vert_data,
1720                                                                               &v_index, f->no, &fmask,
1721                                                                               cd_vert_mask_offset, diffuse_color);
1722                                         }
1723                                 }
1724                         }
1725
1726                         buffers->tot_tri = tottri;
1727                 }
1728
1729                 GPU_buffer_unlock(buffers->vert_buf, GPU_BINDING_ARRAY);
1730
1731                 /* gpu_bmesh_vert_to_buffer_copy sets dirty index values */
1732                 bm->elem_index_dirty |= BM_VERT;
1733         }
1734         else {
1735                 /* Memory map failed */
1736                 GPU_buffer_free(buffers->vert_buf);
1737                 buffers->vert_buf = NULL;
1738                 return;
1739         }
1740
1741         if (buffers->smooth) {
1742                 const int use_short = (maxvert < USHRT_MAX);
1743
1744                 /* Initialize triangle index buffer */
1745                 if (buffers->index_buf && !buffers->is_index_buf_global)
1746                         GPU_buffer_free(buffers->index_buf);
1747                 buffers->is_index_buf_global = false;
1748                 buffers->index_buf = GPU_buffer_alloc((use_short ?
1749                                                       sizeof(unsigned short) :
1750                                                       sizeof(unsigned int)) * 3 * tottri);
1751
1752                 /* Fill triangle index buffer */
1753                 tri_data = GPU_buffer_lock(buffers->index_buf, GPU_BINDING_INDEX);
1754                 if (tri_data) {
1755                         GSetIterator gs_iter;
1756
1757                         GSET_ITER (gs_iter, bm_faces) {
1758                                 BMFace *f = BLI_gsetIterator_getKey(&gs_iter);
1759
1760                                 if (!BM_elem_flag_test(f, BM_ELEM_HIDDEN)) {
1761                                         BMLoop *l_iter;
1762                                         BMLoop *l_first;
1763
1764                                         l_iter = l_first = BM_FACE_FIRST_LOOP(f);
1765                                         do {
1766                                                 BMVert *v = l_iter->v;
1767                                                 if (use_short) {
1768                                                         unsigned short *elem = tri_data;
1769                                                         (*elem) = BM_elem_index_get(v);
1770                                                         elem++;
1771                                                         tri_data = elem;
1772                                                 }
1773                                                 else {
1774                                                         unsigned int *elem = tri_data;
1775                                                         (*elem) = BM_elem_index_get(v);
1776                                                         elem++;
1777                                                         tri_data = elem;
1778                                                 }
1779                                         } while ((l_iter = l_iter->next) != l_first);
1780                                 }
1781                         }
1782
1783                         GPU_buffer_unlock(buffers->index_buf, GPU_BINDING_INDEX);
1784
1785                         buffers->tot_tri = tottri;
1786                         buffers->index_type = (use_short ?
1787                                                GL_UNSIGNED_SHORT :
1788                                                GL_UNSIGNED_INT);
1789                 }
1790                 else {
1791                         /* Memory map failed */
1792                         if (!buffers->is_index_buf_global) {
1793                                 GPU_buffer_free(buffers->index_buf);
1794                         }
1795                         buffers->index_buf = NULL;
1796                         buffers->is_index_buf_global = false;
1797                 }
1798         }
1799         else if (buffers->index_buf) {
1800                 if (!buffers->is_index_buf_global) {
1801                         GPU_buffer_free(buffers->index_buf);
1802                 }
1803                 buffers->index_buf = NULL;
1804                 buffers->is_index_buf_global = false;
1805         }
1806 }
1807
1808 GPU_PBVH_Buffers *GPU_build_bmesh_pbvh_buffers(bool smooth_shading)
1809 {
1810         GPU_PBVH_Buffers *buffers;
1811
1812         buffers = MEM_callocN(sizeof(GPU_PBVH_Buffers), "GPU_Buffers");
1813         buffers->use_bmesh = true;
1814         buffers->smooth = smooth_shading;
1815         buffers->show_diffuse_color = false;
1816         buffers->use_matcaps = false;
1817
1818         return buffers;
1819 }
1820
1821 void GPU_draw_pbvh_buffers(GPU_PBVH_Buffers *buffers, DMSetMaterial setMaterial,
1822                            bool wireframe, bool fast)
1823 {
1824         bool do_fast = fast && buffers->index_buf_fast;
1825         /* sets material from the first face, to solve properly face would need to
1826          * be sorted in buckets by materials */
1827         if (setMaterial) {
1828                 if (buffers->face_indices_len) {
1829                         const MLoopTri *lt = &buffers->looptri[buffers->face_indices[0]];
1830                         const MPoly *mp = &buffers->mpoly[lt->poly];
1831                         if (!setMaterial(mp->mat_nr + 1, NULL))
1832                                 return;
1833                 }
1834                 else if (buffers->totgrid) {
1835                         const DMFlagMat *f = &buffers->grid_flag_mats[buffers->grid_indices[0]];
1836                         if (!setMaterial(f->mat_nr + 1, NULL))
1837                                 return;
1838                 }
1839                 else {
1840                         if (!setMaterial(1, NULL))
1841                                 return;
1842                 }
1843         }
1844
1845         if (buffers->vert_buf) {
1846                 char *base = NULL;
1847                 char *index_base = NULL;
1848                 int bound_options = 0;
1849                 glEnableClientState(GL_VERTEX_ARRAY);
1850                 if (!wireframe) {
1851                         glEnableClientState(GL_NORMAL_ARRAY);
1852                         glEnableClientState(GL_COLOR_ARRAY);
1853
1854                         /* weak inspection of bound options, should not be necessary ideally */
1855                         bound_options = GPU_basic_shader_bound_options();
1856                         GPU_basic_shader_bind(bound_options | GPU_SHADER_USE_COLOR);
1857                 }
1858
1859                 GPU_buffer_bind(buffers->vert_buf, GPU_BINDING_ARRAY);
1860
1861                 if (do_fast) {
1862                         GPU_buffer_bind(buffers->index_buf_fast, GPU_BINDING_INDEX);
1863                 }
1864                 else if (buffers->index_buf) {
1865                         GPU_buffer_bind(buffers->index_buf, GPU_BINDING_INDEX);
1866                 }
1867
1868                 if (wireframe)
1869                         glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
1870                 else {
1871                         bound_options = GPU_basic_shader_bound_options();
1872                         GPU_basic_shader_bind(bound_options | ((buffers->smooth || buffers->face_indices_len) ? 0 : GPU_SHADER_FLAT_NORMAL));
1873                 }
1874
1875                 if (buffers->tot_quad) {
1876                         const char *offset = base;
1877                         const bool drawall = !(buffers->has_hidden || do_fast);
1878
1879                         if (GLEW_ARB_draw_elements_base_vertex && drawall) {
1880
1881                                 glVertexPointer(3, GL_FLOAT, sizeof(VertexBufferFormat),
1882                                                 offset + offsetof(VertexBufferFormat, co));
1883                                 if (!wireframe) {
1884                                         glNormalPointer(GL_SHORT, sizeof(VertexBufferFormat),
1885                                                         offset + offsetof(VertexBufferFormat, no));
1886                                         glColorPointer(3, GL_UNSIGNED_BYTE, sizeof(VertexBufferFormat),
1887                                                        offset + offsetof(VertexBufferFormat, color));
1888                                 }
1889
1890                                 glMultiDrawElementsBaseVertex(GL_TRIANGLES, buffers->baseelemarray, buffers->index_type,
1891                                                               (const void * const *)buffers->baseindex,
1892                                                               buffers->totgrid, &buffers->baseelemarray[buffers->totgrid]);
1893                         }
1894                         else {
1895                                 int i, last = drawall ? buffers->totgrid : 1;
1896
1897                                 /* we could optimize this to one draw call, but it would need more memory */
1898                                 for (i = 0; i < last; i++) {
1899                                         glVertexPointer(3, GL_FLOAT, sizeof(VertexBufferFormat),
1900                                                         offset + offsetof(VertexBufferFormat, co));
1901                                         if (!wireframe) {
1902                                                 glNormalPointer(GL_SHORT, sizeof(VertexBufferFormat),
1903                                                                 offset + offsetof(VertexBufferFormat, no));
1904                                                 glColorPointer(3, GL_UNSIGNED_BYTE, sizeof(VertexBufferFormat),
1905                                                                offset + offsetof(VertexBufferFormat, color));
1906                                         }
1907
1908                                         if (do_fast)
1909                                                 glDrawElements(GL_TRIANGLES, buffers->totgrid * 6, buffers->index_type, index_base);
1910                                         else
1911                                                 glDrawElements(GL_TRIANGLES, buffers->tot_quad * 6, buffers->index_type, index_base);
1912
1913                                         offset += buffers->gridkey.grid_area * sizeof(VertexBufferFormat);
1914                                 }
1915                         }
1916                 }
1917                 else if (buffers->tot_tri) {
1918                         int totelem = buffers->tot_tri * 3;
1919
1920                         glVertexPointer(3, GL_FLOAT, sizeof(VertexBufferFormat),
1921                                         (void *)(base + offsetof(VertexBufferFormat, co)));
1922
1923                         if (!wireframe) {
1924                                 glNormalPointer(GL_SHORT, sizeof(VertexBufferFormat),
1925                                                 (void *)(base + offsetof(VertexBufferFormat, no)));
1926                                 glColorPointer(3, GL_UNSIGNED_BYTE, sizeof(VertexBufferFormat),
1927                                                (void *)(base + offsetof(VertexBufferFormat, color)));
1928                         }
1929
1930                         if (buffers->index_buf)
1931                                 glDrawElements(GL_TRIANGLES, totelem, buffers->index_type, index_base);
1932                         else
1933                                 glDrawArrays(GL_TRIANGLES, 0, totelem);
1934                 }
1935
1936                 if (wireframe)
1937                         glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
1938
1939                 GPU_buffer_unbind(buffers->vert_buf, GPU_BINDING_ARRAY);
1940                 if (buffers->index_buf || do_fast)
1941                         GPU_buffer_unbind(do_fast ? buffers->index_buf_fast : buffers->index_buf, GPU_BINDING_INDEX);
1942
1943                 glDisableClientState(GL_VERTEX_ARRAY);
1944                 if (!wireframe) {
1945                         glDisableClientState(GL_NORMAL_ARRAY);
1946                         glDisableClientState(GL_COLOR_ARRAY);
1947                         GPU_basic_shader_bind(bound_options);
1948                 }
1949         }
1950 }
1951
1952 bool GPU_pbvh_buffers_diffuse_changed(GPU_PBVH_Buffers *buffers, GSet *bm_faces, bool show_diffuse_color)
1953 {
1954         float diffuse_color[4];
1955         bool use_matcaps = GPU_material_use_matcaps_get();
1956
1957         if (buffers->show_diffuse_color != show_diffuse_color)
1958                 return true;
1959
1960         if (buffers->use_matcaps != use_matcaps)
1961                 return true;
1962
1963         if ((buffers->show_diffuse_color == false) || use_matcaps)
1964                 return false;
1965
1966         if (buffers->looptri) {
1967                 const MLoopTri *lt = &buffers->looptri[buffers->face_indices[0]];
1968                 const MPoly *mp = &buffers->mpoly[lt->poly];
1969
1970                 GPU_material_diffuse_get(mp->mat_nr + 1, diffuse_color);
1971         }
1972         else if (buffers->use_bmesh) {
1973                 /* due to dynamic nature of dyntopo, only get first material */
1974                 if (BLI_gset_size(bm_faces) > 0) {
1975                         GSetIterator gs_iter;
1976                         BMFace *f;
1977
1978                         BLI_gsetIterator_init(&gs_iter, bm_faces);
1979                         f = BLI_gsetIterator_getKey(&gs_iter);
1980                         GPU_material_diffuse_get(f->mat_nr + 1, diffuse_color);
1981                 }
1982                 else {
1983                         return false;
1984                 }
1985         }
1986         else {
1987                 const DMFlagMat *flags = &buffers->grid_flag_mats[buffers->grid_indices[0]];
1988
1989                 GPU_material_diffuse_get(flags->mat_nr + 1, diffuse_color);
1990         }
1991
1992         return !equals_v3v3(diffuse_color, buffers->diffuse_color);
1993 }
1994
1995 void GPU_free_pbvh_buffers(GPU_PBVH_Buffers *buffers)
1996 {
1997         if (buffers) {
1998                 if (buffers->vert_buf)
1999                         GPU_buffer_free(buffers->vert_buf);
2000                 if (buffers->index_buf && !buffers->is_index_buf_global)
2001                         GPU_buffer_free(buffers->index_buf);
2002                 if (buffers->index_buf_fast)
2003                         GPU_buffer_free(buffers->index_buf_fast);
2004                 if (buffers->baseelemarray)
2005                         MEM_freeN(buffers->baseelemarray);
2006                 if (buffers->baseindex)
2007                         MEM_freeN(buffers->baseindex);
2008
2009                 MEM_freeN(buffers);
2010         }
2011 }
2012
2013 void GPU_free_pbvh_buffer_multires(GridCommonGPUBuffer **grid_common_gpu_buffer)
2014 {
2015         GridCommonGPUBuffer *gridbuff = *grid_common_gpu_buffer;
2016
2017         if (gridbuff) {
2018                 if (gridbuff->mres_buffer) {
2019                         BLI_mutex_lock(&buffer_mutex);
2020                         gpu_buffer_free_intern(gridbuff->mres_buffer);
2021                         BLI_mutex_unlock(&buffer_mutex);
2022                 }
2023                 MEM_freeN(gridbuff);
2024                 *grid_common_gpu_buffer = NULL;
2025         }
2026 }
2027
2028 /* debug function, draws the pbvh BB */
2029 void GPU_draw_pbvh_BB(float min[3], float max[3], bool leaf)
2030 {
2031         const float quads[4][4][3] = {
2032                 {
2033                         {min[0], min[1], min[2]},
2034                         {max[0], min[1], min[2]},
2035                         {max[0], min[1], max[2]},
2036                         {min[0], min[1], max[2]}
2037                 },
2038
2039                 {
2040                         {min[0], min[1], min[2]},
2041                         {min[0], max[1], min[2]},
2042                         {min[0], max[1], max[2]},
2043                         {min[0], min[1], max[2]}
2044                 },
2045
2046                 {
2047                         {max[0], max[1], min[2]},
2048                         {max[0], min[1], min[2]},
2049                         {max[0], min[1], max[2]},
2050                         {max[0], max[1], max[2]}
2051                 },
2052
2053                 {
2054                         {max[0], max[1], min[2]},
2055                         {min[0], max[1], min[2]},
2056                         {min[0], max[1], max[2]},
2057                         {max[0], max[1], max[2]}
2058                 },
2059         };
2060
2061         if (leaf)
2062                 glColor4f(0.0, 1.0, 0.0, 0.5);
2063         else
2064                 glColor4f(1.0, 0.0, 0.0, 0.5);
2065
2066         glVertexPointer(3, GL_FLOAT, 0, &quads[0][0][0]);
2067         glDrawArrays(GL_QUADS, 0, 16);
2068 }
2069
2070 void GPU_init_draw_pbvh_BB(void)
2071 {
2072         glPushAttrib(GL_ENABLE_BIT);
2073         glDisable(GL_CULL_FACE);
2074         glEnableClientState(GL_VERTEX_ARRAY);
2075         glDisableClientState(GL_COLOR_ARRAY);
2076         glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
2077         glEnable(GL_BLEND);
2078 }
2079
2080 void GPU_end_draw_pbvh_BB(void)
2081 {
2082         glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
2083         glPopAttrib();
2084 }