void CPicture::Load( const char* extension, CDataStream& dataStream ) { if ( strcmp( extension, "dds" ) == 0 ) { LoadDDS( dataStream ); } if ( strcmp( extension, "png" ) == 0 ) { LoadPNG( dataStream ); } else { // WbLog( "Default", "Unsupported texture format : %s\n", extension ); } }
bool Texture::Load(const std::string & path, const TextureInfo & info, std::ostream & error) { if (m_id) { error << "Tried to double load texture " << path << std::endl; return false; } if (!info.data && path.empty()) { error << "Tried to load a texture with an empty name" << std::endl; return false; } if (!info.data && LoadDDS(path, info, error)) return true; m_cube = info.cube; if (m_cube) { return LoadCube(path, info, error); } SDL_Surface * orig_surface = 0; if (info.data) { 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 orig_surface = SDL_CreateRGBSurfaceFrom( info.data, info.width, info.height, info.bytespp * 8, info.width * info.bytespp, rmask, gmask, bmask, amask); } if (!orig_surface) { orig_surface = IMG_Load(path.c_str()); if (!orig_surface) { error << "Error loading texture file: " << path << std::endl; error << IMG_GetError() << std::endl; return false; } } SDL_Surface * surface = orig_surface; if (surface) { m_scale = Scale(info.maxsize, orig_surface->w, orig_surface->h); float scalew = m_scale; float scaleh = m_scale; // scale to power of two if necessary bool norescale = (IsPowerOfTwo(orig_surface->w) && IsPowerOfTwo(orig_surface->h)) || (info.npot && (GLEW_VERSION_2_0 || GLEW_ARB_texture_non_power_of_two)); if (!norescale) { int maxsize = 2048; int new_w = orig_surface->w; int new_h = orig_surface->h; if (!IsPowerOfTwo(orig_surface->w)) { for (new_w = 1; new_w <= maxsize && new_w <= orig_surface->w * m_scale; new_w = new_w * 2); } if (!IsPowerOfTwo(orig_surface->h)) { for (new_h = 1; new_h <= maxsize && new_h <= orig_surface->h * m_scale; new_h = new_h * 2); } scalew = ((float)new_w + 0.5) / orig_surface->w; scaleh = ((float)new_h + 0.5) / orig_surface->h; } // scale texture down if necessary if (scalew < 1.0 || scaleh < 1.0) { surface = zoomSurface(orig_surface, scalew, scaleh, SMOOTHING_ON); } // store dimensions m_w = surface->w; m_h = surface->h; GenTexture(surface, info, m_id, m_alpha, error); } // free the texture surface separately if it's a scaled copy of the original if (surface && surface != orig_surface ) { SDL_FreeSurface(surface); } // free the original surface if it's not a custom surface (used for the track map) if (!info.data && orig_surface) { SDL_FreeSurface(orig_surface); } return 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; }
bool Texture::Load(const std::string & path, const TextureInfo & info, std::ostream & error) { if (texid) { error << "Tried to double load texture " << path << std::endl; return false; } if (!info.data && path.empty()) { error << "Tried to load a texture with an empty name" << std::endl; return false; } if (!info.data && LoadDDS(path, info, error)) { return true; } if (info.cube) { return LoadCube(path, info, error); } SDL_Surface * surface = 0; if (info.data) { 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 surface = SDL_CreateRGBSurfaceFrom( info.data, info.width, info.height, info.bytespp * 8, info.width * info.bytespp, rmask, gmask, bmask, amask); } else { surface = IMG_Load(path.c_str()); } if (!surface) { error << "Error loading texture file: " << path << std::endl; error << IMG_GetError() << std::endl; return false; } const unsigned char * pixels = (const unsigned char *)surface->pixels; const unsigned bytespp = surface->format->BytesPerPixel; unsigned pitch = surface->pitch; unsigned w = surface->w; unsigned h = surface->h; // downsample if requested by application std::vector<unsigned char> pixelsd; unsigned wd = w; unsigned hd = h; if (info.maxsize == TextureInfo::SMALL) { if (w > 256) wd = w / 4; else if (w > 128) wd = w / 2; if (h > 256) hd = h / 4; else if (h > 128) hd = h / 2; } else if (info.maxsize == TextureInfo::MEDIUM) { if (w > 256) wd = w / 2; if (h > 256) hd = h / 2; } if (wd < w || hd < h) { pixelsd.resize(wd * hd * bytespp); SampleDownAvg( bytespp, w, h, pitch, pixels, wd, hd, wd * bytespp, &pixelsd[0]); pixels = &pixelsd[0]; pitch = wd * bytespp; w = wd; h = hd; } // store dimensions width = w; height = h; target = GL_TEXTURE_2D; // gen texture glGenTextures(1, &texid); CheckForOpenGLErrors("Texture ID generation", error); // setup texture glBindTexture(GL_TEXTURE_2D, texid); SetSampler(info); int internalformat, format; GetTextureFormat(surface, info, internalformat, format); // upload texture data glTexImage2D(GL_TEXTURE_2D, 0, internalformat, w, h, 0, format, GL_UNSIGNED_BYTE, pixels); CheckForOpenGLErrors("Texture creation", error); // If we support generatemipmap, go ahead and do it regardless of the info.mipmap setting. // In the GL3 renderer the sampler decides whether or not to do mip filtering, // so we conservatively make mipmaps available for all textures. if (GLC_ARB_framebuffer_object) glGenerateMipmap(GL_TEXTURE_2D); SDL_FreeSurface(surface); return true; }
ImagePtr DDSLoader::load(ArchiveFile& file) const { // Pass the call to the according load function return LoadDDS(file); }
void ae3d::Texture2D::Load( const FileSystem::FileContentsData& fileContents, TextureWrap aWrap, TextureFilter aFilter, Mipmaps aMipmaps, float aAnisotropy ) { filter = aFilter; wrap = aWrap; mipmaps = aMipmaps; anisotropy = aAnisotropy; if (!fileContents.isLoaded) { *this = Texture2DGlobal::defaultTexture; return; } const bool isCached = Texture2DGlobal::pathToCachedTexture.find( fileContents.path ) != Texture2DGlobal::pathToCachedTexture.end(); if (isCached && handle == 0) { *this = Texture2DGlobal::pathToCachedTexture[ fileContents.path ]; return; } // First load. if (handle == 0) { handle = GfxDevice::CreateTextureId(); if (GfxDevice::HasExtension( "KHR_debug" )) { glObjectLabel( GL_TEXTURE, handle, (GLsizei)fileContents.path.size(), fileContents.path.c_str() ); } fileWatcher.AddFile( fileContents.path, TexReload ); } glBindTexture( GL_TEXTURE_2D, handle ); glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, filter == TextureFilter::Nearest ? GL_NEAREST : (mipmaps == Mipmaps::Generate ? GL_LINEAR_MIPMAP_LINEAR : GL_LINEAR ) ); glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, filter == TextureFilter::Nearest ? GL_NEAREST : GL_LINEAR ); glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, wrap == TextureWrap::Repeat ? GL_REPEAT : GL_CLAMP_TO_EDGE ); glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, wrap == TextureWrap::Repeat ? GL_REPEAT : GL_CLAMP_TO_EDGE ); if (GfxDevice::HasExtension( "GL_EXT_texture_filter_anisotropic" ) && anisotropy > 1) { glTexParameterf( GL_TEXTURE_2D, 0x84FE/*GL_TEXTURE_MAX_ANISOTROPY_EXT*/, anisotropy ); } const bool isDDS = fileContents.path.find( ".dds" ) != std::string::npos || fileContents.path.find( ".DDS" ) != std::string::npos; if (HasStbExtension( fileContents.path )) { LoadSTB( fileContents ); } else if (isDDS) { LoadDDS( fileContents.path.c_str() ); } if (mipmaps == Mipmaps::Generate) { glGenerateMipmap( GL_TEXTURE_2D ); } Texture2DGlobal::pathToCachedTexture[ fileContents.path ] = *this; #if DEBUG Texture2DGlobal::pathToCachedTextureSizeInBytes[ fileContents.path ] = static_cast< std::size_t >(width * height * 4 * (mipmaps == Mipmaps::Generate ? 1.0f : 1.33333f)); //Texture2DGlobal::PrintMemoryUsage(); #endif }
/* * Setup OpenGL * * Set up GLFW and GLEW, opens a window. */ void SetupOpenGL() { if (!glfwInit()) { std::cerr << "Failed to initialize GLFW." << std::endl; exit(1); } glfwWindowHint(GLFW_SAMPLES, 4); glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3); glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE); glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); s_window = glfwCreateWindow(1024, 768, "Bullet + OpenGL", nullptr, nullptr); if (s_window == nullptr) { std::cerr << "Failed to open GLFW window." << std::endl; glfwTerminate(); exit(1); } glfwMakeContextCurrent(s_window); glewExperimental = GL_TRUE; if (glewInit() != GLEW_OK) { std::cerr << "Failed to initialize GLEW." << std::endl; glfwTerminate(); exit(1); } glfwSetInputMode(s_window, GLFW_STICKY_KEYS, GL_TRUE); glfwSetCursorPos(s_window, 1024/2, 768/2); glClearColor(0.0f, 0.0f, 0.4f, 0.0f); glEnable(GL_DEPTH_TEST); glDepthFunc(GL_LESS); glEnable(GL_CULL_FACE); glGenVertexArrays(1, &s_vertexArrayId); glBindVertexArray(s_vertexArrayId); s_model = LoadModelFromObjFile("../res/textures/cube.obj"); glGenBuffers(1, &s_vertexBufferId); glBindBuffer(GL_ARRAY_BUFFER, s_vertexBufferId); glBufferData(GL_ARRAY_BUFFER, s_model.vertices().size() * sizeof(glm::vec3), &s_model.vertices()[0], GL_STATIC_DRAW); glGenBuffers(1, &s_uvCoordBufferId); glBindBuffer(GL_ARRAY_BUFFER, s_uvCoordBufferId); glBufferData(GL_ARRAY_BUFFER, s_model.uvCoords().size() * sizeof(glm::vec2), &s_model.uvCoords()[0], GL_STATIC_DRAW); glGenBuffers(1, &s_normalBufferId); glBindBuffer(GL_ARRAY_BUFFER, s_normalBufferId); glBufferData(GL_ARRAY_BUFFER, s_model.normals().size() * sizeof(glm::vec3), &s_model.normals()[0], GL_STATIC_DRAW); LoadShaders("../res/shaders/vertex.glsl", "../res/shaders/fragment.glsl"); s_mvpMatrixId = glGetUniformLocation(s_programId, "mvpMatrix"); s_modelMatrixId = glGetUniformLocation(s_programId, "modelMatris"); s_viewMatrixId = glGetUniformLocation(s_programId, "modelMatrix"); s_textureId = LoadDDS("../res/textures/uvmap.DDS"); s_uniformTextureId = glGetUniformLocation(s_programId, "myTextureSampler"); glUseProgram(s_programId); s_lightPositionId = glGetUniformLocation(s_programId, "lightPosition_worldspace"); s_lightColorId = glGetUniformLocation(s_programId, "lightColor"); s_lightPowerId = glGetUniformLocation(s_programId, "lightPower"); }