X-Git-Url: http://git.mutantstargoat.com/user/nuclear/?p=laserbrain_demo;a=blobdiff_plain;f=src%2Fui_exhibit.cc;h=e583e5d5dd31d568e5e66ae6617c338567c62d76;hp=eda39c660f1c43cbcb5ed7c1502c0f6837209c9d;hb=dda1406df303fd1ec73344fbcce34c6197138642;hpb=92e1b315a32da123b2f8d7bb633375033a10c66d diff --git a/src/ui_exhibit.cc b/src/ui_exhibit.cc index eda39c6..e583e5d 100644 --- a/src/ui_exhibit.cc +++ b/src/ui_exhibit.cc @@ -1,9 +1,16 @@ +#include +#if defined(WIN32) || defined(__WIN32__) +#include +#else +#include +#endif #include #include "ui_exhibit.h" #include "ui.h" #include "app.h" #include "snode.h" #include "shader.h" +#include "rtarg.h" struct Rect { float x, y, w, h; @@ -15,20 +22,25 @@ static void draw_tabs(const Rect &rect); static void draw_text(const Rect &rect); static void layout_text(const char *text); +static float aspect; +static int ui_width, ui_height; + +static RenderTarget *rtarg; static const SceneNode *parent; static Vec3 pos; static Vec2 size; -static float text_padding; -static float text_scale = 0.05f; +static int text_padding; +static float text_scale = 1.0f;//0.05f; static Exhibit *ex; static int vis_tab; static float scroll; static std::vector text_lines; +static int max_line_size; static AudioStream *voice; enum {COL_BG, COL_FG, COL_FRM}; static float color[][3] = { - {0.09, 0.14, 0.2}, // COL_BG + {0.014, 0.016, 0.04}, // COL_BG {0.31, 0.58, 0.9}, // COL_FG {0.19, 0.23, 0.46} // COL_FRM }; @@ -38,13 +50,24 @@ bool exui_init() { size.x = 15; size.y = 18; - text_padding = size.x * 0.01; + text_padding = 6; + + aspect = size.x / size.y; + ui_height = 512; + ui_width = ui_height * aspect; + + rtarg = new RenderTarget; + if(!rtarg->create(ui_width, ui_height, GL_SRGB_ALPHA)) { + error_log("failed to create exui render target\n"); + return false; + } return true; } void exui_shutdown() { + delete rtarg; } void exui_setnode(const SceneNode *node) @@ -92,44 +115,106 @@ void exui_update(float dt) } } +static void draw_2d_ui() +{ + dtx_use_font(ui_font, ui_font_size); + float rowspc = dtx_line_height() * text_scale; + + glMatrixMode(GL_PROJECTION); + glPushMatrix(); + glLoadIdentity(); + glTranslatef(-1, 1, 0); + glScalef(2.0 / ui_width, -2.0 / ui_height, 1); + + glMatrixMode(GL_MODELVIEW); + glPushMatrix(); + glLoadIdentity(); + + bind_shader(0); + + glPushAttrib(GL_ENABLE_BIT); + glDisable(GL_TEXTURE_2D); + glDisable(GL_LIGHTING); + glDisable(GL_DEPTH_TEST); + + Rect rect = {0, 0, (float)ui_width, (float)ui_height}; + draw_frame(rect); + Rect tbar_rect = {rect.x, rect.y, rect.w, rowspc + text_padding}; // half the padding + 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); + + glPopAttrib(); + + glMatrixMode(GL_PROJECTION); + glPopMatrix(); + glMatrixMode(GL_MODELVIEW); + glPopMatrix(); +} + void exui_draw() { if(!exsel_active) return; if(!ui_font) return; - dtx_use_font(ui_font, ui_font_size); - float rowspc = dtx_line_height() * text_scale; - - Rect rect = {-size.x / 2.0f, -size.y / 2.0f, size.x, size.y}; + // render the 2D UI in a texture + push_render_target(rtarg); + glClearColor(0, 1, 0, 0); + glClear(GL_COLOR_BUFFER_BIT); + draw_2d_ui(); + pop_render_target(); + // place UI image into the scene glMatrixMode(GL_MODELVIEW); glPushMatrix(); + + Mat4 mvmat; + glGetFloatv(GL_MODELVIEW_MATRIX, mvmat[0]); + + /* if(parent) { glMultMatrixf(parent->get_matrix()[0]); } glTranslatef(pos.x, pos.y, pos.z); - glScalef(1, -1, 1); + */ + if(parent) { + mvmat = parent->get_matrix() * mvmat; + } + mvmat.translate(pos.x, pos.y, pos.z); - bind_shader(0); + 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); - glDisable(GL_TEXTURE_2D); - glDisable(GL_LIGHTING); glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE); + glEnable(GL_TEXTURE_2D); glDepthMask(0); - draw_frame(rect); - Rect tbar_rect = {rect.x, rect.y, rect.w, rowspc}; - draw_titlebar(tbar_rect); - Rect tabs_rect = {tbar_rect.x, tbar_rect.y + rowspc, tbar_rect.w, tbar_rect.h}; - draw_tabs(tabs_rect); - Rect text_rect = {rect.x, tabs_rect.y + rowspc, rect.w, rect.h - tabs_rect.y - rowspc}; - draw_text(text_rect); + bind_shader(0); + bind_texture(rtarg->texture()); + + glMatrixMode(GL_TEXTURE); + glLoadMatrixf(rtarg->texture_matrix()[0]); + + glBegin(GL_QUADS); + glColor3f(1, 1, 1); + glTexCoord2f(0, 0); glVertex2f(-size.x / 2, -size.y / 2); + glTexCoord2f(1, 0); glVertex2f(size.x / 2, -size.y / 2); + glTexCoord2f(1, 1); glVertex2f(size.x / 2, size.y / 2); + glTexCoord2f(0, 1); glVertex2f(-size.x / 2, size.y / 2); + glEnd(); + + glLoadIdentity(); glDepthMask(1); glPopAttrib(); + glMatrixMode(GL_MODELVIEW); glPopMatrix(); } @@ -153,7 +238,7 @@ static inline void draw_rect(const Rect &rect, int col) static void draw_frame(const Rect &rect) { draw_rect(rect, COL_BG); - glLineWidth(2.0); + glLineWidth(3.0); glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); draw_rect(rect, COL_FRM); glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); @@ -181,6 +266,33 @@ static void draw_tabs(const Rect &rect) static void draw_text(const Rect &rect) { + char *buf = (char*)alloca(max_line_size + 1); + + float dy = dtx_line_height() * text_scale; + + glMatrixMode(GL_MODELVIEW); + glPushMatrix(); + glTranslatef(rect.x + text_padding, rect.y + dy + text_padding, 0); + glScalef(text_scale, -text_scale, text_scale); + + glColor3fv(color[COL_FG]); + + int nlines = text_lines.size() - 1; + for(int i=0; i= size.x - text_padding) { + if(pos > right_margin) { if(text == text_lines.back()) { // not even a single character fits on a line... abort - warning_log("text layout failed. glyph %d doesn't fit in line (%g)\n", code, size.x - 2.0 * text_padding); + warning_log("text layout failed. glyph %d doesn't fit in line (%d)\n", code, right_margin - left_margin); text_lines.clear(); return; } @@ -226,7 +343,9 @@ static void layout_text(const char *text) // no good point to break, just break here text_lines.push_back(text); } - pos = text_padding; + + int d = text_lines.back() - (text_lines[text_lines.size() - 2]); + if(d > max_line_size) max_line_size = d; } text = next; }