Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexander Romanov <a.romanov@blend4web.com>2016-01-27 12:06:57 +0300
committerAlexander Romanov <a.romanov@blend4web.com>2016-01-27 12:06:57 +0300
commit771f73b6bedbdd1c1e2993bd8d3680d53fa67b7c (patch)
tree1e1593c722640fc00a1755d1acd3a4263ff396b0
parentf6ff8f27e35d7b9596bbb2c55c3cf464f6e6ffc0 (diff)
World textures displaying for viewport in BI.
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
-rw-r--r--source/blender/blenkernel/BKE_image.h3
-rw-r--r--source/blender/blenkernel/intern/image.c12
-rw-r--r--source/blender/blenloader/intern/readfile.c20
-rw-r--r--source/blender/editors/space_view3d/drawmesh.c10
-rw-r--r--source/blender/editors/space_view3d/view3d_draw.c4
-rw-r--r--source/blender/gpu/GPU_draw.h12
-rw-r--r--source/blender/gpu/GPU_extensions.h1
-rw-r--r--source/blender/gpu/GPU_material.h3
-rw-r--r--source/blender/gpu/GPU_texture.h2
-rw-r--r--source/blender/gpu/intern/gpu_codegen.c40
-rw-r--r--source/blender/gpu/intern/gpu_codegen.h3
-rw-r--r--source/blender/gpu/intern/gpu_draw.c329
-rw-r--r--source/blender/gpu/intern/gpu_extensions.c7
-rw-r--r--source/blender/gpu/intern/gpu_material.c196
-rw-r--r--source/blender/gpu/intern/gpu_texture.c45
-rw-r--r--source/blender/gpu/shaders/gpu_shader_material.glsl45
-rw-r--r--source/blender/makesdna/DNA_image_types.h11
-rw-r--r--source/blender/makesrna/intern/rna_image_api.c8
-rw-r--r--source/blender/python/intern/gpu.c1
-rw-r--r--source/gameengine/Ketsji/BL_Texture.cpp2
-rw-r--r--source/gameengine/VideoTexture/Texture.cpp6
21 files changed, 619 insertions, 141 deletions
diff --git a/source/blender/blenkernel/BKE_image.h b/source/blender/blenkernel/BKE_image.h
index 1d4a405a89c..aec5b0afa45 100644
--- a/source/blender/blenkernel/BKE_image.h
+++ b/source/blender/blenkernel/BKE_image.h
@@ -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);
diff --git a/source/blender/blenkernel/intern/image.c b/source/blender/blenkernel/intern/image.c
index 7c40674dd6c..d48b455ae81 100644
--- a/source/blender/blenkernel/intern/image.c
+++ b/source/blender/blenkernel/intern/image.c
@@ -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;
diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c
index 8899af1d755..b8470b16e14 100644
--- a/source/blender/blenloader/intern/readfile.c
+++ b/source/blender/blenloader/intern/readfile.c
@@ -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;
}
diff --git a/source/blender/editors/space_view3d/drawmesh.c b/source/blender/editors/space_view3d/drawmesh.c
index 8deabfb31ab..11ba6fb709b 100644
--- a/source/blender/editors/space_view3d/drawmesh.c
+++ b/source/blender/editors/space_view3d/drawmesh.c
@@ -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);
diff --git a/source/blender/editors/space_view3d/view3d_draw.c b/source/blender/editors/space_view3d/view3d_draw.c
index c37d90b1878..adffcb63293 100644
--- a/source/blender/editors/space_view3d/view3d_draw.c
+++ b/source/blender/editors/space_view3d/view3d_draw.c
@@ -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);
diff --git a/source/blender/gpu/GPU_draw.h b/source/blender/gpu/GPU_draw.h
index afb1cbcf71d..75d6362f13e 100644
--- a/source/blender/gpu/GPU_draw.h
+++ b/source/blender/gpu/GPU_draw.h
@@ -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);
diff --git a/source/blender/gpu/GPU_extensions.h b/source/blender/gpu/GPU_extensions.h
index 64167e94933..4a728c881b6 100644
--- a/source/blender/gpu/GPU_extensions.h
+++ b/source/blender/gpu/GPU_extensions.h
@@ -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]);
diff --git a/source/blender/gpu/GPU_material.h b/source/blender/gpu/GPU_material.h
index 65cdf834533..3bcc7e23f06 100644
--- a/source/blender/gpu/GPU_material.h
+++ b/source/blender/gpu/GPU_material.h
@@ -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);
diff --git a/source/blender/gpu/GPU_texture.h b/source/blender/gpu/GPU_texture.h
index 4166aaf293d..efa98f7ca2a 100644
--- a/source/blender/gpu/GPU_texture.h
+++ b/source/blender/gpu/GPU_texture.h
@@ -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);
diff --git a/source/blender/gpu/intern/gpu_codegen.c b/source/blender/gpu/intern/gpu_codegen.c
index fb46b167f0f..c3f79bc9492 100644
--- a/source/blender/gpu/intern/gpu_codegen.c
+++ b/source/blender/gpu/intern/gpu_codegen.c
@@ -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();
diff --git a/source/blender/gpu/intern/gpu_codegen.h b/source/blender/gpu/intern/gpu_codegen.h
index 5aa187014ba..75102658c88 100644
--- a/source/blender/gpu/intern/gpu_codegen.h
+++ b/source/blender/gpu/intern/gpu_codegen.h
@@ -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 {
diff --git a/source/blender/gpu/intern/gpu_draw.c b/source/blender/gpu/intern/gpu_draw.c
index a7f802a4502..be5235b77bb 100644
--- a/source/blender/gpu/intern/gpu_draw.c
+++ b/source/blender/gpu/intern/gpu_draw.c
@@ -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;
}
diff --git a/source/blender/gpu/intern/gpu_extensions.c b/source/blender/gpu/intern/gpu_extensions.c
index a53c55b6016..fd660d2e97c 100644
--- a/source/blender/gpu/intern/gpu_extensions.c
+++ b/source/blender/gpu/intern/gpu_extensions.c
@@ -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);
diff --git a/source/blender/gpu/intern/gpu_material.c b/source/blender/gpu/intern/gpu_material.c
index 81f04f0ef22..09d326e2ee8 100644
--- a/source/blender/gpu/intern/gpu_material.c
+++ b/source/blender/gpu/intern/gpu_material.c
@@ -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;
diff --git a/source/blender/gpu/intern/gpu_texture.c b/source/blender/gpu/intern/gpu_texture.c
index f410edb60b0..294b08f155a 100644
--- a/source/blender/gpu/intern/gpu_texture.c
+++ b/source/blender/gpu/intern/gpu_texture.c
@@ -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);
diff --git a/source/blender/gpu/shaders/gpu_shader_material.glsl b/source/blender/gpu/shaders/gpu_shader_material.glsl
index e7072016cc0..c8ce9f7a229 100644
--- a/source/blender/gpu/shaders/gpu_shader_material.glsl
+++ b/source/blender/gpu/shaders/gpu_shader_material.glsl
@@ -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 */
diff --git a/source/blender/makesdna/DNA_image_types.h b/source/blender/makesdna/DNA_image_types.h
index d48ce863338..b4bc26f45cd 100644
--- a/source/blender/makesdna/DNA_image_types.h
+++ b/source/blender/makesdna/DNA_image_types.h
@@ -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 */
diff --git a/source/blender/makesrna/intern/rna_image_api.c b/source/blender/makesrna/intern/rna_image_api.c
index 23643f722d6..eb8dd5a63d4 100644
--- a/source/blender/makesrna/intern/rna_image_api.c
+++ b/source/blender/makesrna/intern/rna_image_api.c
@@ -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);
diff --git a/source/blender/python/intern/gpu.c b/source/blender/python/intern/gpu.c
index c6e47de8c90..66c1ddcc352 100644
--- a/source/blender/python/intern/gpu.c
+++ b/source/blender/python/intern/gpu.c
@@ -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);
diff --git a/source/gameengine/Ketsji/BL_Texture.cpp b/source/gameengine/Ketsji/BL_Texture.cpp
index 0b0a0f5d403..730e49c4918 100644
--- a/source/gameengine/Ketsji/BL_Texture.cpp
+++ b/source/gameengine/Ketsji/BL_Texture.cpp
@@ -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;
diff --git a/source/gameengine/VideoTexture/Texture.cpp b/source/gameengine/VideoTexture/Texture.cpp
index cc010f08b17..f1c7bc303ee 100644
--- a/source/gameengine/VideoTexture/Texture.cpp
+++ b/source/gameengine/VideoTexture/Texture.cpp
@@ -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;
}
}