ravi.joshi53's picture

Unable to Flip the QuickFont

Hi,
I have an orthogonal view (which is flipped 180 degree) containing some text written using QuickFont
I wanted to flip the text so I thought of setting QFontBuilderConfiguration.TransformToCurrentOrthogProjection and TransformViewport for QFontRenderOptions but its not working. Below is the snippet of my code-

        const float LeftX = 0.0f;
        const float RightX = 16.0f;
        const float BottomY = 12.0f;
        const float TopY = 0.0f;
        const float FarZ = 1.0f;
        const float NearZ = -1.0f;
 
        protected override void OnLoad(EventArgs e)
        {
            base.OnLoad(e);
            QFontBuilderConfiguration fontBuilderConfiguration = new QFontBuilderConfiguration();
            fontBuilderConfiguration.TransformToCurrentOrthogProjection = true; // Adding this throwing error
            font = new QFont("Fonts/HappySans.ttf", 30, fontBuilderConfiguration);
            QFontRenderOptions fontRenderOptions = new QFontRenderOptions();
            fontRenderOptions.TransformToViewport = new TransformViewport(0, 0, RightX, BottomY);
            font.PushOptions(fontRenderOptions);
            GL.ClearColor(Color.AliceBlue);
            GL.Disable(EnableCap.DepthTest);
        }
 
        protected override void OnResize(EventArgs e)
        {
            base.OnResize(e);
            GL.Viewport(0, 0, Width, Height);
            GL.MatrixMode(MatrixMode.Projection);
            GL.LoadIdentity();
            GL.Ortho(RightX, LeftX, TopY, BottomY, FarZ, NearZ);
        }

And what I want is this -
flipped (Both Horizontally and Vertically) Text

I tried to remove fontBuilderConfiguration.TransformToCurrentOrthogProjection but it doesn't work.


Comments

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.
ravi.joshi53's picture

What I am missing here? I hope that fontRenderOptions.TransformToViewport = new TransformViewport(0, 0, RightX, BottomY); is modifying the default viewport to the desired viewport. but why fontBuilderConfiguration.TransformToCurrentOrthogProjection = true; is throwing error and how can I flip the text?

winterhell's picture

You could try to reverse TransformViewport(RightX, BottomY,0,0);
In case that flips the font, you may or may not need to write a 2-line function that reverses the position of the text you want to render.

ravi.joshi53's picture

Hi winterhell,

I tried TransformViewport(RightX, BottomY,0,0); also but it doesn't work. Following is my complete code-

class Program : GameWindow
{
    const float LeftX = 0.0f;
    const float RightX = 16.0f;
    const float BottomY = 12.0f;
    const float TopY = 0.0f;
    const float FarZ = 1.0f;
    const float NearZ = -1.0f;
    QFont font;
    public Program()
        : base(800, 600, GraphicsMode.Default, "QuickFont Test")
    {
        this.WindowBorder = WindowBorder.Fixed;
    }
    protected override void OnLoad(EventArgs e)
    {
        base.OnLoad(e);
        QFontBuilderConfiguration fontBuilderConfiguration = new QFontBuilderConfiguration();
        //fontBuilderConfiguration.TransformToCurrentOrthogProjection = true; //Commenting this, creating errors
        font = new QFont("Fonts/HappySans.ttf", 30, fontBuilderConfiguration);
        QFontRenderOptions fontRenderOptions = new QFontRenderOptions();
        fontRenderOptions.TransformToViewport = new TransformViewport(RightX, BottomY, 0, 0);
        font.PushOptions(fontRenderOptions);
        GL.ClearColor(Color.AliceBlue);
        GL.Disable(EnableCap.DepthTest);
    }
    protected override void OnResize(EventArgs e)
    {
        base.OnResize(e);
        GL.Viewport(0, 0, Width, Height);
        GL.MatrixMode(MatrixMode.Projection);
        GL.LoadIdentity();
        GL.Ortho(RightX, LeftX, TopY, BottomY, FarZ, NearZ);
    }
    protected override void OnRenderFrame(FrameEventArgs e)
    {
        base.OnRenderFrame(e);
        GL.Clear(ClearBufferMask.ColorBufferBit);
        GL.MatrixMode(MatrixMode.Modelview);
        GL.LoadIdentity();
 
        GL.Begin(PrimitiveType.Triangles);
        GL.PushMatrix();
        GL.Color4(Color4.YellowGreen);
        GL.Vertex2(LeftX, TopY);
        GL.Vertex2(RightX, TopY);
        GL.Vertex2((LeftX + RightX) / 2, BottomY);
        GL.PopMatrix();
        GL.End();
 
        QFont.Begin();
        GL.PushMatrix();
        font.Print("QuickFont Test", QFontAlignment.Centre, new Vector2(RightX / 2, BottomY / 2));
        GL.PopMatrix();
        QFont.End();
 
        GL.Disable(EnableCap.Texture2D);
        SwapBuffers();
    }
}

Notice that, Since I have GL.Ortho(RightX, LeftX, TopY, BottomY, FarZ, NearZ);, the rendered triangle is flipped (Which is perfect). But I want the flipped text also(As shown in the screenshot above)

winterhell's picture

I'm not familiar with QuickFont, but if you can render everything backwards, you might be able to do a render to texture/framebuffer. That way you'll have a texture containing your flipped screen. what would be left is to render that image backwards to the backbuffer. This technique has been used in most 3D games in the past 10 years.
For more information you might want to read FBO
It might be a bit of an overkill for this situation, but if you don't have an alternative solution it might help.

ravi.joshi53's picture

Till now, I am not able to render it backwards. The code which I have added above is ONLY rendering the text in forward direction and the flip is not happening. I suspect that something is missing in the code.

Also, using fontRenderOptions.TransformToViewport = new TransformViewport(0, 0, RightX, BottomY); QuickFont is working with my defined orthogonal view, which is GL.Ortho(RightX, LeftX, TopY, BottomY, FarZ, NearZ);

As per my understanding, since QuickFont is following my orthogonal view which is already flipped, this way QuickFont should be flipped.

ppc's picture

Replace this

    const float RightX = 16.0f;
    const float BottomY = 12.0f;

with this

    const float RightX = 800.0f;
    const float BottomY = 600.0f;

Delete the following lines

QFontRenderOptions fontRenderOptions = new QFontRenderOptions();
fontRenderOptions.TransformToViewport = new TransformViewport(0, 0, RightX, BottomY);
font.PushOptions(fontRenderOptions);
QFont.Begin();
QFont.End();
ravi.joshi53's picture

Hi ppc,

Great thanks to you. Now it is rendering the text in flipped manner. Can you please explain the concept here? Why we need to increase the orthogonal 2D limits? And why this newly created orthogonal view need not to be apply in QFont? Does QFont has default 800*600 limit?

ppc's picture

QuickFont is setting up its own orthographic projection when you call QFont.Begin()

Viewport currentVp = (Viewport)CurrentViewport;
GL.MatrixMode(MatrixMode.Projection);
GL.PushMatrix(); //push projection matrix
GL.LoadIdentity();
GL.Ortho(currentVp.X, currentVp.Width, currentVp.Height, currentVp.Y, -1.0, 1.0);

as you can see in the above code, QuickFont uses the size of the viewport to setup the projection (800x600 in your case, as the window size)

ravi.joshi53 wrote:

Why we need to increase the orthogonal 2D limits?

The orthogonal view must have the same size as the window size, otherwise the text will be rendered with wrong size

ravi.joshi53 wrote:

And why this newly created orthogonal view need not to be apply in QFont?

QuickFont uses your own orthogonal view if you not call QFont.Begin().
The fontRenderOptions.TransformToViewport is useless without the QFont.Begin().

ravi.joshi53's picture
ppc wrote:

QuickFont uses the size of the viewport to setup the projection (800x600 in your case, as the window size)

In the previous case, when I have 16*12 window size, why it was not rendering any font?

ppc wrote:

The fontRenderOptions.TransformToViewport is useless without the QFont.Begin().

Cool, but when I declare fontRenderOptions.TransformToViewport with the same limits of , QFont should use it at the time of QFont.Begin() But it was not....

Is 800*600 the default limits of QFont?

ppc's picture
ravi.joshi53 wrote:

In the previous case, when I have 16*12 window size, why it was not rendering any font?

You had 800x600 window and viewport size with 16x12 orthographic projection.
16x12 is too small to see anything when the font size is larger than the orthographic projection.

//800x600 Window Size
public Program() : base(800, 600, GraphicsMode.Default, "QuickFont Test")
//800x600 Viewport Size
GL.Viewport(0, 0, Width, Height);
//16x12 Orthographic projection
const float RightX = 16.0f;
const float BottomY = 12.0f;
GL.Ortho(RightX, LeftX, TopY, BottomY, FarZ, NearZ);
ravi.joshi53 wrote:

Is 800*600 the default limits of QFont?

No, QFont is using the current viewport size to setup its orthographic projection when you call QFont.Begin()