㊣ 大家一起来 ——>> OpenGL之入门系列.1 (100分)

  • 主题发起人 主题发起人 YB_unique
  • 开始时间 开始时间
Y

YB_unique

Unregistered / Unconfirmed
GUEST, unregistred user!
OpenGL编程是很灵活的,因为其仅仅是一套底层API。
它和DirectX有什么异同呢?相信这些是很多朋友都关心的,在接下来的系列专题中大家将会看到。
我将尽力对两者对比,如同一效果用DirectX和OpenGL两种方法实现。希望对大家有更好的感性帮助!

既然要着手编程,那我们就先来认识一下一个OpenGL应用程序所应该具备的基本结构:
1.通过GDI系统中图形设备上下文获取一个DC(Device Context)。
2.设置DC的象素格式(PixelFormat)。
3.通过对DC的调用建立一个着色环境RC(OpenGL Render Context)。
4.将建立的RC激活。
5.主过程处理代码。
6.结束时删除DC。
玩花样主要就在第5步,其余几步在基础编程里可以作为标准模板来做。
好了!空口无凭,大家先来看一个简单实例,


unit DEMO;

interface

uses
OpenGL, Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
StdCtrls, ExtCtrls, ComCtrls;

type
TForm1 = class(TForm)
procedure FormCreate(Sender: TObject);
procedure FormPaint(Sender: TObject);
private
procedure Draw;
public
end;

var
Form1: TForm1; //这以上都没什么好说的,除了加个OpenGL单元

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; // 支持 double buffer
iPixelType:PFD_TYPE_RGBA; // 颜色类型 RGB+Alpha
cColorBits:24; // 色深
cRedBits:0; cRedShift:0; // color bits
cGreenBits:0; cGreenShift:0;
cBlueBits:0; cBlueShift:0;
cAlphaBits:0; cAlphaShift:0; // 不使用 alpha buffer
cAccumBits: 0; // 不使用 accumulation buffer
cAccumRedBits: 0;
cAccumGreenBits: 0;
cAccumBlueBits: 0;
cAccumAlphaBits: 0;
cDepthBits:16; // depth buffer
cStencilBits:0;
cAuxBuffers:0;
iLayerType:PFD_MAIN_PLANE;
bReserved: 0;
dwLayerMask: 0;
dwVisibleMask: 0;
dwDamageMask: 0; // 具体含义大家可以参考 MSDN!太多了!我翻译怕不准!^_^
);
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
glMatrixMode(GL_PROJECTION); //设置物体对象
glFrustum(-0.1, 0.1, -0.1, 0.1, 0.3, 25.0); //设置左右下上进远距离
glMatrixMode(GL_MODELVIEW); //设置观察者
glEnable(GL_DEPTH_TEST); //使用 depth buffer
end;

procedure TForm1.FormCreate(Sender: TObject);
var DC:HDC;
RC:HGLRC;
i:integer;
begin
DC:=GetDC(Handle); //获取一个DC
SetupPixelFormat(DC); //设置DC的象素格式
RC:=wglCreateContext(DC); //建立一个着色环境RC
wglMakeCurrent(DC, RC); //将建立的RC激活
GLInit; //初始化OpenGL
end;

procedure TForm1.Draw;
const S=1.0; D=5.0;
begin
glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT); //清空Buffer
glLoadIdentity; //坐标系矩阵固定
glTranslatef(0.0, 0.0, -12.0); //坐标轴上平移单位
glBegin(GL_TRIANGLES); //定义顶点开始,其参数指定为三角形
glVertex3f( -S, 0, D); //顶点1 补充一下,如果加上glColor3f()过程还可以变换颜色喔
glVertex3f(S, 0, D); //顶点2
glVertex3f(0, S, D); //顶点3
glEnd; //定义结束
SwapBuffers(wglGetCurrentDC); //输出到当前DC上
end;

procedure TForm1.FormPaint(Sender: TObject);
begin
Draw;
end;

end.

怎么样?是不是有些感觉了!呵呵!上机调试一下吧!
有人会说怎么没看到程序结束的过程代码?来来来!自己动手,丰衣足食。
我们只要加上一个Form的Destroy过程即可!
其主要代码如下:
wglMakeCurrent(0,0); //取消当前RC和当前DC
wglDeleteContext(RC);    //删除RC
ReleaseDC(Handle, DC);    //释放DC

以后我们将更深入的走进去,看看OpenGL的圣殿里还有哪些更加神秘的东东!^_^
 
我昏....
opengl12.pas里创立一个rc更简单,CreateRenderingContext(Canvas.Handle, [opDoubleBuffered], 32, 0, 0, 0, 0);
这样一个函数就搞定了.....
还有一个问题,如何画一个环形面呢?
最后请您给大家补一下实体造型这门课,最好有CSG以及Brep的实例,相对于图形学来说,opengl算是简单的了......
 
全系列收藏
 
看了半天,总算……………………还是没看懂。照着编译运行后,什么也没看到!
 
多人接受答案了。
 
后退
顶部