Blender  V2.93
gpencil_render.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 2017, Blender Foundation.
17  */
18 
22 #include "BLI_rect.h"
23 
24 #include "DRW_render.h"
25 
26 #include "BKE_object.h"
27 
28 #include "DNA_gpencil_types.h"
29 
30 #include "DEG_depsgraph_query.h"
31 
32 #include "RE_pipeline.h"
33 
34 #include "gpencil_engine.h"
35 
36 /* init render data */
38  RenderEngine *engine,
39  struct RenderLayer *render_layer,
40  const Depsgraph *depsgraph,
41  const rcti *rect)
42 {
43  GPENCIL_FramebufferList *fbl = vedata->fbl;
44  GPENCIL_TextureList *txl = vedata->txl;
45 
47  const float *viewport_size = DRW_viewport_size_get();
48  const int size[2] = {(int)viewport_size[0], (int)viewport_size[1]};
49 
50  /* Set the perspective & view matrix. */
51  float winmat[4][4], viewmat[4][4], viewinv[4][4];
52 
53  struct Object *camera = DEG_get_evaluated_object(depsgraph, RE_GetCamera(engine->re));
54  RE_GetCameraWindow(engine->re, camera, winmat);
55  RE_GetCameraModelMatrix(engine->re, camera, viewinv);
56 
57  invert_m4_m4(viewmat, viewinv);
58 
59  DRWView *view = DRW_view_create(viewmat, winmat, NULL, NULL, NULL);
62 
63  /* Create depth texture & color texture from render result. */
64  const char *viewname = RE_GetActiveRenderView(engine->re);
65  RenderPass *rpass_z_src = RE_pass_find_by_name(render_layer, RE_PASSNAME_Z, viewname);
66  RenderPass *rpass_col_src = RE_pass_find_by_name(render_layer, RE_PASSNAME_COMBINED, viewname);
67 
68  float *pix_z = (rpass_z_src) ? rpass_z_src->rect : NULL;
69  float *pix_col = (rpass_col_src) ? rpass_col_src->rect : NULL;
70 
71  if (!pix_z || !pix_col) {
73  "Warning: To render grease pencil, enable Combined and Z passes.");
74  }
75 
76  if (pix_z) {
77  /* Depth need to be remapped to [0..1] range. */
78  pix_z = MEM_dupallocN(pix_z);
79 
80  int pix_ct = rpass_z_src->rectx * rpass_z_src->recty;
81 
83  for (int i = 0; i < pix_ct; i++) {
84  pix_z[i] = (-winmat[3][2] / -pix_z[i]) - winmat[2][2];
85  pix_z[i] = clamp_f(pix_z[i] * 0.5f + 0.5f, 0.0f, 1.0f);
86  }
87  }
88  else {
89  /* Keep in mind, near and far distance are negatives. */
90  float near = DRW_view_near_distance_get(view);
91  float far = DRW_view_far_distance_get(view);
92  float range_inv = 1.0f / fabsf(far - near);
93  for (int i = 0; i < pix_ct; i++) {
94  pix_z[i] = (pix_z[i] + near) * range_inv;
95  pix_z[i] = clamp_f(pix_z[i], 0.0f, 1.0f);
96  }
97  }
98  }
99 
100  const bool do_region = (scene->r.mode & R_BORDER) != 0;
101  const bool do_clear_z = !pix_z || do_region;
102  const bool do_clear_col = !pix_col || do_region;
103 
104  /* FIXME(fclem): we have a precision loss in the depth buffer because of this re-upload.
105  * Find where it comes from! */
106  /* In multi view render the textures can be reused. */
107  if (txl->render_depth_tx && !do_clear_z) {
109  }
110  else {
112  size[0], size[1], GPU_DEPTH_COMPONENT24, 0, do_region ? NULL : pix_z);
113  }
114  if (txl->render_color_tx && !do_clear_col) {
116  }
117  else {
119  size[0], size[1], GPU_RGBA16F, 0, do_region ? NULL : pix_col);
120  }
121 
122  GPU_framebuffer_ensure_config(&fbl->render_fb,
123  {
124  GPU_ATTACHMENT_TEXTURE(txl->render_depth_tx),
125  GPU_ATTACHMENT_TEXTURE(txl->render_color_tx),
126  });
127 
128  if (do_clear_z || do_clear_col) {
129  /* To avoid unpredictable result, clear buffers that have not be initialized. */
131  if (do_clear_col) {
132  const float clear_col[4] = {0.0f, 0.0f, 0.0f, 0.0f};
133  GPU_framebuffer_clear_color(fbl->render_fb, clear_col);
134  }
135  if (do_clear_z) {
136  GPU_framebuffer_clear_depth(fbl->render_fb, 1.0f);
137  }
138  }
139 
140  if (do_region) {
141  int x = rect->xmin;
142  int y = rect->ymin;
143  int w = BLI_rcti_size_x(rect);
144  int h = BLI_rcti_size_y(rect);
145  if (pix_col) {
146  GPU_texture_update_sub(txl->render_color_tx, GPU_DATA_FLOAT, pix_col, x, y, 0, w, h, 0);
147  }
148  if (pix_z) {
149  GPU_texture_update_sub(txl->render_depth_tx, GPU_DATA_FLOAT, pix_z, x, y, 0, w, h, 0);
150  }
151  }
152 
153  MEM_SAFE_FREE(pix_z);
154 }
155 
156 /* render all objects and select only grease pencil */
157 static void GPENCIL_render_cache(void *vedata,
158  struct Object *ob,
159  struct RenderEngine *UNUSED(engine),
161 {
162  if (ob && ELEM(ob->type, OB_GPENCIL, OB_LAMP)) {
164  GPENCIL_cache_populate(vedata, ob);
165  }
166  }
167 }
168 
169 static void GPENCIL_render_result_z(struct RenderLayer *rl,
170  const char *viewname,
171  GPENCIL_Data *vedata,
172  const rcti *rect)
173 {
174  const DRWContextState *draw_ctx = DRW_context_state_get();
175  ViewLayer *view_layer = draw_ctx->view_layer;
176 
177  if ((view_layer->passflag & SCE_PASS_Z) != 0) {
178  RenderPass *rp = RE_pass_find_by_name(rl, RE_PASSNAME_Z, viewname);
179 
181  rect->xmin,
182  rect->ymin,
183  BLI_rcti_size_x(rect),
184  BLI_rcti_size_y(rect),
186  rp->rect);
187 
188  float winmat[4][4];
189  DRW_view_winmat_get(NULL, winmat, false);
190 
191  int pix_ct = BLI_rcti_size_x(rect) * BLI_rcti_size_y(rect);
192 
193  /* Convert ogl depth [0..1] to view Z [near..far] */
195  for (int i = 0; i < pix_ct; i++) {
196  if (rp->rect[i] == 1.0f) {
197  rp->rect[i] = 1e10f; /* Background */
198  }
199  else {
200  rp->rect[i] = rp->rect[i] * 2.0f - 1.0f;
201  rp->rect[i] = winmat[3][2] / (rp->rect[i] + winmat[2][2]);
202  }
203  }
204  }
205  else {
206  /* Keep in mind, near and far distance are negatives. */
207  float near = DRW_view_near_distance_get(NULL);
208  float far = DRW_view_far_distance_get(NULL);
209  float range = fabsf(far - near);
210 
211  for (int i = 0; i < pix_ct; i++) {
212  if (rp->rect[i] == 1.0f) {
213  rp->rect[i] = 1e10f; /* Background */
214  }
215  else {
216  rp->rect[i] = rp->rect[i] * range - near;
217  }
218  }
219  }
220  }
221 }
222 
224  const char *viewname,
225  GPENCIL_Data *vedata,
226  const rcti *rect)
227 {
229  GPENCIL_FramebufferList *fbl = ((GPENCIL_Data *)vedata)->fbl;
230 
233  rect->xmin,
234  rect->ymin,
235  BLI_rcti_size_x(rect),
236  BLI_rcti_size_y(rect),
237  4,
238  0,
240  rp->rect);
241 }
242 
243 void GPENCIL_render_to_image(void *ved,
244  RenderEngine *engine,
245  struct RenderLayer *render_layer,
246  const rcti *rect)
247 {
248  GPENCIL_Data *vedata = (GPENCIL_Data *)ved;
249  const char *viewname = RE_GetActiveRenderView(engine->re);
250  const DRWContextState *draw_ctx = DRW_context_state_get();
251  Depsgraph *depsgraph = draw_ctx->depsgraph;
252 
253  GPENCIL_render_init(vedata, engine, render_layer, depsgraph, rect);
254  GPENCIL_engine_init(vedata);
255 
257 
258  /* Loop over all objects and create draw structure. */
259  GPENCIL_cache_init(vedata);
261  GPENCIL_cache_finish(vedata);
262 
264 
265  /* Render the gpencil object and merge the result to the underlying render. */
266  GPENCIL_draw_scene(vedata);
267 
268  GPENCIL_render_result_combined(render_layer, viewname, vedata, rect);
269  GPENCIL_render_result_z(render_layer, viewname, vedata, rect);
270 }
General operations, lookup, etc. for blender objects.
@ OB_VISIBLE_SELF
Definition: BKE_object.h:125
MINLINE float clamp_f(float value, float min, float max)
bool invert_m4_m4(float R[4][4], const float A[4][4])
Definition: math_matrix.c:1278
BLI_INLINE int BLI_rcti_size_y(const struct rcti *rct)
Definition: BLI_rect.h:157
BLI_INLINE int BLI_rcti_size_x(const struct rcti *rct)
Definition: BLI_rect.h:153
#define UNUSED(x)
#define ELEM(...)
struct Depsgraph Depsgraph
Definition: DEG_depsgraph.h:51
struct Object * DEG_get_evaluated_object(const struct Depsgraph *depsgraph, struct Object *object)
struct Scene * DEG_get_evaluated_scene(const struct Depsgraph *graph)
@ OB_LAMP
@ OB_GPENCIL
#define RE_PASSNAME_COMBINED
#define R_BORDER
#define RE_PASSNAME_Z
@ SCE_PASS_Z
static AppView * view
void GPU_framebuffer_bind(GPUFrameBuffer *fb)
_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
void GPU_texture_update_sub(GPUTexture *tex, eGPUDataFormat data_format, const void *pixels, int offset_x, int offset_y, int offset_z, int width, int height, int depth)
Definition: gpu_texture.cc:356
@ GPU_DATA_FLOAT
Definition: GPU_texture.h:172
void GPU_texture_update(GPUTexture *tex, eGPUDataFormat data_format, const void *data)
Definition: gpu_texture.cc:391
@ GPU_RGBA16F
Definition: GPU_texture.h:94
@ GPU_DEPTH_COMPONENT24
Definition: GPU_texture.h:167
#define MEM_SAFE_FREE(v)
static DBVT_INLINE btScalar size(const btDbvtVolume &a)
Definition: btDbvt.cpp:52
SIMD_FORCE_INLINE const btScalar & w() const
Return the w value.
Definition: btQuadWord.h:119
Scene scene
const Depsgraph * depsgraph
void DRW_render_instance_buffer_finish(void)
int DRW_object_visibility_in_active_context(const Object *ob)
Definition: draw_manager.c:235
const DRWContextState * DRW_context_state_get(void)
const float * DRW_viewport_size_get(void)
Definition: draw_manager.c:439
void DRW_render_object_iter(void *vedata, RenderEngine *engine, struct Depsgraph *depsgraph, void(*callback)(void *vedata, Object *ob, RenderEngine *engine, struct Depsgraph *depsgraph))
float DRW_view_near_distance_get(const DRWView *view)
bool DRW_view_is_persp_get(const DRWView *view)
void DRW_view_winmat_get(const DRWView *view, float mat[4][4], bool inverse)
DRWView * DRW_view_create(const float viewmat[4][4], const float winmat[4][4], const float(*culling_viewmat)[4], const float(*culling_winmat)[4], DRWCallVisibilityFn *visibility_fn)
float DRW_view_far_distance_get(const DRWView *view)
void DRW_view_default_set(DRWView *view)
void DRW_view_set_active(DRWView *view)
GPUTexture * DRW_texture_create_2d(int w, int h, eGPUTextureFormat format, DRWTextureFlag flags, const float *fpixels)
void RE_engine_set_error_message(RenderEngine *engine, const char *msg)
Definition: engine.c:507
void GPENCIL_cache_populate(void *ved, Object *ob)
void GPENCIL_draw_scene(void *ved)
void GPENCIL_cache_init(void *ved)
void GPENCIL_cache_finish(void *ved)
void GPENCIL_engine_init(void *ved)
static void GPENCIL_render_result_combined(struct RenderLayer *rl, const char *viewname, GPENCIL_Data *vedata, const rcti *rect)
static void GPENCIL_render_result_z(struct RenderLayer *rl, const char *viewname, GPENCIL_Data *vedata, const rcti *rect)
void GPENCIL_render_init(GPENCIL_Data *vedata, RenderEngine *engine, struct RenderLayer *render_layer, const Depsgraph *depsgraph, const rcti *rect)
static void GPENCIL_render_cache(void *vedata, struct Object *ob, struct RenderEngine *UNUSED(engine), Depsgraph *UNUSED(depsgraph))
void GPENCIL_render_to_image(void *ved, RenderEngine *engine, struct RenderLayer *render_layer, const rcti *rect)
void GPU_framebuffer_read_color(GPUFrameBuffer *gpu_fb, int x, int y, int w, int h, int channels, int slot, eGPUDataFormat format, void *data)
void GPU_framebuffer_read_depth(GPUFrameBuffer *gpu_fb, int x, int y, int w, int h, eGPUDataFormat format, void *data)
void RE_GetCameraWindow(struct Render *re, struct Object *camera, float r_winmat[4][4])
Definition: initrender.c:205
void RE_GetCameraModelMatrix(Render *re, struct Object *camera, float r_modelmat[4][4])
Definition: initrender.c:230
struct Object * RE_GetCamera(Render *re)
Definition: initrender.c:169
#define fabsf(x)
void *(* MEM_dupallocN)(const void *vmemh)
Definition: mallocn.c:42
RenderPass * RE_pass_find_by_name(volatile RenderLayer *rl, const char *name, const char *viewname)
Definition: pipeline.c:2764
const char * RE_GetActiveRenderView(Render *re)
Definition: pipeline.c:1746
struct Depsgraph * depsgraph
Definition: DRW_render.h:753
struct ViewLayer * view_layer
Definition: DRW_render.h:746
struct GPENCIL_TextureList * txl
struct GPENCIL_StorageList * stl
struct GPENCIL_FramebufferList * fbl
struct GPUFrameBuffer * render_fb
struct GPENCIL_PrivateData * pd
struct GPUTexture * render_depth_tx
struct GPUTexture * render_color_tx
struct Render * re
Definition: RE_engine.h:136
float * rect
Definition: RE_pipeline.h:82
struct RenderData r
int ymin
Definition: DNA_vec_types.h:80
int xmin
Definition: DNA_vec_types.h:79