00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include "lux.h"
00025 #include "texture.h"
00026 #include "mipmap.h"
00027 #include "imagereader.h"
00028 #include "paramset.h"
00029 #include "error.h"
00030 #include <map>
00031 using std::map;
00032
00033
00034
00035 namespace lux
00036 {
00037
00038
00039 class ImageFloatTexture : public Texture<float> {
00040 public:
00041
00042 ImageFloatTexture(
00043 TextureMapping2D *m,
00044 ImageTextureFilterType type,
00045 const string &filename,
00046 float maxAniso,
00047 ImageWrap wrapMode,
00048 float gain,
00049 float gamma) {
00050 filterType = type;
00051 mapping = m;
00052 mipmap = GetTexture(filterType, filename, maxAniso, wrapMode, gain, gamma);
00053 };
00054
00055 virtual ~ImageFloatTexture() { delete mapping; };
00056
00057 virtual float Evaluate(const TsPack *tspack, const DifferentialGeometry &dg) const {
00058 float s, t, dsdx, dtdx, dsdy, dtdy;
00059 mapping->Map(dg, &s, &t, &dsdx, &dtdx, &dsdy, &dtdy);
00060 return mipmap->Lookup(s, t, dsdx, dtdx, dsdy, dtdy);
00061 };
00062
00063 u_int getMemoryUsed() const {
00064 if (mipmap)
00065 return mipmap->getMemoryUsed();
00066 else
00067 return 0;
00068 }
00069
00070 void discardMipmaps(int n) {
00071 if (mipmap)
00072 mipmap->discardMipmaps(n);
00073 }
00074
00075 static Texture<float> * CreateFloatTexture(const Transform &tex2world, const TextureParams &tp);
00076
00077
00078 private:
00079
00080 static MIPMap<float> *GetTexture(
00081 ImageTextureFilterType filterType,
00082 const string &filename,
00083 float maxAniso,
00084 ImageWrap wrap,
00085 float gain,
00086 float gamma);
00087 static void convert(const RGBColor &from, RGBColor *to) {
00088 *to = from;
00089 }
00090 static void convert(const RGBColor &from, float *to) {
00091 *to = from.Y();
00092 }
00093
00094
00095 ImageTextureFilterType filterType;
00096 MIPMap<float> *mipmap;
00097 TextureMapping2D *mapping;
00098 };
00099
00100 class ImageSpectrumTexture : public Texture<SWCSpectrum> {
00101 public:
00102
00103 ImageSpectrumTexture(
00104 TextureMapping2D *m,
00105 ImageTextureFilterType type,
00106 const string &filename,
00107 float maxAniso,
00108 ImageWrap wrapMode,
00109 float gain,
00110 float gamma) {
00111 filterType = type;
00112 mapping = m;
00113 mipmap = GetTexture(filterType, filename, maxAniso, wrapMode, gain, gamma);
00114 };
00115
00116 virtual ~ImageSpectrumTexture() { delete mapping; };
00117
00118 virtual SWCSpectrum Evaluate(const TsPack *tspack, const DifferentialGeometry &dg) const {
00119 float s, t, dsdx, dtdx, dsdy, dtdy;
00120 mapping->Map(dg, &s, &t, &dsdx, &dtdx, &dsdy, &dtdy);
00121 return SWCSpectrum(tspack, mipmap->Lookup(s, t, dsdx, dtdx, dsdy, dtdy));
00122 };
00123
00124 u_int getMemoryUsed() const {
00125 if (mipmap)
00126 return mipmap->getMemoryUsed();
00127 else
00128 return 0;
00129 }
00130
00131 void discardMipmaps(int n) {
00132 if (mipmap)
00133 mipmap->discardMipmaps(n);
00134 }
00135
00136
00137 static Texture<SWCSpectrum> * CreateSWCSpectrumTexture(const Transform &tex2world, const TextureParams &tp);
00138
00139 private:
00140
00141 static MIPMap<RGBColor> *GetTexture(
00142 ImageTextureFilterType filterType,
00143 const string &filename,
00144 float maxAniso,
00145 ImageWrap wrap,
00146 float gain,
00147 float gamma);
00148 static void convert(const RGBColor &from, RGBColor *to) {
00149 *to = from;
00150 }
00151 static void convert(const RGBColor &from, float *to) {
00152 *to = from.Y();
00153 }
00154
00155
00156 ImageTextureFilterType filterType;
00157 MIPMap<RGBColor> *mipmap;
00158 TextureMapping2D *mapping;
00159 };
00160
00161
00162
00163 struct TexInfo {
00164 TexInfo(ImageTextureFilterType type, const string &f, float ma,
00165 ImageWrap wm, float ga, float gam)
00166 : filterType(type), filename(f), maxAniso(ma),
00167 wrapMode(wm), gain(ga), gamma(gam) { }
00168
00169 ImageTextureFilterType filterType;
00170 string filename;
00171 float maxAniso;
00172 ImageWrap wrapMode;
00173 float gain;
00174 float gamma;
00175
00176 bool operator<(const TexInfo &t2) const {
00177 if (filterType != t2.filterType) return filterType < t2.filterType;
00178 if (filename != t2.filename) return filename < t2.filename;
00179 if (maxAniso != t2.maxAniso) return maxAniso < t2.maxAniso;
00180 if (wrapMode != t2.wrapMode) return wrapMode < t2.wrapMode;
00181 if (gain != t2.gain) return gain < t2.gain;
00182
00183 return gamma < t2.gamma;
00184 }
00185 };
00186
00187 inline MIPMap<float> *ImageFloatTexture::
00188 GetTexture(
00189 ImageTextureFilterType filterType,
00190 const string &filename,
00191 float maxAniso,
00192 ImageWrap wrap,
00193 float gain,
00194 float gamma) {
00195
00196 static map<TexInfo, MIPMap<float> *> textures;
00197 TexInfo texInfo(filterType, filename, maxAniso, wrap, gain, gamma);
00198 if (textures.find(texInfo) != textures.end())
00199 return textures[texInfo];
00200 int width, height;
00201 auto_ptr<ImageData> imgdata(ReadImage(filename));
00202 MIPMap<float> *ret = NULL;
00203 if (imgdata.get() != NULL) {
00204 width=imgdata->getWidth();
00205 height=imgdata->getHeight();
00206 ret = imgdata->createMIPMap<float>(filterType, maxAniso, wrap, gain, gamma);
00207 } else {
00208
00209 float *oneVal = new float[1];
00210 oneVal[0] = 1.;
00211
00212 ret = new MIPMapFastImpl<float,float>(filterType, 1, 1, oneVal);
00213
00214 delete[] oneVal;
00215 }
00216 textures[texInfo] = ret;
00217
00218 return ret;
00219 }
00220
00221 inline MIPMap<RGBColor> *ImageSpectrumTexture::
00222 GetTexture(
00223 ImageTextureFilterType filterType,
00224 const string &filename,
00225 float maxAniso,
00226 ImageWrap wrap,
00227 float gain,
00228 float gamma) {
00229
00230 static map<TexInfo, MIPMap<RGBColor> *> textures;
00231 TexInfo texInfo(filterType, filename, maxAniso, wrap, gain, gamma);
00232 if (textures.find(texInfo) != textures.end())
00233 return textures[texInfo];
00234 int width, height;
00235 auto_ptr<ImageData> imgdata(ReadImage(filename));
00236 MIPMap<RGBColor> *ret = NULL;
00237 if (imgdata.get() != NULL) {
00238 width=imgdata->getWidth();
00239 height=imgdata->getHeight();
00240 ret = imgdata->createMIPMap<RGBColor>(filterType, maxAniso, wrap, gain, gamma);
00241 } else {
00242
00243 RGBColor *oneVal = new RGBColor[1];
00244 oneVal[0] = 1.;
00245
00246 ret = new MIPMapFastImpl<RGBColor,RGBColor>(filterType, 1, 1, oneVal);
00247
00248 delete[] oneVal;
00249 }
00250 textures[texInfo] = ret;
00251
00252 return ret;
00253 }
00254
00255 }