2985
+1
Оставить Мнение
11 Апреля 2013
К недавней статье об оптимизациях в играх
Чтобы еще больше улучшить процесс, и как следствие ускорить игру, пришла в голову следующая мысль: убирать с отрисовки все что за спиной в игре, или то чего я не вижу. Идея гениальная и не мудреная. В том же майнкрафт, уверен. разработчики применили именно это. Т. е. - игрок повернул голову, отображаем все, а сзади пусто, так и с любым углом куда смотрит ГГ. Решается это с помощью формул векторной геометрии, источник я нашел тут (http://brainstream-dev.blogspot.com/2010/09/blog-post.html), и применил его:
После этого поставил ограничения на угол поворота, т. к. юзер смотря через низ видит пустоту сзади. Ограничения поворота - 90 град по вертикали. Далее на этом не все остановилось. Карта тоже может быть достаточно огромная, поэтому используем простую формулу Пифагора, и опять же выбираем расстояние стен и алмазов ближайших к игроку по какому-нибудь радиусу, скажем 15 кубиков, но: опять возникла проблема - есть на карте участки которые не имеют стен и они достаточно далекие с точки зрения горизонта обзора. Поэтому на тех местах радиус отрисовки показывает пустоту. Как быть? Что делать? Здесь уже обратимся к помощи OpenGL и такому свойству как туман (fog), на дальнее расстояние мы будем применять его, чтобы осуществлялось сглаживание от видимой части к невидимой. На OpenGL это делается следующим образом:
gl.glFogf(GL10.GL_FOG_MODE, GL10.GL_LINEAR);
gl.glFogf(GL10.GL_FOG_START, 10.0f);
gl.glFogf(GL10.GL_FOG_END, 16.0f);
float fogColor[] = {0.8f, 0.8f, 0.8f, 1.0f};
// задали серый цвет тумана, пусть будет серым
ByteBuffer ibb = ByteBuffer.allocateDirect(fogColor.length * 4);
ibb.order(ByteOrder.nativeOrder());
FloatBuffer indexBuffer = ibb.asFloatBuffer();
indexBuffer.put(fogColor);
indexBuffer.position(0);
gl.glFogfv(GL10.GL_FOG_COLOR, indexBuffer);
gl.glEnable(GL10.GL_FOG);
НО: надо так же и задать серый цвет для пустоты на сцене.
gl.glClearColor(0.8f, 0.8f, 0.8f, 1.0f);
// те же значения что и в тумане
И сделать это нужно в методы onSurfaceCreated(GL10 gl, EGLConfig config) когда сцена GLSurfaceView будет инициализирована. К тому что не нужно задавать это в onDrawFrame(GL10 gl), т. к. каждый раз будут выполнятся ненужные повторения при обработке кода. Вот и все - туман подключен.
Да, мы жертвуем обзором в какой-то степени, НО у нас появилась возможность рисовать бесконечные карты, потому что, мы остались не привязаны к ее масштабам. Все теперь вычисляется от положения ГГ.
Итого:
для игры применено 2 формулы для прикладного вычисления
Чтобы еще больше улучшить процесс, и как следствие ускорить игру, пришла в голову следующая мысль: убирать с отрисовки все что за спиной в игре, или то чего я не вижу. Идея гениальная и не мудреная. В том же майнкрафт, уверен. разработчики применили именно это. Т. е. - игрок повернул голову, отображаем все, а сзади пусто, так и с любым углом куда смотрит ГГ. Решается это с помощью формул векторной геометрии, источник я нашел тут (http://brainstream-dev.blogspot.com/2010/09/blog-post.html), и применил его:
После этого поставил ограничения на угол поворота, т. к. юзер смотря через низ видит пустоту сзади. Ограничения поворота - 90 град по вертикали. Далее на этом не все остановилось. Карта тоже может быть достаточно огромная, поэтому используем простую формулу Пифагора, и опять же выбираем расстояние стен и алмазов ближайших к игроку по какому-нибудь радиусу, скажем 15 кубиков, но: опять возникла проблема - есть на карте участки которые не имеют стен и они достаточно далекие с точки зрения горизонта обзора. Поэтому на тех местах радиус отрисовки показывает пустоту. Как быть? Что делать? Здесь уже обратимся к помощи OpenGL и такому свойству как туман (fog), на дальнее расстояние мы будем применять его, чтобы осуществлялось сглаживание от видимой части к невидимой. На OpenGL это делается следующим образом:
gl.glFogf(GL10.GL_FOG_MODE, GL10.GL_LINEAR);
gl.glFogf(GL10.GL_FOG_START, 10.0f);
gl.glFogf(GL10.GL_FOG_END, 16.0f);
float fogColor[] = {0.8f, 0.8f, 0.8f, 1.0f};
// задали серый цвет тумана, пусть будет серым
ByteBuffer ibb = ByteBuffer.allocateDirect(fogColor.length * 4);
ibb.order(ByteOrder.nativeOrder());
FloatBuffer indexBuffer = ibb.asFloatBuffer();
indexBuffer.put(fogColor);
indexBuffer.position(0);
gl.glFogfv(GL10.GL_FOG_COLOR, indexBuffer);
gl.glEnable(GL10.GL_FOG);
НО: надо так же и задать серый цвет для пустоты на сцене.
gl.glClearColor(0.8f, 0.8f, 0.8f, 1.0f);
// те же значения что и в тумане
И сделать это нужно в методы onSurfaceCreated(GL10 gl, EGLConfig config) когда сцена GLSurfaceView будет инициализирована. К тому что не нужно задавать это в onDrawFrame(GL10 gl), т. к. каждый раз будут выполнятся ненужные повторения при обработке кода. Вот и все - туман подключен.
Да, мы жертвуем обзором в какой-то степени, НО у нас появилась возможность рисовать бесконечные карты, потому что, мы остались не привязаны к ее масштабам. Все теперь вычисляется от положения ГГ.
Итого:
для игры применено 2 формулы для прикладного вычисления
- с какой стороны от прямой лежит точка.
- расстояние между двумя точками.