小型三维引擎设计实现-app层如何跨平台2
来源:互联网 发布:在线网络理财投资服务 编辑:程序博客网 时间:2024/05/17 02:47
在Android平台下, 有这样两个问题需要解决, 它们和桌面平台有些不一样:
1: 在Android上如何读写文件? 三维程序需要载入模型, 纹理, 着色器脚本等数据, 如何读写这些文件?
2: 如何把第三方库移植到Android平台上, 可以使用CMake? 还是为其编写Android.mk
一: 首先看看如何读写文件的问题:
从数据存放位置来分, 读写文件可以分为两类, 第一类读取assets文件夹内的文件, 第二类是读取sd卡内的文件。 相比较而言, 读取sd卡内的文件要容易一些(可以看成是读取某磁盘目录下的文件), 直接用标准库中的IO函数即可读取。 但是读取assets下的文件就要用到专门的函数了。
读取asset下文件的方法:
(1) :需要头文件: #include <android_native_app_glue.h>
(2): AAssetManager* assetManager = this->mActivity->assetManager; //获取assetManager
(3): AAssetManager_open(...) // 打开文件
(4):AAsset_getBuffer(...) //获取文件内容
(5): AAsset_getLength(...) //获取文件长度
下面看下代码:
#pragma once #include <jni.h>#include <vector>#include <string>#include <android_native_app_glue.h>#include "AndroidLog.h"class AndroidIO{public:AndroidIO(ANativeActivity* activity);bool readText(const char* filename, std::vector<unsigned char>* buffer);~AndroidIO();private:ANativeActivity* mActivity;mutable pthread_mutex_t mMutex;};
#include "AndroidIO.h"#include <fstream>#include <iostream>AndroidIO::AndroidIO(ANativeActivity* activity){pthread_mutex_init(&mMutex, NULL); pthread_mutex_lock(&mMutex); this->mActivity = activity; pthread_mutex_unlock(&mMutex);}bool AndroidIO::readText(const char* filename, std::vector<unsigned char> *buffer){ pthread_mutex_lock(&mMutex); std::ifstream f(filename, std::ios::binary ); if(f) { LOGI( "reading sdcard:%s", filename ); f.seekg( 0, std::ifstream::end ); int32_t fileSize = f.tellg(); f.seekg( 0, std::ifstream::beg ); buffer->reserve( fileSize ); buffer->assign( std::istreambuf_iterator<char>( f ), std::istreambuf_iterator<char>() ); f.close(); pthread_mutex_unlock( &mMutex ); return true; } else { LOGI( "reading assest:%s", filename ); AAssetManager* assetManager = this->mActivity->assetManager; AAsset* assetFile = AAssetManager_open( assetManager, filename, AASSET_MODE_BUFFER ); if( !assetFile ) { pthread_mutex_unlock( &mMutex ); return false; } uint8_t* data = (uint8_t*) AAsset_getBuffer( assetFile ); int32_t size = AAsset_getLength( assetFile ); if( data == NULL ) { AAsset_close( assetFile ); LOGI( "Failed to load:%s", filename ); pthread_mutex_unlock( &mMutex ); return false; } buffer->reserve( size ); buffer->assign( data, data + size ); AAsset_close( assetFile ); pthread_mutex_unlock( &mMutex ); return true; }}AndroidIO::~AndroidIO(){ pthread_mutex_destroy(&mMutex);}
为了验证读取文件功能, 我把shader文件分别放到assets文件夹下, 和sd卡上, 下面是运行结果:
二: 下面看看C++库如何移植到Android的问题:
这又分为两个小问题, 一是如何把第三方库编译成Android可用的动态库? 二是如何调用这些动态库?
1: 如何把第三方库编译成Android可用的动态库:
一般的第三方库都有CMakeLists文件, 比如Assimp, SDL 等, 这就比较好办了, 我们可以使用CMake的方式, 把开源代码编译成Android下可用的动态库, 仅仅需要在运行CMake时加上几个选项, 具体方法, 请参考这个: https://github.com/taka-no-me/android-cmake。
#!/bin/sh# Path to Android NDKexport ANDROID_NDK=/you_path/android-ndk# Points to the Android SDKexport ANDROID_SDK=/you_path/sdkexport PATH=$PATH:$ANDROID_SDK/toolsexport PATH=$PATH:$ANDROID_SDK/platform-toolsexport PATH=$PATH:$ANDROID_SDK/android-toolchain/bin# from https://github.com/taka-no-me/android-cmakeexport ANDROID_STANDALONE_TOOLCHAIN=/you_path/android-cmake/android.toolchain.cmakeecho $ANDROID_STANDALONE_TOOLCHAIN# Add additional args here as appropriatecd build cmake -DCMAKE_TOOLCHAIN_FILE=$ANDROID_STANDALONE_TOOLCHAIN \ -DANDROID_NDK=$ANDROID_NDK \ -DCMAKE_BUILD_TYPE=Release \ -DANDROID_ABI="armeabi-v7a " \ you_src_path/ cmake --build .cd ..
2: 编译好Android上可用的动态库之后, 下一步就是要解决如何调用的问题了:
调用第三方动态库, 需要配置Android.mk, 以及 Application.mk, 以便程序能找到动态库和头文件, 先看一下目录结构:
图中的 include , lib 分别存放第三方库的头文件和.so 文件。
下面看看Android.mk 中如何调用so, 以及Application.mk 中一个需要注意的地方。
Android.mk
LOCAL_PATH := $(call my-dir)include $(CLEAR_VARS)LOCAL_MODULE := fooLOCAL_SRC_FILES := lib/libfoo.soinclude $(PREBUILT_SHARED_LIBRARY)include $(CLEAR_VARS)LOCAL_MODULE := hello-jniLOCAL_SRC_FILES := hello-jni.cLOCAL_SHARED_LIBRARIES := fooLOCAL_EXPORT_C_INCLUDES := includeinclude $(BUILD_SHARED_LIBRARY)
Application.mk
#APP_ABI := allAPP_ABI := armeabi-v7a armeabi因为编译so属于交叉编译, 比如我们编译出来的so 是arm 指令的, 就不能再x86平台下面用, 所以注意这里的APP_ABI 的配置, 确保要和第一步的 -DANDROID_ABI 一样, 否则会出现.so格式不不正确的错误。
- 小型三维引擎设计实现-app层如何跨平台2
- 小型三维引擎设计实现-app层如何跨平台1
- 小型三维引擎设计实现-设计目标
- 小型三维引擎设计实现-地球的渲染方法
- 小型三维引擎设计实现-怎样通过减少对驱动程序的调用来提高性能
- 三维引擎设计-渲染层封装(Osg渲染层结构)
- cocos2d-x 引擎分析:如何实现跨平台
- 三维渲染引擎渲染层设计(3D Engine Design for Vritual Globes -翻译未完)
- 引擎设计: 三维引擎总体结构
- OPhone平台2D游戏引擎实现——场景、图层、元素(一)
- 三维引擎设计-多线程渲染(平台API基础和封装大致框架)
- 如何设计三维模型?
- 手机APP游戏的发展前景分析 如何实现跨平台
- 三维引擎设计-多线程渲染(线程池的设计思路和实现方案)
- 三维引擎设计专题--文字的渲染
- 三维引擎设计专题--大气散射特效
- 三维引擎设计-图形窗口封装
- 跨平台室内三维地图引擎——FengMap公开测试
- CNN_CT
- 欢迎使用CSDN-markdown编辑器
- 删除单向链表的指定节点
- 纯虚函数
- 可编辑子项的list control控件
- 小型三维引擎设计实现-app层如何跨平台2
- webstorm,Vim常用快捷键
- css选择器整理
- 使用redis中遇到的问题记录
- UVa1587--Box--盒子(代码超简洁)
- LINUX设备驱动模型之PLATFORM(平台)总线详解
- ORA-00922: 选项缺失或无效
- 2017.7.17
- 微信小程序 java服务端记(附部署过程)