Free Pascal + OpenGL + GLUT

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

Free Pascal + OpenGL + GLUT

Сообщение first-leon » 21.12.2006 18:54:58

Всем привет.
Начал писать программу на FPC, ну честно говоря в Lazaruse, но без использования VCL и т. д.
В общем проблемы в следующем - моя программа дает очень, очень мало кадров.
Для теста отключил все расчеты, оставил отрисовку только одного sky box-а. Ну то-есть 6 плоскостей на которых соответственно 6 текстур.

Выглядит сиё следующим образом:
Код: Выделить всё
procedure Display; cdecl;
var
begin
  glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT);
  draw_sky_box;// Сдесь рисуем наш sky_box
  glutSwapBuffers;
  inc(fpspertime);// А это и до конца процедуры - для подсчета FPS
  if (time+1000)< glutget(GLUT_ELAPSED_TIME) then
  begin
    writeln(fpspertime);
    fpspertime:=0;
    time:=glutget(GLUT_ELAPSED_TIME);
  end;
end;                                 

Отрисовываю так:
Код: Выделить всё
procedure my_idle; cdecl;
begin
    glutPostRedisplay();  // Redraw windows
end;


Дает все это дело:
AthlonXP64//Radeon9200//1Gb - 660 кадров/секунда
Sempron 2300//Интегрированое видео//512Mb - 120 кадров/cекунда

Если включаю еще несколько текстурированных объектов - на второй машине частота падает до 13. Общее количество полигогов - ориентровочно 100.

Хочу сразу сказать что первый Unreal на второй машине идет без проблем. На первой - тем более.

Подскажите в чем проблема.
first-leon
новенький
 
Сообщения: 68
Зарегистрирован: 20.04.2006 18:46:31

Сообщение Sniper » 21.12.2006 19:24:30

Дык ты самое интересное и не показал %)
покажи полный код как выводятся эти 6 плоскостей как текстура загружается...
Я вообще скай бокс вывожу при помощи GL_ARB_texture_cube_map
Sniper
постоялец
 
Сообщения: 472
Зарегистрирован: 28.05.2005 13:02:42

Сообщение first-leon » 21.12.2006 19:34:21

Так выводится небо.
Код: Выделить всё
procedure draw_sky_box;
var
  i, j:longint;
  a,b,c,d:array[0..2] of glFloat;
  radius:glFloat;
begin
  radius:=200;

  a[0]:=-radius;
  a[1]:=radius;
  a[2]:=radius;

  b[0]:=radius;
  b[1]:=radius;
  b[2]:=radius;

  c[0]:=radius;
  c[1]:=radius;
  c[2]:=-radius;

  d[0]:=-radius;
  d[1]:=radius;
  d[2]:=-radius;
  glBindTexture(gl_Texture_2D, sky_box_top.TextureGLUint);
  glBegin(GL_QUADS);
    glTexCoord2f(0, 0);  glVertex3fv(@a);
    glTexCoord2f(1, 0);  glVertex3fv(@b);
    glTexCoord2f(1, 1);  glVertex3fv(@c);
    glTexCoord2f(0, 1);  glVertex3fv(@d);
  glEnd();

  a[0]:=radius;
  a[1]:=-radius;
  a[2]:=radius;

  b[0]:=-radius;
  b[1]:=-radius;
  b[2]:=radius;

  c[0]:=-radius;
  c[1]:=-radius;
  c[2]:=-radius;

  d[0]:=radius;
  d[1]:=-radius;
  d[2]:=-radius;
  glBindTexture(gl_Texture_2D, sky_box_bottom.TextureGLUint);
  glBegin(GL_QUADS);
    glTexCoord2f(0, 0);  glVertex3fv(@a);
    glTexCoord2f(1, 0);  glVertex3fv(@b);
    glTexCoord2f(1, 1);  glVertex3fv(@c);
    glTexCoord2f(0, 1);  glVertex3fv(@d);
  glEnd();

  a[0]:=radius;
  a[1]:=radius;
  a[2]:=-radius;

  b[0]:=radius;
  b[1]:=radius;
  b[2]:=radius;

  c[0]:=radius;
  c[1]:=-radius;
  c[2]:=radius;

  d[0]:=radius;
  d[1]:=-radius;
  d[2]:=-radius;
  glBindTexture(gl_Texture_2D, sky_box_back.TextureGLUint);
  glBegin(GL_QUADS);
    glTexCoord2f(0, 0);  glVertex3fv(@a);
    glTexCoord2f(1, 0);  glVertex3fv(@b);
    glTexCoord2f(1, 1);  glVertex3fv(@c);
    glTexCoord2f(0, 1);  glVertex3fv(@d);
  glEnd();

  a[0]:=radius;
  a[1]:=radius;
  a[2]:=radius;

  b[0]:=-radius;
  b[1]:=radius;
  b[2]:=radius;

  c[0]:=-radius;
  c[1]:=-radius;
  c[2]:=radius;

  d[0]:=radius;
  d[1]:=-radius;
  d[2]:=radius;
  glBindTexture(gl_Texture_2D, sky_box_left.TextureGLUint);
  glBegin(GL_QUADS);
    glTexCoord2f(0, 0);  glVertex3fv(@a);
    glTexCoord2f(1, 0);  glVertex3fv(@b);
    glTexCoord2f(1, 1);  glVertex3fv(@c);
    glTexCoord2f(0, 1);  glVertex3fv(@d);
  glEnd();

  a[0]:=-radius;
  a[1]:=radius;
  a[2]:=-radius;

  b[0]:=radius;
  b[1]:=radius;
  b[2]:=-radius;

  c[0]:=radius;
  c[1]:=-radius;
  c[2]:=-radius;

  d[0]:=-radius;
  d[1]:=-radius;
  d[2]:=-radius;
  glBindTexture(gl_Texture_2D, sky_box_right.TextureGLUint);
  glBegin(GL_QUADS);
    glTexCoord2f(0, 0);  glVertex3fv(@a);
    glTexCoord2f(1, 0);  glVertex3fv(@b);
    glTexCoord2f(1, 1);  glVertex3fv(@c);
    glTexCoord2f(0, 1);  glVertex3fv(@d);
  glEnd();

  a[0]:=-radius;
  a[1]:=radius;
  a[2]:=radius;

  b[0]:=-radius;
  b[1]:=radius;
  b[2]:=-radius;

  c[0]:=-radius;
  c[1]:=-radius;
  c[2]:=-radius;

  d[0]:=-radius;
  d[1]:=-radius;
  d[2]:=radius;
  glBindTexture(gl_Texture_2D, sky_box_front.TextureGLUint);
  glBegin(GL_QUADS);
    glTexCoord2f(0, 0);  glVertex3fv(@a);
    glTexCoord2f(1, 0);  glVertex3fv(@b);
    glTexCoord2f(1, 1);  glVertex3fv(@c);
    glTexCoord2f(0, 1);  glVertex3fv(@d);
  glEnd();
end;

Прошу помидорами не кидать. Это просто для теста. Очень долго не мог сделать небо. Пока так. Знаю что можно короче :)

Так текстуры грузим.
Код: Выделить всё
procedure TGLTexture_class.init(const TFN: String);
const
  GL_CLAMP_TO_EDGE=$812F;
begin
  TextureFileName:=TFN;
  LoadFromFile;

  glGenTextures(1, @TextureGLUint);
  glBindTexture(GL_TEXTURE_2D, TextureGLUint);
  glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);


  glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
  glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);

  glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE );
  glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE );

  glTexImage2D(GL_TEXTURE_2D,0,GL_RGBA,TextureWidth,TextureHeight,0,GL_RGB,GL_UNSIGNED_BYTE,TextureBits);
end;
end.


Это init:
Код: Выделить всё
procedure my_init;
begin
  glutInit(@argc, argv);
  glutInitDisplayMode(GLUT_RGB or GLUT_DOUBLE or GLUT_DEPTH);
  glutInitWindowSize(640, 480);
  glutCreateWindow('FOP');
  glutDisplayFunc(@Display);
  glutReshapeFunc(@reshape);
  glutTimerFunc(16, @timerfunction, 0);
  glEnable(gl_depth_test);
  my_procedure;
  glutKeyboardFunc(@onKeyboard);
  glutKeyboardUpFunc(@onKeyboardUp);
  glutSpecialFunc(@onKeyboardSpecial);
  glutSpecialUpFunc(@onKeyboardSpecialUp);
  glutPassiveMotionFunc(@onMouse);
  glutIdleFunc(@my_idle);
  glShadeModel(gl_flat);
  glClearColor(0.0, 0.0, 0.0, 0.0);
  glColor3f (1, 0, 1);
  glEnable(GL_TEXTURE_2D);                 
End;
first-leon
новенький
 
Сообщения: 68
Зарегистрирован: 20.04.2006 18:46:31

Сообщение Romtek » 21.12.2006 21:21:44

Отрисовываю так:

насколько я знаю, процедура Idle должна заниматься обработкой вычислений в холостом режиме, а не рабочем...
На то он и холостой, чтобы не заниматься основной работой, а фоновой.
Аватара пользователя
Romtek
постоялец
 
Сообщения: 190
Зарегистрирован: 22.05.2005 12:29:35
Откуда: Рамат Ган

Сообщение first-leon » 22.12.2006 07:34:04

Romtek
Пробовал так отрисовывать:
Код: Выделить всё
procedure timerfunction(temp_per123:longint) cdecl;
begin
    glutPostRedisplay();
    glutTimerFunc(16, @timerfunction, 0);
end;


На первой машине частота стабилизируется в районе 55 кадров, а на второй никакого увеличения производительности не замечается.
(Это все если добавить упомянутые выше объекты, потому как sky_box он мне и на той и на другой машине прорисовывает 55 раз в секунду, на то и таймер нужен).

Если вместо 16 ставить 0 в таймере, то результаты еще ниже чем при использовании idle.
first-leon
новенький
 
Сообщения: 68
Зарегистрирован: 20.04.2006 18:46:31

Сообщение FedeX » 22.12.2006 08:10:13

А как насчёт размера текстур? У меня бывало точно такое резкое снижение производительности при слишком большом разрешении текстур.

пс... GLUT лучше не юзай. Либо WinApi, либо SDL - мой тебе совет.
... и ещё, если у тебя СкайБокс полностью покрывает фон, то GL_COLOR_BUFFER_BIT в glClear не надо ставить - реально скорее будет...
Последний раз редактировалось FedeX 22.12.2006 08:29:32, всего редактировалось 1 раз.
Аватара пользователя
FedeX
постоялец
 
Сообщения: 422
Зарегистрирован: 27.03.2006 09:25:34
Откуда: украина, житомир

Сообщение first-leon » 22.12.2006 08:26:45

FedeX
Про глут знаю тоже читал. Но пока пусть так.

Размеры текстур:
sky_box - 6 текстур 256x256
И еще 14 текстур 128x128 - наложены на 64 объекта
first-leon
новенький
 
Сообщения: 68
Зарегистрирован: 20.04.2006 18:46:31

Сообщение drew » 22.12.2006 11:37:09

Прет всем =)
Вот наткнулся на FPC и застрял в нем, хе хе.

Что касается отрисовки, я бы ее делал тут:
Код: Выделить всё
  // Цикл обработки сообщений
  while true do
    begin
      if PeekMessage(Msg,0,0,0,PM_REMOVE)
        then
          begin
            if Msg.message = WM_QUIT then break;
            TranslateMessage(Msg);
            DispatchMessage(Msg);
          end
        else
          begin
            // сдесь делаем рендеринг сцены и остальное
          end;
    end;  // while


Правда я использую не GL, а DX, ибо пока кроссплатформенность не интересует.
drew
незнакомец
 
Сообщения: 5
Зарегистрирован: 22.12.2006 11:22:23
Откуда: Рига

Сообщение first-leon » 23.12.2006 10:09:45

FedeX

И еще, SDL и WINApi - это привязка к платформе, а хотелось бы в идеале что-нибудь кросплатформенное. Может быть посаветуешь?
first-leon
новенький
 
Сообщения: 68
Зарегистрирован: 20.04.2006 18:46:31

Сообщение SergKam » 23.12.2006 18:32:47

SDL как раз кросплатформеней некуда
SergKam
постоялец
 
Сообщения: 251
Зарегистрирован: 16.11.2005 21:31:11
Откуда: Украина,Харьков

Сообщение FedeX » 24.12.2006 09:43:21

>SDL как раз кросплатформеней некуда - эт точно!

Ещё есть офигенный ОпенГЛ движок - GLScene. Тож кроссплатформенный. Устанавливается на Лазаря как набор компонентов. Правда он изначально на Делфи писался, а на Лазаря поставлен немного криво. Но работает. Там всё - от загрузки кучи форматов 3Д моделей, всаких скайбоксов, чайников, примитивов и т.д. до реалистичной физики, 3Д звука (при помоши БАСС или ФМОД) эффектов, шейдеров и т. д. и т. п.

Качать сцену отсюда:
http://www.skinhat.com/
Русскоязычный сайт/форум по сцене:
http://www.glscene.ru/

Используя GLScene тебе уже не надо будет писать на ОпенГЛ-е. Там почти всё что надо реализовано в обьектах. Хотя...
Аватара пользователя
FedeX
постоялец
 
Сообщения: 422
Зарегистрирован: 27.03.2006 09:25:34
Откуда: украина, житомир

Сообщение first-leon » 25.12.2006 18:11:15

SergKam
Да. Извиняюсь. Почему то первое что пришло в голову по расшифровке аббревиатуры это "Standart Delphi Library" :lol:
first-leon
новенький
 
Сообщения: 68
Зарегистрирован: 20.04.2006 18:46:31

Сообщение first-leon » 26.12.2006 13:43:42

Что то libsdl.org недоступен второй день. У кого нибудь есть эта библиотека под винду? Не могу в сети найти нигде
first-leon
новенький
 
Сообщения: 68
Зарегистрирован: 20.04.2006 18:46:31

Сообщение Sniper » 26.12.2006 16:05:39

C расшифровкой неугадал - Simple Directmedia Layer %)

Рекомендую качнуть вот это: http://files.delphigl.com/Download/dglsdk_2006.1.exe (8Mb)
В нём собрали всё что нужно для разработки игр и просто 3D приложений. Состав пакета огромен
SDL в полном составе(SDL, SDL_mixer, SDL_net, SDL_image, SDL_ttf), ogg Vorbis, libpng, zlib, ODE, заголовочные файлы, документация ObjectPascal_SDL и разумеется большое колличество примеров использования всего вышеперечисленного.
Sniper
постоялец
 
Сообщения: 472
Зарегистрирован: 28.05.2005 13:02:42

Сообщение first-leon » 26.12.2006 17:48:35

Sniper

Спасибо! Очень интересный пакет. Буду сидеть разбираться. И наверное все таки на SDL переходить буду. А то уж очень GLUT не уважают.
first-leon
новенький
 
Сообщения: 68
Зарегистрирован: 20.04.2006 18:46:31

След.

Вернуться в Графика

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

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

Рейтинг@Mail.ru