| исключение в лабораторной работе № 3 |
Windows Forms и XNA 3.0
Визуализация объекта, использующего эффект
Визуализация примитивов, использующих эффект, начинается с вызова метода effect.Begin() объекта эффекта. Далее приложение должно перебрать все проходы текущей техники (коллекция effect.CurrentTechnique.Passes ) и вызвать метод pass.Begin() для каждого прохода. Внутри прохода нужно визуализировать примитивы с использованием метода device.DrawUserPrimitives(). Визуализацию прохода нужно закончить вызовом метода pass.End(). По окончанию визуализации всего эффекта приложение должно вызвать метод effect.End().
-
Через контекстное меню
перейдите в режим View Designer формы, выделите на ней объект xnaPanel1 и
откройте панель Properties в
режиме Events
-
Найдите событие Paint объекта xnaPanel1 и
двойным щелчком на его поле справа создайте обработчик, который заполните
так
private void xnaPanel1_Paint(object sender, PaintEventArgs e)
{
if (closing)
return;
try
{
if (device.GraphicsDeviceStatus == GraphicsDeviceStatus.Lost)
throw new DeviceLostException();
if (device.GraphicsDeviceStatus == GraphicsDeviceStatus.NotReset)
device.Reset(presentParams);
// Очищаем область экрана
device.Clear(XNAGraphics.Color.CornflowerBlue);
device.RenderState.CullMode = CullMode.None;
device.VertexDeclaration = decl;
// Задаем координаты вершин из установленного в группе панелей цвета
vertices[0] = new VertexPositionColor(new Vector3(0.0f, 0.8f, 0.0f), new XNAGraphics.Color(
vertex1Color.BackColor.R, vertex1Color.BackColor.G, vertex1Color.BackColor.B));
vertices[1] = new VertexPositionColor(new Vector3(0.8f, -0.8f, 0.0f), new XNAGraphics.Color(
vertex2Color.BackColor.R, vertex2Color.BackColor.G, vertex2Color.BackColor.B));
vertices[2] = new VertexPositionColor(new Vector3(-0.8f, -0.8f, 0.0f), new XNAGraphics.Color(
vertex3Color.BackColor.R, vertex3Color.BackColor.G, vertex3Color.BackColor.B));
effect.Begin();
foreach(EffectPass pass in effect.CurrentTechnique.Passes)
{
pass.Begin();
device.DrawUserPrimitives(PrimitiveType.TriangleList, vertices, 0, vertices.Length / 3);
pass.End();
}
effect.End();
device.Present();
}
catch (DeviceNotResetException)
{
Invalidate();
}
catch (DeviceLostException)
{
closing = true; // Больше не выполнять OnPaint()
string title = "Сбой графического устройства";
string message = "Работа программы будет завершена.\n"
+ "Закройте все ненужные программы\n"
+ "и повторите запуск этого приложения";
MessageBox.Show(message, title, MessageBoxButtons.OK, MessageBoxIcon.Stop);
Application.Idle += new EventHandler(Application_Idle);
return;
}
catch (Exception ext) // Все другие исключения
{
closing = true;
MessageBox.Show(ext.Message);
Application.Idle += Application_Idle;
}
}-
Выделите на форме объект xnaPanel1 и
через панель Properties в режиме Events создайте обработчик
события Resize, который заполните так
private void xnaPanel1_Resize(object sender, EventArgs e)
{
// Устанавливаем размеры заднего буфера по клиентской области панели
presentParams.BackBufferWidth = xnaPanel1.ClientSize.Width;
presentParams.BackBufferHeight = xnaPanel1.ClientSize.Height;
// Сбрасываем устройство и применяем к нему новые параметры
// Если окно не минимизировано
if (this.WindowState != FormWindowState.Minimized)
device.Reset(presentParams);
}-
Выделите саму форму
щелчком на ее заголовке и
через панель Properties в режиме Events создайте обработчик
события FormClosed, который заполните так
private void MainForm_FormClosed(object sender, FormClosedEventArgs e)
{
// Удаляем (освобождаем) устройство
device.Dispose();
// На всякий случай присваиваем ссылке на устройство значение null
device = null;
}-
Осторожно (чтобы не
создать обработчик) выделите все три кнопки на форме (удерживая клавишу Ctrl ) и через панель Properties в
режиме Events создайте
обработчик события Click с именем vertexColor_Click, который заполните
так
private void vertexColor_Click(object sender, EventArgs e)
{
Button button = (Button)sender;
colorDialog1.Color = button.BackColor;
if (colorDialog1.ShowDialog() == DialogResult.OK)
{
button.BackColor = colorDialog1.Color;
xnaPanel1.Invalidate();
}
}-
В панели Solution
Explorer выделите узел проекта Application2 и через контекстное меню сделайте проект
стартовым. Запустите приложение - должен получиться такой результат
Запускающее приложение
Если вы все делали так как описано, то исполнимые сборки для упражнений 1 и 2 должны находиться относительно папки решений FormsXNA в подпапках:
FormsXNA\Application1\bin\Debug\Application1.exe FormsXNA\Application2\bin\Debug\Application2.exe
В этом разделе, для тренировки, мы добавим к проекту простое приложение, запускающее сборки с выполненными упражнениями, чтобы легче было их демонстрировать.
-
Добавьте к решению
новый проект с именем StartForm и сделайте его стартовым -
Переименуйте файл формы Form1.cs в StartForm.cs и откройте
его в режиме View Designer и поместите на форму
два экземпляра компонента LinkLabel
-
Создайте для них
обработчики события LinkClicked и заполните их следующим кодом
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.IO;
namespace StartApp
{
public partial class StartForm : Form
{
System.Diagnostics.Process exe = new System.Diagnostics.Process();
String path; // Путь к папке с решением
public StartForm()
{
InitializeComponent();
path = Directory.GetCurrentDirectory();// Получаем путь к сборке StartForm
int pos = path.LastIndexOf(@"\bin\");
path = path.Substring(0, pos);// Убираем 2 последних секции пути
pos = path.LastIndexOf(@"\");
path = path.Substring(0, pos);// Убираем еще одну секцию
}
private void linkLabel1_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
{
Directory.SetCurrentDirectory(path + @"\Application1\bin\Debug");// Путь к сборке
exe.StartInfo.FileName = "Application1.exe";
System.Diagnostics.Debug.WriteLine(path); // Для отладки в окно Output
exe.Start();
}
private void linkLabel2_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
{
Directory.SetCurrentDirectory(path + @"\Application2\bin\Debug");// Путь к сборке
exe.StartInfo.FileName = "Application2.exe";
System.Diagnostics.Debug.WriteLine(path); // Для отладки в окно Output
exe.Start();
}
}
}Код будет работать при условии, что сборка стартовой формы находится в своем каталоге bin дерева решения.


