Occlusion Checking

This commit is contained in:
TheBrokenRail 2024-11-09 00:17:25 -05:00
parent a63125f335
commit a8d0962491
7 changed files with 87 additions and 4 deletions

View File

@ -52,6 +52,7 @@
* `Increase Render Chunk Size` (Enabled By Default) * `Increase Render Chunk Size` (Enabled By Default)
* `Proper Entity Shading` (Enabled By Default) * `Proper Entity Shading` (Enabled By Default)
* `Fix Sugar Position In Hand` (Enabled By Default) * `Fix Sugar Position In Hand` (Enabled By Default)
* `Chunk OpenGL Occlusion Checking` (Disabled By Default)
* Existing Functionality (All Enabled By Default) * Existing Functionality (All Enabled By Default)
* `Fix Screen Rendering When Hiding HUD` * `Fix Screen Rendering When Hiding HUD`
* `Sanitize Usernames` * `Sanitize Usernames`

View File

@ -112,4 +112,5 @@ TRUE Render Entity Shadows
TRUE Render Vignette TRUE Render Vignette
TRUE Increase Render Chunk Size TRUE Increase Render Chunk Size
TRUE Proper Entity Shading TRUE Proper Entity Shading
TRUE Fix Sugar Position In Hand TRUE Fix Sugar Position In Hand
FALSE Chunk OpenGL Occlusion Checking

View File

@ -501,6 +501,63 @@ static int safe_log2(const int x) {
return z; return z;
} }
// Occlusion Checking
static int num_occlusion_ids;
static GLuint *occlusion_ids;
static LevelRenderer *LevelRenderer_injection(LevelRenderer_constructor_t original, LevelRenderer *self, Minecraft *minecraft) {
// Call Original Method
original(self, minecraft);
// Setup
self->occlusion_check = true;
num_occlusion_ids = self->num_buffers / 3;
occlusion_ids = new GLuint[num_occlusion_ids];
media_glGenQueries(num_occlusion_ids, occlusion_ids);
return self;
}
static void LevelRenderer_allChanged_Chunk_setDirty_injection(Chunk *self) {
self->occlusion_id = int(occlusion_ids[self->id]);
// Call Original Method
self->setDirty();
}
static void check_query_result(Chunk *chunk) {
if (chunk->occlusion_querying) {
GLuint val;
media_glGetQueryObjectuiv(chunk->occlusion_id, GL_QUERY_RESULT_AVAILABLE, &val);
if (val != 0) {
chunk->occlusion_querying = false;
media_glGetQueryObjectuiv(chunk->occlusion_id, GL_QUERY_RESULT, &val);
chunk->occlusion_visible = val != 0;
}
}
}
static int LevelRenderer_render_LevelRenderer_renderChunks_injection(LevelRenderer *self, const int start, const int end, const int a, const float b) {
for (int i = start; i < end; i++) {
Chunk *chunk = self->chunks[i];
check_query_result(chunk);
chunk->occlusion_visible = true;
}
// Call Original Method
return self->renderChunks(start, end, a, b);
}
static bool LevelRenderer_render_Chunk_isEmpty_injection(Chunk *self) {
check_query_result(self);
// Call Original Method
return self->isEmpty();
}
static void Chunk_renderBB_injection(__attribute__((unused)) Chunk_renderBB_t original, Chunk *self) {
media_glBeginQuery(GL_SAMPLES_PASSED, self->occlusion_id);
AABB aabb = {
.x1 = self->aabb.x1 - float(self->x),
.y1 = self->aabb.y1 - float(self->y),
.z1 = self->aabb.z1 - float(self->z),
.x2 = self->aabb.x2 - float(self->x),
.y2 = self->aabb.y2 - float(self->y),
.z2 = self->aabb.z2 - float(self->z)
};
EntityRenderer::renderFlat(aabb);
media_glEndQuery(GL_SAMPLES_PASSED);
}
// Init // Init
void _init_misc_graphics() { void _init_misc_graphics() {
// Disable V-Sync // Disable V-Sync
@ -651,6 +708,15 @@ void _init_misc_graphics() {
patch((void *) 0x4f20c, render_chunk_patch_seven); patch((void *) 0x4f20c, render_chunk_patch_seven);
} }
// Occlusion Checking
if(feature_has("Chunk OpenGL Occlusion Checking", server_disabled)) {
overwrite_calls(LevelRenderer_constructor, LevelRenderer_injection);
overwrite_call((void *) 0x4fce4, (void *) LevelRenderer_allChanged_Chunk_setDirty_injection);
overwrite_call((void *) 0x4f8d4, (void *) LevelRenderer_render_LevelRenderer_renderChunks_injection);
overwrite_call((void *) 0x4f960, (void *) LevelRenderer_render_Chunk_isEmpty_injection);
overwrite_calls(Chunk_renderBB, Chunk_renderBB_injection);
}
// Don't Render Game In Headless Mode // Don't Render Game In Headless Mode
if (reborn_is_headless()) { if (reborn_is_headless()) {
overwrite_calls(GameRenderer_render, nop<GameRenderer_render_t, GameRenderer *, float>); overwrite_calls(GameRenderer_render, nop<GameRenderer_render_t, GameRenderer *, float>);

View File

@ -94,13 +94,13 @@ static void multidraw_renderSameAsLast(const LevelRenderer *self, const float b)
media_glDisableClientState(GL_TEXTURE_COORD_ARRAY); media_glDisableClientState(GL_TEXTURE_COORD_ARRAY);
media_glPopMatrix(); media_glPopMatrix();
} }
static int LevelRenderer_renderChunks_injection(__attribute__((unused)) LevelRenderer_renderChunks_t original, LevelRenderer *self, const int start, const int end, const int a, const float b) { static int LevelRenderer_renderChunks_injection(__attribute__((unused)) LevelRenderer_renderChunks_t original, const LevelRenderer *self, const int start, const int end, const int a, const float b) {
// Batch // Batch
multidraw_total = 0; multidraw_total = 0;
for (int i = start; i < end; i++) { for (int i = start; i < end; i++) {
Chunk *chunk = self->chunks[i]; Chunk *chunk = self->chunks[i];
// Check If Chunk Is Visible // Check If Chunk Is Visible
if (!chunk->field_1c[a] && chunk->visible) { if (!chunk->field_1c[a] && chunk->visible && (!self->occlusion_check || chunk->occlusion_visible)) {
const RenderChunk *render_chunk = chunk->getRenderChunk(a); const RenderChunk *render_chunk = chunk->getRenderChunk(a);
// Get Data Block // Get Data Block
const int chunk_id = int(render_chunk->buffer - MULTIDRAW_BASE); const int chunk_id = int(render_chunk->buffer - MULTIDRAW_BASE);

View File

@ -10,3 +10,4 @@ property float shadow_strength = 0x8;
// Globals // Globals
static-property EntityRenderDispatcher *entityRenderDispatcher = 0x137bc0; static-property EntityRenderDispatcher *entityRenderDispatcher = 0x137bc0;
static-method void renderFlat(const AABB &aabb) = 0x627c8;

View File

@ -3,7 +3,15 @@ property int y = 0x8;
property int z = 0xc; property int z = 0xc;
property bool field_1c[3] = 0x1c; property bool field_1c[3] = 0x1c;
property bool visible = 0x4c; property bool visible = 0x4c;
property bool occlusion_visible = 0x4d;
property bool occlusion_querying = 0x4e;
property int occlusion_id = 0x50;
property AABB aabb = 0x30;
property int id = 0x48;
method float distanceToSqr(const Entity *entity) = 0x47ba0; method float distanceToSqr(const Entity *entity) = 0x47ba0;
method int getList(int a) = 0x47e48; method int getList(int a) = 0x47e48;
method RenderChunk *getRenderChunk(int a) = 0x47e74; method RenderChunk *getRenderChunk(int a) = 0x47e74;
method void renderBB() = 0x47ed8;
method void setDirty() = 0x47ef0;
method bool isEmpty() = 0x47edc;

View File

@ -1,3 +1,7 @@
vtable 0x107438;
constructor (Minecraft *minecraft) = 0x4e5f8;
method void tick() = 0x4da1c; method void tick() = 0x4da1c;
method int render(Mob *mob, int param_1, float delta) = 0x4f710; method int render(Mob *mob, int param_1, float delta) = 0x4f710;
method void render_AABB(const AABB &box) = 0x4d740; method void render_AABB(const AABB &box) = 0x4d740;
@ -10,4 +14,6 @@ method void renderEntities(Vec3 pos, void *unknown, float a) = 0x500ec;
property Minecraft *minecraft = 0xb4; property Minecraft *minecraft = 0xb4;
property RenderList render_list = 0x34; property RenderList render_list = 0x34;
property Chunk **chunks = 0x98; property Chunk **chunks = 0x98;
property bool occlusion_check = 0xb8;
property int num_buffers = 0xd0;