#text #libgdx #decal
#текст #libgdx #деколь
Вопрос:
Я работаю над 3D (2.5D) приложением в Libgdx. Я нашел деколи очень полезными для этой цели.
В моем приложении должны быть слои, содержащие динамический текст, теперь мне интересно, как лучше всего рисовать текст с помощью декалей.
В настоящее время моя реализация основана на рисовании BitmapFont в FBO, затем я получаю текстуру FBO и привязываю ее к деколи до декалирования.промывка ().
Я думаю, что это, возможно, не самый эффективный способ сделать это, но не могу придумать лучшего способа.
Мое приложение может содержать большое количество текстовых «слоев», помещенных в 3D-мир, поэтому, возможно, рисование каждого BitmapFont в FBO и привязка текстуры FBO к Decal — не лучший подход.
У вас, ребята, есть идея получше? Каков наиболее эффективный способ сделать это?
Tnx заранее!
Ответ №1:
Вы можете рисовать непосредственно в 3D-пространстве с помощью SpriteBatch, соответствующим образом назначив матрицу проекции.
Во-первых, у вас есть Matrix4, который определяет положение и поворот каждой из ваших строк текста. Причина, по которой вам это нужно, заключается в том, что SpriteBatch и BitmapFont не имеют аргументов для смещения Z.
Поскольку вы можете поместить весь свой перевод в Matrix4, при вызове draw
метода просто нарисуйте значение 0,0.
Затем вы можете использовать Matrix4 каждой сетки для умножения на объединенную матрицу камеры, прежде чем отправлять ее в SpriteBatch. Таким образом, вам понадобится отдельный Matrix4 для выполнения ваших вычислений.
textTransform.idt().scl(0.2f).rotate(0, 0, 1, 45).translate(-50, 2, 25f);
//Probably need to scale it down. Scale before moving or rotating.
spriteBatch.setProjectionMatrix(tmpMat4.set(camera.combined).mul(textTransform));
spriteBatch.begin();
font.draw(spriteBatch, "Testing 1 2 3", 0, 0);
spriteBatch.end();
Комментарии:
1. Обратите внимание, что это все равно приводит к отдельному вызову рисования для каждой сетки, поэтому, если у вас их много, ваши декали могут быть более производительными, при условии, что вы рисуете весь свой текст в одном атласе FBO и используете несколько текстурных областей в этой текстуре FBO для применения ко всем вашим декалям. Это приведет только к двум вызовам рисования для всего вашего текста, но, очевидно, будет сложно правильно настроить. Вы могли бы сэкономить некоторое время графического процессора, отключив смешивание при рисовании текста в FBO.
2. Привет, ты можешь предоставить код для создания текстурных файлов с помощью FBO? Это будет чрезвычайно полезно. Не удается найти какой-либо документ по этому вопросу. Я знаком с рисованием в FBO и получением текстуры из него, а не с TextureAtlas.
3. Это ни в коем случае не автоматически. Вам нужно будет выяснить, как вы хотите разбить 2D-пространство текстурной поверхности, и аккуратно рисовать в пределах этих областей, а также создавать TextureRegions из областей, которые вы настроили, используя стандартные конструкторы.
4. Хорошо. Это имеет смысл, я втайне задавался вопросом, есть ли для этого какой-то встроенный обработчик.
Ответ №2:
Если кто-то все еще приходит к этому ответу 7 лет спустя, я нашел метод, который гораздо больше похож на то, что мне было нужно. Оказывается, это Matrix4.rotateTowardDirection()
был именно тот метод, который мне был нужен:
/* best to make these static, but whatever */
Vector3 textPosition = /* the location of the text */;
Matrix4 projection = new Matrix4();
Matrix4 textTransform = new Matrix4();
textTransform.setToTranslation(textPosition);
textTransform.rotateTowardDirection(new Vector3().set(cam.direction).nor(), Vector3.Y);
projection.set(cam.combined);
Matrix4 op = spriteBatch.getProjectionMatrix().cpy();
Matrix4 ot = spriteBatch.getTransformMatrix().cpy();
// push the matricies
spriteBatch.setProjectionMatrix(projection );
spriteBatch.setTransformMatrix(textTransform);
spriteBatch.begin();
myFont.draw(spriteBatch, "Testing 1 2 3", 0, 0, 0, Align.center, false);
spriteBatch.end();
// pop the matricies
spriteBatch.setProjectionMatrix(op);
spriteBatch.setTransformMatrix(ot);
Ответ №3:
Чтобы получить поведение при вращении декалей, вам нужно сначала вызвать translate перед rotate в матрице textTransform.
textTransform.idt().translate(-50, 2, 25f).rotate(0, 0, 1, 45);
Я немного смущен этим. Возможно, это исторически обосновано из матричного стека.