Умудрился вынести самому себе мозг, чуть не потярял очки SAN разбирая свой фхтагнокод 2008-го года... В конце концов пришлость снести его на и написать с нуля.

Создавать меш, рисовать и тут же уничтожать — сам понимаешь, неочень.
Для консоли уже оптимизировал, остальные места модуля - матки - не критичны, буду оптимизироватоь на стороне игрового модуля:
- Код: Выделить всё
procedure TConsole.Draw();
var
zoom: glFloat;
xmax, zms: integer;
condensed: boolean;
liT, Red, Green, Blue, Alpha: glFloat;
currentLineTop, currentYTop: integer;
//processing from bottom to top until the next line is completely off-screen
function DrawOneLine() : boolean;
var
xp, yp, x, y, c, cc, L2, y2, SubLines, tlen: integer;
ts, tt: GLfloat;
begin
if currentLineTop < 0 then Exit(false);
tlen:= Length(Self.Strings[currentLineTop]);
if (tlen > 1)
then SubLines:= 1 + ((tlen - 1 - 1) div (xmax))
else SubLines:= 1;
currentYTop -= Sublines * trunc(ConsoleCharHeight * zoom);
if (currentYTop + Sublines * ConsoleCharHeight * zoom) < 0 //completely off screen?
then Exit(false);
x:=0;
y:=0;
c:=1;
While c < tlen - 1 do begin
//draw character;
xp:= trunc(ConsoleBorders) + x * trunc(ConsoleCharWidth * zoom);
yp:= y * trunc(ConsoleCharHeight * zoom);
cc:=Ord(Self.Strings[currentLineTop][c]);
if cc >=32 then begin //ignore special characters
ts:=((cc mod 16) * ConsoleCharXstep + ConsoleCharOffsetS) / ConsoleImageWidth;
tt:=((cc div 16) * 16 + ConsoleCharOffsetT) / 256.0;
f_mesh.AddQuad2d(
Red, Green, Blue, Alpha,
xp, yp + currentYTop,
xp + (ConsoleCharWidth + 1) * zoom, yp + currentYTop + ConsoleCharHeight * zoom,
ts, tt, ts + (ConsoleCharWidth + 1) / ConsoleImageWidth, tt + ConsoleCharHeight / 256.0 );
end;
inc (c);
inc (x);
if x > xmax then begin
x:=1;
inc(y);
end;
end;
currentLineTop-= 1;
Result:= true;
end;
begin
if not Mother^.Display.CanRender then Exit;
zms:= Round((Now() - f_lasttime) * 1000.0 * SECONDS_PER_DAY );
LastHeartbeatMoment:=Now();
If not (f_vis
or (zms < (f_hidetime + f_fadetime)))
then begin
f_fadeline:= -1;
f_fade:= 1.0;
Exit;
end;
if f_vis then liT:=0
else begin
if zms < f_hidetime then liT:= - (f_hidetime - zms) / f_hidetime
else liT:=(zms - f_hidetime) / f_fadetime;
end;
if f_scrolled_back < 0 then f_scrolled_back:=0;
if not f_vis then f_scrolled_back:=0;
// f_fade:= 1.0;
Alpha:= CCLd(liT, 4) * Mother^.Display.FadeIn;
condensed:= ConsoleUseCondensedFont or (Mother^.Display.WindowClientRect.Width < f_tosquish);
if not Assigned(f_mesh)
or f_change.Yes
or (f_change.lit <> trunc(Alpha * 1000))
or (f_change.sb <> f_scrolled_back)
or (f_change.dw <> Mother^.Display.WindowClientRect.Width)
or (f_change.dh <> Mother^.Display.WindowClientRect.Height)
or (f_change.condensed <> condensed)
then begin
if Assigned(f_mesh) then begin f_mesh.Free; f_mesh:= nil end;
if Self.Count < 1 then Exit;
f_change.Yes := No;
f_change.dw := Mother^.Display.WindowClientRect.Width;
f_change.dh := Mother^.Display.WindowClientRect.Height;
f_change.sb := f_scrolled_back;
f_change.lit := trunc(Alpha * 1000);
f_change.condensed:= condensed;
Red:= CCLd(liT, 1);
Green:= CCLd(liT, 2);
Blue:= CCLd(liT, 3);
if condensed then begin
ConsoleCharWidth:= 4;
ConsoleCharXstep:= 128 div 16;
ConsoleImageWidth:= 128.0;
ConsoleCharOffsetS:= 2;
end
else begin
ConsoleCharWidth:= 9;
ConsoleCharXstep:= 256 div 16;
ConsoleImageWidth:= 256.0;
ConsoleCharOffsetS:= 4;
end;
zoom:=1.0;
if Mother^.Display.WindowClientRect.Width > f_tostretch then zoom:= 2.0;
xmax := -1 + ((Mother^.Display.WindowClientRect.Width
- trunc(2 * ConsoleBorders * zoom ) ) div trunc(zoom * ConsoleCharWidth));
currentYTop:= Mother^.Display.WindowClientRect.Height - trunc(ConsoleBorders);
currentLineTop:= max(0, Self.Count - 1 - f_scrolled_back);
if (currentLineTop < 1) and (f_scrolled_back > 0) then begin
f_scrolled_back:= max(0, f_scrolled_back - (1 - currentLineTop));
currentLineTop:= max(0, Self.Count - 1 - f_scrolled_back);
end;
f_mesh:= TBasicMesh.Create;
while DrawOneLine() do;
end;
if Assigned(f_mesh) then begin
SetGLStatesForGUI;
f_mesh.SetGLStatesForGUI;
if condensed
then glBindTexture(GL_TEXTURE_2D, f_halftexture)
else glBindTexture(GL_TEXTURE_2D, f_texture);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
f_mesh.Render;
end;
end;
, поэтому даже в FFP нет причины не использовать [Vertex/TexCoord/etc.]Pointer + DrawElements вместо цикла.
Обязательно вернусь к этому когда дойду до стадии непадающей игровой логики.
С наскока ниасилил, получил чёрный экран при молчащей glGetError()
, что у некоторых мешей какие-то атрибуты могут отсутствовать?
Это изначальный базовый для простых вещей.
Понадобится оптимизация - напложу специализированных потомков.
, соответственно, все эти Ortho etc. — функциями, её возвращающими, а не методами левого класса.
В норме да, но я делаю базу для использования старого говнокода с минимумом изменений.
На работе третий год подобным же занимаюсь, целый эмулятор Joomla! 1.5 написал.
Добавлено спустя 11 часов 30 минут 35 секунд:Всё, разобрался. Это не лыжи не едут, это я... кхм.
Когда шлёшь видяхе четырёхмерные координаты (на... кой?) - четвёртую компоненту надо заполнять единицами. А не то.
FFP зачем-то множит три первые компоненты на 1/четвёртую.
Чую, предстоит курить матрицы.
По ходу, потестирую потом производительность этой штуки. Если окажется адекватной - буду рендерить ею все места, где надо быстро подмухлевать геометрию на лету, не дожидаясь ленивого обновления. Например, ближние чанки вокруг игрока, где надо шустро по отдельности переключать грани с общего текстурного атласа чанка на индивидуальные текстуры повышенного разрешения, или дорисовывать подстраховочные оболочки за ближними стенками на случай фейла по z-near.
Напомню, производительность классического glVertex3f(x,y,z) держится на вполне приличном уровне вплоть до 20К где-то полигонов, а потом - резко падает. Наверняка ж специальный хак с буфером в юзерспейсе для поддержки старых игр.
Ещё впечатлился реализацией прозрачности в Fallout 4 (на дизеринге).
http://chebmaster.com/_share/fo4-dithering.avi (4 Мб)
Облизываюсь, примеряюсь где буду такое использовать. Она ж без блендинга вообще, и порядок сортировки не важен!
Что если смещение матрицы смещать на пол-периода каждый кадр? Тогда получится отличное темпоральное сглаживание (не говоря уже, что я планирую искривлённый вывод супер-сэмпленного рендер-буфера для получения сферической проекции, что даст дополнительно сглаживание размытием)