rayfract
changeset 2:87b6a11c920b
added gui stuff
author | John Tsiombikas <nuclear@siggraph.org> |
---|---|
date | Tue, 26 Oct 2010 08:49:09 +0300 |
parents | 03022062c464 |
children | bf1d56975cc9 |
files | src/gui.cc src/gui.h src/utktext.cc src/utktext.h |
diffstat | 4 files changed, 794 insertions(+), 0 deletions(-) [+] |
line diff
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/src/gui.cc Tue Oct 26 08:49:09 2010 +0300 1.3 @@ -0,0 +1,295 @@ 1.4 +#include <stdio.h> 1.5 + 1.6 +#ifndef __APPLE__ 1.7 +#include <GL/glut.h> 1.8 +#else 1.9 +#include <GLUT/glut.h> 1.10 +#endif 1.11 + 1.12 +#include <vmath.h> 1.13 +#include <ubertk.h> 1.14 +#include "gui.h" 1.15 +#include "utktext.h" 1.16 +#include "sdr.h" 1.17 + 1.18 +#define TEXT_PT_SIZE 18 1.19 + 1.20 +void huecb(utk::Event *ev, void *cls); 1.21 +static void cbfunc(utk::Event *ev, void *cls); 1.22 + 1.23 +void utk_color(int r, int g, int b, int a); 1.24 +void utk_clip(int x1, int y1, int x2, int y2); 1.25 +void utk_image(int x, int y, const void *pix, int xsz, int ysz); 1.26 + 1.27 +void utk_rect(int x1, int y1, int x2, int y2); 1.28 +void utk_line(int x1, int y1, int x2, int y2, int width); 1.29 + 1.30 +void utk_text(int x, int y, const char *txt, int sz); 1.31 +int utk_text_spacing(); 1.32 +int utk_text_width(const char *txt, int sz); 1.33 + 1.34 + 1.35 +int xsz, ysz; 1.36 +static utk::Container *utkroot; 1.37 +static float max_descent; 1.38 +utk::Window *win_seed, *win_material; 1.39 + 1.40 + 1.41 +extern unsigned int sdr; 1.42 +extern Vector4 seed; 1.43 +extern int iter; 1.44 +extern float err_thres; 1.45 +extern float reflectivity; 1.46 +extern Vector3 color; 1.47 + 1.48 +int gui_init(int width, int height) 1.49 +{ 1.50 + xsz = width; 1.51 + ysz = height; 1.52 + 1.53 + if(!CreateFont("georgia.ttf", TEXT_PT_SIZE)) { 1.54 + fprintf(stderr, "failed to load font\n"); 1.55 + return -1; 1.56 + } 1.57 + max_descent = GetMaxDescent(); 1.58 + 1.59 + utk::gfx::color = utk_color; 1.60 + utk::gfx::clip = utk_clip; 1.61 + utk::gfx::image = utk_image; 1.62 + utk::gfx::rect = utk_rect; 1.63 + utk::gfx::line = utk_line; 1.64 + utk::gfx::text = utk_text; 1.65 + utk::gfx::text_spacing = utk_text_spacing; 1.66 + utk::gfx::text_width = utk_text_width; 1.67 + 1.68 + utkroot = utk::init(xsz, ysz); 1.69 + 1.70 + win_seed = utk::create_window(utkroot, 5, 25, 220, 175, "julia parameters"); 1.71 + win_seed->set_alpha(128); 1.72 + win_seed->show(); 1.73 + 1.74 + utk::VBox *vbox = utk::create_vbox(win_seed); 1.75 + utk::HBox *hbox; 1.76 + 1.77 + hbox = utk::create_hbox(vbox); 1.78 + utk::create_label(hbox, "seed x"); 1.79 + utk::create_slider(hbox, -1.0, 1.0, cbfunc, (void*)0)->set_value(seed.x); 1.80 + hbox = utk::create_hbox(vbox); 1.81 + utk::create_label(hbox, "seed y"); 1.82 + utk::create_slider(hbox, -1.0, 1.0, cbfunc, (void*)1)->set_value(seed.y); 1.83 + hbox = utk::create_hbox(vbox); 1.84 + utk::create_label(hbox, "seed z"); 1.85 + utk::create_slider(hbox, -1.0, 1.0, cbfunc, (void*)2)->set_value(seed.z); 1.86 + hbox = utk::create_hbox(vbox); 1.87 + utk::create_label(hbox, "seed w"); 1.88 + utk::create_slider(hbox, -1.0, 1.0, cbfunc, (void*)3)->set_value(seed.w); 1.89 + 1.90 + hbox = utk::create_hbox(vbox); 1.91 + utk::create_label(hbox, "iterations"); 1.92 + utk::Slider *iter_slider = utk::create_slider(hbox, 0, 32, cbfunc, (void*)5); 1.93 + iter_slider->set_value(iter); 1.94 + iter_slider->set_vis_decimal(0); 1.95 + 1.96 + hbox = utk::create_hbox(vbox); 1.97 + utk::create_label(hbox, "max error"); 1.98 + utk::Slider *err_slider = utk::create_slider(hbox, 0, 0.075, cbfunc, (void*)6); 1.99 + err_slider->set_value(err_thres); 1.100 + err_slider->set_vis_decimal(4); 1.101 + 1.102 + win_material = utk::create_window(utkroot, 250, 25, 220, 210, "material"); 1.103 + win_material->set_alpha(128); 1.104 + win_material->show(); 1.105 + ((utk::WinFrame*)win_material->get_parent())->set_shade(true); 1.106 + 1.107 + vbox = utk::create_vbox(win_material); 1.108 + 1.109 + utk::ColorBox *colbox = new utk::ColorBox; 1.110 + vbox->add_child(colbox); 1.111 + utk::HueBox *huebox = new utk::HueBox; 1.112 + vbox->add_child(huebox); 1.113 + huebox->set_callback(utk::EVENT_MODIFY, huecb, colbox); 1.114 + 1.115 + float hue, sat, val; 1.116 + utk::rgb_to_hsv(color.x, color.y, color.z, &hue, &sat, &val); 1.117 + colbox->set_color_hsv(hue, sat, val); 1.118 + huebox->set_h(hue); 1.119 + 1.120 + hbox = utk::create_hbox(vbox); 1.121 + utk::create_label(hbox, "reflectivity"); 1.122 + utk::create_slider(hbox, 0, 1.0, cbfunc, (void*)4)->set_value(reflectivity); 1.123 + 1.124 + return 0; 1.125 +} 1.126 + 1.127 +void gui_draw() 1.128 +{ 1.129 + glMatrixMode(GL_MODELVIEW); 1.130 + glPushMatrix(); 1.131 + glLoadIdentity(); 1.132 + glMatrixMode(GL_PROJECTION); 1.133 + glPushMatrix(); 1.134 + glLoadIdentity(); 1.135 + 1.136 + glPushAttrib(GL_ENABLE_BIT); 1.137 + glDisable(GL_LIGHTING); 1.138 + glDisable(GL_DEPTH_TEST); 1.139 + glDisable(GL_CULL_FACE); 1.140 + glEnable(GL_BLEND); 1.141 + 1.142 + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); 1.143 + 1.144 + utk::draw(); 1.145 + 1.146 + glPopAttrib(); 1.147 + 1.148 + glMatrixMode(GL_PROJECTION); 1.149 + glPopMatrix(); 1.150 + glMatrixMode(GL_MODELVIEW); 1.151 + glPopMatrix(); 1.152 +} 1.153 + 1.154 +void gui_set_visible(bool vis) 1.155 +{ 1.156 + if(vis) { 1.157 + win_seed->show(); 1.158 + win_material->show(); 1.159 + } else { 1.160 + win_seed->hide(); 1.161 + win_material->hide(); 1.162 + } 1.163 +} 1.164 + 1.165 +void huecb(utk::Event *ev, void *cls) 1.166 +{ 1.167 + utk::HueBox *huebox = (utk::HueBox*)ev->widget; 1.168 + utk::ColorBox *colbox = (utk::ColorBox*)cls; 1.169 + 1.170 + colbox->set_h(huebox->get_h()); 1.171 +} 1.172 + 1.173 +void cbfunc(utk::Event *ev, void *cls) 1.174 +{ 1.175 + int id = (int)(intptr_t)cls; 1.176 + 1.177 + switch(id) { 1.178 + case 0: 1.179 + case 1: 1.180 + case 2: 1.181 + case 3: 1.182 + { 1.183 + utk::Slider *slider = (utk::Slider*)ev->widget; 1.184 + 1.185 + seed[id] = slider->get_value(); 1.186 + set_uniform_float4(sdr, "seed", seed.x, seed.y, seed.z, seed.w); 1.187 + glutPostRedisplay(); 1.188 + } 1.189 + break; 1.190 + 1.191 + case 4: 1.192 + { 1.193 + utk::Slider *slider = (utk::Slider*)ev->widget; 1.194 + 1.195 + reflectivity = slider->get_value(); 1.196 + set_uniform_float(sdr, "reflectivity", reflectivity); 1.197 + glutPostRedisplay(); 1.198 + } 1.199 + break; 1.200 + 1.201 + case 5: 1.202 + { 1.203 + utk::Slider *slider = (utk::Slider*)ev->widget; 1.204 + 1.205 + iter = (int)slider->get_value(); 1.206 + set_uniform_int(sdr, "iter", iter); 1.207 + glutPostRedisplay(); 1.208 + } 1.209 + break; 1.210 + 1.211 + case 6: 1.212 + { 1.213 + utk::Slider *slider = (utk::Slider*)ev->widget; 1.214 + 1.215 + err_thres = slider->get_value(); 1.216 + set_uniform_float(sdr, "err_thres", err_thres); 1.217 + glutPostRedisplay(); 1.218 + } 1.219 + break; 1.220 + 1.221 + default: 1.222 + fprintf(stderr, "unhandled callback (id: %d)\n", id); 1.223 + break; 1.224 + } 1.225 +} 1.226 + 1.227 + 1.228 +#define CONVX(x) (2.0 * (float)(x) / (float)xsz - 1.0) 1.229 +#define CONVY(y) (1.0 - 2.0 * (float)(y) / (float)ysz) 1.230 + 1.231 +void utk_color(int r, int g, int b, int a) 1.232 +{ 1.233 + glColor4ub(r, g, b, a); 1.234 + SetTextColor(Color(r / 255.0, g / 255.0, b / 255.0, a / 255.0)); 1.235 +} 1.236 + 1.237 +void utk_clip(int x1, int y1, int x2, int y2) 1.238 +{ 1.239 + if(x1 == x2 && y1 == y2 && x1 == y1 && x1 == 0) { 1.240 + glDisable(GL_SCISSOR_TEST); 1.241 + } else { 1.242 + glEnable(GL_SCISSOR_TEST); 1.243 + } 1.244 + glScissor(x1, ysz - y2, x2 - x1, y2 - y1); 1.245 +} 1.246 + 1.247 +void utk_image(int x, int y, const void *pix, int w, int h) 1.248 +{ 1.249 + glPixelZoom(1, -1); 1.250 + glRasterPos2f(CONVX(x), CONVY(y)); 1.251 + glDrawPixels(w, h, GL_BGRA, GL_UNSIGNED_BYTE, pix); 1.252 +} 1.253 + 1.254 +void utk_rect(int x1, int y1, int x2, int y2) 1.255 +{ 1.256 + glRectf(CONVX(x1), CONVY(y1), CONVX(x2), CONVY(y2)); 1.257 +} 1.258 + 1.259 +void utk_line(int x1, int y1, int x2, int y2, int width) 1.260 +{ 1.261 + glPushAttrib(GL_LINE_BIT); 1.262 + 1.263 + glLineWidth((float)width); 1.264 + glBegin(GL_LINES); 1.265 + glVertex2f(CONVX(x1), CONVY(y1)); 1.266 + glVertex2f(CONVX(x2), CONVY(y2)); 1.267 + glEnd(); 1.268 + 1.269 + glPopAttrib(); 1.270 +} 1.271 + 1.272 +void utk_text(int x, int y, const char *txt, int sz) 1.273 +{ 1.274 + float fx = (float)x / (float)xsz; 1.275 + float fy = (float)y / (float)ysz; 1.276 + 1.277 + SetTextPos(Vector2(fx, fy - max_descent)); 1.278 + //SetTextPos(Vector2(0.25, 0.25)); 1.279 + SetTextSize((float)sz / (float)TEXT_PT_SIZE); 1.280 + PrintString(txt); 1.281 +} 1.282 + 1.283 +int utk_text_spacing() 1.284 +{ 1.285 + return (int)(GetLineAdvance() * (float)ysz); 1.286 +} 1.287 + 1.288 +int utk_text_width(const char *txt, int sz) 1.289 +{ 1.290 + float prev_sz = GetTextSize(); 1.291 + SetTextSize((float)sz / (float)TEXT_PT_SIZE); 1.292 + 1.293 + int width = (int)(GetTextWidth(txt) * (float)xsz); 1.294 + 1.295 + SetTextSize(prev_sz); 1.296 + return width; 1.297 +} 1.298 +
2.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 2.2 +++ b/src/gui.h Tue Oct 26 08:49:09 2010 +0300 2.3 @@ -0,0 +1,10 @@ 2.4 +#ifndef GUI_H_ 2.5 +#define GUI_H_ 2.6 + 2.7 +#include <ubertk.h> 2.8 + 2.9 +int gui_init(int xsz, int ysz); 2.10 +void gui_draw(); 2.11 +void gui_set_visible(bool vis); 2.12 + 2.13 +#endif
3.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 3.2 +++ b/src/utktext.cc Tue Oct 26 08:49:09 2010 +0300 3.3 @@ -0,0 +1,444 @@ 3.4 +#include <math.h> 3.5 +#include <ctype.h> 3.6 +#define GL_GLEXT_PROTOTYPES 3.7 +#if defined(__APPLE__) && defined(__MACH__) 3.8 +#include <GLUT/glut.h> 3.9 +#else 3.10 +#include <GL/glut.h> 3.11 +#endif 3.12 +#include <ft2build.h> 3.13 +#include FT_FREETYPE_H 3.14 +#include <vmath.h> 3.15 +#include "utktext.h" 3.16 +#include "utk_common.h" 3.17 + 3.18 +#ifndef GL_BGRA 3.19 +#define GL_BGRA 0x80E1 3.20 +#endif 3.21 + 3.22 +#ifndef GL_ABGR 3.23 +#define GL_ABGR 0x8000 3.24 +#endif 3.25 + 3.26 +#ifdef UTK_BIG_ENDIAN 3.27 +#define PIXFMT GL_ABGR 3.28 +#else 3.29 +#define PIXFMT GL_BGRA 3.30 +#endif 3.31 + 3.32 +#define MAX_CHARS 128 3.33 +#define MAX_IMG_WIDTH 1024 3.34 +#define SIZE_PIXELS(x) ((x) / 64) 3.35 + 3.36 +struct Font { 3.37 + unsigned int tex_id; 3.38 + float scale; // this compensates if a higher res font is loaded in its stead, with a new CreateFont 3.39 + float line_adv; // vertical advance to go to the next line 3.40 + struct { 3.41 + Vector2 pos, size; // glyph position (from origin) and size in normalized coords [0, 1] 3.42 + float advance; // advance in normalized coords 3.43 + Vector2 tc_pos, tc_sz; // tex coord box pos/size 3.44 + } glyphs[MAX_CHARS]; 3.45 +}; 3.46 + 3.47 +static void BlitFontGlyph(Font *fnt, int x, int y, FT_GlyphSlot glyph, unsigned int *img, int xsz, int ysz); 3.48 +static void CleanUp(); 3.49 + 3.50 +static FT_Library ft; 3.51 +static Vector2 text_pos; 3.52 +static float text_size = 1.0; 3.53 +static Color text_color; 3.54 +static Font *act_fnt; 3.55 + 3.56 +#if !defined(GLIBC) && !defined(__GLIBC__) 3.57 +float log2(float x) { 3.58 + float res = 0.0; 3.59 + while(x > 1.0) { 3.60 + x /= 2.0; 3.61 + res += 1.0; 3.62 + } 3.63 + return res; 3.64 +} 3.65 +#endif // _MSC_VER 3.66 + 3.67 + 3.68 +static inline int NextPow2(int x) 3.69 +{ 3.70 + float lg2 = log2((float)x); 3.71 + return (int)pow(2.0f, (int)ceil(lg2)); 3.72 +} 3.73 + 3.74 + 3.75 +unsigned int CreateFont(const char *fname, int font_size) 3.76 +{ 3.77 + if(!ft) { 3.78 + if(FT_Init_FreeType(&ft) != 0) { 3.79 + fprintf(stderr, "failed to initialize freetype\n"); 3.80 + return 0; 3.81 + } 3.82 + atexit(CleanUp); 3.83 + } 3.84 + 3.85 + FT_Face face; 3.86 + if(FT_New_Face(ft, fname, 0, &face) != 0) { 3.87 + fprintf(stderr, "failed to load font: %s\n", fname); 3.88 + return 0; 3.89 + } 3.90 + 3.91 + FT_Set_Pixel_Sizes(face, 0, font_size); 3.92 + 3.93 + Font *fnt = new Font; 3.94 + int max_width = MAX_CHARS * SIZE_PIXELS(face->bbox.xMax - face->bbox.xMin); 3.95 + int foo_xsz = MAX_IMG_WIDTH; 3.96 + int foo_ysz = SIZE_PIXELS(face->bbox.yMax - face->bbox.yMin) * max_width / foo_xsz; 3.97 + 3.98 + int tex_xsz = NextPow2(foo_xsz); 3.99 + int tex_ysz = NextPow2(foo_ysz); 3.100 + 3.101 + unsigned int *img; 3.102 + img = new unsigned int[tex_xsz * tex_ysz]; 3.103 + memset(img, 0, tex_xsz * tex_ysz * sizeof *img); 3.104 + 3.105 + extern int xsz, ysz; 3.106 + int vport_xsz = xsz, vport_ysz = ysz; 3.107 + 3.108 + int max_glyph_y = 0; 3.109 + int max_glyph_x = 0; 3.110 + for(int i=0; i<MAX_CHARS; i++) { 3.111 + FT_Load_Char(face, i, 0); 3.112 + int width = SIZE_PIXELS(face->glyph->metrics.width); 3.113 + int height = SIZE_PIXELS(face->glyph->metrics.height); 3.114 + 3.115 + if(height > max_glyph_y) { 3.116 + max_glyph_y = height; 3.117 + } 3.118 + 3.119 + if(width > max_glyph_x) { 3.120 + max_glyph_x = width; 3.121 + } 3.122 + } 3.123 + 3.124 + int gx = 0, gy = 0; 3.125 + for(int i=0; i<MAX_CHARS; i++) { 3.126 + FT_Load_Char(face, i, FT_LOAD_RENDER); 3.127 + FT_GlyphSlot g = face->glyph; 3.128 + 3.129 + int gwidth = SIZE_PIXELS(g->metrics.width); 3.130 + int gheight = SIZE_PIXELS(g->metrics.height); 3.131 + 3.132 + if(gx > MAX_IMG_WIDTH - gwidth) { 3.133 + gx = 0; 3.134 + gy += max_glyph_y; 3.135 + } 3.136 + 3.137 + BlitFontGlyph(fnt, gx, gy, g, img, tex_xsz, tex_ysz); 3.138 + fnt->scale = 1.0; 3.139 + fnt->line_adv = (float)SIZE_PIXELS(g->metrics.vertAdvance) / (float)vport_ysz; 3.140 + fnt->glyphs[i].tc_pos.x = (float)gx / (float)tex_xsz; 3.141 + fnt->glyphs[i].tc_pos.y = (float)gy / (float)tex_ysz; 3.142 + fnt->glyphs[i].tc_sz.x = (float)gwidth / (float)tex_xsz; 3.143 + fnt->glyphs[i].tc_sz.y = (float)gheight / (float)tex_ysz; 3.144 + fnt->glyphs[i].size.x = (float)gwidth / (float)vport_xsz; 3.145 + fnt->glyphs[i].size.y = (float)gheight / (float)vport_ysz; 3.146 + fnt->glyphs[i].pos.x = (float)SIZE_PIXELS(g->metrics.horiBearingX) / (float)vport_xsz; 3.147 + fnt->glyphs[i].pos.y = -(float)SIZE_PIXELS(g->metrics.horiBearingY) / (float)vport_ysz; 3.148 + fnt->glyphs[i].advance = (float)SIZE_PIXELS(g->metrics.horiAdvance) / (float)vport_xsz; 3.149 + 3.150 + gx += gwidth; 3.151 + } 3.152 + 3.153 + FT_Done_Face(face); 3.154 + 3.155 + glGenTextures(1, &fnt->tex_id); 3.156 + glBindTexture(GL_TEXTURE_2D, fnt->tex_id); 3.157 + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); 3.158 + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); 3.159 + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 3.160 + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 3.161 + glTexImage2D(GL_TEXTURE_2D, 0, 4, tex_xsz, tex_ysz, 0, PIXFMT, GL_UNSIGNED_BYTE, img); 3.162 + 3.163 +#ifdef DUMP_FONT_IMG 3.164 + FILE *fp; 3.165 + unsigned int *ptr = img; 3.166 + 3.167 + if((fp = fopen("fnt.ppm", "wb"))) { 3.168 + fprintf(fp, "P6\n%d %d\n255\n", tex_xsz, tex_ysz); 3.169 + 3.170 + for(int i=0; i<tex_xsz * tex_ysz; i++) { 3.171 + fputc((*ptr >> 24) & 0xff, fp); 3.172 + fputc((*ptr >> 24) & 0xff, fp); 3.173 + fputc((*ptr >> 24) & 0xff, fp); 3.174 + ptr++; 3.175 + } 3.176 + fclose(fp); 3.177 + } 3.178 +#endif 3.179 + 3.180 + delete [] img; 3.181 + 3.182 + act_fnt = fnt; 3.183 + 3.184 + return 1; 3.185 +} 3.186 + 3.187 +void DeleteFont(unsigned int fid) 3.188 +{ 3.189 +} 3.190 + 3.191 +unsigned int GetFont(const char *fname, int sz) 3.192 +{ 3.193 + return 1; 3.194 +} 3.195 + 3.196 +bool BindFont(unsigned int fid) 3.197 +{ 3.198 + return true; 3.199 +} 3.200 + 3.201 +void SetTextPos(const Vector2 &pos) 3.202 +{ 3.203 + text_pos = pos; 3.204 +} 3.205 + 3.206 +Vector2 GetTextPos() 3.207 +{ 3.208 + return text_pos; 3.209 +} 3.210 + 3.211 +void TextLineAdvance(int adv) 3.212 +{ 3.213 + text_pos.y += (float)adv * act_fnt->line_adv; 3.214 +} 3.215 + 3.216 +void TextCRet() 3.217 +{ 3.218 + text_pos.x = 0.0; 3.219 +} 3.220 + 3.221 +void SetTextSize(float sz) 3.222 +{ 3.223 + text_size = sz; 3.224 +} 3.225 + 3.226 +float GetTextSize() 3.227 +{ 3.228 + return text_size; 3.229 +} 3.230 + 3.231 +void SetTextColor(const Color &col) 3.232 +{ 3.233 + text_color = col; 3.234 +} 3.235 + 3.236 +Color GetTextColor() 3.237 +{ 3.238 + return text_color; 3.239 +} 3.240 + 3.241 +static void ImOverlay(const Vector2 &v1, const Vector2 &v2, const Color &col, unsigned int tex) 3.242 +{ 3.243 + float l = v1.x * 2.0f - 1.0f; 3.244 + float r = v2.x * 2.0f - 1.0f; 3.245 + float u = -v1.y * 2.0f + 1.0f; 3.246 + float d = -v2.y * 2.0f + 1.0f; 3.247 + 3.248 + glMatrixMode(GL_PROJECTION); 3.249 + glPushMatrix(); 3.250 + glLoadIdentity(); 3.251 + glMatrixMode(GL_MODELVIEW); 3.252 + glPushMatrix(); 3.253 + glLoadIdentity(); 3.254 + 3.255 + glBindTexture(GL_TEXTURE_2D, tex); 3.256 + 3.257 + glDisable(GL_DEPTH_TEST); 3.258 + glDisable(GL_LIGHTING); 3.259 + glDisable(GL_CULL_FACE); 3.260 + 3.261 + glBegin(GL_QUADS); 3.262 + glColor4f(col.r, col.g, col.b, col.a); 3.263 + glTexCoord2f(0, 0); 3.264 + glVertex2f(l, u); 3.265 + glTexCoord2f(1, 0); 3.266 + glVertex2f(r, u); 3.267 + glTexCoord2f(1, 1); 3.268 + glVertex2f(r, d); 3.269 + glTexCoord2f(0, 1); 3.270 + glVertex2f(l, d); 3.271 + glEnd(); 3.272 + 3.273 + glEnable(GL_LIGHTING); 3.274 + glEnable(GL_DEPTH_TEST); 3.275 + 3.276 + glMatrixMode(GL_PROJECTION); 3.277 + glPopMatrix(); 3.278 + glMatrixMode(GL_MODELVIEW); 3.279 + glPopMatrix(); 3.280 +} 3.281 + 3.282 +float PrintChar(char c) 3.283 +{ 3.284 + // get texture coordinates for the glyph, and construct the texture matrix 3.285 + float tx = act_fnt->glyphs[(int)c].tc_pos.x; 3.286 + float ty = act_fnt->glyphs[(int)c].tc_pos.y; 3.287 + float sx = act_fnt->glyphs[(int)c].tc_sz.x; 3.288 + float sy = act_fnt->glyphs[(int)c].tc_sz.y; 3.289 + 3.290 + float mat[] = { 3.291 + sx, 0, tx, 0, 3.292 + 0, sy, ty, 0, 3.293 + 0, 0, 1, 0, 3.294 + 0, 0, 0, 1 3.295 + }; 3.296 + 3.297 + glMatrixMode(GL_TEXTURE); 3.298 + glPushMatrix(); 3.299 + glLoadMatrixf(mat); 3.300 + 3.301 + Vector2 pos = text_pos + act_fnt->glyphs[(int)c].pos * act_fnt->scale; 3.302 + ImOverlay(pos, pos + act_fnt->glyphs[(int)c].size * act_fnt->scale, text_color, act_fnt->tex_id); 3.303 + 3.304 + glMatrixMode(GL_TEXTURE); 3.305 + glPopMatrix(); 3.306 + 3.307 + return act_fnt->glyphs[(int)c].advance * act_fnt->scale; 3.308 +} 3.309 + 3.310 +// this function contains the preamble of all block text drawing functions (i.e. not printchar above) 3.311 +static void PreDraw() 3.312 +{ 3.313 + glMatrixMode(GL_PROJECTION); 3.314 + glPushMatrix(); 3.315 + /*glLoadTransposeMatrixf(OrthoProj(2, 2, 0, 10).m);*/ 3.316 + glLoadIdentity(); 3.317 + glMatrixMode(GL_MODELVIEW); 3.318 + glPushMatrix(); 3.319 + glLoadIdentity(); 3.320 + glMatrixMode(GL_TEXTURE); 3.321 + glPushMatrix(); 3.322 + glLoadIdentity(); 3.323 + 3.324 + glEnable(GL_TEXTURE_2D); 3.325 + glBindTexture(GL_TEXTURE_2D, act_fnt->tex_id); 3.326 + 3.327 + glBegin(GL_QUADS); 3.328 + glColor4f(text_color.r, text_color.g, text_color.b, text_color.a); 3.329 +} 3.330 + 3.331 +static void PostDraw() 3.332 +{ 3.333 + glEnd(); 3.334 + 3.335 + glDisable(GL_TEXTURE_2D); 3.336 + 3.337 + glMatrixMode(GL_TEXTURE); 3.338 + glPopMatrix(); 3.339 + glMatrixMode(GL_MODELVIEW); 3.340 + glPopMatrix(); 3.341 + glMatrixMode(GL_PROJECTION); 3.342 + glPopMatrix(); 3.343 +} 3.344 + 3.345 +float PrintString(const char *str, bool standalone) 3.346 +{ 3.347 + if(standalone) PreDraw(); 3.348 + 3.349 + float start_x = text_pos.x; 3.350 + while(*str) { 3.351 + float tx = act_fnt->glyphs[(int)*str].tc_pos.x; 3.352 + float ty = act_fnt->glyphs[(int)*str].tc_pos.y; 3.353 + float sx = act_fnt->glyphs[(int)*str].tc_sz.x; 3.354 + float sy = act_fnt->glyphs[(int)*str].tc_sz.y; 3.355 + 3.356 + Vector2 tc1 = Vector2(tx, ty); 3.357 + Vector2 tc2 = Vector2(tx + sx, ty + sy); 3.358 + 3.359 + Vector2 v1 = text_pos + act_fnt->glyphs[(int)*str].pos * act_fnt->scale * text_size; 3.360 + Vector2 v2 = v1 + act_fnt->glyphs[(int)*str].size * act_fnt->scale * text_size; 3.361 + float l = v1.x * 2.0f - 1.0f; 3.362 + float r = v2.x * 2.0f - 1.0f; 3.363 + float u = -v1.y * 2.0f + 1.0f; 3.364 + float d = -v2.y * 2.0f + 1.0f; 3.365 + 3.366 + glTexCoord2f(tc1.x, tc1.y); 3.367 + glVertex2f(l, u); 3.368 + glTexCoord2f(tc2.x, tc1.y); 3.369 + glVertex2f(r, u); 3.370 + glTexCoord2f(tc2.x, tc2.y); 3.371 + glVertex2f(r, d); 3.372 + glTexCoord2f(tc1.x, tc2.y); 3.373 + glVertex2f(l, d); 3.374 + 3.375 + text_pos.x += act_fnt->glyphs[(int)*str++].advance * act_fnt->scale * text_size; 3.376 + } 3.377 + 3.378 + if(standalone) PostDraw(); 3.379 + return text_pos.x - start_x; 3.380 +} 3.381 + 3.382 +void PrintStringLines(const char **str, int lines) 3.383 +{ 3.384 + PreDraw(); 3.385 + 3.386 + while(lines-- > 0) { 3.387 + PrintString(*str++, false); 3.388 + TextLineAdvance(); 3.389 + TextCRet(); 3.390 + } 3.391 + 3.392 + PostDraw(); 3.393 +} 3.394 + 3.395 +static void BlitFontGlyph(Font *fnt, int x, int y, FT_GlyphSlot glyph, unsigned int *img, int xsz, int ysz) 3.396 +{ 3.397 + if(glyph->bitmap.pixel_mode != FT_PIXEL_MODE_GRAY) { 3.398 + fprintf(stderr, "BlitFontGlyph: unsupported pixel mode: %d\n", glyph->bitmap.pixel_mode); 3.399 + return; 3.400 + } 3.401 + 3.402 + unsigned int *dest = img + y * xsz + x; 3.403 + unsigned char *src = glyph->bitmap.buffer; 3.404 + 3.405 + for(int j=0; j<glyph->bitmap.rows; j++) { 3.406 + for(int i=0; i<glyph->bitmap.width; i++) { 3.407 + dest[i] = 0x00ffffff | ((unsigned int)src[i] << 24); 3.408 + } 3.409 + dest += xsz; 3.410 + src += glyph->bitmap.pitch; 3.411 + } 3.412 +} 3.413 + 3.414 +static void CleanUp() 3.415 +{ 3.416 + FT_Done_FreeType(ft); 3.417 +} 3.418 + 3.419 +float GetMaxDescent() 3.420 +{ 3.421 + Font *fnt = act_fnt; 3.422 + 3.423 + float max_descent = 0.0f; 3.424 + 3.425 + for(int i=0; i<MAX_CHARS; i++) { 3.426 + float des = fnt->glyphs[i].pos.y + fnt->glyphs[i].size.y; 3.427 + if(isprint(i) && des > max_descent) { 3.428 + max_descent = des; 3.429 + } 3.430 + } 3.431 + 3.432 + return max_descent; 3.433 +} 3.434 + 3.435 +float GetLineAdvance() 3.436 +{ 3.437 + return act_fnt->line_adv; 3.438 +} 3.439 + 3.440 +float GetTextWidth(const char *str) 3.441 +{ 3.442 + float width = 0; 3.443 + while(*str) { 3.444 + width += act_fnt->glyphs[(int)*str++].advance * act_fnt->scale * text_size; 3.445 + } 3.446 + return width; 3.447 +}
4.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 4.2 +++ b/src/utktext.h Tue Oct 26 08:49:09 2010 +0300 4.3 @@ -0,0 +1,45 @@ 4.4 +#ifndef TEXT_H 4.5 +#define TEXT_H 4.6 + 4.7 +#if defined(WIN32) || defined(__WIN32__) 4.8 +#include <windows.h> 4.9 +#endif 4.10 + 4.11 +#include <vmath.h> 4.12 + 4.13 +class Color { 4.14 +public: 4.15 + float r, g, b, a; 4.16 + 4.17 + Color() {r = g = b = a = 1.0f;} 4.18 + Color(float r, float g, float b, float a = 1.0f) {this->r = r; this->g = g; this->b = b; this->a = a;} 4.19 +}; 4.20 + 4.21 + 4.22 +unsigned int CreateFont(const char *fname, int font_size); 4.23 +void DeleteFont(unsigned int fid); 4.24 +unsigned int GetFont(const char *fname, int sz); 4.25 +bool BindFont(unsigned int fid); 4.26 + 4.27 + 4.28 +void SetTextPos(const Vector2 &pos); 4.29 +Vector2 GetTextPos(); 4.30 + 4.31 +void TextLineAdvance(int adv = 1); 4.32 +void TextCRet(); 4.33 + 4.34 +void SetTextSize(float sz); 4.35 +float GetTextSize(); 4.36 + 4.37 +void SetTextColor(const Color &col); 4.38 +Color GetTextColor(); 4.39 + 4.40 +float PrintChar(char c); 4.41 +float PrintString(const char *text, bool standalone = true); 4.42 +void PrintStringLines(const char **str, int lines); 4.43 + 4.44 +float GetMaxDescent(); 4.45 +float GetLineAdvance(); 4.46 +float GetTextWidth(const char *str); 4.47 + 4.48 +#endif // TEXT_H