Странное поведение присваивания glm::mat2x4

Я пытаюсь загрузить символы произвольного типа, вставить их в текстуру как подизображения, а затем отрисовать их экземпляры. Хотя большинство из них, похоже, работает, у меня сейчас проблема с сохранением координат текстуры в матрице glm::mat2x4.

Как видно ниже, каждый символ имеет структуру с информацией, которую я сейчас считаю необходимой, включая матрицу с именем face, в которой должны храниться координаты текстуры.

Но когда дело доходит до назначения координат, после выхода из цикла, в котором это происходит, внезапно все значения сходят с ума, без какой-либо (желаемой / предполагаемой) операции, выполняемой с моей стороны.

После создания текстурного атласа с помощью freetype и размещения всех моих структур на карте я назначаю ширину и высоту моей текстуры aw & ah к классу хранения с именем c_atlas.

Я вычисляю координаты текстуры в цикле, показанном ниже, делаю glm::mat2x4 матрицей 0.0f и затем вставляю их в нее. Couting их в консоли дает значения, которые я хочу. Покинув цикл for, я запускаю еще один, просматривая матрицу и выводя их на консоль, что дает мне более или менее случайные значения в диапазоне от e^-23 до e^32.

Все это происходит в namespace foo и вызывается в конструкторе класса в том же пространстве имен (что-то вроде этого:)

foo::class::constructor()
{
  call_function();
}
int main()
{
  foo::class c;
  c.call_function();
}

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

Итак, у меня работает следующий цикл (часть call_function():

namespace foo
{
  namespace alphabet
  {
    const char path_arial[] = "res/font/consola.ttf";
    class character
    {
    public:
      glm::vec2 advance;
      glm::vec2 bearing;
      glm::vec2 size;
      glm::vec2 offset;
      glm::mat2x4 face;
    };
    std::map<char, character> char_map;
    FT_Library m_ftlib;
    FT_Face m_ftface;

    GLuint m_VBO, m_VAO;
  }
  c_atlas ascii;
}
void foo::call_function()
{
  //creating all the charactur structs with freetype and store them in the char_map

  std::ofstream f("atlas_data.csv", std::ios::openmode::_S_app);
  f << "letter;topleft.x;topleft.y;topright.x;topright.y;bottomright.x;bottomright.y;bottomleft.x;bottomleft.y" << std::endl;
  for(auto c : alphabet::char_map)
  {
    std::cout << "b4: " << c.second.offset.x;
    c.second.offset /= glm::vec2(aw,ah);
    std::cout << "\nafter: " << c.second.offset.x << std::endl;
    glm::vec2 ts = c.second.size/glm::vec2(aw,ah);
    //couts the right values

    uint16_t n = 0;
    c.second.face = glm::mat2x4(0.0f);
    for(uint16_t i = 0; i < 4; ++i)
    {
      std::cout << c.first << " at init:\n";
      std::cout << c.second.face[0][i] << "\n";
      std::cout << c.second.face[1][i] << std::endl;
    }
    //couts the right values

    c.second.face[0][n++] = c.second.offset.x;
    c.second.face[0][n++] = c.second.offset.y;
    c.second.face[0][n++] = c.second.offset.x+ts.x;
    c.second.face[0][n++] = c.second.offset.y;
    n = 0;
    c.second.face[1][n++]= c.second.offset.x+ts.x;
    c.second.face[1][n++] = c.second.offset.y+ts.y;
    c.second.face[1][n++] = c.second.offset.x;
    c.second.face[1][n++]= c.second.offset.y+ts.y;
    for(uint16_t i = 0; i < 4; ++i)
    {
      std::cout << c.first << " assigned:\n";
      std::cout << c.second.face[0][i] << "\n";
      std::cout << c.second.face[1][i] << std::endl;
    }
    //still couts the right values

    f  << (char)c.first << ";" << c.second.face[0].x << ";" << c.second.face[0].y << ";" << c.second.face[0].z << ";" << c.second.face[0].w << ";" << c.second.face[1].x << ";" << c.second.face[1].y << ";" << c.second.face[1].z << ";" << c.second.face[1].w << std::endl;
    //the file also have the right values
  }
  f.close();

  glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
  //yet here all the values totally off track, i.e. e^32 or e^-23 (while they should all be between 0.01f - 1.0f)
  for(auto i : alphabet::char_map)
  {
    std::cout << "\ntopleft:\n";
    std::cout << "X: " << i.second.face[0].x << " | " << "Y: " << i.second.face[0].x;
    std::cout << "\ntopright:\n";
    std::cout << "X: " << i.second.face[0].z << " | " << "Y: " << i.second.face[0].w;
    std::cout << "\nbotleft:\n";
    std::cout << "X: " << i.second.face[1].x << " | " << "Y: " << i.second.face[1].x;
    std::cout << "\nbotright:\n";
    std::cout << "X: " << i.second.face[1].z << " | " << "Y: " << i.second.face[1].w;
  }
}

мой mwe:

#include <iostream>
#include <string>
#include "glm/glm.hpp"
#include "GL/gl.h"
#include <map>

struct bin
{
  glm::mat2x4 mat;
};

int main( int argc, char *argv[] )
{

    std::map<char, bin> bucket;
    uint16_t r = 0;
    for(uint16_t n = 0; n < 7; ++n)
    {
      glm::vec4 v = glm::vec4(0.12128f, 0.12412f, 0.15532f, 0.23453f);
      bin b;
      r = 0;
      b.mat[0][r++] = v.x;
      b.mat[0][r++] = v.y;
      b.mat[0][r++] = v.z;
      b.mat[0][r++] = v.w;
      r = 0;
      b.mat[1][r++] = v.x;
      b.mat[1][r++] = v.y;
      b.mat[1][r++] = v.z;
      b.mat[1][r++] = v.w;
      bucket[n] = b;
    }

    for(auto it : bucket)
    {
      r = 0;
      std::cout << "0:\t" << it.second.mat[0][0] << "\t" << it.second.mat[0][1] << "\t" << it.second.mat[0][2] << "\t" << it.second.mat[0][3] << "\n";
      r = 0;
      std::cout << "1:\t" << it.second.mat[1][0] << "\t" << it.second.mat[1][1] << "\t" << it.second.mat[1][2] << "\t" << it.second.mat[1][3] << std::endl;

    }



    return 0;
}

Прямо сейчас я полностью потерян, тем более, что мой mwe работает нормально. Я не знаю, что происходит после выхода из цикла, так что спасибо за любую мысль об этом!

В самом деле, я мог бы просто переписать этот раздел и надеяться, что он будет работать - как мой mwe делает. Но я хотел бы узнать / получить помощь по выяснению, что именно происходит между циклом "назначить" для цикла и "извлечь" для цикла. Есть идеи по этому поводу?

1 ответ

Я сделал это работает для меня сейчас:

Явно присваивая значения следующим образом:

for(auto c : alphabet::char_map)
{
  c.second.face[0][n++] = c.second.offset.x;
  //and so on
}

Не работает должным образом (по какой-либо причине..) Изменение этого в for(uint16_t i = 32; i < 128; ++i) работал на меня. Также это был просто цикл назначения, autoИтерации карты в другом месте работают просто отлично.

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