`
lyunabc
  • 浏览: 566245 次
  • 性别: Icon_minigender_2
社区版块
存档分类
最新评论

Android OpenGL ES->Cube Map

 
阅读更多

Cube Map,中文可以翻译成立方环境映射,下面是摘自维基百科的说明:

立方反射映射是用立方映射使得物体看起来如同在反射周围环境的一项技术。通常,这通常使用户外渲染中使用的 skybox 完成。尽管由于反射物周围的物体无法在结果中看到,所以这并不是一个真正的反射,但是通常仍然可以达到所期望的效果。

通过确定观察物体的向量就可以进行立方映射反射,照相机光线在照相机向量与物体相交的位置按照曲面法线方向进行反射,这样传到立方图(cube map)取得纹素(texel)的反射光线在照相机看来好像位于物体表面,这样就得到了物体的反射效果。

简单的讲,就是你把一个具有金属反射特性的茶壶放在一个房间中,茶壶的金属表面会反射房间的场景,Cube Map就是解决如何将场景(环境)的内容显示在茶壶的表面,如下图所示:

本例使用环面(Torus)做为反射的表面,在OpenGL ES中任何3D物体,最终都是通过三角形来构造的,本例代码generateTorusGrid 和Grid对象用来构造环面的顶点坐标。具体算法有兴趣的可以自行研究(需要有立体几何的知识,这里不详细解释)。

Cube map技术说到底就是用一个虚拟的立方体(cube)包围住物体,眼睛到物体某处的向量eyevec经过反射(以该处的法线为对称轴),反射向量reflectvec射到立方体上,就在该立方体上获得一个纹素了(见下图)。明显,我们需要一个类似天空盒般的6张纹理贴在这个虚拟的立方体上。按CUBE MAPPING原意,就是一种enviroment map,因此把周围场景渲染到这6张纹理里是“正统”的。也就是每次渲染时,都作一次离线渲染,分别在每个矩形中心放置相机“拍下”场景,用FBO渲染到纹理,然后把这张纹理作为一个cube map对象的六纹理之一。这样即使是动态之物也能被映射到物体表面了(虽然缺点是不能映射物体自身的任何部分)。

本例使用的六张图为res/raw 目录下的 skycubemap0 — skycubemap5 ,如下图所示

使用Cube Map,首先要检测设备是否支持Cube Map 材质,本例使用以下代码检测设备是否支持Cube Map。

private boolean checkIfContextSupportsCubeMap(GL10 gl) {
return checkIfContextSupportsExtension(gl, "GL_OES_texture_cube_map");
 
}
 
/**
* This is not the fastest way to check for an extension, but fine if
* we are only checking for a few extensions each time a context is created.
* @param gl
* @param extension
* @return true if the extension is present in the current context.
*/
private boolean checkIfContextSupportsExtension(GL10 gl, String extension) {
String extensions = " " + gl.glGetString(GL10.GL_EXTENSIONS) + " ";
// The extensions string is padded with spaces between extensions, but not
// necessarily at the beginning or end. For simplicity, add spaces at the
// beginning and end of the extensions string and the extension string.
// This means we can avoid special-case checks for the first or last
// extension, as well as avoid special-case checks when an extension name
// is the same as the first part of another extension name.
return extensions.indexOf(" " + extension + " ") >= 0;
}


Cube Map (使用6张图),处调用设置Cube Map外,其基本使用步骤类似于普通材质的使用。本例使用资源,其设置Cube Map的基本步骤如下:

1. 调入图像资源

if (mContextSupportsCubeMap) {
int[] cubeMapResourceIds = new int[]{
R.raw.skycubemap0, R.raw.skycubemap1, R.raw.skycubemap2,
R.raw.skycubemap3, R.raw.skycubemap4, R.raw.skycubemap5};
mCubeMapTextureID = generateCubeMap(gl, cubeMapResourceIds);
}
 
....
 
private int generateCubeMap(GL10 gl, int[] resourceIds) {
checkGLError(gl);
int[] ids = new int[1];
gl.glGenTextures(1, ids, 0);
int cubeMapTextureId = ids[0];
gl.glBindTexture(GL11ExtensionPack.GL_TEXTURE_CUBE_MAP, cubeMapTextureId);
gl.glTexParameterf(GL11ExtensionPack.GL_TEXTURE_CUBE_MAP,
GL10.GL_TEXTURE_MIN_FILTER, GL10.GL_LINEAR);
gl.glTexParameterf(GL11ExtensionPack.GL_TEXTURE_CUBE_MAP,
GL10.GL_TEXTURE_MAG_FILTER, GL10.GL_LINEAR);
 
for (int face = 0; face < 6; face++) {
InputStream is = getResources().openRawResource(resourceIds[face]);
Bitmap bitmap;
try {
bitmap = BitmapFactory.decodeStream(is);
} finally {
try {
is.close();
} catch(IOException e) {
Log.e("CubeMap", "Could not decode texture for face " + Integer.toString(face));
}
}
GLUtils.texImage2D(GL11ExtensionPack.GL_TEXTURE_CUBE_MAP_POSITIVE_X + face, 0,
bitmap, 0);
bitmap.recycle();
}
checkGLError(gl);
return cubeMapTextureId;
}


2. 绑定材质

函数generateCubeMap返回一个Texture的ID,在OpenGL ES中使用材质时,需要绑定材质

gl.glActiveTexture(GL10.GL_TEXTURE0);
checkGLError(gl);
gl.glEnable(GL11ExtensionPack.GL_TEXTURE_CUBE_MAP);
checkGLError(gl);
gl.glBindTexture(GL11ExtensionPack.GL_TEXTURE_CUBE_MAP, mCubeMapTextureID);
checkGLError(gl);
GL11ExtensionPack gl11ep = (GL11ExtensionPack) gl;
gl11ep.glTexGeni(GL11ExtensionPack.GL_TEXTURE_GEN_STR,
GL11ExtensionPack.GL_TEXTURE_GEN_MODE,
GL11ExtensionPack.GL_REFLECTION_MAP);
checkGLError(gl);
gl.glEnable(GL11ExtensionPack.GL_TEXTURE_GEN_STR);
checkGLError(gl);
gl.glTexEnvx(GL10.GL_TEXTURE_ENV, GL10.GL_TEXTURE_ENV_MODE, GL10.GL_DECAL);
...
mGrid.draw(gl);
...
gl.glDisable(GL11ExtensionPack.GL_TEXTURE_GEN_STR);


这样就给环面物体添加了环境材质,显示结果如下:

分享到:
评论

相关推荐

    OpenGL ES2.0 Cubemap texture

    在本文中,我们将深入探讨如何在Xcode 4.5环境下使用OpenGL ES 2.0来实现立方体贴图纹理(Cubemap texture)。 立方体贴图是一种特殊的纹理类型,用于表示环境映射,它可以将六个正交的2D纹理面组合成一个3D对象的...

    OpenGL ES 3.0 Programming Guide, 2nd Edition

    All code has been built and tested on iOS 7, Android 4.3, Windows (OpenGL ES 3.0 Emulation), and Ubuntu Linux, and the authors demonstrate how to build OpenGL ES code for each platform. Coverage ...

    【OpenGL ES】立方体贴图(6张图)

    在OpenGL ES中,我们通常使用`GL_TEXTURE_CUBE_MAP`纹理目标来创建立方体贴图。 首先,我们需要创建一个立方体的顶点数据,这包括顶点坐标和法线向量。顶点坐标定义了立方体的形状,而法线向量用于计算光照。立方体...

    OpenGL ES编程指南

    例如,在Android平台上,可以通过修改`AndroidManifest.xml`文件中的`&lt;application&gt;`标签,添加`android:hardwareAccelerated="true"`属性来开启硬件加速。 **2.2 GPU Limitations** GPU在渲染过程中存在一定的...

    opengles绘制天空穹

    在Android系统中,OpenGL ES被广泛应用于游戏开发、图像处理和其他图形密集型应用。本教程将深入探讨如何使用OpenGL ES在移动设备上绘制一个逼真的天空穹。 首先,了解基本概念是至关重要的。OpenGL ES是一个基于...

    PowerVR.Supported+Extensions.OpenGL+ES.EGL.pdf

    - **EGL_KHR_gl_texture_2D_image** 和 **EGL_KHR_gl_texture_cubemap_image**:扩展了将OpenGL ES的纹理对象映射为EGLImage的能力。 - **EGL_KHR_image** 和 **EGL_KHR_image_base**:定义了图像抽象的概念,允许...

    OpenGL ES API 速查

    ### OpenGL ES API 速查知识点解析 #### 一、`glGenTextures` — 生成纹理名 **函数名称**: `glGenTextures` **用途**: 用于生成纹理名称,这些纹理名称可以用来标识和操作OpenGL中的纹理。 **参数**: - **n**: ...

    OpenGL ES纹理详解

    在Android中使用的OpenGL ES的纹理坐标系跟官方的纹理坐标系统不一样,在Android中使用官方的纹理坐标系统,得到的结果是相反的,而是左上角是st坐标(0.0,0.0)点,右下角是st坐标(1.0,1.0)点。 二维纹理映射的原理...

    Android 全景图 展示

    常见的全景图格式有JPEG、PNG等,也有专用于全景图的如立方体映射(Cube Map)、球面映射(Spherical Mapping)等特殊格式。在Android中,需要处理这些格式的读取和解析。 3. **传感器和用户交互**: Android设备上...

    android3D全景相册

    - **全景图格式**:理解Equirectangular、Cubemap等全景图格式,并进行相应的处理。 4. **触摸事件处理**: - **手势识别**:监听用户的滑动、旋转等手势,更新3D场景的视角。 - **传感器集成**:可选地,利用...

    Android 360度全景视频播放器 VR播放器

    2. **360度视频渲染**:解码后的视频帧需要在OpenGL ES或 Vulkan 上进行渲染,以呈现全景效果。渲染过程通常涉及对全景图像进行投影变换,将2D图像转换为适合3D空间的视角。Equirectangular到Cube Map的转换是常见的...

    安卓Android源码——360全景查看demo.zip

    2. **OpenGL ES**:360全景查看通常涉及图形处理,可能使用了OpenGL ES,这是Android支持的图形库,用于在移动设备上创建3D图形。 3. **SurfaceView**:在Android中,为了高效地显示实时图形,开发者可能使用...

    android vr视频播放器

    常见的VR视频格式有equirectangular(等距柱状投影)、cubemap(立方体贴图)等,其中equirectangular格式最为常见,它将全景图像映射到一个二维平面,便于处理和存储。VR视频播放器需要支持这些格式的解码和渲染。 ...

    安卓三种方法预览VR全景图片

    - **图像格式**:全景图片通常为JPEG或PNG格式,但也可能是其他特殊格式如equirectangular或cubemap。 - **性能优化**:处理全景图像可能会消耗大量资源,所以需要考虑低功耗模式和硬件加速。 - **用户体验**:提供...

    360度全景图片浏览android

    2. **全景图片格式**:常见的全景图片格式有JPEG Panorama、Equirectangular、Cubemap等。这些格式存储了全景图像的信息,开发者需要知道如何解析和加载这些格式的图片。 3. **触摸事件处理**:在Android应用中,...

    360°全景图 DroidVR,这是一个值得把玩的APP.zip

    这得益于DroidVR对多种全景图格式的支持,如equirectangular、cubemap等,这些格式都是常见的全景图存储方式。用户只需将全景图文件导入到应用中,就能享受个性化的VR体验。 开源项目的特性使得DroidVR具有了极高的...

    在 3D 图形场景下的前端开发-朱毅.pdf

    "Cubemap"是一种用于实现环境映射的技术,它由六个正方形图像拼接而成,分别代表天空盒的六个面,可以用来创建逼真的反射和环境光效果。在Web端,CSS3D Cubemap可以实现这种效果,让用户仿佛在3D场景中漫游。 "漫游...

    iPhone 3D Samples 随书代码(7-9章)

    7. **ch8_Klein.Cubemap.zip** - 立方体贴图(Cubemap)是一种常见的环境映射技术,用于反射和环境光遮蔽效果。这个例子可能会介绍如何在3D场景中使用立方体贴图来增强真实感。 8. **ch8_CrudeBloom.zip** 和 **ch8...

    panoramaGL

    1. **全景图格式**:`panoramaGL` 支持常见的全景图格式,如 equirectangular、cubemap 和 spherical panoramas。Equirectangular是最常见的全景图类型,通过将球面图像映射到一个长方形上,易于处理和展示。...

Global site tag (gtag.js) - Google Analytics