Страница 46 из 61
Re: Cheb's Game Engine
Добавлено: 08.03.2021 20:55:21
Alex2013
Уф! "Ужасный тормоз" победил ! Очень просто, кстати ... Поместил в снятие скрин-шота в отдельный поток (с двухступенчатой активаций по дополнительному таймеру ) и что выдумаете? Рендер вообще его "не замечает" ... Но появилось странное ограничение по объему данных.
(Разрешению текстуры 1150х1000 все ок а например 1200х1000 не работает причем как-то странно внезпно "вспоминает" самый первый из захваченных кадров... ).
Толи не успевает. Толи еще что-то...
Была бы это программа на ХайАсме я бы точно сказал, что это снова"кольцевание прорезалось " но в Лазарусе вроде такого почти не бывает .
FPS радует а глюк нет ...


Зы
Извиняюсь за оффтоп .

Re: Cheb's Game Engine
Добавлено: 09.03.2021 17:04:58
Cheb
Опенгл и отдельный поток - это "безумству храбрых поём мы песню".
То есть, иногда, у кого-то, работает. Иногда. У кого-то. После плясок с бубном, достойных битого жизнью профессионала в этом гапи.
По моему скромному мнению - скриншот можно снимать в отдельном потоке, а вот в текстуру заливать - только в основном. Иначе драйвер может не понять и обделаться от неожиданности.
У меня в движке создание текстур и заливка в них содержимого - фоновые задачи, разрешённые к выполнению только в основном потоке.
З.Ы. Говорят, что текстуры заливать можно, после определённых плясок с бубном:
https://www.khronos.org/opengl/wiki/Ope ... ithreadingно всё же ведь зависит от радиуса кривизны драйвера
Добавлено спустя 15 часов 38 минут 54 секунды:Вот к вопросу о глобальных переменных: когда всё состояние БД собрано в одну запись (сколько я на отдельные глобальные переменные охотился, сколько они крови моей выпили!) его можно одним махом подменить, заморозив один модуль в памяти и запустив другой.
Пока использую только для модуля панели управления, который заведует выбором языка, выбором модуля и показом всяких страшных сообщений:
Код: Выделить всё
function THubModule.FreezeInMemory: boolean;
begin
Result:= true;
if f_frozen then exit;
f_frozen:= true;
MOVE(chepersy.Cps, SavedChepersyState, sizeof(chepersy.Cps)); //включая диспетчер памяти инстансов и всю информацию о зарегистрированных классах
FillChar(chepersy.Cps, sizeof(chepersy.Cps), 0); // NO deinit!
SavedState:= Mother^.Module.State - [msa_MustUnload];
FillChar(Mother^.Module.State, sizeof(Mother^.Module.State), 0);
SavedLogClass:= MyLogClass;
MyLogClass:= nil;
if Module = Self then Module:= nil;
HubModule:= Self;
Mother^.Module.HubState:= _hubInert;
Mother^.Module.HubPrevState:= _hubInert;
end;
procedure THubModule.UnFreezeFromMemory;
begin
if not f_frozen then Die('Cannot unfreeze, not frozen.');
if not chepersy.Cps.IsDone then begin
Mother^.State.StateTrashedRestartRequired:= true;
Die(RuEn(
'FATAL: предыдущий модуль не завершил работу с %0',
'FATAL: the previous module failed to close the %0'
), [ChepersyTitle]);
end;
MOVE(SavedChepersyState, chepersy.Cps, sizeof(chepersy.Cps));
Mother^.Module.State:= SavedState;
MyLogClass:= THubLogic;
f_frozen:= false;
Module:= Self;
end;
Re: Cheb's Game Engine
Добавлено: 09.03.2021 17:45:53
runewalsh
Вроде бы безопасный способ скопировать по указателю что угодно, включая управляемые типы — это
Код: Выделить всё
var
a, b: T;
procedure fpc_finalize(data, typeInfo: pointer); [external name 'FPC_FINALIZE'];
function fpc_addref(data, typeInfo: pointer): SizeInt; [external name 'FPC_ADDREF'];
fpc_finalize(@b, TypeInfo(T));
// ↑ Или просто Finalize(b), если переменная b типизирована, а не скрыта за голым указателем.
// ↑ Или изкоробочное FinalizeArray(@b, TypeInfo(T), 1).
Move(a, b, sizeof(T));
fpc_addref(@b, TypeInfo(T)); // Нет аналога из коробки.
По идее можно было бы использовать единственную fpc_copy(src, dest, typeInfo) или изкоробочную CopyArray, но последний раз они у меня работали ТОЛЬКО с managed-типами, а fpc_finalize + Move + fpc_addref копирует что угодно, и вроде как полностью универсально и безопасно (даже совместимо с managed operators).
Re: Cheb's Game Engine
Добавлено: 09.03.2021 21:24:53
Alex2013
Cheb писал(а):Опенгл и отдельный поток - это "безумству храбрых поём мы песню".
Это ты слишком хорошо обо мне думаешь....

Разумеется "в поток" я упрятал только "снятие скрина" ("Наружу" выглядывает только глобальная переменная из которой рендер "ложками черпает вдохновение"

) Рендер я кстати "утрамбовал" в мультимедийный таймер и неуверен что это хорошая идея ( но в примерах такое встречается )
Зы
Глюк тоже немного укротил .
(Оказалась что "играть в суперсэмплинг" плохая идея и максимальный размер выдергиваемого скрина должен быть ("Ширина экрана","Высота экрана"-2) тоже непонятно, но уже несмертельно . )


Re: Cheb's Game Engine
Добавлено: 10.03.2021 01:39:57
Cheb
runewalsh писал(а):Вроде бы безопасный способ скопировать по указателю что угодно, включая управляемые типы — это
Спасибо, буду иметь в виду.
Но я намеренно копирую так, "чтобы компилятор ни о чём не догадался". Как бы замораживая всю эту сущность со всеми её счётчиками ссылок в безвременье.
А собирание глобальных переменных в одну запись имеет то преимущество, что по скорости ничем не отличается от обращения к отдельным глобальным переменным.
Кстати, для оптимизации необходимо будет запилить свой аналог массива, адресуемого только последовательно. Т.е. добавить в конец, начать сначала, прочитать следующий, очистить - все доступные операции. И без никакого счётчика ссылок.
Но пока я никак эту заразную машину состояний модуля не добью. То один глюк прёт, то другой.
Alex2013 писал(а):"Высота экрана"-2
Ы?
А там, случаем, где-то параметр не "нижний край" вместо "высота"? А то знаю я этих затейников.
Кстати, теперь понятно. Блит со стретчем - какая-то стрёмная операция, я бы не рискнул. Суперсэмплинг эффективнее делается внутри огля, на шейдерах.
Проверено на практике: если выборки из текстуры ложатся кучно в очень малую область - можно хоть тридцать чтений из текстуры на пиксел в full HD. И это - на хилом Intel HD 3000.
Re: Cheb's Game Engine
Добавлено: 10.03.2021 12:47:15
Alex2013
Cheb писал(а):. Блит со стретчем - какая-то стрёмная операция
Угу ...
Кусок самого "загадочного" кода в моей программе .
Код: Выделить всё
procedure TCaptureThread.Execute;
begin
while (not Terminated) do begin
IF (bmp <> Nil ) and UPDATE Then begin UPDATE:=False;
ProcessRUN :=True;
CaptureForm.CreateSnapshotPlusWH(bmp,R_W,R_H,unit6.FHandle,RS);
Tbmp:=bmp; Tbmp.Canvas.Draw(0, 0 ,bmp);
ProcessRUN :=False;
end
end
end;
Нет я знаю что
Tbmp:=bmp; Tbmp.Canvas.Draw(0, 0 ,bmp); это дичайший бредовый бред ... но без него текстура "не подхватывается" .
Cheb писал(а): Суперсэмплинг эффективнее делается внутри огля, на шейдерах.
Дело за малым научиться использовать эти самые шейдеры. А я еще и в самом "классическом OpenGL " ой как "плаваю".
Re: Cheb's Game Engine
Добавлено: 11.03.2021 04:33:51
Cheb
Alex2013 писал(а):научиться использовать эти самые шейдеры.
Боль. Боооооль.
Зато потом ощущаешь себя, словно ты на холме с пулемётом, а вокруг одни дикари
это дичайший бредовый бред ... но без него текстура "не подхватывается" .
А как не подхватывается - просто ничего не происходит, или её развозит на разводы?
Re: Cheb's Game Engine
Добавлено: 11.03.2021 10:49:24
Alex2013
Cheb писал(а):А как не подхватывается - просто ничего не происходит, или её развозит на разводы?
Просто не видит текстуру как будто её нет. Возможно заявлений размер не совпадает с реальным или еще что-то.
"Пиксель формат" проверял pf24bit все ок.
Для проверки есть простая спец. процедура.
Код: Выделить всё
Function BitmapTest(var TB:TBitmap; Mode:TPixelFormat;
F_Free:Boolean=true):Boolean ;
Var
CB:TBitmap;
Begin
Result:= tb.PixelFormat=mode ;
if not Result then
begin
CB:=TBitmap.Create;
cb.PixelFormat:=Mode;
cb.SetSize(tb.Width,tb.Height);
Cb.Canvas.Draw(0,0,TB);
if F_Free then tb.free;
Tb:=CB;
end
end;
На этом битмапе вообще интересные дела творятся ... Например решил я нарисовать курсор мыши, но думаю, а что мешает мне сделать "битовую версию" рисования линии ? Сказано сделано ! И что ? "Помехи" почти как КП 2077 любят показывать(но не пиксиляция, а "суб пиксельные" черные полосы типа "разсинхронизация" ). Сделал через канвас все ок . Вот откуда ? Да."Выводит OpenGL" но я рисую крестик курсора до того как OpenGL вообще узнает о самом существовании текстуры.
Re: Cheb's Game Engine
Добавлено: 11.03.2021 13:46:03
Cheb
Вангую, что этот битмап - сложная сущность с встроенной двойной буферизацией. И для получения из него "указателя на данные" с ним надо сначала что-то сделать, чтобы привести в пригодное к чтению состояние.
Журналируй, что кормишь glTexImage - указатель не нулевой, случаем?
Смотри, что говорит glGetError()
вот может пригодится
Код: Выделить всё
function GlErrorCodeToString(c: GLenum): Utf16String;
begin
case c of
GL_INVALID_ENUM: Result:= 'GL_INVALID_ENUM';
GL_INVALID_VALUE: Result:= 'GL_INVALID_VALUE';
GL_INVALID_OPERATION: Result:= 'GL_INVALID_OPERATION';
GL_STACK_OVERFLOW: Result:= 'GL_STACK_OVERFLOW';
GL_STACK_UNDERFLOW: Result:= 'GL_STACK_UNDERFLOW';
GL_OUT_OF_MEMORY: Result:= 'GL_OUT_OF_MEMORY';
GL_INVALID_FRAMEBUFFER_OPERATION_EXT: Result:= 'GL_INVALID_FRAMEBUFFER_OPERATION_EXT';
GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT: Result:= 'GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT';
GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT: Result:= 'GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT';
GL_FRAMEBUFFER_INCOMPLETE_DUPLICATE_ATTACHMENT_EXT: Result:= 'GL_FRAMEBUFFER_INCOMPLETE_DUPLICATE_ATTACHMENT_EXT';
GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT: Result:= 'GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT';
GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT: Result:= 'GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT';
GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT: Result:= 'GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT';
GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT: Result:= 'GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT';
GL_FRAMEBUFFER_UNSUPPORTED_EXT: Result:= 'GL_FRAMEBUFFER_UNSUPPORTED_EXT';
GL_FRAMEBUFFER_STATUS_ERROR_EXT: Result:= 'GL_FRAMEBUFFER_STATUS_ERROR_EXT';
else
Result:= RuEn('код', 'code') + ' ' + IntToHex(c, 8) + 'h';
end;
end;
Добавлено спустя 8 минут 36 секунд:P.S.
В многопоточке такой метод разграничения
эффективен, как картонная броня против снаряда главного калибра.
Другой поток выполняется на другом ядре, до которого изменения памяти могут доходить с большой задержкой, как до того жирафа. Ведь кеши 1 и 2 уровня у ядер собственные.
Только TCriticalSection.
Плюс, двойную буферизацию: битмапа - два, один хватает экран, из другого опенгл грузит в текстуру. Потом меняются. Переключение битмапа и чтение в текстуру обернуть в одну критическую секцию.
Re: Cheb's Game Engine
Добавлено: 12.03.2021 01:45:28
Alex2013
Cheb писал(а):В многопоточке такой метод разграничения эффективен, как картонная броня против снаряда главного калибра.
Это разумеется верно но мне нужно узнать закончилось ли снятие скрина или нет чтобы снова поднять флаг UPDATE.
А поскольку проверка происходит по таймеру (а рендер крутится в другом ) то особой точности не нужно (другое дело что рендер может теоретически попасть в момент "пересменки " но ничего особо страшного это вызвать не может никакой "обратной записи" вне TCaptureThread нет, а "кусок памяти по адресу" так останется куском памяти по адресу )
Cheb писал(а):Плюс, двойную буферизацию: битмапа - два, один хватает экран, из другого опенгл грузит в текстуру. Потом меняются. Переключение битмапа и чтение в текстуру обернуть в одну критическую секцию.
А вот это разумеется дельная мысль, попробую !
вот может пригодится
Угу только в рендере с "ВиАр контестом" особо "не попрыгаешь" (уже убедился, что любые задержки больше 10-20 мс (или нестабильности) делают, что-то нехорошее с тамошней хитрой репроекцией ( запоминающей кадры и частично "подменяющей рендер" при быстром движении башкой ) )
glTexImage пробовал и "нулевой" и "не нулевой" и как мне показалось разницы нет потому что дальше все равно идет glTexSubImage2D. (Вот на несовпадение размеров реакция действительно жесткая )
Re: Cheb's Game Engine
Добавлено: 13.03.2021 15:02:23
Cheb
З.Ы. Не два, а много (с запасом на два экрана). И хватать полосками по 64 пиксела высотой. И в опенгл заливать по полоске.
Минус - гарантирован tearing (когда половина экрана опережает другую). Плюс - вытираешь тапочки об латентность.
Re: Cheb's Game Engine
Добавлено: 13.03.2021 21:10:31
Alex2013
Cheb писал(а):З.Ы. Не два, а много (с запасом на два экрана). И хватать полосками по 64 пиксела высотой. И в опенгл заливать по полоске.
Ну это уже на будущее стоит иметь ввиду (ИМХО на уровне техно-демки чрезмерно "вылизывать" оптимизацию смысла нет все равно в "боевом коде" многое будет иначе ). Задача пока просто "попробовать получить результат" в относительно стабильном виде . (Так сказать "на троечку") и двинутся дальше.
Сейчас например разбираюсь с "псевдо-текстовым GUI интерфейсом" точнее с его эмуляций в OpenGL.
(те-же окна, кнопки, панели что и в LCL но "висящие в пространстве" )
Re: Cheb's Game Engine
Добавлено: 14.03.2021 15:56:36
Cheb
Тоды - не помню уже просто, приводил или нет - простой, как валенок, способ понизить латентность
https://habr.com/en/post/308980/ там на лазарусе, но для 11-го директикса. Но для огля тот же метот работает также: перед SwapBuffers вызвать принудительную синхронизацию цпу и гпу путём чтения glReadPixels фрейимбуфера. Он говорит, мипмап надо генерировать, но я думаю прочитать несколько кусочкоа 8х8 из разных мест даст тот же результат: пока не нарисовано - прочитать не сможет, тем самым принуждая синхронизацию.
Добавлено спустя 10 часов 12 минут 5 секунд:Перелопатил систему привязки системы состояний для тредов на нормальный threadvar, оставив связанный список для специфичного места менеджера тредов в модуле и рисовальщика индикаторов загрузки тредов.
И хватит до следующих выходных.
Re: Cheb's Game Engine
Добавлено: 19.03.2021 08:54:26
Cheb
Упсник
Долго не мог найти причину странных крахов при выходе, а конкретно - при попытке очистить/вывести буфер сообщений об ошибках. Уводит куда-то в глубины форматирования строк, оттуда - в неведомые недра RTL, и уже там падает.
Потом зацепился взглядом за гистограммы.

Чу! Что это за загадочный тред без названия и почему у основного треда нулевая загрузка?
Упс.
Менеджер тредов сводит все их записи в запись основного треда. Которая должна лежать в строго определённой глобальной переменной. А я, когда переделывал...
Короче, указатель на запись для основного треда должен выставляться в @Mother^.ExceptionState , а не new(PMotherSehState) , как у всех остальных.
А я это граничное условие забыл

Ииии-хряп. Ииии-хряп.
Re: Cheb's Game Engine
Добавлено: 20.03.2021 16:52:03
Cheb
Начал постепенную переделку словесного поноса в журнале на активацию по типам событий вместо бывшего глобального true/false.
Затрахался с машиной состояний, буду всё сносить на и делать проще: переход на панель управления провоцируется переменной, переход обратно - только через соответствующие элементы главного меню панели управления. Ибо выделывало такие коленца, что просто рукалицо.