![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Как рисовать 3D и 2D объекты в одной сцене? [Delphi, Windows]
Creative © (2006-12-12 16:05:00)Есть процедура
procedure RenderScene:
begin
A.Render; // А и В - произвольные объекты
B.render;
end;
Метод Render объектов А и В обычную процедуру рисования
glPushMatrix;
...// трансформации
....//рисование
glPopMatrix;
НО: Объект А должен находиться в двумерном пространстве и иметь фиксированный размер и координату(например это какое то системное окошко, индикатор, кнопка и так далее), а объект B - находиться в трехмерном пространстве и подвергаться различного рода трансформациям (собственно объекты, которые видит пользователь).
Как совместить рисование первого и второго?
Мне кажется, что проблема в том, что в Resize можно описать только ОДНУ систему координат - либо glOrtho, либо gluPerspective, хотя возможно я и ошибаюсь.
Rial (2006-12-18 17:04:00) [1]Нет, уверен, меньше нас :)
Просто я все жду, когда же сюда сбегутся
защитники классов, ООП, VCL ...
Их же явно больше. Затопчут.
Ну да простит их всевышний, многие не ведают, что творят %)
Есть простой способ в Delphi кстати.
Там же можно посмотреть генерируемый asm - код.
Вот по нему очень легко понять, какой алгоритм
более оптимальный.
Creative (2006-12-18 14:34:00) [2]
> Что то много как то у меня слов получается, о больном потому
> что :)
почему о больном? не уверены, много вас или мало? :-)
Rial (2006-12-18 14:04:00) [3]> [29] Creative (18.12.06 10:37)
> > У меня такие процессы вешают всю систему сразу же :)
> А почему?
Ну, по идее, если процесс получает RealTime и начинает усиленно
работать, что все процессорное время уходит только на него.
Не спасет даже Ctrl+Alt+Del. Но до таких крайностей не
обязательно же доводить :)
I>
> А почему PRec = ^TRec, а не Rec: TRec?
Ну так Data - указатель же.
Привести указатель с TRec не получится, а к указателю на TRec -
запросто. Точнее, получится, но придется копировать данные,
например, так:
Move(Data^, Rec, SizeOf(Rec));
что при больших размерах TRec не очень хорошо.
P.S. А почему Data - указатель ? :)
Ну а что это еще может быть, не понятно. Выделили память,
считали, например, и файла все в область памяти и бегаем
по указателю с разными смещениями.
> А что тогда? Опять возвращаются к рекордам?
Да нет. Я не совсем это имел ввиду.
Просто всему свое место. Не надо на одном зацикливаться.
Если разработка идет несколькими людьми, то классы
предпочтительнее. Или если проект очень большой и потом
будет сложно разобраться без классов (лучше большие
модули все же запихнуть в них).
А если человек один, и он уверен, что правильно
везде после использования финализирует переменные,
освободит память и т.п., то почему бы и не рекорды.
Что то много как то у меня слов получается, о больном потому что :)
Creative (2006-12-18 10:37:00) [4]
> У меня такие процессы вешают всю систему сразу же :)
А почему?
Creative (2006-12-18 10:36:00) [5]
> Ну, рекод - это не более чем более удобный доступк
> области памяти.Например, есть Data : Pointer, в ней лежат
> Integer и 2 Byte.Намного удобнее и понятнее сделать так:
> TRec = packed record
> I : Integer;
> B1, B2 : Byte;end;
> PRec = ^TRec;
...
> PRec(Data)^.B2:=10;
> Чем вот так:PByteArray(Data)^[SizeOf(Integer)
> + SizeOf(Byte) * 2]:=10;
А почему PRec = ^TRec, а не Rec: TRec?
>А класс - это нечто намного большее.
> Слышали Вы про виртуальные, абстрактные методы и т.п.Они
> разработку значительно упрощают.И целостность данных позволяют
> грамотно обеспечить.Все до тех пор, пока не идет война за
> каждый тик процессора :)
А что тогда? Опять возвращаются к рекордам?
MeF Dei Corvi (2006-12-15 21:54:00) [6]
> > а что значит "временно дать RealTime"?
У меня такие процессы вешают всю систему сразу же :)
Rial (2006-12-15 17:28:00) [7]> [25] Creative (15.12.06 16:50)
> FPS?
Да, оно самое.
> а что такое счетчик ограничений?
Ну, например, счетчик такого типа, что не разрешает
перерисовывать экран чаще, чем раз в 20мс.
Вообще, имхо, лучше делать постоянное FPS,
потому как наверняка есть еще какие рассчеты,
а не только вывод на экран. А рассчеты наверняка
четко привязаны ко времени
(ну хотябы падение тела в реальном времени).
Смыла не вижу перерисовывать экран чаще, чем эго
содержимое должно изменяться.
> а что значит "временно дать RealTime"?
Приоритет процесса.
procedure SetPriority(Const PriorityClass, ThreadClass : Integer);
Var ProcessID : DWORD;
ProcessHandle : THandle;
ThreadHandle : THandle;
begin
ProcessID;=GetCurrentProcessID;
ProcessHandle:=OpenProcess(PROCESS_SET_INFORMATION, False, ProcessID);
SetPriorityClass(ProcessHandle, PriorityClass);
ThreadHandle:=GetCurrentThread;
SetThreadPriority(ThreadHandle, ThreadClass)
end;
> Вот так так...а я то думала, чо расписывать извлечение значений
> полей через GetValue - это ужас как круто....
Круто, конечно.
Но это в итоге лишнии инструкции call и ret.
Так то, с т.з. переменных класса, это те же
поля записей.
Name:=MyClass.FName;
Name:=MyRecord.Name;
- разницы особой нет.
Только в случае с классом получаем лишнюю инструкцию move,
ибо переменная MyClass - своего рода указатель на запись.
Может, я мелочный, конечно. Но, имхо, все эти мелочи
со временем могут в большой ком снежный сложиться.
> Я правильно понимаю, что использоваться рекорд - быстрее,
> а класс - многофункциональнее? Или есть еще принципиальные
> различия?
Ну, рекод - это не более чем более удобный доступ
к области памяти.
Например, есть Data : Pointer, в ней лежат Integer и 2 Byte.
Намного удобнее и понятнее сделать так:
TRec = packed record
I : Integer;
B1, B2 : Byte;
end;
PRec = ^TRec;
...
PRec(Data)^.B2:=10;
Чем вот так:
PByteArray(Data)^[SizeOf(Integer) + SizeOf(Byte) * 2]:=10;
А класс - это нечто намного большее.
Слышали Вы про виртуальные, абстрактные методы и т.п.
Они разработку значительно упрощают.
И целостность данных позволяют грамотно обеспечить.
Все до тех пор, пока не идет война за каждый тик процессора :)
Creative (2006-12-15 16:50:00) [8]
> 1. Количество кадров, которые успевают отрисоваться.
FPS?
> нет счетчика ограничейний.
а что такое счетчик ограничений?
> Статистику
> лучше считать временно дав RealTime.
а что значит "временно дать RealTime"?
> Если класс заменяет
> record с двумя полями,а значение полей извлекаются через
> виртуальные методыродителя, да еще через что то типаfunction
> GetValue : TValue;begin Result:=FValue;end;то тут почуствуешь
> в полной мере все "достоинства" ооп :)Итог - замедление
> раз в 5-10.
Вот так так...а я то думала, чо расписывать извлечение значений полей через GetValue - это ужас как круто....
Я правильно понимаю, что использоваться рекорд - быстрее, а класс - многофункциональнее? Или есть еще принципиальные различия? Я напрмимер по странному стечению обстоятельств сначала научилась работать с классами, а про рекорды узнала позже, поэтому тебперь мне с ними трудно.
Rial (2006-12-15 16:40:00) [9]> [23] Creative (15.12.06 10:18)
> А как вы оцениваете производительность программы? Время
> выпорнения операций? Или что это?
1. Количество кадров, которые успевают отрисоваться.
Подходит только если кадры рисуются постоянно и нет
счетчика ограничейний. Способ самый ущербный.
2. Обжее время, затраченное на выполнение все операций
поделить на прошедшее время. Имеется ввиду не разовая
задача, конечно, а отрисовка с относительно постоянным
количеством кадров.
3.Операции считать. Можно посчитать с точностью до
+- 0.1 мс. Статистика, разные условия выполнения и т.п.
Статистику лучше считать временно дав RealTime.
> Не намельчить - в смысле - не пытаться сделать классы из
> всего, чего только можно?
Вот это в точку подмечено.
Особенно заметно это там, где производятся
арифметические рассчеты.
Если класс заменяет record с двумя полями,
а значение полей извлекаются через виртуальные методы
родителя, да еще через что то типа
function GetValue : TValue;
begin
Result:=FValue;
end;
то тут почуствуешь в полной мере все "достоинства" ооп :)
Итог - замедление раз в 5-10.
Creative (2006-12-15 10:18:00) [10]
> Rial © (15.12.06 01:31) [22]
когда я переводил достаточно
> большой кусоккода OpenGL на ООП (объектов вышло достаточно
> много), то потерял 20%производительности. Так что главное
> - не "намельчить".
А как вы оцениваете производительность программы? Время выпорнения операций? Или что это?
Не намельчить - в смысле - не пытаться сделать классы из всего, чего только можно?
Rial (2006-12-15 01:31:00) [11]> [21] Vga © (14.12.06 13:40)
> > [20] Creative (14.12.06 12:56)
> > Я кстати не мгу понять: почему в обоих процедурах (Save,
> > Load) - аргумент - константа?
> Я тоже. Можно const оттуда убрать. Смысла передавать указатель
> по ссылке - не вижу.
Нет, вы конечно правы.
Код с Const и без него будет сгенерирован компилятором
абсолютно идентичный.
Но вот только указатель это или нет - это тут очевидно.
А следить за каждой такой мелочью порой очень сложно :)
Если бы аргумент был TGLMatrixes - потери были бы налицо.
Так что это страховка на будущее.
> [10] Creative (13.12.06 16:54)
> Меня очень волнует реакция на вот это утверждение:
>
> я заметила, что в Resize вообще можно не ставить теперь
> пересчет матриц, кажется и так все ресайзится
Все дело в том, что в gluPerspective используется ArcTan.
А это достаточно медленная арифметическая операция, что иногда критично.
Resize иногда выполняется 2-3 раза за всю работу приложения.
> [20] Creative (14.12.06 12:56)
> А я проше сделала (ладно, может и не проще, понятнее для
> меня) - сделала TGLMatrixes не рекордом, а классом и создала
> две переменные-объекты класса.
Это правильнее безусловно. Но есть одна мелочь. Не исключаю,
что у меня кривые руки, но когда я переводил достаточно большой кусок
кода OpenGL на ООП (объектов вышло достаточно много), то потерял 20%
производительности. Так что главное - не "намельчить".
Vga (2006-12-14 13:40:00) [12]> [20] Creative (14.12.06 12:56)
> Я кстати не мгу понять: почему в обоих процедурах (Save,
> Load) - аргумент - константа?
Я тоже. Можно const оттуда убрать. Смысла передавать указатель по ссылке - не вижу.
Creative (2006-12-14 12:56:00) [13]
> А память под матрицы выделить? Либо GetMem(OrthoMatrix,
> SizeOf(TGLMatrixes)) и то же для второй. Еще можно убрать
> объявление PGLMatrixes и передавать TGLMatrixes как var
> в SaveMatrix и как const в Loadmatrix
А я проше сделала (ладно, может и не проще, понятнее для меня) - сделала TGLMatrixes не рекордом, а классом и создала две переменные-объекты класса. Все работает, проекции грузятся, как раз то, что я хотела.
Этот способ не хуже?
Я кстати не мгу понять: почему в обоих процедурах (Save, Load) - аргумент - константа?
Vga (2006-12-14 12:50:00) [14]> [18] Creative (14.12.06 11:13)
А память под матрицы выделить? Либо GetMem(OrthoMatrix, SizeOf(TGLMatrixes)) и то же для второй. Еще можно убрать объявление PGLMatrixes и передавать TGLMatrixes как var в SaveMatrix и как const в Loadmatrix
Creative (2006-12-14 11:13:00) [15]
> Rial © (12.12.06 19:58) [2]
Я попробовала написать сохранение матриц:
type
TGLMatrix = Array [0..3, 0..3] of GLFloat;
TGLMatrixes = record
Model : TGLMatrix;
Proj : TGLMatrix;
Tex : TGLMatrix;
end;
PGLMatrixes = ^TGLMatrixes;
procedure SaveMatrix(Const PMatrixes : PGLMatrixes);
procedure LoadMatrix(Const PMatrixes : PGLMatrixes);
var
OrthoMatrix : PGLMatrixes;
PerspMatrix : PGLMatrixes;
implementation
procedure SaveMatrix(Const PMatrixes : PGLMatrixes);
begin
With PMatrixes^ do begin
glGetFloatv(GL_PROJECTION_MATRIX, @Proj);
glGetFloatv(GL_MODELVIEW_MATRIX, @Model);
glGetFloatv(GL_TEXTURE_MATRIX, @Tex);
end;//With
end;
procedure TCWnd.ResizeGLScene(Width, Height: integer);
begin
glMatrixMode(GL_PROJECTION);
glLoadIdentity;
glOrtho(0, Width, Height, 0, -1, 1);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity;
glViewport(0, 0, Width, Height);
SaveMatrix(OrthoMatrix);
glMatrixMode(GL_PROJECTION);
glLoadIdentity;
gluPerspective(30, Width/Height, 1.0, 15.0);
glRotate(30,1.0,0.0,0.0);
glRotate(60,0.0,1.0,0.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity;
glViewport(0, 0, Width, Height);
SaveMatrix(PerspMatrix);
end;
Но вероятно я как то неправильно сделала, и PMatrixes^ = NIL. Поправьте меня, пожалуйста.
Piroxyline (2006-12-13 19:19:00) [16]Хотя, наверное, из-за подобной картины:
|
A\--| B
\ |
-------+-------
|\
C|-\ D
| \
koeff = AB/CD
Или что-то типа такого. По крайней мере, мы похожую картину сейчас по физике разбирали
Piroxyline (2006-12-13 19:16:00) [17]Имхо, это уже к создателям OpenGL'я
Creative (2006-12-13 17:59:00) [18]А может кто-нибудь объяснить, почему угол наклона в направлении оси X задается именно отношением ширины области вывода к ее высоте?
Creative (2006-12-13 17:47:00) [19]
> MeF Dei Corvi © (13.12.06 17:41) [13]
Получилось, получилось!!!!!! Спасибо :-)
MeF Dei Corvi (2006-12-13 17:41:00) [20]Попробуй так:
glPushMatrix;
gluPerspective();
...
glPopMatrix;
glDisable(GL_DEPTH_TEST);
glPushMatrix;
glOrtho();
...
glPopMatrix;
glEnable(GL_DEPTH_TEST);