1 #include "image_loader.h"
8 GLuint* loadImage(wxString path, int* imageWidth, int* imageHeight, int* textureWidth, int* textureHeight)
11 GLuint* ID=new GLuint[1];
12 glGenTextures( 1, &ID[0] );
14 glBindTexture( GL_TEXTURE_2D, *ID );
16 // the first time, init image handlers (remove this part if you do it somewhere else in your app)
17 static bool is_first_time = true;
20 wxInitAllImageHandlers();
22 is_first_time = false;
25 // check the file exists
26 if(!wxFileExists(path))
28 wxMessageBox( _("Failed to load resource image") );
32 wxImage* img=new wxImage( path );
34 (*imageWidth)=img->GetWidth();
35 (*imageHeight)=img->GetHeight();
37 glPixelStorei(GL_UNPACK_ALIGNMENT, 1 );
40 * Many graphics card require that textures be power of two.
41 * Below is a simple implementation, probably not optimal but working.
42 * If your texture sizes are not restricted to power of 2s, you can
43 * of course adapt the bit below as needed.
46 float power_of_two_that_gives_correct_width=std::log((float)(*imageWidth))/std::log(2.0);
47 float power_of_two_that_gives_correct_height=std::log((float)(*imageHeight))/std::log(2.0);
49 // check if image dimensions are a power of two
50 if( (int)power_of_two_that_gives_correct_width == power_of_two_that_gives_correct_width &&
51 (int)power_of_two_that_gives_correct_height == power_of_two_that_gives_correct_height)
53 // note: must make a local copy before passing the data to OpenGL, as GetData() returns RGB
54 // and we want the Alpha channel if it's present. Additionally OpenGL seems to interpret the
55 // data upside-down so we need to compensate for that.
56 GLubyte *bitmapData=img->GetData();
57 GLubyte *alphaData=img->GetAlpha();
59 int bytesPerPixel = img->HasAlpha() ? 4 : 3;
61 int imageSize = (*imageWidth) * (*imageHeight) * bytesPerPixel;
62 GLubyte *imageData=new GLubyte[imageSize];
64 int rev_val=(*imageHeight)-1;
66 for(int y=0; y<(*imageHeight); y++)
68 for(int x=0; x<(*imageWidth); x++)
70 imageData[(x+y*(*imageWidth))*bytesPerPixel+0]=
71 bitmapData[( x+(rev_val-y)*(*imageWidth))*3];
73 imageData[(x+y*(*imageWidth))*bytesPerPixel+1]=
74 bitmapData[( x+(rev_val-y)*(*imageWidth))*3 + 1];
76 imageData[(x+y*(*imageWidth))*bytesPerPixel+2]=
77 bitmapData[( x+(rev_val-y)*(*imageWidth))*3 + 2];
79 if(bytesPerPixel==4) imageData[(x+y*(*imageWidth))*bytesPerPixel+3]=
80 alphaData[ x+(rev_val-y)*(*imageWidth) ];
84 // if yes, everything is fine
85 glTexImage2D(GL_TEXTURE_2D,
91 img->HasAlpha() ? GL_RGBA : GL_RGB,
95 (*textureWidth) = (*imageWidth);
96 (*textureHeight) = (*imageHeight);
100 else // texture is not a power of two. We need to resize it
103 int newWidth=(int)std::pow( 2.0, (int)(std::ceil(power_of_two_that_gives_correct_width)) );
104 int newHeight=(int)std::pow( 2.0, (int)(std::ceil(power_of_two_that_gives_correct_height)) );
106 //printf("Unsupported image size. Recommand values: %i %i\n",newWidth,newHeight);
108 GLubyte *bitmapData=img->GetData();
109 GLubyte *alphaData=img->GetAlpha();
111 int old_bytesPerPixel = 3;
112 int bytesPerPixel = img->HasAlpha() ? 4 : 3;
114 int imageSize = newWidth * newHeight * bytesPerPixel;
115 GLubyte *imageData=new GLubyte[imageSize];
117 int rev_val=(*imageHeight)-1;
119 for(int y=0; y<newHeight; y++)
121 for(int x=0; x<newWidth; x++)
124 if( x<(*imageWidth) && y<(*imageHeight) ){
125 imageData[(x+y*newWidth)*bytesPerPixel+0]=
126 bitmapData[( x+(rev_val-y)*(*imageWidth))*old_bytesPerPixel + 0];
128 imageData[(x+y*newWidth)*bytesPerPixel+1]=
129 bitmapData[( x+(rev_val-y)*(*imageWidth))*old_bytesPerPixel + 1];
131 imageData[(x+y*newWidth)*bytesPerPixel+2]=
132 bitmapData[( x+(rev_val-y)*(*imageWidth))*old_bytesPerPixel + 2];
134 if(bytesPerPixel==4) imageData[(x+y*newWidth)*bytesPerPixel+3]=
135 alphaData[ x+(rev_val-y)*(*imageWidth) ];
141 imageData[(x+y*newWidth)*bytesPerPixel+0] = 0;
142 imageData[(x+y*newWidth)*bytesPerPixel+1] = 0;
143 imageData[(x+y*newWidth)*bytesPerPixel+2] = 0;
144 if(bytesPerPixel==4) imageData[(x+y*newWidth)*bytesPerPixel+3] = 0;
151 glTexImage2D(GL_TEXTURE_2D,
153 img->HasAlpha() ? 4 : 3,
157 img->HasAlpha() ? GL_RGBA : GL_RGB,
161 (*textureWidth)=newWidth;
162 (*textureHeight)=newHeight;
167 // set texture parameters as you wish
168 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); // GL_LINEAR
169 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); // GL_LINEAR
171 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
172 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);