1 | /* |
---|
2 | |
---|
3 | Homan Igehy |
---|
4 | |
---|
5 | Computer Graphics Laboratory |
---|
6 | Stanford University |
---|
7 | |
---|
8 | --------------------------------------------------------------------- |
---|
9 | |
---|
10 | Copyright (1997) The Board of Trustees of the Leland Stanford Junior |
---|
11 | University. Except for commercial resale, lease, license or other |
---|
12 | commercial transactions, permission is hereby given to use, copy, |
---|
13 | modify this software for academic purposes only. No part of this |
---|
14 | software or any derivatives thereof may be used in the production of |
---|
15 | computer models for resale or for use in a commercial |
---|
16 | product. STANFORD MAKES NO REPRESENTATIONS OR WARRANTIES OF ANY KIND |
---|
17 | CONCERNING THIS SOFTWARE. No support is implied or provided. |
---|
18 | |
---|
19 | */ |
---|
20 | |
---|
21 | |
---|
22 | /* |
---|
23 | * sl_texture.I |
---|
24 | * |
---|
25 | */ |
---|
26 | |
---|
27 | |
---|
28 | #ifndef SL_TEXTURE_I |
---|
29 | #define SL_TEXTURE_I |
---|
30 | |
---|
31 | #include "sl_texture.H" |
---|
32 | |
---|
33 | static inline |
---|
34 | void PointSample(const TextureMap &ps_tex, const Real S, const Real T, |
---|
35 | Real &curR, Real &curG, Real &curB) |
---|
36 | { |
---|
37 | Integer s = (Integer) S; |
---|
38 | Integer t = (Integer) T; |
---|
39 | |
---|
40 | IntegerPS toffset = s + (t << ps_tex.width_shift); |
---|
41 | toffset += (toffset << 1); |
---|
42 | |
---|
43 | TM_RGB *tsample = (TM_RGB *) ((char *) ps_tex.texture + toffset); |
---|
44 | |
---|
45 | curR *= (Real) tsample->R; |
---|
46 | curG *= (Real) tsample->G; |
---|
47 | curB *= (Real) tsample->B; |
---|
48 | } |
---|
49 | |
---|
50 | |
---|
51 | |
---|
52 | |
---|
53 | |
---|
54 | |
---|
55 | #define LERP(a, b, f) ((a) + (f) * ((b) - (a))) |
---|
56 | |
---|
57 | #define TriLERP(a) \ |
---|
58 | l_lo = LERP(ll_lo->a, lr_lo->a, sfrac); \ |
---|
59 | u_lo = LERP(ul_lo->a, ur_lo->a, sfrac); \ |
---|
60 | l_hi = LERP(ll_hi->a, lr_hi->a, sfrac); \ |
---|
61 | u_hi = LERP(ul_hi->a, ur_hi->a, sfrac); \ |
---|
62 | \ |
---|
63 | __lo = LERP(l_lo, u_lo, tfrac); \ |
---|
64 | __hi = LERP(l_hi, u_hi, tfrac); \ |
---|
65 | \ |
---|
66 | cur##a *= LERP(__lo, __hi, levelfrac); |
---|
67 | |
---|
68 | |
---|
69 | #define BiLERP(a) \ |
---|
70 | lower = LERP(ll->a, lr->a, sfrac); \ |
---|
71 | upper = LERP(ul->a, ur->a, sfrac); \ |
---|
72 | cur##a *= LERP(lower, upper, tfrac); |
---|
73 | |
---|
74 | static inline |
---|
75 | void MipMapSample(const MipMap &mipmap, |
---|
76 | const Real S, const Real T, const Real D, |
---|
77 | Real &curR, Real &curG, Real &curB) |
---|
78 | { |
---|
79 | Integer IntD = *(Integer *) &D; |
---|
80 | |
---|
81 | Integer level = (IntD >> REAL_MANTISSA_BITS) - REAL_EXPONENT_BIAS; |
---|
82 | |
---|
83 | if (level >= mipmap.levels) { |
---|
84 | curR *= (Real) (mipmap.texture[mipmap.levels]->R); |
---|
85 | curG *= (Real) (mipmap.texture[mipmap.levels]->G); |
---|
86 | curB *= (Real) (mipmap.texture[mipmap.levels]->B); |
---|
87 | return; |
---|
88 | } |
---|
89 | |
---|
90 | |
---|
91 | Integer s = (Integer) S; |
---|
92 | Integer t = (Integer) T; |
---|
93 | |
---|
94 | Real sfrac = S - (Real) s; |
---|
95 | Real tfrac = T - (Real) t; |
---|
96 | |
---|
97 | if (level < 0) { |
---|
98 | Integer size = 1 << mipmap.levels; |
---|
99 | IntegerPS offset = s + (t << mipmap.levels); |
---|
100 | size += (size << 1); |
---|
101 | |
---|
102 | TM_RGB *ll = (TM_RGB *) ((char *) mipmap.texture[0] + offset); |
---|
103 | TM_RGB *lr = ll + 1; |
---|
104 | TM_RGB *ul = (TM_RGB *) ((char *) ll + size); |
---|
105 | TM_RGB *ur = ul + 1; |
---|
106 | |
---|
107 | Real lower, upper; |
---|
108 | |
---|
109 | BiLERP(R); |
---|
110 | BiLERP(G); |
---|
111 | BiLERP(B); |
---|
112 | |
---|
113 | return; |
---|
114 | } |
---|
115 | |
---|
116 | Real levelfrac = ((Real) REAL_POW_MANTISSA_BITS * |
---|
117 | (Real) (IntD & REAL_MANTISSA_MASK)); |
---|
118 | |
---|
119 | s = s >> level; |
---|
120 | t = t >> level; |
---|
121 | |
---|
122 | Integer sizelog2 = mipmap.levels - level; |
---|
123 | Integer size = 1 << sizelog2; |
---|
124 | |
---|
125 | IntegerPS offset_lo = s + (t << sizelog2); |
---|
126 | offset_lo += (offset_lo << 1); |
---|
127 | |
---|
128 | size += (size << 1); |
---|
129 | |
---|
130 | TM_RGB *ll_lo = (TM_RGB *) ((char *) mipmap.texture[level] + offset_lo); |
---|
131 | TM_RGB *lr_lo = ll_lo + 1; |
---|
132 | TM_RGB *ul_lo = (TM_RGB *) ((char *) ll_lo + size); |
---|
133 | TM_RGB *ur_lo = ul_lo + 1; |
---|
134 | |
---|
135 | |
---|
136 | IntegerPS offset_hi = (s >> 1) + (t << (sizelog2 - 1)); |
---|
137 | offset_hi += (offset_hi << 1); |
---|
138 | |
---|
139 | TM_RGB *ll_hi = (TM_RGB *) ((char *) mipmap.texture[level + 1] + offset_hi); |
---|
140 | TM_RGB *lr_hi = ll_hi + 1; |
---|
141 | TM_RGB *ul_hi = (TM_RGB *) ((char *) ll_hi + size); |
---|
142 | TM_RGB *ur_hi = ul_hi + 1; |
---|
143 | |
---|
144 | Real l_lo, u_lo, l_hi, u_hi, __lo, __hi; |
---|
145 | |
---|
146 | TriLERP(R); |
---|
147 | TriLERP(G); |
---|
148 | TriLERP(B); |
---|
149 | |
---|
150 | } |
---|
151 | |
---|
152 | |
---|
153 | |
---|
154 | |
---|
155 | #ifdef checkerboard |
---|
156 | |
---|
157 | if (((int) S % 2) ^ ((int) T % 2)) { |
---|
158 | FB_R(sample) = FB_InterpToSample(get(R)); |
---|
159 | #ifdef LevelOfDetail |
---|
160 | FB_G(sample) = (char) (100.0 * D); |
---|
161 | #else |
---|
162 | FB_G(sample) = FB_InterpToSample(get(G)); |
---|
163 | #endif |
---|
164 | FB_B(sample) = FB_InterpToSample(get(B)); |
---|
165 | } |
---|
166 | else { |
---|
167 | FB_R(sample) = (char) FB_InterpToSample(get(R)) >> 2; |
---|
168 | #ifdef LevelOfDetail |
---|
169 | FB_G(sample) = (char) (100.0 * D); |
---|
170 | #else |
---|
171 | FB_G(sample) = (char) FB_InterpToSample(get(G)) >> 2; |
---|
172 | #endif |
---|
173 | FB_B(sample) = (char) FB_InterpToSample(get(B)) >> 2; |
---|
174 | } |
---|
175 | |
---|
176 | #endif |
---|
177 | |
---|
178 | |
---|
179 | |
---|
180 | #endif /* TEXTURE_I */ |
---|
181 | |
---|