修改底层渲染为OpenGL
This commit is contained in:
@@ -1,25 +1,35 @@
|
||||
#include "Sprite.h"
|
||||
#include "EngineCore/Game.h"
|
||||
#include "Text.h"
|
||||
#include "EngineFrame/Render/RenderManager.h"
|
||||
|
||||
void Sprite::Init()
|
||||
{
|
||||
this->Size = m_texture->TextureSize;
|
||||
this->Size = m_texture->getSize();
|
||||
RenderBase::Init();
|
||||
}
|
||||
|
||||
void Sprite::SetTexture(RefPtr<Texture> texture)
|
||||
{
|
||||
m_texture = texture;
|
||||
Init();
|
||||
CalcRenderInfoLogic(); // 第一次计算
|
||||
}
|
||||
|
||||
Sprite::Sprite(std::string imgPath, int Index)
|
||||
{
|
||||
this->imgPath = imgPath;
|
||||
this->Index = Index;
|
||||
m_texture = new Texture(imgPath, Index);
|
||||
m_texture = new Texture();
|
||||
m_texture->Init(imgPath, Index);
|
||||
Init();
|
||||
CalcRenderInfoLogic(); // 第一次计算
|
||||
}
|
||||
|
||||
Sprite::Sprite(std::string PngPath)
|
||||
{
|
||||
m_texture = new Texture(PngPath);
|
||||
m_texture = new Texture();
|
||||
m_texture->Init(PngPath);
|
||||
Init();
|
||||
CalcRenderInfoLogic(); // 第一次计算
|
||||
}
|
||||
@@ -35,6 +45,19 @@ RefPtr<Texture> Sprite::GetTexture()
|
||||
|
||||
void Sprite::CalcRenderInfoLogic()
|
||||
{
|
||||
// 获取至在最终的父对象检查是否显示
|
||||
BaseNode *parentNode = this->GetParent();
|
||||
while (parentNode != nullptr)
|
||||
{
|
||||
if (parentNode->Visible == false)
|
||||
{
|
||||
_RenderGuidanceInfo.Visible = false;
|
||||
return;
|
||||
}
|
||||
parentNode = parentNode->GetParent();
|
||||
}
|
||||
_RenderGuidanceInfo.Visible = true;
|
||||
|
||||
// 计算缩放因子和翻转状态
|
||||
float scaleX = transformIter.scale.x * transform.scale.x;
|
||||
float scaleY = transformIter.scale.y * transform.scale.y;
|
||||
@@ -51,8 +74,10 @@ void Sprite::CalcRenderInfoLogic()
|
||||
_RenderGuidanceInfo.flip = static_cast<SDL_RendererFlip>(SDL_FLIP_VERTICAL | _RenderGuidanceInfo.flip);
|
||||
|
||||
// 纹理数据里带的偏移数据 有这个偏移才能保证动画播放时视觉中心点在一个点上
|
||||
float texturePosX = flipX ? -(m_texture->TextureSize.width + m_texture->TexturePos.x) + SDL_abs(transform.position.x * 2) : m_texture->TexturePos.x;
|
||||
float texturePosY = flipY ? -(m_texture->TextureSize.height + m_texture->TexturePos.y) + SDL_abs(transform.position.y * 2) : m_texture->TexturePos.y;
|
||||
auto T_Size = m_texture->getSize();
|
||||
auto T_Pos = m_texture->getPos();
|
||||
float texturePosX = flipX ? -(T_Size.width + T_Pos.x) + SDL_abs(transform.position.x * 2) : T_Pos.x;
|
||||
float texturePosY = flipY ? -(T_Size.height + T_Pos.y) + SDL_abs(transform.position.y * 2) : T_Pos.y;
|
||||
|
||||
// 先计算Img坐标与精灵坐标合成后的真实坐标
|
||||
float RealPosX = transform.position.x + texturePosX;
|
||||
@@ -93,13 +118,9 @@ void Sprite::CalcRenderInfoLogic()
|
||||
|
||||
// 更新渲染信息
|
||||
_RenderGuidanceInfo.rect = {Xpos, Ypos, scaledWidth, scaledHeight};
|
||||
|
||||
// 如果有阴影 计算阴影的渲染信息
|
||||
if (ShadowFlag)
|
||||
CalculateShadowData();
|
||||
_RenderGuidanceInfo.AnchorPos = {scaledAnchorOffsetX, scaledAnchorOffsetY};
|
||||
// 设置纹理透明度
|
||||
SDL_SetTextureAlphaMod(m_texture->GetTexture(), this->Alpha * 255);
|
||||
m_texture->setAlpha(this->Alpha);
|
||||
|
||||
// 屏幕内检测
|
||||
int screenWidth = Game::GetInstance().Screen_W;
|
||||
@@ -113,17 +134,6 @@ void Sprite::CalcRenderInfoLogic()
|
||||
CalcRenderInfoFlag = false;
|
||||
}
|
||||
|
||||
void Sprite::SetClipRect(SDL_Rect clipRect)
|
||||
{
|
||||
CropFlag = true;
|
||||
CropRect = clipRect;
|
||||
}
|
||||
|
||||
void Sprite::UnsetClipRect()
|
||||
{
|
||||
CropFlag = false;
|
||||
}
|
||||
|
||||
void Sprite::PreRender()
|
||||
{
|
||||
if (CalcRenderInfoFlag && Visible)
|
||||
@@ -134,32 +144,26 @@ void Sprite::Render()
|
||||
{
|
||||
if (!Visible)
|
||||
return;
|
||||
SDL_Renderer *renderer = Game::GetInstance().GetRenderer();
|
||||
if (!m_texture)
|
||||
return;
|
||||
|
||||
RenderManager *renderer = Game::GetInstance().GetRenderer();
|
||||
|
||||
if (_RenderGuidanceInfo.IsInScreen && _RenderGuidanceInfo.Visible)
|
||||
{
|
||||
// 如果有阴影绘制阴影
|
||||
if (ShadowFlag)
|
||||
{
|
||||
std::array<int, 6> indices = {0, 1, 2, 1, 3, 2};
|
||||
SDL_RenderGeometry(renderer, m_texture->GetTexture(), vertices.data(), vertices.size(), indices.data(), indices.size());
|
||||
}
|
||||
SDL_FPoint AnchorPos = _RenderGuidanceInfo.AnchorPos;
|
||||
|
||||
// 混合
|
||||
if (this->_BlendMode != NONE)
|
||||
Blend();
|
||||
|
||||
SDL_Rect srcrect = {0, 0, this->Size.width, this->Size.height};
|
||||
renderer->DrawTexture(m_texture, &srcrect, &_RenderGuidanceInfo.rect, _RenderGuidanceInfo.rotation, &AnchorPos, _RenderGuidanceInfo.flip);
|
||||
|
||||
// 还原混合
|
||||
if (this->_BlendMode != NONE)
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
|
||||
if (_RenderGuidanceInfo.rotation != 0.f || _RenderGuidanceInfo.flip != SDL_FLIP_NONE)
|
||||
{
|
||||
SDL_FPoint AnchorPos = _RenderGuidanceInfo.AnchorPos;
|
||||
SDL_RenderCopyExF(renderer, m_texture->GetTexture(), NULL, &_RenderGuidanceInfo.rect, _RenderGuidanceInfo.rotation, &AnchorPos, _RenderGuidanceInfo.flip);
|
||||
}
|
||||
else
|
||||
{
|
||||
SDL_RenderCopyF(renderer, m_texture->GetTexture(), NULL, &_RenderGuidanceInfo.rect);
|
||||
// // 设置绘制颜色
|
||||
// SDL_SetRenderDrawColor(renderer, 255, 0, 0, 128);
|
||||
// // 绘制填充矩形
|
||||
// SDL_RenderFillRectF(renderer, &_RenderGuidanceInfo.rect);
|
||||
}
|
||||
Game::GetInstance().m_RenderCount++;
|
||||
}
|
||||
}
|
||||
@@ -168,72 +172,22 @@ void Sprite::Clear()
|
||||
{
|
||||
}
|
||||
|
||||
void Sprite::SetBlendMode(SDL_BlendMode blendMode)
|
||||
void Sprite::SetBlendMode(LE_BlEND_MODE mode)
|
||||
{
|
||||
if (GetBlendMode() != blendMode)
|
||||
m_texture->SetBlendMode(blendMode);
|
||||
this->_BlendMode = mode;
|
||||
}
|
||||
|
||||
SDL_BlendMode Sprite::GetBlendMode()
|
||||
void Sprite::Blend()
|
||||
{
|
||||
return m_texture->GetBlendMode();
|
||||
}
|
||||
|
||||
void Sprite::SetShadow()
|
||||
{
|
||||
ShadowFlag = true;
|
||||
CalcRenderInfo();
|
||||
}
|
||||
|
||||
void Sprite::CalculateShadowData()
|
||||
{
|
||||
const float shearX = 1.3f;
|
||||
SDL_FRect guidance = _RenderGuidanceInfo.rect;
|
||||
float shadowW = guidance.w; // 影子宽度(建议与角色宽度一致)
|
||||
float shadowH = guidance.h * 0.33; // 影子高度(可根据需求调整,比如角色高度的1/4)
|
||||
|
||||
// 计算角色脚部中点坐标(底部中心,即需要重叠的锚点)
|
||||
float roleFootX = guidance.x + guidance.w / 2.0f + 3; // 角色X中心 + 位置偏移
|
||||
float roleFootY = guidance.y + guidance.h - 5; // 角色底部Y坐标(脚的位置)
|
||||
|
||||
// 计算错切后的顶点(局部坐标)
|
||||
vertices = {
|
||||
// 左上角(局部坐标)
|
||||
SDL_Vertex{{0.0f, 0.0f}, {0, 0, 0, 110}, {0.0f, 0.0f}},
|
||||
// 右上角(局部坐标)
|
||||
SDL_Vertex{{shadowW, 0.0f}, {0, 0, 0, 110}, {1.0f, 0.0f}},
|
||||
// 左下角(局部坐标)
|
||||
SDL_Vertex{{0.0f + shearX * shadowH, shadowH}, {0, 0, 0, 110}, {0.0f, 1.0f}},
|
||||
// 右下角(局部坐标)
|
||||
SDL_Vertex{{shadowW + shearX * shadowH, shadowH}, {0, 0, 0, 110}, {1.0f, 1.0f}}};
|
||||
|
||||
bool flipHorizontal = (_RenderGuidanceInfo.flip & SDL_FLIP_HORIZONTAL) != 0; // 检查水平翻转标志
|
||||
bool flipVertical = (_RenderGuidanceInfo.flip & SDL_FLIP_VERTICAL) != 0; // 检查垂直翻转标志
|
||||
// 应用纹理坐标翻转(核心逻辑)
|
||||
for (auto &v : vertices)
|
||||
switch (this->_BlendMode)
|
||||
{
|
||||
// 水平翻转:反转u坐标(0→1,1→0)
|
||||
if (flipHorizontal)
|
||||
{
|
||||
v.tex_coord.x = 1.0f - v.tex_coord.x;
|
||||
}
|
||||
// 垂直翻转:反转v坐标(0→1,1→0)
|
||||
if (flipVertical)
|
||||
{
|
||||
v.tex_coord.y = 1.0f - v.tex_coord.y;
|
||||
}
|
||||
}
|
||||
|
||||
// 计算影子底部中点并对齐角色脚部(与之前逻辑一致)
|
||||
float shadowFootX = (vertices[2].position.x + vertices[3].position.x) / 2.0f;
|
||||
float shadowFootY = shadowH;
|
||||
float offsetX = roleFootX - shadowFootX;
|
||||
float offsetY = roleFootY - shadowFootY;
|
||||
|
||||
// 应用位置偏移
|
||||
for (auto &v : vertices)
|
||||
{
|
||||
v.position.x += offsetX;
|
||||
v.position.y += offsetY;
|
||||
case LINEARDODGE:
|
||||
glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE, GL_ZERO, GL_ONE);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
LE_BlEND_MODE Sprite::GetBlendMode()
|
||||
{
|
||||
return this->_BlendMode;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user