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