Оболочка программы
Разработка программы начинается с создания оболочки. Создайте окно программы и разместите на ней элемент openglsimplecontrol, как показано на рисунке 1, после чего установите его размеры 500х500. Переименуйте данный объект, дав ему имя AnT.Рисунок 1. Окно программы с элементами управления.
Для реализации визуализации будет использоваться таймер – после инициализации окна он будет генерировать событие, называемое тиком таймера (раз в 30 миллисекунд). Добавьте элемент таймер, переименуйте экземпляр в RenderTimer и установите время тика 30 миллисекунд (как показано на рисунке 2), а также добавьте ему событие для обработки тика.
Рисунок 2. Настройка свойств таймера для приложения.
Обратите внимание на значение элементов ComboBox, показанных на рисунке 3.
Рисунок 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);
}
}