fix: faster rendering pipeline & introduction to new gl constraints.

This commit is contained in:
JuiceyDev
2026-04-03 23:38:52 +02:00
parent 15f2f54a14
commit dc7625dfdd
4 changed files with 472 additions and 148 deletions
+13 -4
View File
@@ -377,7 +377,14 @@ static char* gdraw_strreplace(char* src, const char* find, const char* rep) {
} }
if (!count) return src; if (!count) return src;
result = (char*)malloc(strlen(src) + count * (rep_len + 1) + 1); size_t src_len = strlen(src);
ptrdiff_t delta = (ptrdiff_t)rep_len - (ptrdiff_t)find_len;
size_t new_len = src_len + 1;
if (delta > 0)
new_len += (size_t)delta * count;
else
new_len -= (size_t)(-delta) * count;
result = (char*)malloc(new_len);
if (!result) return src; if (!result) return src;
tmp = result; tmp = result;
@@ -389,7 +396,7 @@ static char* gdraw_strreplace(char* src, const char* find, const char* rep) {
tmp += rep_len; tmp += rep_len;
src = pos + find_len; src = pos + find_len;
} }
strcpy(tmp, src); memcpy(tmp, src, strlen(src) + 1);
free(base); free(base);
return result; return result;
} }
@@ -409,13 +416,15 @@ static void gdraw_ShaderSourceUpgraded(GLuint shader, GLsizei count,
return; return;
} }
src[0] = '\0'; char* dst = src;
for (int i = 0; i < count; i++) { for (int i = 0; i < count; i++) {
size_t len = lengths ? (lengths[i] >= 0 ? (size_t)lengths[i] size_t len = lengths ? (lengths[i] >= 0 ? (size_t)lengths[i]
: strlen(strings[i])) : strlen(strings[i]))
: strlen(strings[i]); : strlen(strings[i]);
strncat(src, strings[i], len); memcpy(dst, strings[i], len);
dst += len;
} }
*dst = '\0';
int is_vert = (gdraw_get_shader_type(shader) == GL_VERTEX_SHADER); int is_vert = (gdraw_get_shader_type(shader) == GL_VERTEX_SHADER);
@@ -106,6 +106,12 @@ ResourceLocation GameRenderer::SNOW_LOCATION =
// dirty light tracking // dirty light tracking
static bool s_lightTexDirty[XUSER_MAX_COUNT] = {true, true, true, true}; static bool s_lightTexDirty[XUSER_MAX_COUNT] = {true, true, true, true};
static uint64_t s_lightTexKey[XUSER_MAX_COUNT] = {};
static bool s_lightTexKeyValid[XUSER_MAX_COUNT] = {};
static inline uint8_t light_q8(float v) {
v = std::clamp(v, 0.0f, 1.0f);
return (uint8_t)(v * 255.0f + 0.5f);
}
GameRenderer::GameRenderer(Minecraft* mc) { GameRenderer::GameRenderer(Minecraft* mc) {
// 4J - added this block of initialisers // 4J - added this block of initialisers
@@ -877,6 +883,23 @@ void GameRenderer::updateLightTexture(float a) {
Level* level = player->level; Level* level = player->level;
float skyDarken1 = level->getSkyDarken((float)1); float skyDarken1 = level->getSkyDarken((float)1);
float amount =
darkenWorldAmountO + (darkenWorldAmount - darkenWorldAmountO) * a;
bool hasNV = player->hasEffect(MobEffect::nightVision);
float nvScale = hasNV ? getNightVisionScale(player, a) : 0.0f;
uint64_t key = 0;
key |= (uint64_t)light_q8(skyDarken1);
key |= (uint64_t)light_q8(blr) << 8;
key |= (uint64_t)light_q8(blg) << 16;
key |= (uint64_t)light_q8(amount) << 24;
key |= (uint64_t)light_q8(nvScale) << 32;
key |= (uint64_t)(level->skyFlashTime > 0 ? 1 : 0) << 40;
key |= (uint64_t)((unsigned int)level->dimension->id & 0xFF) << 48;
if (s_lightTexKeyValid[j] && s_lightTexKey[j] == key) continue;
s_lightTexKey[j] = key;
s_lightTexKeyValid[j] = true;
for (int i = 0; i < 256; i++) { for (int i = 0; i < 256; i++) {
float darken = skyDarken1 * 0.95f + 0.05f; float darken = skyDarken1 * 0.95f + 0.05f;
float sky = level->dimension->brightnessRamp[i / 16] * darken; float sky = level->dimension->brightnessRamp[i / 16] * darken;
@@ -1240,9 +1263,9 @@ void GameRenderer::renderLevel(float a, int64_t until) {
if (mc->options->anaglyph3d) { if (mc->options->anaglyph3d) {
GameRenderer::anaglyphPass = i; GameRenderer::anaglyphPass = i;
if (GameRenderer::anaglyphPass == 0) if (GameRenderer::anaglyphPass == 0)
glColorMask(false, true, true, false); RenderManager.StateSetWriteEnable(false, true, true, false);
else else
glColorMask(true, false, false, false); RenderManager.StateSetWriteEnable(true, false, false, false);
} }
glViewport(0, 0, mc->width, mc->height); glViewport(0, 0, mc->width, mc->height);
@@ -1376,8 +1399,8 @@ void GameRenderer::renderLevel(float a, int64_t until) {
glDisable(GL_BLEND); glDisable(GL_BLEND);
glEnable(GL_CULL_FACE); glEnable(GL_CULL_FACE);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); RenderManager.StateSetBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glDepthMask(true); RenderManager.StateSetDepthMask(true);
setupFog(0, a); setupFog(0, a);
glEnable(GL_BLEND); glEnable(GL_BLEND);
glDisable(GL_CULL_FACE); glDisable(GL_CULL_FACE);
@@ -1394,11 +1417,11 @@ void GameRenderer::renderLevel(float a, int64_t until) {
GL11::glShadeModel(GL11::GL_SMOOTH); GL11::glShadeModel(GL11::GL_SMOOTH);
} }
glBlendFunc(GL_ZERO, GL_ONE); RenderManager.StateSetBlendFunc(GL_ZERO, GL_ONE);
int visibleWaterChunks = int visibleWaterChunks =
levelRenderer->render(cameraEntity, 1, a, updateChunks); levelRenderer->render(cameraEntity, 1, a, updateChunks);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); RenderManager.StateSetBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
if (visibleWaterChunks > 0) { if (visibleWaterChunks > 0) {
levelRenderer->render( levelRenderer->render(
@@ -1433,7 +1456,7 @@ void GameRenderer::renderLevel(float a, int64_t until) {
turnOffLightLayer(a); // 4J - brought forward from 1.8.2 turnOffLightLayer(a); // 4J - brought forward from 1.8.2
////////////////////////// End of 4J added section ////////////////////////// End of 4J added section
glDepthMask(true); RenderManager.StateSetDepthMask(true);
glEnable(GL_CULL_FACE); glEnable(GL_CULL_FACE);
glDisable(GL_BLEND); glDisable(GL_BLEND);
@@ -1457,7 +1480,7 @@ void GameRenderer::renderLevel(float a, int64_t until) {
*/ */
glEnable(GL_BLEND); glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE); RenderManager.StateSetBlendFunc(GL_SRC_ALPHA, GL_ONE);
{ {
FRAME_PROFILE_SCOPE(WeatherSky); FRAME_PROFILE_SCOPE(WeatherSky);
levelRenderer->renderDestroyAnimation( levelRenderer->renderDestroyAnimation(
@@ -1491,7 +1514,7 @@ void GameRenderer::renderLevel(float a, int64_t until) {
return; return;
} }
} }
glColorMask(true, true, true, false); RenderManager.StateSetWriteEnable(true, true, true, false);
} }
void GameRenderer::prepareAndRenderClouds(LevelRenderer* levelRenderer, void GameRenderer::prepareAndRenderClouds(LevelRenderer* levelRenderer,
@@ -1620,7 +1643,7 @@ void GameRenderer::renderSnowAndRain(float a) {
glDisable(GL_CULL_FACE); glDisable(GL_CULL_FACE);
glNormal3f(0, 1, 0); glNormal3f(0, 1, 0);
glEnable(GL_BLEND); glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); RenderManager.StateSetBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glAlphaFunc(GL_GREATER, 0.01f); glAlphaFunc(GL_GREATER, 0.01f);
mc->textures->bindTexture( mc->textures->bindTexture(
@@ -1811,8 +1834,8 @@ void GameRenderer::setupGuiScreen(int forceScale /*=-1*/) {
glEnable(GL_ALPHA_TEST); glEnable(GL_ALPHA_TEST);
glAlphaFunc(GL_GREATER, 0.1f); glAlphaFunc(GL_GREATER, 0.1f);
glEnable(GL_DEPTH_TEST); glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LEQUAL); RenderManager.StateSetDepthFunc(GL_LEQUAL);
glDepthMask(true); RenderManager.StateSetDepthMask(true);
RenderManager.TextureBindVertex(-1); RenderManager.TextureBindVertex(-1);
+412 -132
View File
@@ -23,6 +23,16 @@
#undef glVertexPointer #undef glVertexPointer
#undef glGenQueriesARB #undef glGenQueriesARB
#undef glGetQueryObjectuARB #undef glGetQueryObjectuARB
#undef glEnable
#undef glDisable
#undef glBlendFunc
#undef glDepthMask
#undef glColorMask
#undef glLineWidth
#undef glFrontFace
#undef glPolygonOffset
#undef glStencilFunc
#undef glStencilMask
#define STB_IMAGE_IMPLEMENTATION #define STB_IMAGE_IMPLEMENTATION
#include "stb_image.h" #include "stb_image.h"
@@ -92,7 +102,45 @@ static pthread_mutex_t s_sharedMtx = PTHREAD_MUTEX_INITIALIZER;
static pthread_mutex_t s_glCallMtx = PTHREAD_MUTEX_INITIALIZER; static pthread_mutex_t s_glCallMtx = PTHREAD_MUTEX_INITIALIZER;
static pthread_t s_mainThread; static pthread_t s_mainThread;
static bool s_mainThreadSet = false; static bool s_mainThreadSet = false;
static thread_local bool s_rs_dirty = true; static thread_local unsigned int s_rs_dirty_mask = 0xFFFFFFFF;
struct GLShadowState {
bool blend;
bool cull;
bool depth;
bool polygon;
bool stencil;
GLint blendSrc;
GLint blendDst;
GLboolean depthMask;
GLboolean colorMask[4];
float lineWidth;
GLenum frontFace;
float polySlope;
float polyBias;
GLenum stencilFunc;
GLint stencilRef;
GLuint stencilMask;
GLuint stencilWriteMask;
};
static GLShadowState s_gl_state;
static unsigned int s_gl_shadow_mask = 0;
enum GLShadowBits {
SHADOW_BLEND = 1 << 0,
SHADOW_CULL = 1 << 1,
SHADOW_DEPTH = 1 << 2,
SHADOW_BLEND_FUNC = 1 << 3,
SHADOW_DEPTH_MASK = 1 << 4,
SHADOW_COLOR_MASK = 1 << 5,
SHADOW_LINE_WIDTH = 1 << 6,
SHADOW_FRONT_FACE = 1 << 7,
SHADOW_POLY_OFFSET = 1 << 8,
SHADOW_POLY_OFFSET_PARAMS = 1 << 9,
SHADOW_STENCIL = 1 << 10,
SHADOW_STENCIL_PARAMS = 1 << 11,
};
static void onFramebufferResize(int w, int h) { static void onFramebufferResize(int w, int h) {
if (w < 1) w = 1; if (w < 1) w = 1;
@@ -221,7 +269,9 @@ static thread_local int s_matMode = 0; // 0=MV 1=proj 2=tex0 3=tex1
static thread_local bool s_normalMatDirty = true; static thread_local bool s_normalMatDirty = true;
static thread_local glm::mat3 s_cachedNormalMat; static thread_local glm::mat3 s_cachedNormalMat;
static thread_local float s_cachedNormalSign = 1.0f; static thread_local float s_cachedNormalSign = 1.0f;
static thread_local bool s_matDirty = true;
static inline void markNormalDirty() { s_normalMatDirty = true; } static inline void markNormalDirty() { s_normalMatDirty = true; }
static inline void markMatrixDirty() { s_matDirty = true; }
static MatrixStack& activeStack() { static MatrixStack& activeStack() {
switch (s_matMode) { switch (s_matMode) {
@@ -236,22 +286,23 @@ static MatrixStack& activeStack() {
} }
static void flushMatrices() { static void flushMatrices() {
glm::mat4 mvp = s_proj.cur() * s_mv.cur(); if (s_matDirty) {
glUniformMatrix4fv(s_shader.uMVP, 1, GL_FALSE, glm::value_ptr(mvp)); glm::mat4 mvp = s_proj.cur() * s_mv.cur();
glUniformMatrix4fv(s_shader.uMV, 1, GL_FALSE, glm::value_ptr(s_mv.cur())); glUniformMatrix4fv(s_shader.uMVP, 1, GL_FALSE, glm::value_ptr(mvp));
glUniformMatrix4fv(s_shader.uMV, 1, GL_FALSE,
glm::value_ptr(s_mv.cur()));
// Send the texture matrix to the depths of hell... // Send the texture matrix to the depths of hell...
glUniformMatrix4fv(s_shader.uTexMat0, 1, GL_FALSE, glUniformMatrix4fv(s_shader.uTexMat0, 1, GL_FALSE,
glm::value_ptr(s_tex[0].cur())); glm::value_ptr(s_tex[0].cur()));
s_matDirty = false;
}
// if (s_shader.uLighting) if (s_shader.uNormalMatrix >= 0 && s_normalMatDirty) {
if (s_shader.uNormalMatrix >= 0) { glm::mat3 m3 = glm::mat3(s_mv.cur());
if (s_normalMatDirty) { s_cachedNormalMat = glm::transpose(glm::inverse(m3));
glm::mat3 m3 = glm::mat3(s_mv.cur()); s_cachedNormalSign = glm::determinant(m3) < 0.0f ? -1.0f : 1.0f;
s_cachedNormalMat = glm::transpose(glm::inverse(m3)); s_normalMatDirty = false;
s_cachedNormalSign = glm::determinant(m3) < 0.0f ? -1.0f : 1.0f;
s_normalMatDirty = false;
}
glUniformMatrix3fv(s_shader.uNormalMatrix, 1, GL_FALSE, glUniformMatrix3fv(s_shader.uNormalMatrix, 1, GL_FALSE,
glm::value_ptr(s_cachedNormalMat)); glm::value_ptr(s_cachedNormalMat));
glUniform1f(s_shader.uNormalSign, s_cachedNormalSign); glUniform1f(s_shader.uNormalSign, s_cachedNormalSign);
@@ -275,27 +326,154 @@ struct RenderState {
glm::vec4 lmt = {1, 1, 0, 0}; glm::vec4 lmt = {1, 1, 0, 0};
glm::vec2 globalLM = {240.f, 240.f}; // fullbright default glm::vec2 globalLM = {240.f, 240.f}; // fullbright default
int activeTexture = 0; int activeTexture = 0;
// we MAKE sure everything is FINE.
bool operator!=(const RenderState& o) const {
return baseColor != o.baseColor || fogColor != o.fogColor ||
fogStart != o.fogStart || fogEnd != o.fogEnd ||
fogDensity != o.fogDensity || fogMode != o.fogMode ||
fogEnable != o.fogEnable || alphaRef != o.alphaRef ||
gamma != o.gamma || useTexture != o.useTexture ||
useLightmap != o.useLightmap || lighting != o.lighting ||
l0 != o.l0 || l1 != o.l1 || ldiff != o.ldiff || lamb != o.lamb ||
lmt != o.lmt || globalLM != o.globalLM ||
activeTexture != o.activeTexture;
}
}; };
enum RenderDirtyBits {
DIRTY_BASECOLOR = 1 << 0,
DIRTY_LIGHTING = 1 << 1,
DIRTY_FOG = 1 << 2,
DIRTY_ALPHA = 1 << 3,
DIRTY_GAMMA = 1 << 4,
DIRTY_TEXTURE = 1 << 5,
DIRTY_LMT = 1 << 6,
DIRTY_GLOBAL_LM = 1 << 7,
};
static inline void markDirty(unsigned int bit) { s_rs_dirty_mask |= bit; }
static thread_local RenderState s_rs; static thread_local RenderState s_rs;
static RenderState s_gpu_state;
static bool s_gpu_state_valid = false;
// track currently bound program to avoid iggy shitting up // track currently bound program to avoid iggy shitting up
static GLuint s_boundProgram = 0; static GLuint s_boundProgram = 0;
static void glShadowSetBlend(bool e) {
if (!(s_gl_shadow_mask & SHADOW_BLEND) || s_gl_state.blend != e) {
if (e)
::glEnable(GL_BLEND);
else
::glDisable(GL_BLEND);
s_gl_state.blend = e;
s_gl_shadow_mask |= SHADOW_BLEND;
}
}
static void glShadowSetCull(bool e) {
if (!(s_gl_shadow_mask & SHADOW_CULL) || s_gl_state.cull != e) {
if (e)
::glEnable(GL_CULL_FACE);
else
::glDisable(GL_CULL_FACE);
s_gl_state.cull = e;
s_gl_shadow_mask |= SHADOW_CULL;
}
}
static void glShadowSetDepthTest(bool e) {
if (!(s_gl_shadow_mask & SHADOW_DEPTH) || s_gl_state.depth != e) {
if (e)
::glEnable(GL_DEPTH_TEST);
else
::glDisable(GL_DEPTH_TEST);
s_gl_state.depth = e;
s_gl_shadow_mask |= SHADOW_DEPTH;
}
}
static void glShadowSetBlendFunc(GLint s, GLint d) {
if (!(s_gl_shadow_mask & SHADOW_BLEND_FUNC) ||
s_gl_state.blendSrc != s || s_gl_state.blendDst != d) {
::glBlendFunc(s, d);
s_gl_state.blendSrc = s;
s_gl_state.blendDst = d;
s_gl_shadow_mask |= SHADOW_BLEND_FUNC;
}
}
static void glShadowSetDepthMask(GLboolean e) {
if (!(s_gl_shadow_mask & SHADOW_DEPTH_MASK) ||
s_gl_state.depthMask != e) {
::glDepthMask(e);
s_gl_state.depthMask = e;
s_gl_shadow_mask |= SHADOW_DEPTH_MASK;
}
}
static void glShadowSetColorMask(GLboolean r, GLboolean g, GLboolean b,
GLboolean a) {
if (!(s_gl_shadow_mask & SHADOW_COLOR_MASK) ||
s_gl_state.colorMask[0] != r || s_gl_state.colorMask[1] != g ||
s_gl_state.colorMask[2] != b || s_gl_state.colorMask[3] != a) {
::glColorMask(r, g, b, a);
s_gl_state.colorMask[0] = r;
s_gl_state.colorMask[1] = g;
s_gl_state.colorMask[2] = b;
s_gl_state.colorMask[3] = a;
s_gl_shadow_mask |= SHADOW_COLOR_MASK;
}
}
static void glShadowSetLineWidth(float w) {
if (!(s_gl_shadow_mask & SHADOW_LINE_WIDTH) || s_gl_state.lineWidth != w) {
::glLineWidth(w);
s_gl_state.lineWidth = w;
s_gl_shadow_mask |= SHADOW_LINE_WIDTH;
}
}
static void glShadowSetFrontFace(GLenum mode) {
if (!(s_gl_shadow_mask & SHADOW_FRONT_FACE) ||
s_gl_state.frontFace != mode) {
::glFrontFace(mode);
s_gl_state.frontFace = mode;
s_gl_shadow_mask |= SHADOW_FRONT_FACE;
}
}
static void glShadowSetPolygonOffset(float slope, float bias) {
bool enable = (slope != 0.0f || bias != 0.0f);
if (!(s_gl_shadow_mask & SHADOW_POLY_OFFSET) ||
s_gl_state.polygon != enable) {
if (enable)
::glEnable(GL_POLYGON_OFFSET_FILL);
else
::glDisable(GL_POLYGON_OFFSET_FILL);
s_gl_state.polygon = enable;
s_gl_shadow_mask |= SHADOW_POLY_OFFSET;
}
if (enable) {
if (!(s_gl_shadow_mask & SHADOW_POLY_OFFSET_PARAMS) ||
s_gl_state.polySlope != slope || s_gl_state.polyBias != bias) {
::glPolygonOffset(slope, bias);
s_gl_state.polySlope = slope;
s_gl_state.polyBias = bias;
s_gl_shadow_mask |= SHADOW_POLY_OFFSET_PARAMS;
}
}
}
static void glShadowSetStencil(GLenum fn, uint8_t ref, uint8_t fmask,
uint8_t wmask) {
if (!(s_gl_shadow_mask & SHADOW_STENCIL) || !s_gl_state.stencil) {
::glEnable(GL_STENCIL_TEST);
s_gl_state.stencil = true;
s_gl_shadow_mask |= SHADOW_STENCIL;
}
if (!(s_gl_shadow_mask & SHADOW_STENCIL_PARAMS) ||
s_gl_state.stencilFunc != fn || s_gl_state.stencilRef != (GLint)ref ||
s_gl_state.stencilMask != fmask ||
s_gl_state.stencilWriteMask != wmask) {
::glStencilFunc(fn, ref, fmask);
::glStencilMask(wmask);
s_gl_state.stencilFunc = fn;
s_gl_state.stencilRef = (GLint)ref;
s_gl_state.stencilMask = fmask;
s_gl_state.stencilWriteMask = wmask;
s_gl_shadow_mask |= SHADOW_STENCIL_PARAMS;
}
}
static thread_local bool s_chunkOffsetValid = false;
static thread_local glm::vec3 s_chunkOffset;
static void pushRenderState() { static void pushRenderState() {
if (!s_shader.prog) return; if (!s_shader.prog) return;
@@ -303,35 +481,53 @@ static void pushRenderState() {
if (s_boundProgram != s_shader.prog) { if (s_boundProgram != s_shader.prog) {
glUseProgram(s_shader.prog); glUseProgram(s_shader.prog);
s_boundProgram = s_shader.prog; s_boundProgram = s_shader.prog;
s_matDirty = true;
s_normalMatDirty = true;
s_rs_dirty_mask = 0xFFFFFFFF;
} }
if (!s_gpu_state_valid || s_gpu_state != s_rs) { if (s_rs_dirty_mask) {
glUniform4fv(s_shader.uBaseColor, 1, glm::value_ptr(s_rs.baseColor)); if (s_rs_dirty_mask & DIRTY_BASECOLOR)
glUniform1i(s_shader.uLighting, s_rs.lighting ? 1 : 0); glUniform4fv(s_shader.uBaseColor, 1,
glUniform3fv(s_shader.uLight0Dir, 1, glm::value_ptr(s_rs.l0)); glm::value_ptr(s_rs.baseColor));
glUniform3fv(s_shader.uLight1Dir, 1, glm::value_ptr(s_rs.l1)); if (s_rs_dirty_mask & DIRTY_LIGHTING) {
glUniform3fv(s_shader.uLightDiffuse, 1, glm::value_ptr(s_rs.ldiff)); glUniform1i(s_shader.uLighting, s_rs.lighting ? 1 : 0);
glUniform3fv(s_shader.uLightAmbient, 1, glm::value_ptr(s_rs.lamb)); glUniform3fv(s_shader.uLight0Dir, 1, glm::value_ptr(s_rs.l0));
glUniform1i(s_shader.uFogMode, s_rs.fogMode); glUniform3fv(s_shader.uLight1Dir, 1, glm::value_ptr(s_rs.l1));
glUniform1f(s_shader.uFogStart, s_rs.fogStart); glUniform3fv(s_shader.uLightDiffuse, 1, glm::value_ptr(s_rs.ldiff));
glUniform1f(s_shader.uFogEnd, s_rs.fogEnd); glUniform3fv(s_shader.uLightAmbient, 1, glm::value_ptr(s_rs.lamb));
glUniform1f(s_shader.uFogDensity, s_rs.fogDensity); }
glUniform4fv(s_shader.uFogColor, 1, glm::value_ptr(s_rs.fogColor)); if (s_rs_dirty_mask & DIRTY_FOG) {
glUniform1i(s_shader.uFogEnable, s_rs.fogEnable ? 1 : 0); glUniform1i(s_shader.uFogMode, s_rs.fogMode);
glUniform1i(s_shader.uUseTexture, s_rs.useTexture ? 1 : 0); glUniform1f(s_shader.uFogStart, s_rs.fogStart);
glUniform1i(s_shader.uUseLightmap, s_rs.useLightmap ? 1 : 0); glUniform1f(s_shader.uFogEnd, s_rs.fogEnd);
glUniform1f(s_shader.uAlphaRef, s_rs.alphaRef); glUniform1f(s_shader.uFogDensity, s_rs.fogDensity);
glUniform1f(s_shader.uInvGamma, 1.0f / s_rs.gamma); glUniform4fv(s_shader.uFogColor, 1,
glUniform4fv(s_shader.uLMTransform, 1, glm::value_ptr(s_rs.lmt)); glm::value_ptr(s_rs.fogColor));
glUniform2fv(s_shader.uGlobalLM, 1, glm::value_ptr(s_rs.globalLM)); glUniform1i(s_shader.uFogEnable, s_rs.fogEnable ? 1 : 0);
s_gpu_state = s_rs; }
s_gpu_state_valid = true; if (s_rs_dirty_mask & DIRTY_TEXTURE) {
s_rs_dirty = false; glUniform1i(s_shader.uUseTexture, s_rs.useTexture ? 1 : 0);
glUniform1i(s_shader.uUseLightmap, s_rs.useLightmap ? 1 : 0);
}
if (s_rs_dirty_mask & DIRTY_ALPHA)
glUniform1f(s_shader.uAlphaRef, s_rs.alphaRef);
if (s_rs_dirty_mask & DIRTY_GAMMA)
glUniform1f(s_shader.uInvGamma, 1.0f / s_rs.gamma);
if (s_rs_dirty_mask & DIRTY_LMT)
glUniform4fv(s_shader.uLMTransform, 1,
glm::value_ptr(s_rs.lmt));
if (s_rs_dirty_mask & DIRTY_GLOBAL_LM)
glUniform2fv(s_shader.uGlobalLM, 1,
glm::value_ptr(s_rs.globalLM));
s_rs_dirty_mask = 0;
} }
flushMatrices(); flushMatrices();
} }
static GLuint s_sVAO_std = 0, s_sVBO_std = 0; static GLuint s_sVAO_std = 0, s_sVBO_std = 0;
static GLsizeiptr s_streamVBOSize = 0;
static bool s_useMapRange = false;
static void bindStdAttribs() { static void bindStdAttribs() {
glEnableVertexAttribArray(0); glEnableVertexAttribArray(0);
@@ -472,18 +668,18 @@ void C4JRender::Initialise() {
int fw, fh; int fw, fh;
SDL_GetWindowSize(s_window, &fw, &fh); SDL_GetWindowSize(s_window, &fw, &fh);
onFramebufferResize(fw, fh); onFramebufferResize(fw, fh);
glEnable(GL_DEPTH_TEST); glShadowSetDepthTest(true);
glDepthFunc(GL_LEQUAL); ::glDepthFunc(GL_LEQUAL);
#ifdef GLES #ifdef GLES
glClearDepthf(1.0f); glClearDepthf(1.0f);
#else #else
glClearDepth(1.0); glClearDepth(1.0);
#endif #endif
glEnable(GL_BLEND); glShadowSetBlend(true);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glShadowSetBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glEnable(GL_CULL_FACE); glShadowSetCull(true);
glCullFace(GL_BACK); ::glCullFace(GL_BACK);
glClearColor(0, 0, 0, 1); ::glClearColor(0, 0, 0, 1);
glViewport(0, 0, s_windowWidth, s_windowHeight); glViewport(0, 0, s_windowWidth, s_windowHeight);
s_shader.build(VERT_SRC, FRAG_SRC); s_shader.build(VERT_SRC, FRAG_SRC);
initStreamingVAOs(); initStreamingVAOs();
@@ -548,6 +744,7 @@ void C4JRender::InitialiseContext() {
} }
void C4JRender::StartFrame() { void C4JRender::StartFrame() {
Set_matrixDirty();
int w, h; int w, h;
SDL_GetWindowSize(s_window, &w, &h); SDL_GetWindowSize(s_window, &w, &h);
s_windowWidth = w > 0 ? w : 1; s_windowWidth = w > 0 ? w : 1;
@@ -706,11 +903,27 @@ void C4JRender::DrawVertices(ePrimitiveType ptype, int count, void* dataIn,
glBindVertexArray(s_sVAO_std); glBindVertexArray(s_sVAO_std);
glBindBuffer(GL_ARRAY_BUFFER, s_sVBO_std); glBindBuffer(GL_ARRAY_BUFFER, s_sVBO_std);
// orphan buffer // orphan buffer
glBufferData(GL_ARRAY_BUFFER, (GLsizeiptr)bytes, nullptr, GL_STREAM_DRAW); if ((GLsizeiptr)bytes != s_streamVBOSize) {
glBufferData(GL_ARRAY_BUFFER, (GLsizeiptr)bytes, dataIn, GL_STREAM_DRAW); s_streamVBOSize = (GLsizeiptr)bytes;
bindStdAttribs(); glBufferData(GL_ARRAY_BUFFER, s_streamVBOSize, nullptr, GL_STREAM_DRAW);
}
if (s_useMapRange) {
void* dst = glMapBufferRange(
GL_ARRAY_BUFFER, 0, (GLsizeiptr)bytes,
GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_RANGE_BIT |
GL_MAP_UNSYNCHRONIZED_BIT);
if (dst) {
memcpy(dst, dataIn, bytes);
glUnmapBuffer(GL_ARRAY_BUFFER);
} else {
s_useMapRange = false;
}
}
if (!s_useMapRange) {
glBufferSubData(GL_ARRAY_BUFFER, 0, (GLsizeiptr)bytes, dataIn);
}
glDrawArrays(glMode, 0, count); glDrawArrays(glMode, 0, count);
@@ -828,39 +1041,48 @@ void C4JRender::MatrixMode(int t) {
void C4JRender::MatrixSetIdentity() { void C4JRender::MatrixSetIdentity() {
activeStack().load(glm::mat4(1.f)); activeStack().load(glm::mat4(1.f));
markMatrixDirty();
if (s_matMode == 0) markNormalDirty(); if (s_matMode == 0) markNormalDirty();
} }
void C4JRender::MatrixPush() { void C4JRender::MatrixPush() {
activeStack().push(); activeStack().push();
// push doesn't change cur() so no dirty needed but mark anyway to be safe // push doesn't change cur() so no dirty needed but mark anyway to be safe
// ;w; // ;w;
markMatrixDirty();
if (s_matMode == 0) markNormalDirty(); if (s_matMode == 0) markNormalDirty();
} }
void C4JRender::MatrixPop() { void C4JRender::MatrixPop() {
activeStack().pop(); activeStack().pop();
markMatrixDirty();
if (s_matMode == 0) markNormalDirty(); if (s_matMode == 0) markNormalDirty();
} }
void C4JRender::MatrixTranslate(float x, float y, float z) { void C4JRender::MatrixTranslate(float x, float y, float z) {
activeStack().mul(glm::translate(glm::mat4(1.f), {x, y, z})); activeStack().mul(glm::translate(glm::mat4(1.f), {x, y, z}));
markMatrixDirty();
if (s_matMode == 0) markNormalDirty(); if (s_matMode == 0) markNormalDirty();
} }
void C4JRender::MatrixRotate(float a, float x, float y, float z) { void C4JRender::MatrixRotate(float a, float x, float y, float z) {
activeStack().mul(glm::rotate(glm::mat4(1.f), a, {x, y, z})); activeStack().mul(glm::rotate(glm::mat4(1.f), a, {x, y, z}));
markMatrixDirty();
if (s_matMode == 0) markNormalDirty(); if (s_matMode == 0) markNormalDirty();
} }
void C4JRender::MatrixScale(float x, float y, float z) { void C4JRender::MatrixScale(float x, float y, float z) {
activeStack().mul(glm::scale(glm::mat4(1.f), {x, y, z})); activeStack().mul(glm::scale(glm::mat4(1.f), {x, y, z}));
markMatrixDirty();
if (s_matMode == 0) markNormalDirty(); if (s_matMode == 0) markNormalDirty();
} }
void C4JRender::MatrixPerspective(float fovy, float asp, float zn, float zf) { void C4JRender::MatrixPerspective(float fovy, float asp, float zn, float zf) {
s_proj.cur() = glm::perspective(glm::radians(fovy), asp, zn, zf); s_proj.cur() = glm::perspective(glm::radians(fovy), asp, zn, zf);
markMatrixDirty();
} }
void C4JRender::MatrixOrthogonal(float l, float r, float b, float t, float zn, void C4JRender::MatrixOrthogonal(float l, float r, float b, float t, float zn,
float zf) { float zf) {
s_proj.cur() = glm::ortho(l, r, b, t, zn, zf); s_proj.cur() = glm::ortho(l, r, b, t, zn, zf);
markMatrixDirty();
} }
void C4JRender::MatrixMult(float* m) { void C4JRender::MatrixMult(float* m) {
activeStack().mul(glm::make_mat4(m)); activeStack().mul(glm::make_mat4(m));
markMatrixDirty();
if (s_matMode == 0) markNormalDirty(); if (s_matMode == 0) markNormalDirty();
} }
const float* C4JRender::MatrixGet(int t) { const float* C4JRender::MatrixGet(int t) {
@@ -875,8 +1097,11 @@ const float* C4JRender::MatrixGet(int t) {
void C4JRender::Set_matrixDirty() { void C4JRender::Set_matrixDirty() {
// iggy wipes opengl state // iggy wipes opengl state
s_boundProgram = 0; s_boundProgram = 0;
s_gpu_state_valid = false; s_rs_dirty_mask = 0xFFFFFFFF;
s_normalMatDirty = true; // normal matrix dirt after iggy reset s_gl_shadow_mask = 0;
s_normalMatDirty = true; // normal matrix dirt after iggy reset
s_matDirty = true;
s_chunkOffsetValid = false;
if (s_shader.prog) { if (s_shader.prog) {
glUseProgram(s_shader.prog); glUseProgram(s_shader.prog);
s_boundProgram = s_shader.prog; s_boundProgram = s_shader.prog;
@@ -890,57 +1115,62 @@ void C4JRender::SetClearColour(const float c[4]) {
bool C4JRender::IsWidescreen() { return true; } bool C4JRender::IsWidescreen() { return true; }
bool C4JRender::IsHiDef() { return true; } bool C4JRender::IsHiDef() { return true; }
void C4JRender::StateSetColour(float r, float g, float b, float a) { void C4JRender::StateSetColour(float r, float g, float b, float a) {
s_rs.baseColor = {r, g, b, a}; glm::vec4 v = {r, g, b, a};
if (s_rs.baseColor != v) {
s_rs.baseColor = v;
markDirty(DIRTY_BASECOLOR);
}
} }
void C4JRender::SetChunkOffset(float x, float y, float z) { void C4JRender::SetChunkOffset(float x, float y, float z) {
if (s_shader.uChunkOffset >= 0) glUniform3f(s_shader.uChunkOffset, x, y, z); if (s_shader.uChunkOffset < 0) return;
glm::vec3 v = {x, y, z};
if (!s_chunkOffsetValid || s_chunkOffset != v) {
s_chunkOffset = v;
s_chunkOffsetValid = true;
}
if (s_boundProgram == s_shader.prog) {
glUniform3f(s_shader.uChunkOffset, x, y, z);
}
} }
void C4JRender::StateSetDepthMask(bool e) { void C4JRender::StateSetDepthMask(bool e) {
glDepthMask(e ? GL_TRUE : GL_FALSE); glShadowSetDepthMask(e ? GL_TRUE : GL_FALSE);
} }
void C4JRender::StateSetBlendEnable(bool e) { void C4JRender::StateSetBlendEnable(bool e) { glShadowSetBlend(e); }
if (e) void C4JRender::StateSetBlendFunc(int s, int d) {
glEnable(GL_BLEND); glShadowSetBlendFunc(s, d);
else
glDisable(GL_BLEND);
} }
void C4JRender::StateSetBlendFunc(int s, int d) { glBlendFunc(s, d); } void C4JRender::StateSetDepthFunc(int f) { ::glDepthFunc(f); }
void C4JRender::StateSetDepthFunc(int f) { glDepthFunc(f); } void C4JRender::StateSetFaceCull(bool e) { glShadowSetCull(e); }
void C4JRender::StateSetFaceCull(bool e) { void C4JRender::StateSetFaceCullCW(bool e) {
if (e) glShadowSetFrontFace(e ? GL_CW : GL_CCW);
glEnable(GL_CULL_FACE);
else
glDisable(GL_CULL_FACE);
} }
void C4JRender::StateSetFaceCullCW(bool e) { glFrontFace(e ? GL_CW : GL_CCW); }
void C4JRender::StateSetLineWidth(float w) { void C4JRender::StateSetLineWidth(float w) {
#ifndef GLES #ifndef GLES
glLineWidth(w); glShadowSetLineWidth(w);
#else #else
(void)w; (void)w;
#endif #endif
} }
void C4JRender::StateSetWriteEnable(bool r, bool g, bool b, bool a) { void C4JRender::StateSetWriteEnable(bool r, bool g, bool b, bool a) {
glColorMask(r, g, b, a); glShadowSetColorMask(r, g, b, a);
}
void C4JRender::StateSetDepthTestEnable(bool e) {
if (e)
glEnable(GL_DEPTH_TEST);
else
glDisable(GL_DEPTH_TEST);
} }
void C4JRender::StateSetDepthTestEnable(bool e) { glShadowSetDepthTest(e); }
void C4JRender::StateSetAlphaTestEnable(bool e) { void C4JRender::StateSetAlphaTestEnable(bool e) {
s_rs.alphaRef = e ? 0.1f : 0.f; float v = e ? 0.1f : 0.f;
} if (s_rs.alphaRef != v) {
void C4JRender::StateSetAlphaFunc(int, float p) { s_rs.alphaRef = p; } s_rs.alphaRef = v;
void C4JRender::StateSetDepthSlopeAndBias(float s, float b) { markDirty(DIRTY_ALPHA);
if (s || b) {
glEnable(GL_POLYGON_OFFSET_FILL);
glPolygonOffset(s, b);
} else {
glDisable(GL_POLYGON_OFFSET_FILL);
} }
} }
void C4JRender::StateSetAlphaFunc(int, float p) {
if (s_rs.alphaRef != p) {
s_rs.alphaRef = p;
markDirty(DIRTY_ALPHA);
}
}
void C4JRender::StateSetDepthSlopeAndBias(float s, float b) {
glShadowSetPolygonOffset(s, b);
}
void C4JRender::StateSetBlendFactor(unsigned int col) { void C4JRender::StateSetBlendFactor(unsigned int col) {
float a = ((col >> 24) & 0xFF) / 255.f; float a = ((col >> 24) & 0xFF) / 255.f;
float r = ((col >> 16) & 0xFF) / 255.f; float r = ((col >> 16) & 0xFF) / 255.f;
@@ -948,58 +1178,96 @@ void C4JRender::StateSetBlendFactor(unsigned int col) {
float b = (col & 0xFF) / 255.f; float b = (col & 0xFF) / 255.f;
glBlendColor(r, g, b, a); glBlendColor(r, g, b, a);
} }
void C4JRender::StateSetFogEnable(bool e) { s_rs.fogEnable = e; } void C4JRender::StateSetFogEnable(bool e) {
void C4JRender::StateSetFogMode(int mode) { if (s_rs.fogEnable != e) {
s_rs.fogMode = (mode == GL_LINEAR) ? 1 s_rs.fogEnable = e;
: (mode == GL_EXP) ? 2 markDirty(DIRTY_FOG);
: (mode == 0x0801) ? 3 }
: 0; }
void C4JRender::StateSetFogMode(int mode) {
int v = (mode == GL_LINEAR) ? 1 : (mode == GL_EXP) ? 2 : (mode == 0x0801) ? 3 : 0;
if (s_rs.fogMode != v) {
s_rs.fogMode = v;
markDirty(DIRTY_FOG);
}
}
void C4JRender::StateSetFogNearDistance(float d) {
if (s_rs.fogStart != d) {
s_rs.fogStart = d;
markDirty(DIRTY_FOG);
}
}
void C4JRender::StateSetFogFarDistance(float d) {
if (s_rs.fogEnd != d) {
s_rs.fogEnd = d;
markDirty(DIRTY_FOG);
}
}
void C4JRender::StateSetFogDensity(float d) {
if (s_rs.fogDensity != d) {
s_rs.fogDensity = d;
markDirty(DIRTY_FOG);
}
} }
void C4JRender::StateSetFogNearDistance(float d) { s_rs.fogStart = d; }
void C4JRender::StateSetFogFarDistance(float d) { s_rs.fogEnd = d; }
void C4JRender::StateSetFogDensity(float d) { s_rs.fogDensity = d; }
void C4JRender::StateSetFogColour(float r, float g, float b) { void C4JRender::StateSetFogColour(float r, float g, float b) {
s_rs.fogColor = {r, g, b, 1}; glm::vec4 v = {r, g, b, 1};
if (s_rs.fogColor != v) {
s_rs.fogColor = v;
markDirty(DIRTY_FOG);
}
} }
void C4JRender::StateSetLightingEnable(bool e) { void C4JRender::StateSetLightingEnable(bool e) {
s_rs.lighting = e; if (s_rs.lighting != e) {
s_rs_dirty = true; s_rs.lighting = e;
markDirty(DIRTY_LIGHTING);
}
} }
void C4JRender::StateSetLightColour(int, float r, float g, float b) { void C4JRender::StateSetLightColour(int, float r, float g, float b) {
s_rs.ldiff = {r, g, b}; glm::vec3 v = {r, g, b};
s_rs_dirty = true; if (s_rs.ldiff != v) {
s_rs.ldiff = v;
markDirty(DIRTY_LIGHTING);
}
} }
void C4JRender::StateSetLightAmbientColour(float r, float g, float b) { void C4JRender::StateSetLightAmbientColour(float r, float g, float b) {
s_rs.lamb = {r, g, b}; glm::vec3 v = {r, g, b};
s_rs_dirty = true; if (s_rs.lamb != v) {
s_rs.lamb = v;
markDirty(DIRTY_LIGHTING);
}
} }
void C4JRender::StateSetLightDirection(int light, float x, float y, float z) { void C4JRender::StateSetLightDirection(int light, float x, float y, float z) {
glm::vec3 d = glm::normalize(glm::mat3(s_mv.cur()) * glm::vec3(x, y, z)); glm::vec3 d = glm::normalize(glm::mat3(s_mv.cur()) * glm::vec3(x, y, z));
if (light == 0) if (light == 0) {
s_rs.l0 = d; if (s_rs.l0 != d) {
else s_rs.l0 = d;
s_rs.l1 = d; markDirty(DIRTY_LIGHTING);
}
} else {
if (s_rs.l1 != d) {
s_rs.l1 = d;
markDirty(DIRTY_LIGHTING);
}
}
} }
void C4JRender::StateSetViewport(eViewportType) { void C4JRender::StateSetViewport(eViewportType) {
glViewport(0, 0, s_windowWidth, s_windowHeight); glViewport(0, 0, s_windowWidth, s_windowHeight);
} }
void C4JRender::StateSetVertexTextureUV(float u, float v) { void C4JRender::StateSetVertexTextureUV(float u, float v) {
s_rs.globalLM = {u, v}; glm::vec2 val = {u, v};
if (s_rs.globalLM != val) {
s_rs.globalLM = val;
markDirty(DIRTY_GLOBAL_LM);
}
} }
void C4JRender::StateSetStencil(int fn, uint8_t ref, uint8_t fmask, void C4JRender::StateSetStencil(int fn, uint8_t ref, uint8_t fmask,
uint8_t wmask) { uint8_t wmask) {
glEnable(GL_STENCIL_TEST); glShadowSetStencil(fn, ref, fmask, wmask);
glStencilFunc(fn, ref, fmask);
glStencilMask(wmask);
} }
void C4JRender::StateSetTextureEnable(bool e) { void C4JRender::StateSetTextureEnable(bool e) {
if (s_rs.activeTexture == 0) { if (s_rs.activeTexture == 0 && s_rs.useTexture != e) {
s_rs.useTexture = e; s_rs.useTexture = e;
if (s_shader.prog) { markDirty(DIRTY_TEXTURE);
glUseProgram(s_shader.prog);
s_boundProgram = s_shader.prog;
glUniform1i(s_shader.uUseTexture, e ? 1 : 0);
}
} }
} }
void C4JRender::StateSetActiveTexture(int tex) { void C4JRender::StateSetActiveTexture(int tex) {
@@ -1021,7 +1289,10 @@ void C4JRender::TextureBind(int idx) {
} }
void C4JRender::TextureBindVertex(int idx, bool scaleLight) { void C4JRender::TextureBindVertex(int idx, bool scaleLight) {
if (idx < 0) { if (idx < 0) {
s_rs.useLightmap = false; if (s_rs.useLightmap) {
s_rs.useLightmap = false;
markDirty(DIRTY_TEXTURE);
}
glActiveTexture(GL_TEXTURE0); glActiveTexture(GL_TEXTURE0);
return; return;
} }
@@ -1032,9 +1303,17 @@ void C4JRender::TextureBindVertex(int idx, bool scaleLight) {
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glActiveTexture(GL_TEXTURE0); glActiveTexture(GL_TEXTURE0);
s_rs.useLightmap = true; if (!s_rs.useLightmap) {
s_rs.lmt = scaleLight ? glm::vec4{1.f, 1.f, 8.f / 256.f, 8.f / 256.f} s_rs.useLightmap = true;
: glm::vec4{1.f, 1.f, 0.f, 0.f}; markDirty(DIRTY_TEXTURE);
}
glm::vec4 newLmt =
scaleLight ? glm::vec4{1.f, 1.f, 8.f / 256.f, 8.f / 256.f}
: glm::vec4{1.f, 1.f, 0.f, 0.f};
if (s_rs.lmt != newLmt) {
s_rs.lmt = newLmt;
markDirty(DIRTY_LMT);
}
} }
void C4JRender::TextureSetTextureLevels(int l) { void C4JRender::TextureSetTextureLevels(int l) {
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, l > 0 ? l - 1 : 0); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, l > 0 ? l - 1 : 0);
@@ -1098,6 +1377,7 @@ int C4JRender::LoadTextureData(uint8_t* pb, uint32_t nb, D3DXIMAGE_INFO* i,
return hr; return hr;
} }
// TODO: TO REMOVE SOON.
void C4JRender::UpdateGamma(unsigned short usGamma) { void C4JRender::UpdateGamma(unsigned short usGamma) {
constexpr unsigned short GAMMA_MAX = 32768; constexpr unsigned short GAMMA_MAX = 32768;
s_rs.gamma = 0.5f + ((float)(usGamma) * (1.0f / GAMMA_MAX)); s_rs.gamma = 0.5f + ((float)(usGamma) * (1.0f / GAMMA_MAX));
@@ -1194,4 +1474,4 @@ void glLightModelfv(GLenum pname, const GLfloat* params) {
void glShadeModel(GLenum) {} void glShadeModel(GLenum) {}
void glColorMaterial(GLenum, GLenum) {} void glColorMaterial(GLenum, GLenum) {}
void glNormal3f(GLfloat, GLfloat, GLfloat) {} void glNormal3f(GLfloat, GLfloat, GLfloat) {}
} }
+12
View File
@@ -490,6 +490,12 @@ extern C4JRender RenderManager;
RenderManager.StateSetAlphaTestEnable(true); \ RenderManager.StateSetAlphaTestEnable(true); \
else if ((cap) == 0x0DE1 /*GL_TEXTURE_2D*/) \ else if ((cap) == 0x0DE1 /*GL_TEXTURE_2D*/) \
RenderManager.StateSetTextureEnable(true); \ RenderManager.StateSetTextureEnable(true); \
else if ((cap) == 0x0BE2 /*GL_BLEND*/) \
RenderManager.StateSetBlendEnable(true); \
else if ((cap) == 0x0B44 /*GL_CULL_FACE*/) \
RenderManager.StateSetFaceCull(true); \
else if ((cap) == 0x0B71 /*GL_DEPTH_TEST*/) \
RenderManager.StateSetDepthTestEnable(true); \
else if ((cap) == 0x4000 /*GL_LIGHT0*/) \ else if ((cap) == 0x4000 /*GL_LIGHT0*/) \
RenderManager.StateSetLightEnable(0, true); \ RenderManager.StateSetLightEnable(0, true); \
else if ((cap) == 0x4001 /*GL_LIGHT1*/) \ else if ((cap) == 0x4001 /*GL_LIGHT1*/) \
@@ -516,6 +522,12 @@ extern C4JRender RenderManager;
RenderManager.StateSetAlphaTestEnable(false); \ RenderManager.StateSetAlphaTestEnable(false); \
else if ((cap) == 0x0DE1 /*GL_TEXTURE_2D*/) \ else if ((cap) == 0x0DE1 /*GL_TEXTURE_2D*/) \
RenderManager.StateSetTextureEnable(false); \ RenderManager.StateSetTextureEnable(false); \
else if ((cap) == 0x0BE2 /*GL_BLEND*/) \
RenderManager.StateSetBlendEnable(false); \
else if ((cap) == 0x0B44 /*GL_CULL_FACE*/) \
RenderManager.StateSetFaceCull(false); \
else if ((cap) == 0x0B71 /*GL_DEPTH_TEST*/) \
RenderManager.StateSetDepthTestEnable(false); \
else if ((cap) == 0x4000 /*GL_LIGHT0*/) \ else if ((cap) == 0x4000 /*GL_LIGHT0*/) \
RenderManager.StateSetLightEnable(0, false); \ RenderManager.StateSetLightEnable(0, false); \
else if ((cap) == 0x4001 /*GL_LIGHT1*/) \ else if ((cap) == 0x4001 /*GL_LIGHT1*/) \