今天看到一篇delphi的openGL的入门的相关文章,上面有代码如下,本人初学delphi,不是很了解其相关函数的用法,还望各位大侠能够给出尽量详细的解释!!看懂就结帖!!谢谢!!
unit Tri;interfaceuses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs,openGL, ExtCtrls;type
TForm1 = class(TForm)
procedure FormCreate(Sender: TObject);
procedure FormPaint(Sender: TObject);
private
{ Private declarations }
procedure Draw; //Draws an OpenGL scene on request
public
{ Public declarations }
end;var
Form1: TForm1;
implementation{$R *.dfm}
procedure setupPixelFormat(DC:HDC);
const
pfd:TPIXELFORMATDESCRIPTOR = (
nSize:sizeof(TPIXELFORMATDESCRIPTOR);
nVersion:1;
dwFlags:PFD_SUPPORT_OPENGL or PFD_DRAW_TO_WINDOW or
PFD_DOUBLEBUFFER;
iPixelType:PFD_TYPE_RGBA;
cColorBits:24;
cRedBits:0; cRedShift:0;
cGreenBits:0; cGreenShift:0;
cBlueBits:0; cBlueShift:0;
cAlphaBits:0; cAlphaShift:0;
cAccumBits: 0;
cAccumRedBits: 0;
cAccumGreenBits: 0;
cAccumBlueBits: 0;
cAccumAlphaBits: 0;
cDepthBits:16;
cStencilBits:0;
cAuxBuffers:0;
iLayerType:PFD_MAIN_PLANE;
bReserved: 0;
dwLayerMask: 0;
dwVisibleMask: 0;
dwDamageMask: 0;
);
var pixelFormat:integer;
begin
pixelFormat := ChoosePixelFormat(DC, @pfd);
if (pixelFormat = 0) then
exit;
if (SetPixelFormat(DC, pixelFormat, @pfd) <> TRUE) then
exit;
end;procedure GLInit;
begin
// set viewing projection
glMatrixMode(GL_PROJECTION);
glFrustum(-0.1, 0.1, -0.1, 0.1, 0.3, 25.0);
// position viewer
glMatrixMode(GL_MODELVIEW);
glEnable(GL_DEPTH_TEST);
end;procedure TForm1.FormCreate(Sender: TObject);
var DC:HDC;
RC:HGLRC;
begin
DC:=GetDC(Handle);
SetupPixelFormat(DC);
RC:=wglCreateContext(DC);
wglMakeCurrent(DC, RC);
GLInit;
end;procedure TForm1.Draw;
const S=1.0; D=5.0;
begin
glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT);
glLoadIdentity;
glTranslatef(0.0, 0.0, -12.0);
glBegin(GL_TRIANGLES);
glVertex3f( -S, 0, D); glVertex3f(S, 0, D); glVertex3f(0, S, D);
glEnd;
SwapBuffers(wglGetCurrentDC);
end;procedure TForm1.FormPaint(Sender: TObject);
begin
Draw;
end;end.
unit Tri;interfaceuses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs,openGL, ExtCtrls;type
TForm1 = class(TForm)
procedure FormCreate(Sender: TObject);
procedure FormPaint(Sender: TObject);
private
{ Private declarations }
procedure Draw; //Draws an OpenGL scene on request
public
{ Public declarations }
end;var
Form1: TForm1;
implementation{$R *.dfm}
procedure setupPixelFormat(DC:HDC);
const
pfd:TPIXELFORMATDESCRIPTOR = (
nSize:sizeof(TPIXELFORMATDESCRIPTOR);
nVersion:1;
dwFlags:PFD_SUPPORT_OPENGL or PFD_DRAW_TO_WINDOW or
PFD_DOUBLEBUFFER;
iPixelType:PFD_TYPE_RGBA;
cColorBits:24;
cRedBits:0; cRedShift:0;
cGreenBits:0; cGreenShift:0;
cBlueBits:0; cBlueShift:0;
cAlphaBits:0; cAlphaShift:0;
cAccumBits: 0;
cAccumRedBits: 0;
cAccumGreenBits: 0;
cAccumBlueBits: 0;
cAccumAlphaBits: 0;
cDepthBits:16;
cStencilBits:0;
cAuxBuffers:0;
iLayerType:PFD_MAIN_PLANE;
bReserved: 0;
dwLayerMask: 0;
dwVisibleMask: 0;
dwDamageMask: 0;
);
var pixelFormat:integer;
begin
pixelFormat := ChoosePixelFormat(DC, @pfd);
if (pixelFormat = 0) then
exit;
if (SetPixelFormat(DC, pixelFormat, @pfd) <> TRUE) then
exit;
end;procedure GLInit;
begin
// set viewing projection
glMatrixMode(GL_PROJECTION);
glFrustum(-0.1, 0.1, -0.1, 0.1, 0.3, 25.0);
// position viewer
glMatrixMode(GL_MODELVIEW);
glEnable(GL_DEPTH_TEST);
end;procedure TForm1.FormCreate(Sender: TObject);
var DC:HDC;
RC:HGLRC;
begin
DC:=GetDC(Handle);
SetupPixelFormat(DC);
RC:=wglCreateContext(DC);
wglMakeCurrent(DC, RC);
GLInit;
end;procedure TForm1.Draw;
const S=1.0; D=5.0;
begin
glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT);
glLoadIdentity;
glTranslatef(0.0, 0.0, -12.0);
glBegin(GL_TRIANGLES);
glVertex3f( -S, 0, D); glVertex3f(S, 0, D); glVertex3f(0, S, D);
glEnd;
SwapBuffers(wglGetCurrentDC);
end;procedure TForm1.FormPaint(Sender: TObject);
begin
Draw;
end;end.
解决方案 »
- 用delphi语句写出条形码打印程序
- DELPHI 控件属性用变量替换
- 程序中使用了TFrame作为子窗口,想在主窗口尺寸改变时TFrame能随主窗口而改变尺寸...在线等...
- 请菜鸟迅子回答
- 如何动态添加字段?
- 100分的问题,然道真的就没有人能解答吗? 如果分不够我再加!进来有分!
- 高手请进来,帮帮忙!dbgrideg的打印问题——打印预览是数据网格全部挤在了一起!
- QucikReport打印问题及Table的edit状态问题
- 呵呵,问个和编程无关的问题,100分也(关于最终幻想的MTV)
- 大家帮忙该delphi的错
- 如何解决"Statement expected but 'FUNCTION'错误
- 救命啊,急!dbgrid,dbedit怎麼只能顯示4位小數啊?
const
pfd:TPIXELFORMATDESCRIPTOR = (
nSize:sizeof(TPIXELFORMATDESCRIPTOR); // 确定象素格式描述结构的大小
nVersion:1; // 版本号
dwFlags:PFD_SUPPORT_OPENGL{缓冲格式需要支持OGL} or PFD_DRAW_TO_WINDOW{缓冲格式需要支持窗口模式} or
PFD_DOUBLEBUFFER{需要双缓冲支持};
iPixelType:PFD_TYPE_RGBA;// 申请 RGBA 格式
cColorBits:24;// 选定 OGL 色彩深度24
cRedBits:0{红色彩位}; cRedShift:0{忽略红色彩位};
cGreenBits:0{同上绿}; cGreenShift:0{通上绿};
cBlueBits:0{同上蓝}; cBlueShift:0{同上蓝};
cAlphaBits:0{同上通道}; cAlphaShift:0{同上通道};
cAccumBits: 0;//无积聚缓存
cAccumRedBits: 0; //忽略红积聚缓存
cAccumGreenBits: 0; //同上绿
cAccumBlueBits: 0;//同上蓝
cAccumAlphaBits: 0;//同上通道
cDepthBits:16;//深度缓存16位
cStencilBits:0;//无模板缓存
cAuxBuffers:0; //无辅助缓存
iLayerType:PFD_MAIN_PLANE;//主绘图层
bReserved: 0;// 保留
dwLayerMask: 0;// 忽略遮罩层
dwVisibleMask: 0;// 忽略透明色
dwDamageMask: 0; // 忽略 Damage 遮罩层
);
var pixelFormat:integer;
begin
pixelFormat := ChoosePixelFormat(DC, @pfd);// 找到系统相应的象素格式
if (pixelFormat = 0) then//没找到相配的象素格式
exit;
if (SetPixelFormat(DC, pixelFormat, @pfd) <> TRUE) then// 设置象素格式
exit;
end;procedure GLInit;
begin
// set viewing projection
glMatrixMode(GL_PROJECTION); // 选择投影矩阵
glFrustum(-0.1, 0.1, -0.1, 0.1, 0.3, 25.0); //定义透视投影体(left,right,bottom,top,near,far)
// position viewer
glMatrixMode(GL_MODELVIEW); // 选择模型观察矩阵
glEnable(GL_DEPTH_TEST);// 启用深度测试
end;procedure TForm1.FormCreate(Sender: TObject);
var DC:HDC; // 设备描述表
RC:HGLRC; // 着色描述表
begin
DC:=GetDC(Handle);// 试着取得 DC(if DC = 0 不能取得 Device Context )
SetupPixelFormat(DC);//设置 OpenGL 的格式
RC:=wglCreateContext(DC);// 取得着色描述表 RC=0 Error
wglMakeCurrent(DC, RC); //激活着色描述表
GLInit;//初始化
end;
const S=1.0; D=5.0;
begin
glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT);// 清除屏幕和深度缓存
glLoadIdentity; // 重置投影矩阵
glTranslatef(0.0, 0.0, -12.0);//移动屏幕(相对)
glBegin(GL_TRIANGLES);//开始绘制三角形
glVertex3f( -S, 0, D); glVertex3f(S, 0, D); glVertex3f(0, S, D); {绘制过程}
glEnd;//结束绘制
SwapBuffers(wglGetCurrentDC);// 将画面显示出来(交换缓存)
end;
const
pfd:TPIXELFORMATDESCRIPTOR = ( //象素格式描述符类
nSize:sizeof(TPIXELFORMATDESCRIPTOR); // // 确定象素格式描述结构的大小
nVersion:1; // version 版本信息
dwFlags:PFD_SUPPORT_OPENGL or PFD_DRAW_TO_WINDOW or //缓冲格式需要支持openGL或缓冲格式需要支持窗口模式或
PFD_DOUBLEBUFFER; // 缓冲格式需要支持双缓冲
iPixelType:PFD_TYPE_RGBA; // color type颜色模式类型(RGBA)
cColorBits:24; // preferred color depth 指定颜色深度24位
cRedBits:0{红色彩位}; cRedShift:0;{忽略红色彩位}; // color bits (ignored)颜色位数(忽略)
cGreenBits:0{绿色彩位}; cGreenShift:0{忽略绿色彩位};
cBlueBits:0{蓝色彩位}; cBlueShift:0{忽略蓝色彩位};
cAlphaBits:0{通道位}; cAlphaShift:0{忽略通道位}; // no alpha buffer 无alpha缓存
cAccumBits: 0;//无积聚缓存
cAccumRedBits: 0; // no accumulation buffer,忽略红积聚缓存
cAccumGreenBits: 0; // accum bits (ignored) 忽略绿积聚缓存
cAccumBlueBits: 0; //忽略蓝积聚缓存
cAccumAlphaBits: 0; //忽略通道积聚缓存
cDepthBits:16; // depth buffer 深度缓存:16位
cStencilBits:0; // no stencil buffer 无模板缓存
cAuxBuffers:0; // no auxiliary buffers 无辅助缓存
iLayerType:PFD_MAIN_PLANE; // main layer 主绘图层
bReserved: 0; // 保留
dwLayerMask: 0; // 忽略遮罩层
dwVisibleMask: 0;// 忽略透明色
dwDamageMask: 0;//忽略 Damage 遮罩层
);
var pixelFormat:integer;
begin
pixelFormat := ChoosePixelFormat(DC, @pfd); //找到系统相应的象素格式
{该函数比较传过来的像素格式描述和OpenGL支持的像素格式,返回一个最佳匹配的像素格式索引。该索引值
可传给SetPixelFormat为DC设置像素格式。返回值为0表示失败。}
if (pixelFormat = 0) then
exit;
if (SetPixelFormat(DC, pixelFormat, @pfd) <> TRUE) then //设置象素格式
{该函数用格式索引iPixelFormat来设置hdc的像素格式。在使用该函数之前应该调用ChoosePixelFormat来获取
像素格式索引。另外,OpenGL窗口风格必须包含WS_CLIPCHILDREN和WS_CLIPSIBLINGS类型,否则设置失败。应该
注意的是ChoosePixelFormat函数并不一定返回一个最佳的像素格式值,可以利用DescribePixelFormat来枚举系
统所支持的所有像素格式。OpenGL的通常支持24种不同的像素格式,如果系统安装了OpenGL硬件加速器,它可能
会支持其它的像素格式。}
exit;
end;procedure GLInit; //openGL初始化
begin
// set viewing projection
glMatrixMode(GL_PROJECTION); //选择投影矩阵(切换到投影矩阵栈)(投影变换的类型决定观察三维模型的观察方式)
glFrustum(-0.1, 0.1, -0.1, 0.1, 0.3, 25.0); //定义透视投影体;物体在这六个参数界定的范围内可见,超出边界将被裁掉。(设置矩阵 垂直面左面右面位置:-0.1,0.1;水平面顶面和底面位置:-0.1,0.1,近面和远面位置:0.3,25)
// position viewer
glMatrixMode(GL_MODELVIEW); //选择模型观察矩阵(切换到模型视见矩阵栈)(视窗变换则对模型的景象进行裁剪缩放,即决定整个三维模型在屏幕上的图象)
glEnable(GL_DEPTH_TEST);// 启用深度测试;GL_DEPTH_TEST参数表示进行深度探测校对,从而进行自动的深度缓冲大小设置
end;procedure TForm1.FormCreate(Sender: TObject);
var DC:HDC; //用于创建设备描述表(Device Context)
RC:HGLRC; //用于创建着色描述表(Rendering Context)
//i:integer;
begin
// ①创建设备描述表(Device Context) (if DC = 0 不能取得 Device Context )
DC:=GetDC(Handle); //Actually, you can use any windowed control here 你可以用窗体上任意control的句柄
{Delphi中有好几种获得或创建设备描述表的方法。最简单的就是直接获得画布对象(TCanvas)的句柄属性(Handle),如:
DC:=Canvas.Handle;
也可以用API函数GetDC获得设备描述表。如:
DC:=GetDC(Handle,DC);
}
//②设置相应的象素格式( PIXELFORMAT DESCRIPTOR)
SetupPixelFormat(DC);
//③创建着色描述表(Rendering Context)(RC=0 Error)
RC:=wglCreateContext(DC); //makes OpenGL window out of DC wglMakeCurrent(DC, RC); //makes OpenGL window active 激活openGL窗口(激活着色描述表)
{该函数把hdc和hglrc关联起来,并使hglrc成为调用线程的现行RC。如果传给hglrc的值为NULL,则函数解除关联,
并置线程的现行RC为非现行RC,此时忽略hdc参数。传给该函数的hdc可以不是调用wglCreateContext时使用的值,
但是,它们所关联的设备必须相同并且拥有相同的像素格式。注意,如果hglrc是另一个线程的现行RC,则调用失败。
}
GLInit; //initialize OpenGL 初始化openGL
end;procedure TForm1.Draw;
const S=1.0; D=5.0;
begin
glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT);//清除屏幕和深度缓存 glLoadIdentity; //重置当前的模型观察矩阵 {当您调用glLoadIdentity()之后,您实际上将当前点移到了屏幕中心,X坐标轴从左至右,
Y坐标轴从下至上,Z坐标轴从里至外。OpenGL屏幕中心的坐标值是X和Y轴上的0.0点。中心
左面的坐标值是负值,右面是正值。移向屏幕顶端是正值,移向屏幕底端是负值。移入屏幕
深处是负值,移出屏幕则是正值。} glTranslatef(0.0, 0.0, -12.0); {glTranslatef(x, y, z)沿着 X, Y 和 Z 轴移动。根据前面的次序,下面的代码沿着X轴不动(0.0),
Y轴不动(0.0),最后移入屏幕12.0个单位。注意在glTranslatef(x, y, z)中当您移动的时候,您并
不是相对屏幕中心移动,而是相对与当前所在的屏幕位置。
//现在我们已经将视图推入屏幕背后足够的距离以便我们可以看见全部的场景} glBegin(GL_TRIANGLES);//开始绘制三角形 {glBegin(GL_TRIANGLES)的意思是开始绘制三角形,glEnd() 告诉OpenGL三角形已经创建好了。通常
您会需要画3个顶点,可以使用GL_TRIANGLES。在绝大多数的显卡上,绘制三角形是相当快速的。如果
要画四个顶点,使用GL_QUADS的话会更方便。但据我所知,绝大多数的显卡都使用三角形来为对象着色。
最后,如果您想要画更多的顶点时,可以使用GL_POLYGON。 这里的简单示例中,我们只画一个三角形。如果要画第二个三角形的话,可以在这三点之后,再加三行
代码(3点)。所有六点代码都应包含在glBegin(GL_TRIANGLES)和glEnd()之间。在他们之间再不会有多余
的点出现,也就是说,(GL_TRIANGLES)和glEnd()之间的点都是以三点为一个集合的。这同样适用于四边
形。如果您知道实在绘制四边形的话,您必须在第一个四点之后,再加上四点为一个集合的点组。另一方
面,多边形可以由任意个顶点,(GL_POLYGON)不在乎glBegin(GL_TRIANGLES)和glEnd()之间有多少行代码。} glVertex3f( -S, 0, D); glVertex3f(S, 0, D); glVertex3f(0, S, D); //一个三角形的三个顶点 glEnd; SwapBuffers(wglGetCurrentDC);//完成两个图形缓冲区的交换,把画完的非显示缓冲图形显示出来。 {双缓冲技术:OpenGL支持一个显示缓冲和一个非显示缓冲。缺省的情况是所有的OpenGL绘制命令在非显示
缓冲中绘制,绘制完成后再将其内容拷贝到显示缓冲区中(使用SwapBuffers函数)。双缓冲使图象转换更平滑,
这就是在快速动画(如波形等的实时输出)时没有屏幕闪烁的奥妙所在。}
end;procedure TForm1.FormPaint(Sender: TObject);
begin
Draw; //执行draw过程
end;