1、VBO
Vertex Buffer object:顶点缓冲对象
2、为什么要用VBO?
不使用VBO时,我们每次绘制( glDrawArrays )图形时都是从本地内存处获取顶点数据然后传输给OpenGL来绘制,这样就会频繁的操作CPU->GPU增大开销,从而降低效率。
使用VBO,我们就能把顶点数据缓存到GPU开辟的一段内存中,然后使用时不必再从本地获取,而是直接从显存中获取,这样就能提升绘制的效率。
3、创建VBO
1、创建VBO
GLES20.glGenBuffers(1, vbos, 0);
2、绑定VBO
GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, vbos[0]);
3、分配VBO需要的缓存大小
GLES20.glBufferData(GLES20.GL_ARRAY_BUFFER, vertex.length * 4,null, GLES20. GL_STATIC_DRAW);
4、为VBO设置顶点数据的值
GLES20.glBufferSubData(GLES20.GL_ARRAY_BUFFER, 0, vertexData.length * 4, vertexBuffer);
5、解绑VBO
GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, 0);
4、使用VBO
1、绑定VBO
GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, vbos[0]);
2、设置顶点数据
GLES20.glVertexAttribPointer(vPosition, 2, GLES20.GL_FLOAT, false, 8, 0);
3、解绑VBO
GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, 0);
public class JfTextureRender implements JfEGLSurfaceView.JfGLRender {
private Context context;
//顶点坐标
private float[] vertexData = {
-1f,-1f,
1f,-1f,
-1f,1f,
1f,1f
};
private FloatBuffer vertexBuffer;
//纹理坐标
private float[] fragmentData = {
// 0f,1f,
// 1f,1f,
// 0f,0f,
// 1f,0f
0f,0.5f,
0.5f,0.5f,
0f,0f,
0.5f,0f
};
private FloatBuffer fragmentBuffer;
private int program;//程序
private int vPosition;//顶点着色器属性
private int fPosition;//片元着色器属性
private int textureId;
private int vboId;
private int sampler;
public JfTextureRender(Context context){
this.context = context;
vertexBuffer = ByteBuffer.allocateDirect(vertexData.length * 4)
.order(ByteOrder.nativeOrder())
.asFloatBuffer()
.put(vertexData);
vertexBuffer.position(0);
fragmentBuffer = ByteBuffer.allocateDirect(fragmentData.length * 4)
.order(ByteOrder.nativeOrder())
.asFloatBuffer()
.put(fragmentData);
fragmentBuffer.position(0);
}
@Override
public void onSurfaceCreated() {
//获取源码
String vertexSource = JfShaderUtil.getRawResource(context,R.raw.vertex_shader);
String fragmentSource = JfShaderUtil.getRawResource(context,R.raw.fragment_shader);
//前6步完成
program = JfShaderUtil.createProgram(vertexSource,fragmentSource);
//得到着色器中的属性
vPosition = GLES20.glGetAttribLocation(program,"v_Position");
fPosition = GLES20.glGetAttribLocation(program,"f_Position");
sampler = GLES20.glGetUniformLocation(program,"sTexture");
//1、创建VBO
int[] vbos = new int[1];
GLES20.glGenBuffers(1, vbos, 0);
vboId = vbos[0];
//2、绑定VBO
GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, vboId);
//3、分配VBO需要的缓存大小
GLES20.glBufferData(GLES20.GL_ARRAY_BUFFER,vertexData.length * 4 + fragmentData.length * 4,null,GLES20. GL_STATIC_DRAW);
//4、为VBO设置顶点数据的值
GLES20.glBufferSubData(GLES20.GL_ARRAY_BUFFER, 0, vertexData.length * 4, vertexBuffer);
GLES20.glBufferSubData(GLES20.GL_ARRAY_BUFFER, vertexData.length * 4, fragmentData.length * 4, fragmentBuffer);
//5、解绑VBO
GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, 0);
//开始绘制纹理,只绘制一个图片纹理
int[] textureIds = new int[1];
GLES20.glGenTextures(1,textureIds,0);//创建纹理
textureId = textureIds[0];
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D,textureId);//绑定纹理
GLES20.glActiveTexture(GLES20.GL_TEXTURE0);
GLES20.glUniform1i(sampler,0);
GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_S, GLES20.GL_REPEAT);
GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_T, GLES20.GL_REPEAT);
GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_LINEAR);
GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_LINEAR);
Bitmap bitmap = BitmapFactory.decodeResource(context.getResources(),R.mipmap.fengjing);
GLUtils.texImage2D(GLES20.GL_TEXTURE_2D,0,bitmap,0);
bitmap.recycle();
bitmap = null;
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D,0);//解绑纹理
}
@Override
public void onSurfaceChanged(int width, int height) {
GLES20.glViewport(0,0,width,height);
}
@Override
public void onDrawFrame() {
GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT);
GLES20.glClearColor(1f,0f,0f,1f);
//使用源程序
GLES20.glUseProgram(program);
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D,textureId);//再次绑定纹理
//1、绑定VBO
GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, vboId);
//使顶点属性数组有效
GLES20.glEnableVertexAttribArray(vPosition);
//为顶点属性赋值
//GLES20.glVertexAttribPointer(vPosition, 2, GLES20.GL_FLOAT, false, 8,vertexBuffer);
GLES20.glVertexAttribPointer(vPosition, 2, GLES20.GL_FLOAT, false, 8,0);
GLES20.glEnableVertexAttribArray(fPosition);
//GLES20.glVertexAttribPointer(fPosition, 2, GLES20.GL_FLOAT, false, 8,fragmentBuffer);
GLES20.glVertexAttribPointer(fPosition, 2, GLES20.GL_FLOAT, false, 8,vertexData.length * 4);
GLES20.glDrawArrays(GLES20.GL_TRIANGLE_STRIP, 0, 4);
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D,0);//再次解绑纹理
//3、解绑VBO
GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, 0);
}
}