Surface::Surface ( Uint16 _sizeX, Uint16 _sizeY, Uint16 _splitSections ) { if ( _splitSections > 64 ) _splitSections = 64; m_sizeXY = std::max ( nearestPowerOfTwo ( _sizeX ), nearestPowerOfTwo ( _sizeY ) ); m_sqrtN = _splitSections; ARCDebugAssert ( isPowerOfTwo ( _splitSections ) ); if ( !isPowerOfTwo ( _splitSections ) ) { _splitSections = nearestPowerOfTwo ( _splitSections ); m_nWays = _splitSections * _splitSections; m_sqrtN = _splitSections; } // We want to force it to use the nicest texture size possible without // compromising performance. Uint16 maxTexSize = std::min ( g_graphics->GetMaximumTextureSize() / 2, 1024 ); m_pixelWH = m_sizeXY / m_sqrtN; while ( m_pixelWH > maxTexSize ) { m_sqrtN *= 2; m_pixelWH = m_sizeXY / m_sqrtN; } m_nWays = m_sqrtN * m_sqrtN; m_sectionIDs.setSize ( m_nWays ); m_srcRects = new SDL_Rect[m_nWays]; m_destRects = new SDL_Rect[m_nWays]; }
void LanczosFilter::updateOffscreenSurfaces() { int w = displayWidth(); int h = displayHeight(); if (!GLTexture::NPOTTextureSupported()) { w = nearestPowerOfTwo(w); h = nearestPowerOfTwo(h); } if (!m_offscreenTex || m_offscreenTex->width() != w || m_offscreenTex->height() != h) { if (m_offscreenTex) { delete m_offscreenTex; delete m_offscreenTarget; } m_offscreenTex = new GLTexture(w, h); m_offscreenTex->setFilter(GL_LINEAR); m_offscreenTex->setWrapMode(GL_CLAMP_TO_EDGE); m_offscreenTarget = new GLRenderTarget(*m_offscreenTex); } }
SDLMixerSoundSystem::SDLMixerSoundSystem() : m_queuesEmpty(true) { int retval = SDL_InitSubSystem ( SDL_INIT_AUDIO ); CrbReleaseAssert ( retval == 0 ); int channels = g_prefsManager->GetInt ( "SoundChannels", 32 ), frequency = g_prefsManager->GetInt ( "SoundMixFreq", 22050 ), bufferSize = g_prefsManager->GetInt ( "SoundBufferSize", 1024 ); if ( channels < 16 ) channels = 16; if ( frequency < 22050 ) frequency = 22050; if ( bufferSize < 512 ) bufferSize = 512; if ( !isPowerOfTwo ( bufferSize ) ) bufferSize = nearestPowerOfTwo ( bufferSize ); retval = Mix_OpenAudio ( frequency, AUDIO_S16SYS, 2, bufferSize ); CrbReleaseAssert ( retval == 0 ); Mix_AllocateChannels ( channels ); m_channelPlaying.setSize ( channels ); }
void CTextRenderer::CGlyphCache::Init(int FontSize) { m_FontSize = FontSize; m_OffsetY = m_FontSize; m_PPG = nearestPowerOfTwo((FontSize+2*s_Margin)/2); m_GPB = 8; m_PPB = m_GPB * m_PPG; //Remove old data if(m_pData) delete[] m_pData; if(m_Texture.IsValid()) Graphics()->UnloadTexture(&m_Texture); m_Blocks.clear(); m_Glyphs.clear(); m_Width = 0; m_Height = 0; //Init UpdateVersion(); }
Uint32 OpenGLGraphics::LoadImage ( const char *_filename, bool _isColorKeyed ) { ARCReleaseAssert ( _filename != NULL ); // Load the image from RAM. SDL_Surface* src = g_app->m_resource->GetImage ( _filename ); // use SDL_Image to load the image ARCReleaseAssert ( src != NULL ); Uint32 oldWidth = 0, oldHeight = 0; Uint32 rmask, gmask, bmask, amask; #if SDL_BYTEORDER == SDL_BIG_ENDIAN rmask = 0xff000000; gmask = 0x00ff0000; bmask = 0x0000ff00; amask = 0x000000ff; #else rmask = 0x000000ff; gmask = 0x0000ff00; bmask = 0x00ff0000; amask = 0xff000000; #endif Uint32 targetW = src->w, targetH = src->h; if ( !g_openGL->GetSetting ( OPENGL_TEX_ALLOW_NPOT, false ) ) { oldWidth = targetW, oldHeight = targetH; if ( !isPowerOfTwo ( targetW ) ) targetW = nearestPowerOfTwo ( targetW ); if ( !isPowerOfTwo ( targetH ) ) targetH = nearestPowerOfTwo ( targetH ); ARCReleaseAssert ( isPowerOfTwo ( targetW * targetH ) ); } if ( g_openGL->GetSetting ( OPENGL_TEX_FORCE_SQUARE, false ) ) { targetH = targetW = std::max ( targetW, targetH ); } OpenGLTexture *tex = new OpenGLTexture(); Uint32 ret = m_textures.insert ( tex ); tex->Dispose(); tex->Create ( targetW, targetH, _isColorKeyed ); ARCReleaseAssert ( tex->m_sdlSurface != NULL ); if ( _isColorKeyed && m_colorKeySet ) { SDL_FillRect ( tex->m_sdlSurface, NULL, ZERO_ALPHA & m_colorKey ); SDL_SetColorKey ( tex->m_sdlSurface, SDL_SRCCOLORKEY | SDL_RLEACCEL, m_colorKey ); } SDL_SetAlpha ( tex->m_sdlSurface, 0, SDL_ALPHA_OPAQUE ); SDL_BlitSurface ( src, NULL, tex->m_sdlSurface, NULL ); SDL_FreeSurface ( src ); tex->Damage(); return ret; }
bool ImageLoader:: load(const std::string& imageName, bool isNormalMap) { // 载入图片 FREE_IMAGE_FORMAT fif = FreeImage_GetFileType(imageName.c_str()); if((fif != FIF_UNKNOWN) && FreeImage_FIFSupportsReading(fif)) { if (mDIB) FreeImage_Unload(mDIB); mDIB = FreeImage_Load(fif, imageName.c_str()); mFormat = fif; bool needScale = !oiram::fequal(config.imageScale, 1.0f); unsigned int newWidth = width(), newHeight = height(), newBpp = bpp(); bool imagePowerOfTwo = config.imagePowerOfTwo; unsigned int imageMaxSize = config.imageMaxSize; // PVRTCII支持non-POT; ETC1和ETC2必须是POT, 最大尺寸限定在2048, 而且必须是正方形 if (config.imageCompressionType == CT_ETC1 || config.imageCompressionType == CT_ETC2) { imagePowerOfTwo = true; imageMaxSize = 2048; } // DXTC/PVRTC/ETCI有最小尺寸限制 switch (config.imageCompressionType) { case CT_DXTC: if (newWidth < DXT_MIN_TEXWIDTH) { newWidth = DXT_MIN_TEXWIDTH; needScale = true; } if (newHeight < DXT_MIN_TEXHEIGHT) { newHeight = DXT_MIN_TEXHEIGHT; needScale = true; } // DXTC的尺寸必须是4的倍数 { unsigned int multiplesOfFourWidth = nearestMultiplesOfFour(newWidth), multiplesOfFourHeight = nearestMultiplesOfFour(newHeight); if (newWidth != multiplesOfFourWidth) { newWidth = multiplesOfFourWidth; needScale = true; } if (newHeight != multiplesOfFourHeight) { newHeight = multiplesOfFourHeight; needScale = true; } } break; case CT_ETC1: case CT_ETC2: if (newWidth < ETC_MIN_TEXWIDTH) { newWidth = ETC_MIN_TEXWIDTH; needScale = true; } if (newHeight < ETC_MIN_TEXHEIGHT) { newHeight = ETC_MIN_TEXHEIGHT; needScale = true; } break; case CT_PVRTC2_4BPP: if (newWidth < PVRTC4_MIN_TEXWIDTH) { newWidth = PVRTC4_MIN_TEXWIDTH; needScale = true; } if (newHeight < PVRTC4_MIN_TEXHEIGHT) { newHeight = PVRTC4_MIN_TEXHEIGHT; needScale = true; } break; } // 超出最大尺寸则按比例缩放 if (imageMaxSize > 0 && (newWidth > imageMaxSize || newHeight > imageMaxSize)) { if (newWidth > newHeight) { float scale = static_cast<float>(newWidth) / newHeight; newWidth = imageMaxSize; newHeight = static_cast<unsigned int>(newWidth / scale); } else { float scale = static_cast<float>(newHeight) / newWidth; newHeight = imageMaxSize; newWidth = static_cast<unsigned int>(newHeight / scale); } needScale = true; } newWidth = static_cast<unsigned int>(newWidth * config.imageScale); newHeight = static_cast<unsigned int>(newHeight * config.imageScale); if (imagePowerOfTwo) { unsigned int potWidth = nearestPowerOfTwo(newWidth), potHeight = nearestPowerOfTwo(newHeight); if (newWidth != potWidth || newHeight != potHeight) { newWidth = potWidth; newHeight = potHeight; needScale = true; } } if (needScale) { FIBITMAP* rescaleDIB = FreeImage_Rescale(mDIB, newWidth, newHeight, FILTER_LANCZOS3); FreeImage_Unload(mDIB); mDIB = rescaleDIB; } return true; } return false; }