GPU: Implement transparency mode
This commit is contained in:
parent
23ef1cafbd
commit
d84bffead1
|
@ -304,6 +304,7 @@ void SDLInterface::RenderDisplay()
|
|||
return;
|
||||
|
||||
glViewport(0, 0, m_window_width, m_window_height - 20);
|
||||
glDisable(GL_BLEND);
|
||||
glDisable(GL_CULL_FACE);
|
||||
glDisable(GL_DEPTH_TEST);
|
||||
glDisable(GL_SCISSOR_TEST);
|
||||
|
|
|
@ -388,7 +388,6 @@ void GPU::WriteGP0(u32 value)
|
|||
m_GPUSTAT.texture_disable = (param & (UINT32_C(1) << 11)) != 0;
|
||||
m_texture_config.x_flip = (param & (UINT32_C(1) << 12)) != 0;
|
||||
m_texture_config.y_flip = (param & (UINT32_C(1) << 13)) != 0;
|
||||
m_texture_config.SetColorMode(m_GPUSTAT.texture_color_mode);
|
||||
Log_DebugPrintf("Set draw mode %08X", param);
|
||||
}
|
||||
break;
|
||||
|
@ -749,18 +748,6 @@ void GPU::DispatchRenderCommand(RenderCommand rc, u32 num_vertices) {}
|
|||
|
||||
void GPU::FlushRender() {}
|
||||
|
||||
void GPU::TextureConfig::SetColorMode(TextureColorMode new_color_mode)
|
||||
{
|
||||
if (new_color_mode == TextureColorMode::Reserved_Direct16Bit)
|
||||
new_color_mode = TextureColorMode::Direct16Bit;
|
||||
|
||||
if (color_mode == new_color_mode)
|
||||
return;
|
||||
|
||||
color_mode = new_color_mode;
|
||||
page_changed = true;
|
||||
}
|
||||
|
||||
void GPU::TextureConfig::SetFromPolygonTexcoord(u32 texcoord0, u32 texcoord1)
|
||||
{
|
||||
SetFromPaletteAttribute(Truncate16(texcoord0 >> 16));
|
||||
|
@ -778,11 +765,16 @@ void GPU::TextureConfig::SetFromPageAttribute(u16 value)
|
|||
if (page_attribute == value)
|
||||
return;
|
||||
|
||||
base_x = static_cast<s32>(ZeroExtend32(value & UINT16_C(0x0F)) * UINT32_C(64));
|
||||
base_y = static_cast<s32>(ZeroExtend32((value >> 11) & UINT16_C(1)) * UINT32_C(512));
|
||||
SetColorMode(static_cast<TextureColorMode>((value >> 7) & UINT16_C(0x03)));
|
||||
page_attribute = value;
|
||||
page_changed = true;
|
||||
|
||||
base_x = static_cast<s32>(ZeroExtend32(value & UINT16_C(0x0F)) * UINT32_C(64));
|
||||
base_y = static_cast<s32>(ZeroExtend32((value >> 11) & UINT16_C(1)) * UINT32_C(512));
|
||||
color_mode = (static_cast<TextureColorMode>((value >> 7) & UINT16_C(0x03)));
|
||||
if (color_mode == TextureColorMode::Reserved_Direct16Bit)
|
||||
color_mode = TextureColorMode::Direct16Bit;
|
||||
|
||||
transparency_mode = (static_cast<TransparencyMode>((value >> 5) & UINT16_C(0x03)));
|
||||
}
|
||||
|
||||
void GPU::TextureConfig::SetFromPaletteAttribute(u16 value)
|
||||
|
|
|
@ -110,6 +110,14 @@ protected:
|
|||
Reserved_Direct16Bit = 3
|
||||
};
|
||||
|
||||
enum class TransparencyMode : u8
|
||||
{
|
||||
HalfBackgroundPlusHalfForeground = 0,
|
||||
BackgroundPlusForeground = 1,
|
||||
BackgroundMinusForeground = 2,
|
||||
BackgroundPlusQuarterForeground = 3
|
||||
};
|
||||
|
||||
union RenderCommand
|
||||
{
|
||||
u32 bits;
|
||||
|
@ -127,6 +135,7 @@ protected:
|
|||
// Helper functions.
|
||||
bool IsTextureEnabled() const { return (primitive != Primitive::Line && texture_enable); }
|
||||
bool IsTextureBlendingEnabled() const { return (IsTextureEnabled() && !texture_blend_disable); }
|
||||
bool IsTransparencyEnabled() const { return transparency_enable; }
|
||||
};
|
||||
|
||||
// TODO: Use BitField to do sign extending instead
|
||||
|
@ -181,7 +190,7 @@ protected:
|
|||
u32 bits;
|
||||
BitField<u32, u8, 0, 4> texture_page_x_base;
|
||||
BitField<u32, u8, 4, 1> texture_page_y_base;
|
||||
BitField<u32, u8, 5, 2> semi_transparency;
|
||||
BitField<u32, TransparencyMode, 5, 2> semi_transparency_mode;
|
||||
BitField<u32, TextureColorMode, 7, 2> texture_color_mode;
|
||||
BitField<u32, bool, 9, 1> dither_enable;
|
||||
BitField<u32, bool, 10, 1> draw_to_display_area;
|
||||
|
@ -221,14 +230,13 @@ protected:
|
|||
u16 page_attribute; // from register in rectangle modes/vertex in polygon modes
|
||||
u16 palette_attribute; // from vertex
|
||||
TextureColorMode color_mode; // from register/vertex in polygon modes
|
||||
TransparencyMode transparency_mode;
|
||||
|
||||
bool page_changed = false;
|
||||
|
||||
bool IsPageChanged() const { return page_changed; }
|
||||
void ClearPageChangedFlag() { page_changed = false; }
|
||||
|
||||
void SetColorMode(TextureColorMode new_color_mode);
|
||||
|
||||
void SetFromPolygonTexcoord(u32 texcoord0, u32 texcoord1);
|
||||
void SetFromRectangleTexcoord(u32 texcoord);
|
||||
|
||||
|
|
|
@ -191,6 +191,36 @@ void GPU_HW_OpenGL::SetScissor()
|
|||
glScissor(x, y, width, height);
|
||||
}
|
||||
|
||||
void GPU_HW_OpenGL::SetBlendState()
|
||||
{
|
||||
struct BlendVars
|
||||
{
|
||||
GLenum src_factor;
|
||||
GLenum func;
|
||||
GLenum dst_factor;
|
||||
float color;
|
||||
};
|
||||
static const std::array<BlendVars, 4> blend_vars = {{
|
||||
{GL_CONSTANT_COLOR, GL_FUNC_ADD, GL_CONSTANT_COLOR, 0.5f}, // B/2 + F/2
|
||||
{GL_ONE, GL_FUNC_ADD, GL_ONE, -1.0f}, // B + F
|
||||
{GL_ONE, GL_FUNC_REVERSE_SUBTRACT, GL_ONE, -1.0f}, // B - F
|
||||
{GL_CONSTANT_COLOR, GL_FUNC_ADD, GL_ONE, 0.25f} // B + F/4
|
||||
}};
|
||||
|
||||
if (!m_batch_command.IsTransparencyEnabled())
|
||||
{
|
||||
glDisable(GL_BLEND);
|
||||
return;
|
||||
}
|
||||
|
||||
const BlendVars& vars = blend_vars[static_cast<u8>(m_texture_config.transparency_mode)];
|
||||
glEnable(GL_BLEND);
|
||||
glBlendFuncSeparate(vars.src_factor, vars.dst_factor, GL_ONE, GL_ZERO);
|
||||
glBlendEquationSeparate(vars.func, GL_FUNC_ADD);
|
||||
if (vars.color >= 0.0f)
|
||||
glBlendColor(vars.color, vars.color, vars.color, 1.0f);
|
||||
}
|
||||
|
||||
void GPU_HW_OpenGL::UpdateDisplay()
|
||||
{
|
||||
GPU_HW::UpdateDisplay();
|
||||
|
@ -322,6 +352,7 @@ void GPU_HW_OpenGL::FlushRender()
|
|||
SetProgram(m_batch_command.IsTextureEnabled(), m_batch_command.IsTextureBlendingEnabled());
|
||||
SetViewport();
|
||||
SetScissor();
|
||||
SetBlendState();
|
||||
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, m_framebuffer_fbo_id);
|
||||
glBindVertexArray(m_vao_id);
|
||||
|
|
|
@ -40,6 +40,7 @@ private:
|
|||
void SetProgram(bool textured, bool blending);
|
||||
void SetViewport();
|
||||
void SetScissor();
|
||||
void SetBlendState();
|
||||
|
||||
std::unique_ptr<GL::Texture> m_framebuffer_texture;
|
||||
GLuint m_framebuffer_fbo_id = 0;
|
||||
|
|
Loading…
Reference in New Issue