From 09e8a8f9819475291a2e755a277337e7d6b21b0e Mon Sep 17 00:00:00 2001 From: JuiceyDev Date: Fri, 27 Mar 2026 00:36:18 +0100 Subject: [PATCH] batch 2: fixing chunk rendering & frustum culling; rewrote most of it, but now it works. next step is to fix the "highlight" effect & add the optimizations i wrote on optifromhell.txt --- .../Platform/Linux/Linux_UIController.cpp | 2 +- Minecraft.Client/Rendering/Camera.cpp | 6 +- Minecraft.Client/Rendering/Frustum.cpp | 81 +++++++------------ Minecraft.Client/Rendering/FrustumData.cpp | 15 ++-- Minecraft.Client/Rendering/LevelRenderer.cpp | 21 ++++- Minecraft.Client/Rendering/Tesselator.cpp | 13 ++- 6 files changed, 69 insertions(+), 69 deletions(-) diff --git a/Minecraft.Client/Platform/Linux/Linux_UIController.cpp b/Minecraft.Client/Platform/Linux/Linux_UIController.cpp index 445fd5d9d..f4a1c033a 100644 --- a/Minecraft.Client/Platform/Linux/Linux_UIController.cpp +++ b/Minecraft.Client/Platform/Linux/Linux_UIController.cpp @@ -1,4 +1,4 @@ -// Linux_UIController.cpp +// should we keep Linux_UIController.cpp?* #include "../../../Minecraft.World/Platform/stdafx.h" #include "Linux_UIController.h" diff --git a/Minecraft.Client/Rendering/Camera.cpp b/Minecraft.Client/Rendering/Camera.cpp index f728f3f09..137108089 100644 --- a/Minecraft.Client/Rendering/Camera.cpp +++ b/Minecraft.Client/Rendering/Camera.cpp @@ -22,8 +22,10 @@ float Camera::xa2 = 0.0f; float Camera::za2 = 0.0f; void Camera::prepare(std::shared_ptr player, bool mirror) { - glGetFloat(GL_MODELVIEW_MATRIX, modelview); - glGetFloat(GL_PROJECTION_MATRIX, projection); + memcpy(modelview->_getDataPointer(), + RenderManager.MatrixGet(GL_MODELVIEW_MATRIX), 16 * sizeof(float)); + memcpy(projection->_getDataPointer(), + RenderManager.MatrixGet(GL_PROJECTION_MATRIX), 16 * sizeof(float)); /* Original java code for reference glGetInteger(GL_VIEWPORT, viewport); diff --git a/Minecraft.Client/Rendering/Frustum.cpp b/Minecraft.Client/Rendering/Frustum.cpp index 1144a7d5f..3d2e562ea 100644 --- a/Minecraft.Client/Rendering/Frustum.cpp +++ b/Minecraft.Client/Rendering/Frustum.cpp @@ -1,9 +1,11 @@ #include "../Platform/stdafx.h" #include "../../Minecraft.World/IO/Streams/FloatBuffer.h" #include "Frustum.h" +#include "Camera.h" Frustum* Frustum::frustum = new Frustum(); +// those are now unused but i still gotta do testing. Frustum::Frustum() { _proj = MemoryTracker::createFloatBuffer(16); _modl = MemoryTracker::createFloatBuffer(16); @@ -43,63 +45,38 @@ void Frustum::normalizePlane(float** frustum, int side) { } void Frustum::calculateFrustum() { - _proj->clear(); - _modl->clear(); - _clip->clear(); + // 4jcraft: GL 3.3 core removed GL_MODELVIEW_MATRIX / GL_PROJECTION_MATRIX + // queries. + // Camera::prepare() already captures both matrices every frame :) + // i spent an ungodly amount of time on this simple fix. + memcpy(proj.data, RenderManager.MatrixGet(GL_PROJECTION_MATRIX), + 16 * sizeof(float)); + memcpy(modl.data, RenderManager.MatrixGet(GL_MODELVIEW_MATRIX), + 16 * sizeof(float)); - // glGetFloatv() is used to extract information about our OpenGL world. - // Below, we pass in GL_PROJECTION_MATRIX to abstract our projection matrix. - // It then stores the matrix into an array of [16]. - glGetFloat(GL_PROJECTION_MATRIX, _proj); + float* p = proj.data; + float* m = modl.data; + float* c = clip.data; - // By passing in GL_MODELVIEW_MATRIX, we can abstract our model view matrix. - // This also stores it in an array of [16]. - glGetFloat(GL_MODELVIEW_MATRIX, _modl); + c[0] = m[0] * p[0] + m[1] * p[4] + m[2] * p[8] + m[3] * p[12]; + c[1] = m[0] * p[1] + m[1] * p[5] + m[2] * p[9] + m[3] * p[13]; + c[2] = m[0] * p[2] + m[1] * p[6] + m[2] * p[10] + m[3] * p[14]; + c[3] = m[0] * p[3] + m[1] * p[7] + m[2] * p[11] + m[3] * p[15]; - _proj->flip()->limit(16); - _proj->get(&proj); - _modl->flip()->limit(16); - _modl->get(&modl); + c[4] = m[4] * p[0] + m[5] * p[4] + m[6] * p[8] + m[7] * p[12]; + c[5] = m[4] * p[1] + m[5] * p[5] + m[6] * p[9] + m[7] * p[13]; + c[6] = m[4] * p[2] + m[5] * p[6] + m[6] * p[10] + m[7] * p[14]; + c[7] = m[4] * p[3] + m[5] * p[7] + m[6] * p[11] + m[7] * p[15]; - // Now that we have our modelview and projection matrix, if we combine these - // 2 matrices, it will give us our clipping planes. To combine 2 matrices, - // we multiply them. + c[8] = m[8] * p[0] + m[9] * p[4] + m[10] * p[8] + m[11] * p[12]; + c[9] = m[8] * p[1] + m[9] * p[5] + m[10] * p[9] + m[11] * p[13]; + c[10] = m[8] * p[2] + m[9] * p[6] + m[10] * p[10] + m[11] * p[14]; + c[11] = m[8] * p[3] + m[9] * p[7] + m[10] * p[11] + m[11] * p[15]; - clip[0] = modl[0] * proj[0] + modl[1] * proj[4] + modl[2] * proj[8] + - modl[3] * proj[12]; - clip[1] = modl[0] * proj[1] + modl[1] * proj[5] + modl[2] * proj[9] + - modl[3] * proj[13]; - clip[2] = modl[0] * proj[2] + modl[1] * proj[6] + modl[2] * proj[10] + - modl[3] * proj[14]; - clip[3] = modl[0] * proj[3] + modl[1] * proj[7] + modl[2] * proj[11] + - modl[3] * proj[15]; - - clip[4] = modl[4] * proj[0] + modl[5] * proj[4] + modl[6] * proj[8] + - modl[7] * proj[12]; - clip[5] = modl[4] * proj[1] + modl[5] * proj[5] + modl[6] * proj[9] + - modl[7] * proj[13]; - clip[6] = modl[4] * proj[2] + modl[5] * proj[6] + modl[6] * proj[10] + - modl[7] * proj[14]; - clip[7] = modl[4] * proj[3] + modl[5] * proj[7] + modl[6] * proj[11] + - modl[7] * proj[15]; - - clip[8] = modl[8] * proj[0] + modl[9] * proj[4] + modl[10] * proj[8] + - modl[11] * proj[12]; - clip[9] = modl[8] * proj[1] + modl[9] * proj[5] + modl[10] * proj[9] + - modl[11] * proj[13]; - clip[10] = modl[8] * proj[2] + modl[9] * proj[6] + modl[10] * proj[10] + - modl[11] * proj[14]; - clip[11] = modl[8] * proj[3] + modl[9] * proj[7] + modl[10] * proj[11] + - modl[11] * proj[15]; - - clip[12] = modl[12] * proj[0] + modl[13] * proj[4] + modl[14] * proj[8] + - modl[15] * proj[12]; - clip[13] = modl[12] * proj[1] + modl[13] * proj[5] + modl[14] * proj[9] + - modl[15] * proj[13]; - clip[14] = modl[12] * proj[2] + modl[13] * proj[6] + modl[14] * proj[10] + - modl[15] * proj[14]; - clip[15] = modl[12] * proj[3] + modl[13] * proj[7] + modl[14] * proj[11] + - modl[15] * proj[15]; + c[12] = m[12] * p[0] + m[13] * p[4] + m[14] * p[8] + m[15] * p[12]; + c[13] = m[12] * p[1] + m[13] * p[5] + m[14] * p[9] + m[15] * p[13]; + c[14] = m[12] * p[2] + m[13] * p[6] + m[14] * p[10] + m[15] * p[14]; + c[15] = m[12] * p[3] + m[13] * p[7] + m[14] * p[11] + m[15] * p[15]; // Now we actually want to get the sides of the frustum. To do this we take // the clipping planes we received above and extract the sides from them. diff --git a/Minecraft.Client/Rendering/FrustumData.cpp b/Minecraft.Client/Rendering/FrustumData.cpp index a5f11b768..eb46045e3 100644 --- a/Minecraft.Client/Rendering/FrustumData.cpp +++ b/Minecraft.Client/Rendering/FrustumData.cpp @@ -1,21 +1,22 @@ #include "../Platform/stdafx.h" #include "FrustumData.h" -float** m_Frustum; +// float** m_Frustum; FrustumData::FrustumData() { - m_Frustum = new float*[16]; - for (int i = 0; i < 16; i++) m_Frustum[i] = new float[16]; + this->m_Frustum = new float*[6]; + for (int i = 0; i < 6; i++) { + this->m_Frustum[i] = new float[4]; + } proj = floatArray(16); modl = floatArray(16); clip = floatArray(16); } FrustumData::~FrustumData() { - delete[] proj.data; - delete[] modl.data; - delete[] clip.data; - for (int i = 0; i < 16; i++) delete[] m_Frustum[i]; + for (int i = 0; i < 6; i++) { + delete[] m_Frustum[i]; + } delete[] m_Frustum; } diff --git a/Minecraft.Client/Rendering/LevelRenderer.cpp b/Minecraft.Client/Rendering/LevelRenderer.cpp index 0d5e9afa7..f64a9b284 100644 --- a/Minecraft.Client/Rendering/LevelRenderer.cpp +++ b/Minecraft.Client/Rendering/LevelRenderer.cpp @@ -856,6 +856,10 @@ int LevelRenderer::renderChunks(int from, int to, int layer, double alpha) { if ((globalChunkFlags[pClipChunk->globalIdx] & emptyFlag) == emptyFlag) continue; // Check that this particular layer isn't empty + glPushMatrix(); + + glTranslatef((float)pClipChunk->chunk->x, (float)pClipChunk->chunk->y, + (float)pClipChunk->chunk->z); // List can be calculated directly from the chunk's global idex int list = pClipChunk->globalIdx * 2 + layer; list += chunkLists; @@ -863,6 +867,8 @@ int LevelRenderer::renderChunks(int from, int to, int layer, double alpha) { if (RenderManager.CBuffCall(list, first)) { first = false; } + + glPopMatrix(); count++; } @@ -2248,9 +2254,13 @@ bool LevelRenderer::updateDirtyChunks() { // int64_t startTime = System::currentTimeMillis(); // app.DebugPrintf("Rebuilding permaChunk %d\n", index); - + Tesselator::getInstance()->offset(-permaChunk[index].x, + -permaChunk[index].y, + -permaChunk[index].z); permaChunk[index].rebuild(); + Tesselator::getInstance()->offset(0, 0, 0); + if (index != 0) s_rebuildCompleteEvents->Set( index - 1); // MGH - this rebuild happening on the main @@ -2303,7 +2313,10 @@ bool LevelRenderer::updateDirtyChunks() { // static int64_t totalTime = 0; // static int64_t countTime = 0; // int64_t startTime = System::currentTimeMillis(); + Tesselator::getInstance()->offset( + -permaChunk[index].x, -permaChunk[index].y, -permaChunk[index].z); permaChunk.rebuild(); + Tesselator::getInstance()->offset(0, 0, 0); // int64_t endTime = System::currentTimeMillis(); // totalTime += (endTime - startTime); // countTime++; @@ -4039,10 +4052,12 @@ int LevelRenderer::rebuildChunkThreadProc(void* lpParam) { while (true) { s_activationEventA[index]->WaitForSignal(INFINITE); - + Tesselator* t = Tesselator::getInstance(); + Tesselator::getInstance()->offset( + -permaChunk[index].x, -permaChunk[index].y, -permaChunk[index].z); // app.DebugPrintf("Rebuilding permaChunk %d\n", index + 1); permaChunk[index + 1].rebuild(); - + Tesselator::getInstance()->offset(0, 0, 0); // Inform the producer thread that we are done with this chunk s_rebuildCompleteEvents->Set(index); } diff --git a/Minecraft.Client/Rendering/Tesselator.cpp b/Minecraft.Client/Rendering/Tesselator.cpp index 49e6f5669..76e13d996 100644 --- a/Minecraft.Client/Rendering/Tesselator.cpp +++ b/Minecraft.Client/Rendering/Tesselator.cpp @@ -215,10 +215,15 @@ void Tesselator::end() { } #endif } - glDisableClientState(GL_VERTEX_ARRAY); - if (hasTexture) glDisableClientState(GL_TEXTURE_COORD_ARRAY); - if (hasColor) glDisableClientState(GL_COLOR_ARRAY); - if (hasNormal) glDisableClientState(GL_NORMAL_ARRAY); + // 4jcraft: gldisableclientstate breaks gl compat, commenting those lead + // to some weird glitches with input but.. somehow stopped one day so.. + // just keep an eye on these incase mouse locking stops working outta + // nowhere (i blame opengl not me) + // + // glDisableClientState(GL_VERTEX_ARRAY); if (hasTexture) + // glDisableClientState(GL_TEXTURE_COORD_ARRAY); if (hasColor) + // glDisableClientState(GL_COLOR_ARRAY); if (hasNormal) + // glDisableClientState(GL_NORMAL_ARRAY); } clear();