Текущий архив: 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