Depth of field high quality:
[blender.git] / source / blender / gpu / intern / gpu_extensions.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_extensions.c
29  *  \ingroup gpu
30  *
31  * Wrap OpenGL features such as textures, shaders and GLSL
32  * with checks for drivers and GPU support.
33  */
34
35
36 #include "DNA_image_types.h"
37
38 #include "MEM_guardedalloc.h"
39
40 #include "BLI_blenlib.h"
41 #include "BLI_utildefines.h"
42 #include "BLI_math_base.h"
43
44 #include "BKE_global.h"
45
46 #include "GPU_glew.h"
47 #include "GPU_debug.h"
48 #include "GPU_draw.h"
49 #include "GPU_extensions.h"
50 #include "GPU_compositing.h"
51 #include "GPU_simple_shader.h"
52
53 #include "intern/gpu_private.h"
54
55 #include <stdlib.h>
56 #include <stdio.h>
57 #include <string.h>
58
59 #ifdef WIN32
60 #  include "BLI_winstuff.h"
61 #endif
62
63 #define MAX_DEFINE_LENGTH 72
64 #define MAX_EXT_DEFINE_LENGTH 280
65
66 /* Extensions support */
67
68 /* extensions used:
69  * - texture border clamp: 1.3 core
70  * - fragment shader: 2.0 core
71  * - framebuffer object: ext specification
72  * - multitexture 1.3 core
73  * - arb non power of two: 2.0 core
74  * - pixel buffer objects? 2.1 core
75  * - arb draw buffers? 2.0 core
76  */
77
78 /* Non-generated shaders */
79 extern char datatoc_gpu_shader_vsm_store_vert_glsl[];
80 extern char datatoc_gpu_shader_vsm_store_frag_glsl[];
81 extern char datatoc_gpu_shader_sep_gaussian_blur_vert_glsl[];
82 extern char datatoc_gpu_shader_sep_gaussian_blur_frag_glsl[];
83 extern char datatoc_gpu_shader_fx_vert_glsl[];
84 extern char datatoc_gpu_shader_fx_ssao_frag_glsl[];
85 extern char datatoc_gpu_shader_fx_dof_frag_glsl[];
86 extern char datatoc_gpu_shader_fx_dof_vert_glsl[];
87 extern char datatoc_gpu_shader_fx_dof_hq_frag_glsl[];
88 extern char datatoc_gpu_shader_fx_dof_hq_vert_glsl[];
89 extern char datatoc_gpu_shader_fx_dof_hq_geo_glsl[];
90 extern char datatoc_gpu_shader_fx_depth_resolve_glsl[];
91 extern char datatoc_gpu_shader_fx_lib_glsl[];
92
93 typedef struct GPUShaders {
94         GPUShader *vsm_store;
95         GPUShader *sep_gaussian_blur;
96         /* cache for shader fx. Those can exist in combinations so store them here */
97         GPUShader *fx_shaders[MAX_FX_SHADERS * 2];
98 } GPUShaders;
99
100 static struct GPUGlobal {
101         GLint maxtexsize;
102         GLint maxtextures;
103         GLuint currentfb;
104         int glslsupport;
105         int extdisabled;
106         int colordepth;
107         int npotdisabled; /* ATI 3xx-5xx (and more) chipsets support NPoT partially (== not enough) */
108         int dlistsdisabled; /* Legacy ATI driver does not support display lists well */
109         GPUDeviceType device;
110         GPUOSType os;
111         GPUDriverType driver;
112         GPUShaders shaders;
113         GPUTexture *invalid_tex_1D; /* texture used in place of invalid textures (not loaded correctly, missing) */
114         GPUTexture *invalid_tex_2D;
115         GPUTexture *invalid_tex_3D;
116 } GG = {1, 0};
117
118 /* Number of maximum output slots. We support 4 outputs for now (usually we wouldn't need more to preserve fill rate) */
119 #define GPU_FB_MAX_SLOTS 4
120
121 struct GPUFrameBuffer {
122         GLuint object;
123         GPUTexture *colortex[GPU_FB_MAX_SLOTS];
124         GPUTexture *depthtex;
125 };
126
127
128 /* GPU Types */
129
130 bool GPU_type_matches(GPUDeviceType device, GPUOSType os, GPUDriverType driver)
131 {
132         return (GG.device & device) && (GG.os & os) && (GG.driver & driver);
133 }
134
135 /* GPU Extensions */
136
137 void GPU_extensions_disable(void)
138 {
139         GG.extdisabled = 1;
140 }
141
142 int GPU_max_texture_size(void)
143 {
144         return GG.maxtexsize;
145 }
146
147 void gpu_extensions_init(void)
148 {
149         GLint r, g, b;
150         const char *vendor, *renderer;
151
152         /* glewIsSupported("GL_VERSION_2_0") */
153
154         if (GLEW_ARB_multitexture)
155                 glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS_ARB, &GG.maxtextures);
156
157         glGetIntegerv(GL_MAX_TEXTURE_SIZE, &GG.maxtexsize);
158
159         GG.glslsupport = 1;
160         if (!GLEW_ARB_multitexture) GG.glslsupport = 0;
161         if (!GLEW_ARB_vertex_shader) GG.glslsupport = 0;
162         if (!GLEW_ARB_fragment_shader) GG.glslsupport = 0;
163
164         glGetIntegerv(GL_RED_BITS, &r);
165         glGetIntegerv(GL_GREEN_BITS, &g);
166         glGetIntegerv(GL_BLUE_BITS, &b);
167         GG.colordepth = r+g+b; /* assumes same depth for RGB */
168
169         vendor = (const char *)glGetString(GL_VENDOR);
170         renderer = (const char *)glGetString(GL_RENDERER);
171
172         if (strstr(vendor, "ATI")) {
173                 GG.device = GPU_DEVICE_ATI;
174                 GG.driver = GPU_DRIVER_OFFICIAL;
175         }
176         else if (strstr(vendor, "NVIDIA")) {
177                 GG.device = GPU_DEVICE_NVIDIA;
178                 GG.driver = GPU_DRIVER_OFFICIAL;
179         }
180         else if (strstr(vendor, "Intel") ||
181                 /* src/mesa/drivers/dri/intel/intel_context.c */
182                 strstr(renderer, "Mesa DRI Intel") ||
183                 strstr(renderer, "Mesa DRI Mobile Intel")) {
184                 GG.device = GPU_DEVICE_INTEL;
185                 GG.driver = GPU_DRIVER_OFFICIAL;
186         }
187         else if (strstr(renderer, "Mesa DRI R") || (strstr(renderer, "Gallium ") && strstr(renderer, " on ATI "))) {
188                 GG.device = GPU_DEVICE_ATI;
189                 GG.driver = GPU_DRIVER_OPENSOURCE;
190         }
191         else if (strstr(renderer, "Nouveau") || strstr(vendor, "nouveau")) {
192                 GG.device = GPU_DEVICE_NVIDIA;
193                 GG.driver = GPU_DRIVER_OPENSOURCE;
194         }
195         else if (strstr(vendor, "Mesa")) {
196                 GG.device = GPU_DEVICE_SOFTWARE;
197                 GG.driver = GPU_DRIVER_SOFTWARE;
198         }
199         else if (strstr(vendor, "Microsoft")) {
200                 GG.device = GPU_DEVICE_SOFTWARE;
201                 GG.driver = GPU_DRIVER_SOFTWARE;
202         }
203         else if (strstr(renderer, "Apple Software Renderer")) {
204                 GG.device = GPU_DEVICE_SOFTWARE;
205                 GG.driver = GPU_DRIVER_SOFTWARE;
206         }
207         else {
208                 GG.device = GPU_DEVICE_ANY;
209                 GG.driver = GPU_DRIVER_ANY;
210         }
211
212         if (GG.device == GPU_DEVICE_ATI) {
213                 /* ATI 9500 to X2300 cards support NPoT textures poorly
214                  * Incomplete list http://dri.freedesktop.org/wiki/ATIRadeon
215                  * New IDs from MESA's src/gallium/drivers/r300/r300_screen.c
216                  */
217                 /* This list is close enough to those using the legacy driver which
218                  * has a bug with display lists and glVertexAttrib 
219                  */
220                 if (strstr(renderer, "R3") || strstr(renderer, "RV3") ||
221                     strstr(renderer, "R4") || strstr(renderer, "RV4") ||
222                     strstr(renderer, "RS4") || strstr(renderer, "RC4") ||
223                     strstr(renderer, "R5") || strstr(renderer, "RV5") ||
224                     strstr(renderer, "RS600") || strstr(renderer, "RS690") ||
225                     strstr(renderer, "RS740") || strstr(renderer, "X1") ||
226                     strstr(renderer, "X2") || strstr(renderer, "Radeon 9") ||
227                     strstr(renderer, "RADEON 9"))
228                 {
229                         GG.npotdisabled = 1;
230                         GG.dlistsdisabled = 1;
231                 }
232         }
233
234         /* make sure double side isn't used by default and only getting enabled in places where it's
235          * really needed to prevent different unexpected behaviors like with intel gme965 card (sergey) */
236         glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_FALSE);
237
238 #ifdef _WIN32
239         GG.os = GPU_OS_WIN;
240 #elif defined(__APPLE__)
241         GG.os = GPU_OS_MAC;
242 #else
243         GG.os = GPU_OS_UNIX;
244 #endif
245
246
247         GPU_invalid_tex_init();
248         GPU_simple_shaders_init();
249 }
250
251 void gpu_extensions_exit(void)
252 {
253         GPU_simple_shaders_exit();
254         GPU_invalid_tex_free();
255 }
256
257 bool GPU_glsl_support(void)
258 {
259         return !GG.extdisabled && GG.glslsupport;
260 }
261
262 bool GPU_non_power_of_two_support(void)
263 {
264         if (GG.npotdisabled)
265                 return false;
266
267         return GLEW_ARB_texture_non_power_of_two;
268 }
269
270 bool GPU_vertex_buffer_support(void)
271 {
272         return GLEW_ARB_vertex_buffer_object || GLEW_VERSION_1_5;
273 }
274
275 bool GPU_display_list_support(void)
276 {
277         return !GG.dlistsdisabled;
278 }
279
280 bool GPU_bicubic_bump_support(void)
281 {
282         return GLEW_ARB_texture_query_lod && GLEW_VERSION_3_0;
283 }
284
285 bool GPU_geometry_shader_support(void)
286 {
287         return GLEW_EXT_geometry_shader4 || GLEW_VERSION_3_2;
288 }
289
290 bool GPU_instanced_drawing_support(void)
291 {
292         return GLEW_EXT_draw_instanced;
293 }
294
295 int GPU_color_depth(void)
296 {
297         return GG.colordepth;
298 }
299
300 static void GPU_print_framebuffer_error(GLenum status, char err_out[256])
301 {
302         const char *err= "unknown";
303
304         switch (status) {
305                 case GL_FRAMEBUFFER_COMPLETE_EXT:
306                         break;
307                 case GL_INVALID_OPERATION:
308                         err= "Invalid operation";
309                         break;
310                 case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT:
311                         err= "Incomplete attachment";
312                         break;
313                 case GL_FRAMEBUFFER_UNSUPPORTED_EXT:
314                         err= "Unsupported framebuffer format";
315                         break;
316                 case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT:
317                         err= "Missing attachment";
318                         break;
319                 case GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT:
320                         err= "Attached images must have same dimensions";
321                         break;
322                 case GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT:
323                         err= "Attached images must have same format";
324                         break;
325                 case GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT:
326                         err= "Missing draw buffer";
327                         break;
328                 case GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT:
329                         err= "Missing read buffer";
330                         break;
331         }
332
333         if (err_out) {
334                 BLI_snprintf(err_out, 256, "GPUFrameBuffer: framebuffer incomplete error %d '%s'",
335                         (int)status, err);
336         }
337         else {
338                 fprintf(stderr, "GPUFrameBuffer: framebuffer incomplete error %d '%s'\n",
339                         (int)status, err);
340         }
341 }
342
343 /* GPUTexture */
344
345 struct GPUTexture {
346         int w, h;                               /* width/height */
347         int number;                             /* number for multitexture binding */
348         int refcount;                   /* reference count */
349         GLenum target;                  /* GL_TEXTURE_* */
350         GLuint bindcode;                /* opengl identifier for texture */
351         int fromblender;                /* we got the texture from Blender */
352
353         GPUFrameBuffer *fb;             /* GPUFramebuffer this texture is attached to */
354         int fb_attachment;              /* slot the texture is attached to */
355         int depth;                              /* is a depth texture? if 3D how deep? */
356 };
357
358 static unsigned char *GPU_texture_convert_pixels(int length, const float *fpixels)
359 {
360         unsigned char *pixels, *p;
361         const float *fp = fpixels;
362         const int len = 4*length;
363         int a;
364
365         p = pixels = MEM_callocN(sizeof(unsigned char)*len, "GPUTexturePixels");
366
367         for (a=0; a<len; a++, p++, fp++)
368                 *p = FTOCHAR((*fp));
369
370         return pixels;
371 }
372
373 static void GPU_glTexSubImageEmpty(GLenum target, GLenum format, int x, int y, int w, int h)
374 {
375         void *pixels = MEM_callocN(sizeof(char)*4*w*h, "GPUTextureEmptyPixels");
376
377         if (target == GL_TEXTURE_1D)
378                 glTexSubImage1D(target, 0, x, w, format, GL_UNSIGNED_BYTE, pixels);
379         else
380                 glTexSubImage2D(target, 0, x, y, w, h, format, GL_UNSIGNED_BYTE, pixels);
381         
382         MEM_freeN(pixels);
383 }
384
385 static GPUTexture *GPU_texture_create_nD(
386         int w, int h, int n, const float *fpixels, int depth, GPUHDRType hdr_type, int components,
387         char err_out[256])
388 {
389         GPUTexture *tex;
390         GLenum type, format, internalformat;
391         void *pixels = NULL;
392
393         if (depth && !GLEW_ARB_depth_texture)
394                 return NULL;
395
396         tex = MEM_callocN(sizeof(GPUTexture), "GPUTexture");
397         tex->w = w;
398         tex->h = h;
399         tex->number = -1;
400         tex->refcount = 1;
401         tex->target = (n == 1)? GL_TEXTURE_1D: GL_TEXTURE_2D;
402         tex->depth = depth;
403         tex->fb_attachment = -1;
404
405         glGenTextures(1, &tex->bindcode);
406
407         if (!tex->bindcode) {
408                 if (err_out) {
409                         BLI_snprintf(err_out, 256, "GPUTexture: texture create failed: %d",
410                                 (int)glGetError());
411                 }
412                 else {
413                         fprintf(stderr, "GPUTexture: texture create failed: %d\n",
414                                 (int)glGetError());
415                 }
416                 GPU_texture_free(tex);
417                 return NULL;
418         }
419
420         if (!GPU_non_power_of_two_support()) {
421                 tex->w = power_of_2_max_i(tex->w);
422                 tex->h = power_of_2_max_i(tex->h);
423         }
424
425         tex->number = 0;
426         glBindTexture(tex->target, tex->bindcode);
427
428         if (depth) {
429                 type = GL_UNSIGNED_BYTE;
430                 format = GL_DEPTH_COMPONENT;
431                 internalformat = GL_DEPTH_COMPONENT;
432         }
433         else {
434                 type = GL_FLOAT;
435
436                 if (components == 4) {
437                         format = GL_RGBA;
438                         switch (hdr_type) {
439                                 case GPU_HDR_NONE:
440                                         internalformat = GL_RGBA8;
441                                         break;
442                                 case GPU_HDR_HALF_FLOAT:
443                                         internalformat = GL_RGBA16F;
444                                         break;
445                                 case GPU_HDR_FULL_FLOAT:
446                                         internalformat = GL_RGBA32F;
447                                         break;
448                                 default:
449                                         break;
450                         }
451                 }
452                 else if (components == 2) {
453                         format = GL_RG;
454                         switch (hdr_type) {
455                                 case GPU_HDR_NONE:
456                                         internalformat = GL_RG8;
457                                         break;
458                                 case GPU_HDR_HALF_FLOAT:
459                                         internalformat = GL_RG16F;
460                                         break;
461                                 case GPU_HDR_FULL_FLOAT:
462                                         internalformat = GL_RG32F;
463                                         break;
464                                 default:
465                                         break;
466                         }
467                 }
468
469                 if (fpixels && hdr_type == GPU_HDR_NONE) {
470                         type = GL_UNSIGNED_BYTE;
471                         pixels = GPU_texture_convert_pixels(w*h, fpixels);
472                 }
473         }
474
475         if (tex->target == GL_TEXTURE_1D) {
476                 glTexImage1D(tex->target, 0, internalformat, tex->w, 0, format, type, NULL);
477
478                 if (fpixels) {
479                         glTexSubImage1D(tex->target, 0, 0, w, format, type,
480                                 pixels ? pixels : fpixels);
481
482                         if (tex->w > w)
483                                 GPU_glTexSubImageEmpty(tex->target, format, w, 0,
484                                         tex->w-w, 1);
485                 }
486         }
487         else {
488                 glTexImage2D(tex->target, 0, internalformat, tex->w, tex->h, 0,
489                              format, type, NULL);
490
491                 if (fpixels) {
492                         glTexSubImage2D(tex->target, 0, 0, 0, w, h,
493                                 format, type, pixels ? pixels : fpixels);
494
495                         if (tex->w > w)
496                                 GPU_glTexSubImageEmpty(tex->target, format, w, 0, tex->w-w, tex->h);
497                         if (tex->h > h)
498                                 GPU_glTexSubImageEmpty(tex->target, format, 0, h, w, tex->h-h);
499                 }
500         }
501
502         if (pixels)
503                 MEM_freeN(pixels);
504
505         if (depth) {
506                 glTexParameteri(tex->target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
507                 glTexParameteri(tex->target, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
508                 glTexParameteri(tex->target, GL_TEXTURE_COMPARE_MODE_ARB, GL_COMPARE_R_TO_TEXTURE);
509                 glTexParameteri(tex->target, GL_TEXTURE_COMPARE_FUNC_ARB, GL_LEQUAL);
510                 glTexParameteri(tex->target, GL_DEPTH_TEXTURE_MODE_ARB, GL_INTENSITY);  
511         }
512         else {
513                 glTexParameteri(tex->target, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
514                 glTexParameteri(tex->target, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
515         }
516
517         if (tex->target != GL_TEXTURE_1D) {
518                 glTexParameteri(tex->target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
519                 glTexParameteri(tex->target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
520         }
521         else
522                 glTexParameteri(tex->target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
523
524         return tex;
525 }
526
527
528 GPUTexture *GPU_texture_create_3D(int w, int h, int depth, int channels, const float *fpixels)
529 {
530         GPUTexture *tex;
531         GLenum type, format, internalformat;
532         void *pixels = NULL;
533         const float vfBorderColor[4] = {0.0f, 0.0f, 0.0f, 0.0f};
534
535         if (!GLEW_VERSION_1_2)
536                 return NULL;
537
538         tex = MEM_callocN(sizeof(GPUTexture), "GPUTexture");
539         tex->w = w;
540         tex->h = h;
541         tex->depth = depth;
542         tex->number = -1;
543         tex->refcount = 1;
544         tex->target = GL_TEXTURE_3D;
545
546         glGenTextures(1, &tex->bindcode);
547
548         if (!tex->bindcode) {
549                 fprintf(stderr, "GPUTexture: texture create failed: %d\n",
550                         (int)glGetError());
551                 GPU_texture_free(tex);
552                 return NULL;
553         }
554
555         if (!GPU_non_power_of_two_support()) {
556                 tex->w = power_of_2_max_i(tex->w);
557                 tex->h = power_of_2_max_i(tex->h);
558                 tex->depth = power_of_2_max_i(tex->depth);
559         }
560
561         tex->number = 0;
562         glBindTexture(tex->target, tex->bindcode);
563
564         GPU_ASSERT_NO_GL_ERRORS("3D glBindTexture");
565
566         type = GL_FLOAT;
567         if (channels == 4) {
568                 format = GL_RGBA;
569                 internalformat = GL_RGBA;
570         }
571         else {
572                 format = GL_RED;
573                 internalformat = GL_INTENSITY;
574         }
575
576         //if (fpixels)
577         //      pixels = GPU_texture_convert_pixels(w*h*depth, fpixels);
578
579         glTexImage3D(tex->target, 0, internalformat, tex->w, tex->h, tex->depth, 0, format, type, NULL);
580
581         GPU_ASSERT_NO_GL_ERRORS("3D glTexImage3D");
582
583         if (fpixels) {
584                 if (!GPU_non_power_of_two_support() && (w != tex->w || h != tex->h || depth != tex->depth)) {
585                         /* clear first to avoid unitialized pixels */
586                         float *zero= MEM_callocN(sizeof(float)*tex->w*tex->h*tex->depth, "zero");
587                         glTexSubImage3D(tex->target, 0, 0, 0, 0, tex->w, tex->h, tex->depth, format, type, zero);
588                         MEM_freeN(zero);
589                 }
590
591                 glTexSubImage3D(tex->target, 0, 0, 0, 0, w, h, depth, format, type, fpixels);
592                 GPU_ASSERT_NO_GL_ERRORS("3D glTexSubImage3D");
593         }
594
595
596         glTexParameterfv(GL_TEXTURE_3D, GL_TEXTURE_BORDER_COLOR, vfBorderColor);
597         GPU_ASSERT_NO_GL_ERRORS("3D GL_TEXTURE_BORDER_COLOR");
598         glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
599         glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
600         GPU_ASSERT_NO_GL_ERRORS("3D GL_LINEAR");
601         glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
602         glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
603         glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
604         GPU_ASSERT_NO_GL_ERRORS("3D GL_CLAMP_TO_BORDER");
605
606         if (pixels)
607                 MEM_freeN(pixels);
608
609         GPU_texture_unbind(tex);
610
611         return tex;
612 }
613
614 GPUTexture *GPU_texture_from_blender(Image *ima, ImageUser *iuser, bool is_data, double time, int mipmap)
615 {
616         GPUTexture *tex;
617         GLint w, h, border, lastbindcode, bindcode;
618
619         glGetIntegerv(GL_TEXTURE_BINDING_2D, &lastbindcode);
620
621         GPU_update_image_time(ima, time);
622         /* this binds a texture, so that's why to restore it with lastbindcode */
623         bindcode = GPU_verify_image(ima, iuser, 0, 0, mipmap, is_data);
624
625         if (ima->gputexture) {
626                 ima->gputexture->bindcode = bindcode;
627                 glBindTexture(GL_TEXTURE_2D, lastbindcode);
628                 return ima->gputexture;
629         }
630
631         tex = MEM_callocN(sizeof(GPUTexture), "GPUTexture");
632         tex->bindcode = bindcode;
633         tex->number = -1;
634         tex->refcount = 1;
635         tex->target = GL_TEXTURE_2D;
636         tex->fromblender = 1;
637
638         ima->gputexture= tex;
639
640         if (!glIsTexture(tex->bindcode)) {
641                 GPU_ASSERT_NO_GL_ERRORS("Blender Texture Not Loaded");
642         }
643         else {
644                 glBindTexture(GL_TEXTURE_2D, tex->bindcode);
645                 glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_WIDTH, &w);
646                 glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_HEIGHT, &h);
647                 glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_BORDER, &border);
648
649                 tex->w = w - border;
650                 tex->h = h - border;
651         }
652
653         glBindTexture(GL_TEXTURE_2D, lastbindcode);
654
655         return tex;
656 }
657
658 GPUTexture *GPU_texture_from_preview(PreviewImage *prv, int mipmap)
659 {
660         GPUTexture *tex = prv->gputexture[0];
661         GLint w, h, lastbindcode;
662         GLuint bindcode = 0;
663         
664         glGetIntegerv(GL_TEXTURE_BINDING_2D, &lastbindcode);
665         
666         if (tex)
667                 bindcode = tex->bindcode;
668         
669         /* this binds a texture, so that's why to restore it */
670         if (bindcode == 0) {
671                 GPU_create_gl_tex(&bindcode, prv->rect[0], NULL, prv->w[0], prv->h[0], mipmap, 0, NULL);
672         }
673         if (tex) {
674                 tex->bindcode = bindcode;
675                 glBindTexture(GL_TEXTURE_2D, lastbindcode);
676                 return tex;
677         }
678
679         tex = MEM_callocN(sizeof(GPUTexture), "GPUTexture");
680         tex->bindcode = bindcode;
681         tex->number = -1;
682         tex->refcount = 1;
683         tex->target = GL_TEXTURE_2D;
684         
685         prv->gputexture[0]= tex;
686         
687         if (!glIsTexture(tex->bindcode)) {
688                 GPU_ASSERT_NO_GL_ERRORS("Blender Texture Not Loaded");
689         }
690         else {
691                 glBindTexture(GL_TEXTURE_2D, tex->bindcode);
692                 glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_WIDTH, &w);
693                 glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_HEIGHT, &h);
694                 
695                 tex->w = w;
696                 tex->h = h;
697         }
698         
699         glBindTexture(GL_TEXTURE_2D, lastbindcode);
700         
701         return tex;
702
703 }
704
705 GPUTexture *GPU_texture_create_1D(int w, const float *fpixels, char err_out[256])
706 {
707         GPUTexture *tex = GPU_texture_create_nD(w, 1, 1, fpixels, 0, GPU_HDR_NONE, 4, err_out);
708
709         if (tex)
710                 GPU_texture_unbind(tex);
711         
712         return tex;
713 }
714
715 GPUTexture *GPU_texture_create_2D(int w, int h, const float *fpixels, GPUHDRType hdr, char err_out[256])
716 {
717         GPUTexture *tex = GPU_texture_create_nD(w, h, 2, fpixels, 0, hdr, 4, err_out);
718
719         if (tex)
720                 GPU_texture_unbind(tex);
721         
722         return tex;
723 }
724
725 GPUTexture *GPU_texture_create_depth(int w, int h, char err_out[256])
726 {
727         GPUTexture *tex = GPU_texture_create_nD(w, h, 2, NULL, 1, GPU_HDR_NONE, 1, err_out);
728
729         if (tex)
730                 GPU_texture_unbind(tex);
731         
732         return tex;
733 }
734
735 /**
736  * A shadow map for VSM needs two components (depth and depth^2)
737  */
738 GPUTexture *GPU_texture_create_vsm_shadow_map(int size, char err_out[256])
739 {
740         GPUTexture *tex = GPU_texture_create_nD(size, size, 2, NULL, 0, GPU_HDR_FULL_FLOAT, 2, err_out);
741
742         if (tex) {
743                 /* Now we tweak some of the settings */
744                 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
745                 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
746
747                 GPU_texture_unbind(tex);
748         }
749
750         return tex;
751 }
752
753 GPUTexture *GPU_texture_create_2D_procedural(int w, int h, const float *pixels, bool repeat, char err_out[256])
754 {
755         GPUTexture *tex = GPU_texture_create_nD(w, h, 2, pixels, 0, GPU_HDR_HALF_FLOAT, 2, err_out);
756
757         if (tex) {
758                 /* Now we tweak some of the settings */
759                 if (repeat) {
760                         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
761                         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
762                 }
763                 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
764                 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
765
766                 GPU_texture_unbind(tex);
767         }
768
769         return tex;
770 }
771
772 GPUTexture *GPU_texture_create_1D_procedural(int w, const float *pixels, char err_out[256])
773 {
774         GPUTexture *tex = GPU_texture_create_nD(w, 0, 1, pixels, 0, GPU_HDR_HALF_FLOAT, 2, err_out);
775
776         if (tex) {
777                 /* Now we tweak some of the settings */
778                 glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_WRAP_S, GL_REPEAT);
779                 glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
780                 glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
781
782                 GPU_texture_unbind(tex);
783         }
784
785         return tex;
786 }
787
788 void GPU_invalid_tex_init(void)
789 {
790         const float color[4] = {1.0f, 0.0f, 1.0f, 1.0f};
791         GG.invalid_tex_1D = GPU_texture_create_1D(1, color, NULL);
792         GG.invalid_tex_2D = GPU_texture_create_2D(1, 1, color, GPU_HDR_NONE, NULL);
793         GG.invalid_tex_3D = GPU_texture_create_3D(1, 1, 1, 4, color);
794 }
795
796 void GPU_invalid_tex_bind(int mode)
797 {
798         switch (mode) {
799                 case GL_TEXTURE_1D:
800                         glBindTexture(GL_TEXTURE_1D, GG.invalid_tex_1D->bindcode);
801                         break;
802                 case GL_TEXTURE_2D:
803                         glBindTexture(GL_TEXTURE_2D, GG.invalid_tex_2D->bindcode);
804                         break;
805                 case GL_TEXTURE_3D:
806                         glBindTexture(GL_TEXTURE_3D, GG.invalid_tex_3D->bindcode);
807                         break;
808         }
809 }
810
811 void GPU_invalid_tex_free(void)
812 {
813         if (GG.invalid_tex_1D)
814                 GPU_texture_free(GG.invalid_tex_1D);
815         if (GG.invalid_tex_2D)
816                 GPU_texture_free(GG.invalid_tex_2D);
817         if (GG.invalid_tex_3D)
818                 GPU_texture_free(GG.invalid_tex_3D);
819 }
820
821
822 void GPU_texture_bind(GPUTexture *tex, int number)
823 {
824         GLenum arbnumber;
825
826         if (number >= GG.maxtextures) {
827                 fprintf(stderr, "Not enough texture slots.");
828                 return;
829         }
830
831         if ((G.debug & G_DEBUG)) {
832                 if (tex->fb && tex->fb->object == GG.currentfb) {
833                         fprintf(stderr, "Feedback loop warning!: Attempting to bind texture attached to current framebuffer!\n");
834                 }
835         }
836
837         if (number < 0)
838                 return;
839
840         GPU_ASSERT_NO_GL_ERRORS("Pre Texture Bind");
841
842         arbnumber = (GLenum)((GLuint)GL_TEXTURE0_ARB + number);
843         if (number != 0) glActiveTextureARB(arbnumber);
844         if (tex->bindcode != 0) {
845                 glBindTexture(tex->target, tex->bindcode);
846         }
847         else
848                 GPU_invalid_tex_bind(tex->target);
849         glEnable(tex->target);
850         if (number != 0) glActiveTextureARB(GL_TEXTURE0_ARB);
851
852         tex->number = number;
853
854         GPU_ASSERT_NO_GL_ERRORS("Post Texture Bind");
855 }
856
857 void GPU_texture_unbind(GPUTexture *tex)
858 {
859         GLenum arbnumber;
860
861         if (tex->number >= GG.maxtextures) {
862                 fprintf(stderr, "Not enough texture slots.");
863                 return;
864         }
865
866         if (tex->number == -1)
867                 return;
868         
869         GPU_ASSERT_NO_GL_ERRORS("Pre Texture Unbind");
870
871         arbnumber = (GLenum)((GLuint)GL_TEXTURE0_ARB + tex->number);
872         if (tex->number != 0) glActiveTextureARB(arbnumber);
873         glBindTexture(tex->target, 0);
874         glDisable(tex->target);
875         if (tex->number != 0) glActiveTextureARB(GL_TEXTURE0_ARB);
876
877         tex->number = -1;
878
879         GPU_ASSERT_NO_GL_ERRORS("Post Texture Unbind");
880 }
881
882 void GPU_texture_filter_mode(GPUTexture *tex, bool compare, bool use_filter)
883 {
884         GLenum arbnumber;
885
886         if (tex->number >= GG.maxtextures) {
887                 fprintf(stderr, "Not enough texture slots.");
888                 return;
889         }
890
891         if (tex->number == -1)
892                 return;
893
894         GPU_ASSERT_NO_GL_ERRORS("Pre Texture Unbind");
895
896         arbnumber = (GLenum)((GLuint)GL_TEXTURE0_ARB + tex->number);
897         if (tex->number != 0) glActiveTextureARB(arbnumber);
898
899         if (tex->depth) {
900                 if (compare)
901                         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_R_TO_TEXTURE);
902                 else
903                         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_NONE);
904         }
905
906         if (use_filter) {
907                 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
908                 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
909         }
910         else {
911                 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
912                 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
913         }
914         if (tex->number != 0) glActiveTextureARB(GL_TEXTURE0_ARB);
915
916         GPU_ASSERT_NO_GL_ERRORS("Post Texture Unbind");
917 }
918
919 void GPU_texture_free(GPUTexture *tex)
920 {
921         tex->refcount--;
922
923         if (tex->refcount < 0)
924                 fprintf(stderr, "GPUTexture: negative refcount\n");
925         
926         if (tex->refcount == 0) {
927                 if (tex->fb)
928                         GPU_framebuffer_texture_detach(tex);
929                 if (tex->bindcode && !tex->fromblender)
930                         glDeleteTextures(1, &tex->bindcode);
931
932                 MEM_freeN(tex);
933         }
934 }
935
936 void GPU_texture_ref(GPUTexture *tex)
937 {
938         tex->refcount++;
939 }
940
941 int GPU_texture_target(const GPUTexture *tex)
942 {
943         return tex->target;
944 }
945
946 int GPU_texture_opengl_width(const GPUTexture *tex)
947 {
948         return tex->w;
949 }
950
951 int GPU_texture_opengl_height(const GPUTexture *tex)
952 {
953         return tex->h;
954 }
955
956 int GPU_texture_opengl_bindcode(const GPUTexture *tex)
957 {
958         return tex->bindcode;
959 }
960
961 GPUFrameBuffer *GPU_texture_framebuffer(GPUTexture *tex)
962 {
963         return tex->fb;
964 }
965
966 /* GPUFrameBuffer */
967
968 GPUFrameBuffer *GPU_framebuffer_create(void)
969 {
970         GPUFrameBuffer *fb;
971
972         if (!GLEW_EXT_framebuffer_object)
973                 return NULL;
974         
975         fb= MEM_callocN(sizeof(GPUFrameBuffer), "GPUFrameBuffer");
976         glGenFramebuffersEXT(1, &fb->object);
977
978         if (!fb->object) {
979                 fprintf(stderr, "GPUFFrameBuffer: framebuffer gen failed. %d\n",
980                         (int)glGetError());
981                 GPU_framebuffer_free(fb);
982                 return NULL;
983         }
984
985         /* make sure no read buffer is enabled, so completeness check will not fail. We set those at binding time */
986         glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fb->object);
987         glReadBuffer(GL_NONE);
988         glDrawBuffer(GL_NONE);
989         glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
990         
991         return fb;
992 }
993
994 int GPU_framebuffer_texture_attach(GPUFrameBuffer *fb, GPUTexture *tex, int slot, char err_out[256])
995 {
996         GLenum attachment;
997         GLenum error;
998
999         if (slot >= GPU_FB_MAX_SLOTS) {
1000                 fprintf(stderr, "Attaching to index %d framebuffer slot unsupported in blender use at most %d\n", slot, GPU_FB_MAX_SLOTS);
1001                 return 0;
1002         }
1003
1004         if ((G.debug & G_DEBUG)) {
1005                 if (tex->number != -1) {
1006                         fprintf(stderr, "Feedback loop warning!: Attempting to attach texture to framebuffer while still bound to texture unit for drawing!");
1007                 }
1008         }
1009
1010         if (tex->depth)
1011                 attachment = GL_DEPTH_ATTACHMENT_EXT;
1012         else
1013                 attachment = GL_COLOR_ATTACHMENT0_EXT + slot;
1014
1015         glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fb->object);
1016         GG.currentfb = fb->object;
1017
1018         /* Clean glError buffer. */
1019         while (glGetError() != GL_NO_ERROR) {}
1020
1021         glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, attachment, 
1022                 tex->target, tex->bindcode, 0);
1023
1024         error = glGetError();
1025
1026         if (error == GL_INVALID_OPERATION) {
1027                 GPU_framebuffer_restore();
1028                 GPU_print_framebuffer_error(error, err_out);
1029                 return 0;
1030         }
1031
1032         if (tex->depth)
1033                 fb->depthtex = tex;
1034         else
1035                 fb->colortex[slot] = tex;
1036
1037         tex->fb= fb;
1038         tex->fb_attachment = slot;
1039
1040         return 1;
1041 }
1042
1043 void GPU_framebuffer_texture_detach(GPUTexture *tex)
1044 {
1045         GLenum attachment;
1046         GPUFrameBuffer *fb;
1047
1048         if (!tex->fb)
1049                 return;
1050
1051         fb = tex->fb;
1052
1053         if (GG.currentfb != fb->object) {
1054                 glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fb->object);
1055                 GG.currentfb = tex->fb->object;
1056         }
1057
1058         if (tex->depth) {
1059                 fb->depthtex = NULL;
1060                 attachment = GL_DEPTH_ATTACHMENT_EXT;
1061         }
1062         else {
1063                 BLI_assert(fb->colortex[tex->fb_attachment] == tex);
1064                 fb->colortex[tex->fb_attachment] = NULL;
1065                 attachment = GL_COLOR_ATTACHMENT0_EXT + tex->fb_attachment;
1066         }
1067
1068         glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, attachment,
1069                 tex->target, 0, 0);
1070
1071         tex->fb = NULL;
1072         tex->fb_attachment = -1;
1073 }
1074
1075 void GPU_texture_bind_as_framebuffer(GPUTexture *tex)
1076 {
1077         if (!tex->fb) {
1078                 fprintf(stderr, "Error, texture not bound to framebuffer!");
1079                 return;
1080         }
1081
1082         /* push attributes */
1083         glPushAttrib(GL_ENABLE_BIT | GL_VIEWPORT_BIT);
1084         glDisable(GL_SCISSOR_TEST);
1085
1086         /* bind framebuffer */
1087         glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, tex->fb->object);
1088
1089         if (tex->depth) {
1090                 glDrawBuffer(GL_NONE);
1091                 glReadBuffer(GL_NONE);
1092         }
1093         else {
1094                 /* last bound prevails here, better allow explicit control here too */
1095                 glDrawBuffer(GL_COLOR_ATTACHMENT0_EXT + tex->fb_attachment);
1096                 glReadBuffer(GL_COLOR_ATTACHMENT0_EXT + tex->fb_attachment);
1097         }
1098         
1099         /* push matrices and set default viewport and matrix */
1100         glViewport(0, 0, tex->w, tex->h);
1101         GG.currentfb = tex->fb->object;
1102
1103         glMatrixMode(GL_PROJECTION);
1104         glPushMatrix();
1105         glMatrixMode(GL_MODELVIEW);
1106         glPushMatrix();
1107 }
1108
1109 void GPU_framebuffer_slots_bind(GPUFrameBuffer *fb, int slot)
1110 {
1111         int numslots = 0, i;
1112         GLenum attachments[4];
1113         
1114         if (!fb->colortex[slot]) {
1115                 fprintf(stderr, "Error, framebuffer slot empty!");
1116                 return;
1117         }
1118         
1119         for (i = 0 ; i < 4; i++) {
1120                 if (fb->colortex[i]) {
1121                         attachments[numslots] = GL_COLOR_ATTACHMENT0_EXT + i;
1122                         numslots++;
1123                 }
1124         }
1125         
1126         /* push attributes */
1127         glPushAttrib(GL_ENABLE_BIT | GL_VIEWPORT_BIT);
1128         glDisable(GL_SCISSOR_TEST);
1129
1130         /* bind framebuffer */
1131         glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fb->object);
1132
1133         /* last bound prevails here, better allow explicit control here too */
1134         glDrawBuffers(numslots, attachments);
1135         glReadBuffer(GL_COLOR_ATTACHMENT0_EXT + slot);
1136
1137         /* push matrices and set default viewport and matrix */
1138         glViewport(0, 0, fb->colortex[slot]->w, fb->colortex[slot]->h);
1139         GG.currentfb = fb->object;
1140
1141         glMatrixMode(GL_PROJECTION);
1142         glPushMatrix();
1143         glMatrixMode(GL_MODELVIEW);
1144         glPushMatrix();
1145 }
1146
1147
1148 void GPU_framebuffer_texture_unbind(GPUFrameBuffer *UNUSED(fb), GPUTexture *UNUSED(tex))
1149 {
1150         /* restore matrix */
1151         glMatrixMode(GL_PROJECTION);
1152         glPopMatrix();
1153         glMatrixMode(GL_MODELVIEW);
1154         glPopMatrix();
1155
1156         /* restore attributes */
1157         glPopAttrib();
1158 }
1159
1160 void GPU_framebuffer_bind_no_save(GPUFrameBuffer *fb, int slot)
1161 {
1162         glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fb->object);
1163         /* last bound prevails here, better allow explicit control here too */
1164         glDrawBuffer(GL_COLOR_ATTACHMENT0_EXT + slot);
1165         glReadBuffer(GL_COLOR_ATTACHMENT0_EXT + slot);
1166
1167         /* push matrices and set default viewport and matrix */
1168         glViewport(0, 0, fb->colortex[slot]->w, fb->colortex[slot]->h);
1169         GG.currentfb = fb->object;
1170         GG.currentfb = fb->object;
1171 }
1172
1173 bool GPU_framebuffer_check_valid(GPUFrameBuffer *fb, char err_out[256])
1174 {
1175         GLenum status;
1176         
1177         glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fb->object);
1178         GG.currentfb = fb->object;
1179         
1180         /* Clean glError buffer. */
1181         while (glGetError() != GL_NO_ERROR) {}
1182         
1183         status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
1184         
1185         if (status != GL_FRAMEBUFFER_COMPLETE_EXT) {
1186                 GPU_framebuffer_restore();
1187                 GPU_print_framebuffer_error(status, err_out);
1188                 return false;
1189         }
1190         
1191         return true;
1192 }
1193
1194 void GPU_framebuffer_free(GPUFrameBuffer *fb)
1195 {
1196         int i;
1197         if (fb->depthtex)
1198                 GPU_framebuffer_texture_detach(fb->depthtex);
1199
1200         for (i = 0; i < GPU_FB_MAX_SLOTS; i++) {
1201                 if (fb->colortex[i]) {
1202                         GPU_framebuffer_texture_detach(fb->colortex[i]);
1203                 }
1204         }
1205
1206         if (fb->object) {
1207                 glDeleteFramebuffersEXT(1, &fb->object);
1208
1209                 if (GG.currentfb == fb->object) {
1210                         glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
1211                         GG.currentfb = 0;
1212                 }
1213         }
1214
1215         MEM_freeN(fb);
1216 }
1217
1218 void GPU_framebuffer_restore(void)
1219 {
1220         if (GG.currentfb != 0) {
1221                 glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
1222                 GG.currentfb = 0;
1223         }
1224 }
1225
1226 void GPU_framebuffer_blur(GPUFrameBuffer *fb, GPUTexture *tex, GPUFrameBuffer *blurfb, GPUTexture *blurtex)
1227 {
1228         const float scaleh[2] = {1.0f / GPU_texture_opengl_width(blurtex), 0.0f};
1229         const float scalev[2] = {0.0f, 1.0f / GPU_texture_opengl_height(tex)};
1230
1231         GPUShader *blur_shader = GPU_shader_get_builtin_shader(GPU_SHADER_SEP_GAUSSIAN_BLUR);
1232         int scale_uniform, texture_source_uniform;
1233
1234         if (!blur_shader)
1235                 return;
1236
1237         scale_uniform = GPU_shader_get_uniform(blur_shader, "ScaleU");
1238         texture_source_uniform = GPU_shader_get_uniform(blur_shader, "textureSource");
1239                 
1240         /* Blurring horizontally */
1241
1242         /* We do the bind ourselves rather than using GPU_framebuffer_texture_bind() to avoid
1243          * pushing unnecessary matrices onto the OpenGL stack. */
1244         glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, blurfb->object);
1245         glDrawBuffer(GL_COLOR_ATTACHMENT0);
1246         
1247         /* avoid warnings from texture binding */
1248         GG.currentfb = blurfb->object;
1249
1250         GPU_shader_bind(blur_shader);
1251         GPU_shader_uniform_vector(blur_shader, scale_uniform, 2, 1, scaleh);
1252         GPU_shader_uniform_texture(blur_shader, texture_source_uniform, tex);
1253         glViewport(0, 0, GPU_texture_opengl_width(blurtex), GPU_texture_opengl_height(blurtex));
1254
1255         /* Peparing to draw quad */
1256         glMatrixMode(GL_MODELVIEW);
1257         glLoadIdentity();
1258         glMatrixMode(GL_TEXTURE);
1259         glLoadIdentity();
1260         glMatrixMode(GL_PROJECTION);
1261         glLoadIdentity();
1262
1263         glDisable(GL_DEPTH_TEST);
1264
1265         GPU_texture_bind(tex, 0);
1266
1267         /* Drawing quad */
1268         glBegin(GL_QUADS);
1269         glTexCoord2d(0, 0); glVertex2f(1, 1);
1270         glTexCoord2d(1, 0); glVertex2f(-1, 1);
1271         glTexCoord2d(1, 1); glVertex2f(-1, -1);
1272         glTexCoord2d(0, 1); glVertex2f(1, -1);
1273         glEnd();
1274
1275         /* Blurring vertically */
1276
1277         glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fb->object);
1278         glDrawBuffer(GL_COLOR_ATTACHMENT0);
1279         
1280         GG.currentfb = fb->object;
1281         
1282         glViewport(0, 0, GPU_texture_opengl_width(tex), GPU_texture_opengl_height(tex));
1283         GPU_shader_uniform_vector(blur_shader, scale_uniform, 2, 1, scalev);
1284         GPU_shader_uniform_texture(blur_shader, texture_source_uniform, blurtex);
1285         GPU_texture_bind(blurtex, 0);
1286
1287         glBegin(GL_QUADS);
1288         glTexCoord2d(0, 0); glVertex2f(1, 1);
1289         glTexCoord2d(1, 0); glVertex2f(-1, 1);
1290         glTexCoord2d(1, 1); glVertex2f(-1, -1);
1291         glTexCoord2d(0, 1); glVertex2f(1, -1);
1292         glEnd();
1293
1294         GPU_shader_unbind();
1295 }
1296
1297 /* GPUOffScreen */
1298
1299 struct GPUOffScreen {
1300         GPUFrameBuffer *fb;
1301         GPUTexture *color;
1302         GPUTexture *depth;
1303 };
1304
1305 GPUOffScreen *GPU_offscreen_create(int width, int height, char err_out[256])
1306 {
1307         GPUOffScreen *ofs;
1308
1309         ofs= MEM_callocN(sizeof(GPUOffScreen), "GPUOffScreen");
1310
1311         ofs->fb = GPU_framebuffer_create();
1312         if (!ofs->fb) {
1313                 GPU_offscreen_free(ofs);
1314                 return NULL;
1315         }
1316
1317         ofs->depth = GPU_texture_create_depth(width, height, err_out);
1318         if (!ofs->depth) {
1319                 GPU_offscreen_free(ofs);
1320                 return NULL;
1321         }
1322
1323         if (!GPU_framebuffer_texture_attach(ofs->fb, ofs->depth, 0, err_out)) {
1324                 GPU_offscreen_free(ofs);
1325                 return NULL;
1326         }
1327
1328         ofs->color = GPU_texture_create_2D(width, height, NULL, GPU_HDR_NONE, err_out);
1329         if (!ofs->color) {
1330                 GPU_offscreen_free(ofs);
1331                 return NULL;
1332         }
1333
1334         if (!GPU_framebuffer_texture_attach(ofs->fb, ofs->color, 0, err_out)) {
1335                 GPU_offscreen_free(ofs);
1336                 return NULL;
1337         }
1338         
1339         /* check validity at the very end! */
1340         if (!GPU_framebuffer_check_valid(ofs->fb, err_out)) {
1341                 GPU_offscreen_free(ofs);
1342                 return NULL;            
1343         }
1344
1345         GPU_framebuffer_restore();
1346
1347         return ofs;
1348 }
1349
1350 void GPU_offscreen_free(GPUOffScreen *ofs)
1351 {
1352         if (ofs->fb)
1353                 GPU_framebuffer_free(ofs->fb);
1354         if (ofs->color)
1355                 GPU_texture_free(ofs->color);
1356         if (ofs->depth)
1357                 GPU_texture_free(ofs->depth);
1358         
1359         MEM_freeN(ofs);
1360 }
1361
1362 void GPU_offscreen_bind(GPUOffScreen *ofs, bool save)
1363 {
1364         glDisable(GL_SCISSOR_TEST);
1365         if (save)
1366                 GPU_texture_bind_as_framebuffer(ofs->color);
1367         else {
1368                 GPU_framebuffer_bind_no_save(ofs->fb, 0);
1369         }
1370 }
1371
1372 void GPU_offscreen_unbind(GPUOffScreen *ofs, bool restore)
1373 {
1374         if (restore)
1375                 GPU_framebuffer_texture_unbind(ofs->fb, ofs->color);
1376         GPU_framebuffer_restore();
1377         glEnable(GL_SCISSOR_TEST);
1378 }
1379
1380 void GPU_offscreen_read_pixels(GPUOffScreen *ofs, int type, void *pixels)
1381 {
1382         glReadPixels(0, 0, ofs->color->w, ofs->color->h, GL_RGBA, type, pixels);
1383 }
1384
1385 int GPU_offscreen_width(const GPUOffScreen *ofs)
1386 {
1387         return ofs->color->w;
1388 }
1389
1390 int GPU_offscreen_height(const GPUOffScreen *ofs)
1391 {
1392         return ofs->color->h;
1393 }
1394
1395 /* GPUShader */
1396
1397 struct GPUShader {
1398         GLhandleARB object;             /* handle for full shader */
1399         GLhandleARB vertex;             /* handle for vertex shader */
1400         GLhandleARB fragment;   /* handle for fragment shader */
1401         GLhandleARB geometry;   /* handle for geometry shader */
1402         GLhandleARB lib;                /* handle for libment shader */
1403         int totattrib;                  /* total number of attributes */
1404         int uniforms;                   /* required uniforms */
1405 };
1406
1407 static void shader_print_errors(const char *task, char *log, const char **code, int totcode)
1408 {
1409         int i;
1410
1411         fprintf(stderr, "GPUShader: %s error:\n", task);
1412
1413         for (i = 0; i < totcode; i++) {
1414                 const char *c, *pos, *end = code[i] + strlen(code[i]);
1415                 int line = 1;
1416
1417                 if ((G.debug & G_DEBUG)) {
1418                         fprintf(stderr, "===== shader string %d ====\n", i + 1);
1419
1420                         c = code[i];
1421                         while ((c < end) && (pos = strchr(c, '\n'))) {
1422                                 fprintf(stderr, "%2d  ", line);
1423                                 fwrite(c, (pos+1)-c, 1, stderr);
1424                                 c = pos+1;
1425                                 line++;
1426                         }
1427                         
1428                         fprintf(stderr, "%s", c);
1429                 }
1430         }
1431         
1432         fprintf(stderr, "%s\n", log);
1433 }
1434
1435 static const char *gpu_shader_version(void)
1436 {
1437         /* turn on glsl 1.30 for bicubic bump mapping and ATI clipping support */
1438         if (GLEW_VERSION_3_0 &&
1439             (GPU_bicubic_bump_support() || GPU_type_matches(GPU_DEVICE_ATI, GPU_OS_ANY, GPU_DRIVER_ANY)))
1440         {
1441                 return "#version 130\n";
1442         }
1443
1444         return "";
1445 }
1446
1447
1448 static void gpu_shader_standard_extensions(char defines[MAX_EXT_DEFINE_LENGTH])
1449 {
1450         /* need this extensions for high quality bump mapping */
1451         if (GPU_bicubic_bump_support())
1452                 strcat(defines, "#extension GL_ARB_texture_query_lod: enable\n");
1453
1454         if (GPU_geometry_shader_support())
1455                 strcat(defines, "#extension GL_EXT_geometry_shader4: enable\n");
1456
1457         if (GPU_instanced_drawing_support()) {
1458                 strcat(defines, "#extension GL_EXT_gpu_shader4: enable\n");
1459                 strcat(defines, "#extension GL_EXT_draw_instanced: enable\n");
1460         }
1461 }
1462
1463 static void gpu_shader_standard_defines(char defines[MAX_DEFINE_LENGTH])
1464 {
1465         /* some useful defines to detect GPU type */
1466         if (GPU_type_matches(GPU_DEVICE_ATI, GPU_OS_ANY, GPU_DRIVER_ANY)) {
1467                 strcat(defines, "#define GPU_ATI\n");
1468                 if (GLEW_VERSION_3_0)
1469                         strcat(defines, "#define CLIP_WORKAROUND\n");
1470         }
1471         else if (GPU_type_matches(GPU_DEVICE_NVIDIA, GPU_OS_ANY, GPU_DRIVER_ANY))
1472                 strcat(defines, "#define GPU_NVIDIA\n");
1473         else if (GPU_type_matches(GPU_DEVICE_INTEL, GPU_OS_ANY, GPU_DRIVER_ANY))
1474                 strcat(defines, "#define GPU_INTEL\n");
1475
1476         if (GPU_bicubic_bump_support())
1477                 strcat(defines, "#define BUMP_BICUBIC\n");
1478         return;
1479 }
1480
1481 GPUShader *GPU_shader_create(const char *vertexcode, const char *fragcode, const char *geocode, const char *libcode, const char *defines)
1482 {
1483         GLint status;
1484         GLcharARB log[5000];
1485         GLsizei length = 0;
1486         GPUShader *shader;
1487         char standard_defines[MAX_DEFINE_LENGTH] = "";
1488         char standard_extensions[MAX_EXT_DEFINE_LENGTH] = "";
1489
1490         if (!GLEW_ARB_vertex_shader || !GLEW_ARB_fragment_shader || (geocode && !GPU_geometry_shader_support()))
1491                 return NULL;
1492
1493         shader = MEM_callocN(sizeof(GPUShader), "GPUShader");
1494
1495         if (vertexcode)
1496                 shader->vertex = glCreateShaderObjectARB(GL_VERTEX_SHADER_ARB);
1497         if (fragcode)
1498                 shader->fragment = glCreateShaderObjectARB(GL_FRAGMENT_SHADER_ARB);
1499         if (geocode)
1500                 shader->geometry = glCreateShaderObjectARB(GL_GEOMETRY_SHADER_EXT);
1501
1502         shader->object = glCreateProgramObjectARB();
1503
1504         if (!shader->object ||
1505             (vertexcode && !shader->vertex) ||
1506             (fragcode && !shader->fragment) ||
1507             (geocode && !shader->geometry))
1508         {
1509                 fprintf(stderr, "GPUShader, object creation failed.\n");
1510                 GPU_shader_free(shader);
1511                 return NULL;
1512         }
1513
1514         gpu_shader_standard_defines(standard_defines);
1515         gpu_shader_standard_extensions(standard_extensions);
1516
1517         if (vertexcode) {
1518                 const char *source[5];
1519                 /* custom limit, may be too small, beware */
1520                 int num_source = 0;
1521
1522                 source[num_source++] = gpu_shader_version();
1523                 source[num_source++] = standard_extensions;
1524                 source[num_source++] = standard_defines;
1525
1526                 if (defines) source[num_source++] = defines;
1527                 source[num_source++] = vertexcode;
1528
1529                 glAttachObjectARB(shader->object, shader->vertex);
1530                 glShaderSourceARB(shader->vertex, num_source, source, NULL);
1531
1532                 glCompileShaderARB(shader->vertex);
1533                 glGetObjectParameterivARB(shader->vertex, GL_OBJECT_COMPILE_STATUS_ARB, &status);
1534
1535                 if (!status) {
1536                         glGetInfoLogARB(shader->vertex, sizeof(log), &length, log);
1537                         shader_print_errors("compile", log, source, num_source);
1538
1539                         GPU_shader_free(shader);
1540                         return NULL;
1541                 }
1542         }
1543
1544         if (fragcode) {
1545                 const char *source[6];
1546                 int num_source = 0;
1547
1548                 source[num_source++] = gpu_shader_version();
1549                 source[num_source++] = standard_extensions;
1550                 source[num_source++] = standard_defines;
1551
1552                 if (defines) source[num_source++] = defines;
1553                 if (libcode) source[num_source++] = libcode;
1554                 source[num_source++] = fragcode;
1555
1556                 glAttachObjectARB(shader->object, shader->fragment);
1557                 glShaderSourceARB(shader->fragment, num_source, source, NULL);
1558
1559                 glCompileShaderARB(shader->fragment);
1560                 glGetObjectParameterivARB(shader->fragment, GL_OBJECT_COMPILE_STATUS_ARB, &status);
1561
1562                 if (!status) {
1563                         glGetInfoLogARB(shader->fragment, sizeof(log), &length, log);
1564                         shader_print_errors("compile", log, source, num_source);
1565
1566                         GPU_shader_free(shader);
1567                         return NULL;
1568                 }
1569         }
1570
1571         if (geocode) {
1572                 const char *source[6];
1573                 int num_source = 0;
1574
1575                 source[num_source++] = gpu_shader_version();
1576                 source[num_source++] = standard_extensions;
1577                 source[num_source++] = standard_defines;
1578
1579                 if (defines) source[num_source++] = defines;
1580                 if (libcode) source[num_source++] = libcode;
1581                 source[num_source++] = geocode;
1582
1583                 glAttachObjectARB(shader->object, shader->geometry);
1584                 glShaderSourceARB(shader->geometry, num_source, source, NULL);
1585
1586                 glCompileShaderARB(shader->geometry);
1587                 glGetObjectParameterivARB(shader->geometry, GL_OBJECT_COMPILE_STATUS_ARB, &status);
1588
1589                 if (!status) {
1590                         glGetInfoLogARB(shader->geometry, sizeof(log), &length, log);
1591                         shader_print_errors("compile", log, source, num_source);
1592
1593                         GPU_shader_free(shader);
1594                         return NULL;
1595                 }
1596         }
1597
1598
1599 #if 0
1600         if (lib && lib->lib)
1601                 glAttachObjectARB(shader->object, lib->lib);
1602 #endif
1603
1604         glLinkProgramARB(shader->object);
1605         glGetObjectParameterivARB(shader->object, GL_OBJECT_LINK_STATUS_ARB, &status);
1606         if (!status) {
1607                 glGetInfoLogARB(shader->object, sizeof(log), &length, log);
1608                 if (fragcode) shader_print_errors("linking", log, &fragcode, 1);
1609                 else if (vertexcode) shader_print_errors("linking", log, &vertexcode, 1);
1610                 else if (libcode) shader_print_errors("linking", log, &libcode, 1);
1611                 else if (geocode) shader_print_errors("linking", log, &geocode, 1);
1612
1613                 GPU_shader_free(shader);
1614                 return NULL;
1615         }
1616
1617         return shader;
1618 }
1619
1620 #if 0
1621 GPUShader *GPU_shader_create_lib(const char *code)
1622 {
1623         GLint status;
1624         GLcharARB log[5000];
1625         GLsizei length = 0;
1626         GPUShader *shader;
1627
1628         if (!GLEW_ARB_vertex_shader || !GLEW_ARB_fragment_shader)
1629                 return NULL;
1630
1631         shader = MEM_callocN(sizeof(GPUShader), "GPUShader");
1632
1633         shader->lib = glCreateShaderObjectARB(GL_FRAGMENT_SHADER_ARB);
1634
1635         if (!shader->lib) {
1636                 fprintf(stderr, "GPUShader, object creation failed.\n");
1637                 GPU_shader_free(shader);
1638                 return NULL;
1639         }
1640
1641         glShaderSourceARB(shader->lib, 1, (const char**)&code, NULL);
1642
1643         glCompileShaderARB(shader->lib);
1644         glGetObjectParameterivARB(shader->lib, GL_OBJECT_COMPILE_STATUS_ARB, &status);
1645
1646         if (!status) {
1647                 glGetInfoLogARB(shader->lib, sizeof(log), &length, log);
1648                 shader_print_errors("compile", log, code);
1649
1650                 GPU_shader_free(shader);
1651                 return NULL;
1652         }
1653
1654         return shader;
1655 }
1656 #endif
1657
1658 void GPU_shader_bind(GPUShader *shader)
1659 {
1660         GPU_ASSERT_NO_GL_ERRORS("Pre Shader Bind");
1661         glUseProgramObjectARB(shader->object);
1662         GPU_ASSERT_NO_GL_ERRORS("Post Shader Bind");
1663 }
1664
1665 void GPU_shader_unbind(void)
1666 {
1667         GPU_ASSERT_NO_GL_ERRORS("Pre Shader Unbind");
1668         glUseProgramObjectARB(0);
1669         GPU_ASSERT_NO_GL_ERRORS("Post Shader Unbind");
1670 }
1671
1672 void GPU_shader_free(GPUShader *shader)
1673 {
1674         if (shader->lib)
1675                 glDeleteObjectARB(shader->lib);
1676         if (shader->vertex)
1677                 glDeleteObjectARB(shader->vertex);
1678         if (shader->fragment)
1679                 glDeleteObjectARB(shader->fragment);
1680         if (shader->object)
1681                 glDeleteObjectARB(shader->object);
1682         MEM_freeN(shader);
1683 }
1684
1685 int GPU_shader_get_uniform(GPUShader *shader, const char *name)
1686 {
1687         return glGetUniformLocationARB(shader->object, name);
1688 }
1689
1690 void GPU_shader_uniform_vector(GPUShader *UNUSED(shader), int location, int length, int arraysize, const float *value)
1691 {
1692         if (location == -1)
1693                 return;
1694
1695         GPU_ASSERT_NO_GL_ERRORS("Pre Uniform Vector");
1696
1697         if (length == 1) glUniform1fvARB(location, arraysize, value);
1698         else if (length == 2) glUniform2fvARB(location, arraysize, value);
1699         else if (length == 3) glUniform3fvARB(location, arraysize, value);
1700         else if (length == 4) glUniform4fvARB(location, arraysize, value);
1701         else if (length == 9) glUniformMatrix3fvARB(location, arraysize, 0, value);
1702         else if (length == 16) glUniformMatrix4fvARB(location, arraysize, 0, value);
1703
1704         GPU_ASSERT_NO_GL_ERRORS("Post Uniform Vector");
1705 }
1706
1707 void GPU_shader_uniform_vector_int(GPUShader *UNUSED(shader), int location, int length, int arraysize, const int *value)
1708 {
1709         if (location == -1)
1710                 return;
1711
1712         GPU_ASSERT_NO_GL_ERRORS("Pre Uniform Vector");
1713
1714         if (length == 1) glUniform1ivARB(location, arraysize, value);
1715         else if (length == 2) glUniform2ivARB(location, arraysize, value);
1716         else if (length == 3) glUniform3ivARB(location, arraysize, value);
1717         else if (length == 4) glUniform4ivARB(location, arraysize, value);
1718
1719         GPU_ASSERT_NO_GL_ERRORS("Post Uniform Vector");
1720 }
1721
1722 void GPU_shader_uniform_int(GPUShader *UNUSED(shader), int location, int value)
1723 {
1724         if (location == -1)
1725                 return;
1726
1727         GPU_CHECK_ERRORS_AROUND(glUniform1iARB(location, value));
1728 }
1729
1730 void GPU_shader_geometry_stage_primitive_io(GPUShader *shader, int input, int output, int number)
1731 {
1732         glProgramParameteriEXT(shader->object, GL_GEOMETRY_INPUT_TYPE_EXT, input);
1733         glProgramParameteriEXT(shader->object, GL_GEOMETRY_OUTPUT_TYPE_EXT, output);
1734         glProgramParameteriEXT(shader->object, GL_GEOMETRY_VERTICES_OUT_EXT, number);
1735
1736         /* relink so settings can take effect (sucks but should only be done right after compilation so...) */
1737         glLinkProgramARB(shader->object);
1738 }
1739
1740 void GPU_shader_uniform_texture(GPUShader *UNUSED(shader), int location, GPUTexture *tex)
1741 {
1742         GLenum arbnumber;
1743
1744         if (tex->number >= GG.maxtextures) {
1745                 fprintf(stderr, "Not enough texture slots.");
1746                 return;
1747         }
1748                 
1749         if (tex->number == -1)
1750                 return;
1751
1752         if (location == -1)
1753                 return;
1754
1755         GPU_ASSERT_NO_GL_ERRORS("Pre Uniform Texture");
1756
1757         arbnumber = (GLenum)((GLuint)GL_TEXTURE0_ARB + tex->number);
1758
1759         if (tex->number != 0) glActiveTextureARB(arbnumber);
1760         if (tex->bindcode != 0)
1761                 glBindTexture(tex->target, tex->bindcode);
1762         else
1763                 GPU_invalid_tex_bind(tex->target);
1764         glUniform1iARB(location, tex->number);
1765         glEnable(tex->target);
1766         if (tex->number != 0) glActiveTextureARB(GL_TEXTURE0_ARB);
1767
1768         GPU_ASSERT_NO_GL_ERRORS("Post Uniform Texture");
1769 }
1770
1771 int GPU_shader_get_attribute(GPUShader *shader, const char *name)
1772 {
1773         int index;
1774         
1775         GPU_CHECK_ERRORS_AROUND(index = glGetAttribLocationARB(shader->object, name));
1776
1777         return index;
1778 }
1779
1780 GPUShader *GPU_shader_get_builtin_shader(GPUBuiltinShader shader)
1781 {
1782         GPUShader *retval = NULL;
1783
1784         switch (shader) {
1785                 case GPU_SHADER_VSM_STORE:
1786                         if (!GG.shaders.vsm_store)
1787                                 GG.shaders.vsm_store = GPU_shader_create(datatoc_gpu_shader_vsm_store_vert_glsl, datatoc_gpu_shader_vsm_store_frag_glsl, NULL, NULL, NULL);
1788                         retval = GG.shaders.vsm_store;
1789                         break;
1790                 case GPU_SHADER_SEP_GAUSSIAN_BLUR:
1791                         if (!GG.shaders.sep_gaussian_blur)
1792                                 GG.shaders.sep_gaussian_blur = GPU_shader_create(datatoc_gpu_shader_sep_gaussian_blur_vert_glsl, datatoc_gpu_shader_sep_gaussian_blur_frag_glsl, NULL, NULL, NULL);
1793                         retval = GG.shaders.sep_gaussian_blur;
1794                         break;
1795         }
1796
1797         if (retval == NULL)
1798                 printf("Unable to create a GPUShader for builtin shader: %d\n", shader);
1799
1800         return retval;
1801 }
1802
1803 #define MAX_DEFINES 100
1804
1805 GPUShader *GPU_shader_get_builtin_fx_shader(int effects, bool persp)
1806 {
1807         int offset;
1808         char defines[MAX_DEFINES] = "";
1809         /* avoid shaders out of range */
1810         if (effects >= MAX_FX_SHADERS)
1811                 return NULL;
1812
1813         offset = 2 * effects;
1814
1815         if (persp) {
1816                 offset += 1;
1817                 strcat(defines, "#define PERSP_MATRIX\n");
1818         }
1819
1820         if (!GG.shaders.fx_shaders[offset]) {
1821                 GPUShader *shader;
1822
1823                 switch(effects) {
1824                         case GPU_SHADER_FX_SSAO:
1825                                 GG.shaders.fx_shaders[offset] = GPU_shader_create(datatoc_gpu_shader_fx_vert_glsl, datatoc_gpu_shader_fx_ssao_frag_glsl, NULL, datatoc_gpu_shader_fx_lib_glsl, defines);
1826                                 break;
1827
1828                         case GPU_SHADER_FX_DEPTH_OF_FIELD_PASS_ONE:
1829                                 strcat(defines, "#define FIRST_PASS\n");
1830                                 GG.shaders.fx_shaders[offset] = GPU_shader_create(datatoc_gpu_shader_fx_dof_vert_glsl, datatoc_gpu_shader_fx_dof_frag_glsl, NULL, datatoc_gpu_shader_fx_lib_glsl, defines);
1831                                 break;
1832
1833                         case GPU_SHADER_FX_DEPTH_OF_FIELD_PASS_TWO:
1834                                 strcat(defines, "#define SECOND_PASS\n");
1835                                 GG.shaders.fx_shaders[offset] = GPU_shader_create(datatoc_gpu_shader_fx_dof_vert_glsl, datatoc_gpu_shader_fx_dof_frag_glsl, NULL, datatoc_gpu_shader_fx_lib_glsl, defines);
1836                                 break;
1837
1838                         case GPU_SHADER_FX_DEPTH_OF_FIELD_PASS_THREE:
1839                                 strcat(defines, "#define THIRD_PASS\n");
1840                                 GG.shaders.fx_shaders[offset] = GPU_shader_create(datatoc_gpu_shader_fx_dof_vert_glsl, datatoc_gpu_shader_fx_dof_frag_glsl, NULL, datatoc_gpu_shader_fx_lib_glsl, defines);
1841                                 break;
1842
1843                         case GPU_SHADER_FX_DEPTH_OF_FIELD_PASS_FOUR:
1844                                 strcat(defines, "#define FOURTH_PASS\n");
1845                                 GG.shaders.fx_shaders[offset] = GPU_shader_create(datatoc_gpu_shader_fx_dof_vert_glsl, datatoc_gpu_shader_fx_dof_frag_glsl, NULL, datatoc_gpu_shader_fx_lib_glsl, defines);
1846                                 break;
1847
1848                         case GPU_SHADER_FX_DEPTH_OF_FIELD_PASS_FIVE:
1849                                 strcat(defines, "#define FIFTH_PASS\n");
1850                                 GG.shaders.fx_shaders[offset] = GPU_shader_create(datatoc_gpu_shader_fx_dof_vert_glsl, datatoc_gpu_shader_fx_dof_frag_glsl, NULL, datatoc_gpu_shader_fx_lib_glsl, defines);
1851                                 break;
1852
1853                         case GPU_SHADER_FX_DEPTH_OF_FIELD_HQ_PASS_ONE:
1854                                 strcat(defines, "#define FIRST_PASS\n");
1855                                 GG.shaders.fx_shaders[offset] = GPU_shader_create(datatoc_gpu_shader_fx_dof_hq_vert_glsl, datatoc_gpu_shader_fx_dof_hq_frag_glsl, NULL, datatoc_gpu_shader_fx_lib_glsl, defines);
1856                                 break;
1857
1858                         case GPU_SHADER_FX_DEPTH_OF_FIELD_HQ_PASS_TWO:
1859                                 strcat(defines, "#define SECOND_PASS\n");
1860                                 shader = GPU_shader_create(datatoc_gpu_shader_fx_dof_hq_vert_glsl, datatoc_gpu_shader_fx_dof_hq_frag_glsl, datatoc_gpu_shader_fx_dof_hq_geo_glsl, datatoc_gpu_shader_fx_lib_glsl, defines);
1861
1862                                 if (shader) {
1863                                         GG.shaders.fx_shaders[offset] = shader;
1864                                         GPU_shader_geometry_stage_primitive_io(shader, GL_POINTS, GL_TRIANGLE_STRIP, 4);
1865                                 }
1866                                 break;
1867
1868                         case GPU_SHADER_FX_DEPTH_OF_FIELD_HQ_PASS_THREE:
1869                                 strcat(defines, "#define THIRD_PASS\n");
1870                                 GG.shaders.fx_shaders[offset] = GPU_shader_create(datatoc_gpu_shader_fx_dof_hq_vert_glsl, datatoc_gpu_shader_fx_dof_hq_frag_glsl, NULL, datatoc_gpu_shader_fx_lib_glsl, defines);
1871                                 break;
1872
1873                         case GPU_SHADER_FX_DEPTH_RESOLVE:
1874                                 GG.shaders.fx_shaders[offset] = GPU_shader_create(datatoc_gpu_shader_fx_vert_glsl, datatoc_gpu_shader_fx_depth_resolve_glsl, NULL, NULL, defines);
1875                 }
1876         }
1877
1878         return GG.shaders.fx_shaders[offset];
1879 }
1880
1881
1882 void GPU_shader_free_builtin_shaders(void)
1883 {
1884         int i;
1885
1886         if (GG.shaders.vsm_store) {
1887                 MEM_freeN(GG.shaders.vsm_store);
1888                 GG.shaders.vsm_store = NULL;
1889         }
1890
1891         if (GG.shaders.sep_gaussian_blur) {
1892                 MEM_freeN(GG.shaders.sep_gaussian_blur);
1893                 GG.shaders.sep_gaussian_blur = NULL;
1894         }
1895
1896         for (i = 0; i < 2 * MAX_FX_SHADERS; i++) {
1897                 if (GG.shaders.fx_shaders[i]) {
1898                         MEM_freeN(GG.shaders.fx_shaders[i]);
1899                         GG.shaders.fx_shaders[i] = NULL;
1900                 }
1901         }
1902 }
1903
1904 #if 0
1905 /* GPUPixelBuffer */
1906
1907 typedef struct GPUPixelBuffer {
1908         GLuint bindcode[2];
1909         GLuint current;
1910         int datasize;
1911         int numbuffers;
1912         int halffloat;
1913 } GPUPixelBuffer;
1914
1915 void GPU_pixelbuffer_free(GPUPixelBuffer *pb)
1916 {
1917         if (pb->bindcode[0])
1918                 glDeleteBuffersARB(pb->numbuffers, pb->bindcode);
1919         MEM_freeN(pb);
1920 }
1921
1922 GPUPixelBuffer *gpu_pixelbuffer_create(int x, int y, int halffloat, int numbuffers)
1923 {
1924         GPUPixelBuffer *pb;
1925
1926         if (!GLEW_ARB_multitexture || !GLEW_EXT_pixel_buffer_object)
1927                 return NULL;
1928         
1929         pb = MEM_callocN(sizeof(GPUPixelBuffer), "GPUPBO");
1930         pb->datasize = x*y*4*((halffloat)? 16: 8);
1931         pb->numbuffers = numbuffers;
1932         pb->halffloat = halffloat;
1933
1934         glGenBuffersARB(pb->numbuffers, pb->bindcode);
1935
1936         if (!pb->bindcode[0]) {
1937                 fprintf(stderr, "GPUPixelBuffer allocation failed\n");
1938                 GPU_pixelbuffer_free(pb);
1939                 return NULL;
1940         }
1941
1942         return pb;
1943 }
1944
1945 void GPU_pixelbuffer_texture(GPUTexture *tex, GPUPixelBuffer *pb)
1946 {
1947         void *pixels;
1948         int i;
1949
1950         glBindTexture(GL_TEXTURE_RECTANGLE_EXT, tex->bindcode);
1951
1952         for (i = 0; i < pb->numbuffers; i++) {
1953                 glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_EXT, pb->bindcode[pb->current]);
1954                 glBufferDataARB(GL_PIXEL_UNPACK_BUFFER_EXT, pb->datasize, NULL,
1955                 GL_STREAM_DRAW_ARB);
1956
1957                 pixels = glMapBufferARB(GL_PIXEL_UNPACK_BUFFER_EXT, GL_WRITE_ONLY);
1958                 /*memcpy(pixels, _oImage.data(), pb->datasize);*/
1959
1960                 if (!glUnmapBufferARB(GL_PIXEL_UNPACK_BUFFER_EXT)) {
1961                         fprintf(stderr, "Could not unmap opengl PBO\n");
1962                         break;
1963                 }
1964         }
1965
1966         glBindTexture(GL_TEXTURE_RECTANGLE_EXT, 0);
1967 }
1968
1969 static int pixelbuffer_map_into_gpu(GLuint bindcode)
1970 {
1971         void *pixels;
1972
1973         glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_EXT, bindcode);
1974         pixels = glMapBufferARB(GL_PIXEL_UNPACK_BUFFER_EXT, GL_WRITE_ONLY);
1975
1976         /* do stuff in pixels */
1977
1978         if (!glUnmapBufferARB(GL_PIXEL_UNPACK_BUFFER_EXT)) {
1979                 fprintf(stderr, "Could not unmap opengl PBO\n");
1980                 return 0;
1981         }
1982         
1983         return 1;
1984 }
1985
1986 static void pixelbuffer_copy_to_texture(GPUTexture *tex, GPUPixelBuffer *pb, GLuint bindcode)
1987 {
1988         GLenum type = (pb->halffloat)? GL_HALF_FLOAT_NV: GL_UNSIGNED_BYTE;
1989         glBindTexture(GL_TEXTURE_RECTANGLE_EXT, tex->bindcode);
1990         glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_EXT, bindcode);
1991
1992         glTexSubImage2D(GL_TEXTURE_RECTANGLE_EXT, 0, 0, 0, tex->w, tex->h,
1993                                         GL_RGBA, type, NULL);
1994
1995         glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_EXT, 0);
1996         glBindTexture(GL_TEXTURE_RECTANGLE_EXT, 0);
1997 }
1998
1999 void GPU_pixelbuffer_async_to_gpu(GPUTexture *tex, GPUPixelBuffer *pb)
2000 {
2001         int newbuffer;
2002
2003         if (pb->numbuffers == 1) {
2004                 pixelbuffer_copy_to_texture(tex, pb, pb->bindcode[0]);
2005                 pixelbuffer_map_into_gpu(pb->bindcode[0]);
2006         }
2007         else {
2008                 pb->current = (pb->current+1)%pb->numbuffers;
2009                 newbuffer = (pb->current+1)%pb->numbuffers;
2010
2011                 pixelbuffer_map_into_gpu(pb->bindcode[newbuffer]);
2012                 pixelbuffer_copy_to_texture(tex, pb, pb->bindcode[pb->current]);
2013         }
2014 }
2015 #endif
2016