summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBjørn Lindeijer <bjorn@lindeijer.nl>2005-02-14 15:13:54 +0000
committerBjørn Lindeijer <bjorn@lindeijer.nl>2005-02-14 15:13:54 +0000
commit4f6c1dad35e575588b73524692d973dec06447c3 (patch)
treed052c3c7db66450888af132ac9dcefb7c28b58a6
parentebccde5d779f25584386ddc0c4bdc6331877bcc6 (diff)
downloadmana-4f6c1dad35e575588b73524692d973dec06447c3.tar.gz
mana-4f6c1dad35e575588b73524692d973dec06447c3.tar.bz2
mana-4f6c1dad35e575588b73524692d973dec06447c3.tar.xz
mana-4f6c1dad35e575588b73524692d973dec06447c3.zip
Support for drawing using OpenGL. Don't expect it to be fast yet though.
-rw-r--r--src/Makefile.am4
-rw-r--r--src/graphic/graphic.cpp30
-rw-r--r--src/graphic/graphic.h7
-rw-r--r--src/gui/char_select.cpp9
-rw-r--r--src/gui/char_server.cpp12
-rw-r--r--src/gui/gui.cpp15
-rw-r--r--src/gui/gui.h3
-rw-r--r--src/gui/login.cpp5
-rw-r--r--src/gui/progressbar.cpp6
-rw-r--r--src/main.cpp8
-rw-r--r--src/resources/image.cpp332
-rw-r--r--src/resources/image.h45
12 files changed, 388 insertions, 88 deletions
diff --git a/src/Makefile.am b/src/Makefile.am
index bcf9ff6b..b4c4ad97 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -102,7 +102,7 @@ tmw_SOURCES = graphic/graphic.cpp \
INCLUDES= $(all_includes)
# the library search path.
-tmw_LDFLAGS = $(all_libraries) $(LIBSDL_RPATH) -lguichan -lguichan_sdl `pkg-config --libs libxml-2.0`
+tmw_LDFLAGS = $(all_libraries) $(LIBSDL_RPATH) -lguichan_sdl -lguichan `pkg-config --libs libxml-2.0`
tmw_CXXFLAGS = $(LIBSDL_CFLAGS) `pkg-config --cflags libxml-2.0`
-tmw_LDADD = $(LIBSDL_LIBS)
+tmw_LDADD = $(LIBSDL_LIBS) -lguichan_opengl -lguichan -lGL
tmw_TARGET = ../tmw
diff --git a/src/graphic/graphic.cpp b/src/graphic/graphic.cpp
index 25d6e0a5..29bf3596 100644
--- a/src/graphic/graphic.cpp
+++ b/src/graphic/graphic.cpp
@@ -29,6 +29,9 @@
#include "../gui/equipment.h"
#include "../main.h"
#include "../being.h"
+#ifdef USE_OPENGL
+#include <SDL_opengl.h>
+#endif
SDL_Surface *screen;
@@ -153,8 +156,13 @@ int get_y_offset(Being *being) {
Graphics::Graphics():
mouseCursor(NULL)
{
+#ifdef USE_OPENGL
+ setTargetPlane(800, 600);
+#else
setTarget(SDL_GetVideoSurface());
+#endif
+#ifndef USE_OPENGL
// Load the mouse cursor
ResourceManager *resman = ResourceManager::getInstance();
mouseCursor = resman->getImage("core/graphics/gui/mouse.png", IMG_ALPHA);
@@ -164,6 +172,7 @@ Graphics::Graphics():
// Hide the system mouse cursor
SDL_ShowCursor(SDL_DISABLE);
+#endif
}
Graphics::~Graphics() {
@@ -221,12 +230,19 @@ void Graphics::drawImageRect(
void Graphics::updateScreen()
{
+#ifdef USE_OPENGL
+ glFlush();
+ glFinish();
+ SDL_GL_SwapBuffers();
+ glClear(GL_COLOR_BUFFER_BIT);
+#else
// Draw mouse before flipping
int mouseX, mouseY;
SDL_GetMouseState(&mouseX, &mouseY);
mouseCursor->draw(screen, mouseX - 5, mouseY - 2);
SDL_Flip(screen);
+#endif
}
@@ -340,14 +356,14 @@ Engine::~Engine()
void Engine::draw()
{
+ guiGraphics->_beginDraw();
+
// Get the current mouse position
int mouseX, mouseY;
SDL_GetMouseState(&mouseX, &mouseY);
- map_x = (player_node->x - 13) * 32 +
- get_x_offset(player_node);
- map_y = (player_node->y - 9) * 32 +
- get_y_offset(player_node);
+ map_x = (player_node->x - 13) * 32 + get_x_offset(player_node);
+ map_y = (player_node->y - 9) * 32 + get_y_offset(player_node);
camera_x = map_x >> 5;
camera_y = map_y >> 5;
@@ -528,10 +544,8 @@ void Engine::draw()
std::stringstream cost;
cost << tile->Gcost;
- guiGraphics->_beginDraw();
guiGraphics->drawText(cost.str(), destRect.x + 4, destRect.y + 12,
gcn::Graphics::CENTER);
- guiGraphics->_endDraw();
// Move to the next node
PATH_NODE *temp = debugPath->next;
@@ -546,7 +560,6 @@ void Engine::draw()
Being *being = (*beingIterator);
if (being->speech != NULL) {
- guiGraphics->_beginDraw();
//if (being->speech_color == makecol(255, 255, 255)) {
// guiGraphics->drawText(being->speech,
// being->text_x + 16, being->text_y - 60,
@@ -557,7 +570,6 @@ void Engine::draw()
being->text_x + 60, being->text_y - 60,
gcn::Graphics::CENTER);
//}
- guiGraphics->_endDraw();
being->speech_time--;
if (being->speech_time == 0) {
@@ -583,4 +595,6 @@ void Engine::draw()
(mouseX / 32 + camera_x) << ", " << (mouseY / 32 + camera_y);
debugInfo->setCaption(debugStream.str());
debugInfo->adjustSize();
+
+ guiGraphics->_endDraw();
}
diff --git a/src/graphic/graphic.h b/src/graphic/graphic.h
index 3e4bc168..126cfcb4 100644
--- a/src/graphic/graphic.h
+++ b/src/graphic/graphic.h
@@ -47,6 +47,9 @@ class Graphics;
#include "spriteset.h"
#include <SDL.h>
#include <guichan/sdl.hpp>
+#ifdef USE_OPENGL
+#include <guichan/opengl.hpp>
+#endif
#define TILE_SIZE 32
@@ -115,7 +118,11 @@ struct ImageRect {
/**
* A central point of control for graphics.
*/
+#ifdef USE_OPENGL
+class Graphics : public gcn::OpenGLGraphics {
+#else
class Graphics : public gcn::SDLGraphics {
+#endif
public:
/**
* Constructor.
diff --git a/src/gui/char_select.cpp b/src/gui/char_select.cpp
index 9cf20f94..24fa9c86 100644
--- a/src/gui/char_select.cpp
+++ b/src/gui/char_select.cpp
@@ -450,13 +450,12 @@ void charSelect()
sel->setPlayerInfo(char_info);
}
- // Draw background
- login_wallpaper->draw(screen, 0, 0);
-
gui->logic();
- gui->draw();
- // Draw to screen
+ guiGraphics->_beginDraw();
+ login_wallpaper->draw(screen, 0, 0);
+ gui->draw();
+ guiGraphics->_endDraw();
guiGraphics->updateScreen();
}
diff --git a/src/gui/char_server.cpp b/src/gui/char_server.cpp
index a0988b5a..6cc45f3d 100644
--- a/src/gui/char_server.cpp
+++ b/src/gui/char_server.cpp
@@ -126,14 +126,24 @@ void char_server() {
case SDL_QUIT:
state = EXIT;
break;
+
+ case SDL_KEYDOWN:
+ if (event.key.keysym.sym == SDLK_ESCAPE)
+ {
+ showServerList = false;
+ }
+ break;
}
guiInput->pushInput(event);
}
- login_wallpaper->draw(screen, 0, 0);
gui->logic();
+
+ guiGraphics->_beginDraw();
+ login_wallpaper->draw(screen, 0, 0);
gui->draw();
+ guiGraphics->_endDraw();
guiGraphics->updateScreen();
}
diff --git a/src/gui/gui.cpp b/src/gui/gui.cpp
index b64f6a98..6cc05910 100644
--- a/src/gui/gui.cpp
+++ b/src/gui/gui.cpp
@@ -41,7 +41,12 @@ Gui::Gui(Graphics *graphics):
guiInput = new gcn::SDLInput();
// Set image loader
+#ifndef USE_OPENGL
imageLoader = new gcn::SDLImageLoader();
+#else
+ hostImageLoader = new gcn::SDLImageLoader();
+ imageLoader = new gcn::OpenGLImageLoader(hostImageLoader);
+#endif
gcn::Image::setImageLoader(imageLoader);
// Initialize top GUI widget
@@ -67,6 +72,9 @@ Gui::~Gui()
delete guiFont;
delete guiTop;
delete imageLoader;
+#ifdef USE_OPENGL
+ delete hostImageLoader;
+#endif
delete guiInput;
delete focusHandler;
}
@@ -148,16 +156,13 @@ void Gui::logic()
void Gui::draw()
{
- guiGraphics->_beginDraw();
+ //guiGraphics->_beginDraw();
guiGraphics->pushClipArea(guiTop->getDimension());
guiTop->draw(guiGraphics);
guiGraphics->popClipArea();
- // Draw the mouse
- //draw_sprite(buffer, mouse_sprite, mouse_x, mouse_y);
-
- guiGraphics->_endDraw();
+ //guiGraphics->_endDraw();
}
void Gui::focusNone()
diff --git a/src/gui/gui.h b/src/gui/gui.h
index cd37ae63..597cdb5c 100644
--- a/src/gui/gui.h
+++ b/src/gui/gui.h
@@ -75,6 +75,9 @@ class Gui
private:
gcn::Gui *gui; /**< The GUI system */
+#ifdef USE_OPENGL
+ gcn::ImageLoader *hostImageLoader; /**< For loading images in GL */
+#endif
gcn::ImageLoader *imageLoader; /**< For loading images */
gcn::ImageFont *guiFont; /**< The global GUI font */
diff --git a/src/gui/login.cpp b/src/gui/login.cpp
index 3c58cde9..5621f5b2 100644
--- a/src/gui/login.cpp
+++ b/src/gui/login.cpp
@@ -152,9 +152,12 @@ void login() {
guiInput->pushInput(event);
}
- login_wallpaper->draw(screen, 0, 0);
gui->logic();
+
+ guiGraphics->_beginDraw();
+ login_wallpaper->draw(screen, 0, 0);
gui->draw();
+ guiGraphics->_endDraw();
guiGraphics->updateScreen();
}
diff --git a/src/gui/progressbar.cpp b/src/gui/progressbar.cpp
index 09e05932..cc12c247 100644
--- a/src/gui/progressbar.cpp
+++ b/src/gui/progressbar.cpp
@@ -42,6 +42,7 @@ ProgressBar::ProgressBar(float progress, int x, int y, int width, unsigned char
void ProgressBar::draw(gcn::Graphics *graphics)
{
+#ifndef USE_OPENGL
int absx, absy;
getAbsolutePosition(absx, absy);
@@ -73,9 +74,10 @@ void ProgressBar::draw(gcn::Graphics *graphics)
Temp = absx+X+int(float(Width)*progress)-2;
if ( Temp < (absx+X+PROGRESSBAR_HEIGHT+1) ) Temp = absx+X+PROGRESSBAR_HEIGHT;
DrawLine(screen, absx+X+PROGRESSBAR_HEIGHT+1, absy+Y+1, Temp, absy+Y+1, abs(Red-40), abs(Green-40), abs(Blue-40));
- DrawLine(screen, absx+X+PROGRESSBAR_HEIGHT, absy+Y+1, absx+X+2, absy+Y+PROGRESSBAR_HEIGHT-1, abs(Red-40), abs(Green-40), abs(Blue-40));
-
+ DrawLine(screen, absx+X+PROGRESSBAR_HEIGHT, absy+Y+1, absx+X+2, absy+Y+PROGRESSBAR_HEIGHT-1, abs(Red-40), abs(Green-40), abs(Blue-40));
+
SDL_UnlockSurface(screen);
+#endif
}
void ProgressBar::setProgress(float progress)
diff --git a/src/main.cpp b/src/main.cpp
index 805bb7f6..043be40d 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -35,6 +35,10 @@
#include <SDL.h>
#include <libxml/xmlversion.h>
+#ifdef USE_OPENGL
+#include <SDL_opengl.h>
+#endif
+
#ifdef __USE_UNIX98
#include <sys/stat.h>
#include <pwd.h>
@@ -224,6 +228,10 @@ void init_engine()
// Setup OpenGL
glViewport(0, 0, 800, 600);
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
+ int gotDoubleBuffer;
+ SDL_GL_GetAttribute(SDL_GL_DOUBLEBUFFER, &gotDoubleBuffer);
+ log("OpenGL is %s double buffering.",
+ (gotDoubleBuffer ? "using" : "not using"));
#endif
const SDL_VideoInfo *vi = SDL_GetVideoInfo();
diff --git a/src/resources/image.cpp b/src/resources/image.cpp
index da0be097..5d818e0e 100644
--- a/src/resources/image.cpp
+++ b/src/resources/image.cpp
@@ -28,8 +28,17 @@
#include "../graphic/graphic.h"
#include "resourcemanager.h"
+#ifndef USE_OPENGL
Image::Image(SDL_Surface *image):
image(image)
+#else
+Image::Image(GLuint image, int width, int height, int texWidth, int texHeight):
+ image(image),
+ width(width),
+ height(height),
+ texWidth(texWidth),
+ texHeight(texHeight)
+#endif
{
}
@@ -44,67 +53,200 @@ Image* Image::load(const std::string &filePath, int flags)
// Attempt to use SDL_Image to load the file.
SDL_Surface *tmpImage = IMG_Load(filePath.c_str());
- SDL_SetColorKey(tmpImage, SDL_SRCCOLORKEY | SDL_RLEACCEL,
- SDL_MapRGB(tmpImage->format, 255, 0, 255));
- SDL_Surface *image = NULL;
+
+ // Check if the file was opened and return the appropriate value.
+ if (!tmpImage) {
+ log("Error: Image load failed.");
+ return NULL;
+ }
+
+#ifndef USE_OPENGL
+
+ SDL_Surface *image;
if (flags & IMG_ALPHA) {
image = SDL_DisplayFormatAlpha(tmpImage);
}
else {
+ SDL_SetColorKey(tmpImage, SDL_SRCCOLORKEY | SDL_RLEACCEL,
+ SDL_MapRGB(tmpImage->format, 255, 0, 255));
image = SDL_DisplayFormat(tmpImage);
}
SDL_FreeSurface(tmpImage);
// Check if the file was opened and return the appropriate value.
if (!image) {
- log("Error: Image load failed: %s", IMG_GetError());
- //log("Error: Image load failed: %s", filePath.c_str());
+ log("Error: Image convert failed.");
return NULL;
}
return new Image(image);
+
+#else
+
+ 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 *formatImage = SDL_CreateRGBSurface(SDL_SWSURFACE, 0, 0, 32,
+ rmask, gmask, bmask, amask);
+
+ if (formatImage == NULL) {
+ log("Error", "Image load failed: not enough memory");
+ }
+
+ SDL_Surface *image = SDL_ConvertSurface(
+ tmpImage, formatImage->format, SDL_SWSURFACE);
+ SDL_FreeSurface(formatImage);
+ SDL_FreeSurface(tmpImage);
+
+ unsigned int *rawData = (unsigned int *)image->pixels;
+ int width = image->w;
+ int height = image->h;
+ int realWidth = 1, realHeight = 1;
+
+ while (realWidth < width && realWidth < 1024) {
+ realWidth *= 2;
+ }
+
+ while (realHeight < height && realHeight < 1024) {
+ realHeight *= 2;
+ }
+
+ unsigned int *realData = new unsigned int[realWidth * realHeight];
+ int x, y;
+
+ for (y = 0; y < realHeight; y++)
+ {
+ for (x = 0; x < realWidth; x++)
+ {
+ if (x < width && y < height)
+ {
+ if (rawData[x + y * width] == 0xffff00ff)
+ {
+ realData[x + y * realWidth] = 0x00000000;
+ }
+ else
+ {
+ realData[x + y * realWidth] = rawData[x + y * width];
+ }
+ }
+ else
+ {
+ realData[x + y * realWidth] = 0;
+ }
+ }
+ }
+
+ GLuint texture;
+ glGenTextures(1, &texture);
+ log("Binding texture %d (%dx%d)", texture, realWidth, realHeight);
+ glBindTexture(GL_TEXTURE_2D, texture);
+ glTexImage2D(
+ GL_TEXTURE_2D, 0, 4,
+ realWidth, realHeight,
+ 0, GL_RGBA, GL_UNSIGNED_BYTE,
+ realData);
+
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+
+ delete[] realData;
+ SDL_FreeSurface(image);
+
+ GLenum error = glGetError();
+ if (error)
+ {
+ std::string errmsg = "Unkown error";
+ switch (error)
+ {
+ case GL_INVALID_ENUM:
+ errmsg = "GL_INVALID_ENUM";
+ break;
+ case GL_INVALID_VALUE:
+ errmsg = "GL_INVALID_VALUE";
+ break;
+ case GL_INVALID_OPERATION:
+ errmsg = "GL_INVALID_OPERATION";
+ break;
+ case GL_STACK_OVERFLOW:
+ errmsg = "GL_STACK_OVERFLOW";
+ break;
+ case GL_STACK_UNDERFLOW:
+ errmsg = "GL_STACK_UNDERFLOW";
+ break;
+ case GL_OUT_OF_MEMORY:
+ errmsg = "GL_OUT_OF_MEMORY";
+ break;
+ }
+ log("Error: Image GL import failed: %s", errmsg.c_str());
+ return NULL;
+ }
+
+ return new Image(texture, width, height, realWidth, realHeight);
+
+#endif
}
void Image::unload()
{
// Free the image surface.
+#ifndef USE_OPENGL
if (image != NULL) {
SDL_FreeSurface(image);
image = NULL;
loaded = false;
}
+#endif
+ loaded = false;
}
int Image::getWidth() const
{
+#ifndef USE_OPENGL
if (image != NULL) {
return image->w;
}
+#else
+ return width;
+#endif
return 0;
}
int Image::getHeight() const
{
+#ifndef USE_OPENGL
if (image != NULL) {
return image->h;
}
+#else
+ return height;
+#endif
return 0;
}
Image *Image::getSubImage(int x, int y, int width, int height)
{
// Create a new clipped sub-image
+#ifdef USE_OPENGL
+ return new SubImage(this, image, x, y, width, height, texWidth, texHeight);
+#else
return new SubImage(this, image, x, y, width, height);
-}
-
-Image *Image::getScaledInstance(int width, int height)
-{
- return new ScaledImage(this, image, width, height);
+#endif
}
bool Image::draw(SDL_Surface *screen, int srcX, int srcY, int dstX, int dstY,
int width, int height)
{
+#ifndef USE_OPENGL
// Check that preconditions for blitting are met.
if (screen == NULL || image == NULL) return false;
@@ -119,11 +261,45 @@ bool Image::draw(SDL_Surface *screen, int srcX, int srcY, int dstX, int dstY,
return false;
}
+#else
+
+ // Find OpenGL texture coordinates
+ float texX1 = srcX / (float)texWidth;
+ float texY1 = srcY / (float)texHeight;
+ float texX2 = (srcX + width) / (float)texWidth;
+ float texY2 = (srcY + height) / (float)texHeight;
+
+ glBindTexture(GL_TEXTURE_2D, image);
+
+ 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);
+
+#endif
return true;
}
bool Image::draw(SDL_Surface *screen, int x, int y)
{
+#ifndef USE_OPENGL
+
// Check that preconditions for blitting are met.
if (screen == NULL || image == NULL) return false;
@@ -135,6 +311,38 @@ bool Image::draw(SDL_Surface *screen, int x, int y)
return false;
}
+#else
+
+ // Find OpenGL texture coordinates
+ float texX1 = 0.0f;
+ float texY1 = 0.0f;
+ float texX2 = width / (float)texWidth;
+ float texY2 = height / (float)texHeight;
+
+ glBindTexture(GL_TEXTURE_2D, image);
+
+ glEnable(GL_TEXTURE_2D);
+ glEnable(GL_BLEND);
+
+ // Draw a textured quad -- the image
+ glBegin(GL_QUADS);
+ glTexCoord2f(texX1, texY1);
+ glVertex3i(x, y, 0);
+
+ glTexCoord2f(texX2, texY1);
+ glVertex3i(x + width, y, 0);
+
+ glTexCoord2f(texX2, texY2);
+ glVertex3i(x + width, y + height, 0);
+
+ glTexCoord2f(texX1, texY2);
+ glVertex3i(x, y + height, 0);
+ glEnd();
+
+ glDisable(GL_TEXTURE_2D);
+ glDisable(GL_BLEND);
+
+#endif
return true;
}
@@ -161,9 +369,15 @@ void Image::drawPattern(SDL_Surface *screen, int x, int y, int w, int h)
//============================================================================
+#ifndef USE_OPENGL
SubImage::SubImage(Image *parent, SDL_Surface *image,
int x, int y, int width, int height):
Image(image),
+#else
+SubImage::SubImage(Image *parent, GLuint image,
+ int x, int y, int width, int height, int texWidth, int texHeight):
+ Image(image, width, height, texWidth, texHeight),
+#endif
parent(parent)
{
parent->incRef();
@@ -177,7 +391,9 @@ SubImage::SubImage(Image *parent, SDL_Surface *image,
SubImage::~SubImage()
{
+#ifndef USE_OPENGL
image = NULL;
+#endif
// TODO: Enable when no longer a problem
//parent->decRef();
}
@@ -200,6 +416,7 @@ Image *SubImage::getSubImage(int x, int y, int w, int h)
bool SubImage::draw(SDL_Surface *screen, int srcX, int srcY,
int dstX, int dstY, int width, int height)
{
+#ifndef USE_OPENGL
// Check that preconditions for blitting are met.
if (screen == NULL || image == NULL) return false;
@@ -215,11 +432,44 @@ bool SubImage::draw(SDL_Surface *screen, int srcX, int srcY,
return false;
}
+#else
+
+ // Find OpenGL texture coordinates
+ float texX1 = (rect.x + srcX) / (float)texWidth;
+ float texY1 = (rect.y + srcY) / (float)texHeight;
+ float texX2 = (rect.x + srcX + width) / (float)texWidth;
+ float texY2 = (rect.y + srcY + height) / (float)texHeight;
+
+ glBindTexture(GL_TEXTURE_2D, image);
+
+ 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);
+
+#endif
return true;
}
bool SubImage::draw(SDL_Surface *screen, int x, int y)
{
+#ifndef USE_OPENGL
// Check that drawing preconditions are satisfied.
if (screen == NULL || image == NULL) return false;
@@ -232,37 +482,39 @@ bool SubImage::draw(SDL_Surface *screen, int x, int y)
return false;
}
- return true;
-}
+#else
-//============================================================================
+ // Find OpenGL texture coordinates
+ float texX1 = rect.x / (float)texWidth;
+ float texY1 = rect.y / (float)texHeight;
+ float texX2 = (rect.x + rect.w) / (float)texWidth;
+ float texY2 = (rect.y + rect.h) / (float)texHeight;
-ScaledImage::ScaledImage(
- Image *parent, SDL_Surface *bmp, int width, int height):
- Image(SDL_CreateRGBSurface(SDL_SWSURFACE, width, height, 32,
-#if SDL_BYTEORDER == SDL_BIG_ENDIAN
- 0xff000000,
- 0x00ff0000,
- 0x0000ff00,
- 0x000000ff
-#else
- 0x000000ff,
- 0x0000ff00,
- 0x00ff0000,
- 0xff000000
-#endif
- ))
-{
- if (image) {
- // Somehow stretch the image using SDL_gfx
- //stretch_blit(bmp, image, 0, 0, bmp->w, bmp->h, 0, 0, width, height);
- }
-}
+ glBindTexture(GL_TEXTURE_2D, image);
-ScaledImage::~ScaledImage()
-{
- if (image) {
- SDL_FreeSurface(image);
- image = NULL;
- }
+ glEnable(GL_TEXTURE_2D);
+ glEnable(GL_BLEND);
+
+ // Draw a textured quad -- the image
+ glBegin(GL_QUADS);
+
+ glTexCoord2f(texX1, texY1);
+ glVertex3i(x, y, 0);
+
+ glTexCoord2f(texX2, texY1);
+ glVertex3i(x + rect.w, y, 0);
+
+ glTexCoord2f(texX2, texY2);
+ glVertex3i(x + rect.w, y + rect.h, 0);
+
+ glTexCoord2f(texX1, texY2);
+ glVertex3i(x, y + rect.h, 0);
+
+ glEnd();
+
+ glDisable(GL_TEXTURE_2D);
+ glDisable(GL_BLEND);
+
+#endif
+ return true;
}
diff --git a/src/resources/image.h b/src/resources/image.h
index bed75983..09a0fc7e 100644
--- a/src/resources/image.h
+++ b/src/resources/image.h
@@ -27,6 +27,10 @@
#include "resource.h"
#include <SDL.h>
+#ifdef USE_OPENGL
+#include <SDL_opengl.h>
+#endif
+
// This flag causes image alpha channel to be preserved, otherwise masking is
// used.
#define IMG_ALPHA 1
@@ -45,7 +49,13 @@ class Image : public Resource
/**
* Constructor.
*/
+#ifdef USE_OPENGL
+ Image(GLuint image,
+ int width, int height,
+ int texWidth, int texHeight);
+#else
Image(SDL_Surface *image);
+#endif
/**
* Destructor.
@@ -83,11 +93,6 @@ class Image : public Resource
virtual Image* getSubImage(int x, int y, int width, int height);
/**
- * Creates a scaled version of this image.
- */
- virtual Image* getScaledInstance(int width, int height);
-
- /**
* Blits the image onto the screen.
*
* @return <code>true</code> if the image was blitted properly
@@ -113,8 +118,13 @@ class Image : public Resource
SDL_Surface *screen, int x, int y, int w, int h);
protected:
+#ifdef USE_OPENGL
+ GLuint image;
+ int width, height;
+ int texWidth, texHeight;
+#else
SDL_Surface *image;
- //BITMAP *image;
+#endif
};
/**
@@ -127,8 +137,13 @@ class SubImage : public Image
* Constructor.
*/
//SubImage(SDL_Surface *timage, int x, int y, int width, int height);
+#ifndef USE_OPENGL
SubImage(Image *parent, SDL_Surface *image,
int x, int y, int width, int height);
+#else
+ SubImage(Image *parent, GLuint image, int x, int y,
+ int width, int height, int texWidth, int textHeight);
+#endif
/**
* Destructor.
@@ -168,24 +183,6 @@ class SubImage : public Image
private:
Image *parent;
SDL_Rect rect;
- //BITMAP *image;
-};
-
-/**
- * A scaled version of an image.
- */
-class ScaledImage : public Image
-{
- public:
- /**
- * Constructor.
- */
- ScaledImage(Image *parent, SDL_Surface *image, int width, int height);
-
- /**
- * Destructor.
- */
- ~ScaledImage();
};
#endif