奇怪的 glm::mat2x4 分配行为

Posted

技术标签:

【中文标题】奇怪的 glm::mat2x4 分配行为【英文标题】:weird glm::mat2x4 assignment behaviour 【发布时间】:2018-03-16 19:41:42 【问题描述】:

我正在尝试加载 freetype 字符,将它们作为子图像填充到纹理中,然后将它们渲染为实例。 虽然大部分似乎都有效,但现在我在将纹理坐标存储到 glm::mat2x4 矩阵时遇到了问题。

如下所示,每个字符都有一个结构,其中包含我现在认为必要的信息,包括一个名为 face 的矩阵,它应该存储纹理坐标。

但是当涉及到分配坐标时,在离开它发生的循环之后,突然所有的值都变得疯狂,我这边没有任何(想要的/预期的)操作。

在使用 freetype 创建纹理图集并将所有结构放入地图后,我将纹理 awah 的宽度和高度分配给名为 c_atlas 的存储类。

我在如下所示的循环中计算纹理坐标,将 glm::mat2x4 设为 0.0f 矩阵,然后将它们填充到其中。将它们计算到控制台中会给出我想要的值。 离开 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;
  

我的妈妈:

#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 工作正常时。 离开for循环后我不知道出了什么问题,所以感谢您对此的任何想法!

确实,我可以重写该部分并希望它能够工作 - 就像我的 mwe 所做的那样。但我想了解/获得帮助,了解“分配”for 循环和“检索”for 循环之间究竟发生了什么。有什么想法吗?

【问题讨论】:

您的代码有点不清楚。 char_map 是全局变量吗?是否在多个文件中使用?如果是这样,您是否使用extern 正确定义了它? 'char_map'是alphabet命名空间的一部分,只用在上面代码所在的cpp中。alphabet是命名空间foo中的命名空间。我编辑了代码以使其更清晰,对此感到抱歉。 【参考方案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 &lt; 128; ++i) 对我有用。也只是分配循环,auto-iterating 提供地图其他地方工作得很好。

【讨论】:

以上是关于奇怪的 glm::mat2x4 分配行为的主要内容,如果未能解决你的问题,请参考以下文章

将 NSMutableArray 分配给另一个时的奇怪行为(iOS 6)

如何根据条件为单元格正确分配样式,而不会在快速滚动后出现奇怪的样式行为?

CUDA 内核的奇怪行为

删除循环中的控件会导致奇怪的行为

iOS swift应用程序中Core Data的奇怪行为

在结构中分配内存时出现不可预测的行为