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

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

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

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

У меня проблема вот с этим: gl.Clear(OpenGL.GL_COLOR_BUFFER_BIT | OpenGL.GL_DEPTH_BUFFER_BIT);. Вылезает ошибка: CS1061 "object" не содержит определения "GL_COLOR_BUFFER_BIT", и не удалось найти доступный метод расширения "GL_COLOR_BUFFER_BIT",...
Большое спасибо. Единственный код который прошел без каких либо ошибок. Ура!!!
Скажите пожалуйста, подскажите алгоритм по которому по заданным точкам можно определить тип многогранника, скажем это куб или прямоугольный параллелепипед. Нашел теорию по этим фигурам: https://www.mat... https://www.mat... Акцентировать внимание...
Всем у кого не работает. файл wizard.script Ещё одно упоминание Glut32 в строке "if (!VerifyLibFile(dir_nomacro_lib, _T("glut32"), _T("GLUT's"))) return false;" меняем на "if (!VerifyLibFile(dir_nomacro_lib, _T("freeglut"), _T("GLUT's"))) return...
Не получается, емаё

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

Рейтинг@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 кб

Комментарии

KiZeProgr аватар
Опубликовано KiZeProgr (не проверено) в 25. Июль 2023 - 11:29.

У меня проблема вот с этим: gl.Clear(OpenGL.GL_COLOR_BUFFER_BIT | OpenGL.GL_DEPTH_BUFFER_BIT);.
Вылезает ошибка: CS1061 "object" не содержит определения "GL_COLOR_BUFFER_BIT", и не удалось найти доступный метод расширения "GL_COLOR_BUFFER_BIT", принимающий тип "object" в качестве первого аргумента (возможно, пропущена директива using или ссылка на сборку).
Хочу с ней разобраться.