Чем можно заменить VBO буффер?

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

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

Чем можно заменить VBO буффер?

Сообщение shyub » 09.03.2017 17:16:37

Пытаюсь создать буффер VBO (OpenGL), но при вызове процедуры glGenBuffers( 1, @vId ); появляется сообщение "Проект project1 вызвал класс исключения External: SIGSEGV". Процедура glGenBuffers объявлена в модуле GLext, которая в свою очередь должна содержаться в OpenGL32.dll. После проверки OpenGL32.dll соответствующей процедуры в ней не обраружил (скорее всего VBO буффер OpenGL больше не поддерживает).
Посоветуйте, как можно решить задачу, чтобы поместить все примитивы картинки в видеопамять.
shyub
постоялец
 
Сообщения: 109
Зарегистрирован: 25.11.2014 23:15:19

Re: Чем можно заменить VBO буффер?

Сообщение Devel0 » 09.03.2017 18:22:28

В Windows очень старая версия opengl. Нужно использовать расширения (GLEW/GLU/и т.д.), тогда будет поддержка VBO.
Devel0
новенький
 
Сообщения: 63
Зарегистрирован: 24.07.2011 10:43:13

Re: Чем можно заменить VBO буффер?

Сообщение zub » 09.03.2017 18:56:03

емнип VBO в старом контексте (который создается TOpenGLControl) доступен в виде расширения и вполне работает
zub
долгожитель
 
Сообщения: 2261
Зарегистрирован: 14.11.2005 23:51:26

Re: Чем можно заменить VBO буффер?

Сообщение Mirage » 09.03.2017 22:19:05

Похоже, дрова просто не стоят на видео.
Mirage
энтузиаст
 
Сообщения: 752
Зарегистрирован: 06.05.2005 20:29:07
Откуда: Russia

Re: Чем можно заменить VBO буффер?

Сообщение Osmiy » 10.03.2017 00:56:18

shyub, вызываете ли вы процедуру инициализации расширений?

Добавлено спустя 2 минуты 30 секунд:
Например Load_GL_VERSION_3_1 из модуля GLext.
Osmiy
новенький
 
Сообщения: 32
Зарегистрирован: 07.05.2016 21:18:39

Re: Чем можно заменить VBO буффер?

Сообщение shyub » 10.03.2017 10:30:30

Проверил, все варианты функции от Load_GL_VERSION_1_2() до Load_GL_VERSION_4_0() возвращают false. Получается, что у меня отсутствует что ли OpenGL?
Файл в Opengl32.dll в Windows\system32 есть (установлен Windows-7 x32), версия файла 6.1.7600.16385 от 14.07.2009 г. Использую ноутбук Acer-5749 (i3), все драйвера установлены из "коробки". Видеоадаптер Intel HD Graphics 3000. Пакет LazOpenGLContext0.0.1 установлен.
Всё "рисование" (примитивы, текстуры, освещение, надписи, чайники и т.д.) в OpenGL работает. Единственная проблема - не могу получить доступ к буферам VBO и VAO, а без них для меня использование OpenGL утрачивает смысл... В чём может быть причина?
К стати, выше уже писал, в файле Opengl32.dll функция glGenBuffers почему-то отсутствует (проверял WinHEX-ом), хотя судя по glext она там должна быть. Скачал более свежую версию Opengl32.dll v.6.3.9600.16384 от 15.05.2014 г. и там glGenBuffers не обнаружил.
shyub
постоялец
 
Сообщения: 109
Зарегистрирован: 25.11.2014 23:15:19

Re: Чем можно заменить VBO буффер?

Сообщение Osmiy » 10.03.2017 10:39:25

Надо разбираться почему false возвращает.
Osmiy
новенький
 
Сообщения: 32
Зарегистрирован: 07.05.2016 21:18:39

Re: Чем можно заменить VBO буффер?

Сообщение Mikhail » 10.03.2017 11:13:10

Что возвращает glGetString(GL_VERSION)?

Добавлено спустя 3 минуты 54 секунды:
shyub писал(а):в файле Opengl32.dll функция glGenBuffers почему-то отсутствует

Ее там и не должно быть.
Mikhail
постоялец
 
Сообщения: 467
Зарегистрирован: 24.10.2013 16:06:47

Re: Чем можно заменить VBO буффер?

Сообщение shyub » 10.03.2017 13:07:20

glGetString(GL_VERSION) возвращает: "3.0.0 - Build 8.15.10.2342".

Добавлено спустя 15 минут 1 секунду:
Osmiy писал(а):Надо разбираться почему false возвращает.

Load_GL_VERSION_3_0(); запускал в TForm1.FormCreate, когда запустил в TForm1.OpenGLControl1Paint вернула "true", но даже если здесь делаю инициализацию VBO всравно та же ошибка.

Добавлено спустя 1 час 11 минут 31 секунду:
Перенёс инициализацию на кнопку, т.е. включаю "вручную" и добавил, как советовал Osmiy, функцию Load_GL_VERSION_3_1:
Код: Выделить всё
// Инициализация VBO-VAO.
procedure TForm1.Button2Click(Sender: TObject);
beginfunction VBOInit: boolean;
var
  Count:integer;
//  d: boolean=false;
begin
  Result:=false;
  Load_GL_VERSION_3_0();
//  glewInit(); // Вот так рекомендуют на С++, но в Lazarus-е нет glew.
  Count:=high(VertexBuffer)+1;
  glGenBuffers( 1, @vId );
  glBindBuffer(GL_ARRAY_BUFFER, vId );
  glBufferData(GL_ARRAY_BUFFER, sizeof(GLFLoat)*3*Count, @VertexBuffer[0],
  GL_STATIC_DRAW); // Передача массива вершин в ОЗУ видеокарты.
  glBindBuffer(GL_ARRAY_BUFFER,0);
  glGenBuffers( 1, @cId );
  glBindBuffer(GL_ARRAY_BUFFER, cId );
  glBufferData(GL_ARRAY_BUFFER, sizeof(GLUByte)*3*Count, @ColorBuffer[0],
  GL_STATIC_DRAW); // Передача массива цветов в ОЗУ видеокарты.
  glBindBuffer(GL_ARRAY_BUFFER,0);
  Result:=true;
end;
  if VBOInit then Label2.Caption:='VBO и VAO вкл.';
end;

Заработало! Почему-то при первой перерисовке procedure TForm1.OpenGLControl1Paint(Sender: TObject); не срабатывало. Может есть смысл поставить таймер и производить инициализацию через какой-то промежуток времени после первой перерисовки? И есть ли смысл использовать перерисовку OpenGLControl1, если планируется работать только с буферами?
Вообщни, самое главное, что получилось. Большое спасибо всем ответившим, особенно Osmiy и Mikhail!

Добавлено спустя 3 минуты 40 секунд:
Запускается, если ставлю от Load_GL_VERSION_2_0(); до Load_GL_VERSION_3_0(); (выше не работает, т.к. у меря 3-я версия OpenGL).
shyub
постоялец
 
Сообщения: 109
Зарегистрирован: 25.11.2014 23:15:19

Re: Чем можно заменить VBO буффер?

Сообщение Лекс Айрин » 10.03.2017 14:42:01

shyub писал(а): Может есть смысл поставить таймер и производить инициализацию через какой-то промежуток времени после первой перерисовки?


Проще, не делать при первой перерисовке. Возможно, что часть данных просто отсутствует в памяти и инициализируется позднее и в другом месте.
Аватара пользователя
Лекс Айрин
долгожитель
 
Сообщения: 4097
Зарегистрирован: 19.02.2013 16:54:51

Re: Чем можно заменить VBO буффер?

Сообщение Снег Север » 10.03.2017 17:15:21

shyub, а вы не пробовали посмотреть исходники паскалевских движков - хотя бы хорошо известную GLscene? Или Castle engine?
Аватара пользователя
Снег Север
энтузиаст
 
Сообщения: 949
Зарегистрирован: 27.11.2007 16:14:47

Re: Чем можно заменить VBO буффер?

Сообщение fedan » 10.03.2017 22:13:16

Наклепал небольшой пример
simple_vbo.zip

Код: Выделить всё
program simple_vbo;

{$mode objfpc}{$H+}

uses
  {$IFDEF UNIX}{$IFDEF UseCThreads}
  cthreads,
  {$ENDIF}{$ENDIF}
  Interfaces, // this includes the LCL widgetset
  Forms, Dialogs, simple_vbo_main, glext, lazopenglcontext
  { you can add units after this };

{$R *.res}

begin
  if not Load_GL_VERSION_1_5() then
  begin
    ShowMessage('Load_GL_VERSION_1_5 failed');
    Exit;
  end;
  RequireDerivedFormResource:=True;
  Application.Initialize;
  Application.CreateForm(TForm1, Form1);
  Application.Run;
end.

Код: Выделить всё
unit  simple_vbo_main;

{$mode objfpc}{$H+}

interface

uses
  Classes, SysUtils, FileUtil, OpenGLContext, Forms, Controls, Graphics,
  Dialogs, gl, glext;

type

  { TForm1 }

  TForm1 = class(TForm)
    OpenGLControl1: TOpenGLControl;
    procedure FormClose(Sender: TObject; var CloseAction: TCloseAction);
    procedure FormShow(Sender: TObject);
    procedure OpenGLControl1Paint(Sender: TObject);
  private
    vertices: GLuint;
    colors: GLuint;
    procedure OnAppIdle(Sender: TObject; var Done: Boolean);
  public

  end;

var
  Form1: TForm1;

implementation

{$R *.lfm}

{ TForm1 }

procedure TForm1.FormShow(Sender: TObject);
const
  planeVertices: array[0..11] of GLfloat = (
    0.5, 0.5, 0.0,  //
    -0.5, 0.5, 0.0, //
    -0.5, -0.5, 0.0,//
    0.5, -0.5, 0.0  //
    );

  planeColors: array[0..11] of GLfloat = (
    1.0, 0.0, 0.0,  //
    0.0, 1.0, 0.0,  //
    0.0, 0.0, 1.0,  //
    1.0, 1.0, 1.0   //
    ); 
var
  ver: string;
begin
  ver := glGetString(GL_VERSION);
  if ver <> '' then
    Caption := 'Simple draw polygon with OpenGL - version: ' + ver
  else
    Caption := 'Simple draw polygon with OpenGL - version: <unknown>';

  glMatrixMode(GL_MODELVIEW);

  glGenBuffers(1, @vertices);
  glGenBuffers(1, @colors);

  glBindBuffer(GL_ARRAY_BUFFER, vertices);
  glBufferData(GL_ARRAY_BUFFER, sizeof(planeVertices), @planeVertices[0],
    GL_STATIC_DRAW);

  glBindBuffer(GL_ARRAY_BUFFER, colors);
  glBufferData(GL_ARRAY_BUFFER, sizeof(planeColors), @planeColors[0], GL_STATIC_DRAW);


  Application.AddOnIdleHandler(@OnAppIdle);
end;

procedure TForm1.FormClose(Sender: TObject; var CloseAction: TCloseAction);
begin
  if CloseAction = caFree then
  begin
    glDeleteBuffers(1, @vertices);
    glDeleteBuffers(1, @colors);
  end;
end;

procedure TForm1.OpenGLControl1Paint(Sender: TObject);
begin
  glClearColor(0, 0, 0, 0);
  glClear(GL_COLOR_BUFFER_BIT);

  glBindBuffer(GL_ARRAY_BUFFER, vertices);
  glVertexPointer(3, GL_FLOAT, 0, nil);
  glEnableClientState(GL_VERTEX_ARRAY);

  glBindBuffer(GL_ARRAY_BUFFER, colors);
  glColorPointer(3, GL_FLOAT, 0, nil);
  glEnableClientState(GL_COLOR_ARRAY);

  glDrawArrays(GL_POLYGON, 0, 4);

  OpenGLControl1.SwapBuffers;
end;

procedure TForm1.OnAppIdle(Sender: TObject; var Done: Boolean);
begin
  Done := False;
  OpenGLControl1.Invalidate;
end;

end.
У вас нет необходимых прав для просмотра вложений в этом сообщении.
fedan
новенький
 
Сообщения: 26
Зарегистрирован: 15.09.2016 21:18:48

Re: Чем можно заменить VBO буффер?

Сообщение shyub » 11.03.2017 00:49:15

Пример у вас получился на много меньше, чем у меня. Однако, попробовал запустить его, но не получилось. Версии менял от 1.5 до 3.0, но ничего не получилось. (У меня стоит Lazarus 1.6, FPC-3.0).
11.03.png

У меня значительно больше кода. Если можно оптимизировать, то было бы очень не плохо.
OpenGLBuffer_02_(Инициализация VBO).rar


Добавлено спустя 10 минут 42 секунды:
К стати, я пробовал у себя выполнять инициализацию (Load_GL_VERSION_3_0()) при первой перерисовке (procedure TForm1.OpenGLControl1Paint(Sender: TObject);) тоже не запускалась. Теперь включаю при первой перерисовке таймер на 1 секунду и по таймеру выполняю инициализацию.
При инициализации, если выбираю версию ниже 2.0, то тоже не запускается. Поэтому, мне кажется, надо стараться запускать либо поддерживаемую версию OpenGL, либо максимально возможную. Поэтому, может не совсем корректно, делаю вот так:
Код: Выделить всё
procedure VBOInit;
begin
  if not Load_GL_VERSION_3_3() then // Инициализация функйий OpenGL.
    if not Load_GL_VERSION_3_2() then
      if not Load_GL_VERSION_3_1() then
        if not Load_GL_VERSION_3_0() then
          if not Load_GL_VERSION_2_1() then
            if not Load_GL_VERSION_2_0() then begin
              Application.MessageBox('OpenGL не обнаружена.',
                'OpenGLBuffer_02_(Инициализация VBO)',MB_ICONWARNING + MB_OK);
              Form1.Close;
            end;
  Form1.Panel1.Caption:='Версия OpenGL '+glGetString(GL_VERSION);
.........................................................................
У вас нет необходимых прав для просмотра вложений в этом сообщении.
shyub
постоялец
 
Сообщения: 109
Зарегистрирован: 25.11.2014 23:15:19

Re: Чем можно заменить VBO буффер?

Сообщение Osmiy » 11.03.2017 02:16:01

Кстати, в моём проекте перед Load_GL_VERSION_3_1() стоит вызов метода OpenGLControl.MakeCurrent. Всё это происходит при создании главной формы. Без этого вызова всё летит в тар-тарары.
Osmiy
новенький
 
Сообщения: 32
Зарегистрирован: 07.05.2016 21:18:39

Re: Чем можно заменить VBO буффер?

Сообщение fedan » 11.03.2017 02:25:31

Я в линуксе проект делал, там всё работает, а перезагрузился в окна, да, не работает. :cry:
Последний раз редактировалось fedan 11.03.2017 03:31:24, всего редактировалось 4 раз(а).
fedan
новенький
 
Сообщения: 26
Зарегистрирован: 15.09.2016 21:18:48

След.

Вернуться в Lazarus

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

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 3

Рейтинг@Mail.ru