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:
Diffstat (limited to 'source/blender/render/intern/source/imagetexture.c')
-rw-r--r--source/blender/render/intern/source/imagetexture.c118
1 files changed, 73 insertions, 45 deletions
diff --git a/source/blender/render/intern/source/imagetexture.c b/source/blender/render/intern/source/imagetexture.c
index f78031c9030..4baa3480ae9 100644
--- a/source/blender/render/intern/source/imagetexture.c
+++ b/source/blender/render/intern/source/imagetexture.c
@@ -1,4 +1,4 @@
-/**
+/*
*
* $Id$
*
@@ -51,14 +51,16 @@
#include "BLI_math.h"
#include "BLI_blenlib.h"
#include "BLI_threads.h"
+#include "BLI_utildefines.h"
-#include "BKE_utildefines.h"
#include "BKE_global.h"
#include "BKE_main.h"
#include "BKE_image.h"
#include "BKE_texture.h"
#include "BKE_library.h"
+#include "RE_render_ext.h"
+
#include "renderpipeline.h"
#include "render_types.h"
#include "texture.h"
@@ -157,8 +159,8 @@ int imagewrap(Tex *tex, Image *ima, ImBuf *ibuf, float *texvec, TexResult *texre
}
}
- x = (int)(fx*ibuf->x);
- y = (int)(fy*ibuf->y);
+ x = (int)floorf(fx*ibuf->x);
+ y = (int)floorf(fy*ibuf->y);
if(tex->extend == TEX_CLIPCUBE) {
if(x<0 || y<0 || x>=ibuf->x || y>=ibuf->y || texvec[2]<-1.0 || texvec[2]>1.0) {
@@ -208,8 +210,14 @@ int imagewrap(Tex *tex, Image *ima, ImBuf *ibuf, float *texvec, TexResult *texre
if(texres->nor) {
if(tex->imaflag & TEX_NORMALMAP) {
// qdn: normal from color
- texres->nor[0] = 2.f*(texres->tr - 0.5f);
- texres->nor[1] = 2.f*(0.5f - texres->tg);
+ // The invert of the red channel is to make
+ // the normal map compliant with the outside world.
+ // It needs to be done because in Blender
+ // the normal used in the renderer points inward. It is generated
+ // this way in calc_vertexnormals(). Should this ever change
+ // this negate must be removed.
+ texres->nor[0] = -2.f*(texres->tr - 0.5f);
+ texres->nor[1] = 2.f*(texres->tg - 0.5f);
texres->nor[2] = 2.f*(texres->tb - 0.5f);
}
else {
@@ -500,7 +508,7 @@ static void boxsampleclip(struct ImBuf *ibuf, rctf *rf, TexResult *texres)
}
}
-static void boxsample(ImBuf *ibuf, float minx, float miny, float maxx, float maxy, TexResult *texres, int imaprepeat, int imapextend, int intpol)
+static void boxsample(ImBuf *ibuf, float minx, float miny, float maxx, float maxy, TexResult *texres, int imaprepeat, int imapextend)
{
/* Sample box, performs clip. minx etc are in range 0.0 - 1.0 .
* Enlarge with antialiased edges of pixels.
@@ -808,7 +816,7 @@ static void imp2radangle(float A, float B, float C, float F, float* a, float* b,
static void ewa_eval(TexResult* texr, ImBuf* ibuf, float fx, float fy, afdata_t* AFD)
{
// scaling dxt/dyt by full resolution can cause overflow because of huge A/B/C and esp. F values,
- // scaling by aspect ratio alone does the opposite, so try something inbetween instead...
+ // scaling by aspect ratio alone does the opposite, so try something in between instead...
const float ff2 = ibuf->x, ff = sqrtf(ff2), q = ibuf->y / ff;
const float Ux = AFD->dxt[0]*ff, Vx = AFD->dxt[1]*q, Uy = AFD->dyt[0]*ff, Vy = AFD->dyt[1]*q;
float A = Vx*Vx + Vy*Vy;
@@ -960,6 +968,30 @@ static void alpha_clip_aniso(ImBuf *ibuf, float minx, float miny, float maxx, fl
}
}
+static void image_mipmap_test(Tex *tex, ImBuf *ibuf)
+{
+ if (tex->imaflag & TEX_MIPMAP) {
+ if ((ibuf->flags & IB_fields) == 0) {
+
+ if (ibuf->mipmap[0] && (ibuf->userflags & IB_MIPMAP_INVALID)) {
+ BLI_lock_thread(LOCK_IMAGE);
+ if (ibuf->userflags & IB_MIPMAP_INVALID) {
+ IMB_remakemipmap(ibuf, tex->imaflag & TEX_GAUSS_MIP);
+ ibuf->userflags &= ~IB_MIPMAP_INVALID;
+ }
+ BLI_unlock_thread(LOCK_IMAGE);
+ }
+ if (ibuf->mipmap[0] == NULL) {
+ BLI_lock_thread(LOCK_IMAGE);
+ if (ibuf->mipmap[0] == NULL)
+ IMB_makemipmap(ibuf, tex->imaflag & TEX_GAUSS_MIP);
+ BLI_unlock_thread(LOCK_IMAGE);
+ }
+ }
+ }
+
+}
+
static int imagewraposa_aniso(Tex *tex, Image *ima, ImBuf *ibuf, float *texvec, float *dxt, float *dyt, TexResult *texres)
{
TexResult texr;
@@ -996,15 +1028,9 @@ static int imagewraposa_aniso(Tex *tex, Image *ima, ImBuf *ibuf, float *texvec,
if ((ibuf == NULL) || ((ibuf->rect == NULL) && (ibuf->rect_float == NULL))) return retval;
- // mipmap test
- if (tex->imaflag & TEX_MIPMAP) {
- if (((ibuf->flags & IB_fields) == 0) && (ibuf->mipmap[0] == NULL)) {
- BLI_lock_thread(LOCK_IMAGE);
- if (ibuf->mipmap[0] == NULL) IMB_makemipmap(ibuf, tex->imaflag & TEX_GAUSS_MIP);
- BLI_unlock_thread(LOCK_IMAGE);
- }
- }
-
+ /* mipmap test */
+ image_mipmap_test(tex, ibuf);
+
if ((tex->imaflag & TEX_USEALPHA) && ((tex->imaflag & TEX_CALCALPHA) == 0)) texres->talpha = 1;
texr.talpha = texres->talpha;
@@ -1328,8 +1354,14 @@ static int imagewraposa_aniso(Tex *tex, Image *ima, ImBuf *ibuf, float *texvec,
ibuf->rect -= ibuf->x*ibuf->y;
if (texres->nor && (tex->imaflag & TEX_NORMALMAP)) { // normal from color
- texres->nor[0] = 2.f*(texres->tr - 0.5f);
- texres->nor[1] = 2.f*(0.5f - texres->tg);
+ // The invert of the red channel is to make
+ // the normal map compliant with the outside world.
+ // It needs to be done because in Blender
+ // the normal used in the renderer points inward. It is generated
+ // this way in calc_vertexnormals(). Should this ever change
+ // this negate must be removed.
+ texres->nor[0] = -2.f*(texres->tr - 0.5f);
+ texres->nor[1] = 2.f*(texres->tg - 0.5f);
texres->nor[2] = 2.f*(texres->tb - 0.5f);
}
@@ -1388,17 +1420,7 @@ int imagewraposa(Tex *tex, Image *ima, ImBuf *ibuf, float *texvec, float *DXT, f
return retval;
/* mipmap test */
- if (tex->imaflag & TEX_MIPMAP) {
- if(ibuf->flags & IB_fields);
- else if(ibuf->mipmap[0]==NULL) {
- BLI_lock_thread(LOCK_IMAGE);
-
- if(ibuf->mipmap[0]==NULL)
- IMB_makemipmap(ibuf, tex->imaflag & TEX_GAUSS_MIP);
-
- BLI_unlock_thread(LOCK_IMAGE);
- }
- }
+ image_mipmap_test(tex, ibuf);
if(tex->imaflag & TEX_USEALPHA) {
if(tex->imaflag & TEX_CALCALPHA);
@@ -1606,11 +1628,11 @@ int imagewraposa(Tex *tex, Image *ima, ImBuf *ibuf, float *texvec, float *DXT, f
//minx*= 1.35f;
//miny*= 1.35f;
- boxsample(curibuf, fx-minx, fy-miny, fx+minx, fy+miny, texres, imaprepeat, imapextend, 0);
+ boxsample(curibuf, fx-minx, fy-miny, fx+minx, fy+miny, texres, imaprepeat, imapextend);
val1= texres->tr+texres->tg+texres->tb;
- boxsample(curibuf, fx-minx+dxt[0], fy-miny+dxt[1], fx+minx+dxt[0], fy+miny+dxt[1], &texr, imaprepeat, imapextend, 0);
+ boxsample(curibuf, fx-minx+dxt[0], fy-miny+dxt[1], fx+minx+dxt[0], fy+miny+dxt[1], &texr, imaprepeat, imapextend);
val2= texr.tr + texr.tg + texr.tb;
- boxsample(curibuf, fx-minx+dyt[0], fy-miny+dyt[1], fx+minx+dyt[0], fy+miny+dyt[1], &texr, imaprepeat, imapextend, 0);
+ boxsample(curibuf, fx-minx+dyt[0], fy-miny+dyt[1], fx+minx+dyt[0], fy+miny+dyt[1], &texr, imaprepeat, imapextend);
val3= texr.tr + texr.tg + texr.tb;
/* don't switch x or y! */
@@ -1619,7 +1641,7 @@ int imagewraposa(Tex *tex, Image *ima, ImBuf *ibuf, float *texvec, float *DXT, f
if(previbuf!=curibuf) { /* interpolate */
- boxsample(previbuf, fx-minx, fy-miny, fx+minx, fy+miny, &texr, imaprepeat, imapextend, 0);
+ boxsample(previbuf, fx-minx, fy-miny, fx+minx, fy+miny, &texr, imaprepeat, imapextend);
/* calc rgb */
dx= 2.0f*(pixsize-maxd)/pixsize;
@@ -1636,9 +1658,9 @@ int imagewraposa(Tex *tex, Image *ima, ImBuf *ibuf, float *texvec, float *DXT, f
}
val1= dy*val1+ dx*(texr.tr + texr.tg + texr.tb);
- boxsample(previbuf, fx-minx+dxt[0], fy-miny+dxt[1], fx+minx+dxt[0], fy+miny+dxt[1], &texr, imaprepeat, imapextend, 0);
+ boxsample(previbuf, fx-minx+dxt[0], fy-miny+dxt[1], fx+minx+dxt[0], fy+miny+dxt[1], &texr, imaprepeat, imapextend);
val2= dy*val2+ dx*(texr.tr + texr.tg + texr.tb);
- boxsample(previbuf, fx-minx+dyt[0], fy-miny+dyt[1], fx+minx+dyt[0], fy+miny+dyt[1], &texr, imaprepeat, imapextend, 0);
+ boxsample(previbuf, fx-minx+dyt[0], fy-miny+dyt[1], fx+minx+dyt[0], fy+miny+dyt[1], &texr, imaprepeat, imapextend);
val3= dy*val3+ dx*(texr.tr + texr.tg + texr.tb);
texres->nor[0]= (val1-val2); /* vals have been interpolated above! */
@@ -1661,10 +1683,10 @@ int imagewraposa(Tex *tex, Image *ima, ImBuf *ibuf, float *texvec, float *DXT, f
maxy= fy+miny;
miny= fy-miny;
- boxsample(curibuf, minx, miny, maxx, maxy, texres, imaprepeat, imapextend, 0);
+ boxsample(curibuf, minx, miny, maxx, maxy, texres, imaprepeat, imapextend);
if(previbuf!=curibuf) { /* interpolate */
- boxsample(previbuf, minx, miny, maxx, maxy, &texr, imaprepeat, imapextend, 0);
+ boxsample(previbuf, minx, miny, maxx, maxy, &texr, imaprepeat, imapextend);
fx= 2.0f*(pixsize-maxd)/pixsize;
@@ -1690,11 +1712,11 @@ int imagewraposa(Tex *tex, Image *ima, ImBuf *ibuf, float *texvec, float *DXT, f
}
if(texres->nor && (tex->imaflag & TEX_NORMALMAP)==0) {
- boxsample(ibuf, fx-minx, fy-miny, fx+minx, fy+miny, texres, imaprepeat, imapextend, 0);
+ boxsample(ibuf, fx-minx, fy-miny, fx+minx, fy+miny, texres, imaprepeat, imapextend);
val1= texres->tr+texres->tg+texres->tb;
- boxsample(ibuf, fx-minx+dxt[0], fy-miny+dxt[1], fx+minx+dxt[0], fy+miny+dxt[1], &texr, imaprepeat, imapextend, 0);
+ boxsample(ibuf, fx-minx+dxt[0], fy-miny+dxt[1], fx+minx+dxt[0], fy+miny+dxt[1], &texr, imaprepeat, imapextend);
val2= texr.tr + texr.tg + texr.tb;
- boxsample(ibuf, fx-minx+dyt[0], fy-miny+dyt[1], fx+minx+dyt[0], fy+miny+dyt[1], &texr, imaprepeat, imapextend, 0);
+ boxsample(ibuf, fx-minx+dyt[0], fy-miny+dyt[1], fx+minx+dyt[0], fy+miny+dyt[1], &texr, imaprepeat, imapextend);
val3= texr.tr + texr.tg + texr.tb;
/* don't switch x or y! */
@@ -1702,7 +1724,7 @@ int imagewraposa(Tex *tex, Image *ima, ImBuf *ibuf, float *texvec, float *DXT, f
texres->nor[1]= (val1-val3);
}
else
- boxsample(ibuf, fx-minx, fy-miny, fx+minx, fy+miny, texres, imaprepeat, imapextend, 0);
+ boxsample(ibuf, fx-minx, fy-miny, fx+minx, fy+miny, texres, imaprepeat, imapextend);
}
if(tex->imaflag & TEX_CALCALPHA) {
@@ -1718,8 +1740,14 @@ int imagewraposa(Tex *tex, Image *ima, ImBuf *ibuf, float *texvec, float *DXT, f
if(texres->nor && (tex->imaflag & TEX_NORMALMAP)) {
// qdn: normal from color
- texres->nor[0] = 2.f*(texres->tr - 0.5f);
- texres->nor[1] = 2.f*(0.5f - texres->tg);
+ // The invert of the red channel is to make
+ // the normal map compliant with the outside world.
+ // It needs to be done because in Blender
+ // the normal used in the renderer points inward. It is generated
+ // this way in calc_vertexnormals(). Should this ever change
+ // this negate must be removed.
+ texres->nor[0] = -2.f*(texres->tr - 0.5f);
+ texres->nor[1] = 2.f*(texres->tg - 0.5f);
texres->nor[2] = 2.f*(texres->tb - 0.5f);
}
@@ -1749,7 +1777,7 @@ void image_sample(Image *ima, float fx, float fy, float dx, float dy, float *res
if( (R.flag & R_SEC_FIELD) && (ibuf->flags & IB_fields) )
ibuf->rect+= (ibuf->x*ibuf->y);
- boxsample(ibuf, fx, fy, fx+dx, fy+dy, &texres, 0, 1, 0);
+ boxsample(ibuf, fx, fy, fx+dx, fy+dy, &texres, 0, 1);
result[0]= texres.tr;
result[1]= texres.tg;
result[2]= texres.tb;