Android最全Android OpenGLES + Camera1 相机预览,2024年最新android ui界面设计

小结

有了这么多优秀的开发工具,可以做出更高质量的Android应用。

当然了,“打铁还需自身硬”,想要写出优秀的代码,最重要的一点还是自身的技术水平,不然用再好的工具也不能发挥出它的全部实力。

在这里我也分享一份大佬自己收录整理的Android学习PDF+架构视频+面试文档+源码笔记,还有高级架构技术进阶脑图、Android开发面试专题资料,高级进阶架构资料这些都是我闲暇还会反复翻阅的精品资料。在脑图中,每个知识点专题都配有相对应的实战项目,可以有效的帮助大家掌握知识点。

总之也是在这里帮助大家学习提升进阶,也节省大家在网上搜索资料的时间来学习,也可以分享给身边好友一起学习

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化学习资料的朋友,可以戳这里获取

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

  • 尺寸
    */
    private int width;
    private int height;

/**

  • 是否绑定Fbo
    */
    private boolean isBindFbo = false;

/**

  • 着色器顶点坐标位置
    */
    private int aPosLocation;

/**

  • 着色器纹理坐标位置
    */
    private int aCoordinateLocation;

/**

  • 着色器纹理位置
    */
    private int uSamplerLocation;

/**

  • 是否执行了onCreate
    */
    private boolean isCreate = false;

/**

  • 是否执行了onChange
    */
    private boolean isChange = false;

public BaseRender(Context context) {
this(context, “render/base/base/vertex.frag”, “render/base/base/frag.frag”);
}

public BaseRender(Context context, String vertexFilename, String fragFilename) {
this.context = context;
this.vertexFilename = vertexFilename;
this.fragFilename = fragFilename;
}

@Override
public void onCreate() {
if (isCreate) {
return;
}
onCreatePre();
onClearColor();
onInitBlend();
onInitVertexBuffer();
onInitCoordinateBuffer();
onInitVbo();
onInitProgram();
onCreateAfter();
isCreate = true;
}

@Override
public void onChange(int width, int height) {
if (isChange) {
return;
}
onChangePre();
setWidth(width);
setHeight(height);
onViewport();
onInitFbo();
onChangeAfter();
isChange = true;
}

@Override
public void onDraw(int textureId) {
if (!onReadyToDraw()) {
return;
}
onDrawPre();
onClear();
onUseProgram();
onInitLocation();
onBindFbo();
onBindVbo();
onActiveTexture(textureId);
onEnableVertexAttributeArray();
onSetVertexData();
onSetCoordinateData();
onSetOtherData();
onDraw();
onDisableVertexAttributeArray();
onUnBind();
onDrawAfter();
}

@Override
public void onRelease() {
onDeleteProgram(program);
onDeleteShader(vertexShader);
onDeleteShader(fragShader);
onDeleteTexture(textureId);
onDeleteTexture(fboTextureId);
onDeleteFbo(fboId);
onDeleteVbo(vboId);
}

/**

  • 创建之前
    */
    public void onCreatePre() {

}

/**

  • 设置背景颜色
    */
    public void onClearColor() {
    GLES20.glClearColor(0, 0, 0, 1);
    }

/**

  • 是否启用混色
    */
    public boolean onEnableBlend() {
    return false;
    }

/**

  • 初始化混色
    */
    private void onInitBlend() {
    if (!onEnableBlend()) {
    return;
    }
    GLES20.glEnable(GLES20.GL_BLEND);
    GLES20.glBlendFunc(GLES20.GL_SRC_ALPHA, GLES20.GL_ONE_MINUS_SRC_ALPHA);
    }

/**

  • 初始化顶点坐标
    */
    public void onInitVertexBuffer() {
    vertexBuffer = OpenGLESUtils.getSquareVertexBuffer();
    }

/**

  • 初始化纹理坐标
    */
    public void onInitCoordinateBuffer() {
    if (isBindFbo) {
    coordinateBuffer = OpenGLESUtils.getSquareCoordinateReverseBuffer();
    } else {
    coordinateBuffer = OpenGLESUtils.getSquareCoordinateBuffer();
    }
    }

/**

  • 初始化Vbo
    */
    public void onInitVbo() {
    vboId = OpenGLESUtils.getVbo(vertexBuffer, coordinateBuffer);
    }

/**

  • 初始化Program
    */
    public void onInitProgram() {
    String vertexShaderCode = OpenGLESUtils.getShaderCode(context, vertexFilename);
    String fragShaderCode = OpenGLESUtils.getShaderCode(context, fragFilename);

vertexShader = OpenGLESUtils.loadShader(GLES20.GL_VERTEX_SHADER, vertexShaderCode);
fragShader = OpenGLESUtils.loadShader(GLES20.GL_FRAGMENT_SHADER, fragShaderCode);

program = OpenGLESUtils.linkProgram(vertexShader, fragShader);
}

/**

  • 创建之后
    */
    public void onCreateAfter() {

}

/**

  • 设置尺寸之前
    */
    public void onChangePre() {

}

/**

  • 设置窗口尺寸
    */
    public void onViewport() {
    GLES20.glViewport(0, 0, width, height);
    }

/**

  • 初始化Fbo
    */
    public void onInitFbo() {
    if (!isBindFbo) {
    return;
    }
    int[] fboData = OpenGLESUtils.getFbo(width, height);
    fboId = fboData[0];
    fboTextureId = fboData[1];
    }

/**

  • 设置尺寸之后
    */
    public void onChangeAfter() {

}

/**

  • 绘制之前的准备
    */
    public boolean onReadyToDraw() {
    return true;
    }

/**

  • 绘制之前
    */
    public void onDrawPre() {

}

/**

  • 清屏
    */
    public void onClear() {
    GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT);
    }

/**

  • 使用Program
    */
    public void onUseProgram() {
    GLES20.glUseProgram(program);
    }

/**

  • 初始化着色器各个位置
    */
    public void onInitLocation() {
    aPosLocation = GLES20.glGetAttribLocation(program, “aPos”);
    aCoordinateLocation = GLES20.glGetAttribLocation(program, “aCoordinate”);
    uSamplerLocation = GLES20.glGetUniformLocation(program, “uSampler”);
    }

/**

  • 绑定Fbo
    */
    public void onBindFbo() {
    if (!isBindFbo) {
    return;
    }
    GLES20.glBindFramebuffer(GLES20.GL_FRAMEBUFFER, fboId);
    GLES20.glFramebufferTexture2D(GLES20.GL_FRAMEBUFFER, GLES20.GL_COLOR_ATTACHMENT0,
    GLES20.GL_TEXTURE_2D, fboTextureId, 0);
    GLES20.glViewport(0, 0, width, height);
    }

/**

  • 绑定Vbo
    */
    public void onBindVbo() {
    GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, vboId);
    }

/**

  • 激活并绑定纹理
    */
    public void onActiveTexture(int textureId) {
    this.textureId = textureId;
    GLES20.glActiveTexture(GLES20.GL_TEXTURE0);
    GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, textureId);
    GLES20.glUniform1i(uSamplerLocation, 0);
    }

/**

  • 启用顶点坐标
    */
    public void onEnableVertexAttributeArray() {
    GLES20.glEnableVertexAttribArray(aPosLocation);
    GLES20.glEnableVertexAttribArray(aCoordinateLocation);
    }

/**

  • 设置顶点坐标
    */
    public void onSetVertexData() {
    GLES20.glVertexAttribPointer(aPosLocation, vertexSize, GLES20.GL_FLOAT, false, vertexStride, 0);
    }

/**

  • 设置纹理坐标
    */
    public void onSetCoordinateData() {
    GLES20.glVertexAttribPointer(aCoordinateLocation, coordinateSize, GLES20.GL_FLOAT, false, coordinateStride, vertexBuffer.limit() * 4);
    }

/**

  • 设置其他数据
    */
    public void onSetOtherData() {

}

/**

  • 绘制
    */
    public void onDraw() {
    GLES20.glDrawArrays(GLES20.GL_TRIANGLE_STRIP, 0, vertexCount);
    }

/**

  • 禁用顶点坐标
    */
    public void onDisableVertexAttributeArray() {
    GLES20.glDisableVertexAttribArray(aPosLocation);
    GLES20.glDisableVertexAttribArray(aCoordinateLocation);
    }

/**

  • 解除绑定
    */
    public void onUnBind() {
    GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, 0);
    GLES20.glBindFramebuffer(GLES20.GL_FRAMEBUFFER, 0);
    GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, 0);
    }

/**

  • 绘制之后
    */
    public void onDrawAfter() {

}

/**

  • 删除Program
    */
    public void onDeleteProgram(int program) {
    GLES20.glDeleteProgram(program);
    }

/**

  • 删除Shader
    */
    public void onDeleteShader(int shader) {
    GLES20.glDeleteShader(shader);
    }

/**

  • 删除纹理
    */
    public void onDeleteTexture(int textureId) {
    GLES20.glDeleteTextures(1, new int[]{textureId}, 0);
    }

/**

  • 删除Fbo
    */
    public void onDeleteFbo(int fboId) {
    GLES20.glDeleteFramebuffers(1, new int[]{fboId}, 0);
    }

/**

  • 删除Vbo
    */
    public void onDeleteVbo(int vboId) {
    GLES20.glDeleteBuffers(1, new int[]{vboId}, 0);
    }

public Context getContext() {
return context;
}

public void setContext(Context context) {
this.context = context;
}

public FloatBuffer getVertexBuffer() {
return vertexBuffer;
}

public void setVertexBuffer(FloatBuffer vertexBuffer) {
this.vertexBuffer = vertexBuffer;
}

public FloatBuffer getCoordinateBuffer() {
return coordinateBuffer;
}

public void setCoordinateBuffer(FloatBuffer coordinateBuffer) {
this.coordinateBuffer = coordinateBuffer;
}

public int getVertexSize() {
return vertexSize;
}

public void setVertexSize(int vertexSize) {
this.vertexSize = vertexSize;
}

public int getCoordinateSize() {
return coordinateSize;
}

public void setCoordinateSize(int coordinateSize) {
this.coordinateSize = coordinateSize;
}

public int getVertexStride() {
return vertexStride;
}

public void setVertexStride(int vertexStride) {
this.vertexStride = vertexStride;
}

public int getCoordinateStride() {
return coordinateStride;
}

public void setCoordinateStride(int coordinateStride) {
this.coordinateStride = coordinateStride;
}

public int getVertexCount() {
return vertexCount;
}

public void setVertexCount(int vertexCount) {
this.vertexCount = vertexCount;
}

public int getCoordinateCount() {
return coordinateCount;
}

public void setCoordinateCount(int coordinateCount) {
this.coordinateCount = coordinateCount;
}

public int getProgram() {
return program;
}

public void setProgram(int program) {
this.program = program;
}

public int getFboTextureId() {
return fboTextureId;
}

public void setFboTextureId(int fboTextureId) {
this.fboTextureId = fboTextureId;
}

public int getFboId() {
return fboId;
}

public void setFboId(int fboId) {
this.fboId = fboId;
}

public int getVboId() {
return vboId;
}

public void setVboId(int vboId) {
this.vboId = vboId;
}

public String getVertexFilename() {
return vertexFilename;
}

public void setVertexFilename(String vertexFilename) {
this.vertexFilename = vertexFilename;
}

public String getFragFilename() {
return fragFilename;
}

public void setFragFilename(String fragFilename) {
this.fragFilename = fragFilename;
}

public int getWidth() {
return width;
}

public void setWidth(int width) {
this.width = width;
}

public int getHeight() {
return height;
}

public void setHeight(int height) {
this.height = height;
}

public boolean isBindFbo() {
return isBindFbo;
}

public void setBindFbo(boolean bindFbo) {
isBindFbo = bindFbo;
}

public int getPosLocation() {
return aPosLocation;
}

public void setPosLocation(int aPosLocation) {
this.aPosLocation = aPosLocation;
}

public int getCoordinateLocation() {
return aCoordinateLocation;
}

public void setCoordinateLocation(int aCoordinateLocation) {
this.aCoordinateLocation = aCoordinateLocation;
}

public int getSamplerLocation() {
return uSamplerLocation;
}

public void setSamplerLocation(int uSamplerLocation) {
this.uSamplerLocation = uSamplerLocation;
}

public boolean isCreate() {
return isCreate;
}

public void setCreate(boolean create) {
isCreate = create;
}

public boolean isChange() {
return isChange;
}

public void setChange(boolean change) {
isChange = change;
}

public BaseRenderBean getRenderBean() {
return renderBean;
}

public void setRenderBean(BaseRenderBean renderBean) {
this.renderBean = renderBean;
}

public void updateRenderBean(BaseRenderBean renderBean) {
setRenderBean(renderBean);
}
}

代码有点长,但是里面尽可能地考虑到了渲染和扩展的需求

顶点着色器 vertex.frag

attribute vec4 aPos;
attribute vec2 aCoordinate;
varying vec2 vCoordinate;
void main(){
vCoordinate = aCoordinate;
gl_Position = aPos;
}

片元着色器 frag.frag

precision mediump float;
uniform sampler2D uSampler;
varying vec2 vCoordinate;
void main(){
gl_FragColor = texture2D(uSampler, vCoordinate);
}

注意到,里面有用到一个工具类OpenGLESUtils和实体类BaseRenderBean具体就不贴出来了,可以到Github上查看

四、BaseOesRender

注意到,BaseRender里面绑定的纹理是2D纹理,而如果想实现相机预览,则需要使用Oes纹理,所以需要创建一个BaseOesRender为相机做渲染

package com.yk.media.opengles.render.base;

import android.content.Context;
import android.graphics.SurfaceTexture;
import android.opengl.GLES11Ext;
import android.opengl.GLES20;

import com.yk.media.utils.OpenGLESUtils;

public class BaseOesRender extends BaseRender {
/**

  • oes纹理id
    */
    private int oesTextureId;

/**

  • 顶点变换矩阵位置
    */
    private int uMatrixLocation;

/**

  • 纹理变换矩阵位置
    */
    private int uOesMatrixLocation;

/**

  • oes尺寸
    */
    private int oesW = -1;
    private int oesH = -1;

/**

  • 顶点变换矩阵
    */
    private float[] mMVPMatrix = new float[16];

/**

  • 纹理变换矩阵
    */
    private float[] mOesMatrix = {
    1, 0, 0, 0,
    0, 1, 0, 0,
    0, 0, 1, 0,
    0, 0, 0, 1
    };

/**

  • 是否准备好绘制
    */
    private boolean isReadyToDraw = false;

/**

  • SurfaceTexture
    */
    private SurfaceTexture surfaceTexture;

/**

  • SurfaceTexture回调
    */
    private OnSurfaceTextureListener onSurfaceTextureListener;

public BaseOesRender(Context context) {
super(context, “render/base/oes/vertex.frag”, “render/base/oes/frag.frag”);
setBindFbo(true);
oesTextureId = OpenGLESUtils.getOesTexture();
}

@Override
public void onInitCoordinateBuffer() {
setCoordinateBuffer(OpenGLESUtils.getSquareCoordinateBuffer());
}

@Override
public boolean onReadyToDraw() {
if (!isReadyToDraw) {
if (onSurfaceTextureListener != null) {
if (surfaceTexture != null) {
surfaceTexture.release();
surfaceTexture = null;
}
surfaceTexture = new SurfaceTexture(oesTextureId);
onSurfaceTextureListener.onSurfaceTexture(surfaceTexture);
isReadyToDraw = true;
} else if (surfaceTexture != null) {
surfaceTexture.attachToGLContext(oesTextureId);
isReadyToDraw = true;
} else {
return false;
}
}
return oesW != -1 && oesH != -1;
}

@Override
public void onDrawPre() {
super.onDrawPre();
mMVPMatrix = OpenGLESUtils.getMatrix(getWidth(), getHeight(), oesW, oesH);

surfaceTexture.updateTexImage();

float[] oesMatrix = new float[16];
surfaceTexture.getTransformMatrix(oesMatrix);
if (!OpenGLESUtils.isIdentityM(oesMatrix)) {
mOesMatrix = oesMatrix;
}
}

@Override
public void onInitLocation() {
super.onInitLocation();
uMatrixLocation = GLES20.glGetUniformLocation(getProgram(), “uMatrix”);
uOesMatrixLocation = GLES20.glGetUniformLocation(getProgram(), “uOesMatrix”);
}

@Override
public void onActiveTexture(int textureId) {
GLES20.glActiveTexture(GLES20.GL_TEXTURE0);
GLES20.glBindTexture(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, textureId);
GLES20.glUniform1i(getSamplerLocation(), 0);
}

@Override
public void onSetOtherData() {
super.onSetOtherData();
GLES20.glUniformMatrix4fv(uMatrixLocation, 1, false, mMVPMatrix, 0);
GLES20.glUniformMatrix4fv(uOesMatrixLocation, 1, false, mOesMatrix, 0);
}

@Override
public void onRelease() {
super.onRelease();
onDeleteTexture(oesTextureId);
}

/**

  • 绘制
    */
    public void onDrawSelf() {
    super.onDraw(oesTextureId);
    }

/**

  • 设置oes尺寸
    */
    public void setOesSize(int width, int height) {
    oesW = width;
    oesH = height;
    }

/**

  • 设置SurfaceTexture
    */
    public void setSurfaceTexture(SurfaceTexture surfaceTexture) {
    this.surfaceTexture = surfaceTexture;
    isReadyToDraw = false;
    }

/**

  • 设置SurfaceTexture回调
    */
    public void setOnSurfaceTextureListener(OnSurfaceTextureListener onSurfaceTextureListener) {
    this.onSurfaceTextureListener = onSurfaceTextureListener;
    isReadyToDraw = false;
    }
    }

顶点着色器 vertex.frag

attribute vec4 aPos;
attribute vec4 aCoordinate;
uniform mat4 uMatrix;
uniform mat4 uOesMatrix;
varying vec2 vCoordinate;
void main(){
vCoordinate = (uOesMatrix * aCoordinate).xy;
gl_Position = uMatrix * aPos;
}

片元着色器 frag.frag

#extension GL_OES_EGL_image_external:require
precision mediump float;
uniform samplerExternalOES uSampler;
varying vec2 vCoordinate;
void main(){
gl_FragColor = texture2D(uSampler, vCoordinate);
}

BaseOesRender是继承BaseRender

推荐学习资料

  • Android进阶学习全套手册

  • Android对标阿里P7学习视频

  • BAT TMD大厂Android高频面试题

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化学习资料的朋友,可以戳这里获取

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

vCoordinate;
void main(){
vCoordinate = (uOesMatrix * aCoordinate).xy;
gl_Position = uMatrix * aPos;
}

片元着色器 frag.frag

#extension GL_OES_EGL_image_external:require
precision mediump float;
uniform samplerExternalOES uSampler;
varying vec2 vCoordinate;
void main(){
gl_FragColor = texture2D(uSampler, vCoordinate);
}

BaseOesRender是继承BaseRender

推荐学习资料

  • Android进阶学习全套手册

    [外链图片转存中…(img-jTJeaZeA-1715225481679)]

  • Android对标阿里P7学习视频

    [外链图片转存中…(img-dOzzb3gR-1715225481679)]

  • BAT TMD大厂Android高频面试题

[外链图片转存中…(img-GdW7yXLl-1715225481680)]

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化学习资料的朋友,可以戳这里获取

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

  • 3
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: OpenGL ES是一种用于开发图形应用程序的开放式图形编程接口。它被广泛用于Android系统上的游戏开发以及其他需要高性能图形渲染的应用程序中。下面是关于OpenGL ESAndroid开发中的一些要点: 1. OpenGL ES的版本:Android支持多个不同版本的OpenGL ES,如OpenGL ES 1.0、1.1、2.0和3.0。开发者根据自己的需求选择合适的版本。 2. 渲染管线:OpenGL ES使用可编程的渲染管线来处理图形渲染。开发者可以通过创建顶点着色器和片段着色器程序来自定义渲染过程,从而实现各种效果。 3. 缓冲对象:开发者可以使用OpenGL ES来创建和管理缓冲对象,如顶点缓冲对象(VBO)和帧缓冲对象(FBO)。这些缓冲对象用于存储图形数据,提高绘制效率。 4. 纹理映射:OpenGL ES允许开发者将纹理映射到三维对象上,以实现更加逼真的图形效果。开发者可以通过加载纹理图像并将其映射到顶点上来创建细节丰富的模型。 5. 事件处理:OpenGL ES提供了一些函数来处理触摸事件、加速度计变化等输入信息。开发者可以使用这些函数来实现交互式的图形应用程序。 6. OpenGL ES的集成:在Android开发中,开发者可以通过GLSurfaceView类来集成OpenGL ES。GLSurfaceView是Android提供的一个用于显示OpenGL ES图形的视图类。 总结来说,OpenGL ESAndroid开发中用于实现高性能图形渲染的重要工具。开发者可以利用它来创建各种各样的游戏和图形应用程序,并通过自定义着色器和纹理映射等技术来增加细节和逼真度。 ### 回答2: OpenGLES是一种用于开发移动设备和嵌入式系统的图形渲染API,它主要用于在Android平台上开发游戏和图形应用程序。使用OpenGLES,开发者可以利用硬件加速的图形渲染功能,提供流畅的图形效果和高性能的图形渲染。 在Android平台上进行OpenGLES开发,首先需要在应用程序中引入OpenGLES库文件,并进行相关的环境设置。然后,开发者可以使用OpenGLES API提供的各种函数和方法来创建图形对象、设置渲染状态、进行变换和纹理映射等操作。同时,还可以使用OpenGLES提供的着色器语言,自定义渲染管线,实现更高级的图形效果。 在开发过程中,需要注意OpenGLES使用的坐标系统是以屏幕为中心的坐标系,而不是传统的以左上角为原点的坐标系。因此,在创建图形对象时,需要进行坐标转换。此外,还需要注意管理资源和内存,避免内存泄漏和资源浪费。 在实际开发中,可以利用OpenGLES创建各种图形效果,如平面、立体、光照、阴影等。同时,还可以通过OpenGLES实现用户交互,如触摸屏幕,操作物体的变换等。此外,还可以使用OpenGLES与其他Android组件进行交互,如利用OpenGL ES绘制图像进行相机预览、视频播放等。 总之,OpenGLESAndroid开发中具有重要的作用,能够实现高性能的图形渲染和丰富的图形效果,为开发者提供了强大的工具和技术支持。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值