--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<CONFIG>
+ <ProjectOptions>
+ <Version Value="9"/>
+ <PathDelim Value="\"/>
+ <General>
+ <SessionStorage Value="InProjectDir"/>
+ <MainUnit Value="0"/>
+ <Title Value="project1"/>
+ <ResourceType Value="res"/>
+ <UseXPManifest Value="True"/>
+ </General>
+ <i18n>
+ <EnableI18N LFM="False"/>
+ </i18n>
+ <VersionInfo>
+ <StringTable ProductVersion=""/>
+ </VersionInfo>
+ <BuildModes Count="1">
+ <Item1 Name="Default" Default="True"/>
+ </BuildModes>
+ <PublishOptions>
+ <Version Value="2"/>
+ </PublishOptions>
+ <RunParams>
+ <local>
+ <FormatVersion Value="1"/>
+ </local>
+ </RunParams>
+ <RequiredPackages Count="1">
+ <Item1>
+ <PackageName Value="LCL"/>
+ </Item1>
+ </RequiredPackages>
+ <Units Count="2">
+ <Unit0>
+ <Filename Value="project1.lpr"/>
+ <IsPartOfProject Value="True"/>
+ </Unit0>
+ <Unit1>
+ <Filename Value="uMainForm.pas"/>
+ <IsPartOfProject Value="True"/>
+ <ComponentName Value="MainForm"/>
+ <HasResources Value="True"/>
+ <ResourceBaseClass Value="Form"/>
+ <UnitName Value="uMainForm"/>
+ </Unit1>
+ </Units>
+ </ProjectOptions>
+ <CompilerOptions>
+ <Version Value="11"/>
+ <PathDelim Value="\"/>
+ <Target>
+ <Filename Value="project1"/>
+ </Target>
+ <SearchPaths>
+ <IncludeFiles Value="$(ProjOutDir);..\.."/>
+ <OtherUnitFiles Value="..\.."/>
+ <UnitOutputDirectory Value="lib\$(TargetCPU)-$(TargetOS)"/>
+ </SearchPaths>
+ <Linking>
+ <Options>
+ <Win32>
+ <GraphicApplication Value="True"/>
+ </Win32>
+ </Options>
+ </Linking>
+ </CompilerOptions>
+ <Debugging>
+ <Exceptions Count="3">
+ <Item1>
+ <Name Value="EAbort"/>
+ </Item1>
+ <Item2>
+ <Name Value="ECodetoolError"/>
+ </Item2>
+ <Item3>
+ <Name Value="EFOpenError"/>
+ </Item3>
+ </Exceptions>
+ </Debugging>
+</CONFIG>
--- /dev/null
+program project1;
+
+{$mode objfpc}{$H+}
+
+uses
+ {$IFDEF UNIX}{$IFDEF UseCThreads}
+ cthreads,
+ {$ENDIF}{$ENDIF}
+ Interfaces, // this includes the LCL widgetset
+ Forms, uMainForm
+ { you can add units after this };
+
+{$R *.res}
+
+begin
+ RequireDerivedFormResource := True;
+ Application.Initialize;
+ Application.CreateForm(TMainForm, MainForm);
+ Application.Run;
+end.
+
--- /dev/null
+/* ShaderObject: GL_VERTEX_SHADER */
+#version 330
+uniform mat4 uModelViewProjMat;
+layout(location = 0) in vec3 inPos;
+
+void main(void)
+{
+ gl_Position = vec4(inPos, 1.0);
+}
+
+/* ShaderObject: GL_FRAGMENT_SHADER */
+#version 330
+
+out vec4 outColor; // ausgegebene Farbe
+
+void main(void)
+{
+ outColor = vec4(1.0, 0.0, 0.0, 1.0);
+}
\ No newline at end of file
--- /dev/null
+object MainForm: TMainForm
+ Left = 465
+ Height = 451
+ Top = 217
+ Width = 411
+ Caption = 'MainForm'
+ ClientHeight = 451
+ ClientWidth = 411
+ OnCreate = FormCreate
+ OnDestroy = FormDestroy
+ LCLVersion = '1.3'
+ object RenderPanel: TPanel
+ Left = 0
+ Height = 371
+ Top = 0
+ Width = 411
+ Align = alClient
+ TabOrder = 0
+ OnResize = RenderPanelResize
+ end
+ object LogLB: TListBox
+ Left = 0
+ Height = 80
+ Top = 371
+ Width = 411
+ Align = alBottom
+ ItemHeight = 0
+ TabOrder = 1
+ end
+ object ApplicationProperties: TApplicationProperties
+ OnIdle = ApplicationPropertiesIdle
+ left = 64
+ top = 24
+ end
+end
--- /dev/null
+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.
+
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<CONFIG>
+ <ProjectOptions>
+ <Version Value="9"/>
+ <PathDelim Value="\"/>
+ <General>
+ <SessionStorage Value="InProjectDir"/>
+ <MainUnit Value="0"/>
+ <Title Value="project1"/>
+ <ResourceType Value="res"/>
+ <UseXPManifest Value="True"/>
+ </General>
+ <i18n>
+ <EnableI18N LFM="False"/>
+ </i18n>
+ <VersionInfo>
+ <StringTable ProductVersion=""/>
+ </VersionInfo>
+ <BuildModes Count="1">
+ <Item1 Name="Default" Default="True"/>
+ </BuildModes>
+ <PublishOptions>
+ <Version Value="2"/>
+ </PublishOptions>
+ <RunParams>
+ <local>
+ <FormatVersion Value="1"/>
+ </local>
+ </RunParams>
+ <RequiredPackages Count="1">
+ <Item1>
+ <PackageName Value="LCL"/>
+ </Item1>
+ </RequiredPackages>
+ <Units Count="2">
+ <Unit0>
+ <Filename Value="project1.lpr"/>
+ <IsPartOfProject Value="True"/>
+ </Unit0>
+ <Unit1>
+ <Filename Value="uMainForm.pas"/>
+ <IsPartOfProject Value="True"/>
+ <ComponentName Value="MainForm"/>
+ <HasResources Value="True"/>
+ <ResourceBaseClass Value="Form"/>
+ <UnitName Value="uMainForm"/>
+ </Unit1>
+ </Units>
+ </ProjectOptions>
+ <CompilerOptions>
+ <Version Value="11"/>
+ <PathDelim Value="\"/>
+ <Target>
+ <Filename Value="project1"/>
+ </Target>
+ <SearchPaths>
+ <IncludeFiles Value="$(ProjOutDir);..\.."/>
+ <OtherUnitFiles Value="..\.."/>
+ <UnitOutputDirectory Value="lib\$(TargetCPU)-$(TargetOS)"/>
+ </SearchPaths>
+ <Linking>
+ <Options>
+ <Win32>
+ <GraphicApplication Value="True"/>
+ </Win32>
+ </Options>
+ </Linking>
+ </CompilerOptions>
+ <Debugging>
+ <Exceptions Count="3">
+ <Item1>
+ <Name Value="EAbort"/>
+ </Item1>
+ <Item2>
+ <Name Value="ECodetoolError"/>
+ </Item2>
+ <Item3>
+ <Name Value="EFOpenError"/>
+ </Item3>
+ </Exceptions>
+ </Debugging>
+</CONFIG>
--- /dev/null
+program project1;
+
+{$mode objfpc}{$H+}
+
+uses
+ {$IFDEF UNIX}{$IFDEF UseCThreads}
+ cthreads,
+ {$ENDIF}{$ENDIF}
+ Interfaces, // this includes the LCL widgetset
+ Forms, uMainForm
+ { you can add units after this };
+
+{$R *.res}
+
+begin
+ RequireDerivedFormResource := True;
+ Application.Initialize;
+ Application.CreateForm(TMainForm, MainForm);
+ Application.Run;
+end.
+
--- /dev/null
+/* ShaderObject: GL_VERTEX_SHADER */
+#version 330
+uniform mat4 uModelViewProjMat;
+layout(location = 0) in vec3 inPos;
+layout(location = 1) in vec2 inTexCoord;
+out vec2 vTexCoord;
+
+void main(void)
+{
+ gl_Position = vec4(inPos, 1.0);
+ vTexCoord = inTexCoord;
+}
+
+/* ShaderObject: GL_FRAGMENT_SHADER */
+#version 330
+uniform sampler2D uTexture;
+in vec2 vTexCoord;
+out vec4 outColor;
+
+void main(void)
+{
+ outColor = texture(uTexture, vTexCoord);
+}
\ No newline at end of file
--- /dev/null
+object MainForm: TMainForm
+ Left = 465
+ Height = 451
+ Top = 217
+ Width = 411
+ Caption = 'MainForm'
+ ClientHeight = 451
+ ClientWidth = 411
+ OnCreate = FormCreate
+ OnDestroy = FormDestroy
+ LCLVersion = '1.3'
+ object RenderPanel: TPanel
+ Left = 0
+ Height = 371
+ Top = 0
+ Width = 411
+ Align = alClient
+ TabOrder = 0
+ OnResize = RenderPanelResize
+ end
+ object LogLB: TListBox
+ Left = 0
+ Height = 80
+ Top = 371
+ Width = 411
+ Align = alBottom
+ ItemHeight = 0
+ TabOrder = 1
+ end
+ object ApplicationProperties: TApplicationProperties
+ OnIdle = ApplicationPropertiesIdle
+ left = 64
+ top = 24
+ end
+end
--- /dev/null
+unit uMainForm;
+
+{$mode objfpc}{$H+}
+
+interface
+
+uses
+ Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, ExtCtrls, StdCtrls,
+ uglcContext, uglcShader, uglcArrayBuffer, uglcTypes, uglcBitmap;
+
+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;
+ fTexture: TglcBitmap2D;
+ 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';
+ TEXTURE_FILE = 'data\texture.png';
+
+ LAYOUT_LOCATION_POS = 0;
+ LAYOUT_LOCATION_TEX = 1;
+
+ UNIFORM_NAME_TEXTURE = 'uTexture';
+
+type
+ TVertex = packed record
+ pos: TgluVector3f;
+ tex: TgluVector2f;
+ end;
+ PVertex = ^TVertex;
+
+procedure TMainForm.FormCreate(Sender: TObject);
+var
+ pf: TglcContextPixelFormatSettings;
+ p: PVertex;
+ texData: TglcBitmapData;
+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;
+ fShader.Uniform1i(UNIFORM_NAME_TEXTURE, 0);
+
+ 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);
+ p^.tex := gluVector2f( 0.0, 1.0);
+ inc(p);
+
+ p^.pos := gluVector3f( 0.5, -0.5, 0);
+ p^.tex := gluVector2f( 1.0, 1.0);
+ inc(p);
+
+ p^.pos := gluVector3f( 0.5, 0.5, 0);
+ p^.tex := gluVector2f( 1.0, 0.0);
+ inc(p);
+
+ p^.pos := gluVector3f(-0.5, 0.5, 0);
+ p^.tex := gluVector2f( 0.0, 0.0);
+ inc(p);
+ finally
+ fVBO.UnmapBuffer;
+ end;
+
+ fTexture := TglcBitmap2D.Create;
+ texData := TglcBitmapData.Create;
+ try
+ texData.LoadFromFile(ExtractFilePath(Application.ExeName) + TEXTURE_FILE);
+ fTexture.UploadData(texData);
+ finally
+ FreeAndNil(texData);
+ 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;
+ fTexture.Bind;
+ fShader.Enable;
+
+ glEnableVertexAttribArray(LAYOUT_LOCATION_POS);
+ glVertexAttribPointer(LAYOUT_LOCATION_POS, 3, GL_FLOAT, False, SizeOf(TVertex), @PVertex(nil)^.pos);
+
+ glEnableVertexAttribArray(LAYOUT_LOCATION_TEX);
+ glVertexAttribPointer(LAYOUT_LOCATION_TEX, 2, GL_FLOAT, False, SizeOf(TVertex), @PVertex(nil)^.tex);
+
+ glDrawArrays(GL_QUADS, 0, fVBO.DataCount);
+
+ glDisableVertexAttribArray(LAYOUT_LOCATION_POS);
+ glDisableVertexAttribArray(LAYOUT_LOCATION_TEX);
+
+ fShader.Disable;
+ fTexture.Unbind;
+ fVBO.Unbind;
+
+ fContext.SwapBuffers;
+end;
+
+end.
+
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<CONFIG>
+ <ProjectOptions>
+ <Version Value="9"/>
+ <PathDelim Value="\"/>
+ <General>
+ <SessionStorage Value="InProjectDir"/>
+ <MainUnit Value="0"/>
+ <Title Value="project1"/>
+ <ResourceType Value="res"/>
+ <UseXPManifest Value="True"/>
+ </General>
+ <i18n>
+ <EnableI18N LFM="False"/>
+ </i18n>
+ <VersionInfo>
+ <StringTable ProductVersion=""/>
+ </VersionInfo>
+ <BuildModes Count="1">
+ <Item1 Name="Default" Default="True"/>
+ </BuildModes>
+ <PublishOptions>
+ <Version Value="2"/>
+ </PublishOptions>
+ <RunParams>
+ <local>
+ <FormatVersion Value="1"/>
+ </local>
+ </RunParams>
+ <RequiredPackages Count="1">
+ <Item1>
+ <PackageName Value="LCL"/>
+ </Item1>
+ </RequiredPackages>
+ <Units Count="3">
+ <Unit0>
+ <Filename Value="project1.lpr"/>
+ <IsPartOfProject Value="True"/>
+ </Unit0>
+ <Unit1>
+ <Filename Value="uMainForm.pas"/>
+ <IsPartOfProject Value="True"/>
+ <ComponentName Value="MainForm"/>
+ <HasResources Value="True"/>
+ <ResourceBaseClass Value="Form"/>
+ <UnitName Value="uMainForm"/>
+ </Unit1>
+ <Unit2>
+ <Filename Value="..\..\uglcVertexArrayObject.pas"/>
+ <IsPartOfProject Value="True"/>
+ <UnitName Value="uglcVertexArrayObject"/>
+ </Unit2>
+ </Units>
+ </ProjectOptions>
+ <CompilerOptions>
+ <Version Value="11"/>
+ <PathDelim Value="\"/>
+ <Target>
+ <Filename Value="project1"/>
+ </Target>
+ <SearchPaths>
+ <IncludeFiles Value="$(ProjOutDir);..\.."/>
+ <OtherUnitFiles Value="..\.."/>
+ <UnitOutputDirectory Value="lib\$(TargetCPU)-$(TargetOS)"/>
+ </SearchPaths>
+ <Linking>
+ <Debugging>
+ <UseHeaptrc Value="True"/>
+ <UseExternalDbgSyms Value="True"/>
+ </Debugging>
+ <Options>
+ <Win32>
+ <GraphicApplication Value="True"/>
+ </Win32>
+ </Options>
+ </Linking>
+ </CompilerOptions>
+ <Debugging>
+ <Exceptions Count="3">
+ <Item1>
+ <Name Value="EAbort"/>
+ </Item1>
+ <Item2>
+ <Name Value="ECodetoolError"/>
+ </Item2>
+ <Item3>
+ <Name Value="EFOpenError"/>
+ </Item3>
+ </Exceptions>
+ </Debugging>
+</CONFIG>
--- /dev/null
+program project1;
+
+{$mode objfpc}{$H+}
+
+uses
+ {$IFDEF UNIX}{$IFDEF UseCThreads}
+ cthreads,
+ {$ENDIF}{$ENDIF}
+ Interfaces, // this includes the LCL widgetset
+ Forms, uMainForm, uglcVertexArrayObject
+ { you can add units after this };
+
+{$R *.res}
+
+begin
+ RequireDerivedFormResource := True;
+ Application.Initialize;
+ Application.CreateForm(TMainForm, MainForm);
+ Application.Run;
+end.
+
--- /dev/null
+/* ShaderObject: GL_VERTEX_SHADER */
+#version 330
+uniform mat4 uModelViewProjMat;
+layout(location = 0) in vec3 inPos;
+layout(location = 1) in vec2 inTexCoord;
+out vec2 vTexCoord;
+
+void main(void)
+{
+ gl_Position = vec4(inPos, 1.0);
+ vTexCoord = inTexCoord;
+}
+
+/* ShaderObject: GL_FRAGMENT_SHADER */
+#version 330
+uniform sampler2D uTexture;
+in vec2 vTexCoord;
+out vec4 outColor;
+
+void main(void)
+{
+ outColor = texture(uTexture, vTexCoord);
+}
\ No newline at end of file
--- /dev/null
+object MainForm: TMainForm
+ Left = 465
+ Height = 451
+ Top = 217
+ Width = 411
+ Caption = 'MainForm'
+ ClientHeight = 451
+ ClientWidth = 411
+ OnCreate = FormCreate
+ OnDestroy = FormDestroy
+ LCLVersion = '1.3'
+ object RenderPanel: TPanel
+ Left = 0
+ Height = 371
+ Top = 0
+ Width = 411
+ Align = alClient
+ TabOrder = 0
+ OnResize = RenderPanelResize
+ end
+ object LogLB: TListBox
+ Left = 0
+ Height = 80
+ Top = 371
+ Width = 411
+ Align = alBottom
+ ItemHeight = 0
+ TabOrder = 1
+ end
+ object ApplicationProperties: TApplicationProperties
+ OnIdle = ApplicationPropertiesIdle
+ left = 64
+ top = 24
+ end
+end
--- /dev/null
+unit uMainForm;
+
+{$mode objfpc}{$H+}
+
+interface
+
+uses
+ Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, ExtCtrls, StdCtrls,
+ uglcContext, uglcShader, uglcArrayBuffer, uglcTypes, uglcBitmap, uglcVertexArrayObject;
+
+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;
+ fVAO: TglcVertexArrayObject;
+ fTexture: TglcBitmap2D;
+ 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';
+ TEXTURE_FILE = 'data\texture.png';
+
+ LAYOUT_LOCATION_POS = 0;
+ LAYOUT_LOCATION_TEX = 1;
+
+ UNIFORM_NAME_TEXTURE = 'uTexture';
+
+type
+ TVertex = packed record
+ pos: TgluVector3f;
+ tex: TgluVector2f;
+ end;
+ PVertex = ^TVertex;
+
+procedure CheckGlError;
+var
+ err: GLenum;
+begin
+ err := glGetError();
+ if (err <> 0) then begin
+ ShowMessage('ERROR: 0x' + IntToHex(err, 16));
+ halt;
+ end;
+end;
+
+procedure TMainForm.FormCreate(Sender: TObject);
+var
+ pf: TglcContextPixelFormatSettings;
+ p: PVertex;
+ texData: TglcBitmapData;
+ vbo: TglcArrayBuffer;
+begin
+ pf := TglcContext.MakePF();
+ fContext := TglcContext.GetPlatformClass.Create(RenderPanel, pf);
+ fContext.BuildContext;
+
+ Log(self, glGetString(GL_VERSION));
+
+ fShader := TglcShaderProgram.Create(@Log);
+ fShader.LoadFromFile(ExtractFilePath(Application.ExeName) + SHADER_FILE);
+ fShader.Compile;
+ fShader.Uniform1i(UNIFORM_NAME_TEXTURE, 0);
+
+ vbo := TglcArrayBuffer.Create(TglcBufferTarget.btArrayBuffer);
+ vbo.BufferData(4, sizeof(TVertex), TglcBufferUsage.buStaticDraw, nil);
+ p := vbo.MapBuffer(TglcBufferAccess.baWriteOnly);
+ try
+ p^.pos := gluVector3f(-0.5, -0.5, 0);
+ p^.tex := gluVector2f( 0.0, 1.0);
+ inc(p);
+
+ p^.pos := gluVector3f( 0.5, -0.5, 0);
+ p^.tex := gluVector2f( 1.0, 1.0);
+ inc(p);
+
+ p^.pos := gluVector3f( 0.5, 0.5, 0);
+ p^.tex := gluVector2f( 1.0, 0.0);
+ inc(p);
+
+ p^.pos := gluVector3f(-0.5, 0.5, 0);
+ p^.tex := gluVector2f( 0.0, 0.0);
+ inc(p);
+ finally
+ vbo.UnmapBuffer;
+ end;
+
+ fVAO := TglcVertexArrayObject.Create;
+ fVAO.BindArrayBuffer(vbo, true);
+ fVAO.VertexAttribPointer(LAYOUT_LOCATION_POS, 3, GL_FLOAT, False, SizeOf(TVertex), GLint(@PVertex(nil)^.pos));
+ fVAO.VertexAttribPointer(LAYOUT_LOCATION_TEX, 2, GL_FLOAT, False, SizeOf(TVertex), GLint(@PVertex(nil)^.tex));
+
+ fTexture := TglcBitmap2D.Create;
+ texData := TglcBitmapData.Create;
+ try
+ texData.LoadFromFile(ExtractFilePath(Application.ExeName) + TEXTURE_FILE);
+ fTexture.UploadData(texData);
+ finally
+ FreeAndNil(texData);
+ end;
+end;
+
+procedure TMainForm.ApplicationPropertiesIdle(Sender: TObject; var Done: Boolean);
+begin
+ Render;
+ Done := false;
+end;
+
+procedure TMainForm.FormDestroy(Sender: TObject);
+begin
+ FreeAndNil(fTexture);
+ FreeAndNil(fVAO);
+ 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
+ CheckGlError;
+
+ glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT);
+
+ fTexture.Bind;
+ fShader.Enable;
+ fVAO.Bind;
+
+ glDrawArrays(GL_QUADS, 0, 4);
+
+ fVAO.Unbind;
+ fShader.Disable;
+ fTexture.Unbind;
+
+ fContext.SwapBuffers;
+end;
+
+end.
+
--- /dev/null
+{ this is the default configuration file of the glBitmap.pas
+ please uncomment you preferences below, rename this file to glBitmapConf.inc
+ and make it available to your compilers include paths }
+
+
+// enable support for OpenGL ES 1.1
+{.$DEFINE OPENGL_ES_1_1}
+
+// enable support for OpenGL ES 2.0
+{.$DEFINE OPENGL_ES_2_0}
+
+// enable support for OpenGL ES 3.0
+{.$DEFINE OPENGL_ES_3_0}
+
+// enable support for all OpenGL ES extensions
+{.$DEFINE OPENGL_ES_EXT}
+
+
+
+// activate to enable the support for SDL_surfaces
+{.$DEFINE GLB_SDL}
+
+// activate to enable the support for Delphi (including support for Delphi's (not Lazarus') TBitmap)
+{.$DEFINE GLB_DELPHI}
+
+// activate to enable the support for TLazIntfImage from Lazarus
+{$DEFINE GLB_LAZARUS}
+
+
+
+// activate to enable the support of SDL_image to load files. (READ ONLY)
+// If you enable SDL_image all other libraries will be ignored!
+{.$DEFINE GLB_SDL_IMAGE}
+
+
+
+// activate to enable Lazarus TPortableNetworkGraphic support
+// if you enable this pngImage and libPNG will be ignored
+{$DEFINE GLB_LAZ_PNG}
+
+// activate to enable png support with the unit pngimage -> http://pngdelphi.sourceforge.net/
+// if you enable pngimage the libPNG will be ignored
+{.$DEFINE GLB_PNGIMAGE}
+
+// activate to use the libPNG -> http://www.libpng.org/
+// You will need an aditional header -> http://www.opengl24.de/index.php?cat=header&file=libpng
+{.$DEFINE GLB_LIB_PNG}
+
+
+
+// activate to enable Lazarus TJPEGImage support
+// if you enable this delphi jpegs and libJPEG will be ignored
+{$DEFINE GLB_LAZ_JPEG}
+
+// if you enable delphi jpegs the libJPEG will be ignored
+{.$DEFINE GLB_DELPHI_JPEG}
+
+// activate to use the libJPEG -> http://www.ijg.org/
+// You will need an aditional header -> http://www.opengl24.de/index.php?cat=header&file=libjpeg
+{.$DEFINE GLB_LIB_JPEG}
+
\ No newline at end of file
- download texture data from video card
- manipulate texture data (e.g. add alpha, remove alpha, convert to other format, switch RGB, ...) }
-unit glBitmap;
+unit uglcBitmap;
{$I glBitmapConf.inc}
TglcBitmapFormat = TglBitmapFormat;
TglcBitmap2D = TglBitmap2D;
+ TglcBitmapData = TglBitmapData;
{$IF NOT DEFINED(OPENGL_ES)}
TglcBitmap1D = TglBitmap1D;
TglcBitmapCubeMap = TglBitmapCubeMap;
aBuildWithGlu := false;
if (MipMap = mmMipmap) then begin
if (GL_VERSION_1_4 or GL_SGIS_generate_mipmap) then
- glTexParameteri(Target, GL_GENERATE_MIPMAP, GL_TRUE)
+ glTexParameteri(Target, GL_GENERATE_MIPMAP, GLint(GL_TRUE))
else
aBuildWithGlu := true;
end else if (MipMap = mmMipmapGlu) then
aBuildWithGlu := true;
{$ELSE}
if (MipMap = mmMipmap) then
- glTexParameteri(Target, GL_GENERATE_MIPMAP, GL_TRUE);
+ glTexParameteri(Target, GL_GENERATE_MIPMAP, GLint(GL_TRUE));
{$ENDIF}
end;
--- /dev/null
+unit uglcVertexArrayObject;
+
+{$mode objfpc}{$H+}
+
+interface
+
+uses
+ Classes, SysUtils, contnrs, dglOpenGL, uglcArrayBuffer;
+
+type
+ EglcVertexArrayObject = class(Exception);
+ TglcVertexArrayObject = class(TObject)
+ private
+ fID: GLuint;
+ fArrayBuffers: TObjectList;
+ public
+ property ID: GLuint read fID;
+
+ procedure BindArrayBuffer(const aBuffer: TglcArrayBuffer; const aOwnsObject: Boolean);
+ procedure VertexAttribPointer(const aIndex: GLuint; const aSize: GLint; const aType: GLenum;
+ const aNormalized: GLboolean; const aStride: GLsizei; const aOffset: GLint);
+
+ procedure Bind;
+ procedure Unbind;
+
+ constructor Create;
+ destructor Destroy; override;
+ end;
+
+implementation
+
+/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+//TglcVertexArrayObject//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+procedure TglcVertexArrayObject.BindArrayBuffer(const aBuffer: TglcArrayBuffer; const aOwnsObject: Boolean);
+begin
+ Bind;
+ aBuffer.Bind;
+ if aOwnsObject and (fArrayBuffers.IndexOf(aBuffer) < 0) then
+ fArrayBuffers.Add(aBuffer);
+end;
+
+/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+procedure TglcVertexArrayObject.VertexAttribPointer(const aIndex: GLuint; const aSize: GLint; const aType: GLenum;
+ const aNormalized: GLboolean; const aStride: GLsizei; const aOffset: GLint);
+begin
+ Bind;
+ glEnableVertexAttribArray(aIndex);
+ glVertexAttribPointer(aIndex, aSize, aType, aNormalized, aStride, Pointer(aOffset));
+end;
+
+/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+procedure TglcVertexArrayObject.Bind;
+begin
+ glBindVertexArray(fID);
+end;
+
+/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+procedure TglcVertexArrayObject.Unbind;
+begin
+ glBindVertexArray(0);
+end;
+
+/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+constructor TglcVertexArrayObject.Create;
+begin
+ inherited Create;
+ if not GL_VERSION_3_0 and
+ not GL_ARB_vertex_array_object then
+ raise EglcVertexArrayObject.Create('vertex array objects are not supported by video vard');
+ glGenVertexArrays(1, @fID);
+ fArrayBuffers := TObjectList.Create(true);
+end;
+
+/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+destructor TglcVertexArrayObject.Destroy;
+begin
+ glDeleteVertexArrays(1, @fID);
+ FreeAndNil(fArrayBuffers);
+ inherited Destroy;
+end;
+
+end.
+