Skip to content

Instantly share code, notes, and snippets.

@ayyess
Last active April 20, 2021 15:13
Show Gist options
  • Save ayyess/dc43be923ba2b5bf86f9 to your computer and use it in GitHub Desktop.
Save ayyess/dc43be923ba2b5bf86f9 to your computer and use it in GitHub Desktop.
SFML SpriteBatch
#include <SFML/Graphics.hpp>
class SpriteBatch
{
public:
SpriteBatch(sf::RenderTarget &rt);
~SpriteBatch(void);
void display(bool reset = true);
void draw(sf::Sprite &sprite);
void draw(const sf::Texture *texture, sf::Vector2f position, sf::IntRect rec, sf::Color color, sf::Vector2f scale, sf::Vector2f origin, float rotation = 0);
void draw(const sf::Texture *texture, sf::FloatRect dest, sf::IntRect rec, sf::Color color);
int batchCount;
private:
sf::RenderTarget *rt;
sf::RenderStates state;
sf::Vertex *vertices;
int count;
int capacity;
};
#include <math.h>
const float Pi = 3.14159265;
const int MaxCapacity = 400000;
const int LookupSize = 512;
float getSin[LookupSize];
float getCos[LookupSize];
bool initialized = false;
void create_lookup()
{
for(int i=0; i < LookupSize; i++)
{
getSin[i] = sin(i * Pi / LookupSize * 2);
getCos[i] = cos(i * Pi / LookupSize * 2);
}
initialized = true;
}
SpriteBatch::SpriteBatch(sf::RenderTarget &target)
{
count = 0;
capacity = 20000;
vertices = new sf::Vertex[capacity];
if(!initialized) {
create_lookup();
}
rt = &target;
batchCount = 0;
}
SpriteBatch::~SpriteBatch(void)
{
delete[] vertices;
vertices = NULL;
}
void SpriteBatch::draw(sf::Sprite &sprite)
{
#if 1
draw(sprite.getTexture(), sprite.getPosition(), sprite.getTextureRect(), sprite.getColor(), sprite.getScale(), sprite.getOrigin(), sprite.getRotation());
#else
if (sprite.getTexture() != state.texture)
{
display(false);
state.texture = sprite.getTexture();
}
if (count*4 >= capacity)
{
display(false);
if(capacity < MaxCapacity)
{
delete[] vertices;
capacity *= 2;
if(capacity > MaxCapacity) capacity = MaxCapacity;
vertices = new sf::Vertex[capacity];
}
}
vertices[count * 4 + 0] = sprite.getVertex(0);
vertices[count * 4 + 0].position = sprite.getTransform() * vertices[count * 4 + 0].position;
vertices[count * 4 + 1] = sprite.getVertex(1);
vertices[count * 4 + 1].position = sprite.getTransform() * vertices[count * 4 + 1].position;
vertices[count * 4 + 2] = sprite.getVertex(2);
vertices[count * 4 + 2].position = sprite.getTransform() * vertices[count * 4 + 2].position;
vertices[count * 4 + 3] = sprite.getVertex(3);
vertices[count * 4 + 3].position = sprite.getTransform() * vertices[count * 4 + 3].position;
count++;
#endif
}
void SpriteBatch::display(bool reset)
{
rt->draw(vertices, count * 4, sf::PrimitiveType::Quads, state);
count = 0;
if(reset) {
state = sf::RenderStates();
}
++batchCount;
}
void SpriteBatch::draw(const sf::Texture *texture, sf::Vector2f position, sf::IntRect rec, sf::Color color, sf::Vector2f scale, sf::Vector2f origin, float rotation)
{
if (texture != state.texture)
{
display(false);
state.texture = texture;
}
if (count*4 >= capacity)
{
display(false);
if(capacity < MaxCapacity)
{
delete[] vertices;
capacity *= 2;
if(capacity > MaxCapacity) capacity = MaxCapacity;
vertices = new sf::Vertex[capacity];
}
}
int rot = (int)(rotation / 360 * LookupSize) & (LookupSize -1);
float _sin = getSin[rot];
float _cos = getCos[rot];
/*
float _sin = 0, _cos = 1;
if (rotation != 0)
{
rotation = rotation * Pi / 180;
_sin = sin(rotation);
_cos = cos(rotation);
}*/
origin.x *= scale.x;
origin.y *= scale.y;
scale.x *= rec.width;
scale.y *= rec.height;
sf::Vertex v;
v.color = color;
float pX, pY;
pX = -origin.x;
pY = -origin.y;
v.position.x = pX * _cos - pY * _sin + position.x;
v.position.y = pX * _sin + pY * _cos + position.y;
v.texCoords.x = rec.left;
v.texCoords.y = rec.top;
vertices[count * 4 + 0] = v;
pX += scale.x;
v.position.x = pX * _cos - pY * _sin + position.x;
v.position.y = pX * _sin + pY * _cos + position.y;
v.texCoords.x += rec.width;
vertices[count * 4 + 1] = v;
pY += scale.y;
v.position.x = pX * _cos - pY * _sin + position.x;
v.position.y = pX * _sin + pY * _cos + position.y;
v.texCoords.y += rec.height;
vertices[count * 4 + 2] = v;
pX -= scale.x;
v.position.x = pX * _cos - pY * _sin + position.x;
v.position.y = pX * _sin + pY * _cos + position.y;
v.texCoords.x -= rec.width;
vertices[count * 4 + 3] = v;
count++;
}
void SpriteBatch::draw(const sf::Texture *texture, sf::FloatRect dest, sf::IntRect rec, sf::Color color)
{
draw(texture, sf::Vector2f(dest.left, dest.top), rec, color, sf::Vector2f(1,1), sf::Vector2f(0,0), 0);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment