← Back to team overview

widelands-dev team mailing list archive

[Merge] lp:~shevonar/widelands/opengl into lp:widelands

 

Shevonar has proposed merging lp:~shevonar/widelands/opengl into lp:widelands.

Requested reviews:
  Widelands Developers (widelands-dev)
Related bugs:
  Bug #594686 in widelands: "Roads not rendered correctly in opengl mode on some systems"
  https://bugs.launchpad.net/widelands/+bug/594686
  Bug #649037 in widelands: "Many menus are not repainted in OpenGL mode"
  https://bugs.launchpad.net/widelands/+bug/649037
  Bug #722196 in widelands: "OpenGL terrain renderer does not dither between adjacent fields"
  https://bugs.launchpad.net/widelands/+bug/722196
  Bug #722796 in widelands: "Minimap not shaded by terrain height in OpenGL"
  https://bugs.launchpad.net/widelands/+bug/722796
  Bug #887093 in widelands: "Make OpenGL the standard renderer"
  https://bugs.launchpad.net/widelands/+bug/887093

For more details, see:
https://code.launchpad.net/~shevonar/widelands/opengl/+merge/93852

This branch improves the OpenGL rendering:
- gameview is split into two subclasses: gameviewSDL and gameviewOpenGL
- terrain edges are dithered and rounded in OpenGL mode (via a texture mask)
- minimap is shaded correctly
- road textures should be fixed (resized to 64x64px)
- Made OpenGL the standard renderer and remove * highly experimental * from options menu
- fixed bug 649037
-- 
https://code.launchpad.net/~shevonar/widelands/opengl/+merge/93852
Your team Widelands Developers is requested to review the proposed merge of lp:~shevonar/widelands/opengl into lp:widelands.
=== modified file 'src/graphic/graphic.cc'
--- src/graphic/graphic.cc	2012-02-19 17:10:12 +0000
+++ src/graphic/graphic.cc	2012-02-20 14:46:47 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2002-2004, 2006-2011 by the Widelands Development Team
+ * Copyright (C) 2002-2004, 2006-2012 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
@@ -1034,8 +1034,9 @@
 */
 void Graphic::animate_maptextures(uint32_t time)
 {
-	for (uint32_t i = 0; i < m_maptextures.size(); ++i)
+	for (uint32_t i = 0; i < m_maptextures.size(); ++i) {
 		m_maptextures[i]->animate(time);
+	}
 }
 
 /**
@@ -1043,8 +1044,9 @@
  */
 void Graphic::reset_texture_animation_reminder()
 {
-	for (uint32_t i = 0; i < m_maptextures.size(); ++i)
+	for (uint32_t i = 0; i < m_maptextures.size(); ++i) {
 		m_maptextures[i]->reset_was_animated();
+	}
 }
 
 /**
@@ -1164,8 +1166,9 @@
 		return 0;
 }
 
+
 /**
- * Sets the name of the current world and loads the fitting road textures
+ * Sets the name of the current world and loads the fitting road and edge textures
  */
 void Graphic::set_world(std::string worldname) {
 	char buf[255];
@@ -1179,6 +1182,10 @@
 	m_roadtextures->pic_road_normal = get_picture(PicMod_Game, buf, false);
 	snprintf(buf, sizeof(buf), "worlds/%s/pics/roadt_busy.png", worldname.c_str());
 	m_roadtextures->pic_road_busy = get_picture(PicMod_Game, buf, false);
+
+	// load edge texture
+	snprintf(buf, sizeof(buf), "worlds/%s/pics/edge.png", worldname.c_str());
+	m_edgetexture = get_picture(PicMod_Game, buf, false);
 }
 
 /**
@@ -1191,3 +1198,12 @@
 	return
 		(roadtex == Widelands::Road_Normal ? m_roadtextures->pic_road_normal : m_roadtextures->pic_road_busy);
 }
+
+/**
+ * Returns the alpha mask texture for edges.
+ * \return The edge texture (alpha mask)
+ */
+PictureID Graphic::get_edge_texture()
+{
+	return m_edgetexture;
+}

=== modified file 'src/graphic/graphic.h'
--- src/graphic/graphic.h	2011-11-30 21:38:37 +0000
+++ src/graphic/graphic.h	2012-02-20 14:46:47 +0000
@@ -189,6 +189,7 @@
 
 	void set_world(std::string);
 	PictureID get_road_texture(int32_t roadtex);
+	PictureID get_edge_texture();
 
 	GraphicCaps const & caps() const throw () {return m_caps;}
 
@@ -236,6 +237,7 @@
 	Picturemap m_picturemap;
 
 	Road_Textures * m_roadtextures;
+	PictureID m_edgetexture;
 	std::vector<Texture *> m_maptextures;
 	std::vector<AnimationGfx *> m_animations;
 };

=== modified file 'src/graphic/render/gameview.cc'
--- src/graphic/render/gameview.cc	2012-02-12 17:17:26 +0000
+++ src/graphic/render/gameview.cc	2012-02-20 14:46:47 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2010-2011 by the Widelands Development Team
+ * Copyright (C) 2010-2012 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
@@ -39,7 +39,6 @@
 #include "wui/overlay_manager.h"
 
 #include "terrain_sdl.h"
-#include "terrain_opengl.h"
 
 using Widelands::BaseImmovable;
 using Widelands::Coords;
@@ -214,8 +213,10 @@
 				f_vert.tx += TRIANGLE_WIDTH / 2;
 				r_vert.tx += TRIANGLE_WIDTH / 2;
 			} else {
-				bl_vert.tx -= TRIANGLE_WIDTH / 2;
-				br_vert.tx -= TRIANGLE_WIDTH / 2;
+				f_vert.tx += TRIANGLE_WIDTH;
+				r_vert.tx += TRIANGLE_WIDTH;
+				bl_vert.tx += TRIANGLE_WIDTH / 2;
+				br_vert.tx += TRIANGLE_WIDTH / 2;
 			}
 
 			draw_field //  Render ground
@@ -986,16 +987,16 @@
  * into the bitmap.
  *
  * Vertices:
- *   - f_vert vertice of the field
- *   - r_vert vertice right of the field
- *   - bl_vert vertice bottom left of the field
- *   - br_vert vertice bottom right of the field
+ *   - f_vert vertex of the field
+ *   - r_vert vertex right of the field
+ *   - bl_vert vertex bottom left of the field
+ *   - br_vert vertex bottom right of the field
  *
  * Textures:
  *   - f_r_texture Terrain of the triangle right of the field
  *   - f_d_texture Terrain of the triangle under of the field
- *   - tr_d_texture Terrain of the triangle to of the right triangle ??
- *   - l_r_texture Terrain of the triangle left if the down triangle ??
+ *   - tr_d_texture Terrain of the triangle top of the right triangle ??
+ *   - l_r_texture Terrain of the triangle left of the down triangle ??
  *
  *             (tr_d)
  *
@@ -1018,43 +1019,7 @@
 	 Texture const &  f_d_texture,
 	 Texture const &  f_r_texture)
 {
-	upcast(SurfaceSDL, sdlsurf, m_surface.get());
-	if (sdlsurf)
-	{
-		sdlsurf->set_subwin(subwin);
-		switch (sdlsurf->format().BytesPerPixel) {
-		case 2:
-			draw_field_int<Uint16>
-				(*sdlsurf,
-				 f_vert, r_vert, bl_vert, br_vert,
-				 roads,
-				 tr_d_texture, l_r_texture, f_d_texture, f_r_texture);
-			break;
-		case 4:
-			draw_field_int<Uint32>
-				(*sdlsurf,
-				 f_vert, r_vert, bl_vert, br_vert,
-				 roads,
-				 tr_d_texture, l_r_texture, f_d_texture, f_r_texture);
-			break;
-		default:
-			assert(false);
-		}
-		sdlsurf->unset_subwin();
-	}
-#ifdef USE_OPENGL
-	else
-	{
-		// Draw triangle right (bottom) of the field
-		draw_field_opengl
-			(subwin, f_vert, br_vert, r_vert, f_r_texture);
-		// Draw triangle bottom of the field
-		draw_field_opengl
-			(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);
-	}
-#endif
+
 }
 
 /*
@@ -1376,35 +1341,3 @@
 
 	m_surface->blit(Point(rc.x, rc.y), picture, rc2);
 }
-
-void GameView::rendermap_init()
-{
-#ifdef USE_OPENGL
-	if (g_opengl) {
-		glMatrixMode(GL_TEXTURE);
-		glLoadIdentity();
-		glScalef
-			(1.0f / static_cast<GLfloat>(TEXTURE_WIDTH),
-			 1.0f / static_cast<GLfloat>(TEXTURE_HEIGHT), 1);
-		glDisable(GL_BLEND);
-
-		// Use scissor test to clip the window. This takes coordinates in screen
-		// coordinates (y goes from bottom to top)
-		glScissor
-			(m_rect.x, g_gr->get_yres() - m_rect.y - m_rect.h,
-			 m_rect.w, m_rect.h);
-		glEnable(GL_SCISSOR_TEST);
-	}
-#endif
-}
-
-void GameView::rendermap_deint()
-{
-#ifdef USE_OPENGL
-	if (g_opengl) {
-		glDisable(GL_SCISSOR_TEST);
-		glMatrixMode(GL_TEXTURE);
-		glLoadIdentity();
-	}
-#endif
-}

=== modified file 'src/graphic/render/gameview.h'
--- src/graphic/render/gameview.h	2012-01-09 21:10:43 +0000
+++ src/graphic/render/gameview.h	2012-02-20 14:46:47 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2010-2011 by the Widelands Development Team
+ * Copyright (C) 2010-2012 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
@@ -46,7 +46,7 @@
 public:
 	GameView(RenderTarget & rt):
 		RenderTarget(rt) {}
-	~GameView() {}
+	virtual ~GameView() {}
 
 	/**
 	 * Renders the map from a player's point of view into the current drawing
@@ -80,12 +80,12 @@
 		 Point                               viewpoint,
 		 uint32_t                            flags);
 
-private:
+protected:
 	/**
 	 * Helper function to draw two terrain triangles. This is called from the
 	 * rendermap() functions.
 	 */
-	void draw_field
+	virtual void draw_field
 		(Rect          & subwin,
 		 Vertex  const &  f_vert,
 		 Vertex  const &  r_vert,
@@ -109,12 +109,12 @@
 	/**
 	 * This is called before the view of the game is rendered.
 	 */
-	void rendermap_init();
+	virtual void rendermap_init() {}
 
 	/**
 	* This is called after the view of the game is rendered.
 	*/
-	void rendermap_deint();
+	virtual void rendermap_deint() {}
 };
 
 #endif //WIDELANDS_GAMEVIEW_H

=== added file 'src/graphic/render/gameview_opengl.cc'
--- src/graphic/render/gameview_opengl.cc	1970-01-01 00:00:00 +0000
+++ src/graphic/render/gameview_opengl.cc	2012-02-20 14:46:47 +0000
@@ -0,0 +1,101 @@
+/*
+ * Copyright (C) 2011-2012 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 "gameview_opengl.h"
+
+#include "constants.h"
+#include "economy/road.h"
+#include "graphic/graphic.h"
+#include "graphic/texture.h"
+
+#include "terrain_opengl.h"
+
+using namespace  Widelands;
+
+/**
+ * Draw ground textures and roads for the given parallelogram (two triangles)
+ * into the bitmap.
+ *
+ * Vertices:
+ *   - f_vert vertex of the field
+ *   - r_vert vertex right of the field
+ *   - bl_vert vertex bottom left of the field
+ *   - br_vert vertex bottom right of the field
+ *
+ * Textures:
+ *   - f_r_texture Terrain of the triangle right of the field
+ *   - f_d_texture Terrain of the triangle under of the field
+ *   - tr_d_texture Terrain of the triangle top of the right triangle ??
+ *   - l_r_texture Terrain of the triangle left of the down triangle ??
+ *
+ *             (tr_d)
+ *
+ *       (f) *------* (r)
+ *          / \  r /
+ *  (l_r)  /   \  /
+ *        /  d  \/
+ *  (bl) *------* (br)
+ */
+void GameViewOpenGL::draw_field
+	(Rect          & subwin,
+	 Vertex  const &  f_vert,
+	 Vertex  const &  r_vert,
+	 Vertex  const & bl_vert,
+	 Vertex  const & br_vert,
+	 uint8_t         roads,
+	 Texture const & tr_d_texture,
+	 Texture const &  l_r_texture,
+	 Texture const &  f_d_texture,
+	 Texture const &  f_r_texture)
+{
+	// Draw triangle right (bottom) of the field
+	draw_field_opengl
+		(subwin, f_vert, br_vert, r_vert, f_r_texture, f_d_texture, tr_d_texture);
+	// Draw triangle bottom of the field
+	draw_field_opengl
+		(subwin, f_vert, bl_vert, br_vert, f_d_texture, l_r_texture, f_d_texture);
+
+	// Draw the roads
+	draw_roads_opengl(subwin, roads, f_vert, r_vert, bl_vert, br_vert);
+}
+
+void GameViewOpenGL::rendermap_init()
+{
+	glMatrixMode(GL_TEXTURE);
+	glLoadIdentity();
+	glScalef
+		(1.0f / static_cast<GLfloat>(TEXTURE_WIDTH),
+		 1.0f / static_cast<GLfloat>(TEXTURE_HEIGHT), 1);
+	glDisable(GL_BLEND);
+
+	// Use scissor test to clip the window. This takes coordinates in screen
+	// coordinates (y goes from bottom to top)
+	glScissor
+		(m_rect.x, g_gr->get_yres() - m_rect.y - m_rect.h,
+		 m_rect.w, m_rect.h);
+	glEnable(GL_SCISSOR_TEST);
+}
+
+void GameViewOpenGL::rendermap_deint()
+{
+	glDisable(GL_SCISSOR_TEST);
+	glMatrixMode(GL_TEXTURE);
+	glLoadIdentity();
+}

=== added file 'src/graphic/render/gameview_opengl.h'
--- src/graphic/render/gameview_opengl.h	1970-01-01 00:00:00 +0000
+++ src/graphic/render/gameview_opengl.h	2012-02-20 14:46:47 +0000
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2011 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 GAMEVIEW_OPENGL_H_
+#define GAMEVIEW_OPENGL_H_
+
+#include "gameview.h"
+
+class GameViewOpenGL : public GameView
+{
+public:
+	GameViewOpenGL(RenderTarget & rt):
+		GameView(rt) {}
+	~GameViewOpenGL() {}
+
+protected:
+	/**
+	 * Helper function to draw two terrain triangles. This is called from the
+	 * rendermap() functions.
+	 */
+	void draw_field
+		(Rect          & subwin,
+		 Vertex  const &  f_vert,
+		 Vertex  const &  r_vert,
+		 Vertex  const & bl_vert,
+		 Vertex  const & br_vert,
+		 uint8_t         roads,
+		 Texture const & tr_d_texture,
+		 Texture const &  l_r_texture,
+		 Texture const &  f_d_texture,
+		 Texture const &  f_r_texture);
+
+	void rendermap_init();
+	void rendermap_deint();
+};
+
+
+#endif /* GAMEVIEW_OPENGL_H_ */

=== added file 'src/graphic/render/gameview_sdl.cc'
--- src/graphic/render/gameview_sdl.cc	1970-01-01 00:00:00 +0000
+++ src/graphic/render/gameview_sdl.cc	2012-02-20 14:46:47 +0000
@@ -0,0 +1,105 @@
+/*
+ * Copyright (C) 2011-2012 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 "gameview_sdl.h"
+
+#include "upcast.h"
+
+#include "economy/road.h"
+#include "economy/flag.h"
+
+#include "wui/minimap.h"
+#include "wui/mapviewpixelconstants.h"
+
+#include "logic/field.h"
+#include "logic/map.h"
+#include "logic/player.h"
+
+#include "graphic/graphic.h"
+#include "graphic/rendertarget.h"
+#include "graphic/surface.h"
+#include "surface_sdl.h"
+#include "graphic/texture.h"
+
+#include "wui/overlay_manager.h"
+
+#include "terrain_sdl.h"
+
+
+/**
+ * Draw ground textures and roads for the given parallelogram (two triangles)
+ * into the bitmap.
+ *
+ * Vertices:
+ *   - f_vert vertex of the field
+ *   - r_vert vertex right of the field
+ *   - bl_vert vertex bottom left of the field
+ *   - br_vert vertex bottom right of the field
+ *
+ * Textures:
+ *   - f_r_texture Terrain of the triangle right of the field
+ *   - f_d_texture Terrain of the triangle under of the field
+ *   - tr_d_texture Terrain of the triangle top of the right triangle ??
+ *   - l_r_texture Terrain of the triangle left of the down triangle ??
+ *
+ *             (tr_d)
+ *
+ *       (f) *------* (r)
+ *          / \  r /
+ *  (l_r)  /   \  /
+ *        /  d  \/
+ *  (bl) *------* (br)
+ */
+void GameViewSDL::draw_field
+	(Rect          & subwin,
+	 Vertex  const &  f_vert,
+	 Vertex  const &  r_vert,
+	 Vertex  const & bl_vert,
+	 Vertex  const & br_vert,
+	 uint8_t         roads,
+	 Texture const & tr_d_texture,
+	 Texture const &  l_r_texture,
+	 Texture const &  f_d_texture,
+	 Texture const &  f_r_texture)
+{
+	upcast(SurfaceSDL, sdlsurf, m_surface.get());
+	if (sdlsurf)
+	{
+		sdlsurf->set_subwin(subwin);
+		switch (sdlsurf->format().BytesPerPixel) {
+		case 2:
+			draw_field_int<Uint16>
+				(*sdlsurf,
+				 f_vert, r_vert, bl_vert, br_vert,
+				 roads,
+				 tr_d_texture, l_r_texture, f_d_texture, f_r_texture);
+			break;
+		case 4:
+			draw_field_int<Uint32>
+				(*sdlsurf,
+				 f_vert, r_vert, bl_vert, br_vert,
+				 roads,
+				 tr_d_texture, l_r_texture, f_d_texture, f_r_texture);
+			break;
+		default:
+			assert(false);
+		}
+		sdlsurf->unset_subwin();
+	}
+}

=== added file 'src/graphic/render/gameview_sdl.h'
--- src/graphic/render/gameview_sdl.h	1970-01-01 00:00:00 +0000
+++ src/graphic/render/gameview_sdl.h	2012-02-20 14:46:47 +0000
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2011-2012 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 GAMEVIEW_SDL_H_
+#define GAMEVIEW_SDL_H_
+
+#include "gameview.h"
+
+class GameViewSDL : public GameView
+{
+public:
+	GameViewSDL(RenderTarget & rt):
+		GameView(rt) {}
+	~GameViewSDL() {}
+
+protected:
+	/**
+	 * Helper function to draw two terrain triangles. This is called from the
+	 * rendermap() functions.
+	 */
+	void draw_field
+		(Rect          & subwin,
+		 Vertex  const &  f_vert,
+		 Vertex  const &  r_vert,
+		 Vertex  const & bl_vert,
+		 Vertex  const & br_vert,
+		 uint8_t         roads,
+		 Texture const & tr_d_texture,
+		 Texture const &  l_r_texture,
+		 Texture const &  f_d_texture,
+		 Texture const &  f_r_texture);
+};
+
+#endif /* GAMEVIEW_SDL_H_ */

=== modified file 'src/graphic/render/terrain_opengl.h'
--- src/graphic/render/terrain_opengl.h	2011-11-30 21:38:37 +0000
+++ src/graphic/render/terrain_opengl.h	2012-02-20 14:46:47 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2010 by the Widelands Development Team
+ * Copyright (C) 2010-2012 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
@@ -18,6 +18,8 @@
  */
 
 #ifdef USE_OPENGL
+#ifndef TERRAIN_OPENGL_H
+#define TERRAIN_OPENGL_H
 
 #include "gl_picture_texture.h"
 #include "vertex.h"
@@ -28,13 +30,13 @@
 	 Vertex const & p1,
 	 Vertex const & p2,
 	 Vertex const & p3,
-	 Texture const & texture)
+	 Texture const & texture,
+	 Texture const & left_texture,
+	 Texture const & top_texture)
 {
 	if (p1.b <= -128 and p2.b <= -128 and p3.b <= -128)
 		return;
 
-	glBindTexture(GL_TEXTURE_2D, texture.getTexture());
-
 	Vertex t1(p1), t2(p2), t3(p3);
 
 	t1.x = p1.x + subwin.x;
@@ -49,39 +51,147 @@
 	if (t1.y < subwin.y and t2.y < subwin.y and t3.y < subwin.y)
 		return;
 
-	{
-		int const subxr = subwin.x + subwin.w;
-		if (t1.x > subxr and t2.x > subxr and t3.x > subxr)
-			return;
-	}
-	{
-		int const subyd = subwin.y + subwin.h;
-		if (t1.y > subyd and t2.y > subyd and t3.y > subyd)
-			return;
-	}
+	int const subxr = subwin.x + subwin.w;
+	if (t1.x > subxr and t2.x > subxr and t3.x > subxr)
+		return;
+
+	int const subyd = subwin.y + subwin.h;
+	if (t1.y > subyd and t2.y > subyd and t3.y > subyd)
+		return;
+
+	glEnable(GL_BLEND);
+
+	// load current texture
+	glActiveTexture(GL_TEXTURE0);
+	glEnable(GL_TEXTURE_2D);
+	glBindTexture(GL_TEXTURE_2D, texture.getTexture());
+	glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
+
+	if ((&top_texture != &texture) and not (p1.b == -128 and p3.b == -128)) {
+		// load top texture
+		glActiveTexture(GL_TEXTURE1);
+		glEnable(GL_TEXTURE_2D);
+		glBindTexture(GL_TEXTURE_2D, top_texture.getTexture());
+		glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
+		glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_REPLACE);
+		glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB, GL_PREVIOUS);
+		glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB, GL_SRC_COLOR);
+
+		GLuint edge = dynamic_cast<GLPictureTexture const &>
+			(*g_gr->get_edge_texture()).get_gl_texture();
+
+		// combine current and top texture
+		glActiveTexture(GL_TEXTURE2);
+		glEnable(GL_TEXTURE_2D);
+		glBindTexture(GL_TEXTURE_2D, edge);
+		glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
+		glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_INTERPOLATE);
+		glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB, GL_PREVIOUS);
+		glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB, GL_TEXTURE1);
+		glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE2_RGB, GL_TEXTURE);
+		glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB, GL_SRC_COLOR);
+		glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB, GL_SRC_COLOR);
+		glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND2_RGB, GL_SRC_COLOR);
+	}
+
+	if ((&left_texture != &texture) and not (p1.b == -128 and p2.b == -128)) {
+		// load left texture
+		glActiveTexture(GL_TEXTURE3);
+		glEnable(GL_TEXTURE_2D);
+		glBindTexture(GL_TEXTURE_2D, left_texture.getTexture());
+		glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
+		glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_REPLACE);
+		glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB, GL_PREVIOUS);
+		glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB, GL_SRC_COLOR);
+
+		GLuint edge = dynamic_cast<GLPictureTexture const &>
+			(*g_gr->get_edge_texture()).get_gl_texture();
+
+		// combine current and left texture
+		glActiveTexture(GL_TEXTURE4);
+		glEnable(GL_TEXTURE_2D);
+		glBindTexture(GL_TEXTURE_2D, edge);
+		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+		glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
+		glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_INTERPOLATE);
+		glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB, GL_PREVIOUS);
+		glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB, GL_TEXTURE3);
+		glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE2_RGB, GL_TEXTURE);
+		glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB, GL_SRC_COLOR);
+		glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB, GL_SRC_COLOR);
+		glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND2_RGB, GL_SRC_COLOR);
+	}
+
+	// Fade effect for fog of war
+	glActiveTexture(GL_TEXTURE5);
+	glEnable(GL_TEXTURE_2D);
+	// texture does not matter but one has to be bound
+	glBindTexture(GL_TEXTURE_2D, texture.getTexture());
+	glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
+	glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_MODULATE);
+	glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB, GL_PREVIOUS);
+	glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB, GL_SRC_COLOR);
+	glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB, GL_PRIMARY_COLOR);
+	glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB, GL_SRC_COLOR);
 
 	glBegin(GL_TRIANGLES); {
 		{
 			GLfloat const brightness = (150.0 + p1.b) / 150.0;
 			glColor3f(brightness, brightness, brightness);
 		}
-		glTexCoord2i(t1.tx, t1.ty);
+		glMultiTexCoord2i(GL_TEXTURE0, t1.tx, t1.ty);
+		glMultiTexCoord2f(GL_TEXTURE1, t1.tx / TEXTURE_WIDTH, t1.ty / TEXTURE_WIDTH);
+		glMultiTexCoord2f(GL_TEXTURE2, 0, 0);
+		glMultiTexCoord2f(GL_TEXTURE3, t1.tx / TEXTURE_WIDTH, t1.ty / TEXTURE_WIDTH);
+		glMultiTexCoord2f(GL_TEXTURE4, 1, 0);
+		glMultiTexCoord2f(GL_TEXTURE5, t1.tx / TEXTURE_WIDTH, t1.ty / TEXTURE_WIDTH);
 		glVertex2f(t1.x, t1.y);
 
 		{
 			GLfloat const brightness = (150.0 + p2.b) / 150.0;
 			glColor3f(brightness, brightness, brightness);
 		}
-		glTexCoord2i(t2.tx, t2.ty);
+		glMultiTexCoord2i(GL_TEXTURE0, t2.tx, t2.ty);
+		glMultiTexCoord2f(GL_TEXTURE1, t2.tx / TEXTURE_WIDTH, t2.ty / TEXTURE_WIDTH);
+		glMultiTexCoord2f(GL_TEXTURE2, 0.5, 1);
+		glMultiTexCoord2f(GL_TEXTURE3, t2.tx / TEXTURE_WIDTH, t2.ty / TEXTURE_WIDTH);
+		glMultiTexCoord2f(GL_TEXTURE4, 0, 0);
+		glMultiTexCoord2f(GL_TEXTURE5, t2.tx / TEXTURE_WIDTH, t2.ty / TEXTURE_WIDTH);
 		glVertex2f(t2.x, t2.y);
 
 		{
 			GLfloat const brightness = (150.0 + p3.b) / 150.0;
 			glColor3f(brightness, brightness, brightness);
 		}
-		glTexCoord2i(t3.tx, t3.ty);
+		glMultiTexCoord2i(GL_TEXTURE0, t3.tx, t3.ty);
+		glMultiTexCoord2f(GL_TEXTURE1, t3.tx / TEXTURE_WIDTH, t3.ty / TEXTURE_WIDTH);
+		glMultiTexCoord2f(GL_TEXTURE2, 1, 0);
+		glMultiTexCoord2f(GL_TEXTURE3, t3.tx / TEXTURE_WIDTH, t3.ty / TEXTURE_WIDTH);
+		glMultiTexCoord2f(GL_TEXTURE4, 0.5, 1);
+		glMultiTexCoord2f(GL_TEXTURE5, t3.tx / TEXTURE_WIDTH, t3.ty / TEXTURE_WIDTH);
 		glVertex2f(t3.x, t3.y);
 	} glEnd();
+
+	// Cleanup OpenGL
+	glActiveTexture(GL_TEXTURE5);
+	glDisable(GL_TEXTURE_2D);
+	glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
+	glActiveTexture(GL_TEXTURE4);
+	glDisable(GL_TEXTURE_2D);
+	glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
+	glActiveTexture(GL_TEXTURE3);
+	glDisable(GL_TEXTURE_2D);
+	glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
+	glActiveTexture(GL_TEXTURE2);
+	glDisable(GL_TEXTURE_2D);
+	glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
+	glActiveTexture(GL_TEXTURE1);
+	glDisable(GL_TEXTURE_2D);
+	glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
+	glActiveTexture(GL_TEXTURE0);
+	glEnable(GL_TEXTURE_2D);
+	glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
 }
 
 #define horiz_road_opengl(tex, start, end)                                    \
@@ -93,7 +203,7 @@
       glVertex2f(subwin.x + end.x,   subwin.y + end.y - 2);                   \
       glTexCoord2i(TEXTURE_WIDTH, 4);                                         \
       glVertex2f(subwin.x + end.x,   subwin.y + end.y + 2);                   \
-      glTexCoord2i(TEXTURE_WIDTH, 4);                                         \
+      glTexCoord2i(0, 4);                                                     \
       glVertex2f(subwin.x + start.x, subwin.y + start.y + 2);                 \
    } glEnd();                                                                 \
 
@@ -106,7 +216,7 @@
       glVertex2f(subwin.x + start.x + 3, subwin.y + start.y);                 \
       glTexCoord2i(TEXTURE_WIDTH, TEXTURE_HEIGHT);                            \
       glVertex2f(subwin.x + end.x + 3,   subwin.y + end.y);                   \
-      glTexCoord2i(TEXTURE_WIDTH - 6, TEXTURE_HEIGHT);                       \
+      glTexCoord2i(TEXTURE_WIDTH - 6, TEXTURE_HEIGHT);                        \
       glVertex2f(subwin.x + end.x - 3,   subwin.y + end.y);                   \
    } glEnd();                                                                 \
 
@@ -174,3 +284,4 @@
 }
 
 #endif
+#endif

=== modified file 'src/graphic/texture.cc'
--- src/graphic/texture.cc	2011-11-30 21:38:37 +0000
+++ src/graphic/texture.cc	2012-02-20 14:46:47 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2002-2004, 2006, 2010 by the Widelands Development Team
+ * Copyright (C) 2002-2004, 2006, 2010, 2012 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
@@ -106,16 +106,38 @@
 			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);
+			// calculate shades on the first frame
+			if (!m_nrframes) {
+				surface->lock(IPixelAccess::Lock_Normal);
+				uint32_t mmap_color_base = surface->get_pixel(0, 0);
+				surface->unlock(IPixelAccess::Unlock_NoChange);
+
+				int32_t i, shade, r, g, b, a;
+				for (i = -128; i < 128; i++) {
+					shade = 128 + i;
+
+					a = (mmap_color_base & 0xff000000) >> 24;
+					b = (mmap_color_base & 0x00ff0000) >> 16;
+					g = (mmap_color_base & 0x0000ff00) >> 8;
+					r = (mmap_color_base & 0x000000ff);
+
+					b = (b * shade) >> 7;
+					g = (g * shade) >> 7;
+					r = (r * shade) >> 7;
+
+					if (b > 255) b = 255;
+					if (g > 255) g = 255;
+					if (r > 255) r = 255;
+
+					m_mmap_color[shade] = (a << 24) | (b << 16) | (g << 8) | r;
+				}
+			}
 
 			++m_nrframes;
 			continue;
 		}
 #endif
 
-
 		// Determine color map if it's the first frame
 		if (!m_nrframes) {
 			if (surf->format->BitsPerPixel == 8)
@@ -187,8 +209,11 @@
  * Return the basic terrain colour to be used in the minimap.
 */
 Uint32 Texture::get_minimap_color(const char shade) {
+	assert(shade >= -128);
+	assert(shade <= 127);
+
 	if (not m_pixels)
-		return m_mmap_color;
+		return m_mmap_color[128 + shade];
 
 	uint8_t clr = m_pixels[0]; // just use the top-left pixel
 	uint32_t table = static_cast<uint8_t>(shade);

=== modified file 'src/graphic/texture.h'
--- src/graphic/texture.h	2012-01-09 21:10:43 +0000
+++ src/graphic/texture.h	2012-02-20 14:46:47 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2002-2004, 2006, 2008-2010 by the Widelands Development Team
+ * Copyright (C) 2002-2004, 2006, 2008-2010, 2012 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
@@ -71,7 +71,7 @@
 private:
 	Colormap * m_colormap;
 	uint8_t  * m_pixels;
-	uint32_t   m_mmap_color;
+	uint32_t   m_mmap_color[256];
 	uint8_t  * m_curframe;
 	int32_t    m_frame_num;
 	char     * m_texture_picture;

=== modified file 'src/ui_fsmenu/options.cc'
--- src/ui_fsmenu/options.cc	2012-01-21 13:09:23 +0000
+++ src/ui_fsmenu/options.cc	2012-02-20 14:46:47 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2002-2004, 2006-2010 by Widelands Development Team
+ * Copyright (C) 2002-2004, 2006-2010, 2012 by 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
@@ -468,7 +468,7 @@
 	m_label_opengl
 		(this,
 		 get_w() * 1313 / 10000, get_h() * 8330 / 10000,
-		 _("OpenGL rendering *Highly experimental!*"), UI::Align_VCenter),
+		 _("OpenGL rendering"), UI::Align_VCenter),
 	m_transparent_chat (this, Point(get_w() * 19 / 200, get_h() * 8645 / 10000)),
 	m_label_transparent_chat
 		(this,
@@ -658,7 +658,7 @@
 	opt.remove_syncstreams    = m_opt_section.get_bool
 		("remove_syncstreams", true);
 	opt.opengl                = m_opt_section.get_bool
-		("opengl", false);
+		("opengl", true);
 	opt.transparent_chat      = m_opt_section.get_bool
 		("transparent_chat", true);
 	return opt;

=== modified file 'src/wlapplication.cc'
--- src/wlapplication.cc	2012-02-07 12:14:30 +0000
+++ src/wlapplication.cc	2012-02-20 14:46:47 +0000
@@ -264,7 +264,7 @@
 m_should_die           (false),
 m_gfx_w(0), m_gfx_h(0),
 m_gfx_fullscreen       (false),
-m_gfx_opengl           (false),
+m_gfx_opengl           (true),
 m_default_datadirs     (true),
 m_homedir(FileSystem::GetHomedir() + "/.widelands"),
 m_redirected_stdio(false)
@@ -512,6 +512,10 @@
 					g_sound_handler.change_music();
 
 				break;
+			case SDL_VIDEOEXPOSE:
+				//log ("SDL Video Window expose event: %i\n", ev.expose.type);
+				g_gr->update_fullscreen();
+				break;
 			}
 		}
 	}
@@ -807,7 +811,7 @@
 	m_gfx_fullscreen = s.get_bool("fullscreen", false);
 
 #if USE_OPENGL
-	m_gfx_opengl = s.get_bool("opengl", false);
+	m_gfx_opengl = s.get_bool("opengl", true);
 #endif
 
 	// KLUDGE!
@@ -1352,8 +1356,7 @@
 		<<
 		_
 			 (" --opengl=[0|1]\n"
-			 "                      Enables opengl rendering\n"
-			 "                      *EXPERIMENTAL*\n")
+			 "                      Enables OpenGL rendering\n")
 #endif
 		<<
 		_

=== modified file 'src/wui/mapview.cc'
--- src/wui/mapview.cc	2011-11-30 21:38:37 +0000
+++ src/wui/mapview.cc	2012-02-20 14:46:47 +0000
@@ -31,6 +31,8 @@
 #include "graphic/graphic.h"
 #include "graphic/rendertarget.h"
 #include "graphic/render/gameview.h"
+#include "graphic/render/gameview_opengl.h"
+#include "graphic/render/gameview_sdl.h"
 
 #include "upcast.h"
 
@@ -93,12 +95,17 @@
 
 	egbase.map().overlay_manager().load_graphics();
 
-	GameView gameview(dst);
+	GameView * gameview;
+	if (g_opengl) {
+		gameview = new GameViewOpenGL(dst);
+	} else {
+		gameview = new GameViewSDL(dst);
+	}
 
 	if (upcast(Interactive_Player const, interactive_player, &intbase()))
-		gameview.rendermap(egbase, interactive_player->player(), m_viewpoint);
+		gameview->rendermap(egbase, interactive_player->player(), m_viewpoint);
 	else
-		gameview.rendermap(egbase, m_viewpoint);
+		gameview->rendermap(egbase, m_viewpoint);
 
 	m_complete_redraw_needed = false;
 	if (char const * const text = tooltip())

=== added file 'worlds/blackland/pics/edge.png'
Binary files worlds/blackland/pics/edge.png	1970-01-01 00:00:00 +0000 and worlds/blackland/pics/edge.png	2012-02-20 14:46:47 +0000 differ
=== modified file 'worlds/blackland/pics/roadt_busy.png'
Binary files worlds/blackland/pics/roadt_busy.png	2011-08-21 14:24:10 +0000 and worlds/blackland/pics/roadt_busy.png	2012-02-20 14:46:47 +0000 differ
=== modified file 'worlds/blackland/pics/roadt_normal.png'
Binary files worlds/blackland/pics/roadt_normal.png	2011-08-21 14:24:10 +0000 and worlds/blackland/pics/roadt_normal.png	2012-02-20 14:46:47 +0000 differ
=== added file 'worlds/desert/pics/edge.png'
Binary files worlds/desert/pics/edge.png	1970-01-01 00:00:00 +0000 and worlds/desert/pics/edge.png	2012-02-20 14:46:47 +0000 differ
=== modified file 'worlds/desert/pics/roadt_busy.png'
Binary files worlds/desert/pics/roadt_busy.png	2011-08-21 14:24:10 +0000 and worlds/desert/pics/roadt_busy.png	2012-02-20 14:46:47 +0000 differ
=== modified file 'worlds/desert/pics/roadt_normal.png'
Binary files worlds/desert/pics/roadt_normal.png	2011-08-21 14:24:10 +0000 and worlds/desert/pics/roadt_normal.png	2012-02-20 14:46:47 +0000 differ
=== added file 'worlds/greenland/pics/edge.png'
Binary files worlds/greenland/pics/edge.png	1970-01-01 00:00:00 +0000 and worlds/greenland/pics/edge.png	2012-02-20 14:46:47 +0000 differ
=== modified file 'worlds/greenland/pics/roadt_busy.png'
Binary files worlds/greenland/pics/roadt_busy.png	2011-10-03 15:11:25 +0000 and worlds/greenland/pics/roadt_busy.png	2012-02-20 14:46:47 +0000 differ
=== modified file 'worlds/greenland/pics/roadt_normal.png'
Binary files worlds/greenland/pics/roadt_normal.png	2011-10-03 15:11:25 +0000 and worlds/greenland/pics/roadt_normal.png	2012-02-20 14:46:47 +0000 differ
=== modified file 'worlds/greenland/terrainconf'
--- worlds/greenland/terrainconf	2012-01-04 18:52:20 +0000
+++ worlds/greenland/terrainconf	2012-02-20 14:46:47 +0000
@@ -80,4 +80,3 @@
 [bergwiese]
 name="Mountain meadow"
 is=green
-

=== added file 'worlds/winterland/pics/edge.png'
Binary files worlds/winterland/pics/edge.png	1970-01-01 00:00:00 +0000 and worlds/winterland/pics/edge.png	2012-02-20 14:46:47 +0000 differ
=== modified file 'worlds/winterland/pics/roadt_busy.png'
Binary files worlds/winterland/pics/roadt_busy.png	2011-08-21 14:24:10 +0000 and worlds/winterland/pics/roadt_busy.png	2012-02-20 14:46:47 +0000 differ
=== modified file 'worlds/winterland/pics/roadt_normal.png'
Binary files worlds/winterland/pics/roadt_normal.png	2011-08-21 14:24:10 +0000 and worlds/winterland/pics/roadt_normal.png	2012-02-20 14:46:47 +0000 differ

Follow ups