Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > разработка игр, графический дизайн и моделирование > Gamedev - cоздание игр: Unity, OpenGL, DirectX
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 24.01.2009, 15:41   #631
Роман Радер
Форумчанин
 
Аватар для Роман Радер
 
Регистрация: 16.12.2006
Сообщений: 859
По умолчанию

Цитата:
Сообщение от Beermonza Посмотреть сообщение
Роман Радер, игра у нас 2D-изометрия MMORPG, разрабатывается на примитивах, то что работает у всех, главное, чтобы был "OC Виндовоз".
Релизов не было и не будет до конца года, или даже неизвестно когда, как сложатся обстоятельства.
С нами уже есть все кто нужен, и мы не набираем людей, извиняй.
Если у тебя есть идеи или опыт, то пожалуйста, организовывай команду и параллельно веди проект, всегда можем помочь советом или сами спросить, ...отписывай в этой теме, будет интересно. Ничего сложного нет, есть желание, а все остальное - пыль.
нет нет, вы меня не поняли. я не прошусь в комманду. я имел в виду, что я тоже делаю программу, которая по стереотипам в делфи не делается.
Роман Радер вне форума Ответить с цитированием
Старый 24.01.2009, 16:41   #632
Beermonza
Инженер ИС
Старожил
 
Аватар для Beermonza
 
Регистрация: 13.12.2006
Сообщений: 2,671
По умолчанию

Вот как? ...я уловил смысл неправильно видимо.
Руководитель проекта MMO 2D RPG: Настоящее имя Денис Стрижак (10.05.1981-6.02.2019) Мир духу его
Beermonza вне форума Ответить с цитированием
Старый 25.01.2009, 11:36   #633
0nni
Форумчанин
 
Аватар для 0nni
 
Регистрация: 24.07.2008
Сообщений: 279
По умолчанию

Вы тут говорили про mmx почитал - все просто, вот только как для рисования спрайта его применить не пойму, одноцветный, полупрозрачный прямоугольник наложить получилось, а вот с разноцветными пикселями пока застрял.
Могете намекнуть?
Сказал и загрустил от бесспорности своей правоты.
0nni вне форума Ответить с цитированием
Старый 25.01.2009, 20:58   #634
Beermonza
Инженер ИС
Старожил
 
Аватар для Beermonza
 
Регистрация: 13.12.2006
Сообщений: 2,671
По умолчанию Подробно про работу с графикой и MMX

Это послужит своеобразным уроком, сподвигнет всех желающих искать методы самостоятельно и в других областях кроме графики, хитровымудренным примером откинув Canvas туда от куда он пришел (юмор). Комбинации и наработки предложены товарищами по программированию (вы очевидно читали предыдущие посты поиска решений), за что им спасибо. Опишу все именно в этой теме, поскольку это только моменты, к новичкам не имеющие ни какого отношения в виду достаточной сложности.

Подготовка

Рационально использовать и хранить спрайты в формате PNG, поэтому в секции uses нужно вставить библиотеку PNGImage. Будем использовать отдельно текстуру и отдельно альфаканал, содержащийся в PNG-файле.

Вот так загружаем спрайт:

Код:
PNGTex := TPNGObject.Create;
PNGTex.LoadFromFile({путь\файл.png});
Просто так с PNG работать не получится, нужно работать с последовательностью байт, т.е. с массивом. Определим размер массива по ширине (он на самом деле одномерный, но ширина - основной параметр перебора пикселей, сколько там строк по высоте в изображении не так важно), учитывая формат 24 бита, по 3 байта на пиксель изображения:

Код:
TexLine := PNGTex.Width*3; // Integer
// формирование длины (ширины) с учетом деления ее на 4
if (TexLine mod 4) <> 0 then TexLine := ((TexLine div 4)+1) * 4;
Теперь нужно подготовить массивы текстуры и маски типа PChar. Понадобится переменная типа TBitmap, в нее передадим поочереди текстуру и маску в свое время (это нужно для того чтобы простыми методами дорисовывать в них что-угодно, например текст или рисовать примитивными методами):

Код:
Buf := TBitmap.Create;
Buf.PixelFormat := pf24bit;
Buf.Width := PNGTex.Width;
Buf.Height := PNGTex.Height;
Отправим в переменную Buf текстуру из PNG-спрайта:

Код:
for i := 0 to PNGTex.Height - 1 do
  begin
     PointPNG := PNGTex.Scanline[i];
     PointBIT := Buf.ScanLine[i];
     for j := 0 to PNGTex.Width - 1 do
        begin
           PointBIT[j].B := PointPNG[j].B;
           PointBIT[j].G := PointPNG[j].G;
           PointBIT[j].R := PointPNG[j].R;
        end;
  end;
В этом коде пробегаем по спрайту, собираем указатели на строку и переписываем байты параллельно. PointPNG и PointBIT переменные особого типа ^TBGR, вот он:

Код:
type
  BGR = packed record
    B: Byte;
    G: Byte;
    R: Byte;
  end;

  TBGR = array [word] of BGR;
Теперь попытаемся взять из переменной Buf изображение и представим его одномерным массивом TexBits типа PChar:

Код:
try
  begin
    GetDIBSizes(Buf.Handle, HeaderSize, BitsSize);
    GetMem(Header, HeaderSize);
    GetMem(TexBits, BitsSize);
    GetDIB(Buf.Handle, 0, Header^, TexBits^);
  end;
finally
  FreeMem(Header);
end;
Здесь HeaderSize и BitsSize типа Cardinal, Header типа Pointer.
Теперь перезапишем переменную Buf для маски:

Код:
Buf := TBitmap.Create;
Buf.PixelFormat := pf24bit;
Buf.Width := PNGTex.Width;
Buf.Height := PNGTex.Height;
Перепишем в Buf маску, учитывая, что она уже 8 бит форматом:

Код:
for i := 0 to PNGTex.Height - 1 do
  begin
    Alpha := PNGTex.AlphaScanline[i];
    PointBIT := Buf.ScanLine[i];
    for j := 0 to PNGTex.Width - 1 do
      begin
         PointBIT[j].B := Alpha[j];
         PointBIT[j].G := Alpha[j];
         PointBIT[j].R := Alpha[j];
      end;
  end;
Тут переменная Alpha типа PByteArray. Попытаемся взять из переменной Buf маску и представить ее одномерным массивом MaskBits типа PChar:

Код:
try
  begin
    GetDIBSizes(Buf.Handle, HeaderSize, BitsSize);
    GetMem(Header, HeaderSize);
    GetMem(MaskBits, BitsSize);
    GetDIB(Buf.Handle, 0, Header^, MaskBits^);
  end;
finally
  FreeMem(Header);
end;
Итак, у нас есть два массива, оба они формата 24 бита, и маска тоже преобразована по 3 байта на пиксел, это нужно для применения эффектов прозрачности притом на какой-угодно выбранный цвет альфа-канала. Второе преимущество - берем параллельно с массивов данные и обрабатываем без ухищрений.

Несколько слов о том, на чем рисуем. Это буфер, он скрыт от пользователя, в нем рисуется изображение кадра и потом передается на буфер экрана, который выводится с нужной периодичностью. Как создаются буферы, вы уже наверное знаете из предыдущих постов, ...через команду CreateDIBSection.
Руководитель проекта MMO 2D RPG: Настоящее имя Денис Стрижак (10.05.1981-6.02.2019) Мир духу его
Beermonza вне форума Ответить с цитированием
Старый 25.01.2009, 20:59   #635
Beermonza
Инженер ИС
Старожил
 
Аватар для Beermonza
 
Регистрация: 13.12.2006
Сообщений: 2,671
По умолчанию Подробно про работу с графикой и MMX Часть 2

Отрисовка

Приведу простой пример отрисовки спрайта в буфер кадра, без обрезки, если не проводить ее и не контролировать положение на экране, как и положено вылетит ошибка, и будет вылетать с частотой смены кадров, поэтому по-началу все отправляется в структуру try..except..end, потом ее нужно убрать, когда будет полная гарантия, что код всегда будет работать корректно. Вот пример:

Код:
// Подготовка строковых массивов типа PChar
TexPoint := TexBits + (SH-1) * TexLine;
MapPoint := MaskBits + (SH-1) * TexLine;
FrameBufPoint := FrameBufScr + (H-1-Y) * FrameBufLine + X * 3;
// SH - высота спрайта, H - высота буфера кадра, X и Y - координаты начального пиксела спрайта в буфере кадра.

asm // подготовка маски
  pxor      xmm7, xmm7     // обнуление регистра
  movq      xmm3, C1       // загрузка маски в регистр 
// C1 - константа int64 = $FFFFFFFFFFFFFFFF
  PUNPCKLBW xmm3, xmm7
end;

for t:=0 to SH-1 do
  begin
     TexPixel := PRGB(TexPoint);
     MaskPixel := PRGB(MaskPoint);
     FrameBufPixel := PRGB(FrameBufPoint);
     C := (SW*3 div 8);  // SW - ширина спрайта
     if C <= 0 then break;

     asm
        push edi
        push esi
        push edx
        push ecx

        mov ecx, C
        mov esi, [TexPixel]
        mov edi, [MaskPixel]
        mov edx, [FrameBufPixel]

      @@1:
        cmp dword ptr [edi], 0
        jne @@mix
        cmp dword ptr [edi+4], 0
        je  @@Next

      @@mix:
        movq      xmm0, [esi]     // tex
        PUNPCKLBW xmm0, xmm7

        movq      xmm1, [edx]     // buf
        PUNPCKLBW xmm1, xmm7
        psubw     xmm0, xmm1      // tex-buf

        movq      xmm2, [edi]     // mask
        PUNPCKLBW xmm2, xmm7

        pmullw    xmm0, xmm2      // (tex-buf)*mask

        psrlw     xmm0, 8         // shr 8
// полная формула смешивания buf = buf + (tex - buf)*mask shr 8
        paddw     xmm1, xmm0      // buf + (tex-buf)*mask shr 8

        pand      xmm1, xmm3
        packuswb  xmm1, xmm1

        movq      [edx], xmm1

      @@next:
        add esi, 8
        add edx, 8
        add edi, 8
        loop @@1

        pop ecx
        pop edx
        pop esi
        pop edi
      end;

    TexPoint := TexPoint - TexLine;
    MaskPoint := MaskPoint - TexLine;
    FrameBufPoint := FrameBufPoint - FrameBufLine;
  end;

asm
   emms
end;
TexPixel, MaskPixel и FrameBufPixel особого типа PRGB, вот он:

Код:
type
  TRGB = packed record
    R: Byte;
    B: Byte;
    G: Byte;
  end;

  PRGB = ^TRGB;
Вот вроде бы и все, ...пришлось несколько упростить, возможно будут вопросы, кому надо тот разберется, кому нужно готовое - извиняйте, такого не держим
Руководитель проекта MMO 2D RPG: Настоящее имя Денис Стрижак (10.05.1981-6.02.2019) Мир духу его

Последний раз редактировалось Beermonza; 25.01.2009 в 21:09.
Beermonza вне форума Ответить с цитированием
Старый 27.01.2009, 14:55   #636
0nni
Форумчанин
 
Аватар для 0nni
 
Регистрация: 24.07.2008
Сообщений: 279
По умолчанию

Ага, попробую понять (я пока на сессии и работаю чисто с теорией).
Метод смешивания, как я и понял целочисленный, который приводился в ранних постах, так вот он не идеален - при попытке создания эффекта размытия (заливал экран прозрачным цветом), я получил плохо различимые следы от объектов, хотя для вывода спрайтов метод действительно наилучший.
Сказал и загрустил от бесспорности своей правоты.

Последний раз редактировалось 0nni; 27.01.2009 в 14:59.
0nni вне форума Ответить с цитированием
Старый 27.01.2009, 15:28   #637
Beermonza
Инженер ИС
Старожил
 
Аватар для Beermonza
 
Регистрация: 13.12.2006
Сообщений: 2,671
По умолчанию

Да, именно, метод заточен на скорость вывода спрайтов, ...при этом предполагается, что все эффекты с анимацией уже проделаны заранее (обработка исходной анимации и сохранение в параллельные массивы), после чего результаты используются так же как и исходная анимация. Я вообще не вижу смысла проделывать одно и тоже кадр за кадром, если можно выполнить обработку всей текущей анимации в мгновение и использовать как стандарт до определенного игрового момента.
Руководитель проекта MMO 2D RPG: Настоящее имя Денис Стрижак (10.05.1981-6.02.2019) Мир духу его
Beermonza вне форума Ответить с цитированием
Старый 09.02.2009, 18:11   #638
Beermonza
Инженер ИС
Старожил
 
Аватар для Beermonza
 
Регистрация: 13.12.2006
Сообщений: 2,671
По умолчанию

Кто знает, SetDIBitsToDevice() в реале быстрее отправит граф. данные на форму чем BitBlt()? ...тесты что-то не показывают разницы, на моем компе одинаковая скорость.
Руководитель проекта MMO 2D RPG: Настоящее имя Денис Стрижак (10.05.1981-6.02.2019) Мир духу его
Beermonza вне форума Ответить с цитированием
Старый 09.02.2009, 20:17   #639
0nni
Форумчанин
 
Аватар для 0nni
 
Регистрация: 24.07.2008
Сообщений: 279
По умолчанию

Есть же стандартные способы замера
Код:
iTick := gettickcount;
for i := 0 to $ffff {или чего пострашнее} do
begin
  <твоя функция>
end
ShowMessage(IntToStr(gettickcount - iTick)
Сказал и загрустил от бесспорности своей правоты.
0nni вне форума Ответить с цитированием
Старый 09.02.2009, 20:58   #640
Beermonza
Инженер ИС
Старожил
 
Аватар для Beermonza
 
Регистрация: 13.12.2006
Сообщений: 2,671
По умолчанию

У меня по FPS отмеряет, результат один и тот же, и по загрузке CPU аналогично, и есть подозрение что различия будут на компах послабее. Ладно, попробую "чего по страшнее" ).
Руководитель проекта MMO 2D RPG: Настоящее имя Денис Стрижак (10.05.1981-6.02.2019) Мир духу его
Beermonza вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Уроки по созданию игр для новичков... -=DeS=- Gamedev - cоздание игр: Unity, OpenGL, DirectX 750 14.11.2017 20:26
Музыка программистов - как вы относитесь к АРИИ? Весёлый Жека Свободное общение 46 10.10.2008 22:32
Конкурсы по созданию игр на Delphi mutabor Свободное общение 0 15.06.2007 12:40
Работа по созданию ПО remix Фриланс 3 22.04.2007 11:00