OpenRA/OpenRA · error · InvalidDataException

Frame buffer size ({size.Width}x{size.Height}) must be a pow

Error message

Frame buffer size ({size.Width}x{size.Height}) must be a power of two

What it means

Thrown by the FrameBuffer constructor when either size.Width or size.Height is not a power of two (Exts.IsPowerOf2). The legacy GL framebuffer path requires power-of-two dimensions for the color texture and depth renderbuffer. InvalidDataException at construction time.

Source

Thrown at OpenRA.Platforms.Default/FrameBuffer.cs:33

using OpenRA.Primitives;

namespace OpenRA.Platforms.Default
{
	sealed class FrameBuffer : ThreadAffine, IFrameBuffer
	{
		readonly ITexture texture;
		readonly Size size;
		readonly Color clearColor;
		uint framebuffer, depth;
		bool disposed;
		bool scissored;

		public FrameBuffer(Size size, ITextureInternal texture, Color clearColor)
		{
			this.size = size;
			this.clearColor = clearColor;
			if (!Exts.IsPowerOf2(size.Width) || !Exts.IsPowerOf2(size.Height))
				throw new InvalidDataException($"Frame buffer size ({size.Width}x{size.Height}) must be a power of two");

			OpenGL.glGenFramebuffers(1, out framebuffer);
			OpenGL.CheckGLError();
			OpenGL.glBindFramebuffer(OpenGL.GL_FRAMEBUFFER, framebuffer);
			OpenGL.CheckGLError();

			// Color
			this.texture = texture;
			texture.SetEmpty(size.Width, size.Height);
			OpenGL.glFramebufferTexture2D(OpenGL.GL_FRAMEBUFFER, OpenGL.GL_COLOR_ATTACHMENT0, OpenGL.GL_TEXTURE_2D, texture.ID, 0);
			OpenGL.CheckGLError();

			// Depth
			OpenGL.glGenRenderbuffers(1, out depth);
			OpenGL.CheckGLError();

			OpenGL.glBindRenderbuffer(OpenGL.GL_RENDERBUFFER, depth);
			OpenGL.CheckGLError();

View on GitHub (pinned to a520984d91)

Solutions

  1. Pass power-of-two dimensions (e.g. 1024, 2048) to the FrameBuffer constructor.
  2. Clamp the requested size up to the next power of two before constructing.
  3. Use a renderer path that supports NPOT textures if the GPU allows it.
  4. Check the caller supplying the Size (window/viewport setup) and round it to PoT.

Example fix

// before
var fb = new FrameBuffer(new Size(width, height), texture, clearColor);
// after - round up to next power of two
int NextPoT(int v) { var p = 1; while (p < v) p <<= 1; return p; }
var fb = new FrameBuffer(new Size(NextPoT(width), NextPoT(height)), texture, clearColor);
Defensive patterns

Strategy: validation

Validate before calling

if (!Exts.IsPowerOf2(size.Width) || !Exts.IsPowerOf2(size.Height))
    throw new InvalidDataException(
        $"Frame buffer size ({size.Width}x{size.Height}) must be a power of two.");

Type guard

static bool IsPoTSize(Size s) => Exts.IsPowerOf2(s.Width) && Exts.IsPowerOf2(s.Height);

Prevention

When it happens

Trigger: Constructing a FrameBuffer with a Size whose width or height is e.g. 1920, 1080, 1366 — any non-PoT value — during renderer/window/sprite-buffer setup.

Common situations: A non-power-of-two display resolution or render target being passed in; a high-DPI/retina scale producing non-PoT backbuffer sizes; custom render targets with arbitrary dimensions; running on the default (non-NPOT) platform renderer.

Related errors


AI-assisted analysis of OpenRA/OpenRA@a520984d91 (2026-08-13). Data as JSON: /api/errors/2f117eaf6e854fb0. Report an issue: GitHub.