#include<d3d9.h> #pragma comment(lib, "d3d9.lib") #pragma comment(lib, "d3dx9.lib") #define WINDOW_CLASS "UGPDX" // 窗口类型名称(名字可随便起) #define WINDOW_NAME "Lines" // 窗口标题 bool InitializeD3D(HWND hWnd,bool fullscreen);// 用于在程序中设置和创建Direct3D void RenderScene();// 用于在屏幕上渲染已经绘制好的图形 void ShutDown();// 用于在程序退出时进行一些销毁工作 bool InitializeObjects(); // 用于创建演示程序中要绘制在屏幕上的物体 LPDIRECT3D9 g_D3D = NULL; LPDIRECT3DDEVICE9 g_D3DDevice = NULL; LPDIRECT3DVERTEXBUFFER9 g_VertexBuffer = NULL; //定义一个顶点缓存对象 //定义场景中单个3D点的结构 struct stD3DVertex {float x, y, z, rhw; //点的x,y,z坐标值unsigned long color; //点的颜色 }; //定义顶点格式标识符,即灵活顶点格式 #define D3DFVF_VERTEX (D3DFVF_XYZRHW | D3DFVF_DIFFUSE) //包含坐标和颜色的顶点格式 //窗口过程函数(系统自动调用,回调函数) LRESULT WINAPI MsgProc(HWND hWnd,UINT msg,WPARAM wParam,LPARAM lParam){ switch (msg) { case WM_DESTROY: PostQuitMessage(0); return 0; break; case WM_KEYUP: if (wParam == VK_ESCAPE) { PostQuitMessage(0); } break; } return DefWindowProc( hWnd, msg, wParam, lParam); } int WINAPI WinMain(HINSTANCE hInst,//程序句柄 HINSTANCE prevhInst,//程序先前的实例 LPSTR cmdLine,//传递给程序的命令行参数指针 int show //指明窗口的显示方式 ) { //注册窗口相关类型 // WNDCLASSEX wc = { sizeof(WNDCLASSEX),CS_CLASSDC,MsgProc,0L,0L,GetModuleHandle(NULL),NULL,NULL,NULL,NULL,WINDOW_CLASS,NULL };WNDCLASSEX wc = { sizeof(WNDCLASSEX), CS_CLASSDC, MsgProc, 0L, 0L,GetModuleHandle(NULL), NULL, NULL, NULL, NULL,WINDOW_CLASS, NULL }; RegisterClassEx(&wc); //创建这个注册好的应用程序窗口 HWND hWnd = CreateWindow(WINDOW_CLASS,WINDOW_NAME,WS_OVERLAPPEDWINDOW,100,100,640,480,GetDesktopWindow(),NULL,wc.hInstance,NULL); //CreateWindow()函数可以创建窗口,它的参数包括:要注册的窗口类名称、窗口标题、定义窗口外观的标识符、窗口的起始位置(x和y坐标)、窗口的宽度和高度 //指向父窗口的句柄(设为NULL)、菜单的资源句柄(由于这里的游戏编程不需要菜单栏,所以这里没有使用该句柄)、传递给WinMain()函数的窗口实例以及创建多文档界面软件时用到的参数。 if(InitializeD3D(hWnd,false)) { //显示该窗口 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 { //处理屏幕回执图像的代码部分 RenderScene(); } } }; ShutDown(); UnregisterClass(WINDOW_CLASS,wc.hInstance); return 0; } bool InitializeD3D(HWND hWnd,bool fullscreen) { D3DDISPLAYMODE displayMode; //创建Direct3D 接口对象 g_D3D = Direct3DCreate9(D3D_SDK_VERSION); if (g_D3D == NULL) { return false; } //获取当前显卡的显示模式 if (FAILED(g_D3D->GetAdapterDisplayMode(D3DADAPTER_DEFAULT,&displayMode))) { return false; } //建立D3DPRESENT_PARAMETERS结构,用于定义Direct3D窗口的显示信息 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, //指定Direct3D中的渲染方式 hWnd, //窗口句柄 D3DCREATE_SOFTWARE_VERTEXPROCESSING, //指定设备的运行方式 &d3dpp, //指定创建的D3DPRESENT_PARAMETERS结构 &g_D3DDevice // 指向新创建的Direct3D设备对象 ))) { return false; }if (!InitializeObjects()){return false;} return true; } void RenderScene() { //清空后台缓存 g_D3DDevice->Clear( 0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0,0,0), 1.0f, 0 ); //开始绘制,开始渲染 g_D3DDevice->BeginScene(); //设置顶点数据流的输入源g_D3DDevice->SetStreamSource(0,g_VertexBuffer,0,sizeof(stD3DVertex));//索引流,偏移字节量,顶点跨度,顶点结构大小//设置顶点格式g_D3DDevice->SetFVF(D3DFVF_VERTEX);//进行绘制g_D3DDevice->DrawPrimitive(D3DPT_LINELIST, 0, 2);//渲染的图元类型,开始渲染的起始顶点索引,渲染的图元数量 //结束绘制,停止渲染 g_D3DDevice->EndScene(); //显示绘制的结果 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; } bool InitializeObjects() {unsigned long col = D3DCOLOR_XRGB(255,255,255);//x,y,z,rhw,color//objData结构体数组:设置所有点的数据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,},//第四个点的坐标及颜色};//创建顶点缓存if (FAILED(g_D3DDevice->CreateVertexBuffer(sizeof(objData),0,D3DFVF_VERTEX,D3DPOOL_DEFAULT,&g_VertexBuffer,NULL))){return false;}//HRESULT CreateVertexBuffer(//UINT Length, // 顶点缓存所需的字节数,即缓冲区的长度,一般使用sizeof()确定顶点的大小//DWORD Usage, // 描述顶点缓存的使用方法,一般设为0就可以了//DWORD FVF, // 描述使用顶点缓存的顶点结构,即灵活顶点格式//D3DPOOL Pool, // 放置资源的正确内存类//IDirect3DVertexBuffer9** ppVertexBuffer, // 返回该指针,之后对顶点缓冲进行的操作就是通过这个指针//HANDLE* pSharedHandle // 设为NULL就行了//);void *ptr;//锁定顶点缓存,以进行读写操作if (FAILED(g_VertexBuffer->Lock(0,sizeof(objData),(void**)&ptr,0)))//开始的偏移值(单位字节)//要用的字节数//指向包含顶点数据的内存的指针//锁定缓存时用的标识符,0,全部缓存{return false;}//将数据复制到该缓存中memcpy(ptr,objData,sizeof(objData));//对顶点缓存进行解锁g_VertexBuffer->Unlock();return true; }