Your texture can be a 1x1 white image that you stretch to fill the screen. (White so it is more versatile.) And if you don't want to fool with calculating how to stretch it relative to where the camera is, you can do this:
private static final Matrix4 IDT = new Matrix4();
batch.setProjectionMatrix(camera.combined);
batch.begin();
//draw stuff in background
batch.setProjectionMatrix(IDT);
batch.setColor(0, 0, 0, 0.7f);
batch.draw(singlePixelTexture, -1, -1, 2, 2); //coordinates and size of the screen when identity projection matrix is used
batch.setProjectionMatrix(camera.combined);
//draw your front window
batch.end();
However, you could also leave the projection matrix alone and instead calculate where and how big the background should be to fill the screen with the existing matrix:
float camX = camera.position.x;
float camY = camera.position.y;
float camWidth = camera.viewportWidth;
float camHeight = camera.viewportHeight;
batch.setProjectionMatrix(camera.combined);
batch.begin();
//draw stuff in background
batch.setColor(0, 0, 0, 0.7f);
batch.draw(singlePixelTexture, camX - camWidth/2, camY - camHeight/2, camWidth, camHeight);
//draw your front window
batch.end();
And FYI, although a large texture does use more memory and load time, it does not slow down rendering unless it is drawn shrunk down without mip mapping.
Edit: How to generate single pixel texture at runtime:
singlePixelPixmap = new Pixmap(1, 1, Pixmap.Format.RGBA8888);
singlePixelPixmap.setColor(1, 1, 1, 1);
singlePixelPixmap.fill();
PixmapTextureData textureData = new PixmapTextureData(singlePixelPixmap, Pixmap.Format.RGBA8888, false, false, true);
singlePixelTexture = new Texture(textureData);
singlePixelTexture.setFilter(TextureFilter.Nearest, TextureFilter.Nearest);
Note that the pixmap must be disposed in the dispose
method, but you don't want to do it earlier than that, or the texture cannot automatically reload if there is a GL context loss.