首先,我们先回顾下我上个博客,关于手动建立一个win32 窗口的博客,在这里,我再写一遍昨天的代码,并且在这里面加几个函数,关于windows窗口的建立这部分代码,注释我就不写了,只是为了展示我的几个函数所加的位置
本博客实例代码地址:http://download.csdn.net/detail/shangdi712/9052045
utility.h
//-------Windows头及库文件-------
#ifndef WINDOWS_PLATFORM_
#define WINDOWS_PLATFORM_
#include
#include
#pragma comment(lib,"Winmm.lib")
#endif
//-------D3D头及库文件-------
#ifndef D3D_USEFUL_H_
#define D3D_USEFUL_H_
#include
#pragma comment(lib,"d3d9.lib")
#include
#pragma comment(lib,"d3dx9.lib")
#endif
//-------SAFE_DELETE_----------
#ifndef SAFE_DELETE_T_
#define SAFE_DELETE_T_
templateinline void Safe_Delete(T* & p)
{
if (p){ delete p; p = nullptr; }
}
templateinline void Safe_Release(T* & p)
{
if (p){ p->Release(); p = nullptr; }
}
#endif
这里稍微解释一下utility.h的代码,开始先引入window.h mmsystem.h两个头文件,和Winmm.lib 这个库的作用是为了生成windows窗口所用
之后引入directx 所需要的库和头文件
好了,重点来了,后面两个函数模板的作用是用来安全释放的,前一个用来释放普通指针,后一个用来释放directx定义的复杂指针,将安全释放的函数写成模板,之后随调随用,增强了代码的简洁性
好了,下面就是WinMain中的内容了
#include "Utility.h"
HWND g_hWnd = 0;
HINSTANCE g_hInstance = 0;
/*
绘图窗口改造的步骤:
1、包含头文件及库文件,见Utility.h文件
2、声明变量
3、创建D3D接口指针
4、创建D3D设备指针
5、创建Sprite精灵指针
6、改造onRender函数
*/
//COM:组件对象模型
LPDIRECT3D9 g_pD3D = nullptr; //D3D的接口指针,为了创建设备指针
LPDIRECT3DDEVICE9 g_pDevice = nullptr; //D3D的设备指针,为了创建精灵指针
LPD3DXSPRITE g_pSprite = nullptr; //D3D的精灵指针,为了画图
LRESULT CALLBACK WndProc(HWND hWnd ,UINT uMsg,
WPARAM wParam,LPARAM lParam);
VOID onInit()
{
//3、创建D3D接口指针
g_pD3D = Direct3DCreate9(D3D_SDK_VERSION);
D3DDISPLAYMODE d3ddm; //D3D显示模式结构体
ZeroMemory(&d3ddm, sizeof(d3ddm));
//获取当前显卡的显示模式
g_pD3D->GetAdapterDisplayMode(
D3DADAPTER_DEFAULT, //哪张显卡的显示模式
&d3ddm); //获取到的显示模式的存储位置
//4、创建D3D的设备指针
D3DPRESENT_PARAMETERS d3dpp; //描述D3D设备的能力
ZeroMemory(&d3dpp, sizeof(d3dpp));
d3dpp.BackBufferCount = 1; //后台缓冲区的个数(双缓冲技术)
//-----窗口模式的写发-----
d3dpp.Windowed = TRUE; //当前窗口是否为"窗口模式"
-----全屏模式的写发-----
//d3dpp.Windowed = FALSE;
//d3dpp.BackBufferWidth = d3ddm.Width;
//d3dpp.BackBufferHeight = d3ddm.Height;
d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD; //翻转效果:抛弃
//创建设备指针
g_pD3D->CreateDevice(
D3DADAPTER_DEFAULT, //默认显卡
D3DDEVTYPE_HAL, //硬件抽象层
g_hWnd, //所依附的窗口(要改造的窗口)
D3DCREATE_SOFTWARE_VERTEXPROCESSING, //顶点软件处理模式
&d3dpp, //设备的能力
&g_pDevice //返回的设备指针
);
//5、创建精灵指针
D3DXCreateSprite(
g_pDevice, //设备指针
&g_pSprite); //返回的精灵指针
}
VOID onLogic(float fElapsedTime)
{
}
VOID onRender(float fElapsedTime)
{
g_pDevice->Clear(
0, //清空矩形的数量
nullptr, //清空矩形的临接信息
D3DCLEAR_TARGET, //要清空颜色缓冲区
D3DCOLOR_XRGB(102,204,255), //清成什么颜色 由于我喜欢洛天依,我每次都清成天依蓝
1.0f, //深度缓冲区的初始值
0 //模板缓冲区的初始值
);
g_pDevice->BeginScene(); //获取绘制权限
//---------------------------------------
// 渲染代码
//---------------------------------------
g_pDevice->EndScene(); //结束绘制
//前后台缓冲区交换的"源动力"
g_pDevice->Present(nullptr, nullptr, 0, nullptr);
}
VOID onDestroy()
{
Safe_Release(g_pSprite);
Safe_Release(g_pDevice);
Safe_Release(g_pD3D);
}
INT WINAPI WinMain( __in HINSTANCE hInstance,
__in_opt HINSTANCE hPrevInstance,
__in_opt LPSTR lpCmdLine,
__in int nShowCmd )
{
WNDCLASS wc;
ZeroMemory(&wc,sizeof(wc));
wc.cbClsExtra = NULL;
wc.cbWndExtra = NULL;
wc.hbrBackground = (HBRUSH)GetStockObject(GRAY_BRUSH);
wc.hCursor = LoadCursor(0,IDC_ARROW);
wc.hIcon = LoadIcon(0,IDI_APPLICATION);
wc.hInstance = hInstance;
wc.lpfnWndProc = WndProc;
wc.lpszClassName = TEXT("Alibaba");
wc.lpszMenuName = NULL;
wc.style = CS_HREDRAW | CS_VREDRAW;
RegisterClass(&wc);
g_hWnd = CreateWindow(wc.lpszClassName,
TEXT("Linimass"),WS_OVERLAPPEDWINDOW,
50,20,800,600,NULL,NULL,hInstance,NULL);
if(g_hWnd)
{
g_hInstance = hInstance;
onInit();
ShowWindow(g_hWnd,SW_SHOWNORMAL);
UpdateWindow(g_hWnd);
}
MSG msg;
ZeroMemory(&msg,sizeof(msg));
while ( msg.message!=WM_QUIT)
{
if(PeekMessage(&msg,NULL,0,0,PM_REMOVE))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
else
{
static DWORD dwTime = timeGetTime();
DWORD dwCurrentTime = timeGetTime();
DWORD dwElapsedTime = dwCurrentTime - dwTime;
float fElapsedTime = dwElapsedTime * 0.001f;
onLogic(fElapsedTime);
onRender(fElapsedTime);
if (dwElapsedTime < 1000 / 60)
Sleep(1000 / 60 - dwElapsedTime);
dwTime = dwCurrentTime;
}
}
onDestroy();
UnregisterClass(wc.lpszClassName, hInstance);
return 0;
}
LRESULT CALLBACK WndProc(HWND hWnd ,UINT uMsg,
WPARAM wParam,LPARAM lParam)
{
switch(uMsg)
{
case WM_KEYDOWN:
if(wParam == VK_ESCAPE)
DestroyWindow(hWnd);
break;
case WM_CLOSE:
DestroyWindow(hWnd);
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
}
return DefWindowProc(hWnd,uMsg,wParam,lParam);
}
但是,问题来了,如果你按照我的代码写,甚至是把整个代码复制进去,运行的时候还是会有错的,如果你用的是高版本的visual stdio的话,估计在导入d3dx9.h的时候就会有一个红色的波浪线挥之不去,为什么呢,当然是没有安装directx的SDK啊,安装完directx 的SDK 并且把他导入VS里就可以了,具体步骤如下:
1.安装SDK
下载SDK,双击,然后一路下一步,然后直到安装完成
2.在VS中导入库和包含文件
打开vs 然后在你的项目上右击属性,会进入属性界面,左侧点击VC++目录,如图,
在包含文件和库文件位置分别作相应设置,首先是包含文件,点击向下小箭头,然后再点编辑,会出现如下界面
点击上方新建文件夹那个黄黄的图标,地下框里会出现一行可编辑区域,右侧有一个方框里面有三个点,就点那个方框然后选择directx所在位置,默认情况下
64位所在位置:C:\Program Files (x86)\Microsoft DirectX SDK (June 2008)\Include
32位所在位置:C:\Program Files \Microsoft DirectX SDK (June 2008)\Include
把Include这个文件夹包含进来就可以了,
库文件相同道理,库文件所在位置
64位系统所在位置:C:\Program Files (x86)\Microsoft DirectX SDK (June 2008)\Lib\x86
32位系统所在位置:C:\Program Files \Microsoft DirectX SDK (June 2008)\Lib\x86
然后确定确定,大功告成,然后你就会发现d3dx9.h下面那个阴魂不散的小红波浪线没有了,但是,在一些个别情况,还有这样的错误
1>c:\program files (x86)\windows kits\8.1\include\um\propidl.h(1304): error C2061: 语法错误: 标识符“__RPC__inout_xcount”
1>c:\program files (x86)\windows kits\8.1\include\um\propidl.h(1305): error C2061: 语法错误: 标识符“__RPC__in_xcount”
没错,就是这货,可讨厌了,这个问题怎么解决呢
好办,首先,让我们打开刚才包含文件那个名叫Include的文件夹,然后在里面找到名为rpcsal.h的文件,打开它,然后随便找个合适的位置输入以下几行代码:
在Rpcsal.h中添加cxyc预编译指令
#define __RPC__out_xcount_part(size,length)
#define __RPC__in_xcount(size)
#define __RPC__in_xcount_full(size)
#define __RPC__in_range(min,max)
#define __RPC__inout_xcount(size)
然后保存,如果系统说你没有权限,那你就先另存为到桌面上,然后复制进去,替换就好,这回可是真真的没有问题了
运行结果如下
对,就是一个窗口,看起来,跟原版windows窗口只有颜色不一样,然而,除此之外,这个窗口是3D的,可以渲染3D图形。
总之,这篇博客上的direct的内容很基础,我之后还会再写一篇关于direct的文章,也很基础,逻辑上很简单,但是要记忆的东西比较多