GlReadPixels生成的照片已损坏

jgzswidk  于 2022-09-26  发布在  其他
关注(0)|答案(1)|浏览(260)

我正在尝试使用glReadPixels将OpenGL屏幕保存到文件中。我找到了这个代码:

void saveScreenshotToFile(const char* filename, int WIDTH, int HEIGHT) {
    int* buffer = new int[WIDTH * HEIGHT * 3];
    glReadPixels(0, 0, WIDTH, HEIGHT, GL_BGR, GL_UNSIGNED_BYTE, buffer);
    FILE* out = fopen(filename, "w");
    short  TGAhead[] = { 0, 2, 0, 0, 0, 0, WIDTH, HEIGHT, 24 };
    fwrite(&TGAhead, sizeof(TGAhead), 1, out);
    fwrite(buffer, 3 * WIDTH * HEIGHT, 1, out);
    fclose(out);
}

在那之后,我只是给你打电话

saveScreenshotToFile("file.tga", 800, 600);

This是我所期望的。但this是我得到的。我正在使用2个VAOS,一个用于物体,一个用于灯光。

yzuktlbb

yzuktlbb1#

这是因为默认情况下,GL_PACK_ALIGNMENT参数为4。由于图像具有3个颜色通道(GL_BGR)并且压缩紧密,因此图像的一行大小可能不会对齐到4个字节。
如果从GPU读取具有3个颜色通道的RGB图像,并且3*宽度不能被4整除,则在读取具有glReadPixels的图像之前,必须将GL_PACK_ALIGNMENT设置为1:

glPixelStorei(GL_PACK_ALIGNMENT, 1);
glReadPixels(0, 0, WIDTH, HEIGHT, GL_BGR, GL_UNSIGNED_BYTE, buffer);

另一个问题可能是,您的屏幕是DPI缩放的,并且帧缓冲区大小与窗口大小不匹配。在截图前确定帧缓冲区大小,例如GLFW:

int w, h;
glfwGetFramebufferSize(wnd, &w, &h);
saveScreenshotToFile("file.tga", w, h);

更多类似C++的函数:

void saveScreenshotToFile(const char* filename, int width, int height) {
    short tgaHead[] = { 0, 2, 0, 0, 0, 0, (short)width, (short)height, 24 };
    std::vector<char> buffer(width*height*3);
    glReadPixels(0, 0, width, height, GL_BGR, GL_UNSIGNED_BYTE, buffer.data());

    std::fstream outFile;
    outFile.open(filename, std::ios::app | std::ios::binary);
    outFile.write(reinterpret_cast<char*>(&tgaHead), sizeof(tgaHead));
    outFile.write(buffer.data(), buffer.size());
    outFile.close();
}

相关问题