From e0e89d0f2b0818a6f15324c5dd4722ca1eb74671 Mon Sep 17 00:00:00 2001 From: Alessandro Mauri Date: Thu, 26 Jan 2023 15:32:36 +0100 Subject: [PATCH] print text --- opengl-ren/charmap.ff | Bin 0 -> 65552 bytes opengl-ren/charmap.png | Bin 0 -> 1026 bytes opengl-ren/fragment.glsl | 6 +- opengl-ren/main.c | 139 ++++++++++++++++++++++++++++++++++----- opengl-ren/vertex.glsl | 3 + 5 files changed, 131 insertions(+), 17 deletions(-) create mode 100644 opengl-ren/charmap.ff create mode 100644 opengl-ren/charmap.png diff --git a/opengl-ren/charmap.ff b/opengl-ren/charmap.ff new file mode 100644 index 0000000000000000000000000000000000000000..711c202a8b3a16d443200dad60cddadc86412c12 GIT binary patch literal 65552 zcmeI2QH~u)5(9O#y~-}u{_>Ykus4_WfDOPV5MWhx_vno#1sFs!NoI9TcX|x@_kaKS zpWlD`{=(8Fg9zlzPD{j68#?CS2C zvzmi0arNBzR`s7%*Phe*@L)cF@>!?;>H4GQ=bWtVIngDWK6!k}TfM8doK^m=c`b*2 z!#sD>(@)=NO=ab*CJqLbtS;K>^j}AZntfHM+#qP5ruo{_mT-N9uNe=o0VtWq#Io&&xdKB~NXAXBFFXS&sR3 zdGgIi-|*CTn%Cx8-+0c^`sh9ySI>p6VLLzmt2)a`o;oq-(@&n-`o>@N;XlQ8uFORb zW}ljVL-gRT{;Cf@$b9OC=o3$UpR+D2o`iAC%zv?4r6|c@q|LWXb9dmYlpH08}oahtnxzX+R@flhk{HYKB;OhqZ z-y_XE%{|R~GT+JUf!PDU(jKtiAK>kMr{6IBO;104)btbSC!$N9+WPPf$pM?5K6=pj z)^9%iiOpwyilWX{t&vK3D ze67E$LvLvFj3>wX#^W=@2cn|};X&hD|Ev4BpN8$8@HbuSU(H#~XAbyozSZ-r>Ud5= z%h~10Hy?e&^tGBCbRayq%YPLg&)LxKFMUnd`s6j8_2CW4Pc%Jz>Zw~FT_V1Q>B|~_ z^1HR=z$dnR^i7xj=CgkCt!8fO;6dxd8{$typFFko;SKQ{p8CkcPi@$Atxs;#S>Jea z4e$1m2j*Pk(Y5}r4!xnx+vUkOAAQ5-vwq`SfA>6=XF2fcYqj~{!OVegxazx0_jJx` ze%{MdKFc+pbG826I-6&Fo8Nr+6PwTa#*=S-scj`I29)SLcw2o;uO`@C`GM+I;jA(I-!BefWmtfas|ct#3U3)jm29e`4#WK5P6S z{j3|``s5knZ-~F?=%Y`hKlr+V`TrK?J(%}kzJu8Vvj=7m{CyAbdxO0f);FFU>l^>H zkGY1-H%y=DuJTvs;J@##5F=kMOfQ|Eaqw>@8*YklLHx7%-e%U$*12X}o>>p2&=I}hKxBhQs+ z=T2SL=7Uc?HGM;LhP%F9ea=1gn-88j)QQ$N9)Iia>d=F$`RKu4-N$o&Hng9M@jRdP zjej>^I}iQD)91S@C+D}i%}symvwm8Cb>3C~?(^lmcddCY!#p>-OAwqujZ`k$bENg&trY#d0y)q|Fe9| zHEicKpYf-8tG=eQzVSRq>!0e#H6+(CeWtt0|ExJVm-_1Sq@P^FtNK-c>aw=;!Ka>@ zz9G6q^vSmxUt;r3|8)cN{{zf>Fz>;92eSue4}8r%!0!!LfBsMBoaUeUuHMJ^@BN*VPtqBFdz$4@?WqV-5o2eznG**!<|5j(*cy-}sh$>LV9yIp{$2hUg6O zo%ZpyoK>CW7~gW64}W6wS>Jf_t#ABQAO2mm^BBLIpZb<-{av29=Cl4){Z&8bTE#Yx zoTjrrd_(3WnlE+K=&2J|`{=;Tp+4=O`f@HgApOMFPyK3bxyH9#e1^?WKmG8Asn6Pc z@aU-hA&HU&GaVBIjN7tLGTq>jq{Y%zH5J!F&g^2WAh<9+*8adtmm!?19+>vj=7m%pRCM zFneJ3!0dt91G5Ka56m8zJurJ<_Q33c*#ol&W)I9Bm_0CiVD`Z5f!PDI2WAh<9+*8a Sdtmm!?19+>vj^U75BvoRPsJDj literal 0 HcmV?d00001 diff --git a/opengl-ren/charmap.png b/opengl-ren/charmap.png new file mode 100644 index 0000000000000000000000000000000000000000..017a3e70a229c89093f7f1bb5f6452937e05077f GIT binary patch literal 1026 zcmV+d1pWJoP)RCwC$T-j~|Aq)%=|NqPBL!}kP2jc^>O*{`(gkTqp zuQ6;NkHVetdcD||shw?PyU{*Z`*OJQ*c-|XT+ws)<|#tIezewFYxrZQ&aE{?A&%`9 zUC}f#&#RF!ufNc3f<9L7iO+|%Hr%QbUBxJbr9cua;8!2VzoS;NA{bTpwVEO)Kh>im{DZ347!@?%7KAXCfjg@pF7v*X1&K8%nr+9*hz( zRw%i9tcZBpgK=GS6jEUD_)nbUASSPSFfeP5xDkb#NrVyP781|G8%K0S_umrz65W@i z*Wd&3#>f(yH91lI512EsPm5$hn{-8T$dZq`ew(wPLgBlK7;7@DUovqn-8S`SO2e1V zP#GR1P0OB+6`{PtQT+2&1RaS4Tjf8-q)g>;_IL7;WO{f(0xZj<{!7KNr_@7skVeV@ zO&gE%TgQr6!st`Jo_A;H?E{ho(Pi1#B z=6c;tC%yQ&Q@2(E6lHf*5e_HajvdV+{0o;T-7Q3lT<(gSsepCcT*I*|j0La?NQshr z!Qgo(5}fs=f`rjg;bDhQjUW##B339Q`s>39%pD?gBA)IXpd4A|1}OL0C6ev<{EGb! zK(APsdeRTFd_7Oz4fSv?sq6z1t7#ARRifM}V-^uZXj)IPqxk8S)n6}fk #define _POSIX_C_SOURCE 200809l #include +#include #include #include @@ -21,16 +23,19 @@ const int vertindex = 0; const int colindex = 1; +const int textindex = 2; struct { SDL_Window *w; SDL_GLContext *gl; GLuint gl_vertbuffer; GLuint gl_program; + GLuint font_texture; } ren = {0}; typedef struct PACKED { - GLfloat x, y; + union { GLfloat x, u; }; + union { GLfloat y, v; }; } vec2; typedef struct PACKED { @@ -42,8 +47,9 @@ typedef struct PACKED { // a vertex has a position and a color struct PACKED vertex { - vec2 pos; - vec4 col; + vec2 pos; + vec2 texture; + vec4 color; }; @@ -62,6 +68,17 @@ int w_width(SDL_Window *); //}; +// this just descrives a farbfeld image +// https://tools.suckless.org/farbfeld/ +struct PACKED _ff { + uint8_t magic[8]; + uint32_t w, h; + uint64_t bytes[]; +}; +const int gw = 7, gh = 9; +unsigned int fw, fh; + + struct { struct vertex *v; int size, idx; @@ -78,7 +95,7 @@ void grow_stack(int step) } -int vstack_push_quad(int x, int y, int w, int h, vec4 color) +int vstack_push_quad_c(int x, int y, int w, int h, vec4 color) { if (vstack.idx <= vstack.size) grow_stack(6); @@ -106,18 +123,64 @@ int vstack_push_quad(int x, int y, int w, int h, vec4 color) y4 = y3 = (float)(hh - y) / hh; y1 = y2 = (float)(hh - y-h) / hh; - printf("x1=%.3f x2=%.3f, y1=%.3f y4=%.3f\n", x1, x2, y1, y4); + vstack.v[vstack.idx++] = (struct vertex){ .pos.x=x1, .pos.y=y1, .color=color }; + vstack.v[vstack.idx++] = (struct vertex){ .pos.x=x2, .pos.y=y2, .color=color }; + vstack.v[vstack.idx++] = (struct vertex){ .pos.x=x3, .pos.y=y3, .color=color }; + vstack.v[vstack.idx++] = (struct vertex){ .pos.x=x1, .pos.y=y1, .color=color }; + vstack.v[vstack.idx++] = (struct vertex){ .pos.x=x3, .pos.y=y3, .color=color }; + vstack.v[vstack.idx++] = (struct vertex){ .pos.x=x4, .pos.y=y4, .color=color }; + + return 0; +} - vstack.v[vstack.idx++] = (struct vertex){ .pos.x=x1, .pos.y=y1, .col=color }; - vstack.v[vstack.idx++] = (struct vertex){ .pos.x=x2, .pos.y=y2, .col=color }; - vstack.v[vstack.idx++] = (struct vertex){ .pos.x=x3, .pos.y=y3, .col=color }; - vstack.v[vstack.idx++] = (struct vertex){ .pos.x=x1, .pos.y=y1, .col=color }; - vstack.v[vstack.idx++] = (struct vertex){ .pos.x=x3, .pos.y=y3, .col=color }; - vstack.v[vstack.idx++] = (struct vertex){ .pos.x=x4, .pos.y=y4, .col=color }; + +int vstack_push_quad_t(int x, int y, int w, int h, int u, int v) +{ + if (vstack.idx <= vstack.size) + grow_stack(6); + + // x4,y4 x3,y3 + // +-------------+ + // |(x,y) /| + // | / | + // | 2 / | + // | / | + // | / | + // | / 1 | + // |/ | + // +-------------+ + // x1,y1 x2,y2 + + int hw = w_width(ren.w)/2; + int hh = w_width(ren.w)/2; + + float x1, x2, x3, x4; + float y1, y2, y3, y4; + + x1 = x4 = (float)(x - hw) / hw; + x2 = x3 = (float)(x+w - hw) / hw; + y1 = y2 = (float)(hh - y-h) / hh; + y3 = y4 = (float)(hh - y) / hh; + + float u1, u2, u3, u4; + float v1, v2, v3, v4; + + u1 = u4 = (float)(u) / fw; + u2 = u3 = (float)(u+gw) / fw; + v1 = v2 = (float)(v+gh) / fh; + v3 = v4 = (float)(v) / fh; + + vstack.v[vstack.idx++] = (struct vertex){ .pos.x=x1, .pos.y=y1, .texture.x=u1, .texture.y=v1 }; + vstack.v[vstack.idx++] = (struct vertex){ .pos.x=x2, .pos.y=y2, .texture.x=u2, .texture.y=v2 }; + vstack.v[vstack.idx++] = (struct vertex){ .pos.x=x3, .pos.y=y3, .texture.x=u3, .texture.y=v3 }; + vstack.v[vstack.idx++] = (struct vertex){ .pos.x=x1, .pos.y=y1, .texture.x=u1, .texture.y=v1 }; + vstack.v[vstack.idx++] = (struct vertex){ .pos.x=x3, .pos.y=y3, .texture.x=u3, .texture.y=v3 }; + vstack.v[vstack.idx++] = (struct vertex){ .pos.x=x4, .pos.y=y4, .texture.x=u4, .texture.y=v4 }; return 0; } + void vstack_clear(void) { vstack.idx = 0; @@ -149,7 +212,10 @@ void ren_initvertbuffer() // always referred to by index and not by pointer or other manners, indices // go from 0 to 15 glEnableVertexAttribArray(colindex); - glVertexAttribPointer(colindex, 4, GL_FLOAT, GL_FALSE, sizeof(struct vertex), (void*)sizeof(vec2)); + glVertexAttribPointer(colindex, 4, GL_FLOAT, GL_FALSE, sizeof(struct vertex), (void*)(2*sizeof(vec2))); + // texture uv data + glEnableVertexAttribArray(textindex); + glVertexAttribPointer(textindex, 2, GL_FLOAT, GL_FALSE, sizeof(struct vertex), (void*)sizeof(vec2)); // reset the object bind so not to create errors glBindBuffer(GL_ARRAY_BUFFER, 0); } @@ -298,6 +364,46 @@ int w_width(SDL_Window *win) } +void import_font(const char *path) +{ + const char *map; + int size; + const struct _ff *img; + + map_file(&map, &size, path); + img = (const struct _ff *)map; + fw = ntohl(img->w); + fh = ntohl(img->h); + + glGenTextures(1, &ren.font_texture); + glBindTexture(GL_TEXTURE_2D, ren.font_texture); + // farbfeld image + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, fw, fh, 0, GL_RGBA, GL_UNSIGNED_SHORT, img->bytes); + + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + + munmap((void *)map, size); +} + + +void push_text(int x, int y, const char *s) +{ + for (; *s; s++) { + int u, v; + int idx = *s - ' '; + u = idx % (fw / gw); + v = (idx / (fw / gw)) % (fh / gh); + vstack_push_quad_t(x, y, gw*2, gh*2, u*gw, v*gh); + x += gw*2; + if (*s == '\n') + y += gh; + } +} + + int main (void) { SDL_Init(SDL_INIT_VIDEO | SDL_INIT_EVENTS); @@ -328,11 +434,14 @@ int main (void) err(-1, "Failed to initialize GLEW: %s", glewGetErrorString(glew_err)); ren_initshaders(); + import_font("./charmap.ff"); vec4 magenta = {.r=1.0, .g=0.0, .b=1.0, .a=1.0}; - vstack_push_quad(0, 0, 100, 100, magenta); - vstack_push_quad(200, 0, 10, 10, magenta); - vstack_push_quad(10, 150, 100, 100, magenta); + vstack_push_quad_c(0, 0, 100, 100, magenta); + vstack_push_quad_c(200, 0, 10, 10, magenta); + vstack_push_quad_c(10, 150, 100, 100, magenta); + + push_text(250, 250, "ò Ciao Victoria <3"); ren_initvertbuffer(); // event loop and drawing diff --git a/opengl-ren/vertex.glsl b/opengl-ren/vertex.glsl index 48f0530..9c4d840 100644 --- a/opengl-ren/vertex.glsl +++ b/opengl-ren/vertex.glsl @@ -3,12 +3,15 @@ // use the input ("in") vertices from index zero layout(location = 0) in vec2 position; layout(location = 1) in vec4 color; +layout(location = 2) in vec2 uv; flat out vec4 out_color; +out vec2 texture_coord; void main() { // simply copy teh output position gl_Position = vec4(position.x, position.y, 0.0f, 1.0f); out_color = color; + texture_coord = uv; } \ No newline at end of file