wordpress   发布时间:2022-04-02  发布网站:大佬教程  code.js-code.com
大佬教程收集整理的这篇文章主要介绍了windows – OpenGL – 直接渲染到位图大佬教程大佬觉得挺不错的,现在分享给大家,也给大家做个参考。

概述

我正在制作具有一堆小窗口和控件的应用程序(所以它是2D渲染),我想将每个窗口和控件渲染到它自己的位图(没有那么多).这有: uses dglOpenGL; ... var BMP: TBitmap; DC, RC: HDc; ... function TMainForm.Init: Boolean; begin Result := InitOpenGL; if Result = T
我正在制作具有一堆小窗口和控件的应用程序(所以它是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);
    ActivateRenderingContext(DC,RC);

    glClearColor(0.27,0.4,0.7,0.0);//Light blue
    glViewport(0,1280,1024);
    glMatrixMode(GL_projection);
    glLoadIdentity;
    glOrtho(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);
  glBegin(GL_QUADS);
    glVertex2f(100,100);
    glVertex2f(1280-100,1024-100);
    glVertex2f(100,1024-100);
  glend;

  //Output
  SwapBuffers(DC);

但是没有输出.
如果我使用MainForm.Canvas.Draw(0,BMp);然后会出现白色矩形.

我想在位图上渲染东西,因为我可以使用位图做很多事情(在它上面绘制图形,绘制文本,模糊),但如果有其他方法可以在屏幕外渲染,那么它没关系……

那么如何设置我的应用程序进行屏幕外渲染?

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

但是,您不应该抢先为DIB DC创建渲染上下文.为什么?因为它会很慢,因为在DIB部分上的OpenGL渲染上下文将使用仅支持cpu上运行的OpenGL-1.1的软件光栅化器.

相反,您应该创建一个Framebuffer对象,附加一个颜色渲染缓冲附件,并在完成glReadPixels时进入您的DIBSection.更容易,更快.

由于评论请求而更新

(我不知道为什么StackOverflow没有正确的语法着色,即找出评论的位置和不在哪里)

// flushes the OpenGL error queue and
// counts the @R_334_10586@l 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 – 直接渲染到位图全部内容,希望文章能够帮你解决windows – OpenGL – 直接渲染到位图所遇到的程序开发问题。

如果觉得大佬教程网站内容还不错,欢迎将大佬教程推荐给程序员好友。

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。