将游戏层和UI层分开渲染 并提高了缩放质量

This commit is contained in:
2025-10-26 14:38:14 +08:00
parent 585724b512
commit dc0213dc16
5 changed files with 56 additions and 24 deletions

View File

@@ -26,6 +26,10 @@ void Game::Init(std::function<void()> CallBack)
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 2); SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 2);
SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); // 双缓冲 SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); // 双缓冲
// 启用多重采样(关键步骤)
SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, 1); // 启用多重采样缓冲
SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, 8); // 4x 采样(可改为 8 等)
if (SDL_Init(SDL_INIT_EVERYTHING) < 0) if (SDL_Init(SDL_INIT_EVERYTHING) < 0)
{ {
SDL_LogError(SDL_LOG_CATEGORY_ERROR, "SDL could not initialize! Error: %s\n", SDL_GetError()); SDL_LogError(SDL_LOG_CATEGORY_ERROR, "SDL could not initialize! Error: %s\n", SDL_GetError());
@@ -39,6 +43,7 @@ void Game::Init(std::function<void()> CallBack)
} }
// 关闭原生鼠标 // 关闭原生鼠标
SDL_ShowCursor(0); SDL_ShowCursor(0);
// 打开所有检测到的控制器 // 打开所有检测到的控制器
int numControllers = SDL_NumJoysticks(); int numControllers = SDL_NumJoysticks();
for (int i = 0; i < numControllers; i++) for (int i = 0; i < numControllers; i++)
@@ -112,6 +117,7 @@ void Game::Run()
// 延迟后,重新计算从帧开始到现在的总时间(包含可能的延迟误差) // 延迟后,重新计算从帧开始到现在的总时间(包含可能的延迟误差)
Uint64 actualFrameTime = SDL_GetTicks64() - frameStart; Uint64 actualFrameTime = SDL_GetTicks64() - frameStart;
m_deltaTime = actualFrameTime / 1000.0f; // 用实际总时间更新deltaTime m_deltaTime = actualFrameTime / 1000.0f; // 用实际总时间更新deltaTime
m_frameTime_ms = actualFrameTime;
} }
} }
@@ -160,9 +166,6 @@ void Game::Update(float deltaTime)
void Game::Render() void Game::Render()
{ {
// 绘制调用次数清0
m_RenderCount = 0;
// 调用预渲染 // 调用预渲染
if (m_scene != nullptr) if (m_scene != nullptr)
m_scene->PreRender(); m_scene->PreRender();
@@ -172,9 +175,15 @@ void Game::Render()
// 清空渲染器后渲染 // 清空渲染器后渲染
m_renderer->ClearScreen(); m_renderer->ClearScreen();
if (m_scene != nullptr) if (m_scene != nullptr)
{
m_renderer->SetOrthoMatrixType(0);
m_scene->Render(); m_scene->Render();
}
if (m_uiScene != nullptr) if (m_uiScene != nullptr)
{
m_renderer->SetOrthoMatrixType(1);
m_uiScene->Render(); m_uiScene->Render();
}
m_renderer->SwapBuffer(); m_renderer->SwapBuffer();
} }

View File

@@ -56,12 +56,7 @@ public:
// 设定UI层场景对象 // 设定UI层场景对象
void ChangeUIScene(RefPtr<Scene> scene); void ChangeUIScene(RefPtr<Scene> scene);
RenderManager* GetRenderer(); RenderManager *GetRenderer();
// 每秒帧率
u32 m_fps;
// 每帧绘制调用次数
u32 m_RenderCount = 0;
private: private:
// 构造函数和析构函数设为私有,防止外部创建和销毁 // 构造函数和析构函数设为私有,防止外部创建和销毁
@@ -73,7 +68,7 @@ private:
// 窗口 // 窗口
SDL_Window *m_window; SDL_Window *m_window;
// 渲染器 // 渲染器
RenderManager* m_renderer; RenderManager *m_renderer;
// 游戏层场景 // 游戏层场景
RefPtr<Scene> m_scene; RefPtr<Scene> m_scene;
@@ -82,22 +77,27 @@ private:
// 帧数 // 帧数
#ifdef __SWITCH__ #ifdef __SWITCH__
float m_Settingfps = 60.0; float m_Settingfps = 5000.0;
#else #else
float m_Settingfps = 144.0; float m_Settingfps = 5000.0;
#endif #endif
// 单帧时间 // 单帧时间
float m_frameTime = 0.f; float m_frameTime = 0.f;
// 每秒内的帧数计数器
u32 m_frameCounter;
// 上一次输出帧率的时间
u32 m_lastFpsPrintTime;
// 帧间隔 // 帧间隔
float m_deltaTime = 0.f; float m_deltaTime = 0.f;
// 每秒内的帧数计数器
u32 m_frameCounter;
u32 m_lastFpsPrintTime;
public: public:
// 屏幕宽高 // 屏幕宽高
int Screen_W = 1280; int Screen_W = 1280;
int Screen_H = 720; int Screen_H = 720;
// 每秒帧率
u32 m_fps;
// 单帧时间
u32 m_frameTime_ms;
// 节点个数
u32 m_nodeCount = 0;
}; };

View File

@@ -26,8 +26,11 @@ RenderManager::RenderManager(SDL_Window *window)
// 设置窗口尺寸 // 设置窗口尺寸
_windowWidth = width; _windowWidth = width;
_windowHeight = height; _windowHeight = height;
// 设置正交投影矩阵
_orthoMatrix = glm::ortho(0.0f, (float)width, (float)height, 0.0f, -1.0f, 1.0f); // 游戏的初始正交投影矩阵
_GameOrthoMatrix = glm::ortho(0.0f, (float)width / 1.2f, (float)height / 1.2f, 0.0f, -1.0f, 1.0f);
// UI的初始正交投影矩阵
_UIOrthoMatrix = glm::ortho(0.0f, (float)width, (float)height, 0.0f, -1.0f, 1.0f);
// 设置清屏颜色 // 设置清屏颜色
glClearColor(0.0f, 0.0f, 0.0f, 1.0f); glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
@@ -217,7 +220,7 @@ void RenderManager::Init2DTextureProgram()
// 设置着色器 uniforms // 设置着色器 uniforms
glUniformMatrix4fv(_currentRenderParams.UnimLocs[0], 1, GL_FALSE, glm::value_ptr(model)); glUniformMatrix4fv(_currentRenderParams.UnimLocs[0], 1, GL_FALSE, glm::value_ptr(model));
glUniformMatrix4fv(_currentRenderParams.UnimLocs[1], 1, GL_FALSE, glm::value_ptr(_orthoMatrix)); glUniformMatrix4fv(_currentRenderParams.UnimLocs[1], 1, GL_FALSE, glm::value_ptr(_OrthoMatrix));
// 绑定纹理并设置采样器 // 绑定纹理并设置采样器
glActiveTexture(GL_TEXTURE0); glActiveTexture(GL_TEXTURE0);
@@ -297,6 +300,7 @@ void RenderManager::SetCurrentBufferObject(std::string name)
void RenderManager::ClearScreen() void RenderManager::ClearScreen()
{ {
glClear(GL_COLOR_BUFFER_BIT); glClear(GL_COLOR_BUFFER_BIT);
_frameRenderCount = 0;
} }
void RenderManager::SwapBuffer() void RenderManager::SwapBuffer()
@@ -317,12 +321,21 @@ void RenderManager::CloseClipRect()
void RenderManager::DrawTexture(RefPtr<Texture> textureObj, const SDL_Rect *srcrect, const SDL_FRect *dstrect, const double angle, const SDL_FPoint *center, const SDL_RendererFlip flip, void *userdata) void RenderManager::DrawTexture(RefPtr<Texture> textureObj, const SDL_Rect *srcrect, const SDL_FRect *dstrect, const double angle, const SDL_FPoint *center, const SDL_RendererFlip flip, void *userdata)
{ {
_frameRenderCount++;
if (_currentRenderParams.DrawFunc != nullptr) if (_currentRenderParams.DrawFunc != nullptr)
_currentRenderParams.DrawFunc(textureObj, srcrect, dstrect, angle, center, flip, userdata); _currentRenderParams.DrawFunc(textureObj, srcrect, dstrect, angle, center, flip, userdata);
else else
SDL_LogError(SDL_LOG_CATEGORY_ERROR, "找不到渲染逻辑函数\n"); SDL_LogError(SDL_LOG_CATEGORY_ERROR, "找不到渲染逻辑函数\n");
} }
void RenderManager::SetOrthoMatrixType(int type)
{
if (type == 0)
_OrthoMatrix = _GameOrthoMatrix;
else
_OrthoMatrix = _UIOrthoMatrix;
}
GLuint RenderManager::CompileShader(GLenum type, std::string Path) GLuint RenderManager::CompileShader(GLenum type, std::string Path)
{ {
std::ifstream Source("shader/" + Path); std::ifstream Source("shader/" + Path);

View File

@@ -31,8 +31,12 @@ private:
// 窗口尺寸 // 窗口尺寸
int _windowWidth; int _windowWidth;
int _windowHeight; int _windowHeight;
// 正交投影矩阵 // 游戏正交投影矩阵
glm::mat4 _orthoMatrix; glm::mat4 _GameOrthoMatrix;
// UI的正交投影矩阵
glm::mat4 _UIOrthoMatrix;
// 渲染的正交投影矩阵
glm::mat4 _OrthoMatrix;
// 渲染器上下文 // 渲染器上下文
SDL_GLContext _ctx; SDL_GLContext _ctx;
@@ -46,6 +50,9 @@ private:
// 当前使用渲染参数 // 当前使用渲染参数
GL_RenderParams _currentRenderParams; GL_RenderParams _currentRenderParams;
public:
// 单帧渲染调用次数
int _frameRenderCount = 0;
public: public:
RenderManager(SDL_Window *window); RenderManager(SDL_Window *window);
~RenderManager(); ~RenderManager();
@@ -69,6 +76,9 @@ public:
void CloseClipRect(); void CloseClipRect();
// 绘制纹理 // 绘制纹理
void DrawTexture(RefPtr<Texture> texture, const SDL_Rect *srcrect, const SDL_FRect *dstrect, const double angle, const SDL_FPoint *center, const SDL_RendererFlip flip, void *userdata = nullptr); void DrawTexture(RefPtr<Texture> texture, const SDL_Rect *srcrect, const SDL_FRect *dstrect, const double angle, const SDL_FPoint *center, const SDL_RendererFlip flip, void *userdata = nullptr);
// 设置正交投影矩阵类型
void SetOrthoMatrixType(int type);
private: private:
// 编译着色器 // 编译着色器

View File

@@ -35,9 +35,9 @@ bool Texture::Init(std::string PngPath)
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
// 缩小过滤:使用最近邻采样 // 缩小过滤:使用最近邻采样
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
// 放大过滤:使用最近邻采样 // 放大过滤:使用最近邻采样
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
// 处理像素对齐确保SDL的像素行对齐与OpenGL兼容 // 处理像素对齐确保SDL的像素行对齐与OpenGL兼容
glPixelStorei(GL_UNPACK_ALIGNMENT, 1); glPixelStorei(GL_UNPACK_ALIGNMENT, 1);