From: Ingo Ruhnke Date: Mon, 3 Jul 2006 17:29:29 +0000 (+0000) Subject: - added sprite rotation X-Git-Url: https://git.verplant.org/?a=commitdiff_plain;h=49796e6cc2385aea989d7c44c789b406190f2bf7;p=supertux.git - added sprite rotation - some spotlight stuff SVN-Revision: 3854 --- diff --git a/data/images/objects/spotlight/lightcone.png b/data/images/objects/spotlight/lightcone.png index 6a7e89d52..63393e8c4 100644 Binary files a/data/images/objects/spotlight/lightcone.png and b/data/images/objects/spotlight/lightcone.png differ diff --git a/data/images/objects/spotlight/lightcone.sprite b/data/images/objects/spotlight/lightcone.sprite index f38f20867..2ec345cac 100644 --- a/data/images/objects/spotlight/lightcone.sprite +++ b/data/images/objects/spotlight/lightcone.sprite @@ -2,5 +2,6 @@ (action (name "default") (images "lightcone.png") + (hitbox 430 93 0 0) ) ) diff --git a/data/images/objects/spotlight/spotlight_base.sprite b/data/images/objects/spotlight/spotlight_base.sprite index 7901be0e2..b4ce25a74 100644 --- a/data/images/objects/spotlight/spotlight_base.sprite +++ b/data/images/objects/spotlight/spotlight_base.sprite @@ -2,5 +2,6 @@ (action (name "default") (images "spotlight_base.png") + (hitbox 32 32 0 0) ) ) diff --git a/data/images/objects/spotlight/spotlight_center.sprite b/data/images/objects/spotlight/spotlight_center.sprite index 996fd4446..96ccda2ef 100644 --- a/data/images/objects/spotlight/spotlight_center.sprite +++ b/data/images/objects/spotlight/spotlight_center.sprite @@ -2,5 +2,6 @@ (action (name "default") (images "spotlight_center.png") + (hitbox 32 32 0 0) ) ) diff --git a/data/images/objects/spotlight/spotlight_lights.sprite b/data/images/objects/spotlight/spotlight_lights.sprite index 3ba02bbd8..03491bc65 100644 --- a/data/images/objects/spotlight/spotlight_lights.sprite +++ b/data/images/objects/spotlight/spotlight_lights.sprite @@ -2,5 +2,6 @@ (action (name "default") (images "spotlight_lights.png") + (hitbox 32 32 0 0) ) ) diff --git a/data/levels/test/light.stl b/data/levels/test/light.stl index 15807cf10..77473f13f 100644 --- a/data/levels/test/light.stl +++ b/data/levels/test/light.stl @@ -70,14 +70,6 @@ (reset-points ) (objects - (light ) - (mriceblock (x 666) (y 68) (stay-on-platform #f)) - (mriceblock (x 892) (y 70) (stay-on-platform #f)) - (mriceblock (x 1146) (y 69) (stay-on-platform #f)) - (mriceblock (x 1363) (y 58) (stay-on-platform #f)) - (mriceblock (x 1180) (y 15) (stay-on-platform #f)) - (mriceblock (x 939) (y 22) (stay-on-platform #f)) - (mriceblock (x 703) (y 25) (stay-on-platform #f)) - (stalactite (x 322) (y 288) (stay-on-platform #f)) + (spotlight ) ) ) diff --git a/src/object/spotlight.cpp b/src/object/spotlight.cpp index 5778b9e94..e15cdf371 100644 --- a/src/object/spotlight.cpp +++ b/src/object/spotlight.cpp @@ -33,6 +33,8 @@ Spotlight::Spotlight(const lisp::Lisp& ) base = sprite_manager->create("images/objects/spotlight/spotlight_base.sprite"); lights = sprite_manager->create("images/objects/spotlight/spotlight_lights.sprite"); lightcone = sprite_manager->create("images/objects/spotlight/lightcone.sprite"); + + angle = 0.0f; } Spotlight::~Spotlight() @@ -44,24 +46,33 @@ Spotlight::~Spotlight() } void -Spotlight::update(float ) +Spotlight::update(float delta) { - // FIXME: add rotation code + angle += delta * 50.0f; } void Spotlight::draw(DrawingContext& context) { - context.push_target(); + context.push_target(); context.set_target(DrawingContext::LIGHTMAP); Vector pos(100, 300); + + lightcone->set_angle(angle); lightcone->draw(context, pos, 0); - // rotate this one 180 degree + + lightcone->set_angle(angle + 180.0f); lightcone->draw(context, pos, 0); context.set_target(DrawingContext::NORMAL); + + lights->set_angle(angle); + lights->draw(context, pos, 0); + + base->set_angle(angle); base->draw(context, pos, 0); + center->draw(context, pos, 0); context.pop_target(); diff --git a/src/object/spotlight.hpp b/src/object/spotlight.hpp index 4948fb674..520ad1a21 100644 --- a/src/object/spotlight.hpp +++ b/src/object/spotlight.hpp @@ -35,6 +35,7 @@ public: void draw(DrawingContext& context); private: + float angle; Sprite* center; Sprite* base; Sprite* lights; diff --git a/src/sprite/sprite.cpp b/src/sprite/sprite.cpp index 7a32c3fee..e14621f80 100644 --- a/src/sprite/sprite.cpp +++ b/src/sprite/sprite.cpp @@ -24,13 +24,15 @@ #include #include + +#include "video/surface.hpp" #include "sprite.hpp" #include "video/drawing_context.hpp" #include "log.hpp" #include "timer.hpp" Sprite::Sprite(SpriteData& newdata) - : data(newdata), frame(0), animation_loops(-1) + : data(newdata), frame(0), animation_loops(-1), angle(0.0f) { action = data.get_action("normal"); if(!action) @@ -103,8 +105,9 @@ Sprite::draw(DrawingContext& context, const Vector& pos, int layer) log_warning << "frame out of range: " << (int)frame << "/" << get_frames() << " at " << get_name() << "/" << get_action() << std::endl; else context.draw_surface(action->surfaces[(int)frame], - pos - Vector(action->x_offset, action->y_offset), - layer + action->z_order); + pos - Vector(action->x_offset, action->y_offset), + angle, + layer + action->z_order); } void @@ -178,4 +181,16 @@ Sprite::set_fps(float new_fps) action->fps = new_fps; } +void +Sprite::set_angle(float a) +{ + angle = a; +} + +float +Sprite::get_angle() const +{ + return angle; +} +/* EOF */ diff --git a/src/sprite/sprite.hpp b/src/sprite/sprite.hpp index df0f9c718..b97b65cde 100644 --- a/src/sprite/sprite.hpp +++ b/src/sprite/sprite.hpp @@ -24,11 +24,11 @@ #include #include -#include "video/surface.hpp" #include "math/vector.hpp" #include "math/rect.hpp" #include "sprite_data.hpp" +class Surface; class DrawingContext; class Sprite @@ -86,6 +86,12 @@ public: /** return current action's hitbox, relative to 0,0 */ Rect get_current_hitbox() const; + /** Set the angle of the sprite rotation in degree */ + void set_angle(float angle); + + /** Get the angle of the sprite rotation in degree */ + float get_angle() const; + /** Get current frame */ int get_frame() const { return (int)frame; } @@ -106,9 +112,10 @@ private: SpriteData& data; float frame; - int animation_loops; + int animation_loops; float last_ticks; - + float angle; + SpriteData::Action* action; }; diff --git a/src/video/drawing_context.cpp b/src/video/drawing_context.cpp index 8abfdc0c4..5dbad1869 100644 --- a/src/video/drawing_context.cpp +++ b/src/video/drawing_context.cpp @@ -70,7 +70,7 @@ DrawingContext::~DrawingContext() } void -DrawingContext::draw_surface(const Surface* surface, const Vector& position, +DrawingContext::draw_surface(const Surface* surface, const Vector& position, float angle, int layer) { assert(surface != 0); @@ -88,12 +88,20 @@ DrawingContext::draw_surface(const Surface* surface, const Vector& position, request.layer = layer; request.drawing_effect = transform.drawing_effect; request.alpha = transform.alpha; + request.angle = angle; request.request_data = const_cast (surface); requests->push_back(request); } void +DrawingContext::draw_surface(const Surface* surface, const Vector& position, + int layer) +{ + draw_surface(surface, position, 0.0f, layer); +} + +void DrawingContext::draw_surface_part(const Surface* surface, const Vector& source, const Vector& size, const Vector& dest, int layer) { @@ -319,7 +327,7 @@ DrawingContext::do_drawing() glLoadIdentity(); // FIXME: Add ambient light support here - glClearColor(0, 0, 0, 1); + glClearColor(0.5, 0.5, 0.5, 1); glClear(GL_COLOR_BUFFER_BIT); handle_drawing_requests(lightmap_requests); lightmap_requests.clear(); @@ -381,7 +389,10 @@ DrawingContext::handle_drawing_requests(DrawingRequests& requests) case SURFACE: { const Surface* surface = (const Surface*) i->request_data; - surface->draw(i->pos.x, i->pos.y, i->alpha, i->drawing_effect); + if (i->angle == 0.0f) + surface->draw(i->pos.x, i->pos.y, i->alpha, i->drawing_effect); + else + surface->draw(i->pos.x, i->pos.y, i->alpha, i->angle, i->drawing_effect); break; } case SURFACE_PART: diff --git a/src/video/drawing_context.hpp b/src/video/drawing_context.hpp index c65e0fb8f..4ed280688 100644 --- a/src/video/drawing_context.hpp +++ b/src/video/drawing_context.hpp @@ -61,9 +61,12 @@ class DrawingContext public: DrawingContext(); ~DrawingContext(); - + + /// Adds a drawing request for a surface into the request list. + void draw_surface(const Surface* surface, const Vector& position, + int layer); /// Adds a drawing request for a surface into the request list. - void draw_surface(const Surface* surface, const Vector& position, + void draw_surface(const Surface* surface, const Vector& position, float angle, int layer); /// Adds a drawing request for part of a surface. void draw_surface_part(const Surface* surface, const Vector& source, @@ -187,8 +190,13 @@ private: DrawingEffect drawing_effect; float alpha; Blend blend; + float angle; void* request_data; + + DrawingRequest() + : angle(0.0f) + {} bool operator<(const DrawingRequest& other) const { diff --git a/src/video/surface.cpp b/src/video/surface.cpp index 7414564bc..799372b27 100644 --- a/src/video/surface.cpp +++ b/src/video/surface.cpp @@ -130,6 +130,62 @@ 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, + 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; + + 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(); +} + +void +Surface::draw(float x, float y, float alpha, float angle, 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, + effect); +} + void Surface::draw(float x, float y, float alpha, DrawingEffect effect) const { diff --git a/src/video/surface.hpp b/src/video/surface.hpp index c1de2993c..8961606ed 100644 --- a/src/video/surface.hpp +++ b/src/video/surface.hpp @@ -51,6 +51,7 @@ private: float uv_right; float uv_bottom; + void draw(float x, float y, float alpha, float angle, DrawingEffect effect) const; void draw(float x, float y, float alpha, DrawingEffect effect) const; void draw_part(float src_x, float src_y, float dst_x, float dst_y, float width, float height,