Esate.ru
Esate.ru Уроки Программирование 3D Уроки OpenGL + C#Вывод 2D треугольника с разложением цветового спектра в OpenGl и C#.

Уроки OpenGL + C#

Выполняя главы последовательно, вы ознакомитесь с основами синтаксиса C#, увидите, как просто создавать оконные приложения с помощью .net, познакомитесь с библиотекой Tao, которая обеспечивает поддержку OpenGl в среде .NET, изучите основы 2D визуализации, работу как с примитивами, так и принцип загрузки и построения сложных 3D моделей , экспортированных из 3D редакторов.

5.3 Вывод 2D треугольника с активным управлением разложением цветового спектра.

В данной части главы, мы более подробно познакомимся с методами визуализации 2D примитивов.
Пример, рассматриваемый в данной главе, будет немного более сложным, но при этом динамичным и более интересным.
Сейчас же мы попробуем нарисовать двухмерный треугольник. Его особенность будет заключаться в том, что при установке каждой его вершины, мы будем задавать отдельный цвет, умножаемый на некоторую переменную. Таким образом, цвет на протяжении плоскости треугольника будет интерполироваться между цветов вершин. Таким образом, мы получим разложенный спектр цветов на треугольнике.

Также мы внесем в код управляемые переменные, которые смогут влиять на установку цвета в определенной вершине, и тем самым в реальном времени посмотреть, как может быть разложен различный цветовой спектр.

Итак, приступим. В первую очередь создайте новый проект и реализуйте на нем систему визуализации, основанную на объекте SimpleOpenGLControl и подключении ссылок к библиотекам Tao, как это было рассказано в главе 4.4. Настройки инициализации OpenGL (код функции Form1_Load будет соответствовать коду, представленному в главе 4.4).

На всякий случай код функции-обработчика события Form1_Load:

/*http://esate.ru, Anvi*/


private void Form1_Load(object sender, EventArgs e) 
{ 

  // инициализация библиотеки GLUT 
  Glut.glutInit(); 
  // инициализация режима окна 
  Glut.glutInitDisplayMode(Glut.GLUT_RGB | Glut.GLUT_DOUBLE); 

  // устанавливаем цвет очистки окна 
  Gl.glClearColor(255, 255, 255, 1); 

  // устанавливаем порт вывода, основываясь на размерах элемента управления AnT 
  Gl.glViewport(0, 0, AnT.Width, AnT.Height); 

  // устанавливаем проекционную матрицу 
  Gl.glMatrixMode(Gl.GL_PROJECTION); 
  // очищаем ее 
  Gl.glLoadIdentity(); 

  // теперь необходимо корректно настроить 2D ортогональную проекцию 
  // в зависимости от того, какая сторона больше 
  // мы немного варьируем то, как будут сконфигурированы настройки проекции 
  if (AnT.Width <= AnT.Height) 
    Glu.gluOrtho2D (0.0, 30.0, 0.0, 30.0 * (float)AnT.Height / (float)AnT.Width); 
  else 
    Glu.gluOrtho2D(0.0, 30.0 * (float)AnT.Width / (float)AnT.Height, 0.0, 30.0); 

  // переходим к объектно-видовой матрице 
  Gl.glMatrixMode(Gl.GL_MODELVIEW);

} 



Помимо этого, нам понадобится добавить на окно программы дополнительные элементы управления: 3 элемента TrackBar (вы можете найти их в Панели элементов (ToolBox) в конце самого первого свитка («Все формы Windows Forms»), три элемента Label, которые будут находиться над элементами TrackBar и содержать названия коэффициентов, которыми будут управлять данные TrackBar’.

Также под каждым элементом TrackBar будут находиться по одному дополнительному элементу label для вывода текущего значения параметра, которым управляет данный ползунок.

Сверху будут находиться элементы label1, label2, label3, а снизу label4, label5, label6.

Разместите все элементы, как показано на рисунке 1. Для того чтобы элемент TrackBar стал вертикальным, необходимо в его свойствах указать параметр Orientation равным Vertical.
Уроки OpenGL + C#: Пример расположения элементов на форме Рисунок 1. Пример расположения элементов на форме.
В свойствах TackBar'ов необходимо указать диапазон значений:

Minimum - 0
Maximum - 1000
TickFrequensy - 10 (количество позиций между отметками)

Для первого TackBar'а установите значение (Value) равное 1000. Для остальных – 0.

Выполните двойной щелчок левой клавишей мыши по каждому TrackBar'у, чтобы создать функции обработчики события перемещения ползунка пользователем.

В начале класса, отвечающего за нашу форму, добавьте следующую строку (для порядка и исключения путаницы в коде разместите эту строку перед функцией Form1_Load).

/*http://esate.ru, Anvi*/

double a = 1, b = 0, c = 0; 



Теперь реализуем функцию, отвечающую за рисование. Назовем ее Draw. Эта функция будет вызываться при нажатии на кнопку «Визуализировать» и при перемещении управляющих ползунков на TrackBar'ах, так как при этом будут изменяться коэффициенты a, b, c и наша сцена будет нуждаться в повторной визуализации.

Код функции с подробными комментариями:

/*http://esate.ru, Anvi*/


// функция Draw 
private void Draw() 
{ 

  // очищаем буфер цвета 
  Gl.glClear(Gl.GL_COLOR_BUFFER_BIT); 

  // активируем рисование в режиме GL_TRIANGLES, при котором задание 
  // трех вершин с помощью функции glVertex2d или glVertex3d 
  // будет объединяться в трехгранный полигон (треугольник) 

  Gl.glBegin(Gl.GL_TRIANGLES); 

  // устанавливаем параметр цвета, основанный на параметрах a b c 
  Gl.glColor3d(a, b, c); 
  // рисуем вершину в координатах 5,5 
  Gl.glVertex2d(5.0, 5.0); 
  // устанавливаем параметр цвета, основанный на параметрах с a b 
  Gl.glColor3d(c, a, b); 
  // рисуем вершину в координатах 25,5 
  Gl.glVertex2d(25.0, 5.0); 
  // устанавливаем параметр цвета, основанный на параметрах b c a 
  Gl.glColor3d(b, c, a); 
  // рисуем вершину в координатах 25,5 
  Gl.glVertex2d(5.0, 25.0); 

  // завершаем режим рисования примитивов 
  Gl.glEnd(); 

  // дожидаемся завершения визуализации кадра 
  Gl.glFlush(); 

  // обновляем изображение в элементе AnT 
  AnT.Invalidate();

} 



Функции обработчики перемещения ползунка в TrackBar'ах будут выглядеть следующим образом:

/*http://esate.ru, Anvi*/


private void trackBar1_Scroll(object sender, EventArgs e) 
{ 
  // генерация коэффициента 
  a = (double)trackBar1.Value / 1000.0; 
  // вывод значения коэффициента, управляемого данным ползунком. 
  // (под TrackBa'ом) 
  label4.Text = a.ToString(); 
} 

private void trackBar2_Scroll(object sender, EventArgs e) 
{ 
  // генерация коэффициента 
  b = (double)trackBar2.Value / 1000.0; 
  // вывод значения коэффициента, управляемого данным ползунком. 
  // (под TrackBa'ом) 
  label5.Text = b.ToString(); 
} 

private void trackBar3_Scroll(object sender, EventArgs e) 
{ 
  // генерация коэффициента 
  c = (double)trackBar3.Value / 1000.0; 
  // вывод значения коэффициента, управляемого данным ползунком. 
  // (под TrackBa'ом) 
  label6.Text = c.ToString(); 
} 



Для корректной визуализации в том случае, если, например, наше окно перекроет какое-либо другое, мы добавим в нашу форму объект Таймер. Он будет отсчитывать промежутки времени таким образом, чтобы примерно 40 раз в секунду перерисовывать содержимое нашего окна.

Для того чтобы добавить объект, перейдите к окну ToolBox, выберите свитке «Компоненты» элемент Timer (рис. 2) и перетащите на форму.
Уроки OpenGL + C#: Добавление элемента Timer для визуализации Рисунок 2. Добавление элемента Timer для визуализации.
Место, куда вы перетащите этот элемент не важно, он не занимает его на форме и отобразится в полоске таких «не занимающих место» объектов под формой.

Щелкните по нему и перейдите в его свойства.

Смените параметр name на значение RenderTimer, а параметр Interval на значение 25 (раз в 25 миллисекунд будет вызываться событие OnTimer).

Теперь щелкните по нему двойным щелчком левой клавиши мыши. Создатся функция обработчик события OnTimer. Отсюда мы будем вызывать функцию Draw:

/*http://esate.ru, Anvi*/


  private void RenderTimer_Tick(object sender, EventArgs e) 
  { 
    // функция визуализации 
    Draw();
  } 
  


Кнопка «Визуализировать» будет отвечать за активацию этого таймера. Для этого будет использоваться функция Start:

/*http://esate.ru, Anvi*/

// обработчики кнопки "Визуализировать" 
private void button1_Click(object sender, EventArgs e) 
{ 
  // страт таймера, отвечающего за вызов функции 
  // визуализирующей кадр 
  RenderTimer.Start();
} 



И в заключении, назначьте обработчик кнопке «Выйти»:

/*http://esate.ru, Anvi*/

// обработчики кнопки "Выйти" 
private void button2_Click(object sender, EventArgs e) 
{ 
  // выход из приложения 
  Application.Exit();
} 



Вот и все, если вы правильно выполнили все инструкции, то теперь после компиляции и запуска программы вы сможете управлять разложением спектра на треугольнике (рис. 3 и 4).
Уроки OpenGL + C#: Пример визуализации треугольника с разложенным спектром в OpenGL C# Рисунок 3. Пример визуализации треугольника с разложенным спектром в OpenGL C#.
Уроки OpenGL + C#: Еще один пример визуализации треугольника с измененными коэффициентами, влияющими на цвета в вершинах Рисунок 4. Еще один пример визуализации треугольника с измененными коэффициентами, влияющими на цвета в вершинах.


Источник: Esate.ru
08 Января 2010


Комментарии (из ветки форума)


Мне нравится0
Помогите пожалуйста! Начал осваивать OpenGL по вашим урокам первая программа прекрасно работает, а вот с этим треугольником выдаёт ошибку (на фотографии - No device or rendering context available!)
error.PNG (101.43 КБ)
Мне нравится0
По какой причине это может происходить, и как сделать чтобы заработала программа?
Мне нравится1
Извините за беспокойство, но проблема решилась:
Первая прога:
Код
public Form1()
        {
            InitializeComponent();
            this.AnT.InitializeContexts();
        }
Вторая:
Код
 public Form1()
        {
            InitializeComponent();
        }
Забыл написать this.AnT.InitializeContexts();
Мне нравится0
Добрый вечер. Все очень понятно и все работает. Только объясните мне кое-что...
Что делает строка [SIZE=16pt]label6.Text = c.ToString(); [/SIZE]
И с другими порядковыми номерами, соответственно.
Мне нравится1
Привет.

Если на примере строки
Код
label6.Text = c.ToString();
то тут все просто:

На форме есть ползунки A.B,C.
Под ползунками на форме размещены элементы типа label, в который выводится значение переменных a,b,c.

Переменные a,b,c. объявлены в коде, у них тип double. Соотв. здесь значение переменной c приводится к строке (из типа double), с помощью функции ToString().
А затем это значение записывается в свойство .Text элемента label6.

P/S/ у каждого элемента label, размещенного на форме, есть имя экземпляра, через которое можно обратиться к его свойствам.
Мне нравится0
Цитата
noname написал:
Привет.

Если на примере строки
Код
 label6.Text = c.ToString(); 
то тут все просто:

На форме есть ползунки A.B,C.
Под ползунками на форме размещены элементы типа label, в который выводится значение переменных a,b,c .

Переменные a,b,c. объявлены в коде, у них тип double. Соотв. здесь значение переменной c приводится к строке (из типа double), с помощью функции ToString().
А затем это значение записывается в свойство .Text элемента label6.

P/S/ у каждого элемента label, размещенного на форме, есть имя экземпляра, через которое можно обратиться к его свойствам.
Да емае. вот я затупил. Спасибо милсдарь)
Мне нравится0
Замечательная статья!
Однако, хотелось бы добавить, что куда целесообразнее было бы использовать событие Paint у элемента управления нежели таймер.


Оставить сообщение:

Авторизируйтесь или Зарегистрируйтесь
чтобы оставлять комментарии.

OpenGL

OpenGL

OpenGL (Open Graphics Library — открытая графическая библиотека, графический API) — спецификация, определяющая независимый от языка программирования платформонезависимый программный интерфейс для написания приложений, использующих двумерную и трёхмерную компьютерную графику.

Регистрация

Регистрируясь, вы принимаете правила сайта. Если вы не получили код подтв. регистрации - не забудьте проверить папку спам.
Логин*
Email*
Пароль*
Подтверждение пароля*
 
Логин*
Код*
 

Восстановление пароля

Пожалуйста, заполните поля, после чего вы получите код подтверждения на ваш E-mail. Если код не пришел в течении нескольких минут - проверьте папку спам.
Логин

или Email
 
Логин*
Код подтверждения*
Новый пароль*
Подтверждение пароля*
 

Авторизация

Пожалуйста, авторизуйтесь, для входа на сайт с помощью соц. сети:
  • Используйте вашу учетную запись на Facebook.com для входа на сайт.
  • Используйте вашу учетную запись VKontakte для входа на сайт.
  • Используйте вашу учетную запись Google для входа на сайт.

или с помощью аккаунта на сайте:

Логин
Пароль