Вопрос по OpenGLControl

Вопросы программирования и использования среды Lazarus.

Модератор: Модераторы

Вопрос по OpenGLControl

Сообщение TehnikHarlan » 03.09.2019 12:45:27

Здраствуйте народ. Столкнулся с непонятной для меня проблемой, строго не судите , поскольку я не особо специалист. Проблема в следующем. Раньше писал на в Лазарусе 1.8.4. Сейчас пересел на другой компютер установил последнюю версию лазаруса 2.0.4 и теперь не могу работать))) Вот такой минимальный код отказывается работать:

procedure TForm1.FormCreate(Sender: TObject);
begin

glClearColor(220/255, 220/255, 220/255, 1); //задаю цвет
glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT); // очищаю буферы

form1.OpenGLControl.SwapBuffers; // тут экран должен заполнится выше заданим цветом

end;

Ошибок не видает но ничего не происходит.

Хотя на старом компютере в версии 1.8.4 он работает. Подскажите пожалуйста с чем это может бить связано.
TehnikHarlan
новенький
 
Сообщения: 16
Зарегистрирован: 26.11.2018 16:01:35

Re: Вопрос по OpenGLControl

Сообщение Vadim » 03.09.2019 13:33:09

TehnikHarlan
А Вы свою программу из консоли запускаете? Если нет - попробуйте из консоли, возможно что-то напишет, тогда будет понятнее...
Vadim
долгожитель
 
Сообщения: 3695
Зарегистрирован: 05.10.2006 08:52:59
Откуда: Красноярск

Re: Вопрос по OpenGLControl

Сообщение TehnikHarlan » 03.09.2019 14:05:12

Я под виндовс 10, через cmd запустилось да и все) ниче не написало. Кстате принесенное откомпилированое тестовое приложение с нового компа на старий, заработало на старом) Может не хватает каких то компонентов для свежоустановленого вин 10 на новом компютере?)
TehnikHarlan
новенький
 
Сообщения: 16
Зарегистрирован: 26.11.2018 16:01:35

Re: Вопрос по OpenGLControl

Сообщение serbod » 03.09.2019 17:47:45

Насколько я понял из https://wiki.lazarus.freepascal.org/OpenGL_Tutorial
нужно отрисовку делать в событии OnPaint
Аватара пользователя
serbod
постоялец
 
Сообщения: 422
Зарегистрирован: 16.09.2016 11:03:02
Откуда: Минск

Re: Вопрос по OpenGLControl

Сообщение zub » 03.09.2019 18:11:10

Подобным действиям не место в FormCreate
zub
долгожитель
 
Сообщения: 2515
Зарегистрирован: 14.11.2005 23:51:26

Re: Вопрос по OpenGLControl

Сообщение TehnikHarlan » 03.09.2019 19:40:53

Да неважно где визивать. Отрисоватся должно при .SwapBuffers, а где его вызывать SwapBuffers не важно, я отрисовую когда мне устройство накинет через езернет полний кадр. Проблема в том что у меня OpenGLControl какой то дохлый) ниче не рисует совсем, неважно в OnPaint, по кнопке, по таймеру нигде. А этот кусок кода простой пример, который я просто в новом проекте сделал. Вот сейчас кидаю на Форму OpenGLControl1, Button1 и текст юнита такой:


unit Unit1;

{$mode objfpc}{$H+}

interface

uses
Classes, SysUtils, FileUtil, OpenGLContext,
Forms, Controls, Graphics, Dialogs, ExtCtrls, StdCtrls, gl, glu, LCLType,
Menus, ComCtrls, EditBtn;

type

{ TForm1 }

TForm1 = class(TForm)
Button1: TButton;
OpenGLControl1: TOpenGLControl;
procedure Button1Click(Sender: TObject);
private

public

end;

var
Form1: TForm1;

implementation

{$R *.lfm}

{ TForm1 }

procedure TForm1.Button1Click(Sender: TObject);
begin
glClearColor(0.5, 0.6, 0.7, 1); //задаю цвет
glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT); // очищаю буферы
form1.OpenGLControl1.SwapBuffers; // тут экран должен заполнится выше заданим цветом
end;

end.

По нажатию кнопки должно зарисовать фон каким то цветом(0.5,0.6,0.7), а ничего не происходит))
TehnikHarlan
новенький
 
Сообщения: 16
Зарегистрирован: 26.11.2018 16:01:35

Re: Вопрос по OpenGLControl

Сообщение zub » 03.09.2019 21:17:59

Дровишки от производителя видеочипа накатите на свежеустановленную десятку.
>>Да неважно где визивать.
Откуда инфа? вас обманули
Большинство опенглных функций работает только при наличии активного контекста. OpenGLControl конечно берет на себя создание контекста, но:
1. вы уверенны что в FormCreate контекст уже создан?
2. надо смотреть что за контекст создает по умолчанию OpenGLControl. вполне возможно что он полагается на то что делает драйвер по умолчанию. тогда откуда уверенность что на этом контексте будет двойная буферизация?

Добавлено спустя 3 минуты 55 секунд:
>>Сейчас пересел на другой компютер установил последнюю версию лазаруса 2.0.4 и теперь не могу работать)))
Вместо того что чтото кудато кинуть и чтото гдето прописать, проинициализируйте и проверте все. Тогда будет работать независммо от версий среды\оси, разрядности и производителя оборудования
zub
долгожитель
 
Сообщения: 2515
Зарегистрирован: 14.11.2005 23:51:26

Re: Вопрос по OpenGLControl

Сообщение sts » 03.09.2019 22:50:44

попробуйте стандартный пример
lazarus\examples\openglcontrol\openglcontrol_demo.lpi
если не поможет значит надо думать, например запустить под отладчиком

Добавлено спустя 7 минут 2 секунды:
по моим наблюдениям в вин10 работа с апи (любым) стала както более строгим, тобишь, формально обязательные для вызова функции инициализации ранее работало и без них а в 10ке уже нет, приходится разбираться и править старый код
sts
постоялец
 
Сообщения: 270
Зарегистрирован: 04.04.2008 12:15:44
Откуда: Тольятти

Re: Вопрос по OpenGLControl

Сообщение Alex2013 » 03.09.2019 23:41:15

Так работает (Лазарус 2.04 32-х битная версия под Win10 64 )...
Код: Выделить всё
unit Unit1;
{$mode objfpc}{$H+}
interface
uses
  Windows,  Classes, SysUtils, Forms, Controls, Graphics, Dialogs, StdCtrls,
  gl, glu,    OpenGLContext;
type
  { TForm1 }
  TForm1 = class(TForm)
    Button1: TButton;
    OpenGLControl1: TOpenGLControl;
    procedure FormCreate(Sender: TObject);
    procedure Button1Click(Sender: TObject);
    procedure OpenGLControl1Paint(Sender: TObject);
  private
  public
  end;
var
  Form1: TForm1;
implementation
{$R *.lfm}
{ TForm1 }
procedure TForm1.FormCreate(Sender: TObject);
begin
OpenGLControl1.OnPaint:=@OpenGLControl1Paint;
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
glClearColor(1, 0, 0, 0);
glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT);
OpenGLControl1.SwapBuffers;
end;
procedure TForm1.OpenGLControl1Paint(Sender: TObject);
begin
glClearColor(0, 1, 0, 0);
glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT);
OpenGLControl1.SwapBuffers;
end;
end.

Причем кнопка тоже (хотя и "не правильно" то есть пока не вызывается полная перерисовка формы )...
..но только при OpenGLControl1.OnPaint:=@OpenGLControl1Paint;
Последний раз редактировалось Alex2013 04.09.2019 02:47:14, всего редактировалось 2 раз(а).
Alex2013
энтузиаст
 
Сообщения: 1495
Зарегистрирован: 03.04.2013 11:59:44

Re: Вопрос по OpenGLControl

Сообщение zub » 03.09.2019 23:58:29

>>Так работает ...
И еще есть миллион случайных комбинаций которые гденибудь работают
zub
долгожитель
 
Сообщения: 2515
Зарегистрирован: 14.11.2005 23:51:26

Re: Вопрос по OpenGLControl

Сообщение Alex2013 » 04.09.2019 00:11:43

В этом случае все понятно . :idea:
При наличии правильной ссылки OpenGLControl1.OnPaint происходит инициализация контекста .
(Кто помнит "чистый OpenGL"(Через WinAPI) знает что он требует ссылки на "DC"(Дисплейный контекст) который нужно получить отдельно )
А OpenGLControl из лазаруса делет это "скрыто от пользователя" но понятное дело перед первым вызовом процедуры на которую ссылается OpenGLControl1.OnPaint . То есть, можно вообще, оставить процедуру TForm1.OpenGLControl1Paint ПУСТОЙ но кнопка сработает .
Зы
Проверил "пустая процедура" действительно работает . ( Возможно в старой версии DC получали при создании OpenGLContro-а или в программе все-же была рабочая ссылка в OpenGLControl1.OnPaint )
Зы Зы
Минимизация "убила красный флаг" так что OpenGLControl1Paint нужно все же использовать нормально .
Последний раз редактировалось Alex2013 04.09.2019 00:48:03, всего редактировалось 1 раз.
Alex2013
энтузиаст
 
Сообщения: 1495
Зарегистрирован: 03.04.2013 11:59:44

Re: Вопрос по OpenGLControl

Сообщение zub » 04.09.2019 00:40:13

>>Да нет, в этом случае все понятно .
Дак да или нет? что понятно?

>>При наличии правильной ссылки OpenGLControl1.OnPaint происходит инициализация контекста .
Инициализация контекста происходит и без ссылки. только в какой момент? кто гарантирует что до вызова FormCreate? на всех поддерживаемых платформах?

>>(Кто помнит "чистый OpenGL" знает что он требует ссылки на "DC"(Дисплейный контекст) который нужно получить отдельно )
пьем таблетки, лечим виндовс головного мозга

>>А OpenGLControl из лазаруса делет это "скрыто от пользователя" но понятное дело перед первым вызовом процедуры на которую ссылается
И он такой умный, делает всегда как нам надо... если ты хочешь чтоб ктото сделал так как тебе надо (двойная буферизация, буфера цвета, глубины, да малоли что) - будь добр, управляй этим или хотябы контролируй это.

>>То есть, можно вообще, оставить процедуру TForm1.OpenGLControl1Paint ПУСТОЙ но кнопка сработает .
ты врешь. кнопка сработает не везде. например в qt она не сработает - там запрещена отрисовка снаружи paintmessage
zub
долгожитель
 
Сообщения: 2515
Зарегистрирован: 14.11.2005 23:51:26

Re: Вопрос по OpenGLControl

Сообщение Alex2013 » 04.09.2019 00:42:23

sts писал(а):по моим наблюдениям в вин10 работа с апи (любым) стала как-то более строгим, тобишь, формально обязательные для вызова функции инициализации ранее работало и без них а в 10ке уже нет, приходится разбираться и править старый код

То-же вариант ... Возможно ранее DC каким-то образом брался "по умолчанию ".

Добавлено спустя 2 минуты 28 секунд:
zub писал(а):ты врешь. кнопка сработает не везде. например в qt она не сработает - там запрещена отрисовка снаружи paintmessage

Вроде разговор про Виндовс 10... :roll:
И мои надежды на "хитрый" OpenGL прогнозируемо провалились и я рекомендую использовать нормальный рендер в OpenGLControl1Paint . Впрочем например в моей программе используется "вывод на битмап" как что варианты все-же есть (но это уже точно не про ТOpenGLControl, а про "чистый OpenGL через WniAPI " так что офф топ ).

Зы
Как очищать при запуске? Ну думаю достаточно отследить первый запуск перерисовки ...
Как-то так .
Код: Выделить всё
procedure TForm1.OpenGLControl1Paint(Sender: TObject);
Const FStart:Boolean= true;
begin
// Очистка при старте..
if FStart then begin
glClearColor(0, 1, 0, 0);
glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT);
OpenGLControl1.SwapBuffers;
FStart:=False;
end;

//.... Основной код рендера .

end;

Хотя если честно то это "мартышкин труд " ( потому что рендер так или иначе должен уметь перерисовывать текущий кадр целиком в любой момент времени . )
Последний раз редактировалось Alex2013 04.09.2019 01:16:58, всего редактировалось 3 раз(а).
Alex2013
энтузиаст
 
Сообщения: 1495
Зарегистрирован: 03.04.2013 11:59:44

Re: Вопрос по OpenGLControl

Сообщение zub » 04.09.2019 00:51:40

Разговор о том как сделать правильно.
Настроить контрол. В нужные моменты вызывать перерисовку контрола соответствующими методами. В OnPaint контрола рисовать то что надо.
А фантазии про пустые кнопки и диси поумолчанию лучше держать при себе
zub
долгожитель
 
Сообщения: 2515
Зарегистрирован: 14.11.2005 23:51:26

Re: Вопрос по OpenGLControl

Сообщение Alex2013 » 04.09.2019 01:49:16

А фантазии про кнопки ...

Проверил в Вин 10 работает.. (Причем именно так как и ожидалось. )
и диси по умолчанию лучше держать при себе....


Код: Выделить всё
procedure TCustomOpenGLControl.Paint;
begin
  if IsVisible and HandleAllocated then begin
    UpdateFrameTimeDiff;
    if IsOpenGLRenderAllowed and ([csDestroying]*ComponentState=[]) then begin
      if AutoResizeViewport then begin
        if not MakeCurrent then exit;
        LOpenGLViewport(Handle,0,0,Width,Height);
      end;
    end;
    //LOpenGLClip(Handle);
    DoOnPaint;
  end;
end;
procedure TCustomOpenGLControl.DoOnPaint;
begin
  if Assigned(OnPaint) then begin
    if not MakeCurrent then exit;
    OnPaint(Self);
  end;
end;
...
TCustomOpenGLControl...
function MakeCurrent(SaveOldToStack: boolean = false): boolean; virtual;
...
function TCustomOpenGLControl.MakeCurrent(SaveOldToStack: boolean): boolean;
var
  Allowed: Boolean;
begin
  if not IsOpenGLRenderAllowed then exit(false);
  if Assigned(FOnMakeCurrent) then begin
    Allowed:=true;
    OnMakeCurrent(Self,Allowed);
    if not Allowed then begin
      Result:=False;
      exit;
    end;
  end;
  // make current
  Result:=LOpenGLMakeCurrent(Handle);
  if Result and SaveOldToStack then begin
    // on success push on stack
    if OpenGLControlStack=nil then
      OpenGLControlStack:=TList.Create;
    OpenGLControlStack.Add(Self);
  end;
end;

и т.д.


Что непонятного ? :shock: Инициализация происходит при наличии OnPaint<>Nil
" if Assigned(OnPaint) then begin..."
(Хотя если совсем честно то копать весь код OpenGLContext (что-бы встановить, что именно не срабатывает при OnPaint=Nil )мне лень, но что там еще может быть ? )
Зы

Насчет DC: Да, вероятно в нормальном случае в Лазарусе (А не как у меня с выводом на битмап ) достаточно готового Handle но это уже вопрос реализации надстройки над WinAPI .
Код: Выделить всё
procedure LOpenGLSwapBuffers(Handle: HWND);
var
  Info: PWGLControlInfo;
begin
  Info:=GetWGLControlInfo(Handle);
  // don't use wglSwapLayerBuffers or wglSwapBuffers!
  SwapBuffers(Info^.DC);
end;


Зы Зы
Кстати, проверить перед ответом суть проблемы "на практике" никто кроме меня в теме не удосужился ... Теоретики ... :wink:
Последний раз редактировалось Alex2013 04.09.2019 12:37:12, всего редактировалось 1 раз.
Alex2013
энтузиаст
 
Сообщения: 1495
Зарегистрирован: 03.04.2013 11:59:44

След.

Вернуться в Lazarus

Кто сейчас на конференции

Сейчас этот форум просматривают: Yandex [Bot] и гости: 5

Рейтинг@Mail.ru