DirecrX (Managed) Using Texture Maps C#
C# 2007. 10. 31. 14:06 |DirectX 코드를 사용해서 텍스처를 연결시켰다.
기존 코드 : http://www.iamgsi.com/entry/DirecrX-Managed-Create-a-Device-C
를 조금더 확장 시켰다.
이벤트 함수 OnResetDevice도 추가 했으며,
여기서 봐야 할 것은 윈도우 사이즈가 변할때 텍스처가 검정색으로 나올때가 있다.
이때 텍스처 함수 부분은 Managed로 해야 하는지는 잘 모르겠지만.
아래와 같은 인자를 사용하게 되는데 Managed를 할때는 몇개의 인자가 더 필요 하더라.
아래의 함수를 사이즈 변할때 호출해줘야 제대로 나오게 된다.
private void directXBaseView1_OnResetDevice(object sender, DeviceEventArgs e)
{
...
if (texture != null)
texture.Dispose(); // 이 코드를 넣지 않으면 메모리가 계속 누적된다. Texture가 계속해서 생성이 되는거 같다.
texture = TextureLoader.FromFile(dev, @"d:\bbbb.jpg");
}
나머지는 타이머를 사용해서 화면은 계속해서 리프레쉬 해주었다.
----DirectXBaseView.cs----
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Windows.Forms;
// DirectX
using Microsoft.DirectX;
using Microsoft.DirectX.Direct3D;
using Direct3D = Microsoft.DirectX.Direct3D;
//
namespace AzeViewerSimple3
{
public delegate void CreateDeviceEventHandler(object sender, DeviceEventArgs e);
public delegate void ResetDeviceEventHandler(object sender, DeviceEventArgs e);
public delegate void RenderEventHandler(object sender, DeviceEventArgs e);
//
public class DeviceEventArgs
{
public Device dev;
public Device Device { get { return dev; } }
public DeviceEventArgs(Device device)
{
dev = device;
}
}
//
public partial class DirectXBaseView : UserControl
{
#region Members;
private Device _device = null;
private bool pause = false;
public bool Pause
{
get { return pause; }
set { this.pause = value; }
}
public event CreateDeviceEventHandler OnCreateDevice;
public event ResetDeviceEventHandler OnResetDevice;
public event RenderEventHandler OnRender;
#endregion
#region ctor
public DirectXBaseView()
{
InitializeComponent();
}
#endregion
#region Init Dx
public void Init()
{
try
{
SetStyle(ControlStyles.AllPaintingInWmPaint | ControlStyles.Opaque, true);
// Setup our D3D stuff
PresentParameters presendParams = new PresentParameters();
presendParams.Windowed = true;
presendParams.SwapEffect = SwapEffect.Discard;
presendParams.EnableAutoDepthStencil = true;
presendParams.AutoDepthStencilFormat = DepthFormat.D16;
_device = new Device(0, DeviceType.Hardware, this, CreateFlags.HardwareVertexProcessing, presendParams);
if(OnCreateDevice != null)
OnCreateDevice(this, new DeviceEventArgs(_device));
if(OnResetDevice != null)
OnResetDevice(this, new DeviceEventArgs(_device));
Pause = false;
}
catch (Direct3DXException ex)
{
throw new ArgumentException("Error initializing DirectX", ex);
}
}
#endregion
#region Properties
private Color _deviceBackColor = Color.Blue;
public Color DeviceBackColor
{
get { return _deviceBackColor; }
set { _deviceBackColor = value; }
}
#endregion
#region Rendering
public void Render()
{
if (Pause)
return;
if (_device == null)
return;
_device.Clear(ClearFlags.Target | ClearFlags.ZBuffer, _deviceBackColor, 1.0f, 0);
_device.BeginScene();
if (OnRender != null)
OnRender(this, new DeviceEventArgs(_device));
_device.EndScene();
_device.Present();
}
#endregion
#region Overrides
protected override void OnPaint(PaintEventArgs e)
{
//base.OnPaint(e);
// this.Render();
}
protected override void OnResize(EventArgs e)
{
base.OnResize(e);
if (OnResetDevice != null)
OnResetDevice(this, new DeviceEventArgs(_device));
}
#endregion
}
}
----Form1.cs----
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;
// DirectX
using Microsoft.DirectX;
using Microsoft.DirectX.Direct3D;
using Direct3D = Microsoft.DirectX.Direct3D;
namespace AzeViewerSimple3
{
public partial class Form1 : Form
{
#region Member
VertexBuffer vertexBuffer = null;
Texture texture = null;
//bool pause = false;
#endregion
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
//pause = false;
directXBaseView1.Init();
}
private void directXBaseView1_OnCreateDevice(object sender, DeviceEventArgs e)
{
Device dev = e.Device;
vertexBuffer = new VertexBuffer(typeof(CustomVertex.PositionNormalTextured),
100,
dev,
Usage.WriteOnly,
CustomVertex.PositionNormalTextured.Format,
Pool.Managed);
vertexBuffer.Created += new EventHandler(OnCreateVertexBuffer);
OnCreateVertexBuffer(vertexBuffer, null);
}
void OnCreateVertexBuffer(object sender, EventArgs e)
{
VertexBuffer vb = (VertexBuffer)sender;
// Create a vertex buffer (100 customervertex)
CustomVertex.PositionNormalTextured[] verts = (CustomVertex.PositionNormalTextured[])vb.Lock(0, 0); // Lock the buffer (which will return our structs)
for (int i = 0; i < 50; i++)
{
// Fill up our structs
float theta = (float)(2 * Math.PI * i) / 49;
verts[2 * i].Position = new Vector3((float)Math.Sin(theta), -1, (float)Math.Cos(theta));
verts[2 * i].Normal = new Vector3((float)Math.Sin(theta), 0, (float)Math.Cos(theta));
verts[2 * i].Tu = ((float)i) / (50 - 1);
verts[2 * i].Tv = 1.0f;
verts[2 * i + 1].Position = new Vector3((float)Math.Sin(theta), 1, (float)Math.Cos(theta));
verts[2 * i + 1].Normal = new Vector3((float)Math.Sin(theta), 0, (float)Math.Cos(theta));
verts[2 * i + 1].Tu = ((float)i) / (50 - 1);
verts[2 * i + 1].Tv = 0.0f;
}
// Unlock (and copy) the data
vb.Unlock();
//throw new NotImplementedException();
}
private void directXBaseView1_OnResetDevice(object sender, DeviceEventArgs e)
{
Device dev = e.Device;
dev.RenderState.CullMode = Cull.None;
dev.RenderState.Lighting = false;
dev.RenderState.ZBufferEnable = true;
if (texture != null)
texture.Dispose();
texture = TextureLoader.FromFile(dev, @"d:\bbbb.jpg");
}
private void directXBaseView1_OnRender(object sender, DeviceEventArgs e)
{
//if (pause) return;
Device dev = e.Device;
dev.Transform.World = Matrix.RotationAxis(new Vector3((float)Math.Cos(Environment.TickCount / 250.0f), 1, (float)Math.Sin(Environment.TickCount / 250.0f)), Environment.TickCount / 1000.0f);
dev.Transform.View = Matrix.LookAtLH(new Vector3(0.0f, 3.0f, -5.0f), new Vector3(0.0f, 0.0f, 0.0f), new Vector3(0.0f, 1.0f, 0.0f));
dev.Transform.Projection = Matrix.PerspectiveFovLH((float)Math.PI / 4.0f, 1.0f, 1.0f, 100.0f);
dev.SetTexture(0, texture);
dev.TextureState[0].ColorOperation = TextureOperation.Modulate;
dev.TextureState[0].ColorArgument1 = TextureArgument.TextureColor;
dev.TextureState[0].ColorArgument2 = TextureArgument.Diffuse;
dev.TextureState[0].AlphaOperation = TextureOperation.Disable;
dev.SetStreamSource(0, vertexBuffer, 0);
dev.VertexFormat = CustomVertex.PositionNormalTextured.Format;
dev.DrawPrimitives(PrimitiveType.TriangleStrip, 0, (4 * 25) - 2);
}
private void timer1_Tick(object sender, EventArgs e)
{
directXBaseView1.Render();
}
private void Form1_Resize(object sender, EventArgs e)
{
directXBaseView1.Pause = ((this.WindowState == FormWindowState.Minimized) || !this.Visible);
}
}
}
질문 내용이 있다면 코멘트 부탁 드려요