55#include " glSmartBitmap.h"
66#include " Loader.h"
77#include " drivers/VideoDriverWrapper.h"
8+ #include " helpers/mathFuncs.h"
89#include " ogl/glBitmapItem.h"
910#include " libsiedler2/ArchivItem_Bitmap.h"
1011#include " libsiedler2/ArchivItem_Bitmap_Player.h"
1112#include " libsiedler2/PixelBufferBGRA.h"
1213#include " s25util/colors.h"
1314#include < glad/glad.h>
15+ #include < cmath>
1416#include < limits>
1517
1618namespace {
@@ -238,12 +240,32 @@ void glSmartBitmap::generateTexture()
238240 }
239241}
240242
243+ void glSmartBitmap::Draw (Rect dstArea, Rect srcArea, unsigned color /* = 0xFFFFFFFF*/ )
244+ {
245+ drawRect (dstArea, srcArea, color);
246+ }
247+
241248void glSmartBitmap::draw (DrawPoint drawPt, unsigned color, unsigned player_color)
242249{
243250 drawPercent (drawPt, 100 , color, player_color);
244251}
245252
246253void glSmartBitmap::drawPercent (DrawPoint drawPt, unsigned percent, unsigned color, unsigned player_color)
254+ {
255+ // nothing to draw?
256+ if (!percent)
257+ return ;
258+ RTTR_Assert (percent <= 100 );
259+
260+ const float partDrawn = percent / 100 .f ;
261+ auto startY = int (std::round (size_.y * (1 - partDrawn)));
262+ auto height = size_.y - startY;
263+ Rect dstArea (drawPt.x , drawPt.y + startY, size_.x , height);
264+ Rect srcArea (0 , startY, size_.x , height);
265+ drawRect (dstArea, srcArea, color, player_color);
266+ }
267+
268+ void glSmartBitmap::drawRect (Rect dstArea, Rect srcArea, unsigned color /* = 0xFFFFFFFF*/ , unsigned player_color /* = 0*/ )
247269{
248270 if (!texture)
249271 {
@@ -253,35 +275,36 @@ void glSmartBitmap::drawPercent(DrawPoint drawPt, unsigned percent, unsigned col
253275 return ;
254276 }
255277
256- // nothing to draw?
257- if (!percent)
258- return ;
259- RTTR_Assert (percent <= 100 );
260-
261- const float partDrawn = percent / 100 .f ;
262278 std::array<Point<GLfloat>, 8 > vertices, curTexCoords;
263279 std::array<GL_RGBAColor, 8 > colors;
264280
281+ auto drawPt = dstArea.getOrigin ();
265282 drawPt -= origin_;
266- vertices[2 ] = Point<GLfloat>(drawPt) + size_;
283+ vertices[2 ] = Point<GLfloat>(dstArea. getEndPt () - origin_); // destination bottom
267284
268285 vertices[0 ].x = vertices[1 ].x = GLfloat (drawPt.x );
269286 vertices[3 ].x = vertices[2 ].x ;
270287
271- vertices[0 ].y = vertices[3 ].y = GLfloat (drawPt.y + size_. y * ( 1 . f - partDrawn));
272- vertices[1 ].y = vertices[2 ].y ;
288+ vertices[0 ].y = vertices[3 ].y = GLfloat (drawPt.y ); // destination top
289+ vertices[1 ].y = vertices[2 ].y ; // destination bottom
273290
274291 colors[0 ].r = GetRed (color);
275292 colors[0 ].g = GetGreen (color);
276293 colors[0 ].b = GetBlue (color);
277294 colors[0 ].a = GetAlpha (color);
278295 colors[3 ] = colors[2 ] = colors[1 ] = colors[0 ];
279296
280- curTexCoords[0 ] = texCoords[0 ];
281- curTexCoords[1 ] = texCoords[1 ];
282- curTexCoords[2 ] = texCoords[2 ];
283- curTexCoords[3 ] = texCoords[3 ];
284- curTexCoords[0 ].y = curTexCoords[3 ].y = curTexCoords[1 ].y - (curTexCoords[1 ].y - curTexCoords[0 ].y ) * partDrawn;
297+ // 0--3/4--7
298+ // | | |
299+ // 1--2/5--6
300+ // Remap srcArea to texture coords
301+ curTexCoords[0 ].x = helpers::lerp (texCoords[0 ].x , texCoords[3 ].x , srcArea.getOrigin ().x / float (size_.x ));
302+ curTexCoords[0 ].y = helpers::lerp (texCoords[0 ].y , texCoords[1 ].y , srcArea.getOrigin ().y / float (size_.y ));
303+ curTexCoords[2 ].x = helpers::lerp (texCoords[0 ].x , texCoords[3 ].x , srcArea.getEndPt ().x / float (size_.x ));
304+ curTexCoords[2 ].y = helpers::lerp (texCoords[0 ].y , texCoords[1 ].y , srcArea.getEndPt ().y / float (size_.y ));
305+
306+ curTexCoords[1 ] = PointF (curTexCoords[0 ].x , curTexCoords[2 ].y );
307+ curTexCoords[3 ] = PointF (curTexCoords[2 ].x , curTexCoords[0 ].y );
285308
286309 int numQuads;
287310 if (player_color && hasPlayer)
0 commit comments