/* byte to float pixels, input and output 4-channel RGBA */ void IMB_buffer_float_from_byte(float *rect_to, const uchar *rect_from, int profile_to, int profile_from, bool predivide, int width, int height, int stride_to, int stride_from) { float tmp[4]; int x, y; /* we need valid profiles */ BLI_assert(profile_to != IB_PROFILE_NONE); BLI_assert(profile_from != IB_PROFILE_NONE); /* RGBA input */ for (y = 0; y < height; y++) { const uchar *from = rect_from + stride_from * y * 4; 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 += 4, to += 4) { rgba_uchar_to_float(to, from); } } else if (profile_to == IB_PROFILE_LINEAR_RGB) { /* convert sRGB to linear */ if (predivide) { for (x = 0; x < width; x++, from += 4, to += 4) { srgb_to_linearrgb_uchar4_predivide(to, from); } } else { for (x = 0; x < width; x++, from += 4, to += 4) { srgb_to_linearrgb_uchar4(to, from); } } } else if (profile_to == IB_PROFILE_SRGB) { /* convert linear to sRGB */ if (predivide) { for (x = 0; x < width; x++, from += 4, to += 4) { rgba_uchar_to_float(tmp, from); linearrgb_to_srgb_predivide_v4(to, tmp); } } else { for (x = 0; x < width; x++, from += 4, to += 4) { rgba_uchar_to_float(tmp, from); linearrgb_to_srgb_v4(to, tmp); } } } } }
MINLINE void srgb_to_linearrgb_uchar4_predivide(float linear[4], const unsigned char srgb[4]) { float fsrgb[4]; int i; if (srgb[3] == 255 || srgb[3] == 0) { srgb_to_linearrgb_uchar4(linear, srgb); return; } for (i = 0; i < 4; i++) fsrgb[i] = srgb[i] * (1.0f / 255.0f); srgb_to_linearrgb_predivide_v4(linear, fsrgb); }
/* add renderlayer and renderpass for each grease pencil layer for using in composition */ static void add_gpencil_renderpass(OGLRender *oglrender, RenderResult *rr, RenderView *rv) { bGPdata *gpd = oglrender->scene->gpd; Scene *scene = oglrender->scene; /* sanity checks */ if (gpd == NULL) { return; } if (scene == NULL) { return; } if (BLI_listbase_is_empty(&gpd->layers)) { return; } if (oglrender->v3d != NULL && (oglrender->v3d->flag2 & V3D_SHOW_GPENCIL) == 0) { return; } /* save old alpha mode */ short oldalphamode = scene->r.alphamode; /* set alpha transparent for gp */ scene->r.alphamode = R_ALPHAPREMUL; /* saves layer status */ short *oldsts = MEM_mallocN(BLI_listbase_count(&gpd->layers) * sizeof(short), "temp_gplayers_flag"); int i = 0; for (bGPDlayer *gpl = gpd->layers.first; gpl; gpl = gpl->next) { oldsts[i] = gpl->flag; ++i; } /* loop all layers to create separate render */ for (bGPDlayer *gpl = gpd->layers.first; gpl; gpl = gpl->next) { /* dont draw layer if hidden */ if (gpl->flag & GP_LAYER_HIDE) continue; /* hide all layer except current */ for (bGPDlayer *gph = gpd->layers.first; gph; gph = gph->next) { if (gpl != gph) { gph->flag |= GP_LAYER_HIDE; } } /* render this gp layer */ screen_opengl_render_doit(oglrender, rr); /* add RendePass composite */ RenderPass *rp = RE_create_gp_pass(rr, gpl->info, rv->name); /* copy image data from rectf */ // XXX: Needs conversion. unsigned char *src = (unsigned char *)RE_RenderViewGetById(rr, oglrender->view_id)->rect32; if (src != NULL) { float *dest = rp->rect; int x, y, rectx, recty; rectx = rr->rectx; recty = rr->recty; for (y = 0; y < recty; y++) { for (x = 0; x < rectx; x++) { unsigned char *pixSrc = src + 4 * (rectx * y + x); if (pixSrc[3] > 0) { float *pixDest = dest + 4 * (rectx * y + x); float float_src[4]; srgb_to_linearrgb_uchar4(float_src, pixSrc); addAlphaOverFloat(pixDest, float_src); } } } } /* back layer status */ i = 0; for (bGPDlayer *gph = gpd->layers.first; gph; gph = gph->next) { gph->flag = oldsts[i]; ++i; } } /* free memory */ MEM_freeN(oldsts); /* back default alpha mode */ scene->r.alphamode = oldalphamode; }