|
|
|
@ -1459,25 +1459,44 @@ public class GLRenderer implements Renderer { |
|
|
|
|
rb.getId()); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
private void bindFrameBuffer(FrameBuffer fb) { |
|
|
|
|
if (fb == null) { |
|
|
|
|
if (context.boundFBO != 0) { |
|
|
|
|
glfbo.glBindFramebufferEXT(GLFbo.GL_FRAMEBUFFER_EXT, 0); |
|
|
|
|
statistics.onFrameBufferUse(null, true); |
|
|
|
|
context.boundFBO = 0; |
|
|
|
|
context.boundFB = null; |
|
|
|
|
} |
|
|
|
|
} else { |
|
|
|
|
assert fb.getId() != -1 && fb.getId() != 0; |
|
|
|
|
if (context.boundFBO != fb.getId()) { |
|
|
|
|
glfbo.glBindFramebufferEXT(GLFbo.GL_FRAMEBUFFER_EXT, fb.getId()); |
|
|
|
|
context.boundFBO = fb.getId(); |
|
|
|
|
context.boundFB = fb; |
|
|
|
|
statistics.onFrameBufferUse(fb, true); |
|
|
|
|
} else { |
|
|
|
|
statistics.onFrameBufferUse(fb, false); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
public void updateFrameBuffer(FrameBuffer fb) { |
|
|
|
|
if (fb.getNumColorBuffers() == 0 && fb.getDepthBuffer() == null) { |
|
|
|
|
throw new IllegalArgumentException("The framebuffer: " + fb |
|
|
|
|
+ "\nDoesn't have any color/depth buffers"); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
int id = fb.getId(); |
|
|
|
|
if (id == -1) { |
|
|
|
|
// create FBO
|
|
|
|
|
glfbo.glGenFramebuffersEXT(intBuf1); |
|
|
|
|
id = intBuf1.get(0); |
|
|
|
|
fb.setId(id); |
|
|
|
|
objManager.registerObject(fb); |
|
|
|
|
|
|
|
|
|
statistics.onNewFrameBuffer(); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (context.boundFBO != id) { |
|
|
|
|
glfbo.glBindFramebufferEXT(GLFbo.GL_FRAMEBUFFER_EXT, id); |
|
|
|
|
// binding an FBO automatically sets draw buf to GL_COLOR_ATTACHMENT0
|
|
|
|
|
context.boundDrawBuf = 0; |
|
|
|
|
context.boundFBO = id; |
|
|
|
|
} |
|
|
|
|
bindFrameBuffer(fb); |
|
|
|
|
|
|
|
|
|
FrameBuffer.RenderBuffer depthBuf = fb.getDepthBuffer(); |
|
|
|
|
if (depthBuf != null) { |
|
|
|
@ -1488,7 +1507,8 @@ public class GLRenderer implements Renderer { |
|
|
|
|
FrameBuffer.RenderBuffer colorBuf = fb.getColorBuffer(i); |
|
|
|
|
updateFrameBufferAttachment(fb, colorBuf); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
setReadDrawBuffers(fb); |
|
|
|
|
checkFrameBufferError(); |
|
|
|
|
|
|
|
|
|
fb.clearUpdateNeeded(); |
|
|
|
@ -1516,93 +1536,45 @@ public class GLRenderer implements Renderer { |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
public void setMainFrameBufferOverride(FrameBuffer fb) { |
|
|
|
|
mainFbOverride = null; |
|
|
|
|
if (context.boundFBO == 0) { |
|
|
|
|
// Main FB is now set to fb, make sure its bound
|
|
|
|
|
setFrameBuffer(fb); |
|
|
|
|
} |
|
|
|
|
mainFbOverride = fb; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
public void setFrameBuffer(FrameBuffer fb) { |
|
|
|
|
if (fb == null && mainFbOverride != null) { |
|
|
|
|
fb = mainFbOverride; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (context.boundFB == fb) { |
|
|
|
|
if (fb == null || !fb.isUpdateNeeded()) { |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (!caps.contains(Caps.FrameBuffer)) { |
|
|
|
|
throw new RendererException("Framebuffer objects are not supported" |
|
|
|
|
+ " by the video hardware"); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// generate mipmaps for last FB if needed
|
|
|
|
|
if (context.boundFB != null) { |
|
|
|
|
for (int i = 0; i < context.boundFB.getNumColorBuffers(); i++) { |
|
|
|
|
RenderBuffer rb = context.boundFB.getColorBuffer(i); |
|
|
|
|
Texture tex = rb.getTexture(); |
|
|
|
|
if (tex != null |
|
|
|
|
&& tex.getMinFilter().usesMipMapLevels()) { |
|
|
|
|
setTexture(0, rb.getTexture()); |
|
|
|
|
|
|
|
|
|
int textureType = convertTextureType(tex.getType(), tex.getImage().getMultiSamples(), rb.getFace()); |
|
|
|
|
glfbo.glGenerateMipmapEXT(textureType); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
public void setReadDrawBuffers(FrameBuffer fb) { |
|
|
|
|
if (gl2 == null) { |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
final int NONE = -2; |
|
|
|
|
final int INITIAL = -1; |
|
|
|
|
final int MRT_OFF = 100; |
|
|
|
|
|
|
|
|
|
if (fb == null) { |
|
|
|
|
// unbind any fbos
|
|
|
|
|
if (context.boundFBO != 0) { |
|
|
|
|
glfbo.glBindFramebufferEXT(GLFbo.GL_FRAMEBUFFER_EXT, 0); |
|
|
|
|
statistics.onFrameBufferUse(null, true); |
|
|
|
|
|
|
|
|
|
context.boundFBO = 0; |
|
|
|
|
// Set Read/Draw buffers to initial value.
|
|
|
|
|
if (context.boundDrawBuf != INITIAL) { |
|
|
|
|
gl2.glDrawBuffer(context.initialDrawBuf); |
|
|
|
|
context.boundDrawBuf = INITIAL; |
|
|
|
|
} |
|
|
|
|
// select back buffer
|
|
|
|
|
if (gl2 != null) { |
|
|
|
|
if (context.boundDrawBuf != -1) { |
|
|
|
|
gl2.glDrawBuffer(context.initialDrawBuf); |
|
|
|
|
context.boundDrawBuf = -1; |
|
|
|
|
} |
|
|
|
|
if (context.boundReadBuf != -1) { |
|
|
|
|
gl2.glReadBuffer(context.initialReadBuf); |
|
|
|
|
context.boundReadBuf = -1; |
|
|
|
|
} |
|
|
|
|
if (context.boundReadBuf != INITIAL) { |
|
|
|
|
gl2.glReadBuffer(context.initialReadBuf); |
|
|
|
|
context.boundReadBuf = INITIAL; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
context.boundFB = null; |
|
|
|
|
} else { |
|
|
|
|
if (fb.getNumColorBuffers() == 0 && fb.getDepthBuffer() == null) { |
|
|
|
|
throw new IllegalArgumentException("The framebuffer: " + fb |
|
|
|
|
+ "\nDoesn't have any color/depth buffers"); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (fb.isUpdateNeeded()) { |
|
|
|
|
updateFrameBuffer(fb); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// update viewport to reflect framebuffer's resolution
|
|
|
|
|
setViewPort(0, 0, fb.getWidth(), fb.getHeight()); |
|
|
|
|
|
|
|
|
|
if (context.boundFBO != fb.getId()) { |
|
|
|
|
glfbo.glBindFramebufferEXT(GLFbo.GL_FRAMEBUFFER_EXT, fb.getId()); |
|
|
|
|
statistics.onFrameBufferUse(fb, true); |
|
|
|
|
|
|
|
|
|
context.boundFBO = fb.getId(); |
|
|
|
|
} else { |
|
|
|
|
statistics.onFrameBufferUse(fb, false); |
|
|
|
|
} |
|
|
|
|
if (fb.getNumColorBuffers() == 0) { |
|
|
|
|
// make sure to select NONE as draw buf
|
|
|
|
|
// no color buffer attached. select NONE
|
|
|
|
|
// no color buffer attached.
|
|
|
|
|
if (gl2 != null) { |
|
|
|
|
if (context.boundDrawBuf != -2) { |
|
|
|
|
if (context.boundDrawBuf != NONE) { |
|
|
|
|
gl2.glDrawBuffer(GL.GL_NONE); |
|
|
|
|
context.boundDrawBuf = -2; |
|
|
|
|
context.boundDrawBuf = NONE; |
|
|
|
|
} |
|
|
|
|
if (context.boundReadBuf != -2) { |
|
|
|
|
if (context.boundReadBuf != NONE) { |
|
|
|
|
gl2.glReadBuffer(GL.GL_NONE); |
|
|
|
|
context.boundReadBuf = -2; |
|
|
|
|
context.boundReadBuf = NONE; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} else { |
|
|
|
@ -1622,7 +1594,7 @@ public class GLRenderer implements Renderer { |
|
|
|
|
+ " by the video hardware!"); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (context.boundDrawBuf != 100 + fb.getNumColorBuffers()) { |
|
|
|
|
if (context.boundDrawBuf != MRT_OFF + fb.getNumColorBuffers()) { |
|
|
|
|
intBuf16.clear(); |
|
|
|
|
for (int i = 0; i < fb.getNumColorBuffers(); i++) { |
|
|
|
|
intBuf16.put(GLFbo.GL_COLOR_ATTACHMENT0_EXT + i); |
|
|
|
@ -1630,7 +1602,7 @@ public class GLRenderer implements Renderer { |
|
|
|
|
|
|
|
|
|
intBuf16.flip(); |
|
|
|
|
glext.glDrawBuffers(intBuf16); |
|
|
|
|
context.boundDrawBuf = 100 + fb.getNumColorBuffers(); |
|
|
|
|
context.boundDrawBuf = MRT_OFF + fb.getNumColorBuffers(); |
|
|
|
|
} |
|
|
|
|
} else { |
|
|
|
|
RenderBuffer rb = fb.getColorBuffer(fb.getTargetIndex()); |
|
|
|
@ -1643,8 +1615,56 @@ public class GLRenderer implements Renderer { |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
public void setFrameBuffer(FrameBuffer fb) { |
|
|
|
|
if (fb == null && mainFbOverride != null) { |
|
|
|
|
fb = mainFbOverride; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (context.boundFB == fb) { |
|
|
|
|
if (fb == null || !fb.isUpdateNeeded()) { |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (!caps.contains(Caps.FrameBuffer)) { |
|
|
|
|
throw new RendererException("Framebuffer objects are not supported" |
|
|
|
|
+ " by the video hardware"); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// generate mipmaps for last FB if needed
|
|
|
|
|
if (context.boundFB != null) { |
|
|
|
|
for (int i = 0; i < context.boundFB.getNumColorBuffers(); i++) { |
|
|
|
|
RenderBuffer rb = context.boundFB.getColorBuffer(i); |
|
|
|
|
Texture tex = rb.getTexture(); |
|
|
|
|
if (tex != null |
|
|
|
|
&& tex.getMinFilter().usesMipMapLevels()) { |
|
|
|
|
setTexture(0, rb.getTexture()); |
|
|
|
|
|
|
|
|
|
int textureType = convertTextureType(tex.getType(), tex.getImage().getMultiSamples(), rb.getFace()); |
|
|
|
|
glfbo.glGenerateMipmapEXT(textureType); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (fb == null) { |
|
|
|
|
bindFrameBuffer(null); |
|
|
|
|
setReadDrawBuffers(null); |
|
|
|
|
} else { |
|
|
|
|
if (fb.isUpdateNeeded()) { |
|
|
|
|
updateFrameBuffer(fb); |
|
|
|
|
} else { |
|
|
|
|
bindFrameBuffer(fb); |
|
|
|
|
setReadDrawBuffers(fb); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// update viewport to reflect framebuffer's resolution
|
|
|
|
|
setViewPort(0, 0, fb.getWidth(), fb.getHeight()); |
|
|
|
|
|
|
|
|
|
assert fb.getId() >= 0; |
|
|
|
|
assert fb.getId() > 0; |
|
|
|
|
assert context.boundFBO == fb.getId(); |
|
|
|
|
|
|
|
|
|
context.boundFB = fb; |
|
|
|
|