#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(m_data["path"]) == "") // m_data["path"] = "sprite/character/common/circlecooltime.img"; // m_texture = new Texture(); // m_texture->Init(std::get(m_data["path"]), std::get(m_data["idx"])); // Sprite::Init(); // this->imgPath = Path; // } Tile::Tile(GameMap *parentMap, std::vector normal, std::vector 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(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(data["path"]); int index = std::get(data["idx"]); // 如果是个空地板 给他默认赋值 if (path == "") path = "sprite/character/common/circlecooltime.img"; // 构造纹理标识符 ImgKey key = {path, index}; // 判断是否存在标识符对应的纹理,如果不存在则创建 if (m_imgMap.find(key) == m_imgMap.end()) { RefPtr 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(data["path"]); int index = std::get(data["idx"]); // 如果是个空地板 给他默认赋值 if (path == "") path = "sprite/character/common/circlecooltime.img"; // 构造纹理标识符 ImgKey key = {path, index}; // 判断是否存在标识符对应的纹理,如果不存在则创建 if (m_imgMap.find(key) == m_imgMap.end()) { RefPtr 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(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"); }