创建OpenGLES视口
1.App窗口改成OpenGL窗口,是通过java调用C++,在以下位置修改如下内容
package com.example.learnogles;import androidx.appcompat.app.AppCompatActivity;import android.content.Context;
import android.opengl.GLSurfaceView;
import android.os.Bundle;
import android.util.Log;
import android.widget.TextView;import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10;class HangyuGLSurfaceViewRenderer implements GLSurfaceView.Renderer{public void onSurfaceCreated(GL10 gl, EGLConfig config){//视口初始化时gl.glClearColor(0.1f,0.4f,0.6f,1.0f);}public void onSurfaceChanged(GL10 gl, int width, int height){//视口改变时gl.glViewport(0,0,width,height);//左下角是0,0,Viewport相当于画布,需要摆放在视口的什么位置}public void onDrawFrame(GL10 gl){//绘制时候gl.glClear(gl.GL_COLOR_BUFFER_BIT|gl.GL_DEPTH_BUFFER_BIT|gl.GL_STENCIL_BUFFER_BIT);//擦除颜色缓冲区}
}class HnagyuGLSurfaceView extends GLSurfaceView{ //重载GLSurfaceViewGLSurfaceView.Renderer mRenderer;//渲染器public HnagyuGLSurfaceView(Context context){super(context);setEGLContextClientVersion(2);//设置openGLES的版本号mRenderer = new HangyuGLSurfaceViewRenderer();//生成一个渲染器setRenderer(mRenderer);//设置渲染器}
}public class MainActivity extends AppCompatActivity {// Used to load the 'native-lib' library on application startup.static {System.loadLibrary("baohangyu"); //会加载动态库}HnagyuGLSurfaceView mGLview;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);mGLview = new HnagyuGLSurfaceView(getApplication());//new一个视口setContentView(mGLview);//设置渲染视口}/*** A native method that is implemented by the 'native-lib' native library,* which is packaged with this application.*/public native String stringFromJNI();public native int Test();public native int TestLive();
}
使用NDK来写OpenGLES代码
1.首先需要先把相关头文件加入到指定位置
#pragma once#include <stdio.h>
#include <string.h>
#include <jni.h>
#include <iostream>
#include <GLES2/gl2.h>
#include <GLES2/gl2ext.h>
#include <GLES2/gl2platform.h>
2.在 MainActivity.java 中调用C++API接口
package com.example.learnogles;import androidx.appcompat.app.AppCompatActivity;import android.content.Context;
import android.opengl.GLSurfaceView;
import android.os.Bundle;
import android.util.Log;
import android.widget.TextView;import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10;class HangyuGLSurfaceViewRenderer implements GLSurfaceView.Renderer{public void onSurfaceCreated(GL10 gl, EGLConfig config){//视口初始化时MainActivity.Instance().Init();}public void onSurfaceChanged(GL10 gl, int width, int height){//视口改变时MainActivity.Instance().OnViewportChanged(width, height);}public void onDrawFrame(GL10 gl){//绘制时候MainActivity.Instance().Render();}
}class HnagyuGLSurfaceView extends GLSurfaceView{ //重载GLSurfaceViewGLSurfaceView.Renderer mRenderer;//渲染器public HnagyuGLSurfaceView(Context context){super(context);setEGLContextClientVersion(2);//设置openGLES的版本号mRenderer = new HangyuGLSurfaceViewRenderer();//生成一个渲染器setRenderer(mRenderer);//设置渲染器}
}public class MainActivity extends AppCompatActivity {// Used to load the 'native-lib' library on application startup.static {System.loadLibrary("baohangyu"); //会加载动态库}static MainActivity mSelf;HnagyuGLSurfaceView mGLview;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);mSelf = this;mGLview = new HnagyuGLSurfaceView(getApplication());//new一个视口setContentView(mGLview);//设置渲染视口}public static MainActivity Instance(){//实例化方法return mSelf;}/*** A native method that is implemented by the 'native-lib' native library,* which is packaged with this application.*///OpenGLES C++接口public native void Init();public native void OnViewportChanged(int width, int height);public native void Render();}
3.cmake需要添加如下配置
# For more information about using CMake with Android Studio, read the
# documentation: https://d.android.com/studio/projects/add-native-code.html# Sets the minimum version of CMake required to build the native library.cmake_minimum_required(VERSION 3.10.2)# Declares and names the project.project("learnogles")# Creates and names a library, sets it as either STATIC
# or SHARED, and provides the relative paths to its source code.
# You can define multiple libraries, and CMake builds them for you.
# Gradle automatically packages shared libraries with your APK.add_library( # Sets the name of the library.baohangyu #baohangyu.so# Sets the library as a shared library.SHARED# Provides a relative path to your source file(s).Sence.cppnative-lib.cpp )# Searches for a specified prebuilt library and stores the path as a
# variable. Because CMake includes system libraries in the search path by
# default, you only need to specify the name of the public NDK library
# you want to add. CMake verifies that the library exists before
# completing its build.find_library( # Sets the name of the path variable.log-lib# Specifies the name of the NDK library that# you want CMake to locate.log )# Specifies libraries CMake should link to your target library. You
# can link multiple libraries, such as libraries you define in this
# build script, prebuilt third-party libraries, or system libraries.target_link_libraries( # Specifies the target library.baohangyu# Links the target library to the log library# included in the NDK.${log-lib} android GLESv2 ) #需要添加安卓相关和真正的OPENGL ES版本
4.cpp中的实现
//
// Created by 19691 on 2020/11/11.
//#include "Sence.h"extern "C" JNIEXPORT void JNICALL
Java_com_example_learnogles_MainActivity_Init(JNIEnv* env,jobject) {glClearColor(0.1f,0.4f,0.6f,1.0f);
}extern "C" JNIEXPORT void JNICALL
Java_com_example_learnogles_MainActivity_OnViewportChanged(JNIEnv* env,jobject,jint width,jint height) {glViewport(0,0,width,height);
}extern "C" JNIEXPORT void JNICALL
Java_com_example_learnogles_MainActivity_Render(JNIEnv* env,jobject /* this */) {glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT);
}
创建Assets资源目录
1.在项目目录中app\src\main文件夹下创建assets文件夹,名字唯一
在CPP里打印日志
1.首先在头文件AllHeader.h中加入安卓打印日志的头文件,#include <android/log.h>
2.再加入 #define HANGYU_LOG_TAG "HANGYUOpenGLES"
3.在cpp中可以调用 __android_log_print(ANDROID_LOG_INFO,HANGYU_LOG_TAG,"Render"); 类似这条语句来打印日志,会在Logcat中显示
在NDK层加载外部资源
1.先添加以下头文件
//在NDK层加载外部文件相关
#include <android/asset_manager.h>
#include <android/asset_manager_jni.h>
2.cpp中初始化需要做如下增加
static AAssetManager *sAAssetManager = nullptr;//定义一个资源相关指针变量
extern "C" JNIEXPORT void JNICALL
Java_com_example_learnogles_MainActivity_Init(JNIEnv* env,jobject ,jobject am) {sAAssetManager = AAssetManager_fromJava(env,am);//初始化资源指针__android_log_print(ANDROID_LOG_INFO,HANGYU_LOG_TAG,"Init");glClearColor(0.0f,1.0f,1.0f,0.0f);
}
3.修改java层的C++API接口
public native void Init(AssetManager am);
4.实现加载文件的C++方法
先创建一个Utils类,并且将cpp文件加入cmake的编译列表,以下为方法实现
unsigned char * LoadfileContent(const char *path, int&filesize)
{unsigned char *filecontent= nullptr;filesize = 0;AAsset *asset = AAssetManager_open(sAAssetManager,path,AASSET_MODE_UNKNOWN); //打开资源,其中AAsset是真正的资源if(asset!= nullptr){filesize = AAsset_getLength(asset);filecontent = new unsigned char[filesize+1];AAsset_read(asset,filecontent,filesize);filecontent[filesize]=0;AAsset_close(asset);}return filecontent;
}