Occlusion Checking
This commit is contained in:
parent
a63125f335
commit
a8d0962491
@ -52,6 +52,7 @@
|
||||
* `Increase Render Chunk Size` (Enabled By Default)
|
||||
* `Proper Entity Shading` (Enabled By Default)
|
||||
* `Fix Sugar Position In Hand` (Enabled By Default)
|
||||
* `Chunk OpenGL Occlusion Checking` (Disabled By Default)
|
||||
* Existing Functionality (All Enabled By Default)
|
||||
* `Fix Screen Rendering When Hiding HUD`
|
||||
* `Sanitize Usernames`
|
||||
|
@ -113,3 +113,4 @@ TRUE Render Vignette
|
||||
TRUE Increase Render Chunk Size
|
||||
TRUE Proper Entity Shading
|
||||
TRUE Fix Sugar Position In Hand
|
||||
FALSE Chunk OpenGL Occlusion Checking
|
@ -501,6 +501,63 @@ static int safe_log2(const int x) {
|
||||
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
|
||||
void _init_misc_graphics() {
|
||||
// Disable V-Sync
|
||||
@ -651,6 +708,15 @@ void _init_misc_graphics() {
|
||||
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
|
||||
if (reborn_is_headless()) {
|
||||
overwrite_calls(GameRenderer_render, nop<GameRenderer_render_t, GameRenderer *, float>);
|
||||
|
@ -94,13 +94,13 @@ static void multidraw_renderSameAsLast(const LevelRenderer *self, const float b)
|
||||
media_glDisableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||
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
|
||||
multidraw_total = 0;
|
||||
for (int i = start; i < end; i++) {
|
||||
Chunk *chunk = self->chunks[i];
|
||||
// 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);
|
||||
// Get Data Block
|
||||
const int chunk_id = int(render_chunk->buffer - MULTIDRAW_BASE);
|
||||
|
@ -10,3 +10,4 @@ property float shadow_strength = 0x8;
|
||||
|
||||
// Globals
|
||||
static-property EntityRenderDispatcher *entityRenderDispatcher = 0x137bc0;
|
||||
static-method void renderFlat(const AABB &aabb) = 0x627c8;
|
@ -3,7 +3,15 @@ property int y = 0x8;
|
||||
property int z = 0xc;
|
||||
property bool field_1c[3] = 0x1c;
|
||||
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 int getList(int a) = 0x47e48;
|
||||
method RenderChunk *getRenderChunk(int a) = 0x47e74;
|
||||
method void renderBB() = 0x47ed8;
|
||||
method void setDirty() = 0x47ef0;
|
||||
method bool isEmpty() = 0x47edc;
|
@ -1,3 +1,7 @@
|
||||
vtable 0x107438;
|
||||
|
||||
constructor (Minecraft *minecraft) = 0x4e5f8;
|
||||
|
||||
method void tick() = 0x4da1c;
|
||||
method int render(Mob *mob, int param_1, float delta) = 0x4f710;
|
||||
method void render_AABB(const AABB &box) = 0x4d740;
|
||||
@ -11,3 +15,5 @@ method void renderEntities(Vec3 pos, void *unknown, float a) = 0x500ec;
|
||||
property Minecraft *minecraft = 0xb4;
|
||||
property RenderList render_list = 0x34;
|
||||
property Chunk **chunks = 0x98;
|
||||
property bool occlusion_check = 0xb8;
|
||||
property int num_buffers = 0xd0;
|
Loading…
Reference in New Issue
Block a user