1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155
|
#include "BaseSprite.h"
#include "RenderCommand.h"
#include "../tracy.h"
namespace nCine
{
BaseSprite::BaseSprite(SceneNode* parent, Texture* texture, float xx, float yy)
: DrawableNode(parent, xx, yy), texture_(texture), texRect_(0, 0, 0, 0), flippedX_(false), flippedY_(false), instanceBlock_(nullptr)
{
renderCommand_.GetMaterial().SetBlendingEnabled(true);
}
BaseSprite::BaseSprite(SceneNode* parent, Texture* texture, Vector2f position)
: BaseSprite(parent, texture, position.X, position.Y)
{
}
void BaseSprite::setSize(float width, float height)
{
// Update anchor points when size changes
if (anchorPoint_.X != 0.0f) {
anchorPoint_.X = (anchorPoint_.X / width_) * width;
}
if (anchorPoint_.Y != 0.0f) {
anchorPoint_.Y = (anchorPoint_.Y / height_) * height;
}
width_ = width;
height_ = height;
dirtyBits_.set(DirtyBitPositions::SizeBit);
dirtyBits_.set(DirtyBitPositions::AabbBit);
}
/*! \note If you set a texture that is already assigned, this method would be equivalent to `resetTexture()` */
void BaseSprite::setTexture(Texture* texture)
{
// Allow self-assignment to take into account the case where the texture stays the same but it loads new data
textureHasChanged(texture);
texture_ = texture;
dirtyBits_.set(DirtyBitPositions::TextureBit);
}
/*! \note Use this method when the content of the currently assigned texture changes */
void BaseSprite::resetTexture()
{
textureHasChanged(texture_);
dirtyBits_.set(DirtyBitPositions::TextureBit);
}
void BaseSprite::setTexRect(const Recti& rect)
{
texRect_ = rect;
setSize(static_cast<float>(rect.W), static_cast<float>(rect.H));
if (flippedX_) {
texRect_.X += texRect_.W;
texRect_.W *= -1;
}
if (flippedY_) {
texRect_.Y += texRect_.H;
texRect_.H *= -1;
}
dirtyBits_.set(DirtyBitPositions::TextureBit);
}
void BaseSprite::setFlippedX(bool flippedX)
{
if (flippedX_ != flippedX) {
texRect_.X += texRect_.W;
texRect_.W *= -1;
flippedX_ = flippedX;
dirtyBits_.set(DirtyBitPositions::TextureBit);
}
}
void BaseSprite::setFlippedY(bool flippedY)
{
if (flippedY_ != flippedY) {
texRect_.Y += texRect_.H;
texRect_.H *= -1;
flippedY_ = flippedY;
dirtyBits_.set(DirtyBitPositions::TextureBit);
}
}
BaseSprite::BaseSprite(const BaseSprite& other)
: DrawableNode(other), texture_(other.texture_), texRect_(other.texRect_),
flippedX_(other.flippedX_), flippedY_(other.flippedY_), instanceBlock_(nullptr)
{
}
void BaseSprite::shaderHasChanged()
{
renderCommand_.GetMaterial().ReserveUniformsDataMemory();
instanceBlock_ = renderCommand_.GetMaterial().UniformBlock(Material::InstanceBlockName);
GLUniformCache* textureUniform = renderCommand_.GetMaterial().Uniform(Material::TextureUniformName);
if (textureUniform != nullptr && textureUniform->GetIntValue(0) != 0) {
textureUniform->SetIntValue(0); // GL_TEXTURE0
}
dirtyBits_.set(DirtyBitPositions::TransformationBit);
dirtyBits_.set(DirtyBitPositions::ColorBit);
dirtyBits_.set(DirtyBitPositions::SizeBit);
dirtyBits_.set(DirtyBitPositions::TextureBit);
}
void BaseSprite::updateRenderCommand()
{
ZoneScopedC(0x81A861);
if (dirtyBits_.test(DirtyBitPositions::TransformationUploadBit)) {
renderCommand_.SetTransformation(worldMatrix_);
//dirtyBits_.reset(DirtyBitPositions::TransformationUploadBit);
}
if (dirtyBits_.test(DirtyBitPositions::ColorUploadBit)) {
GLUniformCache* colorUniform = instanceBlock_->GetUniform(Material::ColorUniformName);
if (colorUniform != nullptr) {
colorUniform->SetFloatVector(absColor().Data());
}
//dirtyBits_.reset(DirtyBitPositions::ColorUploadBit);
}
if (dirtyBits_.test(DirtyBitPositions::SizeBit)) {
GLUniformCache* spriteSizeUniform = instanceBlock_->GetUniform(Material::SpriteSizeUniformName);
if (spriteSizeUniform != nullptr) {
spriteSizeUniform->SetFloatValue(width_, height_);
}
dirtyBits_.reset(DirtyBitPositions::SizeBit);
}
if (dirtyBits_.test(DirtyBitPositions::TextureBit)) {
if (texture_ != nullptr) {
renderCommand_.GetMaterial().SetTexture(*texture_);
GLUniformCache* texRectUniform = instanceBlock_->GetUniform(Material::TexRectUniformName);
if (texRectUniform != nullptr) {
const Vector2i texSize = texture_->GetSize();
const float texScaleX = texRect_.W / float(texSize.X);
const float texBiasX = texRect_.X / float(texSize.X);
const float texScaleY = texRect_.H / float(texSize.Y);
const float texBiasY = texRect_.Y / float(texSize.Y);
texRectUniform->SetFloatValue(texScaleX, texBiasX, texScaleY, texBiasY);
}
} else {
renderCommand_.GetMaterial().SetTexture(nullptr);
}
dirtyBits_.reset(DirtyBitPositions::TextureBit);
}
}
}
|