NeHe的opengl框架delphi版

myling 2003-07-25 08:42:53
加精
将CKER翻译的NeHe的VC 的OPENGL框架转成了Delphi版,
希望对现象我一样初学OPENGL的兄弟有所帮助,
不知为什么,我的Delphi环境下无法直接运行,但是在别的机器上好像没问题
我的机器只能编译后运行EXE文件。
感谢NeHe提供的这么好的框架,感谢CKER翻译的VC的资料



Program Project1;

Uses
opengl,
windows,
Messages;

Const
WND_TITLE = 'OPenGl 基本框架'; //标题
Var
//===========================================================================
// 每一个OpenGL都被连接到一个着色描述表上。着色描述表将所有的OpenGL调用命令连
// 接到Device Context(设备描述表)上,将OpenGL的着色描述表定义为hRC ,要让程序能
// 够绘制窗口的话,还需要创建一个设备描述表,Windows的设备描述表被定义为 hDC,
// DC将窗口连接到GDI(Graphics Device Interface图形设备接口)。而RC将OpenGL连接
// 到DC。
//===========================================================================
h_RC : HGLRC; // Rendering Context(着色描述表)。
h_DC : HDC; // Device Context(设备描述表)
h_Wnd : HWND; // 窗口句柄
h_Instance : HINST; // 程序Instance(实例)。
keys : Array[0..255] Of Boolean; // 用于键盘例程的数组
{$R *.res}

//==============================================================================
//重新设置OpenGL场景的大小,而不管窗口的大小是否已经改变(假定没有使用全屏模式)。
//甚至无法改变窗口的大小时(例如在全屏模式下),它至少仍将运行一次————————
//在程序开始时设置透视图。OpenGL场景的尺寸将被设置成它显示时所在窗口的大小。
//==============================================================================

Procedure glResizeWnd(Width, Height: Integer); // 重置并初始化GL窗口大小
Begin
If (Height = 0) Then // 防止高度为0,产生除0异常
Height := 1;
glViewport(0, 0, Width, Height); // 重置当前的视口(Viewport)

//下面几行为透视图设置屏幕。意味着越远的东西看起来越小。这么做创建了一个现实
//外观的场景。此处透视按照基于窗口宽度和高度的45度视角来计算。0.1f,100.0f是
//我们在场景中所能绘制深度的起点和终点。
//glMatrixMode(GL_PROJECTION)指明接下来的两行代码将影响projection matrix(投影矩阵)。
//投影矩阵负责为我们的场景增加透视。
//glLoadIdentity()近似于重置。它将所选的矩阵状态恢复成其原始状态。
//调用 glLoadIdentity()之后我们为场景设置透视图。

glMatrixMode(GL_PROJECTION); // 选择投影矩阵
glLoadIdentity(); // 重置投影矩阵

gluPerspective(45.0, Width / Height, 0.1, 100.0); // 计算窗口的外观比例

//glMatrixMode(GL_MODELVIEW)指明任何新的变换将会影响 modelview matrix(模型观察矩阵)。
//模型观察矩阵中存放了我们的物体讯息。

glMatrixMode(GL_MODELVIEW); // 选择模型观察矩阵
glLoadIdentity(); // 重置模型观察矩阵

//如果现在还不能理解这些术语的含义,请别着急。
//只要知道如果想获得一个精彩的透视场景的话,必须这么做。
End;

//==============================================================================
// 对OpenGL进行所有的设置。将设置清除屏幕所用的颜色,打开深度缓存,
// 启用smooth shading(阴影平滑),等等。这个例程直到OpenGL窗口创建之后才会被调用。
// 此过程将有返回值。但此处的初始化没那么复杂,现在还用不着担心这个返回值。
//==============================================================================

Procedure glInit();
Begin

//设置清除屏幕时所用的颜色。如果对色彩的工作原理不清楚的话,快速解释一下。
//色彩值的范围从0.0f到1.0f。0.0f代表最黑的情况,1.0f就是最亮的情况。
//glClearColor 后的第一个参数是Red Intensity(红色分量),第二个是绿色,第三个是蓝色。
//最大值也是1.0f,代表特定颜色分量的最亮情况。最后一个参数是Alpha值。
//当它用来清除屏幕的时候,不用关心第四个数字。现在让它为0.0f。
//通过混合三种原色(红、绿、蓝),可以得到不同的色彩
//因此,使用glClearColor(0.0f,0.0f,1.0f,0.0f),您蓝色来清除屏幕。
//如果用 glClearColor(0.5f,0.0f,0.0f,0.0f)的话,将使用中红色来清除屏幕。
//不是最亮(1.0f),也不是最暗 (0.0f)。要得到白色背景,应该将所有的颜色设成最亮(1.0f)。
//要黑色背景的话,该将所有的颜色设为最暗(0.0f)。

glClearColor(0.0, 0.0, 0.0, 0.0); // 黑色背景

//阴影平滑通过多边形精细的混合色彩,并对外部光进行平滑。

glShadeModel(GL_SMOOTH); // 启用阴影平滑

//接下来必须做的是关于depth buffer(深度缓存)的。将深度缓存设想为屏幕后面的层。
//深度缓存不断的对物体进入屏幕内部有多深进行跟踪。本程序其实没有真正使用深度缓存,
//但几乎所有在屏幕上显示3D场景OpenGL程序都使用深度缓存。它的排序决定那个物体先画。
//这样您就不会将一个圆形后面的正方形画到圆形上来。深度缓存是OpenGL十分重要的部分。

glClearDepth(1.0); // 设置深度缓存
glEnable(GL_DEPTH_TEST); // 启用深度测试
glDepthFunc(GL_LESS); // 所作深度测试的类型

//接着告诉OpenGL我们希望进行最好的透视修正。
//这会十分轻微的影响性能。但使得透视图看起来好一点。

glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); // 真正精细的透视修正

End;

//==============================================================================
//所有的绘图代码。任何您所想在屏幕上显示的东东都将在此段代码中出现。
//以后的每个程序会在此处增加新的代码。
//==============================================================================

Procedure glDraw();
Begin
glClear(GL_COLOR_BUFFER_BIT Or GL_DEPTH_BUFFER_BIT); // 清除屏幕和深度缓存
glLoadIdentity(); // 重置当前的模型观察矩阵
End;

Function WndProc(hWnd: HWND; // 窗口的句柄
Msg: UINT; // 窗口的消息
wParam: WPARAM; // 附加的消息内容
lParam: LPARAM // 附加的消息内容
): LRESULT; stdcall;
Begin
Result := 0;
Case (Msg) Of // 检查Windows消息
WM_ACTIVATE: // 监视窗口激活消息
Begin
End;
WM_CREATE: // 创建
Begin
End;
WM_CLOSE: // 关闭
Begin
PostQuitMessage(0); // 发出退出消息
Result := 0
End;
WM_KEYDOWN: // 按键按下
Begin
keys[wParam] := True; // 如果是,设为TRUE
Result := 0;
End;
WM_KEYUP: // 按键松开
Begin
keys[wParam] := False; // 如果是,设为FALSE
Result := 0;
End;
WM_SIZE: //调整OpenGL窗口大小
Begin
glResizeWnd(LOWORD(lParam), HIWORD(lParam)); //LoWord=Width,HiWord=Height
Result := 0;
End;
WM_TIMER: //timers
Begin
End;
Else //其余的让Windows自行处理。
Result := DefWindowProc(hWnd, Msg, wParam, lParam); //向DefWindowProc传递所有未处理的消息。
End;
End;
...全文
183 67 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
67 条回复
切换为时间正序
请发表友善的回复…
发表回复
jaguarcts 2003-09-26
  • 打赏
  • 举报
回复
procedure TPForm.FormCreate(Sender: TObject);
var
pDC: HDC;
begin

// It's simple, really:
pDC := GetDC(GLPanel1.Handle);
CgDC1 := TCGDeviceContext.Create(pDC);
CgDC1.InitGL;
glEnable(GL_DEPTH_TEST);

// Note that each DC you create has its own OpenGL state variables!
pDC := GetDC(GLPanel2.Handle);
CgDC2 := TCGDeviceContext.Create(pDC);
CgDC2.InitGL;
glEnable(GL_DEPTH_TEST);

end;

procedure TPForm.FormClose(Sender: TObject; var Action: TCloseAction);
begin

CgDC1.Free;
CgDC2.Free;

end;

procedure TPForm.FormPaint(Sender: TObject);
begin

// Just draw something...
CgDC1.MakeCurrent;
glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT);
glLoadIdentity;
glRotatef(a, 1, 2, 3);
glutWireTorus(0.2, 0.4, 16, 32);
CgDC1.PageFlip;

// And to the second panel as well...
CgDC2.MakeCurrent;
glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT);
glLoadIdentity;
glRotatef(-a, 1, 2, 3);
glBegin(GL_TRIANGLES);
glColor3f(1, 0, 0); glVertex2f(-0.5, -0.5);
glColor3f(0, 1, 0); glVertex2f(0.5, -0.5);
glColor3f(0, 0, 1); glVertex2f(0, 0.5);
glEnd;
CgDC2.PageFlip;

end;

procedure TPForm.TimerTimer(Sender: TObject);
begin

a := (a+1) mod 360;
Paint;

end;

procedure TPForm.SplitterMoved(Sender: TObject);
begin

// Resize the viewports. Also called when the form resizes.
{ The splitter is set to rsUpdate, so it repaints whenever you drag it. This
causes a lot of flicker, so set it to rsPattern if you get a migraine. }
CgDC1.MakeCurrent;
glViewport(0, 0, GLPanel1.Width, GLPanel1.Height);
CgDC2.MakeCurrent;
glViewport(0, 0, GLPanel2.Width, GLPanel2.Height);

end;

procedure TPForm.SplitterCanResize(Sender: TObject; var NewSize: Integer;
var Accept: Boolean);
begin

// Keep the splitter from snapping to the left edge of the form.
Accept := not (NewSize <= 31);

end;

Devlopered 2003-09-17
  • 打赏
  • 举报
回复
up
chijingde 2003-09-16
  • 打赏
  • 举报
回复
唉,越来越懒,时间拖的越来越长

这次贴两课

第8课:透明

http://www.csdn.net/Develop/read_article.asp?id=21062

第9课:星星动画

http://www.csdn.net/Develop/read_article.asp?id=21064
baisha178 2003-09-09
  • 打赏
  • 举报
回复
MARK
司码君 2003-09-08
  • 打赏
  • 举报
回复
重新整理
我好打印哈哈哈
acceptspf 2003-09-03
  • 打赏
  • 举报
回复
OpenGL 和 Direct3D 有什么区别?
chijingde 2003-09-03
  • 打赏
  • 举报
回复
晕了,已经回了30贴了,只好用马甲了,呵呵


OK,把1-7课还有那个库都发给你了


8、9也翻译好了

等找个时间贴出来
xebaobei 2003-09-03
  • 打赏
  • 举报
回复
myling(阿德)
可不可以把你上边发的好长的代码的程序给我一个啊`
我运行了~
可是什么效果没有啊~
555555555555~~~~~~~~~~~
我很想学习OPENGL啊~
shuizhiqiang@etang.com
snowolf_ren 2003-09-01
  • 打赏
  • 举报
回复
关注!
internetcsdn 2003-08-21
  • 打赏
  • 举报
回复
mark
internetcsdn 2003-08-21
  • 打赏
  • 举报
回复
mark
azher 2003-08-21
  • 打赏
  • 举报
回复
谢谢了,阿德兄!
myling 2003-08-20
  • 打赏
  • 举报
回复
呵呵,最近比较忙,第7课早写翻译了,但是一直没时间整理

现在贴出来了

http://www.csdn.net/Develop/read_article.asp?id=20554
wz蝈蝈 2003-08-08
  • 打赏
  • 举报
回复
学习!
myling 2003-08-02
  • 打赏
  • 举报
回复
http://www.csdn.net/Develop/read_article.asp?id=20023
http://www.csdn.net/Develop/read_article.asp?id=20029
http://www.csdn.net/Develop/read_article.asp?id=20031
http://www.csdn.net/Develop/read_article.asp?id=20039
http://www.csdn.net/Develop/read_article.asp?id=20109
http://www.csdn.net/Develop/read_article.asp?id=20165

一共六课,还会继续贴的
myling 2003-08-02
  • 打赏
  • 举报
回复
算了,没什么人气,已经贴到文档区了,


有兴趣的兄弟到那里找吧


结贴
chijingde 2003-08-02
  • 打赏
  • 举报
回复
up
myling 2003-08-02
  • 打赏
  • 举报
回复
{现在我们绘制贴图过的立方体。这段代码被狂注释了一把,应该很好懂。开始两行代码 glClear() 和 glLoadIdentity() 是第一课中就有的代码。 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT) 清除屏幕并设为我们在 InitGL() 中选定的颜色,本例中是黑色。深度缓存也被清除。模型观察矩阵也使用glLoadIdentity()重置。}

Procedure glDraw();
Begin
glClear(GL_COLOR_BUFFER_BIT Or GL_DEPTH_BUFFER_BIT); // 清除屏幕和深度缓存
glLoadIdentity(); // 重置当前的模型观察矩阵
glTranslatef(0.0, 0.0, -6.0); // 移入屏幕6个单位

//下面三行使立方体绕X、Y、Z轴旋转。
//旋转多少依赖于变量 xrot , yrot 和 zrot 的值。
glRotatef(xrot, 1.0, 0.0, 0.0); // 绕X轴旋转
glRotatef(yrot, 0.0, 1.0, 0.0); // 绕Y轴旋转
glRotatef(zrot, 0.0, 0.0, 1.0); // 绕Z轴旋转

//下一行代码选择我们使用的纹理。
//如果在场景中使用多个纹理,应该使用
//glBindTexture(GL_TEXTURE_2D, texture[ 所使用纹理对应的数字 ]) 来选择要绑定的纹理。
//当想改变纹理时,应该绑定新的纹理。
//有一点值得指出的是,
//不能在 glBegin() 和 glEnd() 之间绑定纹理,
//必须在 glBegin() 之前或 glEnd() 之后绑定。
//注意我们在后面是如何使用 glBindTexture 来指定和绑定纹理的。

glBindTexture(GL_TEXTURE_2D, texture[0]); // 选择纹理

//为了将纹理正确的映射到四边形上,
//必须将纹理的右上角映射到四边形的右上角,
//纹理的左上角映射到四边形的左上角,
//纹理的右下角映射到四边形的右下角,
//纹理的左下角映射到四边形的左下角。
//如果映射错误的话,图像显示时可能上下颠倒,侧向一边或者什么都不是。

//glTexCoord2f 的第一个参数是X坐标。
// 0.0是纹理的左侧。 0.5是纹理的中点, 1.0是纹理的右侧。
//glTexCoord2f 的第二个参数是Y坐标。
//0.0是纹理的底部。 0.5是纹理的中点, 1.0是纹理的顶部。
//所以纹理的左上坐标是 X:0.0f,Y:1.0f ,
//四边形的左上顶点是 X: -1.0f,Y:1.0f 。
//其余三点依此类推。

//试着玩玩 glTexCoord2f 的X,Y坐标参数。
//把1.0改为0.5将只显示纹理的左半部分,
//把0.0改为0.5将只显示纹理的右半部分。
glBegin(GL_QUADS);
// 前面
glTexCoord2f(0.0, 0.0);
glVertex3f(-1.0, -1.0, 1.0); // 纹理和四边形的左下
glTexCoord2f(1.0, 0.0);
glVertex3f(1.0, -1.0, 1.0); // 纹理和四边形的右下
glTexCoord2f(1.0, 1.0);
glVertex3f(1.0, 1.0, 1.0); // 纹理和四边形的右上
glTexCoord2f(0.0, 1.0);
glVertex3f(-1.0, 1.0, 1.0); // 纹理和四边形的左上
// 后面
glTexCoord2f(1.0, 0.0);
glVertex3f(-1.0, -1.0, -1.0); // 纹理和四边形的右下
glTexCoord2f(1.0, 1.0);
glVertex3f(-1.0, 1.0, -1.0); // 纹理和四边形的右上
glTexCoord2f(0.0, 1.0);
glVertex3f(1.0, 1.0, -1.0); // 纹理和四边形的左上
glTexCoord2f(0.0, 0.0);
glVertex3f(1.0, -1.0, -1.0); // 纹理和四边形的左下
// 顶面
glTexCoord2f(0.0, 1.0);
glVertex3f(-1.0, 1.0, -1.0); // 纹理和四边形的左上
glTexCoord2f(0.0, 0.0);
glVertex3f(-1.0, 1.0, 1.0); // 纹理和四边形的左下
glTexCoord2f(1.0, 0.0);
glVertex3f(1.0, 1.0, 1.0); // 纹理和四边形的右下
glTexCoord2f(1.0, 1.0);
glVertex3f(1.0, 1.0, -1.0); // 纹理和四边形的右上
// 底面
glTexCoord2f(1.0, 1.0);
glVertex3f(-1.0, -1.0, -1.0); // 纹理和四边形的右上
glTexCoord2f(0.0, 1.0);
glVertex3f(1.0, -1.0, -1.0); // 纹理和四边形的左上
glTexCoord2f(0.0, 0.0);
glVertex3f(1.0, -1.0, 1.0); // 纹理和四边形的左下
glTexCoord2f(1.0, 0.0);
glVertex3f(-1.0, -1.0, 1.0); // 纹理和四边形的右下
// 右面
glTexCoord2f(1.0, 0.0);
glVertex3f(1.0, -1.0, -1.0); // 纹理和四边形的右下
glTexCoord2f(1.0, 1.0);
glVertex3f(1.0, 1.0, -1.0); // 纹理和四边形的右上
glTexCoord2f(0.0, 1.0);
glVertex3f(1.0, 1.0, 1.0); // 纹理和四边形的左上
glTexCoord2f(0.0, 0.0);
glVertex3f(1.0, -1.0, 1.0); // 纹理和四边形的左下
// 左面
glTexCoord2f(0.0, 0.0);
glVertex3f(-1.0, -1.0, -1.0); // 纹理和四边形的左下
glTexCoord2f(1.0, 0.0);
glVertex3f(-1.0, -1.0, 1.0); // 纹理和四边形的右下
glTexCoord2f(1.0, 1.0);
glVertex3f(-1.0, 1.0, 1.0); // 纹理和四边形的右上
glTexCoord2f(0.0, 1.0);
glVertex3f(-1.0, 1.0, -1.0); // 纹理和四边形的左上
glEnd();

xrot := xrot + 0.3; // X 轴旋转
yrot := yrot + 0.2; // Y 轴旋转
zrot := zrot + 0.4; // Z 轴旋转
End;

{最后,关于用作纹理的图像我想有几点十分重要,并且您必须明白。此图像的宽和高必须是2的n次方;宽度和高度最小必须是64象素;并且出于兼容性的原因,图像的宽度和高度不应超过256象素。如果您的原始素材的宽度和高度不是64,128,256象素的话,使用图像处理软件重新改变图像的大小。可以肯定有办法能绕过这些限制,但现在我们只需要用标准的纹理尺寸。}

//OK!运行一下看看效果
myling 2003-08-02
  • 打赏
  • 举报
回复
//接下来在创建一个新函数,用来载入纹理贴图

Function LoadTexture: boolean;

//Status 的变量。我们使用它来跟踪是否能够载入位图以及能否创建纹理。
// Status 缺省设为 FALSE (表示没有载入或创建任何东东)。
//TextureImage变量PTAUX_RGBImageRec类型 存储位图的图像记录。
//次记录包含位图的宽度、高度和数据。

Var
Status : boolean;
TextureImage : Array[0..1] Of PTAUX_RGBImageRec;
Begin
Status := false;
ZeroMemory(@TextureImage, sizeof(TextureImage)); // 将指针设为 NULL
TextureImage[0] := LoadBMP('Texture.bmp');
If TextureImage[0] <> Nil Then
Begin
Status := TRUE; // 将 Status 设为 TRUE
//现在使用中 TextureImage[0] 的数据创建纹理。
//glGenTextures(1, texture[0]) 告诉OpenGL我们想生成一个纹理名字
//(如果您想载入多个纹理,加大数字)。
//glBindTexture(GL_TEXTURE_2D, texture[0]) 告诉OpenGL将纹理名字 texture[0] 绑定到纹理目标上。
//2D纹理只有高度(在 Y 轴上)和宽度(在 X 轴上)。
//主函数将纹理名字指派给纹理数据。
//本例中我们告知OpenGL, &texture[0] 处的内存已经可用。
//我们创建的纹理将存储在 &texture[0] 的 指向的内存区域。
glGenTextures(1, texture[0]); // 创建纹理
glBindTexture(GL_TEXTURE_2D, texture[0]); // 使用来自位图数据生成 的典型纹理
//下来我们创建真正的纹理。
//下面一行告诉OpenGL此纹理是一个2D纹理 ( GL_TEXTURE_2D )。
//数字零代表图像的详细程度,通常就由它为零去了。
//数字三是数据的成分数。因为图像是由红色数据,绿色数据,蓝色数据三种组分组成。
//TextureImage[0].sizeX 是纹理的宽度。
//如果您知道宽度,您可以在这里填入,但计算机可以很容易的为您指出此值。
// TextureImage[0].sizey 是纹理的高度。
//数字零是边框的值,一般就是零。
// GL_RGB 告诉OpenGL图像数据由红、绿、蓝三色数据组成。
//GL_UNSIGNED_BYTE 意味着组成图像的数据是无符号字节类型的。
//最后... TextureImage[0].data 告诉OpenGL纹理数据的来源。
//此例中指向存放在 TextureImage[0] 记录中的数据。

// 生成纹理
glTexImage2D(GL_TEXTURE_2D, 0, 3, TextureImage[0].sizeX,
TextureImage[0].sizeY, 0, GL_RGB, GL_UNSIGNED_BYTE,
TextureImage[0].data);

//下面的两行告诉OpenGL在显示图像时,
//当它比放大得原始的纹理大(GL_TEXTURE_MAG_FILTER)
//或缩小得比原始得纹理小(GL_TEXTURE_MIN_FILTER)时OpenGL采用的滤波方式。
//通常这两种情况下我都采用 GL_LINEAR。这使得纹理从很远处到离屏幕很近时都平滑显示。
//使用 GL_LINEAR需要CPU和显卡做更多的运算。
//如果您的机器很慢,您也许应该采用 GL_NEAREST 。
//过滤的纹理在放大的时候,看起来斑驳的很(马赛克啦)。
//您也可以结合这两种滤波方式。在近处时使用 GL_LINEAR ,远处时 GL_NEAREST 。
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); // 线形滤波
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); // 线形滤波
End;
//现在我们释放前面用来存放位图数据的内存。
//我们先查看位图数据是否存放在处。
//如果是的话,再查看数据是否已经存储。
//如果已经存储的话,删了它。
//接着再释放 TextureImage[0] 图像结构以保证所有的内存都能释放。
If assigned(TextureImage[0]) Then // 纹理是否存在
If assigned(TextureImage[0].data) Then // 纹理图像是否存在
TextureImage[0].data := Nil; // 释放纹理图像占用的内存
TextureImage[0] := Nil; // 释放图像结构
// 最后返回状态变量。如果一切OK,变量 Status 的值为 TRUE 。否则为 FALSE
result := Status; // 返回 Status
End;


//然后在 glInit 中增加很少的几行代码

Procedure glInit();
Begin
If (Not LoadTexture) Then // 调用纹理载入子例程( 新增 )
exit; // 如果未能载入,退出( 新增 )
glEnable(GL_TEXTURE_2D); // 启用纹理映射( 新增 )
glClearColor(0.0, 0.0, 0.0, 0.0); // 黑色背景
glShadeModel(GL_SMOOTH); // 启用阴影平滑
glClearDepth(1.0); // 设置深度缓存
glEnable(GL_DEPTH_TEST); // 启用深度测试
glDepthFunc(GL_LESS); // 所作深度测试的类型
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); // 真正精细的透视修正

End;

myling 2003-08-02
  • 打赏
  • 举报
回复
继续……


{

贴图可以极大的节省CPU时间。呵呵,但是这一节费了我比较多的时间 : (

因为用到了opengl的辅助库,现在这个库的函数已经很少有人用了,但是我还是找到了,感谢zdcnow(磁效应),他给我提供的这个辅助库的delphi版本。在学习本节之前,请大家到网上下载glaux.dll、Glaux.pas文件,并加到项目中。

好了,让我们继续OPENGL之路.

首先我们需要加进SysUtils单元,因为我们这节要用到文件操作,我们还要将Glaux单元加进来。

然后我们在第一课的基础上加上几个变量,xrot , yrot 和 zrot 。这些变量用来使立方体绕X、Y、Z轴旋转。texture[] 为一个纹理分配存储空间。如果您需要不止一个的纹理,应该将数字1改成您所需要的数字。

}

VAR

h_RC : HGLRC; // Rendering Context(着色描述表)。
h_DC : HDC; // Device Context(设备描述表)
h_Wnd : HWND; // 窗口句柄
h_Instance : HINST; // 程序Instance(实例)。
keys : Array[0..255] Of Boolean; // 用于键盘例程的数组

xrot, // X 旋转量 ( 新增 )
yrot, // Y 旋转量 ( 新增 )
zrot : GLfloat; // Z 旋转量 ( 新增 )

Texture : Array[0..1] Of GLuint; // 存储一个纹理 ( 新增 )

{然后引载入opengl32.dll中的两个过程,我们要用到他们}


Procedure glGenTextures(n: GLsizei; Var textures: GLuint); stdcall; external
opengl32;
Procedure glBindTexture(target: GLenum; texture: GLuint); stdcall; external
opengl32;

{接下来我们需要增加一个新的函数,用来再入图像,该函数的返回类型在Glaux.pas中定义如下:

TAUX_RGBImageRec= record
sizeX, sizeY: GLint;
data: pointer;
end;
PTAUX_RGBImageRec= ^TAUX_RGBImageRec;

具体含义会在后面介绍}

Function LoadBmp(filename: pchar): PTAUX_RGBImageRec;
Var
BitmapFile : Thandle; // 文件句柄
Begin
//接下来检查文件名是否已提供
If Filename = '' Then // 确保文件名已提供。
result := Nil; // 如果没提供,返回 NULL
//接着检查文件是否存在。
BitmapFile := FileOpen(Filename, fmOpenWrite); //尝试打开文件
//如果我们能打开文件的话,很显然文件是存在的。

If BitmapFile > 0 Then // 文件存在么?
Begin
//关闭文件。
FileClose(BitmapFile); // 关闭句柄
//auxDIBImageLoad(Filename) 读取图象数据并将其返回。
result := auxDIBImageLoadA(filename); //载入位图并返回指针
End
Else
//如果我们不能打开文件,我们将返回NiL。
result := Nil; // 如果载入失败,返回NiL。
End;



加载更多回复(47)

1,185

社区成员

发帖
与我相关
我的任务
社区描述
Delphi GAME,图形处理/多媒体
社区管理员
  • GAME,图形处理/多媒体社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧