Fix issue after commit 50282: float texture painting non-color data textures did

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.
This commit is contained in:
Brecht Van Lommel 2012-10-25 15:25:28 +00:00
parent e0a4ca00ac
commit 85d9ba5cbb
13 changed files with 56 additions and 34 deletions

View 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;
}

View 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);

View 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);

View 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);

View 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;
}

View 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 */

View 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)

View 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;

View 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 */

View 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;

View 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 */

View 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);

View 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);