OpenGLES入门笔记:Rajawali学习(1)基本功能初探
2016-08-15 03:22
471 查看
背景
最近开始学习rajawali,rajawali是一个Android下封装了OpenGLES API的引擎,可以方便地建立自己的场景,目前还集成了CardBoard相关,可以进行VR相关的开发,同时也可以进行AR相关的开发。rajawali为我们提供了比较丰富的例程,很多东西可以参照例程快速上手。本文记录了rajawali的集成,以及制作一个简单的音乐频谱变化的小demo,其中遇到不少问题,还需要日后深入理解rajawali的源代码。集成
仓库地址:https://github.com/Rajawali/Rajawali其中包括了rajawali引擎,以及相关AndroidDemo,直接使用AndroidStuido打开即可。同时我们在工程下建立自己的一个Module,我们只需要在Module的build.gradle的dependencies下加入如下语句即可
compile project(':rajawali')
demo中没有涉及AR,VR相关,所以先不导入其他库。
简单Demo
下面我们将完成一个简单的Demo,其中涉及到天空盒,光照,简单模型以及屏幕拖动几个基本功能。试想如果直接使用GLES的API,同时加入这些会使代码非常复杂,如今我们只需要参考自带的Demo,简单定义几个变量并设置相关属性就可以完成这些效果。rajawali中自带了丰富的Demo,很多效果可以直接参照demo实现。如图,这里我们播放喀秋莎的音乐,立柱根据频谱而跳动,同时我们可以触摸屏幕拖动小球。下面我们记录一下这个Demo实现的步骤。
创建Fragment
我们可以直接继承Demo中的AExampleFragment,并且使用其布局文件。布局文件中,显示部分主要是用org.rajawali3d.view.TextureView,这个控件继承了Android自身的TextureView并实现了rajawali的ISurface接口,用于GLES的绘制。public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { super.onCreateView(inflater, container, savedInstanceState); // Inflate the view mLayout = (FrameLayout) inflater.inflate(R.layout.rajawali_textureview_fragment, container, false); // Find the TextureView mRenderSurface = (ISurface) mLayout.findViewById(R.id.rajwali_surface); // Create the loader mProgressBarLoader = (ProgressBar) mLayout.findViewById(R.id.progress_bar_loader); mProgressBarLoader.setVisibility(View.GONE); // Create the renderer mRenderer = createRenderer(); onBeforeApplyRenderer(); applyRenderer(); return mLayout; }
其构造方法主要实例化了TextureView和Renderer,其中createRenderer()方法需要我们自己来实现,也就是定义我们自己的Renderer,用它来渲染TextureView。
在我们的自己的Fragment中,我们主要是实现上述Renderer。
建立天空盒
不用一切从零开始,我们直接使用Rajawali的API创建一个天空盒。private void buildSkyBox(){ try{ getCurrentScene().setSkybox(R.drawable.black, R.drawable.black, R.drawable.black, R.drawable.black, R.drawable.black, R.drawable.black); } catch (ATexture.TextureException e) { e.printStackTrace(); } }
getCurrentScene()就是获取当前的场景,这里所有的模型都是需要添加到这个场景中的,而每个renderer中都会包含一个场景。我们所创建的模型或者其他东西,最后只有添加给场景才能显示。
添加光照
参照Demo中的例子,我们为当前场景加一个点光源。private void buildLights(){ PointLight light1 = new PointLight(); light1.setPower(3.5f); light1.setY(3); light1.setX(0); light1.setZ(1); getCurrentScene().addLight(light1); }
相比较前几篇文章各种shader各种变量,感觉真的简单了好多。
添加蓝色柱子
private void buildRectangularPrisms(float r){ double PI = 3.14; double sectorAngle = 120; double angle = 180 - (180 - sectorAngle)/2; double delta = (angle - (180 - sectorAngle)/2) / MusicPlayer.VisualizerListener.CYLINDER_NUM; int color = 0xff/(MusicPlayer.VisualizerListener.CYLINDER_NUM+5); int colorReflect = color; Material cubeMaterial = new Material(); cubeMaterial.enableLighting(true); cubeMaterial.setDiffuseMethod(new DiffuseMethod.Lambert()); for(int i=0; i< MusicPlayer.VisualizerListener.CYLINDER_NUM; i++) { RectangularPrism rectangularPrism = new RectangularPrism(0.2f, mRectangularPrismHeight, 0.2f); rectangularPrism.setMaterial(cubeMaterial); rectangularPrism.setColor((color*(i+5))<<32); //倒影 RectangularPrism rectangularPrismReflect = new RectangularPrism(0.2f, mRectangularPrismHeight, 0.2f); rectangularPrismReflect.setMaterial(cubeMaterial); rectangularPrismReflect.setColor((colorReflect*(i+5))<<32); double x = Math.cos(PI * angle/180) * r; double z = -Math.sin(PI * angle/180) * r; angle = angle - delta; rectangularPrism.setX(x); rectangularPrism.setZ(z); getCurrentScene().addChild(rectangularPrism); rectangularPrismReflect.setX(x); rectangularPrismReflect.setZ(z); rectangularPrismReflect.setY(-mRectangularPrismHeight); getCurrentScene().addChild(rectangularPrismReflect); RectangularPrismInfo rectangularPrismInfo = new RectangularPrismInfo(); rectangularPrismInfo.rectangularPrism = rectangularPrism; rectangularPrismInfo.yLengthRecorder = 1.0f; RectangularPrismInfo rectangularPrismReflectInfo = new RectangularPrismInfo(); rectangularPrismReflectInfo.rectangularPrism = rectangularPrismReflect; rectangularPrismReflectInfo.yLengthRecorder = 1.0f; mRectangularPrismList.add(rectangularPrismInfo); mRectangularPrismReflectList.add(rectangularPrismReflectInfo); } }
这里相关位置的计算较多,抛开这些计算,其实我们做的事情就是创建一个材质,创建一个几何体模型,设置几何体模型的位置大小等参数,最后把材质设置给几何体。
设置可在屏幕拖动的小球
首先为了获取屏幕拖动坐标,我们要复写Fragment的onTouch方法,这点和普通Android控件开发是一样的。之后我们的renderer要实现OnObjectPickedListener接口,用来监听选中状态。主要实现如下两方法:
public interface OnObjectPickedListener { /** * Called when an object has been picked successfully. * * @param object {@link Object3D} The picked object. */ void onObjectPicked(@NonNull Object3D object); /** * Called when no object was detected during picking. */ void onNoObjectPicked(); }
拖拽的具体原理比较复杂,我们会在后面的文章中单独分析实现过程。
我们还需要在Fragment建立时,让renderer自己监听自己,这样才能响应拖拽事件。
@Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { super.onCreateView(inflater, container, savedInstanceState); ((View) mRenderSurface).setOnTouchListener(this); return mLayout; }
最后,我们还有建立一个ObjectColorPicker对象,它是物体选择的最终管理中枢,其内部维护着所有需要拖拽功能对象的引用以及拖拽回调方法。我们可以用如下方法将一个球体变为到可拖拽物体。
mPicker = new ObjectColorPicker(this); mPicker.setOnObjectPickedListener(this); Material material = new Material(); material.enableLighting(true); material.setDiffuseMethod(new DiffuseMethod.Lambert()); Sphere sphere = new Sphere(.3f, 12, 12); sphere.setMaterial(material); sphere.setColor(0x333333 + (int) (Math.random() * 0xcccccc)); sphere.setX(-2); sphere.setY(0); sphere.setZ(1); sphere.setDrawingMode(GLES20.GL_TRIANGLES); mPicker.registerObject(sphere); getCurrentScene().addChild(sphere);
以上只是拖拽功能实现的基本流程,具体细节还需要参照Demo,具体实现原理将在后面文章中专门介绍。
设置相机位置与角度
Rajawali已经为我们封装好了相机的功能,并把它放入了场景中,此处我们直接调用,设置相机的位置以及方向。getCurrentCamera().enableLookAt(); getCurrentCamera().setLookAt(0, 0, -3); getCurrentCamera().setY(4); getCurrentCamera().setZ(6);
这样,我们的render就设置好了。
总结
本文主要梳理了Rajawali引擎的一些基本功能,对Rajawali有了一些直观上的认识,Demo中还有许多不完善的地方,还需要进一步熟悉项目源码,排除bug。本文代码下载地址http://download.csdn.net/detail/lidec/9603256
相关文章推荐
- OpenGLES入门笔记:Rajawali学习(3)模型绘制的基本流程
- OpenGLES入门笔记:Rajawali学习(2)场景绘制基本流程
- OpenGLES入门笔记:Rajawali学习(4)物体点击事件的实现
- OpenGLES入门笔记:Rajawali学习(3.1)球体的绘制
- Oracle RAC学习笔记:基本概念及入门 04
- Oracle RAC学习笔记:基本概念及入门
- Emacs学习笔记(4):基本的编辑功能
- android 学习笔记2——实现基本功能
- IOS入门学习(五):基本交互功能之滑块、标签和操作表单和告警视图
- cocos2d-x入门学习笔记,主要介绍cocos2d-x的基本结构,并且介绍引擎自带的示例
- Oracle RAC学习笔记:基本概念及入门
- 【Java学习笔记】ThreadPoolExecutor 基本概念入门
- Hadoop基础入门学习笔记(基本概念)
- Oracle RAC学习笔记:基本概念及入门
- IOS入门学习(四):基本交互功能之图像视图和文本字段
- 持续集成学习笔记-入门篇(1)持续集成基本概念
- Emacs学习笔记(4):基本的编辑功能
- 韩顺平_php从入门到精通_视频教程_第2讲_html运行原理②_html文件基本结构_html元素和属性_学习笔记_源代码图解_PPT文档整理
- Oracle RAC学习笔记:基本概念及入门 02