(spawnpoint (name "main") (x 64) (y 11040))
(background
- (top_color 0 0 50)
- (bottom_color 0 0 150)
+ (top_color 0 0 0.2)
+ (bottom_color 0 0 0.6)
(speed 1.000000)
)
(particles-clouds
)
(background
- (top_color 0 0 50)
- (bottom_color 0 0 150)
+ (top_color 0 0 0.2)
+ (bottom_color 0 0 0.6)
(speed 1.000000)
)
(particles-clouds
(bonusblock (x 672) (y 1056)
(contents "custom")
(powerup
- (sprite "red-potion")
+ (sprite "images/powerups/potions/red-potion.sprite")
(script "levelflip();")
)
)
(powerup (x 8608) (y 1024)
- (sprite "red-potion")
+ (sprite "images/powerups/potions/red-potion.sprite")
(script "levelflip();")
)
(powerup (x 9952) (y 416)
- (sprite "red-potion")
+ (sprite "images/powerups/potions/red-potion.sprite")
(script "levelflip();")
)
(powerup (x 8000) (y 352)
if(state == STATE_INIT || state == STATE_INACTIVE)
return;
if(state == STATE_FALLING) {
- uint32_t old_effect = context.get_drawing_effect();
- context.set_drawing_effect(old_effect | VERTICAL_FLIP);
+ DrawingEffect old_effect = context.get_drawing_effect();
+ context.set_drawing_effect((DrawingEffect) (old_effect | VERTICAL_FLIP));
sprite->draw(context, get_pos(), LAYER_OBJECTS);
context.set_drawing_effect(old_effect);
} else {
}
}
if(tilemap->get_drawing_effect() != 0) {
- tilemap->set_drawing_effect(0);
+ tilemap->set_drawing_effect(NO_EFFECT);
} else {
tilemap->set_drawing_effect(VERTICAL_FLIP);
}
-((pause_menu_frame * i)%SCREEN_WIDTH)
,(i*20+pause_menu_frame)%SCREEN_HEIGHT),
Vector(SCREEN_WIDTH,10),
- Color(20,20,20, rand() % 20 + 1), LAYER_FOREGROUND1+1);
+ Color(0.1, 0.1, 0.1, static_cast<float>(rand() % 20 + 1) / 255.0),
+ LAYER_FOREGROUND1+1);
}
context->draw_filled_rect(
Vector(0,0), Vector(SCREEN_WIDTH, SCREEN_HEIGHT),
- Color(rand() % 50, rand() % 50, rand() % 50, 128), LAYER_FOREGROUND1);
+ Color(
+ static_cast<float>(rand() % 50) / 255.0,
+ static_cast<float>(rand() % 50) / 255.0,
+ static_cast<float>(rand() % 50) / 255.0,
+ 0.5), LAYER_FOREGROUND1);
#if 0
context->draw_text(blue_text, _("PAUSE - Press 'P' To Play"),
Vector(SCREEN_WIDTH/2, 230), CENTER_ALLIGN, LAYER_FOREGROUND1+2);
: binding(binding_)
{
image = image_;
- size = Vector(image->w, image->h);
+ size = Vector(image->get_width(), image->get_height());
id = 0;
info = info_;
}
}
if(background == NULL)
- context.draw_gradient(Color(200,240,220), Color(200,200,220), LAYER_BACKGROUND0);
+ context.draw_gradient(Color(0.8, 0.95, 0.85), Color(0.8, 0.8, 0.8),
+ LAYER_BACKGROUND0);
else
context.draw_surface(background, Vector(0,0), LAYER_BACKGROUND0);
int y = y_pos - 12 - effect_offset;
/* Draw a horizontal line with a little 3d effect */
context.draw_filled_rect(Vector(x, y + 6),
- Vector(menu_width, 4), Color(150,200,255,225), LAYER_GUI);
+ Vector(menu_width, 4),
+ Color(0.6f, 0.7f, 1.0f, 1.0f), LAYER_GUI);
context.draw_filled_rect(Vector(x, y + 6),
- Vector(menu_width, 2), Color(255,255,255,255), LAYER_GUI);
+ Vector(menu_width, 2),
+ Color(1.0f, 1.0f, 1.0f, 1.0f), LAYER_GUI);
break;
}
case MN_LABEL:
context.draw_filled_rect(
Vector(input_pos - 5, y_pos - 10),
Vector(input_width + 10, 20),
- Color(255,255,255,255), LAYER_GUI-5);
+ Color(1.0f, 1.0f, 1.0f, 1.0f), LAYER_GUI-5);
context.draw_filled_rect(
Vector(input_pos - 4, y_pos - 9),
Vector(input_width + 8, 18),
- Color(0,0,0,128), LAYER_GUI-4);
+ Color(0, 0, 0, 0.5f), LAYER_GUI-4);
if(pitem.kind == MN_TEXTFIELD || pitem.kind == MN_NUMFIELD)
{
context.draw_filled_rect(
Vector(x_pos - list_pos + text_pos - 1, y_pos - 10),
Vector(list_pos_2 + 2, 20),
- Color(255,255,255,255), LAYER_GUI - 4);
+ Color(1.0f, 1.0f, 1.0f, 1.0f), LAYER_GUI - 4);
context.draw_filled_rect(
Vector(x_pos - list_pos + text_pos, y_pos - 9),
Vector(list_pos_2, 18),
- Color(0,0,0,128), LAYER_GUI - 5);
+ Color(0, 0, 0, 0.5f), LAYER_GUI - 5);
context.draw_text(text_font, pitem.list[pitem.selected],
Vector(SCREEN_WIDTH/2 + text_pos, y_pos - int(text_font->get_height()/2)),
context.draw_filled_rect(
Vector(pos_x - menu_width/2, pos_y - 24*items.size()/2 - 10),
Vector(menu_width,menu_height + 20),
- Color(150,180,200,125), LAYER_GUI-10);
+ Color(0.6f, 0.7f, 0.8f, 0.5f), LAYER_GUI-10);
for(unsigned int i = 0; i < items.size(); ++i)
{
MouseCursor::MouseCursor(std::string cursor_file) : mid_x(0), mid_y(0)
{
- cursor = new Surface(cursor_file, true);
+ cursor = new Surface(cursor_file);
cur_state = MC_NORMAL;
x = int(x * float(SCREEN_WIDTH)/screen->w);
y = int(y * float(SCREEN_HEIGHT)/screen->h);
- w = cursor->w;
- h = cursor->h / MC_STATES_NB;
+ w = (int) cursor->get_width();
+ h = (int) (cursor->get_height() / MC_STATES_NB);
if(ispressed &SDL_BUTTON(1) || ispressed &SDL_BUTTON(2)) {
if(cur_state != MC_CLICK) {
state_before_click = cur_state;
MC_HIDE
};
+class DrawingContext;
+
/// Mouse cursor.
/** Used to create mouse cursors.
The mouse cursors can be animated
}
void
+Writer::write_float_vector(const std::string& name,
+ const std::vector<float>& value)
+{
+ indent();
+ *out << '(' << name;
+ for(std::vector<float>::const_iterator i = value.begin(); i != value.end(); ++i)
+ *out << " " << *i;
+ *out << ")\n";
+}
+
+void
Writer::indent()
{
for(int i = 0; i<indent_depth; ++i)
void write_bool(const std::string& name, bool value);
void write_int_vector(const std::string& name, const std::vector<int>& value);
void write_int_vector(const std::string& name, const std::vector<unsigned int>& value);
+ void write_float_vector(const std::string& name, const std::vector<float>& value);
// add more write-functions when needed...
void end_list(const std::string& listname);
#include "gettext.hpp"
#include "audio/sound_manager.hpp"
#include "video/surface.hpp"
+#include "video/texture_manager.hpp"
#include "control/joystickkeyboardcontroller.hpp"
#include "misc.hpp"
#include "title.hpp"
void init_video()
{
+ if(texture_manager != NULL)
+ texture_manager->save_textures();
+
SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 5);
SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 5);
// setup opengl state and transform
glDisable(GL_DEPTH_TEST);
glDisable(GL_CULL_FACE);
+ glEnable(GL_TEXTURE_2D);
+ glEnable(GL_BLEND);
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glViewport(0, 0, screen->w, screen->h);
glMatrixMode(GL_PROJECTION);
check_gl_error();
- Surface::reload_all();
+ if(texture_manager != NULL)
+ texture_manager->reload_textures();
+ else
+ texture_manager = new TextureManager();
}
static void init_audio()
free_menu();
unload_shared();
-#ifdef DEBUG
- Surface::debug_check();
-#endif
quit_audio();
if(config)
config->save();
delete config;
delete main_controller;
+ delete texture_manager;
SDL_Quit();
PHYSFS_deinit();
#include <math.h>
#include <stdexcept>
+#include <iostream>
#include "ambient_sound.hpp"
#include "object_factory.hpp"
&& reader.get("speed", speed)) {
set_image(imagefile, speed);
} else {
- std::vector <unsigned int> bkgd_top_color, bkgd_bottom_color;
+ std::vector<float> bkgd_top_color, bkgd_bottom_color;
if(reader.get_vector("top_color", bkgd_top_color) &&
reader.get_vector("bottom_color", bkgd_bottom_color))
- set_gradient(Color(bkgd_top_color), Color(bkgd_bottom_color));
+ set_gradient(Color(bkgd_top_color),
+ Color(bkgd_bottom_color));
}
}
writer.write_string("image", imagefile);
writer.write_float("speed", speed);
} else if(type == GRADIENT) {
- std::vector <unsigned int> bkgd_top_color, bkgd_bottom_color;
+ std::vector<float> bkgd_top_color, bkgd_bottom_color;
bkgd_top_color.push_back(gradient_top.red);
bkgd_top_color.push_back(gradient_top.green);
bkgd_top_color.push_back(gradient_top.blue);
bkgd_bottom_color.push_back(gradient_top.red);
bkgd_bottom_color.push_back(gradient_top.green);
bkgd_bottom_color.push_back(gradient_top.blue);
- writer.write_int_vector("top_color", bkgd_top_color);
- writer.write_int_vector("bottom_color", bkgd_bottom_color);
+ writer.write_float_vector("top_color", bkgd_top_color);
+ writer.write_float_vector("bottom_color", bkgd_bottom_color);
}
writer.write_int("layer", layer);
this->speed = speed;
delete image;
- image = new Surface("images/background/" + name, false);
+ image = new Surface("images/background/" + name);
}
void
gradient_bottom = bottom;
delete image;
- image = new Surface(top, bottom, SCREEN_WIDTH, SCREEN_HEIGHT);
+ image = NULL;
}
void
if(type == GRADIENT) {
context.push_transform();
context.set_translation(Vector(0, 0));
- context.draw_surface(image, Vector(0, 0), layer);
+ context.draw_gradient(gradient_top, gradient_bottom, layer);
context.pop_transform();
} else if(type == IMAGE) {
if(!image)
return;
- int sx = int(-context.get_translation().x * speed) % image->w - image->w;
- int sy = int(-context.get_translation().y * speed) % image->h - image->h;
+ int w = (int) image->get_width();
+ int h = (int) image->get_height();
+ int sx = int(-context.get_translation().x * speed) % w - w;
+ int sy = int(-context.get_translation().y * speed) % h - h;
context.push_transform();
context.set_translation(Vector(0, 0));
- for(int x = sx; x < SCREEN_WIDTH; x += image->w)
- for(int y = sy; y < SCREEN_HEIGHT; y += image->h)
+ for(int x = sx; x < SCREEN_WIDTH; x += w)
+ for(int y = sy; y < SCREEN_HEIGHT; y += h)
context.draw_surface(image, Vector(x, y), layer);
context.pop_transform();
}
context.set_translation(Vector(0, 0));
if(black || type != NO_FADE) {
- uint8_t alpha;
+ float alpha;
if(black) {
- alpha = 255;
+ alpha = 1.0f;
} else {
switch(type) {
case FADE_IN:
- alpha = static_cast<uint8_t>
- (fading * 255.0 / fadetime);
+ alpha = fading / fadetime;
break;
case FADE_OUT:
- alpha = static_cast<uint8_t>
- ((fadetime-fading) * 255.0 / fadetime);
+ alpha = (fadetime-fading) / fadetime;
break;
default:
alpha = 0;
if (borders_fading || borders_active) {
context.draw_filled_rect(Vector(0, 0), Vector(SCREEN_WIDTH, border_size),
- Color(0, 0, 0, 255), LAYER_GUI-10);
+ Color(0, 0, 0, 1.0f), LAYER_GUI-10);
context.draw_filled_rect(Vector(0, SCREEN_HEIGHT - border_size), Vector(SCREEN_WIDTH, border_size),
- Color(0, 0, 0, 255), LAYER_GUI-10);
+ Color(0, 0, 0, 1.0f), LAYER_GUI-10);
}
context.pop_transform();
{
borders_fading = false;
}
+
pos += Vector(SCREEN_WIDTH * ((float) rand() / RAND_MAX),
SCREEN_HEIGHT/2 * ((float) rand() / RAND_MAX));
- int red = rand() % 255;
- int green = rand() % red;
+ float red = static_cast<float>(rand() % 255) / 255.0;
+ float green = static_cast<float>(rand() % ((int) red*255)) / 255.0;
sector->add_object(new Particles(pos, 0, 360, Vector(140, 140),
Vector(0, 0), 45, Color(red, green, 0), 3, 1.3,
LAYER_FOREGROUND1+1));
#include "game_object.hpp"
#include "moving_object.hpp"
#include "serializable.hpp"
+#include "video/color.hpp"
/* Bounciness of distros: */
#define NO_BOUNCE 0
#include "level_time.hpp"
#include <stdexcept>
+#include <iostream>
#include "main.hpp"
#include "resources.hpp"
#include "sector.hpp"
SnowParticleSystem::SnowParticleSystem()
{
- snowimages[0] = new Surface("images/objects/particles/snow0.png", true);
- snowimages[1] = new Surface("images/objects/particles/snow1.png", true);
- snowimages[2] = new Surface("images/objects/particles/snow2.png", true);
+ snowimages[0] = new Surface("images/objects/particles/snow0.png");
+ snowimages[1] = new Surface("images/objects/particles/snow1.png");
+ snowimages[2] = new Surface("images/objects/particles/snow2.png");
virtual_width = SCREEN_WIDTH * 2;
// Ghosts don't change their movement pattern - not random
GhostParticleSystem::GhostParticleSystem()
{
- ghosts[0] = new Surface("images/objects/particles/ghost0.png", true);
- ghosts[1] = new Surface("images/objects/particles/ghost1.png", true);
+ ghosts[0] = new Surface("images/objects/particles/ghost0.png");
+ ghosts[1] = new Surface("images/objects/particles/ghost1.png");
virtual_width = SCREEN_WIDTH * 2;
CloudParticleSystem::CloudParticleSystem()
{
- cloudimage = new Surface("images/objects/particles/cloud.png", true);
+ cloudimage = new Surface("images/objects/particles/cloud.png");
virtual_width = 2000.0;
RainParticleSystem::RainParticleSystem()
{
- rainimages[0] = new Surface("images/objects/particles/rain0.png", true);
- rainimages[1] = new Surface("images/objects/particles/rain1.png", true);
+ rainimages[0] = new Surface("images/objects/particles/rain0.png");
+ rainimages[1] = new Surface("images/objects/particles/rain1.png");
virtual_width = SCREEN_WIDTH * 2;
CometParticleSystem::CometParticleSystem()
{
- cometimages[0] = new Surface("images/creatures/mr_bomb/exploding-left-0.png", true);
- cometimages[1] = new Surface("images/creatures/mr_bomb/exploding-left-0.png", true);
+ cometimages[0] = new Surface("images/creatures/mr_bomb/exploding-left-0.png");
+ cometimages[1] = new Surface("images/creatures/mr_bomb/exploding-left-0.png");
virtual_width = SCREEN_WIDTH * 2;
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
// 02111-1307, USA.
-
#include <config.h>
#include "platform.hpp"
+
+#include <iostream>
#include "video/drawing_context.hpp"
#include "resources.hpp"
#include "player.hpp"
#include <config.h>
#include "text_object.hpp"
+
+#include <iostream>
#include "resources.hpp"
#include "video/drawing_context.hpp"
context.push_transform();
context.set_translation(Vector(0, 0));
if(fading > 0) {
- context.set_alpha(static_cast<uint8_t>
- ((fadetime-fading) * 255.0 / fadetime));
+ context.set_alpha((fadetime-fading) / fadetime);
} else if(fading < 0) {
- context.set_alpha(static_cast<uint8_t> (-fading * 255.0 / fadetime));
+ context.set_alpha(-fading / fadetime);
} else if(!visible) {
context.pop_transform();
return;
}
context.draw_filled_rect(Vector(125, 50), Vector(550, 120),
- Color(150, 180, 200, 125), LAYER_GUI-50);
+ Color(0.6, 0.7, 0.8, 0.5), LAYER_GUI-50);
if (centered) {
context.draw_center_text(font, text, Vector(0, 50+35), LAYER_GUI-40);
}
TileMap::TileMap()
: solid(false), speed(1), width(0), height(0), layer(LAYER_TILES),
- drawing_effect(0)
+ drawing_effect(NO_EFFECT)
{
tilemanager = tile_manager;
TileMap::TileMap(const lisp::Lisp& reader, TileManager* new_tile_manager)
: solid(false), speed(1), width(-1), height(-1), layer(LAYER_TILES),
- drawing_effect(0)
+ drawing_effect(NO_EFFECT)
{
tilemanager = new_tile_manager;
if(tilemanager == 0)
TileMap::TileMap(int layer_, bool solid_, size_t width_, size_t height_)
: solid(solid_), speed(1), width(0), height(0), layer(layer_),
- drawing_effect(0)
+ drawing_effect(NO_EFFECT)
{
tilemanager = tile_manager;
for (pos.x = start_x; pos.x < end_x; pos.x += 32)
{
context.draw_filled_rect(Vector (pos.x, start_y), Vector(1, fabsf(start_y - end_y)),
- Color(225, 225, 225), LAYER_GUI-50);
+ Color(0.8f, 0.8f, 0.8f), LAYER_GUI-50);
}
for (pos.y = start_y; pos.y < end_y; pos.y += 32)
{
context.draw_filled_rect(Vector (start_x, pos.y), Vector(fabsf(start_x - end_x), 1),
- Color(225, 225, 225), LAYER_GUI-50);
+ Color(1.0f, 1.0f, 1.0f), LAYER_GUI-50);
}
}
#endif
#include "game_object.hpp"
#include "serializable.hpp"
#include "math/vector.hpp"
+#include "video/drawing_context.hpp"
namespace lisp {
class Lisp;
return tilemanager;
}
- void set_drawing_effect(int effect)
+ void set_drawing_effect(DrawingEffect effect)
{
drawing_effect = effect;
}
- int get_drawing_effect()
+ DrawingEffect get_drawing_effect()
{
return drawing_effect;
}
int width, height;
int layer;
- int drawing_effect;
+ DrawingEffect drawing_effect;
};
#endif /*SUPERTUX_TILEMAP_H*/
if (player_status->lives >= 5) {
sprintf(str, "%dx", player_status->lives);
- float x = SCREEN_WIDTH - gold_text->get_text_width(str) - tux_life->w;
+ float x = SCREEN_WIDTH - gold_text->get_text_width(str) - tux_life->get_width();
context.draw_text(gold_text, str, Vector(x - BORDER_X, BORDER_Y + 20), LEFT_ALLIGN,
LAYER_FOREGROUND1);
context.draw_surface(tux_life, Vector(SCREEN_WIDTH - 16 - BORDER_X, BORDER_Y + 20),
} else {
for(int i= 0; i < player_status->lives; ++i)
context.draw_surface(tux_life,
- Vector(SCREEN_WIDTH - tux_life->w*4 +(tux_life->w*i) - BORDER_X, BORDER_Y + 20),
+ Vector(SCREEN_WIDTH - tux_life->get_width()*4 +(tux_life->get_width()*i) - BORDER_X,
+ BORDER_Y + 20),
LAYER_FOREGROUND1);
}
Font* gold_text;
Font* blue_text;
Font* gray_text;
-Font* yellow_nums;
Font* white_text;
Font* white_small_text;
Font* white_big_text;
void load_shared()
{
/* Load GUI/menu images: */
- checkbox = new Surface("images/engine/menu/checkbox-unchecked.png", true);
- checkbox_checked = new Surface("images/engine/menu/checkbox-checked.png", true);
- back = new Surface("images/engine/menu/arrow-back.png", true);
- arrow_left = new Surface("images/engine/menu/arrow-left.png", true);
- arrow_right = new Surface("images/engine/menu/arrow-right.png", true);
+ checkbox = new Surface("images/engine/menu/checkbox-unchecked.png");
+ checkbox_checked = new Surface("images/engine/menu/checkbox-checked.png");
+ back = new Surface("images/engine/menu/arrow-back.png");
+ arrow_left = new Surface("images/engine/menu/arrow-left.png");
+ arrow_right = new Surface("images/engine/menu/arrow-right.png");
/* Load the mouse-cursor */
mouse_cursor = new MouseCursor("images/engine/menu/mousecursor.png");
MouseCursor::set_current(mouse_cursor);
/* Load global images: */
- gold_text = new Font("images/engine/fonts/gold.png", Font::TEXT, 16,18);
- blue_text = new Font("images/engine/fonts/blue.png", Font::TEXT, 16,18,3);
- white_text = new Font("images/engine/fonts/white.png", Font::TEXT, 16,18);
- gray_text = new Font("images/engine/fonts/gray.png", Font::TEXT, 16,18);
+ gold_text = new Font("images/engine/fonts/gold.png",
+ "images/engine/fonts/shadow.png", 16, 18);
+ blue_text = new Font("images/engine/fonts/blue.png",
+ "images/engine/fonts/shadow.png", 16, 18, 3);
+ white_text = new Font("images/engine/fonts/white.png",
+ "images/engine/fonts/shadow.png", 16, 18);
+ gray_text = new Font("images/engine/fonts/gray.png",
+ "images/engine/fonts/shadow.png", 16, 18);
white_small_text = new Font("images/engine/fonts/white-small.png",
- Font::TEXT, 8,9, 1);
- white_big_text = new Font("images/engine/fonts/white-big.png",
- Font::TEXT, 20,22, 3);
- yellow_nums = new Font("images/engine/fonts/numbers.png", Font::NUM, 32,32);
+ "images/engine/fonts/shadow-small.png", 8, 9, 1);
+ white_big_text = new Font("images/engine/fonts/white-big.png",
+ "images/engine/fonts/shadow-big.png", 20, 22, 3);
Menu::default_font = white_text;
Menu::active_font = blue_text;
for (int i = 0; i < GROWING_FRAMES; i++)
{
sprintf(img_name, "images/creatures/tux_grow/left-%i.png", i+1);
- growingtux_left[i] = new Surface(img_name, true);
+ growingtux_left[i] = new Surface(img_name);
sprintf(img_name, "images/creatures/tux_grow/right-%i.png", i+1);
- growingtux_right[i] = new Surface(img_name, true);
+ growingtux_right[i] = new Surface(img_name);
}
small_tux = new TuxBodyParts();
load_object_gfx();
/* Tux life: */
- tux_life = new Surface("images/creatures/tux_small/tux-life.png", true);
+ tux_life = new Surface("images/creatures/tux_small/tux-life.png");
player_status = new PlayerStatus();
}
delete gray_text;
delete white_small_text;
delete white_big_text;
- delete yellow_nums;
free_object_gfx();
extern Font* gray_text;
extern Font* white_small_text;
extern Font* white_big_text;
-extern Font* yellow_nums;
void load_shared();
void unload_shared();
reader.get("bkgd_red_top", r);
reader.get("bkgd_green_top", g);
reader.get("bkgd_blue_top", b);
- bkgd_top.red = r;
- bkgd_top.green = g;
- bkgd_top.blue = b;
+ bkgd_top.red = static_cast<float> (r) / 255.0f;
+ bkgd_top.green = static_cast<float> (g) / 255.0f;
+ bkgd_top.blue = static_cast<float> (b) / 255.0f;
reader.get("bkgd_red_bottom", r);
reader.get("bkgd_green_bottom", g);
reader.get("bkgd_blue_bottom", b);
- bkgd_bottom.red = r;
- bkgd_bottom.green = g;
- bkgd_bottom.blue = b;
+ bkgd_bottom.red = static_cast<float> (r) / 255.0f;
+ bkgd_bottom.green = static_cast<float> (g) / 255.0f;
+ bkgd_bottom.blue = static_cast<float> (b) / 255.0f;
if(backgroundimage != "") {
Background* background = new Background;
}
void
-Sprite::set_action(std::string name, int loops)
+Sprite::set_action(const std::string& name, int loops)
{
if(action && action->name == name)
return;
int
Sprite::get_width() const
{
- return action->surfaces[get_frame()]->w;
+ return (int) action->surfaces[get_frame()]->get_width();
}
int
Sprite::get_height() const
{
- return action->surfaces[get_frame()]->h;
+ return (int) action->surfaces[get_frame()]->get_height();
}
#define SUPERTUX_SPRITE_H
#include <string>
-#include <vector>
-#include <cassert>
-#include <map>
+#include <assert.h>
+#include <SDL.h>
#include "video/surface.hpp"
#include "math/vector.hpp"
#include "sprite_data.hpp"
+class DrawingContext;
+
class Sprite
{
public:
- Sprite(SpriteData& data);
- Sprite(const Sprite& other);
- ~Sprite();
-
- /** Draw sprite, automatically calculates next frame */
- void draw(DrawingContext& context, const Vector& pos, int layer);
-
- void draw_part(DrawingContext& context, const Vector& source,
- const Vector& size, const Vector& pos, int layer);
-
- /** Set action (or state) */
- void set_action(std::string act, int loops = -1);
-
- /* Stop animation */
- void stop_animation()
- { animation_loops = 0; }
- /** Check if animation is stopped or not */
- bool check_animation();
-
- float get_fps() const
- { return action->fps; }
- /** Get current action total frames */
- int get_frames() const
- { return action->surfaces.size(); }
- /** Get sprite's name */
- const std::string& get_name() const
- { return data.name; }
- /** Get current action name */
- const std::string& get_action_name() const
- { return action->name; }
-
- int get_width() const;
- int get_height() const;
-
- /** Get current frame */
- int get_frame() const
- { return (int)frame; }
- /** Set current frame */
- void set_frame(int frame_)
- { if(frame_ > get_frames()) frame = 0; else frame = frame_; }
- Surface* get_frame(unsigned int frame)
- {
- assert(frame < action->surfaces.size());
- return action->surfaces[frame];
- }
+ Sprite(SpriteData& data);
+ Sprite(const Sprite& other);
+ ~Sprite();
+
+ /** Draw sprite, automatically calculates next frame */
+ void draw(DrawingContext& context, const Vector& pos, int layer);
+
+ void draw_part(DrawingContext& context, const Vector& source,
+ const Vector& size, const Vector& pos, int layer);
+
+ /** Set action (or state) */
+ void set_action(const std::string& act, int loops = -1);
+
+ /* Stop animation */
+ void stop_animation()
+ { animation_loops = 0; }
+ /** Check if animation is stopped or not */
+ bool check_animation();
+
+ float get_fps() const
+ { return action->fps; }
+ /** Get current action total frames */
+ int get_frames() const
+ { return action->surfaces.size(); }
+ /** Get sprite's name */
+ const std::string& get_name() const
+ { return data.name; }
+ /** Get current action name */
+ const std::string& get_action_name() const
+ { return action->name; }
+
+ int get_width() const;
+ int get_height() const;
+
+ /** Get current frame */
+ int get_frame() const
+ { return (int)frame; }
+ /** Set current frame */
+ void set_frame(int frame_)
+ { if(frame_ > get_frames()) frame = 0; else frame = frame_; }
+ Surface* get_frame(unsigned int frame)
+ {
+ assert(frame < action->surfaces.size());
+ return action->surfaces[frame];
+ }
private:
- void update();
+ void update();
- SpriteData& data;
+ SpriteData& data;
- float frame;
- int animation_loops;
- Uint32 last_ticks;
+ float frame;
+ int animation_loops;
+ Uint32 last_ticks;
- SpriteData::Action* action;
+ SpriteData::Action* action;
};
#endif
} else {
for(int i = 0; static_cast<unsigned int>(i) < act_tmp->surfaces.size();
i++) {
- Surface* surface = new Surface(sdl_surface_from_sdl_surface(
- act_tmp->surfaces[i]->impl->get_sdl_surface()), true);
- surface->apply_filter(HORIZONTAL_FLIP_FILTER);
+ Surface* surface = new Surface(*(act_tmp->surfaces[i]));
+ surface->hflip();
action->surfaces.push_back(surface);
}
}
}
for(std::vector<std::string>::size_type i = 0; i < images.size(); i++) {
- action->surfaces.push_back(new Surface(basedir + images[i], true));
+ action->surfaces.push_back(new Surface(basedir + images[i]));
}
}
actions[action->name] = action;
if(line[0] == '!') {
std::string imagename = line.substr(1, line.size()-1);
std::cout << "Imagename: " << imagename << "\n";
- images.insert(std::make_pair(imagename, new Surface(imagename, true)));
+ images.insert(std::make_pair(imagename, new Surface(imagename)));
}
}
// load background image
- Surface* background
- = new Surface("images/background/" + background_file, false);
+ Surface* background = new Surface("images/background/" + background_file);
bool done = false;
float scroll = 0;
}
if(image != 0) {
context.draw_surface(image,
- Vector( (SCREEN_WIDTH - image->w) / 2,
+ Vector( (SCREEN_WIDTH - image->get_width()) / 2,
SCREEN_HEIGHT + y - scroll), 255);
- y += image->h + ITEMS_SPACE;
+ y += image->get_height() + ITEMS_SPACE;
}
}
float height = 200;
context.draw_filled_rect(Vector(x1, y1), Vector(width, height),
- Color(150, 180, 200, 125), LAYER_GUI-1);
+ Color(0.6f, 0.7f, 0.8f, 0.5f), LAYER_GUI-1);
float y = y1;
for(size_t i = firstline; i < lines.size(); ++i) {
Surface* surface;
std::string file = tilesetpath + spec.file;
if(spec.rect.get_width() <= 0) {
- surface = new Surface(file, true);
+ surface = new Surface(file);
} else {
surface = new Surface(file,
(int) spec.rect.p1.x,
(int) spec.rect.p1.y,
(int) spec.rect.get_width(),
- (int) spec.rect.get_height(), true);
+ (int) spec.rect.get_height());
}
images.push_back(surface);
}
if(editor_imagefile != "") {
- editor_image = new Surface(tilesetpath + editor_imagefile, true);
+ editor_image = new Surface(tilesetpath + editor_imagefile);
}
}
#define TILE_H
#include <vector>
+#include <SDL.h>
#include "video/surface.hpp"
#include "math/rect.hpp"
#include "lisp/lisp.hpp"
+class DrawingContext;
+
/**
Tile Class
*/
{
if(!images.size())
return 0;
- return images[0]->w;
+ return (int) images[0]->get_width();
}
/// returns the height of the tiles in pixels
{
if(!images.size())
return 0;
- return images[0]->h;
+ return (int) images[0]->get_height();
}
protected:
#include <memory>
#include <stdexcept>
+#include <iostream>
#include <assert.h>
#include "video/drawing_context.hpp"
#include "lisp/lisp.hpp"
#include <vector>
#include <string>
#include <map>
+#include <iostream>
#include <stdint.h>
#include <assert.h>
#include "tile.hpp"
titlesession = new GameSession("levels/misc/menu.stl", ST_GL_DEMO_GAME);
/* Load images: */
- bkg_title = new Surface("images/background/arctis.jpg", false);
- logo = new Surface("images/engine/menu/logo.png", true);
- //img_choose_subset = new Surface("images/status/choose-level-subset.png", true);
+ bkg_title = new Surface("images/background/arctis.jpg");
+ logo = new Surface("images/engine/menu/logo.png");
+ //img_choose_subset = new Surface("images/status/choose-level-subset.png");
titlesession->get_current_sector()->activate("main");
titlesession->set_current();
draw_demo(elapsed_time);
if (Menu::current() == main_menu)
- context.draw_surface(logo, Vector(SCREEN_WIDTH/2 - logo->w/2, 30),
+ context.draw_surface(logo, Vector(SCREEN_WIDTH/2 - logo->get_width()/2, 30),
LAYER_FOREGROUND1+1);
context.draw_text(white_small_text, " SuperTux " PACKAGE_VERSION "\n",
--- /dev/null
+#ifndef __COLOR_HPP__
+#define __COLOR_HPP__
+
+#include <vector>
+
+class Color
+{
+public:
+ Color()
+ : red(0), green(0), blue(0), alpha(1.0)
+ { }
+ Color(float red, float green, float blue, float alpha = 1.0)
+ : red(red), green(green), blue(blue), alpha(alpha)
+ { }
+ Color(const std::vector<float>& vals)
+ {
+ red = vals[0];
+ green = vals[1];
+ blue = vals[2];
+ if(vals.size() > 3)
+ alpha = vals[3];
+ }
+
+ float red, green, blue, alpha;
+};
+
+#endif
+
#include "gameconfig.hpp"
#include "glutil.hpp"
#include "texture.hpp"
+#include "texture_manager.hpp"
#define LIGHTMAP_DIV 4
lightmap_width = screen->w / LIGHTMAP_DIV;
lightmap_height = screen->h / LIGHTMAP_DIV;
- int width = next_po2(lightmap_width);
- int height = next_po2(lightmap_height);
+ unsigned int width = next_po2(lightmap_width);
+ unsigned int height = next_po2(lightmap_height);
- lightmap.reset(new Texture(width, height, GL_RGB));
+ lightmap = new Texture(width, height, GL_RGB);
lightmap_uv_right = static_cast<float>(lightmap_width) / static_cast<float>(width);
lightmap_uv_bottom = static_cast<float>(lightmap_height) / static_cast<float>(height);
+ texture_manager->register_texture(lightmap);
requests = &drawing_requests;
}
DrawingContext::~DrawingContext()
{
+ texture_manager->remove_texture(lightmap);
+ delete lightmap;
}
void
request.pos = transform.apply(position);
if(request.pos.x >= SCREEN_WIDTH || request.pos.y >= SCREEN_HEIGHT
- || request.pos.x + surface->w < 0 || request.pos.y + surface->h < 0)
+ || request.pos.x + surface->get_width() < 0
+ || request.pos.y + surface->get_height() < 0)
return;
request.layer = layer;
request.drawing_effect = transform.drawing_effect;
- request.zoom = transform.zoom;
request.alpha = transform.alpha;
request.request_data = const_cast<Surface*> (surface);
request.pos = transform.apply(position);
request.layer = layer;
request.drawing_effect = transform.drawing_effect;
- request.zoom = transform.zoom;
request.alpha = transform.alpha;
TextRequest* textrequest = new TextRequest;
}
void
-DrawingContext::draw_gradient(Color top, Color bottom, int layer)
+DrawingContext::draw_gradient(const Color& top, const Color& bottom, int layer)
{
DrawingRequest request;
request.layer = layer;
request.drawing_effect = transform.drawing_effect;
- request.zoom = transform.zoom;
request.alpha = transform.alpha;
GradientRequest* gradientrequest = new GradientRequest;
void
DrawingContext::draw_filled_rect(const Vector& topleft, const Vector& size,
- Color color, int layer)
+ const Color& color, int layer)
{
DrawingRequest request;
request.layer = layer;
request.drawing_effect = transform.drawing_effect;
- request.zoom = transform.zoom;
request.alpha = transform.alpha;
FillRectRequest* fillrectrequest = new FillRectRequest;
fillrectrequest->size = size;
fillrectrequest->color = color;
- fillrectrequest->color.alpha
- = (int) ((float) fillrectrequest->color.alpha
- * ((float) transform.alpha / 255.0));
+ fillrectrequest->color.alpha = color.alpha * transform.alpha;
request.request_data = fillrectrequest;
requests->push_back(request);
SurfacePartRequest* surfacepartrequest
= (SurfacePartRequest*) request.request_data;
- surfacepartrequest->surface->impl->draw_part(
+ surfacepartrequest->surface->draw_part(
surfacepartrequest->source.x, surfacepartrequest->source.y,
request.pos.x, request.pos.y,
- surfacepartrequest->size.x, surfacepartrequest->size.y, request.alpha,
- request.drawing_effect);
+ surfacepartrequest->size.x, surfacepartrequest->size.y,
+ request.alpha, request.drawing_effect);
delete surfacepartrequest;
}
const Color& bottom = gradientrequest->bottom;
glBegin(GL_QUADS);
- glColor3ub(top.red, top.green, top.blue);
+ glColor4f(top.red, top.green, top.blue, top.alpha);
glVertex2f(0, 0);
glVertex2f(SCREEN_WIDTH, 0);
- glColor3ub(bottom.red, bottom.green, bottom.blue);
+ glColor4f(bottom.red, bottom.green, bottom.blue, bottom.alpha);
glVertex2f(SCREEN_WIDTH, SCREEN_HEIGHT);
glVertex2f(0, SCREEN_HEIGHT);
glEnd();
float w = fillrectrequest->size.x;
float h = fillrectrequest->size.y;
- glEnable(GL_BLEND);
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
- glColor4ub(fillrectrequest->color.red, fillrectrequest->color.green,
- fillrectrequest->color.blue, fillrectrequest->color.alpha);
-
- glBegin(GL_POLYGON);
+ glDisable(GL_TEXTURE_2D);
+ glColor4f(fillrectrequest->color.red, fillrectrequest->color.green,
+ fillrectrequest->color.blue, fillrectrequest->color.alpha);
+
+ glBegin(GL_QUADS);
glVertex2f(x, y);
glVertex2f(x+w, y);
glVertex2f(x+w, y+h);
glVertex2f(x, y+h);
glEnd();
- glDisable(GL_BLEND);
+ glEnable(GL_TEXTURE_2D);
delete fillrectrequest;
}
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
- glClearColor(1, 1, 1, 1);
+ glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
handle_drawing_requests(lightmap_requests);
lightmap_requests.clear();
glDisable(GL_BLEND);
- glEnable(GL_TEXTURE_2D);
- glBindTexture(GL_TEXTURE_2D, lightmap->handle);
+ glBindTexture(GL_TEXTURE_2D, lightmap->get_handle());
glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, screen->h - lightmap_height, lightmap_width, lightmap_height);
glViewport(0, 0, screen->w, screen->h);
glOrtho(0, SCREEN_WIDTH, SCREEN_HEIGHT, 0, -1.0, 1.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
+ glEnable(GL_BLEND);
}
//glClear(GL_COLOR_BUFFER_BIT);
drawing_requests.clear();
if(use_lightmap) {
- glEnable(GL_BLEND);
glBlendFunc(GL_DST_COLOR, GL_ZERO);
- //glDisable(GL_BLEND);
- //glColor4f((float) rand() / (float) RAND_MAX, .22, .88, 1.0f);
-
- glEnable(GL_TEXTURE_2D);
- glDisable(GL_DEPTH_TEST);
- glDisable(GL_CULL_FACE);
- glDisable(GL_ALPHA_TEST);
- glBindTexture(GL_TEXTURE_2D, lightmap->handle);
+ glBindTexture(GL_TEXTURE_2D, lightmap->get_handle());
glBegin(GL_QUADS);
glTexCoord2f(0, lightmap_uv_bottom);
glVertex2f(0, SCREEN_HEIGHT);
glEnd();
+
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
}
assert_gl("drawing");
case SURFACE:
{
const Surface* surface = (const Surface*) i->request_data;
-
- if(i->zoom != 1.0)
- surface->impl->draw_stretched(i->pos.x * i->zoom, i->pos.y * i->zoom,
- (int)(surface->w * i->zoom), (int)(surface->h * i->zoom),
- i->alpha, i->drawing_effect);
- else
- surface->impl->draw(i->pos.x, i->pos.y, i->alpha, i->drawing_effect);
+ surface->draw(i->pos.x, i->pos.y, i->alpha, i->drawing_effect);
break;
}
case SURFACE_PART:
}
void
-DrawingContext::set_drawing_effect(uint32_t effect)
+DrawingContext::set_drawing_effect(DrawingEffect effect)
{
transform.drawing_effect = effect;
}
-uint32_t
+DrawingEffect
DrawingContext::get_drawing_effect() const
{
return transform.drawing_effect;
}
void
-DrawingContext::set_zooming(float zoom)
-{
- transform.zoom = zoom;
-}
-
-void
-DrawingContext::set_alpha(uint8_t alpha)
+DrawingContext::set_alpha(float alpha)
{
transform.alpha = alpha;
}
-uint8_t
+float
DrawingContext::get_alpha() const
{
return transform.alpha;
#include <string>
#include <stdint.h>
+#include <GL/gl.h>
#include <SDL.h>
#include <stdint.h>
#include <memory>
#include "math/vector.hpp"
-#include "video/screen.hpp"
-#include "video/surface.hpp"
-#include "video/font.hpp"
+#include "surface.hpp"
+#include "font.hpp"
+#include "color.hpp"
class Surface;
class Texture;
void draw_center_text(const Font* font, const std::string& text,
const Vector& position, int layer);
/// Draws a color gradient onto the whole screen */
- void draw_gradient(Color from, Color to, int layer);
+ void draw_gradient(const Color& from, const Color& to, int layer);
/// Fills a rectangle.
void draw_filled_rect(const Vector& topleft, const Vector& size,
- Color color, int layer);
+ const Color& color, int layer);
/// Processes all pending drawing requests and flushes the list.
void do_drawing();
void pop_transform();
/// Apply that effect in the next draws (effects are listed on surface.h).
- void set_drawing_effect(uint32_t effect);
+ void set_drawing_effect(DrawingEffect effect);
/// return currently applied drawing effect
- uint32_t get_drawing_effect() const;
- /// apply that zoom in the next draws */
- void set_zooming(float zoom);
- /// apply that alpha in the next draws */
- void set_alpha(uint8_t alpha);
+ DrawingEffect get_drawing_effect() const;
+ /// apply that alpha in the next draws (1.0 means fully opaque) */
+ void set_alpha(float alpha);
/// return currently set alpha
- uint8_t get_alpha() const;
+ float get_alpha() const;
enum Target {
NORMAL, LIGHTMAP
{
public:
Vector translation;
- uint32_t drawing_effect;
- float zoom;
- uint8_t alpha;
+ DrawingEffect drawing_effect;
+ float alpha;
Transform()
- : drawing_effect(NONE_EFFECT), zoom(1), alpha(255)
+ : drawing_effect(NO_EFFECT), alpha(1.0f)
{ }
Vector apply(const Vector& v) const
Vector pos;
int layer;
- uint32_t drawing_effect;
- float zoom;
- int alpha;
+ DrawingEffect drawing_effect;
+ float alpha;
Blend blend;
void* request_data;
SDL_Surface* screen;
Target target;
std::vector<Target> target_stack;
- std::auto_ptr<Texture> lightmap;
+ Texture* lightmap;
int lightmap_width, lightmap_height;
float lightmap_uv_right, lightmap_uv_bottom;
};
#include "font.hpp"
#include "drawing_context.hpp"
-Font::Font(const std::string& file, FontType ntype, int nw, int nh,
- int nshadowsize)
- : chars(0), shadow_chars(0), type(ntype), w(nw), h(nh),
- shadowsize(nshadowsize)
+Font::Font(const std::string& file, const std::string& shadowfile,
+ int w, int h, int shadowsize)
+ : chars(0), shadow_chars(0), w(w), h(h), shadowsize(shadowsize)
{
- chars = new Surface(file, true);
+ chars = new Surface(file);
+ shadow_chars = new Surface(shadowfile);
- switch(type) {
- case TEXT:
- first_char = 32;
- break;
- case NUM:
- first_char = 48;
- break;
- }
- char_count = (chars->h / h) * 16;
-
- // Load shadow font.
- if(shadowsize > 0) {
- SDL_Surface* conv = SDL_DisplayFormatAlpha(chars->impl->get_sdl_surface());
- int pixels = conv->w * conv->h;
- SDL_LockSurface(conv);
- for(int i = 0; i < pixels; ++i) {
- Uint32 *p = (Uint32 *)conv->pixels + i;
- *p = *p & conv->format->Amask;
- }
- SDL_UnlockSurface(conv);
- SDL_SetAlpha(conv, SDL_SRCALPHA, 128);
- shadow_chars = new Surface(conv, true);
- SDL_FreeSurface(conv);
- }
+ first_char = 32;
+ char_count = ((int) chars->get_height() / h) * 16;
}
Font::~Font()
void
Font::draw(const std::string& text, const Vector& pos_, FontAlignment alignment,
- uint32_t drawing_effect, uint8_t alpha) const
+ DrawingEffect drawing_effect, float alpha) const
{
/* Cut lines changes into seperate strings, needed to support center/right text
alignments with break lines.
void
Font::draw_text(const std::string& text, const Vector& pos,
- uint32_t drawing_effect, uint8_t alpha) const
+ DrawingEffect drawing_effect, float alpha) const
{
if(shadowsize > 0)
draw_chars(shadow_chars, text, pos + Vector(shadowsize, shadowsize),
void
Font::draw_chars(Surface* pchars, const std::string& text, const Vector& pos,
- uint32_t drawing_effect, uint8_t alpha) const
+ DrawingEffect drawing_effect, float alpha) const
{
- SurfaceImpl* impl = pchars->impl;
-
Vector p = pos;
size_t i = 0;
while(i < text.size()) {
int source_x = (font_index % 16) * w;
int source_y = (font_index / 16) * h;
- impl->draw_part(source_x, source_y, p.x, p.y, w, h, alpha, drawing_effect);
+ pchars->draw_part(source_x, source_y, p.x, p.y, w, h, alpha,
+ drawing_effect);
p.x += w;
}
}
class Font
{
public:
- enum FontType {
- TEXT, // images for all characters
- NUM // only images for numbers
- };
-
- Font(const std::string& file, FontType type, int w, int h,
- int shadowsize=2);
+ Font(const std::string& file, const std::string& shadowfile,
+ int w, int h, int shadowsize = 2);
~Font();
/** returns the width of a given text. (Note that I won't add a normal
* Type of alignment, drawing effect and alpha are optional. */
void draw(const std::string& text, const Vector& pos,
FontAlignment allignment = LEFT_ALLIGN,
- uint32_t drawing_effect = NONE_EFFECT, uint8_t alpha = 255) const;
+ DrawingEffect drawing_effect = NO_EFFECT,
+ float alpha = 1.0f) const;
private:
friend class DrawingContext;
void draw_text(const std::string& text, const Vector& pos,
- uint32_t drawing_effect = NONE_EFFECT, uint8_t alpha = 255) const;
+ DrawingEffect drawing_effect = NO_EFFECT,
+ float alpha = 1.0f) const;
void draw_chars(Surface* pchars, const std::string& text,
- const Vector& position, uint32_t drawing_effect, uint8_t alpha) const;
+ const Vector& position, DrawingEffect drawing_effect,
+ float alpha) const;
Surface* chars;
Surface* shadow_chars;
- FontType type;
int w;
int h;
int shadowsize;
--- /dev/null
+#include <config.h>
+
+#include "image_texture.hpp"
+#include "texture_manager.hpp"
+
+ImageTexture::ImageTexture(SDL_Surface* surface)
+ : Texture(surface, GL_RGBA), refcount(0)
+{
+}
+
+ImageTexture::~ImageTexture()
+{
+}
+
+void
+ImageTexture::release()
+{
+ texture_manager->release(this);
+}
--- /dev/null
+#ifndef __SURFACE_TEXTURE_HPP__
+#define __SURFACE_TEXTURE_HPP__
+
+#include <string>
+#include "texture.hpp"
+
+class ImageTexture : public Texture
+{
+private:
+ std::string filename;
+ float image_width;
+ float image_height;
+ int refcount;
+
+public:
+ float get_image_width() const
+ {
+ return image_width;
+ }
+
+ float get_image_height() const
+ {
+ return image_height;
+ }
+
+ float get_uv_right() const
+ {
+ return image_width / static_cast<float> (get_width());
+ }
+
+ float get_uv_bottom() const
+ {
+ return image_height / static_cast<float> (get_height());
+ }
+
+ void ref()
+ {
+ refcount++;
+ }
+
+ void unref()
+ {
+ assert(refcount > 0);
+ refcount--;
+ if(refcount == 0)
+ release();
+ }
+
+private:
+ friend class TextureManager;
+
+ ImageTexture(SDL_Surface* surface);
+ virtual ~ImageTexture();
+
+ void release();
+};
+
+#endif
+
#include <unistd.h>
#include <SDL.h>
-#include <SDL_image.h>
-
-#ifndef WIN32
-#include <sys/types.h>
-#include <ctype.h>
-#endif
#include "gameconfig.hpp"
#include "screen.hpp"
#include "math/vector.hpp"
static const float LOOP_DELAY = 20.0;
-extern SDL_Surface* screen;
-
-/* 'Stolen' from the SDL documentation.
- * Return the pixel value at (x, y)
- * NOTE: The surface must be locked before calling this!
- */
-Uint32 getpixel(SDL_Surface *surface, int x, int y)
-{
- int bpp = surface->format->BytesPerPixel;
- /* Here p is the address to the pixel we want to retrieve */
- Uint8 *p = (Uint8 *)surface->pixels + y * surface->pitch + x * bpp;
-
- switch(bpp) {
- case 1:
- return *p;
-
- case 2:
- return *(Uint16 *)p;
-
- case 3:
- if(SDL_BYTEORDER == SDL_BIG_ENDIAN)
- return p[0] << 16 | p[1] << 8 | p[2];
- else
- return p[0] | p[1] << 8 | p[2] << 16;
-
- case 4:
- return *(Uint32 *)p;
-
- default:
- return 0; /* shouldn't happen, but avoids warnings */
- }
-}
-
-/* 'Stolen' from the SDL documentation.
- * Set the pixel at (x, y) to the given value
- * NOTE: The surface must be locked before calling this!
- */
-void putpixel(SDL_Surface *surface, int x, int y, Uint32 pixel)
-{
- int bpp = surface->format->BytesPerPixel;
- /* Here p is the address to the pixel we want to set */
- Uint8 *p = (Uint8 *)surface->pixels + y * surface->pitch + x * bpp;
-
- switch(bpp) {
- case 1:
- *p = pixel;
- break;
-
- case 2:
- *(Uint16 *)p = pixel;
- break;
-
- case 3:
- if(SDL_BYTEORDER == SDL_BIG_ENDIAN)
- {
- p[0] = (pixel >> 16) & 0xff;
- p[1] = (pixel >> 8) & 0xff;
- p[2] = pixel & 0xff;
- }
- else
- {
- p[0] = pixel & 0xff;
- p[1] = (pixel >> 8) & 0xff;
- p[2] = (pixel >> 16) & 0xff;
- }
- break;
-
- case 4:
- *(Uint32 *)p = pixel;
- break;
-
- default:
- assert(false);
- }
-}
-
-/* Draw a single pixel on the screen. */
-void drawpixel(int x, int y, Uint32 pixel)
-{
- /* Lock the screen for direct access to the pixels */
- if ( SDL_MUSTLOCK(screen) )
- {
- if ( SDL_LockSurface(screen) < 0 )
- {
- fprintf(stderr, "Can't lock screen: %s\n", SDL_GetError());
- return;
- }
- }
-
- if(!(x < 0 || y < 0 || x > SCREEN_WIDTH || y > SCREEN_HEIGHT))
- putpixel(screen, x, y, pixel);
-
- if ( SDL_MUSTLOCK(screen) )
- {
- SDL_UnlockSurface(screen);
- }
- /* Update just the part of the display that we've changed */
- SDL_UpdateRect(screen, x, y, 1, 1);
-}
-
-/* --- FILL A RECT --- */
void fillrect(float x, float y, float w, float h, int r, int g, int b, int a)
{
h = -h;
}
- glEnable(GL_BLEND);
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glColor4ub(r, g, b,a);
-
+
+ glDisable(GL_TEXTURE_2D);
glBegin(GL_POLYGON);
glVertex2f(x, y);
glVertex2f(x+w, y);
glVertex2f(x+w, y+h);
glVertex2f(x, y+h);
glEnd();
- glDisable(GL_BLEND);
-}
-
-/* Needed for line calculations */
-#define SGN(x) ((x)>0 ? 1 : ((x)==0 ? 0:(-1)))
-#define ABS(x) ((x)>0 ? (x) : (-x))
-
-void draw_line(float x1, float y1, float x2, float y2,
- int r, int g, int b, int a)
-{
- glEnable(GL_BLEND);
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
- glColor4ub(r, g, b,a);
-
- glBegin(GL_LINES);
- glVertex2f(x1, y1);
- glVertex2f(x2, y2);
- glEnd();
- glDisable(GL_BLEND);
+ glEnable(GL_TEXTURE_2D);
}
-
void fadeout(int fade_time)
{
float alpha_inc = 256 / (fade_time / LOOP_DELAY);
while(alpha > 0) {
alpha -= alpha_inc;
fillrect(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, 0,0,0, (int)alpha_inc); // left side
-
- DrawingContext context; // ugly...
- context.do_drawing();
+
+ SDL_GL_SwapBuffers();
sound_manager->update();
SDL_Delay(int(LOOP_DELAY));
fillrect(SCREEN_WIDTH - right_cor, 0, right_cor, SCREEN_HEIGHT, 0,0,0); // right side
fillrect(0, 0, SCREEN_WIDTH, up_cor, 0,0,0); // up side
fillrect(0, SCREEN_HEIGHT - down_cor, SCREEN_WIDTH, down_cor+1, 0,0,0); // down side
- DrawingContext context; // ugly...
- context.do_drawing();
+
+ SDL_GL_SwapBuffers();
sound_manager->update();
SDL_Delay(int(LOOP_DELAY));
#include <vector>
#include "math/vector.hpp"
-/** Stores 8bit RGBA values. */
-class Color
-{
-public:
- Color()
- : red(0), green(0), blue(0), alpha(255)
- {}
-
- Color(Uint8 red_, Uint8 green_, Uint8 blue_, Uint8 alpha_ = 255)
- : red(red_), green(green_), blue(blue_), alpha(alpha_)
- {}
-
- Color(std::vector <unsigned int> color)
- : red(0), green(0), blue(0), alpha(255)
- { if(color.size() >= 3) { red = color[0]; green = color[1]; blue = color[2]; }
- if(color.size() == 4) alpha = color[3]; }
-
- Color(std::vector <int> color)
- : red(0), green(0), blue(0), alpha(255)
- { if(color.size() >= 3) { red = color[0]; green = color[1]; blue = color[2]; }
- if(color.size() == 4) alpha = color[3]; }
-
- Color(const Color& o)
- : red(o.red), green(o.green), blue(o.blue), alpha(o.alpha)
- { }
-
- bool operator==(const Color& o)
- {
- if(red == o.red && green == o.green &&
- blue == o.blue && alpha == o.alpha)
- return true;
- return false;
- }
-
- Uint32 map_rgb(SDL_Surface* surface)
- { return SDL_MapRGB(surface->format, red, green, blue); }
- Uint32 map_rgba(SDL_Surface* surface)
- { return SDL_MapRGBA(surface->format, red, green, blue, alpha); }
-
- Uint8 red, green, blue, alpha;
-};
-
-Uint32 getpixel(SDL_Surface* surface, int x, int y);
-void putpixel(SDL_Surface* surface, int x, int y, Uint32 pixel);
-void drawpixel(int x, int y, Uint32 pixel);
void fillrect(float x, float y, float w, float h, int r, int g, int b, int a = 255);
-void draw_line(float x1, float y1, float x2, float y2, int r, int g, int b, int a = 255);
void fadeout(int fade_time);
void shrink_fade(const Vector& point, int fade_time);
#include <algorithm>
#include <stdexcept>
#include <sstream>
+#include <math.h>
#include <SDL.h>
#include <SDL_image.h>
#include "physfs/physfs_sdl.hpp"
#include "video/surface.hpp"
#include "video/screen.hpp"
+#include "image_texture.hpp"
+#include "texture_manager.hpp"
-Surface::Surfaces Surface::surfaces;
-
-extern SDL_Surface* screen;
-
-SurfaceData::SurfaceData(SDL_Surface* temp, bool use_alpha_)
- : type(SURFACE), surface(0), use_alpha(use_alpha_),
- x(0), y(0), w(0), h(0)
+Surface::Surface(const std::string& file)
{
- // Copy the given surface and make sure that it is not stored in
- // video memory
- surface = SDL_CreateRGBSurface(temp->flags & (~SDL_HWSURFACE),
- temp->w, temp->h,
- temp->format->BitsPerPixel,
- temp->format->Rmask,
- temp->format->Gmask,
- temp->format->Bmask,
- temp->format->Amask);
- if(!surface)
- throw std::runtime_error("No memory left for surface");
-
- SDL_SetAlpha(temp,0,0);
- SDL_BlitSurface(temp, NULL, surface, NULL);
-}
+ texture = texture_manager->get(file);
+ texture->ref();
+ uv_left = 0;
+ uv_top = 0;
+ uv_right = texture->get_uv_right();
+ uv_bottom = texture->get_uv_bottom();
-SurfaceData::SurfaceData(const std::string& file_, bool use_alpha_)
- : type(LOAD), surface(0), file(file_), use_alpha(use_alpha_)
-{}
-
-SurfaceData::SurfaceData(const std::string& file_, int x_, int y_,
- int w_, int h_, bool use_alpha_)
- : type(LOAD_PART), surface(0), file(file_), use_alpha(use_alpha_),
- x(x_), y(y_), w(w_), h(h_)
-{}
-
-SurfaceData::SurfaceData(Color top_gradient_, Color bottom_gradient_,
- int w_, int h_)
- : type(GRADIENT), surface(0), use_alpha(false), w(w_), h(h_)
-{
- top_gradient = top_gradient_;
- bottom_gradient = bottom_gradient_;
+ width = texture->get_image_width();
+ height = texture->get_image_height();
}
-
-SurfaceData::~SurfaceData()
+Surface::Surface(const std::string& file, int x, int y, int w, int h)
{
- SDL_FreeSurface(surface);
-}
+ texture = texture_manager->get(file);
+ texture->ref();
-SurfaceImpl*
-SurfaceData::create()
-{
- return create_SurfaceOpenGL();
-}
+ float tex_w = static_cast<float> (texture->get_width());
+ float tex_h = static_cast<float> (texture->get_height());
+ uv_left = static_cast<float>(x) / tex_w;
+ uv_top = static_cast<float>(y) / tex_h;
+ uv_right = static_cast<float>(x+w) / tex_w;
+ uv_bottom = static_cast<float>(y+h) / tex_h;
-SurfaceOpenGL*
-SurfaceData::create_SurfaceOpenGL()
-{
- switch(type)
- {
- case LOAD:
- return new SurfaceOpenGL(file);
- case LOAD_PART:
- return new SurfaceOpenGL(file, x, y, w, h);
- case SURFACE:
- return new SurfaceOpenGL(surface);
- case GRADIENT:
- return new SurfaceOpenGL(top_gradient, bottom_gradient, w, h);
- default:
- assert(false);
- }
-}
-
-/* Quick utility function for texture creation */
-static int power_of_two(int input)
-{
- int value = 1;
-
- while ( value < input )
- {
- value <<= 1;
- }
- return value;
-}
-
-Surface::Surface(SDL_Surface* surf, bool use_alpha)
- : impl(0), data(surf, use_alpha), w(0), h(0)
-{
- impl = data.create();
- if (impl)
- {
- w = impl->w;
- h = impl->h;
- }
- surfaces.push_back(this);
-}
-
-Surface::Surface(const std::string& file, bool use_alpha)
- : impl(0), data(file, use_alpha), w(0), h(0)
-{
- impl = data.create();
- if (impl)
- {
- w = impl->w;
- h = impl->h;
- }
- surfaces.push_back(this);
+ width = w;
+ height = h;
}
-Surface::Surface(const std::string& file, int x, int y, int w_, int h_, bool use_alpha)
- : impl(0), data(file, x, y, w_, h_, use_alpha), w(0), h(0)
+Surface::Surface(const Surface& other)
{
- impl = data.create();
- if (impl)
- {
- w = impl->w;
- h = impl->h;
- }
- surfaces.push_back(this);
-}
+ texture = other.texture;
+ texture->ref();
-Surface::Surface(Color top_background, Color bottom_background, int w_, int h_)
- : impl(0), data(top_background, bottom_background, w_, h_), w(0), h(0)
-{
- impl = data.create();
- if (impl)
- {
- w = impl->w;
- h = impl->h;
- }
- surfaces.push_back(this);
+ uv_left = other.uv_left;
+ uv_top = other.uv_top;
+ uv_right = other.uv_right;
+ uv_bottom = other.uv_bottom;
+ width = other.width;
+ height = other.height;
}
-void
-Surface::reload()
+const Surface&
+Surface::operator= (const Surface& other)
{
- delete impl;
- impl = data.create();
- if (impl)
- {
- w = impl->w;
- h = impl->h;
- for(std::vector<SurfaceData::Filter>::iterator i =
- data.applied_filters.begin(); i != data.applied_filters.end();
- i++)
- impl->apply_filter(i->type, i->color);
- }
-}
+ other.texture->ref();
+ texture->unref();
+ texture = other.texture;
-void Surface::apply_filter(int filter, Color color)
-{
- impl->apply_filter(filter, color);
+ uv_left = other.uv_left;
+ uv_top = other.uv_top;
+ uv_right = other.uv_right;
+ uv_bottom = other.uv_bottom;
+ width = other.width;
+ height = other.height;
- SurfaceData::Filter apply_filter;
- apply_filter.type = filter;
- apply_filter.color = color;
- data.applied_filters.push_back(apply_filter);
+ return *this;
}
Surface::~Surface()
{
-#ifdef DEBUG
- bool found = false;
- for(std::list<Surface*>::iterator i = surfaces.begin(); i != surfaces.end();
- ++i)
- {
- if(*i == this)
- {
- found = true; break;
- }
- }
- if(!found)
- printf("Error: Surface freed twice!!!\n");
-#endif
- surfaces.remove(this);
- delete impl;
+ texture->unref();
}
void
-Surface::reload_all()
-{
- for(Surfaces::iterator i = surfaces.begin(); i != surfaces.end(); ++i)
- {
- (*i)->reload();
- }
-}
-
-void
-Surface::debug_check()
-{
- for(Surfaces::iterator i = surfaces.begin(); i != surfaces.end(); ++i)
- {
- printf("Surface not freed: T:%d F:%s.\n", (*i)->data.type,
- (*i)->data.file.c_str());
- }
-}
-
-void
-apply_filter_to_surface(SDL_Surface* surface, int filter, Color color)
-{
- if(filter == HORIZONTAL_FLIP_FILTER) {
- SDL_Surface* sur_copy = sdl_surface_from_sdl_surface(surface);
- SDL_BlitSurface(surface, NULL, sur_copy, NULL);
- SDL_SetAlpha(sur_copy,0,0);
-
- SDL_Rect src, dst;
- src.y = dst.y = 0;
- src.w = dst.w = 1;
- src.h = dst.h = sur_copy->h;
- for(int x = 0; x < sur_copy->w; x++)
- {
- src.x = x; dst.x = sur_copy->w-1 - x;
- SDL_BlitSurface(sur_copy, &src, surface, &dst);
- }
-
- SDL_FreeSurface(sur_copy);
- } else if(filter == MASK_FILTER) {
- SDL_Surface* sur_copy = sdl_surface_from_sdl_surface(surface);
-
- Uint8 r,g,b,a;
-
- SDL_LockSurface(sur_copy);
- for(int x = 0; x < sur_copy->w; x++)
- for(int y = 0; y < sur_copy->h; y++) {
- SDL_GetRGBA(getpixel(sur_copy,x,y), sur_copy->format, &r,&g,&b,&a);
- if(a != 0) {
- putpixel(sur_copy, x,y, color.map_rgba(sur_copy));
- }
- }
- SDL_UnlockSurface(sur_copy);
-
- SDL_BlitSurface(sur_copy, NULL, surface, NULL);
- SDL_FreeSurface(sur_copy);
- }
-}
-
-SDL_Surface*
-sdl_surface_part_from_file(const std::string& file, int x, int y, int w, int h)
-{
- SDL_Rect src;
- SDL_Surface * sdl_surface;
- SDL_Surface * temp;
- SDL_Surface * conv;
-
- temp = IMG_Load_RW(get_physfs_SDLRWops(file), true);
- if (temp == 0) {
- std::stringstream msg;
- msg << "Couldn't load '" << file << "': " << SDL_GetError();
- throw std::runtime_error(msg.str());
- }
-
- /* Set source rectangle for conv: */
-
- src.x = x;
- src.y = y;
- src.w = w;
- src.h = h;
-
- conv = SDL_CreateRGBSurface(SDL_SWSURFACE, w, h, temp->format->BitsPerPixel,
- temp->format->Rmask,
- temp->format->Gmask,
- temp->format->Bmask,
- temp->format->Amask);
-
- SDL_SetAlpha(temp,0,0);
-
- SDL_BlitSurface(temp, &src, conv, NULL);
- sdl_surface = SDL_DisplayFormatAlpha(conv);
-
- if (sdl_surface == NULL) {
- std::stringstream msg;
- msg << "Can't convert file '" << file << "' to display format.";
- throw std::runtime_error(msg.str());
- }
-
- SDL_FreeSurface(temp);
- SDL_FreeSurface(conv);
-
- return sdl_surface;
-}
-
-SDL_Surface*
-sdl_surface_from_file(const std::string& file)
-{
- SDL_Surface* sdl_surface;
- SDL_Surface* temp;
-
- temp = IMG_Load_RW(get_physfs_SDLRWops(file), true);
- if (temp == 0) {
- std::stringstream msg;
- msg << "Couldn't load file '" << file << "': " << SDL_GetError();
- throw std::runtime_error(msg.str());
- }
-
- sdl_surface = SDL_DisplayFormatAlpha(temp);
-
- if (sdl_surface == NULL) {
- std::stringstream msg;
- msg << "Couldn't convert file '" << file << "' to display format";
- throw std::runtime_error(msg.str());
- }
-
- SDL_FreeSurface(temp);
-
- return sdl_surface;
-}
-
-SDL_Surface*
-sdl_surface_from_sdl_surface(SDL_Surface* sdl_surf)
+Surface::hflip()
{
- SDL_Surface* sdl_surface = SDL_DisplayFormatAlpha(sdl_surf);
- if (sdl_surface == 0) {
- std::stringstream msg;
- msg << "Can't convert surface to display format.";
- throw std::runtime_error(msg.str());
- }
-
- return sdl_surface;
+ std::swap(uv_left, uv_right);
}
-SDL_Surface*
-sdl_surface_from_gradient(Color top, Color bottom, int w, int h)
+static inline void intern_draw(float left, float top, float right, float bottom, float uv_left, float uv_top,
+ float uv_right, float uv_bottom,
+ DrawingEffect effect)
{
- SDL_Surface* sdl_surface
- = SDL_CreateRGBSurface(SDL_SWSURFACE, w, h,
- screen->format->BitsPerPixel, screen->format->Rmask,
- screen->format->Gmask, screen->format->Bmask, 0);
-
- if(sdl_surface == 0)
- throw std::runtime_error("Can't create gradient surface");
-
- if(top == bottom) {
- SDL_FillRect(sdl_surface, NULL, SDL_MapRGB(sdl_surface->format,
- top.red, top.green, top.blue));
- } else {
- float redstep = (float(bottom.red)-float(top.red)) / float(h);
- float greenstep = (float(bottom.green)-float(top.green)) / float(h);
- float bluestep = (float(bottom.blue) - float(top.blue)) / float(h);
-
- SDL_Rect rect;
- rect.x = 0;
- rect.w = w;
- rect.h = 1;
- for(float y = 0; y < h; y++) {
- rect.y = (int)y;
- SDL_FillRect(sdl_surface, &rect, SDL_MapRGB(sdl_surface->format,
- int(float(top.red) + redstep * y),
- int(float(top.green) + greenstep * y),
- int(float(top.blue) + bluestep * y)));
- }
+ if(effect & HORIZONTAL_FLIP)
+ std::swap(uv_left, uv_right);
+ if(effect & VERTICAL_FLIP) {
+ std::swap(uv_top, uv_bottom);
}
-
- return sdl_surface;
-}
-
-//---------------------------------------------------------------------------
-
-SurfaceImpl::SurfaceImpl()
- : sdl_surface(0)
-{}
-
-SurfaceImpl::~SurfaceImpl()
-{
- if(sdl_surface != 0)
- SDL_FreeSurface(sdl_surface);
-}
-
-SDL_Surface* SurfaceImpl::get_sdl_surface() const
-{
- return sdl_surface;
-}
-
-SurfaceOpenGL::SurfaceOpenGL(SDL_Surface* surf)
-{
- sdl_surface = sdl_surface_from_sdl_surface(surf);
- create_gl(sdl_surface,&gl_texture);
-
- w = sdl_surface->w;
- h = sdl_surface->h;
-}
-
-SurfaceOpenGL::SurfaceOpenGL(const std::string& file)
-{
- sdl_surface = sdl_surface_from_file(file);
- create_gl(sdl_surface,&gl_texture);
-
- w = sdl_surface->w;
- h = sdl_surface->h;
-}
-
-SurfaceOpenGL::SurfaceOpenGL(const std::string& file_, int x_, int y_,
- int w_, int h_)
-{
- sdl_surface = sdl_surface_part_from_file(file_, x_, y_, w_, h_);
- create_gl(sdl_surface, &gl_texture);
- w = sdl_surface->w;
- h = sdl_surface->h;
-}
-
-SurfaceOpenGL::SurfaceOpenGL(Color top_gradient, Color bottom_gradient,
- int _w, int _h)
-{
- sdl_surface = sdl_surface_from_gradient(top_gradient, bottom_gradient,_w,_h);
- create_gl(sdl_surface, &gl_texture);
- w = sdl_surface->w;
- h = sdl_surface->h;
-}
-
-SurfaceOpenGL::~SurfaceOpenGL()
-{
- glDeleteTextures(1, &gl_texture);
-}
-
-void
-SurfaceOpenGL::create_gl(SDL_Surface * surf, GLuint * tex)
-{
- Uint32 saved_flags;
- Uint8 saved_alpha;
- int w, h;
- SDL_Surface *conv;
-
- w = power_of_two(surf->w);
- h = power_of_two(surf->h),
-
-#if SDL_BYTEORDER == SDL_BIG_ENDIAN
- conv = SDL_CreateRGBSurface(SDL_SWSURFACE, w, h, surf->format->BitsPerPixel,
- 0xff000000, 0x00ff0000, 0x0000ff00, 0x000000ff);
-#else
- conv = SDL_CreateRGBSurface(SDL_SWSURFACE, w, h, surf->format->BitsPerPixel,
- 0x000000ff, 0x0000ff00, 0x00ff0000, 0xff000000);
-#endif
-
- /* Save the alpha blending attributes */
- saved_flags = surf->flags&(SDL_SRCALPHA|SDL_RLEACCELOK);
- saved_alpha = surf->format->alpha;
- if ( (saved_flags & SDL_SRCALPHA)
- == SDL_SRCALPHA )
- {
- SDL_SetAlpha(surf, 0, 0);
- }
-
- SDL_BlitSurface(surf, 0, conv, 0);
-
- /* Restore the alpha blending attributes */
- if ( (saved_flags & SDL_SRCALPHA)
- == SDL_SRCALPHA )
- {
- SDL_SetAlpha(surf, saved_flags, saved_alpha);
- }
-
- // We check all the pixels of the surface to figure out which
- // internal format OpenGL should use for storing it, ie. if no alpha
- // is present store in RGB instead of RGBA, this saves a few bytes
- // of memory, but much more importantly it makes the game look
- // *much* better in 16bit color mode
- int internal_format = GL_RGBA;
- bool has_alpha = false;
-
- unsigned char* buf = static_cast<unsigned char*>(conv->pixels);
- for (int y = 0; y < surf->h; ++y)
- for (int x = 0; x < surf->w; ++x)
- {
- if (buf[(conv->pitch*y + x*4) + 3] != 255)
- {
- has_alpha = true;
- break;
- }
- }
-
- if (!has_alpha)
- {
- internal_format = GL_RGB;
- }
-
- glGenTextures(1, &*tex);
- glBindTexture(GL_TEXTURE_2D , *tex);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
- glPixelStorei(GL_UNPACK_ROW_LENGTH, conv->pitch / conv->format->BytesPerPixel);
- glTexImage2D(GL_TEXTURE_2D, 0, internal_format, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, conv->pixels);
- glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
-
- SDL_FreeSurface(conv);
-}
-
-int
-SurfaceOpenGL::draw(float x, float y, Uint8 alpha, Uint32 effect)
-{
- float pw = power_of_two(w);
- float ph = power_of_two(h);
-
- if(effect & SEMI_TRANSPARENT)
- alpha = 128;
-
- glEnable(GL_TEXTURE_2D);
- glEnable(GL_BLEND);
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
-
- glColor4ub(alpha, alpha, alpha, alpha);
-
- glBindTexture(GL_TEXTURE_2D, gl_texture);
-
- glBegin(GL_QUADS);
-
- if(effect & VERTICAL_FLIP & HORIZONTAL_FLIP)
- {
- glTexCoord2f(0, 0);
- glVertex2f((float)w+x, (float)h+y);
-
- glTexCoord2f((float)w / pw, 0);
- glVertex2f(x, (float)h+y);
-
- glTexCoord2f((float)w / pw, (float)h / ph);
- glVertex2f(x, y);
-
- glTexCoord2f(0, (float)h / ph);
- glVertex2f((float)w+x, y);
- }
- else if(effect & VERTICAL_FLIP)
- {
- glTexCoord2f(0, 0);
- glVertex2f(x, (float)h+y);
-
- glTexCoord2f((float)w / pw, 0);
- glVertex2f((float)w+x, (float)h+y);
-
- glTexCoord2f((float)w / pw, (float)h / ph);
- glVertex2f((float)w+x, y);
-
- glTexCoord2f(0, (float)h / ph);
- glVertex2f(x, y);
- }
- else if(effect & HORIZONTAL_FLIP)
- {
- glTexCoord2f(0, 0);
- glVertex2f((float)w+x, y);
-
- glTexCoord2f((float)w / pw, 0);
- glVertex2f(x, y);
-
- glTexCoord2f((float)w / pw, (float)h / ph);
- glVertex2f(x, (float)h+y);
-
- glTexCoord2f(0, (float)h / ph);
- glVertex2f((float)w+x, (float)h+y);
- }
- else
- {
- glTexCoord2f(0, 0);
- glVertex2f(x, y);
-
- glTexCoord2f((float)w / pw, 0);
- glVertex2f((float)w+x, y);
-
- glTexCoord2f((float)w / pw, (float)h / ph);
- glVertex2f((float)w+x, (float)h+y);
-
- glTexCoord2f(0, (float)h / ph);
- glVertex2f(x, (float)h+y);
- }
- glEnd();
-
- glDisable(GL_TEXTURE_2D);
- glDisable(GL_BLEND);
-
- return 0;
-}
-
-int
-SurfaceOpenGL::draw_part(float sx, float sy, float x, float y, float w, float h, Uint8 alpha, Uint32 effect)
-{
- float pw = power_of_two(int(this->w));
- float ph = power_of_two(int(this->h));
-
- if(effect & SEMI_TRANSPARENT)
- alpha = 128;
-
- glBindTexture(GL_TEXTURE_2D, gl_texture);
-
- glEnable(GL_BLEND);
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
-
- glColor4ub(alpha, alpha, alpha, alpha);
-
- glEnable(GL_TEXTURE_2D);
-
-
glBegin(GL_QUADS);
+ glTexCoord2f(uv_left, uv_top);
+ glVertex2f(left, top);
+
+ glTexCoord2f(uv_right, uv_top);
+ glVertex2f(right, top);
- if(effect & VERTICAL_FLIP & HORIZONTAL_FLIP)
- {
- glTexCoord2f(sx / pw, (float)(sy+h) / ph);
- glVertex2f((float)w+x, (float)h+y);
-
- glTexCoord2f((sx+w) / pw, (sy+h) / ph);
- glVertex2f(x, (float)h+y);
-
- glTexCoord2f((float)(sx + w) / pw, sy / ph);
- glVertex2f(x, y);
-
- glTexCoord2f(sx / pw, sy / ph);
- glVertex2f((float)w+x, y);
- }
- else if(effect & VERTICAL_FLIP)
- {
- glTexCoord2f(sx / pw, sy / ph);
- glVertex2f(x, y);
-
- glTexCoord2f((float)(sx + w) / pw, sy / ph);
- glVertex2f(w+x, y);
-
- glTexCoord2f((sx+w) / pw, (sy+h) / ph);
- glVertex2f(w +x, h+y);
-
- glTexCoord2f(sx / pw, (float)(sy+h) / ph);
- glVertex2f(x, h+y);
- }
- else if(effect & HORIZONTAL_FLIP)
- {
- glTexCoord2f(sx / pw, sy / ph);
- glVertex2f((float)w+x, y);
-
- glTexCoord2f((float)(sx + w) / pw, sy / ph);
- glVertex2f(x, y);
-
- glTexCoord2f((sx+w) / pw, (sy+h) / ph);
- glVertex2f(x, (float)h+y);
-
- glTexCoord2f(sx / pw, (float)(sy+h) / ph);
- glVertex2f((float)w+x, (float)h+y);
- }
- else
- {
- glTexCoord2f(sx / pw, (float)(sy+h) / ph);
- glVertex2f(x, h+y);
-
- glTexCoord2f((sx+w) / pw, (sy+h) / ph);
- glVertex2f(w +x, h+y);
-
- glTexCoord2f((float)(sx + w) / pw, sy / ph);
- glVertex2f(w+x, y);
-
- glTexCoord2f(sx / pw, sy / ph);
- glVertex2f(x, y);
- }
+ glTexCoord2f(uv_right, uv_bottom);
+ glVertex2f(right, bottom);
+ glTexCoord2f(uv_left, uv_bottom);
+ glVertex2f(left, bottom);
glEnd();
-
- glDisable(GL_TEXTURE_2D);
- glDisable(GL_BLEND);
-
- return 0;
}
-int
-SurfaceOpenGL::draw_stretched(float x, float y, int sw, int sh, Uint8 alpha, Uint32 effect)
+void
+Surface::draw(float x, float y, float alpha, DrawingEffect effect) const
{
- float pw = power_of_two(sw);
- float ph = power_of_two(sh);
+ glColor4f(1.0f, 1.0f, 1.0f, alpha);
+ glBindTexture(GL_TEXTURE_2D, texture->get_handle());
- if(effect & SEMI_TRANSPARENT)
- alpha = 128;
-
- glEnable(GL_TEXTURE_2D);
- glEnable(GL_BLEND);
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
-
- glColor4ub(alpha, alpha, alpha, alpha);
-
- glBindTexture(GL_TEXTURE_2D, gl_texture);
-
- glBegin(GL_QUADS);
-
- if(effect & VERTICAL_FLIP & HORIZONTAL_FLIP)
- {
- glTexCoord2f(0, 0);
- glVertex2f((float)sw+x, (float)sh+y);
-
- glTexCoord2f((float)w / pw, 0);
- glVertex2f(x, (float)sh+y);
-
- glTexCoord2f((float)w / pw, (float)h / ph);
- glVertex2f(x, y);
-
- glTexCoord2f(0, (float)h / ph);
- glVertex2f((float)sw+x, y);
- }
- else if(effect & VERTICAL_FLIP)
- {
- glTexCoord2f(0, 0);
- glVertex2f(x, (float)sh+y);
-
- glTexCoord2f((float)w / pw, 0);
- glVertex2f((float)sw+x, (float)sh+y);
-
- glTexCoord2f((float)w / pw, (float)h / ph);
- glVertex2f((float)sw+x, y);
-
- glTexCoord2f(0, (float)h / ph);
- glVertex2f(x, y);
- }
- else if(effect & HORIZONTAL_FLIP)
- {
- glTexCoord2f(0, 0);
- glVertex2f((float)sw+x, y);
-
- glTexCoord2f((float)w / pw, 0);
- glVertex2f(x, y);
-
- glTexCoord2f((float)w / pw, (float)h / ph);
- glVertex2f(x, (float)sh+y);
-
- glTexCoord2f(0, (float)h / ph);
- glVertex2f((float)sw+x, (float)sh+y);
- }
- else
- {
- glTexCoord2f(0, 0);
- glVertex2f(x, y);
-
- glTexCoord2f((float)w / pw, 0);
- glVertex2f((float)sw+x, y);
-
- glTexCoord2f((float)w / pw, (float)h / ph);
- glVertex2f((float)sw+x, (float)sh+y);
-
- glTexCoord2f(0, (float)h / ph);
- glVertex2f(x, (float)sh+y);
- }
- glEnd();
-
- glDisable(GL_TEXTURE_2D);
- glDisable(GL_BLEND);
-
- return 0;
+ intern_draw(x, y,
+ x + width, y + height,
+ uv_left, uv_top, uv_right, uv_bottom, effect);
}
void
-SurfaceOpenGL::apply_filter(int filter, Color color)
+Surface::draw_part(float src_x, float src_y, float dst_x, float dst_y,
+ float width, float height, float alpha,
+ DrawingEffect effect) const
{
- ::apply_filter_to_surface(sdl_surface, filter, color);
- create_gl(sdl_surface,&gl_texture);
-
- w = sdl_surface->w;
- h = sdl_surface->h;
+ float uv_width = uv_right - uv_left;
+ float uv_height = uv_bottom - uv_top;
+
+ float uv_left = this->uv_left + (uv_width * src_x) / this->width;
+ float uv_top = this->uv_top + (uv_height * src_y) / this->height;
+ float uv_right = this->uv_left + (uv_width * (src_x + width)) / this->width;
+ float uv_bottom = this->uv_top + (uv_height * (src_y + height)) / this->height;
+
+ glColor4f(1.0f, 1.0f, 1.0f, alpha);
+ glBindTexture(GL_TEXTURE_2D, texture->get_handle());
+
+ intern_draw(dst_x, dst_y,
+ dst_x + width, dst_y + height,
+ uv_left, uv_top, uv_right, uv_bottom, effect);
}
+
-// $Id: surface.h 2175 2004-11-24 19:02:49Z sik0fewl $
+// $Id$
//
// SuperTux
-// Copyright (C) 2004 Tobias Glaesser <tobi.web@gmx.de>
+// Copyright (C) 2005 Matthias Braun <matze@braunis.de>
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
// 02111-1307, USA.
-#ifndef SUPERTUX_TEXTURE_H
-#define SUPERTUX_TEXTURE_H
+#ifndef __SURFACE_HPP__
+#define __SURFACE_HPP__
#include <string>
-#include <list>
-#include <SDL.h>
-#include <GL/gl.h>
+class ImageTexture;
-#include "math/vector.hpp"
-#include "video/screen.hpp"
-
-void apply_filter_to_surface(SDL_Surface *surface, int filter, int value);
-SDL_Surface* sdl_surface_from_sdl_surface(SDL_Surface* sdl_surf);
-SDL_Surface* sdl_surface_from_nothing();
-
-class SurfaceImpl;
-class SurfaceOpenGL;
-class DrawingContext;
-
/// bitset for drawing effects
-enum {
+enum DrawingEffect {
/** Don't apply anything */
- NONE_EFFECT = 0x0000,
+ NO_EFFECT = 0x0000,
/** Draw the Surface upside down */
VERTICAL_FLIP = 0x0001,
/** Draw the Surface from left to down */
HORIZONTAL_FLIP = 0x0002,
- /** Draw the Surface with alpha equal to 128 */
- SEMI_TRANSPARENT = 0x0004
-};
-
-/// types of filters
-enum {
- HORIZONTAL_FLIP_FILTER,
- MASK_FILTER,
- NONE_FILTER
-};
-
-/** This class holds all the data necessary to construct a surface */
-class SurfaceData
-{
-public:
- enum ConstructorType { LOAD, LOAD_PART, SURFACE, GRADIENT };
- ConstructorType type;
- SDL_Surface* surface;
- std::string file;
-
- struct Filter { int type; Color color; };
- std::vector<Filter> applied_filters;
-
- bool use_alpha;
- int x;
- int y;
- int w;
- int h;
- Color top_gradient;
- Color bottom_gradient;
-
- SurfaceData(SDL_Surface* surf, bool use_alpha_);
- SurfaceData(const std::string& file_, bool use_alpha_);
- SurfaceData(const std::string& file_, int x_, int y_, int w_, int h_, bool use_alpha_);
- SurfaceData(Color top_gradient_, Color bottom_gradient_, int w_, int h_);
- ~SurfaceData();
-
- SurfaceOpenGL* create_SurfaceOpenGL();
- SurfaceImpl* create();
};
-
-/** Container class that holds a surface, necessary so that we can
- * switch Surface implementations (OpenGL, SDL) on the fly
+/**
+ * Container class that holds a surface, necessary so that we can
+ * reload Surface implementations on the fly
*/
class Surface
{
+private:
+ friend class DrawingContext;
+ friend class Font;
+ ImageTexture* texture;
+
+ float uv_left;
+ float uv_top;
+ float uv_right;
+ float uv_bottom;
+
+ void draw(float x, float y, float alpha, DrawingEffect effect) const;
+ void draw_part(float src_x, float src_y, float dst_x, float dst_y,
+ float width, float height,
+ float alpha, DrawingEffect effect) const;
+
+ float width;
+ float height;
public:
- SurfaceImpl* impl;
- SurfaceData data;
- int w;
- int h;
-
- typedef std::list<Surface*> Surfaces;
- static Surfaces surfaces;
-public:
- static void reload_all();
- static void debug_check();
-
- Surface(SDL_Surface* surf, bool use_alpha);
- Surface(const std::string& file, bool use_alpha);
- Surface(const std::string& file, int x, int y, int w, int h, bool use_alpha);
- Surface(Color top_gradient, Color bottom_gradient, int w_, int h_);
+ Surface(const std::string& file);
+ Surface(const std::string& file, int x, int y, int w, int h);
+ Surface(const Surface& other);
~Surface();
+
+ /** flip the surface horizontally */
+ void hflip();
/** Reload the surface, which is necesarry in case of a mode swich */
void reload();
-
- void apply_filter(int filter, Color color = Color(0,0,0));
-};
-/** Surface implementation, all implementation have to inherit from
- this class */
-class SurfaceImpl
-{
-protected:
- SDL_Surface* sdl_surface;
-
-public:
- int w;
- int h;
-
-public:
- SurfaceImpl();
- virtual ~SurfaceImpl();
-
- /** Return 0 on success, -2 if surface needs to be reloaded */
- virtual int draw(float x, float y, Uint8 alpha, Uint32 effect = NONE_EFFECT) = 0;
- virtual int draw_part(float sx, float sy, float x, float y, float w, float h, Uint8 alpha, Uint32 effect = NONE_EFFECT) = 0;
- virtual int draw_stretched(float x, float y, int w, int h, Uint8 alpha, Uint32 effect = NONE_EFFECT) = 0;
-
-
- SDL_Surface* get_sdl_surface() const; // @evil@ try to avoid this function
-
- virtual void apply_filter(int filter, Color color = Color(0,0,0)) = 0;
-};
+ const Surface& operator= (const Surface& other);
-class SurfaceOpenGL : public SurfaceImpl
-{
-public:
- GLuint gl_texture;
-
-public:
- SurfaceOpenGL(SDL_Surface* surf);
- SurfaceOpenGL(const std::string& file);
- SurfaceOpenGL(const std::string& file, int x, int y, int w, int h);
- SurfaceOpenGL(Color top_gradient, Color bottom_gradient, int w, int h);
-
- virtual ~SurfaceOpenGL();
-
- int draw(float x, float y, Uint8 alpha, Uint32 effect = NONE_EFFECT);
- int draw_part(float sx, float sy, float x, float y, float w, float h, Uint8 alpha, Uint32 effect = NONE_EFFECT);
- int draw_stretched(float x, float y, int w, int h, Uint8 alpha, Uint32 effect = NONE_EFFECT);
-
- void apply_filter(int filter, Color color);
-
-private:
- void create_gl(SDL_Surface * surf, GLuint * tex);
+ float get_width() const
+ {
+ return width;
+ }
+
+ float get_height() const
+ {
+ return height;
+ }
};
#endif
glDeleteTextures(1, &handle);
}
-void upload_texture(SDL_Surface* , int , int , int , int , int , int )
-{
- // TODO
- assert(false);
-}
-
void
Texture::set_texture_params()
{
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_R, GL_CLAMP);
assert_gl("set texture params");
}
#include <GL/gl.h>
/**
- * This class is a very simple wrapper around a texture handle
+ * This class is a wrapper around a texture handle. It stores the texture width
+ * and height and provides convenience functions for uploading SDL_Surfaces
+ * into the texture
*/
class Texture
{
-public:
+protected:
+ friend class TextureManager;
GLuint handle;
unsigned int width;
unsigned int height;
-
+
+public:
Texture(unsigned int width, unsigned int height, GLenum glformat);
Texture(SDL_Surface* surface, GLenum glformat);
- ~Texture();
+ virtual ~Texture();
+
+ GLuint get_handle() const
+ {
+ return handle;
+ }
+
+ unsigned int get_width() const
+ {
+ return width;
+ }
+
+ unsigned int get_height() const
+ {
+ return height;
+ }
- void upload_texture(SDL_Surface* image, int src_x, int src_y, int dst_x, int dst_y,
- int width, int height);
private:
void set_texture_params();
};
-
#endif
--- /dev/null
+#include <config.h>
+
+#include "texture_manager.hpp"
+
+#include <assert.h>
+#include <SDL.h>
+#include <SDL_image.h>
+#include <GL/gl.h>
+#include <iostream>
+#include <sstream>
+#include <stdexcept>
+#include "physfs/physfs_sdl.hpp"
+#include "image_texture.hpp"
+#include "glutil.hpp"
+
+TextureManager* texture_manager = NULL;
+
+TextureManager::TextureManager()
+{
+}
+
+TextureManager::~TextureManager()
+{
+ for(ImageTextures::iterator i = image_textures.begin();
+ i != image_textures.end(); ++i) {
+ if(i->second == NULL)
+ continue;
+#ifdef DEBUG
+ std::cerr << "Warning: Texture '" << i->first << "' not freed\n";
+#endif
+ delete i->second;
+ }
+}
+
+ImageTexture*
+TextureManager::get(const std::string& filename)
+{
+ ImageTextures::iterator i = image_textures.find(filename);
+
+ ImageTexture* texture = NULL;
+ if(i != image_textures.end())
+ texture = i->second;
+
+ if(texture == NULL) {
+ texture = create_image_texture(filename);
+ image_textures[filename] = texture;
+ }
+
+ return texture;
+}
+
+void
+TextureManager::release(ImageTexture* texture)
+{
+ image_textures[texture->filename] = NULL;
+ delete texture;
+}
+
+void
+TextureManager::register_texture(Texture* texture)
+{
+ textures.insert(texture);
+}
+
+void
+TextureManager::remove_texture(Texture* texture)
+{
+ textures.erase(texture);
+}
+
+static inline int next_power_of_two(int val)
+{
+ int result = 1;
+ while(result < val)
+ result *= 2;
+ return result;
+}
+
+ImageTexture*
+TextureManager::create_image_texture(const std::string& filename)
+{
+ SDL_Surface* image = IMG_Load_RW(get_physfs_SDLRWops(filename), 1);
+ if(image == NULL) {
+ std::ostringstream msg;
+ msg << "Couldn't load image '" << filename << "' :" << SDL_GetError();
+ throw std::runtime_error(msg.str());
+ }
+
+ int texture_w = next_power_of_two(image->w);
+ int texture_h = next_power_of_two(image->h);
+
+#if SDL_BYTEORDER == SDL_BIG_ENDIAN
+ SDL_Surface* convert = SDL_CreateRGBSurface(SDL_SWSURFACE,
+ texture_w, texture_h, 32,
+ 0xff000000, 0x00ff0000, 0x0000ff00, 0x000000ff);
+#else
+ SDL_Surface* convert = SDL_CreateRGBSurface(SDL_SWSURFACE,
+ texture_w, texture_h, 32,
+ 0x000000ff, 0x0000ff00, 0x00ff0000, 0xff000000);
+#endif
+
+ if(convert == 0)
+ throw std::runtime_error("Couldn't create texture: out of memory");
+
+ SDL_SetAlpha(image, 0, 0);
+ SDL_BlitSurface(image, 0, convert, 0);
+
+ ImageTexture* result = NULL;
+ try {
+ result = new ImageTexture(convert);
+ result->filename = filename;
+ result->image_width = image->w;
+ result->image_height = image->h;
+ } catch(...) {
+ delete result;
+ SDL_FreeSurface(convert);
+ throw;
+ }
+
+ SDL_FreeSurface(convert);
+ return result;
+}
+
+void
+TextureManager::save_textures()
+{
+ glPixelStorei(GL_PACK_ROW_LENGTH, 0);
+ glPixelStorei(GL_PACK_IMAGE_HEIGHT, 0);
+ glPixelStorei(GL_PACK_SKIP_PIXELS, 0);
+ glPixelStorei(GL_PACK_SKIP_ROWS, 0);
+ glPixelStorei(GL_PACK_SKIP_IMAGES, 0);
+ glPixelStorei(GL_PACK_ALIGNMENT, 1);
+ for(Textures::iterator i = textures.begin(); i != textures.end(); ++i) {
+ save_texture(*i);
+ }
+ for(ImageTextures::iterator i = image_textures.begin();
+ i != image_textures.end(); ++i) {
+ save_texture(i->second);
+ }
+}
+
+void
+TextureManager::save_texture(Texture* texture)
+{
+ SavedTexture saved_texture;
+ saved_texture.texture = texture;
+ glBindTexture(GL_TEXTURE_2D, texture->get_handle());
+ glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_WIDTH,
+ &saved_texture.width);
+ glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_HEIGHT,
+ &saved_texture.height);
+ glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_BORDER,
+ &saved_texture.border);
+ glGetTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
+ &saved_texture.min_filter);
+ glGetTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,
+ &saved_texture.mag_filter);
+ glGetTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S,
+ &saved_texture.wrap_s);
+ glGetTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T,
+ &saved_texture.wrap_t);
+
+ size_t pixelssize = saved_texture.width * saved_texture.height * 4;
+ saved_texture.pixels = new char[pixelssize];
+
+ glGetTexImage(GL_TEXTURE_2D, 0, GL_RGBA, GL_UNSIGNED_BYTE,
+ saved_texture.pixels);
+
+ saved_textures.push_back(saved_texture);
+
+ glDeleteTextures(1, &(texture->handle));
+ texture->handle = 0;
+
+ assert_gl("retrieving texture");
+}
+
+void
+TextureManager::reload_textures()
+{
+ glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
+ glPixelStorei(GL_UNPACK_IMAGE_HEIGHT, 0);
+ glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
+ glPixelStorei(GL_UNPACK_SKIP_ROWS, 0);
+ glPixelStorei(GL_UNPACK_SKIP_IMAGES, 0);
+ glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
+
+ for(std::vector<SavedTexture>::iterator i = saved_textures.begin();
+ i != saved_textures.end(); ++i) {
+ SavedTexture& saved_texture = *i;
+
+ GLuint handle;
+ glGenTextures(1, &handle);
+ assert_gl("creating texture handle");
+
+ glBindTexture(GL_TEXTURE_2D, handle);
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA,
+ saved_texture.width, saved_texture.height,
+ saved_texture.border, GL_RGBA,
+ GL_UNSIGNED_BYTE, saved_texture.pixels);
+ delete[] saved_texture.pixels;
+ assert_gl("uploading texture pixel data");
+
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
+ saved_texture.min_filter);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,
+ saved_texture.mag_filter);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S,
+ saved_texture.wrap_s);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T,
+ saved_texture.wrap_t);
+
+ assert_gl("setting texture_params");
+ saved_texture.texture->handle = handle;
+ }
+
+ saved_textures.clear();
+}
+
--- /dev/null
+#ifndef __IMAGE_TEXTURE_MANAGER_HPP__
+#define __IMAGE_TEXTURE_MANAGER_HPP__
+
+#include <GL/gl.h>
+#include <string>
+#include <vector>
+#include <map>
+#include <set>
+
+class Texture;
+class ImageTexture;
+
+class TextureManager
+{
+public:
+ TextureManager();
+ ~TextureManager();
+
+ ImageTexture* get(const std::string& filename);
+
+ void register_texture(Texture* texture);
+ void remove_texture(Texture* texture);
+
+ void save_textures();
+ void reload_textures();
+
+private:
+ friend class ImageTexture;
+ void release(ImageTexture* texture);
+
+ typedef std::map<std::string, ImageTexture*> ImageTextures;
+ ImageTextures image_textures;
+
+ ImageTexture* create_image_texture(const std::string& filename);
+
+ typedef std::set<Texture*> Textures;
+ Textures textures;
+
+ struct SavedTexture
+ {
+ Texture* texture;
+ int width;
+ int height;
+ char* pixels;
+ int border;
+
+ int min_filter;
+ int mag_filter;
+ int wrap_s;
+ int wrap_t;
+ };
+ std::vector<SavedTexture> saved_textures;
+
+ void save_texture(Texture* texture);
+};
+
+extern TextureManager* texture_manager;
+
+#endif
+
tux = new Tux(this);
add_object(tux);
- messagedot = new Surface("images/worldmap/common/messagedot.png", true);
- teleporterdot = new Surface("images/worldmap/common/teleporterdot.png", true);
+ messagedot = new Surface("images/worldmap/common/messagedot.png");
+ teleporterdot = new Surface("images/worldmap/common/teleporterdot.png");
name = "<no title>";
music = "salcon.ogg";