【发布时间】:2020-12-13 01:09:23
【问题描述】:
假设我有 640x256 的数据矩阵,其中每个元素都是 -10 到 600 范围内的浮点数。我想在屏幕上显示这个矩阵,每个元素都从 RGB 调色板中分配一个颜色。树莓派上的 OpenGL、C++
我目前在做什么:
for (unsigned int i = 0; i < frameSize; ++i) { // frameSize = 640x256
float value = data[i];
if (value > maxVal) {
color = palette.back();
}
else if (value < minVal) {
color = palette.front();
}
else {
color = palette[((value - minVal) / (maxVal - minVal)) * (palette.size() - 1)];
}
imgData[3 * i] = color.R;
imgData[3 * i + 1] = color.G;
imgData[3 * i + 2] = color.B;
}
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, imgData);
glBegin(GL_QUADS);
{
glTexCoord2f(0, 0); glVertex2f(0, 0);
glTexCoord2f(1, 0); glVertex2f(width, 0);
glTexCoord2f(1, 1); glVertex2f(width, height);
glTexCoord2f(0, 1); glVertex2f(0, height);
}
glEnd();
palette 是用户自定义的 RGB 颜色向量; minVal 和 maxVal 是 data 中的最小值和最大值,但可以由用户更改。
此代码可以正常工作,但图像在 CPU 上被着色,这对于大型 数据 可能会很慢。是否可以直接将浮点 data 作为纹理传递,并在输出上使用 OpenGL 使用调色板对其进行着色?
我不是在问如何优化 CPU-bounded 循环。我的问题是是否可以在 OpenGL 渲染期间完全删除它并完成它的任务。
【问题讨论】:
-
此代码工作正常,但图像在 CPU 上着色,这对于大数据可能会很慢。您是否检查过它在实际用例中是否不可接受? (我很难想象在调色板中进行额外的查找是那么昂贵。)先前的优化可能是只为可见部分生成纹理(即确切的显示尺寸)。使用着色器程序,您有更多选择,但从 OpenGL 1.x 切换到 OpenGL 3.x 也是您必须考虑的一项工作。 (我已经做到了。我知道我在说什么。);-)
-
这是从相机流式传输的图像,并且始终可见。 320x256 @60 Hz 没有问题。但是当分辨率更高时,CPU 使用率会跃升至 100%,并且显示帧速率会降至 fps 以下。当我移除着色循环时,它仍然以超过 40 fps 的速度运行,CPU 使用率降低了 20-30%。
-
这是一个值得edited in 的附加信息。尽管如此,[-10, 600] 范围内的值对我来说似乎有点令人惊讶。您仍然可以选择使用 OpenGL 3.x 和着色器将工作负载转移到 GPU。你也可以试试是否可以通过转动浮点运算来挤出一点。进入积分补偿。并仅用算术运算替换分支(使用
if)。
标签: c++ opengl optimization