exhibit ui
authorJohn Tsiombikas <nuclear@member.fsf.org>
Sun, 21 Jan 2018 05:01:50 +0000 (07:01 +0200)
committerJohn Tsiombikas <nuclear@member.fsf.org>
Sun, 21 Jan 2018 05:01:50 +0000 (07:01 +0200)
sdr/dfont.p.glsl [new file with mode: 0644]
sdr/dfont.v.glsl [new file with mode: 0644]
src/app.cc
src/ui_exhibit.cc

diff --git a/sdr/dfont.p.glsl b/sdr/dfont.p.glsl
new file mode 100644 (file)
index 0000000..dad3080
--- /dev/null
@@ -0,0 +1,12 @@
+uniform sampler2D tex;
+
+void main()
+{
+       const float softness = 0.008;
+
+       float alpha = texture2D(tex, gl_TexCoord[0].st).a;
+       float mask = smoothstep(0.5 - softness, 0.5 + softness, alpha);
+
+       gl_FragColor.rgb = gl_Color.rgb;
+       gl_FragColor.a = mask;
+}
diff --git a/sdr/dfont.v.glsl b/sdr/dfont.v.glsl
new file mode 100644 (file)
index 0000000..7aa01e4
--- /dev/null
@@ -0,0 +1,6 @@
+void main()
+{
+       gl_Position = ftransform();
+       gl_TexCoord[0] = gl_MultiTexCoord0;
+       gl_FrontColor = gl_Color;
+}
index 9a46f4a..0ac331b 100644 (file)
@@ -617,6 +617,22 @@ void app_keyboard(int key, bool pressed)
                case 'x':
                        exman->load(mscn, "data/exhibits");
                        break;
+
+               case KEY_UP:
+                       exui_scroll(-1);
+                       break;
+
+               case KEY_DOWN:
+                       exui_scroll(1);
+                       break;
+
+               case KEY_LEFT:
+                       exui_change_tab(-1);
+                       break;
+
+               case KEY_RIGHT:
+                       exui_change_tab(1);
+                       break;
                }
        }
 
index e583e5d..87fea01 100644 (file)
@@ -9,7 +9,7 @@
 #include "ui.h"
 #include "app.h"
 #include "snode.h"
-#include "shader.h"
+#include "sdr.h"
 #include "rtarg.h"
 
 struct Rect {
@@ -22,6 +22,10 @@ static void draw_tabs(const Rect &rect);
 static void draw_text(const Rect &rect);
 static void layout_text(const char *text);
 
+static struct dtx_font *font;
+static int font_size;
+static unsigned int fontsdr;
+
 static float aspect;
 static int ui_width, ui_height;
 
@@ -30,9 +34,10 @@ static const SceneNode *parent;
 static Vec3 pos;
 static Vec2 size;
 static int text_padding;
-static float text_scale = 1.0f;//0.05f;
+static float text_scale = 0.65f;
 static Exhibit *ex;
-static int vis_tab;
+static int vis_tab, num_tabs;
+static std::vector<std::string> tab_names;
 static float scroll;
 static std::vector<const char*> text_lines;
 static int max_line_size;
@@ -48,6 +53,17 @@ static float color[][3] = {
 
 bool exui_init()
 {
+       if(!(font = dtx_open_font_glyphmap("data/ui_en.glyphmap"))) {
+               error_log("failed to open exhibit ui font\n");
+               return false;
+       }
+       font_size = dtx_get_glyphmap_ptsize(dtx_get_glyphmap(font, 0));
+
+       if(!(fontsdr = create_program_load("sdr/dfont.v.glsl", "sdr/dfont.p.glsl"))) {
+               error_log("failed to load font shader\n");
+               return false;
+       }
+
        size.x = 15;
        size.y = 18;
        text_padding = 6;
@@ -57,7 +73,7 @@ bool exui_init()
        ui_width = ui_height * aspect;
 
        rtarg = new RenderTarget;
-       if(!rtarg->create(ui_width, ui_height, GL_SRGB_ALPHA)) {
+       if(!rtarg->create(ui_width, ui_height, GL_RGBA)) {
                error_log("failed to create exui render target\n");
                return false;
        }
@@ -67,6 +83,7 @@ bool exui_init()
 
 void exui_shutdown()
 {
+       dtx_close_font(font);
        delete rtarg;
 }
 
@@ -77,6 +94,7 @@ void exui_setnode(const SceneNode *node)
 
 void exui_change_tab(int dir)
 {
+       vis_tab = (vis_tab + dir) % num_tabs;
 }
 
 void exui_scroll(float delta)
@@ -94,6 +112,8 @@ void exui_update(float dt)
                ex = exsel_active.ex;
                scroll = 0.0f;
                vis_tab = 0;
+               num_tabs = 0;
+               tab_names.clear();
                text_lines.clear();
                if(voice) voice->stop();
 
@@ -103,6 +123,8 @@ void exui_update(float dt)
                                if(ex->data[i].type == EXDATA_INFO) {
                                        layout_text(ex->data[i].text.c_str());
                                        voice = ex->data[i].voice;
+                                       ++num_tabs;
+                                       tab_names.push_back("info");
                                }
                        }
 
@@ -117,7 +139,7 @@ void exui_update(float dt)
 
 static void draw_2d_ui()
 {
-       dtx_use_font(ui_font, ui_font_size);
+       dtx_use_font(font, font_size);
        float rowspc = dtx_line_height() * text_scale;
 
        glMatrixMode(GL_PROJECTION);
@@ -130,12 +152,13 @@ static void draw_2d_ui()
        glPushMatrix();
        glLoadIdentity();
 
-       bind_shader(0);
+       glUseProgram(0);
 
        glPushAttrib(GL_ENABLE_BIT);
        glDisable(GL_TEXTURE_2D);
        glDisable(GL_LIGHTING);
        glDisable(GL_DEPTH_TEST);
+       glEnable(GL_SCISSOR_TEST);
 
        Rect rect = {0, 0, (float)ui_width, (float)ui_height};
        draw_frame(rect);
@@ -143,8 +166,20 @@ static void draw_2d_ui()
        draw_titlebar(tbar_rect);
        Rect tabs_rect = {tbar_rect.x, tbar_rect.y + tbar_rect.h, tbar_rect.w, tbar_rect.h};
        draw_tabs(tabs_rect);
-       Rect text_rect = {rect.x, tabs_rect.y + tabs_rect.h, rect.w, rect.h - tabs_rect.y - tabs_rect.h};
-       draw_text(text_rect);
+
+       if(num_tabs) {
+               switch(ex->data[vis_tab].type) {
+               case EXDATA_INFO:
+                       {
+                               Rect text_rect = {rect.x, tabs_rect.y + tabs_rect.h, rect.w, rect.h - tabs_rect.y - tabs_rect.h};
+                               draw_text(text_rect);
+                       }
+                       break;
+
+               default:
+                       break;
+               }
+       }
 
        glPopAttrib();
 
@@ -157,7 +192,7 @@ static void draw_2d_ui()
 void exui_draw()
 {
        if(!exsel_active) return;
-       if(!ui_font) return;
+       if(!font) return;
 
        // render the 2D UI in a texture
        push_render_target(rtarg);
@@ -172,13 +207,6 @@ void exui_draw()
 
        Mat4 mvmat;
        glGetFloatv(GL_MODELVIEW_MATRIX, mvmat[0]);
-
-       /*
-       if(parent) {
-               glMultMatrixf(parent->get_matrix()[0]);
-       }
-       glTranslatef(pos.x, pos.y, pos.z);
-       */
        if(parent) {
                mvmat = parent->get_matrix() * mvmat;
        }
@@ -186,7 +214,6 @@ void exui_draw()
 
        mvmat[0][0] = mvmat[1][1] = mvmat[2][2] = 1.0f;
        mvmat[0][1] = mvmat[0][2] = mvmat[1][0] = mvmat[2][0] = mvmat[1][2] = mvmat[2][1] = 0.0f;
-
        glLoadMatrixf(mvmat[0]);
 
        glPushAttrib(GL_ENABLE_BIT);
@@ -195,7 +222,7 @@ void exui_draw()
        glEnable(GL_TEXTURE_2D);
        glDepthMask(0);
 
-       bind_shader(0);
+       glUseProgram(0);
        bind_texture(rtarg->texture());
 
        glMatrixMode(GL_TEXTURE);
@@ -235,8 +262,15 @@ static inline void draw_rect(const Rect &rect, int col)
        glEnd();
 }
 
+static void clip_rect(const Rect &rect)
+{
+       glScissor(rect.x, ui_height - rect.y - rect.h, rect.w, rect.h);
+}
+
 static void draw_frame(const Rect &rect)
 {
+       clip_rect(rect);
+
        draw_rect(rect, COL_BG);
        glLineWidth(3.0);
        glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
@@ -246,10 +280,14 @@ static void draw_frame(const Rect &rect)
 
 static void draw_titlebar(const Rect &rect)
 {
+       clip_rect(rect);
+
        draw_rect(rect, COL_FRM);
 
        const char *title = ex->get_name();
        if(title) {
+               glUseProgram(fontsdr);
+
                glPushMatrix();
                glTranslatef(rect.x + text_padding, rect.y + rect.h - text_padding, 0);
                glScalef(text_scale, -text_scale, text_scale);
@@ -257,18 +295,62 @@ static void draw_titlebar(const Rect &rect)
                glColor3fv(color[COL_BG]);
                dtx_string(ex->get_name());
                glPopMatrix();
+
+               glUseProgram(0);
        }
 }
 
 static void draw_tabs(const Rect &rect)
 {
+       if(!num_tabs) return;
+
+       clip_rect(rect);
+
+       glLineWidth(1);
+       if(num_tabs == 1) {
+               glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
+               draw_rect(rect, COL_FRM);
+               glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
+       }
+
+       int max_tab_size = ui_width / 2;
+       int tab_size = std::min(max_tab_size, ui_width / num_tabs);
+
+       for(int i=0; i<num_tabs; i++) {
+               Rect tr = {rect.x + i * tab_size, rect.y, (float)tab_size, rect.h};
+
+               clip_rect(tr);
+
+               if(vis_tab == i) {
+                       draw_rect(tr, COL_FRM);
+               } else {
+                       glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
+                       draw_rect(tr, COL_FRM);
+                       glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
+               }
+
+               glPushMatrix();
+               glTranslatef(tr.x + text_padding, tr.y + tr.h - text_padding, 0);
+               glScalef(text_scale, -text_scale, text_scale);
+
+               glUseProgram(fontsdr);
+               glColor3fv(color[vis_tab == i ? COL_BG : COL_FRM]);
+               dtx_string(tab_names[i].c_str());
+               glUseProgram(0);
+
+               glPopMatrix();
+       }
 }
 
 static void draw_text(const Rect &rect)
 {
+       clip_rect(rect);
+
        char *buf = (char*)alloca(max_line_size + 1);
 
-       float dy = dtx_line_height() * text_scale;
+       float dy = dtx_line_height();
+
+       glUseProgram(fontsdr);
 
        glMatrixMode(GL_MODELVIEW);
        glPushMatrix();
@@ -288,20 +370,22 @@ static void draw_text(const Rect &rect)
                        buf = (char*)text_lines[i];
                }
 
+               dtx_position(0, -dy * i);
                dtx_string(buf);
-               glTranslatef(0, -dy, 0);
        }
+       dtx_position(0, 0);
 
        glPopMatrix();
+       glUseProgram(0);
 }
 
 static void layout_text(const char *text)
 {
        text_lines.clear();
        if(!text) return;
-       if(!ui_font) return;
+       if(!font) return;
 
-       dtx_use_font(ui_font, ui_font_size);
+       dtx_use_font(font, font_size);
 
        int left_margin = text_padding;
        int right_margin = ui_width - text_padding;