unit uMainForm; {$mode objfpc}{$H+} interface uses Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, ExtCtrls, StdCtrls, uglcContext, uglcShader, uglcArrayBuffer, uglcTypes; type TMainForm = class(TForm) ApplicationProperties: TApplicationProperties; LogLB: TListBox; RenderPanel: TPanel; procedure ApplicationPropertiesIdle(Sender: TObject; var Done: Boolean); procedure FormCreate(Sender: TObject); procedure FormDestroy(Sender: TObject); procedure RenderPanelResize(Sender: TObject); private fContext: TglcContext; fShader: TglcShaderProgram; fVBO: TglcArrayBuffer; procedure Log(aSender: TObject; const aMsg: String); procedure Render; public { public declarations } end; var MainForm: TMainForm; implementation {$R *.lfm} uses dglOpenGL, ugluVector; const SHADER_FILE = 'shader.glsl'; LAYOUT_LOCATION_POS = 0; procedure TMainForm.FormCreate(Sender: TObject); type TVertex = packed record pos: TgluVector3f; end; PVertex = ^TVertex; var pf: TglcContextPixelFormatSettings; p: PVertex; begin pf := TglcContext.MakePF(); fContext := TglcContext.GetPlatformClass.Create(RenderPanel, pf); fContext.BuildContext; fShader := TglcShaderProgram.Create(@Log); fShader.LoadFromFile(ExtractFilePath(Application.ExeName) + SHADER_FILE); fShader.Compile; fVBO := TglcArrayBuffer.Create(TglcBufferTarget.btArrayBuffer); fVBO.BufferData(4, sizeof(TVertex), TglcBufferUsage.buStaticDraw, nil); p := fVBO.MapBuffer(TglcBufferAccess.baWriteOnly); try p^.pos := gluVector3f(-0.5, -0.5, 0); inc(p); p^.pos := gluVector3f( 0.5, -0.5, 0); inc(p); p^.pos := gluVector3f( 0.5, 0.5, 0); inc(p); p^.pos := gluVector3f(-0.5, 0.5, 0); inc(p); finally fVBO.UnmapBuffer; end; end; procedure TMainForm.ApplicationPropertiesIdle(Sender: TObject; var Done: Boolean); begin Render; Done := false; end; procedure TMainForm.FormDestroy(Sender: TObject); begin FreeAndNil(fVBO); FreeAndNil(fShader); FreeAndNil(fContext); end; procedure TMainForm.RenderPanelResize(Sender: TObject); begin if Assigned(fContext) then begin glViewport(0, 0, RenderPanel.ClientWidth, RenderPanel.ClientHeight); end; end; procedure TMainForm.Log(aSender: TObject; const aMsg: String); begin LogLB.Items.Add(aMsg); end; procedure TMainForm.Render; begin glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT); fVBO.Bind; fShader.Enable; glEnableVertexAttribArray(LAYOUT_LOCATION_POS); glVertexAttribPointer(LAYOUT_LOCATION_POS, 3, GL_FLOAT, False, 0, nil); glDrawArrays(GL_QUADS, 0, fVBO.DataCount); glDisableVertexAttribArray(LAYOUT_LOCATION_POS); fShader.Disable; fVBO.Unbind; fContext.SwapBuffers; end; end.