*/ public class VertexArray { private final FloatBuffer floatBuffer; public VertexArray(float [] vertexData) { this.floatBuffer = ByteBuffer.allocateDirect(vertexData.length * BYTE_PER_FLOAT ) .order(ByteOrder.nativeOrder()) .asFloatBuffer(); floatBuffer.put ); glEnableVertexAttribArray(attributeLocation); floatBuffer.position(0); } (start); floatBuffer.put(vertexData, start, count); floatBuffer.position(0); } }
这里面C语言能听懂的数据结构名叫FloatBuffer,于是问题的实质就变成了如何将浮点数组folat[]转换为浮点缓存FloatBuffer,具体的转换过程已经有了现成的模板,开发者只管套进去即可,详细的转换函数代码如下所示 : public static FloatBuffer getFloatBuffer(float[] array) { //初始化字节缓冲区的大小=数组长度*数组元素大小。 floatBuffer = byteBuffer.asFloatBuffer(); //把数组数据写入缓冲区 floatBuffer.put(array); //设置浮点缓冲区的初始位置 floatBuffer.position(0); return floatBuffer; } 现在有了可供OpenGL识别的FloatBuffer 这个便是前面转换而来的FloatBuffer对象了。
convertFloatBuffer (float[] vectices , int sizeByte){ FloatBuffer floatBuffer; floatBuffer (vectices).position(0); return floatBuffer; } private float[] createColorTransVertices( mPosBuffer = convertToFloatBuffer(mPosCoordinate); FloatBuffer mTexBuffer; if(camera_status ---- 接下来,是画中画特效的渲染过程: private void renderEffect(){ // --- for click effect FloatBuffer mPosBuffer = convertToFloatBuffer(mPosCoordinate); FloatBuffer mTexBuffer; if(camera_status
java.nio.DoubleBuffer对应double[], java.nio.FloatBuffer对应float[], java.nio.LongBuffer对应long[], java.nio.IntBuffer int[]…很简单因为ByteBuffer本身就有asDoubleBuffer,asFloatBuffer,asIntBuffer等方法,可以将ByteBuffer直接转换为DoubleBuffer,FloatBuffer ; } public static float[] asFloatArray(byte[] input){ if(null == input ){ return null; } FloatBuffer ){ return null; } return asByteBuffer(DoubleBuffer.wrap(input)).array(); } /** * {@link FloatBuffer } TO {@link ByteBuffer} * @param input * @return */ public static ByteBuffer asByteBuffer(FloatBuffer
this.x = x; this.y = y; this.z = z; } } public class STLUtils { public static FloatBuffer vertBuffer; //每个顶点对应的法向量转换而来的Buffer private FloatBuffer vnormBuffer; //以下分别保存所有点在x,y,z方向上的最大值 getVertBuffer() { return vertBuffer; } public void setVertBuffer(FloatBuffer vertBuffer ) { this.vertBuffer = vertBuffer; } public FloatBuffer getVnormBuffer() { return vnormBuffer; } public void setVnormBuffer(FloatBuffer vnormBuffer) { this.vnormBuffer
extends Buffer implements Comparable<FloatBuffer> public abstract class IntBuffer extends Buffer implements this.mark = mark; } } 下面我们来了解相关特性: /** * 进行nio测试:可以看到ByteBuffer、CharBuffer、DoubleBuffer、FloatBuffer floatBuffer = FloatBuffer.wrap(floatArray); DoubleBuffer doubleBuffer = DoubleBuffer.wrap(doubleArray =" + floatBuffer.getClass().getName()); System.out.println("doubleBuffer=" + doubleBuffer.getClass =" + floatBuffer.capacity()); System.out.println("doubleBuffer.capacity=" + doubleBuffer.capacity
顶点数据容器相关api 初始化顶点数据流程 : 创建ByteBuffer对象 -> 设置ByteBuffer对象顺序 -> 将ByteBuffer对象转为FloatBuffer对象 -> 设置 FloatBuffer对象值 -> 设置FloatBuffer对象起始位置 (1) 创建ByteBuffer对象 ByteBuffer vbb = ByteBuffer.allocateDirect * ③给FloatBuffer设置值, 设置起始位置 */ FloatBuffer mVertexBuffer; //顶点坐标数据缓冲 FloatBuffer mColorBuffer 将ByteBuffer对象转为FloatBuffer对象, 调用asFloatBuffer()方法; * e. 给FloatBuffer对象设置数组, 将开始创建的float数组设置给FloatBuffer对象; * f.
为了避免重复,我们会创建一个单独的类用于封装实际的顶点数组,新的类结构如下图所示: Table用于存储桌子的顶点数据,Mallet用于存储木槌的顶点数据,VertexArray用于存储实际的FloatBuffer 我们先从VertexArray开始,新建一个VertexArray类,并加入以下代码: class VertexArray(vertexData:FloatArray) { private var floatBuffer : FloatBuffer init { floatBuffer= ByteBuffer .allocateDirect(vertexData.size* (dataOffset) glVertexAttribPointer(attributeLocation,componentCount,GL_FLOAT,false,stride,floatBuffer ) glEnableVertexAttribArray(attributeLocation) floatBuffer.position(0) } } 创建一个
final int VERTEX_DIMENSION = 3; private static final int COLOR_DIMENSION = 4; private FloatBuffer vertBuffer; private FloatBuffer colorBuffer; private int aPosition =0;//位置的句柄 private aPosition); GLES30.glDisableVertexAttribArray(aColor); } } 复制代码 ---- 2.2 缓冲数据 float数组需要通过FloatBuffer 进行缓冲,以提高效率 /** * float数组缓冲数据 * * @param vertexs 顶点 * @return 获取浮点形缓冲数据 */ public static FloatBuffer getFloatBuffer(float[] vertexs) { FloatBuffer buffer; ///每个浮点数:坐标个数* 4字节 ByteBuffer qbb
它的使用方法大致都一样,抽出公共的模板: // 声明一个字节缓冲区 FloatBuffer private FloatBuffer floatBuffer; // 定义顶点数据 float[] vertexData = new float[16]; // FloatBuffer 初始化工作并放入顶点数据 floatBuffer = ByteBuffer 接下来asFloatBuffer方法可以得到一个反映底层字节的 FloatBuffer 类实例,避免直接操作单独的字节,而是使用浮点数。 dataOffset); glVertexAttribPointer(attributeLocation, componentCount, GL_FLOAT, false, stride, floatBuffer ); glEnableVertexAttribArray(attributeLocation); floatBuffer.position(0); } 在setVertexAttribPointer
= COORDS_PER_VERTEX * 4; // 4 bytes per vertex private Context context; //位置 private FloatBuffer vertexBuffer; //纹理 private FloatBuffer textureBuffer; private int program; private int import android.opengl.GLES20; import java.nio.ByteBuffer; import java.nio.ByteOrder; import java.nio.FloatBuffer vertexStride = COORDS_PER_VERTEX * 4; // 4 bytes per vertex private Context context; //位置 private FloatBuffer vertexBuffer; //纹理 private FloatBuffer textureBuffer; private int program; private int
02 定义顶点数据 在Android中通常情况下顶点数据的类型是FloatBuffer,定义了3个顶点的Kotlin代码如下: var vertexBuffer = array2Buffer( 0.5f, -0.5f, 0.0f // bottom right ) ) fun array2Buffer(array: FloatArray): FloatBuffer 03 设置attribute数据 设置顶点数据,即将顶点数据从CPU传递到GPU,Kotlin代码如下: fun setAttributePointer(location: Int, buffers: FloatBuffer
()*4,floatBuffer, GL_STATIC_DRAW) //最后一个参数改为偏移值offset glVertexAttribPointer(0, position_component_count projectionMatrix:FloatArray=FloatArray(16)//存储投影矩阵 private val textures=IntArray(3) private var floatBuffer :FloatBuffer private val vao=IntArray(1) private val vbo=IntArray(1) private var bufferY: /16f, 0.0f, 1.0f, // bottom left -1f, 9/16f, 0.0f, 0.0f // top left ) floatBuffer ()*4,floatBuffer, GL_STATIC_DRAW) glVertexAttribPointer(0, position_component_count, GL_FLOAT
floatBuffer = FloatBuffer.wrap(floatValues, 0, desWidth * desHeight * 3); floatBuffer.rewind , 0, 0, desWidth, desHeight); // pixel to data for (int clr : pixels) { floatBuffer.put ((((clr >> 16) & 0xFF) - 128f) / 128f); floatBuffer.put((((clr >> 8) & 0xFF) - 128f) / 128f ); floatBuffer.put(((clr & 0xFF) - 128f) / 128f); } if (bm.isRecycled()) { bm.recycle(); } return floatBuffer.array(); } // compress picture
gl.glClear(GL10.GL_COLOR_BUFFER_BIT); gl.glColor4f(1.0f, 0.0f, 0.0f, 1.0f); FloatBuffer 0.3f, 0f); } 创建一个BufferUtil,目的是吧Array转成buffer static class BufferUtil { public static FloatBuffer mBuffer; public static FloatBuffer floatToBuffer(float[] a) { // 先初始化buffer,数组的长度
import android.view.Surface; import java.nio.ByteBuffer; import java.nio.ByteOrder; import java.nio.FloatBuffer 0f, 1f, 1f, 1f, 0f, 0f, 1f, 0f }; private FloatBuffer vertexBuffer; private FloatBuffer textureBuffer; //mediacodec private int program_mediacodec
java.awt.image.BufferedImage;import java.io.File;import java.io.IOException;import java.nio.ByteBuffer;import java.nio.FloatBuffer INPUT_HEIGHT, INPUT_WIDTH, 3}; // [批次大小, 高度, 宽度, 通道数] return Tensor.create(Float.class, shape, FloatBuffer.wrap float[] probabilities = new float[numClasses]; outputTensor.writeTo(FloatBuffer.wrap
java.awt.image.BufferedImage; import java.io.File; import java.io.IOException; import java.nio.ByteBuffer; import java.nio.FloatBuffer INPUT_HEIGHT, INPUT_WIDTH, 3}; // [批次大小, 高度, 宽度, 通道数] return Tensor.create(Float.class, shape, FloatBuffer.wrap float[] probabilities = new float[numClasses]; outputTensor.writeTo(FloatBuffer.wrap
Buffer的基本概念 Buffer是一个抽象类,对应于Java的主要数据类型,在NIO中有8种缓冲区类,分别是ByteBuffer、CharBuffer、DoubleBuffer、FloatBuffer FloatBuffer:用于单精度浮点数数据的读写。 IntBuffer:用于整数数据的读写。 LongBuffer:用于长整数数据的读写。 ShortBuffer:用于短整数数据的读写。
import android.opengl.GLUtils; import java.nio.ByteBuffer; import java.nio.ByteOrder; import java.nio.FloatBuffer = COORDS_PER_VERTEX * 4; // 4 bytes per vertex private Context context; //位置 private FloatBuffer vertexBuffer; //纹理 private FloatBuffer textureBuffer; private int program; private int