< Tessellator >

테셀레이터는 Hull Shader 의 결과를 입력으로 받아서 작업을 합니다.
이 스테이지는 프로그래머가 제어할 수 없는 영역입니다.( 정말 다행이죠? ^^ )
앞선 Hull Shader 스테이지에서 정의된 폴리곤 분할 방법과 분할 수치에 따라서
실제로 Vertex 데이터들을 생성할 수 있는 정보를 주게 됩니다. 
즉, 우리는 큰 덩어리 형태의 Vertex 데이터만 HullShader 를 통해서 전달할 뿐입니다.
테셀레이터의 정해진 연산에 의해서,
도메인 쉐이더( DomainShader )에 무게 중심 좌표( BarycentricCoordinates )들을 전달
하게 됩니다.



< 무게 중심 좌표( BarycentricCoordinates ) >

무게 중심 좌표를 언급하기 전에, 벡터의 외적의 성질에 대해서 언급할 사항이 있습니다.
우리가 이미 알고 있듯이, 두 벡터의 외적 연산으로 두 벡터에 수직인 벡터를 구할 수 있습니다.
지금부터 여기에 주목할 것은 이렇게 외적 연산을 통해서 얻어진 벡터의 길이입니다.
이렇게 구해진 벡터의 길이는 기하학적으로 두 벡터를 평행사변형을 만들었을 때, 넓이를 의미합니다.
아래의 그림이 이해에 도움이 되었으면 좋겠습니다.^^
꽤 재미있는 성질이지 않습니까? ^^
( 이미 다들 알고 계셨을 것이라 생각하지만, 처음 접했을때, 저는 꽤 재미있는 성질이라고 생각했습니다..^^ )



두 벡터의 외적으로 나온 결과 벡터의 길이가 평행사변형의 넓이라는 사실을 인지한다면,
우리는 이제 무게 중심 좌표에 대해서 얘기할 수 있습니다.
힌트를 드리면, 무게 중심 좌표는 다른 말로 면적 좌표로도 불리기도 합니다.


삼각형 내부의 임의의 점 P는 점 A,B,C를 구성하는 삼각형들의 비율로 표현할 수 있습니다.
위의 그림에서 나오는 공식과 그림은 바로 이를 보여드리고 있습니다.
w들은 가중치 상수를 의미합니다.
각 가중치들의 합은 반드시 1.0 이여야 합니다.
만약 C의 가중치인 w3 의 경우에는 삼각형 APB 의 넓이 / 삼각형 ABC의 넓이 가 되는 것입니다.
이런 식으로 서로 대응되는 각 가중치들을 삼각형을 구성하는 각각의  정점 위치에 대응시키면,
우리가 원하는 P의 위치를 구할 수 있습니다.


벡터 외적의 기하학적 특징을 이용해서 가중치를 구하는 코드는 아래와 같습니다.
이 코드에서는 삼각형 넓이를 구할 때 수행하는 2를 나누는 작업이 생략되어 있습니다.
이유는 어차피 이 코드의 결과는 비율에 대한 가중치이기 때문에, 2를 나누는 작업은 의미가 없기 때문입니다.


이처럼 무게중심좌표를 구하는 일이 DirectX11의 테셀레이터의 임무 중 하나입니다.
삼각형을 구성하는 세 정점이 주어졌을 때 세 정점의 가중치를 구할 수 있다면,
임의의 점 P를 구할 수 있습니다.
바로 이 역활을 수행하는 것이 테셀레이터의 기능 중 하나입니다.
앞선 언급했듯이 테셀레이터의 기능은 우리가 조작 할 수 있지 않습니다.
즉, 고정 기능입니다.

우리는 Hull Shader를 통해서 Patch를 정의하고,
이렇게 정의된 패치 데이터는 이후에 가공되지 않고, 바로 Domain Shader 에서도 사용됩니다.
( 테셀레이터에서도 이 데이터를 사용해서 연산을 합니다. )
테셀레이터 단계에서는 이 패치 데이터에 대응되는 가중치들을 구성해서,
바로 다음 단계인 Domain Shader 로 전달
하게 되는 것입니다.
물론 내부적으로는 더욱 복잡한 과정을 거치겠지만,
우리가 코딩관점에서 관심을 가질 수 있는 변수 정보는 이들 뿐입니다.

Domain Shader의 기본적인 형태는 다음과 같습니다.

[domain("tri")]
DS_OUTPUT DS( HS_CONSTANT_DATA_OUTPUT input,
                    float3 UVW : SV_DomainLocation,
                    const OutputPatch<HS_OUTPUT, 3> patches
{
   DS_OUTPUT Output;
    ...
    return Output;   
}

Domain Shader의 입력으로 들어오는 인자들을 유심히 보시기 바랍니다.
( 패치 정보와 UVW 에 바로 가중치 정보가 입력됩니다. )
이들에 대해서는 다음 시간에 살펴보도록 하겠습니다.




앞선 시간들을 통해서, 우리는 테셀레이션에 대해서 꾸준히 살펴보았습니다.
DirectX9 세대에서부터 테셀레이션을 사용했었으며,
ATI 의 일부 그래픽 카드들은 하드웨어 기반의 테셀레이터를 지원했었습니다.

DirectX11의 테셀레이션 작업은 하드웨어 기반으로 처리됩니다.
즉, 이는 무수히 많은 연산을 처리해서 많은 폴리곤을 화면에 보여주겠다는 하나의 의지입니다.
이들이 강력한 이유는 이전 글인 다음을 참고해 주시기 바랍니다.
http://vsts2010.net/331

요약해 보자면,
이제는 텍스쳐링보다는 폴리곤 갯수를 증가시켜서 퀄리티의 향상을 도모하겠다는 것입니다.
사실 이것에 관해서는 많은 우려와 논란이 많았던 것이 사실입니다.
하지만, 현재의 하드웨어 상황은 이들 테셀레이션 기능을 중심으로 변화하고 있는 것이 사실입니다.
아래는 초창기 ATI의 DirectX11 기반의 하드웨어 구조입니다.



ATI의 경우에는 렌더링 목적에 집중하기 위해서 하나의 테셀레이터와 두개의 래스터라이저로 처리를 했었습니다.
물론 이것은 초기 DirectX11을 지원하는 하드웨어의 경우입니다.

ATI가 이런 테셀레이션 기반의 하드웨어를 출시하자,
상대적으로 후발주자였던 NVIDIA의 경우에는 이 테셀레이터를 더 많이 사용한
DirectX11 기반의 하드웨어를 출시하게 됩니다.




위의 빨간 동그라미 영역에 4개씩 보이는 노란 박스가 모두 테셀레이터입니다.
즉 위의 경우에는 16개의 테셀레이터가 존재합니다.( 4개의 래스터라이져 )
NVIDIA의 이런 과감한(?) 테셀레이터의 지원은 ATI의 향후 대응을 기대하게 만들기도 했습니다.

이런 하드웨어적인 논란은 본 글의 취지와는 맞지 않습니다.
이 글은 이런 현재의 상황에 어떻게 대응하는 API 단계의 개발자들을 주요 대상으로 하기 때문입니다.
즉, 어느 것이 더 효과적인지는 분별하기 어렵습니다.
다만 현재까지 나온 의견을 종합해 본다면,
ATI의 경우에는 테셀레이션과 래스터라이져의 본질적인 기능을 중심으로 설계가 되었고,
NVDIA의 경우에는 테셀레이션과 래스터라이져 외에도 GPGPU 환경의 기능을 더 고려해서 설계가 되었다고 합니다.
( NVIDIA의 경우에는 CUDA라는 GPGPU 플랫폼을 XP세대에서부터 강력히 지원했었습니다.^^ )

테셀레이션은 현재까지도 많은 논란이 있습니다.
그 논란의 중심에는 '빠를까?' 라는 의구심과 '엄청난 양의 연산' 에 대한 우려가 있습니다.
또한 하드웨어 기반의 테셀레이션으로의 패러다임 전환이 쉽지 않은 것도 사실입니다.

실제로 테셀레이션 관련 샘플을 실행시켜보면, GPU의 성능에 굉장히 의존적입니다.( 당연한 얘기겠지만요...^^ )
테셀레이션 샘플들은 DirectX11 기반의 하드웨어에서 그렇게 빠르지도, 또한 느리지도 않습니다.
오히려 일반적인 상황에서는 약간의 성능 저하가 일어날 수도 있으며,
최적화를 잘한 경우에는 테셀레이션 처리가 더 느릴 수도 있습니다.
하지만, 이제 하드웨어는 테셀레이터라는 기능을 장착을 했으며,
앞으로는 테셀레이터 기반으로 최적화하는 것이 더 개발 패러다임에 적합할 것입니다.

당분간 개발 패러다임이 과도기적인 상태를 보이겠지만,
이미 그래픽카드의 발전 방향이 테셀레이터 기반으로 변경되고 있다는 것에 우리는 주목해야 합니다.

개발을 진행하다보면, 아무리 훌륭한 툴이라고 하더라도 기능이 부족해서 확장 컴포넌트를 구매해서 쓰는 경우가 있습니다. 저도 예전에 Visual Studio 2008로 개발할 때, DB의 변경사항을 LINQ to SQL의 OR디자이너에 바로 반영하는 기능이 없어서, 검색하다 찾은 확장 컴포넌트를 체험기간만큼 사용했던 기억이 있습니다. 비주얼 스튜디오 2010의 IDE가 매우 훌륭해지기는 했지만, 그래도 좀 더 손맛이 느껴지는 기능을 찾으시는 분들이 있으실 텐데요, 아주 훌륭하고도 공짜인 확장 툴이 가까이 있습니다. 오늘 소개해드릴 Productivity Power Tools가 바로 그것입니다!

설치부터 아주 간단합니다. '도구' 메뉴의 '확장 관리자'를 이용하셔서 '온라인 갤러리'에서 'power tool'이라고 검색만 하시면 찾을 수 있고, 더블클릭만 해주시면 그냥 쉽게 깔립니다. 하지만 기능은 매우 다양합니다. 이제 부터 하나하나 소개 해드리겠습니다.


- 솔루션의 대양을 항해하라, Solution Navigator

좀 복잡한 프로젝트를 하다보면 솔루션에 프로젝트가 아주 많아집니다. 저는 16개정도까지 포함되는 걸 해본적이 있는데요, 이런 솔루션의 대양을 항해할 때는 역시, 나침반이 제맛이죠 :)


어떤가요? 솔루션 탐색기랑 비교해서 좀 이쁘게 생겼나요? 우선 뭔가 틀린 점들이 보이는데요, 하나씩 알아보죠.

1. 클래스의 멤버레벨까지 탐색.


기존의 솔루션 탐색기는 파일레벨까지 탐색이 가능했지만, Solution Navigator(이하 네비로 줄여씁니다)에서는 클래스의 멤버까지 탐색이 가능합니다.

2. 빠른 검색.

네비를 보면, 검색어를 입력할 수 있는 텍스트박스가 하나 있습니다. 여기에 Cl이라고 입력하면(씨엘...?), 다음과 같이 Cl이 포함되는 항목을 모두 찾아줍니다.


3. 호출 계층구조 바로 보기

Visual Studio 2010에 추가된 호출 계층구조 보기가 네비안에 통합되어 있습니다. 네비안에서 항목을 하나 선택하면, 오른쪽 끝에 조그만 아이콘이 하나 생깁니다. 이 아이콘을 누르면, 네비의 항목이 그 항목을 원점으로 해서 다시 표시됩니다. 예를 들어서 Class1의 PrintCount()메서드를 원점으로 해서 보면 아래와 같습니다.


이 메서드가 포함하는 것과, 참조하는 것들, 누가 이 메서드를 호출하는지, 이 메서드가 어떤 것들을 호출하는지 등을 한번에 파악할 수 있죠.

4. 네비가 표시할 항목 필터링

네비에서 솔루션항목 바로 아래에 보면 4가지 커맨드가 있습니다. All은 말 그대로 모든 항목을 표시하는 거구요, Open은 아래처럼, 지금 코드 편집기에서 열려있는 항목만 표시합니다.


그리고 Unsaved는 아래처럼 변경사항을 저장하지 않은 항목만 보여줍니다.


저장하지 않은 항목의 탭을 붉은색 점으로 강조하는 것도 새로 추가된 기능입니다. 그리고 Edit는 한번이라도 수정되었던 파일을 표시합니다.

5. 이미지 썸네일 제공

네비에 에서 솔루션에 포함된 이미지 파일에 마우스를 올리면, 아래와 같이 이미지의 썸네일을 표시해줍니다.


6. 코드 편집기에서 즉석 호출

코드 편집기에서 네비의 기능을 즉석 호출할 수도 있는데요, 예를 들어서 PrintCount메서드내에 커서를 두고 'Ctrl + 1'키를 누르면, PrintCount메서드와 관련된 항목들이 바로 나타납니다.


그리고 'Ctrl+2'를 누르면, 현재 코드 편집기에서 열려있는 파일의 모든 클래스에 대한 정보가 바로 나타납니다.




- Visual Studio를 Tab!

비주얼 스튜디오의 코드편집기에서 여러파일을 작업하려면 여러파일을 열어놓고 탭으로 파일간의 이동을 하면서 작업을 해야 합니다. 그만큼 많이 사용해야 하는 탭인데요. 이 탭이 어딘가 모르게 좀 불편한 면이 있었습니다. 그래서 Power Tools에서는 이 탭에 대한 지원이 막강해졌습니다.

1. 다양해진 옵션


옵션에 들어가면 Power Tools탭안에 Document Tab이라는 항목이 따로 있습니다. 그리고 미리 정의된 프리셋을 제공하는데요, Visual Studio 2008부터 아주 다양한 프리셋을 지원합니다.

2. Option 1 : Web Browser: Scrollable tab well


이 탭은 브라우저 처럼, 탭에 해당항목의 아이콘이 붙습니다. 그리고 고정시킬 수도 있는데요, 고정시킨 탭은 움직일 수 없습니다. 그리고 'Close All But Pinned'와 같이 고정된 탭을 제외하고 모두 닫기 같은 옵션도 제공합니다. 그리고 옵션에서 'Show pinned tabs in a separate row'를 체크하면 아래와 같이 고정된 탭만 구분해서 볼 수도 있습니다.


3. Option 2 : Scrollable Tab Well: Sorted by project


이 옵션을 사용하면, 위 사진과 같이 프로젝트 별로 탭의 색깔을 구분하고 정렬해서 보여줍니다. 15개까지 다른 프로젝트를 지원합니다.

4. Option 3 : Vertical Tab Well: Color coded and sorted by project


이 옵션을 사용하면, 기존의 수평이 아닌, 수직으로 탭을 나열해서 보여줍니다. 이렇게 하면 훨씬 많은 탭을 한번에 볼 수 있다는 장점이 있습니다 :)

5. Option 4 : Dynamic Tab Well: Removes tabs based on usage

이 옵션은 좀 똑똑한 옵션인데요. 탭이 많아서 한번에 표시하지 못할 경우, 가장 적게 사용한 탭 순으로 먼저 사라지게 하는 것입니다. 쫌 괜찮죠 :)


- 마치면서

오늘은 Power Tools의 Solution Navigator와 Tab에 대해서 알아봤습니다. 이 것만 해도 상당히 유용한 기능인데요, 소개해드릴 기능이 조금 더 남았습니다. 그럼, 다음에 또 뵙죠 :)

Visual Studio 31 (3) - Temp Project

Visual Studio 2010 2010. 11. 18. 09:00 Posted by 알 수 없는 사용자

개발하다 보면, 지금 작성하고 있는 알고리즘이 내가 원하는 대로 작동하는지 헷갈리기 시작합니다. 하지만, 프로젝트의 일부로 속하는 이 알고리즘이 제대로 작동하는지 알 수 있는 방법은 유닛테스트 외에는 직접 실행하는 방법외에는 없습니다. 알고리즘이 UI나 데이터베이스 같은 다른 부분과 긴밀하게 연계되어 있기 때문에 알고리즘만 따로 테스트할 방법이 마땅히 없으며, UI정도라도 배제하고 테스트하는 방법이 바로 유닛테스트를 활용하는 방법인거죠.

그래서 간단한 예제 데이터를 가지고 확인하고 싶을 때는 콘솔 어플리케이션 프로젝트를 활용하기도 합니다. 알고리즘을 제외한 모든 걸 최고로 단순화 시켜놓고 알고리즘 자체만 가지고 테스트를 진행할 수 있기 때문이죠. 그런데, 이 콘솔 어플리케이션을 애용하다보면, 다음과 같은 상황이 발생합니다.


'ConsoleApplication'뒤에 붙는 숫자가 계속해서 늘어만 가고, 프로젝트 폴더는 점점 더 지저분 해지는 것이죠. 이런 상황을 미연에 방지할 수 있는 기능이 Visual Studio에 있습니다. 어떤 기능인지 한번 알아보시죠.


- 왔다 가는 인생 흔적을 남기지 않도록.

'도구'메뉴에서 '옵션'을 선택하면, 다음과 같은 '옵션'창이 나타납니다.


그리고 '환경'탭을 시작으로 아래쪽으로 많은 옵션이 있죠. 평생 저런 옵션 다 만지는 일이 있을까 싶을 정도로 말이죠. 하지만... '환경'에서 한 칸만 위로 올라가보면...?



'프로젝트 및 솔루션'이라는 탭이 숨어있습니다!! 바로 이 탭이 오늘 소개하려는 기능과 관련이 있습니다. 항목을 찬찬히 살펴보다 보면, '만들어질 때 새 프로젝트 저장'이라는 항목이 있습니다. 이 항목이 기본으로 체크되어 있는데요, 이 항목의 체크를 해제하고 확인을 누릅니다.

그리고 새프로젝트 대화상자를 열어보면,


음... 뭐가 바뀐 걸까요? 한번 이 그림을 가지고 묵상을 해보시기 바랍니다...

답을 알아내셨나요? 힌트를 드리자면, 아까 분명히 탐색기를 보여드렸을 때, 'ConsoleApplication9'까지 있었는데, 새프로젝트 대화상자에 나타난 것은 'ConsoleApplication10'이 아니라 'ConsoleApplication1'입니다.

네, 바로 임시 프로젝트 공간에 프로젝트를 생성하기 때문입니다. 그래서 대화상자를 보시면, 경로를 명시하는 부분이 사라진 것을 확인하실 수 있습니다. 그럼 프로젝트를 생성하겠습니다.

그럼 이제 제가 거짓말 하는 것이 아님을 보여드릴 차례네요. 다음과 같이 프로젝트에 오른쪽 버튼을 클릭하고 '윈도우 탐색기에서 폴더 열기'를 선택합니다.


그러면, 프로젝트 폴더가 탐색기에서 열립니다. 탐색기의 경로를 유심히 보시죠.


Local밑의 Temporary Projects라는 경로가 보이실 겁니다. 바로 여기에 생성되었다가, 솔루션을 닫을 때 저장하지 않으면 사라지는 것이죠. 그럼 솔루션을 닫아볼까요?


저장할 것인지, 버릴 것인지 물어봅니다. 버리면 그냥 사라지는 거죠. 모든 기능이 그렇 듯이 임시 프로젝트에도 몇가지 제약 사항이 있는데요. 첫 번째는, 단일 프로젝트만 가능하다는 것입니다. 임시 프로젝트에 새 프로젝트를 추가하려고 하면 다음과 같은 메세지를 볼 수 있습니다.


그리고 두 번째로, 경로가 필요한 웹 어플리케이션 같은 프로젝트 타입에는 사용할 수 없다는 것입니다.


- 마무리

임시 프로젝트 기능을 통해서 프로젝트 폴더를 깔끔하게 유지하시기 바랍니다. 그럼 다음에 또 뵙죠~ :)

[JumpToDX11-17] DirectX9 세대의 테셀레이션( ATI 라이브러리편 )

DirectX 11 2010. 10. 11. 08:30 Posted by 알 수 없는 사용자

오늘은 DX9 세대의 테셀레이션 마지막입니다.
ATI 는 DirectX9를 지원하는 일부 그래픽카드들은 하드웨어 기반의 테셀레이션 작업을 지원합니다.
( HD 2000 시리즈 이후 지원되었다고 합니다. )
이 방법은 왜 DirectX11의 테셀레이션 작업이 강력한지를 이해하는 좋은 출발점이 될 수 있습니다.

이 경우에는그래픽 파이프라인 구조가 다음과 같습니다.




이는 현재 X-BOX 360 에도 동일하게 적용되는 그래픽 파이프라인 구조입니다.
주목할 만한 것은 Tessellator의 위치입니다.
즉, 버텍스 쉐이더( VertexShader ) 스테이지의 앞단계에 위치하고 있습니다.
이 위치는 DX11 세대에서는 버텍스 쉐이더 다음 단계로 변경됩니다.


아래의 그림은 ATI 카드에서 지원되는 DX9 기반의 테셀레이션 작업을 보여줍니다.



DirectX9의 테셀레이션을 위해서 총 3번의 패스를 통과해야 합니다.
즉, 3번의 렌더링 작업이 필요합니다.
이렇게 많은 패스가 필요한 이유는 테셀레이션을 위해서 인접한 정점의 정보가 필요하기 때문입니다.
DX9 의 시대에서는 VertexShader 단계에서 인접한 정점의 정보를 쉽게 확인할 수 있는 방법이 없습니다.
그래서 인접한 정보를 구성하는 단계가 첫번째 패스입니다.

첫번째 패스의 렌더타겟은 백버퍼가 아니라, 텍스쳐입니다.
이 텍스쳐에 정점 정보와 정점의 인덱스를 기록하게 됩니다.
즉, rgb 에는 위치 정보가 기록되며 a 에는 정점의 인덱스 정보가 기록됩니다.

이 때, 주의할 것은 메시가 인덱스 버퍼 기반으로 렌더링 되어지는 경우입니다.
이 경우에는 인덱스 버퍼를 모두 풀어서 새로운 버텍스 버퍼를 만들어야 합니다.
우리가 필요한 것은 폴리곤을 렌더링하는 작업이 아닙니다.
인접정보를 구성하는 일임을 잊지 말아야 합니다.
첫번째 패스에서의 렌더링은 TRIANGLELIST가 아니라, POINTLIST 로 수행하게 됩니다.

또 하나 주의할 것이 있습니다.
POINTLIST 로 렌더링을 수행할 때는 WVP( World-View-Projection ) 변환이 아니라,
World-View까지만 변환
을 해야 합니다.
이유는 간단합니다.
테셀레이션은 주로 시점에 근거해서  얼마나 많은 폴리곤을 생성할지를 판단해야 합니다.
이를 앞 시간들을 통해서 Adaptive 한 방식이라고 언급을 했었습니다.
이후의 패스에서는 이들 정점에 근거해서 LOD를 판정해서 Tessellation Factor 를 연산하게 되니다.
그래서 View 좌표계까지만 변환을 합니다.
첫번째 패스에서는 이렇게 View 공간으로 POINTLIST들을 텍스쳐에 렌더링 합니다.

이렇게 생성된 텍스쳐를 기반으로 해서 두번째 패스를 진행할 수 있습니다.
DX9 를 지원하는 모든 그래픽카드가 VertexShader 단계에서 텍스쳐 데이터를 읽어올 수 있는 것은 아닙니다.
이런 제약 사항들은 이제 큰 의미가 있는 것이 아니기 때문에,
개념적인 것에 포커스를 두시기 바랍니다.^^

두번째 패스의 목적은 Tessellation Factor를 구하는 것입니다.
즉, 얼마나 폴리곤을 세분화 할지를 결정합니다.
두번째 패스도 역시 POINTLIST 로 렌더링을 합니다.
그리고 첫번째 패스에서 생성해둔 인접 정점 정보를 가진 텍스쳐를 바인딩 합니다.
인접 정보가 있기 때문에 현재 정점을 기준으로 Tessellation Factor 를 계산할 수 있습니다.
두번째 패스에서 주의할 것은 이들 Tessellation Factor 를 저장하기 위해
R2VB 라는 일종의 버퍼에 렌더링
을 한다는 것입니다.
이는 ATI 테셀레이션 라이브러리에만 존재하는 개념입니다.

세번째 패스는 실제로 지오메트리(Geometry)를 렌더링 하는 단계입니다.
실제 렌더링 작업은 TRIANGLELIST 로 렌더링 합니다.
인덱스 기반의 렌더링이 아니라,
우리가 인덱스를 풀어서 생성한 버텍스버퍼로 렌더링 하는 것에 주의해야 합니다.
이때 스트림(Stream) 을 하나 더 연결하는데,
이것은 앞서 우리가 렌더링 했던 R2VB 라는 버퍼
입니다.

결과적으로 VertexShader 에는 Barycentric coordiate 기반의 가중치 값이 전달됩니다.
즉, 무게 중심 좌표입니다.

float3 vPosTessOS = i.vPositionVert0.xyz * i.vBarycentric.x +
                              i.vPositionVert1.xyz * i.vBarycentric.y + 
                              i.vPositionVert2.xyz * i.vBarycentric.z;


정점을 구성하는 방법은 위처럼 해야 합니다.

이상으로 DX9 세대의 테셀레이션 작업들에 대해서 아주 간단히 살펴보았습니다.
메인으로 다룰 내용이 아니라서, 쉽게 넘어간 부분이 많습니다.
아무래도 거의 사용하지 않기 때문에, 깊이있게 다루는 것은 의미가 없다고 생각합니다.

하지만, DX9 세대의 테셀레이션 작업은 이렇게 복잡한 방법과 절차를 통과해야 합니다.
DX11 의 테셀레이션 작업은 상대적으로 빠른 성능으로 구현이 됩니다.
왜냐하면 1 Pass 이기 때문입니다.


ATI 는 DX9 세대의 테셀레이션 작업을 위해서, 라이브러리를 제공하고 있습니다.
더 필요한 정보가 있으시면, 아래의 링크를 참고하시기 바랍니다.

http://developer.amd.com/gpu/radeon/Tessellation/Pages/default.aspx#d3d9


DirectX SDK February 2010  버전까지는 'EnhancedMesh' 라는 샘플이 있었습니다.
아쉽게도 2010 June 버전에서 이 샘플은 사라졌습니다.
메시의 퀄리티를 향상시키는 샘플인데, 실제로는 폴리곤 갯수를 증가시키고 있습니다.
굳이 실행을 실켜보실 이유는 없습니다. ^^

ID3DXMesh 인터페이스에는 멤버함수로 CloneMeshFVF() 를 가지고 있습니다.
이 멤버함수의 옵션으로 D3DXMESH_NPATCHES 을 사용하게 되면,
하드웨어 가속을 받아서 폴리곤을 증가시킬 수 있습니다.
물론 내부적으로는 많은 연산을 수행할 것입니다.



만약 테셀레이션 작업이 그래픽카드에서 지원을 해주지 않는다면,
이는 CPU 기반으로 작업을 수행해야 합니다.
바로 이를 도와주는 API 가 D3DXTessellateNPatches() 입니다.



이렇듯 DirectX9 세대에도 테셀레이션을 위해서 API들을 지원해 주고 있었습니다.
물론 정식으로 그래픽카드에서 지원을 하지 않았기 때문에,
성능에 많은 문제점을 가지고 있었습니다.
테셀레이션 자체가 근본적으로 많은 연산을 수반하기 때문입니다.

다음 시간에는, 마지막으로 ATI의 DirectX9 기반의 테셀레이션 작업에 대해서 살펴보도록 하겠습니다.^^




이번 시간에 해 볼 내용은 동적으로 컨트를들을 생성하는 작업입니다.




모두 이렇게 아무것도 없는 상태로 프로젝트를 만들어 주시기 바랍니다.
지금부터 아무 것도 없는 화면에서 동적으로 컨트롤들을 생성해서 배치할 것입니다.
즉, 애플리케이션 실행 중에 컨트롤을 만들 것입니다.

가장 단순한 것이 버튼 컨트롤일 것입니다.
동적으로 버튼 컨트롤을 생성하기 위해서는 당연한 얘기지만,
폰 페이지가 생성되는 시점에 컨트롤을 만들어주는 코드를 추가해 주면 됩니다.
*.cs 파일을 열어서 다음과 같이 내용을 추가해 줍니다.




이들은 블렌드 툴에서 컨트롤 속성을 설정하는 부분을,
프로그램 소스 상에서 속성을 제어하는 부분입니다.
속성 정보는 중에 제가 현재 이벤트를 연결한 부분이 있습니다.
pStartCtrl.Click += OnStartButtonClick 와 pEndCtrl.Click += OnEndButtonClick 부분입니다.
이벤트도 코드 상에서 이렇게 연결해 줄 수 있습니다.


현재 예제에서는 간단히 메시지 박스를 출력하는 것은 마무리 했습니다.
대부분의 컨트롤들은 위의 방법과 같이 동적으로 생성해 줄 수 있습니다.
여기까지가 예제 샘플 작업의 끝입니다.^^






그런데 한가지 생소한 부분이 있을 것이라 생각을 합니다.
바로 ContentPanel.Children.Add( XXX ) 부분입니다.
어딘가에 현재 우리가 생성한 컨트롤들을 추가해주고 있습니다.
과연 이 패널은 무엇일까요?

프로그램 작성을 마치고, 다시 디자인 폼 수정 화면으로 돌아옵니다.



위의 화면을 확인해 보실 수 있겠죠?
앞에서 언급한 낯선 이름이 보입니다.
'ContentPanel' 보이시죠?

여기에 버튼을 하나 만들어 봅니다.
이번에는 소스 코드 레벨이 아니라, 디자인 폼 상에서 버튼을 바로 배치해 봅니다.




디자인 폼 상에서 버튼을 배치시키면,
바로 ContentPanel 의 하위 계층에 추가되어지는 것을 확인할 수 있습니다.
즉, 앞선 언급했던 ContentPanel.Children.Add( XXX ) 소스 코드는 바로
이 작업을 해준 것입니다.

조금 더 정확히 얘기하자면,
윈도우폰7의 레이아웃은 크게 TitlePanel과 ContentPanel 로 나눠져 있습니다.
그래서 이들 패널에 컨트롤을 추가했던 것입니다.

패널( Panel )이 무엇인지 모르시겠다구요?
패널은 이후의 시간에 언급될 기회가 있을 것입니다만,
지금은 단순히 컨트롤들을 그룹화 시켜서
자동으로 관리시켜주는 것 정도로 생각하시면 될 것입니다.^^


샘플 파일 첨부해드립니다..^^

모기와의 사투를 버린 끝에 이제야 컴퓨터 앞에 앉아 글을 쓸 수 있게 되네요(새벽 1시네요ㅡ.ㅡ) 아흑.
비록 눈이 따갑고 눕고 싶지만, 이제는 정말 제 자신과의 약속을 지키기 위해 한자 한자 적어나가렵니다.^^

지난 시간에 유효성 검사에 대해 살펴봤는데요. 이제 본론으로 넘어와서 적용해봐야겠죠?

유효성 검사 적용하기

저희가 USER 모델을 생성할때 엔터티 프레임워크(엔티티가 입에 붙었는데 한글판에 엔터티라고 명시되어있네요;;)를 통해 생성한 것 다들 기억하시죠? 엔터티 프레임워크의 경우 자동으로 모델 클래스를 생성해 주는 것도 다들 아실겁니다. 또한, 엔터티 프레임워크로 생성된 모델클래스를 직접적으로 컨트롤 할수 없다는 것도..
그렇다면 유효성 검사 부분은 도대체 어디다 둬야 한단 말이냐?

파샬 & 메타데이타 클래스 생성하기

메타 데이타 클래스를 만들어야 합니다. 또한 USER 모델에 해당하는 파샬 클래스도 생성해야합니다.
파샬 클래스의 경우 여러 파일, 여러 부분에 멤버나 메쏘드 등의 정의를 각각 두면 컴파일시에 이들 모두를 결합하게 되죠. 다들 아시는 내용!
여기서 잠깐, 엔터티 프레임워크로 생성된 모델 클래스의 소스를 잠깐 살펴보면,


모델 클래스가 파샬 클래스로 정의 되어 있는 것을 확인할 수 있습니다. 아~ 이러면 자동 생성된 이 모델 클래스는 건들 필요 없이 파샬 클래스를 하나 더 추가해서 그곳에다가 우리가 필요한 정의를 내려주면 되겠구나~ 라는 생각이 팍팍 드시죠?

그래서 추가해봤습니다. 동일한 이름의 모델 클래스를 하나 만들어 보죠. 그리고, 메타 데이타 클래스도 같이 만들겠습니다.

using System.ComponentModel.DataAnnotations;
using System.ComponentModel;

namespace MvcSite.Models

    [MetadataType(typeof(USERMetaData))]
    public partial class USER
    {      
    }

    public class USERMetaData
    {
        [Required(ErrorMessage="아이디 입력하셔야죠!")]
        [StringLength(10)]
        public object ID { get; set; }

        [Required(ErrorMessage="이름 입력하셔야죠!")]
        public object NAME { get; set; }
               
        [Required(ErrorMessage="패스워드 입력하셔야죠!")]       
        public object PWD { get; set; }
              
        [Required(ErrorMessage="이메일 입력하셔야죠!")]
        [RegularExpression(@"^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,4}$",
                                                             ErrorMessage = "올바른 이메일 형식이 아닙니다.")]
        public object EMAIL { get; set; }
    }
}

메타 데이터의 경우 테이블의 필드값을 대신합니다. 즉 모델과 같아야 합니다.
메타 데이터를 만든 후 파샬로 된 모델(USER) 클래스에 MetadataTypeAttribute를 통해 USERMetaData을 정의합니다. 이렇게하면 1차작업이 완료됩니다. 실행해 보시면 잘 돌아갑니다. 확인페이지는 따로 보여드리지 않겠습니다^^ 글이 너무 길어지면 지루해지겠죠?

모델에 없는 필드 확인하기

우리는 패스워드 확인 필드를 갖고 있습니다. 필수값이고 비교도 해야하지만 테이블에는 없는 필드죠. DataAnnotation을 통해 나머지 필드들은 각각 비교는 했는데, 패스워드 확인 필드는 어떻게~ 어떻게~ 어떡하면 되냐고~ 띠리링~ 그냥 만들어!

헉. 뭐 만들면 되죠;;;
일단, ValidationAttribute를 상속 받는 PropertiesMatchAttribute라는 이름의 두 값을 비교할 커스텀한 DataAnnotation 클래스를 만듭니다. 중요한건 검사를 담당하게될 IsValid 메쏘드를 오버라이드해야합니다.


이렇게 만든 후에, 생성한 USER 클래스를 수정하도록 하겠습니다.

    [PropertiesMatchAttribute("PWD", "CPWD",
                                         ErrorMessage = "패스워드 확인 안하실거에요?!")]

    [MetadataType(typeof(USERMetaData))]
    public partial class USER
    {
        [Required(ErrorMessage = "패스워드 확인 입력하셔야죠!")] 
       public string CPWD { get; set; }
    }

    public class USERMetaData
    {
        [Required(ErrorMessage="아이디 입력하셔야죠!")]
        [StringLength(10)]
        public object ID { get; set; }

        [Required(ErrorMessage="이름 입력하셔야죠!")]
        public object NAME { get; set; }
               
        [Required(ErrorMessage="패스워드 입력하셔야죠!")]       
        public object PWD { get; set; }
              
        [Required(ErrorMessage="이메일 입력하셔야죠!")]
        [RegularExpression(@"^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,4}$",
                                                            ErrorMessage = "올바른 이메일 형식이 아닙니다.")]
        public object EMAIL { get; set; }
    }

USER 클래스에 커스텀한 DataAnnotation 정의를 추가했고요, 패스워드 확인 필드를 필수값으로 정의하였습니다.
여기까지 잘 오셨죠? 실행해 보도록 하겠습니다.


위 결과물은 모든 필드에 입력을 안하고 submit을 했을 경우고, 아래 결과물은 패스워드를 다르게 입력 했을 경우입니다.


일단 원하는대로 출력되는 것을 확인했습니다.

역시 급정리요

이번시간 역시 유효성 검사 부분을 다뤘고요, 메타 데이터와 파샬 클래스를 이용한 유효성 검사를 살펴봤습니다.
정말 간단한 내용인데 쓰다보면 길어지네요;; 더 간단하게 필요한 메시지만 전달하도록 노력하겠습니다.

참조 : http://byatool.com/mvc/custom-data-annotations-with-mvc-how-to-check-multiple-properties-at-one-time

Visual Studio 2010 공식 팀 블로그의 트위터

안녕하세요. Visual Studio 2010 공식 팀 블로그에서는 트위터를 통해 여러분들과 소통을 하고 있습니다.

   

Visual Studio 2010 Launch Live 를 트위터로 생중계

VS2010 팀의 트위터를 통해 라스베가스의 Bellagio Hotel 에서 생방송으로 진행된 Visual Studio 2010 Launch Live 를 생중계 하였습니다. Visual Studio 2010 Launch Live 는 아래의 링크에서 다시 볼 수 있습니다.

http://www.microsoft.com/presspass/presskits/developer/videogallery.aspx?contentID=devlaunch10_d1keynote

   

트위터의 #vs2010korea 해시태그 커뮤니케이션 오픈

한국에서 Visual Studio 2010 을 사용하는 사람들을 위한 태그입니다. 여러분이 어디에 있든, 무엇을 하든, #vs2010korea 는 여러분들의 이야기에 듣고 있습니다. ^^

Visual Studio 2010 의 질문/답변/팁/노하우/잡담/구매/이슈 등 여러분들의 이야기를 #vs2010korea 라는 하나의 태그로 묶고 싶습니다.

   

   

많은 참여 바랍니다.

안녕하세요. Visual Studio 2010 팀입니다.
이제 다가오는 2010년 4월 12일은 Visual Studio 2010 정식 버전이 출시되는 날입니다.
이에 맞추어 저희 팀과 함께 활동하실 에너지 충만한 분들을 모집하고자 합니다.

   

 

지원 분야

  • Visual Studio 2010
  • .NET Framework 4.0
  • Cloud Development
  • Parallel Development
  • Web Development
  • Windows 7 Development
  • RIA Development
  • Architecture Development
  • Agile Development
  • Office Business Application Development
  • Team Foundation
  • Windows Mobile 7
  • User Experience (UX)
  • 기타 .NET 과 관련된 모든 분야

   

활동 영역

온라인 활동 영역

팀 블로그 활동

팀 블로그를 통해 자신의 글을 게시할 수 있습니다. 현재 수백 명의 정기 구독자에게 글이 공개가 되며, 팀 블로그가 구글 등의 검색 상위권에 이르게 됨으로 자신의 글이 상위 검색에 노출되는 간접적인 혜택을 누릴 수 있습니다.

온라인 세미나

한국 마이크로소프트와 팀 자체에서 진행하는 여러 가지 온라인 세미나의 스피커로 활동하게 됩니다.

온라인 커뮤니티(예정)

온라인 커뮤니티 활동과 함께 커뮤니티 운영 활동을 하게 됩니다.

   

오프라인 활동 영역

오프라인 세미나

한국 마이크로소프트와 팀 자체에서 진행하는 오프라인 세미나의 스피커로 활동합니다.

기고

팀 블로그를 통해 축적된 자신의 콘텐츠는 월간 잡지 등에 기고할 수 있습니다.

책 집필, 번역(예정)

다양한 노하우를 책으로 집필하고, 외국의 유명 서적을 번역하는 활동을 계획하고 있습니다.

Microsoft MVP 추천

MVP 에 되고자 하시는 분은 한국 이크로소프트 직원과 마이크로소프트 MVP 의 추천을 드립니다.

     

지원 방법

umc골벵이dotnetxpert.com 으로 아래의 양식으로 메일 보내주세요.

이름

  

나이

  

블로그

활동 커뮤니티

  

전화번호

  

티스토리 아이디

  

소개

(직업 및 회사명 포함)

관심 분야

(중복 가능)