Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergey Sharybin <sergey.vfx@gmail.com>2013-01-05 19:33:18 +0400
committerSergey Sharybin <sergey.vfx@gmail.com>2013-01-05 19:33:18 +0400
commitfa0805e287e762df3638df1982297c794c4cf4b7 (patch)
tree1b2a7d612bde64569aad2afd72410a43a8147f27
parente8b415bdb4ba282e3574cad1463bf2512fe5eb8f (diff)
Changes for opengl render to reflect new alpha premul pipeline
without hurting quick texture painting - ED_view3d_draw_offscreen will now output buffer with transparent alpha, if sky needed it should be alpha-undered later. - ED_view3d_draw_offscreen_imbuf now accepts alpha mode as an argument which could be either R_ADDSKY or R_PREMULALPHA - OpenGL render and sequencer's opengl preview will now reflect scene's Alpha Mode - Quick Edit will use OpenGL with transparent alpha mode
-rw-r--r--source/blender/blenkernel/intern/sequencer.c2
-rw-r--r--source/blender/editors/include/ED_view3d.h8
-rw-r--r--source/blender/editors/render/render_opengl.c18
-rw-r--r--source/blender/editors/sculpt_paint/paint_image.c2
-rw-r--r--source/blender/editors/space_view3d/view3d_draw.c77
-rw-r--r--source/blender/imbuf/IMB_imbuf.h3
-rw-r--r--source/blender/imbuf/intern/imageprocess.c50
-rw-r--r--source/blender/windowmanager/intern/wm_files.c4
8 files changed, 109 insertions, 55 deletions
diff --git a/source/blender/blenkernel/intern/sequencer.c b/source/blender/blenkernel/intern/sequencer.c
index 8d010de408a..2c1fd092fbb 100644
--- a/source/blender/blenkernel/intern/sequencer.c
+++ b/source/blender/blenkernel/intern/sequencer.c
@@ -2391,7 +2391,7 @@ static ImBuf *seq_render_scene_strip(SeqRenderData context, Sequence *seq, float
BKE_scene_update_for_newframe(context.bmain, scene, scene->lay);
ibuf = sequencer_view3d_cb(scene, camera, context.rectx, context.recty, IB_rect,
context.scene->r.seq_prev_type, context.scene->r.seq_flag & R_SEQ_SOLID_TEX,
- TRUE, FALSE, err_out);
+ TRUE, scene->r.alphamode, err_out);
if (ibuf == NULL) {
fprintf(stderr, "seq_render_scene_strip failed to get opengl buffer: %s\n", err_out);
}
diff --git a/source/blender/editors/include/ED_view3d.h b/source/blender/editors/include/ED_view3d.h
index 3d13938c204..ac2c47216a6 100644
--- a/source/blender/editors/include/ED_view3d.h
+++ b/source/blender/editors/include/ED_view3d.h
@@ -270,13 +270,13 @@ int ED_view3d_scene_layer_set(int lay, const int *values, int *active);
int ED_view3d_context_activate(struct bContext *C);
void ED_view3d_draw_offscreen_init(struct Scene *scene, struct View3D *v3d);
void ED_view3d_draw_offscreen(struct Scene *scene, struct View3D *v3d, struct ARegion *ar,
- int winx, int winy, float viewmat[4][4], float winmat[4][4], int do_bgpic, int colormanage_background);
+ int winx, int winy, float viewmat[4][4], float winmat[4][4], int do_bgpic);
struct ImBuf *ED_view3d_draw_offscreen_imbuf(struct Scene *scene, struct View3D *v3d, struct ARegion *ar, int sizex, int sizey, unsigned int flag,
- int draw_background, int colormanage_background, char err_out[256]);
+ int draw_background, int alpha_mode, char err_out[256]);
struct ImBuf *ED_view3d_draw_offscreen_imbuf_simple(struct Scene *scene, struct Object *camera, int width, int height, unsigned int flag, int drawtype,
- int use_solid_tex, int draw_background, int colormanage_background, char err_out[256]);
-
+ int use_solid_tex, int draw_background, int alpha_mode, char err_out[256]);
+void ED_view3d_offscreen_sky_color_get(struct Scene *scene, float sky_color[3]);
struct Base *ED_view3d_give_base_under_cursor(struct bContext *C, const int mval[2]);
void ED_view3d_quadview_update(struct ScrArea *sa, struct ARegion *ar, short do_clip);
diff --git a/source/blender/editors/render/render_opengl.c b/source/blender/editors/render/render_opengl.c
index cbc076b3342..7ba6a92e4be 100644
--- a/source/blender/editors/render/render_opengl.c
+++ b/source/blender/editors/render/render_opengl.c
@@ -43,6 +43,7 @@
#include "DNA_scene_types.h"
#include "DNA_object_types.h"
+#include "DNA_world_types.h"
#include "BKE_context.h"
#include "BKE_global.h"
@@ -192,7 +193,7 @@ static void screen_opengl_render_apply(OGLRender *oglrender)
}
if ((scene->r.mode & R_OSA) == 0) {
- ED_view3d_draw_offscreen(scene, v3d, ar, sizex, sizey, NULL, winmat, TRUE, FALSE);
+ ED_view3d_draw_offscreen(scene, v3d, ar, sizex, sizey, NULL, winmat, TRUE);
GPU_offscreen_read_pixels(oglrender->ofs, GL_FLOAT, rr->rectf);
}
else {
@@ -206,7 +207,7 @@ static void screen_opengl_render_apply(OGLRender *oglrender)
BLI_jitter_init(jit_ofs[0], scene->r.osa);
/* first sample buffer, also initializes 'rv3d->persmat' */
- ED_view3d_draw_offscreen(scene, v3d, ar, sizex, sizey, NULL, winmat, TRUE, FALSE);
+ ED_view3d_draw_offscreen(scene, v3d, ar, sizex, sizey, NULL, winmat, TRUE);
GPU_offscreen_read_pixels(oglrender->ofs, GL_FLOAT, accum_buffer);
/* skip the first sample */
@@ -216,7 +217,7 @@ static void screen_opengl_render_apply(OGLRender *oglrender)
(jit_ofs[j][0] * 2.0f) / sizex,
(jit_ofs[j][1] * 2.0f) / sizey);
- ED_view3d_draw_offscreen(scene, v3d, ar, sizex, sizey, NULL, winmat_jitter, TRUE, FALSE);
+ ED_view3d_draw_offscreen(scene, v3d, ar, sizex, sizey, NULL, winmat_jitter, TRUE);
GPU_offscreen_read_pixels(oglrender->ofs, GL_FLOAT, accum_tmp);
add_vn_vn(accum_buffer, accum_tmp, sizex * sizey * sizeof(float));
}
@@ -232,7 +233,8 @@ static void screen_opengl_render_apply(OGLRender *oglrender)
else {
/* shouldnt suddenly give errors mid-render but possible */
char err_out[256] = "unknown";
- ImBuf *ibuf_view = ED_view3d_draw_offscreen_imbuf_simple(scene, scene->camera, oglrender->sizex, oglrender->sizey, IB_rectfloat, OB_SOLID, FALSE, TRUE, FALSE, err_out);
+ ImBuf *ibuf_view = ED_view3d_draw_offscreen_imbuf_simple(scene, scene->camera, oglrender->sizex, oglrender->sizey,
+ IB_rectfloat, OB_SOLID, FALSE, TRUE, R_ALPHAPREMUL, err_out);
camera = scene->camera;
if (ibuf_view) {
@@ -243,7 +245,13 @@ static void screen_opengl_render_apply(OGLRender *oglrender)
fprintf(stderr, "%s: failed to get buffer, %s\n", __func__, err_out);
}
}
-
+
+ if (scene->r.alphamode == R_ADDSKY) {
+ float sky_color[3];
+ ED_view3d_offscreen_sky_color_get(scene, sky_color);
+ IMB_alpha_under_color_float(rr->rectf, sizex, sizey, sky_color);
+ }
+
/* note on color management:
*
* OpenGL renders into sRGB colors, but render buffers are expected to be
diff --git a/source/blender/editors/sculpt_paint/paint_image.c b/source/blender/editors/sculpt_paint/paint_image.c
index fa8252c824d..d0f8e36e17d 100644
--- a/source/blender/editors/sculpt_paint/paint_image.c
+++ b/source/blender/editors/sculpt_paint/paint_image.c
@@ -6038,7 +6038,7 @@ static int texture_paint_image_from_view_exec(bContext *C, wmOperator *op)
if (w > maxsize) w = maxsize;
if (h > maxsize) h = maxsize;
- ibuf = ED_view3d_draw_offscreen_imbuf(CTX_data_scene(C), CTX_wm_view3d(C), CTX_wm_region(C), w, h, IB_rect, FALSE, FALSE, err_out);
+ ibuf = ED_view3d_draw_offscreen_imbuf(CTX_data_scene(C), CTX_wm_view3d(C), CTX_wm_region(C), w, h, IB_rect, FALSE, R_ALPHAPREMUL, err_out);
if (!ibuf) {
/* Mostly happens when OpenGL offscreen buffer was failed to create, */
/* but could be other reasons. Should be handled in the future. nazgul */
diff --git a/source/blender/editors/space_view3d/view3d_draw.c b/source/blender/editors/space_view3d/view3d_draw.c
index 4ccf26e12b1..76f62db3c5b 100644
--- a/source/blender/editors/space_view3d/view3d_draw.c
+++ b/source/blender/editors/space_view3d/view3d_draw.c
@@ -2393,7 +2393,7 @@ static void gpu_update_lamps_shadows(Scene *scene, View3D *v3d)
invert_m4_m4(rv3d.persinv, rv3d.viewinv);
/* no need to call ED_view3d_draw_offscreen_init since shadow buffers were already updated */
- ED_view3d_draw_offscreen(scene, v3d, &ar, winsize, winsize, viewmat, winmat, FALSE, FALSE);
+ ED_view3d_draw_offscreen(scene, v3d, &ar, winsize, winsize, viewmat, winmat, FALSE);
GPU_lamp_shadow_buffer_unbind(shadow->lamp);
v3d->drawtype = drawtype;
@@ -2540,13 +2540,11 @@ void ED_view3d_draw_offscreen_init(Scene *scene, View3D *v3d)
/* ED_view3d_draw_offscreen_init should be called before this to initialize
* stuff like shadow buffers
*/
-void ED_view3d_draw_offscreen(Scene *scene, View3D *v3d, ARegion *ar,
- int winx, int winy, float viewmat[4][4], float winmat[4][4],
- int do_bgpic, int colormanage_background)
+void ED_view3d_draw_offscreen(Scene *scene, View3D *v3d, ARegion *ar, int winx, int winy,
+ float viewmat[4][4], float winmat[4][4], int do_bgpic)
{
RegionView3D *rv3d = ar->regiondata;
Base *base;
- float backcol[3];
int bwinx, bwiny;
rcti brect;
@@ -2574,34 +2572,7 @@ void ED_view3d_draw_offscreen(Scene *scene, View3D *v3d, ARegion *ar,
* warning! can be slow so only free animated images - campbell */
GPU_free_images_anim();
- /* set background color, fallback on the view background color
- * (if active clip is set but frame is failed to load fallback to horizon color as background) */
- if (scene->world) {
- /* NOTE: currently OpenGL is supposed to always work in sRGB space and do not
- * apply any tonemaps since it's really tricky to support for all features (GLSL, textures, etc)
- * but due to compatibility issues background is being affected display transform, so we can
- * emulate behavior of disabled color management
- * but this function is also used for sequencer's scene strips which shouldn't be affected by
- * tonemaps now and should be purely sRGB, that's why we've got this colormanage_background
- * we can drop this flag in cost of some compatibility loss -- background wouldn't be
- * color managed in 3d viewport
- * same goes to opengl rendering, where color profile should be applied as very final step
- */
-
- if (colormanage_background) {
- IMB_colormanagement_pixel_to_display_space_v3(backcol, &scene->world->horr, &scene->view_settings,
- &scene->display_settings);
- }
- else {
- linearrgb_to_srgb_v3_v3(backcol, &scene->world->horr);
- }
-
- glClearColor(backcol[0], backcol[1], backcol[2], 0.0f);
- }
- else {
- UI_ThemeClearColor(TH_BACK);
- }
-
+ glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
@@ -2703,10 +2674,30 @@ void ED_view3d_draw_offscreen(Scene *scene, View3D *v3d, ARegion *ar,
G.f &= ~G_RENDER_OGL;
}
+/* get a color used for offscreen sky, returns color in sRGB space */
+void ED_view3d_offscreen_sky_color_get(Scene *scene, float sky_color[3])
+{
+ if (scene->world)
+ linearrgb_to_srgb_v3_v3(sky_color, &scene->world->horr);
+ else
+ UI_GetThemeColor3fv(TH_BACK, sky_color);
+}
+
+static void offscreen_imbuf_add_sky(ImBuf *ibuf, Scene *scene)
+{
+ float sky_color[3];
+
+ ED_view3d_offscreen_sky_color_get(scene, sky_color);
+
+ if (ibuf->rect_float)
+ IMB_alpha_under_color_float(ibuf->rect_float, ibuf->x, ibuf->y, sky_color);
+ else
+ IMB_alpha_under_color_byte((unsigned char *) ibuf->rect, ibuf->x, ibuf->y, sky_color);
+}
+
/* utility func for ED_view3d_draw_offscreen */
-ImBuf *ED_view3d_draw_offscreen_imbuf(Scene *scene, View3D *v3d, ARegion *ar,
- int sizex, int sizey, unsigned int flag, int draw_background,
- int colormanage_background, char err_out[256])
+ImBuf *ED_view3d_draw_offscreen_imbuf(Scene *scene, View3D *v3d, ARegion *ar, int sizex, int sizey, unsigned int flag,
+ int draw_background, int alpha_mode, char err_out[256])
{
RegionView3D *rv3d = ar->regiondata;
ImBuf *ibuf;
@@ -2733,10 +2724,10 @@ ImBuf *ED_view3d_draw_offscreen_imbuf(Scene *scene, View3D *v3d, ARegion *ar,
BKE_camera_params_compute_viewplane(&params, sizex, sizey, scene->r.xasp, scene->r.yasp);
BKE_camera_params_compute_matrix(&params);
- ED_view3d_draw_offscreen(scene, v3d, ar, sizex, sizey, NULL, params.winmat, draw_background, colormanage_background);
+ ED_view3d_draw_offscreen(scene, v3d, ar, sizex, sizey, NULL, params.winmat, draw_background);
}
else {
- ED_view3d_draw_offscreen(scene, v3d, ar, sizex, sizey, NULL, NULL, draw_background, colormanage_background);
+ ED_view3d_draw_offscreen(scene, v3d, ar, sizex, sizey, NULL, NULL, draw_background);
}
/* read in pixels & stamp */
@@ -2747,6 +2738,9 @@ ImBuf *ED_view3d_draw_offscreen_imbuf(Scene *scene, View3D *v3d, ARegion *ar,
else if (ibuf->rect)
GPU_offscreen_read_pixels(ofs, GL_UNSIGNED_BYTE, ibuf->rect);
+ if (alpha_mode == R_ADDSKY)
+ offscreen_imbuf_add_sky(ibuf, scene);
+
/* unbind */
GPU_offscreen_unbind(ofs);
GPU_offscreen_free(ofs);
@@ -2760,9 +2754,8 @@ ImBuf *ED_view3d_draw_offscreen_imbuf(Scene *scene, View3D *v3d, ARegion *ar,
}
/* creates own 3d views, used by the sequencer */
-ImBuf *ED_view3d_draw_offscreen_imbuf_simple(Scene *scene, Object *camera, int width, int height,
- unsigned int flag, int drawtype, int use_solid_tex, int draw_background,
- int colormanage_background, char err_out[256])
+ImBuf *ED_view3d_draw_offscreen_imbuf_simple(Scene *scene, Object *camera, int width, int height, unsigned int flag, int drawtype,
+ int use_solid_tex, int draw_background, int alpha_mode, char err_out[256])
{
View3D v3d = {NULL};
ARegion ar = {NULL};
@@ -2805,7 +2798,7 @@ ImBuf *ED_view3d_draw_offscreen_imbuf_simple(Scene *scene, Object *camera, int w
invert_m4_m4(rv3d.persinv, rv3d.viewinv);
return ED_view3d_draw_offscreen_imbuf(scene, &v3d, &ar, width, height, flag,
- draw_background, colormanage_background, err_out);
+ draw_background, alpha_mode, err_out);
// seq_view3d_cb(scene, cfra, render_size, seqrectx, seqrecty);
}
diff --git a/source/blender/imbuf/IMB_imbuf.h b/source/blender/imbuf/IMB_imbuf.h
index 850060ef4d5..8d60227377b 100644
--- a/source/blender/imbuf/IMB_imbuf.h
+++ b/source/blender/imbuf/IMB_imbuf.h
@@ -416,6 +416,9 @@ void nearest_interpolation_color(struct ImBuf *in, unsigned char col[4], float c
void bilinear_interpolation_color(struct ImBuf *in, unsigned char col[4], float col_float[4], float u, float v);
void bilinear_interpolation_color_wrap(struct ImBuf *in, unsigned char col[4], float col_float[4], float u, float v);
+void IMB_alpha_under_color_float(float *rect_float, int x, int y, float backcol[3]);
+void IMB_alpha_under_color_byte(unsigned char *rect, int x, int y, float backcol[3]);
+
/**
*
* \attention defined in readimage.c
diff --git a/source/blender/imbuf/intern/imageprocess.c b/source/blender/imbuf/intern/imageprocess.c
index 1eac6236829..59282c9d207 100644
--- a/source/blender/imbuf/intern/imageprocess.c
+++ b/source/blender/imbuf/intern/imageprocess.c
@@ -327,3 +327,53 @@ void IMB_processor_apply_threaded(int buffer_lines, int handle_size, void *init_
MEM_freeN(handles);
}
+
+/* Alpha-under */
+
+void IMB_alpha_under_color_float(float *rect_float, int x, int y, float backcol[3])
+{
+ int a = x * y;
+ float *fp = rect_float;
+
+ while (a--) {
+ if (fp[3] == 0.0f) {
+ copy_v3_v3(fp, backcol);
+ }
+ else {
+ float mul = 1.0f - fp[3];
+
+ fp[0] += mul * backcol[0];
+ fp[1] += mul * backcol[1];
+ fp[2] += mul * backcol[2];
+ }
+
+ fp[3] = 1.0f;
+
+ fp += 4;
+ }
+}
+
+void IMB_alpha_under_color_byte(unsigned char *rect, int x, int y, float backcol[3])
+{
+ int a = x * y;
+ unsigned char *cp = rect;
+
+ while (a--) {
+ if (cp[3] == 0) {
+ cp[0] = backcol[0] * 255;
+ cp[1] = backcol[1] * 255;
+ cp[2] = backcol[2] * 255;
+ }
+ else {
+ int mul = 255 - cp[3];
+
+ cp[0] += mul * backcol[0] / 255;
+ cp[1] += mul * backcol[1] / 255;
+ cp[2] += mul * backcol[2] / 255;
+ }
+
+ cp[3] = 255;
+
+ cp += 4;
+ }
+}
diff --git a/source/blender/windowmanager/intern/wm_files.c b/source/blender/windowmanager/intern/wm_files.c
index f31aff3d3f8..a9b3e4272ce 100644
--- a/source/blender/windowmanager/intern/wm_files.c
+++ b/source/blender/windowmanager/intern/wm_files.c
@@ -733,11 +733,11 @@ static ImBuf *blend_file_thumb(Scene *scene, bScreen *screen, int **thumb_pt)
if (scene->camera) {
ibuf = ED_view3d_draw_offscreen_imbuf_simple(scene, scene->camera,
BLEN_THUMB_SIZE * 2, BLEN_THUMB_SIZE * 2,
- IB_rect, OB_SOLID, FALSE, FALSE, FALSE, err_out);
+ IB_rect, OB_SOLID, FALSE, FALSE, R_ADDSKY, err_out);
}
else {
ibuf = ED_view3d_draw_offscreen_imbuf(scene, v3d, ar, BLEN_THUMB_SIZE * 2, BLEN_THUMB_SIZE * 2,
- IB_rect, FALSE, FALSE, err_out);
+ IB_rect, FALSE, R_ADDSKY, err_out);
}
if (ibuf) {