OpenGL完全教程 第一章 初始化OpenGL
第一章 初始化OpenGL
无论是什么东西,要使用它,就必须对它进行初始化。如果你之前使用过GDI,你应该也多多少少了解到GDI在绘制图形之前要为之创建渲染环境。OpenGL也一样。本章给出的代码,大家可以不必理解其中的具体意义,反正以后每次初始化是使用这个代码即可。
首先,在一个新的应用程序中,我们需要添加对OpenGL库的引用。Delphi已经为我们写好了OpenGL的头文件,因此我们只须直接在单元的uses中添加OpenGL即可:
...
uses Windows, Graphics, OpenGL, ...
...
在创建窗口时,应添加如下代码:
- procedure Form1.Create(Sender:TObject);
- var DC: HDC;
- HRC :HGLRC ;
- pfd:TPIXELFORMATDESCRIPTOR; pixelFormat:integer;
- begin
- DC := GetDC(Handle);
- With pfd do
- begin
- nSize:=sizeof(TPIXELFORMATDESCRIPTOR); // size
- nVersion:=; // version
- dwFlags:=PFD_SUPPORT_OPENGL or PFD_DRAW_to_WINDOW or
- PFD_DOUBLEBUFFER; // support double-buffering
- iPixelType:=PFD_TYPE_RGBA; // color type
- cColorBits:=; // preferred color depth
- cRedBits:=;
- cRedShift:=; // color bits (ignored)
- cGreenBits:=;
- cGreenShift:=;
- cBlueBits:=;
- cBlueShift:=;
- cAlphaBits:=;
- cAlphaShift:=; // no alpha buffer
- cAccumBits:=;
- cAccumRedBits:=; // no accumulation buffer,
- cAccumGreenBits:=; // accum bits (ignored)
- cAccumBlueBits:=;
- cAccumAlphaBits:=;
- cDepthBits:=; // depth buffer
- cStencilBits:=; // no stencil buffer
- cAuxBuffers:=; // no auxiliary buffers
- iLayerType:=PFD_MAIN_PLANE; // main layer
- bReserved:=;
- dwLayerMask:=;
- dwVisibleMask:=;
- dwDamageMask:=;
- end;
- pixelFormat := ChoosePixelFormat(DC, @pfd);
- if (pixelFormat = ) then
- exit;
- if (SetPixelFormat(DC, pixelFormat, @pfd) <> TRUE) then
- exit;
- hRc := wglCreateContext(DC);
- wglMakeCurrent(DC,HRC);
- end;
上面的代码是Windows下初始化OpenGL的固定代码。因为本教程不使用任何第三方库,所以在初始化上显得麻烦些。但这些代码是固定的,每次初始化OpenGL时,照抄代码即可。下面对上述代码作简单的说明。
首先,我们用GetDC(Handle)获取当前窗口的设备目录。然后初始化一个TPIXELFORMATDESCRIPTOR类型的字段,用于描述将要使用的像素格式。在此字段中,dwFlags表示渲染方式,一般情况下使用PFD_SUPPORT_OPENGL or PFD_DRAW_to_WINDOW or PFD_DOUBLEBUFFER。其中,PFD_DOUBLEBUFFER表示支持双缓冲。这将会在今后的章节中讲到。cColorBits表示使用的色深,一般情况下使用24位色深。在今后的教程中,会根据不同的需求而改变TPIXELFORMATDESCRIPTOR字段中的值,而其他代码一般都是不变的。
初始化完OpenGL之后,就可以调用OpenGL的绘制函数来绘制图形了。一般情况下,我们把所有绘制图形的函数调用写在一个名为RenderScene的过程中:
第一章 初始化OpenGL
无论是什么东西,要使用它,就必须对它进行初始化。如果你之前使用过GDI,你应该也多多少少了解到GDI在绘制图形之前要为之创建渲染环境。OpenGL也一样。本章给出的代码,大家可以不必理解其中的具体意义,反正以后每次初始化是使用这个代码即可。
首先,在一个新的应用程序中,我们需要添加对OpenGL库的引用。Delphi已经为我们写好了OpenGL的头文件,因此我们只须直接在单元的uses中添加OpenGL即可:
...
uses Windows, Graphics, OpenGL, ...
...
在创建窗口时,应添加如下代码:
procedure Form1.Create(Sender:TObject);
var DC: HDC;
HRC :HGLRC ;
pfd:TPIXELFORMATDESCRIPTOR; pixelFormat:integer;
begin
DC := GetDC(Handle);
With pfd do
beginnSize:=sizeof(TPIXELFORMATDESCRIPTOR); // size
nVersion:=1; // version
dwFlags:=PFD_SUPPORT_OPENGL or PFD_DRAW_to_WINDOW or
PFD_DOUBLEBUFFER; // support double-buffering
iPixelType:=PFD_TYPE_RGBA; // color type
cColorBits:=24; // preferred color depth
cRedBits:=0;
cRedShift:=0; // color bits (ignored)
cGreenBits:=0;
cGreenShift:=0;
cBlueBits:=0;
cBlueShift:=0;
cAlphaBits:=0;
cAlphaShift:=0; // no alpha buffer
cAccumBits:=0;
cAccumRedBits:=0; // no accumulation buffer,
cAccumGreenBits:=0; // accum bits (ignored)
cAccumBlueBits:=0;
cAccumAlphaBits:=0;
cDepthBits:=16; // depth buffer
cStencilBits:=0; // no stencil buffer
cAuxBuffers:=0; // no auxiliary buffers
iLayerType:=PFD_MAIN_PLANE; // main layer
bReserved:=0;
dwLayerMask:=0;
dwVisibleMask:=0;
dwDamageMask:=0;end;
pixelFormat := ChoosePixelFormat(DC, @pfd);
if (pixelFormat = 0) then
exit;
if (SetPixelFormat(DC, pixelFormat, @pfd) <> TRUE) then
exit;
hRc := wglCreateContext(DC);
wglMakeCurrent(DC,HRC);
end;
上面的代码是Windows下初始化OpenGL的固定代码。因为本教程不使用任何第三方库,所以在初始化上显得麻烦些。但这些代码是固定的,每次初始化OpenGL时,照抄代码即可。下面对上述代码作简单的说明。
首先,我们用GetDC(Handle)获取当前窗口的设备目录。然后初始化一个TPIXELFORMATDESCRIPTOR类型的字段,用于描述将要使用的像素格式。在此字段中,dwFlags表示渲染方式,一般情况下使用PFD_SUPPORT_OPENGL or PFD_DRAW_to_WINDOW or PFD_DOUBLEBUFFER。其中,PFD_DOUBLEBUFFER表示支持双缓冲。这将会在今后的章节中讲到。cColorBits表示使用的色深,一般情况下使用24位色深。在今后的教程中,会根据不同的需求而改变TPIXELFORMATDESCRIPTOR字段中的值,而其他代码一般都是不变的。
初始化完OpenGL之后,就可以调用OpenGL的绘制函数来绘制图形了。一般情况下,我们把所有绘制图形的函数调用写在一个名为RenderScene的过程中:
procedure TForm1.RenderScene;
begin
...
end;
然后,我们使用一个Timer,其Interval属性设为1,然后在OnTimer事件中调用RenderScene即可。
在窗体关闭时,我们还必须关闭渲染环境以释放内存。方法如下:
procedure TForm1.Form1Close(Sender:TObject;....);
begin
wglMakeCurrent(DC,HRC);
wglDeleteContext(hRc);
ReleaseDC(Handle,DC);
end;
其实,关于OpenGL初始化,我已经写好了一个类。用这个类初始化,可以让窗体的代码简洁一些。首先,下载glInit.pas,并引用它。然后向单元中加入如下代码初始化OpenGL。
...
uses ...,GLInit;
var
glInitor:TOpenGLInit;
implementation
procedure TForm1.Create(....);
begin
glInitor:=TOpenGLInit.Create(Handle,24,stdDoubleBuffer);
end;
procedure TForm1.Close(...);
begin
glInitor.Free;
end;
在本章的示例程序中,我们将初始化OpenGL,并用OpenGL绘制一个三角形。在此程序中,我们还对OpenGL作了其他一些设置,现在你无须理解其中的意义。此程序中,InitOpenGL过程用于初始化OpenGL,FreeOpenGL过程用于销毁OpenGL,SetView过程用于设置视图投影(将在今后的章节中讲到),在RenderScene过程中,我们使用了一个OpenGL的函数绘制了一个三角形。
以下就是本章示例程序的代码。
unit untMainForm;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, ExtCtrls, OpenGL;
type
TfrmMain = class(TForm)
tmrRender: TTimer;
procedure FormCreate(Sender: TObject);
procedure FormClose(Sender: TObject; var Action: TCloseAction);
procedure tmrRenderTimer(Sender: TObject);
private
procedure InitOpenGL;
procedure FreeOpenGL;
procedure SetView;
procedure RenderScene;
public
end;
var
frmMain: TfrmMain;
DC: HDC;
HRC :HGLRC ;
implementation
{$R *.dfm}
procedure TfrmMain.FreeOpenGL;
begin
wglMakeCurrent(DC,HRC);
wglDeleteContext(hRc);
ReleaseDC(Handle,DC);
end;
procedure TfrmMain.InitOpenGL;
var pfd:TPIXELFORMATDESCRIPTOR; pixelFormat:integer;
begin
DC := GetDC(Handle);
with pfd do
begin
nSize:=sizeof(TPIXELFORMATDESCRIPTOR); // 此结构尺寸
nVersion:=1;
dwFlags:=PFD_SUPPORT_OPENGL or PFD_DRAW_to_WINDOW or
PFD_DOUBLEBUFFER; // 使用双缓冲区
iPixelType:=PFD_TYPE_RGBA; //使用RGBA颜色空间
cColorBits:=24; //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;
end;
pixelFormat := ChoosePixelFormat(DC, @pfd);
if (pixelFormat = 0) then
exit;
if (SetPixelFormat(DC, pixelFormat, @pfd) <> TRUE) then
exit;
hRc := wglCreateContext(DC);
wglMakeCurrent(DC,HRC);
end;
procedure TfrmMain.FormCreate(Sender: TObject);
begin
InitOpenGL;
SetView;
end;
procedure TfrmMain.FormClose(Sender: TObject; var Action: TCloseAction);
begin
FreeOpenGL;
end;
procedure TfrmMain.tmrRenderTimer(Sender: TObject);
begin
RenderScene;
end;
procedure TfrmMain.RenderScene;
begin
glLoadIdentity;
glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT);//清空缓冲区
glColor3ub(0,255,0); //将颜色设置为绿色。
glBegin(GL_TRIANGLES);//告诉OpenGL将要绘制三角形
glVertex2f(200,300); //传输三角形的三个顶点坐标给OpenGL
glVertex2f(400,300);
glVertex2f(300,150);
glEnd; //结束图元的绘制。
SwapBuffers(DC);//交换双缓冲区内容,这将把刚绘制的图形翻印到屏幕上。
end;
procedure TfrmMain.SetView;
begin
glClearColor(0,0,0,0);//设置背景颜色为黑色
glViewPort(0,0,ClientWidth,ClientHeight);//指定OpenGL在此区域内绘图。
glMatrixMode(GL_PROJECTION);//设置视图投影变换矩阵
glLoadIdentity;//加载单位矩阵。
glOrtho(0,ClientWidth,ClientHeight,0,1,-1);//创建平行投影空间。
//在平行投影空间中,远处的物体和近处的物体大小是一致的。
glMatrixMode(GL_MODELVIEW);//将矩阵变换对象切换为模型视图变换。
end;
end.
OpenGL完全教程 第一章 初始化OpenGL的更多相关文章
- [ABP教程]第一章 创建服务端
Web应用程序开发教程 - 第一章: 创建服务端 关于本教程 在本系列教程中, 你将构建一个名为 Acme.BookStore 的用于管理书籍及其作者列表的基于ABP的应用程序. 它是使用以下技术开发 ...
- 村田噪声抑制基础教程-第一章 需要EMI静噪滤波器的原因
1-1. 简介 EMI静噪滤波器 (EMIFIL®) 是为电子设备提供电磁噪声抑制的电子元件,配合屏蔽罩和其他保护装置一起使用.这种滤波器仅从通过连线传导的电流中提取并移除引起电磁噪声的元件.第1章说 ...
- [Learn Android Studio 汉化教程]第一章 : Android Studio 介绍
注:为了看上去比较清晰这里只转载了中文 原地址: [Learn Android Studio 汉化教程]第一章 : Android Studio 介绍 本章将引导您完成安装和设置开发环境,然后你就可 ...
- javascript进阶教程第一章案例实战
javascript进阶教程第一章案例实战 一.学习任务 通过几个案例练习回顾学过的知识 通过练习积累JS的使用技巧 二.实例 练习1:删除确认提示框 实例描述: 防止用户小心单击了“删除”按钮,在用 ...
- 《进击吧!Blazor!》系列入门教程 第一章 8.部署
<进击吧!Blazor!>是本人与张善友老师合作的Blazor零基础入门教程视频,此教程能让一个从未接触过Blazor的程序员掌握开发Blazor应用的能力. 视频地址:https://s ...
- NeHe OpenGL教程 第一课:OpenGL窗口
转自[翻译]NeHe OpenGL 教程 前言 声明,此 NeHe OpenGL教程系列文章由51博客yarin翻译(2010-08-19),本博客为转载并稍加整理与修改.对NeHe的OpenGL管线 ...
- python 教程 第一章、 简介
第一章. 简介 官方介绍: Python是一种简单易学,功能强大的编程语言,它有高效率的高层数据结构,简单而有效地实现面向对象编程.Python简洁的语法和对动态输入的支持,再加上解释性语言的本质,使 ...
- Flask 教程 第一章:Hello, World!
本文翻译自The Flask Mega-Tutorial Part I: Hello, World! 一趟愉快的学习之旅即将开始,跟随它你将学会用Python和Flask来创建Web应用.上面的视频包 ...
- storm入门教程 第一章 前言[转]
1.1 实时流计算 互联网从诞生的第一时间起,对世界的最大的改变就是让信息能够实时交互,从而大大加速了各个环节的效率.正因为大家对信息实时响应.实时交互的需求,软件行业除了个人操作系统之外,数据库 ...
随机推荐
- Python实践:开篇
一.概述 Python实践 是应用Python解决实际问题的案例集合,这些案例中的Python应用通常 功能各异.大小不一. 该系列文章是本人应用Python的实践总结,会不定期更新. 二.目录 Py ...
- [LintCode] Interleaving Positive and Negative Numbers
Given an array with positive and negative integers. Re-range it to interleaving with positive and ne ...
- DFS HDOJ 2181 哈密顿绕行世界问题
题目传送门 题意:中文题面 分析:直接排完序后DFS.这样的题以后不应该再写题解的. #include <bits/stdc++.h> using namespace std; vecto ...
- 数学 Codeforces Round #291 (Div. 2) B. Han Solo and Lazer Gun
题目传送门 /* 水题,就是用三点共线的式子来判断射击次数 */ #include <cstdio> #include <cmath> #include <string& ...
- HDU3657 Game(最小割)
题目大概说,给一个n×m的格子,每个格子都有数字,选择一个格子就能加上格子数字的分数,有k个格子必须选择,如果两个相邻的格子都被选择了那分数要减去两个格子数字的与再乘2.问能取得的最大分数. 已经知道 ...
- How Many Trees?[HDU1130]
How Many Trees? Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)T ...
- SZU-A22
Problem(A22):Party Judge InfoMemory Limit: 32768KBCase Time Limit: 10000MSTime Limit: 10000MSJudger: ...
- Codeforces Round #190 DIV.2 A. Ciel and Dancing
#include <cstdio> #include <iostream> #include <vector> using namespace std; int m ...
- RGB
一,介绍 RGB色彩模式是工业界的一种颜色标准,是通过对红(R).绿(G).蓝(B)三个颜色通道的变化以及它们相互之间的叠加来得到各式各样的颜色的, RGB即是代表红.绿.蓝三个通道的颜色,这个标准几 ...
- c# 使用GetOleDbSchemaTable获取access数据库结构
c# 使用GetOleDbSchemaTable获取access数据库结构 ado.net可以使用GetOleDbSchemaTable方法来获取access数据库的结构,但得到的datatable的 ...