Расчет координат текстуры из клипа - PullRequest
0 голосов
/ 18 февраля 2019

Я использовал следующий фрагментный шейдер для отображения текстуры:

std::string const fragment_shader_source = 
    "#version 330 core\n"
    ""
    "in vec4 fColor;\n"
    "in vec2 fTexPos;\n"
    "\n"
    "out vec4 finalColor;\n"
    "\n"
    "uniform sampler2D textureUniform;\n"
    "\n"
    "void main() {\n"
    "    \n"
    "    vec4 textureColor = texture(textureUniform, fTexPos);\n"
    "    finalColor = fColor * textureColor;\n"
    "}";

enter image description here

Однако я хотел иметь возможностьотображать только клип с изображением, а не все изображение.Итак, я добавил вызов textureSize, чтобы получить ширину и высоту текстуры, чтобы я мог самостоятельно нормализовать координаты.Но это выглядит так, как будто это просто повторяет

std::string const fragment_shader_source = 
    "#version 330 core\n"
    ""
    "in vec4 fColor;\n"
    "in vec2 fTexPos;\n"
    "\n"
    "out vec4 finalColor;\n"
    "\n"
    "uniform sampler2D textureUniform;\n"
    "\n"
    "void main() {\n"
    "    \n"
    "    ivec2 samplerSize = textureSize(textureUniform, 0);\n"
    "    vec2 texturePos = vec2(fTexPos.x / float(samplerSize.x), fTexPos.y / float(samplerSize.y));\n"
    "    vec4 textureColor = texture(textureUniform, texturePos);\n"
    "    finalColor = fColor * textureColor;\n"
    "}";

Вот как я загружаю данные:

  glBufferData(GL_ARRAY_BUFFER, sizeof(acorn::graphics::Vertex) * sprite_batch_.size() * 6, nullptr, GL_DYNAMIC_DRAW);

  std::vector<Vertex> vertex_data;
  for(auto const& sprite : sprite_batch_) {
    GLfloat fw = (sprite.origin_x + sprite.u);
    GLfloat bw = sprite.origin_x;

    GLfloat fh = (sprite.origin_y + sprite.v);
    GLfloat bh = sprite.origin_y;

    //                      body                  color          texture
    //                      x     y      r    g      b    a     s   t
    vertex_data.push_back({0.5f, 0.5f, 1.0f, 1.0f, 1.0f, 1.0f, fw, fh});
    vertex_data.push_back({-0.5f, 0.5f, 1.0f, 1.0f, 1.0f, 1.0f, bw, fh});
    vertex_data.push_back({0.5f, -0.5f, 1.0f, 1.0f, 1.0f, 1.0f, fw, bh});
    vertex_data.push_back({-0.5f, -0.5f, 1.0f, 1.0f, 1.0f, 1.0f, bw, bh});
    vertex_data.push_back({-0.5f, 0.5f, 1.0f, 1.0f, 1.0f, 1.0f, bw, fh});
    vertex_data.push_back({0.5f, -0.5f, 1.0f, 1.0f, 1.0f, 1.0f, fw, bh});

  }

  glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(Vertex) * vertex_data.size(), static_cast<void*>(vertex_data.data()));


  glDrawArrays(GL_TRIANGLES, 0, 6);

enter image description here

1 Ответ

0 голосов
/ 18 февраля 2019

То, что вы сделали, взяли координаты текстуры и переназначили их, чтобы покрыть только первый пиксель изображения.Если вы хотите обрезать входное изображение, вам нужно указать шейдеру границы области, которую вы хотите показать.Вы можете передать нижнюю левую и верхнюю правую координаты и проверить их.Как то так (не проверено):

#version 330 core
in vec4 fColor;
in vec2 fTexPos;

out vec4 finalColor

uniform sampler2D textureUniform;
uniform float2 lowerLeft;
uniform float2 upperRight;

void main()
{
    if ((lowerLeft.x <= fTexPos.x) && (fTexPos.x <= upperRight.x) &&
        (lowerLeft.y <= fTexPos.y) && (fTexPos.y <= upperRight.y))
    {
        textureColor = texture(textureUniform, fTexPos);
    }
    else
    {
        textureColor = vec4(0.0);
    }
    finalColor = textureColor * fColor;
}
...