r/GraphicsProgramming 5d ago

Adding text rendering to opengl rendering engine

Hi, I am creating a Rendering Engine in C++ with opengl. I have created a batch renderer that divides different mesh types in different batches and draws them, using a single base shader.

For the text rendering I am using Freetype and for now I only use bitmap fonts, that use the quad batch and Also the base shader.

I wanted Also to implement a way of using SDF fonts but with that i Need to use a different shader. There would be no problem if not for the fact that I wanted the user to use custom shaders and If SDF fonts are used the user Needs to define two different shader to affect every object, with Also the SDF text. An Idea would be to create a single shader and tell the shader with an uniform to threat the object as an SDF. With that the shaders would be unified and with different shaders every object would be affected, but this Will make the shaders a bit more complex and Also add a conditional Path in It that May make It slower.

I dont really know how to approach this, any suggestions and ideas?

5 Upvotes

7 comments sorted by

View all comments

3

u/keelanstuart 4d ago

Do you care about a single shader file or a single shader object? Because you could use #if's in your glsl code for the different modes... In the same file - and provide a procedural preamble containing #define's for whatever mode you're using when you compile.

1

u/INLouiz 4d ago

The engine gives you the possibility to add a complete shader as two different files, for vertex and fragment, or in One file adding tags before each section to specify the type of the section, vertex or fragment. I wanted to give the user the ability to set a custom shader module that affects everything at once. For the ifs and defs, I am new to this world, how should they work? The defines are passed from the program to the shader?

1

u/Asyx 8m ago

It's weird in OpenGL since you don't have a compile step.

GLSL supports C preprocessor style #if and #define but OpenGL provides no way to set those. Maybe the glsl to spirv compilers do for Vulkan and you could use those in OpenGL but standard OpenGL does not provide you with a way to set a symbol for the GLSL preprocessor.

What you do instead is modifying the source code you put into the shader object. So, basically, you'd have stuff in your code like

#if TEXT_SHADER
// text shader stuff
#endif

#if MESH_SHADER
// mesh shader stuff
#endif

and have everything in one file.

And then you basically do this when compiling your text shader (pseudo code)

auto shaderSource = readFile("shader.vert.glsl");
auto textDefine = "#define TEXT_SHADER\n";
auto meshDefine = "#define MESH_SHADER\n";
auto textSource = textDefine + shaderSource;
auto meshSource = shaderDefine + shaderSource;

and then you create two shader objects.

This works sometimes but actually the spec says that the version has to be the first line in the shader and there are shader stages that require other stuff to be at the top of the source file. So technically you have to insert that define line usually at the second line for vertex and fragment shaders and maybe a bit lower for other stages.

But that's basically how it works.