查看文章
|
22 ----------------------- Page 23----------------------- SetSamplerState(0 , D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP); 边框颜色纹理寻址 一次镜像纹理寻址 纹理包装 光照 D3D 顶点格式 { FLOAT x,y,z; //顶点位置坐标 FLOAT tu,tv; //纹理坐标 FLOAT nx,ny,nz; //顶点法线 23 ----------------------- Page 24----------------------- }; //定义顶点格式 (D3DFVF_XYZ|D3DFVF_TEX1|D3DFVF|NORMAL) ================================================================= 设置物体材质 D3DCOLORVALUE Diffuse; //漫反射 D3DCOLORVALUE Ambient; //环境光 D3DCOLORVALUE Specular; //镜面反射 D3DCOLORVALUE Emissive; //物体本身发光强度 float Power; //镜面反射高光POWER越大,与周围亮度 差距越大 //表示完物体之后需要调用SetMaterial为当前渲染像素点设置材质 CONST D3DMATERIAL9* pMaterial //指向定义材质的指针 漫反射: ZeroMemory(&mtrl,sizeof(D3DMATERIAL9)); mtrl.Diffuse.r = 0.8f; mtrl.Diffuse.g = 0.6f; mtrl.Diffuse.b = 0.5f; mtrl.Diffuse.a = 0.1f; m_pD3Ddevice->SetMaterial(&mtrl); // m_pD3Ddevice为有效的D3D设备句柄 镜面反射: ZeroMemory(&mtrl,sizeof(D3DMATERIAL9)); mtrl. Specular.r = 0.8f; mtrl. Specular.g = 0.6f; mtrl. Specular.b = 0.5f; mtrl.Diffuse.a = 0.1f; m_pD3Ddevice->SetMaterial(&mtrl); // m_pD3Ddevice为有效的D3D设备句柄 //进行镜面反射计算时,需要先打开镜面反射的计算,默认情况下镜面反射为关闭 ==================================================================
----------------------- Page 25----------------------- DirectX 添加光源 光源类型 D3DLIGHT_POINT = 1, //点光源 D3DLIGHT_SPOT = 2, //聚光灯 D3DLIGHT_DIRECTIONAL = 3, //直射光(或平行光) } D3DLIGHTTYPE; 光源属性 D3DLIGHTTYPE Type; //光源类型 D3DCOLORVALUE Diffuse; //光源颜色 D3DCOLORVALUE Ambient; D3DVECTOR Position; //光源位置 D3DVECTOR Direction; //光源方向 float Range; //光源范围 float Falloff; //光源内外锥形衰退 float Attenuation0; //光源衰减系数 float Attenuation2; float Theta; //聚光灯内部锥形角度 float Phi; //聚光灯外部锥形角度 设置光源 D3DLIGHT9 , , 3 : #define LIGHT_TYPE 1 // D3DLIGHT9 d3dLight; Memset(&d3dLight,0,sizeof(d3dlight)); LightType = LIGHT_TYPE; switch(LightType) { Case 1: // Break; Case 2: // Break; Case 3: // Break; } 25 ----------------------- Page 26----------------------- ================================================================= 激活光照运算 激活光照运算的渲染状态 //m_pDevice为有效的D3D设备句柄 指定光源 ( DWORD Index, CONST D3DLIGHT9 *pLight // m_pD3Ddevice为有效的D3D设备句柄,d3dLight为有效的光源指针 激活光源 ( DWORD Index, //指定需要激活的光源的序号值 BOOL Enable //是否激活指定的光源 // m_pD3Ddevice为有效的D3D设备句柄,d3dLight为有效的光源指针 m_pD3Ddevice->LightEnable(0,TRUE); ================================================================= 摄像机 生成视图变换矩阵 26 ----------------------- Page 27----------------------- D3DXMATRIX *WINAPI D3DXMatrixLookAtLH( D3DXMATRIX *pOut, //输出用于视图变换的矩阵 生成投影变换矩阵 D3DXMATRIX *pOut, //输出用于投影变换的矩阵 ================================================================= 27 ----------------------- Page 28----------------------- 模型基础 ID3DXMesh 几何信息的获取 //获取顶点缓冲 ID3DXMesh::GetVertexBuffer(LPDIRECT3DVERTEXBUFFER9* ppVB); //获取索引缓冲 ppVB); 例: //获取顶点缓冲,获取索引缓冲 IDirect3DvertexBuffer9* pVB = NULL; IDirect3DvertexBuffer9* pIB = NULL; Mesh-> GetVertexBuffer(&pVB); Mesh-> GetVertexBuffer(&pIB); 填充顶点与索引缓冲 DWORD Flags, //加锁的方式 LPVOID* ppData //返回被锁定的顶点缓冲区指针 HRESULT ID3DXMesh::LockIndexBuffer( DWORD Flags, //加锁的方式 LPVOID* ppData //返回被锁定的顶点缓冲区指针 HRESULT ID3DXMesh::UnlockVertexBuffer(); //解锁的方式 HRESULT ID3DXMesh::UnlockIndexBuffer(); //解锁的方式 //与Mesh的几何结构有关的ID3DXMesh接口的方法: DWORD GetFVF() -------返回顶点的格式 DWORD GetNumVertices() --------返回顶点缓冲中的顶点数 DWORD GetNumBytesPerVertex() --------返回一个顶点所占的字节数 DWORD GetNumFaces() --------返回Mesh的面数,也就是三角形数 子集与属性缓冲 一个Mesh由数个子集组成,子集是Mesh中的一组使用相同属性渲染的三角形,这里 的属性指的是材质,纹理,渲染状态。每一个子集使用唯一的非负整数表示其ID; 获取属性缓冲 28 ----------------------- Page 29----------------------- Mesh->LockAttributeBuffer(lockingFlags,&buffer); //对属性缓冲区进行操作 渲染 HRESULT DrawSubset( DWORD AttribId //属性ID指示Mesh中的子集,按照子集的ID渲染哪 个图形 ); 例: 2.for(int i = 0;i<numSubsets;i++) { Device->SetMaterial(mtrls[i]); Device->SetTexture(0,textures[i]); Mesh->DrawSubset(i); } ================================================================= ID3DXMesh Mesh DWORD Flags, //执行优化的类型 CONST DWORD *pAdjacencyIn, //没有优化的Mesh的临接数组 DWORD *pAdjacencyOut, //输出优化的Mesh的临接数组 DWORD *pFaceRemap, //接受面重射信息 LPD3DXBUFFER *ppVertexRemap //返回顶点重影射信息 参数Flags可取值以下一值或几种值的组合: D3DXMESHOPT_COMPACT //删除没有用的顶点和索引项 D3DXMESHOPT_ATTRSORT //根据属性给三角形排列顺序并调整属性表,这将使 DrawSubset方法更有效的执行 D3DXMESHOPT_VERTEXCACHE //增加顶点缓冲的命中率 D3DXMESHOPT_STRIPREORDER //重组顶点索引使三角形带尽量长 D3DXMESHOPT_IGNOREVERTS //只优化索引,忽略顶点 注意: D3DXMESHOPT_VERTEXCACHE和D3DXMESHOPT_STRIPREORDER不能同时使用; 下面是对一个网格进行优化的片段 Mesh->GenerateAdjacency(0.0f,adjacencyInfo); //用于保存优化的Mesh的数组 29 ----------------------- Page 30----------------------- Mesh->OptimizeInplace( D3DXMESHOPT_ATTRSORT| D3DXMESHOPT_COMPACT| D3DXMESHOPT_VERTEXCACHE, adjacencyInfo, optimizedAdjacencyInfo, 0, 0); 还有一种方法是输出一个优化后的Mesh而不是在原来的基础上修改; DWORD Flags, //执行优化的类型 CONST DWORD *pAdjacencyIn, //没有优化的MESH临近数组 DWORD *pAdjacencyOut, //输出优化的MESH临近数组 DWORD *pFaceRemap, //接受面重射信息 LPD3DXBUFFER *ppVertexRemap, //返回顶点重影射信息 LPD3DXMESH *ppOptMesh //返回新的网格 属性表 如果一个 MESH 使用 D3DXMESHOPT_ATTRSORT 进行优化,那么将创建一个 D3DXATTRIBUTERANGE结构的属性表数组: DWORD AttribId; //子集的ID DWORD FaceStart; //该自己的面的起始值 // FaceStart*3就是起始三角形在索引缓冲的序号 DWORD FaceCount; //子集的面数,也就是三角形数 DWORD VertexStart; //该子集的起始顶点在顶点缓冲中的序号 DWORD VertexCount; //该子集包含的顶点数 访问MESH的属性表 D3DXATTRIBUTERANGE *pAttribTable, //获取属性表的指针 DWORD *pAttribTableSize //属性表的大小,即属性的数量 此方法可以完成两个功能:返回属性表的属性数,返回完整的属性表 返回属性表的元素个数: Mesh->GetAttributeTable(0,&num); //要得到属性表的元素个数可以给第一个参 数传NULL 然后就可以得到属性表了 Mesh-> GetAttributeTable(table,&num); 还可以使用ID3DXMesh::SetAttribute Table方法直接修改属性表。 30 ----------------------- Page 31----------------------- D3DXATTRIBUTERANGE attributeTable[12]; //填充属性表的值 ================================================================= .X 1. LPCTSTR pFilename, //X文件路径和文件名 DWORD Options, //指定生成多边形网格属性 LPDIRECT3DDEVICE9 pD3DDevice, //D3D设备指针 LPD3DXBUFFER *ppAdjacency, //存储多边形临接信息 LPD3DXBUFFER *ppMaterials, //存储材质的内存地址 LPD3DXBUFFER *ppEffectInstances, //存储模型特殊效果的内存地址 DWORD *pNumMaterials, //存储材质数目的内存指针 LPD3DXMESH *ppMesh //存储生成的多边形网格的内存地址 下面函数片段从名为game.x的文件里读取3D模型: if(FAILED(D3DXLoadMeshFromX(L"game.x", //X文件名 D3DXMESH_MANAGED, //保存在系统管理内存中 g_pd3dDevice, //D3D设备 NULL, //无需返回临接信息 &pD3DXMtrlBuffer, //返回材质信息 NULL, //无需返回 &g_dwNumMaterials,//返回材质的数目,即MESH的子 集 &g_pMesh //返回的MESH接口对象 ) ) ) { MessageBox(NULL,L"Couldnot findgame.x",L"Mesh",MB_OK); returnE_FAIL; } 2.ID3DXBuffer : GetBufferPointer();//返回指向数据块首地址的指针 GetBufferSize(); //返回数据块中的大小 ID3DXBuffer ID3DXBuffer本身也是一个COM对象,所以使用完之后需要调用Release方法释放. 例如: D3DXMATERIAL*d3dxMaterials= (D3DXMATERIAL*)pD3DXMtrlBuffer->GetBufferPointer(); pD3DXMtrlBuffer->Release(); 3.载入纹理和材质: |