LibGDX子类未调用父类构造函数原因及GLFrameBuffer扩展疑问
1. Why isn't the parent constructor explicitly called in LibGDX's FrameBuffer subclass?
Great question—let's start with the core Java rule you're probably thinking about: if a subclass constructor doesn't explicitly call any parent constructor, the compiler automatically inserts super() (a call to the parent's no-arg constructor). This would normally cause a compile error if the parent has no accessible (public/protected) no-arg constructor.
So why does FrameBuffer work even though you see private, empty no-arg constructors in both FrameBuffer and GLFrameBuffer? Here's the breakdown:
- Those private no-arg constructors are placeholder constructors for serialization. Many LibGDX classes implement
Serializable, and Java's serialization mechanism requires a no-arg constructor (even private ones are accessible via reflection for this purpose). These constructors are never used when instantiating the class normally—they're only for deserializing saved objects. - The actual instantiation of FrameBuffer relies on calling GLFrameBuffer's protected parameterized constructor, not the no-arg one. If you look closer at FrameBuffer's source code, its public constructors create a
GLFrameBufferBuilderinstance (configured with texture attachments like color, depth, or stencil) and pass it tosuper(builder). For example:
GLFrameBuffer's protected constructor handles all the heavy lifting of initializing the framebuffer, setting up textures, etc.public FrameBuffer(Format format, int width, int height, boolean hasDepth, boolean hasStencil) { super(new FrameBufferBuilder(width, height) .addBasicColorTextureAttachment(format) .addDepthTextureAttachment(hasDepth) .addStencilTextureAttachment(hasStencil)); }
2. How to write a constructor for a GLFrameBuffer subclass?
GLFrameBuffer is designed to be extended using its protected builder-based constructor. Here's a step-by-step guide with practical examples:
Step 1: Choose your attachment type
Decide if you'll use the default FrameBufferTextureAttachment or create a custom subclass (for specialized texture configurations like custom filtering or non-standard formats).
Step 2: Write your subclass constructors
You can create constructors that either:
- Encapsulate common parameters (for easy, one-line instantiation), or
- Accept a pre-configured builder (for maximum flexibility)
Example 1: Encapsulated constructor for common use cases
import com.badlogic.gdx.graphics.glutils.FrameBufferTextureAttachment; import com.badlogic.gdx.graphics.glutils.GLFrameBuffer; import com.badlogic.gdx.graphics.glutils.GLFrameBufferBuilder; import com.badlogic.gdx.graphics.Pixmap; public class MyCustomFrameBuffer extends GLFrameBuffer<FrameBufferTextureAttachment> { // Constructor with common, easy-to-use parameters public MyCustomFrameBuffer(Pixmap.Format colorFormat, int width, int height, boolean includeDepth) { // Create a builder and configure your desired attachments GLFrameBufferBuilder<FrameBufferTextureAttachment> builder = new GLFrameBufferBuilder<>(width, height); // Add a color attachment with your chosen format builder.addBasicColorTextureAttachment(colorFormat); // Add a depth attachment if requested if (includeDepth) { builder.addDepthTextureAttachment(); } // Call the parent's protected constructor with the configured builder super(builder); // Add any custom initialization logic here (e.g., setting texture filters) } }
Example 2: Constructor accepting a custom builder
If you want callers to fully customize the framebuffer setup (like adding custom attachments or modifying texture parameters), add a constructor that takes a GLFrameBufferBuilder:
public class MyCustomFrameBuffer extends GLFrameBuffer<FrameBufferTextureAttachment> { public MyCustomFrameBuffer(GLFrameBufferBuilder<FrameBufferTextureAttachment> builder) { super(builder); // Add your own post-initialization logic here (if needed) } }
Key Notes:
- Never try to use the private no-arg constructor for instantiation—it's only for serialization and won't properly initialize the framebuffer.
- All core framebuffer initialization is handled in GLFrameBuffer's protected builder constructor, so your subclass just needs to pass a properly configured builder.
- If you need custom texture attachments, create a subclass of
FrameBufferTextureAttachmentand usebuilder.addAttachment()to include it in your setup.
内容的提问来源于stack exchange,提问作者fisherdog1

