[Решено] Нет текстуры во втором окне OpenGL

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

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

[Решено] Нет текстуры во втором окне OpenGL

Сообщение yeger » 18.03.2011 10:36:26

Столкнулся с проблемой, что в первом окне текстуры выводятся корректно, но во втором - можно увидеть только сам примитив, без текстуры. Кто нибудь сталкивался с подобным? Есть мысли по поводу?
Версия: 0.9.28.2
FPC: 2.2.4
Используется OpenGLContext, GL, GLU. Есть главное окно (конт1), есть созданное в главном окно (конт2)
Изображение
Главное окно:
Код: Выделить всё
procedure TFrmMpD.OGLCtrlMpRPaint(Sender: TObject);
var
  ForXK, ForYK, trashLok: Integer;
  PntX, PntY :GLfloat;//PntZ
begin
  if OGLCtrlMpR.MakeCurrent then  AreaInitialized:=true;
  glClearColor(1.0, 1.0, 1.0, 1.0);
  glClear(GL_DEPTH_BUFFER_BIT or GL_COLOR_BUFFER_BIT or GL_STENCIL_BUFFER_BIT);
  glClearDepth(1.0);                      // Разрешить очистку буфера глубины
  glDepthFunc(GL_LESS);                   // Тип теста глубины
  glEnable(GL_DEPTH_TEST);                // разрешить тест глубины
  glMatrixMode(GL_PROJECTION);
  glLoadIdentity();

  glShadeModel(GL_SMOOTH);        // разрешить плавное цветовое сглаживание
  glMatrixMode(GL_PROJECTION);    // Выбор матрицы проекции
  glLoadIdentity();               // Сброс матрицы проекции
  gluPerspective(45.0,GLfloat(OGLCtrlMpR.Width)/GLfloat(OGLCtrlMpR.Height),0.1,100.0);
                                // Вычислить соотношение геометрических размеров для окна
  glMatrixMode(GL_MODELVIEW);     // Выбор матрицы просмотра модели
  glLoadIdentity();

  glTranslatef((ScrollBar1.Position-127)*0.1,(127 - ScrollBar2.Position)*0.1,TrackBar1.Position*0.5);

  glEnable(GL_TEXTURE_2D);      // Разрешение наложение текстуры
  glBindTexture(GL_TEXTURE_2D, Texture[4]);

  glEnable (GL_BLEND);
  glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

  if MapWasGenerate then
    for ForYK := (127 - (TrackBar2.Position Div 2)) to (127+ TrackBar2.Position Div 2) do
      for ForXK := (127- TrackBar2.Position Div 2) to (127 + TrackBar2.Position Div 2) do
      begin
        //Центр это 127х127х7
        //Х = (ForXK - 127)*0,3
        //Y = (ForYK - 127)*0,3
        //Z = (HeightMap[(ForYK*256)+ForXK])
        PntX := (ForXK - 127)*0.3;
        PntY := (ForYK - 127)*0.3;
        if not CheckBox1.Checked then
          glBindTexture(GL_TEXTURE_2D, Texture[0])
          else if (HeightMap[(ForYK*256)+ForXK]+1) < 6 then
          glBindTexture(GL_TEXTURE_2D, Texture[HeightMap[(ForYK*256)+ForXK]+1])
          else glBindTexture(GL_TEXTURE_2D, Texture[6]);
        glBegin(GL_QUADS);
          glTexCoord2f(1.0, 1.0);
          glVertex3f(PntX,PntY,CalkZPoint(ForYK,ForXK,1, false)*0.1);
          glTexCoord2f(1.0, 0.0);
          glVertex3f( PntX, (PntY - 0.3) , CalkZPoint(ForYK,ForXK,4, false)*0.1);
          glTexCoord2f(0.0, 0.0);
          glVertex3f((PntX - 0.3),(PntY - 0.3),CalkZPoint(ForYK,ForXK,3, false)*0.1);
          glTexCoord2f( 0.0, 1.0);
          glVertex3f((PntX - 0.3),PntY,CalkZPoint(ForYK,ForXK,2, false)*0.1);
        glEnd();
      end;
  glDisable(GL_TEXTURE_2D);
  OGLCtrlMapRed.SwapBuffers;
  OpenGLIsPain := true;
end;

Создание второго окна:
Код: Выделить всё
procedure TFrmMapDesigner.MenuItem7Click(Sender: TObject);
var
  CNTLok: Integer;
  LokTex: TOneTexture;
  LokNameTex: String;
begin
  if not Assigned(ObjDesigner) then
  begin
    Application.CreateForm(TFrmObjDesigner, ObjDesigner);
  end;
  ObjDesigner.ListBox1.Clear;
  //Копируем список текстур
  for CNTLok := 0 to (LBxTexture.Count - 1) do
  begin
    LokTex := TOneTexture(LBxTexture.Items.Objects[CNTLok]);
    LokNameTex := LBxTexture.Items.Strings[CNTLok];
    ObjDesigner.ListBox1.Items.AddObject(LokNameTex,LokTex);
  end;
  ObjDesigner.Show;
end;

Вывод текстур во втором окне сделан совершенно аналогично:
Код: Выделить всё
procedure TFrmObjDesigner.OGLViewPaint(Sender: TObject);
begin
  if OGLView.MakeCurrent(true) then AreaInitialized:=true;
  glClearColor(1.0, 1.0, 1.0, 1.0);
  glClear(GL_DEPTH_BUFFER_BIT or GL_COLOR_BUFFER_BIT or GL_STENCIL_BUFFER_BIT);
  glClearDepth(1.0);                      // Разрешить очистку буфера глубины
  glDepthFunc(GL_LESS);                   // Тип теста глубины
  glEnable(GL_DEPTH_TEST);                // разрешить тест глубины
  glMatrixMode(GL_PROJECTION);
  glLoadIdentity();
  glShadeModel(GL_SMOOTH);        // разрешить плавное цветовое сглаживание
  glMatrixMode(GL_PROJECTION);    // Выбор матрицы проекции
  glLoadIdentity();               // Сброс матрицы проекции
  gluPerspective(45.0,GLfloat(OGLView.Width)/GLfloat(OGLView.Height),0.1,100.0);
                                // Вычислить соотношение геометрических размеров для окна
  glMatrixMode(GL_MODELVIEW);     // Выбор матрицы просмотра модели
  glLoadIdentity();
  glTranslatef(0.0,0.0,-3.1);
    glEnable (GL_BLEND);
    glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
    glEnable(GL_TEXTURE_2D);      // Разрешение наложение текстуры
    glBindTexture(GL_TEXTURE_2D, texture0); //[b]Могут не передаться текстуры главного - сделаю новую для проверки[/b]
  glBegin(GL_QUADS);
    glColor3f(1.0,0.0,0.0);                              // Red
    glTexCoord2f(1.0, 1.0);
    glVertex3f(1,1,0);
    glTexCoord2f(1.0, 0.0);
    glVertex3f( 1,-1,0);
    glTexCoord2f(0.0, 0.0);
    glVertex3f(-1,-1,0);
    glTexCoord2f( 0.0, 1.0);
    glVertex3f(-1,1,0);
  glEnd();
  OGLView.SwapBuffers;
end;


Проблему решил. Как удалить тему? 8-)
Последний раз редактировалось yeger 18.03.2011 17:42:07, всего редактировалось 1 раз.
Аватара пользователя
yeger
новенький
 
Сообщения: 49
Зарегистрирован: 17.03.2011 12:26:34

Re: [Решено.Прошу удалить] Нет текстуры во втором окне OpenGL

Сообщение dunin » 18.03.2011 17:39:19

yeger писал(а):Проблему решил. Как удалить тему? 8-)

Чего удалять-то сразу?
Поделились бы с народ что да как - может еще у кого такая проблема возникнет...
Аватара пользователя
dunin
энтузиаст
 
Сообщения: 634
Зарегистрирован: 02.05.2007 13:18:11
Откуда: Тољя††и

Re: [Решено] Нет текстуры во втором окне OpenGL

Сообщение yeger » 18.03.2011 17:54:55

OK.
Проблема в том, что за умолчанием текстуры грузятся в текущий контекст. Следовательно "OGLView.MakeCurrent(true)" - а именно это в данном случае инициализация второго окна OpenGL должно быть выполнено до загрузки текстуры. В примере же видно, что текстура только "отрисовывается", но загружена раньше.

Сейчас ищу кросс платформенный вариант "function wglShareLists(p1, p2: HGLRC): BOOL;" (unit GLWin32WGLContext), но без фанатизма - не беда что потеряется "кросс" - это утилита "только для создания", основное приложение несколько окон не использует. Однако, буду признателен за пример использования "wglShareLists" или кросс платформенной альтернативы.
Аватара пользователя
yeger
новенький
 
Сообщения: 49
Зарегистрирован: 17.03.2011 12:26:34

Re: [Решено] Нет текстуры во втором окне OpenGL

Сообщение Andru » 19.03.2011 14:57:29

Сейчас ищу кросс платформенный вариант "function wglShareLists(p1, p2: HGLRC): BOOL;

В Linux'е дополнительный контекст для "расшаривания" ресурсов указывается при создании контекста:
Код: Выделить всё
function glXCreateContext(dpy: PDisplay; vis: PXVisualInfo; shareList: GLXContext; direct: Boolean): GLXContext; cdecl;

Для MacOS X указывается в том же месте:
Код: Выделить всё
function aglCreateContext(pix:TAGLPixelFormat; share:TAGLContext):TAGLContext;cdecl;


Примеры использования - гугл... :)
Аватара пользователя
Andru
новенький
 
Сообщения: 13
Зарегистрирован: 28.09.2010 10:42:53

Re: [Решено] Нет текстуры во втором окне OpenGL

Сообщение yeger » 21.03.2011 14:17:17

Сайт Гугл не использует опенгл в контекстах 8-))) (это я так не смешно шучу).

Вообще методика "расшаривания" не православная. Т.к. 2-е окно это диалог, и держать его в памяти все время - моветон, лучше создавать и удалять при необходимости, однако OpenGL позволяет давать общий доступ к текстурам лишь перед созданием. Вычитал, что поможет создание второго контекста в одном окне, дескать доступные 2-м контекстам списки отображения и текстуры будут доступны всем последующим по умолчанию. Врут.
Рабочее решение (Windows only):
- Создать контекст без видимости, что будет главным и куда будет все грузиться
Код: Выделить всё
   //Объявлены глобальные переменные в TForm
SecondOGL: THandle;//Нужно для расшаривания текстур
SecondOGL_DC: HDC;

при OnCreate
Код: Выделить всё
procedure TFrmMapDesigner.FormCreate(Sender: TObject);
begin
  //... blabla never mind...
  OGLCtrlMpR.MakeCurrent();
  SecondOGL_DC := wglGetCurrentDC;
  SecondOGL := wglCreateContext(SecondOGL_DC);

  OGLCtrlMpR.MakeCurrent();
  if not wglShareLists(SecondOGL,wglGetCurrentContext) then
    ShowMessage('Ошибка. Не доступны текстуры просмотра карты');
  OGLViewAnimObj.MakeCurrent();
  if not wglShareLists(SecondOGL,wglGetCurrentContext) then
    ShowMessage('Ошибка. Не доступны текстуры просмотра объектов');
end;

- как только созданы 'OpenGLContext'-ы им надо давать их этого обшего контекста доступ (в примере) процедурой wglShareLists(<источник>,<приемник>).

Используются модули: GLWin32WGLContext, LCLType.
Чтоб сделать кросс - можно почитать модуль OpenGLContext, расписано достаточно прозрачно.
Аватара пользователя
yeger
новенький
 
Сообщения: 49
Зарегистрирован: 17.03.2011 12:26:34


Вернуться в Lazarus

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

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

Рейтинг@Mail.ru
cron