Android视频采集渲染学习(2)
1 简单的着色器编程;(代码跟随慕课网站OpenGL学习,如有侵权请立即联系)
桌面与移动逻辑相似:涉及顶点,片元着色;着色器程序的创建,指定源码,编译,绑定,使用;数据通过属性函数传递给着色器入口;
package com.example.glestest import android.opengl.GLSurfaceView import android.os.Bundle import androidx.appcompat.app.AppCompatActivity import androidx.core.view.ViewCompat import androidx.core.view.WindowInsetsCompat import com.example.android.camera2.myglsurfaceview.MyGLSurfaceView class MainActivity : AppCompatActivity() { private lateinit var glview:GLSurfaceView; override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) glview =MyGLSurfaceView(this) setContentView(/* view = */ this.glview) } }
package com.example.android.camera2.myglsurfaceview import android.content.Context import javax.microedition.khronos.egl.EGLConfig import javax.microedition.khronos.opengles.GL10 import android.opengl.GLES30 import android.opengl.GLSurfaceView import com.example.glestest.triangre class MyGLSurfaceView : GLSurfaceView { constructor(context: Context) : super(context) { //使用的OpenGL ES 版本 setEGLContextClientVersion(3) //为GLSurfaceView设置Renderer,在该函数中会启动一个新的线程来构造EGL环境 setRenderer(MyGLRenderer()) } } class MyGLRenderer : GLSurfaceView.Renderer { private lateinit var trangle:triangre; override fun onSurfaceCreated(gl: GL10?, config: EGLConfig?) { //设置OpenGL ES清屏色为红色, R,G,B,A GLES30.glClearColor(1.0f, 1.0f, 1.0f, .5f) trangle =triangre(); } override fun onSurfaceChanged(gl: GL10?, width: Int, height: Int) { //设置OpenGLES的视口大小 GLES30.glViewport(0, 0, width, height) } override fun onDrawFrame(gl: GL10?) { //清空当前缓冲区的颜色缓冲区 GLES30.glClear(GLES30.GL_COLOR_BUFFER_BIT) trangle.Draw(); } }
package com.example.glestest import android.opengl.GLES30 import java.nio.ByteBuffer import java.nio.ByteOrder import java.nio.FloatBuffer class triangre { private var program = 0; private var positionHandle = 0; private var colorHandle = 0; //着色器 private val vertexShaderCode = "attribute vec4 vPosition;" + "void main() {" + " gl_Position = vPosition;" + "}" private val fragmentShaderCode = "precision mediump float;" + "uniform vec4 vColor;" + "void main() {" + " gl_FragColor = vColor;" + "}" //顶点坐标(系统坐标系 -1~1) private val triangleCoords = floatArrayOf( 0.0f, 0.5f, 0.0f, -0.5f, -0.5f, 0.0f, 0.5f, -0.5f, 0.0f) private val color = floatArrayOf(0.5f, 0.5f, 0.5f, 1.0f)//颜色数据 private lateinit var vertexBuf:FloatBuffer; private fun loadshader(type: Int,shadercode:String):Int{ val shader =GLES30.glCreateShader(type); GLES30.glShaderSource(shader,shadercode); GLES30.glCompileShader(shader); return shader; } constructor(){ //分配GPU可访问内存的操作是用ByteBuffer.allocate分配一段Native内存(直接缓冲),GPU 可以直接访问(DMA) // 他是直接内存,不是VBO val buf = ByteBuffer.allocateDirect(triangleCoords.size*4);//开辟空间;顶点数据 buf.order(ByteOrder.nativeOrder());//设置字节序 vertexBuf =buf.asFloatBuffer(); vertexBuf.put(triangleCoords);//CPU 拷贝到GPU可访问的存储位置 vertexBuf.position(0);//从头读数据 //创建着色器,指定源码,编译,绑定(attach),链接 val vertexShader = loadshader(GLES30.GL_VERTEX_SHADER,vertexShaderCode); val fregmentShader = loadshader(GLES30.GL_FRAGMENT_SHADER,fragmentShaderCode); //绑定 program = GLES30.glCreateProgram(); GLES30.glAttachShader(program,vertexShader); GLES30.glAttachShader(program,fregmentShader); //链接 GLES30.glLinkProgram(program); } fun Draw(){ //使用program GLES30.glUseProgram(program); //数据传给着色器 positionHandle= GLES30.glGetAttribLocation(program,"vPosition");//接入点 GLES30.glEnableVertexAttribArray(positionHandle); GLES30.glVertexAttribPointer(positionHandle,3,GLES30.GL_FLOAT,false,0,vertexBuf); colorHandle =GLES30.glGetUniformLocation(program,"vColor"); GLES30.glUniform4fv(colorHandle,1,color,0) //h绘制 GLES30.glDrawArrays(GLES30.GL_TRIANGLES,0,triangleCoords.size/3); //释放顶点资源 GLES30.glDisableVertexAttribArray(positionHandle) } }
plugins { id 'com.android.application' id 'org.jetbrains.kotlin.android' } android { namespace 'com.example.android.camera2.myglsurfaceview' compileSdk 33 defaultConfig { applicationId "com.example.android.camera2.myglsurfaceview" minSdk 25 targetSdk 33 versionCode 1 versionName "1.0" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" } buildTypes { release { minifyEnabled false proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' } } compileOptions { sourceCompatibility JavaVersion.VERSION_1_8 targetCompatibility JavaVersion.VERSION_1_8 } kotlinOptions { jvmTarget = '1.8' } buildToolsVersion '33.0.0' ndkVersion '21.4.7075529' } dependencies { implementation 'androidx.core:core-ktx:1.8.0' implementation 'androidx.appcompat:appcompat:1.6.1' implementation 'com.google.android.material:material:1.5.0' implementation 'androidx.constraintlayout:constraintlayout:2.1.4' testImplementation 'junit:junit:4.13.2' androidTestImplementation 'androidx.test.ext:junit:1.1.5' androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.1' } //build.gradle

浙公网安备 33010602011771号