Files
DNF_DEV/source_game/Actor/Map/Tile.cpp

197 lines
6.2 KiB
C++

#include "Tile.h"
#include "Tool/Tool_String.h"
#include "EngineCore/Game.h"
#include "Actor/Map/GameMap.h"
#include "Global/Global_Game.h"
// Tile::Tile(std::string Path) : Sprite()
// {
// InitInfo(Path);
// if (std::get<std::string>(m_data["path"]) == "")
// m_data["path"] = "sprite/character/common/circlecooltime.img";
// m_texture = new Texture();
// m_texture->Init(std::get<std::string>(m_data["path"]), std::get<int>(m_data["idx"]));
// Sprite::Init();
// this->imgPath = Path;
// }
Tile::Tile(GameMap *parentMap, std::vector<std::string> normal, std::vector<std::string> ex)
{
m_parentMap = parentMap;
m_texture = new Texture();
// 通过父对象获取地图大小
int Width = m_parentMap->_MapLength;
int Height = m_parentMap->_MapHeight;
// 通过大小纹理大小
m_texture->Init(VecSize(Width, Height));
m_rect = {0, 0, (float)Width, (float)Height};
Actor::Init();
glGenFramebuffers(1, &m_fbo);
glBindFramebuffer(GL_FRAMEBUFFER, m_fbo);
// 将目标纹理附加到FBO的颜色附着点
glFramebufferTexture2D(
GL_FRAMEBUFFER, // 帧缓冲类型
GL_COLOR_ATTACHMENT0, // 颜色附着点(可多个,这里用第一个)
GL_TEXTURE_2D, // 纹理类型
m_texture->getID(), // 目标纹理ID
0 // 多级渐远纹理级别
);
glBindFramebuffer(GL_FRAMEBUFFER, 0); // 解绑FBO
for (size_t i = 0; i < normal.size(); i++)
{
InitTile(normal[i], i);
}
m_tileX = normal.size();
for (size_t i = 0; i < ex.size(); i++)
{
InitExTile(ex[i], i);
}
SetPos(Vec2(0, 80 - 200 - std::get<int>(m_parentMap->_MapInfo["background_pos"])));
}
Tile::~Tile()
{
}
void Tile::InitTile(std::string Path, int Index)
{
// 读取文件
TileInfo data;
InitInfo(Path, data);
// 读取信息
std::string path = std::get<std::string>(data["path"]);
int index = std::get<int>(data["idx"]);
// 如果是个空地板 给他默认赋值
if (path == "")
path = "sprite/character/common/circlecooltime.img";
// 构造纹理标识符
ImgKey key = {path, index};
// 判断是否存在标识符对应的纹理,如果不存在则创建
if (m_imgMap.find(key) == m_imgMap.end())
{
RefPtr<Texture> tex = new Texture();
tex->Init(path, index);
m_imgMap[key] = tex;
}
// 构造绘制信息
DrawInfo info;
info.rect.x = Index * m_imgMap[key]->getSize().width + m_imgMap[key]->getPos().x;
info.rect.y = m_imgMap[key]->getPos().y;
info.rect.w = m_imgMap[key]->getSize().width;
info.rect.h = m_imgMap[key]->getSize().height;
info.texture = key;
// 添加到绘制信息列表
m_drawQueue.push_back(info);
}
void Tile::InitExTile(std::string Path, int Index)
{
// 读取文件
TileInfo data;
InitInfo(Path, data);
// 读取信息
std::string path = std::get<std::string>(data["path"]);
int index = std::get<int>(data["idx"]);
// 如果是个空地板 给他默认赋值
if (path == "")
path = "sprite/character/common/circlecooltime.img";
// 构造纹理标识符
ImgKey key = {path, index};
// 判断是否存在标识符对应的纹理,如果不存在则创建
if (m_imgMap.find(key) == m_imgMap.end())
{
RefPtr<Texture> tex = new Texture();
tex->Init(path, index);
m_imgMap[key] = tex;
}
// 构造绘制信息
DrawInfo info;
info.rect.x = Index * m_imgMap[key]->getSize().width + m_imgMap[key]->getPos().x;
info.rect.y = m_imgMap[key]->getPos().y + 560 + ((Index / m_tileX) * 120);
info.rect.w = m_imgMap[key]->getSize().width;
info.rect.h = m_imgMap[key]->getSize().height;
info.texture = key;
// 添加到绘制信息列表
m_drawQueue.push_back(info);
}
// void Tile::SetPos(Vec2 pos)
// {
// // pos.y += std::get<int>(m_data["pos"]);
// // Sprite::SetPos(pos);
// }
void Tile::InitInfo(std::string Path, TileInfo &m_data)
{
ScriptData Data = AssetManager::GetInstance().GetScriptInfo(Path);
m_data["pos"] = 0;
while (!Data.IsEnd())
{
std::string Segment = Data.Get();
if (Segment == "[IMAGE]")
{
std::string PathBuf = Tool_toLowerCase(Data.Get());
m_data["path"] = "sprite/" + PathBuf;
m_data["idx"] = std::stoi(Data.Get());
}
else if (Segment == "[img pos]")
{
m_data["pos"] = std::stoi(Data.Get());
}
}
}
void Tile::PreRender()
{
m_rect.x = GetWorldPos().x;
m_rect.y = GetWorldPos().y;
//计算摄像机位置 知道自己需要渲染多大的区域
// m_srcRect = {0, 0, m_parentMap->_MapLength, m_parentMap->_MapHeight};
// Vec2 Pos = Global_Game::GetInstance().GetCamera() -> _currentPosition;
// m_srcRect = {Pos.x < 1067 ? 0 : Pos.x - 1067, Pos.y, 1067, 600};
}
void Tile::Render()
{
RenderManager *renderer = Game::GetInstance().GetRenderer();
SDL_FPoint AnchorPos = {0, 0};
if (!m_isBuild)
{
// 保存原始的正交矩阵 设置纹理对应的正交矩阵 和 视口
auto oldOm = Game::GetInstance().GetRenderer()->GetOrthoMatrix();
Game::GetInstance().GetRenderer()->SetOrthoMatrix(glm::ortho(0.0f, (float)m_texture->getSize().width, (float)m_texture->getSize().height, 0.0f, -1.0f, 1.0f));
glViewport(0, 0, m_texture->getSize().width, m_texture->getSize().height);
glBindFramebuffer(GL_FRAMEBUFFER, m_fbo); // 绑定FBO
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
glClear(GL_COLOR_BUFFER_BIT);
for (auto &info : m_drawQueue)
{
renderer->DrawTexture(m_imgMap[info.texture], nullptr, &info.rect, 0.f, &AnchorPos, SDL_FLIP_NONE);
}
glBindFramebuffer(GL_FRAMEBUFFER, 0); // 解绑FBO
// 还原原始的正交矩阵 和 视口
Game::GetInstance().GetRenderer()->SetOrthoMatrix(oldOm);
glViewport(0, 0, Game::GetInstance().Screen_W, Game::GetInstance().Screen_H);
m_isBuild = true;
}
renderer->SetCurrentShaderProgram("flip_y");
renderer->DrawTexture(m_texture, nullptr, &m_rect, 0.f, &AnchorPos, SDL_FLIP_NONE);
renderer->SetCurrentShaderProgram("normal");
}