various sprite fixes (#1185)

This commit is contained in:
water111
2022-02-19 20:43:03 -05:00
committed by GitHub
parent eebbe00ce4
commit bbb7213281
8 changed files with 51 additions and 45 deletions
+3 -2
View File
@@ -362,8 +362,9 @@ class DrawMode {
DISABLED = 0,
SRC_DST_SRC_DST = 1,
SRC_0_SRC_DST = 2,
SRC_0_FIX_DST = 3, // fix = 128
SRC_DST_FIX_DST = 4 // fix = 64
SRC_0_FIX_DST = 3, // fix = 128
SRC_DST_FIX_DST = 4, // fix = 64
ZERO_SRC_SRC_DST = 5,
};
enum class AlphaTest {
@@ -71,7 +71,9 @@ RenderMux::RenderMux(const std::string& name,
: BucketRenderer(name, my_id), m_renderers(std::move(renderers)) {
for (auto& r : m_renderers) {
m_name_strs.push_back(r->name_and_id());
m_name_str_ptrs.push_back(m_name_strs.back().data());
}
for (auto& n : m_name_strs) {
m_name_str_ptrs.push_back(n.data());
}
}
@@ -196,8 +196,9 @@ void OpenGLRenderer::init_bucket_renderers() {
init_bucket_renderer<TextureUploadHandler>("pre-sprite-tex", BucketId::PRE_SPRITE_TEX); // 65
std::vector<std::unique_ptr<BucketRenderer>> sprite_renderers;
sprite_renderers.push_back(std::make_unique<SpriteRenderer>("sprite-renderer", BucketId::SPRITE));
// the first renderer added will be the default for sprite.
sprite_renderers.push_back(std::make_unique<Sprite3>("sprite-3", BucketId::SPRITE));
sprite_renderers.push_back(std::make_unique<SpriteRenderer>("sprite-renderer", BucketId::SPRITE));
init_bucket_renderer<RenderMux>("sprite", BucketId::SPRITE, std::move(sprite_renderers)); // 66
init_bucket_renderer<DirectRenderer>("debug-draw-0", BucketId::DEBUG_DRAW_0, 0x20000,
+30 -15
View File
@@ -453,11 +453,10 @@ void Sprite3::flush_sprites(SharedRenderState* render_state,
// two passes through the buckets. first to build the index buffer
u32 idx_offset = 0;
for (auto& kv : m_sprite_buckets) {
memcpy(&m_index_buffer_data[idx_offset], kv.second.ids.data(),
kv.second.ids.size() * sizeof(u32));
kv.second.offset_in_idx_buffer = idx_offset;
idx_offset += kv.second.ids.size();
for (const auto bucket : m_bucket_list) {
memcpy(&m_index_buffer_data[idx_offset], bucket->ids.data(), bucket->ids.size() * sizeof(u32));
bucket->offset_in_idx_buffer = idx_offset;
idx_offset += bucket->ids.size();
}
// now upload it
@@ -466,10 +465,10 @@ void Sprite3::flush_sprites(SharedRenderState* render_state,
GL_STREAM_DRAW);
// now do draws!
for (auto& kv : m_sprite_buckets) {
u32 tbp = kv.first >> 32;
for (const auto bucket : m_bucket_list) {
u32 tbp = bucket->key >> 32;
DrawMode mode;
mode.as_int() = kv.first & 0xffffffff;
mode.as_int() = bucket->key & 0xffffffff;
TextureRecord* tex = nullptr;
tex = render_state->texture_pool->lookup(tbp);
@@ -497,10 +496,10 @@ void Sprite3::flush_sprites(SharedRenderState* render_state,
glUniform1i(glGetUniformLocation(render_state->shaders[ShaderId::SPRITE3].id(), "tex_T0"), 0);
prof.add_draw_call();
prof.add_tri(2 * (kv.second.ids.size() / 5));
prof.add_tri(2 * (bucket->ids.size() / 5));
glDrawElements(GL_TRIANGLE_STRIP, kv.second.ids.size(), GL_UNSIGNED_INT,
(void*)(kv.second.offset_in_idx_buffer * sizeof(u32)));
glDrawElements(GL_TRIANGLE_STRIP, bucket->ids.size(), GL_UNSIGNED_INT,
(void*)(bucket->offset_in_idx_buffer * sizeof(u32)));
if (double_draw) {
switch (settings.kind) {
@@ -508,7 +507,7 @@ void Sprite3::flush_sprites(SharedRenderState* render_state,
break;
case DoubleDrawKind::AFAIL_NO_DEPTH_WRITE:
prof.add_draw_call();
prof.add_tri(2 * (kv.second.ids.size() / 5));
prof.add_tri(2 * (bucket->ids.size() / 5));
glUniform1f(
glGetUniformLocation(render_state->shaders[ShaderId::SPRITE3].id(), "alpha_min"),
-10.f);
@@ -516,8 +515,8 @@ void Sprite3::flush_sprites(SharedRenderState* render_state,
glGetUniformLocation(render_state->shaders[ShaderId::SPRITE3].id(), "alpha_max"),
settings.aref_second);
glDepthMask(GL_FALSE);
glDrawElements(GL_TRIANGLE_STRIP, kv.second.ids.size(), GL_UNSIGNED_INT,
(void*)(kv.second.offset_in_idx_buffer * sizeof(u32)));
glDrawElements(GL_TRIANGLE_STRIP, bucket->ids.size(), GL_UNSIGNED_INT,
(void*)(bucket->offset_in_idx_buffer * sizeof(u32)));
break;
default:
ASSERT(false);
@@ -526,6 +525,7 @@ void Sprite3::flush_sprites(SharedRenderState* render_state,
}
m_sprite_buckets.clear();
m_bucket_list.clear();
m_last_bucket_key = UINT64_MAX;
m_last_bucket = nullptr;
m_sprite_idx = 0;
@@ -616,6 +616,14 @@ void update_mode_from_alpha1(u64 val, DrawMode& mode) {
// Cv = (Cs - Cd) * FIX + Cd
ASSERT(reg.fix() == 64);
mode.set_alpha_blend(DrawMode::AlphaBlend::SRC_DST_FIX_DST);
} else if (reg.a_mode() == GsAlpha::BlendMode::ZERO_OR_FIXED &&
reg.b_mode() == GsAlpha::BlendMode::SOURCE &&
reg.c_mode() == GsAlpha::BlendMode::SOURCE &&
reg.d_mode() == GsAlpha::BlendMode::DEST) {
// (0 - Cs) * As + Cd
// Cd - Cs * As
// s, d
mode.set_alpha_blend(DrawMode::AlphaBlend::ZERO_SRC_SRC_DST);
}
else {
@@ -667,7 +675,14 @@ void Sprite3::do_block_common(SpriteMode mode,
if (key == m_last_bucket_key) {
bucket = m_last_bucket;
} else {
bucket = &m_sprite_buckets[key];
auto it = m_sprite_buckets.find(key);
if (it == m_sprite_buckets.end()) {
bucket = &m_sprite_buckets[key];
bucket->key = key;
m_bucket_list.push_back(bucket);
} else {
bucket = &it->second;
}
}
u32 start_vtx_id = m_sprite_idx * 4;
bucket->ids.push_back(start_vtx_id);
+2
View File
@@ -90,9 +90,11 @@ class Sprite3 : public BucketRenderer {
struct Bucket {
std::vector<u32> ids;
u32 offset_in_idx_buffer = 0;
u64 key = -1;
};
std::map<u64, Bucket> m_sprite_buckets;
std::vector<Bucket*> m_bucket_list;
u64 m_last_bucket_key = UINT64_MAX;
Bucket* m_last_bucket = nullptr;
@@ -17,8 +17,6 @@ void main() {
}
color = fragment_color * T0 * 2.0;
if (color.a < alpha_min) {
discard;
}
@@ -27,24 +25,3 @@ void main() {
discard;
}
}
//out vec4 color;
//
//in flat vec4 fragment_color;
//in vec3 tex_coord;
//in flat uvec2 tex_info;
//
//uniform sampler2D tex_T0;
//
//
//void main() {
// vec4 T0 = texture(tex_T0, tex_coord.xy);
// if (tex_info.y == 0) {
// T0.w = 1.0;
// }
// vec4 tex_color = fragment_color * T0 * 2.0;
// if (tex_color.a < 0.016) {
// discard;
// }
// color = tex_color;
//}
@@ -128,12 +128,12 @@ void main() {
transformed = offset_pos_vf10 + vf12_rotated * xy0_vf19.x + vf13_rotated_trans * xy0_vf19.y;
} else if (rendermode == 2) { // hud sprites
transformed_pos_vf02.xyz *= Q;
vec4 offset_pos_vf10 = transformed_pos_vf02 + (matrix == 0 ? hud_hvdf_offset : hud_hvdf_user[matrix - 1]);
scales_vf01.z = min(max(scales_vf01.z, min_scale), max_scale);
scales_vf01.w = min(max(scales_vf01.w, min_scale), max_scale);
// NOTE: no max scale for hud
scales_vf01.z = max(scales_vf01.z, min_scale);
scales_vf01.w = max(scales_vf01.w, min_scale);
quat.z *= deg_to_rad;
float sp_sin = sin(quat.z);
@@ -36,21 +36,29 @@ DoubleDraw setup_opengl_from_draw_mode(DrawMode mode, u32 tex_unit, bool mipmap)
glEnable(GL_BLEND);
switch (mode.get_alpha_blend()) {
case DrawMode::AlphaBlend::SRC_DST_SRC_DST:
glBlendEquation(GL_FUNC_ADD);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
break;
case DrawMode::AlphaBlend::SRC_0_SRC_DST:
glBlendEquation(GL_FUNC_ADD);
glBlendFunc(GL_SRC_ALPHA, GL_ONE);
break;
case DrawMode::AlphaBlend::SRC_0_FIX_DST:
glBlendEquation(GL_FUNC_ADD);
glBlendFunc(GL_ONE, GL_ONE);
break;
case DrawMode::AlphaBlend::SRC_DST_FIX_DST:
// Cv = (Cs - Cd) * FIX + Cd
// Cs * FIX * 0.5
// Cd * FIX * 0.5
glBlendEquation(GL_FUNC_ADD);
glBlendFunc(GL_CONSTANT_COLOR, GL_CONSTANT_COLOR);
glBlendColor(0.5, 0.5, 0.5, 0.5);
break;
case DrawMode::AlphaBlend::ZERO_SRC_SRC_DST:
glBlendFunc(GL_SRC_ALPHA, GL_ONE);
glBlendEquation(GL_FUNC_REVERSE_SUBTRACT);
break;
default:
ASSERT(false);
}