14.3 OpenGL - реализация системы частиц - часть 3

Необходимые знания:
Вам могут понадобится следующие статьи:

Оболочка программы

Разработка программы начинается с создания оболочки. Создайте окно программы и разместите на ней элемент openglsimplecontrol, как показано на рисунке 1, после чего установите его размеры 500х500. Переименуйте данный объект, дав ему имя AnT.
Уроки OpenGL + C#: Окно программы с элементами управления Рисунок 1. Окно программы с элементами управления.
Для реализации визуализации будет использоваться таймер – после инициализации окна он будет генерировать событие, называемое тиком таймера (раз в 30 миллисекунд). Добавьте элемент таймер, переименуйте экземпляр в RenderTimer и установите время тика 30 миллисекунд (как показано на рисунке 2), а также добавьте ему событие для обработки тика.
Уроки OpenGL + C#: Настройка свойств таймера для приложения Рисунок 2. Настройка свойств таймера для приложения.
Обратите внимание на значение элементов ComboBox, показанных на рисунке 3.
Уроки OpenGL + C#: Установка значения для элементов ComboBox Рисунок 3. Установка значения для элементов ComboBox.
Как и всегда, мы объявим ряд переменных, а также произведем инициализацию OpenGL. Помимо этого мы установим настройки для установки различных камер.

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


// отсчет времени 
float global_time = 0; // массив с параметрами установки камеры 
private float[,] camera_date = new float[3, 7]; 

// экземпляр класса Explosion 
private Explosion BOOOOM_1 = new Explosion(1, 10, 1, 300, 500); 

public Form1() 
{
  InitializeComponent(); 
  AnT.InitializeContexts(); 
} 

// генератор случайны чисел 
Random rnd = new Random(); 

// загрузка формы 
private void Form1_Load( object sender, EventArgs e) 
{
  // инициализация OpenGL 
  Glut.glutInit(); 
  Glut.glutInitDisplayMode( Glut.GLUT_RGB | Glut.GLUT_DOUBLE | Glut.GLUT_DEPTH); 

  Gl.glClearColor(255, 255, 255, 1); 

  Gl.glViewport(0, 0, AnT.Width, AnT.Height); 

  Gl.glMatrixMode( Gl.GL_PROJECTION); 
  Gl.glLoadIdentity(); 

  Glu.gluPerspective(45, (float)AnT.Width / (float)AnT.Height, 0.1, 200); 

  Gl.glMatrixMode( Gl.GL_MODELVIEW); 
  Gl.glLoadIdentity(); 

  Gl.glEnable( Gl.GL_DEPTH_TEST); 
  Gl.glEnable( Gl.GL_LIGHTING); 
  Gl.glEnable( Gl.GL_LIGHT0); 
  Gl.glEnable( Gl.GL_COLOR_MATERIAL); 

  // установка начальных значений элементов comboBox 
  comboBox1.SelectedIndex = 1; 
  comboBox2.SelectedIndex = 0; 

  // позиция камеры 1: 

  camera_date[0,0] = -3; 
  camera_date[0,1] = 0; 
  camera_date[0,2] = -20; 
  camera_date[0,3] = 0; 
  camera_date[0,4] = 1; 
  camera_date[0,5] = 0; 
  camera_date[0,6] = 0; 

  // позиция камеры 2: 

  camera_date[1, 0] = -3; 
  camera_date[2, 1] = 2; 
  camera_date[1, 2] = -20; 
  camera_date[1, 3] = 30; 
  camera_date[1, 4] = 1; 
  camera_date[1, 5] = 0; 
  camera_date[1, 6] = 0; 

  // позиция камеры 3: 

  camera_date[2, 0] = -3; 
  camera_date[2, 1] = 2; 
  camera_date[2, 2] = -20; 
  camera_date[2, 3] = 30; 
  camera_date[2, 4] = 1; 
  camera_date[2, 5] = 1; 
  camera_date[2, 6] = 0; 

  // активация таймера 
  RenderTimer.Start(); 
}

Работа программы довольно проста:

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


public partial class Form1 : Form 
{
  // отсчет времени 
  float global_time = 0; // массив с параметрами установки камеры 
  private float[,] camera_date = new float[3, 7]; 

  // экземпляр класса Explosion 
  private Explosion BOOOOM_1 = new Explosion(1, 10, 1, 300, 500); 

  public Form1() 
  {
    InitializeComponent(); 
    AnT.InitializeContexts(); 
  } 

  // генератор случайны чисел 
  Random rnd = new Random(); 

  // загрузка формы 
  private void Form1_Load( object sender, EventArgs e) 
  {
  // инициализация OpenGL 
    Glut.glutInit(); 
    Glut.glutInitDisplayMode( Glut.GLUT_RGB | Glut.GLUT_DOUBLE | Glut.GLUT_DEPTH); 

    Gl.glClearColor(255, 255, 255, 1); 

    Gl.glViewport(0, 0, AnT.Width, AnT.Height); 

    Gl.glMatrixMode( Gl.GL_PROJECTION); 
    Gl.glLoadIdentity(); 

    Glu.gluPerspective(45, (float)AnT.Width / (float)AnT.Height, 0.1, 200); 

    Gl.glMatrixMode( Gl.GL_MODELVIEW); 
    Gl.glLoadIdentity(); 

    Gl.glEnable( Gl.GL_DEPTH_TEST); 
    Gl.glEnable( Gl.GL_LIGHTING); 
    Gl.glEnable( Gl.GL_LIGHT0); 
    Gl.glEnable( Gl.GL_COLOR_MATERIAL); 

    // установка начальных значений элементов comboBox 
    comboBox1.SelectedIndex = 1; 
    comboBox2.SelectedIndex = 0; 

    // позиция камеры 1: 
    camera_date[0,0] = -3; 
    camera_date[0,1] = 0; 
    camera_date[0,2] = -20; 
    camera_date[0,3] = 0; 
    camera_date[0,4] = 1; 
    camera_date[0,5] = 0; 
    camera_date[0,6] = 0; 

    // позиция камеры 2: 
    camera_date[1, 0] = -3; 
    camera_date[2, 1] = 2; 
    camera_date[1, 2] = -20; 
    camera_date[1, 3] = 30; 
    camera_date[1, 4] = 1; 
    camera_date[1, 5] = 0; 
    camera_date[1, 6] = 0; 

    // позиция камеры 3: 
    camera_date[2, 0] = -3; 
    camera_date[2, 1] = 2; 
    camera_date[2, 2] = -20; 
    camera_date[2, 3] = 30; 
    camera_date[2, 4] = 1; 
    camera_date[2, 5] = 1; 
    camera_date[2, 6] = 0; 

    // активация таймера 
    RenderTimer.Start(); 
  } 

  // отклик таймера 
  private void RenderTimer_Tick( object sender, EventArgs e) 
  {
    // отсчитываем время 
    global_time += (float)RenderTimer.Interval / 1000; 
    // вызываем функцию отрисовки 
    Draw(); 
  } 

  // функция отрисовки сцены 
  private void Draw() 
  {
    // в зависимости от установленного режима отрисовываем сцену в черном или белом цвете 
    if (comboBox2.SelectedIndex == 0) 
    {
      // цвет очистки окна 
      Gl.glClearColor(255, 255, 255, 1); 
    } 
    else 
    {
      Gl.glClearColor(0, 0, 0, 1); 
    } 

    Gl.glClear( Gl.GL_COLOR_BUFFER_BIT | Gl.GL_DEPTH_BUFFER_BIT); 

    Gl.glLoadIdentity(); 

    // в зависимости от установленного режима отрисовываем сцену в черном или белом цвете 
    if (comboBox2.SelectedIndex == 0) 
    {
      // цвет рисования 
      Gl.glColor3d(0, 0, 0); 
    } 
    else 
    {
      Gl.glColor3d(255,255,255); 
    } 

    Gl.glPushMatrix(); 

    // определяем установленную камеру 
    int camera = comboBox1.SelectedIndex; 

    // используем параметры для установленной камеры 
    Gl.glTranslated(camera_date[camera, 0], camera_date[camera, 1], camera_date[camera, 2]); 
    Gl.glRotated(camera_date[camera, 3], camera_date[camera, 4], camera_date[camera, 5], camera_date[camera, 6]); 

    Gl.glPushMatrix(); 

    // отрисовываем сеточную плоскость, которая нам будет напоминать, где находится земля ) 
    DrawMatrix(5); 

    // выполняем просчет взрыва 
    BOOOOM_1.Calculate(global_time); 

    Gl.glPopMatrix(); 

    Gl.glPopMatrix(); 
    Gl.glFlush(); 

    // обновляем окно 
    AnT.Invalidate(); 
  } 

  // функция для отрисовки матрицы 
  private void DrawMatrix( int x) 
  {
    float quad_size = 1; 

    // две последовательные линии после пересечения создадут "матрицу", чтобы мы могли понимать, где находится земля 
    Gl.glBegin( Gl.GL_LINES); 

    for ( int ax = 0; ax < x+1; ax++) 
    {
      Gl.glVertex3d(quad_size * ax, 0, 0); 
      Gl.glVertex3d(quad_size * ax, 0, quad_size * x); 
    } 

    for ( int bx = 0; bx < x+1; bx++) 
    {
      Gl.glVertex3d(0, 0, quad_size * bx); 
      Gl.glVertex3d(quad_size * x, 0, quad_size * bx); 
    } 

    Gl.glEnd(); 
  } 

  // обработка кнопки, реализующей взрыв 
  private void button1_Click( object sender, EventArgs e) 
  {
    Random rnd = new Random(); 
    // устанавливаем новые координаты взрыва 
    BOOOOM_1.SetNewPosition(rnd.Next(1, 5), rnd.Next(1, 5), rnd.Next(1, 5)); 
    // случайную силу 
    BOOOOM_1.SetNewPower(rnd.Next(20,80)); 
    // и активируем сам взрыв 
    BOOOOM_1.Boooom(global_time);
  }
} 
Прикрепленные файлы для скачивания:

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

^