Android OpenGL球体贴图
2016-08-18 11:15
246 查看
OpenGL球体贴图的的整个流程就是计算出球体和纹理材质坐标,然后画出球体,按照纹理坐标将bitmap贴上去。
具体方法和上一篇文章画一个球体类似OpenGL绘制球体,只是需要创建材质,并且需要构建一个用来渲染的Bitmap对象。
创建好了材质,还需要在makeSphereVertices()这个计算球面坐标的方法里,获取材质纹理坐标.
需要注意的是,纹理坐标的原点是在左上角.
最后一步,就是在draw()方法里声明纹理点坐标的位置:
找了一张地球的图片,贴上去之后就长这样啦~~~~\(≧▽≦)/~
完整代码下载地址:点击打开链接
具体方法和上一篇文章画一个球体类似OpenGL绘制球体,只是需要创建材质,并且需要构建一个用来渲染的Bitmap对象。
//使用OpenGL库创建一个材质(Texture),首先是获取一个Texture Id。 int[] textures = new int[1]; // 告诉OpenGL去生成textures.textures中存放了创建的Texture ID gl.glGenTextures(1, textures, 0); //通知OpenGL库使用这个Texture gl.glBindTexture(GL10.GL_TEXTURE_2D, textures[0]); //用来渲染的Texture可能比要渲染的区域大或者小,所以需要设置Texture需要放大或是缩小时OpenGL的模式 //常用的两种模式为GL10.GL_LINEAR和GL10.GL_NEAREST。 //需要比较清晰的图像使用GL10.GL_NEAREST,而使用GL10.GL_LINEAR则会得到一个较模糊的图像 gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MIN_FILTER, GL10.GL_NEAREST); gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MAG_FILTER, GL10.GL_LINEAR); //当定义的材质坐标点超过UV坐标定义的大小(UV坐标为0,0到1,1),这时需要告诉OpenGL库如何去渲染这些不存在的Texture部分。 //有两种设置:GL_REPEAT 重复Texture。GL_CLAMP_TO_EDGE 只靠边线绘制一次。 gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_S, GL10.GL_CLAMP_TO_EDGE); gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_T, GL10.GL_CLAMP_TO_EDGE); //将Bitmap资源和Texture绑定起来 GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, mBitmap, 0);
创建好了材质,还需要在makeSphereVertices()这个计算球面坐标的方法里,获取材质纹理坐标.
需要注意的是,纹理坐标的原点是在左上角.
private void makeSphereVertices() { float altitude; float altitudeDelta; float azimuth; float ex; float ey; float ez; for(int i = 0; i <= divide; i++) { altitude = (float) (Math.PI/2.0 - i * (Math.PI) / divide); altitudeDelta = (float) (Math.PI/2.0 - (i + 1) * (Math.PI) / divide); float[] vertices = new float[divide*6+6]; //创建纹理坐标点数组 float[] texCoords = new float[divide*4+4]; for(int j = 0; j <= divide; j++) { azimuth = (float)(j * (Math.PI*2) / divide); ex = (float) (Math.cos(altitude) * Math.cos(azimuth)); ey = (float) Math.sin(altitude); ez = (float) - (Math.cos(altitude) * Math.sin(azimuth)); vertices[6*j+0] = radius * ex; vertices[6*j+1] = radius * ey; vertices[6*j+2] = radius * ez; //计算azimuth经度下纬度为altitude的纹理点坐标 texCoords[4*j+0] = j/(float)divide; texCoords[4*j+1] = i/(float)divide; ex = (float) (Math.cos(altitudeDelta) * Math.cos(azimuth)); ey = (float) Math.sin(altitudeDelta); ez = (float) -(Math.cos(altitudeDelta) * Math.sin(azimuth)); vertices[6*j+3] = radius * ex; vertices[6*j+4] = radius * ey; vertices[6*j+5] = radius * ez; //计算azimuth经度下纬度为altitudeDelta的纹理点坐标 texCoords[4*j+2] = j/(float)divide; texCoords[4*j+3] = (i + 1) / (float)divide; } mVertices.add(makeFloatBufferFromArray(vertices)); //将纹理点坐标转换成FloatBuffer类型添加到纹理点坐标集合ArrayList<FloatBuffer>里 mTextureCoords.add(makeFloatBufferFromArray(texCoords)); } }
最后一步,就是在draw()方法里声明纹理点坐标的位置:
private void draw(GL10 gl) { gl.glEnable(GL10.GL_TEXTURE_2D); //打开材质开关 gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY); gl.glEnableClientState(GL10.GL_VERTEX_ARRAY); for(int i= 0;i<=divide;i++){ gl.glVertexPointer(3,GL10.GL_FLOAT,0,mVertices.get(i)); //声明纹理点坐标 gl.glTexCoordPointer(2, GL10.GL_FLOAT, 0, mTextureCoords.get(i)); l.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 0, divide*2+2); } gl.glDisableClientState(GL10.GL_VERTEX_ARRAY); //关闭材质开关 gl.glDisableClientState(GL10.GL_TEXTURE_COORD_ARRAY); gl.glDisable(GL10.GL_TEXTURE_2D); }
找了一张地球的图片,贴上去之后就长这样啦~~~~\(≧▽≦)/~
完整代码下载地址:点击打开链接
相关文章推荐
- Android opengl 2d绘图/贴图详细教程
- android opengl jni中纹理贴图
- android的多分辨率支持机制 由anyDensity设置导致OpenGL贴图不能显示的问题谈开
- Android OpenGL绘制球体
- (转)使用OpenGL显示图像(七)Android OpenGLES2.0——纹理贴图之显示图片
- Android OpenGL 2D贴图切换
- Android OpenGLES2.0(十六)——3D模型贴图及光照处理(obj+mtl)
- Android OpenGLES2.0(八)——纹理贴图之显示图片
- android openGL 魔方、贴图、混色
- Android OpenGLES2.0(六)——构建圆锥、圆柱和球体
- 改造的opengl纹理贴图
- OpenGL曲面纹理贴图技术--波浪的模拟(转 作者 Y_Y)
- NeHe的opengl教程delphi版(6)----纹理映射(贴图)
- Android中的OPenGL编程
- OpenGL系统设计-纹理贴图(4)
- OpenGL 立方贴图
- android上用opengl画线
- openGL as android graphic engine
- NeHe的opengl教程delphi版(6)----纹理映射(贴图)
- OpenGL中的平面圆绘制与贴图