首页新闻找找看学习计划

directx中如何让纹理刚好和窗口一样大显示?

0
悬赏园豆:20 [待解决问题]
//=============================================================================
// Desc: 最简单的Direct3D程序,
//=============================================================================
#include <d3d9.h>
#pragma comment(lib,"d3d9.lib")
#include <d3dx9.h>
#pragma comment(lib,"d3dx9.lib")
#include <tchar.h>
//-----------------------------------------------------------------------------
// 全局变量
//-----------------------------------------------------------------------------
LPDIRECT3D9             g_pD3D       = NULL;  //Direct3D对象
LPDIRECT3DDEVICE9       g_pd3dDevice = NULL;  //Direct3D设备对象
LPDIRECT3DVERTEXBUFFER9 g_pd3dVerText1 = NULL; //顶点缓冲区
LPDIRECT3DVERTEXBUFFER9 g_pd3dVerText2 = NULL; //顶点缓冲区
LPDIRECT3DTEXTURE9    g_pd3dTexture1 = NULL;
LPDIRECT3DTEXTURE9    g_pd3dTexture2 = NULL;
int g_nRotateY = 0;    //实体的旋转角度
UINT_PTR g_nTimer = 0;
//定义FVF的顶点结构
struct CUSTOMVERTEXT
{
float x,y,z; //顶点坐标
float u,v;    //纹理
};
//d定义FVF用到的数据项:坐标,颜色
#define D3DFVF_CUSTOMVERTEXT (D3DFVF_XYZ | D3DFVF_TEX1)
//该函数用于设置旋转矩阵
void SetupMatrices()
{
float angle = g_nRotateY*D3DX_PI/180; //把旋转角度换算成弧度
D3DXMATRIX matWorld;
//计算世界变化矩阵
D3DXMatrixRotationY(&matWorld,angle);

//把世界变换矩阵设置到渲染环境
g_pd3dDevice->SetTransform(D3DTS_WORLD,&matWorld);

D3DXVECTOR3 eye(0.0f,0.0f,-4.0f);    //观察点
D3DXVECTOR3 lookat(0.0f,0.0f,0.0f); //视线目标点
D3DXVECTOR3 up(0.0f,1.0f,0.0f);        //上方向
D3DXMATRIX matView;
//计算视角变换矩阵
D3DXMatrixLookAtLH(&matView,&eye,&lookat,&up);
//把视角变换矩阵设置到渲染环境
g_pd3dDevice->SetTransform(D3DTS_VIEW,&matView);

D3DXMATRIXA16 matProj;
//计算透视投影变换矩阵
D3DXMatrixPerspectiveFovLH(&matProj,D3DX_PI/4,1.0f,1.0f,100.0f);
//把投影变换矩阵设置到渲染环境
g_pd3dDevice->SetTransform(D3DTS_PROJECTION,&matProj);
}
//-----------------------------------------------------------------------------
// 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;
d3dpp.MultiSampleType = D3DMULTISAMPLE_8_SAMPLES;
//创建Direct3D设备对象
if( FAILED( g_pD3D->CreateDevice( D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hWnd,
                                  D3DCREATE_SOFTWARE_VERTEXPROCESSING,
                                  &d3dpp, &g_pd3dDevice ) ) )
{
    return E_FAIL;
}
//因为使用顶点颜色渲染,所以要禁用光照
g_pd3dDevice->SetRenderState(D3DRS_LIGHTING,FALSE);
//关闭挑选功能,允许渲染背面
//g_pd3dDevice->SetRenderState(D3DRS_CULLMODE,D3DCULL_NONE);

g_pd3dDevice->SetSamplerState(0,D3DSAMP_MAGFILTER,D3DTEXF_ANISOTROPIC);
g_pd3dDevice->SetSamplerState(0,D3DSAMP_MINFILTER,D3DTEXF_ANISOTROPIC);

g_pd3dDevice->SetRenderState(D3DRS_MULTISAMPLEANTIALIAS, TRUE);
return S_OK;
}

//建模
HRESULT BuildModel1()
{
//三角形尸体的数值模型
CUSTOMVERTEXT vertices[] = 
{
    //正面
    { -1.0f, -1.0f, 0.0f, 0.0f,1.0f},  // 点A,红色 
    { -1.0f, 1.0f, 0.0f, 0.0f,0.0f}, //点B ,绿色 
    {  1.0f, 1.0f, 0.0f, 1.0f,0.0f},
    {  1.0f, -1.0f, 0.0f, 1.0f,1.0f}
};//点C,浅蓝

//创建顶点缓冲区
if (FAILED(    g_pd3dDevice->CreateVertexBuffer(
    sizeof(vertices), //缓冲区尺寸
0,D3DFVF_CUSTOMVERTEXT,D3DPOOL_DEFAULT,&g_pd3dVerText1,NULL)))
{
    return E_FAIL;
}
//将顶点数据填入顶点缓冲区
void* pVertices;
if (FAILED(g_pd3dVerText1->Lock(0,sizeof(vertices),(void**)&pVertices,0)))
{
    return E_FAIL;
}
memcpy(pVertices,vertices,sizeof(vertices));
g_pd3dVerText1->Unlock();

if (FAILED(D3DXCreateTextureFromFile(g_pd3dDevice,_T("z.png"),&g_pd3dTexture1)))
{
    return E_FAIL;
}
return S_OK;
}

HRESULT BuildModel2()
{
//三角形尸体的数值模型
CUSTOMVERTEXT vertices[] = 
{
    //正面
    { -1.0f, -1.0f, 0.0f,1.0f,1.0f},  // 点A,红色 
    { 1.0f, -1.0f, 0.0f,0.0f,1.0f},   //点B ,绿色 
    {  1.0f, 1.0f, 0.0f,0.0f,0.0f},
    {  -1.0f, 1.0f, 0.0f,1.0f,0.0f}
};//点C,浅蓝

//创建顶点缓冲区
if (FAILED(    g_pd3dDevice->CreateVertexBuffer(
    sizeof(vertices), //缓冲区尺寸
0,D3DFVF_CUSTOMVERTEXT,
    D3DPOOL_DEFAULT,
    &g_pd3dVerText2,NULL)))
{
    return E_FAIL;
}
//将顶点数据填入顶点缓冲区
void* pVertices;
if (FAILED(g_pd3dVerText2->Lock(0,sizeof(vertices),(void**)&pVertices,0)))
{
    return E_FAIL;
}
memcpy(pVertices,vertices,sizeof(vertices));
g_pd3dVerText2->Unlock();
if (FAILED(D3DXCreateTextureFromFile(g_pd3dDevice,_T("f.png"),&g_pd3dTexture2)))
{
    return E_FAIL;
}
return S_OK;
}


//-----------------------------------------------------------------------------
// Desc: 释放创建对象
//-----------------------------------------------------------------------------
VOID Cleanup()
{
if (g_pd3dTexture1 != NULL)
    g_pd3dTexture1->Release();

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

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

if (g_pd3dVerText2 != NULL)
    g_pd3dVerText2->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(255,255,255), 1.0f, 0 );

//开始在后台缓冲区绘制图形
if( SUCCEEDED( g_pd3dDevice->BeginScene() ) )
{
    //在此在后台缓冲区绘制图形
    SetupMatrices(); 
    //设置自定义的FVF
    g_pd3dDevice->SetFVF(D3DFVF_CUSTOMVERTEXT);

    g_pd3dDevice->SetStreamSource(0,g_pd3dVerText2,0,sizeof(CUSTOMVERTEXT));
    g_pd3dDevice->SetTexture(0,g_pd3dTexture2);
    g_pd3dDevice->DrawPrimitive(D3DPT_TRIANGLEFAN,0,2);        

    g_pd3dDevice->SetStreamSource(0,g_pd3dVerText1,0,sizeof(CUSTOMVERTEXT));
    g_pd3dDevice->SetTexture(0,g_pd3dTexture1);
    g_pd3dDevice->DrawPrimitive(D3DPT_TRIANGLEFAN,0,2);


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

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

//

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

    case WM_PAINT:
        {
            Render();
            ValidateRect( hWnd, NULL );
            return 0;
        }
    case WM_CREATE:
        {
            g_nTimer = SetTimer(hWnd,1,40,NULL);
        }break;
    case WM_TIMER:
        {
            g_nRotateY += 2; //每次旋转2度
            InvalidateRect(hWnd,NULL,TRUE);
            UpdateWindow(hWnd);
        }break;
}

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"最简单的Direct3D程序", 
                          WS_OVERLAPPEDWINDOW, 200, 100, 600, 500,
                          NULL, NULL, wc.hInstance, NULL );

//初始化Direct3D
if( SUCCEEDED( InitD3D( hWnd ) ) && SUCCEEDED(BuildModel1()) && SUCCEEDED(BuildModel2()))
{ 
    //显示主窗口
    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;
}

 

上面已经实现了纹理正反面贴不同的图(图你随便找两张一样大的就行了).

现在的问题是: 我如何调整观察点(上面代码处有注释)让显示的图片刚好显示的和窗口一样大小? 貌似这个值要么调的过大,要么过小, d3d的书上好像都没将这个, 都是设置一个值, 没有解释

 

likebeta的主页 likebeta | 初学一级 | 园豆:179
提问于:2012-08-23 18:53
< >
分享
所有回答(2)
0

没什么办法,只能一点点试,要么就设置一个camera,往前移动,等到纹理和窗口同大时,计算一下视点的位置就行了。

翰墨小生 | 园豆:51 (初学一级) | 2012-08-25 11:15
0

使用屏幕空间的四边形来绘制纹理,可以搜索一本叫<d3d中的2d编程>的书籍。

D3D也提供了D3DXSprite这个对象来绘制2D图形,使用的都是屏幕坐标系(像素坐标),用起来和一般的绘图很像。

或者也使用正交投影,将投影区域的宽度和高度设为窗口大小。

秋天的栗树 | 园豆:216 (菜鸟二级) | 2012-08-28 20:03
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册