如何在C ++ builder中渲染一个openGL框架? [英] How to render an openGL frame in C++ builder?

查看:197
本文介绍了如何在C ++ builder中渲染一个openGL框架?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想在C ++ builder中初始化一个窗体中的openGL框架。我试图复制此给定的openGL启动代码的内容: http://edn.embarcadero.com/article / 10528

我尝试用TFrame1替换TForm1,然后把它放在表单设计,但它没有工作。如何正确地做这件事,任何经验与此?

解决方案

很容易,只是使用TForm :: Handle作为窗口句柄...



这里有一些我在BCB5移植到BDS2006的古代例子:

  // ------------------------------------------- ---------------------------- 

#include< vcl.h>
#pragma hdrstop

#includeUnit1.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); //获取设备上下文
PIXELFORMATDESCRIPTOR pfd;
ZeroMemory(& pfd,sizeof(pfd)); //设置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); //创建当前渲染上下文
if(hrc == NULL)
{
ShowMessage(无法初始化OpenGL渲染上下文!!!
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); //释放当前渲染上下文
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; //防止除以零
if(ys< = 0)ys = 1;
if(!ogl_inicialized)return;
glViewport(0,0,xs,ys); //将视口设置为窗口尺寸
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; //设备上下文
    HGLRC hrc; // rendering context
    int ogl_inicialized;
    int ogl_init();
    void ogl_exit();
    void ogl_draw();
    void ogl_resize();


  3. 添加计时器〜20-40 ms

    b
  4. 编译并运行



注释




  • 不需要所有OpenGL

  • OpenGL也可以只是窗口的一部分,而不仅仅是整个窗口

  • 可以与VCL组件(使用面板的按钮等,并将大小调整OpenGL到外面的区域)

  • 如果你不能让它工作评论我,但我不看到任何难以做到的事情...
  • 工作,那么您应该在窗体中心看到绿色四边形
  • 鼠标滚轮向前/向后移动相机(缩放)



有乐趣...


I want to initialize an openGL frame inside a form in C++ builder. I tried copying the contents of this given openGL startup code provided here: http://edn.embarcadero.com/article/10528
I tried replacing TForm1 with TFrame1 and then put it in the form design, but it didn't work. How to do this properly, any experience with this?

解决方案

easy, just use TForm::Handle as window handle ...

Here some ancient example of mine in BCB5 ported to 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. create empty 1-Form project

  2. add this to form class header as its user defined members

        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. add timer ~ 20-40 ms

  4. create events and copy bodies for resize,repaint,ontimer,... to match above source code
  5. compile and run

Notes

  • it is not required that all OpenGL stuff is member of form class
  • timer can have any interval
  • OpenGL can be also just a part of a window not only the whole thing
  • can combine with VCL components (use panels for buttons etc and resize OpenGL to area outside)
  • If you cannot get it to work comment me, but i do not see anything difficult to do ...
  • Do not forget to include gl.h !!!
  • if all work then you should see green quad in the center of form
  • mouse wheel moves camera forward/backward ('zoom')

Have fun ...

这篇关于如何在C ++ builder中渲染一个openGL框架?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆