summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog9
-rw-r--r--src/Makefile.am2
-rw-r--r--src/graphics.cpp185
-rw-r--r--src/graphics.h52
-rw-r--r--src/gui/gui.cpp7
-rw-r--r--src/main.cpp9
-rw-r--r--src/openglgraphics.cpp389
-rw-r--r--src/openglgraphics.h68
-rw-r--r--src/resources/image.h3
9 files changed, 506 insertions, 218 deletions
diff --git a/ChangeLog b/ChangeLog
index 4d23aba1..7980ed93 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,12 @@
+2005-08-18 Björn Steinbrink <B.Steinbrink@gmx.de>
+
+ * src/Makefile.am, src/graphics.cpp, src/graphics.h, src/main.cpp,
+ src/openglgraphics.cpp src/openglgraphics.h, src/gui/gui.cpp,
+ src/resources/image.h: Semi-separated OpenGL and SDL graphics classes,
+ improves OpenGL performance quite a bit, while rewriting a good bunch of
+ code provided by guichan (but maybe we'll diverge so much that we'd need
+ that anyways...)
+
2005-08-17 Eugenio Favalli <elvenprogrammer@gmail.com>
* src/configuration.cpp, src/resources/itemmanager.cpp,
diff --git a/src/Makefile.am b/src/Makefile.am
index d20280fa..a8ffa48c 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -153,6 +153,8 @@ tmw_SOURCES = graphic/spriteset.cpp \
main.h \
map.cpp\
map.h \
+ openglgraphics.cpp\
+ openglgraphics.h \
playerinfo.h \
serverinfo.h \
sound.cpp \
diff --git a/src/graphics.cpp b/src/graphics.cpp
index 98a17b4a..9bfce133 100644
--- a/src/graphics.cpp
+++ b/src/graphics.cpp
@@ -35,17 +35,10 @@
extern volatile int framesToDraw;
-#ifdef USE_OPENGL
-Graphics::Graphics(bool useOpenGL):
- mScreen(0), useOpenGL(useOpenGL)
-{
-}
-#else
Graphics::Graphics():
mScreen(0)
{
}
-#endif
Graphics::~Graphics()
{
@@ -63,18 +56,10 @@ bool Graphics::setVideoMode(int w, int h, int bpp, bool fs, bool hwaccel)
displayFlags |= SDL_FULLSCREEN;
}
-#ifdef USE_OPENGL
- if (useOpenGL) {
- displayFlags |= SDL_OPENGL;
- SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
- } else
-#endif
- {
- if (hwaccel) {
- displayFlags |= SDL_HWSURFACE | SDL_DOUBLEBUF;
- } else {
- displayFlags |= SDL_SWSURFACE;
- }
+ if (hwaccel) {
+ displayFlags |= SDL_HWSURFACE | SDL_DOUBLEBUF;
+ } else {
+ displayFlags |= SDL_SWSURFACE;
}
mScreen = SDL_SetVideoMode(w, h, bpp, displayFlags);
@@ -114,22 +99,7 @@ bool Graphics::setVideoMode(int w, int h, int bpp, bool fs, bool hwaccel)
((vi->blit_fill) ? "yes" : "no"));
logger->log("Available video memory: %d", vi->video_mem);
-#ifdef USE_OPENGL
- if (useOpenGL) {
- // Setup OpenGL
- glViewport(0, 0, w, h);
- glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_FASTEST);
- int gotDoubleBuffer;
- SDL_GL_GetAttribute(SDL_GL_DOUBLEBUFFER, &gotDoubleBuffer);
- logger->log("Using OpenGL %s double buffering.",
- (gotDoubleBuffer ? "with" : "without"));
-
- setTargetPlane(w, h);
- } else
-#endif
- {
- setTarget(mScreen);
- }
+ setTarget(mScreen);
return true;
}
@@ -165,53 +135,18 @@ bool Graphics::drawImage(Image *image, int srcX, int srcY, int dstX, int dstY,
srcX += image->bounds.x;
srcY += image->bounds.y;
-#ifdef USE_OPENGL
- if (useOpenGL) {
- // Find OpenGL texture coordinates
- float texX1 = srcX / (float)image->texWidth;
- float texY1 = srcY / (float)image->texHeight;
- float texX2 = (srcX + width) / (float)image->texWidth;
- float texY2 = (srcY + height) / (float)image->texHeight;
-
- glColor4f(1.0f, 1.0f, 1.0f, image->alpha);
- glBindTexture(GL_TEXTURE_2D, image->glimage);
- glEnable(GL_TEXTURE_2D);
- glEnable(GL_BLEND);
-
- // Draw a textured quad -- the image
- glBegin(GL_QUADS);
- glTexCoord2f(texX1, texY1);
- glVertex3i(dstX, dstY, 0);
-
- glTexCoord2f(texX2, texY1);
- glVertex3i(dstX + width, dstY, 0);
-
- glTexCoord2f(texX2, texY2);
- glVertex3i(dstX + width, dstY + height, 0);
-
- glTexCoord2f(texX1, texY2);
- glVertex3i(dstX, dstY + height, 0);
- glEnd();
-
- glDisable(GL_TEXTURE_2D);
- glDisable(GL_BLEND);
- glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
- } else
-#endif
- {
- // Check that preconditions for blitting are met.
- if (!mScreen || !image->image) return false;
-
- SDL_Rect dstRect;
- SDL_Rect srcRect;
- dstRect.x = dstX; dstRect.y = dstY;
- srcRect.x = srcX; srcRect.y = srcY;
- srcRect.w = width;
- srcRect.h = height;
-
- if (SDL_BlitSurface(image->image, &srcRect, mScreen, &dstRect) < 0) {
- return false;
- }
+ // Check that preconditions for blitting are met.
+ if (!mScreen || !image->image) return false;
+
+ SDL_Rect dstRect;
+ SDL_Rect srcRect;
+ dstRect.x = dstX; dstRect.y = dstY;
+ srcRect.x = srcX; srcRect.y = srcY;
+ srcRect.w = width;
+ srcRect.h = height;
+
+ if (SDL_BlitSurface(image->image, &srcRect, mScreen, &dstRect) < 0) {
+ return false;
}
return true;
@@ -291,16 +226,7 @@ void Graphics::drawImageRect(
void Graphics::updateScreen()
{
-#ifdef USE_OPENGL
- if (useOpenGL) {
- glFlush();
- glFinish();
- SDL_GL_SwapBuffers();
- } else
-#endif
- {
- SDL_Flip(mScreen);
- }
+ SDL_Flip(mScreen);
// Decrement frame counter when using framerate limiting
if (framesToDraw > 1) framesToDraw--;
@@ -311,78 +237,3 @@ void Graphics::updateScreen()
SDL_Delay(10);
}
}
-
-#ifdef USE_OPENGL
-void Graphics::_beginDraw()
-{
- if (useOpenGL) {
- gcn::OpenGLGraphics::_beginDraw();
- } else {
- gcn::SDLGraphics::_beginDraw();
- }
-}
-
-void Graphics::_endDraw()
-{
- if (useOpenGL) {
- gcn::OpenGLGraphics::_endDraw();
- } else {
- gcn::SDLGraphics::_endDraw();
- }
-}
-
-void Graphics::setFont(gcn::ImageFont *font)
-{
- if (!useOpenGL) {
- gcn::SDLGraphics::setFont(font);
- } else {
- gcn::OpenGLGraphics::setFont(font);
- }
-}
-
-void Graphics::drawText(const std::string &text,
- int x, int y, unsigned int alignment)
-{
- if (!useOpenGL) {
- gcn::SDLGraphics::drawText(text, x, y, alignment);
- } else {
- gcn::OpenGLGraphics::drawText(text, x, y, alignment);
- }
-}
-
-void Graphics::setColor(gcn::Color color)
-{
- if (!useOpenGL) {
- gcn::SDLGraphics::setColor(color);
- } else {
- gcn::OpenGLGraphics::setColor(color);
- }
-}
-
-void Graphics::popClipArea()
-{
- if (!useOpenGL) {
- gcn::SDLGraphics::popClipArea();
- } else {
- gcn::OpenGLGraphics::popClipArea();
- }
-}
-
-bool Graphics::pushClipArea(gcn::Rectangle area)
-{
- if (!useOpenGL) {
- return gcn::SDLGraphics::pushClipArea(area);
- } else {
- return gcn::OpenGLGraphics::pushClipArea(area);
- }
-}
-
-void Graphics::fillRectangle(const gcn::Rectangle &rectangle)
-{
- if (!useOpenGL) {
- gcn::SDLGraphics::fillRectangle(rectangle);
- } else {
- gcn::OpenGLGraphics::fillRectangle(rectangle);
- }
-}
-#endif
diff --git a/src/graphics.h b/src/graphics.h
index a3b4aab3..f62662f7 100644
--- a/src/graphics.h
+++ b/src/graphics.h
@@ -25,9 +25,6 @@
#define _GRAPHICS_H
#include <guichan/sdl/sdlgraphics.hpp>
-#ifdef USE_OPENGL
-#include <guichan/opengl/openglgraphics.hpp>
-#endif
#include "guichanfwd.h"
@@ -39,30 +36,22 @@ class SDL_Surface;
/**
* A central point of control for graphics.
*/
-class Graphics :
-#ifdef USE_OPENGL
-public gcn::OpenGLGraphics,
-#endif
-public gcn::SDLGraphics {
+class Graphics : public gcn::SDLGraphics {
public:
/**
* Constructor.
*/
-#ifdef USE_OPENGL
- Graphics(bool useOpenGL);
-#else
Graphics();
-#endif
/**
* Destructor.
*/
- ~Graphics();
+ virtual ~Graphics();
/**
* Try to create a window with the given settings.
*/
- bool setVideoMode(int w, int h, int bpp, bool fs, bool hwaccel);
+ virtual bool setVideoMode(int w, int h, int bpp, bool fs, bool hwaccel);
/**
* Set fullscreen mode.
@@ -83,9 +72,9 @@ public gcn::SDLGraphics {
* @return <code>true</code> if the image was blitted properly
* <code>false</code> otherwise.
*/
- bool drawImage(Image *image, int srcX, int srcY, int dstX, int dstY, int width, int height);
+ virtual bool drawImage(Image *image, int srcX, int srcY, int dstX, int dstY, int width, int height);
- void drawImagePattern(Image *image, int x, int y, int w, int h);
+ virtual void drawImagePattern(Image *image, int x, int y, int w, int h);
/**
* Draws a rectangle using images. 4 corner images, 4 side images and 1
@@ -111,7 +100,7 @@ public gcn::SDLGraphics {
* Updates the screen. This is done by either copying the buffer to the
* screen or swapping pages.
*/
- void updateScreen();
+ virtual void updateScreen();
/**
* Returns the width of the screen.
@@ -123,36 +112,9 @@ public gcn::SDLGraphics {
*/
int getHeight();
- /*
- * Wrapper functions to delegate calls to the right base-class when we
- * compile with OpenGL support and thus have two gcn::Graphics
- * base-classes.
- */
-#ifdef USE_OPENGL
- void _beginDraw();
- void _endDraw();
-
- void setFont(gcn::ImageFont *font);
-
- void drawText(const std::string &text,
- int x,
- int y,
- unsigned int alignment);
-
- void setColor(gcn::Color color);
-
- void popClipArea();
- bool pushClipArea(gcn::Rectangle area);
-
- void fillRectangle(const gcn::Rectangle &rectangle);
-#endif
-
- private:
+ protected:
SDL_Surface *mScreen;
bool mFullscreen, mHWAccel;
-#ifdef USE_OPENGL
- bool useOpenGL;
-#endif
};
#endif
diff --git a/src/gui/gui.cpp b/src/gui/gui.cpp
index 5f37e566..612ca7a1 100644
--- a/src/gui/gui.cpp
+++ b/src/gui/gui.cpp
@@ -69,10 +69,10 @@ Gui::Gui(Graphics *graphics):
mMouseCursor(NULL),
mCustomCursor(false)
{
+ // Set graphics
+ setGraphics(graphics);
#ifdef USE_OPENGL
if (config.getValue("opengl", 0)) {
- // Set graphics
- setGraphics((gcn::OpenGLGraphics*)graphics);
// Set image loader
mHostImageLoader = new gcn::SDLImageLoader();
@@ -80,9 +80,6 @@ Gui::Gui(Graphics *graphics):
} else
#endif
{
- // Set graphics
- setGraphics((gcn::SDLGraphics*)graphics);
-
// Set image loader
mImageLoader = new gcn::SDLImageLoader();
}
diff --git a/src/main.cpp b/src/main.cpp
index a6c07467..42212b25 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -40,6 +40,9 @@
#include "game.h"
#include "graphics.h"
#include "log.h"
+#ifdef USE_OPENGL
+#include "openglgraphics.h"
+#endif
#include "playerinfo.h"
#include "sound.h"
@@ -237,7 +240,11 @@ void init_engine()
Image::setLoadAsOpenGL(useOpenGL);
// Create the graphics context
- graphics = new Graphics(useOpenGL);
+ if (useOpenGL) {
+ graphics = new OpenGLGraphics();
+ } else {
+ graphics = new Graphics();
+ }
#else
// Create the graphics context
graphics = new Graphics();
diff --git a/src/openglgraphics.cpp b/src/openglgraphics.cpp
new file mode 100644
index 00000000..5008a22f
--- /dev/null
+++ b/src/openglgraphics.cpp
@@ -0,0 +1,389 @@
+/*
+ * 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$
+ */
+
+#ifdef USE_OPENGL
+
+#include "openglgraphics.h"
+
+#include <iostream>
+#include <SDL.h>
+
+#include "log.h"
+
+#include "resources/image.h"
+
+extern volatile int framesToDraw;
+
+OpenGLGraphics::OpenGLGraphics():
+ mAlpha(false), mTexture(false), mColorAlpha(false)
+{
+}
+
+OpenGLGraphics::~OpenGLGraphics()
+{
+}
+
+bool OpenGLGraphics::setVideoMode(int w, int h, int bpp, bool fs, bool hwaccel)
+{
+ int displayFlags = SDL_ANYFORMAT | SDL_OPENGL;
+
+ mFullscreen = fs;
+ mHWAccel = hwaccel;
+
+ if (fs) {
+ displayFlags |= SDL_FULLSCREEN;
+ }
+
+ SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
+
+ if (!(mScreen = SDL_SetVideoMode(w, h, bpp, displayFlags))) {
+ return false;
+ }
+
+ // Setup OpenGL
+ glViewport(0, 0, w, h);
+ glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_FASTEST);
+ int gotDoubleBuffer;
+ SDL_GL_GetAttribute(SDL_GL_DOUBLEBUFFER, &gotDoubleBuffer);
+ logger->log("Using OpenGL %s double buffering.",
+ (gotDoubleBuffer ? "with" : "without"));
+
+ return true;
+}
+
+bool OpenGLGraphics::drawImage(Image *image, int srcX, int srcY,
+ int dstX, int dstY, int width, int height)
+{
+ srcX += image->bounds.x;
+ srcY += image->bounds.y;
+
+ // Find OpenGL texture coordinates
+ float texX1 = srcX / (float)image->texWidth;
+ float texY1 = srcY / (float)image->texHeight;
+ float texX2 = (srcX + width) / (float)image->texWidth;
+ float texY2 = (srcY + height) / (float)image->texHeight;
+
+ glColor4f(1.0f, 1.0f, 1.0f, image->alpha);
+ glBindTexture(GL_TEXTURE_2D, image->glimage);
+
+ if (!mTexture) {
+ glEnable(GL_TEXTURE_2D);
+ mTexture = true;
+ };
+
+ // Check if blending already is enabled
+ if (!mAlpha)
+ {
+ glEnable(GL_BLEND);
+ mAlpha = true;
+ }
+
+ // Draw a textured quad -- the image
+ glBegin(GL_QUADS);
+ glTexCoord2f(texX1, texY1);
+ glVertex3i(dstX, dstY, 0);
+
+ glTexCoord2f(texX2, texY1);
+ glVertex3i(dstX + width, dstY, 0);
+
+ glTexCoord2f(texX2, texY2);
+ glVertex3i(dstX + width, dstY + height, 0);
+
+ glTexCoord2f(texX1, texY2);
+ glVertex3i(dstX, dstY + height, 0);
+ glEnd();
+
+ glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
+
+ return true;
+}
+
+void OpenGLGraphics::updateScreen()
+{
+ glFlush();
+ glFinish();
+ SDL_GL_SwapBuffers();
+
+ // Decrement frame counter when using framerate limiting
+ if (framesToDraw > 1) framesToDraw--;
+
+ // Wait while we're not allowed to draw next frame yet
+ while (framesToDraw == 1)
+ {
+ SDL_Delay(10);
+ }
+}
+
+void OpenGLGraphics::_beginDraw()
+{
+ glPushAttrib(
+ GL_COLOR_BUFFER_BIT |
+ GL_CURRENT_BIT |
+ GL_DEPTH_BUFFER_BIT |
+ GL_ENABLE_BIT |
+ GL_FOG_BIT |
+ GL_LIGHTING_BIT |
+ GL_LINE_BIT |
+ GL_POINT_BIT |
+ GL_POLYGON_BIT |
+ GL_SCISSOR_BIT |
+ GL_STENCIL_BUFFER_BIT |
+ GL_TEXTURE_BIT |
+ GL_TRANSFORM_BIT
+ );
+
+ glMatrixMode(GL_MODELVIEW);
+ glPushMatrix();
+ glLoadIdentity();
+
+ glMatrixMode(GL_TEXTURE);
+ glPushMatrix();
+ glLoadIdentity();
+
+ glMatrixMode(GL_PROJECTION);
+ glPushMatrix();
+ glLoadIdentity();
+
+ glOrtho(0.0, (double)mScreen->w, (double)mScreen->h, 0.0, -1.0, 1.0);
+
+ glDisable(GL_LIGHTING);
+ glDisable(GL_CULL_FACE);
+ glDisable(GL_DEPTH_TEST);
+
+ glEnable(GL_SCISSOR_TEST);
+
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+
+ glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
+
+ pushClipArea(gcn::Rectangle(0, 0, mScreen->w, mScreen->h));
+}
+
+void OpenGLGraphics::_endDraw()
+{
+ glMatrixMode(GL_MODELVIEW);
+ glPopMatrix();
+
+ glMatrixMode(GL_TEXTURE);
+ glPopMatrix();
+
+ glMatrixMode(GL_PROJECTION);
+ glPopMatrix();
+
+ glPopAttrib();
+
+ popClipArea();
+}
+
+bool OpenGLGraphics::pushClipArea(gcn::Rectangle area)
+{
+ bool result = gcn::Graphics::pushClipArea(area);
+
+ glScissor(mClipStack.top().x,
+ mScreen->h - mClipStack.top().y - mClipStack.top().height,
+ mClipStack.top().width,
+ mClipStack.top().height);
+
+ return result;
+}
+
+void OpenGLGraphics::popClipArea()
+{
+ gcn::Graphics::popClipArea();
+
+ if (mClipStack.empty())
+ {
+ return;
+ }
+
+ glScissor(mClipStack.top().x,
+ mScreen->h - mClipStack.top().y - mClipStack.top().height,
+ mClipStack.top().width,
+ mClipStack.top().height);
+}
+
+void OpenGLGraphics::setColor(const gcn::Color& color)
+{
+ mColor = color;
+ glColor4f(color.r/255.0,
+ color.g/255.0,
+ color.b/255.0,
+ color.a/255.0);
+
+ mColorAlpha = (color.a != 255);
+}
+
+void OpenGLGraphics::drawImage(const gcn::Image* image, int srcX, int srcY,
+ int dstX, int dstY, int width, int height)
+{
+ dstX += mClipStack.top().xOffset;
+ dstY += mClipStack.top().yOffset;
+
+ // The following code finds the real width and height of the texture.
+ // OpenGL only supports texture sizes that are powers of two
+ int realImageWidth = 1;
+ int realImageHeight = 1;
+ while (realImageWidth < image->getWidth())
+ {
+ realImageWidth *= 2;
+ }
+ while (realImageHeight < image->getHeight())
+ {
+ realImageHeight *= 2;
+ }
+
+ // Find OpenGL texture coordinates
+ float texX1 = srcX / (float)realImageWidth;
+ float texY1 = srcY / (float)realImageHeight;
+ float texX2 = (srcX+width) / (float)realImageWidth;
+ float texY2 = (srcY+height) / (float)realImageHeight;
+
+ // 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, *((GLuint *)(image->_getData())));
+
+ if (!mTexture) {
+ glEnable(GL_TEXTURE_2D);
+ mTexture = true;
+ };
+
+ // Check if blending already is enabled
+ if (!mAlpha)
+ {
+ glEnable(GL_BLEND);
+ mAlpha = true;
+ }
+
+ // Draw a textured quad -- the image
+ glBegin(GL_QUADS);
+ glTexCoord2f(texX1, texY1);
+ glVertex3i(dstX, dstY, 0);
+
+ glTexCoord2f(texX1, texY2);
+ glVertex3i(dstX, dstY + height, 0);
+
+ glTexCoord2f(texX2, texY2);
+ glVertex3i(dstX + width, dstY + height, 0);
+
+ glTexCoord2f(texX2, texY1);
+ glVertex3i(dstX + width, dstY, 0);
+ glEnd();
+}
+
+void OpenGLGraphics::drawPoint(int x, int y)
+{
+ x += mClipStack.top().xOffset;
+ y += mClipStack.top().yOffset;
+
+ if (mAlpha && !mColorAlpha) {
+ glDisable(GL_BLEND);
+ mAlpha = false;
+ }
+
+ glDisable(GL_TEXTURE_2D);
+ mTexture = false;
+
+ glBegin(GL_POINTS);
+ glVertex3i(x, y, 0);
+ glEnd();
+}
+
+void OpenGLGraphics::drawLine(int x1, int y1, int x2, int y2)
+{
+ x1 += mClipStack.top().xOffset;
+ y1 += mClipStack.top().yOffset;
+ x2 += mClipStack.top().xOffset;
+ y2 += mClipStack.top().yOffset;
+
+ if (mAlpha && !mColorAlpha) {
+ glDisable(GL_BLEND);
+ mAlpha = false;
+ }
+
+ glDisable(GL_TEXTURE_2D);
+ mTexture = false;
+
+ glBegin(GL_LINES);
+ glVertex3f(x1+0.5f, y1+0.5f, 0);
+ glVertex3f(x2+0.5f, y2+0.5f, 0);
+ glEnd();
+
+ glBegin(GL_POINTS);
+ glVertex3f(x2+0.5f, y2+0.5f, 0);
+ glEnd();
+}
+
+void OpenGLGraphics::drawRectangle(const gcn::Rectangle& rectangle)
+{
+ if (mAlpha && !mColorAlpha) {
+ glDisable(GL_BLEND);
+ mAlpha = false;
+ }
+
+ glDisable(GL_TEXTURE_2D);
+ mTexture = false;
+
+ glBegin(GL_LINE_LOOP);
+ glVertex3f(rectangle.x + mClipStack.top().xOffset + 0.5f,
+ rectangle.y + mClipStack.top().yOffset + 0.5f, 0);
+ glVertex3f(rectangle.x + rectangle.width - 0.5f + mClipStack.top().xOffset,
+ rectangle.y + mClipStack.top().yOffset + 0.5f, 0);
+ glVertex3f(rectangle.x + rectangle.width - 0.5f + mClipStack.top().xOffset,
+ rectangle.y + rectangle.height + mClipStack.top().yOffset - 0.5f, 0);
+ glVertex3f(rectangle.x + mClipStack.top().xOffset + 0.5f,
+ rectangle.y + rectangle.height + mClipStack.top().yOffset - 0.5f, 0);
+ glEnd();
+}
+
+void OpenGLGraphics::fillRectangle(const gcn::Rectangle& rectangle)
+{
+ if (mAlpha && !mColorAlpha) {
+ glDisable(GL_BLEND);
+ mAlpha = false;
+ }
+
+ glDisable(GL_TEXTURE_2D);
+ mTexture = false;
+
+ glBegin(GL_QUADS);
+ glVertex3i(rectangle.x + mClipStack.top().xOffset,
+ rectangle.y + mClipStack.top().yOffset, 0);
+ glVertex3i(rectangle.x + rectangle.width + mClipStack.top().xOffset,
+ rectangle.y + mClipStack.top().yOffset, 0);
+ glVertex3i(rectangle.x + rectangle.width + mClipStack.top().xOffset,
+ rectangle.y + rectangle.height + mClipStack.top().yOffset, 0);
+ glVertex3i(rectangle.x + mClipStack.top().xOffset,
+ rectangle.y + rectangle.height + mClipStack.top().yOffset, 0);
+ glEnd();
+}
+
+void OpenGLGraphics::setTargetPlane(int width, int height)
+{
+}
+
+#endif // USE_OPENGL
diff --git a/src/openglgraphics.h b/src/openglgraphics.h
new file mode 100644
index 00000000..434999bb
--- /dev/null
+++ b/src/openglgraphics.h
@@ -0,0 +1,68 @@
+/*
+ * 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_OPENGLGRAPHICS_H
+#define _TMW_OPENGLGRAPHICS_H
+
+#include "graphics.h"
+
+class OpenGLGraphics : public Graphics
+{
+ public:
+ OpenGLGraphics();
+
+ ~OpenGLGraphics();
+
+ bool setVideoMode(int w, int h, int bpp, bool fs, bool hwaccel);
+
+ bool drawImage(Image *image, int srcX, int srcY, int dstX, int dstY, int width, int height);
+
+ void updateScreen();
+
+ void _beginDraw();
+ void _endDraw();
+
+ bool pushClipArea(gcn::Rectangle area);
+ void popClipArea();
+
+ 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);
+
+ void drawRectangle(const gcn::Rectangle& rectangle);
+
+ void fillRectangle(const gcn::Rectangle &rectangle);
+
+ void setTargetPlane(int width, int height);
+
+ private:
+ bool mAlpha, mTexture;
+ bool mColorAlpha;
+};
+
+#endif
diff --git a/src/resources/image.h b/src/resources/image.h
index b99ad189..a4a65787 100644
--- a/src/resources/image.h
+++ b/src/resources/image.h
@@ -37,6 +37,9 @@
class Image : public Resource
{
friend class Graphics;
+#ifdef USE_OPENGL
+ friend class OpenGLGraphics;
+#endif
public:
/**