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