Team Fortress 2 Source Code as on 22/4/2020
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

332 lines
8.4 KiB

  1. #pragma warning(disable:4244; disable:4305; disable:4018)
  2. #include <assert.h>
  3. #include <ctype.h>
  4. #define STB_WINMAIN
  5. #include "stb_wingraph.h"
  6. #define STB_TRUETYPE_IMPLEMENTATION
  7. #define STB_RECT_PACK_IMPLEMENTATION
  8. #include "stb_rect_pack.h"
  9. #include "stb_truetype.h"
  10. #ifndef WINGDIAPI
  11. #define CALLBACK __stdcall
  12. #define WINGDIAPI __declspec(dllimport)
  13. #define APIENTRY __stdcall
  14. #endif
  15. #include <gl/gl.h>
  16. #include <gl/glu.h>
  17. #define GL_FRAMEBUFFER_SRGB_EXT 0x8DB9
  18. #define SIZE_X 1024
  19. #define SIZE_Y 768
  20. stbtt_packedchar chardata[6][128];
  21. int sx=SIZE_X, sy=SIZE_Y;
  22. #define BITMAP_W 512
  23. #define BITMAP_H 512
  24. unsigned char temp_bitmap[BITMAP_W][BITMAP_H];
  25. unsigned char ttf_buffer[1 << 25];
  26. GLuint font_tex;
  27. float scale[2] = { 24.0f, 14.0f };
  28. int sf[6] = { 0,1,2, 0,1,2 };
  29. void load_fonts(void)
  30. {
  31. stbtt_pack_context pc;
  32. int i;
  33. FILE *f;
  34. char filename[256];
  35. char *win = getenv("windir");
  36. if (win == NULL) win = getenv("SystemRoot");
  37. f = fopen(stb_wingraph_commandline, "rb");
  38. if (!f) {
  39. if (win == NULL)
  40. sprintf(filename, "arial.ttf", win);
  41. else
  42. sprintf(filename, "%s/fonts/arial.ttf", win);
  43. f = fopen(filename, "rb");
  44. if (!f) exit(0);
  45. }
  46. fread(ttf_buffer, 1, 1<<25, f);
  47. stbtt_PackBegin(&pc, temp_bitmap[0], BITMAP_W, BITMAP_H, 0, 1, NULL);
  48. for (i=0; i < 2; ++i) {
  49. stbtt_PackSetOversampling(&pc, 1, 1);
  50. stbtt_PackFontRange(&pc, ttf_buffer, 0, scale[i], 32, 95, chardata[i*3+0]+32);
  51. stbtt_PackSetOversampling(&pc, 2, 2);
  52. stbtt_PackFontRange(&pc, ttf_buffer, 0, scale[i], 32, 95, chardata[i*3+1]+32);
  53. stbtt_PackSetOversampling(&pc, 3, 1);
  54. stbtt_PackFontRange(&pc, ttf_buffer, 0, scale[i], 32, 95, chardata[i*3+2]+32);
  55. }
  56. stbtt_PackEnd(&pc);
  57. glGenTextures(1, &font_tex);
  58. glBindTexture(GL_TEXTURE_2D, font_tex);
  59. glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, BITMAP_W, BITMAP_H, 0, GL_ALPHA, GL_UNSIGNED_BYTE, temp_bitmap);
  60. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
  61. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
  62. }
  63. int black_on_white;
  64. void draw_init(void)
  65. {
  66. glDisable(GL_CULL_FACE);
  67. glDisable(GL_TEXTURE_2D);
  68. glDisable(GL_LIGHTING);
  69. glDisable(GL_DEPTH_TEST);
  70. glViewport(0,0,sx,sy);
  71. if (black_on_white)
  72. glClearColor(255,255,255,0);
  73. else
  74. glClearColor(0,0,0,0);
  75. glClear(GL_COLOR_BUFFER_BIT);
  76. glMatrixMode(GL_PROJECTION);
  77. glLoadIdentity();
  78. gluOrtho2D(0,sx,sy,0);
  79. glMatrixMode(GL_MODELVIEW);
  80. glLoadIdentity();
  81. }
  82. void drawBoxTC(float x0, float y0, float x1, float y1, float s0, float t0, float s1, float t1)
  83. {
  84. glTexCoord2f(s0,t0); glVertex2f(x0,y0);
  85. glTexCoord2f(s1,t0); glVertex2f(x1,y0);
  86. glTexCoord2f(s1,t1); glVertex2f(x1,y1);
  87. glTexCoord2f(s0,t1); glVertex2f(x0,y1);
  88. }
  89. int integer_align;
  90. void print(float x, float y, int font, char *text)
  91. {
  92. glEnable(GL_TEXTURE_2D);
  93. glBindTexture(GL_TEXTURE_2D, font_tex);
  94. glBegin(GL_QUADS);
  95. while (*text) {
  96. stbtt_aligned_quad q;
  97. stbtt_GetPackedQuad(chardata[font], BITMAP_W, BITMAP_H, *text++, &x, &y, &q, font ? 0 : integer_align);
  98. drawBoxTC(q.x0,q.y0,q.x1,q.y1, q.s0,q.t0,q.s1,q.t1);
  99. }
  100. glEnd();
  101. }
  102. int font=3;
  103. int translating;
  104. int rotating=0;
  105. int srgb=0;
  106. float rotate_t, translate_t;
  107. int show_tex;
  108. void draw_world(void)
  109. {
  110. int sfont = sf[font];
  111. float x = 20;
  112. glEnable(GL_BLEND);
  113. glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
  114. if (black_on_white)
  115. glColor3f(0,0,0);
  116. else
  117. glColor3f(1,1,1);
  118. print(80, 30, sfont, "Controls:");
  119. print(100, 60, sfont, "S: toggle font size");
  120. print(100, 85, sfont, "O: toggle oversampling");
  121. print(100,110, sfont, "T: toggle translation");
  122. print(100,135, sfont, "R: toggle rotation");
  123. print(100,160, sfont, "P: toggle pixel-snap (only non-oversampled)");
  124. print(100,185, sfont, "G: toggle srgb gamma-correction");
  125. if (black_on_white)
  126. print(100,210, sfont, "B: toggle to white-on-black");
  127. else
  128. print(100,210, sfont, "B: toggle to black-on-white");
  129. print(100,235, sfont, "V: view font texture");
  130. print(80, 300, sfont, "Current font:");
  131. if (!show_tex) {
  132. if (font < 3)
  133. print(100, 350, sfont, "Font height: 24 pixels");
  134. else
  135. print(100, 350, sfont, "Font height: 14 pixels");
  136. }
  137. if (font%3==1)
  138. print(100, 325, sfont, "2x2 oversampled text at 1:1");
  139. else if (font%3 == 2)
  140. print(100, 325, sfont, "3x1 oversampled text at 1:1");
  141. else if (integer_align)
  142. print(100, 325, sfont, "1:1 text, one texel = one pixel, snapped to integer coordinates");
  143. else
  144. print(100, 325, sfont, "1:1 text, one texel = one pixel");
  145. if (show_tex) {
  146. glBegin(GL_QUADS);
  147. drawBoxTC(200,400, 200+BITMAP_W,300+BITMAP_H, 0,0,1,1);
  148. glEnd();
  149. } else {
  150. glMatrixMode(GL_MODELVIEW);
  151. glTranslatef(200,350,0);
  152. if (translating)
  153. x += fmod(translate_t*8,30);
  154. if (rotating) {
  155. glTranslatef(100,150,0);
  156. glRotatef(rotate_t*2,0,0,1);
  157. glTranslatef(-100,-150,0);
  158. }
  159. print(x,100, font, "This is a test");
  160. print(x,130, font, "Now is the time for all good men to come to the aid of their country.");
  161. print(x,160, font, "The quick brown fox jumps over the lazy dog.");
  162. print(x,190, font, "0123456789");
  163. }
  164. }
  165. void draw(void)
  166. {
  167. draw_init();
  168. draw_world();
  169. stbwingraph_SwapBuffers(NULL);
  170. }
  171. static int initialized=0;
  172. static float last_dt;
  173. int move[4];
  174. int raw_mouse_x, raw_mouse_y;
  175. int loopmode(float dt, int real, int in_client)
  176. {
  177. float actual_dt = dt;
  178. if (!initialized) return 0;
  179. rotate_t += dt;
  180. translate_t += dt;
  181. // music_sim();
  182. if (!real)
  183. return 0;
  184. if (dt > 0.25) dt = 0.25;
  185. if (dt < 0.01) dt = 0.01;
  186. draw();
  187. return 0;
  188. }
  189. int winproc(void *data, stbwingraph_event *e)
  190. {
  191. switch (e->type) {
  192. case STBWGE_create:
  193. break;
  194. case STBWGE_char:
  195. switch(e->key) {
  196. case 27:
  197. stbwingraph_ShowCursor(NULL,1);
  198. return STBWINGRAPH_winproc_exit;
  199. break;
  200. case 'o': case 'O':
  201. font = (font+1) % 3 + (font/3)*3;
  202. break;
  203. case 's': case 'S':
  204. font = (font+3) % 6;
  205. break;
  206. case 't': case 'T':
  207. translating = !translating;
  208. translate_t = 0;
  209. break;
  210. case 'r': case 'R':
  211. rotating = !rotating;
  212. rotate_t = 0;
  213. break;
  214. case 'p': case 'P':
  215. integer_align = !integer_align;
  216. break;
  217. case 'g': case 'G':
  218. srgb = !srgb;
  219. if (srgb)
  220. glEnable(GL_FRAMEBUFFER_SRGB_EXT);
  221. else
  222. glDisable(GL_FRAMEBUFFER_SRGB_EXT);
  223. break;
  224. case 'v': case 'V':
  225. show_tex = !show_tex;
  226. break;
  227. case 'b': case 'B':
  228. black_on_white = !black_on_white;
  229. break;
  230. }
  231. break;
  232. case STBWGE_mousemove:
  233. raw_mouse_x = e->mx;
  234. raw_mouse_y = e->my;
  235. break;
  236. #if 0
  237. case STBWGE_mousewheel: do_mouse(e,0,0); break;
  238. case STBWGE_leftdown: do_mouse(e, 1,0); break;
  239. case STBWGE_leftup: do_mouse(e,-1,0); break;
  240. case STBWGE_rightdown: do_mouse(e,0, 1); break;
  241. case STBWGE_rightup: do_mouse(e,0,-1); break;
  242. #endif
  243. case STBWGE_keydown:
  244. if (e->key == VK_RIGHT) move[0] = 1;
  245. if (e->key == VK_LEFT) move[1] = 1;
  246. if (e->key == VK_UP) move[2] = 1;
  247. if (e->key == VK_DOWN) move[3] = 1;
  248. break;
  249. case STBWGE_keyup:
  250. if (e->key == VK_RIGHT) move[0] = 0;
  251. if (e->key == VK_LEFT) move[1] = 0;
  252. if (e->key == VK_UP) move[2] = 0;
  253. if (e->key == VK_DOWN) move[3] = 0;
  254. break;
  255. case STBWGE_size:
  256. sx = e->width;
  257. sy = e->height;
  258. loopmode(0,1,0);
  259. break;
  260. case STBWGE_draw:
  261. if (initialized)
  262. loopmode(0,1,0);
  263. break;
  264. default:
  265. return STBWINGRAPH_unprocessed;
  266. }
  267. return 0;
  268. }
  269. void stbwingraph_main(void)
  270. {
  271. stbwingraph_Priority(2);
  272. stbwingraph_CreateWindow(1, winproc, NULL, "tt", SIZE_X,SIZE_Y, 0, 1, 0, 0);
  273. stbwingraph_ShowCursor(NULL, 0);
  274. load_fonts();
  275. initialized = 1;
  276. stbwingraph_MainLoop(loopmode, 0.016f); // 30 fps = 0.33
  277. }