ColleagueRiley / RFont

Simple-to-use single header modular font rendering library written in C.
zlib License
27 stars 2 forks source link

Render Background gets overwritten? #1

Closed noxomix closed 10 months ago

noxomix commented 12 months ago

Hello, Im using RFont with GLFW and Glad (openGL 3.3) when I render my Font the Background gets set to black, and everything I render afterwards (like draw cycles, rectangles and so on) is not beeing displayed. If I place the draw text before my other render stuff, only the text with black background is displayed in the window ... and if i do my rendering first and then the text... its again just displayed the text on black background.

Is there a thing needs to done before? For example hook in the GLFW Context or the Glad RFont context pointer into Glad (like this GLFW load user pointer)?

Edit: Im doing Bindings right now, and not expericing it in a C example... so it should be a binding error i will look into that

ColleagueRiley commented 12 months ago

Oh, you've closed the issue. Were you able to solve the problem? Was it a problem with the bindings or something with my code? I'd like to know in case I need to fix anything.

noxomix commented 11 months ago

Sorry, the Problem was in my code i didnt figured out where but it must be an issue with my code. So thank you anyways.

ColleagueRiley commented 11 months ago

@noxomix Ok, thank you. I can still look into the problem if you want me to.

noxomix commented 10 months ago

Ok thank you. I now figured out the Problem a bit.. so after i draw some RFont and i want to draw a simple rectangle with glRectf or whatever nothing gets displayed anymore. Since Ive mentioned earlier Im not a C developer and also Im very unexperienced in OpenGL, which is not a good preset for fixing those issues ;)

My guess is that some openGL commands are set in RFont but not reset to the default after the text is drawn? Thats the only I could imagine right now. But I still believe its an issue with my own code tho.

And the second issue is the Quality of the rendering, it doesn't came to the Quality of the Screenshot in the Readme.MD but I wasn't even able to get the example run, so my only reference is my Bindings I have created for the RFont header file and using it with GLFW and my also own made openGL Bindings for the V Programming Language - as you can imagine: Many potential sources of error/causing the both described issues which potentially not a problem with RFont - and just caused by my own code/bindings whatever.

But maybe you can tell me if this Low Quality rendering is happening and what I can do to avoid it? (If you experienced it before maybe I just need to set a shade_smooth flag or something, currently I didnt do anything then glOrtho.. no glEnable shade smooth or such things) I will attach a screenshot.
Screenshot from 2023-12-19 12-09-41

ColleagueRiley commented 10 months ago

Just going by the screenshot alone. I believe the issue is that it is using an older version of OpenGL.

This could be the result of your system not properly supporting OpenGL or you're not loading a newer version OpenGL with GLfW.

My test uses RGFW for OpenGL 2 and 3. RGFW by default creates an OpenGL 3 context with backwards compatibility. This makes it so the text doesn't look really awful.

This might not be the actual problem. But judging by how the text is rendered it is a possible problem.

ColleagueRiley commented 10 months ago

image

This is the part that enforces the 3.3 context. GLFW has a similar function. Actually it's two functions

glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);

glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);

However, I do not know if GLFW supports OpenGL backwards compatibility.

Also, I'm not fully sure if this is the real issue. I'll look into it later.

noxomix commented 10 months ago

Thank you, Im using GLAD to bind the OpenGL and GLFW only for the Windowing, tried it with 4.6 and 3.3 aswell as gl 2.0 but everywhere the same. I think i need to gain more experience to understand it, I think I first should be able to make the example main.c work before try to create wrapper/bindings whatever to it.

Always getting those errors when compiling:

Must remake target 'gl'.
gcc main.c -I./include -lX11 -lGLX -lm -lGL -I./ext -I../ -D RFONT_RENDER_LEGACY -Wall -o gl
Putting child 0x55c2ca4c26c0 (gl) PID 91756 on the chain.
Live child 0x55c2ca4c26c0 (gl) PID 91756 
/usr/bin/ld: /tmp/ccUaaLek.o: undefined reference to symbol 'dlclose@@GLIBC_2.2.5'
/usr/bin/ld: /lib/x86_64-linux-gnu/libdl.so.2: error adding symbols: DSO missing from command line
collect2: error: ld returned 1 exit status
Reaping losing child 0x55c2ca4c26c0 PID 91756 
make[1]: *** [Makefile:26: gl] Error 1
Removing child 0x55c2ca4c26c0 PID 91756 from chain.
make[1]: Leaving directory '/home/theo/Desktop/Code/Software/rfont/RFont/example'
Reaping losing child 0x559bca466660 PID 91753 
make: *** [Makefile:21: all] Error 2
Removing child 0x559bca466660 PID 91753 from chain.
ColleagueRiley commented 10 months ago

Adding -ldl to the command should "fix" this.

But RFont shouldn't need to link with dl if I'm remembering correctly. I'll look into the issue later. But adding -ldl should work for now.

ColleagueRiley commented 10 months ago

Are you using the newest version of RFont? I'm not sure if the linking error is related to a problem that used to exist maybe.

Could you give me information about your system, such as your OS, so I can better test.

ColleagueRiley commented 10 months ago

image

This is an updated screen shot of the text being rendered using legacy OpenGL and RGFW_setGLVersion(2, 0); to ensure it's actually using the legacy protocols.

noxomix commented 10 months ago

Hello. Im busy right now i will answer you next Week. Yes im using newest Version and tried with OpenGL 2.0, 3.3, 4.6. Thank you ver much

noxomix commented 10 months ago

Hey, so I now created my own example in C, and everything works just fine, so text in high quality and everything. I suppose this issue is with my bindings then . So RFont ist working ;)

Its working with GLAD OpenGL 4.1, GLFW3 without RLGL/RGFW.

Thank you.

noxomix commented 10 months ago

Ou and how can I determine the height/width of text in RFont? Does font-size 16 means 16px height? or 16px width of each char?

ColleagueRiley commented 10 months ago

Font size 16 means a height of 16. The font width is returned by the draw function or by RFont_text_width()

ColleagueRiley commented 10 months ago

Actually

The font width is returned by the draw function

this is not true yet but it will be in the next push.

In the next push I hope to remove the GLAD.h backend as well.

noxomix commented 10 months ago

Yea I figured out ;)

image

I made a Terminal Emulator / not really - i just using libvterm, but it basically can render nano now

noxomix commented 10 months ago

Just dialogs (linux dialog command) isnt working yet, since I suppose RFont only supports like 255 different chararcters (since the text-argument of RFont_draw_text() is of type char) but a terminal might be need way more different characters and special characters i think? or am I missing something important/makes it possible to render more advanced characrers/symbols then the currently supported ones? Reason number 3 could be my font isnt supporting the special chars ;)

image

ColleagueRiley commented 10 months ago

The problem is with your font. If you look at the screen shot my library does support utf-8. I would really like to create a system so that way if the font doesn't support the character you can have it default to another font for that character.

But anyway, it's really awesome to see you creating something cool with my library, it makes me so happy. I've wanted to create a terminal emulator myself but I don't really know how.

Is your project going to be on GitHub in the future? I'd love to put a link to it on my README.

noxomix commented 10 months ago

Oh okay interesting but how can I put in those characters into RFont? I mean there like over a million UTF-8 chars, libvterm gives me a uint32_t so basically a unsigned int, currently Im casting this into a char, then into a *char[1] and finally give it to RFont 🤔.

Actually Im really new to C, okay Im programming in PHP and so on since years, but I still not even able to create a cmakelist or a makefile. Thats why Im wondering how i managed to do the emulator today... Actually I found a Project on github which uses Libvterm with SDL2 ... and now I partially translated this into GLFW, but actally i didnt even have a cursor so what it currently does is at starup run a execvp('/bin/nano', args) and then it displays it with rfont and to draw the backgrounds i draw glRectf() ... it isnt possible to input anything and so on... so its at a really early stage :D

Its so hard because libvterm is not documented... except this senior-developer-comments in the header file...

But Im so happy that i made it until this now, off course I will put it on github later or tomorrow and let you know :)

ColleagueRiley commented 10 months ago

I'll look into that sort of behavior later.

In the example code you can literally just put the UTF-8 character into a string and then it converts it.

I'm thinking the issue is that the font doesn't support that UTF-8 character and I'm not sure how it go about getting that working for this specific project.

I can look into it later and it will be easier when I can checkout your project.

As for cmake and make. Make is pretty much just Unix shell and cmake is, in my opinion, worthless and just an extra thing you have to mess around with.

EimaMei commented 10 months ago

Oh okay interesting but how can I put in those characters into RFont? I mean there like over a million UTF-8 chars, libvterm gives me a uint32_t so basically a unsigned int, currently Im casting this into a char, then into a *char[1] and finally give it to RFont 🤔.

Actually Im really new to C, okay Im programming in PHP and so on since years, but I still not even able to create a cmakelist or a makefile. Thats why Im wondering how i managed to do the emulator today... Actually I found a Project on github which uses Libvterm with SDL2 ... and now I partially translated this into GLFW, but actally i didnt even have a cursor so what it currently does is at starup run a execvp('/bin/nano', args) and then it displays it with rfont and to draw the backgrounds i draw glRectf() ... it isnt possible to input anything and so on... so its at a really early stage :D

Its so hard because libvterm is not documented... except this senior-developer-comments in the header file...

But Im so happy that i made it until this now, off course I will put it on github later or tomorrow and let you know :)

I assume that libvterm is giving you a UTF-32 character, otherwise it wouldn't make sense for it to be uint32_t. RFont only takes UTF-8 as input, so directly casting the UTF-32 character as a char or inputting it as a string won't work. As an example, letter 'Č' in UTF-8 is 0xC4 0x8C, while in UTF-32 it's 0x0000010C (source).

So in short, you need to encode that UTF-32 character into UTF-8 to draw that specifically character. Funnily enough recently I implemented my own fast UTF-32 -> UTF-8 encoder for my STL library. If you're interested in the library, you can check it out here. The function that does the encoding is this:

/* Definitions. */
typedef struct {
    /* The codepoint (UTF-8 encoded). */
    char codepoint[4];
    /* Length of 'codepoint' in bytes. */
    u32 len;
} siUtf8Char;

/* Encodes the specified UTF-32 character into UTF-8 and returns a 'siUtf8Char'
 * structure. This function does not check if the UTF-32 is invalid. */
siUtf8Char si_utf8Encode(i32 codepoint);

...
/* Implementation. */

siUtf8Char si_utf8Encode(i32 codepoint) {
    siUtf8Char result;

    u32 len = (codepoint >= 0x80) + (codepoint >= 0x800) + (codepoint >= 0x10000);
    result.codepoint[0] = ((len != 0) * ((0xFF80 >> len) & 0xFF)) | (codepoint >> (6 * len));
    result.len = len + 1;

    usize i;
    for (i = 1; i < result.len; i += 1) {
        result.codepoint[i] = 0x80 | ((codepoint >> (6 * (len - i))) & 0x3F);
    }

    return result;
}
noxomix commented 10 months ago

Oh okay interesting but how can I put in those characters into RFont? I mean there like over a million UTF-8 chars, libvterm gives me a uint32_t so basically a unsigned int, currently Im casting this into a char, then into a *char[1] and finally give it to RFont 🤔. Actually Im really new to C, okay Im programming in PHP and so on since years, but I still not even able to create a cmakelist or a makefile. Thats why Im wondering how i managed to do the emulator today... Actually I found a Project on github which uses Libvterm with SDL2 ... and now I partially translated this into GLFW, but actally i didnt even have a cursor so what it currently does is at starup run a execvp('/bin/nano', args) and then it displays it with rfont and to draw the backgrounds i draw glRectf() ... it isnt possible to input anything and so on... so its at a really early stage :D Its so hard because libvterm is not documented... except this senior-developer-comments in the header file... But Im so happy that i made it until this now, off course I will put it on github later or tomorrow and let you know :)

I assume that libvterm is giving you a UTF-32 character, otherwise it wouldn't make sense for it to be uint32_t. RFont only takes UTF-8 as input, so directly casting the UTF-32 character as a char or inputting it as a string won't work. As an example, letter 'Č' in UTF-8 is 0xC4 0x8C, while in UTF-32 it's 0x0000010C (source).

So in short, you need to encode that UTF-32 character into UTF-8 to draw that specifically character. Funnily enough recently I implemented my own fast UTF-32 -> UTF-8 encoder for my STL library. If you're interested in the library, you can check it out here. The function that does the encoding is this:

/* Definitions. */
typedef struct {
  /* The codepoint (UTF-8 encoded). */
  char codepoint[4];
  /* Length of 'codepoint' in bytes. */
  u32 len;
} siUtf8Char;

/* Encodes the specified UTF-32 character into UTF-8 and returns a 'siUtf8Char'
 * structure. This function does not check if the UTF-32 is invalid. */
siUtf8Char si_utf8Encode(i32 codepoint);

...
/* Implementation. */

siUtf8Char si_utf8Encode(i32 codepoint) {
  siUtf8Char result;

  u32 len = (codepoint >= 0x80) + (codepoint >= 0x800) + (codepoint >= 0x10000);
  result.codepoint[0] = ((len != 0) * ((0xFF80 >> len) & 0xFF)) | (codepoint >> (6 * len));
  result.len = len + 1;

  usize i;
  for (i = 1; i < result.len; i += 1) {
      result.codepoint[i] = 0x80 | ((codepoint >> (6 * (len - i))) & 0x3F);
  }

  return result;
}

Thank you, actually Vterm supports a function where you can set the charset as utf-8 so it is capable to return up-to utf-32 then but it can automaticly store it like utf-8 , thats why my char casting is working. But interesting to know - that makes sense.

noxomix commented 10 months ago

I'll look into that sort of behavior later.

In the example code you can literally just put the UTF-8 character into a string and then it converts it.

I'm thinking the issue is that the font doesn't support that UTF-8 character and I'm not sure how it go about getting that working for this specific project.

I can look into it later and it will be easier when I can checkout your project.

As for cmake and make. Make is pretty much just Unix shell and cmake is, in my opinion, worthless and just an extra thing you have to mess around with.

Yea with the new knowledge I will try to implement that now if my motivation stills there today ^^

ColleagueRiley commented 10 months ago

@EimaMei I figured that when it casts the UTF-8 character into a char* it will look the same as it does when you put a UTF-8 character in a string.

Is that not how it would work?

noxomix commented 10 months ago

Okay It works now, somehow I was wrong and the uint32_t represents a UTF-32 character, but the (char)my_uint32_123-casting was successfull.

image

noxomix commented 10 months ago

https://github.com/noxomix/vterm_test

No makefile so to compile run: gcc main.c -lglfw -lm -lutil -lvterm -o b.out && ./b.out

you need on linux apt install libvterm-dev and libglfw3-dev i think thats it

ColleagueRiley commented 10 months ago

@noxomix are you using macOS? I'm using manjaro linux so I had to use pacman.

Also do you have discord or something so we can close this issue and talk there instead?

noxomix commented 10 months ago

Im using ZorinOS which is Ubuntu Based I guess

ColleagueRiley commented 10 months ago

I edited another question into the last message if you didn't see it.

Also make sure you're using.

  RFont_font_free(&app.font);
  RFont_close();

At the end of your program to ensure all the memory allocated and stuff is properly freed.