Base refactor 3/4
[blender.git] / source / blender / gpu / intern / gpu_draw.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_draw.c
29  *  \ingroup gpu
30  *
31  * Utility functions for dealing with OpenGL texture & material context,
32  * mipmap generation and light objects.
33  *
34  * These are some obscure rendering functions shared between the
35  * game engine and the blender, in this module to avoid duplication
36  * and abstract them away from the rest a bit.
37  */
38
39 #include <string.h>
40
41 #include "BLI_blenlib.h"
42 #include "BLI_linklist.h"
43 #include "BLI_math.h"
44 #include "BLI_threads.h"
45 #include "BLI_utildefines.h"
46
47 #include "DNA_lamp_types.h"
48 #include "DNA_material_types.h"
49 #include "DNA_mesh_types.h"
50 #include "DNA_meshdata_types.h"
51 #include "DNA_modifier_types.h"
52 #include "DNA_node_types.h"
53 #include "DNA_object_types.h"
54 #include "DNA_scene_types.h"
55 #include "DNA_smoke_types.h"
56 #include "DNA_view3d_types.h"
57 #include "DNA_particle_types.h"
58
59 #include "MEM_guardedalloc.h"
60
61 #include "IMB_imbuf.h"
62 #include "IMB_imbuf_types.h"
63
64 #include "BKE_bmfont.h"
65 #include "BKE_global.h"
66 #include "BKE_image.h"
67 #include "BKE_main.h"
68 #include "BKE_material.h"
69 #include "BKE_node.h"
70 #include "BKE_scene.h"
71 #include "BKE_DerivedMesh.h"
72 #ifdef WITH_GAMEENGINE
73 #  include "BKE_object.h"
74 #endif
75
76 #include "GPU_basic_shader.h"
77 #include "GPU_buffers.h"
78 #include "GPU_draw.h"
79 #include "GPU_extensions.h"
80 #include "GPU_material.h"
81 #include "GPU_shader.h"
82 #include "GPU_texture.h"
83
84 #include "PIL_time.h"
85
86 #ifdef WITH_SMOKE
87 #  include "smoke_API.h"
88 #endif
89
90 #ifdef WITH_OPENSUBDIV
91 #  include "BKE_subsurf.h"
92 #  include "BKE_editmesh.h"
93
94 #  include "gpu_codegen.h"
95 #endif
96
97 extern Material defmaterial; /* from material.c */
98
99 /* Text Rendering */
100
101 static void gpu_mcol(unsigned int ucol)
102 {
103         /* mcol order is swapped */
104         const char *cp = (char *)&ucol;
105         glColor3ub(cp[3], cp[2], cp[1]);
106 }
107
108 void GPU_render_text(
109         MTexPoly *mtexpoly, int mode,
110         const char *textstr, int textlen, unsigned int *col,
111         const float *v_quad[4], const float *uv_quad[4],
112         int glattrib)
113 {
114         if ((mode & GEMAT_TEXT) && (textlen > 0) && mtexpoly->tpage) {
115                 const float *v1 = v_quad[0];
116                 const float *v2 = v_quad[1];
117                 const float *v3 = v_quad[2];
118                 const float *v4 = v_quad[3];
119                 Image *ima = (Image *)mtexpoly->tpage;
120                 const size_t textlen_st = textlen;
121                 float centerx, centery, sizex, sizey, transx, transy, movex, movey, advance;
122                 
123                 /* multiline */
124                 float line_start = 0.0f, line_height;
125                 
126                 if (v4)
127                         line_height = max_ffff(v1[1], v2[1], v3[1], v4[2]) - min_ffff(v1[1], v2[1], v3[1], v4[2]);
128                 else
129                         line_height = max_fff(v1[1], v2[1], v3[1]) - min_fff(v1[1], v2[1], v3[1]);
130                 line_height *= 1.2f; /* could be an option? */
131                 /* end multiline */
132
133                 
134                 /* color has been set */
135                 if (mtexpoly->mode & TF_OBCOL)
136                         col = NULL;
137                 else if (!col)
138                         glColor3f(1.0f, 1.0f, 1.0f);
139
140                 glPushMatrix();
141                 
142                 /* get the tab width */
143                 ImBuf *first_ibuf = BKE_image_get_first_ibuf(ima);
144                 matrixGlyph(first_ibuf, ' ', &centerx, &centery,
145                         &sizex, &sizey, &transx, &transy, &movex, &movey, &advance);
146                 
147                 float advance_tab = advance * 4; /* tab width could also be an option */
148                 
149                 
150                 for (size_t index = 0; index < textlen_st; ) {
151                         unsigned int character;
152                         float uv[4][2];
153
154                         /* lets calculate offset stuff */
155                         character = BLI_str_utf8_as_unicode_and_size_safe(textstr + index, &index);
156                         
157                         if (character == '\n') {
158                                 glTranslatef(line_start, -line_height, 0.0f);
159                                 line_start = 0.0f;
160                                 continue;
161                         }
162                         else if (character == '\t') {
163                                 glTranslatef(advance_tab, 0.0f, 0.0f);
164                                 line_start -= advance_tab; /* so we can go back to the start of the line */
165                                 continue;
166                                 
167                         }
168                         else if (character > USHRT_MAX) {
169                                 /* not much we can do here bmfonts take ushort */
170                                 character = '?';
171                         }
172                         
173                         /* space starts at offset 1 */
174                         /* character = character - ' ' + 1; */
175                         matrixGlyph(first_ibuf, character, & centerx, &centery,
176                                 &sizex, &sizey, &transx, &transy, &movex, &movey, &advance);
177
178                         uv[0][0] = (uv_quad[0][0] - centerx) * sizex + transx;
179                         uv[0][1] = (uv_quad[0][1] - centery) * sizey + transy;
180                         uv[1][0] = (uv_quad[1][0] - centerx) * sizex + transx;
181                         uv[1][1] = (uv_quad[1][1] - centery) * sizey + transy;
182                         uv[2][0] = (uv_quad[2][0] - centerx) * sizex + transx;
183                         uv[2][1] = (uv_quad[2][1] - centery) * sizey + transy;
184                         
185                         glBegin(GL_POLYGON);
186                         if (glattrib >= 0) glVertexAttrib2fv(glattrib, uv[0]);
187                         else glTexCoord2fv(uv[0]);
188                         if (col) gpu_mcol(col[0]);
189                         glVertex3f(sizex * v1[0] + movex, sizey * v1[1] + movey, v1[2]);
190                         
191                         if (glattrib >= 0) glVertexAttrib2fv(glattrib, uv[1]);
192                         else glTexCoord2fv(uv[1]);
193                         if (col) gpu_mcol(col[1]);
194                         glVertex3f(sizex * v2[0] + movex, sizey * v2[1] + movey, v2[2]);
195
196                         if (glattrib >= 0) glVertexAttrib2fv(glattrib, uv[2]);
197                         else glTexCoord2fv(uv[2]);
198                         if (col) gpu_mcol(col[2]);
199                         glVertex3f(sizex * v3[0] + movex, sizey * v3[1] + movey, v3[2]);
200
201                         if (v4) {
202                                 uv[3][0] = (uv_quad[3][0] - centerx) * sizex + transx;
203                                 uv[3][1] = (uv_quad[3][1] - centery) * sizey + transy;
204
205                                 if (glattrib >= 0) glVertexAttrib2fv(glattrib, uv[3]);
206                                 else glTexCoord2fv(uv[3]);
207                                 if (col) gpu_mcol(col[3]);
208                                 glVertex3f(sizex * v4[0] + movex, sizey * v4[1] + movey, v4[2]);
209                         }
210                         glEnd();
211
212                         glTranslatef(advance, 0.0f, 0.0f);
213                         line_start -= advance; /* so we can go back to the start of the line */
214                 }
215                 glPopMatrix();
216
217                 BKE_image_release_ibuf(ima, first_ibuf, NULL);
218         }
219 }
220
221 /* Checking powers of two for images since OpenGL ES requires it */
222
223 static bool is_power_of_2_resolution(int w, int h)
224 {
225         return is_power_of_2_i(w) && is_power_of_2_i(h);
226 }
227
228 static bool is_over_resolution_limit(GLenum textarget, int w, int h)
229 {
230         int size = (textarget == GL_TEXTURE_2D) ?
231                 GPU_max_texture_size() : GPU_max_cube_map_size();
232         int reslimit = (U.glreslimit != 0) ?
233                 min_ii(U.glreslimit, size) : size;
234
235         return (w > reslimit || h > reslimit);
236 }
237
238 static int smaller_power_of_2_limit(int num)
239 {
240         int reslimit = (U.glreslimit != 0) ?
241                 min_ii(U.glreslimit, GPU_max_texture_size()) :
242                 GPU_max_texture_size();
243         /* take texture clamping into account */
244         if (num > reslimit)
245                 return reslimit;
246
247         return power_of_2_min_i(num);
248 }
249
250 /* Current OpenGL state caching for GPU_set_tpage */
251
252 static struct GPUTextureState {
253         int curtile, tile;
254         int curtilemode, tilemode;
255         int curtileXRep, tileXRep;
256         int curtileYRep, tileYRep;
257         Image *ima, *curima;
258
259         /* also controls min/mag filtering */
260         bool domipmap;
261         /* only use when 'domipmap' is set */
262         bool linearmipmap;
263         /* store this so that new images created while texture painting won't be set to mipmapped */
264         bool texpaint;
265
266         int alphablend;
267         float anisotropic;
268         int gpu_mipmap;
269         MTexPoly *lasttface;
270 } GTS = {0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, 1, 0, 0, -1, 1.0f, 0, NULL};
271
272 /* Mipmap settings */
273
274 void GPU_set_gpu_mipmapping(int gpu_mipmap)
275 {
276         int old_value = GTS.gpu_mipmap;
277
278         /* only actually enable if it's supported */
279         GTS.gpu_mipmap = gpu_mipmap;
280
281         if (old_value != GTS.gpu_mipmap) {
282                 GPU_free_images();
283         }
284 }
285
286 static void gpu_generate_mipmap(GLenum target)
287 {
288         const bool is_ati = GPU_type_matches(GPU_DEVICE_ATI, GPU_OS_ANY, GPU_DRIVER_ANY);
289         int target_enabled = 0;
290
291         /* work around bug in ATI driver, need to have GL_TEXTURE_2D enabled
292          * http://www.opengl.org/wiki/Common_Mistakes#Automatic_mipmap_generation */
293         if (is_ati) {
294                 target_enabled = glIsEnabled(target);
295                 if (!target_enabled)
296                         glEnable(target);
297         }
298
299         glGenerateMipmap(target);
300
301         if (is_ati && !target_enabled)
302                 glDisable(target);
303 }
304
305 void GPU_set_mipmap(bool mipmap)
306 {
307         if (GTS.domipmap != mipmap) {
308                 GPU_free_images();
309                 GTS.domipmap = mipmap;
310         }
311 }
312
313 void GPU_set_linear_mipmap(bool linear)
314 {
315         if (GTS.linearmipmap != linear) {
316                 GTS.linearmipmap = linear;
317         }
318 }
319
320 bool GPU_get_mipmap(void)
321 {
322         return GTS.domipmap && !GTS.texpaint;
323 }
324
325 bool GPU_get_linear_mipmap(void)
326 {
327         return GTS.linearmipmap;
328 }
329
330 static GLenum gpu_get_mipmap_filter(bool mag)
331 {
332         /* linearmipmap is off by default *when mipmapping is off,
333          * use unfiltered display */
334         if (mag) {
335                 if (GTS.domipmap)
336                         return GL_LINEAR;
337                 else
338                         return GL_NEAREST;
339         }
340         else {
341                 if (GTS.domipmap) {
342                         if (GTS.linearmipmap) {
343                                 return GL_LINEAR_MIPMAP_LINEAR;
344                         }
345                         else {
346                                 return GL_LINEAR_MIPMAP_NEAREST;
347                         }
348                 }
349                 else {
350                         return GL_NEAREST;
351                 }
352         }
353 }
354
355 /* Anisotropic filtering settings */
356 void GPU_set_anisotropic(float value)
357 {
358         if (GTS.anisotropic != value) {
359                 GPU_free_images();
360
361                 /* Clamp value to the maximum value the graphics card supports */
362                 const float max = GPU_max_texture_anisotropy();
363                 if (value > max)
364                         value = max;
365
366                 GTS.anisotropic = value;
367         }
368 }
369
370 float GPU_get_anisotropic(void)
371 {
372         return GTS.anisotropic;
373 }
374
375 /* Set OpenGL state for an MTFace */
376
377 static void gpu_make_repbind(Image *ima)
378 {
379         ImBuf *ibuf = BKE_image_acquire_ibuf(ima, NULL, NULL);
380         if (ibuf == NULL)
381                 return;
382
383         if (ima->repbind) {
384                 glDeleteTextures(ima->totbind, (GLuint *)ima->repbind);
385                 MEM_freeN(ima->repbind);
386                 ima->repbind = NULL;
387                 ima->tpageflag &= ~IMA_MIPMAP_COMPLETE;
388         }
389
390         ima->totbind = ima->xrep * ima->yrep;
391
392         if (ima->totbind > 1) {
393                 ima->repbind = MEM_callocN(sizeof(int) * ima->totbind, "repbind");
394         }
395
396         BKE_image_release_ibuf(ima, ibuf, NULL);
397 }
398
399 static unsigned int *gpu_get_image_bindcode(Image *ima, GLenum textarget)
400 {
401         unsigned int *bind = 0;
402
403         if (textarget == GL_TEXTURE_2D)
404                 bind = &ima->bindcode[TEXTARGET_TEXTURE_2D];
405         else if (textarget == GL_TEXTURE_CUBE_MAP)
406                 bind = &ima->bindcode[TEXTARGET_TEXTURE_CUBE_MAP];
407
408         return bind;
409 }
410
411 void GPU_clear_tpage(bool force)
412 {
413         if (GTS.lasttface == NULL && !force)
414                 return;
415         
416         GTS.lasttface = NULL;
417         GTS.curtile = 0;
418         GTS.curima = NULL;
419         if (GTS.curtilemode != 0) {
420                 glMatrixMode(GL_TEXTURE);
421                 glLoadIdentity();
422                 glMatrixMode(GL_MODELVIEW);
423         }
424         GTS.curtilemode = 0;
425         GTS.curtileXRep = 0;
426         GTS.curtileYRep = 0;
427         GTS.alphablend = -1;
428         
429         glDisable(GL_BLEND);
430         glDisable(GL_TEXTURE_2D);
431         glDisable(GL_TEXTURE_GEN_S);
432         glDisable(GL_TEXTURE_GEN_T);
433         glDisable(GL_ALPHA_TEST);
434 }
435
436 static void gpu_set_alpha_blend(GPUBlendMode alphablend)
437 {
438         if (alphablend == GPU_BLEND_SOLID) {
439                 glDisable(GL_BLEND);
440                 glDisable(GL_ALPHA_TEST);
441                 glDisable(GL_SAMPLE_ALPHA_TO_COVERAGE);
442                 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
443         }
444         else if (alphablend == GPU_BLEND_ADD) {
445                 glEnable(GL_BLEND);
446                 glBlendFunc(GL_ONE, GL_ONE);
447                 glDisable(GL_ALPHA_TEST);
448                 glDisable(GL_SAMPLE_ALPHA_TO_COVERAGE);
449         }
450         else if (ELEM(alphablend, GPU_BLEND_ALPHA, GPU_BLEND_ALPHA_SORT)) {
451                 glEnable(GL_BLEND);
452                 glDisable(GL_SAMPLE_ALPHA_TO_COVERAGE);
453
454                 /* for OpenGL render we use the alpha channel, this makes alpha blend correct */
455                 glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
456                 
457                 /* if U.glalphaclip == 1.0, some cards go bonkers...
458                  * turn off alpha test in this case */
459
460                 /* added after 2.45 to clip alpha */
461                 if (U.glalphaclip == 1.0f) {
462                         glDisable(GL_ALPHA_TEST);
463                 }
464                 else {
465                         glEnable(GL_ALPHA_TEST);
466                         glAlphaFunc(GL_GREATER, U.glalphaclip);
467                 }
468         }
469         else if (alphablend == GPU_BLEND_CLIP) {
470                 glDisable(GL_BLEND);
471                 glDisable(GL_SAMPLE_ALPHA_TO_COVERAGE);
472                 glEnable(GL_ALPHA_TEST);
473                 glAlphaFunc(GL_GREATER, 0.5f);
474         }
475         else if (alphablend == GPU_BLEND_ALPHA_TO_COVERAGE) {
476                 glEnable(GL_ALPHA_TEST);
477                 glAlphaFunc(GL_GREATER, U.glalphaclip);
478                 glEnable(GL_SAMPLE_ALPHA_TO_COVERAGE);
479         }
480 }
481
482 static void gpu_verify_alpha_blend(int alphablend)
483 {
484         /* verify alpha blending modes */
485         if (GTS.alphablend == alphablend)
486                 return;
487
488         gpu_set_alpha_blend(alphablend);
489         GTS.alphablend = alphablend;
490 }
491
492 static void gpu_verify_reflection(Image *ima)
493 {
494         if (ima && (ima->flag & IMA_REFLECT)) {
495                 /* enable reflection mapping */
496                 glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP);
497                 glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP);
498
499                 glEnable(GL_TEXTURE_GEN_S);
500                 glEnable(GL_TEXTURE_GEN_T);
501         }
502         else {
503                 /* disable reflection mapping */
504                 glDisable(GL_TEXTURE_GEN_S);
505                 glDisable(GL_TEXTURE_GEN_T);
506         }
507 }
508
509 typedef struct VerifyThreadData {
510         ImBuf *ibuf;
511         float *srgb_frect;
512 } VerifyThreadData;
513
514 static void gpu_verify_high_bit_srgb_buffer_slice(float *srgb_frect,
515                                                   ImBuf *ibuf,
516                                                   const int start_line,
517                                                   const int height)
518 {
519         size_t offset = ibuf->channels * start_line * ibuf->x;
520         float *current_srgb_frect = srgb_frect + offset;
521         float *current_rect_float = ibuf->rect_float + offset;
522         IMB_buffer_float_from_float(current_srgb_frect,
523                                     current_rect_float,
524                                     ibuf->channels,
525                                     IB_PROFILE_SRGB,
526                                     IB_PROFILE_LINEAR_RGB, true,
527                                     ibuf->x, height,
528                                     ibuf->x, ibuf->x);
529         IMB_buffer_float_unpremultiply(current_srgb_frect, ibuf->x, height);
530         /* Clamp buffer colors to 1.0 to avoid artifacts due to glu for hdr images. */
531         IMB_buffer_float_clamp(current_srgb_frect, ibuf->x, height);
532 }
533
534 static void verify_thread_do(void *data_v,
535                              int start_scanline,
536                              int num_scanlines)
537 {
538         VerifyThreadData *data = (VerifyThreadData *)data_v;
539         gpu_verify_high_bit_srgb_buffer_slice(data->srgb_frect,
540                                               data->ibuf,
541                                               start_scanline,
542                                               num_scanlines);
543 }
544
545 static void gpu_verify_high_bit_srgb_buffer(float *srgb_frect,
546                                             ImBuf *ibuf)
547 {
548         if (ibuf->y < 64) {
549                 gpu_verify_high_bit_srgb_buffer_slice(srgb_frect,
550                                                       ibuf,
551                                                       0, ibuf->y);
552         }
553         else {
554                 VerifyThreadData data;
555                 data.ibuf = ibuf;
556                 data.srgb_frect = srgb_frect;
557                 IMB_processor_apply_threaded_scanlines(ibuf->y, verify_thread_do, &data);
558         }
559 }
560
561 int GPU_verify_image(
562         Image *ima, ImageUser *iuser,
563         int textarget, int tftile, bool compare, bool mipmap, bool is_data)
564 {
565         unsigned int *bind = NULL;
566         int tpx = 0, tpy = 0;
567         unsigned int *rect = NULL;
568         float *frect = NULL;
569         float *srgb_frect = NULL;
570         /* flag to determine whether deep format is used */
571         bool use_high_bit_depth = false, do_color_management = false;
572
573         /* initialize tile mode and number of repeats */
574         GTS.ima = ima;
575         GTS.tilemode = (ima && (ima->tpageflag & (IMA_TILES | IMA_TWINANIM)));
576         GTS.tileXRep = 0;
577         GTS.tileYRep = 0;
578
579         /* setting current tile according to frame */
580         if (ima && (ima->tpageflag & IMA_TWINANIM))
581                 GTS.tile = ima->lastframe;
582         else
583                 GTS.tile = tftile;
584
585         GTS.tile = MAX2(0, GTS.tile);
586
587         if (ima) {
588                 GTS.tileXRep = ima->xrep;
589                 GTS.tileYRep = ima->yrep;
590         }
591
592         /* if same image & tile, we're done */
593         if (compare && ima == GTS.curima && GTS.curtile == GTS.tile &&
594             GTS.tilemode == GTS.curtilemode && GTS.curtileXRep == GTS.tileXRep &&
595             GTS.curtileYRep == GTS.tileYRep)
596         {
597                 return (ima != NULL);
598         }
599
600         /* if tiling mode or repeat changed, change texture matrix to fit */
601         if (GTS.tilemode != GTS.curtilemode || GTS.curtileXRep != GTS.tileXRep ||
602             GTS.curtileYRep != GTS.tileYRep)
603         {
604                 glMatrixMode(GL_TEXTURE);
605                 glLoadIdentity();
606
607                 if (ima && (ima->tpageflag & IMA_TILES))
608                         glScalef(ima->xrep, ima->yrep, 1.0f);
609
610                 glMatrixMode(GL_MODELVIEW);
611         }
612
613         /* check if we have a valid image */
614         if (ima == NULL || ima->ok == 0)
615                 return 0;
616
617         /* check if we have a valid image buffer */
618         ImBuf *ibuf = BKE_image_acquire_ibuf(ima, iuser, NULL);
619
620         if (ibuf == NULL)
621                 return 0;
622
623         if (ibuf->rect_float) {
624                 if (U.use_16bit_textures) {
625                         /* use high precision textures. This is relatively harmless because OpenGL gives us
626                          * a high precision format only if it is available */
627                         use_high_bit_depth = true;
628                 }
629                 else if (ibuf->rect == NULL) {
630                         IMB_rect_from_float(ibuf);
631                 }
632                 /* we may skip this in high precision, but if not, we need to have a valid buffer here */
633                 else if (ibuf->userflags & IB_RECT_INVALID) {
634                         IMB_rect_from_float(ibuf);
635                 }
636
637                 /* TODO unneeded when float images are correctly treated as linear always */
638                 if (!is_data) {
639                         do_color_management = true;
640                 }
641         }
642
643         /* currently, tpage refresh is used by ima sequences */
644         if (ima->tpageflag & IMA_TPAGE_REFRESH) {
645                 GPU_free_image(ima);
646                 ima->tpageflag &= ~IMA_TPAGE_REFRESH;
647         }
648         
649         if (GTS.tilemode) {
650                 /* tiled mode */
651                 if (ima->repbind == NULL) gpu_make_repbind(ima);
652                 if (GTS.tile >= ima->totbind) GTS.tile = 0;
653                 
654                 /* this happens when you change repeat buttons */
655                 if (ima->repbind && textarget == GL_TEXTURE_2D) bind = &ima->repbind[GTS.tile];
656                 else bind = gpu_get_image_bindcode(ima, textarget);
657                 
658                 if (*bind == 0) {
659                         short texwindx = ibuf->x / ima->xrep;
660                         short texwindy = ibuf->y / ima->yrep;
661                         
662                         if (GTS.tile >= ima->xrep * ima->yrep)
663                                 GTS.tile = ima->xrep * ima->yrep - 1;
664         
665                         short texwinsy = GTS.tile / ima->xrep;
666                         short texwinsx = GTS.tile - texwinsy * ima->xrep;
667         
668                         texwinsx *= texwindx;
669                         texwinsy *= texwindy;
670         
671                         tpx = texwindx;
672                         tpy = texwindy;
673
674                         if (use_high_bit_depth) {
675                                 if (do_color_management) {
676                                         srgb_frect = MEM_mallocN(ibuf->x * ibuf->y * sizeof(float) * 4, "floar_buf_col_cor");
677                                         gpu_verify_high_bit_srgb_buffer(srgb_frect, ibuf);
678                                         frect = srgb_frect + texwinsy * ibuf->x + texwinsx;
679                                 }
680                                 else {
681                                         frect = ibuf->rect_float + texwinsy * ibuf->x + texwinsx;
682                                 }
683                         }
684                         else {
685                                 rect = ibuf->rect + texwinsy * ibuf->x + texwinsx;
686                         }
687                 }
688         }
689         else {
690                 /* regular image mode */
691                 bind = gpu_get_image_bindcode(ima, textarget);
692
693                 if (*bind == 0) {
694                         tpx = ibuf->x;
695                         tpy = ibuf->y;
696                         rect = ibuf->rect;
697                         if (use_high_bit_depth) {
698                                 if (do_color_management) {
699                                         frect = srgb_frect = MEM_mallocN(ibuf->x * ibuf->y * sizeof(*srgb_frect) * 4, "floar_buf_col_cor");
700                                         gpu_verify_high_bit_srgb_buffer(srgb_frect, ibuf);
701                                 }
702                                 else
703                                         frect = ibuf->rect_float;
704                         }
705                 }
706         }
707
708         if (*bind != 0) {
709                 /* enable opengl drawing with textures */
710                 glBindTexture(textarget, *bind);
711                 BKE_image_release_ibuf(ima, ibuf, NULL);
712                 return *bind;
713         }
714
715         const int rectw = tpx;
716         const int recth = tpy;
717
718         unsigned *tilerect = NULL;
719         float *ftilerect = NULL;
720
721         /* for tiles, copy only part of image into buffer */
722         if (GTS.tilemode) {
723                 if (use_high_bit_depth) {
724                         ftilerect = MEM_mallocN(rectw * recth * sizeof(*ftilerect), "tilerect");
725
726                         for (int y = 0; y < recth; y++) {
727                                 const float *frectrow = &frect[y * ibuf->x];
728                                 float *ftilerectrow = &ftilerect[y * rectw];
729
730                                 memcpy(ftilerectrow, frectrow, tpx * sizeof(*frectrow));
731                         }
732
733                         frect = ftilerect;
734                 }
735                 else {
736                         tilerect = MEM_mallocN(rectw * recth * sizeof(*tilerect), "tilerect");
737
738                         for (int y = 0; y < recth; y++) {
739                                 const unsigned *rectrow = &rect[y * ibuf->x];
740                                 unsigned *tilerectrow = &tilerect[y * rectw];
741
742                                 memcpy(tilerectrow, rectrow, tpx * sizeof(*rectrow));
743                         }
744                         
745                         rect = tilerect;
746                 }
747         }
748
749 #ifdef WITH_DDS
750         if (ibuf->ftype == IMB_FTYPE_DDS)
751                 GPU_create_gl_tex_compressed(bind, rect, rectw, recth, textarget, mipmap, ima, ibuf);
752         else
753 #endif
754                 GPU_create_gl_tex(bind, rect, frect, rectw, recth, textarget, mipmap, use_high_bit_depth, ima);
755         
756         /* mark as non-color data texture */
757         if (*bind) {
758                 if (is_data)
759                         ima->tpageflag |= IMA_GLBIND_IS_DATA;   
760                 else
761                         ima->tpageflag &= ~IMA_GLBIND_IS_DATA;  
762         }
763
764         /* clean up */
765         if (tilerect)
766                 MEM_freeN(tilerect);
767         if (ftilerect)
768                 MEM_freeN(ftilerect);
769         if (srgb_frect)
770                 MEM_freeN(srgb_frect);
771
772         BKE_image_release_ibuf(ima, ibuf, NULL);
773
774         return *bind;
775 }
776
777 static void **gpu_gen_cube_map(unsigned int *rect, float *frect, int rectw, int recth, bool use_high_bit_depth)
778 {
779         size_t block_size = use_high_bit_depth ? sizeof(float) * 4 : sizeof(unsigned char) * 4;
780         void **sides = NULL;
781         int h = recth / 2;
782         int w = rectw / 3;
783
784         if ((use_high_bit_depth && frect == NULL) || (!use_high_bit_depth && rect == NULL) || w != h)
785                 return sides;
786
787         /* PosX, NegX, PosY, NegY, PosZ, NegZ */
788         sides = MEM_mallocN(sizeof(void *) * 6, "");
789         for (int i = 0; i < 6; i++)
790                 sides[i] = MEM_mallocN(block_size * w * h, "");
791
792         /* divide image into six parts */
793         /* ______________________
794          * |      |      |      |
795          * | NegX | NegY | PosX |
796          * |______|______|______|
797          * |      |      |      |
798          * | NegZ | PosZ | PosY |
799          * |______|______|______|
800          */
801         if (use_high_bit_depth) {
802                 float (*frectb)[4] = (float(*)[4])frect;
803                 float (**fsides)[4] = (float(**)[4])sides;
804
805                 for (int y = 0; y < h; y++) {
806                         for (int x = 0; x < w; x++) {
807                                 memcpy(&fsides[0][x * h + y], &frectb[(recth - y - 1) * rectw + 2 * w + x], block_size);
808                                 memcpy(&fsides[1][x * h + y], &frectb[(y + h) * rectw + w - 1 - x], block_size);
809                                 memcpy(&fsides[3][y * w + x], &frectb[(recth - y - 1) * rectw + 2 * w - 1 - x], block_size);
810                                 memcpy(&fsides[5][y * w + x], &frectb[(h - y - 1) * rectw + w - 1 - x], block_size);
811                         }
812                         memcpy(&fsides[2][y * w], frectb[y * rectw + 2 * w], block_size * w);
813                         memcpy(&fsides[4][y * w], frectb[y * rectw + w], block_size * w);
814                 }
815         }
816         else {
817                 unsigned int **isides = (unsigned int **)sides;
818
819                 for (int y = 0; y < h; y++) {
820                         for (int x = 0; x < w; x++) {
821                                 isides[0][x * h + y] = rect[(recth - y - 1) * rectw + 2 * w + x];
822                                 isides[1][x * h + y] = rect[(y + h) * rectw + w - 1 - x];
823                                 isides[3][y * w + x] = rect[(recth - y - 1) * rectw + 2 * w - 1 - x];
824                                 isides[5][y * w + x] = rect[(h - y - 1) * rectw + w - 1 - x];
825                         }
826                         memcpy(&isides[2][y * w], &rect[y * rectw + 2 * w], block_size * w);
827                         memcpy(&isides[4][y * w], &rect[y * rectw + w], block_size * w);
828                 }
829         }
830
831         return sides;
832 }
833
834 static void gpu_del_cube_map(void **cube_map)
835 {
836         int i;
837         if (cube_map == NULL)
838                 return;
839         for (i = 0; i < 6; i++)
840                 MEM_freeN(cube_map[i]);
841         MEM_freeN(cube_map);
842 }
843
844 /* Image *ima can be NULL */
845 void GPU_create_gl_tex(
846         unsigned int *bind, unsigned int *rect, float *frect, int rectw, int recth,
847         int textarget, bool mipmap, bool use_high_bit_depth, Image *ima)
848 {
849         ImBuf *ibuf = NULL;
850
851         int tpx = rectw;
852         int tpy = recth;
853
854         /* create image */
855         glGenTextures(1, (GLuint *)bind);
856         glBindTexture(textarget, *bind);
857
858         if (textarget == GL_TEXTURE_2D) {
859                 if (use_high_bit_depth) {
860                         if (GLEW_ARB_texture_float)
861                                 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA16F_ARB, rectw, recth, 0, GL_RGBA, GL_FLOAT, frect);
862                         else
863                                 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA16, rectw, recth, 0, GL_RGBA, GL_FLOAT, frect);
864                 }
865                 else
866                         glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, rectw, recth, 0, GL_RGBA, GL_UNSIGNED_BYTE, rect);
867
868                 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, gpu_get_mipmap_filter(1));
869
870                 if (GPU_get_mipmap() && mipmap) {
871                         if (GTS.gpu_mipmap) {
872                                 gpu_generate_mipmap(GL_TEXTURE_2D);
873                         }
874                         else {
875                                 int i;
876                                 if (!ibuf) {
877                                         if (use_high_bit_depth) {
878                                                 ibuf = IMB_allocFromBuffer(NULL, frect, tpx, tpy);
879                                         }
880                                         else {
881                                                 ibuf = IMB_allocFromBuffer(rect, NULL, tpx, tpy);
882                                         }
883                                 }
884                                 IMB_makemipmap(ibuf, true);
885
886                                 for (i = 1; i < ibuf->miptot; i++) {
887                                         ImBuf *mip = ibuf->mipmap[i - 1];
888                                         if (use_high_bit_depth) {
889                                                 if (GLEW_ARB_texture_float)
890                                                         glTexImage2D(GL_TEXTURE_2D, i, GL_RGBA16F_ARB, mip->x, mip->y, 0, GL_RGBA, GL_FLOAT, mip->rect_float);
891                                                 else
892                                                         glTexImage2D(GL_TEXTURE_2D, i, GL_RGBA16, mip->x, mip->y, 0, GL_RGBA, GL_FLOAT, mip->rect_float);
893                                         }
894                                         else {
895                                                 glTexImage2D(GL_TEXTURE_2D, i, GL_RGBA8, mip->x, mip->y, 0, GL_RGBA, GL_UNSIGNED_BYTE, mip->rect);
896                                         }
897                                 }
898                         }
899                         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, gpu_get_mipmap_filter(0));
900                         if (ima)
901                                 ima->tpageflag |= IMA_MIPMAP_COMPLETE;
902                 }
903                 else {
904                         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
905                 }
906         }
907         else if (textarget == GL_TEXTURE_CUBE_MAP) {
908                 int w = rectw / 3, h = recth / 2;
909
910                 if (h == w && is_power_of_2_i(h) && !is_over_resolution_limit(textarget, h, w)) {
911                         void **cube_map = gpu_gen_cube_map(rect, frect, rectw, recth, use_high_bit_depth);
912                         GLenum informat = use_high_bit_depth ? (GLEW_ARB_texture_float ? GL_RGBA16F_ARB : GL_RGBA16) : GL_RGBA8;
913                         GLenum type = use_high_bit_depth ? GL_FLOAT : GL_UNSIGNED_BYTE;
914
915                         if (cube_map)
916                                 for (int i = 0; i < 6; i++)
917                                         glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, informat, w, h, 0, GL_RGBA, type, cube_map[i]);
918
919                         glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, gpu_get_mipmap_filter(1));
920
921                         if (GPU_get_mipmap() && mipmap) {
922                                 if (GTS.gpu_mipmap) {
923                                         gpu_generate_mipmap(GL_TEXTURE_CUBE_MAP);
924                                 }
925                                 else {
926                                         if (!ibuf) {
927                                                 if (use_high_bit_depth) {
928                                                         ibuf = IMB_allocFromBuffer(NULL, frect, tpx, tpy);
929                                                 }
930                                                 else {
931                                                         ibuf = IMB_allocFromBuffer(rect, NULL, tpx, tpy);
932                                                 }
933                                         }
934
935                                         IMB_makemipmap(ibuf, true);
936
937                                         for (int i = 1; i < ibuf->miptot; i++) {
938                                                 ImBuf *mip = ibuf->mipmap[i - 1];
939                                                 void **mip_cube_map = gpu_gen_cube_map(
940                                                         mip->rect, mip->rect_float,
941                                                         mip->x, mip->y, use_high_bit_depth);
942                                                 int mipw = mip->x / 3, miph = mip->y / 2;
943
944                                                 if (mip_cube_map) {
945                                                         for (int j = 0; j < 6; j++) {
946                                                                 glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + j, i,
947                                                                         informat, mipw, miph, 0, GL_RGBA, type, mip_cube_map[j]);
948                                                         }
949                                                 }
950                                                 gpu_del_cube_map(mip_cube_map);
951                                         }
952                                 }
953                                 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, gpu_get_mipmap_filter(0));
954
955                                 if (ima)
956                                         ima->tpageflag |= IMA_MIPMAP_COMPLETE;
957                         }
958                         else {
959                                 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
960                         }
961                         glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
962                         glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
963                         glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
964
965                         gpu_del_cube_map(cube_map);
966                 }
967                 else {
968                         printf("Incorrect envmap size\n");
969                 }
970         }
971
972         if (GLEW_EXT_texture_filter_anisotropic)
973                 glTexParameterf(textarget, GL_TEXTURE_MAX_ANISOTROPY_EXT, GPU_get_anisotropic());
974
975         if (ibuf)
976                 IMB_freeImBuf(ibuf);
977 }
978
979 /**
980  * GPU_upload_dxt_texture() assumes that the texture is already bound and ready to go.
981  * This is so the viewport and the BGE can share some code.
982  * Returns false if the provided ImBuf doesn't have a supported DXT compression format
983  */
984 bool GPU_upload_dxt_texture(ImBuf *ibuf)
985 {
986 #ifdef WITH_DDS
987         GLint format = 0;
988         int blocksize, height, width, i, size, offset = 0;
989
990         width = ibuf->x;
991         height = ibuf->y;
992
993         if (GLEW_EXT_texture_compression_s3tc) {
994                 if (ibuf->dds_data.fourcc == FOURCC_DXT1)
995                         format = GL_COMPRESSED_RGBA_S3TC_DXT1_EXT;
996                 else if (ibuf->dds_data.fourcc == FOURCC_DXT3)
997                         format = GL_COMPRESSED_RGBA_S3TC_DXT3_EXT;
998                 else if (ibuf->dds_data.fourcc == FOURCC_DXT5)
999                         format = GL_COMPRESSED_RGBA_S3TC_DXT5_EXT;
1000         }
1001
1002         if (format == 0) {
1003                 fprintf(stderr, "Unable to find a suitable DXT compression, falling back to uncompressed\n");
1004                 return false;
1005         }
1006
1007         if (!is_power_of_2_resolution(width, height)) {
1008                 fprintf(stderr, "Unable to load non-power-of-two DXT image resolution, falling back to uncompressed\n");
1009                 return false;
1010         }
1011
1012         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, gpu_get_mipmap_filter(0));
1013         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, gpu_get_mipmap_filter(1));
1014
1015         if (GLEW_EXT_texture_filter_anisotropic)
1016                 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, GPU_get_anisotropic());
1017
1018         blocksize = (ibuf->dds_data.fourcc == FOURCC_DXT1) ? 8 : 16;
1019         for (i = 0; i < ibuf->dds_data.nummipmaps && (width || height); ++i) {
1020                 if (width == 0)
1021                         width = 1;
1022                 if (height == 0)
1023                         height = 1;
1024
1025                 size = ((width + 3) / 4) * ((height + 3) / 4) * blocksize;
1026
1027                 glCompressedTexImage2D(GL_TEXTURE_2D, i, format, width, height,
1028                         0, size, ibuf->dds_data.data + offset);
1029
1030                 offset += size;
1031                 width >>= 1;
1032                 height >>= 1;
1033         }
1034
1035         /* set number of mipmap levels we have, needed in case they don't go down to 1x1 */
1036         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, i - 1);
1037
1038         return true;
1039 #else
1040         (void)ibuf;
1041         return false;
1042 #endif
1043 }
1044
1045 void GPU_create_gl_tex_compressed(
1046         unsigned int *bind, unsigned int *pix, int x, int y,
1047         int textarget, int mipmap, Image *ima, ImBuf *ibuf)
1048 {
1049 #ifndef WITH_DDS
1050         (void)ibuf;
1051         /* Fall back to uncompressed if DDS isn't enabled */
1052         GPU_create_gl_tex(bind, pix, NULL, x, y, textarget, mipmap, 0, ima);
1053 #else
1054         glGenTextures(1, (GLuint *)bind);
1055         glBindTexture(textarget, *bind);
1056
1057         if (textarget == GL_TEXTURE_2D && GPU_upload_dxt_texture(ibuf) == 0) {
1058                 glDeleteTextures(1, (GLuint *)bind);
1059                 GPU_create_gl_tex(bind, pix, NULL, x, y, textarget, mipmap, 0, ima);
1060         }
1061 #endif
1062 }
1063 static void gpu_verify_repeat(Image *ima)
1064 {
1065         /* set either clamp or repeat in X/Y */
1066         if (ima->tpageflag & IMA_CLAMP_U)
1067                 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
1068         else
1069                 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
1070
1071         if (ima->tpageflag & IMA_CLAMP_V)
1072                 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
1073         else
1074                 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
1075 }
1076
1077 int GPU_set_tpage(MTexPoly *mtexpoly, int mipmap, int alphablend)
1078 {
1079         /* check if we need to clear the state */
1080         if (mtexpoly == NULL) {
1081                 GPU_clear_tpage(false);
1082                 return 0;
1083         }
1084
1085         Image *ima = mtexpoly->tpage;
1086         GTS.lasttface = mtexpoly;
1087
1088         gpu_verify_alpha_blend(alphablend);
1089         gpu_verify_reflection(ima);
1090
1091         if (GPU_verify_image(ima, NULL, GL_TEXTURE_2D, mtexpoly->tile, 1, mipmap, false)) {
1092                 GTS.curtile = GTS.tile;
1093                 GTS.curima = GTS.ima;
1094                 GTS.curtilemode = GTS.tilemode;
1095                 GTS.curtileXRep = GTS.tileXRep;
1096                 GTS.curtileYRep = GTS.tileYRep;
1097
1098                 glEnable(GL_TEXTURE_2D);
1099         }
1100         else {
1101                 glDisable(GL_TEXTURE_2D);
1102                 
1103                 GTS.curtile = 0;
1104                 GTS.curima = NULL;
1105                 GTS.curtilemode = 0;
1106                 GTS.curtileXRep = 0;
1107                 GTS.curtileYRep = 0;
1108
1109                 return 0;
1110         }
1111         
1112         gpu_verify_repeat(ima);
1113         
1114         /* Did this get lost in the image recode? */
1115         /* BKE_image_tag_time(ima);*/
1116
1117         return 1;
1118 }
1119
1120 /* these two functions are called on entering and exiting texture paint mode,
1121  * temporary disabling/enabling mipmapping on all images for quick texture
1122  * updates with glTexSubImage2D. images that didn't change don't have to be
1123  * re-uploaded to OpenGL */
1124 void GPU_paint_set_mipmap(bool mipmap)
1125 {
1126         if (!GTS.domipmap)
1127                 return;
1128
1129         GTS.texpaint = !mipmap;
1130
1131         if (mipmap) {
1132                 for (Image *ima = G.main->image.first; ima; ima = ima->id.next) {
1133                         if (BKE_image_has_bindcode(ima)) {
1134                                 if (ima->tpageflag & IMA_MIPMAP_COMPLETE) {
1135                                         if (ima->bindcode[TEXTARGET_TEXTURE_2D]) {
1136                                                 glBindTexture(GL_TEXTURE_2D, ima->bindcode[TEXTARGET_TEXTURE_2D]);
1137                                                 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, gpu_get_mipmap_filter(0));
1138                                                 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, gpu_get_mipmap_filter(1));
1139                                         }
1140                                         if (ima->bindcode[TEXTARGET_TEXTURE_CUBE_MAP]) {
1141                                                 glBindTexture(GL_TEXTURE_CUBE_MAP, ima->bindcode[TEXTARGET_TEXTURE_CUBE_MAP]);
1142                                                 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, gpu_get_mipmap_filter(0));
1143                                                 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, gpu_get_mipmap_filter(1));
1144                                         }
1145                                 }
1146                                 else
1147                                         GPU_free_image(ima);
1148                         }
1149                         else
1150                                 ima->tpageflag &= ~IMA_MIPMAP_COMPLETE;
1151                 }
1152
1153         }
1154         else {
1155                 for (Image *ima = G.main->image.first; ima; ima = ima->id.next) {
1156                         if (BKE_image_has_bindcode(ima)) {
1157                                 if (ima->bindcode[TEXTARGET_TEXTURE_2D]) {
1158                                         glBindTexture(GL_TEXTURE_2D, ima->bindcode[TEXTARGET_TEXTURE_2D]);
1159                                         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
1160                                         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, gpu_get_mipmap_filter(1));
1161                                 }
1162                                 if (ima->bindcode[TEXTARGET_TEXTURE_CUBE_MAP]) {
1163                                         glBindTexture(GL_TEXTURE_CUBE_MAP, ima->bindcode[TEXTARGET_TEXTURE_CUBE_MAP]);
1164                                         glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
1165                                         glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, gpu_get_mipmap_filter(1));
1166                                 }
1167                         }
1168                         else
1169                                 ima->tpageflag &= ~IMA_MIPMAP_COMPLETE;
1170                 }
1171         }
1172 }
1173
1174
1175 /* check if image has been downscaled and do scaled partial update */
1176 static bool GPU_check_scaled_image(ImBuf *ibuf, Image *ima, float *frect, int x, int y, int w, int h)
1177 {
1178         if (is_over_resolution_limit(GL_TEXTURE_2D, ibuf->x, ibuf->y)) {
1179                 int x_limit = smaller_power_of_2_limit(ibuf->x);
1180                 int y_limit = smaller_power_of_2_limit(ibuf->y);
1181
1182                 float xratio = x_limit / (float)ibuf->x;
1183                 float yratio = y_limit / (float)ibuf->y;
1184
1185                 /* find new width, height and x,y gpu texture coordinates */
1186
1187                 /* take ceiling because we will be losing 1 pixel due to rounding errors in x,y... */
1188                 int rectw = (int)ceil(xratio * w);
1189                 int recth = (int)ceil(yratio * h);
1190
1191                 x *= xratio;
1192                 y *= yratio;
1193
1194                 /* ...but take back if we are over the limit! */
1195                 if (rectw + x > x_limit) rectw--;
1196                 if (recth + y > y_limit) recth--;
1197
1198                 /* float rectangles are already continuous in memory so we can use IMB_scaleImBuf */
1199                 if (frect) {
1200                         ImBuf *ibuf_scale = IMB_allocFromBuffer(NULL, frect, w, h);
1201                         IMB_scaleImBuf(ibuf_scale, rectw, recth);
1202
1203                         glBindTexture(GL_TEXTURE_2D, ima->bindcode[TEXTARGET_TEXTURE_2D]);
1204                         glTexSubImage2D(GL_TEXTURE_2D, 0, x, y, rectw, recth, GL_RGBA,
1205                                         GL_FLOAT, ibuf_scale->rect_float);
1206
1207                         IMB_freeImBuf(ibuf_scale);
1208                 }
1209                 /* byte images are not continuous in memory so do manual interpolation */
1210                 else {
1211                         unsigned char *scalerect = MEM_mallocN(rectw * recth * sizeof(*scalerect) * 4, "scalerect");
1212                         unsigned int *p = (unsigned int *)scalerect;
1213                         int i, j;
1214                         float inv_xratio = 1.0f / xratio;
1215                         float inv_yratio = 1.0f / yratio;
1216                         for (i = 0; i < rectw; i++) {
1217                                 float u = (x + i) * inv_xratio;
1218                                 for (j = 0; j < recth; j++) {
1219                                         float v = (y + j) * inv_yratio;
1220                                         bilinear_interpolation_color_wrap(ibuf, (unsigned char *)(p + i + j * (rectw)), NULL, u, v);
1221                                 }
1222                         }
1223                         glBindTexture(GL_TEXTURE_2D, ima->bindcode[TEXTARGET_TEXTURE_2D]);
1224                         glTexSubImage2D(GL_TEXTURE_2D, 0, x, y, rectw, recth, GL_RGBA,
1225                                         GL_UNSIGNED_BYTE, scalerect);
1226
1227                         MEM_freeN(scalerect);
1228                 }
1229
1230                 if (GPU_get_mipmap()) {
1231                         gpu_generate_mipmap(GL_TEXTURE_2D);
1232                 }
1233                 else {
1234                         ima->tpageflag &= ~IMA_MIPMAP_COMPLETE;
1235                 }
1236
1237                 return true;
1238         }
1239
1240         return false;
1241 }
1242
1243 void GPU_paint_update_image(Image *ima, ImageUser *iuser, int x, int y, int w, int h)
1244 {
1245         ImBuf *ibuf = BKE_image_acquire_ibuf(ima, iuser, NULL);
1246
1247         if (ima->repbind ||
1248             (!GTS.gpu_mipmap && GPU_get_mipmap()) ||
1249             (ima->bindcode[TEXTARGET_TEXTURE_2D] == 0) ||
1250             (ibuf == NULL) ||
1251             (w == 0) || (h == 0))
1252         {
1253                 /* these cases require full reload still */
1254                 GPU_free_image(ima);
1255         }
1256         else {
1257                 /* for the special case, we can do a partial update
1258                  * which is much quicker for painting */
1259                 GLint row_length, skip_pixels, skip_rows;
1260
1261                 /* if color correction is needed, we must update the part that needs updating. */
1262                 if (ibuf->rect_float) {
1263                         float *buffer = MEM_mallocN(w * h * sizeof(float) * 4, "temp_texpaint_float_buf");
1264                         bool is_data = (ima->tpageflag & IMA_GLBIND_IS_DATA) != 0;
1265                         IMB_partial_rect_from_float(ibuf, buffer, x, y, w, h, is_data);
1266                         
1267                         if (GPU_check_scaled_image(ibuf, ima, buffer, x, y, w, h)) {
1268                                 MEM_freeN(buffer);
1269                                 BKE_image_release_ibuf(ima, ibuf, NULL);
1270                                 return;
1271                         }
1272
1273                         glBindTexture(GL_TEXTURE_2D, ima->bindcode[TEXTARGET_TEXTURE_2D]);
1274                         glTexSubImage2D(GL_TEXTURE_2D, 0, x, y, w, h, GL_RGBA, GL_FLOAT, buffer);
1275
1276                         MEM_freeN(buffer);
1277
1278                         /* we have already accounted for the case where GTS.gpu_mipmap is false
1279                          * so we will be using GPU mipmap generation here */
1280                         if (GPU_get_mipmap()) {
1281                                 gpu_generate_mipmap(GL_TEXTURE_2D);
1282                         }
1283                         else {
1284                                 ima->tpageflag &= ~IMA_MIPMAP_COMPLETE;
1285                         }
1286
1287                         BKE_image_release_ibuf(ima, ibuf, NULL);
1288                         return;
1289                 }
1290
1291                 if (GPU_check_scaled_image(ibuf, ima, NULL, x, y, w, h)) {
1292                         BKE_image_release_ibuf(ima, ibuf, NULL);
1293                         return;
1294                 }
1295
1296                 glBindTexture(GL_TEXTURE_2D, ima->bindcode[TEXTARGET_TEXTURE_2D]);
1297
1298                 glGetIntegerv(GL_UNPACK_ROW_LENGTH, &row_length);
1299                 glGetIntegerv(GL_UNPACK_SKIP_PIXELS, &skip_pixels);
1300                 glGetIntegerv(GL_UNPACK_SKIP_ROWS, &skip_rows);
1301
1302                 glPixelStorei(GL_UNPACK_ROW_LENGTH, ibuf->x);
1303                 glPixelStorei(GL_UNPACK_SKIP_PIXELS, x);
1304                 glPixelStorei(GL_UNPACK_SKIP_ROWS, y);
1305
1306                 glTexSubImage2D(GL_TEXTURE_2D, 0, x, y, w, h, GL_RGBA,
1307                         GL_UNSIGNED_BYTE, ibuf->rect);
1308
1309                 glPixelStorei(GL_UNPACK_ROW_LENGTH, row_length);
1310                 glPixelStorei(GL_UNPACK_SKIP_PIXELS, skip_pixels);
1311                 glPixelStorei(GL_UNPACK_SKIP_ROWS, skip_rows);
1312
1313                 /* see comment above as to why we are using gpu mipmap generation here */
1314                 if (GPU_get_mipmap()) {
1315                         gpu_generate_mipmap(GL_TEXTURE_2D);
1316                 }
1317                 else {
1318                         ima->tpageflag &= ~IMA_MIPMAP_COMPLETE;
1319                 }
1320         }
1321
1322         BKE_image_release_ibuf(ima, ibuf, NULL);
1323 }
1324
1325 void GPU_update_images_framechange(void)
1326 {
1327         for (Image *ima = G.main->image.first; ima; ima = ima->id.next) {
1328                 if (ima->tpageflag & IMA_TWINANIM) {
1329                         if (ima->twend >= ima->xrep * ima->yrep)
1330                                 ima->twend = ima->xrep * ima->yrep - 1;
1331                 
1332                         /* check: is bindcode not in the array? free. (to do) */
1333                         
1334                         ima->lastframe++;
1335                         if (ima->lastframe > ima->twend)
1336                                 ima->lastframe = ima->twsta;
1337                 }
1338         }
1339 }
1340
1341 int GPU_update_image_time(Image *ima, double time)
1342 {
1343         if (!ima)
1344                 return 0;
1345
1346         if (ima->lastupdate < 0)
1347                 ima->lastupdate = 0;
1348
1349         if (ima->lastupdate > (float)time)
1350                 ima->lastupdate = (float)time;
1351
1352         int inc = 0;
1353
1354         if (ima->tpageflag & IMA_TWINANIM) {
1355                 if (ima->twend >= ima->xrep * ima->yrep) ima->twend = ima->xrep * ima->yrep - 1;
1356                 
1357                 /* check: is the bindcode not in the array? Then free. (still to do) */
1358                 
1359                 float diff = (float)((float)time - ima->lastupdate);
1360                 inc = (int)(diff * (float)ima->animspeed);
1361
1362                 ima->lastupdate += ((float)inc / (float)ima->animspeed);
1363
1364                 int newframe = ima->lastframe + inc;
1365
1366                 if (newframe > (int)ima->twend) {
1367                         if (ima->twend - ima->twsta != 0)
1368                                 newframe = (int)ima->twsta - 1 + (newframe - ima->twend) % (ima->twend - ima->twsta);
1369                         else
1370                                 newframe = ima->twsta;
1371                 }
1372
1373                 ima->lastframe = newframe;
1374         }
1375
1376         return inc;
1377 }
1378
1379
1380 void GPU_free_smoke(SmokeModifierData *smd)
1381 {
1382         if (smd->type & MOD_SMOKE_TYPE_DOMAIN && smd->domain) {
1383                 if (smd->domain->tex)
1384                         GPU_texture_free(smd->domain->tex);
1385                 smd->domain->tex = NULL;
1386
1387                 if (smd->domain->tex_shadow)
1388                         GPU_texture_free(smd->domain->tex_shadow);
1389                 smd->domain->tex_shadow = NULL;
1390
1391                 if (smd->domain->tex_flame)
1392                         GPU_texture_free(smd->domain->tex_flame);
1393                 smd->domain->tex_flame = NULL;
1394         }
1395 }
1396
1397 void GPU_create_smoke(SmokeModifierData *smd, int highres)
1398 {
1399 #ifdef WITH_SMOKE
1400         if (smd->type & MOD_SMOKE_TYPE_DOMAIN) {
1401                 SmokeDomainSettings *sds = smd->domain;
1402                 if (!sds->tex && !highres) {
1403                         /* rgba texture for color + density */
1404                         if (smoke_has_colors(sds->fluid)) {
1405                                 float *data = MEM_callocN(sizeof(float) * sds->total_cells * 4, "smokeColorTexture");
1406                                 smoke_get_rgba(sds->fluid, data, 0);
1407                                 sds->tex = GPU_texture_create_3D(sds->res[0], sds->res[1], sds->res[2], data, NULL);
1408                                 MEM_freeN(data);
1409                         }
1410                         /* density only */
1411                         else {
1412                                 sds->tex = GPU_texture_create_3D_custom(sds->res[0], sds->res[1], sds->res[2], 1,
1413                                                                  GPU_R8, smoke_get_density(sds->fluid), NULL);
1414                         }
1415                         sds->tex_flame = (smoke_has_fuel(sds->fluid)) ?
1416                                           GPU_texture_create_3D_custom(sds->res[0], sds->res[1], sds->res[2], 1,
1417                                           GPU_R8, smoke_get_flame(sds->fluid), NULL) :
1418                                           NULL;
1419                 }
1420                 else if (!sds->tex && highres) {
1421                         /* rgba texture for color + density */
1422                         if (smoke_turbulence_has_colors(sds->wt)) {
1423                                 float *data = MEM_callocN(sizeof(float) * smoke_turbulence_get_cells(sds->wt) * 4, "smokeColorTexture");
1424                                 smoke_turbulence_get_rgba(sds->wt, data, 0);
1425                                 sds->tex = GPU_texture_create_3D(sds->res_wt[0], sds->res_wt[1], sds->res_wt[2], data, NULL);
1426                                 MEM_freeN(data);
1427                         }
1428                         /* density only */
1429                         else {
1430                                 sds->tex = GPU_texture_create_3D_custom(sds->res_wt[0], sds->res_wt[1], sds->res_wt[2], 1,
1431                                                                         GPU_R8, smoke_turbulence_get_density(sds->wt), NULL);
1432                         }
1433                         sds->tex_flame = (smoke_turbulence_has_fuel(sds->wt)) ?
1434                                           GPU_texture_create_3D_custom(sds->res_wt[0], sds->res_wt[1], sds->res_wt[2], 1,
1435                                                                        GPU_R8, smoke_turbulence_get_flame(sds->wt), NULL):
1436                                           NULL;
1437                 }
1438
1439                 sds->tex_shadow = GPU_texture_create_3D_custom(sds->res[0], sds->res[1], sds->res[2], 1,
1440                                                         GPU_R8, sds->shadow, NULL);
1441         }
1442 #else // WITH_SMOKE
1443         (void)highres;
1444         smd->domain->tex = NULL;
1445         smd->domain->tex_flame = NULL;
1446         smd->domain->tex_shadow = NULL;
1447 #endif // WITH_SMOKE
1448 }
1449
1450 static LinkNode *image_free_queue = NULL;
1451
1452 static void gpu_queue_image_for_free(Image *ima)
1453 {
1454         BLI_lock_thread(LOCK_OPENGL);
1455         BLI_linklist_prepend(&image_free_queue, ima);
1456         BLI_unlock_thread(LOCK_OPENGL);
1457 }
1458
1459 void GPU_free_unused_buffers(void)
1460 {
1461         if (!BLI_thread_is_main())
1462                 return;
1463
1464         BLI_lock_thread(LOCK_OPENGL);
1465
1466         /* images */
1467         for (LinkNode *node = image_free_queue; node; node = node->next) {
1468                 Image *ima = node->link;
1469
1470                 /* check in case it was freed in the meantime */
1471                 if (G.main && BLI_findindex(&G.main->image, ima) != -1)
1472                         GPU_free_image(ima);
1473         }
1474
1475         BLI_linklist_free(image_free_queue, NULL);
1476         image_free_queue = NULL;
1477
1478         /* vbo buffers */
1479         GPU_global_buffer_pool_free_unused();
1480
1481         BLI_unlock_thread(LOCK_OPENGL);
1482 }
1483
1484 void GPU_free_image(Image *ima)
1485 {
1486         if (!BLI_thread_is_main()) {
1487                 gpu_queue_image_for_free(ima);
1488                 return;
1489         }
1490
1491         for (int i = 0; i < TEXTARGET_COUNT; i++) {
1492                 /* free regular image binding */
1493                 if (ima->bindcode[i]) {
1494                         glDeleteTextures(1, (GLuint *)&ima->bindcode[i]);
1495                         ima->bindcode[i] = 0;
1496                 }
1497                 /* free glsl image binding */
1498                 if (ima->gputexture[i]) {
1499                         GPU_texture_free(ima->gputexture[i]);
1500                         ima->gputexture[i] = NULL;
1501                 }
1502         }
1503
1504         /* free repeated image binding */
1505         if (ima->repbind) {
1506                 glDeleteTextures(ima->totbind, (GLuint *)ima->repbind);
1507         
1508                 MEM_freeN(ima->repbind);
1509                 ima->repbind = NULL;
1510         }
1511
1512         ima->tpageflag &= ~(IMA_MIPMAP_COMPLETE | IMA_GLBIND_IS_DATA);
1513 }
1514
1515 void GPU_free_images(void)
1516 {
1517         if (G.main)
1518                 for (Image *ima = G.main->image.first; ima; ima = ima->id.next)
1519                         GPU_free_image(ima);
1520 }
1521
1522 /* same as above but only free animated images */
1523 void GPU_free_images_anim(void)
1524 {
1525         if (G.main)
1526                 for (Image *ima = G.main->image.first; ima; ima = ima->id.next)
1527                         if (BKE_image_is_animated(ima))
1528                                 GPU_free_image(ima);
1529 }
1530
1531
1532 void GPU_free_images_old(void)
1533 {
1534         static int lasttime = 0;
1535         int ctime = (int)PIL_check_seconds_timer();
1536
1537         /*
1538          * Run garbage collector once for every collecting period of time
1539          * if textimeout is 0, that's the option to NOT run the collector
1540          */
1541         if (U.textimeout == 0 || ctime % U.texcollectrate || ctime == lasttime)
1542                 return;
1543
1544         /* of course not! */
1545         if (G.is_rendering)
1546                 return;
1547
1548         lasttime = ctime;
1549
1550         Image *ima = G.main->image.first;
1551         while (ima) {
1552                 if ((ima->flag & IMA_NOCOLLECT) == 0 && ctime - ima->lastused > U.textimeout) {
1553                         /* If it's in GL memory, deallocate and set time tag to current time
1554                          * This gives textures a "second chance" to be used before dying. */
1555                         if (BKE_image_has_bindcode(ima) || ima->repbind) {
1556                                 GPU_free_image(ima);
1557                                 ima->lastused = ctime;
1558                         }
1559                         /* Otherwise, just kill the buffers */
1560                         else {
1561                                 BKE_image_free_buffers(ima);
1562                         }
1563                 }
1564                 ima = ima->id.next;
1565         }
1566 }
1567
1568
1569 /* OpenGL Materials */
1570
1571 #define FIXEDMAT 8
1572
1573 /* OpenGL state caching for materials */
1574
1575 typedef struct GPUMaterialFixed {
1576         float diff[3];
1577         float spec[3];
1578         int hard;
1579         float alpha;
1580 } GPUMaterialFixed; 
1581
1582 static struct GPUMaterialState {
1583         GPUMaterialFixed (*matbuf);
1584         GPUMaterialFixed matbuf_fixed[FIXEDMAT];
1585         int totmat;
1586
1587         /* set when called inside GPU_begin_object_materials / GPU_end_object_materials
1588          * otherwise calling GPU_object_material_bind returns zero */
1589         bool is_enabled;
1590
1591         Material **gmatbuf;
1592         Material *gmatbuf_fixed[FIXEDMAT];
1593         Material *gboundmat;
1594         Object *gob;
1595         DupliObject *dob;
1596         Scene *gscene;
1597         int glay;
1598         bool gscenelock;
1599         float (*gviewmat)[4];
1600         float (*gviewinv)[4];
1601         float (*gviewcamtexcofac);
1602
1603         bool backface_culling;
1604         bool two_sided_lighting;
1605
1606         GPUBlendMode *alphablend;
1607         GPUBlendMode alphablend_fixed[FIXEDMAT];
1608         bool use_alpha_pass, is_alpha_pass;
1609         bool use_matcaps;
1610
1611         int lastmatnr, lastretval;
1612         GPUBlendMode lastalphablend;
1613         bool is_opensubdiv;
1614 } GMS = {NULL};
1615
1616 /* fixed function material, alpha handed by caller */
1617 static void gpu_material_to_fixed(
1618         GPUMaterialFixed *smat, const Material *bmat, const int gamma, const Object *ob,
1619         const int new_shading_nodes, const bool dimdown)
1620 {
1621         if (bmat->mode & MA_SHLESS) {
1622                 copy_v3_v3(smat->diff, &bmat->r);
1623
1624                 if (gamma)
1625                         linearrgb_to_srgb_v3_v3(smat->diff, smat->diff);
1626
1627                 zero_v3(smat->spec);
1628                 smat->alpha = 1.0f;
1629                 smat->hard = 0;
1630         }
1631         else if (new_shading_nodes) {
1632                 copy_v3_v3(smat->diff, &bmat->r);
1633                 copy_v3_v3(smat->spec, &bmat->specr);
1634                 smat->alpha = 1.0f;
1635                 smat->hard = CLAMPIS(bmat->har, 0, 128);
1636                 
1637                 if (dimdown) {
1638                         mul_v3_fl(smat->diff, 0.8f);
1639                         mul_v3_fl(smat->spec, 0.5f);
1640                 }
1641                 
1642                 if (gamma) {
1643                         linearrgb_to_srgb_v3_v3(smat->diff, smat->diff);
1644                         linearrgb_to_srgb_v3_v3(smat->spec, smat->spec);
1645                 }
1646         }
1647         else {
1648                 mul_v3_v3fl(smat->diff, &bmat->r, bmat->ref + bmat->emit);
1649
1650                 if (bmat->shade_flag & MA_OBCOLOR)
1651                         mul_v3_v3(smat->diff, ob->col);
1652                 
1653                 mul_v3_v3fl(smat->spec, &bmat->specr, bmat->spec);
1654                 smat->hard = CLAMPIS(bmat->har, 1, 128);
1655                 smat->alpha = 1.0f;
1656
1657                 if (gamma) {
1658                         linearrgb_to_srgb_v3_v3(smat->diff, smat->diff);
1659                         linearrgb_to_srgb_v3_v3(smat->spec, smat->spec);
1660                 }
1661         }
1662 }
1663
1664 static Material *gpu_active_node_material(Material *ma)
1665 {
1666         if (ma && ma->use_nodes && ma->nodetree) {
1667                 bNode *node = nodeGetActiveID(ma->nodetree, ID_MA);
1668
1669                 if (node)
1670                         return (Material *)node->id;
1671                 else
1672                         return NULL;
1673         }
1674
1675         return ma;
1676 }
1677
1678 void GPU_begin_dupli_object(DupliObject *dob)
1679 {
1680         GMS.dob = dob;
1681 }
1682
1683 void GPU_end_dupli_object(void)
1684 {
1685         GMS.dob = NULL;
1686 }
1687
1688 void GPU_begin_object_materials(
1689         View3D *v3d, RegionView3D *rv3d, Scene *scene, Object *ob,
1690         bool glsl, bool *do_alpha_after)
1691 {
1692         Material *ma;
1693         GPUMaterial *gpumat;
1694         GPUBlendMode alphablend;
1695         DupliObject *dob;
1696         int a;
1697         const bool gamma = BKE_scene_check_color_management_enabled(scene);
1698         const bool new_shading_nodes = BKE_scene_use_new_shading_nodes(scene);
1699         const bool use_matcap = (v3d->flag2 & V3D_SHOW_SOLID_MATCAP) != 0;  /* assumes v3d->defmaterial->preview is set */
1700         bool use_opensubdiv = false;
1701
1702 #ifdef WITH_OPENSUBDIV
1703         {
1704                 DerivedMesh *derivedFinal = NULL;
1705                 if (ob->type == OB_MESH) {
1706                         Mesh *me = ob->data;
1707                         BMEditMesh *em = me->edit_btmesh;
1708                         if (em != NULL) {
1709                                 derivedFinal = em->derivedFinal;
1710                         }
1711                         else {
1712                                 derivedFinal = ob->derivedFinal;
1713                         }
1714                 }
1715                 else {
1716                         derivedFinal = ob->derivedFinal;
1717                 }
1718
1719                 if (derivedFinal != NULL && derivedFinal->type == DM_TYPE_CCGDM) {
1720                         CCGDerivedMesh *ccgdm = (CCGDerivedMesh *) derivedFinal;
1721                         use_opensubdiv = ccgdm->useGpuBackend;
1722                 }
1723         }
1724 #endif
1725
1726 #ifdef WITH_GAMEENGINE
1727         if (rv3d->rflag & RV3D_IS_GAME_ENGINE) {
1728                 ob = BKE_object_lod_matob_get(ob, scene);
1729         }
1730 #endif
1731
1732         /* initialize state */
1733         /* DupliObject must be restored */
1734         dob = GMS.dob;
1735         memset(&GMS, 0, sizeof(GMS));
1736         GMS.is_enabled = true;
1737         GMS.dob = dob;
1738         GMS.lastmatnr = -1;
1739         GMS.lastretval = -1;
1740         GMS.lastalphablend = GPU_BLEND_SOLID;
1741         GMS.use_matcaps = use_matcap;
1742
1743         GMS.backface_culling = (v3d->flag2 & V3D_BACKFACE_CULLING) != 0;
1744
1745         GMS.two_sided_lighting = false;
1746         if (ob && ob->type == OB_MESH)
1747                 GMS.two_sided_lighting = (((Mesh *)ob->data)->flag & ME_TWOSIDED) != 0;
1748
1749         GMS.gob = ob;
1750         GMS.gscene = scene;
1751         GMS.is_opensubdiv = use_opensubdiv;
1752         GMS.totmat = use_matcap ? 1 : ob->totcol + 1;  /* materials start from 1, default material is 0 */
1753         GMS.glay = (v3d->localvd) ? v3d->localvd->lay : v3d->lay; /* keep lamps visible in local view */
1754         GMS.gscenelock = (v3d->scenelock != 0);
1755         GMS.gviewmat = rv3d->viewmat;
1756         GMS.gviewinv = rv3d->viewinv;
1757         GMS.gviewcamtexcofac = rv3d->viewcamtexcofac;
1758
1759         /* alpha pass setup. there's various cases to handle here:
1760          * - object transparency on: only solid materials draw in the first pass,
1761          * and only transparent in the second 'alpha' pass.
1762          * - object transparency off: for glsl we draw both in a single pass, and
1763          * for solid we don't use transparency at all. */
1764         GMS.use_alpha_pass = (do_alpha_after != NULL);
1765         GMS.is_alpha_pass = (v3d->transp != false);
1766         if (GMS.use_alpha_pass)
1767                 *do_alpha_after = false;
1768         
1769         if (GMS.totmat > FIXEDMAT) {
1770                 GMS.matbuf = MEM_callocN(sizeof(GPUMaterialFixed) * GMS.totmat, "GMS.matbuf");
1771                 GMS.gmatbuf = MEM_callocN(sizeof(*GMS.gmatbuf) * GMS.totmat, "GMS.matbuf");
1772                 GMS.alphablend = MEM_callocN(sizeof(*GMS.alphablend) * GMS.totmat, "GMS.matbuf");
1773         }
1774         else {
1775                 GMS.matbuf = GMS.matbuf_fixed;
1776                 GMS.gmatbuf = GMS.gmatbuf_fixed;
1777                 GMS.alphablend = GMS.alphablend_fixed;
1778         }
1779
1780         /* viewport material, setup in space_view3d, defaults to matcap using ma->preview now */
1781         if (use_matcap) {
1782                 GMS.gmatbuf[0] = v3d->defmaterial;
1783                 GPU_material_matcap(scene, v3d->defmaterial, use_opensubdiv);
1784
1785                 /* do material 1 too, for displists! */
1786                 memcpy(&GMS.matbuf[1], &GMS.matbuf[0], sizeof(GPUMaterialFixed));
1787         
1788                 GMS.alphablend[0] = GPU_BLEND_SOLID;
1789         }
1790         else {
1791         
1792                 /* no materials assigned? */
1793                 if (ob->totcol == 0) {
1794                         gpu_material_to_fixed(&GMS.matbuf[0], &defmaterial, 0, ob, new_shading_nodes, true);
1795
1796                         /* do material 1 too, for displists! */
1797                         memcpy(&GMS.matbuf[1], &GMS.matbuf[0], sizeof(GPUMaterialFixed));
1798
1799                         if (glsl) {
1800                                 GMS.gmatbuf[0] = &defmaterial;
1801                                 GPU_material_from_blender(GMS.gscene, &defmaterial, GMS.is_opensubdiv);
1802                         }
1803
1804                         GMS.alphablend[0] = GPU_BLEND_SOLID;
1805                 }
1806                 
1807                 /* setup materials */
1808                 for (a = 1; a <= ob->totcol; a++) {
1809                         /* find a suitable material */
1810                         ma = give_current_material(ob, a);
1811                         if (!glsl && !new_shading_nodes) ma = gpu_active_node_material(ma);
1812                         if (ma == NULL) ma = &defmaterial;
1813
1814                         /* create glsl material if requested */
1815                         gpumat = glsl ? GPU_material_from_blender(GMS.gscene, ma, GMS.is_opensubdiv) : NULL;
1816
1817                         if (gpumat) {
1818                                 /* do glsl only if creating it succeed, else fallback */
1819                                 GMS.gmatbuf[a] = ma;
1820                                 alphablend = GPU_material_alpha_blend(gpumat, ob->col);
1821                         }
1822                         else {
1823                                 /* fixed function opengl materials */
1824                                 gpu_material_to_fixed(&GMS.matbuf[a], ma, gamma, ob, new_shading_nodes, false);
1825
1826                                 if (GMS.use_alpha_pass && ((ma->mode & MA_TRANSP) || (new_shading_nodes && ma->alpha != 1.0f))) {
1827                                         GMS.matbuf[a].alpha = ma->alpha;
1828                                         alphablend = (ma->alpha == 1.0f) ? GPU_BLEND_SOLID: GPU_BLEND_ALPHA;
1829                                 }
1830                                 else {
1831                                         GMS.matbuf[a].alpha = 1.0f;
1832                                         alphablend = GPU_BLEND_SOLID;
1833                                 }
1834                         }
1835
1836                         /* setting 'do_alpha_after = true' indicates this object needs to be
1837                          * drawn in a second alpha pass for improved blending */
1838                         if (do_alpha_after && !GMS.is_alpha_pass)
1839                                 if (ELEM(alphablend, GPU_BLEND_ALPHA, GPU_BLEND_ADD, GPU_BLEND_ALPHA_SORT))
1840                                         *do_alpha_after = true;
1841
1842                         GMS.alphablend[a] = alphablend;
1843                 }
1844         }
1845
1846         /* let's start with a clean state */
1847         GPU_object_material_unbind();
1848 }
1849
1850 static int GPU_get_particle_info(GPUParticleInfo *pi)
1851 {
1852         DupliObject *dob = GMS.dob;
1853         if (dob->particle_system) {
1854                 int ind;
1855                 if (dob->persistent_id[0] < dob->particle_system->totpart)
1856                         ind = dob->persistent_id[0];
1857                 else {
1858                         ind = dob->particle_system->child[dob->persistent_id[0] - dob->particle_system->totpart].parent;
1859                 }
1860                 if (ind >= 0) {
1861                         ParticleData *p = &dob->particle_system->particles[ind];
1862
1863                         pi->scalprops[0] = ind;
1864                         pi->scalprops[1] = GMS.gscene->r.cfra - p->time;
1865                         pi->scalprops[2] = p->lifetime;
1866                         pi->scalprops[3] = p->size;
1867
1868                         copy_v3_v3(pi->location, p->state.co);
1869                         copy_v3_v3(pi->velocity, p->state.vel);
1870                         copy_v3_v3(pi->angular_velocity, p->state.ave);
1871                         return 1;
1872                 }
1873                 else return 0;
1874         }
1875         else
1876                 return 0;
1877 }
1878
1879 int GPU_object_material_bind(int nr, void *attribs)
1880 {
1881         GPUVertexAttribs *gattribs = attribs;
1882
1883         /* no GPU_begin_object_materials, use default material */
1884         if (!GMS.matbuf) {
1885                 memset(&GMS, 0, sizeof(GMS));
1886
1887                 float diffuse[3], specular[3];
1888                 mul_v3_v3fl(diffuse, &defmaterial.r, defmaterial.ref + defmaterial.emit);
1889                 mul_v3_v3fl(specular, &defmaterial.specr, defmaterial.spec);
1890                 GPU_basic_shader_colors(diffuse, specular, 35, 1.0f);
1891
1892                 if (GMS.two_sided_lighting)
1893                         GPU_basic_shader_bind(GPU_SHADER_LIGHTING | GPU_SHADER_TWO_SIDED);
1894                 else
1895                         GPU_basic_shader_bind(GPU_SHADER_LIGHTING);
1896
1897                 return 0;
1898         }
1899
1900         /* prevent index to use un-initialized array items */
1901         if (nr >= GMS.totmat)
1902                 nr = 0;
1903
1904         if (gattribs)
1905                 memset(gattribs, 0, sizeof(*gattribs));
1906
1907         /* keep current material */
1908         if (nr == GMS.lastmatnr)
1909                 return GMS.lastretval;
1910
1911         /* unbind glsl material */
1912         if (GMS.gboundmat) {
1913                 if (GMS.is_alpha_pass) glDepthMask(0);
1914                 GPU_material_unbind(GPU_material_from_blender(GMS.gscene, GMS.gboundmat, GMS.is_opensubdiv));
1915                 GMS.gboundmat = NULL;
1916         }
1917
1918         /* draw materials with alpha in alpha pass */
1919         GMS.lastmatnr = nr;
1920         GMS.lastretval = 1;
1921
1922         if (GMS.use_alpha_pass) {
1923                 GMS.lastretval = ELEM(GMS.alphablend[nr], GPU_BLEND_SOLID, GPU_BLEND_CLIP);
1924                 if (GMS.is_alpha_pass)
1925                         GMS.lastretval = !GMS.lastretval;
1926         }
1927         else
1928                 GMS.lastretval = !GMS.is_alpha_pass;
1929
1930         if (GMS.lastretval) {
1931                 /* for alpha pass, use alpha blend */
1932                 GPUBlendMode alphablend = GMS.alphablend[nr];
1933
1934                 if (gattribs && GMS.gmatbuf[nr]) {
1935                         /* bind glsl material and get attributes */
1936                         Material *mat = GMS.gmatbuf[nr];
1937                         GPUParticleInfo partile_info;
1938
1939                         float auto_bump_scale;
1940
1941                         GPUMaterial *gpumat = GPU_material_from_blender(GMS.gscene, mat, GMS.is_opensubdiv);
1942                         GPU_material_vertex_attributes(gpumat, gattribs);
1943
1944                         if (GMS.dob)
1945                                 GPU_get_particle_info(&partile_info);
1946
1947                         GPU_material_bind(
1948                                 gpumat, GMS.gob->lay, GMS.glay, 1.0, !(GMS.gob->mode & OB_MODE_TEXTURE_PAINT),
1949                                 GMS.gviewmat, GMS.gviewinv, GMS.gviewcamtexcofac, GMS.gscenelock);
1950
1951                         auto_bump_scale = GMS.gob->derivedFinal != NULL ? GMS.gob->derivedFinal->auto_bump_scale : 1.0f;
1952                         GPU_material_bind_uniforms(gpumat, GMS.gob->obmat, GMS.gviewmat, GMS.gob->col, auto_bump_scale, &partile_info);
1953                         GMS.gboundmat = mat;
1954
1955                         /* for glsl use alpha blend mode, unless it's set to solid and
1956                          * we are already drawing in an alpha pass */
1957                         if (mat->game.alpha_blend != GPU_BLEND_SOLID)
1958                                 alphablend = mat->game.alpha_blend;
1959
1960                         if (GMS.is_alpha_pass) glDepthMask(1);
1961
1962                         if (GMS.backface_culling) {
1963                                 if (mat->game.flag)
1964                                         glEnable(GL_CULL_FACE);
1965                                 else
1966                                         glDisable(GL_CULL_FACE);
1967                         }
1968
1969                         if (GMS.use_matcaps)
1970                                 glColor3f(1.0f, 1.0f, 1.0f);
1971                 }
1972                 else {
1973                         /* or do fixed function opengl material */
1974                         GPU_basic_shader_colors(
1975                                 GMS.matbuf[nr].diff,
1976                                 GMS.matbuf[nr].spec, GMS.matbuf[nr].hard, GMS.matbuf[nr].alpha);
1977
1978                         if (GMS.two_sided_lighting)
1979                                 GPU_basic_shader_bind(GPU_SHADER_LIGHTING | GPU_SHADER_TWO_SIDED);
1980                         else
1981                                 GPU_basic_shader_bind(GPU_SHADER_LIGHTING);
1982                 }
1983
1984                 /* set (alpha) blending mode */
1985                 GPU_set_material_alpha_blend(alphablend);
1986         }
1987
1988         return GMS.lastretval;
1989 }
1990
1991 int GPU_object_material_visible(int nr, void *attribs)
1992 {
1993         GPUVertexAttribs *gattribs = attribs;
1994         int visible;
1995
1996         if (!GMS.matbuf)
1997                 return 0;
1998
1999         if (gattribs)
2000                 memset(gattribs, 0, sizeof(*gattribs));
2001
2002         if (nr >= GMS.totmat)
2003                 nr = 0;
2004
2005         if (GMS.use_alpha_pass) {
2006                 visible = ELEM(GMS.alphablend[nr], GPU_BLEND_SOLID, GPU_BLEND_CLIP);
2007                 if (GMS.is_alpha_pass)
2008                         visible = !visible;
2009         }
2010         else
2011                 visible = !GMS.is_alpha_pass;
2012
2013         return visible;
2014 }
2015
2016 void GPU_set_material_alpha_blend(int alphablend)
2017 {
2018         if (GMS.lastalphablend == alphablend)
2019                 return;
2020         
2021         gpu_set_alpha_blend(alphablend);
2022         GMS.lastalphablend = alphablend;
2023 }
2024
2025 int GPU_get_material_alpha_blend(void)
2026 {
2027         return GMS.lastalphablend;
2028 }
2029
2030 void GPU_object_material_unbind(void)
2031 {
2032         GMS.lastmatnr = -1;
2033         GMS.lastretval = 1;
2034
2035         if (GMS.gboundmat) {
2036                 if (GMS.backface_culling)
2037                         glDisable(GL_CULL_FACE);
2038
2039                 if (GMS.is_alpha_pass) glDepthMask(0);
2040                 GPU_material_unbind(GPU_material_from_blender(GMS.gscene, GMS.gboundmat, GMS.is_opensubdiv));
2041                 GMS.gboundmat = NULL;
2042         }
2043         else
2044                 GPU_basic_shader_bind(GPU_SHADER_USE_COLOR);
2045
2046         GPU_set_material_alpha_blend(GPU_BLEND_SOLID);
2047 }
2048
2049 void GPU_material_diffuse_get(int nr, float diff[4])
2050 {
2051         /* prevent index to use un-initialized array items */
2052         if (nr >= GMS.totmat)
2053                 nr = 0;
2054
2055         /* no GPU_begin_object_materials, use default material */
2056         if (!GMS.matbuf) {
2057                 mul_v3_v3fl(diff, &defmaterial.r, defmaterial.ref + defmaterial.emit);
2058         }
2059         else {
2060                 copy_v3_v3(diff, GMS.matbuf[nr].diff);
2061                 diff[3] = GMS.matbuf[nr].alpha;
2062         }
2063 }
2064
2065 bool GPU_material_use_matcaps_get(void)
2066 {
2067         return GMS.use_matcaps;
2068 }
2069
2070 bool GPU_object_materials_check(void)
2071 {
2072         return GMS.is_enabled;
2073 }
2074
2075 void GPU_end_object_materials(void)
2076 {
2077         GPU_object_material_unbind();
2078
2079         GMS.is_enabled = false;
2080
2081         if (GMS.matbuf && GMS.matbuf != GMS.matbuf_fixed) {
2082                 MEM_freeN(GMS.matbuf);
2083                 MEM_freeN(GMS.gmatbuf);
2084                 MEM_freeN(GMS.alphablend);
2085         }
2086
2087         GMS.matbuf = NULL;
2088         GMS.gmatbuf = NULL;
2089         GMS.alphablend = NULL;
2090         GMS.two_sided_lighting = false;
2091
2092         /* resetting the texture matrix after the scaling needed for tiled textures */
2093         if (GTS.tilemode) {
2094                 glMatrixMode(GL_TEXTURE);
2095                 glLoadIdentity();
2096                 glMatrixMode(GL_MODELVIEW);
2097         }
2098 }
2099
2100 /* Lights */
2101
2102 int GPU_default_lights(void)
2103 {
2104         /* initialize */
2105         if (U.light[0].flag == 0 && U.light[1].flag == 0 && U.light[2].flag == 0) {
2106                 U.light[0].flag = 1;
2107                 U.light[0].vec[0] = -0.3; U.light[0].vec[1] = 0.3; U.light[0].vec[2] = 0.9;
2108                 U.light[0].col[0] = 0.8; U.light[0].col[1] = 0.8; U.light[0].col[2] = 0.8;
2109                 U.light[0].spec[0] = 0.5; U.light[0].spec[1] = 0.5; U.light[0].spec[2] = 0.5;
2110                 U.light[0].spec[3] = 1.0;
2111                 
2112                 U.light[1].flag = 0;
2113                 U.light[1].vec[0] = 0.5; U.light[1].vec[1] = 0.5; U.light[1].vec[2] = 0.1;
2114                 U.light[1].col[0] = 0.4; U.light[1].col[1] = 0.4; U.light[1].col[2] = 0.8;
2115                 U.light[1].spec[0] = 0.3; U.light[1].spec[1] = 0.3; U.light[1].spec[2] = 0.5;
2116                 U.light[1].spec[3] = 1.0;
2117         
2118                 U.light[2].flag = 0;
2119                 U.light[2].vec[0] = 0.3; U.light[2].vec[1] = -0.3; U.light[2].vec[2] = -0.2;
2120                 U.light[2].col[0] = 0.8; U.light[2].col[1] = 0.5; U.light[2].col[2] = 0.4;
2121                 U.light[2].spec[0] = 0.5; U.light[2].spec[1] = 0.4; U.light[2].spec[2] = 0.3;
2122                 U.light[2].spec[3] = 1.0;
2123         }
2124
2125         GPU_basic_shader_light_set_viewer(false);
2126
2127         int count = 0;
2128
2129         for (int a = 0; a < 8; a++) {
2130                 if (a < 3 && U.light[a].flag) {
2131                         GPULightData light = {0};
2132
2133                         light.type = GPU_LIGHT_SUN;
2134
2135                         normalize_v3_v3(light.direction, U.light[a].vec);
2136                         copy_v3_v3(light.diffuse, U.light[a].col);
2137                         copy_v3_v3(light.specular, U.light[a].spec);
2138
2139                         GPU_basic_shader_light_set(a, &light);
2140
2141                         count++;
2142                 }
2143                 else
2144                         GPU_basic_shader_light_set(a, NULL);
2145         }
2146
2147         return count;
2148 }
2149
2150 int GPU_scene_object_lights(Scene *scene, Object *ob, int lay, float viewmat[4][4], int ortho)
2151 {
2152         /* disable all lights */
2153         for (int count = 0; count < 8; count++)
2154                 GPU_basic_shader_light_set(count, NULL);
2155         
2156         /* view direction for specular is not computed correct by default in
2157          * opengl, so we set the settings ourselfs */
2158         GPU_basic_shader_light_set_viewer(!ortho);
2159
2160         int count = 0;
2161
2162         for (BaseLegacy *base = scene->base.first; base; base = base->next) {
2163                 if (base->object->type != OB_LAMP)
2164                         continue;
2165
2166                 if (!(base->lay & lay) || !(base->lay & ob->lay))
2167                         continue;
2168
2169                 Lamp *la = base->object->data;
2170                 
2171                 /* setup lamp transform */
2172                 glPushMatrix();
2173                 glLoadMatrixf((float *)viewmat);
2174                 
2175                 /* setup light */
2176                 GPULightData light = {0};
2177
2178                 mul_v3_v3fl(light.diffuse, &la->r, la->energy);
2179                 mul_v3_v3fl(light.specular, &la->r, la->energy);
2180
2181                 if (la->type == LA_SUN) {
2182                         /* directional sun light */
2183                         light.type = GPU_LIGHT_SUN;
2184                         normalize_v3_v3(light.direction, base->object->obmat[2]);
2185                 }
2186                 else {
2187                         /* other lamps with position attenuation */
2188                         copy_v3_v3(light.position, base->object->obmat[3]);
2189
2190                         light.constant_attenuation = 1.0f;
2191                         light.linear_attenuation = la->att1 / la->dist;
2192                         light.quadratic_attenuation = la->att2 / (la->dist * la->dist);
2193                         
2194                         if (la->type == LA_SPOT) {
2195                                 light.type = GPU_LIGHT_SPOT;
2196                                 negate_v3_v3(light.direction, base->object->obmat[2]);
2197                                 normalize_v3(light.direction);
2198                                 light.spot_cutoff = RAD2DEGF(la->spotsize * 0.5f);
2199                                 light.spot_exponent = 128.0f * la->spotblend;
2200                         }
2201                         else
2202                                 light.type = GPU_LIGHT_POINT;
2203                 }
2204                 
2205                 GPU_basic_shader_light_set(count, &light);
2206                 
2207                 glPopMatrix();
2208                 
2209                 count++;
2210                 if (count == 8)
2211                         break;
2212         }
2213
2214         return count;
2215 }
2216
2217 static void gpu_multisample(bool enable)
2218 {
2219 #ifdef __linux__
2220         /* changing multisample from the default (enabled) causes problems on some
2221          * systems (NVIDIA/Linux) when the pixel format doesn't have a multisample buffer */
2222         bool toggle_ok = true;
2223
2224         if (GPU_type_matches(GPU_DEVICE_NVIDIA, GPU_OS_UNIX, GPU_DRIVER_ANY)) {
2225                 int samples = 0;
2226                 glGetIntegerv(GL_SAMPLES, &samples);
2227
2228                 if (samples == 0)
2229                         toggle_ok = false;
2230         }
2231
2232         if (toggle_ok) {
2233                 if (enable)
2234                         glEnable(GL_MULTISAMPLE);
2235                 else
2236                         glDisable(GL_MULTISAMPLE);
2237         }
2238 #else
2239         if (enable)
2240                 glEnable(GL_MULTISAMPLE);
2241         else
2242                 glDisable(GL_MULTISAMPLE);
2243 #endif
2244 }
2245
2246 /* Default OpenGL State
2247  *
2248  * This is called on startup, for opengl offscreen render and to restore state
2249  * for the game engine. Generally we should always return to this state when
2250  * temporarily modifying the state for drawing, though that are (undocumented)
2251  * exceptions that we should try to get rid of. */
2252
2253 void GPU_state_init(void)
2254 {
2255         float mat_ambient[] = { 0.0, 0.0, 0.0, 0.0 };
2256         float mat_specular[] = { 0.5, 0.5, 0.5, 1.0 };
2257         
2258         glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, mat_ambient);
2259         glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, mat_specular);
2260         glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, mat_specular);
2261         glMateriali(GL_FRONT_AND_BACK, GL_SHININESS, 35);
2262         glColorMaterial(GL_FRONT_AND_BACK, GL_DIFFUSE);
2263
2264         GPU_default_lights();
2265
2266         GPU_disable_program_point_size();
2267
2268         /* TODO: remove this when we switch to core profile */
2269         glEnable(GL_POINT_SPRITE);
2270
2271
2272         glDepthFunc(GL_LEQUAL);
2273         /* scaling matrices */
2274         glEnable(GL_NORMALIZE);
2275
2276         glDisable(GL_ALPHA_TEST);
2277         glDisable(GL_BLEND);
2278         glDisable(GL_DEPTH_TEST);
2279         glDisable(GL_FOG);
2280         glDisable(GL_LIGHTING);
2281         glDisable(GL_COLOR_MATERIAL);
2282         glDisable(GL_LOGIC_OP);
2283         glDisable(GL_STENCIL_TEST);
2284         glDisable(GL_TEXTURE_1D);
2285         glDisable(GL_TEXTURE_2D);
2286         glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
2287
2288         /* default disabled, enable should be local per function */
2289         glDisableClientState(GL_VERTEX_ARRAY);
2290         glDisableClientState(GL_NORMAL_ARRAY);
2291         glDisableClientState(GL_COLOR_ARRAY);
2292         glDisableClientState(GL_TEXTURE_COORD_ARRAY);
2293
2294         glPixelTransferi(GL_MAP_COLOR, GL_FALSE);
2295         glPixelTransferi(GL_RED_SCALE, 1);
2296         glPixelTransferi(GL_RED_BIAS, 0);
2297         glPixelTransferi(GL_GREEN_SCALE, 1);
2298         glPixelTransferi(GL_GREEN_BIAS, 0);
2299         glPixelTransferi(GL_BLUE_SCALE, 1);
2300         glPixelTransferi(GL_BLUE_BIAS, 0);
2301         glPixelTransferi(GL_ALPHA_SCALE, 1);
2302         glPixelTransferi(GL_ALPHA_BIAS, 0);
2303
2304         glPixelTransferi(GL_DEPTH_BIAS, 0);
2305         glPixelTransferi(GL_DEPTH_SCALE, 1);
2306         glDepthRange(0.0, 1.0);
2307
2308         glMatrixMode(GL_TEXTURE);
2309         glLoadIdentity();
2310         glMatrixMode(GL_MODELVIEW);
2311
2312         glFrontFace(GL_CCW);
2313         glCullFace(GL_BACK);
2314         glDisable(GL_CULL_FACE);
2315
2316         gpu_multisample(false);
2317
2318         GPU_basic_shader_bind(GPU_SHADER_USE_COLOR);
2319 }
2320
2321 void GPU_enable_program_point_size()
2322 {
2323 #ifdef __APPLE__
2324         /* TODO: remove this when we switch to core profile */
2325         glEnable(GL_VERTEX_PROGRAM_POINT_SIZE);
2326 #else
2327         glEnable(GL_PROGRAM_POINT_SIZE);
2328 #endif
2329 }
2330
2331 void GPU_disable_program_point_size()
2332 {
2333 #ifdef __APPLE__
2334         /* TODO: remove this when we switch to core profile */
2335         glDisable(GL_VERTEX_PROGRAM_POINT_SIZE);
2336 #else
2337         glDisable(GL_PROGRAM_POINT_SIZE);
2338 #endif
2339 }
2340
2341 #ifdef WITH_OPENSUBDIV
2342 /* Update face-varying variables offset which might be
2343  * different from mesh to mesh sharing the same material.
2344  */
2345 void GPU_draw_update_fvar_offset(DerivedMesh *dm)
2346 {
2347         /* Sanity check to be sure we only do this for OpenSubdiv draw. */
2348         BLI_assert(dm->type == DM_TYPE_CCGDM);
2349         BLI_assert(GMS.is_opensubdiv);
2350
2351         for (int i = 0; i < GMS.totmat; ++i) {
2352                 Material *material = GMS.gmatbuf[i];
2353                 GPUMaterial *gpu_material;
2354
2355                 if (material == NULL) {
2356                         continue;
2357                 }
2358
2359                 gpu_material = GPU_material_from_blender(GMS.gscene,
2360                                                          material,
2361                                                          GMS.is_opensubdiv);
2362
2363                 GPU_material_update_fvar_offset(gpu_material, dm);
2364         }
2365 }
2366 #endif
2367
2368
2369 /** \name Framebuffer color depth, for selection codes
2370  * \{ */
2371
2372 #ifdef __APPLE__
2373
2374 /* apple seems to round colors to below and up on some configs */
2375
2376 static unsigned int index_to_framebuffer(int index)
2377 {
2378         unsigned int i = index;
2379
2380         switch (GPU_color_depth()) {
2381                 case 12:
2382                         i = ((i & 0xF00) << 12) + ((i & 0xF0) << 8) + ((i & 0xF) << 4);
2383                         /* sometimes dithering subtracts! */
2384                         i |= 0x070707;
2385                         break;
2386                 case 15:
2387                 case 16:
2388                         i = ((i & 0x7C00) << 9) + ((i & 0x3E0) << 6) + ((i & 0x1F) << 3);
2389                         i |= 0x030303;
2390                         break;
2391                 case 24:
2392                         break;
2393                 default: /* 18 bits... */
2394                         i = ((i & 0x3F000) << 6) + ((i & 0xFC0) << 4) + ((i & 0x3F) << 2);
2395                         i |= 0x010101;
2396                         break;
2397         }
2398
2399         return i;
2400 }
2401
2402 #else
2403
2404 /* this is the old method as being in use for ages.... seems to work? colors are rounded to lower values */
2405
2406 static unsigned int index_to_framebuffer(int index)
2407 {
2408         unsigned int i = index;
2409
2410         switch (GPU_color_depth()) {
2411                 case 8:
2412                         i = ((i & 48) << 18) + ((i & 12) << 12) + ((i & 3) << 6);
2413                         i |= 0x3F3F3F;
2414                         break;
2415                 case 12:
2416                         i = ((i & 0xF00) << 12) + ((i & 0xF0) << 8) + ((i & 0xF) << 4);
2417                         /* sometimes dithering subtracts! */
2418                         i |= 0x0F0F0F;
2419                         break;
2420                 case 15:
2421                 case 16:
2422                         i = ((i & 0x7C00) << 9) + ((i & 0x3E0) << 6) + ((i & 0x1F) << 3);
2423                         i |= 0x070707;
2424                         break;
2425                 case 24:
2426                         break;
2427                 default:    /* 18 bits... */
2428                         i = ((i & 0x3F000) << 6) + ((i & 0xFC0) << 4) + ((i & 0x3F) << 2);
2429                         i |= 0x030303;
2430                         break;
2431         }
2432
2433         return i;
2434 }
2435
2436 #endif
2437
2438
2439 void GPU_select_index_set(int index)
2440 {
2441         const int col = index_to_framebuffer(index);
2442         glColor3ub(( (col)        & 0xFF),
2443                    (((col) >>  8) & 0xFF),
2444                    (((col) >> 16) & 0xFF));
2445 }
2446
2447 void GPU_select_index_get(int index, int *r_col)
2448 {
2449         const int col = index_to_framebuffer(index);
2450         char *c_col = (char *)r_col;
2451         c_col[0] = (col & 0xFF); /* red */
2452         c_col[1] = ((col >>  8) & 0xFF); /* green */
2453         c_col[2] = ((col >> 16) & 0xFF); /* blue */
2454         c_col[3] = 0xFF; /* alpha */
2455 }
2456
2457
2458 #define INDEX_FROM_BUF_8(col)     ((((col) & 0xC00000) >> 18) + (((col) & 0xC000) >> 12) + (((col) & 0xC0) >> 6))
2459 #define INDEX_FROM_BUF_12(col)    ((((col) & 0xF00000) >> 12) + (((col) & 0xF000) >> 8)  + (((col) & 0xF0) >> 4))
2460 #define INDEX_FROM_BUF_15_16(col) ((((col) & 0xF80000) >> 9)  + (((col) & 0xF800) >> 6)  + (((col) & 0xF8) >> 3))
2461 #define INDEX_FROM_BUF_18(col)    ((((col) & 0xFC0000) >> 6)  + (((col) & 0xFC00) >> 4)  + (((col) & 0xFC) >> 2))
2462 #define INDEX_FROM_BUF_24(col)      ((col) & 0xFFFFFF)
2463
2464 int GPU_select_to_index(unsigned int col)
2465 {
2466         if (col == 0) {
2467                 return 0;
2468         }
2469
2470         switch (GPU_color_depth()) {
2471                 case  8: return INDEX_FROM_BUF_8(col);
2472                 case 12: return INDEX_FROM_BUF_12(col);
2473                 case 15:
2474                 case 16: return INDEX_FROM_BUF_15_16(col);
2475                 case 24: return INDEX_FROM_BUF_24(col);
2476                 default: return INDEX_FROM_BUF_18(col);
2477         }
2478 }
2479
2480 void GPU_select_to_index_array(unsigned int *col, const unsigned int size)
2481 {
2482 #define INDEX_BUF_ARRAY(INDEX_FROM_BUF_BITS) \
2483         for (i = size; i--; col++) { \
2484                 if ((c = *col)) { \
2485                         *col = INDEX_FROM_BUF_BITS(c); \
2486                 } \
2487         } ((void)0)
2488
2489         if (size > 0) {
2490                 unsigned int i, c;
2491
2492                 switch (GPU_color_depth()) {
2493                         case  8:
2494                                 INDEX_BUF_ARRAY(INDEX_FROM_BUF_8);
2495                                 break;
2496                         case 12:
2497                                 INDEX_BUF_ARRAY(INDEX_FROM_BUF_12);
2498                                 break;
2499                         case 15:
2500                         case 16:
2501                                 INDEX_BUF_ARRAY(INDEX_FROM_BUF_15_16);
2502                                 break;
2503                         case 24:
2504                                 INDEX_BUF_ARRAY(INDEX_FROM_BUF_24);
2505                                 break;
2506                         default:
2507                                 INDEX_BUF_ARRAY(INDEX_FROM_BUF_18);
2508                                 break;
2509                 }
2510         }
2511
2512 #undef INDEX_BUF_ARRAY
2513 }
2514
2515 /** \} */