zoukankan      html  css  js  c++  java
  • 初学Direct X(5)

    初学Direct X(5)


    前面学习了使用表面绘制屏幕,但这种方法与另一种比较起来,有着绘图速度颇慢以及缺乏对任何透明类型的支持,这就是前面的篮框以及炸弹会有黑色背景的原因,这种方法就是纹理。他可以绘制出有透明效果的物体,即只显示对象本身的像素而没有背景。

    1. 加载带有位图的纹理

    应该要让纹理像表面一样有该有的功能,比如将位图加载于纹理上。要做到这个,首先得创建纹理对象,它是LPDIRECT3DTEXTURE9类型:

    LPDIRECT3DTEXTURE9 texture = NULL;
    

    接着从位图中将位图加载到纹理中,其接口如下:

    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);
    

    可见这里面需要知道位图的大小以及D3DXIMAGE_INFO,这个需要使用D3DXGetImageInfoFromFile提前获取:

    D3DXIMAGE_INFO image_info;
    HRESULT result = D3DXGetImageInfoFromFile(filename.c_str(),&image_info);
    

    下面是一个调用D3DXCreateTextureFromFileExA示例:

    D3DXCreateTextureFromFileEx(
    	d3ddev,
    	filename.c_str(),
    	image_info.Width,
    	image_info.Height,
    	1,
    	D3DPOOL_DEFAULT,
    	D3DFMT_UNKNOWN,
    	D3DPOOL_DEFAULT,
    	D3DX_DEFAULT,
    	D3DX_DEFAULT,
    	transcolor,
    	&image_info,
    	NULL,
    	&texture
    	);
    

    2. 将纹理使用渲染器绘制到屏幕上

    2.1 初始化

    首先需要定义一个渲染器,其定义是:

    LPD3DXSPRITE spriteobj;
    

    接下来要将其初始化,作用是将纹理附着在Direct设备上,以便使得Direct设备知道如何在后台缓冲区绘制纹理,以下是接口的定义:

    HRESULT D3DXCreateSprite( 
            LPDIRECT3DDEVICE9   pDevice, 
            LPD3DXSPRITE*       ppSprite);
    

    2.2 绘制前后的操作

    在主Direct设备调用BeginScene之后,就可以开始绘制纹理了,但是需要将表面锁住,这仅通过渲染器使用接口即可:

    HRESULT Begin (DWORD Flags)
    

    flags是必须的,通常是D3DXSPRITE_ALPHABLEND;当然在绘制完后需要对表面解锁,以便其他进程使用:

    HRESULT End (VOID)
    

    2.3 绘制

    十分简单,渲染器,即LPD3DXSPRITE,仅需要使用单一的函数Draw来处理所有的变换,通过它可以执行透明,缩放,以及旋转,以下是这个函数的定义:

    HRESULT Draw(
      [in]       LPDIRECT3DTEXTURE9 pTexture,
      [in] const RECT               *pSrcRect,
      [in] const D3DXVECTOR3        *pCenter, // 旋转发生的中间点
      [in] const D3DXVECTOR3        *pPosition, // 指定纹理的位置
      [in]       D3DCOLOR           Color 
      );
    

    这里还有一个D3DXVECTOR3类型,它是:

    typedef struct D3DXVECTOR3 {
      FLOAT x;
      FLOAT y;
      FLOAT z;
    } D3DXVECTOR3, *LPD3DXVECTOR3;
    

    color:可以是[0xFFFFFFFF - 0x00FFFFFF]:从不透明到透明,可以使用D3DCOLOR_RGBA来生成,一般设置为D3DCOLOR_XRGB(255, 255, 255),即为不透明

    3. 运行一个例子看看

    3.1 绘制无alpha通道位图,无选择ColorKey

    生成图1之前,有几件事需要知道:

    1)在加载位图到纹理时,将ColorKey设置为D3DCOLOR_XRGB(0, 0, 0),也就是黑色

    2)背景色被清空为绿色

    3)原始位图是24位图像,并不包含alpha通道

    图1
    图1

    从结果可以看出,在对其进行绘制时,会对其ColorKey标定的颜色进行背景色填充,似乎也达到了透明的效果:)

    3.2 绘制无alpha通道位图,有选择ColorKey

    生成图2之前,也有几件事需要知道:

    1)在加载位图到纹理时,将ColorKey设置为D3DCOLOR_XRGB(255,0,255),也就是粉色

    2)背景色被清空为绿色

    3)原始位图是24位图像,不包含alpha通道

    图2
    图2

    从结果可以看出,这幅图似乎是我们想要的透明图(原图的背景色就是粉色,和图1处理的原图一样),这里可以看出ColorKey这个变量的意思了,它可以使其所在区域显示背景色,达到透明效果。

    3.3 绘制alpha通道位图,有/无选择ColorKey

    生成图3之前,也有几件事需要知道:

    1)在加载位图到纹理时,将ColorKey设置为D3DCOLOR_XRGB(0,0,0),与图1一样的处理

    2)背景色被清空为绿色

    3)原始位图是32位图像,包含alpha通道

    图3
    图3

    从结果可以看出,似乎绘制的效果不太好,但是它反应出了这几点信息,第一:如果在加载纹理时设置了有效的ColorKeyDraw将毫不留情的将其透明,这导致了显示结果中的飞机头部以及边缘部分是背景颜色;第二:由于飞机背景在alpha通道中被设置为了透明,故在Draw的绘制下,将其透明,这一点合情合理。综上分析,可以看出,在面对带有alpha通道的位图时,Draw在绘制原本就该透明的像素时,也不会忘记处理ColorKey的区域

  • 相关阅读:
    Mysql大文本类型
    js-原生Js汉语拼音首字母匹配城市名
    js-原生Js汉语拼音首字母匹配城市名
    Java学习从基础,中级,高级框架,所有模块整理
    python数组和字符串互相转换
    Spring,SpringMVC,MyBatis,SSM配置文件比较
    Spring,SpringMVC,MyBatis,SSM配置文件比较
    Spring,SpringMVC,MyBatis,SSM配置文件比较
    GPUImage学习总结
    图像处理技术汇总
  • 原文地址:https://www.cnblogs.com/leihui/p/8922307.html
Copyright © 2011-2022 走看看