97 lines
		
	
	
	
		
			3.1 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			97 lines
		
	
	
	
		
			3.1 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
| #include <renderer/dx/shader.hpp>
 | |
| #include <renderer/dx/shared_context.hpp>
 | |
| #include <renderer/dx/vertex_layout.hpp>
 | |
| 
 | |
| namespace lt {
 | |
| 
 | |
| dxVertexLayout::dxVertexLayout(
 | |
|     Ref<Shader> shader,
 | |
|     const std::vector<std::pair<std::string, VertexElementType>> &elements,
 | |
|     Ref<dxSharedContext> sharedContext
 | |
| )
 | |
|     : m_context(sharedContext)
 | |
|     , m_input_layout(nullptr)
 | |
| {
 | |
| 	auto inputElementsDesc = std::vector<D3D11_INPUT_ELEMENT_DESC> {};
 | |
| 	inputElementsDesc.reserve(elements.size());
 | |
| 
 | |
| 	// extract elements desc
 | |
| 	for (const auto &element : elements)
 | |
| 	{
 | |
| 		inputElementsDesc.emplace_back(
 | |
| 		    D3D11_INPUT_ELEMENT_DESC { element.first.c_str(),
 | |
| 		                               NULL,
 | |
| 		                               get_dxgi_format(element.second),
 | |
| 		                               0u,
 | |
| 		                               D3D11_APPEND_ALIGNED_ELEMENT,
 | |
| 		                               D3D11_INPUT_PER_VERTEX_DATA,
 | |
| 		                               0u }
 | |
| 		);
 | |
| 	}
 | |
| 
 | |
| 	auto dxpShader = std::dynamic_pointer_cast<dxShader>(shader);
 | |
| 	ensure(dxpShader, "Failed to cast 'Shader' to 'dxShader'");
 | |
| 
 | |
| 	// create input layout (vertex layout)
 | |
| 	auto hr = HRESULT {};
 | |
| 	dxc(m_context->get_device()->CreateInputLayout(
 | |
| 	    &inputElementsDesc[0],
 | |
| 	    inputElementsDesc.size(),
 | |
| 	    dxpShader->get_vertex_blob().Get()->GetBufferPointer(),
 | |
| 	    dxpShader->get_vertex_blob().Get()->GetBufferSize(),
 | |
| 	    &m_input_layout
 | |
| 	));
 | |
| }
 | |
| 
 | |
| dxVertexLayout::~dxVertexLayout()
 | |
| {
 | |
| 	un_bind();
 | |
| }
 | |
| 
 | |
| void dxVertexLayout::bind()
 | |
| {
 | |
| 	m_context->get_device_context()->IASetInputLayout(m_input_layout.Get());
 | |
| }
 | |
| 
 | |
| void dxVertexLayout::un_bind()
 | |
| {
 | |
| 	m_context->get_device_context()->IASetInputLayout(nullptr);
 | |
| }
 | |
| 
 | |
| auto dxVertexLayout::get_dxgi_format(VertexElementType type) -> DXGI_FORMAT
 | |
| {
 | |
| 	switch (type)
 | |
| 	{
 | |
| 	/* byte */
 | |
| 	case lt::VertexElementType::Byte1: return DXGI_FORMAT_R8_SINT;
 | |
| 	case lt::VertexElementType::Byte2: return DXGI_FORMAT_R8G8_SINT;
 | |
| 	case lt::VertexElementType::Byte4: return DXGI_FORMAT_R8_SINT;
 | |
| 
 | |
| 	/* ubyte */
 | |
| 	case lt::VertexElementType::UByte1: return DXGI_FORMAT_R8_UINT;
 | |
| 	case lt::VertexElementType::UByte2: return DXGI_FORMAT_R8G8_UINT;
 | |
| 	case lt::VertexElementType::UByte4: return DXGI_FORMAT_R8G8B8A8_UINT;
 | |
| 
 | |
| 	/* int */
 | |
| 	case lt::VertexElementType::Int1: return DXGI_FORMAT_R32_SINT;
 | |
| 	case lt::VertexElementType::Int2: return DXGI_FORMAT_R32G32_SINT;
 | |
| 	case lt::VertexElementType::Int3: return DXGI_FORMAT_R32G32B32_SINT;
 | |
| 	case lt::VertexElementType::Int4: return DXGI_FORMAT_R32G32B32A32_SINT;
 | |
| 
 | |
| 	/* uint */
 | |
| 	case lt::VertexElementType::UInt1: return DXGI_FORMAT_R32_UINT;
 | |
| 	case lt::VertexElementType::UInt2: return DXGI_FORMAT_R32G32_UINT;
 | |
| 	case lt::VertexElementType::UInt3: return DXGI_FORMAT_R32G32B32_UINT;
 | |
| 	case lt::VertexElementType::UInt4: return DXGI_FORMAT_R32G32B32A32_UINT;
 | |
| 
 | |
| 	/* float */
 | |
| 	case lt::VertexElementType::Float1: return DXGI_FORMAT_R32_FLOAT;
 | |
| 	case lt::VertexElementType::Float2: return DXGI_FORMAT_R32G32_FLOAT;
 | |
| 	case lt::VertexElementType::Float3: return DXGI_FORMAT_R32G32B32_FLOAT;
 | |
| 	case lt::VertexElementType::Float4: return DXGI_FORMAT_R32G32B32A32_FLOAT;
 | |
| 
 | |
| 	default: ensure(false, "Invalid 'VertexElementType'"); return DXGI_FORMAT_UNKNOWN;
 | |
| 	}
 | |
| }
 | |
| 
 | |
| } // namespace lt
 |