// This assumes that both Surfaces are the same format and bit depth /*static*/ void Surface::ScaledBlit( const Surface& Src, Surface& Dest, int Scalar ) { PROFILE_FUNCTION; ASSERT( Src.GetWidth() * Scalar == Dest.GetWidth() ); ASSERT( Src.GetHeight() * Scalar == Dest.GetHeight() ); const byte* SrcPixels = Src.GetPointerAt( 0, 0 ); int SrcIncrement = Src.GetStride() * 2 - Src.GetPadding(); // Roll forward (padding) to end of line then roll back two lines (stride*2) int DestIncrement = Dest.GetStride() + Scalar * BYTES; // Roll back scalar width plus one line for( int SrcY = 0; SrcY < Src.GetHeight(); ++SrcY ) { for( int SrcX = 0; SrcX < Src.GetWidth(); ++SrcX ) { byte B = *SrcPixels++; byte G = *SrcPixels++; byte R = *SrcPixels++; byte* DestPixels = Dest.GetPointerAt( SrcX * Scalar, SrcY * Scalar ); for( int j = 0; j < Scalar; ++j ) { for( int i = 0; i < Scalar; ++i ) { *DestPixels++ = B; *DestPixels++ = G; *DestPixels++ = R; } DestPixels -= DestIncrement; } } SrcPixels -= SrcIncrement; } }
void Framework3D::CreateSplashWindow(const uint WindowIcon, const char* const Title) { XTRACE_FUNCTION; STATICHASH(Framework); STATICHASH(SplashImage); const char* const pSplashImage = ConfigManager::GetString(sSplashImage, nullptr, sFramework); if (!pSplashImage) { return; } const Surface SplashSurface = Surface(PackStream(pSplashImage), Surface::ESFT_BMP); const int SplashWindowWidth = SplashSurface.GetWidth(); const int SplashWindowHeight = SplashSurface.GetHeight(); ASSERT(!m_SplashWindow); m_SplashWindow = new Window; #if BUILD_WINDOWS_NO_SDL const DWORD WindowStyle = WS_POPUP; const DWORD WindowExStyle = WS_EX_TOOLWINDOW; // Prevents this window appearing in the taskbar const int ScreenWidth = m_Display->m_Fullscreen ? m_Display->m_Width : m_Display->m_ScreenWidth; const int ScreenHeight = m_Display->m_Fullscreen ? m_Display->m_Height : m_Display->m_ScreenHeight; m_SplashWindow->Init(Title, "SplashWindowClass", WindowStyle, WindowExStyle, SplashWindowWidth, SplashWindowHeight, m_hInstance, NULL, WindowIcon, ScreenWidth, ScreenHeight); // The window needs to be shown before we can blit to it. m_SplashWindow->Show(m_CmdShow); #endif #if BUILD_SDL // TODO SDL: Unify interface? const uint Flags = SDL_WINDOW_SHOWN | SDL_WINDOW_BORDERLESS; m_SplashWindow->Init(Title, Flags, SplashWindowWidth, SplashWindowHeight); // Load icon from package file instead of compiled resource. Unused(WindowIcon); STATICHASH(IconImage); const char* const pIconImage = ConfigManager::GetString(sIconImage, nullptr, sFramework); if(pIconImage) { ASSERT(pIconImage); const Surface IconSurface = Surface(PackStream(pIconImage), Surface::ESFT_BMP); SDL_SetWindowIcon(m_SplashWindow->GetSDLWindow(), IconSurface.GetSDLSurface()); } #endif SplashSurface.BlitToWindow(m_SplashWindow); }
Bitmap::Bitmap(const Surface& surface) { width = surface.GetWidth(); height = surface.GetHeight(); format = surface.GetPixelFormat(); pitch = width * format.GetBytes(); image = new uint8[height*pitch]; // copy image CopyImage(image,surface.GetImage(),pitch,surface.GetPitch(),height); }
// takes ownership of image data Image* ResourceManager::LoadImage(const string &aPath) { Surface* pSurface = PngToSurface(aPath.c_str()); Image* pImage = NULL; if (pSurface) { pImage = new Image(); pImage->_pPathName = aPath; pImage->_width = pSurface->GetWidth(); pImage->_height = pSurface->GetHeight(); _preloadData.push_back(ImageSurfacePair(pImage, pSurface)); } return pImage; }
void Map::DrawBackground(Window screen, Graphics* assets){ Point2D dim = GetMapDimension(); Surface* surface =& (assets->forest[0]); Surface* parallax = & (assets->forestParallax); int forestStart = (int)dim.Y;//The bottom of the map int Xstart = 0; int Xcount = 0; int parallaxStartX =0; //(Bottom of map - (the current camera position + the height of the screen)) divided by the height of the background surface -1 //== (bottom of map - the bottom of the screen)/height of background -1 //==how many backgrounds are already beneath this position? int Ycount = (int)((forestStart - (_mapPosition.Y+screen.GetHeight())) / surface->GetHeight()) - 1; //the starting point for the background to draw int Ystart = (int)dim.Y - surface->GetHeight()*Ycount; while(Ystart>_mapPosition.Y){ //The vertical height determines the kind of background surface->SetTransparency(255); if(Ycount == 0) {surface = &(assets->forest[0]); parallax=&(assets->forestParallax);} else if(Ycount == 1) {surface =&( assets->air[0]);parallax=0;} else if(Ycount == 2) {surface = &(assets->space1);parallax=0;} else if(Ycount < 0) {surface->SetTransparency(0);parallax=0;} else {surface = &(assets->space2);parallax=0;} //This one is handled, go the next one Ystart -= surface->GetHeight(); //The starting position of the next background to render Xstart = (int)(_mapPosition.X - ((Uint32)_mapPosition.X % (Uint32)surface->GetWidth())); //How many backgrounds are already left of this? Xcount = (int)(_mapPosition.X/surface->GetWidth()); if (parallax!=0 && parallax->IsInit()) { int parallaxStartX=(int)(_mapPosition.X/2 - ((Uint32)(_mapPosition.X/2) % (Uint32)parallax->GetWidth())); while(parallaxStartX < _mapPosition.X + screen.GetWidth()){ parallax->Draw(screen,(Uint32)(parallaxStartX-_mapPosition.X/2), (Uint32)(Ystart-_mapPosition.Y)+400); parallax->Draw(screen,(Uint32)(parallaxStartX-_mapPosition.X/2), (Uint32)(Ystart-_mapPosition.Y)+400); parallaxStartX += parallax->GetWidth(); } } while(Xstart < _mapPosition.X + screen.GetWidth()){ //Handle the current image for the looping backgrounds if(Ycount == 1){ if(Xcount>2)Xcount = Xcount%3; surface = &(assets->air[Xcount]); Xcount++; } else if(Ycount == 0){ if(Xcount>3) Xcount = Xcount%4; surface = &(assets->forest[Xcount]); Xcount++; } surface->Draw(screen, (Uint32)(Xstart-_mapPosition.X), (Uint32)(Ystart-_mapPosition.Y)); Xstart += surface->GetWidth(); } Ycount++; } }
void ResourceManager::GenerateTextures(const Vector2i &maxSize) { // sort by size for (uint16 i=0; i<_preloadData.size()-1; ++i) { Surface* s1 = _preloadData[i].second; Surface* s2 = _preloadData[i+1].second; if (s1->GetArea() < s2->GetArea()) { Surface* temp = s1; s1 = s2; s2 = s1; } } vector<Surface*> masterTextures; int masterTextureCount = 0; while(!_preloadData.empty() && masterTextureCount < MAX_TEXTURES) { Surface* masterSurface = new Surface(NULL, maxSize.x, maxSize.y, 4); masterTextureCount ++; vector<Image*> imagesOnSurface; Node rootNode; rootNode.rect = Rect(0, 0, maxSize.x, maxSize.y); for (vector<ImageSurfacePair>::iterator it = _preloadData.begin(); it != _preloadData.end();) { Image* image = it->first; Surface* surface = it->second; Rect rect = Rect(0, 0, surface->GetWidth(), surface->GetHeight()); Node* node = rootNode.Insert(rect); if (node) { // we managed to fit it inside the master texture rect = node->rect; masterSurface->BlitSurface(surface, rect.x, rect.y); surface->Destroy(); imagesOnSurface.push_back(image); image->_textureX = (float)rect.x / masterSurface->GetWidth(); image->_textureY = (float)rect.y / masterSurface->GetHeight(); image->_textureW = (float)rect.width / masterSurface->GetWidth(); image->_textureH = (float)rect.height / masterSurface->GetHeight(); it = _preloadData.erase(it); } else ++it; } // OpenGl has reversed Y axis masterSurface->FlipY(); GLuint texture = masterSurface->CreateGLTexture(); masterSurface->Destroy(); for (uint16 i=0; i<imagesOnSurface.size(); ++i) { imagesOnSurface[i]->_texture = texture; } } }