mirror of
https://github.com/open-goal/jak-project
synced 2026-07-10 23:22:17 -04:00
toggle for old format
This commit is contained in:
@@ -42,6 +42,7 @@ struct SharedRenderState {
|
||||
bool use_generic2 = true;
|
||||
math::Vector<u8, 4> fog_color;
|
||||
float fog_intensity = 1.f;
|
||||
bool no_multidraw = false;
|
||||
|
||||
void reset();
|
||||
bool has_camera_planes = false;
|
||||
|
||||
@@ -366,6 +366,7 @@ void OpenGLRenderer::render(DmaFollower dma, const RenderOptions& settings) {
|
||||
void OpenGLRenderer::draw_renderer_selection_window() {
|
||||
ImGui::Begin("Renderer Debug");
|
||||
|
||||
ImGui::Checkbox("Use old single-draw", &m_render_state.no_multidraw);
|
||||
ImGui::SliderFloat("Fog Adjust", &m_render_state.fog_intensity, 0, 10);
|
||||
ImGui::Checkbox("Sky CPU", &m_render_state.use_sky_cpu);
|
||||
ImGui::Checkbox("Occlusion Cull", &m_render_state.use_occlusion_culling);
|
||||
|
||||
@@ -70,6 +70,7 @@ void Shrub::update_load(const Loader::LevelData* loader_data) {
|
||||
size_t max_draws = 0;
|
||||
size_t time_of_day_count = 0;
|
||||
size_t max_num_grps = 0;
|
||||
size_t max_inds = 0;
|
||||
|
||||
for (u32 l_tree = 0; l_tree < lev_data->shrub_trees.size(); l_tree++) {
|
||||
size_t num_grps = 0;
|
||||
@@ -84,6 +85,7 @@ void Shrub::update_load(const Loader::LevelData* loader_data) {
|
||||
max_num_grps = std::max(max_num_grps, num_grps);
|
||||
|
||||
time_of_day_count = std::max(tree.time_of_day_colors.size(), time_of_day_count);
|
||||
max_inds = std::max(tree.indices.size(), max_inds);
|
||||
u32 verts = tree.unpacked.vertices.size();
|
||||
glGenVertexArrays(1, &m_trees[l_tree].vao);
|
||||
glBindVertexArray(m_trees[l_tree].vao);
|
||||
@@ -91,6 +93,7 @@ void Shrub::update_load(const Loader::LevelData* loader_data) {
|
||||
m_trees[l_tree].vert_count = verts;
|
||||
m_trees[l_tree].draws = &tree.static_draws;
|
||||
m_trees[l_tree].colors = &tree.time_of_day_colors;
|
||||
m_trees[l_tree].index_data = tree.indices.data();
|
||||
m_trees[l_tree].tod_cache = swizzle_time_of_day(tree.time_of_day_colors);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, m_trees[l_tree].vertex_buffer);
|
||||
glEnableVertexAttribArray(0);
|
||||
@@ -129,6 +132,7 @@ void Shrub::update_load(const Loader::LevelData* loader_data) {
|
||||
(void*)offsetof(tfrag3::ShrubGpuVertex, color_index) // offset (0)
|
||||
);
|
||||
|
||||
glGenBuffers(1, &m_trees[l_tree].single_draw_index_buffer);
|
||||
glGenBuffers(1, &m_trees[l_tree].index_buffer);
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_trees[l_tree].index_buffer);
|
||||
glBufferData(GL_ELEMENT_ARRAY_BUFFER, tree.indices.size() * sizeof(u32), tree.indices.data(),
|
||||
@@ -148,6 +152,8 @@ void Shrub::update_load(const Loader::LevelData* loader_data) {
|
||||
m_cache.multidraw_offset_per_stripdraw.resize(max_draws);
|
||||
m_cache.multidraw_count_buffer.resize(max_num_grps);
|
||||
m_cache.multidraw_index_offset_buffer.resize(max_num_grps);
|
||||
m_cache.draw_idx_temp.resize(max_draws);
|
||||
m_cache.index_temp.resize(max_inds);
|
||||
ASSERT(time_of_day_count <= TIME_OF_DAY_COLOR_COUNT);
|
||||
}
|
||||
|
||||
@@ -185,6 +191,7 @@ void Shrub::discard_tree_cache() {
|
||||
glBindTexture(GL_TEXTURE_1D, tree.time_of_day_texture);
|
||||
glDeleteTextures(1, &tree.time_of_day_texture);
|
||||
glDeleteBuffers(1, &tree.index_buffer);
|
||||
glDeleteBuffers(1, &tree.single_draw_index_buffer);
|
||||
glDeleteVertexArrays(1, &tree.vao);
|
||||
}
|
||||
|
||||
@@ -206,7 +213,6 @@ void Shrub::render_tree(int idx,
|
||||
Timer tree_timer;
|
||||
auto& tree = m_trees.at(idx);
|
||||
tree.perf.draws = 0;
|
||||
tree.perf.verts = 0;
|
||||
tree.perf.wind_draws = 0;
|
||||
if (!m_has_level) {
|
||||
return;
|
||||
@@ -230,7 +236,8 @@ void Shrub::render_tree(int idx,
|
||||
|
||||
glBindVertexArray(tree.vao);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, tree.vertex_buffer);
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, tree.index_buffer);
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,
|
||||
render_state->no_multidraw ? tree.single_draw_index_buffer : tree.index_buffer);
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
glEnable(GL_PRIMITIVE_RESTART);
|
||||
glPrimitiveRestartIndex(UINT32_MAX);
|
||||
@@ -240,9 +247,16 @@ void Shrub::render_tree(int idx,
|
||||
|
||||
tree.perf.cull_time.add(0);
|
||||
Timer index_timer;
|
||||
make_all_visible_multidraws(m_cache.multidraw_offset_per_stripdraw.data(),
|
||||
m_cache.multidraw_count_buffer.data(),
|
||||
m_cache.multidraw_index_offset_buffer.data(), *tree.draws);
|
||||
if (render_state->no_multidraw) {
|
||||
u32 idx_buffer_size = make_all_visible_index_list(
|
||||
m_cache.draw_idx_temp.data(), m_cache.index_temp.data(), *tree.draws, tree.index_data);
|
||||
glBufferData(GL_ELEMENT_ARRAY_BUFFER, idx_buffer_size * sizeof(u32), m_cache.index_temp.data(),
|
||||
GL_STREAM_DRAW);
|
||||
} else {
|
||||
make_all_visible_multidraws(m_cache.multidraw_offset_per_stripdraw.data(),
|
||||
m_cache.multidraw_count_buffer.data(),
|
||||
m_cache.multidraw_index_offset_buffer.data(), *tree.draws);
|
||||
}
|
||||
|
||||
tree.perf.index_time.add(index_timer.getSeconds());
|
||||
|
||||
@@ -250,10 +264,17 @@ void Shrub::render_tree(int idx,
|
||||
|
||||
for (size_t draw_idx = 0; draw_idx < tree.draws->size(); draw_idx++) {
|
||||
const auto& draw = tree.draws->operator[](draw_idx);
|
||||
const auto& indices = m_cache.multidraw_offset_per_stripdraw[draw_idx];
|
||||
const auto& multidraw_indices = m_cache.multidraw_offset_per_stripdraw[draw_idx];
|
||||
const auto& singledraw_indices = m_cache.draw_idx_temp[draw_idx];
|
||||
|
||||
if (indices.second == 0) {
|
||||
continue;
|
||||
if (render_state->no_multidraw) {
|
||||
if (singledraw_indices.second == 0) {
|
||||
continue;
|
||||
}
|
||||
} else {
|
||||
if (multidraw_indices.second == 0) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if ((int)draw.tree_tex_id != last_texture) {
|
||||
@@ -262,34 +283,42 @@ void Shrub::render_tree(int idx,
|
||||
}
|
||||
|
||||
auto double_draw = setup_tfrag_shader(render_state, draw.mode, ShaderId::SHRUB);
|
||||
int draw_size = indices.second - indices.first;
|
||||
|
||||
prof.add_draw_call();
|
||||
prof.add_tri(draw.num_triangles);
|
||||
|
||||
tree.perf.draws++;
|
||||
tree.perf.verts += draw_size;
|
||||
|
||||
glMultiDrawElements(GL_TRIANGLE_STRIP, &m_cache.multidraw_count_buffer[indices.first],
|
||||
GL_UNSIGNED_INT, &m_cache.multidraw_index_offset_buffer[indices.first],
|
||||
indices.second);
|
||||
if (render_state->no_multidraw) {
|
||||
glDrawElements(GL_TRIANGLE_STRIP, singledraw_indices.second, GL_UNSIGNED_INT,
|
||||
(void*)(singledraw_indices.first * sizeof(u32)));
|
||||
} else {
|
||||
glMultiDrawElements(GL_TRIANGLE_STRIP,
|
||||
&m_cache.multidraw_count_buffer[multidraw_indices.first], GL_UNSIGNED_INT,
|
||||
&m_cache.multidraw_index_offset_buffer[multidraw_indices.first],
|
||||
multidraw_indices.second);
|
||||
}
|
||||
|
||||
switch (double_draw.kind) {
|
||||
case DoubleDrawKind::NONE:
|
||||
break;
|
||||
case DoubleDrawKind::AFAIL_NO_DEPTH_WRITE:
|
||||
tree.perf.draws++;
|
||||
tree.perf.verts += draw_size;
|
||||
prof.add_draw_call();
|
||||
prof.add_tri(draw_size);
|
||||
glUniform1f(glGetUniformLocation(render_state->shaders[ShaderId::SHRUB].id(), "alpha_min"),
|
||||
-10.f);
|
||||
glUniform1f(glGetUniformLocation(render_state->shaders[ShaderId::SHRUB].id(), "alpha_max"),
|
||||
double_draw.aref_second);
|
||||
glDepthMask(GL_FALSE);
|
||||
glMultiDrawElements(GL_TRIANGLE_STRIP, &m_cache.multidraw_count_buffer[indices.first],
|
||||
GL_UNSIGNED_INT, &m_cache.multidraw_index_offset_buffer[indices.first],
|
||||
indices.second);
|
||||
if (render_state->no_multidraw) {
|
||||
glDrawElements(GL_TRIANGLE_STRIP, singledraw_indices.second, GL_UNSIGNED_INT,
|
||||
(void*)(singledraw_indices.first * sizeof(u32)));
|
||||
} else {
|
||||
glMultiDrawElements(
|
||||
GL_TRIANGLE_STRIP, &m_cache.multidraw_count_buffer[multidraw_indices.first],
|
||||
GL_UNSIGNED_INT, &m_cache.multidraw_index_offset_buffer[multidraw_indices.first],
|
||||
multidraw_indices.second);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
ASSERT(false);
|
||||
|
||||
@@ -30,16 +30,17 @@ class Shrub : public BucketRenderer {
|
||||
struct Tree {
|
||||
GLuint vertex_buffer;
|
||||
GLuint index_buffer;
|
||||
GLuint single_draw_index_buffer;
|
||||
GLuint time_of_day_texture;
|
||||
GLuint vao;
|
||||
u32 vert_count;
|
||||
const std::vector<tfrag3::ShrubDraw>* draws = nullptr;
|
||||
const std::vector<tfrag3::TieWindInstance>* instance_info = nullptr;
|
||||
const std::vector<tfrag3::TimeOfDayColor>* colors = nullptr;
|
||||
const u32* index_data = nullptr;
|
||||
SwizzledTimeOfDay tod_cache;
|
||||
|
||||
struct {
|
||||
u32 verts = 0;
|
||||
u32 draws = 0;
|
||||
u32 wind_draws = 0;
|
||||
Filtered<float> cull_time;
|
||||
@@ -62,6 +63,8 @@ class Shrub : public BucketRenderer {
|
||||
bool m_has_level = false;
|
||||
|
||||
struct Cache {
|
||||
std::vector<std::pair<int, int>> draw_idx_temp;
|
||||
std::vector<u32> index_temp;
|
||||
std::vector<std::pair<int, int>> multidraw_offset_per_stripdraw;
|
||||
std::vector<GLsizei> multidraw_count_buffer;
|
||||
std::vector<void*> multidraw_index_offset_buffer;
|
||||
|
||||
@@ -50,6 +50,7 @@ void Tfrag3::update_load(const std::vector<tfrag3::TFragmentTreeKind>& tree_kind
|
||||
size_t vis_temp_len = 0;
|
||||
size_t max_draws = 0;
|
||||
size_t max_num_grps = 0;
|
||||
size_t max_inds = 0;
|
||||
|
||||
for (int geom = 0; geom < GEOM_MAX; ++geom) {
|
||||
for (size_t tree_idx = 0; tree_idx < lev_data->tfrag_trees[geom].size(); tree_idx++) {
|
||||
@@ -65,7 +66,7 @@ void Tfrag3::update_load(const std::vector<tfrag3::TFragmentTreeKind>& tree_kind
|
||||
num_grps += draw.vis_groups.size();
|
||||
}
|
||||
max_num_grps = std::max(max_num_grps, num_grps);
|
||||
|
||||
max_inds = std::max(tree.unpacked.indices.size(), max_inds);
|
||||
time_of_day_count = std::max(tree.colors.size(), time_of_day_count);
|
||||
u32 verts = tree.packed_vertices.vertices.size();
|
||||
glGenVertexArrays(1, &tree_cache.vao);
|
||||
@@ -76,6 +77,7 @@ void Tfrag3::update_load(const std::vector<tfrag3::TFragmentTreeKind>& tree_kind
|
||||
tree_cache.draws = &tree.draws; // todo - should we just copy this?
|
||||
tree_cache.colors = &tree.colors;
|
||||
tree_cache.vis = &tree.bvh;
|
||||
tree_cache.index_data = tree.unpacked.indices.data();
|
||||
tree_cache.tod_cache = swizzle_time_of_day(tree.colors);
|
||||
vis_temp_len = std::max(vis_temp_len, tree.bvh.vis_nodes.size());
|
||||
glBindBuffer(GL_ARRAY_BUFFER, tree_cache.vertex_buffer);
|
||||
@@ -108,7 +110,7 @@ void Tfrag3::update_load(const std::vector<tfrag3::TFragmentTreeKind>& tree_kind
|
||||
sizeof(tfrag3::PreloadedVertex), // stride
|
||||
(void*)offsetof(tfrag3::PreloadedVertex, color_index) // offset (0)
|
||||
);
|
||||
|
||||
glGenBuffers(1, &tree_cache.single_draw_index_buffer);
|
||||
glGenBuffers(1, &tree_cache.index_buffer);
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, tree_cache.index_buffer);
|
||||
glBufferData(GL_ELEMENT_ARRAY_BUFFER, tree.unpacked.indices.size() * sizeof(u32),
|
||||
@@ -129,7 +131,8 @@ void Tfrag3::update_load(const std::vector<tfrag3::TFragmentTreeKind>& tree_kind
|
||||
m_cache.multidraw_offset_per_stripdraw.resize(max_draws);
|
||||
m_cache.multidraw_count_buffer.resize(max_num_grps);
|
||||
m_cache.multidraw_index_offset_buffer.resize(max_num_grps);
|
||||
|
||||
m_cache.draw_idx_temp.resize(max_draws);
|
||||
m_cache.index_temp.resize(max_inds);
|
||||
ASSERT(time_of_day_count <= TIME_OF_DAY_COLOR_COUNT);
|
||||
}
|
||||
|
||||
@@ -191,7 +194,8 @@ void Tfrag3::render_tree(int geom,
|
||||
|
||||
glBindVertexArray(tree.vao);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, tree.vertex_buffer);
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, tree.index_buffer);
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,
|
||||
render_state->no_multidraw ? tree.single_draw_index_buffer : tree.index_buffer);
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
glEnable(GL_PRIMITIVE_RESTART);
|
||||
glPrimitiveRestartIndex(UINT32_MAX);
|
||||
@@ -199,18 +203,34 @@ void Tfrag3::render_tree(int geom,
|
||||
cull_check_all_slow(settings.planes, tree.vis->vis_nodes, settings.occlusion_culling,
|
||||
m_cache.vis_temp.data());
|
||||
|
||||
u32 total_tris = make_multidraws_from_vis_string(
|
||||
m_cache.multidraw_offset_per_stripdraw.data(), m_cache.multidraw_count_buffer.data(),
|
||||
m_cache.multidraw_index_offset_buffer.data(), *tree.draws, m_cache.vis_temp);
|
||||
u32 total_tris;
|
||||
if (render_state->no_multidraw) {
|
||||
u32 idx_buffer_size = make_index_list_from_vis_string(
|
||||
m_cache.draw_idx_temp.data(), m_cache.index_temp.data(), *tree.draws, m_cache.vis_temp,
|
||||
tree.index_data, &total_tris);
|
||||
glBufferData(GL_ELEMENT_ARRAY_BUFFER, idx_buffer_size * sizeof(u32), m_cache.index_temp.data(),
|
||||
GL_STREAM_DRAW);
|
||||
} else {
|
||||
total_tris = make_multidraws_from_vis_string(
|
||||
m_cache.multidraw_offset_per_stripdraw.data(), m_cache.multidraw_count_buffer.data(),
|
||||
m_cache.multidraw_index_offset_buffer.data(), *tree.draws, m_cache.vis_temp);
|
||||
}
|
||||
|
||||
prof.add_tri(total_tris);
|
||||
|
||||
for (size_t draw_idx = 0; draw_idx < tree.draws->size(); draw_idx++) {
|
||||
const auto& draw = tree.draws->operator[](draw_idx);
|
||||
const auto& indices = m_cache.multidraw_offset_per_stripdraw[draw_idx];
|
||||
const auto& multidraw_indices = m_cache.multidraw_offset_per_stripdraw[draw_idx];
|
||||
const auto& singledraw_indices = m_cache.draw_idx_temp[draw_idx];
|
||||
|
||||
if (indices.second == 0) {
|
||||
continue;
|
||||
if (render_state->no_multidraw) {
|
||||
if (singledraw_indices.second == 0) {
|
||||
continue;
|
||||
}
|
||||
} else {
|
||||
if (multidraw_indices.second == 0) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
ASSERT(m_textures);
|
||||
@@ -218,31 +238,37 @@ void Tfrag3::render_tree(int geom,
|
||||
auto double_draw = setup_tfrag_shader(render_state, draw.mode, ShaderId::TFRAG3);
|
||||
tree.tris_this_frame += draw.num_triangles;
|
||||
tree.draws_this_frame++;
|
||||
int draw_size = 0;
|
||||
for (int i = 0; i < indices.second; i++) {
|
||||
draw_size += m_cache.multidraw_count_buffer[indices.first + i];
|
||||
}
|
||||
|
||||
prof.add_draw_call();
|
||||
|
||||
glMultiDrawElements(GL_TRIANGLE_STRIP, &m_cache.multidraw_count_buffer[indices.first],
|
||||
GL_UNSIGNED_INT, &m_cache.multidraw_index_offset_buffer[indices.first],
|
||||
indices.second);
|
||||
if (render_state->no_multidraw) {
|
||||
glDrawElements(GL_TRIANGLE_STRIP, singledraw_indices.second, GL_UNSIGNED_INT,
|
||||
(void*)(singledraw_indices.first * sizeof(u32)));
|
||||
} else {
|
||||
glMultiDrawElements(GL_TRIANGLE_STRIP,
|
||||
&m_cache.multidraw_count_buffer[multidraw_indices.first], GL_UNSIGNED_INT,
|
||||
&m_cache.multidraw_index_offset_buffer[multidraw_indices.first],
|
||||
multidraw_indices.second);
|
||||
}
|
||||
|
||||
switch (double_draw.kind) {
|
||||
case DoubleDrawKind::NONE:
|
||||
break;
|
||||
case DoubleDrawKind::AFAIL_NO_DEPTH_WRITE:
|
||||
prof.add_draw_call();
|
||||
prof.add_tri(draw_size);
|
||||
glUniform1f(glGetUniformLocation(render_state->shaders[ShaderId::TFRAG3].id(), "alpha_min"),
|
||||
-10.f);
|
||||
glUniform1f(glGetUniformLocation(render_state->shaders[ShaderId::TFRAG3].id(), "alpha_max"),
|
||||
double_draw.aref_second);
|
||||
glDepthMask(GL_FALSE);
|
||||
glMultiDrawElements(GL_TRIANGLE_STRIP, &m_cache.multidraw_count_buffer[indices.first],
|
||||
GL_UNSIGNED_INT, &m_cache.multidraw_index_offset_buffer[indices.first],
|
||||
indices.second);
|
||||
if (render_state->no_multidraw) {
|
||||
glDrawElements(GL_TRIANGLE_STRIP, singledraw_indices.second, GL_UNSIGNED_INT,
|
||||
(void*)(singledraw_indices.first * sizeof(u32)));
|
||||
} else {
|
||||
glMultiDrawElements(
|
||||
GL_TRIANGLE_STRIP, &m_cache.multidraw_count_buffer[multidraw_indices.first],
|
||||
GL_UNSIGNED_INT, &m_cache.multidraw_index_offset_buffer[multidraw_indices.first],
|
||||
multidraw_indices.second);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
ASSERT(false);
|
||||
@@ -344,7 +370,7 @@ void Tfrag3::discard_tree_cache() {
|
||||
if (tree.kind != tfrag3::TFragmentTreeKind::INVALID) {
|
||||
glBindTexture(GL_TEXTURE_1D, tree.time_of_day_texture);
|
||||
glDeleteTextures(1, &tree.time_of_day_texture);
|
||||
// glDeleteBuffers(1, &tree.vertex_buffer);
|
||||
glDeleteBuffers(1, &tree.single_draw_index_buffer);
|
||||
glDeleteBuffers(1, &tree.index_buffer);
|
||||
glDeleteVertexArrays(1, &tree.vao);
|
||||
}
|
||||
|
||||
@@ -60,12 +60,14 @@ class Tfrag3 {
|
||||
tfrag3::TFragmentTreeKind kind;
|
||||
GLuint vertex_buffer = -1;
|
||||
GLuint index_buffer = -1;
|
||||
GLuint time_of_day_texture;
|
||||
GLuint vao;
|
||||
GLuint single_draw_index_buffer = -1;
|
||||
GLuint time_of_day_texture = -1;
|
||||
GLuint vao = -1;
|
||||
u32 vert_count = 0;
|
||||
const std::vector<tfrag3::StripDraw>* draws = nullptr;
|
||||
const std::vector<tfrag3::TimeOfDayColor>* colors = nullptr;
|
||||
const tfrag3::BVH* vis = nullptr;
|
||||
const u32* index_data = nullptr;
|
||||
SwizzledTimeOfDay tod_cache;
|
||||
|
||||
void reset_stats() {
|
||||
@@ -83,6 +85,8 @@ class Tfrag3 {
|
||||
|
||||
struct Cache {
|
||||
std::vector<u8> vis_temp;
|
||||
std::vector<std::pair<int, int>> draw_idx_temp;
|
||||
std::vector<u32> index_temp;
|
||||
std::vector<std::pair<int, int>> multidraw_offset_per_stripdraw;
|
||||
std::vector<GLsizei> multidraw_count_buffer;
|
||||
std::vector<void*> multidraw_index_offset_buffer;
|
||||
|
||||
@@ -28,6 +28,7 @@ void Tie3::update_load(const Loader::LevelData* loader_data) {
|
||||
size_t max_num_grps = 0;
|
||||
u16 max_wind_idx = 0;
|
||||
size_t time_of_day_count = 0;
|
||||
size_t max_inds = 0;
|
||||
for (u32 l_geo = 0; l_geo < tfrag3::TIE_GEOS; l_geo++) {
|
||||
for (u32 l_tree = 0; l_tree < lev_data->tie_trees[l_geo].size(); l_tree++) {
|
||||
size_t wind_idx_buffer_len = 0;
|
||||
@@ -45,6 +46,7 @@ void Tie3::update_load(const Loader::LevelData* loader_data) {
|
||||
max_wind_idx = std::max(max_wind_idx, inst.wind_idx);
|
||||
}
|
||||
time_of_day_count = std::max(tree.colors.size(), time_of_day_count);
|
||||
max_inds = std::max(tree.unpacked.indices.size(), max_inds);
|
||||
u32 verts = tree.packed_vertices.color_indices.size();
|
||||
auto& lod_tree = m_trees.at(l_geo);
|
||||
glGenVertexArrays(1, &lod_tree[l_tree].vao);
|
||||
@@ -54,6 +56,7 @@ void Tie3::update_load(const Loader::LevelData* loader_data) {
|
||||
lod_tree[l_tree].draws = &tree.static_draws;
|
||||
lod_tree[l_tree].colors = &tree.colors;
|
||||
lod_tree[l_tree].vis = &tree.bvh;
|
||||
lod_tree[l_tree].index_data = tree.unpacked.indices.data();
|
||||
lod_tree[l_tree].instance_info = &tree.wind_instance_info;
|
||||
lod_tree[l_tree].wind_draws = &tree.instanced_wind_draws;
|
||||
vis_temp_len = std::max(vis_temp_len, tree.bvh.vis_nodes.size());
|
||||
@@ -86,6 +89,7 @@ void Tie3::update_load(const Loader::LevelData* loader_data) {
|
||||
(void*)offsetof(tfrag3::PreloadedVertex, color_index) // offset (0)
|
||||
);
|
||||
|
||||
glGenBuffers(1, &lod_tree[l_tree].single_draw_index_buffer);
|
||||
glGenBuffers(1, &lod_tree[l_tree].index_buffer);
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, lod_tree[l_tree].index_buffer);
|
||||
// todo: move to loader, this will probably be quite slow.
|
||||
@@ -121,6 +125,8 @@ void Tie3::update_load(const Loader::LevelData* loader_data) {
|
||||
m_cache.multidraw_count_buffer.resize(max_num_grps);
|
||||
m_cache.multidraw_index_offset_buffer.resize(max_num_grps);
|
||||
m_wind_vectors.resize(4 * max_wind_idx + 4); // 4x u32's per wind.
|
||||
m_cache.draw_idx_temp.resize(max_draws);
|
||||
m_cache.index_temp.resize(max_inds);
|
||||
ASSERT(time_of_day_count <= TIME_OF_DAY_COLOR_COUNT);
|
||||
}
|
||||
|
||||
@@ -273,6 +279,7 @@ void Tie3::discard_tree_cache() {
|
||||
glBindTexture(GL_TEXTURE_1D, tree.time_of_day_texture);
|
||||
glDeleteTextures(1, &tree.time_of_day_texture);
|
||||
glDeleteBuffers(1, &tree.index_buffer);
|
||||
glDeleteBuffers(1, &tree.single_draw_index_buffer);
|
||||
glDeleteVertexArrays(1, &tree.vao);
|
||||
}
|
||||
|
||||
@@ -465,7 +472,6 @@ void Tie3::render_tree_wind(int idx,
|
||||
|
||||
tree.perf.draws++;
|
||||
tree.perf.wind_draws++;
|
||||
tree.perf.verts += grp.num;
|
||||
|
||||
glDrawElements(GL_TRIANGLE_STRIP, grp.num, GL_UNSIGNED_INT,
|
||||
(void*)((off + tree.wind_vertex_index_offsets.at(draw_idx)) * sizeof(u32)));
|
||||
@@ -477,7 +483,6 @@ void Tie3::render_tree_wind(int idx,
|
||||
case DoubleDrawKind::AFAIL_NO_DEPTH_WRITE:
|
||||
tree.perf.draws++;
|
||||
tree.perf.wind_draws++;
|
||||
tree.perf.verts += grp.num;
|
||||
prof.add_draw_call();
|
||||
prof.add_tri(grp.num);
|
||||
glUniform1f(
|
||||
@@ -502,15 +507,18 @@ void Tie3::render_tree(int idx,
|
||||
const TfragRenderSettings& settings,
|
||||
SharedRenderState* render_state,
|
||||
ScopedProfilerNode& prof) {
|
||||
// reset perf
|
||||
Timer tree_timer;
|
||||
auto& tree = m_trees.at(geom).at(idx);
|
||||
tree.perf.draws = 0;
|
||||
tree.perf.verts = 0;
|
||||
tree.perf.wind_draws = 0;
|
||||
|
||||
// don't render if we haven't loaded
|
||||
if (!m_has_level) {
|
||||
return;
|
||||
}
|
||||
|
||||
// update time of day
|
||||
if (m_color_result.size() < tree.colors->size()) {
|
||||
m_color_result.resize(tree.colors->size());
|
||||
}
|
||||
@@ -529,11 +537,13 @@ void Tie3::render_tree(int idx,
|
||||
glTexSubImage1D(GL_TEXTURE_1D, 0, 0, tree.colors->size(), GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV,
|
||||
m_color_result.data());
|
||||
|
||||
// setup OpenGL shader
|
||||
first_tfrag_draw_setup(settings, render_state, ShaderId::TFRAG3);
|
||||
|
||||
glBindVertexArray(tree.vao);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, tree.vertex_buffer);
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, tree.index_buffer);
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,
|
||||
render_state->no_multidraw ? tree.single_draw_index_buffer : tree.index_buffer);
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
glEnable(GL_PRIMITIVE_RESTART);
|
||||
glPrimitiveRestartIndex(UINT32_MAX);
|
||||
@@ -541,25 +551,49 @@ void Tie3::render_tree(int idx,
|
||||
|
||||
int last_texture = -1;
|
||||
|
||||
u32 num_tris;
|
||||
if (m_debug_all_visible) {
|
||||
tree.perf.cull_time.add(0);
|
||||
Timer index_timer;
|
||||
num_tris = make_all_visible_multidraws(
|
||||
m_cache.multidraw_offset_per_stripdraw.data(), m_cache.multidraw_count_buffer.data(),
|
||||
m_cache.multidraw_index_offset_buffer.data(), *tree.draws);
|
||||
tree.perf.index_time.add(index_timer.getSeconds());
|
||||
} else {
|
||||
if (!m_debug_all_visible) {
|
||||
// need culling data
|
||||
Timer cull_timer;
|
||||
cull_check_all_slow(settings.planes, tree.vis->vis_nodes, settings.occlusion_culling,
|
||||
m_cache.vis_temp.data());
|
||||
tree.perf.cull_time.add(cull_timer.getSeconds());
|
||||
} else {
|
||||
// no culling.
|
||||
tree.perf.cull_time.add(0);
|
||||
}
|
||||
|
||||
u32 num_tris;
|
||||
if (render_state->no_multidraw) {
|
||||
Timer index_timer;
|
||||
num_tris = make_multidraws_from_vis_string(
|
||||
m_cache.multidraw_offset_per_stripdraw.data(), m_cache.multidraw_count_buffer.data(),
|
||||
m_cache.multidraw_index_offset_buffer.data(), *tree.draws, m_cache.vis_temp);
|
||||
u32 idx_buffer_size;
|
||||
if (m_debug_all_visible) {
|
||||
idx_buffer_size =
|
||||
make_all_visible_index_list(m_cache.draw_idx_temp.data(), m_cache.index_temp.data(),
|
||||
*tree.draws, tree.index_data, &num_tris);
|
||||
} else {
|
||||
idx_buffer_size = make_index_list_from_vis_string(
|
||||
m_cache.draw_idx_temp.data(), m_cache.index_temp.data(), *tree.draws, m_cache.vis_temp,
|
||||
tree.index_data, &num_tris);
|
||||
}
|
||||
|
||||
glBufferData(GL_ELEMENT_ARRAY_BUFFER, idx_buffer_size * sizeof(u32), m_cache.index_temp.data(),
|
||||
GL_STREAM_DRAW);
|
||||
tree.perf.index_time.add(index_timer.getSeconds());
|
||||
|
||||
} else {
|
||||
if (m_debug_all_visible) {
|
||||
Timer index_timer;
|
||||
num_tris = make_all_visible_multidraws(
|
||||
m_cache.multidraw_offset_per_stripdraw.data(), m_cache.multidraw_count_buffer.data(),
|
||||
m_cache.multidraw_index_offset_buffer.data(), *tree.draws);
|
||||
tree.perf.index_time.add(index_timer.getSeconds());
|
||||
} else {
|
||||
Timer index_timer;
|
||||
num_tris = make_multidraws_from_vis_string(
|
||||
m_cache.multidraw_offset_per_stripdraw.data(), m_cache.multidraw_count_buffer.data(),
|
||||
m_cache.multidraw_index_offset_buffer.data(), *tree.draws, m_cache.vis_temp);
|
||||
tree.perf.index_time.add(index_timer.getSeconds());
|
||||
}
|
||||
}
|
||||
|
||||
Timer draw_timer;
|
||||
@@ -567,10 +601,17 @@ void Tie3::render_tree(int idx,
|
||||
|
||||
for (size_t draw_idx = 0; draw_idx < tree.draws->size(); draw_idx++) {
|
||||
const auto& draw = tree.draws->operator[](draw_idx);
|
||||
const auto& indices = m_cache.multidraw_offset_per_stripdraw[draw_idx];
|
||||
const auto& multidraw_indices = m_cache.multidraw_offset_per_stripdraw[draw_idx];
|
||||
const auto& singledraw_indices = m_cache.draw_idx_temp[draw_idx];
|
||||
|
||||
if (indices.second == 0) {
|
||||
continue;
|
||||
if (render_state->no_multidraw) {
|
||||
if (singledraw_indices.second == 0) {
|
||||
continue;
|
||||
}
|
||||
} else {
|
||||
if (multidraw_indices.second == 0) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if ((int)draw.tree_tex_id != last_texture) {
|
||||
@@ -579,42 +620,47 @@ void Tie3::render_tree(int idx,
|
||||
}
|
||||
|
||||
auto double_draw = setup_tfrag_shader(render_state, draw.mode, ShaderId::TFRAG3);
|
||||
int draw_size = 0;
|
||||
for (int i = 0; i < indices.second; i++) {
|
||||
draw_size += m_cache.multidraw_count_buffer[indices.first + i];
|
||||
}
|
||||
|
||||
prof.add_draw_call();
|
||||
|
||||
tree.perf.draws++;
|
||||
tree.perf.verts += draw_size;
|
||||
|
||||
glMultiDrawElements(GL_TRIANGLE_STRIP, &m_cache.multidraw_count_buffer[indices.first],
|
||||
GL_UNSIGNED_INT, &m_cache.multidraw_index_offset_buffer[indices.first],
|
||||
indices.second);
|
||||
if (render_state->no_multidraw) {
|
||||
glDrawElements(GL_TRIANGLE_STRIP, singledraw_indices.second, GL_UNSIGNED_INT,
|
||||
(void*)(singledraw_indices.first * sizeof(u32)));
|
||||
} else {
|
||||
glMultiDrawElements(GL_TRIANGLE_STRIP,
|
||||
&m_cache.multidraw_count_buffer[multidraw_indices.first], GL_UNSIGNED_INT,
|
||||
&m_cache.multidraw_index_offset_buffer[multidraw_indices.first],
|
||||
multidraw_indices.second);
|
||||
}
|
||||
|
||||
switch (double_draw.kind) {
|
||||
case DoubleDrawKind::NONE:
|
||||
break;
|
||||
case DoubleDrawKind::AFAIL_NO_DEPTH_WRITE:
|
||||
tree.perf.draws++;
|
||||
tree.perf.verts += draw_size;
|
||||
prof.add_draw_call();
|
||||
prof.add_tri(draw_size);
|
||||
glUniform1f(glGetUniformLocation(render_state->shaders[ShaderId::TFRAG3].id(), "alpha_min"),
|
||||
-10.f);
|
||||
glUniform1f(glGetUniformLocation(render_state->shaders[ShaderId::TFRAG3].id(), "alpha_max"),
|
||||
double_draw.aref_second);
|
||||
glDepthMask(GL_FALSE);
|
||||
glMultiDrawElements(GL_TRIANGLE_STRIP, &m_cache.multidraw_count_buffer[indices.first],
|
||||
GL_UNSIGNED_INT, &m_cache.multidraw_index_offset_buffer[indices.first],
|
||||
indices.second);
|
||||
if (render_state->no_multidraw) {
|
||||
glDrawElements(GL_TRIANGLE_STRIP, singledraw_indices.second, GL_UNSIGNED_INT,
|
||||
(void*)(singledraw_indices.first * sizeof(u32)));
|
||||
} else {
|
||||
glMultiDrawElements(
|
||||
GL_TRIANGLE_STRIP, &m_cache.multidraw_count_buffer[multidraw_indices.first],
|
||||
GL_UNSIGNED_INT, &m_cache.multidraw_index_offset_buffer[multidraw_indices.first],
|
||||
multidraw_indices.second);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
ASSERT(false);
|
||||
}
|
||||
|
||||
if (m_debug_wireframe) {
|
||||
if (m_debug_wireframe && !render_state->no_multidraw) {
|
||||
render_state->shaders[ShaderId::TFRAG3_NO_TEX].activate();
|
||||
glUniformMatrix4fv(
|
||||
glGetUniformLocation(render_state->shaders[ShaderId::TFRAG3_NO_TEX].id(), "camera"), 1,
|
||||
@@ -628,12 +674,12 @@ void Tie3::render_tree(int idx,
|
||||
settings.fog.x());
|
||||
glDisable(GL_BLEND);
|
||||
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
|
||||
glMultiDrawElements(GL_TRIANGLE_STRIP, &m_cache.multidraw_count_buffer[indices.first],
|
||||
GL_UNSIGNED_INT, &m_cache.multidraw_index_offset_buffer[indices.first],
|
||||
indices.second);
|
||||
glMultiDrawElements(GL_TRIANGLE_STRIP,
|
||||
&m_cache.multidraw_count_buffer[multidraw_indices.first], GL_UNSIGNED_INT,
|
||||
&m_cache.multidraw_index_offset_buffer[multidraw_indices.first],
|
||||
multidraw_indices.second);
|
||||
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
|
||||
prof.add_draw_call();
|
||||
prof.add_tri(draw_size);
|
||||
render_state->shaders[ShaderId::TFRAG3].activate();
|
||||
}
|
||||
}
|
||||
@@ -665,7 +711,7 @@ void Tie3::draw_debug_window() {
|
||||
auto& perf = m_trees[lod()][i].perf;
|
||||
ImGui::Text("Tree: %d", i);
|
||||
ImGui::Text("time of days: %d", (int)m_trees[lod()][i].colors->size());
|
||||
ImGui::Text("draw: %d, verts: %d", perf.draws, perf.verts);
|
||||
ImGui::Text("draw: %d", perf.draws);
|
||||
ImGui::Text("wind draw: %d", perf.wind_draws);
|
||||
ImGui::Text("total: %.2f", perf.tree_time.get());
|
||||
ImGui::Text("cull: %.2f index: %.2f tod: %.2f setup: %.2f draw: %.2f",
|
||||
|
||||
@@ -51,6 +51,7 @@ class Tie3 : public BucketRenderer {
|
||||
struct Tree {
|
||||
GLuint vertex_buffer;
|
||||
GLuint index_buffer;
|
||||
GLuint single_draw_index_buffer;
|
||||
GLuint time_of_day_texture;
|
||||
GLuint vao;
|
||||
u32 vert_count;
|
||||
@@ -59,6 +60,7 @@ class Tie3 : public BucketRenderer {
|
||||
const std::vector<tfrag3::TieWindInstance>* instance_info = nullptr;
|
||||
const std::vector<tfrag3::TimeOfDayColor>* colors = nullptr;
|
||||
const tfrag3::BVH* vis = nullptr;
|
||||
const u32* index_data = nullptr;
|
||||
SwizzledTimeOfDay tod_cache;
|
||||
|
||||
std::vector<std::array<math::Vector4f, 4>> wind_matrix_cache;
|
||||
@@ -68,7 +70,6 @@ class Tie3 : public BucketRenderer {
|
||||
std::vector<u32> wind_vertex_index_offsets;
|
||||
|
||||
struct {
|
||||
u32 verts = 0;
|
||||
u32 draws = 0;
|
||||
u32 wind_draws = 0;
|
||||
Filtered<float> cull_time;
|
||||
@@ -86,6 +87,8 @@ class Tie3 : public BucketRenderer {
|
||||
u64 m_load_id = -1;
|
||||
|
||||
struct Cache {
|
||||
std::vector<std::pair<int, int>> draw_idx_temp;
|
||||
std::vector<u32> index_temp;
|
||||
std::vector<u8> vis_temp;
|
||||
std::vector<std::pair<int, int>> multidraw_offset_per_stripdraw;
|
||||
std::vector<GLsizei> multidraw_count_buffer;
|
||||
|
||||
@@ -501,36 +501,6 @@ void make_all_visible_multidraws(std::pair<int, int>* draw_ptrs_out,
|
||||
}
|
||||
}
|
||||
|
||||
u32 make_multidraws_from_vis_string(std::pair<int, int>* draw_ptrs_out,
|
||||
GLsizei* counts_out,
|
||||
void** index_offsets_out,
|
||||
const std::vector<tfrag3::StripDraw>& draws,
|
||||
const std::vector<u8>& vis_data) {
|
||||
u64 md_idx = 0;
|
||||
u32 num_tris = 0;
|
||||
for (size_t i = 0; i < draws.size(); i++) {
|
||||
const auto& draw = draws[i];
|
||||
u64 iidx = draw.unpacked.idx_of_first_idx_in_full_buffer;
|
||||
std::pair<int, int> ds;
|
||||
ds.first = md_idx;
|
||||
ds.second = 0;
|
||||
for (auto& grp : draw.vis_groups) {
|
||||
if (grp.vis_idx_in_pc_bvh == 0xffffffff || vis_data[grp.vis_idx_in_pc_bvh]) {
|
||||
// visible!
|
||||
// let's use a multidraw
|
||||
counts_out[md_idx] = grp.num_inds;
|
||||
index_offsets_out[md_idx] = (void*)(iidx * sizeof(u32));
|
||||
ds.second++;
|
||||
md_idx++;
|
||||
num_tris += grp.num_tris;
|
||||
}
|
||||
iidx += grp.num_inds;
|
||||
}
|
||||
draw_ptrs_out[i] = ds;
|
||||
}
|
||||
return num_tris;
|
||||
}
|
||||
|
||||
u32 make_all_visible_multidraws(std::pair<int, int>* draw_ptrs_out,
|
||||
GLsizei* counts_out,
|
||||
void** index_offsets_out,
|
||||
@@ -557,3 +527,135 @@ u32 make_all_visible_multidraws(std::pair<int, int>* draw_ptrs_out,
|
||||
}
|
||||
return num_tris;
|
||||
}
|
||||
|
||||
u32 make_all_visible_index_list(std::pair<int, int>* group_out,
|
||||
u32* idx_out,
|
||||
const std::vector<tfrag3::ShrubDraw>& draws,
|
||||
const u32* idx_in) {
|
||||
int idx_buffer_ptr = 0;
|
||||
for (size_t i = 0; i < draws.size(); i++) {
|
||||
const auto& draw = draws[i];
|
||||
std::pair<int, int> ds;
|
||||
ds.first = idx_buffer_ptr;
|
||||
memcpy(&idx_out[idx_buffer_ptr], idx_in + draw.first_index_index,
|
||||
draw.num_indices * sizeof(u32));
|
||||
idx_buffer_ptr += draw.num_indices;
|
||||
ds.second = idx_buffer_ptr - ds.first;
|
||||
group_out[i] = ds;
|
||||
}
|
||||
return idx_buffer_ptr;
|
||||
}
|
||||
|
||||
u32 make_multidraws_from_vis_string(std::pair<int, int>* draw_ptrs_out,
|
||||
GLsizei* counts_out,
|
||||
void** index_offsets_out,
|
||||
const std::vector<tfrag3::StripDraw>& draws,
|
||||
const std::vector<u8>& vis_data) {
|
||||
u64 md_idx = 0;
|
||||
u32 num_tris = 0;
|
||||
u32 sanity_check = 0;
|
||||
for (size_t i = 0; i < draws.size(); i++) {
|
||||
const auto& draw = draws[i];
|
||||
u64 iidx = draw.unpacked.idx_of_first_idx_in_full_buffer;
|
||||
ASSERT(sanity_check == iidx);
|
||||
std::pair<int, int> ds;
|
||||
ds.first = md_idx;
|
||||
ds.second = 0;
|
||||
for (auto& grp : draw.vis_groups) {
|
||||
sanity_check += grp.num_inds;
|
||||
if (grp.vis_idx_in_pc_bvh == 0xffffffff || vis_data[grp.vis_idx_in_pc_bvh]) {
|
||||
// visible!
|
||||
// let's use a multidraw
|
||||
counts_out[md_idx] = grp.num_inds;
|
||||
index_offsets_out[md_idx] = (void*)(iidx * sizeof(u32));
|
||||
ds.second++;
|
||||
md_idx++;
|
||||
num_tris += grp.num_tris;
|
||||
}
|
||||
iidx += grp.num_inds;
|
||||
}
|
||||
draw_ptrs_out[i] = ds;
|
||||
}
|
||||
return num_tris;
|
||||
}
|
||||
|
||||
u32 make_index_list_from_vis_string(std::pair<int, int>* group_out,
|
||||
u32* idx_out,
|
||||
const std::vector<tfrag3::StripDraw>& draws,
|
||||
const std::vector<u8>& vis_data,
|
||||
const u32* idx_in,
|
||||
u32* num_tris_out) {
|
||||
int idx_buffer_ptr = 0;
|
||||
u32 num_tris = 0;
|
||||
for (size_t i = 0; i < draws.size(); i++) {
|
||||
const auto& draw = draws[i];
|
||||
int vtx_idx = 0;
|
||||
std::pair<int, int> ds;
|
||||
ds.first = idx_buffer_ptr;
|
||||
bool building_run = false;
|
||||
int run_start_out = 0;
|
||||
int run_start_in = 0;
|
||||
for (auto& grp : draw.vis_groups) {
|
||||
bool vis = grp.vis_idx_in_pc_bvh == 0xffffffff || vis_data[grp.vis_idx_in_pc_bvh];
|
||||
if (vis) {
|
||||
num_tris += grp.num_tris;
|
||||
}
|
||||
|
||||
if (building_run) {
|
||||
if (vis) {
|
||||
idx_buffer_ptr += grp.num_inds;
|
||||
} else {
|
||||
building_run = false;
|
||||
memcpy(&idx_out[run_start_out],
|
||||
idx_in + draw.unpacked.idx_of_first_idx_in_full_buffer + run_start_in,
|
||||
(idx_buffer_ptr - run_start_out) * sizeof(u32));
|
||||
}
|
||||
} else {
|
||||
if (vis) {
|
||||
building_run = true;
|
||||
run_start_out = idx_buffer_ptr;
|
||||
run_start_in = vtx_idx;
|
||||
idx_buffer_ptr += grp.num_inds;
|
||||
}
|
||||
}
|
||||
vtx_idx += grp.num_inds;
|
||||
}
|
||||
|
||||
if (building_run) {
|
||||
memcpy(&idx_out[run_start_out],
|
||||
idx_in + draw.unpacked.idx_of_first_idx_in_full_buffer + run_start_in,
|
||||
(idx_buffer_ptr - run_start_out) * sizeof(u32));
|
||||
}
|
||||
|
||||
ds.second = idx_buffer_ptr - ds.first;
|
||||
group_out[i] = ds;
|
||||
}
|
||||
*num_tris_out = num_tris;
|
||||
return idx_buffer_ptr;
|
||||
}
|
||||
|
||||
u32 make_all_visible_index_list(std::pair<int, int>* group_out,
|
||||
u32* idx_out,
|
||||
const std::vector<tfrag3::StripDraw>& draws,
|
||||
const u32* idx_in,
|
||||
u32* num_tris_out) {
|
||||
int idx_buffer_ptr = 0;
|
||||
u32 num_tris = 0;
|
||||
for (size_t i = 0; i < draws.size(); i++) {
|
||||
const auto& draw = draws[i];
|
||||
std::pair<int, int> ds;
|
||||
ds.first = idx_buffer_ptr;
|
||||
u32 num_inds = 0;
|
||||
for (auto& grp : draw.vis_groups) {
|
||||
num_inds += grp.num_inds;
|
||||
num_tris += grp.num_tris;
|
||||
}
|
||||
memcpy(&idx_out[idx_buffer_ptr], idx_in + draw.unpacked.idx_of_first_idx_in_full_buffer,
|
||||
num_inds * sizeof(u32));
|
||||
idx_buffer_ptr += num_inds;
|
||||
ds.second = idx_buffer_ptr - ds.first;
|
||||
group_out[i] = ds;
|
||||
}
|
||||
*num_tris_out = num_tris;
|
||||
return idx_buffer_ptr;
|
||||
}
|
||||
@@ -74,4 +74,22 @@ u32 make_multidraws_from_vis_string(std::pair<int, int>* draw_ptrs_out,
|
||||
GLsizei* counts_out,
|
||||
void** index_offsets_out,
|
||||
const std::vector<tfrag3::StripDraw>& draws,
|
||||
const std::vector<u8>& vis_data);
|
||||
const std::vector<u8>& vis_data);
|
||||
|
||||
u32 make_all_visible_index_list(std::pair<int, int>* group_out,
|
||||
u32* idx_out,
|
||||
const std::vector<tfrag3::StripDraw>& draws,
|
||||
const u32* idx_in,
|
||||
u32* num_tris_out);
|
||||
|
||||
u32 make_index_list_from_vis_string(std::pair<int, int>* group_out,
|
||||
u32* idx_out,
|
||||
const std::vector<tfrag3::StripDraw>& draws,
|
||||
const std::vector<u8>& vis_data,
|
||||
const u32* idx_in,
|
||||
u32* num_tris_out);
|
||||
|
||||
u32 make_all_visible_index_list(std::pair<int, int>* group_out,
|
||||
u32* idx_out,
|
||||
const std::vector<tfrag3::ShrubDraw>& draws,
|
||||
const u32* idx_in);
|
||||
Reference in New Issue
Block a user