diff options
author | Bjørn Lindeijer <bjorn@lindeijer.nl> | 2007-10-18 18:39:48 +0000 |
---|---|---|
committer | Bjørn Lindeijer <bjorn@lindeijer.nl> | 2007-10-18 18:39:48 +0000 |
commit | 86441fda9c561dd264039edc68ddabbf7cb54ce2 (patch) | |
tree | f9d15edf9587bc149a42399369bfcf3b9d5c5b27 | |
parent | d3ab0ef7be4c1f0098acc08748c308091e75dfff (diff) | |
download | mana-client-86441fda9c561dd264039edc68ddabbf7cb54ce2.tar.gz mana-client-86441fda9c561dd264039edc68ddabbf7cb54ce2.tar.bz2 mana-client-86441fda9c561dd264039edc68ddabbf7cb54ce2.tar.xz mana-client-86441fda9c561dd264039edc68ddabbf7cb54ce2.zip |
Merged removal of dependency on Guichan OpenGL from trunk to 0.0 branch,
including optimization of OpenGL memory usage on modern OpenGL drivers.
Patches by Guillaume Melquiond.
-rw-r--r-- | ChangeLog | 32 | ||||
-rwxr-xr-x | configure.ac | 18 | ||||
-rw-r--r-- | src/CMakeLists.txt | 24 | ||||
-rw-r--r-- | src/Makefile.am | 14 | ||||
-rw-r--r-- | src/graphics.cpp | 15 | ||||
-rw-r--r-- | src/graphics.h | 9 | ||||
-rw-r--r-- | src/gui/gui.cpp | 25 | ||||
-rw-r--r-- | src/gui/gui.h | 2 | ||||
-rw-r--r-- | src/main.cpp | 19 | ||||
-rw-r--r-- | src/main.h | 13 | ||||
-rw-r--r-- | src/openglgraphics.cpp | 135 | ||||
-rw-r--r-- | src/openglgraphics.h | 10 | ||||
-rw-r--r-- | src/resources/image.cpp | 66 | ||||
-rw-r--r-- | src/resources/image.h | 9 | ||||
-rw-r--r-- | src/resources/imageloader.cpp | 99 | ||||
-rw-r--r-- | src/resources/imageloader.h | 69 | ||||
-rw-r--r-- | src/resources/iteminfo.cpp | 1 | ||||
-rw-r--r-- | src/resources/openglsdlimageloader.cpp | 39 | ||||
-rw-r--r-- | src/resources/openglsdlimageloader.h | 38 | ||||
-rw-r--r-- | src/resources/sdlimageloader.cpp | 34 | ||||
-rw-r--r-- | src/resources/sdlimageloader.h | 37 | ||||
-rw-r--r-- | src/utils/minmax.h | 2 |
22 files changed, 397 insertions, 313 deletions
@@ -58,11 +58,11 @@ 2007-09-08 Philipp Sehmisch <tmw@crushnet.org> - * data/graphics/particles/aniblaze.png, + * data/graphics/particles/aniblaze.png, data/graphics/particles/cookingfire.particle.xml, data/graphics/particles/fireplace.particle.xml, - data/graphics/particles/flame.particle.xml: - Improved fire effects by using animated particles. + data/graphics/particles/flame.particle.xml: Improved fire effects by + using animated particles. 2007-09-06 Philipp Sehmisch <tmw@crushnet.org> @@ -150,6 +150,28 @@ * src/gui/updatewindow.cpp, src/main.cpp, tmw.cbp: Removed home dir from config file to avoid encoding issues. +2007-08-26 Guillaume Melquiond <guillaume.melquiond@gmail.com> + + * src/gui/button.cpp: Fixed incorrect button dimensions, as they mess + OpenGL display with rectangle textures. + * src/graphics.cpp, src/openglgraphics.h, src/graphics.h, + src/openglgraphics.cpp: Fixed fonts not being recolored by adding an + explicit parameter to require it. + +2007-08-25 Guillaume Melquiond <guillaume.melquiond@gmail.com> + + * configure.ac: Removed dependency on Guichan's OpenGL library. + * src/Makefile.am, src/resources/sdlimageloader.cpp, + src/resources/sdlimageloader.h, src/resources/openglsdlimageloader.h, + src/resources/openglsdlimageloader.cpp, src/resources/imageloader.cpp, + src/resources/imageloader.h, src/gui/gui.cpp, src/gui/gui.h: Replaced + Guichan's image loaders with our owns, so that we have control over all + the images used as textures. + * src/resources/image.cpp, src/openglgraphics.h, src/resources/image.h, + src/openglgraphics.cpp, src/graphics.cpp, src/graphics.h: Added support + for rectangle OpenGL textures when available, in order to reduce video + memory usage. + 2007-08-24 Bjørn Lindeijer <bjorn@lindeijer.nl> * src/gui/gui.h, src/gui/gui.cpp: Removed useless logic method and @@ -4270,9 +4292,9 @@ src/gui/status.h: Improving General Layout. * src/games.cpp, src/playerinfo.h, src/gui/char_server.cpp, src/gui/char_select.cpp, src/gui/ministatus.cpp, src/gui/skill.cpp, - src/gui/status.cpp, src/gui/status.h : Now the derived stats values + src/gui/status.cpp, src/gui/status.h: Now the derived stats values are got from the server, and then, are correct ones. - * src/gui/minimap.cpp : Only shows the Minimap Window if there's + * src/gui/minimap.cpp: Only shows the Minimap Window if there's actually a minimap to the current map. * src/gui/status.cpp, src/game.cpp: The derived stats are now updated correctly upon equipping/unequipping. diff --git a/configure.ac b/configure.ac index 1d420d80..382a26ba 100755 --- a/configure.ac +++ b/configure.ac @@ -5,7 +5,6 @@ AC_LANG_CPLUSPLUS # Checks for programs. AC_PROG_CXX -AC_PROG_CC AC_PROG_INSTALL AC_PROG_MAKE_SET @@ -25,7 +24,7 @@ AC_CHECK_FUNCS([atexit floor getcwd gethostbyname memset mkdir select socket]) # Checks for libraries AC_CHECK_LIB([pthread], [pthread_create], , -AC_MSG_ERROR([ *** Unable to find pthread library ])) +AC_MSG_ERROR([ *** Unable to find pthread library])) AC_CHECK_LIB([guichan], [gcnGuichanVersion], , AC_MSG_ERROR([ *** Unable to find Guichan library (guichan.sf.net)])) @@ -33,9 +32,6 @@ AC_MSG_ERROR([ *** Unable to find Guichan library (guichan.sf.net)])) #AC_CHECK_LIB([guichan_sdl], [gcnSDL], , #AC_MSG_ERROR([ *** Unable to find Guichan SDL library (guichan.sf.net)])) -#AC_CHECK_LIB([guichan_opengl], [gcnOpenGL], , -#AC_MSG_ERROR([ *** Unable to find Guichan OpenGL library (guichan.sf.net)])) - AC_CHECK_LIB([z], [inflate], , AC_MSG_ERROR([ *** Unable to find zlib (http://www.gzip.org/zlib/)])) @@ -59,9 +55,8 @@ AC_CHECK_LIB(SDL_image, IMG_LoadPNG_RW, , AC_MSG_ERROR([ *** Unable to find SDL_image library with PNG support (http://www.libsdl.org/projects/SDL_image/)])) -AC_CHECK_LIB(SDL_mixer, Mix_OpenAudio, , -AC_MSG_ERROR([ *** Unable to find SDL_mixer library -(http://www.libsdl.org/projects/SDL_mixer/)])) +AC_CHECK_LIB([SDL_mixer], [Mix_OpenAudio], , +AC_MSG_ERROR([ *** Unable to find SDL_mixer library (http://www.libsdl.org/projects/SDL_mixer/)])) AC_CHECK_LIB(SDL_net, SDLNet_Init, , AC_MSG_ERROR([ *** Unable to find SDL_net library])) @@ -82,10 +77,9 @@ if test "x$with_opengl" == "xno"; then with_opengl=no else with_opengl=yes - OPENGL_CFLAGS=' -DUSE_OPENGL' - OPENGL_LIBS=' -lGL -lguichan_opengl' - AC_SUBST(OPENGL_CFLAGS) - AC_SUBST(OPENGL_LIBS) + AC_CHECK_LIB([GL], [glBegin], , + AC_MSG_ERROR([ *** Unable to find OpenGL library])) + AC_DEFINE(USE_OPENGL, 1, [Defines if tmw should use an OpenGL display]) fi # Search for sdl-config diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 86d446b6..08a3b2a1 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -223,38 +223,36 @@ SET(SRCS resources/ambientoverlay.h resources/animation.cpp resources/animation.h + resources/buddylist.cpp + resources/buddylist.h resources/image.cpp resources/image.h + resources/imageloader.cpp + resources/imageloader.h + resources/imageset.h + resources/imageset.cpp resources/imagewriter.cpp resources/imagewriter.h resources/itemdb.cpp resources/itemdb.h - resources/iteminfo.h resources/iteminfo.cpp + resources/iteminfo.h resources/mapreader.cpp resources/mapreader.h - resources/monsterdb.h resources/monsterdb.cpp - resources/monsterinfo.h + resources/monsterdb.h resources/monsterinfo.cpp - resources/music.h + resources/monsterinfo.h resources/music.cpp - resources/openglsdlimageloader.h - resources/openglsdlimageloader.cpp + resources/music.h resources/resource.cpp resources/resource.h resources/resourcemanager.cpp resources/resourcemanager.h - resources/sdlimageloader.h - resources/sdlimageloader.cpp - resources/soundeffect.h resources/soundeffect.cpp + resources/soundeffect.h resources/spritedef.h resources/spritedef.cpp - resources/imageset.h - resources/imageset.cpp - resources/buddylist.h - resources/buddylist.cpp utils/base64.cpp utils/base64.h utils/dtor.h diff --git a/src/Makefile.am b/src/Makefile.am index 6d5ef196..1a121367 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -175,6 +175,10 @@ tmw_SOURCES = gui/widgets/resizegrip.cpp \ resources/animation.h \ resources/image.cpp \ resources/image.h \ + resources/imageloader.cpp \ + resources/imageloader.h \ + resources/imageset.h \ + resources/imageset.cpp \ resources/imagewriter.cpp \ resources/imagewriter.h \ resources/itemdb.cpp \ @@ -189,20 +193,14 @@ tmw_SOURCES = gui/widgets/resizegrip.cpp \ resources/monsterinfo.cpp \ resources/music.h \ resources/music.cpp \ - resources/openglsdlimageloader.h \ - resources/openglsdlimageloader.cpp \ resources/resource.cpp \ resources/resource.h \ resources/resourcemanager.cpp \ resources/resourcemanager.h \ - resources/sdlimageloader.h \ - resources/sdlimageloader.cpp \ resources/soundeffect.h \ resources/soundeffect.cpp \ resources/spritedef.h \ resources/spritedef.cpp \ - resources/imageset.h \ - resources/imageset.cpp \ resources/buddylist.h \ resources/buddylist.cpp \ utils/base64.cpp \ @@ -291,6 +289,6 @@ INCLUDES = \ # the library search path. tmw_LDFLAGS = $(all_libraries) $(LIBSDL_RPATH) `pkg-config --libs libxml-2.0` -tmw_CXXFLAGS = -Wall $(OPENGL_CFLAGS) $(LIBSDL_CFLAGS) `pkg-config --cflags libxml-2.0` $(CURL_CFLAGS) -tmw_LDADD = $(LIBSDL_LIBS) -lguichan_sdl $(OPENGL_LIBS) $(CURL_LIBS) +tmw_CXXFLAGS = -Wall $(LIBSDL_CFLAGS) `pkg-config --cflags libxml-2.0` $(CURL_CFLAGS) +tmw_LDADD = $(LIBSDL_LIBS) -lguichan_sdl $(CURL_LIBS) tmw_TARGET = tmw diff --git a/src/graphics.cpp b/src/graphics.cpp index 1e31f903..586f9f49 100644 --- a/src/graphics.cpp +++ b/src/graphics.cpp @@ -21,11 +21,13 @@ * $Id$ */ -#include "graphics.h" +#include <cassert> +#include "graphics.h" #include "log.h" #include "resources/image.h" +#include "resources/imageloader.h" Graphics::Graphics(): mScreen(0) @@ -125,7 +127,7 @@ bool Graphics::drawImage(Image *image, int x, int y) } bool Graphics::drawImage(Image *image, int srcX, int srcY, int dstX, int dstY, - int width, int height) + int width, int height, bool) { // Check that preconditions for blitting are met. if (!mScreen || !image || !image->mImage) return false; @@ -146,6 +148,15 @@ bool Graphics::drawImage(Image *image, int srcX, int srcY, int dstX, int dstY, return !(SDL_BlitSurface(image->mImage, &srcRect, mScreen, &dstRect) < 0); } +void Graphics::drawImage(gcn::Image const *image, int srcX, int srcY, + int dstX, int dstY, int width, int height) +{ + ProxyImage const *srcImage = + dynamic_cast< ProxyImage const * >(image); + assert(srcImage); + drawImage(srcImage->getImage(), srcX, srcY, dstX, dstY, width, height, true); +} + void Graphics::drawImagePattern(Image *image, int x, int y, int w, int h) { int iw = image->getWidth(); diff --git a/src/graphics.h b/src/graphics.h index 4637973f..564826a2 100644 --- a/src/graphics.h +++ b/src/graphics.h @@ -86,6 +86,12 @@ class Graphics : public gcn::SDLGraphics { bool drawImage(Image *image, int x, int y); /** + * Overrides with our own drawing method. + */ + void drawImage(gcn::Image const *image, int srcX, int srcY, + int dstX, int dstY, int width, int height); + + /** * Blits an image onto the screen. * * @return <code>true</code> if the image was blitted properly @@ -95,7 +101,8 @@ class Graphics : public gcn::SDLGraphics { drawImage(Image *image, int srcX, int srcY, int dstX, int dstY, - int width, int height); + int width, int height, + bool useColor = false); virtual void drawImagePattern(Image *image, diff --git a/src/gui/gui.cpp b/src/gui/gui.cpp index a83f794c..db0b9f80 100644 --- a/src/gui/gui.cpp +++ b/src/gui/gui.cpp @@ -30,14 +30,10 @@ // Should stay here because of Guichan being sensitive to headers order #include <guichan/sdl/sdlinput.hpp> -#ifdef USE_OPENGL -#include "../resources/openglsdlimageloader.h" -#endif - #include "focushandler.h" +#include "viewport.h" #include "window.h" #include "windowcontainer.h" -#include "viewport.h" #include "../configlistener.h" #include "../configuration.h" @@ -46,7 +42,7 @@ #include "../resources/imageset.h" #include "../resources/resourcemanager.h" -#include "../resources/sdlimageloader.h" +#include "../resources/imageloader.h" // Guichan stuff Gui *gui; @@ -79,7 +75,6 @@ class GuiConfigListener : public ConfigListener }; Gui::Gui(Graphics *graphics): - mHostImageLoader(NULL), mCustomCursor(false), mMouseCursors(NULL), mCursorType(CURSOR_POINTER) @@ -89,24 +84,16 @@ Gui::Gui(Graphics *graphics): setGraphics(graphics); // Set image loader -#ifdef USE_OPENGL - if (config.getValue("opengl", 0)) { - mImageLoader = new OpenGLSDLImageLoader(); - } else -#endif - { - mImageLoader = new SDLImageLoader(); - } + static ImageLoader imageLoader; + gcn::Image::setImageLoader(&imageLoader); // Set input guiInput = new gcn::SDLInput(); setInput(guiInput); - gcn::Image::setImageLoader(mImageLoader); - // Set focus handler delete mFocusHandler; - mFocusHandler = new FocusHandler(); + mFocusHandler = new FocusHandler; // Initialize top GUI widget WindowContainer *guiTop = new WindowContainer(); @@ -187,8 +174,6 @@ Gui::~Gui() delete speechFont; delete viewport; delete mTop; - delete mImageLoader; - delete mHostImageLoader; delete guiInput; } diff --git a/src/gui/gui.h b/src/gui/gui.h index c709893f..1e4b9348 100644 --- a/src/gui/gui.h +++ b/src/gui/gui.h @@ -98,8 +98,6 @@ class Gui : public gcn::Gui private: GuiConfigListener *mConfigListener; - gcn::ImageLoader *mHostImageLoader; /**< For loading images in GL */ - gcn::ImageLoader *mImageLoader; /**< For loading images */ gcn::Font *mGuiFont; /**< The global GUI font */ bool mCustomCursor; /**< Show custom cursor */ ImageSet *mMouseCursors; /**< Mouse cursor images */ diff --git a/src/main.cpp b/src/main.cpp index c6544017..be36ac4f 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -288,17 +288,18 @@ void init_engine(const Options &options) graphics = new Graphics(); #endif - int width = (int)config.getValue("screenwidth", 800); - int height = (int)config.getValue("screenheight", 600); + int width = (int) config.getValue("screenwidth", defaultScreenWidth); + int height = (int) config.getValue("screenheight", defaultScreenHeight); int bpp = 0; - bool fullscreen = ((int)config.getValue("screen", 0) == 1); - bool hwaccel = ((int)config.getValue("hwaccel", 0) == 1); + bool fullscreen = ((int) config.getValue("screen", 0) == 1); + bool hwaccel = ((int) config.getValue("hwaccel", 0) == 1); // Try to set the desired video mode if (!graphics->setVideoMode(width, height, bpp, fullscreen, hwaccel)) { - std::cerr << "Couldn't set " << width << "x" << height << "x" << - bpp << " video mode: " << SDL_GetError() << std::endl; + std::cerr << "Couldn't set " + << width << "x" << height << "x" << bpp << " video mode: " + << SDL_GetError() << std::endl; exit(1); } @@ -316,8 +317,10 @@ void init_engine(const Options &options) if (config.getValue("sound", 0) == 1) { sound.init(); } - sound.setSfxVolume((int) config.getValue("sfxVolume", 100)); - sound.setMusicVolume((int) config.getValue("musicVolume", 60)); + sound.setSfxVolume((int) config.getValue("sfxVolume", + defaultSfxVolume)); + sound.setMusicVolume((int) config.getValue("musicVolume", + defaultMusicVolume)); } catch (const char *err) { state = ERROR_STATE; @@ -36,7 +36,9 @@ #define TMW_DATADIR "" #endif - +/* + * Client different States + */ enum { EXIT_STATE, LOADDATA_STATE, @@ -65,6 +67,15 @@ enum { LEN_MIN_PASSWORD = 4 }; +// Default game values +// ------------------- +// Screen +const short defaultScreenWidth = 800; +const short defaultScreenHeight = 600; +// Sound +const short defaultSfxVolume = 100; +const short defaultMusicVolume = 60; + extern char n_server, n_character; extern unsigned char state; extern std::string errorMessage; diff --git a/src/openglgraphics.cpp b/src/openglgraphics.cpp index f2406e38..51e99fa0 100644 --- a/src/openglgraphics.cpp +++ b/src/openglgraphics.cpp @@ -21,10 +21,18 @@ * $Id$ */ +#include "main.h" + #ifdef USE_OPENGL +#ifndef GL_TEXTURE_RECTANGLE_ARB +#define GL_TEXTURE_RECTANGLE_ARB 0x84F5 +#define GL_MAX_RECTANGLE_TEXTURE_SIZE_ARB 0x84F8 +#endif + #include "openglgraphics.h" +#include <cstring> #include <SDL.h> #ifdef __APPLE__ @@ -33,7 +41,6 @@ #include <guichan/exception.hpp> #include <guichan/image.hpp> -#include <guichan/opengl/openglimage.hpp> #include "log.h" @@ -81,27 +88,79 @@ bool OpenGLGraphics::setVideoMode(int w, int h, int bpp, bool fs, bool hwaccel) logger->log("Using OpenGL %s double buffering.", (gotDoubleBuffer ? "with" : "without")); + char const *glExtensions = (char const *)glGetString(GL_EXTENSIONS); + int texSize; + bool rectTex = strstr(glExtensions, "GL_ARB_texture_rectangle"); + if (rectTex) + { + Image::mTextureType = GL_TEXTURE_RECTANGLE_ARB; + glGetIntegerv(GL_MAX_RECTANGLE_TEXTURE_SIZE_ARB, &texSize); + } + else + { + Image::mTextureType = GL_TEXTURE_2D; + glGetIntegerv(GL_MAX_TEXTURE_SIZE, &texSize); + } + Image::mTextureSize = texSize; + logger->log("OpenGL texture size: %d pixels%s", Image::mTextureSize, + rectTex ? " (rectangle textures)" : ""); + return true; } bool OpenGLGraphics::drawImage(Image *image, int srcX, int srcY, - int dstX, int dstY, int width, int height) + int dstX, int dstY, int width, int height, bool useColor) { srcX += image->mBounds.x; srcY += image->mBounds.y; - // Find OpenGL texture coordinates - float texX1 = srcX / (float)image->mTexWidth; - float texY1 = srcY / (float)image->mTexHeight; - float texX2 = (srcX + width) / (float)image->mTexWidth; - float texY2 = (srcY + height) / (float)image->mTexHeight; + if (!useColor) + { + glColor4f(1.0f, 1.0f, 1.0f, image->mAlpha); + } + + glBindTexture(Image::mTextureType, image->mGLImage); - glColor4f(1.0f, 1.0f, 1.0f, image->mAlpha); - glBindTexture(GL_TEXTURE_2D, image->mGLImage); + setTexturingAndBlending(true); - drawTexedQuad(dstX, dstY, width, height, texX1, texY1, texX2, texY2); + // Draw a textured quad. + glBegin(GL_QUADS); - glColor4ub(mColor.r, mColor.g, mColor.b, mColor.a); + if (Image::mTextureType == GL_TEXTURE_2D) + { + // Find OpenGL normalized texture coordinates. + float texX1 = srcX / (float)image->mTexWidth; + float texY1 = srcY / (float)image->mTexHeight; + float texX2 = (srcX + width) / (float)image->mTexWidth; + float texY2 = (srcY + height) / (float)image->mTexHeight; + + glTexCoord2f(texX1, texY1); + glVertex2i(dstX, dstY); + glTexCoord2f(texX2, texY1); + glVertex2i(dstX + width, dstY); + glTexCoord2f(texX2, texY2); + glVertex2i(dstX + width, dstY + height); + glTexCoord2f(texX1, texY2); + glVertex2i(dstX, dstY + height); + } + else + { + glTexCoord2i(srcX, srcY); + glVertex2i(dstX, dstY); + glTexCoord2i(srcX + width, srcY); + glVertex2i(dstX + width, dstY); + glTexCoord2i(srcX + width, srcY + height); + glVertex2i(dstX + width, dstY + height); + glTexCoord2i(srcX, srcY + height); + glVertex2i(dstX, dstY + height); + } + + glEnd(); + + if (!useColor) + { + glColor4ub(mColor.r, mColor.g, mColor.b, mColor.a); + } return true; } @@ -227,33 +286,6 @@ void OpenGLGraphics::setColor(const gcn::Color& color) mColorAlpha = (color.a != 255); } -void OpenGLGraphics::drawImage(const gcn::Image* image, - int srcX, int srcY, - int dstX, int dstY, - int width, int height) -{ - const gcn::OpenGLImage* srcImage = - dynamic_cast<const gcn::OpenGLImage*>(image); - - if (srcImage == NULL) - { - throw GCN_EXCEPTION("Trying to draw an image of unknown format, " - "must be an SDLImage."); - } - - // Find OpenGL texture coordinates - float texX1 = srcX / (float)srcImage->getTextureWidth(); - float texY1 = srcY / (float)srcImage->getTextureHeight(); - float texX2 = (srcX + width) / (float)srcImage->getTextureWidth(); - float texY2 = (srcY + height) / (float)srcImage->getTextureHeight(); - - // Please dont look too closely at the next line, it is not pretty. - // It uses the image data as a pointer to a GLuint - glBindTexture(GL_TEXTURE_2D, srcImage->getTextureHandle()); - - drawTexedQuad(dstX, dstY, width, height, texX1, texY1, texX2, texY2); -} - void OpenGLGraphics::drawPoint(int x, int y) { setTexturingAndBlending(false); @@ -295,9 +327,9 @@ void OpenGLGraphics::setTexturingAndBlending(bool enable) { if (enable) { if (!mTexture) { - glEnable(GL_TEXTURE_2D); + glEnable(Image::mTextureType); mTexture = true; - }; + } if (!mAlpha) { @@ -314,7 +346,7 @@ void OpenGLGraphics::setTexturingAndBlending(bool enable) } if (mTexture) { - glDisable(GL_TEXTURE_2D); + glDisable(Image::mTextureType); mTexture = false; } } @@ -334,25 +366,4 @@ void OpenGLGraphics::drawRectangle(const gcn::Rectangle& rect, bool filled) glEnd(); } -void OpenGLGraphics::drawTexedQuad(int x, int y, int w, int h, - float texX1, float texY1, float texX2, float texY2) -{ - setTexturingAndBlending(true); - - // Draw a textured quad - glBegin(GL_QUADS); - glTexCoord2f(texX1, texY1); - glVertex2i(x, y); - - glTexCoord2f(texX2, texY1); - glVertex2i(x + w, y); - - glTexCoord2f(texX2, texY2); - glVertex2i(x + w, y + h); - - glTexCoord2f(texX1, texY2); - glVertex2i(x, y + h); - glEnd(); -} - #endif // USE_OPENGL diff --git a/src/openglgraphics.h b/src/openglgraphics.h index c61ae66c..ee5bc1e1 100644 --- a/src/openglgraphics.h +++ b/src/openglgraphics.h @@ -38,7 +38,8 @@ class OpenGLGraphics : public Graphics bool drawImage(Image *image, int srcX, int srcY, int dstX, int dstY, - int width, int height); + int width, int height, + bool useColor); void updateScreen(); @@ -50,11 +51,6 @@ class OpenGLGraphics : public Graphics void setColor(const gcn::Color &color); - void drawImage(const gcn::Image* image, - int srcX, int srcY, - int dstX, int dstY, - int width, int height); - void drawPoint(int x, int y); void drawLine(int x1, int y1, int x2, int y2); @@ -74,8 +70,6 @@ class OpenGLGraphics : public Graphics protected: void setTexturingAndBlending(bool enable); - void drawTexedQuad(int x, int y, int w, int h, - float texX1, float texY1, float texX2, float texY2); private: bool mAlpha, mTexture; diff --git a/src/resources/image.cpp b/src/resources/image.cpp index ad280eeb..995e34b0 100644 --- a/src/resources/image.cpp +++ b/src/resources/image.cpp @@ -29,6 +29,8 @@ #ifdef USE_OPENGL bool Image::mUseOpenGL = false; +int Image::mTextureType = 0; +int Image::mTextureSize = 0; #endif Image::Image(const std::string &idPath, SDL_Surface *image): @@ -89,23 +91,21 @@ Image* Image::load(void *buffer, unsigned int bufferSize, return NULL; } - // Determine 32-bit masks based on byte order - 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 + Image *image = load(tmpImage, idPath); + + SDL_FreeSurface(tmpImage); + return image; +} + +Image *Image::load(SDL_Surface *tmpImage, std::string const &idPath) +{ #ifdef USE_OPENGL if (mUseOpenGL) { + // Flush current error flag. + glGetError(); + int width = tmpImage->w; int height = tmpImage->h; int realWidth = powerOfTwo(width); @@ -120,6 +120,20 @@ Image* Image::load(void *buffer, unsigned int bufferSize, // Make sure the alpha channel is not used, but copied to destination SDL_SetAlpha(tmpImage, 0, SDL_ALPHA_OPAQUE); + // Determine 32-bit masks based on byte order + 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 + SDL_Surface *oldImage = tmpImage; tmpImage = SDL_CreateRGBSurface(SDL_SWSURFACE, realWidth, realHeight, 32, rmask, gmask, bmask, amask); @@ -130,25 +144,24 @@ Image* Image::load(void *buffer, unsigned int bufferSize, } SDL_BlitSurface(oldImage, NULL, tmpImage, NULL); - SDL_FreeSurface(oldImage); GLuint texture; glGenTextures(1, &texture); - glBindTexture(GL_TEXTURE_2D, texture); + glBindTexture(mTextureType, texture); if (SDL_MUSTLOCK(tmpImage)) { SDL_LockSurface(tmpImage); } glTexImage2D( - GL_TEXTURE_2D, 0, 4, + mTextureType, 0, 4, tmpImage->w, tmpImage->h, 0, GL_RGBA, GL_UNSIGNED_BYTE, tmpImage->pixels); glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexParameteri(mTextureType, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(mTextureType, GL_TEXTURE_MAG_FILTER, GL_NEAREST); if (SDL_MUSTLOCK(tmpImage)) { SDL_UnlockSurface(tmpImage); @@ -219,7 +232,6 @@ Image* Image::load(void *buffer, unsigned int bufferSize, else { image = SDL_DisplayFormat(tmpImage); } - SDL_FreeSurface(tmpImage); if (!image) { logger->log("Error: Image convert failed."); @@ -289,12 +301,20 @@ Image::setLoadAsOpenGL(bool useOpenGL) int Image::powerOfTwo(int input) { - int value = 1; - while (value < input && value < 1024) + int value; + if (mTextureType == GL_TEXTURE_2D) + { + value = 1; + while (value < input && value < mTextureSize) + { + value <<= 1; + } + } + else { - value <<= 1; + value = input; } - return value; + return value >= mTextureSize ? mTextureSize : value; } #endif diff --git a/src/resources/image.h b/src/resources/image.h index 23715ecb..34515dda 100644 --- a/src/resources/image.h +++ b/src/resources/image.h @@ -24,6 +24,8 @@ #ifndef _TMW_IMAGE_H #define _TMW_IMAGE_H +#include "../main.h" + #include <SDL.h> #ifdef USE_OPENGL @@ -69,6 +71,11 @@ class Image : public Resource load(void* buffer, unsigned int bufferSize, const std::string &idPath); /** + * Loads an image from an SDL surface. + */ + static Image *load(SDL_Surface *, std::string const &idPath); + + /** * Frees the resources created by SDL. */ virtual void @@ -141,6 +148,8 @@ class Image : public Resource int mTexWidth, mTexHeight; static bool mUseOpenGL; + static int mTextureType; + static int mTextureSize; #endif SDL_Surface *mImage; float mAlpha; diff --git a/src/resources/imageloader.cpp b/src/resources/imageloader.cpp new file mode 100644 index 00000000..81a5cf63 --- /dev/null +++ b/src/resources/imageloader.cpp @@ -0,0 +1,99 @@ +/* + * The Mana World + * Copyright 2007 The Mana World Development Team + * + * This file is part of The Mana World. + * + * The Mana World is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * any later version. + * + * The Mana World is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with The Mana World; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * $Id: imageloader.cpp 3515 2007-08-25 16:56:52Z gmelquio $ + */ + +#include <cassert> +#include <string> +#include <guichan/color.hpp> +#include <guichan/sdl/sdlpixel.hpp> + +#include "imageloader.h" + +#include "image.h" +#include "resourcemanager.h" + +ProxyImage::ProxyImage(SDL_Surface *s): + mImage(NULL), mSDLImage(s) +{ +} + +ProxyImage::~ProxyImage() +{ + free(); +} + +void ProxyImage::free() +{ + if (mSDLImage) + { + SDL_FreeSurface(mSDLImage); + mSDLImage = NULL; + } + else if (mImage) + { + delete mImage; + mImage = NULL; + } +} + +int ProxyImage::getWidth() const +{ + return mSDLImage ? mSDLImage->w : mImage->getWidth(); +} + +int ProxyImage::getHeight() const +{ + return mSDLImage ? mSDLImage->h : mImage->getHeight(); +} + +gcn::Color ProxyImage::getPixel(int x, int y) +{ + assert(mSDLImage); + return gcn::SDLgetPixel(mSDLImage, x, y); +} + +void ProxyImage::putPixel(int x, int y, gcn::Color const &color) +{ + assert(mSDLImage); + gcn::SDLputPixel(mSDLImage, x, y, color); +} + +void ProxyImage::convertToDisplayFormat() +{ + assert(mSDLImage); + /* The picture is most probably full of the pink pixels Guichan uses for + transparency, as this function will only be called when setting an image + font. Get rid of them. */ + SDL_SetColorKey(mSDLImage, SDL_SRCCOLORKEY, + SDL_MapRGB(mSDLImage->format, 255, 0, 255)); + mImage = ::Image::load(mSDLImage, std::string()); + SDL_FreeSurface(mSDLImage); + mSDLImage = NULL; +} + +gcn::Image *ImageLoader::load(std::string const &filename, bool convert) +{ + ResourceManager *resman = ResourceManager::getInstance(); + ProxyImage *i = new ProxyImage(resman->loadSDLSurface(filename)); + if (convert) i->convertToDisplayFormat(); + return i; +} diff --git a/src/resources/imageloader.h b/src/resources/imageloader.h new file mode 100644 index 00000000..89f38eda --- /dev/null +++ b/src/resources/imageloader.h @@ -0,0 +1,69 @@ +/* + * The Mana World + * Copyright 2007 The Mana World Development Team + * + * This file is part of The Mana World. + * + * The Mana World is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * any later version. + * + * The Mana World is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with The Mana World; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * $Id: imageloader.h 3515 2007-08-25 16:56:52Z gmelquio $ + */ + +#ifndef _TMW_IMAGELOADER_H +#define _TMW_IMAGELOADER_H + +#include <string> + +#include <guichan/image.hpp> +#include <guichan/imageloader.hpp> + +class Image; +struct SDL_Surface; + +class ProxyImage : public gcn::Image +{ + public: + ProxyImage(SDL_Surface *); + ~ProxyImage(); + void free(); + int getWidth() const; + int getHeight() const; + gcn::Color getPixel(int x, int y); + void putPixel(int x, int y, gcn::Color const &color); + void convertToDisplayFormat(); + + /** + * Gets the image handled by this proxy. + */ + ::Image *getImage() const + { return mImage; } + + private: + ::Image *mImage; /**< The real image. */ + + /** + * An SDL surface kept around until Guichan is done reading pixels from + * an OpenGL texture. + */ + SDL_Surface *mSDLImage; +}; + +class ImageLoader : public gcn::ImageLoader +{ + public: + gcn::Image *load(std::string const &filename, bool convertToDisplayFormat); +}; + +#endif diff --git a/src/resources/iteminfo.cpp b/src/resources/iteminfo.cpp index c2be5396..b5b25ac0 100644 --- a/src/resources/iteminfo.cpp +++ b/src/resources/iteminfo.cpp @@ -18,6 +18,7 @@ * along with The Mana World; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * + * $Id$ */ #include "iteminfo.h" diff --git a/src/resources/openglsdlimageloader.cpp b/src/resources/openglsdlimageloader.cpp deleted file mode 100644 index 5915fb49..00000000 --- a/src/resources/openglsdlimageloader.cpp +++ /dev/null @@ -1,39 +0,0 @@ -/* - * The Mana World - * Copyright 2004 The Mana World Development Team - * - * This file is part of The Mana World. - * - * The Mana World is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * any later version. - * - * The Mana World is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with The Mana World; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - * $Id: sdlimageloader.cpp 2121 2006-01-31 02:55:26Z der_doener $ - */ - -#ifdef USE_OPENGL - -#include "openglsdlimageloader.h" - -#include <string> - -#include "resourcemanager.h" - -SDL_Surface* -OpenGLSDLImageLoader::loadSDLSurface(const std::string &filename) -{ - ResourceManager *resman = ResourceManager::getInstance(); - return resman->loadSDLSurface(filename); -} - -#endif diff --git a/src/resources/openglsdlimageloader.h b/src/resources/openglsdlimageloader.h deleted file mode 100644 index b79dde15..00000000 --- a/src/resources/openglsdlimageloader.h +++ /dev/null @@ -1,38 +0,0 @@ -/* - * The Mana World - * Copyright 2004 The Mana World Development Team - * - * This file is part of The Mana World. - * - * The Mana World is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * any later version. - * - * The Mana World is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with The Mana World; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - * $Id: sdlimageloader.h 1724 2005-09-12 22:15:35Z der_doener $ - */ - -#ifndef _TMW_OPENGLSDLIMAGELOADER_H -#define _TMW_OPENGLSDLIMAGELOADER_H - -#include <iosfwd> - -#include <guichan/opengl/openglsdlimageloader.hpp> - -class OpenGLSDLImageLoader : public gcn::OpenGLSDLImageLoader -{ - protected: - SDL_Surface* - loadSDLSurface(const std::string &filename); -}; - -#endif diff --git a/src/resources/sdlimageloader.cpp b/src/resources/sdlimageloader.cpp deleted file mode 100644 index ae4f4dcb..00000000 --- a/src/resources/sdlimageloader.cpp +++ /dev/null @@ -1,34 +0,0 @@ -/* - * The Mana World - * Copyright 2004 The Mana World Development Team - * - * This file is part of The Mana World. - * - * The Mana World is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * any later version. - * - * The Mana World is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with The Mana World; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - * $Id$ - */ - -#include "sdlimageloader.h" - -#include <string> - -#include "resourcemanager.h" - -SDL_Surface* SDLImageLoader::loadSDLSurface(const std::string& filename) -{ - ResourceManager *resman = ResourceManager::getInstance(); - return resman->loadSDLSurface(filename); -} diff --git a/src/resources/sdlimageloader.h b/src/resources/sdlimageloader.h deleted file mode 100644 index 50b1d4f1..00000000 --- a/src/resources/sdlimageloader.h +++ /dev/null @@ -1,37 +0,0 @@ -/* - * The Mana World - * Copyright 2004 The Mana World Development Team - * - * This file is part of The Mana World. - * - * The Mana World is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * any later version. - * - * The Mana World is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with The Mana World; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - * $Id$ - */ - -#ifndef _TMW_SDLIMAGELOADER_H -#define _TMW_SDLIMAGELOADER_H - -#include <iosfwd> - -#include <guichan/sdl/sdlimageloader.hpp> - -class SDLImageLoader : public gcn::SDLImageLoader -{ - protected: - SDL_Surface* loadSDLSurface(const std::string& filename); -}; - -#endif diff --git a/src/utils/minmax.h b/src/utils/minmax.h index ea6ad9e0..427c5da7 100644 --- a/src/utils/minmax.h +++ b/src/utils/minmax.h @@ -21,6 +21,8 @@ * $Id$ */ +#include <cstdlib> + /** * Returns a random numeric value that is larger than or equal min and smaller * than max |