Внимание!

Эта публикация перенесена в раздел уроков по адресу C#/Tao.framework. Простой способ отобразить текст в OpenGL.
К ней прикреплена новая отдельная ветка комментариев форума, которую вы можетет найти после текста публикации.
Обсуждение публикации рекуомендуется вести по новому адресу, который указан выше.

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

Отрисовка текста в OpenGL, обычно нетривиальная задача, особенно для новичков. Стандартно эта задача сводится к рисованию прямоугольников с натянутой текстурой, на которой отображена та или иная буква. Располагая, которые, относительно друг, друга собираются в слова.
Когда-то, когда я еще учился в Академии, мы делали на ASP.NET капчу отрисовывая строки текста и линии в картинку. На C# это делается очень легко, встроенными методами класса Graphics. Им и воспользуемся для рисования нашего текста.
В этом посте я покажу очень примитивный и к сожалению не масштабируемый пример.=)[spoiler]

Я довольно долго не программировал на C#, так что чтобы не сильно долго вспоминать, как и что, я переделал пример рендера текста из документации 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 пример
0       2239        06.08.2012        2

Внимание!

Эта публикация перенесена в раздел уроков по адресу C#/Tao.framework. Простой способ отобразить текст в OpenGL.
К ней прикреплена новая отдельная ветка комментариев форума, которую вы можетет найти после текста публикации.
Обсуждение публикации рекуомендуется вести по новому адресу, который указан выше.

0  
18.09.2012 00:00:00
Вот всё таки Tao или OpenTK?
Они оба уже годами не поддерживаются. Какой лучше?
0  
21.09.2012 00:00:00
Tao уже давно не поддерживается, c 2008 кажись. А OpenTK вроде еще поддерживается, но последний релиз был в 2010.

Что лучше, я сказать с точностью не могу, все зависит от задачи которую вы решаете. Но если выбирать, с чего начинать осваивать OpenGL, я бы посоветовал OpenTK, для старта.
Хотя если не выбирать из этих двух вариантов, мое мнение лучше начинать на С++ c freeglut, ИМХО.
^