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