25'ten fazla konu seçemezsiniz Konular bir harf veya rakamla başlamalı, kısa çizgiler ('-') içerebilir ve en fazla 35 karakter uzunluğunda olabilir.

171 satır
3.8 KiB

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