游戏开发论坛

 找回密码
 立即注册
搜索
查看: 2153|回复: 3

为什么我画的正方形不是正方形呢??

[复制链接]

6

主题

16

帖子

16

积分

新手上路

Rank: 1

积分
16
发表于 2010-3-27 11:58:00 | 显示全部楼层 |阅读模式
各位大侠,我现在是想用dx画一个正方形,但是在经过一系列的坐标转换后原本是正方形的现在变成了非正方形,我有点想不通,希望给位给予解答!谢谢!


#include <d3dx9.h> //D3DX实用库函数, 该头文件中又包含了d3d9.h头文件


//-----------------------------------------------------------------------------
// Desc: 全局变量
//-----------------------------------------------------------------------------
LPDIRECT3D9                g_pD3D       = NULL;    //Direct3D对象
LPDIRECT3DDEVICE9          g_pd3dDevice = NULL;    //Direct3D设备对象
LPDIRECT3DVERTEXBUFFER9    g_pVB        = NULL;    //顶点缓冲区对象
HWND                                           g_Wnd            = NULL;    //窗口句柄
D3DRECT                    g_ClentRect;


//-----------------------------------------------------------------------------
// Desc: 顶点结构 、灵活的顶点格式
//-----------------------------------------------------------------------------
struct CUSTOMVERTEX
{
    D3DXVECTOR3 position;
    DWORD color;
};
#define D3DFVF_CUSTOMVERTEX (D3DFVF_XYZ|D3DFVF_DIFFUSE)


//-----------------------------------------------------------------------------
// Desc: 设置世界矩阵
//-----------------------------------------------------------------------------
VOID SetupWorldMatrice()
{
        //建立一个绕X轴动态旋转的世界矩阵
    D3DXMATRIX matWorld;
    UINT  iTime  = timeGetTime() % 1000;
   // FLOAT fAngle = iTime * (2.0f * D3DX_PI) / 1000.0f;
        D3DXMatrixIdentity( &matWorld );     //将一个矩阵单位化
    D3DXMatrixTranslation( &matWorld,0,0,0 );


        //设置世界矩阵
    g_pd3dDevice->SetTransform( D3DTS_WORLD, &matWorld );
}


//-----------------------------------------------------------------------------
// Desc: 设置观察矩阵和投影矩阵
//-----------------------------------------------------------------------------
VOID SetupViewandProjMatrices()
{
    //建立并设置观察矩阵
    D3DXVECTOR3 vEyePt( 0.0f, 3.0f,-5.0f );     //此时的坐标范围是什么??????????
    D3DXVECTOR3 vLookatPt( 0.0f, 0.0f, 0.0f );
    D3DXVECTOR3 vUpVec( 0.0f, 1.0f, 0.0f );
    D3DXMATRIX matView;
    D3DXMatrixLookAtLH( &matView, &vEyePt, &vLookatPt, &vUpVec );
    g_pd3dDevice->SetTransform( D3DTS_VIEW, &matView );     //视区是以左上角为坐标原点,“x”轴是向右增大(-1,+1),“y”轴是向下增大(-1,+1),“z”向里增大(0,+1)

    //建立并设置投影矩阵
    D3DXMATRIX matProj;
    D3DXMatrixPerspectiveFovLH( &matProj, D3DX_PI/4, 1.0f, 1.0f, 100.0f );
    g_pd3dDevice->SetTransform( D3DTS_PROJECTION, &matProj );
}


//-----------------------------------------------------------------------------
// Desc: 设置视区
//-----------------------------------------------------------------------------
VOID SetupViewPort()
{
        RECT rect;
        GetClientRect(g_Wnd,&rect);  //g_Wnd:窗口句柄,用这个函数来获得窗口绘制区域的大小,“rect”为窗口返回的地址
        D3DVIEWPORT9 vp;   // D3DVIEWPORT9 为视区结构
        vp.X      = 0;
        vp.Y      = 0;
        vp.Width  = rect.right;
        vp.Height = rect.bottom;
        vp.MinZ   = 0.0f;
        vp.MaxZ   = 1.0f;
        g_pd3dDevice->SetViewport(&vp);
}


//-----------------------------------------------------------------------------
// Desc: 初始化Direct3D
//-----------------------------------------------------------------------------
HRESULT InitD3D( HWND hWnd )
{
        //创建Direct3D对象, 该对象用于创建Direct3D设备对象
    if( NULL == ( g_pD3D = Direct3DCreate9( D3D_SDK_VERSION ) ) )
        return E_FAIL;

        //设置D3DPRESENT_PARAMETERS结构, 准备创建Direct3D设备对象
    D3DPRESENT_PARAMETERS d3dpp;
    ZeroMemory( &d3dpp, sizeof(d3dpp) );
    d3dpp.Windowed = TRUE;
    d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
    d3dpp.BackBufferFormat = D3DFMT_UNKNOWN;

        //创建Direct3D设备对象
    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 );

        //设置观察和投影矩阵
        SetupViewandProjMatrices();

        //设置视区
        SetupViewPort();

        return S_OK;
}


//-----------------------------------------------------------------------------
// Desc: 创建场景图形
//-----------------------------------------------------------------------------
HRESULT InitGeometry()
{
        //创顶点缓冲区  (顶点缓冲区是dx用来保存顶点数据的内存缓冲区)
    if( FAILED( g_pd3dDevice->CreateVertexBuffer( 6*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;
            
        pVertices[0].position = D3DXVECTOR3( -0.5f,0.5f,0.5f );
                pVertices[0].color   =0xffffff00;
        pVertices[1].position = D3DXVECTOR3( 0.5f, 0.5f, 0.5f );
                pVertices[1].color   =0xffffff00;
                pVertices[2].position = D3DXVECTOR3( 0.5f, -0.5f, 0.5f );
                pVertices[2].color   =0xffffff00;

                pVertices[3].position = D3DXVECTOR3( 0.5f, -0.5f, 0.5f );
                pVertices[3].color   =0xffffff00;
                pVertices[4].position = D3DXVECTOR3( -0.5f, -0.5f, 0.5f );
                pVertices[4].color   =0xffffff00;
                pVertices[5].position = D3DXVECTOR3( -0.5f,0.5f,0.5f );
                pVertices[5].color   =0xffffff00;

               
               

   
    g_pVB->Unlock();

    return S_OK;
}


//-----------------------------------------------------------------------------
// Desc: 释放创建的对象
//-----------------------------------------------------------------------------
VOID Cleanup()
{
        //释放顶点缓冲区对象
    if( g_pVB != NULL )
        g_pVB->Release();

        //释放Direct3D设备对象
    if( g_pd3dDevice != NULL )
        g_pd3dDevice->Release();

        //释放Direct3D对象
    if( g_pD3D != NULL )
        g_pD3D->Release();
}


//-----------------------------------------------------------------------------
// Desc: 渲染图形
//-----------------------------------------------------------------------------
VOID Render()
{
        //清空后台缓冲区
    g_pd3dDevice->Clear( 0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(45, 50, 170), 1.0f, 0 );

        //开始在后台缓冲区绘制图形
    if( SUCCEEDED( g_pd3dDevice->BeginScene() ) )
    {
                //设置世界矩阵
        SetupWorldMatrice();   //动画一般在世界坐标系里改变

                //在后台缓冲区绘制图形
        g_pd3dDevice->SetStreamSource( 0, g_pVB, 0, sizeof(CUSTOMVERTEX) );
        g_pd3dDevice->SetFVF( D3DFVF_CUSTOMVERTEX );
        g_pd3dDevice->DrawPrimitive( D3DPT_TRIANGLELIST, 0,2 );

                //结束在后台缓冲区渲染图形
        g_pd3dDevice->EndScene();
    }

        //将在后台缓冲区绘制的图形提交到前台缓冲区显示
    g_pd3dDevice-&gtresent( NULL, NULL, NULL, NULL );
}


//-----------------------------------------------------------------------------
// Desc: 消息处理
//-----------------------------------------------------------------------------
LRESULT WINAPI MsgProc( HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam )
{
        switch( msg )
        {
        case WM_DESTROY:
                Cleanup();
                PostQuitMessage( 0 );
                return 0;
        }

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


//-----------------------------------------------------------------------------
// Desc: 入口函数
//-----------------------------------------------------------------------------
INT WINAPI WinMain( HINSTANCE hInst, HINSTANCE, LPSTR, INT )
{
        //注册窗口类
    WNDCLASSEX wc = { sizeof(WNDCLASSEX), CS_CLASSDC , MsgProc, 0L, 0L,
                      GetModuleHandle(NULL), NULL, NULL, NULL, NULL,
                      L"ClassName", NULL };
    RegisterClassEx( &wc );

        //创建窗口
    HWND hWnd = CreateWindow( L"ClassName", L"坐标变换",
                              WS_OVERLAPPEDWINDOW, 200, 100, 500,500,
                              GetDesktopWindow(), NULL, wc.hInstance, NULL );
        g_Wnd=hWnd;

        //初始化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"ClassName", wc.hInstance );
    return 0;
}

42

主题

140

帖子

158

积分

注册会员

Rank: 2

积分
158
发表于 2010-3-28 10:52:00 | 显示全部楼层

Re:为什么我画的正方形不是正方形呢??

透视投影矩阵的aspect设置对了没有??

180

主题

3511

帖子

3520

积分

论坛元老

Rank: 8Rank: 8

积分
3520
发表于 2010-3-28 13:21:00 | 显示全部楼层

Re: 为什么我画的正方形不是正方形呢??

hqlwy: 为什么我画的正方形不是正方形呢??
D3DXVECTOR3 vEyePt( 0.0f, 3.0f,-5.0f );//此时的坐标范围是什么??????????
D3DXVECTOR3 vLookatPt( 0.0f, 0.0f, 0.0f );

D3D我不懂。
我只会一点OpenGL。

你的摄像机坐标是(0.0,3.0,-5.0),
而你的模型坐标是(0.0,0.0,0.0)。
说明你是从高处往下看的,而不是正面看的。
不是正方形,不是很正常吗?

6

主题

16

帖子

16

积分

新手上路

Rank: 1

积分
16
 楼主| 发表于 2010-3-28 21:01:00 | 显示全部楼层

Re:为什么我画的正方形不是正方形呢??

恩,谢谢,正是这个问题!
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

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

GMT+8, 2025-6-10 10:34

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

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