如何在C ++ builder中渲染一个openGL框架? [英] How to render an openGL frame in C++ builder?
问题描述
我想在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-Form专案
- 这将形成类标题作为其用户定义的成员
int xs,ys;
HDC hdc; //设备上下文
HGLRC hrc; // rendering context
int ogl_inicialized;
int ogl_init();
void ogl_exit();
void ogl_draw();
void ogl_resize();
-
添加计时器〜20-40 ms
b - 编译并运行
。
注释
- 不需要所有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();
}
//---------------------------------------------------------------------------
create empty 1-Form project
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();
add timer ~ 20-40 ms
- create events and copy bodies for resize,repaint,ontimer,... to match above source code
- 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屋!