void PictureBank::createResources() { Picture& originalPic = getPicture( ResourceGroup::utilitya, 34 ); setPicture( std::string( ResourceGroup::waterbuildings ) + "_00001.png", *originalPic.getSurface() ); Picture* fullReservoir = originalPic.createCopy(); //mem leak on destroy picloader fullReservoir->draw( getPicture( ResourceGroup::utilitya, 35 ), 47, 37 ); setPicture( std::string( ResourceGroup::waterbuildings ) + "_00002.png", *fullReservoir->getSurface() ); Picture& emptyFontainOrig = getPicture( ResourceGroup::utilitya, 10 ); setPicture( std::string( ResourceGroup::waterbuildings ) + "_00003.png", *emptyFontainOrig.getSurface() ); Picture* fullFontain = emptyFontainOrig.createCopy(); //mem leak on destroy picloader fullFontain->draw( getPicture( ResourceGroup::utilitya, 11 ), 12, 25 ); setPicture( std::string( ResourceGroup::waterbuildings) + "_00004.png", *fullFontain->getSurface() ); }
void Picture::draw( const Picture &srcpic, const Rect& srcrect, const Rect& dstrect, bool useAlpha ) { SDL_Surface *srcimg = srcpic.getSurface(); if( !(srcimg && _d->surface) ) { return; } SDL_Rect srcRect, dstRect; srcRect.x = srcrect.getLeft(); srcRect.y = srcrect.getTop(); srcRect.w = srcrect.getWidth(); srcRect.h = srcrect.getHeight(); dstRect.x = dstrect.getLeft(); dstRect.y = dstrect.getTop(); dstRect.w = dstrect.getWidth(); dstRect.h = dstrect.getHeight(); if( useAlpha ) { SDL_BlitSurface(srcimg, &srcRect, _d->surface, &dstRect); } else { SDL_Surface* tmpSurface = SDL_ConvertSurface( srcimg, _d->surface->format, SDL_SWSURFACE); SDL_SetAlpha( tmpSurface, 0, 0 ); SDL_BlitSurface(tmpSurface, &srcRect, _d->surface, &dstRect); SDL_FreeSurface( tmpSurface ); } }
void GfxGlEngine::unloadPicture(Picture &ioPicture) { const GLuint& texture = (GLuint)ioPicture.getGlTextureID(); glDeleteTextures(1, &texture ); SDL_FreeSurface(ioPicture.getSurface()); ioPicture = Picture(); }
void GfxGlEngine::loadPicture(Picture& ioPicture) { GLuint& texture(ioPicture.getGlTextureID()); SDL_Surface *surface = ioPicture.getSurface(); GLenum texture_format; GLint nOfColors; // SDL_Surface *surface2 // get the number of channels in the SDL surface nOfColors = surface->format->BytesPerPixel; if (nOfColors == 4) // contains an alpha channel { if (surface->format->Rmask == 0x000000ff) texture_format = GL_RGBA; else texture_format = GL_BGRA; } else if (nOfColors == 3) // no alpha channel { if (surface->format->Rmask == 0x000000ff) texture_format = GL_RGB; else texture_format = GL_BGR; } else { THROW("Invalid image format"); } if (texture == 0) { // the picture has no texture ID! // generate a texture ID glGenTextures( 1, &texture ); } // Bind the texture object glBindTexture( GL_TEXTURE_2D, texture ); // Set the texture's stretching properties glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST ); glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST ); // Edit the texture object's image data using the information SDL_Surface gives us ioPicture.lock(); glTexImage2D( GL_TEXTURE_2D, 0, nOfColors, surface->w, surface->h, 0, texture_format, GL_UNSIGNED_BYTE, surface->pixels ); ioPicture.unlock(); }
void PictureBank::setPicture( const std::string &name, const Picture& pic ) { setPicture( name, *pic.getSurface() ); }
// load in the image data Picture PictureLoaderPng::load( io::NFile file ) const { if(!file.isOpen()) { Logger::warning( "LOAD PNG: can't open file %s", file.getFileName().toString().c_str() ); return Picture::getInvalid(); } png_byte buffer[8]; // Read the first few bytes of the PNG file if( file.read(buffer, 8) != 8 ) { Logger::warning( "LOAD PNG: can't read file %s", file.getFileName().toString().c_str() ); return Picture::getInvalid(); } // Check if it really is a PNG file if( png_sig_cmp(buffer, 0, 8) ) { Logger::warning( "LOAD PNG: not really a png %s", file.getFileName().toString().c_str() ); return Picture::getInvalid(); } // Allocate the png read struct png_structp png_ptr = png_create_read_struct( PNG_LIBPNG_VER_STRING, NULL, (png_error_ptr)png_cpexcept_error, (png_error_ptr)png_cpexcept_warn); if( !png_ptr ) { Logger::warning( "LOAD PNG: Internal PNG create read struct failure %s", file.getFileName().toString().c_str() ); return Picture::getInvalid(); } // Allocate the png info struct png_infop info_ptr = png_create_info_struct(png_ptr); if (!info_ptr) { Logger::warning( "LOAD PNG: Internal PNG create info struct failure 5s", file.getFileName().toString().c_str() ); png_destroy_read_struct(&png_ptr, NULL, NULL); return Picture::getInvalid(); } // for proper error handling if (setjmp(png_jmpbuf(png_ptr))) { png_destroy_read_struct(&png_ptr, &info_ptr, NULL); /* if( RowPointers ) delete [] RowPointers; */ return Picture::getInvalid(); } // changed by zola so we don't need to have public FILE pointers png_set_read_fn(png_ptr, &file, user_read_data_fcn); png_set_sig_bytes(png_ptr, 8); // Tell png that we read the signature png_read_info(png_ptr, info_ptr); // Read the info section of the png file unsigned int Width; unsigned int Height; int BitDepth; int ColorType; { // Use temporary variables to avoid passing casted pointers png_uint_32 w,h; // Extract info png_get_IHDR(png_ptr, info_ptr, &w, &h, &BitDepth, &ColorType, NULL, NULL, NULL); Width=w; Height=h; } // Convert palette color to true color if (ColorType==PNG_COLOR_TYPE_PALETTE) png_set_palette_to_rgb(png_ptr); // Convert low bit colors to 8 bit colors if (BitDepth < 8) { if (ColorType==PNG_COLOR_TYPE_GRAY || ColorType==PNG_COLOR_TYPE_GRAY_ALPHA) png_set_expand_gray_1_2_4_to_8(png_ptr); else png_set_packing(png_ptr); } if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS)) png_set_tRNS_to_alpha(png_ptr); // Convert high bit colors to 8 bit colors if (BitDepth == 16) png_set_strip_16(png_ptr); // Convert gray color to true color if (ColorType==PNG_COLOR_TYPE_GRAY || ColorType==PNG_COLOR_TYPE_GRAY_ALPHA) png_set_gray_to_rgb(png_ptr); int intent; const double screen_gamma = 2.2; if (png_get_sRGB(png_ptr, info_ptr, &intent)) png_set_gamma(png_ptr, screen_gamma, 0.45455); else { double image_gamma; if (png_get_gAMA(png_ptr, info_ptr, &image_gamma)) png_set_gamma(png_ptr, screen_gamma, image_gamma); else png_set_gamma(png_ptr, screen_gamma, 0.45455); } // Update the changes in between, as we need to get the new color type // for proper processing of the RGBA type png_read_update_info(png_ptr, info_ptr); { // Use temporary variables to avoid passing casted pointers png_uint_32 w,h; // Extract info png_get_IHDR(png_ptr, info_ptr, &w, &h, &BitDepth, &ColorType, NULL, NULL, NULL); Width=w; Height=h; } // Convert RGBA to BGRA if (ColorType==PNG_COLOR_TYPE_RGB_ALPHA) { png_set_bgr(png_ptr); } // Create the image structure to be filled by png data Picture* pic = GfxEngine::instance().createPicture( Size( Width, Height ) ); GfxEngine::instance().loadPicture( *pic ); if( pic->getSize().getArea() == 0 ) { Logger::warning( "LOAD PNG: Internal PNG create image struct failure %s", file.getFileName().toString().c_str() ); png_destroy_read_struct(&png_ptr, NULL, NULL); return Picture::getInvalid(); } if( !Height ) { Logger::warning( "LOAD PNG: Internal PNG create row pointers failure %s", file.getFileName().toString().c_str() ); png_destroy_read_struct(&png_ptr, NULL, NULL); return Picture::getInvalid(); } // Create array of pointers to rows in image data ScopedPtr<unsigned char*> RowPointers( (unsigned char**)new png_bytep[ Height ] ); // Fill array of pointers to rows in image data SDL_LockSurface( pic->getSurface() ); unsigned char* data = (unsigned char*)pic->getSurface()->pixels; for(unsigned int i=0; i<Height; ++i) { RowPointers.data()[i] = data; data += pic->getSurface()->pitch; } // for proper error handling if( setjmp( png_jmpbuf( png_ptr ) ) ) { png_destroy_read_struct(&png_ptr, &info_ptr, NULL); GfxEngine::instance().deletePicture( pic ); return Picture::getInvalid(); } // Read data using the library function that handles all transformations including interlacing png_read_image( png_ptr, RowPointers.data() ); png_read_end( png_ptr, NULL ); png_destroy_read_struct( &png_ptr, &info_ptr, 0 ); // Clean up memory SDL_UnlockSurface(pic->getSurface()); return *pic; }