或者打开连接:程序设计开发
多纹理化
像素着色器,只要渲染到屏幕上,那就有像素这个东西,就要有像素着色器.
实现步骤:
1.编写和编译像素着色器文件
2.创建像素着色器
3.设置像素着色器
//文本文件代码 //--------------------------begim ps.txt--------------------------------------- //全局变量 //存储颜色混合的比例值s,其中 //Scalar.x = s //Scalar.y = 1-s vector Scalar; //纹理混合比例(权重) //纹理0; 纹理1 texture Tex0; texture Tex1; //纹理采样器0 sampler Samp0 = sampler_state { Texture = <Tex0>; MipFilter = LINEAR; MinFilter = LINEAR; MagFilter = LINEAR; }; //纹理采样器1 sampler Samp1 = sampler_state { Texture = <Tex1>; MipFilter = LINEAR; MinFilter = LINEAR; MagFilter = LINEAR; }; //输入两套纹理坐标 struct PS_INPUT { float2 uvCoords0 : TEXCOORD0; float2 uvCoords1 : TEXCOORD1; }; //输出像素颜色 struct PS_OUTPUT { float4 Color : COLOR0; }; //入口函数 PS_OUTPUT PS_Main(PS_INPUT input) { PS_OUTPUT output = (PS_OUTPUT)0; //分别对两个纹理进行采样按照比例混合后输出颜色值 output.Color = tex2D(Samp0, input.uvCoords0)*Scalar.x + tex2D(Samp1, input.uvCoords1)*Scalar.y; return output; } //--------------------------end ps.txt---------------------------------------
vs程序中源代码:
//setup void Setup() { HRESULT hr = 0; //创建顶点缓存 m_d3dDevice->GetD3DDevice()->CreateVertexBuffer( 4 * sizeof(MultiTexVertex), D3DUSAGE_WRITEONLY, MultiTexVertex::FVF, D3DPOOL_MANAGED, &quadVB, 0); //填充顶点缓存 MultiTexVertex* v = 0; quadVB->Lock(0, 0, (void**)&v, 0); v[0] = MultiTexVertex(-3.0f, -3.0f, 10.0f, 0.0f, 1.0f, 0.0f, 1.0f); v[1] = MultiTexVertex(-3.0f, 3.0f, 10.0f, 0.0f, 0.0f, 0.0f, 0.0f); v[2] = MultiTexVertex( 3.0f, -3.0f, 10.0f, 1.0f, 1.0f, 1.0f, 1.0f); v[3] = MultiTexVertex( 3.0f, 3.0f, 10.0f, 1.0f, 0.0f, 1.0f, 0.0f); quadVB->Unlock(); //加载纹理: D3DXCreateTextureFromFile(D3DDevice, L"D:\\pic1.png", &quadTexture0); D3DXCreateTextureFromFile(m_d3dDevice->D3DDevice, L"D:\\pic2.png", &quadTexture1); //编译像素着色器: //创建像素着色器 ID3DXBuffer* codeBuffer = 0; ID3DXBuffer* errorBuffer = 0; hr = D3DXCompileShaderFromFile( L"D:\\ps.txt", 0, 0, "PS_Main", // entry point function name "ps_2_0", D3DXSHADER_ENABLE_BACKWARDS_COMPATIBILITY, &codeBuffer, &errorBuffer, &pixelConstTable); // 输出错误信息: if (errorBuffer) { string str = (char*)errorBuffer->GetBufferPointer(); MessageBox(NULL, Common::StringToWString(str).c_str(), L"ERROR", MB_OK); //safe_release<ID3DXBuffer*>(error_buffer); } if (FAILED(hr)) { MessageBox(NULL, L"D3DXCreateEffectFromFile() - FAILED", L"ERROR", MB_OK); } //创建像素着色器 hr = D3DDevice->CreatePixelShader((DWORD*)codeBuffer->GetBufferPointer(), &pixelShader); if (FAILED(hr)) { MessageBox(NULL, L"CreateVertexShader - FAILED", L"ERROR", MB_OK); } //释放 //safe_release<ID3DXBuffer*>(shader_buffer); //设置投影矩阵 D3DXMATRIX p; RECT rt; GetClientRect(Application::GetInstance()->GetWnd(), &rt); D3DXMatrixPerspectiveFovLH(&p, D3DX_PI * 0.25f, (float)rt.right / rt.bottom, 1.0f, 1000.0f); D3DDevice->SetTransform(D3DTS_PROJECTION, &p); //禁用灯光 D3DDevice->SetRenderState(D3DRS_LIGHTING, false); //得到各常量句柄 ScalarHandle = pixelConstTable->GetConstantByName(0, "Scalar"); Samp0Handle = pixelConstTable->GetConstantByName(0, "Samp0"); Samp1Handle = pixelConstTable->GetConstantByName(0, "Samp1"); //设置对着色器变量Samp0、Samp1的描述 UINT count; pixelConstTable->GetConstantDesc(Samp0Handle, &Samp0Desc, &count); pixelConstTable->GetConstantDesc(Samp1Handle, &Samp1Desc, &count); //设定各着色器变量为初始值 pixelConstTable->SetDefaults(D3DDevice); } //display : 设置像素着色器,取用2张纹理,并在渲染前设置对应采样状态 void Display(float timeDelta) { // render now D3DDevice->Clear(0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0); D3DDevice->BeginScene(); //为着色器全局变量Scalar赋值 D3DXVECTOR4 scalar(0.5f, 0.5f, 0.0f, 1.0f);//一半一半混合 pixelConstTable->SetVector(D3DDevice, ScalarHandle, &scalar); //设置像素着色器 D3DDevice->SetPixelShader(pixelShader); //设置定点格式、绑定数据流 D3DDevice->SetFVF(MultiTexVertex::FVF); D3DDevice->SetStreamSource(0, quadVB, 0, sizeof(MultiTexVertex)); //设置第一、二层纹理 D3DDevice->SetTexture(Samp0Desc.RegisterIndex, quadTexture0); D3DDevice->SetTexture(Samp1Desc.RegisterIndex, quadTexture1); //绘制图形 D3DDevice->DrawPrimitive(D3DPT_TRIANGLESTRIP, 0, 2); D3DDevice->EndScene(); D3DDevice->Present(NULL, NULL, NULL, NULL); }