farmlands/src/graphics/SpriteRenderer.cpp

117 lines
2.7 KiB
C++

/*
* SpriteRenderer.cpp
*
* Created on: Nov 30, 2016
* Author: tibi
*/
#include <GameState.h>
#include <base/GameObject.h>
#include <base/Camera.h>
#include <graphics/backend/SdlRenderer.h>
#include <graphics/SpriteRenderer.h>
#include <utils/Assert.h>
#include <iostream>
using namespace farmlands::graphics::backend;
using namespace farmlands::resources;
namespace farmlands {
namespace graphics {
SpriteRenderer::SpriteRenderer()
: sprite(nullptr),
m_transform(nullptr),
m_context(nullptr)
{
}
SpriteRenderer::~SpriteRenderer()
{
delete sprite;
}
base::Component* SpriteRenderer::clone()
{
SpriteRenderer* clone = new SpriteRenderer();
clone->sprite = new base::Sprite(*sprite);
return clone;
}
void SpriteRenderer::onInitialize()
{
Assert(gameObject != nullptr, "Component not properly initialized!");
m_transform = gameObject->component<base::Transform>();
m_context = &GameState::current().renderContext;
}
void SpriteRenderer::onRender()
{
float posX = m_context->xToScreen(m_transform->globalX());
float posY = m_context->yToScreen(m_transform->globalY());
float w = sprite->currentFrame().width * m_context->viewport.pixelsPerUnitX;
float h = sprite->currentFrame().height * m_context->viewport.pixelsPerUnitY;
// Compute destination rectangle
float scale = m_context->camera()->scale;
SDL_Rect dest;
dest.x = posX - sprite->anchorX * w * scale;
dest.y = posY - sprite->anchorY * h * scale;
dest.w = w * scale;
dest.h = h * scale;
if (m_context->visible(dest))
{
// Obtain texture
int texId = sprite->currentFrame().tileSetId;
SDL_Texture* texture = resources::ResourceManager::instance().texture(texId);
// Compute source rectangle
SDL_Rect src;
getCell(texture, sprite->currentFrame().tileSetCell, &src.x, &src.y);
src.w = w;
src.h = h;
// Draw
SdlRenderer::instance().renderTexture(texture, &src, &dest);
}
}
void SpriteRenderer::onPostRender()
{
float animFps = GameState::current().config->animationFps;
float deltaTime = GameState::current().elapsedTime;
sprite->advanceTime(animFps * deltaTime);
}
void SpriteRenderer::getCell(SDL_Texture* texture, uint32_t cell, int* outX, int* outY)
{
int texWidth, texHeight;
SdlRenderer::instance().getTextureSize(texture, &texWidth, &texHeight);
int ppuX = m_context->viewport.pixelsPerUnitX;
int ppuY = m_context->viewport.pixelsPerUnitY;
// Compute texture coordinates
*outX = (cell * ppuX) % texWidth;
*outY = ((cell * ppuX) / texWidth) * ppuY;
}
void SpriteRenderer::dump(unsigned level)
{
for (unsigned i = 0; i < level; i++)
std::cout<<" ";
std::cout << " .Component: SpriteRenderer sprite=";
std::cout << sprite->name <<"\n";
}
} /* namespace graphics */
} /* namespace farmlands */