Blender V4.3
overlay_image.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2019 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
9#include "DRW_render.hh"
10
11#include "BKE_camera.h"
12#include "BKE_image.hh"
13#include "BKE_movieclip.h"
14#include "BKE_object.hh"
15
16#include "BLI_listbase.h"
17#include "BLI_math_rotation.h"
18
19#include "DNA_camera_types.h"
20#include "DNA_screen_types.h"
21
23
24#include "ED_view3d.hh"
25
26#include "IMB_imbuf_types.hh"
27
28#include "overlay_private.hh"
29
31{
32 const DRWContextState *draw_ctx = DRW_context_state_get();
33 OVERLAY_PrivateData *pd = vedata->stl->pd;
34
35 DRWView *default_view = (DRWView *)DRW_view_default_get();
36 pd->view_reference_images = DRW_view_create_with_zoffset(default_view, draw_ctx->rv3d, -1.0f);
37}
38
62
63static void overlay_image_calc_aspect(Image *ima, const int size[2], float r_image_aspect[2])
64{
65 float ima_x, ima_y;
66 if (ima) {
67 ima_x = size[0];
68 ima_y = size[1];
69 }
70 else {
71 /* if no image, make it a 1x1 empty square, honor scale & offset */
72 ima_x = ima_y = 1.0f;
73 }
74 /* Get the image aspect even if the buffer is invalid */
75 float sca_x = 1.0f, sca_y = 1.0f;
76 if (ima) {
77 if (ima->aspx > ima->aspy) {
78 sca_y = ima->aspy / ima->aspx;
79 }
80 else if (ima->aspx < ima->aspy) {
81 sca_x = ima->aspx / ima->aspy;
82 }
83 }
84
85 const float scale_x_inv = ima_x * sca_x;
86 const float scale_y_inv = ima_y * sca_y;
87 if (scale_x_inv > scale_y_inv) {
88 r_image_aspect[0] = 1.0f;
89 r_image_aspect[1] = scale_y_inv / scale_x_inv;
90 }
91 else {
92 r_image_aspect[0] = scale_x_inv / scale_y_inv;
93 r_image_aspect[1] = 1.0f;
94 }
95}
96
98{
99 if ((scene->r.scemode & R_MULTIVIEW) == 0) {
100 return STEREO_LEFT_ID;
101 }
102 if (v3d->stereo3d_camera != STEREO_3D_ID) {
103 /* show only left or right camera */
104 return eStereoViews(v3d->stereo3d_camera);
105 }
106
107 return eStereoViews(v3d->multiview_eye);
108}
109
111 const View3D *v3d,
112 Image *ima,
113 ImageUser *iuser)
114{
115 if (BKE_image_is_stereo(ima)) {
116 iuser->flag |= IMA_SHOW_STEREO;
118 BKE_image_multiview_index(ima, iuser);
119 }
120 else {
121 iuser->flag &= ~IMA_SHOW_STEREO;
122 }
123}
124
126 const DRWContextState *draw_ctx,
128 float *r_aspect,
129 bool *r_use_alpha_premult,
130 bool *r_use_view_transform)
131{
132 Image *image = bgpic->ima;
133 ImageUser *iuser = &bgpic->iuser;
134 MovieClip *clip = nullptr;
135 GPUTexture *tex = nullptr;
136 Scene *scene = draw_ctx->scene;
137 float aspect_x, aspect_y;
138 int width, height;
139 int ctime = int(DEG_get_ctime(draw_ctx->depsgraph));
140 *r_use_alpha_premult = false;
141 *r_use_view_transform = false;
142
143 switch (bgpic->source) {
145 if (image == nullptr) {
146 return nullptr;
147 }
148 *r_use_alpha_premult = (image->alpha_mode == IMA_ALPHA_PREMUL);
149 *r_use_view_transform = (image->flag & IMA_VIEW_AS_RENDER) != 0;
150
151 BKE_image_user_frame_calc(image, iuser, ctime);
152 if (image->source == IMA_SRC_SEQUENCE && !(iuser->flag & IMA_USER_FRAME_IN_RANGE)) {
153 /* Frame is out of range, don't show. */
154 return nullptr;
155 }
156
157 camera_background_images_stereo_setup(scene, draw_ctx->v3d, image, iuser);
158
159 iuser->scene = draw_ctx->scene;
161 iuser->scene = nullptr;
162
163 if (tex == nullptr) {
164 return nullptr;
165 }
166
169
170 aspect_x = bgpic->ima->aspx;
171 aspect_y = bgpic->ima->aspy;
172 break;
173 }
174
176 if (bgpic->flag & CAM_BGIMG_FLAG_CAMERACLIP) {
177 if (scene->camera) {
178 clip = BKE_object_movieclip_get(scene, scene->camera, true);
179 }
180 }
181 else {
182 clip = bgpic->clip;
183 }
184
185 if (clip == nullptr) {
186 return nullptr;
187 }
188
189 BKE_movieclip_user_set_frame(&bgpic->cuser, ctime);
190 tex = BKE_movieclip_get_gpu_texture(clip, &bgpic->cuser);
191 if (tex == nullptr) {
192 return nullptr;
193 }
194
195 aspect_x = clip->aspx;
196 aspect_y = clip->aspy;
197 *r_use_view_transform = true;
198
199 BKE_movieclip_get_size(clip, &bgpic->cuser, &width, &height);
200
201 /* Save for freeing. */
203 break;
204 }
205
206 default:
207 /* Unsupported type. */
208 return nullptr;
209 }
210
211 *r_aspect = (width * aspect_x) / (height * aspect_y);
212 return tex;
213}
214
216{
217 /* Free Movie clip textures after rendering */
218 while (LinkData *link = static_cast<LinkData *>(BLI_pophead(&data->stl->pd->bg_movie_clips))) {
219 MovieClip *clip = (MovieClip *)link->data;
221 MEM_freeN(link);
222 }
223}
224
226 const CameraBGImage *bgpic,
227 const DRWContextState *draw_ctx,
228 const float image_aspect,
229 float rmat[4][4])
230{
231 float rotate[4][4], scale[4][4], translate[4][4];
232
233 axis_angle_to_mat4_single(rotate, 'Z', -bgpic->rotation);
234 unit_m4(scale);
235 unit_m4(translate);
236
237 /* Normalized Object space camera frame corners. */
238 float cam_corners[4][3];
239 BKE_camera_view_frame(draw_ctx->scene, cam, cam_corners);
240 float cam_width = fabsf(cam_corners[0][0] - cam_corners[3][0]);
241 float cam_height = fabsf(cam_corners[0][1] - cam_corners[1][1]);
242 float cam_aspect = cam_width / cam_height;
243
244 if (bgpic->flag & CAM_BGIMG_FLAG_CAMERA_CROP) {
245 /* Crop. */
246 if (image_aspect > cam_aspect) {
247 scale[0][0] *= cam_height * image_aspect;
248 scale[1][1] *= cam_height;
249 }
250 else {
251 scale[0][0] *= cam_width;
252 scale[1][1] *= cam_width / image_aspect;
253 }
254 }
255 else if (bgpic->flag & CAM_BGIMG_FLAG_CAMERA_ASPECT) {
256 /* Fit. */
257 if (image_aspect > cam_aspect) {
258 scale[0][0] *= cam_width;
259 scale[1][1] *= cam_width / image_aspect;
260 }
261 else {
262 scale[0][0] *= cam_height * image_aspect;
263 scale[1][1] *= cam_height;
264 }
265 }
266 else {
267 /* Stretch. */
268 scale[0][0] *= cam_width;
269 scale[1][1] *= cam_height;
270 }
271
272 translate[3][0] = bgpic->offset[0];
273 translate[3][1] = bgpic->offset[1];
274 translate[3][2] = cam_corners[0][2];
275 if (cam->type == CAM_ORTHO) {
276 mul_v2_fl(translate[3], cam->ortho_scale);
277 }
278 /* These lines are for keeping 2.80 behavior and could be removed to keep 2.79 behavior. */
279 translate[3][0] *= min_ff(1.0f, cam_aspect);
280 translate[3][1] /= max_ff(1.0f, cam_aspect) * (image_aspect / cam_aspect);
281 /* quad is -1..1 so divide by 2. */
282 scale[0][0] *= 0.5f * bgpic->scale * ((bgpic->flag & CAM_BGIMG_FLAG_FLIP_X) ? -1.0 : 1.0);
283 scale[1][1] *= 0.5f * bgpic->scale * ((bgpic->flag & CAM_BGIMG_FLAG_FLIP_Y) ? -1.0 : 1.0);
284 /* Camera shift. (middle of cam_corners) */
285 translate[3][0] += (cam_corners[0][0] + cam_corners[2][0]) * 0.5f;
286 translate[3][1] += (cam_corners[0][1] + cam_corners[2][1]) * 0.5f;
287
288 mul_m4_series(rmat, translate, rotate, scale);
289}
290
292{
293 OVERLAY_PrivateData *pd = vedata->stl->pd;
294 OVERLAY_PassList *psl = vedata->psl;
295 const DRWContextState *draw_ctx = DRW_context_state_get();
296 const View3D *v3d = draw_ctx->v3d;
297 const Scene *scene = draw_ctx->scene;
298 const Camera *cam = static_cast<Camera *>(ob->data);
299
300 const bool show_frame = BKE_object_empty_image_frame_is_visible_in_view3d(ob, draw_ctx->rv3d);
301
302 if (!show_frame || DRW_state_is_select()) {
303 return;
304 }
305
306 const bool stereo_eye = camera_background_images_stereo_eye(scene, v3d) == STEREO_LEFT_ID;
307 const char *viewname = (stereo_eye == STEREO_LEFT_ID) ? STEREO_RIGHT_NAME : STEREO_LEFT_NAME;
308 float modelmat[4][4];
309 BKE_camera_multiview_model_matrix(&scene->r, ob, viewname, modelmat);
310
311 LISTBASE_FOREACH (CameraBGImage *, bgpic, &cam->bg_images) {
312 if (bgpic->flag & CAM_BGIMG_FLAG_DISABLED) {
313 continue;
314 }
315
316 float aspect = 1.0;
317 bool use_alpha_premult;
318 bool use_view_transform = false;
319 float mat[4][4];
320
321 /* retrieve the image we want to show, continue to next when no image could be found */
323 bgpic, draw_ctx, pd, &aspect, &use_alpha_premult, &use_view_transform);
324
325 if (tex) {
326 image_camera_background_matrix_get(cam, bgpic, draw_ctx, aspect, mat);
327
328 const bool is_foreground = (bgpic->flag & CAM_BGIMG_FLAG_FOREGROUND) != 0;
329 /* Alpha is clamped just below 1.0 to fix background images to interfere with foreground
330 * images. Without this a background image with 1.0 will be rendered on top of a transparent
331 * foreground image due to the different blending modes they use. */
332 const float color_premult_alpha[4] = {1.0f, 1.0f, 1.0f, std::min(bgpic->alpha, 0.999999f)};
333
334 DRWPass *pass = is_foreground ? (use_view_transform ? psl->image_foreground_scene_ps :
335 psl->image_foreground_ps) :
336 (use_view_transform ? psl->image_background_scene_ps :
338
340 DRWShadingGroup *grp = DRW_shgroup_create(sh, pass);
341 DRW_shgroup_uniform_texture(grp, "imgTexture", tex);
342 DRW_shgroup_uniform_bool_copy(grp, "imgPremultiplied", use_alpha_premult);
343 DRW_shgroup_uniform_bool_copy(grp, "imgAlphaBlend", true);
344 DRW_shgroup_uniform_bool_copy(grp, "isCameraBackground", true);
345 DRW_shgroup_uniform_bool_copy(grp, "depthSet", true);
346 DRW_shgroup_uniform_vec4_copy(grp, "ucolor", color_premult_alpha);
348 }
349 }
350}
351
353{
354 OVERLAY_PassList *psl = vedata->psl;
355 const DRWContextState *draw_ctx = DRW_context_state_get();
356 const RegionView3D *rv3d = draw_ctx->rv3d;
357 GPUTexture *tex = nullptr;
358 Image *ima = static_cast<Image *>(ob->data);
359 float mat[4][4];
360
361 const bool show_frame = BKE_object_empty_image_frame_is_visible_in_view3d(ob, rv3d);
362 const bool show_image = show_frame && BKE_object_empty_image_data_is_visible_in_view3d(ob, rv3d);
363 const bool use_alpha_blend = (ob->empty_image_flag & OB_EMPTY_IMAGE_USE_ALPHA_BLEND) != 0;
364 const bool use_alpha_premult = ima && (ima->alpha_mode == IMA_ALPHA_PREMUL);
365
366 if (!show_frame) {
367 return;
368 }
369
370 {
371 /* Calling 'BKE_image_get_size' may free the texture. Get the size from 'tex' instead,
372 * see: #59347 */
373 int size[2] = {0};
374 if (ima != nullptr) {
375 ImageUser iuser = *ob->iuser;
376 camera_background_images_stereo_setup(draw_ctx->scene, draw_ctx->v3d, ima, &iuser);
377 tex = BKE_image_get_gpu_texture(ima, &iuser);
378 if (tex) {
381 }
382 }
383 CLAMP_MIN(size[0], 1);
384 CLAMP_MIN(size[1], 1);
385
386 float image_aspect[2];
387 overlay_image_calc_aspect(ima, size, image_aspect);
388
389 copy_m4_m4(mat, ob->object_to_world().ptr());
390 mul_v3_fl(mat[0], image_aspect[0] * 0.5f * ob->empty_drawsize);
391 mul_v3_fl(mat[1], image_aspect[1] * 0.5f * ob->empty_drawsize);
392 madd_v3_v3fl(mat[3], mat[0], ob->ima_ofs[0] * 2.0f + 1.0f);
393 madd_v3_v3fl(mat[3], mat[1], ob->ima_ofs[1] * 2.0f + 1.0f);
394 }
395
396 /* Use the actual depth if we are doing depth tests to determine the distance to the object */
397 char depth_mode = DRW_state_is_depth() ? char(OB_EMPTY_IMAGE_DEPTH_DEFAULT) :
399 DRWPass *pass = nullptr;
400 if ((ob->dtx & OB_DRAW_IN_FRONT) != 0) {
401 /* Object In Front overrides image empty depth mode. */
402 pass = psl->image_empties_front_ps;
403 }
404 else {
405 switch (depth_mode) {
407 pass = (use_alpha_blend) ? psl->image_empties_blend_ps : psl->image_empties_ps;
408 break;
410 pass = psl->image_empties_back_ps;
411 break;
413 pass = psl->image_empties_front_ps;
414 break;
415 }
416 }
417
418 if (show_frame) {
420 float *color;
421 DRW_object_wire_theme_get(ob, draw_ctx->view_layer, &color);
422 OVERLAY_empty_shape(cb, mat, 1.0f, OB_EMPTY_IMAGE, color);
423 }
424
425 if (show_image && tex && ((ob->color[3] > 0.0f) || !use_alpha_blend)) {
427 DRWShadingGroup *grp = DRW_shgroup_create(sh, pass);
428 DRW_shgroup_uniform_texture(grp, "imgTexture", tex);
429 DRW_shgroup_uniform_bool_copy(grp, "imgPremultiplied", use_alpha_premult);
430 DRW_shgroup_uniform_bool_copy(grp, "imgAlphaBlend", use_alpha_blend);
431 DRW_shgroup_uniform_bool_copy(grp, "isCameraBackground", false);
432 DRW_shgroup_uniform_bool_copy(grp, "depthSet", depth_mode != OB_EMPTY_IMAGE_DEPTH_DEFAULT);
433 DRW_shgroup_uniform_vec4_copy(grp, "ucolor", ob->color);
435 }
436}
437
446
461
469
471{
472 OVERLAY_PassList *psl = vedata->psl;
473 OVERLAY_PrivateData *pd = vedata->stl->pd;
474
476
479
480 DRW_view_set_active(nullptr);
481}
482
Camera data-block and utility functions.
void BKE_camera_multiview_model_matrix(const struct RenderData *rd, const struct Object *camera, const char *viewname, float r_modelmat[4][4])
void BKE_camera_view_frame(const struct Scene *scene, const struct Camera *camera, float r_vec[4][3])
void BKE_image_user_frame_calc(Image *ima, ImageUser *iuser, int cfra)
GPUTexture * BKE_image_get_gpu_viewer_texture(Image *image, ImageUser *iuser)
Definition image_gpu.cc:481
bool BKE_image_is_stereo(const Image *ima)
GPUTexture * BKE_image_get_gpu_texture(Image *image, ImageUser *iuser)
Definition image_gpu.cc:476
void BKE_image_multiview_index(const Image *ima, ImageUser *iuser)
void BKE_movieclip_user_set_frame(struct MovieClipUser *user, int framenr)
void BKE_movieclip_get_size(struct MovieClip *clip, const struct MovieClipUser *user, int *r_width, int *r_height)
struct GPUTexture * BKE_movieclip_get_gpu_texture(struct MovieClip *clip, struct MovieClipUser *cuser)
void BKE_movieclip_free_gputexture(struct MovieClip *clip)
General operations, lookup, etc. for blender objects.
MovieClip * BKE_object_movieclip_get(Scene *scene, const Object *ob, bool use_default)
bool BKE_object_empty_image_frame_is_visible_in_view3d(const Object *ob, const RegionView3D *rv3d)
bool BKE_object_empty_image_data_is_visible_in_view3d(const Object *ob, const RegionView3D *rv3d)
#define LISTBASE_FOREACH(type, var, list)
void BLI_addtail(struct ListBase *listbase, void *vlink) ATTR_NONNULL(1)
Definition listbase.cc:110
struct LinkData * BLI_genericNodeN(void *data)
Definition listbase.cc:909
void * BLI_pophead(ListBase *listbase) ATTR_NONNULL(1)
Definition listbase.cc:251
MINLINE float max_ff(float a, float b)
MINLINE float min_ff(float a, float b)
void unit_m4(float m[4][4])
Definition rct.c:1127
#define mul_m4_series(...)
void copy_m4_m4(float m1[4][4], const float m2[4][4])
void axis_angle_to_mat4_single(float R[4][4], char axis, float angle)
MINLINE void madd_v3_v3fl(float r[3], const float a[3], float f)
MINLINE void mul_v2_fl(float r[2], float f)
MINLINE void mul_v3_fl(float r[3], float f)
#define CLAMP_MIN(a, b)
float DEG_get_ctime(const Depsgraph *graph)
@ CAM_BGIMG_FLAG_FLIP_X
@ CAM_BGIMG_FLAG_FLIP_Y
@ CAM_BGIMG_FLAG_CAMERA_CROP
@ CAM_BGIMG_FLAG_CAMERACLIP
@ CAM_BGIMG_FLAG_CAMERA_ASPECT
@ CAM_BGIMG_FLAG_DISABLED
@ CAM_BGIMG_FLAG_FOREGROUND
@ CAM_BGIMG_SOURCE_IMAGE
@ CAM_BGIMG_SOURCE_MOVIE
@ CAM_ORTHO
@ IMA_SHOW_STEREO
@ IMA_SRC_SEQUENCE
@ IMA_USER_FRAME_IN_RANGE
@ IMA_VIEW_AS_RENDER
@ IMA_ALPHA_PREMUL
@ OB_EMPTY_IMAGE_DEPTH_DEFAULT
@ OB_EMPTY_IMAGE_DEPTH_FRONT
@ OB_EMPTY_IMAGE_DEPTH_BACK
@ OB_DRAW_IN_FRONT
@ OB_EMPTY_IMAGE
@ OB_EMPTY_IMAGE_USE_ALPHA_BLEND
#define STEREO_LEFT_NAME
@ R_MULTIVIEW
#define STEREO_RIGHT_NAME
eStereoViews
@ STEREO_LEFT_ID
@ STEREO_3D_ID
#define DRW_PASS_CREATE(pass, state)
#define DRW_shgroup_call_obmat(shgroup, geom, obmat)
void GPU_framebuffer_bind(GPUFrameBuffer *framebuffer)
int GPU_texture_original_height(const GPUTexture *texture)
int GPU_texture_original_width(const GPUTexture *texture)
Contains defines and structs used throughout the imbuf module.
Group Output data from inside of a node group A color picker Mix two input colors RGB to Convert a color s luminance to a grayscale value Generate a normal vector and a dot product Brightness Control the brightness and contrast of the input color Vector Map input vector components with curves Camera Retrieve information about the camera and how it relates to the current shading point s position Clamp a value between a minimum and a maximum Vector Perform vector math operation Invert Invert a color
struct GPUShader GPUShader
#define fabsf(x)
blender::gpu::Batch * DRW_cache_quad_get()
int DRW_object_wire_theme_get(Object *ob, ViewLayer *view_layer, float **r_color)
DRWView * DRW_view_create_with_zoffset(const DRWView *parent_view, const RegionView3D *rv3d, float offset)
DefaultFramebufferList * DRW_viewport_framebuffer_list_get()
const DRWContextState * DRW_context_state_get()
bool DRW_state_is_fbo()
bool DRW_state_is_select()
bool DRW_state_is_depth()
const DRWView * DRW_view_default_get()
DRWShadingGroup * DRW_shgroup_create(GPUShader *shader, DRWPass *pass)
void DRW_shgroup_uniform_texture(DRWShadingGroup *shgroup, const char *name, const GPUTexture *tex)
void DRW_pass_sort_shgroup_z(DRWPass *pass)
bool DRW_pass_is_empty(DRWPass *pass)
void DRW_shgroup_uniform_vec4_copy(DRWShadingGroup *shgroup, const char *name, const float *value)
void DRW_shgroup_uniform_bool_copy(DRWShadingGroup *shgroup, const char *name, const bool value)
void DRW_draw_pass(DRWPass *pass)
void DRW_view_set_active(const DRWView *view)
DRWState
Definition draw_state.hh:25
@ DRW_STATE_DEPTH_LESS
Definition draw_state.hh:37
@ DRW_STATE_WRITE_DEPTH
Definition draw_state.hh:29
@ DRW_STATE_WRITE_COLOR
Definition draw_state.hh:30
@ DRW_STATE_BLEND_ALPHA_UNDER_PREMUL
Definition draw_state.hh:65
@ DRW_STATE_DEPTH_LESS_EQUAL
Definition draw_state.hh:38
@ DRW_STATE_BLEND_ALPHA_PREMUL
Definition draw_state.hh:57
@ DRW_STATE_DEPTH_GREATER
Definition draw_state.hh:40
draw_view push_constant(Type::INT, "radiance_src") .push_constant(Type capture_info_buf storage_buf(1, Qualifier::READ, "ObjectBounds", "bounds_buf[]") .push_constant(Type draw_view int
void MEM_freeN(void *vmemh)
Definition mallocn.cc:105
static ulong state[N]
OVERLAY_ExtraCallBuffers * OVERLAY_extra_call_buffer_get(OVERLAY_Data *vedata, Object *ob)
void OVERLAY_empty_shape(OVERLAY_ExtraCallBuffers *cb, const float mat[4][4], const float draw_size, const char draw_type, const float color[4])
static eStereoViews camera_background_images_stereo_eye(const Scene *scene, const View3D *v3d)
static void OVERLAY_image_free_movieclips_textures(OVERLAY_Data *data)
void OVERLAY_image_cache_init(OVERLAY_Data *vedata)
void OVERLAY_image_background_draw(OVERLAY_Data *vedata)
void OVERLAY_image_in_front_draw(OVERLAY_Data *vedata)
void OVERLAY_image_scene_background_draw(OVERLAY_Data *vedata)
void OVERLAY_image_camera_cache_populate(OVERLAY_Data *vedata, Object *ob)
void OVERLAY_image_cache_finish(OVERLAY_Data *vedata)
static void overlay_image_calc_aspect(Image *ima, const int size[2], float r_image_aspect[2])
void OVERLAY_image_draw(OVERLAY_Data *vedata)
static void image_camera_background_matrix_get(const Camera *cam, const CameraBGImage *bgpic, const DRWContextState *draw_ctx, const float image_aspect, float rmat[4][4])
static GPUTexture * image_camera_background_texture_get(CameraBGImage *bgpic, const DRWContextState *draw_ctx, OVERLAY_PrivateData *pd, float *r_aspect, bool *r_use_alpha_premult, bool *r_use_view_transform)
void OVERLAY_image_empty_cache_populate(OVERLAY_Data *vedata, Object *ob)
void OVERLAY_image_init(OVERLAY_Data *vedata)
static void camera_background_images_stereo_setup(const Scene *scene, const View3D *v3d, Image *ima, ImageUser *iuser)
GPUShader * OVERLAY_shader_image()
struct MovieClip * clip
struct ImageUser iuser
struct MovieClipUser cuser
struct Image * ima
struct ListBase bg_images
float ortho_scale
ViewLayer * view_layer
Depsgraph * depsgraph
RegionView3D * rv3d
GPUFrameBuffer * default_fb
struct Scene * scene
char alpha_mode
OVERLAY_PassList * psl
OVERLAY_StorageList * stl
DRWPass * image_background_scene_ps
DRWPass * image_empties_front_ps
DRWPass * image_foreground_scene_ps
DRWPass * image_background_ps
DRWPass * image_empties_blend_ps
DRWPass * image_foreground_ps
DRWPass * image_empties_back_ps
OVERLAY_PrivateData * pd
ImageUser * iuser
char empty_image_flag
float empty_drawsize
float color[4]
char empty_image_depth
float ima_ofs[2]
char multiview_eye
char stereo3d_camera