D3D 纹理 例子程序
程序目的
将纹理图片显示到图元表面。
程序实现
#pragma once
#pragma comment(lib,"winmm.lib")
#pragma comment(lib,"d3d9.lib")
#pragma comment(lib,"d3dx9.lib")
#include<d3d9.h>
#include<d3dx9.h>
struct CUSTOMVERTEX
{
D3DXVECTOR3 position;
FLOAT tu;
FLOAT tv;
};
#define D3DFVF_CUSTOMVERTEX (D3DFVF_XYZ|D3DFVF_TEX1)
LRESULT CALLBACK MsgProc(
HWND hWnd,
UINT msg,
WPARAM wParam,
LPARAM lParam);
HRESULT Init(HWND hWnd);
HRESULT InitD3D(HWND hWnd);
HRESULT InitGeometry();
void SetUpMatrices();
void SetUpTextures();
void Render();
void CleanUp();
//global variables.
LPDIRECT3D9 pd3d9=NULL;
LPDIRECT3DDEVICE9 pd3dDevice9=NULL;
LPDIRECT3DVERTEXBUFFER9 pd3dVB=NULL;
LPDIRECT3DTEXTURE9 pd3dTexture=NULL;
INT WINAPI wWinMain(
HINSTANCE,
HINSTANCE,
LPWSTR,
INT)
{
//wnd class.
WNDCLASSEX wcex;
ZeroMemory(&wcex,sizeof(wcex));
wcex.cbSize=sizeof(wcex);
wcex.hInstance=GetModuleHandle(NULL);
wcex.lpfnWndProc=MsgProc;
wcex.lpszClassName=L"DXTextures";
wcex.style=CS_CLASSDC;
//register class.
RegisterClassEx(&wcex);
//create window.
HWND hWnd=CreateWindowEx(
WS_EX_OVERLAPPEDWINDOW,
L"DXTextures",
L"DXTextures Window",
WS_OVERLAPPEDWINDOW,
100,
100,
300,
300,
NULL,
NULL,
wcex.hInstance,
NULL);
//show window.
ShowWindow(hWnd,SW_SHOWDEFAULT);
UpdateWindow(hWnd);
//init global variables.
if(FAILED(Init(hWnd)))
{
return -1;
}
//message loop
MSG msg;
ZeroMemory(&msg,sizeof(msg));
while(msg.message != WM_QUIT)
{
if(PeekMessage(&msg,hWnd,0,0,PM_REMOVE))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
else
{
Render();
}
}
return 0;
}
LRESULT CALLBACK 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);
}
void Render()
{
pd3dDevice9->Clear(
0,
NULL,
D3DCLEAR_TARGET|D3DCLEAR_ZBUFFER,
D3DCOLOR_XRGB(0,0,255),
1.0f,
0);
if(SUCCEEDED(pd3dDevice9->BeginScene()))
{
SetUpMatrices();
SetUpTextures();
pd3dDevice9->SetStreamSource( 0, pd3dVB, 0, sizeof( CUSTOMVERTEX ) );
pd3dDevice9->SetFVF( D3DFVF_CUSTOMVERTEX );
pd3dDevice9->DrawPrimitive( D3DPT_TRIANGLESTRIP, 0, 2 * 50 - 2 );
pd3dDevice9->EndScene();
}
pd3dDevice9->Present(NULL,NULL,NULL,NULL);
}
HRESULT InitD3D(HWND hWnd)
{
//create d3d.
pd3d9=Direct3DCreate9(D3D_SDK_VERSION);
if(pd3d9 == NULL)
{
return E_FAIL;
}
//init present param.
D3DPRESENT_PARAMETERS d3dpp;
ZeroMemory(&d3dpp,sizeof(d3dpp));
d3dpp.Windowed=TRUE;
d3dpp.BackBufferFormat=D3DFMT_UNKNOWN;
d3dpp.SwapEffect=D3DSWAPEFFECT_DISCARD;
d3dpp.EnableAutoDepthStencil=TRUE;
d3dpp.AutoDepthStencilFormat=D3DFMT_D16;
//create device.
if(FAILED(pd3d9->CreateDevice(
D3DADAPTER_DEFAULT,
D3DDEVTYPE_HAL,
hWnd,
D3DCREATE_SOFTWARE_VERTEXPROCESSING,
&d3dpp,
&pd3dDevice9)))
{
return E_FAIL;
}
return S_OK;
}
void CleanUp()
{
if(pd3dVB != NULL)
{
pd3dVB->Release();
pd3dVB=NULL;
}
if(pd3dDevice9 != NULL)
{
pd3dDevice9->Release();
pd3dDevice9=NULL;
}
if(pd3d9 != NULL)
{
pd3d9->Release();
pd3d9=NULL;
}
}
void SetUpMatrices()
{
//world matrix.
D3DXMATRIXA16 worldMat;
D3DXMatrixIdentity(&worldMat);
D3DXMatrixRotationY(&worldMat,timeGetTime()/1000.0f);
pd3dDevice9->SetTransform(D3DTS_WORLD,&worldMat);
//view matrix.
D3DXMATRIXA16 viewMat;
D3DXVECTOR3 vEye(0.0f,2.0f,-5.0f);
D3DXVECTOR3 vLookAt(0.0f,0.0f,0.0f);
D3DXVECTOR3 vUp(0.0f,1.0f,0.0f);
D3DXMatrixLookAtLH(&viewMat,&vEye,&vLookAt,&vUp);
pd3dDevice9->SetTransform(D3DTS_VIEW,&viewMat);
//projection matrix.
D3DXMATRIXA16 projMat;
D3DXMatrixPerspectiveFovLH(&projMat,D3DX_PI/4,1.0f,1.0f,1000.0f);
pd3dDevice9->SetTransform(D3DTS_PROJECTION,&projMat);
}
HRESULT InitGeometry()
{
//create texture.
if(FAILED(D3DXCreateTextureFromFile(
pd3dDevice9,
L"dxts.jpg",
&pd3dTexture)))
{
return E_FAIL;
}
//create vertex buffer.
if(FAILED(pd3dDevice9->CreateVertexBuffer(
50*2*sizeof(CUSTOMVERTEX),
0,
D3DFVF_CUSTOMVERTEX,
D3DPOOL_DEFAULT,
&pd3dVB,
NULL)))
{
return E_FAIL;
}
//assgin value.
CUSTOMVERTEX* pVertices;
if(FAILED(pd3dVB->Lock(
0,
50*2*sizeof(CUSTOMVERTEX),
(void**)&pVertices,
0)))
{
return E_FAIL;
}
for( DWORD i = 0; i < 50; i++ )
{
FLOAT theta = ( 2 * D3DX_PI * i ) / ( 50 - 1 );
pVertices[2 * i + 0].position = D3DXVECTOR3( cosf( theta ), -1.0f, sinf( theta ) );
pVertices[2 * i + 0].tu=(2*(FLOAT)i)/49.0f;
pVertices[2 * i + 0].tv=1.0f;
pVertices[2 * i + 1].position = D3DXVECTOR3( cosf( theta ), 1.0f, sinf( theta ) );
pVertices[2 * i + 1].tu=(2*(FLOAT)i)/49.0f;
pVertices[2 * i + 1].tv=0.0f;
}
pd3dVB->Unlock();
// Turn off culling
pd3dDevice9->SetRenderState( D3DRS_CULLMODE, D3DCULL_NONE );
// Turn off D3D lighting
pd3dDevice9->SetRenderState( D3DRS_LIGHTING, FALSE );
// Turn on the zbuffer
pd3dDevice9->SetRenderState( D3DRS_ZENABLE, TRUE );
return S_OK;
}
void SetUpTextures()
{
pd3dDevice9->SetTexture(0,pd3dTexture);
}
HRESULT Init(HWND hWnd)
{
if(FAILED(InitD3D(hWnd)))
{
return E_FAIL;
}
if(FAILED(InitGeometry()))
{
return E_FAIL;
}
return S_OK;
}
程序结果
总结
1.d3d学习至今,纹理卡的时间最长,里面涉及的参数太多。现在也不是很懂。
2.d3d大约的流程是:声明一种特性,特性初始化,设置这种特性,使用这种特性。
3.如果想运行这个程序,将DX路径配置好,寻找一个图片,大小2的幂数,修改名字为dxts.jpg加载到工程就可以运行了。
4.学习d3d看来是需要有知识基础的,数学里面的空间与几何是需要的,后面还将会用到矩阵,路漫漫...
5.上周去面试发现这些都没有什么用,唉,等到什么程度才能真的顶用呢?