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

 

posted on 2025-04-07 22:37  邗影  阅读(24)  评论(0)    收藏  举报

导航