关于SetTextureStageState()这个函数,此文的理解有误,怕误导了别人,特别在这里声明一下,大家可以看最下面的那个连接,那个写的很好,我也是看了那个blog才知道我理解错了。
下面的代码可以不看了。
再次说说我的理解吧,一个物体是否透明,取决于它的材质,可以理解,在现实中,玻璃这种材质是透明的,而木头这种材质是不透明的,而材质中的diffuse,diffuse中的alpha就是用来调整这个材质的透明度。
SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_DIFFUSE);这句话是说,现在要画的这个物体,它的alpha来自于颜色,比如这个地方的茶壶,并没有指定它使用什么纹理,而只是指定了它的材质是红色的,且材质的diffsue的alpha值是可调用的,所以它是透明的,而如果使用
SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE);的话,茶壶就不会有透明的效果,因为这句话是说,茶壶的透明度将来自纹理的alpha通道,因为之前设置的纹理是木板墙图片,这个图片没有alpha通道,默认值是0xffffffff,而在这个地方调整的alpha值是茶壶材质的alpha,与纹理的alpha不相干,所以,不管怎么调整这个alpha值,茶壶它都不会变的透明!
View Code

bool DXSetup(){    /*******************************************************************************************    * 背景墙    *******************************************************************************************/

// 创建顶点    g_pd3dDevice->CreateVertexBuffer(6 * sizeof(DX7Vertex),         D3DUSAGE_WRITEONLY,        DX7Vertex::FVF,        D3DPOOL_MANAGED,        &BkGndQuad,0);

    DX7Vertex* v;    BkGndQuad->Lock(0, 0, (void**)&v, 0);

// quad built from two triangles, note texture coordinates:    v[0] = DX7Vertex(-6.0f, -6.0f, 5.0f, 0.0f, 0.0f, -1.0f, 0.0f, 1.0f);    v[1] = DX7Vertex(-6.0f,  6.0f, 5.0f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f);    v[2] = DX7Vertex( 6.0f,  6.0f, 5.0f, 0.0f, 0.0f, -1.0f, 1.0f, 0.0f);

    v[3] = DX7Vertex(-6.0f, -6.0f, 5.0f, 0.0f, 0.0f, -1.0f, 0.0f, 1.0f);    v[4] = DX7Vertex( 6.0f,  6.0f, 5.0f, 0.0f, 0.0f, -1.0f, 1.0f, 0.0f);    v[5] = DX7Vertex( 6.0f, -6.0f, 5.0f, 0.0f, 0.0f, -1.0f, 1.0f, 1.0f);    BkGndQuad->Unlock();

// 设置过滤器    g_pd3dDevice->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);    g_pd3dDevice->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);    g_pd3dDevice->SetSamplerState(0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);        // 设置Mipmaps过滤器

// 创建并使用纹理    D3DXCreateTextureFromFile(g_pd3dDevice, "..\\Texture\\256.bmp", &BkGndTex);    BkGndMtrl = WHITE_MTRL;

/*******************************************************************************************    * 物体    *******************************************************************************************/

// 茶壶材质    ::ZeroMemory(&TeapotMtrl, sizeof(TeapotMtrl));    TeapotMtrl.Ambient = RED;    TeapotMtrl.Diffuse = RED;    TeapotMtrl.Specular = RED;    TeapotMtrl.Emissive = BLACK;    TeapotMtrl.Power = 10.0f;    

// 茶壶物体    D3DXCreateTeapot(g_pd3dDevice, &Teapot, NULL);        // 画一个茶壶

// 灯光默认为True//g_pd3dDevice->SetRenderState(D3DRS_LIGHTING, false);

// 设置摄影机    D3DXVECTOR3 position(0.0f, 0.0f, -3.0f);    D3DXVECTOR3 target(0.0f, 0.0f, 0.0f);    D3DXVECTOR3 up(0.0f, 1.0f, 0.0f);    D3DXMATRIX camera;    D3DXMatrixLookAtLH(&camera,&position, &target, &up);    g_pd3dDevice->SetTransform(D3DTS_VIEW, &camera);

/*******************************************************************************************    * 场景、灯光、摄影机&可视体设置    *******************************************************************************************/

// 设置灯光    D3DLIGHT9 dir;    ::ZeroMemory(&dir, sizeof(dir));    dir.Type = D3DLIGHT_POINT;    dir.Diffuse = WHITE;    dir.Specular = WHITE * 0.3f;    dir.Ambient = WHITE * 0.6f;    dir.Position = D3DXVECTOR3(10.0f, 10.0f, -10.0f);    dir.Range = 100;    g_pd3dDevice->SetLight(0, &dir);    g_pd3dDevice->LightEnable(0, true);

    g_pd3dDevice->SetRenderState(D3DRS_NORMALIZENORMALS, true);    g_pd3dDevice->SetRenderState(D3DRS_SPECULARENABLE, true);

// use alpha in material's diffuse component for alpha    g_pd3dDevice->SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_DIFFUSE);    g_pd3dDevice->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);

// set blending factors so that alpha// component determines transparency    g_pd3dDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);    g_pd3dDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);

// 设置投影矩阵    D3DXMATRIX proj;    D3DXMatrixPerspectiveFovLH(        &proj,        D3DX_PI * 0.5f, // 90 - degree        (float)Width / (float)Height,1.0f,1000.0f);    g_pd3dDevice->SetTransform(D3DTS_PROJECTION, &proj);

return true;}

void Render(){// keyboard message process -->>

// increase/decrease alpha via keyboard input    if (::GetAsyncKeyState('A') & 0x8000f)        TeapotMtrl.Diffuse.a += 0.01f;if (::GetAsyncKeyState('S') & 0x8000f)        TeapotMtrl.Diffuse.a -= 0.01f;

// force alpha to[0,1] interval    if (TeapotMtrl.Diffuse.a > 1.0f)        TeapotMtrl.Diffuse.a = 1.0f;if (TeapotMtrl.Diffuse.a < 0.0f)        TeapotMtrl.Diffuse.a = 0.0f;// keyboard message process <<--

static float angle = 0.0f;    angle += 0.02f;if (angle > 6.48)    {        angle = 0;    }

    g_pd3dDevice->Clear(0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, D3DCOLOR_ARGB(0x00,200,200,200), 1.0f, 0);    g_pd3dDevice->BeginScene();// rendering of scene objects happens here

// 画纹理背景墙    D3DXMATRIX priCode;    D3DXMatrixIdentity(&priCode);    g_pd3dDevice->SetTransform(D3DTS_WORLD, &priCode);    g_pd3dDevice->SetFVF(D3DFVF_XYZ | D3DFVF_NORMAL | D3DFVF_TEX1);    g_pd3dDevice->SetStreamSource(0, BkGndQuad, 0, sizeof(DX7Vertex));        g_pd3dDevice->SetMaterial(&BkGndMtrl);    // 设置材质    g_pd3dDevice->SetTexture(0, BkGndTex);    // 设置纹理    g_pd3dDevice->DrawPrimitive(D3DPT_TRIANGLELIST, 0, 2);

// 画Mesh    g_pd3dDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, true);    g_pd3dDevice->SetFVF(D3DFVF_XYZ | D3DFVF_NORMAL);    g_pd3dDevice->SetMaterial(&TeapotMtrl);        // 设置材质(并没有设置纹理,但是效果却是与纹理混合的效果,因为前面设置了纹理)    Teapot->DrawSubset(0);    g_pd3dDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, false);

    g_pd3dDevice->EndScene();    g_pd3dDevice->Present(NULL, NULL, NULL, NULL);}

说说我对SetTextureStageState这个函数的理解,在这个例子中只出现了下面这两种用法
g_pd3dDevice->SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_DIFFUSE);
g_pd3dDevice->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);

首先关于混合,用下面的函数
g_pd3dDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
g_pd3dDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
指定了源混合因子与目标混合因子,画茶壶的时候调用
g_pd3dDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, true);
将混合应用打开
画茶壶的时候,用公式:OutputPixel=SourcePixel 叉乘 SourceBlendFactor + DestPixel 叉乘 DestBlendFactor来计算目标像素的值

现在,在场景中只画出一个灰色的背景墙和一个茶壶(先不画木板纹理墙),灰色的背景墙的颜色值为D3DCOLOR_ARGB(0x00,200,200,200)
使用SetRenderState()指定源与目标混合因子,但是,此时不使用SetTextureStageState()这个函数,OK,来画一个茶壶吧,像上面贴的代码中那样,使用A和S键可以控制这个茶壶的透明度。

现在,在刚才的场景中增加画一个木板纹理墙,使用SetRenderState()指定源与目标混合因子,还是不使用SetTextureStageState()这个函数,这个时候你会发现,A与S键无法控制茶壶的透明度了!
现在把SetTextureStageState()调用打开(Setup中调用,或者画茶壶之前调用都行)
g_pd3dDevice->SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_DIFFUSE);
g_pd3dDevice->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
这个时候再运行,发现A与S键又可以控制茶壶的透明度了!

OK,小结一下,SetTextureStageState(),这个函数的设置就是与那个纹理背景墙相关的!我和理解如下:
先说说不使用SetTextureStageState()这个函数的情况吧。
我的纹理背景墙的图片是没有alpha通道的,它只有24位颜色值,先画纹理背景墙,再画茶壶的时候,要用上面的那个公式来计算输出像素,可是DestPixel是24位的,没有alpha值,而公式中计算的要求是32位的,所以,计算失败!而最终使用的像素颜色值还是茶壶自身的像素颜色值。

调用SetTextureStageState()这个函数,它的用意就是:
指定DestPixel的alpha从哪里来的!
g_pd3dDevice->SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_DIFFUSE);
这句话是说,在混合的时候,如果目标像素颜色值没有alpha值话,那么,目标像素的alpha值将从它的颜色值中计算出来!这样,画茶壶的时候,用公式来计算混合出的目标颜色时,目标像素就有了alpha值,而公式计算有效!就出现了茶壶在纹理背景墙上可以调整透明度!
而g_pd3dDevice->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);这句话,就是说,使用D3DTSS_ALPHAARG1指定的值,即,D3DTA_DIFFUSE.

OK,那什么,不画背景纹理墙,只画一个灰色背景的时候,在不使用SetTextureStageState()的情况下就可以调用茶壶的透明度呢,因为灰度的背景墙是有alpha值的,这个地方我设置为0x00,其实,你设置成任何数值,茶壶都是在可以在灰色背景墙上调整透明度的!

我觉得自己很罗嗦,OK,索性罗嗦到底吧。
g_pd3dDevice->SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_DIFFUSE);
g_pd3dDevice->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);

这个函数就是用来指定,那个纹理背景墙中的alpha到底从哪里来的!

关于这部分内容,这个文章写的很好!

http://www.cppblog.com/kesalin/archive/2008/03/23/45183.html

转载于:https://www.cnblogs.com/emyueguang/archive/2011/12/16/2290266.html

DirectX 龙书 混合 理解相关推荐

  1. DirectX 9.0c游戏开发手记之“龙书”第二版学习笔记之1: 开场白

    在开场白之前的说明: 这是"DirectX 9.0c游戏开发手记"的第一部分,叫做"'龙书'第二版学习笔记",讲的是我做"龙书"第二版(原名 ...

  2. DirectX 12 3D游戏开发实战 -- 龙书随书源码各章项目运行结果概览

    DirectX 12 3D游戏开发实战 -- 龙书随书源码各章项目运行结果概览 第1章 向量运算 第2章 矩阵运算 第4章 Direct3D初始化 第6章 利用Direct3D绘制几何体Box 第7章 ...

  3. 环境配置 龙书dx12_DX12龙书实践——DirectX3D初始化

    从本章开始进入代码实践阶段,主要是动手写和分析代码来熟悉一些渲染管线和各种基础功能实现的核心逻辑.因为本人阅读本书的主要目的是能更加深入的理解上层开源引擎的一些思路,所以对于具体功能可能涉及的数学模型 ...

  4. dx12龙书 描述符根参数常量缓冲区

    ⭐描述符&根参数 知识所在龙书章节: P83~84 资源与描述符 P201~206 常量缓冲区描述符 根签名 描述符表 P262~271 根签名 ①资源与描述符 GPU资源并非直接与渲染流水线 ...

  5. DirectX12龙书--第五章笔记

    需要龙书电子版的可联系我,部分图片太大,csdn导入不了,可访问我的github图床github或者在书里面查看. DirectX12龙书第五章笔记 第五章 5.1 3D视觉即错觉? 5.2 模型的表 ...

  6. 龙书《编译原理》摘要 第一章 引论

    文章目录 0. 前言 1. 语言处理器 2. 编译器基本结构 3. 一些常用术语 0. 前言 最近开始研究TVM源码,总感觉自己抓不住主线. 说是实现了新语言Relay,里面那些奇怪的东西是什么?是类 ...

  7. dx12 龙书第三章学习笔记 -- 变换

    1.线性变换:   函数的输入和输出都是3D向量,我们称为线性变换 矩阵表示法: ⭐所以已知一个线性变换,只要将i,j,z也就是标准基向量代入线性变换,就能构造一个变换矩阵 A:线性变换的矩阵表示法 ...

  8. Github标星8.3k+,Tensorflow 2.0的代码实现及教学材料(“龙书”)公布下载了!

    本文推荐一个热门的Tensorflow 2.0的学习项目,提供pdf和代码,github上标星8.3k+ Github地址: https://github.com/dragen1860/Deep-Le ...

  9. 龙书啃不动?老司机带你从零入门编译原理,开发编译器

    计算机只认识二进制的,但是我们平常开发中根本不会使用二进制进行开发,我们使用的都是 Java.C.Python 这类的高级语言.每种语言都会经过一系列的转换才能被计算机识别,那么到底是谁做的这项工作呢 ...

  10. “龙书”作者斩获图灵奖!谷歌 AI 大神、Swift 之父都受它启蒙

    整理 | 郑丽媛 出品 | CSDN(ID:CSDNnews) 被誉为"计算机界诺贝尔奖"的图灵奖,昨日火热出炉! 国际计算机协会(ACM)于官网宣布将 2020 图灵奖授予哥伦比 ...

最新文章

  1. ionic app 开发和生产环境的配置
  2. 总结获取原生JS(javascript)的父节点、子节点、兄弟节点
  3. android 日期选择器
  4. 内核中的内存申请:kmalloc、vmalloc、kzalloc、get_free_pages 之间的区别
  5. python用户管理系统模块_Django的用户模块与权限系统的示例代码
  6. C++中使用空格的建议
  7. 怎么在页面关闭时执行代码
  8. Tiny4412 小试牛刀
  9. swift野梦抄袭 taylor_如何看待蔡健雅新歌《半途》被指抄袭 Taylor Swift 的《Safe Sound》?...
  10. android 发短信 oppo,OPPO R11短信发送失败怎么办?OPPO手机短信发送失败的解决方法...
  11. 面试经典必问:ReentrantLock 中CLH队列
  12. 【Codeforces 1392F】Omkar and Landslide | 思维、结论
  13. HTML5作业:美食网站设计(浮动的使用)
  14. MyBatis-plus拦截器
  15. 卸载了PL/SQL Developer,说一下与Toad for Oracle的对比
  16. windows rid劫持
  17. 益聚星荣:DR钻戒,“一生只送一人”的暴利生意
  18. Navicat ORA-12737 ZHS16GBK
  19. 数据库第一范式、第二范式、第三范式、BCNF范式
  20. 计算机的硬件故障维修,计算机硬件故障分析与解决方法

热门文章

  1. 如何设计一个好玩的游戏——游戏设计的艺术
  2. php pdf打印横向,如何将pdfFactory打印调整为横向 - 应用技巧 - 常青藤软件工作室...
  3. wordpress博客加载缓慢解决:去除Open Sans和Lato 字体
  4. CAD图纸是怎么转换成GIF动图的?
  5. 机器人matlab仿真步骤,MATLAB机器人仿真程序.doc
  6. 如何做好离职交接工作?
  7. html创建qq注册页面,用javascript制作qq注册动态页面
  8. 西门子s300编程实例_plc西门子s300编程 西门子编程1000例
  9. 单片机(MCU)最强科普(万字总结,值得收藏)
  10. ◎Vbs调用MsAgent组件,很有趣