android opengl es2.0中的模型如何使它透明?

3587人阅读
OpenGL ES(3)
Android (NDK)(10)
PC上OpenGL渲染到纹理,很容易得到透明背景,但是在android上OpenGL ES渲染出来是黑色背景,对于这个问题,想了两个解决办法。
1& 让android的OpenGL ES环境支持RGBA,默认android系统给出的渲染环境是RGB565的,这是出于性能原因。如果framebuffer不支持alpha通道,renderToTexture当然得不到透明纹理。
& & & & 在androidmanifest.xml文件里改用OpenGL ES2.0,并为GLSurefaceView.Render改用RGBA8888配置,仍然得不到透明图像。尝试失败。
2& 第二种憋足的办法,读取render2texture的pixels,然后手动修改其黑色背景为透明。渲染后使用glReadPixels读取,但是这种办法效率低下,每一帧都这样干是不可能的。
&&相关文章推荐
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:47073次
排名:千里之外
原创:24篇
评论:14条
(1)(1)(2)(1)(1)(1)(1)(1)(1)(1)(1)(1)(1)(3)(5)(4)(1)(2)(1)(2)(2)
(window.slotbydup = window.slotbydup || []).push({
id: '4740881',
container: s,
size: '200,200',
display: 'inlay-fix'博客访问: 368209
博文数量: 193
博客积分: 3845
博客等级: 中校
技术积分: 2003
注册时间:
IT168企业级官微
微信号:IT168qiye
系统架构师大会
微信号:SACC2013
分类: 嵌入式
五颜六色的立方体并算是什么太有意思的事情,看上去太假,没什么感觉。 解决办法就是纹理贴图了。
OpenGL 中使用纹理要先用 glEnable 来启用相关功能
gl.glEnable(GL10.GL_TEXTURE_2D);
然后先准备一张图片作为纹理贴图,需要注意的是,有些设备对图片的尺寸有要求,我手上这个G7就只支持方形的纹理图片,其它可能的限制还有长宽必须是 2 的 n 次幂,最大尺寸不能超过256或1024等等。弄好图片之后,把它放到 res/drawable 文件夹中,比如 leftcode.png,然后通过资源加载到纹理
private void loadTexture(GL10 gl) {
&&&&InputStream bitmapStream =
&&&&Bitmap bitmap =
&&&&&&&&// 打开图片资源流
&&&&&&&&bitmapStream = context.getResources().openRawResource(
&&&&&&&&&&&&&&&&R.drawable.leftcode);
&&&&&&&&// 解码图片生成 Bitmap 实例
&&&&&&&&bitmap = BitmapFactory.decodeStream(bitmapStream);
&&&&&&&&// 生成一个纹理对象,并将其ID保存到成员变量 texture 中
&&&&&&&&int[] textures = new int[1];
&&&&&&&&gl.glGenTextures(1, textures, 0);
&&&&&&&&texture = textures[0];
&&&&&&&&// 将生成的空纹理绑定到当前2D纹理通道
&&&&&&&&gl.glBindTexture(GL10.GL_TEXTURE_2D, texture);
&&&&&&&&// 设置2D纹理通道当前绑定的纹理的属性
&&&&&&&&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);
&&&&&&&&gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_S,
&&&&&&&&&&&&&&&&GL10.GL_REPEAT);
&&&&&&&&gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_T,
&&&&&&&&&&&&&&&&GL10.GL_REPEAT);
&&&&&&&&// 将bitmap应用到2D纹理通道当前绑定的纹理中
&&&&&&&&GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, bitmap, 0);
&&&&} finally {
&&&&&&&&// 释放资源
&&&&&&&&// BTW: 期待 android 早日支持 Java 新的 try-with-resource 语法
&&&&&&&&if (bitmap != null)
&&&&&&&&&&&&bitmap.recycle();
&&&&&&&&if (bitmapStream != null) {
&&&&&&&&&&&&try {
&&&&&&&&&&&&&&&&bitmapStream.close();
&&&&&&&&&&&&} catch (IOException e) {
&&&&&&&&&&&&}
BitmapFactory.decodeStream 从流中加载并解码图片并生成Bitmap对象。令人不解的是更简单的方法的 decodeResource 方法在虚拟机中工作良好,但到我的手机中就不行了,只好退而求其次了。
glGenTextures 生成一组纹理并把纹理的ID存入数组参数中。这里只生成了一个。
glBindTexture 将指定ID的纹理绑定到指定的目标中去,接下来对目录所作的操作将针对该纹理进行。
glTexParameterf 设置纹理参数,这里设置了4个参数:
GL_TEXTURE_MIN_FILTER 和 GL_TEXTURE_MAG_FILTER 指定纹理在被缩小或放大时使用的过滤方式,LINEAR (线性插值?)效果要比 NEAREST(最近点?)好但也更需要更多运算。
GL_TEXTURE_WRAP_S 和 GL_TEXTURE_WRAP_T 表示当贴图坐标不在 0.0-1.0 之间时如何处理,这里使用 REPEAT 即平铺贴图。
GLUtils.texImage2D 辅助方法用于将 Bitmap 对象设置到纹理中,设置完后 Bitmap 对象即不再需要,可以丢弃。
最后,将在 HelloWorldRenderer 构造方法中将参数 Main Activity 存入成员变量 context 中以便在 loadTexture 中用于访问资源。并在 onSurfaceCreated 中调用 loadTexture 加载纹理。
在绘制图元之前,使用 glBindTexture 将纹理绑定到目标中,在接下来的绘制中纹理将自动应用。但在此之前,还需要设置好纹理坐标
private float[] data_tvertices = { 1.0000f, 1.0000f, 1.0000f, 0.0000f,
&&&&&&&&0.0000f, 0.0000f, 0.0000f, 0.0000f, 0.0000f, 1.0000f, 1.0000f,
&&&&&&&&1.0000f, 0.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.0000f,
&&&&&&&&1.0000f, 0.0000f, 0.0000f, 0.0000f, 0.0000f, 1.0000f, 0.0000f,
&&&&&&&&1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.0000f, 1.0000f, 0.0000f,
&&&&&&&&0.0000f, 0.0000f, 0.0000f, 1.0000f, 0.0000f, 1.0000f, 1.0000f,
&&&&&&&&1.0000f, 1.0000f, 0.0000f, 1.0000f, 0.0000f, 0.0000f, 0.0000f,
&&&&&&&&0.0000f, 1.0000f, 0.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f,
&&&&&&&&0.0000f, 1.0000f, 0.0000f, 0.0000f, 0.0000f, 0.0000f, 1.0000f,
&&&&&&&&0.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.0000f, 1.0000f,
&&&&&&&&0.0000f, 0.0000f, 0.0000f, 0.0000f, 1.0000f, };
上坐标是由3ds max 场景中导出,除此之外将原有的顶点坐标及顶点索引数组的内容也一并更新,也是从同一 3ds max 场景中导出(该场景只有一个立方体)
private float[] data_vertices = { -5.0f, -5.0f, -5.0f, -5.0f, 5.0f, -5.0f,
&&&&&&&&5.0f, 5.0f, -5.0f, 5.0f, 5.0f, -5.0f, 5.0f, -5.0f, -5.0f, -5.0f,
&&&&&&&&-5.0f, -5.0f, -5.0f, -5.0f, 5.0f, 5.0f, -5.0f, 5.0f, 5.0f, 5.0f,
&&&&&&&&5.0f, 5.0f, 5.0f, 5.0f, -5.0f, 5.0f, 5.0f, -5.0f, -5.0f, 5.0f,
&&&&&&&&-5.0f, -5.0f, -5.0f, 5.0f, -5.0f, -5.0f, 5.0f, -5.0f, 5.0f, 5.0f,
&&&&&&&&-5.0f, 5.0f, -5.0f, -5.0f, 5.0f, -5.0f, -5.0f, -5.0f, 5.0f, -5.0f,
&&&&&&&&-5.0f, 5.0f, 5.0f, -5.0f, 5.0f, 5.0f, 5.0f, 5.0f, 5.0f, 5.0f, 5.0f,
&&&&&&&&-5.0f, 5.0f, 5.0f, -5.0f, -5.0f, 5.0f, 5.0f, -5.0f, -5.0f, 5.0f,
&&&&&&&&-5.0f, -5.0f, 5.0f, 5.0f, -5.0f, 5.0f, 5.0f, 5.0f, 5.0f, 5.0f,
&&&&&&&&5.0f, 5.0f, -5.0f, -5.0f, 5.0f, -5.0f, -5.0f, -5.0f, -5.0f, -5.0f,
&&&&&&&&-5.0f, 5.0f, -5.0f, -5.0f, 5.0f, -5.0f, 5.0f, 5.0f, -5.0f, 5.0f,
&&&&&&&&-5.0f, };
private byte[] data_triangles = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12,
&&&&&&&&13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29,
&&&&&&&&30, 31, 32, 33, 34, 35, };
在 createBuffers 中添加代码创建纹理坐标缓冲对象
// 创建纹理坐标缓冲
tvertices = ByteBuffer.allocateDirect(data_tvertices.length * 4);
tvertices.order(ByteOrder.nativeOrder());
tvertices.asFloatBuffer().put(data_tvertices);
tvertices.position(0);
最后在绘制代码中添加纹理及纹理坐标设置的代码
// 启用顶点数组、纹理坐标数组
gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
// 设置正面
gl.glFrontFace(GL10.GL_CW);
// 设置顶点数组指针为 ByteBuffer 对象 vertices
// 第一个参数为每个顶点包含的数据长度(以第二个参数表示的数据类型为单位)
gl.glVertexPointer(3, GL10.GL_FLOAT, 0, vertices);
gl.glTexCoordPointer(2, GL10.GL_FLOAT, 0, tvertices);
// 绑定纹理
gl.glBindTexture(GL10.GL_TEXTURE_2D, texture);
// 绘制 triangles 表示的三角形
gl.glDrawElements(GL10.GL_TRIANGLES, triangles.remaining(),
&&&&&&&&GL10.GL_UNSIGNED_BYTE, triangles);
// 禁用顶点、纹理坐标数组
gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
gl.glDisableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
修改投景变换矩阵以显示这个稍大些的立方体
GLU.gluLookAt(gl, 30f, 30f, 30f, 0f, 0f, 0f, 0, 1, 0);
好, 运行一下,看上去还不错
最终代码:&&
阅读(8369) | 评论(0) | 转发(0) |
相关热门文章
给主人留下些什么吧!~~
请登录后评论。Android OpenGL ES 应用(二) 纹理
要是做复杂的OpenGL应用程序,一定会用到纹理技术。纹理说白了就是把图片或者视频图像绘制到OpenGL空间中。
因此纹理也有坐标系,称ST坐标,或者UV
上面是纹理坐标空间,但没有固定的方向
下面演示加载一张image作为纹理贴图。
public class TextureUtils {
public static int createTexture(InputStream ins) {
int[] textures = new int[1];
GLES20.glGenTextures(1, textures, 0);//生成一个纹理
int textureId = textures[0];
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, textureId);
GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MIN_FILTER,GLES20.GL_NEAREST);
GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D,GLES20.GL_TEXTURE_MAG_FILTER,GLES20.GL_LINEAR);
GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_S,GLES20.GL_CLAMP_TO_EDGE);
GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_T,GLES20.GL_CLAMP_TO_EDGE);
//上面是纹理贴图的取样方式,包括拉伸方式,取临近值和线性值
Bitmap bitmap = BitmapFactory.decodeStream(ins);
GLUtils.texImage2D(GLES20.GL_TEXTURE_2D, 0, bitmap, 0);//让图片和纹理关联起来,加载到OpenGl空间中
Log.d(OPENGL,bitmap: + bitmap);
bitmap.recycle();//不需要,可以释放
return textureId;
public class MyRenderer implements Renderer {
public static float[] projMatrix = new float[16];// 投影
public static float[] viewMatrix = new float[16];// 相机
public static float[] mViewPjM// 总变换矩阵
public static float[] matrixs = new float[16];
public static int textureId = -1;
MyDrawModel drawM
public MyRenderer(Context context) {
this.context =
public void onDrawFrame(GL10 arg0) {
GLES20.glClear( GLES20.GL_DEPTH_BUFFER_BIT | GLES20.GL_COLOR_BUFFER_BIT);
Log.e(, textureId: + textureId);
drawModel.drawFrame(textureId);
public void onSurfaceChanged(GL10 arg0, int w, int h) {
GLES20.glViewport(0, 0, w, h);
float ratio = (float) w /
Matrix.frustumM(projMatrix, 0, -ratio, ratio, -1, 1, 1, 10);//投影矩阵设置
Matrix.setLookAtM(viewMatrix, 0, 0, 0, 3, 0, 0, 0, 0.0f, 1.0f, 0.0f);//摄像机坐标设置
public void onSurfaceCreated(GL10 g, EGLConfig eglConfig) {
GLES20.glClearColor(0.5f,0.5f,0.5f, 1.0f);
GLES20.glEnable(GLES20.GL_DEPTH_TEST);
InputStream ins =
drawModel = new MyDrawModel();
drawModel.init();
ins = context.getAssets().open(house.jpg);
textureId = TextureUtils.createTexture(ins);
Log.e(, textureId: + textureId);
} catch (IOException e) {
e.printStackTrace();
} finally {
ins.close();
} catch (IOException e) {
e.printStackTrace();
GLES20.glDisable(GLES20.GL_CULL_FACE);
public class MyDrawModel {
private int programId;
private int mVPMatrixH // 总变换矩阵引用id
private int positionH // 顶点位置id
private int texCoorH // 顶点纹理坐标id
private FloatBuffer vertexB
private FloatBuffer texCoorB
public MyDrawModel() {
public void init() {
initData();
int vertexsharder = pileScript(GLES20.GL_VERTEX_SHADER,
GLScript.vertex2);
int fragmentsharder = pileScript(GLES20.GL_FRAGMENT_SHADER,
GLScript.fragment2);
programId = GLHelper.linkAttach(vertexsharder, fragmentsharder);
boolean isOK = GLHelper.checkProgram(programId);
positionHandle = GLES20.glGetAttribLocation(programId, aPosition);
texCoorHandle = GLES20.glGetAttribLocation(programId, aTexCoor);
mVPMatrixHandle = GLES20.glGetUniformLocation(programId, uMVPMatrix);
Log.d(OPENGL, positionHandle: + positionHandle + ;texCoorHandle:
+ texCoorHandle + ;mVPMatrixHandle: + mVPMatrixHandle + ;
private void initData() {
//X,Y,Z,绘画的顶点
float vertices[] = new float[] {
-1.8f, -1f, 0,
1.8f, -1f, 0,
-1.8f, -1f, 0
ByteBuffer vb = ByteBuffer.allocateDirect(vertices.length * 4);
vb.order(ByteOrder.nativeOrder());
vertexBuffer = vb.asFloatBuffer();
vertexBuffer.put(vertices);
vertexBuffer.position(0);
//纹理空间坐标 S,T
float texCoor[] = new float[] {
0.5f, 0.5f,
ByteBuffer cb = ByteBuffer.allocateDirect(texCoor.length * 4);
cb.order(ByteOrder.nativeOrder());
texCoorBuffer = cb.asFloatBuffer();
texCoorBuffer.put(texCoor);
texCoorBuffer.position(0);
public void drawFrame(int textureId) {
GLES20.glUseProgram(programId);
// // 初始化矩阵
Matrix.setRotateM(MyRenderer.matrixs, 0, 0, 1, 0, 0);
Matrix.translateM(MyRenderer.matrixs, 0, 0, 0, 1);
//矩阵转换 ,投影矩阵,摄像机矩阵,模型矩阵
MyRenderer.mViewPjMatrix = new float[16];
Matrix.multiplyMM(MyRenderer.mViewPjMatrix, 0, MyRenderer.viewMatrix,0, MyRenderer.matrixs, 0);
Matrix.multiplyMM(MyRenderer.mViewPjMatrix, 0, MyRenderer.projMatrix,0, MyRenderer.mViewPjMatrix, 0);
GLES20.glUniformMatrix4fv(mVPMatrixHandle, 1, false, MyRenderer.mViewPjMatrix, 0);
GLES20.glVertexAttribPointer(positionHandle, 3, GLES20.GL_FLOAT, false, 3 * 4, vertexBuffer);
GLES20.glVertexAttribPointer(texCoorHandle,
2, GLES20.GL_FLOAT, false, 2 * 4, texCoorBuffer);
GLES20.glEnableVertexAttribArray(positionHandle);
GLES20.glEnableVertexAttribArray(texCoorHandle);
GLES20.glActiveTexture(GLES20.GL_TEXTURE0);
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, textureId);
GLES20.glDrawArrays(GLES20.GL_TRIANGLE_FAN, 0, 6);//六个定点,绘制三角形
OpenGL需要把设备的坐标归一化到[-1,-1]空间中,所以这里涉及到矩阵相乘的理论,包括世界坐标,物体坐标,摄像机坐标的转换,以后会详细介绍。
public class GLScript {
public GLScript() {
public static final String vertex1 = attribute vec4 mP
void main()
gl_Position=mP
public static final String fragment1 = pre
uniform vec4 mC
void main(){ gl_FragColor=mC
public static final String vertex2 = uniform mat4 uMVPM
+ attribute vec3 aP
+ attribute vec2 aTexC
+ varying vec2 vTextureC
+ void main() {
+ gl_Position = uMVPMatrix * vec4(aPosition,1);
+ vTextureCoord = aTexC
public static final String fragment2 = pre
+ varying vec2 vTextureC
+ uniform sampler2D sT
+ void main() {
+ vec2 coord =
+ coord.s =
coord.s * 0.5;
//其实是去图像的一半,向量缩小了
+ gl_FragColor = texture2D(sTexture, coord);
coord.s * 0.5;
这样是取纹理图像的一半,显示到界面上也就是图片的前半部分内容
其它的工具类和上一篇文章一样。3589人阅读
OpenGL ES(3)
Android (NDK)(10)
PC上OpenGL渲染到纹理,很容易得到透明背景,但是在android上OpenGL ES渲染出来是黑色背景,对于这个问题,想了两个解决办法。
1& 让android的OpenGL ES环境支持RGBA,默认android系统给出的渲染环境是RGB565的,这是出于性能原因。如果framebuffer不支持alpha通道,renderToTexture当然得不到透明纹理。
& & & & 在androidmanifest.xml文件里改用OpenGL ES2.0,并为GLSurefaceView.Render改用RGBA8888配置,仍然得不到透明图像。尝试失败。
2& 第二种憋足的办法,读取render2texture的pixels,然后手动修改其黑色背景为透明。渲染后使用glReadPixels读取,但是这种办法效率低下,每一帧都这样干是不可能的。
&&相关文章推荐
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:47075次
排名:千里之外
原创:24篇
评论:14条
(1)(1)(2)(1)(1)(1)(1)(1)(1)(1)(1)(1)(1)(3)(5)(4)(1)(2)(1)(2)(2)
(window.slotbydup = window.slotbydup || []).push({
id: '4740881',
container: s,
size: '200,200',
display: 'inlay-fix'Android OpenGL es 绘图示例 -
- ITeye博客
博客分类:
开始学OpenGL了,想找个例子,不过弄了好久不行,绘出来的都是黑屏一块,好不容易找到一个可用的例子
对原作者表示感谢
直接上例子吧
Activity很简单,创建一个GLSurfaceView,然后set一个renderer对象
public void onCreate(Bundle savedInstanceState)
super.onCreate(savedInstanceState);
// 创建一个GLSurfaceView,用于显示OpenGL绘制的图形
GLSurfaceView glView = new GLSurfaceView(this);
// 创建GLSurfaceView的内容绘制器
MyRenderer myRender = new MyRenderer();
// 为GLSurfaceView设置绘制器
glView.setRenderer(myRender);
setContentView(glView);
接下来自己要写一个类,实现Renderer接口,接口中的方法就不再介绍了,到处都有介绍,下边是Renderer类的代码
package org.crazyit.
import java.nio.ByteB
import java.nio.ByteO
import java.nio.IntB
import javax.microedition.khronos.egl.EGLC
import javax.microedition.khronos.opengles.GL10;
import android.annotation.SuppressL
import android.annotation.TargetA
import android.opengl.GLSurfaceView.R
import android.os.B
@TargetApi(Build.VERSION_CODES.CUPCAKE)
public class MyRenderer implements Renderer {
// 关于0x10000注明:Thus 0x10000 means a hexadecimal memory address 10000
// 就像cai_huan25大哥说的,大家把它理解为google画图单位就ok
static int one = 0x10000;
// Int型的缓冲区,下面定义了四个分别是三角形,正方形,三角形颜色,正方形颜色的缓冲区
private static IntBuffer triangleB
private static IntBuffer quaterB
private static IntBuffer color1B
private static IntBuffer color2B
// 三角形顶点,分别对应x,y,z,因此程序为二维,所以z轴上皆为0
private int[] vertices = new int[] {
0, one, 0,
-one, -one, 0,
one, -one, 0
//以正方形为例,说明坐标轴:坐标中心位于正方形中心,下面四个顶点分别是右上角,左上角,右下角,左下角
private int[] quater = new int[] {
one, one, 0,
-one, one, 0,
one, -one, 0,
-one, -one, 0
//定义每个顶点的颜色,每个顶点的颜色皆由(r,g,b,a)
//三角形各顶点颜色(三个顶点)
private int[] color = new int[] {
one, 0, 0,one,
0, one,0, one,
0,0,one, one
//正方形各顶点颜色(4个顶点)
private int[] color2 = new int[] {
one, 0, 0, 0,
one, one, 0, 0,
one,one,one, 0,
0, one, one, 0
//实现Renderer接口的方法onDrawFrame
@TargetApi(Build.VERSION_CODES.CUPCAKE)
@SuppressLint("NewApi")
public void onDrawFrame(GL10 gl) {
//因为在glVertexPointer或者是glColorPointer方法中要求传入一个直接的Buffer,
//所以下面的vbb1,vbb2,colorvbb1,colorvbb2皆为创建一个直接的Buffer
//以第一个为例说明,首先用ByteBuffer的allocateDirect方法来分配新的直接字节缓冲区。
//因1个Int有4个byte,所以将vertices的长度乘以4
// order(ByteOrder.nativeOrder)方法以本机字节顺序来修改此缓冲区的字节顺序
//然后用asIntBuffer方法创建此字节缓冲区的视图,作为 int 缓冲区。
//put方法将给定 int 写入此缓冲区的当前位置,然后该位置递增。
//position方法设置此缓冲区的位置。如果标记已定义并且大于新的位置,则要丢弃该标记。
// triangle的ByteBuffer
ByteBuffer vbb1 = ByteBuffer.allocateDirect(vertices.length * 4);
vbb1.order(ByteOrder.nativeOrder());
triangleBuffer = vbb1.asIntBuffer();
triangleBuffer.put(vertices);
triangleBuffer.position(0);
// quater的ByteBuffer
ByteBuffer vbb2 = ByteBuffer.allocateDirect(quater.length * 4);
vbb2.order(ByteOrder.nativeOrder());
quaterBuffer = vbb2.asIntBuffer();
quaterBuffer.put(quater);
quaterBuffer.position(0);
// color的ByteBuffer
ByteBuffer colorvbb1 = ByteBuffer.allocateDirect(color.length * 4);
colorvbb1.order(ByteOrder.nativeOrder());
color1Buffer = colorvbb1.asIntBuffer();
color1Buffer.put(color);
color1Buffer.position(0);
// color2的ByteBuffer
ByteBuffer colorvbb2 = ByteBuffer.allocateDirect(color2.length * 4);
colorvbb2.order(ByteOrder.nativeOrder());
color2Buffer = colorvbb2.asIntBuffer();
color2Buffer.put(color2);
color2Buffer.position(0);
// 绘制Triangles
// 清除屏幕和深度缓存
gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
// 重置当前的模型观察矩阵
gl.glLoadIdentity();
//以下两步为绘制颜色与顶点前必做操作
//(颜色可采用另一种简单方式,说见http://blog.csdn.net/Simdanfeg/archive//6255932.aspx)
// 允许设置顶点
//GL10.GL_VERTEX_ARRAY顶点数组
gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
// 允许设置颜色
//GL10.GL_COLOR_ARRAY颜色数组
gl.glEnableClientState(GL10.GL_COLOR_ARRAY);
// 左移1.5单位,并移入屏幕6.0
gl.glTranslatef(-1.5f, 0.0f, -6.0f);
//GL_FIXED,GL_FLOAT,GL_UNSIGNED_BYTE
//更多信息见
/wireless/Article/
//参数中的GL_FIXED表示我们之前定义的one为单位长度
// 设置三角形
gl.glVertexPointer(3, GL10.GL_FIXED, 0, triangleBuffer);
// 设置三角形颜色
gl.glColorPointer(4, GL10.GL_FIXED, 0, color1Buffer);
// 绘制三角形
//GL10.GL_TRIANGLES:把每三个顶点作为一个独立的三角形。顶点3n-2,3n-1和3n定义了第n个三角形,总共绘制N/3个三角形。
gl.glDrawArrays(GL10.GL_TRIANGLES, 0, 3);
// 重置当前模型的观察矩阵
gl.glLoadIdentity();
// 左移1.5单位,并移入屏幕6.0
gl.glTranslatef(1.5f, 0.0f, -6.0f);
// 设置正方形
gl.glVertexPointer(3, GL10.GL_FIXED, 0, quaterBuffer);
// 设置正方形颜色
gl.glColorPointer(4, GL10.GL_FIXED, 0, color2Buffer);
//GL_TRIANGLE_STRIP:绘制一组相连的三角形。对于奇数点n,顶点n,n+1和n+2定义了第n个三角形;
//对于偶数n,顶点n+1,n和n+2定义了第n个三角形,总共绘制N-2个三角形。
// 绘制正方形
gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 0, 4);
// 取消颜色设置
gl.glDisableClientState(GL10.GL_COLOR_ARRAY);
// 取消顶点设置
gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
//实现Renderer接口的方法onSurfaceChanged
public void onSurfaceChanged(GL10 gl, int width, int height) {
float ratio = (float) width /
// 设置OpenGL场景的大小,(0,0)表示窗口内部视口的左下角,(w,h)指定了视口的大小
gl.glViewport(0, 0, width, height);
// 设置投影矩阵
gl.glMatrixMode(GL10.GL_PROJECTION);
// 重置投影矩阵
gl.glLoadIdentity();
// 设置视口的大小
gl.glFrustumf(-ratio, ratio, -1, 1, 1, 10);
//以下两句告诉opengl es,以后所有的变换都将影响这个模型(即我们绘制的图形)
gl.glMatrixMode(GL10.GL_MODELVIEW);
gl.glLoadIdentity();
//实现Renderer接口的方法onSurfaceCreated
public void onSurfaceCreated(GL10 gl, EGLConfig config) {
// 告诉系统对透视进行修正(选择效率优先还是速度优先,这里我们选择速度优先)
gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT, GL10.GL_FASTEST);
// 用黑色来清除屏幕颜色
gl.glClearColor(0, 0, 0, 0);
// 启用阴影平滑
gl.glShadeModel(GL10.GL_SMOOTH);
// 设置深度缓存
gl.glClearDepthf(1.0f);
// 启用深度测试
gl.glEnable(GL10.GL_DEPTH_TEST);
// 所做深度测试的类型
gl.glDepthFunc(GL10.GL_LEQUAL);
程序的运行结果是一个是三角形和正方形
下载次数: 47
guozhenqian
浏览: 101413 次
来自: 北京
public static byte[] getBytes4 ...
& target=&_blank&quot ...
为什么我的会报“this.cm.rows.length”为空或 ...}

我要回帖

更多关于 opengl es 3d模型 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信