From: Bergmann89 Date: Sat, 31 Jan 2015 15:47:40 +0000 (+0100) Subject: * updated glBitmap X-Git-Url: https://git.delphigl.com/?a=commitdiff_plain;h=f6ca47eeb2c217505d9c1babe79d46b6668d3881;p=LazOpenGLCore.git * updated glBitmap * implemented vertex array objects * added examples --- diff --git a/examples/simple/project1.lpi b/examples/simple/project1.lpi new file mode 100644 index 0000000..7e49921 --- /dev/null +++ b/examples/simple/project1.lpi @@ -0,0 +1,82 @@ + + + + + + + + + + <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> diff --git a/examples/simple/project1.lpr b/examples/simple/project1.lpr new file mode 100644 index 0000000..5ca8fd0 --- /dev/null +++ b/examples/simple/project1.lpr @@ -0,0 +1,21 @@ +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. + diff --git a/examples/simple/shader.glsl b/examples/simple/shader.glsl new file mode 100644 index 0000000..5993f08 --- /dev/null +++ b/examples/simple/shader.glsl @@ -0,0 +1,19 @@ +/* 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 diff --git a/examples/simple/uMainForm.lfm b/examples/simple/uMainForm.lfm new file mode 100644 index 0000000..712be2c --- /dev/null +++ b/examples/simple/uMainForm.lfm @@ -0,0 +1,35 @@ +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 diff --git a/examples/simple/uMainForm.pas b/examples/simple/uMainForm.pas new file mode 100644 index 0000000..1179a67 --- /dev/null +++ b/examples/simple/uMainForm.pas @@ -0,0 +1,122 @@ +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. + diff --git a/examples/texture/data/texture.png b/examples/texture/data/texture.png new file mode 100644 index 0000000..edd43da Binary files /dev/null and b/examples/texture/data/texture.png differ diff --git a/examples/texture/project1.lpi b/examples/texture/project1.lpi new file mode 100644 index 0000000..7e49921 --- /dev/null +++ b/examples/texture/project1.lpi @@ -0,0 +1,82 @@ +<?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> diff --git a/examples/texture/project1.lpr b/examples/texture/project1.lpr new file mode 100644 index 0000000..5ca8fd0 --- /dev/null +++ b/examples/texture/project1.lpr @@ -0,0 +1,21 @@ +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. + diff --git a/examples/texture/shader.glsl b/examples/texture/shader.glsl new file mode 100644 index 0000000..c70ab11 --- /dev/null +++ b/examples/texture/shader.glsl @@ -0,0 +1,23 @@ +/* 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 diff --git a/examples/texture/uMainForm.lfm b/examples/texture/uMainForm.lfm new file mode 100644 index 0000000..712be2c --- /dev/null +++ b/examples/texture/uMainForm.lfm @@ -0,0 +1,35 @@ +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 diff --git a/examples/texture/uMainForm.pas b/examples/texture/uMainForm.pas new file mode 100644 index 0000000..5b325a7 --- /dev/null +++ b/examples/texture/uMainForm.pas @@ -0,0 +1,156 @@ +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. + diff --git a/examples/vertexarrayobject/data/texture.png b/examples/vertexarrayobject/data/texture.png new file mode 100644 index 0000000..edd43da Binary files /dev/null and b/examples/vertexarrayobject/data/texture.png differ diff --git a/examples/vertexarrayobject/project1.lpi b/examples/vertexarrayobject/project1.lpi new file mode 100644 index 0000000..42d2560 --- /dev/null +++ b/examples/vertexarrayobject/project1.lpi @@ -0,0 +1,91 @@ +<?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> diff --git a/examples/vertexarrayobject/project1.lpr b/examples/vertexarrayobject/project1.lpr new file mode 100644 index 0000000..66fcec0 --- /dev/null +++ b/examples/vertexarrayobject/project1.lpr @@ -0,0 +1,21 @@ +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. + diff --git a/examples/vertexarrayobject/shader.glsl b/examples/vertexarrayobject/shader.glsl new file mode 100644 index 0000000..c70ab11 --- /dev/null +++ b/examples/vertexarrayobject/shader.glsl @@ -0,0 +1,23 @@ +/* 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 diff --git a/examples/vertexarrayobject/uMainForm.lfm b/examples/vertexarrayobject/uMainForm.lfm new file mode 100644 index 0000000..712be2c --- /dev/null +++ b/examples/vertexarrayobject/uMainForm.lfm @@ -0,0 +1,35 @@ +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 diff --git a/examples/vertexarrayobject/uMainForm.pas b/examples/vertexarrayobject/uMainForm.pas new file mode 100644 index 0000000..02887d3 --- /dev/null +++ b/examples/vertexarrayobject/uMainForm.pas @@ -0,0 +1,170 @@ +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. + diff --git a/glBitmapConf.inc b/glBitmapConf.inc new file mode 100644 index 0000000..a438dcd --- /dev/null +++ b/glBitmapConf.inc @@ -0,0 +1,61 @@ +{ 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 diff --git a/uglcBitmap.pas b/uglcBitmap.pas index 0388f46..7d53733 100644 --- a/uglcBitmap.pas +++ b/uglcBitmap.pas @@ -22,7 +22,7 @@ - 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} @@ -1207,6 +1207,7 @@ type TglcBitmapFormat = TglBitmapFormat; TglcBitmap2D = TglBitmap2D; + TglcBitmapData = TglBitmapData; {$IF NOT DEFINED(OPENGL_ES)} TglcBitmap1D = TglBitmap1D; TglcBitmapCubeMap = TglBitmapCubeMap; @@ -8164,14 +8165,14 @@ begin 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; diff --git a/uglcVertexArrayObject.pas b/uglcVertexArrayObject.pas new file mode 100644 index 0000000..89e7ac2 --- /dev/null +++ b/uglcVertexArrayObject.pas @@ -0,0 +1,84 @@ +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. +