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:
parent
e0a4ca00ac
commit
85d9ba5cbb
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 */
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue