Но на всех системах надо установить FreeGlut !
На Windows дополнительно надо смотреть 32-х разрядная система или 64-х. Обычно оба DLL идут в одном архиве.
На Linux просто установить FreeGlut.
А вот на MacOS будет подольше.
XQuartz - скачиваем и устанавливаем.
Brew - следуем инструкциям
- Код: Выделить всё
- program Glut_01;
 {$mode objfpc}{$H+}
 {.$Define CORE_GL}
 uses
 // установил freeGlut3 и теперь можно запускать
 dynlibs, sysutils,
 GL, glu, Glut, FreeGlut, GLext;
 const
 AppWidth = 800;
 AppHeight = 600;
 type
 point = array[1..2] of GLfloat;
 {$IfDef CORE_GL}
 TShader = record
 vbo_point, vao_point, shaderProgram, vertexArrayObject: GLuint;
 uniform_viewportSize: GLint;
 end;
 TAAPLVertex = record
 position: array [0..1] of single;
 color: array [0..2] of single;
 end;
 {$EndIf}
 var
 {$IfnDef CORE_GL}
 p: point = (0.0, 0.0);
 vertices: array[1..3] of point = ((0.0, 0.0), (400.0, 600.0),(800.0, 0.0));
 {$Else}
 gOffsetXY: point = (0, 0);
 gSize: Single = 100;
 gShader: TShader;
 verts: array[0..2] of TAAPLVertex;
 GLErrorStr: string = '';
 {$EndIf}
 {$IFDEF CORE_GL}
 const
 //Simple Vertex Shader
 kVert = '#version 330'
 +#10'layout(location = 0) in vec2 position;'
 +#10'layout(location = 1) in vec3 color;'
 +#10'out vec3 fClr;'
 +#10'uniform vec2 viewportSize;'
 +#10'void main() {'
 +#10' gl_Position = vec4((position / (viewportSize/2)), 0.0, 1.0);'
 +#10' fClr = color;'
 +#10'}';
 //Simple Fragment Shader
 kFrag = '#version 330'
 +#10'in vec3 fClr;'
 +#10'out vec4 color;'
 +#10'void main() {'
 +#10' color = vec4(fClr, 1);'
 +#10'}';
 procedure ReportErrorsGL(glObjectID: GLuint);
 var
 s : string;
 maxLength : GLint;
 begin
 glGetShaderiv(glObjectID, GL_INFO_LOG_LENGTH, @maxLength);
 if (maxLength < 2) then exit;
 setlength(s, maxLength);
 glGetShaderInfoLog(glObjectID, maxLength, @maxLength, @s[1]);
 s:=trim(s);
 if GLErrorStr = '' then begin
 GLErrorStr := 'GLSL error '+s;
 {$IFDEF UNIX}writeln(GLErrorStr); {$ENDIF}
 end;
 end;
 procedure GetError(p: integer; str: string = ''); //report OpenGL Error
 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' //out of range https://www.khronos.org/registry/OpenGL-Refpages/es2.0/xhtml/glGetError.xml
 else
 s := s + inttostr(Error);
 if GLErrorStr = '' then begin
 GLErrorStr := 'GLSL error '+str+s;
 {$IFDEF UNIX}writeln(GLErrorStr);{$ENDIF}
 end;
 end;
 function compileShaderOfType (shaderType: GLEnum; shaderText: string): GLuint;
 var
 status: GLint;
 begin
 result := glCreateShader(shaderType);
 glShaderSource(result, 1, PChar(@shaderText), nil);
 glCompileShader(result);
 ReportErrorsGL(result);
 status := 0;
 glGetShaderiv(result, GL_COMPILE_STATUS, @status);
 if (status = 0) and (GLErrorStr = '') then begin //report compiling errors.
 GLErrorStr := 'GLSL shader compile failure';
 end;
 end;
 procedure ReportCompileProgramError(glObjectID: GLuint);
 var
 s : string;
 maxLength : GLint;
 begin
 glGetProgramiv(glObjectID, GL_LINK_STATUS, @maxLength);
 //if (maxLength = GL_TRUE) then exit;
 if (maxLength = 1) then exit; //DGL GL_TRUE
 maxLength := 4096;
 setlength(s, maxLength);
 glGetProgramInfoLog(glObjectID, maxLength, @maxLength, @s[1]);
 if maxLength < 1 then begin
 if GLErrorStr = '' then
 GLErrorStr := ('Program compile error (unspecified)');
 exit
 end;
 s:=trim(s);
 if (length(s) < 2) then exit;
 if GLErrorStr = '' then
 GLErrorStr := ('Program compile error '+s);
 end;
 function initVertFrag(vert, frag: string): GLuint;
 var
 fs, vs: GLuint;
 begin
 result := 0;
 vs := 0;
 glGetError();
 result := glCreateProgram();
 if (length(vert) > 0) then begin
 vs := compileShaderOfType(GL_VERTEX_SHADER, vert);
 if (vs = 0) then exit;
 glAttachShader(result, vs);
 end;
 fs := compileShaderOfType(GL_FRAGMENT_SHADER, frag);
 if (fs = 0) then exit;
 glAttachShader(result, fs);
 glLinkProgram(result);
 ReportCompileProgramError(result);
 if (length(vert) > 0) then begin
 glDetachShader(result, vs);
 glDeleteShader(vs);
 end;
 glDetachShader(result, fs);
 glDeleteShader(fs);
 GetError(123,'newShader');
 glGetError();
 end;
 function initVertFragX(vert, frag: string): GLuint;
 var
 fr, vt: GLuint;
 begin
 result := 0;
 glGetError(); //<- ignore proior errors
 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, 'FragColor');
 glLinkProgram(result);
 glDeleteShader(vt);
 glDeleteShader(fr);
 GetError(1,'initX');
 glGetError(); //<- ignore proior errors
 end;
 procedure LoadBufferData (isInit: boolean);
 const
 kATTRIB_POINT = 0;
 kATTRIB_COLOR = 1;
 var
 verts: array[0..2] of TAAPLVertex;
 begin
 verts[0].position[0] := gOffsetXY[1] + gSize;
 verts[0].position[1] := gOffsetXY[2] - gSize;
 verts[0].color[0] := 1;
 verts[0].color[1] := 0;
 verts[0].color[2] := 0;
 verts[1].position[0] := gOffsetXY[1] - gSize;
 verts[1].position[1] := gOffsetXY[2] - gSize;
 verts[1].color[0] := 0;
 verts[1].color[1] := 1;
 verts[1].color[2] := 0;
 verts[2].position[0] := gOffsetXY[1];
 verts[2].position[1] := gOffsetXY[2] + gSize;
 verts[2].color[0] := 0;
 verts[2].color[1] := 0;
 verts[2].color[2] := 2;
 if (not isInit) then begin
 glBindBuffer(GL_ARRAY_BUFFER, gShader.vbo_point);
 glBufferSubData(GL_ARRAY_BUFFER,0,sizeof(verts), @verts[0]);
 glBindBuffer(GL_ARRAY_BUFFER, 0);
 exit;
 end;
 glGenBuffers(1, @gShader.vbo_point);
 glBindBuffer(GL_ARRAY_BUFFER, gShader.vbo_point);
 glBufferData(GL_ARRAY_BUFFER, sizeof(verts), @verts[0], GL_STATIC_DRAW);
 glBindBuffer(GL_ARRAY_BUFFER, 0);
 // Prepare vertrex array object (VAO)
 // glGenVertexArrays intoduced with OpenGL 3.0
 glGenVertexArrays(1, @gShader.vao_point);
 glBindVertexArray(gShader.vao_point);
 glBindBuffer(GL_ARRAY_BUFFER, gShader.vbo_point);
 glVertexAttribPointer(kATTRIB_POINT, 2, GL_FLOAT, GL_FALSE, 5*4, PChar(0));
 glEnableVertexAttribArray(kATTRIB_POINT);
 glVertexAttribPointer(kATTRIB_COLOR, 3, GL_FLOAT, GL_FALSE, 5*4, PChar(sizeof(single)*2));
 glEnableVertexAttribArray(kATTRIB_COLOR);
 glBindBuffer(GL_ARRAY_BUFFER, 0);
 glBindVertexArray(0);
 gShader.uniform_viewportSize := glGetUniformLocation(gShader.shaderProgram, pAnsiChar('viewportSize'));
 end;
 {$ENDIF}
 procedure MyGlutInit(ParseCmdLine: Boolean); // у меня уже создана, скопирую
 var
 Cmd: array of PChar;
 CmdCount, i: Integer;
 begin
 if ParseCmdLine then
 CmdCount := ParamCount + 1
 else
 CmdCount := 1;
 SetLength(Cmd, CmdCount);
 for i := 0 to CmdCount - 1 do
 Cmd[i] := PChar(ParamStr(i));
 GlutInit(@CmdCount, @Cmd);
 end;
 procedure MyDrawScene; cdecl;
 {$IfnDef CORE_GL}
 var
 i, j: Integer;
 {$EndIf}
 begin
 {$IfnDef CORE_GL}
 glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT);
 glLoadIdentity;
 glColor3f(0, 0, 0);
 for i := 1 to 250000 do
 begin
 j := Random(3) + 1;
 p[1] := (p[1] + vertices[j, 1]) / 2;
 p[2] := (p[2] + vertices[j, 2]) / 2;
 glBegin(GL_POINTS);
 glVertex2fv(@p);
 glEnd;
 end;
 {$Else}
 LoadBufferData(false);
 glClearColor(0.0, 0.0, 0.7, 1.0); //Set blue background
 glClear(GL_COLOR_BUFFER_BIT);
 glDisable(GL_DEPTH_TEST);
 glUseProgram(gShader.shaderProgram);
 glUniform2f(gShader.uniform_viewportSize, AppWidth, AppHeight);
 glBindVertexArray(gShader.vao_point);
 glDrawArrays(GL_TRIANGLE_STRIP, 0, 3);
 glBindVertexArray(0);
 glUseProgram(0);
 {$ENDIF}
 glutSwapBuffers;
 end;
 procedure MyResizeScene(width, height: Integer); cdecl;
 begin
 if height = 0 then height := 1;
 glViewport(0, 0, width, height);
 glMatrixMode(GL_PROJECTION);
 glLoadIdentity;
 gluOrtho2D(0, width, 0, height);
 // gluPerspective(45, width / height, 0.1, 1000);
 glMatrixMode(GL_MODELVIEW);
 glLoadIdentity;
 end;
 procedure GLKeyboard(Key: Byte; x, y: LongInt); cdecl;
 begin
 if Key = 27 then halt(0);
 end;
 var
 ScreenWidth, ScreenHeight: Integer;
 begin
 {$IfDef MacOSAll}
 // для MacOS вручную прописываем путь, куда установили FreeGlut
 LoadFreeGlut(LoadLibrary('/usr/local/Cellar/freeglut/3.2.1/lib/libglut.dylib'));
 // у меня был путь "/usr/local/Cellar/freeglut/3.2.1" оставшуюся часть
 // надо добавить (не знаю, может у кого другой путь будет)
 {$EndIf}
 Randomize;
 MyGlutInit(True);
 glutInitDisplayMode(GLUT_DOUBLE or GLUT_RGB or GLUT_DEPTH);
 glutInitWindowSize(AppWidth, AppHeight);
 ScreenWidth := glutGet(GLUT_SCREEN_WIDTH);
 ScreenHeight := glutGet(GLUT_SCREEN_HEIGHT);
 glutInitWindowPosition((ScreenWidth - AppWidth) div 2, (ScreenHeight - AppHeight) div 2);
 {$IfDef CORE_GL}
 glutInitContextProfile(GLUT_CORE_PROFILE);
 glutInitContextVersion(3, 3);
 {$Else}
 glutInitContextProfile(GLUT_CORE_PROFILE);
 glutInitContextVersion(2, 1);
 {$EndIf}
 glutCreateWindow('OpenGL - Glut');
 {$IfDef CORE_GL}
 Load_GL_version_3_3_CORE();
 gShader.shaderProgram := initVertFrag(kVert, kFrag);
 LoadBufferData(true);
 {$EndIf}
 glClearColor(0.18, 0.20, 0.66, 0);
 glutDisplayFunc(@MyDrawScene);
 glutReshapeFunc(@MyResizeScene);
 glutKeyboardFunc(@GLKeyboard);
 glutMainLoop;
 end.
Из плюсов - достаточно минимальное приложение получается. Можно самому создать окно и "прицепить" Glut к вашему окну, оставив обработки событий вам.
Из минусов - надо разбираться с Glut. Информация в сети, в основном идентичная.
Добавлено спустя 1 час 45 минут 50 секунд:
Подредактировал, теперь пример с шейдерами включён.
Включите дефайн CORE_GL - для использования OpenGL 3.3
Да, похоже, Glut по умолчанию блокирует режим совместимости, поэтому либо шейдеры, либо прямой доступ.
Видео, где излагаю работу с FreeGlut:
Предоставил видео в качестве урока
Сопутствующее видео, решил проблему вывода изображения в Linux
А здесь показал как можно использовать данное окно через WinAPI



 
  
 
  
 )
  )