C++ 正确地将统一数据发送到GPU

C++ 正确地将统一数据发送到GPU,c++,opengl,C++,Opengl,我试图通过制服将灯光数据发送到片段着色器。我对以下功能有问题: void glUniform3fv(GLint location, GLsizei count, const GLfloat *value); 下面是我编写的一个函数,用于将所有灯光数据(存储为类“着色器”中的固定大小数组)发送到片段着色器: (注意:Vector3F类是我自己的,如果需要,我可以提供它的源代码。) 我只见过通过glm::vec3对象调用此函数,因此我不相信我在第三个参数中提供了足够的信息(我似乎只发送Vector

我试图通过制服将灯光数据发送到片段着色器。我对以下功能有问题:

void glUniform3fv(GLint location, GLsizei count, const GLfloat *value);
下面是我编写的一个函数,用于将所有灯光数据(存储为类“着色器”中的固定大小数组)发送到片段着色器: (注意:Vector3F类是我自己的,如果需要,我可以提供它的源代码。)

我只见过通过glm::vec3对象调用此函数,因此我不相信我在第三个参数中提供了足够的信息(我似乎只发送Vector3F的X值,而不是XYZ)。我试图在函数中构建一个浮动列表,以确保发送所有数据,但一旦超出范围,数据就会丢失,导致运行时崩溃。在这种情况下,我真的希望避免堆分配。有什么好方法可以格式化我的数据,使其正确发送?我的片段着色器工作,灯光数据有效(因此我应该看到它),但场景是漆黑的

count
参数是要写入的统一数组中的数组元素数,而不是向量中的元素数。它已经知道向量中元素的数量:这就是函数名中的
3f
的意思

因此,除非
this->uniforms[LIGHT1POS_]
被定义为
uniform vec3 name[3],则此代码将无法正常工作。每次这样的调用都会出现
GL\u INVALID\u操作
错误


当然,所有这些都假设
getXR
返回的任何内容都相当于3个浮点数组。由于您没有费心向我们展示代码,因此在这方面没有更多的内容。

“我试图在函数中建立一个浮动列表,以确保所有数据都已发送,但一旦超出范围,数据就会丢失,导致运行时崩溃。”所以这段记忆没有必要在你通话后继续保持。@Nicolas我不知道是这样的,谢谢你!啊,这是我的错误假设。非常感谢。另外,getXR()只是一个非常量函数,返回向量的X值,这当然是错误的。我现在把每三个值放入它自己的浮点数组中,它就工作了。
void Shader::updateLights()
{
    // this->lights[x].getPosR() returns a Vector3F reference. Same with getLightDirectionR() and getColourR().
    glUniform3fv(this->uniforms[LIGHT1POS_U], 3, &(this->lights[0].getPosR().getXR()));
    glUniform3fv(this->uniforms[LIGHT1LD_U], 3, &(this->lights[0].getLightDirectionR().getXR()));
    glUniform3fv(this->uniforms[LIGHT1COLOUR_U], 3, &(this->lights[0].getColourR().getXR()));
    glUniform1f(this->uniforms[LIGHT1POW_U], this->lights[0].getPowerR());

    glUniform3fv(this->uniforms[LIGHT2POS_U], 3, &(this->lights[1].getPosR().getXR()));
    glUniform3fv(this->uniforms[LIGHT2LD_U], 3, &(this->lights[1].getLightDirectionR().getXR()));
    glUniform3fv(this->uniforms[LIGHT2COLOUR_U], 3, &(this->lights[1].getColourR().getXR()));
    glUniform1f(this->uniforms[LIGHT2POW_U], this->lights[1].getPowerR());

    glUniform3fv(this->uniforms[LIGHT3POS_U], 3, &(this->lights[2].getPosR().getXR()));
    glUniform3fv(this->uniforms[LIGHT3LD_U], 3, &(this->lights[2].getLightDirectionR().getXR()));
    glUniform3fv(this->uniforms[LIGHT3COLOUR_U], 3, &(this->lights[2].getColourR().getXR()));
    glUniform1f(this->uniforms[LIGHT3POW_U], this->lights[2].getPowerR());

    glUniform3fv(this->uniforms[LIGHT3POS_U], 3, &(this->lights[3].getPosR().getXR()));
    glUniform3fv(this->uniforms[LIGHT3LD_U], 3, &(this->lights[3].getLightDirectionR().getXR()));
    glUniform3fv(this->uniforms[LIGHT3COLOUR_U], 3, &(this->lights[3].getColourR().getXR()));
    glUniform1f(this->uniforms[LIGHT3POW_U], this->lights[3].getPowerR());

    // Print out all the information to ensure that data is correct.
    std::cout << "Lights Info:\n";
    for(unsigned int i = 0; i < Shader::MAX_LIGHTS; i++)
    {
        Light* l = &(this->lights[i]);
        std::cout << "Light Id " << i << ": ";
        std::cout << "Position = [" << l->getPosR().getX() << ", " << l->getPosR().getY() << ", " << l->getPosR().getZ() << "], ";
        std::cout << "Light Direction = [" << l->getLightDirectionR().getX() << ", " << l->getLightDirectionR().getY() << ", " << l->getLightDirectionR().getZ() << "], ";
        std::cout << "Light Colour = [" << l->getColourR().getX() << ", " << l->getColourR().getY() << ", " << l->getColourR().getZ() << "], ";
        std::cout << "Light Power = " << l->getPowerR() << " Watts.\n";
    }
}
Light Id 0: Position = [0, 15, 0], Light Direction = [0, -1, 1], Light Colour = [1, 1, 1], Light Power = 200 Watts.
Light Id 1: Position = [5, 15, 10], Light Direction = [0, -1, 1], Light Colour = [1, 1, 1], Light Power = 200 Watts
Light Id 2: Position = [10, 15, 20], Light Direction = [0, -1, 1], Light Colour = [1, 1, 1], Light Power = 200 Watts.
Light Id 3: Position = [15, 15, 30], Light Direction = [0, -1, 1], Light Colour = [1, 1, 1], Light Power = 200 Watts.
glUniform3fv(this->uniforms[LIGHT1POS_U], 3, &(this->lights[0].getPosR().getXR()));