fix: restore block lightmap sampling

This commit is contained in:
MatthewBeshay 2026-03-24 08:21:19 +11:00
parent f5c5df3680
commit fdb2a1098b
6 changed files with 131 additions and 6 deletions

View file

@ -1,5 +1,7 @@
#ifdef __linux__
#include "../stdafx.h"
#include <GL/gl.h>
#include <GL/glu.h>
#include <GL/glext.h>
@ -9,6 +11,48 @@
#include "../../Minecraft.World/IO/Streams/FloatBuffer.h"
#include "../../Minecraft.World/IO/Streams/ByteBuffer.h"
void LinuxGLLogLightmapState(const char* stage, int textureId, bool scaleLight) {
static int logCount = 0;
if (logCount >= 16) return;
++logCount;
static bool loggedSymbols = false;
if (!loggedSymbols) {
loggedSymbols = true;
app.DebugPrintf(
"[linux-lightmap] linuxgl symbols glActiveTexture=%p "
"glClientActiveTexture=%p glMultiTexCoord2f=%p\n",
reinterpret_cast<void*>(::glActiveTexture),
reinterpret_cast<void*>(::glClientActiveTexture),
reinterpret_cast<void*>(::glMultiTexCoord2f));
}
GLint activeTexture = 0;
GLint matrixMode = 0;
::glGetIntegerv(GL_ACTIVE_TEXTURE, &activeTexture);
::glGetIntegerv(GL_MATRIX_MODE, &matrixMode);
const GLint restoreTexture = activeTexture;
::glActiveTexture(GL_TEXTURE1);
GLint unit1Binding = 0;
::glGetIntegerv(GL_TEXTURE_BINDING_2D, &unit1Binding);
const bool unit1Enabled = (::glIsEnabled(GL_TEXTURE_2D) == GL_TRUE);
GLfloat textureMatrix[16];
::glGetFloatv(GL_TEXTURE_MATRIX, textureMatrix);
::glActiveTexture(restoreTexture);
app.DebugPrintf(
"[linux-lightmap] %s tex=%d scale=%d active=%#x matrixMode=%#x "
"unit1Bound=%d unit1Enabled=%d texMatrix=[%.4f %.4f %.4f %.4f]\n",
stage, textureId, scaleLight ? 1 : 0, activeTexture, matrixMode,
unit1Binding, unit1Enabled ? 1 : 0, textureMatrix[0], textureMatrix[5],
textureMatrix[12], textureMatrix[13]);
}
int glGenTextures() {
GLuint id = 0;
::glGenTextures(1, &id);

View file

@ -1,6 +1,18 @@
#include "stdafx.h"
#ifndef __linux__
#ifdef __linux__
void LinuxLogStubLightmapProbe() {
static bool logged = false;
if (logged) return;
logged = true;
app.DebugPrintf(
"[linux-lightmap] stubs.cpp: Linux excludes the no-op multitexture "
"stubs in this file; the runtime uses libGL/4jlibs symbols.\n");
}
#else
void glReadPixels(int,int, int, int, int, int, ByteBuffer *)
{
@ -120,4 +132,4 @@ DWORD XCamSetView(
XCAMDEVICESTATE XCamGetStatus() { return XCAMDEVICESTATE_DISCONNECTED; }
#endif
#endif
#endif

View file

@ -34,6 +34,8 @@ void glBeginQueryARB(int, int);
void glEndQueryARB(int);
void glGetQueryObjectuARB(int, int, IntBuffer *);
void glReadPixels(int, int, int, int, int, int, ByteBuffer *);
void LinuxGLLogLightmapState(const char* stage, int textureId, bool scaleLight);
void LinuxLogStubLightmapProbe();
#else

View file

@ -441,6 +441,15 @@ void ItemInHandRenderer::render(float a) {
Mth::floor(player->z), 0);
int u = col % 65536;
int v = col / 65536;
#ifdef __linux__
static int lightmapLogCount = 0;
if (lightmapLogCount < 8) {
++lightmapLogCount;
app.DebugPrintf(
"[linux-lightmap] item-hand raw=0x%08x uv=(%d,%d)\n", col, u,
v);
}
#endif
glMultiTexCoord2f(GL_TEXTURE1, u / 1.0f, v / 1.0f);
glColor4f(1, 1, 1, 1);
}

View file

@ -767,6 +767,13 @@ void GameRenderer::renderItemInHand(float a, int eye) {
// 4J - change brought forward from 1.8.2
void GameRenderer::turnOffLightLayer(double alpha) { // 4J - TODO
#ifdef __linux__
if (SharedConstants::TEXTURE_LIGHTING) {
LinuxLogStubLightmapProbe();
RenderManager.TextureBindVertex(-1);
LinuxGLLogLightmapState("turnOffLightLayer", -1, false);
}
#else
// 4jcraft: manually handle this in order to ensure that the light layer is
// turned off correctly
#if 1
@ -784,12 +791,30 @@ void GameRenderer::turnOffLightLayer(double alpha) { // 4J - TODO
#else
RenderManager.TextureBindVertex(-1);
#endif
#endif
}
// 4J - change brought forward from 1.8.2
void GameRenderer::turnOnLightLayer(
double alpha,
bool scaleLight) { // 4jcraft: added scaleLight for entity lighting
#ifdef __linux__
if (!SharedConstants::TEXTURE_LIGHTING) return;
LinuxLogStubLightmapProbe();
const int textureId = getLightTexture(mc->player->GetXboxPad(), mc->level);
static int logCount = 0;
if (logCount < 16) {
++logCount;
app.DebugPrintf(
"[linux-lightmap] turnOnLightLayer tex=%d scale=%d\n", textureId,
scaleLight ? 1 : 0);
}
RenderManager.TextureBindVertex(textureId, scaleLight);
LinuxGLLogLightmapState("turnOnLightLayer", textureId, scaleLight);
#else
#if 0
if (SharedConstants::TEXTURE_LIGHTING)
{
@ -827,6 +852,7 @@ void GameRenderer::turnOnLightLayer(
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
#endif
#endif
}
// 4J - change brought forward from 1.8.2

View file

@ -741,6 +741,31 @@ typedef unsigned short hfloat;
extern hfloat convertFloatToHFloat(float f);
extern float convertHFloatToFloat(hfloat hf);
#ifdef __linux__
namespace {
void packLinuxLightmapCoords(int tex2, std::int16_t& u, std::int16_t& v) {
u = static_cast<std::int16_t>(tex2 & 0xffff);
v = static_cast<std::int16_t>((tex2 >> 16) & 0xffff);
// Linux 4jlibs consumes packed UV2 values by dividing them by 256 directly
// for chunk and other non-scaleLight draws, so offset to texel centers here.
u += 8;
v += 8;
}
void logLinuxPackedLightmapCoords(const char* path, int tex2, std::int16_t u,
std::int16_t v) {
static int logCount = 0;
if (logCount >= 16) return;
++logCount;
app.DebugPrintf(
"[linux-lightmap] %s raw=0x%08x packed=(%d,%d) sampled=(%.4f,%.4f)\n",
path, tex2, (int)u, (int)v, u / 256.0f, v / 256.0f);
}
} // namespace
#endif
void Tesselator::vertex(float x, float y, float z) {
bounds.addVert(x + xo, y + yo, z + zo); // 4J MGH - added
count++;
@ -828,8 +853,13 @@ void Tesselator::vertex(float x, float y, float z) {
pShortData[3] = ipackedcol;
pShortData[4] = (((int)(uu * 8192.0f)) & 0xffff);
pShortData[5] = (((int)(v * 8192.0f)) & 0xffff);
std::int16_t u2 = ((std::int16_t*)&_tex2)[0];
std::int16_t v2 = ((std::int16_t*)&_tex2)[1];
std::int16_t u2 = static_cast<std::int16_t>(_tex2 & 0xffff);
std::int16_t v2 =
static_cast<std::int16_t>((_tex2 >> 16) & 0xffff);
#ifdef __linux__
packLinuxLightmapCoords(_tex2, u2, v2);
logLinuxPackedLightmapCoords("compact", _tex2, u2, v2);
#endif
#if defined _XBOX_ONE || defined __ORBIS__
// Optimisation - pack the second UVs into a single short (they could
// actually go in a byte), which frees up a short to store the x offset
@ -943,8 +973,10 @@ void Tesselator::vertex(float x, float y, float z) {
std::int16_t tex2U = ((std::int16_t*)&_tex2)[1] + 8;
std::int16_t tex2V = ((std::int16_t*)&_tex2)[0] + 8;
#else
std::int16_t tex2U = ((std::int16_t*)&_tex2)[0] + 8;
std::int16_t tex2V = ((std::int16_t*)&_tex2)[1] + 8;
std::int16_t tex2U;
std::int16_t tex2V;
packLinuxLightmapCoords(_tex2, tex2U, tex2V);
logLinuxPackedLightmapCoords("standard", _tex2, tex2U, tex2V);
#endif
std::int16_t* pShortArray = (std::int16_t*)&_array->data[p + 7];
pShortArray[0] = tex2U;