DirectX9学习(四)装载位图

来源:互联网 发布:周其仁 知乎 编辑:程序博客网 时间:2024/06/02 04:14

2017.08.24

装载位图,由于d3d本身不知道如何装载位图,所以我这次要用到d3dx9.h 和d3dx9.lib,但是查资料,VS2015本身的内置库的话是不包括d3dx9.h的,因为这个库属于工具库而非dx核心库,查找官方文档发现如果要用这个D3DX,就只能去下载d3d的sdk,官方的话是:

D3DX is not considered the canonical API for using Direct3D in Windows 8 and later and therefore isn't included with the corresponding Windows SDK. 

于是就去下了DX的SDK,(安装的时候要退出vs),在项目的属性页->VC++目录->包含目录(Include)中添加上自己D3D安装的目录下的INCLUDE,在库目录下添加安装的DXSDK的LIB->X86,然后再在自己项目的头文件中添加

#include<d3dx9.h>#pragma comment(lib,"d3dx9.lib")
就能正确的使用这个库中提供的工具了。

今天先把环境配好,明天开始学习如何装载位图。

2017.08.25

今天学习如何装载位图

比较重要的函数是

HRESULT D3DXLoadSurfaceFromFile( LPDIRECT3DSURFACE9 pDestSurface, CONST PALETTEENTRY pDestPalette, CONST RECT* pDestRect, DWORD Filter, D3DCOLOR ColorKey, D3DXIMAGE_INFO* pSrcInfo)
这个函数能够从指定文件中加载图像到指定表面(几乎所有静态图片格式)

还有就是利用

d3ddev->StretchRect(surface, NULL, backbuffer, NULL, D3DTEXF_NONE);
把图片拉伸成窗口大小,这样在改变窗口大小的同时图片大小也会改变,图片会一直填充窗口。

表面在创建的时候大小制定的稍微大一些,这样图片看起来就不会很模糊。

下面是代码:

#include<Windows.h>#include<d3d9.h>#include<d3dx9.h>#include<iostream>using namespace std;#pragma comment(lib,"d3d9.lib")#pragma comment(lib,"d3dx9.lib")const string APPTITLE = "Direct3D_Windowed";const int SCREEN_W = 1024;const int SCREEN_H = 768;const LPSTR FineNames[5] = {"D:\\Personal\\Documents\\My Pictures\\00eb096a08d184f145da2ca64b4b45e905d18c53.jpg","D:\\Personal\\Documents\\My Pictures\\i1XfcG5JX8KqO.jpg","D:\\Personal\\Documents\\My Pictures\\20151016033822677.jpg","D:\\Personal\\Documents\\My Pictures\\20150615122310_MYFPz.jpeg","D:\\Personal\\Documents\\My Pictures\\20130116175135_2C285 (1).jpeg"};int pictureIndex = 0;//D3D设置LPDIRECT3D9 d3d = NULL;LPDIRECT3DDEVICE9 d3ddev = NULL;LPDIRECT3DSURFACE9 backbuffer = NULL;LPDIRECT3DSURFACE9 surface = NULL;bool GameOver = false;#define KEY_DOWN(vk_code) ((GetAsyncKeyState(vk_code) & 0x8000) ? 1 : 0)//GameInitbool Game_Init(HWND hwnd){//初始化D3Dd3d = Direct3DCreate9(D3D_SDK_VERSION);if (d3d == NULL){MessageBox(hwnd, "Error Initialize D3D9", "ERROR", MB_OK);return false;}//设置呈现参数D3DPRESENT_PARAMETERS d3dpp;ZeroMemory(&d3dpp, sizeof(d3dpp));d3dpp.Windowed = TRUE;d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;d3dpp.BackBufferFormat = D3DFMT_X8R8G8B8;d3dpp.BackBufferCount = 1;d3dpp.BackBufferWidth = SCREEN_W;d3dpp.BackBufferHeight = SCREEN_H;d3dpp.hDeviceWindow = hwnd;//创建D3D的设备d3d->CreateDevice(D3DADAPTER_DEFAULT,D3DDEVTYPE_HAL,hwnd,D3DCREATE_SOFTWARE_VERTEXPROCESSING,&d3dpp,&d3ddev);if (d3ddev == NULL){MessageBox(hwnd, "Error Create D3DDEV", "ERROR", MB_OK);return false;}//清除缓冲区d3ddev->Clear(0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0, 0, 0), 1.0F, 0);//让backbuffer指向后台缓冲区d3ddev->GetBackBuffer(0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);//创建一个表面 surface指针指向这个表面HRESULT hResult= d3ddev->CreateOffscreenPlainSurface(SCREEN_W,    //表面的宽SCREEN_H,//表面的高D3DFMT_X8R8G8B8,//格式D3DPOOL_DEFAULT,//所用的内存池&surface,//表面的指针NULL//预留);if (hResult != D3D_OK)return false;//加载图片hResult = D3DXLoadSurfaceFromFile(surface,//需要画图的表面NULL,//调色板 ?NULL,//矩形FineNames[0],//源文件名字(路径)NULL,//源矩形D3DX_DEFAULT,//图片填充样式0,//透明NULL//图片信息(通常为NULL));if (hResult != D3D_OK)return false;return true;//初始化完成return true;}void Game_Run(HWND hwnd){if (KEY_DOWN(VK_ESCAPE)){PostMessage(hwnd, WM_DESTROY, 0, 0);}if (KEY_DOWN(VK_SPACE)){pictureIndex++;if (pictureIndex >= 5)pictureIndex = 0;HRESULT hResult = D3DXLoadSurfaceFromFile(surface,NULL,NULL,FineNames[pictureIndex],NULL,D3DX_DEFAULT,0,NULL);}if (!d3ddev)return;//开始渲染if (d3ddev->BeginScene()){//在后台缓冲中画图并拉伸至屏幕d3ddev->StretchRect(surface, NULL, backbuffer, NULL, D3DTEXF_NONE);//停止渲染d3ddev->EndScene();//copy back buffer to the frame bufferd3ddev->Present(NULL, NULL, NULL, NULL);}}void Game_End(HWND hwnd){if (d3ddev){d3ddev->Release();d3ddev = NULL;}if (d3d){d3d->Release();d3d = NULL;}}//Win消息处理LRESULT CALLBACK WinProc(HWND hWnd, UINT message,WPARAM wParam, LPARAM lParam){//HWND:窗口句柄,使用窗口句柄创建一个新的设备环境句柄HDC,只要引用一个窗口或空间就必须得用到窗口句柄switch (message){case WM_DESTROY:GameOver = true;PostQuitMessage(0);break;}return DefWindowProc(hWnd, message, wParam, lParam);}int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevinstance, LPSTR lpCmdLine, int nCmdShow){//set the new window propertiesWNDCLASSEX wc;MSG msg;wc.cbSize = sizeof(WNDCLASSEX);wc.style = CS_HREDRAW | CS_VREDRAW;  //在移动或尺寸更新完|高度调整后重新绘制wc.lpfnWndProc = (WNDPROC)WinProc;  //返回一个指向回调函数的指针,如果不设定这个值,消息就无法传递给HWNDwc.cbClsExtra = 0;wc.cbWndExtra = 0;wc.hInstance = hInstance;wc.hIcon = NULL;wc.hCursor = LoadCursor(NULL, IDC_ARROW);wc.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);wc.lpszMenuName = NULL;wc.lpszClassName = "MainWindowClass";wc.hIconSm = NULL;if (!RegisterClassEx(&wc))return FALSE;//Create a WindowHWND hwnd = CreateWindow("MainWindowClass",APPTITLE.c_str(),WS_OVERLAPPEDWINDOW,CW_USEDEFAULT,CW_USEDEFAULT,SCREEN_W, SCREEN_H,(HWND)NULL,(HMENU)NULL,hInstance,(LPVOID)NULL);if (hwnd == 0) //创建失败return 0;ShowWindow(hwnd, nCmdShow);UpdateWindow(hwnd);//初始化if (!Game_Init(hwnd))return 0;while (!GameOver){if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)){TranslateMessage(&msg);DispatchMessage(&msg);}Game_Run(hwnd);}Game_End(hwnd);return msg.wParam;}

注:

d3ddev->StretchRect(surface, NULL, backbuffer, NULL, D3DTEXF_NONE);

这句代码是将表面绘制到屏幕,而且是整个表面图片填充到窗口中。

如果添加

RECT rect;rect.bottom = 510;
rect.top = 50;rect.left = 50;rect.right = 510;
d3ddev->StretchRect(surface, NULL, backbuffer, &rect, D3DTEXF_NONE);
则是将整个图片画在了这个矩形的区域内


而如果把代码改成

d3ddev->StretchRect(surface, &rect, backbuffer,NULL, D3DTEXF_NONE);
那么这句代码就只画了图片中矩形的一部分


如果想将表面创建的和图像一样大的话,则需要添加下面代码:

D3DXIMAGE_INFO imageInfo;hResult = D3DXGetImageInfoFromFile(filename, &imageInfo);
HRESULT hResult= d3ddev->CreateOffscreenPlainSurface(
imageInfo.Width,    //表面的宽
imageInfo.Height,//表面的高
D3DFMT_X8R8G8B8, //格式D3DPOOL_DEFAULT, //所用的内存池&surface, //表面的指针NULL //预留);





原创粉丝点击