<code>
import random
</code>
type
TGLForm1 = class(TForm)
ErrorTimer: TTimer;
procedure ErrorTimerTimer(Sender: TObject);
procedure FormCreate(Sender: TObject);
procedure GLboxPaint(Sender: TObject);
procedure MouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer);
procedure MouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
procedure MouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
procedure ShowmessageError(s: string);
private
public
end;
var
GLForm1: TGLForm1;
implementation
{$R *.lfm}
type
TShader = record
Init: boolean;
vbo_point, vao_point, shaderProgram, vertexArrayObject: GLuint;
uniform_angle: GLint;
end;
var
gShader: TShader;
GLBox:TOpenGLControl;
gGLerror : string = '';
gRotation : integer = 30;
gMouseY : integer = -1;
procedure TGLForm1.ShowmessageError(s: string);
begin
if gGLerror <> '' then exit;
gGLerror := s;
ErrorTimer.Enabled := true;
end;
procedure ReportErrorsGL(glObjectID: GLuint);
var
s : string;
maxLength : GLint;
begin
glGetShaderiv(glObjectID, GL_INFO_LOG_LENGTH, @maxLength);
if (maxLength < 1) then exit;
setlength(s, maxLength);
glGetShaderInfoLog(glObjectID, maxLength, maxLength, @s[1]);
s:=trim(s);
GLForm1.ShowmessageError('GLSL error '+s);
end;
const
kVert = '#version 330'
+#10'layout(location = 0) in vec2 point;'
+#10'uniform float angle;'
+#10'void main() {'
+#10' mat2 rotate = mat2(cos(angle), -sin(angle),sin(angle), cos(angle));'
+#10' gl_Position = vec4(0.75 * rotate * point, 0.0, 1.0);'
+#10'}';
kFrag = '#version 330'
+#10'out vec4 color;'
+#10'void main() {'
+#10' color = vec4(1, 0.15, 0.15, 0);'
+#10'}';
procedure GetError(p: integer);
var
Error: GLenum;
s: string;
begin
Error := glGetError();
if Error = GL_NO_ERROR then exit;
s := inttostr(p)+'->';
if Error = GL_INVALID_ENUM then
s := s+'GL_INVALID_ENUM'
else if Error = GL_INVALID_VALUE then
s := s+'GL_INVALID_VALUE'
else
s := s + inttostr(Error);
GLForm1.ShowmessageError('GLSL error : '+s );
end;
function compileShaderOfType (shaderType: GLEnum; shaderText: string): GLuint;
var
status: GLint;
begin
result := glCreateShader(shaderType);
glShaderSource(result, 1, PPGLChar(@shaderText), nil);
glCompileShader(result);
ReportErrorsGL(result);
status := 0;
glGetShaderiv(result, GL_COMPILE_STATUS, @status);
if (status = 0) then begin
GLForm1.ShowmessageError('GLSL shader failure ' );
end;
end;
function initVertFrag(vert, frag: string): GLuint;
var
fr, vt: GLuint;
begin
result := 0;
vt := compileShaderOfType(GL_VERTEX_SHADER, vert);
fr := compileShaderOfType(GL_FRAGMENT_SHADER, frag);
if (fr = 0) or (vt = 0) then exit;
result := glCreateProgram();
glAttachShader(result, vt);
glAttachShader(result, fr);
glBindFragDataLocation(result, 0, 'fragColour');
glLinkProgram(result);
glDeleteShader(vt);
glDeleteShader(fr);
GetError(1);
end;
procedure LoadBufferData;
const
kATTRIB_POINT = 0;
SQUARE : array [0..7] of single = (
-1.0, 1.0,
-1.0, -1.0,
1.0, 1.0,
1.0, -1.0);
begin
glGenBuffers(1, @gShader.vbo_point);
glBindBuffer(GL_ARRAY_BUFFER, gShader.vbo_point);
glBufferData(GL_ARRAY_BUFFER, sizeof(SQUARE), @SQUARE[0], GL_STATIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glGenVertexArrays(1, @gShader.vao_point);
glBindVertexArray(gShader.vao_point);
glBindBuffer(GL_ARRAY_BUFFER, gShader.vbo_point);
glVertexAttribPointer(kATTRIB_POINT, 2, GL_FLOAT, FALSE, 0, nil);
glEnableVertexAttribArray(kATTRIB_POINT);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindVertexArray(0);
gShader.uniform_angle := glGetUniformLocation(gShader.shaderProgram, pAnsiChar('angle'));
GetError(2);
end;
procedure InitGL;
begin
if not gShader.Init then exit;
gShader.Init := false;
InitOpenGL;
ReadExtensions;
GLForm1.caption := glGetString(GL_VENDOR)+'; OpenGL= '+glGetString(GL_VERSION)+'; Shader='+glGetString(GL_SHADING_LANGUAGE_VERSION);
gShader.shaderProgram := initVertFrag(kVert, kFrag);
LoadBufferData;
end;
procedure TGLForm1.GLboxPaint(Sender: TObject);
begin
InitGL;
glClearColor(0.1, 0.1, 0.4, 1.0);
glClear(GL_COLOR_BUFFER_BIT);
glUseProgram(gShader.shaderProgram);
glUniform1f(gShader.uniform_angle, gRotation/90) ;
glBindVertexArray(gShader.vao_point);
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
glBindVertexArray(0);
glUseProgram(0);
GLbox.SwapBuffers;
end;
procedure TGLForm1.MouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer);
begin
if gMouseY < 0 then exit;
gRotation := gRotation + (Y - gMouseY);
gMouseY := Y;
GLBox.Invalidate;
end;
procedure TGLForm1.MouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
begin
gMouseY := -1;
end;
procedure TGLForm1.MouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
begin
gMouseY := Y;
end;
procedure TGLForm1.FormCreate(Sender: TObject);
begin
gShader.Init := true;
GLbox:= TOpenGLControl.Create(GLForm1);
{$IFDEF LCLCarbon}
Error: Carbon only supports Legacy OpenGL. Solution: compile to the Cocoa widgetset (Project/ProjectOptions/Additions&Overrides)
{$ENDIF}
GLbox.OpenGLMajorVersion:= 3;
GLbox.OpenGLMinorVersion:= 2;
GLbox.AlphaBits:= 8;
GLbox.AutoResizeViewport:= true;
GLBox.Parent := self;
GLBox.MultiSampling:= 4;
GLBox.Align := alClient;
GLBox.OnPaint := @GLboxPaint;
GLBox.OnMouseDown := @MouseDown;
GLBox.OnMouseMove := @MouseMove;
GLBox.OnMouseUp := @MouseUp;
GLBox.invalidate;
end;
procedure TGLForm1.ErrorTimerTimer(Sender: TObject);
begin
ErrorTimer.Enabled := false;
if gGLError = '' then exit;
Showmessage(gGLError);
gGLError := '';
end;
end.
>>56358300
What does this (and others) actually do?
>>56358300
>>56358316
>>56358335
>>56358352
>samefag
why you do this, desu senpai?
>>56358700
Because 2,000 character limit. It's [s]moot's[/s]hiro's fault.
>>56358354
Pic related.
>>56358758
Wow, what a bloated piece of shit library..
>>56359756
You just found out why everybody uses Direct3D instead of OpenGL.