Unit GLWindow
Description
TGLWindow is a window with associated OpenGL context.
glwm object (instance of class TGLWindowsManager) is a manager of all active (i.e. visible) TGLWindow objects.
Using this unit:
Declare and create TGLWindow object. Or simply use unit GLW_Win (or GLW_Demo or GLW_Navigated), these units give you already initialized global variable glw :TGLWindow.
Assign glw properties and callbacks like OnDraw, OnResize, Width, Height, Caption. Often you will want to use ParseParameters method to allow user to control your TGLWindow initial settings using command-line options.
Call glw.Init, this will actually show the window and it's associated OpenGL context. It also calls EventInit (OnInit callback) and EventResize (OnResize callback).
Call glwm.Loop. This will enter message loop that will call appropriate windows' callbacks at appropriate times (OnDraw, OnKeyDown, OnResize and many more). (and there are some glwm callbacks, like glwm.OnIdle).
For more advanced use you can use something like while glwm.ProcessMessage do <something>; instead of glwm.Loop.
You can also call glw.InitLoop, this is a shortcut for glw.Init + glwm.Loop.
glwm.Loop ends when you call glwm.Quit, or when you close last visible window using Close(true).
User is also allowed to close a window using WindowManager facilities (clicking on "X" button in the frame corner, pressing Alt+F4 or something like that). By default, such user action will make window close (but you can freely customize what your program does when user tries to close the window using callback OnCloseQuery).
Free the TGLWindow object (as always, it's a good idea to encapsulate calls between Create and Free in "try..finally" block). Of course, you don't have to do that if you simply used one of GLW_Xxx units (with global glw variable) in your program.
So the simplest example of using this unit can look like this:
uses GLWindow, GLW_Win;
procedure Draw(glwin: TGLWindow);
begin ... end;
procedure Resize(glwin: TGLWindow);
begin ... end;
begin
glw.OnResize := Resize;
glw.InitLoop('Simplest GLWindow example', Draw);
end.
More Object-oriented approach: Instead of assigning callbacks (OnDraw, OnResize etc.) you can also derive a new class from TGLWindow and override some of virtual methods, like EventDraw, EventResize etc. Every callback OnXxx has a corresponding EventXxx method. In TGLWindow class, all EventXxx methods simply call appropriate OnXxx callbacks (this way you can use whatever approach you like – OOP or not-OOP).
This is a second version of "simplest example" program above, this time using OOP approach:
uses GLWindow;
type
TMyWindow = class(TGLWindow)
procedure EventDraw; override;
procedure EventResize; override;
end;
procedure TMyWindow.EventDraw;
begin ... end;
procedure TMyWindow.EventResize;
begin ... end;
var glw: TMyWindow;
begin
glw := TMyWindow.Create;
try
glw.Caption := 'Simplest GLWindow example using more OOP';
glw.InitLoop;
finally glw.Free end;
end.
The non-OOP approach has one advantage: you can easily switch all callbacks to some other set of callbacks using TGLWindowCallbacks, Get/SetCallbacksState. Using these functions I implemented unit GLWinModes and then, on top of this, I implemented some very handy things like modal Message Boxes (unit GLWinMessages) and progress bar (unit ProgressGL). These units give me some typical GUI capabilities, and they are in pure OpenGL.
Using OOP approach (overriding EventXxx methods instead of registering OnXxx callbacks) you can not do such things so easily – in general, you have to define something to turn off special EventXxx functionality (like SetDemoOptions in TGLWindowDemo and UseNavigator in TGLWindowNavigator) and you have to turn them off/on when using GLWinModes (mentioned TGLWindowDemo and TGLWindowNavigator are already handled in GLWinModes). TODO: I shall do some virtual methods in TGLWindow to make this easy.
pl: Unit zostal wykonany na klasie, ale program uzywajacy tego modulu nie potrzebuje dbac o rozne tego typu rzeczy. W szczegolnosci, wszystkie rejestrowane funkcje NIE SA procedurami "by object" - sa normalnymi globalnymi funkcjami. Klasa TGLWindow zostala napisana jako klasa aby wygodnie gromadzic mase rzeczy; chociaz moze byc potraktowana jako zalazek jakiejs hierarchii obiektowej (np. patrz dziedziczaca on niej klasa TGLWindowDemo, wirtualne procedury EventXxx) to mozna tez uzywac jej w zupelnie nieobiektowym programie, ktory nie definiuje zadnych wlasnych klas i nie uzywa jako callbackow zadnych metod.
Nazwy wlasciwosci i metod sa krzyzowka nazw znanych z gluta, Delphi i moich wlasnych.
Prace nad GLWindow zaczete 20 lipca 2002. Zaprojektowany jako lepsza alternatywa dla myOpenGL / myGlutGL itp. Od poczatku zrobiony aby kompilowac sie i dzialac nie tylko pod Delphi/Kylix ale takze pod FPC. Later: now it's only for FPC, I don't care in this unit about Delphi compatibility anymore.
Najwazniejsze przewagi nad glutem : - jest metoda ProcessMessage ktora pozwala napisac wlasna wersje Loop - jest mechanizm sprawdzania up / down klawiszy, kilka klawiszy moze byc wcisnietych na raz itp. - jest netoda FlushRedisplay - patrz jej opis po wyjasnienie co ona robi i kiedy jest naprawde potrzebna. - sa klasy fontow ktore opakowuja fonty glut'a (patrz GLUTFonts), fonty zainstalowane pod windowsem (OpenGLWinFonts) lub X-windowsami (OpenGLX11Fonts) i fonty zapisane statycznie w kodzie programu (patrz OpenGLTTFonts, OpenGLBmpFonts) - glutMainLoop to procedura bez powrotu. Wszystkie finalizacje trzeba robic rejestrujac wyjscie programu w libc. Moje glwm.Loop wraca gdy zamkniesz wszystkie okna. - poniewaz ten unit zostal napisany w ObjectPascalu, wszystkie awaryjne sytuacje zalatwiamy wyjatkami. A wyjatki zawsze w razie potrzeby mozesz przechwycic itp. - jest zaimplementowany Frame Per Seconds counter (frame-time i real-time, patrz opis odpowiednich metod) - menu under Windows and GTK is implemented as menu bar (always visible) - no i pare rodzynek nie zaslugujacych na osobny punkcik : . lista aktywnych okien w glwm.Active . automatyczne robienie glFlush / SwapBuffers po OnDraw . specjalna klasa BreakGLWinEvent(CodeBreaker) pozwala elegancko zakonczyc obsluge aktualnego zdarzenia GLWindow w dowolnym miejscu kodu (choc nie nalezy tego uzywac zbyt czesto !) . w tym module zaimplementowalem dwie podklasy TGLWindow o dodatkowej funkcjonalnosci : TGLWindowDemo - okno implementujace przestawianie sie w trakcie dzialania programu miedzy fullscreen a windowed, FPS automatycznie pokazywane w Caption okienka. TGLWindowNavigated - okno poslugujace sie MatruxNavigatorami w MatrixNavigation, w ten sposob mamy juz gotowy interfejs pozwalajacy userowi chodzi po dowolnej scenie jak w DOOMie albo obracac jakis model na srodku okienka.
Mamy tez wlasne mozliwosci VideoChange zmieniania rozmiaru ekranu, pod Windowsem uzywamy ChangeDisplaySettings, pod UNIXem rozszerzen z libXxf86vm (zrobione 16.02.2003). Mozna tez probowac wymuszac pewnych BitDepth roznych buforow (color buffer (possibly with alpha channel), depth, stencil, accumulation).
2/3/2004: You can attach a menu to a window. Menu structure is constructed using classes in glwindowmenu.inc file. Then you have to assign such menu structure to TGLWindow.MainMenu property. When GLWindow is implemented on top of GTK_1 or GTK_2 or WINAPI or GLUT we will show this menu and call EventMenuCommand (OnMenuCommand) when user clicks some menu item. Other implementations (XLIB for now) ignore MainMenu.
See kambi_vrml_game_engine/opengl/examples/menu_test.pasprogram for an example how to use menu.
4/2004: You can use modal dialogs for things such as file selection. GTK implementation will use GTK dialogs, WinAPI implementation will use Windows dialog boxes, XLib implementation will fall back on GLWinMessages text input.
FileDialog (for opening and saving files) is implemented. 25/5/2004: ColorDialog (for choosing RGB colors) implemented. Probably more such things will be added in the future (DirectoryDialog ?).
uses
Overview
Classes, Interfaces, Objects and Records
Functions and Procedures
Types
Constants
Variables
Description
Functions and Procedures
procedure Resize2D(glwin: TGLWindow); |
|
A simple procedure that you can register as OnResize callback, like glw.OnResize := Resize2D; You can also call this from your OnResize callback. It calls glViewport(0, 0, glwin.Width, glwin.Height); ProjectionGLOrtho(0, glwin.Width, 0, glwin.Height); That's the simplest thing to do in OnResize in OpenGL 2D programs.
|
function MenuItemFromSmallId(SearchSmallId: Integer): TMenuItem; |
|
SearchSmallId MUST be a SmallId of some existing (i.e. Created and not Destroyed yet) TMenuItem. This function returns this TMenuItem. (i.e. such Item: TMenuItem that Item.SmallId = SearchSmallId)
|
function SRemoveMnemonics(const S: string): string; |
|
Returns S with each '__' replaced with single '_', any other '_' removed.
In other words: with mnemonics (as defined by TMenuEntryWithCaption.Caption removed.
|
function SQuoteMenuEntryCaption(const S: string): string; |
|
Returns S with each underscore '_' replaced by two underscores, '__'.
In other words: S will not contain any mnemonics. If you will assign S to TMenuEntryWithCaption.Caption, then this menu entry caption will display exactly S, without any mnemonics. Single '_' in S will be displayed exactly as single '_'.
|
Types
TKey = Keys.TKey; |
|
———————————————————————
I'm aliasing here TKey type and key constants from Keys unit, this way code that uses GLWindow unit has automcatically available TKey type and key constants (because a lot of code using GLWindow unit uses also these type/constant, so I want to avoid adding "Keys" unit to uses clauses).
Once the "reuse" keyword will be implemented in FPC, this can be done using something like "reuse Keys".
|
TGLWindowParseOption = (...); |
Values
-
poGeometry:
-
poScreenGeometry:
-
poDisplay:
|
TObjectsListIsSmallerFunction_2 = function (const A, B: TObjectsListItem_2): boolean of object; |
|
|
TObjectsListIsSmallerFunction_3 = function (const A, B: TObjectsListItem_3): boolean of object; |
|
|
TIdleFunc = procedure; |
|
procedure DebugWriteln;
|
TMouseMoveFunc = procedure(Glwin: TGLWindow; NewX, NewY: Integer); |
|
|
TDynArrayItemIsSmallerFunc_2 = function (const a, b: TDynArrayItem_2): boolean; |
|
|
TDynArrayItemIsSmallerFuncByObject_2 = function (const a, b: TDynArrayItem_2): boolean of object; |
|
|
TResizeAllowed = (...); |
Values
-
raNotAllowed:
-
raOnlyAtInit:
-
raAllowed:
|
TGLWindowCursor = (...); |
|
Values for TGLWindow.Cursor.
gcDefault, gcNone, gcCustom have somewhat special meanings. The rest are some cursor images will well-defined meanings for the user, their exact look may depend on current window manager theme etc.
Values
-
gcDefault: Leave cursor as default, decided by a window manager.
-
gcNone: Make cursor invisible.
-
gcCustom: Use custom cursor image in TGLWindow.CustomCursor.
-
gcStandard: Standard arrow, indicates, well, that user can point / click something.
-
gcWait: Indicates the program is busy and user should wait.
-
gcText: Text cursor, indicates that there's text under the cursor, which commonly means that it can be selectec, or that user can click to gain focus to text box.
|
PGtkGLArea =
PGtkWidget
; |
|
This contains two very similar GLWindow backends, both based on GTK. One based on GTK 1.x and GtkGLArea, the other one based on GTK 2.x and GtkGLExt.
|
TObjectsListIsSmallerFunction_1 = function (const A, B: TObjectsListItem_1): boolean of object; |
|
|
Constants
mbLeft = MatrixNavigation.mbLeft; |
|
|
mbMiddle = MatrixNavigation.mbMiddle; |
|
|
mbRight = MatrixNavigation.mbRight; |
|
|
GLWindowPositionCenter = -1000000; |
|
|
GLWindowDefaultSize = -1000000; |
|
|
StandardParseOptions: TGLWindowParseOptions = [poGeometry, poScreenGeometry,
poDisplay]; |
|
Constant below contains all "normal" command-line options, that most programs using GLWindow should be able to handle without any problems.
In other words, most programs calling TGLWindow.ParseParameters method can safely pass as the 1st parameter this constant, StandardParseOptions. Or they can simply call overloaded version of TGLWindow.ParseParameters that doesn't take any parameters, it is always equivalent to calling TGLWindow.ParseParameters(StandardParseOptions).
In case you are not sure what precisely >> "normal" command-line options << mean: well, I'm unsure too. If that bothers you, just don't use this constant and always specify list of parameters for TGLWindow.ParseParameters explicitly.
|
DefaultDepthBufferBits = 16; |
|
|
DefaultCallbacksState: TGLWindowCallbacks =
( MouseMove: nil; MouseDown: nil; MouseUp: nil;
KeyDown: nil; KeyUp: nil;
BeforeDraw: nil; Draw: nil; CloseQuery: nil; Idle: nil; Timer: nil; Resize: nil;
MenuCommand: nil); |
|
|
Variables
glwm: TGLWindowsManager; |
|
One global instance of TGLWindowsManager.
DON'T change value of this variable, don't Free this object ! This will be handled in initialization / finalization of this module. Many things in this unit, also in TGLWindow class implementation, depend on having this variable present all the time.
|
Generated by PasDoc 0.10.0 on 2008-02-25 00:00:30