2

我有一个 4x4 矩阵类,将值保存为 2d 浮点数组:float mat[4][4]; 我重载了 [] 运算符

inline float *Matrix4::operator[](int row) { return mat[row]; }

我的着色器中有一个统一的 mat4(统一的 mat4 Bones[64];),我将把我的数据上传到上面。我将骨骼保存为 Matrix4 指针 (Matrix4 *finalBones),它是一个矩阵数组,包含 numJoints 元素。这就是我用来上传数据的:

glUniformMatrix4fv(shader.getLocation("Bones"),numJoints,false,finalBones[0][0]);

我完全不确定会发生什么,所以我需要询问这是否可行,或者我需要将所有内容提取到 16*numJoints 大小的浮点数组中,这对于每个刻度来说似乎都很昂贵。

编辑这是我所做的,对于每个绘制操作来说似乎真的很昂贵

void MD5Loader::uploadToGPU()
{
float* finalmat=new float[16*numJoints];
for (int i=0; i < numJoints; i++)
    for (int j=0; j < 4; j++)
        for(int k=0; k < 4; k++)
            finalmat[16*i + j*4 + k] = finalBones[i][j][k];


glUniformMatrix4fv(shader.getLocation("Bones"),numJoints,false,finalmat);

delete[] finalmat;
}
4

2 回答 2

5

这取决于两件事。假设您的编译器是 C++03,(并且您关心标准合规性),那么您的Matrix必须POD 类型。特别是,它必须没有构造函数。C++11显着放宽了这些规则

另一件事是您的矩阵似乎是行优先的。我这样说是因为您operator[]似乎认为您的 2D 数组是行优先的。第一个坐标是row而不是列,所以它是行主要的存储顺序。

如果你要给 OpenGL 行优先矩阵,你需要告诉它它们是行优先的:

glUniformMatrix4fv(shader.getLocation("Bones"), numJoints, GL_TRUE, finalBones[0][0]);

于 2013-04-02T10:40:48.037 回答
1

使用 C++11,具有标准布局的类可以转换为指针,寻址它的第一个成员,然后再返回。通过sizeof检查,您可以保证连续的矩阵数据:

#include <type_traits>

static_assert((sizeof(Matrix4) == (sizeof(GLfloat) * 16)) &&
              (std::is_standard_layout<Matrix4>::value),
              "Matrix4 does not satisfy contiguous storage requirements");

一旦您拥有非平凡的构造函数等,平凡transpose(或 POD)布局就太受限制了。您的帖子建议您需要将参数设置为GL_TRUE.

于 2013-04-02T11:24:54.337 回答