Merge lp:~nha/widelands/opengl into lp:widelands

Proposed by Nicolai Hähnle
Status: Merged
Merged at revision: 6501
Proposed branch: lp:~nha/widelands/opengl
Merge into: lp:widelands
Diff against target: 4139 lines (+1650/-1730)
34 files modified
.bzrignore (+2/-0)
src/graphic/graphic.cc (+1/-15)
src/graphic/graphic.h (+3/-4)
src/graphic/igraphic.h (+4/-2)
src/graphic/image_loader.h (+0/-1)
src/graphic/render/gamerenderer.cc (+286/-0)
src/graphic/render/gamerenderer.h (+97/-0)
src/graphic/render/gamerenderer_gl.cc (+669/-0)
src/graphic/render/gamerenderer_gl.h (+132/-0)
src/graphic/render/gamerenderer_sdl.cc (+279/-0)
src/graphic/render/gamerenderer_sdl.h (+55/-0)
src/graphic/render/gameview_opengl.cc (+0/-104)
src/graphic/render/gameview_opengl.h (+0/-56)
src/graphic/render/gameview_sdl.cc (+0/-105)
src/graphic/render/gameview_sdl.h (+0/-50)
src/graphic/render/gl_surface_texture.cc (+2/-2)
src/graphic/render/gl_surface_texture.h (+1/-1)
src/graphic/render/minimaprenderer.cc (+5/-970)
src/graphic/render/minimaprenderer.h (+10/-69)
src/graphic/render/terrain_opengl.h (+0/-327)
src/graphic/rendertarget.h (+3/-1)
src/logic/instances.h (+1/-1)
src/logic/tribe.h (+1/-1)
src/logic/world.cc (+3/-0)
src/logic/world.h (+3/-1)
src/point.h (+4/-1)
src/rect.h (+1/-1)
src/wui/mapview.cc (+17/-14)
src/wui/mapview.h (+3/-0)
src/wui/minimap.cc (+3/-3)
worlds/blackland/terrainconf (+17/-1)
worlds/desert/terrainconf (+16/-0)
worlds/greenland/terrainconf (+16/-0)
worlds/winterland/terrainconf (+16/-0)
To merge this branch: bzr merge lp:~nha/widelands/opengl
Reviewer Review Type Date Requested Status
SirVer Approve
Review via email: mp+147207@code.launchpad.net

Description of the change

Rewrite the OpenGL renderer to be closer to OpenGL best practices. Using vertex arrays gets performance from < 0.5 fps to the point where OpenGL is no longer the bottleneck on at least my system. Tested both OpenGL and SDL rendering with a little bit of playing and editing.

Please take a quick look, in particular a quick test for regressions on different systems would be nice.

To post a comment you must log in.
Revision history for this message
Tino (tino79) wrote :

It works fine on windows, just noticed:
- If i deactivate OpenGL in the Advanced Options menu->Apply->Apply -> Widelands quits, not stderr.txt
- If i active OpenGL via Options menu => Back to main menu, but no fonts, only white bars. I can quit widelands and then the updated config gets written. But if i load a game => crash.

Manually changing config works and Widelands runs fine in both modes. Only on-the-fly change does not.

Revision history for this message
Nicolai Hähnle (nha) wrote :

Could you please check whether you get the same crashes in current trunk? I remembered having one similar crash when switching between software and OpenGL before my changes, but unfortunately I didn't follow up because I thought there may be something driver-related going on.

Revision history for this message
Tino (tino79) wrote :

Sorry, you are right. The same problem occurs with a trunk build.
I am pretty sure it worked at some point before.

Revision history for this message
Nicolai Hähnle (nha) wrote :

Thank you so much for testing! Could you file a bug report for that so we don't forget about it?

Revision history for this message
SirVer (sirver) wrote :

Nicolai! The code compiles and runs great on later Mac OS X - I cannot check with old OS X as my wife took the laptop with her to work. The speedup is quite tremendous: on 100x speed terrain rendering takes less than 15% CPU now on my box. Superb work as always from you.

As you might have noticed we took up a review kind of process. The specifics are not clear yet - I just learned on my job that this can be very useful and improve the code significantly. So here are some comments:

- the diff here on the site is borked (it reports merge conflicts). Can you repropose? I think it updates the diff.
- adding the intensity parameter to the load() function seems suboptimal. First it is very specific to OpenGL rendering as SDL has no use for it. Secondly it gives the class a second task (namely loading and then 'flattening' the image). How about moving the edge/road loading and ownership out of graphic into the gameview renderer and giving only the GLTextures the intensity parameter. You could even make a conversion (static) method that could convert an RGB to an intensity texture - this would slow startup by a tad, but would keep this stuff internal to the (gl) terrain rendering - I feel that is a cleaner design.
- Some of the functions (e.g. drawobject(), but also others) are very long and repetitive? Can you find some seams to offload stuff into private or even better static methods/functions? I would not feel comfi to refactor anything in those methods as they stand now :)
- "and should be treated as read-only by derived classes": You made two pointers const, why not the third as well? How about not making those protected members, but instead combine them into a struct RenderState or so and pass this down to the functions doing the work? Your call.
- RenderTarget & dst: I prefer to pass a mutable object by pointer. The reason is that it becomes apparent on the call site if the call might modify the object or not. I realize that you prefer to use reference when an object must be passed (i.e. cannot be NULL), but i feel adding an assert as first line to the function does an equally good job. Your choice of course.
- I love MapviewPixelFunctions. I will wrap some of those for Lua (there are some values hard coded there).
- You pass Point by value regularly - why not use a const reference?
- GameRenderer is a struct, but should be a class. We started to run into trouble with clang complaining about the difference. We now use Class for anything with non trivial methods and struct otherwise. Sorry, you need to type the public: now :)

Revision history for this message
Nicolai Hähnle (nha) wrote :
Download full text (3.5 KiB)

> Nicolai! The code compiles and runs great on later Mac OS X - I cannot check with old OS X as my wife took the laptop with her to work. The speedup is quite tremendous: on 100x speed terrain rendering takes less than 15% CPU now on my box. Superb work as always from you.
Thank you.
> As you might have noticed we took up a review kind of process. The specifics are not clear yet - I just learned on my job that this can be very useful and improve the code significantly. So here are some comments:
>
> - the diff here on the site is borked (it reports merge conflicts). Can you repropose? I think it updates the diff.
Should be fixed now.
> - adding the intensity parameter to the load() function seems suboptimal. First it is very specific to OpenGL rendering as SDL has no use for it. Secondly it gives the class a second task (namely loading and then 'flattening' the image). How about moving the edge/road loading and ownership out of graphic into the gameview renderer and giving only the GLTextures the intensity parameter. You could even make a conversion (static) method that could convert an RGB to an intensity texture - this would slow startup by a tad, but would keep this stuff internal to the (gl) terrain rendering - I feel that is a cleaner design.
Loading the edge.png texture in GameRendererGL does make sense, though
then it would probably be best to make GameRendererGL a "singleton" to
avoid loading the texture multiple times. Or is your new image cache
meant to also cache textures provided by some other part of the code, so
that multiple instances of GameRendererGL would be using the same texture?
> - Some of the functions (e.g. drawobject(), but also others) are very long and repetitive? Can you find some seams to offload stuff into private or even better static methods/functions? I would not feel comfi to refactor anything in those methods as they stand now :)
I'll have to think about it. The problem is that a lot of that stuff is
inherently a two-pass approach.
> - "and should be treated as read-only by derived classes": You made two pointers const, why not the third as well?
The renderer is not supposed to modify egbase or player, but it _is_
supposed to modify the RenderTarget.
> How about not making those protected members, but instead combine them into a struct RenderState or so and pass this down to the functions doing the work? Your call.
> - RenderTarget & dst: I prefer to pass a mutable object by pointer. The reason is that it becomes apparent on the call site if the call might modify the object or not. I realize that you prefer to use reference when an object must be passed (i.e. cannot be NULL), but i feel adding an assert as first line to the function does an equally good job. Your choice of course.
So sigra's influence is in decline? I actually agree with you in
general, but I believe that most code still passes RenderTargets around
by reference and it's better to be consistent. Besides, it's usually
pretty obvious that you want RenderTargets to be modified.
> - I love MapviewPixelFunctions. I will wrap some of those for Lua (there are some values hard coded there).
> - You pass Point by value regularly - why not u...

Read more...

Revision history for this message
Nicolai Hähnle (nha) wrote :

I adjusted the code based on your comments, except the road rendering which just seemed a bit too awkward to unify. Does get_dither_edge_texture fit with your concept of how the ImageCache is supposed to work?

Revision history for this message
SirVer (sirver) wrote :

Not sure if the code in the diff is up to date again... I did a bzr merge and looked at my local copy.

Responses:
> So sigra's influence is in decline?
Erik has not been around for a long time now. He started a job and
mentioned some years back that this will likely make it hard for him to
continue on widelands. I wouldn't say that is 'influence is in decline',
we just develop, learn and change :)

> I actually agree with you in general, but I believe that most code still
>passes RenderTargets around by reference and it's better to be
>consistent. Besides, it's usually pretty obvious that you want
>RenderTargets to be modified.
Ack.

About get_dither_edge_texture: Yes, approximately. I pushed a branch for merging - I think what you want here is a new TransformedImage or directly using the SurfaceCache. I pushed my branch for review just now, so you can have a look at my design. As you were quicker with the merge proposal though, the fun of fixing the merge conflicts is on me, I guess.

Nitpicking:
- Widelands::Editor_Game_Base const &. Prefer to put const in front, more similar to a pointer. Same for other objects of course.
- class GameRenderer. Make boost::noncopyable?
- in some places inside function you could use const for variables more
  aggressively. This would give the compiler a better chance to
  optimise.
- What about the dynamic_casts? Why not static, we should know the types
  in all cases, right?
- assert(sizeof(basevertex) == 32); We have a compile assert statement
  for this somewhere.

These are just nits from my point of view. So I am completely fine with
merging this as is. Can you do the merge or should I - just remember to
never push your branch to trunk, always merge into trunk and push that.

review: Approve
Revision history for this message
SirVer (sirver) wrote :

Oh just as a comment: I will try to merge your and my branch in a new branch.

Revision history for this message
SirVer (sirver) wrote :

I merged our two branches in lp:~widelands-dev/widelands/opengl_and_autocache because I had time to do this today. I am not sure how to go forward now, though :). I do not want to redo the merge - it was quite a lot of work. Can we continue working on this joint branch?

As a sidenote, I am now going over this and do some of the fixes I suggested myself. I suggest for the future to always push to ~widelands-dev, so that the reviewer can do small fixes himself directly.

Revision history for this message
SirVer (sirver) wrote :

- I did fix the position of the const in const Klass&. I also added a style rule for this now (there are a lot of warnings in the rest of the code).
- Also added a boost::noncopyable to rendertarget.

Revision history for this message
Nicolai Hähnle (nha) wrote :

Nice, and thank you for merging those two branches! I have to run for now, so I would suggest you just do the merge into trunk whenever you're happy with it. Just some quick replies:

1. get_dither_edge_texture(): Since this is such a special case for now, I would just go directly to the SurfaceCache, but I don't have strong feelings about it. I haven't looked at your merge yet.

2. const-modifiers: Sigra was always very vocal about putting the const at the end, because that is more consistent with const-ness when you have pointers-to-pointers, and that just rubbed off a little bit onto me, but I have no strong feelings either way.

3. GameRenderer: Yes, should be boost::noncopyable, forgot about that.

4. const local variables: Compilers should be grown-up enough to be able to do optimizations themselves, but it does make sense to avoid future refactoring bugs.

5. Yes, those dynamic_casts could be static_casts, but it's not a performance critical path. In the spirit of defensive programming, one could leave it as is.

6. compile-time asserts: You're absolutely right about that.

Revision history for this message
SirVer (sirver) wrote :

1. I used the surface cache directly. I am a little unhappy that we copy and paste the image loading code here. I added a TODO for this which will let me sleep :-)

2. I do not understand this argument. const Klass* and const Klass& reads clearer to me. And you always read right to left. Oh well - mainly bikeshedding. I settled this for now by adding a new style checker rule. It reports > 1000 violations right now oO. Will see if I can get them fixed tonight.

3. done.
4. Couldn't be bothered for now to touch this. Just add as much const in as you can in the future. It makes life easier often (I just learned this at work basically).
5. Left as is. I trust you that it is not on timing critical paths.
6. done.

I did the fixes in the common branch and merged it into trunk. How cool is that: Widelands became faster, less demanding on the hardware and uses less memory and these improvements all came in one commit.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file '.bzrignore'
2--- .bzrignore 2012-06-20 09:07:10 +0000
3+++ .bzrignore 2013-02-09 12:25:26 +0000
4@@ -23,3 +23,5 @@
5 /tribes/**/*.xhtml
6 /global/**/*.xhtml
7
8+# Local KDevelop settings files
9+**/.kdev_include_paths
10
11=== modified file 'src/graphic/graphic.cc'
12--- src/graphic/graphic.cc 2013-01-05 20:11:57 +0000
13+++ src/graphic/graphic.cc 2013-02-09 12:25:26 +0000
14@@ -238,8 +238,7 @@
15
16 m_caps.gl.multitexture =
17 ((strstr(extensions, "GL_ARB_multitexture") != 0) and
18- (strstr(extensions, "GL_ARB_texture_env_combine") != 0))
19- and (m_caps.gl.max_tex_combined >= 6);
20+ (strstr(extensions, "GL_ARB_texture_env_combine") != 0));
21 log("Graphics: OpenGL: Multitexture capabilities ");
22 log(m_caps.gl.multitexture ? "sufficient\n" : "insufficient, only basic terrain rendering possible\n");
23
24@@ -971,10 +970,6 @@
25 m_roadtextures->pic_road_normal = imgcache().load(PicMod_Game, buf, false);
26 snprintf(buf, sizeof(buf), "worlds/%s/pics/roadt_busy.png", worldname.c_str());
27 m_roadtextures->pic_road_busy = imgcache().load(PicMod_Game, buf, false);
28-
29- // load edge texture
30- snprintf(buf, sizeof(buf), "worlds/%s/pics/edge.png", worldname.c_str());
31- m_edgetexture = imgcache().load(PicMod_Game, buf, false);
32 }
33
34 /**
35@@ -987,12 +982,3 @@
36 return
37 (roadtex == Widelands::Road_Normal ? m_roadtextures->pic_road_normal : m_roadtextures->pic_road_busy);
38 }
39-
40-/**
41- * Returns the alpha mask texture for edges.
42- * \return The edge texture (alpha mask)
43- */
44-const IPicture* Graphic::get_edge_texture()
45-{
46- return m_edgetexture;
47-}
48
49=== modified file 'src/graphic/graphic.h'
50--- src/graphic/graphic.h 2013-01-05 18:52:13 +0000
51+++ src/graphic/graphic.h 2013-02-09 12:25:26 +0000
52@@ -1,5 +1,5 @@
53 /*
54- * Copyright (C) 2002-2004, 2006-2012 by the Widelands Development Team
55+ * Copyright (C) 2002-2004, 2006-2013 by the Widelands Development Team
56 *
57 * This program is free software; you can redistribute it and/or
58 * modify it under the terms of the GNU General Public License
59@@ -119,7 +119,8 @@
60
61 void save_png(const IPicture*, StreamWrite*) const;
62
63- virtual IPicture* convert_sdl_surface_to_picture(SDL_Surface *, bool alpha = false) const;
64+ virtual IPicture* convert_sdl_surface_to_picture
65+ (SDL_Surface *, bool alpha = false) const;
66
67 Surface* create_surface(int32_t w, int32_t h, bool alpha = false) const;
68
69@@ -144,7 +145,6 @@
70
71 void set_world(std::string);
72 const IPicture* get_road_texture(int32_t roadtex);
73- const IPicture* get_edge_texture();
74
75 const GraphicCaps& caps() const throw () {return m_caps;}
76
77@@ -178,7 +178,6 @@
78 /// stores which features the current renderer has
79 GraphicCaps m_caps;
80 Road_Textures * m_roadtextures;
81- const IPicture* m_edgetexture;
82 std::vector<Texture *> m_maptextures;
83 std::vector<AnimationGfx *> m_animations;
84
85
86=== modified file 'src/graphic/igraphic.h'
87--- src/graphic/igraphic.h 2012-12-15 18:40:59 +0000
88+++ src/graphic/igraphic.h 2013-02-09 12:25:26 +0000
89@@ -1,5 +1,5 @@
90 /*
91- * Copyright (C) 2006-2012 by the Widelands Development Team
92+ * Copyright (C) 2006-2013 by the Widelands Development Team
93 *
94 * This program is free software; you can redistribute it and/or
95 * modify it under the terms of the GNU General Public License
96@@ -32,7 +32,9 @@
97 public:
98 virtual ~IGraphic() {};
99
100- virtual IPicture* convert_sdl_surface_to_picture(SDL_Surface*, bool alpha = false) const = 0;
101+ virtual IPicture* convert_sdl_surface_to_picture
102+ (SDL_Surface*,
103+ bool alpha = false) const = 0;
104 virtual IBlitableSurface * create_surface(int32_t w, int32_t h, bool alpha = false) const = 0;
105
106 virtual ImageCache& imgcache() const = 0;
107
108=== modified file 'src/graphic/image_loader.h'
109--- src/graphic/image_loader.h 2012-12-13 21:10:32 +0000
110+++ src/graphic/image_loader.h 2013-02-09 12:25:26 +0000
111@@ -34,4 +34,3 @@
112 };
113
114 #endif /* end of include guard: IMAGE_LOADER_H */
115-
116
117=== added file 'src/graphic/render/gamerenderer.cc'
118--- src/graphic/render/gamerenderer.cc 1970-01-01 00:00:00 +0000
119+++ src/graphic/render/gamerenderer.cc 2013-02-09 12:25:26 +0000
120@@ -0,0 +1,286 @@
121+/*
122+ * Copyright (C) 2010-2013 by the Widelands Development Team
123+ *
124+ * This program is free software; you can redistribute it and/or
125+ * modify it under the terms of the GNU General Public License
126+ * as published by the Free Software Foundation; either version 2
127+ * of the License, or (at your option) any later version.
128+ *
129+ * This program is distributed in the hope that it will be useful,
130+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
131+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
132+ * GNU General Public License for more details.
133+ *
134+ * You should have received a copy of the GNU General Public License
135+ * along with this program; if not, write to the Free Software
136+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
137+ *
138+ */
139+
140+#include "gamerenderer.h"
141+
142+#include "graphic/rendertarget.h"
143+
144+#include "logic/editor_game_base.h"
145+#include "logic/player.h"
146+
147+#include "wui/mapviewpixelfunctions.h"
148+#include "wui/overlay_manager.h"
149+
150+#include "upcast.h"
151+
152+using namespace Widelands;
153+
154+GameRenderer::GameRenderer()
155+{
156+}
157+
158+GameRenderer::~GameRenderer()
159+{
160+}
161+
162+void GameRenderer::rendermap
163+ (RenderTarget & dst,
164+ Widelands::Editor_Game_Base const & egbase,
165+ Widelands::Player const & player,
166+ Point const & viewofs)
167+{
168+ m_dst = &dst;
169+ m_dst_offset = -viewofs;
170+ m_egbase = &egbase;
171+ m_player = &player;
172+
173+ draw_wrapper();
174+}
175+
176+void GameRenderer::rendermap
177+ (RenderTarget & dst,
178+ Widelands::Editor_Game_Base const & egbase,
179+ Point const & viewofs)
180+{
181+ m_dst = &dst;
182+ m_dst_offset = -viewofs;
183+ m_egbase = &egbase;
184+ m_player = 0;
185+
186+ draw_wrapper();
187+}
188+
189+void GameRenderer::draw_wrapper()
190+{
191+ Point tl_map = m_dst->get_offset() - m_dst_offset;
192+
193+ assert(tl_map.x >= 0); // divisions involving negative numbers are bad
194+ assert(tl_map.y >= 0);
195+
196+ m_minfx = tl_map.x / TRIANGLE_WIDTH - 1;
197+ m_minfy = tl_map.y / TRIANGLE_HEIGHT - 1;
198+ m_maxfx = (tl_map.x + m_dst->get_rect().w + (TRIANGLE_WIDTH / 2)) / TRIANGLE_WIDTH;
199+ m_maxfy = (tl_map.y + m_dst->get_rect().h) / TRIANGLE_HEIGHT;
200+
201+ // fudge for triangle boundary effects and for height differences
202+ m_minfx -= 1;
203+ m_minfy -= 1;
204+ m_maxfx += 1;
205+ m_maxfy += 10;
206+
207+ draw();
208+}
209+
210+void GameRenderer::draw_objects()
211+{
212+ static const uint32_t F = 0;
213+ static const uint32_t R = 1;
214+ static const uint32_t BL = 2;
215+ static const uint32_t BR = 3;
216+ Map const & map = m_egbase->map();
217+
218+ for (int32_t fy = m_minfy; fy <= m_maxfy; ++fy) {
219+ for (int32_t fx = m_minfx; fx <= m_maxfx; ++fx) {
220+ Coords ncoords(fx, fy);
221+ map.normalize_coords(ncoords);
222+ FCoords coords[4];
223+ coords[F] = map.get_fcoords(ncoords);
224+ coords[R] = map.r_n(coords[F]);
225+ coords[BL] = map.bl_n(coords[F]);
226+ coords[BR] = map.br_n(coords[F]);
227+ Point pos[4];
228+ MapviewPixelFunctions::get_basepix(Coords(fx, fy), pos[F].x, pos[F].y);
229+ MapviewPixelFunctions::get_basepix(Coords(fx + 1, fy), pos[R].x, pos[R].y);
230+ MapviewPixelFunctions::get_basepix(Coords(fx + (fy & 1) - 1, fy + 1), pos[BL].x, pos[BL].y);
231+ MapviewPixelFunctions::get_basepix(Coords(fx + (fy & 1), fy + 1), pos[BR].x, pos[BR].y);
232+ for (uint32_t d = 0; d < 4; ++d) {
233+ pos[d].y -= coords[d].field->get_height() * HEIGHT_FACTOR;
234+ pos[d] += m_dst_offset;
235+ }
236+
237+ Player_Number owner_number[4];
238+ bool isborder[4];
239+ Vision vision[4] = {2, 2, 2, 2};
240+ for (uint32_t d = 0; d < 4; ++d)
241+ owner_number[d] = coords[d].field->get_owned_by();
242+ for (uint32_t d = 0; d < 4; ++d)
243+ isborder[d] = coords[d].field->is_border();
244+
245+ if (m_player && !m_player->see_all()) {
246+ for (uint32_t d = 0; d < 4; ++d) {
247+ Player::Field const & pf = m_player->fields()[map.get_index(coords[d], map.get_width())];
248+ vision[d] = pf.vision;
249+ if (pf.vision == 1) {
250+ owner_number[d] = pf.owner;
251+ isborder[d] = pf.border;
252+ }
253+ }
254+ }
255+
256+ if (isborder[F]) {
257+ Player const & owner = m_egbase->player(owner_number[F]);
258+ uint32_t const anim = owner.frontier_anim();
259+ if (vision[F])
260+ m_dst->drawanim(pos[F], anim, 0, &owner);
261+ for (uint32_t d = 1; d < 4; ++d) {
262+ if
263+ ((vision[F] || vision[d]) &&
264+ isborder[d] &&
265+ (owner_number[d] == owner_number[F] || !owner_number[d]))
266+ {
267+ m_dst->drawanim(middle(pos[F], pos[d]), anim, 0, &owner);
268+ }
269+ }
270+ }
271+
272+ if (1 < vision[F]) { // Render stuff that belongs to the node.
273+ if (BaseImmovable * const imm = coords[F].field->get_immovable())
274+ imm->draw(*m_egbase, *m_dst, coords[F], pos[F]);
275+ for
276+ (Bob * bob = coords[F].field->get_first_bob();
277+ bob;
278+ bob = bob->get_next_bob())
279+ bob->draw(*m_egbase, *m_dst, pos[F]);
280+ } else if (vision[F] == 1) {
281+ Player::Field const & f_pl = m_player->fields()[map.get_index(coords[F], map.get_width())];
282+ const Player * owner = owner_number[F] ? m_egbase->get_player(owner_number[F]) : 0;
283+ if
284+ (const Map_Object_Descr * const map_object_descr =
285+ f_pl.map_object_descr[TCoords<>::None])
286+ {
287+ if
288+ (const Player::Constructionsite_Information * const csinf =
289+ f_pl.constructionsite[TCoords<>::None])
290+ {
291+ // draw the partly finished constructionsite
292+ uint32_t anim;
293+ try {
294+ anim = csinf->becomes->get_animation("build");
295+ } catch (Map_Object_Descr::Animation_Nonexistent & e) {
296+ try {
297+ anim = csinf->becomes->get_animation("unoccupied");
298+ } catch (Map_Object_Descr::Animation_Nonexistent) {
299+ anim = csinf->becomes->get_animation("idle");
300+ }
301+ }
302+ const AnimationGfx::Index nr_frames = g_gr->nr_frames(anim);
303+ uint32_t cur_frame =
304+ csinf->totaltime ? csinf->completedtime * nr_frames / csinf->totaltime : 0;
305+ uint32_t tanim = cur_frame * FRAME_LENGTH;
306+ uint32_t w, h;
307+ g_gr->get_animation_size(anim, tanim, w, h);
308+ uint32_t lines = h * csinf->completedtime * nr_frames;
309+ if (csinf->totaltime)
310+ lines /= csinf->totaltime;
311+ assert(h * cur_frame <= lines);
312+ lines -= h * cur_frame; // This won't work if pictures have various sizes.
313+
314+ if (cur_frame) // not the first frame
315+ // draw the prev frame from top to where next image will be drawing
316+ m_dst->drawanimrect
317+ (pos[F], anim, tanim - FRAME_LENGTH, owner, Rect(Point(0, 0), w, h - lines));
318+ else if (csinf->was) {
319+ // Is the first frame, but there was another building here before,
320+ // get its last build picture and draw it instead.
321+ uint32_t a;
322+ try {
323+ a = csinf->was->get_animation("unoccupied");
324+ } catch (Map_Object_Descr::Animation_Nonexistent & e) {
325+ a = csinf->was->get_animation("idle");
326+ }
327+ m_dst->drawanimrect
328+ (pos[F], a, tanim - FRAME_LENGTH, owner, Rect(Point(0, 0), w, h - lines));
329+ }
330+ assert(lines <= h);
331+ m_dst->drawanimrect(pos[F], anim, tanim, owner, Rect(Point(0, h - lines), w, lines));
332+ } else if (upcast(const Building_Descr, building, map_object_descr)) {
333+ // this is a building therefore we either draw unoccupied or idle animation
334+ uint32_t pic;
335+ try {
336+ pic = building->get_animation("unoccupied");
337+ } catch (Map_Object_Descr::Animation_Nonexistent & e) {
338+ pic = building->get_animation("idle");
339+ }
340+ m_dst->drawanim(pos[F], pic, 0, owner);
341+ } else if (const uint32_t pic = map_object_descr->main_animation()) {
342+ m_dst->drawanim(pos[F], pic, 0, owner);
343+ } else if (map_object_descr == &Widelands::g_flag_descr) {
344+ m_dst->drawanim(pos[F], owner->flag_anim(), 0, owner);
345+ }
346+ }
347+ }
348+
349+ {
350+ // Render overlays on the node
351+ Overlay_Manager::Overlay_Info overlay_info[MAX_OVERLAYS_PER_NODE];
352+
353+ const Overlay_Manager::Overlay_Info * const end =
354+ overlay_info
355+ +
356+ map.overlay_manager().get_overlays(coords[F], overlay_info);
357+
358+ for
359+ (const Overlay_Manager::Overlay_Info * it = overlay_info;
360+ it < end;
361+ ++it)
362+ m_dst->blit(pos[F] - it->hotspot, it->pic);
363+ }
364+
365+ {
366+ // Render overlays on the R triangle
367+ Overlay_Manager::Overlay_Info overlay_info[MAX_OVERLAYS_PER_TRIANGLE];
368+ Overlay_Manager::Overlay_Info const * end =
369+ overlay_info
370+ +
371+ map.overlay_manager().get_overlays
372+ (TCoords<>(coords[F], TCoords<>::R), overlay_info);
373+
374+ Point tripos
375+ ((pos[F].x + pos[R].x + pos[BR].x) / 3,
376+ (pos[F].y + pos[R].y + pos[BR].y) / 3);
377+
378+ for
379+ (Overlay_Manager::Overlay_Info const * it = overlay_info;
380+ it < end;
381+ ++it)
382+ m_dst->blit(tripos - it->hotspot, it->pic);
383+ }
384+
385+ {
386+ // Render overlays on the D triangle
387+ Overlay_Manager::Overlay_Info overlay_info[MAX_OVERLAYS_PER_TRIANGLE];
388+ Overlay_Manager::Overlay_Info const * end =
389+ overlay_info
390+ +
391+ map.overlay_manager().get_overlays
392+ (TCoords<>(coords[F], TCoords<>::D), overlay_info);
393+
394+ Point tripos
395+ ((pos[F].x + pos[BL].x + pos[BR].x) / 3,
396+ (pos[F].y + pos[BL].y + pos[BR].y) / 3);
397+
398+ for
399+ (Overlay_Manager::Overlay_Info const * it = overlay_info;
400+ it < end;
401+ ++it)
402+ m_dst->blit(tripos - it->hotspot, it->pic);
403+ }
404+ }
405+ }
406+}
407
408=== added file 'src/graphic/render/gamerenderer.h'
409--- src/graphic/render/gamerenderer.h 1970-01-01 00:00:00 +0000
410+++ src/graphic/render/gamerenderer.h 2013-02-09 12:25:26 +0000
411@@ -0,0 +1,97 @@
412+/*
413+ * Copyright (C) 2010-2013 by the Widelands Development Team
414+ *
415+ * This program is free software; you can redistribute it and/or
416+ * modify it under the terms of the GNU General Public License
417+ * as published by the Free Software Foundation; either version 2
418+ * of the License, or (at your option) any later version.
419+ *
420+ * This program is distributed in the hope that it will be useful,
421+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
422+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
423+ * GNU General Public License for more details.
424+ *
425+ * You should have received a copy of the GNU General Public License
426+ * along with this program; if not, write to the Free Software
427+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
428+ *
429+ */
430+
431+#ifndef WIDELANDS_GAMERENDERER_H
432+#define WIDELANDS_GAMERENDERER_H
433+
434+#include "point.h"
435+
436+namespace Widelands {
437+ struct Player;
438+ struct Editor_Game_Base;
439+};
440+
441+struct RenderTarget;
442+
443+/**
444+ * This abstract base class renders the main game view into an
445+ * arbitrary @ref RenderTarget.
446+ *
447+ * Specializations exist for SDL software rendering and for OpenGL rendering.
448+ *
449+ * Users of this class should keep instances alive for as long as possible,
450+ * so that target-specific optimizations (such as caching data) can
451+ * be effective.
452+ */
453+class GameRenderer {
454+public:
455+ GameRenderer();
456+ virtual ~GameRenderer();
457+
458+ /**
459+ * Renders the map from a player's point of view into the
460+ * given drawing window.
461+ *
462+ * @param viewofs is the offset of the upper left corner of
463+ * the window into the map, in pixels.
464+ */
465+ void rendermap
466+ (RenderTarget & dst,
467+ Widelands::Editor_Game_Base const & egbase,
468+ Widelands::Player const & player,
469+ Point const & viewofs);
470+
471+ /**
472+ * Renders the map from an omniscient perspective.
473+ * This is used for spectators, players that see all, and in the editor.
474+ */
475+ void rendermap
476+ (RenderTarget & dst,
477+ Widelands::Editor_Game_Base const & egbase,
478+ Point const & viewofs);
479+
480+protected:
481+ virtual void draw() = 0;
482+
483+ void draw_objects();
484+
485+ /**
486+ * The following variables, which are setup by @ref rendermap,
487+ * are only valid during rendering,
488+ * and should be treated as read-only by derived classes.
489+ */
490+ /*@{*/
491+ RenderTarget * m_dst;
492+ Widelands::Editor_Game_Base const * m_egbase;
493+ Widelands::Player const * m_player;
494+
495+ /// Translation from map pixel coordinates to @ref m_dst pixel coordinates
496+ Point m_dst_offset;
497+
498+ int32_t m_minfx;
499+ int32_t m_minfy;
500+ int32_t m_maxfx;
501+ int32_t m_maxfy;
502+ /*@}*/
503+
504+private:
505+ void draw_wrapper();
506+};
507+
508+#endif //WIDELANDS_GAMEVIEW_H
509
510=== added file 'src/graphic/render/gamerenderer_gl.cc'
511--- src/graphic/render/gamerenderer_gl.cc 1970-01-01 00:00:00 +0000
512+++ src/graphic/render/gamerenderer_gl.cc 2013-02-09 12:25:26 +0000
513@@ -0,0 +1,669 @@
514+/*
515+ * Copyright (C) 2011-2013 by the Widelands Development Team
516+ *
517+ * This program is free software; you can redistribute it and/or
518+ * modify it under the terms of the GNU General Public License
519+ * as published by the Free Software Foundation; either version 2
520+ * of the License, or (at your option) any later version.
521+ *
522+ * This program is distributed in the hope that it will be useful,
523+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
524+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
525+ * GNU General Public License for more details.
526+ *
527+ * You should have received a copy of the GNU General Public License
528+ * along with this program; if not, write to the Free Software
529+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
530+ *
531+ */
532+
533+#ifdef USE_OPENGL
534+#include "gamerenderer_gl.h"
535+
536+#include "gl_surface.h"
537+
538+#include "logic/editor_game_base.h"
539+#include "logic/player.h"
540+
541+#include "graphic/graphic.h"
542+#include "graphic/rendertarget.h"
543+#include "graphic/texture.h"
544+
545+#include "wui/mapviewpixelconstants.h"
546+#include "wui/mapviewpixelfunctions.h"
547+#include "wui/overlay_manager.h"
548+
549+#include <SDL_image.h>
550+
551+using namespace Widelands;
552+
553+static const uint32_t PatchSize = 4;
554+
555+GameRendererGL::GameRendererGL() :
556+ m_patch_vertices_size(0),
557+ m_patch_indices_size(0),
558+ m_edge_vertices_size(0),
559+ m_road_vertices_size(0)
560+{
561+}
562+
563+GameRendererGL::~GameRendererGL()
564+{
565+}
566+
567+const GLSurfaceTexture * GameRendererGL::get_dither_edge_texture(const Widelands::World & world)
568+{
569+ char fname[256];
570+ snprintf(fname, sizeof(fname), "%s/pics/edge.png", world.basedir().c_str());
571+ std::string cachename = std::string("gltex#") + fname;
572+
573+ const GLSurfaceTexture * edgetexture =
574+ dynamic_cast<const GLSurfaceTexture *>(g_gr->imgcache().get(PicMod_Game, cachename));
575+ if (!edgetexture) {
576+ FileRead fr;
577+ fr.fastOpen(*g_fs, fname);
578+
579+ SDL_Surface * sdlsurf = IMG_Load_RW(SDL_RWFromMem(fr.Data(0), fr.GetSize()), 1);
580+ if (!sdlsurf)
581+ throw wexception("%s", IMG_GetError());
582+
583+ edgetexture = new GLSurfaceTexture(sdlsurf, true);
584+ g_gr->imgcache().insert(PicMod_Game, cachename, edgetexture);
585+ }
586+ return edgetexture;
587+}
588+
589+uint32_t GameRendererGL::patch_index(const Coords & f) const
590+{
591+ uint32_t x = f.x - m_patch_size.x;
592+ uint32_t y = f.y - m_patch_size.y;
593+
594+ assert(x < m_patch_size.w);
595+ assert(y < m_patch_size.h);
596+
597+ uint32_t outerx = x / PatchSize;
598+ uint32_t outery = y / PatchSize;
599+ uint32_t innerx = x % PatchSize;
600+ uint32_t innery = y % PatchSize;
601+
602+ return
603+ (outery * (m_patch_size.w / PatchSize) + outerx) * (PatchSize * PatchSize) +
604+ innery * PatchSize + innerx;
605+}
606+
607+uint8_t GameRendererGL::field_brightness(const FCoords & coords) const
608+{
609+ uint32_t brightness;
610+ brightness = 144 + coords.field->get_brightness();
611+ brightness = (brightness * 255) / 160;
612+ if (brightness > 255)
613+ brightness = 255;
614+
615+ if (m_player && !m_player->see_all()) {
616+ const Map & map = m_egbase->map();
617+ const Player::Field & pf = m_player->fields()[Map::get_index(coords, map.get_width())];
618+ if (pf.vision == 0) {
619+ return 0;
620+ } else if (pf.vision == 1) {
621+ static const uint32_t DecayTime = 20000;
622+ Duration time_ago = m_egbase->get_gametime() - pf.time_node_last_unseen;
623+ if (time_ago < DecayTime)
624+ brightness = (brightness * (2 * DecayTime - time_ago)) / (2 * DecayTime);
625+ else
626+ brightness = brightness / 2;
627+ }
628+ }
629+
630+ return brightness;
631+}
632+
633+void GameRendererGL::draw()
634+{
635+ m_surface = dynamic_cast<GLSurface *>(m_dst->get_surface());
636+ if (!m_surface)
637+ return;
638+ m_rect = m_dst->get_rect();
639+ m_surface_offset = m_dst_offset + m_rect + m_dst->get_offset();
640+
641+ m_patch_size.x = m_minfx - 1;
642+ m_patch_size.y = m_minfy;
643+ m_patch_size.w = ((m_maxfx - m_minfx + 2 + PatchSize) / PatchSize) * PatchSize;
644+ m_patch_size.h = ((m_maxfy - m_minfy + 1 + PatchSize) / PatchSize) * PatchSize;
645+
646+ glScissor
647+ (m_rect.x, m_surface->get_h() - m_rect.y - m_rect.h,
648+ m_rect.w, m_rect.h);
649+ glEnable(GL_SCISSOR_TEST);
650+
651+ prepare_terrain_base();
652+ draw_terrain_base();
653+ if (g_gr->caps().gl.multitexture && g_gr->caps().gl.max_tex_combined >= 2) {
654+ prepare_terrain_dither();
655+ draw_terrain_dither();
656+ }
657+ prepare_roads();
658+ draw_roads();
659+ draw_objects();
660+
661+ glDisable(GL_SCISSOR_TEST);
662+}
663+
664+template<typename vertex>
665+void GameRendererGL::compute_basevertex(const Coords & coords, vertex & vtx) const
666+{
667+ Map const & map = m_egbase->map();
668+ Coords ncoords(coords);
669+ map.normalize_coords(ncoords);
670+ FCoords fcoords = map.get_fcoords(ncoords);
671+ Point pix;
672+ MapviewPixelFunctions::get_basepix(coords, pix.x, pix.y);
673+ pix.y -= fcoords.field->get_height() * HEIGHT_FACTOR;
674+ pix += m_surface_offset;
675+ vtx.x = pix.x;
676+ vtx.y = pix.y;
677+ Point tex;
678+ MapviewPixelFunctions::get_basepix(coords, tex.x, tex.y);
679+ vtx.tcx = float(tex.x) / TEXTURE_WIDTH;
680+ vtx.tcy = float(tex.y) / TEXTURE_HEIGHT;
681+ uint8_t brightness = field_brightness(fcoords);
682+ vtx.color[0] = vtx.color[1] = vtx.color[2] = brightness;
683+ vtx.color[3] = 255;
684+}
685+
686+void GameRendererGL::count_terrain_base(Terrain_Index ter)
687+{
688+ if (ter >= m_terrain_freq.size())
689+ m_terrain_freq.resize(ter + 1);
690+ m_terrain_freq[ter] += 1;
691+}
692+
693+void GameRendererGL::add_terrain_base_triangle
694+ (Terrain_Index ter, const Coords & p1, const Coords & p2, const Coords & p3)
695+{
696+ uint32_t index = m_patch_indices_indexs[ter];
697+ m_patch_indices[index++] = patch_index(p1);
698+ m_patch_indices[index++] = patch_index(p2);
699+ m_patch_indices[index++] = patch_index(p3);
700+ m_patch_indices_indexs[ter] = index;
701+}
702+
703+void GameRendererGL::collect_terrain_base(bool onlyscan)
704+{
705+ Map const & map = m_egbase->map();
706+
707+ uint32_t index = 0;
708+ for (uint32_t outery = 0; outery < m_patch_size.h / PatchSize; ++outery) {
709+ for (uint32_t outerx = 0; outerx < m_patch_size.w / PatchSize; ++outerx) {
710+ for (uint32_t innery = 0; innery < PatchSize; ++innery) {
711+ for (uint32_t innerx = 0; innerx < PatchSize; ++innerx) {
712+ Coords coords
713+ (m_patch_size.x + outerx * PatchSize + innerx,
714+ m_patch_size.y + outery * PatchSize + innery);
715+
716+ if (onlyscan) {
717+ assert(index == patch_index(coords));
718+ compute_basevertex(coords, m_patch_vertices[index]);
719+ ++index;
720+ }
721+
722+ if (coords.x >= m_minfx && coords.y >= m_minfy && coords.x <= m_maxfx && coords.y <= m_maxfy) {
723+ Coords ncoords(coords);
724+ map.normalize_coords(ncoords);
725+ FCoords fcoords = map.get_fcoords(ncoords);
726+ Terrain_Index ter_d = fcoords.field->get_terrains().d;
727+ Terrain_Index ter_r = fcoords.field->get_terrains().r;
728+
729+ if (onlyscan) {
730+ count_terrain_base(ter_d);
731+ count_terrain_base(ter_r);
732+ } else {
733+ Coords brn(coords.x + (coords.y & 1), coords.y + 1);
734+ Coords bln(brn.x - 1, brn.y);
735+ Coords rn(coords.x + 1, coords.y);
736+
737+ add_terrain_base_triangle(ter_d, coords, bln, brn);
738+ add_terrain_base_triangle(ter_r, coords, brn, rn);
739+ }
740+ }
741+ }
742+ }
743+ }
744+ }
745+}
746+
747+void GameRendererGL::prepare_terrain_base()
748+{
749+ assert(sizeof(basevertex) == 32);
750+
751+ uint32_t reqsize = m_patch_size.w * m_patch_size.h;
752+ if (reqsize > 0x10000)
753+ throw wexception("Too many vertices; decrease screen resolution");
754+
755+ if (reqsize > m_patch_vertices_size) {
756+ m_patch_vertices.reset(new basevertex[reqsize]);
757+ m_patch_vertices_size = reqsize;
758+ }
759+
760+ if (m_terrain_freq.size() < 16)
761+ m_terrain_freq.resize(16);
762+ m_terrain_freq.assign(m_terrain_freq.size(), 0);
763+
764+ collect_terrain_base(true);
765+
766+ m_terrain_freq_cum.resize(m_terrain_freq.size());
767+ uint32_t nrtriangles = 0;
768+ for (uint32_t idx = 0; idx < m_terrain_freq.size(); ++idx) {
769+ m_terrain_freq_cum[idx] = nrtriangles;
770+ nrtriangles += m_terrain_freq[idx];
771+ }
772+
773+ if (3 * nrtriangles > m_patch_indices_size) {
774+ m_patch_indices.reset(new uint16_t[3 * nrtriangles]);
775+ m_patch_indices_size = 3 * nrtriangles;
776+ }
777+
778+ m_patch_indices_indexs.resize(m_terrain_freq.size());
779+ for (Terrain_Index ter = 0; ter < m_terrain_freq.size(); ++ter)
780+ m_patch_indices_indexs[ter] = 3 * m_terrain_freq_cum[ter];
781+
782+ collect_terrain_base(false);
783+
784+ for (Terrain_Index ter = 0; ter < m_terrain_freq.size(); ++ter) {
785+ assert(m_patch_indices_indexs[ter] == 3 * (m_terrain_freq_cum[ter] + m_terrain_freq[ter]));
786+ }
787+}
788+
789+void GameRendererGL::draw_terrain_base()
790+{
791+ Map const & map = m_egbase->map();
792+ World const & world = map.world();
793+
794+ glMatrixMode(GL_TEXTURE);
795+ glLoadIdentity();
796+
797+ glVertexPointer(2, GL_FLOAT, sizeof(basevertex), &m_patch_vertices[0].x);
798+ glTexCoordPointer(2, GL_FLOAT, sizeof(basevertex), &m_patch_vertices[0].tcx);
799+ glColorPointer(4, GL_UNSIGNED_BYTE, sizeof(basevertex), &m_patch_vertices[0].color);
800+ glEnableClientState(GL_VERTEX_ARRAY);
801+ glEnableClientState(GL_TEXTURE_COORD_ARRAY);
802+ glEnableClientState(GL_COLOR_ARRAY);
803+
804+ glColor3f(1.0, 1.0, 1.0);
805+ glDisable(GL_BLEND);
806+
807+ for (Terrain_Index ter = 0; ter < m_terrain_freq.size(); ++ter) {
808+ if (!m_terrain_freq[ter])
809+ continue;
810+
811+ const Texture & texture =
812+ *g_gr->get_maptexture_data
813+ (world.terrain_descr(ter).get_texture());
814+ glBindTexture(GL_TEXTURE_2D, texture.getTexture());
815+ glDrawRangeElements
816+ (GL_TRIANGLES,
817+ 0, m_patch_size.w * m_patch_size.h - 1,
818+ 3 * m_terrain_freq[ter], GL_UNSIGNED_SHORT,
819+ &m_patch_indices[3 * m_terrain_freq_cum[ter]]);
820+ }
821+
822+ glDisableClientState(GL_VERTEX_ARRAY);
823+ glDisableClientState(GL_TEXTURE_COORD_ARRAY);
824+ glDisableClientState(GL_COLOR_ARRAY);
825+}
826+
827+void GameRendererGL::add_terrain_dither_triangle
828+ (bool onlyscan, Terrain_Index ter, const Coords & edge1, const Coords & edge2, const Coords & opposite)
829+{
830+ if (onlyscan) {
831+ if (ter >= m_terrain_edge_freq.size())
832+ m_terrain_edge_freq.resize(ter + 1);
833+ m_terrain_edge_freq[ter] += 1;
834+ } else {
835+ static const float TyZero = 1.0 / TEXTURE_HEIGHT;
836+ static const float TyOne = 1.0 - TyZero;
837+
838+ uint32_t index = m_terrain_edge_indexs[ter];
839+ compute_basevertex(edge1, m_edge_vertices[index]);
840+ m_edge_vertices[index].edgex = 0.0;
841+ m_edge_vertices[index].edgey = TyZero;
842+ ++index;
843+ compute_basevertex(edge2, m_edge_vertices[index]);
844+ m_edge_vertices[index].edgex = 1.0;
845+ m_edge_vertices[index].edgey = TyZero;
846+ ++index;
847+ compute_basevertex(opposite, m_edge_vertices[index]);
848+ m_edge_vertices[index].edgex = 0.5;
849+ m_edge_vertices[index].edgey = TyOne;
850+ ++index;
851+ m_terrain_edge_indexs[ter] = index;
852+ }
853+}
854+
855+void GameRendererGL::collect_terrain_dither(bool onlyscan)
856+{
857+ Map const & map = m_egbase->map();
858+ World const & world = map.world();
859+
860+ for (int32_t fy = m_minfy; fy <= m_maxfy; ++fy) {
861+ for (int32_t fx = m_minfx; fx <= m_maxfx; ++fx) {
862+ Coords ncoords(fx, fy);
863+ map.normalize_coords(ncoords);
864+ FCoords fcoords = map.get_fcoords(ncoords);
865+
866+ Terrain_Index ter_d = fcoords.field->get_terrains().d;
867+ Terrain_Index ter_r = fcoords.field->get_terrains().r;
868+ Terrain_Index ter_u = map.tr_n(fcoords).field->get_terrains().d;
869+ Terrain_Index ter_rr = map.r_n(fcoords).field->get_terrains().d;
870+ Terrain_Index ter_l = map.l_n(fcoords).field->get_terrains().r;
871+ Terrain_Index ter_dd = map.bl_n(fcoords).field->get_terrains().r;
872+ int32_t lyr_d = world.get_ter(ter_d).dither_layer();
873+ int32_t lyr_r = world.get_ter(ter_r).dither_layer();
874+ int32_t lyr_u = world.get_ter(ter_u).dither_layer();
875+ int32_t lyr_rr = world.get_ter(ter_rr).dither_layer();
876+ int32_t lyr_l = world.get_ter(ter_l).dither_layer();
877+ int32_t lyr_dd = world.get_ter(ter_dd).dither_layer();
878+
879+ Coords f(fx, fy);
880+ Coords rn(fx + 1, fy);
881+ Coords brn(fx + (fy & 1), fy + 1);
882+ Coords bln(brn.x - 1, brn.y);
883+
884+ if (lyr_r > lyr_d) {
885+ add_terrain_dither_triangle(onlyscan, ter_r, brn, f, bln);
886+ } else if (ter_d != ter_r) {
887+ add_terrain_dither_triangle(onlyscan, ter_d, f, brn, rn);
888+ }
889+ if ((lyr_u > lyr_r) || (lyr_u == lyr_r && ter_u != ter_r)) {
890+ add_terrain_dither_triangle(onlyscan, ter_u, rn, f, brn);
891+ }
892+ if (lyr_rr > lyr_r) {
893+ add_terrain_dither_triangle(onlyscan, ter_rr, brn, rn, f);
894+ }
895+ if ((lyr_l > lyr_d) || (lyr_l == lyr_d && ter_l != ter_d)) {
896+ add_terrain_dither_triangle(onlyscan, ter_l, f, bln, brn);
897+ }
898+ if (lyr_dd > lyr_d) {
899+ add_terrain_dither_triangle(onlyscan, ter_dd, bln, brn, f);
900+ }
901+ }
902+ }
903+}
904+
905+/*
906+ * Schematic of triangle neighborhood:
907+ *
908+ * *
909+ * / \
910+ * / u \
911+ * (f)/ \
912+ * *------*------* (r)
913+ * \ l / \ r / \
914+ * \ / \ / \
915+ * \/ d \/ rr \
916+ * *------*------* (br)
917+ * \ dd /
918+ * \ /
919+ * \/
920+ * *
921+ */
922+void GameRendererGL::prepare_terrain_dither()
923+{
924+ assert(sizeof(dithervertex) == 32);
925+
926+ if (m_terrain_edge_freq.size() < 16)
927+ m_terrain_edge_freq.resize(16);
928+ m_terrain_edge_freq.assign(m_terrain_edge_freq.size(), 0);
929+
930+ collect_terrain_dither(true);
931+
932+ uint32_t nrtriangles = 0;
933+ m_terrain_edge_freq_cum.resize(m_terrain_edge_freq.size());
934+ for (Terrain_Index ter = 0; ter < m_terrain_edge_freq.size(); ++ter) {
935+ m_terrain_edge_freq_cum[ter] = nrtriangles;
936+ nrtriangles += m_terrain_edge_freq[ter];
937+ }
938+
939+ if (3 * nrtriangles > m_edge_vertices_size) {
940+ m_edge_vertices.reset(new dithervertex[3 * nrtriangles]);
941+ m_edge_vertices_size = 3 * nrtriangles;
942+ }
943+
944+ m_terrain_edge_indexs.resize(m_terrain_edge_freq_cum.size());
945+ for (Terrain_Index ter = 0; ter < m_terrain_edge_freq.size(); ++ter)
946+ m_terrain_edge_indexs[ter] = 3 * m_terrain_edge_freq_cum[ter];
947+
948+ collect_terrain_dither(false);
949+
950+ for (Terrain_Index ter = 0; ter < m_terrain_edge_freq.size(); ++ter) {
951+ assert(m_terrain_edge_indexs[ter] == 3 * (m_terrain_edge_freq_cum[ter] + m_terrain_edge_freq[ter]));
952+ }
953+}
954+
955+void GameRendererGL::draw_terrain_dither()
956+{
957+ Map const & map = m_egbase->map();
958+ World const & world = map.world();
959+
960+ if (m_edge_vertices_size == 0)
961+ return;
962+
963+ glVertexPointer(2, GL_FLOAT, sizeof(dithervertex), &m_edge_vertices[0].x);
964+ glTexCoordPointer(2, GL_FLOAT, sizeof(dithervertex), &m_edge_vertices[0].tcx);
965+ glColorPointer(4, GL_UNSIGNED_BYTE, sizeof(dithervertex), &m_edge_vertices[0].color);
966+ glEnableClientState(GL_VERTEX_ARRAY);
967+ glEnableClientState(GL_TEXTURE_COORD_ARRAY);
968+ glEnableClientState(GL_COLOR_ARRAY);
969+
970+ glActiveTextureARB(GL_TEXTURE1_ARB);
971+ glClientActiveTextureARB(GL_TEXTURE1_ARB);
972+ glTexCoordPointer(2, GL_FLOAT, sizeof(dithervertex), &m_edge_vertices[0].edgex);
973+ glEnableClientState(GL_TEXTURE_COORD_ARRAY);
974+ GLuint edge = get_dither_edge_texture(world)->get_gl_texture();
975+ glBindTexture(GL_TEXTURE_2D, edge);
976+ glEnable(GL_TEXTURE_2D);
977+ glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_ARB);
978+ glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_REPLACE);
979+ glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_PREVIOUS);
980+ glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB_ARB, GL_SRC_COLOR);
981+ glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_ARB, GL_REPLACE);
982+ glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_ARB, GL_TEXTURE);
983+ glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA_ARB, GL_SRC_ALPHA);
984+ glActiveTextureARB(GL_TEXTURE0_ARB);
985+ glClientActiveTextureARB(GL_TEXTURE0_ARB);
986+
987+ glEnable(GL_BLEND);
988+ glBlendFunc(GL_ONE_MINUS_SRC_ALPHA, GL_SRC_ALPHA);
989+
990+ for (Terrain_Index ter = 0; ter < m_terrain_freq.size(); ++ter) {
991+ if (!m_terrain_edge_freq[ter])
992+ continue;
993+
994+ const Texture & texture =
995+ *g_gr->get_maptexture_data
996+ (world.terrain_descr(ter).get_texture());
997+ glBindTexture(GL_TEXTURE_2D, texture.getTexture());
998+ glDrawArrays
999+ (GL_TRIANGLES,
1000+ 3 * m_terrain_edge_freq_cum[ter], 3 * m_terrain_edge_freq[ter]);
1001+ }
1002+
1003+ glDisableClientState(GL_VERTEX_ARRAY);
1004+ glDisableClientState(GL_TEXTURE_COORD_ARRAY);
1005+ glDisableClientState(GL_COLOR_ARRAY);
1006+ glActiveTextureARB(GL_TEXTURE1_ARB);
1007+ glClientActiveTextureARB(GL_TEXTURE1_ARB);
1008+ glDisableClientState(GL_TEXTURE_COORD_ARRAY);
1009+ glDisable(GL_TEXTURE_2D);
1010+ glActiveTextureARB(GL_TEXTURE0_ARB);
1011+ glClientActiveTextureARB(GL_TEXTURE0_ARB);
1012+}
1013+
1014+uint8_t GameRendererGL::field_roads(const FCoords & coords) const
1015+{
1016+ if (m_player) {
1017+ const Map & map = m_egbase->map();
1018+ const Player::Field & pf = m_player->fields()[Map::get_index(coords, map.get_width())];
1019+ return pf.roads | map.get_overlay_manager().get_road_overlay(coords);
1020+ } else {
1021+ return coords.field->get_roads();
1022+ }
1023+}
1024+
1025+void GameRendererGL::prepare_roads()
1026+{
1027+ const Map & map = m_egbase->map();
1028+
1029+ m_road_freq[0] = 0;
1030+ m_road_freq[1] = 0;
1031+
1032+ for (int32_t fy = m_minfy; fy <= m_maxfy; ++fy) {
1033+ for (int32_t fx = m_minfx; fx <= m_maxfx; ++fx) {
1034+ Coords ncoords(fx, fy);
1035+ map.normalize_coords(ncoords);
1036+ FCoords fcoords = map.get_fcoords(ncoords);
1037+ uint8_t roads = field_roads(fcoords);
1038+
1039+ for (int dir = 0; dir < 3; ++dir) {
1040+ uint8_t road = (roads >> (2 * dir)) & Road_Mask;
1041+ if (road >= Road_Normal && road <= Road_Busy) {
1042+ ++m_road_freq[road - Road_Normal];
1043+ }
1044+ }
1045+ }
1046+ }
1047+
1048+ uint32_t nrquads = m_road_freq[0] + m_road_freq[1];
1049+ if (4 * nrquads > m_road_vertices_size) {
1050+ m_road_vertices.reset(new basevertex[4 * nrquads]);
1051+ m_road_vertices_size = 4 * nrquads;
1052+ }
1053+
1054+ uint32_t indexs[2];
1055+ indexs[0] = 0;
1056+ indexs[1] = 4 * m_road_freq[0];
1057+
1058+ for (int32_t fy = m_minfy; fy <= m_maxfy; ++fy) {
1059+ for (int32_t fx = m_minfx; fx <= m_maxfx; ++fx) {
1060+ Coords ncoords(fx, fy);
1061+ map.normalize_coords(ncoords);
1062+ FCoords fcoords = map.get_fcoords(ncoords);
1063+ uint8_t roads = field_roads(fcoords);
1064+
1065+ uint8_t road = (roads >> Road_East) & Road_Mask;
1066+ if (road >= Road_Normal && road <= Road_Busy) {
1067+ uint32_t index = indexs[road - Road_Normal];
1068+ basevertex start, end;
1069+ compute_basevertex(Coords(fx, fy), start);
1070+ compute_basevertex(Coords(fx + 1, fy), end);
1071+ m_road_vertices[index] = start;
1072+ m_road_vertices[index].y -= 2;
1073+ m_road_vertices[index].tcy -= 2.0 / TEXTURE_HEIGHT;
1074+ ++index;
1075+ m_road_vertices[index] = start;
1076+ m_road_vertices[index].y += 2;
1077+ m_road_vertices[index].tcy += 2.0 / TEXTURE_HEIGHT;
1078+ ++index;
1079+ m_road_vertices[index] = end;
1080+ m_road_vertices[index].y += 2;
1081+ m_road_vertices[index].tcy += 2.0 / TEXTURE_HEIGHT;
1082+ ++index;
1083+ m_road_vertices[index] = end;
1084+ m_road_vertices[index].y -= 2;
1085+ m_road_vertices[index].tcy -= 2.0 / TEXTURE_HEIGHT;
1086+ ++index;
1087+ indexs[road - Road_Normal] = index;
1088+ }
1089+
1090+ road = (roads >> Road_SouthEast) & Road_Mask;
1091+ if (road >= Road_Normal && road <= Road_Busy) {
1092+ uint32_t index = indexs[road - Road_Normal];
1093+ basevertex start, end;
1094+ compute_basevertex(Coords(fx, fy), start);
1095+ compute_basevertex(Coords(fx + (fy & 1), fy + 1), end);
1096+ m_road_vertices[index] = start;
1097+ m_road_vertices[index].x += 3;
1098+ m_road_vertices[index].tcx += 3.0 / TEXTURE_HEIGHT;
1099+ ++index;
1100+ m_road_vertices[index] = start;
1101+ m_road_vertices[index].x -= 3;
1102+ m_road_vertices[index].tcx -= 3.0 / TEXTURE_HEIGHT;
1103+ ++index;
1104+ m_road_vertices[index] = end;
1105+ m_road_vertices[index].x -= 3;
1106+ m_road_vertices[index].tcx -= 3.0 / TEXTURE_HEIGHT;
1107+ ++index;
1108+ m_road_vertices[index] = end;
1109+ m_road_vertices[index].x += 3;
1110+ m_road_vertices[index].tcx += 3.0 / TEXTURE_HEIGHT;
1111+ ++index;
1112+ indexs[road - Road_Normal] = index;
1113+ }
1114+
1115+ road = (roads >> Road_SouthWest) & Road_Mask;
1116+ if (road >= Road_Normal && road <= Road_Busy) {
1117+ uint32_t index = indexs[road - Road_Normal];
1118+ basevertex start, end;
1119+ compute_basevertex(Coords(fx, fy), start);
1120+ compute_basevertex(Coords(fx + (fy & 1) - 1, fy + 1), end);
1121+ m_road_vertices[index] = start;
1122+ m_road_vertices[index].x += 3;
1123+ m_road_vertices[index].tcx += 3.0 / TEXTURE_HEIGHT;
1124+ ++index;
1125+ m_road_vertices[index] = start;
1126+ m_road_vertices[index].x -= 3;
1127+ m_road_vertices[index].tcx -= 3.0 / TEXTURE_HEIGHT;
1128+ ++index;
1129+ m_road_vertices[index] = end;
1130+ m_road_vertices[index].x -= 3;
1131+ m_road_vertices[index].tcx -= 3.0 / TEXTURE_HEIGHT;
1132+ ++index;
1133+ m_road_vertices[index] = end;
1134+ m_road_vertices[index].x += 3;
1135+ m_road_vertices[index].tcx += 3.0 / TEXTURE_HEIGHT;
1136+ ++index;
1137+ indexs[road - Road_Normal] = index;
1138+ }
1139+ }
1140+ }
1141+
1142+ assert(indexs[0] == 4 * m_road_freq[0]);
1143+ assert(indexs[1] == 4 * nrquads);
1144+}
1145+
1146+void GameRendererGL::draw_roads()
1147+{
1148+ if (!m_road_freq[0] && !m_road_freq[1])
1149+ return;
1150+
1151+ GLuint rt_normal =
1152+ dynamic_cast<GLSurfaceTexture const &>
1153+ (*g_gr->get_road_texture(Widelands::Road_Normal)).get_gl_texture();
1154+ GLuint rt_busy =
1155+ dynamic_cast<GLSurfaceTexture const &>
1156+ (*g_gr->get_road_texture(Widelands::Road_Busy)).get_gl_texture();
1157+
1158+ glVertexPointer(2, GL_FLOAT, sizeof(basevertex), &m_road_vertices[0].x);
1159+ glTexCoordPointer(2, GL_FLOAT, sizeof(basevertex), &m_road_vertices[0].tcx);
1160+ glColorPointer(4, GL_UNSIGNED_BYTE, sizeof(basevertex), &m_road_vertices[0].color);
1161+ glEnableClientState(GL_VERTEX_ARRAY);
1162+ glEnableClientState(GL_TEXTURE_COORD_ARRAY);
1163+ glEnableClientState(GL_COLOR_ARRAY);
1164+
1165+ glDisable(GL_BLEND);
1166+
1167+ if (m_road_freq[0]) {
1168+ glBindTexture(GL_TEXTURE_2D, rt_normal);
1169+ glDrawArrays(GL_QUADS, 0, 4 * m_road_freq[0]);
1170+ }
1171+
1172+ if (m_road_freq[1]) {
1173+ glBindTexture(GL_TEXTURE_2D, rt_busy);
1174+ glDrawArrays(GL_QUADS, 4 * m_road_freq[0], 4 * m_road_freq[1]);
1175+ }
1176+
1177+ glDisableClientState(GL_VERTEX_ARRAY);
1178+ glDisableClientState(GL_TEXTURE_COORD_ARRAY);
1179+ glDisableClientState(GL_COLOR_ARRAY);
1180+}
1181+
1182+#endif // USE_OPENGL
1183
1184=== added file 'src/graphic/render/gamerenderer_gl.h'
1185--- src/graphic/render/gamerenderer_gl.h 1970-01-01 00:00:00 +0000
1186+++ src/graphic/render/gamerenderer_gl.h 2013-02-09 12:25:26 +0000
1187@@ -0,0 +1,132 @@
1188+/*
1189+ * Copyright (C) 2011-2013 by the Widelands Development Team
1190+ *
1191+ * This program is free software; you can redistribute it and/or
1192+ * modify it under the terms of the GNU General Public License
1193+ * as published by the Free Software Foundation; either version 2
1194+ * of the License, or (at your option) any later version.
1195+ *
1196+ * This program is distributed in the hope that it will be useful,
1197+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
1198+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1199+ * GNU General Public License for more details.
1200+ *
1201+ * You should have received a copy of the GNU General Public License
1202+ * along with this program; if not, write to the Free Software
1203+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
1204+ *
1205+ */
1206+
1207+#ifdef USE_OPENGL
1208+#ifndef WIDELANDS_GAMERENDERER_GL_H
1209+#define WIDELANDS_GAMERENDERER_GL_H
1210+
1211+#include "gamerenderer.h"
1212+
1213+#include "logic/widelands.h"
1214+
1215+#include "rect.h"
1216+
1217+#include <vector>
1218+#include <boost/scoped_array.hpp>
1219+
1220+namespace Widelands {
1221+struct Coords;
1222+struct FCoords;
1223+struct World;
1224+}
1225+
1226+class GLSurface;
1227+class GLSurfaceTexture;
1228+
1229+/**
1230+ * OpenGL implementation of @ref GameRenderer.
1231+ */
1232+class GameRendererGL : public GameRenderer {
1233+public:
1234+ GameRendererGL();
1235+ virtual ~GameRendererGL();
1236+
1237+private:
1238+ struct basevertex {
1239+ float x;
1240+ float y;
1241+ float tcx;
1242+ float tcy;
1243+ uint8_t color[4];
1244+ uint32_t pad[3];
1245+ };
1246+
1247+ struct dithervertex {
1248+ float x;
1249+ float y;
1250+ float tcx;
1251+ float tcy;
1252+ float edgex;
1253+ float edgey;
1254+ uint8_t color[4];
1255+ uint32_t pad[1];
1256+ };
1257+
1258+ const GLSurfaceTexture * get_dither_edge_texture(const Widelands::World & world);
1259+
1260+ void draw();
1261+ void prepare_terrain_base();
1262+ void collect_terrain_base(bool onlyscan);
1263+ void count_terrain_base(Widelands::Terrain_Index ter);
1264+ void add_terrain_base_triangle
1265+ (Widelands::Terrain_Index ter,
1266+ const Widelands::Coords & p1, const Widelands::Coords & p2, const Widelands::Coords & p3);
1267+ void draw_terrain_base();
1268+ void prepare_terrain_dither();
1269+ void collect_terrain_dither(bool onlyscan);
1270+ void add_terrain_dither_triangle
1271+ (bool onlyscan, Widelands::Terrain_Index ter,
1272+ const Widelands::Coords & edge1, const Widelands::Coords & edge2,
1273+ const Widelands::Coords & opposite);
1274+ void draw_terrain_dither();
1275+ void prepare_roads();
1276+ void draw_roads();
1277+
1278+ uint32_t patch_index(const Widelands::Coords & f) const;
1279+ uint8_t field_brightness(const Widelands::FCoords & coords) const;
1280+ uint8_t field_roads(const Widelands::FCoords & coords) const;
1281+ template<typename vertex>
1282+ void compute_basevertex(const Widelands::Coords & coords, vertex & vtx) const;
1283+
1284+ /**
1285+ * The following variables are only valid during rendering.
1286+ */
1287+ /*@{*/
1288+ GLSurface * m_surface;
1289+
1290+ /// Bounding rectangle inside the destination surface
1291+ Rect m_rect;
1292+
1293+ /// Translation from map pixel coordinates to surface pixel coordinates
1294+ /// (relative to the top-left corner of the surface, @b not relative
1295+ /// to the bounding rectangle)
1296+ Point m_surface_offset;
1297+
1298+ Rect m_patch_size;
1299+ boost::scoped_array<basevertex> m_patch_vertices;
1300+ uint32_t m_patch_vertices_size;
1301+ boost::scoped_array<uint16_t> m_patch_indices;
1302+ uint32_t m_patch_indices_size;
1303+ std::vector<uint32_t> m_patch_indices_indexs;
1304+ std::vector<uint32_t> m_terrain_freq;
1305+ std::vector<uint32_t> m_terrain_freq_cum;
1306+ boost::scoped_array<dithervertex> m_edge_vertices;
1307+ uint32_t m_edge_vertices_size;
1308+ std::vector<uint32_t> m_terrain_edge_freq;
1309+ std::vector<uint32_t> m_terrain_edge_freq_cum;
1310+ std::vector<uint32_t> m_terrain_edge_indexs;
1311+
1312+ uint32_t m_road_freq[2];
1313+ boost::scoped_array<basevertex> m_road_vertices;
1314+ uint32_t m_road_vertices_size;
1315+ /*@}*/
1316+};
1317+
1318+#endif // WIDELANDS_GAMERENDERER_GL_H
1319+#endif // USE_OPENGL
1320
1321=== added file 'src/graphic/render/gamerenderer_sdl.cc'
1322--- src/graphic/render/gamerenderer_sdl.cc 1970-01-01 00:00:00 +0000
1323+++ src/graphic/render/gamerenderer_sdl.cc 2013-02-09 12:25:26 +0000
1324@@ -0,0 +1,279 @@
1325+/*
1326+ * Copyright (C) 2010-2013 by the Widelands Development Team
1327+ *
1328+ * This program is free software; you can redistribute it and/or
1329+ * modify it under the terms of the GNU General Public License
1330+ * as published by the Free Software Foundation; either version 2
1331+ * of the License, or (at your option) any later version.
1332+ *
1333+ * This program is distributed in the hope that it will be useful,
1334+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
1335+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1336+ * GNU General Public License for more details.
1337+ *
1338+ * You should have received a copy of the GNU General Public License
1339+ * along with this program; if not, write to the Free Software
1340+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
1341+ *
1342+ */
1343+
1344+#include "gamerenderer_sdl.h"
1345+
1346+#include "logic/field.h"
1347+#include "logic/map.h"
1348+#include "logic/player.h"
1349+
1350+#include "graphic/rendertarget.h"
1351+
1352+#include "wui/overlay_manager.h"
1353+
1354+#include "terrain_sdl.h"
1355+
1356+
1357+using namespace Widelands;
1358+
1359+///This is used by rendermap to calculate the brightness of the terrain.
1360+inline static Sint8 node_brightness
1361+ (Widelands::Time const gametime,
1362+ Widelands::Time const last_seen,
1363+ Widelands::Vision const vision,
1364+ int8_t result)
1365+{
1366+ if (vision == 0)
1367+ result = -128;
1368+ else if (vision == 1) {
1369+ assert(last_seen <= gametime);
1370+ Widelands::Duration const time_ago = gametime - last_seen;
1371+ result =
1372+ static_cast<Sint16>
1373+ (((static_cast<Sint16>(result) + 128) >> 1)
1374+ *
1375+ (1.0 + (time_ago < 45000 ? expf(-8.46126929e-5 * time_ago) : 0)))
1376+ -
1377+ 128;
1378+ }
1379+
1380+ return result;
1381+}
1382+
1383+
1384+void GameRendererSDL::draw()
1385+{
1386+ draw_terrain();
1387+ draw_objects();
1388+}
1389+
1390+void GameRendererSDL::draw_terrain()
1391+{
1392+ if (m_player && !m_player->see_all())
1393+ m_dst->get_surface()->fill_rect(m_dst->get_rect(), RGBAColor(0, 0, 0, 255));
1394+
1395+ Map const & map = m_egbase->map();
1396+ World const & world = map.world();
1397+ uint32_t const mapwidth = map.get_width();
1398+
1399+#define get_terrain_texture(ter) \
1400+ (g_gr->get_maptexture_data(world.terrain_descr((ter)).get_texture()))
1401+
1402+ int32_t dx = m_maxfx - m_minfx + 1;
1403+ int32_t dy = m_maxfy - m_minfy + 1;
1404+ int32_t linear_fy = m_minfy;
1405+ int32_t b_posy = linear_fy * TRIANGLE_HEIGHT + m_dst_offset.y;
1406+
1407+ Widelands::Time const gametime = m_egbase->get_gametime();
1408+
1409+ while (dy--) {
1410+ const int32_t posy = b_posy;
1411+ b_posy += TRIANGLE_HEIGHT;
1412+ const int32_t linear_fx = m_minfx;
1413+ FCoords r(Coords(linear_fx, linear_fy));
1414+ FCoords br(Coords(linear_fx + (linear_fy & 1) - 1, linear_fy + 1));
1415+ int32_t r_posx =
1416+ r.x * TRIANGLE_WIDTH
1417+ +
1418+ (linear_fy & 1) * (TRIANGLE_WIDTH / 2)
1419+ +
1420+ m_dst_offset.x;
1421+ int32_t br_posx = r_posx - TRIANGLE_WIDTH / 2;
1422+
1423+ // Calculate safe (bounded) field coordinates and get field pointers
1424+ map.normalize_coords(r);
1425+ map.normalize_coords(br);
1426+ Map_Index r_index = Map::get_index (r, mapwidth);
1427+ r.field = &map[r_index];
1428+ Map_Index br_index = Map::get_index(br, mapwidth);
1429+ br.field = &map[br_index];
1430+ FCoords tr;
1431+ map.get_tln(r, &tr);
1432+ Map_Index tr_index = tr.field - &map[0];
1433+
1434+ const Texture * f_r_texture;
1435+
1436+ if (m_player && !m_player->see_all()) {
1437+ const Player::Field & l_pf = m_player->fields()[Map::get_index(map.l_n(r), mapwidth)];
1438+ f_r_texture = get_terrain_texture(l_pf.terrains.r);
1439+ } else {
1440+ f_r_texture = get_terrain_texture(map.l_n(r).field->get_terrains().r);
1441+ }
1442+
1443+ uint32_t count = dx;
1444+
1445+ while (count--) {
1446+ const FCoords bl = br;
1447+ const FCoords f = r;
1448+ const int32_t f_posx = r_posx;
1449+ const int32_t bl_posx = br_posx;
1450+ Map_Index f_index = r_index;
1451+ Map_Index bl_index = br_index;
1452+ move_r(mapwidth, tr, tr_index);
1453+ move_r(mapwidth, r, r_index);
1454+ move_r(mapwidth, br, br_index);
1455+ r_posx += TRIANGLE_WIDTH;
1456+ br_posx += TRIANGLE_WIDTH;
1457+
1458+ const Texture * l_r_texture = f_r_texture;
1459+ const Texture * f_d_texture;
1460+ const Texture * tr_d_texture;
1461+ uint8_t roads;
1462+ Sint8 f_brightness;
1463+ Sint8 r_brightness;
1464+ Sint8 bl_brightness;
1465+ Sint8 br_brightness;
1466+
1467+ if (m_player && !m_player->see_all()) {
1468+ const Player::Field & f_pf = m_player->fields()[f_index];
1469+ const Player::Field & r_pf = m_player->fields()[r_index];
1470+ const Player::Field & bl_pf = m_player->fields()[bl_index];
1471+ const Player::Field & br_pf = m_player->fields()[br_index];
1472+ const Player::Field & tr_pf = m_player->fields()[tr_index];
1473+
1474+ f_r_texture = get_terrain_texture(f_pf.terrains.r);
1475+ f_d_texture = get_terrain_texture(f_pf.terrains.d);
1476+ tr_d_texture = get_terrain_texture(tr_pf.terrains.d);
1477+
1478+ roads = f_pf.roads | map.overlay_manager().get_road_overlay(f);
1479+
1480+ f_brightness = node_brightness
1481+ (gametime, f_pf.time_node_last_unseen,
1482+ f_pf.vision, f.field->get_brightness());
1483+ r_brightness = node_brightness
1484+ (gametime, r_pf.time_node_last_unseen,
1485+ r_pf.vision, r.field->get_brightness());
1486+ bl_brightness = node_brightness
1487+ (gametime, bl_pf.time_node_last_unseen,
1488+ bl_pf.vision, bl.field->get_brightness());
1489+ br_brightness = node_brightness
1490+ (gametime, br_pf.time_node_last_unseen,
1491+ br_pf.vision, br.field->get_brightness());
1492+ } else {
1493+ f_r_texture = get_terrain_texture(f.field->get_terrains().r);
1494+ f_d_texture = get_terrain_texture(f.field->get_terrains().d);
1495+ tr_d_texture = get_terrain_texture(tr.field->get_terrains().d);
1496+
1497+ roads = f.field->get_roads();
1498+
1499+ f_brightness = f.field->get_brightness();
1500+ r_brightness = r.field->get_brightness();
1501+ bl_brightness = bl.field->get_brightness();
1502+ br_brightness = br.field->get_brightness();
1503+ }
1504+
1505+ Vertex f_vert
1506+ (f_posx, posy - f.field->get_height() * HEIGHT_FACTOR,
1507+ f_brightness, 0, 0);
1508+ Vertex r_vert
1509+ (r_posx, posy - r.field->get_height() * HEIGHT_FACTOR,
1510+ r_brightness, TRIANGLE_WIDTH, 0);
1511+ Vertex bl_vert
1512+ (bl_posx, b_posy - bl.field->get_height() * HEIGHT_FACTOR,
1513+ bl_brightness, 0, 64);
1514+ Vertex br_vert
1515+ (br_posx, b_posy - br.field->get_height() * HEIGHT_FACTOR,
1516+ br_brightness, TRIANGLE_WIDTH, 64);
1517+
1518+ if (linear_fy & 1) {
1519+ f_vert.tx += TRIANGLE_WIDTH / 2;
1520+ r_vert.tx += TRIANGLE_WIDTH / 2;
1521+ } else {
1522+ f_vert.tx += TRIANGLE_WIDTH;
1523+ r_vert.tx += TRIANGLE_WIDTH;
1524+ bl_vert.tx += TRIANGLE_WIDTH / 2;
1525+ br_vert.tx += TRIANGLE_WIDTH / 2;
1526+ }
1527+
1528+ draw_field // Render ground
1529+ (*m_dst,
1530+ f_vert, r_vert, bl_vert, br_vert,
1531+ roads,
1532+ *tr_d_texture, *l_r_texture, *f_d_texture, *f_r_texture);
1533+ }
1534+
1535+ ++linear_fy;
1536+ }
1537+
1538+#undef get_terrain_texture
1539+}
1540+
1541+
1542+/**
1543+ * Draw ground textures and roads for the given parallelogram (two triangles)
1544+ * into the bitmap.
1545+ *
1546+ * Vertices:
1547+ * - f_vert vertex of the field
1548+ * - r_vert vertex right of the field
1549+ * - bl_vert vertex bottom left of the field
1550+ * - br_vert vertex bottom right of the field
1551+ *
1552+ * Textures:
1553+ * - f_r_texture Terrain of the triangle right of the field
1554+ * - f_d_texture Terrain of the triangle under of the field
1555+ * - tr_d_texture Terrain of the triangle top of the right triangle ??
1556+ * - l_r_texture Terrain of the triangle left of the down triangle ??
1557+ *
1558+ * (tr_d)
1559+ *
1560+ * (f) *------* (r)
1561+ * / \ r /
1562+ * (l_r) / \ /
1563+ * / d \/
1564+ * (bl) *------* (br)
1565+ */
1566+void GameRendererSDL::draw_field
1567+ (RenderTarget & dst,
1568+ Vertex const & f_vert,
1569+ Vertex const & r_vert,
1570+ Vertex const & bl_vert,
1571+ Vertex const & br_vert,
1572+ uint8_t roads,
1573+ Texture const & tr_d_texture,
1574+ Texture const & l_r_texture,
1575+ Texture const & f_d_texture,
1576+ Texture const & f_r_texture)
1577+{
1578+ upcast(SDLSurface, sdlsurf, dst.get_surface());
1579+ if (sdlsurf)
1580+ {
1581+ sdlsurf->set_subwin(dst.get_rect());
1582+ switch (sdlsurf->format().BytesPerPixel) {
1583+ case 2:
1584+ draw_field_int<Uint16>
1585+ (*sdlsurf,
1586+ f_vert, r_vert, bl_vert, br_vert,
1587+ roads,
1588+ tr_d_texture, l_r_texture, f_d_texture, f_r_texture);
1589+ break;
1590+ case 4:
1591+ draw_field_int<Uint32>
1592+ (*sdlsurf,
1593+ f_vert, r_vert, bl_vert, br_vert,
1594+ roads,
1595+ tr_d_texture, l_r_texture, f_d_texture, f_r_texture);
1596+ break;
1597+ default:
1598+ assert(false);
1599+ break;
1600+ }
1601+ sdlsurf->unset_subwin();
1602+ }
1603+}
1604
1605=== added file 'src/graphic/render/gamerenderer_sdl.h'
1606--- src/graphic/render/gamerenderer_sdl.h 1970-01-01 00:00:00 +0000
1607+++ src/graphic/render/gamerenderer_sdl.h 2013-02-09 12:25:26 +0000
1608@@ -0,0 +1,55 @@
1609+/*
1610+ * Copyright (C) 2010-2013 by the Widelands Development Team
1611+ *
1612+ * This program is free software; you can redistribute it and/or
1613+ * modify it under the terms of the GNU General Public License
1614+ * as published by the Free Software Foundation; either version 2
1615+ * of the License, or (at your option) any later version.
1616+ *
1617+ * This program is distributed in the hope that it will be useful,
1618+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
1619+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1620+ * GNU General Public License for more details.
1621+ *
1622+ * You should have received a copy of the GNU General Public License
1623+ * along with this program; if not, write to the Free Software
1624+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
1625+ *
1626+ */
1627+
1628+#ifndef WIDELANDS_GAMERENDERER_SDL_H
1629+#define WIDELANDS_GAMERENDERER_SDL_H
1630+
1631+#include "gamerenderer.h"
1632+
1633+struct Texture;
1634+struct Vertex;
1635+
1636+/**
1637+ * Software-rendering implementation of @ref GameRenderer.
1638+ */
1639+class GameRendererSDL : public GameRenderer {
1640+protected:
1641+ void draw();
1642+
1643+private:
1644+ void draw_terrain();
1645+
1646+ /**
1647+ * Helper function to draw two terrain triangles. This is called from the
1648+ * rendermap() functions.
1649+ */
1650+ void draw_field
1651+ (RenderTarget & dst,
1652+ Vertex const & f_vert,
1653+ Vertex const & r_vert,
1654+ Vertex const & bl_vert,
1655+ Vertex const & br_vert,
1656+ uint8_t roads,
1657+ Texture const & tr_d_texture,
1658+ Texture const & l_r_texture,
1659+ Texture const & f_d_texture,
1660+ Texture const & f_r_texture);
1661+};
1662+
1663+#endif // WIDELANDS_GAMERENDERER_SDL_H
1664
1665=== removed file 'src/graphic/render/gameview_opengl.cc'
1666--- src/graphic/render/gameview_opengl.cc 2012-09-21 21:36:07 +0000
1667+++ src/graphic/render/gameview_opengl.cc 1970-01-01 00:00:00 +0000
1668@@ -1,104 +0,0 @@
1669-/*
1670- * Copyright (C) 2011-2012 by the Widelands Development Team
1671- *
1672- * This program is free software; you can redistribute it and/or
1673- * modify it under the terms of the GNU General Public License
1674- * as published by the Free Software Foundation; either version 2
1675- * of the License, or (at your option) any later version.
1676- *
1677- * This program is distributed in the hope that it will be useful,
1678- * but WITHOUT ANY WARRANTY; without even the implied warranty of
1679- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1680- * GNU General Public License for more details.
1681- *
1682- * You should have received a copy of the GNU General Public License
1683- * along with this program; if not, write to the Free Software
1684- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
1685- *
1686- */
1687-
1688-#ifdef USE_OPENGL
1689-
1690-#include "gameview_opengl.h"
1691-
1692-#include "constants.h"
1693-#include "economy/road.h"
1694-#include "graphic/graphic.h"
1695-#include "graphic/texture.h"
1696-
1697-#include "terrain_opengl.h"
1698-
1699-using namespace Widelands;
1700-
1701-/**
1702- * Draw ground textures and roads for the given parallelogram (two triangles)
1703- * into the bitmap.
1704- *
1705- * Vertices:
1706- * - f_vert vertex of the field
1707- * - r_vert vertex right of the field
1708- * - bl_vert vertex bottom left of the field
1709- * - br_vert vertex bottom right of the field
1710- *
1711- * Textures:
1712- * - f_r_texture Terrain of the triangle right of the field
1713- * - f_d_texture Terrain of the triangle under of the field
1714- * - tr_d_texture Terrain of the triangle top of the right triangle ??
1715- * - l_r_texture Terrain of the triangle left of the down triangle ??
1716- *
1717- * (tr_d)
1718- *
1719- * (f) *------* (r)
1720- * / \ r /
1721- * (l_r) / \ /
1722- * / d \/
1723- * (bl) *------* (br)
1724- */
1725-void GameViewOpenGL::draw_field
1726- (Rect & subwin,
1727- Vertex const & f_vert,
1728- Vertex const & r_vert,
1729- Vertex const & bl_vert,
1730- Vertex const & br_vert,
1731- uint8_t roads,
1732- Texture const & tr_d_texture,
1733- Texture const & l_r_texture,
1734- Texture const & f_d_texture,
1735- Texture const & f_r_texture)
1736-{
1737- // Draw triangle right (bottom) of the field
1738- draw_field_opengl
1739- (subwin, f_vert, br_vert, r_vert, f_r_texture, f_d_texture, tr_d_texture);
1740- // Draw triangle bottom of the field
1741- draw_field_opengl
1742- (subwin, f_vert, bl_vert, br_vert, f_d_texture, l_r_texture, f_d_texture);
1743-
1744- // Draw the roads
1745- draw_roads_opengl(subwin, roads, f_vert, r_vert, bl_vert, br_vert);
1746-}
1747-
1748-void GameViewOpenGL::rendermap_init()
1749-{
1750- glMatrixMode(GL_TEXTURE);
1751- glLoadIdentity();
1752- glScalef
1753- (1.0f / static_cast<GLfloat>(TEXTURE_WIDTH),
1754- 1.0f / static_cast<GLfloat>(TEXTURE_HEIGHT), 1);
1755- glDisable(GL_BLEND);
1756-
1757- // Use scissor test to clip the window. This takes coordinates in screen
1758- // coordinates (y goes from bottom to top)
1759- glScissor
1760- (m_rect.x, g_gr->get_yres() - m_rect.y - m_rect.h,
1761- m_rect.w, m_rect.h);
1762- glEnable(GL_SCISSOR_TEST);
1763-}
1764-
1765-void GameViewOpenGL::rendermap_deint()
1766-{
1767- glDisable(GL_SCISSOR_TEST);
1768- glMatrixMode(GL_TEXTURE);
1769- glLoadIdentity();
1770-}
1771-
1772-#endif
1773
1774=== removed file 'src/graphic/render/gameview_opengl.h'
1775--- src/graphic/render/gameview_opengl.h 2012-09-21 21:36:07 +0000
1776+++ src/graphic/render/gameview_opengl.h 1970-01-01 00:00:00 +0000
1777@@ -1,56 +0,0 @@
1778-/*
1779- * Copyright (C) 2011 by the Widelands Development Team
1780- *
1781- * This program is free software; you can redistribute it and/or
1782- * modify it under the terms of the GNU General Public License
1783- * as published by the Free Software Foundation; either version 2
1784- * of the License, or (at your option) any later version.
1785- *
1786- * This program is distributed in the hope that it will be useful,
1787- * but WITHOUT ANY WARRANTY; without even the implied warranty of
1788- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1789- * GNU General Public License for more details.
1790- *
1791- * You should have received a copy of the GNU General Public License
1792- * along with this program; if not, write to the Free Software
1793- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
1794- *
1795- */
1796-
1797-#ifdef USE_OPENGL
1798-#ifndef GAMEVIEW_OPENGL_H_
1799-#define GAMEVIEW_OPENGL_H_
1800-
1801-#include "gameview.h"
1802-
1803-class GameViewOpenGL : public GameView
1804-{
1805-public:
1806- GameViewOpenGL(RenderTarget & rt):
1807- GameView(rt) {}
1808- ~GameViewOpenGL() {}
1809-
1810-protected:
1811- /**
1812- * Helper function to draw two terrain triangles. This is called from the
1813- * rendermap() functions.
1814- */
1815- void draw_field
1816- (Rect & subwin,
1817- Vertex const & f_vert,
1818- Vertex const & r_vert,
1819- Vertex const & bl_vert,
1820- Vertex const & br_vert,
1821- uint8_t roads,
1822- Texture const & tr_d_texture,
1823- Texture const & l_r_texture,
1824- Texture const & f_d_texture,
1825- Texture const & f_r_texture);
1826-
1827- void rendermap_init();
1828- void rendermap_deint();
1829-};
1830-
1831-
1832-#endif /* GAMEVIEW_OPENGL_H_ */
1833-#endif /* USE_OPENGL */
1834
1835=== removed file 'src/graphic/render/gameview_sdl.cc'
1836--- src/graphic/render/gameview_sdl.cc 2012-12-07 20:25:12 +0000
1837+++ src/graphic/render/gameview_sdl.cc 1970-01-01 00:00:00 +0000
1838@@ -1,105 +0,0 @@
1839-/*
1840- * Copyright (C) 2011-2012 by the Widelands Development Team
1841- *
1842- * This program is free software; you can redistribute it and/or
1843- * modify it under the terms of the GNU General Public License
1844- * as published by the Free Software Foundation; either version 2
1845- * of the License, or (at your option) any later version.
1846- *
1847- * This program is distributed in the hope that it will be useful,
1848- * but WITHOUT ANY WARRANTY; without even the implied warranty of
1849- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1850- * GNU General Public License for more details.
1851- *
1852- * You should have received a copy of the GNU General Public License
1853- * along with this program; if not, write to the Free Software
1854- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
1855- *
1856- */
1857-
1858-#include "gameview_sdl.h"
1859-
1860-#include "upcast.h"
1861-
1862-#include "economy/road.h"
1863-#include "economy/flag.h"
1864-
1865-#include "wui/minimap.h"
1866-#include "wui/mapviewpixelconstants.h"
1867-
1868-#include "logic/field.h"
1869-#include "logic/map.h"
1870-#include "logic/player.h"
1871-
1872-#include "graphic/graphic.h"
1873-#include "graphic/rendertarget.h"
1874-#include "graphic/surface.h"
1875-#include "graphic/texture.h"
1876-
1877-#include "wui/overlay_manager.h"
1878-
1879-#include "terrain_sdl.h"
1880-
1881-
1882-/**
1883- * Draw ground textures and roads for the given parallelogram (two triangles)
1884- * into the bitmap.
1885- *
1886- * Vertices:
1887- * - f_vert vertex of the field
1888- * - r_vert vertex right of the field
1889- * - bl_vert vertex bottom left of the field
1890- * - br_vert vertex bottom right of the field
1891- *
1892- * Textures:
1893- * - f_r_texture Terrain of the triangle right of the field
1894- * - f_d_texture Terrain of the triangle under of the field
1895- * - tr_d_texture Terrain of the triangle top of the right triangle ??
1896- * - l_r_texture Terrain of the triangle left of the down triangle ??
1897- *
1898- * (tr_d)
1899- *
1900- * (f) *------* (r)
1901- * / \ r /
1902- * (l_r) / \ /
1903- * / d \/
1904- * (bl) *------* (br)
1905- */
1906-void GameViewSDL::draw_field
1907- (Rect & subwin,
1908- Vertex const & f_vert,
1909- Vertex const & r_vert,
1910- Vertex const & bl_vert,
1911- Vertex const & br_vert,
1912- uint8_t roads,
1913- Texture const & tr_d_texture,
1914- Texture const & l_r_texture,
1915- Texture const & f_d_texture,
1916- Texture const & f_r_texture)
1917-{
1918- upcast(SDLSurface, sdlsurf, m_surface);
1919- if (sdlsurf)
1920- {
1921- sdlsurf->set_subwin(subwin);
1922- switch (sdlsurf->format().BytesPerPixel) {
1923- case 2:
1924- draw_field_int<Uint16>
1925- (*sdlsurf,
1926- f_vert, r_vert, bl_vert, br_vert,
1927- roads,
1928- tr_d_texture, l_r_texture, f_d_texture, f_r_texture);
1929- break;
1930- case 4:
1931- draw_field_int<Uint32>
1932- (*sdlsurf,
1933- f_vert, r_vert, bl_vert, br_vert,
1934- roads,
1935- tr_d_texture, l_r_texture, f_d_texture, f_r_texture);
1936- break;
1937- default:
1938- assert(false);
1939- break;
1940- }
1941- sdlsurf->unset_subwin();
1942- }
1943-}
1944
1945=== removed file 'src/graphic/render/gameview_sdl.h'
1946--- src/graphic/render/gameview_sdl.h 2012-02-27 20:24:28 +0000
1947+++ src/graphic/render/gameview_sdl.h 1970-01-01 00:00:00 +0000
1948@@ -1,50 +0,0 @@
1949-/*
1950- * Copyright (C) 2011-2012 by the Widelands Development Team
1951- *
1952- * This program is free software; you can redistribute it and/or
1953- * modify it under the terms of the GNU General Public License
1954- * as published by the Free Software Foundation; either version 2
1955- * of the License, or (at your option) any later version.
1956- *
1957- * This program is distributed in the hope that it will be useful,
1958- * but WITHOUT ANY WARRANTY; without even the implied warranty of
1959- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1960- * GNU General Public License for more details.
1961- *
1962- * You should have received a copy of the GNU General Public License
1963- * along with this program; if not, write to the Free Software
1964- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
1965- *
1966- */
1967-
1968-#ifndef GAMEVIEW_SDL_H_
1969-#define GAMEVIEW_SDL_H_
1970-
1971-#include "gameview.h"
1972-
1973-class GameViewSDL : public GameView
1974-{
1975-public:
1976- GameViewSDL(RenderTarget & rt):
1977- GameView(rt) {}
1978- ~GameViewSDL() {}
1979-
1980-protected:
1981- /**
1982- * Helper function to draw two terrain triangles. This is called from the
1983- * rendermap() functions.
1984- */
1985- void draw_field
1986- (Rect & subwin,
1987- Vertex const & f_vert,
1988- Vertex const & r_vert,
1989- Vertex const & bl_vert,
1990- Vertex const & br_vert,
1991- uint8_t roads,
1992- Texture const & tr_d_texture,
1993- Texture const & l_r_texture,
1994- Texture const & f_d_texture,
1995- Texture const & f_r_texture);
1996-};
1997-
1998-#endif /* GAMEVIEW_SDL_H_ */
1999
2000=== modified file 'src/graphic/render/gl_surface_texture.cc'
2001--- src/graphic/render/gl_surface_texture.cc 2013-01-04 09:59:13 +0000
2002+++ src/graphic/render/gl_surface_texture.cc 2013-02-09 12:25:26 +0000
2003@@ -85,7 +85,7 @@
2004 *
2005 * \note Takes ownership of the given surface.
2006 */
2007-GLSurfaceTexture::GLSurfaceTexture(SDL_Surface * surface)
2008+GLSurfaceTexture::GLSurfaceTexture(SDL_Surface * surface, bool intensity)
2009 {
2010 init(surface->w, surface->h);
2011
2012@@ -166,7 +166,7 @@
2013 SDL_LockSurface(surface);
2014
2015 glTexImage2D
2016- (GL_TEXTURE_2D, 0, GL_RGBA, m_tex_w, m_tex_h, 0,
2017+ (GL_TEXTURE_2D, 0, intensity ? GL_INTENSITY : GL_RGBA, m_tex_w, m_tex_h, 0,
2018 pixels_format, GL_UNSIGNED_BYTE, surface->pixels);
2019
2020 SDL_UnlockSurface(surface);
2021
2022=== modified file 'src/graphic/render/gl_surface_texture.h'
2023--- src/graphic/render/gl_surface_texture.h 2012-12-15 18:40:59 +0000
2024+++ src/graphic/render/gl_surface_texture.h 2013-02-09 12:25:26 +0000
2025@@ -30,7 +30,7 @@
2026 static void Initialize();
2027 static void Cleanup();
2028
2029- GLSurfaceTexture(SDL_Surface * surface);
2030+ GLSurfaceTexture(SDL_Surface * surface, bool intensity = false);
2031 GLSurfaceTexture(int w, int h, bool alpha);
2032 virtual ~GLSurfaceTexture();
2033
2034
2035=== renamed file 'src/graphic/render/gameview.cc' => 'src/graphic/render/minimaprenderer.cc'
2036--- src/graphic/render/gameview.cc 2012-12-14 20:09:35 +0000
2037+++ src/graphic/render/minimaprenderer.cc 2013-02-09 12:25:26 +0000
2038@@ -1,5 +1,5 @@
2039 /*
2040- * Copyright (C) 2010-2012 by the Widelands Development Team
2041+ * Copyright (C) 2010-2013 by the Widelands Development Team
2042 *
2043 * This program is free software; you can redistribute it and/or
2044 * modify it under the terms of the GNU General Public License
2045@@ -17,7 +17,7 @@
2046 *
2047 */
2048
2049-#include "gameview.h"
2050+#include "minimaprenderer.h"
2051 #include "upcast.h"
2052
2053 #include "economy/road.h"
2054@@ -39,931 +39,7 @@
2055
2056 #include "terrain_sdl.h"
2057
2058-using Widelands::BaseImmovable;
2059-using Widelands::Coords;
2060-using Widelands::FCoords;
2061-using Widelands::Map;
2062-using Widelands::Map_Object_Descr;
2063-using Widelands::Player;
2064-using Widelands::TCoords;
2065-using namespace Widelands;
2066-
2067-///This is used by rendermap to calculate the brightness of the terrain.
2068-inline static Sint8 node_brightness
2069- (Widelands::Time const gametime,
2070- Widelands::Time const last_seen,
2071- Widelands::Vision const vision,
2072- int8_t result)
2073-{
2074- if (vision == 0)
2075- result = -128;
2076- else if (vision == 1) {
2077- assert(last_seen <= gametime);
2078- Widelands::Duration const time_ago = gametime - last_seen;
2079- result =
2080- static_cast<Sint16>
2081- (((static_cast<Sint16>(result) + 128) >> 1)
2082- *
2083- (1.0 + (time_ago < 45000 ? expf(-8.46126929e-5 * time_ago) : 0)))
2084- -
2085- 128;
2086- }
2087-
2088- return result;
2089-}
2090-
2091-
2092-#define RENDERMAP_INITIALIZATIONS \
2093- viewofs -= m_offset; \
2094- \
2095- Map const & map = egbase.map(); \
2096- Widelands::World const & world = map.world(); \
2097- Overlay_Manager const & overlay_manager = map.get_overlay_manager(); \
2098- uint32_t const mapwidth = map.get_width(); \
2099- int32_t minfx, minfy; \
2100- int32_t maxfx, maxfy; \
2101- \
2102- /* hack to prevent negative numbers */ \
2103- minfx = (viewofs.x + (TRIANGLE_WIDTH >> 1)) / TRIANGLE_WIDTH - 1; \
2104- \
2105- minfy = viewofs.y / TRIANGLE_HEIGHT; \
2106- maxfx = (viewofs.x + (TRIANGLE_WIDTH >> 1) + m_rect.w) / TRIANGLE_WIDTH; \
2107- maxfy = (viewofs.y + m_rect.h) / TRIANGLE_HEIGHT; \
2108- maxfx += 1; /* because of big buildings */ \
2109- maxfy += 10; /* because of heights */ \
2110- \
2111- int32_t dx = maxfx - minfx + 1; \
2112- int32_t dy = maxfy - minfy + 1; \
2113- int32_t linear_fy = minfy; \
2114- bool row_is_forward = linear_fy & 1; \
2115- int32_t b_posy = linear_fy * TRIANGLE_HEIGHT - viewofs.y; \
2116-
2117-
2118-/**
2119- * Loop through fields row by row. For each field, draw ground textures, then
2120- * roads, then immovables, then bobs, then overlay stuff (build icons etc...)
2121- */
2122-void GameView::rendermap
2123- (Widelands::Editor_Game_Base const & egbase,
2124- Widelands::Player const & player,
2125- Point viewofs)
2126-{
2127- m_surface->fill_rect(m_rect, RGBAColor(0, 0, 0, 255));
2128-
2129- if (player.see_all())
2130- return rendermap(egbase, viewofs);
2131-
2132- RENDERMAP_INITIALIZATIONS;
2133-
2134- const Player::Field * const first_player_field = player.fields();
2135- Widelands::Time const gametime = egbase.get_gametime();
2136-
2137- rendermap_init();
2138-
2139- while (dy--) {
2140- const int32_t posy = b_posy;
2141- b_posy += TRIANGLE_HEIGHT;
2142- const int32_t linear_fx = minfx;
2143- FCoords r(Coords(linear_fx, linear_fy));
2144- FCoords br(Coords(linear_fx - not row_is_forward, linear_fy + 1));
2145- int32_t r_posx =
2146- r.x * TRIANGLE_WIDTH
2147- +
2148- row_is_forward * (TRIANGLE_WIDTH / 2)
2149- -
2150- viewofs.x;
2151- int32_t br_posx = r_posx - TRIANGLE_WIDTH / 2;
2152-
2153- // Calculate safe (bounded) field coordinates and get field pointers
2154- map.normalize_coords(r);
2155- map.normalize_coords(br);
2156- Widelands::Map_Index r_index = Map::get_index (r, mapwidth);
2157- r.field = &map[r_index];
2158- Widelands::Map_Index br_index = Map::get_index(br, mapwidth);
2159- br.field = &map[br_index];
2160- const Player::Field * r_player_field = first_player_field + r_index;
2161- const Player::Field * br_player_field = first_player_field + br_index;
2162- FCoords tr, f;
2163- map.get_tln(r, &tr);
2164- map.get_ln(r, &f);
2165- Widelands::Map_Index tr_index = tr.field - &map[0];
2166- const Texture * f_r_texture =
2167- g_gr->get_maptexture_data
2168- (world
2169- .terrain_descr(first_player_field[f.field - &map[0]].terrains.r)
2170- .get_texture());
2171-
2172- uint32_t count = dx;
2173-
2174- while (count--) {
2175- const FCoords bl = br;
2176- const Player::Field & f_player_field = *r_player_field;
2177- const Player::Field & bl_player_field = *br_player_field;
2178- f = r;
2179- const int32_t f_posx = r_posx, bl_posx = br_posx;
2180- const Texture & l_r_texture = *f_r_texture;
2181- move_r(mapwidth, tr, tr_index);
2182- move_r(mapwidth, r, r_index);
2183- move_r(mapwidth, br, br_index);
2184- r_player_field = first_player_field + r_index;
2185- br_player_field = first_player_field + br_index;
2186- r_posx += TRIANGLE_WIDTH;
2187- br_posx += TRIANGLE_WIDTH;
2188- const Texture & tr_d_texture =
2189- *g_gr->get_maptexture_data
2190- (world.terrain_descr(first_player_field[tr_index].terrains.d).get_texture());
2191- const Texture & f_d_texture =
2192- *g_gr->get_maptexture_data(world.terrain_descr(f_player_field.terrains.d).get_texture());
2193- f_r_texture =
2194- g_gr->get_maptexture_data(world.terrain_descr(f_player_field.terrains.r).get_texture());
2195-
2196- uint8_t const roads =
2197- f_player_field.roads | overlay_manager.get_road_overlay(f);
2198-
2199- Vertex f_vert
2200- (f_posx, posy - f.field->get_height() * HEIGHT_FACTOR,
2201- node_brightness
2202- (gametime, f_player_field.time_node_last_unseen,
2203- f_player_field.vision, f.field->get_brightness()),
2204- 0, 0);
2205- Vertex r_vert
2206- (r_posx, posy - r.field->get_height() * HEIGHT_FACTOR,
2207- node_brightness
2208- (gametime, r_player_field->time_node_last_unseen,
2209- r_player_field->vision, r.field->get_brightness()),
2210- TRIANGLE_WIDTH, 0);
2211- Vertex bl_vert
2212- (bl_posx, b_posy - bl.field->get_height() * HEIGHT_FACTOR,
2213- node_brightness
2214- (gametime, bl_player_field.time_node_last_unseen,
2215- bl_player_field.vision, bl.field->get_brightness()),
2216- 0, 64);
2217- Vertex br_vert
2218- (br_posx, b_posy - br.field->get_height() * HEIGHT_FACTOR,
2219- node_brightness
2220- (gametime, br_player_field->time_node_last_unseen,
2221- br_player_field->vision, br.field->get_brightness()),
2222- TRIANGLE_WIDTH, 64);
2223-
2224- if (row_is_forward) {
2225- f_vert.tx += TRIANGLE_WIDTH / 2;
2226- r_vert.tx += TRIANGLE_WIDTH / 2;
2227- } else {
2228- f_vert.tx += TRIANGLE_WIDTH;
2229- r_vert.tx += TRIANGLE_WIDTH;
2230- bl_vert.tx += TRIANGLE_WIDTH / 2;
2231- br_vert.tx += TRIANGLE_WIDTH / 2;
2232- }
2233-
2234- draw_field // Render ground
2235- (m_rect,
2236- f_vert, r_vert, bl_vert, br_vert,
2237- roads,
2238- tr_d_texture, l_r_texture, f_d_texture, *f_r_texture);
2239- }
2240-
2241- ++linear_fy;
2242- row_is_forward = not row_is_forward;
2243- }
2244-
2245- {
2246- const int32_t dx2 = maxfx - minfx + 1;
2247- int32_t dy2 = maxfy - minfy + 1;
2248- int32_t linear_fy2 = minfy;
2249- bool row_is_forward2 = linear_fy2 & 1;
2250- int32_t b_posy2 = linear_fy2 * TRIANGLE_HEIGHT - viewofs.y - m_offset.y;
2251-
2252- while (dy2--) {
2253- const int32_t posy = b_posy2;
2254- b_posy2 += TRIANGLE_HEIGHT;
2255-
2256- { // Draw things on the node.
2257- const int32_t linear_fx = minfx;
2258- FCoords r (Coords(linear_fx, linear_fy2));
2259- FCoords br(Coords(linear_fx - not row_is_forward2, linear_fy2 + 1));
2260-
2261- // Calculate safe (bounded) field coordinates and get field pointers.
2262- map.normalize_coords(r);
2263- map.normalize_coords(br);
2264- Widelands::Map_Index r_index = Map::get_index (r, mapwidth);
2265- r.field = &map[r_index];
2266- Widelands::Map_Index br_index = Map::get_index(br, mapwidth);
2267- br.field = &map[br_index];
2268- FCoords tr, f;
2269- map.get_tln(r, &tr);
2270- map.get_ln(r, &f);
2271- bool r_is_border;
2272- uint8_t f_owner_number = f.field->get_owned_by(); // do not use if f_vision < 1 -> PPOV
2273- uint8_t r_owner_number;
2274- r_is_border = r.field->is_border(); // do not use if f_vision < 1 -> PPOV
2275- r_owner_number = r.field->get_owned_by(); // do not use if f_vision < 1 -> PPOV
2276- uint8_t br_owner_number = br.field->get_owned_by(); // do not use if f_vision < 1 -> PPOV
2277- Player::Field const * r_player_field = first_player_field + r_index;
2278- const Player::Field * br_player_field = first_player_field + br_index;
2279- Widelands::Vision r_vision = r_player_field->vision;
2280- Widelands::Vision br_vision = br_player_field->vision;
2281- Point r_pos
2282- (linear_fx * TRIANGLE_WIDTH
2283- +
2284- row_is_forward2 * (TRIANGLE_WIDTH / 2)
2285- -
2286- viewofs.x - m_offset.x,
2287- posy - r.field->get_height() * HEIGHT_FACTOR);
2288- Point br_pos
2289- (r_pos.x - TRIANGLE_WIDTH / 2,
2290- b_posy2 - br.field->get_height() * HEIGHT_FACTOR);
2291-
2292- int32_t count = dx2;
2293-
2294- while (count--) {
2295- f = r;
2296- const Player::Field & f_player_field = *r_player_field;
2297- move_r(mapwidth, tr);
2298- move_r(mapwidth, r, r_index);
2299- move_r(mapwidth, br, br_index);
2300- r_player_field = first_player_field + r_index;
2301- br_player_field = first_player_field + br_index;
2302-
2303- // do not use if f_vision < 1 -> PPOV
2304- const uint8_t tr_owner_number = tr.field->get_owned_by();
2305-
2306- const bool f_is_border = r_is_border;
2307- const uint8_t l_owner_number = f_owner_number;
2308- const uint8_t bl_owner_number = br_owner_number;
2309- f_owner_number = r_owner_number;
2310- r_is_border = r.field->is_border(); // do not use if f_vision < 1 -> PPOV
2311- r_owner_number = r.field->get_owned_by(); // do not use if f_vision < 1 -> PPOV
2312- br_owner_number = br.field->get_owned_by(); // do not use if f_vision < 1 -> PPOV
2313- Widelands::Vision const f_vision = r_vision;
2314- Widelands::Vision const bl_vision = br_vision;
2315- r_vision = player.vision (r_index);
2316- br_vision = player.vision(br_index);
2317- const Point f_pos = r_pos, bl_pos = br_pos;
2318- r_pos = Point(r_pos.x + TRIANGLE_WIDTH, posy - r.field->get_height() * HEIGHT_FACTOR);
2319- br_pos = Point(br_pos.x + TRIANGLE_WIDTH, b_posy2 - br.field->get_height() * HEIGHT_FACTOR);
2320-
2321- if (1 < f_vision) { // Render stuff that belongs to the node.
2322- // Render border markes on and halfway between border nodes.
2323- if (f_is_border) {
2324- const Player & owner = egbase.player(f_owner_number);
2325- uint32_t const anim = owner.frontier_anim();
2326- drawanim(f_pos, anim, 0, &owner);
2327- if
2328- ((f_vision | r_vision)
2329- and
2330- r_owner_number == f_owner_number
2331- and
2332- ((tr_owner_number == f_owner_number)
2333- xor
2334- (br_owner_number == f_owner_number)))
2335- drawanim(middle(f_pos, r_pos), anim, 0, &owner);
2336- if
2337- ((f_vision | bl_vision)
2338- and
2339- bl_owner_number == f_owner_number
2340- and
2341- ((l_owner_number == f_owner_number)
2342- xor
2343- (br_owner_number == f_owner_number)))
2344- drawanim(middle(f_pos, bl_pos), anim, 0, &owner);
2345- if
2346- ((f_vision | br_vision)
2347- and
2348- br_owner_number == f_owner_number
2349- and
2350- ((r_owner_number == f_owner_number)
2351- xor
2352- (bl_owner_number == f_owner_number)))
2353- drawanim(middle(f_pos, br_pos), anim, 0, &owner);
2354- }
2355-
2356-
2357- // Render bobs
2358- // TODO - rendering order?
2359- // This must be defined somehow. Some bobs have a higher
2360- // priority than others. Maybe this priority is a moving
2361- // versus non-moving bobs thing? draw_ground implies that
2362- // this doesn't render map objects. Are there any overdraw
2363- // issues with the current rendering order?
2364-
2365- // Draw Map_Objects hooked to this field
2366- if (BaseImmovable * const imm = f.field->get_immovable())
2367- imm->draw(egbase, *this, f, f_pos);
2368- for
2369- (Widelands::Bob * bob = f.field->get_first_bob();
2370- bob;
2371- bob = bob->get_next_bob())
2372- bob->draw(egbase, *this, f_pos);
2373-
2374- // Render overlays on nodes.
2375- Overlay_Manager::Overlay_Info
2376- overlay_info[MAX_OVERLAYS_PER_NODE];
2377-
2378- const Overlay_Manager::Overlay_Info * const end =
2379- overlay_info
2380- +
2381- overlay_manager.get_overlays(f, overlay_info);
2382-
2383- for
2384- (const Overlay_Manager::Overlay_Info * it = overlay_info;
2385- it < end;
2386- ++it)
2387- blit(f_pos - it->hotspot, it->pic);
2388- } else if (f_vision == 1) {
2389- const Player * owner = f_player_field.owner ? egbase.get_player(f_player_field.owner) : 0;
2390- if (owner) {
2391- // Draw borders as they stood the last time we saw them
2392- uint32_t const anim = owner->frontier_anim();
2393- if (f_player_field.border)
2394- drawanim(f_pos, anim, 0, owner);
2395- if (f_player_field.border_r)
2396- drawanim(middle(f_pos, r_pos), anim, 0, owner);
2397- if (f_player_field.border_br)
2398- drawanim(middle(f_pos, bl_pos), anim, 0, owner);
2399- if (f_player_field.border_bl)
2400- drawanim(middle(f_pos, br_pos), anim, 0, owner);
2401- }
2402- if
2403- (const Map_Object_Descr * const map_object_descr =
2404- f_player_field.map_object_descr[TCoords<>::None])
2405- {
2406- if
2407- (const Player::Constructionsite_Information * const csinf =
2408- f_player_field.constructionsite[TCoords<>::None])
2409- {
2410- // draw the partly finished constructionsite
2411- uint32_t anim;
2412- try {
2413- anim = csinf->becomes->get_animation("build");
2414- } catch (Map_Object_Descr::Animation_Nonexistent & e) {
2415- try {
2416- anim = csinf->becomes->get_animation("unoccupied");
2417- } catch (Map_Object_Descr::Animation_Nonexistent) {
2418- anim = csinf->becomes->get_animation("idle");
2419- }
2420- }
2421- const AnimationGfx::Index nr_frames = g_gr->nr_frames(anim);
2422- uint32_t cur_frame =
2423- csinf->totaltime ? csinf->completedtime * nr_frames / csinf->totaltime : 0;
2424- uint32_t tanim = cur_frame * FRAME_LENGTH;
2425- uint32_t w, h;
2426- g_gr->get_animation_size(anim, tanim, w, h);
2427- uint32_t lines = h * csinf->completedtime * nr_frames;
2428- if (csinf->totaltime)
2429- lines /= csinf->totaltime;
2430- assert(h * cur_frame <= lines);
2431- lines -= h * cur_frame; // This won't work if pictures have various sizes.
2432-
2433- if (cur_frame) // not the first frame
2434- // draw the prev frame from top to where next image will be drawing
2435- drawanimrect
2436- (f_pos, anim, tanim - FRAME_LENGTH, owner, Rect(Point(0, 0), w, h - lines));
2437- else if (csinf->was) {
2438- // Is the first frame, but there was another building here before,
2439- // get its last build picture and draw it instead.
2440- uint32_t a;
2441- try {
2442- a = csinf->was->get_animation("unoccupied");
2443- } catch (Map_Object_Descr::Animation_Nonexistent & e) {
2444- a = csinf->was->get_animation("idle");
2445- }
2446- drawanimrect
2447- (f_pos, a, tanim - FRAME_LENGTH, owner, Rect(Point(0, 0), w, h - lines));
2448- }
2449- assert(lines <= h);
2450- drawanimrect(f_pos, anim, tanim, owner, Rect(Point(0, h - lines), w, lines));
2451- } else if (upcast(const Building_Descr, building, map_object_descr)) {
2452- // this is a building therefore we either draw unoccupied or idle animation
2453- uint32_t pic;
2454- try {
2455- pic = building->get_animation("unoccupied");
2456- } catch (Map_Object_Descr::Animation_Nonexistent & e) {
2457- pic = building->get_animation("idle");
2458- }
2459- drawanim(f_pos, pic, 0, owner);
2460- } else if (const uint32_t pic = map_object_descr->main_animation()) {
2461- drawanim(f_pos, pic, 0, owner);
2462- } else if (map_object_descr == &Widelands::g_flag_descr) {
2463- drawanim(f_pos, owner->flag_anim(), 0, owner);
2464- }
2465- }
2466- }
2467- }
2468- }
2469-
2470- if (false) { // Draw things on the R-triangle (nothing to draw yet).
2471- const int32_t linear_fx = minfx;
2472- FCoords r(Coords(linear_fx, linear_fy2));
2473- FCoords b(Coords(linear_fx - not row_is_forward2, linear_fy2 + 1));
2474- int32_t posx =
2475- (linear_fx - 1) * TRIANGLE_WIDTH
2476- +
2477- (row_is_forward2 + 1) * (TRIANGLE_WIDTH / 2)
2478- -
2479- viewofs.x;
2480-
2481- // Calculate safe (bounded) field coordinates.
2482- map.normalize_coords(r);
2483- map.normalize_coords(b);
2484-
2485- // Get field pointers.
2486- r.field = &map[Map::get_index(r, mapwidth)];
2487- b.field = &map[Map::get_index(b, mapwidth)];
2488-
2489- int32_t count = dx2;
2490-
2491- // One less iteration than for nodes and D-triangles.
2492- while (--count) {
2493- const FCoords f = r;
2494- map.get_rn(r, &r);
2495- map.get_rn(b, &b);
2496- posx += TRIANGLE_WIDTH;
2497-
2498- // FIXME Implement visibility rules for objects on triangles
2499- // FIXME when they are used in the game. The only things that
2500- // FIXME are drawn on triangles now (except the ground) are
2501- // FIXME overlays for the editor terrain tool, and the editor
2502- // FIXME does not need visibility rules.
2503- { // FIXME Visibility check here.
2504- Overlay_Manager::Overlay_Info overlay_info
2505- [MAX_OVERLAYS_PER_TRIANGLE];
2506- const Overlay_Manager::Overlay_Info & overlay_info_end = *
2507- (overlay_info
2508- +
2509- overlay_manager.get_overlays
2510- (TCoords<>(f, TCoords<>::R), overlay_info));
2511-
2512- for
2513- (const Overlay_Manager::Overlay_Info * it = overlay_info;
2514- it < &overlay_info_end;
2515- ++it)
2516- blit
2517- (Point
2518- (posx,
2519- posy
2520- +
2521- (TRIANGLE_HEIGHT
2522- -
2523- (f.field->get_height()
2524- +
2525- r.field->get_height()
2526- +
2527- b.field->get_height())
2528- *
2529- HEIGHT_FACTOR)
2530- /
2531- 3)
2532- -
2533- it->hotspot,
2534- it->pic);
2535- }
2536- }
2537- }
2538-
2539- if (false) { // Draw things on the D-triangle (nothing to draw yet).
2540- const int32_t linear_fx = minfx;
2541- FCoords f(Coords(linear_fx - 1, linear_fy2));
2542- FCoords br
2543- (Coords(linear_fx - not row_is_forward2, linear_fy2 + 1));
2544- int32_t posx =
2545- (linear_fx - 1) * TRIANGLE_WIDTH
2546- +
2547- row_is_forward2 * (TRIANGLE_WIDTH / 2)
2548- -
2549- viewofs.x;
2550-
2551- // Calculate safe (bounded) field coordinates.
2552- map.normalize_coords(f);
2553- map.normalize_coords(br);
2554-
2555- // Get field pointers.
2556- f.field = &map[Map::get_index(f, mapwidth)];
2557- br.field = &map[Map::get_index(br, mapwidth)];
2558-
2559- int32_t count = dx2;
2560-
2561- while (count--) {
2562- const FCoords bl = br;
2563- map.get_rn(f, &f);
2564- map.get_rn(br, &br);
2565- posx += TRIANGLE_WIDTH;
2566-
2567- { // FIXME Visibility check here.
2568- Overlay_Manager::Overlay_Info overlay_info
2569- [MAX_OVERLAYS_PER_TRIANGLE];
2570- Overlay_Manager::Overlay_Info const * const overlay_info_end
2571- =
2572- overlay_info
2573- +
2574- overlay_manager.get_overlays
2575- (TCoords<>(f, TCoords<>::D), overlay_info);
2576-
2577- for
2578- (const Overlay_Manager::Overlay_Info * it = overlay_info;
2579- it < overlay_info_end;
2580- ++it)
2581- blit
2582- (Point
2583- (posx,
2584- posy
2585- +
2586- ((TRIANGLE_HEIGHT * 2)
2587- -
2588- (f.field->get_height()
2589- +
2590- bl.field->get_height()
2591- +
2592- br.field->get_height())
2593- *
2594- HEIGHT_FACTOR)
2595- /
2596- 3)
2597- -
2598- it->hotspot,
2599- it->pic);
2600- }
2601- }
2602- }
2603-
2604- ++linear_fy2;
2605- row_is_forward2 = not row_is_forward2;
2606- }
2607- }
2608-
2609- rendermap_deint();
2610-
2611- g_gr->reset_texture_animation_reminder();
2612-}
2613-
2614-void GameView::rendermap
2615- (Widelands::Editor_Game_Base const & egbase,
2616- Point viewofs)
2617-{
2618- RENDERMAP_INITIALIZATIONS;
2619-
2620- rendermap_init();
2621-
2622- while (dy--) {
2623- const int32_t posy = b_posy;
2624- b_posy += TRIANGLE_HEIGHT;
2625- const int32_t linear_fx = minfx;
2626- FCoords r(Coords(linear_fx, linear_fy));
2627- FCoords br(Coords(linear_fx - not row_is_forward, linear_fy + 1));
2628- int32_t r_posx =
2629- r.x * TRIANGLE_WIDTH
2630- +
2631- row_is_forward * (TRIANGLE_WIDTH / 2)
2632- -
2633- viewofs.x;
2634- int32_t br_posx = r_posx - TRIANGLE_WIDTH / 2;
2635-
2636- // Calculate safe (bounded) field coordinates and get field pointers
2637- map.normalize_coords(r);
2638- map.normalize_coords(br);
2639- Widelands::Map_Index r_index = Map::get_index (r, mapwidth);
2640- r.field = &map[r_index];
2641- Widelands::Map_Index br_index = Map::get_index(br, mapwidth);
2642- br.field = &map[br_index];
2643- FCoords tr, f;
2644- map.get_tln(r, &tr);
2645- map.get_ln(r, &f);
2646- const Texture * f_r_texture =
2647- g_gr->get_maptexture_data
2648- (world.terrain_descr(f.field->terrain_r()).get_texture());
2649-
2650- uint32_t count = dx;
2651-
2652- while (count--) {
2653- const FCoords bl = br;
2654- f = r;
2655- const int32_t f_posx = r_posx, bl_posx = br_posx;
2656- const Texture & l_r_texture = *f_r_texture;
2657- move_r(mapwidth, tr);
2658- move_r(mapwidth, r, r_index);
2659- move_r(mapwidth, br, br_index);
2660- r_posx += TRIANGLE_WIDTH;
2661- br_posx += TRIANGLE_WIDTH;
2662- const Texture & tr_d_texture =
2663- *g_gr->get_maptexture_data
2664- (world.terrain_descr(tr.field->terrain_d()).get_texture());
2665- const Texture & f_d_texture =
2666- *g_gr->get_maptexture_data
2667- (world.terrain_descr(f.field->terrain_d()).get_texture());
2668- f_r_texture =
2669- g_gr->get_maptexture_data
2670- (world.terrain_descr(f.field->terrain_r()).get_texture());
2671-
2672- const uint8_t roads =
2673- f.field->get_roads() | overlay_manager.get_road_overlay(f);
2674-
2675- Vertex f_vert
2676- (f_posx, posy - f.field->get_height() * HEIGHT_FACTOR,
2677- f.field->get_brightness(),
2678- 0, 0);
2679- Vertex r_vert
2680- (r_posx, posy - r.field->get_height() * HEIGHT_FACTOR,
2681- r.field->get_brightness(),
2682- TRIANGLE_WIDTH, 0);
2683- Vertex bl_vert
2684- (bl_posx, b_posy - bl.field->get_height() * HEIGHT_FACTOR,
2685- bl.field->get_brightness(),
2686- 0, 64);
2687- Vertex br_vert
2688- (br_posx, b_posy - br.field->get_height() * HEIGHT_FACTOR,
2689- br.field->get_brightness(),
2690- TRIANGLE_WIDTH, 64);
2691-
2692- if (row_is_forward) {
2693- f_vert.tx += TRIANGLE_WIDTH / 2;
2694- r_vert.tx += TRIANGLE_WIDTH / 2;
2695- } else {
2696- bl_vert.tx -= TRIANGLE_WIDTH / 2;
2697- br_vert.tx -= TRIANGLE_WIDTH / 2;
2698- }
2699-
2700- draw_field // Render ground
2701- (m_rect,
2702- f_vert, r_vert, bl_vert, br_vert,
2703- roads,
2704- tr_d_texture, l_r_texture, f_d_texture, *f_r_texture);
2705- }
2706-
2707- ++linear_fy;
2708- row_is_forward = not row_is_forward;
2709- }
2710-
2711- {
2712- const int32_t dx2 = maxfx - minfx + 1;
2713- int32_t dy2 = maxfy - minfy + 1;
2714- int32_t linear_fy2 = minfy;
2715- bool row_is_forward2 = linear_fy2 & 1;
2716- int32_t b_posy2 = linear_fy2 * TRIANGLE_HEIGHT - viewofs.y;
2717-
2718- while (dy2--) {
2719- const int32_t posy = b_posy2;
2720- b_posy2 += TRIANGLE_HEIGHT;
2721-
2722- { // Draw things on the node.
2723- const int32_t linear_fx = minfx;
2724- FCoords r(Coords(linear_fx, linear_fy2));
2725- FCoords br
2726- (Coords(linear_fx - not row_is_forward2, linear_fy2 + 1));
2727-
2728- // Calculate safe (bounded) field coordinates and get field
2729- // pointers.
2730- map.normalize_coords(r);
2731- map.normalize_coords(br);
2732- Widelands::Map_Index r_index = Map::get_index (r, mapwidth);
2733- r.field = &map[r_index];
2734- Widelands::Map_Index br_index = Map::get_index(br, mapwidth);
2735- br.field = &map[br_index];
2736- FCoords tr, f;
2737- map.get_tln(r, &tr);
2738- map.get_ln(r, &f);
2739- bool r_is_border;
2740- uint8_t f_owner_number = f.field->get_owned_by();
2741- uint8_t r_owner_number;
2742- r_is_border = r.field->is_border();
2743- r_owner_number = r.field->get_owned_by();
2744- uint8_t br_owner_number = br.field->get_owned_by();
2745- Point r_pos
2746- (linear_fx * TRIANGLE_WIDTH
2747- +
2748- row_is_forward2 * (TRIANGLE_WIDTH / 2)
2749- -
2750- viewofs.x,
2751- posy - r.field->get_height() * HEIGHT_FACTOR);
2752- Point br_pos
2753- (r_pos.x - TRIANGLE_WIDTH / 2,
2754- b_posy2 - br.field->get_height() * HEIGHT_FACTOR);
2755-
2756- int32_t count = dx2;
2757-
2758- while (count--) {
2759- f = r;
2760- move_r(mapwidth, tr);
2761- move_r(mapwidth, r, r_index);
2762- move_r(mapwidth, br, br_index);
2763- const uint8_t tr_owner_number = tr.field->get_owned_by();
2764- const bool f_is_border = r_is_border;
2765- const uint8_t l_owner_number = f_owner_number;
2766- const uint8_t bl_owner_number = br_owner_number;
2767- f_owner_number = r_owner_number;
2768- r_is_border = r.field->is_border();
2769- r_owner_number = r.field->get_owned_by();
2770- br_owner_number = br.field->get_owned_by();
2771- const Point f_pos = r_pos, bl_pos = br_pos;
2772- r_pos = Point
2773- (r_pos.x + TRIANGLE_WIDTH,
2774- posy - r.field->get_height() * HEIGHT_FACTOR);
2775- br_pos = Point
2776- (br_pos.x + TRIANGLE_WIDTH,
2777- b_posy2 - br.field->get_height() * HEIGHT_FACTOR);
2778-
2779- // Render border markes on and halfway between border nodes.
2780- if (f_is_border) {
2781- const Player & owner = egbase.player(f_owner_number);
2782- uint32_t const anim = owner.frontier_anim();
2783- drawanim(f_pos, anim, 0, &owner);
2784- if
2785- (r_owner_number == f_owner_number
2786- and
2787- ((tr_owner_number == f_owner_number)
2788- xor
2789- (br_owner_number == f_owner_number)))
2790- drawanim(middle(f_pos, r_pos), anim, 0, &owner);
2791- if
2792- (bl_owner_number == f_owner_number
2793- and
2794- ((l_owner_number == f_owner_number)
2795- xor
2796- (br_owner_number == f_owner_number)))
2797- drawanim(middle(f_pos, bl_pos), anim, 0, &owner);
2798- if
2799- (br_owner_number == f_owner_number
2800- and
2801- ((r_owner_number == f_owner_number)
2802- xor
2803- (bl_owner_number == f_owner_number)))
2804- drawanim(middle(f_pos, br_pos), anim, 0, &owner);
2805- }
2806-
2807- { // Render stuff that belongs to the node.
2808-
2809- // Render bobs
2810- // TODO - rendering order?
2811- // This must be defined somehow. Some bobs have a higher
2812- // priority than others. Maybe this priority is a moving
2813- // versus non-moving bobs thing? draw_ground implies that
2814- // this doesn't render map objects. Are there any overdraw
2815- // issues with the current rendering order?
2816-
2817- // Draw Map_Objects hooked to this field
2818- if (BaseImmovable * const imm = f.field->get_immovable())
2819- imm->draw(egbase, *this, f, f_pos);
2820- for
2821- (Widelands::Bob * bob = f.field->get_first_bob();
2822- bob;
2823- bob = bob->get_next_bob())
2824- bob->draw(egbase, *this, f_pos);
2825-
2826- // Render overlays on nodes.
2827- Overlay_Manager::Overlay_Info
2828- overlay_info[MAX_OVERLAYS_PER_NODE];
2829-
2830- const Overlay_Manager::Overlay_Info * const end =
2831- overlay_info
2832- +
2833- overlay_manager.get_overlays(f, overlay_info);
2834-
2835- for
2836- (const Overlay_Manager::Overlay_Info * it = overlay_info;
2837- it < end;
2838- ++it)
2839- blit(f_pos - it->hotspot, it->pic);
2840- }
2841- }
2842- }
2843-
2844- { // Draw things on the R-triangle.
2845- const int32_t linear_fx = minfx;
2846- FCoords r(Coords(linear_fx, linear_fy2));
2847- FCoords b
2848- (Coords(linear_fx - not row_is_forward2, linear_fy2 + 1));
2849- int32_t posx =
2850- (linear_fx - 1) * TRIANGLE_WIDTH
2851- +
2852- (row_is_forward2 + 1) * (TRIANGLE_WIDTH / 2)
2853- -
2854- viewofs.x;
2855-
2856- // Calculate safe (bounded) field coordinates.
2857- map.normalize_coords(r);
2858- map.normalize_coords(b);
2859-
2860- // Get field pointers.
2861- r.field = &map[Map::get_index(r, mapwidth)];
2862- b.field = &map[Map::get_index(b, mapwidth)];
2863-
2864- int32_t count = dx2;
2865-
2866- // One less iteration than for nodes and D-triangles.
2867- while (--count) {
2868- const FCoords f = r;
2869- map.get_rn(r, &r);
2870- map.get_rn(b, &b);
2871- posx += TRIANGLE_WIDTH;
2872-
2873- {
2874- Overlay_Manager::Overlay_Info overlay_info
2875- [MAX_OVERLAYS_PER_TRIANGLE];
2876- Overlay_Manager::Overlay_Info const & overlay_info_end =
2877- *
2878- (overlay_info
2879- +
2880- overlay_manager.get_overlays
2881- (TCoords<>(f, TCoords<>::R), overlay_info));
2882-
2883- for
2884- (Overlay_Manager::Overlay_Info const * it = overlay_info;
2885- it < &overlay_info_end;
2886- ++it)
2887- blit
2888- (Point
2889- (posx,
2890- posy
2891- +
2892- (TRIANGLE_HEIGHT
2893- -
2894- (f.field->get_height()
2895- +
2896- r.field->get_height()
2897- +
2898- b.field->get_height())
2899- *
2900- HEIGHT_FACTOR)
2901- /
2902- 3)
2903- -
2904- it->hotspot,
2905- it->pic);
2906- }
2907- }
2908- }
2909-
2910- { // Draw things on the D-triangle.
2911- const int32_t linear_fx = minfx;
2912- FCoords f(Coords(linear_fx - 1, linear_fy2));
2913- FCoords br(Coords(linear_fx - not row_is_forward2, linear_fy2 + 1));
2914- int32_t posx =
2915- (linear_fx - 1) * TRIANGLE_WIDTH
2916- +
2917- row_is_forward2 * (TRIANGLE_WIDTH / 2)
2918- -
2919- viewofs.x;
2920-
2921- // Calculate safe (bounded) field coordinates.
2922- map.normalize_coords(f);
2923- map.normalize_coords(br);
2924-
2925- // Get field pointers.
2926- f.field = &map[Map::get_index(f, mapwidth)];
2927- br.field = &map[Map::get_index(br, mapwidth)];
2928-
2929- int32_t count = dx2;
2930-
2931- while (count--) {
2932- const FCoords bl = br;
2933- map.get_rn(f, &f);
2934- map.get_rn(br, &br);
2935- posx += TRIANGLE_WIDTH;
2936-
2937- {
2938- Overlay_Manager::Overlay_Info overlay_info
2939- [MAX_OVERLAYS_PER_TRIANGLE];
2940- const Overlay_Manager::Overlay_Info & overlay_info_end = *
2941- (overlay_info
2942- +
2943- overlay_manager.get_overlays
2944- (TCoords<>(f, TCoords<>::D), overlay_info));
2945-
2946- for
2947- (const Overlay_Manager::Overlay_Info * it = overlay_info;
2948- it < &overlay_info_end;
2949- ++it)
2950- blit
2951- (Point
2952- (posx,
2953- posy
2954- +
2955- ((TRIANGLE_HEIGHT * 2)
2956- -
2957- (f.field->get_height()
2958- +
2959- bl.field->get_height()
2960- +
2961- br.field->get_height())
2962- *
2963- HEIGHT_FACTOR)
2964- /
2965- 3)
2966- -
2967- it->hotspot,
2968- it->pic);
2969- }
2970- }
2971- }
2972-
2973- ++linear_fy2;
2974- row_is_forward2 = not row_is_forward2;
2975- }
2976- }
2977-
2978- rendermap_deint();
2979-
2980- g_gr->reset_texture_animation_reminder();
2981-}
2982-
2983+using namespace Widelands;
2984
2985 /**
2986 * Renders a minimap into the current window. The field at viewpoint will be
2987@@ -973,7 +49,7 @@
2988 * Calculate the field at the top-left corner of the clipping rect
2989 * The entire clipping rect will be used for drawing.
2990 */
2991-void GameView::renderminimap
2992+void MiniMapRenderer::renderminimap
2993 (Widelands::Editor_Game_Base const & egbase,
2994 Player const * const player,
2995 Point const viewpoint,
2996@@ -986,47 +62,6 @@
2997 }
2998
2999
3000-
3001-/**
3002- * Draw ground textures and roads for the given parallelogram (two triangles)
3003- * into the bitmap.
3004- *
3005- * Vertices:
3006- * - f_vert vertex of the field
3007- * - r_vert vertex right of the field
3008- * - bl_vert vertex bottom left of the field
3009- * - br_vert vertex bottom right of the field
3010- *
3011- * Textures:
3012- * - f_r_texture Terrain of the triangle right of the field
3013- * - f_d_texture Terrain of the triangle under of the field
3014- * - tr_d_texture Terrain of the triangle top of the right triangle ??
3015- * - l_r_texture Terrain of the triangle left of the down triangle ??
3016- *
3017- * (tr_d)
3018- *
3019- * (f) *------* (r)
3020- * / \ r /
3021- * (l_r) / \ /
3022- * / d \/
3023- * (bl) *------* (br)
3024- */
3025-
3026-void GameView::draw_field
3027- (Rect & /* subwin */,
3028- Vertex const & /* f_vert */,
3029- Vertex const & /* r_vert */,
3030- Vertex const & /* bl_vert */,
3031- Vertex const & /* br_vert */,
3032- uint8_t /* roads */,
3033- Texture const & /* tr_d_texture */,
3034- Texture const & /* l_r_texture */,
3035- Texture const & /* f_d_texture */,
3036- Texture const & /* f_r_texture */)
3037-{
3038-
3039-}
3040-
3041 /*
3042 * Blend to colors; only needed for calc_minimap_color below
3043 */
3044@@ -1290,7 +325,7 @@
3045 viewpt is the field at the top left of the rectangle.
3046 ===============
3047 */
3048-void GameView::draw_minimap
3049+void MiniMapRenderer::draw_minimap
3050 (Widelands::Editor_Game_Base const & egbase,
3051 Widelands::Player const * const player,
3052 Rect const rc,
3053
3054=== renamed file 'src/graphic/render/gameview.h' => 'src/graphic/render/minimaprenderer.h'
3055--- src/graphic/render/gameview.h 2012-11-24 16:22:10 +0000
3056+++ src/graphic/render/minimaprenderer.h 2013-02-09 12:25:26 +0000
3057@@ -1,5 +1,5 @@
3058 /*
3059- * Copyright (C) 2010-2012 by the Widelands Development Team
3060+ * Copyright (C) 2010-2013 by the Widelands Development Team
3061 *
3062 * This program is free software; you can redistribute it and/or
3063 * modify it under the terms of the GNU General Public License
3064@@ -17,58 +17,25 @@
3065 *
3066 */
3067
3068-#ifndef WIDELANDS_GAMEVIEW_H
3069-#define WIDELANDS_GAMEVIEW_H
3070+#ifndef WIDELANDS_MINIMAPRENDERER_H
3071+#define WIDELANDS_MINIMAPRENDERER_H
3072+
3073+#include "graphic/rendertarget.h"
3074
3075 namespace Widelands {
3076 struct Player;
3077 struct Editor_Game_Base;
3078 };
3079
3080-struct Vertex;
3081-struct Texture;
3082-
3083-#include "graphic/rendertarget.h"
3084-
3085 /**
3086- * This class does the game rendering. The class is initialized from a
3087- * RenderTarget and can draw views of the game and the minimap. The game
3088- * can be rendered to the full screen or to a subwindow. This depends on
3089- * the RenderTarget from which it was initialized.
3090- *
3091- * @todo GameView mixes opengl and software rendering. This should be split
3092- * properly to have different classes for OpenGL and Software rendering.
3093- * Perhaps creating a GameRenderManager where different rendering classes can
3094- * be registered so it is easiely possible to create different game rendering?
3095+ * This class renders the minimap.
3096 */
3097-class GameView : public RenderTarget
3098+class MiniMapRenderer : public RenderTarget
3099 {
3100 public:
3101- GameView(RenderTarget & rt) :
3102+ MiniMapRenderer(RenderTarget & rt) :
3103 RenderTarget(rt) {}
3104- virtual ~GameView() {}
3105-
3106- /**
3107- * Renders the map from a player's point of view into the current drawing
3108- * window.
3109- *
3110- * Will call the function below when player.see_all().
3111- *
3112- * viewofs is the offset of the upper left corner of the window into the map,
3113- * in pixels.
3114- */
3115- void rendermap
3116- (Widelands::Editor_Game_Base const & egbase,
3117- Widelands::Player const & player,
3118- Point viewofs);
3119-
3120- /**
3121- * Same as above but not from a player's point of view. Used in game when
3122- * rendering for a player that sees all and the editor.
3123- */
3124- void rendermap
3125- (Widelands::Editor_Game_Base const & egbase,
3126- Point viewofs);
3127+ virtual ~MiniMapRenderer() {}
3128
3129 /**
3130 * Render the minimap. If player is not 0, it renders from that player's
3131@@ -81,22 +48,6 @@
3132 uint32_t flags);
3133
3134 protected:
3135- /**
3136- * Helper function to draw two terrain triangles. This is called from the
3137- * rendermap() functions.
3138- */
3139- virtual void draw_field
3140- (Rect & subwin,
3141- Vertex const & f_vert,
3142- Vertex const & r_vert,
3143- Vertex const & bl_vert,
3144- Vertex const & br_vert,
3145- uint8_t roads,
3146- Texture const & tr_d_texture,
3147- Texture const & l_r_texture,
3148- Texture const & f_d_texture,
3149- Texture const & f_r_texture);
3150-
3151 /// A helper function to draw the minimap. This is called from
3152 /// renderminimap().
3153 void draw_minimap
3154@@ -106,16 +57,6 @@
3155 Point viewpt,
3156 Point framept,
3157 uint32_t flags);
3158-
3159- /**
3160- * This is called before the view of the game is rendered.
3161- */
3162- virtual void rendermap_init() {}
3163-
3164- /**
3165- * This is called after the view of the game is rendered.
3166- */
3167- virtual void rendermap_deint() {}
3168 };
3169
3170-#endif //WIDELANDS_GAMEVIEW_H
3171+#endif //WIDELANDS_MINIMAPRENDERER_H
3172
3173=== removed file 'src/graphic/render/terrain_opengl.h'
3174--- src/graphic/render/terrain_opengl.h 2012-12-07 07:32:24 +0000
3175+++ src/graphic/render/terrain_opengl.h 1970-01-01 00:00:00 +0000
3176@@ -1,327 +0,0 @@
3177-/*
3178- * Copyright (C) 2010-2012 by the Widelands Development Team
3179- *
3180- * This program is free software; you can redistribute it and/or
3181- * modify it under the terms of the GNU General Public License
3182- * as published by the Free Software Foundation; either version 2
3183- * of the License, or (at your option) any later version.
3184- *
3185- * This program is distributed in the hope that it will be useful,
3186- * but WITHOUT ANY WARRANTY; without even the implied warranty of
3187- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
3188- * GNU General Public License for more details.
3189- *
3190- * You should have received a copy of the GNU General Public License
3191- * along with this program; if not, write to the Free Software
3192- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
3193- *
3194- */
3195-
3196-#ifdef USE_OPENGL
3197-#ifndef TERRAIN_OPENGL_H
3198-#define TERRAIN_OPENGL_H
3199-
3200-#include "gl_surface_texture.h"
3201-#include "vertex.h"
3202-
3203-
3204-void draw_field_opengl
3205- (Rect const & subwin,
3206- Vertex const & p1,
3207- Vertex const & p2,
3208- Vertex const & p3,
3209- Texture const & texture,
3210- Texture const & left_texture,
3211- Texture const & top_texture)
3212-{
3213- if (p1.b <= -128 and p2.b <= -128 and p3.b <= -128)
3214- return;
3215-
3216- Vertex t1(p1), t2(p2), t3(p3);
3217-
3218- t1.x = p1.x + subwin.x;
3219- t1.y = p1.y + subwin.y;
3220- t2.x = p2.x + subwin.x;
3221- t2.y = p2.y + subwin.y;
3222- t3.x = p3.x + subwin.x;
3223- t3.y = p3.y + subwin.y;
3224-
3225- if (t1.x < subwin.x and t2.x < subwin.x and t3.x < subwin.x)
3226- return;
3227- if (t1.y < subwin.y and t2.y < subwin.y and t3.y < subwin.y)
3228- return;
3229-
3230- int const subxr = subwin.x + subwin.w;
3231- if (t1.x > subxr and t2.x > subxr and t3.x > subxr)
3232- return;
3233-
3234- int const subyd = subwin.y + subwin.h;
3235- if (t1.y > subyd and t2.y > subyd and t3.y > subyd)
3236- return;
3237-
3238- glEnable(GL_BLEND);
3239-
3240- if (g_gr->caps().gl.multitexture) {
3241-
3242- // load current texture
3243- glActiveTextureARB(GL_TEXTURE0_ARB);
3244- glEnable(GL_TEXTURE_2D);
3245- glBindTexture(GL_TEXTURE_2D, texture.getTexture());
3246- glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
3247-
3248- // initialize all texture layers to prevent bug if some layers are skipped
3249- for (int i = 1; i < 5; i++) {
3250- glActiveTextureARB(GL_TEXTURE0_ARB + i);
3251- glEnable(GL_TEXTURE_2D);
3252- glBindTexture(GL_TEXTURE_2D, top_texture.getTexture());
3253- glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_ARB);
3254- glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_REPLACE);
3255- glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_PREVIOUS_ARB);
3256- glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB_ARB, GL_SRC_COLOR);
3257- }
3258-
3259- if ((&top_texture != &texture) and not (p1.b == -128 and p3.b == -128)) {
3260- // load top texture
3261- glActiveTextureARB(GL_TEXTURE1_ARB);
3262- glEnable(GL_TEXTURE_2D);
3263- glBindTexture(GL_TEXTURE_2D, top_texture.getTexture());
3264- glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_ARB);
3265- glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_REPLACE);
3266- glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_PREVIOUS_ARB);
3267- glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB_ARB, GL_SRC_COLOR);
3268-
3269- GLuint edge = dynamic_cast<GLSurfaceTexture const &>
3270- (*g_gr->get_edge_texture()).get_gl_texture();
3271-
3272- // combine current and top texture
3273- glActiveTextureARB(GL_TEXTURE2_ARB);
3274- glEnable(GL_TEXTURE_2D);
3275- glBindTexture(GL_TEXTURE_2D, edge);
3276- glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_ARB);
3277- glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_INTERPOLATE_ARB);
3278- glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_PREVIOUS_ARB);
3279- glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB_ARB, GL_TEXTURE1_ARB);
3280- glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE2_RGB_ARB, GL_TEXTURE);
3281- glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB_ARB, GL_SRC_COLOR);
3282- glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB_ARB, GL_SRC_COLOR);
3283- glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND2_RGB_ARB, GL_SRC_COLOR);
3284- }
3285-
3286- if ((&left_texture != &texture) and not (p1.b == -128 and p2.b == -128)) {
3287- // load left texture
3288- glActiveTextureARB(GL_TEXTURE3_ARB);
3289- glEnable(GL_TEXTURE_2D);
3290- glBindTexture(GL_TEXTURE_2D, left_texture.getTexture());
3291- glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_ARB);
3292- glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_REPLACE);
3293- glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_PREVIOUS_ARB);
3294- glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB_ARB, GL_SRC_COLOR);
3295-
3296- GLuint edge = dynamic_cast<GLSurfaceTexture const &>
3297- (*g_gr->get_edge_texture()).get_gl_texture();
3298-
3299- // combine current and left texture
3300- glActiveTextureARB(GL_TEXTURE4_ARB);
3301- glEnable(GL_TEXTURE_2D);
3302- glBindTexture(GL_TEXTURE_2D, edge);
3303- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
3304- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
3305- glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_ARB);
3306- glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_INTERPOLATE_ARB);
3307- glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_PREVIOUS_ARB);
3308- glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB_ARB, GL_TEXTURE3_ARB);
3309- glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE2_RGB_ARB, GL_TEXTURE);
3310- glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB_ARB, GL_SRC_COLOR);
3311- glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB_ARB, GL_SRC_COLOR);
3312- glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND2_RGB_ARB, GL_SRC_COLOR);
3313- }
3314-
3315- // Fade effect for fog of war
3316- glActiveTextureARB(GL_TEXTURE5_ARB);
3317- glEnable(GL_TEXTURE_2D);
3318- // texture does not matter but one has to be bound
3319- glBindTexture(GL_TEXTURE_2D, texture.getTexture());
3320- glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_ARB);
3321- glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_MODULATE);
3322- glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_PREVIOUS_ARB);
3323- glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB_ARB, GL_SRC_COLOR);
3324- glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB_ARB, GL_PRIMARY_COLOR_ARB);
3325- glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB_ARB, GL_SRC_COLOR);
3326-
3327- glBegin(GL_TRIANGLES); {
3328- {
3329- GLfloat const brightness = (150.0 + p1.b) / 150.0;
3330- glColor3f(brightness, brightness, brightness);
3331- }
3332- glMultiTexCoord2iARB(GL_TEXTURE0_ARB, t1.tx, t1.ty);
3333- glMultiTexCoord2fARB(GL_TEXTURE1_ARB, t1.tx / TEXTURE_WIDTH, t1.ty / TEXTURE_WIDTH);
3334- glMultiTexCoord2fARB(GL_TEXTURE2_ARB, 0, 0);
3335- glMultiTexCoord2fARB(GL_TEXTURE3_ARB, t1.tx / TEXTURE_WIDTH, t1.ty / TEXTURE_WIDTH);
3336- glMultiTexCoord2fARB(GL_TEXTURE4_ARB, 1, 0);
3337- glMultiTexCoord2fARB(GL_TEXTURE5_ARB, t1.tx / TEXTURE_WIDTH, t1.ty / TEXTURE_WIDTH);
3338- glVertex2f(t1.x, t1.y);
3339-
3340- {
3341- GLfloat const brightness = (150.0 + p2.b) / 150.0;
3342- glColor3f(brightness, brightness, brightness);
3343- }
3344- glMultiTexCoord2iARB(GL_TEXTURE0_ARB, t2.tx, t2.ty);
3345- glMultiTexCoord2fARB(GL_TEXTURE1_ARB, t2.tx / TEXTURE_WIDTH, t2.ty / TEXTURE_WIDTH);
3346- glMultiTexCoord2fARB(GL_TEXTURE2_ARB, 0.5, 1);
3347- glMultiTexCoord2fARB(GL_TEXTURE3_ARB, t2.tx / TEXTURE_WIDTH, t2.ty / TEXTURE_WIDTH);
3348- glMultiTexCoord2fARB(GL_TEXTURE4_ARB, 0, 0);
3349- glMultiTexCoord2fARB(GL_TEXTURE5_ARB, t2.tx / TEXTURE_WIDTH, t2.ty / TEXTURE_WIDTH);
3350- glVertex2f(t2.x, t2.y);
3351-
3352- {
3353- GLfloat const brightness = (150.0 + p3.b) / 150.0;
3354- glColor3f(brightness, brightness, brightness);
3355- }
3356- glMultiTexCoord2iARB(GL_TEXTURE0_ARB, t3.tx, t3.ty);
3357- glMultiTexCoord2fARB(GL_TEXTURE1_ARB, t3.tx / TEXTURE_WIDTH, t3.ty / TEXTURE_WIDTH);
3358- glMultiTexCoord2fARB(GL_TEXTURE2_ARB, 1, 0);
3359- glMultiTexCoord2fARB(GL_TEXTURE3_ARB, t3.tx / TEXTURE_WIDTH, t3.ty / TEXTURE_WIDTH);
3360- glMultiTexCoord2fARB(GL_TEXTURE4_ARB, 0.5, 1);
3361- glMultiTexCoord2fARB(GL_TEXTURE5_ARB, t3.tx / TEXTURE_WIDTH, t3.ty / TEXTURE_WIDTH);
3362- glVertex2f(t3.x, t3.y);
3363- } glEnd();
3364-
3365- // Cleanup OpenGL
3366- glActiveTextureARB(GL_TEXTURE5_ARB);
3367- glDisable(GL_TEXTURE_2D);
3368- glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
3369- glActiveTextureARB(GL_TEXTURE4_ARB);
3370- glDisable(GL_TEXTURE_2D);
3371- glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
3372- glActiveTextureARB(GL_TEXTURE3_ARB);
3373- glDisable(GL_TEXTURE_2D);
3374- glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
3375- glActiveTextureARB(GL_TEXTURE2_ARB);
3376- glDisable(GL_TEXTURE_2D);
3377- glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
3378- glActiveTextureARB(GL_TEXTURE1_ARB);
3379- glDisable(GL_TEXTURE_2D);
3380- glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
3381- glActiveTextureARB(GL_TEXTURE0_ARB);
3382- glEnable(GL_TEXTURE_2D);
3383- glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
3384-
3385- } else {
3386- // don't use multitexture
3387- glBindTexture(GL_TEXTURE_2D, texture.getTexture());
3388- glBegin(GL_TRIANGLES); {
3389- {
3390- GLfloat const brightness = (150.0 + p1.b) / 150.0;
3391- glColor3f(brightness, brightness, brightness);
3392- }
3393- glTexCoord2i(t1.tx, t1.ty);
3394- glVertex2f(t1.x, t1.y);
3395-
3396- {
3397- GLfloat const brightness = (150.0 + p2.b) / 150.0;
3398- glColor3f(brightness, brightness, brightness);
3399- }
3400- glTexCoord2i(t2.tx, t2.ty);
3401- glVertex2f(t2.x, t2.y);
3402-
3403- {
3404- GLfloat const brightness = (150.0 + p3.b) / 150.0;
3405- glColor3f(brightness, brightness, brightness);
3406- }
3407- glTexCoord2i(t3.tx, t3.ty);
3408- glVertex2f(t3.x, t3.y);
3409- } glEnd();
3410- }
3411-}
3412-
3413-#define horiz_road_opengl(tex, start, end) \
3414- glBindTexture( GL_TEXTURE_2D, tex); \
3415- glBegin(GL_QUADS); { \
3416- glTexCoord2i(0, 0); \
3417- glVertex2f(subwin.x + start.x, subwin.y + start.y - 2); \
3418- glTexCoord2i(TEXTURE_WIDTH, 0); \
3419- glVertex2f(subwin.x + end.x, subwin.y + end.y - 2); \
3420- glTexCoord2i(TEXTURE_WIDTH, 4); \
3421- glVertex2f(subwin.x + end.x, subwin.y + end.y + 2); \
3422- glTexCoord2i(0, 4); \
3423- glVertex2f(subwin.x + start.x, subwin.y + start.y + 2); \
3424- } glEnd(); \
3425-
3426-#define vert_road_opengl(tex, start, end) \
3427- glBindTexture( GL_TEXTURE_2D, tex); \
3428- glBegin(GL_QUADS); { \
3429- glTexCoord2i(0, 0); \
3430- glVertex2f(subwin.x + start.x - 3, subwin.y + start.y); \
3431- glTexCoord2i(6, 0); \
3432- glVertex2f(subwin.x + start.x + 3, subwin.y + start.y); \
3433- glTexCoord2i(TEXTURE_WIDTH, TEXTURE_HEIGHT); \
3434- glVertex2f(subwin.x + end.x + 3, subwin.y + end.y); \
3435- glTexCoord2i(TEXTURE_WIDTH - 6, TEXTURE_HEIGHT); \
3436- glVertex2f(subwin.x + end.x - 3, subwin.y + end.y); \
3437- } glEnd(); \
3438-
3439-void draw_roads_opengl
3440- (Rect & subwin,
3441- uint8_t roads,
3442- Vertex const & f_vert,
3443- Vertex const & r_vert,
3444- Vertex const & bl_vert,
3445- Vertex const & br_vert)
3446-{
3447- uint8_t road;
3448-
3449- GLuint rt_normal =
3450- dynamic_cast<GLSurfaceTexture const &>
3451- (*g_gr->get_road_texture(Widelands::Road_Normal)).get_gl_texture();
3452- GLuint rt_busy =
3453- dynamic_cast<GLSurfaceTexture const &>
3454- (*g_gr->get_road_texture(Widelands::Road_Busy)).get_gl_texture();
3455-
3456- glDisable(GL_BLEND);
3457- glColor4f(1.0f, 1.0f, 1.0f, 0.6f);
3458-
3459- road = (roads >> Widelands::Road_East) & Widelands::Road_Mask;
3460- if ((-128 < f_vert.b or -128 < r_vert.b) and road) {
3461- switch (road) {
3462- case Widelands::Road_Normal:
3463- horiz_road_opengl(rt_normal, f_vert, r_vert)
3464- break;
3465- case Widelands::Road_Busy:
3466- horiz_road_opengl(rt_busy, f_vert, r_vert)
3467- break;
3468- default:
3469- assert(false);
3470- }
3471- }
3472-
3473- road = (roads >> Widelands::Road_SouthEast) & Widelands::Road_Mask;
3474- if ((-128 < f_vert.b or -128 < br_vert.b) and road) {
3475- switch (road) {
3476- case Widelands::Road_Normal:
3477- vert_road_opengl(rt_normal, f_vert, br_vert);
3478- break;
3479- case Widelands::Road_Busy:
3480- vert_road_opengl(rt_busy, f_vert, br_vert);
3481- break;
3482- default:
3483- assert(false);
3484- }
3485- }
3486-
3487- road = (roads >> Widelands::Road_SouthWest) & Widelands::Road_Mask;
3488- if ((-128 < f_vert.b or -128 < bl_vert.b) and road) {
3489- switch (road) {
3490- case Widelands::Road_Normal:
3491- vert_road_opengl(rt_normal, f_vert, bl_vert);
3492- break;
3493- case Widelands::Road_Busy:
3494- vert_road_opengl(rt_busy, f_vert, bl_vert);
3495- break;
3496- default:
3497- assert(false);
3498- }
3499- }
3500-}
3501-
3502-#endif
3503-#endif
3504
3505=== modified file 'src/graphic/rendertarget.h'
3506--- src/graphic/rendertarget.h 2012-12-15 18:40:59 +0000
3507+++ src/graphic/rendertarget.h 2013-02-09 12:25:26 +0000
3508@@ -1,5 +1,5 @@
3509 /*
3510- * Copyright (C) 2002-2004, 2006-2010 by the Widelands Development Team
3511+ * Copyright (C) 2002-2004, 2006-2013 by the Widelands Development Team
3512 *
3513 * This program is free software; you can redistribute it and/or
3514 * modify it under the terms of the GNU General Public License
3515@@ -88,6 +88,8 @@
3516 void reset();
3517
3518 Surface* get_surface() {return m_surface;}
3519+ const Rect & get_rect() const {return m_rect;}
3520+ const Point & get_offset() const {return m_offset;}
3521
3522 protected:
3523 bool clip(Rect & r) const throw ();
3524
3525=== modified file 'src/logic/instances.h'
3526--- src/logic/instances.h 2013-02-03 10:44:13 +0000
3527+++ src/logic/instances.h 2013-02-09 12:25:26 +0000
3528@@ -1,5 +1,5 @@
3529 /*
3530- * Copyright (C) 2002-2004, 2006-2011 by the Widelands Development Team
3531+ * Copyright (C) 2002-2004, 2006-2013 by the Widelands Development Team
3532 *
3533 * This program is free software; you can redistribute it and/or
3534 * modify it under the terms of the GNU General Public License
3535
3536=== modified file 'src/logic/tribe.h'
3537--- src/logic/tribe.h 2013-02-03 10:44:13 +0000
3538+++ src/logic/tribe.h 2013-02-09 12:25:26 +0000
3539@@ -1,5 +1,5 @@
3540 /*
3541- * Copyright (C) 2002, 2006-2011 by the Widelands Development Team
3542+ * Copyright (C) 2002, 2006-2013 by the Widelands Development Team
3543 *
3544 * This program is free software; you can redistribute it and/or
3545 * modify it under the terms of the GNU General Public License
3546
3547=== modified file 'src/logic/world.cc'
3548--- src/logic/world.cc 2012-11-30 22:10:10 +0000
3549+++ src/logic/world.cc 2013-02-09 12:25:26 +0000
3550@@ -821,6 +821,7 @@
3551 m_name (s->get_name()),
3552 m_descname (s->get_string("name", s->get_name())),
3553 m_frametime (FRAME_LENGTH),
3554+m_dither_layer (0),
3555 m_valid_resources (0),
3556 m_nr_valid_resources(0),
3557 m_default_resources (-1),
3558@@ -896,6 +897,8 @@
3559 throw game_data_error("%s: invalid type '%s'", m_name.c_str(), is);
3560 }
3561
3562+ m_dither_layer = s->get_int("dither_layer", 0);
3563+
3564 // Determine template of the texture animation pictures
3565 char fnametmpl[256];
3566
3567
3568=== modified file 'src/logic/world.h'
3569--- src/logic/world.h 2012-11-30 22:10:10 +0000
3570+++ src/logic/world.h 2013-02-09 12:25:26 +0000
3571@@ -113,6 +113,7 @@
3572 int32_t get_default_resources_amount() const throw () {
3573 return m_default_amount;
3574 }
3575+ int32_t dither_layer() const {return m_dither_layer;}
3576
3577 private:
3578 const std::string m_name;
3579@@ -121,12 +122,13 @@
3580 uint32_t m_frametime;
3581 uint8_t m_is;
3582
3583+ int32_t m_dither_layer;
3584+
3585 uint8_t * m_valid_resources;
3586 uint8_t m_nr_valid_resources;
3587 int8_t m_default_resources;
3588 int32_t m_default_amount;
3589 uint32_t m_texture; // renderer's texture
3590-
3591 };
3592
3593 struct MapGenInfo;
3594
3595=== modified file 'src/point.h'
3596--- src/point.h 2012-09-21 21:36:07 +0000
3597+++ src/point.h 2013-02-09 12:25:26 +0000
3598@@ -1,5 +1,5 @@
3599 /*
3600- * Copyright (C) 2002-2004, 2006-2007 by the Widelands Development Team
3601+ * Copyright (C) 2002-2004, 2006-2013 by the Widelands Development Team
3602 *
3603 * This program is free software; you can redistribute it and/or
3604 * modify it under the terms of the GNU General Public License
3605@@ -44,6 +44,9 @@
3606 Point operator+ (const Point & other) const {
3607 return Point(x + other.x, y + other.y);
3608 }
3609+ Point operator- () const {
3610+ return Point(-x, -y);
3611+ }
3612 Point operator- (const Point & other) const {
3613 return Point(x - other.x, y - other.y);
3614 }
3615
3616=== modified file 'src/rect.h'
3617--- src/rect.h 2013-02-04 21:52:38 +0000
3618+++ src/rect.h 2013-02-09 12:25:26 +0000
3619@@ -1,5 +1,5 @@
3620 /*
3621- * Copyright (C) 2002-2004, 2006-2010 by the Widelands Development Team
3622+ * Copyright (C) 2002-2004, 2006-2013 by the Widelands Development Team
3623 *
3624 * This program is free software; you can redistribute it and/or
3625 * modify it under the terms of the GNU General Public License
3626
3627=== modified file 'src/wui/mapview.cc'
3628--- src/wui/mapview.cc 2012-12-16 14:29:46 +0000
3629+++ src/wui/mapview.cc 2013-02-09 12:25:26 +0000
3630@@ -1,5 +1,5 @@
3631 /*
3632- * Copyright (C) 2002-2004, 2006-2011 by the Widelands Development Team
3633+ * Copyright (C) 2002-2004, 2006-2013 by the Widelands Development Team
3634 *
3635 * This program is free software; you can redistribute it and/or
3636 * modify it under the terms of the GNU General Public License
3637@@ -19,7 +19,6 @@
3638
3639 #include "mapview.h"
3640
3641-
3642 #include "interactive_base.h"
3643 #include "interactive_player.h"
3644 #include "mapviewpixelfunctions.h"
3645@@ -30,9 +29,8 @@
3646
3647 #include "graphic/graphic.h"
3648 #include "graphic/rendertarget.h"
3649-#include "graphic/render/gameview.h"
3650-#include "graphic/render/gameview_opengl.h"
3651-#include "graphic/render/gameview_sdl.h"
3652+#include "graphic/render/gamerenderer_gl.h"
3653+#include "graphic/render/gamerenderer_sdl.h"
3654
3655 #include "upcast.h"
3656
3657@@ -48,6 +46,11 @@
3658 m_complete_redraw_needed(true)
3659 {}
3660
3661+Map_View::~Map_View()
3662+{
3663+ // explicit destructor so that smart pointer destructors
3664+ // with forward-declared types are properly instantiated
3665+}
3666
3667 /// Moves the mouse cursor so that it is directly above the given node
3668 void Map_View::warp_mouse_to_node(Widelands::Coords const c) {
3669@@ -95,21 +98,21 @@
3670
3671 egbase.map().overlay_manager().load_graphics();
3672
3673- GameView * gameview;
3674+ if (!m_renderer) {
3675 #ifdef USE_OPENGL
3676- if (g_opengl) {
3677- gameview = new GameViewOpenGL(dst);
3678- } else
3679+ if (g_opengl) {
3680+ m_renderer.reset(new GameRendererGL());
3681+ } else
3682 #endif
3683- {
3684- gameview = new GameViewSDL(dst);
3685+ {
3686+ m_renderer.reset(new GameRendererSDL());
3687+ }
3688 }
3689 if (upcast(Interactive_Player const, interactive_player, &intbase())) {
3690- gameview->rendermap(egbase, interactive_player->player(), m_viewpoint);
3691+ m_renderer->rendermap(dst, egbase, interactive_player->player(), m_viewpoint);
3692 } else {
3693- gameview->rendermap(egbase, m_viewpoint);
3694+ m_renderer->rendermap(dst, egbase, m_viewpoint);
3695 }
3696- delete gameview;
3697
3698 m_complete_redraw_needed = false;
3699 draw_tooltip(dst, tooltip());
3700
3701=== modified file 'src/wui/mapview.h'
3702--- src/wui/mapview.h 2012-02-15 21:25:34 +0000
3703+++ src/wui/mapview.h 2013-02-09 12:25:26 +0000
3704@@ -27,6 +27,7 @@
3705
3706 #include "ui_basic/panel.h"
3707
3708+struct GameRenderer;
3709 struct Interactive_Base;
3710
3711 /**
3712@@ -45,6 +46,7 @@
3713 (UI::Panel * const parent,
3714 const int32_t x, const int32_t y, const uint32_t w, const uint32_t h,
3715 Interactive_Base &);
3716+ virtual ~Map_View();
3717
3718 void set_changeview(const ChangeViewFn & fn);
3719
3720@@ -83,6 +85,7 @@
3721 private:
3722 void stop_dragging();
3723
3724+ boost::scoped_ptr<GameRenderer> m_renderer;
3725 Interactive_Base & m_intbase;
3726 ChangeViewFn m_changeview;
3727 Point m_viewpoint;
3728
3729=== modified file 'src/wui/minimap.cc'
3730--- src/wui/minimap.cc 2012-12-13 10:41:22 +0000
3731+++ src/wui/minimap.cc 2013-02-09 12:25:26 +0000
3732@@ -26,7 +26,7 @@
3733
3734 #include "graphic/graphic.h"
3735 #include "graphic/rendertarget.h"
3736-#include "graphic/render/gameview.h"
3737+#include "graphic/render/minimaprenderer.h"
3738
3739
3740 MiniMap::View::View
3741@@ -60,9 +60,9 @@
3742
3743 void MiniMap::View::draw(RenderTarget & dst)
3744 {
3745- GameView gameview(dst);
3746+ MiniMapRenderer mmr(dst);
3747
3748- gameview.renderminimap
3749+ mmr.renderminimap
3750 (m_ibase.egbase(),
3751 m_ibase.get_player(),
3752 (*m_flags) & (MiniMap::Zoom2) ?
3753
3754=== modified file 'worlds/blackland/terrainconf'
3755--- worlds/blackland/terrainconf 2012-02-15 21:25:34 +0000
3756+++ worlds/blackland/terrainconf 2013-02-09 12:25:26 +0000
3757@@ -7,75 +7,91 @@
3758 name="Ashes"
3759 def_resources=water 5
3760 is=green
3761+dither_layer=20
3762
3763 [mountain1]
3764 name="Mountain1"
3765-resources=coal, iron, gold, granit
3766+resources=coal, iron, gold, granit
3767 is=mountain
3768+dither_layer=50
3769
3770 [lava-stone1]
3771 name="Lava stone1"
3772 is=acid
3773+dither_layer=70
3774
3775 [lava-stone2]
3776 name="Lava stone2"
3777 is=acid
3778+dither_layer=70
3779
3780 [strand]
3781 name="Beach"
3782 is=dry
3783+dither_layer=10
3784
3785 [water]
3786 name="Water"
3787 def_resources=fish 4
3788 is=water
3789 fps=14
3790+dither_layer=0
3791
3792 [hardground1]
3793 name="Hardground1"
3794 def_resources=water 10
3795 is=green
3796+dither_layer=30
3797
3798 [hardground2]
3799 name="Hardground2"
3800 def_resources=water 10
3801 is=green
3802+dither_layer=30
3803
3804 [hardground3]
3805 name="Hardground3"
3806 def_resources=water 10
3807 is=green
3808+dither_layer=30
3809
3810 [mountain2]
3811 name="Mountain2"
3812 resources=coal, iron, gold, granit
3813 is=mountain
3814+dither_layer=50
3815
3816 [mountain3]
3817 name="Mountain3"
3818 resources=coal, iron, gold, granit
3819 is=mountain
3820+dither_layer=50
3821
3822 [mountain4]
3823 name="Mountain4"
3824 resources=coal, iron, gold, granit
3825 is=mountain
3826+dither_layer=50
3827
3828 [ashes2]
3829 name="Ashes2"
3830 def_resources=water 4
3831 is=green
3832+dither_layer=20
3833
3834 [hardground4]
3835 name="Hardground4"
3836 def_resources=water 10
3837 is=green
3838+dither_layer=30
3839
3840 [lava]
3841 name="Lava"
3842 is=acid
3843+dither_layer=60
3844
3845 [hardlava]
3846 name="Hard lava"
3847 is=green
3848+dither_layer=40
3849
3850
3851=== modified file 'worlds/desert/terrainconf'
3852--- worlds/desert/terrainconf 2012-02-15 21:25:34 +0000
3853+++ worlds/desert/terrainconf 2013-02-09 12:25:26 +0000
3854@@ -7,66 +7,80 @@
3855 [desert1]
3856 name="Desert1"
3857 is=dry
3858+dither_layer=20
3859
3860 [desert2]
3861 name="Desert2"
3862 is=dry
3863+dither_layer=20
3864
3865 [desert3]
3866 name="Desert3"
3867 is=dry
3868+dither_layer=20
3869
3870 [desert4]
3871 name="Desert4"
3872 def_resources=water 2
3873 is=green
3874+dither_layer=20
3875
3876 [drysoil]
3877 name="Dry soil"
3878 def_resources=water 4
3879 is=green
3880+dither_layer=30
3881
3882 [beach]
3883 name="Beach"
3884 is=dry
3885+dither_layer=10
3886
3887 [steppe]
3888 name="Steppe"
3889 def_resources=water 5
3890 is=green
3891+dither_layer=30
3892
3893 [meadow]
3894 name="Meadow"
3895 def_resources=water 10
3896 is=green
3897+dither_layer=40
3898
3899 [mountainmeadow]
3900 name="Mountain meadow"
3901 is=green
3902+dither_layer=50
3903
3904 [highmountainmeadow]
3905 name="High mountain meadow"
3906 is=green
3907+dither_layer=60
3908
3909 [mountain1]
3910 name="Mountain1"
3911 resources=coal, iron, gold, granit
3912 is=mountain
3913+dither_layer=70
3914
3915 [mountain2]
3916 name="Mountain2"
3917 resources=coal, iron, gold, granit
3918 is=mountain
3919+dither_layer=70
3920
3921 [mountain3]
3922 name="Mountain3"
3923 resources=coal, iron, gold, granit
3924 is=mountain
3925+dither_layer=70
3926
3927 [mountain4]
3928 name="Mountain4"
3929 resources=coal, iron, gold, granit
3930 is=mountain
3931+dither_layer=70
3932
3933
3934 ##### Here are few imported textures of greenland
3935@@ -76,7 +90,9 @@
3936 def_resources=fish 4
3937 is=water
3938 fps=5
3939+dither_layer=0
3940
3941 [lava]
3942 name="Lava"
3943 is=acid
3944+dither_layer=80
3945
3946=== modified file 'worlds/greenland/terrainconf'
3947--- worlds/greenland/terrainconf 2012-02-15 21:25:34 +0000
3948+++ worlds/greenland/terrainconf 2013-02-09 12:25:26 +0000
3949@@ -7,76 +7,92 @@
3950 name="Steppe"
3951 def_resources=water 5
3952 is=green
3953+dither_layer=20
3954
3955 [berg1]
3956 name="Mountain1"
3957 resources=coal, iron, gold, granit
3958 is=mountain
3959+dither_layer=60
3960
3961 [schnee]
3962 name="Snow"
3963 is=dead
3964+dither_layer=70
3965
3966 [sumpf]
3967 name="Swamp"
3968 def_resources=water 20
3969 is=unpassable
3970 fps=14
3971+dither_layer=30
3972
3973 [strand]
3974 name="Beach"
3975 is=dry
3976+dither_layer=10
3977
3978 [wasser]
3979 name="Water"
3980 def_resources=fish 4
3981 is=water
3982 fps=14
3983+dither_layer=0
3984
3985 [wiese1]
3986 name="Meadow1"
3987 def_resources=water 10
3988 is=green
3989+dither_layer=40
3990
3991 [wiese2]
3992 name="Meadow2"
3993 def_resources=water 10
3994 is=green
3995+dither_layer=40
3996
3997 [wiese3]
3998 name="Meadow3"
3999 def_resources=water 10
4000 is=green
4001+dither_layer=40
4002
4003 [berg2]
4004 name="Mountain2"
4005 resources=coal, iron, gold, granit
4006 is=mountain
4007+dither_layer=60
4008
4009 [berg3]
4010 name="Mountain3"
4011 resources=coal, iron, gold, granit
4012 is=mountain
4013+dither_layer=60
4014
4015 [berg4]
4016 name="Mountain4"
4017 resources=coal, iron, gold, granit
4018 is=mountain
4019+dither_layer=60
4020
4021 [steppe_kahl]
4022 name="Barren steppe"
4023 def_resources=water 4
4024 is=green
4025+dither_layer=20
4026
4027 [wiese4]
4028 name="Meadow4"
4029 def_resources=water 10
4030 is=green
4031+dither_layer=40
4032
4033 [lava]
4034 name="Lava"
4035 is=acid
4036+dither_layer=80
4037
4038 [bergwiese]
4039 name="Mountain meadow"
4040 is=green
4041+dither_layer=50
4042
4043=== modified file 'worlds/winterland/terrainconf'
4044--- worlds/winterland/terrainconf 2012-02-15 21:25:34 +0000
4045+++ worlds/winterland/terrainconf 2013-02-09 12:25:26 +0000
4046@@ -7,77 +7,93 @@
4047 name="Tundra"
4048 def_resources=water 5
4049 is=green
4050+dither_layer=50
4051
4052 [mountain1]
4053 name="Mountain1"
4054 resources=coal, iron, gold, granit
4055 is=mountain
4056+dither_layer=70
4057
4058 [ice_flows]
4059 name="Ice flows"
4060 is=water
4061 fps=5
4062+dither_layer=10
4063
4064 [ice_flows2]
4065 name="Ice flows2"
4066 is=water
4067 fps=5
4068+dither_layer=20
4069
4070 [ice]
4071 name="Ice"
4072 is=dry
4073 #### of course ice is not dry, but this disallows the users, to build on snow. only flags are allowed. ;-)
4074+dither_layer=30
4075
4076 [water]
4077 name="Water"
4078 def_resources=fish 4
4079 is=water
4080 fps=8
4081+dither_layer=0
4082
4083 [tundra_taiga]
4084 name="Tundra taiga"
4085 def_resources=water 10
4086 is=green
4087+dither_layer=50
4088
4089 [tundra2]
4090 name="Tundra2"
4091 def_resources=water 10
4092 is=green
4093+dither_layer=50
4094
4095 [tundra3]
4096 name="Tundra3"
4097 def_resources=water 10
4098 is=green
4099+dither_layer=50
4100
4101 [mountain2]
4102 name="Mountain2"
4103 resources=coal, iron, gold, granit
4104 is=mountain
4105+dither_layer=70
4106
4107 [mountain3]
4108 name="Mountain3"
4109 resources=coal, iron, gold, granit
4110 is=mountain
4111+dither_layer=70
4112
4113 [mountain4]
4114 name="Mountain4"
4115 resources=coal, iron, gold, granit
4116 is=mountain
4117+dither_layer=70
4118
4119 [strand]
4120 name="Beach"
4121 is=dry
4122+dither_layer=40
4123
4124 [taiga]
4125 name="Taiga"
4126 def_resources=water 10
4127 is=green
4128+dither_layer=50
4129
4130 [lava]
4131 name="Lava"
4132 is=acid
4133+dither_layer=80
4134
4135 [snow]
4136 name="Snow"
4137 def_resources=water 30
4138 is=green
4139+dither_layer=60

Subscribers

People subscribed via source and target branches

to status/vote changes: