当前位置:实例文章 » 其他实例» [文章]NDK OpenGL与OpenCV实现大眼萌特效

NDK OpenGL与OpenCV实现大眼萌特效

发布人:shili8 发布时间:2024-12-27 11:38 阅读次数:0

**NDK OpenGL 与 OpenCV 实现大眼萌特效**

在本文中,我们将使用 NDK (Native Development Kit) 的 OpenGL 和 OpenCV 库来实现一个大眼萌特效。这个特效会让眼睛变得更加突出和萌萌的。

### **环境准备**

首先,我们需要准备好我们的开发环境。我们需要安装 Android Studio、NDK、OpenCV 和 CMake 等工具。

* 安装 Android Studio* 下载 NDK 并配置环境变量* 下载 OpenCV 库并配置环境变量* 安装 CMake### **项目结构**

下面是我们的项目结构:

project/
src/
main/
cpp/
MyGLSurfaceView.cppMyGLRenderer.cppOpenCVUtil.cppjni/
Android.mkApplication.mkCMakeLists.txtres/
layout/
activity_main.xmlvalues/
strings.xml...


### **MyGLSurfaceView.java**

javapackage com.example.ndk_opengl;

import android.content.Context;
import android.opengl.GLSurfaceView;
import android.util.AttributeSet;

public class MyGLSurfaceView extends GLSurfaceView {

 public MyGLSurfaceView(Context context) {
 super(context);
 }

 public MyGLSurfaceView(Context context, AttributeSet attrs) {
 super(context, attrs);
 }
}


### **MyGLRenderer.java**

javapackage com.example.ndk_opengl;

import android.opengl.GLSurfaceView;
import android.opengl.Matrix;

import javax.microedition.khronos.opengles.GL10;

public class MyGLRenderer implements GLSurfaceView.Renderer {

 private float[] mvpMatrix = new float[16];
 private float[] projectionMatrix = new float[16];

 @Override public void onSurfaceCreated(GL10 gl, int width, int height) {
 // Set up the camera.
 Matrix.setLookAtM(projectionMatrix,0,0,0,0f,0f, -5f,0f,0f,1.0f,0.0f,0.0f);

 // Create a texture and set the texture wrapping parameters.
 gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MIN_FILTER, GL10.GL_LINEAR);
 gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MAG_FILTER, GL10.GL_LINEAR);
 }

 @Override public void onDrawFrame(GL10 gl) {
 // Draw a triangle.
 gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);

 // Set the camera.
 gl.glMatrixMode(GL10.GL_PROJECTION);
 gl.glLoadMatrixf(projectionMatrix,0);

 // Create a vertex buffer object (VBO) and copy the data to it.
 float[] vertices = new float[]{
 -1.0f, -1.0f,
1.0f, -1.0f,
0.0f,1.0f };

 // Create a vertex buffer object (VBO) and copy the data to it.
 int[] vbo = new int[1];
 gl.glGenBuffers(1, vbo,0);
 gl.glBindBuffer(GL10.GL_ARRAY_BUFFER, vbo[0]);
 gl.glBufferData(GL10.GL_ARRAY_BUFFER, vertices.length *4, vertices, GL10.GL_STATIC_DRAW);

 // Create a vertex shader and set the vertex attributes.
 int[] vs = new int[1];
 gl.glGenVertexShaders(vs.length, vs,0);
 gl.glBindVertexShader(vs[0]);
 gl.glShaderOp(GL10.GL_VERTEX_SHADER, GL10.GL_FALSE, vertices.length *4, vertices,2);

 // Create a fragment shader and set the fragment attributes.
 int[] fs = new int[1];
 gl.glGenFragmentShaders(fs.length, fs,0);
 gl.glBindFragmentShader(fs[0]);
 gl.glShaderOp(GL10.GL_FRAGMENT_SHADER, GL10.GL_FALSE, vertices.length *4, vertices,2);

 // Link the shaders.
 gl.glLinkProgram(vs[0], fs[0]);

 // Draw a triangle using the VBO and shader program.
 gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
 gl.glVertexPointer(2, GL10.GL_FLOAT,4 *4, vbo[0]);
 gl.glDrawArrays(GL10.GL_TRIANGLES,0, vertices.length /2);

 // Disable the client state.
 gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
 }

 @Override public void onSurfaceChanged(GL10 gl, int width, int height) {
 // Set up the camera.
 Matrix.setLookAtM(projectionMatrix,0,0,0,0f,0f, -5f,0f,0f,1.0f,0.0f,0.0f);

 // Create a texture and set the texture wrapping parameters.
 gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MIN_FILTER, GL10.GL_LINEAR);
 gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MAG_FILTER, GL10.GL_LINEAR);
 }
}


### **OpenCVUtil.cpp**

cpp#include 

void OpenCVUtil::cvMatToTexture(cv::Mat mat, int* textureId) {
 // Create a texture and set the texture wrapping parameters.
 gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MIN_FILTER, GL10.GL_LINEAR);
 gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MAG_FILTER, GL10.GL_LINEAR);

 // Copy the data to a texture buffer object (TBO).
 int[] tbo = new int[1];
 gl.glGenBuffers(1, tbo,0);
 gl.glBindBuffer(GL10.GL_TEXTURE_BUFFER, tbo[0]);
 gl.glBufferData(GL10.GL_TEXTURE_BUFFER, mat.total() * mat.channels(), mat.data, GL10.GL_STATIC_DRAW);

 // Create a texture and bind it to the TBO.
 int[] tex = new int[1];
 gl.glGenTextures(1, tex,0);
 gl.glBindTexture(GL10.GL_TEXTURE_2D, tex[0]);
 gl.glTexImage2D(GL10.GL_TEXTURE_2D,0, GL10.GL_RGBA, mat.cols(), mat.rows(),0, GL10.GL_BGRA, GL10.GL_UNSIGNED_BYTE, null);

 // Copy the data from the TBO to the texture.
 gl.glCopyTexSubImage2D(GL10.GL_TEXTURE_2D,0,0,0, tbo[0],0, mat.cols(), mat.rows());

 // Unbind the TBO and texture.
 gl.glBindBuffer(GL10.GL_TEXTURE_BUFFER,0);
 gl.glBindTexture(GL10.GL_TEXTURE_2D,0);

 // Store the texture ID.
 *textureId = tex[0];
}


### **Android.mk**

makefileLOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)
LOCAL_MODULE := MyGLSurfaceViewLOCAL_SRC_FILES := MyGLSurfaceView.cppLOCAL_LDLIBS := -lloginclude $(BUILD_SHARED_LIBRARY)


### **Application.mk**

makefileAPP_ABI := armeabi-v7a


### **CMakeLists.txt**

cmakecmake_minimum_required(VERSION3.10)

project(MyGLSurfaceView)

find_package(OpenCV REQUIRED)

add_library(MyGLSurfaceView SHARED MyGLSurfaceView.cpp)
target_link_libraries(MyGLSurfaceView ${OpenCV_LIBS})


### **activity_main.xml**

xml


 




### **strings.xml**

xml<?xml version="1.0" encoding="utf-8"?>
<resources>

 <string name="app_name">MyGLSurfaceView</string>

</resources>


### **AndroidManifest.xml**

xml<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android=" /> package="com.example.ndk_opengl">

 <application android:allowBackup="true"
 android:icon="@mipmap/ic_launcher"
 android:label="@string/app_name"
 android:supportsRtl="true"
 android:theme="@style/AppTheme">

 <activity android:name=".MainActivity"
 android:exported="true">
 <intent-filter>
 <action android:name="android.intent.action.MAIN" />
 <category android:name="android.intent.category.LAUNCHER" />
 </intent-filter>
 </activity>

 </application>

</manifest>


### **MainActivity.java

其他信息

其他资源

Top