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와 비트맵 객체들은 자동으로 삭제된다. }