Консультация № 186781
06.11.2012, 01:15
99.51 руб.
0 0 0
Здравствуйте! Прошу помощи в следующем вопросе:
разрабатываю простенькую двухмерную программу на управляемом directX (c# .NET 3.5). Суть программы проста: имеется полноэкранное приложение без рамок и панелей, весь экран залит одинаковым фоном (от RGB(0,0,0) до RGB(255, 255,255)). на этом фоне есть 2 объекта красного и синего цветов (RGB компоненты цветов тоже могут изменяться), при этом объекты хочется грузить из bmp-текстур, чтобы иметь возможность расширения библиотеки объектов. объекты двигаются вслед за движением мышки, цель - совместить их. при этом объекты должны быть прозрачны друг для друга. условно это выглядит так: есть синий квадрат и красный квадрат, совмещаем их на половину, общая область - приобретает фиолетовый цвет.
пытался реализовать через прозрачность, но тогда (в зависимости от выбранной матрицы смешивания) примешивается и цвет фона (если он не (0,0,0)).
Вопрос в следующем: как можно сделать так, чтобы цветовая компонента фона не влияла на прозрачные спрайты с текстурами, или какие есть альтернативные варианты для получения такого же результата

Приложение:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using Microsoft.DirectX;
using Microsoft.DirectX.Direct3D;

namespace d2dtest
{
public partial class Form1 : Form
{
public Device device=null;
public const int ScreenWidth = 1024;
public const int ScreenHeight = 768;
Texture spriteTexture;
Sprite sprite;
Rectangle textureSize;
System.Collections.ArrayList ar = new System.Collections.ArrayList();

public Form1()
{
InitializeComponent();
InitializeGraphics();
this.SetStyle(ControlStyles.AllPaintingInWmPaint | ControlStyles.Opaque, true);
ar.Add(new GraphicsSprite(System.Windows.Forms.Screen.PrimaryScreen.Bounds.Width / 2, System.Windows.Forms.Screen.PrimaryScreen.Bounds.Height / 2));
ar.Add(new GraphicsSprite(System.Windows.Forms.Screen.PrimaryScreen.Bounds.Width / 2, System.Windows.Forms.Screen.PrimaryScreen.Bounds.Height / 2, false));
Cursor.Dispose();
}

public void InitializeGraphics()
{
PresentParameters presentParams = new PresentParameters();
presentParams.SwapEffect = SwapEffect.Discard;

Format current = Manager.Adapters[0].CurrentDisplayMode.Format;
if (Manager.CheckDeviceType(0, DeviceType.Hardware, current, current, false))
{
presentParams.Windowed = true;
presentParams.BackBufferFormat = current;
presentParams.BackBufferCount = 1;
presentParams.BackBufferWidth = ScreenWidth;
presentParams.BackBufferHeight = ScreenHeight;
}
else
{
presentParams.Windowed = true;
}
device = new Device(0, DeviceType.Hardware, this, CreateFlags.SoftwareVertexProcessing, presentParams);

spriteTexture = TextureLoader.FromFile(device, "0.bmp");
using (Surface s = spriteTexture.GetSurfaceLevel(0))
{
SurfaceDescription desc = s.Description;
textureSize = new Rectangle(0, 0, desc.Width, desc.Height);
}
sprite = new Sprite(device);
}

private void Form1_KeyUp(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.Escape)
this.Close();
}

public class GraphicsSprite
{
private static readonly Vector3 Center = new Vector3(0, 0, 0);
Vector3 position;
bool tr = true;

public GraphicsSprite(int posx, int posy, bool btr=true)
{
position = new Vector3(posx, posy, 1);
tr = btr;
}

public void Draw(Sprite sprite, Texture t, Rectangle r)
{
sprite.Draw(t, Center, position, (tr) ? Color.FromArgb(102, 1, 0).ToArgb() : Color.FromArgb(0, 88, 100).ToArgb());
}

public void Update(Rectangle textureSize)
{
position.X = (tr) ? Cursor.Position.X : System.Windows.Forms.Screen.PrimaryScreen.Bounds.Width - Cursor.Position.X;
position.Y = (tr) ? Cursor.Position.Y : System.Windows.Forms.Screen.PrimaryScreen.Bounds.Height - Cursor.Position.Y;
if (position.X > System.Windows.Forms.Screen.PrimaryScreen.Bounds.Right)
position.X = System.Windows.Forms.Screen.PrimaryScreen.Bounds.Right;
if (position.X < 0)
position.X = 0;
if (position.Y > System.Windows.Forms.Screen.PrimaryScreen.Bounds.Bottom)
position.Y = System.Windows.Forms.Screen.PrimaryScreen.Bounds.Bottom;
if (position.Y < 0)
position.Y = 0;
}
}

protected override void OnPaint(PaintEventArgs e)
{
device.Clear(ClearFlags.Target, Color.FromArgb(97, 97, 97), 0.0f, 0);

foreach (GraphicsSprite gs in ar)
gs.Update(textureSize);

device.BeginScene();
sprite.Begin(SpriteFlags.None);

device.SetRenderState(RenderStates.AlphaBlendEnable, true);
device.SetRenderState(RenderStates.SourceBlend, 3);
device.SetRenderState(RenderStates.DestinationBlend, 9);

foreach (GraphicsSprite gs in ar)
gs.Draw(sprite, spriteTexture, textureSize);

sprite.End();
device.EndScene();
device.Present();
this.Invalidate();
}
}
}

Обсуждение

Форма ответа