Суббота, 20 Сентября 2025, 23:00

Приветствую Вас Гость

[ Новые сообщения · Игроделы · Правила · Поиск ]
  • Страница 1 из 12
  • 1
  • 2
  • 3
  • 11
  • 12
  • »
Результаты поиска
AlkoshaДата: Вторник, 17 Декабря 2013, 10:34 | Сообщение # 1 | Тема: Оптимизация рейкастинга
участник
Сейчас нет на сайте
Шалом...
Попробовал скомпилить этот сорс.
http://lodev.org/cgtutor/raycasting2.html#Howitworks

На фуллскриновом разрешении 640*480 выдаёт 60 кадров в секунду, и это на 2.2 Гигагерцах. Понизил частоту проца до 800 мегагерц ~15 кадров в секунду (иногда и 10). Запустил на пентиуме MMX - 1 кадр в секунду(!). И это при том, что графика-то на уровне вульфа3д, и это без воспроизведения звуков, просчёта AI, дверей, та и размер карты явно меньше.
Тогда как рейкастинговые игры с нормальным алгоритмом для пня - раз плюнуть, на разрешениях 800*600.

Конкретно в данном примере используется SDL, в дополнительном cpp-файле (quickcg.cpp) реализован оптимизированный вывод пикселей на экран, как я понял (ну и заодно рисование графических примитивов, которые в конкретно этом примере не юзаются).
Как можно оптимизировать сам процесс выборки лучей ? Понизить точность просчёта во благо производительности.

Добавлено (17.12.2013, 10:34)
---------------------------------------------
Хм... Ещё одна особенность, на той версии SDL, что предоставлялась с исходником , фреймрейт вдвое шустрее , нежели на той, с которой компилировал я.
У меня версия SDL 2.0.1, кажись.
Но всё равно слишком маленький fps, как для сотен мегагерц.

Там когда вплотную к "стене" прижимаешься, шибко гладкая перспектива. Может из-за этого так медленно рисует ? То что просчитывает столбцы, кратные одному пикселю?


Сообщение отредактировал Alkosha - Вторник, 17 Декабря 2013, 12:45
AlkoshaДата: Вторник, 17 Декабря 2013, 12:02 | Сообщение # 2 | Тема: Оптимизация рейкастинга
участник
Сейчас нет на сайте
Цитата Xakep ()
рекаст делается для рендера, т.е. из каждого пикселя пускается луч, или просто пара лучей от самого игрока или еще какого объекта?


Для рендера слишком жирно.
По-моему, тут всё же предоставлен пример того, как реализован рейкаст в вульфе3д, то есть по столбцам. Из "глаз" игрока пускаются два луча, ну и в соответствии с этим вертикально масштабируется определённый столбец при "столкновении" луча со стеной (+прорисовка пола и потолка)

Цитата Xakep ()
можно разбить уровень на бинарное дерево


это рационально делать для масштабных локаций. Массив карты не шибко-то и большой. Тем более низкий fps даже если в упор на стенку смотреть, а не только вдаль.

Цитата Xakep ()
обычно такой рекаст делают для пред расчета освещенности сцены и запекания ее потом в lightmap

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

Цитата Xakep ()
Еще вариант, перенести все расчеты на GPU через шейдеры или OpenCL/CUDA.


Не вариант. Только CPU... Если уж и задействовать GPU, то всё вышеописанное можно и на openGL осуществить, полигональной графикой.

Добавлено (17.12.2013, 12:02)
---------------------------------------------
Цитата Xakep ()
ну и на самом сайте много чего интересного можно найти (http://ray-tracing.ru/)

Всё же рей-трейсинг и рей-кастинг - несколько разные вещи.
Хоть и там и там происходит просчёт столкновения луча. Рейкастинг ориентирован на лучи фронтальной перспективы.
Рейтрейсинг же определяет столкновения лучей света с поверхностью трёхмерной модели.


Сообщение отредактировал Alkosha - Пятница, 27 Декабря 2013, 10:38
AlkoshaДата: Вторник, 17 Декабря 2013, 13:07 | Сообщение # 3 | Тема: Оптимизация рейкастинга
участник
Сейчас нет на сайте
Цитата Xakep ()
а разбиение на дерево как раз отсекает не нужные части сцены.

Мне казалось с этим как раз рейкаст и справляется. Ведь луч идёт от игрока к первому встречному объекту, то есть всё что за видимым объектом - автоматически отбрасывается. Ну это при визуализации , разумеется.

Добавлено (17.12.2013, 13:04)
---------------------------------------------

Цитата Xakep ()
то что у тебя так тормозит вряд ли из-за рейкастига.


Наверное процедурки quickCG.cpp на самом деле не такие уж и быстрые.
Потом на досуге проверю с какой скоростью рисуется попиксельно.

Добавлено (17.12.2013, 13:07)
---------------------------------------------
В вульфенштайне были ассемблерные подпрограммы для вывода пикселя на экран, только это с расчётом того, что прога будет работать на i80286-ом проце.
Мне б хотя бы для 166-ти мегагерцового пентиума оптимизировать.

AlkoshaДата: Среда, 18 Декабря 2013, 12:06 | Сообщение # 4 | Тема: Оптимизация рейкастинга
участник
Сейчас нет на сайте
evil непонятная шляпка получается.
Скачал и скомпилировал под ту же версию SDL (1.2.9) что и прилагалась к исходнику, с таким же самым разрешением, и всё той же quickCG.cpp , всё то же самое. Тупо скопипастил.
Тот билд, что на исходнике работает ровно вдвое быстрее, чем тот что скомпилирован у меня.(конечно на 800 мегагерцах 30 кадров в секунду - ужасный показатель для этого примера, но всё же.)
Создавал проект в кодблоксе по шаблону SDL Project (тот что прилагается к примеру тоже был скомпилирован в кодблоксе).
Может ли быть это от того, что линкер ненужные либы подключает ?

Добавлено (18.12.2013, 12:06)
---------------------------------------------
И не сказать, что пиксели рисуются медленно.
Всё с того же сайта скомпилировал пример без текстурирования стен (пол и потолок отсутствуют соответственно) - на 2.2 гигагерцах зашкаливает за 100 кадров в секунду (фреймрейт зависит от уровня закраски, немного понижается, когда вплотную к "стене" подойти, но не ниже 100 кадров всё равно).


Сообщение отредактировал Alkosha - Среда, 18 Декабря 2013, 13:24
AlkoshaДата: Среда, 18 Декабря 2013, 15:11 | Сообщение # 5 | Тема: Оптимизация рейкастинга
участник
Сейчас нет на сайте
Цитата Xakep ()
с включенными опциями оптимизации (-Ofast или -O3 -ffast-math)

Можно поподробнее?
Где именно эти самые опции включаются ?

Я выставил (в settings->compiler & debugger->toolchain executables)
Цитата
с compiler: gcc.exe
c++ compiler: g++.exe
linker for dynamic libs: g++.exe


и всё остальное оставил по дефолту

Цитата
linker for static libs: ar.exe
debugger: gdb.exe
recource compiler: windres.exe
Make programm: mingw32-make.exe


а куда прописывать этот "-Ofast" ?


Сообщение отредактировал Alkosha - Среда, 18 Декабря 2013, 15:13
AlkoshaДата: Среда, 18 Декабря 2013, 21:16 | Сообщение # 6 | Тема: Оптимизация рейкастинга
участник
Сейчас нет на сайте
Цитата SEvg ()

В Кодеблокс Project->Build options->Compiler flags


Данкешон.
Все флаги категории optimize включил - и эзешник стал легче (500 кб , а был почти два метра), и фреймрейт стал такой же, как и в примере...
Но всё равно , 25 кадров для 800 мегагерц - маловата будит!
Такой фреймрейт удовлетворителен разве что для 7-ми мегагерцовой MС68000.
AlkoshaДата: Четверг, 19 Декабря 2013, 18:15 | Сообщение # 7 | Тема: Оптимизация рейкастинга
участник
Сейчас нет на сайте
Слишком много вычислений в теле цикла... В частности умножения...
На каждый пиксель "стен"
Код
int d = y * 256 - h * 128 + lineHeight * 128; //256 and 128 factors to avoid floats
          int texY = ((d * texHeight) / lineHeight) / 256;
          int color = texture[texNum][texWidth * texY + texX];
          //make color darker for y-sides: R, G and B byte each divided through two with a "shift" and an "and"
          if(side == 1) color = (color >> 1) & 8355711;
          buffer[x][y] = color;


На каждый пиксель потолка(потолка) приходится такое:
Код
currentDist = h / (2.0 * y - h); //you could make a small lookup table for this instead

   double weight = (currentDist - distPlayer) / (distWall - distPlayer);

   double currentFloorX = weight * floorXWall + (1.0 - weight) * posX;
   double currentFloorY = weight * floorYWall + (1.0 - weight) * posY;

   int floorTexX, floorTexY;
   floorTexX = int(currentFloorX * texWidth) % texWidth;
   floorTexY = int(currentFloorY * texHeight) % texHeight;

   //floor
   buffer[x][y] = (texture[3][texWidth * floorTexY + floorTexX] >> 1) & 8355711;
   //ceiling (symmetrical!)
   buffer[x][h - y] = texture[6][texWidth * floorTexY + floorTexX];



Сообщение отредактировал Alkosha - Четверг, 19 Декабря 2013, 18:15
AlkoshaДата: Среда, 25 Декабря 2013, 23:34 | Сообщение # 8 | Тема: Оптимизация рейкастинга
участник
Сейчас нет на сайте
Вот только для какой переменной подходит операция побитного сдвига.

Код
    int d1=lineHeight * 128;
       int d2=h * 128;
       for(int y = drawStart; y < drawEnd; y++)
       {
        int d = y *256 - d2 + d1;  //256 and 128 factors to avoid floats
        int texY = ((d * texHeight) / lineHeight) >>8;
         Uint32 color =texture[texNum][texWidth * texY + texX];
         if(side == 1) color = (color >> 1) & 8355711;
         buffer[x][y] = color;
             }


То бишь только для texY
если скроллировать переменную "y" - там шляпа с текстурами ваще конкретная. Что странно, ибо "y" интовый, то есть не дробное число.
И переменные "d1" и "d2" должны быть отдельно. Если до тела цикла записать так:

Код
d1 = lineHeight * 128 + h * 128


То получается, говоря заумным языком геймдевелопера, текстурная шляпенция.

Добавлено (25.12.2013, 23:34)
---------------------------------------------
Подумываю на асме выполнять вычисления... Но я ни разу не пробовал использовать ассемблерные вставки. Более того, не знаю как затем результат вычисления поместить из регистров в переменные.

AlkoshaДата: Четверг, 26 Декабря 2013, 13:02 | Сообщение # 9 | Тема: Оптимизация рейкастинга
участник
Сейчас нет на сайте
если переходить на openGL , то и рейкастинг как таковой не нужен (за исключением игровых моментов, типа просчёта выстрелов или коллизии с объектами).
Я хочу , чтоб моя прога работала на пентиуме MMX , без 3д акселераторов. Только ЦП и ничего лишнего.


Сообщение отредактировал Alkosha - Пятница, 27 Декабря 2013, 10:37
AlkoshaДата: Четверг, 26 Декабря 2013, 15:31 | Сообщение # 10 | Тема: Оптимизация рейкастинга
участник
Сейчас нет на сайте
Как бы полностью от всех дробей и умножений избавиться?
Там, где числа кратные 2 в определённой степени , то понятно... А вот в таких ситуациях скроллом никак не получится ?

Добавлено (26.12.2013, 15:31)
---------------------------------------------
Очень много времени занимает чтение\запись ОЗУ... Нужно данные как-то задержать в кэше.

Сообщение отредактировал Alkosha - Четверг, 26 Декабря 2013, 15:19
AlkoshaДата: Пятница, 27 Декабря 2013, 12:31 | Сообщение # 11 | Тема: Оптимизация рейкастинга
участник
Сейчас нет на сайте
Ну тут очевидно, что самые затратные участки там, где происходит выборка пикселей из текстур (пола\потолка\спрайтов). Со сплошным закрашиванием этот рейкастинг достаточно шустрый.

Добавлено (27.12.2013, 12:31)
---------------------------------------------
Ага. У операции сдвига приоритет меньше , чем у сложения и вычитания. Вот от чего была "текстурная шляпа". Нужно было просто в скобки заключить.

Код
  int d = (y <<8) - d2 + d1;
AlkoshaДата: Четверг, 02 Января 2014, 23:35 | Сообщение # 12 | Тема: Оптимизация рейкастинга
участник
Сейчас нет на сайте
Дело оказывается не в рейкастинге.
Сама SDL медленно выводит пиксели.
Нужно непосредственно записывать в видео-озу vga-контроллера. Похоже придётся прибегнуть к асму, либо искать альтернативу SDL'ке для попиксельного вывода.
AlkoshaДата: Пятница, 03 Января 2014, 00:59 | Сообщение # 13 | Тема: Оптимизация рейкастинга
участник
Сейчас нет на сайте
Цитата OpenGOO ()
Ты что-то не то делаешь


Даже элементарное заполнение пикселями на 166-ти мегагерцовом пентиуме MMX выдаёт 5 кадров в секунду на разрешении 800*600 (32 бита)
(процедура вывода пикселя для заполнения взята отсюда http://plg.lrn.ru/doc/sdl/lesson1.html)

Что на SW-сюрфейсе , что на HW-сюрфейсе мэдлэнно.


Сообщение отредактировал Alkosha - Пятница, 03 Января 2014, 01:00
AlkoshaДата: Суббота, 04 Января 2014, 11:43 | Сообщение # 14 | Тема: Оптимизация рейкастинга
участник
Сейчас нет на сайте
Цитата OpenGOO ()
У тебя просто проц уже не справляется, уменьши разрешение хотя бы. У тебя какая хоть видюха, а то даже Descent 3 в 1999г. уже использовал аппаратное ускорение.


Всё проц справляется.

На софтверном рендеринге Descent 1 и Descent 2 на разрешениях 640*480 летают. А там, как всем известно, даже полигональное 3д.
Рейкастинги тем более он шпарит только так. Порт дюка eduke32 на разрешении 800*600 тоже работает идеально (чуток проседает правда, когда много wav-семплов воспроизводит, но если понизить воспроизведение сэмплов до 22 килогерц, то всё ровненько идёт)
Порт дума Doom95 тоже идеально работает на разрешении 640*480. И даже сравнить тот же дум, где разная высота стен, векторное построение карт, куча спрайтов, ИИ, воспроизведение звуковых сэмплов, и тот пример, который я разбираю.

Добавлено (04.01.2014, 11:43)
---------------------------------------------
Даже полигональное 3дэ для того проца раз плюнуть, если не используется коррекция перспективы при текстурировании.
NFS 1 (NFS SE), и подобные гоночки, например.


Сообщение отредактировал Alkosha - Суббота, 04 Января 2014, 11:44
AlkoshaДата: Суббота, 04 Января 2014, 16:08 | Сообщение # 15 | Тема: Оптимизация рейкастинга
участник
Сейчас нет на сайте
Цитата Alkosha ()
Судя по описанию eduke32 использует OpenGL Doom95 использует DirectX.


Там есть опциональный выбор рендеринга. На openGL вообще не прёт, ибо видяха не тянет это API. (видяшка ATI Rage II)
и при выборе софтверного рендеринга в eduke, там именно рейкастинговый графон, а не спрайтово-полигональное 3д, как если бы было на openGL.
А на DX видяха вообще адски медленно рисует. Есть несколько игор с выбором D3D рендерера и софтверного.
На D3D значительно тормознее, тот же MDK, или motorace. Хоть она фильтрует текстуры, производит коррекцию перспективы, тонирование Гуро дизерингом. Но по скорости уступает тому, что рисует непосредственно проц, поэтому всегда выбираю именно software render.

Кстати установленная ОСь win98 SE. Где всё ещё была поддержка ДОС-программ.
Или вы хотите сказать, что DOS эмулируется , и картинку выводит исключительно DX ?


Сообщение отредактировал Alkosha - Суббота, 04 Января 2014, 16:11
AlkoshaДата: Суббота, 04 Января 2014, 22:45 | Сообщение # 16 | Тема: Оптимизация рейкастинга
участник
Сейчас нет на сайте
Цитата OpenGOO ()
ДОС эмитируется когда она запускается в окне. чтобы был чистый ДОС надо выгрузить винду.


Но запускаю-то я в фуллскрине. Тем паче, я даже при выгруженной винде (перезагрузка в режиме MS-DOS) запускал те же самые descent'ы , и квейк , и nfs... Разница лишь в том, что в этом режиме не грузятся дрова на мышу, потому в квейке , например, только клавой можно управлять. А fps примерно такой же.

Цитата OpenGOO ()
Кстати, в движках Duke Nukem 3D и Doom не использовался рейкастинг.

О_о
Эммм... Вы наверное спутали с третьим думом и с дюком нюкемом форэва.

В дюке нюкеме 3д есть возможность вертеть камеру вверх/вниз, и там нет сдвига перспективы по вертикали, то есть нет точки схода по оси Y, ровно так же, как нет её hertic'e , hexen'e, или воксельном, но в то же время рейкастинговом comanche. Или rise of triad, в котором движок основан вообще на wolf3d.
И ещё одна отличительная черта рейкастинговых движков - нет этажа над этажом. уровни двухмерные при виде сверху в любом случае.

Добавлено (04.01.2014, 22:45)
---------------------------------------------
Цитата OpenGOO ()
есть ZDoom.

Промелькала такая мысля. Но будет ли там возможность всё сделать на свой лад? То есть не очередной клон дума, а полностью видоизменить от и до.
ZDoom этож вроде типа готового конструктора (а-ля, гей-мейкеры всякие)


Сообщение отредактировал Alkosha - Суббота, 04 Января 2014, 22:52
AlkoshaДата: Понедельник, 06 Января 2014, 03:58 | Сообщение # 17 | Тема: Графика консольная (Спрайты)
участник
Сейчас нет на сайте
ASCII-арт != спрайты

Тут скорее всего придётся самому писать прогу, для замены пикселя символом.
Я видел лишь единственный пример на openGL, где отрендеренная картинка конвертировалась в символы посредством шейдеров glsl


Сообщение отредактировал Alkosha - Понедельник, 06 Января 2014, 13:26
AlkoshaДата: Среда, 08 Января 2014, 20:08 | Сообщение # 18 | Тема: Оптимизация рейкастинга
участник
Сейчас нет на сайте
Вы сперва определитесь с понятием "3д". Зачастую анаглифное кино тоже называют ТРИ ДЭ.

таки да, первый дум можно отнести к три дэ, имхо. Так как у спрайтов там как минимум три параметра положения в пространстве, как и в дюке нюкеме ТРИ ДЭ.
Но это не полигональное три дэ, а рейкастинг однозначно. Для скептиков есть чит IDCLIP , при прохождении за пределы стен замечательно видно, что рендерится картинка столбцами, как и положено рейкастингу.

Но как бы там ни было, итоговая картинка всё равно проецируется на двухмерную плоскость, то бишь дисплей юзера.
AlkoshaДата: Пятница, 21 Февраля 2014, 20:28 | Сообщение # 19 | Тема: помогите перевести исходник под иррлихт... пожалуйста...
участник
Сейчас нет на сайте
есть исходник 2д платформера под библиотеку SFML.
Хочу этот самый алгоритм заюзать, только под управлением движка irrlicht.
В первую очередь компилятор ругался на переменную типа String.
ни #include "windows.h" ни #include <string.h> не помогло, потому я заменил String на char*

Далее переменную типа FloatRect объявил так: rect<s32> rectan присвоил ей значение следующим образом: rectan=rect<s32>(7*32,9*32,40,50);

сейчас ругается на строчку rectan.left += dx * time; ,

E:\TURBO\platform\main.cpp|75|error: 'class irr::core::rect<int>' has no member named 'left'|

но ведь структуре rect<s32> присутствует поле left

AlkoshaДата: Пятница, 21 Февраля 2014, 21:07 | Сообщение # 20 | Тема: помогите перевести исходник под иррлихт... пожалуйста...
участник
Сейчас нет на сайте
Код

#include <irrlicht.h>
#include <math.h>

#define MAX_FPS 100
#define IDLE_TIME  (1000 / MAX_FPS)

using namespace irr;

using namespace core;
using namespace scene;
using namespace video;
using namespace io;
using namespace gui;

#ifdef _IRR_WINDOWS_
#pragma comment(lib, "Irrlicht.lib")
#pragma comment(linker, "/subsystem:windows /ENTRY:mainCRTStartup")
#endif
f32 col[4];
IVideoDriver* driver;

int resw=800;// разрешение ёпта
int resh=600;

float offsetX=0, offsetY=0;

const int H = 12;
const int W = 40;

char* TileMap[H] = {

"BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB",
"B                    B     B",
"B                    B     B",
"B                    B     B",
"B                    B     B",
"B         0000                BBBB     B",
"B                    B     B",
"BBB                    B     B",
"B              BB                BB    B",
"B              BB                      B",
"B    B         BB         BB           B",
"BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB",

};

class PLAYER {

public:

float dx,dy;
rect<s32> rectan;
bool onGround;

float currentFrame;

     PLAYER()
    {
//    sprite.setTexture(image);
  rectan=rect<s32>(7*32,9*32,40,50);

  dx=dy=0.1;
  currentFrame = 0;
    }

    void update(float time)
    {

   rectan.left += dx * time;
   Collision(0);

   if (!onGround) dy=dy+0.0005*time;
   rect.top += dy*time;
   onGround=false;
      Collision(1);

    currentFrame += 0.005*time;
    if (currentFrame > 6) currentFrame -=6 ;

    if (dx>0) sprite.setTextureRect(IntRect(40*int(currentFrame),244,40,50));
    if (dx<0) sprite.setTextureRect(IntRect(40*int(currentFrame)+40,244,-40,50));

    sprite.setPosition(rect.left - offsetX, rect.top - offsetY);

    dx=0;
    }

    void Collision(int dir)
    {
      for (int i = rect.top/32 ; i<(rect.top+rect.height)/32; i++)
    for (int j = rect.left/32; j<(rect.left+rect.width)/32; j++)
   {
      if (TileMap[i][j]=='B')
      {
          if ((dx>0) && (dir==0)) rect.left =  j*32 -  rect.width;
       if ((dx<0) && (dir==0)) rect.left =  j*32 + 32;
    if ((dy>0) && (dir==1))  { rect.top =   i*32 -  rect.height;  dy=0;   onGround=true; }
    if ((dy<0) && (dir==1))  { rect.top = i*32 + 32;   dy=0;}
      }

    if (TileMap[i][j]=='0')
                      {
                     TileMap[i][j]=' ';
                      }

      }

    }
};

bool jumpf=false;

const int bitmapy=10,bitmapx=20;
//char bitmap[bitmapy][bitmapx];

char bitmap[bitmapy][bitmapx]= {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
                    0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,
                    0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,1,1,
                    1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,1,1,1,
                    1,1,1,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,
                    1,1,1,1,0,0,0,0,0,1,1,1,1,1,1,0,0,0,0,1,
                    1,1,1,1,1,0,0,0,1,1,1,0,0,0,0,0,0,1,1,1,
                    1,1,1,1,1,1,0,1,1,1,1,1,0,0,0,0,1,1,1,1,
                    1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,1,1,1,1,
                    1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1};

s32 newMaterialType = 0;
class MyShaderCallBack : public IShaderConstantSetCallBack
{
public:

    virtual void OnSetConstants(IMaterialRendererServices* services,
          s32 userData)
    {
        // Передаём индекс(номер текстуры), в пиксельный(фрагментный шейдер)
     s32 TextureLayerID = 0;
        services->setPixelShaderConstant("myTexture", reinterpret_cast<f32*>(&TextureLayerID), 1);

         // Передаём во фрагментный шейдер нужный цвет

             services->setPixelShaderConstant("myColor", col, 4);

    }
    virtual void OnSetMaterial (const SMaterial &material)
    {
         Color = SColorf(material.AmbientColor);
    }
private:
     SColorf Color;
};

void createmat()
{

    io::path vsFileName; // filename for the vertex shader
    io::path psFileName; // filename for the pixel shader
    psFileName = "shdr/frag.glsl";
    vsFileName = "shdr/vert.glsl";

     // Создание нового шейдерного материала
    IGPUProgrammingServices* gpu = driver->getGPUProgrammingServices();

       MyShaderCallBack* mc = new MyShaderCallBack();

       newMaterialType = gpu->addHighLevelShaderMaterialFromFiles(
             vsFileName, "vertexMain", EVST_VS_1_1,
             psFileName, "pixelMain", EPST_PS_1_1,
             mc,EMT_TRANSPARENT_ALPHA_CHANNEL);
}

class MyEventReceiver : public IEventReceiver
{
public:
         // наш собственный обработчик событий
         virtual bool OnEvent(const SEvent& event)
         {
                 // просто запоминаем состояние любой клавиши - нажата/отжата
                 if (event.EventType == EET_KEY_INPUT_EVENT)
                         KeyIsDown[event.KeyInput.Key] = event.KeyInput.PressedDown;

                 return false;
         }

         // метод возвращающий состояние для запрошенной клавиши
         virtual bool IsKeyDown(EKEY_CODE keyCode) const
         {
                 return KeyIsDown[keyCode];
         }

         //конструктор, в цикле сбрасываем статус для всех клавиш
         MyEventReceiver()
         {
                 for (u32 i=0; i<KEY_KEY_CODES_COUNT; ++i)
                         KeyIsDown[i] = false;
         }

private:
         // массив для хранения статусов клавиш
         bool KeyIsDown[KEY_KEY_CODES_COUNT];
};

  MyEventReceiver receiver;

ICameraSceneNode* cam;
  IrrlichtDevice *device;
ISceneManager* smgr;

  ISceneNode* back;
  ISceneNode* pers;
  ISceneNode* fognod=0;
  ISceneNode* nebo;

ISceneNode* kub;

  ILightSceneNode* light;
IAnimatedMesh* mesh ;
ISceneNode* node = 0;

int maintimer = 0;

bool go=false;
int frametime;
bool rainflag = true;
  IParticleSystemSceneNode* ps;

  IBillboardSceneNode * bill1;
f32 fdt;

void move();
void movepers(int dir);
void water();
void addfog();
void setpar(vector3df pos,vector3df scal,char * mat);
void init();
void jump();

class MYgg
{

public:
float x,y;
ITexture * tex[10];

void movepers(int dir){
if(dir==1)
{
     x+=0.1;
     pers->setMaterialFlag( EMF_FRONT_FACE_CULLING, false);
pers->setMaterialFlag( EMF_BACK_FACE_CULLING, true);
}
if(dir==0.1)
{
     x-=1;
pers->setMaterialFlag( EMF_FRONT_FACE_CULLING, true);
pers->setMaterialFlag( EMF_BACK_FACE_CULLING, false);
}
pers->setPosition(vector3df(x*2600,y*2600,495));
light ->setPosition(vector3df(x,100,-400));
frametime+=1000*fdt;

if(frametime>00&&frametime<=100)pers->setMaterialTexture(0, tex[1]);//Эту шляпу
if(frametime>100&&frametime<=200)pers->setMaterialTexture(0, tex[2]);//можно было
if(frametime>200&&frametime<=300)pers->setMaterialTexture(0, tex[3]);//циклом зафигачить
if(frametime>300&&frametime<=400)pers->setMaterialTexture(0, tex[4]);
if(frametime>400&&frametime<=500)pers->setMaterialTexture(0, tex[5]);
if(frametime>500&&frametime<=600)pers->setMaterialTexture(0, tex[6]);
if(frametime>600&&frametime<=700)pers->setMaterialTexture(0, tex[7]);
if(frametime>700&&frametime<=800)pers->setMaterialTexture(0, tex[8]);

if(frametime>800)frametime=0;
go=true;
}

};
MYgg gg;

class MYcamera
{
public:
float posx;
float posz;
float posy;

};

MYcamera camera;

bool flrf;
class MYphys{

public : void collis(){

for(int i=gg.y-2;i<gg.y+2;i++)
{
     for(int j=gg.x-2;j<gg.x+2;j++)
     {
         if(i>=0 && i<=bitmapy && j>=0 && j<=bitmapx)
         {
             if(bitmap[i][j]==1 && i>0)flrf=true;
         }

     }
}

/*
for(int i=0;i<bitmapy;i++)
{
     for(int j=0;j<bitmapx;j++)
     {
          if(bitmap[i][j]== 1&&bitmap[i-1][j]== 1)
        {
            if(gg.x>=j*500+241&&gg.x<=j*500+480&&gg.y>=-i*500&&gg.y<=-i*500+480){
            gg.x+=80;
            pers->setPosition(vector3df(gg.x,gg.y,500));
            }
             if(gg.x>=j*500&&gg.x<=j*500+240&&gg.y>=-i*500&&gg.y<=-i*500+480){
            gg.x-=80;
            pers->setPosition(vector3df(gg.x,gg.y,500));
            }
        }

      if(bitmap[i][j]== 1&&bitmap[i-1][j]== 0)
        {
            if(gg.x>=j*500&&gg.x<=j*500+480&&gg.y>=-i*500&&gg.y<=-i*500+480){
            gg.y+=80;
            pers->setPosition(vector3df(gg.x,gg.y,500));
            flrf=false;
            }
        }

         if(bitmap[i][j]== 0) // пустота внизу
        {
            if(gg.x>=j*500&&gg.x<=j*500+480&&gg.y>=-i*500&&gg.y<=-i*500+480){
          flrf=false;
            }
        }
     }
}*/
}

public : void gravity()
{
if(flrf==false)
{
gg.y-=0.5;
}
}

};

MYphys phys;

class sky
{
public:void rain(){
if(rainflag==true){
rainflag = false;

  ps = smgr->addParticleSystemSceneNode(false);
   IParticleEmitter* em1 = ps->createBoxEmitter(
                 aabbox3d< f32 >(0,00,00,resw,1,1), // размер эмиттера(куба)
                vector3df(0.5f,-2.0f,0.0f),   // начальное направление
                 50,100,                             // частота испускания (мин,макс)
                 SColor(0,255,255,255),       // самый темный цвет
                 SColor(0,255,255,255),       // самый яркий цвет
                 400,800,30,                         // време жизни (мин,макс), угол
                 dimension2df(32.f,32.f),         // минимальный размер частиц
                dimension2df(96.f,32.f));        // максимальный размер частиц

         ps->setEmitter(em1); // отдаем эмиттер системе
         //em->drop(); // а лично нам он не нужен

         IParticleAffector* paf = ps->createFadeOutParticleAffector();

         ps->addAffector(paf); // отдаем аффектор системе и дропаем, т.к. нам он не нужен
         paf->drop();

         ps->setPosition(vector3df(gg.x,500,0));
         ps->setScale(vector3df(4,2,2));
         ps->setMaterialFlag(EMF_LIGHTING, false);
         ps->setMaterialFlag(EMF_ZWRITE_ENABLE, false);
         ps->setMaterialTexture(0, driver->getTexture("xyu\\list.png"));
         ps->setMaterialType(EMT_TRANSPARENT_VERTEX_ALPHA);
        //ps->setMaterialType(EMT_TRANSPARENT_ALPHA_CHANNEL);

}
};

public:void draw()
{
for(int i=0;i<resh;i++){
driver->draw2DLine(position2d<s32>(0,i),position2d<s32>(resw,i),SColor(255, 20,10,0+i/3));
}
if(rainflag==false)ps->setPosition(vector3df(gg.x-2500,1200,0));

};

public:void recolor()
{

};

};

class sloy
{
public: void create1(){
setpar(vector3df(8700,50,800),vector3df(320,320,0),"xyu\\bus.png");
setpar(vector3df(-256,-100,590),vector3df(723,256,0),"xyu\\home1.png");
setpar(vector3df(-256,0,501),vector3df(723,256,0),"xyu\\home2.png");

for(int i=-6000;i<18000;i+=6000){
setpar(vector3df(i,-1675,500),vector3df(600,80,0),"xyu\\ground1.png");
}

setpar(vector3df(5800,-650,501),vector3df(200,128,0),"xyu\\zabor1.png" );

setpar(vector3df(11000,-650,501),vector3df(200,128,0),"xyu\\zabor1.png" );
back->setMaterialFlag(EMF_BACK_FACE_CULLING,false);
back->setMaterialFlag(EMF_FRONT_FACE_CULLING,true);

setpar(vector3df(35000,620,2000),vector3df(850/1.2,760/1.2,0),"xyu\\rock.png");
setpar(vector3df(25000,20,-100),vector3df(397/1.5,387/1.5,0),"xyu\\tree.png");
setpar(vector3df(15950,-2320,497),vector3df(200,215,0),"xyu\\platform1.png");
setpar(vector3df(17700,-2200,500),vector3df(168,185,0),"xyu\\gorka.png");
setpar(vector3df(17700+1650,-2200-950,501),vector3df(168,185,0),"xyu\\gorka.png");
setpar(vector3df(17700+1735*2,-4200,495),vector3df(200,215,0),"xyu\\platform1.png");
setpar(vector3df(22970,-3700,500),vector3df(190,110,0),"xyu\\ground2.png");
setpar(vector3df(22970+1900,-3700,500),vector3df(190,110,0),"xyu\\ground2.png");
setpar(vector3df(35000,620,2000),vector3df(850/1.2,760/1.2,0),"xyu\\door.png");

};
};

sloy sloy1;

int main()
{
/*

int i=0;
int j=0;

  FILE *in;
   in=fopen("gav.no","r");
   char c;

//for(int i=0;i<bitmapy;i++)
  //  for(int j=0;j<bitmapx;j++)
  while ( (c=fgetc(in) ) != EOF )
{
   // while ( (c=fgetc(in) ) != EOF)

      //   c=fgetc(in);
if(c=='1'||c=='0'||c=='\n'){

              if(c=='\n'){
        i++;
        j=0;

         printf("\n");
        }

             bitmap[i][j]=c;
        j++;
        printf("%c",bitmap[i][j]);

}
             //fputc( c,out );//записываем переменную в файл data2.

}

*/
device =
   createDevice( EDT_OPENGL, dimension2d<u32>(resw, resh), 8,
    false, false, true, &receiver);

   device->getCursorControl()->setVisible(false);
  device->setWindowCaption(L"ALKO");

  driver = device->getVideoDriver();
smgr = device->getSceneManager();
//driver->setFog(SColor(50,255,255,255),
   //              EFT_FOG_LINEAR, 500, 5000, .001f, true, false);
init();

createmat();

//cam=smgr->addCameraSceneNodeFPS();
smgr->getActiveCamera()->setFarValue(10000);

light = smgr->addLightSceneNode(0, vector3df(500,1675,500),
                         SColorf(1.0f, 1.0f, 1.0f, 1.0f), 2500.0f);
device->getFileSystem()->addZipFileArchive("xyu\\xyu.penis");

u32 then = device->getTimer()->getTime();

//water();

for(int i=0;i<bitmapy;i++)
{

     for(int j=0;j<bitmapx;j++)
     {
      if(bitmap[i][j]== 1)
        {

         kub = smgr->addCubeSceneNode();
         kub->setPosition(vector3df(j*2600,-i*2600,500));
         kub->setScale(vector3df(190,190,0));

       }
     }

}

bill1 = smgr->addBillboardSceneNode();
bill1->setMaterialFlag(EMF_LIGHTING, false);
bill1->setMaterialType(EMT_TRANSPARENT_ADD_COLOR );
//bill1->setMaterialType(EMT_TRANSPARENT_VERTEX_ALPHA);
   bill1->setMaterialTexture(0,driver->getTexture("xyu\\sun.png"));
   bill1->setSize(dimension2d<f32>(8000.0f,8000.0f));
bill1->setPosition(vector3df(6000,3000,5500));
bill1->setMaterialFlag(EMF_BILINEAR_FILTER, false);

pers = smgr->addCubeSceneNode();
pers->setMaterialFlag(EMF_LIGHTING,false);

pers->setPosition(vector3df(gg.x,gg.y,500));
pers->setScale(vector3df(70,140,0));
pers->setMaterialTexture( 0, gg.tex[0] );

pers->setMaterialType(EMT_TRANSPARENT_ALPHA_CHANNEL_REF);
pers->setMaterialFlag(EMF_BILINEAR_FILTER, false);
//sloy1.create1();

/*
nebo = smgr->addCubeSceneNode();
nebo->setMaterialFlag(EMF_LIGHTING,false);
nebo->setPosition(vector3df(4800,810,2900));
nebo->setScale(vector3df(1600,230,0));
nebo->setMaterialTexture( 0, driver->getTexture("xyu\\tucha.png") );
nebo->setMaterialType(EMT_TRANSPARENT_ALPHA_CHANNEL);
//nebo->setMaterialFlag(EMF_FOG_ENABLE,true);
*/

sky sky1;

  while(device->run())
  {
      maintimer++;
      if((maintimer%100)==true)sky1.recolor();
const u32 now = device->getTimer()->getTime();
               fdt = (f32)(now - then) / 1000.f;
                 then = now;

  u32 time = device->getTimer()->getTime();

move();
jump();
camera.posx = gg.x;
camera.posy = gg.y;
camera.posz = -1200;

cam->setPosition(vector3df(camera.posx,camera.posy,camera.posz));
cam->setTarget(vector3df(gg.x,gg.y+100,1000));
//addfog();
   driver->beginScene(true, true, SColor(255,0, 40,40));
   pers->setPosition(vector3df(gg.x,gg.y,500));
sky1.draw();
sky1.rain();
phys.collis();
phys.gravity();
   smgr->drawAll();

   driver->endScene();
         device->sleep(IDLE_TIME - (time - device->getTimer()->getTime()));
  }

  device->drop();

  return 0;
}

void move(){

if(receiver.IsKeyDown(KEY_KEY_D)){
gg.movepers(1);
    }

if(receiver.IsKeyDown(KEY_KEY_A)){
gg.movepers(0);

    }
    if(receiver.IsKeyDown(KEY_KEY_S)){
    }
    if(receiver.IsKeyDown(KEY_KEY_W)){
        jumpf=true;

    }

if(go==false){pers->setMaterialTexture(0, gg.tex[0]);}
go=false;
}

void init(){
gg.tex[0]=driver->getTexture("xyu\\gg1.png");
gg.tex[1]=driver->getTexture("xyu\\gg2.png");
gg.tex[2]=driver->getTexture("xyu\\gg3.png");
gg.tex[3]=driver->getTexture("xyu\\gg4.png");
gg.tex[4]=driver->getTexture("xyu\\gg5.png");
gg.tex[5]=driver->getTexture("xyu\\gg6.png");
gg.tex[6]=driver->getTexture("xyu\\gg7.png");
gg.tex[7]=driver->getTexture("xyu\\gg8.png");
gg.tex[8]=driver->getTexture("xyu\\gg9.png");

gg.x=0;
gg.y=0;//=-580;
frametime=0;
cam=smgr->addCameraSceneNode(0, vector3df(0,0,00), vector3df(0,100,00));
cam->setPosition(vector3df(gg.x,gg.y,-1200));
cam->setTarget(vector3df(gg.x,gg.y+100,1000));
cam->setFOV(2);

}

void water()
{
driver->setFog(SColor(255,0,255,255),
                 EFT_FOG_LINEAR, 500, 5000, .0001f, true, false);

mesh = smgr->addHillPlaneMesh( "myHill",
   dimension2d<f32>(20,20),
   dimension2d<u32>(50,50), 0, 0,
   dimension2d<f32>(0,0),
  dimension2d<f32>(2,2));

  node = smgr->addWaterSurfaceSceneNode(mesh->getMesh(0), 300.0f, 2000.0f, 300.0f);
  node->setPosition(vector3df(-200,200,3000));
node->setRotation(vector3df(270,0,0));
node->setMaterialFlag(EMF_LIGHTING, false);
node->setMaterialFlag(EMF_GOURAUD_SHADING,false);
  node->setMaterialTexture(1, driver->getTexture("xyu\\water.jpg"));

  node->setMaterialType(EMT_REFLECTION_2_LAYER);
node->setScale(vector3df(20,1,5));
//node->setMaterialFlag(EMF_FOG_ENABLE,true);
}

void addfog(){
     if(fognod==0){
    fognod = smgr->addCubeSceneNode();
fognod->setMaterialFlag(EMF_LIGHTING,false);
fognod->setPosition(vector3df(-300,-1000,480));
fognod->setScale(vector3df(455,100,0));
fognod->setMaterialTexture( 0, driver->getTexture("xyu\\fog.png") );
fognod->setRotation(vector3df(0,0,180));
fognod->setMaterialType(EMT_TRANSPARENT_ALPHA_CHANNEL);

     }

}

void setpar(vector3df pos,vector3df scal,char * mat)
{
back = smgr->addCubeSceneNode();
back->setMaterialFlag(EMF_LIGHTING,false);

back->setScale(scal);
back->setPosition(pos);
back->setMaterialFlag(EMF_BILINEAR_FILTER, false);
back->setMaterialType(EMT_TRANSPARENT_ALPHA_CHANNEL_REF);
back->setMaterialTexture( 0, driver->getTexture(mat) );

col[0] = 0.7;
col[1]=0.0;
col[2]=0.2;
col[3]=0;
     back->setMaterialType((E_MATERIAL_TYPE)newMaterialType);

//back->setMaterialFlag(EMF_FOG_ENABLE,fog);
}

void jump()
{
     if(jumpf==true)
     {
         gg.y+=10;
     }
}

Добавлено (21.02.2014, 21:07)
---------------------------------------------
Там гибрид из того, что я начинал ранее, потом забил. Вот нашёл чё-то на SFML , хочу перевести свой платформер.

  • Страница 1 из 12
  • 1
  • 2
  • 3
  • 11
  • 12
  • »
Поиск:

Все права сохранены. GcUp.ru © 2008-2025 Рейтинг