将统一数据正确发送到GPU
Properly sending Uniform data to the GPU
我正试图通过制服将Light数据发送到我的Fragment Shader。我对以下功能有问题:
void glUniform3fv(GLint location, GLsizei count, const GLfloat *value);
下面是我编写的一个函数,它旨在将所有Light数据(作为固定大小的数组存储在类"Shader"中)发送到Fragment Shader:(注意:Vector3F类是我自己的,如果需要,我可以提供它的来源。)
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";
}
}
然而,制服是空的我确信我的问题在于我对const GLfloat *value
的尝试。light数据存储在类主体中,所以我不认为作用域是问题所在。
以下文本块在运行时打印:
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.
我只见过这个函数是通过glm::vec3对象调用的,所以我不相信我在第三个参数中提供了足够的信息(我只是发送Vector3F的X值,而不是XYZ)。我试图在函数中构建一个浮动列表,以确保发送所有数据,但一旦超出范围,数据就会丢失,导致运行时崩溃。在这种情况下,我真的希望避免堆分配。什么是格式化我的数据以便正确发送的好方法?我的"片段"着色器可以工作,"灯光数据"是有效的(这样我就可以看到它),但场景是一片漆黑。
glUniform3fv(this->uniforms[LIGHT1POS_U], 3, &(this->lights[0].getPosR().getXR()));
count
参数是要写入的统一中的数组元素数,而不是向量中的元素数。它已经知道向量中元素的数量:这就是3f
在函数名称中的含义。
因此,除非将this->uniforms[LIGHT1POS_U]
定义为uniform vec3 name[3];
,否则此代码将无法正常工作。您应该从每个这样的调用中得到一个GL_INVALID_OPERATION
错误。
当然,所有这些都假设无论getXR
返回什么,都相当于3个浮点数组。既然你没有麻烦给我们看代码,那就没什么好说的了。
相关文章:
- 如何在tensorflow中在gpu和cpu之间拉/推送数据
- Caffe 或 Caffe2 可以直接从 GPU 获得输入数据吗?
- 我可以在视频游戏进入 GPU 之前记录图形数据吗?
- 如何在GPU上的两个数据容器(最好是CUDA)上执行关系连接
- 将统一数据正确发送到GPU
- 使用 CUDA 将大数据复制到 GPU 和从 GPU 复制大数据
- OpenGL在GPU上构建和使用数据
- 为什么使用OpenCL下载数据比在GPU上上传要慢得多
- 使用八叉树在GPU中组织三维体积数据
- 以下数据处理任务是否适合GPU计算
- 如何使用 GPU-DMA 从 GPU-CUDA 代码来复制数据
- 减少 GPU 和 CPU 之间的带宽(先发送原始数据或预先计算)
- DirectX 11 - 计算着色器,将数据从 GPU 复制到 CPU
- 带有 c# 的 c++ AMP 库:如何将数据保存在 GPU 内存中
- 在纹理中的 CPU 和 GPU 之间传递数据
- 是否可以在没有完全定义着色器的情况下测试缓冲区数据是否成功加载到GPU上?(C++、OpenGL 4.4、GLFW)
- 将视频帧数据移动到GPU的最有效方法是什么?
- 保持主机数据完整,同时传输到CUDA GPU
- 如何通过 OpenGL 缓冲区将 glm 数据类型直接传递给 GPU
- 使用推力将部分数据集复制到多个 CUDA GPU