Получил боле-менее стабильное вращение без ошибок и лишних усложнений программы.
Еле-еле мне удалось обнаружить суть проблемы, проведя небольшое исследование.
Сгенерировал такой код (многие ругают меня, что у меня много предупреждений от компилятора - но так и работы я за краткие промежутки времени делаю больше, и если что-то не используется вдруг, то значит это применялось в опробировании вариантов исполнения), после чего вращение камеры стало вполне предсказуемым, а надобность в отслеживании OpenGLControl1MouseUp отпала
			   
				   
					   
	
				   
			   
Но, выяснилась одна деталь. Сейчас сначала расшифрую эту строку например
	
поворот камеры.
AngleX -величина угла, на который производится поворот. И далее, через запятые, видимо коэффициенты, или что-то, по осям X, Y, Z.
Так вот, приведённая выше строка осуществляет поворот по оси Z от перемещения курсора мыши по оси X.
Но в данном случае интересует ось X и вот эта строка
	
вполне логично, что раз вертикальным движением вращается вокруг оси Z, то горизонтальным сделал ось X, и вот тут самое интересное - что она кривая в отличии от оси Y, вы это увидете изменив строку так
	
.
Точнее сказать у библиотеки совсем свои представления, в которых ось X для данной функции - диагональная, а ось Y - прямая, и это ещё помимо того, что сами оси просто переносятся из сцены на само окно, что можно понять повернув плоскость на 90 градусов вокруг оси Z, и вы обнаружите что осью Y вдруг стала перпендикуларная ось - меняется местами с X. Сам механизм работы поворота с матрицею - нигде не описывается, а по ссылкам разумеется можно прочитать что угодно, вплоть до того, что в OpenGL вообще камеры не существует. Ну может быть, но тем не менее что получается: ось Z - абсолютная, ось Y - переносная, а ось X - косая. Такой вывод можно сделать если поэкспериментировать с вращением и вот этими строками
	
.
Помогите пожалуйста разобраться в этой ситуации.
Добавлено через 20 минут
Кажется я понял, это возможно происходит потому, что при задании параметров перспективы установлен угол 45 градусов. Но сегодня у меня нет уже времени разбираться - разберусь завтра. Если кто знает точно - прошу подсказать.
                       Еле-еле мне удалось обнаружить суть проблемы, проведя небольшое исследование.
Сгенерировал такой код (многие ругают меня, что у меня много предупреждений от компилятора - но так и работы я за краткие промежутки времени делаю больше, и если что-то не используется вдруг, то значит это применялось в опробировании вариантов исполнения), после чего вращение камеры стало вполне предсказуемым, а надобность в отслеживании OpenGLControl1MouseUp отпала
Кликните здесь для просмотра всего текста
				   :
	unit Unit1;
{$mode objfpc}{$H+}
interface
uses
  Classes, SysUtils, Forms, Controls, Graphics, Dialogs, ExtCtrls, StdCtrls,
  OpenGLContext, GL, GLU;
type
  { TForm1 }
  TForm1 = class(TForm)
    Memo1: TMemo;
    OpenGLControl1: TOpenGLControl;
    procedure FormCreate(Sender: TObject);
    procedure OpenGLControl1MouseDown(Sender: TObject; Button: TMouseButton;
      Shift: TShiftState; X, Y: Integer);
    procedure OpenGLControl1MouseMove(Sender: TObject; Shift: TShiftState; X,
      Y: Integer);
    procedure OpenGLControl1Paint(Sender: TObject);
    procedure OpenGLControl1Resize(Sender: TObject);
    procedure InitOpenGL;
  private
    Vectors: array[0..49, 0..49] of TPoint; // Массив векторов
    GridValues: array[0..50, 0..50] of Byte; // Массив значений ячеек сетки (0-255)
    AngleX, AngleY: Single;
    LastX, LastY: Integer;
    MouseDownFlag: Boolean;
    procedure LogMessage(const Msg: string); // Процедура для добавления сообщений в TMemo
  public
  end;
var
  Form1: TForm1;
implementation
{$R *.lfm}
{ TForm1 }
procedure TForm1.LogMessage(const Msg: string);
begin
  Memo1.Lines.Add(Msg);
end;
//procedure TForm1.InitOpenGL;
//begin
//end;
procedure TForm1.InitOpenGL();
begin
  OpenGLControl1.MakeCurrent;
  // Включение теста глубины
  glEnable(GL_DEPTH_TEST);
  glDepthFunc(GL_LESS);
  // Включение сглаживания линий
  glEnable(GL_LINE_SMOOTH);
  glHint(GL_LINE_SMOOTH_HINT, GL_NICEST);
//  LogMessage('InitOpenGL: OpenGL settings initialized');
  OpenGLControl1.SwapBuffers;
end;
procedure TForm1.FormCreate(Sender: TObject);
var
  i,j:integer;
begin
  OpenGLControl1.Width := 1000;
  OpenGLControl1.Height := 800;
  // Инициализация генератора случайных чисел
  Randomize;
  // Инициализация векторов (пример данных)
  for i := 0 to 49 do
    for j := 0 to 49 do
      Vectors[i][j] := Point(Random(10) - 5, Random(10) - 5); // Пример случайных векторов
  // Инициализация значений ячеек сетки (пример данных)
  for i := 0 to 50 do
    for j := 0 to 50 do
      GridValues[i][j] := Random(256); // Случайные значения от 0 до 255
  AngleX := 0.0;
  AngleY := 0.0;
//  LogMessage('FormCreate: Initialization completed');
  InitOpenGL;
end;
procedure TForm1.OpenGLControl1Paint(Sender: TObject);
var
  i, j,i1,j1: Integer;
  x,y,z, x1, y1, z1, x2, y2, z2, x3, y3, z3, x4, y4, z4: Single;
  grayValue, sizeFactor, alpha: Byte;
begin
 // LogMessage('OpenGLControl1Paint: Rendering started');
  OpenGLControl1.MakeCurrent;
  // Очистка буферов цвета и глубины
  glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT);
  // Сброс матрицы проекции
  glMatrixMode(GL_PROJECTION);
  glLoadIdentity;
  // Установка перспективной проекции
  gluPerspective(45.0, OpenGLControl1.Width / OpenGLControl1.Height, 0.1, 100.0);
  // Сброс матрицы модели-вида
  glMatrixMode(GL_MODELVIEW);
  glLoadIdentity;
  // Перемещение камеры вперед
  gluLookAt(3.0, 3.0, 3.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);
  // Поворот камеры
  glRotatef(AngleY,  1, 0, 0);
  glRotatef(AngleX, 0.0, 0.0, 1.0);
  // Включение смешивания для прозрачности
  glEnable(GL_BLEND);
  glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
  // Отрисовка квадратов в градациях серого с учетом размера и прозрачности
  glBegin(GL_QUADS);
  for i := 0 to 49 do
    for j := 0 to 49 do
    begin
      grayValue := GridValues[i][j];
      // Вычисление фактора размера (чем больше значение, тем меньше квадрат)
      sizeFactor := 10 - (grayValue div 25); // Нормализация значения от 1 до 10
            // Вычисляем координаты центра ячейки
      x := -2.5 + (i * 0.1) + 0.05;
      y := -2.5 + (j * 0.1) + 0.05;
      z := 0.0;
      x1 := x-(sizeFactor / 200);
      y1 := y-(sizeFactor / 200);
      z1 := 0.0;
      x2 := x1 + (sizeFactor/100);
      y2 := y1;
      z2 := 0.0;
      x3 := x2;
      y3 := y1 + (sizeFactor/100);
      z3 := 0.0;
      x4 := x1;
      y4 := y3;
      z4 := 0.0;
      // Вычисление прозрачности (чем больше значение, тем ярче квадрат)
      alpha := grayValue; // Значение от 0 до 255
      glColor4f(grayValue / 255.0, grayValue / 255.0, grayValue / 255.0, alpha / 255.0); // Градации серого с прозрачностью
      glVertex3f(x1, y1, z1);
      glVertex3f(x2, y2, z2);
      glVertex3f(x3, y3, z3);
      glVertex3f(x4, y4, z4);
    end;
  glEnd;
  // Выключение смешивания
  glDisable(GL_BLEND);
  // Отрисовка векторов
  glColor3f(1.0, 0.0, 0.0); // Красный цвет для векторов
  glBegin(GL_LINES);
  for i1 := 1 to 49 do
    for j1 := 1 to 49 do
    begin
      x1 := -2.5 + i1 * 0.1;
      y1 := -2.5 + j1 * 0.1;
      z1 := 0.0;
      x2 := x1 + Vectors[i1][j1].X * 0.01; // Нормализация векторов
      y2 := y1 + Vectors[i1][j1].Y * 0.01;
      z2 := 0.0;
      glVertex3f(x1, y1, z1);
      glVertex3f(x2, y2, z2);
    end;
  glEnd;
//  LogMessage('OpenGLControl1Paint: Rendering completed');
  OpenGLControl1.SwapBuffers;
end;
procedure TForm1.OpenGLControl1Resize(Sender: TObject);
var
  AspectRatio: Single;
begin
  if OpenGLControl1.Height = 0 then Exit; // Защита от деления на ноль
  OpenGLControl1.MakeCurrent;
  // Установка области просмотра
  glViewport(0, 0, OpenGLControl1.Width, OpenGLControl1.Height);
  // Сброс матрицы проекции
  glMatrixMode(GL_PROJECTION);
  glLoadIdentity;
  // Вычисление соотношения сторон
  AspectRatio := OpenGLControl1.Width / OpenGLControl1.Height;
  // Установка перспективной проекции
  gluPerspective(45.0, AspectRatio, 0.1, 100.0);
 // LogMessage('OpenGLControl1Resize: Projection set');
  OpenGLControl1.SwapBuffers;
end;
procedure TForm1.OpenGLControl1MouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
begin
  if Button = mbLeft then
  begin
//    MouseDownFlag := True;
    LastX := X;
    LastY := Y;
  end;
end;
//procedure TForm1.OpenGLControl1MouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
//begin
//  if Button = mbLeft then
//    MouseDownFlag := False;
//end;
procedure TForm1.OpenGLControl1MouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer);
var
  DeltaX, DeltaY: Integer;
begin
  if ssLeft in Shift then
  begin
    DeltaX := X - LastX;
    DeltaY := Y - LastY;
    // Обновление углов вращения камеры
    AngleX := AngleX + DeltaY * 0.5; // Вращение по оси X
    AngleY := AngleY + DeltaX * 0.5; // Вращение по оси Y
    LastX := X;
    LastY := Y;
    // Перерисовка экрана
    OpenGLControl1.Refresh;
//    LogMessage(Format('AngleX: %.2f, AngleY: %.2f', [AngleX, AngleY]));
  end;
end;
end.Но, выяснилась одна деталь. Сейчас сначала расшифрую эту строку например
:
	glRotatef(AngleX, 0.0, 0.0, 1.0);AngleX -величина угла, на который производится поворот. И далее, через запятые, видимо коэффициенты, или что-то, по осям X, Y, Z.
Так вот, приведённая выше строка осуществляет поворот по оси Z от перемещения курсора мыши по оси X.
Но в данном случае интересует ось X и вот эта строка
:
	  glRotatef(AngleY,  1, 0, 0);:
	  glRotatef(AngleY,  0, 1, 0);Точнее сказать у библиотеки совсем свои представления, в которых ось X для данной функции - диагональная, а ось Y - прямая, и это ещё помимо того, что сами оси просто переносятся из сцены на само окно, что можно понять повернув плоскость на 90 градусов вокруг оси Z, и вы обнаружите что осью Y вдруг стала перпендикуларная ось - меняется местами с X. Сам механизм работы поворота с матрицею - нигде не описывается, а по ссылкам разумеется можно прочитать что угодно, вплоть до того, что в OpenGL вообще камеры не существует. Ну может быть, но тем не менее что получается: ось Z - абсолютная, ось Y - переносная, а ось X - косая. Такой вывод можно сделать если поэкспериментировать с вращением и вот этими строками
:
	  glRotatef(AngleY,  1, 0, 0);
  glRotatef(AngleX, 0.0, 0.0, 1.0);Помогите пожалуйста разобраться в этой ситуации.
Добавлено через 20 минут
Кажется я понял, это возможно происходит потому, что при задании параметров перспективы установлен угол 45 градусов. Но сегодня у меня нет уже времени разбираться - разберусь завтра. Если кто знает точно - прошу подсказать.