?? unit1.pas
字號:
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, AppEvnts, Unit3DS, OpenGL, ComCtrls, ExtCtrls, StdCtrls,
Buttons,Textures;
const
HITBUFFERCOUNT = 64;
type
PHit = ^THit;
THit = packed record
NCount, DNear, DFar:GLuint;
Names:array[1..32] of GLuint;
end;
type
TViewPort = packed record
Left, Bottom, Width, Height:GLint;
end;
type
THitBuffer = array[1..HITBUFFERCOUNT] of GLuint;
type
TForm1 = class(TForm)
ApplicationEvents1: TApplicationEvents;
Panel1: TPanel;
Panel2: TPanel;
SpeedButton1: TSpeedButton;
SpeedButton2: TSpeedButton;
Timer1: TTimer;
Edit1: TEdit;
SpeedButton3: TSpeedButton;
Edit2: TEdit;
procedure ApplicationEvents1Idle(Sender: TObject; var Done: Boolean);
procedure FormResize(Sender: TObject);
procedure FormShow(Sender: TObject);
procedure FormClose(Sender: TObject; var Action: TCloseAction);
procedure FormMouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
procedure FormMouseMove(Sender: TObject; Shift: TShiftState; X,
Y: Integer);
procedure FormKeyDown(Sender: TObject; var Key: Word;
Shift: TShiftState);
procedure Panel1MouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
procedure Panel1MouseMove(Sender: TObject; Shift: TShiftState; X,
Y: Integer);
procedure SpeedButton1Click(Sender: TObject);
procedure SpeedButton2Click(Sender: TObject);
procedure Timer1Timer(Sender: TObject);
procedure SpeedButton3Click(Sender: TObject);
procedure Panel1Click(Sender: TObject);
private
{ Private declarations }
procedure Selection(const X, Y: GLdouble);
function SelectionDone:Integer;
function Selected(const X, Y:Integer): Integer;
procedure DrawBackground(backtex:gluint); //////////////
public
{ Public declarations }
Model:T3DModel;
HitBuffer:THitBuffer;
procedure Render;
procedure EnviromentMap;
end;
var
BackgroundTex : glUint;
Form1: TForm1;
Ax, Mx:Single;
Ay, My:Single;
locate,ydistance,ydistance1,xdistance0,xdistance1,zdistance1,zdistance2:glfloat;
g_elev,speed,eye0, eye1, eye2,at0, at1, at2:glfloat;
ObjSelected:T3DObject;
// ********************************** NEW NEW **********************************
T0, T1, T2,T3,T4,T5,T6,T7,T8,T9:TTransformation; // Pointer to transformation for each bject
angle:Single;
a,b,c1,c2:boolean;
anObject1,anObject2:T3DObject;
anObjects:array[1..32] of T3DObject;
implementation
uses UglContext;
{$R *.dfm}
procedure Tform1.DrawBackground(backtex:gluint); //////////////
begin
glMatrixMode(GL_MODELVIEW);
glPushMatrix(); glLoadIdentity(); // 重置投影矩陣 glMatrixMode(GL_PROJECTION); glPushMatrix(); glLoadIdentity(); // 重置投影矩陣
glOrtho(-1.0, 1.0, -1.0, 1.0, 0.0, 1.0);
glDisable(GL_DEPTH_TEST);
glBindTexture(GL_TEXTURE_2D, backtex); // 選擇紋理
glBegin(GL_QUADS);
glTexCoord2f(0.0, 0.0); glVertex2f(-1.0, -1.0); // 紋理和四邊形的左下
glTexCoord2f(1.0, 0.0); glVertex2f( 1.0, -1.0); // 紋理和四邊形的右下
glTexCoord2f(1.0, 1.0); glVertex2f( 1.0, 1.0); // 紋理和四邊形的右上
glTexCoord2f(0.0, 1.0); glVertex2f(-1.0, 1.0); // 紋理和四邊形的左上
glEnd();
glEnable(GL_DEPTH_TEST);
glMatrixMode(GL_PROJECTION); glPopMatrix(); glMatrixMode(GL_MODELVIEW); glPopMatrix();
end;
procedure glBindTexture(target: GLenum; texture: GLuint); stdcall; external
opengl32;
procedure TForm1.FormShow(Sender: TObject);
var anObject:T3DObject;
begin
CreateGLContext(panel1.Handle);
Model:=T3DModel.Create;
Model.LoadFromFile('14.3ds');
glEnable(GL_LIGHT0);
glEnable(GL_LIGHTING);
glPointSize(4);
EnviromentMap;
// ********************************** NEW NEW **********************************
glnewlist(1,gl_compile);
anObjects[1]:=Model.FindObject('Box02');
glendlist();
{anObject:=Model.FindObject('小車');
T0:=anObject.TransformList.AddTransformEx(ttTranslate, 0.0, 0.0, 0.0, 0.0);
anObject:=Model.FindObject('模仿器');
T1:=anObject.TransformList.AddTransformEx(ttTranslate, 0.0, 0.0, 0.0, 0.0);
anObject:=Model.FindObject('模仿器02');
T2:=anObject.TransformList.AddTransformEx(ttTranslate, 0.0, 0.0, 0.0, 0.0);
anObject:=Model.FindObject('長方體58');
T3:=anObject.TransformList.AddTransformEx(ttTranslate, 0.0, 0.0, 0.0, 0.0);
anObject:=Model.FindObject('長方體09');
T4:=anObject.TransformList.AddTransformEx(ttTranslate, 0.0, 0.0, 0.0, 0.0);
anObject:=Model.FindObject('長方體03');
T5:=anObject.TransformList.AddTransformEx(ttTranslate, 0.0, 0.0, 0.0, 0.0);
{angle:=-90;
speed:=0.2;
a:=true;
{ anObject1:=Model.FindObject('點8');
anObject2:=Model.FindObject('點9'); }
//anObject1.Material.Diffuse.SetRGBA(0,255,255,0);
c1:=false;
c2:=false;
// ********************************** END NEW **********************************
end;
procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
Model.Free;
DestroyGLContext;
end;
procedure TForm1.FormResize(Sender: TObject);
begin
ResizeGL(Width, Height);
end;
procedure TForm1.ApplicationEvents1Idle(Sender: TObject;
var Done: Boolean);
begin
Done:=False;
Render;
end;
procedure TForm1.Render;
begin
ClearGL;
ResetModelView;
glRotatef(Ax, 1, 0, 0);
glRotatef(-Ay, 0, 1, 0);
// ********************************** NEW NEW **********************************
// ********************************** END NEW **********************************
{glDisable(GL_TEXTURE_GEN_S);
glDisable(GL_TEXTURE_GEN_T);
glBindTexture(GL_TEXTURE_2D,BackgroundTex);
// glTranslatef(0.0,0.0,-24.0);
glenable(GL_TEXTURE_2D);
loadTexture('NeHe.bmp',BackGroundTex,false);
glBegin(GL_QUADS);
glNormal3f(0.0,0.0,1.0);
glTexCoord2f(0.0,0.0);glVertex3f(-400,0,-100);
glTexCoord2f(1.0,0.0);glVertex3f(400,0,-100);
glTexCoord2f(1.0,1.0);glVertex3f(400,400,-100);
glTexCoord2f(0.0,1.0);glVertex3f(-400,400,-100);
glend(); }
glDisable(GL_TEXTURE_GEN_S);
glDisable(GL_TEXTURE_GEN_T);
glBindTexture(GL_TEXTURE_2D,BackgroundTex);
// glTranslatef(0.0,0.0,-24.0);
glenable(GL_TEXTURE_2D);
loadTexture('NeHe.bmp',BackGroundTex,false);
glBegin(GL_QUADS);
//glNormal3f(0.0,0.0,1.0);
glTexCoord2f(0.0,0.0);glVertex2f(-1,-1);
glTexCoord2f(1.0,0.0);glVertex2f(1,-1);
glTexCoord2f(1.0,1.0);glVertex2f(1,1);
glTexCoord2f(0.0,1.0);glVertex2f(-1,1);
glend();
//GLlightfv(GL_LIGHT0,GL_POSITION,@Lightposition);
DrawBackground(BackgroundTex); ///////////////////
gluLookAt(eye0, eye1+5, eye2+10,at0+5, at1+g_elev, at2-8,0.0, 1.0, 0.0);
//loadTexture('NeHe.bmp',BackGroundTex,false);
Model.Draw;
SwapGL;
end;
procedure TForm1.FormMouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
begin
Mx:=X;
My:=Y;
ObjSelected:=Model.Select(Selected(X, Y));
end;
procedure TForm1.FormMouseMove(Sender: TObject; Shift: TShiftState; X,
Y: Integer);
begin
if ssLeft in Shift then
begin
Ax := Ax + (Y-My)/2;
Ay := Ay + (X-Mx)/2;
Mx:=X;
My:=Y;
end;
end;
procedure TForm1.EnviromentMap;
var I:Integer;
begin
for I:=0 to Model.ObjectCount-1 do
begin
Model.Objects[I].Material.EnviromentMap:=True;
Model.Objects[I].Material.SphericalMap:=True;
end;
end;
procedure TForm1.Selection(const X, Y: GLdouble);
var
ViewPort:TViewPort;
Py:GLdouble;
begin
glSelectBuffer(HITBUFFERCOUNT, @HitBuffer);
glRenderMode(GL_SELECT);
glInitNames;
glPushName(0);
glMatrixMode(GL_PROJECTION);
glPushMatrix;
glLoadIdentity;
glGetIntegerv(GL_VIEWPORT, @ViewPort);
Py:=ViewPort.Height -Y-47;
gluPickMatrix(X, Py, 30.0, 30.0, @ViewPort);
gluPerspective(45, Width/Height, 1, 300);
end;
function TForm1.SelectionDone:Integer;
var Hits:GLint;
Hit:PHit;
begin
Result:=-1;
glMatrixMode(GL_PROJECTION);
glPopMatrix;
Hits:=glRenderMode(GL_RENDER);
if Hits=0 then
Exit;
Hit:=@HitBuffer[1];
Result:=Hit^.Names[Hit^.NCount];
end;
function TForm1.Selected(const X, Y:Integer): Integer;
begin
Selection(X, Y);
Render;
result:=SelectionDone;
end;
procedure TForm1.FormKeyDown(Sender: TObject; var Key: Word;
Shift: TShiftState);
begin
if a then
begin
locate:=zdistance1-zdistance2 ;
if (key=VK_UP)and(locate>=0) then
begin
ydistance :=ydistance + 0.2;
if ydistance >0 then
ydistance :=0
end;
if (key=VK_DOWN)and(locate>=0)and(xdistance0<-42) then begin ydistance := ydistance-1; if ydistance<-5 then begin
locate:=0.001 ;
ydistance:=-5;
end
else if ydistance1<0then ydistance1:=0; end; if (key=VK_DOWN)and(locate>=0)and(xdistance0>-42) then begin ydistance := ydistance-0.2; if ydistance<-11 then begin
locate:=0.001 ;
ydistance:=-11;
end
else if ydistance1<-6 then ydistance1:=-6; end; if (key=VK_RIGHT)and(locate>=0) then xdistance0:=xdistance0+0.2; if xdistance0>0 then xdistance0:=0;
if (key=VK_LEFT) and(locate>=0)and(xdistance0>-40) then xdistance0:=xdistance0-0.2;
if (key=VK_LEFT) and(locate>=0)and(xdistance0<-40)and(ydistance>=-5) then
xdistance0:=xdistance0-0.2;
if xdistance0<-47 then
xdistance0:=-47;
if (key=VK_SPACE) and(ydistance=-11)and(xdistance0>-24)then
begin
zdistance1:=0;
zdistance2:=0;
end;
if (key=VK_SPACE) and(ydistance=-5)and(xdistance0<-40)then
begin
zdistance1:=0;
zdistance2:=0;
end;
if(key=VK_RETURN)and(ydistance1-ydistance=5)and(xdistance1-xdistance0>
46.9)and(xdistance1-xdistance0<47.1) then
begin
zdistance2:=0.2;
zdistance1:=-0.2;
end;
if (key=VK_UP) and (locate<0) then
begin
ydistance := ydistance + 0.2;
ydistance1:= ydistance1 + 0.2;
if ydistance>0 then
begin
ydistance:=0; ydistance1:=5; end end;
if (key=VK_DOWN)and(locate<0)and(xdistance0>-42) then begin ydistance := ydistance-0.2; ydistance1 := ydistance1-0.2; if ydistance<-11 then begin
ydistance:=-11;
ydistance1:=-6 ;
end
end; if (key=VK_DOWN)and(locate<0)and(xdistance0<-42) then begin ydistance := ydistance-0.2; ydistance1 := ydistance1-0.2; if ydistance<-5then begin
ydistance:=-5;
ydistance1:=0 ;
end
end; if (key=VK_RIGHT)and(locate<0) then begin xdistance0:=xdistance0+0.2; xdistance1:=xdistance1+0.2; if xdistance0>0 then begin xdistance0:=0; xdistance1:=47 end end;
if(key=VK_LEFT)and(locate<0)and(xdistance0>-40) then
begin
xdistance0:=xdistance0-0.2;
xdistance1:=xdistance1-0.2; end; if(key=VK_LEFT)and(locate<0)and(xdistance0<-40)and(ydistance>=-5) then begin
xdistance0:=xdistance0-0.2;
xdistance1:=xdistance1-0.2; end;
if xdistance0<-47 then
begin
xdistance0:=-47 ; xdistance1:=0 ; end ;
end;
if (KEY=34)then g_elev:=g_elev+1; //Page UP 鍵
if (KEY=33) then g_elev:=g_elev-1; //Page Down鍵
if (g_elev<-180) then g_elev :=-180; //仰俯角
if (g_elev> 0) then g_elev := 0; //仰俯角
if (KEY=VK_SHIFT) then speed:=speed*4;
if(key=Ord('D')) then
begin
angle:=angle+2.0*speed;
at0 := eye0 + 100*cos(PI*angle/180.0);
at2 := eye2 + 100*sin(PI*angle/180.0);
at1 := eye1;
end;
if(key=Ord('A')) then
begin
angle:=angle-2.0*speed;
at0 := eye0 + 100*cos(PI*angle/180.0);
at2 := eye2 + 100*sin(PI*angle/180.0);
at1 := eye1;
end;
if(key=Ord('W')) then
begin
eye2 :=eye2 + sin(PI*angle/180.0) * speed;
eye0:=eye0+ cos(PI*angle/180.0) * speed;
at0 := eye0 + 100*cos(PI*angle/180.0);
at2 := eye2 + 100*sin(PI*angle/180.0);
at1 := eye1;
end;
if(key=Ord('S')) then
begin
eye2 :=eye2- sin(PI*angle/180.0) *0.8;
eye0 :=eye0- cos(PI*angle/180.0) *0.8;
at0 := eye0 + 100*cos(PI*angle/180.0);
at2 := eye2 + 100*sin(PI*angle/180.0);
at1 := eye1;
end;
end;
procedure TForm1.Panel1MouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
begin
Mx:=X;
My:=Y;
ObjSelected:=Model.Select(Selected(X, Y));
if ObjSelected<>nil then
ObjSelected.Material.Diffuse.SetRGBA(255,255,0,0);
end;
procedure TForm1.Panel1MouseMove(Sender: TObject; Shift: TShiftState; X,
Y: Integer);
begin
if ssLeft in Shift then
begin
Ax := Ax + (Y-My)/2;
Ay := Ay + (X-Mx)/2;
Mx:=X;
My:=Y;
end;
end;
procedure TForm1.SpeedButton1Click(Sender: TObject);
begin
a:=true;
b:=false;
end;
procedure TForm1.SpeedButton2Click(Sender: TObject);
begin
a:=false;
b:=true;
end;
procedure TForm1.Timer1Timer(Sender: TObject);
var anObject:T3DObject;
begin
if c1 then
begin
if anObject1.Material.Diffuse.Alpha=0 then
anObject1.Material.Diffuse.SetRGBA(0,255,174,1)
else
anObject1.Material.Diffuse.SetRGBA(255,255,0,0);
end;
if c2 then
begin
if anObject2.Material.Diffuse.Alpha=0 then
anObject2.Material.Diffuse.SetRGBA(0,255,174,1)
else
anObject2.Material.Diffuse.SetRGBA(255,255,0,0);
end;
end;
procedure TForm1.SpeedButton3Click(Sender: TObject);
var a1,a2:integer;
begin
a1:=StrToInt(Edit1.Text);
a2:=StrToInt(Edit2.Text);
if a1>10 then
c1:=true
else
begin
anObject1.Material.Diffuse.SetRGBA(0,255,174,1);
c1:=false;
end;
if a2>10 then
c2:=true
else
begin
anObject2.Material.Diffuse.SetRGBA(0,255,174,1);
c2:=false;
end;
end;
procedure TForm1.Panel1Click(Sender: TObject);
var a1,a2:integer;
begin
a1:=StrToInt(Edit1.Text);
a2:=StrToInt(Edit2.Text);
if a1>10 then
c1:=true
else
begin
anObject1.Material.Diffuse.SetRGBA(0,255,174,1);
c1:=false;
end;
if a2>10 then
c2:=true
else
begin
anObject2.Material.Diffuse.SetRGBA(0,255,174,1);
c2:=false;
end;
end;
end.
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -