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