【问题标题】:How to render an openGL frame in C++ builder?如何在 C++ builder 中渲染 openGL 框架?
【发布时间】:2013-11-25 08:24:49
【问题描述】:

我想在 C++ builder 的表单中初始化一个 openGL 框架。我尝试复制此处提供的给定 openGL 启动代码的内容:http://edn.embarcadero.com/article/10528
我尝试用TFrame1替换TForm1,然后放到表单设计中,但是没有用。如何正确地做到这一点,有这方面的经验吗?

【问题讨论】:

    标签: c++ forms opengl frame c++builder


    【解决方案1】:

    简单,只需使用TForm::Handle 作为窗口句柄...

    这是我在 BCB5 中移植到 BDS2006 的一些古老示例:

    //---------------------------------------------------------------------------
    
    #include <vcl.h>
    #pragma hdrstop
    
    #include "Unit1.h"
    #include <gl/gl.h>
    #include <gl/glu.h>
    //---------------------------------------------------------------------------
    #pragma package(smart_init)
    #pragma resource "*.dfm"
    TForm1 *Form1;
    //---------------------------------------------------------------------------
    int TForm1::ogl_init()
        {
        if (ogl_inicialized) return 1;
        hdc = GetDC(Form1->Handle);             // get device context
        PIXELFORMATDESCRIPTOR pfd;
        ZeroMemory( &pfd, sizeof( pfd ) );      // set the pixel format for the DC
        pfd.nSize = sizeof( pfd );
        pfd.nVersion = 1;
        pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER;
        pfd.iPixelType = PFD_TYPE_RGBA;
        pfd.cColorBits = 24;
        pfd.cDepthBits = 24;
        pfd.iLayerType = PFD_MAIN_PLANE;
        SetPixelFormat(hdc,ChoosePixelFormat(hdc, &pfd),&pfd);
        hrc = wglCreateContext(hdc);            // create current rendering context
        if(hrc == NULL)
                {
                ShowMessage("Could not initialize OpenGL Rendering context !!!");
                ogl_inicialized=0;
                return 0;
                }
        if(wglMakeCurrent(hdc, hrc) == false)
                {
                ShowMessage("Could not make current OpenGL Rendering context !!!");
                wglDeleteContext(hrc);          // destroy rendering context
                ogl_inicialized=0;
                return 0;
                }
        ogl_resize();
        glEnable(GL_DEPTH_TEST);                // Zbuf
        glDisable(GL_CULL_FACE);                // vynechavaj odvratene steny
        glDisable(GL_TEXTURE_2D);               // pouzivaj textury, farbu pouzivaj z textury
        glDisable(GL_BLEND);                    // priehladnost
        glShadeModel(GL_SMOOTH);                // gourard shading
        glClearColor(0.0f, 0.0f, 0.0f, 1.0f);   // background color
        ogl_inicialized=1;
        return 1;
        }
    //---------------------------------------------------------------------------
    void TForm1::ogl_exit()
        {
        if (!ogl_inicialized) return;
        wglMakeCurrent(NULL, NULL);     // release current rendering context
        wglDeleteContext(hrc);          // destroy rendering context
        ogl_inicialized=0;
        }
    //---------------------------------------------------------------------------
    void TForm1::ogl_draw()
        {
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    
        float x=0.5,y=0.5,z=20.0;
        glBegin(GL_QUADS);
    
        glColor3f(0.0f, 1.0f, 0.0f);
        glVertex3f(-x,-y,-z);
        glVertex3f(-x,+y,-z);
        glVertex3f(+x,+y,-z);
        glVertex3f(+x,-y,-z);
        glColor3f(0.0f, 0.0f, 1.0f);
        glVertex3f(-x,-y,+z);
        glVertex3f(-x,+y,+z);
        glVertex3f(+x,+y,+z);
        glVertex3f(+x,-y,+z);
    
        glEnd();
    
    
    
        glFlush();
        SwapBuffers(hdc);
        }
    //---------------------------------------------------------------------------
    void TForm1::ogl_resize()
        {
        xs=ClientWidth;
        ys=ClientHeight;
        if (xs<=0) xs = 1;                  // Prevent a divide by zero
        if (ys<=0) ys = 1;
        if (!ogl_inicialized) return;
        glViewport(0,0,xs,ys);              // Set Viewport to window dimensions
        glMatrixMode(GL_PROJECTION);        // operacie s projekcnou maticou
        glLoadIdentity();                   // jednotkova matica projekcie
        gluPerspective(30,float(xs)/float(ys),0.1,100.0); // matica=perspektiva,120 stupnov premieta z viewsize do 0.1
        glMatrixMode(GL_TEXTURE);           // operacie s texturovou maticou
        glLoadIdentity();                   // jednotkova matica textury
        glMatrixMode(GL_MODELVIEW);         // operacie s modelovou maticou
        glLoadIdentity();                   // jednotkova matica modelu (objektu)
        ogl_draw();
        }
    //---------------------------------------------------------------------------
    __fastcall TForm1::TForm1(TComponent* Owner)
        : TForm(Owner)
        {
        ogl_inicialized=0;
        hdc=NULL;
        hrc=NULL;
        ogl_init();
        }
    //---------------------------------------------------------------------------
    void __fastcall TForm1::FormDestroy(TObject *Sender)
        {
        ogl_exit();
        }
    //---------------------------------------------------------------------------
    void __fastcall TForm1::FormResize(TObject *Sender)
        {
        ogl_resize();
        }
    //---------------------------------------------------------------------------
    void __fastcall TForm1::FormPaint(TObject *Sender)
        {
        ogl_draw();
        }
    //---------------------------------------------------------------------------
    void __fastcall TForm1::Timer1Timer(TObject *Sender)
        {
        ogl_draw();
        }
    //---------------------------------------------------------------------------
    void __fastcall TForm1::FormMouseWheelDown(TObject *Sender, TShiftState Shift,
          TPoint &MousePos, bool &Handled)
        {
        glMatrixMode(GL_PROJECTION);
        glTranslatef(0,0,+2.0);
        ogl_draw();
        }
    //---------------------------------------------------------------------------
    void __fastcall TForm1::FormMouseWheelUp(TObject *Sender, TShiftState Shift,
          TPoint &MousePos, bool &Handled)
        {
        glMatrixMode(GL_PROJECTION);
        glTranslatef(0,0,-2.0);
        ogl_draw();
        }
    //---------------------------------------------------------------------------
    
    1. 创建空的 1-Form 项目

    2. 将此添加到表单类头作为其用户定义的成员

          int     xs,ys;
          HDC     hdc;            // device context
          HGLRC   hrc;            // rendering context
          int  ogl_inicialized;
          int  ogl_init();
          void ogl_exit();
          void ogl_draw();
          void ogl_resize();
      
    3. 添加计时器 ~ 20-40 毫秒

    4. 创建事件并复制主体以调整大小、重绘、准时...以匹配上述源代码
    5. 编译运行

    备注

    • 并不要求所有 OpenGL 东西都是表单类的成员
    • 定时器可以有任意间隔
    • OpenGL 也可以只是窗口的一部分,而不仅仅是整个窗口
    • 可以与 VCL 组件结合(使用面板作为按钮等并将 OpenGL 调整到外部区域)
    • 如果你不能让它工作,请给我评论,但我认为没有什么难做的......
    • 不要忘记包含gl.h !!!
    • 如果一切正常,那么您应该会在表格中心看到绿色四边形
    • 鼠标滚轮向前/向后移动相机(“缩放”)

    当您准备好超越 OpenGL 1.0 时,请查看:

    玩得开心……

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2010-09-13
      • 2010-12-01
      • 2012-02-02
      • 2014-08-20
      • 2016-04-30
      • 1970-01-01
      • 2020-02-20
      • 2023-04-11
      相关资源
      最近更新 更多