separate nolok sprite
[supertux.git] / src / video / drawing_context.hpp
index f105ea1..dccd31b 100644 (file)
 #include <string>
 #include <stdint.h>
 
+#include <GL/gl.h>
 #include <SDL.h>
 #include <stdint.h>
+#include <memory>
 
 #include "math/vector.hpp"
-#include "video/screen.hpp"
-#include "video/surface.hpp"
-#include "video/font.hpp"
+#include "surface.hpp"
+#include "font.hpp"
+#include "color.hpp"
 
 class Surface;
+class Texture;
 
 // some constants for predefined layer values
 enum {
@@ -46,7 +49,6 @@ enum {
   LAYER_GUI         = 500
 };
 
-/// Handles drawing of things.
 /**
  * This class provides functions for drawing things on screen. It also
  * maintains a stack of transforms that are applied to graphics.
@@ -54,7 +56,7 @@ enum {
 class DrawingContext
 {
 public:
-  DrawingContext(SDL_Surface* targetsurface = 0);
+  DrawingContext();
   ~DrawingContext();
   
   /// Adds a drawing request for a surface into the request list.
@@ -73,10 +75,10 @@ public:
   void draw_center_text(const Font* font, const std::string& text,
                         const Vector& position, int layer);
   /// Draws a color gradient onto the whole screen */
-  void draw_gradient(Color from, Color to, int layer);
+  void draw_gradient(const Color& from, const Color& to, int layer);
   /// Fills a rectangle.
   void draw_filled_rect(const Vector& topleft, const Vector& size,
-                        Color color, int layer);
+                        const Color& color, int layer);
   
   /// Processes all pending drawing requests and flushes the list.
   void do_drawing();
@@ -91,27 +93,31 @@ public:
   void pop_transform();
   
   /// Apply that effect in the next draws (effects are listed on surface.h).
-  void set_drawing_effect(uint32_t effect);
+  void set_drawing_effect(DrawingEffect effect);
   /// return currently applied drawing effect
-  uint32_t get_drawing_effect() const;
-  /// apply that zoom in the next draws */
-  void set_zooming(float zoom);
-  /// apply that alpha in the next draws */
-  void set_alpha(uint8_t alpha);
+  DrawingEffect get_drawing_effect() const;
+  /// apply that alpha in the next draws (1.0 means fully opaque) */
+  void set_alpha(float alpha);
   /// return currently set alpha
-  uint8_t get_alpha() const;
+  float get_alpha() const;
+
+  enum Target {
+    NORMAL, LIGHTMAP
+  };
+  void push_target();
+  void pop_target();
+  void set_target(Target target);
   
 private:
   class Transform
   {
   public:
     Vector translation;
-    uint32_t drawing_effect;
-    float zoom;
-    uint8_t alpha;
+    DrawingEffect drawing_effect;
+    float alpha;
     
     Transform()
-      : drawing_effect(NONE_EFFECT), zoom(1), alpha(255)
+      : drawing_effect(NO_EFFECT), alpha(1.0f)
     { }
     
     Vector apply(const Vector& v) const
@@ -124,6 +130,19 @@ private:
   std::vector<Transform> transformstack;
   /// the currently active transform
   Transform transform;
+
+  class Blend
+  {
+  public:
+    GLenum sfactor;
+    GLenum dfactor;
+    
+    Blend()
+      : sfactor(GL_SRC_ALPHA), dfactor(GL_ONE_MINUS_SRC_ALPHA)
+    {}
+  };
+  std::vector<Blend> blend_stack;
+  Blend blend_mode;
   
   enum RequestType
   {
@@ -161,9 +180,9 @@ private:
     Vector pos;                
     
     int layer;
-    uint32_t drawing_effect;
-    float zoom;
-    int alpha;
+    DrawingEffect drawing_effect;
+    float alpha;
+    Blend blend;
     
     void* request_data;
     
@@ -172,17 +191,27 @@ private:
       return layer < other.layer;
     }
   };
+
+  typedef std::vector<DrawingRequest> DrawingRequests;
   
+  void handle_drawing_requests(DrawingRequests& requests);
   void draw_surface_part(DrawingRequest& request);
   void draw_text(DrawingRequest& request);
   void draw_text_center(DrawingRequest& request);
   void draw_gradient(DrawingRequest& request);
   void draw_filled_rect(DrawingRequest& request);
   
-  typedef std::vector<DrawingRequest> DrawingRequests;
-  DrawingRequests drawingrequests;
+  DrawingRequests drawing_requests;
+  DrawingRequests lightmap_requests;
+
+  DrawingRequests* requests;
 
   SDL_Surface* screen;
+  Target target;
+  std::vector<Target> target_stack;
+  Texture* lightmap;
+  int lightmap_width, lightmap_height;
+  float lightmap_uv_right, lightmap_uv_bottom;
 };
 
 #endif