Add OpenGLPipelineState and integrate into main.cpp

This commit is contained in:
2026-03-16 18:25:58 +08:00
parent 430d23b719
commit 0be91748c2
4 changed files with 259 additions and 3 deletions

View File

@@ -131,11 +131,13 @@ add_library(XCEngine STATIC
include/XCEngine/RHI/OpenGL/OpenGLBuffer.h include/XCEngine/RHI/OpenGL/OpenGLBuffer.h
include/XCEngine/RHI/OpenGL/OpenGLVertexArray.h include/XCEngine/RHI/OpenGL/OpenGLVertexArray.h
include/XCEngine/RHI/OpenGL/OpenGLTexture.h include/XCEngine/RHI/OpenGL/OpenGLTexture.h
include/XCEngine/RHI/OpenGL/OpenGLPipelineState.h
src/RHI/OpenGL/OpenGLDevice.cpp src/RHI/OpenGL/OpenGLDevice.cpp
src/RHI/OpenGL/OpenGLShader.cpp src/RHI/OpenGL/OpenGLShader.cpp
src/RHI/OpenGL/OpenGLBuffer.cpp src/RHI/OpenGL/OpenGLBuffer.cpp
src/RHI/OpenGL/OpenGLVertexArray.cpp src/RHI/OpenGL/OpenGLVertexArray.cpp
src/RHI/OpenGL/OpenGLTexture.cpp src/RHI/OpenGL/OpenGLTexture.cpp
src/RHI/OpenGL/OpenGLPipelineState.cpp
) )
target_include_directories(XCEngine PUBLIC target_include_directories(XCEngine PUBLIC

View File

@@ -0,0 +1,100 @@
#pragma once
#include <GLFW/glfw3.h>
namespace XCEngine {
namespace RHI {
enum class ComparisonFunc {
Never,
Less,
Equal,
LessEqual,
Greater,
NotEqual,
GreaterEqual,
Always
};
enum class BlendFactor {
Zero,
One,
SrcColor,
OneMinusSrcColor,
DstColor,
OneMinusDstColor,
SrcAlpha,
OneMinusSrcAlpha,
DstAlpha,
OneMinusDstAlpha,
ConstantColor,
OneMinusConstantColor,
ConstantAlpha,
OneMinusConstantAlpha
};
enum class CullFace {
Front,
Back,
FrontAndBack
};
enum class FrontFace {
Clockwise,
CounterClockwise
};
struct DepthStencilState {
bool depthTestEnable = true;
bool depthWriteEnable = true;
ComparisonFunc depthFunc = ComparisonFunc::Less;
};
struct BlendState {
bool blendEnable = false;
BlendFactor srcBlend = BlendFactor::SrcAlpha;
BlendFactor dstBlend = BlendFactor::OneMinusSrcAlpha;
BlendFactor srcBlendAlpha = BlendFactor::One;
BlendFactor dstBlendAlpha = BlendFactor::Zero;
};
struct RasterizerState {
bool cullFaceEnable = true;
CullFace cullFace = CullFace::Back;
FrontFace frontFace = FrontFace::CounterClockwise;
bool polygonModeFill = true;
};
struct ViewportState {
int x = 0;
int y = 0;
int width = 0;
int height = 0;
float minDepth = 0.0f;
float maxDepth = 1.0f;
};
class OpenGLPipelineState {
public:
OpenGLPipelineState();
~OpenGLPipelineState();
void SetDepthStencilState(const DepthStencilState& state);
void SetBlendState(const BlendState& state);
void SetRasterizerState(const RasterizerState& state);
void SetViewport(const ViewportState& state);
void Apply();
void SetClearColor(float r, float g, float b, float a);
void Clear(unsigned int buffers);
private:
DepthStencilState m_depthStencilState;
BlendState m_blendState;
RasterizerState m_rasterizerState;
ViewportState m_viewportState;
float m_clearColor[4];
};
} // namespace RHI
} // namespace XCEngine

View File

@@ -0,0 +1,145 @@
#define GLFW_INCLUDE_NONE
#include "XCEngine/RHI/OpenGL/OpenGLPipelineState.h"
#include <glad/glad.h>
#include <GLFW/glfw3.h>
namespace XCEngine {
namespace RHI {
OpenGLPipelineState::OpenGLPipelineState() {
m_clearColor[0] = 0.1f;
m_clearColor[1] = 0.1f;
m_clearColor[2] = 0.1f;
m_clearColor[3] = 1.0f;
}
OpenGLPipelineState::~OpenGLPipelineState() {
}
void OpenGLPipelineState::SetDepthStencilState(const DepthStencilState& state) {
m_depthStencilState = state;
}
void OpenGLPipelineState::SetBlendState(const BlendState& state) {
m_blendState = state;
}
void OpenGLPipelineState::SetRasterizerState(const RasterizerState& state) {
m_rasterizerState = state;
}
void OpenGLPipelineState::SetViewport(const ViewportState& state) {
m_viewportState = state;
}
static unsigned int ToGLComparisonFunc(ComparisonFunc func) {
switch (func) {
case ComparisonFunc::Never: return GL_NEVER;
case ComparisonFunc::Less: return GL_LESS;
case ComparisonFunc::Equal: return GL_EQUAL;
case ComparisonFunc::LessEqual: return GL_LEQUAL;
case ComparisonFunc::Greater: return GL_GREATER;
case ComparisonFunc::NotEqual: return GL_NOTEQUAL;
case ComparisonFunc::GreaterEqual: return GL_GEQUAL;
case ComparisonFunc::Always: return GL_ALWAYS;
default: return GL_LESS;
}
}
static unsigned int ToGLBlendFactor(BlendFactor factor) {
switch (factor) {
case BlendFactor::Zero: return GL_ZERO;
case BlendFactor::One: return GL_ONE;
case BlendFactor::SrcColor: return GL_SRC_COLOR;
case BlendFactor::OneMinusSrcColor: return GL_ONE_MINUS_SRC_COLOR;
case BlendFactor::DstColor: return GL_DST_COLOR;
case BlendFactor::OneMinusDstColor: return GL_ONE_MINUS_DST_COLOR;
case BlendFactor::SrcAlpha: return GL_SRC_ALPHA;
case BlendFactor::OneMinusSrcAlpha: return GL_ONE_MINUS_SRC_ALPHA;
case BlendFactor::DstAlpha: return GL_DST_ALPHA;
case BlendFactor::OneMinusDstAlpha: return GL_ONE_MINUS_DST_ALPHA;
case BlendFactor::ConstantColor: return GL_CONSTANT_COLOR;
case BlendFactor::OneMinusConstantColor: return GL_ONE_MINUS_CONSTANT_COLOR;
case BlendFactor::ConstantAlpha: return GL_CONSTANT_ALPHA;
case BlendFactor::OneMinusConstantAlpha: return GL_ONE_MINUS_CONSTANT_ALPHA;
default: return GL_ONE;
}
}
static unsigned int ToGLCullFace(CullFace face) {
switch (face) {
case CullFace::Front: return GL_FRONT;
case CullFace::Back: return GL_BACK;
case CullFace::FrontAndBack: return GL_FRONT_AND_BACK;
default: return GL_BACK;
}
}
static unsigned int ToGLFrontFace(FrontFace face) {
switch (face) {
case FrontFace::Clockwise: return GL_CW;
case FrontFace::CounterClockwise: return GL_CCW;
default: return GL_CCW;
}
}
void OpenGLPipelineState::Apply() {
if (m_depthStencilState.depthTestEnable) {
glEnable(GL_DEPTH_TEST);
glDepthFunc(ToGLComparisonFunc(m_depthStencilState.depthFunc));
glDepthMask(m_depthStencilState.depthWriteEnable ? GL_TRUE : GL_FALSE);
} else {
glDisable(GL_DEPTH_TEST);
}
if (m_blendState.blendEnable) {
glEnable(GL_BLEND);
glBlendFunc(
ToGLBlendFactor(m_blendState.srcBlend),
ToGLBlendFactor(m_blendState.dstBlend)
);
glBlendFuncSeparate(
ToGLBlendFactor(m_blendState.srcBlend),
ToGLBlendFactor(m_blendState.dstBlend),
ToGLBlendFactor(m_blendState.srcBlendAlpha),
ToGLBlendFactor(m_blendState.dstBlendAlpha)
);
} else {
glDisable(GL_BLEND);
}
if (m_rasterizerState.cullFaceEnable) {
glEnable(GL_CULL_FACE);
glCullFace(ToGLCullFace(m_rasterizerState.cullFace));
glFrontFace(ToGLFrontFace(m_rasterizerState.frontFace));
} else {
glDisable(GL_CULL_FACE);
}
glViewport(
m_viewportState.x,
m_viewportState.y,
m_viewportState.width,
m_viewportState.height
);
glDepthRange(m_viewportState.minDepth, m_viewportState.maxDepth);
}
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) {
unsigned int glBuffers = 0;
if (buffers & 0x1) glBuffers |= GL_COLOR_BUFFER_BIT;
if (buffers & 0x2) glBuffers |= GL_DEPTH_BUFFER_BIT;
if (buffers & 0x4) glBuffers |= GL_STENCIL_BUFFER_BIT;
glClear(glBuffers);
}
} // namespace RHI
} // namespace XCEngine

View File

@@ -19,6 +19,7 @@
#include "XCEngine/Debug/FileLogSink.h" #include "XCEngine/Debug/FileLogSink.h"
#include "XCEngine/RHI/OpenGL/OpenGLShader.h" #include "XCEngine/RHI/OpenGL/OpenGLShader.h"
#include "XCEngine/RHI/OpenGL/OpenGLDevice.h" #include "XCEngine/RHI/OpenGL/OpenGLDevice.h"
#include "XCEngine/RHI/OpenGL/OpenGLPipelineState.h"
using namespace XCEngine::Debug; using namespace XCEngine::Debug;
using namespace XCEngine::RHI; using namespace XCEngine::RHI;
@@ -262,6 +263,7 @@ private:
Model* model = nullptr; Model* model = nullptr;
OpenGLShader* shader = nullptr; OpenGLShader* shader = nullptr;
OpenGLDevice* device = nullptr; OpenGLDevice* device = nullptr;
OpenGLPipelineState* pipeline = nullptr;
int frameCount = 0; int frameCount = 0;
void framebuffer_size_callback(GLFWwindow* window, int width, int height) void framebuffer_size_callback(GLFWwindow* window, int width, int height)
@@ -279,10 +281,17 @@ void Initialize()
Log("OpenGL Test Application Started"); Log("OpenGL Test Application Started");
pipeline = new OpenGLPipelineState();
ViewportState viewport;
viewport.width = SCR_WIDTH;
viewport.height = SCR_HEIGHT;
pipeline->SetViewport(viewport);
pipeline->SetClearColor(0.1f, 0.1f, 0.1f, 1.0f);
pipeline->Apply();
model = new Model("res/models/backpack/backpack.obj"); model = new Model("res/models/backpack/backpack.obj");
shader = new OpenGLShader(); shader = new OpenGLShader();
shader->CompileFromFile("Shaders/vertexshader.glsl", "Shaders/fragmentshader.glsl"); shader->CompileFromFile("Shaders/vertexshader.glsl", "Shaders/fragmentshader.glsl");
glEnable(GL_DEPTH_TEST);
Log("Initialization complete"); Log("Initialization complete");
} }
@@ -319,8 +328,7 @@ bool SaveScreenshot(const char* filename)
void Render() void Render()
{ {
glClearColor(0.1f, 0.1f, 0.1f, 1.0f); pipeline->Clear(3); // COLOR_BUFFER_BIT | DEPTH_BUFFER_BIT
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
shader->Use(); shader->Use();
@@ -387,6 +395,7 @@ int main()
Log("Application closed"); Log("Application closed");
delete pipeline;
delete device; delete device;
delete shader; delete shader;
delete model; delete model;