void TileStorage::CompressTile(uint64_t uid) { uint8_t * m0; uint8_t * m1; uint8_t * m2; uint8_t * m3; uint8_t * dataptr = m_tiles[uid]; uint8_t * compressedmipmaps = new uint8_t[680]; if ( !dataptr ) { delete [] compressedmipmaps; throw InvalidTileDataPointerException(); } uint32_t s; uint32_t s2 = 0; ILuint mip1 = ilGenImage(); ilBindImage(mip1); ilTexImage(32,32,1,4,IL_RGBA,IL_UNSIGNED_BYTE,dataptr); /*std::stringstream ss; ss << "Tile" << uid << ".png"; ilSaveImage(ss.str().c_str());*/ m0 = ilCompressDXT(ilGetData(),32,32,1,IL_DXT1,&s); memcpy(&compressedmipmaps[s2],m0,s); s2 += s; iluScale(16,16,1); m1 = ilCompressDXT(ilGetData(),16,16,1,IL_DXT1,&s); memcpy(&compressedmipmaps[s2],m1,s); s2 += s; iluScale(8,8,1); m2 = ilCompressDXT(ilGetData(),8,8,1,IL_DXT1,&s); memcpy(&compressedmipmaps[s2],m2,s); s2 += s; iluScale(4,4,1); m3 = ilCompressDXT(ilGetData(),4,4,1,IL_DXT1,&s); memcpy(&compressedmipmaps[s2],m3,s); s2 += s; ilDeleteImage(mip1); /*squish::CompressImage(dataptr,32,32,m0,squish::kDxt1); squish::CompressImage(dataptr,16,16,m1,squish::kDxt1); squish::CompressImage(dataptr,8,8,m2,squish::kDxt1); squish::CompressImage(dataptr,4,4,m3,squish::kDxt1);*/ free(m0); free(m1); free(m2); free(m3); m_tiles_compressed[uid] = compressedmipmaps; //std::cout << "Tile " << uid << " compressed!" << std::endl; }
void ofxTexture::DrawString(string text, ofxBitmapFont* font, ofRectangle dest_rect, unsigned char font_size) { if(m_Locked) return; // TODO: implement draw text with boundary float scale; if(font_size == 0) { scale = 1.0f; } else { scale = (float)font_size/font->GetFontSize(); } ofVec2f cursor(dest_rect.x, dest_rect.y); ilDisable(IL_BLIT_BLEND); for (int i = 0; i < text.size(); i++) { ofVec2f draw_region = scale*font->GetRect(text[i]); ILuint character_image = font->GetImageId(text[i]); ILuint dummy = ilGenImage(); ilBindImage(dummy); ilCopyImage(character_image); iluScale(draw_region.x, draw_region.y, 1); ilBindImage(m_ImageId); ilBlit(dummy, cursor.x, cursor.y, 0, 0, 0, 0, draw_region.x, draw_region.y, 1); ilDeleteImage(dummy); cursor.x += draw_region.x; } ilEnable(IL_BLIT_BLEND); }
bool nTextureManager::saveTexture(nTexture *tex, string name) { if(!glIsTexture(tex->tex)) { return false; } mutex->lock(); unsigned char *dat = new unsigned char[3 * (unsigned int)(tex->size.x * tex->size.y)]; glBindTexture(GL_TEXTURE_2D, tex->tex); glGetTexImage(GL_TEXTURE_2D, 0, GL_RGB, GL_UNSIGNED_BYTE, dat); ILuint img; ilGenImages(1, &img); ilBindImage(img); iluScale(tex->size.x, tex->size.y, 1); ilConvertImage(IL_RGB, IL_UNSIGNED_BYTE); bool t = ilTexImage(tex->size.x, tex->size.y, 1, 3, IL_RGB, IL_UNSIGNED_BYTE, dat); ILuint error = ilGetError(); GLuint glError = glGetError(); if(error || !t || glError) { nGine::instance()->getLogger()->addDebugLog("Error while saving file : " + nLogger::numToString((int)error) + "/" + nLogger::numToString((int)glError)); mutex->unlock(); return false; } bool a = ilSaveImage((nGine::instance()->appPath() + name).c_str()); mutex->unlock(); return a; }
ILboolean ilImage::Resize(ILuint Width, ILuint Height, ILuint Depth) { if (this->Id) { this->Bind(); return iluScale(Width, Height, Depth); } return IL_FALSE; }
INT_PTR APIENTRY ResizeDlgProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) { static TCHAR x[255], y[255], z[255]; static ILuint xsize, ysize, zsize; static RECT Rect; switch (message) { case WM_INITDIALOG: { wsprintf(x, L"%d", Width); wsprintf(y, L"%d", Height); wsprintf(z, L"%d", Depth); SetDlgItemText(hDlg, IDC_EDIT_RESIZE_X, x); SetDlgItemText(hDlg, IDC_EDIT_RESIZE_Y, y); SetDlgItemText(hDlg, IDC_EDIT_RESIZE_Z, z); return TRUE; } break; case WM_COMMAND: { if (LOWORD(wParam) == IDOK) { GetDlgItemText(hDlg, IDC_EDIT_RESIZE_X, x, 255); GetDlgItemText(hDlg, IDC_EDIT_RESIZE_Y, y, 255); GetDlgItemText(hDlg, IDC_EDIT_RESIZE_Z, z, 255); xsize = _wtoi(x); ysize = _wtoi(y); zsize = _wtoi(z); if (xsize && ysize && zsize) { iluScale(xsize, ysize, zsize); Width = ilGetInteger(IL_IMAGE_WIDTH); Height = ilGetInteger(IL_IMAGE_HEIGHT); Depth = ilGetInteger(IL_IMAGE_DEPTH); GetWindowRect(HWnd, &Rect); SetWindowPos(HWnd, HWND_TOP, Rect.left, Rect.top, Width < MIN_W ? MIN_W + BORDER_W : Width + BORDER_W, Height + MENU_H, SWP_SHOWWINDOW); InvalidateRect(HWnd, NULL, FALSE); } EndDialog(hDlg, TRUE); } if (LOWORD(wParam) == IDCANCEL) { EndDialog(hDlg, FALSE); } } break; case WM_CLOSE: EndDialog(hDlg, TRUE); break; } return FALSE; }
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"]; }
ILboolean ILAPIENTRY iluEnlargeImage(ILfloat XDim, ILfloat YDim, ILfloat ZDim) { if (XDim <= 0.0f || YDim <= 0.0f || ZDim <= 0.0f) { ilSetError(ILU_INVALID_PARAM); return IL_FALSE; } iluCurImage = ilGetCurImage(); return iluScale((ILuint)(iluCurImage->Width * XDim), (ILuint)(iluCurImage->Height * YDim), (ILuint)(iluCurImage->Depth * ZDim)); }
void ofxTexture::StretchTransfer(ofxTexture* source, ofRectangle source_rect, ofRectangle dest_rect, int alpha) { if(m_Locked || source->IsLocked()) return; ILuint dummy = ilGenImage(); ilBindImage(dummy); ilCopyImage(source->GetDevilId()); iluScale(dest_rect.width, dest_rect.height, 1); ilBindImage(m_ImageId); ilDisable(IL_BLIT_BLEND); ilBlit(dummy, dest_rect.x, dest_rect.y, 0, source_rect.x, source_rect.y, 0, source_rect.width, source_rect.height, 1); ilEnable(IL_BLIT_BLEND); ilDeleteImage(dummy); }
ILuint ScaleImage(Image *image, ILuint width, ILuint height) { ilBindImage(image->id); if (! iluScale(width, height, image->depth)) return 0; image->rawData = ilGetData(); image->width = ilGetInteger(IL_IMAGE_WIDTH); image->height = ilGetInteger(IL_IMAGE_HEIGHT); image->depth = ilGetInteger(IL_IMAGE_DEPTH); image->format = ilGetInteger(IL_IMAGE_FORMAT); return 1; }
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); }
void FractureBox::resizeFractureTexture() { ASSERT(mFracTexID); if(mFracTexScaleID) ilDeleteImage(mFracTexScaleID); mFracTexScaleID = ilGenImage(); ilBindImage(mFracTexScaleID); ilCopyImage(mFracTexID); ILinfo imgInfo; iluGetImageInfo(&imgInfo); //Scale the image to fit our box const int wid = w() - 2; const int hei = h() - 2; 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]; }
//----------------------------------------------------------------------- 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 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; }
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); } }
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; }