Blender  V2.93
initrender.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  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
17  * All rights reserved.
18  */
19 
24 /* Global includes */
25 
26 #include <math.h>
27 #include <stdio.h>
28 #include <stdlib.h>
29 #include <string.h>
30 
31 #include "MEM_guardedalloc.h"
32 
33 #include "BLI_blenlib.h"
34 #include "BLI_ghash.h"
35 #include "BLI_math.h"
36 #include "BLI_utildefines.h"
37 
38 #include "DNA_camera_types.h"
39 
40 #include "BKE_camera.h"
41 
42 /* this module */
43 #include "pipeline.h"
44 #include "render_types.h"
45 
46 /* Own includes */
47 #include "initrender.h"
48 
49 /* ****************** MASKS and LUTS **************** */
50 
51 static float filt_quadratic(float x)
52 {
53  if (x < 0.0f) {
54  x = -x;
55  }
56  if (x < 0.5f) {
57  return 0.75f - (x * x);
58  }
59  if (x < 1.5f) {
60  return 0.50f * (x - 1.5f) * (x - 1.5f);
61  }
62  return 0.0f;
63 }
64 
65 static float filt_cubic(float x)
66 {
67  float x2 = x * x;
68 
69  if (x < 0.0f) {
70  x = -x;
71  }
72 
73  if (x < 1.0f) {
74  return 0.5f * x * x2 - x2 + 2.0f / 3.0f;
75  }
76  if (x < 2.0f) {
77  return (2.0f - x) * (2.0f - x) * (2.0f - x) / 6.0f;
78  }
79  return 0.0f;
80 }
81 
82 static float filt_catrom(float x)
83 {
84  float x2 = x * x;
85 
86  if (x < 0.0f) {
87  x = -x;
88  }
89  if (x < 1.0f) {
90  return 1.5f * x2 * x - 2.5f * x2 + 1.0f;
91  }
92  if (x < 2.0f) {
93  return -0.5f * x2 * x + 2.5f * x2 - 4.0f * x + 2.0f;
94  }
95  return 0.0f;
96 }
97 
98 static float filt_mitchell(float x) /* Mitchell & Netravali's two-param cubic */
99 {
100  float b = 1.0f / 3.0f, c = 1.0f / 3.0f;
101  float p0 = (6.0f - 2.0f * b) / 6.0f;
102  float p2 = (-18.0f + 12.0f * b + 6.0f * c) / 6.0f;
103  float p3 = (12.0f - 9.0f * b - 6.0f * c) / 6.0f;
104  float q0 = (8.0f * b + 24.0f * c) / 6.0f;
105  float q1 = (-12.0f * b - 48.0f * c) / 6.0f;
106  float q2 = (6.0f * b + 30.0f * c) / 6.0f;
107  float q3 = (-b - 6.0f * c) / 6.0f;
108 
109  if (x < -2.0f) {
110  return 0.0f;
111  }
112  if (x < -1.0f) {
113  return (q0 - x * (q1 - x * (q2 - x * q3)));
114  }
115  if (x < 0.0f) {
116  return (p0 + x * x * (p2 - x * p3));
117  }
118  if (x < 1.0f) {
119  return (p0 + x * x * (p2 + x * p3));
120  }
121  if (x < 2.0f) {
122  return (q0 + x * (q1 + x * (q2 + x * q3)));
123  }
124  return 0.0f;
125 }
126 
127 /* x ranges from -1 to 1 */
128 float RE_filter_value(int type, float x)
129 {
130  float gaussfac = 1.6f;
131 
132  x = fabsf(x);
133 
134  switch (type) {
135  case R_FILTER_BOX:
136  if (x > 1.0f) {
137  return 0.0f;
138  }
139  return 1.0f;
140 
141  case R_FILTER_TENT:
142  if (x > 1.0f) {
143  return 0.0f;
144  }
145  return 1.0f - x;
146 
147  case R_FILTER_GAUSS: {
148  const float two_gaussfac2 = 2.0f * gaussfac * gaussfac;
149  x *= 3.0f * gaussfac;
150  return 1.0f / sqrtf((float)M_PI * two_gaussfac2) * expf(-x * x / two_gaussfac2);
151  }
152 
153  case R_FILTER_MITCH:
154  return filt_mitchell(x * gaussfac);
155 
156  case R_FILTER_QUAD:
157  return filt_quadratic(x * gaussfac);
158 
159  case R_FILTER_CUBIC:
160  return filt_cubic(x * gaussfac);
161 
162  case R_FILTER_CATROM:
163  return filt_catrom(x * gaussfac);
164  }
165  return 0.0f;
166 }
167 
168 /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
170 {
171  Object *camera = re->camera_override ? re->camera_override : re->scene->camera;
172  return BKE_camera_multiview_render(re->scene, camera, re->viewname);
173 }
174 
176 {
177  re->camera_override = cam_ob;
178 }
179 
185 void RE_SetCamera(Render *re, Object *cam_ob)
186 {
188 
189  /* setup parameters */
192  BKE_camera_multiview_params(&re->r, &params, cam_ob, re->viewname);
193 
194  /* compute matrix, viewplane, .. */
197 
198  /* extract results */
199  copy_m4_m4(re->winmat, params.winmat);
200  re->clip_start = params.clip_start;
201  re->clip_end = params.clip_end;
202  re->viewplane = params.viewplane;
203 }
204 
205 void RE_GetCameraWindow(struct Render *re, struct Object *camera, float r_winmat[4][4])
206 {
207  RE_SetCamera(re, camera);
208  copy_m4_m4(r_winmat, re->winmat);
209 }
210 
211 /* Must be called after RE_GetCameraWindow(), does not change re->winmat. */
212 void RE_GetCameraWindowWithOverscan(struct Render *re, float overscan, float r_winmat[4][4])
213 {
215  params.is_ortho = re->winmat[3][3] != 0.0f;
216  params.clip_start = re->clip_start;
217  params.clip_end = re->clip_end;
218  params.viewplane = re->viewplane;
219 
220  overscan *= max_ff(BLI_rctf_size_x(&params.viewplane), BLI_rctf_size_y(&params.viewplane));
221 
222  params.viewplane.xmin -= overscan;
223  params.viewplane.xmax += overscan;
224  params.viewplane.ymin -= overscan;
225  params.viewplane.ymax += overscan;
227  copy_m4_m4(r_winmat, params.winmat);
228 }
229 
230 void RE_GetCameraModelMatrix(Render *re, struct Object *camera, float r_modelmat[4][4])
231 {
232  BKE_camera_multiview_model_matrix(&re->r, camera, re->viewname, r_modelmat);
233 }
234 
235 void RE_GetViewPlane(Render *re, rctf *r_viewplane, rcti *r_disprect)
236 {
237  *r_viewplane = re->viewplane;
238 
239  /* make disprect zero when no border render, is needed to detect changes in 3d view render */
240  if (re->r.mode & R_BORDER) {
241  *r_disprect = re->disprect;
242  }
243  else {
244  BLI_rcti_init(r_disprect, 0, 0, 0, 0);
245  }
246 }
247 
248 /* ~~~~~~~~~~~~~~~~ part (tile) calculus ~~~~~~~~~~~~~~~~~~~~~~ */
249 
251 {
252  if (re->parts) {
254  re->parts = NULL;
255  }
256 }
257 
259 {
260  /* part size */
261  re->partx = max_ii(1, min_ii(re->r.tilex, re->rectx));
262  re->party = max_ii(1, min_ii(re->r.tiley, re->recty));
263 }
264 
266 {
267  int nr, xd, yd, partx, party, xparts, yparts;
268  int xminb, xmaxb, yminb, ymaxb;
269 
270  RE_parts_free(re);
271 
272  re->parts = BLI_ghash_new(
274 
275  /* just for readable code.. */
276  xminb = re->disprect.xmin;
277  yminb = re->disprect.ymin;
278  xmaxb = re->disprect.xmax;
279  ymaxb = re->disprect.ymax;
280 
281  RE_parts_clamp(re);
282 
283  partx = re->partx;
284  party = re->party;
285  /* part count */
286  xparts = (re->rectx + partx - 1) / partx;
287  yparts = (re->recty + party - 1) / party;
288 
289  for (nr = 0; nr < xparts * yparts; nr++) {
290  rcti disprect;
291  int rectx, recty;
292 
293  xd = (nr % xparts);
294  yd = (nr - xd) / xparts;
295 
296  disprect.xmin = xminb + xd * partx;
297  disprect.ymin = yminb + yd * party;
298 
299  /* ensure we cover the entire picture, so last parts go to end */
300  if (xd < xparts - 1) {
301  disprect.xmax = disprect.xmin + partx;
302  if (disprect.xmax > xmaxb) {
303  disprect.xmax = xmaxb;
304  }
305  }
306  else {
307  disprect.xmax = xmaxb;
308  }
309 
310  if (yd < yparts - 1) {
311  disprect.ymax = disprect.ymin + party;
312  if (disprect.ymax > ymaxb) {
313  disprect.ymax = ymaxb;
314  }
315  }
316  else {
317  disprect.ymax = ymaxb;
318  }
319 
320  rectx = BLI_rcti_size_x(&disprect);
321  recty = BLI_rcti_size_y(&disprect);
322 
323  /* so, now can we add this part? */
324  if (rectx > 0 && recty > 0) {
325  RenderPart *pa = MEM_callocN(sizeof(RenderPart), "new part");
326 
327  pa->disprect = disprect;
328  pa->rectx = rectx;
329  pa->recty = recty;
330 
331  BLI_ghash_insert(re->parts, &pa->disprect, pa);
332  }
333  }
334 }
Camera data-block and utility functions.
void BKE_camera_multiview_params(const struct RenderData *rd, struct CameraParams *params, const struct Object *camera, const char *viewname)
struct Object * BKE_camera_multiview_render(const struct Scene *scene, struct Object *camera, const char *viewname)
void BKE_camera_params_init(CameraParams *params)
Definition: camera.c:271
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_params_from_object(CameraParams *params, const struct Object *cam_ob)
void BKE_camera_params_compute_viewplane(CameraParams *params, int winx, int winy, float aspx, float aspy)
Definition: camera.c:370
void BKE_camera_params_compute_matrix(CameraParams *params)
Definition: camera.c:436
#define BLI_ghashutil_inthash_v4_cmp
Definition: BLI_ghash.h:378
GHash * BLI_ghash_new(GHashHashFP hashfp, GHashCmpFP cmpfp, const char *info) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT
Definition: BLI_ghash.c:718
#define BLI_ghashutil_inthash_v4_p
Definition: BLI_ghash.h:369
void BLI_ghash_insert(GHash *gh, void *key, void *val)
Definition: BLI_ghash.c:756
void BLI_ghash_free(GHash *gh, GHashKeyFreeFP keyfreefp, GHashValFreeFP valfreefp)
Definition: BLI_ghash.c:1008
MINLINE float max_ff(float a, float b)
MINLINE int min_ii(int a, int b)
MINLINE int max_ii(int a, int b)
#define M_PI
Definition: BLI_math_base.h:38
void copy_m4_m4(float m1[4][4], const float m2[4][4])
Definition: math_matrix.c:95
BLI_INLINE int BLI_rcti_size_y(const struct rcti *rct)
Definition: BLI_rect.h:157
void BLI_rcti_init(struct rcti *rect, int xmin, int xmax, int ymin, int ymax)
Definition: rct.c:446
BLI_INLINE int BLI_rcti_size_x(const struct rcti *rct)
Definition: BLI_rect.h:153
BLI_INLINE float BLI_rctf_size_x(const struct rctf *rct)
Definition: BLI_rect.h:161
BLI_INLINE float BLI_rctf_size_y(const struct rctf *rct)
Definition: BLI_rect.h:165
#define R_FILTER_GAUSS
#define R_BORDER
#define R_FILTER_QUAD
#define R_FILTER_MITCH
#define R_FILTER_TENT
#define R_FILTER_CUBIC
#define R_FILTER_BOX
#define R_FILTER_CATROM
_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 GLsizei GLsizei GLenum type _GL_VOID_RET _GL_VOID GLsizei GLenum GLenum const void *pixels _GL_VOID_RET _GL_VOID const void *pointer _GL_VOID_RET _GL_VOID GLdouble v _GL_VOID_RET _GL_VOID GLfloat v _GL_VOID_RET _GL_VOID GLint GLint i2 _GL_VOID_RET _GL_VOID GLint j _GL_VOID_RET _GL_VOID GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble GLdouble GLdouble zFar _GL_VOID_RET _GL_UINT GLdouble *equation _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLenum GLfloat *v _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLfloat *values _GL_VOID_RET _GL_VOID GLushort *values _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLenum GLdouble *params _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_BOOL GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLushort pattern _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint const GLdouble *points _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint GLdouble GLdouble GLint GLint const GLdouble *points _GL_VOID_RET _GL_VOID GLdouble GLdouble u2 _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLdouble GLdouble v2 _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLdouble GLdouble nz _GL_VOID_RET _GL_VOID GLfloat GLfloat nz _GL_VOID_RET _GL_VOID GLint GLint nz _GL_VOID_RET _GL_VOID GLshort GLshort nz _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_VOID GLsizei const GLfloat *values _GL_VOID_RET _GL_VOID GLsizei const GLushort *values _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID const GLuint const GLclampf *priorities _GL_VOID_RET _GL_VOID GLdouble y _GL_VOID_RET _GL_VOID GLfloat y _GL_VOID_RET _GL_VOID GLint y _GL_VOID_RET _GL_VOID GLshort y _GL_VOID_RET _GL_VOID GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLfloat GLfloat z _GL_VOID_RET _GL_VOID GLint GLint z _GL_VOID_RET _GL_VOID GLshort GLshort z _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble w _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat w _GL_VOID_RET _GL_VOID GLint GLint GLint w _GL_VOID_RET _GL_VOID GLshort GLshort GLshort w _GL_VOID_RET _GL_VOID GLdouble GLdouble x2
_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 type
Read Guarded memory(de)allocation.
static float filt_cubic(float x)
Definition: initrender.c:65
void RE_GetViewPlane(Render *re, rctf *r_viewplane, rcti *r_disprect)
Definition: initrender.c:235
void RE_SetCamera(Render *re, Object *cam_ob)
Definition: initrender.c:185
void RE_SetOverrideCamera(Render *re, Object *cam_ob)
Definition: initrender.c:175
void RE_GetCameraWindowWithOverscan(struct Render *re, float overscan, float r_winmat[4][4])
Definition: initrender.c:212
static float filt_catrom(float x)
Definition: initrender.c:82
void RE_parts_clamp(Render *re)
Definition: initrender.c:258
static float filt_quadratic(float x)
Definition: initrender.c:51
void RE_parts_free(Render *re)
Definition: initrender.c:250
static float filt_mitchell(float x)
Definition: initrender.c:98
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
float RE_filter_value(int type, float x)
Definition: initrender.c:128
struct Object * RE_GetCamera(Render *re)
Definition: initrender.c:169
void RE_parts_init(Render *re)
Definition: initrender.c:265
uiWidgetBaseParameters params[MAX_WIDGET_BASE_BATCH]
#define expf(x)
#define fabsf(x)
#define sqrtf(x)
void(* MEM_freeN)(void *vmemh)
Definition: mallocn.c:41
void *(* MEM_callocN)(size_t len, const char *str)
Definition: mallocn.c:45
static unsigned c
Definition: RandGen.cpp:97
rcti disprect
Definition: render_types.h:56
int recty
Definition: render_types.h:97
float winmat[4][4]
Definition: render_types.h:104
float clip_start
Definition: render_types.h:107
RenderData r
Definition: render_types.h:113
int winy
Definition: render_types.h:92
float clip_end
Definition: render_types.h:108
Scene * scene
Definition: render_types.h:112
int rectx
Definition: render_types.h:97
int partx
Definition: render_types.h:101
int party
Definition: render_types.h:101
struct GHash * parts
Definition: render_types.h:119
char viewname[MAX_NAME]
Definition: render_types.h:154
int winx
Definition: render_types.h:92
rctf viewplane
Definition: render_types.h:94
rcti disprect
Definition: render_types.h:93
struct Object * camera_override
Definition: render_types.h:116
struct Object * camera
int ymin
Definition: DNA_vec_types.h:80
int ymax
Definition: DNA_vec_types.h:80
int xmin
Definition: DNA_vec_types.h:79
int xmax
Definition: DNA_vec_types.h:79