تبليغاتX
ساخت بازیهای سه بعدی رایانه ای - یه برنامه جدید توی دایرکت ایکس (نمونه کار دوم)


//writtrn by Mohammad Nouraien nouraien_m@yahoo.com


#include
#include
#include
#include

//////////////////////////////////////////////////////////////////////
#ifndef __cameraH__
#define __cameraH__

#include

class Camera
{
public:
    enum CameraType { LANDOBJECT, AIRCRAFT };

    Camera();
    Camera(CameraType cameraType);
    ~Camera();

    void strafe(float units);
    void fly(float units);    
    void walk(float units);  
    
    void pitch(float angle);
    void yaw(float angle);  
    void roll(float angle);

    void getViewMatrix(D3DXMATRIX* V);
    void setCameraType(CameraType cameraType);
    void getPosition(D3DXVECTOR3* pos);
    void setPosition(D3DXVECTOR3* pos);

    void getRight(D3DXVECTOR3* right);
    void getUp(D3DXVECTOR3* up);
    void getLook(D3DXVECTOR3* look);
private:
    CameraType  _cameraType;
    D3DXVECTOR3 _right;
    D3DXVECTOR3 _up;
    D3DXVECTOR3 _look;
    D3DXVECTOR3 _pos;
};
#endif // __cameraH__
///////////////////////////////////////////////////////////////////

//////////////////////////////////////////////////////////////////
Camera::Camera()
{
    _cameraType = AIRCRAFT;

    _pos   = D3DXVECTOR3(0.0f, 0.0f, -6.0f);
    _right = D3DXVECTOR3(1.0f, 0.0f, 0.0f);
    _up    = D3DXVECTOR3(0.0f, 1.0f, 0.0f);
    _look  = D3DXVECTOR3(0.0f, 0.0f, 1.0f);
}

Camera::Camera(CameraType cameraType)
{
    _cameraType = cameraType;

    _pos   = D3DXVECTOR3(0.0f, 0.0f, -6.0f);
    _right = D3DXVECTOR3(1.0f, 0.0f, 0.0f);
    _up    = D3DXVECTOR3(0.0f, 1.0f, 0.0f);
    _look  = D3DXVECTOR3(0.0f, 0.0f, 1.0f);
}

Camera::~Camera()
{

}

void Camera::getPosition(D3DXVECTOR3* pos)
{
    *pos = _pos;
}

void Camera::setPosition(D3DXVECTOR3* pos)
{
    _pos = *pos;
}

void Camera::getRight(D3DXVECTOR3* right)
{
    *right = _right;
}

void Camera::getUp(D3DXVECTOR3* up)
{
    *up = _up;
}

void Camera::getLook(D3DXVECTOR3* look)
{
    *look = _look;
}

void Camera::walk(float units)
{
   
    if( _cameraType == LANDOBJECT )
        _pos += D3DXVECTOR3(_look.x, 0.0f, _look.z) * units;

    if( _cameraType == AIRCRAFT )
        _pos += _look * units;
}

void Camera::strafe(float units)
{
   
    if( _cameraType == LANDOBJECT )
        _pos += D3DXVECTOR3(_right.x, 0.0f, _right.z) * units;

    if( _cameraType == AIRCRAFT )
        _pos += _right * units;
}

void Camera::fly(float units)
{
   
    if( _cameraType == LANDOBJECT )
        _pos.y += units;

    if( _cameraType == AIRCRAFT )
        _pos += _up * units;
}

void Camera::pitch(float angle)
{
    D3DXMATRIX T;
    D3DXMatrixRotationAxis(&T, &_right,    angle);

   
    D3DXVec3TransformCoord(&_up,&_up, &T);
    D3DXVec3TransformCoord(&_look,&_look, &T);
}

void Camera::yaw(float angle)
{
    D3DXMATRIX T;

   
    if( _cameraType == LANDOBJECT )
        D3DXMatrixRotationY(&T, angle);

   
    if( _cameraType == AIRCRAFT )
        D3DXMatrixRotationAxis(&T, &_up, angle);

   
    D3DXVec3TransformCoord(&_right,&_right, &T);
    D3DXVec3TransformCoord(&_look,&_look, &T);
}

void Camera::roll(float angle)
{
   
    if( _cameraType == AIRCRAFT )
    {
        D3DXMATRIX T;
        D3DXMatrixRotationAxis(&T, &_look,    angle);

       
        D3DXVec3TransformCoord(&_right,&_right, &T);
        D3DXVec3TransformCoord(&_up,&_up, &T);
    }
}

void Camera::getViewMatrix(D3DXMATRIX* V)
{
   
    D3DXVec3Normalize(&_look, &_look);

    D3DXVec3Cross(&_up, &_look, &_right);
    D3DXVec3Normalize(&_up, &_up);

    D3DXVec3Cross(&_right, &_up, &_look);
    D3DXVec3Normalize(&_right, &_right);

   
    float x = -D3DXVec3Dot(&_right, &_pos);
    float y = -D3DXVec3Dot(&_up, &_pos);
    float z = -D3DXVec3Dot(&_look, &_pos);

    (*V)(0,0) = _right.x; (*V)(0, 1) = _up.x; (*V)(0, 2) = _look.x; (*V)(0, 3) = 0.0f;
    (*V)(1,0) = _right.y; (*V)(1, 1) = _up.y; (*V)(1, 2) = _look.y; (*V)(1, 3) = 0.0f;
    (*V)(2,0) = _right.z; (*V)(2, 1) = _up.z; (*V)(2, 2) = _look.z; (*V)(2, 3) = 0.0f;
    (*V)(3,0) = x;        (*V)(3, 1) = y;     (*V)(3, 2) = z;       (*V)(3, 3) = 1.0f;
}

void Camera::setCameraType(CameraType cameraType)
{
    _cameraType = cameraType;
}
////////////////////////////////////////////////////////////////////////////////////////



#pragma comment(lib,"d3d9.lib")
#pragma comment(lib,"D3dx9.lib")
#pragma comment(lib,"Winmm.lib")


#define WIDTH  640
#define HEIGHT 480
#define CUSTOMFVF ( D3DFVF_XYZ | D3DFVF_NORMAL | D3DFVF_DIFFUSE | D3DFVF_TEX1  )


IDirect3D9*  d3d;
IDirect3DDevice9* d3ddev;
ID3DXMesh *mesh=0;
D3DMATERIAL9 mat;   


Camera TheCamera(Camera::LANDOBJECT);


LRESULT CALLBACK mywndProc(HWND hwnd,UINT msg,WPARAM wPram,LPARAM lParam);
void initd3d(HWND hwnd);
void render_frame(float);
void cleanD3D(void);

int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine,int nShowCmd){
       

    WNDCLASS wc;
    HWND mainwindow;


    ZeroMemory(&wc,sizeof(WNDCLASS));

    wc.cbClsExtra=0;
    wc.cbWndExtra=0;
    wc.style=CS_HREDRAW |  CS_VREDRAW ;
    wc.lpfnWndProc=(WNDPROC)mywndProc;
    wc.hInstance=hInstance;
    wc.hCursor=LoadCursor(0,IDC_ARROW);
    wc.hIcon=LoadIcon(0,IDI_APPLICATION);
    wc.hbrBackground=(HBRUSH)COLOR_WINDOW   ;
    wc.lpszMenuName=0;
    wc.lpszClassName="DirectX";

    if (!RegisterClass(&wc))
        return 0;
    mainwindow=CreateWindow("DirectX","My DirectX",WS_OVERLAPPEDWINDOW,0,0,WIDTH ,HEIGHT ,0,0,hInstance,0);
    ShowWindow(mainwindow,nShowCmd);

    initd3d(mainwindow);

    MSG msg;

    ZeroMemory(&msg,sizeof(MSG ));
    float lasttime=(float)timeGetTime();
    while (true){
        if (::PeekMessage(&msg,0,0,0,PM_REMOVE ))
        {
            if (msg.message==WM_QUIT)
                break;
            TranslateMessage(&msg);
            DispatchMessage(&msg);
        }
        else
        {
            float curtime=(float)timeGetTime();
            float timedelta=(curtime-lasttime)*0.001f;
            render_frame(timedelta);
            lasttime=curtime;
        }

    }
    cleanD3D();
return msg.wParam ;

}
LRESULT CALLBACK mywndProc(HWND hwnd,UINT msg,WPARAM wParam,LPARAM lParam){
    switch(msg){
        case    WM_DESTROY :
            ::PostQuitMessage(WM_QUIT );
            return 0;
        case WM_KEYDOWN :
            if (wParam==VK_ESCAPE)
           
            ::DestroyWindow(hwnd);
            return 0;
           
    }
    return ::DefWindowProc(hwnd,msg,wParam,lParam);

}
void initd3d(HWND hwnd){
    d3d=Direct3DCreate9(D3D_SDK_VERSION );
    D3DPRESENT_PARAMETERS d3dpp;
    ZeroMemory(&d3dpp,sizeof(D3DPRESENT_PARAMETERS));
    d3dpp.Windowed=true;
    d3dpp.SwapEffect=D3DSWAPEFFECT_DISCARD ;
    d3dpp.hDeviceWindow=hwnd;
    d3d->CreateDevice(D3DADAPTER_DEFAULT ,D3DDEVTYPE_HAL,hwnd,D3DCREATE_SOFTWARE_VERTEXPROCESSING ,&d3dpp,&d3ddev);
   

   
   

    D3DXVECTOR3  position(0.0f,0.0f,-3.5f);
    D3DXVECTOR3 target(0.0f,0.0f,0.0f);
    D3DXVECTOR3 up(0.0f,1.0f,0.0f);
    D3DXMATRIX  V;


    mat.Ambient=D3DXCOLOR(0.3f,0.3,0.3f,1.0f);
    mat.Diffuse=D3DXCOLOR(0.0f,1.0f,1.0f,1.0f);
    mat.Power=0.5f;
    mat.Specular=D3DXCOLOR(1.0f,1.0f,1.0f,1.0f);

    d3ddev->SetMaterial(&mat);
    D3DXCreateSphere (d3ddev,1.0f,16,15,&mesh,0);

    D3DLIGHT9 light;
    light.Ambient=D3DXCOLOR(1.0f,1.0f,1.0f,1.0f);
    light.Diffuse=D3DXCOLOR(1.0f,1.0f,1.0f,1.0f);
    light.Direction=D3DXVECTOR3(-1.0,-1.0,1.0);
    light.Specular=D3DXCOLOR(1.0f,1.0f,1.0f,1.0f);
    light.Position =D3DXVECTOR3(2.0f,2.0f,-2.0);
    light.Type=D3DLIGHT_POINT   ;
    light.Theta=D3DX_PI /4.0f;
    light.Phi=D3DX_PI /3.0f;
    light.Range=20.0f;
    light.Attenuation0=1.0f;
    light.Attenuation1=0.0f;
    light.Attenuation2=0.0f;
   


    d3ddev->SetLight(0,&light);
    d3ddev->LightEnable(0,true);


      d3ddev->SetMaterial(&mat);

    D3DXMatrixLookAtLH(&V,&position,&target,&up);
    d3ddev->SetTransform(D3DTS_VIEW,&V);
    D3DXMATRIX proj;
    D3DXMatrixPerspectiveFovLH(&proj,D3DX_PI * 0.2f,(float)WIDTH/(float)HEIGHT ,0.2f,1000.0f);
    d3ddev->SetTransform(D3DTS_PROJECTION ,&proj);

    d3ddev->SetRenderState(D3DRS_FILLMODE,D3DFILL_WIREFRAME);
    d3ddev->SetRenderState(D3DRS_LIGHTING ,true);
    d3ddev->SetRenderState(D3DRS_CULLMODE,D3DCULL_NONE );

   
return;
}
void cleanD3D(void){
    d3d->Release();
    d3ddev->Release();
    mesh->Release();
   
    return;
}
void render_frame(float timedelta){
    D3DXMATRIX Ry,Rx;
static float y=0.0f;
    D3DXMatrixRotationX(&Rx,y);//3.14f/4.0f);
   
    D3DXMatrixRotationY(&Ry,y);
    y+=timedelta;

if (y>=6.28)
    y=0.0f;
 D3DXMATRIX p=Rx * Ry;
    d3ddev->SetTransform(D3DTS_WORLD,&p);

    if( ::GetAsyncKeyState('W') & 0x8000f )
            TheCamera.walk(4.0f * timedelta);

        if( ::GetAsyncKeyState('S') & 0x8000f )
            TheCamera.walk(-4.0f * timedelta);

        if( ::GetAsyncKeyState('A') & 0x8000f )
            TheCamera.strafe(-4.0f * timedelta);

        if( ::GetAsyncKeyState('D') & 0x8000f )
            TheCamera.strafe(4.0f * timedelta);

        if( ::GetAsyncKeyState('R') & 0x8000f )
            TheCamera.fly(4.0f * timedelta);

        if( ::GetAsyncKeyState('F') & 0x8000f )
            TheCamera.fly(-4.0f * timedelta);

        if( ::GetAsyncKeyState(VK_UP) & 0x8000f )
            TheCamera.pitch(1.0f * timedelta);

        if( ::GetAsyncKeyState(VK_DOWN) & 0x8000f )
            TheCamera.pitch(-1.0f * timedelta);

        if( ::GetAsyncKeyState(VK_LEFT) & 0x8000f )
            TheCamera.yaw(-1.0f * timedelta);
           
        if( ::GetAsyncKeyState(VK_RIGHT) & 0x8000f )
            TheCamera.yaw(1.0f * timedelta);

       
        D3DXMATRIX V;
        TheCamera.getViewMatrix(&V);
        d3ddev->SetTransform(D3DTS_VIEW, &V);

        //
    d3ddev->Clear(0,NULL ,D3DCLEAR_TARGET,D3DCOLOR_XRGB(0,0,0),1.0f,0);
    d3ddev->BeginScene();


    d3ddev->SetFVF(CUSTOMFVF);
        mesh->DrawSubset(0);
    d3ddev->EndScene();
    d3ddev->Present(0,0,0,0);
    return;
}







 

+ نوشته شده در  شنبه 23 شهریور1387ساعت 13:2  توسط محمد نورآئین  |