浏览代码

Introduce dynamic camera scaling

rexim 4 年之前
父节点
当前提交
89fd2b2ef3
共有 5 个文件被更改,包括 41 次插入14 次删除
  1. 5 9
      src/free_glyph.c
  2. 2 2
      src/free_glyph.h
  3. 5 0
      src/la.c
  4. 2 0
      src/la.h
  5. 27 3
      src/main.c

+ 5 - 9
src/free_glyph.c

@@ -232,17 +232,17 @@ float free_glyph_buffer_cursor_pos(const Free_Glyph_Buffer *fgb, const char *tex
     return pos.x;
     return pos.x;
 }
 }
 
 
-void free_glyph_buffer_render_line_sized(Free_Glyph_Buffer *fgb, const char *text, size_t text_size, Vec2f pos, Vec4f fg_color, Vec4f bg_color)
+void free_glyph_buffer_render_line_sized(Free_Glyph_Buffer *fgb, const char *text, size_t text_size, Vec2f *pos, Vec4f fg_color, Vec4f bg_color)
 {
 {
     for (size_t i = 0; i < text_size; ++i) {
     for (size_t i = 0; i < text_size; ++i) {
         Glyph_Metric metric = fgb->metrics[(int) text[i]];
         Glyph_Metric metric = fgb->metrics[(int) text[i]];
-        float x2 = pos.x + metric.bl;
-        float y2 = -pos.y - metric.bt;
+        float x2 = pos->x + metric.bl;
+        float y2 = -pos->y - metric.bt;
         float w  = metric.bw;
         float w  = metric.bw;
         float h  = metric.bh;
         float h  = metric.bh;
 
 
-        pos.x += metric.ax;
-        pos.y += metric.ay;
+        pos->x += metric.ax;
+        pos->y += metric.ay;
 
 
         Free_Glyph glyph = {0};
         Free_Glyph glyph = {0};
         glyph.pos = vec2f(x2, -y2);
         glyph.pos = vec2f(x2, -y2);
@@ -255,7 +255,3 @@ void free_glyph_buffer_render_line_sized(Free_Glyph_Buffer *fgb, const char *tex
     }
     }
 }
 }
 
 
-void free_glyph_buffer_render_line(Free_Glyph_Buffer *fgb, const char *text, Vec2f pos, Vec4f fg_color, Vec4f bg_color)
-{
-    free_glyph_buffer_render_line_sized(fgb, text, strlen(text), pos, fg_color, bg_color);
-}

+ 2 - 2
src/free_glyph.h

@@ -81,7 +81,7 @@ void free_glyph_buffer_draw(Free_Glyph_Buffer *fgb);
 
 
 float free_glyph_buffer_cursor_pos(const Free_Glyph_Buffer *fgb, const char *text, size_t text_size, Vec2f pos, size_t col);
 float free_glyph_buffer_cursor_pos(const Free_Glyph_Buffer *fgb, const char *text, size_t text_size, Vec2f pos, size_t col);
 
 
-void free_glyph_buffer_render_line_sized(Free_Glyph_Buffer *fgb, const char *text, size_t text_size, Vec2f pos, Vec4f fg_color, Vec4f bg_color);
-void free_glyph_buffer_render_line(Free_Glyph_Buffer *fgb, const char *text, Vec2f pos, Vec4f fg_color, Vec4f bg_color);
+void free_glyph_buffer_render_line_sized(Free_Glyph_Buffer *fgb, const char *text, size_t text_size, Vec2f *pos, Vec4f fg_color, Vec4f bg_color);
+
 
 
 #endif // FREE_GLYPH_H_
 #endif // FREE_GLYPH_H_

+ 5 - 0
src/la.c

@@ -114,3 +114,8 @@ Vec4f vec4f_div(Vec4f a, Vec4f b)
 {
 {
     return vec4f(a.x / b.x, a.y / b.y, a.z / b.z, a.w / b.w);
     return vec4f(a.x / b.x, a.y / b.y, a.z / b.z, a.w / b.w);
 }
 }
+
+float lerpf(float a, float b, float t)
+{
+    return a + (b - a) * t;
+}

+ 2 - 0
src/la.h

@@ -36,4 +36,6 @@ Vec4f vec4f_sub(Vec4f a, Vec4f b);
 Vec4f vec4f_mul(Vec4f a, Vec4f b);
 Vec4f vec4f_mul(Vec4f a, Vec4f b);
 Vec4f vec4f_div(Vec4f a, Vec4f b);
 Vec4f vec4f_div(Vec4f a, Vec4f b);
 
 
+float lerpf(float a, float b, float t);
+
 #endif // LA_H_
 #endif // LA_H_

+ 27 - 3
src/main.c

@@ -35,6 +35,8 @@
 
 
 Editor editor = {0};
 Editor editor = {0};
 Vec2f camera_pos = {0};
 Vec2f camera_pos = {0};
+float camera_scale = 3.0f;
+float camera_scale_vel = 0.0f;
 Vec2f camera_vel = {0};
 Vec2f camera_vel = {0};
 
 
 void usage(FILE *stream)
 void usage(FILE *stream)
@@ -74,28 +76,39 @@ static Free_Glyph_Buffer fgb = {0};
 static Cursor_Renderer cr = {0};
 static Cursor_Renderer cr = {0};
 
 
 #define FREE_GLYPH_FONT_SIZE 64
 #define FREE_GLYPH_FONT_SIZE 64
+#define ZOOM_OUT_GLYPH_THRESHOLD 30
 
 
 void render_editor_into_fgb(SDL_Window *window, Free_Glyph_Buffer *fgb, Cursor_Renderer *cr, Editor *editor)
 void render_editor_into_fgb(SDL_Window *window, Free_Glyph_Buffer *fgb, Cursor_Renderer *cr, Editor *editor)
 {
 {
     int w, h;
     int w, h;
     SDL_GetWindowSize(window, &w, &h);
     SDL_GetWindowSize(window, &w, &h);
 
 
+    float max_line_len = 0.0f;
+
     free_glyph_buffer_use(fgb);
     free_glyph_buffer_use(fgb);
     {
     {
         glUniform2f(fgb->uniforms[UNIFORM_SLOT_RESOLUTION], (float) w, (float) h);
         glUniform2f(fgb->uniforms[UNIFORM_SLOT_RESOLUTION], (float) w, (float) h);
         glUniform1f(fgb->uniforms[UNIFORM_SLOT_TIME], (float) SDL_GetTicks() / 1000.0f);
         glUniform1f(fgb->uniforms[UNIFORM_SLOT_TIME], (float) SDL_GetTicks() / 1000.0f);
         glUniform2f(fgb->uniforms[UNIFORM_SLOT_CAMERA_POS], camera_pos.x, camera_pos.y);
         glUniform2f(fgb->uniforms[UNIFORM_SLOT_CAMERA_POS], camera_pos.x, camera_pos.y);
-        glUniform1f(fgb->uniforms[UNIFORM_SLOT_CAMERA_SCALE], 1.0f);
+        glUniform1f(fgb->uniforms[UNIFORM_SLOT_CAMERA_SCALE], camera_scale);
 
 
         free_glyph_buffer_clear(fgb);
         free_glyph_buffer_clear(fgb);
 
 
         {
         {
             for (size_t row = 0; row < editor->size; ++row) {
             for (size_t row = 0; row < editor->size; ++row) {
                 const Line *line = editor->lines + row;
                 const Line *line = editor->lines + row;
+
+                const Vec2f begin = vec2f(0, -(float)row * FREE_GLYPH_FONT_SIZE);
+                Vec2f end = begin;
                 free_glyph_buffer_render_line_sized(
                 free_glyph_buffer_render_line_sized(
                     fgb, line->chars, line->size,
                     fgb, line->chars, line->size,
-                    vec2f(0, -(float)row * FREE_GLYPH_FONT_SIZE),
+                    &end,
                     vec4fs(1.0f), vec4fs(0.0f));
                     vec4fs(1.0f), vec4fs(0.0f));
+                // TODO: the max_line_len should be calculated based on what's visible on the screen right now
+                float line_len = fabsf(end.x - begin.x);
+                if (line_len > max_line_len) {
+                    max_line_len = line_len;
+                }
             }
             }
         }
         }
 
 
@@ -118,7 +131,7 @@ void render_editor_into_fgb(SDL_Window *window, Free_Glyph_Buffer *fgb, Cursor_R
         glUniform2f(cr->uniforms[UNIFORM_SLOT_RESOLUTION], (float) w, (float) h);
         glUniform2f(cr->uniforms[UNIFORM_SLOT_RESOLUTION], (float) w, (float) h);
         glUniform1f(cr->uniforms[UNIFORM_SLOT_TIME], (float) SDL_GetTicks() / 1000.0f);
         glUniform1f(cr->uniforms[UNIFORM_SLOT_TIME], (float) SDL_GetTicks() / 1000.0f);
         glUniform2f(cr->uniforms[UNIFORM_SLOT_CAMERA_POS], camera_pos.x, camera_pos.y);
         glUniform2f(cr->uniforms[UNIFORM_SLOT_CAMERA_POS], camera_pos.x, camera_pos.y);
-        glUniform1f(cr->uniforms[UNIFORM_SLOT_CAMERA_SCALE], 1.0f);
+        glUniform1f(cr->uniforms[UNIFORM_SLOT_CAMERA_SCALE], camera_scale);
         glUniform1f(cr->uniforms[UNIFORM_SLOT_CURSOR_HEIGHT], FREE_GLYPH_FONT_SIZE);
         glUniform1f(cr->uniforms[UNIFORM_SLOT_CURSOR_HEIGHT], FREE_GLYPH_FONT_SIZE);
 
 
         cursor_renderer_move_to(cr, cursor_pos);
         cursor_renderer_move_to(cr, cursor_pos);
@@ -126,11 +139,22 @@ void render_editor_into_fgb(SDL_Window *window, Free_Glyph_Buffer *fgb, Cursor_R
     }
     }
 
 
     {
     {
+        float target_scale = 3.0f;
+        if (max_line_len > 0.0f) {
+            target_scale = SCREEN_WIDTH / max_line_len;
+        }
+
+        if (target_scale > 3.0f) {
+            target_scale = 3.0f;
+        }
+
         camera_vel = vec2f_mul(
         camera_vel = vec2f_mul(
                          vec2f_sub(cursor_pos, camera_pos),
                          vec2f_sub(cursor_pos, camera_pos),
                          vec2fs(2.0f));
                          vec2fs(2.0f));
+        camera_scale_vel = (target_scale - camera_scale) * 2.0f;
 
 
         camera_pos = vec2f_add(camera_pos, vec2f_mul(camera_vel, vec2fs(DELTA_TIME)));
         camera_pos = vec2f_add(camera_pos, vec2f_mul(camera_vel, vec2fs(DELTA_TIME)));
+        camera_scale = camera_scale + camera_scale_vel * DELTA_TIME;
     }
     }
 }
 }