作者在 2011-02-12 16:25:55 发布以下内容
//*通过3个顶点来渲染一个2D的三角形,介绍顶点缓冲器的概念,缓冲器是Direct3D用来存储并渲染顶点的一个
对象,需要特定的一个结构体来定义这个顶点,和相应的a custom FVF (flexible vertex format)
然后还得为顶点缓冲区里的数据定义格式,这样:
自定义顶点结构体:
struct CUSTOMVERTEX
{
FLOAT x, y, z, rhw; // The transformed position for the vertex.
DWORD color; // The vertex color.
};
根据我们自定义顶点结构定义FVF,以保证以上的顶点能定义能够创建
FVF(Flexible Vertex Format) 是Direct3d中的可变顶点格式,通过它可以定义三角形的顶点格式,
然后通过创建顶点缓冲区并设置渲染源来显示基本的图形。
D3DFVF_XYZ和D3DFVF_XYZRHW的区别是:
1.D3DXYZ默认的坐标系统用户区中心是 (0,0) 而rhw的左上角是 (0,0)
2.D3DXYZ默认的非光照的,而RHW默认就是高洛夫的光照模式。
在 RHW下需要设置
#define FVF_XYZ (D3DFVF_XYZ | D3DFVF_DIFFUSE)
g_pd3dDevice->SetRenderState(D3DRS_LIGHTING,FALSE)
#define D3DFVF_CUSTOMVERTEX (D3DFVF_XYZRHW|D3DFVF_DIFFUSE)
D3DFVF_D3DFVF_XYZRHW : 表示顶点坐标
D3DFVF_DIFFUSE : 表示顶点有颜色
告诉渲染器这个自定义的点由一个转化的点伴随着一个颜色组成。
they are already in 2D window coordinates.
This means that the point (0,0) is at the top left corner and the positive x-axis
is right and the positive y-axis is down. These vertices are also lit,
meaning that they are not using Direct3D lighting but are supplying their own color.
*/
#include <d3d9.h>
#pragma comment(lib,"d3d9.lib")
LPDIRECT3D9 g_pD3D = NULL;//创建D3D设备
LPDIRECT3DDEVICE9 g_pd3dDevice = NULL;//我们的渲染设备
LPDIRECT3DVERTEXBUFFER9 g_pVB = NULL; //存放顶点的容器
struct CUSTOMVERTEX
{
FLOAT x,y,z,rhw;
DWORD color;
};
#define D3DFVF_CUSTOMVERTEX (D3DFVF_XYZRHW|D3DFVF_DIFFUSE)
HRESULT InitD3D(HWND hWnd)
{
if(NULL==(g_pD3D=Direct3DCreate9(D3D_SDK_VERSION)))
{
return E_FAIL;
}
D3DPRESENT_PARAMETERS d3ddp ;
/*
D3DPRESENT_PARAMETERS结构体:
BackBufferWidth:全屏幕式后备缓冲的宽度
BackBufferHeight :全屏幕式后备缓冲的高度
BackBufferFormat: 后备缓冲的格式
BackBufferCount: 后备缓冲数目
MultiSampleType: 全屏抗锯齿类型
MultiSampleQuality: 全屏抗锯齿质量等级
SwapEffect: 交换缓冲类型
hDeviceWindow: 设备窗口句柄
Windowed: 全屏或窗口
EnableAutoDepthStencil: 激活深度缓冲
AutoDepthStencilFormat: 深度缓冲格式
FullScreen_RefreshRateInHz: 显示器刷新率
PresentationInterval: 图像最大刷新速度 */
ZeroMemory(&d3ddp,sizeof(d3ddp));// 给d3ddp分配一段内存
d3ddp.Windowed =TRUE ;//TRUE if the application runs windowed; FALSE if the application runs full-screen.
d3ddp.SwapEffect = D3DSWAPEFFECT_DISCARD;
d3ddp.BackBufferFormat = D3DFMT_UNKNOWN;D3DFMT_UNKNOWN;//可以指定为BackBufferFormat而在窗口模式。这告诉运行时使用当前的显示模式格式,无需调用
if (FAILED(g_pD3D->CreateDevice(D3DADAPTER_DEFAULT,
D3DDEVTYPE_HAL,
hWnd,
D3DCREATE_SOFTWARE_VERTEXPROCESSING,
&d3ddp,
&g_pd3dDevice)))
{
return E_FAIL;
}/*IDirect3D9::CreateDevice(UINT Adapter, D3DDEVTYPE DeviceType,
HWND hFocusWindow, DWORD BehaviorFlags,
D3DPRESENT_PARAMETERS *pPresentationParameters,
IDirect3DDevice9 **ppReturnedDeviceInterface)*/
return S_OK;
}
HRESULT InitGeometry()
{
CUSTOMVERTEX Vertices[]=
{
{ 150.0f, 50.0f, 0.5f, 1.0f, 0xffff0000, }, // x, y, z, rhw, color
{ 250.0f, 250.0f, 0.5f, 1.0f, 0xff00ff00, },
{ 50.0f, 250.0f, 0.5f, 1.0f, 0xff00ffff, },
};
if( FAILED( g_pd3dDevice->CreateVertexBuffer(4*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();
}
VOID Cleanup()
{
if (g_pVB !=NULL)
{
g_pVB->Release();
}
if (g_pd3dDevice !=NULL)
{
g_pd3dDevice->Release();
}
if (g_pD3D!=NULL)
{
g_pD3D ->Release();
}
}
VOID Render()
{
g_pd3dDevice->Clear(0,NULL,D3DCLEAR_TARGET,D3DCOLOR_XRGB(0,0,255),1.0f,0L);//
if(SUCCEEDED(g_pd3dDevice->BeginScene()))
{
//g_pd3dDevice->SetStreamSource(0,g_pVB,0,sizeof(CUSTOMVERTEX));
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->Present(NULL,NULL,NULL,NULL);
}
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);
}
INT WINAPI WinMain( HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nShowCmd )
{
WNDCLASSEX wcex;
wcex.cbSize =sizeof(WNDCLASSEX);
wcex.cbClsExtra = 0L;
wcex.cbWndExtra = 0L;
wcex.hbrBackground = NULL;
wcex.hCursor = NULL;
wcex.hIcon =NULL;
wcex.hIconSm =NULL;
wcex.lpfnWndProc =MsgProc;
wcex.lpszClassName =L"D3D";
wcex.lpszMenuName = NULL;
wcex.style =CS_CLASSDC;
wcex.hInstance = hInstance;//( NULL );
RegisterClassEx(&wcex);
HWND hWnd;
hWnd = CreateWindow(L"D3D",L"HHAH",WS_OVERLAPPEDWINDOW,100,100,300,300,
NULL,NULL,wcex.hInstance,NULL);
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"D3D",wcex.hInstance);
return 0;
}
对象,需要特定的一个结构体来定义这个顶点,和相应的a custom FVF (flexible vertex format)
然后还得为顶点缓冲区里的数据定义格式,这样:
自定义顶点结构体:
struct CUSTOMVERTEX
{
FLOAT x, y, z, rhw; // The transformed position for the vertex.
DWORD color; // The vertex color.
};
根据我们自定义顶点结构定义FVF,以保证以上的顶点能定义能够创建
FVF(Flexible Vertex Format) 是Direct3d中的可变顶点格式,通过它可以定义三角形的顶点格式,
然后通过创建顶点缓冲区并设置渲染源来显示基本的图形。
D3DFVF_XYZ和D3DFVF_XYZRHW的区别是:
1.D3DXYZ默认的坐标系统用户区中心是 (0,0) 而rhw的左上角是 (0,0)
2.D3DXYZ默认的非光照的,而RHW默认就是高洛夫的光照模式。
在 RHW下需要设置
#define FVF_XYZ (D3DFVF_XYZ | D3DFVF_DIFFUSE)
g_pd3dDevice->SetRenderState(D3DRS_LIGHTING,FALSE)
#define D3DFVF_CUSTOMVERTEX (D3DFVF_XYZRHW|D3DFVF_DIFFUSE)
D3DFVF_D3DFVF_XYZRHW : 表示顶点坐标
D3DFVF_DIFFUSE : 表示顶点有颜色
告诉渲染器这个自定义的点由一个转化的点伴随着一个颜色组成。
they are already in 2D window coordinates.
This means that the point (0,0) is at the top left corner and the positive x-axis
is right and the positive y-axis is down. These vertices are also lit,
meaning that they are not using Direct3D lighting but are supplying their own color.
*/
#include <d3d9.h>
#pragma comment(lib,"d3d9.lib")
LPDIRECT3D9 g_pD3D = NULL;//创建D3D设备
LPDIRECT3DDEVICE9 g_pd3dDevice = NULL;//我们的渲染设备
LPDIRECT3DVERTEXBUFFER9 g_pVB = NULL; //存放顶点的容器
struct CUSTOMVERTEX
{
FLOAT x,y,z,rhw;
DWORD color;
};
#define D3DFVF_CUSTOMVERTEX (D3DFVF_XYZRHW|D3DFVF_DIFFUSE)
HRESULT InitD3D(HWND hWnd)
{
if(NULL==(g_pD3D=Direct3DCreate9(D3D_SDK_VERSION)))
{
return E_FAIL;
}
D3DPRESENT_PARAMETERS d3ddp ;
/*
D3DPRESENT_PARAMETERS结构体:
BackBufferWidth:全屏幕式后备缓冲的宽度
BackBufferHeight :全屏幕式后备缓冲的高度
BackBufferFormat: 后备缓冲的格式
BackBufferCount: 后备缓冲数目
MultiSampleType: 全屏抗锯齿类型
MultiSampleQuality: 全屏抗锯齿质量等级
SwapEffect: 交换缓冲类型
hDeviceWindow: 设备窗口句柄
Windowed: 全屏或窗口
EnableAutoDepthStencil: 激活深度缓冲
AutoDepthStencilFormat: 深度缓冲格式
FullScreen_RefreshRateInHz: 显示器刷新率
PresentationInterval: 图像最大刷新速度 */
ZeroMemory(&d3ddp,sizeof(d3ddp));// 给d3ddp分配一段内存
d3ddp.Windowed =TRUE ;//TRUE if the application runs windowed; FALSE if the application runs full-screen.
d3ddp.SwapEffect = D3DSWAPEFFECT_DISCARD;
d3ddp.BackBufferFormat = D3DFMT_UNKNOWN;D3DFMT_UNKNOWN;//可以指定为BackBufferFormat而在窗口模式。这告诉运行时使用当前的显示模式格式,无需调用
if (FAILED(g_pD3D->CreateDevice(D3DADAPTER_DEFAULT,
D3DDEVTYPE_HAL,
hWnd,
D3DCREATE_SOFTWARE_VERTEXPROCESSING,
&d3ddp,
&g_pd3dDevice)))
{
return E_FAIL;
}/*IDirect3D9::CreateDevice(UINT Adapter, D3DDEVTYPE DeviceType,
HWND hFocusWindow, DWORD BehaviorFlags,
D3DPRESENT_PARAMETERS *pPresentationParameters,
IDirect3DDevice9 **ppReturnedDeviceInterface)*/
return S_OK;
}
HRESULT InitGeometry()
{
CUSTOMVERTEX Vertices[]=
{
{ 150.0f, 50.0f, 0.5f, 1.0f, 0xffff0000, }, // x, y, z, rhw, color
{ 250.0f, 250.0f, 0.5f, 1.0f, 0xff00ff00, },
{ 50.0f, 250.0f, 0.5f, 1.0f, 0xff00ffff, },
};
if( FAILED( g_pd3dDevice->CreateVertexBuffer(4*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();
}
VOID Cleanup()
{
if (g_pVB !=NULL)
{
g_pVB->Release();
}
if (g_pd3dDevice !=NULL)
{
g_pd3dDevice->Release();
}
if (g_pD3D!=NULL)
{
g_pD3D ->Release();
}
}
VOID Render()
{
g_pd3dDevice->Clear(0,NULL,D3DCLEAR_TARGET,D3DCOLOR_XRGB(0,0,255),1.0f,0L);//
if(SUCCEEDED(g_pd3dDevice->BeginScene()))
{
//g_pd3dDevice->SetStreamSource(0,g_pVB,0,sizeof(CUSTOMVERTEX));
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->Present(NULL,NULL,NULL,NULL);
}
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);
}
INT WINAPI WinMain( HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nShowCmd )
{
WNDCLASSEX wcex;
wcex.cbSize =sizeof(WNDCLASSEX);
wcex.cbClsExtra = 0L;
wcex.cbWndExtra = 0L;
wcex.hbrBackground = NULL;
wcex.hCursor = NULL;
wcex.hIcon =NULL;
wcex.hIconSm =NULL;
wcex.lpfnWndProc =MsgProc;
wcex.lpszClassName =L"D3D";
wcex.lpszMenuName = NULL;
wcex.style =CS_CLASSDC;
wcex.hInstance = hInstance;//( NULL );
RegisterClassEx(&wcex);
HWND hWnd;
hWnd = CreateWindow(L"D3D",L"HHAH",WS_OVERLAPPEDWINDOW,100,100,300,300,
NULL,NULL,wcex.hInstance,NULL);
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"D3D",wcex.hInstance);
return 0;
}