ВНИМАНИЕ! Наша конференция посвящена космической тематике и компьютерным играм. Политические вопросы и происходящие в мире события в данный момент на нашем сайте не обсуждаются!
|
» Техническая помощь в реализации самописных игр | страница 6 |
|
|
|
Канал Игры Мечты: «Техническая помощь в реализации самописных игр» |
|
|
БулерМэн 420 EGP
Рейтинг канала: 2(21) Репутация: 68 Сообщения: 1580 Откуда: Гороховец Зарегистрирован: 07.02.2006 |
|
Michael_Moon : |
не могу непосредственно влиять на окно, а, значит, и скомандовать ему активироваться в макс режиме.
|
то есть тебе надо сначала скрыть окно другого приложения, а потом в нужный момент развернуть на весь экран?
добавлено спустя 16 минут:
Michael_Moon : |
Кстати, в VBScript пробовал запускать
|
Так, а может тебе просто концептуально подойти с другого конца?
Как я понимаю, у тебя происходит попытка выполнять несколько "сюжетов" одновременно (в X'сах кстати удаленный бой и удаленная экономика в других секторах работает не "реалтайм", при этом это одно приложение).
У тебя видимо задумка реализовать реалтайм нескольких сюжетов/действий в разных локациях.
Если это так - то почему не в одном приложении? Например, хранить вместо объектов со своими переменными - структуры данных, причем глобально.
Как только кораблики (экземпляры объекта "корабль") перестают иметь собственный выполняемый код в событии STEP, то есть с каждым шагом - у тебя появляется возможность изменять характеристики этого "виртуального объекта" с нужным интервалом времени, на нужную величину.
При появлении тебя в локации - объекты "восстают из небытия" по данным из структуры данных этой локации или даже вообще из глобальной структуры. Ты видишь кораблики, кораблики видят тебя, но по прежнему - обработчик структуры данных работает по всем объектам, но для текущей локации чаще.
Такая имха.
Последний раз редактировалось: БулерМэн (21:20 12-09-2015), всего редактировалось 1 раз |
|
|
Michael_Moon 100 EGP
Рейтинг канала: 1(2) Репутация: -2 Сообщения: 669 Откуда: РК, Кокшетау Зарегистрирован: 15.02.2011 |
|
Описанный алгоритм хорош всем, кроме одного: он - жестко структурирован на самого себя. Отдельные приложения позволяют реализацию своего рода "модульности", а значит и большую гибкость в реализации различных аспектов игры (на мой взгляд) Ну и командная работа проще реализуется
|
|
|
DIMOSUS.X 997 EGP
Рейтинг канала: 4(67) Репутация: 188 Сообщения: 3252 Откуда: Vilnius/Minsk Зарегистрирован: 06.08.2008 |
|
А может мне кто подскажет?
Под линуксом мне нужно уведомить процесс C#(mono) из процесса на C (сгенерировать событие)
Третий день гуглю...
_________________ Даже ежики ежиков могут с трудом,
Иначе бы ежики были кругом.
Последний раз редактировалось: DIMOSUS.X (13:02 13-09-2015), всего редактировалось 1 раз |
|
|
БулерМэн 420 EGP
Рейтинг канала: 2(21) Репутация: 68 Сообщения: 1580 Откуда: Гороховец Зарегистрирован: 07.02.2006 |
|
Michael_Moon : |
Отдельные приложения позволяют реализацию своего рода "модульности"
|
Если хочется отдельными приложениями - то обмен сообщениями проще через сокеты. Модульность в полный рост: "сервер" принимает подключения "модулей" и ведет с ними диалог типа запрос/ответ.
Только вот потом возникнет проблема если захочется сетевой мультиплеер сделать, хотя... Это же по сути и есть мультиплеер только зачем-то на одном компьютере
В Юнити не знаю как, а в GM сокрытие окна на ходу есть. Даже не сворачивание окна, а именно отключение отрисовки окна. Может стоит поискать дополнения или dll-ки, которые изменяют отрисовку окна, если в самом юнити это не предусмотрено?
добавлено спустя 3 минуты:
DIMOSUS.X : |
Под линуксом мне нужно уведомить процесс C#(mono) из процесса на C (сгенерировать событие)
|
так может тоже через сокеты сделать?
под линуксы как-то писал клиент-серверную "передавалку" файлов, исходник на Си где-то валяется.
Думаю, что на СиШарп организовать сетевой листинг проще чем на Си.
Последний раз редактировалось: БулерМэн (14:25 13-09-2015), всего редактировалось 2 раз(а) |
|
|
DIMOSUS.X 997 EGP
Рейтинг канала: 4(67) Репутация: 188 Сообщения: 3252 Откуда: Vilnius/Minsk Зарегистрирован: 06.08.2008 |
|
Спасибо — подтолкнул в нужном направлении Запилил именованные каналы.
_________________ Даже ежики ежиков могут с трудом,
Иначе бы ежики были кругом. |
|
|
БулерМэн 420 EGP
Рейтинг канала: 2(21) Репутация: 68 Сообщения: 1580 Откуда: Гороховец Зарегистрирован: 07.02.2006 |
|
Michael_Moon : |
Отдельные приложения позволяют реализацию своего рода "модульности"
|
Кстати http://habrahabr.ru/post/81067/
может пригодится
|
|
|
БулерМэн 420 EGP
Рейтинг канала: 2(21) Репутация: 68 Сообщения: 1580 Откуда: Гороховец Зарегистрирован: 07.02.2006 |
|
Задумался над тем, как сделать код более понятным для дальнейшей разработки.
Написал подробные комментарии - не помогло.
Попробовал использовать штатный дебагер для отслеживания переменных - не подходит, не видно какой код изменяет эти переменные.
Написал свой дебагер с подсветкой выполняемого кода на ходу - слишком долго приходится ждать пока программа догребет до нужного места.
И вот пока я это здесь писал приходит гениальная мысль - используй процедуры и сократи код, люк!
Хотел спросить, в итоге сам себе ответил
Последний раз редактировалось: БулерМэн (00:31 23-09-2015), всего редактировалось 2 раз(а) |
|
|
Shirson 1605 EGP
Рейтинг канала: 7(626) Репутация: 219 Сообщения: 16511 Откуда: 79°W 44°N Зарегистрирован: 29.01.2002 |
|
БулерМэн : |
Задумался над тем, как сделать код более понятным для дальнейшей разработки.
|
Целая наука
Цитата: |
Написал подробные комментарии - не помогло.
|
Подробные комментарии - зло. Еще большее, чем их отсутствие.
Цитата: |
Попробовал использовать штатный дебагер для отслеживания переменных - не подходит, не видно какой код изменяет эти переменные.
|
Глобальные переменные - страшное, первобытное зло. Страшнее отсутстви якоментариев
Цитата: |
Написал свой дебагер с подсветкой выполняемого кода на ходу - слишком долго приходится ждать пока программа догребет до нужного места.
|
Мсьё знает толк в извращениях!
Цитата: |
И вот пока я это здесь писал приходит гениальная мысль - используй процедуры и сократи код, люк!
Хотел спросить, в итоге сам себе ответил
|
Как писать код, понятный хотя бы себе самому
http://www.gunsmoker.ru/2011/01/blog-post.html
НЕ пишите комментарии!
http://www.gunsmoker.ru/2010/07/blog-post_31.html
_________________ У меня бисера не доxеpа. |
|
|
Guest 2075 EGP
Рейтинг канала: 5(167) Репутация: 376 Сообщения: 27975 Откуда: Моск. Зарегистрирован: 12.10.2004 |
|
Ещё вот: http://habrahabr.ru/post/266969/
Причём в комментариях как обычно больше полезного, чем в статье.
В том числе апологетам "самодокументированного кода". Писать комментарии не в стиле Капитана, т.е. что этот код делает, а причину того, что написано, почему он это делает.
_________________ Трещит земля как пустой орех
Как щепка трещит броня |
|
|
Minx 980 EGP
Рейтинг канала: 6(328) Репутация: 136 Сообщения: 10528 Откуда: Gomel, Belarus Зарегистрирован: 19.11.2005 |
|
БулерМэн : |
Написал подробные комментарии - не помогло.
|
В общем случае подробные комментарии зло.
Но в частном случае, особенно если человек комментариев не пишет, то инструмент для саморазвития.
Т.е. сначала пишем комментариев, потом через месяц возвращаемся к коду. Если видим, что комментарий бесполезен, то удаляем. И запоминаем, что такого писать не надо. Если полезен, то оставляем. Если чего-то не понятно, то разбираемся и дописываем.
Это, имхо, самый эффективный способ обучения комментированию. Потому что в этом деле по большому счету человек учиться только на своих ошибках.
Да, и иногда для достижения качественного комментирования нужно проработать с серьезным проектом несколько лет.
БулерМэн : |
И вот пока я это здесь писал приходит гениальная мысль - используй процедуры и сократи код, люк!
|
Удачные архитектурные решения (способность принимать которые приходит с опытом) и общая способность структурировать свою работу ведет к улучшению в том числе процесса понимания и общения с кодом.
---
Тут предлагают ссылки. От себя предложу книгу: Art of Readable Code (есть перевод, но я знакомился на англ - читается предельно легко). По-моему, со времен Алена Голуба это лучшее, что есть.
_________________ μηδείς αγεωμέτρητος εισίτω
Последний раз редактировалось: Minx (11:04 23-09-2015), всего редактировалось 1 раз |
|
|
Jurec 348 EGP
Рейтинг канала: 4(76) Репутация: 102 Сообщения: 1441 Заблокирован Откуда: Seattle Зарегистрирован: 25.02.2006 |
|
Ребят, а можно что-то поближе к практике? Вы о каких-то таких астральных вещах уже говорите, что хуже оффтопа не придумать
_________________ MOV topka, C++ |
|
|
Diff 708 EGP
Рейтинг канала: 2(11) Репутация: 44 Сообщения: 4179 Откуда: Сферическая Земля в вакууме. Зарегистрирован: 04.07.2003 |
|
Jurec : |
а можно что-то поближе к практике?
|
Можно.
Я тут заинтересовался оптимизацией под кеш-попадания и написал небольшой тестик.
Cкрытый текст (кликните здесь для просмотра)
Код: |
#include <stdio.h>
#include <stdlib.h>
#include <inttypes.h>
#include <string.h>
#include <sys/time.h>
#define blocksize(n) ((1<<n) * 128 * 1024)
//Data amount to transfer in each test, GB
const int DATA_SIZE = 5;
void proceed_mem();
void init_mem();
uint64_t gettime();
int main(){
void *block1, *block2;
for (int size_factor = 0; size_factor < 9; size_factor++){
int block_size = blocksize(size_factor);
int num_runs = ( (1<<30) / block_size ) * DATA_SIZE;
block1 = malloc( block_size );
block2 = malloc( block_size );
uint64_t oldtime = gettime();
for (int j=0; j != num_runs; j++){
proceed_mem(block1, block2, block_size);
}
uint64_t duration = gettime() - oldtime;
free (block1);
free (block2);
double total_bytes = (double)1000000 * block_size * num_runs;
printf ("Size %d KB\tspeed %.f MB/s\n", block_size/1024, total_bytes/duration/(1<<20) );
}
return 0;
}
void proceed_mem(uint64_t *block1, uint64_t *block2, int block_size){
memmove(block1, block2, block_size);
memmove(block2, block1, block_size);
}
uint64_t gettime(){
struct timeval tv;
struct timezone tz;
gettimeofday(&tv, &tz);
return tv.tv_sec * 1000000 + tv.tv_usec;
}
|
|
Тест простой как мычание - выделяет два блока памяти одинакового размера и копирует один в другой и обратно до полной нирваны. После чего выводит скорость операций для размеров блока от 128 КБ до 32 МБ.
Запускал у себя на ноуте.
Ноут про себя пишет что
Код: |
Processor Name: Intel Core i7
Processor Speed: 2,2 GHz
Number of Processors: 1
Total Number of Cores: 4
L2 Cache (per Core): 256 KB
L3 Cache: 6 MB
Memory: 16 GB
|
Запускаем и видим вот такую картину
Код: |
Size 128 KB speed 12188 MB/s
Size 256 KB speed 8444 MB/s
Size 512 KB speed 8896 MB/s
Size 1024 KB speed 9214 MB/s
Size 2048 KB speed 9066 MB/s
Size 4096 KB speed 7649 MB/s
Size 8192 KB speed 5938 MB/s
Size 16384 KB speed 5474 MB/s
Size 32768 KB speed 4747 MB/s
|
Явно видно как работает кэш L2 на блоке в 128 и L3 от 256 до 2048.
Странно, что, похоже, ни один из 256К блоков не сумел залезть в L2.
ОК, попробуем теперь ситуацию многократного выделения памяти. Перенесем malloc и free во внутренний цикл:
Код: |
for (int j=0; j != num_runs; j++){
block1 = malloc( block_size );
block2 = malloc( block_size );
proceed_mem(block1, block2, block_size);
free (block1);
free (block2);
}
|
Запускаем
Код: |
Size 128 KB speed 10874 MB/s
Size 256 KB speed 8555 MB/s
Size 512 KB speed 8359 MB/s
Size 1024 KB speed 8425 MB/s
Size 2048 KB speed 8384 MB/s
Size 4096 KB speed 6316 MB/s
Size 8192 KB speed 1618 MB/s
Size 16384 KB speed 1598 MB/s
Size 32768 KB speed 1453 MB/s
|
Как говорил ослик Иа, душераздирающее зрелище. Кэшу аллокация памяти нипочем, а ОЗУ кряхтит, скрипит и матерится. Начинаешь сочувствовать Джо, мечтающему о более других аллокаторах.
А напоследок попробуем изобразить более кропотливую работу с памятью. Будем не копировать блоки друг в друга, а ксорить их по 64-битным словам.
Код: |
void proceed_mem(uint64_t *block1, uint64_t *block2, int block_size){
// memmove(block1, block2, block_size);
// memmove(block2, block1, block_size);
int word_number = block_size/sizeof(uint64_t);
for (int i=0; i != word_number; i++ ) {
*block1 = (*block1) ^ (*block2);
*block2 = (*block2) ^ (*block1);
++block1;
++block2;
}
}
|
Запускаем
Код: |
Size 128 KB speed 2199 MB/s
Size 256 KB speed 2227 MB/s
Size 512 KB speed 2232 MB/s
Size 1024 KB speed 2257 MB/s
Size 2048 KB speed 2183 MB/s
Size 4096 KB speed 2090 MB/s
Size 8192 KB speed 1186 MB/s
Size 16384 KB speed 1183 MB/s
Size 32768 KB speed 1019 MB/s
|
Влияние L2 кэша пропало совсем, а влияние L3 распространилось на блоки 4MB. Дальше скорость падает в два раза.
Зачем я все это написал? Просто ждал результатов долгого теста .
_________________ Конец света в конце тоннеля |
|
|
БулерМэн 420 EGP
Рейтинг канала: 2(21) Репутация: 68 Сообщения: 1580 Откуда: Гороховец Зарегистрирован: 07.02.2006 |
|
Разбираясь с "волнами в океане" обнаружил такую вещь - сделать это в 3d гораздо проще
Но так как игра не 3d, поэтому сабж:
В данном случае - это просто синусоида, один источник волн.
Очень похоже на стандартный объект "WaveObject" в 3dsmax с расходящимися в стороны волнами.
Есть возможность добавлять несколько источников волн разной конфигурации:
В данном случае два источника, отличаются длиной волны и позицией в пространстве.
Я прекрасно понимаю, что волны в океане это не просто синусоида, и может даже совсем не синусоида
Если кто знает, подскажите как еще можно смоделировать...Так как данная модель не дает возможности делать резкие "перехлесты" и всплески.
|
|
|
БулерМэн 420 EGP
Рейтинг канала: 2(21) Репутация: 68 Сообщения: 1580 Откуда: Гороховец Зарегистрирован: 07.02.2006 |
|
Пишу очередной сервер/клиент.
Сервер висит на 127.0.0.1:80 в локалке.
Клиент подключается к 127.0.0.1:80, устанавливает соединение, ESTABLISHED.
Выношу сервер на выделенный сервер в Интернете, запускаю на 127.0.0.1:80.
Клиентом, со своего локального компьютера - подключаюсь к белому IP удаленного сервера, указываю соединиться с 89.108.XX.XX:80.
...и тут возникает проблема: SYN_SENT на стороне клиента и висит секунд 10, так и не подключившись.
Запустив сервер на 0.0.0.0:80 получаем тот же результат.
На стороне сервера никаких телодвижений или коннектов не наблюдается.
В сеть хожу через мобильного оператора Билайн, через свисток.
В чем может быть проблема?
Для полноты картины привожу фрагменты кода сервера/клиента:
сервер (кликните здесь для просмотра)
Код: |
int tcplisten(PCSTR DEFAULT_ADDR_ext, PCSTR DEFAULT_PORT_ext)
{
WSADATA wsaData;
int iResult;
//SOCKET ListenSocket = INVALID_SOCKET;
//SOCKET ClientSocket = INVALID_SOCKET;
struct addrinfo *result = NULL;
struct addrinfo hints;
int iSendResult;
char recvbuf[DEFAULT_BUFLEN];
int recvbuflen = DEFAULT_BUFLEN;
// Initialize Winsock
iResult = WSAStartup(MAKEWORD(2,2), &wsaData);
if (iResult != 0) {
printf("WSAStartup failed with error: %d\n", iResult);
return 1;
}
else
{
printf("WSAStartup ok\n");
}
ZeroMemory(&hints, sizeof(hints));
hints.ai_family = AF_INET;
printf("ai_family: %d\n", AF_INET);
hints.ai_socktype = SOCK_STREAM;
printf("ai_socktype: %d\n", SOCK_STREAM);
hints.ai_protocol = IPPROTO_TCP;
printf("ai_protocol: %d\n", IPPROTO_TCP);
hints.ai_flags = AI_PASSIVE;
printf("ai_flags: %d\n", AI_PASSIVE);
// Resolve the server address and port
iResult = getaddrinfo(DEFAULT_ADDR_ext, DEFAULT_PORT_ext, &hints, &result);
if ( iResult != 0 ) {
printf("getaddrinfo failed with error: %d\naddr: %s, port: %s", iResult, DEFAULT_ADDR_ext,DEFAULT_PORT_ext);
WSACleanup();
return 1;
}
else
{
printf("getaddrinfo ok: adr - %s, port %s\n", DEFAULT_ADDR_ext,DEFAULT_PORT_ext);
}
// Create a SOCKET for connecting to server
ListenSocket = socket(result->ai_family, result->ai_socktype, result->ai_protocol);
if (ListenSocket == INVALID_SOCKET) {
printf("socket failed with error: %ld\n", WSAGetLastError());
freeaddrinfo(result);
WSACleanup();
return 1;
}
else
{
printf("socket ok: %d\n", ListenSocket);
SET_NONBLOCK(ListenSocket);//Перевод сокета в неблокирующий режим
}
// Setup the TCP listening socket
iResult = bind( ListenSocket, result->ai_addr, (int)result->ai_addrlen);
if (iResult == SOCKET_ERROR) {
printf("bind failed with error: %d\n", WSAGetLastError());
freeaddrinfo(result);
closesocket(ListenSocket);
WSACleanup();
return 1;
}
else
{
printf("bind ok: %d, on port: %s\n", iResult, DEFAULT_PORT_ext);
}
freeaddrinfo(result);
iResult = listen(ListenSocket, SOMAXCONN);
if (iResult == SOCKET_ERROR) {
printf("listen failed with error: %d\n", WSAGetLastError());
closesocket(ListenSocket);
WSACleanup();
return 1;
}
else
{
printf("listen ok: socket %d, max connections %d\n", ListenSocket, SOMAXCONN);
}
}
float tcpaccept()
{
// Accept a client socket
ClientSocket = accept(ListenSocket, NULL, NULL);
if (ClientSocket == INVALID_SOCKET) {
//printf("accept failed with error: %d\n", WSAGetLastError());
//closesocket(ListenSocket);
//WSACleanup();
return -1;
}
else
{
printf("accept ok\n");
return ClientSocket;
}
}
|
|
клиент (кликните здесь для просмотра)
Код: |
WSADATA wsaData;
SOCKET ConnectSocket = INVALID_SOCKET;
struct addrinfo *result = NULL,
*ptr = NULL,
hints;
char *sendbuf = "this is a test";
char recvbuf[DEFAULT_BUFLEN];
int iResult;
int recvbuflen = DEFAULT_BUFLEN;
// Validate the parameters
/*if (argc != 2) {
printf("usage: %s server-name\n", argv[0]);
getch();
return 1;
}*/
char adr[100];
char prt[100];
printf("Put ip-address here:");
scanf("%20s", adr);
printf("\n");
printf("Put port here:");
scanf("%20s", prt);
printf("\n");
// Initialize Winsock
iResult = WSAStartup(MAKEWORD(2,2), &wsaData);
if (iResult != 0) {
printf("WSAStartup failed with error: %d\n", iResult);
getch();
return 1;
}
ZeroMemory( &hints, sizeof(hints) );
hints.ai_family = AF_INET;
hints.ai_socktype = SOCK_STREAM;
hints.ai_protocol = IPPROTO_TCP;
// Resolve the server address and port
iResult = getaddrinfo(adr, prt, &hints, &result);
if ( iResult != 0 ) {
printf("getaddrinfo failed with error: %d\n", iResult);
getch();
WSACleanup();
return 1;
}
// Attempt to connect to an address until one succeeds
for(ptr=result; ptr != NULL ;ptr=ptr->ai_next) {
// Create a SOCKET for connecting to server
ConnectSocket = socket(ptr->ai_family, ptr->ai_socktype,
ptr->ai_protocol);
if (ConnectSocket == INVALID_SOCKET) {
printf("socket failed with error: %ld\n", WSAGetLastError());
getch();
WSACleanup();
return 1;
}
// Connect to server.
iResult = connect( ConnectSocket, ptr->ai_addr, (int)ptr->ai_addrlen);
if (iResult == SOCKET_ERROR) {
closesocket(ConnectSocket);
ConnectSocket = INVALID_SOCKET;
continue;
}
break;
}
freeaddrinfo(result);
if (ConnectSocket == INVALID_SOCKET) {
printf("Unable to connect to server!\n");
getch();
WSACleanup();
return 1;
}
// Send an initial buffer
iResult = send( ConnectSocket, sendbuf, (int)strlen(sendbuf), 0 );
if (iResult == SOCKET_ERROR) {
printf("send failed with error: %d\n", WSAGetLastError());
getch();
closesocket(ConnectSocket);
WSACleanup();
return 1;
}
printf("Bytes Sent: %ld\n", iResult);
|
|
Последний раз редактировалось: БулерМэн (16:36 29-01-2016), всего редактировалось 2 раз(а) |
|
|
БулерМэн 420 EGP
Рейтинг канала: 2(21) Репутация: 68 Сообщения: 1580 Откуда: Гороховец Зарегистрирован: 07.02.2006 |
|
ЗЫ [Закрыто] надо было внешний ip указывать для сервера...
|
|
|
DIMOSUS.X 997 EGP
Рейтинг канала: 4(67) Репутация: 188 Сообщения: 3252 Откуда: Vilnius/Minsk Зарегистрирован: 06.08.2008 |
|
А никто здесь случаем не использовал monogame?
_________________ Даже ежики ежиков могут с трудом,
Иначе бы ежики были кругом. |
|
|
БулерМэн 420 EGP
Рейтинг канала: 2(21) Репутация: 68 Сообщения: 1580 Откуда: Гороховец Зарегистрирован: 07.02.2006 |
|
что-то мне подсказывает, что упрощение процесса создания непременно приведет к упрощению самой игры.
|
|
|
DIMOSUS.X 997 EGP
Рейтинг канала: 4(67) Репутация: 188 Сообщения: 3252 Откуда: Vilnius/Minsk Зарегистрирован: 06.08.2008 |
|
Думаю на рендером спрайтов, тобишь своем SpriteBatch. Пока прешил спрайты рендерить в нахлест. Приходящие запросы на рендер спрайтов складировать. Когда придет время рендера, то начать собирать спрайты в пачки по признаку общей текстуры. Спрайты перебирать один за одним - согласно поступлению запроса на рендер. При этом, если очередной спрайт из очереди вдруг колизится с любым из спрайтов текущей пачки, то формирование пачки заканчивается и начинается новая.
После этого все пачки записываются в один общий вертекс буффер, который несколько раз (по количеству пачек) рендерится с соответствующим офсетом. Что бы меньше данных гонять по шине, для каждого спрайта в вертекс буффер записывать по одному вертексу, а в геометрическом шейдере из него генерировать полноценный спрайт.
Хотелось бы услышать как можно это улучшить/оптимизировать, или вообще заменить на более удачный подход.
_________________ Даже ежики ежиков могут с трудом,
Иначе бы ежики были кругом.
Последний раз редактировалось: DIMOSUS.X (01:27 16-10-2016), всего редактировалось 1 раз |
|
|
DIMOSUS.X 997 EGP
Рейтинг канала: 4(67) Репутация: 188 Сообщения: 3252 Откуда: Vilnius/Minsk Зарегистрирован: 06.08.2008 |
|
Еще один извращенный вариант придумал — загонять все спрайты в константный буффер. Далее компьют шейдером бить экран на тайлы и для каждого находить список спрайтов, в тайл попадающий. Потом спрайты каждого тайла сортировать и применять к каждому пикселю тайла.
_________________ Даже ежики ежиков могут с трудом,
Иначе бы ежики были кругом. |
|
|
DIMOSUS.X 997 EGP
Рейтинг канала: 4(67) Репутация: 188 Сообщения: 3252 Откуда: Vilnius/Minsk Зарегистрирован: 06.08.2008 |
|
Продолжаю монолог.
Спрайты на геометрических шейдерах рулят. Экран усеян текстом, где каждая буква это спрайт. Текст заново форматируется и разбивается на спрайты каждый кадр. 800 фпс на встроенной Intel HD 4400 Самое главное сделать линейный пул вертексов в оперативной памяти.
_________________ Даже ежики ежиков могут с трудом,
Иначе бы ежики были кругом. |
|
|
|
|
|
Канал Игры Мечты: «Техническая помощь в реализации самописных игр» |
|
К списку каналов | Наверх страницы |
Цитата не в тему: Долго гадал как же слить из нивы прошлогоднюю горючку, бо завестись не мог даже с галстука... Оставил в другом месте - за ночь слили при чем вместе со всей гадостью. (krok)
|
» Техническая помощь в реализации самописных игр | страница 6 |
|