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

Author Topic: Error when trying to scale texture with dimensions that are not divisible by 8  (Read 1123 times)

0 Members and 1 Guest are viewing this topic.

Blid

  • Newbie
  • *
  • Posts: 2
    • View Profile
Hi!

For the last while I've been experiencing with updating textures from pixels in order to create a canvas library. So far everything has worked as expected except one really annoying thing; Say I created a 16x9 texture with a corresponding pixel array to match it. Displaying this array is really straightforward using array->texture->sprite->draw. But it obviously would display it by its real size. I want the texture to fill the window as much as possible without it being stretched, so I tried to use a view and a [letterbox effect function I found][https://github.com/SFML/SFML/wiki/Source%3A-Letterbox-effect-using-a-view]  and while it initially worked, every time I wanted to update the texture fast (say randomize it) I would get really weird visual glitches. After playing around with it for a while I found that textures with a (16x9) multiplied by some multiple of 8 would work perfectly well.

Here's the simplified code:
#include <SFML/Graphics/Texture.hpp>
#include <SFML/Window/Event.hpp>
#include <SFML/Window/WindowStyle.hpp>
#include <SFML/Graphics.hpp>


const int window_width = 854, window_h = 480;
const int cell_size = 4;
const int mul = 1;
const int canvas_width = 16 * mul, canvas_height = 9 * mul;



using sf::Uint8;
Uint8* pixels;


int get_power(int value);
void randomize();
sf::View getLetterboxView(sf::View view, int windowWidth, int windowHeight);

int main() {
    sf::RenderWindow window(sf::VideoMode(window_width, window_h), "Hello World SFML Window",  sf::Style::Default | sf::Style::Resize);

    pixels = new Uint8[canvas_width * canvas_height * cell_size];

    sf::View view;
    view.setCenter((float)canvas_width /2.0f, (float)canvas_height / 2.0f);
    view.setSize((float)canvas_width, (float)canvas_height);
    view = getLetterboxView(view, window_width, window_h);

    for (int i = 0; i <= canvas_width * canvas_height * cell_size; i++)
        pixels[i] = 0;

    sf::Texture texture;
    if (!texture.create(canvas_width, canvas_height)) { return -1; };

   

    while (window.isOpen()) {

        sf::Event e;
        while (window.pollEvent(e)) {
            switch (e.type) {
                case sf::Event::EventType::Closed:
                    window.close();
                    break;
                case sf::Event::EventType::Resized:
                    view = getLetterboxView(view, e.size.width, e.size.height);
                default: {}; break;
            }
        }

        window.clear();
        randomize();
        texture.update(pixels);
        sf::Sprite s(texture);

        window.setView(view);
        window.draw(s);
        window.display();
    }

    delete [] pixels;
}


void randomize() {
    for (int i =0; i < canvas_width * canvas_height * cell_size; i++)
    {
        pixels[i] = (i % cell_size == cell_size - 1) ? 255 : rand() % 255;
    }
}

 
   



And as you can see, the pixel scale up extremely distorted, I also encountered the same glitch when trying to just scale up the sprite to the exact window screen.

Any help would be greatly appreciated, thanks! :D

Hapax

  • Hero Member
  • *****
  • Posts: 3379
  • My number of posts is shown in hexadecimal.
    • View Profile
    • Links
It looks like image tearing. Does this still occur if you use vertical sync?

Aside from that...
Changing the view can stretch the image as required, as you have found.
Scaling the sprite is another option.
Using an sf::Rectangle with a texture is another option.

Of course, if you don't want it smoothed, make sure that the texture does not have smoothed enabled (it looks like it doesn't anyway).

Selba Ward -SFML drawables
Cheese Map -Drawable Layered Tile Map
Kairos -Timing Library
Grambol
 *Hapaxia Links*

Blid

  • Newbie
  • *
  • Posts: 2
    • View Profile
Turning Vsync on solved the issue. It was a matter of just adding
window.setVerticalSyncEnabled(true);
 
and the texture scaled up perfectly without taring, which makes a lot of sense, considering Vsync's job in the first place.

Thanks a million! :D