Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > .NET Frameworks (точка нет фреймворки) > C# (си шарп)
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 24.06.2011, 12:34   #1
ds.Dante
Старожил
 
Аватар для ds.Dante
 
Регистрация: 06.08.2009
Сообщений: 2,992
По умолчанию XNA: Рисование маслом по контролу

Второй день уже бьюсь над тем, чтобы сделать хотя бы простенькую программу с XNA. Рисование на весь экран меня не устраивает, поэтому я делаю класс, наследованный от Control.

Код:
// Ambiguity resolve
using Rectangle = Microsoft.Xna.Framework.Rectangle;

class MyGraphics: Control
{
	GraphicsDevice graphicsDevice;
	VertexBuffer buffer;
	PresentationParameters parameters = new PresentationParameters ();
	VertexPositionColor[] data =
	{
		new VertexPositionColor (new Vector3 (0, 0, 0), Color.Lime),
		new VertexPositionColor (new Vector3 (1, 1, 0), Color.Lime),
	};

	public MyGraphics ()
	{
		parameters.BackBufferWidth = Math.Max (Width, 1);
		parameters.BackBufferHeight = Math.Max (Height, 1);
		parameters.BackBufferFormat = SurfaceFormat.Color;
		graphicsDevice = new GraphicsDevice (GraphicsAdapter.DefaultAdapter, DeviceType.Hardware, Handle, parameters);
		buffer = new VertexBuffer (graphicsDevice, typeof(VertexPositionColor), data.Length, BufferUsage.Points);
		buffer.SetData<VertexPositionColor> (data);
		graphicsDevice.Vertices[0].SetSource (buffer, 0, buffer.SizeInBytes);
	}

	protected override void OnPaint (PaintEventArgs e)
	{
		parameters.BackBufferWidth = Math.Max (Width, 1);
		parameters.BackBufferHeight = Math.Max (Height, 1);
		graphicsDevice.Reset (parameters);

		Viewport viewport = new Viewport ();
		viewport.Width = Width;
		viewport.Height = Height;
		graphicsDevice.Viewport = viewport;
		graphicsDevice.Clear (Color.Black);

		graphicsDevice.DrawPrimitives (PrimitiveType.LineList, 0, data.Length);
		graphicsDevice.Present (new Rectangle (0, 0, Width, Height), null, Handle);
	}
}
Я просто пытаюсь нарисовать зелёную линию на чёрном фоне. Этот контрол я сделал путём расковыривания разных примеров, поэтому прошу обращать внимание на всякие несуразности. Пишу всё на XNA 3.1 (нужна совместимость с .NET 3.5).

Ошибка на предпоследней строчке, функция DrawPrimitives():
Цитата:
A valid vertex declaration must be set on the device before any draw operations can be performed.
Что ему ещё не хватает?
ds.Dante вне форума Ответить с цитированием
Старый 24.06.2011, 18:27   #2
Скарам
Дружите с Linq ;)
Форумчанин
 
Аватар для Скарам
 
Регистрация: 15.10.2008
Сообщений: 822
По умолчанию

Код:
 class MyGraphics : Control
    {
        GraphicsDevice graphicsDevice;
        VertexBuffer buffer;
        PresentationParameters parameters = new PresentationParameters();
        VertexDeclaration vertexDeclaration;
        VertexPositionColor[] data =
	{
		new VertexPositionColor (new Vector3 (0, 0, 0), Color.Lime),
		new VertexPositionColor (new Vector3 (100, 100, 0), Color.Lime),
	};
        BasicEffect basicEffect;

        public MyGraphics()
        {
            parameters.BackBufferWidth = Math.Max(Width, 1);
            parameters.BackBufferHeight = Math.Max(Height, 1);
            parameters.BackBufferFormat = SurfaceFormat.Color;

          
                                                  


            graphicsDevice = new GraphicsDevice(GraphicsAdapter.DefaultAdapter, DeviceType.Hardware, Handle, parameters);
            vertexDeclaration = new VertexDeclaration(graphicsDevice, VertexPositionColor.VertexElements);

            
            basicEffect = new BasicEffect(graphicsDevice, null);
            basicEffect.VertexColorEnabled = true; 

           
            buffer = new VertexBuffer(graphicsDevice,
                VertexPositionColor.SizeInBytes * (data.Length),
                BufferUsage.None);

            
            buffer.SetData<VertexPositionColor>(data);

            
            
        }

        protected override void OnPaint(PaintEventArgs e)
        {
            graphicsDevice.VertexDeclaration = vertexDeclaration;
            graphicsDevice.Vertices[0].SetSource(buffer, 0, VertexPositionColor.SizeInBytes);
          

            
            basicEffect.World = Matrix.CreateTranslation(100, 100, 0);
            

            
            basicEffect.Begin();

            foreach (EffectPass pass in basicEffect.CurrentTechnique.Passes)
            {
                pass.Begin();
                graphicsDevice.DrawPrimitives(PrimitiveType.LineList, 0, 3);
                graphicsDevice.RenderState.FillMode = FillMode.Solid;
                pass.End();
            }
            basicEffect.End();
            basicEffect.CommitChanges();
        }
}
Но так никто не пишет. Это противоречит половине основополагающих принципов XNA.Смысл создавать компонент, наследника Control? Гуглите. И ищите реальные примеры. Где Вы откопали это?
Не давай организму поблажки, каждый день тренируй его в шашки..
Скарам вне форума Ответить с цитированием
Старый 27.06.2011, 12:43   #3
ds.Dante
Старожил
 
Аватар для ds.Dante
 
Регистрация: 06.08.2009
Сообщений: 2,992
По умолчанию

О, спасибо огромное. Ошибка, наконец, пропала.

Цитата:
Сообщение от Скарам Посмотреть сообщение
Но так никто не пишет. Это противоречит половине основополагающих принципов XNA.Смысл создавать компонент, наследника Control? Гуглите. И ищите реальные примеры. Где Вы откопали это?
О да, именно по этой книге я и осваиваю XNA. :) Только в этой книге (как и во всех остальных руководствах) даётся готовая структура классов. Если мне было бы достаточно скопировать код в программу, я использовал бы готовую библиотеку. А классы у меня свои. И начинать надо с простейшего варианта.

Я нашёл замену классу-наследнику Control-а - Viewport. :)

Вот что получилось. Ошибок не выдаёт, OnPaint() выполняется, но без видимых результатов.

Код:
using System;
using System.Windows.Forms;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;

namespace XNA3
{
	using Color = Microsoft.Xna.Framework.Graphics.Color;

	public partial class MainForm: Form
	{
		GraphicsDevice device;
		VertexBuffer buffer;
		VertexDeclaration declaration;
		BasicEffect effect;
		PresentationParameters parameters = new PresentationParameters ();
		VertexPositionColor[] data =
		{
			new VertexPositionColor (new Vector3 (0, 0, 0), Color.Lime),
			new VertexPositionColor (new Vector3 (100, 100, 0), Color.Lime),
		};

		public MainForm ()
		{
			InitializeComponent ();

			parameters.BackBufferWidth = Math.Max (Width, 1);
			parameters.BackBufferHeight = Math.Max (Height, 1);
			parameters.BackBufferFormat = SurfaceFormat.Color;

			device = new GraphicsDevice (GraphicsAdapter.DefaultAdapter, DeviceType.Hardware, Handle, parameters);
			declaration = new VertexDeclaration (device, VertexPositionColor.VertexElements);
			effect = new BasicEffect (device, null);
			effect.VertexColorEnabled = true;
			buffer = new VertexBuffer (device, VertexPositionColor.SizeInBytes*data.Length, BufferUsage.None);
			buffer.SetData<VertexPositionColor> (data);

			Viewport viewport = new Viewport ();
			viewport.Width = 100;
			viewport.Height = 100;
			device.Viewport = viewport;

			this.Paint += OnPaint;
			Application.Idle += delegate { Invalidate (); };
		}

		void OnPaint (object sender, PaintEventArgs e)
		{
			device.Clear (Color.Black);
			device.VertexDeclaration = declaration;
			device.Vertices[0].SetSource (buffer, 0, VertexPositionColor.SizeInBytes);
			effect.World = Matrix.CreateTranslation (100, 100, 0);

			effect.Begin ();
			foreach (EffectPass pass in effect.CurrentTechnique.Passes)
			{
				pass.Begin ();
				device.DrawPrimitives (PrimitiveType.LineList, 0, 3);
				device.RenderState.FillMode = FillMode.Solid;
				pass.End ();
			}
			effect.End ();
			effect.CommitChanges ();
		}
	}
}
ds.Dante вне форума Ответить с цитированием
Старый 27.06.2011, 15:48   #4
ds.Dante
Старожил
 
Аватар для ds.Dante
 
Регистрация: 06.08.2009
Сообщений: 2,992
По умолчанию

Ok, я упростил программу, но ясности это не внесло.

Код:
using System.Windows.Forms;
using Microsoft.Xna.Framework.Graphics;

namespace XNA3
{
	using Color = Microsoft.Xna.Framework.Graphics.Color;

	public partial class MainForm: Form
	{
		GraphicsDevice device;

		public MainForm ()
		{
			InitializeComponent ();
			device = new GraphicsDevice (GraphicsAdapter.DefaultAdapter, DeviceType.Hardware, Handle, new PresentationParameters ());
			this.Paint += OnPaint;
			Application.Idle += delegate { Invalidate (); };
		}

		void OnPaint (object sender, PaintEventArgs e)
		{
			device.Clear (Color.Black);
			device.Present ();
		}
	}
}
Я добавил Present(). Окно теперь мерцает чёрным/стандартным оконным.

Если MainForm.DoubleBuffered - false, то в паузах между прорисовками (например, когда окно перетаскивается) оно остаётся чёрным. Если true - стандартным цветом.

А мне хотя бы просто залить окно. :)
ds.Dante вне форума Ответить с цитированием
Старый 27.06.2011, 16:09   #5
m0nax
Форумчанин
 
Аватар для m0nax
 
Регистрация: 25.09.2009
Сообщений: 525
По умолчанию

http://www.intuit.ru/department/se/i...1/3.html#sect6
там как раз для начала закрашивают форму
m0nax вне форума Ответить с цитированием
Старый 27.06.2011, 16:55   #6
ds.Dante
Старожил
 
Аватар для ds.Dante
 
Регистрация: 06.08.2009
Сообщений: 2,992
По умолчанию

Спасибо, как раз принялся за этот пример.

Проблема оказалась в строчке
Application.Idle += delegate { Invalidate (); };
Она была со старого примера, и из-за неё было мерцание.

Теперь буду пытаться нарисовать линию. :)
ds.Dante вне форума Ответить с цитированием
Старый 28.06.2011, 12:36   #7
ds.Dante
Старожил
 
Аватар для ds.Dante
 
Регистрация: 06.08.2009
Сообщений: 2,992
По умолчанию

Viewport таки не катит. Вместо того, чтобы просто залить чёрным область окна 100x100, программа заполняет всё окно мусором, и уже поверх мусора рисует чёрный квадрат.
Код:
using System;
using System.Windows.Forms;
using Microsoft.Xna.Framework.Graphics;

namespace Simple_Fill
{
	using Color = Microsoft.Xna.Framework.Graphics.Color;

	public partial class MainForm: Form
	{
		GraphicsDevice device;

		public MainForm ()
		{
			InitializeComponent ();
			device = new GraphicsDevice (GraphicsAdapter.DefaultAdapter, DeviceType.Hardware, Handle, new PresentationParameters ());

			Viewport viewport = new Viewport ();
			viewport.Width = 100;
			viewport.Height = 100;
			device.Viewport = viewport;
		}

		protected override void OnPaint (PaintEventArgs e)
		{
			device.Clear (Color.Black);
			device.Present ();
			base.OnPaint (e);
		}

		protected override void OnClosed (EventArgs e)
		{
			device.Dispose ();
			base.OnClosed (e);
		}
	}
}
ds.Dante вне форума Ответить с цитированием
Старый 28.06.2011, 15:03   #8
ds.Dante
Старожил
 
Аватар для ds.Dante
 
Регистрация: 06.08.2009
Сообщений: 2,992
По умолчанию

Уже помогли. Сделал через контрол - так хотя бы работает. Теперь снова буду пытаться нарисовать линию. :)
ds.Dante вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
XNA dampirik Gamedev - cоздание игр: Unity, OpenGL, DirectX 5 22.06.2011 01:59
Как обратиться к контролу на листе? Maryver Microsoft Office Excel 1 22.04.2011 18:47
C# и XNA, посоветуйте литературу Пепел Феникса Общие вопросы .NET 21 29.03.2011 02:54
XNA 4, C# stck C# (си шарп) 1 01.02.2011 04:28
C# XNA Cpluser Общие вопросы .NET 1 19.12.2009 15:07