Войти
ПрограммированиеФорумГрафика

Подергивания при glTranslate

#0
1:42, 18 авг. 2013

При попытке реализовать скроллинг камеры за игроком получаю непонятные рывки в сторону движения камеры. Код:

                if (planePos.X >= width && planePos.Y >= height)
                {
                    GL.Translate(pt.X - dx, pt.Y - dy, 0);
                }
                else if (planePos.X >= width)
                {
                    GL.Translate(pt.X, 0, 0);
                }
                else if (planePos.Y >= height)
                {
                    GL.Translate(0, pt.Y, 0);
                }

//Ниже - отрисовка всех текстур

width и height - половины ширины и высоты экрана
planePos - позиция игрока
Без Translate ничего подобного нет.
Что примечательно, меняя очередность отрисовки текстур (z testing отключен), к примеру, сначала рисуя самолет, а потом - дым, подергивания пропадают.
VSynch включен, перепробовал Accumulation буферы, интерполяцию, ничего не помогло. Есть идеи, куда копать?

Изображение

#1
9:26, 18 авг. 2013

Почему в первом блоке есть -dx и -dy, а во втором и третьем нет?

#2
17:45, 18 авг. 2013

NightmareZ, это я пытался "сгладить" камеру интерполяцией, увы, сути не меняет :с
Вот новый код со сглаживанием:

            public static void CameraCenterOnPlayerPlane()
            {
                double width = FormMain.Param.XSize / (2 * Scale);
                double height = FormMain.Param.YSize / (2 * Scale);
                
                PointF planePos = Network.PlayerClient.Plane.Center;

                float dx = (float)Math.Round(planePos.X - Center.X - width);
                float dy = (float)Math.Round(planePos.Y - Center.Y - height);

                Center.X += (float)(dx * 0.01f);
                Center.Y += (float)(dy * 0.01f);

                if (planePos.X >= width && planePos.Y >= height)
                {
                    GL.Translate(-Center.X, -Center.Y, 0);
                }
                else if (planePos.X >= width)
                {
                    GL.Translate(-Center.X, 0, 0);
                }
                else if (planePos.Y >= height)
                {
                    GL.Translate(0, -Center.Y, 0);
                }

            }

И результат:

Изображение
Изображение
#3
18:31, 18 авг. 2013

TonyForge, пришла мысль, что то, что наблюдается при сглаживании камеры и то, что наблюдается при простом центрировании (в первом посте) - разные проблемы.
Убрал сглаживание камеры, рисую в таком порядке:

                Graphics.DrawBG();
                GL.Viewport(0, 0, Param.XSize, Param.YSize);
                Bullet.DisplayAll();
                Smoke.DisplayAll(); //!!!
                Player.DisplayAll(); //!!!
                GraphicsPanels.Display();

Получаю:

Изображение

Теперь рисую в таком:

                Graphics.DrawBG();
                GL.Viewport(0, 0, Param.XSize, Param.YSize);
                Bullet.DisplayAll();
                Player.DisplayAll(); //!!!
                Smoke.DisplayAll(); //!!!
                GraphicsPanels.Display();

И рывки пропадают:

Изображение

Ничего не пойму :)

#4
19:53, 18 авг. 2013

TonyForge, спасибо за исчерпывающий ответ. Если я правильно понимаю, то нужный мне левый верхний угол в мировых координатах - это мировые координаты самолетика отнять половину размера экрана:

                float viewport_x = Network.PlayerClient.Plane.Center.X - Param.XSize / 2;
                float viewport_y = Network.PlayerClient.Plane.Center.Y - Param.YSize / 2;

Делаем сдвиг:

                GL.Translate(-viewport_x, -viewport_y, 0);

После, рисуем мир:

                Graphics.DrawBG(); //фон
                Smoke.DisplayAll(); //дым
                Bullet.DisplayAll(); //пули
                Player.DisplayAll(); //самолетики
                GraphicsPanels.Display(); //панели, хелс-бары...

Почему надо отменять транслейт для всего, что не связано с самолетиком? Ведь если двигаю камеру, то двигаю ее одновременно относительно всего мира?

#5
22:07, 18 авг. 2013

MDS, но ведь пока что нет матриц, которые я затрагиваю, помимо движения камеры

#6
0:11, 19 авг. 2013

TonyForge, когда описал транслейты, как вы показали, я, конечно, отключил метод, в котором использовался код с первого поста. Тем не менее, ведь все правильно работает, да и сдвиги все происходят весьма и весьма адекватно и понятно - даже в мультиплеерном режиме, впрочем, иначе и быть не должно, ведь на статичные к экрану панели я не жалуюсь, а все остальное существует в мировых координатах.

Вот только это странное подергивание. Даже наталкивает на мысли о tearing/неправильной работе swapbuffers/VSynch/Accumulation, но все, что приходило в голову - перекопал. Быть может, еще какие-то идеи?

#7
18:14, 19 авг. 2013

В общем исправил проблему. Оказывается, графика - не виновник. За один цикл отрисовки клиент получал несколько пакетов с информацией о положении игрока и перемещение камеры происходило порой не по актуальной позиции, из-за чего возникали глитчи, как в первом посте.
После сглаживания камеры появились глитчи, как в следующих постах. Из-за гладкой динамики камеры глаз слишком резко воспринимал телепортацию самолетика по координатам с сервера.

Рассчитываю количество кадров между поставкой пакетов, интерполирую по последним позициям, теперь все гладко. Всем спасибо! :3

#8
22:20, 19 авг. 2013
Network.PlayerClient.Plane.Center.X
о_0
Это чей то двиг так вынуждает, или сами? Любопытство гложет :)
#9
22:39, 19 авг. 2013

Zloten, ООП, ООП повсюду :)
А по сабжу, сам делал иерархию. Смущает? Может и вправду сделать больше геттров...

#10
0:55, 20 авг. 2013

TonyForge, после часов отладки до написания поста я пришел к выводу, что сервер работает отлично. Ошибся :3

ПрограммированиеФорумГрафика

Тема в архиве.