Changeset View
Changeset View
Standalone View
Standalone View
source/blender/editors/render/render_opengl.c
| Show First 20 Lines • Show All 51 Lines • ▼ Show 20 Lines | |||||
| #include "BKE_main.h" | #include "BKE_main.h" | ||||
| #include "BKE_report.h" | #include "BKE_report.h" | ||||
| #include "BKE_scene.h" | #include "BKE_scene.h" | ||||
| #include "BKE_sequencer.h" | #include "BKE_sequencer.h" | ||||
| #include "BKE_writeavi.h" | #include "BKE_writeavi.h" | ||||
| #include "DEG_depsgraph.h" | #include "DEG_depsgraph.h" | ||||
| #include "DRW_engine.h" | |||||
| #include "WM_api.h" | #include "WM_api.h" | ||||
| #include "WM_types.h" | #include "WM_types.h" | ||||
| #include "ED_screen.h" | #include "ED_screen.h" | ||||
| #include "ED_view3d.h" | #include "ED_view3d.h" | ||||
| #include "ED_gpencil.h" | #include "ED_gpencil.h" | ||||
| #include "RE_pipeline.h" | #include "RE_pipeline.h" | ||||
| ▲ Show 20 Lines • Show All 250 Lines • ▼ Show 20 Lines | else if (gpd) { | ||||
| IMB_freeImBuf(out); | IMB_freeImBuf(out); | ||||
| } | } | ||||
| if (gpd) { | if (gpd) { | ||||
| int i; | int i; | ||||
| unsigned char *gp_rect; | unsigned char *gp_rect; | ||||
| unsigned char *render_rect = (unsigned char *)RE_RenderViewGetById(rr, oglrender->view_id)->rect32; | unsigned char *render_rect = (unsigned char *)RE_RenderViewGetById(rr, oglrender->view_id)->rect32; | ||||
| DRW_ogl_ctx_enable(); | |||||
| GPU_offscreen_bind(oglrender->ofs, true); | GPU_offscreen_bind(oglrender->ofs, true); | ||||
| glClearColor(0.0f, 0.0f, 0.0f, 0.0f); | glClearColor(0.0f, 0.0f, 0.0f, 0.0f); | ||||
| glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); | glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); | ||||
| wmOrtho2(0, sizex, 0, sizey); | wmOrtho2(0, sizex, 0, sizey); | ||||
| gpuTranslate2f(sizex / 2, sizey / 2); | gpuTranslate2f(sizex / 2, sizey / 2); | ||||
| G.f |= G_RENDER_OGL; | G.f |= G_RENDER_OGL; | ||||
| ED_gpencil_draw_ex(scene, gpd, sizex, sizey, scene->r.cfra, SPACE_SEQ); | ED_gpencil_draw_ex(scene, gpd, sizex, sizey, scene->r.cfra, SPACE_SEQ); | ||||
| G.f &= ~G_RENDER_OGL; | G.f &= ~G_RENDER_OGL; | ||||
| gp_rect = MEM_mallocN(sizex * sizey * sizeof(unsigned char) * 4, "offscreen rect"); | gp_rect = MEM_mallocN(sizex * sizey * sizeof(unsigned char) * 4, "offscreen rect"); | ||||
| GPU_offscreen_read_pixels(oglrender->ofs, GL_UNSIGNED_BYTE, gp_rect); | GPU_offscreen_read_pixels(oglrender->ofs, GL_UNSIGNED_BYTE, gp_rect); | ||||
| for (i = 0; i < sizex * sizey * 4; i += 4) { | for (i = 0; i < sizex * sizey * 4; i += 4) { | ||||
| blend_color_mix_byte(&render_rect[i], &render_rect[i], &gp_rect[i]); | blend_color_mix_byte(&render_rect[i], &render_rect[i], &gp_rect[i]); | ||||
| } | } | ||||
| GPU_offscreen_unbind(oglrender->ofs, true); | GPU_offscreen_unbind(oglrender->ofs, true); | ||||
| DRW_ogl_ctx_disable(); | |||||
| MEM_freeN(gp_rect); | MEM_freeN(gp_rect); | ||||
| } | } | ||||
| } | } | ||||
| else { | else { | ||||
| /* shouldnt suddenly give errors mid-render but possible */ | /* shouldnt suddenly give errors mid-render but possible */ | ||||
| char err_out[256] = "unknown"; | char err_out[256] = "unknown"; | ||||
| ImBuf *ibuf_view; | ImBuf *ibuf_view; | ||||
| ▲ Show 20 Lines • Show All 294 Lines • ▼ Show 20 Lines | static bool screen_opengl_render_init(bContext *C, wmOperator *op) | ||||
| /* stop all running jobs, except screen one. currently previews frustrate Render */ | /* stop all running jobs, except screen one. currently previews frustrate Render */ | ||||
| WM_jobs_kill_all_except(wm, CTX_wm_screen(C)); | WM_jobs_kill_all_except(wm, CTX_wm_screen(C)); | ||||
| /* create offscreen buffer */ | /* create offscreen buffer */ | ||||
| sizex = (scene->r.size * scene->r.xsch) / 100; | sizex = (scene->r.size * scene->r.xsch) / 100; | ||||
| sizey = (scene->r.size * scene->r.ysch) / 100; | sizey = (scene->r.size * scene->r.ysch) / 100; | ||||
| /* corrects render size with actual size, not every card supports non-power-of-two dimensions */ | /* corrects render size with actual size, not every card supports non-power-of-two dimensions */ | ||||
| DRW_ogl_ctx_enable(); /* Offscreen creation needs to be done in DRW context. */ | |||||
| ofs = GPU_offscreen_create(sizex, sizey, full_samples ? 0 : samples, true, err_out); | ofs = GPU_offscreen_create(sizex, sizey, full_samples ? 0 : samples, true, err_out); | ||||
| DRW_ogl_ctx_disable(); | |||||
| if (!ofs) { | if (!ofs) { | ||||
| BKE_reportf(op->reports, RPT_ERROR, "Failed to create OpenGL off-screen buffer, %s", err_out); | BKE_reportf(op->reports, RPT_ERROR, "Failed to create OpenGL off-screen buffer, %s", err_out); | ||||
| return false; | return false; | ||||
| } | } | ||||
| /* allocate opengl render */ | /* allocate opengl render */ | ||||
| oglrender = MEM_callocN(sizeof(OGLRender), "OGLRender"); | oglrender = MEM_callocN(sizeof(OGLRender), "OGLRender"); | ||||
| ▲ Show 20 Lines • Show All 172 Lines • ▼ Show 20 Lines | #endif | ||||
| WM_cursor_modal_restore(oglrender->win); | WM_cursor_modal_restore(oglrender->win); | ||||
| WM_event_add_notifier(C, NC_SCENE | ND_RENDER_RESULT, oglrender->scene); | WM_event_add_notifier(C, NC_SCENE | ND_RENDER_RESULT, oglrender->scene); | ||||
| if (oglrender->fx) | if (oglrender->fx) | ||||
| GPU_fx_compositor_destroy(oglrender->fx); | GPU_fx_compositor_destroy(oglrender->fx); | ||||
| DRW_ogl_ctx_enable(); | |||||
brecht: Maybe `oglrender->fx` should be created and destroyed in the context as well? It seems safer to… | |||||
| GPU_offscreen_free(oglrender->ofs); | GPU_offscreen_free(oglrender->ofs); | ||||
| DRW_ogl_ctx_disable(); | |||||
| if (oglrender->is_sequencer) { | if (oglrender->is_sequencer) { | ||||
| MEM_freeN(oglrender->seq_data.ibufs_arr); | MEM_freeN(oglrender->seq_data.ibufs_arr); | ||||
| } | } | ||||
| oglrender->scene->customdata_mask_modal = 0; | oglrender->scene->customdata_mask_modal = 0; | ||||
| CTX_wm_area_set(C, oglrender->prevsa); | CTX_wm_area_set(C, oglrender->prevsa); | ||||
| ▲ Show 20 Lines • Show All 383 Lines • Show Last 20 Lines | |||||
Maybe oglrender->fx should be created and destroyed in the context as well? It seems safer to just do it for all the OpenGL data structures anyway, even if currently they can be shared.