gpt4 book ai didi

windows - OpenGL - 直接渲染为位图

转载 作者:可可西里 更新时间:2023-11-01 13:20:04 25 4
gpt4 key购买 nike

我正在制作一个应用程序,其中有一堆小窗口和控件(2D 渲染),我想将每个窗口和控件渲染到它自己的位图。到目前为止,这是:

uses dglOpenGL;
...
var BMP: TBitmap;
DC, RC: HDC;
...
function TMainForm.Init: Boolean;
begin
Result := InitOpenGL;
if Result = True then
begin
BMP := TBitmap.Create;
BMP.PixelFormat := pf24bit;
BMP.Width := 1280;
BMP.Height := 1024;

DC := (BMP.Canvas.Handle);
RC := CreateRenderingContext(DC,
[opGDI, opDoubleBuffered], // tried changing, didn't help
24,
24,
0,
0,
0,
0);
ActivateRenderingContext(DC, RC);

glClearColor(0.27, 0.4, 0.7, 0.0); // light blue
glViewport(0, 0, 1280, 1024);
glMatrixMode(GL_PROJECTION);
glLoadIdentity;
glOrtho(0, 1280, 0, 1024, -1, 10);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity;
end;
end;

渲染过程:

  glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT);

// red quad
glColor3f(1, 0, 0);
glBegin(GL_QUADS);
glVertex2f(100, 100);
glVertex2f(1280-100, 100);
glVertex2f(1280-100, 1024-100);
glVertex2f(100, 1024-100);
glend;

// swap
SwapBuffers(DC);

但是没有输出。
如果我使用 MainForm.Canvas.Draw(0, 0, BMP);,则会出现一个白色矩形。

我想在位图上渲染东西,因为我可以用位图做很多事情(绘制其他图像、绘制文本、模糊),但如果有另一种方式进行离屏渲染,那没关系......

那么如何为离屏渲染设置我的应用程序呢?

最佳答案

必须创建与目标设备上下文相匹配的 OpenGL 上下文。对于窗口,它们的创建方式与位图不同。看 http://msdn.microsoft.com/en-us/library/windows/desktop/dd368826(v=vs.85).aspx特别是 dwFlags,其中还有其他

PFD_DRAW_TO_WINDOW The buffer can draw to a window or device surface.

PFD_DRAW_TO_BITMAP The buffer can draw to a memory bitmap.

但是,您应该赶快为您的 DIB DC 创建渲染上下文。为什么?因为它会非常慢,因为 DIB 部分上的 OpenGL 渲染上下文将使用仅支持在 CPU 上运行的 OpenGL-1.1 的软件光栅器。

相反,您应该创建一个帧缓冲区对象,附加一个颜色渲染缓冲区附件,并在完成后将 glReadPixels 添加到您的 DIBSection 中。更容易、更快。

因评论请求而更新

(我不知道为什么 StackOverflow 不能正确着色语法,即弄清楚哪里是注释,哪里不是)

// flushes the OpenGL error queue and
// counts the total number of errors
int flushGLErrors(void)
{
int i = 0;
while( glGetError() != GL_NO_ERROR ) {
i++;
}

return i;
}

// returns a HBITMAP or NULL.
// The HBITMAP must be freed using DeleteObject
HBITMAP ReadPixelsToHBITMAP(
int x,
int y,
int width,
int height )
{
void *pdata = NULL;

/* Note that this values only makes sense if we know a target
* output size like if we put the image to paper. */
const int physical_resolution = 2835; /* 72 DPI */

BITMAPINFOHEADER bmih = {
/* .biSize = */ sizeof(bmih),
/* .biWidth = */ width,
/* .bi.Height = */ height,
/* .biPlanes = */ 1, /* mandatory */
/* .biBitCount = */ 24, /* 8 bits per pixel */
/* .biCompression = */ BI_RGB, /* uncompressed */
/* .biSizeImage = */ 0, /* implicit */
/* .biXPelsPerMeter = */ physical_resolution, /* ignored */
/* .biYPelsPerMeter = */ physical_resolution, /* ignored */
/* .biClrUsed = */ 0, /* no palette */
/* .biClrImportant = */ 0
};

HBITMAP hbm = CreateDIBSection(
hdc, /* may be different than the DC used for OpenGL */
(PBITMAPINFO)&bmih, /* can do this cast, because no palette is used */
DIB_RGB_COLORS,
&pdata,
NULL,
0
);

if( !hbm ) {
return NULL;
}

flushGLErrors();

glPixelStorei(GL_PACK_SWAP_BYTES, GL_FALSE);
glPixelStorei(GL_PACK_LSB_FIRST, GL_TRUE);
glPixelStorei(GL_PACK_ROW_LENGTH, 0);
glPixelStorei(GL_PACK_IMAGE_HEIGHT, 0);
glPixelStorei(GL_PACK_SKIP_PIXELS, 0);
glPixelStorei(GL_PACK_SKIP_ROWS, 0);
glPixelStorei(GL_PACK_ALIGNMENT, 1);

if( glGetError() != GL_NO_ERROR ) {
DeleteObject(hbm);
return NULL;
}

glReadPixels(x, y, width, height, GL_BGR, GL_UNSIGNED_BYTE, pdata);

if( glGetError() != GL_NO_ERROR ) {
DeleteObject(hbm);
return NULL;
}

return hbm;
}

关于windows - OpenGL - 直接渲染为位图,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14908743/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com