游戏开发论坛

 找回密码
 立即注册
搜索
查看: 9007|回复: 15

关于directx中坐标系的问题!!

[复制链接]

6

主题

16

帖子

16

积分

新手上路

Rank: 1

积分
16
发表于 2010-3-18 22:23:00 | 显示全部楼层 |阅读模式
各位大侠,我对directx里坐标系不是很明白,希望给位能不吝赐教,先谢过了!

比如说:我创建的窗口大小是600*600的,为什么在画三角形最后一个点的时候“{ 600.0f, 600.0f, 0.0f, 1.0f, 0xff0000ff,}”却没有在预想的位置呢?按理说应该是刚好显示在右下角了,为什么画出来的情况却不是呢?我觉得很纳闷,希望大侠们能帮我解决这个问题!


//创建窗口
    HWND hWnd = CreateWindow( L"ClassName", L"最简单的Direct3D程序",
                              WS_OVERLAPPEDWINDOW, 0, 0, 600, 600,
                              NULL, NULL, wc.hInstance, NULL );
而我在
HRESULT InitVB()
{
        //顶点数据
    CUSTOMVERTEX vertices[] =
    {
                { 0.0f, 0.0f, 0.0f, 1.0f, 0xffff0000, },
                { 600.0f,  0.0f, 0.0f, 1.0f, 0xff0000ff, },
                     { 600.0f, 600.0f, 0.0f, 1.0f, 0xff0000ff, },
    };

}

3

主题

27

帖子

27

积分

注册会员

Rank: 2

积分
27
发表于 2010-3-19 10:44:00 | 显示全部楼层

Re: 关于directx中坐标系的问题!!

DX使用的是左手坐标系
{ 600.0f, 600.0f, 0.0f, 1.0f, 0xff0000ff,}是逻辑坐标 ,窗体客户区是设备坐标

(0.0f,0.0f,0.0f)经过视口转换后会映射屏幕的中心位置

如果你想要直接使用设备坐标的话,需要使用SetFVF(D3DFVF_XYZRHW),来告诉DX顶点的坐标不需要转换。


1

主题

266

帖子

280

积分

中级会员

Rank: 3Rank: 3

积分
280
发表于 2010-3-19 11:26:00 | 显示全部楼层

Re:关于directx中坐标系的问题!!

你的顶点格式是怎么定义的?

6

主题

16

帖子

16

积分

新手上路

Rank: 1

积分
16
 楼主| 发表于 2010-3-19 15:26:00 | 显示全部楼层

Re:关于directx中坐标系的问题!!

我是刚刚开始学的,所以不是很清楚,那我把代码给出来吧,希望你们能帮我看一下,谢谢!

//=============================================================================
// Desc: 使用顶点缓冲区绘制三角形
//=============================================================================

#include <d3d9.h>


//-----------------------------------------------------------------------------
// Desc: 全局变量
//-----------------------------------------------------------------------------
LPDIRECT3D9             g_pD3D       = NULL;    //Direct3D对象
LPDIRECT3DDEVICE9       g_pd3dDevice = NULL;    //Direct3D设备对象
LPDIRECT3DVERTEXBUFFER9 g_pVB        = NULL;    //顶点缓冲区对象


//-----------------------------------------------------------------------------
// Desc: 顶点结构
//-----------------------------------------------------------------------------
struct CUSTOMVERTEX
{
    FLOAT x, y, z, rhw;
    DWORD color;
};
#define D3DFVF_CUSTOMVERTEX (D3DFVF_XYZRHW|D3DFVF_DIFFUSE)  //顶点格式


//-----------------------------------------------------------------------------
// 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;
    }

    return S_OK;
}


//-----------------------------------------------------------------------------
// Desc: 创建并填充顶点缓冲区  ???????????三角形的顶点顺序要求是顺时针的吗???
//-----------------------------------------------------------------------------
HRESULT InitVB()
{
        //顶点数据
    CUSTOMVERTEX vertices[] =
    {
                { 0.0f, 0.0f, 0.0f, 1.0f, 0xffff0000, },
                { 600.0f,  0.0f, 0.0f, 1.0f, 0xff0000ff, },
        { 600.0f, 600.0f, 0.0f, 1.0f, 0xff0000ff, },
    };

        //创建顶点缓冲区
    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(vertices), (void**)&pVertices, 0 ) ) )
        return E_FAIL;
    memcpy( pVertices, vertices, sizeof(vertices) );
    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(0, 0, 10), 1.0f, 0 );

        //开始在后台缓冲区绘制图形
    if( SUCCEEDED( g_pd3dDevice->BeginScene() ) )
    {
                //在后台缓冲区绘制图形
        g_pd3dDevice->SetStreamSource( 0, g_pVB, 0, sizeof(CUSTOMVERTEX) );
        g_pd3dDevice->SetFVF( D3DFVF_CUSTOMVERTEX );
                g_pd3dDevice->DrawPrimitive( D3DPT_TRIANGLELIST, 0, 1 );

                //结束在后台缓冲区绘制图形
        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, 0, 0, 610, 630,
                              GetDesktopWindow(), 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 )
            {
                if( PeekMessage( &msg, NULL, 0U, 0U, PM_REMOVE ) )  //peekmessage()时调用API来检查消息队列,看某一消息是否到来
                {
                    TranslateMessage(&msg);   //此函数负责将消息的虚拟键转换为字符信息
                    DispatchMessage(&msg);    //此函数最终将消息传送到指定的串口过程中
                }
                else
                                {
                    Render();  //渲染图形
                                }
            }
        }
    }

    UnregisterClass(L"ClassName", wc.hInstance);
    return 0;
}

34

主题

657

帖子

672

积分

高级会员

Rank: 4

积分
672
发表于 2010-3-19 21:15:00 | 显示全部楼层

Re:关于directx中坐标系的问题!!

应该是显示在右上角吧,试着将z坐标改为1试试。

7

主题

55

帖子

55

积分

注册会员

Rank: 2

积分
55
发表于 2010-3-19 21:36:00 | 显示全部楼层

Re:关于directx中坐标系的问题!!

应该是显示在右上角吧。

1

主题

266

帖子

280

积分

中级会员

Rank: 3Rank: 3

积分
280
发表于 2010-3-19 23:17:00 | 显示全部楼层

Re:关于directx中坐标系的问题!!

恩 看了你的定义:
{ 0.0f, 0.0f, 0.0f, 1.0f, 0xffff0000, },   应该在左上角
{ 600.0f,  0.0f, 0.0f, 1.0f, 0xff0000ff, },   在右上角
{ 600.0f, 600.0f, 0.0f, 1.0f, 0xff0000ff},   在右下角
是么?  你是想实现这个效果么?   我想知道你现在看到的显示是什么情况?

还有你确定你的窗口大小是600*600么?
看你的这个函数HWND hWnd = CreateWindow( L"ClassName", L"最简单的Direct3D程序",
                              WS_OVERLAPPEDWINDOW, 0, 0, 600, 600,
                              NULL, NULL, wc.hInstance, NULL );
你的窗口大小可不是600*600啊。

6

主题

16

帖子

16

积分

新手上路

Rank: 1

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

Re:关于directx中坐标系的问题!!

恩,正是你所说的,我是想让窗口大小设置为600*600的,

为什么这个函数HWND hWnd = CreateWindow( L"ClassName", L"最简单的Direct3D程序",
                              WS_OVERLAPPEDWINDOW, 0, 0, 600, 600,
                              NULL, NULL, wc.hInstance, NULL );

不是设为600*600的呢?如果我想实现窗口大小为600*600的,那我应该如何实现呢?希望你能讲解得详细些好么?

显示的效果是,三角形的右下角没有完全显示,好像右上角和右下角都被窗口的最有边挡住了一部分,而且窗口的下边好像是向上移了,所以看到的结果就是右下角被砍掉似的。

说得简单点吧,打个比方:我的窗口是600*600的,画的三角形刚好是窗口的右上角的那个(如前面的点坐标),现在的效果是窗口好像长和宽都缩小为500*500了,这就是我在我机子上看到的效果。

我表达得不是很清楚,不知您是否能明白我的意思,希望你能帮助我,谢谢!!

2

主题

25

帖子

27

积分

注册会员

Rank: 2

积分
27
发表于 2010-3-21 21:02:00 | 显示全部楼层

Re:关于directx中坐标系的问题!!

我编译了,你的结果正常啊,就是在屏幕的右边的一个三角形...你说右下角是什么意思啊/?(0,0),(600,0)(600,600)这三个点组成的三角形不就是这样的么/?

2

主题

25

帖子

27

积分

注册会员

Rank: 2

积分
27
发表于 2010-3-21 21:08:00 | 显示全部楼层

Re:关于directx中坐标系的问题!!

哦,我明白了你的意思,你在创建窗口的时候指定的600*600是整个窗口的大小...而不是客户区的..
而DX是在你的客户区中绘制的..这么讲你明白了么/?
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

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

GMT+8, 2025-6-12 18:40

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

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