sce->r.posthue= 1.0;
sce->r.postmul= 1.0;
+ sce->r.focus= 0.9;
+ sce->r.zgamma= 1.0;
+ sce->r.zsigma= 4.0;
+ sce->r.zblur= 10.0;
+ sce->r.zmin= 0.8;
+
sce->r.xplay= 640;
sce->r.yplay= 480;
sce->r.freqplay= 60;
while(sce) {
if(sce->r.postsat==0.0) sce->r.postsat= 1.0;
+ if(sce->r.zgamma==0.0) {
+ sce->r.focus= 0.9;
+ sce->r.zgamma= 1.0;
+ sce->r.zsigma= 4.0;
+ sce->r.zblur= 10.0;
+ sce->r.zmin= 0.8;
+ }
sce= sce->id.next;
}
while(cam) {
}
}
}
- /*Camera *ca;
-
- for (ca= main->camera.first; ca; ca= ca->id.next) {
- ca->focus= 0.9;
- ca->zgamma= 1.0;
- ca->zblur= 10.0;
- ca->zmin= 0.8;
- ca->flag |= CAM_AUTOFOCUS;
- }*/
}
/* don't forget to set version number in blender.c! */
struct Base;
struct Object;
+struct Camera;
void arrows_move_cursor(unsigned short event);
void borderselect(void);
extern void do_mballbuts(unsigned short event);
extern void do_latticebuts(unsigned short event);
extern void do_fpaintbuts(unsigned short event);
+extern void do_cambuts(unsigned short event);
extern char *get_vertexgroup_menustr(struct Object *ob); // used in object buttons
/* shading */
#define B_SWITCHRENDER 1641
#define B_FBUF_REDO 1642
+#define B_SET_EDGE 1643
+#define B_SET_ZBLUR 1644
+
#ifdef __NLA
/* *********************** */
enum {
float YF_dofdist, YF_aperture;
short YF_bkhtype, YF_bkhbias;
float YF_bkhrot;
-
+
struct Ipo *ipo;
ScriptLink scriptlink;
/* yafray: dof sampling switch */
#define CAM_YF_NO_QMC 4
+
#ifdef __cplusplus
}
#endif
/* Dither noise intensity */
float dither_intensity;
- float pad_dither;
+
+ /* Zblur settings */
+ float zmin, focus, zgamma, zsigma, zblur;
/* yafray: global panel params. TODO: move elsewhere */
short GIquality, GIcache, GImethod, GIphotons, GIdirect;
#define R_GAUSS 0x20000
#define R_FBUF 0x40000
#define R_THREADS 0x80000
+#define R_ZBLUR 0x100000
+
/* yafray: renderer flag (not only exclusive to yafray) */
#define R_INTERN 0
'intern/source/shadbuf.c',
'intern/source/texture.c',
'intern/source/vanillaRenderPipe.c',
+ 'intern/source/zblur.c',
'intern/source/zbuf.c',
'intern/source/zbufferdatastruct.c']
--- /dev/null
+/*
+ * $Id$
+ *
+ * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version. The Blender
+ * Foundation also sells licenses for use in proprietary software under
+ * the Blender License. See http://www.blender.org/BL/ for information
+ * about this.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * ***** END GPL/BL DUAL LICENSE BLOCK *****
+ */
+
+#ifndef ZBLUR_H
+#define ZBLUR_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*-----------------------------------------------------------*/
+/* Includes */
+/*-----------------------------------------------------------*/
+
+/*-----------------------------------------------------------*/
+/* Function */
+/*-----------------------------------------------------------*/
+
+void add_zblur(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
#include "renderHelp.h"
#include "jitter.h"
#include "gammaCorrectionTables.h"
+#include "zblur.h"
/* Own includes */
#include "initrender.h"
if(RE_local_test_break()==0) add_halo_flare();
}
+ if( (R.r.mode & R_ZBLUR)) {
+ if(RE_local_test_break()==0) add_zblur();
+ }
+
if(R.r.mode & R_MBLUR) {
add_to_blurbuf(blur);
}
for(a=num;a>0;a--) {
/* instead of jit i tried random: ugly! */
/* note: the plus 0.5 gives best sampling results, jit used to go from 0-1 */
+ /* xs1 and ys1 are already corrected to be corner of sample area */
xs= xs1 + xres*(j[0] + 0.5);
ys= ys1 + yres*(j[1] + 0.5);
j+=2;
--- /dev/null
+/**
+ * $Id$
+ *
+ * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version. The Blender
+ * Foundation also sells licenses for use in proprietary software under
+ * the Blender License. See http://www.blender.org/BL/ for information
+ * about this.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * ***** END GPL/BL DUAL LICENSE BLOCK *****
+ */
+
+/*
+ * This file is largely based on the focal blur plugin by onk, 8.99
+ *
+ */
+
+#include <math.h>
+#include <string.h>
+#include <limits.h>
+#include <stdio.h>
+
+#include "MEM_guardedalloc.h"
+
+#include "DNA_camera_types.h"
+#include "DNA_scene_types.h"
+
+#include "BKE_global.h"
+#include "BKE_utildefines.h"
+
+#include "RE_callbacks.h"
+
+#include "render.h"
+#include "pixelblending.h"
+
+#include "blendef.h"
+
+//#include "BIF_gl.h"
+
+/* -------------------------------------------------
+ * defines, protos */
+
+typedef enum { I_GRAY, I_FLOAT, I_FLOAT4 } IMGTYPE;
+
+typedef struct {
+ int x, y;
+ int size, el_size;
+ IMGTYPE type;
+ char *data;
+} Image;
+
+typedef struct { /* blur mask struct */
+ int size;
+ float fac;
+ float *val;
+} Mask;
+
+typedef Mask* Maskarray;
+
+/* don't change these */
+#define NMASKS_SHIFT 2
+#define NMASKS 64
+
+
+static Image *alloc_img(int x, int y, IMGTYPE type)
+{
+ Image *ret;
+ int size, typesize;
+
+ switch (type) {
+ case I_GRAY:
+ typesize = 1;
+ break;
+ case I_FLOAT:
+ typesize = sizeof(float);
+ break;
+ case I_FLOAT4:
+ typesize = 4 * sizeof(float);
+ break;
+ default:
+ return 0;
+ }
+
+ size = x * y;
+
+ ret = (Image *) MEM_mallocN(sizeof(Image) + size*typesize, "zblur_img");
+ if (ret) {
+ ret->x = x;
+ ret->y = y;
+ ret->size = size;
+ ret->el_size = typesize;
+ ret->type = type;
+ ret->data = (char *) (ret + 1);
+ size *= typesize;
+ memset(ret->data, 0, size);
+ }
+
+ return ret;
+}
+
+static int free_img(Image *img)
+{
+ MEM_freeN(img);
+ return 1;
+}
+
+/* 32 bits (int) rect to float buf */
+static void recti2imgf(int *src, Image *dest, int x, int y)
+{
+ char *from;
+ float *to;
+ int i, ix, iy;
+
+ if(dest->type != I_FLOAT4) return;
+
+ from = (char *) src;
+ to = (float *) dest->data;
+
+ if (R.r.mode & R_FIELDS) { /* double each scanline */
+ for (iy=0; iy<y; iy++) {
+ for (ix=0; ix<x; ix++) {
+ *to++ = ((float)from[0])/255.0;
+ *to++ = ((float)from[1])/255.0;
+ *to++ = ((float)from[2])/255.0;
+ *to++ = ((float)from[3])/255.0;
+ from += 4;
+ }
+
+ memcpy(to, to-4*sizeof(float)*x, 4*sizeof(float)*x);
+ to+= 4*x;
+
+ iy++;
+ }
+ }
+ else {
+ i = x * y;
+ while(i--) {
+ *to++ = ((float)from[0])/255.0;
+ *to++ = ((float)from[1])/255.0;
+ *to++ = ((float)from[2])/255.0;
+ *to++ = ((float)from[3])/255.0;
+ from += 4;
+ }
+ }
+}
+
+/* float rect to float buf */
+static void rectf2imgf(float *src, Image *dest, int x, int y)
+{
+ float *from;
+ float *to;
+ int i, iy;
+
+ if(dest->type != I_FLOAT4) return;
+
+ from = src;
+ to = (float *) dest->data;
+
+ if (R.r.mode & R_FIELDS) { /* double each scanline */
+ for (iy=0; iy<y; iy++) {
+
+ memcpy(to, from, 4*sizeof(float)*x);
+ to+= 4*x;
+ memcpy(to, from, 4*sizeof(float)*x);
+ to+= 4*x;
+
+ iy++;
+ from += 4*x;
+ }
+ }
+ else {
+ i = y;
+ while(i--) {
+ memcpy(to, from, 4*sizeof(float)*x);
+ from += 4*x;
+ to += 4*x;
+ }
+ }
+}
+
+/* floatbuf back to 32 bits rect */
+static void imgf2recti(Image *src, int *dest)
+{
+ float *from;
+ char *to;
+ int i, ix, iy;
+
+ if(src->type != I_FLOAT4) return;
+
+ from = (float *) src->data;
+ to = (char *) dest;
+
+ if (R.r.mode & R_FIELDS) {
+ for (iy=0; iy<src->y; iy++) {
+ for (ix=0; ix<src->x; ix++) {
+ *to++ = (char)(from[0]*255.0);
+ *to++ = (char)(from[1]*255.0);
+ *to++ = (char)(from[2]*255.0);
+ *to++ = (char)(from[3]*255.0);
+ from += 4;
+ }
+ iy++;
+ from+= 4*src->x;
+ }
+ }
+ else {
+ i = src->x * src->y;
+ while(i--) {
+ *to++ = (char)(from[0]*255.0);
+ *to++ = (char)(from[1]*255.0);
+ *to++ = (char)(from[2]*255.0);
+ *to++ = (char)(from[3]*255.0);
+ from += 4;
+ }
+ }
+}
+
+/* floatbuf back to float rect */
+static void imgf2rectf(Image *src, float *dest)
+{
+ float *from;
+ float *to;
+ int i, iy;
+
+ if(src->type != I_FLOAT4) return;
+
+ from = (float *) src->data;
+ to = dest;
+
+ if (R.r.mode & R_FIELDS) {
+ for (iy=0; iy<src->y; iy++) {
+
+ memcpy(to, from, 4*sizeof(float)*src->x);
+
+ iy++;
+ to+= 4*src->x;
+ from+= 8*src->x;
+ }
+ }
+ else {
+ i = src->x * src->y;
+ memcpy(to, from, 4*sizeof(float)*i);
+ }
+}
+
+
+static void imgf_gamma(Image *src, float gamma)
+{
+ float *to;
+ int i;
+
+ if(gamma==1.0) return;
+
+ i = 4 * src->x * src->y;
+ to= (float *) src->data;
+ while(i--) {
+ *to = powf(*to, gamma);
+ to++;
+ }
+}
+
+#if 0
+/* create new image with alpha & color zero where mask is zero */
+static Image *imgf_apply_mask(Image *src, Image *zmask)
+{
+ Image *dest;
+ float *from, *to;
+ int i;
+ char *zptr;
+
+ dest = alloc_img(src->x, src->y, I_FLOAT4);
+
+ i= src->x * src->y;
+ from= (float *) src->data;
+ to= (float *) dest->data;
+ zptr= (char *)zmask->data;
+
+ while(i--) {
+ if(*zptr) {
+ to[0]= from[0];
+ to[1]= from[1];
+ to[2]= from[2];
+ to[3]= from[3];
+ }
+ else {
+ to[0]= to[1]= to[2]= to[3]= 0.0f;
+ }
+ zptr++;
+ to+= 4;
+ from+= 4;
+ }
+
+ return dest;
+}
+
+static void imgf_alpha_over(Image *dest, Image *src)
+{
+ float *from, *to;
+ int i;
+
+ i= src->x * src->y;
+ from= (float *) src->data;
+ to= (float *) dest->data;
+
+ while(i--) {
+ addAlphaOverFloat(to, from);
+ to+= 4;
+ from+= 4;
+ }
+}
+
+#endif
+
+/* --------------------------------------------------------------------- */
+/* mask routines */
+
+static Mask *alloc_mask(int size)
+{
+ Mask *m;
+ int memsize;
+
+ memsize = (sizeof(Mask) + (2 * size +1) * (2 * size +1) * sizeof(float));
+
+ m = (Mask*) MEM_mallocN(memsize, "zblur_mask");
+ m->size = size;
+ m->val = (float *) (m + 1);
+
+ return m;
+}
+
+static void free_mask(Mask *m)
+{
+ int memsize;
+
+ memsize = 2 * m->size + 1;
+ memsize *= memsize * sizeof(float);
+ memsize += sizeof(Mask);
+
+ MEM_freeN(m);
+}
+
+/* normalize mask to 1 */
+
+static void norm_mask(Mask *m)
+{
+ float fac;
+ int size;
+ float *v;
+
+ fac = m->fac;
+ size = (2 * m->size +1)*(2 * m->size +1);
+
+ v = m->val;
+ while(size--) {
+ *v++ *= fac;
+ }
+ m->fac = 1.0;
+}
+
+/* filters a grayvalue image with a gaussian IIR filter with blur radius "rad"
+ * For large blurs, it's more efficient to call the routine several times
+ * instead of using big blur radii.
+ * The original image is changed */
+
+
+static void gauss_blur(Image *img, float rad)
+{
+ Image *new;
+ register float sum, val;
+ float gval;
+ float *gausstab, *v;
+ int r, n, m;
+ int x, y;
+ int i;
+ int step, bigstep;
+ char *src, *dest;
+
+ r = (1.5 * rad + 1.5);
+ n = 2 * r + 1;
+
+ /* ugly : */
+ if ((img->x <= n) || (img->y <= n)) {
+ return;
+ }
+
+ gausstab = (float *) MEM_mallocN(n * sizeof(float), "zblur_gauss");
+ if (!gausstab) {
+ return;
+ }
+
+ sum = 0.0;
+ v = gausstab;
+ for (x = -r; x <= r; x++) {
+
+ val = exp(-4*(float ) (x*x)/ (float) (r*r));
+ sum += val;
+ *v++ = val;
+ }
+
+ i = n;
+ v = gausstab;
+ while (i--) {
+ *v++ /= sum;
+ }
+
+ new = alloc_img(img->x, img->y, I_GRAY);
+ if (!new) {
+ return;
+ }
+
+ /* horizontal */
+
+ step = (n - 1);
+
+ for (y = 0; y < img->y; y++) {
+ src = (char *)img->data + (y * img->x);
+ dest = (char *)new->data + (y * img->x);
+
+ for (x = r; x > 0 ; x--) {
+ m = n - x;
+ gval = 0.0;
+ sum = 0.0;
+ v = gausstab + x;
+ for (i = 0; i < m; i++) {
+ val = *v++;
+ sum += val;
+ gval += val * (*src++);
+ }
+ *dest++ = gval / sum;
+ src -= m;
+ }
+
+ for (x = 0; x <= (img->x - n); x++) {
+ gval = 0.0;
+ v = gausstab;
+
+ for (i = 0; i < n; i++) {
+ val = *v++;
+ gval += val * (*src++);
+ }
+ *dest++ = gval;
+ src -= step;
+ }
+
+ for (x = 1; x <= r ; x++) {
+ m = n - x;
+ gval = 0.0;
+ sum = 0.0;
+ v = gausstab;
+ for (i = 0; i < m; i++) {
+ val = *v++;
+ sum += val;
+ gval += val * (*src++);
+ }
+ *dest++ = gval / sum;
+ src -= (m - 1);
+ }
+ }
+
+ /* vertical */
+
+ step = img->x;
+ bigstep = (n - 1) * step;
+ for (x = 0; x < step ; x++) {
+ src = new->data + x;
+ dest = img->data + x;
+
+ for (y = r; y > 0; y--) {
+ m = n - y;
+ gval = 0.0;
+ sum = 0.0;
+ v = gausstab + y;
+ for (i = 0; i < m; i++) {
+ val = *v++;
+ sum += val;
+ gval += val * src[0];
+ src += step;
+ }
+ dest[0] = gval / sum;
+ src -= m * step;
+ dest+= step;
+ }
+ for (y = 0; y <= (img->y - n); y++) {
+ gval = 0.0;
+ v = gausstab;
+ for (i = 0; i < n; i++) {
+ val = *v++;
+ gval += val * src[0];
+ src += step;
+ }
+ dest[0] = gval;
+ dest += step;
+ src -= bigstep;
+ }
+ for (y = 1; y <= r ; y++) {
+ m = n - y;
+ gval = 0.0;
+ sum = 0.0;
+ v = gausstab;
+ for (i = 0; i < m; i++) {
+ val = *v++;
+ sum += val;
+ gval += val * src[0];
+ src += step;
+ }
+ dest[0] = gval / sum;
+ dest += step;
+ src -= (m - 1) * step;
+ }
+ }
+ MEM_freeN(gausstab);
+ free_img(new);
+}
+
+static float zigma(float x, float sigma, float sigma4)
+{
+ //return 1.0/(1.0+pow(x, sigma));
+
+ if(x < sigma) {
+ x*= sigma;
+ return 1.0/exp(x*x) - sigma4;
+ }
+ return 0.0;
+}
+
+
+static Mask *gauss_mask(float rad, float sigma)
+{
+ Mask *m;
+ float sum, val, *v, fac, radsq= rad*rad;
+ float sigma4;
+ int r;
+ int ix, iy;
+
+ r = (1.0 * rad + 1.0);
+ m = alloc_mask(r);
+ v = m->val;
+ sum = 0.0;
+
+ sigma4= 1.0/exp(sigma*sigma*sigma*sigma);
+
+ for (iy = -r; iy <= r; iy++) {
+ for (ix = -r; ix <= r; ix++) {
+
+ fac= ((float)(ix*ix + iy*iy))/(radsq);
+ val = zigma(fac, sigma, sigma4);
+
+ // val = exp(-(float) (ix*ix + iy*iy)/(rad * rad));
+ sum += val;
+ *v++ = val;
+ }
+ }
+
+ m->fac = 1.0 / sum;
+
+ norm_mask(m);
+ return m;
+}
+
+/* generates #num masks with the maximal blur radius 'rad'
+ * */
+static Maskarray *init_masks(int num, float rad, float sigma)
+{
+ int i;
+ float r, step;
+ Maskarray *maskarray;
+
+ maskarray = (Maskarray*) MEM_mallocN(num * sizeof (Maskarray), "zblur_masks");
+ step = rad / num;
+ r = 0.1;
+ for (i = 0; i < num; i++) {
+ maskarray[i] = gauss_mask(r, sigma);
+ r += step;
+ }
+ return maskarray;
+}
+
+
+/* ********************* Do the blur ******************************** */
+
+static Image *zblur(Image *src, Image *zbuf, float radius, float sigma)
+{
+ Image *dest;
+ Maskarray *mar;
+ Mask *m;
+ float *sptr, *dptr;
+ float *mval; /* mask value pointer */
+ float rval, gval, bval, aval;
+ float norm, fac;
+ int tmp;
+ int zval;
+ int size;
+ int row;
+ int mrow;
+ int x, y;
+ int i;
+ int sx, sy, ex, ey;
+ int mx, my;
+ char *zptr;
+
+ if(src->type != I_FLOAT4) return NULL;
+
+ dest = alloc_img(src->x, src->y, I_FLOAT4);
+ row = src->x * 4;
+
+ mar = init_masks(NMASKS, radius, sigma);
+
+ for (y = 0; y < src->y ; y++) {
+ for (x = 0; x < src->x; x++) {
+ dptr = (float *) (dest->data + ((y * src->x + x) * src->el_size));
+ zptr = zbuf->data + (y * src->x + x);
+ zval = *zptr;
+ sptr = (float *) (src->data + ((y *src->x + x )* src->el_size));
+
+ m = mar[zval >> NMASKS_SHIFT];
+
+ size = m->size;
+
+ if(size==0 || zval==0) {
+ dptr[0] = sptr[0];
+ dptr[1] = sptr[1];
+ dptr[2] = sptr[2];
+ dptr[3] = sptr[3];
+ continue;
+ }
+
+ ex = src->x - x;
+ ey = src->y - y;
+
+ sx = (x < size) ? x : size;
+ sy = (y < size) ? y : size;
+ ex = (ex <= size) ? ex - 1: size;
+ ey = (ey <= size) ? ey - 1: size;
+
+ sptr -= sy *src->x * 4;
+ zptr -= sy * src->x;
+ mrow = (size << 1) + 1;
+ mval = m->val + (size - sy) * mrow + size;
+
+ norm = rval = gval = bval = aval= 0.0;
+
+ for (my = -sy; my <= ey; my++) {
+ for (mx = -sx; mx <= ex; mx++) {
+ if( zptr[mx] ) {
+ tmp = 4 * mx;
+ fac = mval[mx] * (float) zptr[mx] /255.0 ;
+
+ norm += fac;
+ rval += fac * sptr[tmp];
+ gval += fac * sptr[tmp + 1];
+ bval += fac * sptr[tmp + 2];
+ aval += fac * sptr[tmp + 3];
+ }
+ }
+ mval += mrow;
+ sptr += row;
+ zptr += src->x;
+ }
+
+ dptr[0] = rval / norm;
+ dptr[1] = gval / norm;
+ dptr[2] = bval / norm;
+ dptr[3] = aval / norm;
+ }
+ if(!(y % 4) && RE_local_test_break()) break;
+ }
+
+ for (i= 0; i < NMASKS; i++) {
+ free_mask(mar[i]);
+ }
+
+ MEM_freeN(mar);
+
+ return dest;
+}
+
+
+/* this splits the z-buffer into 2 gray-images (background, foreground)
+* which are used for the weighted blur */
+
+static void zsplit(int *zptr, Image *fg, Image *bg, int zfocus, int zmax, int zmin, int x, int y)
+{
+ char *p, *q;
+ int i, ix, iy;
+ float fdist;
+ float fgnorm, bgnorm;
+
+ p = fg->data;
+ q = bg->data;
+ bgnorm = 255.0 / ((float) zmax - (float) zfocus);
+ fgnorm = 255.0 / ((float) zfocus - (float) zmin);
+
+ if (R.r.mode & R_FIELDS) {
+ for (iy=0; iy<y; iy++) {
+ for (ix=0; ix<x; ix++) {
+ fdist = (float) (*zptr++);
+ if (fdist < zmin) fdist = zmin;
+
+ fdist -= zfocus;
+
+ if (fdist < 0) {
+ *p = (char) (-fdist * fgnorm);
+ *q = 0;
+ }
+ else {
+ *q = (char) (fdist * bgnorm);
+ *p = 0;
+ }
+ p++, q++;
+ }
+ iy++;
+ p+= x;
+ q+= x;
+ }
+ }
+ else {
+ i = x * y;
+ while(i--) {
+ fdist = (float) (*zptr++);
+ if (fdist < zmin) fdist = zmin;
+
+ fdist -= zfocus;
+
+ if (fdist < 0) {
+ *p = (char) (-fdist * fgnorm);
+ *q = 0;
+ }
+ else {
+ *q = (char) (fdist * bgnorm);
+ *p = 0;
+ }
+ p++, q++;
+ }
+ }
+}
+
+void add_zblur(void)
+{
+ Image *orig, *zfront, *work, *zback;
+ float zblurr;
+ int zfocus;
+ int x, y, zmin;
+
+ if (R.rectz == NULL) return;
+
+ x= R.rectx;
+ y= R.recty;
+
+ zblurr= (R.r.zblur*R.r.size)/100;
+
+ if (R.r.mode & R_FIELDS) {
+ y *= 2;
+ zblurr *= 2;
+ }
+
+ zmin= INT_MAX*( 2.0*R.r.zmin - 1.0); // R.r.zmin ranges 0 - 1
+ zfocus = INT_MAX*( 2.0*R.r.focus - 1.0);
+
+ if(zmin>zfocus) zmin= zfocus;
+
+ zfront = alloc_img(x, y, I_GRAY);
+ zback = alloc_img(x, y, I_GRAY);
+ orig = alloc_img(x, y, I_FLOAT4);
+
+ if(R.rectftot) rectf2imgf(R.rectftot, orig, x, y);
+ else recti2imgf(R.rectot, orig, x, y);
+
+ imgf_gamma(orig, R.r.zgamma); // pregamma correct if required
+
+
+ /* split up z buffer into 2 gray images */
+ zsplit(R.rectz, zfront, zback, zfocus, INT_MAX, zmin, x, y);
+
+// glDrawBuffer(GL_FRONT);
+// glRasterPos2i(0, 0);
+// glDrawPixels(x, y, GL_RED, GL_UNSIGNED_BYTE, zback->data);
+// glFlush();
+// glDrawBuffer(GL_BACK);
+
+ gauss_blur(zback, 1.0);
+ gauss_blur(zfront, zblurr);
+
+ /* blur back part */
+ work = zblur(orig, zback, zblurr, R.r.zsigma);
+ free_img(orig);
+
+ /* blur front part */
+ orig = zblur(work, zfront, zblurr, R.r.zsigma);
+
+ imgf_gamma(orig, 1.0/R.r.zgamma); // pregamma correct if required
+
+ if(R.rectftot) imgf2rectf(orig, R.rectftot);
+ else imgf2recti(orig, R.rectot);
+
+ free_img(work);
+ free_img(orig);
+ free_img(zfront);
+ free_img(zback);
+
+ /* make new display rect */
+ if(R.rectftot) RE_floatbuffer_to_output();
+}
+
+
int dist,
int mask)
{
- int counter;
+ int counter=0;
while(ap) {
if(ap->t[0] == RE_NONE) {
do_fontbuts(event);
}
else if(event<=B_CAMBUTS) {
- ;
+ do_cambuts(event);
}
else if(event<=B_MBALLBUTS) {
do_mballbuts(event);
uiDefButF(block, NUM,REDRAWVIEW3D, "DrawSize:", 470,90,160,20, &cam->drawsize, 0.1*grid, 10.0, 10, 0, "Specify the drawsize of the camera");
- uiDefButS(block, TOG, REDRAWVIEW3D, "Ortho", 470,49,61,40, &cam->type, 0, 0, 0, 0, "Render orthogonally");
+ uiDefButS(block, TOG, REDRAWVIEW3D, "Ortho", 470,29,61,60, &cam->type, 0, 0, 0, 0, "Render orthogonally");
uiBlockBeginAlign(block);
- uiDefButS(block, TOG|BIT|0,REDRAWVIEW3D, "ShowLimits", 533,69,97,20, &cam->flag, 0, 0, 0, 0, "Draw the field of view");
- uiDefButS(block, TOG|BIT|1,REDRAWVIEW3D, "Show Mist", 533,49,97,20, &cam->flag, 0, 0, 0, 0, "Draw a line that indicates the mist area");
+ uiDefButS(block, TOG|BIT|0,REDRAWVIEW3D, "ShowLimits", 533,59,97,30, &cam->flag, 0, 0, 0, 0, "Draw the field of view");
+ uiDefButS(block, TOG|BIT|1,REDRAWVIEW3D, "Show Mist", 533,29,97,30, &cam->flag, 0, 0, 0, 0, "Draw a line that indicates the mist area");
uiBlockEndAlign(block);
}
}
+/* **************************** CAMERA *************************** */
+
+void do_cambuts(unsigned short event)
+{
+ Object *ob;
+ Camera *cam;
+
+ ob= OBACT;
+ if (ob==0) return;
+ cam= ob->data;
+
+ switch(event) {
+ case 0:
+ ;
+ break;
+ }
+}
/* *************************** MBALL ******************************** */
BIF_redraw_render_rect();
}
break;
+ case B_SET_EDGE:
+ G.scene->r.mode &= ~R_ZBLUR;
+ allqueue(REDRAWBUTSSCENE, 0);
+ break;
+ case B_SET_ZBLUR:
+ G.scene->r.mode &= ~R_EDGE;
+ allqueue(REDRAWBUTSSCENE, 0);
+ break;
}
}
uiDefButS(block, TOG|BIT|4, 0, "Extensions", 205, 10, 105, 19, &G.scene->r.scemode, 0.0, 0.0, 0, 0, "Adds extensions to the output when rendering animations");
- /* Dither control */
- uiDefButF(block, NUM,B_DIFF, "Dither:", 205,31,105,19, &G.scene->r.dither_intensity, 0.0, 2.0, 0, 0, "The amount of dithering noise present in the output image (0.0 = no dithering)");
-
- /* Toon shading buttons */
- uiBlockBeginAlign(block);
- uiDefButI(block, TOG|BIT|5, 0,"Edge", 100, 94, 70, 20, &G.scene->r.mode, 0, 0, 0, 0, "Enable Toon edge shading");
- uiDefBlockBut(block, edge_render_menu, NULL, "Edge Settings", 170, 94, 140, 20, "Display edge settings");
-
- /* postprocess render buttons */
- uiBlockBeginAlign(block);
- if(R.rectftot)
- uiDefIconTextButI(block, TOG|BIT|18, B_NOP, ICON_IMAGE_DEHLT," Fbuf", 100, 68, 70, 20, &G.scene->r.mode, 0, 0, 0, 0, "Keep RGBA float buffer after render; buffer available");
- else
- uiDefButI(block, TOG|BIT|18, 0,"Fbuf", 100, 68, 70, 20, &G.scene->r.mode, 0, 0, 0, 0, "Keep RGBA float buffer after render, no buffer available now");
- uiDefBlockBut(block, post_render_menu, NULL, "Post process", 170, 68, 140, 20, "Applies on RGBA floats while render or with Fbuf available");
- uiBlockEndAlign(block);
-
/* removed, for time being unified and normal render will use same gamma for blending (2.0) */
//if (G.scene->r.mode & R_GAMMA) {
// uiDefButF(block, NUMSLI, 0,"Gamma:", 10, 68, 142, 20,
uiDefButS(block, ROW,800,"Premul", 405,13,50,20,&G.scene->r.alphamode,3.0,1.0, 0, 0, "Multiply alpha in advance");
uiDefButS(block, ROW,800,"Key", 456,13,35,20,&G.scene->r.alphamode,3.0,2.0, 0, 0, "Alpha and colour values remain unchanged");
uiBlockEndAlign(block);
-
+
if(G.scene->r.mode & R_RAYTRACE)
uiDefButS(block, MENU, B_DIFF,"Octree resolution %t|64 %x64|128 %x128|256 %x256|512 %x512", 496,13,64,20,&G.scene->r.ocres,0.0,0.0, 0, 0, "Octree resolution for ray tracing");
uiDefButF(block, NUMSLI, B_DIFF,"Bi ", 5,35,150,20, &(G.scene->r.YF_raybias),
0.0, 10.0 ,0,0, "Shadow ray bias to avoid self shadowing");
- uiDefButI(block, NUM, B_DIFF, "Raydepth ", 5,60,150,20,
+ uiDefButI(block, NUM, B_DIFF, "Raydepth ", 5,60,150,20,
&G.scene->r.YF_raydepth, 1.0, 80.0, 10, 10, "Maximum render ray depth from the camera");
uiDefButF(block, NUMSLI, B_DIFF, "Gam ", 5,10,150,20, &G.scene->r.YF_gamma, 0.001, 5.0, 0, 0, "Gamma correction, 1 is off");
uiDefButF(block, NUMSLI, B_DIFF, "Exp ", 160,10,150,20,&G.scene->r.YF_exposure, 0.0, 10.0, 0, 0, "Exposure adjustment, 0 is off");
- uiDefButI(block, NUM, B_DIFF, "Processors:", 160,35,150,20,
+ uiDefButI(block, NUM, B_DIFF, "Processors:", 160,35,150,20,
&G.scene->r.YF_numprocs, 1.0, 8.0, 10, 10, "Number of processors to use");
/*AA Settings*/
}
}
+static void render_panel_sfx(void)
+{
+ uiBlock *block;
+
+ block= uiNewBlock(&curarea->uiblocks, "editing_panel_camera_dof", UI_EMBOSS, UI_HELV, curarea->win);
+ uiNewPanelTabbed("Output", "Render");
+ if(uiNewPanel(curarea, block, "Post Effects", "Render", 320, 0, 318, 204)==0) return;
+
+ uiBlockBeginAlign(block);
+ uiDefButI(block, TOG|BIT|20,B_SET_ZBLUR,"Zblur", 10,180,140,20,&G.scene->r.mode,0,0, 0, 0, "Apply blur based on depth values in z-buffer");
+ uiDefButF(block, NUM,B_DIFF, "ZMin:", 10,160,140,20, &G.scene->r.zmin, 0.0, 1.0, 0, 0, "Specify the start distance with maximum blur");
+ uiDefButF(block, NUM,B_DIFF, "Focus:", 10,140,140,20, &G.scene->r.focus, 0.0, 1.0, 0, 0, "Specify the focus distance (not blurred)");
+ uiDefButF(block, NUM,B_DIFF, "Blur:", 10,120,140,20, &G.scene->r.zblur, 1.0, 100.0, 0, 0, "Specify the maximum blur radius");
+ uiDefButF(block, NUM,B_DIFF, "Gamma:", 10,100,140,20, &G.scene->r.zgamma, 0.05, 2.0, 0, 0, "Use Gamma corrected addition of colors");
+ uiDefButF(block, NUM,B_DIFF, "Sigma:", 10,80,140,20, &G.scene->r.zsigma, 1.0, 20.0, 0, 0, "Filter type control, higher value is stronger gaussian");
+
+ /* Toon shading buttons */
+ uiBlockBeginAlign(block);
+ uiDefButI(block, TOG|BIT|5, B_SET_EDGE, "Edge", 160, 180, 150, 20, &G.scene->r.mode, 0, 0, 0, 0, "Enable Toon edge shading");
+ uiDefBlockBut(block, edge_render_menu, NULL, "Edge Settings", 160, 160, 150, 20, "Display edge settings");
+
+ /* postprocess render buttons */
+ uiBlockBeginAlign(block);
+ if(R.rectftot)
+ uiDefIconTextButI(block, TOG|BIT|18, B_NOP, ICON_IMAGE_DEHLT," Fbuf", 160, 130, 150, 20, &G.scene->r.mode, 0, 0, 0, 0, "Keep RGBA float buffer after render; buffer available");
+ else
+ uiDefButI(block, TOG|BIT|18, 0,"Fbuf", 160, 130, 150, 20, &G.scene->r.mode, 0, 0, 0, 0, "Keep RGBA float buffer after render, no buffer available now");
+ uiDefBlockBut(block, post_render_menu, NULL, "Post process", 160, 110, 150, 20, "Applies on RGBA floats while render or with Fbuf available");
+ uiBlockEndAlign(block);
+
+ /* Dither control */
+ uiDefButF(block, NUM,B_DIFF, "Dither:", 160,80,150,20, &G.scene->r.dither_intensity, 0.0, 2.0, 0, 0, "The amount of dithering noise present in the output image (0.0 = no dithering)");
+
+}
+
+
void render_panels()
{
render_panel_output();
+ render_panel_sfx();
render_panel_render();
render_panel_anim();
render_panel_format();
if (rw->flags & RW_FLAGS_PIXEL_EXAMINING) {
int imgco[2];
char buf[64];
- unsigned int *pxl2;
- unsigned char *pxl;
+ int *pxlz; // zbuffer is signed
+ char *pxl;
if (R.rectot && renderwin_win_to_image_co(rw, rw->lmouse, imgco)) {
pxl= (char*) &R.rectot[R.rectx*imgco[1] + imgco[0]];
if (R.rectz) {
- pxl2= &R.rectz[R.rectx*imgco[1] + imgco[0]];
- sprintf(buf, "R: %d, G: %d, B: %d, A: %d, Z: %f", pxl[0], pxl[1], pxl[2], pxl[3], (float)(((float)*pxl2-(float)INT_MIN)/(float)UINT_MAX));
+ pxlz= &R.rectz[R.rectx*imgco[1] + imgco[0]];
+ sprintf(buf, "R: %d, G: %d, B: %d, A: %d, Z: %f", pxl[0], pxl[1], pxl[2], pxl[3], 0.5+0.5*( ((float)*pxlz)/(float)INT_MAX) );
}
else {
sprintf(buf, "R: %d, G: %d, B: %d, A: %d", pxl[0], pxl[1], pxl[2], pxl[3]);