bool Texture::CreateFromSurface(SDL_Surface *s, bool forceRGBA) { bool freeSurface = false; SDL_PixelFormat *pixfmt = s->format; GLenum targetGLformat; SDL_PixelFormat *targetPixfmt; bool needConvert = !GetTargetFormat(pixfmt, &targetGLformat, &targetPixfmt, forceRGBA); if (needConvert) { s = SDL_ConvertSurface(s, targetPixfmt, SDL_SWSURFACE); freeSurface = true; } // store incoming 24-bit as GL_RGB to save on texture memory if (targetGLformat == GL_RGB && m_format.internalFormat == GL_RGBA) { m_format.internalFormat = GL_RGB; m_format.dataFormat = GL_RGB; } unsigned int width = s->w; unsigned int height = s->h; // extend to power-of-two if necessary int width2 = ceil_pow2(s->w); int height2 = ceil_pow2(s->h); if (s->w != width2 || s->h != height2) { SDL_Surface *s2 = SDL_CreateRGBSurface(SDL_SWSURFACE, width2, height2, targetPixfmt->BitsPerPixel, targetPixfmt->Rmask, targetPixfmt->Gmask, targetPixfmt->Bmask, targetPixfmt->Amask); SDL_SetAlpha(s, 0, 0); SDL_SetAlpha(s2, 0, 0); SDL_BlitSurface(s, 0, s2, 0); if (freeSurface) SDL_FreeSurface(s); s = s2; freeSurface = true; m_texWidth = float(width) / float(width2); m_texHeight = float(height) / float(height2); } else m_texWidth = m_texHeight = 1.0f; SDL_LockSurface(s); CreateFromArray(s->pixels, s->w, s->h); SDL_UnlockSurface(s); m_width = width; m_height = height; if (freeSurface) SDL_FreeSurface(s); return true; }
void TextureBuilder::PrepareSurface() { if (m_prepared) return; if (!m_surface && m_filename.length() > 0) LoadSurface(); TextureFormat targetTextureFormat; SDL_PixelFormat *targetPixelFormat; bool needConvert = !GetTargetFormat(m_surface->format, &targetTextureFormat, &targetPixelFormat, m_forceRGBA); if (needConvert) { SDL_Surface *s = SDL_ConvertSurface(m_surface, targetPixelFormat, SDL_SWSURFACE); SDL_FreeSurface(m_surface); m_surface = s; } unsigned int virtualWidth, actualWidth, virtualHeight, actualHeight; virtualWidth = actualWidth = m_surface->w; virtualHeight = actualHeight = m_surface->h; if (m_potExtend) { // extend to power-of-two if necessary actualWidth = ceil_pow2(m_surface->w); actualHeight = ceil_pow2(m_surface->h); if (actualWidth != virtualWidth || actualHeight != virtualHeight) { SDL_Surface *s = SDL_CreateRGBSurface(SDL_SWSURFACE, actualWidth, actualHeight, targetPixelFormat->BitsPerPixel, targetPixelFormat->Rmask, targetPixelFormat->Gmask, targetPixelFormat->Bmask, targetPixelFormat->Amask); SDL_SetAlpha(m_surface, 0, 0); SDL_SetAlpha(s, 0, 0); SDL_BlitSurface(m_surface, 0, s, 0); SDL_FreeSurface(m_surface); m_surface = s; } } else if (m_filename.length() > 0) { // power-of-to check unsigned long width = ceil_pow2(m_surface->w); unsigned long height = ceil_pow2(m_surface->h); if (width != virtualWidth || height != virtualHeight) fprintf(stderr, "WARNING: texture '%s' is not power-of-two and may not display correctly\n", m_filename.c_str()); } m_descriptor = TextureDescriptor( targetTextureFormat, vector2f(actualWidth,actualHeight), vector2f(float(virtualWidth)/float(actualWidth),float(virtualHeight)/float(actualHeight)), m_sampleMode, m_generateMipmaps); m_prepared = true; }
void TextureBuilder::PrepareSurface() { if (m_prepared) return; if (!m_surface && !m_filename.empty()) { std::string filename = m_filename; std::transform(filename.begin(), filename.end(), filename.begin(), ::tolower); if (ends_with_ci(filename, ".dds")) { LoadDDS(); } else { LoadSurface(); } } TextureFormat targetTextureFormat; unsigned int virtualWidth, actualWidth, virtualHeight, actualHeight, numberOfMipMaps = 0, numberOfImages = 1; if( m_surface ) { SDL_PixelFormat *targetPixelFormat; bool needConvert = !GetTargetFormat(m_surface->format, &targetTextureFormat, &targetPixelFormat, m_forceRGBA); if (needConvert) { if(m_textureType == TEXTURE_2D) { SDL_Surface *s = SDL_ConvertSurface(m_surface.Get(), targetPixelFormat, SDL_SWSURFACE); m_surface = SDLSurfacePtr::WrapNew(s); } else if(m_textureType == TEXTURE_CUBE_MAP) { assert(m_cubemap.size() == 6); for(unsigned int i = 0; i < 6; ++i) { SDL_Surface *s = SDL_ConvertSurface(m_cubemap[i].Get(), targetPixelFormat, SDL_SWSURFACE); m_cubemap[i] = SDLSurfacePtr::WrapNew(s); } } else { // Unknown texture type assert(0); } } virtualWidth = actualWidth = m_surface->w; virtualHeight = actualHeight = m_surface->h; if (m_potExtend) { // extend to power-of-two if necessary actualWidth = ceil_pow2(m_surface->w); actualHeight = ceil_pow2(m_surface->h); if (actualWidth != virtualWidth || actualHeight != virtualHeight) { if(m_textureType == TEXTURE_2D) { SDL_Surface *s = SDL_CreateRGBSurface(SDL_SWSURFACE, actualWidth, actualHeight, targetPixelFormat->BitsPerPixel, targetPixelFormat->Rmask, targetPixelFormat->Gmask, targetPixelFormat->Bmask, targetPixelFormat->Amask); SDL_SetSurfaceBlendMode(m_surface.Get(), SDL_BLENDMODE_NONE); SDL_BlitSurface(m_surface.Get(), 0, s, 0); m_surface = SDLSurfacePtr::WrapNew(s); } else if(m_textureType == TEXTURE_CUBE_MAP) { assert(m_cubemap.size() == 6); for(unsigned int i = 0; i < 6; ++i) { SDL_Surface *s = SDL_CreateRGBSurface(SDL_SWSURFACE, actualWidth, actualHeight, targetPixelFormat->BitsPerPixel, targetPixelFormat->Rmask, targetPixelFormat->Gmask, targetPixelFormat->Bmask, targetPixelFormat->Amask); SDL_SetSurfaceBlendMode(m_cubemap[i].Get(), SDL_BLENDMODE_NONE); SDL_BlitSurface(m_cubemap[i].Get(), 0, s, 0); m_cubemap[i] = SDLSurfacePtr::WrapNew(s); } } else { assert(0); } } } else if (! m_filename.empty()) { // power-of-two check unsigned long width = ceil_pow2(m_surface->w); unsigned long height = ceil_pow2(m_surface->h); if (width != virtualWidth || height != virtualHeight) Output("WARNING: texture '%s' is not power-of-two and may not display correctly\n", m_filename.c_str()); } } else { switch(m_dds.GetTextureFormat()) { case PicoDDS::FORMAT_DXT1: targetTextureFormat = TEXTURE_DXT1; break; case PicoDDS::FORMAT_DXT5: targetTextureFormat = TEXTURE_DXT5; break; default: Output("ERROR: DDS texture with invalid format '%s' (only DXT1 and DXT5 are supported)\n", m_filename.c_str()); assert(false); return; } virtualWidth = actualWidth = m_dds.imgdata_.width; virtualHeight = actualHeight = m_dds.imgdata_.height; numberOfMipMaps = m_dds.imgdata_.numMipMaps; numberOfImages = m_dds.imgdata_.numImages; if(m_textureType == TEXTURE_CUBE_MAP) { // Cube map must be fully defined (6 images) to be used correctly assert(numberOfImages == 6); } } m_descriptor = TextureDescriptor( targetTextureFormat, vector2f(actualWidth,actualHeight), vector2f(float(virtualWidth)/float(actualWidth),float(virtualHeight)/float(actualHeight)), m_sampleMode, m_generateMipmaps, m_compressTextures, numberOfMipMaps, m_textureType); m_prepared = true; }