Enhance OpenGL RTV and DSV with comprehensive framebuffer support
OpenGLRenderTargetView: - Add RenderTargetType enum for different texture types - Add RenderTargetViewDesc struct with mip level, array slice, layer info - Add Initialize() with desc parameter for 2D/2DArray/3D/Cube - Add InitializeCubemap() for cubemap faces - Add Bind(count) overload for multiple framebuffers - Add Clear() methods for color and depth-stencil - Add static BindFramebuffer/UnbindFramebuffer methods OpenGLDepthStencilView: - Add DepthStencilType enum for different texture types - Add DepthStencilViewDesc struct with mip level, array slice, layer info - Add Initialize() with desc parameter for 2D/2DArray/Cube - Add InitializeCubemap() for cubemap faces - Add ClearDepth, ClearStencil, ClearDepthStencil methods - Add static BindFramebuffer/UnbindFramebuffer methods
This commit is contained in:
@@ -60,8 +60,8 @@ engine/
|
||||
### 4.1 目录结构调整建议
|
||||
```
|
||||
include/XCEngine/RHI/
|
||||
├── Enums.h # 通用枚举
|
||||
├── Types.h # 通用结构体
|
||||
├── RHIEnums.h # 通用枚举
|
||||
├── RHITypes.h # 通用结构体
|
||||
├── RHICapabilities.h # 硬件能力检测
|
||||
├── RHIDevice.h # 设备抽象(核心入口)
|
||||
├── RHICommandQueue.h # 命令队列抽象
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <GLFW/glfw3.h>
|
||||
#include <cstdint>
|
||||
|
||||
namespace XCEngine {
|
||||
namespace RHI {
|
||||
@@ -12,23 +13,54 @@ enum class DepthStencilFormat {
|
||||
D32_FLOAT_S8X24_UINT
|
||||
};
|
||||
|
||||
enum class DepthStencilType {
|
||||
Texture2D,
|
||||
Texture2DArray,
|
||||
TextureCube
|
||||
};
|
||||
|
||||
struct DepthStencilViewDesc {
|
||||
DepthStencilType type = DepthStencilType::Texture2D;
|
||||
int mipLevel = 0;
|
||||
int baseArraySlice = 0;
|
||||
int arraySize = 1;
|
||||
int layer = 0;
|
||||
};
|
||||
|
||||
class OpenGLDepthStencilView {
|
||||
public:
|
||||
OpenGLDepthStencilView();
|
||||
~OpenGLDepthStencilView();
|
||||
|
||||
bool Initialize(unsigned int texture, const DepthStencilViewDesc& desc);
|
||||
bool Initialize(unsigned int texture, int mipLevel = 0);
|
||||
bool InitializeCubemap(unsigned int cubemap, int face, int mipLevel = 0);
|
||||
void Shutdown();
|
||||
|
||||
void Bind();
|
||||
void Unbind();
|
||||
|
||||
unsigned int GetID() const { return m_texture; }
|
||||
void ClearDepth(float depth);
|
||||
void ClearStencil(uint8_t stencil);
|
||||
void ClearDepthStencil(float depth, uint8_t stencil);
|
||||
|
||||
unsigned int GetFramebuffer() const { return m_framebuffer; }
|
||||
unsigned int GetTexture() const { return m_texture; }
|
||||
int GetMipLevel() const { return m_mipLevel; }
|
||||
int GetWidth() const { return m_width; }
|
||||
int GetHeight() const { return m_height; }
|
||||
|
||||
static void BindFramebuffer(unsigned int framebuffer);
|
||||
static void UnbindFramebuffer();
|
||||
|
||||
private:
|
||||
unsigned int m_texture;
|
||||
unsigned int m_framebuffer;
|
||||
int m_mipLevel;
|
||||
int m_width;
|
||||
int m_height;
|
||||
DepthStencilType m_type;
|
||||
DepthStencilFormat m_format;
|
||||
};
|
||||
|
||||
} // namespace RHI
|
||||
|
||||
@@ -1,27 +1,63 @@
|
||||
#pragma once
|
||||
|
||||
#include <GLFW/glfw3.h>
|
||||
#include <cstdint>
|
||||
#include <vector>
|
||||
|
||||
namespace XCEngine {
|
||||
namespace RHI {
|
||||
|
||||
enum class RenderTargetType {
|
||||
Texture2D,
|
||||
Texture2DArray,
|
||||
Texture3D,
|
||||
TextureCube,
|
||||
TextureCubeArray
|
||||
};
|
||||
|
||||
struct RenderTargetViewDesc {
|
||||
RenderTargetType type = RenderTargetType::Texture2D;
|
||||
int mipLevel = 0;
|
||||
int baseArraySlice = 0;
|
||||
int arraySize = 1;
|
||||
int layer = 0;
|
||||
uint32_t format = 0;
|
||||
};
|
||||
|
||||
class OpenGLRenderTargetView {
|
||||
public:
|
||||
OpenGLRenderTargetView();
|
||||
~OpenGLRenderTargetView();
|
||||
|
||||
bool Initialize(unsigned int texture, const RenderTargetViewDesc& desc);
|
||||
bool Initialize(unsigned int texture, int mipLevel = 0);
|
||||
bool InitializeCubemap(unsigned int cubemap, int face, int mipLevel = 0);
|
||||
void Shutdown();
|
||||
|
||||
void Bind(unsigned int slot);
|
||||
void Bind(unsigned int slot = 0);
|
||||
void Bind(unsigned int count, const unsigned int* framebuffers, const int* drawBuffers);
|
||||
void Unbind();
|
||||
|
||||
unsigned int GetID() const { return m_texture; }
|
||||
void Clear(float r, float g, float b, float a);
|
||||
void Clear(float r, float g, float b, float a, float depth, uint8_t stencil);
|
||||
|
||||
unsigned int GetFramebuffer() const { return m_framebuffer; }
|
||||
unsigned int GetTexture() const { return m_texture; }
|
||||
int GetMipLevel() const { return m_mipLevel; }
|
||||
int GetWidth() const { return m_width; }
|
||||
int GetHeight() const { return m_height; }
|
||||
|
||||
static void BindFramebuffer(unsigned int framebuffer);
|
||||
static void UnbindFramebuffer();
|
||||
|
||||
private:
|
||||
unsigned int m_texture;
|
||||
unsigned int m_framebuffer;
|
||||
int m_mipLevel;
|
||||
int m_width;
|
||||
int m_height;
|
||||
RenderTargetType m_type;
|
||||
std::vector<unsigned int> m_framebuffers;
|
||||
};
|
||||
|
||||
} // namespace RHI
|
||||
|
||||
@@ -6,24 +6,72 @@
|
||||
namespace XCEngine {
|
||||
namespace RHI {
|
||||
|
||||
OpenGLDepthStencilView::OpenGLDepthStencilView() : m_texture(0), m_framebuffer(0), m_mipLevel(0) {
|
||||
OpenGLDepthStencilView::OpenGLDepthStencilView()
|
||||
: m_texture(0)
|
||||
, m_framebuffer(0)
|
||||
, m_mipLevel(0)
|
||||
, m_width(0)
|
||||
, m_height(0)
|
||||
, m_type(DepthStencilType::Texture2D)
|
||||
, m_format(DepthStencilFormat::D24_UNORM_S8_UINT) {
|
||||
}
|
||||
|
||||
OpenGLDepthStencilView::~OpenGLDepthStencilView() {
|
||||
Shutdown();
|
||||
}
|
||||
|
||||
bool OpenGLDepthStencilView::Initialize(unsigned int texture, int mipLevel) {
|
||||
bool OpenGLDepthStencilView::Initialize(unsigned int texture, const DepthStencilViewDesc& desc) {
|
||||
m_texture = texture;
|
||||
m_mipLevel = mipLevel;
|
||||
m_mipLevel = desc.mipLevel;
|
||||
m_type = desc.type;
|
||||
|
||||
glGenFramebuffers(1, &m_framebuffer);
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, m_framebuffer);
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, texture, mipLevel);
|
||||
|
||||
|
||||
GLenum depthAttachment = GL_DEPTH_ATTACHMENT;
|
||||
GLenum stencilAttachment = GL_STENCIL_ATTACHMENT;
|
||||
|
||||
switch (desc.type) {
|
||||
case DepthStencilType::Texture2D:
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, texture, desc.mipLevel);
|
||||
break;
|
||||
case DepthStencilType::Texture2DArray:
|
||||
glFramebufferTextureLayer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, texture, desc.mipLevel, desc.baseArraySlice);
|
||||
break;
|
||||
case DepthStencilType::TextureCube:
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_CUBE_MAP_POSITIVE_X + desc.baseArraySlice, texture, desc.mipLevel);
|
||||
break;
|
||||
}
|
||||
|
||||
if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) {
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool OpenGLDepthStencilView::Initialize(unsigned int texture, int mipLevel) {
|
||||
DepthStencilViewDesc desc;
|
||||
desc.mipLevel = mipLevel;
|
||||
return Initialize(texture, desc);
|
||||
}
|
||||
|
||||
bool OpenGLDepthStencilView::InitializeCubemap(unsigned int cubemap, int face, int mipLevel) {
|
||||
m_texture = cubemap;
|
||||
m_mipLevel = mipLevel;
|
||||
m_type = DepthStencilType::TextureCube;
|
||||
|
||||
glGenFramebuffers(1, &m_framebuffer);
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, m_framebuffer);
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_CUBE_MAP_POSITIVE_X + face, cubemap, mipLevel);
|
||||
|
||||
if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) {
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||
return false;
|
||||
}
|
||||
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||
return true;
|
||||
}
|
||||
@@ -43,5 +91,32 @@ void OpenGLDepthStencilView::Unbind() {
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||
}
|
||||
|
||||
void OpenGLDepthStencilView::ClearDepth(float depth) {
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, m_framebuffer);
|
||||
glClearDepth(depth);
|
||||
glClear(GL_DEPTH_BUFFER_BIT);
|
||||
}
|
||||
|
||||
void OpenGLDepthStencilView::ClearStencil(uint8_t stencil) {
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, m_framebuffer);
|
||||
glClearStencil(stencil);
|
||||
glClear(GL_STENCIL_BUFFER_BIT);
|
||||
}
|
||||
|
||||
void OpenGLDepthStencilView::ClearDepthStencil(float depth, uint8_t stencil) {
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, m_framebuffer);
|
||||
glClearDepth(depth);
|
||||
glClearStencil(stencil);
|
||||
glClear(GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
|
||||
}
|
||||
|
||||
void OpenGLDepthStencilView::BindFramebuffer(unsigned int framebuffer) {
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
|
||||
}
|
||||
|
||||
void OpenGLDepthStencilView::UnbindFramebuffer() {
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||
}
|
||||
|
||||
} // namespace RHI
|
||||
} // namespace XCEngine
|
||||
|
||||
@@ -6,24 +6,89 @@
|
||||
namespace XCEngine {
|
||||
namespace RHI {
|
||||
|
||||
OpenGLRenderTargetView::OpenGLRenderTargetView() : m_texture(0), m_framebuffer(0), m_mipLevel(0) {
|
||||
static unsigned int ToGLRenderTargetType(RenderTargetType type) {
|
||||
switch (type) {
|
||||
case RenderTargetType::Texture2D: return GL_TEXTURE_2D;
|
||||
case RenderTargetType::Texture2DArray: return GL_TEXTURE_2D_ARRAY;
|
||||
case RenderTargetType::Texture3D: return GL_TEXTURE_3D;
|
||||
case RenderTargetType::TextureCube: return GL_TEXTURE_CUBE_MAP;
|
||||
case RenderTargetType::TextureCubeArray: return GL_TEXTURE_CUBE_MAP_ARRAY;
|
||||
default: return GL_TEXTURE_2D;
|
||||
}
|
||||
}
|
||||
|
||||
OpenGLRenderTargetView::OpenGLRenderTargetView()
|
||||
: m_texture(0)
|
||||
, m_framebuffer(0)
|
||||
, m_mipLevel(0)
|
||||
, m_width(0)
|
||||
, m_height(0)
|
||||
, m_type(RenderTargetType::Texture2D) {
|
||||
}
|
||||
|
||||
OpenGLRenderTargetView::~OpenGLRenderTargetView() {
|
||||
Shutdown();
|
||||
}
|
||||
|
||||
bool OpenGLRenderTargetView::Initialize(unsigned int texture, int mipLevel) {
|
||||
bool OpenGLRenderTargetView::Initialize(unsigned int texture, const RenderTargetViewDesc& desc) {
|
||||
m_texture = texture;
|
||||
m_mipLevel = mipLevel;
|
||||
m_mipLevel = desc.mipLevel;
|
||||
m_type = desc.type;
|
||||
|
||||
glGenFramebuffers(1, &m_framebuffer);
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, m_framebuffer);
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, mipLevel);
|
||||
|
||||
|
||||
unsigned int target = ToGLRenderTargetType(desc.type);
|
||||
GLenum attachment = GL_COLOR_ATTACHMENT0;
|
||||
|
||||
switch (desc.type) {
|
||||
case RenderTargetType::Texture2D:
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER, attachment, GL_TEXTURE_2D, texture, desc.mipLevel);
|
||||
break;
|
||||
case RenderTargetType::Texture2DArray:
|
||||
glFramebufferTextureLayer(GL_FRAMEBUFFER, attachment, texture, desc.mipLevel, desc.baseArraySlice);
|
||||
break;
|
||||
case RenderTargetType::Texture3D:
|
||||
glFramebufferTextureLayer(GL_FRAMEBUFFER, attachment, texture, desc.mipLevel, desc.layer);
|
||||
break;
|
||||
case RenderTargetType::TextureCube:
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER, attachment, GL_TEXTURE_CUBE_MAP_POSITIVE_X + desc.baseArraySlice, texture, desc.mipLevel);
|
||||
break;
|
||||
case RenderTargetType::TextureCubeArray:
|
||||
glFramebufferTextureLayer(GL_FRAMEBUFFER, attachment, texture, desc.mipLevel, desc.baseArraySlice);
|
||||
break;
|
||||
}
|
||||
|
||||
if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) {
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool OpenGLRenderTargetView::Initialize(unsigned int texture, int mipLevel) {
|
||||
RenderTargetViewDesc desc;
|
||||
desc.type = RenderTargetType::Texture2D;
|
||||
desc.mipLevel = mipLevel;
|
||||
return Initialize(texture, desc);
|
||||
}
|
||||
|
||||
bool OpenGLRenderTargetView::InitializeCubemap(unsigned int cubemap, int face, int mipLevel) {
|
||||
m_texture = cubemap;
|
||||
m_mipLevel = mipLevel;
|
||||
m_type = RenderTargetType::TextureCube;
|
||||
|
||||
glGenFramebuffers(1, &m_framebuffer);
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, m_framebuffer);
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_CUBE_MAP_POSITIVE_X + face, cubemap, mipLevel);
|
||||
|
||||
if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) {
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||
return false;
|
||||
}
|
||||
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||
return true;
|
||||
}
|
||||
@@ -33,15 +98,55 @@ void OpenGLRenderTargetView::Shutdown() {
|
||||
glDeleteFramebuffers(1, &m_framebuffer);
|
||||
m_framebuffer = 0;
|
||||
}
|
||||
if (!m_framebuffers.empty()) {
|
||||
glDeleteFramebuffers(static_cast<GLsizei>(m_framebuffers.size()), m_framebuffers.data());
|
||||
m_framebuffers.clear();
|
||||
}
|
||||
}
|
||||
|
||||
void OpenGLRenderTargetView::Bind(unsigned int slot) {
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, m_framebuffer);
|
||||
(void)slot;
|
||||
}
|
||||
|
||||
void OpenGLRenderTargetView::Bind(unsigned int count, const unsigned int* framebuffers, const int* drawBuffers) {
|
||||
if (count == 1) {
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, framebuffers[0]);
|
||||
} else {
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||
for (unsigned int i = 0; i < count; i++) {
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, framebuffers[i]);
|
||||
glDrawBuffers(1, (const GLenum*)&drawBuffers[i]);
|
||||
}
|
||||
}
|
||||
(void)count;
|
||||
}
|
||||
|
||||
void OpenGLRenderTargetView::Unbind() {
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||
}
|
||||
|
||||
void OpenGLRenderTargetView::Clear(float r, float g, float b, float a) {
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, m_framebuffer);
|
||||
glClearColor(r, g, b, a);
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
}
|
||||
|
||||
void OpenGLRenderTargetView::Clear(float r, float g, float b, float a, float depth, uint8_t stencil) {
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, m_framebuffer);
|
||||
glClearColor(r, g, b, a);
|
||||
glClearDepth(depth);
|
||||
glClearStencil(stencil);
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
|
||||
}
|
||||
|
||||
void OpenGLRenderTargetView::BindFramebuffer(unsigned int framebuffer) {
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
|
||||
}
|
||||
|
||||
void OpenGLRenderTargetView::UnbindFramebuffer() {
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||
}
|
||||
|
||||
} // namespace RHI
|
||||
} // namespace XCEngine
|
||||
|
||||
Reference in New Issue
Block a user