Android(安卓)RenderScript 使用 Struct 及其下标的赋值
16lz
2021-01-26
这是一个关于RenderScript如何使用 Struct 的文章,是学习RenderScript 一个必须要掌握的基础知识点。
大纲
- 如何定义Struct
- 如何得到指针长度并循环为指针赋值
- 整体DEMO代码
如何定义Struct
RenderScript 里面定义结构有两种定义方法,参考如下:
1.
typedefstructtempArray{
float2position ;
floatsize ;
}Array_T ;
Array_T*myArray; 复制代码
2.
//定义一个struct
typedefstruct__attribute__((packed,aligned(4)))tempArray{inttemp ;
}Array_T ;
Array_T*myArray ; 复制代码
RenderScript 定义Struct 成功后,会自动生成一个java文件,如上面的tempArray名称的结构,会生产这个文件:ScriptField_tempArray,代码如下:
/**Copyright(C)2011TheAndroidOpenSourceProject
*
*LicensedundertheApacheLicense,Version2.0(the"License");
*youmaynotusethisfileexceptincompliancewiththeLicense.
*YoumayobtainacopyoftheLicenseat
*
* http://www.apache.org/licenses/LICENSE-2.0
*
*Unlessrequiredbyapplicablelaworagreedtoinwriting,software
*distributedundertheLicenseisdistributedonan"ASIS"BASIS,
*WITHOUTWARRANTIESORCONDITIONSOFANYKIND,eitherexpressorimplied.
*SeetheLicenseforthespecificlanguagegoverningpermissionsand
*limitationsundertheLicense.
*/
/*
*Thisfileisauto-generated.DONOTMODIFY!
*ThesourceRenderscriptfile:/home/terry/workspace/RenderScriptsArray/src/com/xuzhi/renderScriptArray/array.rs
*/
packagecom.xuzhi.renderScriptArray;
importandroid.renderscript.*;
importandroid.content.res.Resources;
/**
*@hide
*/
public classScriptField_tempArray extendsandroid.renderscript.Script.FieldBase{
static public classItem{
public static final intsizeof=4;
inttemp;
Item(){
}
}
privateItemmItemArray[];
privateFieldPackermIOBuffer;
public staticElementcreateElement(RenderScriptrs){
Element.Buildereb= newElement.Builder(rs);
eb.add(Element.I32(rs),"temp");
returneb.create();
}
publicScriptField_tempArray(RenderScriptrs, intcount){
mItemArray= null;
mIOBuffer= null;
mElement=createElement(rs);
init(rs,count);
}
publicScriptField_tempArray(RenderScriptrs, intcount, intusages){
mItemArray= null;
mIOBuffer= null;
mElement=createElement(rs);
init(rs,count,usages);
}
private voidcopyToArrayLocal(Itemi,FieldPackerfp){
fp.addI32(i.temp);
}
private voidcopyToArray(Itemi, intindex){
if(mIOBuffer== null)mIOBuffer= newFieldPacker(Item.sizeof*getType().getX() /* count */);
mIOBuffer.reset(index*Item.sizeof);
copyToArrayLocal(i,mIOBuffer);
}
public synchronized voidset(Itemi, intindex, booleancopyNow){
if(mItemArray== null)mItemArray= newItem[getType().getX() /* count */];
mItemArray[index]=i;
if(copyNow){
copyToArray(i,index);
FieldPackerfp= newFieldPacker(Item.sizeof);
copyToArrayLocal(i,fp);
mAllocation.setFromFieldPacker(index,fp);
}
}
public synchronizedItemget( intindex){
if(mItemArray== null) return null;
returnmItemArray[index];
}
public synchronized voidset_temp( intindex, intv, booleancopyNow){
if(mIOBuffer== null)mIOBuffer= newFieldPacker(Item.sizeof*getType().getX() /* count */);
if(mItemArray== null)mItemArray= newItem[getType().getX() /* count */];
if(mItemArray[index]== null)mItemArray[index]= newItem();
mItemArray[index].temp=v;
if(copyNow){
mIOBuffer.reset(index*Item.sizeof);
mIOBuffer.addI32(v);
FieldPackerfp= newFieldPacker(4);
fp.addI32(v);
mAllocation.setFromFieldPacker(index,0,fp);
}
}
public synchronized intget_temp( intindex){
if(mItemArray== null) return0;
returnmItemArray[index].temp;
}
public synchronized voidcopyAll(){
for( intct=0;ct<mItemArray.length;ct++)copyToArray(mItemArray[ct],ct);
mAllocation.setFromFieldPacker(0,mIOBuffer);
}
public synchronized voidresize( intnewSize){
if(mItemArray!= null){
intoldSize=mItemArray.length;
intcopySize=Math.min(oldSize,newSize);
if(newSize==oldSize) return;
Itemni[]= newItem[newSize];
System.arraycopy(mItemArray,0,ni,0,copySize);
mItemArray=ni;
}
mAllocation.resize(newSize);
if(mIOBuffer!= null)mIOBuffer= newFieldPacker(Item.sizeof*getType().getX() /* count */);
}
} 复制代码
生成的代码是提供给你做内存分配和操作类似数组的功能。
如何得到指针长度并循环为指针赋值
RenderScript 有两个函数是专门用来获取指针长度的:
rsGetAllocation:返回一个己经分配过地址的指针
rsAllocationGetDimX:获取返回指针的长度
通过将这两个函数做组合使用可以返回指针长度,代码如下:
constintsize=rsAllocationGetDimX(rsGetAllocation(myArray)) ;取得了长度即可以为指针内部变量赋值,代码如下:
for(inti=0 ; i<size;i++){array->temp=i ; //循环赋值
rsDebug("currentvalueis====>",array->temp) ; //打印当前值
//指向下个指针
array++ ;
} 复制代码
整体DEMO代码
本DEMO没有任何界面 ,只是演示如何使用struct并打印出指针下标原素的值,如此简单, 涉及的rs文件代码如下:
#pragmaversion(1)#pragmarsjava_package_name(com.xuzhi.renderScriptArray)
#include"rs_graphics.rsh"
staticintinitialized=0 ;
//定义一个struct
typedefstruct__attribute__((packed,aligned(4)))tempArray{
inttemp ;
}Array_T ;
Array_T*myArray ;
staticvoidinitArray(){
Array_T*array=myArray ;
//得到struct长度
//1.返回一个己经分配过地址的指针
//2.获取返回指针的长度
constintsize=rsAllocationGetDimX(rsGetAllocation(myArray)) ;
for(inti=0 ; i<size;i++){
array->temp=i ; //循环赋值
rsDebug("currentvalueis====>",array->temp) ; //打印当前值
//指向下个指针
array++ ;
}
}
introot(){
rsgClearColor(0.0f,1.0f,0.0f,1.0f) ;
if(initialized==0){
initArray() ;
initialized=1 ;
}
return16 ;
} 复制代码
java 代码如下:
packagecom.xuzhi.renderScriptArray;importandroid.app.Activity;
importandroid.content.Context;
importandroid.content.res.Resources;
importandroid.os.Bundle;
importandroid.renderscript.Allocation;
importandroid.renderscript.RSSurfaceView;
importandroid.renderscript.RenderScriptGL;
public classRenderScriptsArrayActivity extendsActivity{
/** Calledwhentheactivityisfirstcreated. */
@Override
public voidonCreate(BundlesavedInstanceState){
super.onCreate(savedInstanceState);
setContentView( newrenderScriptView( this));
}
public classrenderScriptRS{
privateScriptC_arraymScript;
privateScriptField_tempArrayarray;
RenderScriptGLmRS;
publicrenderScriptRS(RenderScriptGLrs,Resourcesresource){
// TODOAuto-generatedconstructorstub
mRS=rs;
// 初始化struct并为其指定有多少个下标
array= new ScriptField_tempArray(mRS,10,Allocation.USAGE_SCRIPT|Allocation.USAGE_GRAPHICS_VERTEX);
// 实始化CcriptC
mScript= new ScriptC_array(mRS,resource,R.raw.array);
// 绑定struct
mScript.bind_myArray(array);
// 绑定脚本
mRS.bindRootScript(mScript);
}
}
public classrenderScriptView extendsRSSurfaceView{
privateRenderScriptGLmRS;
privaterenderScriptRSmRender;
publicrenderScriptView(Contextcontext){
super(context);
// TODOAuto-generatedconstructorstub
}
@Override
protected voidonAttachedToWindow(){
super.onAttachedToWindow();
android.util.Log.e("rs","onAttachedToWindow");
if(mRS== null){
RenderScriptGL.SurfaceConfigsc= newRenderScriptGL.SurfaceConfig();
mRS=createRenderScriptGL(sc);
mRender= newrenderScriptRS(mRS,getResources());
}
}
@Override
protected voidonDetachedFromWindow(){
super.onDetachedFromWindow();
if(mRS!= null){
mRS= null;
destroyRenderScriptGL();
}
}
}
} 复制代码
都加了注释了,最主要的四段代码标注了红色,要注意。
运行结果:
03-0915:47:50.492:D/RenderScript(2298):currentvalueis====>00x003-0915:47:50.507:D/RenderScript(2298):currentvalueis====>10x1
03-0915:47:50.507:D/RenderScript(2298):currentvalueis====>20x2
03-0915:47:50.507:D/RenderScript(2298):currentvalueis====>30x3
03-0915:47:50.507:D/RenderScript(2298):currentvalueis====>40x4
03-0915:47:50.507:D/RenderScript(2298):currentvalueis====>50x5
03-0915:47:50.507:D/RenderScript(2298):currentvalueis====>60x6
03-0915:47:50.507:D/RenderScript(2298):currentvalueis====>70x7
03-0915:47:50.507:D/RenderScript(2298):currentvalueis====>80x8
03-0915:47:50.507:D/RenderScript(2298):currentvalueis====>90x9
更多相关文章
- 正确获得android设备的IP地址
- android --拍照相册选取图片[兼容小米等其他手机]
- android gallery3d 源码分析(一)
- 使用 Annotation 改善 Android(安卓)代码
- android4.2 长按POWER键3秒关机
- 解决android sdk docs帮助文档打开慢的问题
- Android仿Iphone图标抖动效果
- android多线程读取网页内容
- android TextView空间的setTextSize()方法在真机上运行大小问题