D3D入门---纹理混合,多流
想使用D3D读入一个图片,我们需要做以下步骤。
1:修改顶点灵活格式,和上一个日志中补充的一样,增加光照的时候,我们也需要修改FVF灵活顶点格
式,上一次需要增加的是法线信息,这次我们要增加的是每个顶点的UV信息。 #define D3DFVF_D3DVertex (D3DFVF_XYZ|D3DFVF_TEX1) 2:修改顶点结构。增加对UV的记录。 struct tagVertex{FLOAT fX, fY, fZ; FLOAT fTU, fTV;}; 3:载入纹理图。 LPDIRECT3DTEXTEURE9 pTexture = NULL; D3DCreateTextureFromFile(m_pD3DDevice, “xxx.tga”, &pTexture); 4:设置顶点的UV信息 tagVertex vertexData[x] = {{x, y, z, u, v}; … }; 5:在BeginScene(),EndSence()中设置纹理应用。 m_pD3DDevice->SetTexture(0, pTexture); 6:最后,释放资源。 注意,先创建的后释放就行了。
//=============================================================================== 如果想进行纹理混合,你需要对上面的代码修改一下: 1:灵活顶点格式说明是双层纹理 #define D3DFVF_D3DVertex (D3DFVF_XYZ|D3DFVF_TEX2) 2:顶点结构保存两份UV记录。 3:载入两份纹理图。 4:设置顶点的UV信息 5:在BeginScene(),EndSence()中设置纹理应用这步稍微有些变化。我们需要指示两层纹理的混合方式
。 m_pD3DDevice->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR); m_pD3DDevice->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
m_pD3DDevice->SetTextureStageState(0, D3DTSS_TEXCOORDINDEX, 0);
m_pD3DDevice->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE);
m_pD3DDevice->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
m_pD3DDevice->SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
m_pD3DDevice->SetSamplerState(1, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
m_pD3DDevice->SetSamplerState(1, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
m_pD3DDevice->SetTextureStageState(1, D3DTSS_TEXCOORDINDEX, 1);
m_pD3DDevice->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_MODULATE);
m_pD3DDevice->SetTextureStageState(1, D3DTSS_COLORARG1, D3DTA_TEXTURE);
m_pD3DDevice->SetTextureStageState(1, D3DTSS_COLORARG2, D3DTA_CURRENT);
其中第二层纹理混合时候是将第二层纹理和已经渲染好的纹理进行混合的。 之后设置纹理 m_pD3DDevice->SetTexture(0, Texture); m_pD3DDevice->SetTexture(1, Texture2); 6:释放还是一样。 即使加入更多层的纹理混合,道理还是一致的,没有区别。
//=============================================================================== 要实现多重缓冲流就相对麻烦一些了,不过,在实际应用中多流技术用的更多一些。 1:首先,多流是不会使用FVF灵活格式的,我们多流的目的就是将顶点的信息分开导入,例如:顶点位
置信息和纹理UV信息不再保存在一个结构中。 这个时候就要求我们自己进行顶点格式的声明。 struct tagVertexPos{FLOAT fX, fY, fZ;}; struct tagVertexTex{FLOAT fTU, fTV;}; 2:之后我们需要声明申请两份顶点缓冲,分别为其填充顶点位置信息和纹理UV坐标信息 LPDIRECT3DVERTEXBUFFER9 pVertexPosBuf = NULL; LPDIRECT3DVERTEXBUFFER9 pVertexTexBuf = NULL; 分别对这俩BUF进行锁定,Memcpy,解锁操作就可以了。 3:真正困难的是在这里,对顶点格式的声明。之前我们一直是用FVF的,所以很方便一个函数 m_pD3DDevice->SetFVF(VertexFVF); 就OK了,可这次我们需要自己来进行声明。 首先声明一个顶点声明结构 LPDIRECT3DVERTEXDECLARATION9 pVertexDel = NULL; 之后进行顶点声明结构的构造 D3DVERTEXELEMENT9 tagDeclaration[] = { {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0}, {1, 0, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,
0}, D3DDECL_END() }; 最后,创建结构 m_pD3DDevice->CreateVertexDeclaration(tagDeclaration, &pVertexDel); 4:在进行渲染的时候,通知D3D设备,我们使用的是双流,并通知它我们的顶点结构。
m_pD3DDevice->SetStreamSource(0, pVertexPosBuf ,0, sizeof(pVertexPosBuf ));
m_pD3DDevice->SetStreamSource(1, pVertexTexBuf ,0, sizeof(pVertexTexBuf ));
m_pD3DDevice->SetVertexDeclaration(pVertexDel);