Skip to content

Commit

Permalink
Fix MRT framebuffers (#182)
Browse files Browse the repository at this point in the history
  • Loading branch information
GlennFolker authored Dec 13, 2024
1 parent ae657a7 commit 124ba82
Show file tree
Hide file tree
Showing 4 changed files with 27 additions and 62 deletions.
3 changes: 3 additions & 0 deletions arc-core/src/arc/graphics/Cubemap.java
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,9 @@ public enum CubemapSide{
/** The negative Z and sixth side of the cubemap */
negativeZ(5, GL20.GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, 0, -1, 0, 0, 0, -1);

/** Cached {@link CubemapSide#values()} for performance and ergonomics. */
public static final CubemapSide[] all = values();

/** The zero based index of the side in the cubemap */
public final int index;
/** The OpenGL target (used for glTexImage2D) of the side. */
Expand Down
6 changes: 3 additions & 3 deletions arc-core/src/arc/graphics/gl/FrameBuffer.java
Original file line number Diff line number Diff line change
Expand Up @@ -139,12 +139,12 @@ protected Texture createTexture(FrameBufferTextureAttachmentSpec attachmentSpec)
}

@Override
protected void disposeColorTexture(Texture colorTexture){
protected void disposeTexture(Texture colorTexture){
colorTexture.dispose();
}

@Override
protected void attachFrameBufferColorTexture(Texture texture){
Gl.framebufferTexture2D(Gl.framebuffer, GL20.GL_COLOR_ATTACHMENT0, GL20.GL_TEXTURE_2D, texture.getTextureObjectHandle(), 0);
protected void attachTexture(int attachment, Texture texture){
Gl.framebufferTexture2D(Gl.framebuffer, attachment, Gl.texture2d, texture.getTextureObjectHandle(), 0);
}
}
54 changes: 11 additions & 43 deletions arc-core/src/arc/graphics/gl/FrameBufferCubemap.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package arc.graphics.gl;

import arc.func.*;
import arc.graphics.*;
import arc.graphics.Cubemap.*;
import arc.graphics.Texture.*;
Expand Down Expand Up @@ -40,14 +41,6 @@
* @author realitix
*/
public class FrameBufferCubemap extends GLFrameBuffer<Cubemap>{
/** cubemap sides cache */
private static final Cubemap.CubemapSide[] cubemapSides = Cubemap.CubemapSide.values();
/** the zero-based index of the active side **/
private int currentSide;

FrameBufferCubemap(){
}

/**
* Creates a GLFrameBuffer from the specifications provided by bufferBuilder
**/
Expand Down Expand Up @@ -93,55 +86,30 @@ protected Cubemap createTexture(FrameBufferTextureAttachmentSpec attachmentSpec)
}

@Override
protected void disposeColorTexture(Cubemap colorTexture){
protected void disposeTexture(Cubemap colorTexture){
colorTexture.dispose();
}

@Override
protected void attachFrameBufferColorTexture(Cubemap texture){
protected void attachTexture(int attachment, Cubemap texture){
int glHandle = texture.getTextureObjectHandle();
CubemapSide[] sides = CubemapSide.values();
for(CubemapSide side : sides){
Gl.framebufferTexture2D(Gl.framebuffer, GL20.GL_COLOR_ATTACHMENT0, side.glEnum, glHandle, 0);
for(CubemapSide side : CubemapSide.all){
Gl.framebufferTexture2D(Gl.framebuffer, attachment, side.glEnum, glHandle, 0);
}
}

/**
* Makes the frame buffer current so everything gets drawn to it, must be followed by call to either {@link #nextSide()} or
* {@link #bindSide(arc.graphics.Cubemap.CubemapSide)} to activate the side to render onto.
*/
@Override
public void bind(){
currentSide = -1;
super.bind();
}

/**
* Bind the next side of cubemap and return false if no more side. Should be called in between a call to {@link #begin()} and
* #end to cycle to each side of the cubemap to render on.
*/
public boolean nextSide(){
if(currentSide > 5){
throw new ArcRuntimeException("No remaining sides.");
}else if(currentSide == 5){
return false;
/** Should be called in between a call to {@link #begin()} and {@link #end()}. */
public void eachSide(Cons<CubemapSide> cons){
for(CubemapSide side : CubemapSide.all){
cons.get(side);
}

currentSide++;
bindSide(getSide());
return true;
}

/**
* Bind the side, making it active to render on. Should be called in between a call to {@link #begin()} and {@link #end()}.
* @param side The side to bind
*/
protected void bindSide(final Cubemap.CubemapSide side){
Gl.framebufferTexture2D(Gl.framebuffer, GL20.GL_COLOR_ATTACHMENT0, side.glEnum, getTexture().getTextureObjectHandle(), 0);
}

/** Get the currently bound side. */
public Cubemap.CubemapSide getSide(){
return currentSide < 0 ? null : cubemapSides[currentSide];
public void bindSide(CubemapSide side){
Gl.framebufferTexture2D(Gl.framebuffer, Gl.colorAttachment0, side.glEnum, getTexture().getTextureObjectHandle(), 0);
}
}
26 changes: 10 additions & 16 deletions arc-core/src/arc/graphics/gl/GLFrameBuffer.java
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@
public abstract class GLFrameBuffer<T extends GLTexture> implements Disposable{
protected final static int GL_DEPTH24_STENCIL8_OES = 0x88F0;
/** the currently bound framebuffer; null for the default one. */
protected static GLFrameBuffer currentBoundFramebuffer;
protected static GLFrameBuffer<?> currentBoundFramebuffer;
/** the default framebuffer handle, a.k.a screen. */
protected static int defaultFramebufferHandle;
/** # of nested buffers right now */
Expand All @@ -38,7 +38,7 @@ public abstract class GLFrameBuffer<T extends GLTexture> implements Disposable{
/** the color buffer texture **/
protected Seq<T> textureAttachments = new Seq<>();
/** the framebuffer that was bound before this one began (null to indicate that nothing was bound) **/
protected GLFrameBuffer lastBoundFramebuffer = null;
protected GLFrameBuffer<?> lastBoundFramebuffer = null;
/** the framebuffer handle **/
protected int framebufferHandle;
/** the depthbuffer render object handle **/
Expand Down Expand Up @@ -87,13 +87,12 @@ public Seq<T> getTextureAttachments(){
protected abstract T createTexture(FrameBufferTextureAttachmentSpec attachmentSpec);

/** Override this method in a derived class to dispose the backing texture as you like. */
protected abstract void disposeColorTexture(T colorTexture);
protected abstract void disposeTexture(T colorTexture);

/** Override this method in a derived class to attach the backing texture to the GL framebuffer object. */
protected abstract void attachFrameBufferColorTexture(T texture);
protected abstract void attachTexture(int attachment, T texture);

protected void build(){

checkValidBuilder();

// iOS uses a different framebuffer handle! (not necessarily 0)
Expand Down Expand Up @@ -143,21 +142,18 @@ protected void build(){
T texture = createTexture(attachmentSpec);
textureAttachments.add(texture);
if(attachmentSpec.isColorTexture()){
Gl.framebufferTexture2D(Gl.framebuffer, GL30.GL_COLOR_ATTACHMENT0 + colorTextureCounter, GL30.GL_TEXTURE_2D,
texture.getTextureObjectHandle(), 0);
attachTexture(Gl.colorAttachment0 + colorTextureCounter, texture);
colorTextureCounter++;
}else if(attachmentSpec.isDepth){
Gl.framebufferTexture2D(Gl.framebuffer, GL20.GL_DEPTH_ATTACHMENT, GL20.GL_TEXTURE_2D,
texture.getTextureObjectHandle(), 0);
attachTexture(Gl.depthAttachment, texture);
}else if(attachmentSpec.isStencil){
Gl.framebufferTexture2D(Gl.framebuffer, GL20.GL_STENCIL_ATTACHMENT, GL20.GL_TEXTURE_2D,
texture.getTextureObjectHandle(), 0);
attachTexture(Gl.stencilAttachment, texture);
}
}
}else{
T texture = createTexture(bufferBuilder.textureAttachmentSpecs.first());
textureAttachments.add(texture);
Gl.bindTexture(texture.glTarget, texture.getTextureObjectHandle());
attachTexture(Gl.colorAttachment0, texture);
}

if(isMRT){
Expand All @@ -167,8 +163,6 @@ protected void build(){
}
buffer.position(0);
Core.gl30.glDrawBuffers(colorTextureCounter, buffer);
}else{
attachFrameBufferColorTexture(textureAttachments.first());
}

if(bufferBuilder.hasDepthRenderBuffer){
Expand Down Expand Up @@ -225,7 +219,7 @@ protected void build(){

if(result != Gl.framebufferComplete){
for(T texture : textureAttachments){
disposeColorTexture(texture);
disposeTexture(texture);
}

if(hasDepthStencilPackedBuffer){
Expand Down Expand Up @@ -277,7 +271,7 @@ private void checkValidBuilder(){
@Override
public void dispose(){
for(T texture : textureAttachments){
disposeColorTexture(texture);
disposeTexture(texture);
}

if(hasDepthStencilPackedBuffer){
Expand Down

0 comments on commit 124ba82

Please sign in to comment.