Переместить круг с матрицей проекции

Мне нужна помощь, пытаясь переместить мой круг с матрицей просмотра. Я могу расположить круг, но не могу его переместить. Как я могу это сделать?

Прямо сейчас ограничивающий прямоугольник перемещается, но не круг.

Я пытался центрировать круг в прямоугольнике, но это не работает.

Любая помощь приветствуется!

#include <glew.h>
#include "circle.h"

Circle::Circle()
{
    const std::string vertexShaderSource = R"END(

        #version 330 core
        layout (location = 0) in vec4 vertex; // <vec2 position, vec2 texCoords>

        uniform mat4 model;
        uniform mat4 projection;
        uniform mat4 view;

        void main()
        {
            gl_Position = projection * view * model * vec4(vertex.xy, 0.0, 1.0);
        }

        )END";

    const std::string fragmentShaderSource = R"END(

        #version 330 core

        out vec4 color;
        uniform vec2 dim;
        uniform vec2 pos;

        /**
         * Convert r, g, b to normalized vec3
         */
        vec3 rgb(float r, float g, float b) {
            return vec3(r / 255.0, g / 255.0, b / 255.0);
        }

        /**
         * Draw a circle at vec2 `pos` with radius `rad` and
         * color `color`.
         */
        vec4 circle(vec2 uv, vec2 pos, float rad, vec3 color) {
            float d = length(pos - uv) - rad;
            float t = clamp(d, 0.0, 1.0);
            return vec4(color, 1.0 - t);
        }

        void main() {

            vec2 uv = gl_FragCoord.xy;
            float radius = 60;

            vec2 center = pos;

            // Background layer
            vec4 layer1 = vec4(rgb(210.0, 222.0, 228.0), 0.3);
            
            // Circle
            vec3 red = rgb(225.0, 95.0, 60.0);
            vec4 layer2 = circle(uv, center, radius, red);
            
            // Blend the two
            color = mix(layer1, layer2, layer2.a);
        }

        )END";

    shader.Compile(vertexShaderSource.c_str(), fragmentShaderSource.c_str());

    // Configure VAO etc..
}

void Circle::Update(float deltaTime, int width, int height)
{
    // Activate shader
    shader.Activate();

    auto camera = Services::Get<RenderService>()->camera;

    glm::mat4 model = glm::mat4(1.0f);
    glm::mat4 view;

    if (skipPan == false)
    {
        view = camera.GetViewMatrix();
    }
    else
    {
        view = glm::mat4{1.0f};
    }

    projection = glm::ortho(0.0f, static_cast<float>(width),
                            static_cast<float>(height), 0.0f, -1.0f, 1.0f);

    model = glm::translate(model, glm::vec3(transform.position.x, transform.position.y, 0.0f));
    model = glm::scale(model, glm::vec3(transform.dimension.width, transform.dimension.height, 1.0f));

    shader.setMat4("projection", projection);
    shader.setMat4("model", model);
    shader.setMat4("view", view);
    shader.setVec2("dim", glm::vec2{transform.dimension.width, transform.dimension.height});
    shader.setVec2("pos", glm::vec2{transform.position.x, transform.position.y});
    shader.setVec4("spriteColor", glm::vec4{style.Background.r, style.Background.g, style.Background.b, style.Background.a});

    glBindVertexArray(vao);
    glDrawArrays(GL_TRIANGLES, 0, 6);
}

Это проблема, с которой я уже некоторое время борюсь. Это относится и к другим фигурам, которые рендерятся с помощью SDF и тому подобного.

// configure VAO/VBO
const float vertices[] = {
    0.0f, 1.0f, 0.0f,
    1.0f, 0.0f, 1.0f,
    0.0f, 0.0f, 0.0f,
    0.0f, 1.0f, 0.0f,
    1.0f, 1.0f, 1.0f,
    1.0f, 0.0f, 1.0f};

glGenVertexArrays(1, &vao);
glGenBuffers(1, &vbo);

glBindBuffer(GL_ARRAY_BUFFER, vbo);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);

glBindVertexArray(vao);
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void *)0);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindVertexArray(0);

можете ли вы подтвердить glDrawArrays достаточно одного звонка? для двух объектов принадлежат ли эти два объекта одному массиву?

Dickens A S 09.01.2023 14:29

Задаю этот вопрос, причина вижу только одна glBindVertexArray

Dickens A S 09.01.2023 14:31

Да, два объекта принадлежат одному и тому же массиву вершин.

J.Wennergren 09.01.2023 14:34

так что проблема только с вашим массивом, который смущает gl_Position

Dickens A S 09.01.2023 14:37

Хм, ты прав. но я не уверен, как это исправить.

J.Wennergren 09.01.2023 14:44

можете ли вы подтвердить после звонка useProgram, вы связали атрибут pos с помощью метода glGetAttribLocation? а также подтвердите, что вы используете glGetUniformLocation для привязки glUniformMatrix

Dickens A S 09.01.2023 15:02

Нет, я не связывал атрибут pos с этим методом. Я думал, что мне не нужно, так как я использую униформу.

J.Wennergren 09.01.2023 15:06

Давайте продолжим обсуждение в чате.

Dickens A S 09.01.2023 16:28

Почему uv = gl_FragCoord.xy? почему не координаты uv от вершин? (gl_MultiTexCoord0; или из вершинного шейдера, который является повсеместно распространенным методом). Используя gl_FragCoord, вы непреднамеренно сделали то, что предлагает этот ответ . Но на самом деле вам нужно противоположное тому, что там предлагается, то есть просто используйте координаты UV-текстуры обычным способом. Не волнуйся, ты не первый

Wyck 09.01.2023 17:02
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
9
73
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Вы говорите, что пытаетесь переместить круг с матрицей вида. Вы действительно передаете эту матрицу своему вершинному шейдеру и используете ее при вычислении gl_Position. Однако ваш расчет фрагментного шейдера основан на gl_FragCoord и никоим образом не включает матрицу представления. Помните, что gl_FragCoord — это координаты фрагмента относительно нижнего левого угла фреймбуфера (обычно), и поэтому на него не влияют преобразования модели/вида/проекции.

Чтобы решить эту проблему, вы можете выполнить одно из следующих действий:

  • Вычислите координаты фрагмента центра вашего круга в Circle::Update и передайте их униформе pos:

    glm::vec4 pos = view*glm::vec4{transform.position.x, transform.position.y, 0.0f, 1.0f};
    shader.setVec2("pos", pos.xy);
    
  • Примените преобразование области просмотра во фрагментном шейдере — то же самое, что и выше, но делается в шейдере. Это довольно некрасиво, поскольку вы применяете view, но не model, потому что последнее уже учтено в значении pos. Также это требует больше вычислений во фрагментном шейдере.

  • Измените свой фрагментный шейдер, чтобы он работал с текстурными координатами вместо gl_FragCoord. Если вы установите фиксированные координаты текстуры в вершинах четырехугольника, то интерполированные координаты внутри четырехугольника будут корректно преобразовываться в отношении любого вида/модели/проекции, таким образом обрабатывая масштабирование или даже перспективные проекции из коробки. Это, вероятно, будет самым аккуратным решением в вашем случае. (При этом растеризация на основе gl_FragCoord иногда необходима, чтобы избежать артефактов на стыке между двумя треугольниками четырехугольника.)

Спасибо за ваш ответ. Я выбрал вариант № 3, и теперь он работает как шарм!

J.Wennergren 09.01.2023 19:40

Другие вопросы по теме