OpenGL: rename simple shader to basic shader.
[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 "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)
487 {
488         GPUBufferPool *pool;
489         GPUBuffer *buffer;
490         float *varray;
491         int *mat_orig_to_new;
492         int i;
493         const GPUBufferTypeSettings *ts = &gpu_buffer_type_settings[type];
494         GLenum target = ts->gl_buffer_type;
495         size_t size = gpu_buffer_size_from_type(dm, type);
496         GLboolean uploaded;
497
498         pool = gpu_get_global_buffer_pool();
499
500         BLI_mutex_lock(&buffer_mutex);
501
502         /* alloc a GPUBuffer; fall back to legacy mode on failure */
503         if (!(buffer = gpu_buffer_alloc_intern(size))) {
504                 BLI_mutex_unlock(&buffer_mutex);
505                 return NULL;
506         }
507
508         mat_orig_to_new = MEM_mallocN(sizeof(*mat_orig_to_new) * dm->totmat,
509                                       "GPU_buffer_setup.mat_orig_to_new");
510         for (i = 0; i < object->totmaterial; i++) {
511                 /* map from original material index to new
512                  * GPUBufferMaterial index */
513                 mat_orig_to_new[object->materials[i].mat_nr] = i;
514         }
515
516         /* bind the buffer and discard previous data,
517          * avoids stalling gpu */
518         glBindBuffer(target, buffer->id);
519         glBufferData(target, buffer->size, NULL, GL_STATIC_DRAW);
520
521         /* attempt to map the buffer */
522         if (!(varray = glMapBuffer(target, GL_WRITE_ONLY))) {
523                 buffer = gpu_try_realloc(pool, buffer, size);
524
525                 /* allocation still failed; unfortunately we need to exit */
526                 if (!(buffer && (varray = glMapBuffer(target, GL_WRITE_ONLY)))) {
527                         if (buffer)
528                                 gpu_buffer_free_intern(buffer);
529                         BLI_mutex_unlock(&buffer_mutex);
530                         return NULL;
531                 }
532         }
533
534         uploaded = GL_FALSE;
535
536         /* attempt to upload the data to the VBO */
537         while (uploaded == GL_FALSE) {
538                 dm->copy_gpu_data(dm, type, varray, mat_orig_to_new, user);
539                 /* glUnmapBuffer returns GL_FALSE if
540                  * the data store is corrupted; retry
541                  * in that case */
542                 uploaded = glUnmapBuffer(target);
543         }
544         glBindBuffer(target, 0);
545
546         MEM_freeN(mat_orig_to_new);
547
548         BLI_mutex_unlock(&buffer_mutex);
549
550         return buffer;
551 }
552
553 /* get the GPUDrawObject buffer associated with a type */
554 static GPUBuffer **gpu_drawobject_buffer_from_type(GPUDrawObject *gdo, GPUBufferType type)
555 {
556         switch (type) {
557                 case GPU_BUFFER_VERTEX:
558                         return &gdo->points;
559                 case GPU_BUFFER_NORMAL:
560                         return &gdo->normals;
561                 case GPU_BUFFER_COLOR:
562                         return &gdo->colors;
563                 case GPU_BUFFER_UV:
564                         return &gdo->uv;
565                 case GPU_BUFFER_UV_TEXPAINT:
566                         return &gdo->uv_tex;
567                 case GPU_BUFFER_EDGE:
568                         return &gdo->edges;
569                 case GPU_BUFFER_UVEDGE:
570                         return &gdo->uvedges;
571                 case GPU_BUFFER_TRIANGLES:
572                         return &gdo->triangles;
573                 default:
574                         return NULL;
575         }
576 }
577
578 /* get the amount of space to allocate for a buffer of a particular type */
579 static size_t gpu_buffer_size_from_type(DerivedMesh *dm, GPUBufferType type)
580 {
581         switch (type) {
582                 case GPU_BUFFER_VERTEX:
583                         return sizeof(float) * gpu_buffer_type_settings[type].num_components * (dm->drawObject->tot_loop_verts + dm->drawObject->tot_loose_point);
584                 case GPU_BUFFER_NORMAL:
585                         return sizeof(short) * gpu_buffer_type_settings[type].num_components * dm->drawObject->tot_loop_verts;
586                 case GPU_BUFFER_COLOR:
587                         return sizeof(char) * gpu_buffer_type_settings[type].num_components * dm->drawObject->tot_loop_verts;
588                 case GPU_BUFFER_UV:
589                         return sizeof(float) * gpu_buffer_type_settings[type].num_components * dm->drawObject->tot_loop_verts;
590                 case GPU_BUFFER_UV_TEXPAINT:
591                         return sizeof(float) * gpu_buffer_type_settings[type].num_components * dm->drawObject->tot_loop_verts;
592                 case GPU_BUFFER_EDGE:
593                         return sizeof(int) * gpu_buffer_type_settings[type].num_components * dm->drawObject->totedge;
594                 case GPU_BUFFER_UVEDGE:
595                         return sizeof(int) * gpu_buffer_type_settings[type].num_components * dm->drawObject->tot_loop_verts;
596                 case GPU_BUFFER_TRIANGLES:
597                         return sizeof(int) * gpu_buffer_type_settings[type].num_components * dm->drawObject->tot_triangle_point;
598                 default:
599                         return -1;
600         }
601 }
602
603 /* call gpu_buffer_setup with settings for a particular type of buffer */
604 static GPUBuffer *gpu_buffer_setup_type(DerivedMesh *dm, GPUBufferType type)
605 {
606         void *user_data = NULL;
607         GPUBuffer *buf;
608
609         /* special handling for MCol and UV buffers */
610         if (type == GPU_BUFFER_COLOR) {
611                 if (!(user_data = DM_get_loop_data_layer(dm, dm->drawObject->colType)))
612                         return NULL;
613         }
614         else if (ELEM(type, GPU_BUFFER_UV, GPU_BUFFER_UV_TEXPAINT)) {
615                 if (!DM_get_loop_data_layer(dm, CD_MLOOPUV))
616                         return NULL;
617         }
618
619         buf = gpu_buffer_setup(dm, dm->drawObject, type, user_data);
620
621         return buf;
622 }
623
624 /* get the buffer of `type', initializing the GPUDrawObject and
625  * buffer if needed */
626 static GPUBuffer *gpu_buffer_setup_common(DerivedMesh *dm, GPUBufferType type)
627 {
628         GPUBuffer **buf;
629
630         if (!dm->drawObject)
631                 dm->drawObject = dm->gpuObjectNew(dm);
632
633         buf = gpu_drawobject_buffer_from_type(dm->drawObject, type);
634         if (!(*buf))
635                 *buf = gpu_buffer_setup_type(dm, type);
636
637         return *buf;
638 }
639
640 void GPU_vertex_setup(DerivedMesh *dm)
641 {
642         if (!gpu_buffer_setup_common(dm, GPU_BUFFER_VERTEX))
643                 return;
644
645         glEnableClientState(GL_VERTEX_ARRAY);
646         glBindBuffer(GL_ARRAY_BUFFER, dm->drawObject->points->id);
647         glVertexPointer(3, GL_FLOAT, 0, 0);
648         
649         GLStates |= GPU_BUFFER_VERTEX_STATE;
650 }
651
652 void GPU_normal_setup(DerivedMesh *dm)
653 {
654         if (!gpu_buffer_setup_common(dm, GPU_BUFFER_NORMAL))
655                 return;
656
657         glEnableClientState(GL_NORMAL_ARRAY);
658         glBindBuffer(GL_ARRAY_BUFFER, dm->drawObject->normals->id);
659         glNormalPointer(GL_SHORT, 4 * sizeof(short), 0);
660
661         GLStates |= GPU_BUFFER_NORMAL_STATE;
662 }
663
664 void GPU_uv_setup(DerivedMesh *dm)
665 {
666         if (!gpu_buffer_setup_common(dm, GPU_BUFFER_UV))
667                 return;
668
669         glEnableClientState(GL_TEXTURE_COORD_ARRAY);
670         glBindBuffer(GL_ARRAY_BUFFER, dm->drawObject->uv->id);
671         glTexCoordPointer(2, GL_FLOAT, 0, 0);
672
673         GLStates |= GPU_BUFFER_TEXCOORD_UNIT_0_STATE;
674 }
675
676 void GPU_texpaint_uv_setup(DerivedMesh *dm)
677 {
678         if (!gpu_buffer_setup_common(dm, GPU_BUFFER_UV_TEXPAINT))
679                 return;
680
681         glEnableClientState(GL_TEXTURE_COORD_ARRAY);
682         glBindBuffer(GL_ARRAY_BUFFER, dm->drawObject->uv_tex->id);
683         glTexCoordPointer(2, GL_FLOAT, 4 * sizeof(float), 0);
684         glClientActiveTexture(GL_TEXTURE2);
685         glEnableClientState(GL_TEXTURE_COORD_ARRAY);
686         glTexCoordPointer(2, GL_FLOAT, 4 * sizeof(float), BUFFER_OFFSET(2 * sizeof(float)));
687         glClientActiveTexture(GL_TEXTURE0);
688
689         GLStates |= GPU_BUFFER_TEXCOORD_UNIT_0_STATE | GPU_BUFFER_TEXCOORD_UNIT_2_STATE;
690 }
691
692
693 void GPU_color_setup(DerivedMesh *dm, int colType)
694 {
695         if (!dm->drawObject) {
696                 /* XXX Not really nice, but we need a valid gpu draw object to set the colType...
697                  *     Else we would have to add a new param to gpu_buffer_setup_common. */
698                 dm->drawObject = dm->gpuObjectNew(dm);
699                 dm->dirty &= ~DM_DIRTY_MCOL_UPDATE_DRAW;
700                 dm->drawObject->colType = colType;
701         }
702         /* In paint mode, dm may stay the same during stroke, however we still want to update colors!
703          * Also check in case we changed color type (i.e. which MCol cdlayer we use). */
704         else if ((dm->dirty & DM_DIRTY_MCOL_UPDATE_DRAW) || (colType != dm->drawObject->colType)) {
705                 GPUBuffer **buf = gpu_drawobject_buffer_from_type(dm->drawObject, GPU_BUFFER_COLOR);
706                 /* XXX Freeing this buffer is a bit stupid, as geometry has not changed, size should remain the same.
707                  *     Not sure though it would be worth defining a sort of gpu_buffer_update func - nor whether
708                  *     it is even possible ! */
709                 GPU_buffer_free(*buf);
710                 *buf = NULL;
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))
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))
738                 return;
739
740         if (!gpu_buffer_setup_common(dm, GPU_BUFFER_VERTEX))
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))
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))
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                 glVertexAttribPointer(data[i].index, data[i].size, data[i].type,
826                                          GL_FALSE, elementsize, BUFFER_OFFSET(offset));
827                 offset += data[i].size * GPU_typesize(data[i].type);
828                 
829                 attribData[i].index = data[i].index;
830                 attribData[i].size = data[i].size;
831                 attribData[i].type = data[i].type;
832         }
833         
834         attribData[numdata].index = -1; 
835 }
836
837 void GPU_interleaved_attrib_unbind(void)
838 {
839         int i;
840         for (i = 0; i < MAX_GPU_ATTRIB_DATA; i++) {
841                 if (attribData[i].index != -1) {
842                         glDisableVertexAttribArray(attribData[i].index);
843                 }
844                 else
845                         break;
846         }
847         attribData[0].index = -1;
848 }
849
850 void GPU_buffers_unbind(void)
851 {
852         int i;
853
854         if (GLStates & GPU_BUFFER_VERTEX_STATE)
855                 glDisableClientState(GL_VERTEX_ARRAY);
856         if (GLStates & GPU_BUFFER_NORMAL_STATE)
857                 glDisableClientState(GL_NORMAL_ARRAY);
858         if (GLStates & GPU_BUFFER_TEXCOORD_UNIT_0_STATE)
859                 glDisableClientState(GL_TEXTURE_COORD_ARRAY);
860         if (GLStates & GPU_BUFFER_TEXCOORD_UNIT_2_STATE) {
861                 glClientActiveTexture(GL_TEXTURE2);
862                 glDisableClientState(GL_TEXTURE_COORD_ARRAY);
863                 glClientActiveTexture(GL_TEXTURE0);
864         }
865         if (GLStates & GPU_BUFFER_COLOR_STATE)
866                 glDisableClientState(GL_COLOR_ARRAY);
867         if (GLStates & GPU_BUFFER_ELEMENT_STATE)
868                 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
869
870         GLStates &= ~(GPU_BUFFER_VERTEX_STATE | GPU_BUFFER_NORMAL_STATE |
871                       GPU_BUFFER_TEXCOORD_UNIT_0_STATE | GPU_BUFFER_TEXCOORD_UNIT_2_STATE |
872                       GPU_BUFFER_COLOR_STATE | GPU_BUFFER_ELEMENT_STATE);
873
874         for (i = 0; i < MAX_GPU_ATTRIB_DATA; i++) {
875                 if (attribData[i].index != -1) {
876                         glDisableVertexAttribArray(attribData[i].index);
877                 }
878                 else
879                         break;
880         }
881         attribData[0].index = -1;
882
883         glBindBuffer(GL_ARRAY_BUFFER, 0);
884 }
885
886 void GPU_color_switch(int mode)
887 {
888         if (mode) {
889                 if (!(GLStates & GPU_BUFFER_COLOR_STATE))
890                         glEnableClientState(GL_COLOR_ARRAY);
891                 GLStates |= GPU_BUFFER_COLOR_STATE;
892         }
893         else {
894                 if (GLStates & GPU_BUFFER_COLOR_STATE)
895                         glDisableClientState(GL_COLOR_ARRAY);
896                 GLStates &= ~GPU_BUFFER_COLOR_STATE;
897         }
898 }
899
900 static int gpu_binding_type_gl[] =
901 {
902         GL_ARRAY_BUFFER,
903         GL_ELEMENT_ARRAY_BUFFER
904 };
905
906 void *GPU_buffer_lock(GPUBuffer *buffer, GPUBindingType binding)
907 {
908         float *varray;
909         int bindtypegl;
910
911         if (!buffer)
912                 return 0;
913
914         bindtypegl = gpu_binding_type_gl[binding];
915         glBindBuffer(bindtypegl, buffer->id);
916         varray = glMapBuffer(bindtypegl, GL_WRITE_ONLY);
917         return varray;
918 }
919
920 void *GPU_buffer_lock_stream(GPUBuffer *buffer, GPUBindingType binding)
921 {
922         float *varray;
923         int bindtypegl;
924
925         if (!buffer)
926                 return 0;
927
928         bindtypegl = gpu_binding_type_gl[binding];
929         glBindBuffer(bindtypegl, buffer->id);
930         /* discard previous data, avoid stalling gpu */
931         glBufferData(bindtypegl, buffer->size, 0, GL_STREAM_DRAW);
932         varray = glMapBuffer(bindtypegl, GL_WRITE_ONLY);
933         return varray;
934 }
935
936 void GPU_buffer_unlock(GPUBuffer *UNUSED(buffer), GPUBindingType binding)
937 {
938         int bindtypegl = gpu_binding_type_gl[binding];
939         /* note: this operation can fail, could return
940                  * an error code from this function? */
941         glUnmapBuffer(bindtypegl);
942         glBindBuffer(bindtypegl, 0);
943 }
944
945 void GPU_buffer_bind(GPUBuffer *buffer, GPUBindingType binding)
946 {
947         int bindtypegl = gpu_binding_type_gl[binding];
948         glBindBuffer(bindtypegl, buffer->id);
949 }
950
951 void GPU_buffer_unbind(GPUBuffer *UNUSED(buffer), GPUBindingType binding)
952 {
953         int bindtypegl = gpu_binding_type_gl[binding];
954         glBindBuffer(bindtypegl, 0);
955 }
956
957 /* used for drawing edges */
958 void GPU_buffer_draw_elements(GPUBuffer *UNUSED(elements), unsigned int mode, int start, int count)
959 {
960         glDrawElements(mode, count, GL_UNSIGNED_INT, BUFFER_OFFSET(start * sizeof(unsigned int)));
961 }
962
963
964 /* XXX: the rest of the code in this file is used for optimized PBVH
965  * drawing and doesn't interact at all with the buffer code above */
966
967 /* Convenience struct for building the VBO. */
968 typedef struct {
969         float co[3];
970         short no[3];
971
972         /* inserting this to align the 'color' field to a four-byte
973          * boundary; drastically increases viewport performance on my
974          * drivers (Gallium/Radeon) --nicholasbishop */
975         char pad[2];
976         
977         unsigned char color[3];
978 } VertexBufferFormat;
979
980 struct GPU_PBVH_Buffers {
981         /* opengl buffer handles */
982         GPUBuffer *vert_buf, *index_buf, *index_buf_fast;
983         GLenum index_type;
984
985         int *baseelemarray;
986         void **baseindex;
987
988         /* mesh pointers in case buffer allocation fails */
989         const MPoly *mpoly;
990         const MLoop *mloop;
991         const MLoopTri *looptri;
992         const MVert *mvert;
993
994         const int *face_indices;
995         int        face_indices_len;
996         const float *vmask;
997
998         /* grid pointers */
999         CCGKey gridkey;
1000         CCGElem **grids;
1001         const DMFlagMat *grid_flag_mats;
1002         BLI_bitmap * const *grid_hidden;
1003         const int *grid_indices;
1004         int totgrid;
1005         bool has_hidden;
1006
1007         bool use_bmesh;
1008
1009         unsigned int tot_tri, tot_quad;
1010
1011         /* The PBVH ensures that either all faces in the node are
1012          * smooth-shaded or all faces are flat-shaded */
1013         bool smooth;
1014
1015         bool show_diffuse_color;
1016         bool use_matcaps;
1017         float diffuse_color[4];
1018 };
1019
1020 static float gpu_color_from_mask(float mask)
1021 {
1022         return 1.0f - mask * 0.75f;
1023 }
1024
1025 static void gpu_color_from_mask_copy(float mask, const float diffuse_color[4], unsigned char out[3])
1026 {
1027         float mask_color;
1028
1029         mask_color = gpu_color_from_mask(mask) * 255.0f;
1030
1031         out[0] = diffuse_color[0] * mask_color;
1032         out[1] = diffuse_color[1] * mask_color;
1033         out[2] = diffuse_color[2] * mask_color;
1034 }
1035
1036 static void gpu_color_from_mask_quad_copy(const CCGKey *key,
1037                                           CCGElem *a, CCGElem *b,
1038                                           CCGElem *c, CCGElem *d,
1039                                           const float *diffuse_color,
1040                                           unsigned char out[3])
1041 {
1042         float mask_color =
1043             gpu_color_from_mask((*CCG_elem_mask(key, a) +
1044                                  *CCG_elem_mask(key, b) +
1045                                  *CCG_elem_mask(key, c) +
1046                                  *CCG_elem_mask(key, d)) * 0.25f) * 255.0f;
1047
1048         out[0] = diffuse_color[0] * mask_color;
1049         out[1] = diffuse_color[1] * mask_color;
1050         out[2] = diffuse_color[2] * mask_color;
1051 }
1052
1053 void GPU_update_mesh_pbvh_buffers(
1054         GPU_PBVH_Buffers *buffers, const MVert *mvert,
1055         const int *vert_indices, int totvert, const float *vmask,
1056         const int (*face_vert_indices)[4], bool show_diffuse_color)
1057 {
1058         VertexBufferFormat *vert_data;
1059         int i, j;
1060
1061         buffers->vmask = vmask;
1062         buffers->show_diffuse_color = show_diffuse_color;
1063         buffers->use_matcaps = GPU_material_use_matcaps_get();
1064
1065         {
1066                 int totelem = (buffers->smooth ? totvert : (buffers->tot_tri * 3));
1067                 float diffuse_color[4] = {0.8f, 0.8f, 0.8f, 0.8f};
1068
1069                 if (buffers->use_matcaps)
1070                         diffuse_color[0] = diffuse_color[1] = diffuse_color[2] = 1.0;
1071                 else if (show_diffuse_color) {
1072                         const MLoopTri *lt = &buffers->looptri[buffers->face_indices[0]];
1073                         const MPoly *mp = &buffers->mpoly[lt->poly];
1074
1075                         GPU_material_diffuse_get(mp->mat_nr + 1, diffuse_color);
1076                 }
1077
1078                 copy_v4_v4(buffers->diffuse_color, diffuse_color);
1079
1080                 /* Build VBO */
1081                 if (buffers->vert_buf)
1082                         GPU_buffer_free(buffers->vert_buf);
1083                 buffers->vert_buf = GPU_buffer_alloc(sizeof(VertexBufferFormat) * totelem);
1084                 vert_data = GPU_buffer_lock(buffers->vert_buf, GPU_BINDING_ARRAY);
1085
1086                 if (vert_data) {
1087                         /* Vertex data is shared if smooth-shaded, but separate
1088                          * copies are made for flat shading because normals
1089                          * shouldn't be shared. */
1090                         if (buffers->smooth) {
1091                                 for (i = 0; i < totvert; ++i) {
1092                                         const MVert *v = &mvert[vert_indices[i]];
1093                                         VertexBufferFormat *out = vert_data + i;
1094
1095                                         copy_v3_v3(out->co, v->co);
1096                                         memcpy(out->no, v->no, sizeof(short) * 3);
1097                                 }
1098
1099 #define UPDATE_VERTEX(face, vertex, index, diffuse_color) \
1100                                 { \
1101                                         VertexBufferFormat *out = vert_data + face_vert_indices[face][index]; \
1102                                         if (vmask) \
1103                                                 gpu_color_from_mask_copy(vmask[vertex], diffuse_color, out->color); \
1104                                         else \
1105                                                 rgb_float_to_uchar(out->color, diffuse_color); \
1106                                 } (void)0
1107
1108                                 for (i = 0; i < buffers->face_indices_len; i++) {
1109                                         const MLoopTri *lt = &buffers->looptri[buffers->face_indices[i]];
1110                                         const unsigned int vtri[3] = {
1111                                             buffers->mloop[lt->tri[0]].v,
1112                                             buffers->mloop[lt->tri[1]].v,
1113                                             buffers->mloop[lt->tri[2]].v,
1114                                         };
1115
1116                                         UPDATE_VERTEX(i, vtri[0], 0, diffuse_color);
1117                                         UPDATE_VERTEX(i, vtri[1], 1, diffuse_color);
1118                                         UPDATE_VERTEX(i, vtri[2], 2, diffuse_color);
1119                                 }
1120 #undef UPDATE_VERTEX
1121                         }
1122                         else {
1123                                 /* calculate normal for each polygon only once */
1124                                 unsigned int mpoly_prev = UINT_MAX;
1125                                 short no[3];
1126
1127                                 for (i = 0; i < buffers->face_indices_len; ++i) {
1128                                         const MLoopTri *lt = &buffers->looptri[buffers->face_indices[i]];
1129                                         const unsigned int vtri[3] = {
1130                                             buffers->mloop[lt->tri[0]].v,
1131                                             buffers->mloop[lt->tri[1]].v,
1132                                             buffers->mloop[lt->tri[2]].v,
1133                                         };
1134
1135                                         float fmask;
1136
1137                                         if (paint_is_face_hidden(lt, mvert, buffers->mloop))
1138                                                 continue;
1139
1140                                         /* Face normal and mask */
1141                                         if (lt->poly != mpoly_prev) {
1142                                                 const MPoly *mp = &buffers->mpoly[lt->poly];
1143                                                 float fno[3];
1144                                                 BKE_mesh_calc_poly_normal(mp, &buffers->mloop[mp->loopstart], mvert, fno);
1145                                                 normal_float_to_short_v3(no, fno);
1146                                                 mpoly_prev = lt->poly;
1147                                         }
1148
1149                                         if (vmask) {
1150                                                 fmask = (vmask[vtri[0]] +
1151                                                          vmask[vtri[1]] +
1152                                                          vmask[vtri[2]]) / 3.0f;
1153                                         }
1154
1155                                         for (j = 0; j < 3; j++) {
1156                                                 const MVert *v = &mvert[vtri[j]];
1157                                                 VertexBufferFormat *out = vert_data;
1158
1159                                                 copy_v3_v3(out->co, v->co);
1160                                                 copy_v3_v3_short(out->no, no);
1161
1162                                                 if (vmask)
1163                                                         gpu_color_from_mask_copy(fmask, diffuse_color, out->color);
1164                                                 else
1165                                                         rgb_float_to_uchar(out->color, diffuse_color);
1166
1167                                                 vert_data++;
1168                                         }
1169                                 }
1170                         }
1171
1172                         GPU_buffer_unlock(buffers->vert_buf, GPU_BINDING_ARRAY);
1173                 }
1174                 else {
1175                         GPU_buffer_free(buffers->vert_buf);
1176                         buffers->vert_buf = NULL;
1177                 }
1178         }
1179
1180         buffers->mvert = mvert;
1181 }
1182
1183 GPU_PBVH_Buffers *GPU_build_mesh_pbvh_buffers(
1184         const int (*face_vert_indices)[4],
1185         const MPoly *mpoly, const MLoop *mloop, const MLoopTri *looptri,
1186         const MVert *mvert,
1187         const int *face_indices,
1188         const int  face_indices_len)
1189 {
1190         GPU_PBVH_Buffers *buffers;
1191         unsigned short *tri_data;
1192         int i, j, tottri;
1193
1194         buffers = MEM_callocN(sizeof(GPU_PBVH_Buffers), "GPU_Buffers");
1195         buffers->index_type = GL_UNSIGNED_SHORT;
1196         buffers->smooth = mpoly[looptri[face_indices[0]].poly].flag & ME_SMOOTH;
1197
1198         buffers->show_diffuse_color = false;
1199         buffers->use_matcaps = false;
1200
1201         /* Count the number of visible triangles */
1202         for (i = 0, tottri = 0; i < face_indices_len; ++i) {
1203                 const MLoopTri *lt = &looptri[face_indices[i]];
1204                 if (!paint_is_face_hidden(lt, mvert, mloop))
1205                         tottri++;
1206         }
1207
1208         if (tottri == 0) {
1209                 buffers->tot_tri = 0;
1210
1211                 buffers->mpoly = mpoly;
1212                 buffers->mloop = mloop;
1213                 buffers->looptri = looptri;
1214                 buffers->face_indices = face_indices;
1215                 buffers->face_indices_len = 0;
1216
1217                 return buffers;
1218         }
1219
1220         /* An element index buffer is used for smooth shading, but flat
1221          * shading requires separate vertex normals so an index buffer is
1222          * can't be used there. */
1223         if (buffers->smooth)
1224                 buffers->index_buf = GPU_buffer_alloc(sizeof(unsigned short) * tottri * 3);
1225
1226         if (buffers->index_buf) {
1227                 /* Fill the triangle buffer */
1228                 tri_data = GPU_buffer_lock(buffers->index_buf, GPU_BINDING_INDEX);
1229                 if (tri_data) {
1230                         for (i = 0; i < face_indices_len; ++i) {
1231                                 const MLoopTri *lt = &looptri[face_indices[i]];
1232
1233                                 /* Skip hidden faces */
1234                                 if (paint_is_face_hidden(lt, mvert, mloop))
1235                                         continue;
1236
1237                                 for (j = 0; j < 3; ++j) {
1238                                         *tri_data = face_vert_indices[i][j];
1239                                         tri_data++;
1240                                 }
1241                         }
1242                         GPU_buffer_unlock(buffers->index_buf, GPU_BINDING_INDEX);
1243                 }
1244                 else {
1245                         GPU_buffer_free(buffers->index_buf);
1246                         buffers->index_buf = NULL;
1247                 }
1248         }
1249
1250         buffers->tot_tri = tottri;
1251
1252         buffers->mpoly = mpoly;
1253         buffers->mloop = mloop;
1254         buffers->looptri = looptri;
1255
1256         buffers->face_indices = face_indices;
1257         buffers->face_indices_len = face_indices_len;
1258
1259         return buffers;
1260 }
1261
1262 void GPU_update_grid_pbvh_buffers(GPU_PBVH_Buffers *buffers, CCGElem **grids,
1263                                   const DMFlagMat *grid_flag_mats, int *grid_indices,
1264                                   int totgrid, const CCGKey *key, bool show_diffuse_color)
1265 {
1266         VertexBufferFormat *vert_data;
1267         int i, j, k, x, y;
1268
1269         buffers->show_diffuse_color = show_diffuse_color;
1270         buffers->use_matcaps = GPU_material_use_matcaps_get();
1271         buffers->smooth = grid_flag_mats[grid_indices[0]].flag & ME_SMOOTH;
1272
1273         /* Build VBO */
1274         if (buffers->vert_buf) {
1275                 const int has_mask = key->has_mask;
1276                 float diffuse_color[4] = {0.8f, 0.8f, 0.8f, 1.0f};
1277
1278                 if (buffers->use_matcaps)
1279                         diffuse_color[0] = diffuse_color[1] = diffuse_color[2] = 1.0;
1280                 else if (show_diffuse_color) {
1281                         const DMFlagMat *flags = &grid_flag_mats[grid_indices[0]];
1282
1283                         GPU_material_diffuse_get(flags->mat_nr + 1, diffuse_color);
1284                 }
1285
1286                 copy_v4_v4(buffers->diffuse_color, diffuse_color);
1287
1288                 vert_data = GPU_buffer_lock_stream(buffers->vert_buf, GPU_BINDING_ARRAY);
1289                 if (vert_data) {
1290                         for (i = 0; i < totgrid; ++i) {
1291                                 VertexBufferFormat *vd = vert_data;
1292                                 CCGElem *grid = grids[grid_indices[i]];
1293
1294                                 for (y = 0; y < key->grid_size; y++) {
1295                                         for (x = 0; x < key->grid_size; x++) {
1296                                                 CCGElem *elem = CCG_grid_elem(key, grid, x, y);
1297                                                 
1298                                                 copy_v3_v3(vd->co, CCG_elem_co(key, elem));
1299                                                 if (buffers->smooth) {
1300                                                         normal_float_to_short_v3(vd->no, CCG_elem_no(key, elem));
1301
1302                                                         if (has_mask) {
1303                                                                 gpu_color_from_mask_copy(*CCG_elem_mask(key, elem),
1304                                                                                          diffuse_color, vd->color);
1305                                                         }
1306                                                 }
1307                                                 vd++;
1308                                         }
1309                                 }
1310                                 
1311                                 if (!buffers->smooth) {
1312                                         /* for flat shading, recalc normals and set the last vertex of
1313                                          * each triangle in the index buffer to have the flat normal as
1314                                          * that is what opengl will use */
1315                                         for (j = 0; j < key->grid_size - 1; j++) {
1316                                                 for (k = 0; k < key->grid_size - 1; k++) {
1317                                                         CCGElem *elems[4] = {
1318                                                                 CCG_grid_elem(key, grid, k, j + 1),
1319                                                                 CCG_grid_elem(key, grid, k + 1, j + 1),
1320                                                                 CCG_grid_elem(key, grid, k + 1, j),
1321                                                                 CCG_grid_elem(key, grid, k, j)
1322                                                         };
1323                                                         float fno[3];
1324
1325                                                         normal_quad_v3(fno,
1326                                                                        CCG_elem_co(key, elems[0]),
1327                                                                        CCG_elem_co(key, elems[1]),
1328                                                                        CCG_elem_co(key, elems[2]),
1329                                                                        CCG_elem_co(key, elems[3]));
1330
1331                                                         vd = vert_data + (j + 1) * key->grid_size + k;
1332                                                         normal_float_to_short_v3(vd->no, fno);
1333
1334                                                         if (has_mask) {
1335                                                                 gpu_color_from_mask_quad_copy(key,
1336                                                                                               elems[0],
1337                                                                                               elems[1],
1338                                                                                               elems[2],
1339                                                                                               elems[3],
1340                                                                                               diffuse_color,
1341                                                                                               vd->color);
1342                                                         }
1343                                                 }
1344                                         }
1345                                 }
1346
1347                                 vert_data += key->grid_area;
1348                         }
1349
1350                         GPU_buffer_unlock(buffers->vert_buf, GPU_BINDING_ARRAY);
1351                 }
1352                 else {
1353                         GPU_buffer_free(buffers->vert_buf);
1354                         buffers->vert_buf = NULL;
1355                 }
1356         }
1357
1358         buffers->grids = grids;
1359         buffers->grid_indices = grid_indices;
1360         buffers->totgrid = totgrid;
1361         buffers->grid_flag_mats = grid_flag_mats;
1362         buffers->gridkey = *key;
1363
1364         //printf("node updated %p\n", buffers);
1365 }
1366
1367 /* Build the element array buffer of grid indices using either
1368  * unsigned shorts or unsigned ints. */
1369 #define FILL_QUAD_BUFFER(type_, tot_quad_, buffer_)                     \
1370     {                                                                   \
1371         type_ *tri_data;                                                \
1372         int offset = 0;                                                 \
1373         int i, j, k;                                                    \
1374         buffer_ = GPU_buffer_alloc(sizeof(type_) * (tot_quad_) * 6);    \
1375                                                                         \
1376         /* Fill the buffer */                                           \
1377         tri_data = GPU_buffer_lock(buffer_, GPU_BINDING_INDEX);         \
1378         if (tri_data) {                                                 \
1379             for (i = 0; i < totgrid; ++i) {                             \
1380                 BLI_bitmap *gh = NULL;                                  \
1381                 if (grid_hidden)                                        \
1382                     gh = grid_hidden[(grid_indices)[i]];                \
1383                                                                         \
1384                 for (j = 0; j < gridsize - 1; ++j) {                    \
1385                     for (k = 0; k < gridsize - 1; ++k) {                \
1386                         /* Skip hidden grid face */                     \
1387                         if (gh &&                                       \
1388                             paint_is_grid_face_hidden(gh,               \
1389                                                       gridsize, k, j))  \
1390                             continue;                                    \
1391                                                                           \
1392                         *(tri_data++) = offset + j * gridsize + k + 1;     \
1393                         *(tri_data++) = offset + j * gridsize + k;          \
1394                         *(tri_data++) = offset + (j + 1) * gridsize + k;     \
1395                                                                              \
1396                         *(tri_data++) = offset + (j + 1) * gridsize + k + 1; \
1397                         *(tri_data++) = offset + j * gridsize + k + 1;       \
1398                         *(tri_data++) = offset + (j + 1) * gridsize + k;    \
1399                     }                                                      \
1400                 }                                                         \
1401                                                                          \
1402                 offset += gridsize * gridsize;                          \
1403             }                                                           \
1404             GPU_buffer_unlock(buffer_, GPU_BINDING_INDEX);                         \
1405         }                                                               \
1406         else {                                                          \
1407             GPU_buffer_free(buffer_);                                   \
1408             (buffer_) = NULL;                                           \
1409         }                                                               \
1410     } (void)0
1411 /* end FILL_QUAD_BUFFER */
1412
1413 static GPUBuffer *gpu_get_grid_buffer(int gridsize, GLenum *index_type, unsigned *totquad)
1414 {
1415         /* used in the FILL_QUAD_BUFFER macro */
1416         BLI_bitmap * const *grid_hidden = NULL;
1417         const int *grid_indices = NULL;
1418         int totgrid = 1;
1419
1420         /* VBO is already built */
1421         if (mres_glob_buffer && mres_prev_gridsize == gridsize) {
1422                 *index_type = mres_prev_index_type;
1423                 *totquad = mres_prev_totquad;
1424                 return mres_glob_buffer;
1425         }
1426         /* we can't reuse old, delete the existing buffer */
1427         else if (mres_glob_buffer) {
1428                 GPU_buffer_free(mres_glob_buffer);
1429         }
1430
1431         /* Build new VBO */
1432         *totquad = (gridsize - 1) * (gridsize - 1);
1433
1434         if (gridsize * gridsize < USHRT_MAX) {
1435                 *index_type = GL_UNSIGNED_SHORT;
1436                 FILL_QUAD_BUFFER(unsigned short, *totquad, mres_glob_buffer);
1437         }
1438         else {
1439                 *index_type = GL_UNSIGNED_INT;
1440                 FILL_QUAD_BUFFER(unsigned int, *totquad, mres_glob_buffer);
1441         }
1442
1443         mres_prev_gridsize = gridsize;
1444         mres_prev_index_type = *index_type;
1445         mres_prev_totquad = *totquad;
1446         return mres_glob_buffer;
1447 }
1448
1449 #define FILL_FAST_BUFFER(type_) \
1450 { \
1451         type_ *buffer; \
1452         buffers->index_buf_fast = GPU_buffer_alloc(sizeof(type_) * 6 * totgrid); \
1453         buffer = GPU_buffer_lock(buffers->index_buf_fast, GPU_BINDING_INDEX); \
1454         if (buffer) { \
1455                 int i; \
1456                 for (i = 0; i < totgrid; i++) { \
1457                         int currentquad = i * 6; \
1458                         buffer[currentquad]     = i * gridsize * gridsize + gridsize - 1; \
1459                         buffer[currentquad + 1] = i * gridsize * gridsize; \
1460                         buffer[currentquad + 2] = (i + 1) * gridsize * gridsize - gridsize; \
1461                         buffer[currentquad + 3] = (i + 1) * gridsize * gridsize - 1; \
1462                         buffer[currentquad + 4] = i * gridsize * gridsize + gridsize - 1; \
1463                         buffer[currentquad + 5] = (i + 1) * gridsize * gridsize - gridsize; \
1464                 } \
1465                 GPU_buffer_unlock(buffers->index_buf_fast, GPU_BINDING_INDEX); \
1466         } \
1467         else { \
1468                 GPU_buffer_free(buffers->index_buf_fast); \
1469                 buffers->index_buf_fast = NULL; \
1470         } \
1471 } (void)0
1472
1473 GPU_PBVH_Buffers *GPU_build_grid_pbvh_buffers(int *grid_indices, int totgrid,
1474                                               BLI_bitmap **grid_hidden, int gridsize, const CCGKey *key)
1475 {
1476         GPU_PBVH_Buffers *buffers;
1477         int totquad;
1478         int fully_visible_totquad = (gridsize - 1) * (gridsize - 1) * totgrid;
1479
1480         buffers = MEM_callocN(sizeof(GPU_PBVH_Buffers), "GPU_Buffers");
1481         buffers->grid_hidden = grid_hidden;
1482         buffers->totgrid = totgrid;
1483
1484         buffers->show_diffuse_color = false;
1485         buffers->use_matcaps = false;
1486
1487         /* Count the number of quads */
1488         totquad = BKE_pbvh_count_grid_quads(grid_hidden, grid_indices, totgrid, gridsize);
1489
1490         /* totally hidden node, return here to avoid BufferData with zero below. */
1491         if (totquad == 0)
1492                 return buffers;
1493
1494         /* create and fill indices of the fast buffer too */
1495         if (totgrid * gridsize * gridsize < USHRT_MAX) {
1496                 FILL_FAST_BUFFER(unsigned short);
1497         }
1498         else {
1499                 FILL_FAST_BUFFER(unsigned int);
1500         }
1501
1502         if (totquad == fully_visible_totquad) {
1503                 buffers->index_buf = gpu_get_grid_buffer(gridsize, &buffers->index_type, &buffers->tot_quad);
1504                 buffers->has_hidden = false;
1505         }
1506         else {
1507                 buffers->tot_quad = totquad;
1508
1509                 if (totgrid * gridsize * gridsize < USHRT_MAX) {
1510                         buffers->index_type = GL_UNSIGNED_SHORT;
1511                         FILL_QUAD_BUFFER(unsigned short, totquad, buffers->index_buf);
1512                 }
1513                 else {
1514                         buffers->index_type = GL_UNSIGNED_INT;
1515                         FILL_QUAD_BUFFER(unsigned int, totquad, buffers->index_buf);
1516                 }
1517
1518                 buffers->has_hidden = true;
1519         }
1520
1521         /* Build coord/normal VBO */
1522         if (buffers->index_buf)
1523                 buffers->vert_buf = GPU_buffer_alloc(sizeof(VertexBufferFormat) * totgrid * key->grid_area);
1524
1525         if (GLEW_ARB_draw_elements_base_vertex /* 3.2 */) {
1526                 int i;
1527                 buffers->baseelemarray = MEM_mallocN(sizeof(int) * totgrid * 2, "GPU_PBVH_Buffers.baseelemarray");
1528                 buffers->baseindex = MEM_mallocN(sizeof(void *) * totgrid, "GPU_PBVH_Buffers.baseindex");
1529                 for (i = 0; i < totgrid; i++) {
1530                         buffers->baseelemarray[i] = buffers->tot_quad * 6;
1531                         buffers->baseelemarray[i + totgrid] = i * key->grid_area;
1532                         buffers->baseindex[i] = NULL;
1533                 }
1534         }
1535
1536         return buffers;
1537 }
1538
1539 #undef FILL_QUAD_BUFFER
1540
1541 /* Output a BMVert into a VertexBufferFormat array
1542  *
1543  * The vertex is skipped if hidden, otherwise the output goes into
1544  * index '*v_index' in the 'vert_data' array and '*v_index' is
1545  * incremented.
1546  */
1547 static void gpu_bmesh_vert_to_buffer_copy(BMVert *v,
1548                                           VertexBufferFormat *vert_data,
1549                                           int *v_index,
1550                                           const float fno[3],
1551                                           const float *fmask,
1552                                           const int cd_vert_mask_offset,
1553                                           const float diffuse_color[4])
1554 {
1555         if (!BM_elem_flag_test(v, BM_ELEM_HIDDEN)) {
1556                 VertexBufferFormat *vd = &vert_data[*v_index];
1557
1558                 /* Set coord, normal, and mask */
1559                 copy_v3_v3(vd->co, v->co);
1560                 normal_float_to_short_v3(vd->no, fno ? fno : v->no);
1561
1562                 gpu_color_from_mask_copy(
1563                         fmask ? *fmask :
1564                                 BM_ELEM_CD_GET_FLOAT(v, cd_vert_mask_offset),
1565                         diffuse_color,
1566                         vd->color);
1567
1568                 /* Assign index for use in the triangle index buffer */
1569                 /* note: caller must set:  bm->elem_index_dirty |= BM_VERT; */
1570                 BM_elem_index_set(v, (*v_index)); /* set_dirty! */
1571
1572                 (*v_index)++;
1573         }
1574 }
1575
1576 /* Return the total number of vertices that don't have BM_ELEM_HIDDEN set */
1577 static int gpu_bmesh_vert_visible_count(GSet *bm_unique_verts,
1578                                         GSet *bm_other_verts)
1579 {
1580         GSetIterator gs_iter;
1581         int totvert = 0;
1582
1583         GSET_ITER (gs_iter, bm_unique_verts) {
1584                 BMVert *v = BLI_gsetIterator_getKey(&gs_iter);
1585                 if (!BM_elem_flag_test(v, BM_ELEM_HIDDEN))
1586                         totvert++;
1587         }
1588         GSET_ITER (gs_iter, bm_other_verts) {
1589                 BMVert *v = BLI_gsetIterator_getKey(&gs_iter);
1590                 if (!BM_elem_flag_test(v, BM_ELEM_HIDDEN))
1591                         totvert++;
1592         }
1593
1594         return totvert;
1595 }
1596
1597 /* Return the total number of visible faces */
1598 static int gpu_bmesh_face_visible_count(GSet *bm_faces)
1599 {
1600         GSetIterator gh_iter;
1601         int totface = 0;
1602
1603         GSET_ITER (gh_iter, bm_faces) {
1604                 BMFace *f = BLI_gsetIterator_getKey(&gh_iter);
1605
1606                 if (!BM_elem_flag_test(f, BM_ELEM_HIDDEN))
1607                         totface++;
1608         }
1609
1610         return totface;
1611 }
1612
1613 /* Creates a vertex buffer (coordinate, normal, color) and, if smooth
1614  * shading, an element index buffer. */
1615 void GPU_update_bmesh_pbvh_buffers(GPU_PBVH_Buffers *buffers,
1616                                    BMesh *bm,
1617                                    GSet *bm_faces,
1618                                    GSet *bm_unique_verts,
1619                                    GSet *bm_other_verts,
1620                                    bool show_diffuse_color)
1621 {
1622         VertexBufferFormat *vert_data;
1623         void *tri_data;
1624         int tottri, totvert, maxvert = 0;
1625         float diffuse_color[4] = {0.8f, 0.8f, 0.8f, 1.0f};
1626
1627         /* TODO, make mask layer optional for bmesh buffer */
1628         const int cd_vert_mask_offset = CustomData_get_offset(&bm->vdata, CD_PAINT_MASK);
1629
1630         buffers->show_diffuse_color = show_diffuse_color;
1631         buffers->use_matcaps = GPU_material_use_matcaps_get();
1632
1633         /* Count visible triangles */
1634         tottri = gpu_bmesh_face_visible_count(bm_faces);
1635
1636         if (buffers->smooth) {
1637                 /* Count visible vertices */
1638                 totvert = gpu_bmesh_vert_visible_count(bm_unique_verts, bm_other_verts);
1639         }
1640         else
1641                 totvert = tottri * 3;
1642
1643         if (!tottri) {
1644                 buffers->tot_tri = 0;
1645                 return;
1646         }
1647
1648         if (buffers->use_matcaps)
1649                 diffuse_color[0] = diffuse_color[1] = diffuse_color[2] = 1.0;
1650         else if (show_diffuse_color) {
1651                 /* due to dynamic nature of dyntopo, only get first material */
1652                 GSetIterator gs_iter;
1653                 BMFace *f;
1654                 BLI_gsetIterator_init(&gs_iter, bm_faces);
1655                 f = BLI_gsetIterator_getKey(&gs_iter);
1656                 GPU_material_diffuse_get(f->mat_nr + 1, diffuse_color);
1657         }
1658
1659         copy_v4_v4(buffers->diffuse_color, diffuse_color);
1660
1661         /* Initialize vertex buffer */
1662         if (buffers->vert_buf)
1663                 GPU_buffer_free(buffers->vert_buf);
1664         buffers->vert_buf = GPU_buffer_alloc(sizeof(VertexBufferFormat) * totvert);
1665
1666         /* Fill vertex buffer */
1667         vert_data = GPU_buffer_lock(buffers->vert_buf, GPU_BINDING_ARRAY);
1668         if (vert_data) {
1669                 int v_index = 0;
1670
1671                 if (buffers->smooth) {
1672                         GSetIterator gs_iter;
1673
1674                         /* Vertices get an index assigned for use in the triangle
1675                          * index buffer */
1676                         bm->elem_index_dirty |= BM_VERT;
1677
1678                         GSET_ITER (gs_iter, bm_unique_verts) {
1679                                 gpu_bmesh_vert_to_buffer_copy(BLI_gsetIterator_getKey(&gs_iter),
1680                                                               vert_data, &v_index, NULL, NULL,
1681                                                               cd_vert_mask_offset, diffuse_color);
1682                         }
1683
1684                         GSET_ITER (gs_iter, bm_other_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                         maxvert = v_index;
1691                 }
1692                 else {
1693                         GSetIterator gs_iter;
1694
1695                         GSET_ITER (gs_iter, bm_faces) {
1696                                 BMFace *f = BLI_gsetIterator_getKey(&gs_iter);
1697
1698                                 BLI_assert(f->len == 3);
1699
1700                                 if (!BM_elem_flag_test(f, BM_ELEM_HIDDEN)) {
1701                                         BMVert *v[3];
1702                                         float fmask = 0;
1703                                         int i;
1704
1705 #if 0
1706                                         BM_iter_as_array(bm, BM_VERTS_OF_FACE, f, (void**)v, 3);
1707 #endif
1708                                         BM_face_as_array_vert_tri(f, v);
1709
1710                                         /* Average mask value */
1711                                         for (i = 0; i < 3; i++) {
1712                                                 fmask += BM_ELEM_CD_GET_FLOAT(v[i], cd_vert_mask_offset);
1713                                         }
1714                                         fmask /= 3.0f;
1715                                         
1716                                         for (i = 0; i < 3; i++) {
1717                                                 gpu_bmesh_vert_to_buffer_copy(v[i], vert_data,
1718                                                                               &v_index, f->no, &fmask,
1719                                                                               cd_vert_mask_offset, diffuse_color);
1720                                         }
1721                                 }
1722                         }
1723
1724                         buffers->tot_tri = tottri;
1725                 }
1726
1727                 GPU_buffer_unlock(buffers->vert_buf, GPU_BINDING_ARRAY);
1728
1729                 /* gpu_bmesh_vert_to_buffer_copy sets dirty index values */
1730                 bm->elem_index_dirty |= BM_VERT;
1731         }
1732         else {
1733                 /* Memory map failed */
1734                 GPU_buffer_free(buffers->vert_buf);
1735                 buffers->vert_buf = NULL;
1736                 return;
1737         }
1738
1739         if (buffers->smooth) {
1740                 const int use_short = (maxvert < USHRT_MAX);
1741
1742                 /* Initialize triangle index buffer */
1743                 if (buffers->index_buf)
1744                         GPU_buffer_free(buffers->index_buf);
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                         GPU_buffer_free(buffers->index_buf);
1790                         buffers->index_buf = NULL;
1791                 }
1792         }
1793         else if (buffers->index_buf) {
1794                 GPU_buffer_free(buffers->index_buf);
1795         }
1796 }
1797
1798 GPU_PBVH_Buffers *GPU_build_bmesh_pbvh_buffers(bool smooth_shading)
1799 {
1800         GPU_PBVH_Buffers *buffers;
1801
1802         buffers = MEM_callocN(sizeof(GPU_PBVH_Buffers), "GPU_Buffers");
1803         buffers->use_bmesh = true;
1804         buffers->smooth = smooth_shading;
1805         buffers->show_diffuse_color = false;
1806         buffers->use_matcaps = false;
1807
1808         return buffers;
1809 }
1810
1811 void GPU_draw_pbvh_buffers(GPU_PBVH_Buffers *buffers, DMSetMaterial setMaterial,
1812                            bool wireframe, bool fast)
1813 {
1814         bool do_fast = fast && buffers->index_buf_fast;
1815         /* sets material from the first face, to solve properly face would need to
1816          * be sorted in buckets by materials */
1817         if (setMaterial) {
1818                 if (buffers->face_indices_len) {
1819                         const MLoopTri *lt = &buffers->looptri[buffers->face_indices[0]];
1820                         const MPoly *mp = &buffers->mpoly[lt->poly];
1821                         if (!setMaterial(mp->mat_nr + 1, NULL))
1822                                 return;
1823                 }
1824                 else if (buffers->totgrid) {
1825                         const DMFlagMat *f = &buffers->grid_flag_mats[buffers->grid_indices[0]];
1826                         if (!setMaterial(f->mat_nr + 1, NULL))
1827                                 return;
1828                 }
1829                 else {
1830                         if (!setMaterial(1, NULL))
1831                                 return;
1832                 }
1833         }
1834
1835         glShadeModel((buffers->smooth || buffers->face_indices_len) ? GL_SMOOTH : GL_FLAT);
1836
1837         if (buffers->vert_buf) {
1838                 char *base = NULL;
1839                 char *index_base = NULL;
1840                 int bound_options = 0;
1841                 glEnableClientState(GL_VERTEX_ARRAY);
1842                 if (!wireframe) {
1843                         glEnableClientState(GL_NORMAL_ARRAY);
1844                         glEnableClientState(GL_COLOR_ARRAY);
1845
1846                         /* weak inspection of bound options, should not be necessary ideally */
1847                         bound_options = GPU_basic_shader_bound_options();
1848                         GPU_basic_shader_bind(bound_options | GPU_SHADER_USE_COLOR);
1849                 }
1850
1851                 GPU_buffer_bind(buffers->vert_buf, GPU_BINDING_ARRAY);
1852
1853                 if (do_fast) {
1854                         GPU_buffer_bind(buffers->index_buf_fast, GPU_BINDING_INDEX);
1855                 }
1856                 else if (buffers->index_buf) {
1857                         GPU_buffer_bind(buffers->index_buf, GPU_BINDING_INDEX);
1858                 }
1859
1860                 if (wireframe)
1861                         glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
1862
1863                 if (buffers->tot_quad) {
1864                         const char *offset = base;
1865                         const bool drawall = !(buffers->has_hidden || do_fast);
1866
1867                         if (GLEW_ARB_draw_elements_base_vertex && drawall) {
1868
1869                                 glVertexPointer(3, GL_FLOAT, sizeof(VertexBufferFormat),
1870                                                 offset + offsetof(VertexBufferFormat, co));
1871                                 glNormalPointer(GL_SHORT, sizeof(VertexBufferFormat),
1872                                                 offset + offsetof(VertexBufferFormat, no));
1873                                 glColorPointer(3, GL_UNSIGNED_BYTE, sizeof(VertexBufferFormat),
1874                                                offset + offsetof(VertexBufferFormat, color));
1875
1876                                 glMultiDrawElementsBaseVertex(GL_TRIANGLES, buffers->baseelemarray, buffers->index_type,
1877                                                               (const void * const *)buffers->baseindex,
1878                                                               buffers->totgrid, &buffers->baseelemarray[buffers->totgrid]);
1879                         }
1880                         else {
1881                                 int i, last = drawall ? buffers->totgrid : 1;
1882
1883                                 /* we could optimize this to one draw call, but it would need more memory */
1884                                 for (i = 0; i < last; i++) {
1885                                         glVertexPointer(3, GL_FLOAT, sizeof(VertexBufferFormat),
1886                                                         offset + offsetof(VertexBufferFormat, co));
1887                                         glNormalPointer(GL_SHORT, sizeof(VertexBufferFormat),
1888                                                         offset + offsetof(VertexBufferFormat, no));
1889                                         glColorPointer(3, GL_UNSIGNED_BYTE, sizeof(VertexBufferFormat),
1890                                                        offset + offsetof(VertexBufferFormat, color));
1891
1892                                         if (do_fast)
1893                                                 glDrawElements(GL_TRIANGLES, buffers->totgrid * 6, buffers->index_type, index_base);
1894                                         else
1895                                                 glDrawElements(GL_TRIANGLES, buffers->tot_quad * 6, buffers->index_type, index_base);
1896
1897                                         offset += buffers->gridkey.grid_area * sizeof(VertexBufferFormat);
1898                                 }
1899                         }
1900                 }
1901                 else if (buffers->tot_tri) {
1902                         int totelem = buffers->tot_tri * 3;
1903
1904                         glVertexPointer(3, GL_FLOAT, sizeof(VertexBufferFormat),
1905                                         (void *)(base + offsetof(VertexBufferFormat, co)));
1906                         glNormalPointer(GL_SHORT, sizeof(VertexBufferFormat),
1907                                         (void *)(base + offsetof(VertexBufferFormat, no)));
1908                         glColorPointer(3, GL_UNSIGNED_BYTE, sizeof(VertexBufferFormat),
1909                                        (void *)(base + offsetof(VertexBufferFormat, color)));
1910
1911                         if (buffers->index_buf)
1912                                 glDrawElements(GL_TRIANGLES, totelem, buffers->index_type, index_base);
1913                         else
1914                                 glDrawArrays(GL_TRIANGLES, 0, totelem);
1915                 }
1916
1917                 if (wireframe)
1918                         glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
1919
1920                 GPU_buffer_unbind(buffers->vert_buf, GPU_BINDING_ARRAY);
1921                 if (buffers->index_buf || do_fast)
1922                         GPU_buffer_unbind(do_fast ? buffers->index_buf_fast : buffers->index_buf, GPU_BINDING_INDEX);
1923
1924                 glDisableClientState(GL_VERTEX_ARRAY);
1925                 if (!wireframe) {
1926                         glDisableClientState(GL_NORMAL_ARRAY);
1927                         glDisableClientState(GL_COLOR_ARRAY);
1928                         GPU_basic_shader_bind(bound_options);
1929                 }
1930         }
1931 }
1932
1933 bool GPU_pbvh_buffers_diffuse_changed(GPU_PBVH_Buffers *buffers, GSet *bm_faces, bool show_diffuse_color)
1934 {
1935         float diffuse_color[4];
1936         bool use_matcaps = GPU_material_use_matcaps_get();
1937
1938         if (buffers->show_diffuse_color != show_diffuse_color)
1939                 return true;
1940
1941         if (buffers->use_matcaps != use_matcaps)
1942                 return true;
1943
1944         if ((buffers->show_diffuse_color == false) || use_matcaps)
1945                 return false;
1946
1947         if (buffers->looptri) {
1948                 const MLoopTri *lt = &buffers->looptri[buffers->face_indices[0]];
1949                 const MPoly *mp = &buffers->mpoly[lt->poly];
1950
1951                 GPU_material_diffuse_get(mp->mat_nr + 1, diffuse_color);
1952         }
1953         else if (buffers->use_bmesh) {
1954                 /* due to dynamic nature of dyntopo, only get first material */
1955                 if (BLI_gset_size(bm_faces) > 0) {
1956                         GSetIterator gs_iter;
1957                         BMFace *f;
1958
1959                         BLI_gsetIterator_init(&gs_iter, bm_faces);
1960                         f = BLI_gsetIterator_getKey(&gs_iter);
1961                         GPU_material_diffuse_get(f->mat_nr + 1, diffuse_color);
1962                 }
1963                 else {
1964                         return false;
1965                 }
1966         }
1967         else {
1968                 const DMFlagMat *flags = &buffers->grid_flag_mats[buffers->grid_indices[0]];
1969
1970                 GPU_material_diffuse_get(flags->mat_nr + 1, diffuse_color);
1971         }
1972
1973         return !equals_v3v3(diffuse_color, buffers->diffuse_color);
1974 }
1975
1976 void GPU_free_pbvh_buffers(GPU_PBVH_Buffers *buffers)
1977 {
1978         if (buffers) {
1979                 if (buffers->vert_buf)
1980                         GPU_buffer_free(buffers->vert_buf);
1981                 if (buffers->index_buf && (buffers->tot_tri || buffers->has_hidden))
1982                         GPU_buffer_free(buffers->index_buf);
1983                 if (buffers->index_buf_fast)
1984                         GPU_buffer_free(buffers->index_buf_fast);
1985                 if (buffers->baseelemarray)
1986                         MEM_freeN(buffers->baseelemarray);
1987                 if (buffers->baseindex)
1988                         MEM_freeN(buffers->baseindex);
1989
1990                 MEM_freeN(buffers);
1991         }
1992 }
1993
1994
1995 /* debug function, draws the pbvh BB */
1996 void GPU_draw_pbvh_BB(float min[3], float max[3], bool leaf)
1997 {
1998         const float quads[4][4][3] = {
1999                 {
2000                         {min[0], min[1], min[2]},
2001                         {max[0], min[1], min[2]},
2002                         {max[0], min[1], max[2]},
2003                         {min[0], min[1], max[2]}
2004                 },
2005
2006                 {
2007                         {min[0], min[1], min[2]},
2008                         {min[0], max[1], min[2]},
2009                         {min[0], max[1], max[2]},
2010                         {min[0], min[1], max[2]}
2011                 },
2012
2013                 {
2014                         {max[0], max[1], min[2]},
2015                         {max[0], min[1], min[2]},
2016                         {max[0], min[1], max[2]},
2017                         {max[0], max[1], max[2]}
2018                 },
2019
2020                 {
2021                         {max[0], max[1], min[2]},
2022                         {min[0], max[1], min[2]},
2023                         {min[0], max[1], max[2]},
2024                         {max[0], max[1], max[2]}
2025                 },
2026         };
2027
2028         if (leaf)
2029                 glColor4f(0.0, 1.0, 0.0, 0.5);
2030         else
2031                 glColor4f(1.0, 0.0, 0.0, 0.5);
2032
2033         glVertexPointer(3, GL_FLOAT, 0, &quads[0][0][0]);
2034         glDrawArrays(GL_QUADS, 0, 16);
2035 }
2036
2037 void GPU_init_draw_pbvh_BB(void)
2038 {
2039         glPushAttrib(GL_ENABLE_BIT);
2040         glDisable(GL_CULL_FACE);
2041         glEnableClientState(GL_VERTEX_ARRAY);
2042         glDisableClientState(GL_COLOR_ARRAY);
2043         glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
2044         glEnable(GL_BLEND);
2045 }
2046
2047 void GPU_end_draw_pbvh_BB(void)
2048 {
2049         glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
2050         glPopAttrib();
2051 }