Blender  V2.93
overlay_grid.c
Go to the documentation of this file.
1 /*
2  * This program is free software; you can redistribute it and/or
3  * modify it under the terms of the GNU General Public License
4  * as published by the Free Software Foundation; either version 2
5  * of the License, or (at your option) any later version.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * along with this program; if not, write to the Free Software Foundation,
14  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
15  *
16  * Copyright 2019, Blender Foundation.
17  */
18 
23 #include "DRW_render.h"
24 
25 #include "DNA_camera_types.h"
26 
27 #include "DEG_depsgraph_query.h"
28 
29 #include "ED_image.h"
30 #include "ED_view3d.h"
31 
32 #include "UI_resources.h"
33 
34 #include "overlay_private.h"
35 
36 enum {
37  SHOW_AXIS_X = (1 << 0),
38  SHOW_AXIS_Y = (1 << 1),
39  SHOW_AXIS_Z = (1 << 2),
40  SHOW_GRID = (1 << 3),
41  PLANE_XY = (1 << 4),
42  PLANE_XZ = (1 << 5),
43  PLANE_YZ = (1 << 6),
44  CLIP_ZPOS = (1 << 7),
45  CLIP_ZNEG = (1 << 8),
46  GRID_BACK = (1 << 9),
47  GRID_CAMERA = (1 << 10),
48  PLANE_IMAGE = (1 << 11),
49 };
50 
52 {
53  OVERLAY_PrivateData *pd = vedata->stl->pd;
54  OVERLAY_ShadingData *shd = &pd->shdata;
55  const DRWContextState *draw_ctx = DRW_context_state_get();
56 
57  shd->grid_flag = 0;
58  shd->zneg_flag = 0;
59  shd->zpos_flag = 0;
60  shd->grid_line_size = max_ff(0.0f, U.pixelsize - 1.0f) * 0.5f;
61 
62  if (pd->space_type == SPACE_IMAGE) {
63  SpaceImage *sima = (SpaceImage *)draw_ctx->space_data;
65  shd->grid_distance = 1.0f;
67  shd->grid_size, (float)sima->tile_grid_shape[0], (float)sima->tile_grid_shape[1], 1.0f);
68  for (int step = 0; step < 8; step++) {
69  shd->grid_steps[step] = powf(4, step) * (1.0f / 16.0f);
70  }
71  return;
72  }
73 
74  View3D *v3d = draw_ctx->v3d;
75  Scene *scene = draw_ctx->scene;
76  RegionView3D *rv3d = draw_ctx->rv3d;
77 
78  const bool show_axis_x = (pd->v3d_gridflag & V3D_SHOW_X) != 0;
79  const bool show_axis_y = (pd->v3d_gridflag & V3D_SHOW_Y) != 0;
80  const bool show_axis_z = (pd->v3d_gridflag & V3D_SHOW_Z) != 0;
81  const bool show_floor = (pd->v3d_gridflag & V3D_SHOW_FLOOR) != 0;
82  const bool show_ortho_grid = (pd->v3d_gridflag & V3D_SHOW_ORTHO_GRID) != 0;
83 
86  return;
87  }
88 
89  float viewinv[4][4], wininv[4][4];
90  float viewmat[4][4], winmat[4][4];
91  DRW_view_winmat_get(NULL, winmat, false);
92  DRW_view_winmat_get(NULL, wininv, true);
93  DRW_view_viewmat_get(NULL, viewmat, false);
94  DRW_view_viewmat_get(NULL, viewinv, true);
95 
96  /* If perspective view or non-axis aligned view. */
97  if (winmat[3][3] == 0.0f || rv3d->view == RV3D_VIEW_USER) {
98  if (show_axis_x) {
99  shd->grid_flag |= PLANE_XY | SHOW_AXIS_X;
100  }
101  if (show_axis_y) {
102  shd->grid_flag |= PLANE_XY | SHOW_AXIS_Y;
103  }
104  if (show_floor) {
105  shd->grid_flag |= PLANE_XY | SHOW_GRID;
106  }
107  }
108  else {
109  if (show_ortho_grid && ELEM(rv3d->view, RV3D_VIEW_RIGHT, RV3D_VIEW_LEFT)) {
111  }
112  else if (show_ortho_grid && ELEM(rv3d->view, RV3D_VIEW_TOP, RV3D_VIEW_BOTTOM)) {
114  }
115  else if (show_ortho_grid && ELEM(rv3d->view, RV3D_VIEW_FRONT, RV3D_VIEW_BACK)) {
117  }
118  }
119 
120  shd->grid_axes[0] = (float)((shd->grid_flag & (PLANE_XZ | PLANE_XY)) != 0);
121  shd->grid_axes[1] = (float)((shd->grid_flag & (PLANE_YZ | PLANE_XY)) != 0);
122  shd->grid_axes[2] = (float)((shd->grid_flag & (PLANE_YZ | PLANE_XZ)) != 0);
123 
124  /* Z axis if needed */
125  if (((rv3d->view == RV3D_VIEW_USER) || (rv3d->persp != RV3D_ORTHO)) && show_axis_z) {
126  shd->zpos_flag = SHOW_AXIS_Z;
127 
128  float zvec[3], campos[3];
129  negate_v3_v3(zvec, viewinv[2]);
130  copy_v3_v3(campos, viewinv[3]);
131 
132  /* z axis : chose the most facing plane */
133  if (fabsf(zvec[0]) < fabsf(zvec[1])) {
134  shd->zpos_flag |= PLANE_XZ;
135  }
136  else {
137  shd->zpos_flag |= PLANE_YZ;
138  }
139 
140  shd->zneg_flag = shd->zpos_flag;
141 
142  /* Persp : If camera is below floor plane, we switch clipping
143  * Ortho : If eye vector is looking up, we switch clipping */
144  if (((winmat[3][3] == 0.0f) && (campos[2] > 0.0f)) ||
145  ((winmat[3][3] != 0.0f) && (zvec[2] < 0.0f))) {
146  shd->zpos_flag |= CLIP_ZPOS;
147  shd->zneg_flag |= CLIP_ZNEG;
148  }
149  else {
150  shd->zpos_flag |= CLIP_ZNEG;
151  shd->zneg_flag |= CLIP_ZPOS;
152  }
153 
154  shd->zplane_axes[0] = (float)((shd->zpos_flag & (PLANE_XZ | PLANE_XY)) != 0);
155  shd->zplane_axes[1] = (float)((shd->zpos_flag & (PLANE_YZ | PLANE_XY)) != 0);
156  shd->zplane_axes[2] = (float)((shd->zpos_flag & (PLANE_YZ | PLANE_XZ)) != 0);
157  }
158  else {
159  shd->zneg_flag = shd->zpos_flag = CLIP_ZNEG | CLIP_ZPOS;
160  }
161 
162  float dist;
163  if (rv3d->persp == RV3D_CAMOB && v3d->camera && v3d->camera->type == OB_CAMERA) {
164  Object *camera_object = DEG_get_evaluated_object(draw_ctx->depsgraph, v3d->camera);
165  dist = ((Camera *)(camera_object->data))->clip_end;
166  shd->grid_flag |= GRID_CAMERA;
167  shd->zneg_flag |= GRID_CAMERA;
168  shd->zpos_flag |= GRID_CAMERA;
169  }
170  else {
171  dist = v3d->clip_end;
172  }
173 
174  if (winmat[3][3] == 0.0f) {
175  copy_v3_fl(shd->grid_size, dist);
176  }
177  else {
178  float viewdist = 1.0f / min_ff(fabsf(winmat[0][0]), fabsf(winmat[1][1]));
179  copy_v3_fl(shd->grid_size, viewdist * dist);
180  }
181 
182  shd->grid_distance = dist / 2.0f;
183 
184  ED_view3d_grid_steps(scene, v3d, rv3d, shd->grid_steps);
185 }
186 
188 {
189  OVERLAY_StorageList *stl = vedata->stl;
190  OVERLAY_PrivateData *pd = stl->pd;
191  OVERLAY_ShadingData *shd = &pd->shdata;
192 
193  OVERLAY_PassList *psl = vedata->psl;
195 
196  psl->grid_ps = NULL;
197 
198  if ((shd->grid_flag == 0 && shd->zpos_flag == 0) || !DRW_state_is_fbo()) {
199  return;
200  }
201 
204  DRWShadingGroup *grp;
205  GPUShader *sh;
206  struct GPUBatch *geom = DRW_cache_grid_get();
207 
208  if (pd->space_type == SPACE_IMAGE) {
209  float mat[4][4];
210 
211  /* add quad background */
213  grp = DRW_shgroup_create(sh, psl->grid_ps);
214  float color_back[4];
216  DRW_shgroup_uniform_vec4_copy(grp, "color", color_back);
217  unit_m4(mat);
218  mat[0][0] = shd->grid_size[0];
219  mat[1][1] = shd->grid_size[1];
220  mat[2][2] = shd->grid_size[2];
222  }
223 
224  sh = OVERLAY_shader_grid();
225 
226  /* Create 3 quads to render ordered transparency Z axis */
227  grp = DRW_shgroup_create(sh, psl->grid_ps);
228  DRW_shgroup_uniform_int(grp, "gridFlag", &shd->zneg_flag, 1);
229  DRW_shgroup_uniform_vec3(grp, "planeAxes", shd->zplane_axes, 1);
230  DRW_shgroup_uniform_float(grp, "gridDistance", &shd->grid_distance, 1);
231  DRW_shgroup_uniform_float_copy(grp, "lineKernel", shd->grid_line_size);
232  DRW_shgroup_uniform_vec3(grp, "gridSize", shd->grid_size, 1);
233  DRW_shgroup_uniform_block(grp, "globalsBlock", G_draw.block_ubo);
234  DRW_shgroup_uniform_texture_ref(grp, "depthBuffer", &dtxl->depth);
235  if (shd->zneg_flag & SHOW_AXIS_Z) {
236  DRW_shgroup_call(grp, geom, NULL);
237  }
238 
239  grp = DRW_shgroup_create(sh, psl->grid_ps);
240  DRW_shgroup_uniform_int(grp, "gridFlag", &shd->grid_flag, 1);
241  DRW_shgroup_uniform_vec3(grp, "planeAxes", shd->grid_axes, 1);
242  DRW_shgroup_uniform_block(grp, "globalsBlock", G_draw.block_ubo);
243  DRW_shgroup_uniform_texture_ref(grp, "depthBuffer", &dtxl->depth);
244  DRW_shgroup_uniform_float(grp, "gridSteps", shd->grid_steps, ARRAY_SIZE(shd->grid_steps));
245  if (shd->grid_flag) {
246  DRW_shgroup_call(grp, geom, NULL);
247  }
248 
249  grp = DRW_shgroup_create(sh, psl->grid_ps);
250  DRW_shgroup_uniform_int(grp, "gridFlag", &shd->zpos_flag, 1);
251  DRW_shgroup_uniform_vec3(grp, "planeAxes", shd->zplane_axes, 1);
252  DRW_shgroup_uniform_block(grp, "globalsBlock", G_draw.block_ubo);
253  DRW_shgroup_uniform_texture_ref(grp, "depthBuffer", &dtxl->depth);
254  if (shd->zpos_flag & SHOW_AXIS_Z) {
255  DRW_shgroup_call(grp, geom, NULL);
256  }
257 
258  if (pd->space_type == SPACE_IMAGE) {
259  float theme_color[4];
260  UI_GetThemeColorShade4fv(TH_BACK, 60, theme_color);
261  srgb_to_linearrgb_v4(theme_color, theme_color);
262 
263  float mat[4][4];
264  /* add wire border */
266  grp = DRW_shgroup_create(sh, psl->grid_ps);
267  DRW_shgroup_uniform_vec4_copy(grp, "color", theme_color);
268  unit_m4(mat);
269  for (int x = 0; x < shd->grid_size[0]; x++) {
270  mat[3][0] = x;
271  for (int y = 0; y < shd->grid_size[1]; y++) {
272  mat[3][1] = y;
274  }
275  }
276  }
277 }
278 
280 {
281  OVERLAY_PassList *psl = vedata->psl;
282 
283  if (psl->grid_ps) {
284  DRW_draw_pass(psl->grid_ps);
285  }
286 }
typedef float(TangentPoint)[2]
MINLINE float max_ff(float a, float b)
MINLINE float min_ff(float a, float b)
MINLINE void srgb_to_linearrgb_v4(float linear[4], const float srgb[4])
void unit_m4(float m[4][4])
Definition: rct.c:1140
void interp_v4_v4v4(float r[4], const float a[4], const float b[4], const float t)
Definition: math_vector.c:58
MINLINE void copy_v3_v3(float r[3], const float a[3])
MINLINE void negate_v3_v3(float r[3], const float a[3])
MINLINE void copy_v3_fl3(float v[3], float x, float y, float z)
MINLINE void copy_v3_fl(float r[3], float f)
#define ARRAY_SIZE(arr)
#define ELEM(...)
struct Object * DEG_get_evaluated_object(const struct Depsgraph *depsgraph, struct Object *object)
@ OB_CAMERA
@ SPACE_IMAGE
#define V3D_SHOW_ORTHO_GRID
#define RV3D_CAMOB
#define RV3D_VIEW_BACK
#define V3D_SHOW_Z
#define RV3D_VIEW_BOTTOM
#define V3D_SHOW_Y
#define RV3D_VIEW_LEFT
#define RV3D_VIEW_RIGHT
#define V3D_SHOW_X
#define RV3D_VIEW_TOP
#define RV3D_VIEW_USER
#define RV3D_VIEW_FRONT
#define V3D_SHOW_FLOOR
#define RV3D_ORTHO
DRWState
Definition: DRW_render.h:312
@ DRW_STATE_BLEND_ALPHA
Definition: DRW_render.h:340
@ DRW_STATE_WRITE_COLOR
Definition: DRW_render.h:315
#define DRW_PASS_CREATE(pass, state)
Definition: DRW_render.h:593
#define DRW_shgroup_call_obmat(shgroup, geom, obmat)
Definition: DRW_render.h:424
#define DRW_shgroup_call(shgroup, geom, ob)
Definition: DRW_render.h:420
bool ED_space_image_has_buffer(struct SpaceImage *sima)
Definition: image_edit.c:202
void ED_view3d_grid_steps(const struct Scene *scene, struct View3D *v3d, struct RegionView3D *rv3d, float *r_grid_steps)
GPUBatch
Definition: GPU_batch.h:93
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum const void *lists _GL_VOID_RET _GL_VOID const GLdouble *equation _GL_VOID_RET _GL_VOID GLdouble GLdouble blue _GL_VOID_RET _GL_VOID GLfloat GLfloat blue _GL_VOID_RET _GL_VOID GLint GLint blue _GL_VOID_RET _GL_VOID GLshort GLshort blue _GL_VOID_RET _GL_VOID GLubyte GLubyte blue _GL_VOID_RET _GL_VOID GLuint GLuint blue _GL_VOID_RET _GL_VOID GLushort GLushort blue _GL_VOID_RET _GL_VOID GLbyte GLbyte GLbyte alpha _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble alpha _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat alpha _GL_VOID_RET _GL_VOID GLint GLint GLint alpha _GL_VOID_RET _GL_VOID GLshort GLshort GLshort alpha _GL_VOID_RET _GL_VOID GLubyte GLubyte GLubyte alpha _GL_VOID_RET _GL_VOID GLuint GLuint GLuint alpha _GL_VOID_RET _GL_VOID GLushort GLushort GLushort alpha _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLint y
struct GPUShader GPUShader
Definition: GPU_shader.h:33
@ TH_BACK
Definition: UI_resources.h:55
void UI_GetThemeColorShade4fv(int colorid, int offset, float col[4])
Definition: resources.c:1359
unsigned int U
Definition: btGjkEpa3.h:78
Scene scene
GPUBatch * DRW_cache_quad_get(void)
Definition: draw_cache.c:392
GPUBatch * DRW_cache_grid_get(void)
Definition: draw_cache.c:434
GPUBatch * DRW_cache_quad_wires_get(void)
Definition: draw_cache.c:413
struct DRW_Global G_draw
Definition: draw_common.c:45
bool DRW_state_is_fbo(void)
const DRWContextState * DRW_context_state_get(void)
DefaultTextureList * DRW_viewport_texture_list_get(void)
Definition: draw_manager.c:702
void DRW_shgroup_uniform_float_copy(DRWShadingGroup *shgroup, const char *name, const float value)
void DRW_shgroup_uniform_block(DRWShadingGroup *shgroup, const char *name, const GPUUniformBuf *ubo)
void DRW_shgroup_uniform_vec3(DRWShadingGroup *shgroup, const char *name, const float *value, int arraysize)
void DRW_view_winmat_get(const DRWView *view, float mat[4][4], bool inverse)
DRWShadingGroup * DRW_shgroup_create(struct GPUShader *shader, DRWPass *pass)
void DRW_shgroup_uniform_int(DRWShadingGroup *shgroup, const char *name, const int *value, int arraysize)
void DRW_shgroup_uniform_vec4_copy(DRWShadingGroup *shgroup, const char *name, const float *value)
void DRW_shgroup_uniform_texture_ref(DRWShadingGroup *shgroup, const char *name, GPUTexture **tex)
void DRW_shgroup_uniform_float(DRWShadingGroup *shgroup, const char *name, const float *value, int arraysize)
void DRW_view_viewmat_get(const DRWView *view, float mat[4][4], bool inverse)
void DRW_draw_pass(DRWPass *pass)
#define powf(x, y)
#define fabsf(x)
static ulong state[N]
void OVERLAY_grid_draw(OVERLAY_Data *vedata)
Definition: overlay_grid.c:279
void OVERLAY_grid_cache_init(OVERLAY_Data *vedata)
Definition: overlay_grid.c:187
@ CLIP_ZNEG
Definition: overlay_grid.c:45
@ SHOW_GRID
Definition: overlay_grid.c:40
@ SHOW_AXIS_X
Definition: overlay_grid.c:37
@ PLANE_IMAGE
Definition: overlay_grid.c:48
@ SHOW_AXIS_Z
Definition: overlay_grid.c:39
@ PLANE_YZ
Definition: overlay_grid.c:43
@ SHOW_AXIS_Y
Definition: overlay_grid.c:38
@ GRID_BACK
Definition: overlay_grid.c:46
@ PLANE_XZ
Definition: overlay_grid.c:42
@ PLANE_XY
Definition: overlay_grid.c:41
@ GRID_CAMERA
Definition: overlay_grid.c:47
@ CLIP_ZPOS
Definition: overlay_grid.c:44
void OVERLAY_grid_init(OVERLAY_Data *vedata)
Definition: overlay_grid.c:51
GPUShader * OVERLAY_shader_grid(void)
GPUShader * OVERLAY_shader_grid_image(void)
struct Scene * scene
Definition: DRW_render.h:745
struct SpaceLink * space_data
Definition: DRW_render.h:743
struct Depsgraph * depsgraph
Definition: DRW_render.h:753
struct View3D * v3d
Definition: DRW_render.h:742
struct RegionView3D * rv3d
Definition: DRW_render.h:741
GlobalsUboStorage block
Definition: draw_common.h:208
struct GPUUniformBuf * block_ubo
Definition: draw_common.h:210
struct GPUTexture * depth
float colorGrid[4]
Definition: draw_common.h:133
float colorBackground[4]
Definition: draw_common.h:82
OVERLAY_PassList * psl
OVERLAY_StorageList * stl
OVERLAY_ShadingData shdata
struct OVERLAY_PrivateData * pd
void * data
int tile_grid_shape[2]
float clip_end
struct Object * camera