jjdado

jjdado

0个粉丝

8

问答

0

专栏

0

资料

jjdado  发布于  2012-12-04 12:57:16
采纳率 0%
8个问答
3166

Windows Mobile三维编程

 
  DirectX是一种应用程序接口(API),它可让以windows为平台的游戏或多媒体程序获得更高的执行效率,加强3d图形和声音效果,并提供设计人员一个共同的硬件驱动标准,让游戏开发者不必为每一品牌的硬件来写不同的驱动程序,也降低用户安装及设置硬件的复杂度。
      DirectX有两种不同的加速模式,DirectDraw和Direct3D。其中DirectDraw的主要目的其实是用来让开发者可以直接处理显存,并能够利用硬件来直接实现诸如位图拷贝、覆盖层、页面交换、透明和半透明、调色板处理等,是在2D中最常用的技术。Direct3D:交互式的三维图形技术。这里重点介绍下Windows Mobile 中Direct3D技术:
    一,我们须在头文件中包含 d3dm.h 和 d3dmx.h 头文件。
    二,初始化Direct3D,这里需要调用到API:Direct3DmobileCreate();然后我们调用D3DM的引用设备DLL,得到设备的入口地址,注册该设备。
    三,创建设备的内存空间。
    四,清理释放所有的空间和变量。
程序参考代码如下:
#pragma comment(linker, "/nodefaultlib:oldnames.lib")

#include
#include
#include
#include


//-----------------------------------------------------------------------------
// Global variables
//-----------------------------------------------------------------------------
LPDIRECT3DMOBILE        g_pD3DM       = NULL;  // Used to create the D3DMDevice
LPDIRECT3DMOBILEDEVICE  g_pd3dmDevice = NULL;  // Our rendering device
HMODULE                 g_hRefDLL     = NULL;  // DLL handle for d3dmref.dll
bool                    g_bUseRef     = false; // Flag denoting use of d3dmref

LPDIRECT3DMOBILEVERTEXBUFFER g_pVB    = NULL;  // Buffer to hold vertices

// A structure for our custom vertex type
struct CUSTOMVERTEX
{
    FLOAT x, y, z;  // The transformed position for the vertex
    DWORD color;    // The vertex color
};

// Our custom FVF, which describes our custom vertex structure
#define D3DMFVF_CUSTOMVERTEX (D3DMFVF_XYZ_FLOAT | D3DMFVF_DIFFUSE)


BOOL IsScreenRotated()
{
    DEVMODE devMode  = {0};
    devMode.dmSize   = sizeof(DEVMODE);
    devMode.dmFields = DM_DISPLAYORIENTATION;

    ChangeDisplaySettingsEx(NULL, &devMode, NULL, CDS_TEST, NULL);

    if (devMode.dmDisplayOrientation != DMDO_0)
    {
        MessageBox(
            NULL,
            TEXT("This D3DM sample will not work on a rotated screen.\nThe application will now exit."),
            TEXT("Notice"),
            MB_OK | MB_ICONINFORMATION | MB_SETFOREGROUND
            );

        return TRUE;
    }

    return FALSE;
}

HRESULT InitD3DM( HWND hWnd )
{
    // Create the D3DM object, which is needed to create the D3DMDevice.
    if( NULL == ( g_pD3DM = Direct3DMobileCreate( D3DM_SDK_VERSION ) ) )
        return E_FAIL;

    D3DMPRESENT_PARAMETERS d3dmpp;
    memset( &d3dmpp, 0, sizeof(d3dmpp) );
    d3dmpp.Windowed = TRUE;
    d3dmpp.SwapEffect = D3DMSWAPEFFECT_DISCARD;
    d3dmpp.BackBufferFormat = D3DMFMT_UNKNOWN;

    // Create the Direct3D Mobile device.
    UINT uAdapter;
   
    if (g_bUseRef)
    {
        // Load the D3DM reference driver DLL
        g_hRefDLL = (HMODULE)LoadLibrary(TEXT("d3dmref.dll"));
        if (NULL == g_hRefDLL)
        {
            OutputDebugString(TEXT("Unable to load D3DM reference driver DLL.\n"));
            return E_FAIL;
        }

        // Get the reference driver's entry point
        void* pfnD3DMInit = GetProcAddress(g_hRefDLL, TEXT("D3DM_Initialize"));   
        if ( NULL == pfnD3DMInit )
        {
            OutputDebugString(TEXT("Unable to retrieve D3DM reference driver entry point.\n"));
            return E_FAIL;
        }

        // Register the software device
        if ( FAILED( g_pD3DM->RegisterSoftwareDevice(pfnD3DMInit) ) )
        {
            OutputDebugString(TEXT("Unable to register D3DM reference driver.\n"));
            return E_FAIL;
        }
        
        uAdapter = D3DMADAPTER_REGISTERED_DEVICE;
    }
    else
    {
        // Use the default system D3DM driver   
        uAdapter = D3DMADAPTER_DEFAULT;
    }

    if ( FAILED( g_pD3DM->CreateDevice( uAdapter,
                                    D3DMDEVTYPE_DEFAULT,
                                    hWnd, 0,
                                    &d3dmpp, &g_pd3dmDevice ) ) )
    {
        OutputDebugString(TEXT("Unable to create a D3DM device.\n"));
        return E_FAIL;
    }
   
    // Turn off culling, so we see the front and back of the triangle
    g_pd3dmDevice->SetRenderState( D3DMRS_CULLMODE, D3DMCULL_NONE );

    // Turn off D3DM lighting, since we are providing our own vertex colors
    g_pd3dmDevice->SetRenderState( D3DMRS_LIGHTING, FALSE );

    return S_OK;
}

HRESULT InitVB()
{
    // Initialize three vertices for rendering a triangle
    CUSTOMVERTEX vertices[] =
    {
        { -1.0f,-1.0f, 0.0f, 0xffff0000 },
        {  1.0f,-1.0f, 0.0f, 0xff0000ff },
        {  0.0f, 1.0f, 0.0f, 0xffffffff }
    };

    // Determine if the device can create vertex buffers in video memory
    // by testing the device caps bits.
    D3DMCAPS caps;
    if ( FAILED( g_pd3dmDevice->GetDeviceCaps(&caps) ) )
    {
        return E_FAIL;
    }
    D3DMPOOL pool;
    if (caps.SurfaceCaps & D3DMSURFCAPS_VIDVERTEXBUFFER)
    {
        pool = D3DMPOOL_VIDEOMEM;
    }
    else
    {
        pool = D3DMPOOL_SYSTEMMEM;
    }        

    if ( FAILED( g_pd3dmDevice->CreateVertexBuffer( 3*sizeof(CUSTOMVERTEX),
                                                    0, D3DMFVF_CUSTOMVERTEX,
                                                    pool, &g_pVB ) ) )
    {
        return E_FAIL;
    }

    void* pVertices;
    if ( FAILED( g_pVB->Lock( 0, sizeof(vertices), &pVertices, 0 ) ) )
        return E_FAIL;

    memcpy( pVertices, vertices, sizeof(vertices) );
    g_pVB->Unlock();

    return S_OK;
}

VOID Cleanup()
{
    if( g_pVB != NULL )        
        g_pVB->Release();

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

    if( g_pD3DM != NULL)
    {
        if (g_hRefDLL)
        {
            g_pD3DM->RegisterSoftwareDevice(NULL);
            FreeLibrary(g_hRefDLL);
        }
   
        g_pD3DM->Release();
    }
}

VOID SetupMatrices()
{
    // For our world matrix, we will just rotate the object about the y-axis.
    D3DMXMATRIX matWorld;

    UINT  iTime  = GetTickCount() % 1000;
    float fAngle = iTime * (2.0f * D3DMX_PI) / 1000.0f;
    D3DMXMatrixRotationY( &matWorld, fAngle );
    g_pd3dmDevice->SetTransform( D3DMTS_WORLD, (D3DMMATRIX*)&matWorld, D3DMFMT_D3DMVALUE_FLOAT );

    D3DMXVECTOR3 vEyePt( 0.0f, 3.0f, -5.0f );
    D3DMXVECTOR3 vLookatPt( 0.0f, 0.0f, 0.0f );
    D3DMXVECTOR3 vUpVec( 0.0f, 1.0f, 0.0f );
    D3DMXMATRIX matView;
    D3DMXMatrixLookAtLH( &matView, &vEyePt, &vLookatPt, &vUpVec );
    g_pd3dmDevice->SetTransform( D3DMTS_VIEW, (D3DMMATRIX*)&matView, D3DMFMT_D3DMVALUE_FLOAT );

    D3DMXMATRIX matProj;
    D3DMXMatrixPerspectiveFovLH( &matProj, D3DMX_PI/4.0f, 1.0f, 1.0f, 100.0f );
    g_pd3dmDevice->SetTransform( D3DMTS_PROJECTION, (D3DMMATRIX*)&matProj, D3DMFMT_D3DMVALUE_FLOAT );
}

VOID Render()
{
    if( NULL == g_pd3dmDevice )
        return;

    // Clear the backbuffer to a blue color
    g_pd3dmDevice->Clear( 0, NULL, D3DMCLEAR_TARGET, D3DMCOLOR_XRGB(0,0,0), 1.0f, 0 );
   
    // Begin the scene
    if( SUCCEEDED( g_pd3dmDevice->BeginScene() ) )
    {
        // Setup the world, view, and projection matrices
        SetupMatrices();
        
        // Render the vertex buffer contents
        g_pd3dmDevice->SetStreamSource( 0, g_pVB, sizeof(CUSTOMVERTEX) );
        g_pd3dmDevice->DrawPrimitive( D3DMPT_TRIANGLELIST, 0, 1 );

        // End the scene
        g_pd3dmDevice->EndScene();
    }

    // Present the backbuffer contents to the display
    g_pd3dmDevice->Present( NULL, NULL, NULL, NULL );
}

LRESULT WINAPI MsgProc( HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam )
{
    switch( msg )
    {
    case WM_LBUTTONUP:
            PostMessage(hWnd, WM_CLOSE, 0, 0);
        break;

    case WM_KEYDOWN:
        if (VK_ESCAPE == wParam)
        {
            PostMessage(hWnd, WM_CLOSE, 0, 0);
        }
        break;

    case WM_CLOSE:
        Cleanup();
        break;

    case WM_DESTROY:
        PostQuitMessage( 0 );
        return 0;

    case WM_SETTINGCHANGE:
        //we don't support screen rotation
        if (IsScreenRotated())
        {
            PostMessage(hWnd, WM_CLOSE, 0, 0);
        }
        break;
    }

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

INT WINAPI WinMain( HINSTANCE hInst, HINSTANCE, LPTSTR szCmd, INT )
{
    // Parse command line to determine if user wants to use
    // the D3DM reference driver instead of the default system driver
    if (0 == lstrcmp(szCmd, TEXT("-ref")))
        g_bUseRef = true;

    //We don't support a rotated screen
    if (IsScreenRotated())
    {
        return 0;
    }
   
    // Register the window class
    WNDCLASS wc = { 0L, MsgProc, 0L, 0L, hInst, NULL, NULL, NULL, NULL, TEXT("D3DM Tutorial") };
    RegisterClass( &wc );

    int iScreenWidth  = GetSystemMetrics(SM_CXSCREEN);
    int iScreenHeight = GetSystemMetrics(SM_CYSCREEN);

    // Create the application's window
    HWND hWnd = CreateWindow( TEXT("D3DM Tutorial"),
                              TEXT("D3DM Tutorial 03: Matrices"),
                              WS_VISIBLE,
                              0, 0, iScreenWidth, iScreenHeight,
                              NULL, NULL, wc.hInstance, NULL );

    SHFullScreen(hWnd, SHFS_HIDESIPBUTTON | SHFS_HIDETASKBAR);

    // Initialize Direct3D Mobile
    if( SUCCEEDED( InitD3DM( hWnd ) ) )
    {
        // Create the vertex buffer
        if( SUCCEEDED( InitVB() ) )
        {
            // Show the window
            ShowWindow( hWnd, SW_SHOWNORMAL );
            UpdateWindow( hWnd );

            // Enter the message loop
            MSG msg;
            memset( &msg, 0, sizeof(msg) );
            while( msg.message != WM_QUIT )
            {
                if( PeekMessage( &msg, NULL, 0U, 0U, PM_REMOVE ) )
                {
                    TranslateMessage( &msg );
                    DispatchMessage( &msg );
                }
                else
                    Render();
            }
        }
    }

    return 0;
}
我来回答
回答0个
时间排序
认可量排序
易百纳技术社区暂无数据
或将文件直接拖到这里
悬赏:
E币
网盘
* 网盘链接:
* 提取码:
悬赏:
E币

Markdown 语法

  • 加粗**内容**
  • 斜体*内容*
  • 删除线~~内容~~
  • 引用> 引用内容
  • 代码`代码`
  • 代码块```编程语言↵代码```
  • 链接[链接标题](url)
  • 无序列表- 内容
  • 有序列表1. 内容
  • 缩进内容
  • 图片![alt](url)
+ 添加网盘链接/附件

Markdown 语法

  • 加粗**内容**
  • 斜体*内容*
  • 删除线~~内容~~
  • 引用> 引用内容
  • 代码`代码`
  • 代码块```编程语言↵代码```
  • 链接[链接标题](url)
  • 无序列表- 内容
  • 有序列表1. 内容
  • 缩进内容
  • 图片![alt](url)
举报反馈

举报类型

  • 内容涉黄/赌/毒
  • 内容侵权/抄袭
  • 政治相关
  • 涉嫌广告
  • 侮辱谩骂
  • 其他

详细说明

易百纳技术社区