mirror of
https://github.com/wheremyfoodat/Panda3DS.git
synced 2025-04-09 07:35:41 +12:00
[PICA] Depth buffering v1
This commit is contained in:
parent
d79fd1e198
commit
eaab13b264
3 changed files with 67 additions and 7 deletions
|
@ -72,12 +72,19 @@ public:
|
||||||
void setColourFormat(u32 format) { colourBufferFormat = static_cast<ColourBuffer::Formats>(format); }
|
void setColourFormat(u32 format) { colourBufferFormat = static_cast<ColourBuffer::Formats>(format); }
|
||||||
|
|
||||||
void setDepthFormat(DepthBuffer::Formats format) { depthBufferFormat = format; }
|
void setDepthFormat(DepthBuffer::Formats format) { depthBufferFormat = format; }
|
||||||
void setDepthFormat(u32 format) { depthBufferFormat = static_cast<DepthBuffer::Formats>(format); }
|
void setDepthFormat(u32 format) {
|
||||||
|
if (format == 2) {
|
||||||
|
Helpers::panic("[PICA] Undocumented depth-stencil mode!");
|
||||||
|
}
|
||||||
|
|
||||||
|
depthBufferFormat = static_cast<DepthBuffer::Formats>(format);
|
||||||
|
}
|
||||||
|
|
||||||
void setColourBufferLoc(u32 loc) { colourBufferLoc = loc; }
|
void setColourBufferLoc(u32 loc) { colourBufferLoc = loc; }
|
||||||
void setDepthBufferLoc(u32 loc) { depthBufferLoc = loc; }
|
void setDepthBufferLoc(u32 loc) { depthBufferLoc = loc; }
|
||||||
|
|
||||||
void setupBlending();
|
void setupBlending();
|
||||||
|
void bindDepthBuffer();
|
||||||
|
|
||||||
static constexpr u32 vertexBufferSize = 0x1500;
|
static constexpr u32 vertexBufferSize = 0x1500;
|
||||||
};
|
};
|
|
@ -40,13 +40,13 @@ struct ColourBuffer {
|
||||||
|
|
||||||
void allocate() {
|
void allocate() {
|
||||||
// Create texture for the FBO, setting up filters and the like
|
// Create texture for the FBO, setting up filters and the like
|
||||||
// Reading back the current texture is slow, but allocate calls should be and far between.
|
// Reading back the current texture is slow, but allocate calls should be few and far between.
|
||||||
// If this becomes a bottleneck, we can fix it semi-easily
|
// If this becomes a bottleneck, we can fix it semi-easily
|
||||||
auto prevTexture = OpenGL::getTex2D();
|
auto prevTexture = OpenGL::getTex2D();
|
||||||
texture.create(size.x(), size.y(), GL_RGBA8);
|
texture.create(size.x(), size.y(), GL_RGBA8);
|
||||||
texture.bind();
|
texture.bind();
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
texture.setMinFilter(OpenGL::Linear);
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
texture.setMagFilter(OpenGL::Linear);
|
||||||
glBindTexture(GL_TEXTURE_2D, prevTexture);
|
glBindTexture(GL_TEXTURE_2D, prevTexture);
|
||||||
|
|
||||||
//Helpers::panic("Creating FBO: %d, %d\n", size.x(), size.y());
|
//Helpers::panic("Creating FBO: %d, %d\n", size.x(), size.y());
|
||||||
|
@ -115,14 +115,47 @@ struct DepthBuffer {
|
||||||
DepthBuffer() : valid(false) {}
|
DepthBuffer() : valid(false) {}
|
||||||
|
|
||||||
DepthBuffer(u32 loc, Formats format, u32 x, u32 y, bool valid = true) :
|
DepthBuffer(u32 loc, Formats format, u32 x, u32 y, bool valid = true) :
|
||||||
location(loc), format(format), size({x, y}), valid(valid) {}
|
location(loc), format(format), size({x, y}), valid(valid) {
|
||||||
|
|
||||||
|
u64 endLoc = (u64)loc + sizeInBytes();
|
||||||
|
// Check if start and end are valid here
|
||||||
|
range = Interval<u32>(loc, (u32)endLoc);
|
||||||
|
}
|
||||||
|
|
||||||
bool hasStencil() {
|
bool hasStencil() {
|
||||||
return format == Formats::Depth24Stencil8;
|
return format == Formats::Depth24Stencil8;
|
||||||
}
|
}
|
||||||
|
|
||||||
void allocate() {
|
void allocate() {
|
||||||
printf("Make this depth buffer allocate itself\n");
|
// Create texture for the FBO, setting up filters and the like
|
||||||
|
// Reading back the current texture is slow, but allocate calls should be few and far between.
|
||||||
|
// If this becomes a bottleneck, we can fix it semi-easily
|
||||||
|
auto prevTexture = OpenGL::getTex2D();
|
||||||
|
|
||||||
|
// Internal formats for the texture based on format
|
||||||
|
static constexpr std::array<GLenum, 4> internalFormats = {
|
||||||
|
GL_DEPTH_COMPONENT16, GL_DEPTH_COMPONENT24, GL_DEPTH_COMPONENT24, GL_DEPTH24_STENCIL8
|
||||||
|
};
|
||||||
|
|
||||||
|
// Format of the texture
|
||||||
|
static constexpr std::array<GLenum, 4> formats = {
|
||||||
|
GL_DEPTH_COMPONENT, GL_DEPTH_COMPONENT, GL_DEPTH_COMPONENT, GL_DEPTH_STENCIL
|
||||||
|
};
|
||||||
|
|
||||||
|
static constexpr std::array<GLenum, 4> types = {
|
||||||
|
GL_FLOAT, GL_FLOAT, GL_FLOAT, GL_UNSIGNED_INT_24_8
|
||||||
|
};
|
||||||
|
|
||||||
|
auto internalFormat = internalFormats[(int)format];
|
||||||
|
auto fmt = formats[(int)format];
|
||||||
|
auto type = types[(int)format];
|
||||||
|
|
||||||
|
texture.createDSTexture(size.x(), size.y(), internalFormat, fmt, nullptr, type);
|
||||||
|
texture.bind();
|
||||||
|
texture.setMinFilter(OpenGL::Linear);
|
||||||
|
texture.setMagFilter(OpenGL::Linear);
|
||||||
|
|
||||||
|
glBindTexture(GL_TEXTURE_2D, prevTexture);
|
||||||
}
|
}
|
||||||
|
|
||||||
void free() {
|
void free() {
|
||||||
|
|
|
@ -291,14 +291,18 @@ void Renderer::drawVertices(OpenGL::Primitives primType, Vertex* vertices, u32 c
|
||||||
float viewportHeight = f24::fromRaw(regs[PICAInternalRegs::ViewportHeight] & 0xffffff).toFloat32() * 2.0;
|
float viewportHeight = f24::fromRaw(regs[PICAInternalRegs::ViewportHeight] & 0xffffff).toFloat32() * 2.0;
|
||||||
OpenGL::setViewport(viewportWidth, viewportHeight);
|
OpenGL::setViewport(viewportWidth, viewportHeight);
|
||||||
|
|
||||||
|
// Note: The code below must execute after we've bound the colour buffer & its framebuffer
|
||||||
|
// Because it attaches a depth texture to the aforementioned colour buffer
|
||||||
if (depthEnable) {
|
if (depthEnable) {
|
||||||
OpenGL::enableDepth();
|
OpenGL::enableDepth();
|
||||||
glDepthFunc(depthModes[depthFunc]);
|
glDepthFunc(depthModes[depthFunc]);
|
||||||
glDepthMask(depthWriteEnable ? GL_TRUE : GL_FALSE);
|
glDepthMask(depthWriteEnable ? GL_TRUE : GL_FALSE);
|
||||||
|
bindDepthBuffer();
|
||||||
} else {
|
} else {
|
||||||
if (depthWriteEnable) {
|
if (depthWriteEnable) {
|
||||||
OpenGL::enableDepth();
|
OpenGL::enableDepth();
|
||||||
glDepthFunc(GL_ALWAYS);
|
glDepthFunc(GL_ALWAYS);
|
||||||
|
bindDepthBuffer();
|
||||||
} else {
|
} else {
|
||||||
OpenGL::disableDepth();
|
OpenGL::disableDepth();
|
||||||
}
|
}
|
||||||
|
@ -364,8 +368,24 @@ OpenGL::Framebuffer Renderer::getColourFBO() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Renderer::bindDepthBuffer() {
|
||||||
|
// Similar logic as the getColourFBO function
|
||||||
|
DepthBuffer sampleBuffer(depthBufferLoc, depthBufferFormat, fbSize.x(), fbSize.y());
|
||||||
|
auto buffer = depthBufferCache.find(sampleBuffer);
|
||||||
|
GLuint tex;
|
||||||
|
|
||||||
|
if (buffer.has_value()) {
|
||||||
|
tex = buffer.value().get().texture.m_handle;
|
||||||
|
} else {
|
||||||
|
tex = depthBufferCache.add(sampleBuffer).texture.m_handle;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto attachment = depthBufferFormat == DepthBuffer::Formats::Depth24Stencil8 ? GL_DEPTH_STENCIL_ATTACHMENT : GL_DEPTH_ATTACHMENT;
|
||||||
|
glFramebufferTexture2D(GL_FRAMEBUFFER, attachment, GL_TEXTURE_2D, tex, 0);
|
||||||
|
}
|
||||||
|
|
||||||
OpenGL::Texture Renderer::getTexture(Texture& tex) {
|
OpenGL::Texture Renderer::getTexture(Texture& tex) {
|
||||||
// Similar logic as the getColourFBO/getDepthBuffer functions
|
// Similar logic as the getColourFBO/bindDepthBuffer functions
|
||||||
auto buffer = textureCache.find(tex);
|
auto buffer = textureCache.find(tex);
|
||||||
|
|
||||||
if (buffer.has_value()) {
|
if (buffer.has_value()) {
|
||||||
|
|
Loading…
Add table
Reference in a new issue