Autor Beitrag
boyington
Hält's aus hier
Beiträge: 2



BeitragVerfasst: Do 19.04.12 22:19 
Hallo liebe Delphi Fans,
also ich bin Delphi-Anfänger und muss ein Delphiprogramm schreiben, das CAD-Dateien im STL-Format (Binär) öffnet und 3D-Modell von diesem Bauteil zeichnet, anschließend kann man mit Mouse-Click einen beliebigen Bereich direkt auf dem angezeigten 3D-Modell markieren (der Bereich muss auf der Oberfläche des Bauteils liegen).

Das Programm muss ich später als Entgratprogramm erweitern, nach der Markierung des zu entgratenden Bereiches vom Bauteil sagt das Entgratprogramm dem KUKA Industrieroboter, wo der genau am Bauteil entgraten soll. Natürlich das mache ich später.

Nun beschäfige ich mich nur mit ersten 3 kleinen Aufgaben:
1. STL-Datei (Binär) öffnen
2. mit Hilfe von Direct3D das 3D-Modell zeichnen und anzeigen.
3. den Bereich auf der Oberfläche des 3D-Modells markieren und dann die Koordinaten anzeigen.

1 und 2 habe ich schon gemacht, aber für 3, habe ich im Moment keine Idee, wie ich es realisieren soll, deshalb bitte ich euch um Hilfe

vielen Dank im Voraus!

Gruss
Lee

Moderiert von user profile iconMartok: Beiträge zusammengefasst

Weiß nicht, ob es besser wäre, die Quelltexte von meinem Programm hier zu posten.

Inhalt von KRL_Gen.dpr
----------------------------------------
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
program KRL_Gen;

uses
  Forms,
  Main in '..\KRL_Gen_mit Schiebregler\Main.pas' {frmMain},
  Visu in 'Visu.pas' {frmVisu};

{$R *.RES}

begin
  Application.Initialize;
  Application.CreateForm(TfrmMain, frmMain);
  Application.CreateForm(TfrmVisu, frmVisu);
  Application.Run;
end.


Moderiert von user profile iconMartok: Delphi-Tags hinzugefügt

Moderiert von user profile iconMartok: Beiträge zusammengefasst

Inhalt von Main.pas
-----------------------------
ausblenden volle Höhe Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
72:
73:
74:
75:
76:
77:
78:
79:
80:
81:
82:
83:
84:
85:
86:
87:
88:
89:
90:
91:
92:
93:
94:
95:
96:
97:
98:
99:
100:
101:
102:
103:
104:
105:
106:
107:
108:
109:
110:
111:
112:
113:
114:
115:
116:
117:
118:
119:
120:
121:
122:
123:
124:
125:
126:
127:
128:
129:
130:
131:
132:
133:
134:
135:
136:
137:
138:
139:
140:
141:
142:
143:
144:
145:
146:
147:
148:
149:
150:
151:
152:
153:
154:
155:
156:
157:
158:
159:
160:
161:
162:
163:
164:
165:
166:
167:
168:
169:
170:
171:
172:
173:
174:
175:
176:
177:
178:
179:
180:
181:
182:
183:
184:
185:
186:
187:
188:
189:
190:
191:
192:
193:
194:
195:
196:
197:
198:
199:
200:
201:
202:
203:
204:
205:
206:
207:
208:
209:
210:
211:
212:
213:
214:
215:
216:
217:
218:
219:
220:
221:
222:
223:
224:
225:
226:
227:
228:
229:
230:
231:
232:
233:
234:
235:
236:
237:
238:
239:
240:
241:
242:
243:
244:
245:
246:
247:
248:
249:
250:
251:
252:
253:
254:
255:
256:
257:
258:
259:
260:
261:
262:
263:
264:
265:
266:
267:
268:
269:
270:
271:
272:
273:
274:
275:
276:
277:
278:
279:
280:
281:
282:
283:
284:
285:
286:
287:
288:
289:
290:
291:
292:
293:
294:
295:
296:
297:
298:
299:
300:
301:
302:
303:
304:
305:
306:
307:
308:
309:
310:
311:
312:
313:
314:
315:
316:
317:
318:
319:
320:
321:
unit Main;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  Menus, Visu, Math, ComCtrls;

type
  TVektor  = record
    x, y, z: real;
  end;
  TDreieck = record
    n: TVektor;
    p: array[1..3of TVektor;
  end;
  TfrmMain = class(TForm)
    mnuMain: TMainMenu;
    mnuDatei: TMenuItem;
    mnuLaden: TMenuItem;
    mnuBeenden: TMenuItem;
    TrackBar1: TTrackBar;
    TrackBar2: TTrackBar;
    procedure mnuBeendenClick(Sender: TObject);
    procedure mnuLadenClick(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
    procedure TrackBar1Change(Sender: TObject);
  private
    { Private-Deklarationen }
    xBauteilMin, xBauteilMax, yBauteilMin, yBauteilMax, zBauteilMin, zBauteilMax: real;
    function STLLaden(Dateiname: TFileName; hList: TList): boolean;
    procedure Abmessungen(hList: TList);
    procedure Zentrieren(hList: TList);
  public
    { Public-Deklarationen }
    Bauteilmittelpunkt: TVektor;
    lstDreiecke: TList;
    hMax: real;
  end;

var
  frmMain: TfrmMain;

implementation

{$R *.DFM}

procedure TfrmMain.mnuBeendenClick(Sender: TObject);
begin
  Close;
end;

procedure TfrmMain.mnuLadenClick(Sender: TObject);
begin
  if STLLaden('3loch.stl', lstDreiecke) then
    MessageDlg('Fehler beim Einlesen.', mtError, [mbOK], 0)
  else begin
    Abmessungen(lstDreiecke);
    Zentrieren(lstDreiecke);
    frmVisu.Show;
  end;
end;

{ Einlesen der STL-Datei }
function TfrmMain.STLLaden(Dateiname: TFileName; hList: TList): boolean;
var AsciiDatei: System.Text;
    BinDatei  : File;
    hStr      : string;
    hDreieck  : ^TDreieck;
    i, Zeile,
    hPos      : integer;
    BinKopf   : array[1..80of char;
    BinAnz    : dword;
    BinWerte  : array[1..12of single;
    BinFrei   : array[1..2of char;
    AnzBinRead: integer;

  function NaechsterWert: real;
  var h: integer;
  begin
    h := pos(' ', hStr);
    while h = 1 do
    begin { falls mehrere Leerzeichen zwischen den Zahlen sind, }
      Delete(hStr, 11); { werden diese entfernt. }
      h := pos(' ', hStr);
    end;
    DecimalSeparator := '.';
    if h > 0 then
    begin
      result := StrToFloat(Copy(hStr, 0, h-1));
      hStr := Copy(hStr, h+1, Length(hStr)-h);
    end
      else result := StrToFloat(hStr);
  end;

begin
  result := false;
  if FileExists(Dateiname) then
  begin
    //DreieckeLoeschen(hList);
    //frmWarten.Caption := 'STL-Datei laden';
    //frmWarten.ProgressBar.Position := 0;
    //frmWarten.ProgressBar.Max := 50000;
    //frmWarten.Show;

    if false then
    begin { STL-Datei im ASCII-Format laden }
      AssignFile(AsciiDatei, Dateiname);
      Reset(AsciiDatei);
      if not(eof(AsciiDatei)) then
      begin
        Readln(AsciiDatei, hStr);
        if Copy(hStr, 05) = 'solid' then
        begin
          Zeile := 1;

          while not(eof(AsciiDatei)) and not(result) do
          begin
            Readln(AsciiDatei, hStr);
            if Pos('endsolid', hStr) = 0 then
            begin
              case Zeile of
              1begin
                   hPos := Pos('facet normal', hStr);
                   if hPos > 0 then
                   begin
                     New(hDreieck);
                     hStr := Copy(hStr, hPos+13, length(hStr)-13-hPos+1);
                     hDreieck^.n.x := NaechsterWert;
                     hDreieck^.n.y := NaechsterWert;
                     hDreieck^.n.z := NaechsterWert;
                     inc(Zeile)
                   end
                   else
                     result := true;
                 end;
              2begin
                   if Pos('outer loop', hStr) > 0 then
                     inc(Zeile)
                   else
                     result := true;
                 end;
              3,
              4,
              5begin
                   hPos := Pos('vertex', hStr);
                   if hPos > 0 then
                   begin
                      hStr := Copy(hStr, hPos+7, length(hStr)-7-hPos+1);
                      hDreieck^.p[Zeile-2].x := NaechsterWert;
                      hDreieck^.p[Zeile-2].y := NaechsterWert;
                      hDreieck^.p[Zeile-2].z := NaechsterWert;
                      inc(Zeile);
                   end
                   else
                     result := true;
                 end;
              6begin
                   if Pos('endloop', hStr) > 0 then
                     inc(Zeile)
                   else
                     result := true;
                 end;
              7begin
                   if Pos('endfacet', hStr) > 0 then
                   begin
                     hList.Add(HDreieck); //lstDreiecke.Add(hDreieck);
                     Zeile := 1
                   end
                   else
                     result := true;
                 end;
              end;
            end;
            //if frmWarten.ProgressBar.Position = 50000 then
            //  frmWarten.ProgressBar.Position := 0
            //else
            //  frmWarten.ProgressBar.Position := frmWarten.ProgressBar.Position + 1;
            //Application.ProcessMessages;
          end{ while }
        end
        else
          result := true; { solid am Anfang fehlt }
      end
      else
        result := true; { Datei ist leer }
      CloseFile(AsciiDatei);
    end
    else begin { STL-Datei im Bin鋜format laden }
      AssignFile(BinDatei, Dateiname);
      Reset(BinDatei, 1);
      BlockRead(BinDatei, BinKopf, SizeOf(BinKopf), AnzBinRead);
      if AnzBinRead = SizeOf(BinKopf) then
      begin
        BlockRead(BinDatei, BinAnz, SizeOf(BinAnz), AnzBinRead);
        if AnzBinRead = SizeOf(BinAnz) then
        begin
          //frmWarten.ProgressBar.Max := BinAnz;
          for i := 1 to BinAnz do
          begin
            BlockRead(BinDatei, BinWerte, SizeOf(BinWerte), AnzBinRead);
            if AnzBinRead = SizeOf(BinWerte) then
            begin
              BlockRead(BinDatei, BinFrei, SizeOf(BinFrei), AnzBinRead);
              if AnzBinRead = SizeOf(BinFrei) then
              begin
                New(hDreieck);
                hDreieck^.n.x    := BinWerte[1];
                hDreieck^.n.y    := BinWerte[2];
                hDreieck^.n.z    := BinWerte[3];
                hDreieck^.p[1].x := BinWerte[4];
                hDreieck^.p[1].y := BinWerte[5];
                hDreieck^.p[1].z := BinWerte[6];
                hDreieck^.p[2].x := BinWerte[7];
                hDreieck^.p[2].y := BinWerte[8];
                hDreieck^.p[2].z := BinWerte[9];
                hDreieck^.p[3].x := BinWerte[10];
                hDreieck^.p[3].y := BinWerte[11];
                hDreieck^.p[3].z := BinWerte[12];
                hList.Add(hDreieck); //lstDreiecke.Add(hDreieck);
              end
              else
                result := true;
            end
            else
              result := true;
            //frmWarten.ProgressBar.Position := i;
            //Application.ProcessMessages;
          end{ for }
        end
        else
          result := true
      end
      else
        result := true;
      CloseFile(BinDatei);
    end;

    //frmWarten.Hide;
    (*if result then
      DreieckeLoeschen(hList)
    else begin
      //mmoInfoSTL.Lines.Clear;
      mmoInfoSTL.Lines.Add(IntToStr(hList.Count) + ' Dreiecke geladen.');
    end;*)

  end { FileExists }
  else
    result := true;
end;

procedure TfrmMain.FormCreate(Sender: TObject);
begin
  lstDreiecke := TList.Create;
end;

procedure TfrmMain.FormDestroy(Sender: TObject);
var hDreieck: ^TDreieck;
    i: integer;
begin
  for i := 0 to lstDreiecke.Count-1 do
  begin
    hDreieck := lstDreiecke[i];
    Dispose(hDreieck);
  end;
  lstDreiecke.Free;
end;

procedure TfrmMain.Abmessungen(hList: TList);
var i, j: integer;
    hDreieck: ^TDreieck;
begin
  DecimalSeparator := '.';
  xBauteilMin := 1e30;
  yBauteilMin := 1e30;
  zBauteilMin := 1e30;
  xBauteilMax := -1e30;
  yBauteilMax := -1e30;
  zBauteilMax := -1e30;
  for i := 0 to hList.Count-1 do
  begin
    hDreieck := hList[i];
    for j := 1 to 3 do
    begin { minimale und maximale Koordinaten im Bauteil suchen }
      xBauteilMin := Min(xBauteilMin, hDreieck^.p[j].x);
      yBauteilMin := Min(yBauteilMin, hDreieck^.p[j].y);
      zBauteilMin := Min(zBauteilMin, hDreieck^.p[j].z);
      xBauteilMax := Max(xBauteilMax, hDreieck^.p[j].x);
      yBauteilMax := Max(yBauteilMax, hDreieck^.p[j].y);
      zBauteilMax := Max(zBauteilMax, hDreieck^.p[j].z);
    end;
  end;
  hMax := Max(xBauteilMax - xBauteilMin, yBauteilMax - yBauteilMin);
  hMax := Max(hMax, zBauteilMax - zBauteilMin);
end;

procedure TfrmMain.Zentrieren(hList: TList);
var i, j: integer;
    hDreieck: ^TDreieck;
begin
  Bauteilmittelpunkt.x := (xBauteilMin + xBauteilMax) / 2;
  Bauteilmittelpunkt.y := (yBauteilMin + yBauteilMax) / 2;
  Bauteilmittelpunkt.z := (zBauteilMin + zBauteilMax) / 2;
  for i := 0 to hList.Count-1 do
  begin
    hDreieck := hList[i];
    for j := 1 to 3 do
    begin
      hDreieck^.p[j].x := hDreieck^.p[j].x - Bauteilmittelpunkt.x;
      hDreieck^.p[j].y := hDreieck^.p[j].y - Bauteilmittelpunkt.y;
      hDreieck^.p[j].z := hDreieck^.p[j].z - Bauteilmittelpunkt.z;
    end;
  end;
end;

procedure TfrmMain.TrackBar1Change(Sender: TObject);
begin
  frmVisu.D3DRender;
end;

end.


Moderiert von user profile iconMartok: Delphi-Tags hinzugefügt

Moderiert von user profile iconMartok: Beiträge zusammengefasst

Inhalt von Visu.pas
-------------------------
ausblenden volle Höhe Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
72:
73:
74:
75:
76:
77:
78:
79:
80:
81:
82:
83:
84:
85:
86:
87:
88:
89:
90:
91:
92:
93:
94:
95:
96:
97:
98:
99:
100:
101:
102:
103:
104:
105:
106:
107:
108:
109:
110:
111:
112:
113:
114:
115:
116:
117:
118:
119:
120:
121:
122:
123:
124:
125:
126:
127:
128:
129:
130:
131:
132:
133:
134:
135:
136:
137:
138:
139:
140:
141:
142:
143:
144:
145:
146:
147:
148:
149:
150:
151:
152:
153:
154:
155:
156:
157:
158:
159:
160:
161:
162:
163:
164:
165:
166:
167:
168:
169:
170:
171:
172:
173:
174:
175:
176:
177:
178:
179:
180:
181:
182:
183:
184:
185:
186:
187:
188:
189:
190:
191:
192:
193:
194:
195:
196:
197:
198:
199:
200:
201:
202:
203:
204:
205:
206:
207:
208:
209:
210:
211:
212:
213:
214:
215:
216:
217:
218:
219:
220:
221:
222:
223:
224:
225:
226:
227:
228:
229:
230:
231:
232:
233:
234:
235:
236:
237:
238:
239:
240:
241:
242:
243:
244:
245:
246:
247:
248:
249:
250:
251:
252:
253:
254:
255:
256:
257:
258:
259:
260:
261:
262:
263:
264:
265:
266:
267:
268:
269:
270:
271:
272:
273:
274:
275:
276:
277:
278:
279:
280:
281:
282:
283:
284:
285:
286:
287:
288:
289:
290:
291:
292:
293:
294:
295:
296:
297:
298:
299:
300:
301:
302:
303:
304:
305:
306:
307:
308:
unit Visu;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  Direct3D8, d3dx8, ExtCtrls, ComCtrls, StdCtrls, KEditInt, Math;

const
  Fovy = Pi/50// Öffnungswinkel des Sichtkegels (Field of view)

type
  // Unsere Struktur, in der wir die Dreiecke speichern
  TMyVertex = packed record
    x, y, z, { Postion }
    nx, ny, nz: single; { Normalenvektor }
    color     : dword;  { Farbe des Vertex }
  end;

const
  // Beschreibung des Vertextyps (siehe Lektion 5)
  D3D8T_CUSTOMVERTEX : dword = D3DFVF_XYZ or D3DFVF_DIFFUSE or D3DFVF_NORMAL {D3DFVF_TEX1};

type
  TfrmVisu = class(TForm)
    ppxVisu: TPaintBox;
    procedure FormCreate(Sender: TObject);
    procedure FormShow(Sender: TObject);
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
    procedure FormPaint(Sender: TObject);
    procedure FormDeactivate(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
  private
    { Private-Deklarationen }
    // Direct3D Interfaces (siehe Lektion 5)
    lpd3d            : IDIRECT3D8;
    lpd3ddevice      : IDirect3DDevice8;
    D3DDevCaps       : TD3DCaps8;
    Licht: D3DLIGHT8;
    BauteilVB  : IDirect3DVertexBuffer8; // Vertexbuffer für Bauteil
    HwVertexProcess: boolean;
    Bauteil: array of TMyVertex; { Dreiecke des Bauteils }
    procedure FatalError(hr : HResult; FehlerMsg : string);
    procedure D3DInit;
    procedure D3DShutdown;
    procedure D3DInitScene;
    procedure D3DKillScene;
  public
    { Public-Deklarationen }
    Eye: TD3DXVECTOR3;
    procedure D3DRender;
  end;

var frmVisu: TfrmVisu;

implementation

uses Main;

{$R *.DFM}

procedure TfrmVisu.FormCreate(Sender: TObject);
begin
  lpd3d       := nil;
  lpd3ddevice := nil;
  BauteilVB   := nil;
end;

// Fataler Fehler. Meldung und Programmende
procedure TfrmVisu.FatalError(hr : HResult; FehlerMsg : string);
var
  s : string;
begin
  if hr<>0 then s:=D3DXErrorString(hr)+#13+FehlerMsg else s:=FehlerMsg;
  D3DKillScene;
  D3DShutdown;
  MessageDlg(s,mtError,[mbOK],0);
  Close;
end;

// Mit dieser Funktion initialisieren wir D3D
procedure TfrmVisu.D3DInit;
var
  hr    : HRESULT;
  d3dpp : TD3DPRESENTPARAMETERS;
  d3ddm : TD3DDISPLAYMODE;
  vp    : integer;
  i, j, k: integer;
  hDreieck: ^TDreieck;
begin
  SetLength(Bauteil, 3*(frmMain.lstDreiecke.Count));
  k := 0;
  for i := 0 to frmMain.lstDreiecke.Count-1 do
  begin
    hDreieck := frmMain.lstDreiecke[i];
    for j := 1 to 3 do
    begin
      Bauteil[k].x := hDreieck^.p[j].x;
      Bauteil[k].y := hDreieck^.p[j].y;
      Bauteil[k].z := -hDreieck^.p[j].z; { Übergang von rechts- zum linksh鋘digem Koordinatensystem }
      Bauteil[k].nx := hDreieck^.n.x;
      Bauteil[k].ny := -hDreieck^.n.y;
      Bauteil[k].nz := -hDreieck^.n.z;
      Bauteil[k].color := $FFFFFF;
      inc(k);
    end;
  end;

  //Erstelle Direct3D! Mu?immer als erstes erstellt werden
  //Immer D3D_SDK_VERSION als Version setzen
  lpd3d:=Direct3DCreate8(D3D_SDK_VERSION);

  if(lpd3d=nilthen FatalError(0,'Fehler beim Erstellen von Direct3D!');

  // Setze zunächst alle D3DPRESENT_PARAMETERS auf 0
  ZeroMemory(@d3dpp,sizeof(d3dpp));
  with d3dpp do begin
    SwapEffect:=D3DSWAPEFFECT_DISCARD;
    hDeviceWindow := frmVisu.Handle; // Dies ist unser HWND von TForm

    // Wir brauche einen Z-Buffer also schalten wir ihn ein
    EnableAutoDepthStencil := TRUE;
    AutoDepthStencilFormat := D3DFMT_D16;

    // Initialisieren des Backbuffers
    Windowed := true;
    // Fenster
    hr:=lpd3d.GetAdapterDisplayMode(D3DADAPTER_DEFAULT,d3ddm);
    if failed(hr) then FatalError(hr,'Fehler beim Ermitteln des Dislaymodes');
      BackBufferFormat := d3ddm.Format;
  end;

  // Hardware T&L?
  hr:=lpd3d.GetDeviceCaps(D3DADAPTER_DEFAULT,D3DDEVTYPE_HAL,D3dDevCaps);
  if FAILED(hr) then FatalError(hr,'Fehler beim Abfragen der DevCaps');
  HwVertexProcess:=D3dDevCaps.DevCaps and D3DDEVCAPS_HWTRANSFORMANDLIGHT <> 0;

  if HwVertexProcess then vp:=D3DCREATE_HARDWARE_VERTEXPROCESSING
  else vp:=D3DCREATE_SOFTWARE_VERTEXPROCESSING;

  //Erstellen des D3D-Device
  hr:=lpd3d.CreateDevice(D3DADAPTER_DEFAULT,
                         D3DDEVTYPE_HAL,
                         Handle,
                         vp,
                         d3dpp,
                         lpd3ddevice);
  if FAILED(hr) then FatalError(hr,'Fehler beim Erzeugen des 3D-Device');
end;

// *** D3DShutdown hier werden die Resourcen von D3D wieder freigegeben
procedure TfrmVisu.D3DShutdown;
begin
  if assigned(lpd3ddevice) then lpd3ddevice:=nil;
  if assigned(lpd3d) then lpd3d:=nil;
end;

// Initialisieren der Szenenobjekte
procedure TfrmVisu.D3DInitScene;
var
  hr            : HRESULT;
  vbVertices    : pByte;
  ProjMatrix    : TD3DXMATRIX;
  Gr: Integer;
  EntfLicht : single;
begin
  Gr := SizeOf(TMyVertex) * Length(Bauteil);
  if assigned(lpd3ddevice) then with lpd3ddevice do begin
    // Vertex Buffer für Würfel
    hr:=CreateVertexBuffer (Gr,
                            D3DUSAGE_WRITEONLY,  // Nur Schreibzugriffe
                            D3D8T_CUSTOMVERTEX,  // Unser Vertex
                            D3DPOOL_MANAGED,
                            BauteilVB);              // Pointer zu unserem Buffer
    if FAILED(hr) then FatalError(hr,'Fehler beim Erstellen des Vertex-Buffers');

    // Nun kopieren wir unsere Vertizes in den Buffer
    // Wir müssen es zuvor mit Lock festhalten, um es bearbeiten zu können
    with BauteilVB do begin
      hr:=Lock(0,Gr,vbVertices,0);
      if FAILED(hr) then FatalError(hr,'Fehler beim Locken des Vertex-Buffers');
      // Hier wird der Vertexbuffer kopiert.
      Move(Bauteil[0],vbVertices^,Gr);
      // Und wieder loslassen
      Unlock;
    end;

    Eye.x := 0;
    Eye.y := 0;
    Eye.z := -frmMain.hMax/2/tan(Fovy/2);
    EntfLicht := 2*Eye.z;

    Licht._Type := D3DLIGHT_DIRECTIONAL;    // make the light type 'directional light'
    Licht.Diffuse := D3DXCOLOR(1111);    // set the light's color
    Licht.Position := D3DXVECTOR3(EntfLicht, 00);
    Licht.Direction := D3DXVECTOR3(111);
    SetLight(0, Licht);
    LightEnable(0, true);

    Licht.Position := D3DXVECTOR3(0, -EntfLicht, 0);
    Licht.Direction := D3DXVECTOR3(-1, -1, -1);
    SetLight(1, Licht);
    LightEnable(1, true);

    // Z-Buffer beim Rendern einschalten
    SetRenderState(D3DRS_ZENABLE, D3DZB_TRUE);

    // Erstelle eine Projektionsmatrix
    D3DXMatrixPerspectiveFovLH(ProjMatrix,  // Resultierende Matrix
                               Fovy,        // Öfnungswinkel des Sichtkegels
                               ppxVisu.Width{frmVisu.Width}/ppxVisu.Height{frmVisu.Height},     // Seitenverhältnis der Ansicht
                               1.0,         // Mindeste N鋒e                               10000.0);     // Maximal sichtbare Entfernung
    SetTransform(D3DTS_PROJECTION, ProjMatrix);
  end;
end;

procedure TfrmVisu.D3DKillScene;
begin
  BauteilVB := nil;
end;

// Rendern der Szene
procedure TfrmVisu.D3DRender;
var
  ViewMatrix, RotMatrix, RotMatrixX, RotMatrixY, WorldMatrix: TD3DXMATRIX;
  At, Up: TD3DXVECTOR3;
begin
  if assigned(lpd3ddevice) then with lpd3ddevice do begin
    Clear(0,           // Wieviel Rechtecke löschen? 0 Löscht alle
          nil,         // Pointer zu den Rechtecken. nil = Ganzer Bildschirm
          D3DCLEAR_TARGET or D3DCLEAR_ZBUFFER,
          D3DCOLOR_XRGB(200,0,100), //Hintergrundfarbe
          1,           // Lösche ZBuffer ( Wir haben momentan noch keinen )
          0 );

    if SUCCEEDED(BeginScene) then begin

      At := D3DXVECTOR3(00, -1); // look
      Up := D3DXVECTOR3(010);
      D3DXMatrixLookAtLH (ViewMatrix, Eye, At, Up); // Hier erstellen wir unsere SichtMatrix

      { neg. Winkel, da wir den Beobachter rotieren lassen (aber bei Y nicht?) }
      (*if frmMain.mnuRotKoerper.Checked then
      begin
        case frmRotation.cbxRotAchse.ItemIndex of
          0: D3DXMatrixRotationX(RotMatrix, pi/180*frmRotation.trbRot.Position);
          1: D3DXMatrixRotationY(RotMatrix, pi/180*frmRotation.trbRot.Position);
        end;
      end
      else begin*)

//        D3DXMatrixIdentity(RotMatrix);
        D3DXMatrixRotationX(RotMatrixX, frmMain.TrackBar1.Position/180*pi);
        D3DXMatrixRotationY(RotMatrixY, frmMain.TrackBar2.Position/180*pi);
      //end;

      D3DXMatrixMultiply(RotMatrix, RotMatrixX, RotMatrixY);

      D3DXMatrixMultiply(ViewMatrix, RotMatrix, ViewMatrix);
      D3DXMatrixIdentity(WorldMatrix);
      SetTransform(D3DTS_VIEW, ViewMatrix);
      SetTransform(D3DTS_WORLD, WorldMatrix);
      // Vertex Typ einstellen
      SetVertexShader(D3D8T_CUSTOMVERTEX);

      // Stream auf Vertexbuffer für Würfel setzen
      SetStreamSource(0,BauteilVB,sizeof(TMyVertex));
      DrawPrimitive(D3DPT_TRIANGLELIST, 0, frmMain.lstDreiecke.Count);

      SetStreamSource(0, BauteilVB, SizeOf(TMyVertex));
      SetRenderState(D3DRS_CULLMODE, D3DCULL_CW);

      EndScene;
    end;
    Present(nil,nil,0,nil); // Zeige Resultate auf dem Bildschirm
  end;
end;

procedure TfrmVisu.FormShow(Sender: TObject);
begin
  (*Width  := frmOptionen.ediGroesse.Wert + Width - ClientWidth;
  Height := frmOptionen.ediGroesse.Wert + Height - ClientHeight;*)

  D3DInit;     // Initialisieren von D3D
  D3DInitScene;
  D3DRender;   // Darstellung der 3D-Szene
end;

procedure TfrmVisu.FormClose(Sender: TObject; var Action: TCloseAction);
begin
  D3DKillScene; // Lösche die 3D-Szene bevor wir D3D beenden
  D3DShutdown;  // Lösche D3D
end;

procedure TfrmVisu.FormPaint(Sender: TObject);
begin
  D3DRender;
end;

procedure TfrmVisu.FormDeactivate(Sender: TObject);
begin
  D3DRender;
end;

procedure TfrmVisu.FormDestroy(Sender: TObject);
begin
  Close;
end;

end.


Moderiert von user profile iconMartok: Delphi-Tags hinzugefügt
boyington Threadstarter
Hält's aus hier
Beiträge: 2



BeitragVerfasst: Do 19.04.12 22:39 
Hier lege ich Screenshot.jpg von diesem Programm bei.

Mit 2 Schiebreglern kann man das 3D-Modell um X- und Y-Achse drehen!

Übrigens, das Programm hab ich mit Delphi5 getestet, aber bei Delphi7 bekomme ich irgendwelche Fehlermeldung.
Einloggen, um Attachments anzusehen!