From a33f79733b315f539027eeb2d47c5ca1f2090dbf Mon Sep 17 00:00:00 2001 From: korenkonder Date: Mon, 24 Nov 2025 10:38:57 +0300 Subject: [PATCH] Fixed objects blacking out on Intel iGPUs --- src/CRE/mdl/disp_manager.cpp | 82 +++++++++++++++++++++++++----------- src/CRE/render_context.cpp | 13 ++++++ src/CRE/render_context.hpp | 2 + 3 files changed, 73 insertions(+), 24 deletions(-) diff --git a/src/CRE/mdl/disp_manager.cpp b/src/CRE/mdl/disp_manager.cpp index 1bad6478..18a6cd64 100644 --- a/src/CRE/mdl/disp_manager.cpp +++ b/src/CRE/mdl/disp_manager.cpp @@ -72,6 +72,9 @@ texture_data_struct::texture_data_struct() : field_0() { } namespace mdl { + static void bind_dummy_vertex_attrib_array(uint32_t index, + bool* vertex_attrib_array = 0, const int32_t value = 1); + static void gen_capsule_indices(std::vector& indices, int32_t slices, int32_t stacks, float_t length, bool wire, size_t start); static void gen_capsule_vertices(etc_obj_vertex_data* data, @@ -87,8 +90,6 @@ namespace mdl { static void gen_sphere_vertices(etc_obj_vertex_data* data, int32_t slices, int32_t stacks, float_t radius); - static void set_default_vertex_attrib(); - ObjSubMeshArgs::ObjSubMeshArgs() : sub_mesh(), mesh(), material(), textures(), mat_count(), mats(), vertex_buffer(), vertex_buffer_offset(), index_buffer(), set_blend_color(), chara_color(), self_shadow(), shadow(), morph_vertex_buffer(), morph_vertex_buffer_offset(), morph_weight(), texture_pattern_count(), @@ -1008,8 +1009,6 @@ namespace mdl { gl_state.bind_array_buffer(vbo, true); gl_state.bind_element_array_buffer(ebo, true); - set_default_vertex_attrib(); - glEnableVertexAttribArray(POSITION_INDEX); glVertexAttribPointer(POSITION_INDEX, 3, GL_FLOAT, GL_FALSE, buffer_size, (void*)offsetof(etc_obj_vertex_data, position)); @@ -1125,18 +1124,20 @@ namespace mdl { memcpy(&vertex_array->texcoord_array, texcoord_array, sizeof(texcoord_array)); gl_state.bind_vertex_array(vertex_array->vertex_array, true); - set_default_vertex_attrib(); gl_state.bind_array_buffer(vertex_buffer, true); if (index_buffer) gl_state.bind_element_array_buffer(index_buffer, true); + bool vertex_attrib_array[16] = {}; + size_t offset = vertex_buffer_offset; if (vertex_format & OBJ_VERTEX_POSITION) { glEnableVertexAttribArray(POSITION_INDEX); glVertexAttribPointer(POSITION_INDEX, 3, GL_FLOAT, GL_FALSE, size_vertex, (void*)offset); offset += 12; + vertex_attrib_array[POSITION_INDEX] = true; } if (vertex_format & OBJ_VERTEX_NORMAL) { @@ -1159,6 +1160,7 @@ namespace mdl { offset += 4; break; } + vertex_attrib_array[NORMAL_INDEX] = true; } if (vertex_format & OBJ_VERTEX_TANGENT) { @@ -1181,6 +1183,7 @@ namespace mdl { offset += 4; break; } + vertex_attrib_array[TANGENT_INDEX] = true; } if (!compression && (vertex_format & OBJ_VERTEX_BINORMAL)) @@ -1205,6 +1208,7 @@ namespace mdl { size_vertex, (void*)(offset + 4ULL * texcoord_index)); break; } + vertex_attrib_array[TEXCOORD0_INDEX + i] = true; } } @@ -1249,6 +1253,7 @@ namespace mdl { offset += 8; break; } + vertex_attrib_array[COLOR0_INDEX] = true; } if (!compression && (vertex_format & OBJ_VERTEX_COLOR1)) @@ -1274,6 +1279,7 @@ namespace mdl { offset += 4; break; } + vertex_attrib_array[BONE_WEIGHT_INDEX] = true; glEnableVertexAttribArray(BONE_INDEX_INDEX); switch (compression) { @@ -1290,6 +1296,7 @@ namespace mdl { offset += 4; break; } + vertex_attrib_array[BONE_INDEX_INDEX] = true; } if (!compression && (vertex_format & OBJ_VERTEX_UNKNOWN)) { @@ -1297,6 +1304,7 @@ namespace mdl { glVertexAttribPointer(UNKNOWN_INDEX, 4, GL_FLOAT, GL_FALSE, size_vertex, (void*)offset); offset += 16; + vertex_attrib_array[UNKNOWN_INDEX] = true; } if (morph_vertex_buffer) { @@ -1308,6 +1316,7 @@ namespace mdl { glVertexAttribPointer(MORPH_POSITION_INDEX, 3, GL_FLOAT, GL_FALSE, size_vertex, (void*)offset); offset += 12; + vertex_attrib_array[MORPH_POSITION_INDEX] = true; } if (vertex_format & OBJ_VERTEX_NORMAL) { @@ -1330,6 +1339,7 @@ namespace mdl { offset += 4; break; } + vertex_attrib_array[MORPH_NORMAL_INDEX] = true; } if (vertex_format & OBJ_VERTEX_TANGENT) { @@ -1352,6 +1362,7 @@ namespace mdl { offset += 4; break; } + vertex_attrib_array[MORPH_TANGENT_INDEX] = true; } if (!compression && (vertex_format & OBJ_VERTEX_BINORMAL)) @@ -1373,6 +1384,7 @@ namespace mdl { offset += 4; break; } + vertex_attrib_array[MORPH_TEXCOORD0_INDEX] = true; } if (vertex_format & OBJ_VERTEX_TEXCOORD1) { @@ -1391,6 +1403,7 @@ namespace mdl { offset += 4; break; } + vertex_attrib_array[MORPH_TEXCOORD1_INDEX] = true; } switch (compression) { @@ -1426,6 +1439,7 @@ namespace mdl { offset += 8; break; } + vertex_attrib_array[MORPH_COLOR_INDEX] = true; } switch (compression) { @@ -1451,6 +1465,12 @@ namespace mdl { } } + if (vertex_attrib_array[POSITION_INDEX]) + bind_dummy_vertex_attrib_array(COLOR0_INDEX, vertex_attrib_array, 2); + + if (vertex_attrib_array[MORPH_POSITION_INDEX]) + bind_dummy_vertex_attrib_array(MORPH_COLOR_INDEX, vertex_attrib_array, 2); + gl_state.bind_array_buffer(0); gl_state.bind_vertex_array(0); if (index_buffer) @@ -3266,6 +3286,39 @@ namespace mdl { wet_param = value; } + inline static void bind_dummy_vertex_attrib_array(uint32_t index, + bool* vertex_attrib_array, const int32_t value) { + if (vertex_attrib_array && vertex_attrib_array[index]) + return; + + if (Vulkan::use) { + if (value == 0) + glVertexAttrib4f(index, 0.0f, 0.0f, 0.0f, 0.0f); + else if (value == 2) + glVertexAttrib4f(index, 1.0f, 1.0f, 1.0f, 1.0f); + else + return; + } + else { + size_t offset; + if (value == 0) + offset = sizeof(float_t) * 4 * 0; // (0, 0, 0, 0) + else if (value == 2) + offset = sizeof(float_t) * 4 * 2; // (1, 1, 1, 1) + else + return; + + gl_state.bind_array_buffer(rctx_ptr->dummy_vbo); + + glEnableVertexAttribArray(index); + glVertexAttribPointer(index, 4, GL_FLOAT, GL_FALSE, sizeof(float_t) * 4, (void*)offset); + glVertexAttribDivisor(index, 1); + } + + if (vertex_attrib_array) + vertex_attrib_array[index] = true; + }; + static void gen_capsule_indices(std::vector& indices, int32_t slices, int32_t stacks, float_t length, bool wire, size_t start) { if (slices < 2 || stacks < 2) @@ -3696,25 +3749,6 @@ namespace mdl { *data++ = { { 0.0f, 0.0f, -radius }, { 0.0f, 0.0f, -1.0f } }; } - - inline static void set_default_vertex_attrib() { - glVertexAttrib4f( POSITION_INDEX, 0.0f, 0.0f, 0.0f, 1.0f); - glVertexAttrib4f( BONE_WEIGHT_INDEX, 0.0f, 0.0f, 0.0f, 0.0f); - glVertexAttrib4f( NORMAL_INDEX, 0.0f, 0.0f, 0.0f, 1.0f); - glVertexAttrib4f( COLOR0_INDEX, 1.0f, 1.0f, 1.0f, 1.0f); - glVertexAttrib4f( COLOR1_INDEX, 1.0f, 1.0f, 1.0f, 1.0f); - glVertexAttrib4f( MORPH_COLOR_INDEX, 1.0f, 1.0f, 1.0f, 1.0f); - glVertexAttrib4f( TANGENT_INDEX, 0.0f, 0.0f, 0.0f, 1.0f); - glVertexAttrib4f( UNKNOWN_INDEX, 0.0f, 0.0f, 0.0f, 1.0f); - glVertexAttrib4f( TEXCOORD0_INDEX, 0.0f, 0.0f, 0.0f, 1.0f); - glVertexAttrib4f( TEXCOORD1_INDEX, 0.0f, 0.0f, 0.0f, 1.0f); - glVertexAttrib4f( MORPH_POSITION_INDEX, 0.0f, 0.0f, 0.0f, 1.0f); - glVertexAttrib4f( MORPH_NORMAL_INDEX, 0.0f, 0.0f, 0.0f, 1.0f); - glVertexAttrib4f( MORPH_TANGENT_INDEX, 0.0f, 0.0f, 0.0f, 1.0f); - glVertexAttrib4f(MORPH_TEXCOORD0_INDEX, 0.0f, 0.0f, 0.0f, 1.0f); - glVertexAttrib4f(MORPH_TEXCOORD1_INDEX, 0.0f, 0.0f, 0.0f, 1.0f); - glVertexAttrib4f( BONE_INDEX_INDEX, 0.0f, 0.0f, 0.0f, 0.0f); - } } static void sub_140436760(const cam_data& cam) { diff --git a/src/CRE/render_context.cpp b/src/CRE/render_context.cpp index a606d27f..f1d1c715 100644 --- a/src/CRE/render_context.cpp +++ b/src/CRE/render_context.cpp @@ -1159,6 +1159,16 @@ sprite_width(), sprite_height(), screen_x_offset(), screen_y_offset(), screen_wi tone_map_ubo.Create(gl_state, sizeof(tone_map_shader_data)); transparency_batch_ubo.Create(gl_state, sizeof(transparency_batch_shader_data)); + if (!Vulkan::use) { + const float_t dummy_data[] = { + 0.0f, 0.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 0.0f, 1.0f, + 1.0f, 1.0f, 1.0f, 1.0f, + }; + + dummy_vbo.Create(gl_state, sizeof(dummy_data), dummy_data); + } + for (render_data& i : data) { i = {}; i.init(); @@ -1294,6 +1304,9 @@ render_context::~render_context() { for (render_data& i : data) i.free(); + if (!Vulkan::use) + dummy_vbo.Destroy(); + transparency_batch_ubo.Destroy(); tone_map_ubo.Destroy(); sun_quad_ubo.Destroy(); diff --git a/src/CRE/render_context.hpp b/src/CRE/render_context.hpp index d133f71d..8a12992d 100644 --- a/src/CRE/render_context.hpp +++ b/src/CRE/render_context.hpp @@ -600,6 +600,8 @@ struct render_context { GL::UniformBuffer tone_map_ubo; GL::UniformBuffer transparency_batch_ubo; + GL::ArrayBuffer dummy_vbo; + render_data data[GL_REND_STATE_COUNT]; texture* empty_texture_2d;