widelands-dev team mailing list archive
-
widelands-dev team
-
Mailing list archive
-
Message #00191
[Merge] lp:~nha/widelands/graphics-refactor into lp:widelands
Nicolai Hähnle has proposed merging lp:~nha/widelands/graphics-refactor into lp:widelands.
Requested reviews:
Widelands Developers (widelands-dev)
This merge contains a pretty huge refactoring that attempts to clarify the meaning of surfaces vs. pictures, and enforce it via the C++ type system.
>From now on Pictures are things that can act as blit sources, while Surfaces are things that can act as blit destinations. In SDL mode, everything is both a Picture and a Surface; in OpenGL mode, this is not the case.
As a side-effect, this also fixes the scaling of menu backgrounds in OpenGL mode.
It's a pretty huge change, which is why I didn't want to commit it immediately. Some more testing is a good idea, and I didn't want to mess with people who are playing this weekend.
--
https://code.launchpad.net/~nha/widelands/graphics-refactor/+merge/42016
Your team Widelands Developers is requested to review the proposed merge of lp:~nha/widelands/graphics-refactor into lp:widelands.
=== modified file 'src/CMakeLists.txt'
--- src/CMakeLists.txt 2010-11-07 22:42:19 +0000
+++ src/CMakeLists.txt 2010-11-27 16:29:59 +0000
@@ -54,7 +54,7 @@
add_executable (widelands ${GUI_TYPE} main.cc build_info.cc ${WIN32_ICON_O})
else (DEFINED MINGW)
add_executable (widelands ${GUI_TYPE} main.cc build_info.cc)
- endif (DEFINED MINGW)
+ endif (DEFINED MINGW)
endif (DEFINED MSVC)
add_library (widelands_all ${WL_SRCS_CC} ${WL_SRCS_H})
@@ -72,7 +72,7 @@
if (WIN32)
string(REGEX REPLACE "^.*:" "" sourcenoslash ${sourcenoslash})
endif (WIN32)
- get_filename_component(sourcename ${sourcefile} NAME)
+ get_filename_component(sourcename ${sourcefile} NAME)
set(stamp ${sourcename}_)
add_custom_command(
OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/codecheck_${sourcenoslash}"
@@ -151,7 +151,7 @@
else (DEFINED MSVC)
target_link_libraries(widelands wsock32)
- endif (DEFINED MSVC)
+ endif (DEFINED MSVC)
endif (WIN32)
install(TARGETS widelands DESTINATION ${WLBUILD_INSTALL_BINDIR} COMPONENT ExecutableFiles)
=== modified file 'src/editor/ui_menus/editor_tool_set_terrain_options_menu.cc'
--- src/editor/ui_menus/editor_tool_set_terrain_options_menu.cc 2010-11-01 22:30:23 +0000
+++ src/editor/ui_menus/editor_tool_set_terrain_options_menu.cc 2010-11-27 16:29:59 +0000
@@ -94,7 +94,7 @@
pos.y += TEXTURE_HEIGHT + vspacing();
}
- PictureID surface;
+ PictureID picture;
// If offscreen rendering is not available only the terrain (and not
// the terrain type) is shown.
@@ -102,11 +102,11 @@
// or implement offscreen rendering for opengl
if (g_gr->caps().offscreen_rendering)
{
- // create a surface for this
- surface = g_gr->create_picture_surface(64, 64);
+ OffscreenSurfacePtr offscreen = g_gr->create_offscreen_surface(64, 64);
+ picture = g_gr->get_offscreen_picture(offscreen);
// get the rendertarget for this
- RenderTarget & target = *g_gr->get_surface_renderer(surface);
+ RenderTarget target(offscreen);
// first, blit the terrain texture
target.blit
@@ -144,16 +144,16 @@
target.blit(pic, dry);
}
} else {
- surface = g_gr->get_picture
+ picture = g_gr->get_picture
(PicMod_Game,
g_gr->get_maptexture_data(world.terrain_descr(i).get_texture())
->get_texture_picture());
}
// Save this surface, so we can free it later on.
- m_surfaces.push_back(surface);
+ m_surfaces.push_back(picture);
- UI::Checkbox & cb = *new UI::Checkbox(this, pos, surface);
+ UI::Checkbox & cb = *new UI::Checkbox(this, pos, picture);
cb.set_size(TEXTURE_WIDTH + 1, TEXTURE_HEIGHT + 1);
cb.set_id(i);
cb.set_state(m_tool.is_enabled(i));
@@ -185,9 +185,8 @@
}
-Editor_Tool_Set_Terrain_Options_Menu::~Editor_Tool_Set_Terrain_Options_Menu() {
- container_iterate_const(std::vector<PictureID>, m_surfaces, i)
- g_gr->free_picture_surface(*i.current);
+Editor_Tool_Set_Terrain_Options_Menu::~Editor_Tool_Set_Terrain_Options_Menu()
+{
}
=== modified file 'src/graphic/animation_gfx.h'
--- src/graphic/animation_gfx.h 2010-11-10 20:05:21 +0000
+++ src/graphic/animation_gfx.h 2010-11-27 16:29:59 +0000
@@ -22,23 +22,22 @@
#include "animation.h"
#include "logic/widelands.h"
+#include "picture_id.h"
#include "rgbcolor.h"
-struct Surface;
-
struct AnimationGfx { /// The graphics belonging to an animation.
AnimationGfx(AnimationData const * data);
~AnimationGfx();
const Point get_hotspot() const throw () {return m_hotspot;}
- typedef std::vector<Surface *> Frames;
+ typedef std::vector<PictureID> Frames;
typedef Frames::size_type Index;
Index nr_frames() const
{
assert((*m_plrframes)[0]); return m_plrframes[0].size();
}
- Surface * get_frame
+ const PictureID & get_frame
(Index const i,
Widelands::Player_Number const player_number,
RGBColor const * const playercolor)
@@ -56,7 +55,7 @@
return m_plrframes[player_number][i];
}
- Surface * get_frame(Index const i) const {
+ const PictureID & get_frame(Index const i) const {
assert(i < nr_frames());
return m_plrframes[0][i];
}
=== added file 'src/graphic/compositemode.h'
--- src/graphic/compositemode.h 1970-01-01 00:00:00 +0000
+++ src/graphic/compositemode.h 2010-11-27 16:29:59 +0000
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2010 by the Widelands Development Team
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+#ifndef COMPOSITEMODE_H
+#define COMPOSITEMODE_H
+
+/**
+ * Defines composition operations performed while blitting.
+ */
+enum Composite {
+ /**
+ * Perform a normal blitting operation that respects the alpha
+ * channel if present.
+ */
+ CM_Normal = 0,
+
+ /**
+ * Perform a solid blit that ignores the alpha channel information.
+ */
+ CM_Solid,
+
+ /**
+ * Copy all pixel information, including alpha channel information.
+ */
+ CM_Copy
+};
+
+#endif // COMPOSITEMODE_H
=== modified file 'src/graphic/font_handler.cc'
--- src/graphic/font_handler.cc 2010-11-01 22:37:46 +0000
+++ src/graphic/font_handler.cc 2010-11-27 16:29:59 +0000
@@ -32,7 +32,6 @@
#include "rendertarget.h"
#include "surface.h"
#include "graphic/render/surface_sdl.h"
-#include "graphic/render/surface_opengl.h"
#include <SDL_image.h>
#include <SDL_ttf.h>
@@ -96,7 +95,7 @@
Align const align,
uint32_t const wrap,
Widget_Cache const widget_cache,
- PictureID & widget_cache_id,
+ PictureID * widget_cache_id,
uint32_t const caret,
bool const transparent)
{
@@ -124,20 +123,17 @@
m_cache.erase (i);
}
} else {
- //not cached, create a new surface
+ //not cached, create a new surface and cache it
ci.picture_id =
create_text_surface
(font, fg, bg, text, align, wrap, 0, caret, transparent);
- // Now cache it
- assert(ci.picture_id->surface);
g_gr->get_picture_size(ci.picture_id, ci.w, ci.h);
ci.f = &font;
m_cache.push_front (ci);
- while (m_cache.size() > CACHE_ARRAY_SIZE) {
- g_gr->free_picture_surface(m_cache.back().picture_id);
+ while (m_cache.size() > CACHE_ARRAY_SIZE)
m_cache.pop_back();
- }
+
//Set for alignment and blitting
picid = ci.picture_id;
w = ci.w;
@@ -145,16 +141,16 @@
}
} else if (widget_cache == Widget_Cache_Use) {
// Widget gave us an explicit picid.
- g_gr->get_picture_size(widget_cache_id, w, h);
- picid = widget_cache_id;
- } else { // We need to (re)create the picid for the widget.
- if (widget_cache == Widget_Cache_Update)
- g_gr->free_picture_surface(widget_cache_id);
- widget_cache_id =
+ g_gr->get_picture_size(*widget_cache_id, w, h);
+ picid = *widget_cache_id;
+ } else {
+ // We need to (re)create the picid for the widget.
+ // The old picture is freed automatically
+ *widget_cache_id =
create_text_surface
(font, fg, bg, text, align, wrap, 0, caret, transparent);
- g_gr->get_picture_size(widget_cache_id, w, h);
- picid = widget_cache_id;
+ g_gr->get_picture_size(*widget_cache_id, w, h);
+ picid = *widget_cache_id;
}
do_align(align, dstpoint.x, dstpoint.y, w, h);
dst.blit(dstpoint, picid);
@@ -347,14 +343,11 @@
TTF_SizeUTF8(&font, text_caret_pos.c_str(), &caret_x, &caret_y);
caret_x += LINE_MARGIN;
- Surface * const caret_surf =
- g_gr->get_picture_surface
- (g_gr->get_picture(PicMod_Game, "pics/caret.png"));
-
//TODO: Implement caret rendering for opengl
if (!g_opengl)
{
- upcast(SurfaceSDL, sdlsurf, caret_surf);
+ PictureID caret = g_gr->get_picture(PicMod_Game, "pics/caret.png");
+ upcast(SurfaceSDL, sdlsurf, caret.get());
assert(sdlsurf);
SDL_Surface * const caret_surf_sdl = sdlsurf->get_sdl_surface();
@@ -421,16 +414,13 @@
std::string text,
int32_t wrap,
Widget_Cache widget_cache,
- PictureID & widget_cache_id,
+ PictureID * widget_cache_id,
bool const transparent)
{
PictureID picid;
if (widget_cache == Widget_Cache_Use)
- picid = widget_cache_id;
+ picid = *widget_cache_id;
else {
- if (widget_cache == Widget_Cache_Update) {
- g_gr->free_picture_surface(widget_cache_id);
- }
std::vector<Richtext_Block> blocks;
Text_Parser p;
p.parse(text, blocks);
@@ -473,19 +463,18 @@
img_pos.x = img_surf_w;
img_pos.y = 0;
if
- (Surface * const image =
- g_gr->get_picture_surface // Not Font, but Game.
- (g_gr->get_picture(PicMod_Game, img_it->c_str())))
+ (PictureID const image =
+ g_gr->get_picture(PicMod_Game, *img_it))
{
img_surf_h =
img_surf_h < static_cast<int32_t>(image->get_h()) ?
image->get_h() : img_surf_h;
img_surf_w = img_surf_w + image->get_w();
- upcast(SurfaceSDL, sdlsurf, image);
+ upcast(SurfaceSDL, sdlsurf, image.get());
if (sdlsurf)
rend_cur_images.push_back(sdlsurf->get_sdl_surface());
-
+ // TODO fix this for OpenGL
}
}
SDL_Surface * const block_images =
@@ -701,7 +690,7 @@
convert_sdl_surface
(*join_sdl_surfaces(wrap, global_h, rend_blocks, bg),
bg, transparent);
- widget_cache_id = picid;
+ *widget_cache_id = picid;
}
dst.blit(dstpoint, picid);
}
@@ -813,11 +802,7 @@
(&surface, SDL_SRCCOLORKEY,
SDL_MapRGB(surface.format, bg.r(), bg.g(), bg.b()));
- Surface & surf = g_gr->create_surface(surface, transparent);
-
- PictureID picid = g_gr->get_picture(PicMod_Font, surf);
-
- return picid;
+ return g_gr->convert_sdl_surface_to_picture(&surface, transparent);
}
//Sets dstx and dsty to values for a specified align
@@ -846,15 +831,9 @@
/*
* Flushes the cached picture ids
*/
-void Font_Handler::flush_cache() {
- while (!m_cache.empty()) {
- g_gr->free_picture_surface (m_cache.front().picture_id);
- m_cache.pop_front();
- }
-}
-//Deletes widget controlled surface
-void Font_Handler::delete_widget_cache(PictureID const widget_cache_id) {
- g_gr->free_picture_surface(widget_cache_id);
+void Font_Handler::flush_cache()
+{
+ m_cache.clear();
}
//Inserts linebreaks into a text, so it doesn't get bigger than max_width
=== modified file 'src/graphic/font_handler.h'
--- src/graphic/font_handler.h 2010-11-05 19:36:57 +0000
+++ src/graphic/font_handler.h 2010-11-27 16:29:59 +0000
@@ -56,7 +56,7 @@
Align align = Align_CenterLeft,
uint32_t wrap = std::numeric_limits<uint32_t>::max(),
Widget_Cache widget_cache = Widget_Cache_None,
- PictureID & widget_cache_id = g_gr->get_no_picture(),
+ PictureID * widget_cache_id = 0,
uint32_t caret = std::numeric_limits<uint32_t>::max(),
bool transparent = true);
void get_size
@@ -79,7 +79,6 @@
// from the graphics code before the graphics are flushed,
// to make sure that everything is forgotten
void flush_cache();
- void delete_widget_cache(PictureID widget_cache_id);
void draw_richtext
(RenderTarget &,
RGBColor bg,
@@ -87,7 +86,7 @@
std::string text,
int32_t wrap,
Widget_Cache widget_cache = Widget_Cache_None,
- PictureID & widget_cache_id = g_gr->get_no_picture(),
+ PictureID * widget_cache_id = 0,
bool transparent = true);
void get_size_from_cache
(PictureID widget_cache_id, uint32_t & w, uint32_t & h);
=== modified file 'src/graphic/graphic.cc'
--- src/graphic/graphic.cc 2010-11-01 23:13:48 +0000
+++ src/graphic/graphic.cc 2010-11-27 16:29:59 +0000
@@ -32,11 +32,13 @@
#include "io/streamwrite.h"
#include "font_handler.h"
+#include "picture.h"
#include "rendertarget.h"
#include "texture.h"
#include "render/surface_sdl.h"
-#include "render/surface_opengl.h"
+#include "render/gl_picture_texture.h"
+#include "render/gl_surface_screen.h"
#include "logic/roadtype.h"
#include "logic/widelands_fileread.h"
@@ -50,6 +52,7 @@
#include <cstring>
#include <iostream>
+#include <boost/scoped_array.hpp>
Graphic * g_gr;
bool g_opengl;
@@ -74,8 +77,6 @@
m_update_fullscreen(false),
m_roadtextures (0)
{
- m_picturemap.resize(MaxModule);
-
// Initialize the table used to create grayed pictures
for
(uint32_t i = 0, r = 0, g = 0, b = 0;
@@ -150,9 +151,7 @@
log("Graphics: FULLSCREEN ENABLED\n");
// Set rendering capabilities for sdl. They are overwritten if in opengl mode
- m_caps.resize_surfaces = true;
m_caps.offscreen_rendering = true;
- m_caps.blit_resized = false;
#ifdef USE_OPENGL
if (0 != (sdlsurface->flags & SDL_OPENGL)) {
@@ -199,9 +198,7 @@
(m_caps.gl.tex_power_of_two?"must have a size power of two\n":
"may have any size\n");
- m_caps.resize_surfaces = false;
m_caps.offscreen_rendering = false;
- m_caps.blit_resized = true;
}
#endif
@@ -280,13 +277,16 @@
}
if (g_opengl)
- m_screen = new SurfaceOpenGL(w, h);
+ {
+ m_screen.reset(new GLSurfaceScreen(w, h));
+ }
else
#endif
{
- m_screen = new SurfaceSDL(*sdlsurface);
+ boost::shared_ptr<SurfaceSDL> screen(new SurfaceSDL(*sdlsurface));
+ screen->set_isscreen(true);
+ m_screen = screen;
}
- m_screen->set_type(SURFACE_SCREEN);
m_sdl_screen = sdlsurface;
m_rendertarget = new RenderTarget(m_screen);
@@ -297,12 +297,11 @@
*/
Graphic::~Graphic()
{
- for (size_t i = 1; i < m_picturemap.size(); ++i)
- flush(static_cast<PicMod>(i));
-
delete m_rendertarget;
- delete m_screen;
delete m_roadtextures;
+
+ // Remove traces of cached pictures
+ UI::g_fh->flush_cache();
}
/**
@@ -401,33 +400,27 @@
}
/**
- * Remove all resources (currently pictures) from the given modules.
- * \note flush(0) does nothing <- obviously wrong it deletes a lot!
-*/
-void Graphic::flush(PicMod const module) {
- // Flush pictures
-
- //pmit b, e = m_picturemap.end();
- for (size_t i = 0; i < m_picturemap.size(); ++i) {
- if (static_cast<PicMod>(i) == module) {
- m_picturemap[i].clear();
- }
- }
-
- if (!module || module & PicMod_Game) {
- container_iterate_const(std::vector<Texture *>, m_maptextures, i)
- delete *i.current;
- m_maptextures.clear();
-
- container_iterate_const(std::vector<AnimationGfx *>, m_animations, i)
- delete *i.current;
- m_animations.clear();
-
- delete m_roadtextures;
- m_roadtextures = 0;
- }
-
- if (not module or module & PicMod_UI) // Flush the cached Fontdatas
+ * Clear all cached resources from the given module.
+ *
+ * \note This only removes the cache entries. If the corresonding resources
+ * are still in use somewhere, they will not be freed.
+ */
+void Graphic::flush(PicMod const module)
+{
+ std::vector<std::string> eraselist;
+
+ for (pmit it = m_picturemap.begin(); it != m_picturemap.end(); ++it) {
+ it->second.modules &= ~(1 << module);
+ if (!it->second.modules)
+ eraselist.push_back(it->first);
+ }
+
+ while (!eraselist.empty()) {
+ m_picturemap.erase(eraselist.back());
+ eraselist.pop_back();
+ }
+
+ if (module == PicMod_UI) // Flush the cached Fontdatas
UI::g_fh->flush_cache();
}
@@ -440,7 +433,7 @@
}
-Surface & Graphic::load_image(std::string const & fname, bool const alpha) {
+PictureID Graphic::load_image(std::string const & fname, bool const alpha) {
//log("Graphic::LoadImage(\"%s\")\n", fname.c_str());
FileRead fr;
SDL_Surface * sdlsurf;
@@ -453,9 +446,7 @@
if (!sdlsurf)
throw wexception("%s", IMG_GetError());
- Surface & surf = create_surface(*sdlsurf, alpha);
-
- return surf;
+ return convert_sdl_surface_to_picture(sdlsurf, alpha);
}
/**
@@ -465,171 +456,192 @@
*
* \return 0 (a null-picture) if the picture cannot be loaded.
*/
-PictureID & Graphic::get_picture
+const PictureID & Graphic::get_picture
(PicMod const module, const std::string & fname, bool alpha)
{
// Check if the picture is already loaded.
- pmit it = m_picturemap[module].find(fname);
+ pmit it = m_picturemap.find(fname);
- if (it != m_picturemap[module].end()) {
- return it->second;
- } else {
- Surface * surf;
+ if (it == m_picturemap.end()) {
+ PictureRec rec;
try {
- surf = &load_image(fname, alpha);
+ rec.picture = load_image(fname, alpha);
//log("Graphic::get_picture(): loading picture '%s'\n", fname.c_str());
} catch (std::exception const & e) {
log("WARNING: Could not open %s: %s\n", fname.c_str(), e.what());
return get_no_picture();
}
- // Convert the surface accordingly
-
- // Fill in a free slot in the pictures array
- Picture & pic = * new Picture();
- PictureID id = PictureID(&pic);
- m_picturemap[module].insert(std::make_pair(fname, id));
-
- assert(pic.fname == 0);
- pic.fname = strdup(fname.c_str());
-
- // FIXME no proper check for NULL return value!
- assert(pic.fname != 0);
-
- pic.surface = surf;
-
- it = m_picturemap[module].find(fname);
+
+ it = m_picturemap.insert(std::make_pair(fname, rec)).first;
}
- it->second->module = module;
-
- return it->second;
-}
-
-PictureID Graphic::get_picture
- (PicMod const module, Surface & surf, std::string const & fname)
-{
- Picture & pic = * new Picture();
- PictureID id = PictureID(&pic);
- m_picturemap[module].insert(std::make_pair(fname, id));
-
- pic.module = module;
- pic.surface = &surf;
-
- if (fname.size() != 0) {
- assert(pic.fname == 0);
- pic.fname = strdup(fname.c_str());
- } else
- pic.fname = 0;
-
- //return m_picturemap.find(fname);
- return id;
-}
-
-PictureID & Graphic::get_no_picture() const {
- static PictureID invalid = PictureID(new Picture());
- return invalid;
+ it->second.modules |= 1 << module;
+ return it->second.picture;
+}
+
+/**
+ * Add the given picture to the cache under the given name.
+ *
+ * This overwrites pre-existing cache entries, if any.
+ */
+void Graphic::add_picture_to_cache(PicMod module, const std::string & name, PictureID pic)
+{
+ PictureRec rec;
+ rec.picture = pic;
+ rec.modules = 1 << module;
+ m_picturemap.insert(std::make_pair(name, rec));
+}
+
+/**
+ * \return an empty, invalid, null picture
+ */
+const PictureID & Graphic::get_no_picture() const
+{
+ return IPicture::null();
}
/**
* Produces a resized version of the specified picture
*
- * This might not work with the renderer. Check g_gr->caps().resize_surfaces
- * to be sure the resizing is possible.
* Might return same id if dimensions are the same
*/
PictureID Graphic::get_resized_picture
- (PictureID index,
+ (PictureID src,
uint32_t const w, uint32_t const h,
ResizeMode const mode)
{
- // Resizing is not possible with opengl surfaces
- if (g_opengl)
- g_gr->get_no_picture();
-
- Surface * const orig = index->surface;
- if (orig->get_w() == w and orig->get_h() == h)
- return index;
-
- uint32_t width = w;
- uint32_t height = h;
-
- if (mode != ResizeMode_Loose) {
- const double ratio_x = double(w) / orig->get_w();
- const double ratio_y = double(h) / orig->get_h();
-
- // if proportions are to be kept, recalculate width and height
- if ((ratio_x - ratio_y) > 0.00001) { // if not equal
- double ratio = 0;
-
- if (ResizeMode_Clip == mode)
- ratio = std::max (ratio_x, ratio_y);
- else if (ResizeMode_LeaveBorder == mode)
- ratio = std::max (ratio_x, ratio_y);
- else // average
- ratio = (ratio_x + ratio_y) / 2;
-
- width = uint32_t(orig->get_w() * ratio);
- height = uint32_t(orig->get_h() * ratio);
+ if (src->get_w() == w and src->get_h() == h)
+ return src;
+
+ // First step: compute scaling factors
+ Rect srcrect;
+ Rect destrect;
+
+ if (mode == ResizeMode_Loose) {
+ srcrect = Rect(Point(0, 0), src->get_w(), src->get_h());
+ destrect = Rect(Point(0, 0), w, h);
+ } else {
+ const double ratio_x = double(w) / src->get_w();
+ const double ratio_y = double(h) / src->get_h();
+ double ratio;
+
+ if (ResizeMode_Clip == mode)
+ ratio = std::max(ratio_x, ratio_y);
+ else if (ResizeMode_LeaveBorder == mode)
+ ratio = std::min(ratio_x, ratio_y);
+ else // average
+ ratio = (ratio_x + ratio_y) / 2;
+
+ uint32_t fullwidth(src->get_w() * ratio);
+ uint32_t fullheight(src->get_h() * ratio);
+
+ if (fullwidth <= w) {
+ srcrect.x = 0;
+ srcrect.w = src->get_w();
+ destrect.x = (w - fullwidth) / 2;
+ destrect.w = fullwidth;
+ } else {
+ srcrect.w = std::min(src->get_w(), uint32_t(w / ratio));
+ srcrect.x = (src->get_w() - srcrect.w) / 2;
+ destrect.x = 0;
+ destrect.w = w;
+ }
+
+ if (fullheight <= h) {
+ srcrect.y = 0;
+ srcrect.h = src->get_h();
+ destrect.y = (h - fullheight) / 2;
+ destrect.h = fullheight;
+ } else {
+ srcrect.h = std::min(src->get_h(), uint32_t(h / ratio));
+ srcrect.y = (src->get_h() - srcrect.h) / 2;
+ destrect.y = 0;
+ destrect.h = h;
}
}
- PictureID pic = g_gr->create_picture_surface(w, h);
+ // Second step: get source material
+ SDL_Surface * srcsdl = 0;
+ bool free_source = true;
- if (mode == ResizeMode_Loose || (width == w && height == h)) {
- if (g_opengl)
+ if (upcast(SurfaceSDL, srcsurf, src.get())) {
+ if
+ (srcrect.x != 0 || srcrect.w != uint32_t(srcsurf->get_w()) ||
+ srcrect.y != 0 || srcrect.h != uint32_t(srcsurf->get_h()))
{
+ const SDL_PixelFormat & fmt = *srcsurf->get_sdl_surface()->format;
+ srcsdl = SDL_CreateRGBSurface
+ (SDL_SWSURFACE, srcrect.w, srcrect.h,
+ fmt.BitsPerPixel, fmt.Rmask, fmt.Gmask, fmt.Bmask, fmt.Amask);
+ SDL_Rect srcrc = {srcrect.x, srcrect.y, srcrect.w, srcrect.h};
+ SDL_Rect dstrc = {0, 0, 0, 0};
+ SDL_BlitSurface(srcsurf->get_sdl_surface(), &srcrc, srcsdl, &dstrc);
} else {
- dynamic_cast<SurfaceSDL *>
- (pic->surface)->set_sdl_surface(*resize(index, w, h));
+ srcsdl = srcsurf->get_sdl_surface();
+ free_source = false;
}
} else {
- SurfaceSDL src(*resize(index, width, height));
-
- // apply rectangle by adjusted size
- Rect srcrc;
- srcrc.w = std::min(w, width);
- srcrc.h = std::min(h, height);
- srcrc.x = (width - srcrc.w) / 2;
- srcrc.y = (height - srcrc.h) / 2;
-
-
- g_gr->get_surface_renderer(pic)->blitrect // Get the rendertarget
- (Point((w - srcrc.w) / 2, (h - srcrc.h) / 2),
- get_picture(index->module, src), srcrc);
- }
- return pic;
+ srcsdl = extract_sdl_surface(src->pixelaccess(), srcrect);
+ }
+
+ // Third step: perform the zoom and placement
+ SDL_Surface * zoomed = zoomSurface
+ (srcsdl, double(destrect.w) / srcsdl->w, double(destrect.h) / srcsdl->h, 1);
+ if (free_source)
+ SDL_FreeSurface(srcsdl);
+
+ if (uint32_t(zoomed->w) != w || uint32_t(zoomed->h) != h) {
+ const SDL_PixelFormat & fmt = *zoomed->format;
+ SDL_Surface * placed = SDL_CreateRGBSurface
+ (SDL_SWSURFACE, w, h,
+ fmt.BitsPerPixel, fmt.Rmask, fmt.Gmask, fmt.Bmask, fmt.Amask);
+ SDL_Rect srcrc = {0, 0, zoomed->w, zoomed->h};
+ SDL_Rect dstrc = {destrect.x, destrect.y};
+ SDL_BlitSurface(zoomed, &srcrc, placed, &dstrc);
+ SDL_FreeSurface(zoomed);
+ zoomed = placed;
+ }
+
+ return convert_sdl_surface_to_picture(zoomed);
}
/**
- * Produces a resized version of the specified picture. This works only for
- * SDL rendering. Check g_gr->caps().resize_surfaces before calling this
- * function.
- *
- * \param index position of the source picture in the stack
- * \param w target width
- * \param h target height
- * \return resized version of picture
+ * Create and return an \ref SDL_Surface that contains the given sub-rectangle
+ * of the given pixel region.
*/
-SDL_Surface * Graphic::resize
- (const PictureID index, uint32_t const w, uint32_t const h)
+SDL_Surface * Graphic::extract_sdl_surface(IPixelAccess & pix, Rect srcrect)
{
- Surface & orig = *g_gr->get_picture_surface(index);
-
- if (g_opengl)
- throw wexception("Graphic::resize() not yet implemented for opengl");
- else
- {
- SurfaceSDL & origsdl = dynamic_cast<SurfaceSDL &>(orig);
- return
- zoomSurface
- (origsdl.get_sdl_surface(),
- double(w) / orig.get_w(), double(h) / orig.get_h(),
- 1);
+ assert(srcrect.x >= 0);
+ assert(srcrect.y >= 0);
+ assert(srcrect.x + srcrect.w <= pix.get_w());
+ assert(srcrect.y + srcrect.h <= pix.get_h());
+
+ const SDL_PixelFormat & fmt = pix.format();
+ SDL_Surface * dest = SDL_CreateRGBSurface
+ (SDL_SWSURFACE, srcrect.w, srcrect.h,
+ fmt.BitsPerPixel, fmt.Rmask, fmt.Gmask, fmt.Bmask, fmt.Amask);
+
+ pix.lock(IPixelAccess::Lock_Normal);
+ SDL_LockSurface(dest);
+
+ uint32_t srcpitch = pix.get_pitch();
+ uint32_t rowsize = srcrect.w * fmt.BytesPerPixel;
+ uint8_t * srcpix = pix.get_pixels() + srcpitch * srcrect.y + fmt.BytesPerPixel * srcrect.x;
+ uint8_t * dstpix = static_cast<uint8_t *>(dest->pixels);
+
+ for (uint32_t y = 0; y < srcrect.h; ++y) {
+ memcpy(dstpix, srcpix, rowsize);
+ srcpix += srcpitch;
+ dstpix += dest->pitch;
}
+
+ SDL_UnlockSurface(dest);
+ pix.unlock(IPixelAccess::Unlock_NoChange);
+
+ return dest;
}
-
/**
* Stores the picture size in pw and ph.
* Throws an exception if the picture doesn't exist.
@@ -637,20 +649,27 @@
void Graphic::get_picture_size
(const PictureID & pic, uint32_t & w, uint32_t & h) const
{
- assert (pic->surface);
- Surface & bmp = *pic->surface;
-
- w = bmp.get_w();
- h = bmp.get_h();
-}
-
-/**
- * Saves a surface to a png. This can be a file or part of a stream.
+ w = pic->get_w();
+ h = pic->get_h();
+}
+
+/**
+ * This is purely a convenience function intended to allow casting
+ * pointers without including a whole bunch of headers.
+ */
+PictureID Graphic::get_offscreen_picture(OffscreenSurfacePtr surface) const
+{
+ return surface;
+}
+
+
+/**
+ * Saves a pixel region to a png. This can be a file or part of a stream.
*
* @param surf The Surface to save
* @param sw a StreamWrite where the png is written to
*/
-void Graphic::save_png(Surface & surf, StreamWrite * sw) const
+void Graphic::save_png(IPixelAccess & pix, StreamWrite * sw) const
{
// Save a png
png_structp png_ptr =
@@ -686,7 +705,7 @@
// Fill info struct
png_set_IHDR
- (png_ptr, info_ptr, surf.get_w(), surf.get_h(),
+ (png_ptr, info_ptr, pix.get_w(), pix.get_h(),
8, PNG_COLOR_TYPE_RGB_ALPHA, PNG_INTERLACE_NONE,
PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
@@ -701,64 +720,31 @@
png_set_packing(png_ptr);
{
- uint32_t surf_w = surf.get_w();
- uint32_t surf_h = surf.get_h();
+ uint32_t surf_w = pix.get_w();
+ uint32_t surf_h = pix.get_h();
uint32_t row_size = 4 * surf_w;
- png_bytep rowb = 0;
- png_bytep rowp = 0;
+ boost::scoped_array<png_byte> row(new png_byte[row_size]);
//Write each row
- SDL_PixelFormat * fmt;
- upcast(SurfaceSDL, sdlsurf, &surf);
-#ifdef USE_OPENGL
- upcast(SurfaceOpenGL, oglsurf, &surf);
-#endif
- if (sdlsurf)
- {
- fmt = const_cast<SDL_PixelFormat *>(&sdlsurf->format());
- rowb = (new png_byte[row_size]);
- if (!rowb)
- throw wexception("Out of memory.");
- }
-#ifdef USE_OPENGL
- else if (oglsurf) {
- oglsurf->lock();
- fmt = 0;
- }
-#endif
- else
- return;
-
+ const SDL_PixelFormat & fmt = pix.format();
+ pix.lock(IPixelAccess::Lock_Normal);
// Write each row
for (uint32_t y = 0; y < surf_h; ++y) {
- rowp = rowb;
- if (sdlsurf)
- for (uint32_t x = 0; x < surf_w; rowp += 4, ++x)
- SDL_GetRGBA
- (sdlsurf->get_pixel(x, y),
- fmt,
- rowp + 0, rowp + 1, rowp + 2, rowp + 3);
-#ifdef USE_OPENGL
- else if (oglsurf) {
- rowb = static_cast<png_bytep>
- (oglsurf->get_pixels() +
- oglsurf->get_pitch() * (surf_h - y - 1));
+ for (uint32_t x = 0; x < surf_w; ++x) {
+ RGBAColor color;
+ color.set(fmt, pix.get_pixel(x, y));
+ row[4 * x] = color.r;
+ row[4 * x + 1] = color.g;
+ row[4 * x + 2] = color.b;
+ row[4 * x + 3] = color.a;
}
-#endif
- else
- throw wexception("Try to save save_png with unknown surface\n");
- png_write_row(png_ptr, rowb);
+ png_write_row(png_ptr, row.get());
}
-#ifdef USE_OPENGL
- if (oglsurf)
- oglsurf->unlock();
- else
-#endif
- if (sdlsurf)
- delete rowb;
+
+ pix.unlock(IPixelAccess::Unlock_NoChange);
}
// End write
@@ -767,267 +753,175 @@
}
/**
-* Saves a PictureID to a png. This can be a file or part of a stream. This
-* function retrieves the Surface for the PictureID and calls
-* save_png(Surface, StreamWrite)
-*
-* @param surf The Surface to save
-* @param sw a StreamWrite where the png is written to
-*/
+ * Saves a surface to a png. This can be a file or part of a stream.
+ *
+ * @param surf The Surface to save
+ * @param sw a StreamWrite where the png is written to
+ */
+void Graphic::save_png(SurfacePtr surf, StreamWrite * sw) const
+{
+ save_png(surf->pixelaccess(), sw);
+}
+
+/**
+ * Saves a PictureID to a png. This can be a file or part of a stream. This
+ * function retrieves the Surface for the PictureID and calls
+ * save_png(Surface, StreamWrite)
+ *
+ * @param surf The Surface to save
+ * @param sw a StreamWrite where the png is written to
+ */
void Graphic::save_png(const PictureID & pic_index, StreamWrite * sw) const
{
- Surface & surf = const_cast<Surface &>(*get_picture_surface(pic_index));
- save_png(surf, sw);
-}
-
-/**
- * Create a offscreen surface of specified size and return as PictureID.
- * The surface is put into a normal slot in the picture array so the surface
- * can be used in normal blit() operations. A RenderTarget for the surface can
- * be obtained using get_surface_renderer().
- * \note Surfaces do not belong to a module and must be freed explicitly.
- *
- * @param w width of the new surface
- * @param h height of the new surface
- * @param alpha if true the surface is created with alpha channel
- * @return PictureID of the new created offscreen surface
-*/
-PictureID Graphic::create_picture_surface(int32_t w, int32_t h, bool alpha)
-{
- //log(" Graphic::create_picture_surface(%d, %d)\n", w, h);
- Surface & surf = create_surface(w, h, alpha);
-
- Picture & pic = *new Picture();
- PictureID id = PictureID(&pic);
- m_picturemap[PicSurface].insert(std::make_pair("", id));
-
- pic.module = PicSurface; // mark as surface
- pic.surface = &surf;
- assert(pic.rendertarget == 0);
- pic.rendertarget = new RenderTarget(pic.surface);
-
- return id;
-}
-
-/**
- * Create a Surface from a SDL_Surface. This creates a Surface for OpenGL or
- * Software rendering depending on the actual setting. The SDL_Surface must
- * not be used after calling this. Surface takes care of the SDL_Surface.
- *
- * @param surf a SDL_Surface from which the Surface will be created
+ save_png(pic_index->pixelaccess(), sw);
+}
+
+/**
+ * Create a Picture from an SDL_Surface.
+ *
+ * @param surf a SDL_Surface from which the Surface will be created; this function
+ * takes ownership of surf
* @param alpha if true the surface is created with alpha channel
* @return the new Surface created from the SDL_Surface
*/
-Surface & Graphic::create_surface(SDL_Surface & surf, bool alpha)
+PictureID Graphic::convert_sdl_surface_to_picture(SDL_Surface * surf, bool alpha)
{
if (g_opengl)
{
#ifdef USE_OPENGL
- return *new SurfaceOpenGL(surf);
+ return PictureID(new GLPictureTexture(surf));
#endif
} else {
SDL_Surface * surface;
if (alpha)
- surface = SDL_DisplayFormatAlpha(&surf);
- else
- surface = SDL_DisplayFormat(&surf);
- SDL_FreeSurface(&surf);
- return *new SurfaceSDL(*surface);
- }
-}
-
-/**
-* Create a Surface from an other Surface. This makes a copy of a Surface.
-*
-* @param surf the surface which will be copied to the new surface
-* @param alpha if true the surface is created with alpha channel
-* @return the new Surface
-*/
-Surface & Graphic::create_surface(Surface & surf, bool alpha)
-{
- upcast(SurfaceSDL, sdlsurf, &surf);
- if (sdlsurf)
- {
- if (alpha)
- return
- *new SurfaceSDL
- (*SDL_DisplayFormatAlpha(sdlsurf->get_sdl_surface()));
- else
- return
- *new SurfaceSDL
- (*SDL_DisplayFormat(sdlsurf->get_sdl_surface()));
- }
- else
- {
- Surface & tsurf = create_surface(surf.get_w(), surf.get_h());
-
- surf.lock();
- tsurf.lock();
- for (unsigned int x = 0; x < surf.get_w(); x++)
- for (unsigned int y = 0; y < surf.get_h(); y++)
- {
- tsurf.set_pixel(x, y, surf.get_pixel(x, y));
- }
- surf.unlock();
- tsurf.unlock();
-
- return tsurf;
- }
-}
-
-/**
-* Create a empty offscreen surface of specified size.
-*
-* @param w width of the new surface
-* @param h height of the new surface
-* @param alpha if true the surface is created with alpha channel
-* @return the new created surface
-*/
-Surface & Graphic::create_surface(int32_t w, int32_t h, bool alpha)
-{
- if (g_opengl)
- {
-#ifdef USE_OPENGL
- return *new SurfaceOpenGL(w, h);
-#endif
- } else {
- const SDL_PixelFormat & format = m_screen->format();
- SDL_Surface & tsurf = *SDL_CreateRGBSurface
- (SDL_SWSURFACE,
- w, h,
- format.BitsPerPixel,
- format.Rmask, format.Gmask, format.Bmask, format.Amask);
- if (alpha) {
- SDL_Surface & surf = *SDL_DisplayFormatAlpha(&tsurf);
- SDL_FreeSurface(&tsurf);
- return *new SurfaceSDL(surf);
- }
- return *new SurfaceSDL(tsurf);
- }
-}
-
-/**
- * Free the given surface.
- * Unlike normal pictures, surfaces are not freed by flush().
- *
- * @param picid the PictureID ot to be freed
-*/
-void Graphic::free_picture_surface(const PictureID & picid) {
- if
- (picid->module != PicMod_Font &&
- picid->module != PicSurface)
- {
- log
- ("Graphic::free_surface ignoring free of %u %s\n",
- picid->module, picid->fname);
- return;
- }
- assert(picid->module == PicMod_Font || picid->module == PicSurface);
-
- delete picid->surface;
- picid->surface = 0;
- delete picid->rendertarget;
- picid->rendertarget = 0;
- delete picid->fname;
- picid->fname = 0;
-
- container_iterate(Picturemap, m_picturemap[picid->module], it)
- if (it.current->second == picid) {
- m_picturemap[picid->module].erase(it.current);
- break;
- }
-}
-
-/**
-* create a grayed version.
-*
-* @param picid the PictureID ot to grayed out
-* @return the gray version of the picture
-*/
-PictureID Graphic::create_grayed_out_pic(const PictureID & picid) {
- if (picid != get_no_picture()) {
- Surface & s = create_surface(*get_picture_surface(picid), true);
-#ifdef USE_OPENGL
- upcast(SurfaceOpenGL, gl_dest, &s);
- upcast(SurfaceOpenGL, gl_src, get_picture_surface(picid));
-#endif
- upcast(SurfaceSDL, sdl_s, &s);
- SDL_PixelFormat const * format = 0;
- if (sdl_s)
- format = &(sdl_s->format());
- uint32_t const w = s.get_w(), h = s.get_h();
-#ifdef USE_OPENGL
- if (gl_src)
- gl_src->lock();
-#endif
- s.lock();
- for (uint32_t y = 0; y < h; ++y)
- for (uint32_t x = 0; x < w; ++x) {
- uint8_t r, g, b, a;
-#ifdef USE_OPENGL
- if (gl_src)
- {
- uint32_t pixel = gl_src->get_pixel(x, y);
- r = pixel & 0xFF;
- g = (pixel & 0xFF00) >> 8;
- b = (pixel & 0xFF0000) >> 16;
- a = (pixel & 0xFF000000) >> 24;
- } else
-#endif
- // FIXME need for const_cast is SDL bug #421
- SDL_GetRGBA
- (sdl_s->get_pixel(x, y),
- const_cast<SDL_PixelFormat *>(format), &r, &g, &b, &a);
-
- // Halve the opacity to give some difference for pictures that are
- // grayscale to begin with.
- a >>= 1;
-
- uint8_t const gray =
- (luminance_table_r[r] +
- luminance_table_g[g] +
- luminance_table_b[b] +
- 8388608U) // compensate for truncation: .5 * 2^24
- >> 24;
-
- // NOTE const_cast is needed for SDL-1.2 older than revision 3008
-#ifdef USE_OPENGL
- if (gl_dest)
- {
- gl_dest->set_pixel(x, y, g + (g << 8) + (g << 16) + (a << 24));
- } else
-#endif
- sdl_s->set_pixel
- (x, y,
- SDL_MapRGBA
- (const_cast<SDL_PixelFormat *>(format),
- gray, gray, gray, a));
-
- }
- s.unlock();
-#ifdef USE_OPENGL
- if (gl_src)
- gl_src->unlock();
-#endif
- return get_picture(PicSurface, s);
- } else
+ surface = SDL_DisplayFormatAlpha(surf);
+ else
+ surface = SDL_DisplayFormat(surf);
+ SDL_FreeSurface(surf);
+ return PictureID(new SurfaceSDL(*surface));
+ }
+}
+
+/**
+ * Create a empty offscreen surface of specified size.
+ *
+ * @param w width of the new surface
+ * @param h height of the new surface
+ * @param alpha if true the surface is created with alpha channel
+ * @return the new created surface
+ */
+OffscreenSurfacePtr Graphic::create_offscreen_surface(int32_t w, int32_t h, bool alpha)
+{
+#ifdef USE_OPENGL
+ if (g_opengl)
+ {
+
+ throw wexception("OpenGL mode does not support offscreen surfaces");
+ }
+ else
+#endif
+ {
+ const SDL_PixelFormat & format = *m_sdl_screen->format;
+ SDL_Surface & tsurf = *SDL_CreateRGBSurface
+ (SDL_SWSURFACE,
+ w, h,
+ format.BitsPerPixel,
+ format.Rmask, format.Gmask, format.Bmask, format.Amask);
+ if (alpha) {
+ SDL_Surface & surf = *SDL_DisplayFormatAlpha(&tsurf);
+ SDL_FreeSurface(&tsurf);
+ return OffscreenSurfacePtr(new SurfaceSDL(surf));
+ }
+ return OffscreenSurfacePtr(new SurfaceSDL(tsurf));
+ }
+}
+
+/**
+ * Create a picture with initially undefined contents.
+ *
+ * Use \ref IPicture::pixelaccess to upload image data afterwards.
+ *
+ * @param w width of the new surface
+ * @param h height of the new surface
+ * @param alpha if true the surface is created with alpha channel
+ * @return the new created surface
+ */
+PictureID Graphic::create_picture(int32_t w, int32_t h, bool alpha)
+{
+#ifdef USE_OPENGL
+ if (g_opengl)
+ {
+ return PictureID(new GLPictureTexture(w, h));
+ }
+ else
+#endif
+ {
+ const SDL_PixelFormat & format = *m_sdl_screen->format;
+ SDL_Surface & tsurf = *SDL_CreateRGBSurface
+ (SDL_SWSURFACE,
+ w, h,
+ format.BitsPerPixel,
+ format.Rmask, format.Gmask, format.Bmask, format.Amask);
+ if (alpha) {
+ SDL_Surface & surf = *SDL_DisplayFormatAlpha(&tsurf);
+ SDL_FreeSurface(&tsurf);
+ return OffscreenSurfacePtr(new SurfaceSDL(surf));
+ }
+ return PictureID(new SurfaceSDL(tsurf));
+ }
+}
+
+
+/**
+ * Create a grayed version of the given picture.
+ *
+ * @param picid the PictureID ot to grayed out
+ * @return the gray version of the picture
+ */
+PictureID Graphic::create_grayed_out_pic(const PictureID & picid)
+{
+ if (!picid || !picid->valid())
return get_no_picture();
-}
-
-
-/**
- * Returns the RenderTarget for the given surface
-*/
-RenderTarget * Graphic::get_surface_renderer(const PictureID & pic) {
- //assert(pic < m_pictures.size());
- // assert(m_pictures[pic].module == 0xff); fails showing terrains in editor
-
- RenderTarget & rt = *pic->rendertarget;
-
- rt.reset();
-
- return &rt;
-}
+
+ IPixelAccess & origpix = picid->pixelaccess();
+ uint32_t w = picid->get_w();
+ uint32_t h = picid->get_h();
+ const SDL_PixelFormat & origfmt = origpix.format();
+
+ PictureID destpicture = create_picture(w, h, origfmt.Amask);
+ IPixelAccess & destpix = destpicture->pixelaccess();
+ const SDL_PixelFormat & destfmt = destpix.format();
+
+ origpix.lock(IPixelAccess::Lock_Normal);
+ destpix.lock(IPixelAccess::Lock_Discard);
+ for (uint32_t y = 0; y < h; ++y) {
+ for (uint32_t x = 0; x < w; ++x) {
+ RGBAColor color;
+
+ color.set(origfmt, origpix.get_pixel(x, y));
+
+ // Halve the opacity to give some difference for pictures that are
+ // grayscale to begin with.
+ color.a >>= 1;
+
+ uint8_t const gray =
+ (luminance_table_r[color.r] +
+ luminance_table_g[color.g] +
+ luminance_table_b[color.b] +
+ 8388608U) // compensate for truncation: .5 * 2^24
+ >> 24;
+
+ color.r = color.g = color.b = gray;
+
+ destpix.set_pixel(x, y, color.map(destfmt));
+ }
+ }
+ origpix.unlock(IPixelAccess::Unlock_NoChange);
+ destpix.unlock(IPixelAccess::Unlock_Update);
+
+ return destpicture;
+}
+
/**
* Creates a terrain texture.
@@ -1046,7 +940,7 @@
{
try {
m_maptextures.push_back
- (new Texture(fnametempl, frametime, m_screen->format()));
+ (new Texture(fnametempl, frametime, *m_sdl_screen->format));
} catch (std::exception const & e) {
log("Failed to load maptexture %s: %s\n", &fnametempl, e.what());
return 0;
@@ -1123,10 +1017,10 @@
w = h = 0;
} else {
// Get the frame and its data. Ignore playerclrs.
- Surface const & frame =
- *gfx->get_frame((time / data->frametime) % gfx->nr_frames());
- w = frame.get_w();
- h = frame.get_h();
+ const PictureID & frame =
+ gfx->get_frame((time / data->frametime) % gfx->nr_frames());
+ w = frame->get_w();
+ h = frame->get_h();
}
}
@@ -1137,7 +1031,7 @@
{
log("Save screenshot to %s\n", &fname);
StreamWrite * sw = g_fs->OpenStreamWrite(std::string(&fname));
- save_png(*m_screen, sw);
+ save_png(m_screen, sw);
delete sw;
}
@@ -1163,21 +1057,6 @@
static_cast<StreamWrite *>(png_get_io_ptr(png_ptr))->Flush();
}
-
-/**
-* Returns the bitmap that belongs to the given picture ID.
-* May return 0 if the given picture does not exist.
-*/
-Surface * Graphic::get_picture_surface(const PictureID & id)
-{
- return id->surface;
-}
-
-const Surface * Graphic::get_picture_surface(const PictureID & id) const
-{
- return id->surface;
-}
-
/**
* Retrieve the animation with the given number.
*
@@ -1210,7 +1089,7 @@
* if not done yet.
* \return The road texture
*/
-Surface * Graphic::get_road_texture(int32_t const roadtex)
+PictureID Graphic::get_road_texture(int32_t const roadtex)
{
if (not m_roadtextures) {
// Load the road textures
@@ -1223,7 +1102,6 @@
}
return
- get_picture_surface
- (roadtex == Widelands::Road_Normal ?
- m_roadtextures->pic_road_normal : m_roadtextures->pic_road_busy);
+ (roadtex == Widelands::Road_Normal ?
+ m_roadtextures->pic_road_normal : m_roadtextures->pic_road_busy);
}
=== modified file 'src/graphic/graphic.h'
--- src/graphic/graphic.h 2010-11-15 18:25:31 +0000
+++ src/graphic/graphic.h 2010-11-27 16:29:59 +0000
@@ -21,8 +21,8 @@
#define GRAPHIC_H
#include "animation_gfx.h"
-#include "picture.h"
#include "picture_id.h"
+#include "surfaceptr.h"
#include "rect.h"
#include <png.h>
@@ -41,8 +41,7 @@
namespace UI {struct ProgressWindow;}
-struct Surface;
-class Texture;
+struct IPixelAccess;
struct RenderTarget;
struct Graphic;
struct Road_Textures;
@@ -84,15 +83,29 @@
{
/// The renderer allows rendering (blit, draw_line) to offscreen surfaces
bool offscreen_rendering;
- /// It is possible to resize surfaces with get_resized_picture()
- bool resize_surfaces;
- /// It is possible to resize surfaces while bliting
- bool blit_resized;
/// The capabilities of the opengl hardware and drive
GLCaps gl;
};
/**
+ * Picture caches (modules).
+ *
+ * \ref Graphic maintains a cache of \ref PictureID s to avoid continuous re-loading of
+ * pictures that may not be referenced all the time (e.g. UI elements).
+ *
+ * This cache is separated into different modules, and can be flushed per-module.
+ */
+enum PicMod {
+ PicMod_UI = 0,
+ PicMod_Menu,
+ PicMod_Game,
+
+ // Must be last
+ PicMod_Last
+};
+
+
+/**
* A renderer to get pixels to a 16bit framebuffer.
*
* Picture IDs can be allocated using \ref get_picture() and used in
@@ -102,8 +115,7 @@
* graphics system is unloaded, or when \ref flush() is called with the
* appropriate module flag; the user can request to flush one single picture
* alone, but this is only used (and useful) in the editor.
-*/
-
+ */
struct Graphic {
Graphic
(int32_t w, int32_t h, int32_t bpp,
@@ -124,31 +136,26 @@
void flush(PicMod module);
void flush_animations();
- Surface & load_image(std::string const &, bool alpha = false);
- PictureID & get_picture(PicMod, std::string const &, bool alpha = true)
+ PictureID load_image(std::string const &, bool alpha = false);
+ const PictureID & get_picture(PicMod, std::string const &, bool alpha = true)
__attribute__ ((pure));
- PictureID get_picture
- (PicMod module, Surface &, const std::string & name = "");
- //__attribute__ ((pure));
- PictureID & get_no_picture() const;
-
- Surface * get_picture_surface(const PictureID & id);
- const Surface * get_picture_surface(const PictureID & id) const;
+ void add_picture_to_cache(PicMod, const std::string &, PictureID);
+ const PictureID & get_no_picture() const;
void get_picture_size
(const PictureID & pic, uint32_t & w, uint32_t & h) const;
+ PictureID get_offscreen_picture(OffscreenSurfacePtr surface) const;
void save_png(const PictureID &, StreamWrite *) const;
- void save_png(Surface & surf, StreamWrite *) const;
-
- PictureID create_picture_surface(int32_t w, int32_t h, bool alpha = false);
- Surface & create_surface(SDL_Surface &, bool alpha = false);
- Surface & create_surface(Surface &, bool alpha = false);
- Surface & create_surface(int32_t w, int32_t h, bool alpha = false);
- void free_picture_surface(const PictureID & pic);
+ void save_png(SurfacePtr surf, StreamWrite *) const;
+ void save_png(IPixelAccess & pix, StreamWrite *) const;
+
+ PictureID convert_sdl_surface_to_picture(SDL_Surface *, bool alpha = false);
+
+ OffscreenSurfacePtr create_offscreen_surface(int32_t w, int32_t h, bool alpha = false);
+ PictureID create_picture(int32_t w, int32_t h, bool alpha = false);
PictureID create_grayed_out_pic(const PictureID & picid);
- RenderTarget * get_surface_renderer(const PictureID & pic);
enum ResizeMode {
// do not worry about proportions, just sketch to requested size
@@ -163,7 +170,6 @@
PictureID get_resized_picture
(PictureID, uint32_t w, uint32_t h, ResizeMode);
- SDL_Surface * resize(const PictureID index, uint32_t w, uint32_t h);
uint32_t get_maptexture(char const & fnametempl, uint32_t frametime);
void animate_maptextures(uint32_t time);
@@ -183,10 +189,13 @@
Texture * get_maptexture_data(uint32_t id);
AnimationGfx * get_animation(uint32_t) const;
- Surface * get_road_texture(int32_t roadtex);
+ PictureID get_road_texture(int32_t roadtex);
GraphicCaps const & caps() const throw () {return m_caps;}
+private:
+ SDL_Surface * extract_sdl_surface(IPixelAccess & pix, Rect srcrect);
+
protected:
// Static helper function for png writing
static void m_png_write_function
@@ -197,7 +206,7 @@
/// This is the main screen Surface.
/// A RenderTarget for this can be retrieved with get_render_target()
- Surface * m_screen;
+ SurfacePtr m_screen;
/// This saves a copy of the screen SDL_Surface. This is needed for
/// opengl rendering as the SurfaceOpenGL does not use it. It allows
/// manipulation the screen context.
@@ -214,12 +223,19 @@
/// stores which features the current renderer has
GraphicCaps m_caps;
- /// hash of filename/picture ID pairs
- std::vector
- <std::map<std::string, boost::shared_ptr<Picture> > > m_picturemap;
- typedef std::map<std::string, boost::shared_ptr<Picture> > Picturemap;
+ struct PictureRec {
+ PictureID picture;
+
+ /// bit-mask of modules that this picture exists in
+ uint32_t modules;
+ };
+
+ typedef std::map<std::string, PictureRec> Picturemap;
typedef Picturemap::iterator pmit;
+ /// hash of cached filename/picture pairs
+ Picturemap m_picturemap;
+
Road_Textures * m_roadtextures;
std::vector<Texture *> m_maptextures;
std::vector<AnimationGfx *> m_animations;
@@ -229,4 +245,3 @@
extern bool g_opengl;
#endif
-
=== added file 'src/graphic/offscreensurface.h'
--- src/graphic/offscreensurface.h 1970-01-01 00:00:00 +0000
+++ src/graphic/offscreensurface.h 2010-11-27 16:29:59 +0000
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2010 by the Widelands Development Team
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+#ifndef OFFSCREENSURFACE_H
+#define OFFSCREENSURFACE_H
+
+#include "picture.h"
+#include "pixelaccess.h"
+#include "surface.h"
+
+/**
+ * Interface to surfaces that can act conveniently both as
+ * source and as destination for rendering.
+ */
+struct IOffscreenSurface : Surface, IPicture, IPixelAccess {
+};
+
+#endif // OFFSCREENSURFACE_H
=== modified file 'src/graphic/picture.cc'
--- src/graphic/picture.cc 2009-07-17 18:12:17 +0000
+++ src/graphic/picture.cc 2010-11-27 16:29:59 +0000
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2009 by the Widelands Development Team
+ * Copyright (C) 2009-2010 by the Widelands Development Team
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@@ -19,12 +19,25 @@
#include "picture.h"
-#include "surface.h"
-#include "rendertarget.h"
-
-Picture::~Picture() {
- delete surface;
- free(fname);
- delete rendertarget;
+#include "wexception.h"
+
+struct NullPicture : IPicture {
+ virtual bool valid() {return false;}
+
+ virtual uint32_t get_w() {return 0;}
+ virtual uint32_t get_h() {return 0;}
+
+ virtual IPixelAccess & pixelaccess() {throw wexception("pixelaccess() attempted on null picture");}
+ virtual Surface & surface() {throw wexception("surface() attempted on null picture");}
+};
+
+/**
+ * \return an invalid, null picture
+ *
+ * \see Graphic::get_no_picture
+ */
+const PictureID & IPicture::null()
+{
+ static PictureID thenull(new NullPicture);
+ return thenull;
}
-
=== modified file 'src/graphic/picture.h'
--- src/graphic/picture.h 2010-11-10 20:05:21 +0000
+++ src/graphic/picture.h 2010-11-27 16:29:59 +0000
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2002-2004, 2006-2009 by the Widelands Development Team
+ * Copyright (C) 2002-2004, 2006-2010 by the Widelands Development Team
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@@ -20,43 +20,36 @@
#ifndef PICTURE_H
#define PICTURE_H
-/***
- * Picture/PictureID
- *
- * PictureID is a reference to a picture
- * picmod is used to specify which buffer picture is loaded in.
- * warning: a picture can be loaded multiple times in multiple buffers
- * when buffer is flushed pictures will hang around till the last reference
- * is gone too
- ***/
-
-
-struct RenderTarget;
+#include <stdint.h>
+#include <string>
+
+#include "picture_id.h"
+
+struct IPixelAccess;
struct Surface;
-/// picture module flags
-enum PicMod {
- INVALID = 0,
- PicMod_UI = 1,
- PicMod_Menu = 2,
- PicMod_Game = 3,
- PicMod_Font = 4,
- PicSurface = 5,
- MaxModule = 6 //MaxModule ALWAYS has to be the 'size' of picmod
-};
-
-struct Picture {
- Picture() : module(INVALID), surface(0), fname(0), rendertarget(0) {}
- ~Picture();
- //void operator delete(void * p);
-
- //PicMod lists which 'buffer' to load the images in.
- // INVALID if unused, MaxModule not a legal module
- PicMod module;
- Surface * surface;
-
- char * fname; // module & (PicMod_UI|PicMod_Menu|PicMod_Game)
- RenderTarget * rendertarget; // module & (PicMod_Font | PicSurface)
+/**
+ * Interface to a bitmap that can act as the source of a rendering
+ * operation.
+ */
+struct IPicture {
+ IPicture() {}
+ virtual ~IPicture() {}
+
+ virtual bool valid() = 0;
+
+ virtual uint32_t get_w() = 0;
+ virtual uint32_t get_h() = 0;
+
+ virtual IPixelAccess & pixelaccess() = 0;
+
+private:
+ // forbid copying
+ IPicture(const IPicture &);
+ IPicture & operator= (const IPicture &);
+
+public:
+ static const PictureID & null();
};
#endif
=== modified file 'src/graphic/picture_id.h'
--- src/graphic/picture_id.h 2009-11-22 14:46:22 +0000
+++ src/graphic/picture_id.h 2010-11-27 16:29:59 +0000
@@ -21,8 +21,8 @@
#include <boost/shared_ptr.hpp>
-struct Picture;
+struct IPicture;
-typedef boost::shared_ptr<Picture> PictureID;
+typedef boost::shared_ptr<IPicture> PictureID;
#endif
=== added file 'src/graphic/pixelaccess.h'
--- src/graphic/pixelaccess.h 1970-01-01 00:00:00 +0000
+++ src/graphic/pixelaccess.h 2010-11-27 16:29:59 +0000
@@ -0,0 +1,110 @@
+/*
+ * Copyright 2010 by the Widelands Development Team
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+#ifndef PIXELACCESS_H
+#define PIXELACCESS_H
+
+#include <stdint.h>
+
+struct SDL_PixelFormat;
+
+/**
+ * Interface that provides direct pixel access to a picture or surface.
+ *
+ * \note Direct pixel access should be used only carefully, since it can be
+ * extremely slow.
+ */
+struct IPixelAccess {
+ enum LockMode {
+ /**
+ * Normal mode preserves pre-existing pixel data so that it can
+ * be read or modified.
+ */
+ Lock_Normal = 0,
+
+ /**
+ * Discard mode discards pre-existing pixel data. All pixels
+ * will be undefined unless they are re-written.
+ */
+ Lock_Discard
+ };
+
+ enum UnlockMode {
+ /**
+ * Update mode will ensure that any changes in the pixel data
+ * will appear in subsequent operations.
+ */
+ Unlock_Update = 0,
+
+ /**
+ * NoChange mode indicates that the caller changed no pixel data.
+ *
+ * \note If the caller did change pixel data but specifies NoChange
+ * mode, the results are undefined.
+ */
+ Unlock_NoChange
+ };
+
+ IPixelAccess() {}
+ virtual ~IPixelAccess() {}
+
+ /// Get width and height
+ //@{
+ virtual uint32_t get_w() = 0;
+ virtual uint32_t get_h() = 0;
+ //@}
+
+ /// This returns the pixel format for direct pixel access.
+ virtual SDL_PixelFormat const & format() const = 0;
+
+ /**
+ * Lock/Unlock pairs must guard any of the direct pixel access using the
+ * functions below.
+ *
+ * \note Lock/Unlock pairs cannot be nested.
+ */
+ //@{
+ virtual void lock(LockMode) = 0;
+ virtual void unlock(UnlockMode) = 0;
+ //@}
+
+ //@{
+ virtual uint32_t get_pixel(uint32_t x, uint32_t y) = 0;
+ virtual void set_pixel(uint32_t x, uint32_t y, uint32_t clr) = 0;
+ //@}
+
+ /**
+ * \return Pitch of the raw pixel data, i.e. the number of bytes
+ * contained in each image row. This can be strictly larger than
+ * bytes per pixel times the width.
+ */
+ virtual uint16_t get_pitch() const = 0;
+
+ /**
+ * \return Pointer to the raw pixel data.
+ *
+ * \warning May only be called inside lock/unlock pairs.
+ */
+ virtual uint8_t * get_pixels() const = 0;
+
+private:
+ IPixelAccess & operator= (const IPixelAccess &);
+};
+
+#endif // PIXELSURFACE_H
=== modified file 'src/graphic/render/animationgfx.cc'
--- src/graphic/render/animationgfx.cc 2010-05-18 19:34:36 +0000
+++ src/graphic/render/animationgfx.cc 2010-11-27 16:29:59 +0000
@@ -22,8 +22,8 @@
#include "io/streamwrite.h"
#include "surface_sdl.h"
-#include "surface_opengl.h"
#include "graphic/graphic.h"
+#include "graphic/picture.h"
#include "log.h"
#include "upcast.h"
@@ -99,17 +99,17 @@
strcpy(after_basename, extensions[extnr]);
if (g_fs->FileExists(filename)) { // Is the frame actually there?
try {
- Surface & surface = g_gr->load_image(filename, true);
+ PictureID pic = g_gr->load_image(filename, true);
if (width == 0) { // This is the first frame.
- width = surface.get_w();
- height = surface.get_h();
- } else if (width != surface.get_w() or height != surface.get_h())
+ width = pic->get_w();
+ height = pic->get_h();
+ } else if (width != pic->get_w() or height != pic->get_h())
throw wexception
("wrong size: (%u, %u), should be (%u, %u) like the "
"first frame",
- surface.get_w(), surface.get_h(), width, height);
+ pic->get_w(), pic->get_h(), width, height);
// Get a new AnimFrame.
- m_plrframes[0].push_back(&surface);
+ m_plrframes[0].push_back(pic);
#ifdef VALIDATE_ANIMATION_CROPPING
if (not data_in_x_min)
for (int y = 0; y < height; ++y) {
@@ -179,13 +179,13 @@
strcpy(after_basename + 3, extensions[extnr]);
if (g_fs->FileExists(filename)) {
try {
- Surface & surface = g_gr->load_image(filename, true);
- if (width != surface.get_w() or height != surface.get_h())
+ PictureID picture = g_gr->load_image(filename, true);
+ if (width != picture->get_w() or height != picture->get_h())
throw wexception
("playercolor mask has wrong size: (%u, %u), should "
"be (%u, %u) like the animation frame",
- surface.get_w(), surface.get_h(), width, height);
- m_pcmasks.push_back(&surface);
+ picture->get_w(), picture->get_h(), width, height);
+ m_pcmasks.push_back(picture);
break;
} catch (std::exception const & e) {
throw wexception
@@ -243,14 +243,6 @@
AnimationGfx::~AnimationGfx()
{
- for (Widelands::Player_Number i = 0; i <= MAX_PLAYERS; ++i) {
- std::vector<Surface *> & frames = m_plrframes[i];
- for (uint32_t j = 0; j < frames.size(); ++j)
- delete frames[j];
- }
-
- for (uint32_t j = 0; j < m_pcmasks.size(); ++j)
- delete m_pcmasks[j];
}
@@ -262,47 +254,36 @@
void AnimationGfx::encode(uint8_t const plr, RGBColor const * const plrclrs)
{
assert(m_plrframes[0].size() == m_pcmasks.size());
- std::vector<Surface *> & frames = m_plrframes[plr];
+ std::vector<PictureID> & frames = m_plrframes[plr];
for (uint32_t i = 0; i < m_plrframes[0].size(); ++i) {
// Copy the old surface.
- Surface & origsurface = *m_plrframes[0][i];
- Surface & newsurface = g_gr->create_surface(origsurface, true);
-
- Surface & pcmask = *m_pcmasks[i];
- SDL_PixelFormat * fmt, * fmt_pc;
-
-#ifdef USE_OPENGL
- upcast(SurfaceOpenGL, oglsurf, &origsurface);
-
- if (oglsurf)
- {
- fmt_pc = fmt = new SDL_PixelFormat;
- memset(fmt, 0, sizeof(SDL_PixelFormat));
- fmt->BitsPerPixel = 32; fmt->BytesPerPixel = 4;
- fmt->Amask = 0xFF000000; fmt->Ashift = 24;
- fmt->Bmask = 0x00FF0000; fmt->Bshift = 16;
- fmt->Gmask = 0x0000FF00; fmt->Gshift = 8;
- fmt->Rmask = 0x000000FF; fmt->Rshift = 0;
- } else
-#endif
- {
- fmt = const_cast<SDL_PixelFormat *>(&newsurface.format());
- fmt_pc = const_cast<SDL_PixelFormat *>(&pcmask.format());
- }
-
- origsurface.lock();
- pcmask.lock();
- newsurface.lock();
+ PictureID origpic = m_plrframes[0][i];
+ uint32_t w = origpic->get_w();
+ uint32_t h = origpic->get_h();
+ IPixelAccess & origpix = m_plrframes[0][i]->pixelaccess();
+ IPixelAccess & pcmask = m_pcmasks[i]->pixelaccess();
+
+ PictureID newpicture = g_gr->create_picture(w, h, true);
+ IPixelAccess & newpix = newpicture->pixelaccess();
+
+ const SDL_PixelFormat & fmt = origpix.format();
+ const SDL_PixelFormat & fmt_pc = pcmask.format();
+ const SDL_PixelFormat & destfmt = newpix.format();
+
+ origpix.lock(IPixelAccess::Lock_Normal);
+ pcmask.lock(IPixelAccess::Lock_Normal);
+ newpix.lock(IPixelAccess::Lock_Discard);
// This could be done significantly faster, but since we
// cache the result, let's keep it simple for now.
- for (uint32_t y = 0; y < newsurface.get_h(); ++y) {
- for (uint32_t x = 0; x < newsurface.get_w(); ++x) {
+ for (uint32_t y = 0; y < h; ++y) {
+ for (uint32_t x = 0; x < w; ++x) {
RGBAColor source;
RGBAColor mask;
+ RGBAColor product;
- source.set(*fmt, newsurface.get_pixel(x, y));
- mask.set(*fmt_pc, pcmask.get_pixel(x, y));
+ source.set(fmt, origpix.get_pixel(x, y));
+ mask.set(fmt_pc, pcmask.get_pixel(x, y));
if
(uint32_t const influence =
@@ -320,23 +301,25 @@
plrclr.g = (plrclrs[3].g() * intensity) >> 8;
plrclr.b = (plrclrs[3].b() * intensity) >> 8;
- RGBAColor dest(source);
- dest.r =
- (plrclr.r * influence + dest.r * (65536 - influence)) >> 16;
- dest.g =
- (plrclr.g * influence + dest.g * (65536 - influence)) >> 16;
- dest.b =
- (plrclr.b * influence + dest.b * (65536 - influence)) >> 16;
-
- newsurface.set_pixel(x, y, dest.map(*fmt));
+ product.r =
+ (plrclr.r * influence + source.r * (65536 - influence)) >> 16;
+ product.g =
+ (plrclr.g * influence + source.g * (65536 - influence)) >> 16;
+ product.b =
+ (plrclr.b * influence + source.b * (65536 - influence)) >> 16;
+ product.a = source.a;
+ } else {
+ product = source;
}
+
+ newpix.set_pixel(x, y, product.map(destfmt));
}
}
- origsurface.unlock();
- pcmask.unlock();
- newsurface.unlock();
+ origpix.unlock(IPixelAccess::Unlock_NoChange);
+ pcmask.unlock(IPixelAccess::Unlock_NoChange);
+ newpix.unlock(IPixelAccess::Unlock_Update);
- frames.push_back(&newsurface);
+ frames.push_back(newpicture);
}
}
=== modified file 'src/graphic/render/gameview.cc'
--- src/graphic/render/gameview.cc 2010-11-02 00:07:12 +0000
+++ src/graphic/render/gameview.cc 2010-11-27 16:29:59 +0000
@@ -33,7 +33,6 @@
#include "graphic/graphic.h"
#include "graphic/rendertarget.h"
#include "graphic/surface.h"
-#include "surface_opengl.h"
#include "surface_sdl.h"
#include "graphic/texture.h"
@@ -973,13 +972,10 @@
Texture const & f_d_texture,
Texture const & f_r_texture)
{
- upcast(SurfaceSDL, sdlsurf, m_surface);
-#ifdef USE_OPENGL
- upcast(SurfaceOpenGL, oglsurf, m_surface);
-#endif
+ upcast(SurfaceSDL, sdlsurf, m_surface.get());
if (sdlsurf)
{
- dynamic_cast<SurfaceSDL *>(m_surface)->set_subwin(subwin);
+ sdlsurf->set_subwin(subwin);
switch (sdlsurf->format().BytesPerPixel) {
case 2:
draw_field_int<Uint16>
@@ -998,16 +994,17 @@
default:
assert(false);
}
- dynamic_cast<SurfaceSDL *>(m_surface)->unset_subwin();
+ sdlsurf->unset_subwin();
}
#ifdef USE_OPENGL
- else if (oglsurf) {
+ else
+ {
// Draw triangle right (bottom) of the field
draw_field_opengl
- (*oglsurf, subwin, f_vert, br_vert, r_vert, f_r_texture);
+ (subwin, f_vert, br_vert, r_vert, f_r_texture);
// Draw triangle bottom of the field
draw_field_opengl
- (*oglsurf, subwin, f_vert, bl_vert, br_vert, f_d_texture);
+ (subwin, f_vert, bl_vert, br_vert, f_d_texture);
// Draw the roads
draw_roads_opengl(subwin, roads, f_vert, r_vert, bl_vert, br_vert);
}
@@ -1273,7 +1270,7 @@
// necesary. The created surface could be cached and only redrawn two
// or three times per second
const SDL_PixelFormat & fmt =
- g_gr->get_render_target()->get_surface().format();
+ g_gr->get_render_target()->get_surface()->pixelaccess().format();
SDL_Surface * surface =
SDL_CreateRGBSurface
(SDL_SWSURFACE,
@@ -1312,11 +1309,9 @@
SDL_UnlockSurface(surface);
- Surface & surf = g_gr->create_surface(*surface);
-
- m_surface->blit(Point(rc.x, rc.y), &surf, rc2, false);
-
- delete &surf;
+ PictureID picture = g_gr->convert_sdl_surface_to_picture(surface);
+
+ m_surface->blit(Point(rc.x, rc.y), picture, rc2);
}
void GameView::rendermap_init()
=== added file 'src/graphic/render/gl_picture_texture.cc'
--- src/graphic/render/gl_picture_texture.cc 1970-01-01 00:00:00 +0000
+++ src/graphic/render/gl_picture_texture.cc 2010-11-27 16:29:59 +0000
@@ -0,0 +1,235 @@
+/*
+ * Copyright 2010 by the Widelands Development Team
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include "gl_picture_texture.h"
+
+#include <SDL_video.h>
+
+#include "gl_utils.h"
+#include "graphic/graphic.h"
+#include "wexception.h"
+
+
+/**
+ * Initialize an OpenGL texture of the given dimensions.
+ *
+ * The initial data of the texture is undefined.
+ */
+GLPictureTexture::GLPictureTexture(int w, int h)
+{
+ init(w, h);
+}
+
+/**
+ * Initialize an OpenGL texture with the contents of the given surface.
+ *
+ * \note Takes ownership of the given surface.
+ */
+GLPictureTexture::GLPictureTexture(SDL_Surface * surface)
+{
+ init(surface->w, surface->h);
+
+ // Convert image data
+ uint8_t bpp = surface->format->BytesPerPixel;
+
+ if
+ (surface->format->palette or (surface->format->colorkey > 0) or
+ m_tex_w != static_cast<uint32_t>(surface->w) or
+ m_tex_h != static_cast<uint32_t>(surface->h) or
+ (bpp != 3 && bpp != 4))
+ {
+ SDL_Surface * converted = SDL_CreateRGBSurface
+ (SDL_SWSURFACE, m_tex_w, m_tex_h,
+ 32, 0x000000ff, 0x0000ff00, 0x00ff0000, 0xff000000);
+ assert(converted);
+ SDL_SetAlpha(converted, 0, 0);
+ SDL_SetAlpha(surface, 0, 0);
+ SDL_BlitSurface(surface, 0, converted, 0);
+ SDL_FreeSurface(surface);
+ surface = converted;
+ bpp = surface->format->BytesPerPixel;
+ }
+
+ SDL_PixelFormat const & fmt = *surface->format;
+ GLenum pixels_format;
+
+ glPushAttrib(GL_PIXEL_MODE_BIT);
+
+ if (bpp == 4) {
+ if
+ (fmt.Rmask == 0x000000ff and fmt.Gmask == 0x0000ff00 and
+ fmt.Bmask == 0x00ff0000)
+ {
+ if (fmt.Amask == 0xff000000) {
+ pixels_format = GL_RGBA;
+ } else {
+ pixels_format = GL_RGBA;
+ // Read four bytes per pixel but ignore the alpha value
+ glPixelTransferi(GL_ALPHA_SCALE, 0.0f);
+ glPixelTransferi(GL_ALPHA_BIAS, 1.0f);
+ }
+ } else if
+ (fmt.Bmask == 0x000000ff and fmt.Gmask == 0x0000ff00 and
+ fmt.Rmask == 0x00ff0000)
+ {
+ if (fmt.Amask == 0xff000000) {
+ pixels_format = GL_BGRA;
+ } else {
+ pixels_format = GL_BGRA;
+ // Read four bytes per pixel but ignore the alpha value
+ glPixelTransferi(GL_ALPHA_SCALE, 0.0f);
+ glPixelTransferi(GL_ALPHA_BIAS, 1.0f);
+ }
+ } else
+ throw wexception("OpenGL: Unknown pixel format");
+ } else if (bpp == 3) {
+ if
+ (fmt.Rmask == 0x000000ff and fmt.Gmask == 0x0000ff00 and
+ fmt.Bmask == 0x00ff0000)
+ {
+ pixels_format = GL_RGB;
+ } else if
+ (fmt.Bmask == 0x000000ff and fmt.Gmask == 0x0000ff00 and
+ fmt.Rmask == 0x00ff0000)
+ {
+ pixels_format = GL_BGR;
+ } else
+ throw wexception("OpenGL: Unknown pixel format");
+ } else
+ throw wexception("OpenGL: Unknown pixel format");
+
+ SDL_LockSurface(surface);
+
+ glTexImage2D
+ (GL_TEXTURE_2D, 0, GL_RGBA, m_tex_w, m_tex_h, 0,
+ pixels_format, GL_UNSIGNED_BYTE, surface->pixels);
+
+ SDL_UnlockSurface(surface);
+ SDL_FreeSurface(surface);
+
+ glPopAttrib();
+ handle_glerror();
+}
+
+GLPictureTexture::~GLPictureTexture()
+{
+ glDeleteTextures(1, &m_texture);
+}
+
+void GLPictureTexture::init(uint32_t w, uint32_t h)
+{
+ handle_glerror();
+
+ m_w = w;
+ m_h = h;
+
+ if (g_gr->caps().gl.tex_power_of_two) {
+ m_tex_w = next_power_of_two(w);
+ m_tex_h = next_power_of_two(h);
+ } else {
+ m_tex_w = w;
+ m_tex_h = h;
+ }
+
+ glGenTextures(1, &m_texture);
+ glBindTexture(GL_TEXTURE_2D, m_texture);
+
+ // set texture filter to use linear filtering. This looks nicer for resized
+ // texture. Most textures and images are not resized so the filtering
+ // makes no difference
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+
+ handle_glerror();
+}
+
+bool GLPictureTexture::valid()
+{
+ return true;
+}
+
+uint32_t GLPictureTexture::get_w()
+{
+ return m_w;
+}
+
+uint32_t GLPictureTexture::get_h()
+{
+ return m_h;
+}
+
+const SDL_PixelFormat & GLPictureTexture::format() const
+{
+ return gl_rgba_format();
+}
+
+void GLPictureTexture::lock(LockMode mode)
+{
+ assert(!m_pixels);
+
+ m_pixels.reset(new uint8_t[m_tex_w * m_tex_h * 4]);
+
+ if (mode == Lock_Normal) {
+ glBindTexture(GL_TEXTURE_2D, m_texture);
+ glGetTexImage(GL_TEXTURE_2D, 0, GL_RGBA, GL_UNSIGNED_BYTE, m_pixels.get());
+ }
+}
+
+void GLPictureTexture::unlock(UnlockMode mode)
+{
+ assert(m_pixels);
+
+ if (mode == Unlock_Update) {
+ glBindTexture(GL_TEXTURE_2D, m_texture);
+ glTexImage2D
+ (GL_TEXTURE_2D, 0, GL_RGBA, m_tex_w, m_tex_h, 0, GL_RGBA,
+ GL_UNSIGNED_BYTE, m_pixels.get());
+ }
+
+ m_pixels.reset(0);
+}
+
+uint16_t GLPictureTexture::get_pitch() const
+{
+ return 4 * m_tex_w;
+}
+
+uint8_t * GLPictureTexture::get_pixels() const
+{
+ return m_pixels.get();
+}
+
+uint32_t GLPictureTexture::get_pixel(uint32_t x, uint32_t y)
+{
+ assert(m_pixels);
+ assert(x < m_w);
+ assert(y < m_h);
+
+ uint8_t * data = &m_pixels[(y * m_tex_w + x) * 4];
+ return *(reinterpret_cast<uint32_t *>(data));
+}
+
+void GLPictureTexture::set_pixel(uint32_t x, uint32_t y, uint32_t clr)
+{
+ assert(m_pixels);
+ assert(x < m_w);
+ assert(y < m_h);
+
+ uint8_t * data = &m_pixels[(y * m_tex_w + x) * 4];
+ *(reinterpret_cast<uint32_t *>(data)) = clr;
+}
=== added file 'src/graphic/render/gl_picture_texture.h'
--- src/graphic/render/gl_picture_texture.h 1970-01-01 00:00:00 +0000
+++ src/graphic/render/gl_picture_texture.h 2010-11-27 16:29:59 +0000
@@ -0,0 +1,75 @@
+/*
+ * Copyright 2010 by the Widelands Development Team
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifndef GL_PICTURE_TEXTURE_H
+#define GL_PICTURE_TEXTURE_H
+
+#include <boost/scoped_array.hpp>
+
+#include <SDL_opengl.h>
+
+#include "graphic/picture.h"
+#include "graphic/pixelaccess.h"
+
+struct SDL_Surface;
+
+struct GLPictureTexture : IPicture, IPixelAccess {
+ GLPictureTexture(SDL_Surface * surface);
+ GLPictureTexture(int w, int h);
+ ~GLPictureTexture();
+
+ /// Interface implementation
+ //@{
+ virtual bool valid();
+
+ virtual uint32_t get_w();
+ virtual uint32_t get_h();
+
+ virtual const SDL_PixelFormat & format() const;
+ virtual void lock(LockMode);
+ virtual void unlock(UnlockMode);
+ virtual uint16_t get_pitch() const;
+ virtual uint8_t * get_pixels() const;
+ virtual void set_pixel(uint32_t x, uint32_t y, uint32_t clr);
+ virtual uint32_t get_pixel(uint32_t x, uint32_t y);
+
+ virtual IPixelAccess & pixelaccess() {return *this;}
+ //@}
+
+ GLuint get_gl_texture() const {return m_texture;}
+ uint32_t get_tex_w() const {return m_tex_w;}
+ uint32_t get_tex_h() const {return m_tex_h;}
+
+private:
+ void init(uint32_t w, uint32_t h);
+
+private:
+ GLuint m_texture;
+
+ /// Logical width and height of the surface
+ uint32_t m_w, m_h;
+
+ /// Keep the size of the opengl texture. This is necessary because some
+ /// systems support only a power of two for texture sizes.
+ uint32_t m_tex_w, m_tex_h;
+
+ /// Pixel data, while the texture is locked
+ boost::scoped_array<uint8_t> m_pixels;
+};
+
+#endif //GL_PICTURE_TEXTURE_H
=== added file 'src/graphic/render/gl_surface_screen.cc'
--- src/graphic/render/gl_surface_screen.cc 1970-01-01 00:00:00 +0000
+++ src/graphic/render/gl_surface_screen.cc 2010-11-27 16:29:59 +0000
@@ -0,0 +1,286 @@
+/*
+ * Copyright 2010 by the Widelands Development Team
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include "gl_surface_screen.h"
+
+#include "gl_picture_texture.h"
+#include "gl_utils.h"
+#include "graphic/graphic.h"
+#include "upcast.h"
+
+GLSurfaceScreen::GLSurfaceScreen(uint32_t w, uint32_t h)
+{
+ m_w = w;
+ m_h = h;
+}
+
+bool GLSurfaceScreen::valid()
+{
+ return true;
+}
+
+uint32_t GLSurfaceScreen::get_w()
+{
+ return m_w;
+}
+
+uint32_t GLSurfaceScreen::get_h()
+{
+ return m_h;
+}
+
+void GLSurfaceScreen::update()
+{
+ assert(g_opengl);
+ SDL_GL_SwapBuffers();
+}
+
+const SDL_PixelFormat & GLSurfaceScreen::format() const
+{
+ return gl_rgba_format();
+}
+
+void GLSurfaceScreen::lock(IPixelAccess::LockMode mode)
+{
+ assert(!m_pixels);
+
+ m_pixels.reset(new uint8_t[m_w * m_h * 4]);
+
+ if (mode == Lock_Normal)
+ glReadPixels(0, 0, m_w, m_h, GL_RGBA, GL_UNSIGNED_BYTE, m_pixels.get());
+}
+
+void GLSurfaceScreen::unlock(IPixelAccess::UnlockMode mode)
+{
+ assert(m_pixels);
+
+ if (mode == Unlock_Update)
+ glDrawPixels(m_w, m_h, GL_RGBA, GL_UNSIGNED_BYTE, m_pixels.get());
+
+ m_pixels.reset(0);
+}
+
+uint16_t GLSurfaceScreen::get_pitch() const
+{
+ return 4 * m_w;
+}
+
+uint8_t * GLSurfaceScreen::get_pixels() const
+{
+ return m_pixels.get();
+}
+
+uint32_t GLSurfaceScreen::get_pixel(uint32_t x, uint32_t y)
+{
+ assert(m_pixels);
+ assert(x < m_w);
+ assert(y < m_h);
+
+ uint8_t * data = &m_pixels[4 * (y * m_w + x)];
+ return *(reinterpret_cast<uint32_t *>(data));
+}
+
+void GLSurfaceScreen::set_pixel(uint32_t x, uint32_t y, Uint32 clr)
+{
+ assert(m_pixels);
+ assert(x < m_w);
+ assert(y < m_h);
+
+ uint8_t * data = &m_pixels[4 * (y * m_w + x)];
+ *(reinterpret_cast<uint32_t *>(data)) = clr;
+}
+
+/**
+ * Draws the outline of a rectangle
+ */
+void GLSurfaceScreen::draw_rect(const Rect rc, const RGBColor clr)
+{
+ assert(g_opengl);
+ glDisable(GL_BLEND);
+ glDisable(GL_TEXTURE_2D);
+
+ glBegin(GL_LINE_LOOP); {
+ glColor3ub(clr.r(), clr.g(), clr.b());
+ glVertex2f(rc.x + 0.5f, rc.y + 0.5f);
+ glVertex2f(rc.x + rc.w - 0.5f, rc.y + 0.5f);
+ glVertex2f(rc.x + rc.w - 0.5f, rc.y + rc.h - 0.5f);
+ glVertex2f(rc.x + 0.5f, rc.y + rc.h - 0.5f);
+ } glEnd();
+ glEnable(GL_TEXTURE_2D);
+}
+
+
+/**
+ * Draws a filled rectangle
+ */
+void GLSurfaceScreen::fill_rect(const Rect rc, const RGBAColor clr) {
+ assert(rc.x >= 0);
+ assert(rc.y >= 0);
+ assert(rc.w >= 0);
+ assert(rc.h >= 0);
+ assert(g_opengl);
+
+ glDisable(GL_TEXTURE_2D);
+ glDisable(GL_BLEND);
+
+ glBegin(GL_QUADS); {
+ glColor4ub(clr.r, clr.g, clr.b, clr.a);
+ glVertex2f(rc.x, rc.y);
+ glVertex2f(rc.x + rc.w, rc.y);
+ glVertex2f(rc.x + rc.w, rc.y + rc.h);
+ glVertex2f(rc.x, rc.y + rc.h);
+ } glEnd();
+ glEnable(GL_TEXTURE_2D);
+}
+
+/**
+ * Change the brightness of the given rectangle
+ */
+void GLSurfaceScreen::brighten_rect(const Rect rc, const int32_t factor)
+{
+ if (!factor)
+ return;
+
+ assert(rc.x >= 0);
+ assert(rc.y >= 0);
+ assert(rc.w >= 1);
+ assert(rc.h >= 1);
+ assert(g_opengl);
+
+ /* glBlendFunc is a very nice feature of opengl. You can specify how the
+ * color is calculated.
+ *
+ * glBlendFunc(GL_ONE, GL_ONE) means the following:
+ * Rnew = Rdest + Rsrc
+ * Gnew = Gdest + Gsrc
+ * Bnew = Bdest + Bsrc
+ * Anew = Adest + Asrc
+ * where Xnew is the new calculated color for destination, Xdest is the old
+ * color of the destination and Xsrc is the color of the source.
+ */
+ glEnable(GL_BLEND);
+ glDisable(GL_TEXTURE_2D);
+ glBlendFunc(GL_ONE, GL_ONE);
+
+ // And now simply draw a rect with facor as the color
+ // (this is the source color) over the region
+ glBegin(GL_QUADS); {
+ glColor3f
+ ((static_cast<GLfloat>(factor) / 256.0f),
+ (static_cast<GLfloat>(factor) / 256.0f),
+ (static_cast<GLfloat>(factor) / 256.0f));
+ glVertex2f(rc.x, rc.y);
+ glVertex2f(rc.x + rc.w, rc.y);
+ glVertex2f(rc.x + rc.w, rc.y + rc.h);
+ glVertex2f(rc.x, rc.y + rc.h);
+ } glEnd();
+}
+
+void GLSurfaceScreen::draw_line
+ (int32_t x1,
+ int32_t y1,
+ int32_t x2,
+ int32_t y2,
+ RGBColor color,
+ const Rect * clip)
+{
+ if (clip) {
+ glPushAttrib(GL_ENABLE_BIT | GL_SCISSOR_BIT);
+ glScissor
+ (clip->x, g_gr->get_yres() - clip->y - clip->h, clip->w, clip->h);
+ glEnable(GL_SCISSOR_TEST);
+ }
+ glDisable(GL_BLEND);
+ glDisable(GL_TEXTURE_2D);
+ glBegin(GL_LINES); {
+ glColor3ub(color.r(), color.g(), color.b());
+ glVertex2f(x1 + 0.5f, y1 + 0.5f);
+ glVertex2f(x2 + 0.5f, y2 + 0.5f);
+ } glEnd();
+ if (clip) {
+ glPopAttrib();
+ }
+}
+
+/**
+ * Clear the entire screen to black
+ */
+void GLSurfaceScreen::clear()
+{
+ assert(g_opengl);
+ glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
+ glClear(GL_COLOR_BUFFER_BIT);
+}
+
+
+void GLSurfaceScreen::blit
+ (Point const dst, PictureID const src, Rect const srcrc, Composite cm)
+{
+ upcast(GLPictureTexture, oglsrc, src.get());
+ assert(oglsrc);
+ assert(g_opengl);
+
+ /* Set a texture scaling factor. Normaly texture coordiantes
+ * (see glBegin()...glEnd() Block below) are given in the range 0-1
+ * to avoid the calculation (and let opengl do it) the texture
+ * space is modified. glMatrixMode select which matrix to manipulate
+ * (the texture transformation matrix in this case). glLoadIdentity()
+ * resets the (selected) matrix to the identity matrix. And finally
+ * glScalef() calculates the texture matrix.
+ */
+ glMatrixMode(GL_TEXTURE);
+ glLoadIdentity();
+ glScalef
+ (1.0f / static_cast<GLfloat>(oglsrc->get_tex_w()),
+ 1.0f / static_cast<GLfloat>(oglsrc->get_tex_h()), 1);
+
+ // Enable Alpha blending
+ if (cm == CM_Normal) {
+ glEnable(GL_BLEND);
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ } else {
+ glDisable(GL_BLEND);
+ }
+
+ glEnable(GL_TEXTURE_2D);
+ glBindTexture(GL_TEXTURE_2D, oglsrc->get_gl_texture());
+
+ glBegin(GL_QUADS); {
+ // set color white, otherwise textures get mixed with color
+ glColor3f(1.0, 1.0, 1.0);
+ // top-left
+ glTexCoord2i(srcrc.x, srcrc.y);
+ glVertex2i (dst.x, dst.y);
+ // top-right
+ glTexCoord2i(srcrc.x + srcrc.w, srcrc.y);
+ glVertex2f (dst.x + srcrc.w, dst.y);
+ // bottom-right
+ glTexCoord2i(srcrc.x + srcrc.w, srcrc.y + srcrc.h);
+ glVertex2f (dst.x + srcrc.w, dst.y + srcrc.h);
+ // bottom-left
+ glTexCoord2i(srcrc.x, srcrc.y + srcrc.h);
+ glVertex2f (dst.x, dst.y + srcrc.h);
+ } glEnd();
+
+ glLoadIdentity();
+}
+
+void GLSurfaceScreen::fast_blit(PictureID src)
+{
+ blit(Point(0, 0), src, Rect(Point(0, 0), src->get_w(), src->get_h()), CM_Normal);
+}
=== added file 'src/graphic/render/gl_surface_screen.h'
--- src/graphic/render/gl_surface_screen.h 1970-01-01 00:00:00 +0000
+++ src/graphic/render/gl_surface_screen.h 2010-11-27 16:29:59 +0000
@@ -0,0 +1,74 @@
+/*
+ * Copyright 2010 by the Widelands Development Team
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifndef GL_SURFACE_SCREEN_H
+#define GL_SURFACE_SCREEN_H
+
+#include <boost/scoped_array.hpp>
+
+#include "graphic/picture_id.h"
+#include "graphic/pixelaccess.h"
+#include "graphic/surface.h"
+
+/**
+ * This surface represents the screen in OpenGL mode.
+ */
+struct GLSurfaceScreen : Surface, IPixelAccess {
+ GLSurfaceScreen(uint32_t w, uint32_t h);
+
+ /// Interface implementations
+ //@{
+ virtual bool valid();
+
+ virtual uint32_t get_w();
+ virtual uint32_t get_h();
+
+ virtual void update();
+
+ virtual const SDL_PixelFormat & format() const;
+ virtual void lock(LockMode);
+ virtual void unlock(UnlockMode);
+ virtual uint16_t get_pitch() const;
+ virtual uint8_t * get_pixels() const;
+ virtual void set_pixel(uint32_t x, uint32_t y, Uint32 clr);
+ virtual uint32_t get_pixel(uint32_t x, uint32_t y);
+ virtual IPixelAccess & pixelaccess() {return *this;}
+
+ virtual void clear();
+ virtual void draw_rect(Rect, RGBColor);
+ virtual void fill_rect(Rect, RGBAColor);
+ virtual void brighten_rect(Rect, int32_t factor);
+
+ virtual void draw_line
+ (int32_t x1, int32_t y1,
+ int32_t x2, int32_t y2,
+ RGBColor, Rect const * clip = 0);
+
+ virtual void blit(Point, PictureID, Rect srcrc, Composite cm);
+ virtual void fast_blit(PictureID);
+ //@}
+
+private:
+ /// Size of the screen
+ uint32_t m_w, m_h;
+
+ /// Pixel data while locked
+ boost::scoped_array<uint8_t> m_pixels;
+};
+
+#endif // GL_SURFACE_SCREEN_H
=== added file 'src/graphic/render/gl_utils.cc'
--- src/graphic/render/gl_utils.cc 1970-01-01 00:00:00 +0000
+++ src/graphic/render/gl_utils.cc 2010-11-27 16:29:59 +0000
@@ -0,0 +1,100 @@
+/*
+ * Copyright 2010 by the Widelands Development Team
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include "gl_utils.h"
+
+#include <SDL_video.h>
+
+#include "log.h"
+
+/**
+ * Return the smallest power of two greater than or equal to \p x.
+ */
+uint32_t next_power_of_two(uint32_t x)
+{
+ uint32_t pot = 1;
+
+ while (pot < x)
+ pot *= 2;
+
+ return pot;
+}
+
+/**
+ * \return the standard 32-bit RGBA format that we use in OpenGL
+ */
+const SDL_PixelFormat & gl_rgba_format()
+{
+ static SDL_PixelFormat format;
+ static bool init = false;
+ if (init)
+ return format;
+
+ init = true;
+ memset(&format, 0, sizeof(format));
+ format.BitsPerPixel = 32;
+ format.BytesPerPixel = 4;
+ format.Rmask = 0x000000ff;
+ format.Gmask = 0x0000ff00;
+ format.Bmask = 0x00ff0000;
+ format.Amask = 0xff000000;
+ format.Rshift = 0;
+ format.Gshift = 8;
+ format.Bshift = 16;
+ format.Ashift = 24;
+ return format;
+}
+
+GLenum _handle_glerror(const char * file, unsigned int line)
+{
+ GLenum err = glGetError();
+#ifdef DEBUG
+ if (err == GL_NO_ERROR)
+ return err;
+
+ log("%s:%d: OpenGL ERROR: ", file, line);
+
+ switch (err)
+ {
+ case GL_INVALID_VALUE:
+ log("invalid value\n");
+ break;
+ case GL_INVALID_ENUM:
+ log("invalid enum\n");
+ break;
+ case GL_INVALID_OPERATION:
+ log("invalid operation\n");
+ break;
+ case GL_STACK_OVERFLOW:
+ log("stack overflow\n");
+ break;
+ case GL_STACK_UNDERFLOW:
+ log("stack undeflow\n");
+ break;
+ case GL_OUT_OF_MEMORY:
+ log("out of memory\n");
+ break;
+ case GL_TABLE_TOO_LARGE:
+ log("table too large\n");
+ break;
+ default:
+ log("unknown\n");
+ }
+#endif
+ return err;
+}
=== added file 'src/graphic/render/gl_utils.h'
--- src/graphic/render/gl_utils.h 1970-01-01 00:00:00 +0000
+++ src/graphic/render/gl_utils.h 2010-11-27 16:29:59 +0000
@@ -0,0 +1,37 @@
+/*
+ * Copyright 2010 by the Widelands Development Team
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifndef GL_UTILS_H
+#define GL_UTILS_H
+
+#include <stdint.h>
+#include <SDL_opengl.h>
+
+struct SDL_PixelFormat;
+
+uint32_t next_power_of_two(uint32_t x);
+const SDL_PixelFormat & gl_rgba_format();
+GLenum _handle_glerror(const char * file, unsigned int line);
+
+/**
+ * handle_glerror() is intended to make debugging of oengl easier. It logs the
+ * error code returned by glGetError and returns the error code.
+ */
+#define handle_glerror() _handle_glerror(__FILE__, __LINE__)
+
+#endif // GL_UTILS_H
=== removed file 'src/graphic/render/render_opengl.cc'
--- src/graphic/render/render_opengl.cc 2010-11-01 22:37:46 +0000
+++ src/graphic/render/render_opengl.cc 1970-01-01 00:00:00 +0000
@@ -1,269 +0,0 @@
-/*
- * Copyright 2010 by the Widelands Development Team
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#include "graphic/graphic.h"
-#include "surface_opengl.h"
-
-#include "log.h"
-#include "upcast.h"
-#include "wexception.h"
-
-#include <SDL.h>
-
-
-#ifdef USE_OPENGL
-
-/*
- * Updating the whole Surface
- */
-void SurfaceOpenGL::update() {
- assert(g_opengl);
- SDL_GL_SwapBuffers();
-}
-
-/*
-===============
-Draws the outline of a rectangle
-===============
-*/
-void SurfaceOpenGL::draw_rect(const Rect rc, const RGBColor clr) {
- assert(g_opengl);
- //log("SurfaceOpenGL::draw_rect() for opengl is experimental\n");
- glDisable(GL_BLEND);
- glDisable(GL_TEXTURE_2D);
-
- glBegin(GL_LINE_LOOP); {
- glColor3ub(clr.r(), clr.g(), clr.b());
- glVertex2f(m_offsx + rc.x + 0.5f, m_offsy + rc.y + 0.5f);
- glVertex2f(m_offsx + rc.x + rc.w - 0.5f, m_offsy + rc.y + 0.5f);
- glVertex2f(m_offsx + rc.x + rc.w - 0.5f, m_offsy + rc.y + rc.h - 0.5f);
- glVertex2f(m_offsx + rc.x + 0.5f, m_offsy + rc.y + rc.h - 0.5f);
- } glEnd();
- glEnable(GL_TEXTURE_2D);
-}
-
-
-/*
-===============
-Draws a filled rectangle
-===============
-*/
-void SurfaceOpenGL::fill_rect(const Rect rc, const RGBAColor clr) {
- assert(rc.x >= 0);
- assert(rc.y >= 0);
- assert(rc.w >= 0);
- assert(rc.h >= 0);
- assert(g_opengl);
-
- glDisable(GL_TEXTURE_2D);
- glDisable(GL_BLEND);
-
- glBegin(GL_QUADS); {
- glColor4ub(clr.r, clr.g, clr.b, clr.a);
- glVertex2f(m_offsx + rc.x, m_offsy + rc.y);
- glVertex2f(m_offsx + rc.x + rc.w, m_offsy + rc.y);
- glVertex2f(m_offsx + rc.x + rc.w, m_offsy + rc.y + rc.h);
- glVertex2f(m_offsx + rc.x, m_offsy + rc.y + rc.h);
- } glEnd();
- glEnable(GL_TEXTURE_2D);
-}
-
-/*
-===============
-Change the brightness of the given rectangle
-This function is slow as hell.
-
-* This function is a possible point to optimize on
- slow system. It takes a lot of cpu time atm and is
- not needed. It is used by the ui_basic stuff to
- highlight things.
-===============
-*/
-void SurfaceOpenGL::brighten_rect(const Rect rc, const int32_t factor) {
- if (!factor)
- return;
-
- assert(rc.x >= 0);
- assert(rc.y >= 0);
- assert(rc.w >= 1);
- assert(rc.h >= 1);
- assert(g_opengl);
-
- /* glBlendFunc is a very nice feature of opengl. You can specify how the
- * color is calculated.
- *
- * glBlendFunc(GL_ONE, GL_ONE) means the following:
- * Rnew = Rdest + Rsrc
- * Gnew = Gdest + Gsrc
- * Bnew = Bdest + Bsrc
- * Anew = Adest + Asrc
- * where Xnew is the new calculated color for destination, Xdest is the old
- * color of the destination and Xsrc is the color of the source.
- */
- glEnable(GL_BLEND);
- glDisable(GL_TEXTURE_2D);
- glBlendFunc(GL_ONE, GL_ONE);
-
- // And now simply draw a rect with facor as the color
- // (this is the source color) over the region
- glBegin(GL_QUADS); {
- glColor3f
- ((static_cast<GLfloat>(factor) / 256.0f),
- (static_cast<GLfloat>(factor) / 256.0f),
- (static_cast<GLfloat>(factor) / 256.0f));
- glVertex2f(m_offsx + rc.x, m_offsy + rc.y);
- glVertex2f(m_offsx + rc.x + rc.w, m_offsy + rc.y);
- glVertex2f(m_offsx + rc.x + rc.w, m_offsy + rc.y + rc.h);
- glVertex2f(m_offsx + rc.x, m_offsy + rc.y + rc.h);
- } glEnd();
-}
-
-void SurfaceOpenGL::draw_line
- (int32_t x1,
- int32_t y1,
- int32_t x2,
- int32_t y2,
- RGBColor color,
- const Rect * clip)
-{
- if (clip) {
- glPushAttrib(GL_ENABLE_BIT | GL_SCISSOR_BIT);
- glScissor
- (clip->x, g_gr->get_yres() - clip->y - clip->h, clip->w, clip->h);
- glEnable(GL_SCISSOR_TEST);
- }
- glDisable(GL_BLEND);
- glDisable(GL_TEXTURE_2D);
- glBegin(GL_LINES); {
- glColor3ub(color.r(), color.g(), color.b());
- glVertex2f(x1 + m_offsx + 0.5f, y1 + m_offsy + 0.5f);
- glVertex2f(x2 + m_offsx + 0.5f, y2 + m_offsy + 0.5f);
- } glEnd();
- if (clip) {
- glPopAttrib();
- }
-}
-
-/*
-===============
-Clear the entire bitmap to black
-===============
-*/
-void SurfaceOpenGL::clear()
-{
- assert(g_opengl);
- glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
- glClear(GL_COLOR_BUFFER_BIT);
- return;
-}
-
-
-void SurfaceOpenGL::blit
- (Point const dst, Surface * const src, Rect const srcrc, bool enable_alpha)
-{
- blit(Rect(dst, srcrc.w, srcrc.h), src, srcrc, enable_alpha);
-}
-
-
-void SurfaceOpenGL::blit
- (Rect dst, Surface * src, Rect srcrc, bool enable_alpha)
-{
- upcast(SurfaceOpenGL, oglsrc, src);
-
- assert(g_opengl);
-#ifdef DEBUG
- if (m_surf_type != SURFACE_SCREEN)
- {
- throw wexception
- ("Surface not the screen: Offscreen rendering not possible");
- return;
- }
-
- if (not oglsrc)
- {
- throw wexception("Invalid surface: Not a opengl surface");
- }
-#endif
- GLuint tex;
-
- try {
- tex = oglsrc->get_texture();
- } catch (...) {
- throw wexception
- ("SurfaceOpenGL::blit(): Source surface has no texture\n");
- return;
- }
-
- /* Set a texture scaling factor. Normaly texture coordiantes
- * (see glBegin()...glEnd() Block below) are given in the range 0-1
- * to avoid the calculation (and let opengl do it) the texture
- * space is modified. glMatrixMode select which matrix to manipulate
- * (the texture transformation matrix in this case). glLoadIdentity()
- * resets the (selected) matrix to the identity matrix. And finally
- * glScalef() calculates the texture matrix.
- */
- glMatrixMode(GL_TEXTURE);
- glLoadIdentity();
- glScalef
- (1.0f / static_cast<GLfloat>(oglsrc->get_tex_w()),
- 1.0f / static_cast<GLfloat>(oglsrc->get_tex_h()), 1);
-
- // Enable Alpha blending
- if (enable_alpha) {
- glEnable(GL_BLEND);
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
- } else
- glDisable(GL_BLEND);
-
- /* select the texture to paint on the screen
- * openGL does not know anything about SDL_Surfaces
- * opengl uses textures to handle images
- * getTexture() returns the texture id of the Surface. It creates
- * the texture from the SDL_Surface if it doesn't exist
- */
- glEnable(GL_TEXTURE_2D);
- glBindTexture(GL_TEXTURE_2D, tex);
-
- /* This block between blBegin() and glEnd() does the blit.
- * It draws a textured rectangle. glTexCoord2i() set the Texture
- * Texture cooardinates. This is the source rectangle.
- * glVertex2f() sets the screen coordiantes which belong to the
- * previous texture coordinate. This is the destination rectangle
- */
-
- glBegin(GL_QUADS); {
- // set color white, otherwise textures get mixed with color
- glColor3f(1.0, 1.0, 1.0);
- // top-left
- glTexCoord2i(srcrc.x, srcrc.y);
- glVertex2i (m_offsx + dst.x, m_offsy + dst.y);
- // top-right
- glTexCoord2i(srcrc.x + srcrc.w, srcrc.y);
- glVertex2f (m_offsx + dst.x + dst.w, m_offsy + dst.y);
- // bottom-right
- glTexCoord2i(srcrc.x + srcrc.w, srcrc.y + srcrc.h);
- glVertex2f (m_offsx + dst.x + dst.w, m_offsy + dst.y + dst.h);
- // bottom-left
- glTexCoord2i(srcrc.x, srcrc.y + srcrc.h);
- glVertex2f (m_offsx + dst.x, m_offsy + dst.y + dst.h);
- } glEnd();
-
- glLoadIdentity();
-}
-
-#endif //USE_OPENGL
=== modified file 'src/graphic/render/render_sdl.cc'
--- src/graphic/render/render_sdl.cc 2010-11-01 22:37:46 +0000
+++ src/graphic/render/render_sdl.cc 2010-11-27 16:29:59 +0000
@@ -49,7 +49,7 @@
* Updating the whole Surface
*/
void SurfaceSDL::update() {
- if (m_surf_type == SURFACE_SCREEN) {
+ if (m_isscreen) {
//flip defaults to SDL_UpdateRect(m_surface, 0, 0, 0, 0);
SDL_Flip(m_surface);
//log("SurfaceSDL::update(): update complete screen\n");
@@ -128,7 +128,7 @@
const Point bl = rc.bottom_left();
- lock();
+ lock(IPixelAccess::Lock_Normal);
if (m_surface->format->BytesPerPixel == 4)
{
@@ -183,7 +183,7 @@
SDL_MapRGB(m_surface->format, r, g, b);
}
}
- unlock();
+ unlock(IPixelAccess::Unlock_Update);
}
#define draw_pixel(p, r, clr) \
@@ -257,24 +257,35 @@
void SurfaceSDL::blit
- (Point const dst, Surface * const src, Rect const srcrc, bool enable_alpha)
+ (Point const dst, PictureID src, Rect const srcrc, Composite cm)
{
- assert(src);
+ upcast(SurfaceSDL, sdlsurf, src.get());
+ assert(sdlsurf);
assert(this);
SDL_Rect srcrect = {srcrc.x, srcrc.y, srcrc.w, srcrc.h};
SDL_Rect dstrect = {dst.x, dst.y, 0, 0};
- SDL_BlitSurface
- (dynamic_cast<SurfaceSDL *>(src)->get_sdl_surface(),
- &srcrect, m_surface, &dstrect);
+ bool alpha;
+ uint8_t alphaval;
+ if (cm == CM_Solid || cm == CM_Copy) {
+ alpha = sdlsurf->get_sdl_surface()->flags & SDL_SRCALPHA;
+ alphaval = sdlsurf->get_sdl_surface()->format->alpha;
+ SDL_SetAlpha(sdlsurf->get_sdl_surface(), 0, 0);
+ }
+
+ SDL_BlitSurface(sdlsurf->get_sdl_surface(), &srcrect, m_surface, &dstrect);
+
+ if (cm == CM_Solid || cm == CM_Copy) {
+ SDL_SetAlpha(sdlsurf->get_sdl_surface(), alpha?SDL_SRCALPHA:0, alphaval);
+ }
}
/*
* Fast blit, simply copy the source to the destination
*/
-void SurfaceSDL::fast_blit(Surface * const src) {
+void SurfaceSDL::fast_blit(PictureID const src) {
SDL_BlitSurface
- (dynamic_cast<SurfaceSDL *>(src)->get_sdl_surface(),
+ (dynamic_cast<SurfaceSDL *>(src.get())->get_sdl_surface(),
0, m_surface, 0);
}
=== removed file 'src/graphic/render/surface_opengl.cc'
--- src/graphic/render/surface_opengl.cc 2010-11-01 22:37:46 +0000
+++ src/graphic/render/surface_opengl.cc 1970-01-01 00:00:00 +0000
@@ -1,381 +0,0 @@
-/*
- * Copyright 2010 by the Widelands Development Team
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#include "surface_opengl.h"
-#include "log.h"
-#include "graphic/graphic.h"
-
-#include <cassert>
-#include <cmath>
-
-#ifdef USE_OPENGL
-
-long unsigned int pix_used = 0;
-long unsigned int pix_aloc = 0;
-long unsigned int num_tex = 0;
-
-#define handle_glerror() _handle_glerror(__FILE__, __LINE__)
-
-SDL_PixelFormat * rgbafmt = 0;
-
-/* handle_glerror() is intended to make debugging of oengl easier. It logs the
- * error code returned by glGetError and returns the error code.
- */
-GLenum _handle_glerror(const char * file, unsigned int line)
-{
- GLenum err = glGetError();
-#ifdef DEBUG
- if (err == GL_NO_ERROR)
- return err;
-
- log("%s:%d: OpenGL ERROR: ", file, line);
-
- switch (err)
- {
- case GL_INVALID_VALUE:
- log("invalid value\n");
- break;
- case GL_INVALID_ENUM:
- log("invalid enum\n");
- break;
- case GL_INVALID_OPERATION:
- log("invalid operation\n");
- break;
- case GL_STACK_OVERFLOW:
- log("stack overflow\n");
- break;
- case GL_STACK_UNDERFLOW:
- log("stack undeflow\n");
- break;
- case GL_OUT_OF_MEMORY:
- log("out of memory\n");
- break;
- case GL_TABLE_TOO_LARGE:
- log("table too large\n");
- break;
- default:
- log("unknown\n");
- }
-#endif
- return err;
-}
-
-SurfaceOpenGL::SurfaceOpenGL(SDL_Surface & par_surface):
- Surface(par_surface.w, par_surface.h, SURFACE_SOURCE),
- m_glTexUpdate(false),
- m_pixels (0),
- m_locked(false)
-{
- GLuint texture;
- SDL_Surface * surface;
- GLenum pixels_format, pixels_type;
- GLint Bpp;
-
- handle_glerror();
-
- surface = &par_surface;
-
- if (g_gr->caps().gl.tex_power_of_two)
- {
- int wexp = log(static_cast<float>(surface->w)) / log(2.0f);
- int hexp = log(static_cast<float>(surface->h)) / log(2.0f);
- if (pow(2.0f, wexp) < surface->w)
- wexp++;
- if (pow(2.0f, hexp) < surface->h)
- hexp++;
-
- m_tex_w = pow(2.0f, wexp);
- m_tex_h = pow(2.0f, hexp);
- } else {
- m_tex_w = surface->w;
- m_tex_h = surface->h;
- }
-
- if
- (surface->format->palette or (surface->format->colorkey > 0) or
- m_tex_w != static_cast<uint32_t>(surface->w) or
- m_tex_h != static_cast<uint32_t>(surface->h))
- {
- //log("SurfaceOpenGL: convert surface for opengl\n");
- surface = SDL_CreateRGBSurface
- (SDL_SWSURFACE, m_tex_w, m_tex_h,
- 32, 0x000000ff, 0x0000ff00, 0x00ff0000, 0xff000000);
- assert(surface);
- //SDL_DisplayFormatAlpha(&par_surface);
- SDL_SetAlpha(surface, 0, 0);
- SDL_SetAlpha(&par_surface, 0, 0);
- SDL_BlitSurface(&par_surface, 0, surface, 0);
- SDL_FreeSurface(&par_surface);
- }
-
- SDL_PixelFormat const & fmt = *surface->format;
- Bpp = fmt.BytesPerPixel;
-
- /* log
- ("SurfaceOpenGL::SurfaceOpenGL(SDL_Surface) Size: (%d, %d) %db(%dB) ",
- m_tex_w, m_tex_h,
- fmt.BitsPerPixel, Bpp);
- log("R:%X, G:%X, B:%X, A:%X", fmt.Rmask, fmt.Gmask, fmt.Bmask, fmt.Amask); */
-
- glPushAttrib(GL_PIXEL_MODE_BIT);
- bool pushed = not (handle_glerror() == GL_STACK_OVERFLOW);
-
- if (Bpp == 4)
- {
- if
- (fmt.Rmask == 0x000000ff and fmt.Gmask == 0x0000ff00 and
- fmt.Bmask == 0x00ff0000)
- {
- if (fmt.Amask == 0xff000000)
- {
- pixels_format = GL_RGBA; //log(" RGBA 8888 ");
- } else {
- pixels_format = GL_RGBA; //log(" RGB 8880 ");
- // Read four bytes per pixel but ignore the alpha value
- glPixelTransferi(GL_ALPHA_SCALE, 0.0f);
- glPixelTransferi(GL_ALPHA_BIAS, 1.0f);
- }
- } else if
- (fmt.Bmask == 0x000000ff and fmt.Gmask == 0x0000ff00 and
- fmt.Rmask == 0x00ff0000)
- {
- if (fmt.Amask == 0xff000000)
- {
- pixels_format = GL_BGRA; //log(" BGRA 8888 ");
- } else {
- pixels_format = GL_BGRA; //log(" BGR 8880 ");
- // Read four bytes per pixel but ignore the alpha value
- glPixelTransferi(GL_ALPHA_SCALE, 0.0f);
- glPixelTransferi(GL_ALPHA_BIAS, 1.0f);
- }
- } else
- throw wexception("OpenGL: Unknown pixel format");
- pixels_type = GL_UNSIGNED_BYTE;
- } else if (Bpp == 3)
- {
- if
- (fmt.Rmask == 0x000000ff and fmt.Gmask == 0x0000ff00 and
- fmt.Bmask == 0x00ff0000)
- {
- pixels_format = GL_RGB; //log(" RGB 888 ");
- } else if
- (fmt.Bmask == 0x000000ff and fmt.Gmask == 0x0000ff00 and
- fmt.Rmask == 0x00ff0000)
- {
- pixels_format = GL_BGR; //log(" BGR 888 ");
- } else
- throw wexception("OpenGL: Unknown pixel format");
- pixels_type = GL_UNSIGNED_BYTE;
- } else if (Bpp == 2)
- {
- if (fmt.Rmask == 0xF800 and fmt.Gmask == 0x7E0 and fmt.Bmask == 0x1F)
- {
- pixels_format = GL_RGB; //log(" RGB 565");
- } else if
- (fmt.Bmask == 0xF800 and fmt.Gmask == 0x7E0 and fmt.Rmask == 0x1F)
- {
- pixels_format = GL_BGR; //log(" BGR 565");
- } else
- assert(false);
- pixels_type = GL_UNSIGNED_SHORT_5_6_5;
- } else
- throw wexception("OpenGL: Unknown pixel format");
- //log("\n");
-
- // Let OpenGL create a texture object
- glGenTextures(1, &texture);
- handle_glerror();
-
- // select the texture object
- glBindTexture(GL_TEXTURE_2D, texture);
- handle_glerror();
-
- // set texture filter to use linear filtering. This looks nicer for resized
- // texture. Most textures and images are not resized so the filtering
- // makes no difference
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
- handle_glerror();
-
- SDL_LockSurface(surface);
-
- // glTexImage2D creates the texture of size (m_tex_w x m_tex_h) and copies
- // the pixels for surface->pixels to it.
- // The third parameter (internal format) specifies how opengl should store
- // the pixels. This has nothing to do with the read pixels
- // 7th and 8th parameter (format and type) specify the format of the read
- // pixels (9th parameter)
- glTexImage2D
- (GL_TEXTURE_2D, 0, WL_GLINTERNALFORMAT, m_tex_w, m_tex_h, 0,
- pixels_format, pixels_type, surface->pixels);
- handle_glerror();
-
- if (pushed)
- glPopAttrib();
-
- SDL_UnlockSurface(surface);
- SDL_FreeSurface(surface);
-
- pix_used += m_w * m_h;
- pix_aloc += m_tex_w * m_tex_h;
- num_tex++;
- /*
- log
- ("texture stats: num: %lu, used: %lu (%luM), "
- "alocated: %lu (%luM) ++\n",
- num_tex, pix_used * 4, pix_used * 4 / (1024 * 1024),
- pix_aloc * 4, pix_aloc * 4/ (1024 * 1024));
- */
- assert(glIsTexture(texture));
-
- m_texture = new oglTexture(texture);
- m_glTexUpdate = false;
-}
-
-
-SurfaceOpenGL::~SurfaceOpenGL() {
- if (m_texture) {
- pix_used -= m_w * m_h;
- pix_aloc -= m_tex_w * m_tex_h;
- num_tex--;
- delete m_texture;
- }
- /* log
- ("~SurfaceOpenGL(): texture stats: num: %lu, "
- "used: %lu (%luM), alocated: %lu (%luM) --\n",
- num_tex, pix_used * 4, pix_used * 4 / (1024 * 1024),
- pix_aloc * 4, pix_aloc * 4/ (1024 * 1024)); */
-
- delete[] m_pixels;
-}
-
-
-SurfaceOpenGL::SurfaceOpenGL(int const w, int const h):
- Surface(w, h, SURFACE_SOURCE),
- m_texture(0),
- m_glTexUpdate(false),
- m_pixels (0),
- m_locked(false)
-{
- if (g_gr and g_gr->caps().gl.tex_power_of_two) {
- // Some old graphics cards support only opengl textures which have a
- // size of 2^n. To get it working on these cards we take the next equal
- // or greater power of two. This is a waste of graphics memory and
- // causes some problem with borders of textures and repeated textures
- // but at least it works.
- int wexp = log(static_cast<float>(w)) / log(2.0f);
- int hexp = log(static_cast<float>(h)) / log(2.0f);
- if (pow(2.0f, wexp) < w)
- wexp++;
- if (pow(2.0f, hexp) < h)
- hexp++;
-
- m_tex_w = pow(2.0f, wexp);
- m_tex_h = pow(2.0f, hexp);
- } else {
- m_tex_w = w;
- m_tex_h = h;
- }
-}
-
-/* This returns a SDL_Pixel format for the returned pixels. lock() copies the
- * pixels always as 32Bit RGBA. So we create and return a RGBA SDL_PixelFormat
- */
-const SDL_PixelFormat * SurfaceOpenGL::get_format() const
-{
- if (rgbafmt)
- return rgbafmt;
- rgbafmt = new SDL_PixelFormat;
- rgbafmt->BitsPerPixel = 32;
- rgbafmt->BytesPerPixel = 4;
- rgbafmt->Rmask = 0x000000ff; rgbafmt->Gmask = 0x0000ff00;
- rgbafmt->Bmask = 0x00ff0000; rgbafmt->Amask = 0xff000000;
- rgbafmt->Ashift = 24; rgbafmt->Bshift = 16; rgbafmt->Gshift = 8;
- rgbafmt->Rshift = 0; rgbafmt->palette = 0;
- return rgbafmt;
-}
-
-/* lock the surface for pixel access. This allocates memory and copies the
- * pixles from opengl texture to it. This copies the whole texture even if
- * only one pixel is read. So use this as rare as possible.
- */
-void SurfaceOpenGL::lock() {
- if (m_locked)
- return;
- try {
- if (m_surf_type == SURFACE_SCREEN)
- m_pixels = new uint8_t[m_w * m_h * 4];
- else
- m_pixels = new uint8_t[m_tex_w * m_tex_h * 4];
- } catch (std::bad_alloc) {
- return;
- }
- if (m_surf_type == SURFACE_SCREEN)
- glReadPixels
- (0, 0, m_w, m_h, GL_RGBA, GL_UNSIGNED_BYTE, m_pixels);
- else if (m_texture) {
- assert(glIsTexture(m_texture->id()));
- glBindTexture(GL_TEXTURE_2D, m_texture->id());
- glGetTexImage(GL_TEXTURE_2D, 0, GL_RGBA, GL_UNSIGNED_BYTE, m_pixels);
- m_glTexUpdate = false;
- } else
- m_glTexUpdate = true;
- //log("locked opengl surface(%d, %d)\n", m_tex_w, m_tex_h);
- m_locked = true;
-}
-
-/* Unlock the surface after pixel access. This loads the pixels to the texture
- * if pixels were changed and free the alocated memory.
- */
-void SurfaceOpenGL::unlock() {
- if (not m_locked)
- return;
- assert(m_pixels);
-
- if (m_glTexUpdate) {
- assert(m_surf_type != SURFACE_SCREEN);
- if (!m_texture)
- {
- GLuint texture;
- glGenTextures(1, &texture);
-
- // selcet the texture object
- glBindTexture(GL_TEXTURE_2D, texture);
-
- // set texture filter to siply take the nearest pixel.
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
-
- pix_used += m_w * m_h;
- pix_aloc += m_tex_w * m_tex_h;
- num_tex++;
-
- m_texture = new oglTexture(texture);
- }
- glBindTexture(GL_TEXTURE_2D, m_texture->id());;
- glTexImage2D
- (GL_TEXTURE_2D, 0, WL_GLINTERNALFORMAT, m_tex_w, m_tex_h, 0, GL_RGBA,
- GL_UNSIGNED_BYTE, m_pixels);
- }
-
- delete [] m_pixels;
- m_pixels = 0;
- m_locked = false;
-}
-
-#endif //USE_OPENGL
=== removed file 'src/graphic/render/surface_opengl.h'
--- src/graphic/render/surface_opengl.h 2010-11-01 22:37:46 +0000
+++ src/graphic/render/surface_opengl.h 1970-01-01 00:00:00 +0000
@@ -1,170 +0,0 @@
-/*
- * Copyright 2010 by the Widelands Development Team
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#if !defined(SURFACE_OPENGL_H) and defined(USE_OPENGL)
-#define SURFACE_OPENGL_H
-
-#include "rgbcolor.h"
-#include "rect.h"
-#include "graphic/surface.h"
-
-#include <SDL_opengl.h>
-
-#include <cassert>
-
-#define WL_GLINTERNALFORMAT GL_RGBA
-
-namespace Widelands {
-struct Editor_Game_Base;
-struct Field;
-struct Player;
-}
-
-namespace UI {
-struct Font_Handler;
-}
-
-struct Vertex;
-
-/**
- * This implements OpenGL rendering. Do not use this class directly. The right
- * way is to use the base class Surface wherever possible. Everything which
- * needs to know about the underlying renderer should go to the graphics
- * subdirectory.
- * Surfaces are created through Graphic::create_surface() functions.
-*/
-class SurfaceOpenGL : public Surface {
-public:
- /**
- * Manages a single OpenGL texture. This makes sure the texture is
- * freed when the object is destroyed.
- */
- struct oglTexture {
- oglTexture() {}
- oglTexture(GLuint id): m_textureID(id) {}
- ~oglTexture() {glDeleteTextures(1, &m_textureID);}
- GLuint id() const {return m_textureID;}
- private:
- GLuint m_textureID;
- };
-
- SurfaceOpenGL(SDL_Surface & surface);
- explicit SurfaceOpenGL(int w = 0, int h = 0);
- ~SurfaceOpenGL();
-
- //@{
- /// Get width and height
- uint32_t get_w() const {return m_w;}
- uint32_t get_h() const {return m_h;}
- uint32_t get_tex_w() const {return m_tex_w;}
- uint32_t get_tex_h() const {return m_tex_h;}
- //@}
-
- void update();
-
- GLuint get_texture() const
- {
-#if defined(DEBUG)
- if (m_surf_type != SURFACE_SOURCE)
- throw wexception
- ("Try to get opengl texture id but not a source surface");
- if (not m_texture)
- throw wexception("no texture");
-#endif
- return m_texture->id();
- }
-
- const SDL_PixelFormat * get_format() const;
- SDL_PixelFormat const & format() const {return *get_format();}
-
- /// Directly access the pixels. This is only valid if the surface is locked
- inline uint16_t get_pitch() const {return m_tex_w * 4;}
- uint8_t * get_pixels() const
- {
- assert(m_locked);
- assert(m_pixels);
- return m_pixels;
- }
-
- /// Lock: The Surface need to be locked before get or set pixel
- void lock();
- void unlock();
-
- /// For the slowest: Indirect pixel access
- inline uint32_t get_pixel(uint32_t x, uint32_t y) {
- x += m_offsx;
- y += m_offsy;
-
- assert(x < get_w());
- assert(y < get_h());
- assert(m_locked);
-
- return *reinterpret_cast<uint32_t *>(m_pixels + y * get_pitch() + x * 4);
- }
- inline void set_pixel(uint32_t x, uint32_t y, Uint32 clr) {
- x += m_offsx;
- y += m_offsy;
-
- assert(x < get_w());
- assert(y < get_h());
- assert(m_locked);
- m_glTexUpdate = true;
-
- *reinterpret_cast<uint32_t *>(m_pixels + y * get_pitch() + x * 4) = clr;
- }
-
- void clear();
- void draw_rect(Rect, RGBColor);
- void fill_rect(Rect, RGBAColor);
- void brighten_rect(Rect, int32_t factor);
-
- void draw_line
- (int32_t x1, int32_t y1,
- int32_t x2, int32_t y2,
- RGBColor, Rect const * clip = 0);
-
- void blit(Point, Surface *, Rect srcrc, bool enable_alpha = true);
- void blit(Rect dst, Surface *, Rect srcrc, bool enable_alpha = true);
- //void fast_blit(Surface *);
-
- oglTexture & getTexture() {return *m_texture;}
-
-private:
- SurfaceOpenGL & operator= (SurfaceOpenGL const &);
- explicit SurfaceOpenGL (SurfaceOpenGL const &);
-
- /// stores the opengl texture id and frees if destroyed
- oglTexture * m_texture;
- /// Indicates that the texture needs to be updated after pixel access
- bool m_glTexUpdate;
-
- //@{
- /// set/unset a clipping rectangle
- void set_subwin(Rect r);
- void unset_subwin();
- //@}
-
- uint8_t * m_pixels;
- bool m_locked;
-
- /// Keep the size of the opengl texture. This is necessary because some
- /// systems support only a power of two for texture sizes.
- uint32_t m_tex_w, m_tex_h;
-};
-
-#endif
=== modified file 'src/graphic/render/surface_sdl.cc'
--- src/graphic/render/surface_sdl.cc 2010-05-18 13:21:05 +0000
+++ src/graphic/render/surface_sdl.cc 2010-11-27 16:29:59 +0000
@@ -25,7 +25,7 @@
SurfaceSDL::~SurfaceSDL() {
//log("SurfaceSDL::~SurfaceSDL()\n");
- if (m_surface and m_surf_type != SURFACE_SCREEN)
+ if (m_surface and !m_isscreen)
SDL_FreeSurface(m_surface);
}
@@ -58,12 +58,12 @@
m_offsx * m_surface->format->BytesPerPixel;
}
-void SurfaceSDL::lock() {
+void SurfaceSDL::lock(LockMode) {
if (SDL_MUSTLOCK(m_surface))
SDL_LockSurface(m_surface);
}
-void SurfaceSDL::unlock() {
+void SurfaceSDL::unlock(UnlockMode) {
if (SDL_MUSTLOCK(m_surface))
SDL_UnlockSurface(m_surface);
}
@@ -147,3 +147,8 @@
m_w = m_surface->w;
m_h = m_surface->h;
}
+
+void SurfaceSDL::set_isscreen(bool screen)
+{
+ m_isscreen = screen;
+}
=== modified file 'src/graphic/render/surface_sdl.h'
--- src/graphic/render/surface_sdl.h 2010-11-01 22:37:46 +0000
+++ src/graphic/render/surface_sdl.h 2010-11-27 16:29:59 +0000
@@ -23,7 +23,7 @@
#include "rgbcolor.h"
#include "rect.h"
-#include "graphic/surface.h"
+#include "graphic/offscreensurface.h"
/**
* This implements SDL rendering. Do not use this class directly. The right
@@ -32,17 +32,24 @@
* subdirectory.
* Surfaces are created through Graphic::create_surface() functions.
*/
-struct SurfaceSDL : public Surface {
+struct SurfaceSDL : IOffscreenSurface {
SurfaceSDL(SDL_Surface & surface) :
- Surface(surface.w, surface.h, SURFACE_OFFSCREEN),
- m_surface(&surface)
+ m_surface(&surface),
+ m_offsx(0), m_offsy(0),
+ m_w(surface.w), m_h(surface.h),
+ m_isscreen(false)
{}
SurfaceSDL():
- Surface(),
- m_surface(0)
+ m_surface(0),
+ m_offsx(0), m_offsy(0),
+ m_w(0), m_h(0),
+ m_isscreen(false)
{}
~SurfaceSDL();
+ virtual uint32_t get_w() {return m_w;}
+ virtual uint32_t get_h() {return m_h;}
+
/// Set surface, only call once
void set_sdl_surface(SDL_Surface & surface);
SDL_Surface * get_sdl_surface() {return m_surface;}
@@ -53,21 +60,13 @@
/// Save a bitmap of this to a file
void save_bmp(const char & fname) const;
-/*
- // For the bravest: Direct Pixel access. Use carefully
- /// Needed if you want to blit directly to the screen by memcpy
- void force_disable_alpha();
- const SDL_PixelFormat * get_format() const;
- uint16_t get_pitch() const {return m_surface->pitch;}
-*/
-
SDL_PixelFormat const & format() const;
uint8_t * get_pixels() const;
uint16_t get_pitch() const {return m_surface->pitch;}
/// Lock
- void lock();
- void unlock();
+ void lock(LockMode);
+ void unlock(UnlockMode);
/// For the slowest: Indirect pixel access
uint32_t get_pixel(uint32_t x, uint32_t y);
@@ -83,17 +82,27 @@
int32_t x2, int32_t y2,
RGBColor, Rect const * clip = 0);
- void blit(Point, Surface *, Rect srcrc, bool enable_alpha = true);
- void fast_blit(Surface *);
+ void blit(Point, PictureID, Rect srcrc, Composite cm);
+ void fast_blit(PictureID);
void set_subwin(Rect r);
void unset_subwin();
+ void set_isscreen(bool screen);
+
+ bool valid() {return m_surface;}
+
+ virtual IPixelAccess & pixelaccess() {return *this;}
+
private:
SurfaceSDL & operator= (SurfaceSDL const &);
explicit SurfaceSDL (SurfaceSDL const &);
SDL_Surface * m_surface;
+ int32_t m_offsx;
+ int32_t m_offsy;
+ uint32_t m_w, m_h;
+ bool m_isscreen;
};
#endif
=== modified file 'src/graphic/render/terrain_opengl.h'
--- src/graphic/render/terrain_opengl.h 2010-11-05 19:36:57 +0000
+++ src/graphic/render/terrain_opengl.h 2010-11-27 16:29:59 +0000
@@ -19,13 +19,12 @@
#ifdef USE_OPENGL
-#include "surface_opengl.h"
+#include "gl_picture_texture.h"
#include "vertex.h"
void draw_field_opengl
- (Surface & surf,
- Rect const & subwin,
+ (Rect const & subwin,
Vertex const & p1,
Vertex const & p2,
Vertex const & p3,
@@ -122,11 +121,11 @@
uint8_t road;
GLuint rt_normal =
- dynamic_cast<SurfaceOpenGL const &>
- (*g_gr->get_road_texture(Widelands::Road_Normal)).get_texture();
+ dynamic_cast<GLPictureTexture const &>
+ (*g_gr->get_road_texture(Widelands::Road_Normal)).get_gl_texture();
GLuint rt_busy =
- dynamic_cast<SurfaceOpenGL const &>
- (*g_gr->get_road_texture(Widelands::Road_Busy)).get_texture();
+ dynamic_cast<GLPictureTexture const &>
+ (*g_gr->get_road_texture(Widelands::Road_Busy)).get_gl_texture();
glDisable(GL_BLEND);
glColor4f(1.0f, 1.0f, 1.0f, 0.6f);
=== modified file 'src/graphic/render/terrain_sdl.h'
--- src/graphic/render/terrain_sdl.h 2010-11-05 19:36:57 +0000
+++ src/graphic/render/terrain_sdl.h 2010-11-27 16:29:59 +0000
@@ -23,6 +23,7 @@
#include "constants.h"
#include "log.h"
#include "random.h"
+#include "upcast.h"
#include "vertex.h"
#include "wui/mapviewpixelconstants.h"
@@ -532,7 +533,7 @@
}
template<typename T> static void render_road_horiz
- (SurfaceSDL & dst, Point const start, Point const end, Surface const & src)
+ (SurfaceSDL & dst, Point const start, Point const end, SurfaceSDL const & src)
{
int32_t const dstw = dst.get_w();
int32_t const dsth = dst.get_h();
@@ -559,7 +560,7 @@
}
template<typename T> static void render_road_vert
- (SurfaceSDL & dst, Point const start, Point const end, Surface const & src)
+ (SurfaceSDL & dst, Point const start, Point const end, SurfaceSDL const & src)
{
int32_t const dstw = dst.get_w();
int32_t const dsth = dst.get_h();
@@ -597,10 +598,10 @@
Texture const & f_d_texture,
Texture const & f_r_texture)
{
- Surface const & rt_normal = *g_gr->get_road_texture(Widelands::Road_Normal);
- Surface const & rt_busy = *g_gr->get_road_texture(Widelands::Road_Busy);
+ upcast(SurfaceSDL, rt_normal, g_gr->get_road_texture(Widelands::Road_Normal).get());
+ upcast(SurfaceSDL, rt_busy, g_gr->get_road_texture(Widelands::Road_Busy).get());
- dst.lock();
+ dst.lock(IPixelAccess::Lock_Normal);
render_triangle<T> (dst, f_vert, br_vert, r_vert, f_r_texture);
render_triangle<T> (dst, f_vert, bl_vert, br_vert, f_d_texture);
@@ -613,10 +614,10 @@
if (road) {
switch (road) {
case Widelands::Road_Normal:
- render_road_horiz<T> (dst, f_vert, r_vert, rt_normal);
+ render_road_horiz<T> (dst, f_vert, r_vert, *rt_normal);
break;
case Widelands::Road_Busy:
- render_road_horiz<T> (dst, f_vert, r_vert, rt_busy);
+ render_road_horiz<T> (dst, f_vert, r_vert, *rt_busy);
break;
default:
assert(false);
@@ -631,10 +632,10 @@
if (road) {
switch (road) {
case Widelands::Road_Normal:
- render_road_vert<T> (dst, f_vert, br_vert, rt_normal);
+ render_road_vert<T> (dst, f_vert, br_vert, *rt_normal);
break;
case Widelands::Road_Busy:
- render_road_vert<T> (dst, f_vert, br_vert, rt_busy);
+ render_road_vert<T> (dst, f_vert, br_vert, *rt_busy);
break;
default:
assert(false);
@@ -649,10 +650,10 @@
if (road) {
switch (road) {
case Widelands::Road_Normal:
- render_road_vert<T> (dst, f_vert, bl_vert, rt_normal);
+ render_road_vert<T> (dst, f_vert, bl_vert, *rt_normal);
break;
case Widelands::Road_Busy:
- render_road_vert<T> (dst, f_vert, bl_vert, rt_busy);
+ render_road_vert<T> (dst, f_vert, bl_vert, *rt_busy);
break;
default:
assert(false);
@@ -662,7 +663,7 @@
}
}
- dst.unlock();
+ dst.unlock(IPixelAccess::Unlock_Update);
// FIXME: similar textures may not need dithering
}
=== modified file 'src/graphic/rendertarget.cc'
--- src/graphic/rendertarget.cc 2010-06-14 19:31:37 +0000
+++ src/graphic/rendertarget.cc 2010-11-27 16:29:59 +0000
@@ -27,9 +27,7 @@
#include "logic/tribe.h"
#include "vertex.h"
-#include "surface.h"
-#include "graphic/render/surface_opengl.h"
-#include "graphic/render/surface_sdl.h"
+#include "offscreensurface.h"
#include "log.h"
#include "upcast.h"
@@ -43,16 +41,23 @@
using Widelands::TCoords;
/**
- * Build a render target for the given bitmap.
- * \note The bitmap will not be owned by the renderer, i.e. it won't be
- * deleted by the destructor.
+ * Build a render target for the given surface.
*/
-RenderTarget::RenderTarget(Surface * const bmp)
+RenderTarget::RenderTarget(SurfacePtr bmp)
{
m_surface = bmp;
reset();
}
+/**
+ * Build a render target for the given surface.
+ */
+RenderTarget::RenderTarget(OffscreenSurfacePtr surf)
+{
+ m_surface = surf;
+ reset();
+}
+
/**
* Sets an arbitrary drawing window.
@@ -178,108 +183,33 @@
}
/**
- * Blits a Surface on the screen or (if possible) on another Surface
- * Check g_gr->caps().offscreen_rendering to see if it is possible to blit
- * to a non screen surface.
- *
- * This blit function copies the pixels to the destination surface.
- * I the source surface contains a alpha channel this is used during
- * the blit.
- */
-void RenderTarget::blit(const Point dst, const PictureID picture)
-{
- if (Surface * const src = g_gr->get_picture_surface(picture))
- doblit
- (Rect(dst, 0, 0),
- src, Rect(Point(0, 0), src->get_w(), src->get_h()));
-}
-
-/**
- * Blits a Surface on the screen or (if possible) on another Surface
- * Check g_gr->caps().offscreen_rendering to see if it is possible to blit
- * to a non screen surface.
- *
- * This blit function copies the pixels to the destination surface.
- * I the source surface contains a alpha channel this is used during
- * the blit.
- */
-void RenderTarget::blit(const Rect dst, const PictureID picture)
-{
- if (Surface * const src = g_gr->get_picture_surface(picture))
- doblit(dst, src, Rect(Point(0, 0), src->get_w(), src->get_h()));
-}
-
-/**
- * Blits a Surface on the screen or (if possible) on another Surface
- * Check g_gr->caps().offscreen_rendering to see if it is possible to blit
- * to a non screen surface.
- *
- * This blit function copies the pixels values without alpha channel to the
- * destination surface.
- */
-void RenderTarget::blit_solid(const Point dst, const PictureID picture)
-{
- Surface * const src = g_gr->get_picture_surface(picture);
- if (not src)
- return;
-
- upcast(SurfaceSDL, sdlsurf, src);
- upcast(SurfaceOpenGL, oglsurf, src);
-
- if (sdlsurf) {
- bool alpha;
- uint8_t alphaval;
- alpha = sdlsurf->get_sdl_surface()->flags & SDL_SRCALPHA;
- alphaval = sdlsurf->get_sdl_surface()->format->alpha;
- SDL_SetAlpha(sdlsurf->get_sdl_surface(), 0, 0);
- doblit
- (Rect(dst, 0, 0),
- src, Rect(Point(0, 0), src->get_w(), src->get_h()), false);
- SDL_SetAlpha(sdlsurf->get_sdl_surface(), alpha?SDL_SRCALPHA:0, alphaval);
- } else if (oglsurf) {
- doblit
- (Rect(dst, 0, 0),
- src, Rect(Point(0, 0), src->get_w(), src->get_h()), false);
- }
-}
-
-/**
- * Blits a Surface on the screen or (if possible) on another Surface
- * Check g_gr->caps().offscreen_rendering to see if it is possible to blit
- * to a non screen surface.
- *
- * This blit function copies the pixels (including alpha channel)
- * to the destination surface.
- * The destination pixels will be exactly like the source pixels.
- */
-void RenderTarget::blit_copy(Point dst, PictureID picture)
-{
- Surface * const src = g_gr->get_picture_surface(picture);
- upcast(SurfaceSDL, sdlsurf, src);
- bool alpha;
- uint8_t alphaval;
- if (sdlsurf) {
- alpha = sdlsurf->get_sdl_surface()->flags & SDL_SRCALPHA;
- alphaval = sdlsurf->get_sdl_surface()->format->alpha;
- SDL_SetAlpha(sdlsurf->get_sdl_surface(), 0, 0);
- }
- if (src)
- doblit
- (Rect(dst, 0, 0),
- src, Rect(Point(0, 0), src->get_w(), src->get_h()), false);
- if (sdlsurf) {
- SDL_SetAlpha(sdlsurf->get_sdl_surface(), alpha?SDL_SRCALPHA:0, alphaval);
- }
-}
-
+ * Blits a Picture on the screen or (if possible) on another Surface
+ * Check g_gr->caps().offscreen_rendering to see if it is possible to blit
+ * to a non screen surface.
+ *
+ * This blit function copies the pixels to the destination surface.
+ * I the source surface contains a alpha channel this is used during
+ * the blit.
+ */
+void RenderTarget::blit(const Point dst, const PictureID picture, Composite cm)
+{
+ if (picture->valid())
+ doblit
+ (Rect(dst, 0, 0),
+ picture, Rect(Point(0, 0), picture->get_w(), picture->get_h()), cm);
+}
+
+/**
+ * Like \ref blit, but use only a sub-rectangle of the source picture.
+ */
void RenderTarget::blitrect
- (Point const dst, PictureID const picture, Rect const srcrc)
+ (Point const dst, PictureID const picture, Rect const srcrc, Composite cm)
{
assert(0 <= srcrc.x);
assert(0 <= srcrc.y);
- if (Surface * const src = g_gr->get_picture_surface(picture))
- doblit(Rect(dst, 0, 0), src, srcrc);
+ if (picture->valid())
+ doblit(Rect(dst, 0, 0), picture, srcrc, cm);
}
/**
@@ -288,24 +218,25 @@
* The pixel from ofs inside picture is placed at the top-left corner of
* the filled rectangle.
*/
-void RenderTarget::tile(Rect r, PictureID const picture, Point ofs)
+void RenderTarget::tile(Rect r, PictureID const picture, Point ofs, Composite cm)
{
- Surface * const src = g_gr->get_picture_surface(picture);
-
- if (!src)
+ if (!picture->valid())
return;
+ int32_t srcw = picture->get_w();
+ int32_t srch = picture->get_h();
+
if (clip(r)) {
// Make sure the offset is within bounds
- ofs.x = ofs.x % src->get_w();
+ ofs.x = ofs.x % srcw;
if (ofs.x < 0)
- ofs.x += src->get_w();
+ ofs.x += srcw;
- ofs.y = ofs.y % src->get_h();
+ ofs.y = ofs.y % srch;
if (ofs.y < 0)
- ofs.y += src->get_h();
+ ofs.y += srch;
// Blit the picture into the rectangle
uint32_t ty = 0;
@@ -316,19 +247,19 @@
Rect srcrc;
srcrc.y = ofs.y;
- srcrc.h = src->get_h() - ofs.y;
+ srcrc.h = srch - ofs.y;
if (ty + srcrc.h > r.h)
srcrc.h = r.h - ty;
while (tx < r.w) {
srcrc.x = tofsx;
- srcrc.w = src->get_w() - tofsx;
+ srcrc.w = srcw - tofsx;
if (tx + srcrc.w > r.w)
srcrc.w = r.w - tx;
- m_surface->blit(r + Point(tx, ty), src, srcrc);
+ m_surface->blit(r + Point(tx, ty), picture, srcrc, cm);
tx += srcrc.w;
@@ -372,7 +303,7 @@
// Get the frame and its data
uint32_t const framenumber = time / data->frametime % gfx->nr_frames();
- Surface * const frame =
+ const PictureID & frame =
player ?
gfx->get_frame
(framenumber, player->player_number(), player->get_playercolor())
@@ -411,7 +342,7 @@
// Get the frame and its data
uint32_t const framenumber = time / data->frametime % gfx->nr_frames();
- Surface * const frame =
+ const PictureID & frame =
player ?
gfx->get_frame
(framenumber, player->player_number(), player->get_playercolor())
@@ -486,14 +417,13 @@
* Clip against window and source bitmap, then call the Bitmap blit routine.
*/
void RenderTarget::doblit
- (Rect dst, Surface * const src, Rect srcrc, bool enable_alpha)
+ (Point dst, PictureID src, Rect srcrc, Composite cm)
{
assert(0 <= srcrc.x);
assert(0 <= srcrc.y);
dst += m_offset;
// Clipping
-
if (dst.x < 0) {
if (srcrc.w <= static_cast<uint32_t>(-dst.x))
return;
@@ -527,10 +457,5 @@
dst += m_rect;
- // Draw it
- upcast(SurfaceOpenGL, oglsurf, m_surface);
- if (oglsurf and dst.w and dst.h)
- oglsurf->blit(dst, src, srcrc, enable_alpha);
- else
- m_surface->blit(Point(dst.x, dst.y), src, srcrc, enable_alpha);
+ m_surface->blit(dst, src, srcrc, cm);
}
=== modified file 'src/graphic/rendertarget.h'
--- src/graphic/rendertarget.h 2010-11-10 20:05:21 +0000
+++ src/graphic/rendertarget.h 2010-11-27 16:29:59 +0000
@@ -20,7 +20,9 @@
#ifndef RENDERTARGET_H
#define RENDERTARGET_H
+#include "compositemode.h"
#include "picture_id.h"
+#include "surfaceptr.h"
#include "rect.h"
#include "rgbcolor.h"
@@ -29,7 +31,6 @@
namespace Widelands {
struct Player;
};
-struct Surface;
/**
* This abstract class represents anything that can be rendered to.
@@ -47,7 +48,8 @@
* false and doesn't change the window state at all.
*/
struct RenderTarget {
- RenderTarget(Surface *);
+ RenderTarget(SurfacePtr);
+ RenderTarget(OffscreenSurfacePtr);
RenderTarget(RenderTarget & rt):
m_surface(rt.m_surface),
m_rect(rt.m_rect),
@@ -70,12 +72,9 @@
void brighten_rect(Rect, int32_t factor);
void clear();
- void blit(Point dst, PictureID picture);
- void blit(Rect dst, PictureID picture);
- void blit_solid(Point dst, PictureID picture);
- void blit_copy(Point dst, PictureID picture);
- void blitrect(Point dst, PictureID picture, Rect src);
- void tile(Rect, PictureID picture, Point ofs);
+ void blit(Point dst, PictureID picture, Composite cm = CM_Normal);
+ void blitrect(Point dst, PictureID picture, Rect src, Composite cm = CM_Normal);
+ void tile(Rect, PictureID picture, Point ofs, Composite cm = CM_Normal);
void drawanim
(Point dst,
@@ -92,15 +91,15 @@
void reset();
- Surface & get_surface() {return *m_surface;}
+ SurfacePtr get_surface() {return m_surface;}
protected:
bool clip(Rect & r) const throw ();
- void doblit(Rect dst, Surface * src, Rect srcrc, bool enable_alpha = true);
+ void doblit(Point dst, PictureID src, Rect srcrc, Composite cm = CM_Normal);
///The target surface
- Surface * m_surface;
+ SurfacePtr m_surface;
///The current clip rectangle
Rect m_rect;
///Drawing offset
=== modified file 'src/graphic/surface.h'
--- src/graphic/surface.h 2010-11-01 22:37:46 +0000
+++ src/graphic/surface.h 2010-11-27 16:29:59 +0000
@@ -20,80 +20,28 @@
#ifndef SURFACE_H
#define SURFACE_H
+#include "compositemode.h"
#include "rgbcolor.h"
#include "rect.h"
+#include "surfaceptr.h"
#include "wexception.h"
/**
- * The type of a surface. This make it possible to check a bit before drawing.
+ * Interface to a basic surfaces that can be used as destination for drawing.
*/
-enum SurfaceType {
- SURFACE_INVALID,
- SURFACE_SOURCE, ///< This sourface is used as source only
- SURFACE_OFFSCREEN, ///< Use surface as source and destinantion
- SURFACE_SCREEN ///< This draws to screen directly
-};
-
-/// A virtual base for rendering. Objects of Surface are used as Source or
-/// destination for drawing. Surfaces are created with the
-/// Graphic::create_surface() functions.
struct Surface {
+ Surface() {}
virtual ~Surface() {}
//@{
/// Get width and height
- virtual uint32_t get_w() const {return m_w;}
- virtual uint32_t get_h() const {return m_h;}
+ virtual uint32_t get_w() = 0;
+ virtual uint32_t get_h() = 0;
//@}
/// Update the screen. This is only useful for the screen surface.
virtual void update() = 0;
- //@{
- /// For the slowest: Indirect pixel access.
- /// A safe function to get and set single pixels. lock() must be called
- /// before pixel access can be used. get_pixel() and set_pixel() are easier
- /// and safer to use but also much slower than direct pixel access.
- virtual uint32_t get_pixel(uint32_t x, uint32_t y) {
- // FIXME make abstract or move body out of declaration
- throw wexception("get_pixel() not implemented");
- }
- virtual void set_pixel(uint32_t x, uint32_t y, Uint32 clr) {
- // FIXME make abstract or move body out of declaration
- throw wexception("set_pixel() not implemented");
- }
- //@}
-
- //@{
- /**
- * Locking and unlocking the surface for pixel access. This may be slow. So
- * use it with care.
- */
-
- virtual void lock() {};
- virtual void unlock() {};
- //@}
-
- /// This returns the pixel format for direct pixel access.
- virtual SDL_PixelFormat const & format() const {
- throw wexception("format() not implemented");
- }
-
- //@{
- /**
- * Direct pixel access. lock() must be called before pixles may be access.
- * This is faster than indirect pixel access but also more dangerous.
- * get_pixels() gives a pointer to the pixel data. get_pitch() returns an
- * integer where the next row begins.
- */
- virtual uint16_t get_pitch() const {
- throw wexception("get_pitch() not implemented");
- }
- virtual uint8_t * get_pixels() const {
- throw wexception("get_pixels() not implemented");
- }
- //@}
-
/// Clears the complete surface to black.
virtual void clear() {
fill_rect
@@ -123,36 +71,16 @@
virtual void brighten_rect(Rect, int32_t factor) = 0;
/// This draws a part aother surface to this surface
- virtual void blit(Point, Surface *, Rect srcrc, bool enable_alpha = false) = 0;
+ virtual void blit(Point, PictureID, Rect srcrc, Composite cm = CM_Normal) = 0;
/// This draws another surface completely in the left
/// upper corner of this surface
- virtual void fast_blit(Surface * surface) {
- blit
- (Point(0, 0),
- surface,
- Rect(Point(0, 0), surface->get_w(), surface->get_h()));
- }
-
- /// set the type of the surface
- virtual void set_type(SurfaceType const type) {m_surf_type = type;}
-
-protected:
- int32_t m_offsx;
- int32_t m_offsy;
- uint32_t m_w, m_h;
-
- Surface():
- m_offsx(0), m_offsy(0),
- m_w(0), m_h(0),
- m_surf_type(SURFACE_INVALID)
- {}
- Surface(int w, int h, SurfaceType t):
- m_offsx(0), m_offsy(0),
- m_w(w), m_h(h),
- m_surf_type(t)
- {}
- SurfaceType m_surf_type;
+ virtual void fast_blit(PictureID surface) = 0;
+
+ virtual IPixelAccess & pixelaccess() = 0;
+
private:
+ // surfaces cannot be copied
+ Surface(const Surface &);
Surface & operator= (Surface const &);
};
=== added file 'src/graphic/surfaceptr.h'
--- src/graphic/surfaceptr.h 1970-01-01 00:00:00 +0000
+++ src/graphic/surfaceptr.h 2010-11-27 16:29:59 +0000
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2010 by the Widelands Development Team
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+#ifndef SURFACEPTR_H
+#define SURFACEPTR_H
+
+#include <boost/shared_ptr.hpp>
+
+struct IOffscreenSurface;
+struct Surface;
+
+typedef boost::shared_ptr<IOffscreenSurface> OffscreenSurfacePtr;
+typedef boost::shared_ptr<Surface> SurfacePtr;
+
+#endif // SURFACEPTR_H
=== modified file 'src/graphic/texture.cc'
--- src/graphic/texture.cc 2010-11-21 11:44:22 +0000
+++ src/graphic/texture.cc 2010-11-27 16:29:59 +0000
@@ -102,14 +102,14 @@
#ifdef USE_OPENGL
if (g_opengl) {
- SurfaceOpenGL * tsurface =
- &dynamic_cast<SurfaceOpenGL &>
- (g_gr->load_image(fname));
- // SDL_ConvertSurface(surf, &fmt, 0);
- m_glFrames.push_back(tsurface);
- tsurface->lock();
- m_mmap_color = tsurface->get_pixel(0, 0);
- tsurface->unlock();
+ // Note: we except the constructor to free the SDL surface
+ boost::shared_ptr<GLPictureTexture> surface(new GLPictureTexture(surf));
+ m_glFrames.push_back(surface);
+
+ surface->lock(IPixelAccess::Lock_Normal);
+ m_mmap_color = surface->get_pixel(0, 0);
+ surface->unlock(IPixelAccess::Unlock_NoChange);
+
++m_nrframes;
continue;
}
@@ -181,11 +181,6 @@
delete m_colormap;
free(m_pixels);
free(m_texture_picture);
-
-#ifdef USE_OPENGL
- container_iterate(std::vector<SurfaceOpenGL *>, m_glFrames, it)
- delete *it.current;
-#endif
}
/**
=== modified file 'src/graphic/texture.h'
--- src/graphic/texture.h 2010-11-01 22:37:46 +0000
+++ src/graphic/texture.h 2010-11-27 16:29:59 +0000
@@ -23,7 +23,7 @@
#include "colormap.h"
#include "picture_id.h"
-#include "graphic/render/surface_opengl.h"
+#include "graphic/render/gl_picture_texture.h"
#include <boost/shared_ptr.hpp>
#include <stdint.h>
@@ -65,7 +65,7 @@
bool was_animated() const throw () {return m_was_animated;}
#ifdef USE_OPENGL
uint32_t getTexture() const
- {return m_glFrames.at(m_frame_num)->get_texture();}
+ {return m_glFrames.at(m_frame_num)->get_gl_texture();}
#endif
private:
@@ -80,7 +80,7 @@
bool is_32bit;
bool m_was_animated;
#ifdef USE_OPENGL
- std::vector<SurfaceOpenGL *> m_glFrames;
+ std::vector<boost::shared_ptr<GLPictureTexture> > m_glFrames;
#endif
};
=== modified file 'src/map_io/widelands_map_extradata_data_packet.cc'
--- src/map_io/widelands_map_extradata_data_packet.cc 2010-05-12 10:16:44 +0000
+++ src/map_io/widelands_map_extradata_data_packet.cc 2010-11-27 16:29:59 +0000
@@ -75,20 +75,19 @@
if (!surf)
continue; // Illegal pic. Skip it.
- Surface & picsurf = g_gr->create_surface(*surf);
+ PictureID const picture = g_gr->convert_sdl_surface_to_picture(surf);
std::string picname = FileSystem::FS_Filename(pname->c_str());
picname = "map:" + picname;
- PictureID const data =
- g_gr->get_picture(PicMod_Game, picsurf, picname.c_str());
+ g_gr->add_picture_to_cache(PicMod_Game, picname, picture);
// OK, the pic is now known to the game. But when the game is
// saved, this data has to be regenerated.
Map::Extradata_Info info;
info.type = Map::Extradata_Info::PIC;
info.filename = *pname;
- info.data = data;
+ info.data = picture;
map.m_extradatainfos.push_back(info);
}
}
=== modified file 'src/ui_basic/button.cc'
--- src/ui_basic/button.cc 2010-11-01 23:32:46 +0000
+++ src/ui_basic/button.cc 2010-11-27 16:29:59 +0000
@@ -22,6 +22,7 @@
#include "mouse_constants.h"
#include "graphic/font_handler.h"
+#include "graphic/offscreensurface.h"
#include "graphic/rendertarget.h"
#include "wlapplication.h"
#include "log.h"
@@ -48,7 +49,6 @@
m_repeating (false),
m_flat (flat),
m_needredraw (true),
- m_cache_pic (g_gr->get_no_picture()),
m_title (title_text),
m_pic_background(background_picture_id),
m_pic_custom (g_gr->get_no_picture()),
@@ -81,7 +81,6 @@
m_repeating (false),
m_flat (flat),
m_needredraw (true),
- m_cache_pic (g_gr->get_no_picture()),
m_pic_background(background_picture_id),
m_pic_custom (foreground_picture_id),
m_pic_custom_disabled(g_gr->create_grayed_out_pic(foreground_picture_id)),
@@ -94,9 +93,8 @@
}
-Button::~Button() {
- if (m_pic_custom_disabled != g_gr->get_no_picture())
- g_gr->free_picture_surface(m_pic_custom_disabled);
+Button::~Button()
+{
}
@@ -113,8 +111,6 @@
m_needredraw = true;
m_pic_custom = picid;
- if (m_pic_custom_disabled != g_gr->get_no_picture())
- g_gr->free_picture_surface(m_pic_custom_disabled);
m_pic_custom_disabled = g_gr->create_grayed_out_pic(picid);
update();
@@ -168,7 +164,7 @@
*/
void Button::draw(RenderTarget & odst)
{
- RenderTarget * dst = &odst;
+ RenderTarget dst = odst;
if (g_gr->caps().offscreen_rendering) {
if (!m_needredraw)
@@ -176,18 +172,15 @@
odst.blit(Point(0, 0), m_cache_pic);
return;
} else {
- if (m_cache_pic == g_gr->get_no_picture())
- m_cache_pic =
- g_gr->create_picture_surface(get_w(), get_h(), m_flat);
- else if
- (m_cache_pic->rendertarget->get_w() != get_w() or
- m_cache_pic->rendertarget->get_h() != get_h())
+ if
+ (!m_cache_pic ||
+ (static_cast<IPicture *>(m_cache_pic.get())->get_w() != static_cast<uint32_t>(get_w()) or
+ static_cast<IPicture *>(m_cache_pic.get())->get_h() != static_cast<uint32_t>(get_h())))
{
- g_gr->free_picture_surface(m_cache_pic);
m_cache_pic =
- g_gr->create_picture_surface(get_w(), get_h(), m_flat);
+ g_gr->create_offscreen_surface(get_w(), get_h(), m_flat);
}
- dst = (g_gr->get_surface_renderer(m_cache_pic));
+ dst = RenderTarget(m_cache_pic);
}
}
@@ -195,18 +188,18 @@
// Draw the background
if (not m_flat) {
assert(m_pic_background != g_gr->get_no_picture());
- dst->fill_rect
+ dst.fill_rect
(Rect(Point(0, 0), get_w(), get_h()), RGBAColor(0, 0, 0, 255));
- dst->tile
+ dst.tile
(Rect(Point(0, 0), get_w(), get_h()),
m_pic_background,
Point(get_x(), get_y()));
} else if (g_gr->caps().offscreen_rendering)
- dst->fill_rect
+ dst.fill_rect
(Rect(Point(0, 0), get_w(), get_h()), RGBAColor(0, 0, 0, 0));
if (m_enabled and m_highlighted and not m_flat)
- dst->brighten_rect
+ dst.brighten_rect
(Rect(Point(0, 0), get_w(), get_h()), MOUSE_OVER_BRIGHT_FACTOR);
// if we got a picture, draw it centered
@@ -217,13 +210,14 @@
// ">> 1" is almost like "/ 2", but simpler for signed types (difference
// is that -1 >> 1 is -1 but -1 / 2 is 0).
if (g_gr->caps().offscreen_rendering and m_flat)
- dst->blit_copy
+ dst.blit
(Point
((get_w() - static_cast<int32_t>(cpw)) >> 1,
(get_h() - static_cast<int32_t>(cph)) >> 1),
- m_enabled ? m_pic_custom : m_pic_custom_disabled);
+ m_enabled ? m_pic_custom : m_pic_custom_disabled,
+ CM_Copy);
else
- dst->blit
+ dst.blit
(Point
((get_w() - static_cast<int32_t>(cpw)) >> 1,
(get_h() - static_cast<int32_t>(cph)) >> 1),
@@ -231,7 +225,7 @@
} else if (m_title.length()) // otherwise draw title string centered
UI::g_fh->draw_string
- (*dst,
+ (dst,
m_fontname,
m_fontsize,
m_enabled ? UI_FONT_CLR_FG : UI_FONT_CLR_DISABLED, UI_FONT_CLR_BG,
@@ -240,7 +234,7 @@
Align_Center,
std::numeric_limits<uint32_t>::max(),
Widget_Cache_None,
- g_gr->get_no_picture(),
+ 0,
m_draw_caret ? m_title.length() :
std::numeric_limits<uint32_t>::max());
@@ -260,32 +254,32 @@
// button is a normal one, not flat
if (not draw_pressed) {
// top edge
- dst->brighten_rect
+ dst.brighten_rect
(Rect(Point(0, 0), get_w(), 2), BUTTON_EDGE_BRIGHT_FACTOR);
// left edge
- dst->brighten_rect
+ dst.brighten_rect
(Rect(Point(0, 2), 2, get_h() - 2), BUTTON_EDGE_BRIGHT_FACTOR);
// bottom edge
- dst->fill_rect(Rect(Point(2, get_h() - 2), get_w() - 2, 1), black);
- dst->fill_rect(Rect(Point(1, get_h() - 1), get_w() - 1, 1), black);
+ dst.fill_rect(Rect(Point(2, get_h() - 2), get_w() - 2, 1), black);
+ dst.fill_rect(Rect(Point(1, get_h() - 1), get_w() - 1, 1), black);
// right edge
- dst->fill_rect(Rect(Point(get_w() - 2, 2), 1, get_h() - 2), black);
- dst->fill_rect(Rect(Point(get_w() - 1, 1), 1, get_h() - 1), black);
+ dst.fill_rect(Rect(Point(get_w() - 2, 2), 1, get_h() - 2), black);
+ dst.fill_rect(Rect(Point(get_w() - 1, 1), 1, get_h() - 1), black);
} else {
// bottom edge
- dst->brighten_rect
+ dst.brighten_rect
(Rect(Point(0, get_h() - 2), get_w(), 2),
BUTTON_EDGE_BRIGHT_FACTOR);
// right edge
- dst->brighten_rect
+ dst.brighten_rect
(Rect(Point(get_w() - 2, 0), 2, get_h() - 2),
BUTTON_EDGE_BRIGHT_FACTOR);
// top edge
- dst->fill_rect(Rect(Point(0, 0), get_w() - 1, 1), black);
- dst->fill_rect(Rect(Point(0, 1), get_w() - 2, 1), black);
+ dst.fill_rect(Rect(Point(0, 0), get_w() - 1, 1), black);
+ dst.fill_rect(Rect(Point(0, 1), get_w() - 2, 1), black);
// left edge
- dst->fill_rect(Rect(Point(0, 0), 1, get_h() - 1), black);
- dst->fill_rect(Rect(Point(1, 0), 1, get_h() - 2), black);
+ dst.fill_rect(Rect(Point(0, 0), 1, get_h() - 1), black);
+ dst.fill_rect(Rect(Point(1, 0), 1, get_h() - 2), black);
}
} else {
// Button is flat, do not draw borders, instead, if it is pressed, draw
@@ -293,10 +287,10 @@
if (m_enabled and m_highlighted)
{
RGBAColor shade(100, 100, 100, 80);
- dst->fill_rect(Rect(Point(0, 0), get_w(), 2), shade);
- dst->fill_rect(Rect(Point(0, 2), 2, get_h() - 2), shade);
- dst->fill_rect(Rect(Point(0, get_h() - 2), get_w(), get_h()), shade);
- dst->fill_rect(Rect(Point(get_w() - 2, 0), get_w(), get_h()), shade);
+ dst.fill_rect(Rect(Point(0, 0), get_w(), 2), shade);
+ dst.fill_rect(Rect(Point(0, 2), 2, get_h() - 2), shade);
+ dst.fill_rect(Rect(Point(0, get_h() - 2), get_w(), get_h()), shade);
+ dst.fill_rect(Rect(Point(get_w() - 2, 0), get_w(), get_h()), shade);
//dst.draw_rect(Rect(Point(0, 0), get_w(), get_h()), m_clr_down);
}
}
=== modified file 'src/ui_basic/button.h'
--- src/ui_basic/button.h 2010-11-01 23:54:06 +0000
+++ src/ui_basic/button.h 2010-11-27 16:29:59 +0000
@@ -99,7 +99,7 @@
bool m_repeating;
bool m_flat;
bool m_needredraw;
- PictureID m_cache_pic;
+ OffscreenSurfacePtr m_cache_pic;
int32_t m_time_nextact;
=== modified file 'src/ui_basic/checkbox.cc'
--- src/ui_basic/checkbox.cc 2010-06-16 18:43:40 +0000
+++ src/ui_basic/checkbox.cc 2010-11-27 16:29:59 +0000
@@ -54,11 +54,8 @@
}
-Statebox::~Statebox() {
- if (m_flags & Owns_Custom_Picture) {
- assert(m_flags & Has_Custom_Picture);
- g_gr->free_picture_surface(m_pic_graphics);
- }
+Statebox::~Statebox()
+{
}
=== modified file 'src/ui_basic/editbox.cc'
--- src/ui_basic/editbox.cc 2010-11-01 23:54:06 +0000
+++ src/ui_basic/editbox.cc 2010-11-27 16:29:59 +0000
@@ -401,7 +401,7 @@
align(),
std::numeric_limits<uint32_t>::max(),
Widget_Cache_None,
- g_gr->get_no_picture(),
+ 0,
has_focus() ? static_cast<int32_t>(m->caret) :
std::numeric_limits<uint32_t>::max());
}
=== modified file 'src/ui_basic/icon.cc'
--- src/ui_basic/icon.cc 2010-11-02 20:11:05 +0000
+++ src/ui_basic/icon.cc 2010-11-27 16:29:59 +0000
@@ -19,7 +19,7 @@
#include "icon.h"
#include "graphic/rendertarget.h"
-#include "graphic/surface.h"
+#include "graphic/picture.h"
namespace UI {
@@ -44,8 +44,8 @@
void Icon::draw(RenderTarget & dst) {
assert(m_pic != g_gr->get_no_picture());
- int32_t w = (m_w - m_pic->surface->get_w()) / 2;
- int32_t h = (m_h - m_pic->surface->get_h()) / 2;
+ int32_t w = (m_w - m_pic->get_w()) / 2;
+ int32_t h = (m_h - m_pic->get_h()) / 2;
dst.blit(Point(w, h), m_pic);
}
=== modified file 'src/ui_basic/listselect.cc'
--- src/ui_basic/listselect.cc 2010-06-16 18:43:40 +0000
+++ src/ui_basic/listselect.cc 2010-11-27 16:29:59 +0000
@@ -21,6 +21,7 @@
#include "constants.h"
#include "graphic/font_handler.h"
+#include "graphic/offscreensurface.h"
#include "graphic/rendertarget.h"
#include "wlapplication.h"
#include "log.h"
@@ -55,8 +56,7 @@
m_show_check(show_check),
m_fontname(UI_FONT_NAME),
m_fontsize(UI_FONT_SIZE_SMALL),
- m_needredraw(true),
- m_cache_pic(g_gr->get_no_picture())
+ m_needredraw(true)
{
set_think(false);
@@ -347,7 +347,7 @@
*/
void BaseListselect::draw(RenderTarget & odst)
{
- RenderTarget * dst = &odst;
+ RenderTarget dst = odst;
// Render Caching is disable because it does not work good with the
// transparent background.
@@ -357,11 +357,11 @@
odst.blit(Point(0, 0), m_cache_pic);
return;
} else {
- if (m_cache_pic == g_gr->get_no_picture())
+ if (!m_cache_pic)
m_cache_pic =
- g_gr->create_picture_surface(get_w(), get_h());
+ g_gr->create_offscreen_surface(get_w(), get_h());
// TODO: Handle resize here
- dst = (g_gr->get_surface_renderer(m_cache_pic));
+ dst = RenderTarget(m_cache_pic);
}
}
@@ -371,7 +371,7 @@
int32_t y = 1 + idx * lineheight - m_scrollpos;
//if (not g_gr->caps().offscreen_rendering)
- dst->brighten_rect(Rect(Point(0, 0), get_w(), get_h()), ms_darken_value);
+ dst.brighten_rect(Rect(Point(0, 0), get_w(), get_h()), ms_darken_value);
//else
//dst->fill_rect
//(Rect(Point(0, 0), get_w(), get_h()), RGBAColor(20, 20, 20, 80));
@@ -403,7 +403,7 @@
//if (g_gr->caps().offscreen_rendering and false)
//dst->fill_rect(r, RGBAColor(100, 100, 100, 80));
//else
- dst->brighten_rect
+ dst.brighten_rect
(r, - ms_darken_value * 2);
//(Rect(Point(1, y), get_eff_w() - 2,
// m_lineheight), -ms_darken_value*2);
@@ -423,7 +423,7 @@
// Horizontal center the string
UI::g_fh->draw_string
- (*dst,
+ (dst,
m_fontname, m_fontsize,
col,
RGBColor(107, 87, 55),
@@ -442,11 +442,9 @@
uint32_t w, h;
g_gr->get_picture_size(er.picid, w, h);
if (g_gr->caps().offscreen_rendering and false)
- dst->blit_solid
- (Point(1, y + (get_lineheight() - h) / 2), er.picid);
+ dst.blit(Point(1, y + (get_lineheight() - h) / 2), er.picid, CM_Solid);
else
- dst->blit
- (Point(1, y + (get_lineheight() - h) / 2), er.picid);
+ dst.blit(Point(1, y + (get_lineheight() - h) / 2), er.picid);
}
y += lineheight;
=== modified file 'src/ui_basic/listselect.h'
--- src/ui_basic/listselect.h 2010-05-16 14:57:40 +0000
+++ src/ui_basic/listselect.h 2010-11-27 16:29:59 +0000
@@ -149,7 +149,7 @@
uint32_t m_fontsize;
bool m_needredraw;
- PictureID m_cache_pic;
+ OffscreenSurfacePtr m_cache_pic;
};
template<typename Entry>
=== modified file 'src/ui_basic/multilineeditbox.cc'
--- src/ui_basic/multilineeditbox.cc 2010-05-12 11:20:58 +0000
+++ src/ui_basic/multilineeditbox.cc 2010-11-27 16:29:59 +0000
@@ -297,7 +297,7 @@
m_align,
get_eff_w(),
m_cache_mode,
- m_cache_id,
+ &m_cache_id,
// explicit cast is necessary to avoid a compiler warning
has_focus() ? static_cast<int32_t>(m_cur_pos) :
std::numeric_limits<uint32_t>::max());
=== modified file 'src/ui_basic/multilinetextarea.cc'
--- src/ui_basic/multilinetextarea.cc 2010-09-25 08:11:16 +0000
+++ src/ui_basic/multilinetextarea.cc 2010-11-27 16:29:59 +0000
@@ -62,9 +62,8 @@
/**
* Free allocated resources
*/
-Multiline_Textarea::~Multiline_Textarea() {
- if (m_cache_id != g_gr->get_no_picture())
- UI::g_fh->delete_widget_cache(m_cache_id);
+Multiline_Textarea::~Multiline_Textarea()
+{
}
@@ -132,7 +131,7 @@
m_text,
m_align,
get_eff_w(),
- m_cache_mode, m_cache_id);
+ m_cache_mode, &m_cache_id);
else
UI::g_fh->draw_richtext
(dst,
@@ -140,7 +139,7 @@
Point(get_halign(), 0 - m_textpos),
m_text,
get_eff_w(),
- m_cache_mode, m_cache_id);
+ m_cache_mode, &m_cache_id);
draw_scrollbar();
m_cache_mode = Widget_Cache_Use;
}
=== modified file 'src/ui_basic/panel.cc'
--- src/ui_basic/panel.cc 2010-11-02 20:11:05 +0000
+++ src/ui_basic/panel.cc 2010-11-27 16:29:59 +0000
@@ -51,7 +51,7 @@
:
_parent(nparent), _fchild(0), _lchild(0), _mousein(0), _focus(0),
_flags(pf_handle_mouse|pf_think|pf_visible),
- _cache(g_gr->get_no_picture()), _needdraw(false),
+ _needdraw(false),
_x(nx), _y(ny), _w(nw), _h(nh),
_lborder(0), _rborder(0), _tborder(0), _bborder(0),
_border_snap_distance(0), _panel_snap_distance(0),
@@ -80,9 +80,6 @@
{
update();
- if (_cache != g_gr->get_no_picture())
- g_gr->free_picture_surface(_cache);
-
// Release pointers to this object
if (_g_mousegrab == this)
_g_mousegrab = 0;
@@ -254,9 +251,9 @@
_w = nw;
_h = nh;
- if (_cache != g_gr->get_no_picture()) {
- g_gr->free_picture_surface(_cache);
- _cache = g_gr->create_picture_surface(_w, _h);
+ if (_cache) {
+ // The old surface is freed automatically
+ _cache = g_gr->create_offscreen_surface(_w, _h);
}
if (_parent)
@@ -775,7 +772,7 @@
if (!is_visible())
return;
- if (_cache == g_gr->get_no_picture())
+ if (!_cache)
{
Rect outerrc;
Point outerofs;
@@ -1100,7 +1097,7 @@
Align_Left,
TIP_WIDTH_MAX,
Widget_Cache_None,
- g_gr->get_no_picture(),
+ 0,
std::numeric_limits<uint32_t>::max(),
false);
}
=== modified file 'src/ui_basic/panel.h'
--- src/ui_basic/panel.h 2010-11-02 20:11:05 +0000
+++ src/ui_basic/panel.h 2010-11-27 16:29:59 +0000
@@ -25,6 +25,7 @@
#include "point.h"
#include "graphic/picture_id.h"
+#include "graphic/surfaceptr.h"
#include "graphic/graphic.h"
#include <SDL_keyboard.h>
@@ -258,7 +259,7 @@
Panel * _focus; // keyboard focus
uint32_t _flags;
- PictureID _cache;
+ OffscreenSurfacePtr _cache;
bool _needdraw;
/**
=== modified file 'src/ui_basic/progresswindow.cc'
--- src/ui_basic/progresswindow.cc 2010-11-01 23:54:06 +0000
+++ src/ui_basic/progresswindow.cc 2010-11-27 16:29:59 +0000
@@ -50,8 +50,6 @@
}
ProgressWindow::~ProgressWindow() {
- if (m_background_pic != g_gr->get_no_picture())
- g_gr->free_picture_surface(m_background_pic);
const VisualizationArray & visualizations = m_visualizations;
container_iterate_const(VisualizationArray, visualizations, i)
(*i.current)->stop(); // inform visualizations
@@ -68,27 +66,17 @@
(m_background_pic == g_gr->get_no_picture()
or xres != m_xres or yres != m_yres)
{
- if (m_background_pic != g_gr->get_no_picture())
- g_gr->free_picture_surface(m_background_pic);
-
- // Load background graphics
+ // (Re-)Load background graphics
+ // Note that the old pic is freed automatically
PictureID const background_original =
g_gr->get_picture(PicMod_Menu, m_background.c_str());
- if (g_gr->caps().resize_surfaces and not g_gr->caps().blit_resized) {
- PictureID const background_resized =
- g_gr->get_resized_picture
- (background_original, xres, yres,
- Graphic::ResizeMode_Loose);
+ PictureID const background_resized =
+ g_gr->get_resized_picture
+ (background_original, xres, yres,
+ Graphic::ResizeMode_Loose);
- if (background_resized != g_gr->get_no_picture()) {
- m_background_pic = background_resized;
- if (background_resized != background_original)
- g_gr->free_picture_surface(background_original);
- } else
- m_background_pic = background_original;
- } else
- m_background_pic = background_original;
+ m_background_pic = background_resized;
const uint32_t h = g_fh->get_fontheight (UI_FONT_SMALL);
m_label_rectangle.x = xres / 4;
@@ -101,12 +89,7 @@
m_yres = yres;
}
- if (g_gr->caps().resize_surfaces and not g_gr->caps().blit_resized)
- rt.blit
- (Point(0, 0), m_background_pic);
- else
- rt.blit
- (Rect(Point(0, 0), rt.get_w(), rt.get_h()), m_background_pic);
+ rt.blit(Point(0, 0), m_background_pic);
Rect border_rect = m_label_rectangle;
border_rect.x -= PROGRESS_STATUS_BORDER_X;
@@ -144,7 +127,6 @@
} else
m_background = "pics/progress.png";
if (m_background_pic != g_gr->get_no_picture()) {
- g_gr->free_picture_surface(m_background_pic);
m_background_pic = g_gr->get_no_picture();
}
draw_background(rt, g_gr->get_xres(), g_gr->get_yres());
=== modified file 'src/ui_basic/slider.cc'
--- src/ui_basic/slider.cc 2010-09-27 15:56:07 +0000
+++ src/ui_basic/slider.cc 2010-11-27 16:29:59 +0000
@@ -20,8 +20,8 @@
#include "slider.h"
#include "mouse_constants.h"
+#include "graphic/offscreensurface.h"
#include "graphic/rendertarget.h"
-#include "graphic/surface.h"
#include <cmath>
@@ -73,8 +73,7 @@
m_value >= m_max_value ? get_bar_size() :
(m_value - m_min_value) * get_bar_size() / (m_max_value - m_min_value)),
m_cursor_size (cursor_size),
- m_needredraw (true),
- m_cache_pic (g_gr->get_no_picture())
+ m_needredraw (true)
{
// cursor initial position
@@ -142,7 +141,7 @@
// Make the slider button opaque
if (g_gr->caps().offscreen_rendering)
- m_cache_pic->surface->fill_rect
+ m_cache_pic->fill_rect
(Rect(Point(x, y), w, h), RGBAColor(0, 0, 0, 255));
dst.tile // background
(Rect(Point(x, y), w, h), m_pic_background, Point(get_x(), get_y()));
@@ -356,7 +355,7 @@
* \param dst The graphic destination.
*/
void HorizontalSlider::draw(RenderTarget & odst) {
- RenderTarget * dst = &odst;
+ RenderTarget dst = odst;
if (g_gr->caps().offscreen_rendering) {
if (!m_needredraw)
{
@@ -364,37 +363,37 @@
return;
}
- if (m_cache_pic == g_gr->get_no_picture())
+ if (m_cache_pic)
{
- m_cache_pic = g_gr->create_picture_surface
+ m_cache_pic = g_gr->create_offscreen_surface
(get_w(), get_h(), true);
}
- dst = g_gr->get_surface_renderer(m_cache_pic);
- dst->fill_rect
+ dst = RenderTarget(m_cache_pic);
+ dst.fill_rect
(Rect(Point(0, 0), get_w(), get_h()), RGBAColor(0, 0, 0, 0));
}
RGBAColor black(0, 0, 0, 255);
- dst->brighten_rect // bottom edge
+ dst.brighten_rect // bottom edge
(Rect(Point(get_x_gap(), get_h() / 2), get_bar_size(), 2),
BUTTON_EDGE_BRIGHT_FACTOR);
- dst->brighten_rect // right edge
+ dst.brighten_rect // right edge
(Rect(Point(get_x_gap() + get_bar_size() - 2, get_y_gap()), 2, 2),
BUTTON_EDGE_BRIGHT_FACTOR);
// top edge
- dst->fill_rect
+ dst.fill_rect
(Rect(Point(get_x_gap(), get_y_gap()), get_bar_size() - 1, 1), black);
- dst->fill_rect
+ dst.fill_rect
(Rect(Point(get_x_gap(), get_y_gap() + 1), get_bar_size() - 2, 1), black);
// left edge
- dst->fill_rect(Rect(Point(get_x_gap(), get_y_gap()), 1, 4), black);
- dst->fill_rect(Rect(Point(get_x_gap() + 1, get_y_gap()), 1, 3), black);
+ dst.fill_rect(Rect(Point(get_x_gap(), get_y_gap()), 1, 4), black);
+ dst.fill_rect(Rect(Point(get_x_gap() + 1, get_y_gap()), 1, 3), black);
- draw_cursor(*dst, m_cursor_pos, 0, m_cursor_size, get_h());
+ draw_cursor(dst, m_cursor_pos, 0, m_cursor_size, get_h());
if (g_gr->caps().offscreen_rendering)
odst.blit(Point(0, 0), m_cache_pic);
@@ -457,7 +456,7 @@
* \param dst The graphic destination.
*/
void VerticalSlider::draw(RenderTarget & odst) {
- RenderTarget * dst = &odst;
+ RenderTarget dst = odst;
if (g_gr->caps().offscreen_rendering)
{
if (!m_needredraw)
@@ -465,34 +464,34 @@
odst.blit(Point(0, 0), m_cache_pic);
return;
}
- if (m_cache_pic == g_gr->get_no_picture())
- m_cache_pic = g_gr->create_picture_surface
- (get_w(), get_h(), true);
- dst = g_gr->get_surface_renderer(m_cache_pic);
+ if (m_cache_pic)
+ m_cache_pic = g_gr->create_offscreen_surface
+ (get_w(), get_h(), true);
+ dst = RenderTarget(m_cache_pic);
- dst->fill_rect(Rect(Point(0, 0), get_w(), get_h()), RGBAColor(0, 0, 0, 0));
+ dst.fill_rect(Rect(Point(0, 0), get_w(), get_h()), RGBAColor(0, 0, 0, 0));
}
RGBAColor black(0, 0, 0, 255);
- dst->brighten_rect // right edge
+ dst.brighten_rect // right edge
(Rect(Point(get_w() / 2, get_y_gap()), 2, get_bar_size()),
BUTTON_EDGE_BRIGHT_FACTOR);
- dst->brighten_rect // bottom edge
+ dst.brighten_rect // bottom edge
(Rect(Point(get_x_gap(), get_y_gap() + get_bar_size() - 2), 2, 2),
BUTTON_EDGE_BRIGHT_FACTOR);
// left edge
- dst->fill_rect
+ dst.fill_rect
(Rect(Point(get_x_gap(), get_y_gap()), 1, get_bar_size() - 1), black);
- dst->fill_rect
+ dst.fill_rect
(Rect(Point(get_x_gap() + 1, get_y_gap()), 1, get_bar_size() - 2), black);
// top edge
- dst->fill_rect(Rect(Point(get_x_gap(), get_y_gap()), 4, 1), black);
- dst->fill_rect(Rect(Point(get_x_gap(), get_y_gap() + 1), 3, 1), black);
+ dst.fill_rect(Rect(Point(get_x_gap(), get_y_gap()), 4, 1), black);
+ dst.fill_rect(Rect(Point(get_x_gap(), get_y_gap() + 1), 3, 1), black);
- draw_cursor(*dst, 0, m_cursor_pos, get_w(), m_cursor_size);
+ draw_cursor(dst, 0, m_cursor_pos, get_w(), m_cursor_size);
if (g_gr->caps().offscreen_rendering)
odst.blit(Point(0, 0), m_cache_pic);
=== modified file 'src/ui_basic/slider.h'
--- src/ui_basic/slider.h 2010-05-19 13:25:43 +0000
+++ src/ui_basic/slider.h 2010-11-27 16:29:59 +0000
@@ -97,8 +97,8 @@
protected:
int32_t m_cursor_pos; // cursor position
int32_t m_cursor_size; // cursor width
- bool m_needredraw;
- PictureID m_cache_pic;
+ bool m_needredraw;
+ OffscreenSurfacePtr m_cache_pic;
};
=== modified file 'src/ui_fsmenu/base.cc'
--- src/ui_fsmenu/base.cc 2010-11-02 20:11:05 +0000
+++ src/ui_fsmenu/base.cc 2010-11-27 16:29:59 +0000
@@ -67,23 +67,18 @@
// Load background graphics
char buffer[256];
snprintf(buffer, sizeof(buffer), "pics/%s", bgpic);
- m_pic_background = g_gr->get_picture(PicMod_Menu, buffer, false);
- if (m_pic_background == g_gr->get_no_picture())
+ PictureID background = g_gr->get_picture(PicMod_Menu, buffer, false);
+ if (!background || background == g_gr->get_no_picture())
throw wexception
("could not open splash screen; make sure that all data files are "
"installed");
- m_res_background = g_gr->get_no_picture();
- if (g_gr->caps().resize_surfaces)
- m_res_background = g_gr->get_resized_picture
- (m_pic_background, m_xres, m_yres, Graphic::ResizeMode_Loose);
+ m_res_background = g_gr->get_resized_picture
+ (background, m_xres, m_yres, Graphic::ResizeMode_Loose);
}
-Fullscreen_Menu_Base::~Fullscreen_Menu_Base() {
- if
- (m_res_background != g_gr->get_no_picture() and
- m_res_background != m_pic_background)
- g_gr->free_picture_surface(m_res_background);
+Fullscreen_Menu_Base::~Fullscreen_Menu_Base()
+{
}
@@ -91,10 +86,7 @@
* Draw the background / splash screen
*/
void Fullscreen_Menu_Base::draw(RenderTarget & dst) {
- if (g_gr->caps().blit_resized)
- dst.blit(Rect(Point(0, 0), dst.get_w(), dst.get_h()), m_pic_background);
- else
- dst.blit(Point(0, 0), m_res_background);
+ dst.blit(Point(0, 0), m_res_background);
}
=== modified file 'src/ui_fsmenu/base.h'
--- src/ui_fsmenu/base.h 2010-11-02 20:11:05 +0000
+++ src/ui_fsmenu/base.h 2010-11-27 16:29:59 +0000
@@ -47,7 +47,6 @@
uint32_t m_xres;
uint32_t m_yres;
private:
- PictureID m_pic_background;
PictureID m_res_background;
};
=== modified file 'src/wui/interactive_gamebase.h'
--- src/wui/interactive_gamebase.h 2010-01-07 10:51:25 +0000
+++ src/wui/interactive_gamebase.h 2010-11-27 16:29:59 +0000
@@ -31,8 +31,6 @@
ChatDisplay(UI::Panel * parent, int32_t x, int32_t y, int32_t w, int32_t h);
~ChatDisplay();
- void delete_all_left_message_pictures();
-
void setChatProvider(ChatProvider &);
virtual void draw(RenderTarget &);
=== modified file 'src/wui/interactive_player.cc'
--- src/wui/interactive_player.cc 2010-11-21 11:44:22 +0000
+++ src/wui/interactive_player.cc 2010-11-27 16:29:59 +0000
@@ -76,13 +76,6 @@
{}
ChatDisplay::~ChatDisplay()
{
- delete_all_left_message_pictures();
-}
-
-void ChatDisplay::delete_all_left_message_pictures() {
- container_iterate_const(std::vector<PictureID>, m_cache_id, i)
- if (*i.current != g_gr->get_no_picture())
- UI::g_fh->delete_widget_cache(*i.current);
}
void ChatDisplay::setChatProvider(ChatProvider & chat)
@@ -102,7 +95,6 @@
// delete pictures of all old messages that we won't use again
// this is important to save space
- delete_all_left_message_pictures();
m_cache_id.resize(0);
int32_t const now = time(0);
@@ -137,7 +129,7 @@
Point(0, get_inner_h() -60 -y),
"<rt>" + i.current->text + "</rt>",
get_w(),
- m_cache_mode, picid, transparent_chat);
+ m_cache_mode, &picid, transparent_chat);
y += i.current->h;
m_cache_id.push_back(picid);
}
=== modified file 'src/wui/plot_area.cc'
--- src/wui/plot_area.cc 2010-05-12 10:16:44 +0000
+++ src/wui/plot_area.cc 2010-11-27 16:29:59 +0000
@@ -143,7 +143,7 @@
UI::Align_Center,
std::numeric_limits<uint32_t>::max(),
UI::Widget_Cache_None,
- g_gr->get_no_picture(),
+ 0,
std::numeric_limits<uint32_t>::max(),
false);
posx -= sub;
@@ -209,7 +209,7 @@
UI::Align_CenterRight,
std::numeric_limits<uint32_t>::max(),
UI::Widget_Cache_None,
- g_gr->get_no_picture(),
+ 0,
std::numeric_limits<uint32_t>::max(),
false);
=== modified file 'src/wui/waresqueuedisplay.cc'
--- src/wui/waresqueuedisplay.cc 2010-11-21 11:44:22 +0000
+++ src/wui/waresqueuedisplay.cc 2010-11-27 16:29:59 +0000
@@ -98,8 +98,8 @@
set_think(true);
}
-WaresQueueDisplay::~WaresQueueDisplay() {
- g_gr->free_picture_surface(m_pic_background);
+WaresQueueDisplay::~WaresQueueDisplay()
+{
}
/**
Follow ups