Extra2D/examples/image_display/main.cpp

160 lines
4.7 KiB
C++
Raw Normal View History

/**
* @file main.cpp
* @brief Extra2D
*
* 使 Renderer
* OpenGL
*/
#include "extra2d/core/service_interface.h"
#include "extra2d/core/service_locator.h"
#include <extra2d/extra2d.h>
#include <iostream>
using namespace extra2d;
class ImageDisplayScene : public Scene {
public:
void onEnter() override {
// 加载图片
// 注意:请确保有图片文件在 assets/images/ 目录下
try {
texture_ = renderer_->loadTexture("assets/images/demo.jpg");
std::cout << "Image loaded successfully!" << std::endl;
std::cout << " Size: " << texture_->getWidth() << "x"
<< texture_->getHeight() << std::endl;
} catch (...) {
std::cerr << "Failed to load image from assets/images/demo.jpg"
<< std::endl;
// 尝试使用备用路径
try {
texture_ = renderer_->loadTexture(
"examples/image_display/assets/images/demo.jpg");
std::cout << "Image loaded from alternate path!" << std::endl;
} catch (...) {
std::cerr << "Failed to load image from alternate path!" << std::endl;
texture_ = nullptr;
}
}
}
void onExit() override { texture_.reset(); }
void onRender(Renderer &renderer) override {
Scene::onRender(renderer);
if (!texture_) {
return;
}
// 使用 Renderer 的抽象接口绘制图片
// 不依赖任何特定后端(如 OpenGL
// 自动批处理:无需手动调用 begin/endSpriteBatch
// 计算图片显示位置(居中显示)
float windowWidth = 1280.0f;
float windowHeight = 720.0f;
float imgWidth = static_cast<float>(texture_->getWidth());
float imgHeight = static_cast<float>(texture_->getHeight());
// 缩放图片以适应窗口(保持宽高比)
float scale = 1.0f;
if (imgWidth > windowWidth * 0.8f || imgHeight > windowHeight * 0.8f) {
float scaleX = (windowWidth * 0.8f) / imgWidth;
float scaleY = (windowHeight * 0.8f) / imgHeight;
scale = std::min(scaleX, scaleY);
}
float displayWidth = imgWidth * scale;
float displayHeight = imgHeight * scale;
float x = (windowWidth - displayWidth) * 0.5f;
float y = (windowHeight - displayHeight) * 0.5f;
// 使用 Renderer 的 drawSprite 方法绘制图片
// 参数:纹理、目标矩形、源矩形、颜色、旋转角度、锚点
Rect destRect(x, y, displayWidth, displayHeight);
Rect srcRect(0, 0, imgWidth, imgHeight);
renderer.drawSprite(*texture_, destRect, srcRect, Colors::White, 0.0f,
Vec2(0, 0));
// 注意:无需手动调用 renderer.endSpriteBatch(),帧结束时会自动刷新
}
void setRenderer(Renderer *renderer) { renderer_ = renderer; }
private:
Ptr<Texture> texture_;
Renderer *renderer_ = nullptr;
};
int main(int argc, char *argv[]) {
(void)argc;
(void)argv;
std::cout << "Extra2D Image Display Demo - Starting..." << std::endl;
Application &app = Application::get();
// 注册模块
app.use<WindowModule>([](auto &cfg) {
cfg.w = 1280;
cfg.h = 720;
cfg.title = "Extra2D 图片显示示例";
cfg.priority = 0;
});
app.use<RenderModule>([](auto &cfg) { cfg.priority = 10; });
if (!app.init()) {
std::cerr << "Failed to initialize application!" << std::endl;
return -1;
}
auto win = app.window();
// 设置事件监听
auto eventService = ServiceLocator::instance().getService<IEventService>();
if (eventService) {
eventService->addListener(EventType::KeyPressed, [](Event &e) {
auto &keyEvent = std::get<KeyEvent>(e.data);
if (keyEvent.keyCode == static_cast<int>(Key::Escape)) {
e.handled = true;
Application::get().quit();
}
});
}
// 获取渲染器
Renderer *renderer = app.renderer();
// 创建并配置场景
auto scene = makeShared<ImageDisplayScene>();
scene->setRenderer(renderer);
scene->setBackgroundColor(Color(0.1f, 0.1f, 0.15f, 1.0f));
if (win) {
scene->setViewportSize(static_cast<float>(win->width()),
static_cast<float>(win->height()));
}
// 配置相机
auto cameraService = ServiceLocator::instance().getService<ICameraService>();
if (cameraService && win) {
cameraService->setViewportConfig([&](auto &cfg) {
cfg.logicWidth = static_cast<float>(win->width());
cfg.logicHeight = static_cast<float>(win->height());
cfg.mode = ViewportMode::AspectRatio;
});
cameraService->updateViewport(win->width(), win->height());
cameraService->applyViewportAdapter();
}
app.enterScene(scene);
app.run();
app.shutdown();
return 0;
}