BlenderWorldInfo::BlenderWorldInfo(struct Scene *blenderscene, struct World *blenderworld) { if (blenderworld) { m_hasworld = true; // do we have mist? if ((blenderworld->mode) & WO_MIST) { m_hasmist = true; m_miststart = blenderworld->miststa; m_mistdistance = blenderworld->mistdist; copy_v3_v3(m_mistcolor, &blenderworld->horr); } else { m_hasmist = false; m_miststart = 0.0; m_mistdistance = 0.0; zero_v3(m_mistcolor); } copy_v3_v3(m_backgroundcolor, &blenderworld->horr); copy_v3_v3(m_ambientcolor, &blenderworld->ambr); if (BKE_scene_check_color_management_enabled(blenderscene)) { linearrgb_to_srgb_v3_v3(m_mistcolor, m_mistcolor); linearrgb_to_srgb_v3_v3(m_backgroundcolor, m_backgroundcolor); linearrgb_to_srgb_v3_v3(m_ambientcolor, m_ambientcolor); } } else { m_hasworld = false; } }
MINLINE void linearrgb_to_srgb_uchar3(unsigned char srgb[3], const float linear[3]) { float srgb_f[3]; linearrgb_to_srgb_v3_v3(srgb_f, linear); F3TOCHAR3(srgb_f, srgb); }
void paint_get_tex_pixel_col(MTex *mtex, float u, float v, float rgba[4], struct ImagePool *pool, int thread, bool convert_to_linear, struct ColorSpace *colorspace) { float co[3] = {u, v, 0.0f}; int hasrgb; float intensity; hasrgb = externtex(mtex, co, &intensity, rgba, rgba + 1, rgba + 2, rgba + 3, thread, pool); if (!hasrgb) { rgba[0] = intensity; rgba[1] = intensity; rgba[2] = intensity; rgba[3] = 1.0f; } if (convert_to_linear) IMB_colormanagement_colorspace_to_scene_linear_v3(rgba, colorspace); linearrgb_to_srgb_v3_v3(rgba, rgba); CLAMP(rgba[0], 0.0f, 1.0f); CLAMP(rgba[1], 0.0f, 1.0f); CLAMP(rgba[2], 0.0f, 1.0f); CLAMP(rgba[3], 0.0f, 1.0f); }
/* matching ED_space_image_color_sample() */ int ED_space_node_color_sample(SpaceNode *snode, ARegion *ar, int mval[2], float r_col[3]) { void *lock; Image *ima; ImBuf *ibuf; float fx, fy, bufx, bufy; int ret = FALSE; if (STREQ(snode->tree_idname, ntreeType_Composite->idname) || (snode->flag & SNODE_BACKDRAW) == 0) { /* use viewer image for color sampling only if we're in compositor tree * with backdrop enabled */ return FALSE; } ima = BKE_image_verify_viewer(IMA_TYPE_COMPOSITE, "Viewer Node"); ibuf = BKE_image_acquire_ibuf(ima, NULL, &lock); if (!ibuf) { return FALSE; } /* map the mouse coords to the backdrop image space */ bufx = ibuf->x * snode->zoom; bufy = ibuf->y * snode->zoom; fx = (bufx > 0.0f ? ((float)mval[0] - 0.5f * ar->winx - snode->xof) / bufx + 0.5f : 0.0f); fy = (bufy > 0.0f ? ((float)mval[1] - 0.5f * ar->winy - snode->yof) / bufy + 0.5f : 0.0f); if (fx >= 0.0f && fy >= 0.0f && fx < 1.0f && fy < 1.0f) { float *fp; unsigned char *cp; int x = (int)(fx * ibuf->x), y = (int)(fy * ibuf->y); CLAMP(x, 0, ibuf->x - 1); CLAMP(y, 0, ibuf->y - 1); if (ibuf->rect_float) { fp = (ibuf->rect_float + (ibuf->channels) * (y * ibuf->x + x)); /* IB_PROFILE_NONE is default but infact its linear */ linearrgb_to_srgb_v3_v3(r_col, fp); ret = TRUE; } else if (ibuf->rect) { cp = (unsigned char *)(ibuf->rect + y * ibuf->x + x); rgb_uchar_to_float(r_col, cp); ret = TRUE; } } BKE_image_release_ibuf(ima, ibuf, lock); return ret; }
void KX_WorldInfo::setAmbientColor(float r, float g, float b) { m_ambientcolor[0] = r; m_ambientcolor[1] = g; m_ambientcolor[2] = b; if (m_do_color_management) { linearrgb_to_srgb_v3_v3(m_con_ambientcolor, m_ambientcolor); } else { copy_v3_v3(m_con_ambientcolor, m_ambientcolor); } }
void KX_WorldInfo::setBackColor(float r, float g, float b) { m_backgroundcolor[0] = r; m_backgroundcolor[1] = g; m_backgroundcolor[2] = b; if (m_do_color_management) { linearrgb_to_srgb_v3_v3(m_con_backgroundcolor, m_backgroundcolor); } else { copy_v3_v3(m_con_backgroundcolor, m_backgroundcolor); } }
BlenderWorldInfo::BlenderWorldInfo(struct Scene *blenderscene, struct World* blenderworld) { if (blenderworld) { m_hasworld = true; // do we have mist? if ((blenderworld->mode) & WO_MIST) { m_hasmist = true; m_miststart = blenderworld->miststa; m_mistdistance = blenderworld->mistdist; copy_v3_v3(m_mistcolor, &blenderworld->horr); } else { m_hasmist = false; m_miststart = 0.0; m_mistdistance = 0.0; zero_v3(m_mistcolor); } copy_v3_v3(m_backgroundcolor, &blenderworld->horr); copy_v3_v3(m_ambientcolor, &blenderworld->ambr); /* OCIO TODO */ if(blenderscene->r.color_mgt_flag & R_COLOR_MANAGEMENT) { linearrgb_to_srgb_v3_v3(m_mistcolor, m_mistcolor); linearrgb_to_srgb_v3_v3(m_backgroundcolor, m_backgroundcolor); linearrgb_to_srgb_v3_v3(m_ambientcolor, m_ambientcolor); } } else { m_hasworld = false; } }
static DMDrawOption draw_tface__set_draw_legacy(MTexPoly *mtexpoly, const bool has_mcol, int matnr) { Material *ma = give_current_material(Gtexdraw.ob, matnr + 1); bool invalidtexture = false; if (ma && (ma->game.flag & GEMAT_INVISIBLE)) return DM_DRAW_OPTION_SKIP; invalidtexture = set_draw_settings_cached(0, mtexpoly, ma, Gtexdraw); if (mtexpoly && invalidtexture) { glColor3ub(0xFF, 0x00, 0xFF); return DM_DRAW_OPTION_NO_MCOL; /* Don't set color */ } else if (!has_mcol) { if (mtexpoly) { glColor3f(1.0, 1.0, 1.0); } else { if (ma) { if (ma->shade_flag & MA_OBCOLOR) { glColor3ubv(Gtexdraw.obcol); } else { float col[3]; if (Gtexdraw.color_profile) linearrgb_to_srgb_v3_v3(col, &ma->r); else copy_v3_v3(col, &ma->r); glColor3fv(col); } } else { glColor3f(1.0, 1.0, 1.0); } } return DM_DRAW_OPTION_NORMAL; /* normal drawing (no mcols anyway, no need to turn off) */ } else { return DM_DRAW_OPTION_NORMAL; /* Set color from mcol */ } }
/* matching ED_space_image_color_sample() */ bool ED_space_clip_color_sample(SpaceClip *sc, ARegion *ar, int mval[2], float r_col[3]) { ImBuf *ibuf; float fx, fy, co[2]; bool ret = false; ibuf = ED_space_clip_get_buffer(sc); if (!ibuf) { return false; } /* map the mouse coords to the backdrop image space */ ED_clip_mouse_pos(sc, ar, mval, co); fx = co[0]; fy = co[1]; if (fx >= 0.0f && fy >= 0.0f && fx < 1.0f && fy < 1.0f) { float *fp; unsigned char *cp; int x = (int)(fx * ibuf->x), y = (int)(fy * ibuf->y); CLAMP(x, 0, ibuf->x - 1); CLAMP(y, 0, ibuf->y - 1); if (ibuf->rect_float) { fp = (ibuf->rect_float + (ibuf->channels) * (y * ibuf->x + x)); linearrgb_to_srgb_v3_v3(r_col, fp); ret = true; } else if (ibuf->rect) { cp = (unsigned char *)(ibuf->rect + y * ibuf->x + x); rgb_uchar_to_float(r_col, cp); ret = true; } } return ret; }
MINLINE void linearrgb_to_srgb_v4(float srgb[4], const float linear[4]) { linearrgb_to_srgb_v3_v3(srgb, linear); srgb[3] = linear[3]; }
/* float to byte pixels, output 4-channel RGBA */ void IMB_buffer_byte_from_float(uchar *rect_to, const float *rect_from, int channels_from, float dither, int profile_to, int profile_from, bool predivide, int width, int height, int stride_to, int stride_from) { float tmp[4]; int x, y; DitherContext *di = NULL; float inv_width = 1.0f / width; float inv_height = 1.0f / height; /* we need valid profiles */ BLI_assert(profile_to != IB_PROFILE_NONE); BLI_assert(profile_from != IB_PROFILE_NONE); if (dither) { di = create_dither_context(dither); } for (y = 0; y < height; y++) { float t = y * inv_height; if (channels_from == 1) { /* single channel input */ const float *from = rect_from + ((size_t)stride_from) * y; uchar *to = rect_to + ((size_t)stride_to) * y * 4; for (x = 0; x < width; x++, from++, to += 4) { to[0] = to[1] = to[2] = to[3] = unit_float_to_uchar_clamp(from[0]); } } else if (channels_from == 3) { /* RGB input */ const float *from = rect_from + ((size_t)stride_from) * y * 3; uchar *to = rect_to + ((size_t)stride_to) * y * 4; if (profile_to == profile_from) { /* no color space conversion */ for (x = 0; x < width; x++, from += 3, to += 4) { rgb_float_to_uchar(to, from); to[3] = 255; } } else if (profile_to == IB_PROFILE_SRGB) { /* convert from linear to sRGB */ for (x = 0; x < width; x++, from += 3, to += 4) { linearrgb_to_srgb_v3_v3(tmp, from); rgb_float_to_uchar(to, tmp); to[3] = 255; } } else if (profile_to == IB_PROFILE_LINEAR_RGB) { /* convert from sRGB to linear */ for (x = 0; x < width; x++, from += 3, to += 4) { srgb_to_linearrgb_v3_v3(tmp, from); rgb_float_to_uchar(to, tmp); to[3] = 255; } } } else if (channels_from == 4) { /* RGBA input */ const float *from = rect_from + ((size_t)stride_from) * y * 4; uchar *to = rect_to + ((size_t)stride_to) * y * 4; if (profile_to == profile_from) { float straight[4]; /* no color space conversion */ if (dither && predivide) { for (x = 0; x < width; x++, from += 4, to += 4) { premul_to_straight_v4_v4(straight, from); float_to_byte_dither_v4(to, straight, di, (float)x * inv_width, t); } } else if (dither) { for (x = 0; x < width; x++, from += 4, to += 4) { float_to_byte_dither_v4(to, from, di, (float)x * inv_width, t); } } else if (predivide) { for (x = 0; x < width; x++, from += 4, to += 4) { premul_to_straight_v4_v4(straight, from); rgba_float_to_uchar(to, straight); } } else { for (x = 0; x < width; x++, from += 4, to += 4) { rgba_float_to_uchar(to, from); } } } else if (profile_to == IB_PROFILE_SRGB) { /* convert from linear to sRGB */ unsigned short us[4]; float straight[4]; if (dither && predivide) { for (x = 0; x < width; x++, from += 4, to += 4) { premul_to_straight_v4_v4(straight, from); linearrgb_to_srgb_ushort4(us, from); ushort_to_byte_dither_v4(to, us, di, (float)x * inv_width, t); } } else if (dither) { for (x = 0; x < width; x++, from += 4, to += 4) { linearrgb_to_srgb_ushort4(us, from); ushort_to_byte_dither_v4(to, us, di, (float)x * inv_width, t); } } else if (predivide) { for (x = 0; x < width; x++, from += 4, to += 4) { premul_to_straight_v4_v4(straight, from); linearrgb_to_srgb_ushort4(us, from); ushort_to_byte_v4(to, us); } } else { for (x = 0; x < width; x++, from += 4, to += 4) { linearrgb_to_srgb_ushort4(us, from); ushort_to_byte_v4(to, us); } } } else if (profile_to == IB_PROFILE_LINEAR_RGB) { /* convert from sRGB to linear */ if (dither && predivide) { for (x = 0; x < width; x++, from += 4, to += 4) { srgb_to_linearrgb_predivide_v4(tmp, from); float_to_byte_dither_v4(to, tmp, di, (float)x * inv_width, t); } } else if (dither) { for (x = 0; x < width; x++, from += 4, to += 4) { srgb_to_linearrgb_v4(tmp, from); float_to_byte_dither_v4(to, tmp, di, (float)x * inv_width, t); } } else if (predivide) { for (x = 0; x < width; x++, from += 4, to += 4) { srgb_to_linearrgb_predivide_v4(tmp, from); rgba_float_to_uchar(to, tmp); } } else { for (x = 0; x < width; x++, from += 4, to += 4) { srgb_to_linearrgb_v4(tmp, from); rgba_float_to_uchar(to, tmp); } } } } } if (dither) { clear_dither_context(di); } }
/* float to float pixels, output 4-channel RGBA */ void IMB_buffer_float_from_float(float *rect_to, const float *rect_from, int channels_from, int profile_to, int profile_from, bool predivide, int width, int height, int stride_to, int stride_from) { int x, y; /* we need valid profiles */ BLI_assert(profile_to != IB_PROFILE_NONE); BLI_assert(profile_from != IB_PROFILE_NONE); if (channels_from == 1) { /* single channel input */ for (y = 0; y < height; y++) { const float *from = rect_from + ((size_t)stride_from) * y; float *to = rect_to + ((size_t)stride_to) * y * 4; for (x = 0; x < width; x++, from++, to += 4) { to[0] = to[1] = to[2] = to[3] = from[0]; } } } else if (channels_from == 3) { /* RGB input */ for (y = 0; y < height; y++) { const float *from = rect_from + ((size_t)stride_from) * y * 3; float *to = rect_to + ((size_t)stride_to) * y * 4; if (profile_to == profile_from) { /* no color space conversion */ for (x = 0; x < width; x++, from += 3, to += 4) { copy_v3_v3(to, from); to[3] = 1.0f; } } else if (profile_to == IB_PROFILE_LINEAR_RGB) { /* convert from sRGB to linear */ for (x = 0; x < width; x++, from += 3, to += 4) { srgb_to_linearrgb_v3_v3(to, from); to[3] = 1.0f; } } else if (profile_to == IB_PROFILE_SRGB) { /* convert from linear to sRGB */ for (x = 0; x < width; x++, from += 3, to += 4) { linearrgb_to_srgb_v3_v3(to, from); to[3] = 1.0f; } } } } else if (channels_from == 4) { /* RGBA input */ for (y = 0; y < height; y++) { const float *from = rect_from + ((size_t)stride_from) * y * 4; float *to = rect_to + ((size_t)stride_to) * y * 4; if (profile_to == profile_from) { /* same profile, copy */ memcpy(to, from, sizeof(float) * ((size_t)4) * width); } else if (profile_to == IB_PROFILE_LINEAR_RGB) { /* convert to sRGB to linear */ if (predivide) { for (x = 0; x < width; x++, from += 4, to += 4) { srgb_to_linearrgb_predivide_v4(to, from); } } else { for (x = 0; x < width; x++, from += 4, to += 4) { srgb_to_linearrgb_v4(to, from); } } } else if (profile_to == IB_PROFILE_SRGB) { /* convert from linear to sRGB */ if (predivide) { for (x = 0; x < width; x++, from += 4, to += 4) { linearrgb_to_srgb_predivide_v4(to, from); } } else { for (x = 0; x < width; x++, from += 4, to += 4) { linearrgb_to_srgb_v4(to, from); } } } } } }
int imb_savetiff(ImBuf *ibuf, const char *name, int flags) { TIFF *image = NULL; uint16 samplesperpixel, bitspersample; size_t npixels; unsigned char *pixels = NULL; unsigned char *from = NULL, *to = NULL; unsigned short *pixels16 = NULL, *to16 = NULL; float *fromf = NULL; float xres, yres; int x, y, from_i, to_i, i; /* check for a valid number of bytes per pixel. Like the PNG writer, * the TIFF writer supports 1, 3 or 4 bytes per pixel, corresponding * to gray, RGB, RGBA respectively. */ samplesperpixel = (uint16)((ibuf->planes + 7) >> 3); if ((samplesperpixel > 4) || (samplesperpixel == 2)) { fprintf(stderr, "imb_savetiff: unsupported number of bytes per " "pixel: %d\n", samplesperpixel); return (0); } if ((ibuf->ftype & TIF_16BIT) && ibuf->rect_float) bitspersample = 16; else bitspersample = 8; /* open TIFF file for writing */ if (flags & IB_mem) { /* bork at the creation of a TIFF in memory */ fprintf(stderr, "imb_savetiff: creation of in-memory TIFF files is " "not yet supported.\n"); return (0); } else { /* create image as a file */ #ifdef WIN32 wchar_t *wname = alloc_utf16_from_8(name, 0); image = TIFFOpenW(wname, "w"); free(wname); #else image = TIFFOpen(name, "w"); #endif } if (image == NULL) { fprintf(stderr, "imb_savetiff: could not open TIFF for writing.\n"); return (0); } /* allocate array for pixel data */ npixels = ibuf->x * ibuf->y; if (bitspersample == 16) pixels16 = (unsigned short *)_TIFFmalloc(npixels * samplesperpixel * sizeof(unsigned short)); else pixels = (unsigned char *)_TIFFmalloc(npixels * samplesperpixel * sizeof(unsigned char)); if (pixels == NULL && pixels16 == NULL) { fprintf(stderr, "imb_savetiff: could not allocate pixels array.\n"); TIFFClose(image); return (0); } /* setup pointers */ if (bitspersample == 16) { fromf = ibuf->rect_float; to16 = pixels16; } else { from = (unsigned char *)ibuf->rect; to = pixels; } /* setup samples per pixel */ TIFFSetField(image, TIFFTAG_BITSPERSAMPLE, bitspersample); TIFFSetField(image, TIFFTAG_SAMPLESPERPIXEL, samplesperpixel); if (samplesperpixel == 4) { unsigned short extraSampleTypes[1]; if (bitspersample == 16) extraSampleTypes[0] = EXTRASAMPLE_ASSOCALPHA; else extraSampleTypes[0] = EXTRASAMPLE_UNASSALPHA; /* RGBA images */ TIFFSetField(image, TIFFTAG_EXTRASAMPLES, 1, extraSampleTypes); TIFFSetField(image, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_RGB); } else if (samplesperpixel == 3) { /* RGB images */ TIFFSetField(image, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_RGB); } else if (samplesperpixel == 1) { /* grayscale images, 1 channel */ TIFFSetField(image, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_MINISBLACK); } /* copy pixel data. While copying, we flip the image vertically. */ for (x = 0; x < ibuf->x; x++) { for (y = 0; y < ibuf->y; y++) { from_i = 4 * (y * ibuf->x + x); to_i = samplesperpixel * ((ibuf->y - y - 1) * ibuf->x + x); if (pixels16) { /* convert from float source */ float rgb[4]; if (ibuf->float_colorspace) { /* float buffer was managed already, no need in color space conversion */ copy_v3_v3(rgb, &fromf[from_i]); } else { /* standard linear-to-srgb conversion if float buffer wasn't managed */ linearrgb_to_srgb_v3_v3(rgb, &fromf[from_i]); } rgb[3] = fromf[from_i + 3]; for (i = 0; i < samplesperpixel; i++, to_i++) to16[to_i] = FTOUSHORT(rgb[i]); } else { for (i = 0; i < samplesperpixel; i++, to_i++, from_i++) to[to_i] = from[from_i]; } } } /* write the actual TIFF file */ TIFFSetField(image, TIFFTAG_IMAGEWIDTH, ibuf->x); TIFFSetField(image, TIFFTAG_IMAGELENGTH, ibuf->y); TIFFSetField(image, TIFFTAG_ROWSPERSTRIP, ibuf->y); TIFFSetField(image, TIFFTAG_COMPRESSION, COMPRESSION_DEFLATE); TIFFSetField(image, TIFFTAG_FILLORDER, FILLORDER_MSB2LSB); TIFFSetField(image, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG); if (ibuf->ppm[0] > 0.0 && ibuf->ppm[1] > 0.0) { xres = (float)(ibuf->ppm[0] * 0.0254); yres = (float)(ibuf->ppm[1] * 0.0254); } else { xres = yres = IMB_DPI_DEFAULT; } TIFFSetField(image, TIFFTAG_XRESOLUTION, xres); TIFFSetField(image, TIFFTAG_YRESOLUTION, yres); TIFFSetField(image, TIFFTAG_RESOLUTIONUNIT, RESUNIT_INCH); if (TIFFWriteEncodedStrip(image, 0, (bitspersample == 16) ? (unsigned char *)pixels16 : pixels, ibuf->x * ibuf->y * samplesperpixel * bitspersample / 8) == -1) { fprintf(stderr, "imb_savetiff: Could not write encoded TIFF.\n"); TIFFClose(image); if (pixels) _TIFFfree(pixels); if (pixels16) _TIFFfree(pixels16); return (1); } /* close the TIFF file */ TIFFClose(image); if (pixels) _TIFFfree(pixels); if (pixels16) _TIFFfree(pixels16); return (1); }
static void fill_bins(bNode* node, CompBuf* in, int* bins, int colorcor) { float value[4]; int ivalue=0; int x,y; /*fill bins */ for(y=0; y<in->y; y++) { for(x=0; x<in->x; x++) { /* get the pixel */ qd_getPixel(in, x, y, value); if(value[3] > 0.0) { /* don't count transparent pixels */ switch(node->custom1) { case 1: { /* all colors */ if(colorcor) linearrgb_to_srgb_v3_v3(&value[0],&value[0]); rgb_tobw(value[0],value[1],value[2], &value[0]); value[0]=value[0]*255; /* scale to 0-255 range */ ivalue=(int)value[0]; break; } case 2: { /* red channel */ if(colorcor) value[0]=linearrgb_to_srgb(value[0]); value[0]=value[0]*255; /* scale to 0-255 range */ ivalue=(int)value[0]; break; } case 3: { /* green channel */ if(colorcor) value[1]=linearrgb_to_srgb(value[1]); value[1]=value[1]*255; /* scale to 0-255 range */ ivalue=(int)value[1]; break; } case 4: /*blue channel */ { if(colorcor) value[2]=linearrgb_to_srgb(value[2]); value[2]=value[2]*255; /* scale to 0-255 range */ ivalue=(int)value[2]; break; } case 5: /* luminence */ { if(colorcor) linearrgb_to_srgb_v3_v3(&value[0],&value[0]); rgb_to_yuv(value[0],value[1],value[2], &value[0], &value[1], &value[2]); value[0]=value[0]*255; /* scale to 0-255 range */ ivalue=(int)value[0]; break; } } /*end switch */ /*clip*/ if(ivalue<0) ivalue=0; if(ivalue>255) ivalue=255; /*put in the correct bin*/ bins[ivalue]+=1; } /*end if alpha */ } } }
static void bake_shade(void *handle, Object *ob, ShadeInput *shi, int UNUSED(quad), int x, int y, float UNUSED(u), float UNUSED(v), float *tvn, float *ttang) { BakeShade *bs = handle; ShadeSample *ssamp = &bs->ssamp; ShadeResult shr; VlakRen *vlr = shi->vlr; shade_input_init_material(shi); if (bs->type == RE_BAKE_AO) { ambient_occlusion(shi); if (R.r.bake_flag & R_BAKE_NORMALIZE) { copy_v3_v3(shr.combined, shi->ao); } else { zero_v3(shr.combined); environment_lighting_apply(shi, &shr); } } else { if (bs->type == RE_BAKE_SHADOW) /* Why do shadows set the color anyhow?, ignore material color for baking */ shi->r = shi->g = shi->b = 1.0f; shade_input_set_shade_texco(shi); /* only do AO for a full bake (and obviously AO bakes) * AO for light bakes is a leftover and might not be needed */ if (ELEM3(bs->type, RE_BAKE_ALL, RE_BAKE_AO, RE_BAKE_LIGHT)) shade_samples_do_AO(ssamp); if (shi->mat->nodetree && shi->mat->use_nodes) { ntreeShaderExecTree(shi->mat->nodetree, shi, &shr); shi->mat = vlr->mat; /* shi->mat is being set in nodetree */ } else shade_material_loop(shi, &shr); if (bs->type == RE_BAKE_NORMALS) { float nor[3]; copy_v3_v3(nor, shi->vn); if (R.r.bake_normal_space == R_BAKE_SPACE_CAMERA) { /* pass */ } else if (R.r.bake_normal_space == R_BAKE_SPACE_TANGENT) { float mat[3][3], imat[3][3]; /* bitangent */ if (tvn && ttang) { copy_v3_v3(mat[0], ttang); cross_v3_v3v3(mat[1], tvn, ttang); mul_v3_fl(mat[1], ttang[3]); copy_v3_v3(mat[2], tvn); } else { copy_v3_v3(mat[0], shi->nmaptang); cross_v3_v3v3(mat[1], shi->nmapnorm, shi->nmaptang); mul_v3_fl(mat[1], shi->nmaptang[3]); copy_v3_v3(mat[2], shi->nmapnorm); } invert_m3_m3(imat, mat); mul_m3_v3(imat, nor); } else if (R.r.bake_normal_space == R_BAKE_SPACE_OBJECT) mul_mat3_m4_v3(ob->imat_ren, nor); /* ob->imat_ren includes viewinv! */ else if (R.r.bake_normal_space == R_BAKE_SPACE_WORLD) mul_mat3_m4_v3(R.viewinv, nor); normalize_v3(nor); /* in case object has scaling */ /* The invert of the red channel is to make * the normal map compliant with the outside world. * It needs to be done because in Blender * the normal used in the renderer points inward. It is generated * this way in calc_vertexnormals(). Should this ever change * this negate must be removed. */ shr.combined[0] = (-nor[0]) / 2.0f + 0.5f; shr.combined[1] = nor[1] / 2.0f + 0.5f; shr.combined[2] = nor[2] / 2.0f + 0.5f; } else if (bs->type == RE_BAKE_TEXTURE) { copy_v3_v3(shr.combined, &shi->r); shr.alpha = shi->alpha; } else if (bs->type == RE_BAKE_SHADOW) { copy_v3_v3(shr.combined, shr.shad); shr.alpha = shi->alpha; } else if (bs->type == RE_BAKE_SPEC_COLOR) { copy_v3_v3(shr.combined, &shi->specr); shr.alpha = 1.0f; } else if (bs->type == RE_BAKE_SPEC_INTENSITY) { copy_v3_fl(shr.combined, shi->spec); shr.alpha = 1.0f; } else if (bs->type == RE_BAKE_MIRROR_COLOR) { copy_v3_v3(shr.combined, &shi->mirr); shr.alpha = 1.0f; } else if (bs->type == RE_BAKE_MIRROR_INTENSITY) { copy_v3_fl(shr.combined, shi->ray_mirror); shr.alpha = 1.0f; } else if (bs->type == RE_BAKE_ALPHA) { copy_v3_fl(shr.combined, shi->alpha); shr.alpha = 1.0f; } else if (bs->type == RE_BAKE_EMIT) { copy_v3_fl(shr.combined, shi->emit); shr.alpha = 1.0f; } else if (bs->type == RE_BAKE_VERTEX_COLORS) { copy_v3_v3(shr.combined, shi->vcol); shr.alpha = shi->vcol[3]; } } if (bs->rect_float && !bs->vcol) { float *col = bs->rect_float + 4 * (bs->rectx * y + x); copy_v3_v3(col, shr.combined); if (bs->type == RE_BAKE_ALL || bs->type == RE_BAKE_TEXTURE || bs->type == RE_BAKE_VERTEX_COLORS) { col[3] = shr.alpha; } else { col[3] = 1.0; } } else { /* Target is char (LDR). */ unsigned char col[4]; if (ELEM(bs->type, RE_BAKE_ALL, RE_BAKE_TEXTURE)) { float rgb[3]; copy_v3_v3(rgb, shr.combined); if (R.scene_color_manage) { /* Vertex colors have no way to specify color space, so they * default to sRGB. */ if (!bs->vcol) IMB_colormanagement_scene_linear_to_colorspace_v3(rgb, bs->rect_colorspace); else linearrgb_to_srgb_v3_v3(rgb, rgb); } rgb_float_to_uchar(col, rgb); } else { rgb_float_to_uchar(col, shr.combined); } if (ELEM3(bs->type, RE_BAKE_ALL, RE_BAKE_TEXTURE, RE_BAKE_VERTEX_COLORS)) { col[3] = FTOCHAR(shr.alpha); } else { col[3] = 255; } if (bs->vcol) { /* Vertex color baking. Vcol has no useful alpha channel (it exists * but is used only for vertex painting). */ bs->vcol->r = col[0]; bs->vcol->g = col[1]; bs->vcol->b = col[2]; } else { unsigned char *imcol = (unsigned char *)(bs->rect + bs->rectx * y + x); copy_v4_v4_char((char *)imcol, (char *)col); } } if (bs->rect_mask) { bs->rect_mask[bs->rectx * y + x] = FILTER_MASK_USED; } if (bs->do_update) { *bs->do_update = true; } }
/* update rectangular section of the brush image */ static void brush_painter_imbuf_update(BrushPainter *painter, ImBuf *oldtexibuf, int origx, int origy, int w, int h, int xt, int yt) { Scene *scene = painter->scene; Brush *brush = painter->brush; rctf tex_mapping = painter->tex_mapping; rctf mask_mapping = painter->mask_mapping; struct ImagePool *pool = painter->pool; bool use_masking = painter->cache.use_masking; bool use_color_correction = painter->cache.use_color_correction; bool use_float = painter->cache.use_float; bool is_texbrush = painter->cache.is_texbrush; bool is_maskbrush = painter->cache.is_maskbrush; bool use_texture_old = (oldtexibuf != NULL); int x, y, thread = 0; float brush_rgb[3]; ImBuf *ibuf = painter->cache.ibuf; ImBuf *texibuf = painter->cache.texibuf; unsigned short *mask = painter->cache.mask; /* get brush color */ if (brush->imagepaint_tool == PAINT_TOOL_DRAW) { copy_v3_v3(brush_rgb, brush->rgb); if (use_color_correction) srgb_to_linearrgb_v3_v3(brush_rgb, brush_rgb); } else { brush_rgb[0] = 1.0f; brush_rgb[1] = 1.0f; brush_rgb[2] = 1.0f; } /* fill pixes */ for (y = origy; y < h; y++) { for (x = origx; x < w; x++) { /* sample texture and multiply with brush color */ float texco[3], rgba[4]; if (!use_texture_old) { if (is_texbrush) { brush_imbuf_tex_co(&tex_mapping, x, y, texco); BKE_brush_sample_tex_3D(scene, brush, texco, rgba, thread, pool); /* TODO(sergey): Support texture paint color space. */ if (!use_float) { linearrgb_to_srgb_v3_v3(rgba, rgba); } mul_v3_v3(rgba, brush_rgb); } else { copy_v3_v3(rgba, brush_rgb); rgba[3] = 1.0f; } if (is_maskbrush) { brush_imbuf_tex_co(&mask_mapping, x, y, texco); rgba[3] *= BKE_brush_sample_masktex(scene, brush, texco, thread, pool); } } if (use_float) { /* handle float pixel */ float *bf = ibuf->rect_float + (y * ibuf->x + x) * 4; float *tf = texibuf->rect_float + (y * texibuf->x + x) * 4; /* read from old texture buffer */ if (use_texture_old) { float *otf = oldtexibuf->rect_float + ((y - origy + yt) * oldtexibuf->x + (x - origx + xt)) * 4; copy_v4_v4(rgba, otf); } /* write to new texture buffer */ copy_v4_v4(tf, rgba); /* if not using masking, multiply in the mask now */ if (!use_masking) { unsigned short *m = mask + (y * ibuf->x + x); rgba[3] *= *m * (1.0f / 65535.0f); } /* output premultiplied float image, mf was already premultiplied */ mul_v3_v3fl(bf, rgba, rgba[3]); bf[3] = rgba[3]; } else { unsigned char crgba[4]; /* handle byte pixel */ unsigned char *b = (unsigned char *)ibuf->rect + (y * ibuf->x + x) * 4; unsigned char *t = (unsigned char *)texibuf->rect + (y * texibuf->x + x) * 4; /* read from old texture buffer */ if (use_texture_old) { unsigned char *ot = (unsigned char *)oldtexibuf->rect + ((y - origy + yt) * oldtexibuf->x + (x - origx + xt)) * 4; crgba[0] = ot[0]; crgba[1] = ot[1]; crgba[2] = ot[2]; crgba[3] = ot[3]; } else rgba_float_to_uchar(crgba, rgba); /* write to new texture buffer */ t[0] = crgba[0]; t[1] = crgba[1]; t[2] = crgba[2]; t[3] = crgba[3]; /* if not using masking, multiply in the mask now */ if (!use_masking) { unsigned short *m = mask + (y * ibuf->x + x); crgba[3] = (crgba[3] * (*m)) / 65535; } /* write to brush image buffer */ b[0] = crgba[0]; b[1] = crgba[1]; b[2] = crgba[2]; b[3] = crgba[3]; } } } }
/* converts from linear float to sRGB byte for part of the texture, buffer will hold the changed part */ void IMB_partial_rect_from_float(struct ImBuf *ibuf,float *buffer, int x, int y, int w, int h) { /* indices to source and destination image pixels */ float *srcFloatPxl; unsigned char *dstBytePxl; /* buffer index will fill buffer */ float *bufferIndex; /* convenience pointers to start of image buffers */ float *init_srcFloatPxl = (float *)ibuf->rect_float; unsigned char *init_dstBytePxl = (unsigned char *) ibuf->rect; /* Dithering factor */ float dither= ibuf->dither / 255.0f; /* respective attributes of image */ short profile= ibuf->profile; int channels= ibuf->channels; int i, j; /* if called -only- from GPU_paint_update_image this test will never fail but leaving it here for better or worse */ if(init_srcFloatPxl==NULL || (buffer == NULL)){ return; } if(init_dstBytePxl==NULL) { imb_addrectImBuf(ibuf); init_dstBytePxl = (unsigned char *) ibuf->rect; } if(channels==1) { for (j = 0; j < h; j++){ bufferIndex = buffer + w*j*4; dstBytePxl = init_dstBytePxl + (ibuf->x*(y + j) + x)*4; srcFloatPxl = init_srcFloatPxl + (ibuf->x*(y + j) + x); for(i = 0; i < w; i++, dstBytePxl+=4, srcFloatPxl++, bufferIndex+=4) { dstBytePxl[1]= dstBytePxl[2]= dstBytePxl[3]= dstBytePxl[0] = FTOCHAR(srcFloatPxl[0]); bufferIndex[0] = bufferIndex[1] = bufferIndex[2] = bufferIndex[3] = srcFloatPxl[0]; } } } else if (profile == IB_PROFILE_LINEAR_RGB) { if(channels == 3) { for (j = 0; j < h; j++){ bufferIndex = buffer + w*j*4; dstBytePxl = init_dstBytePxl + (ibuf->x*(y + j) + x)*4; srcFloatPxl = init_srcFloatPxl + (ibuf->x*(y + j) + x)*3; for(i = 0; i < w; i++, dstBytePxl+=4, srcFloatPxl+=3, bufferIndex += 4) { linearrgb_to_srgb_v3_v3(bufferIndex, srcFloatPxl); F3TOCHAR4(bufferIndex, dstBytePxl); bufferIndex[3]= 1.0; } } } else if (channels == 4) { if (dither != 0.f) { for (j = 0; j < h; j++){ bufferIndex = buffer + w*j*4; dstBytePxl = init_dstBytePxl + (ibuf->x*(y + j) + x)*4; srcFloatPxl = init_srcFloatPxl + (ibuf->x*(y + j) + x)*4; for(i = 0; i < w; i++, dstBytePxl+=4, srcFloatPxl+=4, bufferIndex+=4) { const float d = (BLI_frand()-0.5f)*dither; linearrgb_to_srgb_v3_v3(bufferIndex, srcFloatPxl); bufferIndex[3] = srcFloatPxl[3]; add_v4_fl(bufferIndex, d); F4TOCHAR4(bufferIndex, dstBytePxl); } } } else { for (j = 0; j < h; j++){ bufferIndex = buffer + w*j*4; dstBytePxl = init_dstBytePxl + (ibuf->x*(y + j) + x)*4; srcFloatPxl = init_srcFloatPxl + (ibuf->x*(y + j) + x)*4; for(i = 0; i < w; i++, dstBytePxl+=4, srcFloatPxl+=4, bufferIndex+=4) { linearrgb_to_srgb_v3_v3(bufferIndex, srcFloatPxl); bufferIndex[3]= srcFloatPxl[3]; F4TOCHAR4(bufferIndex, dstBytePxl); } } } } } else if(ELEM(profile, IB_PROFILE_NONE, IB_PROFILE_SRGB)) { if(channels==3) { for (j = 0; j < h; j++){ bufferIndex = buffer + w*j*4; dstBytePxl = init_dstBytePxl + (ibuf->x*(y + j) + x)*4; srcFloatPxl = init_srcFloatPxl + (ibuf->x*(y + j) + x)*3; for(i = 0; i < w; i++, dstBytePxl+=4, srcFloatPxl+=3, bufferIndex+=4) { copy_v3_v3(bufferIndex, srcFloatPxl); F3TOCHAR4(bufferIndex, dstBytePxl); bufferIndex[3] = 1.0; } } } else { if (dither != 0.f) { for (j = 0; j < h; j++){ bufferIndex = buffer + w*j*4; dstBytePxl = init_dstBytePxl + (ibuf->x*(y + j) + x)*4; srcFloatPxl = init_srcFloatPxl + (ibuf->x*(y + j) + x)*4; for(i = 0; i < w; i++, dstBytePxl+=4, srcFloatPxl+=4, bufferIndex+=4) { const float d = (BLI_frand()-0.5f)*dither; copy_v4_v4(bufferIndex, srcFloatPxl); add_v4_fl(bufferIndex,d); F4TOCHAR4(bufferIndex, dstBytePxl); } } } else { for (j = 0; j < h; j++){ bufferIndex = buffer + w*j*4; dstBytePxl = init_dstBytePxl + (ibuf->x*(y + j) + x)*4; srcFloatPxl = init_srcFloatPxl + (ibuf->x*(y + j) + x)*4; for(i = 0; i < w; i++, dstBytePxl+=4, srcFloatPxl+=4, bufferIndex+=4) { copy_v4_v4(bufferIndex, srcFloatPxl); F4TOCHAR4(bufferIndex, dstBytePxl); } } } } } /* ensure user flag is reset */ ibuf->userflags &= ~IB_RECT_INVALID; }
/* used for both 3d view and image window */ void paint_sample_color(bContext *C, ARegion *ar, int x, int y, bool texpaint_proj, bool use_palette) { Scene *scene = CTX_data_scene(C); Paint *paint = BKE_paint_get_active_from_context(C); Palette *palette = BKE_paint_palette(paint); PaletteColor *color; Brush *br = BKE_paint_brush(BKE_paint_get_active_from_context(C)); unsigned int col; const unsigned char *cp; CLAMP(x, 0, ar->winx); CLAMP(y, 0, ar->winy); if (use_palette) { if (!palette) { palette = BKE_palette_add(CTX_data_main(C), "Palette"); BKE_paint_palette_set(paint, palette); } color = BKE_palette_color_add(palette); } if (CTX_wm_view3d(C) && texpaint_proj) { /* first try getting a colour directly from the mesh faces if possible */ Object *ob = OBACT; bool sample_success = false; if (ob) { DerivedMesh *dm = mesh_get_derived_final(scene, ob, CD_MASK_BAREMESH); ViewContext vc; const int mval[2] = {x, y}; unsigned int faceindex; unsigned int totface = dm->getNumTessFaces(dm); MTFace *dm_mtface = dm->getTessFaceDataArray(dm, CD_MTFACE); DM_update_materials(dm, ob); if (dm_mtface) { view3d_set_viewcontext(C, &vc); view3d_operator_needs_opengl(C); if (imapaint_pick_face(&vc, mval, &faceindex, totface)) { Image *image = imapaint_face_image(dm, faceindex); ImBuf *ibuf = BKE_image_acquire_ibuf(image, NULL, NULL); if (ibuf && ibuf->rect) { float uv[2]; float u, v; imapaint_pick_uv(scene, ob, faceindex, mval, uv); sample_success = true; u = fmodf(uv[0], 1.0f); v = fmodf(uv[1], 1.0f); if (u < 0.0f) u += 1.0f; if (v < 0.0f) v += 1.0f; u = u * ibuf->x - 0.5f; v = v * ibuf->y - 0.5f; if (ibuf->rect_float) { float rgba_f[4]; bilinear_interpolation_color_wrap(ibuf, NULL, rgba_f, u, v); straight_to_premul_v4(rgba_f); if (use_palette) { linearrgb_to_srgb_v3_v3(color->rgb, rgba_f); } else { linearrgb_to_srgb_v3_v3(rgba_f, rgba_f); BKE_brush_color_set(scene, br, rgba_f); } } else { unsigned char rgba[4]; bilinear_interpolation_color_wrap(ibuf, rgba, NULL, u, v); if (use_palette) { rgb_uchar_to_float(color->rgb, rgba); } else { float rgba_f[3]; rgb_uchar_to_float(rgba_f, rgba); BKE_brush_color_set(scene, br, rgba_f); } } } BKE_image_release_ibuf(image, ibuf, NULL); } } dm->release(dm); } if (!sample_success) { glReadBuffer(GL_FRONT); glReadPixels(x + ar->winrct.xmin, y + ar->winrct.ymin, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, &col); glReadBuffer(GL_BACK); } else return; } else { glReadBuffer(GL_FRONT); glReadPixels(x + ar->winrct.xmin, y + ar->winrct.ymin, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, &col); glReadBuffer(GL_BACK); } cp = (unsigned char *)&col; if (use_palette) { rgb_uchar_to_float(color->rgb, cp); } else { float rgba_f[3]; rgb_uchar_to_float(rgba_f, cp); BKE_brush_color_set(scene, br, rgba_f); } }
void ui_draw_but_CURVE(ARegion *ar, uiBut *but, uiWidgetColors *wcol, rcti *rect) { CurveMapping *cumap; CurveMap *cuma; CurveMapPoint *cmp; float fx, fy, fac[2], zoomx, zoomy, offsx, offsy; GLint scissor[4]; rcti scissor_new; int a; if (but->editcumap) { cumap = but->editcumap; } else { cumap = (CurveMapping *)but->poin; } cuma = &cumap->cm[cumap->cur]; /* need scissor test, curve can draw outside of boundary */ glGetIntegerv(GL_VIEWPORT, scissor); scissor_new.xmin = ar->winrct.xmin + rect->xmin; scissor_new.ymin = ar->winrct.ymin + rect->ymin; scissor_new.xmax = ar->winrct.xmin + rect->xmax; scissor_new.ymax = ar->winrct.ymin + rect->ymax; BLI_rcti_isect(&scissor_new, &ar->winrct, &scissor_new); glScissor(scissor_new.xmin, scissor_new.ymin, BLI_rcti_size_x(&scissor_new), BLI_rcti_size_y(&scissor_new)); /* calculate offset and zoom */ zoomx = (BLI_rcti_size_x(rect) - 2.0f * but->aspect) / BLI_rctf_size_x(&cumap->curr); zoomy = (BLI_rcti_size_y(rect) - 2.0f * but->aspect) / BLI_rctf_size_y(&cumap->curr); offsx = cumap->curr.xmin - but->aspect / zoomx; offsy = cumap->curr.ymin - but->aspect / zoomy; /* backdrop */ if (but->a1 == UI_GRAD_H) { /* magic trigger for curve backgrounds */ rcti grid; float col[3] = {0.0f, 0.0f, 0.0f}; /* dummy arg */ grid.xmin = rect->xmin + zoomx * (-offsx); grid.xmax = rect->xmax + zoomx * (-offsx); grid.ymin = rect->ymin + zoomy * (-offsy); grid.ymax = rect->ymax + zoomy * (-offsy); ui_draw_gradient(&grid, col, UI_GRAD_H, 1.0f); /* grid, hsv uses different grid */ glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glColor4ub(0, 0, 0, 48); ui_draw_but_curve_grid(rect, zoomx, zoomy, offsx, offsy, 0.1666666f); glDisable(GL_BLEND); } else { if (cumap->flag & CUMA_DO_CLIP) { gl_shaded_color((unsigned char *)wcol->inner, -20); glRectf(rect->xmin, rect->ymin, rect->xmax, rect->ymax); glColor3ubv((unsigned char *)wcol->inner); glRectf(rect->xmin + zoomx * (cumap->clipr.xmin - offsx), rect->ymin + zoomy * (cumap->clipr.ymin - offsy), rect->xmin + zoomx * (cumap->clipr.xmax - offsx), rect->ymin + zoomy * (cumap->clipr.ymax - offsy)); } else { glColor3ubv((unsigned char *)wcol->inner); glRectf(rect->xmin, rect->ymin, rect->xmax, rect->ymax); } /* grid, every 0.25 step */ gl_shaded_color((unsigned char *)wcol->inner, -16); ui_draw_but_curve_grid(rect, zoomx, zoomy, offsx, offsy, 0.25f); /* grid, every 1.0 step */ gl_shaded_color((unsigned char *)wcol->inner, -24); ui_draw_but_curve_grid(rect, zoomx, zoomy, offsx, offsy, 1.0f); /* axes */ gl_shaded_color((unsigned char *)wcol->inner, -50); glBegin(GL_LINES); glVertex2f(rect->xmin, rect->ymin + zoomy * (-offsy)); glVertex2f(rect->xmax, rect->ymin + zoomy * (-offsy)); glVertex2f(rect->xmin + zoomx * (-offsx), rect->ymin); glVertex2f(rect->xmin + zoomx * (-offsx), rect->ymax); glEnd(); } /* cfra option */ /* XXX 2.48 */ #if 0 if (cumap->flag & CUMA_DRAW_CFRA) { glColor3ub(0x60, 0xc0, 0x40); glBegin(GL_LINES); glVertex2f(rect->xmin + zoomx * (cumap->sample[0] - offsx), rect->ymin); glVertex2f(rect->xmin + zoomx * (cumap->sample[0] - offsx), rect->ymax); glEnd(); } #endif /* sample option */ if (cumap->flag & CUMA_DRAW_SAMPLE) { if (but->a1 == UI_GRAD_H) { float tsample[3]; float hsv[3]; linearrgb_to_srgb_v3_v3(tsample, cumap->sample); rgb_to_hsv_v(tsample, hsv); glColor3ub(240, 240, 240); glBegin(GL_LINES); glVertex2f(rect->xmin + zoomx * (hsv[0] - offsx), rect->ymin); glVertex2f(rect->xmin + zoomx * (hsv[0] - offsx), rect->ymax); glEnd(); } else if (cumap->cur == 3) { float lum = rgb_to_bw(cumap->sample); glColor3ub(240, 240, 240); glBegin(GL_LINES); glVertex2f(rect->xmin + zoomx * (lum - offsx), rect->ymin); glVertex2f(rect->xmin + zoomx * (lum - offsx), rect->ymax); glEnd(); } else { if (cumap->cur == 0) glColor3ub(240, 100, 100); else if (cumap->cur == 1) glColor3ub(100, 240, 100); else glColor3ub(100, 100, 240); glBegin(GL_LINES); glVertex2f(rect->xmin + zoomx * (cumap->sample[cumap->cur] - offsx), rect->ymin); glVertex2f(rect->xmin + zoomx * (cumap->sample[cumap->cur] - offsx), rect->ymax); glEnd(); } } /* the curve */ glColor3ubv((unsigned char *)wcol->item); glEnable(GL_LINE_SMOOTH); glEnable(GL_BLEND); glBegin(GL_LINE_STRIP); if (cuma->table == NULL) curvemapping_changed(cumap, FALSE); cmp = cuma->table; /* first point */ if ((cuma->flag & CUMA_EXTEND_EXTRAPOLATE) == 0) { glVertex2f(rect->xmin, rect->ymin + zoomy * (cmp[0].y - offsy)); } else { fx = rect->xmin + zoomx * (cmp[0].x - offsx + cuma->ext_in[0]); fy = rect->ymin + zoomy * (cmp[0].y - offsy + cuma->ext_in[1]); glVertex2f(fx, fy); } for (a = 0; a <= CM_TABLE; a++) { fx = rect->xmin + zoomx * (cmp[a].x - offsx); fy = rect->ymin + zoomy * (cmp[a].y - offsy); glVertex2f(fx, fy); } /* last point */ if ((cuma->flag & CUMA_EXTEND_EXTRAPOLATE) == 0) { glVertex2f(rect->xmax, rect->ymin + zoomy * (cmp[CM_TABLE].y - offsy)); } else { fx = rect->xmin + zoomx * (cmp[CM_TABLE].x - offsx - cuma->ext_out[0]); fy = rect->ymin + zoomy * (cmp[CM_TABLE].y - offsy - cuma->ext_out[1]); glVertex2f(fx, fy); } glEnd(); glDisable(GL_LINE_SMOOTH); glDisable(GL_BLEND); /* the points, use aspect to make them visible on edges */ cmp = cuma->curve; glPointSize(3.0f); bglBegin(GL_POINTS); for (a = 0; a < cuma->totpoint; a++) { if (cmp[a].flag & CUMA_SELECT) UI_ThemeColor(TH_TEXT_HI); else UI_ThemeColor(TH_TEXT); fac[0] = rect->xmin + zoomx * (cmp[a].x - offsx); fac[1] = rect->ymin + zoomy * (cmp[a].y - offsy); bglVertex2fv(fac); } bglEnd(); glPointSize(1.0f); /* restore scissortest */ glScissor(scissor[0], scissor[1], scissor[2], scissor[3]); /* outline */ glColor3ubv((unsigned char *)wcol->outline); fdrawbox(rect->xmin, rect->ymin, rect->xmax, rect->ymax); }
void draw_image_info(ARegion *ar, int color_manage, int channels, int x, int y, char *cp, float *fp, int *zp, float *zpf) { char str[256]; float dx= 6; /* text colors */ /* XXX colored text not allowed in Blender UI */ #if 0 unsigned char red[3] = {255, 50, 50}; unsigned char green[3] = {0, 255, 0}; unsigned char blue[3] = {100, 100, 255}; #else unsigned char red[3] = {255, 255, 255}; unsigned char green[3] = {255, 255, 255}; unsigned char blue[3] = {255, 255, 255}; #endif float hue=0, sat=0, val=0, lum=0, u=0, v=0; float col[4], finalcol[4]; glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA); glEnable(GL_BLEND); /* noisy, high contrast make impossible to read if lower alpha is used. */ glColor4ub(0, 0, 0, 190); glRecti(0.0, 0.0, ar->winrct.xmax - ar->winrct.xmin + 1, 20); glDisable(GL_BLEND); BLF_size(blf_mono_font, 11, 72); glColor3ub(255, 255, 255); sprintf(str, "X:%-4d Y:%-4d |", x, y); // UI_DrawString(6, 6, str); // works ok but fixed width is nicer. BLF_position(blf_mono_font, dx, 6, 0); BLF_draw_ascii(blf_mono_font, str, sizeof(str)); dx += BLF_width(blf_mono_font, str); if(zp) { glColor3ub(255, 255, 255); sprintf(str, " Z:%-.4f |", 0.5f+0.5f*(((float)*zp)/(float)0x7fffffff)); BLF_position(blf_mono_font, dx, 6, 0); BLF_draw_ascii(blf_mono_font, str, sizeof(str)); dx += BLF_width(blf_mono_font, str); } if(zpf) { glColor3ub(255, 255, 255); sprintf(str, " Z:%-.3f |", *zpf); BLF_position(blf_mono_font, dx, 6, 0); BLF_draw_ascii(blf_mono_font, str, sizeof(str)); dx += BLF_width(blf_mono_font, str); } if(channels >= 3) { glColor3ubv(red); if (fp) sprintf(str, " R:%-.4f", fp[0]); else if (cp) sprintf(str, " R:%-3d", cp[0]); else sprintf(str, " R:-"); BLF_position(blf_mono_font, dx, 6, 0); BLF_draw_ascii(blf_mono_font, str, sizeof(str)); dx += BLF_width(blf_mono_font, str); glColor3ubv(green); if (fp) sprintf(str, " G:%-.4f", fp[1]); else if (cp) sprintf(str, " G:%-3d", cp[1]); else sprintf(str, " G:-"); BLF_position(blf_mono_font, dx, 6, 0); BLF_draw_ascii(blf_mono_font, str, sizeof(str)); dx += BLF_width(blf_mono_font, str); glColor3ubv(blue); if (fp) sprintf(str, " B:%-.4f", fp[2]); else if (cp) sprintf(str, " B:%-3d", cp[2]); else sprintf(str, " B:-"); BLF_position(blf_mono_font, dx, 6, 0); BLF_draw_ascii(blf_mono_font, str, sizeof(str)); dx += BLF_width(blf_mono_font, str); if(channels == 4) { glColor3ub(255, 255, 255); if (fp) sprintf(str, " A:%-.4f", fp[3]); else if (cp) sprintf(str, " A:%-3d", cp[3]); else sprintf(str, "- "); BLF_position(blf_mono_font, dx, 6, 0); BLF_draw_ascii(blf_mono_font, str, sizeof(str)); dx += BLF_width(blf_mono_font, str); } } /* color rectangle */ if (channels==1) { if (fp) col[0] = col[1] = col[2] = fp[0]; else if (cp) col[0] = col[1] = col[2] = (float)cp[0]/255.0f; else col[0] = col[1] = col[2] = 0.0f; } else if (channels==3) { if (fp) copy_v3_v3(col, fp); else if (cp) { col[0] = (float)cp[0]/255.0f; col[1] = (float)cp[1]/255.0f; col[2] = (float)cp[2]/255.0f; } else zero_v3(col); } else if (channels==4) { if (fp) copy_v4_v4(col, fp); else if (cp) { col[0] = (float)cp[0]/255.0f; col[1] = (float)cp[1]/255.0f; col[2] = (float)cp[2]/255.0f; col[3] = (float)cp[3]/255.0f; } else zero_v4(col); } if (color_manage) { linearrgb_to_srgb_v3_v3(finalcol, col); finalcol[3] = col[3]; } else { copy_v4_v4(finalcol, col); } glDisable(GL_BLEND); glColor3fv(finalcol); dx += 5; glBegin(GL_QUADS); glVertex2f(dx, 3); glVertex2f(dx, 17); glVertex2f(dx+30, 17); glVertex2f(dx+30, 3); glEnd(); dx += 35; glColor3ub(255, 255, 255); if(channels == 1) { if (fp) { rgb_to_hsv(fp[0], fp[0], fp[0], &hue, &sat, &val); rgb_to_yuv(fp[0], fp[0], fp[0], &lum, &u, &v); } else if (cp) { rgb_to_hsv((float)cp[0]/255.0f, (float)cp[0]/255.0f, (float)cp[0]/255.0f, &hue, &sat, &val); rgb_to_yuv((float)cp[0]/255.0f, (float)cp[0]/255.0f, (float)cp[0]/255.0f, &lum, &u, &v); } sprintf(str, "V:%-.4f", val); BLF_position(blf_mono_font, dx, 6, 0); BLF_draw_ascii(blf_mono_font, str, sizeof(str)); dx += BLF_width(blf_mono_font, str); sprintf(str, " L:%-.4f", lum); BLF_position(blf_mono_font, dx, 6, 0); BLF_draw_ascii(blf_mono_font, str, sizeof(str)); dx += BLF_width(blf_mono_font, str); } else if(channels >= 3) { if (fp) { rgb_to_hsv(fp[0], fp[1], fp[2], &hue, &sat, &val); rgb_to_yuv(fp[0], fp[1], fp[2], &lum, &u, &v); } else if (cp) { rgb_to_hsv((float)cp[0]/255.0f, (float)cp[1]/255.0f, (float)cp[2]/255.0f, &hue, &sat, &val); rgb_to_yuv((float)cp[0]/255.0f, (float)cp[1]/255.0f, (float)cp[2]/255.0f, &lum, &u, &v); } sprintf(str, "H:%-.4f", hue); BLF_position(blf_mono_font, dx, 6, 0); BLF_draw_ascii(blf_mono_font, str, sizeof(str)); dx += BLF_width(blf_mono_font, str); sprintf(str, " S:%-.4f", sat); BLF_position(blf_mono_font, dx, 6, 0); BLF_draw_ascii(blf_mono_font, str, sizeof(str)); dx += BLF_width(blf_mono_font, str); sprintf(str, " V:%-.4f", val); BLF_position(blf_mono_font, dx, 6, 0); BLF_draw_ascii(blf_mono_font, str, sizeof(str)); dx += BLF_width(blf_mono_font, str); sprintf(str, " L:%-.4f", lum); BLF_position(blf_mono_font, dx, 6, 0); BLF_draw_ascii(blf_mono_font, str, sizeof(str)); dx += BLF_width(blf_mono_font, str); } (void)dx; }
void ui_draw_but_COLORBAND(uiBut *but, uiWidgetColors *UNUSED(wcol), rcti *rect) { ColorBand *coba; CBData *cbd; float x1, y1, sizex, sizey; float v3[2], v1[2], v2[2], v1a[2], v2a[2]; int a; float pos, colf[4]= {0,0,0,0}; /* initialize incase the colorband isnt valid */ coba= (ColorBand *)(but->editcoba? but->editcoba: but->poin); if(coba==NULL) return; x1= rect->xmin; y1= rect->ymin; sizex= rect->xmax-x1; sizey= rect->ymax-y1; /* first background, to show tranparency */ glColor4ub(UI_TRANSP_DARK, UI_TRANSP_DARK, UI_TRANSP_DARK, 255); glRectf(x1, y1, x1+sizex, y1+sizey); glEnable(GL_POLYGON_STIPPLE); glColor4ub(UI_TRANSP_LIGHT, UI_TRANSP_LIGHT, UI_TRANSP_LIGHT, 255); glPolygonStipple(checker_stipple_sml); glRectf(x1, y1, x1+sizex, y1+sizey); glDisable(GL_POLYGON_STIPPLE); glShadeModel(GL_FLAT); glEnable(GL_BLEND); cbd= coba->data; v1[0]= v2[0]= x1; v1[1]= y1; v2[1]= y1+sizey; glBegin(GL_QUAD_STRIP); glColor4fv( &cbd->r ); glVertex2fv(v1); glVertex2fv(v2); for( a = 1; a <= sizex; a++ ) { pos = ((float)a) / (sizex-1); do_colorband( coba, pos, colf ); if (but->block->color_profile != BLI_PR_NONE) linearrgb_to_srgb_v3_v3(colf, colf); v1[0]=v2[0]= x1 + a; glColor4fv( colf ); glVertex2fv(v1); glVertex2fv(v2); } glEnd(); glShadeModel(GL_FLAT); glDisable(GL_BLEND); /* outline */ glColor4f(0.0, 0.0, 0.0, 1.0); fdrawbox(x1, y1, x1+sizex, y1+sizey); /* help lines */ v1[0]= v2[0]=v3[0]= x1; v1[1]= y1; v1a[1]= y1+0.25f*sizey; v2[1]= y1+0.5f*sizey; v2a[1]= y1+0.75f*sizey; v3[1]= y1+sizey; cbd= coba->data; glBegin(GL_LINES); for(a=0; a<coba->tot; a++, cbd++) { v1[0]=v2[0]=v3[0]=v1a[0]=v2a[0]= x1+ cbd->pos*sizex; if(a==coba->cur) { glColor3ub(0, 0, 0); glVertex2fv(v1); glVertex2fv(v3); glEnd(); setlinestyle(2); glBegin(GL_LINES); glColor3ub(255, 255, 255); glVertex2fv(v1); glVertex2fv(v3); glEnd(); setlinestyle(0); glBegin(GL_LINES); /* glColor3ub(0, 0, 0); glVertex2fv(v1); glVertex2fv(v1a); glColor3ub(255, 255, 255); glVertex2fv(v1a); glVertex2fv(v2); glColor3ub(0, 0, 0); glVertex2fv(v2); glVertex2fv(v2a); glColor3ub(255, 255, 255); glVertex2fv(v2a); glVertex2fv(v3); */ } else { glColor3ub(0, 0, 0); glVertex2fv(v1); glVertex2fv(v2); glColor3ub(255, 255, 255); glVertex2fv(v2); glVertex2fv(v3); } } glEnd(); }
static opj_image_t* ibuftoimage(ImBuf *ibuf, opj_cparameters_t *parameters) { unsigned char *rect; float *rect_float; int subsampling_dx = parameters->subsampling_dx; int subsampling_dy = parameters->subsampling_dy; int i, numcomps, w, h, prec; int x,y, y_row; OPJ_COLOR_SPACE color_space; opj_image_cmptparm_t cmptparm[4]; /* maximum of 4 components */ opj_image_t * image = NULL; img_fol_t img_fol; /* only needed for cinema presets */ memset(&img_fol,0,sizeof(img_fol_t)); if (ibuf->ftype & JP2_CINE) { if (ibuf->x==4096 || ibuf->y==2160) parameters->cp_cinema= CINEMA4K_24; else { if (ibuf->ftype & JP2_CINE_48FPS) { parameters->cp_cinema= CINEMA2K_48; } else { parameters->cp_cinema= CINEMA2K_24; } } if (parameters->cp_cinema){ img_fol.rates = (float*)MEM_mallocN(parameters->tcp_numlayers * sizeof(float), "jp2_rates"); for(i=0; i< parameters->tcp_numlayers; i++){ img_fol.rates[i] = parameters->tcp_rates[i]; } cinema_parameters(parameters); } color_space= CLRSPC_SYCC; prec= 12; numcomps= 3; } else { /* Get settings from the imbuf */ color_space = (ibuf->ftype & JP2_YCC) ? CLRSPC_SYCC : CLRSPC_SRGB; if (ibuf->ftype & JP2_16BIT) prec= 16; else if (ibuf->ftype & JP2_12BIT) prec= 12; else prec= 8; /* 32bit images == alpha channel */ /* grayscale not supported yet */ numcomps= (ibuf->depth==32) ? 4 : 3; } w= ibuf->x; h= ibuf->y; /* initialize image components */ memset(&cmptparm[0], 0, 4 * sizeof(opj_image_cmptparm_t)); for(i = 0; i < numcomps; i++) { cmptparm[i].prec = prec; cmptparm[i].bpp = prec; cmptparm[i].sgnd = 0; cmptparm[i].dx = subsampling_dx; cmptparm[i].dy = subsampling_dy; cmptparm[i].w = w; cmptparm[i].h = h; } /* create the image */ image = opj_image_create(numcomps, &cmptparm[0], color_space); if(!image) { printf("Error: opj_image_create() failed\n"); return NULL; } /* set image offset and reference grid */ image->x0 = parameters->image_offset_x0; image->y0 = parameters->image_offset_y0; image->x1 = parameters->image_offset_x0 + (w - 1) * subsampling_dx + 1; image->y1 = parameters->image_offset_y0 + (h - 1) * subsampling_dy + 1; /* set image data */ rect = (unsigned char*) ibuf->rect; rect_float= ibuf->rect_float; if (rect_float && rect && prec==8) { /* No need to use the floating point buffer, just write the 8 bits from the char buffer */ rect_float= NULL; } if (rect_float) { float rgb[3]; switch (prec) { case 8: /* Convert blenders float color channels to 8,12 or 16bit ints */ for(y=h-1; y>=0; y--) { y_row = y*w; for(x=0; x<w; x++, rect_float+=4) { i = y_row + x; if (ibuf->profile == IB_PROFILE_LINEAR_RGB) linearrgb_to_srgb_v3_v3(rgb, rect_float); else copy_v3_v3(rgb, rect_float); image->comps[0].data[i] = DOWNSAMPLE_FLOAT_TO_8BIT(rgb[0]); image->comps[1].data[i] = DOWNSAMPLE_FLOAT_TO_8BIT(rgb[1]); image->comps[2].data[i] = DOWNSAMPLE_FLOAT_TO_8BIT(rgb[2]); if (numcomps>3) image->comps[3].data[i] = DOWNSAMPLE_FLOAT_TO_8BIT(rect_float[3]); } } break; case 12: for(y=h-1; y>=0; y--) { y_row = y*w; for(x=0; x<w; x++, rect_float+=4) { i = y_row + x; if (ibuf->profile == IB_PROFILE_LINEAR_RGB) linearrgb_to_srgb_v3_v3(rgb, rect_float); else copy_v3_v3(rgb, rect_float); image->comps[0].data[i] = DOWNSAMPLE_FLOAT_TO_12BIT(rgb[0]); image->comps[1].data[i] = DOWNSAMPLE_FLOAT_TO_12BIT(rgb[1]); image->comps[2].data[i] = DOWNSAMPLE_FLOAT_TO_12BIT(rgb[2]); if (numcomps>3) image->comps[3].data[i] = DOWNSAMPLE_FLOAT_TO_12BIT(rect_float[3]); } } break; case 16: for(y=h-1; y>=0; y--) { y_row = y*w; for(x=0; x<w; x++, rect_float+=4) { i = y_row + x; if (ibuf->profile == IB_PROFILE_LINEAR_RGB) linearrgb_to_srgb_v3_v3(rgb, rect_float); else copy_v3_v3(rgb, rect_float); image->comps[0].data[i] = DOWNSAMPLE_FLOAT_TO_16BIT(rgb[0]); image->comps[1].data[i] = DOWNSAMPLE_FLOAT_TO_16BIT(rgb[1]); image->comps[2].data[i] = DOWNSAMPLE_FLOAT_TO_16BIT(rgb[2]); if (numcomps>3) image->comps[3].data[i] = DOWNSAMPLE_FLOAT_TO_16BIT(rect_float[3]); } } break; } } else { /* just use rect*/ switch (prec) { case 8: for(y=h-1; y>=0; y--) { y_row = y*w; for(x=0; x<w; x++, rect+=4) { i = y_row + x; image->comps[0].data[i] = rect[0]; image->comps[1].data[i] = rect[1]; image->comps[2].data[i] = rect[2]; if (numcomps>3) image->comps[3].data[i] = rect[3]; } } break; case 12: /* Up Sampling, a bit pointless but best write the bit depth requested */ for(y=h-1; y>=0; y--) { y_row = y*w; for(x=0; x<w; x++, rect+=4) { i = y_row + x; image->comps[0].data[i]= UPSAMPLE_8_TO_12(rect[0]); image->comps[1].data[i]= UPSAMPLE_8_TO_12(rect[1]); image->comps[2].data[i]= UPSAMPLE_8_TO_12(rect[2]); if (numcomps>3) image->comps[3].data[i]= UPSAMPLE_8_TO_12(rect[3]); } } break; case 16: for(y=h-1; y>=0; y--) { y_row = y*w; for(x=0; x<w; x++, rect+=4) { i = y_row + x; image->comps[0].data[i]= UPSAMPLE_8_TO_16(rect[0]); image->comps[1].data[i]= UPSAMPLE_8_TO_16(rect[1]); image->comps[2].data[i]= UPSAMPLE_8_TO_16(rect[2]); if (numcomps>3) image->comps[3].data[i]= UPSAMPLE_8_TO_16(rect[3]); } } break; } } /* Decide if MCT should be used */ parameters->tcp_mct = image->numcomps == 3 ? 1 : 0; if(parameters->cp_cinema){ cinema_setup_encoder(parameters,image,&img_fol); } if (img_fol.rates) MEM_freeN(img_fol.rates); return image; }
static void update_tface_color_layer(DerivedMesh *dm, bool use_mcol) { const MPoly *mp = dm->getPolyArray(dm); const int mpoly_num = dm->getNumPolys(dm); MTexPoly *mtexpoly = DM_get_poly_data_layer(dm, CD_MTEXPOLY); MLoopCol *finalCol; int i, j; MLoopCol *mloopcol = NULL; /* cache material values to avoid a lot of lookups */ Material *ma = NULL; short mat_nr_prev = -1; enum { COPY_CALC, COPY_ORIG, COPY_PREV, } copy_mode = COPY_CALC; if (use_mcol) { mloopcol = dm->getLoopDataArray(dm, CD_PREVIEW_MLOOPCOL); if (!mloopcol) mloopcol = dm->getLoopDataArray(dm, CD_MLOOPCOL); } if (CustomData_has_layer(&dm->loopData, CD_TEXTURE_MLOOPCOL)) { finalCol = CustomData_get_layer(&dm->loopData, CD_TEXTURE_MLOOPCOL); } else { finalCol = MEM_mallocN(sizeof(MLoopCol) * dm->numLoopData, "add_tface_color_layer"); CustomData_add_layer(&dm->loopData, CD_TEXTURE_MLOOPCOL, CD_ASSIGN, finalCol, dm->numLoopData); } for (i = mpoly_num; i--; mp++) { const short mat_nr = mp->mat_nr; if (UNLIKELY(mat_nr_prev != mat_nr)) { ma = give_current_material(Gtexdraw.ob, mat_nr + 1); copy_mode = COPY_CALC; mat_nr_prev = mat_nr; } /* avoid lookups */ if (copy_mode == COPY_ORIG) { memcpy(&finalCol[mp->loopstart], &mloopcol[mp->loopstart], sizeof(*finalCol) * mp->totloop); } else if (copy_mode == COPY_PREV) { int loop_index = mp->loopstart; const MLoopCol *lcol_prev = &finalCol[(mp - 1)->loopstart]; for (j = 0; j < mp->totloop; j++, loop_index++) { finalCol[loop_index] = *lcol_prev; } } /* (copy_mode == COPY_CALC) */ else if (ma && (ma->game.flag & GEMAT_INVISIBLE)) { if (mloopcol) { memcpy(&finalCol[mp->loopstart], &mloopcol[mp->loopstart], sizeof(*finalCol) * mp->totloop); copy_mode = COPY_ORIG; } else { memset(&finalCol[mp->loopstart], 0xff, sizeof(*finalCol) * mp->totloop); copy_mode = COPY_PREV; } } else if (mtexpoly && set_draw_settings_cached(0, mtexpoly, ma, Gtexdraw)) { int loop_index = mp->loopstart; for (j = 0; j < mp->totloop; j++, loop_index++) { finalCol[loop_index].r = 255; finalCol[loop_index].g = 0; finalCol[loop_index].b = 255; } copy_mode = COPY_PREV; } else if (ma && (ma->shade_flag & MA_OBCOLOR)) { int loop_index = mp->loopstart; for (j = 0; j < mp->totloop; j++, loop_index++) { copy_v3_v3_char((char *)&finalCol[loop_index].r, (char *)Gtexdraw.obcol); } copy_mode = COPY_PREV; } else { if (mloopcol) { memcpy(&finalCol[mp->loopstart], &mloopcol[mp->loopstart], sizeof(*finalCol) * mp->totloop); copy_mode = COPY_ORIG; } else if (mtexpoly) { memset(&finalCol[mp->loopstart], 0xff, sizeof(*finalCol) * mp->totloop); copy_mode = COPY_PREV; } else { float col[3]; if (ma) { int loop_index = mp->loopstart; MLoopCol lcol; if (Gtexdraw.color_profile) linearrgb_to_srgb_v3_v3(col, &ma->r); else copy_v3_v3(col, &ma->r); rgb_float_to_uchar((unsigned char *)&lcol.r, col); lcol.a = 255; for (j = 0; j < mp->totloop; j++, loop_index++) { finalCol[loop_index] = lcol; } } else { memset(&finalCol[mp->loopstart], 0xff, sizeof(*finalCol) * mp->totloop); } copy_mode = COPY_PREV; } } } }
/* create imbuf with brush color */ static ImBuf *brush_painter_imbuf_new(BrushPainter *painter, int size) { Scene *scene = painter->scene; Brush *brush = painter->brush; rctf tex_mapping = painter->tex_mapping; rctf mask_mapping = painter->mask_mapping; struct ImagePool *pool = painter->pool; bool use_masking = painter->cache.use_masking; bool use_color_correction = painter->cache.use_color_correction; bool use_float = painter->cache.use_float; bool is_texbrush = painter->cache.is_texbrush; bool is_maskbrush = painter->cache.is_maskbrush; float alpha = (use_masking) ? 1.0f : BKE_brush_alpha_get(scene, brush); int radius = BKE_brush_size_get(scene, brush); int xoff = -size * 0.5f + 0.5f; int yoff = -size * 0.5f + 0.5f; int x, y, thread = 0; float brush_rgb[3]; /* allocate image buffer */ ImBuf *ibuf = IMB_allocImBuf(size, size, 32, (use_float) ? IB_rectfloat : IB_rect); /* get brush color */ if (brush->imagepaint_tool == PAINT_TOOL_DRAW) { copy_v3_v3(brush_rgb, brush->rgb); if (use_color_correction) srgb_to_linearrgb_v3_v3(brush_rgb, brush_rgb); } else { brush_rgb[0] = 1.0f; brush_rgb[1] = 1.0f; brush_rgb[2] = 1.0f; } /* fill image buffer */ for (y = 0; y < size; y++) { for (x = 0; x < size; x++) { /* sample texture and multiply with brush color */ float texco[3], rgba[4]; if (is_texbrush) { brush_imbuf_tex_co(&tex_mapping, x, y, texco); BKE_brush_sample_tex_3D(scene, brush, texco, rgba, thread, pool); /* TODO(sergey): Support texture paint color space. */ if (!use_float) { linearrgb_to_srgb_v3_v3(rgba, rgba); } mul_v3_v3(rgba, brush_rgb); } else { copy_v3_v3(rgba, brush_rgb); rgba[3] = 1.0f; } if (is_maskbrush) { brush_imbuf_tex_co(&mask_mapping, x, y, texco); rgba[3] *= BKE_brush_sample_masktex(scene, brush, texco, thread, pool); } /* when not using masking, multiply in falloff and strength */ if (!use_masking) { float xy[2] = {x + xoff, y + yoff}; float len = len_v2(xy); rgba[3] *= alpha * BKE_brush_curve_strength_clamp(brush, len, radius); } if (use_float) { /* write to float pixel */ float *dstf = ibuf->rect_float + (y * size + x) * 4; mul_v3_v3fl(dstf, rgba, rgba[3]); /* premultiply */ dstf[3] = rgba[3]; } else { /* write to byte pixel */ unsigned char *dst = (unsigned char *)ibuf->rect + (y * size + x) * 4; rgb_float_to_uchar(dst, rgba); dst[3] = FTOCHAR(rgba[3]); } } } return ibuf; }
static void update_tface_color_layer(DerivedMesh *dm) { MTFace *tface = DM_get_tessface_data_layer(dm, CD_MTFACE); MFace *mface = dm->getTessFaceArray(dm); MCol *finalCol; int i, j; MCol *mcol = dm->getTessFaceDataArray(dm, CD_PREVIEW_MCOL); if (!mcol) mcol = dm->getTessFaceDataArray(dm, CD_MCOL); if (CustomData_has_layer(&dm->faceData, CD_TEXTURE_MCOL)) { finalCol = CustomData_get_layer(&dm->faceData, CD_TEXTURE_MCOL); } else { finalCol = MEM_mallocN(sizeof(MCol) * 4 * dm->getNumTessFaces(dm), "add_tface_color_layer"); CustomData_add_layer(&dm->faceData, CD_TEXTURE_MCOL, CD_ASSIGN, finalCol, dm->numTessFaceData); } for (i = 0; i < dm->getNumTessFaces(dm); i++) { Material *ma = give_current_material(Gtexdraw.ob, mface[i].mat_nr + 1); if (ma && (ma->game.flag & GEMAT_INVISIBLE)) { if (mcol) memcpy(&finalCol[i * 4], &mcol[i * 4], sizeof(MCol) * 4); else for (j = 0; j < 4; j++) { finalCol[i * 4 + j].b = 255; finalCol[i * 4 + j].g = 255; finalCol[i * 4 + j].r = 255; } } else if (tface && set_draw_settings_cached(0, tface, ma, Gtexdraw)) { for (j = 0; j < 4; j++) { finalCol[i * 4 + j].b = 255; finalCol[i * 4 + j].g = 0; finalCol[i * 4 + j].r = 255; } } else if (ma && (ma->shade_flag & MA_OBCOLOR)) { for (j = 0; j < 4; j++) { finalCol[i * 4 + j].b = Gtexdraw.obcol[0]; finalCol[i * 4 + j].g = Gtexdraw.obcol[1]; finalCol[i * 4 + j].r = Gtexdraw.obcol[2]; } } else if (!mcol) { if (tface) { for (j = 0; j < 4; j++) { finalCol[i * 4 + j].b = 255; finalCol[i * 4 + j].g = 255; finalCol[i * 4 + j].r = 255; } } else { float col[3]; if (ma) { if (Gtexdraw.color_profile) linearrgb_to_srgb_v3_v3(col, &ma->r); else copy_v3_v3(col, &ma->r); for (j = 0; j < 4; j++) { finalCol[i * 4 + j].b = FTOCHAR(col[0]); finalCol[i * 4 + j].g = FTOCHAR(col[1]); finalCol[i * 4 + j].r = FTOCHAR(col[2]); } } else for (j = 0; j < 4; j++) { finalCol[i * 4 + j].b = 255; finalCol[i * 4 + j].g = 255; finalCol[i * 4 + j].r = 255; } } } else { for (j = 0; j < 4; j++) { finalCol[i * 4 + j].r = mcol[i * 4 + j].r; finalCol[i * 4 + j].g = mcol[i * 4 + j].g; finalCol[i * 4 + j].b = mcol[i * 4 + j].b; } } } }
void scopes_update(Scopes *scopes, ImBuf *ibuf, int use_color_management) { int x, y, c; unsigned int n, nl; double div, divl; float *rf = NULL; unsigned char *rc = NULL; unsigned int *bin_r, *bin_g, *bin_b, *bin_lum; int savedlines, saveline; float rgb[3], ycc[3], luma; int ycc_mode = -1; const short is_float = (ibuf->rect_float != NULL); if (ibuf->rect == NULL && ibuf->rect_float == NULL) return; if (scopes->ok == 1) return; if (scopes->hist.ymax == 0.f) scopes->hist.ymax = 1.f; /* hmmmm */ if (!(ELEM(ibuf->channels, 3, 4))) return; scopes->hist.channels = 3; scopes->hist.x_resolution = 256; switch (scopes->wavefrm_mode) { case SCOPES_WAVEFRM_RGB: ycc_mode = -1; break; case SCOPES_WAVEFRM_LUMA: case SCOPES_WAVEFRM_YCC_JPEG: ycc_mode = BLI_YCC_JFIF_0_255; break; case SCOPES_WAVEFRM_YCC_601: ycc_mode = BLI_YCC_ITU_BT601; break; case SCOPES_WAVEFRM_YCC_709: ycc_mode = BLI_YCC_ITU_BT709; break; } /* temp table to count pix value for histo */ bin_r = MEM_callocN(256 * sizeof(unsigned int), "temp historgram bins"); bin_g = MEM_callocN(256 * sizeof(unsigned int), "temp historgram bins"); bin_b = MEM_callocN(256 * sizeof(unsigned int), "temp historgram bins"); bin_lum = MEM_callocN(256 * sizeof(unsigned int), "temp historgram bins"); /* convert to number of lines with logarithmic scale */ scopes->sample_lines = (scopes->accuracy * 0.01f) * (scopes->accuracy * 0.01f) * ibuf->y; if (scopes->sample_full) scopes->sample_lines = ibuf->y; /* scan the image */ savedlines = 0; for (c = 0; c < 3; c++) { scopes->minmax[c][0] = 25500.0f; scopes->minmax[c][1] = -25500.0f; } scopes->waveform_tot = ibuf->x * scopes->sample_lines; if (scopes->waveform_1) MEM_freeN(scopes->waveform_1); if (scopes->waveform_2) MEM_freeN(scopes->waveform_2); if (scopes->waveform_3) MEM_freeN(scopes->waveform_3); if (scopes->vecscope) MEM_freeN(scopes->vecscope); scopes->waveform_1 = MEM_callocN(scopes->waveform_tot * 2 * sizeof(float), "waveform point channel 1"); scopes->waveform_2 = MEM_callocN(scopes->waveform_tot * 2 * sizeof(float), "waveform point channel 2"); scopes->waveform_3 = MEM_callocN(scopes->waveform_tot * 2 * sizeof(float), "waveform point channel 3"); scopes->vecscope = MEM_callocN(scopes->waveform_tot * 2 * sizeof(float), "vectorscope point channel"); if (is_float) rf = ibuf->rect_float; else rc = (unsigned char *)ibuf->rect; for (y = 0; y < ibuf->y; y++) { if (savedlines < scopes->sample_lines && y >= ((savedlines) * ibuf->y) / (scopes->sample_lines + 1)) { saveline = 1; } else { saveline = 0; } for (x = 0; x < ibuf->x; x++) { if (is_float) { if (use_color_management) linearrgb_to_srgb_v3_v3(rgb, rf); else copy_v3_v3(rgb, rf); } else { for (c = 0; c < 3; c++) rgb[c] = rc[c] * INV_255; } /* we still need luma for histogram */ luma = rgb_to_luma(rgb); /* check for min max */ if (ycc_mode == -1) { for (c = 0; c < 3; c++) { if (rgb[c] < scopes->minmax[c][0]) scopes->minmax[c][0] = rgb[c]; if (rgb[c] > scopes->minmax[c][1]) scopes->minmax[c][1] = rgb[c]; } } else { rgb_to_ycc(rgb[0], rgb[1], rgb[2], &ycc[0], &ycc[1], &ycc[2], ycc_mode); for (c = 0; c < 3; c++) { ycc[c] *= INV_255; if (ycc[c] < scopes->minmax[c][0]) scopes->minmax[c][0] = ycc[c]; if (ycc[c] > scopes->minmax[c][1]) scopes->minmax[c][1] = ycc[c]; } } /* increment count for histo*/ bin_r[get_bin_float(rgb[0])] += 1; bin_g[get_bin_float(rgb[1])] += 1; bin_b[get_bin_float(rgb[2])] += 1; bin_lum[get_bin_float(luma)] += 1; /* save sample if needed */ if (saveline) { const float fx = (float)x / (float)ibuf->x; const int idx = 2 * (ibuf->x * savedlines + x); save_sample_line(scopes, idx, fx, rgb, ycc); } rf += ibuf->channels; rc += ibuf->channels; } if (saveline) savedlines += 1; } /* convert hist data to float (proportional to max count) */ n = 0; nl = 0; for (x = 0; x < 256; x++) { if (bin_r[x] > n) n = bin_r[x]; if (bin_g[x] > n) n = bin_g[x]; if (bin_b[x] > n) n = bin_b[x]; if (bin_lum[x] > nl) nl = bin_lum[x]; } div = 1.0 / (double)n; divl = 1.0 / (double)nl; for (x = 0; x < 256; x++) { scopes->hist.data_r[x] = bin_r[x] * div; scopes->hist.data_g[x] = bin_g[x] * div; scopes->hist.data_b[x] = bin_b[x] * div; scopes->hist.data_luma[x] = bin_lum[x] * divl; } MEM_freeN(bin_r); MEM_freeN(bin_g); MEM_freeN(bin_b); MEM_freeN(bin_lum); scopes->ok = 1; }
int imb_savetiff(ImBuf *ibuf, const char *name, int flags) { TIFF *image = NULL; uint16 samplesperpixel, bitspersample; size_t npixels; unsigned char *pixels = NULL; unsigned char *from = NULL, *to = NULL; unsigned short *pixels16 = NULL, *to16 = NULL; float *fromf = NULL; int x, y, from_i, to_i, i; int extraSampleTypes[1] = { EXTRASAMPLE_ASSOCALPHA }; /* check for a valid number of bytes per pixel. Like the PNG writer, * the TIFF writer supports 1, 3 or 4 bytes per pixel, corresponding * to gray, RGB, RGBA respectively. */ samplesperpixel = (uint16)((ibuf->depth + 7) >> 3); if((samplesperpixel > 4) || (samplesperpixel == 2)) { fprintf(stderr, "imb_savetiff: unsupported number of bytes per " "pixel: %d\n", samplesperpixel); return (0); } if((ibuf->ftype & TIF_16BIT) && ibuf->rect_float) bitspersample = 16; else bitspersample = 8; /* open TIFF file for writing */ if(flags & IB_mem) { /* bork at the creation of a TIFF in memory */ fprintf(stderr, "imb_savetiff: creation of in-memory TIFF files is " "not yet supported.\n"); return (0); } else { /* create image as a file */ image = TIFFOpen(name, "w"); } if(image == NULL) { fprintf(stderr, "imb_savetiff: could not open TIFF for writing.\n"); return (0); } /* allocate array for pixel data */ npixels = ibuf->x * ibuf->y; if(bitspersample == 16) pixels16 = (unsigned short*)_TIFFmalloc(npixels * samplesperpixel * sizeof(unsigned short)); else pixels = (unsigned char*)_TIFFmalloc(npixels * samplesperpixel * sizeof(unsigned char)); if(pixels == NULL && pixels16 == NULL) { fprintf(stderr, "imb_savetiff: could not allocate pixels array.\n"); TIFFClose(image); return (0); } /* setup pointers */ if(bitspersample == 16) { fromf = ibuf->rect_float; to16 = pixels16; } else { from = (unsigned char*)ibuf->rect; to = pixels; } /* setup samples per pixel */ TIFFSetField(image, TIFFTAG_BITSPERSAMPLE, bitspersample); TIFFSetField(image, TIFFTAG_SAMPLESPERPIXEL, samplesperpixel); if(samplesperpixel == 4) { /* RGBA images */ TIFFSetField(image, TIFFTAG_EXTRASAMPLES, 1, extraSampleTypes); TIFFSetField(image, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_RGB); } else if(samplesperpixel == 3) { /* RGB images */ TIFFSetField(image, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_RGB); } else if(samplesperpixel == 1) { /* greyscale images, 1 channel */ TIFFSetField(image, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_MINISBLACK); } /* copy pixel data. While copying, we flip the image vertically. */ for(x = 0; x < ibuf->x; x++) { for(y = 0; y < ibuf->y; y++) { from_i = 4*(y*ibuf->x+x); to_i = samplesperpixel*((ibuf->y-y-1)*ibuf->x+x); if(pixels16) { /* convert from float source */ float rgb[3]; if (ibuf->profile == IB_PROFILE_LINEAR_RGB) linearrgb_to_srgb_v3_v3(rgb, &fromf[from_i]); else copy_v3_v3(rgb, &fromf[from_i]); to16[to_i+0] = FTOUSHORT(rgb[0]); to16[to_i+1] = FTOUSHORT(rgb[1]); to16[to_i+2] = FTOUSHORT(rgb[2]); to_i += 3; from_i+=3; if (samplesperpixel == 4) { to16[to_i+3] = FTOUSHORT(fromf[from_i+3]); /*to_i++; from_i++;*/ /*unused, set on each loop */ } } else { for(i = 0; i < samplesperpixel; i++, to_i++, from_i++) to[to_i] = from[from_i]; } } } /* write the actual TIFF file */ TIFFSetField(image, TIFFTAG_IMAGEWIDTH, ibuf->x); TIFFSetField(image, TIFFTAG_IMAGELENGTH, ibuf->y); TIFFSetField(image, TIFFTAG_ROWSPERSTRIP, ibuf->y); TIFFSetField(image, TIFFTAG_COMPRESSION, COMPRESSION_DEFLATE); TIFFSetField(image, TIFFTAG_FILLORDER, FILLORDER_MSB2LSB); TIFFSetField(image, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG); TIFFSetField(image, TIFFTAG_XRESOLUTION, 150.0); TIFFSetField(image, TIFFTAG_YRESOLUTION, 150.0); TIFFSetField(image, TIFFTAG_RESOLUTIONUNIT, RESUNIT_INCH); if(TIFFWriteEncodedStrip(image, 0, (bitspersample == 16)? (unsigned char*)pixels16: pixels, ibuf->x*ibuf->y*samplesperpixel*bitspersample/8) == -1) { fprintf(stderr, "imb_savetiff: Could not write encoded TIFF.\n"); TIFFClose(image); if(pixels) _TIFFfree(pixels); if(pixels16) _TIFFfree(pixels16); return (1); } /* close the TIFF file */ TIFFClose(image); if(pixels) _TIFFfree(pixels); if(pixels16) _TIFFfree(pixels16); return (1); }