因为疫情隔离有一周了,最近重庆疫情很严重,被f公司7天了,继续之前没学完的DLGOPENGL学习,其实就没有怎么开始。
unit Unit1;
interface
uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.ExtCtrls;
const
//定义视角的原端与近端
NearClipping = 1;
FarClipping = 1000;
type
TForm1 = class(TForm)
Timer1: TTimer;
procedure FormCreate(Sender: TObject);
procedure FormDestroy(Sender: TObject);
procedure FormResize(Sender: TObject);
procedure IdleHandler(Sender: TObject; var Done: Boolean);
procedure Timer1Timer(Sender: TObject);
private
{ Private declarations }
StartTime, DrawTime: Cardinal;
TimeCount, FrameCount: Cardinal;
Frames: Cardinal;
procedure Render;
procedure ErrorHandler;
procedure SetupGL;
public
{ Public declarations }
DC: HDC;
RC: HGLRC;
procedure Display(Sender: TObject; var Done: Boolean);
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
uses dglOpenGL;
procedure TForm1.Display(Sender: TObject; var Done: Boolean);
begin
//这个过程没有调用,这是另一个例子的Idle过程。
// 写成这个样子, 是因为我们要把这个
// Display 设为 Application.OnIdle 事件.
// 这个事件在程序空闲时重复执行,
// 直到收到消息(用户操作, 定时器事件)或 Done
// 变量被设置为 True. 利用这个方法可以模拟很多游戏教程中的”主循环”.
glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT); // 清屏
SwapBuffers(DC); // 应用更改
Done := False;
end;
procedure TForm1.ErrorHandler;
begin
Form1.Caption := gluErrorString(glGetError);
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
DC := GetDC(Handle); // 获得 DC
if not InitOpenGL() then
raise Exception.Create(‘初始化 OpenGL 失败!’);
RC := CreateRenderingContext(DC, [opDoubleBuffered], // 双缓冲
32, // 32位色
24, // 深度缓存,用于遮挡判断
0, // 模版缓冲区位数
0, // 累计缓冲区位数
0, // 辅助缓冲区位数
0); // Layer type,在windowsnt下只能用0
ActivateRenderingContext(DC, RC); // 绑定 DC, RC
SetupGL;//给定一个基本的颜色
Application.OnIdle := IdleHandler;
end;
procedure TForm1.FormDestroy(Sender: TObject);
begin
DeactivateRenderingContext; // 解绑 DC, RC
wglDeleteContext(RC); // 释放 RC
ReleaseDC(Handle, DC); // 释放 DC
end;
procedure TForm1.FormResize(Sender: TObject);
var
tmpBool: Boolean;
begin
glViewport(0, 0, ClientWidth, ClientHeight); // 设置视窗,前两个0表示没有偏移.
glMatrixMode(GL_PROJECTION); // 更改投影矩阵
glLoadIdentity; // 设置当前矩阵为单位阵,矩阵设置为单位阵
gluPerspective(45.0, ClientWidth / ClientHeight, NearClipping, FarClipping); // 设置场景大小
// 45为视角,长宽比,最近处为1,最远处为1000,
glMatrixMode(GL_MODELVIEW); // 更改模型视图矩阵
glLoadIdentity; // 设置当前矩阵为单位阵
IdleHandler(Sender, tmpBool);
end;
procedure TForm1.IdleHandler(Sender: TObject; var Done: Boolean);
begin
StartTime := GetTickCount;//获得开始时间
Render;//渲染
DrawTime := GetTickCount – StartTime;//获得渲染耗时
Inc(TimeCount, DrawTime);//
Inc(FrameCount);
if TimeCount >= 1000 then
begin
Frames := FrameCount;
TimeCount := TimeCount – 1000;
FrameCount := 0;
Caption := InttoStr(Frames) + ‘FPS’;
ErrorHandler;
end;
sleep(5);
Done := False;
end;
procedure TForm1.Render;
begin
glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_PROJECTION);
glLoadIdentity;
gluPerspective(45.0, ClientWidth / ClientHeight, NearClipping, FarClipping);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity;
glTranslatef(0, 0, -5);
glBegin(GL_QUADS);
glColor3f(1, 0, 0);
glVertex3f(0, 0, 0);
glColor3f(0, 1, 0);
glVertex3f(1, 0, 0);
glColor3f(0, 0, 1);
glVertex3f(1, 1, 0);
glColor3f(1, 1, 0);
glVertex3f(0, 1, 0);
glEnd;
SwapBuffers(DC);//没有这一步没有图像,可以理解为前面的内容属于背后的小操作,这一步让这些小操作显示出来。
end;
procedure TForm1.SetupGL;
begin
glClearColor(0.3, 0.4, 0.7, 0.0);
glEnable(GL_DEPTH_TEST);
glEnable(GL_CULL_FACE);
end;
procedure TForm1.Timer1Timer(Sender: TObject);
begin
Inc(FrameCount);
Render;
If FrameCount = 20 then
begin
ErrorHandler;
FrameCount := 0;
end;
end;
end.
转摘内容:
https://zhuanlan.zhihu.com/p/30350510
这部分内容相当于简单走了一边流程:
1,OPENGL初始化和释放,
2,Idle渲染,普通渲染
原文地址:http://www.cnblogs.com/Lidashi/p/16908757.html