Advertisement
krzat

sfml spritebatch

Feb 16th, 2013
329
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 4.81 KB | None | 0 0
  1. //SpriteBatch.hpp
  2. #pragma once
  3. #include <SFML/Graphics.hpp>
  4. #include <vector>
  5.  
  6. struct QueueItem
  7. {
  8.     unsigned int count;
  9.     const sf::Texture* texture;
  10. };
  11.  
  12. class SpriteBatch : public sf::Drawable
  13. {
  14. public:
  15.     SpriteBatch(void);
  16.     ~SpriteBatch(void);
  17.  
  18.     void begin();
  19.     void end();
  20.  
  21.     void draw(sf::Sprite& sprite);
  22.     void draw(const sf::Texture* texture, sf::Vector2f position, sf::IntRect rec, sf::Color color, sf::Vector2f scale,
  23.         sf::Vector2f origin, float rotation = 0);
  24.     void draw(const sf::Texture* texture, sf::FloatRect rec, sf::IntRect src, sf::Color color);
  25.  
  26.     virtual void draw(sf::RenderTarget& target, sf::RenderStates states) const;
  27.  
  28. private:
  29.     std::vector<QueueItem> textures;
  30.     std::vector<sf::Vertex> vertices;
  31.     int count;
  32.     bool active;
  33.     unsigned int queueCount;
  34.     const sf::Texture* activeTexture;
  35.  
  36.     int create(const sf::Texture* texture);
  37.     void enqueue();
  38. };
  39.  
  40. //SpriteBatch.cpp
  41.  
  42. #include "SpriteBatch.hpp"
  43. #include <cmath>
  44. #define M_PI 3.14159265358979323846
  45.  
  46. SpriteBatch::SpriteBatch(void) : count(0), active(false), queueCount(0), activeTexture(0)
  47. {
  48. }
  49.  
  50. SpriteBatch::~SpriteBatch(void)
  51. {
  52. }
  53.  
  54. void SpriteBatch::begin() {
  55.     if(active) throw std::exception("SpriteBatch is already active.");
  56.     vertices.clear();
  57.     count = 0;
  58.     textures.clear();
  59.     active = true;
  60. }
  61.  
  62. void SpriteBatch::end() {
  63.     if(!active) throw std::exception("SpriteBatch is not active.");
  64.     enqueue();
  65.     active = false;
  66. }
  67.  
  68. void SpriteBatch::draw(sf::RenderTarget& target, sf::RenderStates states) const
  69. {
  70.     int index = 0;
  71.     for(auto item : textures) {
  72.         states.texture = item.texture;
  73.         target.draw(&vertices[index], item.count, sf::PrimitiveType::Quads, states);
  74.         index += item.count;
  75.     }
  76. }
  77.  
  78. void SpriteBatch::draw(sf::Sprite& sprite)
  79. {
  80.     draw(
  81.         sprite.getTexture(), sprite.getPosition(), sprite.getTextureRect(),
  82.         sprite.getColor(), sprite.getScale(), sprite.getOrigin(), sprite.getRotation());
  83. }
  84.  
  85. void SpriteBatch::draw(const sf::Texture* texture, sf::Vector2f position, sf::IntRect rec,
  86.                        sf::Color color, sf::Vector2f scale, sf::Vector2f origin, float rotation /*= 0*/)
  87. {
  88.     int index = create(texture);
  89.     float _sin=0, _cos=1;
  90.  
  91.     if(rotation != 0) {
  92.         rotation = rotation / 180 * (float)M_PI;
  93.         _sin = sin(rotation);
  94.         _cos = cos(rotation);
  95.     }
  96.  
  97.     float pX = -origin.x * scale.x;
  98.     float pY = -origin.y * scale.y;
  99.  
  100.     sf::Vertex* ptr = &vertices[index];
  101.  
  102.     ptr->position.x = pX * _cos - pY * _sin + position.x;
  103.     ptr->position.y = pX * _sin + pY * _cos + position.y;
  104.     ptr->texCoords.x = (float)rec.left;
  105.     ptr->texCoords.y = (float)rec.top;
  106.     ptr->color = color;
  107.     ptr++;
  108.  
  109.     pX += scale.x;
  110.     ptr->position.x = pX * _cos - pY * _sin + position.x;
  111.     ptr->position.y = pX * _sin + pY * _cos + position.y;
  112.     ptr->texCoords.x = (float)(rec.left + rec.width);
  113.     ptr->texCoords.y = (float)rec.top;
  114.     ptr->color = color;
  115.     ptr++;
  116.  
  117.     pY += scale.y;
  118.     ptr->position.x = pX * _cos - pY * _sin + position.x;
  119.     ptr->position.y = pX * _sin + pY * _cos + position.y;
  120.     ptr->texCoords.x = (float)(rec.left + rec.width);
  121.     ptr->texCoords.y = (float)(rec.top + rec.height);
  122.     ptr->color = color;
  123.     ptr++;
  124.  
  125.     pX -= scale.x;
  126.     ptr->position.x = pX * _cos - pY * _sin + position.x;
  127.     ptr->position.y = pX * _sin + pY * _cos + position.y;
  128.     ptr->texCoords.x = (float)rec.left;
  129.     ptr->texCoords.y = (float)(rec.top + rec.height);
  130.     ptr->color = color;
  131. }
  132.  
  133. void SpriteBatch::draw(const sf::Texture* texture, sf::FloatRect rec, sf::IntRect src, sf::Color color)
  134. {
  135.     int index = create(texture);
  136.     sf::Vertex* ptr = &vertices[index];
  137.  
  138.     ptr->position.x = rec.left;
  139.     ptr->position.y = rec.top;
  140.     ptr->texCoords.x = (float)src.left;
  141.     ptr->texCoords.y = (float)src.top;
  142.     ptr->color = color;
  143.     ptr++;
  144.  
  145.     ptr->position.x = rec.left + rec.width;
  146.     ptr->position.y = rec.top;
  147.     ptr->texCoords.x = (float)(src.left + src.width);
  148.     ptr->texCoords.y = (float)(src.top);
  149.     ptr->color = color;
  150.     ptr++;
  151.  
  152.     ptr->position.x = rec.left + rec.width;
  153.     ptr->position.y = rec.top + rec.height;
  154.     ptr->texCoords.x = (float)(src.left + src.width);
  155.     ptr->texCoords.y = (float)(src.top + src.height);
  156.     ptr->color = color;
  157.     ptr++;
  158.  
  159.     ptr->position.x = rec.left;
  160.     ptr->position.y = rec.top + rec.height;
  161.     ptr->texCoords.x = (float)src.left;
  162.     ptr->texCoords.y = (float)(src.top + src.height);
  163.     ptr->color = color;
  164. }
  165.  
  166. int SpriteBatch::create(const sf::Texture* texture)
  167. {
  168.     if(!active) throw std::exception("SpriteBatch is not active.");
  169.     if(texture != activeTexture) {
  170.         enqueue();
  171.         activeTexture = texture;
  172.     }
  173.  
  174.     vertices.resize(vertices.size()+4);
  175.     queueCount += 4;
  176.  
  177.     return 4 * count++;
  178. }
  179.  
  180. void SpriteBatch::enqueue()
  181. {
  182.     if(queueCount > 0) {
  183.         QueueItem qi;
  184.         qi.texture = activeTexture;
  185.         activeTexture = NULL;
  186.         qi.count = queueCount;
  187.         textures.push_back(qi);
  188.         queueCount = 0;
  189.     }
  190.  
  191. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement