Merge remote-tracking branch 'glBitmap@DGL/master'
[LazOpenGLCore.git] / examples / texture / uMainForm.pas
1 unit uMainForm;
2
3 {$mode objfpc}{$H+}
4
5 interface
6
7 uses
8   Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, ExtCtrls, StdCtrls,
9   uglcContext, uglcShader, uglcArrayBuffer, uglcTypes, uglcBitmap;
10
11 type
12   TMainForm = class(TForm)
13     ApplicationProperties: TApplicationProperties;
14     LogLB: TListBox;
15     RenderPanel: TPanel;
16     procedure ApplicationPropertiesIdle(Sender: TObject; var Done: Boolean);
17     procedure FormCreate(Sender: TObject);
18     procedure FormDestroy(Sender: TObject);
19     procedure RenderPanelResize(Sender: TObject);
20   private
21     fContext: TglcContext;
22     fShader: TglcShaderProgram;
23     fVBO: TglcArrayBuffer;
24     fTexture: TglcBitmap2D;
25     procedure Log(aSender: TObject; const aMsg: String);
26     procedure Render;
27   public
28     { public declarations }
29   end;
30
31 var
32   MainForm: TMainForm;
33
34 implementation
35
36 {$R *.lfm}
37
38 uses
39   dglOpenGL, ugluVector;
40
41 const
42   SHADER_FILE  = 'shader.glsl';
43   TEXTURE_FILE = 'data\texture.png';
44
45   LAYOUT_LOCATION_POS = 0;
46   LAYOUT_LOCATION_TEX = 1;
47
48   UNIFORM_NAME_TEXTURE = 'uTexture';
49
50 type
51   TVertex = packed record
52     pos: TgluVector3f;
53     tex: TgluVector2f;
54   end;
55   PVertex = ^TVertex;
56
57 procedure TMainForm.FormCreate(Sender: TObject);
58 var
59   pf: TglcContextPixelFormatSettings;
60   p: PVertex;
61   texData: TglcBitmapData;
62 begin
63   pf := TglcContext.MakePF();
64   fContext := TglcContext.GetPlatformClass.Create(RenderPanel, pf);
65   fContext.BuildContext;
66
67   fShader := TglcShaderProgram.Create(@Log);
68   fShader.LoadFromFile(ExtractFilePath(Application.ExeName) + SHADER_FILE);
69   fShader.Compile;
70   fShader.Uniform1i(UNIFORM_NAME_TEXTURE, 0);
71
72   fVBO := TglcArrayBuffer.Create(TglcBufferTarget.btArrayBuffer);
73   fVBO.BufferData(4, sizeof(TVertex), TglcBufferUsage.buStaticDraw, nil);
74   p := fVBO.MapBuffer(TglcBufferAccess.baWriteOnly);
75   try
76     p^.pos := gluVector3f(-0.5, -0.5, 0);
77     p^.tex := gluVector2f( 0.0,  1.0);
78     inc(p);
79
80     p^.pos := gluVector3f( 0.5, -0.5, 0);
81     p^.tex := gluVector2f( 1.0,  1.0);
82     inc(p);
83
84     p^.pos := gluVector3f( 0.5,  0.5, 0);
85     p^.tex := gluVector2f( 1.0,  0.0);
86     inc(p);
87
88     p^.pos := gluVector3f(-0.5,  0.5, 0);
89     p^.tex := gluVector2f( 0.0,  0.0);
90     inc(p);
91   finally
92     fVBO.UnmapBuffer;
93   end;
94
95   fTexture := TglcBitmap2D.Create;
96   texData := TglcBitmapData.Create;
97   try
98     texData.LoadFromFile(ExtractFilePath(Application.ExeName) + TEXTURE_FILE);
99     fTexture.UploadData(texData);
100   finally
101     FreeAndNil(texData);
102   end;
103 end;
104
105 procedure TMainForm.ApplicationPropertiesIdle(Sender: TObject; var Done: Boolean);
106 begin
107   Render;
108   Done := false;
109 end;
110
111 procedure TMainForm.FormDestroy(Sender: TObject);
112 begin
113   FreeAndNil(fVBO);
114   FreeAndNil(fShader);
115   FreeAndNil(fContext);
116 end;
117
118 procedure TMainForm.RenderPanelResize(Sender: TObject);
119 begin
120   if Assigned(fContext) then begin
121     glViewport(0, 0, RenderPanel.ClientWidth, RenderPanel.ClientHeight);
122   end;
123 end;
124
125 procedure TMainForm.Log(aSender: TObject; const aMsg: String);
126 begin
127   LogLB.Items.Add(aMsg);
128 end;
129
130 procedure TMainForm.Render;
131 begin
132   glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT);
133   fVBO.Bind;
134   fTexture.Bind;
135   fShader.Enable;
136
137   glEnableVertexAttribArray(LAYOUT_LOCATION_POS);
138   glVertexAttribPointer(LAYOUT_LOCATION_POS, 3, GL_FLOAT, False, SizeOf(TVertex), @PVertex(nil)^.pos);
139
140   glEnableVertexAttribArray(LAYOUT_LOCATION_TEX);
141   glVertexAttribPointer(LAYOUT_LOCATION_TEX, 2, GL_FLOAT, False, SizeOf(TVertex), @PVertex(nil)^.tex);
142
143   glDrawArrays(GL_QUADS, 0, fVBO.DataCount);
144
145   glDisableVertexAttribArray(LAYOUT_LOCATION_POS);
146   glDisableVertexAttribArray(LAYOUT_LOCATION_TEX);
147
148   fShader.Disable;
149   fTexture.Unbind;
150   fVBO.Unbind;
151
152   fContext.SwapBuffers;
153 end;
154
155 end.
156