Skip to content

Commit

Permalink
Use legacy envobj and detail object draw code if using a legacy shader
Browse files Browse the repository at this point in the history
  • Loading branch information
kavika13 committed Mar 16, 2024
1 parent b723171 commit b64451a
Show file tree
Hide file tree
Showing 2 changed files with 116 additions and 39 deletions.
16 changes: 10 additions & 6 deletions Source/Graphics/detailobjectsurface.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -623,7 +623,11 @@ void DetailObjectSurface::Draw(const mat4& transform, DetailObjectShaderType sha
}
}

int kBatchSize = 200 * (!g_ubo_batch_multiplier_force_1x ? ubo_batch_size_multiplier : 1);
int vertex_version_major, vertex_version_minor, fragment_version_major, fragment_version_minor;
shaders->GetProgramOvergrowthVersion(shader_id, vertex_version_major, vertex_version_minor, fragment_version_major, fragment_version_minor);
bool shader_is_v1_5_or_greater = vertex_version_major >= 1 && vertex_version_minor >= 5 && fragment_version_major >= 1 && fragment_version_minor >= 5;

int kBatchSize = 200 * (shader_is_v1_5_or_greater && !g_ubo_batch_multiplier_force_1x ? ubo_batch_size_multiplier : 1);

{
PROFILER_ZONE(g_profiler_ctx, "Issue draw calls");
Expand All @@ -636,11 +640,11 @@ void DetailObjectSurface::Draw(const mat4& transform, DetailObjectShaderType sha
if (indices[1] != GL_INVALID_INDEX) {
memcpy(&texcoords2[0], &draw_detail_instances[i], to_draw * sizeof(vec4));
}
{
// Copying over the whole block because fields aren't contiguous (struct of arrays), so at best can only save the final field's gap until the end of the buffer
detail_object_instance_buffer.Fill(block_size, blockBuffer);
glBindBufferRange(GL_UNIFORM_BUFFER, 0, detail_object_instance_buffer.gl_id, detail_object_instance_buffer.offset, detail_object_instance_buffer.next_offset - detail_object_instance_buffer.offset);
}

// Copying over the whole block because fields aren't contiguous (struct of arrays), so at best can only save the final field's gap until the end of the buffer
detail_object_instance_buffer.Fill(block_size, blockBuffer);
glBindBufferRange(GL_UNIFORM_BUFFER, 0, detail_object_instance_buffer.gl_id, detail_object_instance_buffer.offset, detail_object_instance_buffer.next_offset - detail_object_instance_buffer.offset);

CHECK_GL_ERROR();
graphics->DrawElementsInstanced(GL_TRIANGLES, bm.instance_num_faces, GL_UNSIGNED_INT, 0, to_draw);
CHECK_GL_ERROR();
Expand Down
139 changes: 106 additions & 33 deletions Source/Objects/envobject.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -257,11 +257,14 @@ static void UpdateNormalOverride(EnvObject* obj, Model* model) {

const size_t kAttribIdCountVboInstancing = 11;
const size_t kAttribIdCountUboInstancing = 7;
const size_t kAttribIdCountLegacyShader = 6;
static int attrib_ids[kAttribIdCountVboInstancing];

static void SetupAttribPointers(bool shader_changed, Model* model, VBORingContainer& env_object_model_translation_instance_vbo, VBORingContainer& env_object_model_scale_instance_vbo, VBORingContainer& env_object_model_rotation_quat_instance_vbo, VBORingContainer& env_object_color_tint_instance_vbo, VBORingContainer& env_object_detail_scale_instance_vbo, Shaders* shaders, int the_shader, Graphics* graphics) {
static void SetupAttribPointers(bool shader_changed, bool shader_is_v1_5_or_greater, Model* model, VBORingContainer& env_object_model_translation_instance_vbo, VBORingContainer& env_object_model_scale_instance_vbo, VBORingContainer& env_object_model_rotation_quat_instance_vbo, VBORingContainer& env_object_color_tint_instance_vbo, VBORingContainer& env_object_detail_scale_instance_vbo, Shaders* shaders, int the_shader, Graphics* graphics) {
bool attrib_envobj_instancing = g_attrib_envobj_intancing_support && g_attrib_envobj_intancing_enabled;
int attrib_count = attrib_envobj_instancing ? kAttribIdCountVboInstancing : kAttribIdCountUboInstancing;
int attrib_count = shader_is_v1_5_or_greater
? (attrib_envobj_instancing ? kAttribIdCountVboInstancing : kAttribIdCountUboInstancing)
: kAttribIdCountLegacyShader;
if (shader_changed) {
for (int i = 0; i < attrib_count; ++i) {
const char* attrib_str;
Expand Down Expand Up @@ -724,7 +727,13 @@ void EnvObject::DrawInstances(EnvObject** instance_array, int num_instances, con
}
model->VBO_faces.Bind();

int kBatchSize = 256 * (!g_ubo_batch_multiplier_force_1x ? ubo_batch_size_multiplier : 1);
int vertex_version_major, vertex_version_minor, fragment_version_major, fragment_version_minor;
shaders->GetProgramOvergrowthVersion(the_shader, vertex_version_major, vertex_version_minor, fragment_version_major, fragment_version_minor);
bool shader_is_v1_5_or_greater = vertex_version_major >= 1 && vertex_version_minor >= 5 && fragment_version_major >= 1 && fragment_version_minor >= 5;

int kBatchSize = shader_is_v1_5_or_greater
? (256 * (!g_ubo_batch_multiplier_force_1x ? ubo_batch_size_multiplier : 1))
: 100;
const bool ignore_multiplier = true;
static VBORingContainer env_object_model_translation_instance_vbo(sizeof(vec3) * kBatchSize * 16, kVBOFloat | kVBOStream, ignore_multiplier);
static VBORingContainer env_object_model_scale_instance_vbo(sizeof(vec3) * kBatchSize * 15, kVBOFloat | kVBOStream, ignore_multiplier);
Expand All @@ -735,7 +744,8 @@ void EnvObject::DrawInstances(EnvObject** instance_array, int num_instances, con
PROFILER_LEAVE(g_profiler_ctx); // Attribs
PROFILER_LEAVE(g_profiler_ctx); // Setup

bool attrib_envobj_instancing = g_attrib_envobj_intancing_support && g_attrib_envobj_intancing_enabled;
bool attrib_envobj_instancing = shader_is_v1_5_or_greater &&
g_attrib_envobj_intancing_support && g_attrib_envobj_intancing_enabled; // TODO: Typo in these names

int instance_block_index = shaders->GetUBOBindIndex(the_shader, "InstanceInfo");
if (attrib_envobj_instancing || (unsigned)instance_block_index != GL_INVALID_INDEX) {
Expand All @@ -754,8 +764,11 @@ void EnvObject::DrawInstances(EnvObject** instance_array, int num_instances, con

static GLubyte blockBuffer[131072]; // Big enough for 8x the OpenGL guaranteed minimum size. Max supported by shader flags currently. 16x or higher could be added if new platforms end up having > 128k frequently

// For shaders v1.5 or greater
static std::vector<vec3> model_translation_buffer;
model_translation_buffer.resize(kBatchSize);
if (shader_is_v1_5_or_greater) {
model_translation_buffer.resize(kBatchSize);
}

static std::vector<vec3> model_scale_buffer;
static std::vector<vec4> model_rotation_quat_buffer;
Expand All @@ -769,12 +782,37 @@ void EnvObject::DrawInstances(EnvObject** instance_array, int num_instances, con
detail_scale_buffer.resize(kBatchSize);
}

// For legacy shaders
static std::vector<mat4> model_mat_buffer;
static std::vector<vec4> model_rotation_mat_buffer;

for (int i = 0; i < num_instances; i += kBatchSize) {
vec3* model_translation_attrib = &model_translation_buffer[0];
vec3* model_scale = attrib_envobj_instancing ? &model_scale_buffer[0] : (vec3*)((uintptr_t)blockBuffer + 0 * sizeof(float) * 4);
vec4* model_rotation_quat = attrib_envobj_instancing ? &model_rotation_quat_buffer[0] : (vec4*)((uintptr_t)blockBuffer + 1 * sizeof(float) * 4);
vec4* color_tint = attrib_envobj_instancing ? &color_tint_buffer[0] : (vec4*)((uintptr_t)blockBuffer + 2 * sizeof(float) * 4);
vec4* detail_scale = attrib_envobj_instancing ? &detail_scale_buffer[0] : (vec4*)((uintptr_t)blockBuffer + 3 * sizeof(float) * 4);
// For shaders v1.5 or greater
vec3* model_translation_attrib = NULL;
vec3* model_scale = NULL;
vec4* model_rotation_quat = NULL;
vec4* color_tint = NULL;
vec4* detail_scale = NULL;

// For legacy shaders
mat4* model_mat = NULL;
vec4* model_rotation_mat = NULL;

if (shader_is_v1_5_or_greater) {
// For shaders v1.5 or greater
model_translation_attrib = &model_translation_buffer[0];
model_scale = attrib_envobj_instancing ? &model_scale_buffer[0] : (vec3*)((uintptr_t)blockBuffer + 0 * sizeof(float) * 4);
model_rotation_quat = attrib_envobj_instancing ? &model_rotation_quat_buffer[0] : (vec4*)((uintptr_t)blockBuffer + 1 * sizeof(float) * 4);
color_tint = attrib_envobj_instancing ? &color_tint_buffer[0] : (vec4*)((uintptr_t)blockBuffer + 2 * sizeof(float) * 4);
detail_scale = attrib_envobj_instancing ? &detail_scale_buffer[0] : (vec4*)((uintptr_t)blockBuffer + 3 * sizeof(float) * 4);
} else {
// For legacy shaders
model_mat = (mat4*)((uintptr_t)blockBuffer + 0 * sizeof(float) * 4);
model_rotation_mat = (vec4*)((uintptr_t)blockBuffer + 4 * sizeof(float) * 4);
color_tint = (vec4*)((uintptr_t)blockBuffer + 7 * sizeof(float) * 4);
detail_scale = (vec4*)((uintptr_t)blockBuffer + 8 * sizeof(float) * 4);
}

if (!attrib_envobj_instancing) {
glUniformBlockBinding(shaders->programs[the_shader].gl_program, instance_block_index, 0);
}
Expand All @@ -784,17 +822,38 @@ void EnvObject::DrawInstances(EnvObject** instance_array, int num_instances, con
EnvObject* obj = instance_array[i + j];
PlantComponent* plant_component = obj->plant_component_.get();
{
*model_scale = obj->scale_;
*model_rotation_quat = *(vec4*)&obj->GetRotation();
*model_translation_attrib = obj->translation_;
if (plant_component && plant_component->IsActive()) {
// TODO: This used to calculate a pivot. Is that important anymore, or can it just rotate around its origin?
// if(!plant_component->IsPivotCalculated()){
// plant_component->SetPivot(*scenegraph_->bullet_world_,
// obj->sphere_center_, obj->sphere_radius_);
//}
quaternion plant_rotation = plant_component->GetQuaternion(obj->sphere_radius_) * obj->GetRotation();
*model_rotation_quat = *(vec4*)&plant_rotation;
if (shader_is_v1_5_or_greater) {
// For shaders v1.5 or greater
*model_scale = obj->scale_;
*model_rotation_quat = *(vec4*)&obj->GetRotation();
*model_translation_attrib = obj->translation_;
if (plant_component && plant_component->IsActive()) {
// TODO: This used to calculate a pivot. Is that important anymore, or can it just rotate around its origin?
// if(!plant_component->IsPivotCalculated()){
// plant_component->SetPivot(*scenegraph_->bullet_world_,
// obj->sphere_center_, obj->sphere_radius_);
//}
quaternion plant_rotation = plant_component->GetQuaternion(obj->sphere_radius_) * obj->GetRotation();
*model_rotation_quat = *(vec4*)&plant_rotation;
}
} else {
// For legacy shaders
*model_mat = obj->transform_;
if(plant_component && plant_component->IsActive()){
if(!plant_component->IsPivotCalculated()){
plant_component->SetPivot(*scenegraph_->bullet_world_,
obj->sphere_center_, obj->sphere_radius_);
}
const vec3 &pivot = plant_component->GetPivot();

mat4 base_mat = obj->transform_;
vec3 base_trans = base_mat.GetTranslationPart();
base_mat.SetTranslationPart(base_trans-pivot);
mat4 transform = plant_component->GetTransform(obj->sphere_radius_) * base_mat;
transform.AddTranslation(pivot-base_trans);
transform.AddTranslation(base_trans);
*model_mat = transform;
}
}
}
{
Expand All @@ -819,17 +878,29 @@ void EnvObject::DrawInstances(EnvObject** instance_array, int num_instances, con
*detail_scale = scale_vec;
}

++model_translation_attrib;
if (attrib_envobj_instancing) {
++model_scale;
++model_rotation_quat;
++color_tint;
++detail_scale;
if (shader_is_v1_5_or_greater) {
// For shaders v1.5 or greater
++model_translation_attrib;

if (attrib_envobj_instancing) {
++model_scale;
++model_rotation_quat;
++color_tint;
++detail_scale;
} else {
model_scale = (vec3*)((uintptr_t)model_scale + 64);
model_rotation_quat = (vec4*)((uintptr_t)model_rotation_quat + 64);
color_tint = (vec4*)((uintptr_t)color_tint + 64);
detail_scale = (vec4*)((uintptr_t)detail_scale + 64);
}
} else {
model_scale = (vec3*)((uintptr_t)model_scale + 64);
model_rotation_quat = (vec4*)((uintptr_t)model_rotation_quat + 64);
color_tint = (vec4*)((uintptr_t)color_tint + 64);
detail_scale = (vec4*)((uintptr_t)detail_scale + 64);
// For legacy shaders
memcpy(&model_rotation_mat[0], &(obj->rotation_mat_), sizeof(vec4) * 3);

model_mat = (mat4*)((uintptr_t)model_mat + 144);
model_rotation_mat = (vec4*)((uintptr_t)model_rotation_mat + 144);
color_tint = (vec4*)((uintptr_t)color_tint + 144);
detail_scale = (vec4*)((uintptr_t)detail_scale + 144);
}

if (g_draw_collision) {
Expand All @@ -847,7 +918,9 @@ void EnvObject::DrawInstances(EnvObject** instance_array, int num_instances, con
}
PROFILER_LEAVE(g_profiler_ctx); // Setup batch data
{
env_object_model_translation_instance_vbo.Fill(sizeof(vec3) * to_draw, &model_translation_buffer[0]);
if (shader_is_v1_5_or_greater) {
env_object_model_translation_instance_vbo.Fill(sizeof(vec3) * to_draw, &model_translation_buffer[0]);
}

if (attrib_envobj_instancing) {
env_object_model_scale_instance_vbo.Fill(sizeof(vec3) * to_draw, &model_scale_buffer[0]);
Expand All @@ -856,7 +929,7 @@ void EnvObject::DrawInstances(EnvObject** instance_array, int num_instances, con
env_object_detail_scale_instance_vbo.Fill(sizeof(vec4) * to_draw, &detail_scale_buffer[0]);
}

SetupAttribPointers(shader_changed, model, env_object_model_translation_instance_vbo, env_object_model_scale_instance_vbo, env_object_model_rotation_quat_instance_vbo, env_object_color_tint_instance_vbo, env_object_detail_scale_instance_vbo, shaders, the_shader, graphics);
SetupAttribPointers(shader_changed, shader_is_v1_5_or_greater, model, env_object_model_translation_instance_vbo, env_object_model_scale_instance_vbo, env_object_model_rotation_quat_instance_vbo, env_object_color_tint_instance_vbo, env_object_detail_scale_instance_vbo, shaders, the_shader, graphics);
shader_changed = false;

if (!attrib_envobj_instancing) {
Expand Down

0 comments on commit b64451a

Please sign in to comment.