我有一个4x4矩阵类,它将值保存为2d float array: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大小的float数组中,这对于每个tick来说似乎都很昂贵。
编辑 这就是我所做的,每次抽奖操作看起来真的很贵
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;
}
答案 0 :(得分:5)
这取决于两件事。假设您的编译器是C ++ 03,(并且您关心标准符合性),那么您的Matrix
类必须为a POD type。特别是它必须没有构造函数。 C ++ 11 relaxes these rules significantly。
另一件事是你的矩阵似乎是行主要的。我这样说是因为你的operator[]
似乎认为你的2D数组是行主要的。第一个坐标是row
而不是列,因此它是行主要存储顺序。
如果你打算给OpenGL行主矩阵,你需要告诉它们是行主要的:
glUniformMatrix4fv(shader.getLocation(“Bones”),numJoints,GL_TRUE,finalBones [0] [0]);
答案 1 :(得分:1)
使用C ++ 11,可以将具有standard layout的类强制转换为指针,对其第一个成员进行寻址,然后再返回。通过 sizeof 检查,您可以保证连续的矩阵数据:
#include <type_traits>
static_assert((sizeof(Matrix4) == (sizeof(GLfloat) * 16)) &&
(std::is_standard_layout<Matrix4>::value),
"Matrix4 does not satisfy contiguous storage requirements");
一旦你有非平凡的构造函数等, Trivial(或POD)布局就会过于严格。你的帖子建议你需要将transpose
参数设置为GL_TRUE
。 / p>