~ubuntu-branches/ubuntu/maverick/blender/maverick

« back to all changes in this revision

Viewing changes to extern/qdune/svm/ImageTextures.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Khashayar Naderehvandi, Khashayar Naderehvandi, Alessio Treglia
  • Date: 2009-01-22 16:53:59 UTC
  • mfrom: (14.1.1 experimental)
  • Revision ID: james.westby@ubuntu.com-20090122165359-v0996tn7fbit64ni
Tags: 2.48a+dfsg-1ubuntu1
[ Khashayar Naderehvandi ]
* Merge from debian experimental (LP: #320045), Ubuntu remaining changes:
  - Add patch correcting header file locations.
  - Add libvorbis-dev and libgsm1-dev to Build-Depends.
  - Use avcodec_decode_audio2() in source/blender/src/hddaudio.c

[ Alessio Treglia ]
* Add missing previous changelog entries.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
//---------------------------------------------------------------------------------------
2
 
// Handles image based textures, including environment & shadow maps
3
 
//---------------------------------------------------------------------------------------
4
 
// (environmentmaps not yet TODO)
5
 
 
6
 
#include "ImageTextures.h"
7
 
#include "TexCache.h"
8
 
 
9
 
#include "exr_io.h"
10
 
#include "State.h"
11
 
#include "Mathutil.h"
12
 
#include "mcqmc.h"
13
 
 
14
 
__BEGIN_QDRENDER
15
 
 
16
 
using namespace std;
17
 
 
18
 
//---------------------------------------------------------------------------------------
19
 
 
20
 
void getTextureColor(RtColor col, const char* texname, float st[8], float A)
21
 
{
22
 
        const TextureCache* const texcache = State::Instance()->getTextureCache();
23
 
        const EXRbuf_t* const texinfo = texcache->getTextureInfo(texname);
24
 
        if (texinfo == NULL) {
25
 
                // texture could not be opened or possibly some other error occured
26
 
                col[0] = col[1] = col[2] = 0.f;
27
 
                return;
28
 
        }
29
 
        // convert to color if texture is actually single channel
30
 
        if (texinfo->numChannels() == 1) {
31
 
                getTextureFloat(col[0], texname, st, A);
32
 
                col[1] = col[2] = col[0];
33
 
                return;
34
 
        }
35
 
        
36
 
        const float cs = (st[0] + st[2] + st[4] + st[6])*0.25f, ct = (st[1] + st[3] + st[5] + st[7])*0.25f;
37
 
        const int wd = texinfo->getWidth(0), ht = texinfo->getHeight(0);
38
 
 
39
 
        float levf = MAX2(0.5f*logf(wd*ht*A)*(float)M_LOG2E, 0.f);      // includes sqrt
40
 
        const int maxlevel = texinfo->getLevels() - 2;  // -2 to account for trilerp
41
 
        int level = MIN2(FLOORI(levf), maxlevel);
42
 
        RtColor col1, col2;
43
 
        // color at current level
44
 
        int wdl = texinfo->getWidth(level), htl = texinfo->getHeight(level);
45
 
        float u0 = wdl*(cs - FLOORF(cs))-0.5f, v0 = htl*(ct - FLOORF(ct))-0.5f;
46
 
        // x0/y0 coords change here depending on wrap type, currently wrap for now
47
 
        int x0 = int(u0) % wdl, y0 = int(v0) % htl;
48
 
        if (x0 < 0) x0 += wdl;
49
 
        if (y0 < 0) y0 += htl;
50
 
        RtColor c00, c10, c01, c11;
51
 
        texcache->getColor(texinfo, x0, y0, level, c00);
52
 
        texcache->getColor(texinfo, x0+1, y0, level, c10);
53
 
        texcache->getColor(texinfo, x0+1, y0+1, level, c11);
54
 
        texcache->getColor(texinfo, x0, y0+1, level, c01);
55
 
        bilerp(col1, u0-x0, v0-y0, c00, c10, c01, c11);
56
 
        // color at next level
57
 
        level++;
58
 
        wdl = texinfo->getWidth(level), htl = texinfo->getHeight(level);
59
 
        u0 = wdl*(cs - FLOORF(cs))-0.5f, v0 = htl*(ct - FLOORF(ct))-0.5f;
60
 
        x0 = int(u0) % wdl, y0 = int(v0) % htl;
61
 
        if (x0 < 0) x0 += wdl;
62
 
        if (y0 < 0) y0 += htl;
63
 
        texcache->getColor(texinfo, x0, y0, level, c00);
64
 
        texcache->getColor(texinfo, x0+1, y0, level, c10);
65
 
        texcache->getColor(texinfo, x0+1, y0+1, level, c11);
66
 
        texcache->getColor(texinfo, x0, y0+1, level, c01);
67
 
        bilerp(col2, u0-x0, v0-y0, c00, c10, c01, c11);
68
 
        // trilerp
69
 
        levf -= FLOORF(levf);
70
 
        col[0] = col1[0] + levf*(col2[0] - col1[0]);
71
 
        col[1] = col1[1] + levf*(col2[1] - col1[1]);
72
 
        col[2] = col1[2] + levf*(col2[2] - col1[2]);
73
 
 
74
 
        #if 0
75
 
        // test, samples actual st area at level 0
76
 
        const int wd = texinfo->getWidth(0), ht = texinfo->getHeight(0);
77
 
        const float fxmin = wd*MIN4(st[0], st[2], st[4], st[6]);
78
 
        const float fymin = ht*MIN4(st[1], st[3], st[5], st[7]);
79
 
        const float fxmax = wd*MAX4(st[0], st[2], st[4], st[6]);
80
 
        const float fymax = ht*MAX4(st[1], st[3], st[5], st[7]);
81
 
        const float fw = (fxmax - fxmin), fh = (fymax - fymin);
82
 
        const int xmin = FLOORI(fxmin), ymin = FLOORI(fymin);
83
 
        const int xmax = CEILI(fxmax), ymax = CEILI(fymax);
84
 
        col[0] = col[1] = col[2] = 0.f;
85
 
        float wts = 0.f;
86
 
        for (int y=ymin; y<=ymax; ++y)
87
 
                for (int x=xmin; x<=xmax; ++x) {
88
 
                        const float fx = (x - cs*wd), fy = (y - ct*ht);
89
 
                        const float wt = RiGaussianFilter(fx, fy, fw, fh);
90
 
                        wts += wt;
91
 
                        RtColor tc;
92
 
                        texcache->getColor(texinfo, x, y, 0, tc);
93
 
                        col[0] += wt*tc[0], col[1] += wt*tc[1], col[2] += wt*tc[2];
94
 
                }
95
 
        const float sd = (wts==0.f) ? 1.f : (1.f/wts);
96
 
        col[0] *= sd, col[1] *= sd, col[2] *= sd;
97
 
        #endif
98
 
}
99
 
 
100
 
 
101
 
void getTextureFloat(RtFloat& fval, const char* texname, float st[8], float A)
102
 
{
103
 
        const TextureCache* const texcache = State::Instance()->getTextureCache();
104
 
        const EXRbuf_t* const texinfo = texcache->getTextureInfo(texname);
105
 
        if (texinfo == NULL) {
106
 
                // texture could not be opened or possibly some other error occured
107
 
                fval = 0.f;
108
 
                return;
109
 
        }
110
 
        if (!texinfo->numChannels() == 1) {
111
 
                // actually a color image, return red channel only (could also average or weight channels)
112
 
                RtColor col;
113
 
                getTextureColor(col, texname, st, A);
114
 
                fval = col[0];
115
 
                return;
116
 
        }
117
 
        
118
 
        const float cs = (st[0] + st[2] + st[4] + st[6])*0.25f, ct = (st[1] + st[3] + st[5] + st[7])*0.25f;
119
 
        const int wd = texinfo->getWidth(0), ht = texinfo->getHeight(0);
120
 
 
121
 
        float levf = MAX2(0.5f*logf(wd*ht*A)*(float)M_LOG2E, 0.f);      // includes sqrt
122
 
        const int maxlevel = texinfo->getLevels() - 2;
123
 
        int level = MIN2(FLOORI(levf), maxlevel);
124
 
 
125
 
        RtFloat fval1, fval2;
126
 
        // value at current level
127
 
        int wdl = texinfo->getWidth(level), htl = texinfo->getHeight(level);
128
 
        float u0 = wdl*(cs - FLOORF(cs))-0.5f, v0 = htl*(ct - FLOORF(ct))-0.5f;
129
 
        // WRAPMODES!!! TODO
130
 
        int x0 = int(u0) % wdl, y0 = int(v0) % htl;
131
 
        if (x0 < 0) x0 += wdl;
132
 
        if (y0 < 0) y0 += htl;
133
 
        float f00 = texcache->getFloat(texinfo, x0, y0, level);
134
 
        float f10 = texcache->getFloat(texinfo, x0+1, y0, level);
135
 
        float f11 = texcache->getFloat(texinfo, x0+1, y0+1, level);
136
 
        float f01 = texcache->getFloat(texinfo, x0, y0+1, level);
137
 
        bilerpF(fval1, u0-x0, v0-y0, f00, f10, f01, f11);
138
 
        // value at next level
139
 
        level++;
140
 
        wdl = texinfo->getWidth(level), htl = texinfo->getHeight(level);
141
 
        u0 = wdl*(cs - FLOORF(cs))-0.5f, v0 = htl*(ct - FLOORF(ct))-0.5f;
142
 
        x0 = int(u0) % wdl, y0 = int(v0) % htl;
143
 
        if (x0 < 0) x0 += wdl;
144
 
        if (y0 < 0) y0 += htl;
145
 
        f00 = texcache->getFloat(texinfo, x0, y0, level);
146
 
        f10 = texcache->getFloat(texinfo, x0+1, y0, level);
147
 
        f11 = texcache->getFloat(texinfo, x0+1, y0+1, level);
148
 
        f01 = texcache->getFloat(texinfo, x0, y0+1, level);
149
 
        bilerpF(fval2, u0-x0, v0-y0, f00, f10, f01, f11);
150
 
        // trilerp
151
 
        levf -= FLOORF(levf);
152
 
        fval = fval1 + levf*(fval2 - fval1);
153
 
}
154
 
 
155
 
 
156
 
float getShadowFactor(const char* texname, float st[8], const RtPoint& wldP, float* samples, float* blur, float* bias)
157
 
{
158
 
        const TextureCache* const texcache = State::Instance()->getTextureCache();
159
 
        const EXRbuf_t* const texinfo = texcache->getTextureInfo(texname);
160
 
        if (texinfo == NULL) return 0.f;        // texture could not be opened or possibly some other error occured
161
 
        RtPoint ltP;
162
 
        mulPMP(ltP, texinfo->get_w2c(), wldP);
163
 
        const float wz = bias ? (ltP[2] - *bias) : (ltP[2] - 0.01f);    // 0.01 default bias
164
 
        const RtMatrix& c2r = texinfo->get_c2r();
165
 
        if (texinfo->isOrtho()) {
166
 
                ltP[0] = c2r[0][0]*ltP[0] + c2r[0][1]*ltP[1] + c2r[0][2]*ltP[2] + c2r[0][3];
167
 
                ltP[1] = c2r[1][0]*ltP[0] + c2r[1][1]*ltP[1] + c2r[1][2]*ltP[2] + c2r[1][3];
168
 
        }
169
 
        else {
170
 
                ltP[0] = c2r[0][0]*ltP[0] + c2r[0][1]*ltP[1] + c2r[0][2]*ltP[2];
171
 
                ltP[1] = c2r[1][0]*ltP[0] + c2r[1][1]*ltP[1] + c2r[1][2]*ltP[2];
172
 
                if (ltP[2] != 0.f) { ltP[2] = 1.f/ltP[2];  ltP[0] *= ltP[2];  ltP[1] *= ltP[2]; }
173
 
        }
174
 
        const float blur_rad = blur ? (*blur)*0.5f : 0;
175
 
        const float maxwd = float(texinfo->getWidth() - 1), maxht = float(texinfo->getHeight() - 1);
176
 
        const float xmin = MIN2(MAX2(ltP[0] - blur_rad, 0.f), maxwd);
177
 
        const float xmax = MIN2(MAX2(ltP[0] + blur_rad, 0.f), maxwd);
178
 
        const float ymin = MIN2(MAX2(ltP[1] - blur_rad, 0.f), maxht);
179
 
        const float ymax = MIN2(MAX2(ltP[1] + blur_rad, 0.f), maxht);
180
 
        const float dx = xmax - xmin, dy = ymax - ymin;
181
 
        if ((dx < 0.f) || (dy < 0.f)) return 0.f;
182
 
        const int numsam = samples ? int(*samples) : 1; // single sample default
183
 
        const float sdiv = 1.f/(float)numsam;
184
 
        int ts = 0;
185
 
        //static unsigned int VDCC = 0, SBC = 0;
186
 
        static Halton H2(2), H3(3);
187
 
        for (int sm=0; sm<numsam; ++sm) {
188
 
                /*if (sm == 16) {
189
 
                        if (ts == 16) return 0.f;
190
 
                        if (ts == 0) return 1.f;
191
 
                }*/
192
 
                const float zval = texcache->getDepth(texinfo, int(xmin + H2.getNext()*dx), int(ymin + H3.getNext()*dy));
193
 
                //const float zval = texcache->getDepth(texinfo, int(xmin + RI_vdC(++VDCC)*dx), int(ymin + RI_Sb(++SBC)*dy));
194
 
                //const float zval = texcache->getDepth(texinfo, int(xmin + RI_vdC(++VDCC)*dx), int(ymin + (sm + 0.5f)*sdiv*dy));
195
 
                //const float zval = texcache->getDepth(texinfo, int(xmin + frand()*dx), int(ymin + frand()*dy));
196
 
                // zval <= 0.f is invalid access return value of getFloat()
197
 
                ts += (zval > 0.f) ? ((zval < wz) ? 0 : 1) : 0;
198
 
        }
199
 
        return 1.f - ts*sdiv;
200
 
}
201
 
 
202
 
__END_QDRENDER