00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #include <iostream>
00024 #include "ipltexture.h"
00025
00026 IplTexture::IplTexture(const IplTexture &a)
00027 {
00028 downsampled=0;
00029 textureGenerated=false;
00030 *this = a;
00031 }
00032 const IplTexture &IplTexture::operator = (const IplTexture &a)
00033 {
00034 this->~IplTexture();
00035 if (a.im == &a.header) {
00036 header = a.header;
00037 im = &header;
00038 } else {
00039 im = a.im;
00040 }
00041 allowCache = a.allowCache;
00042 reload = true;
00043 smooth = a.smooth;
00044 textureGenerated=false;
00045 refcnt = 1;
00046 isAlpha = a.isAlpha;
00047 return *this;
00048 }
00049
00050 IplTexture::~IplTexture()
00051 {
00052 if (downsampled) cvReleaseImage(&downsampled);
00053
00054 if (textureGenerated) {
00055 glDeleteTextures(1,(GLuint*) &texture);
00056 }
00057 }
00058
00059 void IplTexture::genTexture()
00060 {
00061 #ifdef HAVE_GL
00062 if (im==0) return;
00063
00064 if (!textureGenerated) {
00065 glGenTextures(1,(GLuint*) &texture);
00066 textureGenerated = true;
00067 }
00068 glBindTexture(GL_TEXTURE_2D, texture);
00069
00070 for (texWidth=1; texWidth < im->width; texWidth <<=1) {}
00071 for (texHeight=1; texHeight < im->height; texHeight <<=1) {}
00072
00073 if (texWidth > 1024) texWidth = 1024;
00074 if (texHeight > 1024) texHeight = 1024;
00075
00076
00077
00078 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
00079 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
00080 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, (smooth ? GL_LINEAR : GL_NEAREST));
00081 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, (smooth ? GL_LINEAR : GL_NEAREST));
00082
00083 int sz = texWidth*texHeight*4;
00084 char *buffer = (char *) malloc(sz);
00085 memset(buffer, 0, sz);
00086
00087 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, texWidth,texHeight, 0, GL_RGBA,
00088 GL_UNSIGNED_BYTE, buffer);
00089 free(buffer);
00090 #endif
00091 }
00092
00093 void IplTexture::loadTexture()
00094 {
00095 #ifdef HAVE_GL
00096 if (im==0) return;
00097 if (!textureGenerated) genTexture();
00098
00099 IplImage *im = (downsampled ? downsampled : this->im);
00100
00101 if ((im->width > texWidth) || (im->height > texHeight)) {
00102 if (downsampled) cvReleaseImage(&downsampled);
00103 downsampled = cvCreateImage(cvSize(texWidth, texHeight), this->im->depth, this->im->nChannels);
00104 im = downsampled;
00105 }
00106
00107 glEnable(GL_TEXTURE_2D);
00108 glBindTexture(GL_TEXTURE_2D, texture);
00109
00110 if (allowCache && !reload) return;
00111 reload = false;
00112
00113 if (downsampled)
00114 cvResize(this->im, downsampled, CV_INTER_AREA);
00115
00116 GLenum format;
00117 GLenum type;
00118 switch (im->depth) {
00119 case IPL_DEPTH_8U: type = GL_UNSIGNED_BYTE; break;
00120 case IPL_DEPTH_8S: type = GL_BYTE; break;
00121 case IPL_DEPTH_16S: type = GL_SHORT; break;
00122 case IPL_DEPTH_32F: type = GL_FLOAT; break;
00123 default:
00124 std::cerr << "IplTexture::loadTexture(): unsupported pixel type.\n";
00125 return;
00126 }
00127 switch (im->nChannels) {
00128 case 1: format = (isAlpha ? GL_ALPHA : GL_LUMINANCE); break;
00129 case 3: format = (im->channelSeq[0] == 'B') ? GL_BGR_EXT : GL_RGB; break;
00130 case 4: format = GL_RGBA; break;
00131 default:
00132 std::cerr << "IplTexture::loadTexture(): unsupported number of channels.\n";
00133 return;
00134 }
00135
00136
00137 glPixelStorei(GL_UNPACK_ALIGNMENT, im->align);
00138
00139 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, im->width, im->height,
00140 format, type, im->imageData);
00141
00142 uScale = (double(im->width)/double(this->im->width))/double(texWidth);
00143 vScale = (double(im->height)/double(this->im->height))/double(texHeight);
00144 vOrigin = 0;
00145
00146 if (im->origin) {
00147 vScale = -vScale;
00148 vOrigin = double(im->height)/double(texHeight);
00149 }
00150 #endif
00151 }
00152
00153 void IplTexture::disableTexture()
00154 {
00155 #ifdef HAVE_GL
00156 glDisable(GL_TEXTURE_2D);
00157 #endif
00158 }
00159
00160 void IplTexture::unref()
00161 {
00162 refcnt--;
00163 if (refcnt <= 0)
00164 delete this;
00165 }
00166
00167 void IplTexture::setImage(IplImage *image)
00168 {
00169 im = image;
00170 if (downsampled) cvReleaseImage(&downsampled);
00171 update();
00172 }
00173
00174 void IplTexture::setImage(CvMat *mat)
00175 {
00176 setImage(cvGetImage(mat, &header));
00177 }
00178
00179 void IplTexture::regen()
00180 {
00181 update();
00182 textureGenerated = false;
00183 }
00184
00185 void IplTexture::drawQuad(float r) {
00186 drawQuad(-r,-r,2*r,2*r);
00187 }
00188
00190 void IplTexture::drawQuad(float x, float y, float _width, float _height)
00191 {
00192 if (!this || !getIm()) return;
00193
00194 IplImage *im = getIm();
00195 int w = im->width-1;
00196 int h = im->height-1;
00197
00198 float width = (_width==0 ? im->width : _width);
00199 float height = (_height==0 ? im->height : _height);
00200
00201
00202 loadTexture();
00203
00204 glBegin(GL_QUADS);
00205
00206 glTexCoord2f(u(0), v(0));
00207 glVertex2f(x, y);
00208
00209 glTexCoord2f(u(w), v(0));
00210 glVertex2f(x+width, y);
00211
00212 glTexCoord2f(u(w), v(h));
00213 glVertex2f(x+width, y+height);
00214
00215 glTexCoord2f(u(0), v(h));
00216 glVertex2f(x, y+height);
00217 glEnd();
00218
00219 disableTexture();
00220 }
00221
00222 #ifdef ___MACOS
00223 #include <QuickTime/QuickTime.h>
00224 #include <QuickTime/Movies.h>
00225 #include <QuickTime/QuickTimeComponents.h>
00226
00227 bool LoadTexture(IplTexture *tex, const char *filename, const char *subdir)
00228 {
00229 ComponentInstance fileImporter;
00230 OSErr error;
00231 ImageDescriptionHandle imageInfo;
00232 ComponentResult err;
00233
00234
00235 CFStringRef name = CFStringCreateWithCStringNoCopy(NULL, filename, kCFStringEncodingASCII, NULL);
00236 CFStringRef _subdir = CFStringCreateWithCStringNoCopy(NULL, subdir, kCFStringEncodingASCII, NULL);
00237
00238 CFURLRef texture_url = CFBundleCopyResourceURL(
00239 CFBundleGetMainBundle(),
00240 name,
00241 NULL,
00242 _subdir);
00243
00244
00245 Handle dataRef;
00246 OSType dataRefType;
00247
00248 dataRef = NewHandle(sizeof(AliasHandle));
00249
00250
00251
00252 error = QTNewDataReferenceFromCFURL(texture_url, 0, &dataRef, &dataRefType);
00253 if(error != noErr) {
00254
00255
00256 return false;
00257 }
00258
00259
00260 error = GetGraphicsImporterForDataRef(dataRef, dataRefType, &fileImporter);
00261
00262
00263 imageInfo = (ImageDescriptionHandle)NewHandle(sizeof(ImageDescription));
00264 err = GraphicsImportGetImageDescription(fileImporter, &imageInfo);
00265 unsigned width = ((**imageInfo).width);
00266 unsigned height = ((**imageInfo).height);
00267
00268 IplImage *im = tex->getIm();
00269 if (im && (im->width != width || im->height!=height))
00270 cvReleaseImage(&im);
00271 if (im==0) {
00272 im = cvCreateImage(cvSize(width,height), IPL_DEPTH_8U, 4);
00273
00274
00275 tex->setImage(im);
00276
00277 }
00278 tex->update();
00279
00280 void *imageData = im->imageData;
00281
00282
00283 Rect imageRect;
00284 err = GraphicsImportGetNaturalBounds(fileImporter, &imageRect);
00285
00286
00287
00288
00289 long bytesPerRow = im->widthStep;
00290
00291 GWorldPtr offscreenBuffer=0;
00292
00293 if (offscreenBuffer==0) {
00294 error = QTNewGWorldFromPtr(&offscreenBuffer, k32RGBAPixelFormat, &imageRect,
00295 NULL, NULL, kNativeEndianPixMap, imageData, bytesPerRow);
00296 assert(error == noErr);
00297 }
00298
00299
00300 err = GraphicsImportSetGWorld(fileImporter, offscreenBuffer, NULL);
00301 assert(err == noErr);
00302 err = GraphicsImportDraw(fileImporter);
00303 assert(err == noErr);
00304
00305
00306 error = CloseComponent(fileImporter);
00307 DisposeHandle((Handle)imageInfo);
00308 DisposeHandle(dataRef);
00309 DisposeGWorld(offscreenBuffer);
00310 return true;
00311 }
00312 #endif
00313
00314