Directx9学习(七)初识texture(1)

来源:互联网 发布:jpg用什么软件 编辑:程序博客网 时间:2024/06/12 09:24

2017.08.29

今天学习了texture的简单的使用,利用将texture画到sprite上来达到更高效的绘图,由于使用的sprite,那么在后面可以对sprite进行平移旋转缩放等操作,这些操作有的在表面上是做不到的。

表面surface的缺点:绘图较慢,不支持透明transparent

所以使用sprite还是比较好的选择

1.加载纹理texture:

声明纹理

LPDIRECT3DTEXTURE9 texture = NULL;
从位图文件读取分辨率数据:

D3DXIMAGE_INFO info;HRESULT result = D3DXGetImageInfoFromFile(fileName.c_str(), &info);

从这里也可以得到图片的宽和高,可以存储在 D3DXVECTOR2类型的一个变量中

从位图文件中加载texture:使用D3DXCreateTextureFromFileEx直接将图片加载到纹理中

HRESULT WINAPI    D3DXCreateTextureFromFileExA(        LPDIRECT3DDEVICE9         pDevice,        LPCSTR                    pSrcFile,        UINT                      Width,        UINT                      Height,        UINT                      MipLevels,        DWORD                     Usage,        D3DFORMAT                 Format,        D3DPOOL                   Pool,        DWORD                     Filter,        DWORD                     MipFilter,        D3DCOLOR                  ColorKey,        D3DXIMAGE_INFO*           pSrcInfo,        PALETTEENTRY*             pPalette,        LPDIRECT3DTEXTURE9*       ppTexture);


2.对于透明的Sprite基本实用其alpha通道就可以

在有了纹理texture之后,需要从纹理绘制sprite道平哭上,因此需要sprite指针

LPD3DXSPRITE sprite = NULL;

然后再调用D3DXCreateSprite来初始化Sprite对象,将sprite处理器附着在D3D设备上,让他知道如何在后台缓冲区中绘制Sprite

HRESULT WINAPI     D3DXCreateSprite(         LPDIRECT3DDEVICE9   pDevice,         LPD3DXSPRITE*       ppSprite);

开始画吧!

首先需要锁住Sprite,使用Begin来开始绘画(其参数一般使用D3DXSPRITE_ALPHABLEND,支持透明),然后就可以从已有的texture中加载到Sprite上(Draw函数),最后调用End()来解锁

Draw函数:

HRESULT Draw(LPDIRECT3DTEXTURE9 pTexture, //源图像纹理CONST RECT *pSrcRect, //源图片的某一部分CONST D3DXVECTOR3 *pCenter, //旋转发生的中心点CONST D3DXVECTOR3 *pPosition, //sprite的绘制位置(在窗口的某个地方开始,图片的左上角为原点)D3DCOLOR Color//对色彩的变更,不影响透明度)


顺序大致如下

if (d3ddev->BeginScene()){sprite->Begin(D3DXSPRITE_ALPHABLEND);  //锁住Sprite并开始绘制sprite->Draw(texture, NULL, NULL, &vec3, D3DCOLOR_XRGB(255, 255, 255));sprite->End();d3ddev->EndScene();d3ddev->Present(NULL, NULL, NULL, NULL); //交换后台到前台}


基本的操作就是这么多,从texture绘制Sprite到窗口的基本操作就是这些。


注:

1.需要修改/添加d3dpp的一些设定,和之前写的几个程序不太一样

d3dpp.AutoDepthStencilFormat = D3DFMT_D24S8;d3dpp.Flags = D3DPRESENTFLAG_DISCARD_DEPTHSTENCIL;d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE;d3dpp.EnableAutoDepthStencil = 1;
d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;

2.在没有缩放的情况下,原图多大,Sprite就画的多大,也就是说,

当我的图片是1680*1050,而我的窗口是1024*768的时候,我画出来的效果:


无论怎么去拉伸窗口(因为窗口已经定了就是那么大),图片都不会画成别的样子(全屏以后的图片,拉伸了但是没有画多)



如果把窗口的大小调成1680*1050,那么图片就能完整的画出来



如果图片比较小(我这里用了一张898*562的图片,窗口大小1024*768),他仍然不会拉伸


也就是说,在没有缩放的情况下,源图片有多大,则画到窗口上的就是多大,不会去像表面StretchRect一样适应屏幕


3.目前对于Draw中那个绘画position的理解:是图片左上角的位置而不是图片中心的位置

刚开始认为是图片中心的位置,于是就吧这个值写成了

D3DXVECTOR3 vec3(0.5*SCREENW,0.5*SCREENH,0);sprite->Draw(texture, NULL, NULL, &vec3, D3DCOLOR_XRGB(255, 255, 255));

结果肯定是跑偏了


所以这个点(就目前所了解的知识来看)应该是图片的左上角(0,0)点的位置

把vector3改成0以后就正常了

D3DXVECTOR3 vec3(0,0,0);sprite->Draw(texture, NULL, NULL, &vec3, D3DCOLOR_XRGB(255, 255, 255));


4.最后别忘了释放资源

sprite->Release();


最后是这次的主要代码:

//MyD3d.h#pragma once#include<iostream>#include<windows.h>#include<d3d9.h>#include<d3dx9.h>#pragma comment(lib,"d3d9.lib")#pragma comment(lib,"d3dx9.lib")using namespace std;int SCREENW = 1024;int SCREENH = 768;LPDIRECT3D9 d3d;LPDIRECT3DDEVICE9 d3ddev;LPDIRECT3DSURFACE9 backbuffer = NULL;LPDIRECT3DTEXTURE9 texture = NULL;LPD3DXSPRITE sprite = NULL;bool Direct3D_Init(HWND hwnd, int width, int height, bool fullscreen);D3DXVECTOR2 GetImgSize(string fileName);LPDIRECT3DTEXTURE9 LoadTexture(string fileName, D3DCOLOR transcolor);//加载位图到纹理
#include"MyD3d.h"
bool gameOver = false;string imgPath = "D:\\Personal\\Documents\\My Pictures\\20151016033822677.jpg";string imgAlphaPath = "E:\\Win32\\Win321\\MyFirstD3DGame\\Bucket.png";LRESULT CALLBACK WinProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lparam){switch (msg){case WM_DESTROY:gameOver = true;PostQuitMessage(0);break;}return DefWindowProc(hwnd, msg, wParam, lparam);}//Windows Entry pointint WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow){//initialize window settingsWNDCLASSEX wc;wc.cbSize = sizeof(WNDCLASSEX);wc.style = CS_HREDRAW | CS_VREDRAW;wc.lpfnWndProc = (WNDPROC)WinProc;wc.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;RegisterClassEx(&wc);//Create a new windowHWND window = CreateWindow("MainWindowClass","MainWindowClass",WS_OVERLAPPEDWINDOW,CW_USEDEFAULT, CW_USEDEFAULT,SCREENW, SCREENH,NULL, NULL,hInstance, NULL);if (window == 0)        //BUG??return 0;//display windowShowWindow(window, nCmdShow);UpdateWindow(window);if (!Direct3D_Init(window, SCREENW, SCREENH, false))return 0;//main message loopMSG message;while (!gameOver){if (PeekMessage(&message, NULL, 0, 0, PM_REMOVE)){TranslateMessage(&message);DispatchMessage(&message);}//process game loopif (d3ddev->BeginScene()){sprite->Begin(D3DXSPRITE_ALPHABLEND);  //锁住Sprite并开始绘制//画 ,在没有缩放等变换之前 图片大小:如果是比窗口大的图片就只显示一部分(sprite大小和图片一样大),但如果是小图片的话就只会画出原始的,不会拉伸填充之类的//总之,sprite多大,他就只会画多大的D3DXVECTOR3 vec3(0,0,0);sprite->Draw(texture, NULL, NULL, &vec3, D3DCOLOR_XRGB(255, 255, 255));//texture图源,图片单元(动画帧的矩形),旋转中心点,sprite位置(图片的左上角所在的位置而不是中心所在的位置),色彩变更(不影响透明度)sprite->End();d3ddev->EndScene();d3ddev->Present(NULL, NULL, NULL, NULL); //交换后台到前台}}//shut downsprite->Release();d3ddev->Release();d3d->Release();return message.wParam;}bool Direct3D_Init(HWND hwnd, int width, int height, bool fullscreen){d3d = Direct3DCreate9(D3D_SDK_VERSION);if (!d3d)return false;D3DPRESENT_PARAMETERS d3dpp;ZeroMemory(&d3dpp, sizeof(d3dpp));d3dpp.Windowed = (!fullscreen);d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;d3dpp.BackBufferFormat = D3DFMT_X8R8G8B8;d3dpp.BackBufferCount = 1;d3dpp.BackBufferWidth = width;d3dpp.BackBufferHeight = height;d3dpp.hDeviceWindow = hwnd;d3dpp.AutoDepthStencilFormat = D3DFMT_D24S8;d3dpp.Flags = D3DPRESENTFLAG_DISCARD_DEPTHSTENCIL;d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE;d3dpp.EnableAutoDepthStencil = 1;d3d->CreateDevice(D3DADAPTER_DEFAULT,D3DDEVTYPE_HAL,hwnd,D3DCREATE_SOFTWARE_VERTEXPROCESSING,&d3dpp,&d3ddev);if (!d3ddev)return false;d3ddev->GetBackBuffer(0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);texture = LoadTexture(imgPath, D3DCOLOR_XRGB(0,0,0));//将sprite处理器附着在d3d设备上,以便他知道如何在后台缓冲区中绘制spriteHRESULT result = D3DXCreateSprite(d3ddev, &sprite);return true;}//得到图像大小(长宽)D3DXVECTOR2 GetImgSize(string fileName){D3DXIMAGE_INFO info;HRESULT result = D3DXGetImageInfoFromFile(fileName.c_str(), &info);D3DXVECTOR2 size = D3DXVECTOR2((float)info.Width, (float)info.Height);return size;}//加载贴图LPDIRECT3DTEXTURE9 LoadTexture(string fileName, D3DCOLOR transcolor){LPDIRECT3DTEXTURE9 tex = NULL;D3DXIMAGE_INFO info;HRESULT result = D3DXGetImageInfoFromFile(fileName.c_str(), &info);if (result != D3D_OK)return NULL;//create a new texture by loading a bitmap img fileresult = D3DXCreateTextureFromFileEx(d3ddev,//d3d device objfileName.c_str(),// bitmap filenameinfo.Width,//bitmap img widthinfo.Height,//bitmap img height1,//mip-map levels(1 for no chain)D3DPOOL_DEFAULT,//type of surfaceD3DFMT_UNKNOWN,//surface formatD3DPOOL_DEFAULT,//memory class for the textureD3DX_DEFAULT,//img filterD3DX_DEFAULT,//mip filtertranscolor,//color key for transparency&info,//bitmap file infoNULL,//color palette&tex//destination tex);if (result != D3D_OK)return NULL;return tex;}



原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 手臂起小水泡痒怎么办 手背有小水泡痒怎么办 水泡破了很痒怎么办 有一块牙龈肿了怎么办 耳前瘘管有脓怎么办 睡歪脖子很痛怎么办 睡歪脖子怎么办小妙招 睡觉睡得脖子疼怎么办 睡久了后脑勺疼怎么办 腮帮肿了但不疼怎么办 吃硬东西腮帮痛怎么办 嘴巴长开旁边疼怎么办 晚上腿酸睡不着觉怎么办 吃酸的牙齿酸软怎么办 吃酸东西牙齿酸怎么办 拔完智齿神经疼怎么办 22岁腿关节疼痛怎么办 耳洞里面有硬块怎么办 耳洞发炎有硬块怎么办 小孩慢性扁桃体发炎怎么办大全 侧切伤口化脓了怎么办 狗狗伤口不愈合怎么办 狗后腿烂了化脓怎么办 乳腺增生腋下淋巴结肿大怎么办 手术刀口冒脓了怎么办 脚伤口感染肿了怎么办 皮外伤口不愈合怎么办 烫伤新皮红红的怎么办 脸上痘痘化脓了怎么办 痘痘引起的红肿怎么办 痘痘引起的硬块怎么办 痘痘化脓感染了怎么办 烫伤有脓了烂掉怎么办 烫伤起泡破皮了怎么办 一出汗就有狐臭怎么办 耳朵后面臭臭的怎么办 赤黑abo意外怀孕怎么办 qq忘记密保了怎么办 三星s8耗电太快怎么办 360云盘关闭照片怎么办 360云盘停止服务怎么办