/* applies to render pipeline */ static void node_composit_exec_composite(void *data, bNode *node, bNodeStack **in, bNodeStack **out) { /* image assigned to output */ /* stack order input sockets: col, alpha, z */ if(node->flag & NODE_DO_OUTPUT) { /* only one works on out */ Scene *scene= (Scene *)node->id; RenderData *rd= data; if(scene && (rd->scemode & R_DOCOMP)) { Render *re= RE_GetRender(scene->id.name); RenderResult *rr= RE_AcquireResultWrite(re); if(rr) { CompBuf *outbuf, *zbuf=NULL; if(rr->rectf) MEM_freeN(rr->rectf); outbuf= alloc_compbuf(rr->rectx, rr->recty, CB_RGBA, 1); if(in[1]->data==NULL) composit1_pixel_processor(node, outbuf, in[0]->data, in[0]->vec, do_copy_rgba, CB_RGBA); else composit2_pixel_processor(node, outbuf, in[0]->data, in[0]->vec, in[1]->data, in[1]->vec, do_copy_a_rgba, CB_RGBA, CB_VAL); if(in[2]->data) { if(rr->rectz) MEM_freeN(rr->rectz); zbuf= alloc_compbuf(rr->rectx, rr->recty, CB_VAL, 1); composit1_pixel_processor(node, zbuf, in[2]->data, in[2]->vec, do_copy_value, CB_VAL); rr->rectz= zbuf->rect; zbuf->malloc= 0; free_compbuf(zbuf); } generate_preview(data, node, outbuf); /* we give outbuf to rr... */ rr->rectf= outbuf->rect; outbuf->malloc= 0; free_compbuf(outbuf); RE_ReleaseResult(re); /* signal for imageviewer to refresh (it converts to byte rects...) */ BKE_image_signal(BKE_image_verify_viewer(IMA_TYPE_R_RESULT, "Render Result"), NULL, IMA_SIGNAL_FREE); return; } else RE_ReleaseResult(re); } } if(in[0]->data) generate_preview(data, node, in[0]->data); }
/* Renders texture directly to render buffer. */ static void shader_preview_texture(ShaderPreview *sp, Tex *tex, Scene *sce, Render *re) { /* Setup output buffer. */ int width = sp->sizex; int height = sp->sizey; /* This is needed otherwise no RenderResult is created. */ sce->r.scemode &= ~R_BUTS_PREVIEW; RE_InitState(re, NULL, &sce->r, &sce->view_layers, NULL, width, height, NULL); RE_SetScene(re, sce); /* Create buffer in empty RenderView created in the init step. */ RenderResult *rr = RE_AcquireResultWrite(re); RenderView *rv = (RenderView *)rr->views.first; rv->rectf = MEM_callocN(sizeof(float) * 4 * width * height, "texture render result"); RE_ReleaseResult(re); /* Get texture image pool (if any) */ struct ImagePool *img_pool = BKE_image_pool_new(); BKE_texture_fetch_images_for_pool(tex, img_pool); /* Fill in image buffer. */ float *rect_float = rv->rectf; float tex_coord[3] = {0.0f, 0.0f, 0.0f}; bool color_manage = true; for (int y = 0; y < height; y++) { /* Tex coords between -1.0f and 1.0f. */ tex_coord[1] = ((float)y / (float)height) * 2.0f - 1.0f; for (int x = 0; x < width; x++) { tex_coord[0] = ((float)x / (float)height) * 2.0f - 1.0f; /* Evaluate texture at tex_coord .*/ TexResult texres = {0}; BKE_texture_get_value_ex(sce, tex, tex_coord, &texres, img_pool, color_manage); rect_float[0] = texres.tr; rect_float[1] = texres.tg; rect_float[2] = texres.tb; rect_float[3] = 1.0f; rect_float += 4; } /* Check if we should cancel texture preview. */ if (shader_preview_break(sp)) { break; } } BKE_image_pool_free(img_pool); }
void CompositorOperation::deinitExecution() { if (!this->m_active) return; if (!isBreaked()) { Render *re = RE_GetRender(this->m_sceneName); RenderResult *rr = RE_AcquireResultWrite(re); if (rr) { if (rr->rectf != NULL) { MEM_freeN(rr->rectf); } rr->rectf = this->m_outputBuffer; if (rr->rectz != NULL) { MEM_freeN(rr->rectz); } rr->rectz = this->m_depthBuffer; } else { if (this->m_outputBuffer) { MEM_freeN(this->m_outputBuffer); } if (this->m_depthBuffer) { MEM_freeN(this->m_depthBuffer); } } if (re) { RE_ReleaseResult(re); re = NULL; } BLI_lock_thread(LOCK_DRAW_IMAGE); BKE_image_signal(BKE_image_verify_viewer(IMA_TYPE_R_RESULT, "Render Result"), NULL, IMA_SIGNAL_FREE); BLI_unlock_thread(LOCK_DRAW_IMAGE); } else { if (this->m_outputBuffer) { MEM_freeN(this->m_outputBuffer); } if (this->m_depthBuffer) { MEM_freeN(this->m_depthBuffer); } } this->m_outputBuffer = NULL; this->m_depthBuffer = NULL; this->m_imageInput = NULL; this->m_alphaInput = NULL; this->m_depthInput = NULL; }
static void screen_opengl_views_setup(OGLRender *oglrender) { RenderResult *rr; RenderView *rv; SceneRenderView *srv; bool is_multiview; View3D *v3d = oglrender->v3d; RenderData *rd = &oglrender->scene->r; rr = RE_AcquireResultWrite(oglrender->re); is_multiview = screen_opengl_is_multiview(oglrender); if (!is_multiview) { /* we only have one view when multiview is off */ rv = rr->views.first; if (rv == NULL) { rv = MEM_callocN(sizeof(RenderView), "new opengl render view"); BLI_addtail(&rr->views, rv); } while (rv->next) { RenderView *rv_del = rv->next; BLI_remlink(&rr->views, rv_del); if (rv_del->rectf) MEM_freeN(rv_del->rectf); if (rv_del->rectz) MEM_freeN(rv_del->rectz); MEM_freeN(rv_del); } } else { if (!oglrender->is_sequencer) RE_SetOverrideCamera(oglrender->re, V3D_CAMERA_SCENE(oglrender->scene, v3d)); /* remove all the views that are not needed */ rv = rr->views.last; while (rv) { srv = BLI_findstring(&rd->views, rv->name, offsetof(SceneRenderView, name)); if (BKE_scene_multiview_is_render_view_active(rd, srv)) { if (rv->rectf == NULL) rv->rectf = MEM_callocN(sizeof(float) * 4 * oglrender->sizex * oglrender->sizey, "screen_opengl_render_init rect"); rv = rv->prev; } else { RenderView *rv_del = rv; rv = rv_del->prev; BLI_remlink(&rr->views, rv_del); if (rv_del->rectf) MEM_freeN(rv_del->rectf); if (rv_del->rectz) MEM_freeN(rv_del->rectz); MEM_freeN(rv_del); } } /* create all the views that are needed */ for (srv = rd->views.first; srv; srv = srv->next) { if (BKE_scene_multiview_is_render_view_active(rd, srv) == false) continue; rv = BLI_findstring(&rr->views, srv->name, offsetof(SceneRenderView, name)); if (rv == NULL) { rv = MEM_callocN(sizeof(RenderView), "new opengl render view"); BLI_strncpy(rv->name, srv->name, sizeof(rv->name)); BLI_addtail(&rr->views, rv); } } } for (rv = rr->views.first; rv; rv = rv->next) { if (rv->rectf == NULL) { rv->rectf = MEM_callocN(sizeof(float) * 4 * oglrender->sizex * oglrender->sizey, "screen_opengl_render_init rect"); } } BLI_lock_thread(LOCK_DRAW_IMAGE); if (is_multiview && BKE_scene_multiview_is_stereo3d(rd)) { oglrender->ima->flag |= IMA_IS_STEREO; } else { oglrender->ima->flag &= ~IMA_IS_STEREO; oglrender->iuser.flag &= ~IMA_SHOW_STEREO; } BLI_unlock_thread(LOCK_DRAW_IMAGE); RE_ReleaseResult(oglrender->re); }
static int screen_opengl_render_init(bContext *C, wmOperator *op) { /* new render clears all callbacks */ wmWindowManager *wm = CTX_wm_manager(C); wmWindow *win = CTX_wm_window(C); Scene *scene = CTX_data_scene(C); ScrArea *prevsa = CTX_wm_area(C); ARegion *prevar = CTX_wm_region(C); RenderResult *rr; GPUOffScreen *ofs; OGLRender *oglrender; int sizex, sizey; short is_view_context = RNA_boolean_get(op->ptr, "view_context"); const short is_animation = RNA_boolean_get(op->ptr, "animation"); const short is_sequencer = RNA_boolean_get(op->ptr, "sequencer"); const short is_write_still = RNA_boolean_get(op->ptr, "write_still"); char err_out[256] = "unknown"; if (G.background) { BKE_report(op->reports, RPT_ERROR, "Cannot use OpenGL render in background mode (no opengl context)"); return 0; } /* ensure we have a 3d view */ if (!ED_view3d_context_activate(C)) { RNA_boolean_set(op->ptr, "view_context", FALSE); is_view_context = 0; } /* only one render job at a time */ if (WM_jobs_test(wm, scene, WM_JOB_TYPE_RENDER)) return 0; if (!is_view_context && scene->camera == NULL) { BKE_report(op->reports, RPT_ERROR, "Scene has no camera"); return 0; } if (!is_animation && is_write_still && BKE_imtype_is_movie(scene->r.im_format.imtype)) { BKE_report(op->reports, RPT_ERROR, "Cannot write a single file with an animation format selected"); return 0; } /* stop all running jobs, except screen one. currently previews frustrate Render */ WM_jobs_kill_all_except(wm, CTX_wm_screen(C)); /* create offscreen buffer */ sizex = (scene->r.size * scene->r.xsch) / 100; sizey = (scene->r.size * scene->r.ysch) / 100; /* corrects render size with actual size, not every card supports non-power-of-two dimensions */ ofs = GPU_offscreen_create(sizex, sizey, err_out); if (!ofs) { BKE_reportf(op->reports, RPT_ERROR, "Failed to create OpenGL off-screen buffer, %s", err_out); return 0; } /* allocate opengl render */ oglrender = MEM_callocN(sizeof(OGLRender), "OGLRender"); op->customdata = oglrender; oglrender->ofs = ofs; oglrender->sizex = sizex; oglrender->sizey = sizey; oglrender->bmain = CTX_data_main(C); oglrender->scene = scene; oglrender->cfrao = scene->r.cfra; oglrender->write_still = is_write_still && !is_animation; oglrender->is_sequencer = is_sequencer; if (is_sequencer) { oglrender->sseq = CTX_wm_space_seq(C); } oglrender->obcenter_dia_back = U.obcenter_dia; U.obcenter_dia = 0; oglrender->prevsa = prevsa; oglrender->prevar = prevar; if (is_view_context) { ED_view3d_context_user_region(C, &oglrender->v3d, &oglrender->ar); /* so quad view renders camera */ oglrender->rv3d = oglrender->ar->regiondata; /* MUST be cleared on exit */ oglrender->scene->customdata_mask_modal = ED_view3d_datamask(oglrender->scene, oglrender->v3d); /* apply immediately in case we're rendering from a script, * running notifiers again will overwrite */ oglrender->scene->customdata_mask |= oglrender->scene->customdata_mask_modal; } /* create render */ oglrender->re = RE_NewRender(scene->id.name); /* create image and image user */ oglrender->ima = BKE_image_verify_viewer(IMA_TYPE_R_RESULT, "Render Result"); BKE_image_signal(oglrender->ima, NULL, IMA_SIGNAL_FREE); BKE_image_backup_render(oglrender->scene, oglrender->ima); oglrender->iuser.scene = scene; oglrender->iuser.ok = 1; /* create render result */ RE_InitState(oglrender->re, NULL, &scene->r, NULL, sizex, sizey, NULL); rr = RE_AcquireResultWrite(oglrender->re); if (rr->rectf == NULL) rr->rectf = MEM_callocN(sizeof(float) * 4 * sizex * sizey, "screen_opengl_render_init rect"); RE_ReleaseResult(oglrender->re); /* wm vars */ oglrender->wm = wm; oglrender->win = win; return 1; }