Страница 1 из 1

OpenGL - FreeGlut/Glut.

СообщениеДобавлено: 08.10.2020 11:42:36
Seenkao
FreeGlut - это расширение Glut.
Но на всех системах надо установить 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

Re: OpenGL - FreeGlut/Glut.

СообщениеДобавлено: 08.10.2020 22:11:01
Alex2013
Кстати никто еще не "подружил" Лазарус OpenVR и OpenGL :?:
Нужен хоть какой-то пример бо все мои адаптации сишных + "хитроумные хедеры OpenVR" для Лазаруса/Дельфи постоянно падают ( иногда даже с страшным БСОД-ом. )
Зы
Сети есть некий Benjamin Rosseaux но исходников демки PasOpenVR у него не выпросишь . :cry:
Зы Зы
Может кому то пригодится : :arrow: Примеры использования OpenGL в Lazarus :idea:

Re: OpenGL - FreeGlut/Glut.

СообщениеДобавлено: 09.10.2020 01:19:54
Seenkao
Alex2013 писал(а):Может кому то пригодится : :arrow: Примеры использования OpenGL в Lazarus :idea:

Данные примеры чисто под Glut, который всегда и везде работал. FreeGlut, даже на других языках недостаточно информации, а для MacOS вообще бедно.
Alex2013 писал(а):Кстати никто еще не "подружил" Лазарус OpenVR и OpenGL :?:

Я глянул быстро, что такое OpenVR. И судя по всему, просто ни кому нафиг не нужно переводить данную библиотеку на паскаль. Учитывая что выложены исходники напрямую и надо просто переделать код на паскаль.
Не проще скомпилировать из тех исходников библиотеку и пользоваться ей по мере надобности? (сильно не вникал! :) )

Re: OpenGL - FreeGlut/Glut.

СообщениеДобавлено: 09.10.2020 17:56:32
Alex2013
Честно говоря я в обычном OpenGL с Glu слабо разбираюсь (одну модель вести могу а вот сцену уже нет ).
.
Что касается OpenVR (и более продвинутого OpenXR ) то практически ВСЕ самоделки в области ВиАр делают с его помощью, еще есть libovr для стандарта окулус и его эмуляции но таскать лишних 10 гигов при использовании ВиАр девайсов отличных от окулус удовольствие сомнительное (тем более что обратная совместимость "Окулус с OpenVR"(точнее с SteamVR ) есть по умолчанию ) В принципе для меня есть возможность использовать АПИ от МS но это уже совсем "нишевой вариант" (что не очень интересно даже для разных самоделок ).

К сожалению что дельфи что лазарус оказались "на обочине ВиАр" (хотя даже питон в деле) и найти что-то вроде "набора примеров для начинающего" сложно. (Но ВиАР программы на обжект паскале пишут и весьма успешно )

Re: OpenGL - FreeGlut/Glut.

СообщениеДобавлено: 09.10.2020 21:11:00
Seenkao
Alex2013, OpenVR - посмотри тут. Я не думаю, что там несколько гигов.

Re: OpenGL - FreeGlut/Glut.

СообщениеДобавлено: 10.10.2020 14:44:13
Alex2013
Seenkao писал(а):Alex2013, OpenVR - посмотри тут. Я не думаю, что там несколько гигов.

Спасибо ! Но мне вообще-то нужна именно адаптация (и особенно примеры ) на Обжект Паскаль
Беда в том что OpenVR написан на "бескомпромиссном" Си++ то есть из DLL нужно брать именно КЛАССЫ С++.
Кое-что я уже нашел .
openVR_header.pas Хедер библиотеки openvr_api.dll
и
PasVulkan.VirtualReality.OpenVR.pas

Но без примеров понять как эту хитрую "обвязку" использовать не получается .

Re: OpenGL - FreeGlut/Glut.

СообщениеДобавлено: 11.10.2020 02:35:14
Seenkao

Re: OpenGL - FreeGlut/Glut.

СообщениеДобавлено: 12.10.2020 17:49:51
Alex2013
Seenkao писал(а):Alex2013, тебе надо искать подобное?

Что-то похожие но ближе к паскалю ... (Но вообще, даже если исходник, на хорошо знакомом паскале, далеко не факт, что его можно использовать "как есть" - например есть СДК на Дельфи для Окулуса но собрать его в Лазарус как оказалось задача далеко не тривиальная . )

Re: OpenGL - FreeGlut/Glut.

СообщениеДобавлено: 17.10.2020 04:13:59
Seenkao
Шапку обновил, код не включён в шапку.

Добавлю код для работы с FreeGlut, может полезно кому будет, да и я не потеряю. :)
Код: Выделить всё
program GLUT_non_LCL;

{$mode objfpc}{$H+}

uses
  {$IFDEF UNIX}{$IFDEF UseCThreads}
  cthreads,
  {$ENDIF}{$ENDIF}
  sysutils, windows,
  GL, glu, FreeGlut, Glut;
//  newGlut;        используйте freeglut и glut, это идентичная библиотека, которая включила обе части.

const
  AppWidth  = 800;
  AppHeight = 600;

  // мышь
  MB_LEFT   = 1;
  MB_RIGHT  = 2;
  MB_MIDDLE = 4;

type
  XYZ_Col = record
    X, Y, Z: Single;
    R, G, B: Single;
  end;

var
  ScreenWidth, ScreenHeight: Integer;
  point: array[0..3] of XYZ_Col;
  angle: array [0..2] of Single;
  MB_Down, MB_Up: Byte;

  mouseX, mouseY: Integer;
  myTimeUse: Integer = 1;
  KeyDown: array[0..255] of Boolean;

  winOn: Boolean = False;
  oldFPS, newFPS, maxFPS: Single;
  Z: Integer = 0;

procedure glutInitPascal(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);

  // ------------------------------------
  point[0].X := 0;
  point[0].Y := 1;
  point[0].Z := 0;
  point[0].R := 1;
  point[0].G := 0;
  point[0].B := 0;

  point[1].X := - 0.8;
  point[1].Y := - 0.5;
  point[1].Z := 0.5;
  point[1].R := 0;
  point[1].G := 1;
  point[1].B := 0;

  point[2].X := 0.8;
  point[2].Y := - 0.5;
  point[2].Z := 0.5;
  point[2].R := 0;
  point[2].G := 0;
  point[2].B := 1;

  point[3].X := 0;
  point[3].Y := - 0.5;
  point[3].Z := - 0.8;
  point[3].R := 0.7;
  point[3].G := 0;
  point[3].B := 0.7;

  angle[0] := 50;
  angle[1] := 3;
  angle[2] := 236;
  // ------------------------------------
  glutGameModeString('800x600:16@60');   // обратить особое внимание! Это запрос полноэкранного режима, существует он или нет.
                                      // В Linux не надо прописывать :16@60 - оно там не работает для FreeGlut
end;

procedure DrawGL; cdecl;
begin
  glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT);
  glLoadIdentity;

  glTranslatef(0, 0, - 3);

  glRotatef(angle[0], 1, 0, 0);
  glRotatef(angle[1], 0, 1, 0);
//  glRotatef(angle[2], 0, 0, 1);

  glBegin(GL_TRIANGLES);
    glColor3f(point[0].R, point[0].G, point[0].B);
    glVertex3f(point[0].X, point[0].Y, point[0].Z);
    glColor3f(point[1].R, point[1].G, point[1].B);
    glVertex3f(point[1].X, point[1].Y, point[1].Z);
    glColor3f(point[2].R, point[2].G, point[2].B);
    glVertex3f(point[2].X, point[2].Y, point[2].Z);

    glColor3f(point[3].R, point[3].G, point[3].B);
    glVertex3f(point[3].X, point[3].Y, point[3].Z);
    glColor3f(point[1].R, point[1].G, point[1].B);
    glVertex3f(point[1].X, point[1].Y, point[1].Z);
    glColor3f(point[2].R, point[2].G, point[2].B);
    glVertex3f(point[2].X, point[2].Y, point[2].Z);

    glColor3f(point[0].R, point[0].G, point[0].B);
    glVertex3f(point[0].X, point[0].Y, point[0].Z);
    glColor3f(point[3].R, point[3].G, point[3].B);
    glVertex3f(point[3].X, point[3].Y, point[3].Z);
    glColor3f(point[2].R, point[2].G, point[2].B);
    glVertex3f(point[2].X, point[2].Y, point[2].Z);

    glColor3f(point[0].R, point[0].G, point[0].B);
    glVertex3f(point[0].X, point[0].Y, point[0].Z);
    glColor3f(point[1].R, point[1].G, point[1].B);
    glVertex3f(point[1].X, point[1].Y, point[1].Z);
    glColor3f(point[3].R, point[3].G, point[3].B);
    glVertex3f(point[3].X, point[3].Y, point[3].Z);
  glEnd;

  glutSwapBuffers;
end;

procedure ReSizeGLScene(Width, Height: Integer); cdecl;
begin
  if Height = 0 then
    Height := 1;

  glViewport(0, 0, Width, Height);
  glMatrixMode(GL_PROJECTION);
  glLoadIdentity;
  gluPerspective(45, Width / Height, 0.1, 1000);

  glMatrixMode(GL_MODELVIEW);
  glLoadIdentity;
end;

// обработка клавиатуры, нажатие!!!!
procedure GLKeyboard(Key: Byte; X, Y: LongInt); cdecl;
begin
  inc(z);
  if Key = 27 then
//    glutLeaveMainLoop;
    winOn := False;                   // закрываем если Escape
  if (key = 119) {and (not KeyDown[Key])} then
  begin
    myTimeUse := myTimeUse + 10;
    if myTimeUse > 200 then myTimeUse := 200;

  end;
  if (key = 115) and (not KeyDown[Key]) then
  begin

    if myTimeUse < 20 then
      myTimeUse := myTimeUse - 3
    else
      myTimeUse := myTimeUse - 10;
    if myTimeUse < 1 then myTimeUse := 1;
  end;
  KeyDown[key] := true;
//  glutSetWindowTitle(PChar('time: ' + IntToStr(myTimeUse)));
  glutSetWindowTitle(Pchar(IntToStr(z)));
end;

// обработка отпускания клавиши
procedure GLKeyboardUp(Key: Byte; X, Y: LongInt); cdecl;
begin
  KeyDown[key] := False;
end;

// обработка специальных клавиш, нажатие!!!!
procedure GLSpecKeyboard(Key, X, Y: LongInt); cdecl;
begin

end;

// обработка отпускания специальных клавиш
procedure GLSpecKeyboardUp(Key, X, Y: LongInt); cdecl;
begin

end;

// закрываем окно
procedure ClozeGL; cdecl;
begin
  winOn := False;
//  glutLeaveMainLoop
end;

// таймер основного процесса, возможно нужен таймер для прорисовки???
procedure MyTimerGL(value: Integer); cdecl;
var
  i: Integer;
begin
  if (MB_Down and MB_LEFT) > 0 then  ;

  if (MB_Down and MB_LEFT) > 0 then ;

  angle[0] := angle[0] + 0.5;
  if angle[0] > 360 then angle[0] := 0;
  angle[1] := angle[1] + 0.5;
  if angle[1] > 360 then angle[1] := 0;
  angle[2] := angle[2] + 0.5;
  if angle[2] > 360 then angle[2] := 0;

  if newFPS > (oldFPS + maxFPS) then
  begin
    glutPostRedisplay;
    oldFPS := oldFPS + maxFPS;
  end;

  glutTimerFunc(myTimeUse, @MyTimerGL, value);          // создать структуру таймеров.
  newFPS := newFPS + myTimeUse;
end;

// обработка мыши
procedure MouseGL(button, state, X, Y: Integer); cdecl;
var
  n: Byte;
begin
  n := button;

  if state = GLUT_UP then
    begin
     if button = GLUT_LEFT_BUTTON then
     begin
       MB_Down := MB_Down and (255 - MB_LEFT);
       MB_Up := MB_Up or MB_LEFT;
     end;
     if button = GLUT_RIGHT_BUTTON then
     begin
       MB_Down := MB_Down and (255 - MB_RIGHT);
       MB_Up := MB_Up or MB_RIGHT;
     end;
     if button = GLUT_MIDDLE_BUTTON then
     begin
       MB_Down := MB_Down and (255 - MB_MIDDLE);
       MB_Up := MB_Up or MB_MIDDLE;
     end;
     KeyDown[n] := false;               // клавиши с минимальным кодом всё равно не используются, используем пространство для мыши
    end;

  if state = GLUT_DOWN then
  begin
   if button = GLUT_LEFT_BUTTON then
   begin
     MB_Down := MB_Down or MB_LEFT;
     MB_Up := MB_Up and (255 - MB_LEFT);
   end;
   if button = GLUT_RIGHT_BUTTON then
   begin
     MB_Down := MB_Down or MB_RIGHT;
     MB_Up := MB_Up and (255 - MB_RIGHT);
   end;
   if button = GLUT_MIDDLE_BUTTON then
   begin
     MB_Down := MB_Down or MB_MIDDLE;
     MB_Up := MB_Up and (255 - MB_MIDDLE);
   end;
   KeyDown[n] := true;
  end;

  mouseX := X;
  mouseY := Y;
end;

// ролик мыши
procedure MouseWheelGL(wheel, dir, X, Y: Integer); cdecl;
begin

end;

var
  win00: Integer;
  myWND: HWND;
begin
  glutInitPascal(true);
  glutInitDisplayMode(GLUT_DOUBLE or GLUT_RGB or GLUT_DEPTH);
  glutInitWindowSize(AppWidth, AppHeight);
       //----------------------------------------
  glutInitContextVersion(2, 1);
  glutInitContextProfile(GLUT_COMPATIBILITY_PROFILE);
       //----------------------------------------
  ScreenWidth := glutGet(GLUT_SCREEN_WIDTH);
  ScreenHeight := glutGet(GLUT_SCREEN_HEIGHT);
  glutInitWindowPosition((ScreenWidth - AppWidth) div 2, (ScreenHeight - AppHeight) div 2);
  win00 := glutCreateWindow('OpenGL testing mouse and keyboard.');

  // хендл окна
  myWND := WindowFromDC(wglGetCurrentDC);

  // устанавливаем стиль окна
  SetWindowLongPtr(myWND, GWL_STYLE, WS_CAPTION or WS_MINIMIZEBOX or WS_SYSMENU or WS_VISIBLE);
  // устанавливаем размеры окна.
  SetWindowPos(myWND, HWND_TOPMOST, (ScreenWidth - AppWidth) div 2, (ScreenHeight - AppHeight) div 2, AppWidth, AppHeight, SWP_NOACTIVATE);

  glClearColor(0.48, 0.6, 0.86, 1.0);

// initializing
  glutDisplayFunc(@DrawGL);
  glutReshapeFunc(@ResizeGLScene);
  glutKeyboardFunc(@GLKeyboard);
  glutKeyboardUpFunc(@GLKeyboardUp);
  glutCloseFunc(@ClozeGL);
  glutMouseFunc(@MouseGL);
  glutMouseWheelFunc(@MouseWheelGL);
  glutSpecialFunc(@GLSpecKeyboard);
  glutSpecialUpFunc(@GLSpecKeyboardUp);

  glClearDepth(1.0);
  glDepthFunc(GL_LESS);
  glEnable(GL_DEPTH_TEST);

  oldFPS := 0;
  newFPS := 0;
  maxFPS := 1000 / 60;
  winOn := True;

  if glutGameModeGet(GLUT_GAME_MODE_POSSIBLE) = 1 then    // а здесь, мы проверяем существует ли запрошенный в начале программы
    glutTimerFunc(50, @MyTimerGL, 0);                      // режим (800х600), и включаем таймер, если режим существует

  while winOn do
  begin
    glutMainLoopEvent;
    inc(z);
  end;
  glutLeaveMainLoop;
  glutDestroyWindow(win00);
end.

Данный код, для "вылавливания" хендла окна (пример для Windows) и после получения хендла, мы можем использовать стандартные функции данного окна, без обращения к функциям окна через FreeGlut.

Особенность FreeGlut: при использовании glutSwapBuffers, все процессы будут заморожены, пока не выполнится данная команда, поэтому надо вводить ограничения на использование данной функции, особенно в *nix системах, там очень сильно работает задержка. В данном коде ограничение 60FPS.

Re: OpenGL - FreeGlut/Glut.

СообщениеДобавлено: 19.10.2020 13:00:06
Seenkao
Делал, делал, подгонял всё... А б... на маке половина не работает... Матов не хватает.

В glutInitDisplayMode можно установить флаги, которые убирают системное меню (закрыть, свернуть, развернуть), а так же убирают рамку окна. Для Windows работает и только для FreeGlut.

Таймер, думаю, лучше использовать внешний и вызывать glutMainLoopEvent, вместо зацикленного glutMainLoop - это даст больше свободы.

Не забываем, glutSwapBuffers останавливает все процессы, пока не пройдёт задержка по времени (glFlush?) и она не отдаст свободное время программе. Так же функция glutReshapeFunc - она вообще полностью блокирует все процессы GLUT пока пользователь не отпустит кнопку мыши. Это можно обойти, хорошенько подумав (а нужно ли? Ведь выше есть флаги, которые запрещают изменять размер окна).

На этом всё. Забиваю на FreeGlut. Вставляю в ZenGL для MacOS как есть и наплевать. Буду переделывать, если на новых версиях Мака не откажутся полностью от OpenGL. А так... могу только извинится перед пользователями(программистами) MacOS.

под шумок... ссылку наверняка удалят, а интересного много найти можно: http://iihm.imag.fr/blanch/software/glut-macosx/

Re: OpenGL - FreeGlut/Glut.

СообщениеДобавлено: 23.10.2020 15:20:41
Seenkao
Ковырялся... ковырялся... всё искал решение. Видел, что у MacOS было низкоуровневое обращение через CGL (Core GL). И решил поискать по данному запросу... и случайно нашёл ссылочку http://www.dxgames.narod.ru/other/cgl/cgl.htm - А? Что? Что я сейчас только что прочитал? CGL посредством GLUT? :shock:
ТАК GLUT В MACOS - ЭТО САМЫЙ НИЗКИЙ УРОВЕНЬ ДЛЯ ИСПОЛЬЗОВАНИЯ OPENGL???? :shock: :shock: :shock:

Я решил проверить, ведь всё-таки ссылка больше к какой-то винде подходит, чем к маку. Залез в Macintosh, полез искать GLUT и... дальше я уже не удивлялся.

GLUT на MacOS - весит 1мб. Все CGL, NS* и похоже многое другое в себе уже и содержит GLUT. (мне вот интересно, а они разрешение у разработчика GLUT на его изменение брали? И сами требуют для всего лицензий... А то такая система, но пользуется библиотекой более чем 20-ти летней давности и при чём дорабатывает её сама.)

Но это всё догадки. Но то, что GLUT - это самый низкий уровень очень большое подозрение.

Добавлено спустя 56 минут 41 секунду:
Да, там указано, что от разработчика библиотека идёт. (вроеде как).

Re: OpenGL - FreeGlut/Glut.

СообщениеДобавлено: 26.10.2020 14:45:58
CynicRus
Для MacOS это сизифов труд, поскольку OpenGL в MacOS deprecated с 2018 года. У них есть свой Metal API.

Re: OpenGL - FreeGlut/Glut.

СообщениеДобавлено: 26.10.2020 16:35:08
Seenkao
Да, я помню об этом. Поэтому и хочу малыми затратами труда создать именно нативное приложение. И, если в следующей версии (16-й) поддержка OpenGL так и останется (не выпилится полностью), то буду уже более конкретно решать проблему на Маке.

И... вообще это бред, по поводу отказа Apple от OpenGL. OpenGL не зависит от системы, он зависит от видеокарты, и если разработчик видеокарт поддерживает OpenGL, то MacOS не может ни как влиять на работу с OpenGL, лишь программно. Где, человек, использующий видеокарту поддерживающую OpenGL, вправе использовать его.

Блин... какой-то замкнутый круг... Вероятно у них на примете есть производитель видеокарт, который будет поддерживать только Metal?