Fix issue after commit 50282: float texture painting non-color data textures did
authorBrecht Van Lommel <brechtvanlommel@pandora.be>
Thu, 25 Oct 2012 15:25:28 +0000 (15:25 +0000)
committerBrecht Van Lommel <brechtvanlommel@pandora.be>
Thu, 25 Oct 2012 15:25:28 +0000 (15:25 +0000)
not do correct partial updates, now it remembers if the opengl texture is a
non-color data texture or not and takes that into account for the update.

Also includes some renaming ncd => is_data for consistency with color space
terminology used elsewhere.

13 files changed:
source/blender/blenloader/intern/readfile.c
source/blender/gpu/GPU_draw.h
source/blender/gpu/GPU_extensions.h
source/blender/gpu/GPU_material.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/imbuf/IMB_imbuf.h
source/blender/imbuf/intern/divers.c
source/blender/makesdna/DNA_image_types.h
source/blender/nodes/shader/nodes/node_shader_tex_environment.c
source/blender/nodes/shader/nodes/node_shader_tex_image.c

index 9dc75ad..085424a 100644 (file)
@@ -1293,6 +1293,7 @@ void blo_end_image_pointer_map(FileData *fd, Main *oldmain)
                        if (NULL == newimaadr(fd, ibuf)) {      /* so was restored */
                                BLI_remlink(&ima->ibufs, ibuf);
                                ima->bindcode = 0;
+                               ima->tpageflag &= ~IMA_GLBIND_IS_DATA;
                                ima->gputexture = NULL;
                        }
                }
@@ -3025,6 +3026,7 @@ static void direct_link_image(FileData *fd, Image *ima)
        /* if not restored, we keep the binded opengl index */
        if (ima->ibufs.first == NULL) {
                ima->bindcode = 0;
+               ima->tpageflag &= ~IMA_GLBIND_IS_DATA;
                ima->gputexture = NULL;
        }
        
index 7d829bd..b26c255 100644 (file)
@@ -124,7 +124,7 @@ void GPU_set_gpu_mipmapping(int gpu_mipmap);
 void GPU_paint_update_image(struct Image *ima, 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, int compare, int mipmap, int ncd);
+int GPU_verify_image(struct Image *ima, struct ImageUser *iuser, int tftile, int compare, int mipmap, int isdata);
 void GPU_create_gl_tex(unsigned int *bind, unsigned int *pix, float *frect, int rectw, int recth, int mipmap, int 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);
 int GPU_upload_dxt_texture(struct ImBuf *ibuf);
index f4bb5da..7eaa408 100644 (file)
@@ -111,7 +111,7 @@ GPUTexture *GPU_texture_create_3D(int w, int h, int depth, int channels, float *
 GPUTexture *GPU_texture_create_depth(int w, int h, char err_out[256]);
 GPUTexture *GPU_texture_create_vsm_shadow_map(int size, char err_out[256]);
 GPUTexture *GPU_texture_from_blender(struct Image *ima,
-       struct ImageUser *iuser, int ncd, double time, int mipmap);
+       struct ImageUser *iuser, int isdata, double time, int mipmap);
 void GPU_texture_free(GPUTexture *tex);
 
 void GPU_texture_ref(GPUTexture *tex);
index baa557c..97e8b75 100644 (file)
@@ -107,7 +107,7 @@ typedef struct GPUNodeStack {
 GPUNodeLink *GPU_attribute(int type, const char *name);
 GPUNodeLink *GPU_uniform(float *num);
 GPUNodeLink *GPU_dynamic_uniform(float *num, int dynamictype, void *data);
-GPUNodeLink *GPU_image(struct Image *ima, struct ImageUser *iuser, int ncd);
+GPUNodeLink *GPU_image(struct Image *ima, struct ImageUser *iuser, int isdata);
 GPUNodeLink *GPU_texture(int size, float *pixels);
 GPUNodeLink *GPU_dynamic_texture(struct GPUTexture *tex, int dynamictype, void *data);
 GPUNodeLink *GPU_socket(GPUNodeStack *sock);
index 25990e8..b90e67a 100644 (file)
@@ -761,7 +761,7 @@ void GPU_pass_bind(GPUPass *pass, double time, int mipmap)
        /* now bind the textures */
        for (input=inputs->first; input; input=input->next) {
                if (input->ima)
-                       input->tex = GPU_texture_from_blender(input->ima, input->iuser, input->imagencd, time, mipmap);
+                       input->tex = GPU_texture_from_blender(input->ima, input->iuser, input->image_isdata, time, mipmap);
 
                if (input->tex && input->bindtex) {
                        GPU_texture_bind(input->tex, input->texid);
@@ -917,7 +917,7 @@ static void gpu_node_input_link(GPUNode *node, GPUNodeLink *link, int type)
 
                input->ima = link->ptr1;
                input->iuser = link->ptr2;
-               input->imagencd = link->imagencd;
+               input->image_isdata = link->image_isdata;
                input->textarget = GL_TEXTURE_2D;
                input->textype = GPU_TEX2D;
                MEM_freeN(link);
@@ -1110,14 +1110,14 @@ GPUNodeLink *GPU_dynamic_uniform(float *num, int dynamictype, void *data)
        return link;
 }
 
-GPUNodeLink *GPU_image(Image *ima, ImageUser *iuser, int ncd)
+GPUNodeLink *GPU_image(Image *ima, ImageUser *iuser, int isdata)
 {
        GPUNodeLink *link = GPU_node_link_create(0);
 
        link->image= 1;
        link->ptr1= ima;
        link->ptr2= iuser;
-       link->imagencd= ncd;
+       link->image_isdata= isdata;
 
        return link;
 }
index 42e8753..f61f349 100644 (file)
@@ -91,7 +91,7 @@ struct GPUNodeLink {
        const char *attribname;
 
        int image;
-       int imagencd;
+       int image_isdata;
 
        int texture;
        int texturesize;
@@ -138,7 +138,7 @@ typedef struct GPUInput {
 
        struct Image *ima;              /* image */
        struct ImageUser *iuser;/* image user */
-       int imagencd;                   /* image does not contain color data */
+       int image_isdata;               /* image does not contain color data */
        float *dynamicvec;              /* vector data in case it is dynamic */
        int dynamictype;                /* origin of the dynamic uniform (GPUDynamicType) */
        void *dynamicdata;              /* data source of the dynamic uniform */
index fd8dd56..b40e19e 100644 (file)
@@ -422,7 +422,7 @@ static void gpu_verify_reflection(Image *ima)
        }
 }
 
-int GPU_verify_image(Image *ima, ImageUser *iuser, int tftile, int compare, int mipmap, int ncd)
+int GPU_verify_image(Image *ima, ImageUser *iuser, int tftile, int compare, int mipmap, int is_data)
 {
        ImBuf *ibuf = NULL;
        unsigned int *bind = NULL;
@@ -492,7 +492,7 @@ int GPU_verify_image(Image *ima, ImageUser *iuser, int tftile, int compare, int
                }
 
                /* TODO unneeded when float images are correctly treated as linear always */
-               if (!ncd)
+               if (!is_data)
                        do_color_management = TRUE;
 
                if (ibuf->rect==NULL)
@@ -611,12 +611,21 @@ int GPU_verify_image(Image *ima, ImageUser *iuser, int tftile, int compare, int
                        rect= tilerect;
                }
        }
+
 #ifdef WITH_DDS
        if (ibuf->ftype & DDS)
                GPU_create_gl_tex_compressed(bind, rect, rectw, recth, mipmap, ima, ibuf);
        else
 #endif
                GPU_create_gl_tex(bind, rect, frect, rectw, recth, mipmap, use_high_bit_depth, ima);
+       
+       /* mark as non-color data texture */
+       if(*bind) {
+               if (is_data)
+                       ima->tpageflag |= IMA_GLBIND_IS_DATA;   
+               else
+                       ima->tpageflag &= ~IMA_GLBIND_IS_DATA;  
+       }
 
        /* clean up */
        if (tilerect)
@@ -908,7 +917,8 @@ void GPU_paint_update_image(Image *ima, int x, int y, int w, int h)
                /* if color correction is needed, we must update the part that needs updating. */
                if (ibuf->rect_float) {
                        float *buffer = MEM_mallocN(w*h*sizeof(float)*4, "temp_texpaint_float_buf");
-                       IMB_partial_rect_from_float(ibuf, buffer, x, y, w, h);
+                       int is_data = (ima->tpageflag & IMA_GLBIND_IS_DATA);
+                       IMB_partial_rect_from_float(ibuf, buffer, x, y, w, h, is_data);
 
                        glBindTexture(GL_TEXTURE_2D, ima->bindcode);
                        glTexSubImage2D(GL_TEXTURE_2D, 0, x, y, w, h, GL_RGBA,
@@ -934,12 +944,8 @@ void GPU_paint_update_image(Image *ima, int x, int y, int w, int h)
                glPixelStorei(GL_UNPACK_SKIP_PIXELS, x);
                glPixelStorei(GL_UNPACK_SKIP_ROWS, y);
 
-               if (ibuf->rect_float)
-                       glTexSubImage2D(GL_TEXTURE_2D, 0, x, y, w, h, GL_RGBA,
-                               GL_FLOAT, ibuf->rect_float);
-               else
-                       glTexSubImage2D(GL_TEXTURE_2D, 0, x, y, w, h, GL_RGBA,
-                               GL_UNSIGNED_BYTE, ibuf->rect);
+               glTexSubImage2D(GL_TEXTURE_2D, 0, x, y, w, h, GL_RGBA,
+                       GL_UNSIGNED_BYTE, ibuf->rect);
 
                glPixelStorei(GL_UNPACK_ROW_LENGTH, row_length);
                glPixelStorei(GL_UNPACK_SKIP_PIXELS, skip_pixels);
@@ -1135,7 +1141,7 @@ void GPU_free_image(Image *ima)
                ima->repbind= NULL;
        }
 
-       ima->tpageflag &= ~IMA_MIPMAP_COMPLETE;
+       ima->tpageflag &= ~(IMA_MIPMAP_COMPLETE|IMA_GLBIND_IS_DATA);
 }
 
 void GPU_free_images(void)
index 798868a..21d5482 100644 (file)
@@ -528,7 +528,7 @@ GPUTexture *GPU_texture_create_3D(int w, int h, int depth, int channels, float *
        return tex;
 }
 
-GPUTexture *GPU_texture_from_blender(Image *ima, ImageUser *iuser, int ncd, double time, int mipmap)
+GPUTexture *GPU_texture_from_blender(Image *ima, ImageUser *iuser, int isdata, double time, int mipmap)
 {
        GPUTexture *tex;
        GLint w, h, border, lastbindcode, bindcode;
@@ -536,7 +536,7 @@ GPUTexture *GPU_texture_from_blender(Image *ima, ImageUser *iuser, int ncd, doub
        glGetIntegerv(GL_TEXTURE_BINDING_2D, &lastbindcode);
 
        GPU_update_image_time(ima, time);
-       bindcode = GPU_verify_image(ima, iuser, 0, 0, mipmap, ncd);
+       bindcode = GPU_verify_image(ima, iuser, 0, 0, mipmap, isdata);
 
        if (ima->gputexture) {
                ima->gputexture->bindcode = bindcode;
index 28dbe11..e297ebe 100644 (file)
@@ -371,7 +371,7 @@ void IMB_interlace(struct ImBuf *ibuf);
 void IMB_rect_from_float(struct ImBuf *ibuf);
 /* Create char buffer for part of the image, color corrected if necessary,
  * Changed part will be stored in buffer. This is expected to be used for texture painting updates */
-void IMB_partial_rect_from_float(struct ImBuf *ibuf, float *buffer, int x, int y, int w, int h);
+void IMB_partial_rect_from_float(struct ImBuf *ibuf, float *buffer, int x, int y, int w, int h, int is_data);
 void IMB_float_from_rect(struct ImBuf *ibuf);
 void IMB_float_from_rect_simple(struct ImBuf *ibuf); /* no profile conversion */
 /* note, check that the conversion exists, only some are supported */
index 95b085d..55c1b02 100644 (file)
@@ -561,7 +561,7 @@ void IMB_rect_from_float(ImBuf *ibuf)
 }
 
 /* converts from linear float to sRGB byte for part of the texture, buffer will hold the changed part */
-void IMB_partial_rect_from_float(ImBuf *ibuf, float *buffer, int x, int y, int w, int h)
+void IMB_partial_rect_from_float(ImBuf *ibuf, float *buffer, int x, int y, int w, int h, int is_data)
 {
        float *rect_float;
        uchar *rect_byte;
@@ -580,14 +580,27 @@ void IMB_partial_rect_from_float(ImBuf *ibuf, float *buffer, int x, int y, int w
        rect_float = ibuf->rect_float + (x + y * ibuf->x) * ibuf->channels;
        rect_byte = (uchar *)ibuf->rect + (x + y * ibuf->x) * 4;
 
-       IMB_buffer_float_from_float(buffer, rect_float,
-                                   ibuf->channels, IB_PROFILE_SRGB, profile_from, predivide,
-                                   w, h, w, ibuf->x);
+       if (is_data) {
+               /* exception for non-color data, just copy float */
+               IMB_buffer_float_from_float(buffer, rect_float,
+                                                                       ibuf->channels, IB_PROFILE_LINEAR_RGB, IB_PROFILE_LINEAR_RGB, 0,
+                                                                       w, h, w, ibuf->x);
 
-       /* XXX: need to convert to image buffer's rect space */
-       IMB_buffer_byte_from_float(rect_byte, buffer,
-                                  4, ibuf->dither, IB_PROFILE_SRGB, IB_PROFILE_SRGB, 0,
-                                  w, h, ibuf->x, w);
+               /* and do color space conversion to byte */
+               IMB_buffer_byte_from_float(rect_byte, rect_float,
+                                                                  4, ibuf->dither, IB_PROFILE_SRGB, profile_from, predivide,
+                                                                  w, h, ibuf->x, w);
+       }
+       else {
+               IMB_buffer_float_from_float(buffer, rect_float,
+                                                                       ibuf->channels, IB_PROFILE_SRGB, profile_from, predivide,
+                                                                       w, h, w, ibuf->x);
+
+               /* XXX: need to convert to image buffer's rect space */
+               IMB_buffer_byte_from_float(rect_byte, buffer,
+                                                                  4, ibuf->dither, IB_PROFILE_SRGB, IB_PROFILE_SRGB, 0,
+                                                                  w, h, ibuf->x, w);
+       }
 
        /* ensure user flag is reset */
        ibuf->userflags &= ~IB_RECT_INVALID;
index 38058db..fe35503 100644 (file)
@@ -137,6 +137,7 @@ typedef struct Image {
 #define IMA_CLAMP_U                    16 
 #define IMA_CLAMP_V                    32
 #define IMA_TPAGE_REFRESH      64
+#define IMA_GLBIND_IS_DATA     128 /* opengl image texture bound as non-color data */
 
 /* ima->type and ima->source moved to BKE_image.h, for API */
 
index 08a3b47..30bfe17 100644 (file)
@@ -61,7 +61,7 @@ static int node_shader_gpu_tex_environment(GPUMaterial *mat, bNode *node, GPUNod
        Image *ima= (Image*)node->id;
        ImageUser *iuser= NULL;
        NodeTexImage *tex = node->storage;
-       int ncd = tex->color_space == SHD_COLORSPACE_NONE;
+       int isdata = tex->color_space == SHD_COLORSPACE_NONE;
        int ret;
 
        if (!ima)
@@ -72,7 +72,7 @@ static int node_shader_gpu_tex_environment(GPUMaterial *mat, bNode *node, GPUNod
 
        node_shader_gpu_tex_mapping(mat, node, in, out);
 
-       ret = GPU_stack_link(mat, "node_tex_environment", in, out, GPU_image(ima, iuser, ncd));
+       ret = GPU_stack_link(mat, "node_tex_environment", in, out, GPU_image(ima, iuser, isdata));
 
        if (ret) {
                ImBuf *ibuf = BKE_image_get_ibuf(ima, iuser);
index 82d4e50..9b17f76 100644 (file)
@@ -61,7 +61,7 @@ static int node_shader_gpu_tex_image(GPUMaterial *mat, bNode *node, GPUNodeStack
        Image *ima= (Image*)node->id;
        ImageUser *iuser= NULL;
        NodeTexImage *tex = node->storage;
-       int ncd = tex->color_space == SHD_COLORSPACE_NONE;
+       int isdata = tex->color_space == SHD_COLORSPACE_NONE;
        int ret;
 
        if (!ima)
@@ -72,7 +72,7 @@ static int node_shader_gpu_tex_image(GPUMaterial *mat, bNode *node, GPUNodeStack
 
        node_shader_gpu_tex_mapping(mat, node, in, out);
 
-       ret = GPU_stack_link(mat, "node_tex_image", in, out, GPU_image(ima, iuser, ncd));
+       ret = GPU_stack_link(mat, "node_tex_image", in, out, GPU_image(ima, iuser, isdata));
 
        if (ret) {
                ImBuf *ibuf = BKE_image_get_ibuf(ima, iuser);