Extra2D/examples/image_display/main.cpp

160 lines
4.7 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/**
* @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;
}