6.파이프라인
이제 범용적으로 사용하는 것들을 Pipeline으로 묶어서 사용할 수 있도록 해보자
Render단계에 있는 것 중에 범용적으로 사용하는 부분만 따로 빼주고 이에 맞게 범용적으로 사용되는 포인터 변수를 담은 PipelineInfo 구조체도 만들어주자
범용적이지 않은 물체에 관련돼있는 변수들은 따로 설정할 수 있게 함수를 만들어주자
Pipeline.h
#pragma once
//포탄 갈아끼우기
//범용적으로 사용하는 것만 설정
struct PipelineInfo
{
shared_ptr<InputLayout> inputLayout;
shared_ptr<VertexShader> vertexShader;
shared_ptr<PixelShader> pixelShader;
shared_ptr<RasterizerState> rasterizerState;
shared_ptr<BlendState> blendState;
D3D11_PRIMITIVE_TOPOLOGY topology = D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST;
};
class Pipeline
{
public:
Pipeline(ComPtr<ID3D11DeviceContext> deviceContext);
~Pipeline();
void UpdatePipeline(PipelineInfo info);
void SetVertexBuffer(shared_ptr<VertexBuffer> buffer);
void SetIndexBuffer(shared_ptr<IndexBuffer> buffer);
template<typename T>
void SetConstantBuffer(uint32 slot,uint32 scope,shared_ptr<ConstantBuffer<T>> buffer)
{
if(scope & SS_VertexShader)
_deviceContext->VSSetConstantBuffers(slot, 1, buffer->GetComPtr().GetAddressOf());
if (scope & SS_PixelShader)
_deviceContext->PSSetConstantBuffers(slot, 1, buffer->GetComPtr().GetAddressOf());
}
void SetTexture(uint32 slot, uint32 scope, shared_ptr<Texture> texture);
void SetSamplerState(uint32 slot, uint32 scope, shared_ptr<SamplerState> samplerState);
void Draw(uint32 vertexcount, uint32 startVertexLocation);
void DrawIndexed(uint32 indexCount, uint32 startIndexLocation, uint32 baseVertexLocation);
private:
ComPtr<ID3D11DeviceContext> _deviceContext;
};
Pipeline.cpp
#include "pch.h"
#include "Pipeline.h"
Pipeline::Pipeline(ComPtr<ID3D11DeviceContext> deviceContext)
:_deviceContext(deviceContext)
{
}
Pipeline::~Pipeline()
{
}
void Pipeline::UpdatePipeline(PipelineInfo info)
{
//IA - 세팅부분
_deviceContext->IASetInputLayout(info.inputLayout->GetComPtr().Get());
_deviceContext->IASetPrimitiveTopology(info.topology); //삼각형으로 만들어주기
//VS
if (info.vertexShader)
_deviceContext->VSSetShader(info.vertexShader->GetComPtr().Get(), nullptr, 0); //이걸로 일하게
//RS
if(info.rasterizerState)
_deviceContext->RSSetState(info.rasterizerState->GetComPtr().Get());
//PS
if(info.pixelShader)
_deviceContext->PSSetShader(info.pixelShader->GetComPtr().Get(), nullptr, 0);
//OM
if(info.blendState)
_deviceContext->OMSetBlendState(info.blendState->GetComPtr().Get(), info.blendState->GetBlendFactor(), info.blendState->GetSampleMask());
}
void Pipeline::SetVertexBuffer(shared_ptr<VertexBuffer> buffer)
{
uint32 stride = buffer->GetStride();
uint32 offset = buffer->GetOffset();
_deviceContext->IASetVertexBuffers(0, 1, buffer->GetComPtr().GetAddressOf(), &stride, &offset);
}
void Pipeline::SetIndexBuffer(shared_ptr<IndexBuffer> buffer)
{
_deviceContext->IASetIndexBuffer(buffer->GetComPtr().Get(), DXGI_FORMAT_R32_UINT, 0);
}
void Pipeline::SetTexture(uint32 slot, uint32 scope, shared_ptr<Texture> texture)
{
if (scope & SS_VertexShader)
_deviceContext->VSSetShaderResources(0, 1, texture->GetComPtr().GetAddressOf()); //0번슬롯에 1개
if (scope & SS_PixelShader)
_deviceContext->PSSetShaderResources(0, 1, texture->GetComPtr().GetAddressOf()); //0번슬롯에 1개
}
void Pipeline::SetSamplerState(uint32 slot, uint32 scope, shared_ptr<SamplerState> samplerState)
{
if (scope & SS_VertexShader)
_deviceContext->VSSetSamplers(0, 1, samplerState->GetComPtr().GetAddressOf());
if (scope & SS_PixelShader)
_deviceContext->PSSetSamplers(0, 1, samplerState->GetComPtr().GetAddressOf());
}
void Pipeline::Draw(uint32 vertexcount, uint32 startVertexLocation)
{
_deviceContext->Draw(vertexcount, startVertexLocation);
}
void Pipeline::DrawIndexed(uint32 indexCount, uint32 startIndexLocation, uint32 baseVertexLocation)
{
_deviceContext->DrawIndexed(indexCount, startIndexLocation, baseVertexLocation);
}
그리고 마지막으로 메인코드를 정리해주자
Game.h
#pragma once
class Game
{
public:
Game();
~Game();
public:
void Init(HWND hwnd); //윈도우 핸들받아줌
void Update();
void Render();
private:
HWND _hwnd;
shared_ptr<Graphics> _graphics;
shared_ptr<Pipeline> _pipeline;
private:
//기하학적 도형 - cpu
//vector<Vertex> _vertices;
//vector<uint32> _indices;
shared_ptr<Geometry<VertexTextureData>> _geometry;
shared_ptr<VertexBuffer> _vertexBuffer;
//인덱스버퍼 - 이거도 Geometry에 포함
shared_ptr<IndexBuffer> _indexBuffer;
shared_ptr<InputLayout> _inputLayout;
//VS
shared_ptr<VertexShader> _vertexShader;
//RS
shared_ptr<RasterizerState> _rasterizerState;
//PS
shared_ptr<PixelShader> _pixelShader;
//SRV - 이미지를 어떻게 쓸것인가 - 텍스처
shared_ptr<Texture> _texture1;
shared_ptr<SamplerState> _samplerState;
shared_ptr<BlendState> _blendState;
private:
//SRT scale, rotate translate
TransformData _transformData;
shared_ptr<ConstantBuffer<TransformData>> _constantBuffer;
Vec3 _localposition = { 0.f,0.f,0.f };
Vec3 _localRotation = { 0.f,0.f,0.f };
Vec3 _localScale = { 1.f,1.f,1.f };
};
Game.cpp
#include "pch.h"
#include "Game.h"
Game::Game()
{
}
Game::~Game()
{
}
void Game::Init(HWND hwnd)
{
_hwnd = hwnd;
//_graphics=make_shared<Graphics>(hwnd):
_graphics = make_shared<Graphics>(hwnd);
_vertexBuffer = make_shared<VertexBuffer>(_graphics->GetDevice());
_indexBuffer = make_shared<IndexBuffer>(_graphics->GetDevice());
_inputLayout = make_shared<InputLayout>(_graphics->GetDevice());
_geometry = make_shared<Geometry<VertexTextureData>>();
_vertexShader = make_shared<VertexShader>(_graphics->GetDevice());
_pixelShader = make_shared<PixelShader>(_graphics->GetDevice());
_constantBuffer = make_shared<ConstantBuffer<TransformData>>(_graphics->GetDevice(), _graphics->GetDeviceContext());
_texture1 = make_shared<Texture>(_graphics->GetDevice());
_rasterizerState = make_shared<RasterizerState>(_graphics->GetDevice());
_samplerState = make_shared<SamplerState>(_graphics->GetDevice());
_blendState = make_shared<BlendState>(_graphics->GetDevice());
_pipeline = make_shared<Pipeline>(_graphics->GetDeviceContext());
//삼각형 그리기 파트
/// <summary>
/// 기하학적인 도형만들기
/// </summary>
//정점정보
GeometryHelper::CreateRectangle(_geometry);
//정점버퍼
_vertexBuffer->Create(_geometry->GetVertices());
//IndexBuffer
_indexBuffer->Create(_geometry->GetIndices());
_vertexShader->Create(L"Default.hlsl", "VS", "vs_5_0");
//인풋레이아웃
/// <summary>
/// 입력이 어떻게 이뤄져있는지
/// </summary>
_inputLayout->Create(VertexTextureData::descs, _vertexShader->GetBlob());
_pixelShader->Create(L"Default.hlsl", "PS", "ps_5_0");
_rasterizerState->Create();
_samplerState->Create();
_blendState->Create();
/// <summary>
/// 쉐이더 리소스 뷰
/// </summary>
_texture1->Create(L"cat.png");
_constantBuffer->Create();
}
void Game::Update()
{
//크기 회전 이동
Matrix matScale = Matrix::CreateScale(_localScale/3);
Matrix matRotation = Matrix::CreateRotationX(_localRotation.x);
matRotation *= Matrix::CreateRotationY(_localRotation.y);
matRotation *= Matrix::CreateRotationZ(_localRotation.z);
Matrix matTranslation = Matrix::CreateTranslation(_localposition);
Matrix matWorld = matScale * matRotation * matTranslation; //SRT
_transformData.matWorld = matWorld;
_constantBuffer->CopyData(_transformData);
}
void Game::Render()
{
_graphics->RenderBegin(); //초기화
auto _deviceContext = _graphics->GetDeviceContext();
// IA - VS - RS - PS -OM
//TODO : 그리기
{
PipelineInfo info;
info.inputLayout = _inputLayout;
info.vertexShader = _vertexShader;
info.pixelShader = _pixelShader;
info.rasterizerState = _rasterizerState;
info.blendState = _blendState;
_pipeline->UpdatePipeline(info);
auto _deviceContext = _graphics->GetDeviceContext();
_pipeline->SetVertexBuffer(_vertexBuffer);
_pipeline->SetIndexBuffer(_indexBuffer);
_pipeline->SetConstantBuffer(0, SS_VertexShader, _constantBuffer);
_pipeline->SetTexture(0, SS_PixelShader, _texture1);
_pipeline->SetSamplerState(0, SS_PixelShader, _samplerState);
_pipeline->DrawIndexed(_geometry->GetIndexCount(), 0, 0);
}
_graphics->RenderEnd(); //제출
}
정상 작동하는 것을 볼 수 있다.
'게임공부 > Directx11' 카테고리의 다른 글
[Directx11][C++]13. 엔진구조-1(MeshRenderer) (0) | 2024.08.17 |
---|---|
[Directx11][C++]12. 프레임워크 제작4(GameObject,Component) (1) | 2024.08.13 |
[Directx11][C++]10. 프레임워크 제작2(Shader,Rasterizer) (0) | 2024.08.08 |
[Directx11][C++]9. 프레임워크 제작(Graphics,Input Assembler,Geometry) (0) | 2024.07.31 |
[Directx11]8. Simple Math (0) | 2024.07.15 |