C#/Tao.framework. Простой способ отобразить текст в OpenGL

Блоговая публикация пользователя: Flashhell Эта публикация была перенесена из личного блога пользователя в общие разделы уровок сайта.

C#/Tao.framework. Простой способ отобразить текст в OpenGL

Задача отрисовки текста в OpenGL обычно сводится к рисованию прямоугольников с натянутой текстурой, на которой отображена та или иная буква. Затем нужно располагать их друг относительно друга так, чтобы получались слова. На C# это делается очень легко с помощью встроенных методов класса Graphics.

В основу был взят пример рендера текста из документации OpenTK.

OpenTK - это net привязка к различным инструментам, библиотекам таким OpenGL, OpenCL, OpenAL, также имеются различные вспомогательные классы для работы c математикой и вводом. В ней присутствует дополнительная к OpenTK библиотека под названием QuickFont, помогающая быстро и качественно отрисовать текст в OpenGL. Но здесь речь пойдет о том, как сделать это с помощью tao.framework.

Пример очень простой и соответственно о какой-либо оптимизации и речи быть не может. Он лишь показывает, как сделать можно, но это не самый лучший способ сделать это.

Пример:

Код:
/*http://esate.ru, Flashhell*/

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using Tao.OpenGl;
using System.Drawing.Imaging;

namespace tao_lesson
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
            simpleOpenGlControl1.InitializeContexts();
        }

        private void simpleOpenGlControl1_Load(object sender, EventArgs e)
        {
        }

        private void simpleOpenGlControl1_Paint(object sender, PaintEventArgs e)
        {
            uint texture_text = 0;

            Gl.glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
            Gl.glClear(Gl.GL_COLOR_BUFFER_BIT);

            // ! Создаем картинку
            Bitmap text_bmp = new Bitmap(simpleOpenGlControl1.Width, simpleOpenGlControl1.Height);
            // ! Создаем поверхность рисования GDI+ из картинки
            Graphics gfx = Graphics.FromImage(text_bmp);
            // ! Очищаем поверхность рисования цветом
            gfx.Clear(Color.Beige);
            // ! Создаем шрифт
            Font font = new Font(FontFamily.GenericSerif, 14.0f);
            // ! Отрисовываем строку в поверхность рисования (в картинку)
            gfx.DrawString("Привет, Мир!", font, Brushes.Black, new PointF(30, 30));
            // ! Вытягиваем данные из картинки
            BitmapData data = text_bmp.LockBits(new Rectangle(0, 0, text_bmp.Width, text_bmp.Height), ImageLockMode.ReadOnly, System.Drawing.Imaging.PixelFormat.Format32bppArgb);

            // ! Включаем тектстурирование
            Gl.glEnable(Gl.GL_TEXTURE_2D);
            // ! Генерируем тектурный ID
            Gl.glGenTextures(1, out texture_text);
            // ! Делаем текстуру текущей
            Gl.glBindTexture(Gl.GL_TEXTURE_2D, texture_text);
            // ! Настраиваем свойства текстура
            Gl.glTexParameteri(Gl.GL_TEXTURE_2D, Gl.GL_TEXTURE_MAG_FILTER, Gl.GL_LINEAR);
            Gl.glTexParameteri(Gl.GL_TEXTURE_2D, Gl.GL_TEXTURE_MIN_FILTER, Gl.GL_LINEAR);
            Gl.glTexEnvf(Gl.GL_TEXTURE_ENV, Gl.GL_TEXTURE_ENV_MODE, Gl.GL_REPLACE);
            // ! Подгружаем данные из картинки в текстуру
            Gl.glTexImage2D(Gl.GL_TEXTURE_2D, 0, Gl.GL_RGBA, text_bmp.Width, text_bmp.Height, 0, Gl.GL_BGRA, Gl.GL_UNSIGNED_BYTE, data.Scan0);

            text_bmp.UnlockBits(data);

            // ! Включаем смешивание
            Gl.glEnable(Gl.GL_BLEND);
            Gl.glBlendFunc(Gl.GL_SRC_ALPHA, Gl.GL_ONE_MINUS_SRC_ALPHA);

            // ! Делаем текстру текущей
            Gl.glBindTexture(Gl.GL_TEXTURE_2D, texture_text);

            // ! Рисуем прямогульник с нашей тектурой, на которой текст
            Gl.glBegin(Gl.GL_QUADS);
                Gl.glTexCoord2f(0f, 1f); 
                Gl.glVertex2f(-1.0f, -1.0f);

                Gl.glTexCoord2f(1f, 1f); 
                Gl.glVertex2f(1f, -1.0f);

                Gl.glTexCoord2f(1f, 0f); 
                Gl.glVertex2f(1f, 1f);

                Gl.glTexCoord2f(0f, 0f); 
                Gl.glVertex2f(-1.0f, 1f);
            Gl.glEnd();

            Gl.glFlush();
            Invalidate();
        }
    }
}



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

Скачать проект

Полезные ссылки:
Сайт OpenTK
Оригинал примера с OpenTK
Пример с QuickFont

Нет доступа к просмотру комментариев.

^