mirror of
https://github.com/wheremyfoodat/Panda3DS.git
synced 2025-04-08 23:25:40 +12:00
[GL] More state stuff
This commit is contained in:
parent
64fa970468
commit
adb78bf838
4 changed files with 67 additions and 7 deletions
|
@ -1,6 +1,7 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
#include <type_traits>
|
#include <type_traits>
|
||||||
|
|
||||||
|
#include "helpers.hpp"
|
||||||
#include "opengl.hpp"
|
#include "opengl.hpp"
|
||||||
|
|
||||||
// GL state manager object for use in the OpenGL GPU renderer and potentially other things in the future (such as a potential ImGui GUI)
|
// GL state manager object for use in the OpenGL GPU renderer and potentially other things in the future (such as a potential ImGui GUI)
|
||||||
|
@ -18,10 +19,16 @@
|
||||||
// backend-agnostic as possible
|
// backend-agnostic as possible
|
||||||
|
|
||||||
struct GLStateManager {
|
struct GLStateManager {
|
||||||
|
// We only support 6 clipping planes in our state manager because that's the minimum for GL_MAX_CLIP_PLANES
|
||||||
|
// And nobody needs more than 6 clip planes anyways
|
||||||
|
static constexpr GLint clipPlaneCount = 6;
|
||||||
|
|
||||||
bool blendEnabled;
|
bool blendEnabled;
|
||||||
|
bool logicOpEnabled;
|
||||||
bool depthEnabled;
|
bool depthEnabled;
|
||||||
bool scissorEnabled;
|
bool scissorEnabled;
|
||||||
bool stencilEnabled;
|
bool stencilEnabled;
|
||||||
|
u32 enabledClipPlanes; // Bitfield of enabled clip planes
|
||||||
|
|
||||||
// Colour/depth masks
|
// Colour/depth masks
|
||||||
bool redMask, greenMask, blueMask, alphaMask;
|
bool redMask, greenMask, blueMask, alphaMask;
|
||||||
|
@ -35,6 +42,7 @@ struct GLStateManager {
|
||||||
|
|
||||||
void reset();
|
void reset();
|
||||||
void resetBlend();
|
void resetBlend();
|
||||||
|
void resetClipping();
|
||||||
void resetColourMask();
|
void resetColourMask();
|
||||||
void resetDepth();
|
void resetDepth();
|
||||||
void resetVAO();
|
void resetVAO();
|
||||||
|
@ -99,6 +107,42 @@ struct GLStateManager {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void enableLogicOp() {
|
||||||
|
if (!logicOpEnabled) {
|
||||||
|
logicOpEnabled = true;
|
||||||
|
OpenGL::enableLogicOp();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void disableLogicOp() {
|
||||||
|
if (logicOpEnabled) {
|
||||||
|
logicOpEnabled = false;
|
||||||
|
OpenGL::disableLogicOp();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void enableClipPlane(GLuint index) {
|
||||||
|
if (index >= clipPlaneCount) [[unlikely]] {
|
||||||
|
Helpers::panic("Enabled invalid clipping plane %d\n", index);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((enabledClipPlanes & (1 << index)) == 0) {
|
||||||
|
enabledClipPlanes |= 1 << index; // Enable relevant bit in clipping plane bitfield
|
||||||
|
OpenGL::enableClipPlane(index); // Enable plane
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void disableClipPlane(GLuint index) {
|
||||||
|
if (index >= clipPlaneCount) [[unlikely]] {
|
||||||
|
Helpers::panic("Disabled invalid clipping plane %d\n", index);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((enabledClipPlanes & (1 << index)) != 0) {
|
||||||
|
enabledClipPlanes ^= 1 << index; // Disable relevant bit in bitfield by flipping it
|
||||||
|
OpenGL::disableClipPlane(index); // Disable plane
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void bindVAO(GLuint handle) {
|
void bindVAO(GLuint handle) {
|
||||||
if (boundVAO != handle) {
|
if (boundVAO != handle) {
|
||||||
boundVAO = handle;
|
boundVAO = handle;
|
||||||
|
|
|
@ -519,6 +519,8 @@ namespace OpenGL {
|
||||||
static void disableScissor() { glDisable(GL_SCISSOR_TEST); }
|
static void disableScissor() { glDisable(GL_SCISSOR_TEST); }
|
||||||
static void enableBlend() { glEnable(GL_BLEND); }
|
static void enableBlend() { glEnable(GL_BLEND); }
|
||||||
static void disableBlend() { glDisable(GL_BLEND); }
|
static void disableBlend() { glDisable(GL_BLEND); }
|
||||||
|
static void enableLogicOp() { glEnable(GL_COLOR_LOGIC_OP); }
|
||||||
|
static void disableLogicOp() { glDisable(GL_COLOR_LOGIC_OP); }
|
||||||
static void enableDepth() { glEnable(GL_DEPTH_TEST); }
|
static void enableDepth() { glEnable(GL_DEPTH_TEST); }
|
||||||
static void disableDepth() { glDisable(GL_DEPTH_TEST); }
|
static void disableDepth() { glDisable(GL_DEPTH_TEST); }
|
||||||
static void enableStencil() { glEnable(GL_STENCIL_TEST); }
|
static void enableStencil() { glEnable(GL_STENCIL_TEST); }
|
||||||
|
|
|
@ -2,7 +2,18 @@
|
||||||
|
|
||||||
void GLStateManager::resetBlend() {
|
void GLStateManager::resetBlend() {
|
||||||
blendEnabled = false;
|
blendEnabled = false;
|
||||||
|
logicOpEnabled = false;
|
||||||
|
|
||||||
OpenGL::disableBlend();
|
OpenGL::disableBlend();
|
||||||
|
OpenGL::disableLogicOp();
|
||||||
|
}
|
||||||
|
|
||||||
|
void GLStateManager::resetClipping() {
|
||||||
|
// Disable all (supported) clip planes
|
||||||
|
enabledClipPlanes = 0;
|
||||||
|
for (int i = 0; i < clipPlaneCount; i++) {
|
||||||
|
OpenGL::disableClipPlane(i);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void GLStateManager::resetColourMask() {
|
void GLStateManager::resetColourMask() {
|
||||||
|
@ -48,6 +59,7 @@ void GLStateManager::resetProgram() {
|
||||||
|
|
||||||
void GLStateManager::reset() {
|
void GLStateManager::reset() {
|
||||||
resetBlend();
|
resetBlend();
|
||||||
|
resetClipping();
|
||||||
resetColourMask();
|
resetColourMask();
|
||||||
resetDepth();
|
resetDepth();
|
||||||
|
|
||||||
|
|
|
@ -185,10 +185,12 @@ void RendererGL::setupBlending() {
|
||||||
if (!blendingEnabled) { // Logic ops are enabled
|
if (!blendingEnabled) { // Logic ops are enabled
|
||||||
const u32 logicOp = getBits<0, 4>(regs[PICA::InternalRegs::LogicOp]);
|
const u32 logicOp = getBits<0, 4>(regs[PICA::InternalRegs::LogicOp]);
|
||||||
glLogicOp(logicOps[logicOp]);
|
glLogicOp(logicOps[logicOp]);
|
||||||
glEnable(GL_COLOR_LOGIC_OP);
|
|
||||||
|
// If logic ops are enabled we don't need to disable blending because they override it
|
||||||
|
gl.enableLogicOp();
|
||||||
} else {
|
} else {
|
||||||
gl.enableBlend();
|
gl.enableBlend();
|
||||||
glDisable(GL_COLOR_LOGIC_OP);
|
gl.disableLogicOp();
|
||||||
|
|
||||||
// Get blending equations
|
// Get blending equations
|
||||||
const u32 blendControl = regs[PICA::InternalRegs::BlendFunc];
|
const u32 blendControl = regs[PICA::InternalRegs::BlendFunc];
|
||||||
|
@ -359,9 +361,9 @@ void RendererGL::drawVertices(PICA::PrimType primType, std::span<const Vertex> v
|
||||||
gl.bindVAO(vao);
|
gl.bindVAO(vao);
|
||||||
gl.useProgram(triangleProgram);
|
gl.useProgram(triangleProgram);
|
||||||
|
|
||||||
OpenGL::enableClipPlane(0); // Clipping plane 0 is always enabled
|
gl.enableClipPlane(0); // Clipping plane 0 is always enabled
|
||||||
if (regs[PICA::InternalRegs::ClipEnable] & 1) {
|
if (regs[PICA::InternalRegs::ClipEnable] & 1) {
|
||||||
OpenGL::enableClipPlane(1);
|
gl.enableClipPlane(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
setupBlending();
|
setupBlending();
|
||||||
|
@ -563,7 +565,7 @@ void RendererGL::displayTransfer(u32 inputAddr, u32 outputAddr, u32 inputSize, u
|
||||||
screenFramebuffer.bind(OpenGL::DrawFramebuffer);
|
screenFramebuffer.bind(OpenGL::DrawFramebuffer);
|
||||||
|
|
||||||
gl.disableBlend();
|
gl.disableBlend();
|
||||||
glDisable(GL_COLOR_LOGIC_OP);
|
gl.disableLogicOp();
|
||||||
gl.disableDepth();
|
gl.disableDepth();
|
||||||
gl.disableScissor();
|
gl.disableScissor();
|
||||||
gl.disableStencil();
|
gl.disableStencil();
|
||||||
|
@ -571,8 +573,8 @@ void RendererGL::displayTransfer(u32 inputAddr, u32 outputAddr, u32 inputSize, u
|
||||||
gl.useProgram(displayProgram);
|
gl.useProgram(displayProgram);
|
||||||
gl.bindVAO(dummyVAO);
|
gl.bindVAO(dummyVAO);
|
||||||
|
|
||||||
OpenGL::disableClipPlane(0);
|
gl.disableClipPlane(0);
|
||||||
OpenGL::disableClipPlane(1);
|
gl.disableClipPlane(1);
|
||||||
|
|
||||||
// Hack: Detect whether we are writing to the top or bottom screen by checking output gap and drawing to the proper part of the output texture
|
// Hack: Detect whether we are writing to the top or bottom screen by checking output gap and drawing to the proper part of the output texture
|
||||||
// We consider output gap == 320 to mean bottom, and anything else to mean top
|
// We consider output gap == 320 to mean bottom, and anything else to mean top
|
||||||
|
|
Loading…
Add table
Reference in a new issue