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:
authorMiika Hamalainen <blender@miikah.org>2011-10-04 15:42:44 +0400
committerMiika Hamalainen <blender@miikah.org>2011-10-04 15:42:44 +0400
commite8bb972f3c04b00f6e813b61332c53213c12e8c4 (patch)
tree5d05e7c8421c5af4e034ff3a01ebe34a2d94b9ec /source/blender/render
parent9e9b26b8ba54227f79f97acc87893611d61b9831 (diff)
parent019dca9c54289136b34c688a048ee009e2e852ee (diff)
Merge with trunk r40782
Diffstat (limited to 'source/blender/render')
-rw-r--r--source/blender/render/intern/include/render_types.h1
-rw-r--r--source/blender/render/intern/include/rendercore.h12
-rw-r--r--source/blender/render/intern/include/shading.h4
-rw-r--r--source/blender/render/intern/raytrace/rayobject.cpp2
-rw-r--r--source/blender/render/intern/raytrace/rayobject_qbvh.cpp4
-rw-r--r--source/blender/render/intern/raytrace/rayobject_svbvh.cpp4
-rw-r--r--source/blender/render/intern/raytrace/rayobject_vbvh.cpp4
-rw-r--r--source/blender/render/intern/source/convertblender.c27
-rw-r--r--source/blender/render/intern/source/envmap.c6
-rw-r--r--source/blender/render/intern/source/pipeline.c2
-rw-r--r--source/blender/render/intern/source/pixelshading.c3
-rw-r--r--source/blender/render/intern/source/rayshade.c241
-rw-r--r--source/blender/render/intern/source/render_texture.c25
-rw-r--r--source/blender/render/intern/source/rendercore.c2
-rw-r--r--source/blender/render/intern/source/shadeinput.c8
-rw-r--r--source/blender/render/intern/source/shadeoutput.c56
-rw-r--r--source/blender/render/intern/source/strand.c4
-rw-r--r--source/blender/render/intern/source/volume_precache.c178
-rw-r--r--source/blender/render/intern/source/voxeldata.c2
-rw-r--r--source/blender/render/intern/source/zbuf.c9
20 files changed, 311 insertions, 283 deletions
diff --git a/source/blender/render/intern/include/render_types.h b/source/blender/render/intern/include/render_types.h
index 0b339d285ce..6d27c7707f0 100644
--- a/source/blender/render/intern/include/render_types.h
+++ b/source/blender/render/intern/include/render_types.h
@@ -485,7 +485,6 @@ typedef struct VolPrecachePart
int res[3];
float bbmin[3];
float voxel[3];
- int working, done;
struct Render *re;
} VolPrecachePart;
diff --git a/source/blender/render/intern/include/rendercore.h b/source/blender/render/intern/include/rendercore.h
index f9486b5d5c0..7f804c9311d 100644
--- a/source/blender/render/intern/include/rendercore.h
+++ b/source/blender/render/intern/include/rendercore.h
@@ -76,12 +76,12 @@ typedef struct PixStrMain
void calc_view_vector(float *view, float x, float y);
-float mistfactor(float zcor, float *co); /* dist and height, return alpha */
+float mistfactor(float zcor, const float co[3]); /* dist and height, return alpha */
-void renderspothalo(struct ShadeInput *shi, float *col, float alpha);
+void renderspothalo(struct ShadeInput *shi, float col[4], float alpha);
void add_halo_flare(Render *re);
-void calc_renderco_zbuf(float co[3], float *view, int z);
+void calc_renderco_zbuf(float co[3], const float view[3], int z);
void calc_renderco_ortho(float co[3], float x, float y, int z);
int count_mask(unsigned short mask);
@@ -103,9 +103,9 @@ extern void freeraytree(Render *re);
extern void makeraytree(Render *re);
struct RayObject* makeraytree_object(Render *re, ObjectInstanceRen *obi);
-extern void ray_shadow(ShadeInput *, LampRen *, float *);
-extern void ray_trace(ShadeInput *, ShadeResult *);
-extern void ray_ao(ShadeInput *, float *, float *);
+extern void ray_shadow(ShadeInput *shi, LampRen *lar, float shadfac[4]);
+extern void ray_trace(ShadeInput *shi, ShadeResult *);
+extern void ray_ao(ShadeInput *shi, float ao[3], float env[3]);
extern void init_jitter_plane(LampRen *lar);
extern void init_ao_sphere(struct World *wrld);
extern void init_render_qmcsampler(Render *re);
diff --git a/source/blender/render/intern/include/shading.h b/source/blender/render/intern/include/shading.h
index 91507ef3f98..df5578dad7a 100644
--- a/source/blender/render/intern/include/shading.h
+++ b/source/blender/render/intern/include/shading.h
@@ -96,8 +96,8 @@ void ambient_occlusion(struct ShadeInput *shi);
void environment_lighting_apply(struct ShadeInput *shi, struct ShadeResult *shr);
ListBase *get_lights(struct ShadeInput *shi);
-float lamp_get_visibility(struct LampRen *lar, const float co[3], float *lv, float *dist);
-void lamp_get_shadow(struct LampRen *lar, ShadeInput *shi, float inp, float *shadfac, int do_real);
+float lamp_get_visibility(struct LampRen *lar, const float co[3], float lv[3], float *dist);
+void lamp_get_shadow(struct LampRen *lar, ShadeInput *shi, float inp, float shadfac[4], int do_real);
float fresnel_fac(float *view, float *vn, float fresnel, float fac);
diff --git a/source/blender/render/intern/raytrace/rayobject.cpp b/source/blender/render/intern/raytrace/rayobject.cpp
index dfff35ba51a..550652560be 100644
--- a/source/blender/render/intern/raytrace/rayobject.cpp
+++ b/source/blender/render/intern/raytrace/rayobject.cpp
@@ -441,7 +441,7 @@ int RE_rayobject_intersect(RayObject *r, Isect *i)
}
else {
assert(0);
- return 0;
+ return 0;
}
}
diff --git a/source/blender/render/intern/raytrace/rayobject_qbvh.cpp b/source/blender/render/intern/raytrace/rayobject_qbvh.cpp
index 331358f727b..8fc3c938427 100644
--- a/source/blender/render/intern/raytrace/rayobject_qbvh.cpp
+++ b/source/blender/render/intern/raytrace/rayobject_qbvh.cpp
@@ -116,8 +116,8 @@ void bvh_hint_bb(Tree *tree, LCTSHint *hint, float *min, float *max)
{
//TODO renable hint support
{
- hint->size = 0;
- hint->stack[hint->size++] = (RayObject*)tree->root;
+ hint->size = 0;
+ hint->stack[hint->size++] = (RayObject*)tree->root;
}
}
/* the cast to pointer function is needed to workarround gcc bug: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=11407 */
diff --git a/source/blender/render/intern/raytrace/rayobject_svbvh.cpp b/source/blender/render/intern/raytrace/rayobject_svbvh.cpp
index a99c57ab233..0d1526fba6f 100644
--- a/source/blender/render/intern/raytrace/rayobject_svbvh.cpp
+++ b/source/blender/render/intern/raytrace/rayobject_svbvh.cpp
@@ -152,8 +152,8 @@ void bvh_hint_bb(Tree *tree, LCTSHint *hint, float *min, float *max)
{
//TODO renable hint support
{
- hint->size = 0;
- hint->stack[hint->size++] = (RayObject*)tree->root;
+ hint->size = 0;
+ hint->stack[hint->size++] = (RayObject*)tree->root;
}
}
/* the cast to pointer function is needed to workarround gcc bug: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=11407 */
diff --git a/source/blender/render/intern/raytrace/rayobject_vbvh.cpp b/source/blender/render/intern/raytrace/rayobject_vbvh.cpp
index 25eada43a4a..620477f1e70 100644
--- a/source/blender/render/intern/raytrace/rayobject_vbvh.cpp
+++ b/source/blender/render/intern/raytrace/rayobject_vbvh.cpp
@@ -154,8 +154,8 @@ void bvh_hint_bb(Tree *tree, LCTSHint *hint, float *min, float *max)
{
//TODO renable hint support
{
- hint->size = 0;
- hint->stack[hint->size++] = (RayObject*)tree->root;
+ hint->size = 0;
+ hint->stack[hint->size++] = (RayObject*)tree->root;
}
}
diff --git a/source/blender/render/intern/source/convertblender.c b/source/blender/render/intern/source/convertblender.c
index a15662f86f4..0ea0725d05d 100644
--- a/source/blender/render/intern/source/convertblender.c
+++ b/source/blender/render/intern/source/convertblender.c
@@ -1349,7 +1349,7 @@ static void particle_billboard(Render *re, ObjectRen *obr, Material *ma, Particl
int totsplit = bb->uv_split * bb->uv_split;
int tile, x, y;
/* Tile offsets */
- float uvx = 0.0f, uvy = 0.0f, uvdx = 1.0f, uvdy = 1.0f, time = 0.0f;
+ float uvx = 0.0f, uvy = 0.0f, uvdx = 1.0f, uvdy = 1.0f, time = 0.0f;
vlr= RE_findOrAddVlak(obr, obr->totvlak++);
vlr->v1= RE_findOrAddVert(obr, obr->totvert++);
@@ -4359,9 +4359,9 @@ static void finalize_render_object(Render *re, ObjectRen *obr, int timeoffset)
/* Database */
/* ------------------------------------------------------------------------- */
-static int render_object_type(int type)
+static int render_object_type(short type)
{
- return ELEM5(type, OB_FONT, OB_CURVE, OB_SURF, OB_MESH, OB_MBALL);
+ return OB_TYPE_SUPPORT_MATERIAL(type);
}
static void find_dupli_instances(Render *re, ObjectRen *obr)
@@ -4852,8 +4852,13 @@ static void database_init_objects(Render *re, unsigned int renderlay, int nolamp
* NULL is just for init */
set_dupli_tex_mat(NULL, NULL, NULL);
- for(SETLOOPER(re->scene, sce_iter, base)) {
- ob= base->object;
+ /* loop over all objects rather then using SETLOOPER because we may
+ * reference an mtex-mapped object which isnt rendered or is an
+ * empty in a dupli group. We could scan all render material/lamp/world
+ * mtex's for mapto objects but its easier just to set the
+ * 'imat' / 'imat_ren' on all and unlikely to be a performance hit
+ * See bug: [#28744] - campbell */
+ for(ob= re->main->object.first; ob; ob= ob->id.next) {
/* imat objects has to be done here, since displace can have texture using Object map-input */
mul_m4_m4m4(mat, ob->obmat, re->viewmat);
invert_m4_m4(ob->imat_ren, mat);
@@ -5021,7 +5026,7 @@ void RE_Database_FromScene(Render *re, Main *bmain, Scene *scene, unsigned int l
/* per second, per object, stats print this */
re->i.infostr= "Preparing Scene data";
re->i.cfra= scene->r.cfra;
- strncpy(re->i.scenename, scene->id.name+2, 20);
+ BLI_strncpy(re->i.scenename, scene->id.name+2, sizeof(re->i.scenename));
/* XXX add test if dbase was filled already? */
@@ -5304,11 +5309,13 @@ static void calculate_speedvector(const float vectors[2], int step, float winsq,
static float *calculate_strandsurface_speedvectors(Render *re, ObjectInstanceRen *obi, StrandSurface *mesh)
{
- float winsq= (float)re->winx*(float)re->winy, winroot= sqrt(winsq), (*winspeed)[4]; /* int's can wrap on large images */
- float ho[4], prevho[4], nextho[4], winmat[4][4], vec[2];
- int a;
-
if(mesh->co && mesh->prevco && mesh->nextco) {
+ float winsq= (float)re->winx*(float)re->winy; /* int's can wrap on large images */
+ float winroot= sqrt(winsq);
+ float (*winspeed)[4];
+ float ho[4], prevho[4], nextho[4], winmat[4][4], vec[2];
+ int a;
+
if(obi->flag & R_TRANSFORMED)
mul_m4_m4m4(winmat, obi->mat, re->winmat);
else
diff --git a/source/blender/render/intern/source/envmap.c b/source/blender/render/intern/source/envmap.c
index e2b3b23b9c9..25895b81dd7 100644
--- a/source/blender/render/intern/source/envmap.c
+++ b/source/blender/render/intern/source/envmap.c
@@ -689,9 +689,9 @@ int envmaptex(Tex *tex, float *texvec, float *dxt, float *dyt, int osatex, TexRe
env->ima= tex->ima;
if(env->ima && env->ima->ok) {
if(env->cube[1]==NULL) {
- ImBuf *ibuf= BKE_image_get_ibuf(env->ima, NULL);
- if(ibuf)
- envmap_split_ima(env, ibuf);
+ ImBuf *ibuf_ima= BKE_image_get_ibuf(env->ima, NULL);
+ if(ibuf_ima)
+ envmap_split_ima(env, ibuf_ima);
else
env->ok= 0;
}
diff --git a/source/blender/render/intern/source/pipeline.c b/source/blender/render/intern/source/pipeline.c
index 05bcc32a90a..7835ae6dcd3 100644
--- a/source/blender/render/intern/source/pipeline.c
+++ b/source/blender/render/intern/source/pipeline.c
@@ -1198,7 +1198,7 @@ Render *RE_NewRender(const char *name)
/* new render data struct */
re= MEM_callocN(sizeof(Render), "new render");
BLI_addtail(&RenderGlobal.renderlist, re);
- strncpy(re->name, name, RE_MAXNAME);
+ BLI_strncpy(re->name, name, RE_MAXNAME);
BLI_rw_mutex_init(&re->resultmutex);
}
diff --git a/source/blender/render/intern/source/pixelshading.c b/source/blender/render/intern/source/pixelshading.c
index 5c5162d268b..93038984115 100644
--- a/source/blender/render/intern/source/pixelshading.c
+++ b/source/blender/render/intern/source/pixelshading.c
@@ -226,8 +226,7 @@ static void render_lighting_halo(HaloRen *har, float col_r[3])
}
/* shadow */
- if(i> -0.41f) { /* heuristic valua! */
- shadfac= 1.0;
+ if(i> -0.41f) { /* heuristic valua! */
if(lar->shb) {
shadfac = testshadowbuf(&R, lar->shb, rco, dco, dco, inp, 0.0f);
if(shadfac==0.0f) continue;
diff --git a/source/blender/render/intern/source/rayshade.c b/source/blender/render/intern/source/rayshade.c
index e82e969d502..8fa90a51442 100644
--- a/source/blender/render/intern/source/rayshade.c
+++ b/source/blender/render/intern/source/rayshade.c
@@ -334,7 +334,6 @@ static void makeraytree_single(Render *re)
for(obi=re->instancetable.first; obi; obi=obi->next)
if(is_raytraceable(re, obi))
{
- int v;
ObjectRen *obr = obi->obr;
obs++;
@@ -344,6 +343,7 @@ static void makeraytree_single(Render *re)
}
else
{
+ int v;
for(v=0;v<obr->totvlak;v++)
{
VlakRen *vlr = obr->vlaknodes[v>>8].vlak + (v&255);
@@ -539,7 +539,7 @@ void shade_ray(Isect *is, ShadeInput *shi, ShadeResult *shr)
VlakRen *vlr= (VlakRen*)is->hit.face;
/* set up view vector */
- VECCOPY(shi->view, is->dir);
+ copy_v3_v3(shi->view, is->dir);
/* render co */
shi->co[0]= is->start[0]+is->dist*(shi->view[0]);
@@ -594,16 +594,16 @@ void shade_ray(Isect *is, ShadeInput *shi, ShadeResult *shr)
}
/* raytrace likes to separate the spec color */
- VECSUB(shr->diff, shr->combined, shr->spec);
+ sub_v3_v3v3(shr->diff, shr->combined, shr->spec);
}
}
-static int refraction(float *refract, float *n, float *view, float index)
+static int refraction(float refract[3], const float n[3], const float view[3], float index)
{
float dot, fac;
- VECCOPY(refract, view);
+ copy_v3_v3(refract, view);
dot= view[0]*n[0] + view[1]*n[1] + view[2]*n[2];
@@ -626,26 +626,26 @@ static int refraction(float *refract, float *n, float *view, float index)
return 1;
}
+static void reflection_simple(float ref[3], float n[3], const float view[3])
+{
+ const float f1= -2.0f * dot_v3v3(n, view);
+ madd_v3_v3v3fl(ref, view, n, f1);
+}
+
/* orn = original face normal */
-static void reflection(float *ref, float *n, float *view, float *orn)
+static void reflection(float ref[3], float n[3], const float view[3], const float orn[3])
{
float f1;
-
- f1= -2.0f*(n[0]*view[0]+ n[1]*view[1]+ n[2]*view[2]);
-
- ref[0]= (view[0]+f1*n[0]);
- ref[1]= (view[1]+f1*n[1]);
- ref[2]= (view[2]+f1*n[2]);
- if(orn) {
- /* test phong normals, then we should prevent vector going to the back */
- f1= ref[0]*orn[0]+ ref[1]*orn[1]+ ref[2]*orn[2];
- if(f1>0.0f) {
- f1+= .01f;
- ref[0]-= f1*orn[0];
- ref[1]-= f1*orn[1];
- ref[2]-= f1*orn[2];
- }
+ reflection_simple(ref, n, view);
+
+ /* test phong normals, then we should prevent vector going to the back */
+ f1= dot_v3v3(ref, orn);
+ if(f1>0.0f) {
+ f1+= 0.01f;
+ ref[0]-= f1*orn[0];
+ ref[1]-= f1*orn[1];
+ ref[2]-= f1*orn[2];
}
}
@@ -672,8 +672,7 @@ static void color_combine(float *result, float fac1, float fac2, float *col1, fl
static float shade_by_transmission(Isect *is, ShadeInput *shi, ShadeResult *shr)
{
- float dx, dy, dz, d, p;
-
+ float d;
if (0 == (shi->mat->mode & MA_TRANSP))
return -1;
@@ -681,10 +680,12 @@ static float shade_by_transmission(Isect *is, ShadeInput *shi, ShadeResult *shr)
d= 1.0f;
}
else {
+ float p;
+
/* shi.co[] calculated by shade_ray() */
- dx= shi->co[0] - is->start[0];
- dy= shi->co[1] - is->start[1];
- dz= shi->co[2] - is->start[2];
+ const float dx= shi->co[0] - is->start[0];
+ const float dy= shi->co[1] - is->start[1];
+ const float dz= shi->co[2] - is->start[2];
d= sqrt(dx*dx+dy*dy+dz*dz);
if (d > shi->mat->tx_limit)
d= shi->mat->tx_limit;
@@ -701,13 +702,13 @@ static float shade_by_transmission(Isect *is, ShadeInput *shi, ShadeResult *shr)
return d;
}
-static void ray_fadeout_endcolor(float *col, ShadeInput *origshi, ShadeInput *shi, ShadeResult *shr, Isect *isec, float *vec)
+static void ray_fadeout_endcolor(float col[3], ShadeInput *origshi, ShadeInput *shi, ShadeResult *shr, Isect *isec, const float vec[3])
{
/* un-intersected rays get either rendered material color or sky color */
if (origshi->mat->fadeto_mir == MA_RAYMIR_FADETOMAT) {
- VECCOPY(col, shr->combined);
+ copy_v3_v3(col, shr->combined);
} else if (origshi->mat->fadeto_mir == MA_RAYMIR_FADETOSKY) {
- VECCOPY(shi->view, vec);
+ copy_v3_v3(shi->view, vec);
normalize_v3(shi->view);
shadeSkyView(col, isec->start, shi->view, NULL, shi->thread);
@@ -715,7 +716,7 @@ static void ray_fadeout_endcolor(float *col, ShadeInput *origshi, ShadeInput *sh
}
}
-static void ray_fadeout(Isect *is, ShadeInput *shi, float *col, float *blendcol, float dist_mir)
+static void ray_fadeout(Isect *is, ShadeInput *shi, float col[3], const float blendcol[3], float dist_mir)
{
/* if fading out, linear blend against fade color */
float blendfac;
@@ -729,14 +730,14 @@ static void ray_fadeout(Isect *is, ShadeInput *shi, float *col, float *blendcol,
/* the main recursive tracer itself
* note: 'col' must be initialized */
-static void traceray(ShadeInput *origshi, ShadeResult *origshr, short depth, float *start, float *dir, float *col, ObjectInstanceRen *obi, VlakRen *vlr, int traflag)
+static void traceray(ShadeInput *origshi, ShadeResult *origshr, short depth, const float start[3], const float dir[3], float col[4], ObjectInstanceRen *obi, VlakRen *vlr, int traflag)
{
ShadeInput shi= {0};
Isect isec;
float dist_mir = origshi->mat->dist_mir;
- VECCOPY(isec.start, start);
- VECCOPY(isec.dir, dir );
+ copy_v3_v3(isec.start, start);
+ copy_v3_v3(isec.dir, dir );
isec.dist = dist_mir > 0 ? dist_mir : RE_RAYTRACE_MAXDIST;
isec.mode= RE_RAY_MIRROR;
isec.check = RE_CHECK_VLR_RENDER;
@@ -752,8 +753,8 @@ static void traceray(ShadeInput *origshi, ShadeResult *origshr, short depth, flo
float d= 1.0f;
/* for as long we don't have proper dx/dy transform for rays we copy over original */
- VECCOPY(shi.dxco, origshi->dxco);
- VECCOPY(shi.dyco, origshi->dyco);
+ copy_v3_v3(shi.dxco, origshi->dxco);
+ copy_v3_v3(shi.dyco, origshi->dyco);
shi.mask= origshi->mask;
shi.osatex= origshi->osatex;
@@ -845,7 +846,7 @@ static void traceray(ShadeInput *origshi, ShadeResult *origshr, short depth, flo
float mircol[4];
float ref[3];
- reflection(ref, shi.vn, shi.view, NULL);
+ reflection_simple(ref, shi.vn, shi.view);
traceray(origshi, origshr, depth-1, shi.co, ref, mircol, shi.obi, shi.vlr, 0);
f1= 1.0f-f;
@@ -896,7 +897,7 @@ static void traceray(ShadeInput *origshi, ShadeResult *origshr, short depth, flo
/* calc distributed planar energy */
-static void DP_energy(float *table, float *vec, int tot, float xsize, float ysize)
+static void DP_energy(float *table, float vec[2], int tot, float xsize, float ysize)
{
int x, y, a;
float *fp, force[3], result[3];
@@ -950,7 +951,7 @@ static void jitter_plane_offset(float *jitter1, float *jitter2, int tot, float s
void init_jitter_plane(LampRen *lar)
{
float *fp;
- int x, iter=12, tot= lar->ray_totsamp;
+ int x, tot= lar->ray_totsamp;
/* test if already initialized */
if(lar->jitter) return;
@@ -962,7 +963,8 @@ void init_jitter_plane(LampRen *lar)
/* if 1 sample, we leave table to be zero's */
if(tot>1) {
-
+ int iter=12;
+
/* set per-lamp fixed seed */
BLI_srandom(tot);
@@ -1125,7 +1127,7 @@ static void QMC_getSample(double *s, QMCSampler *qsa, int thread, int num)
}
/* phong weighted disc using 'blur' for exponent, centred on 0,0 */
-static void QMC_samplePhong(float *vec, QMCSampler *qsa, int thread, int num, float blur)
+static void QMC_samplePhong(float vec[3], QMCSampler *qsa, int thread, int num, float blur)
{
double s[2];
float phi, pz, sqr;
@@ -1142,7 +1144,7 @@ static void QMC_samplePhong(float *vec, QMCSampler *qsa, int thread, int num, fl
}
/* rect of edge lengths sizex, sizey, centred on 0.0,0.0 i.e. ranging from -sizex/2 to +sizey/2 */
-static void QMC_sampleRect(float *vec, QMCSampler *qsa, int thread, int num, float sizex, float sizey)
+static void QMC_sampleRect(float vec[3], QMCSampler *qsa, int thread, int num, float sizex, float sizey)
{
double s[2];
@@ -1154,7 +1156,7 @@ static void QMC_sampleRect(float *vec, QMCSampler *qsa, int thread, int num, flo
}
/* disc of radius 'radius', centred on 0,0 */
-static void QMC_sampleDisc(float *vec, QMCSampler *qsa, int thread, int num, float radius)
+static void QMC_sampleDisc(float vec[3], QMCSampler *qsa, int thread, int num, float radius)
{
double s[2];
float phi, sqr;
@@ -1170,7 +1172,7 @@ static void QMC_sampleDisc(float *vec, QMCSampler *qsa, int thread, int num, flo
}
/* uniform hemisphere sampling */
-static void QMC_sampleHemi(float *vec, QMCSampler *qsa, int thread, int num)
+static void QMC_sampleHemi(float vec[3], QMCSampler *qsa, int thread, int num)
{
double s[2];
float phi, sqr;
@@ -1187,7 +1189,7 @@ static void QMC_sampleHemi(float *vec, QMCSampler *qsa, int thread, int num)
#if 0 /* currently not used */
/* cosine weighted hemisphere sampling */
-static void QMC_sampleHemiCosine(float *vec, QMCSampler *qsa, int thread, int num)
+static void QMC_sampleHemiCosine(float vec[3], QMCSampler *qsa, int thread, int num)
{
double s[2];
float phi, sqr;
@@ -1238,10 +1240,9 @@ static void release_thread_qmcsampler(Render *UNUSED(re), int UNUSED(thread), QM
void free_render_qmcsampler(Render *re)
{
- QMCSampler *qsa, *next;
- int a;
-
if(re->qmcsamplers) {
+ QMCSampler *qsa, *next;
+ int a;
for(a=0; a<BLENDER_MAX_THREADS; a++) {
for(qsa=re->qmcsamplers[a].first; qsa; qsa=next) {
next= qsa->next;
@@ -1256,7 +1257,7 @@ void free_render_qmcsampler(Render *re)
}
}
-static int adaptive_sample_variance(int samples, float *col, float *colsq, float thresh)
+static int adaptive_sample_variance(int samples, const float col[3], const float colsq[3], float thresh)
{
float var[3], mean[3];
@@ -1306,7 +1307,7 @@ static float get_avg_speed(ShadeInput *shi)
/* ***************** main calls ************** */
-static void trace_refract(float *col, ShadeInput *shi, ShadeResult *shr)
+static void trace_refract(float col[4], ShadeInput *shi, ShadeResult *shr)
{
QMCSampler *qsa=NULL;
int samp_type;
@@ -1345,7 +1346,7 @@ static void trace_refract(float *col, ShadeInput *shi, ShadeResult *shr)
if((shi->vlr->flag & R_SMOOTH))
reflection(v_refract, shi->vn, shi->view, shi->facenor);
else
- reflection(v_refract, shi->vn, shi->view, NULL);
+ reflection_simple(v_refract, shi->vn, shi->view);
/* can't blur total external reflection */
max_samples = 1;
@@ -1366,7 +1367,7 @@ static void trace_refract(float *col, ShadeInput *shi, ShadeResult *shr)
normalize_v3(v_refract_new);
} else {
/* no blurriness, use the original normal */
- VECCOPY(v_refract_new, v_refract);
+ copy_v3_v3(v_refract_new, v_refract);
}
sampcol[0]= sampcol[1]= sampcol[2]= sampcol[3]= 0.0f;
@@ -1406,7 +1407,7 @@ static void trace_refract(float *col, ShadeInput *shi, ShadeResult *shr)
release_thread_qmcsampler(&R, shi->thread, qsa);
}
-static void trace_reflect(float *col, ShadeInput *shi, ShadeResult *shr, float fresnelfac)
+static void trace_reflect(float col[3], ShadeInput *shi, ShadeResult *shr, float fresnelfac)
{
QMCSampler *qsa=NULL;
int samp_type;
@@ -1445,7 +1446,7 @@ static void trace_reflect(float *col, ShadeInput *shi, ShadeResult *shr, float f
* if tangent shading enabled */
if (shi->mat->mode & (MA_TANGENT_V)) {
cross_v3_v3v3(orthx, shi->vn, shi->tang); // bitangent
- VECCOPY(orthy, shi->tang);
+ copy_v3_v3(orthy, shi->tang);
mul_v3_fl(orthx, samp3d[0]);
mul_v3_fl(orthy, samp3d[1]*aniso);
} else {
@@ -1460,13 +1461,13 @@ static void trace_reflect(float *col, ShadeInput *shi, ShadeResult *shr, float f
normalize_v3(v_nor_new);
} else {
/* no blurriness, use the original normal */
- VECCOPY(v_nor_new, shi->vn);
+ copy_v3_v3(v_nor_new, shi->vn);
}
if((shi->vlr->flag & R_SMOOTH))
reflection(v_reflect, v_nor_new, shi->view, shi->facenor);
else
- reflection(v_reflect, v_nor_new, shi->view, NULL);
+ reflection_simple(v_reflect, v_nor_new, shi->view);
sampcol[0]= sampcol[1]= sampcol[2]= sampcol[3]= 0.0f;
@@ -1517,7 +1518,7 @@ static void trace_reflect(float *col, ShadeInput *shi, ShadeResult *shr, float f
/* extern call from render loop */
void ray_trace(ShadeInput *shi, ShadeResult *shr)
{
- float i, f, f1, fr, fg, fb;
+ float f1, fr, fg, fb;
float mircol[4], tracol[4];
float diff[3];
int do_tra, do_mir;
@@ -1527,12 +1528,12 @@ void ray_trace(ShadeInput *shi, ShadeResult *shr)
/* raytrace mirror amd refract like to separate the spec color */
if(shi->combinedflag & SCE_PASS_SPEC)
- VECSUB(diff, shr->combined, shr->spec) /* no ; */
+ sub_v3_v3v3(diff, shr->combined, shr->spec);
else
- VECCOPY(diff, shr->combined);
+ copy_v3_v3(diff, shr->combined);
if(do_tra) {
- float olddiff[3];
+ float olddiff[3], f;
trace_refract(tracol, shi, shr);
@@ -1542,24 +1543,23 @@ void ray_trace(ShadeInput *shi, ShadeResult *shr)
fb= 1.0f+ shi->mat->filter*(shi->b-1.0f);
/* for refract pass */
- VECCOPY(olddiff, diff);
+ copy_v3_v3(olddiff, diff);
diff[0]= f*diff[0] + f1*fr*tracol[0];
diff[1]= f*diff[1] + f1*fg*tracol[1];
diff[2]= f*diff[2] + f1*fb*tracol[2];
if(shi->passflag & SCE_PASS_REFRACT)
- VECSUB(shr->refr, diff, olddiff);
+ sub_v3_v3v3(shr->refr, diff, olddiff);
if(!(shi->combinedflag & SCE_PASS_REFRACT))
- VECSUB(diff, diff, shr->refr);
+ sub_v3_v3v3(diff, diff, shr->refr);
shr->alpha= MIN2(1.0f, tracol[3]);
}
if(do_mir) {
-
- i= shi->ray_mirror*fresnel_fac(shi->view, shi->vn, shi->mat->fresnel_mir_i, shi->mat->fresnel_mir);
+ const float i= shi->ray_mirror*fresnel_fac(shi->view, shi->vn, shi->mat->fresnel_mir_i, shi->mat->fresnel_mir);
if(i!=0.0f) {
trace_reflect(mircol, shi, shr, i);
@@ -1597,12 +1597,12 @@ void ray_trace(ShadeInput *shi, ShadeResult *shr)
if(shi->combinedflag & SCE_PASS_SPEC)
VECADD(shr->combined, diff, shr->spec) /* no ; */
else
- VECCOPY(shr->combined, diff);
+ copy_v3_v3(shr->combined, diff);
}
/* color 'shadfac' passes through 'col' with alpha and filter */
/* filter is only applied on alpha defined transparent part */
-static void addAlphaLight(float *shadfac, float *col, float alpha, float filter)
+static void addAlphaLight(float shadfac[4], const float col[3], float alpha, float filter)
{
float fr, fg, fb;
@@ -1621,19 +1621,20 @@ static void ray_trace_shadow_tra(Isect *is, ShadeInput *origshi, int depth, int
{
/* ray to lamp, find first face that intersects, check alpha properties,
if it has col[3]>0.0f continue. so exit when alpha is full */
- ShadeInput shi;
- ShadeResult shr;
- float initial_dist = is->dist;
-
+ const float initial_dist = is->dist;
+
if(RE_rayobject_raycast(R.raytree, is)) {
- float d= 1.0f;
- /* we got a face */
-
- /* Warning, This is not that nice, and possibly a bit slow for every ray,
- however some variables were not initialized properly in, unless using shade_input_initialize(...), we need to do a memset */
- memset(&shi, 0, sizeof(ShadeInput));
+ /* Warning regarding initializing to zero's, This is not that nice,
+ * and possibly a bit slow for every ray, however some variables were
+ * not initialized properly in, unless using
+ * shade_input_initialize(...), we need to zero them. */
+ ShadeInput shi= {NULL};
/* end warning! - Campbell */
-
+
+ ShadeResult shr;
+
+ /* we got a face */
+
shi.depth= origshi->depth + 1; /* only used to indicate tracing */
shi.mask= origshi->mask;
shi.thread= origshi->thread;
@@ -1647,9 +1648,9 @@ static void ray_trace_shadow_tra(Isect *is, ShadeInput *origshi, int depth, int
shade_ray(is, &shi, &shr);
if (shi.mat->material_type == MA_TYPE_SURFACE) {
- if (traflag & RAY_TRA)
- d= shade_by_transmission(is, &shi, &shr);
-
+ const float d= (traflag & RAY_TRA) ?
+ shade_by_transmission(is, &shi, &shr) :
+ 1.0f;
/* mix colors based on shadfac (rgb + amount of light factor) */
addAlphaLight(col, shr.diff, shr.alpha, d*shi.mat->filter);
} else if (shi.mat->material_type == MA_TYPE_VOLUME) {
@@ -1665,7 +1666,7 @@ static void ray_trace_shadow_tra(Isect *is, ShadeInput *origshi, int depth, int
if(depth>0 && col[3]>0.0f) {
/* adapt isect struct */
- VECCOPY(is->start, shi.co);
+ copy_v3_v3(is->start, shi.co);
is->dist = initial_dist-is->dist;
is->orig.ob = shi.obi;
is->orig.face = shi.vlr;
@@ -1702,7 +1703,7 @@ static int UNUSED_FUNCTION(ray_trace_shadow_rad)(ShadeInput *ship, ShadeResult *
isec.orig.face = ship->vlr;
isec.hint = 0;
- VECCOPY(isec.start, ship->co);
+ copy_v3_v3(isec.start, ship->co);
RE_RC_INIT(isec, shi);
@@ -1710,14 +1711,14 @@ static int UNUSED_FUNCTION(ray_trace_shadow_rad)(ShadeInput *ship, ShadeResult *
counter+=3;
counter %= 768;
- VECCOPY(vec, hashvectf+counter);
+ copy_v3_v3(vec, hashvectf+counter);
if(ship->vn[0]*vec[0]+ship->vn[1]*vec[1]+ship->vn[2]*vec[2]>0.0f) {
vec[0]-= vec[0];
vec[1]-= vec[1];
vec[2]-= vec[2];
}
- VECCOPY(isec.dir, vec );
+ copy_v3_v3(isec.dir, vec );
isec.dist = RE_RAYTRACE_MAXDIST;
if(RE_rayobject_raycast(R.raytree, &isec)) {
@@ -1751,7 +1752,7 @@ static int UNUSED_FUNCTION(ray_trace_shadow_rad)(ShadeInput *ship, ShadeResult *
}
/* aolight: function to create random unit sphere vectors for total random sampling */
-static void RandomSpherical(float *v)
+static void RandomSpherical(float v[3])
{
float r;
v[2] = 2.f*BLI_frand()-1.f;
@@ -1765,7 +1766,7 @@ static void RandomSpherical(float *v)
}
/* calc distributed spherical energy */
-static void DS_energy(float *sphere, int tot, float *vec)
+static void DS_energy(float *sphere, int tot, float vec[3])
{
float *fp, fac, force[3], res[3];
int a;
@@ -1863,13 +1864,15 @@ static float *sphere_sampler(int type, int resol, int thread, int xs, int ys, in
}
else {
float *sphere;
- float cosfi, sinfi, cost, sint;
- float ang, *vec1;
- int a;
+ float *vec1;
// returns table if xs and ys were equal to last call, and not resetting
sphere= (reset)? NULL: threadsafe_table_sphere(1, thread, xs, ys, tot);
if(sphere==NULL) {
+ float cosfi, sinfi, cost, sint;
+ float ang;
+ int a;
+
sphere= threadsafe_table_sphere(0, thread, xs, ys, tot);
// random rotation
@@ -1890,7 +1893,7 @@ static float *sphere_sampler(int type, int resol, int thread, int xs, int ys, in
}
}
-static void ray_ao_qmc(ShadeInput *shi, float *ao, float *env)
+static void ray_ao_qmc(ShadeInput *shi, float ao[3], float env[3])
{
Isect isec;
RayHint point_hint;
@@ -1924,7 +1927,7 @@ static void ray_ao_qmc(ShadeInput *shi, float *ao, float *env)
isec.mode= (R.wrld.aomode & WO_AODIST)?RE_RAY_SHADOW_TRA:RE_RAY_SHADOW;
isec.lay= -1;
- VECCOPY(isec.start, shi->co);
+ copy_v3_v3(isec.start, shi->co);
RE_rayobject_hint_bb( R.raytree, &point_hint, isec.start, isec.start );
isec.hint = &point_hint;
@@ -1943,10 +1946,10 @@ static void ray_ao_qmc(ShadeInput *shi, float *ao, float *env)
}
if(shi->vlr->flag & R_SMOOTH) {
- VECCOPY(nrm, shi->vn);
+ copy_v3_v3(nrm, shi->vn);
}
else {
- VECCOPY(nrm, shi->facenor);
+ copy_v3_v3(nrm, shi->facenor);
}
ortho_basis_v3v3_v3( up, side,nrm);
@@ -1990,7 +1993,7 @@ static void ray_ao_qmc(ShadeInput *shi, float *ao, float *env)
}
else if(envcolor!=WO_AOPLAIN) {
float skycol[4];
- float skyfac, view[3];
+ float view[3];
view[0]= -dir[0];
view[1]= -dir[1];
@@ -1998,7 +2001,7 @@ static void ray_ao_qmc(ShadeInput *shi, float *ao, float *env)
normalize_v3(view);
if(envcolor==WO_AOSKYCOL) {
- skyfac= 0.5f*(1.0f+view[0]*R.grvec[0]+ view[1]*R.grvec[1]+ view[2]*R.grvec[2]);
+ const float skyfac= 0.5f*(1.0f+view[0]*R.grvec[0]+ view[1]*R.grvec[1]+ view[2]*R.grvec[2]);
env[0]+= (1.0f-skyfac)*R.wrld.horr + skyfac*R.wrld.zenr;
env[1]+= (1.0f-skyfac)*R.wrld.horg + skyfac*R.wrld.zeng;
env[2]+= (1.0f-skyfac)*R.wrld.horb + skyfac*R.wrld.zenb;
@@ -2039,7 +2042,7 @@ static void ray_ao_qmc(ShadeInput *shi, float *ao, float *env)
}
/* extern call from shade_lamp_loop, ambient occlusion calculus */
-static void ray_ao_spheresamp(ShadeInput *shi, float *ao, float *env)
+static void ray_ao_spheresamp(ShadeInput *shi, float ao[3], float env[3])
{
Isect isec;
RayHint point_hint;
@@ -2063,7 +2066,7 @@ static void ray_ao_spheresamp(ShadeInput *shi, float *ao, float *env)
isec.mode= (R.wrld.aomode & WO_AODIST)?RE_RAY_SHADOW_TRA:RE_RAY_SHADOW;
isec.lay= -1;
- VECCOPY(isec.start, shi->co);
+ copy_v3_v3(isec.start, shi->co);
RE_rayobject_hint_bb( R.raytree, &point_hint, isec.start, isec.start );
isec.hint = &point_hint;
@@ -2128,7 +2131,7 @@ static void ray_ao_spheresamp(ShadeInput *shi, float *ao, float *env)
}
else if(envcolor!=WO_AOPLAIN) {
float skycol[4];
- float fac, view[3];
+ float view[3];
view[0]= -vec[0];
view[1]= -vec[1];
@@ -2136,7 +2139,7 @@ static void ray_ao_spheresamp(ShadeInput *shi, float *ao, float *env)
normalize_v3(view);
if(envcolor==WO_AOSKYCOL) {
- fac= 0.5f*(1.0f+view[0]*R.grvec[0]+ view[1]*R.grvec[1]+ view[2]*R.grvec[2]);
+ const float fac= 0.5f*(1.0f+view[0]*R.grvec[0]+ view[1]*R.grvec[1]+ view[2]*R.grvec[2]);
env[0]+= (1.0f-fac)*R.wrld.horr + fac*R.wrld.zenr;
env[1]+= (1.0f-fac)*R.wrld.horg + fac*R.wrld.zeng;
env[2]+= (1.0f-fac)*R.wrld.horb + fac*R.wrld.zenb;
@@ -2167,7 +2170,7 @@ static void ray_ao_spheresamp(ShadeInput *shi, float *ao, float *env)
copy_v3_v3(env, ao);
}
-void ray_ao(ShadeInput *shi, float *ao, float *env)
+void ray_ao(ShadeInput *shi, float ao[3], float env[3])
{
/* Unfortunately, the unusual way that the sphere sampler calculates roughly twice as many
* samples as are actually traced, and skips them based on bias and OSA settings makes it very difficult
@@ -2214,12 +2217,12 @@ static void ray_shadow_jittered_coords(ShadeInput *shi, int max, float jitco[RE_
*totjitco= tot;
}
else {
- VECCOPY(jitco[0], shi->co);
+ copy_v3_v3(jitco[0], shi->co);
*totjitco= 1;
}
}
-static void ray_shadow_qmc(ShadeInput *shi, LampRen *lar, float *lampco, float *shadfac, Isect *isec)
+static void ray_shadow_qmc(ShadeInput *shi, LampRen *lar, const float lampco[3], float shadfac[4], Isect *isec)
{
QMCSampler *qsa=NULL;
int samples=0;
@@ -2276,7 +2279,7 @@ static void ray_shadow_qmc(ShadeInput *shi, LampRen *lar, float *lampco, float *
isec->hint = &bb_hint;
isec->check = RE_CHECK_VLR_RENDER;
isec->skip = RE_SKIP_VLR_NEIGHBOUR;
- VECCOPY(vec, lampco);
+ copy_v3_v3(vec, lampco);
while (samples < max_samples) {
@@ -2294,9 +2297,7 @@ static void ray_shadow_qmc(ShadeInput *shi, LampRen *lar, float *lampco, float *
float ru[3], rv[3], v[3], s[3];
/* calc tangent plane vectors */
- v[0] = co[0] - lampco[0];
- v[1] = co[1] - lampco[1];
- v[2] = co[2] - lampco[2];
+ sub_v3_v3v3(v, co, lampco);
normalize_v3(v);
ortho_basis_v3v3_v3( ru, rv,v);
@@ -2308,7 +2309,7 @@ static void ray_shadow_qmc(ShadeInput *shi, LampRen *lar, float *lampco, float *
s[1] = samp3d[0]*ru[1] + samp3d[1]*rv[1];
s[2] = samp3d[0]*ru[2] + samp3d[1]*rv[2];
- VECCOPY(samp3d, s);
+ copy_v3_v3(samp3d, s);
}
else {
/* sampling, returns quasi-random vector in [sizex,sizey]^2 plane */
@@ -2321,7 +2322,7 @@ static void ray_shadow_qmc(ShadeInput *shi, LampRen *lar, float *lampco, float *
end[1] = vec[1]+samp3d[1];
end[2] = vec[2]+samp3d[2];
} else {
- VECCOPY(end, vec);
+ copy_v3_v3(end, vec);
}
if(shi->strand) {
@@ -2329,7 +2330,7 @@ static void ray_shadow_qmc(ShadeInput *shi, LampRen *lar, float *lampco, float *
float jitbias= 0.5f*(len_v3(shi->dxco) + len_v3(shi->dyco));
float v[3];
- VECSUB(v, co, end);
+ sub_v3_v3v3(v, co, end);
normalize_v3(v);
co[0] -= jitbias*v[0];
@@ -2337,7 +2338,7 @@ static void ray_shadow_qmc(ShadeInput *shi, LampRen *lar, float *lampco, float *
co[2] -= jitbias*v[2];
}
- VECCOPY(isec->start, co);
+ copy_v3_v3(isec->start, co);
isec->dir[0] = end[0]-isec->start[0];
isec->dir[1] = end[1]-isec->start[1];
isec->dir[2] = end[2]-isec->start[2];
@@ -2393,7 +2394,7 @@ static void ray_shadow_qmc(ShadeInput *shi, LampRen *lar, float *lampco, float *
release_thread_qmcsampler(&R, shi->thread, qsa);
}
-static void ray_shadow_jitter(ShadeInput *shi, LampRen *lar, float *lampco, float *shadfac, Isect *isec)
+static void ray_shadow_jitter(ShadeInput *shi, LampRen *lar, const float lampco[3], float shadfac[4], Isect *isec)
{
/* area soft shadow */
float *jitlamp;
@@ -2416,7 +2417,7 @@ static void ray_shadow_jitter(ShadeInput *shi, LampRen *lar, float *lampco, floa
if(a==4) mask |= (mask>>4)|(mask>>8);
else if(a==9) mask |= (mask>>9);
- VECCOPY(isec->start, shi->co);
+ copy_v3_v3(isec->start, shi->co);
isec->orig.ob = shi->obi;
isec->orig.face = shi->vlr;
RE_rayobject_hint_bb( R.raytree, &point_hint, isec->start, isec->start );
@@ -2477,7 +2478,7 @@ static void ray_shadow_jitter(ShadeInput *shi, LampRen *lar, float *lampco, floa
}
}
/* extern call from shade_lamp_loop */
-void ray_shadow(ShadeInput *shi, LampRen *lar, float *shadfac)
+void ray_shadow(ShadeInput *shi, LampRen *lar, float shadfac[4])
{
Isect isec;
float lampco[3];
@@ -2520,7 +2521,7 @@ void ray_shadow(ShadeInput *shi, LampRen *lar, float *shadfac)
lampco[2]= shi->co[2] - R.maxdist*lar->vec[2];
}
else {
- VECCOPY(lampco, lar->co);
+ copy_v3_v3(lampco, lar->co);
}
if (ELEM(lar->ray_samp_method, LA_SAMP_HALTON, LA_SAMP_HAMMERSLEY)) {
@@ -2536,8 +2537,8 @@ void ray_shadow(ShadeInput *shi, LampRen *lar, float *shadfac)
shadfac[3]= 1.0f; // 1.0=full light
/* set up isec.dir */
- VECCOPY(isec.start, shi->co);
- VECSUB(isec.dir, lampco, isec.start);
+ copy_v3_v3(isec.start, shi->co);
+ sub_v3_v3v3(isec.dir, lampco, isec.start);
isec.dist = normalize_v3(isec.dir);
if(isec.mode==RE_RAY_SHADOW_TRA) {
@@ -2545,7 +2546,7 @@ void ray_shadow(ShadeInput *shi, LampRen *lar, float *shadfac)
float col[4] = {1.0f, 1.0f, 1.0f, 1.0f};
ray_trace_shadow_tra(&isec, shi, DEPTH_SHADOW_TRA, 0, col);
- QUATCOPY(shadfac, col);
+ copy_v4_v4(shadfac, col);
}
else if(RE_rayobject_raycast(R.raytree, &isec))
shadfac[3]= 0.0f;
@@ -2584,15 +2585,15 @@ static void ray_translucent(ShadeInput *shi, LampRen *lar, float *distfac, float
lampco[2]= shi->co[2] - RE_RAYTRACE_MAXDIST*lar->vec[2];
}
else {
- VECCOPY(lampco, lar->co);
+ copy_v3_v3(lampco, lar->co);
}
isec.orig.ob = shi->obi;
isec.orig.face = shi->vlr;
/* set up isec.dir */
- VECCOPY(isec.start, shi->co);
- VECCOPY(isec.end, lampco);
+ copy_v3_v3(isec.start, shi->co);
+ copy_v3_v3(isec.end, lampco);
if(RE_rayobject_raycast(R.raytree, &isec)) {
/* we got a face */
diff --git a/source/blender/render/intern/source/render_texture.c b/source/blender/render/intern/source/render_texture.c
index 2b04a3520e8..2d9ce24b46c 100644
--- a/source/blender/render/intern/source/render_texture.c
+++ b/source/blender/render/intern/source/render_texture.c
@@ -747,7 +747,7 @@ static int plugintex(Tex *tex, float *texvec, float *dxt, float *dyt, int osatex
{
PluginTex *pit;
int rgbnor=0;
- float result[ 8 ];
+ float result[8]= {0.0f};
texres->tin= 0.0;
@@ -1748,7 +1748,7 @@ static int compatible_bump_compute(CompatibleBump *compat_bump, ShadeInput *shi,
TexResult ttexr = {0, 0, 0, 0, 0, texres->talpha, NULL}; // temp TexResult
float tco[3], texv[3], cd, ud, vd, du, dv, idu, idv;
const int fromrgb = ((tex->type == TEX_IMAGE) || ((tex->flag & TEX_COLORBAND)!=0));
- const float bf = 0.04f*Tnor*mtex->norfac;
+ const float bf = -0.04f*Tnor*mtex->norfac;
int rgbnor;
// disable internal bump eval
float* nvec = texres->nor;
@@ -1904,8 +1904,17 @@ static int ntap_bump_compute(NTapBump *ntap_bump, ShadeInput *shi, MTex *mtex, T
TexResult ttexr = {0, 0, 0, 0, 0, texres->talpha, NULL}; // temp TexResult
const int fromrgb = ((tex->type == TEX_IMAGE) || ((tex->flag & TEX_COLORBAND)!=0));
- float Hscale = Tnor*mtex->norfac;
+
+ // The negate on Hscale is done because the
+ // normal in the renderer points inward which corresponds
+ // to inverting the bump map. The normals are generated
+ // this way in calc_vertexnormals(). Should this ever change
+ // this negate must be removed.
+ float Hscale = -Tnor*mtex->norfac;
+
int dimx=512, dimy=512;
+ const int imag_tspace_dimension_x = 1024; // only used for texture space variant
+ float aspect = 1.0f;
// 2 channels for 2D texture and 3 for 3D textures.
const int nr_channels = (mtex->texco == TEXCO_UV)? 2 : 3;
@@ -1938,6 +1947,7 @@ static int ntap_bump_compute(NTapBump *ntap_bump, ShadeInput *shi, MTex *mtex, T
if (ibuf) {
dimx = ibuf->x;
dimy = ibuf->y;
+ aspect = ((float) dimy) / dimx;
}
}
@@ -2111,12 +2121,13 @@ static int ntap_bump_compute(NTapBump *ntap_bump, ShadeInput *shi, MTex *mtex, T
if(tex->ima) {
// crazy hack solution that gives results similar to normal mapping - part 2
float vec[2];
+ const float imag_tspace_dimension_y = aspect*imag_tspace_dimension_x;
- vec[0] = dimx*dxt[0];
- vec[1] = dimy*dxt[1];
+ vec[0] = imag_tspace_dimension_x*dxt[0];
+ vec[1] = imag_tspace_dimension_y*dxt[1];
dHdx *= 1.0f/len_v2(vec);
- vec[0] = dimx*dyt[0];
- vec[1] = dimy*dyt[1];
+ vec[0] = imag_tspace_dimension_x*dyt[0];
+ vec[1] = imag_tspace_dimension_y*dyt[1];
dHdy *= 1.0f/len_v2(vec);
}
}
diff --git a/source/blender/render/intern/source/rendercore.c b/source/blender/render/intern/source/rendercore.c
index bc5e7f23e21..fd824cee8a4 100644
--- a/source/blender/render/intern/source/rendercore.c
+++ b/source/blender/render/intern/source/rendercore.c
@@ -142,7 +142,7 @@ void calc_renderco_ortho(float co[3], float x, float y, int z)
co[2]= R.winmat[3][2]/( R.winmat[2][3]*zco - R.winmat[2][2] );
}
-void calc_renderco_zbuf(float co[3], float *view, int z)
+void calc_renderco_zbuf(float co[3], const float view[3], int z)
{
float fac, zco;
diff --git a/source/blender/render/intern/source/shadeinput.c b/source/blender/render/intern/source/shadeinput.c
index 44aa227fe4c..f3e5fc63bda 100644
--- a/source/blender/render/intern/source/shadeinput.c
+++ b/source/blender/render/intern/source/shadeinput.c
@@ -1369,20 +1369,18 @@ void shade_sample_initialize(ShadeSample *ssamp, RenderPart *pa, RenderLayer *rl
/* Do AO or (future) GI */
void shade_samples_do_AO(ShadeSample *ssamp)
{
- ShadeInput *shi;
- int sample;
-
if(!(R.r.mode & R_SHADOW))
return;
if(!(R.r.mode & R_RAYTRACE) && !(R.wrld.ao_gather_method == WO_AOGATHER_APPROX))
return;
if(R.wrld.mode & (WO_AMB_OCC|WO_ENV_LIGHT|WO_INDIRECT_LIGHT)) {
- shi= &ssamp->shi[0];
+ ShadeInput *shi= &ssamp->shi[0];
+ int sample;
if(((shi->passflag & SCE_PASS_COMBINED) && (shi->combinedflag & (SCE_PASS_AO|SCE_PASS_ENVIRONMENT|SCE_PASS_INDIRECT)))
|| (shi->passflag & (SCE_PASS_AO|SCE_PASS_ENVIRONMENT|SCE_PASS_INDIRECT)))
- for(sample=0, shi= ssamp->shi; sample<ssamp->tot; shi++, sample++)
+ for(sample=0; sample<ssamp->tot; shi++, sample++)
if(!(shi->mode & MA_SHLESS))
ambient_occlusion(shi); /* stores in shi->ao[] */
}
diff --git a/source/blender/render/intern/source/shadeoutput.c b/source/blender/render/intern/source/shadeoutput.c
index 274c9bdc424..0056b073c81 100644
--- a/source/blender/render/intern/source/shadeoutput.c
+++ b/source/blender/render/intern/source/shadeoutput.c
@@ -119,7 +119,7 @@ static void fogcolor(float *colf, float *rco, float *view)
#endif
/* zcor is distance, co the 3d coordinate in eye space, return alpha */
-float mistfactor(float zcor, float *co)
+float mistfactor(float zcor, float const co[3])
{
float fac, hi;
@@ -162,8 +162,7 @@ static void spothalo(struct LampRen *lar, ShadeInput *shi, float *intens)
double t0, t1 = 0.0f, t2= 0.0f, t3;
float p1[3], p2[3], ladist, maxz = 0.0f, maxy = 0.0f, haint;
int snijp, doclip=1, use_yco=0;
- int ok1=0, ok2=0;
-
+
*intens= 0.0f;
haint= lar->haint;
@@ -243,6 +242,8 @@ static void spothalo(struct LampRen *lar, ShadeInput *shi, float *intens)
}
}
if(snijp==2) {
+ int ok1=0, ok2=0;
+
/* sort */
if(t1>t2) {
a= t1; t1= t2; t2= a;
@@ -345,7 +346,7 @@ static void spothalo(struct LampRen *lar, ShadeInput *shi, float *intens)
}
}
-void renderspothalo(ShadeInput *shi, float *col, float alpha)
+void renderspothalo(ShadeInput *shi, float col[4], float alpha)
{
ListBase *lights;
GroupObject *go;
@@ -726,7 +727,7 @@ static float Toon_Diff( float *n, float *l, float *UNUSED(v), float size, float
/* in latter case, only last multiplication uses 'nl' */
static float OrenNayar_Diff(float nl, float *n, float *l, float *v, float rough )
{
- float i/*, nh*/, nv, vh, realnl, h[3];
+ float i/*, nh*/, nv /*, vh */, realnl, h[3];
float a, b, t, A, B;
float Lit_A, View_A, Lit_B[3], View_B[3];
@@ -745,8 +746,8 @@ static float OrenNayar_Diff(float nl, float *n, float *l, float *v, float rough
if(realnl<=0.0f) return 0.0f;
if(nl<0.0f) return 0.0f; /* value from area light */
- vh= v[0]*h[0]+v[1]*h[1]+v[2]*h[2]; /* Dot product between view vector and halfway vector */
- if(vh<=0.0f) vh= 0.0f;
+ /* vh= v[0]*h[0]+v[1]*h[1]+v[2]*h[2]; */ /* Dot product between view vector and halfway vector */
+ /* if(vh<=0.0f) vh= 0.0f; */
Lit_A = saacos(realnl);
View_A = saacos( nv );
@@ -897,12 +898,11 @@ void shade_color(ShadeInput *shi, ShadeResult *shr)
static void ramp_diffuse_result(float *diff, ShadeInput *shi)
{
Material *ma= shi->mat;
- float col[4], fac=0;
+ float col[4];
if(ma->ramp_col) {
if(ma->rampin_col==MA_RAMP_IN_RESULT) {
-
- fac= 0.3f*diff[0] + 0.58f*diff[1] + 0.12f*diff[2];
+ float fac= 0.3f*diff[0] + 0.58f*diff[1] + 0.12f*diff[2];
do_colorband(ma->ramp_col, fac, col);
/* blending method */
@@ -917,8 +917,7 @@ static void ramp_diffuse_result(float *diff, ShadeInput *shi)
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;
-
+
if(ma->ramp_col && (ma->mode & MA_RAMP_COL)) {
/* MA_RAMP_IN_RESULT is exceptional */
@@ -929,6 +928,9 @@ static void add_to_diffuse(float *diff, ShadeInput *shi, float is, float r, floa
diff[2] += b * shi->b;
}
else {
+ float colt[3], col[4];
+ float fac;
+
/* input */
switch(ma->rampin_col) {
case MA_RAMP_IN_ENERGY:
@@ -940,6 +942,9 @@ static void add_to_diffuse(float *diff, ShadeInput *shi, float is, float r, floa
case MA_RAMP_IN_NOR:
fac= shi->view[0]*shi->vn[0] + shi->view[1]*shi->vn[1] + shi->view[2]*shi->vn[2];
break;
+ default:
+ fac= 0.0f;
+ break;
}
do_colorband(ma->ramp_col, fac, col);
@@ -968,11 +973,11 @@ static void add_to_diffuse(float *diff, ShadeInput *shi, float is, float r, floa
static void ramp_spec_result(float *specr, float *specg, float *specb, ShadeInput *shi)
{
Material *ma= shi->mat;
- float col[4];
- float fac;
-
+
if(ma->ramp_spec && (ma->rampin_spec==MA_RAMP_IN_RESULT)) {
- fac= 0.3f*(*specr) + 0.58f*(*specg) + 0.12f*(*specb);
+ float col[4];
+ float fac= 0.3f*(*specr) + 0.58f*(*specg) + 0.12f*(*specb);
+
do_colorband(ma->ramp_spec, fac, col);
/* blending method */
@@ -984,19 +989,19 @@ static void ramp_spec_result(float *specr, float *specg, float *specb, ShadeInpu
}
/* is = dot product shade, t = spec energy */
-static 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[3])
{
Material *ma= shi->mat;
- float col[4];
- float fac=0.0f;
-
+
spec[0]= shi->specr;
spec[1]= shi->specg;
spec[2]= shi->specb;
/* MA_RAMP_IN_RESULT is exception */
if(ma->ramp_spec && (ma->rampin_spec!=MA_RAMP_IN_RESULT)) {
-
+ float fac;
+ float col[4];
+
/* input */
switch(ma->rampin_spec) {
case MA_RAMP_IN_ENERGY:
@@ -1008,6 +1013,9 @@ static void do_specular_ramp(ShadeInput *shi, float is, float t, float *spec)
case MA_RAMP_IN_NOR:
fac= shi->view[0]*shi->vn[0] + shi->view[1]*shi->vn[1] + shi->view[2]*shi->vn[2];
break;
+ default:
+ fac= 0.0f;
+ break;
}
do_colorband(ma->ramp_spec, fac, col);
@@ -1092,7 +1100,7 @@ static void indirect_lighting_apply(ShadeInput *shi, ShadeResult *shr)
}
/* result written in shadfac */
-void lamp_get_shadow(LampRen *lar, ShadeInput *shi, float inp, float *shadfac, int do_real)
+void lamp_get_shadow(LampRen *lar, ShadeInput *shi, float inp, float shadfac[4], int do_real)
{
LampShadowSubSample *lss= &(lar->shadsamp[shi->thread].s[shi->sample]);
@@ -1121,7 +1129,7 @@ void lamp_get_shadow(LampRen *lar, ShadeInput *shi, float inp, float *shadfac, i
}
/* lampdistance and spot angle, writes in lv and dist */
-float lamp_get_visibility(LampRen *lar, float *co, float *lv, float *dist)
+float lamp_get_visibility(LampRen *lar, const float co[3], float lv[3], float *dist)
{
if(lar->type==LA_SUN || lar->type==LA_HEMI) {
*dist= 1.0f;
@@ -1627,7 +1635,7 @@ static void shade_lamp_loop_only_shadow(ShadeInput *shi, ShadeResult *shr)
}
/* let's map negative light as if it mirrors positive light, otherwise negative values disappear */
-static void wrld_exposure_correct(float *diff)
+static void wrld_exposure_correct(float diff[3])
{
diff[0]= R.wrld.linfac*(1.0f-exp( diff[0]*R.wrld.logfac) );
diff --git a/source/blender/render/intern/source/strand.c b/source/blender/render/intern/source/strand.c
index 840e5444ff0..15226493977 100644
--- a/source/blender/render/intern/source/strand.c
+++ b/source/blender/render/intern/source/strand.c
@@ -92,7 +92,7 @@ void strand_eval_point(StrandSegment *sseg, StrandPoint *spoint)
Material *ma;
StrandBuffer *strandbuf;
float *simplify;
- float p[4][3], data[4], cross[3], crosslen, w, dx, dy, t;
+ float p[4][3], data[4], cross[3], w, dx, dy, t;
int type;
strandbuf= sseg->buffer;
@@ -164,7 +164,7 @@ void strand_eval_point(StrandSegment *sseg, StrandPoint *spoint)
if(w > 0.0f) {
if(strandbuf->flag & R_STRAND_B_UNITS) {
- crosslen= len_v3(cross);
+ const float crosslen= len_v3(cross);
w= 2.0f*crosslen*strandbuf->minwidth/w;
if(spoint->width < w) {
diff --git a/source/blender/render/intern/source/volume_precache.c b/source/blender/render/intern/source/volume_precache.c
index 18132c4a7f3..d6cfcee4ac9 100644
--- a/source/blender/render/intern/source/volume_precache.c
+++ b/source/blender/render/intern/source/volume_precache.c
@@ -477,6 +477,11 @@ static void *vol_precache_part_test(void *data)
}
#endif
+typedef struct VolPrecacheQueue {
+ ThreadQueue *work;
+ ThreadQueue *done;
+} VolPrecacheQueue;
+
/* Iterate over the 3d voxel grid, and fill the voxels with scattering information
*
* It's stored in memory as 3 big float grids next to each other, one for each RGB channel.
@@ -485,58 +490,65 @@ static void *vol_precache_part_test(void *data)
*/
static void *vol_precache_part(void *data)
{
- VolPrecachePart *pa = (VolPrecachePart *)data;
- ObjectInstanceRen *obi = pa->obi;
- RayObject *tree = pa->tree;
- ShadeInput *shi = pa->shi;
- float scatter_col[3] = {0.f, 0.f, 0.f};
- float co[3], cco[3], view[3];
- int x, y, z, i;
- int res[3];
-
- res[0]= pa->res[0];
- res[1]= pa->res[1];
- res[2]= pa->res[2];
-
- for (z= pa->minz; z < pa->maxz; z++) {
- co[2] = pa->bbmin[2] + (pa->voxel[2] * (z + 0.5f));
-
- for (y= pa->miny; y < pa->maxy; y++) {
- co[1] = pa->bbmin[1] + (pa->voxel[1] * (y + 0.5f));
+ VolPrecacheQueue *queue = (VolPrecacheQueue*)data;
+ VolPrecachePart *pa;
+
+ while ((pa = BLI_thread_queue_pop(queue->work))) {
+ ObjectInstanceRen *obi = pa->obi;
+ RayObject *tree = pa->tree;
+ ShadeInput *shi = pa->shi;
+ float scatter_col[3] = {0.f, 0.f, 0.f};
+ float co[3], cco[3], view[3];
+ int x, y, z, i;
+ int res[3];
+
+ if (pa->re->test_break && pa->re->test_break(pa->re->tbh))
+ break;
+
+ res[0]= pa->res[0];
+ res[1]= pa->res[1];
+ res[2]= pa->res[2];
+
+ for (z= pa->minz; z < pa->maxz; z++) {
+ co[2] = pa->bbmin[2] + (pa->voxel[2] * (z + 0.5f));
- for (x=pa->minx; x < pa->maxx; x++) {
- co[0] = pa->bbmin[0] + (pa->voxel[0] * (x + 0.5f));
-
- if (pa->re->test_break && pa->re->test_break(pa->re->tbh))
- break;
+ for (y= pa->miny; y < pa->maxy; y++) {
+ co[1] = pa->bbmin[1] + (pa->voxel[1] * (y + 0.5f));
- /* convert from world->camera space for shading */
- mul_v3_m4v3(cco, pa->viewmat, co);
-
- i= V_I(x, y, z, res);
+ for (x=pa->minx; x < pa->maxx; x++) {
+ co[0] = pa->bbmin[0] + (pa->voxel[0] * (x + 0.5f));
+
+ if (pa->re->test_break && pa->re->test_break(pa->re->tbh))
+ break;
+
+ /* convert from world->camera space for shading */
+ mul_v3_m4v3(cco, pa->viewmat, co);
+
+ i= V_I(x, y, z, res);
+
+ // don't bother if the point is not inside the volume mesh
+ if (!point_inside_obi(tree, obi, cco)) {
+ obi->volume_precache->data_r[i] = -1.0f;
+ obi->volume_precache->data_g[i] = -1.0f;
+ obi->volume_precache->data_b[i] = -1.0f;
+ continue;
+ }
+
+ copy_v3_v3(view, cco);
+ normalize_v3(view);
+ vol_get_scattering(shi, scatter_col, cco, view);
- // don't bother if the point is not inside the volume mesh
- if (!point_inside_obi(tree, obi, cco)) {
- obi->volume_precache->data_r[i] = -1.0f;
- obi->volume_precache->data_g[i] = -1.0f;
- obi->volume_precache->data_b[i] = -1.0f;
- continue;
+ obi->volume_precache->data_r[i] = scatter_col[0];
+ obi->volume_precache->data_g[i] = scatter_col[1];
+ obi->volume_precache->data_b[i] = scatter_col[2];
+
}
-
- copy_v3_v3(view, cco);
- normalize_v3(view);
- vol_get_scattering(shi, scatter_col, cco, view);
-
- obi->volume_precache->data_r[i] = scatter_col[0];
- obi->volume_precache->data_g[i] = scatter_col[1];
- obi->volume_precache->data_b[i] = scatter_col[2];
-
}
}
+
+ BLI_thread_queue_push(queue->done, pa);
}
- pa->done = 1;
-
return NULL;
}
@@ -602,9 +614,6 @@ static void precache_init_parts(Render *re, RayObject *tree, ShadeInput *shi, Ob
minz = z * sizez;
maxz = minz + sizez;
maxz = (maxz>res[2])?res[2]:maxz;
-
- pa->done = 0;
- pa->working = 0;
pa->re = re;
pa->num = i;
@@ -630,21 +639,6 @@ static void precache_init_parts(Render *re, RayObject *tree, ShadeInput *shi, Ob
}
}
-static VolPrecachePart *precache_get_new_part(Render *re)
-{
- VolPrecachePart *pa, *nextpa=NULL;
-
- for (pa = re->volume_precache_parts.first; pa; pa=pa->next)
- {
- if (pa->done==0 && pa->working==0) {
- nextpa = pa;
- break;
- }
- }
-
- return nextpa;
-}
-
/* calculate resolution from bounding box in world space */
static int precache_resolution(Render *re, VolumePrecache *vp, ObjectInstanceRen *obi, int res)
{
@@ -678,14 +672,15 @@ static int precache_resolution(Render *re, VolumePrecache *vp, ObjectInstanceRen
static void vol_precache_objectinstance_threads(Render *re, ObjectInstanceRen *obi, Material *ma)
{
VolumePrecache *vp;
- VolPrecachePart *nextpa, *pa;
+ VolPrecachePart *pa;
RayObject *tree;
ShadeInput shi;
ListBase threads;
+ VolPrecacheQueue queue;
int parts[3] = {1, 1, 1}, totparts;
- int caching=1, counter=0;
- int totthread = re->r.threads;
+ int counter=0;
+ int totthread = re->r.threads, thread;
double time, lasttime= PIL_check_seconds_timer();
@@ -718,34 +713,29 @@ static void vol_precache_objectinstance_threads(Render *re, ObjectInstanceRen *o
precache_init_parts(re, tree, &shi, obi, totthread, parts);
totparts = parts[0] * parts[1] * parts[2];
+
+ /* setup work and done queues */
+ queue.work = BLI_thread_queue_init();
+ queue.done = BLI_thread_queue_init();
+ BLI_thread_queue_nowait(queue.work);
+
+ for(pa= re->volume_precache_parts.first; pa; pa= pa->next)
+ BLI_thread_queue_push(queue.work, pa);
+ /* launch threads */
BLI_init_threads(&threads, vol_precache_part, totthread);
+
+ for(thread= 0; thread<totthread; thread++)
+ BLI_insert_thread(&threads, &queue);
- while(caching) {
+ /* loop waiting for work to be done */
+ while(counter < totparts) {
+ if(re->test_break && re->test_break(re->tbh))
+ break;
- if(BLI_available_threads(&threads) && !(re->test_break(re->tbh))) {
- nextpa = precache_get_new_part(re);
- if (nextpa) {
- nextpa->working = 1;
- BLI_insert_thread(&threads, nextpa);
- }
- }
- else PIL_sleep_ms(50);
+ if(BLI_thread_queue_pop_timeout(queue.done, 50))
+ counter++;
- caching=0;
- counter=0;
- for(pa= re->volume_precache_parts.first; pa; pa= pa->next) {
-
- if(pa->done) {
- counter++;
- BLI_remove_thread(&threads, pa);
- } else
- caching = 1;
- }
-
- if (re->test_break(re->tbh) && BLI_available_threads(&threads)==totthread)
- caching=0;
-
time= PIL_check_seconds_timer();
if(time-lasttime>1.0) {
char str[64];
@@ -757,7 +747,10 @@ static void vol_precache_objectinstance_threads(Render *re, ObjectInstanceRen *o
}
}
+ /* free */
BLI_end_threads(&threads);
+ BLI_thread_queue_free(queue.work);
+ BLI_thread_queue_free(queue.done);
BLI_freelistN(&re->volume_precache_parts);
if(tree) {
@@ -788,13 +781,22 @@ void volume_precache(Render *re)
ObjectInstanceRen *obi;
VolumeOb *vo;
+ re->i.infostr= "Volume preprocessing";
+ re->stats_draw(re->sdh, &re->i);
+
for(vo= re->volumes.first; vo; vo= vo->next) {
if (using_lightcache(vo->ma)) {
for(obi= re->instancetable.first; obi; obi= obi->next) {
if (obi->obr == vo->obr) {
vol_precache_objectinstance_threads(re, obi, vo->ma);
+
+ if(re->test_break && re->test_break(re->tbh))
+ break;
}
}
+
+ if(re->test_break && re->test_break(re->tbh))
+ break;
}
}
diff --git a/source/blender/render/intern/source/voxeldata.c b/source/blender/render/intern/source/voxeldata.c
index 77219abee20..3831b379148 100644
--- a/source/blender/render/intern/source/voxeldata.c
+++ b/source/blender/render/intern/source/voxeldata.c
@@ -389,7 +389,7 @@ int voxeldatatex(struct Tex *tex, const float texvec[3], struct TexResult *texre
VoxelData *vd = tex->vd;
float co[3], offset[3] = {0.5, 0.5, 0.5};
- if ((!vd) || (vd->dataset==NULL)) {
+ if (vd->dataset==NULL) {
texres->tin = 0.0f;
return 0;
}
diff --git a/source/blender/render/intern/source/zbuf.c b/source/blender/render/intern/source/zbuf.c
index f36994e0969..62a54a51102 100644
--- a/source/blender/render/intern/source/zbuf.c
+++ b/source/blender/render/intern/source/zbuf.c
@@ -1747,13 +1747,14 @@ static void zbuf_project_cache_clear(ZbufProjectCache *cache, int size)
static int zbuf_shadow_project(ZbufProjectCache *cache, int index, float winmat[][4], float *co, float *ho)
{
- int clipflag, cindex= index & 255;
+ int cindex= index & 255;
if(cache[cindex].index == index) {
QUATCOPY(ho, cache[cindex].ho);
return cache[cindex].clip;
}
else {
+ int clipflag;
projectvert(co, winmat, ho);
clipflag= testclip(ho);
@@ -1775,14 +1776,16 @@ static void zbuffer_part_bounds(int winx, int winy, RenderPart *pa, float *bound
static int zbuf_part_project(ZbufProjectCache *cache, int index, float winmat[][4], float *bounds, float *co, float *ho)
{
- float vec[3], wco;
- int clipflag= 0, cindex= index & 255;
+ float vec[3];
+ int cindex= index & 255;
if(cache[cindex].index == index) {
QUATCOPY(ho, cache[cindex].ho);
return cache[cindex].clip;
}
else {
+ float wco;
+ int clipflag= 0;
VECCOPY(vec, co)
projectvert(co, winmat, ho);