Android: Initial commit to support FrameBuffers. This is still a work in progress. FilterPostProcessors currently don't work on Android devices that do not support NPOT.
git-svn-id: https://jmonkeyengine.googlecode.com/svn/trunk@10513 75d07b2b-3a1a-0410-a2c5-0572b91ccdca
This commit is contained in:
parent
a1fd0272d4
commit
e26c86c794
@ -78,6 +78,8 @@ public class OGLESShaderRenderer implements Renderer {
|
|||||||
private final EnumSet<Caps> caps = EnumSet.noneOf(Caps.class);
|
private final EnumSet<Caps> caps = EnumSet.noneOf(Caps.class);
|
||||||
// current state
|
// current state
|
||||||
private Shader boundShader;
|
private Shader boundShader;
|
||||||
|
// initalDrawBuf and initialReadBuf are not used on ES,
|
||||||
|
// http://www.khronos.org/opengles/sdk/docs/man/xhtml/glBindFramebuffer.xml
|
||||||
//private int initialDrawBuf, initialReadBuf;
|
//private int initialDrawBuf, initialReadBuf;
|
||||||
private int glslVer;
|
private int glslVer;
|
||||||
private int vertexTextureUnits;
|
private int vertexTextureUnits;
|
||||||
@ -86,15 +88,16 @@ public class OGLESShaderRenderer implements Renderer {
|
|||||||
private int fragUniforms;
|
private int fragUniforms;
|
||||||
private int vertexAttribs;
|
private int vertexAttribs;
|
||||||
// private int maxFBOSamples;
|
// private int maxFBOSamples;
|
||||||
// private int maxFBOAttachs;
|
private final int maxFBOAttachs = 1; // Only 1 color attachment on ES
|
||||||
// private int maxMRTFBOAttachs;
|
private final int maxMRTFBOAttachs = 1; // FIXME for now, not sure if > 1 is needed for ES
|
||||||
// private int maxRBSize;
|
private int maxRBSize;
|
||||||
private int maxTexSize;
|
private int maxTexSize;
|
||||||
private int maxCubeTexSize;
|
private int maxCubeTexSize;
|
||||||
private int maxVertCount;
|
private int maxVertCount;
|
||||||
private int maxTriCount;
|
private int maxTriCount;
|
||||||
private boolean tdc;
|
private boolean tdc;
|
||||||
// private FrameBuffer lastFb = null;
|
private FrameBuffer lastFb = null;
|
||||||
|
private FrameBuffer mainFbOverride = null;
|
||||||
private final Statistics statistics = new Statistics();
|
private final Statistics statistics = new Statistics();
|
||||||
private int vpX, vpY, vpW, vpH;
|
private int vpX, vpY, vpW, vpH;
|
||||||
private int clipX, clipY, clipW, clipH;
|
private int clipX, clipY, clipW, clipH;
|
||||||
@ -155,11 +158,18 @@ public class OGLESShaderRenderer implements Renderer {
|
|||||||
|
|
||||||
powerVr = GLES20.glGetString(GLES20.GL_RENDERER).contains("PowerVR");
|
powerVr = GLES20.glGetString(GLES20.GL_RENDERER).contains("PowerVR");
|
||||||
|
|
||||||
|
/*
|
||||||
// Fix issue in TestRenderToMemory when GL_FRONT is the main
|
// Fix issue in TestRenderToMemory when GL_FRONT is the main
|
||||||
// buffer being used.
|
// buffer being used.
|
||||||
|
initialDrawBuf = glGetInteger(GL_DRAW_BUFFER);
|
||||||
|
initialReadBuf = glGetInteger(GL_READ_BUFFER);
|
||||||
|
|
||||||
// initialDrawBuf = GLES20.glGetIntegeri(GLES20.GL_DRAW_BUFFER);
|
// XXX: This has to be GL_BACK for canvas on Mac
|
||||||
// initialReadBuf = GLES20.glGetIntegeri(GLES20.GL_READ_BUFFER);
|
// Since initialDrawBuf is GL_FRONT for pbuffer, gotta
|
||||||
|
// change this value later on ...
|
||||||
|
// initialDrawBuf = GL_BACK;
|
||||||
|
// initialReadBuf = GL_BACK;
|
||||||
|
*/
|
||||||
|
|
||||||
// Check OpenGL version
|
// Check OpenGL version
|
||||||
int openGlVer = extractVersion("OpenGL ES ", GLES20.glGetString(GLES20.GL_VERSION));
|
int openGlVer = extractVersion("OpenGL ES ", GLES20.glGetString(GLES20.GL_VERSION));
|
||||||
@ -226,6 +236,10 @@ public class OGLESShaderRenderer implements Renderer {
|
|||||||
maxCubeTexSize = intBuf16.get(0);
|
maxCubeTexSize = intBuf16.get(0);
|
||||||
logger.log(Level.FINE, "Maximum CubeMap Resolution: {0}", maxCubeTexSize);
|
logger.log(Level.FINE, "Maximum CubeMap Resolution: {0}", maxCubeTexSize);
|
||||||
|
|
||||||
|
GLES20.glGetIntegerv(GLES20.GL_MAX_RENDERBUFFER_SIZE, intBuf16);
|
||||||
|
maxRBSize = intBuf16.get(0);
|
||||||
|
logger.log(Level.FINER, "FBO RB Max Size: {0}", maxRBSize);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
if (ctxCaps.GL_ARB_color_buffer_float){
|
if (ctxCaps.GL_ARB_color_buffer_float){
|
||||||
// XXX: Require both 16 and 32 bit float support for FloatColorBuffer.
|
// XXX: Require both 16 and 32 bit float support for FloatColorBuffer.
|
||||||
@ -951,180 +965,268 @@ public class OGLESShaderRenderer implements Renderer {
|
|||||||
|* Framebuffers *|
|
|* Framebuffers *|
|
||||||
\*********************************************************************/
|
\*********************************************************************/
|
||||||
public void copyFrameBuffer(FrameBuffer src, FrameBuffer dst) {
|
public void copyFrameBuffer(FrameBuffer src, FrameBuffer dst) {
|
||||||
logger.warning("copyFrameBuffer is not supported.");
|
copyFrameBuffer(src, dst, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void copyFrameBuffer(FrameBuffer src, FrameBuffer dst, boolean copyDepth) {
|
public void copyFrameBuffer(FrameBuffer src, FrameBuffer dst, boolean copyDepth) {
|
||||||
logger.warning("copyFrameBuffer is not supported.");
|
throw new RendererException("Copy framebuffer not implemented yet.");
|
||||||
|
|
||||||
|
// if (GLContext.getCapabilities().GL_EXT_framebuffer_blit) {
|
||||||
|
// int srcX0 = 0;
|
||||||
|
// int srcY0 = 0;
|
||||||
|
// int srcX1 = 0;
|
||||||
|
// int srcY1 = 0;
|
||||||
|
//
|
||||||
|
// int dstX0 = 0;
|
||||||
|
// int dstY0 = 0;
|
||||||
|
// int dstX1 = 0;
|
||||||
|
// int dstY1 = 0;
|
||||||
|
//
|
||||||
|
// int prevFBO = context.boundFBO;
|
||||||
|
//
|
||||||
|
// if (mainFbOverride != null) {
|
||||||
|
// if (src == null) {
|
||||||
|
// src = mainFbOverride;
|
||||||
|
// }
|
||||||
|
// if (dst == null) {
|
||||||
|
// dst = mainFbOverride;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// if (src != null && src.isUpdateNeeded()) {
|
||||||
|
// updateFrameBuffer(src);
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// if (dst != null && dst.isUpdateNeeded()) {
|
||||||
|
// updateFrameBuffer(dst);
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// if (src == null) {
|
||||||
|
// GLES20.glBindFramebuffer(GLES20.GL_FRAMEBUFFER, 0);
|
||||||
|
// srcX0 = vpX;
|
||||||
|
// srcY0 = vpY;
|
||||||
|
// srcX1 = vpX + vpW;
|
||||||
|
// srcY1 = vpY + vpH;
|
||||||
|
// } else {
|
||||||
|
// GLES20.glBindFramebuffer(GLES20.GL_FRAMEBUFFER, src.getId());
|
||||||
|
// srcX1 = src.getWidth();
|
||||||
|
// srcY1 = src.getHeight();
|
||||||
|
// }
|
||||||
|
// if (dst == null) {
|
||||||
|
// GLES20.glBindFramebuffer(GLES20.GL_FRAMEBUFFER, 0);
|
||||||
|
// dstX0 = vpX;
|
||||||
|
// dstY0 = vpY;
|
||||||
|
// dstX1 = vpX + vpW;
|
||||||
|
// dstY1 = vpY + vpH;
|
||||||
|
// } else {
|
||||||
|
// GLES20.glBindFramebuffer(GLES20.GL_FRAMEBUFFER, dst.getId());
|
||||||
|
// dstX1 = dst.getWidth();
|
||||||
|
// dstY1 = dst.getHeight();
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// int mask = GL_COLOR_BUFFER_BIT;
|
||||||
|
// if (copyDepth) {
|
||||||
|
// mask |= GL_DEPTH_BUFFER_BIT;
|
||||||
|
// }
|
||||||
|
// GLES20.glBlitFramebufferEXT(srcX0, srcY0, srcX1, srcY1,
|
||||||
|
// dstX0, dstY0, dstX1, dstY1, mask,
|
||||||
|
// GL_NEAREST);
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// GLES20.glBindFramebuffer(GLES20.GL_FRAMEBUFFER, prevFBO);
|
||||||
|
// try {
|
||||||
|
// checkFrameBufferError();
|
||||||
|
// } catch (IllegalStateException ex) {
|
||||||
|
// logger.log(Level.SEVERE, "Source FBO:\n{0}", src);
|
||||||
|
// logger.log(Level.SEVERE, "Dest FBO:\n{0}", dst);
|
||||||
|
// throw ex;
|
||||||
|
// }
|
||||||
|
// } else {
|
||||||
|
// throw new RendererException("EXT_framebuffer_blit required.");
|
||||||
|
// // TODO: support non-blit copies?
|
||||||
|
// }
|
||||||
}
|
}
|
||||||
/*
|
|
||||||
public void copyFrameBuffer(FrameBuffer src, FrameBuffer dst){
|
|
||||||
if (GLContext.getCapabilities().GL_EXT_framebuffer_blit){
|
|
||||||
int srcW = 0;
|
|
||||||
int srcH = 0;
|
|
||||||
int dstW = 0;
|
|
||||||
int dstH = 0;
|
|
||||||
int prevFBO = context.boundFBO;
|
|
||||||
|
|
||||||
if (src != null && src.isUpdateNeeded())
|
private void checkFrameBufferStatus(FrameBuffer fb) {
|
||||||
updateFrameBuffer(src);
|
|
||||||
|
|
||||||
if (dst != null && dst.isUpdateNeeded())
|
|
||||||
updateFrameBuffer(dst);
|
|
||||||
|
|
||||||
if (src == null){
|
|
||||||
glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, 0);
|
|
||||||
// srcW = viewWidth;
|
|
||||||
// srcH = viewHeight;
|
|
||||||
}else{
|
|
||||||
glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, src.getId());
|
|
||||||
srcW = src.getWidth();
|
|
||||||
srcH = src.getHeight();
|
|
||||||
}
|
|
||||||
if (dst == null){
|
|
||||||
glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, 0);
|
|
||||||
// dstW = viewWidth;
|
|
||||||
// dstH = viewHeight;
|
|
||||||
}else{
|
|
||||||
glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, dst.getId());
|
|
||||||
dstW = dst.getWidth();
|
|
||||||
dstH = dst.getHeight();
|
|
||||||
}
|
|
||||||
glBlitFramebufferEXT(0, 0, srcW, srcH,
|
|
||||||
0, 0, dstW, dstH,
|
|
||||||
GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT,
|
|
||||||
GL_NEAREST);
|
|
||||||
|
|
||||||
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, prevFBO);
|
|
||||||
try {
|
try {
|
||||||
checkFrameBufferError();
|
checkFrameBufferError();
|
||||||
} catch (IllegalStateException ex) {
|
} catch (IllegalStateException ex) {
|
||||||
logger.log(Level.SEVERE, "Source FBO:\n{0}", src);
|
logger.log(Level.SEVERE, "=== jMonkeyEngine FBO State ===\n{0}", fb);
|
||||||
logger.log(Level.SEVERE, "Dest FBO:\n{0}", dst);
|
printRealFrameBufferInfo(fb);
|
||||||
throw ex;
|
throw ex;
|
||||||
}
|
}
|
||||||
}else{
|
|
||||||
throw new UnsupportedOperationException("EXT_framebuffer_blit required.");
|
|
||||||
// TODO: support non-blit copies?
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
private void checkFrameBufferError() {
|
private void checkFrameBufferError() {
|
||||||
logger.warning("checkFrameBufferError is not supported.");
|
int status = GLES20.glCheckFramebufferStatus(GLES20.GL_FRAMEBUFFER);
|
||||||
}
|
|
||||||
/*
|
|
||||||
private void checkFrameBufferError() {
|
|
||||||
int status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
|
|
||||||
switch (status) {
|
switch (status) {
|
||||||
case GL_FRAMEBUFFER_COMPLETE_EXT:
|
case GLES20.GL_FRAMEBUFFER_COMPLETE:
|
||||||
break;
|
break;
|
||||||
case GL_FRAMEBUFFER_UNSUPPORTED_EXT:
|
case GLES20.GL_FRAMEBUFFER_UNSUPPORTED:
|
||||||
//Choose different formats
|
//Choose different formats
|
||||||
throw new IllegalStateException("Framebuffer object format is " +
|
throw new IllegalStateException("Framebuffer object format is "
|
||||||
"unsupported by the video hardware.");
|
+ "unsupported by the video hardware.");
|
||||||
case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT:
|
case GLES20.GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT:
|
||||||
throw new IllegalStateException("Framebuffer has erronous attachment.");
|
throw new IllegalStateException("Framebuffer has erronous attachment.");
|
||||||
case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT:
|
case GLES20.GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT:
|
||||||
throw new IllegalStateException("Framebuffer is missing required attachment.");
|
throw new IllegalStateException("Framebuffer doesn't have any renderbuffers attached.");
|
||||||
case GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT:
|
case GLES20.GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS:
|
||||||
throw new IllegalStateException("Framebuffer attachments must have same dimensions.");
|
throw new IllegalStateException("Framebuffer attachments must have same dimensions.");
|
||||||
case GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT:
|
// case GLES20.GL_FRAMEBUFFER_INCOMPLETE_FORMATS:
|
||||||
throw new IllegalStateException("Framebuffer attachments must have same formats.");
|
// throw new IllegalStateException("Framebuffer attachments must have same formats.");
|
||||||
case GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT:
|
// case GLES20.GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER:
|
||||||
throw new IllegalStateException("Incomplete draw buffer.");
|
// throw new IllegalStateException("Incomplete draw buffer.");
|
||||||
case GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT:
|
// case GLES20.GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT:
|
||||||
throw new IllegalStateException("Incomplete read buffer.");
|
// throw new IllegalStateException("Incomplete read buffer.");
|
||||||
case GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_EXT:
|
// case GLES20.GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_EXT:
|
||||||
throw new IllegalStateException("Incomplete multisample buffer.");
|
// throw new IllegalStateException("Incomplete multisample buffer.");
|
||||||
default:
|
default:
|
||||||
//Programming error; will fail on all hardware
|
//Programming error; will fail on all hardware
|
||||||
throw new IllegalStateException("Some video driver error " +
|
throw new IllegalStateException("Some video driver error "
|
||||||
"or programming error occured. " +
|
+ "or programming error occured. "
|
||||||
"Framebuffer object status is invalid. ");
|
+ "Framebuffer object status is invalid: " + status);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
|
|
||||||
private void updateRenderBuffer(FrameBuffer fb, RenderBuffer rb) {
|
private void printRealRenderBufferInfo(FrameBuffer fb, RenderBuffer rb, String name) {
|
||||||
logger.warning("updateRenderBuffer is not supported.");
|
System.out.println("== Renderbuffer " + name + " ==");
|
||||||
|
System.out.println("RB ID: " + rb.getId());
|
||||||
|
System.out.println("Is proper? " + GLES20.glIsRenderbuffer(rb.getId()));
|
||||||
|
|
||||||
|
int attachment = convertAttachmentSlot(rb.getSlot());
|
||||||
|
|
||||||
|
intBuf16.clear();
|
||||||
|
GLES20.glGetFramebufferAttachmentParameteriv(GLES20.GL_FRAMEBUFFER,
|
||||||
|
attachment, GLES20.GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE, intBuf16);
|
||||||
|
int type = intBuf16.get(0);
|
||||||
|
|
||||||
|
intBuf16.clear();
|
||||||
|
GLES20.glGetFramebufferAttachmentParameteriv(GLES20.GL_FRAMEBUFFER,
|
||||||
|
attachment, GLES20.GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME, intBuf16);
|
||||||
|
int rbName = intBuf16.get(0);
|
||||||
|
|
||||||
|
switch (type) {
|
||||||
|
case GLES20.GL_NONE:
|
||||||
|
System.out.println("Type: None");
|
||||||
|
break;
|
||||||
|
case GLES20.GL_TEXTURE:
|
||||||
|
System.out.println("Type: Texture");
|
||||||
|
break;
|
||||||
|
case GLES20.GL_RENDERBUFFER:
|
||||||
|
System.out.println("Type: Buffer");
|
||||||
|
System.out.println("RB ID: " + rbName);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
/*
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private void printRealFrameBufferInfo(FrameBuffer fb) {
|
||||||
|
// boolean doubleBuffer = GLES20.glGetBooleanv(GLES20.GL_DOUBLEBUFFER);
|
||||||
|
boolean doubleBuffer = false; // FIXME
|
||||||
|
// String drawBuf = getTargetBufferName(glGetInteger(GL_DRAW_BUFFER));
|
||||||
|
// String readBuf = getTargetBufferName(glGetInteger(GL_READ_BUFFER));
|
||||||
|
|
||||||
|
int fbId = fb.getId();
|
||||||
|
intBuf16.clear();
|
||||||
|
// int curDrawBinding = GLES20.glGetIntegerv(GLES20.GL_DRAW_FRAMEBUFFER_BINDING);
|
||||||
|
// int curReadBinding = glGetInteger(ARBFramebufferObject.GL_READ_FRAMEBUFFER_BINDING);
|
||||||
|
|
||||||
|
System.out.println("=== OpenGL FBO State ===");
|
||||||
|
System.out.println("Context doublebuffered? " + doubleBuffer);
|
||||||
|
System.out.println("FBO ID: " + fbId);
|
||||||
|
System.out.println("Is proper? " + GLES20.glIsFramebuffer(fbId));
|
||||||
|
// System.out.println("Is bound to draw? " + (fbId == curDrawBinding));
|
||||||
|
// System.out.println("Is bound to read? " + (fbId == curReadBinding));
|
||||||
|
// System.out.println("Draw buffer: " + drawBuf);
|
||||||
|
// System.out.println("Read buffer: " + readBuf);
|
||||||
|
|
||||||
|
if (context.boundFBO != fbId) {
|
||||||
|
GLES20.glBindFramebuffer(GLES20.GL_FRAMEBUFFER, fbId);
|
||||||
|
context.boundFBO = fbId;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fb.getDepthBuffer() != null) {
|
||||||
|
printRealRenderBufferInfo(fb, fb.getDepthBuffer(), "Depth");
|
||||||
|
}
|
||||||
|
for (int i = 0; i < fb.getNumColorBuffers(); i++) {
|
||||||
|
printRealRenderBufferInfo(fb, fb.getColorBuffer(i), "Color" + i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void updateRenderBuffer(FrameBuffer fb, RenderBuffer rb) {
|
private void updateRenderBuffer(FrameBuffer fb, RenderBuffer rb) {
|
||||||
int id = rb.getId();
|
int id = rb.getId();
|
||||||
if (id == -1) {
|
if (id == -1) {
|
||||||
glGenRenderbuffersEXT(intBuf1);
|
GLES20.glGenRenderbuffers(1, intBuf1);
|
||||||
id = intBuf1.get(0);
|
id = intBuf1.get(0);
|
||||||
rb.setId(id);
|
rb.setId(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (context.boundRB != id) {
|
if (context.boundRB != id) {
|
||||||
glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, id);
|
GLES20.glBindRenderbuffer(GLES20.GL_RENDERBUFFER, id);
|
||||||
context.boundRB = id;
|
context.boundRB = id;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fb.getWidth() > maxRBSize || fb.getHeight() > maxRBSize)
|
if (fb.getWidth() > maxRBSize || fb.getHeight() > maxRBSize) {
|
||||||
throw new UnsupportedOperationException("Resolution "+fb.getWidth()+
|
throw new RendererException("Resolution " + fb.getWidth()
|
||||||
":"+fb.getHeight()+" is not supported.");
|
+ ":" + fb.getHeight() + " is not supported.");
|
||||||
|
|
||||||
if (fb.getSamples() > 0 && GLContext.getCapabilities().GL_EXT_framebuffer_multisample){
|
|
||||||
int samples = fb.getSamples();
|
|
||||||
if (maxFBOSamples < samples){
|
|
||||||
samples = maxFBOSamples;
|
|
||||||
}
|
}
|
||||||
glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER_EXT,
|
|
||||||
samples,
|
int glRenderBufferStorageFormat = TextureUtil.getImageFormat(rb.getFormat()).renderBufferStorageFormat;
|
||||||
TextureUtil.convertTextureFormat(rb.getFormat()),
|
|
||||||
fb.getWidth(),
|
// if (fb.getSamples() > 1 && GLContext.getCapabilities().GL_EXT_framebuffer_multisample) {
|
||||||
fb.getHeight());
|
if (fb.getSamples() > 1) {
|
||||||
|
// // FIXME
|
||||||
|
throw new RendererException("Multisample FrameBuffer is not supported yet.");
|
||||||
|
// int samples = fb.getSamples();
|
||||||
|
// if (maxFBOSamples < samples) {
|
||||||
|
// samples = maxFBOSamples;
|
||||||
|
// }
|
||||||
|
// glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER_EXT,
|
||||||
|
// samples,
|
||||||
|
// glFmt.internalFormat,
|
||||||
|
// fb.getWidth(),
|
||||||
|
// fb.getHeight());
|
||||||
} else {
|
} else {
|
||||||
glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT,
|
GLES20.glRenderbufferStorage(GLES20.GL_RENDERBUFFER,
|
||||||
TextureUtil.convertTextureFormat(rb.getFormat()),
|
glRenderBufferStorageFormat,
|
||||||
fb.getWidth(),
|
fb.getWidth(),
|
||||||
fb.getHeight());
|
fb.getHeight());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
|
|
||||||
private int convertAttachmentSlot(int attachmentSlot) {
|
|
||||||
logger.warning("convertAttachmentSlot is not supported.");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
/*
|
|
||||||
private int convertAttachmentSlot(int attachmentSlot) {
|
private int convertAttachmentSlot(int attachmentSlot) {
|
||||||
// can also add support for stencil here
|
// can also add support for stencil here
|
||||||
if (attachmentSlot == -100) {
|
if (attachmentSlot == -100) {
|
||||||
return GL_DEPTH_ATTACHMENT_EXT;
|
return GLES20.GL_DEPTH_ATTACHMENT;
|
||||||
} else if (attachmentSlot < 0 || attachmentSlot >= 16) {
|
} else if (attachmentSlot < 0 || attachmentSlot >= 16) {
|
||||||
throw new UnsupportedOperationException("Invalid FBO attachment slot: " + attachmentSlot);
|
throw new UnsupportedOperationException("Invalid FBO attachment slot: " + attachmentSlot);
|
||||||
}
|
}
|
||||||
|
|
||||||
return GL_COLOR_ATTACHMENT0_EXT + attachmentSlot;
|
return GLES20.GL_COLOR_ATTACHMENT0 + attachmentSlot;
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
|
|
||||||
public void updateRenderTexture(FrameBuffer fb, RenderBuffer rb) {
|
|
||||||
logger.warning("updateRenderTexture is not supported.");
|
|
||||||
}
|
|
||||||
/*
|
|
||||||
public void updateRenderTexture(FrameBuffer fb, RenderBuffer rb) {
|
public void updateRenderTexture(FrameBuffer fb, RenderBuffer rb) {
|
||||||
Texture tex = rb.getTexture();
|
Texture tex = rb.getTexture();
|
||||||
Image image = tex.getImage();
|
Image image = tex.getImage();
|
||||||
if (image.isUpdateNeeded())
|
if (image.isUpdateNeeded()) {
|
||||||
updateTexImageData(image, tex.getType(), tex.getMinFilter().usesMipMapLevels());
|
updateTexImageData(image, tex.getType());
|
||||||
|
|
||||||
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT,
|
// NOTE: For depth textures, sets nearest/no-mips mode
|
||||||
|
// Required to fix "framebuffer unsupported"
|
||||||
|
// for old NVIDIA drivers!
|
||||||
|
setupTextureParams(tex);
|
||||||
|
}
|
||||||
|
|
||||||
|
GLES20.glFramebufferTexture2D(GLES20.GL_FRAMEBUFFER,
|
||||||
convertAttachmentSlot(rb.getSlot()),
|
convertAttachmentSlot(rb.getSlot()),
|
||||||
convertTextureType(tex.getType()),
|
convertTextureType(tex.getType()),
|
||||||
image.getId(),
|
image.getId(),
|
||||||
0);
|
0);
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
|
|
||||||
public void updateFrameBufferAttachment(FrameBuffer fb, RenderBuffer rb) {
|
|
||||||
logger.warning("updateFrameBufferAttachment is not supported.");
|
|
||||||
}
|
|
||||||
/*
|
|
||||||
public void updateFrameBufferAttachment(FrameBuffer fb, RenderBuffer rb) {
|
public void updateFrameBufferAttachment(FrameBuffer fb, RenderBuffer rb) {
|
||||||
boolean needAttach;
|
boolean needAttach;
|
||||||
if (rb.getTexture() == null) {
|
if (rb.getTexture() == null) {
|
||||||
@ -1136,23 +1238,19 @@ public class OGLESShaderRenderer implements Renderer {
|
|||||||
updateRenderTexture(fb, rb);
|
updateRenderTexture(fb, rb);
|
||||||
}
|
}
|
||||||
if (needAttach) {
|
if (needAttach) {
|
||||||
glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT,
|
GLES20.glFramebufferRenderbuffer(GLES20.GL_FRAMEBUFFER,
|
||||||
convertAttachmentSlot(rb.getSlot()),
|
convertAttachmentSlot(rb.getSlot()),
|
||||||
GL_RENDERBUFFER_EXT,
|
GLES20.GL_RENDERBUFFER,
|
||||||
rb.getId());
|
rb.getId());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
|
|
||||||
public void updateFrameBuffer(FrameBuffer fb) {
|
|
||||||
logger.warning("updateFrameBuffer is not supported.");
|
|
||||||
}
|
|
||||||
/*
|
|
||||||
public void updateFrameBuffer(FrameBuffer fb) {
|
public void updateFrameBuffer(FrameBuffer fb) {
|
||||||
int id = fb.getId();
|
int id = fb.getId();
|
||||||
if (id == -1) {
|
if (id == -1) {
|
||||||
|
intBuf1.clear();
|
||||||
// create FBO
|
// create FBO
|
||||||
glGenFramebuffersEXT(intBuf1);
|
GLES20.glGenFramebuffers(1, intBuf1);
|
||||||
id = intBuf1.get(0);
|
id = intBuf1.get(0);
|
||||||
fb.setId(id);
|
fb.setId(id);
|
||||||
objManager.registerForCleanup(fb);
|
objManager.registerForCleanup(fb);
|
||||||
@ -1161,7 +1259,7 @@ public class OGLESShaderRenderer implements Renderer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (context.boundFBO != id) {
|
if (context.boundFBO != id) {
|
||||||
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, id);
|
GLES20.glBindFramebuffer(GLES20.GL_FRAMEBUFFER, id);
|
||||||
// binding an FBO automatically sets draw buf to GL_COLOR_ATTACHMENT0
|
// binding an FBO automatically sets draw buf to GL_COLOR_ATTACHMENT0
|
||||||
context.boundDrawBuf = 0;
|
context.boundDrawBuf = 0;
|
||||||
context.boundFBO = id;
|
context.boundFBO = id;
|
||||||
@ -1179,17 +1277,21 @@ public class OGLESShaderRenderer implements Renderer {
|
|||||||
|
|
||||||
fb.clearUpdateNeeded();
|
fb.clearUpdateNeeded();
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
|
|
||||||
public void setMainFrameBufferOverride(FrameBuffer fb){
|
public void setMainFrameBufferOverride(FrameBuffer fb){
|
||||||
|
mainFbOverride = fb;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setFrameBuffer(FrameBuffer fb) {
|
public void setFrameBuffer(FrameBuffer fb) {
|
||||||
|
if (fb == null && mainFbOverride != null) {
|
||||||
|
fb = mainFbOverride;
|
||||||
}
|
}
|
||||||
/*
|
|
||||||
public void setFrameBuffer(FrameBuffer fb) {
|
if (lastFb == fb) {
|
||||||
if (lastFb == fb)
|
if (fb == null || !fb.isUpdateNeeded()) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// generate mipmaps for last FB if needed
|
// generate mipmaps for last FB if needed
|
||||||
if (lastFb != null) {
|
if (lastFb != null) {
|
||||||
@ -1199,20 +1301,24 @@ public class OGLESShaderRenderer implements Renderer {
|
|||||||
if (tex != null
|
if (tex != null
|
||||||
&& tex.getMinFilter().usesMipMapLevels()) {
|
&& tex.getMinFilter().usesMipMapLevels()) {
|
||||||
setTexture(0, rb.getTexture());
|
setTexture(0, rb.getTexture());
|
||||||
glGenerateMipmapEXT(convertTextureType(tex.getType()));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
// int textureType = convertTextureType(tex.getType(), tex.getImage().getMultiSamples(), rb.getFace());
|
||||||
|
int textureType = convertTextureType(tex.getType());
|
||||||
|
GLES20.glGenerateMipmap(textureType);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (fb == null) {
|
if (fb == null) {
|
||||||
// unbind any fbos
|
// unbind any fbos
|
||||||
if (context.boundFBO != 0) {
|
if (context.boundFBO != 0) {
|
||||||
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
|
GLES20.glBindFramebuffer(GLES20.GL_FRAMEBUFFER, 0);
|
||||||
statistics.onFrameBufferUse(null, true);
|
statistics.onFrameBufferUse(null, true);
|
||||||
|
|
||||||
context.boundFBO = 0;
|
context.boundFBO = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
// select back buffer
|
// select back buffer
|
||||||
if (context.boundDrawBuf != -1) {
|
if (context.boundDrawBuf != -1) {
|
||||||
glDrawBuffer(initialDrawBuf);
|
glDrawBuffer(initialDrawBuf);
|
||||||
@ -1222,14 +1328,21 @@ public class OGLESShaderRenderer implements Renderer {
|
|||||||
glReadBuffer(initialReadBuf);
|
glReadBuffer(initialReadBuf);
|
||||||
context.boundReadBuf = -1;
|
context.boundReadBuf = -1;
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
lastFb = null;
|
lastFb = null;
|
||||||
} else {
|
} else {
|
||||||
if (fb.isUpdateNeeded())
|
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);
|
updateFrameBuffer(fb);
|
||||||
|
}
|
||||||
|
|
||||||
if (context.boundFBO != fb.getId()) {
|
if (context.boundFBO != fb.getId()) {
|
||||||
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fb.getId());
|
GLES20.glBindFramebuffer(GLES20.GL_FRAMEBUFFER, fb.getId());
|
||||||
statistics.onFrameBufferUse(fb, true);
|
statistics.onFrameBufferUse(fb, true);
|
||||||
|
|
||||||
// update viewport to reflect framebuffer's resolution
|
// update viewport to reflect framebuffer's resolution
|
||||||
@ -1240,37 +1353,44 @@ public class OGLESShaderRenderer implements Renderer {
|
|||||||
statistics.onFrameBufferUse(fb, false);
|
statistics.onFrameBufferUse(fb, false);
|
||||||
}
|
}
|
||||||
if (fb.getNumColorBuffers() == 0) {
|
if (fb.getNumColorBuffers() == 0) {
|
||||||
// make sure to select NONE as draw buf
|
// // make sure to select NONE as draw buf
|
||||||
// no color buffer attached. select NONE
|
// // no color buffer attached. select NONE
|
||||||
if (context.boundDrawBuf != -2) {
|
if (context.boundDrawBuf != -2) {
|
||||||
glDrawBuffer(GL_NONE);
|
// glDrawBuffer(GL_NONE);
|
||||||
context.boundDrawBuf = -2;
|
context.boundDrawBuf = -2;
|
||||||
}
|
}
|
||||||
if (context.boundReadBuf != -2) {
|
if (context.boundReadBuf != -2) {
|
||||||
glReadBuffer(GL_NONE);
|
// glReadBuffer(GL_NONE);
|
||||||
context.boundReadBuf = -2;
|
context.boundReadBuf = -2;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
if (fb.getNumColorBuffers() > maxFBOAttachs) {
|
||||||
|
throw new RendererException("Framebuffer has more color "
|
||||||
|
+ "attachments than are supported"
|
||||||
|
+ " by the video hardware!");
|
||||||
|
}
|
||||||
if (fb.isMultiTarget()) {
|
if (fb.isMultiTarget()) {
|
||||||
if (fb.getNumColorBuffers() > maxMRTFBOAttachs)
|
if (fb.getNumColorBuffers() > maxMRTFBOAttachs) {
|
||||||
throw new UnsupportedOperationException("Framebuffer has more"
|
throw new RendererException("Framebuffer has more"
|
||||||
+ " targets than are supported"
|
+ " multi targets than are supported"
|
||||||
+ " on the system!");
|
+ " by the video hardware!");
|
||||||
|
}
|
||||||
|
|
||||||
if (context.boundDrawBuf != 100 + fb.getNumColorBuffers()) {
|
if (context.boundDrawBuf != 100 + fb.getNumColorBuffers()) {
|
||||||
intBuf16.clear();
|
intBuf16.clear();
|
||||||
for (int i = 0; i < fb.getNumColorBuffers(); i++)
|
for (int i = 0; i < fb.getNumColorBuffers(); i++) {
|
||||||
intBuf16.put( GL_COLOR_ATTACHMENT0_EXT + i );
|
intBuf16.put(GLES20.GL_COLOR_ATTACHMENT0 + i);
|
||||||
|
}
|
||||||
|
|
||||||
intBuf16.flip();
|
intBuf16.flip();
|
||||||
glDrawBuffers(intBuf16);
|
// glDrawBuffers(intBuf16);
|
||||||
context.boundDrawBuf = 100 + fb.getNumColorBuffers();
|
context.boundDrawBuf = 100 + fb.getNumColorBuffers();
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
RenderBuffer rb = fb.getColorBuffer(fb.getTargetIndex());
|
RenderBuffer rb = fb.getColorBuffer(fb.getTargetIndex());
|
||||||
// select this draw buffer
|
// select this draw buffer
|
||||||
if (context.boundDrawBuf != rb.getSlot()) {
|
if (context.boundDrawBuf != rb.getSlot()) {
|
||||||
glDrawBuffer(GL_COLOR_ATTACHMENT0_EXT + rb.getSlot());
|
GLES20.glActiveTexture(convertAttachmentSlot(rb.getSlot()));
|
||||||
context.boundDrawBuf = rb.getSlot();
|
context.boundDrawBuf = rb.getSlot();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1278,73 +1398,49 @@ public class OGLESShaderRenderer implements Renderer {
|
|||||||
|
|
||||||
assert fb.getId() >= 0;
|
assert fb.getId() >= 0;
|
||||||
assert context.boundFBO == fb.getId();
|
assert context.boundFBO == fb.getId();
|
||||||
lastFb = fb;
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
lastFb = fb;
|
||||||
checkFrameBufferError();
|
|
||||||
} catch (IllegalStateException ex){
|
checkFrameBufferStatus(fb);
|
||||||
logger.log(Level.SEVERE, "Problem FBO:\n{0}", fb);
|
|
||||||
throw ex;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Reads the Color Buffer from OpenGL and stores into the ByteBuffer.
|
* Reads the Color Buffer from OpenGL and stores into the ByteBuffer.
|
||||||
* Since jME for Android does not support Frame Buffers yet, make sure the FrameBuffer
|
* Make sure to call setViewPort with the appropriate viewport size before
|
||||||
* passed in is NULL (default) or an exception will be thrown.
|
|
||||||
* Also, make sure to call setViewPort with the appropriate viewport size before
|
|
||||||
* calling readFrameBuffer.
|
* calling readFrameBuffer.
|
||||||
* @param fb FrameBuffer (must be NULL)
|
* @param fb FrameBuffer
|
||||||
* @param byteBuf ByteBuffer to store the Color Buffer from OpenGL
|
* @param byteBuf ByteBuffer to store the Color Buffer from OpenGL
|
||||||
*/
|
*/
|
||||||
public void readFrameBuffer(FrameBuffer fb, ByteBuffer byteBuf) {
|
|
||||||
if (fb != null) {
|
|
||||||
throw new IllegalArgumentException("FrameBuffer is not supported yet.");
|
|
||||||
}
|
|
||||||
|
|
||||||
GLES20.glReadPixels(vpX, vpY, vpW, vpH, GLES20.GL_RGBA, GLES20.GL_UNSIGNED_BYTE, byteBuf);
|
|
||||||
}
|
|
||||||
/*
|
|
||||||
public void readFrameBuffer(FrameBuffer fb, ByteBuffer byteBuf) {
|
public void readFrameBuffer(FrameBuffer fb, ByteBuffer byteBuf) {
|
||||||
if (fb != null) {
|
if (fb != null) {
|
||||||
RenderBuffer rb = fb.getColorBuffer();
|
RenderBuffer rb = fb.getColorBuffer();
|
||||||
if (rb == null)
|
if (rb == null) {
|
||||||
throw new IllegalArgumentException("Specified framebuffer" +
|
throw new IllegalArgumentException("Specified framebuffer"
|
||||||
" does not have a colorbuffer");
|
+ " does not have a colorbuffer");
|
||||||
|
}
|
||||||
|
|
||||||
setFrameBuffer(fb);
|
setFrameBuffer(fb);
|
||||||
if (context.boundReadBuf != rb.getSlot()) {
|
if (context.boundReadBuf != rb.getSlot()) {
|
||||||
glReadBuffer(GL_COLOR_ATTACHMENT0_EXT + rb.getSlot());
|
GLES20.glActiveTexture(convertAttachmentSlot(rb.getSlot()));
|
||||||
context.boundReadBuf = rb.getSlot();
|
context.boundReadBuf = rb.getSlot();
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
setFrameBuffer(null);
|
setFrameBuffer(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
glReadPixels(vpX, vpY, vpW, vpH, GL_RGBA GL_BGRA, GL_UNSIGNED_BYTE, byteBuf);
|
GLES20.glReadPixels(vpX, vpY, vpW, vpH, GLES20.GL_RGBA, GLES20.GL_UNSIGNED_BYTE, byteBuf);
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
|
|
||||||
private void deleteRenderBuffer(FrameBuffer fb, RenderBuffer rb) {
|
|
||||||
logger.warning("deleteRenderBuffer is not supported.");
|
|
||||||
}
|
|
||||||
/*
|
|
||||||
private void deleteRenderBuffer(FrameBuffer fb, RenderBuffer rb) {
|
private void deleteRenderBuffer(FrameBuffer fb, RenderBuffer rb) {
|
||||||
intBuf1.put(0, rb.getId());
|
intBuf1.put(0, rb.getId());
|
||||||
glDeleteRenderbuffersEXT(intBuf1);
|
GLES20.glDeleteRenderbuffers(1, intBuf1);
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
|
|
||||||
public void deleteFrameBuffer(FrameBuffer fb) {
|
|
||||||
logger.warning("deleteFrameBuffer is not supported.");
|
|
||||||
}
|
|
||||||
/*
|
|
||||||
public void deleteFrameBuffer(FrameBuffer fb) {
|
public void deleteFrameBuffer(FrameBuffer fb) {
|
||||||
if (fb.getId() != -1) {
|
if (fb.getId() != -1) {
|
||||||
if (context.boundFBO == fb.getId()) {
|
if (context.boundFBO == fb.getId()) {
|
||||||
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
|
GLES20.glBindFramebuffer(GLES20.GL_FRAMEBUFFER, 0);
|
||||||
context.boundFBO = 0;
|
context.boundFBO = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1356,13 +1452,12 @@ public class OGLESShaderRenderer implements Renderer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
intBuf1.put(0, fb.getId());
|
intBuf1.put(0, fb.getId());
|
||||||
glDeleteFramebuffersEXT(intBuf1);
|
GLES20.glDeleteFramebuffers(1, intBuf1);
|
||||||
fb.resetObject();
|
fb.resetObject();
|
||||||
|
|
||||||
statistics.onDeleteFrameBuffer();
|
statistics.onDeleteFrameBuffer();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
|
|
||||||
/*********************************************************************\
|
/*********************************************************************\
|
||||||
|* Textures *|
|
|* Textures *|
|
||||||
@ -1657,7 +1752,7 @@ public class OGLESShaderRenderer implements Renderer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private int convertFormat(Format format) {
|
private int convertVertexBufferFormat(Format format) {
|
||||||
switch (format) {
|
switch (format) {
|
||||||
case Byte:
|
case Byte:
|
||||||
return GLES20.GL_BYTE;
|
return GLES20.GL_BYTE;
|
||||||
@ -1856,7 +1951,7 @@ public class OGLESShaderRenderer implements Renderer {
|
|||||||
|
|
||||||
Android22Workaround.glVertexAttribPointer(loc,
|
Android22Workaround.glVertexAttribPointer(loc,
|
||||||
vb.getNumComponents(),
|
vb.getNumComponents(),
|
||||||
convertFormat(vb.getFormat()),
|
convertVertexBufferFormat(vb.getFormat()),
|
||||||
vb.isNormalized(),
|
vb.isNormalized(),
|
||||||
vb.getStride(),
|
vb.getStride(),
|
||||||
0);
|
0);
|
||||||
@ -1918,7 +2013,7 @@ public class OGLESShaderRenderer implements Renderer {
|
|||||||
int[] elementLengths = mesh.getElementLengths();
|
int[] elementLengths = mesh.getElementLengths();
|
||||||
|
|
||||||
int elMode = convertElementMode(Mode.Triangles);
|
int elMode = convertElementMode(Mode.Triangles);
|
||||||
int fmt = convertFormat(indexBuf.getFormat());
|
int fmt = convertVertexBufferFormat(indexBuf.getFormat());
|
||||||
int elSize = indexBuf.getFormat().getComponentSize();
|
int elSize = indexBuf.getFormat().getComponentSize();
|
||||||
int listStart = modeStart[0];
|
int listStart = modeStart[0];
|
||||||
int stripStart = modeStart[1];
|
int stripStart = modeStart[1];
|
||||||
@ -1964,7 +2059,7 @@ public class OGLESShaderRenderer implements Renderer {
|
|||||||
/*
|
/*
|
||||||
GLES20.glDrawElementsInstancedARB(convertElementMode(mesh.getMode()),
|
GLES20.glDrawElementsInstancedARB(convertElementMode(mesh.getMode()),
|
||||||
indexBuf.getData().limit(),
|
indexBuf.getData().limit(),
|
||||||
convertFormat(indexBuf.getFormat()),
|
convertVertexBufferFormat(indexBuf.getFormat()),
|
||||||
0,
|
0,
|
||||||
count);
|
count);
|
||||||
*/
|
*/
|
||||||
@ -1973,7 +2068,7 @@ public class OGLESShaderRenderer implements Renderer {
|
|||||||
GLES20.glDrawElements(
|
GLES20.glDrawElements(
|
||||||
convertElementMode(mesh.getMode()),
|
convertElementMode(mesh.getMode()),
|
||||||
indexBuf.getData().limit(),
|
indexBuf.getData().limit(),
|
||||||
convertFormat(indexBuf.getFormat()),
|
convertVertexBufferFormat(indexBuf.getFormat()),
|
||||||
0);
|
0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2172,7 +2267,7 @@ public class OGLESShaderRenderer implements Renderer {
|
|||||||
int[] elementLengths = mesh.getElementLengths();
|
int[] elementLengths = mesh.getElementLengths();
|
||||||
|
|
||||||
int elMode = convertElementMode(Mode.Triangles);
|
int elMode = convertElementMode(Mode.Triangles);
|
||||||
int fmt = convertFormat(indexBuf.getFormat());
|
int fmt = convertVertexBufferFormat(indexBuf.getFormat());
|
||||||
int elSize = indexBuf.getFormat().getComponentSize();
|
int elSize = indexBuf.getFormat().getComponentSize();
|
||||||
int listStart = modeStart[0];
|
int listStart = modeStart[0];
|
||||||
int stripStart = modeStart[1];
|
int stripStart = modeStart[1];
|
||||||
@ -2195,7 +2290,7 @@ public class OGLESShaderRenderer implements Renderer {
|
|||||||
GLES20.glDrawElements(
|
GLES20.glDrawElements(
|
||||||
convertElementMode(mesh.getMode()),
|
convertElementMode(mesh.getMode()),
|
||||||
indexBuf.getData().limit(),
|
indexBuf.getData().limit(),
|
||||||
convertFormat(indexBuf.getFormat()),
|
convertVertexBufferFormat(indexBuf.getFormat()),
|
||||||
indexBuf.getData());
|
indexBuf.getData());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2242,7 +2337,7 @@ public class OGLESShaderRenderer implements Renderer {
|
|||||||
// Upload attribute data
|
// Upload attribute data
|
||||||
GLES20.glVertexAttribPointer(loc,
|
GLES20.glVertexAttribPointer(loc,
|
||||||
vb.getNumComponents(),
|
vb.getNumComponents(),
|
||||||
convertFormat(vb.getFormat()),
|
convertVertexBufferFormat(vb.getFormat()),
|
||||||
vb.isNormalized(),
|
vb.isNormalized(),
|
||||||
vb.getStride(),
|
vb.getStride(),
|
||||||
avb.getData());
|
avb.getData());
|
||||||
|
@ -24,16 +24,19 @@ public class TextureUtil {
|
|||||||
private static boolean ETC1support = false;
|
private static boolean ETC1support = false;
|
||||||
private static boolean DXT1 = false;
|
private static boolean DXT1 = false;
|
||||||
private static boolean DEPTH24 = false;
|
private static boolean DEPTH24 = false;
|
||||||
|
private static boolean DEPTH_TEXTURE = false;
|
||||||
|
|
||||||
public static void loadTextureFeatures(String extensionString) {
|
public static void loadTextureFeatures(String extensionString) {
|
||||||
ETC1support = extensionString.contains("GL_OES_compressed_ETC1_RGB8_texture");
|
ETC1support = extensionString.contains("GL_OES_compressed_ETC1_RGB8_texture");
|
||||||
DEPTH24 = extensionString.contains("GL_OES_depth24");
|
DEPTH24 = extensionString.contains("GL_OES_depth24");
|
||||||
NPOT = extensionString.contains("GL_OES_texture_npot") || extensionString.contains("GL_NV_texture_npot_2D_mipmap");
|
NPOT = extensionString.contains("GL_OES_texture_npot") || extensionString.contains("GL_NV_texture_npot_2D_mipmap");
|
||||||
DXT1 = extensionString.contains("GL_EXT_texture_compression_dxt1");
|
DXT1 = extensionString.contains("GL_EXT_texture_compression_dxt1");
|
||||||
|
DEPTH_TEXTURE = extensionString.contains("GL_OES_depth_texture");
|
||||||
logger.log(Level.FINE, "Supports ETC1? {0}", ETC1support);
|
logger.log(Level.FINE, "Supports ETC1? {0}", ETC1support);
|
||||||
logger.log(Level.FINE, "Supports DEPTH24? {0}", DEPTH24);
|
logger.log(Level.FINE, "Supports DEPTH24? {0}", DEPTH24);
|
||||||
logger.log(Level.FINE, "Supports NPOT? {0}", NPOT);
|
logger.log(Level.FINE, "Supports NPOT? {0}", NPOT);
|
||||||
logger.log(Level.FINE, "Supports DXT1? {0}", DXT1);
|
logger.log(Level.FINE, "Supports DXT1? {0}", DXT1);
|
||||||
|
logger.log(Level.FINE, "Supports DEPTH_TEXTURE? {0}", DEPTH_TEXTURE);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void buildMipmap(Bitmap bitmap, boolean compress) {
|
private static void buildMipmap(Bitmap bitmap, boolean compress) {
|
||||||
@ -241,7 +244,7 @@ public class TextureUtil {
|
|||||||
throw new UnsupportedOperationException("The image format '" + fmt + "' is unsupported by the video hardware.");
|
throw new UnsupportedOperationException("The image format '" + fmt + "' is unsupported by the video hardware.");
|
||||||
}
|
}
|
||||||
|
|
||||||
private static AndroidGLImageFormat getImageFormat(Format fmt) throws UnsupportedOperationException {
|
public static AndroidGLImageFormat getImageFormat(Format fmt) throws UnsupportedOperationException {
|
||||||
AndroidGLImageFormat imageFormat = new AndroidGLImageFormat();
|
AndroidGLImageFormat imageFormat = new AndroidGLImageFormat();
|
||||||
switch (fmt) {
|
switch (fmt) {
|
||||||
case RGBA16:
|
case RGBA16:
|
||||||
@ -269,14 +272,17 @@ public class TextureUtil {
|
|||||||
case RGB565:
|
case RGB565:
|
||||||
imageFormat.format = GLES20.GL_RGB;
|
imageFormat.format = GLES20.GL_RGB;
|
||||||
imageFormat.dataType = GLES20.GL_UNSIGNED_SHORT_5_6_5;
|
imageFormat.dataType = GLES20.GL_UNSIGNED_SHORT_5_6_5;
|
||||||
|
imageFormat.renderBufferStorageFormat = GLES20.GL_RGB565;
|
||||||
break;
|
break;
|
||||||
case ARGB4444:
|
case ARGB4444:
|
||||||
imageFormat.format = GLES20.GL_RGBA4;
|
imageFormat.format = GLES20.GL_RGBA4;
|
||||||
imageFormat.dataType = GLES20.GL_UNSIGNED_SHORT_4_4_4_4;
|
imageFormat.dataType = GLES20.GL_UNSIGNED_SHORT_4_4_4_4;
|
||||||
|
imageFormat.renderBufferStorageFormat = GLES20.GL_RGBA4;
|
||||||
break;
|
break;
|
||||||
case RGB5A1:
|
case RGB5A1:
|
||||||
imageFormat.format = GLES20.GL_RGBA;
|
imageFormat.format = GLES20.GL_RGBA;
|
||||||
imageFormat.dataType = GLES20.GL_UNSIGNED_SHORT_5_5_5_1;
|
imageFormat.dataType = GLES20.GL_UNSIGNED_SHORT_5_5_5_1;
|
||||||
|
imageFormat.renderBufferStorageFormat = GLES20.GL_RGB5_A1;
|
||||||
break;
|
break;
|
||||||
case RGB8:
|
case RGB8:
|
||||||
imageFormat.format = GLES20.GL_RGB;
|
imageFormat.format = GLES20.GL_RGB;
|
||||||
@ -293,8 +299,12 @@ public class TextureUtil {
|
|||||||
case Depth:
|
case Depth:
|
||||||
case Depth16:
|
case Depth16:
|
||||||
case Depth24:
|
case Depth24:
|
||||||
|
if (!DEPTH_TEXTURE) {
|
||||||
|
unsupportedFormat(fmt);
|
||||||
|
}
|
||||||
imageFormat.format = GLES20.GL_DEPTH_COMPONENT;
|
imageFormat.format = GLES20.GL_DEPTH_COMPONENT;
|
||||||
imageFormat.dataType = GLES20.GL_UNSIGNED_BYTE;
|
imageFormat.dataType = GLES20.GL_UNSIGNED_SHORT;
|
||||||
|
imageFormat.renderBufferStorageFormat = GLES20.GL_DEPTH_COMPONENT16;
|
||||||
break;
|
break;
|
||||||
case DXT1:
|
case DXT1:
|
||||||
if (!DXT1) {
|
if (!DXT1) {
|
||||||
@ -318,10 +328,11 @@ public class TextureUtil {
|
|||||||
return imageFormat;
|
return imageFormat;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static class AndroidGLImageFormat {
|
public static class AndroidGLImageFormat {
|
||||||
|
|
||||||
boolean compress = false;
|
boolean compress = false;
|
||||||
int format = -1;
|
int format = -1;
|
||||||
|
int renderBufferStorageFormat = -1;
|
||||||
int dataType = -1;
|
int dataType = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user