Main repository of MikuMikuStudio
Revision | 7bfd8006751a294d37cad75df61e98dbb73308c6 (tree) |
---|---|
Time | 2013-07-06 10:37:56 |
Author | kobayasi <kobayasi@pscn...> |
Commiter | kobayasi |
Add FrameBuffer support for Android
@@ -96,7 +96,7 @@ public final class OGLESShaderRenderer implements Renderer { | ||
96 | 96 | private int fragUniforms; |
97 | 97 | private int vertexAttribs; |
98 | 98 | private int maxFBOSamples; |
99 | - private int maxFBOAttachs; | |
99 | + private int maxFBOAttachs = 1; | |
100 | 100 | private int maxMRTFBOAttachs; |
101 | 101 | private int maxRBSize; |
102 | 102 | private int maxTexSize; |
@@ -105,6 +105,7 @@ public final class OGLESShaderRenderer implements Renderer { | ||
105 | 105 | private int maxTriCount; |
106 | 106 | private boolean tdc; |
107 | 107 | private FrameBuffer lastFb = null; |
108 | + private FrameBuffer mainFbOverride = null; | |
108 | 109 | private final Statistics statistics = new Statistics(); |
109 | 110 | private int vpX, vpY, vpW, vpH; |
110 | 111 | private int clipX, clipY, clipW, clipH; |
@@ -371,6 +372,9 @@ public final class OGLESShaderRenderer implements Renderer { | ||
371 | 372 | } |
372 | 373 | } |
373 | 374 | */ |
375 | + GLES20.glGetIntegerv(GLES20.GL_MAX_RENDERBUFFER_SIZE, intBuf16); | |
376 | + maxRBSize = intBuf16.get(0); | |
377 | + logger.log(Level.FINER, "FBO RB Max Size: {0}", maxRBSize); | |
374 | 378 | |
375 | 379 | String extensions = GLES20.glGetString(GLES20.GL_EXTENSIONS); |
376 | 380 | logger.log(Level.INFO, "GL_EXTENSIONS: {0}", extensions); |
@@ -885,6 +889,9 @@ public final class OGLESShaderRenderer implements Renderer { | ||
885 | 889 | if (val instanceof ColorRGBA) { |
886 | 890 | ColorRGBA c = (ColorRGBA) val; |
887 | 891 | GLES20.glUniform4f(loc, c.r, c.g, c.b, c.a); |
892 | + } else if (val instanceof Vector4f) { | |
893 | + Vector4f c = (Vector4f) val; | |
894 | + GLES20.glUniform4f(loc, c.x, c.y, c.z, c.w); | |
888 | 895 | } else { |
889 | 896 | Quaternion c = (Quaternion) uniform.getValue(); |
890 | 897 | GLES20.glUniform4f(loc, c.getX(), c.getY(), c.getZ(), c.getW()); |
@@ -1420,390 +1427,427 @@ public final class OGLESShaderRenderer implements Renderer { | ||
1420 | 1427 | |* Framebuffers *| |
1421 | 1428 | \*********************************************************************/ |
1422 | 1429 | public void copyFrameBuffer(FrameBuffer src, FrameBuffer dst) { |
1423 | - logger.warning("copyFrameBuffer is not supported."); | |
1430 | + copyFrameBuffer(src, dst, true); | |
1424 | 1431 | } |
1425 | 1432 | |
1426 | 1433 | public void copyFrameBuffer(FrameBuffer src, FrameBuffer dst, boolean copyDepth) { |
1427 | 1434 | logger.warning("copyFrameBuffer is not supported."); |
1428 | 1435 | } |
1429 | - /* | |
1430 | - public void copyFrameBuffer(FrameBuffer src, FrameBuffer dst){ | |
1431 | - if (GLContext.getCapabilities().GL_EXT_framebuffer_blit){ | |
1432 | - int srcW = 0; | |
1433 | - int srcH = 0; | |
1434 | - int dstW = 0; | |
1435 | - int dstH = 0; | |
1436 | - int prevFBO = context.boundFBO; | |
1437 | - | |
1438 | - if (src != null && src.isUpdateNeeded()) | |
1439 | - updateFrameBuffer(src); | |
1440 | - | |
1441 | - if (dst != null && dst.isUpdateNeeded()) | |
1442 | - updateFrameBuffer(dst); | |
1443 | - | |
1444 | - if (src == null){ | |
1445 | - glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, 0); | |
1446 | - // srcW = viewWidth; | |
1447 | - // srcH = viewHeight; | |
1448 | - }else{ | |
1449 | - glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, src.getId()); | |
1450 | - srcW = src.getWidth(); | |
1451 | - srcH = src.getHeight(); | |
1452 | - } | |
1453 | - if (dst == null){ | |
1454 | - glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, 0); | |
1455 | - // dstW = viewWidth; | |
1456 | - // dstH = viewHeight; | |
1457 | - }else{ | |
1458 | - glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, dst.getId()); | |
1459 | - dstW = dst.getWidth(); | |
1460 | - dstH = dst.getHeight(); | |
1461 | - } | |
1462 | - glBlitFramebufferEXT(0, 0, srcW, srcH, | |
1463 | - 0, 0, dstW, dstH, | |
1464 | - GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT, | |
1465 | - GL_NEAREST); | |
1466 | - | |
1467 | - glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, prevFBO); | |
1468 | - try { | |
1469 | - checkFrameBufferError(); | |
1470 | - } catch (IllegalStateException ex){ | |
1471 | - logger.log(Level.SEVERE, "Source FBO:\n{0}", src); | |
1472 | - logger.log(Level.SEVERE, "Dest FBO:\n{0}", dst); | |
1473 | - throw ex; | |
1474 | - } | |
1475 | - }else{ | |
1476 | - throw new UnsupportedOperationException("EXT_framebuffer_blit required."); | |
1477 | - // TODO: support non-blit copies? | |
1478 | - } | |
1436 | + private void checkFrameBufferStatus(FrameBuffer fb) { | |
1437 | + try { | |
1438 | + checkFrameBufferError(); | |
1439 | + } catch (IllegalStateException ex) { | |
1440 | + logger.log(Level.SEVERE, "=== jMonkeyEngine FBO State ===\n{0}", fb); | |
1441 | + printRealFrameBufferInfo(fb); | |
1442 | + throw ex; | |
1443 | + } | |
1479 | 1444 | } |
1480 | - */ | |
1481 | 1445 | |
1482 | 1446 | private void checkFrameBufferError() { |
1483 | - logger.warning("checkFrameBufferError is not supported."); | |
1447 | + int status = GLES20.glCheckFramebufferStatus(GLES20.GL_FRAMEBUFFER); | |
1448 | + switch (status) { | |
1449 | + case GLES20.GL_FRAMEBUFFER_COMPLETE: | |
1450 | + break; | |
1451 | + case GLES20.GL_FRAMEBUFFER_UNSUPPORTED: | |
1452 | + //Choose different formats | |
1453 | + throw new IllegalStateException("Framebuffer object format is " | |
1454 | + + "unsupported by the video hardware."); | |
1455 | + case GLES20.GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT: | |
1456 | + throw new IllegalStateException("Framebuffer has erronous attachment."); | |
1457 | + case GLES20.GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT: | |
1458 | + throw new IllegalStateException("Framebuffer doesn't have any renderbuffers attached."); | |
1459 | + case GLES20.GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS: | |
1460 | + throw new IllegalStateException("Framebuffer attachments must have same dimensions."); | |
1461 | +// case GLES20.GL_FRAMEBUFFER_INCOMPLETE_FORMATS: | |
1462 | +// throw new IllegalStateException("Framebuffer attachments must have same formats."); | |
1463 | +// case GLES20.GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER: | |
1464 | +// throw new IllegalStateException("Incomplete draw buffer."); | |
1465 | +// case GLES20.GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT: | |
1466 | +// throw new IllegalStateException("Incomplete read buffer."); | |
1467 | +// case GLES20.GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_EXT: | |
1468 | +// throw new IllegalStateException("Incomplete multisample buffer."); | |
1469 | + default: | |
1470 | + //Programming error; will fail on all hardware | |
1471 | + throw new IllegalStateException("Some video driver error " | |
1472 | + + "or programming error occured. " | |
1473 | + + "Framebuffer object status is invalid: " + status); | |
1474 | + } | |
1484 | 1475 | } |
1485 | - /* | |
1486 | - private void checkFrameBufferError() { | |
1487 | - int status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT); | |
1488 | - switch (status) { | |
1489 | - case GL_FRAMEBUFFER_COMPLETE_EXT: | |
1490 | - break; | |
1491 | - case GL_FRAMEBUFFER_UNSUPPORTED_EXT: | |
1492 | - //Choose different formats | |
1493 | - throw new IllegalStateException("Framebuffer object format is " + | |
1494 | - "unsupported by the video hardware."); | |
1495 | - case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT: | |
1496 | - throw new IllegalStateException("Framebuffer has erronous attachment."); | |
1497 | - case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT: | |
1498 | - throw new IllegalStateException("Framebuffer is missing required attachment."); | |
1499 | - case GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT: | |
1500 | - throw new IllegalStateException("Framebuffer attachments must have same dimensions."); | |
1501 | - case GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT: | |
1502 | - throw new IllegalStateException("Framebuffer attachments must have same formats."); | |
1503 | - case GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT: | |
1504 | - throw new IllegalStateException("Incomplete draw buffer."); | |
1505 | - case GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT: | |
1506 | - throw new IllegalStateException("Incomplete read buffer."); | |
1507 | - case GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_EXT: | |
1508 | - throw new IllegalStateException("Incomplete multisample buffer."); | |
1509 | - default: | |
1510 | - //Programming error; will fail on all hardware | |
1511 | - throw new IllegalStateException("Some video driver error " + | |
1512 | - "or programming error occured. " + | |
1513 | - "Framebuffer object status is invalid. "); | |
1476 | + private void printRealRenderBufferInfo(FrameBuffer fb, RenderBuffer rb, String name) { | |
1477 | + System.out.println("== Renderbuffer " + name + " =="); | |
1478 | + System.out.println("RB ID: " + rb.getId()); | |
1479 | + System.out.println("Is proper? " + GLES20.glIsRenderbuffer(rb.getId())); | |
1480 | + | |
1481 | + int attachment = convertAttachmentSlot(rb.getSlot()); | |
1482 | + | |
1483 | + intBuf16.clear(); | |
1484 | + GLES20.glGetFramebufferAttachmentParameteriv(GLES20.GL_FRAMEBUFFER, | |
1485 | + attachment, GLES20.GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE, intBuf16); | |
1486 | + int type = intBuf16.get(0); | |
1487 | + | |
1488 | + intBuf16.clear(); | |
1489 | + GLES20.glGetFramebufferAttachmentParameteriv(GLES20.GL_FRAMEBUFFER, | |
1490 | + attachment, GLES20.GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME, intBuf16); | |
1491 | + int rbName = intBuf16.get(0); | |
1492 | + | |
1493 | + switch (type) { | |
1494 | + case GLES20.GL_NONE: | |
1495 | + System.out.println("Type: None"); | |
1496 | + break; | |
1497 | + case GLES20.GL_TEXTURE: | |
1498 | + System.out.println("Type: Texture"); | |
1499 | + break; | |
1500 | + case GLES20.GL_RENDERBUFFER: | |
1501 | + System.out.println("Type: Buffer"); | |
1502 | + System.out.println("RB ID: " + rbName); | |
1503 | + break; | |
1504 | + } | |
1505 | + | |
1506 | + | |
1507 | + | |
1514 | 1508 | } |
1509 | + | |
1510 | + private void printRealFrameBufferInfo(FrameBuffer fb) { | |
1511 | +// boolean doubleBuffer = GLES20.glGetBooleanv(GLES20.GL_DOUBLEBUFFER); | |
1512 | + boolean doubleBuffer = false; // FIXME | |
1513 | +// String drawBuf = getTargetBufferName(glGetInteger(GL_DRAW_BUFFER)); | |
1514 | +// String readBuf = getTargetBufferName(glGetInteger(GL_READ_BUFFER)); | |
1515 | + | |
1516 | + int fbId = fb.getId(); | |
1517 | + intBuf16.clear(); | |
1518 | +// int curDrawBinding = GLES20.glGetIntegerv(GLES20.GL_DRAW_FRAMEBUFFER_BINDING); | |
1519 | +// int curReadBinding = glGetInteger(ARBFramebufferObject.GL_READ_FRAMEBUFFER_BINDING); | |
1520 | + | |
1521 | + System.out.println("=== OpenGL FBO State ==="); | |
1522 | + System.out.println("Context doublebuffered? " + doubleBuffer); | |
1523 | + System.out.println("FBO ID: " + fbId); | |
1524 | + System.out.println("Is proper? " + GLES20.glIsFramebuffer(fbId)); | |
1525 | +// System.out.println("Is bound to draw? " + (fbId == curDrawBinding)); | |
1526 | +// System.out.println("Is bound to read? " + (fbId == curReadBinding)); | |
1527 | +// System.out.println("Draw buffer: " + drawBuf); | |
1528 | +// System.out.println("Read buffer: " + readBuf); | |
1529 | + | |
1530 | + if (context.boundFBO != fbId) { | |
1531 | + GLES20.glBindFramebuffer(GLES20.GL_FRAMEBUFFER, fbId); | |
1532 | + context.boundFBO = fbId; | |
1533 | + } | |
1534 | + | |
1535 | + if (fb.getDepthBuffer() != null) { | |
1536 | + printRealRenderBufferInfo(fb, fb.getDepthBuffer(), "Depth"); | |
1537 | + } | |
1538 | + for (int i = 0; i < fb.getNumColorBuffers(); i++) { | |
1539 | + printRealRenderBufferInfo(fb, fb.getColorBuffer(i), "Color" + i); | |
1540 | + } | |
1515 | 1541 | } |
1516 | - */ | |
1517 | 1542 | |
1518 | 1543 | private void updateRenderBuffer(FrameBuffer fb, RenderBuffer rb) { |
1519 | - logger.warning("updateRenderBuffer is not supported."); | |
1520 | - } | |
1521 | - /* | |
1522 | - private void updateRenderBuffer(FrameBuffer fb, RenderBuffer rb){ | |
1523 | - int id = rb.getId(); | |
1524 | - if (id == -1){ | |
1525 | - glGenRenderbuffersEXT(intBuf1); | |
1526 | - id = intBuf1.get(0); | |
1527 | - rb.setId(id); | |
1528 | - } | |
1529 | - | |
1530 | - if (context.boundRB != id){ | |
1531 | - glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, id); | |
1532 | - context.boundRB = id; | |
1533 | - } | |
1534 | - | |
1535 | - if (fb.getWidth() > maxRBSize || fb.getHeight() > maxRBSize) | |
1536 | - throw new UnsupportedOperationException("Resolution "+fb.getWidth()+ | |
1537 | - ":"+fb.getHeight()+" is not supported."); | |
1538 | - | |
1539 | - if (fb.getSamples() > 0 && GLContext.getCapabilities().GL_EXT_framebuffer_multisample){ | |
1540 | - int samples = fb.getSamples(); | |
1541 | - if (maxFBOSamples < samples){ | |
1542 | - samples = maxFBOSamples; | |
1543 | - } | |
1544 | - glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER_EXT, | |
1545 | - samples, | |
1546 | - TextureUtil.convertTextureFormat(rb.getFormat()), | |
1547 | - fb.getWidth(), | |
1548 | - fb.getHeight()); | |
1549 | - }else{ | |
1550 | - glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, | |
1551 | - TextureUtil.convertTextureFormat(rb.getFormat()), | |
1552 | - fb.getWidth(), | |
1553 | - fb.getHeight()); | |
1554 | - } | |
1555 | - } | |
1556 | - */ | |
1544 | + int id = rb.getId(); | |
1545 | + if (id == -1) { | |
1546 | + GLES20.glGenRenderbuffers(1, intBuf1); | |
1547 | +// RendererUtil.checkGLError(); | |
1557 | 1548 | |
1558 | - private int convertAttachmentSlot(int attachmentSlot) { | |
1559 | - logger.warning("convertAttachmentSlot is not supported."); | |
1560 | - return -1; | |
1561 | - } | |
1562 | - /* | |
1563 | - private int convertAttachmentSlot(int attachmentSlot){ | |
1564 | - // can also add support for stencil here | |
1565 | - if (attachmentSlot == -100){ | |
1566 | - return GL_DEPTH_ATTACHMENT_EXT; | |
1567 | - }else if (attachmentSlot < 0 || attachmentSlot >= 16){ | |
1568 | - throw new UnsupportedOperationException("Invalid FBO attachment slot: "+attachmentSlot); | |
1549 | + id = intBuf1.get(0); | |
1550 | + rb.setId(id); | |
1551 | + } | |
1552 | + | |
1553 | + if (context.boundRB != id) { | |
1554 | + GLES20.glBindRenderbuffer(GLES20.GL_RENDERBUFFER, id); | |
1555 | +// RendererUtil.checkGLError(); | |
1556 | + | |
1557 | + context.boundRB = id; | |
1558 | + } | |
1559 | + | |
1560 | + if (fb.getWidth() > maxRBSize || fb.getHeight() > maxRBSize) { | |
1561 | + throw new RendererException("Resolution " + fb.getWidth() | |
1562 | + + ":" + fb.getHeight() + " is not supported."); | |
1563 | + } | |
1564 | + | |
1565 | + TextureUtil.AndroidGLImageFormat imageFormat = TextureUtil.getImageFormat(rb.getFormat()); | |
1566 | + if (imageFormat.renderBufferStorageFormat == 0) { | |
1567 | + throw new RendererException("The format '" + rb.getFormat() + "' cannot be used for renderbuffers."); | |
1568 | + } | |
1569 | + | |
1570 | +// if (fb.getSamples() > 1 && GLContext.getCapabilities().GL_EXT_framebuffer_multisample) { | |
1571 | + if (fb.getSamples() > 1) { | |
1572 | +// // FIXME | |
1573 | + throw new RendererException("Multisample FrameBuffer is not supported yet."); | |
1574 | +// int samples = fb.getSamples(); | |
1575 | +// if (maxFBOSamples < samples) { | |
1576 | +// samples = maxFBOSamples; | |
1577 | +// } | |
1578 | +// glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER_EXT, | |
1579 | +// samples, | |
1580 | +// glFmt.internalFormat, | |
1581 | +// fb.getWidth(), | |
1582 | +// fb.getHeight()); | |
1583 | + } else { | |
1584 | + GLES20.glRenderbufferStorage(GLES20.GL_RENDERBUFFER, | |
1585 | + imageFormat.renderBufferStorageFormat, | |
1586 | + fb.getWidth(), | |
1587 | + fb.getHeight()); | |
1588 | + | |
1589 | +// RendererUtil.checkGLError(); | |
1590 | + } | |
1569 | 1591 | } |
1570 | - | |
1571 | - return GL_COLOR_ATTACHMENT0_EXT + attachmentSlot; | |
1592 | + private int convertAttachmentSlot(int attachmentSlot) { | |
1593 | + // can also add support for stencil here | |
1594 | + if (attachmentSlot == -100) { | |
1595 | + return GLES20.GL_DEPTH_ATTACHMENT; | |
1596 | + } else if (attachmentSlot == 0) { | |
1597 | + return GLES20.GL_COLOR_ATTACHMENT0; | |
1598 | + } else { | |
1599 | + throw new UnsupportedOperationException("Android does not support multiple color attachments to an FBO"); | |
1600 | + } | |
1572 | 1601 | } |
1573 | - */ | |
1574 | 1602 | |
1575 | 1603 | public void updateRenderTexture(FrameBuffer fb, RenderBuffer rb) { |
1576 | - logger.warning("updateRenderTexture is not supported."); | |
1577 | - } | |
1578 | - /* | |
1579 | - public void updateRenderTexture(FrameBuffer fb, RenderBuffer rb){ | |
1580 | - Texture tex = rb.getTexture(); | |
1581 | - Image image = tex.getImage(); | |
1582 | - if (image.isUpdateNeeded()) | |
1583 | - updateTexImageData(image, tex.getType(), tex.getMinFilter().usesMipMapLevels()); | |
1584 | - | |
1585 | - glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, | |
1586 | - convertAttachmentSlot(rb.getSlot()), | |
1587 | - convertTextureType(tex.getType()), | |
1588 | - image.getId(), | |
1589 | - 0); | |
1604 | + Texture tex = rb.getTexture(); | |
1605 | + Image image = tex.getImage(); | |
1606 | + if (image.isUpdateNeeded()) { | |
1607 | + updateTexImageData(image, tex.getType(), false); | |
1608 | + | |
1609 | + // NOTE: For depth textures, sets nearest/no-mips mode | |
1610 | + // Required to fix "framebuffer unsupported" | |
1611 | + // for old NVIDIA drivers! | |
1612 | + setupTextureParams(tex); | |
1613 | + } | |
1614 | + | |
1615 | + GLES20.glFramebufferTexture2D(GLES20.GL_FRAMEBUFFER, | |
1616 | + convertAttachmentSlot(rb.getSlot()), | |
1617 | + convertTextureType(tex.getType()), | |
1618 | + image.getId(), | |
1619 | + 0); | |
1620 | + | |
1621 | +// RendererUtil.checkGLError(); | |
1590 | 1622 | } |
1591 | - */ | |
1592 | 1623 | |
1593 | 1624 | public void updateFrameBufferAttachment(FrameBuffer fb, RenderBuffer rb) { |
1594 | - logger.warning("updateFrameBufferAttachment is not supported."); | |
1595 | - } | |
1596 | - /* | |
1597 | - public void updateFrameBufferAttachment(FrameBuffer fb, RenderBuffer rb){ | |
1598 | - boolean needAttach; | |
1599 | - if (rb.getTexture() == null){ | |
1600 | - // if it hasn't been created yet, then attach is required. | |
1601 | - needAttach = rb.getId() == -1; | |
1602 | - updateRenderBuffer(fb, rb); | |
1603 | - }else{ | |
1604 | - needAttach = false; | |
1605 | - updateRenderTexture(fb, rb); | |
1606 | - } | |
1607 | - if (needAttach){ | |
1608 | - glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, | |
1609 | - convertAttachmentSlot(rb.getSlot()), | |
1610 | - GL_RENDERBUFFER_EXT, | |
1611 | - rb.getId()); | |
1612 | - } | |
1613 | - } | |
1614 | - */ | |
1625 | + boolean needAttach; | |
1626 | + if (rb.getTexture() == null) { | |
1627 | + // if it hasn't been created yet, then attach is required. | |
1628 | + needAttach = rb.getId() == -1; | |
1629 | + updateRenderBuffer(fb, rb); | |
1630 | + } else { | |
1631 | + needAttach = false; | |
1632 | + updateRenderTexture(fb, rb); | |
1633 | + } | |
1634 | + if (needAttach) { | |
1635 | + GLES20.glFramebufferRenderbuffer(GLES20.GL_FRAMEBUFFER, | |
1636 | + convertAttachmentSlot(rb.getSlot()), | |
1637 | + GLES20.GL_RENDERBUFFER, | |
1638 | + rb.getId()); | |
1615 | 1639 | |
1616 | - public void updateFrameBuffer(FrameBuffer fb) { | |
1617 | - logger.warning("updateFrameBuffer is not supported."); | |
1640 | +// RendererUtil.checkGLError(); | |
1641 | + } | |
1618 | 1642 | } |
1619 | - /* | |
1643 | + | |
1620 | 1644 | public void updateFrameBuffer(FrameBuffer fb) { |
1621 | - int id = fb.getId(); | |
1622 | - if (id == -1){ | |
1623 | - // create FBO | |
1624 | - glGenFramebuffersEXT(intBuf1); | |
1625 | - id = intBuf1.get(0); | |
1626 | - fb.setId(id); | |
1627 | - objManager.registerForCleanup(fb); | |
1628 | - | |
1629 | - statistics.onNewFrameBuffer(); | |
1630 | - } | |
1631 | - | |
1632 | - if (context.boundFBO != id){ | |
1633 | - glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, id); | |
1634 | - // binding an FBO automatically sets draw buf to GL_COLOR_ATTACHMENT0 | |
1635 | - context.boundDrawBuf = 0; | |
1636 | - context.boundFBO = id; | |
1637 | - } | |
1638 | - | |
1639 | - FrameBuffer.RenderBuffer depthBuf = fb.getDepthBuffer(); | |
1640 | - if (depthBuf != null){ | |
1641 | - updateFrameBufferAttachment(fb, depthBuf); | |
1642 | - } | |
1643 | - | |
1644 | - for (int i = 0; i < fb.getNumColorBuffers(); i++){ | |
1645 | - FrameBuffer.RenderBuffer colorBuf = fb.getColorBuffer(i); | |
1646 | - updateFrameBufferAttachment(fb, colorBuf); | |
1647 | - } | |
1648 | - | |
1649 | - fb.clearUpdateNeeded(); | |
1645 | + int id = fb.getId(); | |
1646 | + if (id == -1) { | |
1647 | + intBuf1.clear(); | |
1648 | + // create FBO | |
1649 | + GLES20.glGenFramebuffers(1, intBuf1); | |
1650 | +// RendererUtil.checkGLError(); | |
1651 | + | |
1652 | + id = intBuf1.get(0); | |
1653 | + fb.setId(id); | |
1654 | + objManager.registerForCleanup(fb); | |
1655 | + | |
1656 | + statistics.onNewFrameBuffer(); | |
1657 | + } | |
1658 | + | |
1659 | + if (context.boundFBO != id) { | |
1660 | + GLES20.glBindFramebuffer(GLES20.GL_FRAMEBUFFER, id); | |
1661 | +// RendererUtil.checkGLError(); | |
1662 | + | |
1663 | + // binding an FBO automatically sets draw buf to GL_COLOR_ATTACHMENT0 | |
1664 | + context.boundDrawBuf = 0; | |
1665 | + context.boundFBO = id; | |
1666 | + } | |
1667 | + | |
1668 | + FrameBuffer.RenderBuffer depthBuf = fb.getDepthBuffer(); | |
1669 | + if (depthBuf != null) { | |
1670 | + updateFrameBufferAttachment(fb, depthBuf); | |
1671 | + } | |
1672 | + | |
1673 | + for (int i = 0; i < fb.getNumColorBuffers(); i++) { | |
1674 | + FrameBuffer.RenderBuffer colorBuf = fb.getColorBuffer(i); | |
1675 | + updateFrameBufferAttachment(fb, colorBuf); | |
1676 | + } | |
1677 | + | |
1678 | + fb.clearUpdateNeeded(); | |
1650 | 1679 | } |
1651 | - */ | |
1652 | 1680 | |
1653 | - public void setMainFrameBufferOverride(FrameBuffer fb) { | |
1681 | + public void setMainFrameBufferOverride(FrameBuffer fb){ | |
1682 | + mainFbOverride = fb; | |
1654 | 1683 | } |
1655 | 1684 | |
1656 | 1685 | public void setFrameBuffer(FrameBuffer fb) { |
1657 | - if (verboseLogging) { | |
1658 | - logger.warning("setFrameBuffer is not supported."); | |
1686 | + if (fb == null && mainFbOverride != null) { | |
1687 | + fb = mainFbOverride; | |
1688 | + } | |
1689 | + | |
1690 | + if (lastFb == fb) { | |
1691 | + if (fb == null || !fb.isUpdateNeeded()) { | |
1692 | + return; | |
1693 | + } | |
1694 | + } | |
1695 | + | |
1696 | + // generate mipmaps for last FB if needed | |
1697 | + if (lastFb != null) { | |
1698 | + for (int i = 0; i < lastFb.getNumColorBuffers(); i++) { | |
1699 | + RenderBuffer rb = lastFb.getColorBuffer(i); | |
1700 | + Texture tex = rb.getTexture(); | |
1701 | + if (tex != null | |
1702 | + && tex.getMinFilter().usesMipMapLevels()) { | |
1703 | + setTexture(0, rb.getTexture()); | |
1704 | + | |
1705 | +// int textureType = convertTextureType(tex.getType(), tex.getImage().getMultiSamples(), rb.getFace()); | |
1706 | + int textureType = convertTextureType(tex.getType()); | |
1707 | + GLES20.glGenerateMipmap(textureType); | |
1708 | +// RendererUtil.checkGLError(); | |
1709 | + } | |
1710 | + } | |
1711 | + } | |
1712 | + | |
1713 | + if (fb == null) { | |
1714 | + // unbind any fbos | |
1715 | + if (context.boundFBO != 0) { | |
1716 | + GLES20.glBindFramebuffer(GLES20.GL_FRAMEBUFFER, 0); | |
1717 | +// RendererUtil.checkGLError(); | |
1718 | + | |
1719 | + statistics.onFrameBufferUse(null, true); | |
1720 | + | |
1721 | + context.boundFBO = 0; | |
1722 | + } | |
1723 | + | |
1724 | + /* | |
1725 | + // select back buffer | |
1726 | + if (context.boundDrawBuf != -1) { | |
1727 | + glDrawBuffer(initialDrawBuf); | |
1728 | + context.boundDrawBuf = -1; | |
1729 | + } | |
1730 | + if (context.boundReadBuf != -1) { | |
1731 | + glReadBuffer(initialReadBuf); | |
1732 | + context.boundReadBuf = -1; | |
1733 | + } | |
1734 | + */ | |
1735 | + | |
1736 | + lastFb = null; | |
1737 | + } else { | |
1738 | + if (fb.getNumColorBuffers() == 0 && fb.getDepthBuffer() == null) { | |
1739 | + throw new IllegalArgumentException("The framebuffer: " + fb | |
1740 | + + "\nDoesn't have any color/depth buffers"); | |
1741 | + } | |
1742 | + | |
1743 | + if (fb.isUpdateNeeded()) { | |
1744 | + updateFrameBuffer(fb); | |
1745 | + } | |
1746 | + | |
1747 | + if (context.boundFBO != fb.getId()) { | |
1748 | + GLES20.glBindFramebuffer(GLES20.GL_FRAMEBUFFER, fb.getId()); | |
1749 | +// RendererUtil.checkGLError(); | |
1750 | + | |
1751 | + statistics.onFrameBufferUse(fb, true); | |
1752 | + | |
1753 | + // update viewport to reflect framebuffer's resolution | |
1754 | + setViewPort(0, 0, fb.getWidth(), fb.getHeight()); | |
1755 | + | |
1756 | + context.boundFBO = fb.getId(); | |
1757 | + } else { | |
1758 | + statistics.onFrameBufferUse(fb, false); | |
1759 | + } | |
1760 | + if (fb.getNumColorBuffers() == 0) { | |
1761 | +// // make sure to select NONE as draw buf | |
1762 | +// // no color buffer attached. select NONE | |
1763 | + if (context.boundDrawBuf != -2) { | |
1764 | +// glDrawBuffer(GL_NONE); | |
1765 | + context.boundDrawBuf = -2; | |
1766 | + } | |
1767 | + if (context.boundReadBuf != -2) { | |
1768 | +// glReadBuffer(GL_NONE); | |
1769 | + context.boundReadBuf = -2; | |
1770 | + } | |
1771 | + } else { | |
1772 | + if (fb.getNumColorBuffers() > maxFBOAttachs) { | |
1773 | + throw new RendererException("Framebuffer has more color " | |
1774 | + + "attachments than are supported" | |
1775 | + + " by the video hardware!"); | |
1776 | + } | |
1777 | + if (fb.isMultiTarget()) { | |
1778 | + if (fb.getNumColorBuffers() > maxMRTFBOAttachs) { | |
1779 | + throw new RendererException("Framebuffer has more" | |
1780 | + + " multi targets than are supported" | |
1781 | + + " by the video hardware!"); | |
1782 | + } | |
1783 | + | |
1784 | + if (context.boundDrawBuf != 100 + fb.getNumColorBuffers()) { | |
1785 | + intBuf16.clear(); | |
1786 | + for (int i = 0; i < fb.getNumColorBuffers(); i++) { | |
1787 | + intBuf16.put(GLES20.GL_COLOR_ATTACHMENT0 + i); | |
1788 | + } | |
1789 | + | |
1790 | + intBuf16.flip(); | |
1791 | +// glDrawBuffers(intBuf16); | |
1792 | + context.boundDrawBuf = 100 + fb.getNumColorBuffers(); | |
1793 | + } | |
1794 | + } else { | |
1795 | + RenderBuffer rb = fb.getColorBuffer(fb.getTargetIndex()); | |
1796 | + // select this draw buffer | |
1797 | + if (context.boundDrawBuf != rb.getSlot()) { | |
1798 | + GLES20.glActiveTexture(convertAttachmentSlot(rb.getSlot())); | |
1799 | +// RendererUtil.checkGLError(); | |
1800 | + | |
1801 | + context.boundDrawBuf = rb.getSlot(); | |
1802 | + } | |
1803 | + } | |
1804 | + } | |
1805 | + | |
1806 | + assert fb.getId() >= 0; | |
1807 | + assert context.boundFBO == fb.getId(); | |
1808 | + | |
1809 | + lastFb = fb; | |
1810 | + | |
1811 | + checkFrameBufferStatus(fb); | |
1659 | 1812 | } |
1660 | 1813 | } |
1661 | - /* | |
1662 | - public void setFrameBuffer(FrameBuffer fb) { | |
1663 | - if (lastFb == fb) | |
1664 | - return; | |
1665 | - | |
1666 | - // generate mipmaps for last FB if needed | |
1667 | - if (lastFb != null){ | |
1668 | - for (int i = 0; i < lastFb.getNumColorBuffers(); i++){ | |
1669 | - RenderBuffer rb = lastFb.getColorBuffer(i); | |
1670 | - Texture tex = rb.getTexture(); | |
1671 | - if (tex != null | |
1672 | - && tex.getMinFilter().usesMipMapLevels()){ | |
1673 | - setTexture(0, rb.getTexture()); | |
1674 | - glGenerateMipmapEXT(convertTextureType(tex.getType())); | |
1675 | - } | |
1676 | - } | |
1677 | - } | |
1678 | - | |
1679 | - | |
1680 | - if (fb == null){ | |
1681 | - // unbind any fbos | |
1682 | - if (context.boundFBO != 0){ | |
1683 | - glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); | |
1684 | - statistics.onFrameBufferUse(null, true); | |
1685 | - | |
1686 | - context.boundFBO = 0; | |
1687 | - } | |
1688 | - // select back buffer | |
1689 | - if (context.boundDrawBuf != -1){ | |
1690 | - glDrawBuffer(initialDrawBuf); | |
1691 | - context.boundDrawBuf = -1; | |
1692 | - } | |
1693 | - if (context.boundReadBuf != -1){ | |
1694 | - glReadBuffer(initialReadBuf); | |
1695 | - context.boundReadBuf = -1; | |
1696 | - } | |
1697 | - | |
1698 | - lastFb = null; | |
1699 | - }else{ | |
1700 | - if (fb.isUpdateNeeded()) | |
1701 | - updateFrameBuffer(fb); | |
1702 | - | |
1703 | - if (context.boundFBO != fb.getId()){ | |
1704 | - glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fb.getId()); | |
1705 | - statistics.onFrameBufferUse(fb, true); | |
1706 | - | |
1707 | - // update viewport to reflect framebuffer's resolution | |
1708 | - setViewPort(0, 0, fb.getWidth(), fb.getHeight()); | |
1709 | - | |
1710 | - context.boundFBO = fb.getId(); | |
1711 | - }else{ | |
1712 | - statistics.onFrameBufferUse(fb, false); | |
1713 | - } | |
1714 | - if (fb.getNumColorBuffers() == 0){ | |
1715 | - // make sure to select NONE as draw buf | |
1716 | - // no color buffer attached. select NONE | |
1717 | - if (context.boundDrawBuf != -2){ | |
1718 | - glDrawBuffer(GL_NONE); | |
1719 | - context.boundDrawBuf = -2; | |
1720 | - } | |
1721 | - if (context.boundReadBuf != -2){ | |
1722 | - glReadBuffer(GL_NONE); | |
1723 | - context.boundReadBuf = -2; | |
1724 | - } | |
1725 | - }else{ | |
1726 | - if (fb.isMultiTarget()){ | |
1727 | - if (fb.getNumColorBuffers() > maxMRTFBOAttachs) | |
1728 | - throw new UnsupportedOperationException("Framebuffer has more" | |
1729 | - + " targets than are supported" | |
1730 | - + " on the system!"); | |
1731 | - | |
1732 | - if (context.boundDrawBuf != 100 + fb.getNumColorBuffers()){ | |
1733 | - intBuf16.clear(); | |
1734 | - for (int i = 0; i < fb.getNumColorBuffers(); i++) | |
1735 | - intBuf16.put( GL_COLOR_ATTACHMENT0_EXT + i ); | |
1736 | - | |
1737 | - intBuf16.flip(); | |
1738 | - glDrawBuffers(intBuf16); | |
1739 | - context.boundDrawBuf = 100 + fb.getNumColorBuffers(); | |
1740 | - } | |
1741 | - }else{ | |
1742 | - RenderBuffer rb = fb.getColorBuffer(fb.getTargetIndex()); | |
1743 | - // select this draw buffer | |
1744 | - if (context.boundDrawBuf != rb.getSlot()){ | |
1745 | - glDrawBuffer(GL_COLOR_ATTACHMENT0_EXT + rb.getSlot()); | |
1746 | - context.boundDrawBuf = rb.getSlot(); | |
1747 | - } | |
1748 | - } | |
1749 | - } | |
1750 | - | |
1751 | - assert fb.getId() >= 0; | |
1752 | - assert context.boundFBO == fb.getId(); | |
1753 | - lastFb = fb; | |
1754 | - } | |
1755 | - | |
1756 | - try { | |
1757 | - checkFrameBufferError(); | |
1758 | - } catch (IllegalStateException ex){ | |
1759 | - logger.log(Level.SEVERE, "Problem FBO:\n{0}", fb); | |
1760 | - throw ex; | |
1761 | - } | |
1762 | - } | |
1763 | - */ | |
1764 | 1814 | |
1815 | + /** | |
1816 | + * Reads the Color Buffer from OpenGL and stores into the ByteBuffer. | |
1817 | + * Make sure to call setViewPort with the appropriate viewport size before | |
1818 | + * calling readFrameBuffer. | |
1819 | + * @param fb FrameBuffer | |
1820 | + * @param byteBuf ByteBuffer to store the Color Buffer from OpenGL | |
1821 | + */ | |
1765 | 1822 | public void readFrameBuffer(FrameBuffer fb, ByteBuffer byteBuf) { |
1766 | - logger.warning("readFrameBuffer is not supported."); | |
1823 | + if (fb != null) { | |
1824 | + RenderBuffer rb = fb.getColorBuffer(); | |
1825 | + if (rb == null) { | |
1826 | + throw new IllegalArgumentException("Specified framebuffer" | |
1827 | + + " does not have a colorbuffer"); | |
1828 | + } | |
1829 | + | |
1830 | + setFrameBuffer(fb); | |
1831 | + } else { | |
1832 | + setFrameBuffer(null); | |
1833 | + } | |
1834 | + | |
1767 | 1835 | GLES20.glReadPixels(vpX, vpY, vpW, vpH, GLES20.GL_RGBA, GLES20.GL_UNSIGNED_BYTE, byteBuf); |
1836 | +// RendererUtil.checkGLError(); | |
1768 | 1837 | } |
1769 | - /* | |
1770 | - public void readFrameBuffer(FrameBuffer fb, ByteBuffer byteBuf){ | |
1771 | - if (fb != null){ | |
1772 | - RenderBuffer rb = fb.getColorBuffer(); | |
1773 | - if (rb == null) | |
1774 | - throw new IllegalArgumentException("Specified framebuffer" + | |
1775 | - " does not have a colorbuffer"); | |
1776 | - | |
1777 | - setFrameBuffer(fb); | |
1778 | - if (context.boundReadBuf != rb.getSlot()){ | |
1779 | - glReadBuffer(GL_COLOR_ATTACHMENT0_EXT + rb.getSlot()); | |
1780 | - context.boundReadBuf = rb.getSlot(); | |
1781 | - } | |
1782 | - }else{ | |
1783 | - setFrameBuffer(null); | |
1784 | - } | |
1785 | - | |
1786 | - glReadPixels(vpX, vpY, vpW, vpH, GL_RGBA GL_BGRA, GL_UNSIGNED_BYTE, byteBuf); | |
1787 | - } | |
1788 | - */ | |
1789 | 1838 | |
1790 | 1839 | private void deleteRenderBuffer(FrameBuffer fb, RenderBuffer rb) { |
1791 | - logger.warning("deleteRenderBuffer is not supported."); | |
1792 | 1840 | intBuf1.put(0, rb.getId()); |
1793 | 1841 | GLES20.glDeleteRenderbuffers(1, intBuf1); |
1842 | +// RendererUtil.checkGLError(); | |
1794 | 1843 | } |
1795 | - /* | |
1796 | - private void deleteRenderBuffer(FrameBuffer fb, RenderBuffer rb){ | |
1797 | - intBuf1.put(0, rb.getId()); | |
1798 | - glDeleteRenderbuffersEXT(intBuf1); | |
1799 | - } | |
1800 | - */ | |
1801 | 1844 | |
1802 | 1845 | public void deleteFrameBuffer(FrameBuffer fb) { |
1803 | - logger.warning("deleteFrameBuffer is not supported."); | |
1804 | 1846 | if (fb.getId() != -1) { |
1805 | 1847 | if (context.boundFBO == fb.getId()) { |
1806 | 1848 | GLES20.glBindFramebuffer(GLES20.GL_FRAMEBUFFER, 0); |
1849 | +// RendererUtil.checkGLError(); | |
1850 | + | |
1807 | 1851 | context.boundFBO = 0; |
1808 | 1852 | } |
1809 | 1853 |
@@ -1816,34 +1860,13 @@ public final class OGLESShaderRenderer implements Renderer { | ||
1816 | 1860 | |
1817 | 1861 | intBuf1.put(0, fb.getId()); |
1818 | 1862 | GLES20.glDeleteFramebuffers(1, intBuf1); |
1863 | +// RendererUtil.checkGLError(); | |
1864 | + | |
1819 | 1865 | fb.resetObject(); |
1820 | 1866 | |
1821 | 1867 | statistics.onDeleteFrameBuffer(); |
1822 | 1868 | } |
1823 | 1869 | } |
1824 | - /* | |
1825 | - public void deleteFrameBuffer(FrameBuffer fb) { | |
1826 | - if (fb.getId() != -1){ | |
1827 | - if (context.boundFBO == fb.getId()){ | |
1828 | - glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); | |
1829 | - context.boundFBO = 0; | |
1830 | - } | |
1831 | - | |
1832 | - if (fb.getDepthBuffer() != null){ | |
1833 | - deleteRenderBuffer(fb, fb.getDepthBuffer()); | |
1834 | - } | |
1835 | - if (fb.getColorBuffer() != null){ | |
1836 | - deleteRenderBuffer(fb, fb.getColorBuffer()); | |
1837 | - } | |
1838 | - | |
1839 | - intBuf1.put(0, fb.getId()); | |
1840 | - glDeleteFramebuffersEXT(intBuf1); | |
1841 | - fb.resetObject(); | |
1842 | - | |
1843 | - statistics.onDeleteFrameBuffer(); | |
1844 | - } | |
1845 | - } | |
1846 | - */ | |
1847 | 1870 | |
1848 | 1871 | /*********************************************************************\ |
1849 | 1872 | |* Textures *| |
@@ -14,6 +14,23 @@ import java.util.logging.Logger; | ||
14 | 14 | import javax.microedition.khronos.opengles.GL10; |
15 | 15 | |
16 | 16 | public class TextureUtil { |
17 | + public static boolean ENABLE_COMPRESSION = true; | |
18 | + private static boolean NPOT = false; | |
19 | + private static boolean ETC1support = false; | |
20 | + private static boolean DXT1 = false; | |
21 | + private static boolean DEPTH24_STENCIL8 = false; | |
22 | + private static boolean DEPTH_TEXTURE = true; | |
23 | + private static boolean RGBA8 = false; | |
24 | + | |
25 | + // Same constant used by both GL_ARM_rgba8 and GL_OES_rgb8_rgba8. | |
26 | + private static final int GL_RGBA8 = 0x8058; | |
27 | + | |
28 | + private static final int GL_DXT1 = 0x83F0; | |
29 | + private static final int GL_DXT1A = 0x83F1; | |
30 | + | |
31 | + private static final int GL_DEPTH_STENCIL_OES = 0x84F9; | |
32 | + private static final int GL_UNSIGNED_INT_24_8_OES = 0x84FA; | |
33 | + private static final int GL_DEPTH24_STENCIL8_OES = 0x88F0; | |
17 | 34 | |
18 | 35 | public static int convertTextureFormat(Format fmt){ |
19 | 36 | switch (fmt){ |
@@ -149,7 +166,149 @@ public class TextureUtil { | ||
149 | 166 | //bitmap.recycle(); |
150 | 167 | } |
151 | 168 | } |
169 | + private static void unsupportedFormat(Format fmt) { | |
170 | + throw new UnsupportedOperationException("The image format '" + fmt + "' is unsupported by the video hardware."); | |
171 | + } | |
172 | + | |
173 | + public static AndroidGLImageFormat getImageFormat(Format fmt) throws UnsupportedOperationException { | |
174 | + AndroidGLImageFormat imageFormat = new AndroidGLImageFormat(); | |
175 | + switch (fmt) { | |
176 | + case RGBA16: | |
177 | + case RGB16: | |
178 | + case RGB10: | |
179 | + case Luminance16: | |
180 | + case Luminance16Alpha16: | |
181 | + case Alpha16: | |
182 | + case Depth32: | |
183 | + case Depth32F: | |
184 | + throw new UnsupportedOperationException("The image format '" | |
185 | + + fmt + "' is not supported by OpenGL ES 2.0 specification."); | |
186 | + case Alpha8: | |
187 | + imageFormat.format = GLES20.GL_ALPHA; | |
188 | + imageFormat.dataType = GLES20.GL_UNSIGNED_BYTE; | |
189 | + if (RGBA8) { | |
190 | + imageFormat.renderBufferStorageFormat = GL_RGBA8; | |
191 | + } else { | |
192 | + // Highest precision alpha supported by vanilla OGLES2 | |
193 | + imageFormat.renderBufferStorageFormat = GLES20.GL_RGBA4; | |
194 | + } | |
195 | + break; | |
196 | + case Luminance8: | |
197 | + imageFormat.format = GLES20.GL_LUMINANCE; | |
198 | + imageFormat.dataType = GLES20.GL_UNSIGNED_BYTE; | |
199 | + if (RGBA8) { | |
200 | + imageFormat.renderBufferStorageFormat = GL_RGBA8; | |
201 | + } else { | |
202 | + // Highest precision luminance supported by vanilla OGLES2 | |
203 | + imageFormat.renderBufferStorageFormat = GLES20.GL_RGB565; | |
204 | + } | |
205 | + break; | |
206 | + case Luminance8Alpha8: | |
207 | + imageFormat.format = GLES20.GL_LUMINANCE_ALPHA; | |
208 | + imageFormat.dataType = GLES20.GL_UNSIGNED_BYTE; | |
209 | + if (RGBA8) { | |
210 | + imageFormat.renderBufferStorageFormat = GL_RGBA8; | |
211 | + } else { | |
212 | + imageFormat.renderBufferStorageFormat = GLES20.GL_RGBA4; | |
213 | + } | |
214 | + break; | |
215 | + case RGB565: | |
216 | + imageFormat.format = GLES20.GL_RGB; | |
217 | + imageFormat.dataType = GLES20.GL_UNSIGNED_SHORT_5_6_5; | |
218 | + imageFormat.renderBufferStorageFormat = GLES20.GL_RGB565; | |
219 | + break; | |
220 | + case ARGB4444: | |
221 | + imageFormat.format = GLES20.GL_RGBA4; | |
222 | + imageFormat.dataType = GLES20.GL_UNSIGNED_SHORT_4_4_4_4; | |
223 | + imageFormat.renderBufferStorageFormat = GLES20.GL_RGBA4; | |
224 | + break; | |
225 | + case RGB5A1: | |
226 | + imageFormat.format = GLES20.GL_RGBA; | |
227 | + imageFormat.dataType = GLES20.GL_UNSIGNED_SHORT_5_5_5_1; | |
228 | + imageFormat.renderBufferStorageFormat = GLES20.GL_RGB5_A1; | |
229 | + break; | |
230 | + case RGB8: | |
231 | + imageFormat.format = GLES20.GL_RGB; | |
232 | + imageFormat.dataType = GLES20.GL_UNSIGNED_BYTE; | |
233 | + if (RGBA8) { | |
234 | + imageFormat.renderBufferStorageFormat = GL_RGBA8; | |
235 | + } else { | |
236 | + // Fallback: Use RGB565 if RGBA8 is not available. | |
237 | + imageFormat.renderBufferStorageFormat = GLES20.GL_RGB565; | |
238 | + } | |
239 | + break; | |
240 | + case BGR8: | |
241 | + imageFormat.format = GLES20.GL_RGB; | |
242 | + imageFormat.dataType = GLES20.GL_UNSIGNED_BYTE; | |
243 | + if (RGBA8) { | |
244 | + imageFormat.renderBufferStorageFormat = GL_RGBA8; | |
245 | + } else { | |
246 | + imageFormat.renderBufferStorageFormat = GLES20.GL_RGB565; | |
247 | + } | |
248 | + break; | |
249 | + case RGBA8: | |
250 | + imageFormat.format = GLES20.GL_RGBA; | |
251 | + imageFormat.dataType = GLES20.GL_UNSIGNED_BYTE; | |
252 | + if (RGBA8) { | |
253 | + imageFormat.renderBufferStorageFormat = GL_RGBA8; | |
254 | + } else { | |
255 | + imageFormat.renderBufferStorageFormat = GLES20.GL_RGBA4; | |
256 | + } | |
257 | + break; | |
258 | + case Depth: | |
259 | + case Depth16: | |
260 | + if (!DEPTH_TEXTURE) { | |
261 | + unsupportedFormat(fmt); | |
262 | + } | |
263 | + imageFormat.format = GLES20.GL_DEPTH_COMPONENT; | |
264 | + imageFormat.dataType = GLES20.GL_UNSIGNED_SHORT; | |
265 | + imageFormat.renderBufferStorageFormat = GLES20.GL_DEPTH_COMPONENT16; | |
266 | + break; | |
267 | + case Depth24: | |
268 | +// case Depth24Stencil8: | |
269 | +// if (!DEPTH_TEXTURE) { | |
270 | +// unsupportedFormat(fmt); | |
271 | +// } | |
272 | +// if (DEPTH24_STENCIL8) { | |
273 | +// // NEW: True Depth24 + Stencil8 format. | |
274 | +// imageFormat.format = GL_DEPTH_STENCIL_OES; | |
275 | +// imageFormat.dataType = GL_UNSIGNED_INT_24_8_OES; | |
276 | +// imageFormat.renderBufferStorageFormat = GL_DEPTH24_STENCIL8_OES; | |
277 | +// } else { | |
278 | +// // Vanilla OGLES2, only Depth16 available. | |
279 | +// imageFormat.format = GLES20.GL_DEPTH_COMPONENT; | |
280 | +// imageFormat.dataType = GLES20.GL_UNSIGNED_SHORT; | |
281 | +// imageFormat.renderBufferStorageFormat = GLES20.GL_DEPTH_COMPONENT16; | |
282 | +// } | |
283 | +// break; | |
284 | + case DXT1: | |
285 | + if (!DXT1) { | |
286 | + unsupportedFormat(fmt); | |
287 | + } | |
288 | + imageFormat.format = GL_DXT1; | |
289 | + imageFormat.dataType = GLES20.GL_UNSIGNED_BYTE; | |
290 | + imageFormat.compress = true; | |
291 | + break; | |
292 | + case DXT1A: | |
293 | + if (!DXT1) { | |
294 | + unsupportedFormat(fmt); | |
295 | + } | |
296 | + imageFormat.format = GL_DXT1A; | |
297 | + imageFormat.dataType = GLES20.GL_UNSIGNED_BYTE; | |
298 | + imageFormat.compress = true; | |
299 | + break; | |
300 | + default: | |
301 | + throw new UnsupportedOperationException("Unrecognized format: " + fmt); | |
302 | + } | |
303 | + return imageFormat; | |
304 | + } | |
305 | + public static class AndroidGLImageFormat { | |
152 | 306 | |
307 | + boolean compress = false; | |
308 | + int format = -1; | |
309 | + int renderBufferStorageFormat = -1; | |
310 | + int dataType = -1; | |
311 | + } | |
153 | 312 | public static void uploadTexture( |
154 | 313 | Image img, |
155 | 314 | int target, |