【问题标题】:Couldn't create HBITMAP from glReadpixels无法从 glReadpixels 创建 HBITMAP
【发布时间】:2018-10-29 05:38:46
【问题描述】:

所以这是我的代码的一部分,我想做的是从 OpenGL 帧捕获中制作 HBITMAP。

unsigned char *output = 0;
output = new unsigned char[WINDOW_WIDTH * WINDOW_HEIGHT * 3];

glReadPixels(0, 0, WINDOW_WIDTH, WINDOW_HEIGHT, GL_RGB, GL_UNSIGNED_BYTE,
    output);

HBITMAP hdm = CreateBitmap(800, 800, 1, 32, output);

但我的 (HBITMAP)hdm 始终为 NULL。也许还有另一种方法可以做到这一点或有什么问题?我猜 CreateBitmap 会自己分配内存,所以错误一定不在这里。不过输出数组似乎没问题。

我也尝试过这里的代码:Creating a HBITMAP from glReadPixels,但效果不佳,仍然为 NULL。

不胜感激!

【问题讨论】:

  • 由于像素数据的格式是GL_RGB,所以CreateBitmap的第三个参数应该是24而不是32。否则你必须使用GL_RGBA格式。你调试过代码吗? output 收到数据了吗?
  • 你试过打电话给GetLastError吗?错误代码是什么?
  • Rabbid76,非常感谢,它成功了!是的,输出收到了数据。您的解决方案解决了问题。
  • @joe_chip:在调用CreateBitmap 之后调用GetLastError 返回一个无意义的值。

标签: c++ winapi opengl glreadpixels hbitmap


【解决方案1】:

CreateBitmap的第4个参数是识别单个像素颜色所需的位数。

由于像素数据的格式是GL_RGB,所以CreateBitmap的第3个参数是24而不是32。注意GL_RGB/GL_UNSIGNED_BYTE表示3个颜色分量,每个1字节,导致24位:

HBITMAP hdm = CreateBitmap(WINDOW_WIDTH, WINDOW_HEIGHT, 1, 24, output);

或者你必须使用GL_RGBA 格式:

unsigned char *output = new unsigned char[WINDOW_WIDTH * WINDOW_HEIGHT * 4];
glReadPixels(0, 0, WINDOW_WIDTH, WINDOW_HEIGHT, GL_RGBA, GL_UNSIGNED_BYTE, output);

HBITMAP hdm = CreateBitmap(WINDOW_WIDTH, WINDOW_HEIGHT, 1, 32, output);


注意,如果您使用GL_RGB 格式,您必须考虑CreateBitmap 要求每条扫描线都是字对齐的。
glReadPixels 操作的 alignmnet 可以由 glPixelStorei 设置,通过设置参数 GL_PACK_ALIGNMENT,默认为 4,所以这应该不是问题。
但是你必须确保动态分配的缓冲区足够大:

size_t bpl = WINDOW_WIDTH * 3; // bytes per line
size_t r   = bpl % 4;          // rest of division by 4
bpl       += r ? (4-r) : 0;    // bytes per line aligned to 4
unsigned char *output = new unsigned char[bpl * WINDOW_HEIGHT];

size_t bpl = (WINDOW_WIDTH * 3 + 3) & ~3;
unsigned char *output = new unsigned char[bpl * WINDOW_HEIGHT];

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-06-03
    • 2014-03-23
    • 2017-11-10
    • 2012-05-14
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多