diff options
Diffstat (limited to 'source/blender/render/intern/source/imagetexture.c')
-rw-r--r-- | source/blender/render/intern/source/imagetexture.c | 118 |
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; |