Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTon Roosendaal <ton@blender.org>2006-01-24 01:05:47 +0300
committerTon Roosendaal <ton@blender.org>2006-01-24 01:05:47 +0300
commit042d612df219c8f6a29afa235537380f227b5684 (patch)
tree310a2c859b99c559115bbcda0aa70f2543bf962c /source/blender/render
parent5668480c99001a617fd59a2383deb858195ffb26 (diff)
Giant commit!
A full detailed description of this will be done later... is several days of work. Here's a summary: Render: - Full cleanup of render code, removing *all* globals and bad level calls all over blender. Render module is now not called abusive anymore - API-fied calls to rendering - Full recode of internal render pipeline. Is now rendering tiles by default, prepared for much smarter 'bucket' render later. - Each thread now can render a full part - Renders were tested with 4 threads, goes fine, apart from some lookup tables in softshadow and AO still - Rendering is prepared to do multiple layers and passes - No single 32 bits trick in render code anymore, all 100% floats now. Writing images/movies - moved writing images to blender kernel (bye bye 'schrijfplaatje'!) - made a new Movie handle system, also in kernel. This will enable much easier use of movies in Blender PreviewRender: - Using new render API, previewrender (in buttons) now uses regular render code to generate images. - new datafile 'preview.blend.c' has the preview scenes in it - previews get rendered in exact displayed size (1 pixel = 1 pixel) 3D Preview render - new; press Pkey in 3d window, for a panel that continuously renders (pkey is for games, i know... but we dont do that in orange now!) - this render works nearly identical to buttons-preview render, so it stops rendering on any event (mouse, keyboard, etc) - on moving/scaling the panel, the render code doesn't recreate all geometry - same for shifting/panning view - all other operations (now) regenerate the full render database still. - this is WIP... but big fun, especially for simple scenes! Compositor - Using same node system as now in use for shaders, you can composit images - works pretty straightforward... needs much more options/tools and integration with rendering still - is not threaded yet, nor is so smart to only recalculate changes... will be done soon! - the "Render Result" node will get all layers/passes as output sockets - The "Output" node renders to a builtin image, which you can view in the Image window. (yes, output nodes to render-result, and to files, is on the list!) The Bad News - "Unified Render" is removed. It might come back in some stage, but this system should be built from scratch. I can't really understand this code... I expect it is not much needed, especially with advanced layer/passes control - Panorama render, Field render, Motion blur, is not coded yet... (I had to recode every single feature in render, so...!) - Lens Flare is also not back... needs total revision, might become composit effect though (using zbuffer for visibility) - Part render is gone! (well, thats obvious, its default now). - The render window is only restored with limited functionality... I am going to check first the option to render to a Image window, so Blender can become a true single-window application. :) For example, the 'Spare render buffer' (jkey) doesnt work. - Render with border, now default creates a smaller image - No zbuffers are written yet... on the todo! - Scons files and MSVC will need work to get compiling again OK... thats what I can quickly recall. Now go compiling!
Diffstat (limited to 'source/blender/render')
-rw-r--r--source/blender/render/extern/include/RE_pipeline.h161
-rw-r--r--source/blender/render/extern/include/RE_render_ext.h (renamed from source/blender/render/intern/include/jitter.h)41
-rw-r--r--source/blender/render/extern/include/RE_shader_ext.h107
-rw-r--r--source/blender/render/extern/include/render.h304
-rw-r--r--source/blender/render/intern/include/RE_callbacks.h85
-rw-r--r--source/blender/render/intern/include/envmap.h5
-rw-r--r--source/blender/render/intern/include/errorHandler.h69
-rw-r--r--source/blender/render/intern/include/gammaCorrectionTables.h19
-rw-r--r--source/blender/render/intern/include/initrender.h22
-rw-r--r--source/blender/render/intern/include/pixelblending.h107
-rw-r--r--source/blender/render/intern/include/pixelshading.h42
-rw-r--r--source/blender/render/intern/include/renderHelp.h64
-rw-r--r--source/blender/render/intern/include/renderPreAndPost.h43
-rw-r--r--source/blender/render/intern/include/render_types.h (renamed from source/blender/render/extern/include/render_types.h)237
-rw-r--r--source/blender/render/intern/include/rendercore.h47
-rw-r--r--source/blender/render/intern/include/renderdatabase.h69
-rw-r--r--source/blender/render/intern/include/renderpipeline.h (renamed from source/blender/render/intern/include/outerRenderLoop.h)31
-rw-r--r--source/blender/render/intern/include/shadbuf.h2
-rw-r--r--source/blender/render/intern/include/texture.h5
-rw-r--r--source/blender/render/intern/include/vanillaRenderPipe.h59
-rw-r--r--source/blender/render/intern/include/vanillaRenderPipe_types.h87
-rw-r--r--source/blender/render/intern/include/zblur.h48
-rw-r--r--source/blender/render/intern/include/zbuf.h196
-rw-r--r--source/blender/render/intern/include/zbuf_types.h75
-rw-r--r--source/blender/render/intern/include/zbufferdatastruct.h98
-rw-r--r--source/blender/render/intern/include/zbufferdatastruct_types.h80
-rw-r--r--source/blender/render/intern/source/RE_callbacks.c168
-rw-r--r--source/blender/render/intern/source/convertblender.c3108
-rw-r--r--source/blender/render/intern/source/edgeRender.c150
-rw-r--r--source/blender/render/intern/source/envmap.c358
-rw-r--r--source/blender/render/intern/source/errorHandler.c102
-rw-r--r--source/blender/render/intern/source/gammaCorrectionTables.c14
-rw-r--r--source/blender/render/intern/source/imagetexture.c19
-rw-r--r--source/blender/render/intern/source/initrender.c1742
-rw-r--r--source/blender/render/intern/source/jitter.c198
-rw-r--r--source/blender/render/intern/source/pipeline.c954
-rw-r--r--source/blender/render/intern/source/pixelblending.c581
-rw-r--r--source/blender/render/intern/source/pixelshading.c295
-rw-r--r--source/blender/render/intern/source/ray.c405
-rw-r--r--source/blender/render/intern/source/renderHelp.c306
-rw-r--r--source/blender/render/intern/source/renderPreAndPost.c103
-rw-r--r--source/blender/render/intern/source/rendercore.c1419
-rw-r--r--source/blender/render/intern/source/renderdatabase.c446
-rw-r--r--source/blender/render/intern/source/shadbuf.c180
-rw-r--r--source/blender/render/intern/source/texture.c69
-rw-r--r--source/blender/render/intern/source/vanillaRenderPipe.c1641
-rw-r--r--source/blender/render/intern/source/zblur.c818
-rw-r--r--source/blender/render/intern/source/zbuf.c1986
-rw-r--r--source/blender/render/intern/source/zbufferdatastruct.c310
49 files changed, 7198 insertions, 10277 deletions
diff --git a/source/blender/render/extern/include/RE_pipeline.h b/source/blender/render/extern/include/RE_pipeline.h
new file mode 100644
index 00000000000..14d21b699a3
--- /dev/null
+++ b/source/blender/render/extern/include/RE_pipeline.h
@@ -0,0 +1,161 @@
+/**
+ * $Id$
+ *
+ * ***** BEGIN GPL 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.
+ *
+ * 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.
+ *
+ * The Original Code is Copyright (C) 2006 Blender Foundation.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+#ifndef RE_PIPELINE_H
+#define RE_PIPELINE_H
+
+#include "DNA_listBase.h"
+#include "DNA_vec_types.h"
+#include "BKE_utildefines.h"
+
+struct Scene;
+struct RenderData;
+
+/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
+/* this include is what is exposed of render to outside world */
+/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
+
+
+#define RE_MAXNAME 32
+
+/* only used as handle */
+typedef struct Render Render;
+
+/* Render Result usage:
+
+- render engine allocates/frees and delivers raw floating point rects
+- right now it's full rects, but might become tiles or file
+- the display client has to allocate display rects, sort out what to display,
+ and how it's converted
+*/
+
+/* a renderlayer is a full image, but with all passes and samples */
+/* size of the rects is defined in RenderResult */
+typedef struct RenderLayer {
+ struct RenderLayer *next, *prev;
+
+ char name[RE_MAXNAME];
+ int flag, type;
+
+ float *rectf; /* standard rgba buffer */
+ float *rectz; /* standard camera coordinate zbuffer */
+
+ ListBase passes;
+
+} RenderLayer;
+
+typedef struct RenderResult {
+
+ /* target image size */
+ int rectx, recty;
+ short crop, pad;
+
+ /* optional, 32 bits version of (composited?) layers */
+ int *rect32;
+
+ /* coordinates within final image (after cropping) */
+ rcti tilerect;
+
+ /* the main buffers */
+ ListBase layers;
+
+ /* optional saved endresult on disk */
+ char exrfile[FILE_MAXDIR];
+ int filehandle;
+
+} RenderResult;
+
+typedef struct RenderStats {
+ int totface, totvert, tothalo, totlamp, totpart;
+ short curfield, curblur, curpart, partsdone, convertdone;
+ double starttime, lastframetime;
+
+} RenderStats;
+
+/* *********************** API ******************** */
+
+/* the name is used as identifier, so elsewhere in blender the result can retrieved */
+/* calling a new render with same name, frees automatic existing render */
+Render *RE_NewRender (const char *name);
+Render *RE_GetRender(const char *name);
+
+/* use free render as signal to do everything over (previews) */
+void RE_FreeRender (Render *re);
+/* only called on exit */
+void RE_FreeAllRender (void);
+
+/* get results and statistics */
+RenderResult *RE_GetResult(Render *re);
+RenderStats *RE_GetStats(Render *re);
+void RE_ResultGet32(Render *re, unsigned int *rect);
+
+/* obligatory initialize call, disprect is optional */
+void RE_InitState (struct Render *re, struct RenderData *rd, int winx, int winy, rcti *disprect);
+
+/* use this to change disprect of active render */
+void RE_SetDispRect (struct Render *re, rcti *disprect);
+
+/* set up the viewplane/perspective matrix, three choices */
+void RE_SetCamera(Render *re, struct Object *camera);
+void RE_SetWindow (Render *re, rctf *viewplane, float clipsta, float clipend);
+void RE_SetOrtho (Render *re, rctf *viewplane, float clipsta, float clipend);
+
+/* option to set viewmatrix before making dbase */
+void RE_SetView (Render *re, float mat[][4]);
+
+/* make or free the dbase */
+void RE_Database_FromScene(Render *re, Scene *scene, int use_camera_view);
+void RE_Database_Free (Render *re);
+
+/* project dbase again, when viewplane/perspective changed */
+void RE_DataBase_ApplyWindow(Render *re);
+
+/* the main processor, assumes all was set OK! */
+void RE_TileProcessor(Render *re);
+
+/* only RE_NewRender() needed, main Blender render calls */
+void RE_BlenderFrame(Render *re, struct Scene *scene, int frame);
+void RE_BlenderAnim(Render *re, struct Scene *scene, int sfra, int efra);
+
+
+/* display and event callbacks */
+void RE_display_init_cb (Render *re, void (*f)(RenderResult *rr));
+void RE_display_clear_cb(Render *re, void (*f)(RenderResult *rr));
+void RE_display_draw_cb (Render *re, void (*f)(RenderResult *rr, struct rcti *rect));
+void RE_stats_draw_cb (Render *re, void (*f)(RenderStats *rs));
+void RE_timecursor_cb (Render *re, void (*f)(int));
+void RE_test_break_cb (Render *re, int (*f)(void));
+void RE_test_return_cb (Render *re, int (*f)(void));
+void RE_error_cb (Render *re, void (*f)(const char *str));
+
+
+
+
+#endif /* RE_PIPELINE_H */
+
diff --git a/source/blender/render/intern/include/jitter.h b/source/blender/render/extern/include/RE_render_ext.h
index 696ded297b1..b8fc573a9a5 100644
--- a/source/blender/render/intern/include/jitter.h
+++ b/source/blender/render/extern/include/RE_render_ext.h
@@ -1,17 +1,12 @@
-/*
- * jitter.h
- *
+/**
* $Id$
*
- * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
+ * ***** BEGIN GPL 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.
+ * of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
@@ -22,7 +17,7 @@
* along with this program; if not, write to the Free Software Foundation,
* Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
- * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * The Original Code is Copyright (C) 2006 by Blender Foundation
* All rights reserved.
*
* The Original Code is: all of this file.
@@ -32,21 +27,23 @@
* ***** END GPL/BL DUAL LICENSE BLOCK *****
*/
-#ifndef JITTER_H
-#define JITTER_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
+#ifndef RE_RENDER_EXT_H
+#define RE_RENDER_EXT_H
-extern float jit[64][2];
+/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
+/* this include is for non-render pipeline exports (still old cruft here) */
+/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
-extern void initjit(float *jitarr, int num);
-extern void init_render_jit(int nr);
+/* called by meshtools */
+void RE_make_sticky(void);
+
+/* for radiosity module */
+struct RadView;
+struct RNode;
+void RE_zbufferall_radio(struct RadView *vw, struct RNode **rg_elem, int rg_totelem, struct Render *re);
-#ifdef __cplusplus
-}
-#endif
+/* effect.c and editmesh_modes. */
+void externtex(struct MTex *mtex, float *vec, float *tin, float *tr, float *tg, float *tb, float *ta);
-#endif
+#endif /* RE_RENDER_EXT_H */
diff --git a/source/blender/render/extern/include/RE_shader_ext.h b/source/blender/render/extern/include/RE_shader_ext.h
new file mode 100644
index 00000000000..84204d88976
--- /dev/null
+++ b/source/blender/render/extern/include/RE_shader_ext.h
@@ -0,0 +1,107 @@
+/**
+ * $Id$
+ *
+ * ***** BEGIN GPL 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.
+ *
+ * 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.
+ *
+ * The Original Code is Copyright (C) 2006 by Blender Foundation
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL/BL DUAL LICENSE BLOCK *****
+ */
+
+#ifndef RE_SHADER_EXT_H
+#define RE_SHADER_EXT_H
+
+/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
+/* this include is for shading and texture exports */
+/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
+
+/* localized texture result data */
+/* note; tr tg tb ta has to remain in this order */
+typedef struct TexResult {
+ float tin, tr, tg, tb, ta;
+ int talpha;
+ float *nor;
+} TexResult;
+
+/* localized shade result data */
+typedef struct ShadeResult
+{
+ float diff[3];
+ float spec[3];
+ float alpha;
+
+} ShadeResult;
+
+/* localized renderloop data */
+typedef struct ShadeInput
+{
+ struct Material *mat;
+ struct VlakRen *vlr;
+ float co[3];
+
+ /* copy from material, keep synced so we can do memcopy */
+ /* current size: 23*4 */
+ float r, g, b;
+ float specr, specg, specb;
+ float mirr, mirg, mirb;
+ float ambr, ambb, ambg;
+
+ float amb, emit, ang, spectra, ray_mirror;
+ float alpha, refl, spec, zoffs, add;
+ float translucency;
+ /* end direct copy from material */
+
+ /* individual copies: */
+ int har;
+ float layerfac;
+
+ /* texture coordinates */
+ float lo[3], gl[3], uv[3], ref[3], orn[3], winco[3], sticky[3], vcol[3], rad[3];
+ float vn[3], vno[3], facenor[3], view[3], refcol[4], displace[3], strand, tang[3], stress;
+
+ /* dx/dy OSA coordinates */
+ float dxco[3], dyco[3];
+ float dxlo[3], dylo[3], dxgl[3], dygl[3], dxuv[3], dyuv[3];
+ float dxref[3], dyref[3], dxorn[3], dyorn[3];
+ float dxno[3], dyno[3], dxview, dyview;
+ float dxlv[3], dylv[3];
+ float dxwin[3], dywin[3];
+ float dxsticky[3], dysticky[3];
+ float dxrefract[3], dyrefract[3];
+ float dxstrand, dystrand;
+
+ int xs, ys; /* pixel to be rendered */
+ short do_preview; /* for nodes, in previewrender */
+ short thread;
+ short osatex, puno;
+ int mask;
+ int depth;
+
+} ShadeInput;
+
+
+/* node shaders... */
+int multitex(struct Tex *tex, float *texvec, float *dxt, float *dyt, int osatex, struct TexResult *texres);
+
+
+#endif /* RE_SHADER_EXT_H */
+
diff --git a/source/blender/render/extern/include/render.h b/source/blender/render/extern/include/render.h
deleted file mode 100644
index 0622ae79112..00000000000
--- a/source/blender/render/extern/include/render.h
+++ /dev/null
@@ -1,304 +0,0 @@
-/**
- * $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.
- *
- * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
- * All rights reserved.
- *
- * The Original Code is: all of this file.
- *
- * Contributor(s): none yet.
- *
- * ***** END GPL/BL DUAL LICENSE BLOCK *****
- * Interface to transform the Blender scene into renderable data.
- */
-
-#ifndef RENDER_H
-#define RENDER_H
-
-/* ------------------------------------------------------------------------- */
-/* This little preamble might be moved to a separate include. It contains */
-/* some defines that should become functions, and some platform dependency */
-/* fixes. I think it is risky to always include it... */
-/* ------------------------------------------------------------------------- */
-
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* ------------------------------------------------------------------------- */
-/* Types */
-/* Both external and internal types can be placed here. Make sure there are */
-/* no dirty extras in the type files so they can be included without */
-/* problems. If possible, make a note why the include is needed. */
-/* ------------------------------------------------------------------------- */
-
-#include "render_types.h"
-
-/* ------------------------------------------------------------------------- */
-/* Global variables */
-/* These variable are global to the render module, and also externally */
-/* visible. The file where they are defined must be added. */
-/* ------------------------------------------------------------------------- */
-
-extern RE_Render R; /* rendercore.c */
-extern unsigned short *igamtab1; /* initrender.c */
-extern unsigned short *gamtab; /* initrender.c */
-
-struct View3D;
-
-/* ------------------------------------------------------------------------- */
-/* Function definitions */
-/* */
-/* All functions that need to be externally visible must be declared here. */
-/* Currently, this interface contains 38 functions and 11 callbacks. */
-/* ------------------------------------------------------------------------- */
-
-
-/* ------------------------------------------------------------------------- */
-/* shadbuf.c (1) */
-/* ------------------------------------------------------------------------- */
-
-/* only for renderconvertor */
-void RE_initshadowbuf(struct LampRen *lar, float mat[][4]);
-
-
-/* ------------------------------------------------------------------------- */
-/* initrender (9) */
-/* ------------------------------------------------------------------------- */
-
-struct View3D;
-
-/**
- * Guarded call to frame renderer? Tests several limits and boundary
- * conditions.
- *
- * @param ogl_render_area The View3D area to use for OpenGL rendering
- * (can be NULL unless render R_OGL flag is set)
- */
-void RE_initrender(struct View3D *ogl_render_view3d);
-
-/**
- * only for renderconvertor
- */
-void RE_setwindowclip(int mode, int jmode);
-
-/*
- * @param ogl_render_area The View3D area to use for OpenGL rendering
- * (can be NULL unless render R_OGL flag is set)
- */
-void RE_animrender(struct View3D *ogl_render_view3d);
-void RE_free_render_data(void);
-void RE_init_render_data(void);
- /* jitterate is used by blenkernel effect */
-void RE_jitterate1(float *jit1, float *jit2, int num, float rad1);
-void RE_jitterate2(float *jit1, float *jit2, int num, float rad2);
-void RE_make_existing_file(char *name);
-void RE_floatbuffer_to_output(void);
-
-/* ------------------------------------------------------------------------- */
-/* zbuf (2) */
-/* ------------------------------------------------------------------------- */
-
-/**
- * Converts a world coordinate into a homogenous coordinate in view
- * coordinates. (WCS -> HCS)
- * Also called in: shadbuf.c render.c radfactors.c
- * initrender.c envmap.c editmesh.c
- * @param v1 [3 floats] the world coordinate
- * @param adr [4 floats] the homogenous view coordinate
- */
-void RE_projectverto(float *v1,float *adr);
-
-/**
- * Something about doing radiosity z buffering?
- * (called in radfactors.c), hope the RadView is defined already...
- * Also called in: radfactors.c
- * Note: Uses globals.
- * @param radview radiosity view definition
- */
- struct RadView;
- struct RNode;
-void RE_zbufferall_radio(struct RadView *vw, struct RNode **rg_elem, int rg_totelem);
-
-
-/* ------------------------------------------------------------------------- */
-/* texture (9) */
-/* ------------------------------------------------------------------------- */
-struct MTex;
-struct Tex;
-struct TexResult;
-
-void init_render_textures(void);
-void init_render_texture(struct Tex *tex);
-
-void do_material_tex(ShadeInput *shi);
-void do_lamp_tex(struct LampRen *la, float *lavec, ShadeInput *shi, float *fcol);
-
-int multitex(struct Tex *tex, float *texvec, float *dxt, float *dyt, int osatex, struct TexResult *texres);
-int multitex_ext(struct Tex *tex, float *texvec, float *tin, float *tr, float *tg, float *tb, float *ta);
-void externtex(struct MTex *mtex, float *vec, float *tin, float *tr, float *tg, float *tb, float *ta);
-
-/* ------------------------------------------------------------------------- */
-/* envmap (4) */
-/* ------------------------------------------------------------------------- */
-struct EnvMap;
-
-void RE_free_envmapdata(struct EnvMap *env);
-void RE_free_envmap(struct EnvMap *env);
-struct EnvMap *RE_add_envmap(void);
-/* these two maybe not external? yes, they are, for texture.c */
-struct EnvMap *RE_copy_envmap(struct EnvMap *env);
-
-/* --------------------------------------------------------------------- */
-/* rendercore (12) */
-/* --------------------------------------------------------------------- */
-struct MaterialLayer;
-struct ShadeResult;
-
-float Phong_Spec(float *n, float *l, float *v, int hard, int tangent);
-float CookTorr_Spec(float *n, float *l, float *v, int hard, int tangent);
-float Blinn_Spec(float *n, float *l, float *v, float refrac, float spec_power, int tangent);
-float Toon_Spec( float *n, float *l, float *v, float size, float smooth, int tangent);
-float WardIso_Spec(float *n, float *l, float *v, float rms, int tangent);
-
-float OrenNayar_Diff(float *n, float *l, float *v, float rough);
-float Toon_Diff( float *n, float *l, float *v, float size, float smooth);
-float Minnaert_Diff( float nl, float *n, float *v, float darkness);
-float Fresnel_Diff(float *vn, float *lv, float *view, float ior, float fac);
-
-void add_to_diffuse(float *diff, ShadeInput *shi, float is, float r, float g, float b);
-void ramp_diffuse_result(float *diff, ShadeInput *shi);
-void do_specular_ramp(ShadeInput *shi, float is, float t, float *spec);
-void ramp_spec_result(float *specr, float *specg, float *specb, ShadeInput *shi);
-
-void matlayer_blend(struct MaterialLayer *ml, float blendfac, struct ShadeResult *target, struct ShadeResult *src);
-void ramp_blend(int type, float *r, float *g, float *b, float fac, float *col);
-
-void shade_material_loop(struct ShadeInput *shi, struct ShadeResult *shr);
-
-/* --------------------------------------------------------------------- */
-/* ray.c (2) */
-/* --------------------------------------------------------------------- */
-void init_jitter_plane(LampRen *lar);
-void init_ao_sphere(float *sphere, int tot, int iter);
-
-
-/* --------------------------------------------------------------------- */
-/* renderdatabase () */
-/* --------------------------------------------------------------------- */
-struct VlakRen *RE_findOrAddVlak(int nr);
-struct VertRen *RE_findOrAddVert(int nr);
-struct HaloRen *RE_findOrAddHalo(int nr);
-HaloRen *RE_inithalo(struct Material *ma, float *vec, float *vec1, float *orco, float hasize,
- float vectsize, int seed);
-
-float *RE_vertren_get_sticky(struct VertRen *ver, int verify);
-float *RE_vertren_get_stress(struct VertRen *ver, int verify);
-float *RE_vertren_get_rad(struct VertRen *ver, int verify);
-float *RE_vertren_get_strand(struct VertRen *ver, int verify);
-float *RE_vertren_get_tangent(struct VertRen *ver, int verify);
-
-void RE_free_vertex_tables(void);
-void RE_init_vertex_tables(void);
-
-/**
- * callbacks (11):
- *
- * If the callbacks aren't set, rendering will still proceed as
- * desired, but the concerning functionality will not be enabled.
- *
- * There need to be better uncoupling between the renderer and
- * these functions still!
- * */
-
-void RE_set_test_break_callback(int (*f)(void));
-
-void RE_set_timecursor_callback(void (*f)(int));
-
-void RE_set_renderdisplay_callback(void (*f)(int, int, int, int, unsigned int *));
-void RE_set_initrenderdisplay_callback(void (*f)(void));
-void RE_set_clearrenderdisplay_callback(void (*f)(short));
-
-void RE_set_printrenderinfo_callback(void (*f)(double,int));
-
-void RE_set_getrenderdata_callback(void (*f)(void));
-void RE_set_freerenderdata_callback(void (*f)(void));
-
-
-/*from renderhelp, should disappear!!! */
-/** Recalculate all normals on renderdata. */
-void set_normalflags(void);
-/**
- * On loan from zbuf.h:
- * Tests whether the first three coordinates should be clipped
- * wrt. the fourth component. Bits 1 and 2 test on x, 3 and 4 test on
- * y, 5 and 6 test on z:
- * xyz > test => set first bit (01),
- * xyz < -test => set second bit (10),
- * xyz == test => reset both bits (00).
- * Note: functionality is duplicated from an internal function
- * Also called in: initrender.c, radfactors.c
- * @param v [4 floats] a coordinate
- * @return a vector of bitfields
- */
-int RE_testclip(float *v);
-
-/* patch for the external if, to support the split for the ui */
-void RE_addalphaAddfac(char *doel, char *bron, char addfac);
-void RE_sky_char(float *view, char *col);
-void RE_renderflare(struct HaloRen *har);
-/**
- * Shade the pixel at xn, yn for halo har, and write the result to col.
- * Also called in: previewrender.c
- * @param har The halo to be rendered on this location
- * @param col [char 4] The destination colour vector
- * @param colf [float 4] destination colour vector (need both)
- * @param zz Some kind of distance
- * @param dist Square of the distance of this coordinate to the halo's center
- * @param x [f] Pixel x relative to center
- * @param y [f] Pixel y relative to center
- * @param flarec Flare counter? Always har->flarec...
- */
-void RE_shadehalo(struct HaloRen *har,
- char *col, float *colf,
- int zz,
- float dist,
- float x,
- float y,
- short flarec);
-
-/***/
-
-/* haloren->type: flags */
-
-#define HA_ONLYSKY 1
-#define HA_VECT 2
-#define HA_XALPHA 4
-#define HA_FLARECIRC 8
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* RENDER_H */
-
diff --git a/source/blender/render/intern/include/RE_callbacks.h b/source/blender/render/intern/include/RE_callbacks.h
deleted file mode 100644
index 159eaa84ca4..00000000000
--- a/source/blender/render/intern/include/RE_callbacks.h
+++ /dev/null
@@ -1,85 +0,0 @@
-/**
- * $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.
- *
- * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
- * All rights reserved.
- *
- * The Original Code is: all of this file.
- *
- * Contributor(s): none yet.
- *
- * ***** END GPL/BL DUAL LICENSE BLOCK *****
- * Callbacks to make the renderer interact with calling modules.
- */
-
-#ifndef RE_CALLBACKS_H
-#define RE_CALLBACKS_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
- /**
- * Test whether operation should be prematurely terminated.
- *
- * @returns 0 to continue, any other value to break.
- */
- int RE_local_test_break(void);
-
- /**
- * Set a red square with the argument as text as cursor.
- */
- void RE_local_timecursor(int i);
-
- /**
- * Render these lines from the renderbuffer on screen (needs better spec)
- */
- void RE_local_render_display(int i, int j, int k, int l, unsigned int *m);
-
- /**
- * Initialise a render display (needs better spec)
- */
- void RE_local_init_render_display(void);
-
- /**
- * Clear/close a render display (needs better spec)
- */
- void RE_local_clear_render_display(short);
-
- /**
- * Print render statistics.
- */
- void RE_local_printrenderinfo(double time, int i);
-
- /** Get the data for the scene to render. */
- void RE_local_get_renderdata(void);
-
- /** Release the data for the scene that was rendered. */
- void RE_local_free_renderdata(void);
-
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
-
diff --git a/source/blender/render/intern/include/envmap.h b/source/blender/render/intern/include/envmap.h
index 7a44a139b20..32d72555ca4 100644
--- a/source/blender/render/intern/include/envmap.h
+++ b/source/blender/render/intern/include/envmap.h
@@ -41,10 +41,11 @@
* (initrender.c)
*/
+struct Render;
struct TexResult;
-void make_envmaps(void);
-int envmaptex(struct Tex *tex, float *texvec, float *dxt, float *dyt, int osatex, struct TexResult *texres);
+void make_envmaps(struct Render *re);
+int envmaptex(struct Tex *tex, float *texvec, float *dxt, float *dyt, int osatex, struct TexResult *texres);
#endif /* ENVMAP_EXT_H */
diff --git a/source/blender/render/intern/include/errorHandler.h b/source/blender/render/intern/include/errorHandler.h
deleted file mode 100644
index fb980fa255a..00000000000
--- a/source/blender/render/intern/include/errorHandler.h
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * errorHandler.h
- *
- * $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.
- *
- * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
- * All rights reserved.
- *
- * The Original Code is: all of this file.
- *
- * Contributor(s): none yet.
- *
- * ***** END GPL/BL DUAL LICENSE BLOCK *****
- */
-
-#ifndef ERRORHANDLER_H
-#define ERRORHANDLER_H
-
-/* error codes */
-enum RE_RENDER_ERROR {
- RE_NO_ERROR,
- RE_DEPTH_MISMATCH, /* 1. conflict resolution detects a bad z value */
- RE_BAD_FACE_TYPE, /* 2. a face type switch fails */
- RE_BAD_FACE_INDEX, /* 3. tried to do an operation with a bad index */
- RE_BAD_DATA_POINTER,
- RE_TRACE_COUNTER,
- RE_TOO_MANY_FACES, /* 6. overflow on z-buffer depth */
- RE_EDGERENDER_WRITE_OUTSIDE_BUFFER, /* 7. write value outside buffer */
- RE_CANNOT_ALLOCATE_MEMORY, /* 8. no memory for malloc */
- RE_WRITE_OUTSIDE_COLOUR_BUFFER, /* 9. write outside colour target buffer */
- RE_MAX_ERROR
-};
-
-/**
- * Reset all counters for the error trace
- */
-void RE_errortrace_reset(void);
-
-/**
- * Signals an error to screen. Counts repetitive errors
- */
-void RE_error(int errType, char* fname);
-
-/**
- * Signals an error, and prints an integer argument
- */
-void RE_error_int(int errType, char* fname, int valye);
-
-#endif /* ERRORHANDLER_H */
-
diff --git a/source/blender/render/intern/include/gammaCorrectionTables.h b/source/blender/render/intern/include/gammaCorrectionTables.h
index 6197f769f6f..3d0928f84a3 100644
--- a/source/blender/render/intern/include/gammaCorrectionTables.h
+++ b/source/blender/render/intern/include/gammaCorrectionTables.h
@@ -35,26 +35,12 @@
#ifndef GAMMACORRECTIONTABLES_H
#define GAMMACORRECTIONTABLES_H
-/* Default gamma. For most CRTs, gamma ranges from 2.2 to 2.5 (Foley), so */
-/* 2.35 seems appropriate enough. Experience teaches a different number */
-/* though. Old blender: 2.0. It might be nice to make this a slider */
-#define RE_DEFAULT_GAMMA 2.0
-/* This 400 is sort of based on the number of intensity levels needed for */
-/* the typical dynamic range of a medium, in this case CRTs. (Foley) */
-/* (Actually, it says the number should be between 400 and 535.) */
-#define RE_GAMMA_TABLE_SIZE 400
-
/**
* Initialise the gamma lookup tables
*/
void makeGammaTables(float gamma);
/**
- * Returns true if the table is initialised, false otherwise
- */
-int gammaTableIsInitialised(void);
-
-/**
* Apply gamma correction on col
*/
float gammaCorrect(float col);
@@ -64,10 +50,5 @@ float gammaCorrect(float col);
*/
float invGammaCorrect(float col);
-/**
- * Tell whether or not to do gamma.
- */
-extern int do_gamma;
-
#endif
diff --git a/source/blender/render/intern/include/initrender.h b/source/blender/render/intern/include/initrender.h
index 15ec3eb69a3..9a94d193990 100644
--- a/source/blender/render/intern/include/initrender.h
+++ b/source/blender/render/intern/include/initrender.h
@@ -32,19 +32,21 @@
* ***** END GPL/BL DUAL LICENSE BLOCK *****
*/
-#ifndef INITRENDER_EXT_H
-#define INITRENDER_EXT_H
+#ifndef INITRENDER_H
+#define INITRENDER_H
-/* type includes */
-
-#include "DNA_effect_types.h" /* for PartEff type */
-#include "render_types.h"
+struct Object;
/* Functions */
-void schrijfplaatje(char *name);
-void render(void); /* Switch between the old and the unified renderer. */
-/* void write_screendump(char *name); not here !*/
+void free_sample_tables(Render *re);
+void make_sample_tables(Render *re);
+
+void render_scene_set_window(Render *re, struct Object *camera, int blursample);
+
+void initparts(Render *re);
+void freeparts(Render *re);
+
-#endif /* INITRENDER_EXT_H */
+#endif /* INITRENDER_H */
diff --git a/source/blender/render/intern/include/pixelblending.h b/source/blender/render/intern/include/pixelblending.h
index b82642a34d0..bc44c916701 100644
--- a/source/blender/render/intern/include/pixelblending.h
+++ b/source/blender/render/intern/include/pixelblending.h
@@ -1,18 +1,12 @@
/*
- * pixelblending_ext.h
- * external interface for pixelblending
- *
* $Id$
*
- * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
+ * ***** BEGIN GPL 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.
+ * of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
@@ -26,9 +20,7 @@
* The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
* All rights reserved.
*
- * The Original Code is: all of this file.
- *
- * Contributor(s): none yet.
+ * Contributor(s): 2004-2006 Blender Foundation, full recode
*
* ***** END GPL/BL DUAL LICENSE BLOCK *****
*/
@@ -36,41 +28,12 @@
#ifndef PIXELBLENDING_EXT_H
#define PIXELBLENDING_EXT_H
-/* local includes */
-#include "vanillaRenderPipe_types.h"
-
-/**
- * Halo-add pixel, bring your own R.osa setting, and add factor
- */
-void addAddSampColF(float *s, float *d, int m, int osa, char add);
-
-/**
- * Alpha undersamples pixel, bring your own R.osa setting
- */
-int addUnderSampColF(float *sampcol, float *dest, int mask, int osaNr);
-
-/**
- * Alpha oversample pixel, bring your own R.osa setting
- */
-void addOverSampColF(float *sampcol, float *dest, int mask, int osaNr);
/**
* add 1 pixel to into filtered three lines
* (float vecs to float vec)
*/
-void add_filt_fmask(unsigned int mask, float *col, float *rb1, float *rb2, float *rb3);
-
-/**
- * Convert a series of oversampled pixels into filtered three lines
- * (float vecs to float vec)
- */
-void sampleFloatColV2FloatColVFilter(float *sample, float *dest1, float *dest2, float *dest3, int osaNr);
-
-/**
- * Convert a series of oversampled pixels into a single pixel. Uses R.osa to
- * count the length! (short vecs to short vec)
- */
-void sampleShortColV2ShortColV(unsigned short *sample, unsigned short *dest, int osaNr);
+void add_filt_fmask(unsigned int mask, float *col, float *rowbuf, int row_w);
/**
* Alpha-over blending for floats.
@@ -82,50 +45,6 @@ void addAlphaOverFloat(float *dest, float *source);
*/
void addAlphaUnderFloat(float *dest, float *source);
-/**
- * Write a 16-bit-colour colour vector to a 8-bit-colour colour vector.
- */
-void cpShortColV2CharColV(unsigned short *source, char *dest);
-
-/**
- * Write a 8-bit-colour colour vector to a 16-bit-colour colour vector.
- */
-void cpCharColV2ShortColV(char *source, unsigned short *dest);
-
-/**
- * Write a 32-bit-colour colour vector to a 8-bit-colour colour vector.
- */
-void cpIntColV2CharColV(unsigned int *source, char *dest);
-
-/**
- * Write a floating-point-colour colour vector to a 8-bit-colour colour
- * vector. Clip colours to [0, 1].
- */
-void cpFloatColV2CharColV(float *source, char *dest);
-
-/**
- * Cpoy a 8-bit-colour vector to floating point colour vector.
- */
-void cpCharColV2FloatColV(char *source, float *dest);
-/**
- * Cpoy a 16-bit-colour vector to floating point colour vector.
- */
-void cpShortColV2FloatColV(unsigned short *source, float *dest);
-
-/**
- * Copy a float-colour colour vector.
- */
-void cpFloatColV(float *source, float *dest);
-
-/**
- * Copy a 16-bit-colour colour vector.
- */
-void cpShortColV(unsigned short *source, unsigned short *dest);
-
-/**
- * Copy an 8-bit-colour colour vector.
- */
-void cpCharColV(char *source, char *dest);
/**
* Same for floats
@@ -137,26 +56,20 @@ void addalphaAddfacFloat(float *dest, float *source, char addfac);
*/
void addalphaAddFloat(float *dest, float *source);
-/** ols functions: side effects?
-void addalphaUnderFloat(char *doel, char *bron); think this already exists...
-void addalphaUnderGammaFloat(char *doel, char *bron);
-*/
/**
* Blend bron under doel, while doing gamma correction
*/
void addalphaUnderGammaFloat(float *doel, float *bron);
/**
- * Transform an premul-alpha 32-bit colour into a key-alpha 32-bit colour.
+* Copy the colour buffer output to R.rectot, to line y.
+ */
+void transferColourBufferToOutput(float *buf, int y);
+/**
+* using default transforms for brightness, gamma, hue, saturation etc.
*/
-void applyKeyAlphaCharCol(char* target);
+void std_floatcol_to_charcol(float *buf, char *target);
-/* Old blending functions */
-void keyalpha(char *doel); /* maakt premul 255 */
-void addalphaUnder(char *doel, char *bron);
-void addalphaUnderGamma(char *doel, char *bron);
-void addalphaOver(char *doel, char *bron);
-void addalphaAdd(char *doel, char *bron);
#endif /* PIXELBLENDING_EXT_H */
diff --git a/source/blender/render/intern/include/pixelshading.h b/source/blender/render/intern/include/pixelshading.h
index a7a611ed117..67b0e5bcf3c 100644
--- a/source/blender/render/intern/include/pixelshading.h
+++ b/source/blender/render/intern/include/pixelshading.h
@@ -1,19 +1,12 @@
/*
- * pixelshading.h
- *
- * These functions determine what actual colour a pixel will have.
- *
* $Id$
*
- * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
+ * ***** BEGIN GPL 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.
+ * of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
@@ -27,19 +20,20 @@
* The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
* All rights reserved.
*
- * The Original Code is: all of this file.
- *
- * Contributor(s): none yet.
+ * Contributor(s): 2004-2006, Blender Foundation, full recode
*
- * ***** END GPL/BL DUAL LICENSE BLOCK *****
+ * ***** END GPL LICENSE BLOCK *****
*/
+/* pixelshading.h
+*
+* These functions determine what actual colour a pixel will have.
+*/
+
+
#ifndef PIXELSHADING_H
#define PIXELSHADING_H
-#include "render.h"
-#include "vanillaRenderPipe_types.h"
-
/**
* Render the pixel at (x,y) for object ap. Apply the jitter mask.
* Output is given in float collector[4]. The type vector:
@@ -51,30 +45,18 @@
* mask is pixel coverage in bits
* @return pointer to the object
*/
-void *renderPixel(RE_COLBUFTYPE *collector, float x, float y, int *t, int mask);
-
-
-void setSkyBlendingMode(enum RE_SkyAlphaBlendingType mode);
-
void shadeHaloFloat(HaloRen *har,
float *col, int zz,
float dist, float xn,
float yn, short flarec);
/**
- * Get the sky blending mode.
- */
-enum RE_SkyAlphaBlendingType getSkyBlendingMode(void);
-/**
* Render the sky at pixel (x, y).
*/
-void renderSkyPixelFloat(RE_COLBUFTYPE *collector, float x, float y, float *rco);
-void shadeSkyPixel(RE_COLBUFTYPE *collector, float fx, float fy, float *rco);
+void renderSkyPixelFloat(float *collector, float x, float y, float *rco);
+void shadeSkyPixel(float *collector, float fx, float fy, float *rco);
void shadeSkyPixelFloat(float *colf, float *rco, float *view, float *dxyview);
-void renderSpotHaloPixel(float x, float y, float *target);
-void fillBackgroundImageChar(char *col, float x, float y);
-
/* ------------------------------------------------------------------------- */
#endif
diff --git a/source/blender/render/intern/include/renderHelp.h b/source/blender/render/intern/include/renderHelp.h
deleted file mode 100644
index 318b538d510..00000000000
--- a/source/blender/render/intern/include/renderHelp.h
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * renderhelp_ext.h
- *
- * $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.
- *
- * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
- * All rights reserved.
- *
- * The Original Code is: all of this file.
- *
- * Contributor(s): none yet.
- *
- * ***** END GPL/BL DUAL LICENSE BLOCK *****
- */
-
-#ifndef RENDERHELP_EXT_H
-#define RENDERHELP_EXT_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
- /* Push-pop, because this sometimes is necessary... */
- void pushTempPanoPhi(float p);
- void popTempPanoPhi(void);
-
- float getPanoPhi(void);
- float getPanovCo(void);
- float getPanovSi(void);
- void setPanoRot(int part);
-
- /** Set clip flags on all data entries, using the given projection
- * function */
- void setzbufvlaggen( void (*projectfunc)(float *, float *) );
-
-/* external for the time being, since the converter calls it. */
-/** Recalculate all normals on renderdata. */
-/* void set_normalflags(void); */
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
-
diff --git a/source/blender/render/intern/include/renderPreAndPost.h b/source/blender/render/intern/include/renderPreAndPost.h
deleted file mode 100644
index 59315868010..00000000000
--- a/source/blender/render/intern/include/renderPreAndPost.h
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * renderpreandpost.h
- *
- * $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.
- *
- * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
- * All rights reserved.
- *
- * The Original Code is: all of this file.
- *
- * Contributor(s): none yet.
- *
- * ***** END GPL/BL DUAL LICENSE BLOCK *****
- */
-
-#ifndef RENDERPREANDPOST_H
-#define RENDERPREANDPOST_H
-
-void prepareScene(void);
-void finalizeScene(void);
-void doClipping( void (*projectfunc)(float *, float *) );
-
-#endif
-
diff --git a/source/blender/render/extern/include/render_types.h b/source/blender/render/intern/include/render_types.h
index 8fad87c2707..c73deca6d22 100644
--- a/source/blender/render/extern/include/render_types.h
+++ b/source/blender/render/intern/include/render_types.h
@@ -20,9 +20,7 @@
* The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
* All rights reserved.
*
- * The Original Code is: all of this file.
- *
- * Contributor(s): none yet.
+ * Contributor(s): (c) 2006 Blender Foundation, full refactor
*
* ***** END GPL LICENSE BLOCK *****
*/
@@ -30,154 +28,150 @@
#ifndef RENDER_TYPES_H
#define RENDER_TYPES_H
+/* ------------------------------------------------------------------------- */
+/* exposed internal in render module only! */
+/* ------------------------------------------------------------------------- */
+
#include "DNA_scene_types.h"
#include "DNA_world_types.h"
#include "DNA_object_types.h"
+#include "DNA_vec_types.h"
-#define TABLEINITSIZE 1024
-#define LAMPINITSIZE 256
-
-/* This is needed to not let VC choke on near and far... old
- * proprietary MS extensions... */
-#ifdef WIN32
-#undef near
-#undef far
-#define near clipsta
-#define far clipend
-#endif
+#include "RE_pipeline.h"
+#include "RE_shader_ext.h" /* TexResult, ShadeResult, ShadeInput */
-/* ------------------------------------------------------------------------- */
+struct MemArena;
+struct VertTableNode;
+struct Octree;
+struct GHash;
-/* localized texture result data */
-/* note; tr tg tb ta has to remain in this order */
-typedef struct TexResult {
- float tin, tr, tg, tb, ta;
- int talpha;
- float *nor;
-} TexResult;
+#define TABLEINITSIZE 1024
+#define LAMPINITSIZE 256
-/* localized shade result data */
-typedef struct ShadeResult
+typedef struct SampleTables
{
- float diff[3];
- float spec[3];
- float alpha;
+ float centLut[16];
+ float *fmask1[9], *fmask2[9];
+ char cmask[256], *centmask;
-} ShadeResult;
+} SampleTables;
-/* localized renderloop data */
-typedef struct ShadeInput
+/* this is handed over to threaded hiding/passes/shading engine */
+typedef struct RenderPart
{
- struct Material *mat;
- struct VlakRen *vlr;
- float co[3];
-
- /* copy from material, keep synced so we can do memcopy */
- /* current size: 23*4 */
- float r, g, b;
- float specr, specg, specb;
- float mirr, mirg, mirb;
- float ambr, ambb, ambg;
+ struct RenderPart *next, *prev;
- float amb, emit, ang, spectra, ray_mirror;
- float alpha, refl, spec, zoffs, add;
- float translucency;
- /* end direct copy from material */
+ /* result of part rendering */
+ RenderResult *result;
- /* individual copies: */
- int har;
- float layerfac;
+ unsigned int *rectp; /* polygon index table */
+ int *rectz; /* zbuffer */
+ long *rectdaps; /* delta acum buffer for pixel structs */
- /* texture coordinates */
- float lo[3], gl[3], uv[3], ref[3], orn[3], winco[3], sticky[3], vcol[3], rad[3];
- float vn[3], vno[3], facenor[3], view[3], refcol[4], displace[3], strand, tang[3], stress;
+ rcti disprect; /* part coordinates within total picture */
+ int rectx, recty; /* the size */
+ short crop, ready; /* crop is amount of pixels we crop, for filter */
+ short sample, nr; /* sample can be used by zbuffers, nr is partnr */
+ short thread; /* thread id */
- /* dx/dy OSA coordinates */
- float dxco[3], dyco[3];
- float dxlo[3], dylo[3], dxgl[3], dygl[3], dxuv[3], dyuv[3];
- float dxref[3], dyref[3], dxorn[3], dyorn[3];
- float dxno[3], dyno[3], dxview, dyview;
- float dxlv[3], dylv[3];
- float dxwin[3], dywin[3];
- float dxsticky[3], dysticky[3];
- float dxrefract[3], dyrefract[3];
- float dxstrand, dystrand;
-
- int xs, ys; /* pixel to be rendered */
- short do_preview, pr_type; /* for nodes, in previewrender */
- short osatex, puno;
- int mask;
- int depth;
-
-} ShadeInput;
+} RenderPart;
-struct MemArena;
-struct VertTableNode;
+typedef struct Octree {
+ struct Branch **adrbranch;
+ struct Node **adrnode;
+ float ocsize; /* ocsize: mult factor, max size octree */
+ float ocfacx,ocfacy,ocfacz;
+ float min[3], max[3];
+ int ocres;
+ int branchcount, nodecount;
+} Octree;
-/* here only stuff to initalize the render itself */
-typedef struct RE_Render
-{
- float grvec[3];
- float imat[3][3];
+/* controls state of render, everything that's read-only during render stage */
+struct Render
+{
+ struct Render *next, *prev;
+ char name[RE_MAXNAME];
+
+ /* state settings */
+ short flag, osa, ok, do_gamma;
+
+ /* result of rendering */
+ RenderResult *result;
+
+ /* window size, display rect, viewplane */
+ int winx, winy;
+ rcti disprect; /* part within winx winy */
+ rctf viewplane; /* mapped on winx winy */
+ float viewdx, viewdy; /* size of 1 pixel */
+
+ /* final picture width and height (within disprect) */
+ int rectx, recty;
+
+ /* correction values for pixels or view */
+ float ycor, viewfac;
+ float bluroffsx, bluroffsy;
+ float panosi, panoco;
+
+ /* Matrices */
+ float grvec[3]; /* for world */
+ float imat[3][3]; /* copy of viewinv */
float viewmat[4][4], viewinv[4][4];
- float persmat[4][4], persinv[4][4];
float winmat[4][4];
- short flag, osa, rt, pad;
- /**
- * Screen sizes and positions, in pixels
- */
- short xstart, xend, ystart, yend, afmx, afmy;
- short rectx; /* Picture width - 1, normally xend - xstart. */
- short recty; /* picture height - 1, normally yend - ystart. */
-
- /**
- * Distances and sizes in world coordinates nearvar, farvar were
- * near and far, but VC in cpp mode chokes on it :( */
- float near; /* near clip distance */
- float far; /* far clip distance */
- float ycor, pixsize, viewfac;
-
-
- /* These three need to be 'handlerized'. Not an easy task... */
-/* RE_RenderDataHandle r; */
+ /* clippping */
+ float clipsta;
+ float clipend;
+
+ /* samples */
+ SampleTables *samples;
+ float jit[32][2];
+
+ /* scene, and its full copy of renderdata and world */
+ Scene *scene;
RenderData r;
World wrld;
+
ListBase parts;
+ /* octree tables and variables for raytrace */
+ Octree oc;
+
+ /* use this instead of R.r.cfra */
+ float cfra;
+
+ /* render database */
int totvlak, totvert, tothalo, totlamp;
-
- /* internal, fortunately */
ListBase lights;
- struct LampRen **la;
- struct VlakRen **blovl;
+
+ int vertnodeslen;
struct VertTableNode *vertnodes;
+ int blohalen;
struct HaloRen **bloha;
+ int blovllen;
+ struct VlakRen **blovl;
+
+ struct GHash *orco_hash;
/* arena for allocating data for use during render, for
- * example dynamic TFaces to go in the VlakRen structure.
- */
+ * example dynamic TFaces to go in the VlakRen structure.
+ */
struct MemArena *memArena;
-
- int *rectaccu;
- int *rectz; /* z buffer: distance buffer */
- float *rectzf; /* z distances, camera space */
- unsigned int *rectf1, *rectf2;
- unsigned int *rectot; /* z buffer: face index buffer, recycled as colour buffer! */
- unsigned int *rectspare; /* */
- /* for 8 byte systems! */
- long *rectdaps;
- float *rectftot; /* original full color buffer */
- short win, winpos, winx, winy, winxof, winyof;
- short winpop, displaymode, sparex, sparey;
-
- /* Not sure what these do... But they're pointers, so good for handlerization */
- struct Image *backbuf, *frontbuf;
- /* backbuf is an image that drawn as background */
+ /* callbacks */
+ void (*display_init)(RenderResult *rr);
+ void (*display_clear)(RenderResult *rr);
+ void (*display_draw)(RenderResult *rr, rcti *rect);
+
+ void (*stats_draw)(RenderStats *ri);
+ void (*timecursor)(int i);
+
+ int (*test_break)(void);
+ int (*test_return)(void);
+ void (*error)(const char *str);
-} RE_Render;
+ RenderStats i;
+};
/* ------------------------------------------------------------------------- */
@@ -188,7 +182,7 @@ typedef struct ShadBuf {
float viewmat[4][4];
float winmat[4][4];
float *jit;
- float d,far,pixsize,soft;
+ float d,clipend,pixsize,soft;
int co[3];
int size,bias;
long *zbuf;
@@ -204,8 +198,8 @@ typedef struct VertRen
float ho[4];
float *orco;
short clip;
- short flag; /* in use for clipping ztra parts, temp setting stuff in convertBlenderscene.c */
- float accum; /* accum for radio weighting, and for strand texco static particles */
+ unsigned short flag; /* in use for clipping zbuffer parts, temp setting stuff in convertblender.c */
+ float accum; /* accum for radio weighting, and for strand texco static particles */
int index; /* index allows extending vertren with any property */
} VertRen;
@@ -230,7 +224,6 @@ typedef struct VlakRen
{
struct VertRen *v1, *v2, *v3, *v4;
unsigned int lay;
- unsigned int raycount;
float n[3];
struct Material *mat;
struct TFace *tface;
@@ -241,8 +234,6 @@ typedef struct VlakRen
Object *ob;
} VlakRen;
-/* vlakren->flag is in DNA_scene_types.h */
-
typedef struct HaloRen
{
short miny, maxy;
diff --git a/source/blender/render/intern/include/rendercore.h b/source/blender/render/intern/include/rendercore.h
index 8f236c502f4..cfdf34c205b 100644
--- a/source/blender/render/intern/include/rendercore.h
+++ b/source/blender/render/intern/include/rendercore.h
@@ -46,6 +46,8 @@
struct HaloRen;
struct ShadeInput;
+/* ------------------------------------------------------------------------- */
+
typedef struct PixStr
{
struct PixStr *next;
@@ -53,14 +55,15 @@ typedef struct PixStr
unsigned short mask, amount;
} PixStr;
-/* ------------------------------------------------------------------------- */
-
typedef struct PixStrMain
{
+ struct PixStrMain *next, *prev;
struct PixStr *ps;
- struct PixStrMain *next;
+ int counter;
} PixStrMain;
+/* ------------------------------------------------------------------------- */
+
void calc_view_vector(float *view, float x, float y);
float mistfactor(float zcor, float *co); /* dist and height, return alpha */
@@ -74,34 +77,30 @@ void shade_lamp_loop(struct ShadeInput *shi, ShadeResult *shr);
float fresnel_fac(float *view, float *vn, float fresnel, float fac);
void calc_R_ref(struct ShadeInput *shi);
-float spec(float inp, int hard);
-/* -------- ray.c ------- */
+/* for nodes */
+void shade_material_loop(struct ShadeInput *shi, struct ShadeResult *shr);
-extern void ray_shadow(ShadeInput *, LampRen *, float *);
-extern void ray_trace(ShadeInput *, ShadeResult *);
-extern void ray_ao(ShadeInput *, World *, float *);
-
-/**
- * Do z buffer and shade
- */
void zbufshade(void);
-
-/**
- * zbuffer and shade, anti aliased
- */
void zbufshadeDA(void); /* Delta Accum Pixel Struct */
-/**
- * Also called in: zbuf.c
- */
-void *shadepixel(float x, float y, int z, int facenr, int mask, float *col, float *rco);
+void *shadepixel(RenderPart *pa, float x, float y, int z, int facenr, int mask, float *col, float *rco);
-/**
- * A cryptic but very efficient way of counting the number of bits that
- * is set in the unsigned short.
- */
int count_mask(unsigned short mask);
+void zbufshade_tile(struct RenderPart *pa);
+void zbufshadeDA_tile(struct RenderPart *pa);
+
+/* -------- ray.c ------- */
+
+extern void freeoctree(Render *re);
+extern void makeoctree(Render *re);
+
+extern void ray_shadow(ShadeInput *, LampRen *, float *);
+extern void ray_trace(ShadeInput *, ShadeResult *);
+extern void ray_ao(ShadeInput *, float *);
+extern void init_jitter_plane(LampRen *lar);
+extern void init_ao_sphere(float *sphere, int tot, int iter);
+
#endif /* RENDER_EXT_H */
diff --git a/source/blender/render/intern/include/renderdatabase.h b/source/blender/render/intern/include/renderdatabase.h
new file mode 100644
index 00000000000..6996bca7a5c
--- /dev/null
+++ b/source/blender/render/intern/include/renderdatabase.h
@@ -0,0 +1,69 @@
+/**
+ * $Id$
+ *
+ * ***** BEGIN GPL 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.
+ *
+ * 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.
+ *
+ * The Original Code is Copyright (C) 2006 Blender Foundation.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+#ifndef RENDERDATABASE_H
+#define RENDERDATABASE_H
+
+struct VlakRen;
+struct VertRen;
+struct HaloRen;
+struct Material;
+struct Render;
+
+/* renderdatabase.c */
+void free_renderdata_tables(struct Render *re);
+void set_normalflags(Render *re);
+void project_renderdata(struct Render *re, void (*projectfunc)(float *, float mat[][4], float *), int do_pano, int part);
+
+/* functions are not exported... so wrong names */
+
+struct VlakRen *RE_findOrAddVlak(struct Render *re, int nr);
+struct VertRen *RE_findOrAddVert(struct Render *re, int nr);
+struct HaloRen *RE_findOrAddHalo(struct Render *re, int nr);
+struct HaloRen *RE_inithalo(struct Render *re, struct Material *ma, float *vec, float *vec1, float *orco, float hasize,
+ float vectsize, int seed);
+
+float *RE_vertren_get_sticky(struct Render *re, struct VertRen *ver, int verify);
+float *RE_vertren_get_stress(struct Render *re, struct VertRen *ver, int verify);
+float *RE_vertren_get_rad(struct Render *re, struct VertRen *ver, int verify);
+float *RE_vertren_get_strand(struct Render *re, struct VertRen *ver, int verify);
+float *RE_vertren_get_tangent(struct Render *re, struct VertRen *ver, int verify);
+
+/* haloren->type: flags */
+#define HA_ONLYSKY 1
+#define HA_VECT 2
+#define HA_XALPHA 4
+#define HA_FLARECIRC 8
+
+
+void init_render_world(Render *re);
+
+
+#endif /* RENDERDATABASE_H */
+
diff --git a/source/blender/render/intern/include/outerRenderLoop.h b/source/blender/render/intern/include/renderpipeline.h
index 1c0faf666ae..5ccb2f318dc 100644
--- a/source/blender/render/intern/include/outerRenderLoop.h
+++ b/source/blender/render/intern/include/renderpipeline.h
@@ -1,17 +1,12 @@
-/*
- * outerRenderLoop.h
- *
+/**
* $Id$
*
- * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
+ * ***** BEGIN GPL 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.
+ * of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
@@ -22,23 +17,25 @@
* along with this program; if not, write to the Free Software Foundation,
* Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
- * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * The Original Code is Copyright (C) 2006 Blender Foundation.
* All rights reserved.
*
* The Original Code is: all of this file.
*
* Contributor(s): none yet.
*
- * ***** END GPL/BL DUAL LICENSE BLOCK *****
+ * ***** END GPL LICENSE BLOCK *****
*/
-#ifndef OUTERRENDERLOOP_H
-#define OUTERRENDERLOOP_H
+#ifndef PIPELINE_H
+#define PIPELINE_H
+
+struct Render;
+
+void *RE_mallocN(int len, char *name);
+void *RE_callocN(int len, char *name);
+void RE_freeN(void *poin);
-/**
- * Outer loop for rendering a single picture.
- */
-void unifiedRenderingLoop(void);
-#endif
+#endif /* PIPELINE_H */
diff --git a/source/blender/render/intern/include/shadbuf.h b/source/blender/render/intern/include/shadbuf.h
index 279d5319b21..16127537975 100644
--- a/source/blender/render/intern/include/shadbuf.h
+++ b/source/blender/render/intern/include/shadbuf.h
@@ -41,7 +41,7 @@
* Calculates shadowbuffers for a vector of shadow-giving lamps
* @param lar The vector of lamps
*/
-void makeshadowbuf(LampRen *lar);
+void makeshadowbuf(struct Render *re, LampRen *lar);
/**
* Determines the shadow factor for a face and lamp. There is some
diff --git a/source/blender/render/intern/include/texture.h b/source/blender/render/intern/include/texture.h
index 4b7ac102d80..9eb4f16a60d 100644
--- a/source/blender/render/intern/include/texture.h
+++ b/source/blender/render/intern/include/texture.h
@@ -56,6 +56,11 @@ struct Image;
void do_halo_tex(struct HaloRen *har, float xn, float yn, float *colf);
void do_sky_tex(float *rco, float *lo, float *dxyview, float *hor, float *zen, float *blend);
+void do_material_tex(struct ShadeInput *shi);
+void do_lamp_tex(LampRen *la, float *lavec, struct ShadeInput *shi, float *colf);
+
+void init_render_textures(void);
+
void render_realtime_texture(struct ShadeInput *shi);
/* imagetexture.h */
diff --git a/source/blender/render/intern/include/vanillaRenderPipe.h b/source/blender/render/intern/include/vanillaRenderPipe.h
deleted file mode 100644
index f242b8522fc..00000000000
--- a/source/blender/render/intern/include/vanillaRenderPipe.h
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * vanillaRenderPipe_ext.h
- *
- * $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.
- *
- * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
- * All rights reserved.
- *
- * The Original Code is: all of this file.
- *
- * Contributor(s): none yet.
- *
- * ***** END GPL/BL DUAL LICENSE BLOCK *****
- */
-
-#ifndef VANILLARENDERPIPE_EXT_H
-#define VANILLARENDERPIPE_EXT_H
-
-#include "vanillaRenderPipe_types.h"
-
-/**
- * Render pipeline with all kinds of extras.
- * status-------------------------\/
- * - integrated z buffering ok
- * - integrated halo rendering ok
- */
-void zBufShadeAdvanced(void);
-
-/**
- * Copy the colour buffer output to R.rectot, to line y.
- */
-void transferColourBufferToOutput(float *buf, int y);
-/**
- * using default transforms for brightness, gamma, hue, saturation etc.
- */
-void std_floatcol_to_charcol(float *buf, char *target);
-
-
-#endif /* VANILLARENDERPIPE_EXT_H */
-
diff --git a/source/blender/render/intern/include/vanillaRenderPipe_types.h b/source/blender/render/intern/include/vanillaRenderPipe_types.h
deleted file mode 100644
index df24ed01f5e..00000000000
--- a/source/blender/render/intern/include/vanillaRenderPipe_types.h
+++ /dev/null
@@ -1,87 +0,0 @@
-/*
- * vanillaRenderPipe_types.h
- *
- * $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.
- *
- * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
- * All rights reserved.
- *
- * The Original Code is: all of this file.
- *
- * Contributor(s): none yet.
- *
- * ***** END GPL/BL DUAL LICENSE BLOCK *****
- */
-
-#ifndef VANILLARENDERPIPE_TYPES_H
-#define VANILLARENDERPIPE_TYPES_H
-
-/* Render defines */
-#define RE_MAX_OSA_COUNT 16 /* The max. number of possible oversamples */
-#define RE_MAX_FACES_PER_PIXEL 1000 /* max. nr of faces rendered behind one */
- /* pixel */
-
-enum RE_SkyAlphaBlendingType {
- RE_ALPHA_NODEF = 0,
- RE_ALPHA_PREMUL,
- RE_ALPHA_KEY,
- RE_ALPHA_SKY,
- RE_ALPHA_MAX
-};
-
-
-/* Render typedefs */
-typedef float RE_COLBUFTYPE; /* datatype for the colour buffer */
-
-
-/**
- * Threshold for add-blending for faces
- */
-#define RE_FACE_ADD_THRESHOLD 0.001
-
-/**
- For oversampling
-
- New stack: the old stack limits our freedom to do all kinds of
- manipulation, so we rewrite it.
-
- A stacked face needs:
- - a face type
- - a colour
- - a conflict count
- - a data pointer (void*)
- - a mask
-
- The stack starts at index 0, with the closest face, and stacks up.
-
-*/
-
-struct RE_faceField {
- int faceType;
- float colour[4];
- int conflictCount;
- void *data;
- int mask;
-};
-
-#endif /* VANILLARENDERPIPE_TYPES_H */
-
diff --git a/source/blender/render/intern/include/zblur.h b/source/blender/render/intern/include/zblur.h
deleted file mode 100644
index a0e1c6a39ce..00000000000
--- a/source/blender/render/intern/include/zblur.h
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * $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
-
diff --git a/source/blender/render/intern/include/zbuf.h b/source/blender/render/intern/include/zbuf.h
index 394e38be47e..7a6c78d5728 100644
--- a/source/blender/render/intern/include/zbuf.h
+++ b/source/blender/render/intern/include/zbuf.h
@@ -1,18 +1,12 @@
/*
- * zbuf_ext.h
- * external interface for zbuf.h
- *
* $Id$
*
- * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
+ * ***** BEGIN GPL 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.
+ * of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
@@ -26,7 +20,7 @@
* The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
* All rights reserved.
*
- * The Original Code is: all of this file.
+ * Full recode: 2004-2006 Blender Foundation
*
* Contributor(s): none yet.
*
@@ -36,158 +30,66 @@
#ifndef ZBUF_H
#define ZBUF_H
-#ifdef __cplusplus
-extern "C" {
-#endif
-
+struct RenderPart;
struct LampRen;
struct VlakRen;
+struct ListBase;
-/*-----------------------------------------------------------*/
-/* Includes */
-/*-----------------------------------------------------------*/
-
-#include "zbuf_types.h"
-#include "render_types.h"
-#include "radio_types.h" /* for RadView */
-
-/*-----------------------------------------------------------*/
-/* Function */
-/* (11 so far ) */
-/*-----------------------------------------------------------*/
-
-/**
- * Fill a 'rectangle' with a fixed value. The rectangle contains x by
- * y points. The rows are assumed to be contiguous in memory, and to
- * consist of uints. This function is used for initializing the z
- * buffer.
- * (why is x int and y uint? called in envmap, render, zbuf)
- * @param rect Pointer to the data representing the rectangle.
- * @param x The width of the rectangle
- * @param y The height of the rectangle
- * @param val The value used to fill the rectangle.
- */
void fillrect(int *rect, int x, int y, int val);
/**
* Converts a world coordinate into a homogenous coordinate in view
- * coordinates. The transformation matrix is only allowed to have a
- * scaling and translation component.
- * Also called in: shadbuf.c render.c radfactors.c
- * initrender.c envmap.c editmesh.c
- * @param v1 [3 floats] the world coordinate
- * @param adr [4 floats] the homogenous view coordinate
- */
-void projectvert(float *v1,float *adr);
-
-
-/**
- * Do a z buffer calculation pass for shadow calculations.
- * Also called in: shadbuf.c
- * Note: Uses globals.
- * @param lar lamp definition data
- */
-void zbuffershad(struct LampRen *lar);
-
- /* to the external interface, temp, I hope... */
-/**
- * Tests whether the first three coordinates should be clipped
- * wrt. the fourth component. Bits 1 and 2 test on x, 3 and 4 test on
- * y, 5 and 6 test on z:
- * xyz > test => set first bit (01),
- * xyz < -test => set second bit (10),
- * xyz == test => reset both bits (00).
- * Note: functionality is duplicated from an internal function
- * Also called in: initrender.c, radfactors.c
- * @param v [4 floats] a coordinate
- * @return a vector of bitfields
- */
-/* int testclip(float *v); */
-
-
-/* The following are only used in zbuf.c and render.c ---------------*/
-/**
- * Fills the entire in the alpha DA buffer. (All of it!)
- * Note: Uses globals.
- * Also called in: render.c
- * @param y the line number to set
- */
-void abufsetrow(float *acolrow, int y);
-
-
-/**
- * Calculate the z buffer for all faces (or edges when in wireframe
- * mode) presently visible.
- * Note: Uses globals.
- * Also called in: render.c
+ * coordinates.
*/
-void zbufferall(void);
-
-
-/**
- * Initialize accumulation buffers for alpha z buffering.
- * The buffers are global variables. Also resets Accu buffer
- * y bounds.
- * <LI>
- * <IT> Acolrow : colour buffer for one line
- * <IT> Arectz : distance buffer for one line, depth ABUFPART
- * <IT> APixbuf : pixel data buffer for one line, depth ABUFPART
- * </LI>
- * Also called in: render.c (should migrate)
- * Note: Uses globals.
- */
-void bgnaccumbuf(void);
-
-/**
- * Discard accumulation buffers for alpha z buffering.
- * The buffers are global variables. The released buffers are Acolrow,
- * Arectz, APixBuf.
- * Also called in: render.c (should migrate)
- * Note: Uses globals.
- */
-void endaccumbuf(void);
-
-/**
- * Z face intersect?
- */
-int vergzvlak(const void *x1, const void *x2);
-
-/**
- * Clip and fill vertex into the z buffer. zbuffunc needs to be set
- * before entering, to assure that there is a buffer fill function
- * that can be called. Zvlnr must be set to the current valid face
- * index .
- * Note: uses globals
- * @param f1 [4 floats] vertex 1
- * @param f2 [4 floats] vertex 2
- * @param f3 [4 floats] vertex 3
- * @param c1 clip conditions?
- * @param c2
- * @param c3
- */
-
-/* span fill in method */
+void projectvert(float *v1, float winmat[][4], float *adr);
+void projectverto(float *v1, float winmat[][4], float *adr);
+int testclip(float *v);
+
+void set_part_zbuf_clipflag(struct RenderPart *pa);
+void zbuffer_shadow(struct Render *re, struct LampRen *lar, int *rectz, int size);
+void zbuffer_solid(struct RenderPart *pa);
+void zbuffer_transp_shade(struct RenderPart *pa, float *pass);
+
+typedef struct APixstr {
+ unsigned short mask[4]; /* jitter mask */
+ int z[4]; /* distance */
+ int p[4]; /* index */
+ struct APixstr *next;
+} APixstr;
+
+typedef struct APixstrMain
+{
+ struct APixstrMain *next, *prev;
+ struct APixstr *ps;
+} APixstrMain;
+
+/* span fill in method, is also used to localize data for zbuffering */
typedef struct ZSpan {
- int yres, miny, maxy; /* range for clipping */
+ int rectx, recty; /* range for clipping */
+
int miny1, maxy1, miny2, maxy2; /* actual filled in range */
float *minp1, *maxp1, *minp2, *maxp2; /* vertex pointers detect min/max range in */
float *span1, *span2;
+
+ float zmulx, zmuly, zofsx, zofsy; /* transform from hoco to zbuf co */
+
+ int *rectz, *arectz; /* zbuffers, arectz is for transparant */
+ int *rectp; /* polygon index buffer */
+ APixstr *apixbuf, *curpstr; /* apixbuf for transparent */
+ struct ListBase *apsmbase;
+
+ int polygon_offset; /* offset in Z */
+ int mask, apsmcounter; /* in use by apixbuf */
+
+ void (*zbuffunc)(struct ZSpan *, int, float *, float *, float *, float *);
+ void (*zbuflinefunc)(struct ZSpan *, int, float *, float *);
+
} ZSpan;
-void zbufclip(struct ZSpan *zspan, int zvlnr, float *f1, float *f2, float *f3, int c1, int c2, int c3);
-
-/* These function pointers are used for z buffer filling. */
-extern void (*zbuffunc)(struct ZSpan *zspan, int, float *, float *, float *);
-extern void (*zbuflinefunc)(int, float *, float *);
-
-/**
- * same, for edges
- */
-void zbufclipwire(int zvlnr, struct VlakRen *vlr);
-
-#ifdef __cplusplus
-}
-#endif
+/* exported for evil edge render... */
+void zbufclip(struct ZSpan *zspan, int zvlnr, float *f1, float *f2, float *f3, int c1, int c2, int c3);
+void zbuf_alloc_span(ZSpan *zspan, int rectx, int recty);
+void zbufclipwire(ZSpan *zspan, int zvlnr, struct VlakRen *vlr);
#endif
diff --git a/source/blender/render/intern/include/zbuf_types.h b/source/blender/render/intern/include/zbuf_types.h
deleted file mode 100644
index b5ad9c75902..00000000000
--- a/source/blender/render/intern/include/zbuf_types.h
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
- * zbuf_types.h
- * type definitions used (and maybe exported) by zbuf.c.
- *
- * $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.
- *
- * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
- * All rights reserved.
- *
- * The Original Code is: all of this file.
- *
- * Contributor(s): none yet.
- *
- * ***** END GPL/BL DUAL LICENSE BLOCK *****
- */
-
-#ifndef ZBUF_TYPES_H
-#define ZBUF_TYPES_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#define ABUFPART 64
-
-/**
- * Primitive data structure for zbuffering. One struct
- * stores data for 4 entries.
- */
-typedef struct APixstr {
- unsigned short mask[4]; /* jitter mask */
- int z[4]; /* distance */
- int p[4]; /* index */
- struct APixstr *next;
-} APixstr;
-
-
-typedef struct APixstrMain
-{
- struct APixstr *ps;
- struct APixstrMain *next;
-} APixstrMain;
-
-
-typedef struct {
- float *vert;
- float hoco[4];
- int clip;
-} VertBucket;
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* ZBUF_TYPES_H */
-
diff --git a/source/blender/render/intern/include/zbufferdatastruct.h b/source/blender/render/intern/include/zbufferdatastruct.h
deleted file mode 100644
index 2cef53dc9f6..00000000000
--- a/source/blender/render/intern/include/zbufferdatastruct.h
+++ /dev/null
@@ -1,98 +0,0 @@
-/*
- * zbufferdatastruct_ext.h
- *
- * $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.
- *
- * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
- * All rights reserved.
- *
- * The Original Code is: all of this file.
- *
- * Contributor(s): none yet.
- *
- * ***** END GPL/BL DUAL LICENSE BLOCK *****
- */
-
-#ifndef ZBUFFERDATASTRUCT_EXT_H
-#define ZBUFFERDATASTRUCT_EXT_H
-
-#include "zbufferdatastruct_types.h"
-
-/**
- * Set memory and counters for a fresh z buffer
- */
-void initZbuffer(int linewidth);
-
-/**
- * Release memory for the current z buffer
- */
-void freeZbuffer(void);
-
-/**
- * Release previous buffer and initialise new buffer.
- */
-void resetZbuffer(void);
-
-/**
- * Make a root for a memory block (internal)
- */
-RE_APixstrExt *addpsemainA(void);
-
-/**
- * Release a memory chunk
- */
-void freepseA(void);
-
-/**
- * Add a structure
- */
-RE_APixstrExt *addpseA(void);
-
-/**
- * Add an object to a zbuffer entry.
- */
-void insertObject(int teller,
- int obindex,
- int obtype,
- int dist,
- int mask);
-
-/**
- * Add a flat object to a zbuffer entry.
- */
-void insertFlatObject(RE_APixstrExt* ap,
- int obindex,
- int obtype,
- int dist,
- int mask);
-
-/**
- * Add a flat object to a zbuffer entry, but don't do OSA entry testing.
- */
-void insertFlatObjectNoOsa(RE_APixstrExt* ap,
- int obindex,
- int obtype,
- int dist,
- int mask);
-
-#endif
-
diff --git a/source/blender/render/intern/include/zbufferdatastruct_types.h b/source/blender/render/intern/include/zbufferdatastruct_types.h
deleted file mode 100644
index 5048adfa8bc..00000000000
--- a/source/blender/render/intern/include/zbufferdatastruct_types.h
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- * zbufferdatastruct_types.h
- *
- * $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.
- *
- * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
- * All rights reserved.
- *
- * The Original Code is: all of this file.
- *
- * Contributor(s): none yet.
- *
- * ***** END GPL/BL DUAL LICENSE BLOCK *****
- */
-
-#ifndef ZBUFFERDATASTRUCT_TYPES_H
-#define ZBUFFERDATASTRUCT_TYPES_H
-
-#define RE_ZBUFLEN 64 /* number of lines in the accumulation buffer */
-
-/**
- * Primitive data structure for zbuffering. One struct
- * stores data for 4 entries. This struct has been extended
- * for the render pipeline overhaul.
- */
-typedef struct RE_APixstrExt {
- unsigned short mask[4]; /* jitter masks */
- int zmin[4]; /* min. distance of all samples */
- int zmax[4]; /* max. distance of all samples */
- int p[4]; /* index */
- int t[4]; /* entry type: ZB_POLY or ZB_HALO */
- struct RE_APixstrExt *next;
-} RE_APixstrExt;
-
-/* For now I'll stick to the Blender convention of hand made defines */
-/* but this should definitely be done in a better way. An enum may */
-/* be some help, but masking is still a nice feature... */
-/* object types to buffer in the z buffer */
-/* RE_SOLID is flag for RE_POLY, as speedup */
-#define RE_NONE 0
-#define RE_POLY 1
-#define RE_HALO 2
-#define RE_SKY 4
-#define RE_SOLID 8
-
-/* unique indices for each field */
-#define RE_ZMIN 0
-#define RE_INDEX 1
-#define RE_MASK 2
-#define RE_TYPE 3
-#define RE_ZMAX 4
-#define RE_PIXELFIELDSIZE 5
-
-typedef struct RE_APixstrExtMain
-{
- struct RE_APixstrExt *ps;
- struct RE_APixstrExtMain *next;
-} RE_APixstrExtMain;
-
-#endif
-
diff --git a/source/blender/render/intern/source/RE_callbacks.c b/source/blender/render/intern/source/RE_callbacks.c
deleted file mode 100644
index acc115b2b87..00000000000
--- a/source/blender/render/intern/source/RE_callbacks.c
+++ /dev/null
@@ -1,168 +0,0 @@
-/**
- * $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.
- *
- * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
- * All rights reserved.
- *
- * The Original Code is: all of this file.
- *
- * Contributor(s): none yet.
- *
- * ***** END GPL/BL DUAL LICENSE BLOCK *****
- * Callbacks to make the renderer interact with calling modules.
- */
-
-#include <stdlib.h> /* for NULL??? */
-#include <stdio.h>
-#include "render.h"
-#include "RE_callbacks.h"
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-/*
- * The callbacks are done in three parts:
- *
- * - a local static pointer to the eventual function. NULL if not
- * defined, or if the behaviour is not required.
- *
- * - a hook that can be called locally
- *
- * - a hook that can be called externally, to set an external function
- * to provide said functionality.
- *
- * These might be generated from a spec such as:
- *
- * callback {
- * local = <local name>
- * external = <external name>
- * type = <ret_type> (<args>,...)
- * }
- *
- * Should generate:
- * - a static var
- * - an internal loop, plus decl.
- * - an external setter, plus decl.
- *
- */
-
-/* Part 1: ------------------------------------------------------------- */
-
-static int (*RE_local_test_break_function)(void) = NULL;
-
-static void (*RE_local_timecursor_function)(int) = NULL;
-
-static void (*RE_local_renderdisplay_function)(int i,
- int j,
- int k,
- int l,
- unsigned int *m)
- = NULL;
-
-static void (*RE_local_initrenderdisplay_function)(void) = NULL;
-static void (*RE_local_clearrenderdisplay_function)(short) = NULL;
-
-static void (*RE_local_printrenderinfo_function)(double,int) = NULL;
-
-static void (*RE_local_getrenderdata_function)(void) = NULL;
-static void (*RE_local_freerenderdata_function)(void) = NULL;
-
-/* Part 2: ------------------------------------------------------------- */
-
-int RE_local_test_break(void) {
- if (RE_local_test_break_function) {
- return RE_local_test_break_function();
- } else {
- /* transparant behaviour: proceed */
- return 0;
- }
-}
-
-void RE_local_timecursor(int i) {
- if (RE_local_timecursor_function) RE_local_timecursor_function(i);
-}
-
-void RE_local_render_display(int i, int j, int k, int l, unsigned int* m) {
- if (RE_local_renderdisplay_function) RE_local_renderdisplay_function(i, j, k, l, m);
- else {
- if(j-i >= l-1) printf("\n");// full picture
- else printf("\rRender %d%% ", (100*i)/l);
- fflush(stdout);
- }
-}
-void RE_local_init_render_display(void) {
- if (RE_local_initrenderdisplay_function) RE_local_initrenderdisplay_function();
-}
-void RE_local_clear_render_display(short i) {
- if (RE_local_clearrenderdisplay_function) RE_local_clearrenderdisplay_function(i);
-}
-
-void RE_local_printrenderinfo(double time, int i) {
- if (RE_local_printrenderinfo_function) RE_local_printrenderinfo_function(time, i);
-}
-
-void RE_local_get_renderdata(void) {
- if (RE_local_getrenderdata_function) RE_local_getrenderdata_function();
-}
-void RE_local_free_renderdata(void) {
- if (RE_local_freerenderdata_function) RE_local_freerenderdata_function();
-}
-
-/* Part 3: ------------------------------------------------------------- */
-
-void RE_set_test_break_callback(int (*f)(void)) {
- RE_local_test_break_function = f;
-}
-
-void RE_set_timecursor_callback(void (*f)(int)) {
- RE_local_timecursor_function = f;
-}
-
-void RE_set_renderdisplay_callback(void (*f)(int i,
- int j,
- int k,
- int l,
- unsigned int *))
-{
- RE_local_renderdisplay_function = f;
-}
-
-void RE_set_initrenderdisplay_callback(void (*f)(void)) {
- RE_local_initrenderdisplay_function = f;
-}
-
-void RE_set_clearrenderdisplay_callback(void (*f)(short)) {
- RE_local_clearrenderdisplay_function = f;
-}
-
-void RE_set_printrenderinfo_callback(void (*f)(double,int)) {
- RE_local_printrenderinfo_function = f;
-}
-
-void RE_set_getrenderdata_callback(void (*f)(void)) {
- RE_local_getrenderdata_function = f;
-}
-
-void RE_set_freerenderdata_callback(void (*f)(void)) {
- RE_local_freerenderdata_function = f;
-}
diff --git a/source/blender/render/intern/source/convertblender.c b/source/blender/render/intern/source/convertblender.c
new file mode 100644
index 00000000000..76f4b11fe7b
--- /dev/null
+++ b/source/blender/render/intern/source/convertblender.c
@@ -0,0 +1,3108 @@
+/**
+ * $Id$
+ *
+ * ***** BEGIN GPL 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.
+ *
+ * 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.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * Contributors: 2004/2005/2006 Blender Foundation, full recode
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+#include <math.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <limits.h>
+
+#include "blendef.h"
+#include "MTC_matrixops.h"
+
+#include "MEM_guardedalloc.h"
+
+#include "BLI_arithb.h"
+#include "BLI_blenlib.h"
+#include "BLI_rand.h"
+#include "BLI_memarena.h"
+#include "BLI_ghash.h"
+
+#include "DNA_armature_types.h"
+#include "DNA_camera_types.h"
+#include "DNA_material_types.h"
+#include "DNA_curve_types.h"
+#include "DNA_effect_types.h"
+#include "DNA_group_types.h"
+#include "DNA_lamp_types.h"
+#include "DNA_lattice_types.h"
+#include "DNA_mesh_types.h"
+#include "DNA_meshdata_types.h"
+#include "DNA_meta_types.h"
+#include "DNA_object_types.h"
+#include "DNA_object_force.h"
+#include "DNA_scene_types.h"
+#include "DNA_texture_types.h"
+#include "DNA_view3d_types.h"
+
+#include "BKE_anim.h"
+#include "BKE_armature.h"
+#include "BKE_action.h"
+#include "BKE_curve.h"
+#include "BKE_constraint.h"
+#include "BKE_displist.h"
+#include "BKE_deform.h"
+#include "BKE_DerivedMesh.h"
+#include "BKE_effect.h"
+#include "BKE_global.h"
+#include "BKE_group.h"
+#include "BKE_key.h"
+#include "BKE_ipo.h"
+#include "BKE_lattice.h"
+#include "BKE_material.h"
+#include "BKE_main.h"
+#include "BKE_mball.h"
+#include "BKE_mesh.h"
+#include "BKE_node.h"
+#include "BKE_object.h"
+#include "BKE_scene.h"
+#include "BKE_subsurf.h"
+#include "BKE_texture.h"
+#include "BKE_utildefines.h"
+#include "BKE_world.h"
+
+#include "envmap.h"
+#include "render_types.h"
+#include "rendercore.h"
+#include "renderdatabase.h"
+#include "renderpipeline.h"
+#include "radio.h"
+#include "shadbuf.h"
+#include "texture.h"
+#include "zbuf.h"
+
+#include "YafRay_Api.h"
+
+/* yafray: Identity transform 'hack' removed, exporter now transforms vertices back to world.
+ * Same is true for lamp coords & vec.
+ * Duplicated data objects & dupliframe/duplivert objects are only stored once,
+ * only the matrix is stored for all others, in yafray these objects are instances of the original.
+ * The main changes are in RE_rotateBlenderScene().
+ */
+
+/* ------------------------------------------------------------------------- */
+/* Local functions */
+/* ------------------------------------------------------------------------- */
+static short test_for_displace(Render *re, Object *ob);
+static void do_displacement(Render *re, Object *ob, int startface, int numface, int startvert, int numvert );
+
+/* ------------------------------------------------------------------------- */
+/* tool functions/defines for ad hoc simplification and possible future
+ cleanup */
+/* ------------------------------------------------------------------------- */
+
+#define UVTOINDEX(u,v) (startvlak + (u) * sizev + (v))
+/*
+
+NOTE THAT U/V COORDINATES ARE SOMETIMES SWAPPED !!
+
+^ ()----p4----p3----()
+| | | | |
+u | | F1 | F2 |
+ | | | |
+ ()----p1----p2----()
+ v ->
+*/
+
+/* ------------------------------------------------------------------------- */
+
+static VertRen *duplicate_vertren(Render *re, VertRen *ver)
+{
+ VertRen *v1= RE_findOrAddVert(re, re->totvert++);
+ int index= v1->index;
+ *v1= *ver;
+ v1->index= index;
+ return v1;
+}
+
+static void split_v_renderfaces(Render *re, int startvlak, int startvert, int usize, int vsize, int uIndex, int cyclu, int cyclv)
+{
+ int vLen = vsize-1+(!!cyclv);
+ int v;
+
+ for (v=0; v<vLen; v++) {
+ VlakRen *vlr = RE_findOrAddVlak(re, startvlak + vLen*uIndex + v);
+ VertRen *vert = duplicate_vertren(re, vlr->v2);
+
+ if (cyclv) {
+ vlr->v2 = vert;
+
+ if (v==vLen-1) {
+ VlakRen *vlr = RE_findOrAddVlak(re, startvlak + vLen*uIndex + 0);
+ vlr->v1 = vert;
+ } else {
+ VlakRen *vlr = RE_findOrAddVlak(re, startvlak + vLen*uIndex + v+1);
+ vlr->v1 = vert;
+ }
+ } else {
+ vlr->v2 = vert;
+
+ if (v<vLen-1) {
+ VlakRen *vlr = RE_findOrAddVlak(re, startvlak + vLen*uIndex + v+1);
+ vlr->v1 = vert;
+ }
+
+ if (v==0) {
+ vlr->v1 = duplicate_vertren(re, vlr->v1);
+ }
+ }
+ }
+}
+
+/* ------------------------------------------------------------------------- */
+
+static int contrpuntnormr(float *n, float *puno)
+{
+ float inp;
+
+ inp=n[0]*puno[0]+n[1]*puno[1]+n[2]*puno[2];
+ if(inp<0.0) return 1;
+ return 0;
+}
+
+/* ------------------------------------------------------------------------- */
+
+static void calc_edge_stress_add(float *accum, VertRen *v1, VertRen *v2)
+{
+ float len= VecLenf(v1->co, v2->co)/VecLenf(v1->orco, v2->orco);
+ float *acc;
+
+ acc= accum + 2*v1->index;
+ acc[0]+= len;
+ acc[1]+= 1.0f;
+
+ acc= accum + 2*v2->index;
+ acc[0]+= len;
+ acc[1]+= 1.0f;
+}
+
+static void calc_edge_stress(Render *re, Mesh *me, int startvert, int startvlak)
+{
+ float loc[3], size[3], *accum, *acc, *accumoffs, *stress;
+ int a;
+
+ if(startvert==re->totvert) return;
+
+ mesh_get_texspace(me, loc, NULL, size);
+
+ accum= MEM_callocN(2*sizeof(float)*(re->totvert-startvert), "temp accum for stress");
+
+ /* de-normalize orco */
+ for(a=startvert; a<re->totvert; a++, acc+=2) {
+ VertRen *ver= RE_findOrAddVert(re, a);
+ if(ver->orco) {
+ ver->orco[0]= ver->orco[0]*size[0] +loc[0];
+ ver->orco[1]= ver->orco[1]*size[1] +loc[1];
+ ver->orco[2]= ver->orco[2]*size[2] +loc[2];
+ }
+ }
+
+ /* add stress values */
+ accumoffs= accum - 2*startvert; /* so we can use vertex index */
+ for(a=startvlak; a<re->totvlak; a++) {
+ VlakRen *vlr= RE_findOrAddVlak(re, a);
+
+ if(vlr->v1->orco && vlr->v4) {
+ calc_edge_stress_add(accumoffs, vlr->v1, vlr->v2);
+ calc_edge_stress_add(accumoffs, vlr->v2, vlr->v3);
+ calc_edge_stress_add(accumoffs, vlr->v3, vlr->v1);
+ if(vlr->v4) {
+ calc_edge_stress_add(accumoffs, vlr->v3, vlr->v4);
+ calc_edge_stress_add(accumoffs, vlr->v4, vlr->v1);
+ calc_edge_stress_add(accumoffs, vlr->v2, vlr->v4);
+ }
+ }
+ }
+
+ for(a=startvert; a<re->totvert; a++) {
+ VertRen *ver= RE_findOrAddVert(re, a);
+ if(ver->orco) {
+ /* find stress value */
+ acc= accumoffs + 2*ver->index;
+ if(acc[1]!=0.0f)
+ acc[0]/= acc[1];
+ stress= RE_vertren_get_stress(re, ver, 1);
+ *stress= *acc;
+
+ /* restore orcos */
+ ver->orco[0] = (ver->orco[0]-loc[0])/size[0];
+ ver->orco[1] = (ver->orco[1]-loc[1])/size[1];
+ ver->orco[2] = (ver->orco[2]-loc[2])/size[2];
+ }
+ }
+
+ MEM_freeN(accum);
+}
+
+static void calc_tangent_vector(Render *re, VlakRen *vlr, float fac1, float fac2, float fac3, float fac4)
+{
+ TFace *tface= vlr->tface;
+
+ if(tface) {
+ VertRen *v1=vlr->v1, *v2=vlr->v2, *v3=vlr->v3, *v4=vlr->v4;
+ float *uv1= tface->uv[0], *uv2= tface->uv[1], *uv3= tface->uv[2], *uv4= tface->uv[3];
+ float tang[3], *tav;
+ float s1, s2, t1, t2, det;
+
+ /* we calculate quads as two triangles, so weight for diagonal gets halved */
+ if(v4) {
+ fac1*= 0.5f;
+ fac3*= 0.5f;
+ }
+
+ /* first tria, we use the V now */
+ s1= uv2[0] - uv1[0];
+ s2= uv3[0] - uv1[0];
+ t1= uv2[1] - uv1[1];
+ t2= uv3[1] - uv1[1];
+ det= 1.0f / (s1 * t2 - s2 * t1);
+
+ /* normals in render are inversed... */
+ tang[0]= (t2 * (v1->co[0]-v2->co[0]) - t1 * (v1->co[0]-v3->co[0]));
+ tang[1]= (t2 * (v1->co[1]-v2->co[1]) - t1 * (v1->co[1]-v3->co[1]));
+ tang[2]= (t2 * (v1->co[2]-v2->co[2]) - t1 * (v1->co[2]-v3->co[2]));
+
+ tav= RE_vertren_get_tangent(re, v1, 1);
+ VECADDFAC(tav, tav, tang, fac1);
+ tav= RE_vertren_get_tangent(re, v2, 1);
+ VECADDFAC(tav, tav, tang, fac2);
+ tav= RE_vertren_get_tangent(re, v3, 1);
+ VECADDFAC(tav, tav, tang, fac3);
+
+ if(v4) {
+ /* 2nd tria, we use the V now */
+ s1= uv3[0] - uv1[0];
+ s2= uv4[0] - uv1[0];
+ t1= uv3[1] - uv1[1];
+ t2= uv4[1] - uv1[1];
+ det= 1.0f / (s1 * t2 - s2 * t1);
+
+ /* normals in render are inversed... */
+ tang[0]= (t2 * (v1->co[0]-v3->co[0]) - t1 * (v1->co[0]-v4->co[0]));
+ tang[1]= (t2 * (v1->co[1]-v3->co[1]) - t1 * (v1->co[1]-v4->co[1]));
+ tang[2]= (t2 * (v1->co[2]-v3->co[2]) - t1 * (v1->co[2]-v4->co[2]));
+
+ Normalise(tang);
+
+ tav= RE_vertren_get_tangent(re, v1, 1);
+ VECADDFAC(tav, tav, tang, fac1);
+ tav= RE_vertren_get_tangent(re, v3, 1);
+ VECADDFAC(tav, tav, tang, fac3);
+ tav= RE_vertren_get_tangent(re, v4, 1);
+ VECADDFAC(tav, tav, tang, fac4);
+ }
+ }
+}
+
+static void calc_vertexnormals(Render *re, int startvert, int startvlak, int do_tangent)
+{
+ int a;
+
+ /* clear all vertex normals */
+ for(a=startvert; a<re->totvert; a++) {
+ VertRen *ver= RE_findOrAddVert(re, a);
+ ver->n[0]=ver->n[1]=ver->n[2]= 0.0;
+ }
+
+ /* calculate cos of angles and point-masses, use as weight factor to
+ add face normal to vertex */
+ for(a=startvlak; a<re->totvlak; a++) {
+ VlakRen *vlr= RE_findOrAddVlak(re, a);
+ if(vlr->flag & ME_SMOOTH) {
+ VertRen *adrve1= vlr->v1;
+ VertRen *adrve2= vlr->v2;
+ VertRen *adrve3= vlr->v3;
+ VertRen *adrve4= vlr->v4;
+ float n1[3], n2[3], n3[3], n4[3];
+ float fac1, fac2, fac3, fac4=0.0f;
+
+ VecSubf(n1, adrve2->co, adrve1->co);
+ Normalise(n1);
+ VecSubf(n2, adrve3->co, adrve2->co);
+ Normalise(n2);
+ if(adrve4==NULL) {
+ VecSubf(n3, adrve1->co, adrve3->co);
+ Normalise(n3);
+
+ fac1= saacos(-n1[0]*n3[0]-n1[1]*n3[1]-n1[2]*n3[2]);
+ fac2= saacos(-n1[0]*n2[0]-n1[1]*n2[1]-n1[2]*n2[2]);
+ fac3= saacos(-n2[0]*n3[0]-n2[1]*n3[1]-n2[2]*n3[2]);
+ }
+ else {
+ VecSubf(n3, adrve4->co, adrve3->co);
+ Normalise(n3);
+ VecSubf(n4, adrve1->co, adrve4->co);
+ Normalise(n4);
+
+ fac1= saacos(-n4[0]*n1[0]-n4[1]*n1[1]-n4[2]*n1[2]);
+ fac2= saacos(-n1[0]*n2[0]-n1[1]*n2[1]-n1[2]*n2[2]);
+ fac3= saacos(-n2[0]*n3[0]-n2[1]*n3[1]-n2[2]*n3[2]);
+ fac4= saacos(-n3[0]*n4[0]-n3[1]*n4[1]-n3[2]*n4[2]);
+
+ if(!(vlr->flag & R_NOPUNOFLIP)) {
+ if( contrpuntnormr(vlr->n, adrve4->n) ) fac4= -fac4;
+ }
+
+ adrve4->n[0] +=fac4*vlr->n[0];
+ adrve4->n[1] +=fac4*vlr->n[1];
+ adrve4->n[2] +=fac4*vlr->n[2];
+ }
+
+ if(!(vlr->flag & R_NOPUNOFLIP)) {
+ if( contrpuntnormr(vlr->n, adrve1->n) ) fac1= -fac1;
+ if( contrpuntnormr(vlr->n, adrve2->n) ) fac2= -fac2;
+ if( contrpuntnormr(vlr->n, adrve3->n) ) fac3= -fac3;
+ }
+
+ adrve1->n[0] +=fac1*vlr->n[0];
+ adrve1->n[1] +=fac1*vlr->n[1];
+ adrve1->n[2] +=fac1*vlr->n[2];
+
+ adrve2->n[0] +=fac2*vlr->n[0];
+ adrve2->n[1] +=fac2*vlr->n[1];
+ adrve2->n[2] +=fac2*vlr->n[2];
+
+ adrve3->n[0] +=fac3*vlr->n[0];
+ adrve3->n[1] +=fac3*vlr->n[1];
+ adrve3->n[2] +=fac3*vlr->n[2];
+
+ if(do_tangent)
+ calc_tangent_vector(re, vlr, fac1, fac2, fac3, fac4);
+ }
+ }
+
+ /* do solid faces */
+ for(a=startvlak; a<re->totvlak; a++) {
+ VlakRen *vlr= RE_findOrAddVlak(re, a);
+ if((vlr->flag & ME_SMOOTH)==0) {
+ float *f1= vlr->v1->n;
+ if(f1[0]==0.0 && f1[1]==0.0 && f1[2]==0.0) VECCOPY(f1, vlr->n);
+ f1= vlr->v2->n;
+ if(f1[0]==0.0 && f1[1]==0.0 && f1[2]==0.0) VECCOPY(f1, vlr->n);
+ f1= vlr->v3->n;
+ if(f1[0]==0.0 && f1[1]==0.0 && f1[2]==0.0) VECCOPY(f1, vlr->n);
+ if(vlr->v4) {
+ f1= vlr->v4->n;
+ if(f1[0]==0.0 && f1[1]==0.0 && f1[2]==0.0) VECCOPY(f1, vlr->n);
+ }
+ }
+ }
+
+ /* normalise vertex normals */
+ for(a=startvert; a<re->totvert; a++) {
+ VertRen *ver= RE_findOrAddVert(re, a);
+ Normalise(ver->n);
+ if(do_tangent) {
+ float *tav= RE_vertren_get_tangent(re, ver, 0);
+ if(tav) Normalise(tav);
+ }
+ }
+
+ /* vertex normal (puno) switch flags for during render */
+ for(a=startvlak; a<re->totvlak; a++) {
+ VlakRen *vlr= RE_findOrAddVlak(re, a);
+
+ if((vlr->flag & R_NOPUNOFLIP)==0) {
+ VertRen *adrve1= vlr->v1;
+ VertRen *adrve2= vlr->v2;
+ VertRen *adrve3= vlr->v3;
+ VertRen *adrve4= vlr->v4;
+ vlr->puno &= ~15;
+ if ((vlr->n[0]*adrve1->n[0]+vlr->n[1]*adrve1->n[1]+vlr->n[2]*adrve1->n[2])<0.0) vlr->puno= 1;
+ if ((vlr->n[0]*adrve2->n[0]+vlr->n[1]*adrve2->n[1]+vlr->n[2]*adrve2->n[2])<0.0) vlr->puno+= 2;
+ if ((vlr->n[0]*adrve3->n[0]+vlr->n[1]*adrve3->n[1]+vlr->n[2]*adrve3->n[2])<0.0) vlr->puno+= 4;
+ if(adrve4) {
+ if((vlr->n[0]*adrve4->n[0]+vlr->n[1]*adrve4->n[1]+vlr->n[2]*adrve4->n[2])<0.0) vlr->puno+= 8;
+ }
+ }
+ }
+}
+
+/* ------------------------------------------------------------------------- */
+/* Autosmoothing: */
+/* ------------------------------------------------------------------------- */
+
+typedef struct ASvert {
+ int totface;
+ ListBase faces;
+} ASvert;
+
+typedef struct ASface {
+ struct ASface *next, *prev;
+ VlakRen *vlr[4];
+ VertRen *nver[4];
+} ASface;
+
+static void as_addvert(ASvert *asv, VertRen *v1, VlakRen *vlr)
+{
+ ASface *asf;
+ int a;
+
+ if(v1 == NULL) return;
+
+ if(asv->faces.first==NULL) {
+ asf= MEM_callocN(sizeof(ASface), "asface");
+ BLI_addtail(&asv->faces, asf);
+ }
+
+ asf= asv->faces.last;
+ for(a=0; a<4; a++) {
+ if(asf->vlr[a]==NULL) {
+ asf->vlr[a]= vlr;
+ asv->totface++;
+ break;
+ }
+ }
+
+ /* new face struct */
+ if(a==4) {
+ asf= MEM_callocN(sizeof(ASface), "asface");
+ BLI_addtail(&asv->faces, asf);
+ asf->vlr[0]= vlr;
+ asv->totface++;
+ }
+}
+
+static int as_testvertex(VlakRen *vlr, VertRen *ver, ASvert *asv, float thresh)
+{
+ /* return 1: vertex needs a copy */
+ ASface *asf;
+ float inp;
+ int a;
+
+ if(vlr==0) return 0;
+
+ asf= asv->faces.first;
+ while(asf) {
+ for(a=0; a<4; a++) {
+ if(asf->vlr[a] && asf->vlr[a]!=vlr) {
+ inp= fabs( vlr->n[0]*asf->vlr[a]->n[0] + vlr->n[1]*asf->vlr[a]->n[1] + vlr->n[2]*asf->vlr[a]->n[2] );
+ if(inp < thresh) return 1;
+ }
+ }
+ asf= asf->next;
+ }
+
+ return 0;
+}
+
+static VertRen *as_findvertex(VlakRen *vlr, VertRen *ver, ASvert *asv, float thresh)
+{
+ /* return when new vertex already was made */
+ ASface *asf;
+ float inp;
+ int a;
+
+ asf= asv->faces.first;
+ while(asf) {
+ for(a=0; a<4; a++) {
+ if(asf->vlr[a] && asf->vlr[a]!=vlr) {
+ /* this face already made a copy for this vertex! */
+ if(asf->nver[a]) {
+ inp= fabs( vlr->n[0]*asf->vlr[a]->n[0] + vlr->n[1]*asf->vlr[a]->n[1] + vlr->n[2]*asf->vlr[a]->n[2] );
+ if(inp >= thresh) {
+ return asf->nver[a];
+ }
+ }
+ }
+ }
+ asf= asf->next;
+ }
+
+ return NULL;
+}
+
+static void autosmooth(Render *re, int startvert, int startvlak, int degr)
+{
+ ASvert *asv, *asverts, *asvertoffs;
+ ASface *asf;
+ VertRen *ver, *v1;
+ VlakRen *vlr;
+ float thresh;
+ int a, b, totvert;
+
+ if(startvert==re->totvert) return;
+ asverts= MEM_callocN(sizeof(ASvert)*(re->totvert-startvert), "all smooth verts");
+ asvertoffs= asverts-startvert; /* se we can use indices */
+
+ thresh= cos( M_PI*((float)degr)/180.0 );
+
+ /* step one: construct listbase of all vertices and pointers to faces */
+ for(a=startvlak; a<re->totvlak; a++) {
+ vlr= RE_findOrAddVlak(re, a);
+
+ as_addvert(asvertoffs+vlr->v1->index, vlr->v1, vlr);
+ as_addvert(asvertoffs+vlr->v2->index, vlr->v2, vlr);
+ as_addvert(asvertoffs+vlr->v3->index, vlr->v3, vlr);
+ if(vlr->v4)
+ as_addvert(asvertoffs+vlr->v4->index, vlr->v4, vlr);
+ }
+
+ /* we now test all vertices, when faces have a normal too much different: they get a new vertex */
+ totvert= re->totvert;
+ for(a=startvert, asv=asverts; a<totvert; a++, asv++) {
+ if(asv && asv->totface>1) {
+ ver= RE_findOrAddVert(re, a);
+
+ asf= asv->faces.first;
+ while(asf) {
+ for(b=0; b<4; b++) {
+
+ /* is there a reason to make a new vertex? */
+ vlr= asf->vlr[b];
+ if( as_testvertex(vlr, ver, asv, thresh) ) {
+
+ /* already made a new vertex within threshold? */
+ v1= as_findvertex(vlr, ver, asv, thresh);
+ if(v1==NULL) {
+ /* make a new vertex */
+ v1= duplicate_vertren(re, ver);
+ }
+ asf->nver[b]= v1;
+ if(vlr->v1==ver) vlr->v1= v1;
+ if(vlr->v2==ver) vlr->v2= v1;
+ if(vlr->v3==ver) vlr->v3= v1;
+ if(vlr->v4==ver) vlr->v4= v1;
+ }
+ }
+ asf= asf->next;
+ }
+ }
+ }
+
+ /* free */
+ for(a=0; a<totvert-startvert; a++) {
+ BLI_freelistN(&asverts[a].faces);
+ }
+ MEM_freeN(asverts);
+}
+
+/* ------------------------------------------------------------------------- */
+/* End of autosmoothing: */
+/* ------------------------------------------------------------------------- */
+
+/* ------------------------------------------------------------------------- */
+/* Orco hash */
+/* ------------------------------------------------------------------------- */
+
+
+static float *get_object_orco(Render *re, Object *ob)
+{
+ float *orco;
+
+ if (!re->orco_hash)
+ re->orco_hash = BLI_ghash_new(BLI_ghashutil_ptrhash, BLI_ghashutil_ptrcmp);
+
+ orco = BLI_ghash_lookup(re->orco_hash, ob);
+
+ if (!orco) {
+ if (ob->type==OB_MESH) {
+ orco = mesh_create_orco_render(ob);
+ } else if (ELEM(ob->type, OB_CURVE, OB_FONT)) {
+ orco = make_orco_curve(ob);
+ } else if (ob->type==OB_SURF) {
+ orco = make_orco_surf(ob);
+ }
+
+ if (orco)
+ BLI_ghash_insert(re->orco_hash, ob, orco);
+ }
+
+ return orco;
+}
+
+static void free_mesh_orco_hash(Render *re)
+{
+ if (re->orco_hash) {
+ BLI_ghash_free(re->orco_hash, NULL, (GHashValFreeFP)MEM_freeN);
+ re->orco_hash = NULL;
+ }
+}
+
+/* ******************** END ORCO HASH ***************** */
+
+
+static void make_render_halos(Render *re, Object *ob, Mesh *me, int totvert, MVert *mvert, Material *ma, float *orco)
+{
+ HaloRen *har;
+ float xn, yn, zn, nor[3], view[3];
+ float vec[3], hasize, mat[4][4], imat[3][3];
+ int a, ok, seed= ma->seed1;
+
+ MTC_Mat4MulMat4(mat, ob->obmat, re->viewmat);
+ MTC_Mat3CpyMat4(imat, ob->imat);
+
+ re->flag |= R_HALO;
+
+ for(a=0; a<totvert; a++, mvert++) {
+ ok= 1;
+
+ if(ok) {
+ hasize= ma->hasize;
+
+ VECCOPY(vec, mvert->co);
+ MTC_Mat4MulVecfl(mat, vec);
+
+ if(ma->mode & MA_HALOPUNO) {
+ xn= mvert->no[0];
+ yn= mvert->no[1];
+ zn= mvert->no[2];
+
+ /* transpose ! */
+ nor[0]= imat[0][0]*xn+imat[0][1]*yn+imat[0][2]*zn;
+ nor[1]= imat[1][0]*xn+imat[1][1]*yn+imat[1][2]*zn;
+ nor[2]= imat[2][0]*xn+imat[2][1]*yn+imat[2][2]*zn;
+ Normalise(nor);
+
+ VECCOPY(view, vec);
+ Normalise(view);
+
+ zn= nor[0]*view[0]+nor[1]*view[1]+nor[2]*view[2];
+ if(zn>=0.0) hasize= 0.0;
+ else hasize*= zn*zn*zn*zn;
+ }
+
+ if(orco) har= RE_inithalo(re, ma, vec, NULL, orco, hasize, 0.0, seed);
+ else har= RE_inithalo(re, ma, vec, NULL, mvert->co, hasize, 0.0, seed);
+ if(har) har->lay= ob->lay;
+ }
+ if(orco) orco+= 3;
+ seed++;
+ }
+}
+
+/* ------------------------------------------------------------------------- */
+static Material *give_render_material(Render *re, Object *ob, int nr)
+{
+ extern Material defmaterial; /* material.c */
+ Material *ma;
+
+ ma= give_current_material(ob, nr);
+ if(ma==NULL)
+ ma= &defmaterial;
+ else
+ if(ma->mode & MA_ZTRA)
+ re->flag |= R_ZTRA;
+
+ return ma;
+}
+
+
+
+static void render_particle_system(Render *re, Object *ob, PartEff *paf)
+{
+ Particle *pa=0;
+ HaloRen *har=0;
+ Material *ma=0;
+ float xn, yn, zn, imat[3][3], tmat[4][4], mat[4][4], hasize, stime, ptime, ctime, vec[3], vec1[3], view[3], nor[3];
+ int a, mat_nr=1, seed;
+
+ pa= paf->keys;
+ if(pa==NULL || paf->disp!=100) {
+ build_particle_system(ob);
+ pa= paf->keys;
+ if(pa==NULL) return;
+ }
+
+ ma= give_render_material(re, ob, paf->omat);
+
+ MTC_Mat4MulMat4(mat, ob->obmat, re->viewmat);
+ MTC_Mat4Invert(ob->imat, mat); /* this is correct, for imat texture */
+
+ /* enable duplicators to work */
+ Mat4MulMat4(tmat, paf->imat, ob->obmat);
+ MTC_Mat4MulMat4(mat, tmat, re->viewmat);
+
+ MTC_Mat4Invert(tmat, mat);
+ MTC_Mat3CpyMat4(imat, tmat);
+
+ re->flag |= R_HALO;
+
+ if(ob->ipoflag & OB_OFFS_PARTICLE) ptime= ob->sf;
+ else ptime= 0.0;
+ ctime= bsystem_time(ob, 0, (float)re->scene->r.cfra, ptime);
+ seed= ma->seed1;
+
+ for(a=0; a<paf->totpart; a++, pa+=paf->totkey, seed++) {
+
+ /* offset time for calculating normal */
+ stime= ctime;
+ ptime= ctime+1.0f;
+ if(ctime < pa->time) {
+ if(paf->flag & PAF_UNBORN)
+ ptime= pa->time+1.0f;
+ else
+ continue;
+ }
+ if(ctime > pa->time+pa->lifetime) {
+ if(paf->flag & PAF_DIED)
+ stime= pa->time+pa->lifetime-1.0f;
+ else
+ continue;
+ }
+
+ /* watch it: also calculate the normal of a particle */
+ if(paf->stype==PAF_VECT || ma->mode & MA_HALO_SHADE) {
+ where_is_particle(paf, pa, stime, vec);
+ MTC_Mat4MulVecfl(mat, vec);
+ where_is_particle(paf, pa, ptime, vec1);
+ MTC_Mat4MulVecfl(mat, vec1);
+ }
+ else {
+ where_is_particle(paf, pa, ctime, vec);
+ MTC_Mat4MulVecfl(mat, vec);
+ }
+
+ if(pa->mat_nr != mat_nr) {
+ mat_nr= pa->mat_nr;
+ ma= give_render_material(re, ob, mat_nr);
+ }
+
+ if(ma->ipo) {
+ /* correction for lifetime */
+ ptime= 100.0*(ctime-pa->time)/pa->lifetime;
+ calc_ipo(ma->ipo, ptime);
+ execute_ipo((ID *)ma, ma->ipo);
+ }
+
+ hasize= ma->hasize;
+
+ if(ma->mode & MA_HALOPUNO) {
+ xn= pa->no[0];
+ yn= pa->no[1];
+ zn= pa->no[2];
+
+ /* transpose ! */
+ nor[0]= imat[0][0]*xn+imat[0][1]*yn+imat[0][2]*zn;
+ nor[1]= imat[1][0]*xn+imat[1][1]*yn+imat[1][2]*zn;
+ nor[2]= imat[2][0]*xn+imat[2][1]*yn+imat[2][2]*zn;
+ Normalise(nor);
+
+ VECCOPY(view, vec);
+ Normalise(view);
+
+ zn= nor[0]*view[0]+nor[1]*view[1]+nor[2]*view[2];
+ if(zn>=0.0) hasize= 0.0;
+ else hasize*= zn*zn*zn*zn;
+ }
+
+ if(paf->stype==PAF_VECT) har= RE_inithalo(re, ma, vec, vec1, pa->co, hasize, paf->vectsize, seed);
+ else {
+ har= RE_inithalo(re, ma, vec, NULL, pa->co, hasize, 0.0, seed);
+ if(har && ma->mode & MA_HALO_SHADE) {
+ VecSubf(har->no, vec, vec1);
+ Normalise(har->no);
+ }
+ }
+ if(har) har->lay= ob->lay;
+ }
+
+ /* restore material */
+ for(a=1; a<=ob->totcol; a++) {
+ ma= give_render_material(re, ob, a);
+ if(ma) do_mat_ipo(ma);
+ }
+
+ if(paf->disp!=100) {
+ MEM_freeN(paf->keys);
+ paf->keys= NULL;
+ }
+}
+
+
+/* ------------------------------------------------------------------------- */
+
+/* future thread problem... */
+static void static_particle_strand(Render *re, Object *ob, Material *ma, float *orco, float *vec, float *vec1, float ctime, int first)
+{
+ static VertRen *v1= NULL, *v2= NULL;
+ VlakRen *vlr;
+ float nor[3], cross[3], w, dx, dy;
+ int flag;
+
+ VecSubf(nor, vec, vec1);
+ Normalise(nor); // nor needed as tangent
+ Crossf(cross, vec, nor);
+
+ /* turn cross in pixelsize */
+ w= vec[2]*re->winmat[2][3] + re->winmat[3][3];
+ dx= re->winx*cross[0]*re->winmat[0][0]/w;
+ dy= re->winy*cross[1]*re->winmat[1][1]/w;
+ w= sqrt(dx*dx + dy*dy);
+ if(w!=0.0f) {
+ float fac;
+ if(ma->strand_ease!=0.0f) {
+ if(ma->strand_ease<0.0f)
+ fac= pow(ctime, 1.0+ma->strand_ease);
+ else
+ fac= pow(ctime, 1.0/(1.0f-ma->strand_ease));
+ }
+ else fac= ctime;
+
+ VecMulf(cross, ((1.0f-fac)*ma->strand_sta + (fac)*ma->strand_end)/w);
+ }
+
+ if(ma->mode & MA_TANGENT_STR)
+ flag= R_SMOOTH|R_NOPUNOFLIP|R_STRAND|R_TANGENT;
+ else
+ flag= R_SMOOTH|R_STRAND;
+
+ /* first two vertices */
+ if(first) {
+ v1= RE_findOrAddVert(re, re->totvert++);
+ v2= RE_findOrAddVert(re, re->totvert++);
+
+ VECCOPY(v1->co, vec);
+ VecAddf(v1->co, v1->co, cross);
+ VECCOPY(v1->n, nor);
+ v1->orco= orco;
+ v1->accum= -1.0f; // accum abuse for strand texco
+
+ VECCOPY(v2->co, vec);
+ VecSubf(v2->co, v2->co, cross);
+ VECCOPY(v2->n, nor);
+ v2->orco= orco;
+ v2->accum= v1->accum;
+ }
+ else {
+
+ vlr= RE_findOrAddVlak(re, re->totvlak++);
+ vlr->flag= flag;
+ vlr->ob= ob;
+ vlr->v1= v1;
+ vlr->v2= v2;
+ vlr->v3= RE_findOrAddVert(re, re->totvert++);
+ vlr->v4= RE_findOrAddVert(re, re->totvert++);
+
+ v1= vlr->v4; // cycle
+ v2= vlr->v3; // cycle
+
+ VECCOPY(vlr->v4->co, vec);
+ VecAddf(vlr->v4->co, vlr->v4->co, cross);
+ VECCOPY(vlr->v4->n, nor);
+ vlr->v4->orco= orco;
+ vlr->v4->accum= -1.0f + 2.0f*ctime; // accum abuse for strand texco
+
+ VECCOPY(vlr->v3->co, vec);
+ VecSubf(vlr->v3->co, vlr->v3->co, cross);
+ VECCOPY(vlr->v3->n, nor);
+ vlr->v3->orco= orco;
+ vlr->v3->accum= vlr->v4->accum;
+
+ CalcNormFloat4(vlr->v4->co, vlr->v3->co, vlr->v2->co, vlr->v1->co, vlr->n);
+
+ vlr->mat= ma;
+ vlr->ec= ME_V2V3;
+ vlr->lay= ob->lay;
+ }
+}
+
+static void render_static_particle_system(Render *re, Object *ob, PartEff *paf)
+{
+ Particle *pa=0;
+ HaloRen *har=0;
+ Material *ma=0;
+ VertRen *v1= NULL;
+ VlakRen *vlr;
+ float xn, yn, zn, imat[3][3], mat[4][4], hasize;
+ float mtime, ptime, ctime, vec[3], vec1[3], view[3], nor[3];
+ float *orco= NULL, loc_tex[3], size_tex[3];
+ int a, mat_nr=1, seed, totvlako, totverto, first;
+
+ pa= paf->keys;
+ if(pa==NULL || (paf->flag & PAF_ANIMATED) || paf->disp!=100) {
+ build_particle_system(ob);
+ pa= paf->keys;
+ if(pa==NULL) return;
+ }
+
+ totvlako= re->totvlak;
+ totverto= re->totvert;
+
+ ma= give_render_material(re, ob, paf->omat);
+ if(ma->mode & MA_HALO)
+ re->flag |= R_HALO;
+
+ MTC_Mat4MulMat4(mat, ob->obmat, re->viewmat);
+ MTC_Mat4Invert(ob->imat, mat); /* need to be that way, for imat texture */
+
+ MTC_Mat3CpyMat4(imat, ob->imat);
+
+ /* orcos */
+ if(!(ma->mode & (MA_HALO|MA_WIRE))) {
+ orco= MEM_mallocN(3*sizeof(float)*paf->totpart, "static particle orcos");
+ if (!re->orco_hash)
+ re->orco_hash = BLI_ghash_new(BLI_ghashutil_ptrhash, BLI_ghashutil_ptrcmp);
+ BLI_ghash_insert(re->orco_hash, paf, orco); /* pointer is particles, otherwise object uses it */
+ }
+
+ mesh_get_texspace(ob->data, loc_tex, NULL, size_tex);
+
+ if(ob->ipoflag & OB_OFFS_PARTICLE) ptime= ob->sf;
+ else ptime= 0.0;
+ ctime= bsystem_time(ob, 0, (float)re->scene->r.cfra, ptime);
+ seed= ma->seed1;
+
+ for(a=0; a<paf->totpart; a++, pa+=paf->totkey) {
+
+ where_is_particle(paf, pa, pa->time, vec1);
+ if(orco) {
+ orco[0] = (vec1[0]-loc_tex[0])/size_tex[0];
+ orco[1] = (vec1[1]-loc_tex[1])/size_tex[1];
+ orco[2] = (vec1[2]-loc_tex[2])/size_tex[2];
+ }
+ MTC_Mat4MulVecfl(mat, vec1);
+ mtime= pa->time+pa->lifetime+paf->staticstep-1;
+
+ first= 1;
+ for(ctime= pa->time; ctime<mtime; ctime+=paf->staticstep) {
+
+ /* make sure hair grows until the end.. */
+ if(ctime>pa->time+pa->lifetime) ctime= pa->time+pa->lifetime;
+
+ /* watch it: also calc the normal of a particle */
+ if(paf->stype==PAF_VECT || ma->mode & MA_HALO_SHADE) {
+ where_is_particle(paf, pa, ctime+1.0, vec);
+ MTC_Mat4MulVecfl(mat, vec);
+ }
+ else {
+ where_is_particle(paf, pa, ctime, vec);
+ MTC_Mat4MulVecfl(mat, vec);
+ }
+
+ if(pa->mat_nr != mat_nr) {
+ mat_nr= pa->mat_nr;
+ ma= give_render_material(re, ob, mat_nr);
+ }
+
+ /* wires */
+ if(ma->mode & MA_WIRE) {
+ if(ctime == pa->time) {
+ v1= RE_findOrAddVert(re, re->totvert++);
+ VECCOPY(v1->co, vec);
+ }
+ else {
+ vlr= RE_findOrAddVlak(re, re->totvlak++);
+ vlr->ob= ob;
+ vlr->v1= v1;
+ vlr->v2= RE_findOrAddVert(re, re->totvert++);
+ vlr->v3= vlr->v2;
+ vlr->v4= NULL;
+
+ v1= vlr->v2; // cycle
+ VECCOPY(v1->co, vec);
+
+ VecSubf(vlr->n, vec, vec1);
+ Normalise(vlr->n);
+ VECCOPY(v1->n, vlr->n);
+
+ vlr->mat= ma;
+ vlr->ec= ME_V1V2;
+ vlr->lay= ob->lay;
+ }
+ }
+ else {
+ if(ma->ipo) {
+ /* correction for lifetime */
+ ptime= 100.0*(ctime-pa->time)/pa->lifetime;
+ calc_ipo(ma->ipo, ptime);
+ execute_ipo((ID *)ma, ma->ipo);
+ }
+
+ if(ma->mode & MA_HALO) {
+ hasize= ma->hasize;
+
+ if(ma->mode & MA_HALOPUNO) {
+ xn= pa->no[0];
+ yn= pa->no[1];
+ zn= pa->no[2];
+
+ /* transpose ! */
+ nor[0]= imat[0][0]*xn+imat[0][1]*yn+imat[0][2]*zn;
+ nor[1]= imat[1][0]*xn+imat[1][1]*yn+imat[1][2]*zn;
+ nor[2]= imat[2][0]*xn+imat[2][1]*yn+imat[2][2]*zn;
+ Normalise(nor);
+
+ VECCOPY(view, vec);
+ Normalise(view);
+
+ zn= nor[0]*view[0]+nor[1]*view[1]+nor[2]*view[2];
+ if(zn>=0.0) hasize= 0.0;
+ else hasize*= zn*zn*zn*zn;
+ }
+
+ if(paf->stype==PAF_VECT) har= RE_inithalo(re, ma, vec, vec1, pa->co, hasize, paf->vectsize, seed);
+ else {
+ har= RE_inithalo(re, ma, vec, NULL, pa->co, hasize, 0.0, seed);
+ if(har && (ma->mode & MA_HALO_SHADE)) {
+ VecSubf(har->no, vec, vec1);
+ Normalise(har->no);
+ har->lay= ob->lay;
+ }
+ }
+ if(har) har->lay= ob->lay;
+ }
+ else { /* generate pixel sized hair strand */
+ static_particle_strand(re, ob, ma, orco, vec, vec1, (ctime-pa->time)/(mtime-pa->time), first);
+ }
+ }
+
+ VECCOPY(vec1, vec);
+ first= 0;
+ }
+
+ seed++;
+ if(orco) orco+=3;
+ }
+
+ if(paf->disp!=100) {
+ MEM_freeN(paf->keys);
+ paf->keys= NULL;
+ }
+
+ if((ma->mode & MA_TANGENT_STR)==0)
+ calc_vertexnormals(re, totverto, totvlako, 0);
+}
+
+
+/* ------------------------------------------------------------------------- */
+
+static int verghalo(const void *a1, const void *a2)
+{
+ const struct halosort *x1=a1, *x2=a2;
+
+ if( x1->z < x2->z ) return 1;
+ else if( x1->z > x2->z) return -1;
+ return 0;
+}
+
+/* ------------------------------------------------------------------------- */
+static void sort_halos(Render *re)
+{
+ struct halosort *hablock, *haso;
+ HaloRen *har = NULL, **bloha;
+ int a;
+
+ if(re->tothalo==0) return;
+
+ /* make datablock with halo pointers, sort */
+ haso= hablock= MEM_mallocN(sizeof(struct halosort)*re->tothalo, "hablock");
+
+ for(a=0; a<re->tothalo; a++) {
+ if((a & 255)==0) har= re->bloha[a>>8];
+ else har++;
+ haso->har= har;
+ haso->z= har->zs;
+ haso++;
+ }
+
+ qsort(hablock, re->tothalo, sizeof(struct halosort), verghalo);
+
+ /* re-assamble re->bloha */
+
+ bloha= re->bloha;
+ re->bloha= (HaloRen **)MEM_callocN(sizeof(void *)*(re->blohalen),"Bloha");
+
+ haso= hablock;
+ for(a=0; a<re->tothalo; a++) {
+ har= RE_findOrAddHalo(re, a);
+ *har= *(haso->har);
+
+ haso++;
+ }
+
+ /* free */
+ a= 0;
+ while(bloha[a]) {
+ MEM_freeN(bloha[a]);
+ a++;
+ }
+ MEM_freeN(bloha);
+ MEM_freeN(hablock);
+
+}
+
+/* ------------------------------------------------------------------------- */
+static void init_render_mball(Render *re, Object *ob)
+{
+ DispList *dl, *dlo;
+ VertRen *ver;
+ VlakRen *vlr, *vlr1;
+ Material *ma;
+ float *data, *nors, mat[4][4], imat[3][3], xn, yn, zn;
+ int a, need_orco, startvert, *index;
+
+ if (ob!=find_basis_mball(ob))
+ return;
+
+ MTC_Mat4MulMat4(mat, ob->obmat, re->viewmat);
+ MTC_Mat4Invert(ob->imat, mat);
+ MTC_Mat3CpyMat4(imat, ob->imat);
+
+ ma= give_render_material(re, ob, 1);
+
+ need_orco= 0;
+ if(ma->texco & TEXCO_ORCO) {
+ need_orco= 1;
+ }
+
+ dlo= ob->disp.first;
+ if(dlo) BLI_remlink(&ob->disp, dlo);
+
+ makeDispListMBall(ob);
+ dl= ob->disp.first;
+ if(dl==0) return;
+
+ startvert= re->totvert;
+ data= dl->verts;
+ nors= dl->nors;
+
+ for(a=0; a<dl->nr; a++, data+=3, nors+=3) {
+
+ ver= RE_findOrAddVert(re, re->totvert++);
+ VECCOPY(ver->co, data);
+ MTC_Mat4MulVecfl(mat, ver->co);
+
+ xn= nors[0];
+ yn= nors[1];
+ zn= nors[2];
+
+ /* transpose ! */
+ ver->n[0]= imat[0][0]*xn+imat[0][1]*yn+imat[0][2]*zn;
+ ver->n[1]= imat[1][0]*xn+imat[1][1]*yn+imat[1][2]*zn;
+ ver->n[2]= imat[2][0]*xn+imat[2][1]*yn+imat[2][2]*zn;
+ Normalise(ver->n);
+ //if(ob->transflag & OB_NEG_SCALE) VecMulf(ver->n. -1.0);
+
+ if(need_orco) ver->orco= data;
+ }
+
+ index= dl->index;
+ for(a=0; a<dl->parts; a++, index+=4) {
+
+ vlr= RE_findOrAddVlak(re, re->totvlak++);
+ vlr->ob= ob;
+ vlr->v1= RE_findOrAddVert(re, startvert+index[0]);
+ vlr->v2= RE_findOrAddVert(re, startvert+index[1]);
+ vlr->v3= RE_findOrAddVert(re, startvert+index[2]);
+ vlr->v4= 0;
+
+ if(ob->transflag & OB_NEG_SCALE)
+ CalcNormFloat(vlr->v1->co, vlr->v2->co, vlr->v3->co, vlr->n);
+ else
+ CalcNormFloat(vlr->v3->co, vlr->v2->co, vlr->v1->co, vlr->n);
+
+ vlr->mat= ma;
+ vlr->flag= ME_SMOOTH+R_NOPUNOFLIP;
+ vlr->ec= 0;
+ vlr->lay= ob->lay;
+
+ /* mball -too bad- always has triangles, because quads can be non-planar */
+ if(index[3]) {
+ vlr1= RE_findOrAddVlak(re, re->totvlak++);
+ *vlr1= *vlr;
+ vlr1->v2= vlr1->v3;
+ vlr1->v3= RE_findOrAddVert(re, startvert+index[3]);
+ if(ob->transflag & OB_NEG_SCALE)
+ CalcNormFloat(vlr1->v1->co, vlr1->v2->co, vlr1->v3->co, vlr1->n);
+ else
+ CalcNormFloat(vlr1->v3->co, vlr1->v2->co, vlr1->v1->co, vlr1->n);
+ }
+ }
+
+ if(need_orco) {
+ /* store displist and scale */
+ make_orco_mball(ob);
+ if(dlo) BLI_addhead(&ob->disp, dlo);
+
+ }
+ else {
+ freedisplist(&ob->disp);
+ if(dlo) BLI_addtail(&ob->disp, dlo);
+ }
+}
+/* ------------------------------------------------------------------------- */
+/* convert */
+
+struct edgesort {
+ int v1, v2;
+ int has_mcol;
+ TFace *tface;
+ float uv1[2], uv2[2];
+ unsigned int mcol1, mcol2;
+};
+
+/* edges have to be added with lowest index first for sorting */
+static void to_edgesort(struct edgesort *ed, int i1, int i2, int v1, int v2, unsigned int *mcol, TFace *tface)
+{
+ if(v1<v2) {
+ ed->v1= v1; ed->v2= v2;
+ }
+ else {
+ ed->v1= v2; ed->v2= v1;
+ SWAP(int, i1, i2);
+ }
+ /* copy color and tface, edges use different ordering */
+ ed->tface= tface;
+ if(tface) {
+ ed->uv1[0]= tface->uv[i1][0];
+ ed->uv1[1]= tface->uv[i1][1];
+ ed->uv2[0]= tface->uv[i2][0];
+ ed->uv2[1]= tface->uv[i2][1];
+
+ ed->mcol1= tface->col[i1];
+ ed->mcol2= tface->col[i2];
+ }
+ ed->has_mcol= mcol!=NULL;
+ if(mcol) {
+ ed->mcol1= mcol[i1];
+ ed->mcol2= mcol[i2];
+ }
+}
+
+static int vergedgesort(const void *v1, const void *v2)
+{
+ const struct edgesort *x1=v1, *x2=v2;
+
+ if( x1->v1 > x2->v1) return 1;
+ else if( x1->v1 < x2->v1) return -1;
+ else if( x1->v2 > x2->v2) return 1;
+ else if( x1->v2 < x2->v2) return -1;
+
+ return 0;
+}
+
+static struct edgesort *make_mesh_edge_lookup(Mesh *me, DispListMesh *dlm, int *totedgesort)
+{
+ MFace *mf, *mface;
+ TFace *tface=NULL;
+ struct edgesort *edsort, *ed;
+ unsigned int *mcol=NULL;
+ int a, totedge=0, totface;
+
+ if (dlm) {
+ mface= dlm->mface;
+ totface= dlm->totface;
+ if (dlm->tface)
+ tface= dlm->tface;
+ else if (dlm->mcol)
+ mcol= (unsigned int *)dlm->mcol;
+ } else {
+ mface= me->mface;
+ totface= me->totface;
+ if (me->tface)
+ tface= me->tface;
+ else if (me->mcol)
+ mcol= (unsigned int *)me->mcol;
+ }
+
+ if(mcol==NULL && tface==NULL) return NULL;
+
+ /* make sorted table with edges and and tface/mcol pointers in it */
+ for(a= totface, mf= mface; a>0; a--, mf++) {
+ if(mf->v4) totedge+=4;
+ else if(mf->v3) totedge+=3;
+ }
+ if(totedge==0) return NULL;
+
+ ed= edsort= MEM_mallocN(totedge*sizeof(struct edgesort), "edgesort");
+
+ for(a= me->totface, mf= mface; a>0; a--, mf++) {
+ if(mface->v4 || mface->v3) {
+ to_edgesort(ed++, 0, 1, mf->v1, mf->v2, mcol, tface);
+ to_edgesort(ed++, 1, 2, mf->v2, mf->v3, mcol, tface);
+ if(mf->v4) {
+ to_edgesort(ed++, 2, 3, mf->v3, mf->v4, mcol, tface);
+ to_edgesort(ed++, 3, 0, mf->v4, mf->v1, mcol, tface);
+ }
+ else if(mf->v3) {
+ to_edgesort(ed++, 2, 3, mf->v3, mf->v1, mcol, tface);
+ }
+ }
+ if(mcol) mcol+=4;
+ if(tface) tface++;
+ }
+
+ qsort(edsort, totedge, sizeof(struct edgesort), vergedgesort);
+
+ *totedgesort= totedge;
+ return edsort;
+}
+
+static void use_mesh_edge_lookup(Render *re, Mesh *me, DispListMesh *dlm, MEdge *medge, VlakRen *vlr, struct edgesort *edgetable, int totedge)
+{
+ struct edgesort ed, *edp;
+
+ if(medge->v1 < medge->v2) {
+ ed.v1= medge->v1; ed.v2= medge->v2;
+ }
+ else {
+ ed.v1= medge->v2; ed.v2= medge->v1;
+ }
+
+ edp= bsearch(&ed, edgetable, totedge, sizeof(struct edgesort), vergedgesort);
+ if(edp) {
+ /* since edges have different index ordering, we have to duplicate mcol and tface */
+ if(edp->tface) {
+ vlr->tface= BLI_memarena_alloc(re->memArena, sizeof(TFace));
+ vlr->vcol= vlr->tface->col;
+ memcpy(vlr->tface, edp->tface, sizeof(TFace));
+
+ if(edp->v1==medge->v1) {
+ vlr->vcol[0]= edp->mcol1;
+ vlr->vcol[1]= edp->mcol2;
+ }
+ else {
+ vlr->vcol[0]= edp->mcol2;
+ vlr->vcol[1]= edp->mcol1;
+ }
+ vlr->vcol[2]= vlr->vcol[1];
+ vlr->vcol[3]= vlr->vcol[1];
+
+ if(edp->v1==medge->v1) {
+ memcpy(vlr->tface->uv[0], edp->uv1, 2*sizeof(float));
+ memcpy(vlr->tface->uv[1], edp->uv2, 2*sizeof(float));
+ }
+ else {
+ memcpy(vlr->tface->uv[0], edp->uv2, 2*sizeof(float));
+ memcpy(vlr->tface->uv[1], edp->uv1, 2*sizeof(float));
+ }
+ memcpy(vlr->tface->uv[2], vlr->tface->uv[1], 2*sizeof(float));
+ memcpy(vlr->tface->uv[3], vlr->tface->uv[1], 2*sizeof(float));
+ }
+ else if(edp->has_mcol) {
+ vlr->vcol= BLI_memarena_alloc(re->memArena, sizeof(MCol)*4);
+ vlr->vcol[0]= edp->mcol1;
+ vlr->vcol[1]= edp->mcol2;
+ vlr->vcol[2]= vlr->vcol[1];
+ vlr->vcol[3]= vlr->vcol[1];
+ }
+ }
+}
+
+static void init_render_mesh(Render *re, Object *ob)
+{
+ Mesh *me;
+ MVert *mvert = NULL;
+ MFace *mface;
+ VlakRen *vlr; //, *vlr1;
+ VertRen *ver;
+ Material *ma;
+ MSticky *ms = NULL;
+ PartEff *paf;
+ DispListMesh *dlm = NULL;
+ DerivedMesh *dm;
+ unsigned int *vertcol;
+ float xn, yn, zn, imat[3][3], mat[4][4]; //nor[3],
+ float *orco=0;
+ int a, a1, ok, need_orco=0, need_stress=0, need_tangent=0, totvlako, totverto, vertofs;
+ int end, do_autosmooth=0, totvert = 0, dm_needsfree;
+
+ me= ob->data;
+
+ paf = give_parteff(ob);
+ if(paf) {
+ /* warning; build_particle_system does modifier calls itself */
+ if(paf->flag & PAF_STATIC) render_static_particle_system(re, ob, paf);
+ else render_particle_system(re, ob, paf);
+ if((paf->flag & PAF_SHOWE)==0) return;
+ }
+
+ MTC_Mat4MulMat4(mat, ob->obmat, re->viewmat);
+ MTC_Mat4Invert(ob->imat, mat);
+ MTC_Mat3CpyMat4(imat, ob->imat);
+
+ if(me->totvert==0) {
+ return;
+ }
+
+ totvlako= re->totvlak;
+ totverto= re->totvert;
+
+ need_orco= 0;
+ for(a=1; a<=ob->totcol; a++) {
+ ma= give_render_material(re, ob, a);
+ if(ma) {
+ if(ma->texco & (TEXCO_ORCO|TEXCO_STRESS))
+ need_orco= 1;
+ if(ma->texco & TEXCO_STRESS)
+ need_stress= 1;
+ if(ma->mode & MA_TANGENT_V)
+ need_tangent= 1;
+ }
+ }
+
+ if(need_orco) orco = get_object_orco(re, ob);
+
+ dm = mesh_create_derived_render(ob);
+ dm_needsfree= 1;
+
+ if(dm==NULL) return; /* in case duplicated object fails? */
+
+ dlm = dm->convertToDispListMesh(dm, 1);
+
+ mvert= dlm->mvert;
+ totvert= dlm->totvert;
+
+ ms = (totvert==me->totvert)?me->msticky:NULL;
+
+ ma= give_render_material(re, ob, 1);
+
+ if(ma->mode & MA_HALO) {
+ make_render_halos(re, ob, me, totvert, mvert, ma, orco);
+ }
+ else {
+
+ for(a=0; a<totvert; a++, mvert++) {
+ ver= RE_findOrAddVert(re, re->totvert++);
+ VECCOPY(ver->co, mvert->co);
+ MTC_Mat4MulVecfl(mat, ver->co);
+
+ if(orco) {
+ ver->orco= orco;
+ orco+=3;
+ }
+ if(ms) {
+ float *sticky= RE_vertren_get_sticky(re, ver, 1);
+ sticky[0]= ms->co[0];
+ sticky[1]= ms->co[1];
+ ms++;
+ }
+ }
+ /* still to do for keys: the correct local texture coordinate */
+
+ /* faces in order of color blocks */
+ vertofs= re->totvert - totvert;
+ for(a1=0; (a1<ob->totcol || (a1==0 && ob->totcol==0)); a1++) {
+
+ ma= give_render_material(re, ob, a1+1);
+
+ /* test for 100% transparant */
+ ok= 1;
+ if(ma->alpha==0.0 && ma->spectra==0.0) {
+ ok= 0;
+ /* texture on transparency? */
+ for(a=0; a<MAX_MTEX; a++) {
+ if(ma->mtex[a] && ma->mtex[a]->tex) {
+ if(ma->mtex[a]->mapto & MAP_ALPHA) ok= 1;
+ }
+ }
+ }
+
+ /* if wire material, and we got edges, don't do the faces */
+ if(ma->mode & MA_WIRE) {
+ end= dlm?dlm->totedge:me->totedge;
+ if(end) ok= 0;
+ }
+
+ if(ok) {
+ TFace *tface= NULL;
+
+ /* radio faces need autosmooth, to separate shared vertices in corners */
+ if(re->r.mode & R_RADIO)
+ if(ma->mode & MA_RADIO)
+ do_autosmooth= 1;
+
+ end= dlm?dlm->totface:me->totface;
+ if (dlm) {
+ mface= dlm->mface;
+ if (dlm->tface) {
+ tface= dlm->tface;
+ vertcol= NULL;
+ } else if (dlm->mcol) {
+ vertcol= (unsigned int *)dlm->mcol;
+ } else {
+ vertcol= NULL;
+ }
+ } else {
+ mface= me->mface;
+ if (me->tface) {
+ tface= me->tface;
+ vertcol= NULL;
+ } else if (me->mcol) {
+ vertcol= (unsigned int *)me->mcol;
+ } else {
+ vertcol= NULL;
+ }
+ }
+
+ for(a=0; a<end; a++) {
+ int v1, v2, v3, v4, flag;
+
+ if( mface->mat_nr==a1 ) {
+ float len;
+
+ v1= mface->v1;
+ v2= mface->v2;
+ v3= mface->v3;
+ v4= mface->v4;
+ flag= mface->flag & ME_SMOOTH;
+
+ vlr= RE_findOrAddVlak(re, re->totvlak++);
+ vlr->ob= ob;
+ vlr->v1= RE_findOrAddVert(re, vertofs+v1);
+ vlr->v2= RE_findOrAddVert(re, vertofs+v2);
+ vlr->v3= RE_findOrAddVert(re, vertofs+v3);
+ if(v4) vlr->v4= RE_findOrAddVert(re, vertofs+v4);
+ else vlr->v4= 0;
+
+ /* render normals are inverted in render */
+ if(vlr->v4) len= CalcNormFloat4(vlr->v4->co, vlr->v3->co, vlr->v2->co,
+ vlr->v1->co, vlr->n);
+ else len= CalcNormFloat(vlr->v3->co, vlr->v2->co, vlr->v1->co,
+ vlr->n);
+
+ vlr->mat= ma;
+ vlr->flag= flag;
+ if((me->flag & ME_NOPUNOFLIP) ) {
+ vlr->flag |= R_NOPUNOFLIP;
+ }
+ vlr->ec= 0; /* mesh edges rendered separately */
+ vlr->lay= ob->lay;
+
+ if(len==0) re->totvlak--;
+ else {
+ if(dlm) {
+ if(tface) {
+ vlr->tface= BLI_memarena_alloc(re->memArena, sizeof(TFace));
+ vlr->vcol= vlr->tface->col;
+ memcpy(vlr->tface, tface, sizeof(TFace));
+ }
+ else if (vertcol) {
+ vlr->vcol= BLI_memarena_alloc(re->memArena, sizeof(int)*4);
+ memcpy(vlr->vcol, vertcol+4*a, sizeof(int)*4);
+ }
+ } else {
+ if(tface) {
+ vlr->vcol= tface->col;
+ vlr->tface= tface;
+ }
+ else if (vertcol) {
+ vlr->vcol= vertcol+4*a;
+ }
+ }
+ }
+ }
+
+ mface++;
+ if(tface) tface++;
+ }
+ }
+ }
+
+ /* exception... we do edges for wire mode. potential conflict when faces exist... */
+ end= dlm?dlm->totedge:me->totedge;
+ mvert= dlm?dlm->mvert:me->mvert;
+ ma= give_render_material(re, ob, 1);
+ if(end && (ma->mode & MA_WIRE)) {
+ MEdge *medge;
+ struct edgesort *edgetable;
+ int totedge;
+
+ medge= dlm?dlm->medge:me->medge;
+
+ /* we want edges to have UV and vcol too... */
+ edgetable= make_mesh_edge_lookup(me, dlm, &totedge);
+
+ for(a1=0; a1<end; a1++, medge++) {
+ if (medge->flag&ME_EDGERENDER) {
+ MVert *v0 = &mvert[medge->v1];
+ MVert *v1 = &mvert[medge->v2];
+
+ vlr= RE_findOrAddVlak(re, re->totvlak++);
+ vlr->ob= ob;
+ vlr->v1= RE_findOrAddVert(re, vertofs+medge->v1);
+ vlr->v2= RE_findOrAddVert(re, vertofs+medge->v2);
+ vlr->v3= vlr->v2;
+ vlr->v4= NULL;
+
+ if(edgetable) {
+ use_mesh_edge_lookup(re, me, dlm, medge, vlr, edgetable, totedge);
+ }
+
+ xn= (v0->no[0]+v1->no[0]);
+ yn= (v0->no[1]+v1->no[1]);
+ zn= (v0->no[2]+v1->no[2]);
+ /* transpose ! */
+ vlr->n[0]= imat[0][0]*xn+imat[0][1]*yn+imat[0][2]*zn;
+ vlr->n[1]= imat[1][0]*xn+imat[1][1]*yn+imat[1][2]*zn;
+ vlr->n[2]= imat[2][0]*xn+imat[2][1]*yn+imat[2][2]*zn;
+ Normalise(vlr->n);
+
+ vlr->mat= ma;
+ vlr->flag= 0;
+ vlr->ec= ME_V1V2;
+ vlr->lay= ob->lay;
+ }
+ }
+ if(edgetable)
+ MEM_freeN(edgetable);
+ }
+ }
+
+ if (test_for_displace(re, ob ) ) {
+ calc_vertexnormals(re, totverto, totvlako, 0);
+ do_displacement(re, ob, totvlako, re->totvlak-totvlako, totverto, re->totvert-totverto);
+ }
+
+ if(do_autosmooth || (me->flag & ME_AUTOSMOOTH)) {
+ autosmooth(re, totverto, totvlako, me->smoothresh);
+ }
+
+ calc_vertexnormals(re, totverto, totvlako, need_tangent);
+
+ if(need_stress)
+ calc_edge_stress(re, me, totverto, totvlako);
+
+ if(dlm) displistmesh_free(dlm);
+ if(dm_needsfree) dm->release(dm);
+}
+
+/* ------------------------------------------------------------------------- */
+
+static void initshadowbuf(Render *re, LampRen *lar, float mat[][4])
+{
+ struct ShadBuf *shb;
+ float hoek, temp, viewinv[4][4];
+
+ /* if(la->spsi<16) return; */
+
+ /* memory reservation */
+ shb= (struct ShadBuf *)MEM_callocN( sizeof(struct ShadBuf),"initshadbuf");
+ lar->shb= shb;
+
+ if(shb==NULL) return;
+
+ VECCOPY(shb->co, lar->co);
+
+ /* percentage render: keep track of min and max */
+ shb->size= (lar->bufsize*re->r.size)/100;
+ if(shb->size<512) shb->size= 512;
+ else if(shb->size > lar->bufsize) shb->size= lar->bufsize;
+
+ shb->size &= ~15; /* make sure its multiples of 16 */
+
+ shb->samp= lar->samp;
+ shb->soft= lar->soft;
+ shb->shadhalostep= lar->shadhalostep;
+
+ shb->zbuf= (unsigned long *)MEM_mallocN( sizeof(unsigned long)*(shb->size*shb->size)/256, "initshadbuf2");
+ shb->cbuf= (char *)MEM_callocN( (shb->size*shb->size)/256, "initshadbuf3");
+
+ if(shb->zbuf==0 || shb->cbuf==0) {
+ if(shb->zbuf) MEM_freeN(shb->zbuf);
+ MEM_freeN(lar->shb);
+ lar->shb= 0;
+ return;
+ }
+
+ MTC_Mat4Ortho(mat);
+ MTC_Mat4Invert(shb->winmat, mat); /* winmat is temp */
+
+ /* matrix: combination of inverse view and lampmat */
+ /* calculate again: the ortho-render has no correct viewinv */
+ MTC_Mat4Invert(viewinv, re->viewmat);
+ MTC_Mat4MulMat4(shb->viewmat, viewinv, shb->winmat);
+
+ /* projection */
+ hoek= saacos(lar->spotsi);
+ temp= 0.5*shb->size*cos(hoek)/sin(hoek);
+ shb->d= lar->clipsta;
+
+ shb->pixsize= (shb->d)/temp;
+
+ shb->clipend= lar->clipend;
+ /* bias is percentage, made 2x karger because of correction for angle of incidence */
+ /* when a ray is closer to parallel of a face, bias value is increased during render */
+ shb->bias= (0.02*lar->bias)*0x7FFFFFFF;
+ shb->bias= shb->bias*(100/re->r.size);
+
+}
+
+
+static void area_lamp_vectors(LampRen *lar)
+{
+ float xsize= 0.5*lar->area_size, ysize= 0.5*lar->area_sizey;
+
+ /* corner vectors */
+ lar->area[0][0]= lar->co[0] - xsize*lar->mat[0][0] - ysize*lar->mat[1][0];
+ lar->area[0][1]= lar->co[1] - xsize*lar->mat[0][1] - ysize*lar->mat[1][1];
+ lar->area[0][2]= lar->co[2] - xsize*lar->mat[0][2] - ysize*lar->mat[1][2];
+
+ /* corner vectors */
+ lar->area[1][0]= lar->co[0] - xsize*lar->mat[0][0] + ysize*lar->mat[1][0];
+ lar->area[1][1]= lar->co[1] - xsize*lar->mat[0][1] + ysize*lar->mat[1][1];
+ lar->area[1][2]= lar->co[2] - xsize*lar->mat[0][2] + ysize*lar->mat[1][2];
+
+ /* corner vectors */
+ lar->area[2][0]= lar->co[0] + xsize*lar->mat[0][0] + ysize*lar->mat[1][0];
+ lar->area[2][1]= lar->co[1] + xsize*lar->mat[0][1] + ysize*lar->mat[1][1];
+ lar->area[2][2]= lar->co[2] + xsize*lar->mat[0][2] + ysize*lar->mat[1][2];
+
+ /* corner vectors */
+ lar->area[3][0]= lar->co[0] + xsize*lar->mat[0][0] - ysize*lar->mat[1][0];
+ lar->area[3][1]= lar->co[1] + xsize*lar->mat[0][1] - ysize*lar->mat[1][1];
+ lar->area[3][2]= lar->co[2] + xsize*lar->mat[0][2] - ysize*lar->mat[1][2];
+ /* only for correction button size, matrix size works on energy */
+ lar->areasize= lar->dist*lar->dist/(4.0*xsize*ysize);
+}
+
+/* If lar takes more lamp data, the decoupling will be better. */
+static void add_render_lamp(Render *re, Object *ob, int actual_render)
+{
+ Lamp *la= ob->data;
+ LampRen *lar;
+ GroupObject *go;
+ float mat[4][4], hoek, xn, yn;
+ int c;
+
+ /* prevent only shadow from rendering light, but only return on render, not preview */
+ if(actual_render) {
+ if(la->mode & LA_ONLYSHADOW)
+ if((re->r.mode & R_SHADOW)==0)
+ return;
+ }
+
+ go= MEM_callocN(sizeof(GroupObject), "groupobject");
+ BLI_addtail(&re->lights, go);
+ re->totlamp++;
+ lar= (LampRen *)MEM_callocN(sizeof(LampRen),"lampren");
+ go->lampren= lar;
+ go->ob= ob;
+
+ MTC_Mat4MulMat4(mat, ob->obmat, re->viewmat);
+ MTC_Mat4Invert(ob->imat, mat);
+
+ MTC_Mat3CpyMat4(lar->mat, mat);
+ MTC_Mat3CpyMat4(lar->imat, ob->imat);
+
+ lar->bufsize = la->bufsize;
+ lar->samp = la->samp;
+ lar->soft = la->soft;
+ lar->shadhalostep = la->shadhalostep;
+ lar->clipsta = la->clipsta;
+ lar->clipend = la->clipend;
+ lar->bias = la->bias;
+
+ lar->type= la->type;
+ lar->mode= la->mode;
+
+ lar->energy= la->energy;
+ lar->energy= la->energy;
+ if(la->mode & LA_NEG) lar->energy= -lar->energy;
+
+ lar->vec[0]= -mat[2][0];
+ lar->vec[1]= -mat[2][1];
+ lar->vec[2]= -mat[2][2];
+ Normalise(lar->vec);
+ lar->co[0]= mat[3][0];
+ lar->co[1]= mat[3][1];
+ lar->co[2]= mat[3][2];
+ lar->dist= la->dist;
+ lar->haint= la->haint;
+ lar->distkw= lar->dist*lar->dist;
+ lar->r= lar->energy*la->r;
+ lar->g= lar->energy*la->g;
+ lar->b= lar->energy*la->b;
+ lar->k= la->k;
+
+ // area
+ lar->ray_samp= la->ray_samp;
+ lar->ray_sampy= la->ray_sampy;
+ lar->ray_sampz= la->ray_sampz;
+
+ lar->area_size= la->area_size;
+ lar->area_sizey= la->area_sizey;
+ lar->area_sizez= la->area_sizez;
+
+ lar->area_shape= la->area_shape;
+ lar->ray_samp_type= la->ray_samp_type;
+
+ if(lar->type==LA_AREA) {
+ switch(lar->area_shape) {
+ case LA_AREA_SQUARE:
+ lar->ray_totsamp= lar->ray_samp*lar->ray_samp;
+ lar->ray_sampy= lar->ray_samp;
+ lar->area_sizey= lar->area_size;
+ break;
+ case LA_AREA_RECT:
+ lar->ray_totsamp= lar->ray_samp*lar->ray_sampy;
+ break;
+ case LA_AREA_CUBE:
+ lar->ray_totsamp= lar->ray_samp*lar->ray_samp*lar->ray_samp;
+ lar->ray_sampy= lar->ray_samp;
+ lar->ray_sampz= lar->ray_samp;
+ lar->area_sizey= lar->area_size;
+ lar->area_sizez= lar->area_size;
+ break;
+ case LA_AREA_BOX:
+ lar->ray_totsamp= lar->ray_samp*lar->ray_sampy*lar->ray_sampz;
+ break;
+ }
+
+ area_lamp_vectors(lar);
+ }
+ else lar->ray_totsamp= 0;
+
+ /* yafray: photonlight and other params */
+ if (re->r.renderer==R_YAFRAY) {
+ lar->YF_numphotons = la->YF_numphotons;
+ lar->YF_numsearch = la->YF_numsearch;
+ lar->YF_phdepth = la->YF_phdepth;
+ lar->YF_useqmc = la->YF_useqmc;
+ lar->YF_causticblur = la->YF_causticblur;
+ lar->YF_ltradius = la->YF_ltradius;
+ lar->YF_bufsize = la->YF_bufsize;
+ lar->YF_glowint = la->YF_glowint;
+ lar->YF_glowofs = la->YF_glowofs;
+ lar->YF_glowtype = la->YF_glowtype;
+ }
+
+ lar->spotsi= la->spotsize;
+ if(lar->mode & LA_HALO) {
+ if(lar->spotsi>170.0) lar->spotsi= 170.0;
+ }
+ lar->spotsi= cos( M_PI*lar->spotsi/360.0 );
+ lar->spotbl= (1.0-lar->spotsi)*la->spotblend;
+
+ memcpy(lar->mtex, la->mtex, MAX_MTEX*sizeof(void *));
+
+ lar->lay= ob->lay & 0xFFFFFF; // higher 8 bits are localview layers
+
+ lar->ld1= la->att1;
+ lar->ld2= la->att2;
+
+ if(lar->type==LA_SPOT) {
+
+ Normalise(lar->imat[0]);
+ Normalise(lar->imat[1]);
+ Normalise(lar->imat[2]);
+
+ xn= saacos(lar->spotsi);
+ xn= sin(xn)/cos(xn);
+ lar->spottexfac= 1.0/(xn);
+
+ if(lar->mode & LA_ONLYSHADOW) {
+ if((lar->mode & (LA_SHAD|LA_SHAD_RAY))==0) lar->mode -= LA_ONLYSHADOW;
+ }
+
+ }
+
+ /* set flag for spothalo en initvars */
+ if(la->type==LA_SPOT && (la->mode & LA_HALO)) {
+ if(la->haint>0.0) {
+ re->flag |= R_LAMPHALO;
+
+ /* camera position (0,0,0) rotate around lamp */
+ lar->sh_invcampos[0]= -lar->co[0];
+ lar->sh_invcampos[1]= -lar->co[1];
+ lar->sh_invcampos[2]= -lar->co[2];
+ MTC_Mat3MulVecfl(lar->imat, lar->sh_invcampos);
+
+ /* z factor, for a normalized volume */
+ hoek= saacos(lar->spotsi);
+ xn= lar->spotsi;
+ yn= sin(hoek);
+ lar->sh_zfac= yn/xn;
+ /* pre-scale */
+ lar->sh_invcampos[2]*= lar->sh_zfac;
+
+ }
+ }
+
+ for(c=0; c<MAX_MTEX; c++) {
+ if(la->mtex[c] && la->mtex[c]->tex) {
+ lar->mode |= LA_TEXTURE;
+
+ if(G.rendering) {
+ if(re->osa) {
+ if(la->mtex[c]->tex->type==TEX_IMAGE) lar->mode |= LA_OSATEX;
+ }
+ }
+ }
+ }
+
+ /* yafray: shadowbuffers and jitter only needed for internal render */
+ if (actual_render && re->r.renderer==R_INTERN) {
+ if(re->r.mode & R_SHADOW) {
+ if (la->type==LA_SPOT && (lar->mode & LA_SHAD) ) {
+ /* Per lamp, one shadow buffer is made. */
+ Mat4CpyMat4(mat, ob->obmat);
+ initshadowbuf(re, lar, mat); // mat is altered
+ }
+ else if(la->type==LA_AREA && (lar->mode & LA_SHAD_RAY) ) {
+ init_jitter_plane(lar);
+ }
+ }
+ }
+
+ /* yafray: shadow flag should not be cleared, only used with internal renderer */
+ if (re->r.renderer==R_INTERN) {
+ /* to make sure we can check ray shadow easily in the render code */
+ if(lar->mode & LA_SHAD_RAY) {
+ if( (re->r.mode & R_RAYTRACE)==0)
+ lar->mode &= ~LA_SHAD_RAY;
+ }
+ }
+}
+
+/* ------------------------------------------------------------------------- */
+static void init_render_surf(Render *re, Object *ob)
+{
+ extern Material defmaterial; // initrender.c
+ Nurb *nu=0;
+ Curve *cu;
+ ListBase displist;
+ DispList *dl;
+ VertRen *ver, *v1, *v2, *v3, *v4;
+ VlakRen *vlr;
+ Material *matar[32];
+ float *data, *orco=NULL, *orcobase=NULL, n1[3], flen, mat[4][4];
+ int a, need_orco=0, startvlak, startvert, p1, p2, p3, p4;
+ int u, v;
+ int sizeu, sizev;
+ VlakRen *vlr1, *vlr2, *vlr3;
+ float vn[3]; // n2[3],
+
+ cu= ob->data;
+ nu= cu->nurb.first;
+ if(nu==0) return;
+
+ MTC_Mat4MulMat4(mat, ob->obmat, re->viewmat);
+ MTC_Mat4Invert(ob->imat, mat);
+
+ /* material array */
+ memset(matar, 0, 4*32);
+ matar[0]= &defmaterial;
+ for(a=0; a<ob->totcol; a++) {
+ matar[a]= give_render_material(re, ob, a+1);
+ if(matar[a] && matar[a]->texco & TEXCO_ORCO) {
+ need_orco= 1;
+ }
+ }
+
+ if(ob->parent && (ob->parent->type==OB_LATTICE)) need_orco= 1;
+
+ if(need_orco) orcobase= orco= get_object_orco(re, ob);
+
+ displist.first= displist.last= 0;
+ makeDispListSurf(ob, &displist, 1);
+
+ dl= displist.first;
+ /* walk along displaylist and create rendervertices/-faces */
+ while(dl) {
+ /* watch out: u ^= y, v ^= x !! */
+ if(dl->type==DL_SURF) {
+ int nsizeu, nsizev;
+
+ startvert= re->totvert;
+ nsizeu = sizeu = dl->parts; nsizev = sizev = dl->nr;
+
+ data= dl->verts;
+ for (u = 0; u < sizeu; u++) {
+ v1 = RE_findOrAddVert(re, re->totvert++); /* save this for possible V wrapping */
+ VECCOPY(v1->co, data); data += 3;
+ if(orco) {
+ v1->orco= orco; orco+= 3;
+ }
+ MTC_Mat4MulVecfl(mat, v1->co);
+
+ for (v = 1; v < sizev; v++) {
+ ver= RE_findOrAddVert(re, re->totvert++);
+ VECCOPY(ver->co, data); data += 3;
+ if(orco) {
+ ver->orco= orco; orco+= 3;
+ }
+ MTC_Mat4MulVecfl(mat, ver->co);
+ }
+ /* if V-cyclic, add extra vertices at end of the row */
+ if (dl->flag & DL_CYCL_U) {
+ ver= RE_findOrAddVert(re, re->totvert++);
+ VECCOPY(ver->co, v1->co);
+ if(orco) {
+ ver->orco= orcobase + 3*(u*sizev + 0);
+ }
+ }
+ }
+
+ /* Done before next loop to get corner vert */
+ if (dl->flag & DL_CYCL_U) nsizev++;
+ if (dl->flag & DL_CYCL_V) nsizeu++;
+
+ /* if U cyclic, add extra row at end of column */
+ if (dl->flag & DL_CYCL_V) {
+ for (v = 0; v < nsizev; v++) {
+ v1= RE_findOrAddVert(re, startvert + v);
+ ver= RE_findOrAddVert(re, re->totvert++);
+ VECCOPY(ver->co, v1->co);
+ if(orco) {
+ ver->orco= orcobase + 3*(0*sizev + v);
+ }
+ }
+ }
+
+ sizeu = nsizeu;
+ sizev = nsizev;
+
+ startvlak= re->totvlak;
+
+ for(u = 0; u < sizeu - 1; u++) {
+ p1 = startvert + u * sizev; /* walk through face list */
+ p2 = p1 + 1;
+ p3 = p2 + sizev;
+ p4 = p3 - 1;
+
+ for(v = 0; v < sizev - 1; v++) {
+ v1= RE_findOrAddVert(re, p1);
+ v2= RE_findOrAddVert(re, p2);
+ v3= RE_findOrAddVert(re, p3);
+ v4= RE_findOrAddVert(re, p4);
+
+ vlr= RE_findOrAddVlak(re, re->totvlak++);
+ vlr->ob= ob;
+ vlr->v1= v1; vlr->v2= v2; vlr->v3= v3; vlr->v4= v4;
+
+ flen= CalcNormFloat4(vlr->v4->co, vlr->v3->co, vlr->v2->co, vlr->v1->co, n1);
+ VECCOPY(vlr->n, n1);
+
+ vlr->lay= ob->lay;
+ vlr->mat= matar[ dl->col];
+ vlr->ec= ME_V1V2+ME_V2V3;
+ vlr->flag= dl->rt;
+ if( (cu->flag & CU_NOPUNOFLIP) ) {
+ vlr->flag |= R_NOPUNOFLIP;
+ }
+
+ VecAddf(v1->n, v1->n, n1);
+ VecAddf(v2->n, v2->n, n1);
+ VecAddf(v3->n, v3->n, n1);
+ VecAddf(v4->n, v4->n, n1);
+
+ p1++; p2++; p3++; p4++;
+ }
+ }
+ /* fix normals for U resp. V cyclic faces */
+ sizeu--; sizev--; /* dec size for face array */
+ if (dl->flag & DL_CYCL_V) {
+
+ for (v = 0; v < sizev; v++)
+ {
+ /* optimize! :*/
+ vlr= RE_findOrAddVlak(re, UVTOINDEX(sizeu - 1, v));
+ vlr1= RE_findOrAddVlak(re, UVTOINDEX(0, v));
+ VecAddf(vlr1->v1->n, vlr1->v1->n, vlr->n);
+ VecAddf(vlr1->v2->n, vlr1->v2->n, vlr->n);
+ VecAddf(vlr->v3->n, vlr->v3->n, vlr1->n);
+ VecAddf(vlr->v4->n, vlr->v4->n, vlr1->n);
+ }
+ }
+ if (dl->flag & DL_CYCL_U) {
+
+ for (u = 0; u < sizeu; u++)
+ {
+ /* optimize! :*/
+ vlr= RE_findOrAddVlak(re, UVTOINDEX(u, 0));
+ vlr1= RE_findOrAddVlak(re, UVTOINDEX(u, sizev-1));
+ VecAddf(vlr1->v2->n, vlr1->v2->n, vlr->n);
+ VecAddf(vlr1->v3->n, vlr1->v3->n, vlr->n);
+ VecAddf(vlr->v1->n, vlr->v1->n, vlr1->n);
+ VecAddf(vlr->v4->n, vlr->v4->n, vlr1->n);
+ }
+ }
+ /* last vertex is an extra case:
+
+ ^ ()----()----()----()
+ | | | || |
+ u | |(0,n)||(0,0)|
+ | | || |
+ ()====()====[]====()
+ | | || |
+ | |(m,n)||(m,0)|
+ | | || |
+ ()----()----()----()
+ v ->
+
+ vertex [] is no longer shared, therefore distribute
+ normals of the surrounding faces to all of the duplicates of []
+ */
+
+ if ((dl->flag & DL_CYCL_V) && (dl->flag & DL_CYCL_U))
+ {
+ vlr= RE_findOrAddVlak(re, UVTOINDEX(sizeu - 1, sizev - 1)); /* (m,n) */
+ vlr1= RE_findOrAddVlak(re, UVTOINDEX(0,0)); /* (0,0) */
+ VecAddf(vn, vlr->n, vlr1->n);
+ vlr2= RE_findOrAddVlak(re, UVTOINDEX(0, sizev-1)); /* (0,n) */
+ VecAddf(vn, vn, vlr2->n);
+ vlr3= RE_findOrAddVlak(re, UVTOINDEX(sizeu-1, 0)); /* (m,0) */
+ VecAddf(vn, vn, vlr3->n);
+ VECCOPY(vlr->v3->n, vn);
+ VECCOPY(vlr1->v1->n, vn);
+ VECCOPY(vlr2->v2->n, vn);
+ VECCOPY(vlr3->v4->n, vn);
+ }
+ for(a = startvert; a < re->totvert; a++) {
+ ver= RE_findOrAddVert(re, a);
+ Normalise(ver->n);
+ }
+
+
+ }
+
+ dl= dl->next;
+ }
+ freedisplist(&displist);
+}
+
+static void init_render_curve(Render *re, Object *ob)
+{
+ extern Material defmaterial; // initrender.c
+ Curve *cu;
+ VertRen *ver;
+ VlakRen *vlr;
+ DispList *dl;
+ Material *matar[32];
+ float len, *data, *fp, *orco=NULL;
+ float n[3], mat[4][4];
+ int nr, startvert, startvlak, a, b;
+ int frontside, need_orco=0;
+
+ cu= ob->data;
+ if(cu->nurb.first==NULL) return;
+
+ /* no modifier call here, is in makedisp */
+
+ /* test displist */
+ if(cu->disp.first==0) makeDispListCurveTypes(ob, 0);
+ dl= cu->disp.first;
+ if(cu->disp.first==0) return;
+
+ MTC_Mat4MulMat4(mat, ob->obmat, re->viewmat);
+ MTC_Mat4Invert(ob->imat, mat);
+
+ /* material array */
+ memset(matar, 0, 4*32);
+ matar[0]= &defmaterial;
+ for(a=0; a<ob->totcol; a++) {
+ matar[a]= give_render_material(re, ob, a+1);
+ if(matar[a]->texco & TEXCO_ORCO) {
+ need_orco= 1;
+ }
+ }
+
+ if(need_orco) orco= get_object_orco(re, ob);
+
+ dl= cu->disp.first;
+ while(dl) {
+ if(dl->type==DL_INDEX3) {
+ int *index;
+
+ startvert= re->totvert;
+ data= dl->verts;
+
+ n[0]= ob->imat[0][2];
+ n[1]= ob->imat[1][2];
+ n[2]= ob->imat[2][2];
+ Normalise(n);
+
+ /* copy first, rotate later for comparision trick */
+ for(a=0; a<dl->nr; a++, data+=3) {
+ ver= RE_findOrAddVert(re, re->totvert++);
+ VECCOPY(ver->co, data);
+ MTC_Mat4MulVecfl(mat, ver->co);
+
+ if(ver->co[2] < 0.0) {
+ VECCOPY(ver->n, n);
+ ver->flag = 1;
+ }
+ else {
+ ver->n[0]= -n[0]; ver->n[1]= -n[1]; ver->n[2]= -n[2];
+ ver->flag = 0;
+ }
+
+ if (orco) {
+ ver->orco = orco;
+ orco += 3;
+ }
+ }
+
+ startvlak= re->totvlak;
+ index= dl->index;
+ for(a=0; a<dl->parts; a++, index+=3) {
+
+ vlr= RE_findOrAddVlak(re, re->totvlak++);
+ vlr->ob = ob;
+ vlr->v1= RE_findOrAddVert(re, startvert+index[0]);
+ vlr->v2= RE_findOrAddVert(re, startvert+index[1]);
+ vlr->v3= RE_findOrAddVert(re, startvert+index[2]);
+ vlr->v4= NULL;
+
+ if(vlr->v1->flag) {
+ VECCOPY(vlr->n, n);
+ }
+ else {
+ vlr->n[0]= -n[0]; vlr->n[1]= -n[1]; vlr->n[2]= -n[2];
+ }
+
+ vlr->mat= matar[ dl->col ];
+ vlr->flag= 0;
+ if( (cu->flag & CU_NOPUNOFLIP) ) {
+ vlr->flag |= R_NOPUNOFLIP;
+ }
+ vlr->ec= 0;
+ vlr->lay= ob->lay;
+ }
+ }
+ else if (dl->type==DL_SURF) {
+ int p1,p2,p3,p4;
+
+ fp= dl->verts;
+ startvert= re->totvert;
+ nr= dl->nr*dl->parts;
+
+ while(nr--) {
+ ver= RE_findOrAddVert(re, re->totvert++);
+
+ VECCOPY(ver->co, fp);
+ MTC_Mat4MulVecfl(mat, ver->co);
+ fp+= 3;
+
+ if (orco) {
+ ver->orco = orco;
+ orco += 3;
+ }
+ }
+
+ startvlak= re->totvlak;
+
+ for(a=0; a<dl->parts; a++) {
+
+ frontside= (a >= dl->nr/2);
+
+ DL_SURFINDEX(dl->flag & DL_CYCL_U, dl->flag & DL_CYCL_V, dl->nr, dl->parts);
+ p1+= startvert;
+ p2+= startvert;
+ p3+= startvert;
+ p4+= startvert;
+
+ for(; b<dl->nr; b++) {
+ vlr= RE_findOrAddVlak(re, re->totvlak++);
+ vlr->ob= ob;
+ vlr->v1= RE_findOrAddVert(re, p2);
+ vlr->v2= RE_findOrAddVert(re, p1);
+ vlr->v3= RE_findOrAddVert(re, p3);
+ vlr->v4= RE_findOrAddVert(re, p4);
+ vlr->ec= ME_V2V3+ME_V3V4;
+ if(a==0) vlr->ec+= ME_V1V2;
+
+ vlr->flag= dl->rt;
+ vlr->lay= ob->lay;
+
+ /* this is not really scientific: the vertices
+ * 2, 3 en 4 seem to give better vertexnormals than 1 2 3:
+ * front and backside treated different!!
+ */
+
+ if(frontside)
+ CalcNormFloat(vlr->v2->co, vlr->v3->co, vlr->v4->co, vlr->n);
+ else
+ CalcNormFloat(vlr->v1->co, vlr->v2->co, vlr->v3->co, vlr->n);
+
+ vlr->mat= matar[ dl->col ];
+
+ p4= p3;
+ p3++;
+ p2= p1;
+ p1++;
+ }
+ }
+
+ if (dl->bevelSplitFlag) {
+ for(a=0; a<dl->parts-1+!!(dl->flag&DL_CYCL_V); a++)
+ if(dl->bevelSplitFlag[a>>5]&(1<<(a&0x1F)))
+ split_v_renderfaces(re, startvlak, startvert, dl->parts, dl->nr, a, dl->flag&DL_CYCL_V, dl->flag&DL_CYCL_U);
+ }
+
+ /* vertex normals */
+ for(a= startvlak; a<re->totvlak; a++) {
+ vlr= RE_findOrAddVlak(re, a);
+
+ VecAddf(vlr->v1->n, vlr->v1->n, vlr->n);
+ VecAddf(vlr->v3->n, vlr->v3->n, vlr->n);
+ VecAddf(vlr->v2->n, vlr->v2->n, vlr->n);
+ VecAddf(vlr->v4->n, vlr->v4->n, vlr->n);
+ }
+ for(a=startvert; a<re->totvert; a++) {
+ ver= RE_findOrAddVert(re, a);
+ len= Normalise(ver->n);
+ if(len==0.0) ver->flag= 1; /* flag use, its only used in zbuf now */
+ else ver->flag= 0;
+ }
+ for(a= startvlak; a<re->totvlak; a++) {
+ vlr= RE_findOrAddVlak(re, a);
+ if(vlr->v1->flag) VECCOPY(vlr->v1->n, vlr->n);
+ if(vlr->v2->flag) VECCOPY(vlr->v2->n, vlr->n);
+ if(vlr->v3->flag) VECCOPY(vlr->v3->n, vlr->n);
+ if(vlr->v4->flag) VECCOPY(vlr->v4->n, vlr->n);
+ }
+ }
+
+ dl= dl->next;
+ }
+}
+
+/* prevent phong interpolation for giving ray shadow errors (terminator problem) */
+static void set_phong_threshold(Render *re, Object *ob, int startface, int numface, int startvert, int numvert )
+{
+// VertRen *ver;
+ VlakRen *vlr;
+ float thresh= 0.0, dot;
+ int tot=0, i;
+
+ /* Added check for 'pointy' situations, only dotproducts of 0.9 and larger
+ are taken into account. This threshold is meant to work on smooth geometry, not
+ for extreme cases (ton) */
+
+ for(i=startface; i<startface+numface; i++) {
+ vlr= RE_findOrAddVlak(re, i);
+ if(vlr->flag & R_SMOOTH) {
+ dot= INPR(vlr->n, vlr->v1->n);
+ dot= ABS(dot);
+ if(dot>0.9) {
+ thresh+= dot; tot++;
+ }
+ dot= INPR(vlr->n, vlr->v2->n);
+ dot= ABS(dot);
+ if(dot>0.9) {
+ thresh+= dot; tot++;
+ }
+
+ dot= INPR(vlr->n, vlr->v3->n);
+ dot= ABS(dot);
+ if(dot>0.9) {
+ thresh+= dot; tot++;
+ }
+
+ if(vlr->v4) {
+ dot= INPR(vlr->n, vlr->v4->n);
+ dot= ABS(dot);
+ if(dot>0.9) {
+ thresh+= dot; tot++;
+ }
+ }
+ }
+ }
+
+ if(tot) {
+ thresh/= (float)tot;
+ ob->smoothresh= cos(0.5*M_PI-acos(thresh));
+ }
+}
+
+static void init_render_object(Render *re, Object *ob)
+{
+ float mat[4][4];
+ int startface, startvert;
+
+ startface=re->totvlak;
+ startvert=re->totvert;
+
+ ob->flag |= OB_DONE;
+
+ if(ob->type==OB_LAMP)
+ add_render_lamp(re, ob, 1);
+ else if ELEM(ob->type, OB_FONT, OB_CURVE)
+ init_render_curve(re, ob);
+ else if(ob->type==OB_SURF)
+ init_render_surf(re, ob);
+ else if(ob->type==OB_MESH)
+ init_render_mesh(re, ob);
+ else if(ob->type==OB_MBALL)
+ init_render_mball(re, ob);
+ else {
+ MTC_Mat4MulMat4(mat, ob->obmat, re->viewmat);
+ MTC_Mat4Invert(ob->imat, mat);
+ }
+
+ /* generic post process here */
+ if(startvert!=re->totvert) {
+
+ /* the exception below is because displace code now is in init_render_mesh call,
+ I will look at means to have autosmooth enabled for all object types
+ and have it as general postprocess, like displace */
+ if (ob->type!=OB_MESH && test_for_displace(re, ob ) )
+ do_displacement(re, ob, startface, re->totvlak-startface, startvert, re->totvert-startvert);
+
+ /* phong normal interpolation can cause error in tracing (terminator prob) */
+ ob->smoothresh= 0.0;
+ if( (re->r.mode & R_RAYTRACE) && (re->r.mode & R_SHADOW) )
+ set_phong_threshold(re, ob, startface, re->totvlak-startface, startvert, re->totvert-startvert);
+ }
+}
+
+void RE_Database_Free(Render *re)
+{
+ ShadBuf *shb;
+ Object *ob = NULL;
+ GroupObject *go;
+ unsigned long *ztile;
+ int b, v;
+ char *ctile;
+
+ /* FREE */
+
+ if(re->memArena) {
+ BLI_memarena_free(re->memArena);
+ re->memArena = NULL;
+ }
+
+ for(go= re->lights.first; go; go= go->next) {
+ struct LampRen *lar= go->lampren;
+ if(lar->shb) {
+ shb= lar->shb;
+ v= (shb->size*shb->size)/256;
+ ztile= shb->zbuf;
+ ctile= shb->cbuf;
+ for(b=0; b<v; b++, ztile++, ctile++) {
+ if(*ctile) MEM_freeN((void *) *ztile);
+ }
+
+ MEM_freeN(shb->zbuf);
+ MEM_freeN(shb->cbuf);
+ MEM_freeN(lar->shb);
+ }
+ if(lar->jitter) MEM_freeN(lar->jitter);
+ MEM_freeN(lar);
+ }
+
+ BLI_freelistN(&re->lights);
+
+ free_renderdata_tables(re);
+
+ /* free orco. check all objects because of duplis and sets */
+ ob= G.main->object.first;
+ while(ob) {
+ if(ob->type==OB_MBALL) {
+ if(ob->disp.first && ob->disp.first!=ob->disp.last) {
+ DispList *dl= ob->disp.first;
+ BLI_remlink(&ob->disp, dl);
+ freedisplist(&ob->disp);
+ BLI_addtail(&ob->disp, dl);
+ }
+ }
+ ob= ob->id.next;
+ }
+
+ free_mesh_orco_hash(re);
+
+ end_radio_render();
+ end_render_materials();
+
+ if(re->wrld.aosphere) {
+ MEM_freeN(re->wrld.aosphere);
+ re->wrld.aosphere= NULL;
+ re->scene->world->aosphere= NULL;
+ }
+
+ if(re->r.mode & R_RAYTRACE) freeoctree(re);
+
+ re->totvlak=re->totvert=re->totlamp=re->tothalo= 0;
+ re->i.convertdone= 0;
+
+}
+
+/* per face check if all samples should be taken.
+ if raytrace, do always for raytraced material, or when material full_osa set */
+static void set_fullsample_flag(Render *re)
+{
+ VlakRen *vlr;
+ int a, trace;
+
+ trace= re->r.mode & R_RAYTRACE;
+
+ for(a=re->totvlak-1; a>=0; a--) {
+ vlr= RE_findOrAddVlak(re, a);
+
+ if(vlr->mat->mode & MA_FULL_OSA) vlr->flag |= R_FULL_OSA;
+ else if(trace) {
+ if(vlr->mat->mode & MA_SHLESS);
+ else if(vlr->mat->mode & (MA_RAYTRANSP|MA_RAYMIRROR|MA_SHADOW))
+ vlr->flag |= R_FULL_OSA;
+ }
+ }
+}
+
+/* 10 times larger than normal epsilon, test it on default nurbs sphere with ray_transp */
+#ifdef FLT_EPSILON
+#undef FLT_EPSILON
+#endif
+#define FLT_EPSILON 1.19209290e-06F
+
+
+static void check_non_flat_quads(Render *re)
+{
+ VlakRen *vlr, *vlr1;
+ VertRen *v1, *v2, *v3, *v4;
+ float nor[3], xn, flen;
+ int a;
+
+ for(a=re->totvlak-1; a>=0; a--) {
+ vlr= RE_findOrAddVlak(re, a);
+
+ /* test if rendering as a quad or triangle, skip wire */
+ if(vlr->v4 && (vlr->flag & R_STRAND)==0 && (vlr->mat->mode & MA_WIRE)==0) {
+
+ /* check if quad is actually triangle */
+ v1= vlr->v1;
+ v2= vlr->v2;
+ v3= vlr->v3;
+ v4= vlr->v4;
+ VECSUB(nor, v1->co, v2->co);
+ if( ABS(nor[0])<FLT_EPSILON && ABS(nor[1])<FLT_EPSILON && ABS(nor[2])<FLT_EPSILON ) {
+ vlr->v1= v2;
+ vlr->v2= v3;
+ vlr->v3= v4;
+ vlr->v4= NULL;
+ }
+ else {
+ VECSUB(nor, v2->co, v3->co);
+ if( ABS(nor[0])<FLT_EPSILON && ABS(nor[1])<FLT_EPSILON && ABS(nor[2])<FLT_EPSILON ) {
+ vlr->v2= v3;
+ vlr->v3= v4;
+ vlr->v4= NULL;
+ }
+ else {
+ VECSUB(nor, v3->co, v4->co);
+ if( ABS(nor[0])<FLT_EPSILON && ABS(nor[1])<FLT_EPSILON && ABS(nor[2])<FLT_EPSILON ) {
+ vlr->v4= NULL;
+ }
+ else {
+ VECSUB(nor, v4->co, v1->co);
+ if( ABS(nor[0])<FLT_EPSILON && ABS(nor[1])<FLT_EPSILON && ABS(nor[2])<FLT_EPSILON ) {
+ vlr->v4= NULL;
+ }
+ }
+ }
+ }
+
+ if(vlr->v4) {
+
+ /* Face is divided along edge with the least gradient */
+ /* Flagged with R_DIVIDE_24 if divide is from vert 2 to 4 */
+ /* 4---3 4---3 */
+ /* |\ 1| or |1 /| */
+ /* |0\ | |/ 0| */
+ /* 1---2 1---2 0 = orig face, 1 = new face */
+
+ /* render normals are inverted in render! we calculate normal of single tria here */
+ flen= CalcNormFloat(vlr->v4->co, vlr->v3->co, vlr->v1->co, nor);
+ if(flen==0.0) CalcNormFloat(vlr->v4->co, vlr->v2->co, vlr->v1->co, nor);
+
+ xn= nor[0]*vlr->n[0] + nor[1]*vlr->n[1] + nor[2]*vlr->n[2];
+ if(ABS(xn) < 0.99995 ) { // checked on noisy fractal grid
+ float d1, d2;
+
+ vlr1= RE_findOrAddVlak(re, re->totvlak++);
+ *vlr1= *vlr;
+ vlr1->flag |= R_FACE_SPLIT;
+
+ /* split direction based on vnorms */
+ CalcNormFloat(vlr->v1->co, vlr->v2->co, vlr->v3->co, nor);
+ d1= nor[0]*vlr->v1->n[0] + nor[1]*vlr->v1->n[1] + nor[2]*vlr->v1->n[2];
+
+ CalcNormFloat(vlr->v2->co, vlr->v3->co, vlr->v4->co, nor);
+ d2= nor[0]*vlr->v2->n[0] + nor[1]*vlr->v2->n[1] + nor[2]*vlr->v2->n[2];
+
+ if( fabs(d1) < fabs(d2) ) vlr->flag |= R_DIVIDE_24;
+ else vlr->flag &= ~R_DIVIDE_24;
+
+ /* new vertex pointers */
+ if (vlr->flag & R_DIVIDE_24) {
+ vlr1->v1= vlr->v2;
+ vlr1->v2= vlr->v3;
+ vlr1->v3= vlr->v4;
+
+ vlr->v3 = vlr->v4;
+
+ vlr1->flag |= R_DIVIDE_24;
+ }
+ else {
+ vlr1->v1= vlr->v1;
+ vlr1->v2= vlr->v3;
+ vlr1->v3= vlr->v4;
+
+ vlr1->flag &= ~R_DIVIDE_24;
+ }
+ vlr->v4 = vlr1->v4 = NULL;
+
+ /* new normals */
+ CalcNormFloat(vlr->v3->co, vlr->v2->co, vlr->v1->co, vlr->n);
+ CalcNormFloat(vlr1->v3->co, vlr1->v2->co, vlr1->v1->co, vlr1->n);
+
+ /* so later UV can be pulled from original tface, look for R_DIVIDE_24 for direction */
+ vlr1->tface=vlr->tface;
+
+ }
+ /* clear the flag when not divided */
+ else vlr->flag &= ~R_DIVIDE_24;
+ }
+ }
+ }
+}
+
+static void set_material_lightgroups(Render *re)
+{
+ GroupObject *go, *gol;
+ Material *ma;
+
+ /* it's a bit too many loops in loops... but will survive */
+ for(ma= G.main->mat.first; ma; ma=ma->id.next) {
+ if(ma->group) {
+ for(go= ma->group->gobject.first; go; go= go->next) {
+ for(gol= re->lights.first; gol; gol= gol->next) {
+ if(gol->ob==go->ob) {
+ go->lampren= gol->lampren;
+ break;
+ }
+ }
+ }
+ }
+ }
+}
+
+void init_render_world(Render *re)
+{
+ int a;
+ char *cp;
+
+ if(re->scene && re->scene->world) {
+ re->wrld= *(re->scene->world);
+
+ cp= (char *)&re->wrld.fastcol;
+
+ cp[0]= 255.0*re->wrld.horr;
+ cp[1]= 255.0*re->wrld.horg;
+ cp[2]= 255.0*re->wrld.horb;
+ cp[3]= 1;
+
+ VECCOPY(re->grvec, re->viewmat[2]);
+ Normalise(re->grvec);
+ Mat3CpyMat4(re->imat, re->viewinv);
+
+ for(a=0; a<MAX_MTEX; a++)
+ if(re->wrld.mtex[a] && re->wrld.mtex[a]->tex) re->wrld.skytype |= WO_SKYTEX;
+
+ while(re->wrld.aosamp*re->wrld.aosamp < re->osa) re->wrld.aosamp++;
+ }
+ else {
+ memset(&re->wrld, 0, sizeof(World));
+ re->wrld.exp= 0.0;
+ re->wrld.range= 1.0;
+ }
+
+ re->wrld.linfac= 1.0 + pow((2.0*re->wrld.exp + 0.5), -10);
+ re->wrld.logfac= log( (re->wrld.linfac-1.0)/re->wrld.linfac )/re->wrld.range;
+}
+
+/* used to be 'rotate scene' */
+void RE_Database_FromScene(Render *re, Scene *scene, int use_camera_view)
+{
+ extern int slurph_opt; /* key.c */
+ GroupObject *go;
+ Base *base;
+ Object *ob;
+ Scene *sce;
+ unsigned int lay;
+ float mat[4][4];
+
+ re->scene= scene;
+
+ /* XXX add test if dbase was filled already? */
+
+ re->memArena = BLI_memarena_new(BLI_MEMARENA_STD_BUFSIZE);
+ re->totvlak=re->totvert=re->totlamp=re->tothalo= 0;
+ re->lights.first= re->lights.last= NULL;
+
+ slurph_opt= 0;
+
+ /* in localview, lamps are using normal layers, objects only local bits */
+ if(re->scene->lay & 0xFF000000) lay= re->scene->lay & 0xFF000000;
+ else lay= re->scene->lay;
+
+ /* applies changes fully */
+ scene_update_for_newframe(re->scene, lay);
+
+ /* if no camera, viewmat should have been set! */
+ if(use_camera_view && re->scene->camera) {
+ Mat4Ortho(re->scene->camera->obmat);
+ Mat4Invert(mat, re->scene->camera->obmat);
+ RE_SetView(re, mat);
+ }
+
+ init_render_world(re); /* do first, because of ambient. also requires re->osa set correct */
+ if( (re->wrld.mode & WO_AMB_OCC) && (re->r.mode & R_RAYTRACE) ) {
+ re->wrld.aosphere= MEM_mallocN(2*3*re->wrld.aosamp*re->wrld.aosamp*sizeof(float), "AO sphere");
+ /* we make twice the amount of samples, because only a hemisphere is used */
+ init_ao_sphere(re->wrld.aosphere, 2*re->wrld.aosamp*re->wrld.aosamp, 16);
+ }
+
+ /* still bad... doing all */
+ init_render_textures();
+ init_render_materials(re->osa, &re->wrld.ambr);
+ set_node_shader_lamp_loop(shade_material_loop);
+
+ for(SETLOOPER(re->scene, base)) {
+ ob= base->object;
+ /* imat objects has to be done here, since displace can have texture using Object map-input */
+ MTC_Mat4MulMat4(mat, ob->obmat, re->viewmat);
+ MTC_Mat4Invert(ob->imat, mat);
+ /* each object should only be rendered once */
+ ob->flag &= ~OB_DONE;
+ }
+
+ /* MAKE RENDER DATA */
+
+ for(SETLOOPER(re->scene, base)) {
+ ob= base->object;
+
+ if( (base->lay & lay) || (ob->type==OB_LAMP && (base->lay & re->scene->lay)) ) {
+ if(ob->transflag & OB_DUPLI) {
+
+ /* exception: mballs! */
+ /* yafray: Include at least one copy of a dupliframe object for yafray in the renderlist.
+ mballs comment above true as well for yafray, they are not included, only all other object types */
+ if (re->r.renderer==R_YAFRAY) {
+ if ((ob->type!=OB_MBALL) && ((ob->transflag & OB_DUPLIFRAMES)!=0)) {
+ printf("Object %s has OB_DUPLIFRAMES set, adding to renderlist\n", ob->id.name);
+ init_render_object(re, ob);
+ }
+ }
+ /* before make duplis, update particle for current frame */
+ if(ob->transflag & OB_DUPLIVERTS) {
+ PartEff *paf= give_parteff(ob);
+ if(paf) {
+ if(paf->flag & PAF_ANIMATED) build_particle_system(ob);
+ }
+ }
+
+ if(ob->type==OB_MBALL) {
+ init_render_object(re, ob);
+ }
+ else {
+ DupliObject *dob;
+ ListBase *lb= object_duplilist(sce, ob);
+
+ for(dob= lb->first; dob; dob= dob->next) {
+ Object *obd= dob->ob;
+ Mat4CpyMat4(obd->obmat, dob->mat);
+
+ if(obd->type!=OB_MBALL) {
+ /* yafray: special handling of duplivert objects for yafray:
+ only the matrix is stored, together with the source object name.
+ Since the original object is needed as well, it is included in the renderlist (see above)
+ NOT done for lamps, these need to be included as normal lamps separately
+ correction: also ignore lattices, armatures and cameras (....) */
+ if ((obd->type!=OB_LATTICE) && (obd->type!=OB_ARMATURE) &&
+ (obd->type!=OB_LAMP) && (obd->type!=OB_CAMERA) && (re->r.renderer==R_YAFRAY))
+ {
+ printf("Adding dupli matrix for object %s\n", obd->id.name);
+ YAF_addDupliMtx(obd);
+ }
+ else init_render_object(re, obd);
+ }
+ Mat4CpyMat4(obd->obmat, dob->omat);
+ }
+ BLI_freelistN(lb);
+ }
+ }
+ else {
+ /* yafray: if there are linked data objects (except lamps, empties or armatures),
+ yafray only needs to know about one, the rest can be instanciated.
+ The dupliMtx list is used for this purpose.
+ Exception: objects which have object linked materials, these cannot be instanciated. */
+ if ((re->r.renderer==R_YAFRAY) && (ob->colbits==0))
+ {
+ /* Special case, parent object dupli's: ignore if object itself is lamp or parent is lattice or empty */
+ if (ob->parent) {
+ if ((ob->type!=OB_LAMP) && (ob->parent->type!=OB_EMPTY) &&
+ (ob->parent->type!=OB_LATTICE) && YAF_objectKnownData(ob))
+ printf("From parent: Added dupli matrix for linked data object %s\n", ob->id.name);
+ else
+ init_render_object(re, ob);
+ }
+ else if ((ob->type!=OB_EMPTY) && (ob->type!=OB_LAMP) && (ob->type!=OB_ARMATURE) && YAF_objectKnownData(ob))
+ printf("Added dupli matrix for linked data object %s\n", ob->id.name);
+ else
+ init_render_object(re, ob);
+ }
+ else init_render_object(re, ob);
+ }
+
+ }
+
+ if(re->test_break()) break;
+ }
+
+
+ if(!re->test_break()) {
+ sort_halos(re);
+
+ set_material_lightgroups(re);
+
+ slurph_opt= 1;
+
+ /* for now some clumsy copying still */
+ re->i.totvert= re->totvert;
+ re->i.totface= re->totvlak;
+ re->i.tothalo= re->tothalo;
+ re->i.totlamp= re->totlamp;
+ re->stats_draw(&re->i);
+
+ set_fullsample_flag(re);
+ check_non_flat_quads(re);
+ set_normalflags(re);
+
+ /* SHADOW BUFFER */
+ for(go=re->lights.first; go; go= go->next) {
+ LampRen *lar= go->lampren;
+
+ if(re->test_break()) break;
+ if(lar->shb) {
+ makeshadowbuf(re, lar);
+ }
+ }
+
+ /* yafray: 'direct' radiosity, environment maps and octree init not needed for yafray render */
+ /* although radio mode could be useful at some point, later */
+ if (re->r.renderer==R_INTERN) {
+ /* RADIO (uses no R anymore) */
+ if(!re->test_break())
+ if(re->r.mode & R_RADIO) do_radio_render(re);
+
+ /* octree */
+ if(!re->test_break())
+ if(re->r.mode & R_RAYTRACE) makeoctree(re);
+
+ /* ENVIRONMENT MAPS */
+ if(!re->test_break())
+ make_envmaps(re);
+ }
+
+ if(!re->test_break())
+ project_renderdata(re, projectverto, re->r.mode & R_PANORAMA, 0);
+ }
+
+ if(re->test_break())
+ RE_Database_Free(re);
+ else
+ re->i.convertdone= 1;
+
+}
+
+/* exported call to recalculate hoco for vertices, when winmat changed */
+void RE_DataBase_ApplyWindow(Render *re)
+{
+ project_renderdata(re, projectverto, 0, 0);
+}
+
+/* **************************************************************** */
+/* Displacement mapping */
+/* **************************************************************** */
+static short test_for_displace(Render *re, Object *ob)
+{
+ /* return 1 when this object uses displacement textures. */
+ Material *ma;
+ int i;
+
+ for (i=1; i<=ob->totcol; i++) {
+ ma=give_render_material(re, ob, i);
+ /* ma->mapto is ORed total of all mapto channels */
+ if(ma && (ma->mapto & MAP_DISPLACE)) return 1;
+ }
+ return 0;
+}
+
+static void displace_render_vert(Render *re, ShadeInput *shi, VertRen *vr, float *scale)
+{
+ short texco= shi->mat->texco;
+ float sample=0;
+ /* shi->co is current render coord, just make sure at least some vector is here */
+ VECCOPY(shi->co, vr->co);
+ /* vertex normal is used for textures type 'col' and 'var' */
+ VECCOPY(shi->vn, vr->n);
+
+ /* set all rendercoords, 'texco' is an ORed value for all textures needed */
+ if ((texco & TEXCO_ORCO) && (vr->orco)) {
+ VECCOPY(shi->lo, vr->orco);
+ }
+ if (texco & TEXCO_STICKY) {
+ float *sticky= RE_vertren_get_sticky(re, vr, 0);
+ if(sticky) {
+ shi->sticky[0]= sticky[0];
+ shi->sticky[1]= sticky[1];
+ shi->sticky[2]= 0.0f;
+ }
+ }
+ if (texco & TEXCO_GLOB) {
+ VECCOPY(shi->gl, shi->co);
+ MTC_Mat4MulVecfl(re->viewinv, shi->gl);
+ }
+ if (texco & TEXCO_NORM) {
+ VECCOPY(shi->orn, shi->vn);
+ }
+ if(texco & TEXCO_REFL) {
+ /* not (yet?) */
+ }
+
+ shi->displace[0]= shi->displace[1]= shi->displace[2]= 0.0;
+
+ do_material_tex(shi);
+
+ //printf("no=%f, %f, %f\nbefore co=%f, %f, %f\n", vr->n[0], vr->n[1], vr->n[2],
+ //vr->co[0], vr->co[1], vr->co[2]);
+
+ /* 0.5 could become button once? */
+ vr->co[0] += shi->displace[0] * scale[0] ;
+ vr->co[1] += shi->displace[1] * scale[1] ;
+ vr->co[2] += shi->displace[2] * scale[2] ;
+
+ //printf("after co=%f, %f, %f\n", vr->co[0], vr->co[1], vr->co[2]);
+
+ /* we just don't do this vertex again, bad luck for other face using same vertex with
+ different material... */
+ vr->flag |= 1;
+
+ /* Pass sample back so displace_face can decide which way to split the quad */
+ sample = shi->displace[0]*shi->displace[0];
+ sample += shi->displace[1]*shi->displace[1];
+ sample += shi->displace[2]*shi->displace[2];
+
+ vr->accum=sample;
+ /* Should be sqrt(sample), but I'm only looking for "bigger". Save the cycles. */
+ return;
+}
+
+static void displace_render_face(Render *re, VlakRen *vlr, float *scale)
+{
+ ShadeInput shi;
+ // VertRen vr;
+ // float samp1,samp2, samp3, samp4, xn;
+ short hasuv=0;
+ /* set up shadeinput struct for multitex() */
+
+ shi.osatex= 0; /* signal not to use dx[] and dy[] texture AA vectors */
+ shi.vlr= vlr; /* current render face */
+ shi.mat= vlr->mat; /* current input material */
+
+
+ /* UV coords must come from face */
+ hasuv = vlr->tface && (shi.mat->texco & TEXCO_UV);
+ if (hasuv) shi.uv[2]=0.0f;
+ /* I don't think this is used, but seting it just in case */
+
+ /* Displace the verts, flag is set when done */
+ if (! (vlr->v1->flag)){
+ if (hasuv) {
+ shi.uv[0] = 2*vlr->tface->uv[0][0]-1.0f; /* shi.uv and tface->uv are */
+ shi.uv[1]= 2*vlr->tface->uv[0][1]-1.0f; /* scalled differently */
+ }
+ displace_render_vert(re, &shi, vlr->v1, scale);
+ }
+
+ if (! (vlr->v2->flag)) {
+ if (hasuv) {
+ shi.uv[0] = 2*vlr->tface->uv[1][0]-1.0f;
+ shi.uv[1]= 2*vlr->tface->uv[1][1]-1.0f;
+ }
+ displace_render_vert(re, &shi, vlr->v2, scale);
+ }
+
+ if (! (vlr->v3->flag)) {
+ if (hasuv) {
+ shi.uv[0] = 2*vlr->tface->uv[2][0]-1.0f;
+ shi.uv[1]= 2*vlr->tface->uv[2][1]-1.0f;
+ }
+ displace_render_vert(re, &shi, vlr->v3, scale);
+ }
+
+ if (vlr->v4) {
+ if (! (vlr->v4->flag)) {
+ if (hasuv) {
+ shi.uv[0] = 2*vlr->tface->uv[3][0]-1.0f;
+ shi.uv[1]= 2*vlr->tface->uv[3][1]-1.0f;
+ }
+ displace_render_vert(re, &shi, vlr->v4, scale);
+ }
+ /* We want to split the quad along the opposite verts that are */
+ /* closest in displace value. This will help smooth edges. */
+ if ( fabs(vlr->v1->accum - vlr->v3->accum) > fabs(vlr->v2->accum - vlr->v4->accum))
+ vlr->flag |= R_DIVIDE_24;
+ else vlr->flag &= ~R_DIVIDE_24; // E: typo?, was missing '='
+ }
+
+ /* Recalculate the face normal - if flipped before, flip now */
+ if(vlr->v4) {
+ CalcNormFloat4(vlr->v4->co, vlr->v3->co, vlr->v2->co, vlr->v1->co, vlr->n);
+ }
+ else {
+ CalcNormFloat(vlr->v3->co, vlr->v2->co, vlr->v1->co, vlr->n);
+ }
+
+}
+
+
+static void do_displacement(Render *re, Object *ob, int startface, int numface, int startvert, int numvert )
+{
+ VertRen *vr;
+ VlakRen *vlr;
+// float min[3]={1e30, 1e30, 1e30}, max[3]={-1e30, -1e30, -1e30};
+ float scale[3]={1.0f, 1.0f, 1.0f}, temp[3];//, xn
+ int i; //, texflag=0;
+ Object *obt;
+
+ /* Object Size with parenting */
+ obt=ob;
+ while(obt){
+ VecAddf(temp, obt->size, obt->dsize);
+ scale[0]*=temp[0]; scale[1]*=temp[1]; scale[2]*=temp[2];
+ obt=obt->parent;
+ }
+
+ /* Clear all flags */
+ for(i=startvert; i<startvert+numvert; i++){
+ vr= RE_findOrAddVert(re, i);
+ vr->flag= 0;
+ }
+
+ for(i=startface; i<startface+numface; i++){
+ vlr=RE_findOrAddVlak(re, i);
+ displace_render_face(re, vlr, scale);
+ }
+
+ /* Recalc vertex normals */
+ calc_vertexnormals(re, startvert, startface, 0);
+}
+
diff --git a/source/blender/render/intern/source/edgeRender.c b/source/blender/render/intern/source/edgeRender.c
index 7bf3b7f3e09..7d15e3f8145 100644
--- a/source/blender/render/intern/source/edgeRender.c
+++ b/source/blender/render/intern/source/edgeRender.c
@@ -1,15 +1,12 @@
/**
* $Id$
*
- * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
+ * ***** BEGIN GPL 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.
+ * of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
@@ -23,12 +20,12 @@
* The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
* All rights reserved.
*
- * The Original Code is: all of this file.
+ * Contributors: 2004/2005/2006 Blender Foundation, full recode
*
- * Contributor(s): none yet.
- *
- * ***** END GPL/BL DUAL LICENSE BLOCK *****
- * Add enhanced edges on a rendered image (toon shading, edge shading).
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/* Add enhanced edges on a rendered image (toon shading, edge shading).
*/
/*
@@ -58,29 +55,25 @@
#include <limits.h> /* INT_MIN,MAX are used here */
#include <stdio.h>
+#include "DNA_material_types.h"
+
#include "MEM_guardedalloc.h"
#include "MTC_vectorops.h"
#include "BKE_utildefines.h"
+#include "BLI_jitter.h"
-#include "RE_callbacks.h"
+#include "render_types.h"
+#include "renderpipeline.h"
#include "edgeRender.h"
-#include "render.h"
#include "zbuf.h" /* for zbufclipwire and zbufclip */
-#include "jitter.h"
-
-#ifdef RE_EDGERENDERSAFE
-char edgeRender_h[] = EDGERENDER_H;
-char edgeRender_c[] = "$Id$";
-#include "errorHandler.h"
-#endif
-/* ------------------------------------------------------------------------- */
- /* These function pointers are used for z buffer filling. */
-extern float Zmulx, Zmuly; /* Some kind of scale? */
-extern float Zjitx,Zjity; /* The x,y values for jitter offset */
+/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
+/* defined in pipeline.c, is hardcopy of active dynamic allocated Render */
+/* only to be used here in this file, it's for speed */
+extern struct Render R;
+/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
-/* ------------------------------------------------------------------------- */
/* exp: */
static Material** matBuffer; /* buffer with material indices */
@@ -111,64 +104,59 @@ static char edgeB;
/**
* Initialise the edge render buffer memory.
*/
-void initEdgeRenderBuffer(void);
+static void initEdgeRenderBuffer(void);
/**
* Release buffer memory.
*/
-void freeEdgeRenderBuffer(void);
+static void freeEdgeRenderBuffer(void);
/**
* Set all distances in the distance buffer to the maximum distance.
*/
-void resetDistanceBuffer(void);
+static void resetDistanceBuffer(void);
/**
* Insert this distance at these pixel coordinates.
*/
-void insertInEdgeBuffer(int x, int y, int dist);
+static void insertInEdgeBuffer(int x, int y, int dist);
/**
* Renders enhanced edges. Distances from distRect are used to
* determine a correction on colourRect
*/
-void renderEdges(char * colourRect);
+static void renderEdges(char * colourRect);
/**
* Buffer an edge between these two vertices in the e.r. distance buffer.
*/
-static void fillEdgeRenderEdge(int, float *vec1, float *vec2);
+static void fillEdgeRenderEdge(ZSpan *zspan, int, float *vec1, float *vec2);
/**
* Buffer a face between these two vertices in the e.r. distance buffer.
*/
-static void fillEdgeRenderFace(struct ZSpan *zspan, int, float *v1, float *v2, float *v3);
+static void fillEdgeRenderFace(struct ZSpan *zspan, int, float *v1, float *v2, float *v3, float *v4);
/**
* Compose the edge render colour buffer.
*/
-void calcEdgeRenderColBuf(char * tarbuf);
+static void calcEdgeRenderColBuf(char * tarbuf);
/**
* Loop over all objects that need to be edge rendered. This loop determines
* which objects get to be elected for edge rendering.
*/
-int zBufferEdgeRenderObjects(void);
+static int zBufferEdgeRenderObjects(void);
/**
* Add edge pixels to the original image. It blends <bron> over <doel>.
*/
-void addEdgeOver(unsigned char *dst, unsigned char *src);
+static void addEdgeOver(unsigned char *dst, unsigned char *src);
/* ------------------------------------------------------------------------- */
-void addEdges(
- char * targetbuf,
- int iw, int ih,
- int osanr,
- short int intens, short int intens_redux,
- int compat, int mode,
- float r, float g, float b
- )
+/* this is main call! */
+void addEdges(char * targetbuf, int iw, int ih, int osanr,
+ short int intens, short int intens_redux, int compat, int mode, float r, float g, float b)
{
float rf, gf ,bf;
/* render parameters */
@@ -178,6 +166,10 @@ void addEdges(
compatible_mode = compat;
osaCount = osanr;
intensity = intens;
+
+ printf("Unsuported code!\n");
+ return;
+
/* Reduction doesn't exceed intensity. */
same_mat_redux = ((intens_redux < intensity)? intens_redux : intensity);
@@ -197,7 +189,7 @@ void addEdges(
/* ------------------------------------------------------------------------- */
-void initEdgeRenderBuffer()
+static void initEdgeRenderBuffer()
{
char *ptr;
int i;
@@ -230,16 +222,10 @@ void initEdgeRenderBuffer()
}
}
-#ifdef RE_EDGERENDERSAFE
- if (!edgeBuffer || !colBuffer) {
- char *fname = "initEdgeRenderBuffer";
- RE_error(RE_CANNOT_ALLOCATE_MEMORY, fname);
- }
-#endif
} /* end of void initEdgeRenderBuffer(void) */
/* ------------------------------------------------------------------------- */
-void freeEdgeRenderBuffer(void)
+static void freeEdgeRenderBuffer(void)
{
if(edgeBuffer) MEM_freeN(edgeBuffer);
edgeBuffer= NULL;
@@ -251,7 +237,7 @@ void freeEdgeRenderBuffer(void)
/* ------------------------------------------------------------------------- */
-void resetDistanceBuffer(void)
+static void resetDistanceBuffer(void)
{
int i;
for(i = 0; i < bufWidth * bufHeight; i++) edgeBuffer[i] = 0x7FFFFFFF;
@@ -259,17 +245,9 @@ void resetDistanceBuffer(void)
/* ------------------------------------------------------------------------- */
-void insertInEdgeBuffer(int x, int y, int dist)
+static void insertInEdgeBuffer(int x, int y, int dist)
{
int index;
-#ifdef RE_EDGERENDERSAFE
- char *fname = "insertInEdgeBuffer";
- if ((x < 0) || (x > imWidth ) ||
- (y < 0) || (y > (imHeight-1) ) ) {
- RE_error(RE_EDGERENDER_WRITE_OUTSIDE_BUFFER, fname);
- return;
- }
-#endif
/* +1? */
index = (y * bufWidth) + x + maskBorder;
@@ -286,7 +264,7 @@ void insertInEdgeBuffer(int x, int y, int dist)
/* ------------------------------------------------------------------------- */
/* Modelled after rendercore.c/edge_enhance() */
-void renderEdges(char *colourRect)
+static void renderEdges(char *colourRect)
{
/* use zbuffer to define edges, add it to the image */
int val, y, x, col, *rz, *rz1, *rz2, *rz3;
@@ -496,7 +474,7 @@ void renderEdges(char *colourRect)
/* ------------------------------------------------------------------------- */
/* adds src to dst */
-void addEdgeOver(unsigned char *dst, unsigned char *src)
+static void addEdgeOver(unsigned char *dst, unsigned char *src)
{
unsigned char inverse;
unsigned char alpha;
@@ -534,20 +512,15 @@ void addEdgeOver(unsigned char *dst, unsigned char *src)
dst[2] = c;
}
-void calcEdgeRenderColBuf(char* colTargetBuffer)
+static void calcEdgeRenderColBuf(char* colTargetBuffer)
{
-
int keepLooping = 1;
int sample;
/* zbuffer fix: here? */
- Zmulx= ((float) imWidth)/2.0;
- Zmuly= ((float) imHeight)/2.0;
+// Zmulx= ((float) imWidth)/2.0;
+// Zmuly= ((float) imHeight)/2.0;
- /* use these buffer fill functions */
- zbuffunc = fillEdgeRenderFace;
- zbuflinefunc = fillEdgeRenderEdge;
-
/* always buffer the max. extent */
Aminy = 0;
Amaxy = imHeight;
@@ -555,8 +528,8 @@ void calcEdgeRenderColBuf(char* colTargetBuffer)
sample = 0; /* Zsample is used internally ! */
while ( (sample < osaCount) && keepLooping ) {
/* jitter */
- Zjitx= -jit[sample][0];
- Zjity= -jit[sample][1];
+// Zjitx= -R.jit[sample][0];
+// Zjity= -R.jit[sample][1];
/* should reset dis buffer here */
resetDistanceBuffer();
@@ -567,7 +540,7 @@ void calcEdgeRenderColBuf(char* colTargetBuffer)
/* do filtering */
renderEdges(colTargetBuffer);
- if(RE_local_test_break()) keepLooping = 0;
+ if(R.test_break()) keepLooping = 0;
sample++;
}
@@ -589,13 +562,28 @@ void calcEdgeRenderColBuf(char* colTargetBuffer)
/* ------------------------------------------------------------------------- */
/* Clip flags etc. should still be set. When called in the span of 'normal' */
/* rendering, this should be ok. */
-int zBufferEdgeRenderObjects(void)
+static int zBufferEdgeRenderObjects(void)
{
+ ZSpan zspan;
VlakRen *vlr= NULL;
+ Material *ma;
unsigned int zvlnr;
int keepLooping;
int faceCounter; /* counter for face number */
- Material *ma;
+
+ zbuf_alloc_span(&zspan, imWidth, imHeight);
+
+ /* needed for transform from hoco to zbuffer co */
+ zspan.zmulx= ((float)imWidth)/2.0;
+ zspan.zmuly= ((float)imHeight)/2.0;
+ zspan.zofsx= -0.5f;
+ zspan.zofsy= -0.5f;
+
+ /* the buffers ??? */
+
+ /* filling methods */
+ zspan.zbuffunc = fillEdgeRenderFace;
+ zspan.zbuflinefunc = fillEdgeRenderEdge;
keepLooping = 1;
ma = NULL;
@@ -618,19 +606,19 @@ int zBufferEdgeRenderObjects(void)
/* here we cull all transparent faces if mode == 0 */
if (selectmode || !(ma->mode & MA_ZTRA)) {
/* here we can add all kinds of extra selection criteria */
- if(ma->mode & (MA_WIRE)) zbufclipwire(zvlnr, vlr);
+ if(ma->mode & (MA_WIRE)) zbufclipwire(&zspan, zvlnr, vlr);
else {
- zbufclip(NULL, zvlnr, vlr->v1->ho, vlr->v2->ho, vlr->v3->ho,
+ zbufclip(&zspan, zvlnr, vlr->v1->ho, vlr->v2->ho, vlr->v3->ho,
vlr->v1->clip, vlr->v2->clip, vlr->v3->clip);
if(vlr->v4) {
zvlnr+= 0x800000; /* in a sense, the 'adjoint' face */
- zbufclip(NULL, zvlnr, vlr->v1->ho, vlr->v3->ho, vlr->v4->ho,
+ zbufclip(&zspan, zvlnr, vlr->v1->ho, vlr->v3->ho, vlr->v4->ho,
vlr->v1->clip, vlr->v3->clip, vlr->v4->clip);
}
}
}
};
- if(RE_local_test_break()) keepLooping = 0;
+ if(R.test_break()) keepLooping = 0;
faceCounter++;
}
return keepLooping;
@@ -638,7 +626,7 @@ int zBufferEdgeRenderObjects(void)
/* ------------------------------------------------------------------------- */
-static void fillEdgeRenderFace(struct ZSpan *zspan, int zvlnr, float *v1, float *v2, float *v3)
+static void fillEdgeRenderFace(struct ZSpan *zspan, int zvlnr, float *v1, float *v2, float *v3, float *v4)
{
/* Coordinates of the vertices are specified in ZCS */
double z0; /* used as temp var*/
@@ -846,7 +834,7 @@ static void fillEdgeRenderFace(struct ZSpan *zspan, int zvlnr, float *v1, float
/* ------------------------------------------------------------------------- */
-static void fillEdgeRenderEdge(int zvlnr, float *vec1, float *vec2)
+static void fillEdgeRenderEdge(ZSpan *zspan, int zvlnr, float *vec1, float *vec2)
{
int start, end, x, y, oldx, oldy, ofs;
int dz, vergz/* , mask */;
diff --git a/source/blender/render/intern/source/envmap.c b/source/blender/render/intern/source/envmap.c
index 7c962ff1328..d38ff7d2d38 100644
--- a/source/blender/render/intern/source/envmap.c
+++ b/source/blender/render/intern/source/envmap.c
@@ -1,15 +1,12 @@
-
-/* envmap.c RENDER
+/*
+ * $Id$
*
- * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
+ * ***** BEGIN GPL 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.
+ * of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
@@ -23,15 +20,9 @@
* The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
* All rights reserved.
*
- * The Original Code is: all of this file.
+ * Contributors: 2004/2005/2006 Blender Foundation, full recode
*
- * Contributor(s): none yet.
- *
- * ***** END GPL/BL DUAL LICENSE BLOCK *****
- *
- * may 1999
- *
- * $Id$
+ * ***** END GPL LICENSE BLOCK *****
*/
#include <math.h>
@@ -55,8 +46,8 @@
#include "BKE_library.h"
#include "BKE_main.h"
#include "BKE_global.h"
-#include "BKE_world.h" // init_render_world
#include "BKE_image.h" // BKE_write_ibuf
+#include "BKE_texture.h"
#include "MTC_matrixops.h"
@@ -65,81 +56,18 @@
#define main main /* stupid SDL_main redefines main as SDL_main */
/* this module */
-#include "RE_callbacks.h"
-#include "render.h"
+#include "render_types.h"
+#include "renderpipeline.h"
#include "envmap.h"
-#include "mydevice.h"
#include "rendercore.h"
-#include "renderHelp.h"
+#include "renderdatabase.h"
#include "texture.h"
#include "zbuf.h"
+#include "initrender.h"
/* ------------------------------------------------------------------------- */
-EnvMap *RE_add_envmap(void)
-{
- EnvMap *env;
-
- env= MEM_callocN(sizeof(EnvMap), "envmap");
- env->type= ENV_CUBE;
- env->stype= ENV_STATIC;
- env->clipsta= 0.1;
- env->clipend= 100.0;
- env->cuberes= 100;
-
- return env;
-} /* end of EnvMap *RE_add_envmap() */
-
-/* ------------------------------------------------------------------------- */
-
-EnvMap *RE_copy_envmap(EnvMap *env)
-{
- EnvMap *envn;
- int a;
-
- envn= MEM_dupallocN(env);
- envn->ok= 0;
- for(a=0; a<6; a++) envn->cube[a]= 0;
- if(envn->ima) id_us_plus((ID *)envn->ima);
-
- return envn;
-}
-
-/* ------------------------------------------------------------------------- */
-
-void RE_free_envmapdata(EnvMap *env)
-{
- Image *ima;
- unsigned int a, part;
-
- for(part=0; part<6; part++) {
- ima= env->cube[part];
- if(ima) {
- if(ima->ibuf) IMB_freeImBuf(ima->ibuf);
-
- for(a=0; a<BLI_ARRAY_NELEMS(ima->mipmap); a++) {
- if(ima->mipmap[a]) IMB_freeImBuf(ima->mipmap[a]);
- }
- MEM_freeN(ima);
- env->cube[part]= 0;
- }
- }
- env->ok= 0;
-}
-
-/* ------------------------------------------------------------------------- */
-
-void RE_free_envmap(EnvMap *env)
-{
-
- RE_free_envmapdata(env);
- MEM_freeN(env);
-
-}
-
-/* ------------------------------------------------------------------------- */
-
static void envmap_split_ima(EnvMap *env)
{
ImBuf *ibuf;
@@ -147,7 +75,7 @@ static void envmap_split_ima(EnvMap *env)
/* extern rectcpy(); */
int dx, part;
- RE_free_envmapdata(env);
+ BKE_free_envmapdata(env);
dx= env->ima->ibuf->y;
dx/= 2;
@@ -183,52 +111,76 @@ static void envmap_split_ima(EnvMap *env)
/* ------------------------------------------------------------------------- */
/* ****************** RENDER ********************** */
-static void envmap_renderdata(EnvMap *env)
+/* copy current render */
+static Render *envmap_render_copy(Render *re, EnvMap *env)
{
- extern void init_filt_mask(void);
- static RE_Render envR;
- static Object *camera;
+ Render *envre;
int cuberes;
- if(env) {
- envR= R;
- camera= G.scene->camera;
-
- cuberes = (env->cuberes * R.r.size) / 100;
- cuberes &= 0xFFFC;
- env->lastsize= R.r.size;
- R.rectx= R.r.xsch= R.recty= R.r.ysch= cuberes;
- R.afmx= R.afmy= R.r.xsch/2;
- R.xstart= R.ystart= -R.afmx;
- R.xend= R.yend= R.xstart+R.rectx-1;
-
- R.r.mode &= ~(R_BORDER | R_PANORAMA | R_ORTHO | R_MBLUR);
- R.r.filtertype= 0;
- R.r.xparts= R.r.yparts= 1;
- R.r.bufflag= 0;
- R.r.size= 100;
- R.ycor= 1.0;
- R.r.yasp= R.r.xasp= 1;
-
- R.near= env->clipsta;
- R.far= env->clipend;
-
- G.scene->camera= env->object;
-
- }
- else {
- /* this to make sure init_renderdisplay works */
- envR.winx= R.winx;
- envR.winy= R.winy;
- envR.winxof= R.winxof;
- envR.winyof= R.winyof;
-
- R= envR;
- G.scene->camera= camera;
- }
-
- /* gauss, gamma, etc */
- init_filt_mask();
+ envre= RE_NewRender("Envmap");
+
+ env->lastsize= re->r.size;
+ cuberes = (env->cuberes * re->r.size) / 100;
+ cuberes &= 0xFFFC;
+
+ /* set up renderdata */
+ envre->r= re->r;
+ envre->r.mode &= ~(R_BORDER | R_PANORAMA | R_ORTHO | R_MBLUR);
+ envre->r.filtertype= 0;
+ envre->r.xparts= envre->r.yparts= 1;
+ envre->r.bufflag= 0;
+ envre->r.size= 100;
+ envre->r.yasp= envre->r.xasp= 1;
+
+ RE_InitState(envre, &re->r, cuberes, cuberes, NULL);
+ envre->scene= re->scene; /* unsure about this... */
+
+ /* view stuff in env render */
+ envre->ycor= 1.0;
+ envre->clipsta= env->clipsta; /* render_scene_set_window() respects this for now */
+ envre->clipend= env->clipend;
+
+ RE_SetCamera(envre, env->object);
+
+ /* callbacks */
+ envre->display_draw= re->display_draw;
+ envre->test_break= re->test_break;
+
+ /* and for the evil stuff; copy the database... */
+ envre->totvlak= re->totvlak;
+ envre->totvert= re->totvert;
+ envre->tothalo= re->tothalo;
+ envre->totlamp= re->totlamp;
+ envre->lights= re->lights;
+ envre->vertnodeslen= re->vertnodeslen;
+ envre->vertnodes= re->vertnodes;
+ envre->blohalen= re->blohalen;
+ envre->bloha= re->bloha;
+ envre->blovllen= re->blovllen;
+ envre->blovl= re->blovl;
+ envre->oc= re->oc;
+
+ return envre;
+}
+
+static void envmap_free_render_copy(Render *envre)
+{
+
+ envre->totvlak= 0;
+ envre->totvert= 0;
+ envre->tothalo= 0;
+ envre->totlamp= 0;
+ envre->lights.first= envre->lights.last= NULL;
+ envre->vertnodeslen= 0;
+ envre->vertnodes= NULL;
+ envre->blohalen= 0;
+ envre->bloha= NULL;
+ envre->blovllen= 0;
+ envre->blovl= NULL;
+ envre->oc.adrbranch= NULL;
+ envre->oc.adrnode= NULL;
+
+ RE_FreeRender(envre);
}
/* ------------------------------------------------------------------------- */
@@ -265,7 +217,7 @@ static void envmap_transmatrix(float mat[][4], int part)
/* ------------------------------------------------------------------------- */
-static void env_rotate_scene(float mat[][4], int mode)
+static void env_rotate_scene(Render *re, float mat[][4], int mode)
{
GroupObject *go;
VlakRen *vlr = NULL;
@@ -284,8 +236,8 @@ static void env_rotate_scene(float mat[][4], int mode)
MTC_Mat3CpyMat4(imat, mat);
}
- for(a=0; a<R.totvert; a++) {
- if((a & 255)==0) ver= RE_findOrAddVert(a);
+ for(a=0; a<re->totvert; a++) {
+ if((a & 255)==0) ver= RE_findOrAddVert(re, a);
else ver++;
MTC_Mat4MulVecfl(tmat, ver->co);
@@ -300,15 +252,15 @@ static void env_rotate_scene(float mat[][4], int mode)
Normalise(ver->n);
}
- for(a=0; a<R.tothalo; a++) {
- if((a & 255)==0) har= R.bloha[a>>8];
+ for(a=0; a<re->tothalo; a++) {
+ if((a & 255)==0) har= re->bloha[a>>8];
else har++;
MTC_Mat4MulVecfl(tmat, har->co);
}
- for(a=0; a<R.totvlak; a++) {
- if((a & 255)==0) vlr= R.blovl[a>>8];
+ for(a=0; a<re->totvlak; a++) {
+ if((a & 255)==0) vlr= re->blovl[a>>8];
else vlr++;
xn= vlr->n[0];
@@ -321,9 +273,9 @@ static void env_rotate_scene(float mat[][4], int mode)
Normalise(vlr->n);
}
- set_normalflags();
+ set_normalflags(re);
- for(go=R.lights.first; go; go= go->next) {
+ for(go=re->lights.first; go; go= go->next) {
lar= go->lampren;
/* removed here some horrible code of someone in NaN who tried to fix
@@ -355,25 +307,25 @@ static void env_rotate_scene(float mat[][4], int mode)
/* ------------------------------------------------------------------------- */
-static void env_layerflags(unsigned int notlay)
+static void env_layerflags(Render *re, unsigned int notlay)
{
VlakRen *vlr = NULL;
int a;
- for(a=0; a<R.totvlak; a++) {
- if((a & 255)==0) vlr= R.blovl[a>>8];
+ for(a=0; a<re->totvlak; a++) {
+ if((a & 255)==0) vlr= re->blovl[a>>8];
else vlr++;
if(vlr->lay & notlay) vlr->flag &= ~R_VISIBLE;
}
}
-static void env_hideobject(Object *ob)
+static void env_hideobject(Render *re, Object *ob)
{
VlakRen *vlr = NULL;
int a;
- for(a=0; a<R.totvlak; a++) {
- if((a & 255)==0) vlr= R.blovl[a>>8];
+ for(a=0; a<re->totvlak; a++) {
+ if((a & 255)==0) vlr= re->blovl[a>>8];
else vlr++;
if(vlr->ob == ob) vlr->flag &= ~R_VISIBLE;
}
@@ -381,14 +333,14 @@ static void env_hideobject(Object *ob)
/* ------------------------------------------------------------------------- */
-static void env_set_imats()
+static void env_set_imats(Render *re)
{
Base *base;
float mat[4][4];
base= G.scene->base.first;
while(base) {
- MTC_Mat4MulMat4(mat, base->object->obmat, R.viewmat);
+ MTC_Mat4MulMat4(mat, base->object->obmat, re->viewmat);
MTC_Mat4Invert(base->object->imat, mat);
base= base->next;
@@ -398,118 +350,97 @@ static void env_set_imats()
/* ------------------------------------------------------------------------- */
-static void render_envmap(EnvMap *env)
+static void render_envmap(Render *re, EnvMap *env)
{
/* only the cubemap is implemented */
+ Render *envre;
ImBuf *ibuf;
Image *ima;
float oldviewinv[4][4], mat[4][4], tmat[4][4];
short part;
/* need a recalc: ortho-render has no correct viewinv */
- MTC_Mat4Invert(oldviewinv, R.viewmat);
+ MTC_Mat4Invert(oldviewinv, re->viewmat);
- /* do first, envmap_renderdata copies entire R struct */
- if(R.rectz) MEM_freeN(R.rectz);
- if(R.rectot) MEM_freeN(R.rectot);
- if(R.rectftot) MEM_freeN(R.rectftot);
- R.rectftot= NULL;
- R.rectz= NULL;
- R.rectot= NULL;
-
- /* setup necessary globals */
- envmap_renderdata(env);
+ envre= envmap_render_copy(re, env);
- RE_local_init_render_display();
-
- R.rectot= MEM_mallocN(sizeof(int)*R.rectx*R.recty, "rectot");
- R.rectz= MEM_mallocN(sizeof(int)*R.rectx*R.recty, "rectz");
+// re->display_init(envre->result);
for(part=0; part<6; part++) {
- RE_local_clear_render_display(R.win);
- fillrect(R.rectot, R.rectx, R.recty, 0);
-
- RE_setwindowclip(1,-1); /* no jit:(-1) */
+ re->display_clear(envre->result);
- MTC_Mat4CpyMat4(tmat, G.scene->camera->obmat);
+ MTC_Mat4CpyMat4(tmat, env->object->obmat);
MTC_Mat4Ortho(tmat);
envmap_transmatrix(tmat, part);
MTC_Mat4Invert(mat, tmat);
/* mat now is the camera 'viewmat' */
- MTC_Mat4CpyMat4(R.viewmat, mat);
- MTC_Mat4CpyMat4(R.viewinv, tmat);
+ MTC_Mat4CpyMat4(envre->viewmat, mat);
+ MTC_Mat4CpyMat4(envre->viewinv, tmat);
/* we have to correct for the already rotated vertexcoords */
- MTC_Mat4MulMat4(tmat, oldviewinv, R.viewmat);
+ MTC_Mat4MulMat4(tmat, oldviewinv, envre->viewmat);
MTC_Mat4Invert(env->imat, tmat);
- env_rotate_scene(tmat, 1);
- init_render_world();
- setzbufvlaggen(RE_projectverto);
- env_layerflags(env->notlay);
- env_hideobject(env->object);
- env_set_imats();
+ env_rotate_scene(envre, tmat, 1);
+ init_render_world(envre);
+ project_renderdata(envre, projectverto, 0, 0);
+ env_layerflags(envre, env->notlay);
+ env_hideobject(envre, env->object);
+ env_set_imats(envre);
- if(RE_local_test_break()==0) {
-
- RE_local_printrenderinfo(0.0, part);
-
- if(R.r.mode & R_OSA) zbufshadeDA();
- else zbufshade();
-
+ if(re->test_break()==0) {
+ RE_TileProcessor(envre);
}
/* rotate back */
- env_rotate_scene(tmat, 0);
+ env_rotate_scene(envre, tmat, 0);
- if(RE_local_test_break()==0) {
- ibuf= IMB_allocImBuf(R.rectx, R.recty, 24, IB_rect, 0);
+ if(re->test_break()==0) {
+ RenderLayer *rl= envre->result->layers.first;
+
+ ibuf= IMB_allocImBuf(envre->rectx, envre->recty, 24, IB_rect, 0);
+ ibuf->rect_float= rl->rectf;
+ IMB_rect_from_float(ibuf);
+ ibuf->rect_float= NULL;
+
ima= MEM_callocN(sizeof(Image), "image");
- memcpy(ibuf->rect, R.rectot, 4*ibuf->x*ibuf->y);
+
ima->ibuf= ibuf;
ima->ok= 1;
env->cube[part]= ima;
}
- if(RE_local_test_break()) break;
+ if(re->test_break()) break;
}
- if(R.rectz) MEM_freeN(R.rectz);
- if(R.rectot) MEM_freeN(R.rectot);
- if(R.rectftot) MEM_freeN(R.rectftot);
- R.rectz= NULL;
- R.rectot= NULL;
- R.rectftot= NULL;
-
- if(RE_local_test_break()) RE_free_envmapdata(env);
+ if(re->test_break()) BKE_free_envmapdata(env);
else {
- if(R.r.mode & R_OSA) env->ok= ENV_OSA;
+ if(envre->r.mode & R_OSA) env->ok= ENV_OSA;
else env->ok= ENV_NORMAL;
- env->lastframe= G.scene->r.cfra;
+ env->lastframe= G.scene->r.cfra; /* hurmf */
}
/* restore */
- envmap_renderdata(0);
- env_set_imats();
- init_render_world();
+ envmap_free_render_copy(envre);
+ env_set_imats(re);
}
/* ------------------------------------------------------------------------- */
-void make_envmaps()
+void make_envmaps(Render *re)
{
Tex *tex;
int do_init= 0, depth= 0, trace;
- if (!(R.r.mode & R_ENVMAP)) return;
+ if (!(re->r.mode & R_ENVMAP)) return;
/* we dont raytrace, disabling the flag will cause ray_transp render solid */
- trace= (R.r.mode & R_RAYTRACE);
- R.r.mode &= ~R_RAYTRACE;
+ trace= (re->r.mode & R_RAYTRACE);
+ re->r.mode &= ~R_RAYTRACE;
/* 5 = hardcoded max recursion level */
while(depth<5) {
@@ -527,21 +458,21 @@ void make_envmaps()
if(tex->env->ok) {
/* free when OSA, and old one isn't OSA */
- if((R.r.mode & R_OSA) && tex->env->ok==ENV_NORMAL)
- RE_free_envmapdata(tex->env);
+ if((re->r.mode & R_OSA) && tex->env->ok==ENV_NORMAL)
+ BKE_free_envmapdata(tex->env);
/* free when size larger */
- else if(tex->env->lastsize < R.r.size)
- RE_free_envmapdata(tex->env);
+ else if(tex->env->lastsize < re->r.size)
+ BKE_free_envmapdata(tex->env);
/* free when env is in recalcmode */
else if(tex->env->recalc)
- RE_free_envmapdata(tex->env);
+ BKE_free_envmapdata(tex->env);
}
if(tex->env->ok==0 && depth==0) tex->env->recalc= 1;
if(tex->env->ok==0) {
do_init= 1;
- render_envmap(tex->env);
+ render_envmap(re, tex->env);
if(depth==tex->env->depth) tex->env->recalc= 0;
}
@@ -556,12 +487,12 @@ void make_envmaps()
}
if(do_init) {
- RE_local_init_render_display();
- RE_local_clear_render_display(R.win);
- R.flag |= R_REDRAW_PRV;
+ re->display_init(re->result);
+ re->display_clear(re->result);
+ re->flag |= R_REDRAW_PRV;
}
// restore
- R.r.mode |= trace;
+ re->r.mode |= trace;
}
@@ -643,6 +574,7 @@ static void set_dxtdyt(float *dxts, float *dyts, float *dxt, float *dyt, int fac
int envmaptex(Tex *tex, float *texvec, float *dxt, float *dyt, int osatex, TexResult *texres)
{
extern SDL_mutex *load_ibuf_lock; // initrender.c
+ extern Render R; /* only in this call */
/* texvec should be the already reflected normal */
EnvMap *env;
Image *ima;
diff --git a/source/blender/render/intern/source/errorHandler.c b/source/blender/render/intern/source/errorHandler.c
deleted file mode 100644
index 0ab927a9cd9..00000000000
--- a/source/blender/render/intern/source/errorHandler.c
+++ /dev/null
@@ -1,102 +0,0 @@
-/**
- * $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.
- *
- * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
- * All rights reserved.
- *
- * The Original Code is: all of this file.
- *
- * Contributor(s): none yet.
- *
- * ***** END GPL/BL DUAL LICENSE BLOCK *****
- * Error handler for the rendering code. Maybe also useful elsewhere?
- */
-
-#include "GEN_messaging.h"
-#include "stdio.h"
-
-#include "errorHandler.h"
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-/* ------------------------------------------------------------------------- */
-
-/* counters for error handling */
-static int lastError; /* code of last encountered error */
-static int errorCount; /* count how many time it occured */
-/* ------------------------------------------------------------------------- */
-
-char errorStrings[RE_MAX_ERROR][100] = {
- "0: No error",
- "1: recalculated depth falls outside original range",
- "2: invalid face/halo type",
- "3: invalid face index",
- "4: invalid data pointer",
- "5: generic trace counter",
- "6: overflow on z buffer depth",
- "7: write outside edgerender buffer",
- "8: cannot allocate memory",
- "9: write outside colour target buffer",
-};
-
-/* ------------------------------------------------------------------------- */
-
-void RE_errortrace_reset(void)
-{
- lastError = RE_NO_ERROR;
- errorCount = 0;
-}
-
-void RE_error(int errType, char* fname)
-{
- /*
- * This memory behaviour should move to the generic stream...
- */
-
- if (lastError == errType) {
- int teller;
- errorCount++;
- for (teller = 0; teller < 12; teller++)
- fprintf(GEN_errorstream, "%c", 0x08); /* backspaces */
- fprintf(GEN_errorstream, "( %8u )", errorCount);
- } else {
- fprintf(GEN_errorstream, "\n*** %s: %s ",
- fname, errorStrings[errType]);
- lastError = errType;
- errorCount = 1;
- }
-} /* end of void RE_error(int errType, char* errText) */
-
-/* ------------------------------------------------------------------------- */
-/* note: non-repeating */
-void RE_error_int(int errType, char* fname, int value)
-{
- fprintf(GEN_errorstream, "\n*** %s: %s : %d",
- fname, errorStrings[errType], value);
- lastError = RE_NO_ERROR;
-} /* end of void RE_error_int(int errType, char* errText, int value) */
-
-/* ------------------------------------------------------------------------- */
-
-/* eof */
diff --git a/source/blender/render/intern/source/gammaCorrectionTables.c b/source/blender/render/intern/source/gammaCorrectionTables.c
index 9273aa899ee..812feabede7 100644
--- a/source/blender/render/intern/source/gammaCorrectionTables.c
+++ b/source/blender/render/intern/source/gammaCorrectionTables.c
@@ -43,10 +43,9 @@
/* WARNING; optimized, cannot be used to do gamma(invgamma()) and expect */
/* result remain identical (ton) */
-/* Default gamma. For most CRTs, gamma ranges from 2.2 to 2.5 (Foley), so */
-/* 2.35 seems appropriate enough. Experience teaches a different number */
-/* though. Old blender: 2.0. It might be nice to make this a slider */
+/* gamma is only used here for correcting adding colors or alpha */
#define RE_DEFAULT_GAMMA 2.0
+
/* This 400 is sort of based on the number of intensity levels needed for */
/* the typical dynamic range of a medium, in this case CRTs. (Foley) */
/* (Actually, it says the number should be between 400 and 535.) */
@@ -63,8 +62,7 @@ static float colour_step;
static float inv_colour_step;
static float valid_gamma;
static float valid_inv_gamma;
-static int gamma_table_initialised = 0;
-int do_gamma=0;
+
/* ------------------------------------------------------------------------- */
float gammaCorrect(float c)
@@ -141,15 +139,9 @@ void makeGammaTables(float gamma)
* (inv_gamma_range_table[i + 1] - inv_gamma_range_table[i]) ;
}
- gamma_table_initialised = 1;
} /* end of void makeGammaTables(float gamma) */
-/* ------------------------------------------------------------------------- */
-int gammaTableIsInitialised(void)
-{
- return gamma_table_initialised;
-}
/* ------------------------------------------------------------------------- */
diff --git a/source/blender/render/intern/source/imagetexture.c b/source/blender/render/intern/source/imagetexture.c
index 479bf7190f7..6a59250b448 100644
--- a/source/blender/render/intern/source/imagetexture.c
+++ b/source/blender/render/intern/source/imagetexture.c
@@ -2,15 +2,12 @@
*
* $Id:
*
- * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
+ * ***** BEGIN GPL 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.
+ * of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
@@ -24,9 +21,7 @@
* The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
* All rights reserved.
*
- * The Original Code is: all of this file.
- *
- * Contributor(s): none yet.
+ * Contributors: 2004/2005/2006 Blender Foundation, full recode
*
* ***** END GPL/BL DUAL LICENSE BLOCK *****
*/
@@ -63,9 +58,15 @@
#include "SDL_thread.h"
-#include "render.h"
+#include "renderpipeline.h"
+#include "render_types.h"
#include "texture.h"
+/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
+/* defined in pipeline.c, is hardcopy of active dynamic allocated Render */
+/* only to be used here in this file, it's for speed */
+extern struct Render R;
+/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
int imaprepeat, imapextend;
diff --git a/source/blender/render/intern/source/initrender.c b/source/blender/render/intern/source/initrender.c
index baa908cc9b2..c37b30a9bcb 100644
--- a/source/blender/render/intern/source/initrender.c
+++ b/source/blender/render/intern/source/initrender.c
@@ -1,15 +1,12 @@
/**
* $Id$
*
- * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
+ * ***** BEGIN GPL 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.
+ * of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
@@ -23,11 +20,9 @@
* The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
* All rights reserved.
*
- * The Original Code is: all of this file.
+ * Contributors: 2004/2005/2006 Blender Foundation, full recode
*
- * Contributor(s): none yet.
- *
- * ***** END GPL/BL DUAL LICENSE BLOCK *****
+ * ***** END GPL LICENSE BLOCK *****
*/
@@ -38,22 +33,23 @@
#include <string.h>
#include <stdio.h>
-#include "blendef.h"
#include "MEM_guardedalloc.h"
#include "PIL_time.h"
#include "BLI_arithb.h"
#include "BLI_blenlib.h"
+#include "BLI_jitter.h"
#include "BLI_rand.h"
#include "MTC_matrixops.h"
-#include "DNA_image_types.h"
#include "DNA_camera_types.h"
+#include "DNA_group_types.h"
+#include "DNA_image_types.h"
#include "DNA_lamp_types.h"
-#include "DNA_scene_types.h"
#include "DNA_object_types.h"
+#include "DNA_scene_types.h"
#include "BKE_utildefines.h"
#include "BKE_global.h"
@@ -66,13 +62,6 @@
#include "BKE_writeavi.h"
#include "BKE_scene.h"
-#include "BIF_toolbox.h"
-#include "BIF_writeavicodec.h"
-#include "BIF_writemovie.h" /* start_movie(), append_movie(), end_movie() */
-
-#include "BSE_drawview.h"
-#include "BSE_sequence.h"
-
#include "IMB_imbuf_types.h"
#include "IMB_imbuf.h"
@@ -83,34 +72,33 @@
#include "SDL_thread.h"
/* this module */
-#include "render.h"
+#include "renderpipeline.h"
+#include "render_types.h"
-#include "RE_callbacks.h"
-#include "zbuf.h"
-#include "rendercore.h" /* part handler for the old renderer, shading functions */
+#include "rendercore.h"
#include "pixelshading.h"
-#include "renderPreAndPost.h"
-#include "vanillaRenderPipe.h"
-#include "renderHelp.h"
-#include "jitter.h"
#include "gammaCorrectionTables.h"
-#include "zblur.h"
+#include "zbuf.h"
/* Own includes */
#include "initrender.h"
-/* yafray: include for yafray export/render */
-#include "YafRay_Api.h"
-
-float centLut[16], *fmask1[9], *fmask2[9];
-unsigned short *gamtab, *igamtab2, *igamtab1;
-char cmask[256], *centmask;
+/* ********************** */
-Material defmaterial;
-
-/* ------- prototypes ----------- */
-void init_filt_mask(void);
+static void init_render_jit(Render *re)
+{
+ static float jit[32][2]; /* simple caching */
+ static int lastjit= 0;
+
+ if(lastjit!=re->osa) {
+ memset(jit, 0, sizeof(jit));
+ BLI_initjit(jit[0], re->osa);
+ }
+
+ lastjit= re->osa;
+ memcpy(re->jit, jit, sizeof(jit));
+}
/* ****************** GAMMA, MASKS and LUTS **************** */
@@ -165,48 +153,48 @@ static float filt_mitchell(float x) /* Mitchell & Netravali's two-param cubic */
return 0.0;
}
-static float calc_weight(float *weight, int i, int j)
+static float calc_weight(Render *re, float *weight, int i, int j)
{
float x, y, dist, totw= 0.0;
int a;
- for(a=0; a<R.osa; a++) {
- x= jit[a][0] + i;
- y= jit[a][1] + j;
+ for(a=0; a<re->osa; a++) {
+ x= re->jit[a][0] + i;
+ y= re->jit[a][1] + j;
dist= sqrt(x*x+y*y);
weight[a]= 0.0;
/* Weighting choices */
- switch(R.r.filtertype) {
+ switch(re->r.filtertype) {
case R_FILTER_BOX:
if(i==0 && j==0) weight[a]= 1.0;
break;
case R_FILTER_TENT:
- if(dist < R.r.gauss)
- weight[a]= R.r.gauss - dist;
+ if(dist < re->r.gauss)
+ weight[a]= re->r.gauss - dist;
break;
case R_FILTER_GAUSS:
- x = dist*R.r.gauss;
- weight[a]= (1.0/exp(x*x) - 1.0/exp(R.r.gauss*R.r.gauss*2.25));
+ x = dist*re->r.gauss;
+ weight[a]= (1.0/exp(x*x) - 1.0/exp(re->r.gauss*re->r.gauss*2.25));
break;
case R_FILTER_MITCH:
- weight[a]= filt_mitchell(dist*R.r.gauss);
+ weight[a]= filt_mitchell(dist*re->r.gauss);
break;
case R_FILTER_QUAD:
- weight[a]= filt_quadratic(dist*R.r.gauss);
+ weight[a]= filt_quadratic(dist*re->r.gauss);
break;
case R_FILTER_CUBIC:
- weight[a]= filt_cubic(dist*R.r.gauss);
+ weight[a]= filt_cubic(dist*re->r.gauss);
break;
case R_FILTER_CATROM:
- weight[a]= filt_catrom(dist*R.r.gauss);
+ weight[a]= filt_catrom(dist*re->r.gauss);
break;
}
@@ -217,1416 +205,440 @@ static float calc_weight(float *weight, int i, int j)
return totw;
}
-// extern called in render_envmap, to disable gauss...
-// extern called in sequence.c, it needs the gamtab
-void init_filt_mask(void)
+void free_sample_tables(Render *re)
{
- static int firsttime=1;
- static int lastosa=0;
- static int lastfilter= -1;
- static float lastgamma= 0.0f, lastgaussdist=0.0f;
- float gamma, igamma, flweight[32], fmask[256];
+ int a;
+
+ if(re->samples) {
+ for(a=0; a<9; a++) {
+ MEM_freeN(re->samples->fmask1[a]);
+ MEM_freeN(re->samples->fmask2[a]);
+ }
+
+ MEM_freeN(re->samples->centmask);
+ MEM_freeN(re->samples);
+ re->samples= NULL;
+ }
+}
+
+/* based on settings in render, it makes the lookup tables */
+void make_sample_tables(Render *re)
+{
+ static int firsttime= 1;
+ SampleTables *st;
+ float flweight[32], fmask[256];
float weight[32], totw, val, *fpx1, *fpx2, *fpy1, *fpy2, *m3, *m4;
int i, j, a;
+ /* optimization tables, only once */
if(firsttime) {
+ makeGammaTables(2.0); /* tables only used for adding colors */
firsttime= 0;
-
- for(a=0; a<9;a++) {
- fmask1[a]= MEM_mallocN(256*sizeof(float), "initfilt");
- fmask2[a]= MEM_mallocN(256*sizeof(float), "initfilt");
- }
- for(a=0; a<256; a++) {
- cmask[a]= 0;
- if(a & 1) cmask[a]++;
- if(a & 2) cmask[a]++;
- if(a & 4) cmask[a]++;
- if(a & 8) cmask[a]++;
- if(a & 16) cmask[a]++;
- if(a & 32) cmask[a]++;
- if(a & 64) cmask[a]++;
- if(a & 128) cmask[a]++;
- }
- centmask= MEM_mallocN(65536, "Initfilt3");
- for(a=0; a<16; a++) {
- centLut[a]= -0.45+((float)a)/16.0;
- }
-
- gamtab= MEM_mallocN(65536*sizeof(short), "initGaus2");
- igamtab1= MEM_mallocN(256*sizeof(short), "initGaus2");
- igamtab2= MEM_mallocN(65536*sizeof(short), "initGaus2");
-
- return; // this case is called on startup
}
-
- if(R.r.alphamode==R_ALPHAKEY) gamma= 1.0; /* gamma correction of alpha is nasty */
- else if(R.r.mode & R_GAMMA) gamma= 2.0;
- else gamma= 1.0;
- igamma= 1.0/gamma;
-
- if(gamma!= lastgamma) {
- lastgamma= gamma;
-
- /* gamtab: in short, out short */
- for(a=0; a<65536; a++) {
- val= a;
- val/= 65535.0;
-
- if(gamma==2.0) val= sqrt(val);
- else if(gamma!=1.0) val= pow(val, igamma);
+ free_sample_tables(re);
+
+ if(re->osa==0) {
+ /* just prevents cpu cycles for larger render and copying */
+ re->r.filtertype= 0;
+ return;
+ }
+
+ re->do_gamma= 0;
+ if(re->r.mode & R_GAMMA) {
+ if(re->r.alphamode!=R_ALPHAKEY) /* alpha corrected gamma doesnt work for key alpha */
+ re->do_gamma= 1;
+ }
+
+ init_render_jit(re);
- gamtab[a]= (65535.99*val);
- }
- /* inverse gamtab1 : in byte, out short */
- for(a=1; a<=256; a++) {
- if(gamma==2.0) igamtab1[a-1]= a*a-1;
- else if(gamma==1.0) igamtab1[a-1]= 256*a-1;
- else {
- val= a/256.0;
- igamtab1[a-1]= (65535.0*pow(val, gamma)) -1 ;
- }
- }
+ st= re->samples= MEM_callocN(sizeof(SampleTables), "sample tables");
+
+ for(a=0; a<9;a++) {
+ st->fmask1[a]= MEM_callocN(256*sizeof(float), "initfilt");
+ st->fmask2[a]= MEM_callocN(256*sizeof(float), "initfilt");
+ }
+ for(a=0; a<256; a++) {
+ st->cmask[a]= 0;
+ if(a & 1) st->cmask[a]++;
+ if(a & 2) st->cmask[a]++;
+ if(a & 4) st->cmask[a]++;
+ if(a & 8) st->cmask[a]++;
+ if(a & 16) st->cmask[a]++;
+ if(a & 32) st->cmask[a]++;
+ if(a & 64) st->cmask[a]++;
+ if(a & 128) st->cmask[a]++;
+ }
+
+ st->centmask= MEM_mallocN((1<<re->osa), "Initfilt3");
+
+ for(a=0; a<16; a++) {
+ st->centLut[a]= -0.45+((float)a)/16.0;
+ }
- /* inverse gamtab2 : in short, out short */
- for(a=0; a<65536; a++) {
- val= a;
- val/= 65535.0;
- if(gamma==2.0) val= val*val;
- else val= pow(val, gamma);
+ val= 1.0/((float)re->osa);
+ for(a=0; a<256; a++) {
+ fmask[a]= ((float)st->cmask[a])*val;
+ }
- igamtab2[a]= 65535.0*val;
+ /* calculate totw */
+ totw= 0.0;
+ for(j= -1; j<2; j++) {
+ for(i= -1; i<2; i++) {
+ totw+= calc_weight(re, weight, i, j);
}
}
- if(R.osa && (lastosa!=R.osa || lastfilter != (R.r.filtertype) || lastgaussdist!=R.r.gauss)) {
- lastosa= R.osa;
- lastfilter= R.r.filtertype;
- lastgaussdist= R.r.gauss;
-
- val= 1.0/((float)R.osa);
- for(a=0; a<256; a++) {
- fmask[a]= ((float)cmask[a])*val;
- }
+ for(j= -1; j<2; j++) {
+ for(i= -1; i<2; i++) {
+ /* calculate using jit, with offset the weights */
- for(a=0; a<9;a++) {
- memset(fmask1[a], 0, 256*sizeof(float));
- memset(fmask2[a], 0, 256*sizeof(float));
- }
+ memset(weight, 0, sizeof(weight));
+ calc_weight(re, weight, i, j);
- /* calculate totw */
- totw= 0.0;
- for(j= -1; j<2; j++) {
- for(i= -1; i<2; i++) {
- totw+= calc_weight(weight, i, j);
- }
- }
+ for(a=0; a<16; a++) flweight[a]= weight[a]*(1.0/totw);
- for(j= -1; j<2; j++) {
- for(i= -1; i<2; i++) {
- /* calculate using jit, with offset the weights */
-
- memset(weight, 0, sizeof(weight));
- calc_weight(weight, i, j);
-
- for(a=0; a<16; a++) flweight[a]= weight[a]*(1.0/totw);
-
- m3= fmask1[ 3*(j+1)+i+1 ];
- m4= fmask2[ 3*(j+1)+i+1 ];
-
- for(a=0; a<256; a++) {
- if(a & 1) {
- m3[a]+= flweight[0];
- m4[a]+= flweight[8];
- }
- if(a & 2) {
- m3[a]+= flweight[1];
- m4[a]+= flweight[9];
- }
- if(a & 4) {
- m3[a]+= flweight[2];
- m4[a]+= flweight[10];
- }
- if(a & 8) {
- m3[a]+= flweight[3];
- m4[a]+= flweight[11];
- }
- if(a & 16) {
- m3[a]+= flweight[4];
- m4[a]+= flweight[12];
- }
- if(a & 32) {
- m3[a]+= flweight[5];
- m4[a]+= flweight[13];
- }
- if(a & 64) {
- m3[a]+= flweight[6];
- m4[a]+= flweight[14];
- }
- if(a & 128) {
- m3[a]+= flweight[7];
- m4[a]+= flweight[15];
- }
- }
- }
- }
+ m3= st->fmask1[ 3*(j+1)+i+1 ];
+ m4= st->fmask2[ 3*(j+1)+i+1 ];
- /* centmask: the correct subpixel offset per mask */
-
- fpx1= MEM_mallocN(256*sizeof(float), "initgauss4");
- fpx2= MEM_mallocN(256*sizeof(float), "initgauss4");
- fpy1= MEM_mallocN(256*sizeof(float), "initgauss4");
- fpy2= MEM_mallocN(256*sizeof(float), "initgauss4");
- for(a=0; a<256; a++) {
- fpx1[a]= fpx2[a]= 0.0;
- fpy1[a]= fpy2[a]= 0.0;
- if(a & 1) {
- fpx1[a]+= jit[0][0];
- fpy1[a]+= jit[0][1];
- fpx2[a]+= jit[8][0];
- fpy2[a]+= jit[8][1];
- }
- if(a & 2) {
- fpx1[a]+= jit[1][0];
- fpy1[a]+= jit[1][1];
- fpx2[a]+= jit[9][0];
- fpy2[a]+= jit[9][1];
- }
- if(a & 4) {
- fpx1[a]+= jit[2][0];
- fpy1[a]+= jit[2][1];
- fpx2[a]+= jit[10][0];
- fpy2[a]+= jit[10][1];
- }
- if(a & 8) {
- fpx1[a]+= jit[3][0];
- fpy1[a]+= jit[3][1];
- fpx2[a]+= jit[11][0];
- fpy2[a]+= jit[11][1];
- }
- if(a & 16) {
- fpx1[a]+= jit[4][0];
- fpy1[a]+= jit[4][1];
- fpx2[a]+= jit[12][0];
- fpy2[a]+= jit[12][1];
- }
- if(a & 32) {
- fpx1[a]+= jit[5][0];
- fpy1[a]+= jit[5][1];
- fpx2[a]+= jit[13][0];
- fpy2[a]+= jit[13][1];
- }
- if(a & 64) {
- fpx1[a]+= jit[6][0];
- fpy1[a]+= jit[6][1];
- fpx2[a]+= jit[14][0];
- fpy2[a]+= jit[14][1];
- }
- if(a & 128) {
- fpx1[a]+= jit[7][0];
- fpy1[a]+= jit[7][1];
- fpx2[a]+= jit[15][0];
- fpy2[a]+= jit[15][1];
+ for(a=0; a<256; a++) {
+ if(a & 1) {
+ m3[a]+= flweight[0];
+ m4[a]+= flweight[8];
+ }
+ if(a & 2) {
+ m3[a]+= flweight[1];
+ m4[a]+= flweight[9];
+ }
+ if(a & 4) {
+ m3[a]+= flweight[2];
+ m4[a]+= flweight[10];
+ }
+ if(a & 8) {
+ m3[a]+= flweight[3];
+ m4[a]+= flweight[11];
+ }
+ if(a & 16) {
+ m3[a]+= flweight[4];
+ m4[a]+= flweight[12];
+ }
+ if(a & 32) {
+ m3[a]+= flweight[5];
+ m4[a]+= flweight[13];
+ }
+ if(a & 64) {
+ m3[a]+= flweight[6];
+ m4[a]+= flweight[14];
+ }
+ if(a & 128) {
+ m3[a]+= flweight[7];
+ m4[a]+= flweight[15];
+ }
}
}
-
- for(a= (1<<R.osa)-1; a>0; a--) {
- val= count_mask(a);
- i= 8+(15.9*(fpy1[a & 255]+fpy2[a>>8])/val);
- CLAMP(i, 0, 15);
- j= 8+(15.9*(fpx1[a & 255]+fpx2[a>>8])/val);
- CLAMP(j, 0, 15);
- i= j + (i<<4);
- centmask[a]= i;
- }
-
- MEM_freeN(fpx1);
- MEM_freeN(fpx2);
- MEM_freeN(fpy1);
- MEM_freeN(fpy2);
}
-}
-static void free_filt_mask()
-{
- int a;
-
- for(a=0; a<9; a++) {
- MEM_freeN(fmask1[a]);
- MEM_freeN(fmask2[a]);
- }
- MEM_freeN(gamtab);
- MEM_freeN(igamtab1);
- MEM_freeN(igamtab2);
-
- MEM_freeN(centmask);
+ /* centmask: the correct subpixel offset per mask */
+
+ fpx1= MEM_mallocN(256*sizeof(float), "initgauss4");
+ fpx2= MEM_mallocN(256*sizeof(float), "initgauss4");
+ fpy1= MEM_mallocN(256*sizeof(float), "initgauss4");
+ fpy2= MEM_mallocN(256*sizeof(float), "initgauss4");
+ for(a=0; a<256; a++) {
+ fpx1[a]= fpx2[a]= 0.0;
+ fpy1[a]= fpy2[a]= 0.0;
+ if(a & 1) {
+ fpx1[a]+= re->jit[0][0];
+ fpy1[a]+= re->jit[0][1];
+ fpx2[a]+= re->jit[8][0];
+ fpy2[a]+= re->jit[8][1];
+ }
+ if(a & 2) {
+ fpx1[a]+= re->jit[1][0];
+ fpy1[a]+= re->jit[1][1];
+ fpx2[a]+= re->jit[9][0];
+ fpy2[a]+= re->jit[9][1];
+ }
+ if(a & 4) {
+ fpx1[a]+= re->jit[2][0];
+ fpy1[a]+= re->jit[2][1];
+ fpx2[a]+= re->jit[10][0];
+ fpy2[a]+= re->jit[10][1];
+ }
+ if(a & 8) {
+ fpx1[a]+= re->jit[3][0];
+ fpy1[a]+= re->jit[3][1];
+ fpx2[a]+= re->jit[11][0];
+ fpy2[a]+= re->jit[11][1];
+ }
+ if(a & 16) {
+ fpx1[a]+= re->jit[4][0];
+ fpy1[a]+= re->jit[4][1];
+ fpx2[a]+= re->jit[12][0];
+ fpy2[a]+= re->jit[12][1];
+ }
+ if(a & 32) {
+ fpx1[a]+= re->jit[5][0];
+ fpy1[a]+= re->jit[5][1];
+ fpx2[a]+= re->jit[13][0];
+ fpy2[a]+= re->jit[13][1];
+ }
+ if(a & 64) {
+ fpx1[a]+= re->jit[6][0];
+ fpy1[a]+= re->jit[6][1];
+ fpx2[a]+= re->jit[14][0];
+ fpy2[a]+= re->jit[14][1];
+ }
+ if(a & 128) {
+ fpx1[a]+= re->jit[7][0];
+ fpy1[a]+= re->jit[7][1];
+ fpx2[a]+= re->jit[15][0];
+ fpy2[a]+= re->jit[15][1];
+ }
+ }
+
+ for(a= (1<<re->osa)-1; a>0; a--) {
+ val= st->cmask[a & 255] + st->cmask[a>>8];
+ i= 8+(15.9*(fpy1[a & 255]+fpy2[a>>8])/val);
+ CLAMP(i, 0, 15);
+ j= 8+(15.9*(fpx1[a & 255]+fpx2[a>>8])/val);
+ CLAMP(j, 0, 15);
+ i= j + (i<<4);
+ st->centmask[a]= i;
+ }
+
+ MEM_freeN(fpx1);
+ MEM_freeN(fpx2);
+ MEM_freeN(fpy1);
+ MEM_freeN(fpy2);
}
-/* ********************* init calls *********************** */
-static void init_def_material(void)
-{
- Material *ma;
-
- ma= &defmaterial;
-
- init_material(&defmaterial);
-
- init_render_material(ma);
-}
+/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
-/* this is called in creator.c, on startup */
-void RE_init_render_data(void)
+/* call this after InitState() */
+/* per render, there's one persistant viewplane. Parts will set their own viewplanes */
+void RE_SetCamera(Render *re, Object *camera)
{
- memset(&R, 0, sizeof(RE_Render));
+ Camera *cam=NULL;
+ rctf viewplane;
+ float pixsize, clipsta, clipend;
+ float lens;
+ float xd, yd;
+ int blursample= 0; /* make new call for that */
- RE_init_vertex_tables();
- R.blovl= (VlakRen **)MEM_callocN(sizeof(void *)*(TABLEINITSIZE),"Blovl");
- R.bloha= (HaloRen **)MEM_callocN(sizeof(void *)*(TABLEINITSIZE),"Bloha");
+ /* question mark */
+ re->ycor= ( (float)re->r.yasp)/( (float)re->r.xasp);
- init_def_material();
- init_filt_mask();
-}
-
-/* called in usiblender.c on exit, also for blender -b render */
-void RE_free_render_data()
-{
- MEM_freeN(R.vertnodes);
- R.vertnodes= NULL;
- MEM_freeN(R.blovl);
- R.blovl= NULL;
- MEM_freeN(R.bloha);
- R.bloha= NULL;
-
- if(R.rectot) MEM_freeN(R.rectot);
- if(R.rectftot) MEM_freeN(R.rectftot);
- if(R.rectz) MEM_freeN(R.rectz);
- if(R.rectzf) MEM_freeN(R.rectzf);
- if(R.rectspare) MEM_freeN(R.rectspare);
- R.rectot= NULL;
- R.rectftot= NULL;
- R.rectz= NULL;
- R.rectzf= NULL;
- R.rectspare= NULL;
-
- free_filt_mask();
-}
-
-/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
-
-void RE_make_existing_file(char *name)
-{
- char di[FILE_MAXDIR], fi[FILE_MAXFILE];
-
- strcpy(di, name);
- BLI_splitdirstring(di, fi);
-
- /* test exist */
- if (BLI_exists(di) == 0) {
- BLI_recurdir_fileops(di);
+ if(camera->type==OB_CAMERA) {
+ cam= camera->data;
+
+ if(cam->type==CAM_ORTHO) re->r.mode |= R_ORTHO;
+
+ lens= cam->lens;
+ clipsta= cam->clipsta;
+ clipend= cam->clipend;
}
-}
+ else if(camera->type==OB_LAMP) {
+ /* fac= cos( PI*((float)(256- la->spsi))/512.0 ); */
-
-/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
-
-void RE_setwindowclip(int mode, int jmode)
-{
- extern float bluroffsx, bluroffsy; // rendercore.c... hackish (ton)
- Camera *cam=NULL;
- float lens, minx, miny, maxx, maxy;
- float xd, yd, afmx, afmy;
-
- if(G.scene->camera==NULL) return;
-
- afmx= R.afmx;
- afmy= R.afmy;
-
- if(mode) {
-
- if(G.scene->camera->type==OB_LAMP) {
- /* fac= cos( PI*((float)(256- la->spsi))/512.0 ); */
-
- /* phi= acos(fac); */
- /* lens= 16.0*fac/sin(phi); */
- lens= 35.0;
- R.near= 0.1;
- R.far= 1000.0;
+ /* phi= acos(fac); */
+ /* lens= 16.0*fac/sin(phi); */
+ lens= 35.0;
+ clipsta= 0.1;
+ clipend= 1000.0;
+ }
+ else { /* envmap exception, can be done better... */
+ lens= 16.0;
+ clipsta= re->clipsta;
+ clipend= re->clipend;
+ if(clipsta==0.0f || clipend==0.0f) {
+ clipsta= 0.1;
+ clipend= 1000.0;
}
- else if(G.scene->camera->type==OB_CAMERA) {
- cam= G.scene->camera->data;
+ }
- lens= cam->lens;
- R.near= cam->clipsta;
- R.far= cam->clipend;
+ /* ortho only with camera available */
+ if(re->r.mode & R_ORTHO) {
+ if( (re->r.xasp*re->winx) >= (re->r.yasp*re->winy) ) {
+ re->viewfac= re->winx;
}
else {
- lens= 16.0;
+ re->viewfac= re->ycor*re->winy;
}
-
- if(R.r.mode & R_ORTHO) {
- if( (R.r.xasp*afmx) >= (R.r.yasp*afmy) ) {
- R.viewfac= 2.0*afmx;
- }
- else {
- R.viewfac= 2.0*R.ycor*afmy;
- }
- /* ortho_scale == 1.0 means exact 1 to 1 mapping */
- R.pixsize= cam->ortho_scale/R.viewfac;
+ /* ortho_scale == 1.0 means exact 1 to 1 mapping */
+ pixsize= cam->ortho_scale/re->viewfac;
+ }
+ else {
+ if( (re->r.xasp*re->winx) >= (re->r.yasp*re->winy) ) {
+ re->viewfac= (re->winx*lens)/32.0;
}
else {
- if( (R.r.xasp*afmx) >= (R.r.yasp*afmy) ) {
- R.viewfac= (afmx*lens)/16.0;
- }
- else {
- R.viewfac= R.ycor*(afmy*lens)/16.0;
- }
-
- R.pixsize= R.near/R.viewfac;
+ re->viewfac= re->ycor*(re->winy*lens)/32.0;
}
- /* pixsize is not a real global... get rid of it! (ton) */
+ pixsize= clipsta/re->viewfac;
}
-
+
/* revision / simplification of subpixel offsets:
- the matrix will go without offset from start (e.g. -100) to end (e.g. +99).
- filling in with zbuffer will set offset of 0.5. to make sure clipped faces fill in too
- in shadepixel() again that 0.5 offset is corrected
*/
- minx= R.xstart;
- miny= R.ycor*(R.ystart);
- maxx= R.xend;
- maxy= R.ycor*(R.yend);
-
- if(R.flag & R_SEC_FIELD) {
- if(R.r.mode & R_ODDFIELD) {
- miny-= .5*R.ycor;
- maxy-= .5*R.ycor;
+ viewplane.xmin= -0.5f*(float)re->winx;
+ viewplane.ymin= -0.5f*re->ycor*(float)re->winy;
+ viewplane.xmax= 0.5f*(float)re->winx;
+ viewplane.ymax= 0.5f*re->ycor*(float)re->winy;
+
+ if(re->flag & R_SEC_FIELD) {
+ if(re->r.mode & R_ODDFIELD) {
+ viewplane.ymin-= .5*re->ycor;
+ viewplane.ymax-= .5*re->ycor;
}
else {
- miny+= .5*R.ycor;
- maxy+= .5*R.ycor;
+ viewplane.ymin+= .5*re->ycor;
+ viewplane.ymax+= .5*re->ycor;
}
}
xd= yd= 0.0;
- if(jmode!= -1) {
- bluroffsx= xd= jit[jmode % R.osa][0];
- bluroffsy= yd= R.ycor*jit[jmode % R.osa][1];
+ if(blursample!= -1) {
+ re->bluroffsx= xd= re->jit[blursample % re->osa][0];
+ re->bluroffsy= yd= re->ycor*re->jit[blursample % re->osa][1];
}
- else bluroffsx=bluroffsy= 0.0;
+ else re->bluroffsx=re->bluroffsy= 0.0f;
- minx= R.pixsize*(minx+xd);
- maxx= R.pixsize*(maxx+xd);
- miny= R.pixsize*(miny+yd);
- maxy= R.pixsize*(maxy+yd);
-
- if(R.r.mode & R_ORTHO)
- i_ortho(minx, maxx, miny, maxy, R.near, R.far, R.winmat);
+ viewplane.xmin= pixsize*(viewplane.xmin+xd);
+ viewplane.xmax= pixsize*(viewplane.xmax+xd);
+ viewplane.ymin= pixsize*(viewplane.ymin+yd);
+ viewplane.ymax= pixsize*(viewplane.ymax+yd);
+
+ re->viewdx= pixsize;
+ re->viewdy= re->ycor*pixsize;
+
+ if(re->r.mode & R_ORTHO)
+ RE_SetOrtho(re, &viewplane, clipsta, clipend);
else
- i_window(minx, maxx, miny, maxy, R.near, R.far, R.winmat);
+ RE_SetWindow(re, &viewplane, clipsta, clipend);
- //printmatrix4("win", R.winmat);
+ //printmatrix4("win", re->winmat);
}
-/* ~~~~~~~~~~~~~~~~ PARTS ~~~~~~~~~~~~~~~~~~~~~~ */
+/* ~~~~~~~~~~~~~~~~ part (tile) calculus ~~~~~~~~~~~~~~~~~~~~~~ */
-/**
-* Part as in part-rendering. An image rendered in parts is rendered
-* to a list of parts, with x,y size, and a pointer to the render
-* output stored per part. Internal!
-*/
-typedef struct Part
-{
- struct Part *next, *prev;
- unsigned int *rect; // color 4x8 bits
- float *rectf; // color 4x32 bits
- unsigned int *rectz; // zbuffer
-
- short minx, miny, maxx, maxy, x, y;
-} Part;
-static void freeparts(void)
+void freeparts(Render *re)
{
- Part *part= R.parts.first;
+ RenderPart *part= re->parts.first;
+
while(part) {
- if(part->rect) MEM_freeN(part->rect);
+ if(part->rectp) MEM_freeN(part->rectp);
if(part->rectz) MEM_freeN(part->rectz);
- if(part->rectf) MEM_freeN(part->rectf);
part= part->next;
}
- BLI_freelistN(&R.parts);
-}
-
-static void initparts(void)
-{
- Part *pa;
- short nr, xd, yd, xpart, ypart, xparts, yparts;
- short a, xminb, xmaxb, yminb, ymaxb;
-
- freeparts();
-
- if(R.r.mode & R_BORDER) {
- xminb= R.r.border.xmin*R.rectx;
- xmaxb= R.r.border.xmax*R.rectx;
-
- yminb= R.r.border.ymin*R.recty;
- ymaxb= R.r.border.ymax*R.recty;
-
- if(xminb<0) xminb= 0;
- if(xmaxb>R.rectx) xmaxb= R.rectx;
- if(yminb<0) yminb= 0;
- if(ymaxb>R.recty) ymaxb= R.recty;
- }
- else {
- xminb=yminb= 0;
- xmaxb= R.rectx;
- ymaxb= R.recty;
- }
-
- xparts= R.r.xparts; /* for border */
- yparts= R.r.yparts;
-
- xpart= R.rectx/xparts;
- ypart= R.recty/yparts;
-
- /* if border: test if amount of parts can be fewer */
- if(R.r.mode & R_BORDER) {
- a= (xmaxb-xminb-1)/xpart+1; /* amount of parts in border */
- if(a<xparts) xparts= a;
- a= (ymaxb-yminb-1)/ypart+1; /* amount of parts in border */
- if(a<yparts) yparts= a;
-
- xpart= (xmaxb-xminb)/xparts;
- ypart= (ymaxb-yminb)/yparts;
- }
-
- for(nr=0; nr<xparts*yparts; nr++) {
- pa= MEM_callocN(sizeof(Part), "new part");
-
- if(R.r.mode & R_PANORAMA) {
- pa->minx= pa->miny= 0;
- pa->maxx= pa->x= R.rectx;
- pa->maxy= pa->y= R.recty;
- }
- else {
- xd= (nr % xparts);
- yd= (nr-xd)/xparts;
-
- pa->minx= xminb+ xd*xpart;
- pa->miny= yminb+ yd*ypart;
- if(xd<R.r.xparts-1) pa->maxx= pa->minx+xpart;
- else pa->maxx= xmaxb;
- if(yd<R.r.yparts-1) pa->maxy= pa->miny+ypart;
- else pa->maxy= ymaxb;
-
- pa->x= pa->maxx-pa->minx;
- pa->y= pa->maxy-pa->miny;
- }
-
- if(pa->x>0 && pa->y>0) {
- /* Non-box filters might need 1 pixel extra to work */
- if((R.r.filtertype)) {
- pa->minx-= 1;
- pa->miny-= 1;
- pa->maxx+= 1;
- pa->maxy+= 1;
- pa->x+= 2;
- pa->y+= 2;
- }
- BLI_addtail(&R.parts, pa);
- }
- else MEM_freeN(pa);
- }
-
+ BLI_freelistN(&re->parts);
}
-/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
-static void setpart(Part *pa)
+void initparts(Render *re)
{
-
- R.xstart= pa->minx-R.afmx;
- R.ystart= pa->miny-R.afmy;
- R.xend= pa->maxx-R.afmx;
- R.yend= pa->maxy-R.afmy;
- R.rectx= pa->x;
- R.recty= pa->y;
-}
-
-/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
-static void addparttorect(Part *pa)
-{
- float *rf, *rfp;
- unsigned int *rt, *rtp, *rz, *rzp;
- int y, height, len, copylen;
-
- /* calc the right offset in rects, zbuffer cannot exist... */
- if(pa->rect==NULL) return;
+ int nr, xd, yd, xpart, ypart, xparts, yparts;
+ int xminb, xmaxb, yminb, ymaxb;
- rtp= pa->rect;
- rzp= pa->rectz;
- rfp= pa->rectf;
+ freeparts(re);
- copylen=len= pa->x;
- height= pa->y;
+ /* this is render info for caller, is not reset when parts are freed! */
+ re->i.totpart= 0;
+ re->i.curpart= 0;
+ re->i.partsdone= 0;
- if(R.r.filtertype) { /* filters added 1 pixel extra */
-
- rtp+= 1+len;
- if(rzp) rzp+= 1+len;
- if(rfp) rfp+= 4*(1+len);
-
- copylen= len-2;
- height -= 2;
- rt= R.rectot+ (pa->miny + 1)*R.rectx+ (pa->minx+1);
- rz= R.rectz+ (pa->miny + 1)*R.rectx+ (pa->minx+1);
- rf= R.rectftot+ 4*( (pa->miny + 1)*R.rectx + (pa->minx+1) );
- }
- else {
- rt= R.rectot+ pa->miny*R.rectx+ pa->minx;
- rz= R.rectz+ pa->miny*R.rectx+ pa->minx;
- rf= R.rectftot+ 4*(pa->miny*R.rectx+ pa->minx);
- }
-
- for(y=0; y<height; y++) {
- memcpy(rt, rtp, 4*copylen);
- rt+= R.rectx;
- rtp+= len;
-
- if(rzp) {
- memcpy(rz, rzp, 4*copylen);
- rz+= R.rectx;
- rzp+= len;
- }
- if(rfp) {
- memcpy(rf, rfp, 16*copylen);
- rf+= 4*R.rectx;
- rfp+= 4*len;
- }
- }
-}
-
-/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
-
-static void convert_zbuf_to_distbuf(void)
-{
- float *rectzf, zco;
- int a, *rectz, ortho= R.r.mode & R_ORTHO;
+ /* just for readable code.. */
+ xminb= re->disprect.xmin;
+ yminb= re->disprect.ymin;
+ xmaxb= re->disprect.xmax;
+ ymaxb= re->disprect.ymax;
- if(R.rectz==NULL) return;
- if(R.rectzf) {
- printf("called convert zbuf wrong...\n");
- MEM_freeN(R.rectzf);
- }
+ xparts= re->r.xparts;
+ yparts= re->r.yparts;
- /* need to make sure winmat is OK */
- R.xstart= -R.afmx;
- R.ystart= -R.afmy;
- R.xend= R.xstart+R.rectx-1;
- R.yend= R.ystart+R.recty-1;
+ /* mininum part size */
+ if(re->rectx/xparts < 64)
+ xparts= 1 + re->rectx/64;
+ if(re->recty/yparts < 64)
+ yparts= 1 + re->recty/64;
- RE_setwindowclip(0, -1);
-
- rectzf= R.rectzf= MEM_mallocN(R.rectx*R.recty*sizeof(float), "rectzf");
- rectz= R.rectz;
+ /* part size */
+ xpart= re->rectx/xparts;
+ ypart= re->recty/yparts;
- for(a=R.rectx*R.recty; a>0; a--, rectz++, rectzf++) {
- if(*rectz==0x7FFFFFFF)
- *rectzf= 10e10;
- else {
- /* inverse of zbuf calc: zbuf = MAXZ*hoco_z/hoco_w */
- /* or: (R.winmat[3][2] - zco*R.winmat[3][3])/(R.winmat[2][2] - R.winmat[2][3]*zco); */
- /* if ortho [2][3] is zero, else [3][3] is zero */
-
- zco= ((float)*rectz)/2147483647.0f;
- if(ortho)
- *rectzf= (R.winmat[3][2] - zco*R.winmat[3][3])/(R.winmat[2][2]);
- else
- *rectzf= (R.winmat[3][2])/(R.winmat[2][2] - R.winmat[2][3]*zco);
- }
- }
-
- MEM_freeN(R.rectz);
- R.rectz= NULL;
-}
-
-
-/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
-
-
-static void add_to_blurbuf(int blur)
-{
- static unsigned int *blurrect= 0;
- int tot, gamval;
- short facr, facb;
- char *rtr, *rtb;
-
- if(blur<0) {
- if(blurrect) {
- if(R.rectot) MEM_freeN(R.rectot);
- R.rectot= blurrect;
- blurrect= 0;
- }
- }
- else if(blur==R.osa-1) {
- /* first time */
- blurrect= MEM_mallocN(R.rectx*R.recty*sizeof(int), "rectblur");
- if(R.rectot) memcpy(blurrect, R.rectot, R.rectx*R.recty*4);
- }
- else if(blurrect) {
- /* accumulate */
-
- facr= 256/(R.osa-blur);
- facb= 256-facr;
-
- if(R.rectot) {
- rtr= (char *)R.rectot;
- rtb= (char *)blurrect;
- tot= R.rectx*R.recty;
- while(tot--) {
- if( *((unsigned int *)rtb) != *((unsigned int *)rtr) ) {
-
- if(R.r.mode & R_GAMMA) {
- gamval= (facr* igamtab2[ rtr[0]<<8 ] + facb* igamtab2[ rtb[0]<<8 ])>>8;
- rtb[0]= gamtab[ gamval ]>>8;
- gamval= (facr* igamtab2[ rtr[1]<<8 ] + facb* igamtab2[ rtb[1]<<8 ])>>8;
- rtb[1]= gamtab[ gamval ]>>8;
- gamval= (facr* igamtab2[ rtr[2]<<8 ] + facb* igamtab2[ rtb[2]<<8 ])>>8;
- rtb[2]= gamtab[ gamval ]>>8;
- gamval= (facr* igamtab2[ rtr[3]<<8 ] + facb* igamtab2[ rtb[3]<<8 ])>>8;
- rtb[3]= gamtab[ gamval ]>>8;
- }
- else {
- rtb[0]= (facr*rtr[0] + facb*rtb[0])>>8;
- rtb[1]= (facr*rtr[1] + facb*rtb[1])>>8;
- rtb[2]= (facr*rtr[2] + facb*rtb[2])>>8;
- rtb[3]= (facr*rtr[3] + facb*rtb[3])>>8;
- }
- }
- rtr+= 4;
- rtb+= 4;
- }
- }
- if(blur==0) {
- /* last time */
- if(R.rectot) MEM_freeN(R.rectot);
- R.rectot= blurrect;
- blurrect= 0;
- }
- }
-}
-
-
-/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
-
-
-/* yafray: main yafray render/export call */
-static void yafrayRender(void)
-{
- R.flag |= R_RENDERING; /* !!! */
-
- /* bug #3193: these params were not initialized, needed later for winmat calc. */
- R.xstart = -R.afmx;
- R.ystart = -R.afmy;
- R.xend = R.xstart + R.rectx - 1;
- R.yend = R.ystart + R.recty - 1;
-
- /* all allocs moved here, out of export code */
- /* display rgba buf */
- if (R.rectot) MEM_freeN(R.rectot);
- R.rectot = MEM_callocN(sizeof(int)*R.rectx*R.recty, "rectot");
- /* zbuf */
- if (R.rectz) MEM_freeN(R.rectz);
- if (R.rectzf) MEM_freeN(R.rectzf);
- R.rectzf= NULL;
- R.rectz = (unsigned int *)MEM_mallocN(sizeof(int)*R.rectx*R.recty, "rectz");
- /* float rgba buf */
- if (R.rectftot) MEM_freeN(R.rectftot);
- if (R.r.mode & R_FBUF) R.rectftot= MEM_callocN(4*sizeof(float)*R.rectx*R.recty, "rectftot");
- else R.rectftot = NULL;
-
- // switch must be done before prepareScene()
- if (!R.r.YFexportxml)
- YAF_switchFile();
- else
- YAF_switchPlugin();
-
- RE_local_init_render_display();
- RE_local_clear_render_display(R.win);
- RE_local_timecursor((G.scene->r.cfra));
-
- printf("Starting scene conversion.\n");
- prepareScene();
- printf("Scene conversion done.\n");
-
- YAF_exportScene();
- finalizeScene();
-
- // show postpro effects if floatbuffer used (plugin only)
- if (R.r.YFexportxml) {
- if ((R.r.mode & R_FBUF) && R.rectftot)
- RE_floatbuffer_to_output();
- }
-}
-
-
-/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
-
-// exported to other files, belongs in include... later
-SDL_mutex *render_abuf_lock=NULL, *load_ibuf_lock=NULL;
-
-
-static void renderloop_setblending(void)
-{
-
- /* this value should only be set here. do_gamma is for gammablended adding of subpixels */
- do_gamma= 0;
- if(R.r.mode & R_GAMMA) {
- if(R.r.alphamode==R_ALPHAKEY); // alpha corrected gamma doesnt work for key alpha
- else if((R.r.mode & R_OSA)) do_gamma= 1;
- }
-
- /* always call, it does gamma tables used by alphaunder, but call after R.osa and jit was set */
- init_filt_mask();
-
- switch (R.r.alphamode) {
- case R_ALPHAKEY:
- setSkyBlendingMode(RE_ALPHA_KEY);
- break;
- case R_ALPHAPREMUL:
- setSkyBlendingMode(RE_ALPHA_PREMUL);
- break;
- default:
- setSkyBlendingMode(RE_ALPHA_SKY);
- }
-
- /* SHould use slider when the gamma button is pressed. */
- if (do_gamma) {
- makeGammaTables(2.0);
- } else {
- makeGammaTables(1.0);
- }
-
-}
-
-static void mainRenderLoop(void) /* here the PART and FIELD loops */
-{
- Part *pa;
- int blur, fields, fi, totparts, nr;
-
- /* create mutexes for threaded render */
- render_abuf_lock = SDL_CreateMutex();
- load_ibuf_lock = SDL_CreateMutex();
-
- if(R.rectz) MEM_freeN(R.rectz);
- R.rectz = NULL;
- if(R.rectzf) MEM_freeN(R.rectzf);
- R.rectzf = NULL;
- if(R.rectftot) MEM_freeN(R.rectftot);
- R.rectftot = NULL;
-
- /* FIELD LOOP */
- totparts= R.r.xparts*R.r.yparts;
- fields= 1;
-
- if(R.r.mode & R_FIELDS) {
- fields= 2;
- R.rectf1= R.rectf2= NULL; /* field rects */
- R.r.ysch/= 2;
- R.afmy/= 2;
- R.r.yasp*= 2;
- R.ycor= ( (float)R.r.yasp)/( (float)R.r.xasp);
-
- }
-
- for(fi=0; fi<fields; fi++) {
-
- /* INIT */
- BLI_srandom( 2*(G.scene->r.cfra)+fi);
-
- R.flag|= R_RENDERING;
- if(fi==1) R.flag |= R_SEC_FIELD;
-
- /* MOTIONBLUR loop */
- if(R.r.mode & R_MBLUR) blur= R.osa;
- else blur= 1;
- while(blur--) {
-
- /* WINDOW */
- R.rectx= R.r.xsch;
- R.recty= R.r.ysch;
- R.xstart= -R.afmx;
- R.ystart= -R.afmy;
- R.xend= R.xstart+R.rectx-1;
- R.yend= R.ystart+R.recty-1;
-
- if(R.r.mode & R_MBLUR) set_mblur_offs(R.osa-blur);
-
- initparts(); /* always do, because of border and gauss */
- if(R.parts.first==NULL) {
- G.afbreek=1;
- error("Image too small");
- break;
- }
-
- setpart(R.parts.first);
-
- RE_local_init_render_display();
- RE_local_clear_render_display(R.win);
- RE_local_timecursor((G.scene->r.cfra));
-
- prepareScene();
-
- /* PARTS LOOP */
- nr= 0;
- for(pa= R.parts.first; pa; pa= pa->next, nr++) {
-
- if(RE_local_test_break()) break;
-
- setpart(pa);
-
- if(R.r.mode & R_MBLUR) RE_setwindowclip(0, blur);
- else RE_setwindowclip(0,-1);
-
- if(R.r.mode & R_PANORAMA) setPanoRot(nr);
-
- /* HOMOGENIC COORDINATES AND ZBUF AND CLIP OPTIMISATION (per part) */
- /* There may be some interference with z-coordinate */
- /* calculation here? */
-
- doClipping(RE_projectverto);
- if(RE_local_test_break()) break;
-
- /* rectot is for result and integer face indices */
- if(R.rectot) MEM_freeN(R.rectot);
- R.rectot= MEM_callocN(sizeof(int)*R.rectx*R.recty, "rectot");
-
- if(R.rectftot) MEM_freeN(R.rectftot);
- if(R.r.mode & R_FBUF) R.rectftot= MEM_callocN(4*sizeof(float)*R.rectx*R.recty, "rectftot");
- else R.rectftot = NULL;
-
- if(R.r.mode & R_MBLUR) {
- RE_local_printrenderinfo(0.0, R.osa - blur);
- if(G.background && blur<R.osa) printf("\n"); // newline for percentage print
- }
- else RE_local_printrenderinfo(0.0, -1);
-
- if(R.r.mode & R_UNIFIED) {
- zBufShadeAdvanced();
- }
- else {
- if(R.rectz) MEM_freeN(R.rectz);
- R.rectz = (unsigned int *)MEM_mallocN(sizeof(int)*R.rectx*R.recty, "rectz");
-
- if(R.r.mode & R_OSA) zbufshadeDA();
- else zbufshade();
- }
-
- /* exception */
- if( (R.r.mode & R_BORDER) && (R.r.mode & R_MOVIECROP));
- else {
- /* HANDLE PART OR BORDER */
- if(totparts>1 || (R.r.mode & R_BORDER) || (R.r.filtertype)) {
-
- pa->rect= R.rectot;
- R.rectot= NULL;
- pa->rectf= R.rectftot;
- R.rectftot= NULL;
- pa->rectz= R.rectz;
- R.rectz= NULL;
- }
- }
-
- if(RE_local_test_break()) break;
- }
-
- /* JOIN PARTS OR INSERT BORDER */
-
- /* exception: crop */
- if( (R.r.mode & R_BORDER) && (R.r.mode & R_MOVIECROP)) ;
- else {
- R.rectx= R.r.xsch;
- R.recty= R.r.ysch;
-
- if(R.r.mode & R_PANORAMA) R.rectx*= R.r.xparts;
-
- if(totparts>1 || (R.r.mode & R_BORDER) || (R.r.filtertype)) {
- int a;
-
- if(R.rectot) MEM_freeN(R.rectot);
- if(R.rectftot) MEM_freeN(R.rectftot);
- if(R.rectz) MEM_freeN(R.rectz);
-
- R.rectot= MEM_callocN(sizeof(int)*R.rectx*R.recty, "rectot");
-
- if(R.r.mode & R_UNIFIED) R.rectz= NULL;
- else R.rectz= MEM_callocN(sizeof(int)*R.rectx*R.recty, "rectz");
-
- if(R.r.mode & R_FBUF) R.rectftot= MEM_callocN(4*sizeof(float)*R.rectx*R.recty, "rectftot");
- else R.rectftot= NULL;
-
- for(a=0, pa= R.parts.first; pa; pa= pa->next, a++) {
-
- if(R.r.mode & R_PANORAMA) { // pano is fake parts...
- pa->minx += a*R.r.xsch;
- pa->maxx += a*R.r.xsch;
- }
- addparttorect(pa);
- }
- }
- }
-
- freeparts();
-
- if( (R.flag & R_HALO)) {
- 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);
- }
-
- /* END (blur loop) */
- finalizeScene();
-
- if(RE_local_test_break()) break;
- }
-
- /* definite free */
- add_to_blurbuf(-1);
-
- /* HANDLE FIELD */
- if(R.r.mode & R_FIELDS) {
- if(R.flag & R_SEC_FIELD) R.rectf2= R.rectot;
- else R.rectf1= R.rectot;
- R.rectot= NULL;
- }
-
- if(RE_local_test_break()) break;
- }
-
- /* JOIN FIELDS */
- if(R.r.mode & R_FIELDS) {
- R.r.ysch*= 2;
- R.afmy*= 2;
- R.recty*= 2;
- R.r.yasp/=2;
-
- if(R.rectot) MEM_freeN(R.rectot); /* happens when a render has been stopped */
- R.rectot=(unsigned int *)MEM_callocN(sizeof(int)*R.rectx*R.recty, "rectot");
+ for(nr=0; nr<xparts*yparts; nr++) {
+ rcti disprect;
+ int rectx, recty;
- if(RE_local_test_break()==0) {
- unsigned int *rt, *rt1, *rt2;
- int len, a;
-
- rt= R.rectot;
-
- if(R.r.mode & R_ODDFIELD) {
- rt2= R.rectf1;
- rt1= R.rectf2;
- }
- else {
- rt1= R.rectf1;
- rt2= R.rectf2;
- }
-
- len= 4*R.rectx;
-
- for(a=0; a<R.recty; a+=2) {
- memcpy(rt, rt1, len);
- rt+= R.rectx;
- rt1+= R.rectx;
- memcpy(rt, rt2, len);
- rt+= R.rectx;
- rt2+= R.rectx;
- }
- }
+ xd= (nr % xparts);
+ yd= (nr-xd)/xparts;
- if(R.rectf1) MEM_freeN(R.rectf1);
- R.rectf1= NULL;
- if(R.rectf2) MEM_freeN(R.rectf2);
- R.rectf2= NULL;
- /* fbuf and zbuf free, image size differs now */
- if(R.rectftot) MEM_freeN(R.rectftot);
- R.rectftot= NULL;
- if(R.rectz) MEM_freeN(R.rectz);
- R.rectz= NULL;
+ disprect.xmin= xminb+ xd*xpart;
+ disprect.ymin= yminb+ yd*ypart;
- }
-
- /* if border: still do skybuf */
- if(R.r.mode & R_BORDER) {
- if( (R.r.mode & R_MOVIECROP)==0) {
- if(R.r.bufflag & 1) {
- unsigned int *rt;
- int x, y;
-
- R.xstart= -R.afmx;
- R.ystart= -R.afmy;
- rt= R.rectot;
- for(y=0; y<R.recty; y++) {
- for(x=0; x<R.rectx; x++, rt++) {
- if(*rt==0) fillBackgroundImageChar((char *)rt, x, y);
- }
- }
- }
- }
- }
-
- set_mblur_offs(0);
-
- /* mutexes free */
- SDL_DestroyMutex(load_ibuf_lock);
- SDL_DestroyMutex(render_abuf_lock);
- load_ibuf_lock= NULL;
- render_abuf_lock= NULL;
-}
-
-void render() {
- /* yafray: render, see above */
- if (R.r.renderer==R_YAFRAY)
- yafrayRender();
- else
- mainRenderLoop();
-}
-
-
-/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
-
-void RE_initrender(struct View3D *ogl_render_view3d)
-{
- double start_time;
- Image *bima;
- char name[256];
-
- /* scene data to R */
- R.r= G.scene->r;
- R.r.postigamma= 1.0/R.r.postgamma;
-
- /* WINDOW size (sch='scherm' dutch for screen...) */
- R.r.xsch= (R.r.size*R.r.xsch)/100;
- R.r.ysch= (R.r.size*R.r.ysch)/100;
-
- R.afmx= R.r.xsch/2;
- R.afmy= R.r.ysch/2;
-
- /* to be sure: when a premature return (rectx can differ from xsch) */
- R.rectx= R.r.xsch;
- R.recty= R.r.ysch;
-
- /* IS RENDERING ALLOWED? */
-
- /* forbidden combination */
- if(R.r.mode & R_PANORAMA) {
- if(R.r.mode & R_BORDER) {
- error("No border supported for Panorama");
- G.afbreek= 1;
- }
- if(R.r.yparts>1) {
- error("No Y-Parts supported for Panorama");
- G.afbreek= 1;
+ /* ensure we cover the entire picture, so last parts go to end */
+ if(xd<xparts-1) {
+ disprect.xmax= disprect.xmin + xpart;
+ if(disprect.xmax > xmaxb)
+ disprect.xmax = xmaxb;
}
- if(R.r.mode & R_ORTHO) {
- error("No Ortho render possible for Panorama");
- G.afbreek= 1;
- }
- }
-
- if(R.r.mode & R_BORDER) {
- if(R.r.border.xmax <= R.r.border.xmin ||
- R.r.border.ymax <= R.r.border.ymin) {
- error("No border area selected.");
- G.afbreek= 1;
- }
- }
-
- if(R.r.xparts*R.r.yparts>=2 && (R.r.mode & R_MOVIECROP) && (R.r.mode & R_BORDER)) {
- error("Combination of border, crop and parts not allowed");
- G.afbreek= 1;
- return;
- }
-
- if(R.r.xparts*R.r.yparts>64) {
- error("No more than 64 parts supported");
- G.afbreek= 1;
- return;
- }
-
- if(R.r.yparts>1 && (R.r.mode & R_PANORAMA)) {
- error("No Y-Parts supported for Panorama");
- G.afbreek= 1;
- return;
- }
-
- if(G.afbreek==1) return;
-
- /* TEST BACKBUF */
- /* If an image is specified for use as backdrop, that image is loaded */
- /* here. */
- if((R.r.bufflag & 1) && (G.scene->r.scemode & R_OGL)==0) {
- if(R.r.alphamode == R_ADDSKY) {
- strcpy(name, R.r.backbuf);
- BLI_convertstringcode(name, G.sce, G.scene->r.cfra);
-
- if(R.backbuf) {
- R.backbuf->id.us--;
- bima= R.backbuf;
- }
- else bima= NULL;
-
- R.backbuf= add_image(name);
-
- if(bima && bima->id.us<1) {
- free_image_buffers(bima);
- }
-
- if(R.backbuf && R.backbuf->ibuf==NULL) {
- R.backbuf->ibuf= IMB_loadiffname(R.backbuf->name, IB_rect);
- if(R.backbuf->ibuf==NULL) R.backbuf->ok= 0;
- else R.backbuf->ok= 1;
- }
- if(R.backbuf==NULL || R.backbuf->ok==0) {
- // error() doesnt work with render window open
- //error("No backbuf there!");
- printf("Error: No backbuf %s\n", name);
- }
- }
- }
-
- if(R.r.mode & (R_OSA|R_MBLUR)) {
- R.osa= R.r.osa;
- if(R.osa>16) R.osa= 16;
-
- init_render_jit(R.osa);
+ else disprect.xmax= xmaxb;
- }
- else R.osa= 0;
-
- /* just prevents cpu cycles for larger render and copying */
- if((R.r.mode & R_OSA)==0)
- R.r.filtertype= 0;
-
- renderloop_setblending(); // alpha, sky, gamma
-
- /* when rendered without camera object */
- /* it has to done here because of envmaps */
- R.near= 0.1;
- R.far= 1000.0;
-
-
- if(R.afmx<1 || R.afmy<1) {
- error("Image too small");
- return;
- }
- R.ycor= ( (float)R.r.yasp)/( (float)R.r.xasp);
-
- start_time= PIL_check_seconds_timer();
-
- if(R.r.scemode & R_OGL) {
- R.rectx= R.r.xsch;
- R.recty= R.r.ysch;
-
- if(R.rectot) MEM_freeN(R.rectot);
- R.rectot= (unsigned int *)MEM_callocN(sizeof(int)*R.rectx*R.recty, "rectot");
-
- if(R.rectftot) MEM_freeN(R.rectftot);
- R.rectftot= NULL;
-
- RE_local_init_render_display();
- drawview3d_render(ogl_render_view3d);
- }
- else if(R.r.scemode & R_DOSEQ) {
- R.rectx= R.r.xsch;
- R.recty= R.r.ysch;
- if(R.r.mode & R_PANORAMA) {
- R.rectx*= R.r.xparts;
+ if(yd<yparts-1) {
+ disprect.ymax= disprect.ymin + ypart;
+ if(disprect.ymax > ymaxb)
+ disprect.ymax = ymaxb;
}
+ else disprect.ymax= ymaxb;
- if(R.rectot) MEM_freeN(R.rectot);
- R.rectot= (unsigned int *)MEM_callocN(sizeof(int)*R.rectx*R.recty, "rectot");
-
- if(R.rectftot) MEM_freeN(R.rectftot);
- R.rectftot= NULL;
-
- RE_local_timecursor((G.scene->r.cfra));
-
- if(RE_local_test_break()==0) do_render_seq();
-
- /* display */
- if(R.rectot) RE_local_render_display(0, R.recty-1, R.rectx, R.recty,R.rectot);
- }
- else {
- if(G.scene->camera==0) {
- G.scene->camera= scene_find_camera(G.scene);
- }
+ rectx= disprect.xmax - disprect.xmin;
+ recty= disprect.ymax - disprect.ymin;
- if(G.scene->camera==0) {
- error("No camera");
- /* needed because R.rectx and R.recty can be unmatching R.rectot */
+ /* so, now can we add this part? */
+ if(rectx>0 && recty>0) {
+ RenderPart *pa= MEM_callocN(sizeof(RenderPart), "new part");
- if(R.rectot) MEM_freeN(R.rectot);
- R.rectot= NULL;
- if(R.rectftot) MEM_freeN(R.rectftot);
- R.rectftot= NULL;
-
- G.afbreek=1;
- return;
- }
- else {
-
- if(G.scene->camera->type==OB_CAMERA) {
- Camera *cam= G.scene->camera->data;
- if(cam->type==CAM_ORTHO) R.r.mode |= R_ORTHO;
+ /* Non-box filters need 2 pixels extra to work */
+ if((re->r.filtertype || (re->r.mode & R_EDGE))) {
+ pa->crop= 2;
+ disprect.xmin -= pa->crop;
+ disprect.ymin -= pa->crop;
+ disprect.xmax += pa->crop;
+ disprect.ymax += pa->crop;
+ rectx+= 2*pa->crop;
+ recty+= 2*pa->crop;
}
-
- render(); /* returns with complete rect xsch-ysch */
- }
- }
-
- /* display again: fields/seq/parts/pano etc */
- if(R.rectot) {
- RE_local_init_render_display();
- RE_local_render_display(0, R.recty-1, R.rectx, R.recty, R.rectot);
- }
- else RE_local_clear_render_display(R.win);
-
- if ((G.scene->r.scemode & R_OGL)==0) /* header gets scrabled if renderwindow holds OGL context */
- RE_local_printrenderinfo((PIL_check_seconds_timer() - start_time), -1);
-
- /* grms... this is a nasty global */
- do_gamma= 0;
-
- /* for now, we do always */
- convert_zbuf_to_distbuf();
-
- /* these flags remain on, until reset in caller to render (renderwin.c) */
- R.flag &= (R_RENDERING|R_ANIMRENDER|R_REDRAW_PRV);
-}
+ pa->disprect= disprect;
+ pa->rectx= rectx;
+ pa->recty= recty;
-void RE_animrender(struct View3D *ogl_render_view3d)
-{
- int cfrao;
- char name[256];
-
- if(G.scene==NULL) return;
- if(G.scene->r.sfra > G.scene->r.efra) {
- error("Startframe larger than Endframe");
- return;
- }
-
- /* scenedata to R: (for backbuf, R.rectx etc) */
- R.r= G.scene->r;
-
- /* START ANIMLOOP, everywhere NOT the cfra from R.r is gebruikt: because of rest blender */
- cfrao= (G.scene->r.cfra);
-
- /* disable options for ogl render */
- if(G.scene->r.scemode & R_OGL) R.r.mode &= ~(R_PANORAMA|R_MOVIECROP);
-
- // these calculations apply for all movie formats
- R.rectx= (R.r.size*R.r.xsch)/100;
- R.recty= (R.r.size*R.r.ysch)/100;
- if(R.r.mode & R_PANORAMA) {
- R.rectx*= R.r.xparts;
- R.recty*= R.r.yparts;
- }
- if(R.r.mode & R_MOVIECROP) {
- initparts();
- setpart(R.parts.first); // this will adjust r.rectx
- }
-
- if (0) {
-#ifdef __sgi
- } else if (R.r.imtype==R_MOVIE) {
- start_movie();
-#endif
-#if defined(_WIN32) && !defined(FREE_WINDOWS)
- } else if (R.r.imtype == R_AVICODEC) {
- start_avi_codec();
-#endif
-#if WITH_QUICKTIME
- } else if (R.r.imtype == R_QUICKTIME) {
- start_qt();
-#endif
- } else if ELEM4(R.r.imtype, R_AVIRAW, R_AVIJPEG, R_MOVIE, R_AVICODEC) {
- if ELEM(R.r.imtype, R_MOVIE, R_AVICODEC) {
- printf("Selected movie format not supported on this platform,\nusing RAW AVI instead\n");
+ BLI_addtail(&re->parts, pa);
+ re->i.totpart++;
}
- start_avi();
}
-// set initial conditions for softbodies here
-// ******************************************
- for((G.scene->r.cfra)=(G.scene->r.sfra); (G.scene->r.cfra)<=(G.scene->r.efra); (G.scene->r.cfra)++) {
- double starttime= PIL_check_seconds_timer();
+}
- R.flag |= R_ANIMRENDER; // unused now (ton)
- RE_initrender(ogl_render_view3d);
-
- /* WRITE IMAGE */
- if(RE_local_test_break()==0) {
+/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
- if (0) {
-#ifdef __sgi
- } else if (R.r.imtype == R_MOVIE) {
- append_movie((G.scene->r.cfra));
-#endif
-#if defined(_WIN32) && !defined(FREE_WINDOWS)
- } else if (R.r.imtype == R_AVICODEC) {
- append_avi_codec((G.scene->r.cfra));
-#endif
-#ifdef WITH_QUICKTIME
- } else if (R.r.imtype == R_QUICKTIME) {
- append_qt((G.scene->r.cfra));
-#endif
- } else if ELEM4(R.r.imtype, R_AVIRAW, R_AVIJPEG, R_MOVIE, R_AVICODEC) {
- append_avi((G.scene->r.cfra));
- } else {
- makepicstring(name, (G.scene->r.cfra));
- schrijfplaatje(name);
- if(RE_local_test_break()==0) printf("Saved: %s", name);
- }
+// exported to other files, belongs in include... later
+SDL_mutex *render_abuf_lock=NULL, *load_ibuf_lock=NULL;
- timestr(PIL_check_seconds_timer()-starttime, name);
- printf(" Time: %s\n", name);
- fflush(stdout); /* needed for renderd !! */
- }
- if(G.afbreek==1) break;
- }
+/* **************************************************************** */
+/* sticky texture coords */
+/* **************************************************************** */
- G.scene->r.cfra= cfrao;
+void RE_make_sticky(void)
+{
+ /* oldfile.txt */
+}
- /* restore time */
- if(R.r.mode & (R_FIELDS|R_MBLUR)) {
- /* applies changes fully */
- scene_update_for_newframe(G.scene, G.scene->lay);
- }
- if (0) {
-#ifdef __sgi
- } else if (R.r.imtype==R_MOVIE) {
- end_movie();
-#endif
-#if defined(_WIN32) && !defined(FREE_WINDOWS)
- } else if (R.r.imtype == R_AVICODEC) {
- end_avi_codec();
-#endif
-#ifdef WITH_QUICKTIME
- } else if (R.r.imtype == R_QUICKTIME) {
- end_qt();
-#endif
- } else if ELEM4(R.r.imtype, R_AVIRAW, R_AVIJPEG, R_MOVIE, R_AVICODEC) {
- end_avi();
- }
-}
-/* *************************************************** */
-/* ******************* Screendumps ******************** */
-/* moved to the windowControl thing */
diff --git a/source/blender/render/intern/source/jitter.c b/source/blender/render/intern/source/jitter.c
deleted file mode 100644
index 98bb1543068..00000000000
--- a/source/blender/render/intern/source/jitter.c
+++ /dev/null
@@ -1,198 +0,0 @@
-/**
- * Jitter offset table
- *
- * $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.
- *
- * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
- * All rights reserved.
- *
- * The Original Code is: all of this file.
- *
- * Contributor(s): none yet.
- *
- * ***** END GPL/BL DUAL LICENSE BLOCK *****
- */
-
-#include <math.h>
-#include <stdlib.h>
-#include <string.h>
-#include "MEM_guardedalloc.h"
-
-#include "BLI_arithb.h"
-#include "BLI_rand.h"
-#include "render.h"
-#include "jitter.h"
-
-
-float jit[64][2];
-
-void init_render_jit(int nr);
-
-
-void RE_jitterate1(float *jit1, float *jit2, int num, float rad1)
-{
- int i , j , k;
- float vecx, vecy, dvecx, dvecy, x, y, len;
-
- for (i = 2*num-2; i>=0 ; i-=2) {
- dvecx = dvecy = 0.0;
- x = jit1[i];
- y = jit1[i+1];
- for (j = 2*num-2; j>=0 ; j-=2) {
- if (i != j){
- vecx = jit1[j] - x - 1.0;
- vecy = jit1[j+1] - y - 1.0;
- for (k = 3; k>0 ; k--){
- if( fabs(vecx)<rad1 && fabs(vecy)<rad1) {
- len= sqrt(vecx*vecx + vecy*vecy);
- if(len>0 && len<rad1) {
- len= len/rad1;
- dvecx += vecx/len;
- dvecy += vecy/len;
- }
- }
- vecx += 1.0;
-
- if( fabs(vecx)<rad1 && fabs(vecy)<rad1) {
- len= sqrt(vecx*vecx + vecy*vecy);
- if(len>0 && len<rad1) {
- len= len/rad1;
- dvecx += vecx/len;
- dvecy += vecy/len;
- }
- }
- vecx += 1.0;
-
- if( fabs(vecx)<rad1 && fabs(vecy)<rad1) {
- len= sqrt(vecx*vecx + vecy*vecy);
- if(len>0 && len<rad1) {
- len= len/rad1;
- dvecx += vecx/len;
- dvecy += vecy/len;
- }
- }
- vecx -= 2.0;
- vecy += 1.0;
- }
- }
- }
-
- x -= dvecx/18.0 ;
- y -= dvecy/18.0;
- x -= floor(x) ;
- y -= floor(y);
- jit2[i] = x;
- jit2[i+1] = y;
- }
- memcpy(jit1,jit2,2 * num * sizeof(float));
-}
-
-void RE_jitterate2(float *jit1, float *jit2, int num, float rad2)
-{
- int i, j;
- float vecx, vecy, dvecx, dvecy, x, y;
-
- for (i=2*num -2; i>= 0 ; i-=2){
- dvecx = dvecy = 0.0;
- x = jit1[i];
- y = jit1[i+1];
- for (j =2*num -2; j>= 0 ; j-=2){
- if (i != j){
- vecx = jit1[j] - x - 1.0;
- vecy = jit1[j+1] - y - 1.0;
-
- if( fabs(vecx)<rad2) dvecx+= vecx*rad2;
- vecx += 1.0;
- if( fabs(vecx)<rad2) dvecx+= vecx*rad2;
- vecx += 1.0;
- if( fabs(vecx)<rad2) dvecx+= vecx*rad2;
-
- if( fabs(vecy)<rad2) dvecy+= vecy*rad2;
- vecy += 1.0;
- if( fabs(vecy)<rad2) dvecy+= vecy*rad2;
- vecy += 1.0;
- if( fabs(vecy)<rad2) dvecy+= vecy*rad2;
-
- }
- }
-
- x -= dvecx/2 ;
- y -= dvecy/2;
- x -= floor(x) ;
- y -= floor(y);
- jit2[i] = x;
- jit2[i+1] = y;
- }
- memcpy(jit1,jit2,2 * num * sizeof(float));
-}
-
-
-void initjit(float *jitarr, int num)
-{
- float *jit2, x, rad1, rad2, rad3;
- int i;
-
- if(num==0) return;
-
- jit2= MEM_mallocN(12 + 2*sizeof(float)*num, "initjit");
- rad1= 1.0/sqrt((float)num);
- rad2= 1.0/((float)num);
- rad3= sqrt((float)num)/((float)num);
-
- BLI_srand(31415926 + num);
- x= 0;
- for(i=0; i<2*num; i+=2) {
- jitarr[i]= x+ rad1*(0.5-BLI_drand());
- jitarr[i+1]= ((float)i/2)/num +rad1*(0.5-BLI_drand());
- x+= rad3;
- x -= floor(x);
- }
-
- for (i=0 ; i<24 ; i++) {
- RE_jitterate1(jitarr, jit2, num, rad1);
- RE_jitterate1(jitarr, jit2, num, rad1);
- RE_jitterate2(jitarr, jit2, num, rad2);
- }
-
- MEM_freeN(jit2);
-
- /* finally, move jittertab to be centered around (0,0) */
- for(i=0; i<2*num; i+=2) {
- jitarr[i] -= 0.5;
- jitarr[i+1] -= 0.5;
- }
-
-}
-
-void init_render_jit(int nr)
-{
- static int lastjit= 0;
-
- if(lastjit==nr) return;
-
- memset(jit, 0, 64*2*4);
- initjit(jit[0], nr);
-
- lastjit= nr;
-}
-
-/* eof */
diff --git a/source/blender/render/intern/source/pipeline.c b/source/blender/render/intern/source/pipeline.c
new file mode 100644
index 00000000000..67690fd69f6
--- /dev/null
+++ b/source/blender/render/intern/source/pipeline.c
@@ -0,0 +1,954 @@
+/**
+ *
+ * ***** BEGIN GPL 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.
+ *
+ * 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.
+ *
+ * The Original Code is Copyright (C) 2006 Blender Foundation.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+#include <math.h>
+#include <limits.h>
+#include <string.h>
+#include <stdlib.h>
+
+#include "DNA_group_types.h"
+#include "DNA_object_types.h"
+#include "DNA_scene_types.h"
+
+#include "BKE_global.h"
+#include "BKE_image.h"
+#include "BKE_scene.h"
+#include "BKE_writeavi.h" /* <------ should be replaced once with generic movie module */
+
+#include "MEM_guardedalloc.h"
+
+#include "BLI_arithb.h"
+#include "BLI_blenlib.h"
+
+#include "PIL_time.h"
+#include "IMB_imbuf.h"
+#include "IMB_imbuf_types.h"
+
+#include "RE_pipeline.h"
+#include "radio.h"
+
+#include "BSE_sequence.h" /* <----------------- bad!!! */
+
+/* internal */
+#include "render_types.h"
+#include "renderpipeline.h"
+#include "renderdatabase.h"
+#include "rendercore.h"
+#include "envmap.h"
+#include "initrender.h"
+#include "shadbuf.h"
+#include "zbuf.h"
+
+#include "SDL_thread.h"
+
+/* render flow
+
+1) Initialize state
+- state data, tables
+- movie/image file init
+- everything that doesn't change during animation
+
+2) Initialize data
+- camera, world, matrices
+- make render verts, faces, halos, strands
+- everything can change per frame/field
+
+3) Render Processor
+- multiple layers
+- tiles, rect, baking
+- layers/tiles optionally to disk or directly in Render Result
+
+4) Composit Render Result
+- also read external files etc
+
+5) Image Files
+- save file or append in movie
+
+*/
+
+
+/* ********* globals ******** */
+
+/* here we store all renders */
+static struct ListBase RenderList= {NULL, NULL};
+
+/* hardcopy of current render, used while rendering for speed */
+Render R;
+
+/* ********* alloc and free ******** */
+
+
+static SDL_mutex *malloc_lock= NULL;
+
+void *RE_mallocN(int len, char *name)
+{
+ void *mem;
+ if(malloc_lock) SDL_mutexP(malloc_lock);
+ mem= MEM_mallocN(len, name);
+ if(malloc_lock) SDL_mutexV(malloc_lock);
+ return mem;
+}
+void *RE_callocN(int len, char *name)
+{
+ void *mem;
+ if(malloc_lock) SDL_mutexP(malloc_lock);
+ mem= MEM_callocN(len, name);
+ if(malloc_lock) SDL_mutexV(malloc_lock);
+ return mem;
+}
+void RE_freeN(void *poin)
+{
+ if(malloc_lock) SDL_mutexP(malloc_lock);
+ MEM_freeN(poin);
+ if(malloc_lock) SDL_mutexV(malloc_lock);
+}
+
+/* ********************** */
+
+
+/* default callbacks, set in each new render */
+static void result_nothing(RenderResult *rr) {}
+static void result_rcti_nothing(RenderResult *rr, rcti *rect) {}
+static void stats_nothing(RenderStats *rs) {}
+static void int_nothing(int val) {}
+static int void_nothing(void) {return 0;}
+static void print_error(const char *str) {printf("ERROR: %s\n", str);}
+
+static void free_render_result(RenderResult *res)
+{
+ if(res==NULL) return;
+
+ while(res->layers.first) {
+ RenderLayer *rl= res->layers.first;
+ if(rl->rectf) RE_freeN(rl->rectf);
+ if(rl->rectz) RE_freeN(rl->rectz);
+ BLI_remlink(&res->layers, rl);
+ RE_freeN(rl);
+ }
+
+ if(res->rect32)
+ MEM_freeN(res->rect32);
+
+ RE_freeN(res);
+}
+
+/* called by main render as well for parts */
+/* will read info from Render *re to define layers */
+/* called in threads */
+/* winrct is coordinate rect of entire image, partrct the part within */
+static RenderResult *new_render_result(Render *re, rcti *partrct, int crop)
+{
+ RenderResult *rr;
+ RenderLayer *rl;
+ int rectx, recty;
+
+ rectx= partrct->xmax - partrct->xmin;
+ recty= partrct->ymax - partrct->ymin;
+
+ if(rectx<=0 || recty<=0)
+ return NULL;
+
+ rr= RE_callocN(sizeof(RenderResult), "new render result");
+ rr->rectx= rectx;
+ rr->recty= recty;
+ /* crop is one or two extra pixels rendered for filtering, is used for merging and display too */
+ rr->crop= crop;
+
+ /* tilerect is relative coordinates within render disprect. do not subtract crop yet */
+ rr->tilerect.xmin= partrct->xmin - re->disprect.xmin;
+ rr->tilerect.xmax= partrct->xmax - re->disprect.xmax;
+ rr->tilerect.ymin= partrct->ymin - re->disprect.ymin;
+ rr->tilerect.ymax= partrct->ymax - re->disprect.ymax;
+
+ /* check renderdata for amount of layers */
+ /* for now just one */
+ rl= RE_callocN(sizeof(RenderLayer), "new render layer");
+ BLI_addtail(&rr->layers, rl);
+
+ rl->rectf= RE_callocN(rectx*recty*sizeof(float)*4, "layer float rgba");
+ rl->rectz= RE_callocN(rectx*recty*sizeof(float), "layer float Z");
+
+ return rr;
+}
+
+#define FTOCHAR(val) val<=0.0f?0: (val>=1.0f?255: (char)(255.0f*val))
+/* caller is responsible for allocating rect in correct size! */
+void RE_ResultGet32(Render *re, unsigned int *rect)
+{
+ if(re->result) {
+ RenderLayer *rl= re->result->layers.first;
+ float *fp= rl->rectf;
+ if(fp) {
+ int tot= re->rectx*re->recty;
+ char *cp= (char *)rect;
+
+ for(;tot>0; tot--, cp+=4, fp+=4) {
+ cp[0] = FTOCHAR(fp[0]);
+ cp[1] = FTOCHAR(fp[1]);
+ cp[2] = FTOCHAR(fp[2]);
+ cp[3] = FTOCHAR(fp[3]);
+ }
+ return;
+ }
+ }
+ /* else fill with black */
+ memset(rect, sizeof(int)*re->rectx*re->recty, 0);
+}
+
+/* used when rendering to a full buffer, or when reading the exr part-layer-pass file */
+/* no test happens here if it fits... */
+/* is used within threads */
+static void merge_render_result(RenderResult *rr, RenderResult *rrpart)
+{
+ RenderLayer *rl= rr->layers.first;
+ RenderLayer *rlp= rrpart->layers.first;
+ float *rf, *rfp;
+ int *rz=NULL, *rzp;
+ int y, height, len, copylen;
+
+ if(rlp->rectf==NULL) return;
+ if(rl->rectf==NULL) return;
+
+ rzp= NULL; //rlp->rectz;
+ rfp= rlp->rectf;
+
+ copylen=len= rrpart->rectx;
+ height= rrpart->recty;
+
+ if(rrpart->crop) { /* filters add pixel extra */
+
+ if(rzp) rzp+= rrpart->crop + rrpart->crop*len;
+ if(rfp) rfp+= 4*(rrpart->crop + rrpart->crop*len);
+
+ copylen= len-2*rrpart->crop;
+ height -= 2*rrpart->crop;
+
+ // rz= re->rectz+ (pa->miny + rrpart->crop)*rr->rectx+ (pa->minx+rrpart->crop);
+ rf= rl->rectf+ ( (rrpart->tilerect.ymin + rrpart->crop)*rr->rectx + (rrpart->tilerect.xmin+rrpart->crop) )*4;
+ }
+ else {
+ // rz= re->rectz + (pa->disprect.ymin*rr->rectx + pa->disprect.xmin);
+ rf= rl->rectf+ (rrpart->tilerect.ymin*rr->rectx + rrpart->tilerect.xmin)*4;
+ }
+
+ for(y=0; y<height; y++) {
+ if(rzp) {
+ memcpy(rz, rzp, 4*copylen);
+ rz+= rr->rectx;
+ rzp+= len;
+ }
+ if(rfp) {
+ memcpy(rf, rfp, 16*copylen);
+ rf+= 4*rr->rectx;
+ rfp+= 4*len;
+ }
+ }
+}
+
+
+/* *************************************************** */
+
+Render *RE_GetRender(const char *name)
+{
+ Render *re;
+
+ /* search for existing renders */
+ for(re= RenderList.first; re; re= re->next) {
+ if(strncmp(re->name, name, RE_MAXNAME)==0) {
+ break;
+ }
+ }
+ return re;
+}
+
+RenderResult *RE_GetResult(Render *re)
+{
+ if(re)
+ return re->result;
+ return NULL;
+}
+
+RenderStats *RE_GetStats(Render *re)
+{
+ return &re->i;
+}
+
+Render *RE_NewRender(const char *name)
+{
+ Render *re;
+
+ /* only one render per name exists */
+ re= RE_GetRender(name);
+ if(re) {
+ BLI_remlink(&RenderList, re);
+ RE_FreeRender(re);
+ }
+
+ /* new render data struct */
+ re= RE_callocN(sizeof(Render), "new render");
+ BLI_addtail(&RenderList, re);
+ strncpy(re->name, name, RE_MAXNAME);
+
+ /* set default empty callbacks */
+ re->display_init= result_nothing;
+ re->display_clear= result_nothing;
+ re->display_draw= result_rcti_nothing;
+ re->timecursor= int_nothing;
+ re->test_break= void_nothing;
+ re->test_return= void_nothing;
+ re->error= print_error;
+ re->stats_draw= stats_nothing;
+
+ /* init some variables */
+ re->ycor= 1.0f;
+
+ return re;
+}
+
+/* only call this while you know it will remove the link too */
+void RE_FreeRender(Render *re)
+{
+
+ free_renderdata_tables(re);
+ free_sample_tables(re);
+
+ free_render_result(re->result);
+
+ BLI_remlink(&RenderList, re);
+ RE_freeN(re);
+}
+
+/* exit blender */
+void RE_FreeAllRender(void)
+{
+ while(RenderList.first) {
+ RE_FreeRender(RenderList.first);
+ }
+}
+
+/* ********* initialize state ******** */
+
+
+/* what doesn't change during entire render sequence */
+/* disprect is optional, if NULL it assumes full window render */
+void RE_InitState(Render *re, RenderData *rd, int winx, int winy, rcti *disprect)
+{
+ re->ok= TRUE; /* maybe flag */
+
+ re->i.starttime= PIL_check_seconds_timer();
+ re->r= *rd; /* hardcopy */
+
+ re->winx= winx;
+ re->winy= winy;
+ if(disprect) {
+ re->disprect= *disprect;
+ re->rectx= disprect->xmax-disprect->xmin;
+ re->recty= disprect->ymax-disprect->ymin;
+ }
+ else {
+ re->disprect.xmin= re->disprect.xmax= 0;
+ re->disprect.xmax= winx;
+ re->disprect.ymax= winy;
+ re->rectx= winx;
+ re->recty= winy;
+ }
+
+ if(re->rectx < 2 || re->recty < 2) {
+ re->error("Image too small");
+ re->ok= 0;
+ }
+ else {
+ /* check state variables, osa? */
+ if(re->r.mode & (R_OSA|R_MBLUR)) {
+ re->osa= re->r.osa;
+ if(re->osa>16) re->osa= 16;
+ }
+ else re->osa= 0;
+
+ /* always call, checks for gamma, gamma tables and jitter too */
+ make_sample_tables(re);
+
+ /* initialize render result */
+ free_render_result(re->result);
+ re->result= new_render_result(re, &re->disprect, 0);
+
+ }
+}
+
+void RE_SetDispRect (struct Render *re, rcti *disprect)
+{
+ re->disprect= *disprect;
+ re->rectx= disprect->xmax-disprect->xmin;
+ re->recty= disprect->ymax-disprect->ymin;
+
+ /* initialize render result */
+ free_render_result(re->result);
+ re->result= new_render_result(re, &re->disprect, 0);
+}
+
+void RE_SetWindow(Render *re, rctf *viewplane, float clipsta, float clipend)
+{
+ /* re->ok flag? */
+
+ re->viewplane= *viewplane;
+ re->clipsta= clipsta;
+ re->clipend= clipend;
+
+ i_window(re->viewplane.xmin, re->viewplane.xmax, re->viewplane.ymin, re->viewplane.ymax, re->clipsta, re->clipend, re->winmat);
+}
+
+void RE_SetOrtho(Render *re, rctf *viewplane, float clipsta, float clipend)
+{
+ /* re->ok flag? */
+
+ re->viewplane= *viewplane;
+ re->clipsta= clipsta;
+ re->clipend= clipend;
+ re->r.mode |= R_ORTHO;
+
+ i_ortho(re->viewplane.xmin, re->viewplane.xmax, re->viewplane.ymin, re->viewplane.ymax, re->clipsta, re->clipend, re->winmat);
+}
+
+void RE_SetView(Render *re, float mat[][4])
+{
+ /* re->ok flag? */
+ Mat4CpyMat4(re->viewmat, mat);
+ Mat4Invert(re->viewinv, re->viewmat);
+}
+
+/* image and movie output has to move to either imbuf or kernel */
+
+void RE_display_init_cb(Render *re, void (*f)(RenderResult *rr))
+{
+ re->display_init= f;
+}
+void RE_display_clear_cb(Render *re, void (*f)(RenderResult *rr))
+{
+ re->display_clear= f;
+}
+void RE_display_draw_cb(Render *re, void (*f)(RenderResult *rr, rcti *rect))
+{
+ re->display_draw= f;
+}
+
+void RE_stats_draw_cb(Render *re, void (*f)(RenderStats *rs))
+{
+ re->stats_draw= f;
+}
+void RE_timecursor_cb(Render *re, void (*f)(int))
+{
+ re->timecursor= f;
+}
+
+void RE_test_break_cb(Render *re, int (*f)(void))
+{
+ re->test_break= f;
+}
+void RE_test_return_cb(Render *re, int (*f)(void))
+{
+ re->test_return= f;
+}
+void RE_error_cb(Render *re, void (*f)(const char *str))
+{
+ re->error= f;
+}
+
+
+/* ********* add object data (later) ******** */
+
+/* object is considered fully prepared on correct time etc */
+/* includes lights */
+void RE_AddObject(Render *re, Object *ob)
+{
+
+}
+
+/* ********** basic thread control API ************ */
+
+#define RE_MAX_THREAD 4
+
+typedef struct ThreadSlot {
+ RenderPart *part;
+ int avail;
+} ThreadSlot;
+
+static ThreadSlot threadslots[RE_MAX_THREAD];
+
+static void init_threadslots(int tot)
+{
+ int a;
+
+ if(tot>RE_MAX_THREAD) tot= RE_MAX_THREAD;
+ else if(tot<1) tot= 1;
+
+ for(a=0; a< RE_MAX_THREAD; a++) {
+ threadslots[a].part= NULL;
+ if(a<tot)
+ threadslots[a].avail= 1;
+ else
+ threadslots[a].avail= 0;
+ }
+}
+
+static int available_threadslots(void)
+{
+ int a, counter=0;
+ for(a=0; a< RE_MAX_THREAD; a++)
+ if(threadslots[a].avail)
+ counter++;
+ return counter;
+}
+
+static void insert_threadslot(RenderPart *pa)
+{
+ int a;
+ for(a=0; a< RE_MAX_THREAD; a++) {
+ if(threadslots[a].avail) {
+ threadslots[a].avail= 0;
+ threadslots[a].part= pa;
+ pa->thread= a;
+ break;
+ }
+ }
+}
+
+static void remove_threadslot(RenderPart *pa)
+{
+ int a;
+ for(a=0; a< RE_MAX_THREAD; a++) {
+ if(threadslots[a].part==pa) {
+ threadslots[a].avail= 1;
+ threadslots[a].part= NULL;
+ }
+ }
+}
+
+/* ********** basic thread control API ************ */
+
+static int do_part_thread(void *pa_v)
+{
+ RenderPart *pa= pa_v;
+
+ /* need to return nicely all parts on esc */
+ if(R.test_break()==0) {
+
+ pa->result= new_render_result(&R, &pa->disprect, pa->crop);
+
+ if(R.osa)
+ zbufshadeDA_tile(pa);
+ else
+ zbufshade_tile(pa);
+
+ if(!R.test_break())
+ merge_render_result(R.result, pa->result);
+ }
+
+ pa->ready= 1;
+ remove_threadslot(pa);
+
+ return 0;
+}
+
+/* returns with render result filled, not threaded */
+static void render_tile_processor(Render *re)
+{
+ RenderPart *pa;
+
+ if(re->test_break())
+ return;
+
+ re->i.lastframetime= PIL_check_seconds_timer()- re->i.starttime;
+ re->stats_draw(&re->i);
+ re->i.starttime= PIL_check_seconds_timer();
+
+ if(re->result==NULL)
+ return;
+
+ initparts(re);
+
+ /* assuming no new data gets added to dbase... */
+ R= *re;
+
+ for(pa= re->parts.first; pa; pa= pa->next) {
+ do_part_thread(pa);
+
+ if(pa->result) {
+ if(!re->test_break()) {
+ re->display_draw(pa->result, NULL);
+ re->i.partsdone++;
+ }
+ free_render_result(pa->result);
+ pa->result= NULL;
+ }
+ if(re->test_break())
+ break;
+ }
+
+ re->i.lastframetime= PIL_check_seconds_timer()- re->i.starttime;
+ re->stats_draw(&re->i);
+
+ freeparts(re);
+}
+
+static RenderPart *find_nicest_part(Render *re)
+{
+ RenderPart *pa, *best= NULL;
+ int centx=re->winx/2, centy=re->winy/2, tot=1;
+ int mindist, distx, disty;
+
+ /* find center of rendered parts, image center counts for 1 too */
+ for(pa= re->parts.first; pa; pa= pa->next) {
+ if(pa->ready) {
+ centx+= (pa->disprect.xmin+pa->disprect.xmax)/2;
+ centy+= (pa->disprect.ymin+pa->disprect.ymax)/2;
+ tot++;
+ }
+ }
+ centx/=tot;
+ centy/=tot;
+
+ /* closest of the non-rendering parts */
+ mindist= re->winx*re->winy;
+ for(pa= re->parts.first; pa; pa= pa->next) {
+ if(pa->ready==0 && pa->nr==0) {
+ distx= centx - (pa->disprect.xmin+pa->disprect.xmax)/2;
+ disty= centy - (pa->disprect.ymin+pa->disprect.ymax)/2;
+ distx= (int)sqrt(distx*distx + disty*disty);
+ if(distx<mindist) {
+ best= pa;
+ mindist= distx;
+ }
+ }
+ }
+ return best;
+}
+
+static void threaded_tile_processor(Render *re)
+{
+ RenderPart *pa;
+ int maxthreads=2, rendering=1, counter= 1;
+
+ if(re->result==NULL)
+ return;
+ if(re->test_break())
+ return;
+
+ initparts(re);
+ init_threadslots(maxthreads);
+
+ /* assuming no new data gets added to dbase... */
+ R= *re;
+
+ malloc_lock = SDL_CreateMutex();
+
+ while(rendering) {
+
+ /* I noted that test_break() in a thread doesn't make ghost send ESC */
+ if(available_threadslots() && !re->test_break()) {
+ pa= find_nicest_part(re);
+ if(pa) {
+ insert_threadslot(pa);
+ pa->nr= counter++; /* only for stats */
+ SDL_CreateThread(do_part_thread, pa);
+ }
+ }
+ else
+ PIL_sleep_ms(50);
+
+ /* check for ready ones to display, and if we need to continue */
+ rendering= 0;
+ for(pa= re->parts.first; pa; pa= pa->next) {
+ if(pa->ready) {
+ if(pa->result) {
+ re->display_draw(pa->result, NULL);
+ free_render_result(pa->result);
+ pa->result= NULL;
+ re->i.partsdone++;
+ }
+ }
+ else rendering= 1;
+ }
+
+ /* on break, wait for all slots to get freed */
+ if(re->test_break() && available_threadslots()==maxthreads)
+ rendering= 0;
+
+ }
+
+ if(malloc_lock) SDL_DestroyMutex(malloc_lock); malloc_lock= NULL;
+
+ freeparts(re);
+}
+
+void RE_TileProcessor(Render *re)
+{
+ if(re->r.mode & R_THREADS)
+ threaded_tile_processor(re);
+ else
+ render_tile_processor(re);
+}
+
+
+/* ************ This part uses API, for rendering Blender scenes ********** */
+
+void render_one_frame(Render *re)
+{
+
+// re->cfra= cfra; /* <- unused! */
+
+ /* make render verts/faces/halos/lamps */
+ RE_Database_FromScene(re, re->scene, 1);
+
+ RE_TileProcessor(re);
+
+ /* free all render verts etc */
+ RE_Database_Free(re);
+}
+
+/* accumulates osa frames */
+static void do_render_blurred(Render *re, float frame)
+{
+
+}
+
+/* interleaves 2 frames */
+static void do_render_fields(Render *re)
+{
+
+}
+
+static void do_render_final(Render *re, Scene *scene)
+{
+ if(re->r.scemode & R_DOSEQ) {
+ re->result->rect32= MEM_callocN(sizeof(int)*re->rectx*re->recty, "rectot");
+ if(!re->test_break())
+ do_render_seq(re->result);
+ }
+ else {
+
+ re->scene= scene;
+
+ /* now use renderdata and camera to set viewplane */
+ RE_SetCamera(re, re->scene->camera);
+
+ if(re->r.mode & R_FIELDS)
+ do_render_fields(re);
+ else if(re->r.mode & R_MBLUR)
+ do_render_blurred(re, re->scene->r.cfra);
+ else
+ render_one_frame(re);
+ }
+
+
+ re->i.lastframetime= PIL_check_seconds_timer()- re->i.starttime;
+ re->stats_draw(&re->i);
+
+ re->display_draw(re->result, NULL);
+
+}
+
+
+static int is_rendering_allowed(Render *re)
+{
+
+ /* forbidden combinations */
+ if(re->r.mode & R_PANORAMA) {
+ if(re->r.mode & R_BORDER) {
+ re->error("No border supported for Panorama");
+ return 0;
+ }
+ if(re->r.yparts>1) {
+ re->error("No Y-Parts supported for Panorama");
+ return 0;
+ }
+ if(re->r.mode & R_ORTHO) {
+ re->error("No Ortho render possible for Panorama");
+ return 0;
+ }
+ }
+
+ if(re->r.mode & R_BORDER) {
+ if(re->r.border.xmax <= re->r.border.xmin ||
+ re->r.border.ymax <= re->r.border.ymin) {
+ re->error("No border area selected.");
+ return 0;
+ }
+ }
+
+ if(re->r.xparts*re->r.yparts>=2 && (re->r.mode & R_MOVIECROP) && (re->r.mode & R_BORDER)) {
+ re->error("Combination of border, crop and parts not allowed");
+ return 0;
+ }
+
+ if(re->r.xparts*re->r.yparts>64) {
+ re->error("No more than 64 parts supported");
+ return 0;
+ }
+
+ if(re->r.yparts>1 && (re->r.mode & R_PANORAMA)) {
+ re->error("No Y-Parts supported for Panorama");
+ return 0;
+ }
+
+ /* check valid camera */
+ if(re->scene->camera==NULL)
+ re->scene->camera= scene_find_camera(re->scene);
+ if(re->scene->camera==NULL) {
+ re->error("No camera");
+ return 0;
+ }
+
+
+ return 1;
+}
+
+/* evaluating scene options for general Blender render */
+static int render_initialize_from_scene(Render *re, Scene *scene)
+{
+ int winx, winy;
+ rcti disprect;
+
+ /* r.xsch and r.ysch has the actual view window size
+ r.border is the clipping rect */
+
+ /* calculate actual render result and display size */
+ winx= (scene->r.size*scene->r.xsch)/100;
+ winy= (scene->r.size*scene->r.ysch)/100;
+ // if(scene->r.mode & R_PANORAMA)
+ // winx*= scene->r.xparts;
+
+ /* only in movie case we render smaller part */
+ if(scene->r.mode & R_BORDER) {
+ disprect.xmin= scene->r.border.xmin*winx;
+ disprect.xmax= scene->r.border.xmax*winx;
+
+ disprect.ymin= scene->r.border.ymin*winy;
+ disprect.ymax= scene->r.border.ymax*winy;
+ }
+ else {
+ disprect.xmin= disprect.ymin= 0;
+ disprect.xmax= winx;
+ disprect.ymax= winy;
+ }
+
+ RE_InitState(re, &scene->r, winx, winy, &disprect);
+
+ re->scene= scene;
+ if(!is_rendering_allowed(re))
+ return 0;
+
+ re->display_init(re->result);
+ re->display_clear(re->result);
+
+ return 1;
+}
+
+/* general Blender frame render call */
+/* should return 1 when all is OK, otherwise it throws up errors */
+void RE_BlenderFrame(Render *re, Scene *scene, int frame)
+{
+ /* ugly global still... is to prevent renderwin events and signal subsurfs etc to make full resol */
+ /* is also set by caller renderwin.c */
+ G.rendering= 1;
+
+ if(render_initialize_from_scene(re, scene)) {
+ do_render_final(re, scene);
+ }
+}
+
+
+/* saves images to disk */
+void RE_BlenderAnim(Render *re, Scene *scene, int sfra, int efra)
+{
+ bMovieHandle *mh= BKE_get_movie_handle(scene->r.imtype);
+ int cfrao= scene->r.cfra;
+ char name[FILE_MAXDIR+FILE_MAXFILE];
+
+ /* ugly global still... is to prevent renderwin events and signal subsurfs etc to make full resol */
+ /* is also set by caller renderwin.c */
+ G.rendering= 1;
+
+ if(!render_initialize_from_scene(re, scene))
+ return;
+
+ if(BKE_imtype_is_movie(scene->r.imtype))
+ mh->start_movie(&G.scene->r, re->rectx, re->recty);
+
+ for(scene->r.cfra= sfra; scene->r.cfra<=efra; G.scene->r.cfra++) {
+
+ do_render_final(re, scene);
+
+ /* write image or movie */
+ if(re->test_break()==0) {
+ RenderResult *rr= re->result;
+ RenderLayer *rl= rr->layers.first;
+
+ /* write movie or image */
+ if(BKE_imtype_is_movie(scene->r.imtype)) {
+ if(rr->rect32==NULL) {
+ rr->rect32= MEM_mallocN(sizeof(int)*rr->rectx*rr->recty, "temp 32 bits rect");
+ }
+ RE_ResultGet32(re, rr->rect32);
+ mh->append_movie(scene->r.cfra, rr->rect32, rr->rectx, rr->recty);
+ printf("Append frame %d", scene->r.cfra);
+ }
+ else {
+ ImBuf *ibuf= IMB_allocImBuf(rr->rectx, rr->recty, scene->r.planes, 0, 0);
+ int ok;
+
+ BKE_makepicstring(name, (scene->r.cfra));
+ ibuf->rect= rr->rect32; /* if not exists, BKE_write_ibuf makes one */
+ ibuf->rect_float= rl->rectf;
+ ibuf->zbuf_float= rl->rectz;
+ ok= BKE_write_ibuf(ibuf, name, scene->r.imtype, scene->r.subimtype, scene->r.quality);
+ IMB_freeImBuf(ibuf); /* imbuf knows which rects are not part of ibuf */
+
+ if(ok==0) {
+ printf("Render error: cannot save %s\n", name);
+ break;
+ }
+ else printf("Saved: %s", name);
+ }
+
+ BLI_timestr(re->i.lastframetime, name);
+ printf(" Time: %s\n", name);
+ fflush(stdout); /* needed for renderd !! (not anymore... (ton)) */
+ }
+
+ if(G.afbreek==1) break;
+ }
+
+ /* end movie */
+ if(BKE_imtype_is_movie(scene->r.imtype))
+ mh->end_movie();
+
+ scene->r.cfra= cfrao;
+}
+
+
+
diff --git a/source/blender/render/intern/source/pixelblending.c b/source/blender/render/intern/source/pixelblending.c
index f774a624ba9..73a8e86bc95 100644
--- a/source/blender/render/intern/source/pixelblending.c
+++ b/source/blender/render/intern/source/pixelblending.c
@@ -6,15 +6,12 @@
*
* $Id$
*
- * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
+ * ***** BEGIN GPL 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.
+ * of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
@@ -28,29 +25,29 @@
* The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
* All rights reserved.
*
- * The Original Code is: all of this file.
+ * Contributor(s): Full recode, 2004-2006 Blender Foundation
*
- * Contributor(s): none yet.
- *
- * ***** END GPL/BL DUAL LICENSE BLOCK *****
+ * ***** END GPL LICENSE BLOCK *****
*/
#include <math.h>
/* global includes */
-#include "render.h"
-
-/* local includes */
-#include "vanillaRenderPipe_types.h"
+#include "BLI_arithb.h"
+#include "BLI_rand.h"
/* own includes */
+#include "render_types.h"
+#include "renderpipeline.h"
#include "pixelblending.h"
#include "gammaCorrectionTables.h"
-/* externals */
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
+/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
+/* defined in pipeline.c, is hardcopy of active dynamic allocated Render */
+/* only to be used here in this file, it's for speed */
+extern struct Render R;
+/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
+
/* ------------------------------------------------------------------------- */
/* Debug/behaviour defines */
@@ -72,88 +69,6 @@
#define RE_EMPTY_COLOUR_FLOAT 0.0002
-/* functions --------------------------------------------------------------- */
-
-/*
- One things about key-alpha is that simply dividing by the alpha will
- sometimes cause 'overflows' in that the pixel colours will be shot
- way over full colour. This should be caught, and subsequently, the
- operation will end up modifying the alpha as well.
-
- Actually, when the starting colour is premul, it shouldn't overflow
- ever. Strange thing is that colours keep overflowing...
-
-*/
-void applyKeyAlphaCharCol(char* target) {
-
- if ((!(target[3] == 0))
- || (target[3] == 255)) {
- /* else: nothing to do */
- /* check whether div-ing is enough */
- float cf[4];
- cf[0] = target[0]/target[3];
- cf[1] = target[1]/target[3];
- cf[2] = target[2]/target[3];
- if ((cf[0] <= 1.0) && (cf[1] <= 1.0) && (cf[2] <= 1.0)) {
- /* all colours remain properly scaled? */
- /* scale to alpha */
- cf[0] = (float) target[0] * (255.0/ (float)target[3]);
- cf[1] = (float) target[1] * (255.0/ (float)target[3]);
- cf[2] = (float) target[2] * (255.0/ (float)target[3]);
-
- /* Clipping is important. */
- target[0] = (cf[0] > 255.0 ? 255 : (char) cf[0]);
- target[1] = (cf[1] > 255.0 ? 255 : (char) cf[1]);
- target[2] = (cf[2] > 255.0 ? 255 : (char) cf[2]);
-
- } else {
- /* shouldn't happen! we were premul, remember? */
-/* should go to error handler: printf("Non-premul colour detected\n"); */
- }
- }
-
-}
-
-/* ------------------------------------------------------------------------- */
-
-void addAddSampColF(float *sampvec, float *source, int mask, int osaNr,
- char addfac)
-{
- int a;
-
- for(a=0; a < osaNr; a++) {
- if(mask & (1<<a)) addalphaAddfacFloat(sampvec, source, addfac);
- sampvec+= 4;
- }
-}
-
-/* ------------------------------------------------------------------------- */
-
-void addOverSampColF(float *sampvec, float *source, int mask, int osaNr)
-{
- int a;
-
- for(a=0; a < osaNr; a++) {
- if(mask & (1<<a)) addAlphaOverFloat(sampvec, source);
- sampvec+= 4;
- }
-}
-
-/* ------------------------------------------------------------------------- */
-
-int addUnderSampColF(float *sampvec, float *source, int mask, int osaNr)
-{
- int a, retval = osaNr;
-
- for(a=0; a < osaNr; a++) {
- if(mask & (1<<a)) addAlphaUnderFloat(sampvec, source);
- if(sampvec[3] > RE_FULL_COLOUR_FLOAT) retval--;
- sampvec+= 4;
- }
- return retval;
-}
-
-
/* ------------------------------------------------------------------------- */
void addAlphaOverFloat(float *dest, float *source)
@@ -211,106 +126,6 @@ void addAlphaUnderFloat(float *dest, float *source)
}
-/* ------------------------------------------------------------------------- */
-
-void cpShortColV2CharColV(unsigned short *source, char *dest)
-{
- dest[0] = source[0]>>8;
- dest[1] = source[1]>>8;
- dest[2] = source[2]>>8;
- dest[3] = source[3]>>8;
-}
-/* ------------------------------------------------------------------------- */
-
-void cpCharColV2ShortColV(char *source, unsigned short *dest)
-{
- dest[0] = source[0]<<8;
- dest[1] = source[1]<<8;
- dest[2] = source[2]<<8;
- dest[3] = source[3]<<8;
-}
-
-/* ------------------------------------------------------------------------- */
-
-void cpIntColV2CharColV(unsigned int *source, char *dest)
-{
- dest[0] = source[0]>>24;
- dest[1] = source[1]>>24;
- dest[2] = source[2]>>24;
- dest[3] = source[3]>>24;
-}
-
-/* ------------------------------------------------------------------------- */
-
-void cpCharColV2FloatColV(char *source, float *dest)
-{
- dest[0] = source[0]/255.0;
- dest[1] = source[1]/255.0;
- dest[2] = source[2]/255.0;
- dest[3] = source[3]/255.0;
-}
-
-/* ------------------------------------------------------------------------- */
-
-void cpShortColV2FloatColV(unsigned short *source, float *dest)
-{
- dest[0] = source[0]/65535.0;
- dest[1] = source[1]/65535.0;
- dest[2] = source[2]/65535.0;
- dest[3] = source[3]/65535.0;
-}
-
-/* ------------------------------------------------------------------------- */
-
-void cpFloatColV2CharColV(float* source, char *dest)
-{
- /* can't this be done more efficient? hope the conversions are correct... */
- if (source[0] < 0.0) dest[0] = 0;
- else if (source[0] > 1.0) dest[0] = 255;
- else dest[0] = (char) (source[0] * 255.0);
-
- if (source[1] < 0.0) dest[1] = 0;
- else if (source[1] > 1.0) dest[1] = 255;
- else dest[1] = (char) (source[1] * 255.0);
-
- if (source[2] < 0.0) dest[2] = 0;
- else if (source[2] > 1.0) dest[2] = 255;
- else dest[2] = (char) (source[2] * 255.0);
-
- if (source[3] < 0.0) dest[3] = 0;
- else if (source[3] > 1.0) dest[3] = 255;
- else dest[3] = (char) (source[3] * 255.0);
-
-}
-
-/* ------------------------------------------------------------------------- */
-
-void cpShortColV(unsigned short *source, unsigned short *dest)
-{
- dest[0] = source[0];
- dest[1] = source[1];
- dest[2] = source[2];
- dest[3] = source[3];
-}
-
-/* ------------------------------------------------------------------------- */
-void cpFloatColV(float *source, float *dest)
-{
- dest[0] = source[0];
- dest[1] = source[1];
- dest[2] = source[2];
- dest[3] = source[3];
-}
-
-/* ------------------------------------------------------------------------- */
-
-void cpCharColV(char *source, char *dest)
-{
- dest[0] = source[0];
- dest[1] = source[1];
- dest[2] = source[2];
- dest[3] = source[3];
-}
/* ------------------------------------------------------------------------- */
void addalphaAddfacFloat(float *dest, float *source, char addfac)
@@ -353,43 +168,27 @@ void addalphaAddfacFloat(float *dest, float *source, char addfac)
}
-/* ------------------------------------------------------------------------- */
-
-void sampleShortColV2ShortColV(unsigned short *sample, unsigned short *dest, int osaNr)
-{
- unsigned int intcol[4] = {0};
- unsigned short *scol = sample;
- int a = 0;
-
- for(a=0; a < osaNr; a++, scol+=4) {
- intcol[0]+= scol[0]; intcol[1]+= scol[1];
- intcol[2]+= scol[2]; intcol[3]+= scol[3];
- }
-
- /* Now normalise the integrated colour. It is guaranteed */
- /* to be correctly bounded. */
- dest[0]= intcol[0]/osaNr;
- dest[1]= intcol[1]/osaNr;
- dest[2]= intcol[2]/osaNr;
- dest[3]= intcol[3]/osaNr;
-
-}
/* ------------------------------------------------------------------------- */
/* filtered adding to scanlines */
-void add_filt_fmask(unsigned int mask, float *col, float *rb1, float *rb2, float *rb3)
+void add_filt_fmask(unsigned int mask, float *col, float *rowbuf, int row_w)
{
/* calc the value of mask */
- extern float *fmask1[], *fmask2[];
+ float **fmask1= R.samples->fmask1, **fmask2=R.samples->fmask2;
+ float *rb1, *rb2, *rb3;
float val, r, g, b, al;
unsigned int a, maskand, maskshift;
int j;
- al= col[3];
r= col[0];
g= col[1];
b= col[2];
+ al= col[3];
+
+ rb2= rowbuf-4;
+ rb1= rb2-4*row_w;
+ rb3= rb2+4*row_w;
maskand= (mask & 255);
maskshift= (mask >>8);
@@ -400,28 +199,28 @@ void add_filt_fmask(unsigned int mask, float *col, float *rb1, float *rb2, float
val= *(fmask1[a] +maskand) + *(fmask2[a] +maskshift);
if(val!=0.0) {
- rb1[3]+= val*al;
rb1[0]+= val*r;
rb1[1]+= val*g;
rb1[2]+= val*b;
+ rb1[3]+= val*al;
}
a+=3;
val= *(fmask1[a] +maskand) + *(fmask2[a] +maskshift);
if(val!=0.0) {
- rb2[3]+= val*al;
rb2[0]+= val*r;
rb2[1]+= val*g;
rb2[2]+= val*b;
+ rb2[3]+= val*al;
}
a+=3;
val= *(fmask1[a] +maskand) + *(fmask2[a] +maskshift);
if(val!=0.0) {
- rb3[3]+= val*al;
rb3[0]+= val*r;
rb3[1]+= val*g;
rb3[2]+= val*b;
+ rb3[3]+= val*al;
}
rb1+= 4;
@@ -430,186 +229,6 @@ void add_filt_fmask(unsigned int mask, float *col, float *rb1, float *rb2, float
}
}
-
-void sampleFloatColV2FloatColVFilter(float *sample, float *dest1, float *dest2, float *dest3, int osaNr)
-{
- float intcol[4] = {0};
- float *scol = sample;
- int a = 0;
-
- if(osaNr==1) {
- dest2[4]= sample[0];
- dest2[5]= sample[1];
- dest2[6]= sample[2];
- dest2[7]= sample[3];
- }
- else {
- if (do_gamma) {
- /* use a LUT and interpolation to do the gamma correction */
- for(a=0; a < osaNr; a++, scol+=4) {
- intcol[0] = gammaCorrect( (scol[0]<1.0) ? scol[0]:1.0 );
- intcol[1] = gammaCorrect( (scol[1]<1.0) ? scol[1]:1.0 );
- intcol[2] = gammaCorrect( (scol[2]<1.0) ? scol[2]:1.0 );
- intcol[3] = scol[3];
- add_filt_fmask(1<<a, intcol, dest1, dest2, dest3);
- }
- }
- else {
- for(a=0; a < osaNr; a++, scol+=4) {
- add_filt_fmask(1<<a, scol, dest1, dest2, dest3);
- }
- }
- }
-
-}
-
-/* ------------------------------------------------------------------------- */
-/* The following functions are 'old' blending functions: */
-
-/* ------------------------------------------------------------------------- */
-void keyalpha(char *doel) /* makes premul 255 */
-{
- int c;
- short div;
- div= doel[3];
- if (!div)
- {
- doel[0] = (doel[0] ? 255 : 0);
- doel[1] = (doel[1] ? 255 : 0);
- doel[2] = (doel[2] ? 255 : 0);
- } else
- {
- c= (doel[0]<<8)/div;
- if(c>255) doel[0]=255;
- else doel[0]= c;
- c= (doel[1]<<8)/div;
- if(c>255) doel[1]=255;
- else doel[1]= c;
- c= (doel[2]<<8)/div;
- if(c>255) doel[2]=255;
- else doel[2]= c;
- }
-}
-
-/* ------------------------------------------------------------------------- */
-/* fills in bron (source) under doel (target) with alpha of doel*/
-void addalphaUnder(char *doel, char *bron)
-{
- int c;
- int mul;
-
- if(doel[3]==255) return;
- if( doel[3]==0) { /* tested */
- *((unsigned int *)doel)= *((unsigned int *)bron);
- return;
- }
-
- mul= 255-doel[3];
-
- c= doel[0]+ ((mul*bron[0])/255);
- if(c>255) doel[0]=255;
- else doel[0]= c;
- c= doel[1]+ ((mul*bron[1])/255);
- if(c>255) doel[1]=255;
- else doel[1]= c;
- c= doel[2]+ ((mul*bron[2])/255);
- if(c>255) doel[2]=255;
- else doel[2]= c;
-
- c= doel[3]+ ((mul*bron[3])/255);
- if(c>255) doel[3]=255;
- else doel[3]= c;
-
- /* doel[0]= MAX2(doel[0], bron[0]); */
-}
-
-/* ------------------------------------------------------------------------- */
-/* gamma-corrected */
-void addalphaUnderGamma(char *doel, char *bron)
-{
- unsigned int tot;
- int c, doe, bro;
- int mul;
-
- /* if doel[3]==0 or doel==255 has been handled in sky loop */
- mul= 256-doel[3];
-
- doe= igamtab1[(int)doel[0]];
- bro= igamtab1[(int)bron[0]];
- tot= (doe+ ((mul*bro)>>8));
- if(tot>65535) tot=65535;
- doel[0]= *((gamtab+tot)) >>8;
-
- doe= igamtab1[(int)doel[1]];
- bro= igamtab1[(int)bron[1]];
- tot= (doe+ ((mul*bro)>>8));
- if(tot>65535) tot=65535;
- doel[1]= *((gamtab+tot)) >>8;
-
- doe= igamtab1[(int)doel[2]];
- bro= igamtab1[(int)bron[2]];
- tot= (doe+ ((mul*bro)>>8));
- if(tot>65535) tot=65535;
- doel[2]= *((gamtab+tot)) >>8;
-
- c= doel[3]+ ((mul*bron[3])/255);
- if(c>255) doel[3]=255;
- else doel[3]= c;
- /* doel[0]= MAX2(doel[0], bron[0]); */
-}
-
-/* ------------------------------------------------------------------------- */
-/* doel= bron over doel */
-void addalphaOver(char *doel, char *bron)
-{
- int c;
- int mul;
-
- if(bron[3]==0) return;
- if( bron[3]==255) { /* tested */
- *((unsigned int *)doel)= *((unsigned int *)bron);
- return;
- }
-
- mul= 255-bron[3];
-
- c= ((mul*doel[0])/255)+bron[0];
- if(c>255) doel[0]=255;
- else doel[0]= c;
- c= ((mul*doel[1])/255)+bron[1];
- if(c>255) doel[1]=255;
- else doel[1]= c;
- c= ((mul*doel[2])/255)+bron[2];
- if(c>255) doel[2]=255;
- else doel[2]= c;
- c= ((mul*doel[3])/255)+bron[3];
- if(c>255) doel[3]=255;
- else doel[3]= c;
-}
-
-/* ------------------------------------------------------------------------- */
-void addalphaAdd(char *doel, char *bron) /* adds bron (source) to doel (target) */
-{
- int c;
-
- if( doel[3]==0 || bron[3]==255) { /* tested */
- *((unsigned int *)doel)= *((unsigned int *)bron);
- return;
- }
- c= doel[0]+bron[0];
- if(c>255) doel[0]=255;
- else doel[0]= c;
- c= doel[1]+bron[1];
- if(c>255) doel[1]=255;
- else doel[1]= c;
- c= doel[2]+bron[2];
- if(c>255) doel[2]=255;
- else doel[2]= c;
- c= doel[3]+bron[3];
- if(c>255) doel[3]=255;
- else doel[3]= c;
-}
-
/* ------------------------------------------------------------------------- */
void addalphaAddFloat(float *dest, float *source)
{
@@ -631,44 +250,136 @@ void addalphaAddFloat(float *dest, float *source)
}
-/* ALPHADDFAC:
- *
- * Z= X alphaover Y:
- * Zrgb= (1-Xa)*Yrgb + Xrgb
- *
- * (1-fac)*(1-Xa) + fac <=>
- * 1-Xa-fac+fac*Xa+fac <=>
- * Xa*(fac-1)+1
- */
+/* ------------------------------------------------------------------------- */
/* ------------------------------------------------------------------------- */
-/* doel= bron over doel */
-void RE_addalphaAddfac(char *doel, char *bron, char addfac)
+/* Colour buffer related: */
+/* This transforms the 4 inputvalues RE_COLBUFTYPE to a new value */
+/* It expects the values R.r.postigamma, R.r.postmul and R.r.postadd. */
+/* This is the standard transformation, more elaborate tools are for later. */
+/* ------------------------------------------------------------------------- */
+void std_floatcol_to_charcol( float *buf, char *target)
{
+ float col[3];
+
+ float dither_value;
+
+ dither_value = ((BLI_frand()-0.5)*R.r.dither_intensity)/256.0;
- int c, mul;
-
- mul= 255 - (bron[3]*(255-addfac))/255;
-
- c= ((mul*doel[0])/255)+bron[0];
- if(c>255) doel[0]=255;
- else doel[0]= c;
- c= ((mul*doel[1])/255)+bron[1];
- if(c>255) doel[1]=255;
- else doel[1]= c;
- c= ((mul*doel[2])/255)+bron[2];
- if(c>255) doel[2]=255;
- else doel[2]= c;
+ /* alpha */
+ if((buf[3]+dither_value)<=0.0) target[3]= 0;
+ else if((buf[3]+dither_value)>1.0) target[3]= 255;
+ else target[3]= 255.0*(buf[3]+dither_value);
+
+ if(R.r.postgamma==1.0) {
+ /* r */
+ col[0]= R.r.postmul*buf[0] + R.r.postadd + dither_value;
+ /* g */
+ col[1]= R.r.postmul*buf[1] + R.r.postadd + dither_value;
+ /* b */
+ col[2]= R.r.postmul*buf[2] + R.r.postadd + dither_value;
+ }
+ else {
+ /* putting the postmul within the pow() gives an
+ * easier control for the user, values from 1.0-2.0
+ * are relevant then
+ */
+
+ /* r */
+ col[0]= pow(R.r.postmul*buf[0], R.r.postigamma) + R.r.postadd + dither_value;
+ /* g */
+ col[1]= pow( R.r.postmul*buf[1], R.r.postigamma) + R.r.postadd + dither_value;
+ /* b */
+ col[2]= pow(R.r.postmul*buf[2], R.r.postigamma) + R.r.postadd + dither_value;
+ }
- /* c= ((mul*doel[3])/255)+bron[3]; */
- c= doel[3]+bron[3];
- if(c>255) doel[3]=255;
- else doel[3]= c;
+ if(R.r.posthue!=0.0 || R.r.postsat!=1.0) {
+ float hsv[3];
+
+ rgb_to_hsv(col[0], col[1], col[2], hsv, hsv+1, hsv+2);
+ hsv[0]+= R.r.posthue;
+ if(hsv[0]>1.0) hsv[0]-=1.0; else if(hsv[0]<0.0) hsv[0]+= 1.0;
+ hsv[1]*= R.r.postsat;
+ if(hsv[1]>1.0) hsv[1]= 1.0; else if(hsv[1]<0.0) hsv[1]= 0.0;
+ hsv_to_rgb(hsv[0], hsv[1], hsv[2], col, col+1, col+2);
+ }
+
+ if(col[0]<=0.0) target[0]= 0;
+ else if(col[0]>1.0) target[0]= 255;
+ else target[0]= 255.0*col[0];
+
+ if(col[1]<=0.0) target[1]= 0;
+ else if(col[1]>1.0) target[1]= 255;
+ else target[1]= 255.0*col[1];
+
+ if(col[2]<=0.0) target[2]= 0;
+ else if(col[2]>1.0) target[2]= 255;
+ else target[2]= 255.0*col[2];
}
+/* ----------------------------------------------------------------------------
+
+Colour buffer related:
+
+The colour buffer is a buffer of a single screen line. It contains
+four fields of type RE_COLBUFTYPE per pixel.
+
+We can do several post-process steps. I would prefer to move them outside
+the render module later on, but it's ok to leave it here for now. For the
+time being, we have:
+- post-process function
+ Does some operations with the colours.
+- Multiply with some factor
+- Add constant offset
+- Apply extra gamma correction (seems weird...)
+- key-alpha correction
+ Key alpha means 'un-applying' the alpha. For fully covered pixels, this
+ operation has no effect.
+
+- XXX WARNING! Added the inverse render gamma here, so this cannot be used external
+ without setting Osa or Gamma flags off (ton)
+
+---------------------------------------------------------------------------- */
+/* used external! */
+void transferColourBufferToOutput( float *buf, int y)
+{
+ /* Copy the contents of AColourBuffer3 to R.rectot + y * R.rectx */
+ int x = 0;
+// char *target = (char*) (R.rectot + (y * R.rectx));
+
+ /* Copy the first <R.rectx> pixels. We can do some more clipping on */
+ /* the z buffer, I think. */
+ while (x < R.rectx) {
+
+
+ /* invert gamma corrected additions */
+ if(R.do_gamma) {
+ buf[0] = invGammaCorrect(buf[0]);
+ buf[1] = invGammaCorrect(buf[1]);
+ buf[2] = invGammaCorrect(buf[2]);
+ }
+
+// std_floatcol_to_charcol(buf, target);
+
+ /*
+ Key-alpha mode:
+ Need to un-apply alpha if alpha is non-full. For full alpha,
+ the operation doesn't have effect. Do this after the post-
+ processing, so we can still use the benefits of that.
+
+ */
+
+ if (R.r.alphamode == R_ALPHAKEY) {
+// applyKeyAlphaCharCol(target);
+ }
+
+// target+=4;
+ buf+=4;
+ x++;
+ }
+}
-/* ------------------------------------------------------------------------- */
/* eof pixelblending.c */
diff --git a/source/blender/render/intern/source/pixelshading.c b/source/blender/render/intern/source/pixelshading.c
index 4878b738767..53bce2cbb84 100644
--- a/source/blender/render/intern/source/pixelshading.c
+++ b/source/blender/render/intern/source/pixelshading.c
@@ -1,14 +1,11 @@
/**
*
- * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
+ * ***** BEGIN GPL 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.
+ * of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
@@ -22,17 +19,9 @@
* The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
* All rights reserved.
*
- * The Original Code is: all of this file.
- *
- * Contributor(s): none yet.
- *
- * ***** END GPL/BL DUAL LICENSE BLOCK *****
- * Shading of pixels
- *
- * 11-09-2000 nzc
- *
- * $Id$
+ * Contributor(s): 2004-2006, Blender Foundation, full recode
*
+ * ***** END GPL LICENSE BLOCK *****
*/
#include <math.h>
@@ -57,105 +46,23 @@
#include "BKE_texture.h"
#include "BKE_utildefines.h"
-#include "render.h"
+/* own module */
+#include "render_types.h"
+#include "renderpipeline.h"
+#include "renderdatabase.h"
#include "texture.h"
-
-#include "vanillaRenderPipe_types.h"
#include "pixelblending.h"
-#include "rendercore.h" /* for some shading functions... */
+#include "rendercore.h"
#include "shadbuf.h"
-#include "zbufferdatastruct.h"
-
-#include "renderHelp.h"
-
#include "gammaCorrectionTables.h"
-#include "errorHandler.h"
#include "pixelshading.h"
+/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
+/* defined in pipeline.c, is hardcopy of active dynamic allocated Render */
+/* only to be used here in this file, it's for speed */
+extern struct Render R;
+/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
-/* ton:
- - unified render now uses face render routines from rendercore.c
- - todo still: shalo render and sky routines */
-
-
-/* ------------------------------------------------------------------------- */
-static int calcHaloZ(HaloRen *har, int zz)
-{
-
- if(har->type & HA_ONLYSKY) {
- if(zz!=0x7FFFFFFF) zz= - 0x7FFFFF;
- }
- else {
- zz= (zz>>8);
- }
- return zz;
-}
-
-static void *renderHaloPixel(RE_COLBUFTYPE *collector, float x, float y, int haloNr)
-{
- HaloRen *har = NULL;
- float dist = 0.0;
- int zz = 0;
-
- /* Find har to go with haloNr */
- har = RE_findOrAddHalo(haloNr);
-
- /* zz is a strange number... This call should effect that halo's are */
- /* never cut? Seems a bit strange to me now... (nzc) */
- /* it checks for sky... which is info not available in unified (ton) */
- zz = calcHaloZ(har, 0x7FFFFFFF);
- if(zz> har->zs) {
-
- /* distance of this point wrt. the halo center. Maybe xcor is also needed? */
- dist = ((x - har->xs) * (x - har->xs))
- + ((y - har->ys) * (y - har->ys) * R.ycor * R.ycor) ;
-
- collector[0] = 0.0f; collector[1] = 0.0f;
- collector[2] = 0.0f; collector[3] = 0.0f;
-
- if (dist < har->radsq) {
- shadeHaloFloat(har, collector, zz, dist,
- (x - har->xs), (y - har->ys) * R.ycor, har->flarec);
- }; /* else: this pixel is not rendered for this halo: no colour */
- }
- return (void*) har;
-
-} /* end of void* renderHaloPixel(float x, float y, int haloNr) */
-
-
-
-/* ------------------------------------------------------------------------- */
-
-void *renderPixel(RE_COLBUFTYPE *collector, float x, float y, int *obdata, int mask)
-{
- void *data = NULL;
- float rco[3]; /* not used (yet?) */
-
- if (obdata[3] & RE_POLY) {
- data = shadepixel(x, y, obdata[0], obdata[1], mask, collector, rco);
- }
- else if (obdata[3] & RE_HALO) {
- data = renderHaloPixel(collector, x, y, obdata[1]);
- }
- else if( obdata[1] == 0 ) {
- /* for lamphalo, but doesn't seem to be called? Actually it is, and */
- /* it returns NULL pointers. */
- data = shadepixel(x, y, obdata[0], obdata[1], mask, collector, rco);
- }
- return data;
-
-} /* end of void renderPixel(float x, float y, int *obdata) */
-
-/* ------------------------------------------------------------------------- */
-
-void renderSpotHaloPixel(float x, float y, float* fcol)
-{
- float rco[3]; /* unused */
- shadepixel(x, y, 0, 0, 0, fcol, rco);
-}
-
-
-/* ------------------------------------------------------------------------- */
extern float hashvectf[];
@@ -537,29 +444,14 @@ void shadeHaloFloat(HaloRen *har, float *col, int zz,
*/
-/* Sky vars. */
-enum RE_SkyAlphaBlendingType keyingType = RE_ALPHA_SKY; /* The blending type */
-
-void setSkyBlendingMode(enum RE_SkyAlphaBlendingType mode) {
- if ((RE_ALPHA_NODEF < mode) && (mode < RE_ALPHA_MAX) ) {
- keyingType = mode;
- } else {
- /* error: false mode received */
- keyingType = RE_ALPHA_SKY;
- }
-}
-
-enum RE_SkyAlphaBlendingType getSkyBlendingMode() {
- return keyingType;
-}
/* This one renders into collector, as always. */
-void renderSkyPixelFloat(RE_COLBUFTYPE *collector, float x, float y, float *rco)
+void renderSkyPixelFloat(float *collector, float x, float y, float *rco)
{
- switch (keyingType) {
- case RE_ALPHA_PREMUL:
- case RE_ALPHA_KEY:
+ switch (R.r.alphamode) {
+ case R_ALPHAPREMUL:
+ case R_ALPHAKEY:
/* Premul or key: don't fill, and don't change the values! */
/* key alpha used to fill in color in 'empty' pixels, doesn't work anymore this way */
collector[0] = 0.0;
@@ -567,7 +459,7 @@ void renderSkyPixelFloat(RE_COLBUFTYPE *collector, float x, float y, float *rco)
collector[2] = 0.0;
collector[3] = 0.0;
break;
- case RE_ALPHA_SKY:
+ case R_ADDSKY:
/* Fill in the sky as if it were a normal face. */
shadeSkyPixel(collector, x, y, rco);
collector[3]= 0.0;
@@ -577,123 +469,10 @@ void renderSkyPixelFloat(RE_COLBUFTYPE *collector, float x, float y, float *rco)
}
}
-
-
-/*
- Render pixel (x,y) from the backbuffer into the collector
-
- backbuf is type Image, backbuf->ibuf is an ImBuf. ibuf->rect is the
- rgba data (32 bit total), in ibuf->x by ibuf->y pixels. Copying
- should be really easy. I hope I understand the way ImBuf works
- correctly. (nzc)
- */
-void fillBackgroundImageChar(char *col, float x, float y)
-{
- struct ImBuf *ibuf;
- int iy, ix;
- unsigned int* imBufPtr;
-
- /* check to be sure... */
- if (R.backbuf==NULL || R.backbuf->ok==0) {
- /* bail out */
- col[0] = 0;
- col[1] = 0;
- col[2] = 0;
- col[3] = 255;
- return;
- }
- /* load image if not already done?*/
- if(R.backbuf->ibuf==0) {
- R.backbuf->ok= 0;
- return;
- }
-
- ibuf= R.backbuf->ibuf;
-
- /* Now for the real extraction: */
- /* Get the y-coordinate of the scanline? */
- ix= (int) (0.5f + ( ((x+R.afmx+R.xstart)/(float)R.r.xsch))*(float)ibuf->x);
- iy= (int) (0.5f + ( ((y+R.afmy+R.ystart)/(float)R.r.ysch))*(float)ibuf->y);
-
- /* correct in case of fields rendering: */
- if(R.flag & R_SEC_FIELD) {
- if((R.r.mode & R_ODDFIELD)==0) {
- if( iy<ibuf->y) iy++;
- }
- else {
- if( iy>0) iy--;
- }
- }
-
- /* Offset into the buffer: start of scanline y: */
- imBufPtr = ibuf->rect
- + (iy * ibuf->x)
- + ix;
-
- *( (int *)col) = *imBufPtr;
-
-}
-
-static void fillBackgroundImage(float *col, float x, float y)
-{
- struct ImBuf *ibuf;
- int iy, ix;
-
- /* check to be sure... */
- if (R.backbuf==NULL || R.backbuf->ok==0) {
- /* bail out */
- col[0] = 0;
- col[1] = 0;
- col[2] = 0;
- col[3] = 255;
- return;
- }
- /* load image if not already done?*/
- if(R.backbuf->ibuf==NULL) {
- R.backbuf->ok= 0;
- return;
- }
-
- ibuf= R.backbuf->ibuf;
-
- /* Now for the real extraction: */
- /* Get the y-coordinate of the scanline? */
- ix= (int) (( ((x+R.afmx+R.xstart)/(float)R.r.xsch))*(float)ibuf->x);
- iy= (int) (( ((y+R.afmy+R.ystart)/(float)R.r.ysch))*(float)ibuf->y);
-
- /* correct in case of fields rendering: */
- if(R.flag & R_SEC_FIELD) {
- if((R.r.mode & R_ODDFIELD)==0) {
- if( iy<ibuf->y) iy++;
- }
- else {
- if( iy>0) iy--;
- }
- }
-
- CLAMP(ix, 0, ibuf->x-1);
- CLAMP(iy, 0, ibuf->y-1);
-
- /* Offset into the buffer: start of scanline y: */
- if(ibuf->rect_float) {
- float *fp = ibuf->rect_float + 4*(iy * ibuf->x + ix);
- QUATCOPY(col, fp);
- }
- else {
- char *cp = (char *)(ibuf->rect + (iy * ibuf->x) + ix);
-
- col[0]= (1.0f/255.0f) * (float)cp[0];
- col[1]= (1.0f/255.0f) * (float)cp[1];
- col[2]= (1.0f/255.0f) * (float)cp[2];
- col[3]= (1.0f/255.0f) * (float)cp[3];
- }
-
-}
-
/*
Stuff the sky colour into the collector.
*/
-void shadeSkyPixel(RE_COLBUFTYPE *collector, float fx, float fy, float *rco)
+void shadeSkyPixel(float *collector, float fx, float fy, float *rco)
{
float view[3], dxyview[2];
@@ -707,7 +486,7 @@ void shadeSkyPixel(RE_COLBUFTYPE *collector, float fx, float fy, float *rco)
/* 1. Do a backbuffer image: */
if(R.r.bufflag & 1) {
- fillBackgroundImage(collector, fx, fy);
+// fillBackgroundImage(collector, fx, fy);
return;
} else if((R.wrld.skytype & (WO_SKYBLEND+WO_SKYTEX))==0) {
/*
@@ -730,26 +509,17 @@ void shadeSkyPixel(RE_COLBUFTYPE *collector, float fx, float fy, float *rco)
/* This one true because of the context of this routine */
/* if(rect[3] < 254) { */
if(R.wrld.skytype & WO_SKYPAPER) {
- view[0]= (fx+(R.xstart))/(float)R.afmx;
- view[1]= (fy+(R.ystart))/(float)R.afmy;
+ view[0]= (fx/(float)R.winx);
+ view[1]= (fy/(float)R.winy);
view[2]= 0.0;
- dxyview[0]= 1.0/(float)R.afmx;
- dxyview[1]= 1.0/(float)R.afmy;
+ dxyview[0]= 1.0f/(float)R.winx;
+ dxyview[1]= 1.0f/(float)R.winy;
}
else {
- /* Wasn't this some pano stuff? */
- view[0]= (fx+(R.xstart)+1.0);
-
- if(R.flag & R_SEC_FIELD) {
- if(R.r.mode & R_ODDFIELD) view[1]= (fy+R.ystart+0.5)*R.ycor;
- else view[1]= (fy+R.ystart+1.5)*R.ycor;
- }
- else view[1]= (fy+R.ystart+1.0)*R.ycor;
-
- view[2]= -R.viewfac;
-
+ calc_view_vector(view, fx, fy);
fac= Normalise(view);
+
if(R.wrld.skytype & WO_SKYTEX) {
dxyview[0]= 1.0/fac;
dxyview[1]= R.ycor/fac;
@@ -757,15 +527,10 @@ void shadeSkyPixel(RE_COLBUFTYPE *collector, float fx, float fy, float *rco)
}
if(R.r.mode & R_PANORAMA) {
- float panoco, panosi;
- float u, v;
-
- panoco = getPanovCo();
- panosi = getPanovSi();
- u= view[0]; v= view[2];
+ float u= view[0]; float v= view[2];
- view[0]= panoco*u + panosi*v;
- view[2]= -panosi*u + panoco*v;
+ view[0]= R.panoco*u + R.panosi*v;
+ view[2]= -R.panosi*u + R.panoco*v;
}
/* get sky colour in the collector */
diff --git a/source/blender/render/intern/source/ray.c b/source/blender/render/intern/source/ray.c
index a91219846de..19ec1dd546d 100644
--- a/source/blender/render/intern/source/ray.c
+++ b/source/blender/render/intern/source/ray.c
@@ -1,15 +1,12 @@
/**
* $Id$
*
- * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
+ * ***** BEGIN GPL 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.
+ * of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
@@ -23,15 +20,16 @@
* The Original Code is Copyright (C) 1990-1998 NeoGeo BV.
* All rights reserved.
*
- * The Original Code is: all of this file.
+ * Contributors: 2004/2005 Blender Foundation, full recode
*
- * ***** END GPL/BL DUAL LICENSE BLOCK *****
+ * ***** END GPL LICENSE BLOCK *****
*/
#include <math.h>
#include <string.h>
#include <stdlib.h>
+#include <float.h>
#include "MEM_guardedalloc.h"
@@ -42,17 +40,16 @@
#include "BKE_global.h"
#include "BLI_arithb.h"
-#include <BLI_rand.h>
+#include "BLI_rand.h"
+#include "BLI_jitter.h"
-#include "render.h"
+#include "render_types.h"
+#include "renderpipeline.h"
#include "rendercore.h"
#include "pixelblending.h"
#include "pixelshading.h"
-#include "jitter.h"
#include "texture.h"
-#include "SDL_thread.h"
-
#define DDA_SHADOW 0
#define DDA_MIRROR 1
#define DDA_SHADOW_TRA 2
@@ -61,23 +58,17 @@
#define RAY_TRAFLIP 2
#define DEPTH_SHADOW_TRA 10
-/* from float.h */
-#define FLT_EPSILON 1.19209290e-07F
+/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
+/* defined in pipeline.c, is hardcopy of active dynamic allocated Render */
+/* only to be used here in this file, it's for speed */
+extern struct Render R;
+/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
/* ********** structs *************** */
#define BRANCH_ARRAY 1024
-
-typedef struct Octree {
- struct Branch *adrbranch[BRANCH_ARRAY];
- struct Node *adrnode[4096];
- float ocsize; /* ocsize: mult factor, max size octree */
- float ocfacx,ocfacy,ocfacz;
- float min[3], max[3];
- int ocres;
-
-} Octree;
+#define NODE_ARRAY 4096
typedef struct Isect {
float start[3], vec[3], end[3]; /* start+vec = end, in d3dda */
@@ -112,16 +103,10 @@ typedef struct Node
/* ******** globals ***************** */
-static Octree g_oc; /* can be scene pointer or so later... */
-
/* just for statistics */
-static int raycount, branchcount, nodecount;
+static int raycount;
static int accepted, rejected, coherent_ray;
-/* prototypes ------------------------ */
-void freeoctree(void);
-void makeoctree(void);
-int ray_trace_shadow_rad(ShadeInput *ship, ShadeResult *shr);
/* **************** ocval method ******************* */
/* within one octree node, a set of 3x15 bits defines a 'boundbox' to OR with */
@@ -190,36 +175,42 @@ static void calc_ocval_ray(OcVal *ov, float xo, float yo, float zo, float *vec1,
/* ************* octree ************** */
-static Branch *addbranch(Branch *br, short oc)
+static Branch *addbranch(Octree *oc, Branch *br, short ocb)
{
+ int index;
- if(br->b[oc]) return br->b[oc];
+ if(br->b[ocb]) return br->b[ocb];
- branchcount++;
- if(g_oc.adrbranch[branchcount>>12]==NULL)
- g_oc.adrbranch[branchcount>>12]= MEM_callocN(4096*sizeof(Branch),"addbranch");
+ oc->branchcount++;
+ index= oc->branchcount>>12;
+
+ if(oc->adrbranch[index]==NULL)
+ oc->adrbranch[index]= MEM_callocN(4096*sizeof(Branch), "new oc branch");
- if(branchcount>= BRANCH_ARRAY*4096) {
+ if(oc->branchcount>= BRANCH_ARRAY*4096) {
printf("error; octree branches full\n");
- branchcount=0;
+ oc->branchcount=0;
}
- return br->b[oc]=g_oc.adrbranch[branchcount>>12]+(branchcount & 4095);
+ return br->b[ocb]= oc->adrbranch[index]+(oc->branchcount & 4095);
}
-static Node *addnode(void)
+static Node *addnode(Octree *oc)
{
+ int index;
+
+ oc->nodecount++;
+ index= oc->nodecount>>12;
- nodecount++;
- if(g_oc.adrnode[nodecount>>12]==NULL)
- g_oc.adrnode[nodecount>>12]= MEM_callocN(4096*sizeof(Node),"addnode");
+ if(oc->adrnode[index]==NULL)
+ oc->adrnode[index]= MEM_callocN(4096*sizeof(Node),"addnode");
- if(nodecount> 4096*4096) {
+ if(oc->nodecount> NODE_ARRAY*NODE_ARRAY) {
printf("error; octree nodes full\n");
- nodecount=0;
+ oc->nodecount=0;
}
- return g_oc.adrnode[nodecount>>12]+(nodecount & 4095);
+ return oc->adrnode[index]+(oc->nodecount & 4095);
}
static int face_in_node(VlakRen *vlr, short x, short y, short z, float rtf[][3])
@@ -262,7 +253,7 @@ static int face_in_node(VlakRen *vlr, short x, short y, short z, float rtf[][3])
return 0;
}
-static void ocwrite(VlakRen *vlr, short x, short y, short z, float rtf[][3])
+static void ocwrite(Octree *oc, VlakRen *vlr, short x, short y, short z, float rtf[][3])
{
Branch *br;
Node *no;
@@ -273,19 +264,19 @@ static void ocwrite(VlakRen *vlr, short x, short y, short z, float rtf[][3])
x<<=2;
y<<=1;
- br= g_oc.adrbranch[0];
+ br= oc->adrbranch[0];
- if(g_oc.ocres==512) {
+ if(oc->ocres==512) {
oc0= ((x & 1024)+(y & 512)+(z & 256))>>8;
- br= addbranch(br, oc0);
+ br= addbranch(oc, br, oc0);
}
- if(g_oc.ocres>=256) {
+ if(oc->ocres>=256) {
oc0= ((x & 512)+(y & 256)+(z & 128))>>7;
- br= addbranch(br, oc0);
+ br= addbranch(oc, br, oc0);
}
- if(g_oc.ocres>=128) {
+ if(oc->ocres>=128) {
oc0= ((x & 256)+(y & 128)+(z & 64))>>6;
- br= addbranch(br, oc0);
+ br= addbranch(oc, br, oc0);
}
oc0= ((x & 128)+(y & 64)+(z & 32))>>5;
@@ -295,19 +286,19 @@ static void ocwrite(VlakRen *vlr, short x, short y, short z, float rtf[][3])
oc4= ((x & 8)+(y & 4)+(z & 2))>>1;
oc5= ((x & 4)+(y & 2)+(z & 1));
- br= addbranch(br,oc0);
- br= addbranch(br,oc1);
- br= addbranch(br,oc2);
- br= addbranch(br,oc3);
- br= addbranch(br,oc4);
+ br= addbranch(oc, br,oc0);
+ br= addbranch(oc, br,oc1);
+ br= addbranch(oc, br,oc2);
+ br= addbranch(oc, br,oc3);
+ br= addbranch(oc, br,oc4);
no= (Node *)br->b[oc5];
- if(no==NULL) br->b[oc5]= (Branch *)(no= addnode());
+ if(no==NULL) br->b[oc5]= (Branch *)(no= addnode(oc));
while(no->next) no= no->next;
a= 0;
if(no->v[7]) { /* node full */
- no->next= addnode();
+ no->next= addnode(oc);
no= no->next;
}
else {
@@ -320,7 +311,7 @@ static void ocwrite(VlakRen *vlr, short x, short y, short z, float rtf[][3])
}
-static void d2dda(short b1, short b2, short c1, short c2, char *ocvlak, short rts[][3], float rtf[][3])
+static void d2dda(Octree *oc, short b1, short b2, short c1, short c2, char *ocface, short rts[][3], float rtf[][3])
{
int ocx1,ocx2,ocy1,ocy2;
int x,y,dx=0,dy=0;
@@ -333,7 +324,7 @@ static void d2dda(short b1, short b2, short c1, short c2, char *ocvlak, short rt
ocy2= rts[b2][c2];
if(ocx1==ocx2 && ocy1==ocy2) {
- ocvlak[g_oc.ocres*ocx1+ocy1]= 1;
+ ocface[oc->ocres*ocx1+ocy1]= 1;
return;
}
@@ -377,8 +368,8 @@ static void d2dda(short b1, short b2, short c1, short c2, char *ocvlak, short rt
while(TRUE) {
- if(x<0 || y<0 || x>=g_oc.ocres || y>=g_oc.ocres);
- else ocvlak[g_oc.ocres*x+y]= 1;
+ if(x<0 || y<0 || x>=oc->ocres || y>=oc->ocres);
+ else ocface[oc->ocres*x+y]= 1;
labdao=labda;
if(labdax==labday) {
@@ -399,10 +390,10 @@ static void d2dda(short b1, short b2, short c1, short c2, char *ocvlak, short rt
if(labda==labdao) break;
if(labda>=1.0) break;
}
- ocvlak[g_oc.ocres*ocx2+ocy2]=1;
+ ocface[oc->ocres*ocx2+ocy2]=1;
}
-static void filltriangle(short c1, short c2, char *ocvlak, short *ocmin)
+static void filltriangle(Octree *oc, short c1, short c2, char *ocface, short *ocmin)
{
short *ocmax;
int a, x, y, y1, y2;
@@ -410,14 +401,14 @@ static void filltriangle(short c1, short c2, char *ocvlak, short *ocmin)
ocmax=ocmin+3;
for(x=ocmin[c1];x<=ocmax[c1];x++) {
- a= g_oc.ocres*x;
+ a= oc->ocres*x;
for(y=ocmin[c2];y<=ocmax[c2];y++) {
- if(ocvlak[a+y]) {
+ if(ocface[a+y]) {
y++;
- while(ocvlak[a+y] && y!=ocmax[c2]) y++;
+ while(ocface[a+y] && y!=ocmax[c2]) y++;
for(y1=ocmax[c2];y1>y;y1--) {
- if(ocvlak[a+y1]) {
- for(y2=y;y2<=y1;y2++) ocvlak[a+y2]=1;
+ if(ocface[a+y1]) {
+ for(y2=y;y2<=y1;y2++) ocface[a+y2]=1;
y1=0;
}
}
@@ -427,35 +418,45 @@ static void filltriangle(short c1, short c2, char *ocvlak, short *ocmin)
}
}
-void freeoctree(void)
+void freeoctree(Render *re)
{
- int a= 0;
-
- while(g_oc.adrbranch[a]) {
- MEM_freeN(g_oc.adrbranch[a]);
- g_oc.adrbranch[a]= NULL;
- a++;
- }
-
- a= 0;
- while(g_oc.adrnode[a]) {
- MEM_freeN(g_oc.adrnode[a]);
- g_oc.adrnode[a]= NULL;
- a++;
- }
+ Octree *oc= &re->oc;
if(G.f & G_DEBUG) {
- printf("branches %d nodes %d\n", branchcount, nodecount);
+ printf("branches %d nodes %d\n", oc->branchcount, oc->nodecount);
printf("raycount %d \n", raycount);
printf("ray coherent %d \n", coherent_ray);
printf("accepted %d rejected %d\n", accepted, rejected);
}
- branchcount= 0;
- nodecount= 0;
+
+ if(oc->adrbranch) {
+ int a= 0;
+ while(oc->adrbranch[a]) {
+ MEM_freeN(oc->adrbranch[a]);
+ oc->adrbranch[a]= NULL;
+ a++;
+ }
+ MEM_freeN(oc->adrbranch);
+ oc->adrbranch= NULL;
+ }
+ oc->branchcount= 0;
+
+ if(oc->adrnode) {
+ int a= 0;
+ while(oc->adrnode[a]) {
+ MEM_freeN(oc->adrnode[a]);
+ oc->adrnode[a]= NULL;
+ a++;
+ }
+ MEM_freeN(oc->adrnode);
+ oc->adrnode= NULL;
+ }
+ oc->nodecount= 0;
}
-void makeoctree(void)
+void makeoctree(Render *re)
{
+ Octree *oc;
VlakRen *vlr=NULL;
VertRen *v1, *v2, *v3, *v4;
float ocfac[3], t00, t01, t02;
@@ -463,68 +464,68 @@ void makeoctree(void)
int v;
int a, b, c, oc1, oc2, oc3, oc4, x, y, z, ocres2;
short rts[4][3], ocmin[6], *ocmax;
- char *ocvlak; // front, top, size view of face, to fill in
+ char *ocface; // front, top, size view of face, to fill in
- ocmax= ocmin+3;
+ oc= &re->oc;
+ oc->adrbranch= MEM_callocN(sizeof(void *)*BRANCH_ARRAY, "octree branches");
+ oc->adrnode= MEM_callocN(sizeof(void *)*NODE_ARRAY, "octree nodes");
- memset(g_oc.adrnode, 0, sizeof(g_oc.adrnode));
- memset(g_oc.adrbranch, 0, sizeof(g_oc.adrbranch));
+ ocmax= ocmin+3;
- branchcount=0;
- nodecount=0;
+ /* only for debug info */
raycount=0;
accepted= 0;
rejected= 0;
coherent_ray= 0;
/* fill main octree struct */
- g_oc.ocres= R.r.ocres;
- ocres2= g_oc.ocres*g_oc.ocres;
- INIT_MINMAX(g_oc.min, g_oc.max);
+ oc->ocres= re->r.ocres;
+ ocres2= oc->ocres*oc->ocres;
+ INIT_MINMAX(oc->min, oc->max);
/* first min max octree space */
- for(v=0;v<R.totvlak;v++) {
- if((v & 255)==0) vlr= R.blovl[v>>8];
+ for(v=0;v<re->totvlak;v++) {
+ if((v & 255)==0) vlr= re->blovl[v>>8];
else vlr++;
if(vlr->mat->mode & MA_TRACEBLE) {
if((vlr->mat->mode & MA_WIRE)==0) {
- DO_MINMAX(vlr->v1->co, g_oc.min, g_oc.max);
- DO_MINMAX(vlr->v2->co, g_oc.min, g_oc.max);
- DO_MINMAX(vlr->v3->co, g_oc.min, g_oc.max);
+ DO_MINMAX(vlr->v1->co, oc->min, oc->max);
+ DO_MINMAX(vlr->v2->co, oc->min, oc->max);
+ DO_MINMAX(vlr->v3->co, oc->min, oc->max);
if(vlr->v4) {
- DO_MINMAX(vlr->v4->co, g_oc.min, g_oc.max);
+ DO_MINMAX(vlr->v4->co, oc->min, oc->max);
}
}
}
}
- if(g_oc.min[0] > g_oc.max[0]) return; /* empty octree */
+ if(oc->min[0] > oc->max[0]) return; /* empty octree */
- g_oc.adrbranch[0]=(Branch *)MEM_callocN(4096*sizeof(Branch), "makeoctree");
+ oc->adrbranch[0]=(Branch *)MEM_callocN(4096*sizeof(Branch), "makeoctree");
/* the lookup table, per face, for which nodes to fill in */
- ocvlak= MEM_callocN( 3*ocres2 + 8, "ocvlak");
- memset(ocvlak, 0, 3*ocres2);
+ ocface= MEM_callocN( 3*ocres2 + 8, "ocface");
+ memset(ocface, 0, 3*ocres2);
for(c=0;c<3;c++) { /* octree enlarge, still needed? */
- g_oc.min[c]-= 0.01;
- g_oc.max[c]+= 0.01;
+ oc->min[c]-= 0.01;
+ oc->max[c]+= 0.01;
}
- t00= g_oc.max[0]-g_oc.min[0];
- t01= g_oc.max[1]-g_oc.min[1];
- t02= g_oc.max[2]-g_oc.min[2];
+ t00= oc->max[0]-oc->min[0];
+ t01= oc->max[1]-oc->min[1];
+ t02= oc->max[2]-oc->min[2];
/* this minus 0.1 is old safety... seems to be needed? */
- g_oc.ocfacx=ocfac[0]= (g_oc.ocres-0.1)/t00;
- g_oc.ocfacy=ocfac[1]= (g_oc.ocres-0.1)/t01;
- g_oc.ocfacz=ocfac[2]= (g_oc.ocres-0.1)/t02;
+ oc->ocfacx=ocfac[0]= (oc->ocres-0.1)/t00;
+ oc->ocfacy=ocfac[1]= (oc->ocres-0.1)/t01;
+ oc->ocfacz=ocfac[2]= (oc->ocres-0.1)/t02;
- g_oc.ocsize= sqrt(t00*t00+t01*t01+t02*t02); /* global, max size octree */
+ oc->ocsize= sqrt(t00*t00+t01*t01+t02*t02); /* global, max size octree */
- for(v=0; v<R.totvlak; v++) {
- if((v & 255)==0) vlr= R.blovl[v>>8];
+ for(v=0; v<re->totvlak; v++) {
+ if((v & 255)==0) vlr= re->blovl[v>>8];
else vlr++;
if(vlr->mat->mode & MA_TRACEBLE) {
@@ -536,14 +537,14 @@ void makeoctree(void)
v4= vlr->v4;
for(c=0;c<3;c++) {
- rtf[0][c]= (v1->co[c]-g_oc.min[c])*ocfac[c] ;
+ rtf[0][c]= (v1->co[c]-oc->min[c])*ocfac[c] ;
rts[0][c]= (short)rtf[0][c];
- rtf[1][c]= (v2->co[c]-g_oc.min[c])*ocfac[c] ;
+ rtf[1][c]= (v2->co[c]-oc->min[c])*ocfac[c] ;
rts[1][c]= (short)rtf[1][c];
- rtf[2][c]= (v3->co[c]-g_oc.min[c])*ocfac[c] ;
+ rtf[2][c]= (v3->co[c]-oc->min[c])*ocfac[c] ;
rts[2][c]= (short)rtf[2][c];
if(v4) {
- rtf[3][c]= (v4->co[c]-g_oc.min[c])*ocfac[c] ;
+ rtf[3][c]= (v4->co[c]-oc->min[c])*ocfac[c] ;
rts[3][c]= (short)rtf[3][c];
}
}
@@ -563,44 +564,44 @@ void makeoctree(void)
ocmin[c]= MIN4(oc1,oc2,oc3,oc4);
ocmax[c]= MAX4(oc1,oc2,oc3,oc4);
}
- if(ocmax[c]>g_oc.ocres-1) ocmax[c]=g_oc.ocres-1;
+ if(ocmax[c]>oc->ocres-1) ocmax[c]=oc->ocres-1;
if(ocmin[c]<0) ocmin[c]=0;
}
- d2dda(0,1,0,1,ocvlak+ocres2,rts,rtf);
- d2dda(0,1,0,2,ocvlak,rts,rtf);
- d2dda(0,1,1,2,ocvlak+2*ocres2,rts,rtf);
- d2dda(1,2,0,1,ocvlak+ocres2,rts,rtf);
- d2dda(1,2,0,2,ocvlak,rts,rtf);
- d2dda(1,2,1,2,ocvlak+2*ocres2,rts,rtf);
+ d2dda(oc, 0,1,0,1,ocface+ocres2,rts,rtf);
+ d2dda(oc, 0,1,0,2,ocface,rts,rtf);
+ d2dda(oc, 0,1,1,2,ocface+2*ocres2,rts,rtf);
+ d2dda(oc, 1,2,0,1,ocface+ocres2,rts,rtf);
+ d2dda(oc, 1,2,0,2,ocface,rts,rtf);
+ d2dda(oc, 1,2,1,2,ocface+2*ocres2,rts,rtf);
if(v4==NULL) {
- d2dda(2,0,0,1,ocvlak+ocres2,rts,rtf);
- d2dda(2,0,0,2,ocvlak,rts,rtf);
- d2dda(2,0,1,2,ocvlak+2*ocres2,rts,rtf);
+ d2dda(oc, 2,0,0,1,ocface+ocres2,rts,rtf);
+ d2dda(oc, 2,0,0,2,ocface,rts,rtf);
+ d2dda(oc, 2,0,1,2,ocface+2*ocres2,rts,rtf);
}
else {
- d2dda(2,3,0,1,ocvlak+ocres2,rts,rtf);
- d2dda(2,3,0,2,ocvlak,rts,rtf);
- d2dda(2,3,1,2,ocvlak+2*ocres2,rts,rtf);
- d2dda(3,0,0,1,ocvlak+ocres2,rts,rtf);
- d2dda(3,0,0,2,ocvlak,rts,rtf);
- d2dda(3,0,1,2,ocvlak+2*ocres2,rts,rtf);
+ d2dda(oc, 2,3,0,1,ocface+ocres2,rts,rtf);
+ d2dda(oc, 2,3,0,2,ocface,rts,rtf);
+ d2dda(oc, 2,3,1,2,ocface+2*ocres2,rts,rtf);
+ d2dda(oc, 3,0,0,1,ocface+ocres2,rts,rtf);
+ d2dda(oc, 3,0,0,2,ocface,rts,rtf);
+ d2dda(oc, 3,0,1,2,ocface+2*ocres2,rts,rtf);
}
/* nothing todo with triangle..., just fills :) */
- filltriangle(0,1,ocvlak+ocres2,ocmin);
- filltriangle(0,2,ocvlak,ocmin);
- filltriangle(1,2,ocvlak+2*ocres2,ocmin);
+ filltriangle(oc, 0,1,ocface+ocres2,ocmin);
+ filltriangle(oc, 0,2,ocface,ocmin);
+ filltriangle(oc, 1,2,ocface+2*ocres2,ocmin);
/* init static vars here */
face_in_node(vlr, 0,0,0, rtf);
for(x=ocmin[0];x<=ocmax[0];x++) {
- a= g_oc.ocres*x;
+ a= oc->ocres*x;
for(y=ocmin[1];y<=ocmax[1];y++) {
- if(ocvlak[a+y+ocres2]) {
- b= g_oc.ocres*y+2*ocres2;
+ if(ocface[a+y+ocres2]) {
+ b= oc->ocres*y+2*ocres2;
for(z=ocmin[2];z<=ocmax[2];z++) {
- if(ocvlak[b+z] && ocvlak[a+z]) ocwrite(vlr, x,y,z, rtf);
+ if(ocface[b+z] && ocface[a+z]) ocwrite(oc, vlr, x,y,z, rtf);
}
}
}
@@ -608,17 +609,17 @@ void makeoctree(void)
/* same loops to clear octree, doubt it can be done smarter */
for(x=ocmin[0];x<=ocmax[0];x++) {
- a= g_oc.ocres*x;
+ a= oc->ocres*x;
for(y=ocmin[1];y<=ocmax[1];y++) {
/* x-y */
- ocvlak[a+y+ocres2]= 0;
+ ocface[a+y+ocres2]= 0;
- b= g_oc.ocres*y + 2*ocres2;
+ b= oc->ocres*y + 2*ocres2;
for(z=ocmin[2];z<=ocmax[2];z++) {
/* y-z */
- ocvlak[b+z]= 0;
+ ocface[b+z]= 0;
/* x-z */
- ocvlak[a+z]= 0;
+ ocface[a+z]= 0;
}
}
}
@@ -626,7 +627,7 @@ void makeoctree(void)
}
}
- MEM_freeN(ocvlak);
+ MEM_freeN(ocface);
}
/* ************ raytracer **************** */
@@ -1007,23 +1008,23 @@ static Node *ocread(int x, int y, int z)
x<<=2;
y<<=1;
- br= g_oc.adrbranch[0];
+ br= R.oc.adrbranch[0];
- if(g_oc.ocres==512) {
+ if(R.oc.ocres==512) {
oc1= ((x & 1024)+(y & 512)+(z & 256))>>8;
br= br->b[oc1];
if(br==NULL) {
return NULL;
}
}
- if(g_oc.ocres>=256) {
+ if(R.oc.ocres>=256) {
oc1= ((x & 512)+(y & 256)+(z & 128))>>7;
br= br->b[oc1];
if(br==NULL) {
return NULL;
}
}
- if(g_oc.ocres>=128) {
+ if(R.oc.ocres>=128) {
oc1= ((x & 256)+(y & 128)+(z & 64))>>6;
br= br->b[oc1];
if(br==NULL) {
@@ -1127,7 +1128,7 @@ static int d3dda(Isect *is)
int ocx1,ocx2,ocy1, ocy2,ocz1,ocz2;
/* clip with octree */
- if(branchcount==0) return 0;
+ if(R.oc.branchcount==0) return 0;
/* do this before intersect calls */
is->vlrcontr= NULL; /* to check shared edge */
@@ -1150,14 +1151,14 @@ static int d3dda(Isect *is)
u2= 1.0;
/* clip with octree cube */
- if(cliptest(-ldx, is->start[0]-g_oc.min[0], &u1,&u2)) {
- if(cliptest(ldx, g_oc.max[0]-is->start[0], &u1,&u2)) {
+ if(cliptest(-ldx, is->start[0]-R.oc.min[0], &u1,&u2)) {
+ if(cliptest(ldx, R.oc.max[0]-is->start[0], &u1,&u2)) {
ldy= is->end[1] - is->start[1];
- if(cliptest(-ldy, is->start[1]-g_oc.min[1], &u1,&u2)) {
- if(cliptest(ldy, g_oc.max[1]-is->start[1], &u1,&u2)) {
+ if(cliptest(-ldy, is->start[1]-R.oc.min[1], &u1,&u2)) {
+ if(cliptest(ldy, R.oc.max[1]-is->start[1], &u1,&u2)) {
ldz= is->end[2] - is->start[2];
- if(cliptest(-ldz, is->start[2]-g_oc.min[2], &u1,&u2)) {
- if(cliptest(ldz, g_oc.max[2]-is->start[2], &u1,&u2)) {
+ if(cliptest(-ldz, is->start[2]-R.oc.min[2], &u1,&u2)) {
+ if(cliptest(ldz, R.oc.max[2]-is->start[2], &u1,&u2)) {
c1=1;
if(u2<1.0) {
is->end[0]= is->start[0]+u2*ldx;
@@ -1179,15 +1180,15 @@ static int d3dda(Isect *is)
if(c1==0) return 0;
/* reset static variables in ocread */
- //ocread(g_oc.ocres, 0, 0);
+ //ocread(R.oc.ocres, 0, 0);
/* setup 3dda to traverse octree */
- ox1= (is->start[0]-g_oc.min[0])*g_oc.ocfacx;
- oy1= (is->start[1]-g_oc.min[1])*g_oc.ocfacy;
- oz1= (is->start[2]-g_oc.min[2])*g_oc.ocfacz;
- ox2= (is->end[0]-g_oc.min[0])*g_oc.ocfacx;
- oy2= (is->end[1]-g_oc.min[1])*g_oc.ocfacy;
- oz2= (is->end[2]-g_oc.min[2])*g_oc.ocfacz;
+ ox1= (is->start[0]-R.oc.min[0])*R.oc.ocfacx;
+ oy1= (is->start[1]-R.oc.min[1])*R.oc.ocfacy;
+ oz1= (is->start[2]-R.oc.min[2])*R.oc.ocfacz;
+ ox2= (is->end[0]-R.oc.min[0])*R.oc.ocfacx;
+ oy2= (is->end[1]-R.oc.min[1])*R.oc.ocfacy;
+ oz2= (is->end[2]-R.oc.min[2])*R.oc.ocfacz;
ocx1= (int)ox1;
ocy1= (int)oy1;
@@ -1522,9 +1523,9 @@ static void traceray(short depth, float *start, float *vec, float *col, VlakRen
float ref[3];
VECCOPY(isec.start, start);
- isec.end[0]= start[0]+g_oc.ocsize*vec[0];
- isec.end[1]= start[1]+g_oc.ocsize*vec[1];
- isec.end[2]= start[2]+g_oc.ocsize*vec[2];
+ isec.end[0]= start[0]+R.oc.ocsize*vec[0];
+ isec.end[1]= start[1]+R.oc.ocsize*vec[1];
+ isec.end[2]= start[2]+R.oc.ocsize*vec[2];
isec.mode= DDA_MIRROR;
isec.vlrorig= vlr;
@@ -1712,7 +1713,7 @@ void init_jitter_plane(LampRen *lar)
}
/* table around origin, -0.5*size to 0.5*size */
-static float *give_jitter_plane(LampRen *lar, int xs, int ys)
+static float *give_jitter_plane(LampRen *lar, int thread, int xs, int ys)
{
int tot;
@@ -1720,7 +1721,7 @@ static float *give_jitter_plane(LampRen *lar, int xs, int ys)
if(lar->ray_samp_type & LA_SAMP_JITTER) {
/* made it threadsafe */
- if(ys & 1) {
+ if(thread & 1) {
if(lar->xold1!=xs || lar->yold1!=ys) {
jitter_plane_offset(lar->jitter, lar->jitter+2*tot, tot, lar->area_size, lar->area_sizey, BLI_thread_frand(1), BLI_thread_frand(1));
lar->xold1= xs; lar->yold1= ys;
@@ -1886,9 +1887,9 @@ int ray_trace_shadow_rad(ShadeInput *ship, ShadeResult *shr)
vec[2]-= vec[2];
}
VECCOPY(isec.start, ship->co);
- isec.end[0]= isec.start[0] + g_oc.ocsize*vec[0];
- isec.end[1]= isec.start[1] + g_oc.ocsize*vec[1];
- isec.end[2]= isec.start[2] + g_oc.ocsize*vec[2];
+ isec.end[0]= isec.start[0] + R.oc.ocsize*vec[0];
+ isec.end[1]= isec.start[1] + R.oc.ocsize*vec[1];
+ isec.end[2]= isec.start[2] + R.oc.ocsize*vec[2];
if( d3dda(&isec)) {
float fac;
@@ -1976,13 +1977,13 @@ void init_ao_sphere(float *sphere, int tot, int iter)
}
-static float *threadsafe_table_sphere(int test, int xs, int ys)
+static float *threadsafe_table_sphere(int test, int thread, int xs, int ys)
{
static float sphere1[2*3*256];
static float sphere2[2*3*256];
static int xs1=-1, xs2=-1, ys1=-1, ys2=-1;
- if(ys & 1) {
+ if(thread & 1) {
if(xs==xs1 && ys==ys1) return sphere1;
if(test) return NULL;
xs1= xs; ys1= ys;
@@ -1996,7 +1997,7 @@ static float *threadsafe_table_sphere(int test, int xs, int ys)
}
}
-static float *sphere_sampler(int type, int resol, int xs, int ys)
+static float *sphere_sampler(int type, int resol, int thread, int xs, int ys)
{
int tot;
float *vec;
@@ -2023,14 +2024,14 @@ static float *sphere_sampler(int type, int resol, int xs, int ys)
float ang, *vec1;
int a;
- sphere= threadsafe_table_sphere(1, xs, ys); // returns table if xs and ys were equal to last call
+ sphere= threadsafe_table_sphere(1, thread, xs, ys); // returns table if xs and ys were equal to last call
if(sphere==NULL) {
- sphere= threadsafe_table_sphere(0, xs, ys);
+ sphere= threadsafe_table_sphere(0, thread, xs, ys);
// random rotation
- ang= BLI_thread_frand(ys & 1);
+ ang= BLI_thread_frand(thread);
sinfi= sin(ang); cosfi= cos(ang);
- ang= BLI_thread_frand(ys & 1);
+ ang= BLI_thread_frand(thread);
sint= sin(ang); cost= cos(ang);
vec= R.wrld.aosphere;
@@ -2047,11 +2048,11 @@ static float *sphere_sampler(int type, int resol, int xs, int ys)
/* extern call from shade_lamp_loop, ambient occlusion calculus */
-void ray_ao(ShadeInput *shi, World *wrld, float *shadfac)
+void ray_ao(ShadeInput *shi, float *shadfac)
{
Isect isec;
float *vec, *nrm, div, bias, sh=0;
- float maxdist = wrld->aodist;
+ float maxdist = R.wrld.aodist;
int j= -1, tot, actual=0, skyadded=0;
isec.vlrorig= shi->vlr;
@@ -2071,10 +2072,10 @@ void ray_ao(ShadeInput *shi, World *wrld, float *shadfac)
nrm= shi->facenor;
}
- vec= sphere_sampler(wrld->aomode, wrld->aosamp, shi->xs, shi->ys);
+ vec= sphere_sampler(R.wrld.aomode, R.wrld.aosamp, shi->thread, shi->xs, shi->ys);
// warning: since we use full sphere now, and dotproduct is below, we do twice as much
- tot= 2*wrld->aosamp*wrld->aosamp;
+ tot= 2*R.wrld.aosamp*R.wrld.aosamp;
while(tot--) {
@@ -2099,10 +2100,10 @@ void ray_ao(ShadeInput *shi, World *wrld, float *shadfac)
/* do the trace */
if (d3dda(&isec)) {
- if (wrld->aomode & WO_AODIST) sh+= exp(-isec.labda*wrld->aodistfac);
+ if (R.wrld.aomode & WO_AODIST) sh+= exp(-isec.labda*R.wrld.aodistfac);
else sh+= 1.0;
}
- else if(wrld->aocolor!=WO_AOPLAIN) {
+ else if(R.wrld.aocolor!=WO_AOPLAIN) {
float skycol[4];
float fac, view[3];
@@ -2111,7 +2112,7 @@ void ray_ao(ShadeInput *shi, World *wrld, float *shadfac)
view[2]= -vec[2];
Normalise(view);
- if(wrld->aocolor==WO_AOSKYCOL) {
+ if(R.wrld.aocolor==WO_AOSKYCOL) {
fac= 0.5*(1.0+view[0]*R.grvec[0]+ view[1]*R.grvec[1]+ view[2]*R.grvec[2]);
shadfac[0]+= (1.0-fac)*R.wrld.horr + fac*R.wrld.zenr;
shadfac[1]+= (1.0-fac)*R.wrld.horg + fac*R.wrld.zeng;
@@ -2133,7 +2134,7 @@ void ray_ao(ShadeInput *shi, World *wrld, float *shadfac)
if(actual==0) shadfac[3]= 1.0;
else shadfac[3] = 1.0 - sh/((float)actual);
- if(wrld->aocolor!=WO_AOPLAIN && skyadded) {
+ if(R.wrld.aocolor!=WO_AOPLAIN && skyadded) {
div= shadfac[3]/((float)skyadded);
shadfac[0]*= div; // average color times distances/hits formula
@@ -2162,9 +2163,9 @@ void ray_shadow(ShadeInput *shi, LampRen *lar, float *shadfac)
if(lar->type==LA_SUN || lar->type==LA_HEMI) {
- lampco[0]= shi->co[0] - g_oc.ocsize*lar->vec[0];
- lampco[1]= shi->co[1] - g_oc.ocsize*lar->vec[1];
- lampco[2]= shi->co[2] - g_oc.ocsize*lar->vec[2];
+ lampco[0]= shi->co[0] - R.oc.ocsize*lar->vec[0];
+ lampco[1]= shi->co[1] - R.oc.ocsize*lar->vec[1];
+ lampco[2]= shi->co[2] - R.oc.ocsize*lar->vec[2];
}
else {
VECCOPY(lampco, lar->co);
@@ -2202,7 +2203,7 @@ void ray_shadow(ShadeInput *shi, LampRen *lar, float *shadfac)
else shadfac[3]= 1.0; // 1.0=full light
fac= 0.0;
- jitlamp= give_jitter_plane(lar, shi->xs, shi->ys);
+ jitlamp= give_jitter_plane(lar, shi->thread, shi->xs, shi->ys);
a= lar->ray_totsamp;
@@ -2284,9 +2285,9 @@ void ray_translucent(ShadeInput *shi, LampRen *lar, float *distfac, float *co)
if(lar->mode & LA_LAYER) isec.lay= lar->lay; else isec.lay= -1;
if(lar->type==LA_SUN || lar->type==LA_HEMI) {
- lampco[0]= shi->co[0] - g_oc.ocsize*lar->vec[0];
- lampco[1]= shi->co[1] - g_oc.ocsize*lar->vec[1];
- lampco[2]= shi->co[2] - g_oc.ocsize*lar->vec[2];
+ lampco[0]= shi->co[0] - R.oc.ocsize*lar->vec[0];
+ lampco[1]= shi->co[1] - R.oc.ocsize*lar->vec[1];
+ lampco[2]= shi->co[2] - R.oc.ocsize*lar->vec[2];
}
else {
VECCOPY(lampco, lar->co);
diff --git a/source/blender/render/intern/source/renderHelp.c b/source/blender/render/intern/source/renderHelp.c
deleted file mode 100644
index aba78079472..00000000000
--- a/source/blender/render/intern/source/renderHelp.c
+++ /dev/null
@@ -1,306 +0,0 @@
-/**
- *
- * ***** 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.
- *
- * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
- * All rights reserved.
- *
- * The Original Code is: all of this file.
- *
- * Contributor(s): none yet.
- *
- * ***** END GPL/BL DUAL LICENSE BLOCK *****
- * Some helpful conversions/functions.
- *
- * $Id$
- */
-
-#include <math.h>
-#include <limits.h>
-#include <stdlib.h>
-
-#include "DNA_mesh_types.h"
-#include "DNA_meshdata_types.h"
-#include "BKE_utildefines.h"
-#include "BLI_arithb.h"
-
-#include "render.h"
-#include "renderHelp.h"
-#include "zbuf.h"
-
-static float panovco, panovsi;
-static float panophi=0.0;
-static float tempPanoPhi;
-
-static int panotestclip(float *v);
-
-void pushTempPanoPhi(float p) {
- tempPanoPhi = panophi;
- panophi = p;
-}
-
-void popTempPanoPhi() {
- panophi = tempPanoPhi;
-}
-
-float getPanoPhi(){
- return panophi;
-}
-float getPanovCo(){
- return panovco;
-}
-float getPanovSi(){
- return panovsi;
-}
-
-void setPanoRot(int part)
-{
-/* extern float panovco, panovsi; */
- static float alpha= 1.0;
-
- /* part==0 init all */
-
- if(part==0) {
-
- alpha= ((float)R.r.xsch)/R.viewfac;
- alpha= 2.0*atan(alpha/2.0);
- }
-
-
- /* rotate it all around the y-as with phi degrees */
-
- panophi= -0.5*(R.r.xparts-1)*alpha + part*alpha;
-
- panovsi= sin(-panophi);
- panovco= cos(-panophi);
-
-}
-
-
-
-
-static int panotestclip(float *v)
-{
- /* to be used for halos en infos */
- float abs4;
- short c=0;
-
- if((R.r.mode & R_PANORAMA)==0) return RE_testclip(v);
-
- abs4= fabs(v[3]);
-
- if(v[2]< -abs4) c=16; /* this used to be " if(v[2]<0) ", see clippz() */
- else if(v[2]> abs4) c+= 32;
-
- if( v[1]>abs4) c+=4;
- else if( v[1]< -abs4) c+=8;
-
- abs4*= R.r.xparts;
- if( v[0]>abs4) c+=2;
- else if( v[0]< -abs4) c+=1;
-
- return c;
-}
-
-/*
-
- This adds the hcs coordinates to vertices. It iterates over all
- vertices, halos and faces. After the conversion, we clip in hcs.
-
- Elsewhere, all primites are converted to vertices.
- Called in
- - envmapping (envmap.c)
- - shadow buffering (shadbuf.c)
- - preparation for rendering (renderPreAndPost.c)
-
-*/
-
-/* move to renderer */
-void setzbufvlaggen( void (*projectfunc)(float *, float *) )
-/* homocos too */
-{
- VlakRen *vlr = NULL;
- VertRen *ver = NULL;
- HaloRen *har = NULL;
- float zn, vec[3], si, co, hoco[4];
- int a;
- float panophi = 0.0;
-
- panophi = getPanoPhi();
- si= sin(panophi);
- co= cos(panophi);
-
- /* calculate view coordinates (and zbuffer value) */
- for(a=0; a< R.totvert;a++) {
- if((a & 255)==0) ver= RE_findOrAddVert(a);
- else ver++;
-
- if(R.r.mode & R_PANORAMA) {
- vec[0]= co*ver->co[0] + si*ver->co[2];
- vec[1]= ver->co[1];
- vec[2]= -si*ver->co[0] + co*ver->co[2];
- }
- else {
- VECCOPY(vec, ver->co);
- }
- /* Go from wcs to hcs ... */
- projectfunc(vec, ver->ho);
- /* ... and clip in that system. */
- ver->clip = RE_testclip(ver->ho);
- /*
- Because all other ops are performed in other systems, this is
- the only thing that has to be done.
- */
- }
-
- /* calculate view coordinates (and zbuffer value) */
- for(a=0; a<R.tothalo; a++) {
- if((a & 255)==0) har= R.bloha[a>>8];
- else har++;
-
- if(R.r.mode & R_PANORAMA) {
- vec[0]= co*har->co[0] + si*har->co[2];
- vec[1]= har->co[1];
- vec[2]= -si*har->co[0] + co*har->co[2];
- }
- else {
- VECCOPY(vec, har->co);
- }
-
- projectfunc(vec, hoco);
-
- /* we clip halos less critical, but not for the Z */
- hoco[0]*= 0.5;
- hoco[1]*= 0.5;
-
- if( panotestclip(hoco) ) {
- har->miny= har->maxy= -10000; /* that way render clips it */
- }
- else if(hoco[3]<0.0) {
- har->miny= har->maxy= -10000; /* render clips it */
- }
- else /* do the projection...*/
- {
- /* bring back hocos */
- hoco[0]*= 2.0;
- hoco[1]*= 2.0;
-
- zn= hoco[3];
- har->xs= 0.5*R.rectx*(1.0+hoco[0]/zn); /* the 0.5 negates the previous 2...*/
- har->ys= 0.5*R.recty*(1.0+hoco[1]/zn);
-
- /* this should be the zbuffer coordinate */
- har->zs= 0x7FFFFF*(hoco[2]/zn);
- /* taking this from the face clip functions? seems ok... */
- har->zBufDist = 0x7FFFFFFF*(hoco[2]/zn);
-
- vec[0]+= har->hasize;
- projectfunc(vec, hoco);
- vec[0]-= har->hasize;
- zn= hoco[3];
- har->rad= fabs(har->xs- 0.5*R.rectx*(1.0+hoco[0]/zn));
-
- /* this clip is not really OK, to prevent stars to become too large */
- if(har->type & HA_ONLYSKY) {
- if(har->rad>3.0) har->rad= 3.0;
- }
-
- har->radsq= har->rad*har->rad;
-
- har->miny= har->ys - har->rad/R.ycor;
- har->maxy= har->ys + har->rad/R.ycor;
-
- /* the Zd value is still not really correct for pano */
-
- vec[2]-= har->hasize; /* z negative, otherwise it's clipped */
- projectfunc(vec, hoco);
- zn= hoco[3];
- zn= fabs( (float)har->zs - 0x7FFFFF*(hoco[2]/zn));
- har->zd= CLAMPIS(zn, 0, INT_MAX);
-
- }
-
- }
-
- /* set flags at 0 if clipped away */
- for(a=0; a<R.totvlak; a++) {
- if((a & 255)==0) vlr= R.blovl[a>>8];
- else vlr++;
-
- vlr->flag |= R_VISIBLE;
- if(vlr->v4) {
- if(vlr->v1->clip & vlr->v2->clip & vlr->v3->clip & vlr->v4->clip) vlr->flag &= ~R_VISIBLE;
- }
- else if(vlr->v1->clip & vlr->v2->clip & vlr->v3->clip) vlr->flag &= ~R_VISIBLE;
-
- }
-
-}
-
-/* ------------------------------------------------------------------------- */
-/* move to renderer */
-
-void set_normalflags(void)
-{
- VlakRen *vlr = NULL;
- float *v1, xn, yn, zn;
- int a1, doflip;
-
- /* switch normal 'snproj' values (define which axis is the optimal one for calculations) */
- for(a1=0; a1<R.totvlak; a1++) {
- if((a1 & 255)==0) vlr= R.blovl[a1>>8];
- else vlr++;
-
- /* abuse of this flag... this is code that just sets face normal in direction of camera */
- /* that convention we should get rid of */
- if((vlr->flag & R_NOPUNOFLIP)==0) {
-
- doflip= 0;
- if(R.r.mode & R_ORTHO) {
- if(vlr->n[2]>0.0) doflip= 1;
- }
- else {
- v1= vlr->v1->co;
- if( (v1[0]*vlr->n[0] +v1[1]*vlr->n[1] +v1[2]*vlr->n[2])<0.0 ) doflip= 1;
- }
- if(doflip) {
- vlr->n[0]= -vlr->n[0];
- vlr->n[1]= -vlr->n[1];
- vlr->n[2]= -vlr->n[2];
- }
- }
-
- /* recalculate puno. Displace & flipped matrices can screw up */
- vlr->puno= 0;
- if(!(vlr->flag & R_TANGENT)) {
- if( Inpf(vlr->n, vlr->v1->n) < 0.0 ) vlr->puno |= ME_FLIPV1;
- if( Inpf(vlr->n, vlr->v2->n) < 0.0 ) vlr->puno |= ME_FLIPV2;
- if( Inpf(vlr->n, vlr->v3->n) < 0.0 ) vlr->puno |= ME_FLIPV3;
- if(vlr->v4 && Inpf(vlr->n, vlr->v4->n) < 0.0 ) vlr->puno |= ME_FLIPV4;
- }
- xn= fabs(vlr->n[0]);
- yn= fabs(vlr->n[1]);
- zn= fabs(vlr->n[2]);
- if(zn>=xn && zn>=yn) vlr->snproj= 0;
- else if(yn>=xn && yn>=zn) vlr->snproj= 1;
- else vlr->snproj= 2;
-
- }
-}
diff --git a/source/blender/render/intern/source/renderPreAndPost.c b/source/blender/render/intern/source/renderPreAndPost.c
deleted file mode 100644
index 0753a73276b..00000000000
--- a/source/blender/render/intern/source/renderPreAndPost.c
+++ /dev/null
@@ -1,103 +0,0 @@
-/**
- *
- * ***** 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.
- *
- * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
- * All rights reserved.
- *
- * The Original Code is: all of this file.
- *
- * Contributor(s): none yet.
- *
- * ***** END GPL/BL DUAL LICENSE BLOCK *****
- * Prepare the scene data for rendering.
- *
- * $Id$
- */
-
-#include "MEM_guardedalloc.h"
-
-#include "DNA_group_types.h"
-
-#include "render.h"
-#include "renderPreAndPost.h"
-#include "RE_callbacks.h"
-
-#include "shadbuf.h"
-#include "envmap.h"
-#include "renderHelp.h"
-#include "radio.h"
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-/**
- * Rotate all objects, make shadowbuffers and environment maps.
- */
-void prepareScene()
-{
- GroupObject *go;
- extern void makeoctree(void);
-
- RE_local_get_renderdata();
-
- /* SHADOW BUFFER */
- for(go=R.lights.first; go; go= go->next) {
- LampRen *lar= go->lampren;
- if(lar->shb) makeshadowbuf(lar);
- if(RE_local_test_break()) break;
- }
-
- /* yafray: 'direct' radiosity, environment maps and octree init not needed for yafray render */
- /* although radio mode could be useful at some point, later */
- if (R.r.renderer==R_INTERN) {
-
- /* RADIO */
- if(R.r.mode & R_RADIO) do_radio_render();
-
- /* octree */
- if(R.r.mode & R_RAYTRACE) makeoctree();
-
- /* ENVIRONMENT MAPS */
- make_envmaps();
-
- }
-}
-
-void finalizeScene(void)
-{
- extern void freeoctree(void);
-
- /* Among other things, it releases the shadow buffers. */
- RE_local_free_renderdata();
- /* yafray: freeoctree not needed after yafray render, not initialized, see above */
- if (R.r.renderer==R_INTERN) {
- if(R.r.mode & R_RAYTRACE) freeoctree();
- }
-}
-
-
-void doClipping( void (*projectfunc)(float *, float *) )
-{
- setzbufvlaggen(projectfunc);
-}
-
-/* eof */
diff --git a/source/blender/render/intern/source/rendercore.c b/source/blender/render/intern/source/rendercore.c
index 379b5415604..b226346ede9 100644
--- a/source/blender/render/intern/source/rendercore.c
+++ b/source/blender/render/intern/source/rendercore.c
@@ -1,15 +1,12 @@
/**
* $Id$
*
- * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
+ * ***** BEGIN GPL 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.
+ * of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
@@ -23,11 +20,10 @@
* The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
* All rights reserved.
*
- * The Original Code is: all of this file.
+ * Contributors: Hos, Robert Wenzlaff.
+ * Contributors: 2004/2005/2006 Blender Foundation, full recode
*
- * Contributor(s): Hos, Robert Wenzlaff.
- *
- * ***** END GPL/BL DUAL LICENSE BLOCK *****
+ * ***** END GPL LICENSE BLOCK *****
*/
/* system includes */
@@ -36,83 +32,81 @@
#include <stdlib.h>
/* External modules: */
-#include "MEM_guardedalloc.h"
-#include "BLI_arithb.h"
#include "MTC_matrixops.h"
+#include "BLI_arithb.h"
+#include "BLI_blenlib.h"
+#include "BLI_rand.h"
+#include "BLI_jitter.h"
#include "BKE_utildefines.h"
-#include "DNA_camera_types.h"
#include "DNA_group_types.h"
#include "DNA_image_types.h"
#include "DNA_lamp_types.h"
+#include "DNA_material_types.h"
#include "DNA_mesh_types.h"
#include "DNA_meshdata_types.h"
#include "DNA_object_types.h"
#include "DNA_texture_types.h"
#include "BKE_global.h"
+#include "BKE_material.h"
#include "BKE_node.h"
#include "BKE_texture.h"
-#include "BLI_rand.h"
-
/* local include */
-#include "RE_callbacks.h"
-#include "render.h"
-#include "zbuf.h" /* stuff like bgnaccumbuf, fillrect, ...*/
+#include "renderpipeline.h"
+#include "render_types.h"
+#include "renderdatabase.h"
#include "pixelblending.h"
#include "pixelshading.h"
-#include "vanillaRenderPipe.h" /* transfercolour... */
#include "gammaCorrectionTables.h"
#include "shadbuf.h"
-#include "renderHelp.h"
+#include "zbuf.h"
-#include "jitter.h"
#include "texture.h"
/* own include */
#include "rendercore.h"
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include "SDL_thread.h"
-
-/* global for this file. struct render will be more dynamic later, to allow multiple renderers */
-RE_Render R;
+/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
+/* defined in pipeline.c, is hardcopy of active dynamic allocated Render */
+/* only to be used here in this file, it's for speed */
+extern struct Render R;
+/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
-float bluroffsx=0.0, bluroffsy=0.0; // set in initrender.c (bad, ton)
-
-/* x and y are current pixels to be rendered */
+/* x and y are current pixels in rect to be rendered */
+/* do not normalize! */
void calc_view_vector(float *view, float x, float y)
{
-
+
if(R.r.mode & R_ORTHO) {
view[0]= view[1]= 0.0;
}
else {
- view[0]= (x+(R.xstart)+bluroffsx +0.5);
+ /* move x and y to real viewplane coords */
+ x= (x/(float)R.winx);
+ view[0]= R.viewplane.xmin + x*(R.viewplane.xmax - R.viewplane.xmin);
- if(R.flag & R_SEC_FIELD) {
- if(R.r.mode & R_ODDFIELD) view[1]= (y+R.ystart)*R.ycor;
- else view[1]= (y+R.ystart+1.0)*R.ycor;
- }
- else view[1]= (y+R.ystart+bluroffsy+0.5)*R.ycor;
- }
- view[2]= -R.viewfac;
+ y= (y/(float)R.winy);
+ view[1]= R.viewplane.ymin + y*(R.viewplane.ymax - R.viewplane.ymin);
+
+// if(R.flag & R_SEC_FIELD) {
+// if(R.r.mode & R_ODDFIELD) view[1]= (y+R.ystart)*R.ycor;
+// else view[1]= (y+R.ystart+1.0)*R.ycor;
+// }
+// else view[1]= (y+R.ystart+R.bluroffsy+0.5)*R.ycor;
+ }
+
+ view[2]= -R.clipsta;
if(R.r.mode & R_PANORAMA) {
- float panoco, panosi, u, v;
- panoco = getPanovCo();
- panosi = getPanovSi();
-
- u= view[0]; v= view[2];
- view[0]= panoco*u + panosi*v;
- view[2]= -panosi*u + panoco*v;
+ float u= view[0]; float v= view[2];
+ view[0]= R.panoco*u + R.panosi*v;
+ view[2]= -R.panosi*u + R.panoco*v;
}
+
}
#if 0
@@ -194,32 +188,6 @@ float mistfactor(float zcor, float *co) /* dist en height, return alpha */
return (1.0-fac)* (1.0-R.wrld.misi);
}
-/* external for preview only */
-void RE_sky_char(float *view, char *col)
-{
- float f, colf[3];
- float dither_value;
-
- dither_value = ( (BLI_frand()-0.5)*R.r.dither_intensity)/256.0;
-
- shadeSkyPixelFloat(colf, view, view, NULL);
-
- f= 255.0*(colf[0]+dither_value);
- if(f<=0.0) col[0]= 0; else if(f>255.0) col[0]= 255;
- else col[0]= (char)f;
- f= 255.0*(colf[1]+dither_value);
- if(f<=0.0) col[1]= 0; else if(f>255.0) col[1]= 255;
- else col[1]= (char)f;
- f= 255.0*(colf[2]+dither_value);
- if(f<=0.0) col[2]= 0; else if(f>255.0) col[2]= 255;
- else col[2]= (char)f;
- col[3]= 1; /* to prevent wrong optimalisation alphaover of flares */
-}
-
-
-/* ************************************** */
-
-
static void spothalo(struct LampRen *lar, ShadeInput *shi, float *intens)
{
double a, b, c, disc, nray[3], npos[3];
@@ -433,9 +401,18 @@ static void renderspothalo(ShadeInput *shi, float *col, float alpha)
}
-static int calchalo_z(HaloRen *har, int zz)
+
+/* also used in zbuf.c */
+int count_mask(unsigned short mask)
{
+ if(R.samples)
+ return (R.samples->cmask[mask & 255]+R.samples->cmask[mask>>8]);
+ return 0;
+}
+static int calchalo_z(HaloRen *har, int zz)
+{
+
if(har->type & HA_ONLYSKY) {
if(zz!=0x7FFFFFFF) zz= - 0x7FFFFF;
}
@@ -445,186 +422,119 @@ static int calchalo_z(HaloRen *har, int zz)
return zz;
}
-static void scanlinehaloPS(int *rectz, long *rectdelta, float *rowbuf, short ys)
+static void halo_pixelstruct(HaloRen *har, float *rb, float dist, float xn, float yn, PixStr *ps)
{
- HaloRen *har = NULL;
- PixStr *ps;
- float dist, xsq, ysq, xn, yn;
- float *rb;
float col[4], accol[4];
- int a, *rz, zz, didgamma=0;
- long *rd;
- short minx, maxx, x, amount, amountm, flarec;
-
- for(a=0; a<R.tothalo; a++) {
- if((a & 255)==0) {
- har= R.bloha[a>>8];
- if( RE_local_test_break() ) break;
- }
- else har++;
-
- if(ys>har->maxy);
- else if(ys<har->miny);
- else {
- minx= floor(har->xs-har->rad);
- maxx= ceil(har->xs+har->rad);
+ int amount, amountm, zz, flarec;
+
+ amount= 0;
+ accol[0]=accol[1]=accol[2]=accol[3]= 0.0;
+ flarec= har->flarec;
+
+ while(ps) {
+ amountm= count_mask(ps->mask);
+ amount+= amountm;
+
+ zz= calchalo_z(har, ps->z);
+ if(zz> har->zs) {
+ float fac;
- if(maxx<0);
- else if(R.rectx<minx);
- else {
- if(minx<0) minx= 0;
- if(maxx>=R.rectx) maxx= R.rectx-1;
-
- rb= rowbuf + 4*minx;
- rd= rectdelta + minx;
- rz= rectz + minx;
-
- yn= (ys-har->ys)*R.ycor;
- ysq= yn*yn;
- for(x=minx; x<=maxx; x++) {
-
- xn= x-har->xs;
- xsq= xn*xn;
- dist= xsq+ysq;
-
- if(dist<har->radsq) {
-
- /* well yah, halo adding shouldnt be done gamma corrected, have to bypass it this way */
- /* alternative is moving it outside of thread renderlineDA */
- /* on positive side; the invert correct cancels out correcting halo color */
- if(do_gamma && didgamma==0) {
- float *buf= rowbuf;
- int xt;
- for(xt=0; xt<R.rectx; xt++, buf+=4) {
- buf[0]= sasqrt(buf[0]); // invers gamma 2.0
- buf[1]= sasqrt(buf[1]);
- buf[2]= sasqrt(buf[2]);
- }
- didgamma= 1;
- }
-
- flarec= har->flarec; /* har->pixels is only allowed to count once */
-
- if(*rd) { /* theres a pixel struct */
-
- ps= (PixStr *)(*rd);
- amount= 0;
- accol[0]=accol[1]=accol[2]=accol[3]= 0.0;
-
- while(ps) {
- amountm= count_mask(ps->mask);
- amount+= amountm;
-
- zz= calchalo_z(har, ps->z);
- if(zz> har->zs) {
- float fac;
-
- shadeHaloFloat(har, col, zz, dist, xn, yn, flarec);
- fac= ((float)amountm)/(float)R.osa;
- accol[0]+= fac*col[0];
- accol[1]+= fac*col[1];
- accol[2]+= fac*col[2];
- accol[3]+= fac*col[3];
- flarec= 0;
- }
-
- ps= ps->next;
- }
- /* now do the sky sub-pixels */
- amount= R.osa-amount;
- if(amount) {
- float fac;
-
- shadeHaloFloat(har, col, 0x7FFFFF, dist, xn, yn, flarec);
- fac= ((float)amount)/(float)R.osa;
- accol[0]+= fac*col[0];
- accol[1]+= fac*col[1];
- accol[2]+= fac*col[2];
- accol[3]+= fac*col[3];
- }
- col[0]= accol[0];
- col[1]= accol[1];
- col[2]= accol[2];
- col[3]= accol[3];
-
- addalphaAddfacFloat(rb, col, har->add);
- }
- else {
- zz= calchalo_z(har, *rz);
- if(zz> har->zs) {
-
- shadeHaloFloat(har, col, zz, dist, xn, yn, flarec);
- addalphaAddfacFloat(rb, col, har->add);
- }
- }
- }
- rb+=4;
- rz++;
- rd++;
- }
- }
+ shadeHaloFloat(har, col, zz, dist, xn, yn, flarec);
+ fac= ((float)amountm)/(float)R.osa;
+ accol[0]+= fac*col[0];
+ accol[1]+= fac*col[1];
+ accol[2]+= fac*col[2];
+ accol[3]+= fac*col[3];
+ flarec= 0;
}
+
+ ps= ps->next;
}
+ /* now do the sky sub-pixels */
+ amount= R.osa-amount;
+ if(amount) {
+ float fac;
- /* the entire scanline has to be put back in gammaspace */
- if(didgamma) {
- float *buf= rowbuf;
- int xt;
- for(xt=0; xt<R.rectx; xt++, buf+=4) {
- buf[0]*= (buf[0]); // gamma 2.0
- buf[1]*= (buf[1]);
- buf[2]*= (buf[2]);
- }
+ shadeHaloFloat(har, col, 0x7FFFFF, dist, xn, yn, flarec);
+ fac= ((float)amount)/(float)R.osa;
+ accol[0]+= fac*col[0];
+ accol[1]+= fac*col[1];
+ accol[2]+= fac*col[2];
+ accol[3]+= fac*col[3];
}
-
+ col[0]= accol[0];
+ col[1]= accol[1];
+ col[2]= accol[2];
+ col[3]= accol[3];
+
+ addalphaAddfacFloat(rb, col, har->add);
+
}
-static void scanlinehalo(int *rectz, float *rowbuf, short ys)
+static void halo_tile(RenderPart *pa, float *pass)
{
HaloRen *har = NULL;
+ rcti disprect= pa->disprect;
float dist, xsq, ysq, xn, yn, *rb;
float col[4];
- int a, *rz, zz;
- short minx, maxx, x;
+ long *rd= NULL;
+ int a, *rz, zz, y;
+ short minx, maxx, miny, maxy, x;
for(a=0; a<R.tothalo; a++) {
- if((a & 255)==0) har= R.bloha[a>>8];
+ if((a & 255)==0) {
+ if(R.test_break() ) break;
+ har= R.bloha[a>>8];
+ }
else har++;
- if(RE_local_test_break() ) break;
-
- if(ys>har->maxy);
- else if(ys<har->miny);
+ /* clip halo with y */
+ if(disprect.ymin > har->maxy);
+ else if(disprect.ymax < har->miny);
else {
+
minx= floor(har->xs-har->rad);
maxx= ceil(har->xs+har->rad);
- if(maxx<0);
- else if(R.rectx<minx);
+ if(disprect.xmin > maxx);
+ else if(disprect.xmax < minx);
else {
- if(minx<0) minx= 0;
- if(maxx>=R.rectx) maxx= R.rectx-1;
-
- rb= rowbuf + 4*minx;
- rz= rectz + minx;
-
- yn= (ys-har->ys)*R.ycor;
- ysq= yn*yn;
- for(x=minx; x<=maxx; x++) {
- zz= calchalo_z(har, *rz);
- if(zz> har->zs) {
+ minx= MAX2(minx, disprect.xmin);
+ maxx= MIN2(maxx, disprect.xmax);
+
+ miny= MAX2(har->miny, disprect.ymin);
+ maxy= MIN2(har->maxy, disprect.ymax);
+
+ for(y=miny; y<maxy; y++) {
+ int rectofs= (y-disprect.ymin)*pa->rectx + (minx - disprect.xmin);
+ rb= pass + 4*rectofs;
+ rz= pa->rectz + rectofs;
+
+ if(pa->rectdaps)
+ rd= pa->rectdaps + rectofs;
+
+ yn= (y-har->ys)*R.ycor;
+ ysq= yn*yn;
+
+ for(x=minx; x<maxx; x++, rb+=4, rz++) {
xn= x- har->xs;
xsq= xn*xn;
dist= xsq+ysq;
if(dist<har->radsq) {
- shadeHaloFloat(har, col, zz, dist, xn, yn, har->flarec);
- addalphaAddfacFloat(rb, col, har->add);
+ if(rd && *rd) {
+ halo_pixelstruct(har, rb, dist, xn, yn, (PixStr *)*rd);
+ }
+ else {
+ zz= calchalo_z(har, *rz);
+ if(zz> har->zs) {
+ shadeHaloFloat(har, col, zz, dist, xn, yn, har->flarec);
+ addalphaAddfacFloat(rb, col, har->add);
+ }
+ }
}
+ if(rd) rd++;
}
-
- rb+=4;
- rz++;
}
}
}
@@ -727,7 +637,7 @@ static float area_lamp_energy(float *co, float *vn, LampRen *lar)
return pow(fac*lar->areasize, lar->k); // corrected for buttons size and lar->dist^2
}
-float spec(float inp, int hard)
+static float spec(float inp, int hard)
{
float b1;
@@ -767,7 +677,7 @@ float spec(float inp, int hard)
return inp;
}
-float Phong_Spec( float *n, float *l, float *v, int hard, int tangent )
+static float Phong_Spec( float *n, float *l, float *v, int hard, int tangent )
{
float h[3];
float rslt;
@@ -788,7 +698,7 @@ float Phong_Spec( float *n, float *l, float *v, int hard, int tangent )
/* reduced cook torrance spec (for off-specular peak) */
-float CookTorr_Spec(float *n, float *l, float *v, int hard, int tangent)
+static float CookTorr_Spec(float *n, float *l, float *v, int hard, int tangent)
{
float i, nh, nv, h[3];
@@ -812,7 +722,7 @@ float CookTorr_Spec(float *n, float *l, float *v, int hard, int tangent)
}
/* Blinn spec */
-float Blinn_Spec(float *n, float *l, float *v, float refrac, float spec_power, int tangent)
+static float Blinn_Spec(float *n, float *l, float *v, float refrac, float spec_power, int tangent)
{
float i, nh, nv, nl, vh, h[3];
float a, b, c, g=0.0, p, f, ang;
@@ -866,7 +776,7 @@ float Blinn_Spec(float *n, float *l, float *v, float refrac, float spec_power, i
}
/* cartoon render spec */
-float Toon_Spec( float *n, float *l, float *v, float size, float smooth, int tangent)
+static float Toon_Spec( float *n, float *l, float *v, float size, float smooth, int tangent)
{
float h[3];
float ang;
@@ -890,7 +800,7 @@ float Toon_Spec( float *n, float *l, float *v, float size, float smooth, int tan
}
/* Ward isotropic gaussian spec */
-float WardIso_Spec( float *n, float *l, float *v, float rms, int tangent)
+static float WardIso_Spec( float *n, float *l, float *v, float rms, int tangent)
{
float i, nh, nv, nl, h[3], angle, alpha;
@@ -916,13 +826,13 @@ float WardIso_Spec( float *n, float *l, float *v, float rms, int tangent)
angle = tan(saacos(nh));
alpha = MAX2(rms,0.001);
- i= nl * (1.0/(4*PI*alpha*alpha)) * (exp( -(angle*angle)/(alpha*alpha))/(sqrt(nv*nl)));
+ i= nl * (1.0/(4*M_PI*alpha*alpha)) * (exp( -(angle*angle)/(alpha*alpha))/(sqrt(nv*nl)));
return i;
}
/* cartoon render diffuse */
-float Toon_Diff( float *n, float *l, float *v, float size, float smooth )
+static float Toon_Diff( float *n, float *l, float *v, float size, float smooth )
{
float rslt, ang;
@@ -941,7 +851,7 @@ float Toon_Diff( float *n, float *l, float *v, float size, float smooth )
/* 'nl' is either dot product, or return value of area light */
/* in latter case, only last multiplication uses 'nl' */
-static float OrenNayar_Diff_i(float nl, float *n, float *l, float *v, float rough )
+static float OrenNayar_Diff(float nl, float *n, float *l, float *v, float rough )
{
float i, nh, nv, vh, realnl, h[3];
float a, b, t, A, B;
@@ -1000,15 +910,8 @@ static float OrenNayar_Diff_i(float nl, float *n, float *l, float *v, float roug
return i;
}
-/* Oren Nayar diffuse */
-float OrenNayar_Diff(float *n, float *l, float *v, float rough )
-{
- float nl= n[0]*l[0] + n[1]*l[1] + n[2]*l[2];
- return OrenNayar_Diff_i(nl, n, l, v, rough);
-}
-
/* Minnaert diffuse */
-float Minnaert_Diff(float nl, float *n, float *v, float darkness)
+static float Minnaert_Diff(float nl, float *n, float *v, float darkness)
{
float i, nv;
@@ -1030,7 +933,7 @@ float Minnaert_Diff(float nl, float *n, float *v, float darkness)
return i;
}
-float Fresnel_Diff(float *vn, float *lv, float *view, float fac_i, float fac)
+static float Fresnel_Diff(float *vn, float *lv, float *view, float fac_i, float fac)
{
return fresnel_fac(lv, vn, fac_i, fac);
}
@@ -1084,6 +987,7 @@ void calc_R_ref(ShadeInput *shi)
}
+/* called from ray.c */
void shade_color(ShadeInput *shi, ShadeResult *shr)
{
Material *ma= shi->mat;
@@ -1114,91 +1018,8 @@ void shade_color(ShadeInput *shi, ShadeResult *shr)
shr->alpha= shi->alpha;
}
-/* r g b = current value, col = new value, fac==0 is no change */
-/* if g==NULL, it only does r channel */
-void ramp_blend(int type, float *r, float *g, float *b, float fac, float *col)
-{
- float tmp, facm= 1.0-fac;
-
- switch (type) {
- case MA_RAMP_BLEND:
- *r = facm*(*r) + fac*col[0];
- if(g) {
- *g = facm*(*g) + fac*col[1];
- *b = facm*(*b) + fac*col[2];
- }
- break;
- case MA_RAMP_ADD:
- *r += fac*col[0];
- if(g) {
- *g += fac*col[1];
- *b += fac*col[2];
- }
- break;
- case MA_RAMP_MULT:
- *r *= (facm + fac*col[0]);
- if(g) {
- *g *= (facm + fac*col[1]);
- *b *= (facm + fac*col[2]);
- }
- break;
- case MA_RAMP_SCREEN:
- *r = 1.0 - (facm + fac*(1.0 - col[0])) * (1.0 - *r);
- if(g) {
- *g = 1.0 - (facm + fac*(1.0 - col[1])) * (1.0 - *g);
- *b = 1.0 - (facm + fac*(1.0 - col[2])) * (1.0 - *b);
- }
- break;
- case MA_RAMP_SUB:
- *r -= fac*col[0];
- if(g) {
- *g -= fac*col[1];
- *b -= fac*col[2];
- }
- break;
- case MA_RAMP_DIV:
- if(col[0]!=0.0)
- *r = facm*(*r) + fac*(*r)/col[0];
- if(g) {
- if(col[1]!=0.0)
- *g = facm*(*g) + fac*(*g)/col[1];
- if(col[2]!=0.0)
- *b = facm*(*b) + fac*(*b)/col[2];
- }
- break;
- case MA_RAMP_DIFF:
- *r = facm*(*r) + fac*fabs(*r-col[0]);
- if(g) {
- *g = facm*(*g) + fac*fabs(*g-col[1]);
- *b = facm*(*b) + fac*fabs(*b-col[2]);
- }
- break;
- case MA_RAMP_DARK:
- tmp= fac*col[0];
- if(tmp < *r) *r= tmp;
- if(g) {
- tmp= fac*col[1];
- if(tmp < *g) *g= tmp;
- tmp= fac*col[2];
- if(tmp < *b) *b= tmp;
- }
- break;
- case MA_RAMP_LIGHT:
- tmp= fac*col[0];
- if(tmp > *r) *r= tmp;
- if(g) {
- tmp= fac*col[1];
- if(tmp > *g) *g= tmp;
- tmp= fac*col[2];
- if(tmp > *b) *b= tmp;
- }
- break;
- }
-
-}
-
/* ramp for at end of shade */
-void ramp_diffuse_result(float *diff, ShadeInput *shi)
+static void ramp_diffuse_result(float *diff, ShadeInput *shi)
{
Material *ma= shi->mat;
float col[4], fac=0;
@@ -1218,7 +1039,7 @@ void ramp_diffuse_result(float *diff, ShadeInput *shi)
}
/* r,g,b denote energy, ramp is used with different values to make new material color */
-void add_to_diffuse(float *diff, ShadeInput *shi, float is, float r, float g, float b)
+static void add_to_diffuse(float *diff, ShadeInput *shi, float is, float r, float g, float b)
{
Material *ma= shi->mat;
float col[4], colt[3], fac=0;
@@ -1267,7 +1088,7 @@ void add_to_diffuse(float *diff, ShadeInput *shi, float is, float r, float g, fl
}
}
-void ramp_spec_result(float *specr, float *specg, float *specb, ShadeInput *shi)
+static void ramp_spec_result(float *specr, float *specg, float *specb, ShadeInput *shi)
{
Material *ma= shi->mat;
float col[4];
@@ -1286,7 +1107,7 @@ void ramp_spec_result(float *specr, float *specg, float *specb, ShadeInput *shi)
}
/* is = dot product shade, t = spec energy */
-void do_specular_ramp(ShadeInput *shi, float is, float t, float *spec)
+static void do_specular_ramp(ShadeInput *shi, float is, float t, float *spec)
{
Material *ma= shi->mat;
float col[4];
@@ -1323,32 +1144,32 @@ void do_specular_ramp(ShadeInput *shi, float is, float t, float *spec)
-static void ambient_occlusion(World *wrld, ShadeInput *shi, ShadeResult *shr)
+static void ambient_occlusion(ShadeInput *shi, ShadeResult *shr)
{
float f, shadfac[4];
- if((wrld->mode & WO_AMB_OCC) && (R.r.mode & R_RAYTRACE) && shi->amb!=0.0) {
- ray_ao(shi, wrld, shadfac);
+ if((R.wrld.mode & WO_AMB_OCC) && (R.r.mode & R_RAYTRACE) && shi->amb!=0.0) {
+ ray_ao(shi, shadfac);
- if(wrld->aocolor==WO_AOPLAIN) {
- if (wrld->aomix==WO_AOADDSUB) shadfac[3] = 2.0*shadfac[3]-1.0;
- else if (wrld->aomix==WO_AOSUB) shadfac[3] = shadfac[3]-1.0;
+ if(R.wrld.aocolor==WO_AOPLAIN) {
+ if (R.wrld.aomix==WO_AOADDSUB) shadfac[3] = 2.0*shadfac[3]-1.0;
+ else if (R.wrld.aomix==WO_AOSUB) shadfac[3] = shadfac[3]-1.0;
- f= wrld->aoenergy*shadfac[3]*shi->amb;
+ f= R.wrld.aoenergy*shadfac[3]*shi->amb;
add_to_diffuse(shr->diff, shi, f, f, f, f);
}
else {
- if (wrld->aomix==WO_AOADDSUB) {
+ if (R.wrld.aomix==WO_AOADDSUB) {
shadfac[0] = 2.0*shadfac[0]-1.0;
shadfac[1] = 2.0*shadfac[1]-1.0;
shadfac[2] = 2.0*shadfac[2]-1.0;
}
- else if (wrld->aomix==WO_AOSUB) {
+ else if (R.wrld.aomix==WO_AOSUB) {
shadfac[0] = shadfac[0]-1.0;
shadfac[1] = shadfac[1]-1.0;
shadfac[2] = shadfac[2]-1.0;
}
- f= wrld->aoenergy*shi->amb;
+ f= R.wrld.aoenergy*shi->amb;
add_to_diffuse(shr->diff, shi, f, f*shadfac[0], f*shadfac[1], f*shadfac[2]);
}
}
@@ -1410,7 +1231,7 @@ void shade_lamp_loop(ShadeInput *shi, ShadeResult *shr)
if(lar->shb) i = testshadowbuf(lar->shb, shi->co, shi->dxco, shi->dyco, inp);
else {
float shad[4];
- //ray_shadow(shi, lar, shad);
+ ray_shadow(shi, lar, shad);
i= shad[3];
}
@@ -1435,7 +1256,7 @@ void shade_lamp_loop(ShadeInput *shi, ShadeResult *shr)
/* single sided? */
if( shi->facenor[0]*lv[0] + shi->facenor[1]*lv[1] + shi->facenor[2]*lv[2] > -0.01) {
- //ray_shadow(shi, lar, shad);
+ ray_shadow(shi, lar, shad);
shadfac[3]+= shad[3];
ir+= 1.0;
}
@@ -1451,7 +1272,7 @@ void shade_lamp_loop(ShadeInput *shi, ShadeResult *shr)
if((R.wrld.mode & WO_AMB_OCC) && (R.r.mode & R_RAYTRACE) && shi->amb!=0.0) {
float f;
- ray_ao(shi, &R.wrld, shadfac); // shadfac==0: full light
+ ray_ao(shi, shadfac); // shadfac==0: full light
shadfac[3]= 1.0-shadfac[3];
f= R.wrld.aoenergy*shadfac[3]*shi->amb;
@@ -1511,7 +1332,7 @@ void shade_lamp_loop(ShadeInput *shi, ShadeResult *shr)
shr->diff[2]= shi->b*shi->emit;
}
- ambient_occlusion(&R.wrld, shi, shr);
+ ambient_occlusion(shi, shr);
for(go=lights->first; go; go= go->next) {
lar= go->lampren;
@@ -1681,7 +1502,7 @@ void shade_lamp_loop(ShadeInput *shi, ShadeResult *shr)
}
/* diffuse shaders (oren nayer gets inp from area light) */
- if(ma->diff_shader==MA_DIFF_ORENNAYAR) is= OrenNayar_Diff_i(inp, vn, lv, view, ma->roughness);
+ if(ma->diff_shader==MA_DIFF_ORENNAYAR) is= OrenNayar_Diff(inp, vn, lv, view, ma->roughness);
else if(ma->diff_shader==MA_DIFF_TOON) is= Toon_Diff(vn, lv, view, ma->param[0], ma->param[1]);
else if(ma->diff_shader==MA_DIFF_MINNAERT) is= Minnaert_Diff(inp, vn, view, ma->darkness);
else if(ma->diff_shader==MA_DIFF_FRESNEL) is= Fresnel_Diff(vn, lv, view, ma->param[0], ma->param[1]);
@@ -1709,7 +1530,7 @@ void shade_lamp_loop(ShadeInput *shi, ShadeResult *shr)
shadfac[3] = testshadowbuf(lar->shb, shi->co, shi->dxco, shi->dyco, inp);
}
else if(lar->mode & LA_SHAD_RAY) {
- //ray_shadow(shi, lar, shadfac);
+ ray_shadow(shi, lar, shadfac);
}
/* warning, here it skips the loop */
@@ -2016,9 +1837,9 @@ void shade_input_set_coords(ShadeInput *shi, float u, float v, int i1, int i2, i
if(mode & MA_TANGENT_V) {
float *s1, *s2, *s3;
- s1= RE_vertren_get_tangent(v1, 0);
- s2= RE_vertren_get_tangent(v2, 0);
- s3= RE_vertren_get_tangent(v3, 0);
+ s1= RE_vertren_get_tangent(&R, v1, 0);
+ s2= RE_vertren_get_tangent(&R, v2, 0);
+ s3= RE_vertren_get_tangent(&R, v3, 0);
if(s1 && s2 && s3) {
shi->tang[0]= (l*s3[0] - u*s1[0] - v*s2[0]);
shi->tang[1]= (l*s3[1] - u*s1[1] - v*s2[1]);
@@ -2177,9 +1998,9 @@ void shade_input_set_coords(ShadeInput *shi, float u, float v, int i1, int i2, i
if(mode & MA_RADIO) {
float *r1, *r2, *r3;
- r1= RE_vertren_get_rad(v1, 0);
- r2= RE_vertren_get_rad(v2, 0);
- r3= RE_vertren_get_rad(v3, 0);
+ r1= RE_vertren_get_rad(&R, v1, 0);
+ r2= RE_vertren_get_rad(&R, v2, 0);
+ r3= RE_vertren_get_rad(&R, v3, 0);
if(r1 && r2 && r3) {
shi->rad[0]= (l*r3[0] - u*r1[0] - v*r2[0]);
@@ -2200,9 +2021,9 @@ void shade_input_set_coords(ShadeInput *shi, float u, float v, int i1, int i2, i
if(texco & TEXCO_STRESS) {
float *s1, *s2, *s3;
- s1= RE_vertren_get_stress(v1, 0);
- s2= RE_vertren_get_stress(v2, 0);
- s3= RE_vertren_get_stress(v3, 0);
+ s1= RE_vertren_get_stress(&R, v1, 0);
+ s2= RE_vertren_get_stress(&R, v2, 0);
+ s3= RE_vertren_get_stress(&R, v3, 0);
if(s1 && s2 && s3) {
shi->stress= l*s3[0] - u*s1[0] - v*s2[0];
if(shi->stress<1.0f) shi->stress-= 1.0f;
@@ -2250,18 +2071,6 @@ static float isec_view_line(float *view, float *v3, float *v4)
}
#endif
-void matlayer_blend(MaterialLayer *ml, float blendfac, ShadeResult *target, ShadeResult *src)
-{
-
- if(ml->flag & ML_DIFFUSE)
- ramp_blend(ml->blendmethod, target->diff, target->diff+1, target->diff+2, blendfac*src->alpha, src->diff);
-
- if(ml->flag & ML_SPECULAR)
- ramp_blend(ml->blendmethod, target->spec, target->spec+1, target->spec+2, blendfac*src->alpha, src->spec);
-
- if(ml->flag & ML_ALPHA)
- ramp_blend(ml->blendmethod, &target->alpha, NULL, NULL, blendfac, &src->alpha);
-}
/* also used as callback for nodes */
void shade_material_loop(ShadeInput *shi, ShadeResult *shr)
@@ -2301,7 +2110,7 @@ void shade_material_loop(ShadeInput *shi, ShadeResult *shr)
/* note, facenr declared volatile due to over-eager -O2 optimizations
* on cygwin (particularly -frerun-cse-after-loop)
*/
-void *shadepixel(float x, float y, int z, volatile int facenr, int mask, float *col, float *rco)
+void *shadepixel(RenderPart *pa, float x, float y, int z, volatile int facenr, int mask, float *col, float *rco)
{
ShadeResult shr;
ShadeInput shi;
@@ -2310,10 +2119,11 @@ void *shadepixel(float x, float y, int z, volatile int facenr, int mask, float *
if(facenr< 0) { /* error */
return NULL;
}
- /* currently in use for dithering (soft shadow) and detecting thread */
+ /* currently in use for dithering (soft shadow) node preview */
shi.xs= (int)(x+0.5f);
shi.ys= (int)(y+0.5f);
- shi.do_preview= 0;
+ shi.thread= pa->thread;
+ shi.do_preview= R.r.scemode & R_NODE_PREVIEW;
/* mask is used to indicate amount of samples (ray shad/mir and AO) */
shi.mask= mask;
@@ -2327,7 +2137,7 @@ void *shadepixel(float x, float y, int z, volatile int facenr, int mask, float *
VertRen *v1;
float alpha, fac, zcor;
- vlr= RE_findOrAddVlak( (facenr-1) & 0x7FFFFF);
+ vlr= RE_findOrAddVlak(&R, (facenr-1) & 0x7FFFFF);
shi.vlr= vlr;
shi.mat= vlr->mat;
@@ -2341,7 +2151,7 @@ void *shadepixel(float x, float y, int z, volatile int facenr, int mask, float *
v1= vlr->v1;
/* COXYZ AND VIEW VECTOR */
- calc_view_vector(shi.view, x, y);
+ calc_view_vector(shi.view, x, y); /* returns not normalized, so is in viewplane coords */
/* wire cannot use normal for calculating shi.co */
if(shi.mat->mode & MA_WIRE) {
@@ -2364,11 +2174,11 @@ void *shadepixel(float x, float y, int z, volatile int facenr, int mask, float *
/* ortho viewplane cannot intersect using view vector originating in (0,0,0) */
if(R.r.mode & R_ORTHO) {
/* x and y 3d coordinate can be derived from pixel coord and winmat */
- float fx= 2.0/(R.rectx*R.winmat[0][0]);
- float fy= 2.0/(R.recty*R.winmat[1][1]);
+ float fx= 2.0/(R.winx*R.winmat[0][0]);
+ float fy= 2.0/(R.winy*R.winmat[1][1]);
- shi.co[0]= (0.5 + x - 0.5*R.rectx)*fx - R.winmat[3][0]/R.winmat[0][0];
- shi.co[1]= (0.5 + y - 0.5*R.recty)*fy - R.winmat[3][1]/R.winmat[1][1];
+ shi.co[0]= (0.5 + x - 0.5*R.winx)*fx - R.winmat[3][0]/R.winmat[0][0];
+ shi.co[1]= (0.5 + y - 0.5*R.winy)*fy - R.winmat[3][1]/R.winmat[1][1];
/* using a*x + b*y + c*z = d equation, (a b c) is normal */
if(shi.facenor[2]!=0.0f)
@@ -2407,15 +2217,15 @@ void *shadepixel(float x, float y, int z, volatile int facenr, int mask, float *
/* pixel dx/dy for render coord */
if(shi.osatex || (R.r.mode & R_SHADOW) ) {
- float u= dface/(div-shi.facenor[0]);
- float v= dface/(div- R.ycor*shi.facenor[1]);
+ float u= dface/(div - R.viewdx*shi.facenor[0]);
+ float v= dface/(div - R.viewdy*shi.facenor[1]);
- shi.dxco[0]= shi.co[0]- (shi.view[0]-1.0)*u;
+ shi.dxco[0]= shi.co[0]- (shi.view[0]-R.viewdx)*u;
shi.dxco[1]= shi.co[1]- (shi.view[1])*u;
shi.dxco[2]= shi.co[2]- (shi.view[2])*u;
shi.dyco[0]= shi.co[0]- (shi.view[0])*v;
- shi.dyco[1]= shi.co[1]- (shi.view[1]-1.0*R.ycor)*v;
+ shi.dyco[1]= shi.co[1]- (shi.view[1]-R.viewdy)*v;
shi.dyco[2]= shi.co[2]- (shi.view[2])*v;
}
@@ -2424,14 +2234,14 @@ void *shadepixel(float x, float y, int z, volatile int facenr, int mask, float *
/* rco might be used for sky texture */
VECCOPY(rco, shi.co);
- /* cannot normalise earlier, code above needs it at pixel level */
+ /* cannot normalise earlier, code above needs it at viewplane level */
fac= Normalise(shi.view);
zcor*= fac; // for mist, distance of point from camera
if(shi.osatex) {
if( (shi.mat->texco & TEXCO_REFL) ) {
- shi.dxview= -1.0/fac;
- shi.dyview= -R.ycor/fac;
+ shi.dxview= -R.viewdx/fac;
+ shi.dyview= -R.viewdy/fac;
}
}
@@ -2443,12 +2253,12 @@ void *shadepixel(float x, float y, int z, volatile int facenr, int mask, float *
/* this only avalailable for scanline */
if(shi.mat->texco & TEXCO_WINDOW) {
- shi.winco[0]= (x+(R.xstart))/(float)R.afmx;
- shi.winco[1]= (y+(R.ystart))/(float)R.afmy;
+ shi.winco[0]= -1.0f + 2.0f*x/(float)R.winx;
+ shi.winco[1]= -1.0f + 2.0f*y/(float)R.winy;
shi.winco[2]= 0.0;
if(shi.osatex) {
- shi.dxwin[0]= 0.5/(float)R.r.xsch;
- shi.dywin[1]= 0.5/(float)R.r.ysch;
+ shi.dxwin[0]= 2.0/(float)R.winx;
+ shi.dywin[1]= 2.0/(float)R.winy;
shi.dxwin[1]= shi.dxwin[2]= 0.0;
shi.dywin[0]= shi.dywin[2]= 0.0;
}
@@ -2464,15 +2274,18 @@ void *shadepixel(float x, float y, int z, volatile int facenr, int mask, float *
v2= vlr->v2; v3= vlr->v3;
}
- s1= RE_vertren_get_sticky(v1, 0);
- s2= RE_vertren_get_sticky(v2, 0);
- s3= RE_vertren_get_sticky(v3, 0);
+ s1= RE_vertren_get_sticky(&R, v1, 0);
+ s2= RE_vertren_get_sticky(&R, v2, 0);
+ s3= RE_vertren_get_sticky(&R, v3, 0);
if(s1 && s2 && s3) {
- extern float Zmulx, Zmuly;
+ float Zmulx, Zmuly;
float hox, hoy, l, dl, u, v;
float s00, s01, s10, s11, detsh;
+ /* XXXX */
+ Zmulx= R.winx; Zmuly= R.winy;
+
s00= v3->ho[0]/v3->ho[3] - v1->ho[0]/v1->ho[3];
s01= v3->ho[1]/v3->ho[3] - v1->ho[1]/v1->ho[3];
s10= v3->ho[0]/v3->ho[3] - v2->ho[0]/v2->ho[3];
@@ -2598,12 +2411,12 @@ void *shadepixel(float x, float y, int z, volatile int facenr, int mask, float *
return vlr;
}
-static void shadepixel_sky(float x, float y, int z, int facenr, int mask, float *colf)
+static void shadepixel_sky(RenderPart *pa, float x, float y, int z, int facenr, int mask, float *colf)
{
VlakRen *vlr;
float collector[4], rco[3];
- vlr= shadepixel(x, y, z, facenr, mask, colf, rco);
+ vlr= shadepixel(pa, x, y, z, facenr, mask, colf, rco);
if(colf[3] != 1.0) {
/* bail out when raytrace transparency (sky included already) */
if(vlr && (R.r.mode & R_RAYTRACE))
@@ -2615,120 +2428,30 @@ static void shadepixel_sky(float x, float y, int z, int facenr, int mask, float
}
}
-/* ************* pixel struct ******** */
-
-static PixStrMain psmfirst;
-static int psmteller;
-
-static PixStr *addpsmain(void)
-{
- PixStrMain *psm;
-
- psm= &psmfirst;
-
- while(psm->next) {
- psm= psm->next;
- }
-
- psm->next= (PixStrMain *)MEM_mallocN(sizeof(PixStrMain),"pixstrMain");
-
- psm= psm->next;
- psm->next=0;
- psm->ps= (PixStr *)MEM_mallocN(4096*sizeof(PixStr),"pixstr");
- psmteller= 0;
-
- return psm->ps;
-}
-
-static void freeps(void)
-{
- PixStrMain *psm,*next;
-
- psm= &psmfirst;
-
- while(psm) {
- next= psm->next;
- if(psm->ps) {
- MEM_freeN(psm->ps);
- psm->ps= 0;
- }
- if(psm!= &psmfirst) MEM_freeN(psm);
- psm= next;
- }
-
- psmfirst.next= 0;
- psmfirst.ps= 0;
-}
-
-static void addps(long *rd, int facenr, int z, unsigned short mask)
-{
- static PixStr *cur;
- PixStr *ps, *last = NULL;
-
- if(*rd) {
- ps= (PixStr *)(*rd);
-
- while(ps) {
- if( ps->facenr == facenr ) {
- ps->mask |= mask;
- return;
- }
- last= ps;
- ps= ps->next;
- }
- }
-
- /* make new PS (pixel struct) */
- if((psmteller & 4095)==0) cur= addpsmain();
- else cur++;
- psmteller++;
-
- if(last) last->next= cur;
- else *rd= (long)cur;
-
- cur->next= NULL;
- cur->facenr= facenr;
- cur->z= z;
- cur->mask = mask;
-}
-
-
-int count_mask(unsigned short mask)
-{
- extern char cmask[256];
- return (cmask[mask & 255]+cmask[mask>>8]);
-}
-
-static void edge_enhance(void)
+/* adds only alpha values */
+static void edge_enhance_calc(RenderPart *pa, float *rectf)
{
/* use zbuffer to define edges, add it to the image */
- int val, y, x, col, *rz, *rz1, *rz2, *rz3;
+ int y, x, col, *rz, *rz1, *rz2, *rz3;
int zval1, zval2, zval3;
- char *cp;
+ float *rf;
/* shift values in zbuffer 4 to the right, for filter we need multiplying with 12 max */
- rz= (int *)R.rectz;
+ rz= pa->rectz;
if(rz==NULL) return;
- for(y=0; y<R.recty; y++) {
- for(x=0; x<R.rectx; x++, rz++) (*rz)>>= 4;
+ for(y=0; y<pa->recty; y++) {
+ for(x=0; x<pa->rectx; x++, rz++) (*rz)>>= 4;
}
- rz1= (int *)R.rectz;
- rz2= rz1+R.rectx;
- rz3= rz2+R.rectx;
-
- if(R.r.mode & R_OSA) {
- cp= (char *)(R.rectaccu+R.rectx);
- }
- else {
- cp= (char *)(R.rectot+R.rectx);
- }
- cp+= 4;
+ rz1= pa->rectz;
+ rz2= rz1+pa->rectx;
+ rz3= rz2+pa->rectx;
- for(y=0; y<R.recty-2; y++) {
-
- for(x=0; x<R.rectx-2; x++, rz++, rz1++, rz2++, rz3++, cp+=4) {
+ rf= rectf+pa->rectx+1;
+
+ for(y=0; y<pa->recty-2; y++) {
+ for(x=0; x<pa->rectx-2; x++, rz1++, rz2++, rz3++, rf++) {
/* prevent overflow with sky z values */
zval1= rz1[0] + 2*rz1[1] + rz1[2];
@@ -2742,482 +2465,348 @@ static void edge_enhance(void)
else col= (R.r.edgeint*col)>>8;
if(col>0) {
- if(col>255) col= 255;
+ float fcol;
- if(R.r.mode & R_OSA) {
- col/= R.osa;
-
- val= cp[3]+col;
- if(val>255) cp[3]= 255; else cp[3]= val;
- }
- else {
- val= cp[0]- col;
- if(val<0) cp[0]= 0; else cp[0]= val;
- val= cp[1]- col;
- if(val<0) cp[1]= 0; else cp[1]= val;
- val= cp[2]- col;
- if(val<0) cp[2]= 0; else cp[2]= val;
- }
+ if(col>255) fcol= 1.0f;
+ else fcol= (float)col/255.0f;
+
+ if(R.osa)
+ *rf+= fcol/(float)R.osa;
+ else
+ *rf= fcol;
}
}
- rz++;
rz1+= 2;
rz2+= 2;
rz3+= 2;
- cp+= 8;
+ rf+= 2;
}
+}
+static void edge_enhance_add(RenderPart *pa, float *rectf, float *arect)
+{
+ float addcol[4];
+ int pix;
+
+ for(pix= pa->rectx*pa->recty; pix>0; pix--, arect++, rectf+=4) {
+ if(*arect != 0.0f) {
+ addcol[0]= *arect * R.r.edgeR;
+ addcol[1]= *arect * R.r.edgeG;
+ addcol[2]= *arect * R.r.edgeB;
+ addcol[3]= *arect;
+ addAlphaOverFloat(rectf, addcol);
+ }
+ }
}
+
/* ********************* MAINLOOPS ******************** */
-struct renderlineDA {
- long *rd;
- int *rz;
- float *rb1, *rb2, *rb3;
- float *acol;
- int y;
-};
-
-static int do_renderlineDA(void *poin)
+
+static void shadeDA_tile(RenderPart *pa, float *rectf, float *recta)
{
- struct renderlineDA *rl= poin;
PixStr *ps;
float xs, ys;
- float fcol[4], *acol=NULL, *rb1, *rb2, *rb3;
- long *rd= rl->rd;
+ float fcol[4], *rf, *grf, *acol= NULL;
+ long *rd, *rectdaps= pa->rectdaps;
int zbuf, samp, curmask, face, mask, fullmask;
- int b, x, full_osa, seed;
+ int b, x, y, full_osa, seed, crop=0;
- /* we set per pixel a fixed seed, for random AO and shadow samples */
- seed= (R.ystart + rl->y + R.afmy)*R.r.xsch + R.xstart + R.afmx;
+ if(R.test_break()) return;
+ /* we set per pixel a fixed seed, for random AO and shadow samples */
+ seed= pa->rectx*pa->disprect.ymin;
+
fullmask= (1<<R.osa)-1;
- rb1= rl->rb1;
- rb2= rl->rb2;
- rb3= rl->rb3;
- if(R.flag & R_ZTRA) { /* zbuf tra */
- abufsetrow(rl->acol, rl->y);
- acol= rl->acol;
+ /* might need it for gamma, in end of this function */
+ grf= rectf;
+
+ /* filtered render, for now we assume only 1 filter size */
+ if(pa->crop) {
+ crop= 1;
+ rectf+= 4*(pa->rectx + 1);
+ rectdaps+= pa->rectx + 1;
+ if(recta) recta+= 4*(pa->rectx + 1);
}
+
+ for(y=pa->disprect.ymin+crop; y<pa->disprect.ymax-crop; y++) {
+ rf= rectf;
+ rd= rectdaps;
+ if(recta) acol= recta;
- for(x=0; x<R.rectx; x++, rd++) {
-
- BLI_thread_srandom(rl->y & 1, seed+x);
-
- ps= (PixStr *)(*rd);
- mask= 0;
-
- /* complex loop, because empty spots are sky, without mask */
- while(TRUE) {
-
- if(ps==NULL) {
- face= 0;
- curmask= (~mask) & fullmask;
- zbuf= *(rl->rz+x);
- }
- else {
- face= ps->facenr;
- curmask= ps->mask;
- zbuf= ps->z;
- }
-
- /* check osa level */
- if(face==0) full_osa= 0;
- else {
- VlakRen *vlr= RE_findOrAddVlak( (face-1) & 0x7FFFFF);
- full_osa= (vlr->flag & R_FULL_OSA);
- }
+ for(x=pa->disprect.xmin+crop; x<pa->disprect.xmax-crop; x++, rd++, rf+=4) {
+ BLI_thread_srandom(pa->thread, seed+x);
- if(full_osa) {
- for(samp=0; samp<R.osa; samp++) {
- if(curmask & (1<<samp)) {
- xs= (float)x + jit[samp][0];
- ys= (float)rl->y + jit[samp][1];
- shadepixel_sky(xs, ys, zbuf, face, (1<<samp), fcol);
-
- if(acol && acol[3]!=0.0) addAlphaOverFloat(fcol, acol);
- if(do_gamma) {
- fcol[0]= gammaCorrect(fcol[0]);
- fcol[1]= gammaCorrect(fcol[1]);
- fcol[2]= gammaCorrect(fcol[2]);
+ ps= (PixStr *)(*rd);
+ mask= 0;
+
+ /* complex loop, because empty spots are sky, without mask */
+ while(TRUE) {
+
+ if(ps==NULL) {
+ face= 0;
+ curmask= (~mask) & fullmask;
+ zbuf= 0x7FFFFFFF;
+ }
+ else {
+ face= ps->facenr;
+ curmask= ps->mask;
+ zbuf= ps->z;
+ }
+
+ /* check osa level */
+ if(face==0) full_osa= 0;
+ else {
+ VlakRen *vlr= RE_findOrAddVlak(&R, (face-1) & 0x7FFFFF);
+ full_osa= (vlr->flag & R_FULL_OSA);
+ }
+
+ if(full_osa) {
+ for(samp=0; samp<R.osa; samp++) {
+ if(curmask & (1<<samp)) {
+ xs= (float)x + R.jit[samp][0];
+ ys= (float)y + R.jit[samp][1];
+ shadepixel_sky(pa, xs, ys, zbuf, face, (1<<samp), fcol);
+
+ if(acol && acol[3]!=0.0) addAlphaOverFloat(fcol, acol);
+ if(R.do_gamma) {
+ fcol[0]= gammaCorrect(fcol[0]);
+ fcol[1]= gammaCorrect(fcol[1]);
+ fcol[2]= gammaCorrect(fcol[2]);
+ }
+ add_filt_fmask(1<<samp, fcol, rf, pa->rectx);
}
- add_filt_fmask(1<<samp, fcol, rb1, rb2, rb3);
}
}
- }
- else {
- extern char *centmask; // initrender.c
- extern float centLut[16];
-
- b= centmask[curmask];
- xs= (float)x+centLut[b & 15];
- ys= (float)rl->y+centLut[b>>4];
- shadepixel_sky(xs, ys, zbuf, face, curmask, fcol);
+ else {
+ b= R.samples->centmask[curmask];
+ xs= (float)x+R.samples->centLut[b & 15];
+ ys= (float)y+R.samples->centLut[b>>4];
+ shadepixel_sky(pa, xs, ys, zbuf, face, curmask, fcol);
+
+ if(acol && acol[3]!=0.0) addAlphaOverFloat(fcol, acol);
+
+ if(R.do_gamma) {
+ fcol[0]= gammaCorrect(fcol[0]);
+ fcol[1]= gammaCorrect(fcol[1]);
+ fcol[2]= gammaCorrect(fcol[2]);
+ }
+ add_filt_fmask(curmask, fcol, rf, pa->rectx);
+ }
- if(acol && acol[3]!=0.0) addAlphaOverFloat(fcol, acol);
+ mask |= curmask;
- if(do_gamma) {
- fcol[0]= gammaCorrect(fcol[0]);
- fcol[1]= gammaCorrect(fcol[1]);
- fcol[2]= gammaCorrect(fcol[2]);
- }
- add_filt_fmask(curmask, fcol, rb1, rb2, rb3);
+ if(ps==NULL) break;
+ else ps= ps->next;
}
-
- mask |= curmask;
-
- if(ps==NULL) break;
- else ps= ps->next;
+ if(acol) acol+=4;
}
- rb1+=4;
- rb2+=4;
- rb3+=4;
- if(acol) acol+=4;
+ rectf+= 4*pa->rectx;
+ rectdaps+= pa->rectx;
+ if(recta) recta+= 4*pa->rectx;
+ seed+= pa->rectx;
+
+ if(y&1) if(R.test_break()) break;
}
-
- return 1;
+
+ if(R.do_gamma) {
+ for(y= pa->rectx*pa->recty; y>0; y--, grf+=4) {
+ grf[0] = invGammaCorrect(grf[0]);
+ grf[1] = invGammaCorrect(grf[1]);
+ grf[2] = invGammaCorrect(grf[2]);
+ }
+ }
+
}
-void zbufshadeDA(void) /* Delta Accum Pixel Struct */
-{
- extern float Zjitx,Zjity;
- struct renderlineDA rl1, rl2;
- float xd, yd, *rf;
- long *rd;
- int *rz, *rp, *rt;
- float *rowbuf1, *rowbuf2, *rowbuf3, *rowbuf0, *rowbuf1a, *rowbuf2a, *rb3;
- int a;
- short v, x, y;
+/* ************* pixel struct ******** */
- R.rectdaps= MEM_callocN(sizeof(long)*R.rectx*R.recty+4,"zbufDArectd");
+
+static PixStrMain *addpsmain(ListBase *lb)
+{
+ PixStrMain *psm;
- if(R.flag & R_ZTRA) {
- bgnaccumbuf();
- rl1.acol= MEM_callocN((R.rectx+4)*4*sizeof(float), "Acol");
- rl2.acol= MEM_callocN((R.rectx+4)*4*sizeof(float), "Acol");
- }
+ psm= (PixStrMain *)RE_mallocN(sizeof(PixStrMain),"pixstrMain");
+ BLI_addtail(lb, psm);
+
+ psm->ps= (PixStr *)RE_mallocN(4096*sizeof(PixStr),"pixstr");
+ psm->counter= 0;
- psmteller= 0;
+ return psm;
+}
- if(R.r.mode & R_EDGE) {
- R.rectaccu= (int *)MEM_callocN(sizeof(int)*R.rectx*R.recty,"zbufshadeDA");
+static void freeps(ListBase *lb)
+{
+ PixStrMain *psm, *psmnext;
+
+ for(psm= lb->first; psm; psm= psmnext) {
+ psmnext= psm->next;
+ if(psm->ps)
+ RE_freeN(psm->ps);
+ RE_freeN(psm);
}
+}
- for(v=0; v<R.osa; v++) {
-
- xd= jit[v][0];
- yd= jit[v][1];
- Zjitx= -xd -0.5;
- Zjity= -yd -0.5;
-
- if((R.r.mode & R_MBLUR)==0) RE_local_printrenderinfo(0.0, v);
-
- /* RECTDELTA */
- fillrect(R.rectot,R.rectx,R.recty,0);
-
- zbufferall();
-
- rd= R.rectdaps;
- rp= R.rectot;
- rz= R.rectz;
- for(y=0; y<R.recty; y++) {
- for(x=0; x<R.rectx; x++, rp++, rd++) {
- if(*rp) {
- addps(rd, *rp, *(rz+x), 1<<v);
- }
- }
- rz+= R.rectx;
- }
-
- if(R.r.mode & R_EDGE) edge_enhance();
-
- if(RE_local_test_break()) break;
- }
+static void addps(ListBase *lb, long *rd, int facenr, int z, unsigned short mask)
+{
+ PixStrMain *psm;
+ PixStr *ps, *last= NULL;
- rd= R.rectdaps;
- rz= R.rectz;
- rt= R.rectot;
- rf= R.rectftot;
-
- /* the rowbuf is 4 pixels larger than an image! */
- rowbuf0= MEM_callocN((R.rectx+4)*4*sizeof(float), "ZbufshadeDA3");
- rowbuf1= MEM_callocN((R.rectx+4)*4*sizeof(float), "ZbufshadeDA3");
- rowbuf2= MEM_callocN((R.rectx+4)*4*sizeof(float), "ZbufshadeDA3");
- rowbuf1a= MEM_callocN((R.rectx+4)*4*sizeof(float), "ZbufshadeDA3");
- rowbuf2a= MEM_callocN((R.rectx+4)*4*sizeof(float), "ZbufshadeDA3");
- rowbuf3= MEM_callocN((R.rectx+4)*4*sizeof(float), "ZbufshadeDA3");
-
- for(y=0; y<=R.recty; y++, rd+=R.rectx, rt+=R.rectx, rz+= R.rectx) {
-
- if(y<R.recty) {
- rl1.rd= rd;
- rl1.rz= rz;
- rl1.y= y;
- rl1.rb1= rowbuf1;
- rl1.rb2= rowbuf2;
- rl1.rb3= rowbuf3;
-
- if( (R.r.mode & R_THREADS) && y!=R.recty-1) { // odd amount of total y pixels...
- if((y & 1)==0) {
- SDL_Thread *thread;
-
- thread = SDL_CreateThread(do_renderlineDA, &rl1);
- if ( thread == NULL ) {
- fprintf(stderr, "Unable to create thread");
- G.afbreek= 1;
- break;
- }
-
- rl2.rd= rd+R.rectx;
- rl2.rz= rz+R.rectx;
- rl2.y= y+1;
- rl2.rb1= rowbuf0;
- rl2.rb2= rowbuf1a;
- rl2.rb3= rowbuf2a;
-
- do_renderlineDA(&rl2);
- SDL_WaitThread(thread, NULL);
-
- if(R.r.filtertype) {
- float *rb1= rowbuf1, *rb2= rowbuf2, *rb1a= rowbuf1a, *rb2a= rowbuf2a;
- a= 4*(R.rectx + 4);
- while(a--) {
- *rb1 += *rb1a;
- *rb2 += *rb2a;
- *(rb1a++)= 0; rb1++;
- *(rb2a++)= 0; rb2++;
- }
- }
- else {
- SWAP(float *, rowbuf1a, rowbuf1);
- }
- }
- }
- else do_renderlineDA(&rl1);
-
- }
- if(y>0) {
- /* halos are alpha-added, not in thread loop (yet) because of gauss mask */
- if(R.flag & R_HALO) {
- /* one scanline older... */
- scanlinehaloPS(rz-R.rectx, rd-R.rectx, rowbuf3+4, y-1);
- }
-
- /* convert 4x32 bits buffer to 4x8, this can't be threaded due to gauss */
- transferColourBufferToOutput(rowbuf3+4, y-1);
- if(R.rectftot) {
- memcpy(rf, rowbuf3+4, 4*sizeof(float)*R.rectx);
- rf+= 4*R.rectx;
- }
-
- }
- if(y<R.recty) {
- memset(rowbuf3, 0, (R.rectx+4)*4*sizeof(int));
- rb3= rowbuf3;
- rowbuf3= rowbuf2;
- rowbuf2= rowbuf1;
- rowbuf1= rowbuf0;
- rowbuf0= rb3;
-
- if( y>0) {
- if((y & 1)==0) {
- RE_local_render_display(y-2, y-1, R.rectx, R.recty, R.rectot);
- }
+ if(*rd) {
+ ps= (PixStr *)(*rd);
+
+ while(ps) {
+ if( ps->facenr == facenr ) {
+ ps->mask |= mask;
+ return;
}
+ last= ps;
+ ps= ps->next;
}
- if(RE_local_test_break()) break;
}
+
+ /* make new PS (pixel struct) */
+ psm= lb->last;
+
+ if(psm->counter==4095)
+ psm= addpsmain(lb);
+
+ ps= psm->ps + psm->counter++;
+
+ if(last) last->next= ps;
+ else *rd= (long)ps;
+
+ ps->next= NULL;
+ ps->facenr= facenr;
+ ps->z= z;
+ ps->mask = mask;
+}
- if( (R.r.mode & R_EDGE) && RE_local_test_break()==0) {
- if(R.rectftot) {
- float *rtf= R.rectftot, colf[4];
- rp= R.rectaccu;
- for(a= R.rectx*R.recty; a>0; a--, rtf+=4, rp++) {
- cpCharColV2FloatColV((char *)rp, colf);
- addAlphaOverFloat(rtf, colf);
- }
- RE_floatbuffer_to_output();
- }
- else {
- rt= R.rectot;
- rp= R.rectaccu;
- for(a= R.rectx*R.recty; a>0; a--, rt++, rp++) {
- addalphaOver((char *)rt, (char *)rp);
+static void make_pixelstructs(RenderPart *pa, ListBase *lb)
+{
+ long *rd= pa->rectdaps;
+ int *rp= pa->rectp;
+ int *rz= pa->rectz;
+ int x, y;
+ int mask= 1<<pa->sample;
+
+ for(y=0; y<pa->recty; y++) {
+ for(x=0; x<pa->rectx; x++, rd++, rp++) {
+ if(*rp) {
+ addps(lb, rd, *rp, *(rz+x), mask);
}
}
+ rz+= pa->rectx;
}
-
- MEM_freeN(R.rectdaps);
- freeps();
- MEM_freeN(rowbuf0);
- MEM_freeN(rowbuf1);
- MEM_freeN(rowbuf2);
- MEM_freeN(rowbuf1a);
- MEM_freeN(rowbuf2a);
- MEM_freeN(rowbuf3);
- R.rectdaps= NULL;
-
- if(R.r.mode & R_EDGE) if(R.rectaccu) MEM_freeN(R.rectaccu);
- R.rectaccu= NULL;
- if(R.flag & R_ZTRA) {
- endaccumbuf();
- MEM_freeN(rl1.acol);
- MEM_freeN(rl2.acol);
- }
-
-} /* end of void zbufshadeDA() */
-
-/* ------------------------------------------------------------------------ */
-
-struct renderline {
- float *rowbuf, *acol;
- int *rp;
- int *rz;
- short ys;
- float y;
-};
+}
-static int do_renderline(void *poin)
+/* supposed to be fully threadable! */
+void zbufshadeDA_tile(RenderPart *pa)
{
- struct renderline *rl= poin;
- float *fcol= rl->rowbuf;
- float *acol=NULL;
- int x, *rz, *rp, seed;
+ RenderLayer *rl= pa->result->layers.first;
+ ListBase psmlist= {NULL, NULL};
+ float *acolrect= NULL, *edgerect= NULL;
- /* we set per pixel a fixed seed, for random AO and shadow samples */
- seed= (R.ystart + rl->y + R.afmy)*R.r.xsch + R.xstart + R.afmx;
+ set_part_zbuf_clipflag(pa);
- if(R.flag & R_ZTRA) { /* zbuf tra */
- abufsetrow(rl->acol, rl->ys);
- acol= rl->acol;
- }
+ /* allocate the necessary buffers */
+ pa->rectdaps= RE_callocN(sizeof(long)*pa->rectx*pa->recty+4, "zbufDArectd");
+ /* zbuffer inits these rects */
+ pa->rectp= RE_mallocN(sizeof(int)*pa->rectx*pa->recty, "rectp");
+ pa->rectz= RE_mallocN(sizeof(int)*pa->rectx*pa->recty, "rectz");
+ if(R.r.mode & R_EDGE) edgerect= RE_callocN(sizeof(float)*pa->rectx*pa->recty, "rectedge");
+
+ /* initialize pixelstructs */
+ addpsmain(&psmlist);
- for(x=0, rz= rl->rz, rp= rl->rp; x<R.rectx; x++, rz++, rp++, fcol+=4) {
- BLI_thread_srandom(rl->ys & 1, seed+x);
+ for(pa->sample=0; pa->sample<R.osa; pa->sample++) {
+ zbuffer_solid(pa);
+ make_pixelstructs(pa, &psmlist);
- shadepixel_sky((float)x, rl->y, *rz, *rp, 0, fcol);
- if(acol) {
- if(acol[3]!=0.0) addAlphaOverFloat(fcol, acol);
- acol+= 4;
- }
+ if(R.r.mode & R_EDGE) edge_enhance_calc(pa, edgerect);
+ if(R.test_break()) break;
}
-
- if(R.flag & R_HALO) {
- scanlinehalo(rl->rz, rl->rowbuf, rl->ys);
+
+ /* we do transp layer first, so its get added with filter in main buffer... still incorrect though */
+ if(R.flag & R_ZTRA) {
+ acolrect= RE_callocN(4*sizeof(float)*pa->rectx*pa->recty, "alpha layer");
+ zbuffer_transp_shade(pa, acolrect);
}
- transferColourBufferToOutput(rl->rowbuf, rl->ys);
-
- if(R.rectftot) {
- memcpy(R.rectftot + 4*rl->ys*R.rectx, rl->rowbuf, 4*sizeof(float)*R.rectx);
- }
+ /* shades solid and adds transparent layer */
+ shadeDA_tile(pa, rl->rectf, acolrect);
+
+ /* extra layers */
+ if(R.r.mode & R_EDGE)
+ edge_enhance_add(pa, rl->rectf, edgerect);
+ if(R.flag & R_HALO)
+ halo_tile(pa, rl->rectf);
+
+ /* free all */
+ RE_freeN(pa->rectp); pa->rectp= NULL;
+ RE_freeN(pa->rectz); pa->rectz= NULL;
+ RE_freeN(pa->rectdaps); pa->rectdaps= NULL;
+ if(acolrect) RE_freeN(acolrect);
+ if(edgerect) RE_freeN(edgerect);
+
+ freeps(&psmlist);
- return 1;
}
-void zbufshade(void)
-{
- struct renderline rl1, rl2;
- extern float Zjitx,Zjity;
- int *rz, *rp;
- float fy;
- int y;
+/* ------------------------------------------------------------------------ */
- rl1.rowbuf= MEM_callocN((R.rectx+4)*4*sizeof(float), "Zbufshade");
- rl2.rowbuf= MEM_callocN((R.rectx+4)*4*sizeof(float), "Zbufshade");
+/* supposed to be fully threadable! */
+void zbufshade_tile(RenderPart *pa)
+{
+ RenderLayer *rl= pa->result->layers.first;
+ float *fcol;
+ int x, y, *rp, *rz;
- Zjitx=Zjity= -0.5;
-
- zbufferall();
-
- /* SHADE */
- rp= R.rectot;
- rz= R.rectz;
-
- if(R.flag & R_ZTRA) {
- rl1.acol= MEM_callocN((R.rectx+4)*4*sizeof(float), "Acol");
- rl2.acol= MEM_callocN((R.rectx+4)*4*sizeof(float), "Acol");
- bgnaccumbuf();
- }
-
- for(y=0; y<R.recty; y++) {
- fy= y;
-
- rl1.rp= rp;
- rl1.rz= rz;
- rl1.y= fy;
- rl1.ys= y;
-
- if(R.r.mode & R_THREADS) {
- SDL_Thread *thread;
-
- thread = SDL_CreateThread(do_renderline, &rl1);
- if ( thread == NULL ) {
- fprintf(stderr, "Unable to create thread");
- G.afbreek= 1;
- break;
+ set_part_zbuf_clipflag(pa);
+
+ /* zbuffer code clears/inits rects */
+ rp= pa->rectp= RE_mallocN(sizeof(int)*pa->rectx*pa->recty, "rectp");
+ rz= pa->rectz= RE_mallocN(sizeof(int)*pa->rectx*pa->recty, "rectz");
+
+ zbuffer_solid(pa);
+
+ if(!R.test_break()) {
+ fcol= rl->rectf;
+ for(y=pa->disprect.ymin; y<pa->disprect.ymax; y++) {
+ for(x=pa->disprect.xmin; x<pa->disprect.xmax; x++, rz++, rp++, fcol+=4) {
+ shadepixel_sky(pa, (float)x, (float)y, *rz, *rp, 0, fcol);
}
- rp+= R.rectx;
- rz+= R.rectx;
-
- if(y < R.recty-1) {
- rl2.rp= rp;
- rl2.rz= rz;
- rl2.y= fy+1.0;
- rl2.ys= y+1;
- do_renderline(&rl2);
- rp+= R.rectx;
- rz+= R.rectx;
- y++;
- }
- SDL_WaitThread(thread, NULL);
- }
- else {
- do_renderline(&rl1);
- rp+= R.rectx;
- rz+= R.rectx;
+ if(y&1) if(R.test_break()) break;
}
-
- if(y & 1) {
- RE_local_render_display(y-1, y, R.rectx, R.recty, R.rectot);
- }
-
- if(RE_local_test_break()) break;
}
- MEM_freeN(rl1.rowbuf);
- MEM_freeN(rl2.rowbuf);
+ if(!R.test_break())
+ if(R.flag & R_ZTRA)
+ zbuffer_transp_shade(pa, rl->rectf);
- if(R.flag & R_ZTRA) {
- endaccumbuf();
- MEM_freeN(rl1.acol);
- MEM_freeN(rl2.acol);
+ if(!R.test_break()) {
+ if(R.r.mode & R_EDGE) {
+ fillrect(pa->rectp, pa->rectx, pa->recty, 0);
+ edge_enhance_calc(pa, (float *)pa->rectp);
+ edge_enhance_add(pa, rl->rectf, (float *)pa->rectp);
+ }
}
- if(R.r.mode & R_EDGE) edge_enhance();
+ if(!R.test_break())
+ if(R.flag & R_HALO)
+ halo_tile(pa, rl->rectf);
-} /* end of void zbufshade() */
+ RE_freeN(pa->rectp); pa->rectp= NULL;
+ RE_freeN(pa->rectz); pa->rectz= NULL;
+}
/* ------------------------------------------------------------------------ */
-void RE_shadehalo(HaloRen *har, char *col, float *colf, int zz, float dist, float xn, float yn, short flarec)
-{
-
- shadeHaloFloat(har, colf, zz, dist, xn, yn, flarec);
-
- if(colf[0]<=0.0) col[0]= 0; else if(colf[0]>=1.0) col[0]= 255; else col[0]= 255.0*colf[0];
- if(colf[1]<=0.0) col[1]= 0; else if(colf[1]>=1.0) col[1]= 255; else col[1]= 255.0*colf[1];
- if(colf[2]<=0.0) col[2]= 0; else if(colf[2]>=1.0) col[2]= 255; else col[2]= 255.0*colf[2];
- if(colf[3]<=0.0) col[3]= 0; else if(colf[3]>=1.0) col[3]= 255; else col[3]= 255.0*colf[3];
-
-}
-
static void renderhalo(HaloRen *har) /* postprocess version */
{
-
+#if 0
float dist, xsq, ysq, xn, yn, colf[4], *rectft, *rtf;
int *rectt, *rt;
int minx, maxx, miny, maxy, x, y;
@@ -3262,7 +2851,7 @@ static void renderhalo(HaloRen *har) /* postprocess version */
if(R.rectftot) addalphaAddfacFloat(rtf, colf, har->add);
else {
std_floatcol_to_charcol(colf, col);
- RE_addalphaAddfac((char *)rt, col, har->add);
+ addalphaAddfac((char *)rt, col, har->add);
}
}
rt++;
@@ -3272,14 +2861,15 @@ static void renderhalo(HaloRen *har) /* postprocess version */
rectt+= R.rectx;
rectft+= 4*R.rectx;
- if(RE_local_test_break()) break;
+ if(R.test_break()) break;
}
}
}
+#endif
}
/* ------------------------------------------------------------------------ */
-void RE_renderflare(HaloRen *har)
+static void renderflare(HaloRen *har)
{
extern float hashvectf[];
HaloRen fla;
@@ -3333,12 +2923,12 @@ void RE_renderflare(HaloRen *har)
fla.radsq= fla.rad*fla.rad;
- vec[0]= 1.4*rc[5]*(har->xs-R.afmx);
- vec[1]= 1.4*rc[5]*(har->ys-R.afmy);
+ vec[0]= 1.4*rc[5]*(har->xs-R.winx/2);
+ vec[1]= 1.4*rc[5]*(har->ys-R.winy/2);
vec[2]= 32.0*sqrt(vec[0]*vec[0] + vec[1]*vec[1] + 1.0);
- fla.xs= R.afmx + vec[0] + (1.2+rc[8])*R.rectx*vec[0]/vec[2];
- fla.ys= R.afmy + vec[1] + (1.2+rc[8])*R.rectx*vec[1]/vec[2];
+ fla.xs= R.winx/2 + vec[0] + (1.2+rc[8])*R.rectx*vec[0]/vec[2];
+ fla.ys= R.winy/2 + vec[1] + (1.2+rc[8])*R.rectx*vec[1]/vec[2];
if(R.flag & R_SEC_FIELD) {
if(R.r.mode & R_ODDFIELD) fla.ys += 0.5;
@@ -3355,36 +2945,35 @@ void RE_renderflare(HaloRen *har)
rc+= 7;
}
-} /* end of void renderflare(HaloRen *har) */
+}
+/* needs recode... integrate this! */
void add_halo_flare(void)
{
-/* extern void RE_projectverto(); */ /* zbuf.c */
HaloRen *har = NULL;
int a, mode;
mode= R.r.mode;
R.r.mode &= ~R_PANORAMA;
- R.xstart= -R.afmx;
- R.ystart= -R.afmy;
- R.xend= R.xstart+R.rectx-1;
- R.yend= R.ystart+R.recty-1;
+// R.xstart= -R.afmx;
+// R.ystart= -R.afmy;
+// R.xend= R.xstart+R.rectx-1;
+// R.yend= R.ystart+R.recty-1;
- RE_setwindowclip(1,-1); /* no jit:(-1) */
- setzbufvlaggen(RE_projectverto);
+// RE_setwindowclip(1,-1); /* no jit:(-1) */
+ project_renderdata(&R, projectverto, 0, 0);
for(a=0; a<R.tothalo; a++) {
if((a & 255)==0) har= R.bloha[a>>8];
else har++;
if(har->flarec) {
- RE_renderflare(har);
+ renderflare(har);
}
}
R.r.mode= mode;
- if(R.rectftot) RE_floatbuffer_to_output();
}
diff --git a/source/blender/render/intern/source/renderdatabase.c b/source/blender/render/intern/source/renderdatabase.c
index d37c73dc932..098d4491060 100644
--- a/source/blender/render/intern/source/renderdatabase.c
+++ b/source/blender/render/intern/source/renderdatabase.c
@@ -1,15 +1,12 @@
/**
* $Id$
*
- * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
+ * ***** BEGIN GPL 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.
+ * of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
@@ -23,15 +20,14 @@
* The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
* All rights reserved.
*
- * The Original Code is: all of this file.
- *
- * Contributor(s): none yet.
+ * Contributor(s): 2004-2006, Blender Foundation, full recode
*
* ***** END GPL/BL DUAL LICENSE BLOCK *****
- * Storage, retrieval and query of render specific data.
*/
/*
+ * Storage, retrieval and query of render specific data.
+ *
* All data from a Blender scene is converter by the renderconverter/
* into a special format that is used by the render module to make
* images out of. These functions interface to the render-specific
@@ -57,6 +53,7 @@
*
*/
+#include <limits.h>
#include <math.h>
#include <string.h>
@@ -66,14 +63,20 @@
#include "DNA_material_types.h"
#include "DNA_mesh_types.h"
+#include "DNA_meshdata_types.h"
#include "DNA_texture_types.h"
#include "BKE_texture.h"
-#include "render.h"
+#include "RE_render_ext.h" /* externtex */
-/* ------------------------------------------------------------------------- */
+#include "renderpipeline.h"
+#include "render_types.h"
+#include "renderdatabase.h"
+#include "texture.h"
+#include "zbuf.h"
+/* ------------------------------------------------------------------------- */
/* More dynamic allocation of options for render vertices, so we dont
have to reserve this space inside vertices.
@@ -99,30 +102,30 @@ typedef struct VertTableNode {
float *stress;
} VertTableNode;
-float *RE_vertren_get_sticky(VertRen *ver, int verify)
+float *RE_vertren_get_sticky(Render *re, VertRen *ver, int verify)
{
float *sticky;
int nr= ver->index>>8;
- sticky= R.vertnodes[nr].sticky;
+ sticky= re->vertnodes[nr].sticky;
if(sticky==NULL) {
if(verify)
- sticky= R.vertnodes[nr].sticky= MEM_mallocN(256*RE_STICKY_ELEMS*sizeof(float), "sticky table");
+ sticky= re->vertnodes[nr].sticky= MEM_mallocN(256*RE_STICKY_ELEMS*sizeof(float), "sticky table");
else
return NULL;
}
return sticky + (ver->index & 255)*RE_STICKY_ELEMS;
}
-float *RE_vertren_get_stress(VertRen *ver, int verify)
+float *RE_vertren_get_stress(Render *re, VertRen *ver, int verify)
{
float *stress;
int nr= ver->index>>8;
- stress= R.vertnodes[nr].stress;
+ stress= re->vertnodes[nr].stress;
if(stress==NULL) {
if(verify)
- stress= R.vertnodes[nr].stress= MEM_mallocN(256*RE_STRESS_ELEMS*sizeof(float), "stress table");
+ stress= re->vertnodes[nr].stress= MEM_mallocN(256*RE_STRESS_ELEMS*sizeof(float), "stress table");
else
return NULL;
}
@@ -130,30 +133,30 @@ float *RE_vertren_get_stress(VertRen *ver, int verify)
}
/* this one callocs! */
-float *RE_vertren_get_rad(VertRen *ver, int verify)
+float *RE_vertren_get_rad(Render *re, VertRen *ver, int verify)
{
float *rad;
int nr= ver->index>>8;
- rad= R.vertnodes[nr].rad;
+ rad= re->vertnodes[nr].rad;
if(rad==NULL) {
if(verify)
- rad= R.vertnodes[nr].rad= MEM_callocN(256*RE_RAD_ELEMS*sizeof(float), "rad table");
+ rad= re->vertnodes[nr].rad= MEM_callocN(256*RE_RAD_ELEMS*sizeof(float), "rad table");
else
return NULL;
}
return rad + (ver->index & 255)*RE_RAD_ELEMS;
}
-float *RE_vertren_get_strand(VertRen *ver, int verify)
+float *RE_vertren_get_strand(Render *re, VertRen *ver, int verify)
{
float *strand;
int nr= ver->index>>8;
- strand= R.vertnodes[nr].strand;
+ strand= re->vertnodes[nr].strand;
if(strand==NULL) {
if(verify)
- strand= R.vertnodes[nr].strand= MEM_mallocN(256*RE_STRAND_ELEMS*sizeof(float), "strand table");
+ strand= re->vertnodes[nr].strand= MEM_mallocN(256*RE_STRAND_ELEMS*sizeof(float), "strand table");
else
return NULL;
}
@@ -161,15 +164,15 @@ float *RE_vertren_get_strand(VertRen *ver, int verify)
}
/* needs calloc */
-float *RE_vertren_get_tangent(VertRen *ver, int verify)
+float *RE_vertren_get_tangent(Render *re, VertRen *ver, int verify)
{
float *tangent;
int nr= ver->index>>8;
- tangent= R.vertnodes[nr].tangent;
+ tangent= re->vertnodes[nr].tangent;
if(tangent==NULL) {
if(verify)
- tangent= R.vertnodes[nr].tangent= MEM_callocN(256*RE_TANGENT_ELEMS*sizeof(float), "tangent table");
+ tangent= re->vertnodes[nr].tangent= MEM_callocN(256*RE_TANGENT_ELEMS*sizeof(float), "tangent table");
else
return NULL;
}
@@ -177,36 +180,35 @@ float *RE_vertren_get_tangent(VertRen *ver, int verify)
}
-VertRen *RE_findOrAddVert(int nr)
+VertRen *RE_findOrAddVert(Render *re, int nr)
{
VertTableNode *temp;
VertRen *v;
- static int rvertnodeslen=TABLEINITSIZE;
int a;
if(nr<0) {
printf("error in findOrAddVert: %d\n",nr);
- return R.vertnodes[0].vert;
+ return NULL;
}
a= nr>>8;
- if (a>=rvertnodeslen-1){ /* Need to allocate more columns..., and keep last element NULL for free loop */
- temp= R.vertnodes;
+ if (a>=re->vertnodeslen-1) { /* Need to allocate more columns..., and keep last element NULL for free loop */
+ temp= re->vertnodes;
- R.vertnodes= MEM_mallocN(sizeof(VertTableNode)*(rvertnodeslen+TABLEINITSIZE) , "vertnodes");
- memcpy(R.vertnodes, temp, rvertnodeslen*sizeof(VertTableNode));
- memset(R.vertnodes+rvertnodeslen, 0, TABLEINITSIZE*sizeof(VertTableNode));
+ re->vertnodes= MEM_mallocN(sizeof(VertTableNode)*(re->vertnodeslen+TABLEINITSIZE) , "vertnodes");
+ if(temp) memcpy(re->vertnodes, temp, re->vertnodeslen*sizeof(VertTableNode));
+ memset(re->vertnodes+re->vertnodeslen, 0, TABLEINITSIZE*sizeof(VertTableNode));
- rvertnodeslen+=TABLEINITSIZE;
- MEM_freeN(temp);
+ re->vertnodeslen+=TABLEINITSIZE;
+ if(temp) MEM_freeN(temp);
}
- v= R.vertnodes[a].vert;
+ v= re->vertnodes[a].vert;
if(v==NULL) {
int i;
v= (VertRen *)MEM_callocN(256*sizeof(VertRen),"findOrAddVert");
- R.vertnodes[a].vert= v;
+ re->vertnodes[a].vert= v;
for(i= (nr & 0xFFFFFF00), a=0; a<256; a++, i++) {
v[a].index= i;
@@ -216,74 +218,80 @@ VertRen *RE_findOrAddVert(int nr)
return v;
}
-void RE_free_vertex_tables(void)
+void free_renderdata_tables(Render *re)
{
int a=0;
- while(R.vertnodes[a].vert) {
- if(R.vertnodes[a].vert) {
- MEM_freeN(R.vertnodes[a].vert);
- R.vertnodes[a].vert= NULL;
-
- if(R.vertnodes[a].rad) {
- MEM_freeN(R.vertnodes[a].rad);
- R.vertnodes[a].rad= NULL;
- }
- if(R.vertnodes[a].sticky) {
- MEM_freeN(R.vertnodes[a].sticky);
- R.vertnodes[a].sticky= NULL;
- }
- if(R.vertnodes[a].strand) {
- MEM_freeN(R.vertnodes[a].strand);
- R.vertnodes[a].strand= NULL;
- }
- if(R.vertnodes[a].tangent) {
- MEM_freeN(R.vertnodes[a].tangent);
- R.vertnodes[a].tangent= NULL;
- }
- if(R.vertnodes[a].stress) {
- MEM_freeN(R.vertnodes[a].stress);
- R.vertnodes[a].stress= NULL;
- }
+ if(re->blovl) {
+ for(a=0; re->blovl[a]; a++)
+ MEM_freeN(re->blovl[a]);
+
+ MEM_freeN(re->blovl);
+ re->blovl= NULL;
+ re->blovllen= 0;
+ }
+
+ if(re->bloha) {
+ for(a=0; re->bloha[a]; a++)
+ MEM_freeN(re->bloha[a]);
+
+ MEM_freeN(re->bloha);
+ re->bloha= NULL;
+ re->blohalen= 0;
+ }
+
+ if(re->vertnodes) {
+ for(a=0; re->vertnodes[a].vert; a++) {
+ MEM_freeN(re->vertnodes[a].vert);
+
+ if(re->vertnodes[a].rad)
+ MEM_freeN(re->vertnodes[a].rad);
+ if(re->vertnodes[a].sticky)
+ MEM_freeN(re->vertnodes[a].sticky);
+ if(re->vertnodes[a].strand)
+ MEM_freeN(re->vertnodes[a].strand);
+ if(re->vertnodes[a].tangent)
+ MEM_freeN(re->vertnodes[a].tangent);
+ if(re->vertnodes[a].stress)
+ MEM_freeN(re->vertnodes[a].stress);
}
- a++;
+
+ MEM_freeN(re->vertnodes);
+ re->vertnodes= NULL;
+ re->vertnodeslen= 0;
}
}
-/* only once, on startup */
-void RE_init_vertex_tables(void)
-{
- R.vertnodes= MEM_callocN(sizeof(VertTableNode)*TABLEINITSIZE , "vertnodes");
-}
/* ------------------------------------------------------------------------ */
-int rblohalen=TABLEINITSIZE;
-HaloRen *RE_findOrAddHalo(int nr)
+
+HaloRen *RE_findOrAddHalo(Render *re, int nr)
{
HaloRen *h, **temp;
int a;
if(nr<0) {
printf("error in findOrAddHalo: %d\n",nr);
- return R.bloha[0];
+ return NULL;
}
a= nr>>8;
- if (a>=rblohalen-1){ /* Need to allocate more columns..., and keep last element NULL for free loop */
+ if (a>=re->blohalen-1){ /* Need to allocate more columns..., and keep last element NULL for free loop */
//printf("Allocating %i more halo groups. %i total.\n",
- // TABLEINITSIZE, rblohalen+TABLEINITSIZE );
- temp=R.bloha;
- R.bloha=(HaloRen**)MEM_callocN(sizeof(void*)*(rblohalen+TABLEINITSIZE) , "Bloha");
- memcpy(R.bloha, temp, rblohalen*sizeof(void*));
- memset(&(R.bloha[rblohalen]), 0, TABLEINITSIZE*sizeof(void*));
- rblohalen+=TABLEINITSIZE; /*Does this really need to be power of 2?*/
- MEM_freeN(temp);
+ // TABLEINITSIZE, re->blohalen+TABLEINITSIZE );
+ temp=re->bloha;
+
+ re->bloha=(HaloRen**)MEM_callocN(sizeof(void*)*(re->blohalen+TABLEINITSIZE) , "Bloha");
+ if(temp) memcpy(re->bloha, temp, re->blohalen*sizeof(void*));
+ memset(&(re->bloha[re->blohalen]), 0, TABLEINITSIZE*sizeof(void*));
+ re->blohalen+=TABLEINITSIZE; /*Does this really need to be power of 2?*/
+ if(temp) MEM_freeN(temp);
}
- h= R.bloha[a];
- if(h==0) {
+ h= re->bloha[a];
+ if(h==NULL) {
h= (HaloRen *)MEM_callocN(256*sizeof(HaloRen),"findOrAdHalo");
- R.bloha[a]= h;
+ re->bloha[a]= h;
}
h+= (nr & 255);
return h;
@@ -291,34 +299,34 @@ HaloRen *RE_findOrAddHalo(int nr)
/* ------------------------------------------------------------------------ */
-VlakRen *RE_findOrAddVlak(int nr)
+VlakRen *RE_findOrAddVlak(Render *re, int nr)
{
VlakRen *v, **temp;
- static int rblovllen=TABLEINITSIZE;
int a;
if(nr<0) {
printf("error in findOrAddVlak: %d\n",nr);
- return R.blovl[0];
+ return re->blovl[0];
}
a= nr>>8;
- if (a>=rblovllen-1){ /* Need to allocate more columns..., and keep last element NULL for free loop */
+ if (a>=re->blovllen-1){ /* Need to allocate more columns..., and keep last element NULL for free loop */
// printf("Allocating %i more face groups. %i total.\n",
- // TABLEINITSIZE, rblovllen+TABLEINITSIZE );
- temp=R.blovl;
- R.blovl=(VlakRen**)MEM_callocN(sizeof(void*)*(rblovllen+TABLEINITSIZE) , "Blovl");
- memcpy(R.blovl, temp, rblovllen*sizeof(void*));
- memset(&(R.blovl[rblovllen]), 0, TABLEINITSIZE*sizeof(void*));
- rblovllen+=TABLEINITSIZE; /*Does this really need to be power of 2?*/
- MEM_freeN(temp);
+ // TABLEINITSIZE, re->blovllen+TABLEINITSIZE );
+ temp= re->blovl;
+
+ re->blovl=(VlakRen**)MEM_callocN(sizeof(void*)*(re->blovllen+TABLEINITSIZE) , "Blovl");
+ if(temp) memcpy(re->blovl, temp, re->blovllen*sizeof(void*));
+ memset(&(re->blovl[re->blovllen]), 0, TABLEINITSIZE*sizeof(void*));
+ re->blovllen+=TABLEINITSIZE; /*Does this really need to be power of 2?*/
+ if(temp) MEM_freeN(temp);
}
- v= R.blovl[a];
+ v= re->blovl[a];
- if(v==0) {
+ if(v==NULL) {
v= (VlakRen *)MEM_callocN(256*sizeof(VlakRen),"findOrAddVlak");
- R.blovl[a]= v;
+ re->blovl[a]= v;
}
v+= (nr & 255);
return v;
@@ -326,7 +334,7 @@ VlakRen *RE_findOrAddVlak(int nr)
/* ------------------------------------------------------------------------- */
-HaloRen *RE_inithalo(Material *ma, float *vec, float *vec1,
+HaloRen *RE_inithalo(Render *re, Material *ma, float *vec, float *vec1,
float *orco, float hasize, float vectsize, int seed)
{
HaloRen *har;
@@ -336,18 +344,18 @@ HaloRen *RE_inithalo(Material *ma, float *vec, float *vec1,
if(hasize==0.0) return NULL;
- RE_projectverto(vec, hoco);
+ projectverto(vec, re->winmat, hoco);
if(hoco[3]==0.0) return NULL;
if(vec1) {
- RE_projectverto(vec1, hoco1);
+ projectverto(vec1, re->winmat, hoco1);
if(hoco1[3]==0.0) return NULL;
}
- har= RE_findOrAddHalo(R.tothalo++);
+ har= RE_findOrAddHalo(re, re->tothalo++);
VECCOPY(har->co, vec);
har->hasize= hasize;
- /* projectvert is done in function 'zbufvlaggen' because of parts/border/pano */
+ /* actual projectvert is done in function transform_renderdata() because of parts/border/pano */
/* halovect */
if(vec1) {
@@ -355,14 +363,14 @@ HaloRen *RE_inithalo(Material *ma, float *vec, float *vec1,
har->type |= HA_VECT;
zn= hoco[3];
- har->xs= 0.5*R.rectx*(hoco[0]/zn);
- har->ys= 0.5*R.recty*(hoco[1]/zn);
+ har->xs= 0.5*re->winx*(hoco[0]/zn);
+ har->ys= 0.5*re->winy*(hoco[1]/zn);
har->zs= 0x7FFFFF*(hoco[2]/zn);
har->zBufDist = 0x7FFFFFFF*(hoco[2]/zn);
- xn= har->xs - 0.5*R.rectx*(hoco1[0]/hoco1[3]);
- yn= har->ys - 0.5*R.recty*(hoco1[1]/hoco1[3]);
+ xn= har->xs - 0.5*re->winx*(hoco1[0]/hoco1[3]);
+ yn= har->ys - 0.5*re->winy*(hoco1[1]/hoco1[3]);
if(xn==0.0 || (xn==0.0 && yn==0.0)) zn= 0.0;
else zn= atan2(yn, xn);
@@ -435,4 +443,228 @@ HaloRen *RE_inithalo(Material *ma, float *vec, float *vec1,
return har;
}
+
+/* -------------------------- operations on entire database ----------------------- */
+
+static float get_pano_rot(Render *re, int part)
+{
+ static float alpha= 1.0;
+
+ /* part==0 init all */
+ if(part==0) {
+ alpha= ((float)re->r.xsch)/re->viewfac;
+ alpha= 2.0*atan(alpha/2.0);
+ }
+
+ /* rotate it all around the y-as with phi degrees */
+ return 0.5*(re->r.xparts-1)*alpha + part*alpha;
+}
+
+/* ugly function for halos in panorama */
+static int panotestclip(Render *re, int do_pano, float *v)
+{
+ /* to be used for halos en infos */
+ float abs4;
+ short c=0;
+
+ if(do_pano) return testclip(v);
+
+ abs4= fabs(v[3]);
+
+ if(v[2]< -abs4) c=16; /* this used to be " if(v[2]<0) ", see clippz() */
+ else if(v[2]> abs4) c+= 32;
+
+ if( v[1]>abs4) c+=4;
+ else if( v[1]< -abs4) c+=8;
+
+ abs4*= re->r.xparts;
+ if( v[0]>abs4) c+=2;
+ else if( v[0]< -abs4) c+=1;
+
+ return c;
+}
+
+/*
+ This adds the hcs coordinates to vertices. It iterates over all
+ vertices, halos and faces. After the conversion, we clip in hcs.
+
+ Elsewhere, all primites are converted to vertices.
+ Called in
+ - envmapping (envmap.c)
+ - shadow buffering (shadbuf.c)
+*/
+
+void project_renderdata(Render *re, void (*projectfunc)(float *, float mat[][4], float *), int do_pano, int part)
+{
+ VlakRen *vlr = NULL;
+ VertRen *ver = NULL;
+ HaloRen *har = NULL;
+ float zn, vec[3], hoco[4];
+ int a;
+
+ if(do_pano) {
+ float panophi= get_pano_rot(re, part);
+
+ re->panosi= sin(panophi);
+ re->panoco= cos(panophi);
+ }
+
+ /* calculate view coordinates (and zbuffer value) */
+ for(a=0; a< re->totvert;a++) {
+ if((a & 255)==0) ver= RE_findOrAddVert(re, a);
+ else ver++;
+
+ if(do_pano) {
+ vec[0]= re->panoco*ver->co[0] + re->panosi*ver->co[2];
+ vec[1]= ver->co[1];
+ vec[2]= -re->panosi*ver->co[0] + re->panoco*ver->co[2];
+ }
+ else {
+ VECCOPY(vec, ver->co);
+ }
+ /* Go from wcs to hcs ... */
+ projectfunc(vec, re->winmat, ver->ho);
+ /* ... and clip in that system. */
+ ver->clip = testclip(ver->ho);
+ /*
+ Because all other ops are performed in other systems, this is
+ the only thing that has to be done.
+ */
+ }
+
+ /* calculate view coordinates (and zbuffer value) */
+ for(a=0; a<re->tothalo; a++) {
+ if((a & 255)==0) har= re->bloha[a>>8];
+ else har++;
+
+ if(do_pano) {
+ vec[0]= re->panoco*har->co[0] + re->panosi*har->co[2];
+ vec[1]= har->co[1];
+ vec[2]= -re->panosi*har->co[0] + re->panoco*har->co[2];
+ }
+ else {
+ VECCOPY(vec, har->co);
+ }
+
+ projectfunc(vec, re->winmat, hoco);
+
+ /* we clip halos less critical, but not for the Z */
+ hoco[0]*= 0.5;
+ hoco[1]*= 0.5;
+
+ if( panotestclip(re, do_pano, hoco) ) {
+ har->miny= har->maxy= -10000; /* that way render clips it */
+ }
+ else if(hoco[3]<0.0) {
+ har->miny= har->maxy= -10000; /* render clips it */
+ }
+ else /* do the projection...*/
+ {
+ /* bring back hocos */
+ hoco[0]*= 2.0;
+ hoco[1]*= 2.0;
+
+ zn= hoco[3];
+ har->xs= 0.5*re->winx*(1.0+hoco[0]/zn); /* the 0.5 negates the previous 2...*/
+ har->ys= 0.5*re->winy*(1.0+hoco[1]/zn);
+
+ /* this should be the zbuffer coordinate */
+ har->zs= 0x7FFFFF*(hoco[2]/zn);
+ /* taking this from the face clip functions? seems ok... */
+ har->zBufDist = 0x7FFFFFFF*(hoco[2]/zn);
+
+ vec[0]+= har->hasize;
+ projectfunc(vec, re->winmat, hoco);
+ vec[0]-= har->hasize;
+ zn= hoco[3];
+ har->rad= fabs(har->xs- 0.5*re->winx*(1.0+hoco[0]/zn));
+
+ /* this clip is not really OK, to prevent stars to become too large */
+ if(har->type & HA_ONLYSKY) {
+ if(har->rad>3.0) har->rad= 3.0;
+ }
+
+ har->radsq= har->rad*har->rad;
+
+ har->miny= har->ys - har->rad/re->ycor;
+ har->maxy= har->ys + har->rad/re->ycor;
+
+ /* the Zd value is still not really correct for pano */
+
+ vec[2]-= har->hasize; /* z negative, otherwise it's clipped */
+ projectfunc(vec, re->winmat, hoco);
+ zn= hoco[3];
+ zn= fabs( (float)har->zs - 0x7FFFFF*(hoco[2]/zn));
+ har->zd= CLAMPIS(zn, 0, INT_MAX);
+
+ }
+
+ }
+
+ /* set flags at 0 if clipped away */
+ for(a=0; a<re->totvlak; a++) {
+ if((a & 255)==0) vlr= re->blovl[a>>8];
+ else vlr++;
+
+ vlr->flag |= R_VISIBLE;
+ if(vlr->v4) {
+ if(vlr->v1->clip & vlr->v2->clip & vlr->v3->clip & vlr->v4->clip) vlr->flag &= ~R_VISIBLE;
+ }
+ else if(vlr->v1->clip & vlr->v2->clip & vlr->v3->clip) vlr->flag &= ~R_VISIBLE;
+
+ }
+
+}
+
/* ------------------------------------------------------------------------- */
+
+void set_normalflags(Render *re)
+{
+ VlakRen *vlr = NULL;
+ float *v1, xn, yn, zn;
+ int a1, doflip;
+
+ /* switch normal 'snproj' values (define which axis is the optimal one for calculations) */
+ for(a1=0; a1<re->totvlak; a1++) {
+ if((a1 & 255)==0) vlr= re->blovl[a1>>8];
+ else vlr++;
+
+ /* abuse of this flag... this is code that just sets face normal in direction of camera */
+ /* that convention we should get rid of */
+ if((vlr->flag & R_NOPUNOFLIP)==0) {
+
+ doflip= 0;
+ if(re->r.mode & R_ORTHO) {
+ if(vlr->n[2]>0.0) doflip= 1;
+ }
+ else {
+ v1= vlr->v1->co;
+ if( (v1[0]*vlr->n[0] +v1[1]*vlr->n[1] +v1[2]*vlr->n[2])<0.0 ) doflip= 1;
+ }
+ if(doflip) {
+ vlr->n[0]= -vlr->n[0];
+ vlr->n[1]= -vlr->n[1];
+ vlr->n[2]= -vlr->n[2];
+ }
+ }
+
+ /* recalculate puno. Displace & flipped matrices can screw up */
+ vlr->puno= 0;
+ if(!(vlr->flag & R_TANGENT)) {
+ if( Inpf(vlr->n, vlr->v1->n) < 0.0 ) vlr->puno |= ME_FLIPV1;
+ if( Inpf(vlr->n, vlr->v2->n) < 0.0 ) vlr->puno |= ME_FLIPV2;
+ if( Inpf(vlr->n, vlr->v3->n) < 0.0 ) vlr->puno |= ME_FLIPV3;
+ if(vlr->v4 && Inpf(vlr->n, vlr->v4->n) < 0.0 ) vlr->puno |= ME_FLIPV4;
+ }
+ xn= fabs(vlr->n[0]);
+ yn= fabs(vlr->n[1]);
+ zn= fabs(vlr->n[2]);
+ if(zn>=xn && zn>=yn) vlr->snproj= 0;
+ else if(yn>=xn && yn>=zn) vlr->snproj= 1;
+ else vlr->snproj= 2;
+
+ }
+}
+
+
+
diff --git a/source/blender/render/intern/source/shadbuf.c b/source/blender/render/intern/source/shadbuf.c
index 9ff3c104d0a..1403139269f 100644
--- a/source/blender/render/intern/source/shadbuf.c
+++ b/source/blender/render/intern/source/shadbuf.c
@@ -1,14 +1,10 @@
-/* shadbuf.c RENDER
- *
- * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
+/*
+ * ***** BEGIN GPL 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.
+ * of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
@@ -22,20 +18,10 @@
* The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
* All rights reserved.
*
- * The Original Code is: all of this file.
- *
- * Contributor(s): none yet.
+ * Contributor(s): 2004-2006, Blender Foundation
*
- * ***** END GPL/BL DUAL LICENSE BLOCK *****
- *
- * april 95
- *
- * $Id$
- *
- * 27-Jun-2001 switched the shadow buffer for UR to the object-shadow
- * buffers, and removed all references and fixes for UR rendering from
- * this one.
- * */
+ * ***** END GPL LICENSE BLOCK *****
+ */
#include <math.h>
#include <string.h>
@@ -45,16 +31,18 @@
#include "DNA_lamp_types.h"
#include "BKE_utildefines.h"
+
#include "BLI_arithb.h"
+#include "BLI_jitter.h"
-#include "render.h"
+#include "renderpipeline.h"
+#include "render_types.h"
+#include "renderdatabase.h"
#include "shadbuf.h"
-#include "renderHelp.h"
-#include "jitter.h"
#include "zbuf.h"
-/* XXX, could be better implemented...
+/* XXX, could be better implemented... this is for endian issues
*/
#if defined(__sgi) || defined(__sparc) || defined(__sparc__) || defined (__PPC__) || defined (__ppc__) || defined (__BIG_ENDIAN__)
#define RCOMP 3
@@ -70,80 +58,27 @@
/* ------------------------------------------------------------------------- */
+/* initshadowbuf() in convertBlenderScene.c */
-void RE_initshadowbuf(LampRen *lar, float mat[][4])
-{
- struct ShadBuf *shb;
- float hoek, temp, viewinv[4][4];
-
- /* if(la->spsi<16) return; */
-
- /* memory reservation */
- shb= (struct ShadBuf *)MEM_callocN( sizeof(struct ShadBuf),"initshadbuf");
- lar->shb= shb;
-
- if(shb==NULL) return;
-
- VECCOPY(shb->co, lar->co);
-
- /* percentage render: keep track of min and max */
- shb->size= (lar->bufsize*R.r.size)/100;
- if(shb->size<512) shb->size= 512;
- else if(shb->size > lar->bufsize) shb->size= lar->bufsize;
-
- shb->size &= ~15; /* make sure its multiples of 16 */
-
- shb->samp= lar->samp;
- shb->soft= lar->soft;
- shb->shadhalostep= lar->shadhalostep;
-
- shb->zbuf= (unsigned long *)MEM_mallocN( sizeof(unsigned long)*(shb->size*shb->size)/256, "initshadbuf2");
- shb->cbuf= (char *)MEM_callocN( (shb->size*shb->size)/256, "initshadbuf3");
-
- if(shb->zbuf==0 || shb->cbuf==0) {
- if(shb->zbuf) MEM_freeN(shb->zbuf);
- MEM_freeN(lar->shb);
- lar->shb= 0;
- return;
- }
-
- MTC_Mat4Ortho(mat);
- MTC_Mat4Invert(shb->winmat, mat); /* winmat is temp */
-
- /* matrix: combination of inverse view and lampmat */
- /* calculate again: the ortho-render has no correct viewinv */
- MTC_Mat4Invert(viewinv, R.viewmat);
- MTC_Mat4MulMat4(shb->viewmat, viewinv, shb->winmat);
-
- /* projection */
- hoek= saacos(lar->spotsi);
- temp= 0.5*shb->size*cos(hoek)/sin(hoek);
- shb->d= lar->clipsta;
-
- shb->pixsize= (shb->d)/temp;
-
- shb->far= lar->clipend;
- /* bias is percentage, made 2x karger because of correction for angle of incidence */
- /* when a ray is closer to parallel of a face, bias value is increased during render */
- shb->bias= (0.02*lar->bias)*0x7FFFFFFF;
- shb->bias= shb->bias*(100/R.r.size);
-
-}
/* ------------------------------------------------------------------------- */
-
-static void lrectreadRectz(int x1, int y1, int x2, int y2, char *r1) /* reads part from rectz in r1 */
+static void copy_to_ztile(int *rectz, int size, int x1, int y1, int tile, char *r1)
{
- unsigned int len4, *rz;
-
- if(x1>=R.rectx || x2>=R.rectx || y1>=R.recty || y2>=R.recty) return;
- if(x1>x2 || y1>y2) return;
-
- len4= 4*(x2- x1+1);
- rz= R.rectz+R.rectx*y1+x1;
- for(;y1<=y2;y1++) {
- memcpy(r1,rz,len4);
- rz+= R.rectx;
+ int len4, *rz;
+ int x2, y2;
+
+ x2= x1+tile;
+ y2= y1+tile;
+ if(x2>=size) x2= size-1;
+ if(y2>=size) y2= size-1;
+
+ if(x1>=x2 || y1>=y2) return;
+
+ len4= 4*(x2- x1);
+ rz= rectz + size*y1 + x1;
+ for(; y1<y2; y1++) {
+ memcpy(r1, rz, len4);
+ rz+= size;
r1+= len4;
}
}
@@ -180,7 +115,7 @@ static float *give_jitter_tab(int samp)
for(a=0; a<samp-1; a++) offset+= tab[a];
if(ctab[samp]==0) {
- initjit(jit[offset], samp*samp);
+ BLI_initjit(jit[offset], samp*samp);
ctab[samp]= 1;
}
@@ -188,56 +123,35 @@ static float *give_jitter_tab(int samp)
}
-void makeshadowbuf(LampRen *lar)
+void makeshadowbuf(Render *re, LampRen *lar)
{
struct ShadBuf *shb= lar->shb;
- float panophi;
- float temp, wsize, dist;
- int *rz, *rz1, verg, verg1;
+ float wsize, dist;
+ int *rectz, *rz, *rz1, verg, verg1;
unsigned long *ztile;
- int a, x, y, minx, miny, byt1, byt2, tempmode;
- short temprx,tempry, square;
+ int a, x, y, minx, miny, byt1, byt2, square;
char *rc, *rcline, *ctile, *zt;
- panophi = getPanoPhi();
-
- /* store viewvars */
- temprx= R.rectx; tempry= R.recty;
- tempmode= R.r.mode;
- R.r.mode &= ~R_ORTHO;
- R.rectx= R.recty= shb->size;
-
shb->jit= give_jitter_tab(shb->samp);
- /* matrices and window: in R.winmat the transformation is being put,
+ /* matrices and window: in winmat the transformation is being put,
transforming from observer view to lamp view, including lamp window matrix */
-
wsize= shb->pixsize*(shb->size/2.0);
- i_window(-wsize, wsize, -wsize, wsize, shb->d, shb->far, shb->winmat);
+ i_window(-wsize, wsize, -wsize, wsize, shb->d, shb->clipend, shb->winmat);
MTC_Mat4MulMat4(shb->persmat, shb->viewmat, shb->winmat);
/* temp, will be restored */
- MTC_Mat4SwapMat4(shb->persmat, R.winmat);
+ MTC_Mat4SwapMat4(shb->persmat, re->winmat);
/* zbuffering */
- if(R.rectz) MEM_freeN(R.rectz);
- R.rectz= (unsigned int *)MEM_mallocN(sizeof(int)*shb->size*shb->size,"makeshadbuf");
- rcline= MEM_mallocN(256*4+sizeof(int),"makeshadbuf2");
-
- /* store: panorama rot */
- temp= panophi;
- panophi= 0.0;
- pushTempPanoPhi(0.0);
-
- /* pano interference here? */
- setzbufvlaggen(projectvert);
+ rectz= MEM_mallocN(sizeof(int)*shb->size*shb->size, "makeshadbuf");
+ rcline= MEM_mallocN(256*4+sizeof(int), "makeshadbuf2");
- popTempPanoPhi();
- panophi= temp;
+ project_renderdata(re, projectvert, 0, 0);
- zbuffershad(lar);
+ zbuffer_shadow(re, lar, rectz, shb->size);
square= lar->mode & LA_SQUARE;
@@ -263,7 +177,7 @@ void makeshadowbuf(LampRen *lar)
rz1= (&verg)+1;
}
else {
- lrectreadRectz(x, y, MIN2(shb->size-1,x+15), MIN2(shb->size-1,y+15), rcline);
+ copy_to_ztile(rectz, shb->size, x, y, 16, rcline);
rz1= (int *)rcline;
verg= (*rz1 & 0xFFFFFF00);
@@ -334,12 +248,10 @@ void makeshadowbuf(LampRen *lar)
}
MEM_freeN(rcline);
- MEM_freeN(R.rectz); R.rectz= NULL;
+ MEM_freeN(rectz);
- /* old globals back */
- R.rectx= temprx; R.recty= tempry;
- R.r.mode= tempmode;
- MTC_Mat4SwapMat4(shb->persmat, R.winmat);
+ /* old matrix back */
+ MTC_Mat4SwapMat4(shb->persmat, re->winmat);
/* printf("lampbuf %d\n", sizeoflampbuf(shb)); */
}
@@ -455,7 +367,7 @@ float testshadowbuf(struct ShadBuf *shb, float *rco, float *dxco, float *dyco, f
xs1= siz*(1.0+co[0]/co[3]);
ys1= siz*(1.0+co[1]/co[3]);
- /* Clip for z: near and far clip values of the shadow buffer. We
+ /* Clip for z: clipsta and clipend clip values of the shadow buffer. We
* can test for -1.0/1.0 because of the properties of the
* coordinate transformations. */
fac= (co[2]/co[3]);
diff --git a/source/blender/render/intern/source/texture.c b/source/blender/render/intern/source/texture.c
index b3d053b3f34..fae58a1ec29 100644
--- a/source/blender/render/intern/source/texture.c
+++ b/source/blender/render/intern/source/texture.c
@@ -1,17 +1,12 @@
-/* texture.c
- *
- *
+/*
* $Id$
*
- * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
+ * ***** BEGIN GPL 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.
+ * of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
@@ -25,11 +20,9 @@
* The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
* All rights reserved.
*
- * The Original Code is: all of this file.
- *
- * Contributor(s): none yet.
+ * Contributor(s): 2004-2006, Blender Foundation, full recode
*
- * ***** END GPL/BL DUAL LICENSE BLOCK *****
+ * ***** END GPL LICENSE BLOCK *****
*/
#include <stdio.h>
@@ -37,10 +30,6 @@
#include <string.h>
#include <math.h>
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
#include "MTC_matrixops.h"
#include "BLI_blenlib.h"
@@ -70,11 +59,19 @@
#include "BKE_key.h"
#include "BKE_ipo.h"
-#include "render.h"
+#include "renderpipeline.h"
+#include "render_types.h"
#include "rendercore.h"
#include "envmap.h"
#include "texture.h"
+/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
+/* defined in pipeline.c, is hardcopy of active dynamic allocated Render */
+/* only to be used here in this file, it's for speed */
+extern struct Render R;
+/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
+
+
/* prototypes */
static int calcimanr(int cfra, Tex *tex);
@@ -174,12 +171,6 @@ void init_render_texture(Tex *tex)
}
}
}
- if(tex->imaflag & (TEX_ANTIALI+TEX_ANTISCALE)) {
- if(tex->ima && tex->ima->lastquality<R.osa) {
- if(tex->ima->ibuf) IMB_freeImBuf(tex->ima->ibuf);
- tex->ima->ibuf= 0;
- }
- }
if(tex->type==TEX_PLUGIN) {
if(tex->plugin && tex->plugin->doit) {
@@ -194,8 +185,8 @@ void init_render_texture(Tex *tex)
tex->extend= TEX_CLIP;
if(tex->env) {
- if(R.flag & R_RENDERING) {
- if(tex->env->stype==ENV_ANIM) RE_free_envmapdata(tex->env);
+ if(G.rendering) {
+ if(tex->env->stype==ENV_ANIM) BKE_free_envmapdata(tex->env);
}
}
}
@@ -1232,34 +1223,6 @@ int multitex(Tex *tex, float *texvec, float *dxt, float *dyt, int osatex, TexRes
return retval;
}
-/* preview render */
-int multitex_ext(Tex *tex, float *texvec, float *tin, float *tr, float *tg, float *tb, float *ta)
-{
- TexResult texr;
- float dummy[3];
- int retval;
-
- /* does not return Tin, hackish... */
- if(tex->type==TEX_STUCCI) {
- texr.nor= dummy;
- dummy[0]= 1.0;
- dummy[1]= dummy[2]= 0.0;
- }
- else texr.nor= NULL;
-
- retval= multitex(tex, texvec, NULL, NULL, 0, &texr);
- if(tex->type==TEX_STUCCI) {
- *tin= 0.5 + 0.7*texr.nor[0];
- CLAMP(*tin, 0.0, 1.0);
- }
- else *tin= texr.tin;
- *tr= texr.tr;
- *tg= texr.tg;
- *tb= texr.tb;
- *ta= texr.ta;
- return retval;
-}
-
/* ------------------------------------------------------------------------- */
/* in = destination, tex = texture, out = previous color */
diff --git a/source/blender/render/intern/source/vanillaRenderPipe.c b/source/blender/render/intern/source/vanillaRenderPipe.c
deleted file mode 100644
index 1b74adaae9c..00000000000
--- a/source/blender/render/intern/source/vanillaRenderPipe.c
+++ /dev/null
@@ -1,1641 +0,0 @@
-/**
- *
- * ***** 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.
- *
- * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
- * All rights reserved.
- *
- * The Original Code is: all of this file.
- *
- * Contributor(s): none yet.
- *
- * ***** END GPL/BL DUAL LICENSE BLOCK *****
- * vanillaRenderPipe.c
- *
- * 28-06-2000 nzc
- *
- * $Id$
- *
- */
-
-/*
- The render pipe
- ---------------
-
- The overall results of the render pass should end up in R.rectot. This
- buffer already exists, and although its contents may change, its location
- may not. A lot of other routines depend on it!
-
-*/
-
-/* global includes */
-#include <math.h>
-#include <limits.h> /* INT_MIN,MAX are used here */
-#include <stdlib.h>
-#include "MTC_vectorops.h"
-#include "MTC_matrixops.h"
-#include "MEM_guardedalloc.h"
-
-#include "DNA_camera_types.h"
-#include "DNA_object_types.h"
-#include "BKE_global.h"
-#include "BKE_utildefines.h"
-
-#include "BLI_arithb.h"
-#include "BLI_rand.h"
-
-/* local includes (from the render module) */
-#include "RE_callbacks.h"
-#include "render.h" /* all kinds of stuff */
-#include "zbuf.h" /* for vergzvlak, zbufclip, zbufclipwire */
-#include "edgeRender.h" /* all edge rendering stuff */
-#include "pixelshading.h" /* painting the pixels */
-#include "rendercore.h"
-
-/* general calculus and data manipulation, also local */
-#include "gammaCorrectionTables.h"
-#include "jitter.h"
-#include "pixelblending.h"
-#include "zbufferdatastruct.h"
-
-/* own includes */
-#include "vanillaRenderPipe.h"
-
-#include "SDL_thread.h"
-
-/* threshold for alpha */
-#define RE_FULL_ALPHA_FLOAT 0.9998
-
-/* ------------------------------------------------------------------------- */
-/* Debug defines: disable all for production level code. */
-/* These variables control faking of rendered colours, extra tracing, */
-/* extra error checking and such. */
-/* ------------------------------------------------------------------------- */
-
-/* if defined: _very_ explicit tracing and checking enabled */
-/* #define RE_FULL_SAFETY */
-/* if defined: use 'simple' alpha thresholding on oversampling */
-/* #define RE_SIMPLE_ALPHA_THRESHOLD */
-
-/* ------------------------------------------------------------------------- */
-
-/* ------------------------------------------------------------------------- */
-
-/* External : -------------------------------------------------------------- */
-
-extern float centLut[16]; /* Lookup for jitter offsets. */
-extern unsigned int Zsample; /* Nr. of the currently active oversample. This */
- /* counter must be set explicitly by the */
- /* function that builds the z-buffer. */
- /* The buffer-filling functions use it. */
-extern float Zjitx,Zjity; /* The x,y values for jitter offset */
-
-extern float Zmulx, Zmuly; /* Some kind of scale? */
-
-extern char cmask[256]; /* When a pixel is supersampled, we must */
-extern char *centmask; /* compute its colour on a point _on_ the face. */
- /* These two are used to compute an offset to */
- /* guarantee we use valid coordinates. */
-
-extern RE_APixstrExt *APixbufExt;/*Zbuffer: linked list of face, halo indices*/
-
-/* Globals : --------------------------------------------------------------- */
- /* we use 2 x three lines, for gaussian sample */
-RE_COLBUFTYPE *AColourBuffer0; /* Buffer for colours of 1 line of pixels */
-RE_COLBUFTYPE *AColourBuffer1; /* Buffer for colours of 1 line of pixels */
-RE_COLBUFTYPE *AColourBuffer2; /* Buffer for colours of 1 line of pixels */
-RE_COLBUFTYPE *AColourBuffer1a; /* Buffer for colours of 1 line of pixels */
-RE_COLBUFTYPE *AColourBuffer2a; /* Buffer for colours of 1 line of pixels */
-RE_COLBUFTYPE *AColourBuffer3; /* Buffer for colours of 1 line of pixels */
-
-static int Aminy; /* y value of first line in the accu buffer */
-static int Amaxy; /* y value of last line in the accu buffer */
- /* -also used to clip when zbuffering */
-
-/* Buffer width refers to the size of the buffers we build. Image size is */
-/* the same as R.rectx, R.recty. */
-static int zBufferWidth; /* special width because zbuffer needs to be */
- /* wider */
-
-static int Azvoordeel; /* A small offset for transparent rendering. */
-int alphaLUT[32]; /* alpha lookuptable, for oversampling */
- /* Its function has been superceded because */
- /* pixels are always integrated. This */
- /* performs the same normalization. */
-int osaNr; /* The oversample number. I keep it */
- /* separately here, because I treat no OSA */
- /* as if it were osa=1. */
-
-/* ------------------------------------------------------------------------- */
-
-/**
-* Z buffer initializer, for new pipeline.
- * <LI>
- * <IT> AColourBuffer : colour buffer for one line
- * <IT> APixbufExt : pixel data buffer for one line, depth RE_ZBUFLEN
- * </LI>
- */
-static void initRenderBuffers(int bwidth)
-{
- /* bwidth+4, as in rendercore.c. I think it's too much, but yah (ton) */
- AColourBuffer0 = MEM_callocN(4 * sizeof(RE_COLBUFTYPE) * (bwidth+4), "Acolrow");
- AColourBuffer1 = MEM_callocN(4 * sizeof(RE_COLBUFTYPE) * (bwidth+4), "Acolrow");
- AColourBuffer2 = MEM_callocN(4 * sizeof(RE_COLBUFTYPE) * (bwidth+4), "Acolrow");
- AColourBuffer1a = MEM_callocN(4 * sizeof(RE_COLBUFTYPE) * (bwidth+4), "Acolrow");
- AColourBuffer2a = MEM_callocN(4 * sizeof(RE_COLBUFTYPE) * (bwidth+4), "Acolrow");
- AColourBuffer3 = MEM_callocN(4 * sizeof(RE_COLBUFTYPE) * (bwidth+4), "Acolrow");
-
- /* The +1 is needed because the fill-functions use a +1 offset when */
- /* filling in pixels. Mind that also the buffer-clearing function needs */
- /* this offset (done in calcZBufLine). */
- /* The offset is wrong: it shouldn't be there. I need to fix this still. */
- zBufferWidth = bwidth + 1;
- initZbuffer(bwidth + 1);
-
- Aminy= -1000; /* indices of lines in the z buffer: no lines buffered */
- Amaxy= -1000;
-
-
-}
-
-/* ------------------------------------------------------------------------- */
-/**
- * Z buffer destructor, frees stuff from initZBuffers().
- */
-
-static void freeRenderBuffers(void) {
- if (AColourBuffer0) MEM_freeN(AColourBuffer0);
- if (AColourBuffer1) MEM_freeN(AColourBuffer1);
- if (AColourBuffer2) MEM_freeN(AColourBuffer2);
- if (AColourBuffer1a) MEM_freeN(AColourBuffer1a);
- if (AColourBuffer2a) MEM_freeN(AColourBuffer2a);
- if (AColourBuffer3) MEM_freeN(AColourBuffer3);
- freeZbuffer();
-}
-/* ------------------------------------------------------------------------- */
-
-/**
- * New fill function for z buffer, for edge-only rendering.
- */
-static void zBufferFillFace(ZSpan *zspan, int zvlnr, float *v1, float *v2, float *v3)
-{
- /* Coordinates of the vertices are specified in ZCS */
- VlakRen *vlr;
- int apteller, apoffsetteller;
- double z0; /* used as temp var*/
- double xx1;
- double zxd,zyd,zy0, tmp;
- float *minv,*maxv,*midv;
- register int zverg,zvlak,x;
- int my0,my2,sn1,sn2,rectx,zd;
- int y,omsl,xs0,xs1,xs2,xs3, dx0,dx1,dx2, mask;
- int obtype;
- /* These used to be doubles. We may want to change them back if the */
- /* loss of accuracy proves to be a problem? There does not seem to be */
- /* any performance issues here, so I'll just keep the doubles. */
- /* float vec0[3], vec1[3], vec2[3]; */
- double vec0[3], vec1[3], vec2[3];
-
- vlr= RE_findOrAddVlak( (zvlnr-1) & 0x7FFFFF);
- if(vlr->mat->mode & MA_ZTRA) obtype= RE_POLY;
- else obtype= RE_POLY|RE_SOLID;
-
- /* MIN MAX */
- /* sort vertices for min mid max y value */
- if(v1[1]<v2[1]) {
- if(v2[1]<v3[1]) { minv=v1; midv=v2; maxv=v3;}
- else if(v1[1]<v3[1]) { minv=v1; midv=v3; maxv=v2;}
- else { minv=v3; midv=v1; maxv=v2;}
- }
- else {
- if(v1[1]<v3[1]) { minv=v2; midv=v1; maxv=v3;}
- else if(v2[1]<v3[1]) { minv=v2; midv=v3; maxv=v1;}
- else { minv=v3; midv=v2; maxv=v1;}
- }
-
- if(minv[1] == maxv[1]) return; /* security to remove 'zero' size faces */
-
- my0 = ceil(minv[1]);
- my2 = floor(maxv[1]);
- omsl = floor(midv[1]);
-
- /* outside the current z buffer slice: clip whole face */
- if( (my2 < Aminy) || (my0 > Amaxy)) return;
-
- if(my0<Aminy) my0= Aminy;
-
- /* EDGES : THE LONGEST */
- xx1= maxv[1]-minv[1];
- if(xx1>2.0/65536.0) {
- z0= (maxv[0]-minv[0])/xx1;
-
- tmp= (-65536.0*z0);
- dx0= CLAMPIS(tmp, INT_MIN, INT_MAX);
-
- tmp= 65536.0*(z0*(my2-minv[1])+minv[0]);
- xs0= CLAMPIS(tmp, INT_MIN, INT_MAX);
- }
- else {
- dx0= 0;
- xs0= 65536.0*(MIN2(minv[0],maxv[0]));
- }
- /* EDGES : THE TOP ONE */
- xx1= maxv[1]-midv[1];
- if(xx1>2.0/65536.0) {
- z0= (maxv[0]-midv[0])/xx1;
-
- tmp= (-65536.0*z0);
- dx1= CLAMPIS(tmp, INT_MIN, INT_MAX);
-
- tmp= 65536.0*(z0*(my2-midv[1])+midv[0]);
- xs1= CLAMPIS(tmp, INT_MIN, INT_MAX);
- }
- else {
- dx1= 0;
- xs1= 65536.0*(MIN2(midv[0],maxv[0]));
- }
- /* EDGES : THE BOTTOM ONE */
- xx1= midv[1]-minv[1];
- if(xx1>2.0/65536.0) {
- z0= (midv[0]-minv[0])/xx1;
-
- tmp= (-65536.0*z0);
- dx2= CLAMPIS(tmp, INT_MIN, INT_MAX);
-
- tmp= 65536.0*(z0*(omsl-minv[1])+minv[0]);
- xs2= CLAMPIS(tmp, INT_MIN, INT_MAX);
- }
- else {
- dx2= 0;
- xs2= 65536.0*(MIN2(minv[0],midv[0]));
- }
-
- /* ZBUF DX DY */
- /* xyz_1 = v_1 - v_2 */
- MTC_diff3DFF(vec1, v1, v2);
- /* xyz_2 = v_2 - v_3 */
- MTC_diff3DFF(vec2, v2, v3);
- /* xyz_0 = xyz_1 cross xyz_2 */
- MTC_cross3Double(vec0, vec1, vec2);
-
- /* cross product of two of the sides is 0 => this face is too small */
- if(vec0[2]==0.0) return;
-
- if(midv[1] == maxv[1]) omsl= my2;
- if(omsl < Aminy) omsl= Aminy-1; /* make sure it takes the first loop entirely */
-
- while (my2 > Amaxy) { /* my2 can be larger */
- xs0+=dx0;
- if (my2<=omsl) {
- xs2+= dx2;
- }
- else{
- xs1+= dx1;
- }
- my2--;
- }
-
- xx1= (vec0[0]*v1[0]+vec0[1]*v1[1])/vec0[2]+v1[2];
-
- zxd= -vec0[0]/vec0[2];
- zyd= -vec0[1]/vec0[2];
- zy0= my2*zyd+xx1;
- zd= (int)CLAMPIS(zxd, INT_MIN, INT_MAX);
-
- /* start-ofset in rect */
- /* rectx= R.rectx; */
- /* I suspect this var needs very careful setting... When edge rendering */
- /* is on, this is strange */
- rectx = zBufferWidth;
- apoffsetteller = rectx*(my2-Aminy);
-
- mask= 1<<Zsample;
- zvlak= zvlnr;
-
- xs3= 0; /* flag */
- if(dx0>dx1) {
- MTC_swapInt(&xs0, &xs1);
- MTC_swapInt(&dx0, &dx1);
- xs3= 1; /* flag */
-
- }
-
- for(y=my2;y>omsl;y--) {
-
- sn1= xs0>>16;
- xs0+= dx0;
-
- sn2= xs1>>16;
- xs1+= dx1;
-
- sn1++;
-
- if(sn2>=rectx) sn2= rectx-1;
- if(sn1<0) sn1= 0;
- zverg= (int) CLAMPIS((sn1*zxd+zy0), INT_MIN, INT_MAX);
- apteller = apoffsetteller + sn1;
- x= sn2-sn1;
-
- zverg-= Azvoordeel;
-
- while(x>=0) {
- insertObject(apteller, zvlnr, obtype, zverg, mask);
- zverg+= zd;
- apteller++;
- x--;
- }
- zy0-= zyd;
- apoffsetteller -= rectx;
- }
-
- if(xs3) {
- xs0= xs1;
- dx0= dx1;
- }
- if(xs0>xs2) {
- xs3= xs0;
- xs0= xs2;
- xs2= xs3;
- xs3= dx0;
- dx0= dx2;
- dx2= xs3;
- }
-
- for(; y>=my0; y--) {
-
- sn1= xs0>>16;
- xs0+= dx0;
-
- sn2= xs2>>16;
- xs2+= dx2;
-
- sn1++;
-
- if(sn2>=rectx) sn2= rectx-1;
- if(sn1<0) sn1= 0;
- zverg= (int) CLAMPIS((sn1*zxd+zy0), INT_MIN, INT_MAX);
- apteller = apoffsetteller + sn1;
- x= sn2-sn1;
-
- zverg-= Azvoordeel;
-
- while(x>=0) {
- insertObject(apteller, zvlnr, obtype, zverg, mask);
- zverg+= zd;
- apteller++;
- x--;
- }
-
- zy0-=zyd;
- apoffsetteller -= rectx;
- }
-}
-/* ------------------------------------------------------------------------- */
-
-static void zBufferFillEdge(int zvlnr, float *vec1, float *vec2)
-{
- int apteller;
- int start, end, x, y, oldx, oldy, ofs;
- int dz, vergz, mask, maxtest=0;
- float dx, dy;
- float v1[3], v2[3];
-
- dx= vec2[0]-vec1[0];
- dy= vec2[1]-vec1[1];
-
- if(fabs(dx) > fabs(dy)) {
-
- /* all lines from left to right */
- if(vec1[0]<vec2[0]) {
- VECCOPY(v1, vec1);
- VECCOPY(v2, vec2);
- }
- else {
- VECCOPY(v2, vec1);
- VECCOPY(v1, vec2);
- dx= -dx; dy= -dy;
- }
-
- start= floor(v1[0]);
- end= start+floor(dx);
- if(end >= zBufferWidth) end = zBufferWidth - 1;
-
- oldy= floor(v1[1]);
- dy/= dx;
-
- vergz= v1[2];
- vergz-= Azvoordeel;
- dz= (v2[2]-v1[2])/dx;
- if(vergz>0x70000000 && dz>0) maxtest= 1; // prevent overflow
-
- apteller = zBufferWidth*(oldy-Aminy) +start;
- mask = 1<<Zsample;
-
- if(dy<0) ofs= -zBufferWidth;
- else ofs= zBufferWidth;
-
- for(x= start; x<=end; x++, /* ap++, */ apteller++) {
-
- y= floor(v1[1]);
- if(y!=oldy) {
- oldy= y;
- apteller += ofs;
- }
-
- if(x>=0 && y>=Aminy && y<=Amaxy) {
- insertObject(apteller, zvlnr, RE_POLY, vergz, mask);
- }
-
- v1[1]+= dy;
- vergz+= dz;
- if(maxtest && vergz<0) vergz= 0x7FFFFFF0;
- }
- }
- else {
-
- /* all lines from top to bottom */
- if(vec1[1]<vec2[1]) {
- VECCOPY(v1, vec1);
- VECCOPY(v2, vec2);
- }
- else {
- VECCOPY(v2, vec1);
- VECCOPY(v1, vec2);
- dx= -dx; dy= -dy;
- }
-
- start= floor(v1[1]);
- end= start+floor(dy);
-
- if(start>Amaxy || end<Aminy) return;
-
- if(end>Amaxy) end= Amaxy;
-
- oldx= floor(v1[0]);
- dx/= dy;
-
- vergz= v1[2];
- vergz-= Azvoordeel;
- dz= (v2[2]-v1[2])/dy;
- if(vergz>0x70000000 && dz>0) maxtest= 1; // prevent overflow
-
- apteller = zBufferWidth*(start-Aminy) +oldx;
-
- mask= 1<<Zsample;
-
- if(dx<0) ofs= -1;
- else ofs= 1;
-
- for(y= start; y<=end; y++, apteller += zBufferWidth) {
-
- x= floor(v1[0]);
- if(x!=oldx) {
- oldx= x;
- apteller += ofs;
- }
-
- if(x>=0 && y>=Aminy && (x < zBufferWidth)) {
- insertObject(apteller, zvlnr, RE_POLY, vergz, mask);
- }
-
- v1[0]+= dx;
- vergz+= dz;
- if(maxtest && vergz<0) vergz= 0x7FFFFFF0;
- }
- }
-}
-/* ------------------------------------------------------------------------- */
-
-/**
- * Count and sort the list behind ap into buf. Sorts on min. distance.
- * Low index <=> high z
- */
-static int countAndSortPixelFaces(int zrow[][RE_PIXELFIELDSIZE],
- RE_APixstrExt *ap)
-{
- int totvlak; /* face counter */
- int i; /* generic counter */
-
- totvlak= 0;
- while(ap) {
- for(i=0; i<4; i++) {
- if(ap->t[i]) {
- zrow[totvlak][0] = ap->zmin[i];
- zrow[totvlak][1] = ap->p[i];
- zrow[totvlak][2] = ap->mask[i];
- zrow[totvlak][3] = ap->t[i];
- zrow[totvlak][4] = ap->zmax[i];
- totvlak++;
- if(totvlak > (RE_MAX_FACES_PER_PIXEL - 1))
- {
- totvlak = (RE_MAX_FACES_PER_PIXEL - 1);
- }
- } else break;
- };
- ap= ap->next;
- }
-
- if(totvlak==2) { /* Sort faces ----------------------------- */
- if(zrow[0][0] < zrow[1][0]) {
- i= zrow[0][0]; zrow[0][0]= zrow[1][0]; zrow[1][0]= i;
- i= zrow[0][1]; zrow[0][1]= zrow[1][1]; zrow[1][1]= i;
- i= zrow[0][2]; zrow[0][2]= zrow[1][2]; zrow[1][2]= i;
- i= zrow[0][3]; zrow[0][3]= zrow[1][3]; zrow[1][3]= i;
- i= zrow[0][4]; zrow[0][4]= zrow[1][4]; zrow[1][4]= i;
- } /* else: two faces, and ordering is ok */
- } else if (totvlak != 1) qsort(zrow, totvlak,
- sizeof(int)*RE_PIXELFIELDSIZE, vergzvlak);
- return totvlak;
-}
-
-/* ------------------------------------------------------------------------- */
-/* Oversampler v3 - check CVS for older versions */
-/* */
-/* In this version, I have split up the rendering into several parts, so I */
-/* can generate better profiles. */
-/* */
-/* - multiple blend functions ? */
-/* - x-rays? */
-/* - volumetric stuff ? */
-/* - maybe the oversampling should move to the shading part */
-/* */
-/* ------------------------------------------------------------------------- */
-
-/* These variables describe the buffers needed for the oversampling. */
-/* 1. A bit vector with flags to indicate which pixels have received colour. */
-static int VR_covered = 0;
-/* 2. The local vector collector, for resolving conflicts only. */
-static int VR_cbuf[RE_MAX_FACES_PER_PIXEL][2];
-
-/**
- * Analyze the z-buffer, and pre-sample the colours.
- */
-static int composeStack(int zrow[][RE_PIXELFIELDSIZE], RE_COLBUFTYPE *collector,
- struct RE_faceField* stack, int ptr,
- int totvlak, float x, float y, int osaNr)
-{
- VlakRen *vlr= NULL;
- float xs = 0.0;
- float ys = 0.0; /* coordinates for the render-spot */
- float alphathreshold[RE_MAX_OSA_COUNT];
- float colbuf[4];
- int inconflict = 0;
- int saturationthreshold = 0;
- int saturated = 0;
- int i = 0;
- int Ccount = 0;
- int Cthresh = 0;
- int save_totvlak = totvlak;
- int fullsubpixelflags = 0;
- int full_osa;
-
- VR_covered = 0;
- for(i = 0; i < osaNr; i++) alphathreshold[i] = 0.0;
- saturationthreshold = ( (1<<osaNr) - 1);
-
- while ( (!saturated || (saturated && inconflict) ) && (totvlak > 0) ) {
- totvlak--;
-
- full_osa= 0;
- if(R.osa && (zrow[totvlak][RE_TYPE] & RE_POLY)) {
- vlr= RE_findOrAddVlak((zrow[totvlak][RE_INDEX]-1) & 0x7FFFFF);
- if(vlr->flag & R_FULL_OSA) full_osa= 1;
- }
-
- if(full_osa) {
- float div=0.0, accol[4]={0.0, 0.0, 0.0, 0.0};
- int a, mask= zrow[totvlak][RE_MASK];
-
- for(a=0; a<R.osa; a++) {
- if(mask & (1<<a)) {
- xs= (float)x + jit[a][0];
- ys= (float)y + jit[a][1];
- renderPixel(collector, xs, ys, zrow[totvlak], 1<<a);
- accol[0] += collector[0]; accol[1] += collector[1]; accol[2] += collector[2]; accol[3] += collector[3];
- div+= 1.0;
- }
- }
- if(div!=0.0) {
- div= 1.0/div;
- collector[0]= accol[0]*div; collector[1]= accol[1]*div; collector[2]= accol[2]*div; collector[3]= accol[3]*div;
- }
- stack[ptr].mask= mask;
- stack[ptr].data= vlr;
- }
- else {
- if(R.osa) {
- i= centmask[ zrow[totvlak][RE_MASK] ]; /* recenter sample position - */
- xs= (float)x+centLut[i & 15];
- ys= (float)y+centLut[i >> 4];
- }
- else {
- xs= (float)x;
- ys= (float)y;
- }
-
- /* stack face ----------- */
- stack[ptr].mask = zrow[totvlak][RE_MASK];
- stack[ptr].data = renderPixel(collector, xs, ys, zrow[totvlak], stack[ptr].mask);
- }
- stack[ptr].faceType = zrow[totvlak][RE_TYPE];
- cpFloatColV(collector, stack[ptr].colour);
-
- /* This is done so that spothalos are properly overlayed on halos */
- /* maybe we need to check the colour here... */
- if(zrow[totvlak][RE_TYPE] & RE_POLY) VR_covered |= zrow[totvlak][RE_MASK];
-
- /* calculate conflict parameters: ---------------------------------- */
- if( zrow[totvlak][RE_ZMIN] < Cthresh ) {
- inconflict = 1;
- /* Prevent from switching on bad data. This may be done more */
- /* efficiently later on. It is _quite_ important. */
- if (totvlak == save_totvlak - 1) Ccount = 0;
- else if(Ccount == 0) Ccount = 2;
- else Ccount++;
- stack[ptr].conflictCount = Ccount;
- if (zrow[totvlak][RE_ZMAX] > Cthresh)
- Cthresh = zrow[totvlak][RE_ZMAX];
- } else {
- Cthresh = zrow[totvlak][RE_ZMAX];
- Ccount = 0;
- stack[ptr].conflictCount = 0;
- if (totvlak > 0 )
- inconflict = (zrow[totvlak-1][RE_ZMIN] < Cthresh);
- else inconflict = 0;
- }
-
- ptr++;
-
- /* alpha threshold ------------------------------------------------- */
- /* There are currently two ways of blending: alpha-over, and add. */
- /* Add-blending does strange things, in the sense that alpha is */
- /* simply added, and colour is sort of alpha-over blended. Using the */
- /* same thresholding relation seems to work ok. For less than unity */
- /* add factor, the alpha threshold may rise faster, but currently we */
- /* do not check for this factor. */
- for(i = 0; i < osaNr; i++) {
- if ( zrow[totvlak][RE_MASK] & (1<<i)) {
- alphathreshold[i] +=
- ((1.0 - alphathreshold[i]) * collector[3]);
- if (alphathreshold[i] > RE_FULL_ALPHA_FLOAT)
- fullsubpixelflags |= (1<<i);
- }
- }
- saturated = (fullsubpixelflags >= saturationthreshold);
-
- } /* done stacking ----------------------------------------------------- */
-
- /*
- STACK_SKY Sometimes, a sky pixel is needed. Since there are
- some issues with mist/ ztra/ env, I always put the sky here.
- */
-/* if (!saturated) { */
- totvlak--;
-
- xs= (float)x;
- ys= (float)y;
-
- /* code identical for rendering empty sky pixel */
- renderSkyPixelFloat(collector, xs, ys, NULL);
- cpFloatColV(collector, colbuf);
-
- if(R.flag & R_LAMPHALO) {
- renderSpotHaloPixel(x, y, collector);
- addAlphaOverFloat(colbuf, collector);
- }
-
- stack[ptr].faceType = RE_SKY;
- cpFloatColV(colbuf, stack[ptr].colour);
- stack[ptr].data = NULL;
- stack[ptr].mask = 0xFFFF;
- stack[ptr].conflictCount = 0;
- ptr++;
-/* } */
-
- /* Index of the top of the stack */
- return ptr;
-}
-
-/* ------------------------------------------------------------------------- */
-
-/**
- * Calculate the view depth to this object on this location, with
- * the current view parameters in R.
- */
-static int calcDepth(float x, float y, void *data, int type)
-{
- float view[3];
-
- if (type & RE_POLY) {
- VlakRen* vlr = (VlakRen*) data;
- VertRen* v1;
- float dface, div, zco, hoco_z, hoco_w;
- int zbuf_co;
-
- v1 = vlr->v1;
-
- /* vertex dot face normal: WCS */
- dface= v1->co[0]*vlr->n[0]+v1->co[1]*vlr->n[1]+v1->co[2]*vlr->n[2];
-
- /* jitter has been added to x, y ! */
- /* view vector view: screen coords */
- view[0]= (x+(R.xstart)+0.5);
-
- if(R.flag & R_SEC_FIELD) {
- if(R.r.mode & R_ODDFIELD) view[1]= (y + R.ystart)*R.ycor;
- else view[1]= (y + R.ystart + 1.0)*R.ycor;
- }
- else view[1]= (y + R.ystart + 0.5)*R.ycor;
-
-
- /* for pano, another rotation in the xz plane is needed.... */
-
- /* this is ok, in WCS */
- view[2]= -R.viewfac; /* distance to viewplane */
-
- /* calculate zcoord */
- if(R.r.mode & R_ORTHO) {
- /* x and y 3d coordinate can be derived from pixel coord and winmat */
- float fx= 2.0/(R.rectx*R.winmat[0][0]);
- float fy= 2.0/(R.recty*R.winmat[1][1]);
-
- fx= (0.5 + x - 0.5*R.rectx)*fx - R.winmat[3][0]/R.winmat[0][0];
- fy= (0.5 + y - 0.5*R.recty)*fy - R.winmat[3][1]/R.winmat[1][1];
-
- /* using a*x + b*y + c*z = d equation, (a b c) is normal */
- zco= (dface - vlr->n[0]*fx - vlr->n[1]*fy)/vlr->n[2];
-
- }
- else {
- /* face normal dot view vector: but how can this work? (nzc) */
- div = MTC_dot3Float(vlr->n, view);
- if (div!=0.0) zco = (view[2]*dface)/div;
- else zco = 0.0;
- }
-
- /* same as in zbuf.c */
- hoco_z = zco*R.winmat[2][2] + R.winmat[3][2];
- hoco_w = zco*R.winmat[2][3] + R.winmat[3][3];
-
- if(hoco_w!=0.0) zbuf_co = 0x7FFFFFFF*(hoco_z/hoco_w);
- else zbuf_co= 0x7FFFFFFF;
-
- return zbuf_co; /* z component of R.co */
- } else if (type & RE_HALO) {
- HaloRen* har = (HaloRen*) data;
- return har->zBufDist;
- }
- return 0;
-}
-
-/**
- * Blend source over dest, and leave result in dest. 1 pixel.
- */
-static void blendOverFloat(int type, float* dest, float* source, void* data)
-{
-
- if (type & RE_POLY) {
- VlakRen *ver = (VlakRen*) data;
- if ((ver->mat != NULL) && (ver->mat->add > RE_FACE_ADD_THRESHOLD)) {
- char addf = (char) (ver->mat->add * 255.0);
- addalphaAddfacFloat(dest, source, addf);
- }
- else
- addAlphaOverFloat(dest, source);
- } else if (type & RE_HALO) {
- HaloRen *har= (HaloRen*) data;
- addalphaAddfacFloat(dest, source, har->add);
- } else if (type & RE_SKY) {
- addAlphaOverFloat(dest, source);
- }
-
-}
-
-
-/**
- * New approach: sample substacks. Each substack is first copied into
- * a stack buffer, and then blended down.
- * */
-static void integratePerSubStack(float *sampcol, struct RE_faceField* stack,
- int ptr, float x, float y, int osaNr)
-{
- int i = 0;
- int j = 0;
- int k = 0;
- int l = 0;
- int filterMask = 0;
- /* next step would be to improve on the substack, I guess */
- int subStack[RE_MAX_FACES_PER_PIXEL + 1];
- float colSubStack[4 * (RE_MAX_FACES_PER_PIXEL + 1)];
- int subStackPtr = 0;
- int subStackSize = 0;
- float xs, ys;
-
-
- while (i < osaNr) {
- xs = x + jit[i][0];
- ys = y + jit[i][1];
-
- /*
- * 1. Copy all relevant faces. Mind that stack is built from
- * low index = low z to high index =high z. The sub-stack is
- * exactly the other way around! (low index = high z)
- */
- filterMask = (1 << i);
- subStackPtr = 0;
- j = ptr - 1; /* the topmost valid face */
- while (j >= 0) {
- if (stack[j].conflictCount) {
- /* Conflict: we sort the faces for distance right
- * away. We could adapt conflict count, and adjust the
- * stack later on, but that's really doing too much,
- * too complicated. This is just fine.
- * */
- k = 0;
- l = 0;
- /* check whether the face intersects, and if so,
- * stores depth */
- while (k < stack[j].conflictCount) {
- if (stack[j - k].mask & filterMask) {
- VR_cbuf[l][0] = calcDepth(xs, ys,
- stack[j - k].data,
- stack[j - k].faceType);
- VR_cbuf[l][1] = j - k;
- l++;
- }
- k++;
- }
- /* VR_cbuf now contains l pairs (distance, stackindex) */
- qsort(VR_cbuf, l, sizeof(int)*2, vergzvlak);
- /*
- * Now we put the sorted indices on the
- * substack. qsort delivers low index = low z, which
- * is the right wrong order for the substack */
- k = 0;
- while (k < l) {
- subStack[subStackPtr] = VR_cbuf[k][1];
- cpFloatColV(stack[VR_cbuf[k][1]].colour, &colSubStack[4*subStackPtr]);
- subStackPtr++;
- k++;
- }
-
- j -= stack[j].conflictCount;
- } else {
- /* no conflict */
- if (stack[j].mask & filterMask) {
- subStack[subStackPtr] = j;
- cpFloatColV(stack[j].colour, &colSubStack[4*subStackPtr]);
- subStackPtr++;
- }
- j--;
- }
- }
- subStackSize = subStackPtr;
-
- /* 2. Operations on the faces can go here for now. I might
- * want to mix this code with the blending. Currently, I only
- * handle env/ztra faces. It's a dirty patch now...*/
- subStackPtr = subStackSize - 1;
- while (subStackPtr >= 0) {
- /* we can make a general meachanism here for operations */
- if (stack[subStack[subStackPtr]].faceType & RE_POLY){
- VlakRen* vlr = (VlakRen*) stack[subStack[subStackPtr]].data;
- if (vlr->mat) {
- /* ENV faces */
- if (vlr->mat->mode & MA_ENV) {
- int m;
- colSubStack[4*subStackPtr] = 0.0;
- colSubStack[(4*subStackPtr) + 1] = 0.0;
- colSubStack[(4*subStackPtr) + 2] = 0.0;
- colSubStack[(4*subStackPtr) + 3] = 0.0;
- m = subStackPtr - 1;
- while (m >= 0) {
- if (stack[subStack[m]].faceType != RE_SKY) {
- colSubStack[4*m] = 0.0;
- colSubStack[(4*m) + 1] = 0.0;
- colSubStack[(4*m) + 2] = 0.0;
- colSubStack[(4*m) + 3] = 0.0;
- }
- m--;
- }
- }
- /* ZTRA faces */
- else if (!(vlr->mat->mode & MA_ZTRA)) {
- int m;
- m = subStackPtr - 1;
- while (m >= 0) {
- if (stack[subStack[m]].faceType != RE_SKY) {
- colSubStack[4*m] = 0.0;
- colSubStack[(4*m) + 1] = 0.0;
- colSubStack[(4*m) + 2] = 0.0;
- colSubStack[(4*m) + 3] = 0.0;
- }
- m--;
- }
- }
- }
- }
- subStackPtr--;
- }
-
- /* 3. blend down */
- subStackPtr = 0;
- while( subStackPtr < subStackSize ) {
- blendOverFloat(stack[subStack[subStackPtr]].faceType, /* type */
- sampcol + (4 * i), /* dest */
- &colSubStack[4 * subStackPtr],
- stack[subStack[subStackPtr]].data); /* data */
- subStackPtr++;
- }
-
- i++;
- }
-}
-
-
-
-/* ------------------------------------------------------------------------- */
-/* Rendering: per line */
-/* */
-/* For each pixel in this line, we render as follows: */
-/* a. Count the number of objects buffered for this pixel, and sort on z */
-/* ------- Result is left in zrow */
-/* b. Shade the pixel: */
-/* 1. From front to back: calculate the colour for this object */
-/* 2. Blend this colour in with the already calculated colour */
-/* Repeat 1. and 2. until no faces remain. */
-/* For each pixel, a face is only rendered once, even if it is */
-/* jittered. All subpixels get the colour of the weighted centre */
-/* of the jitter-positions this face covers. */
-/* ------- Result is left in sampcol[] */
-/* c. Copy the result to the colour buffer */
-/* d. Do gamma-corrected blending */
-/* */
-/* zrow may need some clarification: */
-/* 0 - min. distance */
-/* 1 - face/halo index */
-/* 2 - masks */
-/* 3 - type RE_POLY or RE_HALO */
-/* 4 - max. distance */
-/* It is used to store copies of RE_APixstrExt records. These are sorted for */
-/* distance, and then used for rendering pixels. zrow might be replaced by */
-/* an RE_APixstrExt* array */
-/* - redo the numbering to something more logical */
-
-
-/* threadsafe global arrays, too large for stack */
-typedef struct zbufline {
- int zrow[RE_MAX_FACES_PER_PIXEL][RE_PIXELFIELDSIZE];
- struct RE_faceField osastack[RE_MAX_FACES_PER_PIXEL + 1];
-} zbufline;
-
-static zbufline zb1, zb2;
-
-static void renderZBufLine(int y, RE_COLBUFTYPE *colbuf1, RE_COLBUFTYPE *colbuf2, RE_COLBUFTYPE *colbuf3)
-{
- RE_APixstrExt *ap; /* iterator for the face-lists */
- RE_COLBUFTYPE collector[4];
- RE_COLBUFTYPE sampcol[RE_MAX_OSA_COUNT * 4];
- RE_COLBUFTYPE *j = NULL; /* generic pixel pointer */
- int apteller;
- int x; /* pixel counter */
- int i; /* yet another counter */
- int stackDepth; /* faces-behind-this-pixel counter */
- int osastack_ptr; /* Points to the lowest empty field. The indexed */
- zbufline *zbl;
-
- /* thread safe row buffers */
- if(y & 1) zbl= &zb1;
- else zbl= &zb2;
-
- /* Prepare iterators */
- ap = APixbufExt + (zBufferWidth * (y - Aminy));
- apteller = (zBufferWidth * (y - Aminy));
-
- /* Rendering: give the right colour to this pixel (shade it) */
- for( x = 0; x < R.rectx; x++, ap++, colbuf1+=4, colbuf2+=4, colbuf3+=4) {
- if(ap->t[0]) {
- /* reset sample collector */
- j = sampcol;
- for(i = 0; i < osaNr; i++, j+=4) {
- j[0] = 0.0f; j[1] = 0.0f;
- j[2] = 0.0f; j[3] = 0.0f;
- };
-
- /* a. count and sort number of faces */
- stackDepth = countAndSortPixelFaces( zbl->zrow, ap);
-
- /* b,c. oversample all subpixels, then integrate */
- osastack_ptr = 0;
- osastack_ptr = composeStack(zbl->zrow, collector, zbl->osastack, osastack_ptr,
- stackDepth, x, y, osaNr);
- integratePerSubStack(sampcol, zbl->osastack, osastack_ptr, x, y, osaNr);
-
- /* d. Gamma corrected blending and Gaussian */
- sampleFloatColV2FloatColVFilter(sampcol, colbuf1, colbuf2, colbuf3, osaNr);
-
- } else {
- /* Remember to do things back-to-front! */
-
- /* This is a bit dirty. Depending on sky-mode, the pixel is */
- /* blended in differently. */
- renderSkyPixelFloat(collector, x, y, NULL);
-
- j = sampcol;
- for(i = 0; i < osaNr; i++, j+=4) {
- j[0]= collector[0]; j[1]= collector[1];
- j[2]= collector[2]; j[3]= collector[3];
- }
-
- /* Spothalos are part of the normal pixelshader, so for covered */
- /* pixels they are handled ok. They are 'normally' alpha blended */
- /* onto the existing colour in the collector. */
- if(R.flag & R_LAMPHALO) {
- renderSpotHaloPixel(x, y, collector);
- if(do_gamma) {
- collector[0]= gammaCorrect(collector[0]);
- collector[1]= gammaCorrect(collector[1]);
- collector[2]= gammaCorrect(collector[2]);
- }
-
- j = sampcol;
- for(i = 0; i < osaNr; i++, j+=4) {
- addAlphaOverFloat(j, collector);
- }
- }
-
- sampleFloatColV2FloatColVFilter(sampcol, colbuf1, colbuf2, colbuf3, osaNr);
-
- }
- }
-}
-
-
-/**
- * Fills in distances of faces in the z buffer.
- *
- * Halo z buffering ----------------------------------------------
- *
- * A halo is treated here as a billboard: no z-extension, always
- * oriented perpendicular to the viewer. The rest of the z-buffer
- * stores face-numbers first, then calculates colours as the
- * final image is rendered. We'll use the same approach here,
- * which differs from the original method (which was add halos per
- * scan line). This means that the z-buffer now also needs to
- * store info about what sort of 'thing' the index refers to.
- *
- * Halo extension:
- * h.maxy ---------
- * | h.xs + h.rad
- * | h.xs
- * | h.xs - h.rad
- * h.miny ---------
- *
- * These coordinates must be clipped to picture size.
- * I'm not quite certain about halo numbering.
- *
- * Halos and jittering -------------------------------------------
- *
- * Halos were not jittered previously. Now they are. I wonder
- * whether this may have some adverse effects here.
-
- * @return 1 for succes, 0 if the operation was interrupted.
- */
-
-/* ------------------------------------------------------------------------- */
-/* Transparent faces and the 'Azvoordeel' */
-/* A transparent face can get a z-offset, which is a */
-/* way of pretending the face is a bit closer than it */
-/* actually is. This is used in animations, when faces */
-/* that are used to glue on animated characters, items, */
-/* et. need their shadows to be drawn on top of the */
-/* objects they stand on. The Azvoordeel is added to */
-/* the calculated z-coordinate in the buffer-fill */
-/* procedures. */
-
-/* static int RE_treat_face_as_opaque; */
-
-static int zBufferAllFaces(void)
-{
- VlakRen *vlr=NULL;
- unsigned int zvlnr;
- int faceCounter;
- int keepLooping = 1;
- float vec[3], hoco[4], mul, zval, fval;
- Material *ma=0;
-
- faceCounter = 0;
-
-/* printf("Going to buffer faces:\n"); */
-/* printf("\tfirst pass:\n"); */
-
-/* RE_treat_face_as_opaque = 1; */
-
- while ( (faceCounter < R.totvlak) && keepLooping) {
- if((faceCounter & 255)==0) { vlr= R.blovl[faceCounter>>8]; }
- else vlr++;
-
- ma= vlr->mat;
-
- /* VERY dangerous construction... zoffs is set by a slide in the ui */
- /* so it should be safe... */
- if((ma->mode & (MA_ZTRA)) && (ma->zoffs != 0.0)) {
- mul= 0x7FFFFFFF;
- zval= mul*(1.0+vlr->v1->ho[2]/vlr->v1->ho[3]);
-
- VECCOPY(vec, vlr->v1->co);
- /* z is negatief, wordt anders geclipt */
- vec[2]-= ma->zoffs;
- RE_projectverto(vec, hoco); /* vec onto hoco */
- fval= mul*(1.0+hoco[2]/hoco[3]);
-
- Azvoordeel= (int) fabs(zval - fval );
- } else {
- Azvoordeel= 0;
- }
- /* face number is used in the fill functions */
- zvlnr = faceCounter + 1;
-
- if(vlr->flag & R_VISIBLE) { /* might test for this sooner... */
-
- if(ma->mode & (MA_WIRE)) zbufclipwire(zvlnr, vlr);
- else {
- zbufclip(NULL, zvlnr, vlr->v1->ho, vlr->v2->ho, vlr->v3->ho,
- vlr->v1->clip, vlr->v2->clip, vlr->v3->clip);
- if(vlr->v4) {
- zvlnr+= 0x800000; /* in a sense, the 'adjoint' face */
- zbufclip(NULL, zvlnr, vlr->v1->ho, vlr->v3->ho, vlr->v4->ho,
- vlr->v1->clip, vlr->v3->clip, vlr->v4->clip);
- }
- }
- }
- if(RE_local_test_break()) keepLooping = 0;
- faceCounter++;
- }
-
- return keepLooping;
-}
-
-/**
- * Fills in distances of halos in the z buffer.
- * @return 1 for succes, 0 if the operation was interrupted.
- */
-
-/* ------------------------------------------------------------------------- */
-/* We cheat a little here: we only fill the halo on the first pass, and we */
-/* set a full complement of mask flags. This can be done because we consider */
-/* halos to be flat (billboards), so we do not have to correct the z range */
-/* every time we insert a halo. Also, halos fall off to zero at the edges, */
-/* so we can safely render them in pixels where they do not exist. */
-static int zBufferAllHalos(void)
-{
- HaloRen *har = NULL;
- int haloCounter = 0;
- int dist = 0;
- int keepLooping = 1;
- short miny = 0, maxy = 0, minx = 0, maxx = 0;
- short ycount = 0, xcount = 0;
- RE_APixstrExt *ap, *apoffset;
- int mask; /* jitter mask */
-
- if (!Zsample)
- {
- mask = (1 << osaNr) - 1 ; /* Fill all samples together */
-
- while ( (haloCounter < R.tothalo) && keepLooping) {
- if((haloCounter & 255)==0) har= R.bloha[haloCounter>>8];
- else har++;
-
- /* Halos are sometimes wrongly kicked out of the box they belong */
- /* in... */
-
- /* Only buffer the current alpha buffer contents!!! The line */
- /* indices have already been clipped to picture size. */
- minx = floor(har->xs - har->rad) - 1; /* assume min =< max is true*/
- if (minx < 0 ) minx = 0;
- maxx = ceil(har->xs + har->rad ) + 1;
- /* Do the extra -1 because of the +1 later on. I guess halos might */
- /* have to start one pixel sooner? Or maybe the lower clip should */
- /* be adjusted */
- if (maxx >= zBufferWidth - 1) maxx = zBufferWidth - 2;
-
- miny = har->miny;
- if (miny < Aminy) miny = Aminy;
- maxy = har->maxy;
- if (maxy > Amaxy) maxy = Amaxy;
-
- if ( (minx <= maxx) && (miny <= maxy)) {
- /* distance to this halo? */
- dist = har->zBufDist /* * R.ycor */;
- /* strange that the ycor influences the z coordinate ..*/
- ycount = miny;
- while (ycount <= maxy) {
- apoffset = APixbufExt + (zBufferWidth * (ycount - Aminy));
- ap = apoffset + minx;
- xcount = minx;
- while (xcount <= maxx) {
- insertFlatObjectNoOsa(ap, haloCounter, RE_HALO, dist, mask);
- xcount++;
- ap++;
- }
- ycount++;
- }
- }
- if(RE_local_test_break()) keepLooping = 0;
- haloCounter++;
- }
- }
-
- return keepLooping;
-}
-/* ------------------------------------------------------------------------- */
-
-/**
-* Fills in distances of all faces in a z buffer, for given jitter settings.
- */
-static int fillZBufDistances()
-{
- int keepLooping = 1;
-
- keepLooping = zBufferAllFaces(); /* Solid and transparent faces*/
- keepLooping = zBufferAllHalos() && keepLooping; /* ...and halos*/
- return keepLooping;
-
-}
-
-
-
-#if 0
-/* ------------------------------------------------------------------------- */
-/**
- * One more filler: fill in halo data in z buffer.
- * Empty so far, but may receive content of halo loop.
- */
-void zBufferFillHalo(void)
-{
- /* so far, intentionally empty */
-}
-#endif
-
-/* ------------------------------------------------------------------------- */
-/* Colour buffer related: */
-/* This transforms the 4 inputvalues RE_COLBUFTYPE to a new value */
-/* It expects the values R.r.postigamma, R.r.postmul and R.r.postadd. */
-/* This is the standard transformation, more elaborate tools are for later. */
-/* ------------------------------------------------------------------------- */
-void std_floatcol_to_charcol( float *buf, char *target)
-{
- float col[3];
-
- float dither_value;
-
- dither_value = ((BLI_frand()-0.5)*R.r.dither_intensity)/256.0;
-
- /* alpha */
- if((buf[3]+dither_value)<=0.0) target[3]= 0;
- else if((buf[3]+dither_value)>1.0) target[3]= 255;
- else target[3]= 255.0*(buf[3]+dither_value);
-
- if(R.r.postgamma==1.0) {
- /* r */
- col[0]= R.r.postmul*buf[0] + R.r.postadd + dither_value;
- /* g */
- col[1]= R.r.postmul*buf[1] + R.r.postadd + dither_value;
- /* b */
- col[2]= R.r.postmul*buf[2] + R.r.postadd + dither_value;
- }
- else {
- /* putting the postmul within the pow() gives an
- * easier control for the user, values from 1.0-2.0
- * are relevant then
- */
-
- /* r */
- col[0]= pow(R.r.postmul*buf[0], R.r.postigamma) + R.r.postadd + dither_value;
- /* g */
- col[1]= pow( R.r.postmul*buf[1], R.r.postigamma) + R.r.postadd + dither_value;
- /* b */
- col[2]= pow(R.r.postmul*buf[2], R.r.postigamma) + R.r.postadd + dither_value;
- }
-
- if(R.r.posthue!=0.0 || R.r.postsat!=1.0) {
- float hsv[3];
-
- rgb_to_hsv(col[0], col[1], col[2], hsv, hsv+1, hsv+2);
- hsv[0]+= R.r.posthue;
- if(hsv[0]>1.0) hsv[0]-=1.0; else if(hsv[0]<0.0) hsv[0]+= 1.0;
- hsv[1]*= R.r.postsat;
- if(hsv[1]>1.0) hsv[1]= 1.0; else if(hsv[1]<0.0) hsv[1]= 0.0;
- hsv_to_rgb(hsv[0], hsv[1], hsv[2], col, col+1, col+2);
- }
-
- if(col[0]<=0.0) target[0]= 0;
- else if(col[0]>1.0) target[0]= 255;
- else target[0]= 255.0*col[0];
-
- if(col[1]<=0.0) target[1]= 0;
- else if(col[1]>1.0) target[1]= 255;
- else target[1]= 255.0*col[1];
-
- if(col[2]<=0.0) target[2]= 0;
- else if(col[2]>1.0) target[2]= 255;
- else target[2]= 255.0*col[2];
-}
-
-/* ----------------------------------------------------------------------------
-
- Colour buffer related:
-
- The colour buffer is a buffer of a single screen line. It contains
- four fields of type RE_COLBUFTYPE per pixel.
-
- We can do several post-process steps. I would prefer to move them outside
- the render module later on, but it's ok to leave it here for now. For the
- time being, we have:
- - post-process function
- Does some operations with the colours.
- - Multiply with some factor
- - Add constant offset
- - Apply extra gamma correction (seems weird...)
- - key-alpha correction
- Key alpha means 'un-applying' the alpha. For fully covered pixels, this
- operation has no effect.
-
- - XXX WARNING! Added the inverse render gamma here, so this cannot be used external
- without setting Osa or Gamme flags off (ton)
-
----------------------------------------------------------------------------- */
-/* used external! */
-void transferColourBufferToOutput( float *buf, int y)
-{
- /* Copy the contents of AColourBuffer3 to R.rectot + y * R.rectx */
- int x = 0;
- char *target = (char*) (R.rectot + (y * R.rectx));
-
- /* Copy the first <R.rectx> pixels. We can do some more clipping on */
- /* the z buffer, I think. */
- while (x < R.rectx) {
-
-
- /* invert gamma corrected additions */
- if(do_gamma) {
- buf[0] = invGammaCorrect(buf[0]);
- buf[1] = invGammaCorrect(buf[1]);
- buf[2] = invGammaCorrect(buf[2]);
- }
-
- std_floatcol_to_charcol(buf, target);
-
- /*
- Key-alpha mode:
- Need to un-apply alpha if alpha is non-full. For full alpha,
- the operation doesn't have effect. Do this after the post-
- processing, so we can still use the benefits of that.
-
- */
-
- if (getSkyBlendingMode() == RE_ALPHA_KEY) {
- applyKeyAlphaCharCol(target);
- }
-
- target+=4;
- buf+=4;
- x++;
- }
-}
-
-/* used for redisplay after render. assumes size globals to be set OK! */
-void RE_floatbuffer_to_output(void)
-{
- float *buf= R.rectftot;
- int pix= R.rectx*R.recty;
- char *target = (char *)R.rectot;
-
- if(R.rectftot==NULL) return;
-
- while(pix--) {
- std_floatcol_to_charcol(buf, target);
- buf+= 4;
- target+= 4;
- }
-}
-
-/* ------------------------------------------------------------------------- */
-
-static void eraseColBuf(RE_COLBUFTYPE *buf)
-{
- /* By definition, the buffer's length is 4 * R.rectx items */
- int i = 0;
-
- while (i < 4 * (R.rectx+3)) {
- *buf = 0.0f;
- buf++; i++;
- }
-}
-
-/* ------------------------------------------------------------------------- */
-
-
-/**
- * Fill the accumulation buffer APixbufExt with face and halo indices.
- * Note: Uses globals.
- * @param y the line number to set
- */
-static void calcZBufLine(int y)
-{
- int part;
- int keepLooping = 1;
-
- if(y<0) return;
-
- /* zbuffer fix: here? */
- Zmulx= ((float) R.rectx)/2.0;
- Zmuly= ((float) R.recty)/2.0;
-
-
- /* use these buffer fill functions */
- zbuffunc = zBufferFillFace;
- zbuflinefunc = zBufferFillEdge;
-
- /* (FORALL y: Aminy =< y =< Amaxy: y is buffered) */
- if( (y < Aminy) || (y > Amaxy)) {
-
- /* prepare buffer */
- part = (y/RE_ZBUFLEN); /* These two lines are mystifying me... */
- Aminy = part * RE_ZBUFLEN; /* Possibly for rounding things? */
- Amaxy = Aminy + RE_ZBUFLEN - 1;
- /* if(Amaxy >= R.recty) Amaxy = R.recty-1; */
- if(Amaxy >= R.recty) Amaxy = R.recty - 1;
- resetZbuffer();
-
- Zsample = 0; /* Zsample is used internally ! */
- while ( (Zsample < osaNr) && keepLooping ) {
- /* Apply jitter to this pixel. The jitter offsets are globals. */
- /* They are added in zbufclip() */
- /* Negative: these offsets are added to the vertex coordinates */
- /* so it equals translating viewpoint over the positive vector. */
- Zjitx= -jit[Zsample][0]-0.5;
- Zjity= -jit[Zsample][1]-0.5;
-
- keepLooping = fillZBufDistances();
-
- if(RE_local_test_break()) keepLooping = 0;
- Zsample++;
- }
- }
-
-}
-
-
-/* ------------------------------------------------------------------------- */
-
-struct renderline {
- RE_COLBUFTYPE *buf1, *buf2, *buf3;
- int y;
-};
-
-static int do_renderline(void *poin)
-{
- struct renderline *rl= poin;
-
- renderZBufLine(rl->y, rl->buf1, rl->buf2, rl->buf3);
- return 1;
-}
-
-void zBufShadeAdvanced()
-{
- RE_COLBUFTYPE *cycle;
- struct renderline rl1, rl2;
- int y, keepLooping = 1;
- float xjit = 0.0, yjit = 0.0;
-
- Zjitx=Zjity= -0.5; /* jitter preset: -0.5 pixel */
-
- /* Set osaNr. Treat 'no osa' as 'osa = 1' */
- if(R.r.mode & R_OSA) {
- osaNr = R.osa;
- if(osaNr > 16) { /* check was moved from calcZBufLine */
- printf("zBufShadeAdvanced> osa too large (internal error)\n");
- G.afbreek= 1;
- return;
- }
- } else {
- /* little hack */
- osaNr = 1;
- xjit = jit[0][0];
- yjit = jit[0][1];
- jit[0][0] = 0.0;
- jit[0][1] = 0.0;
- }
-
- RE_setwindowclip(0, -1); /* just to be sure, reset the view matrix */
-
- initRenderBuffers(R.rectx);
-
- y = 0;
- while ( (y < R.recty) && keepLooping) {
-
- calcZBufLine(y);
-
- rl1.buf1= AColourBuffer1;
- rl1.buf2= AColourBuffer2;
- rl1.buf3= AColourBuffer3;
- rl1.y= y;
-
- if(R.r.mode & R_THREADS) {
- if((y & 1)==0) {
- SDL_Thread *thread;
-
- thread = SDL_CreateThread(do_renderline, &rl1);
- if ( thread == NULL ) {
- fprintf(stderr, "Unable to create thread");
- G.afbreek= 1;
- break;
- }
-
- rl2.buf1= AColourBuffer0;
- rl2.buf2= AColourBuffer1a;
- rl2.buf3= AColourBuffer2a;
- rl2.y= y+1;
-
- do_renderline(&rl2);
-
- SDL_WaitThread(thread, NULL);
-
- if(R.r.filtertype) {
- float *rb1= AColourBuffer1, *rb2= AColourBuffer2, *rb1a= AColourBuffer1a, *rb2a= AColourBuffer2a;
- int a= 4*(R.rectx + 4);
- while(a--) {
- *rb1 += *rb1a;
- *rb2 += *rb2a;
- *(rb1a++)= 0.0; rb1++;
- *(rb2a++)= 0.0; rb2++;
- }
- }
- else {
- cycle= AColourBuffer1a; AColourBuffer1a= AColourBuffer1; AColourBuffer1= cycle;
- }
- }
- }
- else do_renderline(&rl1);
-
- if(y) {
- transferColourBufferToOutput(AColourBuffer3+4, y-1);
-
- if((y & 1)==0) RE_local_render_display(y-2, y-1, R.rectx, R.recty, R.rectot);
- }
-
- /* buffer cycling */
- eraseColBuf(AColourBuffer3);
- cycle= AColourBuffer3;
- AColourBuffer3= AColourBuffer2;
- AColourBuffer2= AColourBuffer1;
- AColourBuffer1= AColourBuffer0;
- AColourBuffer0= cycle;
-
- if(RE_local_test_break()) keepLooping = 0;
- y++;
- }
- if(keepLooping) transferColourBufferToOutput(AColourBuffer3+4, y-1);
-
- freeRenderBuffers();
-
- /* Edge rendering is done purely as a post-effect */
- if(R.r.mode & R_EDGE) {
- addEdges((char*)R.rectot, R.rectx, R.recty,
- osaNr,
- R.r.edgeint, R.r.same_mat_redux,
- G.compat, G.notonlysolid,
- R.r.edgeR, R.r.edgeG, R.r.edgeB);
- }
-
- if (!(R.r.mode & R_OSA)) {
- jit[0][0] = xjit;
- jit[0][1] = yjit;
- }
-
-}
-
-/* ------------------------------------------------------------------------- */
-
-
-
-
-/* eof vanillaRenderPipe.c */
diff --git a/source/blender/render/intern/source/zblur.c b/source/blender/render/intern/source/zblur.c
deleted file mode 100644
index a1e8304ba75..00000000000
--- a/source/blender/render/intern/source/zblur.c
+++ /dev/null
@@ -1,818 +0,0 @@
-/**
- * $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 "zblur.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(unsigned 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, unsigned 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 = (float)pow(*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();
-}
-
-
diff --git a/source/blender/render/intern/source/zbuf.c b/source/blender/render/intern/source/zbuf.c
index 368acfe1a41..7790a4cff65 100644
--- a/source/blender/render/intern/source/zbuf.c
+++ b/source/blender/render/intern/source/zbuf.c
@@ -1,15 +1,12 @@
/**
* $Id$
*
- * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
+ * ***** BEGIN GPL 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.
+ * of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
@@ -23,21 +20,24 @@
* The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
* All rights reserved.
*
- * The Original Code is: all of this file.
+ * Contributors: Hos, RPW
+ * 2004-2006 Blender Foundation, full recode
*
- * Contributor(s): Hos, RPW.
- *
- * ***** END GPL/BL DUAL LICENSE BLOCK *****
+ * ***** END GPL LICENSE BLOCK *****
*/
+
/*---------------------------------------------------------------------------*/
/* Common includes */
/*---------------------------------------------------------------------------*/
#include <math.h>
+#include <float.h>
#include <stdlib.h>
#include <limits.h>
#include <string.h>
+
+#include "BLI_blenlib.h"
#include "MTC_matrixops.h"
#include "MEM_guardedalloc.h"
@@ -49,75 +49,57 @@
#include "BKE_utildefines.h"
#include "radio_types.h"
-#include "radio.h" /* needs RG, some root data for radiosity */
+#include "radio.h" /* needs RG, some root data for radiosity */
#include "SDL_thread.h"
-#include "render.h"
-#include "RE_callbacks.h"
+#include "RE_render_ext.h"
/* local includes */
-#include "rendercore.h" /* shade_pixel and count_mask */
+#include "render_types.h"
+#include "renderpipeline.h"
+#include "renderdatabase.h"
+#include "rendercore.h"
#include "pixelblending.h"
-#include "jitter.h"
/* own includes */
#include "zbuf.h"
-#define FLT_EPSILON 1.19209290e-07F
+/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
+/* defined in pipeline.c, is hardcopy of active dynamic allocated Render */
+/* only to be used here in this file, it's for speed */
+extern struct Render R;
+/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
-/*-----------------------------------------------------------*/
-/* Globals for this file */
-/* main reason for globals; unified zbuffunc() with simple args */
-/*-----------------------------------------------------------*/
-
-float Zmulx; /* Half the screenwidth, in pixels. (used in render.c, */
- /* zbuf.c) */
-float Zmuly; /* Half the screenheight, in pixels. (used in render.c,*/
- /* zbuf.c) */
-float Zjitx; /* Jitter offset in x. When jitter is disabled, this */
- /* should be 0.5. (used in render.c, zbuf.c) */
-float Zjity; /* Jitter offset in y. When jitter is disabled, this */
- /* should be 0.5. (used in render.c, zbuf.c) */
-
-int Zsample;
-void (*zbuffunc)(ZSpan *, int, float *, float *, float *);
-void (*zbuffunc4)(ZSpan *, int, float *, float *, float *, float *);
-void (*zbuflinefunc)(int, float *, float *);
-
-static APixstr *APixbuf; /* Zbuffer: linked list of face indices */
-static int *Arectz; /* Zbuffer: distance buffer, almost obsolete */
-static int Aminy; /* y value of first line in the accu buffer */
-static int Amaxy; /* y value of last line in the accu buffer */
-static int Azvoordeel = 0;
-static APixstrMain apsmfirst;
-static short apsmteller = 0;
/* ****************** Spans ******************************* */
-static void zbuf_alloc_span(ZSpan *zspan, int yres)
+/* each zbuffer has coordinates transformed to local rect coordinates, so we can simply clip */
+void zbuf_alloc_span(ZSpan *zspan, int rectx, int recty)
{
- zspan->yres= yres;
+ memset(zspan, 0, sizeof(ZSpan));
+
+ zspan->rectx= rectx;
+ zspan->recty= recty;
- zspan->span1= MEM_callocN(yres*sizeof(float), "zspan");
- zspan->span2= MEM_callocN(yres*sizeof(float), "zspan");
+ zspan->span1= RE_mallocN(recty*sizeof(float), "zspan");
+ zspan->span2= RE_mallocN(recty*sizeof(float), "zspan");
}
static void zbuf_free_span(ZSpan *zspan)
{
if(zspan) {
- if(zspan->span1) MEM_freeN(zspan->span1);
- if(zspan->span2) MEM_freeN(zspan->span2);
+ if(zspan->span1) RE_freeN(zspan->span1);
+ if(zspan->span2) RE_freeN(zspan->span2);
zspan->span1= zspan->span2= NULL;
}
}
-static void zbuf_init_span(ZSpan *zspan, int miny, int maxy)
+/* reset range for clipping */
+static void zbuf_init_span(ZSpan *zspan)
{
- zspan->miny= miny; /* range for clipping */
- zspan->maxy= maxy;
- zspan->miny1= zspan->miny2= maxy+1;
- zspan->maxy1= zspan->maxy2= miny-1;
+ zspan->miny1= zspan->miny2= zspan->recty+1;
+ zspan->maxy1= zspan->maxy2= -1;
zspan->minp1= zspan->maxp1= zspan->minp2= zspan->maxp2= NULL;
}
@@ -137,12 +119,12 @@ static void zbuf_add_to_span(ZSpan *zspan, float *v1, float *v2)
my0= ceil(minv[1]);
my2= floor(maxv[1]);
- if(my2<zspan->miny || my0> zspan->maxy) return;
+ if(my2<0 || my0>= zspan->recty) return;
/* clip top */
- if(my2>=zspan->maxy) my2= zspan->maxy-1;
+ if(my2>=zspan->recty) my2= zspan->recty-1;
/* clip bottom */
- if(my0<zspan->miny) my0= zspan->miny;
+ if(my0<0) my0= 0;
if(my0>my2) return;
/* if(my0>my2) should still fill in, that way we get spans that skip nicely */
@@ -217,16 +199,7 @@ void fillrect(int *rect, int x, int y, int val)
}
}
-/**
-* Tests whether this coordinate is 'inside' or 'outside' of the view
- * volume? By definition, this is in [0, 1].
- * @param p vertex z difference plus coordinate difference?
- * @param q origin z plus r minus some coordinate?
- * @param u1 [in/out] clip fraction for ?
- * @param u2 [in/out]
- * @return 0 if point is outside, or 1 if the point lies on the clip
- * boundary
- */
+/* based on Liang&Barsky, for clipping of pyramidical volume */
static short cliptestf(float p, float q, float *u1, float *u2)
{
float r;
@@ -253,7 +226,7 @@ static short cliptestf(float p, float q, float *u1, float *u2)
return 1;
}
-int RE_testclip(float *v)
+int testclip(float *v)
{
float abs4; /* WATCH IT: this function should do the same as cliptestf, otherwise troubles in zbufclip()*/
short c=0;
@@ -278,315 +251,42 @@ int RE_testclip(float *v)
/* ************* ACCUMULATION ZBUF ************ */
-/*-APixstr---------------------(antialised pixel struct)------------------------------*/
-static APixstr *addpsmainA()
+static APixstr *addpsmainA(ListBase *lb)
{
APixstrMain *psm;
- psm= &apsmfirst;
-
- while(psm->next) {
- psm= psm->next;
- }
-
- psm->next= MEM_mallocN(sizeof(APixstrMain), "addpsmainA");
-
- psm= psm->next;
- psm->next=0;
- psm->ps= MEM_callocN(4096*sizeof(APixstr),"pixstr");
- apsmteller= 0;
+ psm= RE_mallocN(sizeof(APixstrMain), "addpsmainA");
+ BLI_addtail(lb, psm);
+ psm->ps= RE_mallocN(4096*sizeof(APixstr),"pixstr");
return psm->ps;
}
-static void freepsA()
+static void freepsA(ListBase *lb)
{
- APixstrMain *psm, *next;
-
- psm= &apsmfirst;
+ APixstrMain *psm, *psmnext;
- while(psm) {
- next= psm->next;
- if(psm->ps) {
- MEM_freeN(psm->ps);
- psm->ps= 0;
- }
- if(psm!= &apsmfirst) MEM_freeN(psm);
- psm= next;
+ for(psm= lb->first; psm; psm= psmnext) {
+ psmnext= psm->next;
+ if(psm->ps)
+ RE_freeN(psm->ps);
+ RE_freeN(psm);
}
-
- apsmfirst.next= 0;
- apsmfirst.ps= 0;
- apsmteller= 0;
-}
-
-static APixstr *addpsA(void)
-{
- static APixstr *prev;
-
- /* make first PS */
- if((apsmteller & 4095)==0) prev= addpsmainA();
- else prev++;
- apsmteller++;
-
- return prev;
}
-/**
- * Fill the z buffer for accumulation (transparency)
- *
- * This is one of the z buffer fill functions called in zbufclip() and
- * zbufwireclip().
- *
- * @param v1 [4 floats, world coordinates] first vertex
- * @param v2 [4 floats, world coordinates] second vertex
- * @param v3 [4 floats, world coordinates] third vertex
- */
-static void zbufinvulAc(ZSpan *zspan, int zvlnr, float *v1, float *v2, float *v3)
+static APixstr *addpsA(ZSpan *zspan)
{
- APixstr *ap, *apofs, *apn;
- double x0,y0,z0,x1,y1,z1,x2,y2,z2,xx1;
- double zxd,zyd,zy0, tmp;
- float *minv,*maxv,*midv;
- int *rz,zverg,x;
- int my0,my2,sn1,sn2,rectx,zd,*rectzofs;
- int y,omsl,xs0,xs1,xs2,xs3, dx0,dx1,dx2, mask;
-
- /* MIN MAX */
- if(v1[1]<v2[1]) {
- if(v2[1]<v3[1]) {
- minv=v1; midv=v2; maxv=v3;
- }
- else if(v1[1]<v3[1]) {
- minv=v1; midv=v3; maxv=v2;
- }
- else {
- minv=v3; midv=v1; maxv=v2;
- }
- }
- else {
- if(v1[1]<v3[1]) {
- minv=v2; midv=v1; maxv=v3;
- }
- else if(v2[1]<v3[1]) {
- minv=v2; midv=v3; maxv=v1;
- }
- else {
- minv=v3; midv=v2; maxv=v1;
- }
- }
-
- if(minv[1] == maxv[1]) return; /* prevent 'zero' size faces */
-
- my0= ceil(minv[1]);
- my2= floor(maxv[1]);
- omsl= floor(midv[1]);
-
- if(my2<Aminy || my0> Amaxy) return;
-
- if(my0<Aminy) my0= Aminy;
-
- /* EDGES : LONGEST */
- xx1= maxv[1]-minv[1];
- if(xx1>2.0/65536.0) {
- z0= (maxv[0]-minv[0])/xx1;
-
- tmp= (-65536.0*z0);
- dx0= CLAMPIS(tmp, INT_MIN, INT_MAX);
-
- tmp= 65536.0*(z0*(my2-minv[1])+minv[0]);
- xs0= CLAMPIS(tmp, INT_MIN, INT_MAX);
- }
- else {
- dx0= 0;
- xs0= 65536.0*(MIN2(minv[0],maxv[0]));
- }
- /* EDGES : THE TOP ONE */
- xx1= maxv[1]-midv[1];
- if(xx1>2.0/65536.0) {
- z0= (maxv[0]-midv[0])/xx1;
-
- tmp= (-65536.0*z0);
- dx1= CLAMPIS(tmp, INT_MIN, INT_MAX);
-
- tmp= 65536.0*(z0*(my2-midv[1])+midv[0]);
- xs1= CLAMPIS(tmp, INT_MIN, INT_MAX);
+ /* make new PS */
+ if(zspan->apsmcounter==0) {
+ zspan->curpstr= addpsmainA(zspan->apsmbase);
+ zspan->apsmcounter= 4095;
}
else {
- dx1= 0;
- xs1= 65536.0*(MIN2(midv[0],maxv[0]));
- }
- /* EDGES : BOTTOM ONE */
- xx1= midv[1]-minv[1];
- if(xx1>2.0/65536.0) {
- z0= (midv[0]-minv[0])/xx1;
-
- tmp= (-65536.0*z0);
- dx2= CLAMPIS(tmp, INT_MIN, INT_MAX);
-
- tmp= 65536.0*(z0*(omsl-minv[1])+minv[0]);
- xs2= CLAMPIS(tmp, INT_MIN, INT_MAX);
- }
- else {
- dx2= 0;
- xs2= 65536.0*(MIN2(minv[0],midv[0]));
- }
-
- /* ZBUF DX DY */
- x1= v1[0]- v2[0];
- x2= v2[0]- v3[0];
- y1= v1[1]- v2[1];
- y2= v2[1]- v3[1];
- z1= v1[2]- v2[2];
- z2= v2[2]- v3[2];
- x0= y1*z2-z1*y2;
- y0= z1*x2-x1*z2;
- z0= x1*y2-y1*x2;
- if(z0==0.0) return;
-
- if(midv[1]==maxv[1]) omsl= my2;
- if(omsl<Aminy) omsl= Aminy-1; /* to make sure it does the first loop completely */
-
- while (my2 > Amaxy) { /* my2 can be larger */
- xs0+=dx0;
- if (my2<=omsl) {
- xs2+= dx2;
- }
- else{
- xs1+= dx1;
- }
- my2--;
- }
-
- xx1= (x0*v1[0]+y0*v1[1])/z0+v1[2];
-
- zxd= -x0/z0;
- zyd= -y0/z0;
- zy0= my2*zyd+xx1;
- zd= (int)CLAMPIS(zxd, INT_MIN, INT_MAX);
-
- /* start-offset in rect */
- rectx= R.rectx;
- rectzofs= (int *)(Arectz+rectx*(my2-Aminy));
- apofs= (APixbuf+ rectx*(my2-Aminy));
- mask= 1<<Zsample;
-
- xs3= 0; /* flag */
- if(dx0>dx1) {
- xs3= xs0;
- xs0= xs1;
- xs1= xs3;
- xs3= dx0;
- dx0= dx1;
- dx1= xs3;
- xs3= 1; /* flag */
-
- }
-
- for(y=my2;y>omsl;y--) {
-
- sn1= xs0>>16;
- xs0+= dx0;
-
- sn2= xs1>>16;
- xs1+= dx1;
-
- sn1++;
-
- if(sn2>=rectx) sn2= rectx-1;
- if(sn1<0) sn1= 0;
- zverg= (int) CLAMPIS((sn1*zxd+zy0), INT_MIN, INT_MAX);
- rz= rectzofs+sn1;
- ap= apofs+sn1;
- x= sn2-sn1;
-
- zverg-= Azvoordeel;
-
- while(x>=0) {
- if(zverg< *rz) {
- apn= ap;
- while(apn) { /* loop unrolled */
- if(apn->p[0]==0) {apn->p[0]= zvlnr; apn->z[0]= zverg; apn->mask[0]= mask; break; }
- if(apn->p[0]==zvlnr) {apn->mask[0]|= mask; break; }
- if(apn->p[1]==0) {apn->p[1]= zvlnr; apn->z[1]= zverg; apn->mask[1]= mask; break; }
- if(apn->p[1]==zvlnr) {apn->mask[1]|= mask; break; }
- if(apn->p[2]==0) {apn->p[2]= zvlnr; apn->z[2]= zverg; apn->mask[2]= mask; break; }
- if(apn->p[2]==zvlnr) {apn->mask[2]|= mask; break; }
- if(apn->p[3]==0) {apn->p[3]= zvlnr; apn->z[3]= zverg; apn->mask[3]= mask; break; }
- if(apn->p[3]==zvlnr) {apn->mask[3]|= mask; break; }
- if(apn->next==0) apn->next= addpsA();
- apn= apn->next;
- }
- }
- zverg+= zd;
- rz++;
- ap++;
- x--;
- }
- zy0-= zyd;
- rectzofs-= rectx;
- apofs-= rectx;
- }
-
- if(xs3) {
- xs0= xs1;
- dx0= dx1;
- }
- if(xs0>xs2) {
- xs3= xs0;
- xs0= xs2;
- xs2= xs3;
- xs3= dx0;
- dx0= dx2;
- dx2= xs3;
- }
-
- for(; y>=my0; y--) {
-
- sn1= xs0>>16;
- xs0+= dx0;
-
- sn2= xs2>>16;
- xs2+= dx2;
-
- sn1++;
-
- if(sn2>=rectx) sn2= rectx-1;
- if(sn1<0) sn1= 0;
- zverg= (int) CLAMPIS((sn1*zxd+zy0), INT_MIN, INT_MAX);
- rz= rectzofs+sn1;
- ap= apofs+sn1;
- x= sn2-sn1;
-
- zverg-= Azvoordeel;
-
- while(x>=0) {
- if(zverg< *rz) {
- apn= ap;
- while(apn) { /* loop unrolled */
- if(apn->p[0]==0) {apn->p[0]= zvlnr; apn->z[0]= zverg; apn->mask[0]= mask; break; }
- if(apn->p[0]==zvlnr) {apn->mask[0]|= mask; break; }
- if(apn->p[1]==0) {apn->p[1]= zvlnr; apn->z[1]= zverg; apn->mask[1]= mask; break; }
- if(apn->p[1]==zvlnr) {apn->mask[1]|= mask; break; }
- if(apn->p[2]==0) {apn->p[2]= zvlnr; apn->z[2]= zverg; apn->mask[2]= mask; break; }
- if(apn->p[2]==zvlnr) {apn->mask[2]|= mask; break; }
- if(apn->p[3]==0) {apn->p[3]= zvlnr; apn->z[3]= zverg; apn->mask[3]= mask; break; }
- if(apn->p[3]==zvlnr) {apn->mask[3]|= mask; break; }
- if(apn->next==0) apn->next= addpsA();
- apn= apn->next;
- }
- }
- zverg+= zd;
- rz++;
- ap++;
- x--;
- }
-
- zy0-=zyd;
- rectzofs-= rectx;
- apofs-= rectx;
+ zspan->curpstr++;
+ zspan->apsmcounter--;
}
+ return zspan->curpstr;
}
static void zbufinvulAc4(ZSpan *zspan, int zvlnr, float *v1, float *v2, float *v3, float *v4)
@@ -600,13 +300,17 @@ static void zbufinvulAc4(ZSpan *zspan, int zvlnr, float *v1, float *v2, float *v
int sn1, sn2, rectx, *rectzofs, my0, my2, mask;
/* init */
- zbuf_init_span(zspan, Aminy, Amaxy+1);
+ zbuf_init_span(zspan);
/* set spans */
zbuf_add_to_span(zspan, v1, v2);
zbuf_add_to_span(zspan, v2, v3);
- zbuf_add_to_span(zspan, v3, v4);
- zbuf_add_to_span(zspan, v4, v1);
+ if(v4) {
+ zbuf_add_to_span(zspan, v3, v4);
+ zbuf_add_to_span(zspan, v4, v1);
+ }
+ else
+ zbuf_add_to_span(zspan, v3, v1);
/* clipped */
if(zspan->minp2==NULL || zspan->maxp2==NULL) return;
@@ -636,11 +340,11 @@ static void zbufinvulAc4(ZSpan *zspan, int zvlnr, float *v1, float *v2, float *v
zy0= ((double)my2)*zyd + (double)xx1;
/* start-offset in rect */
- rectx= R.rectx;
- rectzofs= (int *)(Arectz+rectx*(my2-Aminy));
- apofs= (APixbuf+ rectx*(my2-Aminy));
- mask= 1<<Zsample;
-
+ rectx= zspan->rectx;
+ rectzofs= (int *)(zspan->arectz+rectx*(my2));
+ apofs= (zspan->apixbuf+ rectx*(my2));
+ mask= zspan->mask;
+
/* correct span */
sn1= (my0 + my2)/2;
if(zspan->span1[sn1] < zspan->span2[sn1]) {
@@ -667,7 +371,7 @@ static void zbufinvulAc4(ZSpan *zspan, int zvlnr, float *v1, float *v2, float *v
ap= apofs+sn1;
x= sn2-sn1;
- zverg-= Azvoordeel;
+ zverg-= zspan->polygon_offset;
while(x>=0) {
if( (int)zverg < *rz) {
@@ -685,7 +389,7 @@ static void zbufinvulAc4(ZSpan *zspan, int zvlnr, float *v1, float *v2, float *v
if(apn->p[3]==zvlnr) {apn->mask[3]|= mask; break; }
// if(apn->p[i]==0) {apn->p[i]= zvlnr; apn->z[i]= zverg; apn->mask[i]= mask; break; }
// if(apn->p[i]==zvlnr) {apn->mask[i]|= mask; break; }
- if(apn->next==NULL) apn->next= addpsA();
+ if(apn->next==NULL) apn->next= addpsA(zspan);
apn= apn->next;
}
}
@@ -704,7 +408,7 @@ static void zbufinvulAc4(ZSpan *zspan, int zvlnr, float *v1, float *v2, float *v
-static void zbuflineAc(int zvlnr, float *vec1, float *vec2)
+static void zbuflineAc(ZSpan *zspan, int zvlnr, float *vec1, float *vec2)
{
APixstr *ap, *apn;
int *rectz;
@@ -716,6 +420,8 @@ static void zbuflineAc(int zvlnr, float *vec1, float *vec2)
dx= vec2[0]-vec1[0];
dy= vec2[1]-vec1[1];
+ mask= zspan->mask;
+
if(fabs(dx) > fabs(dy)) {
/* all lines from left to right */
@@ -731,22 +437,21 @@ static void zbuflineAc(int zvlnr, float *vec1, float *vec2)
start= floor(v1[0]);
end= start+floor(dx);
- if(end>=R.rectx) end= R.rectx-1;
+ if(end>=zspan->rectx) end= zspan->rectx-1;
oldy= floor(v1[1]);
dy/= dx;
vergz= v1[2];
- vergz-= Azvoordeel;
+ vergz-= zspan->polygon_offset;
dz= (v2[2]-v1[2])/dx;
if(vergz>0x50000000 && dz>0) maxtest= 1; // prevent overflow
- rectz= (int *)(Arectz+R.rectx*(oldy-Aminy) +start);
- ap= (APixbuf+ R.rectx*(oldy-Aminy) +start);
- mask= 1<<Zsample;
-
- if(dy<0) ofs= -R.rectx;
- else ofs= R.rectx;
+ rectz= (int *)(zspan->arectz+zspan->rectx*(oldy) +start);
+ ap= (zspan->apixbuf+ zspan->rectx*(oldy) +start);
+
+ if(dy<0) ofs= -zspan->rectx;
+ else ofs= zspan->rectx;
for(x= start; x<=end; x++, rectz++, ap++) {
@@ -757,7 +462,7 @@ static void zbuflineAc(int zvlnr, float *vec1, float *vec2)
ap+= ofs;
}
- if(x>=0 && y>=Aminy && y<=Amaxy) {
+ if(x>=0 && y>=0 && y<zspan->recty) {
if(vergz<*rectz) {
apn= ap;
@@ -770,7 +475,7 @@ static void zbuflineAc(int zvlnr, float *vec1, float *vec2)
if(apn->p[2]==zvlnr) {apn->mask[2]|= mask; break; }
if(apn->p[3]==0) {apn->p[3]= zvlnr; apn->z[3]= vergz; apn->mask[3]= mask; break; }
if(apn->p[3]==zvlnr) {apn->mask[3]|= mask; break; }
- if(apn->next==0) apn->next= addpsA();
+ if(apn->next==0) apn->next= addpsA(zspan);
apn= apn->next;
}
@@ -798,26 +503,25 @@ static void zbuflineAc(int zvlnr, float *vec1, float *vec2)
start= floor(v1[1]);
end= start+floor(dy);
- if(start>Amaxy || end<Aminy) return;
+ if(start>=zspan->recty || end<0) return;
- if(end>Amaxy) end= Amaxy;
+ if(end>=zspan->recty) end= zspan->recty-1;
oldx= floor(v1[0]);
dx/= dy;
vergz= v1[2];
- vergz-= Azvoordeel;
+ vergz-= zspan->polygon_offset;
dz= (v2[2]-v1[2])/dy;
if(vergz>0x50000000 && dz>0) maxtest= 1; // prevent overflow
- rectz= (int *)( Arectz+ (start-Aminy)*R.rectx+ oldx );
- ap= (APixbuf+ R.rectx*(start-Aminy) +oldx);
- mask= 1<<Zsample;
+ rectz= (int *)( zspan->arectz+ (start)*zspan->rectx+ oldx );
+ ap= (zspan->apixbuf+ zspan->rectx*(start) +oldx);
if(dx<0) ofs= -1;
else ofs= 1;
- for(y= start; y<=end; y++, rectz+=R.rectx, ap+=R.rectx) {
+ for(y= start; y<=end; y++, rectz+=zspan->rectx, ap+=zspan->rectx) {
x= floor(v1[0]);
if(x!=oldx) {
@@ -826,7 +530,7 @@ static void zbuflineAc(int zvlnr, float *vec1, float *vec2)
ap+= ofs;
}
- if(x>=0 && y>=Aminy && x<R.rectx) {
+ if(x>=0 && y>=0 && x<zspan->rectx) {
if(vergz<*rectz) {
apn= ap;
@@ -839,7 +543,7 @@ static void zbuflineAc(int zvlnr, float *vec1, float *vec2)
if(apn->p[2]==zvlnr) {apn->mask[2]|= mask; break; }
if(apn->p[3]==0) {apn->p[3]= zvlnr; apn->z[3]= vergz; apn->mask[3]= mask; break; }
if(apn->p[3]==zvlnr) {apn->mask[3]|= mask; break; }
- if(apn->next==0) apn->next= addpsA();
+ if(apn->next==0) apn->next= addpsA(zspan);
apn= apn->next;
}
@@ -853,30 +557,9 @@ static void zbuflineAc(int zvlnr, float *vec1, float *vec2)
}
}
-
-
/* ************* NORMAL ZBUFFER ************ */
-/**
- * Convert a homogenous coordinate to a z buffer coordinate. The
- * function makes use of Zmulx, Zmuly, the x and y scale factors for
- * the screen, and Zjitx, Zjity, the pixel offset. (These are declared
- * in render.c) The normalised z coordinate must fall on [0, 1].
- * @param zco [3, 4 floats] pointer to the resulting z buffer coordinate
- * @param hoco [4 floats] pointer to the homogenous coordinate of the
- * vertex in world space.
- */
-static void hoco_to_zco(float *zco, float *hoco)
-{
- float deler;
-
- deler= hoco[3];
- zco[0]= Zmulx*(1.0+hoco[0]/deler)+ Zjitx;
- zco[1]= Zmuly*(1.0+hoco[1]/deler)+ Zjity;
- zco[2]= 0x7FFFFFFF *(hoco[2]/deler);
-}
-
-static void zbufline(int zvlnr, float *vec1, float *vec2)
+static void zbufline(ZSpan *zspan, int zvlnr, float *vec1, float *vec2)
{
int *rectz, *rectp;
int start, end, x, y, oldx, oldy, ofs;
@@ -902,7 +585,7 @@ static void zbufline(int zvlnr, float *vec1, float *vec2)
start= floor(v1[0]);
end= start+floor(dx);
- if(end>=R.rectx) end= R.rectx-1;
+ if(end>=zspan->rectx) end= zspan->rectx-1;
oldy= floor(v1[1]);
dy/= dx;
@@ -911,11 +594,11 @@ static void zbufline(int zvlnr, float *vec1, float *vec2)
dz= floor((v2[2]-v1[2])/dx);
if(vergz>0x50000000 && dz>0) maxtest= 1; // prevent overflow
- rectz= R.rectz+ oldy*R.rectx+ start;
- rectp= R.rectot+ oldy*R.rectx+ start;
+ rectz= zspan->rectz + oldy*zspan->rectx+ start;
+ rectp= zspan->rectp + oldy*zspan->rectx+ start;
- if(dy<0) ofs= -R.rectx;
- else ofs= R.rectx;
+ if(dy<0) ofs= -zspan->rectx;
+ else ofs= zspan->rectx;
for(x= start; x<=end; x++, rectz++, rectp++) {
@@ -926,7 +609,7 @@ static void zbufline(int zvlnr, float *vec1, float *vec2)
rectp+= ofs;
}
- if(x>=0 && y>=0 && y<R.recty) {
+ if(x>=0 && y>=0 && y<zspan->recty) {
if(vergz<*rectz) {
*rectz= vergz;
*rectp= zvlnr;
@@ -954,7 +637,7 @@ static void zbufline(int zvlnr, float *vec1, float *vec2)
start= floor(v1[1]);
end= start+floor(dy);
- if(end>=R.recty) end= R.recty-1;
+ if(end>=zspan->recty) end= zspan->recty-1;
oldx= floor(v1[0]);
dx/= dy;
@@ -963,13 +646,13 @@ static void zbufline(int zvlnr, float *vec1, float *vec2)
dz= floor((v2[2]-v1[2])/dy);
if(vergz>0x50000000 && dz>0) maxtest= 1; // prevent overflow
- rectz= R.rectz+ start*R.rectx+ oldx;
- rectp= R.rectot+ start*R.rectx+ oldx;
+ rectz= zspan->rectz + start*zspan->rectx+ oldx;
+ rectp= zspan->rectp + start*zspan->rectx+ oldx;
if(dx<0) ofs= -1;
else ofs= 1;
- for(y= start; y<=end; y++, rectz+=R.rectx, rectp+=R.rectx) {
+ for(y= start; y<=end; y++, rectz+=zspan->rectx, rectp+=zspan->rectx) {
x= floor(v1[0]);
if(x!=oldx) {
@@ -978,7 +661,7 @@ static void zbufline(int zvlnr, float *vec1, float *vec2)
rectp+= ofs;
}
- if(x>=0 && y>=0 && x<R.rectx) {
+ if(x>=0 && y>=0 && x<zspan->rectx) {
if(vergz<*rectz) {
*rectz= vergz;
*rectp= zvlnr;
@@ -992,7 +675,7 @@ static void zbufline(int zvlnr, float *vec1, float *vec2)
}
}
-static void zbufline_onlyZ(int zvlnr, float *vec1, float *vec2)
+static void zbufline_onlyZ(ZSpan *zspan, int zvlnr, float *vec1, float *vec2)
{
int *rectz;
int start, end, x, y, oldx, oldy, ofs;
@@ -1018,7 +701,7 @@ static void zbufline_onlyZ(int zvlnr, float *vec1, float *vec2)
start= floor(v1[0]);
end= start+floor(dx);
- if(end>=R.rectx) end= R.rectx-1;
+ if(end>=zspan->rectx) end= zspan->rectx-1;
oldy= floor(v1[1]);
dy/= dx;
@@ -1027,10 +710,10 @@ static void zbufline_onlyZ(int zvlnr, float *vec1, float *vec2)
dz= floor((v2[2]-v1[2])/dx);
if(vergz>0x50000000 && dz>0) maxtest= 1; // prevent overflow
- rectz= R.rectz+ oldy*R.rectx+ start;
+ rectz= zspan->rectz + oldy*zspan->rectx+ start;
- if(dy<0) ofs= -R.rectx;
- else ofs= R.rectx;
+ if(dy<0) ofs= -zspan->rectx;
+ else ofs= zspan->rectx;
for(x= start; x<=end; x++, rectz++) {
@@ -1040,7 +723,7 @@ static void zbufline_onlyZ(int zvlnr, float *vec1, float *vec2)
rectz+= ofs;
}
- if(x>=0 && y>=0 && y<R.recty) {
+ if(x>=0 && y>=0 && y<zspan->recty) {
if(vergz<*rectz) {
*rectz= vergz;
}
@@ -1067,7 +750,7 @@ static void zbufline_onlyZ(int zvlnr, float *vec1, float *vec2)
start= floor(v1[1]);
end= start+floor(dy);
- if(end>=R.recty) end= R.recty-1;
+ if(end>=zspan->recty) end= zspan->recty-1;
oldx= floor(v1[0]);
dx/= dy;
@@ -1076,12 +759,12 @@ static void zbufline_onlyZ(int zvlnr, float *vec1, float *vec2)
dz= floor((v2[2]-v1[2])/dy);
if(vergz>0x50000000 && dz>0) maxtest= 1; // prevent overflow
- rectz= R.rectz+ start*R.rectx+ oldx;
+ rectz= zspan->rectz + start*zspan->rectx+ oldx;
if(dx<0) ofs= -1;
else ofs= 1;
- for(y= start; y<=end; y++, rectz+=R.rectx) {
+ for(y= start; y<=end; y++, rectz+=zspan->rectx) {
x= floor(v1[0]);
if(x!=oldx) {
@@ -1089,7 +772,7 @@ static void zbufline_onlyZ(int zvlnr, float *vec1, float *vec2)
rectz+= ofs;
}
- if(x>=0 && y>=0 && x<R.rectx) {
+ if(x>=0 && y>=0 && x<zspan->rectx) {
if(vergz<*rectz) {
*rectz= vergz;
}
@@ -1153,10 +836,19 @@ static int clipline(float *v1, float *v2) /* return 0: do not draw */
return 0;
}
+static void hoco_to_zco(ZSpan *zspan, float *zco, float *hoco)
+{
+ float div;
+
+ div= 1.0f/hoco[3];
+ zco[0]= zspan->zmulx*(1.0+hoco[0]*div) + zspan->zofsx;
+ zco[1]= zspan->zmuly*(1.0+hoco[1]*div) + zspan->zofsy;
+ zco[2]= 0x7FFFFFFF *(hoco[2]*div);
+}
-void zbufclipwire(int zvlnr, VlakRen *vlr)
+void zbufclipwire(ZSpan *zspan, int zvlnr, VlakRen *vlr)
{
- float vez[20], *f1, *f2, *f3, *f4= 0, deler;
+ float vez[20], *f1, *f2, *f3, *f4= 0;
int c1, c2, c3, c4, ec, and, or;
/* edgecode: 1= draw */
@@ -1192,18 +884,18 @@ void zbufclipwire(int zvlnr, VlakRen *vlr)
QUATCOPY(vez, f1);
QUATCOPY(vez+4, f2);
if( clipline(vez, vez+4)) {
- hoco_to_zco(vez, vez);
- hoco_to_zco(vez+4, vez+4);
- zbuflinefunc(zvlnr, vez, vez+4);
+ hoco_to_zco(zspan, vez, vez);
+ hoco_to_zco(zspan, vez+4, vez+4);
+ zspan->zbuflinefunc(zspan, zvlnr, vez, vez+4);
}
}
if(ec & ME_V2V3) {
QUATCOPY(vez, f2);
QUATCOPY(vez+4, f3);
if( clipline(vez, vez+4)) {
- hoco_to_zco(vez, vez);
- hoco_to_zco(vez+4, vez+4);
- zbuflinefunc(zvlnr, vez, vez+4);
+ hoco_to_zco(zspan, vez, vez);
+ hoco_to_zco(zspan, vez+4, vez+4);
+ zspan->zbuflinefunc(zspan, zvlnr, vez, vez+4);
}
}
if(vlr->v4) {
@@ -1211,18 +903,18 @@ void zbufclipwire(int zvlnr, VlakRen *vlr)
QUATCOPY(vez, f3);
QUATCOPY(vez+4, f4);
if( clipline(vez, vez+4)) {
- hoco_to_zco(vez, vez);
- hoco_to_zco(vez+4, vez+4);
- zbuflinefunc(zvlnr, vez, vez+4);
+ hoco_to_zco(zspan, vez, vez);
+ hoco_to_zco(zspan, vez+4, vez+4);
+ zspan->zbuflinefunc(zspan, zvlnr, vez, vez+4);
}
}
if(ec & ME_V4V1) {
QUATCOPY(vez, f4);
QUATCOPY(vez+4, f1);
if( clipline(vez, vez+4)) {
- hoco_to_zco(vez, vez);
- hoco_to_zco(vez+4, vez+4);
- zbuflinefunc(zvlnr, vez, vez+4);
+ hoco_to_zco(zspan, vez, vez);
+ hoco_to_zco(zspan, vez+4, vez+4);
+ zspan->zbuflinefunc(zspan, zvlnr, vez, vez+4);
}
}
}
@@ -1231,9 +923,9 @@ void zbufclipwire(int zvlnr, VlakRen *vlr)
QUATCOPY(vez, f3);
QUATCOPY(vez+4, f1);
if( clipline(vez, vez+4)) {
- hoco_to_zco(vez, vez);
- hoco_to_zco(vez+4, vez+4);
- zbuflinefunc(zvlnr, vez, vez+4);
+ hoco_to_zco(zspan, vez, vez);
+ hoco_to_zco(zspan, vez+4, vez+4);
+ zspan->zbuflinefunc(zspan, zvlnr, vez, vez+4);
}
}
}
@@ -1242,36 +934,21 @@ void zbufclipwire(int zvlnr, VlakRen *vlr)
}
}
- deler= f1[3];
- vez[0]= Zmulx*(1.0+f1[0]/deler)+ Zjitx;
- vez[1]= Zmuly*(1.0+f1[1]/deler)+ Zjity;
- vez[2]= 0x7FFFFFFF *(f1[2]/deler);
-
- deler= f2[3];
- vez[4]= Zmulx*(1.0+f2[0]/deler)+ Zjitx;
- vez[5]= Zmuly*(1.0+f2[1]/deler)+ Zjity;
- vez[6]= 0x7FFFFFFF *(f2[2]/deler);
-
- deler= f3[3];
- vez[8]= Zmulx*(1.0+f3[0]/deler)+ Zjitx;
- vez[9]= Zmuly*(1.0+f3[1]/deler)+ Zjity;
- vez[10]= 0x7FFFFFFF *(f3[2]/deler);
-
+ hoco_to_zco(zspan, vez, f1);
+ hoco_to_zco(zspan, vez+4, f2);
+ hoco_to_zco(zspan, vez+8, f3);
if(vlr->v4) {
- deler= f4[3];
- vez[12]= Zmulx*(1.0+f4[0]/deler)+ Zjitx;
- vez[13]= Zmuly*(1.0+f4[1]/deler)+ Zjity;
- vez[14]= 0x7FFFFFFF *(f4[2]/deler);
+ hoco_to_zco(zspan, vez+12, f4);
- if(ec & ME_V3V4) zbuflinefunc(zvlnr, vez+8, vez+12);
- if(ec & ME_V4V1) zbuflinefunc(zvlnr, vez+12, vez);
+ if(ec & ME_V3V4) zspan->zbuflinefunc(zspan, zvlnr, vez+8, vez+12);
+ if(ec & ME_V4V1) zspan->zbuflinefunc(zspan, zvlnr, vez+12, vez);
}
else {
- if(ec & ME_V3V1) zbuflinefunc(zvlnr, vez+8, vez);
+ if(ec & ME_V3V1) zspan->zbuflinefunc(zspan, zvlnr, vez+8, vez);
}
- if(ec & ME_V1V2) zbuflinefunc(zvlnr, vez, vez+4);
- if(ec & ME_V2V3) zbuflinefunc(zvlnr, vez+4, vez+8);
+ if(ec & ME_V1V2) zspan->zbuflinefunc(zspan, zvlnr, vez, vez+4);
+ if(ec & ME_V2V3) zspan->zbuflinefunc(zspan, zvlnr, vez+4, vez+8);
}
@@ -1286,226 +963,7 @@ void zbufclipwire(int zvlnr, VlakRen *vlr)
* @param v2 [4 floats, world coordinates] second vertex
* @param v3 [4 floats, world coordinates] third vertex
*/
-static void zbufinvulGLinv(ZSpan *zspan, int zvlnr, float *v1, float *v2, float *v3)
-{
- double x0,y0,z0,x1,y1,z1,x2,y2,z2,xx1;
- double zxd,zyd,zy0,tmp;
- float *minv,*maxv,*midv;
- int *rectpofs,*rp;
- int *rz,zverg,zvlak,x;
- int my0,my2,sn1,sn2,rectx,zd,*rectzofs;
- int y,omsl,xs0,xs1,xs2,xs3, dx0,dx1,dx2;
-
- /* MIN MAX */
- if(v1[1]<v2[1]) {
- if(v2[1]<v3[1]) {
- minv=v1; midv=v2; maxv=v3;
- }
- else if(v1[1]<v3[1]) {
- minv=v1; midv=v3; maxv=v2;
- }
- else {
- minv=v3; midv=v1; maxv=v2;
- }
- }
- else {
- if(v1[1]<v3[1]) {
- minv=v2; midv=v1; maxv=v3;
- }
- else if(v2[1]<v3[1]) {
- minv=v2; midv=v3; maxv=v1;
- }
- else {
- minv=v3; midv=v2; maxv=v1;
- }
- }
-
- my0= ceil(minv[1]);
- my2= floor(maxv[1]);
- omsl= floor(midv[1]);
-
- if(my2<0 || my0> R.recty) return;
-
- if(my0<0) my0=0;
-
- /* EDGES : LONGEST */
- xx1= maxv[1]-minv[1];
- if(xx1>2.0/65536.0) {
- z0= (maxv[0]-minv[0])/xx1;
-
- tmp= (-65536.0*z0);
- dx0= CLAMPIS(tmp, INT_MIN, INT_MAX);
-
- tmp= 65536.0*(z0*(my2-minv[1])+minv[0]);
- xs0= CLAMPIS(tmp, INT_MIN, INT_MAX);
- }
- else {
- dx0= 0;
- xs0= 65536.0*(MIN2(minv[0],maxv[0]));
- }
- /* EDGES : THE TOP ONE */
- xx1= maxv[1]-midv[1];
- if(xx1>2.0/65536.0) {
- z0= (maxv[0]-midv[0])/xx1;
-
- tmp= (-65536.0*z0);
- dx1= CLAMPIS(tmp, INT_MIN, INT_MAX);
-
- tmp= 65536.0*(z0*(my2-midv[1])+midv[0]);
- xs1= CLAMPIS(tmp, INT_MIN, INT_MAX);
- }
- else {
- dx1= 0;
- xs1= 65536.0*(MIN2(midv[0],maxv[0]));
- }
- /* EDGES : THE BOTTOM ONE */
- xx1= midv[1]-minv[1];
- if(xx1>2.0/65536.0) {
- z0= (midv[0]-minv[0])/xx1;
-
- tmp= (-65536.0*z0);
- dx2= CLAMPIS(tmp, INT_MIN, INT_MAX);
-
- tmp= 65536.0*(z0*(omsl-minv[1])+minv[0]);
- xs2= CLAMPIS(tmp, INT_MIN, INT_MAX);
- }
- else {
- dx2= 0;
- xs2= 65536.0*(MIN2(minv[0],midv[0]));
- }
-
- /* ZBUF DX DY */
- x1= v1[0]- v2[0];
- x2= v2[0]- v3[0];
- y1= v1[1]- v2[1];
- y2= v2[1]- v3[1];
- z1= v1[2]- v2[2];
- z2= v2[2]- v3[2];
- x0= y1*z2-z1*y2;
- y0= z1*x2-x1*z2;
- z0= x1*y2-y1*x2;
-
- if(z0==0.0) return;
-
- if(midv[1]==maxv[1]) omsl= my2;
- if(omsl<0) omsl= -1; /* then it does the first loop entirely */
-
- while (my2 >= R.recty) { /* my2 can be larger */
- xs0+=dx0;
- if (my2<=omsl) {
- xs2+= dx2;
- }
- else{
- xs1+= dx1;
- }
- my2--;
- }
-
- xx1= (x0*v1[0]+y0*v1[1])/z0+v1[2];
-
- zxd= -x0/z0;
- zyd= -y0/z0;
- zy0= my2*zyd+xx1;
- zd= (int)CLAMPIS(zxd, INT_MIN, INT_MAX);
-
- /* start-offset in rect */
- rectx= R.rectx;
- rectzofs= (int *)(R.rectz+rectx*my2);
- rectpofs= (R.rectot+rectx*my2);
- zvlak= zvlnr;
-
- xs3= 0; /* flag */
- if(dx0>dx1) {
- xs3= xs0;
- xs0= xs1;
- xs1= xs3;
- xs3= dx0;
- dx0= dx1;
- dx1= xs3;
- xs3= 1; /* flag */
-
- }
-
- for(y=my2;y>omsl;y--) {
-
- sn1= xs0>>16;
- xs0+= dx0;
-
- sn2= xs1>>16;
- xs1+= dx1;
-
- sn1++;
-
- if(sn2>=rectx) sn2= rectx-1;
- if(sn1<0) sn1= 0;
- zverg= (int) CLAMPIS((sn1*zxd+zy0), INT_MIN, INT_MAX);
- rz= rectzofs+sn1;
- rp= rectpofs+sn1;
- x= sn2-sn1;
- while(x>=0) {
- if(zverg> *rz || *rz==0x7FFFFFFF) {
- *rz= zverg;
- *rp= zvlak;
- }
- zverg+= zd;
- rz++;
- rp++;
- x--;
- }
- zy0-=zyd;
- rectzofs-= rectx;
- rectpofs-= rectx;
- }
-
- if(xs3) {
- xs0= xs1;
- dx0= dx1;
- }
- if(xs0>xs2) {
- xs3= xs0;
- xs0= xs2;
- xs2= xs3;
- xs3= dx0;
- dx0= dx2;
- dx2= xs3;
- }
-
- for(;y>=my0;y--) {
-
- sn1= xs0>>16;
- xs0+= dx0;
-
- sn2= xs2>>16;
- xs2+= dx2;
-
- sn1++;
-
- if(sn2>=rectx) sn2= rectx-1;
- if(sn1<0) sn1= 0;
- zverg= (int) CLAMPIS((sn1*zxd+zy0), INT_MIN, INT_MAX);
- rz= rectzofs+sn1;
- rp= rectpofs+sn1;
- x= sn2-sn1;
- while(x>=0) {
- if(zverg> *rz || *rz==0x7FFFFFFF) {
- *rz= zverg;
- *rp= zvlak;
- }
- zverg+= zd;
- rz++;
- rp++;
- x--;
- }
-
- zy0-=zyd;
- rectzofs-= rectx;
- rectpofs-= rectx;
- }
-}
-
-/* uses spanbuffers */
-
-static void zbufinvulGL4(ZSpan *zspan, int zvlnr, float *v1, float *v2, float *v3, float *v4)
+static void zbufinvulGLinv4(ZSpan *zspan, int zvlnr, float *v1, float *v2, float *v3, float *v4)
{
double zxd, zyd, zy0, zverg;
float x0,y0,z0;
@@ -1516,13 +974,17 @@ static void zbufinvulGL4(ZSpan *zspan, int zvlnr, float *v1, float *v2, float *v
int sn1, sn2, rectx, *rectzofs, my0, my2;
/* init */
- zbuf_init_span(zspan, 0, R.recty);
+ zbuf_init_span(zspan);
/* set spans */
zbuf_add_to_span(zspan, v1, v2);
zbuf_add_to_span(zspan, v2, v3);
- zbuf_add_to_span(zspan, v3, v4);
- zbuf_add_to_span(zspan, v4, v1);
+ if(v4) {
+ zbuf_add_to_span(zspan, v3, v4);
+ zbuf_add_to_span(zspan, v4, v1);
+ }
+ else
+ zbuf_add_to_span(zspan, v3, v1);
/* clipped */
if(zspan->minp2==NULL || zspan->maxp2==NULL) return;
@@ -1530,7 +992,7 @@ static void zbufinvulGL4(ZSpan *zspan, int zvlnr, float *v1, float *v2, float *v
if(zspan->miny1 < zspan->miny2) my0= zspan->miny2; else my0= zspan->miny1;
if(zspan->maxy1 > zspan->maxy2) my2= zspan->maxy2; else my2= zspan->maxy1;
-// printf("my %d %d\n", my0, my2);
+ // printf("my %d %d\n", my0, my2);
if(my2<my0) return;
@@ -1546,18 +1008,18 @@ static void zbufinvulGL4(ZSpan *zspan, int zvlnr, float *v1, float *v2, float *v
z0= x1*y2-y1*x2;
if(z0==0.0) return;
-
+
xx1= (x0*v1[0] + y0*v1[1])/z0 + v1[2];
-
+
zxd= -(double)x0/(double)z0;
zyd= -(double)y0/(double)z0;
zy0= ((double)my2)*zyd + (double)xx1;
-
+
/* start-offset in rect */
- rectx= R.rectx;
- rectzofs= (int *)(R.rectz+rectx*my2);
- rectpofs= (R.rectot+rectx*my2);
-
+ rectx= zspan->rectx;
+ rectzofs= (zspan->rectz+rectx*my2);
+ rectpofs= (zspan->rectp+rectx*my2);
+
/* correct span */
sn1= (my0 + my2)/2;
if(zspan->span1[sn1] < zspan->span2[sn1]) {
@@ -1585,7 +1047,7 @@ static void zbufinvulGL4(ZSpan *zspan, int zvlnr, float *v1, float *v2, float *v
x= sn2-sn1;
while(x>=0) {
- if( (int)zverg < *rz) {
+ if( (int)zverg > *rz || *rz==0x7FFFFFFF) {
*rz= (int)zverg;
*rp= zvlnr;
}
@@ -1602,33 +1064,42 @@ static void zbufinvulGL4(ZSpan *zspan, int zvlnr, float *v1, float *v2, float *v
}
}
-static void zbufinvulGL(ZSpan *zspan, int zvlnr, float *v1, float *v2, float *v3)
+/* uses spanbuffers */
+
+static void zbufinvulGL4(ZSpan *zspan, int zvlnr, float *v1, float *v2, float *v3, float *v4)
{
- double x0,y0,z0;
- double x1,y1,z1,x2,y2,z2,xx1;
- double zxd, zyd, zy0, zverg, zd;
+ double zxd, zyd, zy0, zverg;
+ float x0,y0,z0;
+ float x1,y1,z1,x2,y2,z2,xx1;
float *span1, *span2;
int *rectpofs, *rp;
- int *rz, zvlak, x, y, my0, my2;
- int sn1,sn2, rectx, *rectzofs;
+ int *rz, x, y;
+ int sn1, sn2, rectx, *rectzofs, my0, my2;
/* init */
- zbuf_init_span(zspan, 0, R.recty);
+ zbuf_init_span(zspan);
/* set spans */
zbuf_add_to_span(zspan, v1, v2);
zbuf_add_to_span(zspan, v2, v3);
- zbuf_add_to_span(zspan, v3, v1);
-
+ if(v4) {
+ zbuf_add_to_span(zspan, v3, v4);
+ zbuf_add_to_span(zspan, v4, v1);
+ }
+ else
+ zbuf_add_to_span(zspan, v3, v1);
+
/* clipped */
if(zspan->minp2==NULL || zspan->maxp2==NULL) return;
if(zspan->miny1 < zspan->miny2) my0= zspan->miny2; else my0= zspan->miny1;
if(zspan->maxy1 > zspan->maxy2) my2= zspan->maxy2; else my2= zspan->maxy1;
+// printf("my %d %d\n", my0, my2);
if(my2<my0) return;
- /* ZBUF DX DY */
+
+ /* ZBUF DX DY, in floats still */
x1= v1[0]- v2[0];
x2= v2[0]- v3[0];
y1= v1[1]- v2[1];
@@ -1640,21 +1111,19 @@ static void zbufinvulGL(ZSpan *zspan, int zvlnr, float *v1, float *v2, float *v3
z0= x1*y2-y1*x2;
if(z0==0.0) return;
-
- xx1= (x0*v1[0]+y0*v1[1])/z0+v1[2];
-
- zxd= -x0/z0;
- zyd= -y0/z0;
- zy0= my2*zyd+xx1;
- zd= zxd;
-
+
+ xx1= (x0*v1[0] + y0*v1[1])/z0 + v1[2];
+
+ zxd= -(double)x0/(double)z0;
+ zyd= -(double)y0/(double)z0;
+ zy0= ((double)my2)*zyd + (double)xx1;
+
/* start-offset in rect */
- rectx= R.rectx;
- rectzofs= (int *)(R.rectz+rectx*my2);
- rectpofs= (R.rectot+rectx*my2);
- zvlak= zvlnr;
-
- /* find correct span */
+ rectx= zspan->rectx;
+ rectzofs= (zspan->rectz+rectx*my2);
+ rectpofs= (zspan->rectp+rectx*my2);
+
+ /* correct span */
sn1= (my0 + my2)/2;
if(zspan->span1[sn1] < zspan->span2[sn1]) {
span1= zspan->span1+my2;
@@ -1669,24 +1138,23 @@ static void zbufinvulGL(ZSpan *zspan, int zvlnr, float *v1, float *v2, float *v3
sn1= floor(*span1);
sn2= floor(*span2);
-
sn1++;
if(sn2>=rectx) sn2= rectx-1;
if(sn1<0) sn1= 0;
if(sn2>=sn1) {
- zverg= sn1*zxd+zy0;
+ zverg= (double)sn1*zxd + zy0;
rz= rectzofs+sn1;
rp= rectpofs+sn1;
x= sn2-sn1;
while(x>=0) {
- if(zverg< *rz) {
- *rz= floor(zverg);
- *rp= zvlak;
+ if( (int)zverg < *rz) {
+ *rz= (int)zverg;
+ *rp= zvlnr;
}
- zverg+= zd;
+ zverg+= zxd;
rz++;
rp++;
x--;
@@ -1699,8 +1167,6 @@ static void zbufinvulGL(ZSpan *zspan, int zvlnr, float *v1, float *v2, float *v3
}
}
-
-
/**
* Fill the z buffer. The face buffer is not operated on!
*
@@ -1712,106 +1178,39 @@ static void zbufinvulGL(ZSpan *zspan, int zvlnr, float *v1, float *v2, float *v3
* @param v3 [4 floats, world coordinates] third vertex
*/
-static void zbufinvulGL_onlyZ(ZSpan *zspan, int zvlnr, float *v1, float *v2, float *v3)
+static void zbufinvulGL_onlyZ(ZSpan *zspan, int zvlnr, float *v1, float *v2, float *v3, float *v4)
{
- double x0,y0,z0,x1,y1,z1,x2,y2,z2,xx1;
- double zxd,zyd,zy0,tmp;
- float *minv,*maxv,*midv;
- int *rz,zverg,x;
- int my0,my2,sn1,sn2,rectx,zd,*rectzofs;
- int y,omsl,xs0,xs1,xs2,xs3, dx0,dx1,dx2;
-
- /* MIN MAX */
- if(v1[1]<v2[1]) {
- if(v2[1]<v3[1]) {
- minv=v1;
- midv=v2;
- maxv=v3;
- }
- else if(v1[1]<v3[1]) {
- minv=v1;
- midv=v3;
- maxv=v2;
- }
- else {
- minv=v3;
- midv=v1;
- maxv=v2;
- }
- }
- else {
- if(v1[1]<v3[1]) {
- minv=v2;
- midv=v1;
- maxv=v3;
- }
- else if(v2[1]<v3[1]) {
- minv=v2;
- midv=v3;
- maxv=v1;
- }
- else {
- minv=v3;
- midv=v2;
- maxv=v1;
- }
- }
-
- my0= ceil(minv[1]);
- my2= floor(maxv[1]);
- omsl= floor(midv[1]);
-
- if(my2<0 || my0> R.recty) return;
-
- if(my0<0) my0=0;
-
- /* EDGES : LONGEST */
- xx1= maxv[1]-minv[1];
- if(xx1!=0.0) {
- z0= (maxv[0]-minv[0])/xx1;
-
- tmp= (-65536.0*z0);
- dx0= CLAMPIS(tmp, INT_MIN, INT_MAX);
-
- tmp= 65536.0*(z0*(my2-minv[1])+minv[0]);
- xs0= CLAMPIS(tmp, INT_MIN, INT_MAX);
- }
- else {
- dx0= 0;
- xs0= 65536.0*(MIN2(minv[0],maxv[0]));
- }
- /* EDGES : TOP */
- xx1= maxv[1]-midv[1];
- if(xx1!=0.0) {
- z0= (maxv[0]-midv[0])/xx1;
-
- tmp= (-65536.0*z0);
- dx1= CLAMPIS(tmp, INT_MIN, INT_MAX);
-
- tmp= 65536.0*(z0*(my2-midv[1])+midv[0]);
- xs1= CLAMPIS(tmp, INT_MIN, INT_MAX);
- }
- else {
- dx1= 0;
- xs1= 65536.0*(MIN2(midv[0],maxv[0]));
- }
- /* EDGES : BOTTOM */
- xx1= midv[1]-minv[1];
- if(xx1!=0.0) {
- z0= (midv[0]-minv[0])/xx1;
-
- tmp= (-65536.0*z0);
- dx2= CLAMPIS(tmp, INT_MIN, INT_MAX);
-
- tmp= 65536.0*(z0*(omsl-minv[1])+minv[0]);
- xs2= CLAMPIS(tmp, INT_MIN, INT_MAX);
- }
- else {
- dx2= 0;
- xs2= 65536.0*(MIN2(minv[0],midv[0]));
+ double zxd, zyd, zy0, zverg;
+ float x0,y0,z0;
+ float x1,y1,z1,x2,y2,z2,xx1;
+ float *span1, *span2;
+ int *rz, x, y;
+ int sn1, sn2, rectx, *rectzofs, my0, my2;
+
+ /* init */
+ zbuf_init_span(zspan);
+
+ /* set spans */
+ zbuf_add_to_span(zspan, v1, v2);
+ zbuf_add_to_span(zspan, v2, v3);
+ if(v4) {
+ zbuf_add_to_span(zspan, v3, v4);
+ zbuf_add_to_span(zspan, v4, v1);
}
-
- /* ZBUF DX DY */
+ else
+ zbuf_add_to_span(zspan, v3, v1);
+
+ /* clipped */
+ if(zspan->minp2==NULL || zspan->maxp2==NULL) return;
+
+ if(zspan->miny1 < zspan->miny2) my0= zspan->miny2; else my0= zspan->miny1;
+ if(zspan->maxy1 > zspan->maxy2) my2= zspan->maxy2; else my2= zspan->maxy1;
+
+ // printf("my %d %d\n", my0, my2);
+ if(my2<my0) return;
+
+
+ /* ZBUF DX DY, in floats still */
x1= v1[0]- v2[0];
x2= v2[0]- v3[0];
y1= v1[1]- v2[1];
@@ -1821,112 +1220,54 @@ static void zbufinvulGL_onlyZ(ZSpan *zspan, int zvlnr, float *v1, float *v2, flo
x0= y1*z2-z1*y2;
y0= z1*x2-x1*z2;
z0= x1*y2-y1*x2;
-
+
if(z0==0.0) return;
-
- if(midv[1]==maxv[1]) omsl= my2;
- if(omsl<0) omsl= -1; /* then it takes first loop entirely */
-
- while (my2 >= R.recty) { /* my2 can be larger */
- xs0+=dx0;
- if (my2<=omsl) {
- xs2+= dx2;
- }
- else{
- xs1+= dx1;
- }
- my2--;
- }
-
- xx1= (x0*v1[0]+y0*v1[1])/z0+v1[2];
-
- zxd= -x0/z0;
- zyd= -y0/z0;
- zy0= my2*zyd+xx1;
- zd= (int)CLAMPIS(zxd, INT_MIN, INT_MAX);
-
+
+ xx1= (x0*v1[0] + y0*v1[1])/z0 + v1[2];
+
+ zxd= -(double)x0/(double)z0;
+ zyd= -(double)y0/(double)z0;
+ zy0= ((double)my2)*zyd + (double)xx1;
+
/* start-offset in rect */
- rectx= R.rectx;
- rectzofs= (int *)(R.rectz+rectx*my2);
-
- xs3= 0; /* flag */
- if(dx0>dx1) {
- xs3= xs0;
- xs0= xs1;
- xs1= xs3;
- xs3= dx0;
- dx0= dx1;
- dx1= xs3;
- xs3= 1; /* flag */
-
- }
-
- for(y=my2;y>omsl;y--) {
-
- sn1= xs0>>16;
- xs0+= dx0;
-
- sn2= xs1>>16;
- xs1+= dx1;
-
- sn1++;
-
- if(sn2>=rectx) sn2= rectx-1;
- if(sn1<0) sn1= 0;
- zverg= (int) CLAMPIS((sn1*zxd+zy0), INT_MIN, INT_MAX);
- rz= rectzofs+sn1;
-
- x= sn2-sn1;
- while(x>=0) {
- if(zverg< *rz) {
- *rz= zverg;
- }
- zverg+= zd;
- rz++;
- x--;
- }
- zy0-=zyd;
- rectzofs-= rectx;
- }
-
- if(xs3) {
- xs0= xs1;
- dx0= dx1;
+ rectx= zspan->rectx;
+ rectzofs= (zspan->rectz+rectx*my2);
+
+ /* correct span */
+ sn1= (my0 + my2)/2;
+ if(zspan->span1[sn1] < zspan->span2[sn1]) {
+ span1= zspan->span1+my2;
+ span2= zspan->span2+my2;
}
- if(xs0>xs2) {
- xs3= xs0;
- xs0= xs2;
- xs2= xs3;
- xs3= dx0;
- dx0= dx2;
- dx2= xs3;
+ else {
+ span1= zspan->span2+my2;
+ span2= zspan->span1+my2;
}
-
- for(;y>=my0;y--) {
-
- sn1= xs0>>16;
- xs0+= dx0;
-
- sn2= xs2>>16;
- xs2+= dx2;
-
- sn1++;
-
+
+ for(y=my2; y>=my0; y--, span1--, span2--) {
+
+ sn1= floor(*span1);
+ sn2= floor(*span2);
+ sn1++;
+
if(sn2>=rectx) sn2= rectx-1;
if(sn1<0) sn1= 0;
- zverg= (int) CLAMPIS((sn1*zxd+zy0), INT_MIN, INT_MAX);
- rz= rectzofs+sn1;
-
- x= sn2-sn1;
- while(x>=0) {
- if(zverg< *rz) {
- *rz= zverg;
+
+ if(sn2>=sn1) {
+ zverg= (double)sn1*zxd + zy0;
+ rz= rectzofs+sn1;
+ x= sn2-sn1;
+
+ while(x>=0) {
+ if( (int)zverg < *rz) {
+ *rz= (int)zverg;
+ }
+ zverg+= zxd;
+ rz++;
+ x--;
}
- zverg+= zd;
- rz++;
- x--;
}
-
+
zy0-=zyd;
rectzofs-= rectx;
}
@@ -1958,7 +1299,7 @@ static void clippyra(float *labda, float *v1, float *v2, int *b2, int *b3, int a
db= v2[3]-v1[3];
/* according the original article by Liang&Barsky, for clipping of
- * homeginic coordinates with viewplane, the value of "0" is used instead of "-w" .
+ * homogenous coordinates with viewplane, the value of "0" is used instead of "-w" .
* This differs from the other clipping cases (like left or top) and I considered
* it to be not so 'homogenic'. But later it has proven to be an error,
* who would have thought that of L&B!
@@ -2032,7 +1373,7 @@ static void makevertpyra(float *vez, float *labda, float **trias, float *v1, flo
/* ------------------------------------------------------------------------- */
-void RE_projectverto(float *v1, float *adr)
+void projectverto(float *v1, float winmat[][4], float *adr)
{
/* calcs homogenic coord of vertex v1 */
float x,y,z;
@@ -2040,17 +1381,17 @@ void RE_projectverto(float *v1, float *adr)
x= v1[0];
y= v1[1];
z= v1[2];
- adr[0]= x*R.winmat[0][0] + z*R.winmat[2][0] + R.winmat[3][0];
- adr[1]= y*R.winmat[1][1] + z*R.winmat[2][1] + R.winmat[3][1];
- adr[2]= z*R.winmat[2][2] + R.winmat[3][2];
- adr[3]= z*R.winmat[2][3] + R.winmat[3][3];
+ adr[0]= x*winmat[0][0] + z*winmat[2][0] + winmat[3][0];
+ adr[1]= y*winmat[1][1] + z*winmat[2][1] + winmat[3][1];
+ adr[2]= z*winmat[2][2] + winmat[3][2];
+ adr[3]= z*winmat[2][3] + winmat[3][3];
//printf("hoco %f %f %f %f\n", adr[0], adr[1], adr[2], adr[3]);
}
/* ------------------------------------------------------------------------- */
-void projectvert(float *v1, float *adr)
+void projectvert(float *v1, float winmat[][4], float *adr)
{
/* calcs homogenic coord of vertex v1 */
float x,y,z;
@@ -2058,17 +1399,16 @@ void projectvert(float *v1, float *adr)
x= v1[0];
y= v1[1];
z= v1[2];
- adr[0]= x*R.winmat[0][0]+ y*R.winmat[1][0]+ z*R.winmat[2][0]+ R.winmat[3][0];
- adr[1]= x*R.winmat[0][1]+ y*R.winmat[1][1]+ z*R.winmat[2][1]+ R.winmat[3][1];
- adr[2]= x*R.winmat[0][2]+ y*R.winmat[1][2]+ z*R.winmat[2][2]+ R.winmat[3][2];
- adr[3]= x*R.winmat[0][3]+ y*R.winmat[1][3]+ z*R.winmat[2][3]+ R.winmat[3][3];
+ adr[0]= x*winmat[0][0]+ y*winmat[1][0]+ z*winmat[2][0]+ winmat[3][0];
+ adr[1]= x*winmat[0][1]+ y*winmat[1][1]+ z*winmat[2][1]+ winmat[3][1];
+ adr[2]= x*winmat[0][2]+ y*winmat[1][2]+ z*winmat[2][2]+ winmat[3][2];
+ adr[3]= x*winmat[0][3]+ y*winmat[1][3]+ z*winmat[2][3]+ winmat[3][3];
}
/* do zbuffering and clip, f1 f2 f3 are hocos, c1 c2 c3 are clipping flags */
void zbufclip(ZSpan *zspan, int zvlnr, float *f1, float *f2, float *f3, int c1, int c2, int c3)
{
- float deler;
float *vlzp[32][3], labda[3][2];
float vez[400], *trias[40];
@@ -2127,7 +1467,7 @@ void zbufclip(ZSpan *zspan, int zvlnr, float *f1, float *f2, float *f3, int c1,
clipflag[1]= clipflag[2]= 0;
f1= vez;
for(b3=0; b3<clve; b3++) {
- c4= RE_testclip(f1);
+ c4= testclip(f1);
clipflag[1] |= (c4 & 3);
clipflag[2] |= (c4 & 12);
f1+= 4;
@@ -2155,15 +1495,12 @@ void zbufclip(ZSpan *zspan, int zvlnr, float *f1, float *f2, float *f3, int c1,
/* perspective division */
f1=vez;
for(c1=0;c1<clve;c1++) {
- deler= f1[3];
- f1[0]= Zmulx*(1.0+f1[0]/deler)+ Zjitx;
- f1[1]= Zmuly*(1.0+f1[1]/deler)+ Zjity;
- f1[2]= 0x7FFFFFFF *(f1[2]/deler);
+ hoco_to_zco(zspan, f1, f1);
f1+=4;
}
for(b=1;b<clvl;b++) {
if(vlzp[b][0]) {
- zbuffunc(zspan, zvlnr, vlzp[b][0],vlzp[b][1],vlzp[b][2]);
+ zspan->zbuffunc(zspan, zvlnr, vlzp[b][0],vlzp[b][1],vlzp[b][2], NULL);
}
}
return;
@@ -2171,28 +1508,15 @@ void zbufclip(ZSpan *zspan, int zvlnr, float *f1, float *f2, float *f3, int c1,
}
/* perspective division: HCS to ZCS */
-
- deler= f1[3];
- vez[0]= Zmulx*(1.0+f1[0]/deler)+ Zjitx;
- vez[1]= Zmuly*(1.0+f1[1]/deler)+ Zjity;
- vez[2]= 0x7FFFFFFF *(f1[2]/deler);
+ hoco_to_zco(zspan, vez, f1);
+ hoco_to_zco(zspan, vez+4, f2);
+ hoco_to_zco(zspan, vez+8, f3);
- deler= f2[3];
- vez[4]= Zmulx*(1.0+f2[0]/deler)+ Zjitx;
- vez[5]= Zmuly*(1.0+f2[1]/deler)+ Zjity;
- vez[6]= 0x7FFFFFFF *(f2[2]/deler);
-
- deler= f3[3];
- vez[8]= Zmulx*(1.0+f3[0]/deler)+ Zjitx;
- vez[9]= Zmuly*(1.0+f3[1]/deler)+ Zjity;
- vez[10]= 0x7FFFFFFF *(f3[2]/deler);
-
- zbuffunc(zspan, zvlnr, vez,vez+4,vez+8);
+ zspan->zbuffunc(zspan, zvlnr, vez,vez+4,vez+8, NULL);
}
static void zbufclip4(ZSpan *zspan, int zvlnr, float *f1, float *f2, float *f3, float *f4, int c1, int c2, int c3, int c4)
{
- float div;
float vez[16];
if(c1 | c2 | c3 | c4) { /* not in middle */
@@ -2206,52 +1530,102 @@ static void zbufclip4(ZSpan *zspan, int zvlnr, float *f1, float *f2, float *f3,
}
/* perspective division: HCS to ZCS */
+ hoco_to_zco(zspan, vez, f1);
+ hoco_to_zco(zspan, vez+4, f2);
+ hoco_to_zco(zspan, vez+8, f3);
+ hoco_to_zco(zspan, vez+12, f4);
- div= 1.0f/f1[3];
- vez[0]= Zmulx*(1.0+f1[0]*div)+ Zjitx;
- vez[1]= Zmuly*(1.0+f1[1]*div)+ Zjity;
- vez[2]= 0x7FFFFFFF *(f1[2]*div);
-
- div= 1.0f/f2[3];
- vez[4]= Zmulx*(1.0+f2[0]*div)+ Zjitx;
- vez[5]= Zmuly*(1.0+f2[1]*div)+ Zjity;
- vez[6]= 0x7FFFFFFF *(f2[2]*div);
-
- div= 1.0f/f3[3];
- vez[8]= Zmulx*(1.0+f3[0]*div)+ Zjitx;
- vez[9]= Zmuly*(1.0+f3[1]*div)+ Zjity;
- vez[10]= 0x7FFFFFFF *(f3[2]*div);
-
- div= 1.0f/f4[3];
- vez[12]= Zmulx*(1.0+f4[0]*div)+ Zjitx;
- vez[13]= Zmuly*(1.0+f4[1]*div)+ Zjity;
- vez[14]= 0x7FFFFFFF *(f4[2]*div);
-
- zbuffunc4(zspan, zvlnr, vez, vez+4, vez+8, vez+12);
+ zspan->zbuffunc(zspan, zvlnr, vez, vez+4, vez+8, vez+12);
}
/* ***************** ZBUFFER MAIN ROUTINES **************** */
+void set_part_zbuf_clipflag(RenderPart *pa)
+{
+ VertRen *ver=NULL;
+ float minx, miny, maxx, maxy, wco;
+ unsigned short clipclear;
+ int v;
-void zbufferall(void)
+ minx= (2*pa->disprect.xmin - R.winx-1)/(float)R.winx;
+ maxx= (2*pa->disprect.xmax - R.winx+1)/(float)R.winx;
+ miny= (2*pa->disprect.ymin - R.winy-1)/(float)R.winy;
+ maxy= (2*pa->disprect.ymax - R.winy+1)/(float)R.winy;
+
+ /* supports up to 4 threads this way */
+ clipclear= ~(15 << 4*(pa->thread & 3));
+
+ for(v=0; v<R.totvert; v++) {
+ if((v & 255)==0) ver= RE_findOrAddVert(&R, v);
+ else ver++;
+
+ wco= ver->ho[3];
+ ver->flag &= clipclear;
+
+ switch(pa->thread & 3) {
+ case 0:
+ if( ver->ho[0] > maxx*wco) ver->flag |= 1;
+ else if( ver->ho[0]< minx*wco) ver->flag |= 2;
+ if( ver->ho[1] > maxy*wco) ver->flag |= 4;
+ else if( ver->ho[1]< miny*wco) ver->flag |= 8;
+ break;
+ case 1:
+ if( ver->ho[0] > maxx*wco) ver->flag |= 16;
+ else if( ver->ho[0]< minx*wco) ver->flag |= 32;
+ if( ver->ho[1] > maxy*wco) ver->flag |= 64;
+ else if( ver->ho[1]< miny*wco) ver->flag |= 128;
+ break;
+ case 2:
+ if( ver->ho[0] > maxx*wco) ver->flag |= 256;
+ else if( ver->ho[0]< minx*wco) ver->flag |= 512;
+ if( ver->ho[1] > maxy*wco) ver->flag |= 1024;
+ else if( ver->ho[1]< miny*wco) ver->flag |= 2048;
+ break;
+ case 3:
+ if( ver->ho[0] > maxx*wco) ver->flag |= 4096;
+ else if( ver->ho[0]< minx*wco) ver->flag |= 8192;
+ if( ver->ho[1] > maxy*wco) ver->flag |= 16384;
+ else if( ver->ho[1]< miny*wco) ver->flag |= 32768;
+ break;
+ }
+ }
+}
+
+void zbuffer_solid(RenderPart *pa)
{
ZSpan zspan;
VlakRen *vlr= NULL;
Material *ma=0;
int v, zvlnr;
+ unsigned short clipmask;
short transp=0, env=0, wire=0;
- Zmulx= ((float)R.rectx)/2.0;
- Zmuly= ((float)R.recty)/2.0;
-
- fillrect(R.rectz, R.rectx, R.recty, 0x7FFFFFFF);
-
- zbuf_alloc_span(&zspan, R.recty);
+ zbuf_alloc_span(&zspan, pa->rectx, pa->recty);
- zbuffunc= zbufinvulGL;
- zbuffunc4= zbufinvulGL4;
- zbuflinefunc= zbufline;
+ /* needed for transform from hoco to zbuffer co */
+ zspan.zmulx= ((float)R.winx)/2.0;
+ zspan.zmuly= ((float)R.winy)/2.0;
+ zspan.zofsx= -pa->disprect.xmin -0.5f;
+ zspan.zofsy= -pa->disprect.ymin -0.5f;
+
+ if(R.osa) {
+ zspan.zofsx-= R.jit[pa->sample][0];
+ zspan.zofsy-= R.jit[pa->sample][1];
+ }
+
+ /* the buffers */
+ zspan.rectz= pa->rectz;
+ zspan.rectp= pa->rectp;
+ fillrect(pa->rectp, pa->rectx, pa->recty, 0);
+ fillrect(pa->rectz, pa->rectx, pa->recty, 0x7FFFFFFF);
+
+ /* filling methods */
+ zspan.zbuffunc= zbufinvulGL4;
+ zspan.zbuflinefunc= zbufline;
+
+ /* part clipflag, threaded */
+ clipmask= (15 << 4*(pa->thread & 3));
for(v=0; v<R.totvlak; v++) {
@@ -2265,24 +1639,34 @@ void zbufferall(void)
env= (ma->mode & MA_ENV);
wire= (ma->mode & MA_WIRE);
- if(ma->mode & MA_ZINV) zbuffunc= zbufinvulGLinv;
- else zbuffunc= zbufinvulGL;
+ if(ma->mode & MA_ZINV) zspan.zbuffunc= zbufinvulGLinv4;
+ else zspan.zbuffunc= zbufinvulGL4;
}
if(transp==0) {
- if(env) zvlnr= 0;
- else zvlnr= v+1;
+ unsigned short partclip;
- if(wire) zbufclipwire(zvlnr, vlr);
- else {
- if(vlr->v4 && (vlr->flag & R_STRAND)) {
- zbufclip4(&zspan, zvlnr, vlr->v1->ho, vlr->v2->ho, vlr->v3->ho, vlr->v4->ho, vlr->v1->clip, vlr->v2->clip, vlr->v3->clip, vlr->v4->clip);
- }
+ /* partclipping doesn't need viewplane clipping */
+ if(vlr->v4) partclip= vlr->v1->flag & vlr->v2->flag & vlr->v3->flag & vlr->v4->flag;
+ else partclip= vlr->v1->flag & vlr->v2->flag & vlr->v3->flag;
+
+ if((partclip & clipmask)==0) {
+
+ if(env) zvlnr= 0;
+ else zvlnr= v+1;
+
+ if(wire) zbufclipwire(&zspan, zvlnr, vlr);
else {
- zbufclip(&zspan, zvlnr, vlr->v1->ho, vlr->v2->ho, vlr->v3->ho, vlr->v1->clip, vlr->v2->clip, vlr->v3->clip);
- if(vlr->v4) {
- if(zvlnr) zvlnr+= 0x800000;
- zbufclip(&zspan, zvlnr, vlr->v1->ho, vlr->v3->ho, vlr->v4->ho, vlr->v1->clip, vlr->v3->clip, vlr->v4->clip);
+ /* strands allow to be filled in as quad */
+ if(vlr->v4 && (vlr->flag & R_STRAND)) {
+ zbufclip4(&zspan, zvlnr, vlr->v1->ho, vlr->v2->ho, vlr->v3->ho, vlr->v4->ho, vlr->v1->clip, vlr->v2->clip, vlr->v3->clip, vlr->v4->clip);
+ }
+ else {
+ zbufclip(&zspan, zvlnr, vlr->v1->ho, vlr->v2->ho, vlr->v3->ho, vlr->v1->clip, vlr->v2->clip, vlr->v3->clip);
+ if(vlr->v4) {
+ if(zvlnr) zvlnr+= 0x800000;
+ zbufclip(&zspan, zvlnr, vlr->v1->ho, vlr->v3->ho, vlr->v4->ho, vlr->v1->clip, vlr->v3->clip, vlr->v4->clip);
+ }
}
}
}
@@ -2293,11 +1677,19 @@ void zbufferall(void)
zbuf_free_span(&zspan);
}
-static int hashlist_projectvert(float *v1, float *hoco)
+typedef struct {
+ float *vert;
+ float hoco[4];
+ int clip;
+} VertBucket;
+
+/* warning, not threaded! */
+static int hashlist_projectvert(float *v1, float winmat[][4], float *hoco)
{
static VertBucket bucket[256], *buck;
- if(v1==0) {
+ /* init static bucket */
+ if(v1==NULL) {
memset(bucket, 0, 256*sizeof(VertBucket));
return 0;
}
@@ -2308,49 +1700,42 @@ static int hashlist_projectvert(float *v1, float *hoco)
return buck->clip;
}
- projectvert(v1, hoco);
- buck->clip = RE_testclip(hoco);
+ projectvert(v1, winmat, hoco);
+ buck->clip = testclip(hoco);
buck->vert= v1;
QUATCOPY(buck->hoco, hoco);
return buck->clip;
}
/* used for booth radio 'tool' as during render */
-void RE_zbufferall_radio(struct RadView *vw, RNode **rg_elem, int rg_totelem)
+void RE_zbufferall_radio(struct RadView *vw, RNode **rg_elem, int rg_totelem, Render *re)
{
ZSpan zspan;
- float hoco[4][4];
+ float hoco[4][4], winmat[4][4];
int a, zvlnr;
int c1, c2, c3, c4= 0;
- int *rectoto, *rectzo;
- int rectxo, rectyo;
if(rg_totelem==0) return;
- hashlist_projectvert(NULL, NULL);
+ hashlist_projectvert(NULL, winmat, NULL);
- rectxo= R.rectx;
- rectyo= R.recty;
- rectoto= R.rectot;
- rectzo= R.rectz;
-
- R.rectx= vw->rectx;
- R.recty= vw->recty;
- R.rectot= vw->rect;
- R.rectz= vw->rectz;
-
- Zmulx= ((float)R.rectx)/2.0;
- Zmuly= ((float)R.recty)/2.0;
-
/* needed for projectvert */
- MTC_Mat4MulMat4(R.winmat, vw->viewmat, vw->winmat);
-
- fillrect(R.rectz, R.rectx, R.recty, 0x7FFFFFFF);
- fillrect(R.rectot, R.rectx, R.recty, 0xFFFFFF);
+ MTC_Mat4MulMat4(winmat, vw->viewmat, vw->winmat);
- zbuf_alloc_span(&zspan, R.recty);
+ zbuf_alloc_span(&zspan, vw->rectx, vw->recty);
+ zspan.zmulx= ((float)vw->rectx)/2.0;
+ zspan.zmuly= ((float)vw->recty)/2.0;
+ zspan.zofsx= 0;
+ zspan.zofsy= 0;
- zbuffunc= zbufinvulGL;
+ /* the buffers */
+ zspan.rectz= vw->rectz;
+ zspan.rectp= vw->rect;
+ fillrect(zspan.rectz, vw->rectx, vw->recty, 0x7FFFFFFF);
+ fillrect(zspan.rectp, vw->rectx, vw->recty, 0xFFFFFF);
+
+ /* filling methods */
+ zspan.zbuffunc= zbufinvulGL4;
if(rg_elem) { /* radio tool */
RNode **re, *rn;
@@ -2365,18 +1750,18 @@ void RE_zbufferall_radio(struct RadView *vw, RNode **rg_elem, int rg_totelem)
else if( rn->f & RAD_BACKFACE) zvlnr= 0xFFFFFF;
else zvlnr= a;
- c1= hashlist_projectvert(rn->v1, hoco[0]);
- c2= hashlist_projectvert(rn->v2, hoco[1]);
- c3= hashlist_projectvert(rn->v3, hoco[2]);
+ c1= hashlist_projectvert(rn->v1, winmat, hoco[0]);
+ c2= hashlist_projectvert(rn->v2, winmat, hoco[1]);
+ c3= hashlist_projectvert(rn->v3, winmat, hoco[2]);
if(rn->v4) {
- c4= hashlist_projectvert(rn->v4, hoco[3]);
+ c4= hashlist_projectvert(rn->v4, winmat, hoco[3]);
}
- zbufclip(&zspan, zvlnr, hoco[0], hoco[1], hoco[2], c1, c2, c3);
- if(rn->v4) {
- zbufclip(&zspan, zvlnr, hoco[0], hoco[2], hoco[3], c1, c3, c4);
- }
+ if(rn->v4)
+ zbufclip4(&zspan, zvlnr, hoco[0], hoco[1], hoco[2], hoco[3], c1, c2, c3, c4);
+ else
+ zbufclip(&zspan, zvlnr, hoco[0], hoco[1], hoco[2], c1, c2, c3);
}
}
}
@@ -2385,8 +1770,8 @@ void RE_zbufferall_radio(struct RadView *vw, RNode **rg_elem, int rg_totelem)
RadFace *rf;
int totface=0;
- for(a=0; a<R.totvlak; a++) {
- if((a & 255)==0) vlr= R.blovl[a>>8]; else vlr++;
+ for(a=0; a<re->totvlak; a++) {
+ if((a & 255)==0) vlr= re->blovl[a>>8]; else vlr++;
if(vlr->radface) {
rf= vlr->radface;
@@ -2396,34 +1781,28 @@ void RE_zbufferall_radio(struct RadView *vw, RNode **rg_elem, int rg_totelem)
else if( rf->flag & RAD_BACKFACE) zvlnr= 0xFFFFFF; /* receives no energy, but is zbuffered */
else zvlnr= totface;
- c1= hashlist_projectvert(vlr->v1->co, hoco[0]);
- c2= hashlist_projectvert(vlr->v2->co, hoco[1]);
- c3= hashlist_projectvert(vlr->v3->co, hoco[2]);
+ c1= hashlist_projectvert(vlr->v1->co, winmat, hoco[0]);
+ c2= hashlist_projectvert(vlr->v2->co, winmat, hoco[1]);
+ c3= hashlist_projectvert(vlr->v3->co, winmat, hoco[2]);
if(vlr->v4) {
- c4= hashlist_projectvert(vlr->v4->co, hoco[3]);
+ c4= hashlist_projectvert(vlr->v4->co, winmat, hoco[3]);
}
- zbufclip(&zspan, zvlnr, hoco[0], hoco[1], hoco[2], c1, c2, c3);
- if(vlr->v4) {
- zbufclip(&zspan, zvlnr, hoco[0], hoco[2], hoco[3], c1, c3, c4);
- }
+ if(vlr->v4)
+ zbufclip4(&zspan, zvlnr, hoco[0], hoco[1], hoco[2], hoco[3], c1, c2, c3, c4);
+ else
+ zbufclip(&zspan, zvlnr, hoco[0], hoco[1], hoco[2], c1, c2, c3);
}
totface++;
}
}
}
-
- /* restore */
- R.rectx= rectxo;
- R.recty= rectyo;
- R.rectot= rectoto;
- R.rectz= rectzo;
zbuf_free_span(&zspan);
}
-void zbuffershad(LampRen *lar)
+void zbuffer_shadow(Render *re, LampRen *lar, int *rectz, int size)
{
ZSpan zspan;
VlakRen *vlr= NULL;
@@ -2432,20 +1811,23 @@ void zbuffershad(LampRen *lar)
if(lar->mode & LA_LAYER) lay= lar->lay;
- Zmulx= ((float)R.rectx)/2.0;
- Zmuly= ((float)R.recty)/2.0;
- Zjitx= Zjity= -0.5;
-
- fillrect(R.rectz,R.rectx,R.recty,0x7FFFFFFE);
-
- zbuf_alloc_span(&zspan, R.recty);
+ zbuf_alloc_span(&zspan, size, size);
+ zspan.zmulx= ((float)size)/2.0;
+ zspan.zmuly= ((float)size)/2.0;
+ zspan.zofsx= -0.5f;
+ zspan.zofsy= -0.5f;
+
+ /* the buffers */
+ zspan.rectz= rectz;
+ fillrect(rectz, size, size, 0x7FFFFFFE);
- zbuflinefunc= zbufline_onlyZ;
- zbuffunc= zbufinvulGL_onlyZ;
+ /* filling methods */
+ zspan.zbuflinefunc= zbufline_onlyZ;
+ zspan.zbuffunc= zbufinvulGL_onlyZ;
- for(a=0;a<R.totvlak;a++) {
+ for(a=0; a<re->totvlak; a++) {
- if((a & 255)==0) vlr= R.blovl[a>>8];
+ if((a & 255)==0) vlr= re->blovl[a>>8];
else vlr++;
if(vlr->mat!= ma) {
@@ -2455,11 +1837,13 @@ void zbuffershad(LampRen *lar)
}
if(ok && (vlr->flag & R_VISIBLE) && (vlr->lay & lay)) {
- if(ma->mode & MA_WIRE) zbufclipwire(a+1, vlr);
- else if(vlr->flag & R_STRAND) zbufclipwire(a+1, vlr);
+ if(ma->mode & MA_WIRE) zbufclipwire(&zspan, a+1, vlr);
+ else if(vlr->flag & R_STRAND) zbufclipwire(&zspan, a+1, vlr);
else {
- zbufclip(&zspan, 0, vlr->v1->ho, vlr->v2->ho, vlr->v3->ho, vlr->v1->clip, vlr->v2->clip, vlr->v3->clip);
- if(vlr->v4) zbufclip(&zspan, 0, vlr->v1->ho, vlr->v3->ho, vlr->v4->ho, vlr->v1->clip, vlr->v3->clip, vlr->v4->clip);
+ if(vlr->v4)
+ zbufclip4(&zspan, 0, vlr->v1->ho, vlr->v2->ho, vlr->v3->ho, vlr->v4->ho, vlr->v1->clip, vlr->v2->clip, vlr->v3->clip, vlr->v4->clip);
+ else
+ zbufclip(&zspan, 0, vlr->v1->ho, vlr->v2->ho, vlr->v3->ho, vlr->v1->clip, vlr->v2->clip, vlr->v3->clip);
}
}
}
@@ -2470,57 +1854,31 @@ void zbuffershad(LampRen *lar)
/* ******************** ABUF ************************* */
-
-void bgnaccumbuf(void)
-{
-
- Arectz= MEM_mallocN(sizeof(int)*ABUFPART*R.rectx, "Arectz");
- APixbuf= MEM_mallocN(ABUFPART*R.rectx*sizeof(APixstr), "APixbuf");
-
- Aminy= -1000;
- Amaxy= -1000;
-
- apsmteller= 0;
- apsmfirst.next= 0;
- apsmfirst.ps= 0;
-}
-/* ------------------------------------------------------------------------ */
-
-void endaccumbuf(void)
-{
-
- MEM_freeN(Arectz);
- MEM_freeN(APixbuf);
- freepsA();
-}
-
-/* ------------------------------------------------------------------------ */
-
/**
* Copy results from the solid face z buffering to the transparent
* buffer.
*/
-static void copyto_abufz(int sample)
+static void copyto_abufz(RenderPart *pa, int *arectz, int sample)
{
PixStr *ps;
int x, y, *rza;
long *rd;
/* now, in OSA the pixstructs contain all faces filled in */
- if(R.r.mode & R_OSA) fillrect(Arectz, R.rectx, Amaxy-Aminy+1, 0x7FFFFFFF);
+ if(R.r.mode & R_OSA) fillrect(arectz, pa->rectx, pa->recty, 0x7FFFFFFF);
else {
- memcpy(Arectz, R.rectz+ R.rectx*Aminy, 4*R.rectx*(Amaxy-Aminy+1));
+ memcpy(arectz, pa->rectz, 4*pa->rectx*pa->recty);
return;
}
- //if( (R.r.mode & R_OSA)==0 || sample==0) return;
+ if( (R.r.mode & R_OSA)==0 || sample==0) return;
- rza= Arectz;
- rd= (R.rectdaps+ R.rectx*Aminy);
+ rza= arectz;
+ rd= pa->rectdaps;
sample= (1<<sample);
- for(y=Aminy; y<=Amaxy; y++) {
- for(x=0; x<R.rectx; x++) {
+ for(y=0; y<pa->recty; y++) {
+ for(x=0; x<pa->rectx; x++) {
if(*rd) {
ps= (PixStr *)(*rd);
@@ -2547,93 +1905,60 @@ static void copyto_abufz(int sample)
* Do accumulation z buffering.
*/
-
-static void set_faces_raycountflag(void)
-{
- VertRen *ver=NULL;
- VlakRen *vlr=NULL;
- float wco, miny, maxy;
- int v, clipval;
-
- miny= (float)(2*Aminy-R.recty-1)/(float)R.recty;
- maxy= (float)(2*Amaxy-R.recty+2)/(float)R.recty;
-
- for(v=0; v<R.totvert; v++) {
- if((v & 255)==0) ver= RE_findOrAddVert(v);
- else ver++;
-
- wco= ver->ho[3];
- ver->flag= 0;
- if( ver->ho[1] > maxy*wco) ver->flag |= 64;
- else if( ver->ho[1]< miny*wco) ver->flag |= 128;
- }
-
- for(v=0; v<R.totvlak; v++) {
- if((v & 255)==0) {
- vlr= R.blovl[v>>8];
- }
- else vlr++;
-
- if(vlr->v4)
- clipval= vlr->v1->flag & vlr->v2->flag & vlr->v3->flag & vlr->v4->flag;
- else
- clipval= vlr->v1->flag & vlr->v2->flag & vlr->v3->flag;
-
- if(clipval==64 || clipval==128)
- vlr->raycount= 0;
- else
- vlr->raycount= 1;
- }
-}
-
-
-static void zbuffer_abuf()
+static void zbuffer_abuf(RenderPart *pa, APixstr *APixbuf, ListBase *apsmbase)
{
ZSpan zspan;
Material *ma=0;
VlakRen *vlr=NULL;
float vec[3], hoco[4], mul, zval, fval;
- int v, zvlnr;
- int len;
+ int v, zvlnr, zsample;
+ unsigned short clipmask;
- Zjitx= Zjity= -0.5;
- Zmulx= ((float)R.rectx)/2.0;
- Zmuly= ((float)R.recty)/2.0;
-
- /* clear APixstructs */
- len= sizeof(APixstr)*R.rectx*ABUFPART;
- memset(APixbuf, 0, len);
+ zbuf_alloc_span(&zspan, pa->rectx, pa->recty);
- zbuf_alloc_span(&zspan, R.recty);
+ /* needed for transform from hoco to zbuffer co */
+ zspan.zmulx= ((float)R.winx)/2.0;
+ zspan.zmuly= ((float)R.winy)/2.0;
+ zspan.zofsx= -pa->disprect.xmin -0.5f;
+ zspan.zofsy= -pa->disprect.ymin -0.5f;
- zbuffunc= zbufinvulAc;
- zbuffunc4= zbufinvulAc4;
- zbuflinefunc= zbuflineAc;
-
- set_faces_raycountflag();
+ /* the buffers */
+ zspan.arectz= RE_mallocN(sizeof(int)*pa->rectx*pa->recty, "Arectz");
+ zspan.apixbuf= APixbuf;
+ zspan.apsmbase= apsmbase;
+
+ /* filling methods */
+ zspan.zbuffunc= zbufinvulAc4;
+ zspan.zbuflinefunc= zbuflineAc;
+
+ /* part clipflag, 4 threads */
+ clipmask= (15 << 4*(pa->thread & 3));
- for(Zsample=0; Zsample<R.osa || R.osa==0; Zsample++) {
+ for(zsample=0; zsample<R.osa || R.osa==0; zsample++) {
+
+ copyto_abufz(pa, zspan.arectz, zsample); /* init zbuffer */
+ zspan.mask= 1<<zsample;
- copyto_abufz(Zsample); /* init zbuffer */
-
if(R.r.mode & R_OSA) {
- Zjitx= -jit[Zsample][0]-0.5;
- Zjity= -jit[Zsample][1]-0.5;
+ zspan.zofsx= -pa->disprect.xmin-R.jit[zsample][0]-0.5;
+ zspan.zofsy= -pa->disprect.ymin-R.jit[zsample][1]-0.5;
}
for(v=0; v<R.totvlak; v++) {
- if((v & 255)==0) {
+ if((v & 255)==0)
vlr= R.blovl[v>>8];
- }
else vlr++;
- if(vlr->raycount) {
- ma= vlr->mat;
-
- if(ma->mode & (MA_ZTRA)) {
-
- if(vlr->flag & R_VISIBLE) {
-
+ ma= vlr->mat;
+ if(ma->mode & (MA_ZTRA)) {
+ if(vlr->flag & R_VISIBLE) {
+ unsigned short partclip;
+
+ /* partclipping doesn't need viewplane clipping */
+ if(vlr->v4) partclip= vlr->v1->flag & vlr->v2->flag & vlr->v3->flag & vlr->v4->flag;
+ else partclip= vlr->v1->flag & vlr->v2->flag & vlr->v3->flag;
+
+ if((partclip & clipmask)==0) {
/* a little advantage for transp rendering (a z offset) */
if( ma->zoffs != 0.0) {
mul= 0x7FFFFFFF;
@@ -2642,16 +1967,16 @@ static void zbuffer_abuf()
VECCOPY(vec, vlr->v1->co);
/* z is negative, otherwise its being clipped */
vec[2]-= ma->zoffs;
- RE_projectverto(vec, hoco);
+ projectverto(vec, R.winmat, hoco);
fval= mul*(1.0+hoco[2]/hoco[3]);
- Azvoordeel= (int) fabs(zval - fval );
+ zspan.polygon_offset= (int) fabs(zval - fval );
}
- else Azvoordeel= 0;
+ else zspan.polygon_offset= 0;
zvlnr= v+1;
- if(ma->mode & (MA_WIRE)) zbufclipwire(zvlnr, vlr);
+ if(ma->mode & (MA_WIRE)) zbufclipwire(&zspan, zvlnr, vlr);
else {
if(vlr->v4 && (vlr->flag & R_STRAND)) {
zbufclip4(&zspan, zvlnr, vlr->v1->ho, vlr->v2->ho, vlr->v3->ho, vlr->v4->ho, vlr->v1->clip, vlr->v2->clip, vlr->v3->clip, vlr->v4->clip);
@@ -2665,21 +1990,23 @@ static void zbuffer_abuf()
}
}
}
- if( (v & 255)==255)
- if(RE_local_test_break())
- break;
}
+ if( (v & 255)==255)
+ if(R.test_break())
+ break;
}
}
if((R.r.mode & R_OSA)==0) break;
- if(RE_local_test_break()) break;
+ if(R.test_break()) break;
}
+ RE_freeN(zspan.arectz);
zbuf_free_span(&zspan);
+
}
-int vergzvlak(const void *a1, const void *a2)
+static int vergzvlak(const void *a1, const void *a2)
{
const int *x1=a1, *x2=a2;
@@ -2691,7 +2018,7 @@ int vergzvlak(const void *a1, const void *a2)
/**
* Shade this face at this location in SCS.
*/
-static void shadetrapixel(float x, float y, int z, int facenr, int mask, float *fcol)
+static void shadetrapixel(RenderPart *pa, float x, float y, int z, int facenr, int mask, float *fcol)
{
float rco[3];
@@ -2700,14 +2027,14 @@ static void shadetrapixel(float x, float y, int z, int facenr, int mask, float *
return;
}
if(R.r.mode & R_OSA) {
- VlakRen *vlr= RE_findOrAddVlak( (facenr-1) & 0x7FFFFF);
+ VlakRen *vlr= RE_findOrAddVlak(&R, (facenr-1) & 0x7FFFFF);
float accumcol[4]={0,0,0,0}, tot=0.0;
int a;
if(vlr->flag & R_FULL_OSA) {
for(a=0; a<R.osa; a++) {
if(mask & (1<<a)) {
- shadepixel(x+jit[a][0], y+jit[a][1], z, facenr, 1<<a, fcol, rco);
+ shadepixel(pa, x+R.jit[a][0], y+R.jit[a][1], z, facenr, 1<<a, fcol, rco);
accumcol[0]+= fcol[0];
accumcol[1]+= fcol[1];
accumcol[2]+= fcol[2];
@@ -2722,17 +2049,14 @@ static void shadetrapixel(float x, float y, int z, int facenr, int mask, float *
fcol[3]= accumcol[3]*tot;
}
else {
- extern float centLut[16];
- extern char *centmask;
-
- int b= centmask[mask];
- x= x+centLut[b & 15];
- y= y+centLut[b>>4];
- shadepixel(x, y, z, facenr, mask, fcol, rco);
+ int b= R.samples->centmask[mask];
+ x= x+R.samples->centLut[b & 15];
+ y= y+R.samples->centLut[b>>4];
+ shadepixel(pa, x, y, z, facenr, mask, fcol, rco);
}
}
- else shadepixel(x, y, z, facenr, mask, fcol, rco);
+ else shadepixel(pa, x, y, z, facenr, mask, fcol, rco);
}
static int addtosampcol(float *sampcol, float *fcol, int mask)
@@ -2747,29 +2071,31 @@ static int addtosampcol(float *sampcol, float *fcol, int mask)
return retval;
}
-/*
- * renders when needed the Abuffer with faces stored in pixels, returns 1 scanline rendered
- */
-
#define MAX_ZROW 1000
-void abufsetrow(float *acolrow, int y)
+/* main render call to fill in pass the full transparent layer */
+
+void zbuffer_transp_shade(RenderPart *pa, float *pass)
{
- extern SDL_mutex *render_abuf_lock; // initrender.c
+ APixstr *APixbuf; /* Zbuffer: linked list of face samples */
APixstr *ap, *apn;
- float *col, fcol[4], tempcol[4], sampcol[16*4], *scol, accumcol[4];
- float ys, fac, alpha[32];
- int x, part, a, zrow[MAX_ZROW][3], totface, nr;
+ ListBase apsmbase={NULL, NULL};
+ float col[4], fcol[4], tempcol[4], sampcol[16*4], *scol, accumcol[4];
+ float fac, alpha[32];
+ int x, y, a, zrow[MAX_ZROW][3], totface, nr;
int sval;
- if(y<0) return;
+ /* looks nicer for calling code */
+ if(R.test_break())
+ return;
+
+ APixbuf= RE_callocN(pa->rectx*pa->recty*sizeof(APixstr), "APixbuf");
+
if(R.osa>16) {
printf("abufsetrow: osa too large\n");
G.afbreek= 1;
return;
}
-
- //R.flag &= ~R_LAMPHALO;
-
+
/* alpha LUT */
if(R.r.mode & R_OSA ) {
fac= (1.0/(float)R.osa);
@@ -2777,146 +2103,132 @@ void abufsetrow(float *acolrow, int y)
alpha[a]= (float)a*fac;
}
}
-
- if(R.r.mode & R_THREADS) {
- /* lock thread if... */
- if(y>Aminy+2 && y<Amaxy-2);
- else {
- if(render_abuf_lock) SDL_mutexP(render_abuf_lock);
- }
- }
- /* does a pixbuf has to be created? */
- if(y<Aminy || y>Amaxy) {
- part= (y/ABUFPART);
- Aminy= part*ABUFPART;
- Amaxy= Aminy+ABUFPART-1;
- if(Amaxy>=R.recty) Amaxy= R.recty-1;
- freepsA();
- zbuffer_abuf();
- }
-
- /* render row */
- col= acolrow;
- memset(col, 0, 4*sizeof(float)*R.rectx);
- ap= APixbuf + R.rectx*(y-Aminy);
- ys= y;
-
- for(x=0; x<R.rectx; x++, col+=4, ap++) {
- if(ap->p[0]) {
- /* sort in z */
- totface= 0;
- apn= ap;
- while(apn) {
- for(a=0; a<4; a++) {
- if(apn->p[a]) {
- zrow[totface][0]= apn->z[a];
- zrow[totface][1]= apn->p[a];
- zrow[totface][2]= apn->mask[a];
- totface++;
- if(totface>=MAX_ZROW) totface= MAX_ZROW-1;
+ /* fill the Apixbuf */
+ zbuffer_abuf(pa, APixbuf, &apsmbase);
+
+ /* render tile */
+ ap= APixbuf;
+
+ for(y=pa->disprect.ymin; y<pa->disprect.ymax; y++) {
+ for(x=pa->disprect.xmin; x<pa->disprect.xmax; x++, ap++, pass+=4) {
+
+ if(ap->p[0]) {
+ /* sort in z */
+ totface= 0;
+ apn= ap;
+ while(apn) {
+ for(a=0; a<4; a++) {
+ if(apn->p[a]) {
+ zrow[totface][0]= apn->z[a];
+ zrow[totface][1]= apn->p[a];
+ zrow[totface][2]= apn->mask[a];
+ totface++;
+ if(totface>=MAX_ZROW) totface= MAX_ZROW-1;
+ }
+ else break;
}
- else break;
+ apn= apn->next;
}
- apn= apn->next;
- }
-
- if(totface==1) {
- shadetrapixel((float)x, (float)y, zrow[0][0], zrow[0][1], zrow[0][2], fcol);
-
- nr= count_mask(zrow[0][2]);
- if( (R.r.mode & R_OSA) && nr<R.osa) {
- fac= alpha[ nr ];
- col[0]= (fcol[0]*fac);
- col[1]= (fcol[1]*fac);
- col[2]= (fcol[2]*fac);
- col[3]= (fcol[3]*fac);
+ if(totface==1) {
+
+ shadetrapixel(pa, (float)x, (float)y, zrow[0][0], zrow[0][1], zrow[0][2], fcol);
+
+ nr= count_mask(zrow[0][2]);
+ if( (R.r.mode & R_OSA) && nr<R.osa) {
+ fac= alpha[ nr ];
+ col[0]= (fcol[0]*fac);
+ col[1]= (fcol[1]*fac);
+ col[2]= (fcol[2]*fac);
+ col[3]= (fcol[3]*fac);
+ }
+ else {
+ col[0]= fcol[0];
+ col[1]= fcol[1];
+ col[2]= fcol[2];
+ col[3]= fcol[3];
+ }
}
else {
- col[0]= fcol[0];
- col[1]= fcol[1];
- col[2]= fcol[2];
- col[3]= fcol[3];
- }
- }
- else {
-
- if(totface==2) {
- if(zrow[0][0] < zrow[1][0]) {
- a= zrow[0][0]; zrow[0][0]= zrow[1][0]; zrow[1][0]= a;
- a= zrow[0][1]; zrow[0][1]= zrow[1][1]; zrow[1][1]= a;
- a= zrow[0][2]; zrow[0][2]= zrow[1][2]; zrow[1][2]= a;
+ col[0]= col[1]= col[2]= col[3]= 0.0f;
+
+ if(totface==2) {
+ if(zrow[0][0] < zrow[1][0]) {
+ a= zrow[0][0]; zrow[0][0]= zrow[1][0]; zrow[1][0]= a;
+ a= zrow[0][1]; zrow[0][1]= zrow[1][1]; zrow[1][1]= a;
+ a= zrow[0][2]; zrow[0][2]= zrow[1][2]; zrow[1][2]= a;
+ }
+
+ }
+ else { /* totface>2 */
+ qsort(zrow, totface, sizeof(int)*3, vergzvlak);
}
-
- }
- else { /* totface>2 */
- qsort(zrow, totface, sizeof(int)*3, vergzvlak);
- }
-
- /* join when pixels are adjacent */
-
- while(totface>0) {
- totface--;
- shadetrapixel((float)x, (float)y, zrow[totface][0], zrow[totface][1], zrow[totface][2], fcol);
+ /* join when pixels are adjacent */
- a= count_mask(zrow[totface][2]);
- if( (R.r.mode & R_OSA ) && a<R.osa) {
- if(totface>0) {
- memset(sampcol, 0, 4*sizeof(float)*R.osa);
- sval= addtosampcol(sampcol, fcol, zrow[totface][2]);
-
- /* sval==0: alpha completely full */
- while( (sval != 0) && (totface>0) ) {
- a= count_mask(zrow[totface-1][2]);
- if(a==R.osa) break;
- totface--;
-
- shadetrapixel((float)x, (float)y, zrow[totface][0], zrow[totface][1], zrow[totface][2], fcol);
+ while(totface>0) {
+ totface--;
+
+ shadetrapixel(pa, (float)x, (float)y, zrow[totface][0], zrow[totface][1], zrow[totface][2], fcol);
+
+ a= count_mask(zrow[totface][2]);
+ if( (R.r.mode & R_OSA ) && a<R.osa) {
+ if(totface>0) {
+ memset(sampcol, 0, 4*sizeof(float)*R.osa);
sval= addtosampcol(sampcol, fcol, zrow[totface][2]);
+
+ /* sval==0: alpha completely full */
+ while( (sval != 0) && (totface>0) ) {
+ a= count_mask(zrow[totface-1][2]);
+ if(a==R.osa) break;
+ totface--;
+
+ shadetrapixel(pa, (float)x, (float)y, zrow[totface][0], zrow[totface][1], zrow[totface][2], fcol);
+ sval= addtosampcol(sampcol, fcol, zrow[totface][2]);
+ }
+
+ scol= sampcol;
+ accumcol[0]= scol[0]; accumcol[1]= scol[1];
+ accumcol[2]= scol[2]; accumcol[3]= scol[3];
+ scol+= 4;
+ for(a=1; a<R.osa; a++, scol+=4) {
+ accumcol[0]+= scol[0]; accumcol[1]+= scol[1];
+ accumcol[2]+= scol[2]; accumcol[3]+= scol[3];
+ }
+ tempcol[0]= accumcol[0]/R.osa;
+ tempcol[1]= accumcol[1]/R.osa;
+ tempcol[2]= accumcol[2]/R.osa;
+ tempcol[3]= accumcol[3]/R.osa;
+
+ addAlphaUnderFloat(col, tempcol);
+
}
- scol= sampcol;
- accumcol[0]= scol[0]; accumcol[1]= scol[1];
- accumcol[2]= scol[2]; accumcol[3]= scol[3];
- scol+= 4;
- for(a=1; a<R.osa; a++, scol+=4) {
- accumcol[0]+= scol[0]; accumcol[1]+= scol[1];
- accumcol[2]+= scol[2]; accumcol[3]+= scol[3];
+ else {
+ fac= alpha[a];
+ fcol[0]= (fcol[0]*fac);
+ fcol[1]= (fcol[1]*fac);
+ fcol[2]= (fcol[2]*fac);
+ fcol[3]= (fcol[3]*fac);
+ addAlphaUnderFloat(col, fcol);
}
- tempcol[0]= accumcol[0]/R.osa;
- tempcol[1]= accumcol[1]/R.osa;
- tempcol[2]= accumcol[2]/R.osa;
- tempcol[3]= accumcol[3]/R.osa;
-
- addAlphaUnderFloat(col, tempcol);
-
- }
- else {
- fac= alpha[a];
- fcol[0]= (fcol[0]*fac);
- fcol[1]= (fcol[1]*fac);
- fcol[2]= (fcol[2]*fac);
- fcol[3]= (fcol[3]*fac);
- addAlphaUnderFloat(col, fcol);
- }
- }
- else addAlphaUnderFloat(col, fcol);
-
- if(col[3]>=0.999) break;
+ }
+ else addAlphaUnderFloat(col, fcol); /* no osa or full pixel with same face? */
+
+ if(col[3]>=0.999) break;
+ }
}
+ if(col[3]!=0.0) addAlphaOverFloat(pass, col);
}
}
}
- if(R.r.mode & R_THREADS) {
- if(y>Aminy+2 && y<Amaxy-2);
- else {
- if(render_abuf_lock) SDL_mutexV(render_abuf_lock);
- }
- }
+ RE_freeN(APixbuf);
+ freepsA(&apsmbase);
+
}
+
/* end of zbuf.c */
diff --git a/source/blender/render/intern/source/zbufferdatastruct.c b/source/blender/render/intern/source/zbufferdatastruct.c
deleted file mode 100644
index d237b7d64f4..00000000000
--- a/source/blender/render/intern/source/zbufferdatastruct.c
+++ /dev/null
@@ -1,310 +0,0 @@
-/**
- * zbufferdatastruct.c
- *
- * $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.
- *
- * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
- * All rights reserved.
- *
- * The Original Code is: all of this file.
- *
- * Contributor(s): none yet.
- *
- * ***** END GPL/BL DUAL LICENSE BLOCK *****
- *
- * The z buffer consists of an array of lists. Each list holds the objects
- * behind a pixel. These can be sorted for closest distance. Per object,
- * we store:
- * - object type
- * - object index
- * - minimum distance
- * - maximum distance
- * - oversample flags
- *
- * The buffer was created to fit the new unified renderpipeline. We might
- * turn it into an object later on.
- *
- * The z buffer has an unlimited depth. The oversampling code chops at a
- * certain number of faces. This number is defined in
- * vanillaRenderPipe_types.h
- *
- * Version 1 of the z buffer inserted objects by means of linear
- * search: we walk along the list until we find the right object or
- * until we have to insert a new one. This is terribly inefficient
- * when we are dealing with large numbers of objects. Can we find a
- * better solution here?
- *
- * Because we treat halos as billboards, we optimize halo
- * insertion. For this purpose the fillFlatObject() functions have
- * been implemented. */
-
-#include <string.h>
-
-#include "MEM_guardedalloc.h"
-#include "zbufferdatastruct.h"
-#include "vanillaRenderPipe_types.h"
-#include "render.h"
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-/* if defined: all jittersamples are stored individually. _very_ serious */
-/* performance hit ! also gives some buffer size problems in big scenes */
-#define RE_INDIVIDUAL_SUBPIXELS
-
-/* ------------------------------------------------------------------------- */
-
-static RE_APixstrExtMain RE_apsemfirst; /* pixstr bookkeeping var */
-static short RE_apsemteller = 0; /* pixstr bookkeeping var */
-static int RE_zbufferwidth; /* width of the z-buffer (pixels) */
-RE_APixstrExt *APixbufExt; /* Zbuffer: linked list of face, halo indices */
-
-/*-RE_APixstrExt------------------------------------------------------------ */
-
-void initZbuffer(int width)
-{
- APixbufExt = MEM_callocN(RE_ZBUFLEN * width * sizeof(RE_APixstrExt),
- "APixbufExt");
- RE_zbufferwidth = width;
- RE_apsemteller = 0;
- RE_apsemfirst.next = NULL;
- RE_apsemfirst.ps = NULL;
-} /* end of RE_APixstrExt *initZbufferDataStruct() */
-
-/* ------------------------------------------------------------------------- */
-
-void freeZbuffer(void)
-{
- if (APixbufExt) MEM_freeN(APixbufExt);
- freepseA();
-} /* end of void freeZbuffer(void) */
-
-/* ------------------------------------------------------------------------- */
-
-void resetZbuffer(void)
-{
- int len;
-
- freepseA();
- len = sizeof(RE_APixstrExt) * RE_zbufferwidth * RE_ZBUFLEN;
- memset(APixbufExt, 0, len);
-} /* end of void resetZbuffer(void) */
-
-/* ------------------------------------------------------------------------- */
-
-RE_APixstrExt *addpsemainA()
-{
- RE_APixstrExtMain *psm;
-
- psm= &RE_apsemfirst;
-
- while(psm->next) {
- psm= psm->next;
- }
-
- psm->next= MEM_callocN(sizeof(RE_APixstrExtMain), "addpsemainA");
-
- psm= psm->next;
-
- /* Initialise the new structure to safe values. Memory that is newly */
- /* allocated must be zero... Not sure if that happens everywhere now.*/
- psm->next=0;
- psm->ps= MEM_callocN(4096*sizeof(RE_APixstrExt),"pixstrext");
- RE_apsemteller= 0;
-
- return psm->ps;
-} /* End of RE_APixstrExt *addpsemainA() */
-
-/* ------------------------------------------------------------------------- */
-
-void freepseA()
-{
- RE_APixstrExtMain *psm, *next;
-
- psm= &RE_apsemfirst;
-
- while(psm) {
- next= psm->next;
- if(psm->ps) {
- MEM_freeN(psm->ps);
- psm->ps= 0;
- }
- if(psm!= &RE_apsemfirst) MEM_freeN(psm);
- psm= next;
- }
-
- RE_apsemfirst.next= 0;
- RE_apsemfirst.ps= 0;
- RE_apsemteller= 0;
-} /* End of void freepseA() */
-
-/* ------------------------------------------------------------------------- */
-
-RE_APixstrExt *addpseA(void)
-{
- static RE_APixstrExt *prev;
-
- /* eerste PS maken */
- if((RE_apsemteller & 4095)==0) prev= addpsemainA();
- else prev++;
- RE_apsemteller++;
-
- return prev;
-} /* End of RE_APixstrExt *addpseA(void) */
-
-/* ------------------------------------------------------------------------- */
-
-void insertObject(int apteller,
- int obindex,
- int obtype,
- int dist,
- int mask)
-{
- /* Guard the insertion if needed? */
- RE_APixstrExt* apn = &APixbufExt[apteller];
- int all_subpixels= 0; // not used now... (ton)
-
- while(apn) {
-
- if(apn->t[0] == RE_NONE) {
- apn->p[0] = obindex; apn->t[0] = obtype;
- apn->zmin[0] = dist; apn->zmax[0] = dist;
- apn->mask[0] = mask;
- break;
- }
- else if(all_subpixels==0) {
- if((apn->p[0] == obindex) && (apn->t[0] & obtype)) {
- if(dist < apn->zmin[0]) apn->zmin[0] = dist;
- else if(dist > apn->zmax[0]) apn->zmax[0] = dist;
- apn->mask[0]|= mask;
- break;
- }
- }
-
- if(apn->t[1] == RE_NONE) {
- apn->p[1] = obindex; apn->t[1] = obtype;
- apn->zmin[1] = dist; apn->zmax[1] = dist;
- apn->mask[1] = mask;
- break;
- }
- else if(all_subpixels==0) {
- if((apn->p[1] == obindex) && (apn->t[1] & obtype)) {
- if(dist < apn->zmin[1]) apn->zmin[1] = dist;
- else if(dist > apn->zmax[1]) apn->zmax[1] = dist;
- apn->mask[1]|= mask;
- break;
- }
- }
-
- if(apn->t[2] == RE_NONE) {
- apn->p[2] = obindex; apn->t[2] = obtype;
- apn->zmin[2] = dist; apn->zmax[2] = dist;
- apn->mask[2] = mask;
- break;
- }
- else if(all_subpixels==0) {
- if((apn->p[2] == obindex) && (apn->t[2] & obtype)) {
- if(dist < apn->zmin[2]) apn->zmin[2] = dist;
- else if(dist > apn->zmax[2]) apn->zmax[2] = dist;
- apn->mask[2]|= mask;
- break;
- }
- }
-
- if(apn->t[3] == RE_NONE) {
- apn->p[3] = obindex; apn->t[3] = obtype;
- apn->zmin[3] = dist; apn->zmax[3] = dist;
- apn->mask[3] = mask;
- break;
- }
- else if(all_subpixels==0) {
- if((apn->p[3] == obindex) && (apn->t[3] & obtype)) {
- if(dist < apn->zmin[3]) apn->zmin[3] = dist;
- else if(dist > apn->zmax[3]) apn->zmax[3] = dist;
- apn->mask[3]|= mask;
- break;
- }
- }
-
- if(apn->next==0) apn->next= addpseA();
- apn= apn->next;
- }
-}
-
-/* ------------------------------------------------------------------------- */
-
-/* ------------------------------------------------------------------------- */
-
-/* This function might be helped by an end-of-list marker */
-void insertFlatObjectNoOsa(RE_APixstrExt *ap,
- int obindex,
- int obtype,
- int dist,
- int mask)
-{
- int counter=0;
-
- while(ap) {
- if(ap->t[0] == RE_NONE) {
- ap->p[0] = obindex; ap->zmin[0] = dist;
- ap->zmax[0] = dist; ap->mask[0] = mask;
- ap->t[0] = obtype;
- break;
- }
- else if(ap->t[0] & RE_SOLID) if( dist > ap->zmin[0] ) break;
-
- if(ap->t[1] == RE_NONE) {
- ap->p[1] = obindex; ap->zmin[1] = dist;
- ap->zmax[1] = dist; ap->mask[1] = mask;
- ap->t[1] = obtype;
- break;
- }
- else if(ap->t[1] & RE_SOLID) if( dist > ap->zmin[1] ) break;
-
- if(ap->t[2] == RE_NONE) {
- ap->p[2] = obindex; ap->zmin[2] = dist;
- ap->zmax[2] = dist; ap->mask[2] = mask;
- ap->t[2] = obtype;
- break;
- }
- else if(ap->t[2] & RE_SOLID) if( dist > ap->zmin[2] ) break;
-
- if(ap->t[3] == RE_NONE) {
- ap->p[3] = obindex; ap->zmin[3] = dist;
- ap->zmax[3] = dist; ap->mask[3] = mask;
- ap->t[3] = obtype;
- break;
- }
- else if(ap->t[3] & RE_SOLID) if( dist > ap->zmin[3] ) break;
-
- counter+= 4;
- if(counter > RE_MAX_FACES_PER_PIXEL) break;
-
- if(ap->next==0) ap->next= addpseA();
- ap= ap->next;
- };
-}
-
-/* ------------------------------------------------------------------------- */
-
-/* EOF */