游戏开发论坛

 找回密码
 立即注册
搜索
查看: 1771|回复: 0

一个问题困扰好久的问题

[复制链接]

48

主题

61

帖子

61

积分

注册会员

Rank: 2

积分
61
发表于 2008-2-18 15:22:00 | 显示全部楼层 |阅读模式
一个问题困扰好久的问题,我把主要的程序贴出来。这个是主程序
int APIENTRY WinMain(HINSTANCE hInstance,       //传入的窗口句柄
                     HINSTANCE hPrevInstance,   //已存在的窗口句柄
                     LPSTR     lpCmdLine,        //传入的命令行参数
                     int       nCmdShow)         //设置窗口的显示方式
{
        CGameEngine_App GameEngine_App;
        MSG msg;
        if(!GameEngine_App.CreateWnd("骨骼动画例子",hInstance,hPrevInstance,nCmdShow)){
                return false;
        }
        hWnd=GameEngine_App.GetHWnd();  //取得已创建的窗口句柄
        if(!GameEngine_Input.CreateInput(hInstance,hWnd)){  //初始化输入设备
                MessageBox(NULL,"初始化输入设备失败.","警告",MB_OK|MB_ICONINFORMATION);
                return false;
        }
        ShowCursor(true);  
        GameEngine_Timer.InitGameTime();  //初始化游戏时间
        if(!CreateD3DDevice(hWnd,true)){  //创建D3D设备
                return false;
        }
        SetupView(); //设置摄影机位置
        SetupProjection();  //设置透视投影
        //装入骨骼动画文件tiny.x       
        g_pRole=new CSkinMesh(g_pIDirect3DDevice);
        g_pRole->LoadFromXFile("tiny.x");  
        //初始化地图       
        g_pMap=new CSimpleMap(g_pIDirect3DDevice,10000,10000);
        g_pMap->InitMap("grass.bmp");
        //上次游戏时间
    g_fGameLastTime=GameEngine_Timer.GetGamePlayTime();

        while(msg.message!=WM_QUIT){
                if(PeekMessage(&msg,NULL,0,0,PM_REMOVE)){
                        TranslateMessage(&msg);
                        DispatchMessage(&msg);
                }
                else{
                        if(DoFrame()==false) break;  //渲染一帧动画
                }
        }
        Shutdown();
        UnregisterClass(WNDCLASSNAME, hInstance);
        CoUninitialize();  //注销所有COM对象
        return true;
}

bool CreateD3DDevice(HWND hWnd,bool bFullScreen){
        //创建IDirect3D9对象
        g_pIDirect3D=Direct3DCreate9(D3D_SDK_VERSION);
        if(g_pIDirect3D==NULL){
        return false;
    }
        D3DCAPS9 d3dcaps;
        g_pIDirect3D->GetDeviceCaps(D3DADAPTER_DEFAULT,D3DDEVTYPE_HAL,&d3dcaps);
        bool bHarwareProcess;
        if(d3dcaps.DevCaps & D3DDEVCAPS_HWTRANSFORMANDLIGHT){
                bHarwareProcess=true;
        }
        else{
                bHarwareProcess=false;
        }
        //取得显示模式
        D3DDISPLAYMODE d3dDisplayMode;
    if(FAILED(g_pIDirect3D->GetAdapterDisplayMode(D3DADAPTER_DEFAULT, &d3dDisplayMode))){
            return false;
    }
        //设置d3d设备的渲染参数
        D3DPRESENT_PARAMETERS d3dPresent_Param;   //渲染参数结构体
    ZeroMemory(&d3dPresent_Param, sizeof(d3dPresent_Param));  //结构体清0
        d3dPresent_Param.BackBufferWidth=800;
        d3dPresent_Param.BackBufferHeight=600;
        d3dPresent_Param.BackBufferFormat=d3dDisplayMode.Format;
        d3dPresent_Param.BackBufferCount=1;
        d3dPresent_Param.hDeviceWindow=hWnd;  //
        d3dPresent_Param.Windowed=!bFullScreen;  //false为全屏幕显示方式
    d3dPresent_Param.SwapEffect=D3DSWAPEFFECT_FLIP;
        d3dPresent_Param.PresentationInterval=D3DPRESENT_INTERVAL_DEFAULT;
        d3dPresent_Param.EnableAutoDepthStencil=TRUE;
        d3dPresent_Param.AutoDepthStencilFormat=D3DFMT_D16;
        //创建d3d设备
        if(bHarwareProcess){
                if(FAILED(g_pIDirect3D->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hWnd,
                                   D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dPresent_Param,
                                   &g_pIDirect3DDevice))){  //已改为软件处理
                        return false;
                }
        }
        else{
                if(FAILED(g_pIDirect3D->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hWnd,
                                   D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dPresent_Param,
                                   &g_pIDirect3DDevice))){
                        return false;
                }
        }
       
        return true;
}

void Shutdown(){
        delete g_pMap;g_pMap=NULL;
        delete g_pRole;g_pRole=NULL;
        SafeRelease(g_pIDirect3DDevice);
    SafeRelease(g_pIDirect3D);
}
//调整摄影机的距离
void Zoom(float fStep)
{
        g_vEyePt+=(g_vEyePt - g_vLookatPt)*fStep;
}
//旋转摄影机
void CameraRotate(float fAngle){
        D3DXVECTOR3 vRotateAxis=D3DXVECTOR3(0,1,0);
        D3DXMATRIX matRotate;
        D3DXMatrixRotationAxis(&matRotate,&vRotateAxis,fAngle);
        D3DXVec3TransformCoord(&g_vEyePt,&g_vEyePt,&matRotate);
}
//设置摄影机位置
void SetupView()
{
        D3DXMATRIX matView;

        D3DXVECTOR3        vUpVec( 0.0f, 1.0f, 0.0f );
        D3DXMatrixLookAtLH( &matView, &g_vEyePt, &g_vLookatPt, &vUpVec );
        g_pIDirect3DDevice->SetTransform( D3DTS_VIEW, &matView );
}
//设置透视投影
void SetupProjection()
{
        D3DXMATRIX matProj;
        D3DXMatrixPerspectiveFovLH( &matProj, D3DX_PI/4, 1.0f, 100.0f, 100000.0f );
        g_pIDirect3DDevice->SetTransform( D3DTS_PROJECTION, &matProj);
}
//设置世界空间
void SetupWorld()
{
        D3DXMATRIX matWorld;
        D3DXMatrixIdentity(&matWorld);
        g_pIDirect3DDevice->SetTransform( D3DTS_WORLD, &matWorld );
}
//渲染一动画帧
bool DoFrame()
{
        D3DXVECTOR3        g_vCurrentMousePt;
        D3DXMATRIX matProj,matView,matWorld;
        D3DVIEWPORT9 viewPort;
        POINT ptCursor;
        D3DXVECTOR3 vScreen,vOut;
        D3DXPLANE plane;
        D3DXVECTOR3 v1(1.0f,0.0f,1.0f);
        D3DXVECTOR3 v2(-1.0f,0.0f,1.0f);
        D3DXVECTOR3 v3(-1.0f,0.0f,-1.0f);
        float fAngle;
        //读取键盘输入
        if(GameEngine_Input.ReadKeyboard()){
                if(GameEngine_Input.IsKeyPressed(DIK_ESCAPE)){
                        return false;
                }
                if(GameEngine_Input.IsKeyPressed(DIK_UP)){
                        Zoom(-fZoomStep);
                }
                if(GameEngine_Input.IsKeyPressed(DIK_DOWN)){
                        Zoom(fZoomStep);
                }
                if(GameEngine_Input.IsKeyPressed(DIK_LEFT)){
                        CameraRotate(-ROTATE_ANGLE);
                }
                if(GameEngine_Input.IsKeyPressed(DIK_RIGHT)){
                        CameraRotate(ROTATE_ANGLE);
                }
        }
        //读取鼠标
        if(GameEngine_Input.ReadMouse()){
                if(GameEngine_Input.IsLButtonPressed()){
                        g_pRole->SetAnim(true);
                        g_bRoleMove=true;
                        g_bMoveLoop=true;
                }
        }
        if(GameEngine_Timer.GetGamePlayTime()<g_fGameLastTime +30){
                return true;
        }
        //若Clear函数成功执行,清屏
        g_pIDirect3DDevice->Clear(0,NULL,D3DCLEAR_TARGET|D3DCLEAR_ZBUFFER,D3DCOLOR_XRGB(0,0,255),1.0f,0);
        g_pIDirect3DDevice->BeginScene();
        SetupWorld();  //设置世界矩阵为单位矩阵,重置数据
        SetupView();
        g_pMap->Render();   //绘制地图
    //角色绘制
        if(g_bRoleMove){
                g_pIDirect3DDevice->GetTransform( D3DTS_PROJECTION, &matProj );
                g_pIDirect3DDevice->GetTransform( D3DTS_VIEW, &matView );
                g_pIDirect3DDevice->GetTransform( D3DTS_WORLD,&matWorld );
                g_pIDirect3DDevice->GetViewport(&viewPort);
                GetCursorPos(&ptCursor);
                ScreenToClient(hWnd, &ptCursor);
                vScreen=D3DXVECTOR3((float)ptCursor.x,(float)ptCursor.y,0.0f);
                D3DXVec3Unproject(&vOut,&vScreen,&viewPort,&matProj,&matView,&matWorld);
                D3DXPlaneFromPoints(&plane, &v1, &v2, &v3);
                D3DXPlaneIntersectLine(&g_vCurrentMousePt, &plane, &g_vEyePt, &vOut);  //y=0平面交点
                fAngle=3*D3DX_PI/2-(float)atan2(g_vCurrentMousePt.z-g_vLastMousePt.z , g_vCurrentMousePt.x-g_vLastMousePt.x);  //鼠标点在世界空间的坐标
               
                g_pRole->SetRotateAngle(fAngle);
                g_vRoleEndPt=g_vCurrentMousePt;  //可以替换
                g_vLastMousePt=g_vCurrentMousePt;
                g_bRoleMove=false;
        }
        if(g_bMoveLoop){
                RoleMove(g_vRoleStartPt,g_vRoleEndPt,g_iRolePos);
                g_iRolePos++;
        }

        g_pRole->Render();
        g_pIDirect3DDevice->EndScene();
        g_pIDirect3DDevice-&gtresent(NULL,NULL,NULL,NULL);
        return true;
}
//角色行走
void RoleMove(D3DXVECTOR3 vStartPoint,D3DXVECTOR3 vEndPoint,int iPos){
        D3DXVECTOR3 vCurrentPos;
        D3DXMATRIX matStep;
        if(iPos<=STEPCOUNT){
                vCurrentPos=(vEndPoint-vStartPoint)*(float)iPos/STEPCOUNT + vStartPoint;
                D3DXMatrixTranslation(&matStep,
                        vCurrentPos.x-g_vLastRolePt.x,
                        vCurrentPos.y-g_vLastRolePt.y,
                        vCurrentPos.z-g_vLastRolePt.z);
                g_pRole->m_matMoveMatrices=g_pRole->m_matMoveMatrices * matStep;
                g_vLastRolePt=vCurrentPos;
        }
        else{
                g_pRole->SetAnim(false);
                g_iRolePos=0;
                g_bRoleMove=false;
                g_bMoveLoop=false;
                g_vRoleStartPt=g_vRoleEndPt;
               
        }
}
然后还有一个叫GameEngine_ScnenManager的类
CGameEngine_SceneManager::CGameEngine_SceneManager(){

}

CGameEngine_SceneManager::~CGameEngine_SceneManager(){
        Closedown();
}

bool CGameEngine_SceneManager::Init(){
        //创建IDirect3D9对象
        m_pIDirect3D=Direct3DCreate9(D3D_SDK_VERSION);
        if(m_pIDirect3D==NULL){
        return false;
    }
        return true;
}

bool CGameEngine_SceneManager::SetRenderMode(HWND hWnd,bool bFullScreen,int iWidth,int iHeight){
        //取得显示模式
        D3DDISPLAYMODE d3dDisplayMode;
        RECT clientRect;
        RECT wndRect;
        int iWndPosX,iWndPosY,iTitlebarWidth,iTitlebarHeight;
        m_hWnd=hWnd;
        if(FAILED(m_pIDirect3D->GetAdapterDisplayMode(D3DADAPTER_DEFAULT, &d3dDisplayMode)))
                return false;
        //设置屏幕窗口大小
        if(bFullScreen){
                m_iWidth=iWidth;
                m_iHeight=iHeight;
        }
        else{
                if(iWidth>0 && iHeight>0){
                        m_iWidth=iWidth;
                        m_iHeight=iHeight;
                        GetClientRect(m_hWnd,&clientRect);
                }
                else
                        return false;
        }
        //窗口,则移动到屏幕中央位置
        if(!bFullScreen){
                iWndPosX=(d3dDisplayMode.Width - m_iWidth)/2;
                iWndPosY=(d3dDisplayMode.Height - m_iHeight)/2;
                GetWindowRect(m_hWnd,&wndRect);
                iTitlebarWidth=(wndRect.right - wndRect.left) - clientRect.right;
                iTitlebarHeight=(wndRect.bottom - wndRect.top) - clientRect.bottom;
                MoveWindow(m_hWnd,iWndPosX,iWndPosY,iTitlebarWidth+m_iWidth,iTitlebarHeight+m_iHeight,true);
        }
        //设置D3D设备的属性参数
        D3DPRESENT_PARAMETERS d3dPresent_Param;   //渲染参数结构体
    ZeroMemory(&d3dPresent_Param, sizeof(d3dPresent_Param));  //结构体清0
        d3dPresent_Param.BackBufferFormat=d3dDisplayMode.Format;
        if(bFullScreen){  //全屏幕方式
                d3dPresent_Param.BackBufferWidth=m_iWidth;
                d3dPresent_Param.BackBufferHeight=m_iHeight;
                d3dPresent_Param.BackBufferCount=1;
                d3dPresent_Param.hDeviceWindow=m_hWnd;
                d3dPresent_Param.Windowed=false;  //false为全屏幕显示方式
                d3dPresent_Param.SwapEffect=D3DSWAPEFFECT_FLIP;
                d3dPresent_Param.FullScreen_RefreshRateInHz=D3DPRESENT_RATE_DEFAULT;
                d3dPresent_Param.PresentationInterval=D3DPRESENT_INTERVAL_DEFAULT;
                d3dPresent_Param.EnableAutoDepthStencil=true;
                d3dPresent_Param.AutoDepthStencilFormat=D3DFMT_D24S8;
        }
        else{
                d3dPresent_Param.Windowed=true;
                d3dPresent_Param.SwapEffect=D3DSWAPEFFECT_DISCARD;
        }
        //简单的硬件、软件渲染选择
        D3DCAPS9 d3dcaps;
        bool bHardwareProcess;
        m_pIDirect3D->GetDeviceCaps(D3DADAPTER_DEFAULT,D3DDEVTYPE_HAL,&d3dcaps);
        if(d3dcaps.DevCaps & D3DDEVCAPS_HWTRANSFORMANDLIGHT){
                bHardwareProcess=true;
        }
        else{
                bHardwareProcess=false;
        }
        //创建d3d设备
        if(bHardwareProcess){
                if(FAILED(m_pIDirect3D->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, m_hWnd,
                                   D3DCREATE_HARDWARE_VERTEXPROCESSING, &d3dPresent_Param,
                                   &m_pIDirect3DDevice))){
                        return false;
                }
        }
        else{
                if(FAILED(m_pIDirect3D->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, m_hWnd,
                                   D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dPresent_Param,
                                   &m_pIDirect3DDevice))){
                        return false;
                }
        }
        //设置渲染状态
        m_pIDirect3DDevice->SetRenderState(D3DRS_LIGHTING,false);
        m_pIDirect3DDevice->SetRenderState(D3DRS_ZENABLE,true);
        m_pIDirect3DDevice->SetRenderState(D3DRS_ALPHATESTENABLE,false);
        m_pIDirect3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE,false);
        m_pIDirect3DDevice->SetSamplerState(0,D3DSAMP_MAGFILTER,D3DTEXF_LINEAR);
        m_pIDirect3DDevice->SetSamplerState(0,D3DSAMP_MINFILTER,D3DTEXF_LINEAR);
        //创建精灵
        if(FAILED(D3DXCreateSprite(m_pIDirect3DDevice,&m_pSprite)))
                return false;
        return true;
}

大家可以看到关于场景初始化的部分有重复,我想用GameEngine_SceneManager里的Init()和SetRenderMode()函数对main里的场景初始化的部分进行代替,可是代替之后,骨骼动画就用不了了,问题是怎样对g_pIDirect3DDevice进行变换,有兴趣的朋友可以加我QQ:739880612
我可以把所有代码发给你

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

作品发布|文章投稿|广告合作|关于本站|游戏开发论坛 ( 闽ICP备17032699号-3 )

GMT+8, 2025-12-20 02:59

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表