From f10ced4626df7172ef0b2acc7e8341b54960e9ba Mon Sep 17 00:00:00 2001 From: Eduardo Bart Date: Tue, 23 Nov 2010 01:13:37 -0200 Subject: [PATCH] texture manager, texture loader, texture --- CMakeLists.txt | 3 + src/engine.cpp | 2 +- src/graphics.cpp | 2 + src/texture.cpp | 83 +++++++++++++++++++++++++++ src/texture.h | 56 ++++++++++++++++++ src/textureloader.cpp | 125 +++++++++++++++++++++++++++++++++++++++++ src/textureloader.h | 36 ++++++++++++ src/texturemanager.cpp | 71 +++++++++++++++++++++++ src/texturemanager.h | 49 ++++++++++++++++ 9 files changed, 426 insertions(+), 1 deletion(-) create mode 100644 src/texture.cpp create mode 100644 src/texture.h create mode 100644 src/textureloader.cpp create mode 100644 src/textureloader.h create mode 100644 src/texturemanager.cpp create mode 100644 src/texturemanager.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 12fa3abb..e78aeeed 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -50,6 +50,9 @@ ENDIF(CMAKE_BUILD_TYPE STREQUAL "Debug") # find sources SET(SOURCES + src/textureloader.cpp + src/texture.cpp + src/texturemanager.cpp src/configmanager.cpp src/resourcemanager.cpp src/main.cpp diff --git a/src/engine.cpp b/src/engine.cpp index 665c0534..acd8bbfa 100644 --- a/src/engine.cpp +++ b/src/engine.cpp @@ -126,7 +126,7 @@ void Engine::onClose() void Engine::onResize(int width, int height) { - + g_graphics.resize(width, height); } void Engine::onInputEvent(InputEvent *event) diff --git a/src/graphics.cpp b/src/graphics.cpp index e9f08eb3..571334ca 100644 --- a/src/graphics.cpp +++ b/src/graphics.cpp @@ -24,9 +24,11 @@ #include "graphics.h" #include "logger.h" +#include "texturemanager.h" #include #include +#include "platform.h" Graphics g_graphics; diff --git a/src/texture.cpp b/src/texture.cpp new file mode 100644 index 00000000..d56ac410 --- /dev/null +++ b/src/texture.cpp @@ -0,0 +1,83 @@ +/* The MIT License + * + * Copyright (c) 2010 OTClient, https://github.com/edubart/otclient + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + + +#include "texture.h" + +#include +#include + +Texture::Texture(int width, int height, unsigned char *pixels, int components) +{ + m_width = width; + m_height = height; + + glGenTextures(1, &m_textureId); + glBindTexture(GL_TEXTURE_2D, m_textureId); + glPixelStorei(GL_UNPACK_ALIGNMENT, 1); + + GLenum format = 0; + switch(components) { + case 4: + format = GL_RGBA; + break; + case 3: + format = GL_RGB; + break; + case 2: + format = GL_LUMINANCE_ALPHA; + break; + case 1: + format = GL_LUMINANCE; + break; + } + + glTexImage2D(GL_TEXTURE_2D, 0, components, width, height, 0, format, GL_UNSIGNED_BYTE, pixels); + + glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_WIDTH, &width); + glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_HEIGHT, &height); + + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); +} + +Texture::~Texture() +{ + if(m_textureId > 0) + glDeleteTextures(1, &m_textureId); +} + +void Texture::enableBilinearFilter() +{ + glBindTexture(GL_TEXTURE_2D, m_textureId); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); +} + +void Texture::bind() +{ + glBindTexture(GL_TEXTURE_2D, m_textureId); +} diff --git a/src/texture.h b/src/texture.h new file mode 100644 index 00000000..6245d5b3 --- /dev/null +++ b/src/texture.h @@ -0,0 +1,56 @@ +/* The MIT License + * + * Copyright (c) 2010 OTClient, https://github.com/edubart/otclient + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + + +#ifndef TEXTURE_H +#define TEXTURE_H + +#include +#include + +class TextureManager; + +class Texture +{ +public: + Texture(int width, int height, unsigned char *pixels, int components); + virtual ~Texture(); + + /// Bind texture for drawing + void bind(); + + /// Enable texture bilinear filter (smooth scaled textures) + void enableBilinearFilter(); + + int getWidth() const { return m_width; } + int getHeight() const { return m_height; } + +private: + GLuint m_textureId; + int m_width; + int m_height; +}; + +typedef boost::shared_ptr TexturePtr; + +#endif // TEXTURE_H diff --git a/src/textureloader.cpp b/src/textureloader.cpp new file mode 100644 index 00000000..7f73a34e --- /dev/null +++ b/src/textureloader.cpp @@ -0,0 +1,125 @@ +/* The MIT License + * + * Copyright (c) 2010 OTClient, https://github.com/edubart/otclient + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + + +#include "textureloader.h" + +#include +#include + +TexturePtr TextureLoader::loadPNG(const unsigned char *fileData, unsigned int fileSize) +{ + TexturePtr texture; + FILE *pngFile = fmemopen((void*)fileData, fileSize, "rb"); + + if(!pngFile) + return texture; + + png_byte sig[8]; + if(!fread(&sig, 8, 1, pngFile)) + return texture; + + if(png_sig_cmp(sig, 0, 8)) + return texture; + + png_structp png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); + if(!png_ptr) + return texture; + + png_infop info_ptr = png_create_info_struct(png_ptr); + if(!info_ptr) { + png_destroy_read_struct(&png_ptr, NULL, NULL); + return texture; + } + + if(setjmp(png_jmpbuf(png_ptr))) { + png_destroy_read_struct(&png_ptr, &info_ptr, NULL); + return texture; + } + + png_init_io(png_ptr, pngFile); + png_set_sig_bytes(png_ptr, 8); + png_read_info(png_ptr, info_ptr); + + int bitDepth = png_get_bit_depth(png_ptr, info_ptr); + int colourType = png_get_color_type(png_ptr, info_ptr); + + if(colourType == PNG_COLOR_TYPE_PALETTE) + png_set_palette_to_rgb(png_ptr); + + if(bitDepth < 8 && (colourType == PNG_COLOR_TYPE_GRAY || colourType == PNG_COLOR_TYPE_GRAY_ALPHA)) + png_set_expand_gray_1_2_4_to_8(png_ptr); + + if(png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS)) + png_set_tRNS_to_alpha(png_ptr); + + if(bitDepth < 8) + png_set_packing(png_ptr); + else if(bitDepth == 16) + png_set_strip_16(png_ptr); + + png_read_update_info(png_ptr, info_ptr); + + png_uint_32 width, height; + png_get_IHDR(png_ptr, info_ptr, &width, &height, &bitDepth, &colourType, NULL, NULL, NULL); + + int components; + switch(colourType) + { + case PNG_COLOR_TYPE_GRAY: + components = 1; + break; + case PNG_COLOR_TYPE_GRAY_ALPHA: + components = 2; + break; + case PNG_COLOR_TYPE_RGB: + components = 3; + break; + case PNG_COLOR_TYPE_RGB_ALPHA: + components = 4; + break; + default: + if(png_ptr) + png_destroy_read_struct(&png_ptr, &info_ptr, NULL); + return texture; + }; + + unsigned char *pixels = new unsigned char[width * height * components]; + + png_bytep *row_pointers = new png_bytep[height]; + for(unsigned int i = 0; i < height; ++i) + row_pointers[i] = (png_bytep)(pixels + (i * width * components)); + + png_read_image(png_ptr, row_pointers); + png_read_end(png_ptr, NULL); + + png_destroy_read_struct(&png_ptr, &info_ptr, NULL); + fclose(pngFile); + delete[] row_pointers; + + texture = TexturePtr(new Texture(width, height, pixels, components)); + + delete[] pixels; + + return texture; +} diff --git a/src/textureloader.h b/src/textureloader.h new file mode 100644 index 00000000..140f816e --- /dev/null +++ b/src/textureloader.h @@ -0,0 +1,36 @@ +/* The MIT License + * + * Copyright (c) 2010 OTClient, https://github.com/edubart/otclient + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + + +#ifndef TEXTURELOADER_H +#define TEXTURELOADER_H + +#include "texture.h" + +namespace TextureLoader +{ + /// Load a png textures using libpng + TexturePtr loadPNG(const unsigned char *fileData, unsigned int fileSize); +} + +#endif // TEXTURELOADER_H diff --git a/src/texturemanager.cpp b/src/texturemanager.cpp new file mode 100644 index 00000000..4320ef63 --- /dev/null +++ b/src/texturemanager.cpp @@ -0,0 +1,71 @@ +/* The MIT License + * + * Copyright (c) 2010 OTClient, https://github.com/edubart/otclient + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + + +#include "texturemanager.h" +#include "resourcemanager.h" +#include "textureloader.h" +#include "logger.h" + +#include + +TextureManager g_textures; + +TextureManager::TextureManager() +{ + +} + +TextureManager::~TextureManager() +{ + m_texturesMap.clear(); +} + +TexturePtr TextureManager::get(const std::string& textureFile) +{ + TexturePtr texture; + + // check if the texture is already loaded + TexturesMap::iterator it = m_texturesMap.find(textureFile); + if(it != m_texturesMap.end()) + texture = it->second; + else { // load texture + // currently only png textures are supported + if(!boost::ends_with(textureFile, ".png")) { + error("Unable to load texture %s, file format no supported.", textureFile.c_str()); + return texture; + } + + unsigned int fileSize; + unsigned char *textureFileData = g_resources.loadFile(textureFile, &fileSize); + if(!textureFileData) + return texture; + + texture = TextureLoader::loadPNG(textureFileData, fileSize); + if(!texture) + error("Unable to load texture %s, loading error.", textureFile.c_str()); + delete[] textureFileData; + } + + return texture; +} diff --git a/src/texturemanager.h b/src/texturemanager.h new file mode 100644 index 00000000..a95264ce --- /dev/null +++ b/src/texturemanager.h @@ -0,0 +1,49 @@ +/* The MIT License + * + * Copyright (c) 2010 OTClient, https://github.com/edubart/otclient + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + + +#ifndef TEXTUREMANAGER_H +#define TEXTUREMANAGER_H + +#include "texture.h" + +#include +#include + +class TextureManager +{ +public: + TextureManager(); + ~TextureManager(); + + /// Load a texture from file, if it was already loaded a cached one will be retrieved + TexturePtr get(const std::string& textureFile); + +private: + typedef std::map TexturesMap; + TexturesMap m_texturesMap; +}; + +extern TextureManager g_textures; + +#endif // TEXTUREMANAGER_H