Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2007.07.22;
Скачать: CL | DM;

Вниз

OpenGL. Помогите оптимизировать код.   Найти похожие ветки 

 
Начинающий_1   (2006-08-28 21:03) [0]

type
TColorArr = array of TGLArrayf3;
TuShortArray = array of gluShort;
TSingleArr = array of Single;
TDblSingleArr = array of TSingleArr;

function ArrListCompile(const ListMode: glInt; const VertArr: TDblSingleArr; const ColorArr: TColorArr; const EnumArr: TuShortArray): glInt;
var
i: integer;
ArrLen: DWord;
aVertArr: TSingleArr;
begin
Result:=glGenLists(1);
if Result = 0 then Exit;
ArrLen:=Length(EnumArr);
glNewList(Result, ListMode);
try
 for i:=0 to Length(VertArr) - 1 do
  begin
   glVertexPointer(3, GL_FLOAT, 0, @VertArr[i, 0]);
   glColor3f(ColorArr[i, 0], ColorArr[i, 1], ColorArr[i, 2]);
   glDrawElements(GL_LINE_STRIP, ArrLen, GL_UNSIGNED_SHORT, @EnumArr[0]);
  end;
finally
 glEndList;
end;
end;


 
Rial ©   (2006-08-29 16:40) [1]

procedure glVertexPointer (size: GLint; atype: GLenum;
stride: GLsizel; data: pointer); stdcall; external OpenGL32;

Procedure glColorPointer (size: GLint; atype: GLenum; stride: GLsizel;
data: pointer); stdcall; external OpenGL32;

procedure glDrawArrays (mode: GLenum; first: GLint; count: GLsizel);
stdcall; external OpenGL32;

Procedure glEnableClientState (aarray: GLenum);
stdcall; external OpenGL32;

Procedure glDisableClientState (aarray: GLenum);
stdcall; external CpenGL32;

const
GL_VERTEX_ARRAY = $8074;
GL__COLOR_ARRAY = $8076;

Отсюда первое, что приходит на ум :

glVertexPointer(2, GL_FLOAT, 0, @VertArr);
glColorPointer(3, GL FLOAT, 0, @ColorArr);
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_COLOR_ARRAY);
glDrawArrays(GL_LINE_STRIP, 0, ArrLen);
glDisableClientState(GL_COLOR_ARRAY);
glDisableClientState(GL_VERTEX_ARRAY);

Но мне не понятно, что же лежит в EnumArr.
И режет гла странное сочетание.
Размер EnumArr равен размеру ColorArr и VertArr ?
Тогда не слишком ли много раз отобразятся связанные линии ?


 
Начинающий_1   (2006-08-29 18:39) [2]

>Размер EnumArr равен размеру ColorArr и VertArr ?
VertArr - Массив вершин (3D) размера m * n.
ColorArr - Массив из m цветов цветов, заданных тройкой (f1, f2, f3). (dlFloat)
EnumArr - Массив индексов размера n. = (0, 1, 2, ...., n - 1).
Требуется нарисовать m линий, каждая имеет n вершин и каждая i-ая
линия имеет цвет ColorArr[i]
>Тогда не слишком ли много раз отобразятся связанные линии ?
Вроде, каждая линия ( длиной n вершин) прорисовывается только один раз.


 
DevilDevil ©   (2006-08-29 20:28) [3]

А по кой фиг, извините, его оптимизировать? Раз инициализировал, потом только лист юзать. Или я что то не понял?


 
Начинающий_1   (2006-08-29 22:05) [4]

>А по кой фиг, извините, его оптимизировать?
Если поступили новые данные, а это может быть довольно часто,
нужно его перекомпелировать.


 
Rial ©   (2006-08-30 00:55) [5]

Ну, я понял суть.
Тогда оптимизировать тут можно разве что
 glColor3f(ColorArr[i, 0], ColorArr[i, 1], ColorArr[i, 2]);
и написать
 glColor3fv(ColorArr[i]);

А есть ли тормоза вобще ?
Если есть, то, скорее всего, собака порылась именно в
как таковой GL_LINE_STRIP.
Впредь старайся делать все только через GL_TRIAGLES или
GL_TRIANGLE_STRIP. Получешь большое ускорение.

Попробуй что то типа этого :

procedure TRialOpenGL.Line(Const X1, Y1, Z1, X2, Y2, Z2 : GLFloat);
Var X, Y, R : GLFloat;
begin
Y :=(X2 - X1) / 2.0;
X :=(Y2 - Y1) / 2.0;
R :=FLineWidth / Hypot(X, Y);
Y :=Y * R;
X :=X * R;
glBegin(GL_TRIANGLES);
 glVertex3f(X2 - X, Y2 + Y, Z2);
 glVertex3f(X1 - X, Y1 + Y, Z1);
 glVertex3f(X1 + X, Y1 - Y, Z1);
 glVertex3f(X2 - X, Y2 + Y, Z2);
 glVertex3f(X1 + X, Y1 - Y, Z1);
 glVertex3f(X2 + X, Y2 - Y, Z2);
glEnd;
end;


Короче, оптимизируй вывод самих линий применительно к твоей задаче.


 
Начинающий_1   (2006-08-30 04:47) [6]

Спасибо ! Попробую.
У меня еще вопрос:
При поступлении новых данных ( динамический двумерный массив ),
я проверяю произошли ли изменения в них.
Для этого храню копию предыдущего массива и сравниваю ее с новым.
Отнюдь не лучший способ. Подскажите, как это можно реализовать
по человечески ? :))


 
Rial ©   (2006-08-30 16:40) [7]

Если крайне важна точность проверки, то
другого столько надежного способа, естественно, нет.

Но с потерями точности пожно пользоваться какой - либо
хеш - функцией. На крайний случай считай контрольную сумму.

Вот элементарный пример:

procedure XorData(Const MainData,KeyData :Pointer;Const MainSize,KeySize :Integer);
Var ptMain, ptKey : PByte;
   I, J, D       : Integer;
begin
If (MainSize<=0)or(KeySize<=0)then Exit;
D :=MainSize div KeySize;
ptMain :=MainData;
I :=0;
While (I<=D-1)do begin
 ptKey :=KeyData;
 J     :=0;
 While (J<=KeySize-1)do begin
  ptMain^:=ptMain^ xor ptKey^;
  Inc (ptMain);
  Inc (ptKey);
  Inc (J);
 end;
 Inc(I);
end;
D :=MainSize mod KeySize;
ptKey :=KeyData;
J:=0;
While (J<=D-1)do begin
 ptMain^:=ptMain^ xor ptKey^;
 Inc (ptMain);
 Inc (ptKey);
 Inc (J);
end;
end;


Запоминаешь код, сравниваешь его потом с новым.
Разумным будет запоминать 8-16 байт.
Вероятноть ошибки, соответственно:
p= (2 ^ (-l) , l - длина кода


 
DevilDevil ©   (2006-08-31 00:26) [8]

Вот мой вопрос относительно ЛИСТОВ, если не возражаете, конечно:

"Где физически хранится Лист, почему и насколько скорость его использования выше обычных методов?"


 
Rial ©   (2006-08-31 04:45) [9]

Про скорость.
При воспроизведении листов не производятся рассчеты,
поэтому если неободимо сделать их один раз и их много,
то листы использовать предпочтительно.
Если же используются, например, массивы вершин,
то особого прироста не будет.
В принципе, листы пригождаются редко ...
разве что при допотопной загрузке текстур.
При компановке Vertex-ов в лист максимум, чего удасться добиться -
это 5-10% прироста скорости.

Раньше подразумевалось, чо листы хранятся в видеопамяти.
Но про них все забыли сейчас, и их поддержка в
следующих версиях карт вообще не очень то гарантируется.
Поэтому лучше их уже не трогать, иначе пожно наткнуться
на тормоза в будущем, на каких нибудь новых видеокартах.
Лист хранится так же, как и текстура.


 
Начинающий_1   (2006-08-31 14:03) [10]

Спасибо !
Такая точность меня вполне устраивает :)
У меня ситуация такая:
Поступают данные. Если они не совпадают с предыдущими,
то генерирую новый массив вершин и на его базе компилирую лист.
При совпадении просто прорисовываю старый лист. Что, в этой ситуации
и в свете новых топиков, лучше использовать вместо листа ?
И еще.
Обычно изменения касаются только небольшой части данных.
Я пытался генерировать два листа ( на перую половину данных
и на вторую). Но, почему - то, генерация двух листов занимала почти
в 3.5 раза больше времени и я отказался от этой затеи.
Интересно на что тратилось время и можно ли это обойти ?


 
Rial ©   (2006-08-31 20:40) [11]

> Но, почему - то, генерация двух листов занимала почти
> в 3.5 раза больше времени и я отказался от этой затеи.

Время тратилось на компиляцию листа, а именно,
на выделение памяти под его уструктуру и запоминание команд.
Это действительно известный факт.
Лист компилируется в 2-3 раза дольше, чем выполняется.

Если уж данные так часто меняются, то наиболее разумным решением
будет отказ от листов вообще. Нужно будет просто каждый
раз вызывать обычную отрисовку.
Главное, что тогда и сравнивать данные не будет необходимости.
Просто не нужно было так усложнять жизнь.



Страницы: 1 вся ветка

Текущий архив: 2007.07.22;
Скачать: CL | DM;

Наверх




Память: 0.5 MB
Время: 0.03 c
2-1182415834
Abcdef123
2007-06-21 12:50
2007.07.22
Почему датасоурс Nil (не определяется)? (выдает ошибку)Что не так


1-1179470162
DELORAC
2007-05-18 10:36
2007.07.22
GetDesktopWindow и Application.MessageBox


15-1182234630
StriderMan
2007-06-19 10:30
2007.07.22
Игра шарики. помогите найти!


11-1165943277
Goko
2006-12-12 20:07
2007.07.22
Создание MCK компонента


15-1182807045
SerJaNT
2007-06-26 01:30
2007.07.22
Вывод из WebMoney