3. D3Dlines(+D3DFVF_XYZ和D3DFVF_XYZRHW的区别)

#include<d3d9.h>

#pragma comment(lib, "d3d9.lib")
#pragma comment(lib, "d3dx9.lib")

#define WINDOW_CLASS "UGPDX"
#define WINDOW_NAME "Drawing Lines"

// Function Prototypes...
bool InitializeD3D(HWND hWnd, bool fullscreen);
bool InitializeObjects();
void RenderScene();
void Shutdown();


// Direct3D object and device.
LPDIRECT3D9 g_D3D = NULL;
LPDIRECT3DDEVICE9 g_D3DDevice
= NULL;

// Vertex buffer to hold the geometry.
LPDIRECT3DVERTEXBUFFER9 g_VertexBuffer = NULL;


// A structure for our custom vertex type
struct stD3DVertex
{
float x, y, z, rhw;
unsigned
long color;
};

// Our custom FVF, which describes our custom vertex structure.
#define D3DFVF_VERTEX (D3DFVF_XYZRHW | D3DFVF_DIFFUSE)


LRESULT WINAPI MsgProc(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp)
{
switch(msg)
{
case WM_DESTROY:
PostQuitMessage(
0);
return 0;
break;

case WM_KEYUP:
if(wp == VK_ESCAPE) PostQuitMessage(0);
break;
}

return DefWindowProc(hWnd, msg, wp, lp);
}


int WINAPI WinMain(HINSTANCE hInst, HINSTANCE prevhInst,
LPSTR cmdLine,
int show)
{
// Register the window class
WNDCLASSEX wc = { sizeof(WNDCLASSEX), CS_CLASSDC, MsgProc,
0, 0, GetModuleHandle(NULL), NULL, NULL,
NULL, NULL, WINDOW_CLASS, NULL };
RegisterClassEx(
&wc);

// Create the application's window
HWND hWnd = CreateWindow(WINDOW_CLASS, WINDOW_NAME,
WS_OVERLAPPEDWINDOW,
100, 100,
640, 480, GetDesktopWindow(), NULL,
wc.hInstance, NULL);

// Initialize Direct3D
if(InitializeD3D(hWnd, false))
{
// Show the window
ShowWindow(hWnd, SW_SHOWDEFAULT);
UpdateWindow(hWnd);

// Enter the message loop
MSG msg;
ZeroMemory(
&msg, sizeof(msg));

while(msg.message != WM_QUIT)
{
if(PeekMessage(&msg, NULL, 0U, 0U, PM_REMOVE))
{
TranslateMessage(
&msg);
DispatchMessage(
&msg);
}
else
RenderScene();
}
}

// Release any and all resources.
Shutdown();

// Unregister our window.
UnregisterClass(WINDOW_CLASS, wc.hInstance);
return 0;
}

// 在该函数内调用initializeObjects()
bool InitializeD3D(HWND hWnd, bool fullscreen)
{
D3DDISPLAYMODE displayMode;

// Create the D3D object.
g_D3D = Direct3DCreate9(D3D_SDK_VERSION);
if(g_D3D == NULL) return false;


// Get the desktop display mode.
if(FAILED(g_D3D->GetAdapterDisplayMode(D3DADAPTER_DEFAULT,
&displayMode))) return false;


// Set up the structure used to create the D3DDevice
D3DPRESENT_PARAMETERS d3dpp;
ZeroMemory(
&d3dpp, sizeof(d3dpp));


if(fullscreen)
{
d3dpp.Windowed
= FALSE;
d3dpp.BackBufferWidth
= 640;
d3dpp.BackBufferHeight
= 480;
}
else
d3dpp.Windowed
= TRUE;
d3dpp.SwapEffect
= D3DSWAPEFFECT_DISCARD;
d3dpp.BackBufferFormat
= displayMode.Format;


// Create the D3DDevice
if(FAILED(g_D3D->CreateDevice(D3DADAPTER_DEFAULT,
D3DDEVTYPE_HAL, hWnd, D3DCREATE_HARDWARE_VERTEXPROCESSING,
&d3dpp, &g_D3DDevice))) return false;


// Initialize any objects we will be displaying.
if(!InitializeObjects()) return false;

return true;
}


bool InitializeObjects()
{
unsigned
long col = D3DCOLOR_XRGB(0, 255, 0);

// Fill in our structure to draw an object.
// x, y, z, rhw, color.
stD3DVertex objData[] =
{
{
420.0f, 150.0f, 0.5f, 1.0f, col, },
{
420.0f, 350.0f, 0.5f, 1.0f, col, },
{
220.0f, 150.0f, 0.5f, 1.0f, col, },
{
220.0f, 350.0f, 0.5f, 1.0f, col, },
};

// Create the vertex buffer.
if(FAILED(g_D3DDevice->CreateVertexBuffer(sizeof(objData), 0,
D3DFVF_VERTEX, D3DPOOL_DEFAULT,
&g_VertexBuffer,
NULL)))
return false;

// Fill the vertex buffer.
void *ptr;

if(FAILED(g_VertexBuffer->Lock(0, sizeof(objData),
(
void**)&ptr, 0))) return false;

memcpy(ptr, objData,
sizeof(objData));

g_VertexBuffer
->Unlock();

return true;
}


void RenderScene()
{
// Clear the backbuffer.
g_D3DDevice->Clear(0, NULL, D3DCLEAR_TARGET,
D3DCOLOR_XRGB(
0,0,0), 1.0f, 0);

// Begin the scene. Start rendering.
g_D3DDevice->BeginScene();

// Render object.
g_D3DDevice->SetStreamSource(0, g_VertexBuffer, 0, sizeof(stD3DVertex));
g_D3DDevice
->SetFVF(D3DFVF_VERTEX);
g_D3DDevice
->DrawPrimitive(D3DPT_LINELIST, 0, 2);

// End the scene. Stop rendering.
g_D3DDevice->EndScene();

// Display the scene.
g_D3DDevice->Present(NULL, NULL, NULL, NULL);
}


void Shutdown()
{
if(g_D3DDevice != NULL) g_D3DDevice->Release();
if(g_D3D != NULL) g_D3D->Release();
if(g_VertexBuffer != NULL) g_VertexBuffer->Release();

g_D3DDevice
= NULL;
g_D3D
= NULL;
g_VertexBuffer
= NULL;
}

/*
DrawPrimitive()函数将绘制出当前设置为流的顶点缓存内容。该函数的参数包括:
要渲染的图元类型、开始渲染的起始顶点索引(开始为0)以及要渲染的图元数目。
由于这里指定在屏幕上绘制两条线段,因为最后一个参数的值为2。图元类型(第一个参数)
可以是D3DPT_POINTLIST、3DPT_LINELIST、3DPT_LINESTRIP、3DPT_TRIANGLELIST、3DPT_TRIANGLESTRIP或
3DPT_TRIANGLEFAN。



【ZT】D3DFVF_XYZ和D3DFVF_XYZRHW的区别

D3DFVF_XYZ和D3DFVF_XYZRHW有什么区别?以前好像没有仔细思考过,只是见到Beginning DirectX9中如是说:
The RHW value, which stands for Reciprocal of Homogeneous W[1], tells Direct3D that the vertices that
are being used are already in screen coordinates. This value is normally used in fog and clipping
calculations and should be set to 1.0.

今天,做了个实验得知,在顶点结构体中没有RHW时,Direct3D将执行视、投影、世界等变换以及进行光线计算,
之后你才能在窗口中得到你所绘制的物体。当顶点结构体中有RHW时,就像上面那段英文所述,告知Direct3D使
用的顶点已经在屏幕坐标系中了,不再执行视图、投影、世界等变换和光线计算,因为D3DFVF_XYZRHW标志告诉
它顶点已经经过了这些处理,并直接将顶点进行光栅操作,任何用SetTransform进行的转换都对其无效。不过
这时的原点就在客户区的左上角了,其中x向右为正,y向下为正,而z的意义已经变为z-buffer的象素深度。

值得注意的是,D3DFVF_XYZRHW和D3DFVF_XYZ、D3DFVF_NORMAL不能共存,因为后两个标志与前一个矛盾。在使用
这种顶点时,系统需要顶点的位置已经经过变换了,也就是说x、y必须在屏幕坐标系中,z必须是z-buffer中
的象素深度,取值范围:0.0-1.0,离观察者最近的地方为0.0,观察范围内最远可见的地方为1.0。(不过我测
试的时候似乎z值不起作用。)

If you use D3DFVF_XYZ, then your vertex format needs to have 3 floats in it, for x, y and z. Those are used
to define a vertex position in 3D space.If you use D3DFVF_XYZRHW, then your vertex format needs to have 4
floats in it, for x, y, z and rhw. X and Y are used to define a vertex position in 2D space, Z is ignored
(I think, it may be used for fog and such, but I don't recall just now - I always set it to 0.0f), and rhw
is the Reciprocal of Homogenous W - which is basically 1 / the depth of the vertex.

Usually, you use D3DFVF_XYZRHW for doing 2D, and D3DFVF_XYZ any other time. However, a lot of people just
use D3DFVF_XYZ, and use an orthoganal projection matrix to make it seem 2D.
_______________________

[1] RHW表示投影空间中顶点所在的齐次点(x,y,z,w)(homogeneous point)的w坐标的倒数(reciprocal)。

*/

  

原文地址:https://www.cnblogs.com/kex1n/p/2145512.html