diff --git a/src/hardware/r_opengl/r_opengl.c b/src/hardware/r_opengl/r_opengl.c
index 75a92c2fb33ad542b0931786a9b4688a9f9dccbc..d1d16666e3446ed421bf6768b4275d930c6a8e29 100644
--- a/src/hardware/r_opengl/r_opengl.c
+++ b/src/hardware/r_opengl/r_opengl.c
@@ -626,6 +626,13 @@ typedef enum
 	gluniform_palette_lookup_tex, // 3d texture containing the rgb->index lookup table
 	gluniform_lighttable_tex, // 2d texture containing a light table
 
+	// rr
+	gluniform_tex,
+	gluniform_brightmap,
+	gluniform_light_dir,
+	gluniform_light_contrast,
+	gluniform_light_backlight,
+
 	// misc.
 	gluniform_leveltime,
 
@@ -657,6 +664,13 @@ static gl_shaderstate_t gl_shaderstate;
 // Shader info
 static float shader_leveltime = 0;
 
+// rr
+static float shader_light_x = 0.0f;
+static float shader_light_y = 0.0f;
+static float shader_light_z = 0.0f;
+static INT32 shader_light_contrast = 0;
+static INT32 shader_light_backlight = 0;
+
 // Lactozilla: Shader functions
 static boolean Shader_CompileProgram(gl_shader_t *shader, GLint i);
 static void Shader_CompileError(const char *message, GLuint program, INT32 shadernum);
@@ -799,6 +813,22 @@ EXPORT void HWRAPI(SetShaderInfo) (hwdshaderinfo_t info, INT32 value)
 		case HWD_SHADERINFO_LEVELTIME:
 			shader_leveltime = (((float)(value-1)) + FIXED_TO_FLOAT(rendertimefrac)) / TICRATE;
 			break;
+		// rr	
+		case HWD_SHADERINFO_LIGHT_X:
+			shader_light_x = FixedToFloat(value);
+			break;
+		case HWD_SHADERINFO_LIGHT_Y:
+			shader_light_y = FixedToFloat(value);
+			break;
+		case HWD_SHADERINFO_LIGHT_Z:
+			shader_light_z = FixedToFloat(value);
+			break;
+		case HWD_SHADERINFO_LIGHT_CONTRAST:
+			shader_light_contrast = value;
+			break;
+		case HWD_SHADERINFO_LIGHT_BACKLIGHT:
+			shader_light_backlight = value;
+			break;
 		default:
 			break;
 	}
@@ -862,14 +892,17 @@ EXPORT void HWRAPI(UnSetShader) (void)
 // -----------------+
 // SetNoTexture     : Disable texture
 // -----------------+
-static void SetNoTexture(void)
+//static void SetNoTexture(void)
+static void SetNoTexture(GLenum texture) // rr
 {
 	// Disable texture.
 	if (tex_downloaded != NOTEXTURE_NUM)
 	{
 		if (NOTEXTURE_NUM == 0)
 			pglGenTextures(1, &NOTEXTURE_NUM);
+		pglActiveTexture(texture); // rr
 		pglBindTexture(GL_TEXTURE_2D, NOTEXTURE_NUM);
+		pglActiveTexture(GL_TEXTURE0); // rr
 		tex_downloaded = NOTEXTURE_NUM;
 	}
 }
@@ -1015,7 +1048,7 @@ void SetStates(void)
 	SetBlend(0);
 
 	tex_downloaded = 0;
-	SetNoTexture();
+	SetNoTexture(GL_TEXTURE0); // rr
 
 	pglPolygonOffset(-1.0f, -1.0f);
 
@@ -1473,7 +1506,7 @@ EXPORT void HWRAPI(SetBlend) (FBITFIELD PolyFlags)
 		}
 		if (PolyFlags & PF_NoTexture)
 		{
-			SetNoTexture();
+			SetNoTexture(GL_TEXTURE0); // rr
 		}
 	}
 	CurrentPolyFlags = PolyFlags;
@@ -1597,6 +1630,14 @@ EXPORT void HWRAPI(UpdateTexture) (GLMipmap_t *pTexInfo)
 	else
 		GL_MSG_Warning("UpdateTexture: bad format %d\n", pTexInfo->format);
 
+	// rr
+	if (!(pTexInfo->flags & TF_BRIGHTMAP))
+	{
+		tex_downloaded = 0; // force update
+		SetNoTexture(GL_TEXTURE1); // will be assigned later, if needed
+	}
+
+	pglActiveTexture(pTexInfo->flags & TF_BRIGHTMAP ? GL_TEXTURE1 : GL_TEXTURE0); // rr
 	pglBindTexture(GL_TEXTURE_2D, num);
 	tex_downloaded = num;
 
@@ -1696,14 +1737,23 @@ EXPORT void HWRAPI(SetTexture) (GLMipmap_t *pTexInfo)
 {
 	if (!pTexInfo)
 	{
-		SetNoTexture();
+		SetNoTexture(GL_TEXTURE0); // rr
 		return;
 	}
 	else if (pTexInfo->downloaded)
 	{
 		if (pTexInfo->downloaded != tex_downloaded)
 		{
+			// rr
+			if (!(pTexInfo->flags & TF_BRIGHTMAP))
+			{
+				tex_downloaded = 0; // force update
+				SetNoTexture(GL_TEXTURE1); // will be assigned later, if needed
+			}
+			
+			pglActiveTexture(pTexInfo->flags & TF_BRIGHTMAP ? GL_TEXTURE1 : GL_TEXTURE0); // rr
 			pglBindTexture(GL_TEXTURE_2D, pTexInfo->downloaded);
+			pglActiveTexture(GL_TEXTURE0); // rr
 			tex_downloaded = pTexInfo->downloaded;
 		}
 	}
@@ -1775,15 +1825,33 @@ static void Shader_SetUniforms(FSurfaceInfo *Surface, GLRGBAFloat *poly, GLRGBAF
 				function (uniform, a, b, c, d);
 
 		// polygon
+		UNIFORM_1(shader->uniforms[gluniform_tex], 0, pglUniform1i); // rr
+		UNIFORM_1(shader->uniforms[gluniform_brightmap], 1, pglUniform1i); // rr
 		UNIFORM_4(shader->uniforms[gluniform_poly_color], poly->red, poly->green, poly->blue, poly->alpha, pglUniform4f);
 		UNIFORM_4(shader->uniforms[gluniform_tint_color], tint->red, tint->green, tint->blue, tint->alpha, pglUniform4f);
 		UNIFORM_4(shader->uniforms[gluniform_fade_color], fade->red, fade->green, fade->blue, fade->alpha, pglUniform4f);
 
+		boolean directional = false; // rr
 		if (Surface != NULL)
 		{
 			UNIFORM_1(shader->uniforms[gluniform_lighting], (GLfloat)Surface->LightInfo.light_level, pglUniform1f);
 			UNIFORM_1(shader->uniforms[gluniform_fade_start], (GLfloat)Surface->LightInfo.fade_start, pglUniform1f);
 			UNIFORM_1(shader->uniforms[gluniform_fade_end], (GLfloat)Surface->LightInfo.fade_end, pglUniform1f);
+			directional = Surface->LightInfo.directional; // rr
+		}
+
+		// rr
+		if (directional)
+		{
+			UNIFORM_3(shader->uniforms[gluniform_light_dir], shader_light_x, shader_light_y, shader_light_z, pglUniform3f);
+			UNIFORM_1(shader->uniforms[gluniform_light_contrast], shader_light_contrast, pglUniform1f);
+			UNIFORM_1(shader->uniforms[gluniform_light_backlight], shader_light_backlight, pglUniform1f);
+		}
+		else
+		{
+			UNIFORM_3(shader->uniforms[gluniform_light_dir], 0, 0, 0, pglUniform3f);
+			UNIFORM_1(shader->uniforms[gluniform_light_contrast], 0, pglUniform1f);
+			UNIFORM_1(shader->uniforms[gluniform_light_backlight], 0, pglUniform1f);
 		}
 
 		UNIFORM_1(shader->uniforms[gluniform_leveltime], shader_leveltime, pglUniform1f);
@@ -1911,6 +1979,13 @@ static boolean Shader_CompileProgram(gl_shader_t *shader, GLint i)
 	shader->uniforms[gluniform_palette_lookup_tex] = GETUNI("palette_lookup_tex");
 	shader->uniforms[gluniform_lighttable_tex] = GETUNI("lighttable_tex");
 
+	// rr
+	shader->uniforms[gluniform_tex] = GETUNI("tex");
+	shader->uniforms[gluniform_brightmap] = GETUNI("brightmap");
+	shader->uniforms[gluniform_light_dir] = GETUNI("light_dir");
+	shader->uniforms[gluniform_light_contrast] = GETUNI("light_contrast");
+	shader->uniforms[gluniform_light_backlight] = GETUNI("light_backlight");
+
 	// misc.
 	shader->uniforms[gluniform_leveltime] = GETUNI("leveltime");
 #undef GETUNI