World textures displaying for viewport in BI.
authorAlexander Romanov <a.romanov@blend4web.com>
Wed, 27 Jan 2016 09:06:57 +0000 (12:06 +0300)
committerAlexander Romanov <a.romanov@blend4web.com>
Wed, 27 Jan 2016 09:06:57 +0000 (12:06 +0300)
This patch supports "Image or Movie" and "Environment map" types of world texture for the viewport.
It supports:

  - "View", "AngMap" and "Equirectangular" types of mapping.

  - Different types of texture blending (according to BI world render).

  - Same color blending as when it lacked textures (but render via glsl).

{F207734}
{F207735}

Example: {F275180}
Original author: @valentin_b4w

Regards,
Alexander (Blend4Web Team).

Reviewers: sergey, valentin_b4w, brecht, merwin

Reviewed By: merwin

Subscribers: campbellbarton, merwin, blueprintrandom, youle, a.romanov, yurikovelenov, AlexKowel, Evgeny_Rodygin

Projects: #rendering, #opengl_gfx, #bf_blender:_next

Differential Revision: https://developer.blender.org/D1414

21 files changed:
source/blender/blenkernel/BKE_image.h
source/blender/blenkernel/intern/image.c
source/blender/blenloader/intern/readfile.c
source/blender/editors/space_view3d/drawmesh.c
source/blender/editors/space_view3d/view3d_draw.c
source/blender/gpu/GPU_draw.h
source/blender/gpu/GPU_extensions.h
source/blender/gpu/GPU_material.h
source/blender/gpu/GPU_texture.h
source/blender/gpu/intern/gpu_codegen.c
source/blender/gpu/intern/gpu_codegen.h
source/blender/gpu/intern/gpu_draw.c
source/blender/gpu/intern/gpu_extensions.c
source/blender/gpu/intern/gpu_material.c
source/blender/gpu/intern/gpu_texture.c
source/blender/gpu/shaders/gpu_shader_material.glsl
source/blender/makesdna/DNA_image_types.h
source/blender/makesrna/intern/rna_image_api.c
source/blender/python/intern/gpu.c
source/gameengine/Ketsji/BL_Texture.cpp
source/gameengine/VideoTexture/Texture.cpp

index 1d4a405a89cba1ccc8e989705244f62afb774692..aec5b0afa45592abd84666bb57d40357aa64e591 100644 (file)
@@ -259,6 +259,9 @@ bool BKE_image_scale(struct Image *image, int width, int height);
 /* check if texture has alpha (depth=32) */
 bool BKE_image_has_alpha(struct Image *image);
 
+/* check if texture has gpu texture code */
+bool BKE_image_has_bindcode(struct Image *ima);
+
 void BKE_image_get_size(struct Image *image, struct ImageUser *iuser, int *width, int *height);
 void BKE_image_get_size_fl(struct Image *image, struct ImageUser *iuser, float size[2]);
 void BKE_image_get_aspect(struct Image *image, float *aspx, float *aspy);
index 7c40674dd6c0ee0f68ef4e7c6ffa69c60d3961e0..d48b455ae812444093e6eed081e8fd79d0c8a245 100644 (file)
@@ -657,6 +657,18 @@ bool BKE_image_scale(Image *image, int width, int height)
        return (ibuf != NULL);
 }
 
+bool BKE_image_has_bindcode(Image *ima)
+{
+       bool has_bindcode = false;
+       for (int i = 0; i < TEXTARGET_COUNT; i++) {
+               if (ima->bindcode[i]) {
+                       has_bindcode = true;
+                       break;
+               }
+       }
+       return has_bindcode;
+}
+
 static void image_init_color_management(Image *ima)
 {
        ImBuf *ibuf;
index 8899af1d755280e9b4f4d6c7b682c853b45d6f84..b8470b16e142b1a714489987782597bd26cf46d9 100644 (file)
@@ -1565,8 +1565,9 @@ void blo_make_image_pointer_map(FileData *fd, Main *oldmain)
        for (; ima; ima = ima->id.next) {
                if (ima->cache)
                        oldnewmap_insert(fd->imamap, ima->cache, ima->cache, 0);
-               if (ima->gputexture)
-                       oldnewmap_insert(fd->imamap, ima->gputexture, ima->gputexture, 0);
+               for (a = 0; a < TEXTARGET_COUNT; a++)
+                       if (ima->gputexture[a])
+                               oldnewmap_insert(fd->imamap, ima->gputexture[a], ima->gputexture[a], 0);
                if (ima->rr)
                        oldnewmap_insert(fd->imamap, ima->rr, ima->rr, 0);
                for (a=0; a < IMA_MAX_RENDER_SLOT; a++)
@@ -1602,15 +1603,18 @@ void blo_end_image_pointer_map(FileData *fd, Main *oldmain)
        for (; ima; ima = ima->id.next) {
                ima->cache = newimaadr(fd, ima->cache);
                if (ima->cache == NULL) {
-                       ima->bindcode = 0;
                        ima->tpageflag &= ~IMA_GLBIND_IS_DATA;
-                       ima->gputexture = NULL;
+                       for (i = 0; i < TEXTARGET_COUNT; i++) {
+                               ima->bindcode[i] = 0;
+                               ima->gputexture[i] = NULL;
+                       }
                        ima->rr = NULL;
                }
                for (i = 0; i < IMA_MAX_RENDER_SLOT; i++)
                        ima->renders[i] = newimaadr(fd, ima->renders[i]);
                
-               ima->gputexture = newimaadr(fd, ima->gputexture);
+               for (i = 0; i < TEXTARGET_COUNT; i++)
+                       ima->gputexture[i] = newimaadr(fd, ima->gputexture[i]);
                ima->rr = newimaadr(fd, ima->rr);
        }
        for (; sce; sce = sce->id.next) {
@@ -3644,9 +3648,11 @@ static void direct_link_image(FileData *fd, Image *ima)
 
        /* if not restored, we keep the binded opengl index */
        if (!ima->cache) {
-               ima->bindcode = 0;
                ima->tpageflag &= ~IMA_GLBIND_IS_DATA;
-               ima->gputexture = NULL;
+               for (int i = 0; i < TEXTARGET_COUNT; i++) {
+                       ima->bindcode[i] = 0;
+                       ima->gputexture[i] = NULL;
+               }
                ima->rr = NULL;
        }
 
index 8deabfb31abc5eb4507cb541dc459d9c86ef6e39..11ba6fb709b93a5297315d18f26f0cea584ee89f 100644 (file)
@@ -318,7 +318,7 @@ static bool set_draw_settings_cached(int clearcache, MTexPoly *texface, Material
                if (textured) {
                        if (texpaint) {
                                c_badtex = false;
-                               if (GPU_verify_image(ima, NULL, 0, 1, 0, false)) {
+                               if (GPU_verify_image(ima, NULL, GL_TEXTURE_2D, 0, 1, 0, false)) {
                                        glEnable(GL_TEXTURE_2D);
                                        glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
                                        glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_MODULATE);
@@ -337,7 +337,7 @@ static bool set_draw_settings_cached(int clearcache, MTexPoly *texface, Material
                                        glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND2_RGB, GL_SRC_ALPHA);
                                        glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA, GL_REPLACE);
                                        glTexEnvi(GL_TEXTURE_ENV, GL_SRC0_ALPHA, GL_PREVIOUS);
-                                       glBindTexture(GL_TEXTURE_2D, ima->bindcode);
+                                       glBindTexture(GL_TEXTURE_2D, ima->bindcode[TEXTARGET_TEXTURE_2D]);
                                        glActiveTexture(GL_TEXTURE0);                                   
                                }
                                else {
@@ -465,7 +465,7 @@ static void draw_textured_begin(Scene *scene, View3D *v3d, RegionView3D *rv3d, O
                /* load the stencil texture here */
                if (Gtexdraw.stencil != NULL) {
                        glActiveTexture(GL_TEXTURE2);
-                       if (GPU_verify_image(Gtexdraw.stencil, NULL, false, false, false, false)) {
+                       if (GPU_verify_image(Gtexdraw.stencil, NULL, GL_TEXTURE_2D, false, false, false, false)) {
                                float col[4] = {imapaint->stencil_col[0], imapaint->stencil_col[1], imapaint->stencil_col[2], 1.0f};
                                glEnable(GL_TEXTURE_2D);
                                glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
@@ -1046,7 +1046,7 @@ static void tex_mat_set_texture_cb(void *userData, int mat_nr, void *attribs)
        if (ED_object_get_active_image(data->ob, mat_nr, &ima, &iuser, &node, NULL)) {
                /* get openl texture */
                int mipmap = 1;
-               int bindcode = (ima) ? GPU_verify_image(ima, iuser, 0, 0, mipmap, false) : 0;
+               int bindcode = (ima) ? GPU_verify_image(ima, iuser, GL_TEXTURE_2D, 0, 0, mipmap, false) : 0;
 
                if (bindcode) {
                        NodeTexBase *texbase = node->storage;
@@ -1055,7 +1055,7 @@ static void tex_mat_set_texture_cb(void *userData, int mat_nr, void *attribs)
                        GPU_object_material_unbind();
 
                        /* bind texture */
-                       glBindTexture(GL_TEXTURE_2D, ima->bindcode);
+                       glBindTexture(GL_TEXTURE_2D, ima->bindcode[TEXTARGET_TEXTURE_2D]);
 
                        glMatrixMode(GL_TEXTURE);
                        glLoadMatrixf(texbase->tex_mapping.mat);
index c37d90b18784c9beaab9aa23f29fc1647e99ef63..adffcb63293df9a494c39d9c4f11c964bc9435cc 100644 (file)
@@ -99,6 +99,7 @@
 #include "GPU_framebuffer.h"
 #include "GPU_material.h"
 #include "GPU_compositing.h"
+#include "GPU_extensions.h"
 
 #include "view3d_intern.h"  /* own include */
 
@@ -2971,8 +2972,7 @@ void ED_view3d_draw_offscreen_init(Scene *scene, View3D *v3d)
 static void view3d_main_region_clear(Scene *scene, View3D *v3d, ARegion *ar)
 {
        if (scene->world && (v3d->flag3 & V3D_SHOW_WORLD)) {
-               bool glsl = BKE_scene_use_new_shading_nodes(scene) && scene->world->nodetree && scene->world->use_nodes;
-               
+               bool glsl = GPU_glsl_support();
                if (glsl) {
                        RegionView3D *rv3d = ar->regiondata;
                        GPUMaterial *gpumat = GPU_material_world(scene, scene->world);
index afb1cbcf71d4df503fbc5c54b1a3f886352ffbce..75d6362f13ee46e8747e63b5eda7a14042089420 100644 (file)
@@ -132,13 +132,13 @@ void GPU_set_gpu_mipmapping(int gpu_mipmap);
 void GPU_paint_update_image(struct Image *ima, struct ImageUser *iuser, int x, int y, int w, int h);
 void GPU_update_images_framechange(void);
 int GPU_update_image_time(struct Image *ima, double time);
-int GPU_verify_image(struct Image *ima, struct ImageUser *iuser, int tftile, bool compare, bool mipmap, bool is_data);
-void GPU_create_gl_tex(
-        unsigned int *bind, unsigned int *rect, float *frect, int rectw, int recth,
-        bool mipmap, bool use_hight_bit_depth, struct Image *ima);
+int GPU_verify_image(struct Image *ima,
+       struct ImageUser *iuser, int textarget, int tftile, bool compare, bool mipmap, bool is_data);
+void GPU_create_gl_tex(unsigned int *bind, unsigned int *rect, float *frect, int rectw, int recth,
+       int textarget, bool mipmap, bool use_hight_bit_depth, struct Image *ima);
 void GPU_create_gl_tex_compressed(
-        unsigned int *bind, unsigned int *pix, int x, int y, int mipmap,
-        struct Image *ima, struct ImBuf *ibuf);
+       unsigned int *bind, unsigned int *pix, int x, int y, int mipmap,
+       int textarget, struct Image *ima, struct ImBuf *ibuf);
 bool GPU_upload_dxt_texture(struct ImBuf *ibuf);
 void GPU_free_image(struct Image *ima);
 void GPU_free_images(void);
index 64167e94933fc197eeb5c9e557c94dcd64c8a4f7..4a728c881b62ee920d46d06b78e1d7e7054e2573 100644 (file)
@@ -53,6 +53,7 @@ int GPU_max_texture_size(void);
 int GPU_max_textures(void);
 float GPU_max_texture_anisotropy(void);
 int GPU_max_color_texture_samples(void);
+int GPU_max_cube_map_size(void);
 int GPU_color_depth(void);
 void GPU_get_dfdy_factors(float fac[2]);
 
index 65cdf834533f57348586d04387626dfcdc6a7328..3bcc7e23f06dbd2a190dc89251214ee233014289 100644 (file)
@@ -78,6 +78,7 @@ typedef enum GPUType {
 
        GPU_TEX2D = 1002,
        GPU_SHADOW2D = 1003,
+       GPU_TEXCUBE = 1004,
        GPU_ATTRIB = 3001
 } GPUType;
 
@@ -179,6 +180,7 @@ typedef enum GPUDynamicType {
 
        GPU_DYNAMIC_HORIZON_COLOR        = 1  | GPU_DYNAMIC_GROUP_WORLD,
        GPU_DYNAMIC_AMBIENT_COLOR        = 2  | GPU_DYNAMIC_GROUP_WORLD,
+       GPU_DYNAMIC_ZENITH_COLOR         = 3  | GPU_DYNAMIC_GROUP_WORLD,
 
        GPU_DYNAMIC_MAT_DIFFRGB          = 1  | GPU_DYNAMIC_GROUP_MAT,
        GPU_DYNAMIC_MAT_REF              = 2  | GPU_DYNAMIC_GROUP_MAT,
@@ -194,6 +196,7 @@ GPUNodeLink *GPU_attribute(CustomDataType type, const char *name);
 GPUNodeLink *GPU_uniform(float *num);
 GPUNodeLink *GPU_dynamic_uniform(float *num, GPUDynamicType dynamictype, void *data);
 GPUNodeLink *GPU_image(struct Image *ima, struct ImageUser *iuser, bool is_data);
+GPUNodeLink *GPU_cube_map(struct Image *ima, struct ImageUser *iuser, bool is_data);
 GPUNodeLink *GPU_image_preview(struct PreviewImage *prv);
 GPUNodeLink *GPU_texture(int size, float *pixels);
 GPUNodeLink *GPU_dynamic_texture(struct GPUTexture *tex, GPUDynamicType dynamictype, void *data);
index 4166aaf293d332441aa298ede2c2e05fffb5ef21..efa98f7ca2aafad596d07127eb237ea999a9c91a 100644 (file)
@@ -72,7 +72,7 @@ GPUTexture *GPU_texture_create_2D_multisample(
         int w, int h, const float *pixels, GPUHDRType hdr, int samples, char err_out[256]);
 GPUTexture *GPU_texture_create_depth_multisample(int w, int h, int samples, char err_out[256]);
 GPUTexture *GPU_texture_from_blender(
-        struct Image *ima, struct ImageUser *iuser, bool is_data, double time, int mipmap);
+               struct Image *ima, struct ImageUser *iuser, int textarget, bool is_data, double time, int mipmap);
 GPUTexture *GPU_texture_from_preview(struct PreviewImage *prv, int mipmap);
 void GPU_invalid_tex_init(void);
 void GPU_invalid_tex_bind(int mode);
index fb46b167f0f693e3449b860f5da701850af3709f..c3f79bc9492bfa7be84c3631bcc93ffd3637ad29 100644 (file)
@@ -177,6 +177,9 @@ static void gpu_parse_functions_string(GHash *hash, char *code)
                                }
                        }
 
+                       if (!type && gpu_str_prefix(code, "samplerCube")) {
+                               type = GPU_TEXCUBE;
+                       }
                        if (!type && gpu_str_prefix(code, "sampler2DShadow")) {
                                type = GPU_SHADOW2D;
                        }
@@ -505,8 +508,9 @@ static int codegen_print_uniforms_functions(DynStr *ds, ListBase *nodes)
                                /* create exactly one sampler for each texture */
                                if (codegen_input_has_texture(input) && input->bindtex) {
                                        BLI_dynstr_appendf(ds, "uniform %s samp%d;\n",
-                                                          (input->textype == GPU_TEX2D) ? "sampler2D" : "sampler2DShadow",
-                                                          input->texid);
+                                               (input->textype == GPU_TEX2D) ? "sampler2D" :
+                                               (input->textype == GPU_TEXCUBE) ? "samplerCube" : "sampler2DShadow",
+                                               input->texid);
                                }
                        }
                        else if (input->source == GPU_SOURCE_BUILTIN) {
@@ -1015,7 +1019,7 @@ void GPU_pass_bind(GPUPass *pass, double time, int mipmap)
        /* create the textures */
        for (input = inputs->first; input; input = input->next) {
                if (input->ima)
-                       input->tex = GPU_texture_from_blender(input->ima, input->iuser, input->image_isdata, time, mipmap);
+                       input->tex = GPU_texture_from_blender(input->ima, input->iuser, input->textarget, input->image_isdata, time, mipmap);
                else if (input->prv)
                        input->tex = GPU_texture_from_preview(input->prv, mipmap);
        }
@@ -1192,15 +1196,25 @@ static void gpu_node_input_link(GPUNode *node, GPUNodeLink *link, const GPUType
                input->type = GPU_VEC4;
                input->source = GPU_SOURCE_TEX;
 
-               if (link->image == GPU_NODE_LINK_IMAGE_PREVIEW)
+               if (link->image == GPU_NODE_LINK_IMAGE_PREVIEW) {
                        input->prv = link->ptr1;
-               else {
+                       input->textarget = GL_TEXTURE_2D;
+                       input->textype = GPU_TEX2D;
+               }
+               else if (link->image == GPU_NODE_LINK_IMAGE_BLENDER) {
                        input->ima = link->ptr1;
                        input->iuser = link->ptr2;
                        input->image_isdata = link->image_isdata;
+                       input->textarget = GL_TEXTURE_2D;
+                       input->textype = GPU_TEX2D;
+               }
+               else if (link->image == GPU_NODE_LINK_IMAGE_CUBE_MAP) {
+                       input->ima = link->ptr1;
+                       input->iuser = link->ptr2;
+                       input->image_isdata = link->image_isdata;
+                       input->textarget = GL_TEXTURE_CUBE_MAP;
+                       input->textype = GPU_TEXCUBE;
                }
-               input->textarget = GL_TEXTURE_2D;
-               input->textype = GPU_TEX2D;
                MEM_freeN(link);
        }
        else if (link->attribtype) {
@@ -1405,6 +1419,18 @@ GPUNodeLink *GPU_image(Image *ima, ImageUser *iuser, bool is_data)
        return link;
 }
 
+GPUNodeLink *GPU_cube_map(Image *ima, ImageUser *iuser, bool is_data)
+{
+       GPUNodeLink *link = GPU_node_link_create();
+
+       link->image = GPU_NODE_LINK_IMAGE_CUBE_MAP;
+       link->ptr1 = ima;
+       link->ptr2 = iuser;
+       link->image_isdata = is_data;
+
+       return link;
+}
+
 GPUNodeLink *GPU_image_preview(PreviewImage *prv)
 {
        GPUNodeLink *link = GPU_node_link_create();
index 5aa187014baac95b581d3b679a8fbd3d247b548a..75102658c88d4109976f394b9bb51ef474b03d16 100644 (file)
@@ -63,7 +63,8 @@ typedef enum GPUDataSource {
 typedef enum {
        GPU_NODE_LINK_IMAGE_NONE = 0,
        GPU_NODE_LINK_IMAGE_BLENDER = 1,
-       GPU_NODE_LINK_IMAGE_PREVIEW = 2
+       GPU_NODE_LINK_IMAGE_PREVIEW = 2,
+       GPU_NODE_LINK_IMAGE_CUBE_MAP = 3
 } GPUNodeLinkImage;
 
 struct GPUNode {
index a7f802a4502df4baf635e6bbb6f6c860a38cf2c4..be5235b77bbe5a01f42a8a49ab811a44b8d31b55 100644 (file)
@@ -224,11 +224,12 @@ static bool is_power_of_2_resolution(int w, int h)
        return is_power_of_2_i(w) && is_power_of_2_i(h);
 }
 
-static bool is_over_resolution_limit(int w, int h)
+static bool is_over_resolution_limit(GLenum textarget, int w, int h)
 {
+       int size = (textarget == GL_TEXTURE_2D)?
+       GPU_max_texture_size() : GPU_max_cube_map_size();
        int reslimit = (U.glreslimit != 0) ?
-               min_ii(U.glreslimit, GPU_max_texture_size()) :
-               GPU_max_texture_size();
+               min_ii(U.glreslimit, size) : size;
 
        return (w > reslimit || h > reslimit);
 }
@@ -398,6 +399,18 @@ static void gpu_make_repbind(Image *ima)
        BKE_image_release_ibuf(ima, ibuf, NULL);
 }
 
+static unsigned int *gpu_get_image_bindcode(Image *ima, GLenum textarget)
+{
+       unsigned int *bind = 0;
+
+       if (textarget == GL_TEXTURE_2D)
+               bind = &ima->bindcode[TEXTARGET_TEXTURE_2D];
+       else if (textarget == GL_TEXTURE_CUBE_MAP)
+               bind = &ima->bindcode[TEXTARGET_TEXTURE_CUBE_MAP];
+
+       return bind;
+}
+
 void GPU_clear_tpage(bool force)
 {
        if (GTS.lasttface == NULL && !force)
@@ -496,7 +509,7 @@ static void gpu_verify_reflection(Image *ima)
        }
 }
 
-int GPU_verify_image(Image *ima, ImageUser *iuser, int tftile, bool compare, bool mipmap, bool is_data)
+int GPU_verify_image(Image *ima, ImageUser *iuser, int textarget, int tftile, bool compare, bool mipmap, bool is_data)
 {
        unsigned int *bind = NULL;
        int tpx = 0, tpy = 0;
@@ -587,8 +600,8 @@ int GPU_verify_image(Image *ima, ImageUser *iuser, int tftile, bool compare, boo
                if (GTS.tile >= ima->totbind) GTS.tile = 0;
                
                /* this happens when you change repeat buttons */
-               if (ima->repbind) bind = &ima->repbind[GTS.tile];
-               else bind = &ima->bindcode;
+               if (ima->repbind && textarget == GL_TEXTURE_2D) bind = &ima->repbind[GTS.tile];
+               else bind = gpu_get_image_bindcode(ima, textarget);
                
                if (*bind == 0) {
                        short texwindx = ibuf->x / ima->xrep;
@@ -628,7 +641,7 @@ int GPU_verify_image(Image *ima, ImageUser *iuser, int tftile, bool compare, boo
        }
        else {
                /* regular image mode */
-               bind = &ima->bindcode;
+               bind = gpu_get_image_bindcode(ima, textarget);
 
                if (*bind == 0) {
                        tpx = ibuf->x;
@@ -653,7 +666,7 @@ int GPU_verify_image(Image *ima, ImageUser *iuser, int tftile, bool compare, boo
 
        if (*bind != 0) {
                /* enable opengl drawing with textures */
-               glBindTexture(GL_TEXTURE_2D, *bind);
+               glBindTexture(textarget, *bind);
                BKE_image_release_ibuf(ima, ibuf, NULL);
                return *bind;
        }
@@ -694,10 +707,10 @@ int GPU_verify_image(Image *ima, ImageUser *iuser, int tftile, bool compare, boo
 
 #ifdef WITH_DDS
        if (ibuf->ftype == IMB_FTYPE_DDS)
-               GPU_create_gl_tex_compressed(bind, rect, rectw, recth, mipmap, ima, ibuf);
+               GPU_create_gl_tex_compressed(bind, rect, rectw, recth, textarget, mipmap, ima, ibuf);
        else
 #endif
-               GPU_create_gl_tex(bind, rect, frect, rectw, recth, mipmap, use_high_bit_depth, ima);
+               GPU_create_gl_tex(bind, rect, frect, rectw, recth, textarget, mipmap, use_high_bit_depth, ima);
        
        /* mark as non-color data texture */
        if (*bind) {
@@ -720,9 +733,76 @@ int GPU_verify_image(Image *ima, ImageUser *iuser, int tftile, bool compare, boo
        return *bind;
 }
 
+static void **gpu_gen_cube_map(unsigned int *rect, float *frect, int rectw, int recth, bool use_high_bit_depth)
+{
+       size_t block_size = use_high_bit_depth ? sizeof(float) * 4 : sizeof(unsigned char) * 4;
+       void **sides = NULL;
+       int h = recth / 2;
+       int w = rectw / 3;
+
+       if ((use_high_bit_depth && frect == NULL) || (!use_high_bit_depth && rect == NULL) || w != h)
+               return sides;
+
+       /* PosX, NegX, PosY, NegY, PosZ, NegZ */
+       sides = MEM_mallocN(sizeof(void*) * 6, "");
+       for (int i = 0; i < 6; i++)
+               sides[i] = MEM_mallocN(block_size * w * h, "");
+
+       /* divide image into six parts */
+       /* ______________________
+        * |      |      |      |
+        * | NegX | NegY | PosX |
+        * |______|______|______|
+        * |      |      |      |
+        * | NegZ | PosZ | PosY |
+        * |______|______|______|
+       */
+       if (use_high_bit_depth) {
+               float (*frectb)[4] = (float(*)[4])frect;
+               float (**fsides)[4] = (float(**)[4])sides;
+
+               for (int y = 0; y < h; y++) {
+                       for (int x = 0; x < w; x++) {
+                               memcpy(&fsides[0][x * h + y], &frectb[(recth - y - 1) * rectw + 2 * w + x], block_size);
+                               memcpy(&fsides[1][x * h + y], &frectb[(y + h) * rectw + w - 1 - x], block_size);
+                               memcpy(&fsides[3][y * w + x], &frectb[(recth - y - 1) * rectw + 2 * w - 1 - x], block_size);
+                               memcpy(&fsides[5][y * w + x], &frectb[(h - y - 1) * rectw + w - 1 - x], block_size);
+                       }
+                       memcpy(&fsides[2][y * w], frectb[y * rectw + 2 * w], block_size * w);
+                       memcpy(&fsides[4][y * w], frectb[y * rectw + w], block_size * w);
+               }
+       }
+       else {
+               unsigned int **isides = (unsigned int **)sides;
+
+               for (int y = 0; y < h; y++) {
+                       for (int x = 0; x < w; x++) {
+                               isides[0][x * h + y] = rect[(recth - y - 1) * rectw + 2 * w + x];
+                               isides[1][x * h + y] = rect[(y + h) * rectw + w - 1 - x];
+                               isides[3][y * w + x] = rect[(recth - y - 1) * rectw + 2 * w - 1 - x];
+                               isides[5][y * w + x] = rect[(h - y - 1) * rectw + w - 1 - x];
+                       }
+                       memcpy(&isides[2][y * w], &rect[y * rectw + 2 * w], block_size * w);
+                       memcpy(&isides[4][y * w], &rect[y * rectw + w], block_size * w);
+               }
+       }
+
+       return sides;
+}
+
+static void gpu_del_cube_map(void **cube_map)
+{
+       int i;
+       if (cube_map == NULL)
+               return;
+       for (i = 0; i < 6; i++)
+               MEM_freeN(cube_map[i]);
+       MEM_freeN(cube_map);
+}
+
 /* Image *ima can be NULL */
 void GPU_create_gl_tex(unsigned int *bind, unsigned int *rect, float *frect, int rectw, int recth,
-                       bool mipmap, bool use_high_bit_depth, Image *ima)
+       int textarget, bool mipmap, bool use_high_bit_depth, Image *ima)
 {
        ImBuf *ibuf = NULL;
 
@@ -732,12 +812,13 @@ void GPU_create_gl_tex(unsigned int *bind, unsigned int *rect, float *frect, int
        /* scale if not a power of two. this is not strictly necessary for newer
         * GPUs (OpenGL version >= 2.0) since they support non-power-of-two-textures 
         * Then don't bother scaling for hardware that supports NPOT textures! */
-       if ((!GPU_full_non_power_of_two_support() && !is_power_of_2_resolution(rectw, recth)) ||
-           is_over_resolution_limit(rectw, recth))
+       if (textarget == GL_TEXTURE_2D &&
+                       (!GPU_full_non_power_of_two_support() && !is_power_of_2_resolution(rectw, recth) ||
+                       is_over_resolution_limit(textarget, rectw, recth)))
        {
                rectw = smaller_power_of_2_limit(rectw);
                recth = smaller_power_of_2_limit(recth);
-               
+
                if (use_high_bit_depth) {
                        ibuf = IMB_allocFromBuffer(NULL, frect, tpx, tpy);
                        IMB_scaleImBuf(ibuf, rectw, recth);
@@ -754,62 +835,123 @@ void GPU_create_gl_tex(unsigned int *bind, unsigned int *rect, float *frect, int
 
        /* create image */
        glGenTextures(1, (GLuint *)bind);
-       glBindTexture(GL_TEXTURE_2D, *bind);
+       glBindTexture(textarget, *bind);
 
-       if (use_high_bit_depth) {
-               if (GLEW_ARB_texture_float)
-                       glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA16F_ARB, rectw, recth, 0, GL_RGBA, GL_FLOAT, frect);
+       if (textarget == GL_TEXTURE_2D) {
+               if (use_high_bit_depth) {
+                       if (GLEW_ARB_texture_float)
+                               glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA16F_ARB, rectw, recth, 0, GL_RGBA, GL_FLOAT, frect);
+                       else
+                               glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA16, rectw, recth, 0, GL_RGBA, GL_FLOAT, frect);
+               }
                else
-                       glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA16, rectw, recth, 0, GL_RGBA, GL_FLOAT, frect);
-       }
-       else
-               glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, rectw, recth, 0, GL_RGBA, GL_UNSIGNED_BYTE, rect);
+                       glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, rectw, recth, 0, GL_RGBA, GL_UNSIGNED_BYTE, rect);
 
-       glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, gpu_get_mipmap_filter(1));
+               glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, gpu_get_mipmap_filter(1));
 
-       if (GPU_get_mipmap() && mipmap) {
-               if (GTS.gpu_mipmap) {
-                       gpu_generate_mipmap(GL_TEXTURE_2D);
-               }
-               else {
-                       if (!ibuf) {
-                               if (use_high_bit_depth) {
-                                       ibuf = IMB_allocFromBuffer(NULL, frect, tpx, tpy);
+               if (GPU_get_mipmap() && mipmap) {
+                       if (GTS.gpu_mipmap) {
+                               gpu_generate_mipmap(GL_TEXTURE_2D);
+                       }
+                       else {
+                               int i;
+                               if (!ibuf) {
+                                       if (use_high_bit_depth) {
+                                               ibuf = IMB_allocFromBuffer(NULL, frect, tpx, tpy);
+                                       }
+                                       else {
+                                               ibuf = IMB_allocFromBuffer(rect, NULL, tpx, tpy);
+                                       }
                                }
-                               else {
-                                       ibuf = IMB_allocFromBuffer(rect, NULL, tpx, tpy);
+                               IMB_makemipmap(ibuf, true);
+
+                               for (i = 1; i < ibuf->miptot; i++) {
+                                       ImBuf *mip = ibuf->mipmap[i - 1];
+                                       if (use_high_bit_depth) {
+                                               if (GLEW_ARB_texture_float)
+                                                       glTexImage2D(GL_TEXTURE_2D, i, GL_RGBA16F_ARB, mip->x, mip->y, 0, GL_RGBA, GL_FLOAT, mip->rect_float);
+                                               else
+                                                       glTexImage2D(GL_TEXTURE_2D, i, GL_RGBA16, mip->x, mip->y, 0, GL_RGBA, GL_FLOAT, mip->rect_float);
+                                       }
+                                       else {
+                                               glTexImage2D(GL_TEXTURE_2D, i, GL_RGBA8, mip->x, mip->y, 0, GL_RGBA, GL_UNSIGNED_BYTE, mip->rect);
+                                       }
                                }
                        }
+                       glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, gpu_get_mipmap_filter(0));
+                       if (ima)
+                               ima->tpageflag |= IMA_MIPMAP_COMPLETE;
+               }
+               else {
+                       glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+               }
+       }
+       else if (textarget == GL_TEXTURE_CUBE_MAP) {
+               int w = rectw / 3, h = recth / 2;
+
+               if (h == w && is_power_of_2_i(h) && !is_over_resolution_limit(textarget, h, w)) {
+                       void **cube_map = gpu_gen_cube_map(rect, frect, rectw, recth, use_high_bit_depth);
+                       GLenum informat = use_high_bit_depth ? (GLEW_ARB_texture_float ? GL_RGBA16F_ARB : GL_RGBA16) : GL_RGBA8;
+                       GLenum type = use_high_bit_depth ? GL_FLOAT : GL_UNSIGNED_BYTE;
 
-                       IMB_makemipmap(ibuf, true);
-
-                       for (int i = 1; i < ibuf->miptot; i++) {
-                               ImBuf *mip = ibuf->mipmap[i - 1];
-                               if (use_high_bit_depth) {
-                                       if (GLEW_ARB_texture_float)
-                                               glTexImage2D(GL_TEXTURE_2D, i, GL_RGBA16F_ARB, mip->x, mip->y,
-                                                            0, GL_RGBA, GL_FLOAT, mip->rect_float);
-                                       else
-                                               glTexImage2D(GL_TEXTURE_2D, i, GL_RGBA16, mip->x, mip->y,
-                                                            0, GL_RGBA, GL_FLOAT, mip->rect_float);
+                       if (cube_map)
+                               for (int i = 0; i < 6; i++)
+                                       glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, informat, w, h, 0, GL_RGBA, type, cube_map[i]);
+
+                       glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, gpu_get_mipmap_filter(1));
+
+                       if (GPU_get_mipmap() && mipmap) {
+                               if (GTS.gpu_mipmap) {
+                                       gpu_generate_mipmap(GL_TEXTURE_CUBE_MAP);
                                }
                                else {
-                                       glTexImage2D(GL_TEXTURE_2D, i, GL_RGBA8, mip->x, mip->y,
-                                                    0, GL_RGBA, GL_UNSIGNED_BYTE, mip->rect);
+                                       if (!ibuf) {
+                                               if (use_high_bit_depth) {
+                                                       ibuf = IMB_allocFromBuffer(NULL, frect, tpx, tpy);
+                                               }
+                                               else {
+                                                       ibuf = IMB_allocFromBuffer(rect, NULL, tpx, tpy);
+                                               }
+                                       }
+
+                                       IMB_makemipmap(ibuf, true);
+
+                                       for (int i = 1; i < ibuf->miptot; i++) {
+                                               ImBuf *mip = ibuf->mipmap[i - 1];
+                                               void **mip_cube_map = gpu_gen_cube_map(mip->rect, mip->rect_float,
+                                                                                                       mip->x, mip->y, use_high_bit_depth);
+                                               int mipw = mip->x / 3, miph = mip->y / 2;
+
+                                               if (mip_cube_map) {
+                                                       for (int j = 0; j < 6; j++) {
+                                                               glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + j, i,
+                                                                       informat, mipw, miph, 0, GL_RGBA, type, mip_cube_map[j]);
+                                                       }
+                                               }
+                                               gpu_del_cube_map(mip_cube_map);
+                                       }
                                }
+                               glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, gpu_get_mipmap_filter(0));
+
+                               if (ima)
+                                       ima->tpageflag |= IMA_MIPMAP_COMPLETE;
                        }
-               }
-               glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, gpu_get_mipmap_filter(0));
+                       else {
+                               glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+                       }
+                       glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+                       glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+                       glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
 
-               if (ima)
-                       ima->tpageflag |= IMA_MIPMAP_COMPLETE;
-       }
-       else {
-               glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+                       gpu_del_cube_map(cube_map);
+               }
+               else {
+                       printf("Incorrect envmap size\n");
+               }
        }
 
        if (GLEW_EXT_texture_filter_anisotropic)
-               glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, GPU_get_anisotropic());
+               glTexParameterf(textarget, GL_TEXTURE_MAX_ANISOTROPY_EXT, GPU_get_anisotropic());
 
        if (ibuf)
                IMB_freeImBuf(ibuf);
@@ -882,20 +1024,20 @@ bool GPU_upload_dxt_texture(ImBuf *ibuf)
 }
 
 void GPU_create_gl_tex_compressed(
-        unsigned int *bind, unsigned int *pix, int x, int y, int mipmap,
-        Image *ima, ImBuf *ibuf)
+        unsigned int *bind, unsigned int *pix, int x, int y,
+        int textarget, int mipmap, Image *ima, ImBuf *ibuf)
 {
 #ifndef WITH_DDS
        (void)ibuf;
        /* Fall back to uncompressed if DDS isn't enabled */
-       GPU_create_gl_tex(bind, pix, NULL, x, y, mipmap, 0, ima);
+       GPU_create_gl_tex(bind, pix, NULL, x, y, textarget, mipmap, 0, ima);
 #else
        glGenTextures(1, (GLuint *)bind);
-       glBindTexture(GL_TEXTURE_2D, *bind);
+       glBindTexture(textarget, *bind);
 
-       if (GPU_upload_dxt_texture(ibuf) == 0) {
+       if (textarget == GL_TEXTURE_2D && GPU_upload_dxt_texture(ibuf) == 0) {
                glDeleteTextures(1, (GLuint *)bind);
-               GPU_create_gl_tex(bind, pix, NULL, x, y, mipmap, 0, ima);
+               GPU_create_gl_tex(bind, pix, NULL, x, y, textarget, mipmap, 0, ima);
        }
 #endif
 }
@@ -927,7 +1069,7 @@ int GPU_set_tpage(MTexPoly *mtexpoly, int mipmap, int alphablend)
        gpu_verify_alpha_blend(alphablend);
        gpu_verify_reflection(ima);
 
-       if (GPU_verify_image(ima, NULL, mtexpoly->tile, 1, mipmap, false)) {
+       if (GPU_verify_image(ima, NULL, GL_TEXTURE_2D, mtexpoly->tile, 1, mipmap, false)) {
                GTS.curtile = GTS.tile;
                GTS.curima = GTS.ima;
                GTS.curtilemode = GTS.tilemode;
@@ -969,11 +1111,18 @@ void GPU_paint_set_mipmap(bool mipmap)
 
        if (mipmap) {
                for (Image *ima = G.main->image.first; ima; ima = ima->id.next) {
-                       if (ima->bindcode) {
+                       if (BKE_image_has_bindcode(ima)) {
                                if (ima->tpageflag & IMA_MIPMAP_COMPLETE) {
-                                       glBindTexture(GL_TEXTURE_2D, ima->bindcode);
-                                       glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, gpu_get_mipmap_filter(0));
-                                       glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, gpu_get_mipmap_filter(1));
+                                       if (ima->bindcode[TEXTARGET_TEXTURE_2D]) {
+                                               glBindTexture(GL_TEXTURE_2D, ima->bindcode[TEXTARGET_TEXTURE_2D]);
+                                               glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, gpu_get_mipmap_filter(0));
+                                               glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, gpu_get_mipmap_filter(1));
+                                       }
+                                       if (ima->bindcode[TEXTARGET_TEXTURE_CUBE_MAP]) {
+                                               glBindTexture(GL_TEXTURE_CUBE_MAP, ima->bindcode[TEXTARGET_TEXTURE_CUBE_MAP]);
+                                               glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, gpu_get_mipmap_filter(0));
+                                               glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, gpu_get_mipmap_filter(1));
+                                       }
                                }
                                else
                                        GPU_free_image(ima);
@@ -985,10 +1134,17 @@ void GPU_paint_set_mipmap(bool mipmap)
        }
        else {
                for (Image *ima = G.main->image.first; ima; ima = ima->id.next) {
-                       if (ima->bindcode) {
-                               glBindTexture(GL_TEXTURE_2D, ima->bindcode);
-                               glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
-                               glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, gpu_get_mipmap_filter(1));
+                       if (BKE_image_has_bindcode(ima)) {
+                               if (ima->bindcode[TEXTARGET_TEXTURE_2D]) {
+                                       glBindTexture(GL_TEXTURE_2D, ima->bindcode[TEXTARGET_TEXTURE_2D]);
+                                       glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+                                       glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, gpu_get_mipmap_filter(1));
+                               }
+                               if (ima->bindcode[TEXTARGET_TEXTURE_CUBE_MAP]) {
+                                       glBindTexture(GL_TEXTURE_CUBE_MAP, ima->bindcode[TEXTARGET_TEXTURE_CUBE_MAP]);
+                                       glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+                                       glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, gpu_get_mipmap_filter(1));
+                               }
                        }
                        else
                                ima->tpageflag &= ~IMA_MIPMAP_COMPLETE;
@@ -1001,7 +1157,7 @@ void GPU_paint_set_mipmap(bool mipmap)
 static bool GPU_check_scaled_image(ImBuf *ibuf, Image *ima, float *frect, int x, int y, int w, int h)
 {
        if ((!GPU_full_non_power_of_two_support() && !is_power_of_2_resolution(ibuf->x, ibuf->y)) ||
-           is_over_resolution_limit(ibuf->x, ibuf->y))
+               is_over_resolution_limit(GL_TEXTURE_2D, ibuf->x, ibuf->y))
        {
                int x_limit = smaller_power_of_2_limit(ibuf->x);
                int y_limit = smaller_power_of_2_limit(ibuf->y);
@@ -1027,7 +1183,7 @@ static bool GPU_check_scaled_image(ImBuf *ibuf, Image *ima, float *frect, int x,
                        ImBuf *ibuf_scale = IMB_allocFromBuffer(NULL, frect, w, h);
                        IMB_scaleImBuf(ibuf_scale, rectw, recth);
 
-                       glBindTexture(GL_TEXTURE_2D, ima->bindcode);
+                       glBindTexture(GL_TEXTURE_2D, ima->bindcode[TEXTARGET_TEXTURE_2D]);
                        glTexSubImage2D(GL_TEXTURE_2D, 0, x, y, rectw, recth, GL_RGBA,
                                        GL_FLOAT, ibuf_scale->rect_float);
 
@@ -1047,7 +1203,7 @@ static bool GPU_check_scaled_image(ImBuf *ibuf, Image *ima, float *frect, int x,
                                        bilinear_interpolation_color_wrap(ibuf, (unsigned char *)(p + i + j * (rectw)), NULL, u, v);
                                }
                        }
-                       glBindTexture(GL_TEXTURE_2D, ima->bindcode);
+                       glBindTexture(GL_TEXTURE_2D, ima->bindcode[TEXTARGET_TEXTURE_2D]);
                        glTexSubImage2D(GL_TEXTURE_2D, 0, x, y, rectw, recth, GL_RGBA,
                                        GL_UNSIGNED_BYTE, scalerect);
 
@@ -1071,7 +1227,7 @@ void GPU_paint_update_image(Image *ima, ImageUser *iuser, int x, int y, int w, i
 {
        ImBuf *ibuf = BKE_image_acquire_ibuf(ima, iuser, NULL);
        
-       if (ima->repbind || (GPU_get_mipmap() && !GTS.gpu_mipmap) || !ima->bindcode || !ibuf ||
+       if (ima->repbind || (GPU_get_mipmap() && !GTS.gpu_mipmap) || BKE_image_has_bindcode(ima) || !ibuf ||
            (w == 0) || (h == 0))
        {
                /* these cases require full reload still */
@@ -1094,7 +1250,7 @@ void GPU_paint_update_image(Image *ima, ImageUser *iuser, int x, int y, int w, i
                                return;
                        }
 
-                       glBindTexture(GL_TEXTURE_2D, ima->bindcode);
+                       glBindTexture(GL_TEXTURE_2D, ima->bindcode[TEXTARGET_TEXTURE_2D]);
                        glTexSubImage2D(GL_TEXTURE_2D, 0, x, y, w, h, GL_RGBA, GL_FLOAT, buffer);
 
                        MEM_freeN(buffer);
@@ -1117,7 +1273,7 @@ void GPU_paint_update_image(Image *ima, ImageUser *iuser, int x, int y, int w, i
                        return;
                }
 
-               glBindTexture(GL_TEXTURE_2D, ima->bindcode);
+               glBindTexture(GL_TEXTURE_2D, ima->bindcode[TEXTARGET_TEXTURE_2D]);
 
                glGetIntegerv(GL_UNPACK_ROW_LENGTH, &row_length);
                glGetIntegerv(GL_UNPACK_SKIP_PIXELS, &skip_pixels);
@@ -1303,16 +1459,17 @@ void GPU_free_image(Image *ima)
                return;
        }
 
-       /* free regular image binding */
-       if (ima->bindcode) {
-               glDeleteTextures(1, (GLuint *)&ima->bindcode);
-               ima->bindcode = 0;
-       }
-
-       /* free glsl image binding */
-       if (ima->gputexture) {
-               GPU_texture_free(ima->gputexture);
-               ima->gputexture = NULL;
+       for (int i = 0; i < TEXTARGET_COUNT; i++) {
+               /* free regular image binding */
+               if (ima->bindcode[i]) {
+                       glDeleteTextures(1, (GLuint *)&ima->bindcode[i]);
+                       ima->bindcode[i] = 0;
+               }
+               /* free glsl image binding */
+               if (ima->gputexture[i]) {
+                       GPU_texture_free(ima->gputexture[i]);
+                       ima->gputexture[i] = NULL;
+               }
        }
 
        /* free repeated image binding */
@@ -1366,7 +1523,7 @@ void GPU_free_images_old(void)
                if ((ima->flag & IMA_NOCOLLECT) == 0 && ctime - ima->lastused > U.textimeout) {
                        /* If it's in GL memory, deallocate and set time tag to current time
                         * This gives textures a "second chance" to be used before dying. */
-                       if (ima->bindcode || ima->repbind) {
+                       if (BKE_image_has_bindcode(ima) || ima->repbind) {
                                GPU_free_image(ima);
                                ima->lastused = ctime;
                        }
index a53c55b6016f5193d8acf0fef9b1a64bb9a919e7..fd660d2e97c96effba9e3c4d961013c2de0266da 100644 (file)
@@ -73,6 +73,7 @@
 
 static struct GPUGlobal {
        GLint maxtexsize;
+       GLint maxcubemapsize;
        GLint maxtextures;
        bool extdisabled;
        int colordepth;
@@ -120,6 +121,11 @@ int GPU_max_color_texture_samples(void)
        return GG.samples_color_texture_max;
 }
 
+int GPU_max_cube_map_size(void)
+{
+       return GG.maxcubemapsize;
+}
+
 void GPU_get_dfdy_factors(float fac[2])
 {
        copy_v2_v2(fac, GG.dfdyfactors);
@@ -133,6 +139,7 @@ void gpu_extensions_init(void)
        glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS, &GG.maxtextures);
 
        glGetIntegerv(GL_MAX_TEXTURE_SIZE, &GG.maxtexsize);
+       glGetIntegerv(GL_MAX_CUBE_MAP_TEXTURE_SIZE, &GG.maxcubemapsize);
 
        if (GLEW_EXT_texture_filter_anisotropic)
                glGetFloatv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &GG.max_anisotropy);
index 81f04f0ef22ab79bf414975cf7112fb7c1303b9f..09d326e2ee8d922773d98c1e6098d05bccf02711 100644 (file)
@@ -1814,6 +1814,198 @@ GPUMaterial *GPU_material_matcap(Scene *scene, Material *ma, bool use_opensubdiv
        return mat;
 }
 
+static void do_world_tex(GPUShadeInput *shi, struct World *wo, GPUNodeLink **hor, GPUNodeLink **zen, GPUNodeLink **blend)
+{
+       GPUMaterial *mat = shi->gpumat;
+       GPUNodeLink *texco, *tin, *trgb, *stencil, *tcol, *zenfac;
+       MTex *mtex;
+       Tex *tex;
+       float ofs[3], zero = 0.0f;
+       int tex_nr, rgbnor;
+
+       GPU_link(mat, "set_value_one", &stencil);
+       /* go over texture slots */
+       for (tex_nr = 0; tex_nr < MAX_MTEX; tex_nr++) {
+               if (wo->mtex[tex_nr]) {
+                       mtex = wo->mtex[tex_nr];
+                       tex = mtex->tex;
+                       if (tex == NULL || !tex->ima || (tex->type != TEX_IMAGE && tex->type != TEX_ENVMAP))
+                               continue;
+                       /* which coords */
+                       if (mtex->texco == TEXCO_VIEW || mtex->texco == TEXCO_GLOB) {
+                               if (tex->type == TEX_IMAGE)
+                                       texco = GPU_builtin(GPU_VIEW_POSITION);
+                               else if (tex->type == TEX_ENVMAP)
+                                       GPU_link(mat, "background_transform_to_world", GPU_builtin(GPU_VIEW_POSITION), &texco);
+                       }
+                       else if (mtex->texco == TEXCO_EQUIRECTMAP || mtex->texco == TEXCO_ANGMAP) {
+                               if ((tex->type == TEX_IMAGE && wo->skytype & WO_SKYREAL) || tex->type == TEX_ENVMAP)
+                                       GPU_link(mat, "background_transform_to_world", GPU_builtin(GPU_VIEW_POSITION), &texco);
+                               else
+                                       texco = GPU_builtin(GPU_VIEW_POSITION);
+                       }
+                       else
+                               continue;
+                       GPU_link(mat, "texco_norm", texco, &texco);
+                       if (tex->type == TEX_IMAGE && !(wo->skytype & WO_SKYREAL)) {
+                               GPU_link(mat, "mtex_2d_mapping", texco, &texco);
+                       }
+                       if (mtex->size[0] != 1.0f || mtex->size[1] != 1.0f || mtex->size[2] != 1.0f) {
+                               float size[3] = { mtex->size[0], mtex->size[1], mtex->size[2] };
+                               if (tex->type == TEX_ENVMAP) {
+                                       size[1] = mtex->size[2];
+                                       size[2] = mtex->size[1];
+                               }
+                               GPU_link(mat, "mtex_mapping_size", texco, GPU_uniform(size), &texco);
+                       }
+                       ofs[0] = mtex->ofs[0] + 0.5f - 0.5f * mtex->size[0];
+                       if (tex->type == TEX_ENVMAP) {
+                               ofs[1] = -mtex->ofs[2] + 0.5f - 0.5f * mtex->size[2];
+                               ofs[2] = mtex->ofs[1] + 0.5f - 0.5f * mtex->size[1];
+                       }
+                       else {
+                               ofs[1] = mtex->ofs[1] + 0.5f - 0.5f * mtex->size[1];
+                               ofs[2] = 0.0;
+                       }
+                       if (ofs[0] != 0.0f || ofs[1] != 0.0f || ofs[2] != 0.0f)
+                               GPU_link(mat, "mtex_mapping_ofs", texco, GPU_uniform(ofs), &texco);
+                       if (mtex->texco == TEXCO_EQUIRECTMAP) {
+                               GPU_link(mat, "node_tex_environment_equirectangular", texco, GPU_image(tex->ima, &tex->iuser, false), &trgb);
+                       }
+                       else if (mtex->texco == TEXCO_ANGMAP) {
+                               GPU_link(mat, "node_tex_environment_mirror_ball", texco, GPU_image(tex->ima, &tex->iuser, false), &trgb);
+                       }
+                       else {
+                               if (tex->type == TEX_ENVMAP)
+                                       GPU_link(mat, "mtex_cube_map", texco, GPU_cube_map(tex->ima, &tex->iuser, false), &tin, &trgb);
+                               else if (tex->type == TEX_IMAGE)
+                                       GPU_link(mat, "mtex_image", texco, GPU_image(tex->ima, &tex->iuser, false), &tin, &trgb);
+                       }
+                       rgbnor = TEX_RGB;
+                       if (tex->type == TEX_IMAGE || tex->type == TEX_ENVMAP)
+                               if (GPU_material_do_color_management(mat))
+                                       GPU_link(mat, "srgb_to_linearrgb", trgb, &trgb);
+                       /* texture output */
+                       if ((rgbnor & TEX_RGB) && (mtex->texflag & MTEX_RGBTOINT)) {
+                               GPU_link(mat, "mtex_rgbtoint", trgb, &tin);
+                               rgbnor -= TEX_RGB;
+                       }
+                       if (mtex->texflag & MTEX_NEGATIVE) {
+                               if (rgbnor & TEX_RGB)
+                                       GPU_link(mat, "mtex_rgb_invert", trgb, &trgb);
+                               else
+                                       GPU_link(mat, "mtex_value_invert", tin, &tin);
+                       }
+                       if (mtex->texflag & MTEX_STENCIL) {
+                               if (rgbnor & TEX_RGB)
+                                       GPU_link(mat, "mtex_rgb_stencil", stencil, trgb, &stencil, &trgb);
+                               else
+                                       GPU_link(mat, "mtex_value_stencil", stencil, tin, &stencil, &tin);
+                       }
+                       else {
+                               if (rgbnor & TEX_RGB)
+                                       GPU_link(mat, "mtex_alpha_multiply_value", trgb, stencil, &trgb);
+                               else
+                                       GPU_link(mat, "math_multiply", stencil, tin, &tin);
+                       }
+                       /* color mapping */
+                       if (mtex->mapto & (WOMAP_HORIZ + WOMAP_ZENUP + WOMAP_ZENDOWN)) {
+                               if ((rgbnor & TEX_RGB) == 0)
+                                       GPU_link(mat, "set_rgb", GPU_uniform(&mtex->r), &trgb);
+                               else
+                                       GPU_link(mat, "mtex_alpha_from_col", trgb, &tin);
+                               GPU_link(mat, "set_rgb", trgb, &tcol);
+                               if (mtex->mapto & WOMAP_HORIZ) {
+                                       texture_rgb_blend(mat, tcol, *hor, tin, GPU_uniform(&mtex->colfac), mtex->blendtype, hor);
+                               }
+                               if (mtex->mapto & (WOMAP_ZENUP + WOMAP_ZENDOWN)) {
+                                       GPU_link(mat, "set_value_zero", &zenfac);
+                                       if (wo->skytype & WO_SKYREAL) {
+                                               if (mtex->mapto & WOMAP_ZENUP) {
+                                                       if (mtex->mapto & WOMAP_ZENDOWN) {
+                                                               GPU_link(mat, "world_zen_mapping", shi->view, GPU_uniform(&mtex->zenupfac),
+                                                                       GPU_uniform(&mtex->zendownfac), &zenfac);
+                                                       }
+                                                       else {
+                                                               GPU_link(mat, "world_zen_mapping", shi->view, GPU_uniform(&mtex->zenupfac),
+                                                                       GPU_uniform(&zero), &zenfac);
+                                                       }
+                                               }
+                                               else if (mtex->mapto & WOMAP_ZENDOWN)
+                                                       GPU_link(mat, "world_zen_mapping", shi->view, GPU_uniform(&zero),
+                                                               GPU_uniform(&mtex->zendownfac), &zenfac);
+                                       }
+                                       else {
+                                               if (mtex->mapto & WOMAP_ZENUP)
+                                                       GPU_link(mat, "set_value", GPU_uniform(&mtex->zenupfac), &zenfac);
+                                               else if (mtex->mapto & WOMAP_ZENDOWN)
+                                                       GPU_link(mat, "set_value", GPU_uniform(&mtex->zendownfac), &zenfac);
+                                       }
+                                       texture_rgb_blend(mat, tcol, *zen, tin, zenfac, mtex->blendtype, zen);
+                               }
+                       }
+                       if (mtex->mapto & WOMAP_BLEND && wo->skytype & WO_SKYBLEND) {
+                               if (rgbnor & TEX_RGB)
+                                       GPU_link(mat, "mtex_rgbtoint", trgb, &tin);
+                               texture_value_blend(mat, GPU_uniform(&mtex->def_var), *blend, tin, GPU_uniform(&mtex->blendfac), mtex->blendtype, blend);
+                       }
+               }
+       }
+}
+
+static void GPU_material_old_world(struct GPUMaterial *mat, struct World *wo)
+{
+       GPUShadeInput shi;
+       GPUShadeResult shr;
+       GPUNodeLink *hor, *zen, *ray, *blend;
+
+       shi.gpumat = mat;
+
+       for (int i = 0; i < MAX_MTEX; i++) {
+               if (wo->mtex[i] && wo->mtex[i]->tex) {
+                       wo->skytype |= WO_SKYTEX;
+                       break;
+               }
+       }
+       if ((wo->skytype & (WO_SKYBLEND + WO_SKYTEX)) == 0) {
+               GPU_link(mat, "set_rgb", GPU_dynamic_uniform(&wo->horr, GPU_DYNAMIC_HORIZON_COLOR, NULL), &shr.combined);
+       }
+       else {
+               GPU_link(mat, "set_rgb_zero", &shi.rgb);
+               GPU_link(mat, "background_transform_to_world", GPU_builtin(GPU_VIEW_POSITION), &ray);
+               if (wo->skytype & WO_SKYPAPER)
+                       GPU_link(mat, "world_paper_view", GPU_builtin(GPU_VIEW_POSITION), &shi.view);
+               else
+                       GPU_link(mat, "shade_view", ray, &shi.view);
+               if (wo->skytype & WO_SKYBLEND) {
+                       if (wo->skytype & WO_SKYPAPER) {
+                               if (wo->skytype & WO_SKYREAL)
+                                       GPU_link(mat, "world_blend_paper_real", GPU_builtin(GPU_VIEW_POSITION), &blend);
+                               else
+                                       GPU_link(mat, "world_blend_paper", GPU_builtin(GPU_VIEW_POSITION), &blend);
+                       }
+                       else {
+                               if (wo->skytype & WO_SKYREAL)
+                                       GPU_link(mat, "world_blend_real", ray, &blend);
+                               else
+                                       GPU_link(mat, "world_blend", ray, &blend);
+                       }
+               }
+               else {
+                       GPU_link(mat, "set_value_zero", &blend);
+               }
+               GPU_link(mat, "set_rgb", GPU_dynamic_uniform(&wo->horr, GPU_DYNAMIC_HORIZON_COLOR, NULL), &hor);
+               GPU_link(mat, "set_rgb", GPU_dynamic_uniform(&wo->zenr, GPU_DYNAMIC_ZENITH_COLOR, NULL), &zen);
+               do_world_tex(&shi, wo, &hor, &zen, &blend);
+               if (wo->skytype & WO_SKYBLEND)
+                       GPU_link(mat, "node_mix_shader", blend, hor, zen, &shi.rgb);
+               else
+                       GPU_link(mat, "set_rgb", hor, &shi.rgb);
+               GPU_link(mat, "set_rgb", shi.rgb, &shr.combined);
+       }
+       GPU_material_output_link(mat, shr.combined);
+}
+
 GPUMaterial *GPU_material_world(struct Scene *scene, struct World *wo)
 {
        LinkData *link;
@@ -1832,7 +2024,7 @@ GPUMaterial *GPU_material_world(struct Scene *scene, struct World *wo)
        if (BKE_scene_use_new_shading_nodes(scene) && wo->nodetree && wo->use_nodes)
                ntreeGPUMaterialNodes(wo->nodetree, mat, NODE_NEW_SHADING);
        else {
-               /* old fixed function world */
+               GPU_material_old_world(mat, wo);
        }
 
        if (GPU_material_do_color_management(mat))
@@ -2424,6 +2616,7 @@ GPUShaderExport *GPU_shader_export(struct Scene *scene, struct Material *ma)
                                                break;
 
                                        case GPU_NONE:
+                                       case GPU_TEXCUBE:
                                        case GPU_FLOAT:
                                        case GPU_VEC2:
                                        case GPU_VEC3:
@@ -2459,6 +2652,7 @@ GPUShaderExport *GPU_shader_export(struct Scene *scene, struct Material *ma)
 
                                        case GPU_NONE:
                                        case GPU_TEX2D:
+                                       case GPU_TEXCUBE:
                                        case GPU_SHADOW2D:
                                        case GPU_ATTRIB:
                                                break;
index f410edb60b0790b770c116ea1153966e93812ce5..294b08f155a679cc74e6a73f52026852bdf862e9 100644 (file)
@@ -368,27 +368,33 @@ GPUTexture *GPU_texture_create_3D(int w, int h, int depth, int channels, const f
        return tex;
 }
 
-GPUTexture *GPU_texture_from_blender(Image *ima, ImageUser *iuser, bool is_data, double time, int mipmap)
+GPUTexture *GPU_texture_from_blender(Image *ima, ImageUser *iuser, int textarget, bool is_data, double time, int mipmap)
 {
-       GPU_update_image_time(ima, time);
+       int gputt;
        /* this binds a texture, so that's why to restore it to 0 */
-       GLint bindcode = GPU_verify_image(ima, iuser, 0, 0, mipmap, is_data);
+       GLint bindcode = GPU_verify_image(ima, iuser, textarget, 0, 0, mipmap, is_data);
+       GPU_update_image_time(ima, time);
 
-       if (ima->gputexture) {
-               ima->gputexture->bindcode = bindcode;
-               glBindTexture(GL_TEXTURE_2D, 0);
-               return ima->gputexture;
+       if (textarget == GL_TEXTURE_2D)
+               gputt = TEXTARGET_TEXTURE_2D;
+       else
+               gputt = TEXTARGET_TEXTURE_CUBE_MAP;
+
+       if (ima->gputexture[gputt]) {
+               ima->gputexture[gputt]->bindcode = bindcode;
+               glBindTexture(textarget, 0);
+               return ima->gputexture[gputt];
        }
 
        GPUTexture *tex = MEM_callocN(sizeof(GPUTexture), "GPUTexture");
        tex->bindcode = bindcode;
        tex->number = -1;
        tex->refcount = 1;
-       tex->target = GL_TEXTURE_2D;
+       tex->target = textarget;
        tex->target_base = GL_TEXTURE_2D;
        tex->fromblender = 1;
 
-       ima->gputexture = tex;
+       ima->gputexture[gputt] = tex;
 
        if (!glIsTexture(tex->bindcode)) {
                GPU_ASSERT_NO_GL_ERRORS("Blender Texture Not Loaded");
@@ -396,16 +402,23 @@ GPUTexture *GPU_texture_from_blender(Image *ima, ImageUser *iuser, bool is_data,
        else {
                GLint w, h, border;
 
-               glBindTexture(GL_TEXTURE_2D, tex->bindcode);
-               glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_WIDTH, &w);
-               glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_HEIGHT, &h);
-               glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_BORDER, &border);
+               GLenum gettarget;
+
+               if (textarget == GL_TEXTURE_2D)
+                       gettarget = GL_TEXTURE_2D;
+               else
+                       gettarget = GL_TEXTURE_CUBE_MAP_POSITIVE_X;
+
+               glBindTexture(textarget, tex->bindcode);
+               glGetTexLevelParameteriv(gettarget, 0, GL_TEXTURE_WIDTH, &w);
+               glGetTexLevelParameteriv(gettarget, 0, GL_TEXTURE_HEIGHT, &h);
+               glGetTexLevelParameteriv(gettarget, 0, GL_TEXTURE_BORDER, &border);
 
                tex->w = w - border;
                tex->h = h - border;
        }
 
-       glBindTexture(GL_TEXTURE_2D, 0);
+       glBindTexture(textarget, 0);
 
        return tex;
 }
@@ -420,7 +433,7 @@ GPUTexture *GPU_texture_from_preview(PreviewImage *prv, int mipmap)
        
        /* this binds a texture, so that's why we restore it to 0 */
        if (bindcode == 0) {
-               GPU_create_gl_tex(&bindcode, prv->rect[0], NULL, prv->w[0], prv->h[0], mipmap, 0, NULL);
+               GPU_create_gl_tex(&bindcode, prv->rect[0], NULL, prv->w[0], prv->h[0], GL_TEXTURE_2D, mipmap, 0, NULL);
        }
        if (tex) {
                tex->bindcode = bindcode;
@@ -641,6 +654,8 @@ void GPU_texture_unbind(GPUTexture *tex)
        GLenum arbnumber = (GLenum)((GLuint)GL_TEXTURE0 + tex->number);
        if (tex->number != 0) glActiveTexture(arbnumber);
        glBindTexture(tex->target, 0);
+       glDisable(tex->target);
+       glBindTexture(tex->target_base, 0);
        glDisable(tex->target_base);
        if (tex->number != 0) glActiveTexture(GL_TEXTURE0);
 
index e7072016cc01a29df3acd4c33a3d349a9c03a354..c8ce9f7a229d9b74cdae1f259a1647de4a0470c9 100644 (file)
@@ -1204,6 +1204,11 @@ void mtex_alpha_to_col(vec4 col, float alpha, out vec4 outcol)
        outcol = vec4(col.rgb, alpha);
 }
 
+void mtex_alpha_multiply_value(vec4 col, float value, out vec4 outcol)
+{
+    outcol = vec4(col.rgb, col.a * value);
+}
+
 void mtex_rgbtoint(vec4 rgb, out float intensity)
 {
        intensity = dot(vec3(0.35, 0.45, 0.2), rgb.rgb);
@@ -1253,6 +1258,12 @@ vec3 mtex_2d_mapping(vec3 vec)
        return vec3(vec.xy*0.5 + vec2(0.5), vec.z);
 }
 
+void mtex_cube_map(vec3 co, samplerCube ima, out float value, out vec4 color)
+{
+       color = textureCube(ima, co);
+       value = 1.0;
+}
+
 void mtex_image(vec3 texco, sampler2D ima, out float value, out vec4 color)
 {
        color = texture2D(ima, texco.xy);
@@ -1653,6 +1664,40 @@ void lamp_visibility_clamp(float visifac, out float outvisifac)
        outvisifac = (visifac < 0.001)? 0.0: visifac;
 }
 
+void world_paper_view(vec3 vec, out vec3 outvec)
+{
+       vec3 nvec = normalize(vec);
+       outvec = (gl_ProjectionMatrix[3][3] == 0.0) ? vec3(nvec.x, 0.0, nvec.y) : vec3(0.0, 0.0, -1.0);
+}
+
+void world_zen_mapping(vec3 view, float zenup, float zendown, out float zenfac)
+{
+       if (view.z >= 0.0)
+               zenfac = zenup;
+       else
+               zenfac = zendown;
+}
+
+void world_blend_paper_real(vec3 vec, out float blend)
+{
+       blend = abs(vec.y);
+}
+
+void world_blend_paper(vec3 vec, out float blend)
+{
+       blend = (vec.y + 1.0) * 0.5;
+}
+
+void world_blend_real(vec3 vec, out float blend)
+{
+       blend = abs(normalize(vec).z);
+}
+
+void world_blend(vec3 vec, out float blend)
+{
+       blend = (normalize(vec).z + 1) * 0.5;
+}
+
 void shade_view(vec3 co, out vec3 view)
 {
        /* handle perspective/orthographic */
index d48ce863338968b80f92ef7483f9bf5ccb95318a..b4bc26f45cd01e5fed2a473feb8986661d724715 100644 (file)
@@ -90,13 +90,19 @@ typedef struct RenderSlot {
 #define IMA_NEED_FRAME_RECALC  8
 #define IMA_SHOW_STEREO                16
 
+enum {
+       TEXTARGET_TEXTURE_2D = 0,
+       TEXTARGET_TEXTURE_CUBE_MAP = 1,
+       TEXTARGET_COUNT = 2
+};
+
 typedef struct Image {
        ID id;
        
        char name[1024];                        /* file path, 1024 = FILE_MAX */
        
        struct MovieCache *cache;       /* not written in file */
-       struct GPUTexture *gputexture;  /* not written in file */
+       struct GPUTexture *gputexture[2]; /* not written in file 2 = TEXTARGET_COUNT */
        
        /* sources from: */
        ListBase anims;
@@ -113,7 +119,8 @@ typedef struct Image {
        short tpageflag, totbind;
        short xrep, yrep;
        short twsta, twend;
-       unsigned int bindcode;  /* only for current image... */
+       unsigned int bindcode[2]; /* only for current image... 2 = TEXTARGET_COUNT */
+       char pad1[4];
        unsigned int *repbind;  /* for repeat of parts of images */
        
        struct PackedFile *packedfile DNA_DEPRECATED; /* deprecated */
index 23643f722d6722f92de519491f1fafe62b46c8f1..eb8dd5a63d4907ef8cf94ca1134481adcfe2517b 100644 (file)
@@ -224,7 +224,7 @@ static void rna_Image_scale(Image *image, ReportList *reports, int width, int he
 static int rna_Image_gl_load(Image *image, ReportList *reports, int frame, int filter, int mag)
 {
        ImBuf *ibuf;
-       unsigned int *bind = &image->bindcode;
+       unsigned int *bind = &image->bindcode[TEXTARGET_TEXTURE_2D];
        int error = GL_NO_ERROR;
        ImageUser iuser = {NULL};
        void *lock;
@@ -245,7 +245,7 @@ static int rna_Image_gl_load(Image *image, ReportList *reports, int frame, int f
                return (int)GL_INVALID_OPERATION;
        }
 
-       GPU_create_gl_tex(bind, ibuf->rect, ibuf->rect_float, ibuf->x, ibuf->y,
+       GPU_create_gl_tex(bind, ibuf->rect, ibuf->rect_float, GL_TEXTURE_2D, ibuf->x, ibuf->y,
                          (filter != GL_NEAREST && filter != GL_LINEAR), false, image);
 
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, (GLint)filter);
@@ -255,7 +255,7 @@ static int rna_Image_gl_load(Image *image, ReportList *reports, int frame, int f
 
        if (error) {
                glDeleteTextures(1, (GLuint *)bind);
-               image->bindcode = 0;
+               image->bindcode[TEXTARGET_TEXTURE_2D] = 0;
        }
 
        BKE_image_release_ibuf(image, ibuf, NULL);
@@ -265,7 +265,7 @@ static int rna_Image_gl_load(Image *image, ReportList *reports, int frame, int f
 
 static int rna_Image_gl_touch(Image *image, ReportList *reports, int frame, int filter, int mag)
 {
-       unsigned int *bind = &image->bindcode;
+       unsigned int *bind = &image->bindcode[TEXTARGET_TEXTURE_2D];
        int error = GL_NO_ERROR;
 
        BKE_image_tag_time(image);
index c6e47de8c9040567d4ff463cb75879993d57232a..66c1ddcc352d79d8cd7357dcc8d0bba6e35ebf1c 100644 (file)
@@ -128,6 +128,7 @@ static PyObject *PyInit_gpu(void)
        /* GPU_DYNAMIC_GROUP_WORLD */
        PY_MODULE_ADD_CONSTANT(m, GPU_DYNAMIC_HORIZON_COLOR);
        PY_MODULE_ADD_CONSTANT(m, GPU_DYNAMIC_AMBIENT_COLOR);
+       PY_MODULE_ADD_CONSTANT(m, GPU_DYNAMIC_ZENITH_COLOR);
        /* GPU_DYNAMIC_GROUP_MAT */
        PY_MODULE_ADD_CONSTANT(m, GPU_DYNAMIC_MAT_DIFFRGB);
        PY_MODULE_ADD_CONSTANT(m, GPU_DYNAMIC_MAT_REF);
index 0b0a0f5d4032c02b8db09e2a3a9a3e55d93abaaa..730e49c491885485e67489f63497e146b6504f08 100644 (file)
@@ -138,7 +138,7 @@ bool BL_Texture::InitFromImage(int unit,  Image *img, bool mipmap)
 
        mipmap = mipmap && GPU_get_mipmap();
 
-       mTexture = img->bindcode;
+       mTexture = img->bindcode[TEXTARGET_TEXTURE_2D];
        mType = GL_TEXTURE_2D;
        mUnit = unit;
 
index cc010f08b17bd5864f68103dadf6576f99f16949..f1c7bc303ee730296d62095b86663f6f744a5915 100644 (file)
@@ -299,7 +299,7 @@ PyObject *Texture_close(Texture * self)
                        self->m_matTexture->swapTexture(self->m_orgTex);
                else
                {
-                       self->m_imgTexture->bindcode = self->m_orgTex;
+                       self->m_imgTexture->bindcode[TEXTARGET_TEXTURE_2D] = self->m_orgTex;
                        BKE_image_release_ibuf(self->m_imgTexture, self->m_imgBuf, NULL);
                        self->m_imgBuf = NULL;
                }
@@ -357,8 +357,8 @@ static PyObject *Texture_refresh(Texture *self, PyObject *args)
                                                // WARNING: GPU has a ImageUser to pass, we don't. Using NULL
                                                // works on image file, not necessarily on other type of image.
                                                self->m_imgBuf = BKE_image_acquire_ibuf(self->m_imgTexture, NULL, NULL);
-                                               self->m_orgTex = self->m_imgTexture->bindcode;
-                                               self->m_imgTexture->bindcode = self->m_actTex;
+                                               self->m_orgTex = self->m_imgTexture->bindcode[TEXTARGET_TEXTURE_2D];
+                                               self->m_imgTexture->bindcode[TEXTARGET_TEXTURE_2D] = self->m_actTex;
                                        }
                                }