第129讲 纹理贴图

第129讲  纹理贴图

上一讲我们说了怎么绘制基本的图形,而且我们已经简单的绘制出一个正方形了,嗯,别纠结了,不管绘制什么都是一样的,将你想绘制的模型分解为多个三角形即可,在上一讲里面我们使用了顶点buffer绘制,顶点buffer的好处是简单,但是带来的问题是内存的开销,所以DirectX提供了更方便的绘制,使用索引buffer。所谓索引就是顶点的所以,简单点说,我们在上一讲里面为了绘制正方向使用了6个顶点,但事实上有两个是重复,当然模型越复杂重复的顶点会越多,而顶点的开销又是自定义的,所以重复的顶点越多需要开销的内存就越大,当然这不关键,关键是还不好控制,所以我们这里引出索引buffer,好了,现在我们可以直接定义出正方形的四个顶点:


//—————————


BasicPCT  

points[] ={

{ -400, 400, 0
},{ 1.f, 1.f, 1.f, 1.f
},{ 0.f, 0.f
}
},

{ 400, 400, 0
},{ 1.f, 1.f, 1.f, 1.f
},{ 1.f, 0.f
}
},

{ -400, -400, 0
},{ 1.f, 1.f, 1.f, 1.f
},{ 0.f, 1.f

} ,

{ 400, -400, 0
},{ 1.f, 1.f, 1.f, 1.f
},{ 1.f, 1.f
}
}

};


//————————–


这和上一讲的是一样的,不过是不是发现有点小小的不一样了呢?当然不是说现在只有四个顶点而上一讲有6个顶点这事,我们看到每个顶点的第三段数据和上一讲的有稍微的不同,这是纹理坐标,上一讲我们曾说过,纹理坐标的预留着,所以在上一讲的顶点数据里并没有关心纹理坐标,而全都设置为0,这里我们为了不让颜色影响到我们的贴图,所以我们把顶点颜色全部设置白色(rgb都为1表示白色,rgb为0表示黑色)


纹理坐标的数值在0到1之间,对于水平方向来说,0是最左端,1是最右端,中间值采用线性插值方式,对于水平方向来说,0是最顶端,1是最下端。结合想象力是不是很好理解上面这段定点数据了呢?


好吧,现在我们已经把四边形的顶点给定义出来了,同样纹理坐标也描述好了,现在就差一个索引buffer和一张图片,嗯,DirectX支持很多种格式的图片,所以可以随意的找一张图来作为我们的贴图。


索引是从0开始的,索然当然就是顶点buffer的索引了,所以要绘制一个四边形就是绘制两个三角形,那么前面三个顶点可以绘制左上角的三角形,这个三角行所用到的顶点索引为0,1,2,而右下半三角行就是由2,1,3这个三个顶点组成,所以索引buffer可以为:


//———————–

unsigned indexs[] ={

0,1,2,

2,1,3

};


//

// 这三个对象作为类成员声明

//

ID3D11Buffer* pVertexBuffer{ nullptr
};

ID3D11Buffer* pIndexBuffer{ nullptr
};

unsigned  

 

 

 

mIndexNum;



pVertexBuffer = pBufferManager->dx_CreateVectexBuffer(points, ARRAYSIZE(points));

pIndexBuffer = pBufferManager->dx_CreateIndexBuffer(indexs, ARRAYSIZE(indexs));

mIndexNum = ARRAYSIZE(indexs);


//

// 在dx_LoadContent函数我们顺便创建出纹理

// 我们使用的纹理贴图为:IMG_8266.JPG

// 我们创建出来后就设置到Effect里面后面就不需要关心他

// 以后的事都在着色器里面完成

//

auto it = pBufferManager->dx_CreateTexTureResouceOnly(“Res/IMG_8266.JPG”);

pLayoutManager->dx_GetShaderResourceFromEF(“MWindowTexture”)->SetResource(it);


//————————–


一切准备妥当之后就进入绘制阶段了,绘制很简单,现在我们多添加了一个索引buffer,索引将该buffer在IA阶段进行设置好,然后我们不再使用Draw函数绘制,而是选用DrawIndexed进行绘制。


//————————-


//

// 设置索引buffer

//

dx_GetContext()->IASetIndexBuffer(pIndexBuffer, DXGI_FORMAT_R32_UINT, 0);


//

// 绘制索引buffer

//

dx_GetContext()->DrawIndexed(mIndexNum,0, 0);


//

// 对FX文件的像素着色器进行修改如下

//

float4 PSMain(PSSceneIn input) : SV_Target

{

float4 colour = MWindowTexture.Sample(WindowSampler, input.tex);


return input.colour*colour;

}


//————————




完整代码如下:


//———————-

class FirstDirectWindow : public MDx11Base{

public:

FirstDirectWindow(){

}


~FirstDirectWindow(){

safe_delete(pBufferManager);

safe_delete(pLayoutManager);

}

bool dx_LoadContent(){ 

try{

std::vector<unsigned>indexs;

std::vector<BasicPCT>points;


points.push_back({{ -400.5, 300.5, 0
},{ 1.f, 1.f, 1.f, 1.f
},{ 0.f, 0.f
}
});

points.push_back({{ 400.5, 300.5, 0
},{ 1.f, 1.f, 1.f, 1.f
},{ 1.f, 0.f
}
});

points.push_back({{ -400.5, -300.5, 0
},{ 1.f, 1.f, 1.f, 1.f
},{ 0.f, 1.f
}
});

points.push_back({{ 400.5, -300.5, 0
},{ 1.f, 1.f, 1.f, 1.f
},{ 1.f, 1.f
}
});


indexs.push_back(2);

indexs.push_back(0);

indexs.push_back(1);


indexs.push_back(2);

indexs.push_back(1);

indexs.push_back(3);

pLayoutManager = new MDx11LayoutManage(dx_GetDevice());

pBufferManager = new MDx11BufferManage(dx_GetDevice());

pLayoutManager->dx_FxComplieFile(“FX/MDx11WindowFX.fx”);

pTechnique = pLayoutManager->dx_GetTechFromEF(“MDx11WindowTech”);

pLayout = pLayoutManager->dx_CreatInputLayout(PCTLayout, ARRAYSIZE(PCTLayout), “MDx11WindowTech”);

//

// 由BufferManager创建的buffer除非特殊指出否则Manager会对buffer进行回收

//

pVertexBuffer = pBufferManager->dx_CreateVectexBuffer(&

points[0], points.size());

pIndexBuffer = pBufferManager->dx_CreateIndexBuffer(&

indexs[0], indexs.size());

mIndexNum = indexs.size();


auto it = pBufferManager->dx_CreateTexTureResouceOnly(“Res/IMG_8266.JPG”);

pLayoutManager->dx_GetShaderResourceFromEF(“MWindowTexture”)->SetResource(it);


return true;

}

catch (std::runtime_error e){

box::ErrorBox(e.what());


return false;

}

}


void dx_Render();


private:

MDx11BufferManage* pBufferManager{ nullptr
};

MDx11LayoutManage* pLayoutManager{ nullptr
};

LPD3D11EFFECTTECHNIQUE pTechnique{ nullptr
};

ID3D11Buffer* pVertexBuffer{ nullptr
};

ID3D11Buffer* pIndexBuffer{ nullptr
};

unsigned mIndexNum{ 0
};

ID3D11InputLayout*  

 

pLayout{ nullptr
};

};


void FirstDirectWindow::dx_Render(){

if (!dx_GetDevice() || !dx_GetContext()){

return;

}

float clearColor[4] ={ 1.f, 1.f, 1.f, 1.0f
};

dx_GetContext()->ClearRenderTargetView(p_backBufferTarget, clearColor);

dx_GetContext()->ClearDepthStencilView(p_depthStencilView, D3D11_CLEAR_DEPTH, 1.0f, 0.0f);

size_t strit = sizeof(BasicPCT);

size_t offset = 0;

dx_GetContext()->IASetVertexBuffers(0, 1, &

pVertexBuffer, &

strit, &

offset);

dx_GetContext()->IASetIndexBuffer(pIndexBuffer, DXGI_FORMAT_R32_UINT, 0);

dx_GetContext()->IASetInputLayout(pLayout);

dx_GetContext()->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);

//D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST D3D11_PRIMITIVE_TOPOLOGY_POINTLIST

pLayoutManager->dx_GetMatrixFromEF(“MWorldMatrix”)->SetMatrix(reinterpret_cast<
float*>(&

word));

XMMATRIX vp = mCamera.dx_GetModeViewMatrix() *mCamera.dx_GetProjectMatrix();

pLayoutManager->dx_GetMatrixFromEF(“MVPMatrix”)->SetMatrix(reinterpret_cast<
float*>(&

vp));

word *= vp;

pLayoutManager->dx_GetMatrixFromEF(“MWVPMatrix”)->SetMatrix(reinterpret_cast<
float*>(&

word));

D3DX11_TECHNIQUE_DESC techdesc = pLayoutManager->dx_GetTichDescFromEF(“MDx11WindowTech”);


for (int i = 0;

i <techdesc.Passes;

++i){

pTechnique->GetPassByIndex(i)->Apply(i, dx_GetContext());

dx_GetContext()->DrawIndexed(mIndexNum,0, 0);

}

dx_GetSwapChain()->Present(0, 0);

}



int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE prevInstance, LPWSTR cmdLine,
int cmdShow)

{

INITCOM;

MWindow w;

FirstDirectWindow dw;

if (!dw.dx_Init(&

w,false,false)){


return 0;

}

w.Show();


return w.Run();

}


//—————————

第129讲  纹理贴图


贴图就到这里,我们主要使用着色器编程,所以大家可以了解一下DirectX11的着色器编程,对理解我们所说的内容很有帮助,比如说我们可以尝试修改采样器的设置看看其他效果是什么:


//—————————


//

// 修改下面的描述可以看看另外的效果

//

SamplerState WindowSampler

{

Filter = MIN_MAG_MIP_LINEAR;

AddressU = Border;

AddressV = Border;

};


//————————–



//==========================

回复D查看目录,回复数字查看相应章节


原文始发于微信公众号(

C/C++的编程教室

):第129讲 纹理贴图

|

发表评论