반응형

//-----------------------------------------------------------------------------
// File: Meshes.cpp
//
// Desc: 보다 멋진 기하 정보를 출력하기 위해서는 전문적인 3D모델러가 만든 모델을
//       파일로 읽어들이는 것이 일반적이다. 다행스럽게도 D3DX에는 강력한 X파일
//       처리 기능이 있어서 정점 버퍼, 인덱스 버퍼 생성 등의 많은 부분을 대신해 
//       준다. 이번 예제는 D3DXMESH를 사용해 파일을 읽어서 이 파일과 연관된 제질과
//       텍스처를 함께 사용하는 것을 알아본다.
//
//       Note: 이번에 소개 되지는 않짐나 나중에 사용하게 될 강력한 기능 중 하나는
//       FVF를 지정하여 새로운 메시를 복제(clone)하는 것이다. 이 기능을 사용하여
//       텍스처 좌표나 법선벡터 등을 기존 메시에 추가한 새로운 메시를 생성할 수 있다.
//       (나중에 Cg, HLSL 등을 공부할 때 많이 사용될 것이다.
//
// Copyright (c) Microsoft Corporation. All rights reserved.

//-----------------------------------------------------------------------------

// 전역 변수
//-----------------------------------------------------------------------------
LPDIRECT3D9         g_pD3D = NULL; // D3DDevice 생성할 D3D 객체 변수
LPDIRECT3DDEVICE9   g_pd3dDevice = NULL; // 렌더링에 사용될 D3D 디바이스

LPD3DXMESH          g_pMesh = NULL; // 메시 객체
D3DMATERIAL9*       g_pMeshMaterials = NULL; // 메시에 사용될 제질
LPDIRECT3DTEXTURE9* g_pMeshTextures = NULL; // 메시에 사용될 텍스처
DWORD               g_dwNumMaterials = 0L;   // 메시에 사용중인 재질의 수

 


//-----------------------------------------------------------------------------
// Name: InitD3D()
// Desc: Direct3D 초기화
//-----------------------------------------------------------------------------
HRESULT InitD3D( HWND hWnd )
{
    // 디바이스를 생성하기위한 D3D 객체 생성
    if( NULL == ( g_pD3D = Direct3DCreate9( D3D_SDK_VERSION ) ) )
        return E_FAIL;

    // 디바이스를 생성할 구조체
    // 복잡한 오브젝트를 그리기 위해 Z버퍼를 사용한다.
    D3DPRESENT_PARAMETERS d3dpp;
    ZeroMemory( &d3dpp, sizeof( d3dpp ) );
    d3dpp.Windowed = TRUE;
    d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
    d3dpp.BackBufferFormat = D3DFMT_UNKNOWN;
    d3dpp.EnableAutoDepthStencil = TRUE;
    d3dpp.AutoDepthStencilFormat = D3DFMT_D16;

    // 디바이스 생성
    if( FAILED( g_pD3D->CreateDevice( D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hWnd,
                                      D3DCREATE_SOFTWARE_VERTEXPROCESSING,
                                      &d3dpp, &g_pd3dDevice ) ) )
    {
        return E_FAIL;
    }

    // Z버퍼 기능을 켠다.
    g_pd3dDevice->SetRenderState( D3DRS_ZENABLE, TRUE );

    // 주변광원(ambient)값을 최대 밝기로
    g_pd3dDevice->SetRenderState( D3DRS_AMBIENT, 0xffffffff );

    return S_OK;
}

 


//-----------------------------------------------------------------------------
// Name: InitGeometry()
// Desc: 메시 읽기, 재질과 텍스처 배열 생성
//-----------------------------------------------------------------------------
HRESULT InitGeometry()
{
 // 재질을 임시로 보관할 버퍼 선언
    LPD3DXBUFFER pD3DXMtrlBuffer;

    // 메시 파일을 읽어 들인다. 재질 정보도 함께 읽는다.
    if( FAILED( D3DXLoadMeshFromX( L"Tiger.x", D3DXMESH_SYSTEMMEM,
                                   g_pd3dDevice, NULL,
                                   &pD3DXMtrlBuffer, NULL, &g_dwNumMaterials,
                                   &g_pMesh ) ) )
    {
        // 현재 폴더에 없으면 상위 폴더 검색
        if( FAILED( D3DXLoadMeshFromX( L"..\\Tiger.x", D3DXMESH_SYSTEMMEM,
                                       g_pd3dDevice, NULL,
                                       &pD3DXMtrlBuffer, NULL, &g_dwNumMaterials,
                                       &g_pMesh ) ) )
        {
            MessageBox( NULL, L"Could not find tiger.x", L"Meshes.exe", MB_OK );
            return E_FAIL;
        }
    }

    // 재질 정보와 텍스처 정보를 따로 뽑아낸다.
    D3DXMATERIAL* d3dxMaterials = ( D3DXMATERIAL* )pD3DXMtrlBuffer->GetBufferPointer();
    g_pMeshMaterials = new D3DMATERIAL9[g_dwNumMaterials];
    if( g_pMeshMaterials == NULL )
        return E_OUTOFMEMORY;
    g_pMeshTextures = new LPDIRECT3DTEXTURE9[g_dwNumMaterials];
    if( g_pMeshTextures == NULL )
        return E_OUTOFMEMORY;

    for( DWORD i = 0; i < g_dwNumMaterials; i++ )
    {
        // 재질을 복사한다.
        g_pMeshMaterials[i] = d3dxMaterials[i].MatD3D;

        // 재질 주변광원 정보를 Diffuse
        g_pMeshMaterials[i].Ambient = g_pMeshMaterials[i].Diffuse;

        g_pMeshTextures[i] = NULL;
        if( d3dxMaterials[i].pTextureFilename != NULL &
            lstrlenA( d3dxMaterials[i].pTextureFilename ) > 0 )
        {
            // 텍스처를 파일에서 로드한다.
            if( FAILED( D3DXCreateTextureFromFileA( g_pd3dDevice,
                                                    d3dxMaterials[i].pTextureFilename,
                                                    &g_pMeshTextures[i] ) ) )
            {
                // 텍스처를 로드 한다.
                const CHAR* strPrefix = "..\\";
                CHAR strTexture[MAX_PATH];
                strcpy_s( strTexture, MAX_PATH, strPrefix );
                strcat_s( strTexture, MAX_PATH, d3dxMaterials[i].pTextureFilename );
                // 텍스처가 현재 폴더에 없으면 상위 폴더 검색
                if( FAILED( D3DXCreateTextureFromFileA( g_pd3dDevice,
                                                        strTexture,
                                                        &g_pMeshTextures[i] ) ) )
                {
                    MessageBox( NULL, L"Could not find texture map", L"Meshes.exe", MB_OK );
                }
            }
        }
    }

    // 임시로 생성한 재질 버퍼 초기화
    pD3DXMtrlBuffer->Release();

    return S_OK;
}

 


//-----------------------------------------------------------------------------
// Name: Cleanup()
// Desc: 초기화된 객체들 소거
//-----------------------------------------------------------------------------
VOID Cleanup()
{
    if( g_pMeshMaterials != NULL )
        delete[] g_pMeshMaterials;

    if( g_pMeshTextures )
    {
        for( DWORD i = 0; i < g_dwNumMaterials; i++ )
        {
            if( g_pMeshTextures[i] )
                g_pMeshTextures[i]->Release();
        }
        delete[] g_pMeshTextures;
    }
    if( g_pMesh != NULL )
        g_pMesh->Release();

    if( g_pd3dDevice != NULL )
        g_pd3dDevice->Release();

    if( g_pD3D != NULL )
        g_pD3D->Release();
}

 

//-----------------------------------------------------------------------------
// Name: SetupMatrices()
// Desc: 월드, 뷰, 프로젝션 메트릭스를 설정한다.
//-----------------------------------------------------------------------------
VOID SetupMatrices()
{
    // 월드 행렬 설정
    D3DXMATRIXA16 matWorld;
    D3DXMatrixRotationY( &matWorld, timeGetTime() / 1000.0f );
    g_pd3dDevice->SetTransform( D3DTS_WORLD, &matWorld );

    // 뷰 행렬 설정
    D3DXVECTOR3 vEyePt( 0.0f, 3.0f,-5.0f );
    D3DXVECTOR3 vLookatPt( 0.0f, 0.0f, 0.0f );
    D3DXVECTOR3 vUpVec( 0.0f, 1.0f, 0.0f );
    D3DXMATRIXA16 matView;
    D3DXMatrixLookAtLH( &matView, &vEyePt, &vLookatPt, &vUpVec );
    g_pd3dDevice->SetTransform( D3DTS_VIEW, &matView );

    // 프로젝션 행렬 설정
    D3DXMATRIXA16 matProj;
    D3DXMatrixPerspectiveFovLH( &matProj, D3DX_PI / 4, 1.0f, 1.0f, 100.0f );
    g_pd3dDevice->SetTransform( D3DTS_PROJECTION, &matProj );
}

 


//-----------------------------------------------------------------------------
// Name: Render()
// Desc: 화면 그리기
//-----------------------------------------------------------------------------
VOID Render()
{
    // 후면 버퍼와 Z버퍼를 지운다.
    g_pd3dDevice->Clear( 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER,
                         D3DCOLOR_XRGB( 0, 0, 255 ), 1.0f, 0 );

    // 렌더링 시작
    if( SUCCEEDED( g_pd3dDevice->BeginScene() ) )
    {
        // 월드, 뷰, 프로젝션 행렬 설정
        SetupMatrices();

        // 메시는 재질이 다른 메시별로 부분집합을 이루고 있다.
        // 이들을 루프를 수행하여 모두 그려준다.
        for( DWORD i = 0; i < g_dwNumMaterials; i++ )
        {
            // 부분집합 메시의 재질과 텍스처 설정
            g_pd3dDevice->SetMaterial( &g_pMeshMaterials[i] );
            g_pd3dDevice->SetTexture( 0, g_pMeshTextures[i] );

            // 부분집합 메시 출력
            g_pMesh->DrawSubset( i );
        }

        // 렌더링 종료
        g_pd3dDevice->EndScene();
    }

    // 후면 버퍼를 보이는 화면으로
    g_pd3dDevice->Present( NULL, NULL, NULL, NULL );
}

 


//-----------------------------------------------------------------------------
// Name: MsgProc()
// Desc: 윈도우 메시지 프로시저
//-----------------------------------------------------------------------------
LRESULT WINAPI MsgProc( HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam )
{
    switch( msg )
    {
        case WM_DESTROY:
            Cleanup();
            PostQuitMessage( 0 );
            return 0;

  case WM_KEYDOWN: // 키를 눌렀을때
   if( wParam == VK_ESCAPE ) { // esc를 눌렀을때
    ::DestroyWindow(hWnd);
    return 0;
   }
 }

    return DefWindowProc( hWnd, msg, wParam, lParam );
}

 


//-----------------------------------------------------------------------------
// Name: WinMain()
// Desc: 프로그램 시작점
//-----------------------------------------------------------------------------
INT WINAPI wWinMain( HINSTANCE hInst, HINSTANCE, LPWSTR, INT )
{
    // 윈도우 클래스 등록
 WNDCLASSEX wc =
    {
        sizeof( WNDCLASSEX ), CS_CLASSDC, MsgProc, 0L, 0L,
        GetModuleHandle( NULL ), NULL, NULL, NULL, NULL,
        L"D3D Tutorial", NULL
    };
    RegisterClassEx( &wc );

    // 윈도우창 생성
    HWND hWnd = CreateWindow( L"D3D Tutorial", L"D3D Tutorial 06: Meshes",
                              WS_OVERLAPPEDWINDOW, 100, 100, 300, 300,
                              NULL, NULL, wc.hInstance, NULL );

    // Direct3D 초기화
    if( SUCCEEDED( InitD3D( hWnd ) ) )
    {
        // 기하 정보 초기화
        if( SUCCEEDED( InitGeometry() ) )
        {
            // 윈도우 출력
            ShowWindow( hWnd, SW_SHOWDEFAULT );
            UpdateWindow( hWnd );

            // 메시지 루프
            MSG msg;
            ZeroMemory( &msg, sizeof( msg ) );
            while( msg.message != WM_QUIT )
            {
                if( PeekMessage( &msg, NULL, 0U, 0U, PM_REMOVE ) )
                {
                    TranslateMessage( &msg );
                    DispatchMessage( &msg );
                }
                else
                    Render();
            }
        }
    }
 //등록된 클래스 소거
    UnregisterClass( L"D3D Tutorial", wc.hInstance );
    return 0;
}

반응형

'DirectX > DirectX 9.0' 카테고리의 다른 글

[DirectX 9.0] Textures  (0) 2014.02.11
[DirectX 9.0] Lights  (0) 2014.02.11
[DirectX 9.0] Matrices  (0) 2014.02.11
[DirectX 9.0] Vertices  (0) 2014.02.11
CreateDevice  (0) 2011.03.02
반응형

C#을 공부하는데 참고하면 좋은 블로그

책이 없어도 읽으면서 공부할 수 있다.

http://blog.naver.com/skyarro

반응형

'Helpful' 카테고리의 다른 글

유니티와 NGUI  (0) 2014.02.11
반응형

//-----------------------------------------------------------------------------
// File: Textures.cpp
//
// Desc: 보다 좋은 광원과 제질은 3차원 오브체트는 텍스쳐와 결합될 때 더욱 현실감
//   있게 된다. 텍스처란 마치 벽지 같은 것으로, 적당하게 늘이거나 줄여서 면에
//       붙이게 된다. 일반적으로 텍스처는 이미지 파일(jpg, bmp, tga등)을 D3DX 계열
//   의 함수를 사용해서 읽어들여서 사용하게 된다. 정점ㅈ 버퍼와 마찬가지로 
//       Lock()과 Unlock() 함수를 사용해서 메모리에 직접 접근할 수도 있다. 이렇게
//   생성한 텍스처를 면에 붙이는 행위를 맵핑이라고 한다.
//
//   텍스쳐와 기하 정보와 연결되기 위해서 텍스쳐 좌표계를 갖게 되는데, 각각의
//       정점은 이러한 텍스처 좌표를 포함하고 있어야 한다. 일반적으로 (U,V)좌표계를
//       사용하고 U,V의 값은 0.0 ~ 0.1 사이의 값이다. 텍스처 좌표는 최초에 설정될 수
//       도 있지만 실시간으로 직접 계산하여 더 다양한 효과를 낼 수도 있다.
//
// Copyright (c) Microsoft Corporation. All rights reserved.
// 아래 주석을 지우면 텍스쳐가 고정된 것 처럼 보여진다.

//#define SHOW_HOW_TO_USE_TCI

//-----------------------------------------------------------------------------
// 전역 변수
//-----------------------------------------------------------------------------
LPDIRECT3D9             g_pD3D = NULL; // D3DDevice를 생성할 D3D객체 변수
LPDIRECT3DDEVICE9       g_pd3dDevice = NULL; // 렌더링에 사용될 D3D 디바이스
LPDIRECT3DVERTEXBUFFER9 g_pVB = NULL; // 정점을 보관할 정점 버퍼
LPDIRECT3DTEXTURE9      g_pTexture = NULL; // 텍스처 정보

//정점을 정의할 구조체. 텍스처 좌표가 추가 되었다.
struct CUSTOMVERTEX
{
    D3DXVECTOR3 position; // 3차원 좌표
 D3DXVECTOR3 normal;   // 정점의 법선벡터
 D3DCOLOR color;    // 색상
#ifndef SHOW_HOW_TO_USE_TCI
    FLOAT tu, tv;   // 텍스처 좌표
#endif
};

// O사용자 정점 구조체에 관한 정보를 나타내는 FVF값
#ifdef SHOW_HOW_TO_USE_TCI
#define D3DFVF_CUSTOMVERTEX (D3DFVF_XYZ|D3DFVF_DIFFUSE)
#else
#define D3DFVF_CUSTOMVERTEX (D3DFVF_XYZ|D3DFVF_NORMAL|D3DFVF_DIFFUSE|D3DFVF_TEX1)
#endif

 

//-----------------------------------------------------------------------------
// Name: InitD3D()
// Desc: IDirect3D 초기화
//-----------------------------------------------------------------------------
HRESULT InitD3D( HWND hWnd )
{
    // 디바이스를 생성하기 위한 D3D 객체 생성.
    if( NULL == ( g_pD3D = Direct3DCreate9( D3D_SDK_VERSION ) ) )
        return E_FAIL;

    // 디바이스를 생성할 구조체
    // 복잡한 오브젝트를 사용하기 위해, Z버퍼를 생성한다.
    D3DPRESENT_PARAMETERS d3dpp;
    ZeroMemory( &d3dpp, sizeof( d3dpp ) );
    d3dpp.Windowed = TRUE;
    d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
    d3dpp.BackBufferFormat = D3DFMT_UNKNOWN;
    d3dpp.EnableAutoDepthStencil = TRUE;
    d3dpp.AutoDepthStencilFormat = D3DFMT_D16;

    // Create the D3DDevice
    if( FAILED( g_pD3D->CreateDevice( D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hWnd,
                                      D3DCREATE_SOFTWARE_VERTEXPROCESSING,
                                      &d3dpp, &g_pd3dDevice ) ) )
    {
        return E_FAIL;
    }

    // 컬러 기능을 끈다
    g_pd3dDevice->SetRenderState( D3DRS_CULLMODE, D3DCULL_NONE );

    // 조명 기능을 켠다.
    g_pd3dDevice->SetRenderState( D3DRS_LIGHTING, TRUE );

    // Z버퍼 기능을 켠다.
    g_pd3dDevice->SetRenderState( D3DRS_ZENABLE, TRUE );

    return S_OK;
}

 


//-----------------------------------------------------------------------------
// Name: InitGeometry()
// Desc: 기하 정보 초기화
//-----------------------------------------------------------------------------
HRESULT InitGeometry()
{
    // D3DX 계열 함수를 사용해서 파일로 부터 텍스처 생성(babana.bmp)
    if( FAILED( D3DXCreateTextureFromFile( g_pd3dDevice, L"banana.bmp", &g_pTexture ) ) )
    {
        // 현제 폴더에 파일이 없으면 상위 폴더 검색
        if( FAILED( D3DXCreateTextureFromFile( g_pd3dDevice, L"..\\banana.bmp", &g_pTexture ) ) )
        {
            MessageBox( NULL, L"Could not find banana.bmp", L"Textures.exe", MB_OK );
            return E_FAIL;
        }
    }

    // 정점 버퍼 생성
    if( FAILED( g_pd3dDevice->CreateVertexBuffer( 50 * 2 * sizeof( CUSTOMVERTEX ),
                                                  0, D3DFVF_CUSTOMVERTEX,
                                                  D3DPOOL_DEFAULT, &g_pVB, NULL ) ) )
    {
        return E_FAIL;
    }

    // 정점 버퍼를 채운다. 텍스처 U,V좌표값을 0.0~1.0 사이의 값으로 채운다.
    CUSTOMVERTEX* pVertices;
    if( FAILED( g_pVB->Lock( 0, 0, ( void** )&pVertices, 0 ) ) )
        return E_FAIL;
    for( DWORD i = 0; i < 50; i++ )
    {
        FLOAT theta = ( 2 * D3DX_PI * i ) / ( 50 - 1 );

        pVertices[2 * i + 0].position = D3DXVECTOR3( sinf( theta ), -1.0f, cosf( theta ) );
  // 실린더 아래쪽 원통의 법선 벡터
  pVertices[2 * i + 0].normal = D3DXVECTOR3( sinf( theta ), 0.0f, cosf( theta ) );
  pVertices[2 * i + 0].color = 0xffffffff;
#ifndef SHOW_HOW_TO_USE_TCI
        pVertices[2 * i + 0].tu = ( ( FLOAT )i ) / ( 50 - 1 );
        pVertices[2 * i + 0].tv = 1.0f;
#endif

        pVertices[2 * i + 1].position = D3DXVECTOR3( sinf( theta ), 1.0f, cosf( theta ) );
  // 실린더 위쪽 원통의 법선 벡터
  pVertices[2 * i + 1].normal = D3DXVECTOR3( sinf( theta ), 0.0f, cosf( theta ) );
  pVertices[2 * i + 1].color = 0xff808080;
#ifndef SHOW_HOW_TO_USE_TCI
        pVertices[2 * i + 1].tu = ( ( FLOAT )i ) / ( 50 - 1 );
        pVertices[2 * i + 1].tv = 0.0f;
#endif
    }
    g_pVB->Unlock();

    return S_OK;
}

 


//-----------------------------------------------------------------------------
// Name: Cleanup()
// Desc: 초기화된 객체들 소거
//-----------------------------------------------------------------------------
VOID Cleanup()
{
    if( g_pTexture != NULL )
        g_pTexture->Release();

    if( g_pVB != NULL )
        g_pVB->Release();

    if( g_pd3dDevice != NULL )
        g_pd3dDevice->Release();

    if( g_pD3D != NULL )
        g_pD3D->Release();
}

 

//-----------------------------------------------------------------------------
// Name: SetupMatrices()
// Desc: 월드, 뷰, 프로젝션 메트릭스를 설정한다.
//-----------------------------------------------------------------------------
VOID SetupMatrices()
{
    // 월드행렬 설정
    D3DXMATRIXA16 matWorld;
    D3DXMatrixIdentity( &matWorld );
    D3DXMatrixRotationX( &matWorld, timeGetTime() / 1000.0f );
    g_pd3dDevice->SetTransform( D3DTS_WORLD, &matWorld );

    // 뷰행렬 설정
    D3DXVECTOR3 vEyePt( 0.0f, 3.0f,-5.0f );
    D3DXVECTOR3 vLookatPt( 0.0f, 0.0f, 0.0f );
    D3DXVECTOR3 vUpVec( 0.0f, 1.0f, 0.0f );
    D3DXMATRIXA16 matView;
    D3DXMatrixLookAtLH( &matView, &vEyePt, &vLookatPt, &vUpVec );
    g_pd3dDevice->SetTransform( D3DTS_VIEW, &matView );

    // 프로젝션 행렬 설정
    D3DXMATRIXA16 matProj;
    D3DXMatrixPerspectiveFovLH( &matProj, D3DX_PI / 4, 1.0f, 1.0f, 100.0f );
    g_pd3dDevice->SetTransform( D3DTS_PROJECTION, &matProj );
}


//-----------------------------------------------------------------------------
// Name: SetupLights()
// Desc: 재질과 조명을 설정한다.
//-----------------------------------------------------------------------------
VOID SetupLights()
{
 // 재질 설정. 여기서는 주변색(Ambient)과 확산색(Diffuse)을 사용 한다.
 // 색상은 노란색. 재질은 디바이스에 단 하나만 설정할수 있다.
 D3DMATERIAL9 mtrl;
 ZeroMemory( &mtrl, sizeof( D3DMATERIAL9 ) );
 mtrl.Diffuse.r = mtrl.Ambient.r = 1.0f;
 mtrl.Diffuse.g = mtrl.Ambient.g = 1.0f;
 mtrl.Diffuse.b = mtrl.Ambient.b = 0.0f;
 mtrl.Diffuse.a = mtrl.Ambient.a = 1.0f;
 g_pd3dDevice->SetMaterial( &mtrl );

 // 흰색의 방향성 광원을 설치한다.
 // 많은 조명을 사요할 경우 렌더링 시간이 오래 걸린다.
 // 하지만, 여기서는 하나의 조명만 사용한다. 그리고,
 // 우리는 D3D광원을 사용 렌더링 한다.
 D3DXVECTOR3 vecDir;
 D3DLIGHT9 light;
 ZeroMemory( &light, sizeof( D3DLIGHT9 ) );
 light.Type = D3DLIGHT_DIRECTIONAL;
 light.Diffuse.r = 1.0f;
 light.Diffuse.g = 1.0f;
 light.Diffuse.b = 1.0f;
 vecDir = D3DXVECTOR3( cosf( timeGetTime() / 350.0f ),
  1.0f,
  sinf( timeGetTime() / 350.0f ) );
 D3DXVec3Normalize( ( D3DXVECTOR3* )&light.Direction, &vecDir );// 단위벡터로 만든다
 light.Range = 1000.0f; // 광원이 갈수 있는 최대 거리
 g_pd3dDevice->SetLight( 0, &light );
 g_pd3dDevice->LightEnable( 0, TRUE );
 g_pd3dDevice->SetRenderState( D3DRS_LIGHTING, TRUE );

 // 환경광원 값 설정
 g_pd3dDevice->SetRenderState( D3DRS_AMBIENT, 0x00202020 );
}

 

//-----------------------------------------------------------------------------
// Name: Render()
// Desc: 화면 그리기
//-----------------------------------------------------------------------------
VOID Render()
{
    // 후면 버퍼와 Z버퍼를 지운다.
    g_pd3dDevice->Clear( 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER,
                         D3DCOLOR_XRGB( 0, 0, 255 ), 1.0f, 0 );

    // 렌더링 시작
    if( SUCCEEDED( g_pd3dDevice->BeginScene() ) )
    {
  // 광원과 재질 설정
  SetupLights();

        // 메트릭스 설정
        SetupMatrices();

        // 생성한 텍스쳐를 0번 텍스처 스테이지에 올린다.
        // 텍스처 스제이지는 여러 장의 텍스처와 색상 정보를 섞어서 출력할 때 사용된다.
  // 여기서 텍스처의 색상과 정점의 색상 정보를 modulate 연산으로 섞어서 출력한다.
        g_pd3dDevice->SetTexture( 0, g_pTexture );
        g_pd3dDevice->SetTextureStageState( 0, D3DTSS_COLOROP, D3DTOP_MODULATE );
        g_pd3dDevice->SetTextureStageState( 0, D3DTSS_COLORARG1, D3DTA_TEXTURE );
        g_pd3dDevice->SetTextureStageState( 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE );
        g_pd3dDevice->SetTextureStageState( 0, D3DTSS_ALPHAOP, D3DTOP_DISABLE );

#ifdef SHOW_HOW_TO_USE_TCI
        // Note: to use D3D texture coordinate generation, use the stage state
 // D3DTSS_TEXCOORDINDEX, as shown below. In this example, we are using
 // the position of the vertex in camera space (D3DTSS_TCI_CAMERASPACEPOSITION)
 // to generate texture coordinates. Camera space is the vertex position
 // multiplied by the World and View matrices.  The tex coord index (TCI)  
 // parameters are passed into a texture transform, which is a 4x4 matrix  
 // which transforms the x,y,z TCI coordinates into tu, tv texture coordinates.

 // In this example, the texture matrix is setup to transform the input
 // camera space coordinates (all of R^3) to projection space (-1,+1) 
 // and finally to texture space (0,1).
 //    CameraSpace.xyzw = (input vertex position) * (WorldView)
 //    ProjSpace.xyzw = CameraSpace.xyzw * Projection           //move to -1 to 1
 //    TexSpace.xyzw = ProjSpace.xyzw * ( 0.5, -0.5, 1.0, 1.0 ) //scale to -0.5 to 0.5 (flip y)
 //    TexSpace.xyzw += ( 0.5, 0.5, 0.0, 0.0 )                  //shift to 0 to 1

 // Setting D3DTSS_TEXTURETRANSFORMFLAGS to D3DTTFF_COUNT4 | D3DTTFF_PROJECTED
 // tells D3D to divide the input texture coordinates by the 4th (w) component.
 // This divide is necessary when performing a perspective projection since
 // the TexSpace.xy coordinates prior to the homogeneous divide are not actually 
 // in the 0 to 1 range.
 D3DXMATRIXA16 mTextureTransform;
 D3DXMATRIXA16 mProj;
 D3DXMATRIXA16 mTrans;
 D3DXMATRIXA16 mScale;

 g_pd3dDevice->GetTransform( D3DTS_PROJECTION, &mProj );
 D3DXMatrixTranslation( &mTrans, 0.5f, 0.5f, 0.0f );
 D3DXMatrixScaling( &mScale, 0.5f, -0.5f, 1.0f );
 mTextureTransform = mProj * mScale * mTrans;

 g_pd3dDevice->SetTransform( D3DTS_TEXTURE0, &mTextureTransform );
 g_pd3dDevice->SetTextureStageState( 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT4 | D3DTTFF_PROJECTED );
 g_pd3dDevice->SetTextureStageState( 0, D3DTSS_TEXCOORDINDEX, D3DTSS_TCI_CAMERASPACEPOSITION );
    #endif

        // 정점을 그린다.
        g_pd3dDevice->SetStreamSource( 0, g_pVB, 0, sizeof( CUSTOMVERTEX ) );
        g_pd3dDevice->SetFVF( D3DFVF_CUSTOMVERTEX );
        g_pd3dDevice->DrawPrimitive( D3DPT_TRIANGLESTRIP, 0, 2 * 50 - 2 );

       // 렌더링 종료
        g_pd3dDevice->EndScene();
    }

    // 후면 버퍼를 보이는 화면으로
    g_pd3dDevice->Present( NULL, NULL, NULL, NULL );
}

 


//-----------------------------------------------------------------------------
// Name: MsgProc()
// Desc: 윈도우 메시지 프로시저
//-----------------------------------------------------------------------------
LRESULT WINAPI MsgProc( HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam )
{
    switch( msg )
    {
        case WM_DESTROY:
            Cleanup();
            PostQuitMessage( 0 );
            return 0;

  case WM_KEYDOWN: // 키를 눌렀을때
   if( wParam == VK_ESCAPE ) { // esc를 눌렀을때
    ::DestroyWindow(hWnd);
    return 0;
   }
    }

    return DefWindowProc( hWnd, msg, wParam, lParam );
}

 


//-----------------------------------------------------------------------------
// Name: WinMain()
// Desc: 프로그램 시작점
//-----------------------------------------------------------------------------
INT WINAPI wWinMain( HINSTANCE hInst, HINSTANCE, LPWSTR, INT )
{
    // 윈도우 클래스 등록
    WNDCLASSEX wc =
    {
        sizeof( WNDCLASSEX ), CS_CLASSDC, MsgProc, 0L, 0L,
        GetModuleHandle( NULL ), NULL, NULL, NULL, NULL,
        L"D3D Tutorial", NULL
    };
    RegisterClassEx( &wc );

    // 윈도우창 생성
    HWND hWnd = CreateWindow( L"D3D Tutorial", L"D3D Tutorial 05: Textures",
                              WS_OVERLAPPEDWINDOW, 100, 100, 300, 300,
                              NULL, NULL, wc.hInstance, NULL );

    // Direct3D 초기화
    if( SUCCEEDED( InitD3D( hWnd ) ) )
    {
        // 기하 정보 초기화
        if( SUCCEEDED( InitGeometry() ) )
        {
            // 윈도우 출력
            ShowWindow( hWnd, SW_SHOWDEFAULT );
            UpdateWindow( hWnd );

            // 메시지 루프
            MSG msg;
            ZeroMemory( &msg, sizeof( msg ) );
            while( msg.message != WM_QUIT )
            {
                if( PeekMessage( &msg, NULL, 0U, 0U, PM_REMOVE ) )
                {
                    TranslateMessage( &msg );
                    DispatchMessage( &msg );
                }
                else
                    Render();
            }
        }
    }
 //등록된 클래스 소거
    UnregisterClass( L"D3D Tutorial", wc.hInstance );
    return 0;
}

반응형

'DirectX > DirectX 9.0' 카테고리의 다른 글

[DirectX 9.0] Meshes  (0) 2014.02.11
[DirectX 9.0] Lights  (0) 2014.02.11
[DirectX 9.0] Matrices  (0) 2014.02.11
[DirectX 9.0] Vertices  (0) 2014.02.11
CreateDevice  (0) 2011.03.02
반응형

//-----------------------------------------------------------------------------
// File: Lights.cpp
//
// Desc: 조명을 사용하면 훨씬더 극적인 연출이 가능하다
//       조명을 사용하기 위해서는 광원이나 재질을 생성해야 한다. 또 기하정보에
//       법선벡터 정보를 포함하고 있어야 한다.
//       광원은 위치, 색상, 방향 등의 정보를 바탕으로 생성된다.
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//-----------------------------------------------------------------------------

// 전역 변수
//-----------------------------------------------------------------------------
LPDIRECT3D9             g_pD3D = NULL; // D3DDevice를 생성할 D3D객체 변수
LPDIRECT3DDEVICE9       g_pd3dDevice = NULL; // 렌더링에 사용될 D3D 디바이스
LPDIRECT3DVERTEXBUFFER9 g_pVB = NULL; // 정점을 보관할 정점 버퍼

// 정점을 정의할 구조체.
// 광원을 사용하기 때문에 법선 벡터가 있어야 한다.
struct CUSTOMVERTEX
{
    D3DXVECTOR3 position; // 정점의 3차원 자표
    D3DXVECTOR3 normal;   // 정점의 법선벡터
};

// 사용자 정점 구조체에 관한 정보를 나타내는 FVF값
#define D3DFVF_CUSTOMVERTEX (D3DFVF_XYZ|D3DFVF_NORMAL)

 


//-----------------------------------------------------------------------------
// Name: InitD3D()
// Desc: Direct3D 초기화
//-----------------------------------------------------------------------------
HRESULT InitD3D( HWND hWnd )
{
    // 디바이스를 생성하기 위한 D3D 객체 생성.
    if( NULL == ( g_pD3D = Direct3DCreate9( D3D_SDK_VERSION ) ) )
        return E_FAIL;

    // 디바이스를 생성할 구조체
    // Z버퍼를 사용한다.
    D3DPRESENT_PARAMETERS d3dpp;
    ZeroMemory( &d3dpp, sizeof( d3dpp ) );
    d3dpp.Windowed = TRUE;
    d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
    d3dpp.BackBufferFormat = D3DFMT_UNKNOWN;
    d3dpp.EnableAutoDepthStencil = TRUE;
    d3dpp.AutoDepthStencilFormat = D3DFMT_D16;

    // D3DDevice 생성
    if( FAILED( g_pD3D->CreateDevice( D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hWnd,
                                      D3DCREATE_SOFTWARE_VERTEXPROCESSING,
                                      &d3dpp, &g_pd3dDevice ) ) )
    {
        return E_FAIL;
    }

    // 컬러기능을 끈다
    g_pd3dDevice->SetRenderState( D3DRS_CULLMODE, D3DCULL_NONE );

    // Z버퍼 기능을 켠다.
    g_pd3dDevice->SetRenderState( D3DRS_ZENABLE, TRUE );

    return S_OK;
}

 


//-----------------------------------------------------------------------------
// Name: InitGeometry()
// Desc: 기하 정보 초기화
//-----------------------------------------------------------------------------
HRESULT InitGeometry()
{
    // 정점 버퍼 생성
    if( FAILED( g_pd3dDevice->CreateVertexBuffer( 50 * 2 * sizeof( CUSTOMVERTEX ),
                                                  0, D3DFVF_CUSTOMVERTEX,
                                                  D3DPOOL_DEFAULT, &g_pVB, NULL ) ) )
    {
        return E_FAIL;
    }

    // 정점 버퍼를 채운다.알고리즘을 사용해 실린더를 만든다.
    // 법선벡터를 포함하고 조명을 사용한다.
    CUSTOMVERTEX* pVertices;
    if( FAILED( g_pVB->Lock( 0, 0, ( void** )&pVertices, 0 ) ) )
        return E_FAIL;
    for( DWORD i = 0; i < 50; i++ )
    {
        FLOAT theta = ( 2 * D3DX_PI * i ) / ( 50 - 1 );
  // 실린더 아래쪽 원통의 좌표
        pVertices[2 * i + 0].position = D3DXVECTOR3( sinf( theta ), -1.0f, cosf( theta ) );
        // 실린더 아래쪽 원통의 법선 벡터
  pVertices[2 * i + 0].normal = D3DXVECTOR3( sinf( theta ), 0.0f, cosf( theta ) );
        // 실린더 위쪽 원통의 좌표
  pVertices[2 * i + 1].position = D3DXVECTOR3( sinf( theta ), 1.0f, cosf( theta ) );
        // 실린더 위쪽 원통의 법선 벡터
  pVertices[2 * i + 1].normal = D3DXVECTOR3( sinf( theta ), 0.0f, cosf( theta ) );
    }
    g_pVB->Unlock();

    return S_OK;
}

 


//-----------------------------------------------------------------------------
// Name: Cleanup()
// Desc: 초기화된 객체들 소거
//-----------------------------------------------------------------------------
VOID Cleanup()
{
    if( g_pVB != NULL )
        g_pVB->Release();

    if( g_pd3dDevice != NULL )
        g_pd3dDevice->Release();

    if( g_pD3D != NULL )
        g_pD3D->Release();
}

 

//-----------------------------------------------------------------------------
// Name: SetupMatrices()
// Desc: 월드, 뷰, 프로젝션 메트릭스를 설정한다.
//-----------------------------------------------------------------------------
VOID SetupMatrices()
{
    // 월드행렬 설정
    D3DXMATRIXA16 matWorld;
    D3DXMatrixIdentity( &matWorld ); // 월드 행렬을 단위 행렬로 설정
    D3DXMatrixRotationX( &matWorld, timeGetTime() / 500.0f ); // x축을 중심으로 회전
    g_pd3dDevice->SetTransform( D3DTS_WORLD, &matWorld ); // 장치에 월드행렬 적용

    // 뷰행렬 설정
    D3DXVECTOR3 vEyePt( 0.0f, 3.0f,-5.0f );
    D3DXVECTOR3 vLookatPt( 0.0f, 0.0f, 0.0f );
    D3DXVECTOR3 vUpVec( 0.0f, 1.0f, 0.0f );
    D3DXMATRIXA16 matView;
    D3DXMatrixLookAtLH( &matView, &vEyePt, &vLookatPt, &vUpVec );
    g_pd3dDevice->SetTransform( D3DTS_VIEW, &matView );

    // 프로젝션 행렬 설정
    D3DXMATRIXA16 matProj;
    D3DXMatrixPerspectiveFovLH( &matProj, D3DX_PI / 4, 1.0f, 1.0f, 100.0f );
    g_pd3dDevice->SetTransform( D3DTS_PROJECTION, &matProj );
}

 


//-----------------------------------------------------------------------------
// Name: SetupLights()
// Desc: 재질과 조명을 설정한다.
//-----------------------------------------------------------------------------
VOID SetupLights()
{
    // 재질 설정. 여기서는 주변색(Ambient)과 확산색(Diffuse)을 사용 한다.
    // 색상은 노란색. 재질은 디바이스에 단 하나만 설정할수 있다.
    D3DMATERIAL9 mtrl;
    ZeroMemory( &mtrl, sizeof( D3DMATERIAL9 ) );
    mtrl.Diffuse.r = mtrl.Ambient.r = 1.0f;
    mtrl.Diffuse.g = mtrl.Ambient.g = 1.0f;
    mtrl.Diffuse.b = mtrl.Ambient.b = 0.0f;
    mtrl.Diffuse.a = mtrl.Ambient.a = 1.0f;
    g_pd3dDevice->SetMaterial( &mtrl );

    // 흰색의 방향성 광원을 설치한다.
    // 많은 조명을 사요할 경우 렌더링 시간이 오래 걸린다.
    // 하지만, 여기서는 하나의 조명만 사용한다. 그리고,
    // 우리는 D3D광원을 사용 렌더링 한다.
    D3DXVECTOR3 vecDir;
    D3DLIGHT9 light;
    ZeroMemory( &light, sizeof( D3DLIGHT9 ) );
    light.Type = D3DLIGHT_DIRECTIONAL;
    light.Diffuse.r = 1.0f;
    light.Diffuse.g = 1.0f;
    light.Diffuse.b = 1.0f;
    vecDir = D3DXVECTOR3( cosf( timeGetTime() / 350.0f ),
                          1.0f,
                          sinf( timeGetTime() / 350.0f ) );
    D3DXVec3Normalize( ( D3DXVECTOR3* )&light.Direction, &vecDir );// 단위벡터로 만든다
    light.Range = 1000.0f; // 광원이 갈수 있는 최대 거리
    g_pd3dDevice->SetLight( 0, &light );
    g_pd3dDevice->LightEnable( 0, TRUE );
    g_pd3dDevice->SetRenderState( D3DRS_LIGHTING, TRUE );

    // 환경광원 값 설정
    g_pd3dDevice->SetRenderState( D3DRS_AMBIENT, 0x00202020 );
}

 


//-----------------------------------------------------------------------------
// Name: Render()
// Desc: 화면 그리기
//-----------------------------------------------------------------------------
VOID Render()
{
    // 후면 버퍼와 Z버퍼를 지운다.
    g_pd3dDevice->Clear( 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER,
                         D3DCOLOR_XRGB( 0, 0, 255 ), 1.0f, 0 );

    // 렌더링 시작
    if( SUCCEEDED( g_pd3dDevice->BeginScene() ) )
    {
        // 광원과 재질 설정
        SetupLights();

        // 메트릭스 설정
        SetupMatrices();

        // 정점을 그린다.
        g_pd3dDevice->SetStreamSource( 0, g_pVB, 0, sizeof( CUSTOMVERTEX ) );
        g_pd3dDevice->SetFVF( D3DFVF_CUSTOMVERTEX );
        g_pd3dDevice->DrawPrimitive( D3DPT_TRIANGLESTRIP, 0, 2 * 50 - 2 );

        // 렌더링 종료
        g_pd3dDevice->EndScene();
    }

    // 후면 버퍼를 보이는 화면으로
    g_pd3dDevice->Present( NULL, NULL, NULL, NULL );
}

 


//-----------------------------------------------------------------------------
// Name: MsgProc()
// Desc: 윈도우 메시지 프로지서
//-----------------------------------------------------------------------------
LRESULT WINAPI MsgProc( HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam )
{
    switch( msg )
    {
        case WM_DESTROY:
            Cleanup();
            PostQuitMessage( 0 );
            return 0;

  case WM_KEYDOWN: // 키를 눌렀을때
   if( wParam == VK_ESCAPE ) { // esc를 눌렀을때
    ::DestroyWindow(hWnd);
    return 0;
   }
    }

    return DefWindowProc( hWnd, msg, wParam, lParam );
}

 


//-----------------------------------------------------------------------------
// Name: WinMain()
// Desc: 프로그램 시작점
//-----------------------------------------------------------------------------
INT WINAPI wWinMain( HINSTANCE hInst, HINSTANCE, LPWSTR, INT )
{
    // 윈도우 클래스 등록
    WNDCLASSEX wc =
    {
        sizeof( WNDCLASSEX ), CS_CLASSDC, MsgProc, 0L, 0L,
        GetModuleHandle( NULL ), NULL, NULL, NULL, NULL,
        L"D3D Tutorial", NULL
    };
    RegisterClassEx( &wc );

    // Create the application's window
    HWND hWnd = CreateWindow( L"D3D Tutorial", L"D3D Tutorial 04: Lights",
                              WS_OVERLAPPEDWINDOW, 100, 100, 300, 300,
                              NULL, NULL, wc.hInstance, NULL );

    // 윈도우 창 생성
    if( SUCCEEDED( InitD3D( hWnd ) ) )
    {
        // 정점 버퍼 초기화
        if( SUCCEEDED( InitGeometry() ) )
        {
            // 윈도우 출력
            ShowWindow( hWnd, SW_SHOWDEFAULT );
            UpdateWindow( hWnd );

            // 메시지 루프
            MSG msg;
            ZeroMemory( &msg, sizeof( msg ) );
            while( msg.message != WM_QUIT )
            {
                if( PeekMessage( &msg, NULL, 0U, 0U, PM_REMOVE ) )
                {
                    TranslateMessage( &msg );
                    DispatchMessage( &msg );
                }
                else
                    Render();
            }
        }
    }

 //등록된 클래스 소거
    UnregisterClass( L"D3D Tutorial", wc.hInstance );
    return 0;
}

 

 

 

- 재질의 종류
재질이란 메시의 표면 상태를 말하는 것으로 빛이 물체의 표면에서 반사되어 변화된 뒤
사람의 눈에 들어오기까지의 과정을 을 수학적으로 모델링하기 위해서 사용하는 값들.

주변색(ambient) : 광원의 위치와 무관학 똑같은 양으로 모든 점에서 반사되는 색
확산색(diffuse) : 광원에 반사될 때 출력되는 가장 주된 색
반사색(specular) : 특정한 방향으로만 반사되는 색. 광원의 위치와 카메라의 위치에 따라서 달라진다.
방출색(emissive) : 메시 표면에서 자체적으로 방출되는 색. 단 이 빛이 다른 메시에 영향을
   주지는 못한다.


- 광원의 종류


 

광원모델은 D3D의 고정 함수 파이프라인을 사용할 때만 유효하고, 정점 세이더와 픽셀 셰이더를
 사용하게 되면 모두 무용지물이 된다.

반응형

'DirectX > DirectX 9.0' 카테고리의 다른 글

[DirectX 9.0] Meshes  (0) 2014.02.11
[DirectX 9.0] Textures  (0) 2014.02.11
[DirectX 9.0] Matrices  (0) 2014.02.11
[DirectX 9.0] Vertices  (0) 2014.02.11
CreateDevice  (0) 2011.03.02
반응형

//-----------------------------------------------------------------------------
// File: Matrices.cpp
//
// Desc: 우리는 이제 장치를 생성하고 2D 정점을 렌더링하는 법을 알았다.
//   이 튜토리얼은 다음으로 기하학적인 3D를 렌더링을 배운다.
//       기하학적 3D를 다루기 위해서는 4x4 메트릭스 변환을 이용해 기하학적으로
//       변환(이동), 회전, 크기조정 그리고 카메라를 조종할수 있다.
//       
//   3차원 모델계 좌표를 사용하는데, 우리가 월드 변환을 하여 이동, 회전,
//   크기 조정할수 있다. 이떄 월드 행렬이 사용된다. 다시 월드 좌표계의 기하
//   정보를 카메라 좌표계로 변환한다.
//   기하학적 월드좌표를 사용하기 위해서는 카메라의 위치나 눈의 위치 월드계의
//       어느곳을 보고 있는지가 필요하다.
//       또하나의 변환은 view matrix에 의한 시점의 위치와 회전을 한다.
//       마지막 변환으로 투영 변환이 있다. 프로젝션은 3D를 우리가 보이는 
//   2D 화면으로 변환한다.
//
//       OpenGL에서는 행렬 연산 함수를 직접 작성해야 하지만, D3D에서는 D3DX라는 
//   유틸리티 함수들이 여러 개 존재한다. 여기서는 D3DX 계열 함수를 사용할
//   것이다.
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//-----------------------------------------------------------------------------

// Global variables
//-----------------------------------------------------------------------------
LPDIRECT3D9             g_pD3D = NULL; // D3DDevice를 생성할 D3D객체 변수
LPDIRECT3DDEVICE9       g_pd3dDevice = NULL; // 렌더링에 사용될 D3D 디바이스
LPDIRECT3DVERTEXBUFFER9 g_pVB = NULL; // 정점을 보관할 정점 버퍼

// 정점을 정의할 구조체
struct CUSTOMVERTEX
{
 FLOAT x, y, z; // 정점의 변화된 좌표(rhw값이 있으면 변환이 완료된 정점)
 DWORD color;        // 정점의 색상
};

// 사용자 정점 구조체에 관한 정보를 나타내는 FVF값
#define D3DFVF_CUSTOMVERTEX (D3DFVF_XYZ|D3DFVF_DIFFUSE)

 


//-----------------------------------------------------------------------------
// Name: InitD3D()
// Desc: Direct3D 초기화
//-----------------------------------------------------------------------------
HRESULT InitD3D( HWND hWnd )
{
   if( NULL == ( g_pD3D = Direct3DCreate9( D3D_SDK_VERSION ) ) )
        return E_FAIL;

    // 디바이스 생성을 위한 구조체
    D3DPRESENT_PARAMETERS d3dpp;
    ZeroMemory( &d3dpp, sizeof( d3dpp ) );
    d3dpp.Windowed = TRUE;
    d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
    d3dpp.BackBufferFormat = D3DFMT_UNKNOWN;

    // D3DDevice 장치 생성
    if( FAILED( g_pD3D->CreateDevice( D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hWnd,
                                      D3DCREATE_SOFTWARE_VERTEXPROCESSING,
                                      &d3dpp, &g_pd3dDevice ) ) )
    {
        return E_FAIL;
    }

    // 컬러 기능을 끈다. 삼각형의 앞면, 뒷면을 모두 렌더링 한다.
    g_pd3dDevice->SetRenderState( D3DRS_CULLMODE, D3DCULL_NONE );

    // 정점에 색상값이 있으므로, 광원의 기능을 끈다.
    g_pd3dDevice->SetRenderState( D3DRS_LIGHTING, FALSE );

    return S_OK;
}

 


//-----------------------------------------------------------------------------
// Name: InitGeometry()
// Desc: 기하 정보 초기화
//-----------------------------------------------------------------------------
HRESULT InitGeometry()
{
    // 삼각형을 렌더링 하기 위해 세개의 정점 선언
    CUSTOMVERTEX g_Vertices[] =
    {
        { -1.0f, -1.0f, 0.0f, 0xffff0000, },
        {  1.0f, -1.0f, 0.0f, 0xff0000ff, },
        {  0.0f,  1.0f, 0.0f, 0xffffffff, },
    };

    // 정점 버퍼 생성
    if( FAILED( g_pd3dDevice->CreateVertexBuffer( 3 * sizeof( CUSTOMVERTEX ),
                                                  0, D3DFVF_CUSTOMVERTEX,
                                                  D3DPOOL_DEFAULT, &g_pVB, NULL ) ) )
    {
        return E_FAIL;
    }
 
    // 정점 버퍼를 값으로 채운다.
    VOID* pVertices;
    if( FAILED( g_pVB->Lock( 0, sizeof( g_Vertices ), ( void** )&pVertices, 0 ) ) )
        return E_FAIL;
    memcpy( pVertices, g_Vertices, sizeof( g_Vertices ) );
    g_pVB->Unlock();

    return S_OK;
}

 


//-----------------------------------------------------------------------------
// Name: Cleanup()
// Desc: 초기화된 객체들 소거
//-----------------------------------------------------------------------------
VOID Cleanup()
{
    if( g_pVB != NULL )
        g_pVB->Release();

    if( g_pd3dDevice != NULL )
        g_pd3dDevice->Release();

    if( g_pD3D != NULL )
        g_pD3D->Release();
}

 

//-----------------------------------------------------------------------------
// Name: SetupMatrices()
// Desc: 행렬은 세 개가 있고, 월드. 뷰, 프로젝션 행렬이다.
//-----------------------------------------------------------------------------
VOID SetupMatrices()
{
    // 월드 행렬, 우리가 물체를 Y축으로 돌리기 위해 사용
    D3DXMATRIXA16 matWorld;

    // 회전 행렬 설정은일반적으로 전체 한바퀴 회전은 2*PI radians 이다. 
    // float 연산의 정밀도를 위해 1000으로 나머지 연산을 한다.
    UINT iTime = timeGetTime() % 1000;
 // 1000미리 초마다 한 바퀴씩 회전하는 애니메이션 행렬을 만든다.
    FLOAT fAngle = iTime * ( 2.0f * D3DX_PI ) / 1000.0f; 
    D3DXMatrixRotationY( &matWorld, fAngle );
 // 생성한 회전 행렬을 월드 행렬로 디바이스에 설정
    g_pd3dDevice->SetTransform( D3DTS_WORLD, &matWorld );

 // 뷰행렬을 정의하기 위해서는 세가지 값이 필요하다.
 // 눈의 위치, 눈이 바라보는 위치, 천정 방향을 나타내는 상방벡터
 // 위 세가지의 값으로 뷰 행렬을 생성 한다.
 D3DXVECTOR3 vEyePt( 0.0f, 3.0f,-5.0f );
    D3DXVECTOR3 vLookatPt( 0.0f, 0.0f, 0.0f );
    D3DXVECTOR3 vUpVec( 0.0f, 1.0f, 0.0f );
    D3DXMATRIXA16 matView;
    D3DXMatrixLookAtLH( &matView, &vEyePt, &vLookatPt, &vUpVec );
 // 생성한 뷰 행렬을 장치에 적용한다.
    g_pd3dDevice->SetTransform( D3DTS_VIEW, &matView );

 // 프로젝션 행렬을 정의하기 위해서는 시야각(FOV=Field Of View)과
 // 종회비(aspect ratio), 클리핑 평면의 값이 필요하다.
    D3DXMATRIXA16 matProj;
    D3DXMatrixPerspectiveFovLH( &matProj, D3DX_PI / 4, 1.0f, 1.0f, 100.0f );
    g_pd3dDevice->SetTransform( D3DTS_PROJECTION, &matProj );
}

 

//-----------------------------------------------------------------------------
// Name: Render()
// Desc: 화면을 그린다
//-----------------------------------------------------------------------------
VOID Render()
{
    // 백버퍼를 검은색으로 지운다.
    g_pd3dDevice->Clear( 0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB( 0, 0, 0 ), 1.0f, 0 );

    // 렌더링 시작
    if( SUCCEEDED( g_pd3dDevice->BeginScene() ) )
    {
        // 월드, 뷰, 프로젝션 메트릭스를 설정한다
        SetupMatrices();

        // 정점 정보를 렌더링 한다
        g_pd3dDevice->SetStreamSource( 0, g_pVB, 0, sizeof( CUSTOMVERTEX ) );
        g_pd3dDevice->SetFVF( D3DFVF_CUSTOMVERTEX );
        g_pd3dDevice->DrawPrimitive( D3DPT_TRIANGLESTRIP, 0, 1 );

        // 렌더링 종료
        g_pd3dDevice->EndScene();
    }

 // 후면 버퍼를 보이는 화면으로 
    g_pd3dDevice->Present( NULL, NULL, NULL, NULL );
}

 


//-----------------------------------------------------------------------------
// Name: MsgProc()
// Desc: 윈도우 메시지 처리
//-----------------------------------------------------------------------------
LRESULT WINAPI MsgProc( HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam )
{
    switch( msg )
    {
        case WM_DESTROY:
            Cleanup();
            PostQuitMessage( 0 );
            return 0;

  case WM_KEYDOWN: // 키를 눌렀을때
   if( wParam == VK_ESCAPE ) { // esc를 눌렀을때
    ::DestroyWindow(hWnd);
    return 0;
   }
    }

    return DefWindowProc( hWnd, msg, wParam, lParam );
}

 


//-----------------------------------------------------------------------------
// Name: WinMain()
// Desc: 프로그램 시작 지점
//-----------------------------------------------------------------------------
INT WINAPI wWinMain( HINSTANCE hInst, HINSTANCE, LPWSTR, INT )
{
 // 윈도우 클래스 등록
    WNDCLASSEX wc =
    {
        sizeof( WNDCLASSEX ), CS_CLASSDC, MsgProc, 0L, 0L,
        GetModuleHandle( NULL ), NULL, NULL, NULL, NULL,
        L"D3D Tutorial", NULL
    };
    RegisterClassEx( &wc );

 // 윈도우 창 생성
    HWND hWnd = CreateWindow( L"D3D Tutorial", L"D3D Tutorial 03: Matrices",
                              WS_OVERLAPPEDWINDOW, 100, 100, 256, 256,
                              NULL, NULL, wc.hInstance, NULL );

 // Direct3D 초기화
    if( SUCCEEDED( InitD3D( hWnd ) ) )
    {
  // 정점 버퍼 초기화
        if( SUCCEEDED( InitGeometry() ) )
        {
   // 윈도우 출력
            ShowWindow( hWnd, SW_SHOWDEFAULT );
            UpdateWindow( hWnd );

            // 메시지 루프
            MSG msg;
            ZeroMemory( &msg, sizeof( msg ) );
            while( msg.message != WM_QUIT )
            {
                if( PeekMessage( &msg, NULL, 0U, 0U, PM_REMOVE ) )
                {
                    TranslateMessage( &msg );
                    DispatchMessage( &msg );
                }
                else
                    Render();
            }
        }
    }
 // 등록된 클래스 소거
    UnregisterClass( L"D3D Tutorial", wc.hInstance );
    return 0;
}

 

 

 

 

- 월드 변환(World transform)
 3차원 그래픽에서 모든 정점은 지역 좌표계(로컬 좌표계, 모델 좌표계) 값을 갖는다.
이 값들은 최초에 3차원 데이터가 생성되는 시점에서 기준이 되는 원점을 중심으로 한 좌표계이다.
 모든 물체들이 각각의 고유한 원점을 기준으로 모델링 되어 있으므로 여러개의 물체를 3차원 공간에
 출력할 경우 이들 물체들이 원점을 공유하게 되는 현상이 발생한다.

 (원점에서 물체가 겹쳐서 나타남)

 로컬좌표계를 월드 좌표계로 변화하는 행렬을 간단하게 변환 행렬(Transform Matrix)이라 하며
줄여서 TM이라고 부른다. 100개의 물체를 3차원 공간에 그리려면 100개의 TM이 필요하다.
 과거에는 TM값을 적용해서 물체를 그리기 위해 루프를 돌며 정점과 TM을 일일이 곱해주는 연산을
했지만 D3D 7.0 이후부터는 그렇게 할 경우 TnL지원을 받지 못한다. 
 따라서 TM은 반드시 SetTransform(D3DTS_WORLD, &matWorld)처럼 해주어야 하드웨어 가속을 받을수
있다.


- 카메라 변화(Camera transform)
 3차원 월드 좌표계를 카메라를 기준으로 한 카메라 좌표계로 변환하는 것을 말한다.

 카메라 변환 행렬 계산은 D3DMatrixLookAtLH(&matView, &vEyePt, &LookatPt, &vUpVec) 를 사용 한다.
matView : 변환 행렬이 들어갈 행렬 구조체,
vEyePt : 카메라의 위치 월드 좌표
LookatPt : 카메라가 바라보는 위치 월드 좌표
vUpVec : 카메라의 상방로컬벡터

 카메라 변환 행렬 적용은 SetTransform(D3DTS_VIEW, &matView)처럼 적용해주어야 한다.


- 투영 변환(Projection transform)
 월드 좌표계와 카메라는 모두 3차원 좌표계다. 하지만 우리가 모니터를 통해서 보는 화면은 2차원
화면이다. 그렇기 때문에 3차원을 우리가 볼수있는 2차원으로 변환이 필요하다. 가장 쉬운 방법은
3개의 축중에서 한개의 축을 버리고 2개의 축으로 2차원 좌표계로 변환된다.
 투영에는 가장 많이 사용하는 원근 투영(perspective projection) 기법으로 직교투영 법이 있다.

 투영 변환 행렬 계산은 D3DXMatrixPerspectiveFovLH(&matProj, fov, Sw/Sh, Zn, Zf) 를 사용 한다.
matProj : 변환 행렬이 들어갈 행렬 구조체
fov : 시야 각 (Field Of View)
Sw/Sh : 종횡비(가로세로의 비율)
Zn : 가까운 클리핑 평면(near clipping plane)
Zf : 먼 클리핑 평면(far clipping plane)

 투영 변환 행렬 적용은 SetTransform(D3DTS_PROJECTION, &matProj)처럼 적용해주어야 한다.

- 렌더링 파이프 라인
 렌터링 파이프는 로컬 좌표계 정점 -> 월드 행렬 -> 카메라 행렬 -> 투영 행렬 -> 뷰포트 좌표계 정점 이런 순의 과정을 거치게 된다.


이전 소스에 비해 회전이 들어가고 예제 코드에서 정점 구조체에 rhw값이 없다는 것에 주의할것
#define에서도 D3DFVF_XYZ로 RHW가 빠져있다 이것을 추가하게 되면 화면이 나오지 않는다.

반응형

'DirectX > DirectX 9.0' 카테고리의 다른 글

[DirectX 9.0] Textures  (0) 2014.02.11
[DirectX 9.0] Lights  (0) 2014.02.11
[DirectX 9.0] Vertices  (0) 2014.02.11
CreateDevice  (0) 2011.03.02
DirectX 설치 및 설정 방법  (0) 2011.03.02
반응형

//-----------------------------------------------------------------------------
// File: Vertices.cpp
//
// Desc: 이번 튜토리얼은 정점을 렌더링에 대한것 이다. 여기서 정점 버퍼의 개념에
//       대해 보게 될 것이다. 정점 버퍼란 정점을 보관하기 위한 D3D용 객체인데,
//   사용자가 FVF를 사용하여 자유롭게 형식을 정의할 수 있다. 변환과 광원 
//   처리가 완료된 정점을 이용할 것이다.
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//-----------------------------------------------------------------------------

// Global variables
//-----------------------------------------------------------------------------
LPDIRECT3D9             g_pD3D = NULL; // D3DDevice 생성하기 위한 변수
LPDIRECT3DDEVICE9       g_pd3dDevice = NULL; // device에 그리기 위한 변수
LPDIRECT3DVERTEXBUFFER9 g_pVB = NULL; // 정점을 보관할 정점 버퍼

// 정점을 정의할 구조체
struct CUSTOMVERTEX
{
    FLOAT x, y, z, rhw; // 정점의 변화된 좌표(rhw값이 있으면 변환이 완료된 정점)
    DWORD color;        // 정점의 색상
};

// 사용자 정점 구조체에 관한 정보를 나타내는 FVF값
#define D3DFVF_CUSTOMVERTEX (D3DFVF_XYZRHW|D3DFVF_DIFFUSE)

 


//-----------------------------------------------------------------------------
// Name: InitD3D()
// Desc: Direct3D 초기화
//-----------------------------------------------------------------------------
HRESULT InitD3D( HWND hWnd )
{
    // 디바이스 생성하기 위한 D3D객체 생성 및 버전 확인
    if( NULL == ( g_pD3D = Direct3DCreate9( D3D_SDK_VERSION ) ) )
        return E_FAIL;

    // 디바이스 생성을 위한 구조체
    D3DPRESENT_PARAMETERS d3dpp;
    ZeroMemory( &d3dpp, sizeof( d3dpp ) );
    d3dpp.Windowed = TRUE;
    d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
    d3dpp.BackBufferFormat = D3DFMT_UNKNOWN;

    // D3DDevice 장치 생성
    if( FAILED( g_pD3D->CreateDevice( D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hWnd,
                                      D3DCREATE_SOFTWARE_VERTEXPROCESSING,
                                      &d3dpp, &g_pd3dDevice ) ) )
    {
        return E_FAIL;
    }

    // 디바이스 상태 정보를 처리할 경우 이곳에서 한다.

    return S_OK;
}

 


//-----------------------------------------------------------------------------
// Name: InitVB()
// Desc: 정점 버퍼를 생성하고 정점의 값을 채워 넣는다. 
//       정점 버퍼란 기본적으로 정점 정보를 갖고 있는 메모리 블록이다.
//       정점 버퍼를 생성한 다음에는 반드시 Lock()/Unlock()으로 포인터를 얻어내서 
//       정점퍼에 써넣어야 한다. 또한 D3D는 인덱스 버퍼도 사용 가능하다.
//       정점 버퍼나 인덱스 버퍼는 기본 시스템 메모리 외에 디바이스 메모리
//   (비디오카드 메모리)에 생성될 수 있는데, 대부분의 비디오카드에서는 이렇게
//       할 경우 엄청난 속도의 향상을 얻을 수 있다.
//-----------------------------------------------------------------------------
HRESULT InitVB()
{
    // 삼각형을 렌더링하기 위해 세 개의 정점을 선언
    CUSTOMVERTEX Vertices[] =
    {
        { 250.0f, 150.0f, 0.5f, 1.0f, 0xffff0000, }, // x, y, z, rhw, 
        { 350.0f, 350.0f, 0.5f, 1.0f, 0xff00ff00, }, // color(AARRGGBB)
        { 150.0f, 350.0f, 0.5f, 1.0f, 0xff00ffff, }, // 알파알쥐비 순서
    };

    // 정점 버퍼 생성. 3개의 사용자 정점을 보관할 메모리를 할당 한다.
    // FVF를 지정하여 보관할 데이터의 형식을 지정한다.
    if( FAILED( g_pd3dDevice->CreateVertexBuffer( 3 * sizeof( CUSTOMVERTEX ),
                                                  0, D3DFVF_CUSTOMVERTEX,
                                                  D3DPOOL_DEFAULT, &g_pVB, NULL ) ) )
    {
        return E_FAIL;
    }

    // 정점 버퍼를 값으로 채운다.
    // 정점 버퍼의 Lock()함수를 호출하여 포인터를 얻어온다
    VOID* pVertices;
    if( FAILED( g_pVB->Lock( 0, sizeof( Vertices ), ( void** )&pVertices, 0 ) ) )
        return E_FAIL;
    memcpy( pVertices, Vertices, sizeof( Vertices ) );
    g_pVB->Unlock();

    return S_OK;
}

 


//-----------------------------------------------------------------------------
// Name: Cleanup()
// Desc: 초기화된 객체들을 소거한다
//-----------------------------------------------------------------------------
VOID Cleanup()
{
    if( g_pVB != NULL )
        g_pVB->Release();

    if( g_pd3dDevice != NULL )
        g_pd3dDevice->Release();

    if( g_pD3D != NULL )
        g_pD3D->Release();
}

 


//-----------------------------------------------------------------------------
// Name: Render()
// Desc: 화면을 그린다
//-----------------------------------------------------------------------------
VOID Render()
{
    // 백버퍼를 지정딘 색으로 지운다.
    g_pd3dDevice->Clear( 0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB( 0, 0, 255 ), 1.0f, 0 );

    // 렌더링 시작
    if( SUCCEEDED( g_pd3dDevice->BeginScene() ) )
    {
        // 정점 버퍼의 삼각형을 그린다.
        // 먼저 정점 정보가 담겨있는 정점 버퍼를 출력 스트림으로 할당한다.
  // D3D에 정점 셰이더 정보를 지정한다. 대부분 FVF만 지정
        // 기하학적 정보를 출력하기 위한 DrawPrimitive() 함수를 호출
        g_pd3dDevice->SetStreamSource( 0, g_pVB, 0, sizeof( CUSTOMVERTEX ) );
        g_pd3dDevice->SetFVF( D3DFVF_CUSTOMVERTEX );
        g_pd3dDevice->DrawPrimitive( D3DPT_TRIANGLELIST, 0, 1 );
  // DrawPrimitive는 삼각형을 그려주는 함수이다. 다음 6개의 형태가 있다.
  // D3DPT_POINTLIST, D3DPT_LINELIST, D3DPT_LINESTRIP, D3DPT_TRIANGLELIST,
  // D3DPT_TRIANGLESTRIP, D3DPT_TRIANGLEFAN



        // 랜더링 종료
        g_pd3dDevice->EndScene();
    }

    // 후면 버퍼를 보이는 화면으로 
    g_pd3dDevice->Present( NULL, NULL, NULL, NULL );
}

 


//-----------------------------------------------------------------------------
// Name: MsgProc()
// Desc: 윈도우 메시지 처리
//-----------------------------------------------------------------------------
LRESULT WINAPI MsgProc( HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam )
{
    switch( msg )
    {
        case WM_DESTROY:
            Cleanup();
            PostQuitMessage( 0 );
            return 0;

  case WM_KEYDOWN: // 키를 눌렀을때
   if( wParam == VK_ESCAPE ) { // esc를 눌렀을때
    ::DestroyWindow(hWnd);
    return 0;
   }
    }

    return DefWindowProc( hWnd, msg, wParam, lParam );
}

 


//-----------------------------------------------------------------------------
// Name: wWinMain()
// Desc: 프로그램 시작 지점
//-----------------------------------------------------------------------------
INT WINAPI wWinMain( HINSTANCE hInst, HINSTANCE, LPWSTR, INT )
{
    // 윈도우 클래스 등록
    WNDCLASSEX wc =
    {
        sizeof( WNDCLASSEX ), CS_CLASSDC, MsgProc, 0L, 0L,
        GetModuleHandle( NULL ), NULL, NULL, NULL, NULL,
        L"D3D Tutorial", NULL
    };
    RegisterClassEx( &wc );

    // 윈도우 창 생성
    HWND hWnd = CreateWindow( L"D3D Tutorial", L"D3D Tutorial 02: Vertices",
                              WS_OVERLAPPEDWINDOW, 100, 100, 500, 500,
                              NULL, NULL, wc.hInstance, NULL );

    // Direct3D 초기화
    if( SUCCEEDED( InitD3D( hWnd ) ) )
    {
        // 정점 버퍼 초기화
        if( SUCCEEDED( InitVB() ) )
        {
            // 윈도우 출력
            ShowWindow( hWnd, SW_SHOWDEFAULT );
            UpdateWindow( hWnd );

            // 메시지 루프
            MSG msg;
            ZeroMemory( &msg, sizeof( msg ) ); // 메시지 루프 초기화
            while( msg.message != WM_QUIT )
            {
    // 메시지 큐에 메시지가 있으면 처리
    // PeekMessage는 메시지가 있으면 처리하고 없으면 즉시 다음 문장으로 넘어 가는 특성이 있다.
    // GetMessage는 새로운 메시지가 발생하기 까지 대기 상태로 들어감 그래서 PeekMessage를 사용
    // 하여 대기 시간없이 남아도는 시간을 게임에 관련된 내용을 처리하는데 사용한다.
                if( PeekMessage( &msg, NULL, 0U, 0U, PM_REMOVE ) ) 
                {
                    TranslateMessage( &msg );
                    DispatchMessage( &msg );
                }
                else // 처리할 메시지 없으면 그려준다.
                    Render(); // 반응을 빨리 대처하기 위해 메인에서 사용됨
            }
        }
    }

 // 등록된 클래스 소거
    UnregisterClass( L"D3D Tutorial", wc.hInstance );
    return 0;
}

반응형

'DirectX > DirectX 9.0' 카테고리의 다른 글

[DirectX 9.0] Textures  (0) 2014.02.11
[DirectX 9.0] Lights  (0) 2014.02.11
[DirectX 9.0] Matrices  (0) 2014.02.11
CreateDevice  (0) 2011.03.02
DirectX 설치 및 설정 방법  (0) 2011.03.02
반응형
CFile::modeCreate           -   파일을 새로 만든다.

CFile::modeRead             -   읽기 위해서 파일을 연다.

CFile::modeReadWrite      -   읽고 쓰기 위해서 파일을 연다.

CFile::modeWrite             -   쓰기 전용으로 파일을 연다.

CFile::ShareDenyNone     -   다른 모듈의 파일 접근을 허용한다.

CFile::ShareDenyRead     -   다른 모듈이 해당 파일을 읽는 것을 허용하지 않는다.

CFile::ShareDenyWrite     -    다른 모듈이 해당 파일에 쓰는 것을 허용하지 않는다.

CFile::ShareExclusive     -    다른 모듈이 해당 파일에 읽기/쓰기를 허용하지 않는다.

CFile::typeText               -   텍스트 모드.

CFile::typeBinary            -   바이너리 모드.


파일 입출력 사용시  권한 문제로 액세스 할 수 없을때 위의 속성을 추가해 준다.

사용 예)

CString strPathName = FileDlg.GetPathName();
CFileException e;
CFile m_file;
if(!m_file.Open(strPathName, CFile::modeWrite|CFile::modeCreate|
CFile::shareDenyNone, &e ))
e.ReportError();
}
반응형

'MFC & API' 카테고리의 다른 글

CFileDialog 속성 값  (0) 2011.10.23
반응형

LPOPENFILENAME 구조체의 Flags 멤버에 줄 수 있는 플래그들

 

OFN_ALLOWMULTISELECT

복수개의 파일명 선택할수 있게 해준다.

 

OFN_CREATEPROMPT

존재하지 않는 파일명을 입력했을 경우 사용자에게 파일을 생성할 것인지 물어본다.

사용자가 파일 생성을 선택하면 대화상자가 닫히고, 입력한 파일을 리턴한다.

 

OFN_DONTADDTORECENT

2000 이상. 최근 사용한 파일 목록에 선택한 파일의 링크를 추가하지 않는다.

 

OFN_ENABLEHOOK

lpfnHook 맴버가 가리키는 훅 프로시저를 사용한다.

 

OFN_ENABLEINCLUDENOTIFY

2000 이상. 폴더를 열 때 훅 프로시저에게 CDN_INCLUDEITEM 통지 메시지를 보낸다.

 

OFN_ENABLESIZING

98이상. 크기 조정이 가능하도록 한다.

디폴트로 크기조정이 가능하나 커스터마이징한 경우에는 이 플래그 지정해줘야함.

 

OFN_ENABLETEMPLATE

리소스의 템플리트를 사용한다. 이때 hInstance는 리소스를 정의하는 모듈의 핸들

 

OFN_ENABLETEMPLATEHANDLE

리소스의 템플리트를 사용한다. 이때 hInstance는 템플리트 데이터 핸들이다.

 

OFN_EXPLOER

대화상자의 커스터마이징 방법 지정.

이 플래그가 설정되어 있으면 탐색기, 그렇지 않다면 구형방식으로 창이 뜬다.

기본으로 탐색기 스타일이 잡혀 있지만 커스터마이징하는 경우나

OFN_ALLOWMULTISELECT 플래그가 지정된 경우는 이 플래그를 설정해줘야 한다.

 

OFN_EXTENTIONDEFERENT

사용자가 입력한 확장자가 디폴트 확장자와 다를 때 이 플래그가 설정된다.

lpstrDefExt가 NULL이면 이 플래그는 사용되지 않는다.

 

OFN_FILEMUSTEXIST

사용자는 존재하는 파일만 입력해 넣을 수 있으며 없는 파일을 입력한 경우

경고 메시지를 보여준다. 이 플래그는 OFN_PATHMUSTEXIST 를 포함한다.

 

OFN_FORCESHOWHIDDEN

2000이상. 시스템 파일과 숨겨진 파일을 보여준다. 그러나 숨겨진 시스템

파일은 안보인다.

 

OFN_HIDEREADONLY

읽기전용 체크박스를 숨긴다

 

OFN_LONGNAMES

구형대화상자에서 긴 파일 이름을 보여준다.

탐색기 스타일의 대화상자는 이 플래그에 상관없이 항상 풀로 보여줌

 

OFN_NOLONGNAMES

구형 대화상자에서 짧은 파일 이름을 보여준다. 탐색기 스타일의 대화상자는

이 플래그를 무시한다.

 

OFN_NOCHANGEDIR

사용자가 파일 선택을 위해 디렉토리를 변경하더라도 현재 디렉토리는

원래대로 유지한다.

 

OFN_NODEREFERENCELINKS

쇼트컷 파일을 리턴한다. 이 플래그가 지정되지 않으면

쇼트컷이 참조하는 파일을 리턴한다.

 

OFN_NONETWORKBUTTON

네트워크 버튼을 숨긴다.

 

OFN_NOREADONLYRETURN

선택된 파일은 읽기전용 버튼이 선택되지 않은 상태이며 쓰기 가능한

디렉토리에 있음을 지정한다.

 

OFN_NOTESTFILECREATE

대화상자가 닫히기 전에 파일이 생성되지 않도록 한다.

 

OFN_NOVALIDATE

파일명으로 사용할 수 없는 문자를 검사하지 않도록 한다.

 

OFN_OVERWRITEPROMPT

저장하기 대화상자에서 선택한 파일이 이미 있을 경우 파일을

덮어쓸 것인지를 물어보도록한다.

 

OFN_PATHMUSTEXIST

존재하는 경로와 파일만 입력할 수 있도록 한다. 존재하지 않는

파일을 입력하면 경고를 보여준다.

 

OFN_READONLY

대화상자를 만들 떄 읽기 전용 체크박스를 선택한 채로 생성한다.

또한 이 플래그는 대화상자가 닫힐 떄 읽기 전용 체크박스의 선택여부를 리턴해준다.

 

OFN_SHAREWARE

네트윅 공유 위반 에러가 발생해도 선택한 파일을 리턴하도록 한다.

 

OFN_SHOWHELP

도움말 버튼을 보여준다

 

출처: 가남사 윈도우 API

[출처] OFN 멤버들|작성자 로지어

반응형

'MFC & API' 카테고리의 다른 글

CFile 속성 값 ( 파일 접근권한 )  (0) 2011.10.23
반응형


Xfile을 기본 메인 파일에 있을 때 텍스쳐가 잘 불러와 지다가 파일들을
한 폴더에 몰아 넣고서 폴더 경로를 지정해 줄때 파일은 읽어 지는데
텍스쳐 파일이 안 넘어 올때가 있다.

그 이유는 D3DXLoadMeshFromX에서는 잘 읽어 오는데 D3DXCreateTextureFromFile에서 전체 경로를 읽어오지 못하고 파일 이름으로만 읽어져서 문제가 생긴다. 이 경우 폴더 경로를 모두 읽을수 있도록 파일 경로를 수정하여 위치를 지정해 주어야 한다.

예) "project\\skysphere.x"
위의 경로를 텍스쳐 에서는 skysphere만 들어 오기 떄문에 파일 앞의 경로까지 읽어 위치를 찾고난 후 path에 저장한다.

 int lastSlash = filename.find_last_of( '\\' );

 std::string path = filename.substr( 0, lastSlash + 1 );

 std::string texturePath = path + mtrls[i].pTextureFilename;
 D3DXCreateTextureFromFile( m_Device, texturePath.c_str(),
                                             &tex);

다음과 같이 수정 해주면 텍스쳐 파일이 읽어올 수 있다.

반응형
반응형
GL_POINTS
GL_LINES
GL_LINE_STRIP
GL_LINE_LOOP 
GL_LINE_STIPPLE
 
GL_TRIANGLES
GL_TRIANGLE_STRIP
GL_TRIANGLE_FAN

반응형

'OpenGL' 카테고리의 다른 글

OpenGl 기본 창 생성  (0) 2011.03.21
OpenGL 설치  (0) 2011.03.21

+ Recent posts