динамический текст деколи libgdx

#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);
  

Я немного смущен этим. Возможно, это исторически обосновано из матричного стека.