麒麟子

~~

导航

<2024年11月>
272829303112
3456789
10111213141516
17181920212223
24252627282930
1234567

统计

常用链接

留言簿(12)

随笔分类

随笔档案

Friends

WebSites

积分与排名

最新随笔

最新评论

阅读排行榜

评论排行榜

#

第一次实现水面渲染(纹理动画方法)

找了很久的相关资料,关于水面渲染的还真不好找呢,突然发现了一个地方有介绍纹理动画,于是就试着做了做,效果还真是不错呢。

只是还没有实现倒影,下次再做。

虽然大虾很多,但像我这样自己捣鼓的也同样存在,那我就说说怎么实现的吧,也顺便理清自己的思路
我说说我的实现方法吧

std::vector<IDirect3DTexture9 *> vecTexture(0); //这个就是用来存储我们的几十张纹理。
先把他们全部加载进去。
然后我们先画一个矩形(略)
 
然后我们根据下面这个来动态切换纹理
Direct3DTexture9* Texture = NULL;
float timeElapsed = 0;
DWORD dwFrameSpeed = 0;
timeElapsed += timeDelta*FrameSpeed;//timeDelta是两次渲染的间隔时间
   if(timeElapsed>vecTexture.size()) timeElapsed = 0;
   Texture = vecTexture[(int)timeElapsed];
 
接下来我们就可以设置纹理,然后渲染那个矩形就可以了。
如果要使水呈透明效果,只要和地形进行ALPHA混合就行了,混合参数自己多调两下。

posted @ 2009-04-22 12:26 麒麟子 阅读(1324) | 评论 (1)编辑 收藏

为DEMO加入雾化效果

雾化效果

首先来看看我们可以设置哪些参数
1、D3DFOGSTART、D3DFOGEND表示雾的起始和结束距离
2、D3DFOGDENSITY 雾的浓度
3、D3DFOGCOLOR 雾的颜色
4、D3DFOGTABLEMODE、D3DFOGVERTEXMODE 雾的模式,第一个为像素雾化,第二个为顶点雾化


首先看看雾化的方程

Color = f * Color(scene) + (1-f) * color(fog)

Color(scene):背景色
Color(fog): 雾色
f:雾化参数,随观察点的距离的增大而减小,从而可知最后得到的颜色,当观察点越远时,雾色占的比例越大。

雾有四种方式
D3DFOG_NONE 禁用雾化效果
D3DFOG_EXP  雾化效果随指数增加 f = 1/(e^density)
D3DFOG_EXP2 同上,不过公式变为 f = 1/(e^(density^2))
D3DFOG_LINEAR 线性雾 f = (end-d)/(end-start) d 为当前计算点与观察点距离

现在我们来看如何实现雾化
首先开启雾化效果
Device->SetRenderState(D3DRS_FOGENABLE,true);
然后我们要设置雾化的模式和公式
Device->SetRenderState(DEDRS_FOGTABLEMODE,D3DFOG_LINEAR);
这里我将其设置成了像素雾和线性,同样可以将其换成上面介绍的其它模式和公式
接下来我们就要设置雾化参数了
Device->SetRenderState(D3DRS_FOGCOLOR,oxffffffff);//设置成白色

设置start end
float start= 50,end = 400;
Device->SetRenderState(D3DRS_FOGSTART,*(DWORD*)&start);
Device->SetRenderState(D3DRS_FOGEND,*(DWORD*)&end);
设置浓度
float density = 0.001f;//0.0 -- 1.0
Device->SetRenderState(D3DRS_FOGDENSITY,*(DWORD*)&density);

这样,我们的设置就完了,只要将雾化设置放入我们渲染场景中,就可以看到雾化效果了.
但应该注意以下几点
-----------------------------------------line
   A          B          C
    \          |             /
     \                     /
       \       |         /
        \              /
         \    d     /
          \        /
           \   |  /
            \   /
              P
------------------------------------------
雾化效果是以刚刚上面讲的 d 作为计算标准,所以,我们从P点看到A ,B ,C三点的雾化效果是一样的,而按常理,A ,C的雾应该更浓才对.
很显然,这让我们想到,D3D会有对应的处理办法.
D3D提供了基于发散的雾化效果,雾化随观察点的距离增大而增大,就像点光源,不过,这要求我们的硬件支持,所以在设置前应该检查
D3DCAPS9 caps;
Device->GetDeviceCaps(&caps);

if(caps.RasterCaps&D3DPRASTERCAPS_FOGRANGE)
 Device->SetRenderState(D3DRS_RANGEFOGENABLE,true);

把这个增加到雾化设置中即可~~~

已经12点了,估计人有点晕,也讲不明白些什么东西了,到此为止

 


 

posted @ 2009-04-20 11:58 麒麟子 阅读(597) | 评论 (0)编辑 收藏

透明纹理和平面阴隐DEMO


加入了影子后的效果

渲染树目纹理之前,进行如下设置
Device->SetRenderState(D3DRS_ALPHABLENDENABLE,true);
Device->SetRenderState(D3DRS_SCRBLEND,D3DBLEND_SCRALPHA);
Device->SetRenderState(D3DRS_DESTBLEND,D3DBLEND_INVSCRALPHA);
Device->SetRenderState(D3DRS_ALPHATESTENABLE,true);
Device->SetRenderState(D3DRS_ALPHAREF,0x0);
Device->SetRenderState(D3DRS_ALPHAFUNC,D3DCMP_GREATEREQUAL);


渲染阴影的时候,使用的是同一纹理,但需进行如下设置
Device->SetRenderState(D3DRS_SCRBLEND,D3DBLEND_INVSCRALPHA);


调了一下午,才调出这阴影,难得呀~~`

posted @ 2009-04-19 14:40 麒麟子 阅读(331) | 评论 (0)编辑 收藏

3D DEMO的初步实现


D3DMULTISAMPLE_0_SAMPLES

 


D3DMULTISAMPLE_4_SAMPLES

终于成功地把天空盒,公告板,MESH,纹理等一起用在了一个工程中,哈哈,虽然比较白啦,但还是很有成就感。

posted @ 2009-04-18 15:42 麒麟子 阅读(364) | 评论 (0)编辑 收藏

从Xfile加载MESH模型

首先介绍ID3DXBuffer 接口
此类型有两个方法
LPVOID ID3DXBuffer::GetBufferPointer();//返回指向缓存中数据起始位置的指针
DWORD ID3DXBuffer::GetBufferSize()//返回缓存的大小,单位为字节

下面函数用于创建一个空的ID3DXBuffer对象

HRESULT D3DXCreateBuffer(DWORD NumBytes, LPD3DBUFFER *ppBuffer);


再来介绍一个D3DXMATRIAL结构
typedef struct D3DXMATERIAL
{
      D3DMATERIAL9 Mat3D; //存储材质
      LPSTR pTextureFilename;//存储纹理路径名
}D3DXMATERIAL;

再来看看一个重要的函数
HRESULT D3DXLoadMeshFromX(
LPCSTR pFilename,//文件名
DWORD Options,//创建网格时所使用的标记
LPDIRECT3DDEVICE9 *pDevice,
LPD3DXBUFFER *ppAdjacency,//邻接表信息
LPD3DXBUFFER *ppMaterials,//材质和纹理信息. D3DXMATRIAL结构
LPD3DXBUFFER *ppEffectInstances,//
PDWORD pNumMaterials,//材质数目
LPD3DXMESH *ppMesh//返回填充好的Mesh对象
};

下面是一个实用的例子

class MyMesh
{
...........

private:
ID3DXMesh* Mesh = 0;
std::vector<D3DMATERIAL9> Mtrls(0);
std::vector<IDirect3DTexture9*> Textures(0);
......
};

bool MyMesh::LoadMyMesh( LPCSTR pName,IDirect3DDevice9* Device)
{
   ID3DXBuffer* adjBuffer = 0;
   ID3DXBuffer* mtrlBuffer = 0;
   DWORD numMtrls = 0;
   HRESULT hr = D3DXLoadMeshFromX(pName,D3DXMESH_MANAGED,Device,&adjBuffer,&mtrlBuffer,0,&numMtrls,&Mesh);
   if(FAILED(hr))
   {
     ::MessageBox(NULL,"D3DXLoadFromX() - FAILED",0,0);
    return false;
   }
   if(mtrlBuffer!=0&&numMtrls!=0) //如果有材质
    { 
        D3DXMATERIAL* mtrls  =
        (D3DXMATERIAL*)mtrlBuffer->GetBufferPointer();//GetBufferPointer() 为了适合各种类型,因为返回VOID*类型 需要强制转换
        for(int i = 0;i<numMtrls;i++)
        {
          //得到的材质没有环境光,我们得自己加上,让它等于漫射光
           mtrls[i].MatD3D.Ambient = mtrls[i].MatD3D.Diffuse;
           Mtrls.push_back(mtrls[i].MatD3D);
         }
        if(mtrls[i].pTextureFilename!=0)//纹理不为空
        IDirect3DTexture9* tex = 0;
        D3DXCreateTextureFromFile(Device,mtrls.pTextureFilename,&tex);
        Textures.push_back(tex);
        }
        else
         {
            Textures.push_back(0);
         }
     }
 adjBuffer->Release();
 mtrlBuffer->Release();
 return true;
}

//加载好后,设置好矩阵,就可以进行绘制了.由于Mesh是分为许多子集的,所以要一个一个渲染
void MyMesh::DrawMyMesh(IDreict3DDevice9* Deivice)
{
     for(int i =0;i<Mtrls.size();i++)
     {
       Device->SetMaterial(&Mtrls[i]);
       Device->SetTexture(0,Textures[i]);
       Mesh->DrawSubset(i);
     }
}

posted @ 2009-04-18 10:02 麒麟子 阅读(411) | 评论 (0)编辑 收藏

仅列出标题
共38页: First 24 25 26 27 28 29 30 31 32 Last