Files
XCEngine/engine/src/RHI/OpenGL/OpenGLPipelineState.cpp

230 lines
6.2 KiB
C++
Raw Normal View History

#include "XCEngine/RHI/OpenGL/OpenGLPipelineState.h"
#include "XCEngine/RHI/OpenGL/OpenGLShader.h"
#include "XCEngine/RHI/OpenGL/OpenGLEnums.h"
#include <glad/glad.h>
namespace XCEngine {
namespace RHI {
OpenGLPipelineState::OpenGLPipelineState()
: m_program(0), m_programAttached(false) {
}
OpenGLPipelineState::~OpenGLPipelineState() {
}
void OpenGLPipelineState::SetInputLayout(const InputLayoutDesc& layout) {
m_inputLayoutDesc = layout;
}
void OpenGLPipelineState::SetRasterizerState(const RasterizerDesc& state) {
m_rasterizerDesc = state;
}
void OpenGLPipelineState::SetBlendState(const BlendDesc& state) {
m_blendDesc = state;
}
void OpenGLPipelineState::SetDepthStencilState(const DepthStencilStateDesc& state) {
m_depthStencilDesc = state;
}
void OpenGLPipelineState::SetTopology(uint32_t topologyType) {
m_topologyType = topologyType;
}
void OpenGLPipelineState::SetRenderTargetFormats(uint32_t count, const uint32_t* formats, uint32_t depthFormat) {
}
void OpenGLPipelineState::SetSampleCount(uint32_t count) {
}
void OpenGLPipelineState::SetComputeShader(RHIShader* shader) {
m_computeShader = shader;
if (shader) {
OpenGLShader* glShader = static_cast<OpenGLShader*>(shader);
m_computeProgram = glShader->GetID();
} else {
m_computeProgram = 0;
}
}
PipelineStateHash OpenGLPipelineState::GetHash() const {
PipelineStateHash hash = {};
return hash;
}
void OpenGLPipelineState::Shutdown() {
m_program = 0;
m_computeProgram = 0;
m_computeShader = nullptr;
m_programAttached = false;
}
void OpenGLPipelineState::Bind() {
if (HasComputeShader()) {
glUseProgram(m_computeProgram);
} else if (m_programAttached) {
glUseProgram(m_program);
}
Apply();
}
void OpenGLPipelineState::Unbind() {
glUseProgram(0);
}
void OpenGLPipelineState::Apply() {
ApplyDepthStencil();
ApplyBlend();
ApplyRasterizer();
}
void OpenGLPipelineState::ApplyDepthStencil() {
if (m_glDepthStencilState.depthTestEnable) {
glEnable(GL_DEPTH_TEST);
} else {
glDisable(GL_DEPTH_TEST);
}
glDepthMask(m_glDepthStencilState.depthWriteEnable ? GL_TRUE : GL_FALSE);
glDepthFunc(ToOpenGL(m_glDepthStencilState.depthFunc));
if (m_glDepthStencilState.stencilEnable) {
glEnable(GL_STENCIL_TEST);
glStencilMask(m_glDepthStencilState.stencilWriteMask);
glStencilFunc(
ToOpenGL(m_glDepthStencilState.stencilFunc),
m_glDepthStencilState.stencilRef,
m_glDepthStencilState.stencilReadMask
);
glStencilOp(
ToOpenGL(m_glDepthStencilState.stencilFailOp),
ToOpenGL(m_glDepthStencilState.stencilDepthFailOp),
ToOpenGL(m_glDepthStencilState.stencilDepthPassOp)
);
} else {
glDisable(GL_STENCIL_TEST);
}
}
void OpenGLPipelineState::ApplyBlend() {
if (m_glBlendState.blendEnable) {
glEnable(GL_BLEND);
glBlendFuncSeparate(
ToOpenGL(m_glBlendState.srcBlend),
ToOpenGL(m_glBlendState.dstBlend),
ToOpenGL(m_glBlendState.srcBlendAlpha),
ToOpenGL(m_glBlendState.dstBlendAlpha)
);
glBlendEquationSeparate(
ToOpenGL(m_glBlendState.blendOp),
ToOpenGL(m_glBlendState.blendOpAlpha)
);
glColorMask(
(m_glBlendState.colorWriteMask & 1) != 0,
(m_glBlendState.colorWriteMask & 2) != 0,
(m_glBlendState.colorWriteMask & 4) != 0,
(m_glBlendState.colorWriteMask & 8) != 0
);
} else {
glDisable(GL_BLEND);
}
}
void OpenGLPipelineState::ApplyRasterizer() {
if (m_glRasterizerState.cullFaceEnable) {
glEnable(GL_CULL_FACE);
glCullFace(ToOpenGL(m_glRasterizerState.cullFace));
glFrontFace(ToOpenGL(m_glRasterizerState.frontFace));
} else {
glDisable(GL_CULL_FACE);
}
glPolygonMode(GL_FRONT_AND_BACK, ToOpenGL(m_glRasterizerState.polygonMode));
if (m_glRasterizerState.multisampleEnable) {
glEnable(GL_MULTISAMPLE);
} else {
glDisable(GL_MULTISAMPLE);
}
}
void OpenGLPipelineState::ApplyViewport() {
glViewport((GLint)m_viewportState.x, (GLint)m_viewportState.y,
(GLsizei)m_viewportState.width, (GLsizei)m_viewportState.height);
glDepthRange(m_viewportState.minDepth, m_viewportState.maxDepth);
}
void OpenGLPipelineState::ApplyScissor() {
if (m_scissorState.enable) {
glEnable(GL_SCISSOR_TEST);
glScissor(m_scissorState.x, m_scissorState.y, m_scissorState.width, m_scissorState.height);
} else {
glDisable(GL_SCISSOR_TEST);
}
}
void OpenGLPipelineState::SetProgram(unsigned int program) {
m_program = program;
m_programAttached = (program != 0);
}
void OpenGLPipelineState::SetDepthStencilState(const OpenGLDepthStencilState& state) {
m_glDepthStencilState = state;
}
void OpenGLPipelineState::SetBlendState(const OpenGLBlendState& state) {
m_glBlendState = state;
}
void OpenGLPipelineState::SetRasterizerState(const OpenGLRasterizerState& state) {
m_glRasterizerState = state;
}
void OpenGLPipelineState::SetViewport(const ViewportState& state) {
m_viewportState = state;
}
void OpenGLPipelineState::SetScissor(const ScissorState& state) {
m_scissorState = state;
}
void OpenGLPipelineState::SetClearColor(float r, float g, float b, float a) {
m_clearColor[0] = r;
m_clearColor[1] = g;
m_clearColor[2] = b;
m_clearColor[3] = a;
glClearColor(r, g, b, a);
}
void OpenGLPipelineState::Clear(unsigned int buffers) {
glClear(ToOpenGLClearBuffer(buffers));
}
void OpenGLPipelineState::AttachShader(unsigned int program) {
m_program = program;
m_programAttached = true;
glUseProgram(program);
}
void OpenGLPipelineState::DetachShader() {
m_program = 0;
m_programAttached = false;
glUseProgram(0);
}
const OpenGLDepthStencilState& OpenGLPipelineState::GetOpenGLDepthStencilState() const {
return m_glDepthStencilState;
}
const OpenGLBlendState& OpenGLPipelineState::GetOpenGLBlendState() const {
return m_glBlendState;
}
const OpenGLRasterizerState& OpenGLPipelineState::GetOpenGLRasterizerState() const {
return m_glRasterizerState;
}
} // namespace RHI
} // namespace XCEngine