将 OpenGL 场景保存到 TBitmap - glReadPixels 返回空数据?
我正在尝试将 OpenGL 创建的场景保存为 TBitmap。我遇到的问题是 glReadPixels 返回所有空数据(全 0)。思考为什么会发生这种情况?我正在尝试捕获当前的 OpenGL 上下文。 (屏幕上的显示一切正常)。这是 Windows 下的 Delphi 7。
var
pbuf: pointer;
y: integer;
bmp: TBitmap;
p1, p2: pointer;
begin
GetMem( pbuf, pnScene.Width * pnScene.Height * 4);
glReadPixels( 0, 0, pnScene.Width, pnScene.Height, GL_RGBA, GL_UNSIGNED_BYTE, pbuf);
//<------ pbuf now contains all 0's ---------->
bmp := TBitmap.Create;
bmp.PixelFormat := pf32bit;
bmp.Width := pnScene.Width;
bmp.Height := pnScene.height;
for y := 0 to (pnScene.Height -1) do
begin
p1 := bmp.ScanLine[y];
p2 := pointer( integer(pbuf)+ (y * bmp.Width * 4));
CopyMemory( p1, p2, bmp.Width * 4);
end;
bmp.SaveToFile( 'c:\test\temp.bmp');
bmp.Free;
FreeMem( pbuf);
end;
非常欢迎提出建议/想法!
附录:
最终计划是在渲染调用之后立即调用 glReadPixels() 来录制视频。当我这样做时,效果很好,所以这最终不是问题。
I'm attempting to save an OpenGL created scene as a TBitmap. The problem I'm having is glReadPixels is returning all empty data (all 0's). Thoughts on why this would occur? I'm attempting to capture the currentl OpenGL context. (display on screen is all working fine). This is with Delphi 7 under Windows.
var
pbuf: pointer;
y: integer;
bmp: TBitmap;
p1, p2: pointer;
begin
GetMem( pbuf, pnScene.Width * pnScene.Height * 4);
glReadPixels( 0, 0, pnScene.Width, pnScene.Height, GL_RGBA, GL_UNSIGNED_BYTE, pbuf);
//<------ pbuf now contains all 0's ---------->
bmp := TBitmap.Create;
bmp.PixelFormat := pf32bit;
bmp.Width := pnScene.Width;
bmp.Height := pnScene.height;
for y := 0 to (pnScene.Height -1) do
begin
p1 := bmp.ScanLine[y];
p2 := pointer( integer(pbuf)+ (y * bmp.Width * 4));
CopyMemory( p1, p2, bmp.Width * 4);
end;
bmp.SaveToFile( 'c:\test\temp.bmp');
bmp.Free;
FreeMem( pbuf);
end;
And suggestions/thoughts are greatly welcome!
Addendum:
Ultimately the plan was to place the glReadPixels() call right after the rendering calls for purposes of recording video. When I did that, it worked ok, so this ended up being something of a non-problem.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
确保您在创建 GL 上下文的同一线程中执行此操作。如果这是您提供给第三方库的回调函数,那么它可能会在另一个线程中执行,而您甚至没有意识到。这发生在我身上一次,我得到的只是零,就像你一样。
Make sure you are doing this from the same thread as where you created the GL context. If this is a callback function you supply to a third-party library then it may execute in another thread without you even realizing it. This happened to me once and all I got was zeroes just like you.
我假设您想要检索已交换到双缓冲窗口的前缓冲区的图片。然后尝试在
glReadPixels(...)
之前添加glReadBuffer(GL_FRONT)
I assume you want to retrieve a picture that has been already swapped to the front buffer of a double buffered window. Then try prepending a
glReadBuffer(GL_FRONT)
beforeglReadPixels(...)
在
for
循环中,您必须将语句更改为:to
否则,复制的位图将是颠倒的。
In the
for
loop you must change the statement:to
Otherwise, the copied bitmap will be upside-down.