11#include < esengine/ESEngine.hpp>
2+ #include < esengine/ui/UIContext.hpp>
3+ #include < esengine/ui/rendering/UIBatchRenderer.hpp>
4+ #include < esengine/ui/font/SDFFont.hpp>
5+ #include < esengine/events/Dispatcher.hpp>
26
37using namespace esengine ;
48using namespace esengine ::ecs;
59
6- // Simple movement system
7- class MovementSystem : public System {
8- public:
9- void update (Registry& registry, f32 deltaTime) override {
10- registry.each <LocalTransform, Velocity>([deltaTime](Entity entity, LocalTransform& transform, Velocity& velocity) {
11- (void )entity;
12- transform.position += velocity.linear * deltaTime;
13- });
14- }
15- };
16-
17- // Demo application
10+ // Demo application with SDF font testing
1811class HelloTriangleApp : public Application {
1912public:
2013 HelloTriangleApp () : Application(createConfig()) {}
2114
2215private:
2316 static ApplicationConfig createConfig () {
2417 ApplicationConfig config;
25- config.title = " Hello Triangle " ;
18+ config.title = " SDF Font Test - 中英文测试 " ;
2619 config.width = 800 ;
2720 config.height = 600 ;
2821 return config;
2922 }
3023
3124protected:
3225 void onInit () override {
33- ES_LOG_INFO (" Hello Triangle initialized!" );
26+ ES_LOG_INFO (" SDF Font Test initialized!" );
27+
28+ // Create UI context for font rendering
29+ uiContext_ = makeUnique<ui::UIContext>(getRenderContext (), dispatcher_);
30+ uiContext_->init ();
31+ uiContext_->setViewport (getWidth (), getHeight ());
32+
33+ // Load SDF font with CJK support
34+ const char * fontPaths[] = {
35+ #ifdef _WIN32
36+ " C:/Windows/Fonts/msyh.ttc" , // Microsoft YaHei (中文)
37+ " C:/Windows/Fonts/simhei.ttf" , // SimHei
38+ " C:/Windows/Fonts/simsun.ttc" , // SimSun
39+ " C:/Windows/Fonts/arial.ttf" , // Arial (English fallback)
40+ #else
41+ " /usr/share/fonts/truetype/noto/NotoSansCJK-Regular.ttc" ,
42+ " /usr/share/fonts/truetype/dejavu/DejaVuSans.ttf" ,
43+ #endif
44+ nullptr
45+ };
46+
47+ for (const char ** path = fontPaths; *path != nullptr ; ++path) {
48+ sdfFont_ = ui::SDFFont::create (*path, 48 .0f , 8 .0f );
49+ if (sdfFont_) {
50+ ES_LOG_INFO (" Loaded SDF font: {}" , *path);
51+ break ;
52+ }
53+ }
3454
35- // Create some entities with the ECS
36- auto & registry = getRegistry ();
55+ if (!sdfFont_) {
56+ ES_LOG_ERROR (" Failed to load any SDF font!" );
57+ }
3758
38- // Create a triangle entity
59+ // Create some entities
60+ auto & registry = getRegistry ();
3961 Entity triangle = registry.create ();
40- registry.emplace <LocalTransform>(triangle, glm::vec3 (400 .0f , 300 .0f , 0 .0f ));
62+ registry.emplace <LocalTransform>(triangle, glm::vec3 (400 .0f , 450 .0f , 0 .0f ));
4163 registry.emplace <Name>(triangle, " Triangle" );
4264
43- // Create moving entities
44- for (int i = 0 ; i < 5 ; ++i) {
45- Entity entity = registry.create ();
46- registry.emplace <LocalTransform>(entity, glm::vec3 (100 .0f + i * 120 .0f , 100 .0f , 0 .0f ));
47- registry.emplace <Velocity>(entity, glm::vec3 (50 .0f * (i % 2 == 0 ? 1 .0f : -1 .0f ), 0 .0f , 0 .0f ));
48- registry.emplace <Sprite>(entity);
49- }
50-
51- ES_LOG_INFO (" Created {} entities" , registry.entityCount ());
65+ ES_LOG_INFO (" Press ESC to exit" );
5266 }
5367
5468 void onUpdate (f32 deltaTime) override {
55- // Update entities manually (or use SystemGroup)
56- auto & registry = getRegistry ();
57- registry.each <LocalTransform, Velocity>([deltaTime, this ](LocalTransform& transform, Velocity& velocity) {
58- transform.position += velocity.linear * deltaTime;
59-
60- // Bounce off edges
61- if (transform.position .x < 0 || transform.position .x > getWidth ()) {
62- velocity.linear .x *= -1 .0f ;
63- }
64- });
65-
66- // Check for touch input
67- if (getInput ().isTouchPressed ()) {
68- auto pos = getInput ().getTouchPosition ();
69- ES_LOG_DEBUG (" Touch at ({}, {})" , pos.x , pos.y );
70- }
71-
72- // Check for key input
69+ (void )deltaTime;
7370 if (getInput ().isKeyPressed (KeyCode::Escape)) {
7471 quit ();
7572 }
7673 }
7774
7875 void onRender () override {
79- auto & registry = getRegistry ();
8076 auto & renderer = getRenderer ();
8177
82- // Draw colored quads for entities with LocalTransform and Sprite
83- auto view = registry.view <LocalTransform, Sprite>();
84- for (auto entity : view) {
85- auto & transform = view.get <LocalTransform>(entity);
86- auto & sprite = view.get <Sprite>(entity);
78+ // Draw a simple quad
79+ renderer.drawQuad (
80+ glm::vec2 (400 .0f , 450 .0f ),
81+ glm::vec2 (100 .0f , 100 .0f ),
82+ glm::vec4 (1 .0f , 0 .5f , 0 .2f , 1 .0f )
83+ );
84+
85+ // Draw SDF text
86+ if (sdfFont_ && uiContext_) {
87+ auto & uiRenderer = uiContext_->getRenderer ();
88+
89+ glm::mat4 projection = glm::ortho (
90+ 0 .0f , static_cast <f32 >(getWidth ()),
91+ static_cast <f32 >(getHeight ()), 0 .0f ,
92+ -1 .0f , 1 .0f
93+ );
94+
95+ uiRenderer.begin (projection);
8796
88- renderer.drawQuad (
89- glm::vec2 (transform.position .x , transform.position .y ),
90- sprite.size * 50 .0f ,
91- sprite.color
97+ // English text
98+ uiRenderer.drawText (
99+ " Hello SDF Font!" ,
100+ {50 .0f , 50 .0f },
101+ *sdfFont_,
102+ 32 .0f ,
103+ {1 .0f , 1 .0f , 1 .0f , 1 .0f }
92104 );
93- }
94105
95- // Draw the main triangle
96- auto triangleView = registry.view <LocalTransform, Name>();
97- for (auto entity : triangleView) {
98- auto & transform = triangleView.get <LocalTransform>(entity);
99- auto & name = triangleView.get <Name>(entity);
100-
101- if (name.value == " Triangle" ) {
102- renderer.drawQuad (
103- glm::vec2 (transform.position .x , transform.position .y ),
104- glm::vec2 (100 .0f , 100 .0f ),
105- glm::vec4 (1 .0f , 0 .5f , 0 .2f , 1 .0f )
106- );
107- }
108- }
109- }
106+ // Chinese text
107+ uiRenderer.drawText (
108+ " 你好,世界!中文测试" ,
109+ {50 .0f , 100 .0f },
110+ *sdfFont_,
111+ 32 .0f ,
112+ {1 .0f , 1 .0f , 0 .0f , 1 .0f }
113+ );
114+
115+ // Mixed text
116+ uiRenderer.drawText (
117+ " ESEngine 引擎 - SDF字体渲染" ,
118+ {50 .0f , 150 .0f },
119+ *sdfFont_,
120+ 28 .0f ,
121+ {0 .5f , 1 .0f , 0 .5f , 1 .0f }
122+ );
123+
124+ // Different sizes to show SDF scaling
125+ uiRenderer.drawText (
126+ " Small 小字 16px" ,
127+ {50 .0f , 200 .0f },
128+ *sdfFont_,
129+ 16 .0f ,
130+ {0 .8f , 0 .8f , 1 .0f , 1 .0f }
131+ );
132+
133+ uiRenderer.drawText (
134+ " Large 大字 48px" ,
135+ {50 .0f , 240 .0f },
136+ *sdfFont_,
137+ 48 .0f ,
138+ {1 .0f , 0 .6f , 0 .6f , 1 .0f }
139+ );
110140
111- void onTouch (TouchType type, const TouchPoint& point) override {
112- if (type == TouchType::Begin) {
113- // Create new entity at touch position
114- auto & registry = getRegistry ();
115- Entity entity = registry.create ();
116- registry.emplace <Transform>(entity, glm::vec3 (point.x , point.y , 0 .0f ));
117- registry.emplace <Sprite>(entity);
118- registry.emplace <Velocity>(entity, glm::vec3 (
119- (rand () % 200 - 100 .0f ),
120- (rand () % 200 - 100 .0f ),
121- 0 .0f
122- ));
141+ uiRenderer.drawText (
142+ " 动态加载 Dynamic Loading" ,
143+ {50 .0f , 320 .0f },
144+ *sdfFont_,
145+ 24 .0f ,
146+ {0 .6f , 0 .9f , 1 .0f , 1 .0f }
147+ );
148+
149+ uiRenderer.end ();
123150 }
124151 }
125152
126153 void onShutdown () override {
127- ES_LOG_INFO (" Hello Triangle shutdown" );
154+ sdfFont_.reset ();
155+ uiContext_.reset ();
156+ ES_LOG_INFO (" SDF Font Test shutdown" );
128157 }
158+
159+ private:
160+ Dispatcher dispatcher_;
161+ Unique<ui::UIContext> uiContext_;
162+ Unique<ui::SDFFont> sdfFont_;
129163};
130164
131165// Entry point
@@ -136,6 +170,5 @@ int main() {
136170 return 0 ;
137171}
138172#else
139- // For web, entry is through the C API
140173ES_MAIN (HelloTriangleApp)
141174#endif
0 commit comments