public QuadCore(String vertShader, String fragShader) { super(vertShader, fragShader); // compile the shader and get our uniform and attribute uScreenSize = prog.getUniform2f("u_ScreenSize"); uData = prog.getUniform4fv("u_Data"); aVertex = prog.getAttrib("a_Vertex", VERTEX_SIZE, GL20.GL_SHORT); // create our stock supply of unit quads and stuff them into our buffers vertices = ctx.createShortBuffer(maxQuads*VERTICES_PER_QUAD*VERTEX_SIZE); elements = ctx.createShortBuffer(maxQuads*ELEMENTS_PER_QUAD); for (int ii = 0; ii < maxQuads; ii++) { vertices.add(0, 0).add(ii); vertices.add(1, 0).add(ii); vertices.add(0, 1).add(ii); vertices.add(1, 1).add(ii); int base = ii * VERTICES_PER_QUAD; elements.add(base+0).add(base+1).add(base+2); elements.add(base+1).add(base+3).add(base+2); } // create the buffer that will hold quad data, and the float array that we'll use to avoid // making too many calls to FloatBuffer.put() which has crap performance on Android data = ctx.createFloatBuffer(maxQuads*vec4sPerQuad()*4); vertices.bind(GL20.GL_ARRAY_BUFFER); vertices.send(GL20.GL_ARRAY_BUFFER, GL20.GL_STATIC_DRAW); elements.bind(GL20.GL_ELEMENT_ARRAY_BUFFER); elements.send(GL20.GL_ELEMENT_ARRAY_BUFFER, GL20.GL_STATIC_DRAW); }
protected final void addElems(int vertIdx, int[] indices, int indicesOffset, int indicesLen, int indexBase) { short[] data = elements.array(); int offset = elements.position(); for (int ii = indicesOffset, ll = ii+indicesLen; ii < ll; ii++) { data[offset++] = (short)(vertIdx+indices[ii]-indexBase); } elements.skip(offset - elements.position()); }
protected int beginPrimitive(int vertexCount, int elemCount) { int vertIdx = vertices.position() / vertexSize(); int verts = vertIdx + vertexCount, elems = elements.position() + elemCount; int availVerts = vertices.capacity() / vertexSize(), availElems = elements.capacity(); if ((verts > availVerts) || (elems > availElems)) { IndexedTrisShader.this.flush(); if (verts > availVerts) expandVerts(verts); if (elems > availElems) expandElems(elems); return 0; } return vertIdx; }
@Override public void flush() { super.flush(); if (vertices.position() == 0) return; ctx.checkGLError("Shader.flush"); if (delayedBinding) { // see comments in activate() bindAttribsBufs(); ctx.checkGLError("Shader.flush bind"); } vertices.send(GL20.GL_ARRAY_BUFFER, GL20.GL_STREAM_DRAW); int elems = elements.send(GL20.GL_ELEMENT_ARRAY_BUFFER, GL20.GL_STREAM_DRAW); ctx.checkGLError("Shader.flush BufferData"); elements.drawElements(GL20.GL_TRIANGLES, elems); ctx.checkGLError("Shader.flush DrawElements"); }
private void bindAttribsBufs() { vertices.bind(GL20.GL_ARRAY_BUFFER); // bind our stable attributes int stride = vertexStride(); aMatrix.bind(stride, 0); aTranslation.bind(stride, 16); aColor.bind(stride, 24); // bind our changing attributes int offset = stableAttrsSize()*FLOAT_SIZE_BYTES; aPosition.bind(stride, offset); if (aTexCoord != null) aTexCoord.bind(stride, offset+8); elements.bind(GL20.GL_ELEMENT_ARRAY_BUFFER); }
@Override public String toString() { return "cq=" + (elements.capacity()/6); }
@Override public void destroy() { super.destroy(); vertices.destroy(); elements.destroy(); }
@Override public void flush() { super.flush(); if (quadCounter == 0) return; uData.bind(data, quadCounter * vec4sPerQuad()); elements.drawElements(GL20.GL_TRIANGLES, ELEMENTS_PER_QUAD*quadCounter); quadCounter = 0; }