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

Обратите внимание на значение элементов ComboBox, показанных на рисунке 3.

Как и всегда, мы объявим ряд переменных, а также произведем инициализацию 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);
}
}