void Rend_DrawMaskedWall(drawmaskedwallparams_t const &parms) { DENG_ASSERT_IN_MAIN_THREAD(); DENG_ASSERT_GL_CONTEXT_ACTIVE(); TextureVariant *tex = nullptr; if(::renderTextures) { MaterialAnimator *matAnimator = parms.animator; DENG2_ASSERT(matAnimator); // Ensure we have up to date info about the material. matAnimator->prepare(); tex = matAnimator->texUnit(MaterialAnimator::TU_LAYER0).texture; } // Do we have a dynamic light to blend with? // This only happens when multitexturing is enabled. bool withDyn = false; dint normal = 0, dyn = 1; if(parms.modTex && ::numTexUnits > 1) { if(IS_MUL) { normal = 1; dyn = 0; } else { normal = 0; dyn = 1; } GL_SelectTexUnits(2); GL_ModulateTexture(IS_MUL ? 4 : 5); // The dynamic light. glActiveTexture(IS_MUL ? GL_TEXTURE0 : GL_TEXTURE1); /// @todo modTex may be the name of a "managed" texture. GL_BindTextureUnmanaged(renderTextures ? parms.modTex : 0, gl::ClampToEdge, gl::ClampToEdge); glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, parms.modColor); // The actual texture. glActiveTexture(IS_MUL ? GL_TEXTURE1 : GL_TEXTURE0); GL_BindTexture(tex); withDyn = true; } else { GL_ModulateTexture(1); glEnable(GL_TEXTURE_2D); GL_BindTexture(tex); normal = 0; } GL_BlendMode(parms.blendMode); GLenum normalTarget = normal? GL_TEXTURE1 : GL_TEXTURE0; GLenum dynTarget = dyn? GL_TEXTURE1 : GL_TEXTURE0; // Draw one quad. This is obviously not a very efficient way to render // lots of masked walls, but since 3D models and sprites must be // rendered interleaved with masked walls, there's not much that can be // done about this. if(withDyn) { glBegin(GL_QUADS); glColor4fv(parms.vertices[0].color); glMultiTexCoord2f(normalTarget, parms.texCoord[0][0], parms.texCoord[1][1]); glMultiTexCoord2f(dynTarget, parms.modTexCoord[0][0], parms.modTexCoord[1][1]); glVertex3f(parms.vertices[0].pos[0], parms.vertices[0].pos[2], parms.vertices[0].pos[1]); glColor4fv(parms.vertices[1].color); glMultiTexCoord2f(normalTarget, parms.texCoord[0][0], parms.texCoord[0][1]); glMultiTexCoord2f(dynTarget, parms.modTexCoord[0][0], parms.modTexCoord[0][1]); glVertex3f(parms.vertices[1].pos[0], parms.vertices[1].pos[2], parms.vertices[1].pos[1]); glColor4fv(parms.vertices[3].color); glMultiTexCoord2f(normalTarget, parms.texCoord[1][0], parms.texCoord[0][1]); glMultiTexCoord2f(dynTarget, parms.modTexCoord[1][0], parms.modTexCoord[0][1]); glVertex3f(parms.vertices[3].pos[0], parms.vertices[3].pos[2], parms.vertices[3].pos[1]); glColor4fv(parms.vertices[2].color); glMultiTexCoord2f(normalTarget, parms.texCoord[1][0], parms.texCoord[1][1]); glMultiTexCoord2f(dynTarget, parms.modTexCoord[1][0], parms.modTexCoord[1][1]); glVertex3f(parms.vertices[2].pos[0], parms.vertices[2].pos[2], parms.vertices[2].pos[1]); glEnd(); // Restore normal GL state. GL_SelectTexUnits(1); GL_ModulateTexture(1); } else { glBegin(GL_QUADS); glColor4fv(parms.vertices[0].color); glTexCoord2f(parms.texCoord[0][0], parms.texCoord[1][1]); glVertex3f(parms.vertices[0].pos[0], parms.vertices[0].pos[2], parms.vertices[0].pos[1]); glColor4fv(parms.vertices[1].color); glTexCoord2f(parms.texCoord[0][0], parms.texCoord[0][1]); glVertex3f(parms.vertices[1].pos[0], parms.vertices[1].pos[2], parms.vertices[1].pos[1]); glColor4fv(parms.vertices[3].color); glTexCoord2f(parms.texCoord[1][0], parms.texCoord[0][1]); glVertex3f(parms.vertices[3].pos[0], parms.vertices[3].pos[2], parms.vertices[3].pos[1]); glColor4fv(parms.vertices[2].color); glTexCoord2f(parms.texCoord[1][0], parms.texCoord[1][1]); glVertex3f(parms.vertices[2].pos[0], parms.vertices[2].pos[2], parms.vertices[2].pos[1]); glEnd(); } glDisable(GL_TEXTURE_2D); GL_BlendMode(BM_NORMAL); }