Welcome, Guest. Please login or register. Did you miss your activation email?

Show Posts

This section allows you to view all posts made by this member. Note that you can only see posts made in areas you currently have access to.


Topics - underww

Pages: [1]
1
General discussions / Better font rendering
« on: March 29, 2019, 03:08:18 am »
I'm always dissatisfied with SFML font rendering quality. I know it has been improved for the last several years, but it is still hard to say good enough. So I've been trying to improve it myself last few days and I found FT_LOAD_FORCE_AUTOHINT flag in sf::Font makes more bad result mostly.



Check this. The first one is default SFML text and the second one is SFML text without FT_LOAD_FORCE_AUTOHINT flag, the last one is my implementation of SFML + freetype + harfbuzz. Interestingly they all have different letter spacing even though they all have the same character size. I don't know which one is correct, but the result of my implementation is exactly the same as the original code (https://github.com/lxnt/ex-sdl-freetype-harfbuzz)

You easily find ugly rendered Korean text(the red box, only few characters here but generally I could found a lot). Maybe you can't find significant differences between English texts here, but I'm sure it's not just a problem of non-English text. Usually in small texts, SFML font rendering is not so nice.

Any ideas?

I also attach my short example code.
Sorry for my bad English :P

#include <SFML/Graphics.hpp>

#include <ft2build.h>
#include FT_FREETYPE_H

#include <harfbuzz/hb.h>
#include <harfbuzz/hb-ft.h>

int main()
{
        const std::string filename = "fonts/KoPub Dotum Bold.ttf";
        const sf::String string = L"The quick brown fox jumps over the lazy dog. 다람쥐 헌 쳇바퀴에 타고파. 글굴귤";
        constexpr int font_size = 20;

        constexpr int width = 800;
        constexpr int height = 600;

        sf::RenderWindow window(sf::VideoMode(width, height), "SFML Text");

        sf::Font font;
        font.loadFromFile(filename);

        sf::Text text(string, font, font_size);
        text.setPosition(50.f, 50.f);

        FT_Library ft_library;
        FT_Face ft_face;

        if (FT_Init_FreeType(&ft_library) ||
                FT_New_Face(ft_library, filename.c_str(), 0, &ft_face) ||
                FT_Set_Char_Size(ft_face, font_size * 64, font_size * 64, 0, 0))
                return 1;

        hb_font_t* hb_font = hb_ft_font_create(ft_face, NULL);

        hb_buffer_t* hb_buffer = hb_buffer_create();
        hb_buffer_add_utf32(hb_buffer, string.getData(), -1, 0, -1);
        hb_buffer_guess_segment_properties(hb_buffer);

        hb_shape(hb_font, hb_buffer, NULL, 0);

        unsigned int glyph_count = hb_buffer_get_length(hb_buffer);
        hb_glyph_info_t* glyph_info = hb_buffer_get_glyph_infos(hb_buffer, NULL);
        hb_glyph_position_t* glyph_pos = hb_buffer_get_glyph_positions(hb_buffer, NULL);

        std::vector<sf::Uint8> pixelbuffer;
        pixelbuffer.resize(width * height * 4, 0);

        {
                sf::Uint8* current = pixelbuffer.data();
                sf::Uint8* end = current + width * height * 4;

                while (current != end)
                {
                        (*current++) = 255;
                        (*current++) = 255;
                        (*current++) = 255;
                        (*current++) = 0;
                }
        }

        int current_x = 50;
        int current_y = 100;

        // render
        for (unsigned int i = 0; i < glyph_count; ++i)
        {
                if (FT_Load_Glyph(ft_face, glyph_info[i].codepoint, 0))
                        return 1;

                current_x += glyph_pos[i].x_offset / 64;
                current_y += glyph_pos[i].y_offset / 64;

                FT_GlyphSlot ft_slot = ft_face->glyph;
                FT_Render_Glyph(ft_slot, FT_RENDER_MODE_NORMAL);
                FT_Bitmap ft_bitmap = ft_slot->bitmap;

                int w = ft_bitmap.width;
                int h = ft_bitmap.rows;
                int left = ft_slot->bitmap_left;
                int top = ft_slot->bitmap_top;

                const sf::Uint8* buffer = ft_bitmap.buffer;

                if (ft_bitmap.pixel_mode == FT_PIXEL_MODE_MONO)
                        return 1;

                constexpr int padding = 1;

                w += 2 * padding;
                h += 2 * padding;

                for (int y = padding; y < h - padding; ++y)
                {
                        for (int x = padding; x < w - padding; ++x)
                        {
                                if (buffer[x - padding] > 0)
                                {
                                        std::size_t index = (current_x + x + left) + (current_y + y - top) * width - padding;
                                        pixelbuffer[index * 4 + 3] = buffer[x - padding];
                                }
                        }

                        buffer += ft_bitmap.pitch;
                }

                current_x += glyph_pos[i].x_advance / 64;
                current_y += glyph_pos[i].y_advance / 64;
        }
        //

        hb_buffer_clear_contents(hb_buffer);

        sf::Image image;
        image.create(width, height, pixelbuffer.data());

        sf::Texture texture;
        texture.loadFromImage(image);

        sf::Sprite sprite(texture);

        while (window.isOpen())
        {
                sf::Event event;

                while (window.pollEvent(event))
                {
                        if (event.type == sf::Event::Closed)
                                window.close();
                }

                window.clear();
                window.draw(text);
                window.draw(sprite);
                window.display();
        }

        hb_buffer_destroy(hb_buffer);
        hb_font_destroy(hb_font);

        FT_Done_Face(ft_face);
        FT_Done_FreeType(ft_library);

        return 0;
}
 

Edit: fixed typo

2
Graphics / Is it possible to make full white sprite?
« on: January 29, 2018, 03:31:53 pm »
I'm trying to make the sprites white shortly when characters take damage.
Some solutions I found are making white images by hand then swap the sprites or using shaders.

I don't like both solutions for a couple of reasons.
(There're a lot of images and I change the images often. and also I don't want to use shader for now.)

I was trying to make the white sprite using sf::BlendMode, but I could make only white sprite with black background.
(It seems because of the transparent area of the images.)

So I want to know if it is possible to make full white sprite without making white image or shader.
Thanks in advance. :)

3
Window / Strange behavior with borderless windowed fullscreen
« on: April 12, 2017, 12:42:14 pm »
Recently I realized there's a strange difference between these codes.
I tested the codes on Windows 10, Visual Studio 2015/2017, with SFML 2.4.2
(also in my desktop and laptop)

// I assume 1920x1080 is your desktop resolution.
1. window.create(sf::VideoMode(1920, 1080), "title", sf::Style::None);
2. window.create(sf::VideoMode(1920, 1079), "title", sf::Style::None);
3. window.setPosition(1, 1); // after code #1

First, #1 is flickered a little when the window is created while #2 is not flickered.
It also flickers when you try alt+tab or the window gains/loses focus.
(it's also delayed when you gain the window focus in some case)

Windows default screen capture doesn't work after you gain focus the SFML window in #1.
(I could capture the screen after alt+tab twice)

Second, #2 is drawn behind the taskbar while #1 is drawn in front of the taskbar.
(You can also check the same behavior if you change position after you create #1 window) - #3

#3 is the same as #2

So, what's the reason of these strange behaviors?
Thanks in advance.

Edit: In my opinion, this seems to be handled the same as real fullscreen when the window size is the desktop resolution.

4
Graphics / How can I draw pretty box with .ttf font?
« on: February 29, 2016, 08:10:31 pm »
I'm trying to draw a box with sf::text with .ttf font and unicode.
but the result is a bit ugly, here's a screenshot and it's just one text object.
some fonts look better but most fonts don't look good.

I know I can draw a box with sf::Rectangle, but I want to draw it with font for some reason.
and I've tried to turn on/off the font smoothing, but it didn't help.

5
Graphics / Monospace fonts is not rendered correctly
« on: October 18, 2015, 03:12:32 pm »
I'm making a pseudo-console using SFML with a monospace font.
but I found that the monospace fonts is not rendered correctly in SFML.

the width(the 'advance' of the glyph) values are not equal.
and the 'bounds'  values of the glyph are also a bit strange.

here's some glyph data from my test.
(I tested a few monospace fonts, and they're normal in other environments)

any help would be appreciated. Thanks :)

 // OfficeCodePro, 20px
 // bounds = (left, top, width, height)
 'I' : bounds =  2, -14,  8, 14, advance = 12
 'J' : bounds =  1, -14,  9, 14, advance = 12
 'K' : bounds =  2, -14, 10, 14, advance = 12
 'L' : bounds =  3, -14,  8, 14, advance = 12
 'M' : bounds =  2, -14, 10, 14, advance = 13
 'N' : bounds =  2, -14,  9, 14, advance = 12
 'O' : bounds =  1, -14, 10, 14, advance = 12
 'P' : bounds =  2, -14,  9, 14, advance = 12
 'Q' : bounds =  1, -14, 11, 18, advance = 12
 'R' : bounds =  2, -14, 10, 14, advance = 12

 // FantasqueSansMono, 20px
 'I' : bounds =  1, -13,  7, 13, advance = 10
 'J' : bounds =  1, -13,  9, 13, advance = 10
 'K' : bounds =  1, -13,  9, 14, advance = 10
 'L' : bounds =  1, -13,  8, 13, advance = 10
 'M' : bounds =  1, -13,  8, 13, advance = 11
 'N' : bounds =  1, -13,  8, 13, advance = 10
 'O' : bounds =  1, -13,  9, 13, advance = 11
 'P' : bounds =  1, -13,  8, 13, advance = 10
 'Q' : bounds =  1, -13,  9, 15, advance = 10
 'R' : bounds =  1, -13,  9, 14, advance = 10
 

6
Graphics / is it ok to load texture object multiple times?
« on: July 20, 2015, 12:21:02 pm »
Hello there,

I use only one sf::Texture object as a tileset at the same time.
but sometimes I need to change a tileset in game. (runtime)
in this case, can I call loadFromFile function again?
is there any drawback like waste memory? or should I delete and create the object?

Thanks.

7
General / Strange behavior with isKeyPressed() function
« on: July 11, 2015, 09:21:08 am »
Hi,

I'm using isKeyPressed function for smooth movement.
it works correctly when I'm using up/down/left/right with shift.

But when I use numpad, the problem comes up.
First, if I press shift and then numpad, it doesn't catch shift.
and when I press numpad first and then shift (while pressing numpad),
isKeyPressed(numpad) returns always true after I released the key. (not always but very often)

also in this situation, even if I turn the program off and on, the isKeyPressed function still returns true.
Here's a small example of the code. (I'm using windows 8.1 and vs2013)


        while (window.isOpen())
        {
                bool shift = sf::Keyboard::isKeyPressed(sf::Keyboard::LShift) || sf::Keyboard::isKeyPressed(sf::Keyboard::RShift);

                bool up = sf::Keyboard::isKeyPressed(sf::Keyboard::Up) || sf::Keyboard::isKeyPressed(sf::Keyboard::Numpad8);
                bool down = sf::Keyboard::isKeyPressed(sf::Keyboard::Down) || sf::Keyboard::isKeyPressed(sf::Keyboard::Numpad2);
                bool left = sf::Keyboard::isKeyPressed(sf::Keyboard::Left) || sf::Keyboard::isKeyPressed(sf::Keyboard::Numpad4);
                bool right = sf::Keyboard::isKeyPressed(sf::Keyboard::Right) || sf::Keyboard::isKeyPressed(sf::Keyboard::Numpad6);

                std::string string = "";

                if (shift)
                        string += "shift ";
                if (up)
                        string += "up";
                if (down)
                        string += "down";
                if (left)
                        string += "left";
                if (right)
                        string += "right";

                text.setString(string);

                window.clear();
                window.draw(text);
                window.display();
        }
 

I always very appreciate to SFML team, Thanks :)

Edit: fixed typos

8
SFML projects / Arcane, the roguelike
« on: November 18, 2014, 12:17:00 pm »
Hi,

Since the beginning of this year, I've been making a simple roguelike game called Arcane.
I'm trying to make a bit traditional roguelike game but has a nice graphical interface.

Here's a link for the demo. I made this demo for ProcJam.
http://underww.itch.io/arcane

It's a just engine demo though, :)
Thanks.



[Screenshots]




9
General / Looking for gamedev resources.
« on: April 06, 2014, 09:24:07 pm »
I read SFML Game Development book and it was very impressive.
Actually, there are lots of game tutorials / articles, but I've hardly seen something handles the modern techniques and C++11.
Is there any good gamedev resources with C++11 or modern techniques?

I don't know about C++11 much, but I've been using C++ around 10 years.
(and relatively new to gamedev.)

10
Window / Centering the game window.
« on: March 07, 2014, 04:01:33 pm »
SFML basically centers the window when it is created.
but it doesn't consider Windows taskbar and also the game window's border size.
the border size is negligible but, the taskbar is a bit annoying.
here's some pictures for the explanation.





I want to set the window like the second image.
so, how can I get the taskbar's position, size and a window's border size?
any advice will be appreciated. thank you :)

11
Graphics / Afterimages while fast scrolling screen
« on: January 08, 2014, 12:38:38 pm »
While scrolling the game screen, it isn't clear because of afterimages.

It is not a serious problem but, I want to fix this.

I guess this problem related with double buffering.

I'm already using vertical sync, but it doesn't help to fix this problem.

I'm using sf::View to scroll the screen.

Here's some sample code.

// view.move(0.f, 1.f); // this works well
// view.move(0.f, 2.f); // this works well too
view.move(0.f, 3.f); // the problem happens here

window.clear();
window.setView(view);
window.draw();
window.display();
 

Thanks :)

12
Graphics / Sprite draw problem. or bug?
« on: December 31, 2013, 12:29:43 pm »
I found sometimes SFML draw a sprite incorrectly on a particular position or in some cases.

For example, this code can't draw a sprite correctly.

I tested it on SFML 2.1 stable version and latest version also.

Here is the source code and the result screen.

        sf::RenderWindow window(sf::VideoMode(800, 600), "Test", sf::Style::Close);

        sf::Texture texture;
        texture.loadFromFile("texture.png");

        sf::Sprite sprite(texture);
        sprite.setPosition(16.49849838f, 16.49849838f);

        sf::Sprite sprite2(texture);
        sprite2.setPosition(16.5f, 50.f);

        sf::Sprite sprite3(texture);
        sprite3.setPosition(16.f, 85.f);

        while (window.isOpen())
        {
                sf::Event event;
                while (window.pollEvent(event))
                {
                        if (event.type == sf::Event::Closed)
                                window.close();
                }

                window.clear();
                window.draw(sprite);
                window.draw(sprite2);
                window.draw(sprite3);
                window.display();
        }
 




Only third one draw normally.

Actually it can avoid using just integer position.

But, when I draw an animation like this ( move(velocity * dt.asSeconds(); )

SFML will draw an incorrect image a while.

Also sf::Font looks have the same problem.

13
Graphics / Change sprites color problem.
« on: November 29, 2013, 03:54:12 pm »
I'm trying to make short white blink effect as a result of collisions.

but I can't change sprite's color to white because white color is default color on sprite class.

so, is there any solution for this problem?

Thanks and I'm sorry for my poor English, I hope you understand my question.

Pages: [1]