From: Darryl L. <py...@us...> - 2000-11-06 23:07:09
|
Update of /cvsroot/pythianproject/Prototypes/GLForm In directory slayer.i.sourceforge.net:/tmp/cvs-serv2645 Added Files: Main.pas Main.dfm GLFormTest.res GLFormTest.dpr GLFormTest.dof GLFormTest.cfg GLForms.pas Log Message: First try --- NEW FILE --- unit Main; interface uses Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, Cameras, GLForms, OpenGL, ExtCtrls; type TForm1 = class(TForm) Timer1: TTimer; procedure Button1Click(Sender: TObject); procedure Timer1Timer(Sender: TObject); private { Private declarations } FCamera: TCamera; FDir: Single; FGLForm: TGLForm; FX: Single; procedure GLFormClose(Sender: TObject); procedure GLFormGLInit(Sender: TObject); procedure GLFormPaint(Sender: TObject); procedure MakeForm; public { Public declarations } end; var Form1: TForm1; implementation {$R *.DFM} procedure TForm1.Button1Click(Sender: TObject); begin MakeForm; end; procedure TForm1.GLFormClose(Sender: TObject); begin FCamera.Free; FGLForm.Free; FGLForm := nil; Close; end; procedure TForm1.GLFormGLInit(Sender: TObject); begin FCamera := TCamera.Create; FCamera.ViewWidth := FGLForm.Width; FCamera.ViewHeight := FGLForm.Height; FX := -10; FDir := 0.1; end; procedure TForm1.GLFormPaint(Sender: TObject); const MaxDist = 7.5; begin FCamera.Draw; glPushMatrix; glRotatef(90 * (FX - MaxDist) / MaxDist, 0, 0, 1); glBegin(GL_TRIANGLES); glColor3f(1, 0, 0); glVertex3f(-0.5, -0.5, FX); glColor3f(0, 1, 0); glVertex3f(0.5, -0.5, FX); glColor3f(0, 0, 1); glVertex3f(0.0, 0.5, FX); glEnd; glPopMatrix; if (FX < -10) or (FX > -10 + MaxDist) then FDir := -FDir; FX := FX + FDir; end; procedure TForm1.MakeForm; begin if Assigned(FGLForm) then exit; FGLForm := TGLForm.Create; FGLForm.SetBounds(0, 0, 640, 480); FGLForm.Caption := 'Sample GLForm'; FGLForm.OnClose := GLFormClose; FGLForm.OnOpenGLInit := GLFormGLInit; FGLForm.OnPaint := GLFormPaint; try FGLForm.Open; except exit; end; FGLForm.Run; end; procedure TForm1.Timer1Timer(Sender: TObject); begin Hide; MakeForm; Timer1.Enabled := False; end; end. --- NEW FILE --- ÿ Font.ColorclWindowTextFont.Heightõ Font.Name MS Sans Serif Font.Style TextHeight --- NEW FILE --- --- NEW FILE --- program GLFormTest; uses Forms, Main in 'Main.pas' {Form1}, GLForms in 'GLForms.pas'; {$R *.RES} begin Application.Initialize; Application.CreateForm(TForm1, Form1); Application.Run; end. --- NEW FILE --- [Compiler] A=1 B=0 C=1 D=1 E=0 F=0 G=1 H=1 I=1 J=1 K=0 L=1 M=0 N=1 O=1 P=1 Q=0 R=0 S=0 T=0 U=0 V=1 W=0 X=1 Y=1 Z=1 ShowHints=1 ShowWarnings=1 UnitAliases=WinTypes=Windows;WinProcs=Windows;DbiTypes=BDE;DbiProcs=BDE;DbiErrs=BDE; [Linker] MapFile=0 OutputObjs=0 ConsoleApp=1 DebugInfo=0 RemoteSymbols=0 MinStackSize=16384 MaxStackSize=1048576 ImageBase=4194304 ExeDescription= [Directories] OutputDir= UnitOutputDir= PackageDLLOutputDir= PackageDCPOutputDir= SearchPath= Packages=VCL50;VCLX50;VCLSMP50;QRPT50;VCLDB50;VCLBDE50;ibevnt50;VCLDBX50;TEEUI50;TEEDB50;TEE50;TEEQR50;VCLIB50;VCLIE50;INETDB50;INET50;NMFAST50;dclocx50;dclaxserver50 Conditionals= DebugSourceDirs= UsePackages=0 [Parameters] RunParams= HostApplication= [Language] ActiveLang= ProjectLang=$00000409 RootDir= [Version Info] IncludeVerInfo=0 AutoIncBuild=0 MajorVer=1 MinorVer=0 Release=0 Build=0 Debug=0 PreRelease=0 Special=0 Private=0 DLL=0 Locale=1033 CodePage=1252 [Version Info Keys] CompanyName= FileDescription= FileVersion=1.0.0.0 InternalName= LegalCopyright= LegalTrademarks= OriginalFilename= ProductName= ProductVersion=1.0.0.0 Comments= [HistoryLists\hlUnitAliases] Count=1 Item0=WinTypes=Windows;WinProcs=Windows;DbiTypes=BDE;DbiProcs=BDE;DbiErrs=BDE; [HistoryLists\hlSearchPath] Count=3 Item0=..\Units Item1=$(DELPHI)\Projects\Pythian\GameProject\Units;$(DELPHI)\Projects\Pythian\GLPanel Item2=$(DELPHI)\Projects\Pythian\GameProject\Units;$(DELPHI)\Projects\Pythian\GLPanel;$(DELPHI)\Projects\Pythian\GameProject\Picking [HistoryLists\hlUnitOutputDirectory] Count=1 Item0=..\..\Bin\dcu [HistoryLists\hlOutputDirectorry] Count=1 Item0=..\..\Bin [HistoryLists\hlBPLOutput] Count=1 Item0=$(DELPHI)\Projects\Bpl --- NEW FILE --- -$A+ -$B- -$C+ -$D+ -$E- -$F- -$G+ -$H+ -$I+ -$J+ -$K- -$L+ -$M- -$N+ -$O+ -$P+ -$Q- -$R- -$S- -$T- -$U- -$V+ -$W- -$X+ -$YD -$Z1 -cg -AWinTypes=Windows;WinProcs=Windows;DbiTypes=BDE;DbiProcs=BDE;DbiErrs=BDE; -H+ -W+ -M -$M16384,1048576 -K$00400000 -LE"c:\program files\borland\delphi5\Projects\Bpl" -LN"c:\program files\borland\delphi5\Projects\Bpl" --- NEW FILE --- unit GLForms; interface uses Windows, Classes, Messages, OpenGL, SysUtils; type TAutoClearFlag = (acColor, acDepth); TAutoClearFlags = set of TAutoClearFlag; TMouseButton = (mbLeft, mbRight, mbMiddle); TButtonState = (bsUp, bsDown); TKBModifier = (kbmAlt, kbmControl, kbmShift); TKBModifiers = set of TKBModifier; TKeyPressEvent = procedure(Sender: TObject; KeyCode, KeyData: LongInt; ButtonState: TButtonState; Modifiers: TKBModifiers) of object; TMouseButtonEvent = procedure(Sender: TObject; Button: TMouseButton; X, Y: Integer; ButtonState: TButtonState; Modifiers: TKBModifiers) of object; TMouseMoveEvent = procedure(Sender: TObject; X, Y: Integer; Modifiers: TKBModifiers) of object; TGLForm = class private FAutoClear: TAutoClearFlags; FCaption: string; FClosing: Boolean; FDC: hDC; FFullScreen: Boolean; FGLRC: hGLRC; FHandle: THandle; FHeight: Integer; FLeft: Integer; FOnClose: TNotifyEvent; FOnOpen: TNotifyEvent; FSavedCW: Word; FTop: Integer; FWidth: Integer; FWndClass: TWndClass; FWndClassName: string; FOnKeypress: TKeypressEvent; FOnMouseButton: TMouseButtonEvent; FOnMouseMove: TMouseMoveEvent; FOnOpenGLInit: TNotifyEvent; FOnPaint: TNotifyEvent; FOpening: Boolean; FRunExclusive: Boolean; procedure CloseMsg(Msg: UInt); function CreateWin(WinStyle: Cardinal): Boolean; function InitializeOpenGL: Boolean; procedure PaintCaption; procedure PaintMsg; function RegisterWindowClass: Boolean; procedure SetCaption(const Value: string); procedure SetFullScreen(const Value: Boolean); procedure SetHeight(const Value: Integer); procedure SetLeft(const Value: Integer); procedure SetOnClose(const Value: TNotifyEvent); procedure SetOnOpen(const Value: TNotifyEvent); procedure SetTop(const Value: Integer); procedure SetWidth(const Value: Integer); procedure SetOnKeypress(const Value: TKeypressEvent); procedure SetOnMouseButton(const Value: TMouseButtonEvent); procedure SetOnMouseMove(const Value: TMouseMoveEvent); procedure SetOnOpenGLInit(const Value: TNotifyEvent); procedure SetAutoClear(const Value: TAutoClearFlags); procedure SetOnPaint(const Value: TNotifyEvent); protected procedure DoClose; virtual; procedure DoKeyPress(KeyCode, KeyData: LongInt; ButtonState: TButtonState; Modifiers: TKBModifiers); virtual; procedure DoMouseButton(Button: TMouseButton; X, Y: Integer; ButtonState: TButtonState; Modifiers: TKBModifiers); virtual; procedure DoMouseMove(X, Y: Integer; Modifiers: TKBModifiers); virtual; procedure DoOpen; virtual; procedure DoOpenGLInit; virtual; public constructor Create; destructor Destroy; override; procedure Close; procedure Open; procedure Run; procedure SetBounds(ALeft, ATop, AWidth, AHeight: Integer); procedure Update; // property Canvas: TGLCanvas; property Handle: THandle read FHandle; published property AutoClear: TAutoClearFlags read FAutoClear write SetAutoClear; property Caption: string read FCaption write SetCaption; property FullScreen: Boolean read FFullScreen write SetFullScreen; property Height: Integer read FHeight write SetHeight; property Left: Integer read FLeft write SetLeft; property Top: Integer read FTop write SetTop; property Width: Integer read FWidth write SetWidth; property OnClose: TNotifyEvent read FOnClose write SetOnClose; property OnKeypress: TKeypressEvent read FOnKeypress write SetOnKeypress; property OnMouseButton: TMouseButtonEvent read FOnMouseButton write SetOnMouseButton; property OnMouseMove: TMouseMoveEvent read FOnMouseMove write SetOnMouseMove; property OnOpen: TNotifyEvent read FOnOpen write SetOnOpen; property OnOpenGLInit: TNotifyEvent read FOnOpenGLInit write SetOnOpenGLInit; property OnPaint: TNotifyEvent read FOnPaint write SetOnPaint; end; implementation var RegWindows: TList; { WinProc } function FindWindow(hWindow: THandle): TGLForm; var i: Integer; begin i := 0; while (i < RegWindows.Count) and (TGLForm(RegWindows[i]).Handle <> hWindow) do inc(i); if (i < RegWindows.Count) then Result := TGLForm(RegWindows[i]) else Result := nil; end; procedure CallMouseButtonProc(GLForm: TGLForm; Button: TMouseButton; KS: TButtonState; WParam: WPARAM; LParam: LPARAM); var KBM: TKBModifiers; begin KBM := []; if (MK_CONTROL and wParam <> 0) then KBM := KBM + [kbmControl]; if (MK_SHIFT and wParam <> 0) then KBM := KBM + [kbmShift]; GLForm.DoMouseButton(Button, Lo(lParam), Hi(lParam), KS, KBM); end; procedure CallMouseMoveProc(GLForm: TGLForm; wParam, lParam: LongInt); var KBM: TKBModifiers; begin KBM := []; if (MK_CONTROL and wParam <> 0) then KBM := KBM + [kbmControl]; if (MK_SHIFT and wParam <> 0) then KBM := KBM + [kbmShift]; GLForm.DoMouseMove(Lo(lParam), Hi(lParam), KBM); end; procedure CallKeyPressProc(GLForm: TGLForm; Msg: UINT; KeyCode, lParam: LongInt; ButtonState: TButtonState); begin if ((Msg = WM_SYSKEYUP) or (Msg = WM_SYSKEYDOWN)) and ((lParam and $10000000) > 0) then GLForm.DoKeyPress(KeyCode, lParam, ButtonState, [kbmAlt]) else GLForm.DoKeyPress(KeyCode, lParam, ButtonState, []); end; function WinProc(hWindow : THandle; Msg : UINT; wParam : WPARAM; LParam : LPARAM): LResult; stdcall; var GLForm: TGLForm; begin Result := 0; GLForm := FindWindow(hWindow); if not Assigned(GLForm) then begin Result := DefWindowProc(hWindow, Msg, wParam, lParam); exit; end; case Msg of WM_CLOSE: GLForm.CloseMsg(WM_CLOSE); WM_DESTROY: GLForm.CloseMsg(WM_DESTROY); WM_MOUSEMOVE: CallMouseMoveProc(GLForm, wParam, lParam); WM_LBUTTONDOWN: CallMouseButtonProc(GLForm, mbLeft, bsDown, wParam, lParam); WM_LBUTTONUP: CallMouseButtonProc(GLForm, mbLeft, bsUp, wParam, lParam); WM_RBUTTONDOWN: CallMouseButtonProc(GLForm, mbRight, bsDown, wParam, lParam); WM_RBUTTONUP: CallMouseButtonProc(GLForm, mbRight, bsUp, wParam, lParam); WM_MBUTTONDOWN: CallMouseButtonProc(GLForm, mbMiddle, bsDown, wParam, lParam); WM_MBUTTONUP: CallMouseButtonProc(GLForm, mbMiddle, bsUp, wParam, lParam); WM_KEYDOWN: CallKeyPressProc(GLForm, Msg, wParam, lParam, bsDown); WM_SYSKEYDOWN: CallKeyPressProc(GLForm, Msg, wParam, lParam, bsDown); WM_KEYUP: CallKeyPressProc(GLForm, Msg, wParam, lParam, bsUp); WM_SYSKEYUP: CallKeyPressProc(GLForm, Msg, wParam, lParam, bsUp); WM_ERASEBKGND: ; WM_PAINT: GLForm.PaintMsg; else Result := DefWindowProc(hWindow, Msg, wParam, lParam); end; end; { TGLForm } procedure TGLForm.Close; begin CloseWindow(FHandle); end; procedure TGLForm.CloseMsg(Msg: UInt); begin case Msg of WM_CLOSE: begin DeactivateRenderingContext; DestroyRenderingContext(FGLRC); FClosing := True; DestroyWindow(FHandle); RegWindows.Remove(Self); end; WM_DESTROY: begin FClosing := True; DoClose; end; end; end; constructor TGLForm.Create; begin inherited; FAutoClear := [acColor, acDepth]; FGLRC := 0; FSavedCW := Default8087CW; Set8087CW($133F); { Disable all fpu exceptions } FWndClassName := 'Pythian_Project_OpenGLForm'; end; function TGLForm.CreateWin(WinStyle: Cardinal): Boolean; begin FHandle := CreateWindow( PChar(FWndClassName), PChar(FCaption), WinStyle, FLeft, FTop, FWidth, FHeight, 0, 0, hInstance, nil); Result := (FHandle <> 0); end; destructor TGLForm.Destroy; begin inherited; Set8087CW(FSavedCW); inherited; end; procedure TGLForm.DoClose; begin if Assigned(FOnClose) then FOnCLose(Self); end; procedure TGLForm.DoKeyPress(KeyCode, KeyData: Integer; ButtonState: TButtonState; Modifiers: TKBModifiers); begin if Assigned(FOnKeypress) then FOnKeyPress(Self, KeyCode, KeyData, ButtonState, Modifiers); end; procedure TGLForm.DoMouseButton(Button: TMouseButton; X, Y: Integer; ButtonState: TButtonState; Modifiers: TKBModifiers); begin if Assigned(FOnMouseButton) then FOnMouseButton(Self, Button, X, Y, ButtonState, Modifiers); end; procedure TGLForm.DoMouseMove(X, Y: Integer; Modifiers: TKBModifiers); begin if Assigned(FOnMouseMove) then FOnMouseMove(Self, X, Y, Modifiers); end; procedure TGLForm.DoOpen; begin if Assigned(FOnOpen) then FOnOpen(Self); end; procedure TGLForm.DoOpenGLInit; begin if Assigned(FOnOpenGLInit) then FOnOpenGLInit(Self); end; function TGLForm.InitializeOpenGL: Boolean; begin Result := False; FGLRC := CreateRenderingContext(FDC, [opDoubleBuffered], 32, 0, 0, 0, 0); if (FGLRC = 0) then exit; ActivateRenderingContext(FDC, FGLRC); // make context drawable glClearColor(0.0, 0.0, 0.0, 1.0); // background color of the context glDisable(GL_ALPHA_TEST); glDisable(GL_BLEND); glDisable(GL_CULL_FACE); glDisable(GL_DEPTH_TEST); glDisable(GL_DITHER); glDisable(GL_FOG); glDisable(GL_LIGHTING); glDisable(GL_LOGIC_OP); glDisable(GL_STENCIL_TEST); glDisable(GL_TEXTURE_1D); glDisable(GL_TEXTURE_2D); glPixelTransferi(GL_MAP_COLOR, GL_FALSE); glPixelTransferi(GL_RED_SCALE, 1); glPixelTransferi(GL_RED_BIAS, 0); glPixelTransferi(GL_GREEN_SCALE, 1); glPixelTransferi(GL_GREEN_BIAS, 0); glPixelTransferi(GL_BLUE_SCALE, 1); glPixelTransferi(GL_BLUE_BIAS, 0); glPixelTransferi(GL_ALPHA_SCALE, 1); glPixelTransferi(GL_ALPHA_BIAS, 0); Result := True; end; procedure TGLForm.Open; var ErrorMsg: string; WinStyle: Cardinal; procedure DoError; begin end; begin FOpening := True; RegWindows.Add(Self); if not RegisterWindowClass then begin ErrorMsg := 'Unable to register new window class'; DoError; exit; end; if FFullscreen then WinStyle := ws_PopUpWindow + ws_Overlapped else WinStyle := ws_DlgFrame + ws_SysMenu; if not CreateWin(WinStyle) then begin WinStyle := GetLastError; ErrorMsg := 'Unable to create Window (' + IntToStr(WinStyle) + ')'; DoError; exit; end; ShowWindow(FHandle, cmdShow); UpdateWindow(FHandle); DoOpen; FDC := GetDC(FHandle); if FDC = 0 then begin ErrorMsg := 'Unable to create new window device context'; DoError; exit; end; if not InitializeOpenGL then begin ErrorMsg := 'Unable to initialize OpenGL device context.'; DoError; exit; end; DoOpenGLInit; FOpening := False; end; procedure TGLForm.PaintCaption; begin SetWindowText(FHandle, PChar(FCaption)); end; procedure TGLForm.PaintMsg; begin if not FRunExclusive and not FClosing and not FOpening then Update; end; function TGLForm.RegisterWindowClass: Boolean; const TRANSP_COLOR = $00000; begin with FWndClass do begin Style := CS_SAVEBITS; lpfnWndProc := @WinProc; cbWndExtra := 0; hInstance := hInstance; hIcon := LoadIcon(hInstance, 'MAINICON'); hCursor := 0; hbrBackground := TRANSP_COLOR; lpszMenuName := nil; lpszClassName := PChar(FWndClassName); end; Result := (Windows.RegisterClass(FWndClass) <> 0); end; procedure TGLForm.Run; var Msg: TMsg; begin FRunExclusive := True; while not FClosing do begin if PeekMessage(Msg, 0, 0, 0, PM_REMOVE) then begin TranslateMessage(Msg); DispatchMessage(Msg); end; Update; end; FRunExclusive := False; end; procedure TGLForm.SetAutoClear(const Value: TAutoClearFlags); begin FAutoClear := Value; end; procedure TGLForm.SetBounds(ALeft, ATop, AWidth, AHeight: Integer); begin if (ALeft <> FLeft) or (ATop <> FTop) or (AWidth <> FWidth) or (AHeight <> FHeight) then begin FLeft := ALeft; FTop := ATop; FWidth := AWidth; FHeight := AHeight; if (FHandle <> 0) then SetWindowPos(FHandle, 0, ALeft, ATop, AWidth, AHeight, SWP_NOZORDER + SWP_NOACTIVATE) end; end; procedure TGLForm.SetCaption(const Value: string); begin FCaption := Value; PaintCaption; end; procedure TGLForm.SetFullScreen(const Value: Boolean); begin FFullScreen := Value; end; procedure TGLForm.SetHeight(const Value: Integer); begin SetBounds(FLeft, FTop, FWidth, Value); end; procedure TGLForm.SetLeft(const Value: Integer); begin SetBounds(Value, FTop, FWidth, FHeight); end; procedure TGLForm.SetOnClose(const Value: TNotifyEvent); begin FOnClose := Value; end; procedure TGLForm.SetOnKeypress(const Value: TKeypressEvent); begin FOnKeypress := Value; end; procedure TGLForm.SetOnMouseButton(const Value: TMouseButtonEvent); begin FOnMouseButton := Value; end; procedure TGLForm.SetOnMouseMove(const Value: TMouseMoveEvent); begin FOnMouseMove := Value; end; procedure TGLForm.SetOnOpen(const Value: TNotifyEvent); begin FOnOpen := Value; end; procedure TGLForm.SetOnOpenGLInit(const Value: TNotifyEvent); begin FOnOpenGLInit := Value; end; procedure TGLForm.SetOnPaint(const Value: TNotifyEvent); begin FOnPaint := Value; end; procedure TGLForm.SetTop(const Value: Integer); begin SetBounds(FLeft, Value, FWidth, FHeight); end; procedure TGLForm.SetWidth(const Value: Integer); begin SetBounds(FLeft, FTop, Value, FHeight); end; procedure TGLForm.Update; begin if acDepth in FAutoClear then glClear(GL_DEPTH_BUFFER_BIT); if acColor in FAutoClear then glClear(GL_COLOR_BUFFER_BIT); if Assigned(FOnPaint) then FOnPaint(Self); SwapBuffers(FDC); // copy back buffer to front end; initialization RegWindows := TList.Create; finalization RegWindows.Free; end. |