Уроки, алгоритмы, программы, примеры

Вход на сайт

Материалы по разделам

Построения
на плоскости (2D)
Графика
в пространстве (3D)
Вычислительная
геометрия
Физическое
моделирование
Фрактальная
графика

Новые комментарии

torrvic, возможно, Вам нужно добавить -lGLU
Извините за тупой вопрос. У меня при сборке Вашего примера выходит ошибка: "undefined reference to gluLookAt". Не могу найти в какой библиотеке находится эта функция. У меня задано: -lGL -lglut ... Искал в /usr/lib таким образом: nm lib*so* | grep...
Здравствуйте. Спасибо за проект. У меня вопрос, по какой причине определение принадлежности точки многоугольнику работает некорректно, если координаты из больших чисел состоят, например: int[] vertex = new int[] {...
Сейчас проверила нашла причину не запускания // Создание контекста воспроизведения OpenGL и привязка его к панели на форме OpenGLControl1:=TOpenGLControl.Create(Self); with OpenGLControl1 do begin Name:='OpenGLControl1'; //вот тут...
Ну..кажется что то пошло не так http://pp.usera...

Счетчики и рейтинг

Рейтинг@Mail.ru
Среда программирования: 
Microsoft C#

В данной программе будет реализовано создание пирамиды с переливающимися гранями, куба с разноцветными гранями, их одновременное разобщенное вращение с помощью различных методов технологии OpenGL для языка С# - SharpGL - в проекте Windows Forms.

Работа с OpenGL в WPF почти ничем не отличается, поэтому смело можно использовать описанный в данном уроке материал. О том, как подключить SharpGL в WPF проекте или проекте Windows Forms, читайте тут http://grafika.me/lessons.

Из новых методов стоит отметить gl.Flush();. Этот метод контролирует правильное обновление изображений.

1. Создадим пирамиду

Первое, что необходимо сделать - нарисовать грани. Однако для реализации переливающегося цвета граней нам понадобится задавать цвет каждой вершины отдельно, которые в данном примере будут окрашены в красный, синий и зеленый цвета.
Так как в предыдущем уроке уже было реализовано что-то подобное, сразу зададим вращение нашему объекту. Создадим переменную - значение угла поворота, и будем менять ее на каждой итерации отрисовки. Сам поворот реализуется методом gl.Rotate(angle, X.Xf, Y.Yf, Z.Zf);, где (X.Xf, Y.Yf, Z.Zf) - координаты вектора на оси, вокруг которой будет осуществляться вращение. Для начала просто посмотрим на пирамиду сбоку, для этого просто повращаем фигуру вокруг ее оси Y.

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using SharpGL;
 
namespace SharpGL
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }
        float rtri = 0;
 
        private void openGLControl1_OpenGLDraw(object sender, RenderEventArgs args)
        {
            // Создаем экземпляр
            OpenGL gl = this.openGLControl1.OpenGL;
            // Очистка экрана и буфера глубин
            gl.Clear(OpenGL.GL_COLOR_BUFFER_BIT | OpenGL.GL_DEPTH_BUFFER_BIT);
 
            // Пирамида /////////////////////////////
            // Сбрасываем модельно-видовую матрицу
            gl.LoadIdentity();
            // Сдвигаем перо влево от центра и вглубь экрана
            gl.Translate(0.0f, 0.0f, -5.0f);
            // Вращаем пирамиду вокруг ее оси Y
            gl.Rotate(rtri, 0.0f, 1.0f, 0.0f);
            // Рисуем треугольники - грани пирамиды
            gl.Begin(OpenGL.GL_TRIANGLES);
 
            // Front
            gl.Color(1.0f, 0.0f, 0.0f);
            gl.Vertex(0.0f, 1.0f, 0.0f);
            gl.Color(0.0f, 1.0f, 0.0f);
            gl.Vertex(-1.0f, -1.0f, 1.0f);
            gl.Color(0.0f, 0.0f, 1.0f);
            gl.Vertex(1.0f, -1.0f, 1.0f);
            // Right
            gl.Color(1.0f, 0.0f, 0.0f);
            gl.Vertex(0.0f, 1.0f, 0.0f);
            gl.Color(0.0f, 1.0f, 0.0f);
            gl.Vertex(1.0f, -1.0f, -1.0f);
            gl.Color(0.0f, 0.0f, 1.0f);
            gl.Vertex(1.0f, -1.0f, 1.0f);
            // Back
            gl.Color(1.0f, 0.0f, 0.0f);
            gl.Vertex(0.0f, 1.0f, 0.0f);
            gl.Color(0.0f, 1.0f, 0.0f);
            gl.Vertex(1.0f, -1.0f, -1.0f);
            gl.Color(0.0f, 0.0f, 1.0f);
            gl.Vertex(-1.0f, -1.0f, -1.0f);
            // Left
            gl.Color(1.0f, 0.0f, 0.0f);
            gl.Vertex(0.0f, 1.0f, 0.0f);
            gl.Color(0.0f, 1.0f, 0.0f);
            gl.Vertex(-1.0f, -1.0f, 1.0f);
            gl.Color(0.0f, 0.0f, 1.0f);
            gl.Vertex(-1.0f, -1.0f, -1.0f);
 
            gl.End();
            // Контроль полной отрисовки следующего изображения
            gl.Flush();
            // Меняем угол поворота 
            rtri -= 3.0f;
        }
    }
}

Вот что получим на выходе:

Изменим на gl.Rotate(rtri, 0.0f, 0.0f, 1.0f);, т.е. покрутим вокруг оси Z. Естественно, получим просто треугольник, который вращается вокруг своей вершины, в действительности - это вершина пирамиды, не принадлежащая основанию.

Самое интересное - вращение вокруг оси X. Увидим, что дна у пирамиды нет, т.к. оно и не было изначально отрисовано. Тем не менее, грани внутри пирамиды также переливаются.

2. Вращение куба.

Отрисуем грани с помощью метода gl.Begin(OpenGL.GL_QUADS);, зададим вращение вокруг оси (1.0, 1.0, 1.0).

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using SharpGL;
 
namespace SharpGL
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }
        float rquad = 0;
 
        private void openGLControl1_OpenGLDraw(object sender, RenderEventArgs args)
        {
            // Создаем экземпляр
            OpenGL gl = this.openGLControl1.OpenGL;
            // Очистка экрана и буфера глубин
            gl.Clear(OpenGL.GL_COLOR_BUFFER_BIT | OpenGL.GL_DEPTH_BUFFER_BIT);
 
            // Куб ///////////////////////////////
            // Сбрасываем модельно-видовую матрицу 
            gl.LoadIdentity();
            // Сдвигаем перо вправо от центра и вглубь экрана, но уже дальше
            gl.Translate(0.0f, 0.0f, -10.0f);
            // Вращаем куб вокруг его диагонали
            gl.Rotate(rquad, 1.0f, 1.0f, 1.0f);
            // Рисуем квадраты - грани куба
            gl.Begin(OpenGL.GL_QUADS);
 
            // Top
            gl.Color(0.0f, 1.0f, 0.0f);
            gl.Vertex(1.0f, 1.0f, -1.0f);
            gl.Vertex(-1.0f, 1.0f, -1.0f);
            gl.Vertex(-1.0f, 1.0f, 1.0f);
            gl.Vertex(1.0f, 1.0f, 1.0f);
            // Bottom
            gl.Color(1.0f, 0.5f, 0.0f);
            gl.Vertex(1.0f, -1.0f, 1.0f);
            gl.Vertex(-1.0f, -1.0f, 1.0f);
            gl.Vertex(-1.0f, -1.0f, -1.0f);
            gl.Vertex(1.0f, -1.0f, -1.0f);
            // Front
            gl.Color(1.0f, 0.0f, 0.0f);
            gl.Vertex(1.0f, 1.0f, 1.0f);
            gl.Vertex(-1.0f, 1.0f, 1.0f);
            gl.Vertex(-1.0f, -1.0f, 1.0f);
            gl.Vertex(1.0f, -1.0f, 1.0f);
            // Back
            gl.Color(1.0f, 1.0f, 0.0f);
            gl.Vertex(1.0f, -1.0f, -1.0f);
            gl.Vertex(-1.0f, -1.0f, -1.0f);
            gl.Vertex(-1.0f, 1.0f, -1.0f);
            gl.Vertex(1.0f, 1.0f, -1.0f);
            // Left
            gl.Color(0.0f, 0.0f, 1.0f);
            gl.Vertex(-1.0f, 1.0f, 1.0f);
            gl.Vertex(-1.0f, 1.0f, -1.0f);
            gl.Vertex(-1.0f, -1.0f, -1.0f);
            gl.Vertex(-1.0f, -1.0f, 1.0f);
            // Right
            gl.Color(1.0f, 0.0f, 1.0f);
            gl.Vertex(1.0f, 1.0f, -1.0f);
            gl.Vertex(1.0f, 1.0f, 1.0f);
            gl.Vertex(1.0f, -1.0f, 1.0f);
            gl.Vertex(1.0f, -1.0f, -1.0f);
 
            gl.End();
            // Контроль полной отрисовки следующего изображения
            gl.Flush();
            // Меняем угол поворота 
            rquad -= 3.0f;
        }
    }
}

Получим такую анимацию:

3. Совместное вращение

Из приведенных примеров становится ясно, что вращение - достаточно легкая тема, особенно если реализовывать это с помощью технологии OpenGL. Для того, чтобы получить справа ту же вращающуюся пирамиду и тот же куб, нам необходимо скомпоновать примеры и отдельно задать координаты пера.

            ...
            // Пирамида. Очищаем матрицу. Сдвигаем перо влево от центра и вглубь
            gl.LoadIdentity();
            Translate(-1.5f, 0.0f, -5.0f);
            ...
            // Куб. Очищаем матрицу. Сдвигаем перо вправо от центра и вглубь
            gl.LoadIdentity();
            Translate( 1.5f, 0.0f, -5.0f);
            ...
            gl.End();

Для получения анимации просто надо просто скачать проект и запустить.

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

Прикрепленный файлРазмер
Ametov_SharpGL.zip390.27 кб