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