[김재진][API]Dialog에서 Slider Componet를 사용하기

Programming/MFC 2010. 7. 13. 18:23 Posted by 알 수 없는 사용자
float g_fPos1 = 1; // Slider 수치값을 저장할 변수

// Dialog Callback Function Create
BOOL CALLBACK  DlgMapInfo(HWND hDlg, UINT iMessage, WPARAM wParam, LPARAM lParam)
{
    switch(iMessage)
    {
    case WM_INITDIALOG:
        // SendMessage(GetDlgItem(hDlg, IDC_SLIDER1) Slider를 사용한 Wnd 값을 가져온다.
        // TBM_SETRANGE는 SLIDER Range 설정
        // MAKELPARAM(최소값, 최대치) 값을 설정한다.
        SendMessage(GetDlgItem(hDlg, IDC_SLIDER1), TBM_SETRANGE, false, MAKELPARAM(1, 10));
        // 위치값 설정 TBM_SETPOS
        SendMessage(GetDlgItem(hDlg, IDC_SLIDER1), TBM_SETPOS, NULL, 0);
        // Edit Component에 출력
        SetDlgItemInt(hDlg, IDC_EDIT1, (int)g_fPos1, true);
        // Dialogbox를 새로 고침
        InvalidateRect(hDlg, NULL, true);
        return true;

    // Slider Scoll 변경 Event 처리
    case WM_HSCROLL:
        // 실행된 윈도우 Handle 값을 가져와서 Slider Component의 값을 읽어온다.
        if((HWND)lParam == GetDlgItem(hDlg, IDC_SLIDER1))
        {
            // Slider Component 의 값을 읽어와 g_fPos에 저장
            // TBM_GETPOS : Slider의 위치값을 읽어온다.
            g_fPos1 = (float)SendMessage(GetDlgItem(hDlg, IDC_SLIDER1), TBM_GETPOS, 0, 0);
            // Edit Component 에 값을 입력한다.
            SetDlgItemInt(hDlg, IDC_EDIT1, (INT)g_fPos1 , FALSE);
            InvalidateRect(hDlg, NULL, true);
        }

        return true;
    case WM_DESTROY:
        EndDialog(hDlg, IDCANCEL);
        return true;
    }
    return false;
}

※ 주의사항 : Resource에 Dialog를 생성하고 그 안에 Slider Component를 생성한 후에 적용 시켜야 함.

'Programming > MFC' 카테고리의 다른 글

[서동권] MFC 메뉴 삭제하는 방법  (0) 2010.06.06
[장영수]MFC-Cimage  (1) 2010.05.27

[김재진]메모리 누수 확인 방법

Programming 2010. 7. 12. 13:00 Posted by 알 수 없는 사용자
header 추가

#ifdef _DEBUG
#define CRTDBG_MAP_ALLOC
#include <stdlib.h>
#include <crtdbg.h>
#endif

WinMain() 함수에
_CrtDumpMemoryLeaks();
Function Call

위와 같이 실행 할 경우 Debug모드로 실행 후 종료 시  아래와 같은 메시지 출력된다.
Detected memory leaks!
Dumping objects ->
{57} normal block at 0x003E5D38, 36 bytes long.
 Data: <                > 00 00 00 00 00 00 00 00 00 00 00 80 00 00 00 00
{56} normal block at 0x003E5BF0, 268 bytes long.
 Data: <                > CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD
Object dump complete.
---------------------------------------------------------------------------------------
메 모리 누수 검출 방법

1. 함수를 이용한 메모리 누수 검색방법

영역표시된 부분(57)이 메모리 누수가 발생하는 프로그램 주소값이다. 이 주소 값을 이용하여
라는 함수 파라미터 값으로 주소 값을 입력하게 되면 메모리 할당 및 메모리 위치, 메모리 누수 위치는 중단점에서 멈추게 된다.

2. Visual Studio 에 있는 기능을 이용한 검색 방법


영역표시된 부분이 메모리 누적이 발생한 위치값이다.
이것을 Ctrl + B를 누르게 되면 새 중단점을 지정할 수 있다.



위와 같이 설정 후 확인을 누르게 되면 메모리 누수가 발생하는 곳에서 멈추게 된다.

※ 주의사항 : 이 중단점(Break Point)는 Visual Studio에서 표시가 이루어지지 않는다. 그렇기 때문에 설정된 중단점을 삭제하기 위해서는  모든 중단점 해제(ctrl + shift + F9)로 중단점 해제해야 한다.
그렇지 않으면 매번 디버그 할때마다 같은 지역에서 멈추게 된다.

난 .... 끝없이 나오더라 orz

[김재진] 카메라 시점 자동 설정

Programming/DirectX 2010. 7. 6. 17:01 Posted by 알 수 없는 사용자

카메라 시점 자동 설정(강제적으로 카메라를 Object를 바라 보도록 설정하기위한 방법)



Y값과 Z값은 0.1f 이상이어야 한다.
D3DXVECTOR3 DA = D3DXVECTOR3(0.0f, 0.1f, 0.0f); // Object 위치정보를 저장한 Vector Y값
m_fXAngle = D3DXVec3Dot(&DA, &m_vCameraPos);
zDA = D3DXVECTOR3(0.1f, 0.0f, 0.0f);                     // Object 위치정보를 저장한 Vector X값
m_fYAngle = -D3DXVec3Dot(&m_vCameraPos, &DA);

// D3DXToDegree : 값
// D3DXToRadian : 각도
// 회전값을 저장한 Quaternion변수에 Rotation값을 저장
D3DXQuaternionRotationYawPitchRoll( &m_qRotation
                                                     , D3DXToRadian(m_fYAngle)
                                                     , D3DXToRadian(m_fXAngle)
                                                     , 0.0f);
   

// 회전과 이동을 곱한 것을 m_qRotation을 행렬변수인 m_matOrientation로 변경
D3DXMatrixAffineTransformation(&m_matOrientation, 1.0f, NULL, &m_qRotation, &m_vCameraPos);

/* m_matOrientation을 m_matView에 반대값을 입력
    (카메라가 움직이는것이 아닌 월드행렬이 움직이는 것이기 때문에) */
D3DXMatrixInverse( &m_matView, NULL, &m_matOrientation );

단, 카메라의 위치가 Z축이 0.001보다 낮다면 X와 Y값의 변경 가중치 값을 변경해야 한다.
(0.5f 이상 변경해야함)

문제점 많은 오브젝트 시점 바라보게 만드는 코딩임...
해결할 사람 ㄱㄱㄱㄱ

[장영수] 게임 UI 구현에 관한글

Programming/etc. 2010. 6. 18. 17:54 Posted by 알 수 없는 사용자
http://wrice.egloos.com/4970240

그냥 참고할만한 수준의 글이지만 링크해봅니다.

[손동진] TCP 서버/클라이언트 구조

Programming/Network 2010. 6. 14. 15:04 Posted by 알 수 없는 사용자
1. TCP 서버의 흐름

< TCP 서버/클라이언트 구조 >


< 반복 서버의 흐름 >



2. 함수 설명

2.1 서버

2.1.1 WSAStartup() / WSACleanup()

* 윈속 라이브러리 초기화

int WSAStartup( WORD wVersionRequested, LPWSASATA lpWSAData );

성공 시 0, 실패 시 0이 아닌 에러코드 값 반환

wVersionRequested: 프로그래머가 사용할 윈속의 버전정보 전달.

lpWSAData:  WSADATA라는 구조체 변수의 주소 값 전달.


* 윈속 라이브러리 해제

int WSACleanup(void);

성공 시 0, 실패 시 SOCKET_ERROR 반환



2.1.2 socket()

* 소켓 생성

SOCKET socket( int af, int type, int protocol );

성공 시 소켓 핸들, 실패 시 INVALID_SOCKET 반환

af: 소켓이 사용할 프로토콜 체계 정보 전달

type: 소켓의 데이터 전송 방식에 대한 정보 전달

protocol: 두 컴퓨터간 통신에 사용되는 프로토콜 정보 전달



2.1.3 bind()

* 소켓에 주소 할당

int bind( SOCKET s, const struct sockaddr* name, int namelen );

성공 시 소켓 핸들, 실패 시 INVALID_SOCKET 반환

s: 주소정보를 할당할 소켓의 핸들

name: 할당하고자 하는 주소정보를 지니는 구조체 변수의 주소 값

namelen: 두번째 인자로 전달된 구조체 변수의 길이 정보



2.1.4 listen()

* 연결요청 대기 상태

int listen( SOCKET s, int backlog );

성공 시 0, 실패 시 SOCKET_ERROR 반환

s: 연결요청 대기상태에 두고자 하는 소켓의 핸들 전달, 이 함수의 인자로 전달된 핸들의 소켓이 서버 소켓(리스닝 소켓)이 된다.

backlog: 연결요청 큐의 크기정보 전달, 5가 전달되면 큐의 크기가 5가 되어 클라이언트의 연결요청을 5개까지 대기시킬 수 있다.



2.1.5 accept()

* 연결요청 수락

SOCKET accept( SOCKET s, struct sockaddr* addr, int* addrlen );

성공 시 소켓 핸들, 실패 시 INVALID_SOCKET 반환

s: 서버 소켓의 핸들 전달

addr: 연결요청 한 클라이언트의 주소정보를 담을 변수의 주소 값 전달, 함수호출이 완료되면 인자로 전달된 주소의 변수에는 클라이언트의 주소정보가 채워진다.

addrlen: 두 번째 매개변수 addr에 전달된 주소의 변수 크기를 바이트 단위로 전달, 단 크기 정보를 변수에 저장한 다음에 변수의 주소 값을 전달한다. 그리고 함수호출이 완료되면 크기정보로 채워져 있던 변수에는 클라이언트의 주소정보 길이가 바이트 단위로 계산되어 채워진다.



2.1.6 recv()

* 자료 받기

int recv( SOCKET s, const char* buf, int len, int flags );

성공 시 수신한 바이트 수(단 EOF 전송 시 0), 실패 시 SOCKET_ERROR 반환

s: 데이터 수신 대상과의 연결을 의미하는 소켓의 핸들 값 전달

buf: 수신된 데이터를 저장할 버퍼의 주소 값 전달

len: 수신할 수 있는 최대 바이트 수 전달

flags: 데이터 수신 시 적용할 다양한 옵션 정보 전달



2.1.7 send()

* 자료 보내기

int send( SOCKET s, const char* buf, int len, int flags );

성공 시 전송된 바이트 수, 실패 시 SOCKET_ERROR 반환

s: 데이터 전송 대상과의 연결을 의미하는 소켓의 핸들 값 전달

buf: 전송할 데이터를 저장하고 있는 버퍼의 주소 값 전달

len: 전송할 바이트 수 전달

flags: 데이터 전송 시 적용할 다양한 옵션 정보 전달



2.1.7 closesocket()

* 소켓 닫기

int closesocket( SOCKET s );

성공 시 0, 실패 시 SOCKET_ERROR 반환



2.2 클라이언트

2.2.1 connect()

* 서버에 연결 요청

int connect( SOCKETs, const struct sockaddr* name, int namelen );

성공 시 0, 실패 시 SOCKET_ERROR 반환

s: 클라이언트 소켓의 핸들 전달

name: 연결요청 할 서버의 주소정보를 담은 변수의 주소 값 전달, 함수 호출이 완료되면 인자로 전달된 주소의 변수에는 클라이언트의 주소정보가 채워진다.

namelen: 두 번째 매개변수 servaddr에 전달된 주소의 변수 크기를 바이트 단위로 전달, 단 크기정보를 변수에 저장한 다음에 변수의 주소 값을 전달한다. 그리고 함수호출이 완료되면 크기정보로 채워져 있던 변수에는 클라이언트의 주소정보 길이가 바이트 단위로 계산되어 채워진다.

[임지웅] DX - 법선맵핑 (Normal map)

Programming/DirectX 2010. 6. 10. 21:31 Posted by 알 수 없는 사용자

법선맵핑이란?
 법선 맵핑이란 텍스처의 텍셀(텍스처의 각 픽셀)에 RGB값대신 그 해당 텍셀의 법선 벡터가 들어간 법선맵텍스쳐를  사용해서 특수하게 맵핑하는 기법이다.

법선 맵핑을 사용하는 이유는?
  3D 모델링한 오브젝트는 결국은 2D화면에 출력되는데 미세한 요철(凹凸)등의 부분은 많은 폴리곤을 써서 고퀄리티로 만들더라도 실제로 표현될때는 픽셀단위로 표현되기때문에 세세하게 모델링된 폴리곤을 표현할수가 없다. 게다가 표현이 되지 않더라도 요철부분의 폴리곤들도 모두 연산되기때문에 메모리공간도 많이 잡아먹고 불필요한 부하가 걸리게 되므로 몹시 비효율 적이다.
 이런 문제를 해결하기 위해서 나온 효과적인 방법중하나로 법선맵핑이다.

요철(凹凸)을 표현하는 방법.
 요철이 요철로 보이는 이유는 튀어나온 부분과 들어간 부분에서 생기는 그림자 때문인데 그림자가 생기는 것은 광원과 밀접한 관계가 있다.
 광원처리에는 보는눈에 방향인 시점 벡터와 광원의 방향인 광원벡터, 그리고 오브젝트의 법선벡터가 필요한데, 광원 벡터와 법선벡터를 이용해서 빛의 반사를 계산해서 결국은 시점벡터에 보이게 되는것이므로 요철부분의 법선벡터만 있다면 음영을 만들어 요철처럼 표현할수있다.
 미세요철의 음영은 결국 픽셀에 그린 결과로 나오기만 하면 되므로, 픽셀단위로 법선벡터를 얻을 수 있으면 된다. 픽셀단위의 법선벡터를 얻기위해선 텍스쳐를 사용하면 된다.

법선맵(Normalmap) 텍스처
 텍스처를 입히면 텍스처의 텍셀의 보관된 RGB컬러 값을 화면에 그리는데, 텍스처의 텍셀의 컬러값에 RGB값대신 법선벡터의 값을 넣어두고 그 텍셀에서의 법선벡터값과 광원과의 광원처리 즉 반사를 연산하면 픽셀단위로 조명이 들어가기 때문에 미세요철의 음영을 표현할 수 있다.

텍스처의 텍셀에 RGB값대신 벡터(x.y.z)값을 넣는다.
 일반적인 텍스처의 텍셀의 경우 ARGB의 컬러값이 들어가는데 A(투명도)값을 제외한 RGB대신 벡터의 x, y, z,성분을 넣어준다.

R -> x  ,  G -> y  ,  B -> z

이렇게 텍셀에 법선벡터를 RGB값대신 넣어두는 텍스처를 법선맵(Normalmap)이라고 한다. 랜더링시에 이 법선맵의 법선벡터를 이용해서 광원처리를 한다.

법선맵의 종류
 법선맵 텍스처는 2D상의 법선벡터를 저장하고있지만 3D상의 오브젝트 폴리곤의 법선방향은 고려하지 않고있으므로 바로 사용할수는 없고 좌표계 통일을 위한 변환이 필요하다. 여기서 기준 좌표계에따라서 오브젝트 공간 법선맵과 접선공간 법선맵으로 나뉜다.

-오브젝트공간 법선맵
 법선벡터가 기준으로 삼는 좌표계가 오브젝트의 로컬 좌표계이다. 즉 오브젝트의 원점이 법선벡터들의 원점이된다. 이 기법은 오브젝트가 몰핑(다른 오브젝트등에 묻히는)되지않는 벽면이나 바닥 갑옷등에 사용하면 좋다. 하지만 케릭터등의 오브젝트는 애니메이션될때 스키닝기법을 써서 정점을 몰핑하는데 몰핑되면 법선벡터의 방향이 바껴야 되서 오브젝트공간 법선맵은 사용할수가없다. 또 좌우대칭되는 오브젝트의 경우 텍스처를 반쪽만 만들어서 대칭으로 맵핑하는 기법을 사용하는데, 오브젝트공간 법선맵은 기준좌표계가 오브젝트의 로컬 좌표계이기 때문에 대칭점에서 법선벡터가 달라서 전체에 대해서 법선맵을 만들어줘야된다.

-접선공간 법선맵
 정점공간 법선맵이라고도 한다. 이 방법은 모든 법선벡터를 각 정점이 원점이되는 접선공간으로 변환해서 보관하는 방식인데 잘 모르겠으요 -_-; 나중에 뒤에서 나온답니다;;

법선맵핑의 효과
  법선맵핑은 저폴리곤 모델을 고폴리곤처럼 보여주는 기법이다. 일반적으로 1000개 정도의 폴리곤에 법선맵을 적용할경우 20000~30000개의 폴리곤으로 모델링한것 이상의 효과를 볼수있다.
 즉 저폴리곤 모델 + 법선맵 = 고폴리곤 모델

법선맵 생성하기
 -놉이맵에 의한 생성법
 텍스처를 흑백으로 변환하면 높이맵이 생성된다 (흰색은 높고 검은색은 낮은걸로 치면 0~255의 높이맵이된다). 이 높이맵에서 인접한 텍셀들간의 고저차를 비교해서 기울기를 나타내는 미분벡터를 만든다.(미분하면 기울기가 나온다) 이렇게 만들어진 미분벡터 2개(x방향으로의 미분벡터, y방향으로의 미분벡터)를 외적하면 법선벡터가 만들어지는데 이 법선벡터가 그 텍셀의 법선벡터가 된다.

-오브젝트 비교에 의한 생성법
 오브젝트를 저폴리곤과 고폴리곤으로 두 개를 만들고 두 모델의 차이를 비교해서 법선맵을 만드는 방법이다. 저폴리곤 모델의 텍셀에서 고폴리곤으로 직선을 쏴서 접하는 지점의 법선벡터를 저장하는 방법이다.
 요즘에는 이방법을 사용하는 추세다.

벡터를 RGB로 변환하는 방법
 법선벡터는 단위벡터이므로 단위 벡터 v 를 RGB로 변환한다.
 ARGB중에 투명값을 나타내는 A값은 제외하고 RGB값에 각각 벡터v의 (x, y, z)값이 들어가게되는데 벡터는 단위벡터이므로 -1 에서 +1의 값이고 RGB값은 각각 8비트이므로 0 에서 255사이의 값이다. 그래서 -1 -> 0 ,  1 -> 255에 대응되게 해야되는데 그 함수는 다음과 같다.

R = (DWORD) (127.0 * x + 128.0)
G = (DWORD) (127.0 * y + 128.0)
B = (DWORD) (127.0 * z + 128.0)

Color = ( (R<<16) | (G<<8) | B )

이렇게 하면 Color값에는 벡터 v = (x, y, z)의 정보가 RGB값으로 변환되어 들어가게 된다.
# ARGB에 각각 8비트씩 할당해서 값을 저장하지않고 A값과 B의 값을 제외하고 R,G값에 x, y 를 각각 16비트씩 변환하면 보다 정밀도를 높게 할 수 있다. z값은 벡터 v가 단위벡터이므로 루트(x^2 + y^2 + z^2) = 1임을 이용해서 얻을 수 있는
z = 루트( 1 - (x^2 + y^2) ) 식으로 x, y값을 이용해 z값을 넣어주면된다.

# 법선맵 디자인툴에는 Z-BRUSH등이 있다.

===============================================================================================================
결국 오브젝트에 텍스처 + 법선맵 텍스처를 혼합해서 적용해서 픽셀당 조명효과로 오브젝트의 요철을 효과적으로 표현하는 방법이었습니다 !!
일단 간단(?)하게 정리해봤는데요. 좀이라도 도움이 됬음 좋겠네요;; 소스는 첨부파일

<-



음...서버쪽으로 마음을 굳히고 보니

클라이언트와 서버를 둘다 병행하기는 힘들거 같아서

앞으로 DirectX 에 관한 스터디 동참은 못할거 같네요..

동진형님께서는 두개 모두 하신다고 하시지만 저는 둘다 했다가는..

어느하나 제대로 못하게 되는 상황이 올거 같아서 ㅜㅜ..

대신 서버쪽을 열심히 파서 Pathfinder 의 서버를 책임질수 있는 역량을 키우도록 하겠습니다.

Pathfinder - Server 가 되는건가요? -_-ㅋ;

보호되어 있는 글입니다.
내용을 보시려면 비밀번호를 입력하세요.

[강민수] DirectX-기초수학

Programming/DirectX 2010. 6. 10. 11:52 Posted by 리뷰하는 (게임)프로그래머_리프TV

삼각 함수

3개의 변 A, B, C가 존재 할 때
A(빗변)의 제곱 = B(밑변)의 제곱 + C(높이)의 제곱

cos = 밑변 / 빗변 ( r = 1, 밑변의 길이 )
sin = 높이 / 빗변 ( r = 1, 높이의 길이 )
tan = 높이 / 밑변 ( r = 1, 연장선의 높이의 길이?ㅋ )

밑변 : 세타 + 직각이 있는 곳
빗변 : 세타 + 직각이 아닌 곳
높이 : 직각 + 세타가 아닌 곳

  0 도 30 도 45 도 60 도 90 도
 cos  루트3/2   루트2/2  1/2  0
 sin 0  1/2  루트2/2  루트3/2  1
 tan  루트3/3  1  루트3  무한

파이/2 = 90도
파이 = 189도
3파이/2 = 270도
2파이 = 360도

역수란?

a의 역수 = 1/a ( 즉, 곱하였을 때 1이 되는 수 )

1/cos세타 -> cos세타의 역수 -> sec세타 라고 함
1/sin세타 -> sin세타의 역수 -> cosec세타 라고 함
1/tan세타 -> tan세타의 역수 -> cotan세타 라고 함

덧셈 정리( 가법 정리 )

cos( A + B ) = ( cos A * cos B ) - ( sin A * sin B )
cos( A - B ) = ( cos A * cos B ) + ( sin A * sin B )
sin( A [+ or -] B ) = ( sin A * cos B ) [+ or -] ( cos A * sin B )

벡터
단위 벡터 : 방향을 가지는 크기가 1인 벡터

벡터의 내적, 외적
내적 : 두 벡터 안의 각
외적 : 법선 벡터를 구하기 위해 사용

벡터 A - 벡터 B = 벡터 B에서 A로 이동하는 벡터
벡터 B - 벡터 A = 벡터 A에서 B로 이동하는 벡터

벡터 A + 벡터 B = 그 사이를 가로 지르는 벡터

asin, acos, atan

사용 이유 : 2변의 길이를 알고, 세타의 각을 모를 때
세타를 도출하기 위해 필요 하다.

ps : 글만 봐서는 무슨 내용이신지 잘 모르실 겁니다.

딱히 그렇다고 그림을 찾아서 끼우기 보단 제가 직접 그리면서 설명을 하게 될거 같으니,
최대한 열심히 설명 하겠지만, 자신은 없네요 ㅎㄷㄷ

[손동진] 빌보드 (Billboard)

Programming/DirectX 2010. 6. 7. 15:42 Posted by 알 수 없는 사용자
1. 빌보드

텍스처중 항상 정면을 바라봐야 하는 경우가 있는데, 이러한 처리를 하기 위한 전문적인 기법을 '빌보드'라고 한다.

예를 들어 길가의 나무, 파티클 등의 이펙트를 출력하는 용도로 많이 사용한다.


1.1 빌보드의 종류

 종류
 용도
 Y축 빌보드
 지면에 고정된 이미지 출력
 전체 화면 빌보드
 파티클 등의 이미지 출력


1.1.1 Y축 빌보드

카메라 변환 행렬의 성분 중, Y축 회전 행렬 부분만 역변환하면 빌보드를 구할 수 있다.




1.1.2 전체 화면 빌보드

카메라 변환 행렬의 성분 중, 회전 행렬 전체를 역변환하면 빌보드를 구할 수 있다.