우선 Silverlight를 ASP.NET AJAX와 연동해서 화면 구성을 얼마나 극대화 하게 해주는지를 보는 좋은 예가 되었으며, Silverlight를 활용한 동영상 부분은 기존에도 봐왔지만. asp.net를 배우는 시점에서 어떻게 적용하고 동영상 컨텐츠로서의 발전 가능성에서도 조금씩 생각의 틀을 잡아 주는 시간이였던거 같습니다.
Web Service의 활용 가치에 대해서도 조금씩 이해가 가네요. 실버라이트가 1.1을 바라보고 있는 가운데 많은 부분 업데이트가 되고 다양한 적용 사례가 나올거 같습니다. 내년이 기대가 되네요.
기존 디자이너의 일러 스터에서의 디자인 방법을 그대로 가져 갈 수 있도록 XAML Export도 제공한다고 하니 Blend를 배우지 않아도 협업 과정에서 조금은 가능성이 보이네요 ^^.
지금 구상중인 제 웹 페이지도 ASP.NET AJAX를 기본 구성으로 가지만 궁극적인 목표는 WPF, Silverlight의 접목에 있기 때문에 많은 고민을 해야 할거 같습니다.
if (openFileDialog1.ShowDialog() == DialogResult.OK) { // 컨트롤에 이름 설정하기 tbAzeName.Text = openFileDialog1.FileName;
try { if ((myStream = openFileDialog1.OpenFile()) != null) { using (myStream) { // 바이너리로 읽기 위해서 BinaryReader를 생성하고 myStream의 // 스트림 값을 넘겨 받는다. BinaryReader r = new BinaryReader(myStream); for (int i = 0; i < 5; i++) { Console.WriteLine(r.ReadInt32()); } } } } catch (Exception ex) { MessageBox.Show("Error: Could not read file from disk. Original error: " + ex.Message); } } }
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 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 (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
C#에서 프로젝트를 하기 위해서 DirectX를 연동하고 있다. 현재 소스는 Tutorial 1: Create a Device를 사용해서 UserControl에 붙인 것과 동일합니다.
----DxViewer.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 Gsi.DxViewer { public delegate void RenderEventHandler(object sender, DeviceEventArgs e); public delegate void CreateDeviceEventHandler(object sender, DeviceEventArgs e);
public class DeviceEventArgs : EventArgs { private Device _device;
public Device Device { get { return _device; } }
public DeviceEventArgs(Device device) { _device = device; } }
public partial class DxViewer : UserControl { #region Members;
/// <summary> /// Extend this list of properties if you like /// </summary> private Color _deviceBackColor = Color.Black;
public Color DeviceBackColor { get { return _deviceBackColor; } set { _deviceBackColor = value; } } #endregion
#region Rendering
/// <summary> /// Rendering-method /// </summary> public void Render() { if (_device == null) return;
//Clear the backbuffer _device.Clear(ClearFlags.Target, _deviceBackColor, 1.0f, 0);
//Begin the scene _device.BeginScene();
// Render of scene here if (OnRender != null) OnRender(this, new DeviceEventArgs(_device));
//End the scene _device.EndScene(); _device.Present(); }
#endregion
#region Overrides
protected override void OnPaint(PaintEventArgs e) { // Render on each Paint this.Render(); } #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;
using Gsi.DxViewer;
namespace AzeViewerSimple2 { public partial class Form1 : Form { public Form1() { InitializeComponent(); }
----참고사항---- References 에 Microsoft.DirectX Microsoft.DirectX.Direct3D Microsoft.DirectX.Direct3DX 를 추가 한후에 빌더를 하고 나면 DxViewer 컨트롤이 Toolbox에 생깁니다. 그 컨트롤을 Form1의 디자인 화면으로 드래그 해서 넣은 후에 이름을 dxViewer1이라고 지정한후 코드를 참조 하시면 됩니다.
비주얼 C++에서 자동으로 이 문제를 지원하는 방법은 없고, 다만 이에 대한 함수가 공개되어 있을 뿐입니다. MSJDrawTransparentBitmap이라는 함수가 마이크로소프트의 knowledgebase 079212에 나와있습니다. 다음 소스 코드를 보면 이 함수가 하는 일은 비트맵을 불러오고 페인팅 표면을 투명하게 칠하기 위해 마스크로 보내는 작업을 한다는 것을 알 수 있습니다(자세한 내용은 MSJ 한국판 98년 1월호 108쪽 참고).
// MSJDrawTransparentBitmap // 함수는 복사되었고 Knowledgebase 기사 Q79212으로부터 적용되었다. // 제목 : 투과되는 비트맵 그리기 void MSJDrawTransparentBitmap(CDC* pDC, CBitmap* pBitmap, int xStart, int yStart, COLORREF cTransparentColor) { CBitmap bmAndBack, bmAndObject, bmAndMem, bmSave; CDC dcMem, dcBack, dcObject, dcTemp, dcSave; dcTemp.CreateCompatibleDC(pDC); dcTemp.SelectObject(pBitmap); //비트맵 선택하기 BITMAP bm; pBitmap->GetObject(sizeof(BITMAP), (LPSTR)&bm); CPoint ptSize; ptSize.x = bm.bmWidth; // 비트맵의 폭 ptSize.y = bm.bmHeight; // 비트맵의 높이 dcTemp.DPtoLP(&ptSize, 1); // 논리 포인트로부터 장치 포인트로 변환 // 임시 데이터를 보관하기 위해 몇몇 DC를 생성 dcBack.CreateCompatibleDC(pDC); dcObject.CreateCompatibleDC(pDC); dcMem.CreateCompatibleDC(pDC); dcSave.CreateCompatibleDC(pDC); // 각 DC를 위해 비트맵을 생성. DC는 GDI의 숫자만큼 필요하다. functions. // 모노크롬 DC bmAndBack.CreateBitmap(ptSize.x, ptSize.y, 1, 1, NULL); // 모노크롬 DC bmAndObject.CreateBitmap(ptSize.x, ptSize.y, 1, 1, NULL); bmAndMem.CreateCompatibleBitmap(pDC, ptSize.x, ptSize.y); bmSave.CreateCompatibleBitmap(pDC, ptSize.x, ptSize.y); // 각 DC는 픽셀 데이터를 저장하기 위해 비트맵 객체를 선택해야 한다. CBitmap* pbmBackOld = dcBack.SelectObject(&bmAndBack); CBitmap* pbmObjectOld = dcObject.SelectObject(&bmAndObject); CBitmap* pbmMemOld = dcMem.SelectObject(&bmAndMem); CBitmap* pbmSaveOld = dcSave.SelectObject(&bmSave); // 적당한 맵핑 모드를 설정한다. dcTemp.SetMapMode(pDC->GetMapMode()); // 이리로 보내진 비트맵을 저장한다. dcSave.BitBlt(0, 0, ptSize.x, ptSize.y, &dcTemp, 0, 0, SRCCOPY); // 투영되는 비트맵에 포함되는 색으로 소스 DC의 배경색을 설정한다. COLORREF cColor = dcTemp.SetBkColor(cTransparentColor); // 소스 비트맵에서 모노크롬 비트맵까지 BitBlt를 수행해서 // 비트맵용 오브젝트 마스크를 생성한다. dcObject.BitBlt(0, 0, ptSize.x, ptSize.y, &dcTemp, 0, 0, SRCCOPY); // 원래 색으로 되돌리는 소스 DC의 배경색을 설정한다. dcTemp.SetBkColor(cColor); // 객체 마스크를 반전시킨다. dcBack.BitBlt(0, 0, ptSize.x, ptSize.y, &dcObject, 0, 0, NOTSRCCOPY); // 목적지에 메인 DC의 배경을 복사한다. dcMem.BitBlt(0, 0, ptSize.x, ptSize.y, pDC, xStart, yStart, SRCCOPY); // 비트맵이 놓여지는 위치를 마스크한다. dcMem.BitBlt(0, 0, ptSize.x, ptSize.y, &dcObject, 0, 0, SRCAND); // 비트맵의 투명 색상 픽셀을 마스크한다. dcTemp.BitBlt(0, 0, ptSize.x, ptSize.y, &dcBack, 0, 0, SRCAND); // 목적지 DC상에서 배경색과 비트맵을 XOR 연산한다. dcMem.BitBlt(0, 0, ptSize.x, ptSize.y, &dcTemp, 0, 0, SRCPAINT); // 스크린에 목적지를 복사한다. pDC->BitBlt(xStart, yStart, ptSize.x, ptSize.y, &dcMem, 0, 0, SRCCOPY); // 보내진 비트맵으로 원래 비트맵을 대체한다. dcTemp.BitBlt(0, 0, ptSize.x, ptSize.y, &dcSave, 0, 0, SRCCOPY); // 메모리 비트맵을 리셋시킨다. dcBack.SelectObject(pbmBackOld); dcObject.SelectObject(pbmObjectOld); dcMem.SelectObject(pbmMemOld); dcSave.SelectObject(pbmSaveOld); // 메모리 DC와 비트맵 객체들은 자동으로 삭제된다. }