渲染后端加入
This commit is contained in:
232
Fostbite2D/src/main.cpp
Normal file
232
Fostbite2D/src/main.cpp
Normal file
@@ -0,0 +1,232 @@
|
||||
#include <SDL2/SDL.h>
|
||||
#include <cmath>
|
||||
#include <fostbite2D/app/application.h>
|
||||
#include <fostbite2D/core/color.h>
|
||||
#include <fostbite2D/platform/window.h>
|
||||
#include <fostbite2D/render/camera.h>
|
||||
#include <fostbite2D/render/opengl/gl_font_atlas.h>
|
||||
#include <fostbite2D/render/opengl/gl_renderer.h>
|
||||
#include <fostbite2D/render/opengl/gl_shader.h>
|
||||
#include <fostbite2D/render/shader/shader_manager.h>
|
||||
#include <glad/glad.h>
|
||||
#include <iostream>
|
||||
|
||||
using namespace frostbite2D;
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
|
||||
AppConfig config = AppConfig::createDefault();
|
||||
config.appName = "Frostbite2D Render Test";
|
||||
config.appVersion = "1.0.0";
|
||||
config.windowConfig.width = 800;
|
||||
config.windowConfig.height = 600;
|
||||
config.windowConfig.title = "Frostbite2D - OpenGL Render Test";
|
||||
|
||||
Application &app = Application::get();
|
||||
if (!app.init(config)) {
|
||||
std::cerr << "Failed to initialize application!" << std::endl;
|
||||
return -1;
|
||||
}
|
||||
|
||||
// 初始化 ShaderManager
|
||||
auto shaderFactory = makePtr<GLShaderFactory>();
|
||||
if (!ShaderManager::getInstance().init(shaderFactory)) {
|
||||
std::cerr << "Failed to initialize ShaderManager!" << std::endl;
|
||||
return -1;
|
||||
}
|
||||
|
||||
// 创建 OpenGL 渲染器
|
||||
GLRenderer renderer;
|
||||
SDL_Window *sdlWindow = SDL_GL_GetCurrentWindow();
|
||||
if (!sdlWindow) {
|
||||
std::cerr << "Failed to get SDL window!" << std::endl;
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!renderer.init(sdlWindow)) {
|
||||
std::cerr << "Failed to initialize OpenGL renderer!" << std::endl;
|
||||
return -1;
|
||||
}
|
||||
|
||||
// 加载字体(使用系统默认字体或项目字体)
|
||||
std::string fontPath = "C:/Windows/Fonts/arial.ttf"; // Windows 系统字体
|
||||
FontAtlas *font = nullptr;
|
||||
|
||||
// 尝试加载字体
|
||||
try {
|
||||
font = new GLFontAtlas(fontPath, 24, false); // 24像素大小,不使用SDF
|
||||
SDL_Log("Font loaded successfully: %s", fontPath.c_str());
|
||||
} catch (...) {
|
||||
SDL_LogWarn(SDL_LOG_CATEGORY_APPLICATION, "Failed to load font: %s",
|
||||
fontPath.c_str());
|
||||
SDL_Log("Text rendering will be disabled");
|
||||
}
|
||||
|
||||
// 创建相机 - 视口范围 (0,0) 到 (800,600),相机位置在 (0,0) 表示左上角
|
||||
Camera camera(0.0f, 800.0f, 600.0f, 0.0f);
|
||||
// 相机默认位置 (0,0),表示看向世界坐标的左上角
|
||||
|
||||
SDL_Log("Frostbite2D OpenGL Renderer initialized successfully!");
|
||||
SDL_Log("Press ESC to exit");
|
||||
SDL_Log("Use WASD to move camera, Q/E to zoom, R to reset");
|
||||
|
||||
// 主循环
|
||||
bool running = true;
|
||||
SDL_Event event;
|
||||
float time = 0.0f;
|
||||
float zoom = 1.0f;
|
||||
|
||||
while (running) {
|
||||
// 处理事件
|
||||
while (SDL_PollEvent(&event)) {
|
||||
if (event.type == SDL_QUIT) {
|
||||
running = false;
|
||||
}
|
||||
if (event.type == SDL_KEYDOWN) {
|
||||
if (event.key.keysym.sym == SDLK_ESCAPE) {
|
||||
running = false;
|
||||
}
|
||||
// 相机控制
|
||||
if (event.key.keysym.sym == SDLK_w) {
|
||||
camera.move(
|
||||
0.0f,
|
||||
10.0f); // 向上移动(Y轴向下,所以正方向是向下,反方向是向上)
|
||||
}
|
||||
if (event.key.keysym.sym == SDLK_s) {
|
||||
camera.move(0.0f, -10.0f); // 向下移动
|
||||
}
|
||||
if (event.key.keysym.sym == SDLK_a) {
|
||||
camera.move(10.0f, 0.0f); // 向左移动
|
||||
}
|
||||
if (event.key.keysym.sym == SDLK_d) {
|
||||
camera.move(-10.0f, 0.0f); // 向右移动
|
||||
}
|
||||
if (event.key.keysym.sym == SDLK_q) {
|
||||
zoom = std::max(0.5f, zoom - 0.1f);
|
||||
camera.setZoom(zoom);
|
||||
}
|
||||
if (event.key.keysym.sym == SDLK_e) {
|
||||
zoom = std::min(3.0f, zoom + 0.1f);
|
||||
camera.setZoom(zoom);
|
||||
}
|
||||
if (event.key.keysym.sym == SDLK_r) {
|
||||
camera.setPosition(0.0f, 0.0f);
|
||||
zoom = 1.0f;
|
||||
camera.setZoom(zoom);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 更新时间
|
||||
time += 0.016f; // 假设 60 FPS
|
||||
|
||||
// 开始渲染帧
|
||||
renderer.beginFrame(Color(0.1f, 0.1f, 0.15f, 1.0f)); // 深蓝灰色背景
|
||||
|
||||
// 设置视口
|
||||
renderer.setViewport(0, 0, 800, 600);
|
||||
|
||||
// 使用相机的视图投影矩阵
|
||||
renderer.setViewProjection(camera.getViewProjectionMatrix());
|
||||
|
||||
// 绘制测试图形(使用世界坐标)
|
||||
|
||||
// 1. 绘制红色矩形边框
|
||||
renderer.drawRect(Rect(100.0f, 100.0f, 200.0f, 150.0f), Colors::Red, 2.0f);
|
||||
|
||||
// 2. 绘制绿色填充矩形
|
||||
renderer.fillRect(Rect(350.0f, 100.0f, 200.0f, 150.0f), Colors::Green);
|
||||
|
||||
// 3. 绘制蓝色圆形
|
||||
renderer.fillCircle(Vec2(650.0f, 175.0f), 75.0f, Colors::Blue, 32);
|
||||
|
||||
// 4. 绘制动态旋转的矩形(使用填充三角形组合)
|
||||
float centerX = 400.0f;
|
||||
float centerY = 400.0f;
|
||||
float size = 100.0f;
|
||||
float angle = time * 2.0f; // 旋转角度
|
||||
|
||||
// 计算旋转后的四个角
|
||||
float cosA = cosf(angle);
|
||||
float sinA = sinf(angle);
|
||||
|
||||
Vec2 p1(centerX + (-size * cosA - (-size) * sinA),
|
||||
centerY + (-size * sinA + (-size) * cosA));
|
||||
Vec2 p2(centerX + (size * cosA - (-size) * sinA),
|
||||
centerY + (size * sinA + (-size) * cosA));
|
||||
Vec2 p3(centerX + (size * cosA - size * sinA),
|
||||
centerY + (size * sinA + size * cosA));
|
||||
Vec2 p4(centerX + (-size * cosA - size * sinA),
|
||||
centerY + (-size * sinA + size * cosA));
|
||||
|
||||
// 绘制旋转的四边形(分成两个三角形)
|
||||
renderer.fillTriangle(p1, p2, p3, Colors::Yellow);
|
||||
renderer.fillTriangle(p1, p3, p4, Colors::Yellow);
|
||||
|
||||
// 5. 绘制线条
|
||||
renderer.drawLine(Vec2(50.0f, 550.0f), Vec2(750.0f, 550.0f), Colors::White,
|
||||
3.0f);
|
||||
|
||||
// 6. 绘制三角形
|
||||
renderer.fillTriangle(Vec2(200.0f, 300.0f), Vec2(300.0f, 300.0f),
|
||||
Vec2(250.0f, 200.0f), Colors::Cyan);
|
||||
|
||||
// 7. 绘制网格(帮助观察相机移动)
|
||||
for (int i = 0; i <= 800; i += 100) {
|
||||
renderer.drawLine(Vec2((float)i, 0.0f), Vec2((float)i, 600.0f),
|
||||
Color(0.2f, 0.2f, 0.2f, 0.5f), 1.0f);
|
||||
}
|
||||
for (int i = 0; i <= 600; i += 100) {
|
||||
renderer.drawLine(Vec2(0.0f, (float)i), Vec2(800.0f, (float)i),
|
||||
Color(0.2f, 0.2f, 0.2f, 0.5f), 1.0f);
|
||||
}
|
||||
|
||||
// 8. 绘制文本(使用 GLRenderer 的 drawText)
|
||||
if (font) {
|
||||
renderer.beginSpriteBatch();
|
||||
|
||||
// 测试:直接绘制字体纹理的一部分(第一个字符 'F')
|
||||
Texture *fontTex = font->getTexture();
|
||||
if (fontTex) {
|
||||
// 绘制字体纹理的一部分来测试
|
||||
Rect destRect(50.0f, 300.0f, 64.0f, 64.0f); // 目标位置和大小
|
||||
Rect srcRect(0.0f, 0.0f, 64.0f, 64.0f); // 纹理的前64x64像素
|
||||
renderer.drawSprite(*fontTex, destRect, srcRect, Colors::White, 0.0f,
|
||||
Vec2(0, 0));
|
||||
SDL_Log("Drawing font texture test at (50, 300)");
|
||||
}
|
||||
|
||||
// 绘制标题
|
||||
renderer.drawText(*font, "Frostbite2D Engine", 50.0f, 50.0f,
|
||||
Colors::White);
|
||||
|
||||
// 绘制说明文字
|
||||
renderer.drawText(*font, "WASD: Move Camera", 50.0f, 100.0f,
|
||||
Colors::Yellow);
|
||||
renderer.drawText(*font, "Q/E: Zoom", 50.0f, 130.0f, Colors::Yellow);
|
||||
renderer.drawText(*font, "R: Reset", 50.0f, 160.0f, Colors::Yellow);
|
||||
renderer.drawText(*font, "ESC: Exit", 50.0f, 190.0f, Colors::Yellow);
|
||||
|
||||
// 绘制 FPS 信息
|
||||
renderer.drawText(*font, "OpenGL Renderer Active", 50.0f, 250.0f,
|
||||
Colors::Green);
|
||||
|
||||
renderer.endSpriteBatch();
|
||||
}
|
||||
|
||||
// 结束渲染帧
|
||||
renderer.endFrame();
|
||||
|
||||
// 交换缓冲区
|
||||
SDL_GL_SwapWindow(sdlWindow);
|
||||
}
|
||||
|
||||
// 清理资源
|
||||
delete font;
|
||||
renderer.shutdown();
|
||||
ShaderManager::getInstance().shutdown();
|
||||
app.shutdown();
|
||||
|
||||
std::cout << "程序正常退出" << std::endl;
|
||||
return 0;
|
||||
}
|
||||
Reference in New Issue
Block a user