159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta/*
259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * Copyright (c) 2009-2010 jMonkeyEngine
359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * All rights reserved.
459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta *
559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * Redistribution and use in source and binary forms, with or without
659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * modification, are permitted provided that the following conditions are
759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * met:
859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta *
959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * * Redistributions of source code must retain the above copyright
1059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta *   notice, this list of conditions and the following disclaimer.
1159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta *
1259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * * Redistributions in binary form must reproduce the above copyright
1359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta *   notice, this list of conditions and the following disclaimer in the
1459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta *   documentation and/or other materials provided with the distribution.
1559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta *
1659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * * Neither the name of 'jMonkeyEngine' nor the names of its contributors
1759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta *   may be used to endorse or promote products derived from this software
1859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta *   without specific prior written permission.
1959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta *
2059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
2159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
2259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
2359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
2459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
2559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
2659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
2759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
2859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
2959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
3059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
3159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta */
3259b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartapackage com.jme3.renderer.android;
3359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
3459b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport android.opengl.GLES10;
3559b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport android.opengl.GLES20;
3659b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport android.os.Build;
3759b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.asset.AndroidImageInfo;
3859b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.light.LightList;
3959b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.material.RenderState;
4059b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.math.*;
4159b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.renderer.*;
4259b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.scene.Mesh;
4359b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.scene.Mesh.Mode;
4459b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.scene.VertexBuffer;
4559b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.scene.VertexBuffer.Format;
4659b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.scene.VertexBuffer.Type;
4759b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.scene.VertexBuffer.Usage;
4859b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.shader.Attribute;
4959b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.shader.Shader;
5059b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.shader.Shader.ShaderSource;
5159b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.shader.Shader.ShaderType;
5259b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.shader.Uniform;
5359b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.texture.FrameBuffer;
5459b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.texture.FrameBuffer.RenderBuffer;
5559b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.texture.Image;
5659b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.texture.Texture;
5759b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.texture.Texture.WrapAxis;
5859b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.util.BufferUtils;
5959b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.util.ListMap;
6059b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.util.NativeObjectManager;
6159b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport java.nio.*;
6259b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport java.util.EnumSet;
6359b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport java.util.List;
6459b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport java.util.logging.Level;
6559b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport java.util.logging.Logger;
6659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
6759b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartapublic class OGLESShaderRenderer implements Renderer {
6859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
6959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    private static final Logger logger = Logger.getLogger(OGLESShaderRenderer.class.getName());
7059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    private static final boolean VALIDATE_SHADER = false;
7159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    private final ByteBuffer nameBuf = BufferUtils.createByteBuffer(250);
7259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    private final StringBuilder stringBuf = new StringBuilder(250);
7359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    private final IntBuffer intBuf1 = BufferUtils.createIntBuffer(1);
7459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    private final IntBuffer intBuf16 = BufferUtils.createIntBuffer(16);
7559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    private final RenderContext context = new RenderContext();
7659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    private final NativeObjectManager objManager = new NativeObjectManager();
7759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    private final EnumSet<Caps> caps = EnumSet.noneOf(Caps.class);
7859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    // current state
7959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    private Shader boundShader;
8059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    private int initialDrawBuf, initialReadBuf;
8159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    private int glslVer;
8259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    private int vertexTextureUnits;
8359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    private int fragTextureUnits;
8459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    private int vertexUniforms;
8559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    private int fragUniforms;
8659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    private int vertexAttribs;
8759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    private int maxFBOSamples;
8859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    private int maxFBOAttachs;
8959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    private int maxMRTFBOAttachs;
9059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    private int maxRBSize;
9159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    private int maxTexSize;
9259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    private int maxCubeTexSize;
9359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    private int maxVertCount;
9459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    private int maxTriCount;
9559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    private boolean tdc;
9659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    private FrameBuffer lastFb = null;
9759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    private final Statistics statistics = new Statistics();
9859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    private int vpX, vpY, vpW, vpH;
9959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    private int clipX, clipY, clipW, clipH;
10059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    //private final GL10 gl;
10159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    private boolean powerVr = false;
10259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    private boolean powerOf2 = false;
10359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    private boolean verboseLogging = false;
10459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    private boolean useVBO = false;
10559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    private boolean checkErrors = true;
10659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
10759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public OGLESShaderRenderer() {
10859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
10959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
11059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public void setUseVA(boolean value) {
11159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        logger.log(Level.INFO, "use_VBO [{0}] -> [{1}]", new Object[]{useVBO, !value});
11259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        useVBO = !value;
11359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
11459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
11559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public void setVerboseLogging(boolean value) {
11659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        logger.log(Level.INFO, "verboseLogging [{0}] -> [{1}]", new Object[]{verboseLogging, value});
11759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        verboseLogging = value;
11859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
11959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
12059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    protected void updateNameBuffer() {
12159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        int len = stringBuf.length();
12259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
12359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        nameBuf.position(0);
12459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        nameBuf.limit(len);
12559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        for (int i = 0; i < len; i++) {
12659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            nameBuf.put((byte) stringBuf.charAt(i));
12759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
12859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
12959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        nameBuf.rewind();
13059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
13159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
13259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    private void checkGLError() {
13359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (!checkErrors) return;
13459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        int error;
13559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        while ((error = GLES20.glGetError()) != GLES20.GL_NO_ERROR) {
13659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            throw new RendererException("OpenGL Error " + error);
13759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
13859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
13959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
14059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    private boolean log(String message) {
14159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        logger.info(message);
14259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        return true;
14359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
14459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
14559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public Statistics getStatistics() {
14659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        return statistics;
14759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
14859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
14959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public EnumSet<Caps> getCaps() {
15059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        return caps;
15159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
15259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
15359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public void initialize() {
15459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
15559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        logger.log(Level.INFO, "Vendor: {0}", GLES20.glGetString(GLES20.GL_VENDOR));
15659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        logger.log(Level.INFO, "Renderer: {0}", GLES20.glGetString(GLES20.GL_RENDERER));
15759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        logger.log(Level.INFO, "Version: {0}", GLES20.glGetString(GLES20.GL_VERSION));
15859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
15959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        powerVr = GLES20.glGetString(GLES20.GL_RENDERER).contains("PowerVR");
16059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
16159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        String versionStr = GLES20.glGetString(GLES20.GL_SHADING_LANGUAGE_VERSION);
16259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        logger.log(Level.INFO, "GLES20.Shading Language Version: {0}", versionStr);
16359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (versionStr == null || versionStr.equals("")) {
16459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            glslVer = -1;
16559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            throw new UnsupportedOperationException("GLSL and OpenGL2 is "
16659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                    + "required for the OpenGL ES "
16759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                    + "renderer!");
16859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
16959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
17059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        // Fix issue in TestRenderToMemory when GL_FRONT is the main
17159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        // buffer being used.
17259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
17359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta//        initialDrawBuf = GLES20.glGetIntegeri(GLES20.GL_DRAW_BUFFER);
17459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta//        initialReadBuf = GLES20.glGetIntegeri(GLES20.GL_READ_BUFFER);
17559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
17659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        String openGlEsStr = "OpenGL ES GLSL ES ";
17759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        int spaceIdx = versionStr.indexOf(" ", openGlEsStr.length());
17859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (spaceIdx >= 1) {
17959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            versionStr = versionStr.substring(openGlEsStr.length(), spaceIdx).trim();
18059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }else{
18159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            versionStr = versionStr.substring(openGlEsStr.length()).trim();
18259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
18359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
18459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        float version = Float.parseFloat(versionStr);
18559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        glslVer = (int) (version * 100);
18659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
18759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        switch (glslVer) {
18859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            // TODO: When new versions of OpenGL ES shader language come out,
18959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            // update this.
19059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            default:
19159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                caps.add(Caps.GLSL100);
19259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                break;
19359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
19459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
19559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (!caps.contains(Caps.GLSL100)) {
19659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            logger.info("Force-adding GLSL100 support, since OpenGL2 is supported.");
19759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            caps.add(Caps.GLSL100);
19859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
19959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
20059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        GLES20.glGetIntegerv(GLES20.GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS, intBuf16);
20159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        vertexTextureUnits = intBuf16.get(0);
20259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        logger.log(Level.INFO, "VTF Units: {0}", vertexTextureUnits);
20359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (vertexTextureUnits > 0) {
20459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            caps.add(Caps.VertexTextureFetch);
20559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
20659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
20759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        GLES20.glGetIntegerv(GLES20.GL_MAX_TEXTURE_IMAGE_UNITS, intBuf16);
20859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        fragTextureUnits = intBuf16.get(0);
20959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        logger.log(Level.INFO, "Texture Units: {0}", fragTextureUnits);
21059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        /*
21159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        GLES20.glGetIntegerv(GLES20.GL_MAX_VERTEX_UNIFORM_COMPONENTS, intBuf16);
21259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        vertexUniforms = intBuf16.get(0);
21359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        logger.log(Level.FINER, "Vertex Uniforms: {0}", vertexUniforms);
21459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
21559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        GLES20.glGetIntegerv(GLES20.GL_MAX_FRAGMENT_UNIFORM_COMPONENTS, intBuf16);
21659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        fragUniforms = intBuf16.get(0);
21759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        logger.log(Level.FINER, "Fragment Uniforms: {0}", fragUniforms);
21859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta         */
21959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
22059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        GLES20.glGetIntegerv(GLES20.GL_MAX_VERTEX_ATTRIBS, intBuf16);
22159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        vertexAttribs = intBuf16.get(0);
22259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        logger.log(Level.INFO, "Vertex Attributes: {0}", vertexAttribs);
22359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
22459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        /*
22559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        GLES20.glGetIntegerv(GLES20.GL_MAX_VARYING_FLOATS, intBuf16);
22659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        int varyingFloats = intBuf16.get(0);
22759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        logger.log(Level.FINER, "Varying Floats: {0}", varyingFloats);
22859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta         */
22959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
23059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        GLES20.glGetIntegerv(GLES20.GL_SUBPIXEL_BITS, intBuf16);
23159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        int subpixelBits = intBuf16.get(0);
23259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        logger.log(Level.INFO, "Subpixel Bits: {0}", subpixelBits);
23359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        /*
23459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        GLES20.glGetIntegerv(GLES20.GL_MAX_ELEMENTS_VERTICES, intBuf16);
23559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        maxVertCount = intBuf16.get(0);
23659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        logger.log(Level.FINER, "Preferred Batch Vertex Count: {0}", maxVertCount);
23759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
23859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        GLES20.glGetIntegerv(GLES20.GL_MAX_ELEMENTS_INDICES, intBuf16);
23959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        maxTriCount = intBuf16.get(0);
24059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        logger.log(Level.FINER, "Preferred Batch Index Count: {0}", maxTriCount);
24159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta         */
24259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        GLES20.glGetIntegerv(GLES20.GL_MAX_TEXTURE_SIZE, intBuf16);
24359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        maxTexSize = intBuf16.get(0);
24459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        logger.log(Level.INFO, "Maximum Texture Resolution: {0}", maxTexSize);
24559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
24659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        GLES20.glGetIntegerv(GLES20.GL_MAX_CUBE_MAP_TEXTURE_SIZE, intBuf16);
24759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        maxCubeTexSize = intBuf16.get(0);
24859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        logger.log(Level.INFO, "Maximum CubeMap Resolution: {0}", maxCubeTexSize);
24959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
25059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
25159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        /*
25259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (ctxCaps.GL_ARB_color_buffer_float){
25359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        // XXX: Require both 16 and 32 bit float support for FloatColorBuffer.
25459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (ctxCaps.GL_ARB_half_float_pixel){
25559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        caps.add(Caps.FloatColorBuffer);
25659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
25759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
25859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
25959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (ctxCaps.GL_ARB_depth_buffer_float){
26059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        caps.add(Caps.FloatDepthBuffer);
26159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
26259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
26359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (ctxCaps.GL_ARB_draw_instanced)
26459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        caps.add(Caps.MeshInstancing);
26559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
26659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (ctxCaps.GL_ARB_fragment_program)
26759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        caps.add(Caps.ARBprogram);
26859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
26959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (ctxCaps.GL_ARB_texture_buffer_object)
27059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        caps.add(Caps.TextureBuffer);
27159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
27259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (ctxCaps.GL_ARB_texture_float){
27359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (ctxCaps.GL_ARB_half_float_pixel){
27459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        caps.add(Caps.FloatTexture);
27559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
27659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
27759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
27859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (ctxCaps.GL_ARB_vertex_array_object)
27959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        caps.add(Caps.VertexBufferArray);
28059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
28159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        boolean latc = ctxCaps.GL_EXT_texture_compression_latc;
28259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        boolean atdc = ctxCaps.GL_ATI_texture_compression_3dc;
28359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (latc || atdc){
28459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        caps.add(Caps.TextureCompressionLATC);
28559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (atdc && !latc){
28659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        tdc = true;
28759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
28859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
28959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
29059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (ctxCaps.GL_EXT_packed_float){
29159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        caps.add(Caps.PackedFloatColorBuffer);
29259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (ctxCaps.GL_ARB_half_float_pixel){
29359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        // because textures are usually uploaded as RGB16F
29459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        // need half-float pixel
29559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        caps.add(Caps.PackedFloatTexture);
29659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
29759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
29859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
29959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (ctxCaps.GL_EXT_texture_array)
30059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        caps.add(Caps.TextureArray);
30159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
30259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (ctxCaps.GL_EXT_texture_shared_exponent)
30359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        caps.add(Caps.SharedExponentTexture);
30459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
30559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (ctxCaps.GL_EXT_framebuffer_object){
30659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        caps.add(Caps.FrameBuffer);
30759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
30859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        glGetInteger(GL_MAX_RENDERBUFFER_SIZE_EXT, intBuf16);
30959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        maxRBSize = intBuf16.get(0);
31059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        logger.log(Level.FINER, "FBO RB Max Size: {0}", maxRBSize);
31159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
31259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        glGetInteger(GL_MAX_COLOR_ATTACHMENTS_EXT, intBuf16);
31359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        maxFBOAttachs = intBuf16.get(0);
31459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        logger.log(Level.FINER, "FBO Max renderbuffers: {0}", maxFBOAttachs);
31559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
31659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (ctxCaps.GL_EXT_framebuffer_multisample){
31759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        caps.add(Caps.FrameBufferMultisample);
31859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
31959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        glGetInteger(GL_MAX_SAMPLES_EXT, intBuf16);
32059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        maxFBOSamples = intBuf16.get(0);
32159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        logger.log(Level.FINER, "FBO Max Samples: {0}", maxFBOSamples);
32259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
32359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
32459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (ctxCaps.GL_ARB_draw_buffers){
32559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        caps.add(Caps.FrameBufferMRT);
32659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        glGetInteger(ARBDrawBuffers.GL_MAX_DRAW_BUFFERS_ARB, intBuf16);
32759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        maxMRTFBOAttachs = intBuf16.get(0);
32859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        logger.log(Level.FINER, "FBO Max MRT renderbuffers: {0}", maxMRTFBOAttachs);
32959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
33059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
33159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
33259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (ctxCaps.GL_ARB_multisample){
33359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        glGetInteger(ARBMultisample.GL_SAMPLE_BUFFERS_ARB, intBuf16);
33459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        boolean available = intBuf16.get(0) != 0;
33559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        glGetInteger(ARBMultisample.GL_SAMPLES_ARB, intBuf16);
33659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        int samples = intBuf16.get(0);
33759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        logger.log(Level.FINER, "Samples: {0}", samples);
33859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        boolean enabled = glIsEnabled(ARBMultisample.GL_MULTISAMPLE_ARB);
33959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (samples > 0 && available && !enabled){
34059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        glEnable(ARBMultisample.GL_MULTISAMPLE_ARB);
34159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
34259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
34359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta         */
34459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
34559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        String extensions = GLES20.glGetString(GLES20.GL_EXTENSIONS);
34659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        logger.log(Level.INFO, "GL_EXTENSIONS: {0}", extensions);
34759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
34859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        GLES20.glGetIntegerv(GLES20.GL_COMPRESSED_TEXTURE_FORMATS, intBuf16);
34959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        for (int i = 0; i < intBuf16.limit(); i++) {
35059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            logger.log(Level.INFO, "Compressed Texture Formats: {0}", intBuf16.get(i));
35159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
35259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
35359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (extensions.contains("GL_OES_texture_npot")) {
35459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            powerOf2 = true;
35559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
35659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
35759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        applyRenderState(RenderState.DEFAULT);
358a6b44658eb1c55295f132a36233a11aa2bd8f9cfScott Barta        GLES20.glDisable(GLES20.GL_DITHER);
35959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
36059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        checkGLError();
36159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
36259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        useVBO = false;
36359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
36459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        // NOTE: SDK_INT is only available since 1.6,
36559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        // but for jME3 it doesn't matter since android versions 1.5 and below
36659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        // are not supported.
36759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (Build.VERSION.SDK_INT >= 9){
36859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            useVBO = true;
36959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
37059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
37159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        logger.log(Level.INFO, "Caps: {0}", caps);
37259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
37359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
37459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /**
37559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * <code>resetGLObjects</code> should be called when die GLView gets recreated to reset all GPU objects
37659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
37759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public void resetGLObjects() {
37859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        objManager.resetObjects();
37959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        statistics.clearMemory();
38059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        boundShader = null;
38159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        lastFb = null;
38259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        context.reset();
38359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
38459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
38559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public void cleanup() {
38659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        objManager.deleteAllObjects(this);
38759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        statistics.clearMemory();
38859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
38959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
39059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    private void checkCap(Caps cap) {
39159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (!caps.contains(cap)) {
39259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            throw new UnsupportedOperationException("Required capability missing: " + cap.name());
39359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
39459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
39559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
39659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /*********************************************************************\
39759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    |* Render State                                                      *|
39859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    \*********************************************************************/
39959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public void setDepthRange(float start, float end) {
40059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
40159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (verboseLogging) {
40259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            logger.log(Level.INFO, "GLES20.glDepthRangef({0}, {1})", new Object[]{start, end});
40359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
40459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        GLES20.glDepthRangef(start, end);
40559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        checkGLError();
40659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
40759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
40859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public void clearBuffers(boolean color, boolean depth, boolean stencil) {
40959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        int bits = 0;
41059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (color) {
41159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            bits = GLES20.GL_COLOR_BUFFER_BIT;
41259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
41359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (depth) {
41459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            bits |= GLES20.GL_DEPTH_BUFFER_BIT;
41559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
41659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (stencil) {
41759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            bits |= GLES20.GL_STENCIL_BUFFER_BIT;
41859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
41959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (bits != 0) {
42059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            if (verboseLogging) {
42159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                logger.log(Level.INFO, "GLES20.glClear(color={0}, depth={1}, stencil={2})", new Object[]{color, depth, stencil});
42259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            }
42359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            GLES20.glClear(bits);
42459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            checkGLError();
42559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
42659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
42759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
42859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public void setBackgroundColor(ColorRGBA color) {
42959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (verboseLogging) {
43059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            logger.log(Level.INFO, "GLES20.glClearColor({0}, {1}, {2}, {3})", new Object[]{color.r, color.g, color.b, color.a});
43159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
43259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        GLES20.glClearColor(color.r, color.g, color.b, color.a);
43359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        checkGLError();
43459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
43559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
43659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public void applyRenderState(RenderState state) {
43759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        /*
43859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (state.isWireframe() && !context.wireframe){
43959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        GLES20.glPolygonMode(GLES20.GL_FRONT_AND_BACK, GLES20.GL_LINE);
44059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        context.wireframe = true;
44159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }else if (!state.isWireframe() && context.wireframe){
44259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        GLES20.glPolygonMode(GLES20.GL_FRONT_AND_BACK, GLES20.GL_FILL);
44359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        context.wireframe = false;
44459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
44559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta         */
44659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (state.isDepthTest() && !context.depthTestEnabled) {
44759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            if (verboseLogging) {
44859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                logger.info("GLES20.glEnable(GLES20.GL_DEPTH_TEST)");
44959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            }
45059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            GLES20.glEnable(GLES20.GL_DEPTH_TEST);
45159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            checkGLError();
45259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            if (verboseLogging) {
45359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                logger.info("GLES20.glDepthFunc(GLES20.GL_LEQUAL)");
45459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            }
45559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            GLES20.glDepthFunc(GLES20.GL_LEQUAL);
45659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            checkGLError();
45759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            context.depthTestEnabled = true;
45859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        } else if (!state.isDepthTest() && context.depthTestEnabled) {
45959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            if (verboseLogging) {
46059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                logger.info("GLES20.glDisable(GLES20.GL_DEPTH_TEST)");
46159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            }
46259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            GLES20.glDisable(GLES20.GL_DEPTH_TEST);
46359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            checkGLError();
46459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            context.depthTestEnabled = false;
46559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
46659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (state.isAlphaTest() && !context.alphaTestEnabled) {
46759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta//            GLES20.glEnable(GLES20.GL_ALPHA_TEST);
46859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta//           GLES20.glAlphaFunc(GLES20.GL_GREATER, state.getAlphaFallOff());
46959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            context.alphaTestEnabled = true;
47059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        } else if (!state.isAlphaTest() && context.alphaTestEnabled) {
47159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta//            GLES20.glDisable(GLES20.GL_ALPHA_TEST);
47259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            context.alphaTestEnabled = false;
47359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
47459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (state.isDepthWrite() && !context.depthWriteEnabled) {
47559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            if (verboseLogging) {
47659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                logger.info("GLES20.glDepthMask(true)");
47759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            }
47859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            GLES20.glDepthMask(true);
47959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            checkGLError();
48059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            context.depthWriteEnabled = true;
48159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        } else if (!state.isDepthWrite() && context.depthWriteEnabled) {
48259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            if (verboseLogging) {
48359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                logger.info("GLES20.glDepthMask(false)");
48459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            }
48559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            GLES20.glDepthMask(false);
48659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            checkGLError();
48759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            context.depthWriteEnabled = false;
48859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
48959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (state.isColorWrite() && !context.colorWriteEnabled) {
49059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            if (verboseLogging) {
49159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                logger.info("GLES20.glColorMask(true, true, true, true)");
49259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            }
49359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            GLES20.glColorMask(true, true, true, true);
49459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            checkGLError();
49559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            context.colorWriteEnabled = true;
49659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        } else if (!state.isColorWrite() && context.colorWriteEnabled) {
49759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            if (verboseLogging) {
49859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                logger.info("GLES20.glColorMask(false, false, false, false)");
49959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            }
50059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            GLES20.glColorMask(false, false, false, false);
50159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            checkGLError();
50259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            context.colorWriteEnabled = false;
50359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
50459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (state.isPointSprite() && !context.pointSprite) {
50559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta//            GLES20.glEnable(GLES20.GL_POINT_SPRITE);
50659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta//            GLES20.glTexEnvi(GLES20.GL_POINT_SPRITE, GLES20.GL_COORD_REPLACE, GLES20.GL_TRUE);
50759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta//            GLES20.glEnable(GLES20.GL_VERTEX_PROGRAM_POINT_SIZE);
50859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta//            GLES20.glPointParameterf(GLES20.GL_POINT_SIZE_MIN, 1.0f);
50959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        } else if (!state.isPointSprite() && context.pointSprite) {
51059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta//            GLES20.glDisable(GLES20.GL_POINT_SPRITE);
51159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
51259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
51359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (state.isPolyOffset()) {
51459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            if (!context.polyOffsetEnabled) {
51559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                if (verboseLogging) {
51659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                    logger.info("GLES20.glEnable(GLES20.GL_POLYGON_OFFSET_FILL)");
51759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                }
51859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                GLES20.glEnable(GLES20.GL_POLYGON_OFFSET_FILL);
51959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                checkGLError();
52059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                if (verboseLogging) {
52159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                    logger.log(Level.INFO, "GLES20.glPolygonOffset({0}, {1})", new Object[]{state.getPolyOffsetFactor(), state.getPolyOffsetUnits()});
52259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                }
52359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                GLES20.glPolygonOffset(state.getPolyOffsetFactor(),
52459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                        state.getPolyOffsetUnits());
52559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                checkGLError();
52659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                context.polyOffsetEnabled = true;
52759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                context.polyOffsetFactor = state.getPolyOffsetFactor();
52859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                context.polyOffsetUnits = state.getPolyOffsetUnits();
52959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            } else {
53059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                if (state.getPolyOffsetFactor() != context.polyOffsetFactor
53159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                        || state.getPolyOffsetUnits() != context.polyOffsetUnits) {
53259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                    if (verboseLogging) {
53359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                        logger.log(Level.INFO, "GLES20.glPolygonOffset({0}, {1})", new Object[]{state.getPolyOffsetFactor(), state.getPolyOffsetUnits()});
53459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                    }
53559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                    GLES20.glPolygonOffset(state.getPolyOffsetFactor(),
53659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                            state.getPolyOffsetUnits());
53759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                    checkGLError();
53859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                    context.polyOffsetFactor = state.getPolyOffsetFactor();
53959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                    context.polyOffsetUnits = state.getPolyOffsetUnits();
54059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                }
54159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            }
54259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        } else {
54359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            if (context.polyOffsetEnabled) {
54459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                if (verboseLogging) {
54559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                    logger.info("GLES20.glDisable(GLES20.GL_POLYGON_OFFSET_FILL)");
54659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                }
54759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                GLES20.glDisable(GLES20.GL_POLYGON_OFFSET_FILL);
54859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                checkGLError();
54959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                context.polyOffsetEnabled = false;
55059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                context.polyOffsetFactor = 0;
55159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                context.polyOffsetUnits = 0;
55259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            }
55359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
55459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (state.getFaceCullMode() != context.cullMode) {
55559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            if (state.getFaceCullMode() == RenderState.FaceCullMode.Off) {
55659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                if (verboseLogging) {
55759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                    logger.info("GLES20.glDisable(GLES20.GL_CULL_FACE)");
55859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                }
55959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                GLES20.glDisable(GLES20.GL_CULL_FACE);
56059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            } else {
56159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                if (verboseLogging) {
56259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                    logger.info("GLES20.glEnable(GLES20.GL_CULL_FACE)");
56359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                }
56459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                GLES20.glEnable(GLES20.GL_CULL_FACE);
56559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            }
56659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
56759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            checkGLError();
56859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
56959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            switch (state.getFaceCullMode()) {
57059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                case Off:
57159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                    break;
57259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                case Back:
57359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                    if (verboseLogging) {
57459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                        logger.info("GLES20.glCullFace(GLES20.GL_BACK)");
57559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                    }
57659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                    GLES20.glCullFace(GLES20.GL_BACK);
57759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                    break;
57859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                case Front:
57959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                    if (verboseLogging) {
58059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                        logger.info("GLES20.glCullFace(GLES20.GL_FRONT)");
58159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                    }
58259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                    GLES20.glCullFace(GLES20.GL_FRONT);
58359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                    break;
58459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                case FrontAndBack:
58559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                    if (verboseLogging) {
58659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                        logger.info("GLES20.glCullFace(GLES20.GL_FRONT_AND_BACK)");
58759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                    }
58859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                    GLES20.glCullFace(GLES20.GL_FRONT_AND_BACK);
58959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                    break;
59059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                default:
59159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                    throw new UnsupportedOperationException("Unrecognized face cull mode: "
59259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                            + state.getFaceCullMode());
59359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            }
59459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
59559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            checkGLError();
59659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
59759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            context.cullMode = state.getFaceCullMode();
59859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
59959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
60059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (state.getBlendMode() != context.blendMode) {
60159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            if (state.getBlendMode() == RenderState.BlendMode.Off) {
60259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                if (verboseLogging) {
60359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                    logger.info("GLES20.glDisable(GLES20.GL_BLEND)");
60459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                }
60559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                GLES20.glDisable(GLES20.GL_BLEND);
60659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            } else {
60759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                if (verboseLogging) {
60859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                    logger.info("GLES20.glEnable(GLES20.GL_BLEND)");
60959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                }
61059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                GLES20.glEnable(GLES20.GL_BLEND);
61159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                switch (state.getBlendMode()) {
61259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                    case Off:
61359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                        break;
61459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                    case Additive:
61559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                        if (verboseLogging) {
61659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                            logger.info("GLES20.glBlendFunc(GLES20.GL_ONE, GLES20.GL_ONE)");
61759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                        }
61859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                        GLES20.glBlendFunc(GLES20.GL_ONE, GLES20.GL_ONE);
61959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                        break;
62059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                    case AlphaAdditive:
62159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                        if (verboseLogging) {
62259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                            logger.info("GLES20.glBlendFunc(GLES20.GL_SRC_ALPHA, GLES20.GL_ONE)");
62359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                        }
62459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                        GLES20.glBlendFunc(GLES20.GL_SRC_ALPHA, GLES20.GL_ONE);
62559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                        break;
62659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                    case Color:
62759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                        if (verboseLogging) {
62859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                            logger.info("GLES20.glBlendFunc(GLES20.GL_ONE, GLES20.GL_ONE_MINUS_SRC_COLOR)");
62959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                        }
63059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                        GLES20.glBlendFunc(GLES20.GL_ONE, GLES20.GL_ONE_MINUS_SRC_COLOR);
63159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                        break;
63259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                    case Alpha:
63359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                        if (verboseLogging) {
63459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                            logger.info("GLES20.glBlendFunc(GLES20.GL_SRC_ALPHA, GLES20.GL_ONE_MINUS_SRC_ALPHA)");
63559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                        }
63659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                        GLES20.glBlendFunc(GLES20.GL_SRC_ALPHA, GLES20.GL_ONE_MINUS_SRC_ALPHA);
63759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                        break;
63859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                    case PremultAlpha:
63959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                        if (verboseLogging) {
64059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                            logger.info("GLES20.glBlendFunc(GLES20.GL_ONE, GLES20.GL_ONE_MINUS_SRC_ALPHA)");
64159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                        }
64259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                        GLES20.glBlendFunc(GLES20.GL_ONE, GLES20.GL_ONE_MINUS_SRC_ALPHA);
64359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                        break;
64459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                    case Modulate:
64559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                        if (verboseLogging) {
64659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                            logger.info("GLES20.glBlendFunc(GLES20.GL_DST_COLOR, GLES20.GL_ZERO)");
64759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                        }
64859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                        GLES20.glBlendFunc(GLES20.GL_DST_COLOR, GLES20.GL_ZERO);
64959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                        break;
65059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                    case ModulateX2:
65159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                        if (verboseLogging) {
65259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                            logger.info("GLES20.glBlendFunc(GLES20.GL_DST_COLOR, GLES20.GL_SRC_COLOR)");
65359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                        }
65459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                        GLES20.glBlendFunc(GLES20.GL_DST_COLOR, GLES20.GL_SRC_COLOR);
65559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                        break;
65659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                    default:
65759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                        throw new UnsupportedOperationException("Unrecognized blend mode: "
65859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                                + state.getBlendMode());
65959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                }
66059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            }
66159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
66259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            checkGLError();
66359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
66459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            context.blendMode = state.getBlendMode();
66559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
66659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
66759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
66859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /*********************************************************************\
66959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    |* Camera and World transforms                                       *|
67059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    \*********************************************************************/
67159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public void setViewPort(int x, int y, int w, int h) {
67259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (x != vpX || vpY != y || vpW != w || vpH != h) {
67359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            if (verboseLogging) {
67459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                logger.log(Level.INFO, "GLES20.glViewport({0}, {1}, {2}, {3})", new Object[]{x, y, w, h});
67559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            }
67659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            GLES20.glViewport(x, y, w, h);
67759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            checkGLError();
67859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            vpX = x;
67959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            vpY = y;
68059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            vpW = w;
68159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            vpH = h;
68259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
68359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
68459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
68559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public void setClipRect(int x, int y, int width, int height) {
68659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (!context.clipRectEnabled) {
68759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            if (verboseLogging) {
68859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                logger.info("GLES20.glEnable(GLES20.GL_SCISSOR_TEST)");
68959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            }
69059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            GLES20.glEnable(GLES20.GL_SCISSOR_TEST);
69159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            checkGLError();
69259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            context.clipRectEnabled = true;
69359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
69459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (clipX != x || clipY != y || clipW != width || clipH != height) {
69559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            if (verboseLogging) {
69659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                logger.log(Level.INFO, "GLES20.glScissor({0}, {1}, {2}, {3})", new Object[]{x, y, width, height});
69759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            }
69859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            GLES20.glScissor(x, y, width, height);
69959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            clipX = x;
70059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            clipY = y;
70159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            clipW = width;
70259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            clipH = height;
70359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            checkGLError();
70459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
70559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
70659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
70759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public void clearClipRect() {
70859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (context.clipRectEnabled) {
70959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            if (verboseLogging) {
71059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                logger.info("GLES20.glDisable(GLES20.GL_SCISSOR_TEST)");
71159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            }
71259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            GLES20.glDisable(GLES20.GL_SCISSOR_TEST);
71359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            checkGLError();
71459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            context.clipRectEnabled = false;
71559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
71659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            clipX = 0;
71759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            clipY = 0;
71859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            clipW = 0;
71959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            clipH = 0;
72059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
72159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
72259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
72359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public void onFrame() {
72459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (!checkErrors){
72559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            int error = GLES20.glGetError();
72659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            if (error != GLES20.GL_NO_ERROR){
72759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                throw new RendererException("OpenGL Error " + error + ". Enable error checking for more info.");
72859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            }
72959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
73059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        objManager.deleteUnused(this);
73159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta//      statistics.clearFrame();
73259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
73359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
73459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public void setWorldMatrix(Matrix4f worldMatrix) {
73559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
73659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
73759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public void setViewProjectionMatrices(Matrix4f viewMatrix, Matrix4f projMatrix) {
73859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
73959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
74059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /*********************************************************************\
74159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    |* Shaders                                                           *|
74259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    \*********************************************************************/
74359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    protected void updateUniformLocation(Shader shader, Uniform uniform) {
74459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        stringBuf.setLength(0);
74559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        stringBuf.append(uniform.getName()).append('\0');
74659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        updateNameBuffer();
74759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (verboseLogging) {
74859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            logger.log(Level.INFO, "GLES20.glGetUniformLocation({0}, {1})", new Object[]{shader.getId(), uniform.getName()});
74959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
75059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        int loc = GLES20.glGetUniformLocation(shader.getId(), uniform.getName());
75159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        checkGLError();
75259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (loc < 0) {
75359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            uniform.setLocation(-1);
75459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            // uniform is not declared in shader
75559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            if (verboseLogging) {
75659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                logger.log(Level.WARNING, "Uniform [{0}] is not declared in shader.", uniform.getName());
75759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            }
75859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        } else {
75959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            uniform.setLocation(loc);
76059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
76159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
76259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
76359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    protected void updateUniform(Shader shader, Uniform uniform) {
76459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        int shaderId = shader.getId();
76559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
76659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        assert uniform.getName() != null;
76759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        assert shader.getId() > 0;
76859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
76959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (context.boundShaderProgram != shaderId) {
77059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            if (verboseLogging) {
77159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                logger.log(Level.INFO, "GLES20.glUseProgram({0})", shaderId);
77259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            }
77359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            GLES20.glUseProgram(shaderId);
77459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            checkGLError();
77559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            statistics.onShaderUse(shader, true);
77659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            boundShader = shader;
77759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            context.boundShaderProgram = shaderId;
77859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        } else {
77959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            statistics.onShaderUse(shader, false);
78059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
78159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
78259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        int loc = uniform.getLocation();
78359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (loc == -1) {
78459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            if (verboseLogging) {
78559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                logger.log(Level.WARNING, "no location for uniform [{0}]", uniform.getName());
78659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            }
78759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            return;
78859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
78959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
79059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (loc == -2) {
79159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            // get uniform location
79259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            updateUniformLocation(shader, uniform);
79359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            if (uniform.getLocation() == -1) {
79459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                // not declared, ignore
79559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
79659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                if (verboseLogging) {
79759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                    logger.log(Level.WARNING, "not declared uniform: [{0}]", uniform.getName());
79859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                }
79959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
80059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                uniform.clearUpdateNeeded();
80159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                return;
80259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            }
80359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            loc = uniform.getLocation();
80459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
80559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
80659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (uniform.getVarType() == null) {
80759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            logger.warning("value is not set yet.");
80859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            return; // value not set yet..
80959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
81059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
81159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        statistics.onUniformSet();
81259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
81359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        uniform.clearUpdateNeeded();
81459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        FloatBuffer fb;
81559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        switch (uniform.getVarType()) {
81659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            case Float:
81759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                if (verboseLogging) {
81859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                    logger.info("GLES20.glUniform1f set Float. " + uniform.getName());
81959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                }
82059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                Float f = (Float) uniform.getValue();
82159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                GLES20.glUniform1f(loc, f.floatValue());
82259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                break;
82359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            case Vector2:
82459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                if (verboseLogging) {
82559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                    logger.info("GLES20.glUniform2f set Vector2. " + uniform.getName());
82659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                }
82759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                Vector2f v2 = (Vector2f) uniform.getValue();
82859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                GLES20.glUniform2f(loc, v2.getX(), v2.getY());
82959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                break;
83059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            case Vector3:
83159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                if (verboseLogging) {
83259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                    logger.info("GLES20.glUniform3f set Vector3. " + uniform.getName());
83359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                }
83459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                Vector3f v3 = (Vector3f) uniform.getValue();
83559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                GLES20.glUniform3f(loc, v3.getX(), v3.getY(), v3.getZ());
83659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                break;
83759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            case Vector4:
83859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                if (verboseLogging) {
83959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                    logger.info("GLES20.glUniform4f set Vector4." + uniform.getName());
84059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                }
84159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                Object val = uniform.getValue();
84259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                if (val instanceof ColorRGBA) {
84359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                    ColorRGBA c = (ColorRGBA) val;
84459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                    GLES20.glUniform4f(loc, c.r, c.g, c.b, c.a);
84559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                } else {
84659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                    Quaternion c = (Quaternion) uniform.getValue();
84759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                    GLES20.glUniform4f(loc, c.getX(), c.getY(), c.getZ(), c.getW());
84859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                }
84959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                break;
85059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            case Boolean:
85159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                if (verboseLogging) {
85259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                    logger.info("GLES20.glUniform1i set Boolean." + uniform.getName());
85359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                }
85459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                Boolean b = (Boolean) uniform.getValue();
85559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                GLES20.glUniform1i(loc, b.booleanValue() ? GLES20.GL_TRUE : GLES20.GL_FALSE);
85659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                break;
85759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            case Matrix3:
85859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                if (verboseLogging) {
85959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                    logger.info("GLES20.glUniformMatrix3fv set Matrix3." + uniform.getName());
86059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                }
86159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                fb = (FloatBuffer) uniform.getValue();
86259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                assert fb.remaining() == 9;
86359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                GLES20.glUniformMatrix3fv(loc, 1, false, fb);
86459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                break;
86559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            case Matrix4:
86659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                if (verboseLogging) {
86759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                    logger.info("GLES20.glUniformMatrix4fv set Matrix4." + uniform.getName());
86859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                }
86959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                fb = (FloatBuffer) uniform.getValue();
87059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                assert fb.remaining() == 16;
87159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                GLES20.glUniformMatrix4fv(loc, 1, false, fb);
87259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                break;
87359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            case FloatArray:
87459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                if (verboseLogging) {
87559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                    logger.info("GLES20.glUniform1fv set FloatArray." + uniform.getName());
87659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                }
87759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                fb = (FloatBuffer) uniform.getValue();
87859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                GLES20.glUniform1fv(loc, fb.capacity(), fb);
87959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                break;
88059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            case Vector2Array:
88159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                if (verboseLogging) {
88259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                    logger.info("GLES20.glUniform2fv set Vector2Array." + uniform.getName());
88359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                }
88459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                fb = (FloatBuffer) uniform.getValue();
88559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                GLES20.glUniform2fv(loc, fb.capacity() / 2, fb);
88659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                break;
88759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            case Vector3Array:
88859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                if (verboseLogging) {
88959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                    logger.info("GLES20.glUniform3fv set Vector3Array." + uniform.getName());
89059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                }
89159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                fb = (FloatBuffer) uniform.getValue();
89259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                GLES20.glUniform3fv(loc, fb.capacity() / 3, fb);
89359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                break;
89459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            case Vector4Array:
89559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                if (verboseLogging) {
89659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                    logger.info("GLES20.glUniform4fv set Vector4Array." + uniform.getName());
89759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                }
89859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                fb = (FloatBuffer) uniform.getValue();
89959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                GLES20.glUniform4fv(loc, fb.capacity() / 4, fb);
90059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                break;
90159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            case Matrix4Array:
90259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                if (verboseLogging) {
90359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                    logger.info("GLES20.glUniform4fv set Matrix4Array." + uniform.getName());
90459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                }
90559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                fb = (FloatBuffer) uniform.getValue();
90659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                GLES20.glUniformMatrix4fv(loc, fb.capacity() / 16, false, fb);
90759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                break;
90859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            case Int:
90959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                if (verboseLogging) {
91059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                    logger.info("GLES20.glUniform1i set Int." + uniform.getName());
91159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                }
91259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                Integer i = (Integer) uniform.getValue();
91359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                GLES20.glUniform1i(loc, i.intValue());
91459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                break;
91559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            default:
91659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                throw new UnsupportedOperationException("Unsupported uniform type: " + uniform.getVarType());
91759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
91859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        checkGLError();
91959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
92059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
92159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    protected void updateShaderUniforms(Shader shader) {
92259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        ListMap<String, Uniform> uniforms = shader.getUniformMap();
92359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta//        for (Uniform uniform : shader.getUniforms()){
92459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        for (int i = 0; i < uniforms.size(); i++) {
92559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            Uniform uniform = uniforms.getValue(i);
92659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            if (uniform.isUpdateNeeded()) {
92759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                updateUniform(shader, uniform);
92859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            }
92959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
93059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
93159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
93259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    protected void resetUniformLocations(Shader shader) {
93359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        ListMap<String, Uniform> uniforms = shader.getUniformMap();
93459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta//        for (Uniform uniform : shader.getUniforms()){
93559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        for (int i = 0; i < uniforms.size(); i++) {
93659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            Uniform uniform = uniforms.getValue(i);
93759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            uniform.reset(); // e.g check location again
93859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
93959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
94059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
94159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /*
94259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * (Non-javadoc)
94359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * Only used for fixed-function. Ignored.
94459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
94559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public void setLighting(LightList list) {
94659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
94759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
94859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public int convertShaderType(ShaderType type) {
94959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        switch (type) {
95059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            case Fragment:
95159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                return GLES20.GL_FRAGMENT_SHADER;
95259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            case Vertex:
95359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                return GLES20.GL_VERTEX_SHADER;
95459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta//            case Geometry:
95559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta//                return ARBGeometryShader4.GL_GEOMETRY_SHADER_ARB;
95659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            default:
95759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                throw new RuntimeException("Unrecognized shader type.");
95859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
95959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
96059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
96159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public void updateShaderSourceData(ShaderSource source, String language) {
96259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        int id = source.getId();
96359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (id == -1) {
96459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            // create id
96559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            if (verboseLogging) {
96659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                logger.info("GLES20.glCreateShader(" + source.getType() + ")");
96759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            }
96859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            id = GLES20.glCreateShader(convertShaderType(source.getType()));
96959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            checkGLError();
97059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            if (id <= 0) {
97159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                throw new RendererException("Invalid ID received when trying to create shader.");
97259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            }
97359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
97459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            source.setId(id);
97559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
97659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
97759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        // upload shader source
97859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        // merge the defines and source code
97959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        byte[] versionData = new byte[]{};//"#version 140\n".getBytes();
98059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta//        versionData = "#define INSTANCING 1\n".getBytes();
98159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        byte[] definesCodeData = source.getDefines().getBytes();
98259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        byte[] sourceCodeData = source.getSource().getBytes();
98359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        ByteBuffer codeBuf = BufferUtils.createByteBuffer(versionData.length
98459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                + definesCodeData.length
98559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                + sourceCodeData.length);
98659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        codeBuf.put(versionData);
98759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        codeBuf.put(definesCodeData);
98859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        codeBuf.put(sourceCodeData);
98959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        codeBuf.flip();
99059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
99159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (verboseLogging) {
99259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            logger.info("GLES20.glShaderSource(" + id + ")");
99359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
99459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
99559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (powerVr && source.getType() == ShaderType.Vertex) {
99659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            // XXX: This is to fix a bug in old PowerVR, remove
99759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            // when no longer applicable.
99859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            GLES20.glShaderSource(
99959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                    id, source.getDefines()
100059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                    + source.getSource());
100159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        } else {
100259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            GLES20.glShaderSource(
100359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                    id,
100459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                    "precision mediump float;\n"
100559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                    + source.getDefines()
100659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                    + source.getSource());
100759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
100859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
100959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        checkGLError();
101059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
101159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (verboseLogging) {
101259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            logger.info("GLES20.glCompileShader(" + id + ")");
101359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
101459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
101559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        GLES20.glCompileShader(id);
101659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
101759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        checkGLError();
101859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
101959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (verboseLogging) {
102059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            logger.info("GLES20.glGetShaderiv(" + id + ", GLES20.GL_COMPILE_STATUS)");
102159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
102259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
102359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        GLES20.glGetShaderiv(id, GLES20.GL_COMPILE_STATUS, intBuf1);
102459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
102559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        checkGLError();
102659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
102759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        boolean compiledOK = intBuf1.get(0) == GLES20.GL_TRUE;
102859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        String infoLog = null;
102959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
103059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (VALIDATE_SHADER || !compiledOK) {
103159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            // even if compile succeeded, check
103259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            // log for warnings
103359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            if (verboseLogging) {
103459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                logger.info("GLES20.glGetShaderiv()");
103559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            }
103659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            GLES20.glGetShaderiv(id, GLES20.GL_INFO_LOG_LENGTH, intBuf1);
103759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            checkGLError();
103859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            if (verboseLogging) {
103959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                logger.info("GLES20.glGetShaderInfoLog(" + id + ")");
104059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            }
104159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            infoLog = GLES20.glGetShaderInfoLog(id);
104259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            logger.severe("Errooooooooooot(" + id + ")");
104359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
104459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
104559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (compiledOK) {
104659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            if (infoLog != null) {
104759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                logger.log(Level.INFO, "compile success: " + source.getName() + ", " + infoLog);
104859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            } else {
104959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                logger.log(Level.FINE, "compile success: " + source.getName());
105059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            }
105159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        } else {
105259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta           logger.log(Level.WARNING, "Bad compile of:\n{0}{1}",
105359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                    new Object[]{source.getDefines(), source.getSource()});
105459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            if (infoLog != null) {
105559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                throw new RendererException("compile error in:" + source + " error:" + infoLog);
105659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            } else {
105759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                throw new RendererException("compile error in:" + source + " error: <not provided>");
105859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            }
105959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
106059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
106159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        source.clearUpdateNeeded();
106259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        // only usable if compiled
106359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        source.setUsable(compiledOK);
106459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (!compiledOK) {
106559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            // make sure to dispose id cause all program's
106659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            // shaders will be cleared later.
106759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            if (verboseLogging) {
106859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                logger.info("GLES20.glDeleteShader(" + id + ")");
106959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            }
107059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            GLES20.glDeleteShader(id);
107159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            checkGLError();
107259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        } else {
107359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            // register for cleanup since the ID is usable
107459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            objManager.registerForCleanup(source);
107559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
107659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
107759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
107859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public void updateShaderData(Shader shader) {
107959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        int id = shader.getId();
108059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        boolean needRegister = false;
108159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (id == -1) {
108259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            // create program
108359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
108459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            if (verboseLogging) {
108559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                logger.info("GLES20.glCreateProgram()");
108659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            }
108759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
108859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            id = GLES20.glCreateProgram();
108959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
109059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            if (id <= 0) {
109159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                throw new RendererException("Invalid ID received when trying to create shader program.");
109259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            }
109359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
109459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            shader.setId(id);
109559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            needRegister = true;
109659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
109759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
109859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        for (ShaderSource source : shader.getSources()) {
109959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            if (source.isUpdateNeeded()) {
110059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                updateShaderSourceData(source, shader.getLanguage());
110159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                // shader has been compiled here
110259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            }
110359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
110459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            if (!source.isUsable()) {
110559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                // it's useless.. just forget about everything..
110659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                shader.setUsable(false);
110759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                shader.clearUpdateNeeded();
110859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                return;
110959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            }
111059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            if (verboseLogging) {
111159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                logger.info("GLES20.glAttachShader(" + id + ", " + source.getId() + ")");
111259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            }
111359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
111459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            GLES20.glAttachShader(id, source.getId());
111559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
111659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
111759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        // link shaders to program
111859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (verboseLogging) {
111959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            logger.info("GLES20.glLinkProgram(" + id + ")");
112059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
112159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
112259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        GLES20.glLinkProgram(id);
112359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
112459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
112559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (verboseLogging) {
112659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            logger.info("GLES20.glGetProgramiv(" + id + ")");
112759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
112859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
112959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        GLES20.glGetProgramiv(id, GLES20.GL_LINK_STATUS, intBuf1);
113059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
113159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        boolean linkOK = intBuf1.get(0) == GLES20.GL_TRUE;
113259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        String infoLog = null;
113359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
113459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (VALIDATE_SHADER || !linkOK) {
113559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            if (verboseLogging) {
113659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                logger.info("GLES20.glGetProgramiv(" + id + ", GLES20.GL_INFO_LOG_LENGTH, buffer)");
113759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            }
113859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
113959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            GLES20.glGetProgramiv(id, GLES20.GL_INFO_LOG_LENGTH, intBuf1);
114059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
114159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            int length = intBuf1.get(0);
114259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            if (length > 3) {
114359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                // get infos
114459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
114559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                if (verboseLogging) {
114659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                    logger.info("GLES20.glGetProgramInfoLog(" + id + ")");
114759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                }
114859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
114959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                infoLog = GLES20.glGetProgramInfoLog(id);
115059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            }
115159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
115259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
115359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (linkOK) {
115459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            if (infoLog != null) {
115559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                logger.log(Level.INFO, "shader link success. \n{0}", infoLog);
115659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            } else {
115759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                logger.fine("shader link success");
115859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            }
115959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        } else {
116059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            if (infoLog != null) {
116159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                throw new RendererException("Shader link failure, shader:" + shader + " info:" + infoLog);
116259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            } else {
116359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                throw new RendererException("Shader link failure, shader:" + shader + " info: <not provided>");
116459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            }
116559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
116659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
116759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        shader.clearUpdateNeeded();
116859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (!linkOK) {
116959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            // failure.. forget about everything
117059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            shader.resetSources();
117159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            shader.setUsable(false);
117259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            deleteShader(shader);
117359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        } else {
117459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            shader.setUsable(true);
117559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            if (needRegister) {
117659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                objManager.registerForCleanup(shader);
117759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                statistics.onNewShader();
117859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            } else {
117959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                // OpenGL spec: uniform locations may change after re-link
118059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                resetUniformLocations(shader);
118159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            }
118259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
118359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
118459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
118559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public void setShader(Shader shader) {
118659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (verboseLogging) {
118759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            logger.info("setShader(" + shader + ")");
118859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
118959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
119059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (shader == null) {
119159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            if (context.boundShaderProgram > 0) {
119259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
119359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                if (verboseLogging) {
119459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                    logger.info("GLES20.glUseProgram(0)");
119559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                }
119659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
119759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                GLES20.glUseProgram(0);
119859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
119959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                statistics.onShaderUse(null, true);
120059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                context.boundShaderProgram = 0;
120159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                boundShader = null;
120259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            }
120359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        } else {
120459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            if (shader.isUpdateNeeded()) {
120559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                updateShaderData(shader);
120659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            }
120759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
120859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            // NOTE: might want to check if any of the
120959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            // sources need an update?
121059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
121159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            if (!shader.isUsable()) {
121259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                logger.warning("shader is not usable.");
121359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                return;
121459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            }
121559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
121659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            assert shader.getId() > 0;
121759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
121859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            updateShaderUniforms(shader);
121959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            if (context.boundShaderProgram != shader.getId()) {
122059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                if (VALIDATE_SHADER) {
122159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                    // check if shader can be used
122259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                    // with current state
122359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                    if (verboseLogging) {
122459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                        logger.info("GLES20.glValidateProgram(" + shader.getId() + ")");
122559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                    }
122659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
122759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                    GLES20.glValidateProgram(shader.getId());
122859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
122959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                    if (verboseLogging) {
123059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                        logger.info("GLES20.glGetProgramiv(" + shader.getId() + ", GLES20.GL_VALIDATE_STATUS, buffer)");
123159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                    }
123259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
123359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                    GLES20.glGetProgramiv(shader.getId(), GLES20.GL_VALIDATE_STATUS, intBuf1);
123459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
123559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                    boolean validateOK = intBuf1.get(0) == GLES20.GL_TRUE;
123659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
123759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                    if (validateOK) {
123859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                        logger.fine("shader validate success");
123959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                    } else {
124059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                        logger.warning("shader validate failure");
124159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                    }
124259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                }
124359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
124459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                if (verboseLogging) {
124559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                    logger.info("GLES20.glUseProgram(" + shader.getId() + ")");
124659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                }
124759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
124859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                GLES20.glUseProgram(shader.getId());
124959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
125059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                statistics.onShaderUse(shader, true);
125159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                context.boundShaderProgram = shader.getId();
125259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                boundShader = shader;
125359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            } else {
125459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                statistics.onShaderUse(shader, false);
125559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            }
125659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
125759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
125859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
125959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public void deleteShaderSource(ShaderSource source) {
126059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (source.getId() < 0) {
126159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            logger.warning("Shader source is not uploaded to GPU, cannot delete.");
126259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            return;
126359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
126459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        source.setUsable(false);
126559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        source.clearUpdateNeeded();
126659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
126759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (verboseLogging) {
126859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            logger.info("GLES20.glDeleteShader(" + source.getId() + ")");
126959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
127059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
127159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        GLES20.glDeleteShader(source.getId());
127259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        source.resetObject();
127359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
127459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
127559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public void deleteShader(Shader shader) {
127659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (shader.getId() == -1) {
127759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            logger.warning("Shader is not uploaded to GPU, cannot delete.");
127859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            return;
127959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
128059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        for (ShaderSource source : shader.getSources()) {
128159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            if (source.getId() != -1) {
128259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
128359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                if (verboseLogging) {
128459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                    logger.info("GLES20.glDetachShader(" + shader.getId() + ", " + source.getId() + ")");
128559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                }
128659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
128759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                GLES20.glDetachShader(shader.getId(), source.getId());
128859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                // the next part is done by the GLObjectManager automatically
128959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta//                glDeleteShader(source.getId());
129059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            }
129159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
129259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        // kill all references so sources can be collected
129359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        // if needed.
129459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        shader.resetSources();
129559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
129659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (verboseLogging) {
129759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            logger.info("GLES20.glDeleteProgram(" + shader.getId() + ")");
129859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
129959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
130059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        GLES20.glDeleteProgram(shader.getId());
130159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
130259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        statistics.onDeleteShader();
130359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
130459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
130559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /*********************************************************************\
130659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    |* Framebuffers                                                      *|
130759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    \*********************************************************************/
130859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public void copyFrameBuffer(FrameBuffer src, FrameBuffer dst) {
130959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        logger.warning("copyFrameBuffer is not supported.");
131059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
131159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
131259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public void copyFrameBuffer(FrameBuffer src, FrameBuffer dst, boolean copyDepth) {
131359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        logger.warning("copyFrameBuffer is not supported.");
131459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
131559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /*
131659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public void copyFrameBuffer(FrameBuffer src, FrameBuffer dst){
131759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    if (GLContext.getCapabilities().GL_EXT_framebuffer_blit){
131859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    int srcW = 0;
131959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    int srcH = 0;
132059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    int dstW = 0;
132159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    int dstH = 0;
132259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    int prevFBO = context.boundFBO;
132359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
132459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    if (src != null && src.isUpdateNeeded())
132559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    updateFrameBuffer(src);
132659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
132759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    if (dst != null && dst.isUpdateNeeded())
132859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    updateFrameBuffer(dst);
132959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
133059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    if (src == null){
133159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, 0);
133259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    //                srcW = viewWidth;
133359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    //                srcH = viewHeight;
133459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }else{
133559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, src.getId());
133659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    srcW = src.getWidth();
133759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    srcH = src.getHeight();
133859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
133959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    if (dst == null){
134059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, 0);
134159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    //                dstW = viewWidth;
134259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    //                dstH = viewHeight;
134359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }else{
134459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, dst.getId());
134559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    dstW = dst.getWidth();
134659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    dstH = dst.getHeight();
134759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
134859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    glBlitFramebufferEXT(0, 0, srcW, srcH,
134959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    0, 0, dstW, dstH,
135059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT,
135159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    GL_NEAREST);
135259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
135359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, prevFBO);
135459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    try {
135559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    checkFrameBufferError();
135659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    } catch (IllegalStateException ex){
135759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    logger.log(Level.SEVERE, "Source FBO:\n{0}", src);
135859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    logger.log(Level.SEVERE, "Dest FBO:\n{0}", dst);
135959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    throw ex;
136059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
136159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }else{
136259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    throw new UnsupportedOperationException("EXT_framebuffer_blit required.");
136359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    // TODO: support non-blit copies?
136459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
136559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
136659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
136759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
136859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    private void checkFrameBufferError() {
136959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        logger.warning("checkFrameBufferError is not supported.");
137059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
137159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /*
137259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    private void checkFrameBufferError() {
137359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    int status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
137459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    switch (status) {
137559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    case GL_FRAMEBUFFER_COMPLETE_EXT:
137659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    break;
137759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    case GL_FRAMEBUFFER_UNSUPPORTED_EXT:
137859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    //Choose different formats
137959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    throw new IllegalStateException("Framebuffer object format is " +
138059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    "unsupported by the video hardware.");
138159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT:
138259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    throw new IllegalStateException("Framebuffer has erronous attachment.");
138359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT:
138459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    throw new IllegalStateException("Framebuffer is missing required attachment.");
138559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    case GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT:
138659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    throw new IllegalStateException("Framebuffer attachments must have same dimensions.");
138759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    case GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT:
138859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    throw new IllegalStateException("Framebuffer attachments must have same formats.");
138959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    case GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT:
139059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    throw new IllegalStateException("Incomplete draw buffer.");
139159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    case GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT:
139259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    throw new IllegalStateException("Incomplete read buffer.");
139359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    case GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_EXT:
139459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    throw new IllegalStateException("Incomplete multisample buffer.");
139559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    default:
139659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    //Programming error; will fail on all hardware
139759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    throw new IllegalStateException("Some video driver error " +
139859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    "or programming error occured. " +
139959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    "Framebuffer object status is invalid. ");
140059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
140159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
140259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
140359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
140459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    private void updateRenderBuffer(FrameBuffer fb, RenderBuffer rb) {
140559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        logger.warning("updateRenderBuffer is not supported.");
140659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
140759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /*
140859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    private void updateRenderBuffer(FrameBuffer fb, RenderBuffer rb){
140959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    int id = rb.getId();
141059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    if (id == -1){
141159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    glGenRenderbuffersEXT(intBuf1);
141259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    id = intBuf1.get(0);
141359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    rb.setId(id);
141459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
141559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
141659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    if (context.boundRB != id){
141759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, id);
141859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    context.boundRB = id;
141959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
142059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
142159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    if (fb.getWidth() > maxRBSize || fb.getHeight() > maxRBSize)
142259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    throw new UnsupportedOperationException("Resolution "+fb.getWidth()+
142359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    ":"+fb.getHeight()+" is not supported.");
142459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
142559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    if (fb.getSamples() > 0 && GLContext.getCapabilities().GL_EXT_framebuffer_multisample){
142659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    int samples = fb.getSamples();
142759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    if (maxFBOSamples < samples){
142859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    samples = maxFBOSamples;
142959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
143059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER_EXT,
143159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    samples,
143259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    TextureUtil.convertTextureFormat(rb.getFormat()),
143359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    fb.getWidth(),
143459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    fb.getHeight());
143559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }else{
143659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT,
143759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    TextureUtil.convertTextureFormat(rb.getFormat()),
143859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    fb.getWidth(),
143959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    fb.getHeight());
144059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
144159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
144259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
144359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
144459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    private int convertAttachmentSlot(int attachmentSlot) {
144559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        logger.warning("convertAttachmentSlot is not supported.");
144659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        return -1;
144759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
144859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /*
144959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    private int convertAttachmentSlot(int attachmentSlot){
145059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    // can also add support for stencil here
145159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    if (attachmentSlot == -100){
145259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    return GL_DEPTH_ATTACHMENT_EXT;
145359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }else if (attachmentSlot < 0 || attachmentSlot >= 16){
145459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    throw new UnsupportedOperationException("Invalid FBO attachment slot: "+attachmentSlot);
145559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
145659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
145759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    return GL_COLOR_ATTACHMENT0_EXT + attachmentSlot;
145859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
145959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
146059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
146159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public void updateRenderTexture(FrameBuffer fb, RenderBuffer rb) {
146259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        logger.warning("updateRenderTexture is not supported.");
146359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
146459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /*
146559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public void updateRenderTexture(FrameBuffer fb, RenderBuffer rb){
146659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    Texture tex = rb.getTexture();
146759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    Image image = tex.getImage();
146859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    if (image.isUpdateNeeded())
146959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    updateTexImageData(image, tex.getType(), tex.getMinFilter().usesMipMapLevels());
147059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
147159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT,
147259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    convertAttachmentSlot(rb.getSlot()),
147359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    convertTextureType(tex.getType()),
147459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    image.getId(),
147559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    0);
147659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
147759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
147859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
147959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public void updateFrameBufferAttachment(FrameBuffer fb, RenderBuffer rb) {
148059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        logger.warning("updateFrameBufferAttachment is not supported.");
148159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
148259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /*
148359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public void updateFrameBufferAttachment(FrameBuffer fb, RenderBuffer rb){
148459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    boolean needAttach;
148559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    if (rb.getTexture() == null){
148659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    // if it hasn't been created yet, then attach is required.
148759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    needAttach = rb.getId() == -1;
148859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    updateRenderBuffer(fb, rb);
148959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }else{
149059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    needAttach = false;
149159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    updateRenderTexture(fb, rb);
149259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
149359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    if (needAttach){
149459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT,
149559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    convertAttachmentSlot(rb.getSlot()),
149659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    GL_RENDERBUFFER_EXT,
149759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    rb.getId());
149859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
149959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
150059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
150159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
150259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public void updateFrameBuffer(FrameBuffer fb) {
150359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        logger.warning("updateFrameBuffer is not supported.");
150459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
150559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /*
150659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public void updateFrameBuffer(FrameBuffer fb) {
150759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    int id = fb.getId();
150859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    if (id == -1){
150959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    // create FBO
151059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    glGenFramebuffersEXT(intBuf1);
151159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    id = intBuf1.get(0);
151259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    fb.setId(id);
151359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    objManager.registerForCleanup(fb);
151459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
151559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    statistics.onNewFrameBuffer();
151659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
151759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
151859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    if (context.boundFBO != id){
151959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, id);
152059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    // binding an FBO automatically sets draw buf to GL_COLOR_ATTACHMENT0
152159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    context.boundDrawBuf = 0;
152259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    context.boundFBO = id;
152359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
152459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
152559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    FrameBuffer.RenderBuffer depthBuf = fb.getDepthBuffer();
152659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    if (depthBuf != null){
152759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    updateFrameBufferAttachment(fb, depthBuf);
152859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
152959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
153059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    for (int i = 0; i < fb.getNumColorBuffers(); i++){
153159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    FrameBuffer.RenderBuffer colorBuf = fb.getColorBuffer(i);
153259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    updateFrameBufferAttachment(fb, colorBuf);
153359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
153459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
153559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    fb.clearUpdateNeeded();
153659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
153759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
153859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
153959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public void setMainFrameBufferOverride(FrameBuffer fb){
154059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
154159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
154259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public void setFrameBuffer(FrameBuffer fb) {
154359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (verboseLogging) {
154459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            logger.warning("setFrameBuffer is not supported.");
154559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
154659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
154759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /*
154859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public void setFrameBuffer(FrameBuffer fb) {
154959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    if (lastFb == fb)
155059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    return;
155159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
155259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    // generate mipmaps for last FB if needed
155359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    if (lastFb != null){
155459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    for (int i = 0; i < lastFb.getNumColorBuffers(); i++){
155559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    RenderBuffer rb = lastFb.getColorBuffer(i);
155659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    Texture tex = rb.getTexture();
155759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    if (tex != null
155859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    && tex.getMinFilter().usesMipMapLevels()){
155959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    setTexture(0, rb.getTexture());
156059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    glGenerateMipmapEXT(convertTextureType(tex.getType()));
156159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
156259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
156359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
156459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
156559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
156659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    if (fb == null){
156759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    // unbind any fbos
156859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    if (context.boundFBO != 0){
156959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
157059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    statistics.onFrameBufferUse(null, true);
157159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
157259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    context.boundFBO = 0;
157359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
157459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    // select back buffer
157559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    if (context.boundDrawBuf != -1){
157659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    glDrawBuffer(initialDrawBuf);
157759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    context.boundDrawBuf = -1;
157859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
157959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    if (context.boundReadBuf != -1){
158059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    glReadBuffer(initialReadBuf);
158159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    context.boundReadBuf = -1;
158259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
158359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
158459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    lastFb = null;
158559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }else{
158659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    if (fb.isUpdateNeeded())
158759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    updateFrameBuffer(fb);
158859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
158959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    if (context.boundFBO != fb.getId()){
159059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fb.getId());
159159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    statistics.onFrameBufferUse(fb, true);
159259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
159359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    // update viewport to reflect framebuffer's resolution
159459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    setViewPort(0, 0, fb.getWidth(), fb.getHeight());
159559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
159659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    context.boundFBO = fb.getId();
159759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }else{
159859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    statistics.onFrameBufferUse(fb, false);
159959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
160059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    if (fb.getNumColorBuffers() == 0){
160159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    // make sure to select NONE as draw buf
160259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    // no color buffer attached. select NONE
160359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    if (context.boundDrawBuf != -2){
160459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    glDrawBuffer(GL_NONE);
160559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    context.boundDrawBuf = -2;
160659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
160759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    if (context.boundReadBuf != -2){
160859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    glReadBuffer(GL_NONE);
160959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    context.boundReadBuf = -2;
161059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
161159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }else{
161259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    if (fb.isMultiTarget()){
161359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    if (fb.getNumColorBuffers() > maxMRTFBOAttachs)
161459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    throw new UnsupportedOperationException("Framebuffer has more"
161559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    + " targets than are supported"
161659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    + " on the system!");
161759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
161859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    if (context.boundDrawBuf != 100 + fb.getNumColorBuffers()){
161959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    intBuf16.clear();
162059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    for (int i = 0; i < fb.getNumColorBuffers(); i++)
162159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    intBuf16.put( GL_COLOR_ATTACHMENT0_EXT + i );
162259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
162359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    intBuf16.flip();
162459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    glDrawBuffers(intBuf16);
162559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    context.boundDrawBuf = 100 + fb.getNumColorBuffers();
162659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
162759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }else{
162859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    RenderBuffer rb = fb.getColorBuffer(fb.getTargetIndex());
162959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    // select this draw buffer
163059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    if (context.boundDrawBuf != rb.getSlot()){
163159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    glDrawBuffer(GL_COLOR_ATTACHMENT0_EXT + rb.getSlot());
163259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    context.boundDrawBuf = rb.getSlot();
163359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
163459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
163559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
163659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
163759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    assert fb.getId() >= 0;
163859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    assert context.boundFBO == fb.getId();
163959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    lastFb = fb;
164059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
164159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
164259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    try {
164359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    checkFrameBufferError();
164459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    } catch (IllegalStateException ex){
164559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    logger.log(Level.SEVERE, "Problem FBO:\n{0}", fb);
164659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    throw ex;
164759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
164859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
164959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
165059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
165159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public void readFrameBuffer(FrameBuffer fb, ByteBuffer byteBuf) {
165259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        logger.warning("readFrameBuffer is not supported.");
165359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
165459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /*
165559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public void readFrameBuffer(FrameBuffer fb, ByteBuffer byteBuf){
165659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    if (fb != null){
165759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    RenderBuffer rb = fb.getColorBuffer();
165859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    if (rb == null)
165959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    throw new IllegalArgumentException("Specified framebuffer" +
166059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    " does not have a colorbuffer");
166159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
166259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    setFrameBuffer(fb);
166359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    if (context.boundReadBuf != rb.getSlot()){
166459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    glReadBuffer(GL_COLOR_ATTACHMENT0_EXT + rb.getSlot());
166559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    context.boundReadBuf = rb.getSlot();
166659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
166759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }else{
166859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    setFrameBuffer(null);
166959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
167059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
167159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    glReadPixels(vpX, vpY, vpW, vpH, GL_RGBA GL_BGRA, GL_UNSIGNED_BYTE, byteBuf);
167259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
167359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
167459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
167559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    private void deleteRenderBuffer(FrameBuffer fb, RenderBuffer rb) {
167659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        logger.warning("deleteRenderBuffer is not supported.");
167759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
167859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /*
167959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    private void deleteRenderBuffer(FrameBuffer fb, RenderBuffer rb){
168059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    intBuf1.put(0, rb.getId());
168159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    glDeleteRenderbuffersEXT(intBuf1);
168259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
168359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
168459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
168559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public void deleteFrameBuffer(FrameBuffer fb) {
168659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        logger.warning("deleteFrameBuffer is not supported.");
168759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
168859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /*
168959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public void deleteFrameBuffer(FrameBuffer fb) {
169059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    if (fb.getId() != -1){
169159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    if (context.boundFBO == fb.getId()){
169259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
169359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    context.boundFBO = 0;
169459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
169559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
169659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    if (fb.getDepthBuffer() != null){
169759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    deleteRenderBuffer(fb, fb.getDepthBuffer());
169859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
169959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    if (fb.getColorBuffer() != null){
170059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    deleteRenderBuffer(fb, fb.getColorBuffer());
170159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
170259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
170359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    intBuf1.put(0, fb.getId());
170459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    glDeleteFramebuffersEXT(intBuf1);
170559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    fb.resetObject();
170659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
170759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    statistics.onDeleteFrameBuffer();
170859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
170959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
171059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
171159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
171259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /*********************************************************************\
171359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    |* Textures                                                          *|
171459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    \*********************************************************************/
171559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    private int convertTextureType(Texture.Type type) {
171659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        switch (type) {
171759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            case TwoDimensional:
171859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                return GLES20.GL_TEXTURE_2D;
171959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            //        case TwoDimensionalArray:
172059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            //            return EXTTextureArray.GL_TEXTURE_2D_ARRAY_EXT;
172159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta//            case ThreeDimensional:
172259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            //               return GLES20.GL_TEXTURE_3D;
172359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            case CubeMap:
172459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                return GLES20.GL_TEXTURE_CUBE_MAP;
172559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            default:
172659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                throw new UnsupportedOperationException("Unknown texture type: " + type);
172759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
172859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
172959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
173059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    private int convertMagFilter(Texture.MagFilter filter) {
173159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        switch (filter) {
173259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            case Bilinear:
173359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                return GLES20.GL_LINEAR;
173459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            case Nearest:
173559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                return GLES20.GL_NEAREST;
173659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            default:
173759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                throw new UnsupportedOperationException("Unknown mag filter: " + filter);
173859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
173959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
174059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
174159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    private int convertMinFilter(Texture.MinFilter filter) {
174259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        switch (filter) {
174359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            case Trilinear:
174459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                return GLES20.GL_LINEAR_MIPMAP_LINEAR;
174559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            case BilinearNearestMipMap:
174659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                return GLES20.GL_LINEAR_MIPMAP_NEAREST;
174759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            case NearestLinearMipMap:
174859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                return GLES20.GL_NEAREST_MIPMAP_LINEAR;
174959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            case NearestNearestMipMap:
175059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                return GLES20.GL_NEAREST_MIPMAP_NEAREST;
175159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            case BilinearNoMipMaps:
175259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                return GLES20.GL_LINEAR;
175359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            case NearestNoMipMaps:
175459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                return GLES20.GL_NEAREST;
175559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            default:
175659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                throw new UnsupportedOperationException("Unknown min filter: " + filter);
175759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
175859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
175959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
176059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    private int convertWrapMode(Texture.WrapMode mode) {
176159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        switch (mode) {
1762a6b44658eb1c55295f132a36233a11aa2bd8f9cfScott Barta            case BorderClamp:
1763a6b44658eb1c55295f132a36233a11aa2bd8f9cfScott Barta            case Clamp:
176459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            case EdgeClamp:
176559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                return GLES20.GL_CLAMP_TO_EDGE;
176659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            case Repeat:
176759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                return GLES20.GL_REPEAT;
176859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            case MirroredRepeat:
176959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                return GLES20.GL_MIRRORED_REPEAT;
177059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            default:
177159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                throw new UnsupportedOperationException("Unknown wrap mode: " + mode);
177259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
177359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
177459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
177559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /**
177659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * <code>setupTextureParams</code> sets the OpenGL context texture parameters
177759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param tex the Texture to set the texture parameters from
177859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
177959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    private void setupTextureParams(Texture tex) {
178059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        int target = convertTextureType(tex.getType());
178159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
178259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        // filter things
178359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        int minFilter = convertMinFilter(tex.getMinFilter());
178459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        int magFilter = convertMagFilter(tex.getMagFilter());
178559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
178659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (verboseLogging) {
178759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            logger.info("GLES20.glTexParameteri(" + target + ", GLES20.GL_TEXTURE_MIN_FILTER, " + minFilter + ")");
178859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
178959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
179059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        GLES20.glTexParameteri(target, GLES20.GL_TEXTURE_MIN_FILTER, minFilter);
179159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
179259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (verboseLogging) {
179359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            logger.info("GLES20.glTexParameteri(" + target + ", GLES20.GL_TEXTURE_MAG_FILTER, " + magFilter + ")");
179459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
179559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
179659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        GLES20.glTexParameteri(target, GLES20.GL_TEXTURE_MAG_FILTER, magFilter);
179759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
179859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        /*
179959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (tex.getAnisotropicFilter() > 1){
180059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
180159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (GLContext.getCapabilities().GL_EXT_texture_filter_anisotropic){
180259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        glTexParameterf(target,
180359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        EXTTextureFilterAnisotropic.GL_TEXTURE_MAX_ANISOTROPY_EXT,
180459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        tex.getAnisotropicFilter());
180559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
180659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
180759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
180859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta         */
180959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        // repeat modes
181059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
181159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        switch (tex.getType()) {
181259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            case ThreeDimensional:
181359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            case CubeMap: // cubemaps use 3D coords
181459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            // GL_TEXTURE_WRAP_R is not available in api 8
181559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            //GLES20.glTexParameteri(target, GLES20.GL_TEXTURE_WRAP_R, convertWrapMode(tex.getWrap(WrapAxis.R)));
181659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            case TwoDimensional:
181759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            case TwoDimensionalArray:
181859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
181959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                if (verboseLogging) {
182059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                    logger.info("GLES20.glTexParameteri(" + target + ", GLES20.GL_TEXTURE_WRAP_T, " + convertWrapMode(tex.getWrap(WrapAxis.T)));
182159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                }
182259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
182359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                GLES20.glTexParameteri(target, GLES20.GL_TEXTURE_WRAP_T, convertWrapMode(tex.getWrap(WrapAxis.T)));
182459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
182559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                // fall down here is intentional..
182659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta//          case OneDimensional:
182759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
182859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                if (verboseLogging) {
182959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                    logger.info("GLES20.glTexParameteri(" + target + ", GLES20.GL_TEXTURE_WRAP_S, " + convertWrapMode(tex.getWrap(WrapAxis.S)));
183059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                }
183159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
183259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                GLES20.glTexParameteri(target, GLES20.GL_TEXTURE_WRAP_S, convertWrapMode(tex.getWrap(WrapAxis.S)));
183359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                break;
183459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            default:
183559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                throw new UnsupportedOperationException("Unknown texture type: " + tex.getType());
183659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
183759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
183859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        // R to Texture compare mode
183959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta/*
184059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (tex.getShadowCompareMode() != Texture.ShadowCompareMode.Off){
184159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        GLES20.glTexParameteri(target, GLES20.GL_TEXTURE_COMPARE_MODE, GLES20.GL_COMPARE_R_TO_TEXTURE);
184259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        GLES20.glTexParameteri(target, GLES20.GL_DEPTH_TEXTURE_MODE, GLES20.GL_INTENSITY);
184359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (tex.getShadowCompareMode() == Texture.ShadowCompareMode.GreaterOrEqual){
184459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        GLES20.glTexParameteri(target, GLES20.GL_TEXTURE_COMPARE_FUNC, GLES20.GL_GEQUAL);
184559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }else{
184659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        GLES20.glTexParameteri(target, GLES20.GL_TEXTURE_COMPARE_FUNC, GLES20.GL_LEQUAL);
184759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
184859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
184959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta         */
185059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
185159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
185259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /**
185359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * <code>updateTexImageData</code> activates and binds the texture
185459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param img
185559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param type
185659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param mips
185759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
185859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public void updateTexImageData(Image img, Texture.Type type, boolean mips) {
185959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        int texId = img.getId();
186059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (texId == -1) {
186159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            // create texture
186259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            if (verboseLogging) {
186359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                logger.info("GLES20.glGenTexture(1, buffer)");
186459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            }
186559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
186659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            GLES20.glGenTextures(1, intBuf1);
186759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            texId = intBuf1.get(0);
186859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            img.setId(texId);
186959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            objManager.registerForCleanup(img);
187059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
187159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            statistics.onNewTexture();
187259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
187359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
187459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        // bind texture
187559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        int target = convertTextureType(type);
187659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (context.boundTextures[0] != img) {
187759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            if (context.boundTextureUnit != 0) {
187859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                if (verboseLogging) {
187959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                    logger.info("GLES20.glActiveTexture(GLES20.GL_TEXTURE0)");
188059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                }
188159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
188259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                GLES20.glActiveTexture(GLES20.GL_TEXTURE0);
188359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                context.boundTextureUnit = 0;
188459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            }
188559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
188659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            if (verboseLogging) {
188759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                logger.info("GLES20.glBindTexture(" + target + ", " + texId + ")");
188859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            }
188959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
189059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            GLES20.glBindTexture(target, texId);
189159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            context.boundTextures[0] = img;
189259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
189359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
189459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
189559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (target == GLES20.GL_TEXTURE_CUBE_MAP) {
189659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            // Upload a cube map / sky box
189759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            @SuppressWarnings("unchecked")
189859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            List<AndroidImageInfo> bmps = (List<AndroidImageInfo>) img.getEfficentData();
189959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            if (bmps != null) {
190059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                // Native android bitmap
190159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                if (bmps.size() != 6) {
190259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                    throw new UnsupportedOperationException("Invalid texture: " + img
190359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                            + "Cubemap textures must contain 6 data units.");
190459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                }
190559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                for (int i = 0; i < 6; i++) {
190659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                    TextureUtil.uploadTextureBitmap(GLES20.GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, bmps.get(i).getBitmap(), false, powerOf2);
190759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                }
190859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            } else {
190959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                // Standard jme3 image data
191059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                List<ByteBuffer> data = img.getData();
191159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                if (data.size() != 6) {
191259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                    logger.log(Level.WARNING, "Invalid texture: {0}\n"
191359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                            + "Cubemap textures must contain 6 data units.", img);
191459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                    return;
191559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                }
191659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                for (int i = 0; i < 6; i++) {
191759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                    TextureUtil.uploadTexture(img, GLES20.GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, i, 0, tdc, false, powerOf2);
191859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                }
191959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            }
192059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        } else {
192159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            TextureUtil.uploadTexture(img, target, 0, 0, tdc, false, powerOf2);
192259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
192359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            if (verboseLogging) {
192459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                logger.info("GLES20.glTexParameteri(" + target + "GLES11.GL_GENERATE_MIMAP, GLES20.GL_TRUE)");
192559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            }
192659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
192759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            if (!img.hasMipmaps() && mips) {
192859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                // No pregenerated mips available,
192959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                // generate from base level if required
193059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                if (verboseLogging) {
193159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                    logger.info("GLES20.glGenerateMipmap(GLES20.GL_TEXTURE_2D)");
193259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                }
193359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                GLES20.glGenerateMipmap(GLES20.GL_TEXTURE_2D);
193459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            }
193559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
193659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
193759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        img.clearUpdateNeeded();
193859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
193959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
194059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public void setTexture(int unit, Texture tex) {
194159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        Image image = tex.getImage();
194259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (image.isUpdateNeeded()) {
194359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            /*
194459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            Bitmap bmp = (Bitmap)image.getEfficentData();
194559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            if (bmp != null)
194659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            {
194759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            // Check if the bitmap got recycled, can happen after wakeup/restart
194859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            if ( bmp.isRecycled() )
194959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            {
195059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            // We need to reload the bitmap
195159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            Texture textureReloaded = JmeSystem.newAssetManager().loadTexture((TextureKey)tex.getKey());
195259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            image.setEfficentData( textureReloaded.getImage().getEfficentData());
195359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            }
195459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            }
195559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta             */
195659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            updateTexImageData(image, tex.getType(), tex.getMinFilter().usesMipMapLevels());
195759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
195859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
195959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        int texId = image.getId();
196059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        assert texId != -1;
196159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
196259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (texId == -1) {
196359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            logger.warning("error: texture image has -1 id");
196459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
196559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
196659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        Image[] textures = context.boundTextures;
196759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
196859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        int type = convertTextureType(tex.getType());
196959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (!context.textureIndexList.moveToNew(unit)) {
197059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta//             if (context.boundTextureUnit != unit){
197159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta//                glActiveTexture(GL_TEXTURE0 + unit);
197259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta//                context.boundTextureUnit = unit;
197359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta//             }
197459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta//             glEnable(type);
197559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
197659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
197759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (textures[unit] != image) {
197859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            if (context.boundTextureUnit != unit) {
197959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                if (verboseLogging) {
198059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                    logger.info("GLES20.glActiveTexture(GLES20.GL_TEXTURE0 + " + unit + ")");
198159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                }
198259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                GLES20.glActiveTexture(GLES20.GL_TEXTURE0 + unit);
198359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                context.boundTextureUnit = unit;
198459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            }
198559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
198659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            if (verboseLogging) {
198759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                logger.info("GLES20.glBindTexture(" + type + ", " + texId + ")");
198859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            }
198959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
199059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            GLES20.glBindTexture(type, texId);
199159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            textures[unit] = image;
199259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
199359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            statistics.onTextureUse(tex.getImage(), true);
199459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        } else {
199559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            statistics.onTextureUse(tex.getImage(), false);
199659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
199759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
199859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        setupTextureParams(tex);
199959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
200059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
200159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public void clearTextureUnits() {
200259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        IDList textureList = context.textureIndexList;
200359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        Image[] textures = context.boundTextures;
200459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        for (int i = 0; i < textureList.oldLen; i++) {
200559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            int idx = textureList.oldList[i];
200659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta//            if (context.boundTextureUnit != idx){
200759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta//                glActiveTexture(GL_TEXTURE0 + idx);
200859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta//                context.boundTextureUnit = idx;
200959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta//            }
201059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta//            glDisable(convertTextureType(textures[idx].getType()));
201159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            textures[idx] = null;
201259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
201359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        context.textureIndexList.copyNewToOld();
201459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
201559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
201659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public void deleteImage(Image image) {
201759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        int texId = image.getId();
201859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (texId != -1) {
201959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            intBuf1.put(0, texId);
202059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            intBuf1.position(0).limit(1);
202159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
202259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            if (verboseLogging) {
202359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                logger.info("GLES20.glDeleteTexture(1, buffer)");
202459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            }
202559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
202659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            GLES20.glDeleteTextures(1, intBuf1);
202759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            image.resetObject();
202859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
202959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            statistics.onDeleteTexture();
203059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
203159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
203259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
203359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /*********************************************************************\
203459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    |* Vertex Buffers and Attributes                                     *|
203559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    \*********************************************************************/
203659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    private int convertUsage(Usage usage) {
203759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        switch (usage) {
203859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            case Static:
203959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                return GLES20.GL_STATIC_DRAW;
204059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            case Dynamic:
204159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                return GLES20.GL_DYNAMIC_DRAW;
204259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            case Stream:
204359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                return GLES20.GL_STREAM_DRAW;
204459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            default:
204559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                throw new RuntimeException("Unknown usage type.");
204659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
204759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
204859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
204959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    private int convertFormat(Format format) {
205059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        switch (format) {
205159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            case Byte:
205259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                return GLES20.GL_BYTE;
205359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            case UnsignedByte:
205459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                return GLES20.GL_UNSIGNED_BYTE;
205559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            case Short:
205659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                return GLES20.GL_SHORT;
205759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            case UnsignedShort:
205859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                return GLES20.GL_UNSIGNED_SHORT;
205959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            case Int:
206059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                return GLES20.GL_INT;
206159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            case UnsignedInt:
206259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                return GLES20.GL_UNSIGNED_INT;
206359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            /*
206459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            case Half:
206559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            return NVHalfFloat.GL_HALF_FLOAT_NV;
206659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            //                return ARBHalfFloatVertex.GL_HALF_FLOAT;
206759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta             */
206859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            case Float:
206959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                return GLES20.GL_FLOAT;
207059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta//            case Double:
207159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta//                return GLES20.GL_DOUBLE;
207259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            default:
207359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                throw new RuntimeException("Unknown buffer format.");
207459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
207559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
207659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
207759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
207859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public void updateBufferData(VertexBuffer vb) {
207959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
208059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (verboseLogging) {
208159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            logger.info("updateBufferData(" + vb + ")");
208259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
208359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
208459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        int bufId = vb.getId();
208559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        boolean created = false;
208659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (bufId == -1) {
208759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            // create buffer
208859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
208959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            if (verboseLogging) {
209059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                logger.info("GLES20.glGenBuffers(" + 1 + ", buffer)");
209159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            }
209259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
209359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            GLES20.glGenBuffers(1, intBuf1);
209459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            bufId = intBuf1.get(0);
209559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            vb.setId(bufId);
209659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            objManager.registerForCleanup(vb);
209759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
209859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            created = true;
209959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
210059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
210159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        // bind buffer
210259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        int target;
210359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (vb.getBufferType() == VertexBuffer.Type.Index) {
210459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            target = GLES20.GL_ELEMENT_ARRAY_BUFFER;
210559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
210659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            if (verboseLogging) {
210759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                logger.info("vb.getBufferType() == VertexBuffer.Type.Index");
210859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            }
210959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
211059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            if (context.boundElementArrayVBO != bufId) {
211159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
211259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                if (verboseLogging) {
211359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                    logger.info("GLES20.glBindBuffer(" + target + ", " + bufId + ")");
211459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                }
211559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
211659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                GLES20.glBindBuffer(target, bufId);
211759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                context.boundElementArrayVBO = bufId;
211859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            }
211959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        } else {
212059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            if (verboseLogging) {
212159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                logger.info("vb.getBufferType() != VertexBuffer.Type.Index");
212259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            }
212359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
212459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            target = GLES20.GL_ARRAY_BUFFER;
212559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
212659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            if (context.boundArrayVBO != bufId) {
212759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
212859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                if (verboseLogging) {
212959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                    logger.info("GLES20.glBindBuffer(" + target + ", " + bufId + ")");
213059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                }
213159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
213259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                GLES20.glBindBuffer(target, bufId);
213359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                context.boundArrayVBO = bufId;
213459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            }
213559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
213659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
213759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        int usage = convertUsage(vb.getUsage());
213859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        vb.getData().clear();
213959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
214059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (created || vb.hasDataSizeChanged()) {
214159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            // upload data based on format
214259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            int size = vb.getData().capacity() * vb.getFormat().getComponentSize();
214359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
214459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            switch (vb.getFormat()) {
214559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                case Byte:
214659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                case UnsignedByte:
214759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
214859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                    if (verboseLogging) {
214959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                        logger.info("GLES20.glBufferData(" + target + ", " + size + ", (data), " + usage + ")");
215059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                    }
215159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
215259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                    GLES20.glBufferData(target, size, (ByteBuffer) vb.getData(), usage);
215359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                    break;
215459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                //            case Half:
215559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                case Short:
215659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                case UnsignedShort:
215759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
215859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                    if (verboseLogging) {
215959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                        logger.info("GLES20.glBufferData(" + target + ", " + size + ", (data), " + usage + ")");
216059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                    }
216159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
216259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                    GLES20.glBufferData(target, size, (ShortBuffer) vb.getData(), usage);
216359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                    break;
216459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                case Int:
216559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                case UnsignedInt:
216659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
216759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                    if (verboseLogging) {
216859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                        logger.info("GLES20.glBufferData(" + target + ", " + size + ", (data), " + usage + ")");
216959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                    }
217059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
217159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                    GLES20.glBufferData(target, size, (IntBuffer) vb.getData(), usage);
217259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                    break;
217359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                case Float:
217459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                    if (verboseLogging) {
217559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                        logger.info("GLES20.glBufferData(" + target + ", " + size + ", (data), " + usage + ")");
217659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                    }
217759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
217859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                    GLES20.glBufferData(target, size, (FloatBuffer) vb.getData(), usage);
217959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                    break;
218059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                case Double:
218159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                    if (verboseLogging) {
218259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                        logger.info("GLES20.glBufferData(" + target + ", " + size + ", (data), " + usage + ")");
218359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                    }
218459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
218559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                    GLES20.glBufferData(target, size, (DoubleBuffer) vb.getData(), usage);
218659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                    break;
218759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                default:
218859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                    throw new RuntimeException("Unknown buffer format.");
218959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            }
219059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        } else {
219159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            int size = vb.getData().capacity() * vb.getFormat().getComponentSize();
219259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
219359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            switch (vb.getFormat()) {
219459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                case Byte:
219559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                case UnsignedByte:
219659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                    if (verboseLogging) {
219759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                        logger.info("GLES20.glBufferSubData(" + target + ", 0, " + size + ", (data))");
219859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                    }
219959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
220059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                    GLES20.glBufferSubData(target, 0, size, (ByteBuffer) vb.getData());
220159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                    break;
220259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                case Short:
220359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                case UnsignedShort:
220459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                    if (verboseLogging) {
220559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                        logger.info("GLES20.glBufferSubData(" + target + ", 0, " + size + ", (data))");
220659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                    }
220759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
220859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                    GLES20.glBufferSubData(target, 0, size, (ShortBuffer) vb.getData());
220959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                    break;
221059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                case Int:
221159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                case UnsignedInt:
221259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                    if (verboseLogging) {
221359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                        logger.info("GLES20.glBufferSubData(" + target + ", 0, " + size + ", (data))");
221459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                    }
221559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
221659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                    GLES20.glBufferSubData(target, 0, size, (IntBuffer) vb.getData());
221759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                    break;
221859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                case Float:
221959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                    if (verboseLogging) {
222059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                        logger.info("GLES20.glBufferSubData(" + target + ", 0, " + size + ", (data))");
222159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                    }
222259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
222359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                    GLES20.glBufferSubData(target, 0, size, (FloatBuffer) vb.getData());
222459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                    break;
222559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                case Double:
222659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                    if (verboseLogging) {
222759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                        logger.info("GLES20.glBufferSubData(" + target + ", 0, " + size + ", (data))");
222859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                    }
222959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
223059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                    GLES20.glBufferSubData(target, 0, size, (DoubleBuffer) vb.getData());
223159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                    break;
223259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                default:
223359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                    throw new RuntimeException("Unknown buffer format.");
223459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            }
223559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
223659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta//        }else{
223759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta//            if (created || vb.hasDataSizeChanged()){
223859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta//                glBufferData(target, vb.getData().capacity() * vb.getFormat().getComponentSize(), usage);
223959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta//            }
224059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta//
224159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta//            ByteBuffer buf = glMapBuffer(target,
224259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta//                                         GL_WRITE_ONLY,
224359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta//                                         vb.getMappedData());
224459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta//
224559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta//            if (buf != vb.getMappedData()){
224659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta//                buf = buf.order(ByteOrder.nativeOrder());
224759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta//                vb.setMappedData(buf);
224859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta//            }
224959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta//
225059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta//            buf.clear();
225159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta//
225259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta//            switch (vb.getFormat()){
225359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta//                case Byte:
225459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta//                case UnsignedByte:
225559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta//                    buf.put( (ByteBuffer) vb.getData() );
225659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta//                    break;
225759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta//                case Short:
225859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta//                case UnsignedShort:
225959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta//                    buf.asShortBuffer().put( (ShortBuffer) vb.getData() );
226059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta//                    break;
226159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta//                case Int:
226259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta//                case UnsignedInt:
226359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta//                    buf.asIntBuffer().put( (IntBuffer) vb.getData() );
226459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta//                    break;
226559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta//                case Float:
226659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta//                    buf.asFloatBuffer().put( (FloatBuffer) vb.getData() );
226759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta//                    break;
226859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta//                case Double:
226959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta//                    break;
227059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta//                default:
227159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta//                    throw new RuntimeException("Unknown buffer format.");
227259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta//            }
227359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta//
227459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta//            glUnmapBuffer(target);
227559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta//        }
227659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
227759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        vb.clearUpdateNeeded();
227859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
227959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
228059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public void deleteBuffer(VertexBuffer vb) {
228159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        int bufId = vb.getId();
228259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (bufId != -1) {
228359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            // delete buffer
228459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            intBuf1.put(0, bufId);
228559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            intBuf1.position(0).limit(1);
228659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            if (verboseLogging) {
228759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                logger.info("GLES20.glDeleteBuffers(1, buffer)");
228859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            }
228959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
229059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            GLES20.glDeleteBuffers(1, intBuf1);
229159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            vb.resetObject();
229259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
229359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
229459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
229559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public void clearVertexAttribs() {
229659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        IDList attribList = context.attribIndexList;
229759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        for (int i = 0; i < attribList.oldLen; i++) {
229859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            int idx = attribList.oldList[i];
229959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
230059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            if (verboseLogging) {
230159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                logger.info("GLES20.glDisableVertexAttribArray(" + idx + ")");
230259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            }
230359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
230459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            GLES20.glDisableVertexAttribArray(idx);
230559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            context.boundAttribs[idx] = null;
230659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
230759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        context.attribIndexList.copyNewToOld();
230859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
230959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
231059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public void setVertexAttrib(VertexBuffer vb, VertexBuffer idb) {
231159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (verboseLogging) {
231259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            logger.info("setVertexAttrib(" + vb + ", " + idb + ")");
231359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
231459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
231559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (vb.getBufferType() == VertexBuffer.Type.Index) {
231659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            throw new IllegalArgumentException("Index buffers not allowed to be set to vertex attrib");
231759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
231859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
231959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (vb.isUpdateNeeded() && idb == null) {
232059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            updateBufferData(vb);
232159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
232259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
232359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        int programId = context.boundShaderProgram;
232459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (programId > 0) {
232559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            Attribute attrib = boundShader.getAttribute(vb.getBufferType());
232659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            int loc = attrib.getLocation();
232759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            if (loc == -1) {
232859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
232959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                if (verboseLogging) {
233059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                    logger.warning("location is invalid for attrib: [" + vb.getBufferType().name() + "]");
233159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                }
233259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
233359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                return; // not defined
233459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            }
233559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
233659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            if (loc == -2) {
233759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta//                stringBuf.setLength(0);
233859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta//                stringBuf.append("in").append(vb.getBufferType().name()).append('\0');
233959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta//                updateNameBuffer();
234059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
234159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                String attributeName = "in" + vb.getBufferType().name();
234259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
234359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                if (verboseLogging) {
234459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                    logger.info("GLES20.glGetAttribLocation(" + programId + ", " + attributeName + ")");
234559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                }
234659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
234759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                loc = GLES20.glGetAttribLocation(programId, attributeName);
234859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
234959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                // not really the name of it in the shader (inPosition\0) but
235059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                // the internal name of the enum (Position).
235159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                if (loc < 0) {
235259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                    attrib.setLocation(-1);
235359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
235459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                    if (verboseLogging) {
235559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                        logger.warning("attribute is invalid in shader: [" + vb.getBufferType().name() + "]");
235659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                    }
235759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
235859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                    return; // not available in shader.
235959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                } else {
236059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                    attrib.setLocation(loc);
236159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                }
236259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            }
236359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
236459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            VertexBuffer[] attribs = context.boundAttribs;
236559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            if (!context.attribIndexList.moveToNew(loc)) {
236659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                if (verboseLogging) {
236759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                    logger.info("GLES20.glEnableVertexAttribArray(" + loc + ")");
236859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                }
236959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
237059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                GLES20.glEnableVertexAttribArray(loc);
237159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                //System.out.println("Enabled ATTRIB IDX: "+loc);
237259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            }
237359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            if (attribs[loc] != vb) {
237459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                // NOTE: Use id from interleaved buffer if specified
237559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                int bufId = idb != null ? idb.getId() : vb.getId();
237659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                assert bufId != -1;
237759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
237859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                if (bufId == -1) {
237959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                    logger.warning("invalid buffer id");
238059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                }
238159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
238259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                if (context.boundArrayVBO != bufId) {
238359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                    if (verboseLogging) {
238459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                        logger.info("GLES20.glBindBuffer(" + GLES20.GL_ARRAY_BUFFER + ", " + bufId + ")");
238559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                    }
238659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                    GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, bufId);
238759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                    context.boundArrayVBO = bufId;
238859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                }
238959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
239059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                vb.getData().clear();
239159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
239259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                if (verboseLogging) {
239359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                    logger.info("GLES20.glVertexAttribPointer("
239459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                            + "location=" + loc + ", "
239559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                            + "numComponents=" + vb.getNumComponents() + ", "
239659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                            + "format=" + vb.getFormat() + ", "
239759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                            + "isNormalized=" + vb.isNormalized() + ", "
239859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                            + "stride=" + vb.getStride() + ", "
239959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                            + "data.capacity=" + vb.getData().capacity() + ")");
240059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                }
240159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
240259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                Android22Workaround.glVertexAttribPointer(loc,
240359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                                    vb.getNumComponents(),
240459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                                    convertFormat(vb.getFormat()),
240559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                                    vb.isNormalized(),
240659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                                    vb.getStride(),
240759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                                    0);
240859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
240959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                attribs[loc] = vb;
241059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            }
241159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        } else {
241259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            throw new IllegalStateException("Cannot render mesh without shader bound");
241359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
241459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
241559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
241659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public void setVertexAttrib(VertexBuffer vb) {
241759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        setVertexAttrib(vb, null);
241859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
241959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
242059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public void drawTriangleArray(Mesh.Mode mode, int count, int vertCount) {
242159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        /*        if (count > 1){
242259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        ARBDrawInstanced.glDrawArraysInstancedARB(convertElementMode(mode), 0,
242359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        vertCount, count);
242459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }else{*/
242559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (verboseLogging) {
242659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            logger.info("GLES20.glDrawArrays(" + vertCount + ")");
242759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
242859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
242959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        GLES20.glDrawArrays(convertElementMode(mode), 0, vertCount);
243059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        /*
243159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }*/
243259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
243359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
243459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public void drawTriangleList(VertexBuffer indexBuf, Mesh mesh, int count) {
243559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
243659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (verboseLogging) {
243759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            logger.info("drawTriangleList(" + count + ")");
243859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
243959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
244059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (indexBuf.getBufferType() != VertexBuffer.Type.Index) {
244159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            throw new IllegalArgumentException("Only index buffers are allowed as triangle lists.");
244259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
244359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
244459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (indexBuf.isUpdateNeeded()) {
244559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            if (verboseLogging) {
244659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                logger.info("updateBufferData for indexBuf.");
244759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            }
244859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            updateBufferData(indexBuf);
244959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
245059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
245159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        int bufId = indexBuf.getId();
245259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        assert bufId != -1;
245359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
245459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (bufId == -1) {
245559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            logger.info("invalid buffer id!");
245659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
245759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
245859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (context.boundElementArrayVBO != bufId) {
245959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            if (verboseLogging) {
246059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                logger.log(Level.INFO, "GLES20.glBindBuffer(GLES20.GL_ELEMENT_ARRAY_BUFFER, {0})", bufId);
246159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            }
246259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
246359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            GLES20.glBindBuffer(GLES20.GL_ELEMENT_ARRAY_BUFFER, bufId);
246459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            context.boundElementArrayVBO = bufId;
246559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
246659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
246759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        int vertCount = mesh.getVertexCount();
246859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        boolean useInstancing = count > 1 && caps.contains(Caps.MeshInstancing);
246959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
247059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        Buffer indexData = indexBuf.getData();
247159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
247259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (mesh.getMode() == Mode.Hybrid) {
247359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            int[] modeStart = mesh.getModeStart();
247459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            int[] elementLengths = mesh.getElementLengths();
247559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
247659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            int elMode = convertElementMode(Mode.Triangles);
247759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            int fmt = convertFormat(indexBuf.getFormat());
247859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            int elSize = indexBuf.getFormat().getComponentSize();
247959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            int listStart = modeStart[0];
248059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            int stripStart = modeStart[1];
248159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            int fanStart = modeStart[2];
248259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            int curOffset = 0;
248359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            for (int i = 0; i < elementLengths.length; i++) {
248459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                if (i == stripStart) {
248559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                    elMode = convertElementMode(Mode.TriangleStrip);
248659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                } else if (i == fanStart) {
248759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                    elMode = convertElementMode(Mode.TriangleStrip);
248859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                }
248959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                int elementLength = elementLengths[i];
249059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
249159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                if (useInstancing) {
249259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                    //ARBDrawInstanced.
249359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                    throw new IllegalArgumentException("instancing is not supported.");
249459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                    /*
249559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                    GLES20.glDrawElementsInstancedARB(elMode,
249659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                    elementLength,
249759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                    fmt,
249859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                    curOffset,
249959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                    count);
250059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                     */
250159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                } else {
250259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                    indexBuf.getData().position(curOffset);
250359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                    if (verboseLogging) {
250459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                        logger.log(Level.INFO, "glDrawElements(): {0}, {1}", new Object[]{elementLength, curOffset});
250559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                    }
250659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
250759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                    GLES20.glDrawElements(elMode, elementLength, fmt, indexBuf.getData());
250859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                    /*
250959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                    glDrawRangeElements(elMode,
251059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                    0,
251159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                    vertCount,
251259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                    elementLength,
251359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                    fmt,
251459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                    curOffset);
251559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                     */
251659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                }
251759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
251859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                curOffset += elementLength * elSize;
251959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            }
252059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        } else {
252159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            if (useInstancing) {
252259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                throw new IllegalArgumentException("instancing is not supported.");
252359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                //ARBDrawInstanced.
252459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta/*
252559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                GLES20.glDrawElementsInstancedARB(convertElementMode(mesh.getMode()),
252659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                indexBuf.getData().capacity(),
252759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                convertFormat(indexBuf.getFormat()),
252859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                0,
252959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                count);
253059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                 */
253159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            } else {
253259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                indexData.clear();
253359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
253459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                if (verboseLogging) {
253559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                    logger.log(Level.INFO, "glDrawElements(), indexBuf.capacity ({0}), vertCount ({1})", new Object[]{indexBuf.getData().capacity(), vertCount});
253659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                }
253759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
2538a6b44658eb1c55295f132a36233a11aa2bd8f9cfScott Barta                GLES20.glDrawElements(
253959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                        convertElementMode(mesh.getMode()),
254059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                        indexBuf.getData().capacity(),
254159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                        convertFormat(indexBuf.getFormat()),
254259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                        0);
254359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            }
254459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
254559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
254659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
254759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /*********************************************************************\
254859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    |* Render Calls                                                      *|
254959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    \*********************************************************************/
255059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public int convertElementMode(Mesh.Mode mode) {
255159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        switch (mode) {
255259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            case Points:
255359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                return GLES20.GL_POINTS;
255459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            case Lines:
255559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                return GLES20.GL_LINES;
255659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            case LineLoop:
255759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                return GLES20.GL_LINE_LOOP;
255859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            case LineStrip:
255959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                return GLES20.GL_LINE_STRIP;
256059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            case Triangles:
256159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                return GLES20.GL_TRIANGLES;
256259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            case TriangleFan:
256359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                return GLES20.GL_TRIANGLE_FAN;
256459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            case TriangleStrip:
256559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                return GLES20.GL_TRIANGLE_STRIP;
256659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            default:
256759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                throw new UnsupportedOperationException("Unrecognized mesh mode: " + mode);
256859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
256959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
257059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
257159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public void updateVertexArray(Mesh mesh) {
257259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        logger.log(Level.INFO, "updateVertexArray({0})", mesh);
257359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        int id = mesh.getId();
257459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        /*
257559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (id == -1){
257659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        IntBuffer temp = intBuf1;
257759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        //      ARBVertexArrayObject.glGenVertexArrays(temp);
257859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        GLES20.glGenVertexArrays(temp);
257959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        id = temp.get(0);
258059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        mesh.setId(id);
258159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
258259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
258359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (context.boundVertexArray != id){
258459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        //     ARBVertexArrayObject.glBindVertexArray(id);
258559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        GLES20.glBindVertexArray(id);
258659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        context.boundVertexArray = id;
258759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
258859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta         */
258959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        VertexBuffer interleavedData = mesh.getBuffer(Type.InterleavedData);
259059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (interleavedData != null && interleavedData.isUpdateNeeded()) {
259159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            updateBufferData(interleavedData);
259259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
259359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
259459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
259559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        for (VertexBuffer vb : mesh.getBufferList().getArray()){
259659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
259759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            if (vb.getBufferType() == Type.InterleavedData
259859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                    || vb.getUsage() == Usage.CpuOnly // ignore cpu-only buffers
259959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                    || vb.getBufferType() == Type.Index) {
260059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                continue;
260159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            }
260259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
260359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            if (vb.getStride() == 0) {
260459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                // not interleaved
260559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                setVertexAttrib(vb);
260659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            } else {
260759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                // interleaved
260859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                setVertexAttrib(vb, interleavedData);
260959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            }
261059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
261159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
261259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
261359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /**
261459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * renderMeshVertexArray renders a mesh using vertex arrays
261559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param mesh
261659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param lod
261759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param count
261859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
261959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    private void renderMeshVertexArray(Mesh mesh, int lod, int count) {
262059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (verboseLogging) {
262159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            logger.info("renderMeshVertexArray");
262259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
262359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
262459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta      //  IntMap<VertexBuffer> buffers = mesh.getBuffers();
262559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta         for (VertexBuffer vb : mesh.getBufferList().getArray()){
262659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
262759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            if (vb.getBufferType() == Type.InterleavedData
262859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                    || vb.getUsage() == Usage.CpuOnly // ignore cpu-only buffers
262959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                    || vb.getBufferType() == Type.Index) {
263059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                continue;
263159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            }
263259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
263359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            if (vb.getStride() == 0) {
263459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                // not interleaved
263559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                setVertexAttrib_Array(vb);
263659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            } else {
263759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                // interleaved
263859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                VertexBuffer interleavedData = mesh.getBuffer(Type.InterleavedData);
263959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                setVertexAttrib_Array(vb, interleavedData);
264059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            }
264159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
264259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
264359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        VertexBuffer indices = null;
264459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (mesh.getNumLodLevels() > 0) {
264559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            indices = mesh.getLodLevel(lod);
264659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        } else {
264759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            indices = mesh.getBuffer(Type.Index);//buffers.get(Type.Index.ordinal());
264859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
264959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (indices != null) {
265059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            drawTriangleList_Array(indices, mesh, count);
265159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        } else {
265259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            if (verboseLogging) {
265359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                logger.log(Level.INFO, "GLES20.glDrawArrays({0}, {1}, {2})",
265459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                        new Object[]{mesh.getMode(), 0, mesh.getVertexCount()});
265559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            }
265659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
265759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            GLES20.glDrawArrays(convertElementMode(mesh.getMode()), 0, mesh.getVertexCount());
265859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
265959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        clearVertexAttribs();
266059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        clearTextureUnits();
266159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
266259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
266359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    private void renderMeshDefault(Mesh mesh, int lod, int count) {
266459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (verboseLogging) {
266559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            logger.log(Level.INFO, "renderMeshDefault({0}, {1}, {2})",
266659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                    new Object[]{mesh, lod, count});
266759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
266859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        VertexBuffer indices = null;
266959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
267059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        VertexBuffer interleavedData = mesh.getBuffer(Type.InterleavedData);
267159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (interleavedData != null && interleavedData.isUpdateNeeded()) {
267259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            updateBufferData(interleavedData);
267359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
267459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
267559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        //IntMap<VertexBuffer> buffers = mesh.getBuffers();     ;
267659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (mesh.getNumLodLevels() > 0) {
267759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            indices = mesh.getLodLevel(lod);
267859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        } else {
267959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            indices = mesh.getBuffer(Type.Index);// buffers.get(Type.Index.ordinal());
268059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
268159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        for (VertexBuffer vb : mesh.getBufferList().getArray()){
268259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
268359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            if (vb.getBufferType() == Type.InterleavedData
268459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                    || vb.getUsage() == Usage.CpuOnly // ignore cpu-only buffers
268559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                    || vb.getBufferType() == Type.Index) {
268659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                continue;
268759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            }
268859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
268959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            if (vb.getStride() == 0) {
269059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                // not interleaved
269159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                setVertexAttrib(vb);
269259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            } else {
269359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                // interleaved
269459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                setVertexAttrib(vb, interleavedData);
269559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            }
269659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
269759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (indices != null) {
269859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            drawTriangleList(indices, mesh, count);
269959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        } else {
270059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta//            throw new UnsupportedOperationException("Cannot render without index buffer");
270159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            if (verboseLogging) {
270259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                logger.log(Level.INFO, "GLES20.glDrawArrays({0}, 0, {1})",
270359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                        new Object[]{convertElementMode(mesh.getMode()), mesh.getVertexCount()});
270459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            }
270559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
270659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            GLES20.glDrawArrays(convertElementMode(mesh.getMode()), 0, mesh.getVertexCount());
270759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
270859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        clearVertexAttribs();
270959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        clearTextureUnits();
271059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
271159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
271259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public void renderMesh(Mesh mesh, int lod, int count) {
271359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (context.pointSize != mesh.getPointSize()) {
271459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
271559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            if (verboseLogging) {
271659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                logger.log(Level.INFO, "GLES10.glPointSize({0})", mesh.getPointSize());
271759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            }
271859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
271959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            GLES10.glPointSize(mesh.getPointSize());
272059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            context.pointSize = mesh.getPointSize();
272159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
272259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (context.lineWidth != mesh.getLineWidth()) {
272359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
272459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            if (verboseLogging) {
272559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                logger.log(Level.INFO, "GLES20.glLineWidth({0})", mesh.getLineWidth());
272659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            }
272759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
272859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            GLES20.glLineWidth(mesh.getLineWidth());
272959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            context.lineWidth = mesh.getLineWidth();
273059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
273159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
273259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        statistics.onMeshDrawn(mesh, lod);
273359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta//        if (GLContext.getCapabilities().GL_ARB_vertex_array_object){
273459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta//            renderMeshVertexArray(mesh, lod, count);
273559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta//        }else{
273659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
273759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (useVBO) {
273859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            if (verboseLogging) {
273959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                logger.info("RENDERING A MESH USING VertexBufferObject");
274059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            }
274159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
274259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            renderMeshDefault(mesh, lod, count);
274359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        } else {
274459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            if (verboseLogging) {
274559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                logger.info("RENDERING A MESH USING VertexArray");
274659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            }
274759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
274859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            renderMeshVertexArray(mesh, lod, count);
274959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
275059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
275159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta//        }
275259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
275359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
275459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /**
275559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * drawTriangleList_Array uses Vertex Array
275659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param indexBuf
275759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param mesh
275859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param count
275959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
276059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public void drawTriangleList_Array(VertexBuffer indexBuf, Mesh mesh, int count) {
276159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (verboseLogging) {
276259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            logger.log(Level.INFO, "drawTriangleList_Array(Count = {0})", count);
276359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
276459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
276559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (indexBuf.getBufferType() != VertexBuffer.Type.Index) {
276659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            throw new IllegalArgumentException("Only index buffers are allowed as triangle lists.");
276759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
276859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
276959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        boolean useInstancing = count > 1 && caps.contains(Caps.MeshInstancing);
277059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (useInstancing) {
277159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            throw new IllegalArgumentException("Caps.MeshInstancing is not supported.");
277259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
277359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
277459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        int vertCount = mesh.getVertexCount();
277559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        Buffer indexData = indexBuf.getData();
277659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        indexData.clear();
277759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
277859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (mesh.getMode() == Mode.Hybrid) {
277959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            int[] modeStart = mesh.getModeStart();
278059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            int[] elementLengths = mesh.getElementLengths();
278159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
278259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            int elMode = convertElementMode(Mode.Triangles);
278359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            int fmt = convertFormat(indexBuf.getFormat());
278459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            int elSize = indexBuf.getFormat().getComponentSize();
278559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            int listStart = modeStart[0];
278659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            int stripStart = modeStart[1];
278759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            int fanStart = modeStart[2];
278859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            int curOffset = 0;
278959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            for (int i = 0; i < elementLengths.length; i++) {
279059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                if (i == stripStart) {
279159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                    elMode = convertElementMode(Mode.TriangleStrip);
279259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                } else if (i == fanStart) {
279359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                    elMode = convertElementMode(Mode.TriangleStrip);
279459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                }
279559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                int elementLength = elementLengths[i];
279659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
279759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                indexBuf.getData().position(curOffset);
279859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                if (verboseLogging) {
279959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                    logger.log(Level.INFO, "glDrawElements(): {0}, {1}", new Object[]{elementLength, curOffset});
280059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                }
280159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
280259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                GLES20.glDrawElements(elMode, elementLength, fmt, indexBuf.getData());
280359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
280459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                curOffset += elementLength * elSize;
280559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            }
280659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        } else {
280759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            if (verboseLogging) {
280859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                logger.log(Level.INFO, "glDrawElements(), indexBuf.capacity ({0}), vertCount ({1})", new Object[]{indexBuf.getData().capacity(), vertCount});
280959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            }
281059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
281159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            GLES20.glDrawElements(
281259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                    convertElementMode(mesh.getMode()),
281359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                    indexBuf.getData().capacity(),
281459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                    convertFormat(indexBuf.getFormat()),
281559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                    indexBuf.getData());
281659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
281759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
281859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
281959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /**
282059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * setVertexAttrib_Array uses Vertex Array
282159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param vb
282259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param idb
282359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
282459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public void setVertexAttrib_Array(VertexBuffer vb, VertexBuffer idb) {
282559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (verboseLogging) {
282659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            logger.log(Level.INFO, "setVertexAttrib_Array({0}, {1})", new Object[]{vb, idb});
282759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
282859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
282959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (vb.getBufferType() == VertexBuffer.Type.Index) {
283059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            throw new IllegalArgumentException("Index buffers not allowed to be set to vertex attrib");
283159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
283259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
283359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        // Get shader
283459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        int programId = context.boundShaderProgram;
283559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (programId > 0) {
283659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            VertexBuffer[] attribs = context.boundAttribs;
283759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
283859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            Attribute attrib = boundShader.getAttribute(vb.getBufferType());
283959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            int loc = attrib.getLocation();
284059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            if (loc == -1) {
284159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                //throw new IllegalArgumentException("Location is invalid for attrib: [" + vb.getBufferType().name() + "]");
284259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                if (verboseLogging) {
284359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                    logger.log(Level.WARNING, "attribute is invalid in shader: [{0}]", vb.getBufferType().name());
284459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                }
284559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                return;
284659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            } else if (loc == -2) {
284759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                String attributeName = "in" + vb.getBufferType().name();
284859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
284959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                if (verboseLogging) {
285059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                    logger.log(Level.INFO, "GLES20.glGetAttribLocation({0}, {1})", new Object[]{programId, attributeName});
285159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                }
285259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
285359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                loc = GLES20.glGetAttribLocation(programId, attributeName);
285459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                if (loc < 0) {
285559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                    attrib.setLocation(-1);
285659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                    if (verboseLogging) {
285759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                        logger.log(Level.WARNING, "attribute is invalid in shader: [{0}]", vb.getBufferType().name());
285859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                    }
285959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                    return; // not available in shader.
286059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                } else {
286159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                    attrib.setLocation(loc);
286259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                }
286359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
286459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            }  // if (loc == -2)
286559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
286659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            if ((attribs[loc] != vb) || vb.isUpdateNeeded()) {
286759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                // NOTE: Use data from interleaved buffer if specified
286859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                VertexBuffer avb = idb != null ? idb : vb;
286959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                avb.getData().clear();
287059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                avb.getData().position(vb.getOffset());
287159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
287259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                if (verboseLogging) {
287359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                    logger.log(Level.INFO,
287459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                            "GLES20.glVertexAttribPointer(" +
287559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                            "location={0}, " +
287659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                            "numComponents={1}, " +
287759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                            "format={2}, " +
287859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                            "isNormalized={3}, " +
287959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                            "stride={4}, " +
288059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                            "data.capacity={5})",
288159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                            new Object[]{loc, vb.getNumComponents(),
288259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                                         vb.getFormat(),
288359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                                         vb.isNormalized(),
288459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                                         vb.getStride(),
288559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                                         avb.getData().capacity()});
288659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                }
288759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
288859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
288959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                // Upload attribute data
289059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                GLES20.glVertexAttribPointer(loc,
289159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                        vb.getNumComponents(),
289259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                        convertFormat(vb.getFormat()),
289359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                        vb.isNormalized(),
289459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                        vb.getStride(),
289559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                        avb.getData());
289659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                checkGLError();
289759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
289859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                GLES20.glEnableVertexAttribArray(loc);
289959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
290059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                attribs[loc] = vb;
290159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            } // if (attribs[loc] != vb)
290259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        } else {
290359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            throw new IllegalStateException("Cannot render mesh without shader bound");
290459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
290559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
290659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
290759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /**
290859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * setVertexAttrib_Array uses Vertex Array
290959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param vb
291059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
291159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public void setVertexAttrib_Array(VertexBuffer vb) {
291259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        setVertexAttrib_Array(vb, null);
291359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
291459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
291559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public void setAlphaToCoverage(boolean value) {
291659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (value) {
291759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            GLES20.glEnable(GLES20.GL_SAMPLE_ALPHA_TO_COVERAGE);
291859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        } else {
291959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            GLES20.glDisable(GLES20.GL_SAMPLE_ALPHA_TO_COVERAGE);
292059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
292159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
292259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
292359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    @Override
292459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public void invalidateState() {
292559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        context.reset();
292659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        boundShader = null;
292759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        lastFb = null;
292859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
292959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta}
2930