Autor Beitrag
Aya
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 1964
Erhaltene Danke: 15

MacOSX 10.6.7
Xcode / C++
BeitragVerfasst: Do 10.04.03 18:26 
Hi,

wie angekündigt gibt es hier nun mein OpenGL Tutorial worauf der kleine OpenGL Kurs aufbauen wird.. ;)

Über die geschichte etc von OpenGL werde ich mal nichts erzählen (weiß auchnet sonderlich viel darüber :oops: ), und komme gleich richtig zur sache.

Eine sache noch für die leute hier, die OpenGL schon besser können... dieses Tutorial ist für anfänger gedacht! Einige dinge sind evtl umständlich, oder unpassend gemacht.. aber es ist so leichter den sinn zu verstehen ;)

Vorbereitung:
  • Delphi starten und ein neues Projekt anlegen
  • OpenGL12.pas und Textures.pas hier runterladen.
  • OpenGL12 in die Uses der Form packen

Der erste schritt:
Bevor wir mit OpenGL arbeiten können, muß es ersteinmal Initialisiert werden, hierfür benötigen wir 2 Variablen:

ausblenden Delphi-Quelltext
1:
2:
3:
var
  h_DC: hDC;
  hRC: HGLRC;


in welchen die Adresse des RenderContext für unsere OpenGL Scene gespeichert wird.

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
  InitOpenGL;
  h_DC:=GetDC(Handle);
  SetDCPixelFormat(h_DC);
  hRC:=wglCreateContext(h_DC);
  wglMakeCurrent(h_DC,hRC);


Diese 5 Zeilen sollten in's OnCreate Ereigniss der Form.
InitOpenGL:
Wird erst seit der OpenGL12.pas benötigt und ist wichtig, damit die Variablen, Objekte etc der OpenGL12.pas erzeugt werden.

h_DC:=GetDC(Handle);:
Hier holen wir uns den DeviceContext von unserem Form.

SetDCPixelFormat(h_DC);:
Hier wird das PixelFormat der Scene eingestellt (siehe unten).

hRC:=wglCreateContext(h_DC);:
Erstellt den OpenGL RenderContext (Befehle die mit wgl, bzw gl beginnen sind OpenGL spezifische Befehle. wgl ist zudemnoch Windows Spezifisch)

wglMakeCurrent(h_DC,hRC);:
Diese Zeile gibt an welches der aktuelle RenderContext ist, am anfang eher nebensächlich da wir sowieso nur ein OpenGL Fenster haben.. aber wenn ihr mal ein Programm schreibt wo es mehrere OpenGL Fenster gibt werdet ihr drauf zurückkommen ;)

So, damit währe die Initialisierung schon fast geschafft, fehlt nurnoch die procedur SetDCPixelFormat. Das meißte hier sollte schon vom Namen der Variable her klar sein... ;)

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:
  procedure SetDCPixelFormat(Handle: HDC);
  var
    nPixelFormat: GLUint;
  const
    pfd: PIXELFORMATDESCRIPTOR = (
        nSize: sizeof( PIXELFORMATDESCRIPTOR );
        nVersion: 1;
        dwFlags: PFD_DRAW_TO_WINDOW
        or PFD_SUPPORT_OPENGL
        or PFD_DOUBLEBUFFER;
        iPixelType: PFD_TYPE_RGBA;
        cColorBits: 16;
        cRedBits: 0;
        cRedShift: 0;
        cGreenBits: 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
    );
  begin
    nPixelFormat:=ChoosePixelFormat(h_DC, @pfd);
    SetPixelFormat(h_DC,nPixelFormat,@pfd);
  end;


und damit wäre die Initialisierung fertig :D

Als nächstes schreiben wir uns eine kleine eigene Procedur, namens InitGL welche so aussehen sollte:

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
procedure TForm1.InitGL;
begin
  glClearColor(0,0,0,0);
  glClearDepth(1);
  glDepthFunc(GL_LESS);
  glShadeModel(GL_SMOOTH);
  glEnable(GL_DEPTH_TEST);

  glViewport(0,0,Width,Height);
  glMatrixMode(GL_PROJECTION);
  glLoadIdentity;
  gluPerspective(45,Width/Height,1,100);
  glMatrixMode(GL_MODELVIEW);
end;


glClearColor:
Hiermit bestimmen wir die Hintergrundfarbe unserer Scene. (Ganz genau genommen wird wenn dieser Befehl aufgerufen wird die komplette Scene it der hier angegebenen Farbe übermalt)

glClearDepth:
Hiermit wird unser Tiefenbuffer geleert. (Komme ich später genauer drauf zurück)

glDepthFunc:
Der hier verwendete Parameter gibt an, wie der TiefenTest von OpenGL Funktioniert. GL_LESS z.B. bedeutet das die Objekte die näher beim Betrachter liegen die weiter entfernten überdecken. Bei GL_GREATER wäre es z.B. genau andersrum.

glShadeModel:
Gibt an welche ShadingTechnik verwendet werden soll. GL_SMOOTH wird für weiche kanten benutzt, GL_FLAT für harte.

glEnable:
Mit glEnable werden div. funktionen von OpenGL aktiviert, in diesem fall wird GL_DEPTH_TEST aktiviert, also unser Tiefentest. (Welcher dafür verantwortlich ist das weiter entfernte objekte von den näheren überdeckt werden)

glViewport;
Viewport ist gibt die fläche an, in der die Scene angezeigt wird. i.d.R. wählt man hier die komplette fläche, aber es kann u.U. sinnvoll sein mal nur einen kleinen ausschnitt zu benutzen.

glMatrixMode:
Stellt unsere WeltMatrix um. In dem fall auf die ProjektionsMatrix.
mit GL_MODELMATRIX kommen wir zurück in die ModellierungsMatrix.

glLoadIdentity:
Mit glLoadIdentity wird die Scene zurück auf 0 gesetzt. Also, wenn man die Scene rotiert und verschiebt, kann man hiermit einfach auf den ausgangspunkt bei 0 zurückgehen.

gluPerspective:
Bedeutet das wir eine PerspektivKamera benutzen (keine Orthogonale). Der erste Parameter gibt den KameraWinkel an, der zweite das verhältniss.
Parameter 3 und 4 sind die sogenannte clipping plane... also alles was ausserhalb der ClippingPlane ist, wird nicht gerendert (in dem fall alles was näher als 1 Einheit, oder weiter weg als 100 Einheiten ist)

So, nun als letztes noch eine Procedur DrawScene, und alles ist perfekt ;)

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
procedure TForm1.DrawScene;
begin
  glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT);
  glLoadIdentity;
  //Hier wird später die Scene gezeichnet.

  SwapBuffers(h_DC);
end;


glClear:
Leert wie der name schon sagt die Scene, in diesem fall wird die Scene mit der Farbe die bei der Initialisierung bei glClearColor angegeben wurde übermalt und der TiefenBuffer geleert.

glLoadIdentity:
Setzt unsere Scene wieder auf den 0 Punkt zurück. (siehe oben)

SwapBuffers:
Ist nur wichtig wenn ihr bei eurem PixelFormat DoubleBuffered eingestellt habt, hiermit wird zwischen den beiden Buffern hin und her gewechselt.

So, als allerletztes müßen wir die 2 Proceduren noch aufrufen.
InitGL wird am ende vom OnCreate ereigniss aufgerufen.
DrawScene im OnIdle der Scene.

Hierfür benutzt ihr am besten für den anfang die TApplication Komponente, ein doppelklick auf den OnIdle Event der Kompo:

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
procedure TForm1.ApplicationEvents1Idle(Sender: TObject;
  var Done: Boolean);
begin
  DrawScene;
  Done:=False;
end;


Done müßt ihr auf alle fälle auf False setzen, da sonst das OnIdle Event nicht wieder aufgerufen wird. (Siehe OnlineHilfe)

Wenn ihr jetzt auf F9 drückt solltet ihr eine leere OpenGL Scene vor euch haben... ;)

Ok, aber eine leere Scene ist nicht so das wahre... nicht wahr..? :)
Kommen wir also nu ndazu, wie wir die Scene füllen.

Als erstes mal gibt es 3 wichtige Befehle:

glTranslate(X, Y, Z: Single);
Wie der Name schon sagt wird hiermit die Scene um die angegeben Koordinaten verschoben.
glTranslate(2,0,0) würde unsere Scene z.B. um 2 Einheiten in X-Richtung verschieben.

glRotate(Angle, X, Y, Z: Single);
Hiermit rotieren wir die Scene um den angegeben Winkel (Angle) auf der angegeben Achse.
um die Scene z.B. um 27° auf der Z Achse zu drehen würde es so aussehen: glRotate(27,0,0,1);

glScale(X, Y, Z: Single);
Hiermit Scalieren (Zoomen) wir unsere Scene... z.B:
glScale(2,2,2) würde alle Objekte doppelt so groß zeichnen wie sie sind.
glScale(0.5,0.5,0.5) alle nur halb so groß.
oder glScale(2,1,1) würde das Objekt auf der X-Achse strecken.

Diese 3 Befehle werden wohl die sein, die euch am anfang mit am häufigsten begegnen... auch wenn sie für leute die nochnie irgendwas mit 3D Kram gemacht haben sehr verwirrend sein können.. wenn ihr es erstmal ausprobiert habt, kapiert ihr da schon ;) (Die die 3D Programme benutzen sind hier klar im Vorteil *g*)

Als nächstes kommen wir zu den Farben...
Eine farbe wird in OpenGL mit glColor3f angegeben, wobei das 3f am ende dafür steht das hier 3 Parameter vom typ f (float) erwartet werden. ein 2i würde bedeutetn das 2 Integer Werte erwartet werden.. 4ub = 4 Paratemer vom typ Bate.. ;)

ok, glColor3f erwartet also 3 Single-Werte.
Das was viele hier verwirren wird ist das Farbschema von OpenGL, denn Farben werden hier in der regel nicht von 0..255 vergeben, sondern nur von 0..1
Ein paar Beispiele:
Weiß: 255,255,255 ist in OpenGL 1,1,1
Schwarz: 0,0,0 = 0,0,0
Grün: 0,255,0 = 0,1,0
HellesRot: 0,128,0 = 0,0.5,0

etc etc etc... Im grudne ganz einfach ;)
Für die, die sich daran absolut nicht gewöhnen können/wollen bleibt noch glColor3ub wo als Parameter herkömmliche Byte Werte erwartet werden... (aber ich würde euch empfehlen euch gleich an den OpenGL standard zu gewöhnen, da er an anderen stellen öffters mal in dieser Form gebraucht wird)

Kommen wir also nun zum eigentlichen Zeichnen unserer Scene.
In OpenGL kann man nur folgene grunddinge Zeichnen:
    Einen einfachen punkt (Pixel) (GL_POINTS)
    Eine Linie (GL_LINES)
    Mehrere Verbundene Linien (GL_LINE_STRIP)
    Mehrere Verbundene Linien wo die Anfangs Koordinate = End Koordinate (GL_LINE_LOOP)
    Ein Dreieck (GL_TRIANGLES)
    Mehrere Verbundene Dreiecke (GL_TRIANGLE_STRIP)
    Ein "Dreiceksfächer" (GL_TRIANGLE_FAN)
    Ein Quadrat (GL_QUADS)
    Mehrere Verbundene Dreiecke (GL_QUAD_STRIP)
    Ein Polygon (GL_POLYGON)


uns interressiert als erstesmal nur das einfache Quadrat.

ausblenden Delphi-Quelltext
1:
2:
3:
glBegin(GL_QUADS);
  //Koordinaten
glEnd;


Hier teilen wir OpenGL mit das wir gleich ein Quad Zeichnen möchten (glBegin), und wenn wir fertig sind damit (glEnd)

Die Koordinaten werden in OpenGL mit glVertex übergeben, da wir das ganze 3D und nicht 2D haben möchten benutzen wir glVertex3f = 3 Float Parameter für X, Y und Z.

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
glBegin(GL_QUADS);
  glVertex3f(1,-1,-5);
  glVertex3f(1,1,-5);
  glVertex3f(-1,1,-5);
  glVertex3f(-1,-1,-5);
glEnd;


Hier übergeben wir OpenGL also 4x3 Koordinaten, welche die Eckpunkte unseres Quadrates ergeben.
Das -5 am ende ist unsere Z Koordinate. Wenn wir hier 0 hinmachen würden, würden wir nix sehen da wir dann in dem Quadrat drinständen. Deswegen bewegen wir die Koordinate in den Bildschrim hinein um 5 Einheiten.

Das ganze könnte man aber auch so lösen:

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
glTranslate(0,0,-5);
glBegin(GL_QUADS);
  glVertex3f(1,-1,0);
  glVertex3f(1,1,0);
  glVertex3f(-1,1,0);
  glVertex3f(-1,-1,0);
glEnd;


Wir schieben die ganze Scene also ersteinmal in den Bildschirm hinein und zeichen dann das Quad.

Wenn ihr jetzt F9 drückt, solltet ihr ein Weißes Quadrat in der mitte eurer Scene sehen.

Machen wir das ganze mal ein wenig Bunt, um zu verdeutlichen welcher Koordinate wo auf dem Bildschirm ist ;)

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
glTranslate(0,0,-5);
glBegin(GL_QUADS);
  glColor3f(1,0,0);  //Rot
  glVertex3f(1,-1,0);
  glColor3f(1,1,0);  //Gelb
  glVertex3f(1,1,0);
  glColor3f(0,1,0);  //Grün
  glVertex3f(-1,1,0);
  glColor3f(0,0,1);  //Blau
  glVertex3f(-1,-1,0);
glEnd;


Hier weisen wir also jeder Koordinate eine eigene Farbe zu, womit recht gut verdeutlicht wird welche Koordinate wo gezeichnet wird ;)

Wenn wir jetzt das ganze Quad z.B. Rot haben wollen, brauchen wir nicht jeder Koordinate ihre eigene Farbe zuzuweisen, sondern können am anfang vor dem Zeichnen einmal glColor3f(1,0,0) aufrufen, dann wird die Farbe rot solange benutzt bis man wieder eine andere farbe wählt.

So, als nächstes wollen wir unser Quad mal rotieren lassen, ok? :)
Hierfür brauchen wir als erstes eine Globale Variable.

ausblenden Delphi-Quelltext
1:
2:
var
  RotateX: Single;


nun setzen wir hinter unser glTranslate ein glRotate:

ausblenden Delphi-Quelltext
1:
2:
3:
4:
glTranslate(0,0,-5);
glRotate(RotateX,1,0,0);
glBegin(GL_QUADS);
  [...]


Bedeutet, wir drehen unsere Scene auf der X achse um den Wert RotateX.

Jetzt noch diese 3 Zeilen an's ende unserer Draw Procedur:

ausblenden Delphi-Quelltext
1:
2:
3:
RotateX:=RotateX + 1;
if RotateX>360 then
  RotateX:=RotateX - 360;


Hier erhöhen wir also RotateX dauernd um 1, und sobald es größer als 360 ist, ziehen wir 360 ab.

Ein druck auf F9 müßte unser Quad nun rotieren lassen.

Hier solltet ihr nun auch den ersten 3D Effekt sehen :D

So, als letztes für dieses Tutorial werde ich euch nun noch Zeigen wir ihr Texturen verwenden könnt, hierfür braucht ihr die Textures.pas aus dem ZIP (Siehe oben) und müßt diese in das Projekt einbinden.

Der grund warum wir hier eine externe datei verwenden ist ganz einfach, es ist extrem kompliziert sowas selbst zu machen ;)
Ich hab mich die letzten Tage hingesetzt und mal eine Texture-Unit geschrieben, davor habe ich auch immer fremde genommen dafür.

Ok, nachdem wir die Unit nun eingebunden haben, brauchen wir mal wieder eine neue Varbiable:

ausblenden Delphi-Quelltext
1:
  MyTex: TTextur;					


und am Ende von OnCreate (es muß NACH der Initialisation von OpenGL geschehen, da sonst kein Speicher auf der GrafikKarte für die Textur reserviert wird.):

ausblenden Delphi-Quelltext
1:
  MyTex:=TTextur.Create('C:\Programme\Delphi\Bla.bmp');					

Als format gehen hier Bitmaps, JPEG und TGA Dateien.

Bevor wir die Textur nun aber verwenden können, müßen wir unsere Zeichen Routine noch ein wenig abändern. Hier kommt nun der befehl glTexCoord2fzur geltung.

mit glTexCoord2f geben wir die Koordinaten für unsere Textur an, also die TexturKoordinaten ;) Da eine Textur 2D und nicht 3D ist, gibt es hier nur 2 Parameter.

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
glBegin(GL_QUADS);
  glTexCoord2f(1,0); glVertex3f(1,-1,0);
  glTexCoord2f(1,1); glVertex3f(1,1,0);
  glTexCoord2f(0,1); glVertex3f(-1,1,0);
  glTexCoord2f(0,0); glVertex3f(-1,-1,0);
glEnd;


Ihr seht, wir müßen für jede Koordinate des Quadrates auch die TexturKoordinate festlegen. (Spielt damit einfahc mal ein wenig rum, wenn ihr es seht versteht ihr es schon.. ;) )

So, nun müßen wir OpenGL noch mitteilen das wir Texturen benutzen möchten, das tun wir wieder im OnCreate, also bei der Initialisierung der Scene.

ausblenden Delphi-Quelltext
1:
glEnable(GL_TEXTURE_2D);					

Wir aktivieren also Texturierung.

So, nun noch angeben welche Textur wir möchten, und fertig ist's:

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
[...]
glRotate(RotateX,1,0,0);
MyTex.Bind;
glBegin(GL_QUADS);
  [...]


So, ein druck auf F9 sollte euch nun eure Textur auf dem Quad zeigen welches rotiert... ;)

Und ich denke das reicht für den einstieg erstmal... am besten ihr spielt nun ein wenig damit rum, indem ihr z.B. aus 6 Quads einen Würfel bastelt etc.

Oder ihr verändert das RotateX nicht in der RenderLoop, sondern z.B. bei einem druck auf eine Taste.. so das ihr das Quad mit den Tasten rotieren könnt ;) etc etc etc...

Hoffe das tutorial hat euch gefallen.

Au'revoir,
Aya~

PS: Ich will ja nun zu dme Tutorial hier noch einen kleinen IRC Kurs geben, hierzu bitte nur im OffTopic Thread reden, denn hier sollen nur die dinge hin, die für das Tutorial wichtig sind. Also Termin etc für das IRC Treffen wird im OffTopic ausgemacht.

_________________
Aya
I aim for my endless dreams and I know they will come true!


Zuletzt bearbeitet von Aya am Do 10.04.03 23:39, insgesamt 1-mal bearbeitet
mars
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 238

Debian Woody, Win 2000, Win XP
D7 Ent, Kylix 3
BeitragVerfasst: Do 10.04.03 23:34 
Hehe, ist ja ganz einfach :D
Ja, das Tutorial hat Spass gemacht. Danke, Aya. Noch eine kleine Anmerkung: Ich glaube, du solltest die Variable hDC umbenennen, nicht?
Ansonsten sehr gut beschrieben und läuft alles glatt.
Aya Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 1964
Erhaltene Danke: 15

MacOSX 10.6.7
Xcode / C++
BeitragVerfasst: Do 10.04.03 23:37 
mh... stimmt.. jetzt wo du es sagst.... :)

_________________
Aya
I aim for my endless dreams and I know they will come true!
FloFri
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 97



BeitragVerfasst: Fr 11.04.03 00:30 
super tutorial. das beste, was ich bis jetzt zu opengl gesehen habe! ich hoffe auf eine baldige fortsetzung (z.B. über lichter, texturenmatrizen, bumpmapping, runde objekte (kugeln, zylinder), etc.)
Andi1982
ontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic starofftopic star
Beiträge: 497

WinXP HE
D6 Enterprise
BeitragVerfasst: Fr 11.04.03 13:20 
Hi,
also ich habs mir bis jetzt zwar nur mal durchgelesen, aber so wie es aussieht ist das endlich mal was einfaches! Das versteh ja sogar ich endlich mal :D

Werds am wochenende gleich mal durcharbeiten!

Vielen Dank mal von allen dass du dir die Arbeit gemacht hast und dann auch noch so fix!

Cu Andi

_________________
Solange die Bombe tickt ist alles in Ordnung, erst wenn sie damit aufhört wird es problematisch...
mimi
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 3458

Ubuntu, Win XP
Lazarus
BeitragVerfasst: Fr 11.04.03 17:20 
habe es mal ebend ausgedruck;)
(es sind 8 seiten)

_________________
MFG
Michael Springwald, "kann kein englisch...."
t/f
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 70



BeitragVerfasst: Fr 18.04.03 14:38 
Hi Board, hi Aya!

Irgendwas haut nicht hin.

Ich bin gerade soweit, dass ein weißes Rechteck gezichnet werden sollte. Es tut sich aber nichts. Habe ich etwas falsch gemacht? Auf meinem Bildschirm erscheintlich lediglich das normale Form1.

Ich erlaube mir, einfach 'mal hier meinen bisherigen Quellcode zu posten.

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:
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, OpenGL12;

type
  TForm1 = class(TForm)
    procedure FormCreate(Sender: TObject);
    procedure InitGL; 
    procedure DrawScene;
    procedure ApplicationEvents1Idle(Sender: TObject; var Done: Boolean);
  private
    { Private-Deklarationen }
  public
    { Public-Deklarationen }
  end;

procedure SetDCPixelFormat(Handle: HDC);

var
  Form1: TForm1;
  h_DC: hDC; 
  hRC: HGLRC;
  
implementation

{$R *.dfm}

procedure TForm1.FormCreate(Sender: TObject);
begin
InitOpenGL;
h_DC:=GetDC(Handle);
SetDCPixelFormat(h_DC);
hRC:=wglCreateContext(h_DC);
wglMakeCurrent(h_DC,hRC);
InitGL;
end;

procedure TForm1.ApplicationEvents1Idle(Sender: TObject; 
  var Done: Boolean); 
begin 
  DrawScene; 
  Done:=False; 
end;

procedure TForm1.DrawScene;
begin
  glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT);
  glLoadIdentity;

  glTranslate(0,0,-5);
  glBegin(GL_QUADS);
    glVertex3f(1,-1,0);
    glVertex3f(1,1,0);
    glVertex3f(-1,1,0);
    glVertex3f(-1,-1,0);
  glEnd;
  
  SwapBuffers(h_DC); 
end;

procedure TForm1.InitGL;
begin 
  glClearColor(0,0,0,0);
  glClearDepth(1);
  glDepthFunc(GL_LESS);
  glShadeModel(GL_SMOOTH); 
  glEnable(GL_DEPTH_TEST); 

  glViewport(0,0,Width,Height); 
  glMatrixMode(GL_PROJECTION); 
  glLoadIdentity; 
  gluPerspective(45,Width/Height,1,100); 
  glMatrixMode(GL_MODELVIEW); 
end;

procedure SetDCPixelFormat(Handle: HDC);
var
  nPixelFormat: GLUint;
const
  pfd: PIXELFORMATDESCRIPTOR = (
      nSize: sizeof( PIXELFORMATDESCRIPTOR );
      nVersion: 1;
      dwFlags: PFD_DRAW_TO_WINDOW
      or PFD_SUPPORT_OPENGL
      or PFD_DOUBLEBUFFER;
      iPixelType: PFD_TYPE_RGBA;
      cColorBits: 16;
      cRedBits: 0;
      cRedShift: 0;
      cGreenBits: 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
  );
begin
    nPixelFormat:=ChoosePixelFormat(h_DC, @pfd); 
    SetPixelFormat(h_DC,nPixelFormat,@pfd); 
  end;

end.

Compiler-Errors krieg ich keine.

Was ich noch nicht wirklich verstanden habe ist die Funktion ApplicationEvents1Idle ... wann und wo wird sie eigentlich aufgerufen?

greetz
//me
Raphael O.
ontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic starofftopic star
Beiträge: 1596


VS 2013
BeitragVerfasst: Fr 18.04.03 15:20 
du musst im oncreate ereignis folgendes einfügen:
ausblenden Quelltext
1:
ApplicationEvents1Idle:=application.onEventsidle;					
t/f
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 70



BeitragVerfasst: Fr 18.04.03 15:26 
so?

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
procedure TForm1.FormCreate(Sender: TObject);
begin
InitOpenGL;
h_DC:=GetDC(Handle);
SetDCPixelFormat(h_DC);
hRC:=wglCreateContext(h_DC);
wglMakeCurrent(h_DC,hRC);
InitGL;
ApplicationEvents1Idle := application.onEventsidle;
end;

geht nicht...
Compiler hat folgendes geschrieben:
[Fehler] Unit1.pas(40): Undefinierter Bezeichner: 'onEventsidle'
[Fehler] Unit1.pas(40): Nicht genügend wirkliche Parameter
[Fataler Fehler] Project1.dpr(5): Verwendete Unit 'Unit1.pas' kann nicht compiliert werden

... superschnell seid ihr ja hier. Find ich klasse! Ich glaub, das Forum gefällt mir ;)

greetz
//me

Moderiert von user profile iconTino: Quote-Tags hinzugefügt.
t/f
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 70



BeitragVerfasst: Fr 18.04.03 15:45 
(kurze Frage noch: wo kann ich eine Detaillierte übersicht über die Wichtigsten OpenGL-Befehle kriegen? Ich habe bereits einen Blick in die .pas-Datei geworfen, aber die ist mit schier zu lang. :? )
Alibi
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 458

Win2K SP3
Delphi 6 Ent
BeitragVerfasst: Fr 18.04.03 15:45 
Die Zeile muss so lauten:
ausblenden Quelltext
1:
Application.OnIdle := ApplicationEvents1Idle;					
t/f
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 70



BeitragVerfasst: Fr 18.04.03 15:51 
:D *Daumen hoch* klappt! :)
Aya Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 1964
Erhaltene Danke: 15

MacOSX 10.6.7
Xcode / C++
BeitragVerfasst: Fr 18.04.03 17:12 
huhu,

ok.. war ich wohl ein wenig zu spät diesmal ;)

Aber zu der frage wo du ne liste bekommst..
im MSDN oder PSDK sind alle drin beschrieben... oder z.B. auch hier:
pyopengl.sourceforge...anual/reference.html

gibt viele solche seiten :)

Au'revoir,
Aya~

_________________
Aya
I aim for my endless dreams and I know they will come true!
chucky
Hält's aus hier
Beiträge: 5



BeitragVerfasst: Fr 18.04.03 20:54 
Ich würde am anfang jedem empfehlen die leichtere variante zu wählen, ogl zu initialisieren, wodurch pixelformat usw wegfällt. sowas sollte man meiner meinung nach erst später verstehen was das überhaupt soll.
ausblenden Quelltext
1:
2:
DeviceContext := GetDC (FormMain.Handle);
RenderingContext := CreateRenderingContext (DeviceContext, [opDoubleBuffered], iPixelDepth, 0, 0, 0, 0, TempPal);
Aya Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 1964
Erhaltene Danke: 15

MacOSX 10.6.7
Xcode / C++
BeitragVerfasst: Fr 18.04.03 20:58 
Hi,

Man sollte es evtl erst später verstehen, aber sich gleich daran gewöhnen finde ich.. ;)

Au'revoir,
Aya~

_________________
Aya
I aim for my endless dreams and I know they will come true!
Raphael O.
ontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic starofftopic star
Beiträge: 1596


VS 2013
BeitragVerfasst: Sa 19.04.03 00:52 
Alibi hat folgendes geschrieben:
Die Zeile muss so lauten:
ausblenden Quelltext
1:
Application.OnIdle := ApplicationEvents1Idle;					

:oops: stimmt schon...
hatte aber auf dem PC, wo ich dran war leider kein Delphi drauf, so das ich es nicht testen konnte...
ist aber natürlich eigentlich klar ;)
t/f
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 70



BeitragVerfasst: Sa 19.04.03 00:55 
Wann findet dieses Ereignis eigentlich statt? Bei vielen Ereignissen ist es mir ja klar... OnClick -> *Klick* ... aber Idle? Wenn nix passiert?
Aya Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 1964
Erhaltene Danke: 15

MacOSX 10.6.7
Xcode / C++
BeitragVerfasst: Sa 19.04.03 01:00 
huhu,

OnIdle wird ausgelöst wenn die CPU grad mal nix zu tun hat ;)

Au'revoir,
Aya~

_________________
Aya
I aim for my endless dreams and I know they will come true!
mimi
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 3458

Ubuntu, Win XP
Lazarus
BeitragVerfasst: Do 24.04.03 17:56 
ich verzuche gerade openGl zu lehren, aber ich sehe nur ein schwartzes bild warum:?
Fehler gerfunden ;)

_________________
MFG
Michael Springwald, "kann kein englisch...."
The-FoX
ontopic starontopic starontopic starontopic starofftopic starofftopic starofftopic starofftopic star
Beiträge: 203

Win XP
D6 Pers
BeitragVerfasst: Do 08.05.03 20:31 
Jo haste echt gut gemacht :wink:, nur irgendwie bekomm ich gleich am Anfang die Meldung:
[Fehler] Unit1.pas(31): Undefinierter Bezeichner: 'SetDCPixelFormat'