Last active
April 20, 2021 15:13
-
-
Save ayyess/dc43be923ba2b5bf86f9 to your computer and use it in GitHub Desktop.
SFML SpriteBatch
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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 = ⌖ | |
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