diff options
author | Arystanbek Dyussenov <arystan.d@gmail.com> | 2010-09-04 22:49:07 +0400 |
---|---|---|
committer | Arystanbek Dyussenov <arystan.d@gmail.com> | 2010-09-04 22:49:07 +0400 |
commit | 90b464d3728d9ed8ec26fdf59058d236b99dbcd9 (patch) | |
tree | e88cab4fb1358e962b19f658064ca8c9f8d29f5b /source/blender/editors/render/render_opengl.c | |
parent | 08d02dd04d836976b25793bb1d4c6a86b3f924c7 (diff) | |
parent | b0b787ef38f9947b3176642556f5282eb3518f69 (diff) |
COLLADA branch: merge from trunk -r 28015:31610.soc-2009-chingachgook
Diffstat (limited to 'source/blender/editors/render/render_opengl.c')
-rw-r--r-- | source/blender/editors/render/render_opengl.c | 138 |
1 files changed, 95 insertions, 43 deletions
diff --git a/source/blender/editors/render/render_opengl.c b/source/blender/editors/render/render_opengl.c index ee5363a00f9..7833f93b3b5 100644 --- a/source/blender/editors/render/render_opengl.c +++ b/source/blender/editors/render/render_opengl.c @@ -38,20 +38,13 @@ #include "BLI_dlrbTree.h" #include "DNA_scene_types.h" +#include "DNA_object_types.h" -#include "BKE_blender.h" -#include "BKE_object.h" #include "BKE_context.h" -#include "BKE_global.h" #include "BKE_image.h" -#include "BKE_library.h" #include "BKE_main.h" -#include "BKE_mesh.h" -#include "BKE_multires.h" #include "BKE_report.h" #include "BKE_scene.h" -#include "BKE_screen.h" -#include "BKE_utildefines.h" #include "BKE_writeavi.h" #include "WM_api.h" @@ -59,9 +52,11 @@ #include "ED_screen.h" #include "ED_view3d.h" +#include "ED_image.h" #include "RE_pipeline.h" #include "IMB_imbuf_types.h" +#include "IMB_imbuf.h" #include "RNA_access.h" #include "RNA_define.h" @@ -94,6 +89,17 @@ typedef struct OGLRender { wmTimer *timer; /* use to check if running modal or not (invoke'd or exec'd)*/ } OGLRender; +/* added because v3d is not always valid */ +static unsigned int screen_opengl_layers(OGLRender *oglrender) +{ + if(oglrender->v3d) { + return oglrender->scene->lay | oglrender->v3d->lay; + } + else { + return oglrender->scene->lay; + } +} + static void screen_opengl_render_apply(OGLRender *oglrender) { Scene *scene= oglrender->scene; @@ -106,32 +112,54 @@ static void screen_opengl_render_apply(OGLRender *oglrender) float winmat[4][4]; int sizex= oglrender->sizex; int sizey= oglrender->sizey; + int view_context = (v3d != NULL); - /* bind */ - GPU_offscreen_bind(oglrender->ofs); + rr= RE_AcquireResultRead(oglrender->re); + + /* note on color management: + * looked into how best to deal with color management here and found heres how it should work. + * + * OpenGL materials etc are color corrected, so a float buffer from the graphics card is + * color corrected, without running any conversion functions. + * + * With color correction disabled blender expects the rr->rectf to be non-color managed so + * just do a direct copy from the byte array to the rectf with no conversion too. + * notice IMB_float_from_rect has the profile set so no conversion is done. + */ + + if(view_context) { + GPU_offscreen_bind(oglrender->ofs); /* bind */ + + /* render 3d view */ + if(rv3d->persp==RV3D_CAMOB && v3d->camera) { + RE_GetCameraWindow(oglrender->re, v3d->camera, scene->r.cfra, winmat); + ED_view3d_draw_offscreen(scene, v3d, ar, sizex, sizey, NULL, winmat); + } + else { + ED_view3d_draw_offscreen(scene, v3d, ar, sizex, sizey, NULL, NULL); + } + + glReadPixels(0, 0, sizex, sizey, GL_RGBA, GL_FLOAT, rr->rectf); - /* render 3d view */ - if(rv3d->persp==RV3D_CAMOB && v3d->camera) { - RE_GetCameraWindow(oglrender->re, v3d->camera, scene->r.cfra, winmat); - ED_view3d_draw_offscreen(scene, v3d, ar, sizex, sizey, NULL, winmat); + GPU_offscreen_unbind(oglrender->ofs); /* unbind */ } - else - ED_view3d_draw_offscreen(scene, v3d, ar, sizex, sizey, NULL, NULL); + else { + ImBuf *ibuf_view= ED_view3d_draw_offscreen_imbuf_simple(scene, oglrender->sizex, oglrender->sizey, IB_rectfloat, OB_SOLID); + memcpy(rr->rectf, ibuf_view->rect_float, sizeof(float) * 4 * oglrender->sizex * oglrender->sizey); + IMB_freeImBuf(ibuf_view); + } + + /* rr->rectf is now filled with image data */ - /* read in pixels & stamp */ - rr= RE_AcquireResultRead(oglrender->re); - glReadPixels(0, 0, sizex, sizey, GL_RGBA, GL_FLOAT, rr->rectf); if((scene->r.stamp & R_STAMP_ALL) && (scene->r.stamp & R_STAMP_DRAW)) BKE_stamp_buf(scene, NULL, rr->rectf, rr->rectx, rr->recty, 4); + RE_ReleaseResult(oglrender->re); /* update byte from float buffer */ ibuf= BKE_image_acquire_ibuf(oglrender->ima, &oglrender->iuser, &lock); if(ibuf) image_buffer_rect_update(NULL, rr, ibuf, NULL); BKE_image_release_ibuf(oglrender->ima, lock); - - /* unbind */ - GPU_offscreen_unbind(oglrender->ofs); } static int screen_opengl_render_init(bContext *C, wmOperator *op) @@ -142,14 +170,23 @@ static int screen_opengl_render_init(bContext *C, wmOperator *op) GPUOffScreen *ofs; OGLRender *oglrender; int sizex, sizey; + int view_context= RNA_boolean_get(op->ptr, "view_context"); /* ensure we have a 3d view */ - if(!ED_view3d_context_activate(C)) - return 0; + + if(!ED_view3d_context_activate(C)) { + RNA_boolean_set(op->ptr, "view_context", 0); + view_context = 0; + } /* only one render job at a time */ if(WM_jobs_test(CTX_wm_manager(C), scene)) return 0; + + if(!view_context && scene->camera==NULL) { + BKE_report(op->reports, RPT_ERROR, "Scene has no camera."); + return 0; + } /* stop all running jobs, currently previews frustrate Render */ WM_jobs_stop_all(CTX_wm_manager(C)); @@ -177,9 +214,11 @@ static int screen_opengl_render_init(bContext *C, wmOperator *op) oglrender->sizey= sizey; oglrender->scene= scene; - oglrender->v3d= CTX_wm_view3d(C); - oglrender->ar= CTX_wm_region(C); - oglrender->rv3d= CTX_wm_region_view3d(C); + if(view_context) { + oglrender->v3d= CTX_wm_view3d(C); + oglrender->ar= CTX_wm_region(C); + oglrender->rv3d= CTX_wm_region_view3d(C); + } /* create image and image user */ oglrender->ima= BKE_image_verify_viewer(IMA_TYPE_R_RESULT, "Render Result"); @@ -194,7 +233,7 @@ static int screen_opengl_render_init(bContext *C, wmOperator *op) rr= RE_AcquireResultWrite(oglrender->re); if(rr->rectf==NULL) - rr->rectf= MEM_mallocN(sizeof(float)*4*sizex*sizey, "32 bits rects"); + rr->rectf= MEM_callocN(sizeof(float)*4*sizex*sizey, "screen_opengl_render_init rect"); RE_ReleaseResult(oglrender->re); return 1; @@ -202,6 +241,7 @@ static int screen_opengl_render_init(bContext *C, wmOperator *op) static void screen_opengl_render_end(bContext *C, OGLRender *oglrender) { + Main *bmain= CTX_data_main(C); Scene *scene= oglrender->scene; if(oglrender->mh) { @@ -211,7 +251,7 @@ static void screen_opengl_render_end(bContext *C, OGLRender *oglrender) if(oglrender->timer) { /* exec will not have a timer */ scene->r.cfra= oglrender->cfrao; - scene_update_for_newframe(scene, scene->lay); + scene_update_for_newframe(bmain, scene, screen_opengl_layers(oglrender)); WM_event_remove_timer(CTX_wm_manager(C), CTX_wm_window(C), oglrender->timer); } @@ -258,32 +298,42 @@ static int screen_opengl_render_anim_initialize(bContext *C, wmOperator *op) } static int screen_opengl_render_anim_step(bContext *C, wmOperator *op) { + Main *bmain= CTX_data_main(C); OGLRender *oglrender= op->customdata; Scene *scene= oglrender->scene; ImBuf *ibuf; void *lock; char name[FILE_MAXDIR+FILE_MAXFILE]; - unsigned int lay; int ok= 0; + int view_context = (oglrender->v3d != NULL); + + /* update animated image textures for gpu, etc, + * call before scene_update_for_newframe so modifiers with textuers dont lag 1 frame */ + ED_image_update_frame(C); /* go to next frame */ while(CFRA<oglrender->nfra) { - if(scene->lay & 0xFF000000) - lay= scene->lay & 0xFF000000; - else - lay= scene->lay; + unsigned int lay= screen_opengl_layers(oglrender); - scene_update_for_newframe(scene, lay); + if(lay & 0xFF000000) + lay &= 0xFF000000; + + scene_update_for_newframe(bmain, scene, lay); CFRA++; } - scene_update_for_newframe(scene, scene->lay); + scene_update_for_newframe(bmain, scene, screen_opengl_layers(oglrender)); - if(oglrender->rv3d->persp==RV3D_CAMOB && oglrender->v3d->camera && oglrender->v3d->scenelock) { - /* since scene_update_for_newframe() is used rather - * then ED_update_for_newframe() the camera needs to be set */ - if(scene_camera_switch_update(scene)) - oglrender->v3d->camera= scene->camera; + if(view_context) { + if(oglrender->rv3d->persp==RV3D_CAMOB && oglrender->v3d->camera && oglrender->v3d->scenelock) { + /* since scene_update_for_newframe() is used rather + * then ED_update_for_newframe() the camera needs to be set */ + if(scene_camera_switch_update(scene)) + oglrender->v3d->camera= scene->camera; + } + } + else { + scene_camera_switch_update(scene); } /* render into offscreen buffer */ @@ -354,9 +404,10 @@ static int screen_opengl_render_modal(bContext *C, wmOperator *op, wmEvent *even return OPERATOR_RUNNING_MODAL; } - ret= screen_opengl_render_anim_step(C, op); - + /* run first because screen_opengl_render_anim_step can free oglrender */ WM_event_add_notifier(C, NC_SCENE|ND_RENDER_RESULT, oglrender->scene); + + ret= screen_opengl_render_anim_step(C, op); /* stop at the end or on error */ if(ret == 0) { @@ -445,6 +496,7 @@ void RENDER_OT_opengl(wmOperatorType *ot) ot->poll= ED_operator_screenactive; RNA_def_boolean(ot->srna, "animation", 0, "Animation", ""); + RNA_def_boolean(ot->srna, "view_context", 1, "View Context", "Use the current 3D view for rendering, else use scene settings."); } /* function for getting an opengl buffer from a View3D, used by sequencer */ |