Чем можно заменить VBO буффер?
Модератор: Модераторы
Чем можно заменить VBO буффер?
Пытаюсь создать буффер VBO (OpenGL), но при вызове процедуры glGenBuffers( 1, @vId ); появляется сообщение "Проект project1 вызвал класс исключения External: SIGSEGV". Процедура glGenBuffers объявлена в модуле GLext, которая в свою очередь должна содержаться в OpenGL32.dll. После проверки OpenGL32.dll соответствующей процедуры в ней не обраружил (скорее всего VBO буффер OpenGL больше не поддерживает).
Посоветуйте, как можно решить задачу, чтобы поместить все примитивы картинки в видеопамять.
Посоветуйте, как можно решить задачу, чтобы поместить все примитивы картинки в видеопамять.
В Windows очень старая версия opengl. Нужно использовать расширения (GLEW/GLU/и т.д.), тогда будет поддержка VBO.
емнип VBO в старом контексте (который создается TOpenGLControl) доступен в виде расширения и вполне работает
shyub, вызываете ли вы процедуру инициализации расширений?
Добавлено спустя 2 минуты 30 секунд:
Например Load_GL_VERSION_3_1 из модуля GLext.
Добавлено спустя 2 минуты 30 секунд:
Например Load_GL_VERSION_3_1 из модуля GLext.
Проверил, все варианты функции от 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 не обнаружил.
Файл в 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 не обнаружил.
Надо разбираться почему false возвращает.
Что возвращает glGetString(GL_VERSION)?
Добавлено спустя 3 минуты 54 секунды:
Ее там и не должно быть.
Добавлено спустя 3 минуты 54 секунды:
shyub писал(а):в файле Opengl32.dll функция glGenBuffers почему-то отсутствует
Ее там и не должно быть.
glGetString(GL_VERSION) возвращает: "3.0.0 - Build 8.15.10.2342".
Добавлено спустя 15 минут 1 секунду:
Load_GL_VERSION_3_0(); запускал в TForm1.FormCreate, когда запустил в TForm1.OpenGLControl1Paint вернула "true", но даже если здесь делаю инициализацию VBO всравно та же ошибка.
Добавлено спустя 1 час 11 минут 31 секунду:
Перенёс инициализацию на кнопку, т.е. включаю "вручную" и добавил, как советовал Osmiy, функцию Load_GL_VERSION_3_1:
Заработало! Почему-то при первой перерисовке procedure TForm1.OpenGLControl1Paint(Sender: TObject); не срабатывало. Может есть смысл поставить таймер и производить инициализацию через какой-то промежуток времени после первой перерисовки? И есть ли смысл использовать перерисовку OpenGLControl1, если планируется работать только с буферами?
Вообщни, самое главное, что получилось. Большое спасибо всем ответившим, особенно Osmiy и Mikhail!
Добавлено спустя 3 минуты 40 секунд:
Запускается, если ставлю от Load_GL_VERSION_2_0(); до Load_GL_VERSION_3_0(); (выше не работает, т.к. у меря 3-я версия OpenGL).
Добавлено спустя 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).
- Лекс Айрин
- долгожитель
- Сообщения: 5723
- Зарегистрирован: 19.02.2013 16:54:51
- Откуда: Волгоград
- Контактная информация:
shyub писал(а): Может есть смысл поставить таймер и производить инициализацию через какой-то промежуток времени после первой перерисовки?
Проще, не делать при первой перерисовке. Возможно, что часть данных просто отсутствует в памяти и инициализируется позднее и в другом месте.
- Снег Север
- долгожитель
- Сообщения: 3067
- Зарегистрирован: 27.11.2007 15:14:47
- Контактная информация:
shyub, а вы не пробовали посмотреть исходники паскалевских движков - хотя бы хорошо известную GLscene? Или Castle engine?
Наклепал небольшой пример
Код: Выделить всё
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.
У вас нет необходимых прав для просмотра вложений в этом сообщении.
Пример у вас получился на много меньше, чем у меня. Однако, попробовал запустить его, но не получилось. Версии менял от 1.5 до 3.0, но ничего не получилось. (У меня стоит Lazarus 1.6, FPC-3.0).
У меня значительно больше кода. Если можно оптимизировать, то было бы очень не плохо.
Добавлено спустя 10 минут 42 секунды:
К стати, я пробовал у себя выполнять инициализацию (Load_GL_VERSION_3_0()) при первой перерисовке (procedure TForm1.OpenGLControl1Paint(Sender: TObject);) тоже не запускалась. Теперь включаю при первой перерисовке таймер на 1 секунду и по таймеру выполняю инициализацию.
При инициализации, если выбираю версию ниже 2.0, то тоже не запускается. Поэтому, мне кажется, надо стараться запускать либо поддерживаемую версию OpenGL, либо максимально возможную. Поэтому, может не совсем корректно, делаю вот так:
У меня значительно больше кода. Если можно оптимизировать, то было бы очень не плохо.
Добавлено спустя 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);
.........................................................................У вас нет необходимых прав для просмотра вложений в этом сообщении.
Кстати, в моём проекте перед Load_GL_VERSION_3_1() стоит вызов метода OpenGLControl.MakeCurrent. Всё это происходит при создании главной формы. Без этого вызова всё летит в тар-тарары.
Я в линуксе проект делал, там всё работает, а перезагрузился в окна, да, не работает. 
Последний раз редактировалось fedan 11.03.2017 02:31:24, всего редактировалось 4 раза.
