bool Image32::load_pixels_from_file_32(const char *path) { // free texture free_texture(); // generate image ILuint image_id = 0; ilGenImages(1, &image_id); ilBindImage(image_id); //Load image bool loaded_image = ilLoadImage( path ); if (loaded_image) { // convert image bool converted = ilConvertImage(IL_RGBA, IL_UNSIGNED_BYTE); if (converted == IL_TRUE) { // init dimensions GLuint image_width = (GLuint)ilGetInteger(IL_IMAGE_WIDTH); GLuint image_height = (GLuint)ilGetInteger(IL_IMAGE_HEIGHT); GLuint texture_width = power_of_two(image_width); GLuint texture_height = power_of_two(image_height); if (image_width != texture_width || image_height != texture_height) { // place image in upper left iluImageParameter(ILU_PLACEMENT, ILU_UPPER_LEFT); // resize image iluEnlargeCanvas((int)texture_width, (int)texture_height, 1); } // allocate memory for texture GLuint size = texture_height*texture_width; _pixels_32 = new GLuint[size]; _image_width = image_width; _image_height = image_height; _texture_width = texture_width; _texture_height = texture_height; memcpy(_pixels_32, ilGetData(), size*4); } ilDeleteImages(1,&image_id); } else { std::cout << "unable to load pixels from file: " << path << std::endl; return false; } _pixel_format = GL_RGBA; return true; }
bool LTexture::loadTextureFromFile32( std::string path ) { //Texture loading success bool textureLoaded = false; //Generate and set current image ID ILuint imgID = 0; ilGenImages( 1, &imgID ); ilBindImage( imgID ); //Load image ILboolean success = ilLoadImage( path.c_str() ); //Image loaded successfully if( success == IL_TRUE ) { //Convert image to RGBA success = ilConvertImage( IL_RGBA, IL_UNSIGNED_BYTE ); if( success == IL_TRUE ) { //Initialize dimensions GLuint imgWidth = (GLuint)ilGetInteger( IL_IMAGE_WIDTH ); GLuint imgHeight = (GLuint)ilGetInteger( IL_IMAGE_HEIGHT ); //Calculate required texture dimensions GLuint texWidth = powerOfTwo( imgWidth ); GLuint texHeight = powerOfTwo( imgHeight ); //Texture is the wrong size if( imgWidth != texWidth || imgHeight != texHeight ) { //Place image at upper left iluImageParameter( ILU_PLACEMENT, ILU_UPPER_LEFT ); //Resize image iluEnlargeCanvas( (int)texWidth, (int)texHeight, 1 ); } //Create texture from file pixels textureLoaded = loadTextureFromPixels32( (GLuint*)ilGetData(), imgWidth, imgHeight, texWidth, texHeight ); } //Delete file from memory ilDeleteImages( 1, &imgID ); //Set pixel format mPixelFormat = GL_RGBA; } //Report error if( !textureLoaded ) { printf( "Unable to load %s\n", path.c_str() ); } return textureLoaded; }
HBITMAP TextureControl::GetBlankBitmap(HDC destDC) { if(namedBitmaps.find("Blank") != namedBitmaps.end()) return namedBitmaps["Blank"]; ILuint img = getImageHandle(); ilDefaultImage(); iluImageParameter(ILU_FILTER, ILU_BILINEAR); iluScale(126,126,1); namedBitmaps["Blank"] = ilutConvertToHBitmap(destDC); ilDeleteImage(img); return namedBitmaps["Blank"]; }
bool Image32::load_texture_from_file_32(const char *path) { // generate image ILuint image_id = 0; ilGenImages(1, &image_id); ilBindImage(image_id); //Load image bool got = ilLoadImage( path ); if (got == IL_TRUE) { // convert image bool converted = ilConvertImage(IL_RGBA, IL_UNSIGNED_BYTE); if (converted == IL_TRUE) { // init dimensions GLuint image_width = (GLuint)ilGetInteger(IL_IMAGE_WIDTH); GLuint image_height = (GLuint)ilGetInteger(IL_IMAGE_HEIGHT); GLuint texture_width = power_of_two(image_width); GLuint texture_height = power_of_two(image_height); if (image_width != texture_width || image_height != texture_height) { // place image in upper left iluImageParameter(ILU_PLACEMENT, ILU_UPPER_LEFT); // resize image iluEnlargeCanvas((int)texture_width, (int)texture_height, 1); } bool loaded = load_texture_from_pixels_32((GLuint*)ilGetData(), image_width, image_height, texture_width, texture_height); if (!loaded) { std::cout << "unable to load image: " << path << std::endl; return false; } } ilDeleteImages(1,&image_id); } _pixel_format = GL_RGBA; return true; }
void FractureBox::LoadFractureMap(const char *filename, bool bolden) { if(mFracTexID) ilDeleteImage(mFracTexID); if(mFracTexScaleID) ilDeleteImage(mFracTexScaleID); mFracTexID = ilGenImage(); ilBindImage(mFracTexID); if(!ilLoadImage(filename)) { std::cout << "Error loading " << filename << std::endl; return; } if(!ilConvertImage(IL_RGB, IL_UNSIGNED_BYTE)) { std::cout << "Error converting image " << filename << std::endl; return; } ILinfo imgInfo; iluGetImageInfo(&imgInfo); //if(imgInfo.Origin == IL_ORIGIN_UPPER_LEFT) if(imgInfo.Origin == IL_ORIGIN_LOWER_LEFT) iluFlipImage(); if(bolden) boldenLines(); //Now create the scaled version of the image mFracTexScaleID = ilGenImage(); ilBindImage(mFracTexScaleID); ilCopyImage(mFracTexID); //Scale the image to fit our box const int wid = w() - 2; const int hei = h() - 2; iluImageParameter(ILU_FILTER, ILU_SCALE_MITCHELL); iluScale(wid, hei, imgInfo.Depth); mFracImage = RGBImagePtr(new Fl_RGB_Image(ilGetData(), wid, hei)); image(mFracImage.get()); redraw(); ilBindImage(0); }
HBITMAP TextureControl::GetBitmap(string name, HDC destDC, bool refresh, unsigned int w, unsigned int h) { if(refresh == false && namedBitmaps.find(name) != namedBitmaps.end()) return namedBitmaps[name]; // else bitmap doesn't exist. if(namedImages.find(name) == namedImages.end()) return NULL; //img not loaded ILuint tmp = getImageHandle(); ilCopyImage(namedImages[name]); iluImageParameter(ILU_FILTER, ILU_SCALE_BSPLINE); iluScale(w,h,1); if(alphaMatte) ilEnable(IL_BMP_MATTEALPHAB); else ilEnable(IL_BMP_MATTEALPHA); namedBitmaps[name] = ilutConvertToHBitmap(destDC); ilDeleteImage(tmp); return namedBitmaps[name]; }
std::tr1::shared_ptr<ATexture> ATextureLoader::LoadFile(const std::string& path) { // try to retrieve the texture from the cache, if it exists std::tr1::shared_ptr<ATexture> texture_sp = ATextureCache::GetInstance()->Get(path); if(texture_sp != nullptr){ return texture_sp; } unsigned int width, contentWidth, height, contentHeight; ILuint imageID = ilGenImage(); ilBindImage(imageID); if(!ilLoadImage(path.c_str())){ std::string error = "Fail to load file: " + path; throw std::exception(error.c_str()); return nullptr; } // The content in width = contentWidth = ilGetInteger(IL_IMAGE_WIDTH); height = contentHeight = ilGetInteger(IL_IMAGE_HEIGHT); ILint bpp = ilGetInteger(IL_IMAGE_BYTES_PER_PIXEL); // Actual texture size padded with extra pixels, ensure width and height are power of two. if(!isPowerOfTwo(contentWidth)) width = nextPowerOfTwo(contentWidth); if(!isPowerOfTwo(contentHeight)) height = nextPowerOfTwo(contentHeight); // default background colour will be solid black ilClearColour(0.0f, 0.0f, 0.0f, 1.0f); // TODO: there is still some confusion here....... // flip texture problem is mentioned here: http://www.gamedev.net/topic/308200-devil-textures-upside-down/ // Together with the ilOriginFunc in the graphics_engine.h initialize function, and followed by iLuFlipImage(). // They ensure the image data will be correctly loaded and place on top left corner. And the data will be always stored from top left corner. iluImageParameter(ILU_PLACEMENT, ILU_UPPER_LEFT); // bitmap image seems like storing data upside down, its origin is on the lower left. // jpg, png data seems like using upper left as the origin. if (ilGetInteger(IL_IMAGE_ORIGIN) == IL_ORIGIN_UPPER_LEFT){ // This is for fixing the loaded image upside down in OpenGL... iluFlipImage(); } // set the canvas size. iluEnlargeCanvas(width, height, bpp); // Allocate the memory for the image data. GLubyte* buffer = new GLubyte[width * height * bpp]; // Copy the loaded image data into the texture data depending on how many bytes per pixel if(bpp == 4){ ilCopyPixels(0, 0, 0, width, height, 1, IL_RGBA, GL_UNSIGNED_BYTE, buffer); } else if(bpp == 3){ ilCopyPixels(0, 0, 0, width, height, 1, IL_RGB, GL_UNSIGNED_BYTE, buffer); } else{ std::string error = "Loading process, byte per pixel error, bpp: "+bpp; throw std::exception(error.c_str()); } // Delete the devIL image data ilDeleteImage(imageID); // create a brand new texture to use // put the texture into the texture cache. texture_sp = ATextureCache::GetInstance()->Cache(path, new ATexture(buffer, contentWidth, contentHeight, width, height, GL_RGBA, bpp)); // after texture is created, the buffer data will be uploaded to OpenGL, so no long needed. delete[] buffer; // This is a pointer to the loaded image data return texture_sp; }
void ColladaTexture::ProcessDevilImage() { //int width = ilGetInteger(IL_IMAGE_WIDTH); //int height = ilGetInteger(IL_IMAGE_HEIGHT); ////Fast algorithm to check if a number is a power of two (from wikipedia) ////x is a power of two \Leftrightarrow (x > 0) and ((x & (x - 1)) == 0) //if ((width & (width-1))==0) //int larger; //// who is bigger //if (width>height) // larger=width; //else // larger=height; // Retrieve the width/height of the image file. uint32 width = ilGetInteger(IL_IMAGE_WIDTH); uint32 height = ilGetInteger(IL_IMAGE_HEIGHT); uint32 depth = ilGetInteger(IL_IMAGE_DEPTH); // if (width == 0 || height == 0 || depth == 0) // { // //std::cout << "Invalid image file: '" << TO_std::string(filename).c_str() << "'." << std::endl; // ilDeleteImages(1, &imageId); // return; // } // //Check if the dimensions are power of 2 uint16 countW=0, msbW=0, countH=0, msbH=0, countD=0, msbD=0; uint32 mask = 0x00000001; for(uint16 i=0; i<32; i++) { if((width&mask) == mask) { countW++; msbW = i; } if((height&mask) == mask) { countH++; msbH = i; } if((depth&mask) == mask) { countD++; msbD = i; } mask = mask << 1; } // Round to the closest power of 2 if(countW > 1) { mask = 1 << (msbW-1); if((width&mask) == mask) width = mask<<2; else width = mask<<1; } if(countH > 1) { mask = 1 << (msbH-1); if((height&mask) == mask) height = mask<<2; else height = mask<<1; } if(countD > 1) { mask = 1 << (msbH-1); if((depth&mask) == mask) depth = mask<<2; else depth = mask<<1; } // Resize image if ((countW | countH | countD) > 1) { iluImageParameter(ILU_FILTER, ILU_LINEAR); //if () iluScale(width, height, depth); } }
//----------------------------------------------------------------------- void Image::scale(const PixelBox &src, const PixelBox &scaled, Filter filter) { assert(PixelUtil::isAccessible(src.format)); assert(PixelUtil::isAccessible(scaled.format)); #ifdef NEWSCALING MemoryDataStreamPtr buf; // For auto-delete PixelBox temp; switch (filter) { case FILTER_NEAREST: if(src.format == scaled.format) { // No intermediate buffer needed temp = scaled; } else { // Allocate temporary buffer of destination size in source format temp = PixelBox(scaled.getWidth(), scaled.getHeight(), scaled.getDepth(), src.format); buf.bind(new MemoryDataStream(temp.getConsecutiveSize())); temp.data = buf->getPtr(); } // super-optimized: no conversion switch (PixelUtil::getNumElemBytes(src.format)) { case 1: NearestResampler<1>::scale(src, temp); break; case 2: NearestResampler<2>::scale(src, temp); break; case 3: NearestResampler<3>::scale(src, temp); break; case 4: NearestResampler<4>::scale(src, temp); break; case 6: NearestResampler<6>::scale(src, temp); break; case 8: NearestResampler<8>::scale(src, temp); break; case 12: NearestResampler<12>::scale(src, temp); break; case 16: NearestResampler<16>::scale(src, temp); break; default: // never reached assert(false); } if(temp.data != scaled.data) { // Blit temp buffer PixelUtil::bulkPixelConversion(temp, scaled); } break; case FILTER_LINEAR: case FILTER_BILINEAR: switch (src.format) { case PF_L8: case PF_A8: case PF_BYTE_LA: case PF_R8G8B8: case PF_B8G8R8: case PF_R8G8B8A8: case PF_B8G8R8A8: case PF_A8B8G8R8: case PF_A8R8G8B8: case PF_X8B8G8R8: case PF_X8R8G8B8: if(src.format == scaled.format) { // No intermediate buffer needed temp = scaled; } else { // Allocate temp buffer of destination size in source format temp = PixelBox(scaled.getWidth(), scaled.getHeight(), scaled.getDepth(), src.format); buf.bind(new MemoryDataStream(temp.getConsecutiveSize())); temp.data = buf->getPtr(); } // super-optimized: byte-oriented math, no conversion switch (PixelUtil::getNumElemBytes(src.format)) { case 1: LinearResampler_Byte<1>::scale(src, temp); break; case 2: LinearResampler_Byte<2>::scale(src, temp); break; case 3: LinearResampler_Byte<3>::scale(src, temp); break; case 4: LinearResampler_Byte<4>::scale(src, temp); break; default: // never reached assert(false); } if(temp.data != scaled.data) { // Blit temp buffer PixelUtil::bulkPixelConversion(temp, scaled); } break; case PF_FLOAT32_RGB: case PF_FLOAT32_RGBA: if (scaled.format == PF_FLOAT32_RGB || scaled.format == PF_FLOAT32_RGBA) { // float32 to float32, avoid unpack/repack overhead LinearResampler_Float32::scale(src, scaled); break; } // else, fall through default: // non-optimized: floating-point math, performs conversion but always works LinearResampler::scale(src, scaled); } break; default: // fall back to old, slow, wildly incorrect DevIL code #endif #if OGRE_NO_DEVIL == 0 ILuint ImageName; ilGenImages( 1, &ImageName ); ilBindImage( ImageName ); // Convert image from OGRE to current IL image ILUtil::fromOgre(src); // set filter iluImageParameter(ILU_FILTER, getILFilter(filter)); // do the scaling if(!iluScale(scaled.getWidth(), scaled.getHeight(), scaled.getDepth())) { OGRE_EXCEPT( Exception::ERR_INTERNAL_ERROR, iluErrorString(ilGetError()), "Image::scale" ) ; } ILUtil::toOgre(scaled); ilDeleteImages(1, &ImageName); // return to default filter iluImageParameter(ILU_FILTER, ILU_NEAREST); #else OGRE_EXCEPT( Exception::UNIMPLEMENTED_FEATURE, "Scaling algorithm not implemented without DevIL", "Image::scale" ) ; #endif #ifdef NEWSCALING } #endif }
int main(int argc, char* argv[]) { if ( argc < 4 ) { fprintf(stderr, "usage: tool_font filename.ttf chars.txt ptsize <style> <supersample>\n"); return -1; } char szFont[256]; strcpy(szFont, argv[1]); *strstr(szFont, ".ttf") = 0; int nFontSize = atol(argv[3]); int nStyle = TTF_STYLE_NORMAL; if ( argc > 3 ) { for ( int i = 0 ; argv[4][i] != 0 ; i++ ) { switch ( argv[4][i] ) { case 'b': nStyle |= TTF_STYLE_BOLD; break; case 'i': nStyle |= TTF_STYLE_ITALIC; break; case 'u': nStyle |= TTF_STYLE_UNDERLINE; break; } } } float fScale = 1.0f; if ( argc > 5 ) { fScale = 1.0f/atof(argv[6]); } SDL_Init(SDL_INIT_VIDEO); TTF_Init(); TTF_Font* pFont = TTF_OpenFont(argv[1], nFontSize/fScale); if ( !pFont ) { fprintf(stderr, "could not open %s @ %d points\n", argv[1], nFontSize); return -1; } int nAscent = TTF_FontAscent(pFont); int nDescent = TTF_FontDescent(pFont); int nHeight = TTF_FontHeight(pFont); char szStyle[4] = { 0 }; char* pchStyle = szStyle; if ( nStyle & TTF_STYLE_BOLD ) *pchStyle++ = 'b'; if ( nStyle & TTF_STYLE_ITALIC ) *pchStyle++ = 'i'; if ( nStyle & TTF_STYLE_UNDERLINE ) *pchStyle++ = 'u'; TTF_SetFontStyle(pFont, nStyle); char achGlyphs[1024]; int cGlyphs = 0; FILE* fpChars = fopen(argv[2], "r"); while ( EOF != (achGlyphs[cGlyphs++] = fgetc(fpChars)) ); fclose(fpChars); cGlyphs--; SDL_Rect* aRects = new SDL_Rect[cGlyphs]; SDL_Surface** apSurfaces = new SDL_Surface*[cGlyphs]; for ( int iGlyph = 0 ; iGlyph < cGlyphs ; ++iGlyph ) { SDL_Color color = { 255, 255, 255, 0 }; char szGlyph[2] = { 0 }; szGlyph[0] = achGlyphs[iGlyph]; apSurfaces[iGlyph] = TTF_RenderText_Blended(pFont, szGlyph, color); // char szFile[128]; // sprintf(szFile, "textures/fonts/%s/%d.raw", argv[1], szGlyph[0]); // FILE* fp = fopen(szFile, "wb"); // fwrite(apSurfaces[iGlyph]->pixels, apSurfaces[iGlyph]->pitch*apSurfaces[iGlyph]->h, 1, fp); // fclose(fp); } struct DIMS { int w, h; }; DIMS aDims[] = { 64, 64, 64, 128, 64, 256, 128, 64, 128, 128, 128, 256, 256, 64, 256, 128, 256, 256, 64, 512, 128, 512, 256, 512, 512, 64, 512, 128, 512, 256, 512, 512, 64, 1024, 128, 1024, 256, 1024, 256, 1024, 512, 1024, 1024, 64, 1024, 128, 1024, 256, 1024, 512, 1024, 1024, 64, 2048, 128, 2048, 256, 2048, 512, 2048, 1024, 2048, 2048, 64, 2048, 128, 2048, 256, 2048, 512, 2048, 1024, 2048, 2048, /* 512, 64, 512, 128, 512, 256, 512, 512, 64, 512, 128, 512, 256, 512, 1024, 64, 1024, 128, 1024, 256, 1024, 512, 64, 1024, 128, 1024, 256, 1024, 512, 1024, 2048, 64, 2048, 128, 2048, 256, 2048, 1024, 2048, 2048, 64, 2048, 128, 2048, 256, 2048, 512, 2048, 1024, 2048 */ }; int cDims = sizeof(aDims)/sizeof(DIMS); for ( int iDims = 0 ; iDims < cDims ; ++iDims ) { int nWidth = aDims[iDims].w; int nHeight = aDims[iDims].h; SDL_Surface* pSurfaceGeneric = SDL_CreateRGBSurface(SDL_SWSURFACE, nWidth, nHeight, 32, 0, 0, 0, 0); SDL_Surface* pSurface = SDL_ConvertSurface(pSurfaceGeneric, apSurfaces[0]->format, 0); SDL_FillRect(pSurface, NULL, SDL_MapRGBA(pSurface->format, 0,0,0,0)); bool* aabyUsage = new bool[nHeight*nWidth]; memset(aabyUsage, 0, nHeight*nWidth*sizeof(bool)); bool bFit = true; for ( int iGlyph = 0 ; iGlyph < cGlyphs ; ++iGlyph ) { if ( !Fit(aabyUsage, pSurface, apSurfaces[iGlyph], &aRects[iGlyph], fScale) ) { bFit = false; break; } } if ( bFit ) { fprintf(stderr, "glyphs fit into %d x %d texture\n", nWidth, nHeight); char szFile[256]; sprintf(szFile, "textures/fonts/%s%d%s.png", szFont, nFontSize, szStyle); for ( int y = 0 ; y < pSurface->h ; ++y ) { for ( int x = 0 ; x < pSurface->w ; ++x ) { unsigned char r = ((unsigned char*)pSurface->pixels)[x*4 + y*pSurface->w*4 + 0]; unsigned char g = ((unsigned char*)pSurface->pixels)[x*4 + y*pSurface->w*4 + 1]; unsigned char b = ((unsigned char*)pSurface->pixels)[x*4 + y*pSurface->w*4 + 2]; unsigned char a = (r+g+b)/3; r = g = b = 255; ((unsigned char*)pSurface->pixels)[x*4 + y*pSurface->w*4 + 0] = r; ((unsigned char*)pSurface->pixels)[x*4 + y*pSurface->w*4 + 1] = g; ((unsigned char*)pSurface->pixels)[x*4 + y*pSurface->w*4 + 2] = b; ((unsigned char*)pSurface->pixels)[x*4 + y*pSurface->w*4 + 3] = a; } } ILuint iImage = 0; ilInit(); ilGenImages(1, &iImage); ilBindImage(iImage); ilTexImage(pSurface->w, pSurface->h, 1, 4, IL_RGBA, IL_UNSIGNED_BYTE, pSurface->pixels); // ilConvertImage(IL_LUMINANCE, IL_UNSIGNED_BYTE); iluFlipImage(); iluImageParameter(ILU_FILTER, ILU_SCALE_LANCZOS3); iluScale(pSurface->w*fScale, pSurface->h*fScale, 1); ilSaveImage(szFile); int nDescent = TTF_FontDescent(pFont); char szFontFile[256]; sprintf(szFontFile, "fonts/%s%d%s.font", szFont, nFontSize, szStyle); FILE* fp = fopen(szFontFile, "w"); fprintf(fp, "<font name=\"%s\" height=\"%d\" lineskip=\"%d\" shader=\"%s,srcalpha,invsrcalpha\">\n", szFont, int(TTF_FontHeight(pFont)*fScale), int(TTF_FontLineSkip(pFont)*fScale), szFile); for ( int iGlyph = 0 ; iGlyph < cGlyphs ; ++iGlyph ) { int xmin, xmax, ymin, ymax, adv; TTF_GlyphMetrics(pFont, achGlyphs[iGlyph], &xmin, &xmax, &ymin, &ymax, &adv); fprintf(fp, "%c<glyph ascii=\"%d\" adv=\"%d\" dims=\"%d,%d\" origin=\"%d,%d\" u0=\"%f\" v0=\"%f\" u1=\"%f\" v1=\"%f\"/>\n", 9, achGlyphs[iGlyph], int(adv*fScale), int(aRects[iGlyph].w*fScale), int(aRects[iGlyph].h*fScale), int(xmin*fScale), int(-nDescent*fScale), float(aRects[iGlyph].x)/float(pSurface->w), float(aRects[iGlyph].y)/float(pSurface->h), float(aRects[iGlyph].x+aRects[iGlyph].w)/float(pSurface->w), float(aRects[iGlyph].y+aRects[iGlyph].h)/float(pSurface->h)); } fprintf(fp, "</font>\n"); fclose(fp); // FILE* fp = fopen("textures/fonts/blockup.raw", "wb"); // fwrite(pSurface->pixels, pSurface->pitch*pSurface->h, 1, fp); // fclose(fp); return 0; } delete [] aabyUsage; SDL_FreeSurface(pSurface); SDL_FreeSurface(pSurfaceGeneric); } return 0; }
bool TextureControl::GenerateComposite(string sourceName,string modName,string outputName, unsigned int destSize, unsigned int mode ) { ILuint srctex = 0; ILuint modtex = 0; ILuint canvas = 0; if(namedImages.find(modName) == namedImages.end()) // mod not selected? return false; modtex = namedImages[modName]; ilBindImage(modtex); ILuint mW = ilGetInteger(IL_IMAGE_WIDTH); ILuint mH = ilGetInteger(IL_IMAGE_HEIGHT); if(destSize && (mW != destSize)) { iluImageParameter(ILU_FILTER, ILU_SCALE_BSPLINE); iluScale(destSize,destSize,1); mW = mH = destSize; } if(namedImages.find(sourceName) == namedImages.end()) // source not selected? return false; srctex = namedImages[sourceName]; ilBindImage(srctex); ILuint sW = ilGetInteger(IL_IMAGE_WIDTH); ILuint sH = ilGetInteger(IL_IMAGE_HEIGHT); if(destSize && (sW != destSize)) { iluImageParameter(ILU_FILTER, ILU_SCALE_BSPLINE); iluScale(destSize,destSize,1); sW = sH = destSize; } if(namedImages.find(outputName) != namedImages.end()) // already have an output? ilDeleteImage(namedImages[outputName]); if(sW < mW) { ilBindImage(modtex); iluImageParameter(ILU_FILTER, ILU_SCALE_BSPLINE); iluScale(sW,sH,1); ilBindImage(srctex); } else if(sW > mW){ iluImageParameter(ILU_FILTER, ILU_SCALE_BSPLINE); iluScale(mW,mH,1); sW=mW; sH=mH; } namedImages[outputName] = getImageHandle(); ilTexImage(sW,sH,1,4,IL_RGBA,IL_UNSIGNED_BYTE,NULL); ilBlit(srctex,0,0,0,0,0,0,sW,sH,1); ilEnable(IL_BLIT_BLEND); ilBlit(modtex,0,0,0,0,0,0,sW,sH,1); return true; }
// Window procedure, handles all messages for this program LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { static HMENU hMenu; static ILuint Colours; static RECT Rect; static PAINTSTRUCT ps; static HDROP hDrop; static TCHAR OpenFilter[2048]; static TCHAR SaveFilter[2048]; static TCHAR *OFilter[] = { L"All Files (*.*)", L"*.*", L"Alias|Wavefront Files (*.pix)", L"*.pix", L"Cut Files (*.cut)", L"*.cut", L"Dcx Files (*.dcx)", L"*.dcx", L"Graphics Interchange Format (*.gif)", L"*.gif", L"Half-Life Model Files (*.mdl)", L"*.mdl", L"Homeworld Image Files (*.lif)", L"*.lif", L"Image Files (All Supported Types)", L"*.jpe;*.jpg;*.jpeg;*.lif;*.bmp;*.ico;*.pbm;*.pgm;*.pnm;*.ppm;*.png;*.bw;*.rgb;*.rgba;*.sgi;*.tga;*.tif;*.tiff;*.pcx;*.xpm;*.psp;*.psd;*.pix;*.pxr;*.cut;*.dcx", L"Jpeg Files (*.jpe, *.jpg, *.jpeg)", L"*.jpe;*.jpg;*.jpeg", L"Kodak Photo CD Files (*.pcd)", L"*.pcd", L"Microsoft Bitmap Files (*.bmp)", L"*.bmp", L"Microsoft DirectDraw Surface (*.dds)", L"*.dds", L"Microsoft Icon Files (*.ico, *.cur)", L"*.ico, *.cur", L"Multiple Network Graphics Files (*.mng)", L"*.mng", L"Paint Shop Pro Files (*.psp)", L"*.psp", L"PhotoShop Files (*.psd)", L"*.psd", L"Pic Files (*.pic)", L"*.pic", L"Pixar Files (*.pix)", L"*.pix", L"Portable AnyMap Files (*.pbm, *.pgm, *.pnm, *.ppm)", L"*.pbm;*.pgm;*.pnm;*.ppm", L"Portable Network Graphics Files (*.png)", L"*.png", L"Sgi Files (*.sgi)", L"*.bw;*.rgb;*.rgba;*.sgi", L"Targa Files (*.tga, *.vda, *.icb, *.vst)", L"*.tga;*.vda;*.icb;*.vst", L"Tiff Files (*.tif)", L"*.tif;*.tiff", L"Valve Texture Files (*.vtf)", L"*.vtf", L"Quake Wal Files (*.wal)", L"*.wal", L"X PixelMap (*.xpm)", L"*.xpm", L"ZSoft Pcx Files (*.pcx)", L"*.pcx", L"\0\0" }; static TCHAR *SFilter[] = { L"All Files (*.*)", L"*.*", L"C-Style Header (*.h)", L"*.h", L"Jpeg Files (*.jpe, *.jpg, *.jpeg)", L"*.jpe;*.jpg;*.jpeg", L"Microsoft Bitmap Files (*.bmp)", L"*.bmp", L"Microsoft DirectDraw Surface (*.dds)", L"*.dds", L"PhotoShop Files (*.psd)", L"*.psd", L"Portable AnyMap Files (*.pbm, *.pgm, *.ppm)", L"*.pbm;*.pgm;*.ppm", L"Portable Network Graphics Files (*.png)", L"*.png", L"Sgi Files (*.sgi)", L"*.bw;*.rgb;*.rgba;*.sgi", L"Targa Files (*.tga)", L"*.tga", L"Tiff Files (*.tif)", L"*.tif", L"ZSoft Pcx Files (*.pcx)", L"*.pcx", L"\0\0" }; static OPENFILENAME Ofn = { sizeof(OPENFILENAME), hWnd, NULL, OpenFilter, NULL, 0, 0, OpenFileName, 2048, NULL, 0, NULL, NULL, OFN_HIDEREADONLY | OFN_FILEMUSTEXIST | OFN_PATHMUSTEXIST, 0, 0, NULL, NULL, NULL, NULL }; POINT CurMouse; static POINT PrevMouse; static ILboolean MouseDown = IL_FALSE; static RECT WinSize; unsigned int currentColor = 0x80000000; unsigned int originalColor = 0x80000000; bool userClickedOK; ILclampf Red = 255, Green = 255, Blue = 255; ILubyte *AlphaChannel; ILenum Origin; switch (message) { case WM_CREATE: GenFilterString(OpenFilter, OFilter); GenFilterString(SaveFilter, SFilter); hDC = GetDC(hWnd); DragAcceptFiles(hWnd, TRUE); ReleaseDC(hWnd, hDC); break; case WM_CLOSE: #ifdef _DEBUG _CrtDumpMemoryLeaks(); #endif DestroyGDI(); DestroyWindow(hWnd); UnregisterClass(TITLE, hInstance); break; case WM_DESTROY: PostQuitMessage(0); break; case WM_PAINT: GetWindowRect(HWnd, &WinSize); // Shouldn't be here! hDC = BeginPaint(hWnd, &ps); //StretchBlt(hDC, 0, 0, WinSize.right - WinSize.left, // WinSize.bottom - WinSize.top, BackHDC, 0, 0, 1, 1, SRCCOPY); WinSize.right -= WinSize.left; WinSize.bottom -= WinSize.top; WinSize.top = 0; WinSize.left = 0; FillRect(hDC, &WinSize, BackBrush); BitBlt(hDC, XOff, YOff, (WORD)BmpInfo.biWidth, (WORD)BmpInfo.biHeight, hMemDC, 0, 0, SRCCOPY); EndPaint(hWnd, &ps); ValidateRect(hWnd, NULL); break; case WM_KEYDOWN: if (wParam == VK_ESCAPE) PostQuitMessage(0); // View the next image in the animation chain. if (wParam == VK_RIGHT) { ilBindImage(Undos[0]); // @TODO: Implement undos better with this. CurImage++; if (CurImage > ilGetInteger(IL_NUM_IMAGES)) CurImage = 0; // Go back to the beginning of the animation. ilActiveImage(CurImage); ilutRenderer(ILUT_WIN32); ResizeWin(); CreateGDI(); } if (wParam == '0') { ilBindImage(Undos[0]); // @TODO: Implement undos better with this. ilutRenderer(ILUT_WIN32); ResizeWin(); CreateGDI(); } if (wParam == '1') { ilActiveMipmap(1); ilutRenderer(ILUT_WIN32); ResizeWin(); CreateGDI(); } else if (wParam == '2') { ilActiveMipmap(2); ilutRenderer(ILUT_WIN32); ResizeWin(); CreateGDI(); } else if (wParam == '3') { ilActiveMipmap(3); ilutRenderer(ILUT_WIN32); ResizeWin(); CreateGDI(); } else if (wParam == '4') { ilActiveMipmap(4); ilutRenderer(ILUT_WIN32); ResizeWin(); CreateGDI(); } else if (wParam == '5') { ilActiveMipmap(5); ilutRenderer(ILUT_WIN32); ResizeWin(); CreateGDI(); } else if (wParam == '6') { ilActiveMipmap(6); ilutRenderer(ILUT_WIN32); ResizeWin(); CreateGDI(); } else if (wParam == '7') { ilActiveMipmap(7); ilutRenderer(ILUT_WIN32); ResizeWin(); CreateGDI(); } else if (wParam == '8') { ilActiveMipmap(8); ilutRenderer(ILUT_WIN32); ResizeWin(); CreateGDI(); } else if (wParam == '9') { ilActiveMipmap(9); ilutRenderer(ILUT_WIN32); ResizeWin(); CreateGDI(); } // View the previous image in the animation chain. if (wParam == VK_LEFT) { ilBindImage(Undos[0]); // @TODO: Implement undos better with this. CurImage--; if (CurImage < 0) CurImage = 0; ilActiveImage(CurImage); ilutRenderer(ILUT_WIN32); ResizeWin(); CreateGDI(); } if (wParam == VK_PRIOR) { if (!GetPrevImage()) break; DestroyGDI(); if (UndoSize == 0) UndoSize = 1; ilDeleteImages(UndoSize, Undos); UndoSize = 0; XOff = 0; YOff = 0; ilGenImages(1, Undos); ilBindImage(Undos[0]); //last_elapsed = SDL_GetTicks(); if (!ilLoadImage(OpenFileName)) { wsprintf(CurFileName, L"%s", OpenFileName); wsprintf(NewTitle, L"%s - Could not open %s", TITLE, OpenFileName); SetWindowText(hWnd, NewTitle); return (0L); } CurImage = 0; //cur_elapsed = SDL_GetTicks(); elapsed = cur_elapsed - last_elapsed; last_elapsed = cur_elapsed; ilutRenderer(ILUT_WIN32); ResizeWin(); CreateGDI(); wsprintf(CurFileName, L"%s", OpenFileName); wsprintf(NewTitle, L"%s - %s: %u ms", TITLE, OpenFileName, (unsigned int)elapsed); SetWindowText(hWnd, NewTitle); } if (wParam == VK_NEXT) { if (!GetNextImage()) break; DestroyGDI(); if (UndoSize == 0) UndoSize = 1; ilDeleteImages(UndoSize, Undos); UndoSize = 0; XOff = 0; YOff = 0; ilGenImages(1, Undos); ilBindImage(Undos[0]); //last_elapsed = SDL_GetTicks(); if (!ilLoadImage(OpenFileName)) { wsprintf(CurFileName, L"%s", OpenFileName); wsprintf(NewTitle, L"%s - Could not open %s", TITLE, OpenFileName); SetWindowText(hWnd, NewTitle); return (0L); } CurImage = 0; //cur_elapsed = SDL_GetTicks(); elapsed = cur_elapsed - last_elapsed; last_elapsed = cur_elapsed; ilutRenderer(ILUT_WIN32); ResizeWin(); CreateGDI(); wsprintf(CurFileName, L"%s", OpenFileName); wsprintf(NewTitle, L"%s - %s: %u ms", TITLE, OpenFileName, (unsigned int)elapsed); SetWindowText(hWnd, NewTitle); } InvalidateRect(hWnd, NULL, FALSE); break; // Moves the "viewport" case WM_MOUSEMOVE: if (!MouseDown) break; GetCursorPos(&CurMouse); XOff += CurMouse.x - PrevMouse.x; YOff += CurMouse.y - PrevMouse.y; PrevMouse.x = CurMouse.x; PrevMouse.y = CurMouse.y; InvalidateRect(hWnd, NULL, FALSE); break; case WM_LBUTTONDOWN: MouseDown = IL_TRUE; GetCursorPos(&PrevMouse); break; case WM_LBUTTONUP: MouseDown = IL_FALSE; break; case WM_DROPFILES: hDrop = (HDROP)wParam; DragQueryFile(hDrop, 0, OpenFileName, 512); DestroyGDI(); ilDeleteImages(UndoSize, Undos); UndoSize = 0; ilGenImages(1, Undos); ilBindImage(Undos[0]); ilLoadImage(OpenFileName); CurImage = 0; ilutRenderer(ILUT_WIN32); ResizeWin(); CreateGDI(); wsprintf(CurFileName, L"%s", OpenFileName); wsprintf(NewTitle, L"%s - %s", TITLE, OpenFileName); SetWindowText(hWnd, NewTitle); DragFinish(hDrop); return 0; case WM_COMMAND: FilterType = LOWORD(wParam); switch (LOWORD(wParam)) { case ID_FILE_EXIT: PostMessage(hWnd, WM_CLOSE, 0, 0); return (0L); case ID_HELP_ABOUT: DialogBox (hInstance, MAKEINTRESOURCE(IDD_DIALOG_ABOUT), hWnd, AboutDlgProc); return (0L); case ID_FILE_PROPERTIES: DialogBox (hInstance, MAKEINTRESOURCE(IDD_DIALOG_PROPERTIES), hWnd, PropertiesDlgProc); return (0L); case ID_BATCHCONVERT: DialogBox (hInstance, MAKEINTRESOURCE(IDD_DIALOG_BATCHCONV), hWnd, BatchDlgProc); return (0L); case ID_EFFECTS_COUNTCOLORS: Colours = iluColoursUsed(); TCHAR ColourString[255]; wsprintf(ColourString, L"The number of colours in this image is: %d", Colours); MessageBox(NULL, ColourString, L"Colour Count", MB_OK); return (0L); case ID_EFFECTSTOOLS_BACKGROUNDCOLOUR: //userClickedOK = FSColorPickerDoModal(¤tColor, true, &originalColor, true, 0); userClickedOK = 0; if (userClickedOK) { Red = (ILfloat)((currentColor & 0xff0000) >> 16) / 255.0f; Green = (ILfloat)((currentColor & 0xff00) >> 8) / 255.0f; Blue = (ILfloat)(currentColor & 0xff) / 255.0f; ilClearColour(Red, Green, Blue, 1.0f); } return (0L); case ID_EDIT_COPY: ilutSetWinClipboard(); return (0L); case ID_EDIT_PASTE: ILuint Test; ilGenImages(1, &Test); ilBindImage(Test); // Check if there's anything in the clipboard. if (!ilutGetWinClipboard()) { ilDeleteImages(1, &Test); return (0L); } ilDeleteImages(1, &Test); DestroyGDI(); ilDeleteImages(UndoSize, Undos); UndoSize = 0; XOff = 0; YOff = 0; ilGenImages(1, Undos); ilBindImage(Undos[0]); ilutGetWinClipboard(); wsprintf(CurFileName, L"Clipboard Paste"); wsprintf(NewTitle, L"%s - Pasted from the Clipboard", TITLE); SetWindowText(hWnd, NewTitle); //ilConvertImage(IL_BGRA); ilutRenderer(ILUT_WIN32); ResizeWin(); CreateGDI(); return (0L); // @TODO: Will probably fail if no image loaded! case ID_FILE_PRINT: /*PRINTDLG Pd; DOCINFO Di; //HDC PrintDC; //HBITMAP PrintReplace; memset(&Pd, 0, sizeof(PRINTDLG)); Pd.lStructSize = sizeof(PRINTDLG); Pd.hwndOwner = hWnd; Pd.Flags = PD_RETURNDC; Pd.nCopies = 1; Pd.nFromPage = 0xFFFF; Pd.nToPage = 0xFFFF; Pd.nMinPage = 1; Pd.nMaxPage = 0xFFFF; if (!PrintDlg(&Pd)) return (0L); Di.cbSize = sizeof(DOCINFO); Di.lpszDocName = L"DevIL Printing Test"; Di.lpszOutput = NULL; Di.lpszDatatype = NULL; Di.fwType = 0; StartDoc(Pd.hDC, &Di); StartPage(Pd.hDC); //PrintDC = CreateCompatibleDC(Pd.hDC); //PrintReplace = (HBITMAP)SelectObject(PrintDC, hBitmap); StretchBlt(Pd.hDC, 0, 0, Width * 2, Height * 2, hMemDC, 0, 0, Width, Height, SRCCOPY); EndPage(Pd.hDC); EndDoc(Pd.hDC); //DeleteObject(PrintReplace); //DeleteDC(PrintDC); DeleteDC(Pd.hDC);*/ ilutWinPrint(0, 0, ilGetInteger(IL_IMAGE_WIDTH) * 2, ilGetInteger(IL_IMAGE_HEIGHT) * 2, hDC); return (0L); case ID_FILE_LOAD: wsprintf(OpenFileName, L"*.*"); Ofn.lpstrFilter = OpenFilter; Ofn.lpstrFile = OpenFileName; Ofn.lpstrTitle = L"Open File"; Ofn.nFilterIndex = 1; Ofn.Flags = OFN_HIDEREADONLY | OFN_FILEMUSTEXIST | OFN_PATHMUSTEXIST; if (!GetOpenFileName(&Ofn)) return (0L); DestroyGDI(); if (UndoSize == 0) UndoSize = 1; ilDeleteImages(UndoSize, Undos); UndoSize = 0; XOff = 0; YOff = 0; ilGenImages(1, Undos); ilBindImage(Undos[0]); //last_elapsed = SDL_GetTicks(); if (!ilLoadImage(OpenFileName)) return (0L); CurImage = 0; //cur_elapsed = SDL_GetTicks(); elapsed = cur_elapsed - last_elapsed; last_elapsed = cur_elapsed; //iluBuildMipmaps(); //ilConvertImage(IL_RGBA, IL_UNSIGNED_BYTE); //ilEnable(IL_NVIDIA_COMPRESS); //ilEnable(IL_SQUISH_COMPRESS); //ilSetInteger(IL_DXTC_FORMAT, IL_DXT5); //free(ilCompressDXT(ilGetData(), ilGetInteger(IL_IMAGE_WIDTH), ilGetInteger(IL_IMAGE_HEIGHT), 1, IL_DXT5, &Size)); //free(ilNVidiaCompressDXT(ilGetData(), ilGetInteger(IL_IMAGE_WIDTH), ilGetInteger(IL_IMAGE_HEIGHT), 1, IL_DXT5)); ilutRenderer(ILUT_WIN32); ResizeWin(); CreateGDI(); wsprintf(CurFileName, L"%s", OpenFileName); wsprintf(NewTitle, L"%s - %s: %u ms", TITLE, OpenFileName, (unsigned int)elapsed); SetWindowText(hWnd, NewTitle); return (0L); case ID_FILE_OPENURL: if (DialogBox(hInstance, MAKEINTRESOURCE(IDD_DIALOG_FILTER), hWnd, FilterDlgProc) != TRUE) { return (0L); } DestroyGDI(); ilDeleteImages(UndoSize, Undos); UndoSize = 0; XOff = 0; YOff = 0; ilGenImages(1, Undos); ilBindImage(Undos[0]); /*if (!ilutWinLoadUrl(FilterEditString)) return (0L);*/ ilutRenderer(ILUT_WIN32); ResizeWin(); CreateGDI(); wsprintf(NewTitle, L"%s - %s", TITLE, FilterEditString); SetWindowText(hWnd, NewTitle); return (0L); case ID_FILE_SAVE: wsprintf(SaveFileName, L"monkey.tga"); Ofn.lpstrFilter = SaveFilter; Ofn.lpstrFile = SaveFileName; Ofn.lpstrTitle = L"Save File"; Ofn.nFilterIndex = 1; Ofn.Flags = OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT; if (!GetSaveFileName(&Ofn)) return (0L); ilEnable(IL_FILE_OVERWRITE); //ilBindImage(Undos[0]); //@TODO: Do better here... //last_elapsed = SDL_GetTicks(); ilSaveImage(SaveFileName); //cur_elapsed = SDL_GetTicks(); elapsed = cur_elapsed - last_elapsed; last_elapsed = cur_elapsed; wsprintf(CurFileName, L"%s", SaveFileName); wsprintf(NewTitle, L"%s - %s: %u ms", TITLE, SaveFileName, (unsigned int)elapsed); SetWindowText(hWnd, NewTitle); return (0L); case ID_EDIT_UNDOLEVEL: if (DialogBox(hInstance, MAKEINTRESOURCE(IDD_DIALOG_FILTER), hWnd, FilterDlgProc) == TRUE) { NumUndosAllowed = FilterParamInt <= 10 ? FilterParamInt : 10; } return (0L); case ID_EDIT_UNDO: if (UndoSize && NumUndosAllowed) { ilDeleteImages(1, &Undos[UndoSize]); ilBindImage(Undos[--UndoSize]); ResizeWin(); CreateGDI(); } return (0L); case ID_EDIT_VIEWIMAGENUM: if (DialogBox(hInstance, MAKEINTRESOURCE(IDD_DIALOG_FILTER), hWnd, FilterDlgProc) == TRUE) { ilBindImage(Undos[0]); // @TODO: Implement undos better with this. ilActiveImage(FilterParamInt); ilutRenderer(ILUT_WIN32); ResizeWin(); CreateGDI(); } return (0L); case ID_EDIT_VIEWFACE: if (DialogBox(hInstance, MAKEINTRESOURCE(IDD_DIALOG_FILTER), hWnd, FilterDlgProc) == TRUE) { ilActiveFace(FilterParamInt); ilutRenderer(ILUT_WIN32); ResizeWin(); CreateGDI(); } return (0L); case ID_EDIT_VIEWMIPMAP: if (DialogBox(hInstance, MAKEINTRESOURCE(IDD_DIALOG_FILTER), hWnd, FilterDlgProc) == TRUE) { ilActiveMipmap(FilterParamInt); ilutRenderer(ILUT_WIN32); ResizeWin(); CreateGDI(); } return (0L); case ID_EDIT_NEXT: ilBindImage(Undos[0]); // @TODO: Implement undos better with this. CurImage++; ilActiveImage(CurImage); ilutRenderer(ILUT_WIN32); ResizeWin(); CreateGDI(); return (0L); case ID_EDIT_PREV: ilBindImage(Undos[0]); // @TODO: Implement undos better with this. CurImage--; ilActiveImage(CurImage); ilutRenderer(ILUT_WIN32); ResizeWin(); CreateGDI(); return (0L); } if (++UndoSize > NumUndosAllowed) { if (NumUndosAllowed > 0) { UndoSize = NumUndosAllowed; ilDeleteImages(1, &Undos[0]); memcpy(Undos, Undos+1, NumUndosAllowed * sizeof(ILuint)); ilBindImage(Undos[UndoSize]); } } if (NumUndosAllowed > 0) { ilGetIntegerv(IL_ACTIVE_IMAGE, (ILint*)&Undos[UndoSize]); /*ilGenImages(1, &Undos[UndoSize]); ilBindImage(Undos[UndoSize]); ilCopyImage(Undos[UndoSize-1]);*/ Undos[UndoSize] = ilCloneCurImage(); ilBindImage(Undos[UndoSize]); } DestroyGDI(); switch (LOWORD(wParam)) { case ID_CONVERT_PALETTE: ilConvertImage(IL_COLOUR_INDEX, IL_UNSIGNED_BYTE); break; case ID_CONVERT_RGB: ilConvertImage(IL_RGB, ilGetInteger(IL_IMAGE_TYPE)); break; case ID_CONVERT_RGBA: ilConvertImage(IL_RGBA, ilGetInteger(IL_IMAGE_TYPE)); break; case ID_CONVERT_BGR: ilConvertImage(IL_BGR, ilGetInteger(IL_IMAGE_TYPE)); break; case ID_CONVERT_BGRA: ilConvertImage(IL_BGRA, ilGetInteger(IL_IMAGE_TYPE)); break; case ID_CONVERT_LUMINANCE: ilConvertImage(IL_LUMINANCE, ilGetInteger(IL_IMAGE_TYPE)); break; case ID_CONVERT_LUMINANCEALPHA: ilConvertImage(IL_LUMINANCE_ALPHA, ilGetInteger(IL_IMAGE_TYPE)); break; case ID_EDIT_VIEWALPHA: Origin = ilGetInteger(IL_ORIGIN_MODE); AlphaChannel = ilGetAlpha(IL_UNSIGNED_BYTE); ilTexImage(ilGetInteger(IL_IMAGE_WIDTH), ilGetInteger(IL_IMAGE_HEIGHT), ilGetInteger(IL_IMAGE_DEPTH), 1, IL_LUMINANCE, IL_UNSIGNED_BYTE, AlphaChannel); free(AlphaChannel); ilRegisterOrigin(Origin); break; case ID_EFFECTS_FLIP: iluFlipImage(); break; case ID_EFFECTS_MIRROR: iluMirror(); break; case ID_FILTER_EMBOSS: iluEmboss(); break; case ID_FILTER_EQUALIZE: iluEqualize(); break; case ID_FILTER_ALIENIFY: iluAlienify(); break; case ID_FILTER_NEGATIVE: iluNegative(); break; case ID_EFFECTS_FILTERS_EDGEDETECT_EMBOSS: iluEdgeDetectE(); break; case ID_EFFECTS_FILTERS_EDGEDETECT_SOBEL: iluEdgeDetectS(); break; case ID_EFFECTS_FILTERS_EDGEDETECT_PREWITT: iluEdgeDetectP(); break; case ID_FILTER_NOISE: if (DialogBox(hInstance, MAKEINTRESOURCE(IDD_DIALOG_FILTER), hWnd, FilterDlgProc) == TRUE) { iluNoisify(FilterParamFloat); } break; case ID_EFFECTS_FILTERS_WAVE: if (DialogBox(hInstance, MAKEINTRESOURCE(IDD_DIALOG_FILTER), hWnd, FilterDlgProc) == TRUE) { iluWave(FilterParamFloat); } break; case ID_FILTER_PIXELIZE: if (DialogBox(hInstance, MAKEINTRESOURCE(IDD_DIALOG_FILTER), hWnd, FilterDlgProc) == TRUE) { iluPixelize(FilterParamInt); } break; case ID_FILTERS_BLUR_AVERAGE: if (DialogBox(hInstance, MAKEINTRESOURCE(IDD_DIALOG_FILTER), hWnd, FilterDlgProc) == TRUE) { iluBlurAvg(FilterParamInt); } break; case ID_FILTERS_BLUR_GAUSSIAN: if (DialogBox(hInstance, MAKEINTRESOURCE(IDD_DIALOG_FILTER), hWnd, FilterDlgProc) == TRUE) { iluBlurGaussian(FilterParamInt); /*iluMatrixMode(ILU_CONVOLUTION_MATRIX); iluLoadFilter(ILU_FILTER_GAUSSIAN_5X5); iluApplyMatrix();*/ } break; case ID_FILTER_GAMMACORRECT: if (DialogBox(hInstance, MAKEINTRESOURCE(IDD_DIALOG_FILTER), hWnd, FilterDlgProc) == TRUE) { iluGammaCorrect(FilterParamFloat); } break; case ID_FILTER_SHARPEN: if (DialogBox(hInstance, MAKEINTRESOURCE(IDD_DIALOG_FILTER), hWnd, FilterDlgProc) == TRUE) { iluSharpen(FilterParamFloat, 1); } break; case ID_EFFECTS_FILTERS_ROTATE: if (DialogBox(hInstance, MAKEINTRESOURCE(IDD_DIALOG_FILTER), hWnd, FilterDlgProc) == TRUE) { iluRotate(FilterParamFloat); ResizeWin(); } break; case ID_EFFECTS_FILTERS_SCALE: HWnd = hWnd; iluImageParameter(ILU_FILTER, ILU_BILINEAR); DialogBox(hInstance, MAKEINTRESOURCE(IDD_DIALOG_RESIZE), hWnd, ResizeDlgProc); break; } CreateGDI(); InvalidateRect(hWnd, NULL, FALSE); break; default: return (DefWindowProc(hWnd, message, wParam, lParam)); } return (0L); }
bool LTexture::loadPixelsFromFile32( std::string path ) { //Free texture data if needed freeTexture(); //Texture loading success bool pixelsLoaded = false; //Generate and set current image ID ILuint imgID = 0; ilGenImages( 1, &imgID ); ilBindImage( imgID ); //Load image ILboolean success = ilLoadImage( path.c_str() ); //Image loaded successfully if( success == IL_TRUE ) { //Convert image to RGBA success = ilConvertImage( IL_RGBA, IL_UNSIGNED_BYTE ); if( success == IL_TRUE ) { //Initialize dimensions GLuint imgWidth = (GLuint)ilGetInteger( IL_IMAGE_WIDTH ); GLuint imgHeight = (GLuint)ilGetInteger( IL_IMAGE_HEIGHT ); //Calculate required texture dimensions GLuint texWidth = powerOfTwo( imgWidth ); GLuint texHeight = powerOfTwo( imgHeight ); //Texture is the wrong size if( imgWidth != texWidth || imgHeight != texHeight ) { //Place image at upper left iluImageParameter( ILU_PLACEMENT, ILU_UPPER_LEFT ); //Resize image iluEnlargeCanvas( (int)texWidth, (int)texHeight, 1 ); } //Allocate memory for texture data GLuint size = texWidth * texHeight; mPixels32 = new GLuint[ size ]; //Get image dimensions mImageWidth = imgWidth; mImageHeight = imgHeight; mTextureWidth = texWidth; mTextureHeight = texHeight; //Copy pixels memcpy( mPixels32, ilGetData(), size * 4 ); pixelsLoaded = true; } //Delete file from memory ilDeleteImages( 1, &imgID ); //Set pixel format mPixelFormat = GL_RGBA; } //Report error if( !pixelsLoaded ) { printf( "Unable to load %s\n", path.c_str() ); } return pixelsLoaded; }
bool TextureAtlas::Generate(int textureSize, bool mipmap) { // TODO mipmap pas encore 100% parfait... assert(!mipmap); if (!IsPowerOfTwo(textureSize)) return false; // Initialize Devil only once: static bool alreadyInitialized = false; if (!alreadyInitialized) { ilInit(); iluInit(); alreadyInitialized = true; } for (TextureList::iterator it = m_textureList.begin(); it != m_textureList.end(); ++it) { ILuint texid = it->second.texId; if (texid == (ILuint)-1) { std::cout << "Loading " << it->first << " (id=" << it->second.texIdx << ")..." << std::endl; ilGenImages(1, &texid); ilBindImage(texid); ilOriginFunc(IL_ORIGIN_LOWER_LEFT); ilEnable(IL_ORIGIN_SET); if (!ilLoadImage((const ILstring)it->first.c_str())) return false; if (!ilConvertImage(IL_RGBA, IL_UNSIGNED_BYTE)) return false; iluScale(textureSize, textureSize, 1); it->second.texId = texid; } } //std::cout << ilGetInteger(IL_IMAGE_BPP) << std::endl; //std::cout << ilGetInteger(IL_IMAGE_FORMAT) << std::endl; //std::cout << ilGetInteger(IL_IMAGE_DEPTH) << std::endl; //std::cout << ilGetInteger(IL_IMAGE_TYPE) << std::endl; //std::cout << ilGetInteger(IL_IMAGE_WIDTH) << std::endl; //std::cout << ilGetInteger(IL_IMAGE_HEIGHT) << std::endl; glGenTextures(1, &m_textureId); glBindTexture(GL_TEXTURE_2D, m_textureId); if (mipmap) { glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); } else { glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); } int level = textureSize; int oglLevel = 0; int mipmapSize = textureSize * m_nbTexturePerSide; while (mipmapSize != 0) { ILuint atlasTex; ilGenImages(1, &atlasTex); ilBindImage(atlasTex); ilTexImage(mipmapSize, mipmapSize, 1, 4, IL_RGBA, IL_UNSIGNED_BYTE, 0); ilClearColour(1, 0, 0, 1); ilClearImage(); for (TextureList::iterator it = m_textureList.begin(); it != m_textureList.end(); ++it) { ILuint tmpImg; ilGenImages(1, &tmpImg); ilBindImage(tmpImg); ilCopyImage(it->second.texId); iluImageParameter(ILU_FILTER, ILU_NEAREST); //iluImageParameter(ILU_FILTER, ILU_BILINEAR); if (level != textureSize) iluScale(level, level, 1); char* data = new char[level * level * 4]; ilCopyPixels(0, 0, 0, level, level, 1, IL_RGBA, IL_UNSIGNED_BYTE, data); int imgIdx = it->second.texIdx; int x = imgIdx % m_nbTexturePerSide; int y = m_nbTexturePerSide - 1 - imgIdx / m_nbTexturePerSide; ilBindImage(atlasTex); ilSetPixels(x * level, y * level, 0, level, level, 1, IL_RGBA, IL_UNSIGNED_BYTE, data); //ilOverlayImage(tmpImg, x * level, y * level, 0); delete[] data; ilDeleteImages(1, &tmpImg); } // TODO //if(level == textureSize) //{ //ilEnable(IL_FILE_OVERWRITE); //ilSaveImage("textureatlas.png"); //} //std::cout << oglLevel << ":" << level << ":" << mipmapSize << std::endl; glTexImage2D(GL_TEXTURE_2D, oglLevel++, GL_RGBA, ilGetInteger(IL_IMAGE_WIDTH), ilGetInteger(IL_IMAGE_HEIGHT), 0, GL_RGBA, GL_UNSIGNED_BYTE, ilGetData()); //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE); //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_R, GL_CLAMP); //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); CHECK_GL_ERROR(); ilDeleteImages(1, &atlasTex); if (!mipmap) break; level /= 2; mipmapSize /= 2; } m_isValid = true; return true; }
//Load---------------------------------------------------------------------- bool TextureItem::Load( GLuint minFilter, GLuint maxFilter, bool forceMipmap, bool resizeIfNeeded ) { /** NOTE: This is a test of using an archive file. This will need to be modified to allow direct file access, or archived file access. */ ArchiveFile* file = ArchiveManager::GetSingleton().CreateArchiveFile( mImageFileName ); if ( file ) { UInt32 fileSize = file->Length(); unsigned char* buf = new unsigned char [ fileSize ]; if ( !buf ) { delete file; return false; } file->Read( buf, fileSize ); // Load the texture: //**** ilInit(); iluInit(); // Make sure the DevIL version is valid: if ( ilGetInteger( IL_VERSION_NUM ) < IL_VERSION || iluGetInteger( ILU_VERSION_NUM ) < ILU_VERSION ) { // Invalid version... delete file; delete buf; return false; } // Get the decompressed data ILuint imageID; ilGenImages( 1, &imageID ); ilBindImage( imageID ); //if ( ilLoadImage( const_cast< char* >( mImageFileName.c_str() ) ) ) if ( ilLoadL( IL_TYPE_UNKNOWN, buf, fileSize ) ) { // Convert the image to unsigned bytes: ilConvertImage( IL_RGBA, IL_UNSIGNED_BYTE ); // Generate the GL texture glGenTextures( 1, &mTextureID ); glBindTexture( GL_TEXTURE_2D, mTextureID ); mWidth = ilGetInteger( IL_IMAGE_WIDTH ); mHeight = ilGetInteger( IL_IMAGE_HEIGHT ); mOriginalWidth = mWidth; mOriginalHeight = mHeight; // OpenGL will work better with textures that have dimensions // that are a power of 2. If doing a scrolling tile map, then // this is pretty much a necessity. However, there are times // when using a mipmap instead is perfectly fine (ie, when NOT // doing tiles, or in cases where we might be running out of // video memory... if ( resizeIfNeeded && !forceMipmap ) { UInt32 newWidth = mWidth, newHeight = mHeight; if ( !Math::IsPowerOf2( mWidth ) ) { // Find the next power of 2: newWidth = Math::FindNextPowerOf2( mWidth ); } if ( !Math::IsPowerOf2( mHeight ) ) { // Find the next power of 2: newHeight = Math::FindNextPowerOf2( mHeight ); } if ( newWidth != mWidth || newHeight != mHeight ) { // Resize the canvas: ilClearColor( 0, 0, 0, 0 ); iluImageParameter( ILU_PLACEMENT, ILU_UPPER_LEFT ); iluEnlargeCanvas( newWidth, newHeight, ilGetInteger( IL_IMAGE_DEPTH ) ); mWidth = ilGetInteger( IL_IMAGE_WIDTH ); mHeight = ilGetInteger( IL_IMAGE_HEIGHT ); } } // If forcing mipmap generation, or if the size is not a power of 2, // generate as mipmaps if ( forceMipmap || !Math::IsPowerOf2( mWidth ) || !Math::IsPowerOf2( mHeight ) ) { gluBuild2DMipmaps( GL_TEXTURE_2D, ilGetInteger( IL_IMAGE_BPP ), mWidth, mHeight, ilGetInteger( IL_IMAGE_FORMAT ), GL_UNSIGNED_BYTE, ilGetData() ); } else { glTexImage2D( GL_TEXTURE_2D, 0, ilGetInteger( IL_IMAGE_BPP ), mWidth, mHeight, 0, ilGetInteger( IL_IMAGE_FORMAT ), GL_UNSIGNED_BYTE, ilGetData() ); } // Set the minification and magnification filters glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, minFilter ); glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, maxFilter ); glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP ); glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP ); mIsLoaded = true; } else { ILenum error; error = ilGetError(); //std::string errString = iluErrorString( error ); } ilDeleteImages( 1, &imageID ); //*** // Free memory: delete buf; delete file; } else return false; return true; }
bool Texture::CacheIn() { fbyte *im; if (Bad()) { return false; } if (!IsCachedIn()) { ILuint image_id; ILint format; ilGenImages(1, &image_id); ilBindImage(image_id); if(!ilLoadImage((ILstring)m_impl->m_filename.c_str())) { ilDeleteImages(1, &image_id); m_impl->m_bad = true; cerr << "Failed to load texture file " << m_impl->m_filename << endl; return false; } format=ilGetInteger(IL_DXTC_DATA_FORMAT); switch(format) { case IL_DXT_NO_COMP: break; case IL_DXT1: m_impl->m_dxt_format = TextureImpl::e_dxt1; break; case IL_DXT2: m_impl->m_dxt_format = TextureImpl::e_dxt2; break; case IL_DXT3: m_impl->m_dxt_format = TextureImpl::e_dxt3; break; case IL_DXT4: m_impl->m_dxt_format = TextureImpl::e_dxt4; break; case IL_DXT5: m_impl->m_dxt_format = TextureImpl::e_dxt5; break; } if(m_impl->m_dxt_format!=TextureImpl::e_dxt_none) { m_impl->m_width=ilGetInteger(IL_IMAGE_WIDTH); m_impl->m_height=ilGetInteger(IL_IMAGE_HEIGHT); m_impl->m_widthP2 = m_impl->m_width; m_impl->m_heightP2 = m_impl->m_height; m_impl->m_type = Texture::TYPE_RGBA; ILint s; char *data; s = ilGetDXTCData(NULL,0,format); m_impl->m_dxt_size = s; im = new fbyte[s]; ilGetDXTCData(im,s,format); BindTextureToOpenGL(m_impl, im); delete [] im; } else { format=ilGetInteger(IL_IMAGE_FORMAT); if(format == IL_RGBA || format == IL_BGRA || format == IL_LUMINANCE_ALPHA || m_impl->m_autoGenAlphaMask) { ilConvertImage(IL_RGBA,IL_UNSIGNED_BYTE); m_impl->m_type = Texture::TYPE_RGBA; } else { ilConvertImage(IL_RGB,IL_UNSIGNED_BYTE); m_impl->m_type = Texture::TYPE_RGB; } m_impl->m_width=ilGetInteger(IL_IMAGE_WIDTH); m_impl->m_height=ilGetInteger(IL_IMAGE_HEIGHT); m_impl->m_widthP2 = m_impl->m_width; m_impl->m_heightP2 = m_impl->m_height; if((m_impl->m_width & (m_impl->m_width - 1)) != 0 || (m_impl->m_height & (m_impl->m_height - 1)) != 0) { for(fdword i=2;i<=c_max_texture_size_power;i++) { if((m_impl->m_width<<1) > (1UL<<i)) { m_impl->m_widthP2 = (1UL<<i); } if((m_impl->m_height<<1) > (1UL<<i)) { m_impl->m_heightP2 = (1UL<<i); } } cerr << m_impl->m_filename << " has invalid texture size: " << m_impl->m_width << "x" << m_impl->m_height << " resizing to " << m_impl->m_widthP2 << "x" << m_impl->m_heightP2 << endl; cerr << " Wasted space due to texture resize: " << (((m_impl->m_widthP2 * m_impl->m_heightP2) - (m_impl->m_width * m_impl->m_height)) / float(m_impl->m_widthP2 * m_impl->m_heightP2)) * 100.0f << "%" << endl; iluImageParameter(ILU_PLACEMENT, ILU_UPPER_LEFT); ilClearColour(1.0f,0.2f,0.8f,1.0f); if(!iluEnlargeCanvas(m_impl->m_widthP2, m_impl->m_heightP2, ilGetInteger(IL_IMAGE_DEPTH))) { ilDeleteImages(1, &image_id); m_impl->m_bad = true; cerr << "Resize of texture canvas failed" << endl; return false; } } im = ilGetData(); if(m_impl->m_autoGenAlphaMask) { Colour c; fdword i,j; for(j=0;j<m_impl->m_height;j++) { for(i=0;i<m_impl->m_width;i++) { c.FromInteger(((fdword *)im)[j*m_impl->m_widthP2+i], c_rgba_red_mask, c_rgba_red_shift, c_rgba_green_mask, c_rgba_green_shift, c_rgba_blue_mask, c_rgba_blue_shift, c_rgba_alpha_mask, c_rgba_alpha_shift); GF1::Colour cd(c - m_impl->m_autoGenAlphaMaskColour); if(m_impl->m_autoGenAlphaMaskFade && m_impl->m_autoGenAlphaMaskTolerance > 0) { c.a = cd.Length() / m_impl->m_autoGenAlphaMaskTolerance; } else { if(cd.LengthSquared() <= m_impl->m_autoGenAlphaMaskTolerance * m_impl->m_autoGenAlphaMaskTolerance) { c.a=0.0f; } else { c.a=1.0f; } } ((fdword *)im)[j*m_impl->m_widthP2+i] = c.ToInteger(255,0,255,8,255,16,255,24); } } } BindTextureToOpenGL(m_impl, im); } ilDeleteImages(1, &image_id); } return true; }