X-Git-Url: https://git.verplant.org/?a=blobdiff_plain;f=src%2Fvideo%2Fsurface.cpp;h=c7b1e1bbae98073a4a364cbbf2661673d36bd520;hb=6cd71a8644049d1951b5a9702a57ad02a7971c1e;hp=145a1abf6abe6c2ea4fc468f45d3eb5af30ef08d;hpb=07ddaed2a657e4d2a3d038fed223fc5827159caf;p=supertux.git diff --git a/src/video/surface.cpp b/src/video/surface.cpp index 145a1abf6..c7b1e1bba 100644 --- a/src/video/surface.cpp +++ b/src/video/surface.cpp @@ -32,7 +32,8 @@ #include "gameconfig.hpp" #include "physfs/physfs_sdl.hpp" #include "video/surface.hpp" -#include "video/screen.hpp" +#include "video/drawing_context.hpp" +#include "video/color.hpp" #include "image_texture.hpp" #include "texture_manager.hpp" @@ -40,8 +41,8 @@ Surface::Surface(const std::string& file) { texture = texture_manager->get(file); texture->ref(); - uv_left = 0; - uv_top = 0; + uv_left = 0.5 / texture->get_width(); + uv_top = 0.5 / texture->get_height(); uv_right = texture->get_uv_right(); uv_bottom = texture->get_uv_bottom(); @@ -56,10 +57,10 @@ Surface::Surface(const std::string& file, int x, int y, int w, int h) float tex_w = static_cast (texture->get_width()); float tex_h = static_cast (texture->get_height()); - uv_left = static_cast(x) / tex_w; - uv_top = static_cast(y) / tex_h; - uv_right = static_cast(x+w) / tex_w; - uv_bottom = static_cast(y+h) / tex_h; + uv_left = static_cast(x+0.5) / tex_w; + uv_top = static_cast(y+0.5) / tex_h; + uv_right = static_cast(x+w-0.5) / tex_w; + uv_bottom = static_cast(y+h-0.5) / tex_h; width = w; height = h; @@ -115,11 +116,11 @@ static inline void intern_draw(float left, float top, float right, float bottom, if(effect & VERTICAL_FLIP) { std::swap(uv_top, uv_bottom); } - + glBegin(GL_QUADS); glTexCoord2f(uv_left, uv_top); glVertex2f(left, top); - + glTexCoord2f(uv_right, uv_top); glVertex2f(right, top); @@ -131,6 +132,72 @@ static inline void intern_draw(float left, float top, float right, float bottom, glEnd(); } +static inline void intern_draw2(float left, float top, float right, float bottom, + float uv_left, float uv_top, + float uv_right, float uv_bottom, + float angle, + const Color& color, + const Blend& blend, + DrawingEffect effect) +{ + if(effect & HORIZONTAL_FLIP) + std::swap(uv_left, uv_right); + if(effect & VERTICAL_FLIP) { + std::swap(uv_top, uv_bottom); + } + + float center_x = (left + right) / 2; + float center_y = (top + bottom) / 2; + + float sa = sinf(angle/180.0f*M_PI); + float ca = cosf(angle/180.0f*M_PI); + + left -= center_x; + right -= center_x; + + top -= center_y; + bottom -= center_y; + + glBlendFunc(blend.sfactor, blend.dfactor); + glColor4f(color.red, color.green, color.blue, color.alpha); + glBegin(GL_QUADS); + glTexCoord2f(uv_left, uv_top); + glVertex2f(left*ca - top*sa + center_x, + left*sa + top*ca + center_y); + + glTexCoord2f(uv_right, uv_top); + glVertex2f(right*ca - top*sa + center_x, + right*sa + top*ca + center_y); + + glTexCoord2f(uv_right, uv_bottom); + glVertex2f(right*ca - bottom*sa + center_x, + right*sa + bottom*ca + center_y); + + glTexCoord2f(uv_left, uv_bottom); + glVertex2f(left*ca - bottom*sa + center_x, + left*sa + bottom*ca + center_y); + glEnd(); + + // FIXME: find a better way to restore the blend mode + glColor4f(1.0f, 1.0f, 1.0f, 1.0f); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); +} + +void +Surface::draw(float x, float y, float alpha, float angle, const Color& color, const Blend& blend, DrawingEffect effect) const +{ + glColor4f(1.0f, 1.0f, 1.0f, alpha); + glBindTexture(GL_TEXTURE_2D, texture->get_handle()); + + intern_draw2(x, y, + x + width, y + height, + uv_left, uv_top, uv_right, uv_bottom, + angle, + color, + blend, + effect); +} + void Surface::draw(float x, float y, float alpha, DrawingEffect effect) const { @@ -149,17 +216,16 @@ Surface::draw_part(float src_x, float src_y, float dst_x, float dst_y, { float uv_width = uv_right - uv_left; float uv_height = uv_bottom - uv_top; - + float uv_left = this->uv_left + (uv_width * src_x) / this->width; float uv_top = this->uv_top + (uv_height * src_y) / this->height; float uv_right = this->uv_left + (uv_width * (src_x + width)) / this->width; float uv_bottom = this->uv_top + (uv_height * (src_y + height)) / this->height; - + glColor4f(1.0f, 1.0f, 1.0f, alpha); - glBindTexture(GL_TEXTURE_2D, texture->get_handle()); - + glBindTexture(GL_TEXTURE_2D, texture->get_handle()); + intern_draw(dst_x, dst_y, dst_x + width, dst_y + height, uv_left, uv_top, uv_right, uv_bottom, effect); } -