c++ - 如何在 C++ builder 中渲染 openGL 帧?

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

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

最佳答案

简单,只需使用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. 将此添加到表单类 header 作为其用户定义的成员

        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 时,请查看:

玩得开心...

关于c++ - 如何在 C++ builder 中渲染 openGL 帧?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19941859/

相关文章:

Python pygame 检测鼠标是否位于表面的非透明部分上

c++ - 在 C++ 函数调用中使用自增运算符是否合法?

c++ - XCode 6.1 - 缺少项目模板(C++ 库和 C++ STL 库)

Php Form 不会将 mysql_query 发送到数据库

c++ - 使用多个 QGLWidgets (QT) 来显示(相同的)3D 纹理?

c++ - 球体旋转 OpenGL

C++宏函数或动态成员名

c++ - 在 C++/OpenGL 中加载 tga/bmp 文件

javascript - 使用 php 检索与父输入相关的子输入

javascript - 使用 Javascript 检查输入表单中的字符和字符顺序,以显示与字符和字符顺序匹配的图像