⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 unit1.pas

📁 在Delphi利用opengl调用3ds文件并且添加背景帖图。
💻 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 + -