GPU: Implement transparency mode
This commit is contained in:
parent
23ef1cafbd
commit
d84bffead1
|
@ -304,6 +304,7 @@ void SDLInterface::RenderDisplay()
|
||||||
return;
|
return;
|
||||||
|
|
||||||
glViewport(0, 0, m_window_width, m_window_height - 20);
|
glViewport(0, 0, m_window_width, m_window_height - 20);
|
||||||
|
glDisable(GL_BLEND);
|
||||||
glDisable(GL_CULL_FACE);
|
glDisable(GL_CULL_FACE);
|
||||||
glDisable(GL_DEPTH_TEST);
|
glDisable(GL_DEPTH_TEST);
|
||||||
glDisable(GL_SCISSOR_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_GPUSTAT.texture_disable = (param & (UINT32_C(1) << 11)) != 0;
|
||||||
m_texture_config.x_flip = (param & (UINT32_C(1) << 12)) != 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.y_flip = (param & (UINT32_C(1) << 13)) != 0;
|
||||||
m_texture_config.SetColorMode(m_GPUSTAT.texture_color_mode);
|
|
||||||
Log_DebugPrintf("Set draw mode %08X", param);
|
Log_DebugPrintf("Set draw mode %08X", param);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -749,18 +748,6 @@ void GPU::DispatchRenderCommand(RenderCommand rc, u32 num_vertices) {}
|
||||||
|
|
||||||
void GPU::FlushRender() {}
|
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)
|
void GPU::TextureConfig::SetFromPolygonTexcoord(u32 texcoord0, u32 texcoord1)
|
||||||
{
|
{
|
||||||
SetFromPaletteAttribute(Truncate16(texcoord0 >> 16));
|
SetFromPaletteAttribute(Truncate16(texcoord0 >> 16));
|
||||||
|
@ -778,11 +765,16 @@ void GPU::TextureConfig::SetFromPageAttribute(u16 value)
|
||||||
if (page_attribute == value)
|
if (page_attribute == value)
|
||||||
return;
|
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_attribute = value;
|
||||||
page_changed = true;
|
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)
|
void GPU::TextureConfig::SetFromPaletteAttribute(u16 value)
|
||||||
|
|
|
@ -110,6 +110,14 @@ protected:
|
||||||
Reserved_Direct16Bit = 3
|
Reserved_Direct16Bit = 3
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum class TransparencyMode : u8
|
||||||
|
{
|
||||||
|
HalfBackgroundPlusHalfForeground = 0,
|
||||||
|
BackgroundPlusForeground = 1,
|
||||||
|
BackgroundMinusForeground = 2,
|
||||||
|
BackgroundPlusQuarterForeground = 3
|
||||||
|
};
|
||||||
|
|
||||||
union RenderCommand
|
union RenderCommand
|
||||||
{
|
{
|
||||||
u32 bits;
|
u32 bits;
|
||||||
|
@ -127,6 +135,7 @@ protected:
|
||||||
// Helper functions.
|
// Helper functions.
|
||||||
bool IsTextureEnabled() const { return (primitive != Primitive::Line && texture_enable); }
|
bool IsTextureEnabled() const { return (primitive != Primitive::Line && texture_enable); }
|
||||||
bool IsTextureBlendingEnabled() const { return (IsTextureEnabled() && !texture_blend_disable); }
|
bool IsTextureBlendingEnabled() const { return (IsTextureEnabled() && !texture_blend_disable); }
|
||||||
|
bool IsTransparencyEnabled() const { return transparency_enable; }
|
||||||
};
|
};
|
||||||
|
|
||||||
// TODO: Use BitField to do sign extending instead
|
// TODO: Use BitField to do sign extending instead
|
||||||
|
@ -181,7 +190,7 @@ protected:
|
||||||
u32 bits;
|
u32 bits;
|
||||||
BitField<u32, u8, 0, 4> texture_page_x_base;
|
BitField<u32, u8, 0, 4> texture_page_x_base;
|
||||||
BitField<u32, u8, 4, 1> texture_page_y_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, TextureColorMode, 7, 2> texture_color_mode;
|
||||||
BitField<u32, bool, 9, 1> dither_enable;
|
BitField<u32, bool, 9, 1> dither_enable;
|
||||||
BitField<u32, bool, 10, 1> draw_to_display_area;
|
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 page_attribute; // from register in rectangle modes/vertex in polygon modes
|
||||||
u16 palette_attribute; // from vertex
|
u16 palette_attribute; // from vertex
|
||||||
TextureColorMode color_mode; // from register/vertex in polygon modes
|
TextureColorMode color_mode; // from register/vertex in polygon modes
|
||||||
|
TransparencyMode transparency_mode;
|
||||||
|
|
||||||
bool page_changed = false;
|
bool page_changed = false;
|
||||||
|
|
||||||
bool IsPageChanged() const { return page_changed; }
|
bool IsPageChanged() const { return page_changed; }
|
||||||
void ClearPageChangedFlag() { page_changed = false; }
|
void ClearPageChangedFlag() { page_changed = false; }
|
||||||
|
|
||||||
void SetColorMode(TextureColorMode new_color_mode);
|
|
||||||
|
|
||||||
void SetFromPolygonTexcoord(u32 texcoord0, u32 texcoord1);
|
void SetFromPolygonTexcoord(u32 texcoord0, u32 texcoord1);
|
||||||
void SetFromRectangleTexcoord(u32 texcoord);
|
void SetFromRectangleTexcoord(u32 texcoord);
|
||||||
|
|
||||||
|
|
|
@ -191,6 +191,36 @@ void GPU_HW_OpenGL::SetScissor()
|
||||||
glScissor(x, y, width, height);
|
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()
|
void GPU_HW_OpenGL::UpdateDisplay()
|
||||||
{
|
{
|
||||||
GPU_HW::UpdateDisplay();
|
GPU_HW::UpdateDisplay();
|
||||||
|
@ -322,6 +352,7 @@ void GPU_HW_OpenGL::FlushRender()
|
||||||
SetProgram(m_batch_command.IsTextureEnabled(), m_batch_command.IsTextureBlendingEnabled());
|
SetProgram(m_batch_command.IsTextureEnabled(), m_batch_command.IsTextureBlendingEnabled());
|
||||||
SetViewport();
|
SetViewport();
|
||||||
SetScissor();
|
SetScissor();
|
||||||
|
SetBlendState();
|
||||||
|
|
||||||
glBindFramebuffer(GL_FRAMEBUFFER, m_framebuffer_fbo_id);
|
glBindFramebuffer(GL_FRAMEBUFFER, m_framebuffer_fbo_id);
|
||||||
glBindVertexArray(m_vao_id);
|
glBindVertexArray(m_vao_id);
|
||||||
|
|
|
@ -40,6 +40,7 @@ private:
|
||||||
void SetProgram(bool textured, bool blending);
|
void SetProgram(bool textured, bool blending);
|
||||||
void SetViewport();
|
void SetViewport();
|
||||||
void SetScissor();
|
void SetScissor();
|
||||||
|
void SetBlendState();
|
||||||
|
|
||||||
std::unique_ptr<GL::Texture> m_framebuffer_texture;
|
std::unique_ptr<GL::Texture> m_framebuffer_texture;
|
||||||
GLuint m_framebuffer_fbo_id = 0;
|
GLuint m_framebuffer_fbo_id = 0;
|
||||||
|
|
Loading…
Reference in New Issue