修改底层渲染为OpenGL

This commit is contained in:
2025-10-23 15:21:12 +08:00
parent 1fe898e09c
commit f9a2300b5a
37 changed files with 2782 additions and 3761 deletions

View File

@@ -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→11→0
if (flipHorizontal)
{
v.tex_coord.x = 1.0f - v.tex_coord.x;
}
// 垂直翻转反转v坐标0→11→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;
}