From d4d4e5e7e87c9d3710ca91d5e3e57de03f03f6be Mon Sep 17 00:00:00 2001 From: Ricardo Cruz Date: Mon, 31 May 2004 13:02:21 +0000 Subject: [PATCH] Added support for drawing effects again. We really need a include.h file with major includes, or we could just put the includes into the defines.h. SVN-Revision: 1372 --- src/badguy.cpp | 16 +++--- src/screen/drawing_context.cpp | 11 +++-- src/screen/drawing_context.h | 9 +++- src/screen/texture.cpp | 110 ++++++++++++++++++++++++++++++++++------- src/screen/texture.h | 23 ++++++--- src/sprite.cpp | 12 +---- src/sprite.h | 4 +- 7 files changed, 132 insertions(+), 53 deletions(-) diff --git a/src/badguy.cpp b/src/badguy.cpp index 97913c736..8a0d66b78 100644 --- a/src/badguy.cpp +++ b/src/badguy.cpp @@ -984,19 +984,17 @@ BadGuy::draw(DrawingContext& context) if(sprite == 0) return; - sprite->draw(context, Vector(base.x, base.y), LAYER_OBJECTS); -#if 0 - Sprite* sprite = (dir == LEFT) ? sprite_left : sprite_right; if(dying == DYING_FALLING && physic.get_velocity_y() < 0) - sprite->draw(viewport.world2screen(Vector(base.x, base.y)), SD_VERTICAL_FLIP); + sprite->draw(context, Vector(base.x, base.y), LAYER_OBJECTS, VERTICAL_FLIP); else - sprite->draw(viewport.world2screen(Vector(base.x, base.y))); -#endif + sprite->draw(context, Vector(base.x, base.y), LAYER_OBJECTS); - float scroll_x = context.get_translation().x; - float scroll_y = context.get_translation().y; - if(debug_mode) + if(debug_mode) // draw hotpoint + { + float scroll_x = context.get_translation().x; + float scroll_y = context.get_translation().y; fillrect(base.x - scroll_x, base.y - scroll_y, base.width, base.height, 75,0,75, 150); + } } void diff --git a/src/screen/drawing_context.cpp b/src/screen/drawing_context.cpp index 52bb81eeb..5a424ca93 100644 --- a/src/screen/drawing_context.cpp +++ b/src/screen/drawing_context.cpp @@ -17,7 +17,7 @@ DrawingContext::~DrawingContext() void DrawingContext::draw_surface(const Surface* surface, const Vector& position, - int layer) + int layer, uint32_t drawing_effect) { assert(surface != 0); @@ -27,13 +27,14 @@ DrawingContext::draw_surface(const Surface* surface, const Vector& position, request.layer = layer; request.request_data = const_cast (surface); request.pos = transform.apply(position); + request.drawing_effect = drawing_effect; drawingrequests.push_back(request); } void DrawingContext::draw_surface_part(const Surface* surface, const Vector& source, - const Vector& size, const Vector& dest, int layer) + const Vector& size, const Vector& dest, int layer, uint32_t drawing_effect) { assert(surface != 0); @@ -42,6 +43,7 @@ DrawingContext::draw_surface_part(const Surface* surface, const Vector& source, request.type = SURFACE_PART; request.layer = layer; request.pos = transform.apply(dest); + request.drawing_effect = drawing_effect; SurfacePartRequest* surfacepartrequest = new SurfacePartRequest(); surfacepartrequest->size = size; @@ -133,7 +135,8 @@ DrawingContext::draw_surface_part(DrawingRequest& request) surfacepartrequest->surface->impl->draw_part( surfacepartrequest->source.x, surfacepartrequest->source.y, request.pos.x, request.pos.y, - surfacepartrequest->size.x, surfacepartrequest->size.y, 255); + surfacepartrequest->size.x, surfacepartrequest->size.y, 255, + request.drawing_effect); delete surfacepartrequest; } @@ -271,7 +274,7 @@ DrawingContext::do_drawing() case SURFACE: { const Surface* surface = (const Surface*) i->request_data; - surface->impl->draw(i->pos.x, i->pos.y, 255); + surface->impl->draw(i->pos.x, i->pos.y, 255, i->drawing_effect); break; } case SURFACE_PART: diff --git a/src/screen/drawing_context.h b/src/screen/drawing_context.h index c763cfb2b..eef845add 100644 --- a/src/screen/drawing_context.h +++ b/src/screen/drawing_context.h @@ -1,9 +1,11 @@ #ifndef __DRAWINGCONTEXT_H__ #define __DRAWINGCONTEXT_H__ +#include #include #include #include "vector.h" +#include "screen.h" #include class Surface; @@ -50,10 +52,12 @@ public: ~DrawingContext(); /** Adds a drawing request for a surface into the request list */ - void draw_surface(const Surface* surface, const Vector& position, int layer); + void draw_surface(const Surface* surface, const Vector& position, int layer, + uint32_t drawing_effect = NONE_EFFECT); /** Adds a drawing request for part of a surface */ void draw_surface_part(const Surface* surface, const Vector& source, - const Vector& size, const Vector& dest, int layer); + const Vector& size, const Vector& dest, int layer, + uint32_t drawing_effect = NONE_EFFECT); /** draws a text */ void draw_text(Font* font, const std::string& text, const Vector& position, int layer); @@ -126,6 +130,7 @@ private: struct DrawingRequest { int layer; + uint32_t drawing_effect; RequestType type; Vector pos; diff --git a/src/screen/texture.cpp b/src/screen/texture.cpp index 681329673..f7a50e940 100644 --- a/src/screen/texture.cpp +++ b/src/screen/texture.cpp @@ -448,11 +448,14 @@ SurfaceOpenGL::create_gl(SDL_Surface * surf, GLuint * tex) } int -SurfaceOpenGL::draw(float x, float y, Uint8 alpha) +SurfaceOpenGL::draw(float x, float y, Uint8 alpha, uint32_t effect) { float pw = power_of_two(w); float ph = power_of_two(h); + if(effect & SEMI_TRANSPARENT) + alpha = 128; + glEnable(GL_TEXTURE_2D); glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); @@ -462,13 +465,35 @@ SurfaceOpenGL::draw(float x, float y, Uint8 alpha) glBindTexture(GL_TEXTURE_2D, gl_texture); glBegin(GL_QUADS); - glTexCoord2f(0, 0); - glVertex2f(x, y); - glTexCoord2f((float)w / pw, 0); - glVertex2f((float)w+x, y); - glTexCoord2f((float)w / pw, (float)h / ph); glVertex2f((float)w+x, (float)h+y); - glTexCoord2f(0, (float)h / ph); - glVertex2f(x, (float)h+y); + + if(effect & VERTICAL_FLIP) + { + glTexCoord2f(0, 0); + glVertex2f(x, (float)h+y); + + glTexCoord2f((float)w / pw, 0); + glVertex2f((float)w+x, (float)h+y); + + glTexCoord2f((float)w / pw, (float)h / ph); + glVertex2f((float)w+x, y); + + glTexCoord2f(0, (float)h / ph); + glVertex2f(x, y); + } + else + { + glTexCoord2f(0, 0); + glVertex2f(x, y); + + glTexCoord2f((float)w / pw, 0); + glVertex2f((float)w+x, y); + + glTexCoord2f((float)w / pw, (float)h / ph); + glVertex2f((float)w+x, (float)h+y); + + glTexCoord2f(0, (float)h / ph); + glVertex2f(x, (float)h+y); + } glEnd(); glDisable(GL_TEXTURE_2D); @@ -478,11 +503,14 @@ SurfaceOpenGL::draw(float x, float y, Uint8 alpha) } int -SurfaceOpenGL::draw_part(float sx, float sy, float x, float y, float w, float h, Uint8 alpha) +SurfaceOpenGL::draw_part(float sx, float sy, float x, float y, float w, float h, Uint8 alpha, uint32_t effect) { float pw = power_of_two(int(this->w)); float ph = power_of_two(int(this->h)); + if(effect & SEMI_TRANSPARENT) + alpha = 128; + glBindTexture(GL_TEXTURE_2D, gl_texture); glEnable(GL_BLEND); @@ -494,14 +522,36 @@ SurfaceOpenGL::draw_part(float sx, float sy, float x, float y, float w, float h, glBegin(GL_QUADS); - glTexCoord2f(sx / pw, sy / ph); - glVertex2f(x, y); - glTexCoord2f((float)(sx + w) / pw, sy / ph); - glVertex2f(w+x, y); - glTexCoord2f((sx+w) / pw, (sy+h) / ph); - glVertex2f(w +x, h+y); - glTexCoord2f(sx / pw, (float)(sy+h) / ph); - glVertex2f(x, h+y); + + if(effect & VERTICAL_FLIP) + { + glTexCoord2f(sx / pw, sy / ph); + glVertex2f(x, y); + + glTexCoord2f((float)(sx + w) / pw, sy / ph); + glVertex2f(w+x, y); + + glTexCoord2f((sx+w) / pw, (sy+h) / ph); + glVertex2f(w +x, h+y); + + glTexCoord2f(sx / pw, (float)(sy+h) / ph); + glVertex2f(x, h+y); + } + else + { + glTexCoord2f(sx / pw, (float)(sy+h) / ph); + glVertex2f(x, h+y); + + glTexCoord2f((sx+w) / pw, (sy+h) / ph); + glVertex2f(w +x, h+y); + + glTexCoord2f((float)(sx + w) / pw, sy / ph); + glVertex2f(w+x, y); + + glTexCoord2f(sx / pw, sy / ph); + glVertex2f(x, y); + } + glEnd(); glDisable(GL_TEXTURE_2D); @@ -569,7 +619,7 @@ SurfaceSDL::SurfaceSDL(const std::string& file, int x, int y, int w, int h, int } int -SurfaceSDL::draw(float x, float y, Uint8 alpha) +SurfaceSDL::draw(float x, float y, Uint8 alpha, uint32_t effect) { SDL_Rect dest; @@ -578,6 +628,17 @@ SurfaceSDL::draw(float x, float y, Uint8 alpha) dest.w = w; dest.h = h; + if(effect & SEMI_TRANSPARENT) + alpha = 128; + + if(effect & VERTICAL_FLIP) // FIXME: feel free to replace this hack + { + for(float sy = 0; sy < h; sy++) + if(draw_part(0, sy, x, y+(h-sy), w, 1, alpha, NONE_EFFECT) == -2) + return -2; + return 0; + } + if(alpha != 255) { /* Create a Surface, make it using colorkey, blit surface into temp, apply alpha @@ -610,7 +671,7 @@ SurfaceSDL::draw(float x, float y, Uint8 alpha) } int -SurfaceSDL::draw_part(float sx, float sy, float x, float y, float w, float h, Uint8 alpha) +SurfaceSDL::draw_part(float sx, float sy, float x, float y, float w, float h, Uint8 alpha, uint32_t effect) { SDL_Rect src, dest; @@ -624,6 +685,17 @@ SurfaceSDL::draw_part(float sx, float sy, float x, float y, float w, float h, Ui dest.w = (int)w; dest.h = (int)h; + if(effect & SEMI_TRANSPARENT) + alpha = 128; + + if(effect & VERTICAL_FLIP) // FIXME: feel free to replace this hack + { + for(float sy_ = sy; sy_ < h; sy_++) + if(draw_part(sx, sy_, x, y+(h-sy_), w, 1, alpha, NONE_EFFECT) == -2) + return -2; + return 0; + } + if(alpha != 255) { /* Create a Surface, make it using colorkey, blit surface into temp, apply alpha diff --git a/src/screen/texture.h b/src/screen/texture.h index ef6902713..84cdc13b9 100644 --- a/src/screen/texture.h +++ b/src/screen/texture.h @@ -27,6 +27,7 @@ #include #endif +#include #include #include "screen.h" #include "vector.h" @@ -38,6 +39,16 @@ class SurfaceSDL; class SurfaceOpenGL; class DrawingContext; +/// bitset for drawing effects +enum { + /** Draw the Surface upside down */ + NONE_EFFECT = 0x0000, + /** Draw the Surface upside down */ + VERTICAL_FLIP = 0x0001, + /** Draw the Surface with alpha equal to 128 */ + SEMI_TRANSPARENT = 0x0002 + }; + /** This class holds all the data necessary to construct a surface */ class SurfaceData { @@ -105,8 +116,8 @@ public: virtual ~SurfaceImpl(); /** Return 0 on success, -2 if surface needs to be reloaded */ - virtual int draw(float x, float y, Uint8 alpha) = 0; - virtual int draw_part(float sx, float sy, float x, float y, float w, float h, Uint8 alpha) = 0; + virtual int draw(float x, float y, Uint8 alpha, uint32_t effect = NONE_EFFECT) = 0; + virtual int draw_part(float sx, float sy, float x, float y, float w, float h, Uint8 alpha, uint32_t effect = NONE_EFFECT) = 0; #if 0 virtual int draw_stretched(float x, float y, int w, int h, Uint8 alpha, bool update) = 0; #endif @@ -123,8 +134,8 @@ public: SurfaceSDL(const std::string& file, int x, int y, int w, int h, int use_alpha); virtual ~SurfaceSDL(); - int draw(float x, float y, Uint8 alpha); - int draw_part(float sx, float sy, float x, float y, float w, float h, Uint8 alpha); + int draw(float x, float y, Uint8 alpha, uint32_t effect = NONE_EFFECT); + int draw_part(float sx, float sy, float x, float y, float w, float h, Uint8 alpha, uint32_t effect = NONE_EFFECT); #if 0 int draw_stretched(float x, float y, int w, int h, Uint8 alpha); #endif @@ -142,8 +153,8 @@ public: SurfaceOpenGL(const std::string& file, int x, int y, int w, int h, int use_alpha); virtual ~SurfaceOpenGL(); - int draw(float x, float y, Uint8 alpha); - int draw_part(float sx, float sy, float x, float y, float w, float h, Uint8 alpha); + int draw(float x, float y, Uint8 alpha, uint32_t effect = NONE_EFFECT); + int draw_part(float sx, float sy, float x, float y, float w, float h, Uint8 alpha, uint32_t effect = NONE_EFFECT); #if 0 int draw_stretched(float x, float y, int w, int h, Uint8 alpha); #endif diff --git a/src/sprite.cpp b/src/sprite.cpp index 3e8a553fe..68315f193 100644 --- a/src/sprite.cpp +++ b/src/sprite.cpp @@ -75,7 +75,7 @@ Sprite::update(float /*delta*/) void Sprite::draw(DrawingContext& context, const Vector& pos, int layer, - int special_drawing) + uint32_t drawing_effect) { time = SDL_GetTicks(); unsigned int frame = get_current_frame(); @@ -84,15 +84,7 @@ Sprite::draw(DrawingContext& context, const Vector& pos, int layer, { Surface* surface = surfaces[frame]; -#if 0 // TODO - if(special_drawing == SD_SEMI_TRANSPARENT) - surfaces[frame]->draw(x - x_hotspot, y - y_hotspot, 128); - if(special_drawing == SD_VERTICAL_FLIP) - surfaces[frame]->draw(x - x_hotspot, y - y_hotspot, 255, true); - else - surfaces[frame]->draw(x - x_hotspot, y - y_hotspot); -#endif - context.draw_surface(surface, pos - Vector(x_hotspot, y_hotspot), layer); + context.draw_surface(surface, pos - Vector(x_hotspot, y_hotspot), layer, drawing_effect); } } diff --git a/src/sprite.h b/src/sprite.h index 1c5361806..62dba8f19 100644 --- a/src/sprite.h +++ b/src/sprite.h @@ -26,8 +26,6 @@ #include "screen/texture.h" #include "vector.h" -enum SpecialDrawing { SD_NONE, SD_VERTICAL_FLIP, SD_SEMI_TRANSPARENT }; - class Sprite { private: @@ -59,7 +57,7 @@ class Sprite /** Update the sprite and process to the next frame */ void update(float delta); void draw(DrawingContext& context, const Vector& pos, int layer, - int special_drawing = SD_NONE); + uint32_t drawing_effect = NONE_EFFECT); int get_current_frame() const; float get_fps() { return fps; } ; -- 2.11.0