123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582 |
- //
- // The graphics engine GLXEngine. The unit of GXScene for Delphi
- //
- unit GXS.InitOpenGL;
- (* OpenGL for Initialization in FMX *)
- interface
- uses
- Winapi.OpenGL,
- Winapi.OpenGLext,
- Winapi.Windows,
- FMX.Forms;
- type
- TgxOpenGL = class
- private
- CommonCustomForm: TCommonCustomForm;
- _WND: HWND;
- _DC: HDC;
- protected
- _PFD: TPixelFormatDescriptor;
- _PFI: Integer;
- _RC: HGLRC;
- procedure SetPFD(const PFD_: TPixelFormatDescriptor);
- procedure SetPFI(const PFI_: Integer);
- procedure CreateWindow;
- procedure DestroyWindow;
- procedure ValidatePFD(const PFD_: TPixelFormatDescriptor);
- procedure ValidatePFI(const PFI_: Integer);
- procedure CreateDC;
- procedure DestroyDC;
- procedure CreateRC;
- procedure DestroyRC;
- public
- constructor Create;
- destructor Destroy; override;
- property PFD: TPixelFormatDescriptor read _PFD write SetPFD;
- property PFI: Integer read _PFI write SetPFI;
- property RC: HGLRC read _RC;
- class function DefaultPFD: TPixelFormatDescriptor;
- procedure BeginGL;
- procedure EndGL;
- procedure InitOpenGL;
- procedure ApplyPixelFormat(const DC_: HDC);
- end;
- //-----------------------------------------------------------------------
- TgxShader = class
- private
- protected
- _ID: GLuint;
- public
- constructor Create(const Kind_: GLenum);
- destructor Destroy; override;
- property ID: GLuint read _ID;
- procedure SetSource(const Source_: String);
- end;
- //-----------------------------------------------------------------------
- TgxShaderV = class(TgxShader)
- private
- protected
- public
- constructor Create;
- destructor Destroy; override;
- end;
- //-----------------------------------------------------------------------
- TgxShaderG = class(TgxShader)
- private
- protected
- public
- constructor Create;
- destructor Destroy; override;
- end;
- //-----------------------------------------------------------------------
- TgxShaderF = class(TgxShader)
- private
- protected
- public
- constructor Create;
- destructor Destroy; override;
- end;
- //-----------------------------------------------------------------------
- TgxProgram = class
- private
- protected
- _ID: GLuint;
- public
- constructor Create;
- destructor Destroy; override;
- procedure Attach(const Shader_: TgxShader);
- procedure Detach(const Shader_: TgxShader);
- procedure Link;
- procedure Use;
- end;
- //-----------------------------------------------------------------------
- TgxBuffer<_TYPE_: record > = class
- public type
- _PValue_ = ^_TYPE_;
- private
- protected
- _ID: GLuint;
- _Kind: GLenum;
- _Count: Integer;
- _Head: _PValue_;
- procedure SetCount(const Count_: Integer);
- public
- constructor Create(const Kind_: GLenum);
- destructor Destroy; override;
- property ID: GLuint read _ID;
- property Count: Integer read _Count write SetCount;
- procedure Bind;
- procedure Unbind;
- procedure Map;
- procedure Unmap;
- end;
- //-----------------------------------------------------------------------
- TgxBufferV<_TYPE_: record > = class(TgxBuffer<_TYPE_>)
- private
- protected
- public
- constructor Create;
- destructor Destroy; override;
- end;
- //-----------------------------------------------------------------------
- TgxBufferI<_TYPE_: record > = class(TgxBuffer<_TYPE_>)
- private
- protected
- public
- constructor Create;
- destructor Destroy; override;
- end;
- //-----------------------------------------------------------------------
- TgxBufferU<_TYPE_: record > = class(TgxBuffer<_TYPE_>)
- private
- protected
- public
- constructor Create;
- destructor Destroy; override;
- end;
- //-----------------------------------------------------------------------
- TgxArray = class
- private
- protected
- _ID: GLuint;
- public
- constructor Create;
- destructor Destroy; override;
- property ID: GLuint read _ID;
- procedure BeginBind;
- procedure EndBind;
- end;
- var
- GXOpenGL: TgxOpenGL;
- //-----------------------------------------------------------------------
- implementation
- //-----------------------------------------------------------------------
- uses
- System.SysUtils,
- FMX.Platform.Win;
- procedure TgxOpenGL.SetPFD(const PFD_: TPixelFormatDescriptor);
- begin
- DestroyRC;
- DestroyDC;
- CreateDC;
- ValidatePFD(PFD_);
- CreateRC;
- end;
- procedure TgxOpenGL.SetPFI(const PFI_: Integer);
- begin
- DestroyRC;
- DestroyDC;
- CreateDC;
- ValidatePFI(PFI_);
- CreateRC;
- end;
- // ------------------------------------------------------------------------------
- procedure TgxOpenGL.CreateWindow;
- begin
- CommonCustomForm := TCommonCustomForm.Create(nil);
- _WND := WindowHandleToPlatform(CommonCustomForm.Handle).Wnd;
- end;
- procedure TgxOpenGL.DestroyWindow;
- begin
- CommonCustomForm.Free;
- end;
- // ------------------------------------------------------------------------------
- procedure TgxOpenGL.ValidatePFD(const PFD_: TPixelFormatDescriptor);
- var
- I: Integer;
- begin
- _PFD := PFD_;
- I := ChoosePixelFormat(_DC, @_PFD);
- Assert(I > 0, 'Not found the PixelFormat with a close setting!');
- ValidatePFI(I);
- end;
- procedure TgxOpenGL.ValidatePFI(const PFI_: Integer);
- begin
- _PFI := PFI_;
- Assert(DescribePixelFormat(_DC, _PFI, SizeOf(TPixelFormatDescriptor), _PFD),
- 'Not found the PixelFormat of the index!');
- end;
- // ------------------------------------------------------------------------------
- procedure TgxOpenGL.CreateDC;
- begin
- _DC := GetDC(_WND);
- end;
- procedure TgxOpenGL.DestroyDC;
- begin
- ReleaseDC(0, _DC);
- end;
- // ------------------------------------------------------------------------------
- procedure TgxOpenGL.CreateRC;
- begin
- ApplyPixelFormat(_DC);
- _RC := wglCreateContext(_DC);
- end;
- procedure TgxOpenGL.DestroyRC;
- begin
- wglDeleteContext(_RC);
- end;
- constructor TgxOpenGL.Create;
- begin
- inherited;
- CreateWindow;
- CreateDC;
- ValidatePFD(DefaultPFD);
- CreateRC;
- InitOpenGL;
- end;
- destructor TgxOpenGL.Destroy;
- begin
- DestroyRC;
- DestroyDC;
- DestroyWindow;
- inherited;
- end;
- // ------------------------------------------------------------------------------
- class function TgxOpenGL.DefaultPFD: TPixelFormatDescriptor;
- begin
- with Result do
- begin
- nSize := SizeOf(TPixelFormatDescriptor);
- nVersion := 1;
- dwFlags := PFD_DRAW_TO_WINDOW or PFD_SUPPORT_OPENGL or PFD_DOUBLEBUFFER;
- iPixelType := PFD_TYPE_RGBA;
- cColorBits := 24;
- cRedBits := 0;
- cRedShift := 0;
- cGreenBits := 0;
- cGreenShift := 0;
- cBlueBits := 0;
- cBlueShift := 0;
- cAlphaBits := 0;
- cAlphaShift := 0;
- cAccumBits := 0;
- cAccumRedBits := 0;
- cAccumGreenBits := 0;
- cAccumBlueBits := 0;
- cAccumAlphaBits := 0;
- cDepthBits := 32;
- cStencilBits := 0;
- cAuxBuffers := 0;
- iLayerType := PFD_MAIN_PLANE;
- bReserved := 0;
- dwLayerMask := 0;
- dwVisibleMask := 0;
- dwDamageMask := 0;
- end;
- end;
- // ------------------------------------------------------------------------------
- procedure TgxOpenGL.BeginGL;
- begin
- wglMakeCurrent(_DC, _RC);
- end;
- procedure TgxOpenGL.EndGL;
- begin
- wglMakeCurrent(_DC, 0);
- end;
- // ------------------------------------------------------------------------------
- procedure TgxOpenGL.InitOpenGL;
- begin
- BeginGL;
- glEnable(GL_DEPTH_TEST);
- glEnable(GL_CULL_FACE);
- EndGL;
- end;
- // ------------------------------------------------------------------------------
- procedure TgxOpenGL.ApplyPixelFormat(const DC_: HDC);
- begin
- Assert(SetPixelFormat(DC_, _PFI, @_PFD), 'SetPixelFormat() is failed!');
- end;
- // ------------------------------------------------------------------------------
- constructor TgxShader.Create(const Kind_: GLenum);
- begin
- inherited Create;
- _ID := glCreateShader(Kind_);
- end;
- destructor TgxShader.Destroy;
- begin
- glDeleteShader(_ID);
- inherited;
- end;
- // ------------------------------------------------------------------------------
- procedure TgxShader.SetSource(const Source_: String);
- var
- P: PAnsiChar;
- N: GLint;
- E: GLint;
- Cs: array of PGLchar;
- CsN: GLsizei;
- begin
- P := PAnsiChar(AnsiString(Source_));
- N := Length(Source_);
- glShaderSource(_ID, 1, @P, @N);
- glCompileShader(_ID);
- glGetShaderiv(_ID, GL_COMPILE_STATUS, @E);
- if E = GL_FALSE then
- begin
- glGetShaderiv(_ID, GL_INFO_LOG_LENGTH, @N);
- SetLength(Cs, N);
- glGetShaderInfoLog(_ID, N, @CsN, @Cs[0]);
- Assert(False, AnsiString(Cs));
- end;
- end;
- // ------------------------------------------------------------------------------
- constructor TgxShaderV.Create;
- begin
- inherited Create(GL_VERTEX_SHADER);
- end;
- destructor TgxShaderV.Destroy;
- begin
- inherited;
- end;
- // ------------------------------------------------------------------------------
- constructor TgxShaderG.Create;
- begin
- inherited Create(GL_GEOMETRY_SHADER);
- end;
- destructor TgxShaderG.Destroy;
- begin
- inherited;
- end;
- // ------------------------------------------------------------------------------
- constructor TgxShaderF.Create;
- begin
- inherited Create(GL_FRAGMENT_SHADER);
- end;
- destructor TgxShaderF.Destroy;
- begin
- inherited;
- end;
- // ------------------------------------------------------------------------------
- constructor TgxProgram.Create;
- begin
- inherited;
- _ID := glCreateProgram;
- end;
- destructor TgxProgram.Destroy;
- begin
- glDeleteProgram(_ID);
- inherited;
- end;
- // ------------------------------------------------------------------------------
- procedure TgxProgram.Attach(const Shader_: TgxShader);
- begin
- glAttachShader(_ID, Shader_.ID);
- end;
- procedure TgxProgram.Detach(const Shader_: TgxShader);
- begin
- glDetachShader(_ID, Shader_.ID);
- end;
- // ------------------------------------------------------------------------------
- procedure TgxProgram.Link;
- begin
- glLinkProgram(_ID);
- end;
- // ------------------------------------------------------------------------------
- procedure TgxProgram.Use;
- begin
- glUseProgram(_ID);
- end;
- // ------------------------------------------------------------------------------
- procedure TgxBuffer<_TYPE_>.SetCount(const Count_: Integer);
- begin
- _Count := Count_;
- Bind;
- glBufferData(_Kind, SizeOf(_TYPE_) * _Count, nil, GL_DYNAMIC_DRAW);
- Unbind;
- end;
- // ------------------------------------------------------------------------------
- constructor TgxBuffer<_TYPE_>.Create(const Kind_: GLenum);
- begin
- inherited Create;
- glGenBuffers(1, @_ID);
- _Kind := Kind_;
- Count := 0;
- end;
- // ------------------------------------------------------------------------------
- destructor TgxBuffer<_TYPE_>.Destroy;
- begin
- glDeleteBuffers(1, @_ID);
- inherited;
- end;
- // ------------------------------------------------------------------------------
- procedure TgxBuffer<_TYPE_>.Bind;
- begin
- glBindBuffer(_Kind, _ID);
- end;
- procedure TgxBuffer<_TYPE_>.Unbind;
- begin
- glBindBuffer(_Kind, 0);
- end;
- // ------------------------------------------------------------------------------
- procedure TgxBuffer<_TYPE_>.Map;
- begin
- Bind;
- _Head := glMapBuffer(_Kind, GL_READ_WRITE);
- end;
- procedure TgxBuffer<_TYPE_>.Unmap;
- begin
- glUnmapBuffer(_Kind);
- Unbind;
- end;
- constructor TgxBufferV<_TYPE_>.Create;
- begin
- inherited Create(GL_ARRAY_BUFFER);
- end;
- destructor TgxBufferV<_TYPE_>.Destroy;
- begin
- inherited;
- end;
- // ------------------------------------------------------------------------------
- constructor TgxBufferI<_TYPE_>.Create;
- begin
- inherited Create(GL_ELEMENT_ARRAY_BUFFER);
- end;
- destructor TgxBufferI<_TYPE_>.Destroy;
- begin
- inherited;
- end;
- // ------------------------------------------------------------------------------
- constructor TgxBufferU<_TYPE_>.Create;
- begin
- inherited Create(GL_UNIFORM_BUFFER);
- end;
- destructor TgxBufferU<_TYPE_>.Destroy;
- begin
- inherited;
- end;
- // ------------------------------------------------------------------------------
- constructor TgxArray.Create;
- begin
- inherited Create;
- glGenVertexArrays(1, @_ID);
- end;
- destructor TgxArray.Destroy;
- begin
- glDeleteVertexArrays(1, @_ID);
- inherited;
- end;
- // ------------------------------------------------------------------------------
- procedure TgxArray.BeginBind;
- begin
- glBindVertexArray(_ID);
- end;
- procedure TgxArray.EndBind;
- begin
- glBindVertexArray(0);
- end;
- //==========================================================================
- initialization
- //==========================================================================
- GXOpenGL := TgxOpenGL.Create;
- GXOpenGL.BeginGL;
- InitOpenGLext;
- finalization
- GXOpenGL.EndGL;
- GXOpenGL.Free;
- end.
|