So... ich stelle jetzt endlich mal meine GameDev Komponenten online, da ich zu der Erkenntnis gekommen bin, dass ich doch auf längere Sicht nicht mehr dazu komme, daran weiter zu arbeiten oder meine Homepage zu launchen.
Den Anfang mache ich mit GLInterface.
Vorweg... ja ich hab gelesen, dass die Unit eigentlich komplett hier stehen müsste, aber leider ist sie RIESIG und zweitens bekommt ihr sonst die Komponentenicons nicht, die ich gemacht habe. Auch das mit dem "nur eine Unit pro Post" weiß ich, aber die Units gehören halt zusammen. Wenns wirklich ein Problem ist, soll mich ein Admin drauf ansprechen, dann sehen wir, was wir machen können.
-------------------------------------------------------------------------------------------------------------------
Da ich öfter mal kleine Programme mit OpenGL geschrieben habe, aber weder jedes mal alles neucoden wollte, noch so Sachen wie DelphiGL benutzen, die dafür viel zu kompliziert sind und ich lieber direkt mit den Originalbefehlen arbeite, hab ich mir dann einfach mal mein eigenes Interface geschrieben.
-> Sobald die Komponente installiert ist (hoffe ihr wisst, wie das geht), könnt ihr unter dem Reiter OpenGL zwei neue Komponenten auswählen: GLOutBox und GL2DOutBox. Die müsst ihr nur aufziehen wie z.B. ein Panel und schon ist euer OpenGL Fenster inklusive Projektionsmatrix fertig. Jetzt nur noch z.B. ins OnInitialize Event z.B. die Anfangskameraposition oder sonstwas reinschreiben, ins OnRender Event das was eben gemacht werden soll, vielleicht noch ein paar Einstellungen setzen (siehe unten) und dann in einer Endlosschleife oder mit Timer regelmäßig Repaint aufrufen.
Und das beste: Ihr braucht die OpenGL.pas oder ähnliches auch nicht mehr, denn in GLInterface ist ein header gleich integriert, der zwar nicht alle, aber eigentlich alle Befehle enthält, die man für ein Programm braucht!
Ich denke, dass ist auch ideal für Anfänger, die mal OGL probieren wollen, aber sich nicht mit dem ganzen Initialisierungsmüss rumschlagen wollen.
ehome.compuserve.de/...eDev/GLInterface.zip
Zu Demozwecken will ich hier gerade mal ein Programm dazustellen, dass u.a. mit GLInterface gemacht wurde:
ehome.compuserve.de/...meDev/OpenGLTest.zip
--------------------------------------------------------------------------------------------------------------
Ich denke, ich stelle jetzt einfach mal die Komponenten vor indem ich Auszüge aus den Units poste...
(Beschreibungen sind auf Englisch, da ich auch Freunde in Übersee habe, mit denen ich mich manchmal über das Zeug unterhalte. Hoffe, das ist kein zu großes Problem)
GLInterface.pas:
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:
| TGLOutBox = class(TWinControl) [...] public property Initialized:Boolean read FInitialized; function Activate:Boolean; procedure Deactivate; procedure BeginFormatChange; procedure EndFormatChange; procedure Clear; procedure Swap; function ExtensionSupported(const Extension:String):Boolean; constructor Create(AOwner: TComponent); override; destructor Destroy; override; published property Align; property Anchors; property Cursor; property Visible; property Ctl3D; property ClearColor:TColor read FClearColor write SetClearColor default clBlack; property DrawColor:TColor read FDrawColor write SetDrawColor default clWhite; property GLDoubleBuffered:Boolean read FDoubleBuffered write SetGLDoubleBuffered default True; property GLAntialiasing:Boolean read FAntiAliasing write SetAntiAliasing default False; property GLColorDepth:byte read CurrPFD.cColorBits write SetColorDepth default 32; property GLZBuffer:byte read CurrPFD.cDepthBits write SetZBuffer default 24; property GLStencilBuffer:byte read CurrPFD.cStencilBits write SetStencilBuffer default 0; property HwAcceleration:Boolean read GetAcceleration; property AutoClear:Boolean read FAutoClear write FAutoClear default True; property GLVSync:Boolean read FVSync write SetVSync default True; property GLPerspViewAngle:Double read FViewAngle write SetViewAngle; property GLClipFar:Double read FClipFar write SetClipFar; property GLClipNear:Double read FClipNear write SetClipNear; property GLBackCulling:Boolean read FCullFace write SetCulling default False; property OnResize; property OnRender:TMethodCall read FOnRender write FOnRender; property OnInitialize:TMethodCall read FOnInitialize write FOnInitialize; property OnProjMatrixNeeded:TMethodCall read FOnProjMatrixNeeded write FOnProjMatrixNeeded; end; |
GLOutBox erzeugt ein OGL Fenster mit den oben gesetzen Optionen, mit einer Projektionsmatrix (nach GLClipNear,GLClipFar,GlPerspViewAngle). Wenn Repaint aufgerufen wird, löscht es ggf selbständig den Buffer, ruft OnRender in einem try..finally Block auf und ruft dann ggf glSwap auf. In OnRender muss also wirklich nur das rein, was auch gerendert werden soll.
GL2DOutBox macht prinzipiell dasselbe, aber erstellt eine 2D orthogonale Matrix, d.h. alle Vektorangaben beziehen sich zukünftig direkt auf Pixel im Fenster [0,0]=links unten)
Den Rest findet ihr hoffentlich selber raus. Sonst halt hier Fragen...
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19:
| TGLBitmapFont = class(TComponent) [...] public procedure BeginWrite3D(ZBufferIgnore:Boolean = False); procedure EndWrite3D; procedure BeginWrite2D; procedure EndWrite2D; procedure TextOut(const AText:String; X,Y,Z:Single); constructor Create(AOwner:TComponent); override; constructor CreateRunTime(const GLWindow:TGLOutBox; const Font:TFontName; Size:Byte; Bold,Italic,Underlined:Boolean); destructor Destroy; override; published property OutputComponent:TGLOutBox read FOutputComponent write FOutputComponent; property Font:TFontName read FFont write FFont; property Size:Byte read FSize write FSize; property XBold:Boolean read FBold write FBold; property XItalic:Boolean read FItalic write FItalic; property XUnderlined:Boolean read FUnderlined write FUnderlined; end; |
Da es ja das übliche Problem ist, in OGL Text auszugeben, wie auf einem Canvas, hab ich gleich noch die Komponente hier dazugetan. Damit könnt ihr ein BitmapFont erstellen und im OGL fenster ausgeben.
GLTextures.pas
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18:
| TGLTextureLoader = class(TComponent) [...] public function LoadFromFile(const Source:String):Cardinal; function LoadFromScreen(X,Y,Width,Height:Integer):Cardinal; function GeneratePlainRGB(Width,Height:Integer):Cardinal; function GeneratePlainRGBA(Width,Height:Integer):Cardinal; procedure CopyScreen(X,Y,Width,Height:Integer; RGBDest:Cardinal); procedure SetPriority(Tex:Cardinal; NewPriority:Single); procedure Unload(Tex:Cardinal); constructor Create(AOwner:TComponent); override; destructor Destroy; override; published property TextureFilter:TTexFilterType read FFilter write SetFilter default tfBilinear; property BuildMipMaps:Boolean read FMipMap write SetMipMap default False; property Tiling:Boolean read FTiling write FTiling default True; property MemPriority:Single read FPriority write FPriority; end; |
Texturen braucht man natürlich auch für OpenGl, weswegen ich den Textureloader hier gebastelt habe. Der Ladecode für JPG und TGA stammt nicht von mir aus einer anderen bekannten unit, die ich aber momentan nicht mehr wiederfinde. (muss ich irgendwann nochmal dazusetzen).
Ist eigentlich für jemanden, der sich mit OpenGl schon ein Bisschen auskennt recht selbsterklärend. Die Properties müssen vor dem Laden gesetzt werden und gelten dann jeweils für die geladene Textur.
GLEffects.pas
Die Unit müsst ihr euch selber angucken. Ich fand's im Nachhinein eher eine dumme Idee, die zu schreiben. Darin kapsele ich Lichter und Nebel in Komponenten.
GLOut2D.pas
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10:
| procedure glRectangle(const Client:T2DBox; Opaque:Boolean=False); procedure glPolygon(const Client:TPolygon; Opaque:Boolean=False); procedure glLine(const AStart,AEnd:TVector2f); overload; procedure glLine(const ALine:TLineSegment); overload; procedure glArrow(const AStart,AEnd:TVector2f; HeadSize:Single); procedure glPoint(const Destination:TVector2f; Size:Single); procedure glCircle(const Center:TVector2f; Radius:Single; Opaque:Boolean=False); overload; procedure glCircle(const ACircle:T2DCircle; Opaque:Boolean=False); overload; procedure glCircle64(const ACircle:T2DCircle; Opaque:Boolean=False); procedure glCircle32(const ACircle:T2DCircle; Opaque:Boolean=False); |
In den nächsten Tagen wird auch meine Unit Geometry2D herauskommen. Mit dieser kleinen Befehlssammlung kann man die darin enthaltenen Formen direkt ausgeben, was ja sonst bei OGL immer etwas kompliziert wird.
So... ich glaube, das reicht erstmal...
Viel Spass!