Шейдер в sfml, покрывающий весь экран - PullRequest
1 голос
/ 13 апреля 2020

Я делаю игру на C ++ и sfml, я использую шейдер и он покрывает все окно экрана.
Но я хочу, чтобы он покрывал только часть экрана, такую ​​как игровой объект или спрайт.

Примечание: не весь код в основном файле мой, но он довольно общий c код для sfml, так что ...

Основной файл:

#define SCREEN_WIDTH 800
#define SCREEN_HEIGHT 480

#include <SFML/Graphics.hpp>

int main() 
{
    sf::RenderWindow window(sf::VideoMode(SCREEN_WIDTH, SCREEN_HEIGHT), "Shaders!!!", sf::Style::Close);
    window.setFramerateLimit(60);

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

    sf::Sprite sprite(texture); //create a sprite from the created texture

    sf::Shader shader;
    shader.loadFromFile("shader.vert", "shader.frag");

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

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

        window.clear(sf::Color(255, 255, 255));
        window.draw(sprite, &shader); //draw the sprite with blur shader
        window.display();
    }
    return 0;
}

шейдер. frag:

#version 330 core
out vec4 FragColor;

in vec4 vertexColor; // the input variable from the vertex shader (same name and same type)  

void main()
{
    FragColor = vertexColor;
}

shader.vert

#version 330 core

in vec2 texCoord;

out vec4 vertexColor;
void main()
{
    gl_Position = vec4(texCoord, 0.0, 1.0);
    vertexColor = vec4(0.5, 0.2, 0.7, 1.0);
}

Есть ли что-то очевидное, чего мне не хватает, или я могу просто перенастроить gl_Position, чтобы просто покрыть часть экрана? (но как бы я прояснил цвет на других «правильных» частях экрана?)

1 Ответ

1 голос
/ 13 апреля 2020

Координаты вершины (и преобразования) определяют область, которая покрыта примитивами. Вы должны определить матрицу преобразования. (См. LearnOpenGL - Преобразования )

Добавьте равномерную переменную их mat4 в вершинный шейдер и преобразуйте координату вершины с помощью матрицы преобразования.

#version 330 core

in vec2 texCoord;
out vec4 vertexColor;
uniform mat4 transformMat;

void main()
{
    gl_Position = transformMat * vec4(texCoord, 0.0, 1.0);
    vertexColor = vec4(0.5, 0.2, 0.7, 1.0);
}

В прикладной программе должно быть определено преобразование и заданы унифицированные hs.

Определите sf::Transform, который масштабирует и переводит координаты вершины. Например:

sf::Transform transform;
transform.scale(0.25f, 0.25f);
transform.translate(-0.5f, -0.5f);

Создать sf::Glsl::Mat4 из преобразования:

sf::Glsl::Mat4 modelMat(transform.getMatrix());

Установить матрицу преобразования равной матричной униформе (sf::Shader::setUniform ):

shader.setUniform("transformMat", modelMat);
...