您的位置:首页 > 移动开发 > Android开发

Android OpenGL 2D贴图切换

2014-10-19 18:02 204 查看
/*

* Copyright (C) 2009 The Android Open Source Project

*

* Licensed under the Apache License, Version 2.0 (the "License");

* you may not use this file except in compliance with the License.

* You may obtain a copy of the License at

*

* http://www.apache.org/licenses/LICENSE-2.0
*

* Unless required by applicable law or agreed to in writing, software

* distributed under the License is distributed on an "AS IS" BASIS,

* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

* See the License for the specific language governing permissions and

* limitations under the License.

*/

package com.example.hellojni;

import java.nio.ByteBuffer;

import java.nio.ByteOrder;

import java.nio.FloatBuffer;

import java.nio.IntBuffer;

import java.nio.ShortBuffer;

import javax.microedition.khronos.egl.EGLConfig;

import javax.microedition.khronos.opengles.GL10;

import android.app.Activity;

import android.content.Context;

import android.graphics.Bitmap;

import android.graphics.BitmapFactory;

import android.graphics.Bitmap.Config;

import android.util.Log;

import android.view.View;

import android.view.Window;

import android.view.WindowManager;

import android.widget.TextView;

import android.opengl.GLSurfaceView;

import android.opengl.GLSurfaceView.Renderer;

import android.opengl.GLUtils;

import android.os.Bundle;



public class HelloJni extends Activity

{

String ss;

/** Called when the activity is first created. */

@Override

public void onCreate(Bundle savedInstanceState)

{

onCreateGL2(savedInstanceState);

//onCreateTest( savedInstanceState);

}



public void onCreateTest(Bundle savedInstanceState)

{

super.onCreate(savedInstanceState);

/* Create a TextView and set its content.

* the text is retrieved by calling a native

* function.

*/

myJni("vvvvvvvvvvvv");

TextView tv = new TextView(this);

//tv.setText( stringFromJNI() );

tv.setText( ss );

setContentView(tv);

}



public void myCallbackFunc(String nMsg)

{

ss=nMsg;

}

/* A native method that is implemented by the

* 'hello-jni' native library, which is packaged

* with this application.

*/

public native String stringFromJNI();

public native String myJni(String nParam);

/* This is another native method declaration that is *not*

* implemented by 'hello-jni'. This is simply to show that

* you can declare as many native methods in your Java code

* as you want, their implementation is searched in the

* currently loaded native libraries only the first time

* you call them.

*

* Trying to call this function will result in a

* java.lang.UnsatisfiedLinkError exception !

*/

public native String unimplementedStringFromJNI();

/* this is used to load the 'hello-jni' library on application

* startup. The library has already been unpacked into

* /data/data/com.example.hellojni/lib/libhello-jni.so at

* installation time by the package manager.

*/

static {

System.loadLibrary("hello-jni");

}



//-------------------------------------------



Renderer render=new GLRender();

public void onCreateGL(Bundle savedInstanceState)

{

super.onCreate(savedInstanceState);

GLSurfaceView gview=new GLSurfaceView(this);

gview.setRenderer(render);

setContentView(gview);

}



public class GLRender implements Renderer {

private float rotateTri;

private int ne=0x10000;

//三角形的一个顶点

private IntBuffer triggerBuffer= fBuffer(new int[]{

0,1,0, //上顶点

-1,-1,0, //左顶点

1,-1,0 //右下点

});

private IntBuffer colorBuffer= fBuffer(new int[]{

1,0,0,1,

0,1,0,1,

0,0,1,1

});



@Override

public void onDrawFrame(GL10 gl) {

// 清除屏幕和深度缓存

gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);

// 重置当前的模型观察矩阵

gl.glLoadIdentity();

// 左移 1.5 单位,并移入屏幕 6.0

gl.glTranslatef(-1.5f, 0.0f, -6.0f);

//设置旋转

gl.glRotatef(rotateTri, 0.0f, 1.0f, 0.0f);

//设置定点数组

gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);

//设置颜色数组

gl.glEnableClientState(GL10.GL_COLOR_ARRAY);

gl.glColorPointer(4, GL10.GL_FIXED, 0, colorBuffer);

// 设置三角形顶点

gl.glVertexPointer(3, GL10.GL_FIXED, 0, triggerBuffer);

//绘制三角形

gl.glDrawArrays(GL10.GL_TRIANGLES, 0, 3);

//取消顶点数组

gl.glDisableClientState(GL10.GL_COLOR_ARRAY);

//绘制三角形结束

gl.glFinish();



//Toast.makeText(getApplicationContext() , "onDrawFrame", 1000).show();

Log.v("onDrawFrame","-----------onDrawFrame");

}



@Override

public void onSurfaceChanged(GL10 gl, int width, int height) {

float ratio = (float) width / height;

//设置OpenGL场景的大小

gl.glViewport(0, 0, width, height);

//设置投影矩阵

gl.glMatrixMode(GL10.GL_PROJECTION);

//重置投影矩阵

gl.glLoadIdentity();

// 设置视口的大小

gl.glFrustumf(-ratio, ratio, -1, 1, 1, 10);

// 选择模型观察矩阵

gl.glMatrixMode(GL10.GL_MODELVIEW);

// 重置模型观察矩阵

gl.glLoadIdentity();



//Toast.makeText(getApplicationContext() , "onSurfaceChanged", 1000).show();

Log.v("onSurfaceChanged","-----------onDrawFrame");

}





@Override

public void onSurfaceCreated(GL10 gl,

javax.microedition.khronos.egl.EGLConfig arg1) {

// TODO Auto-generated method stub

// 启用阴影平滑

gl.glShadeModel(GL10.GL_SMOOTH);

// 黑色背景,银灰色

gl.glClearColor(1,1,1, 0);

// 设置深度缓存

gl.glClearDepthf(1.0f);

// 启用深度测试

gl.glEnable(GL10.GL_DEPTH_TEST);

// 所作深度测试的类型

gl.glDepthFunc(GL10.GL_LEQUAL);

// 告诉系统对透视进行修正

gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT, GL10.GL_FASTEST);



//Toast.makeText(getApplicationContext() , "onSurfaceCreated", 1000).show();

Log.v("onSurfaceCreated","-----------onDrawFrame");

}

}



public static class BufferUtil {

public static FloatBuffer mBuffer;

public static FloatBuffer floatToBuffer(float[] a){

//先初始化buffer,数组的长度*4,因为一个float占4个字节

ByteBuffer mbb = ByteBuffer.allocateDirect(a.length*4);

//数组排序用nativeOrder

mbb.order(ByteOrder.nativeOrder());

mBuffer = mbb.asFloatBuffer();

mBuffer.put(a);

mBuffer.position(0);

return mBuffer;

}

}



static IntBuffer floatBuffer;

public static IntBuffer fBuffer(int[] a) {

ByteBuffer mbb = ByteBuffer.allocateDirect(a.length * 4);

// 数组排列用nativeOrder

mbb.order(ByteOrder.nativeOrder());

floatBuffer = mbb.asIntBuffer();

floatBuffer.put(a);

floatBuffer.position(0);

return floatBuffer;

}



//------------------------------------代码段 2---------------------------------------

//public GLSurfaceView glView;

public Bitmap Bbitmap1;

public Bitmap Bbitmap2;

public void onCreateGL2(Bundle savedInstanceState)

{

super.onCreate(savedInstanceState);

// 去掉activity的标题,全屏显示

requestWindowFeature(Window.FEATURE_NO_TITLE);

getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,

WindowManager.LayoutParams.FLAG_FULLSCREEN);

View view=View.inflate(getApplicationContext(), R.layout.mainlayout, null);

GLSurfaceView glSurfaceView1=(GLSurfaceView) view.findViewById(R.id.GLSurfaceView1);

GLSurfaceView glSurfaceView2=(GLSurfaceView) view.findViewById(R.id.GLSurfaceView2);

GLSurfaceView glSurfaceView3=(GLSurfaceView) view.findViewById(R.id.GLSurfaceView3);

GLSurfaceView glSurfaceView4=(GLSurfaceView) view.findViewById(R.id.GLSurfaceView4);

glSurfaceView1.setRenderer(new SimpleRenderer(glSurfaceView1));//(new MyRenderer());//

glSurfaceView2.setRenderer(new SimpleRenderer(glSurfaceView2));//(new MyRenderer());//

glSurfaceView3.setRenderer(new SimpleRenderer(glSurfaceView3));//(new MyRenderer());//

glSurfaceView4.setRenderer(new SimpleRenderer(glSurfaceView4));//(new MyRenderer());//

setContentView(view);

/*glView = new GLSurfaceView(this);

glView.setRenderer(new SimpleRenderer());

setContentView(glView);*/

int[] colors=new int[168*168];

for(int i=0;i<168*168;i++)

colors[i]=0x8F00FF00;

Bbitmap1 = BitmapFactory.decodeStream( this.getResources().openRawResource(R.drawable.phone));

Bbitmap2 = BitmapFactory.decodeStream( this.getResources().openRawResource(R.drawable.people));

//Bbitmap = Bitmap.createBitmap( colors, 168, 168, Config.ARGB_8888);

}



//应用程序背景透明 http://www.android100.org/html/201406/09/22092.html

class SimpleRenderer implements Renderer {

GLSurfaceView glSurfaceView;

FloatBuffer vertices;

FloatBuffer texture;

ShortBuffer indices;

int textureId;

int i=0;

public SimpleRenderer(GLSurfaceView glSurfaceView) {

this.glSurfaceView=glSurfaceView;

ByteBuffer byteBuffer = ByteBuffer.allocateDirect(4 * 2 * 4);

byteBuffer.order(ByteOrder.nativeOrder());

vertices = byteBuffer.asFloatBuffer();

// vertices.put( new float[] { -80f, -120f,0,1f,

// 80f, -120f, 1f,1f,

// -80f, 120f, 0f,0f,

// 80f,120f, 1f,0f});

/*vertices.put( new float[] { -80f, -120f,

80f, -120f,

-80f, 120f,

80f, 120f});*/



ByteBuffer indicesBuffer = ByteBuffer.allocateDirect(6 * 2);

indicesBuffer.order(ByteOrder.nativeOrder());

indices = indicesBuffer.asShortBuffer();

indices.put(new short[] { 0, 1, 2,1,2,3});



ByteBuffer textureBuffer = ByteBuffer.allocateDirect(4 * 2 * 4);

textureBuffer.order(ByteOrder.nativeOrder());

texture = textureBuffer.asFloatBuffer();

texture.put( new float[] { 0,1f,

1f,1f,

0f,0f,

1f,0f});



indices.position(0);



texture.position(0);



}

@Override

public void onSurfaceCreated(GL10 gl, javax.microedition.khronos.egl.EGLConfig config) {

Log.d("GLSurfaceViewTest", "surface created");

textureId = createTextureId( gl);

// 关闭抗抖动

/*gl.glDisable(GL10.GL_DITHER);

// 设置系统对透视进行修正

gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT, GL10.GL_FASTEST);

gl.glClearColor(0, 0, 0, 0);

// 设置阴影平滑模式

gl.glShadeModel(GL10.GL_SMOOTH);

// 启用深度测试

gl.glEnable(GL10.GL_DEPTH_TEST);

// 设置深度测试的类型

gl.glDepthFunc(GL10.GL_LEQUAL); */

// 启用2D纹理贴图

//gl.glEnable(GL10.GL_TEXTURE_2D);

}

@Override

public void onSurfaceChanged(GL10 gl, int width, int height) {

Log.d("GLSurfaceViewTest", "surface changed: " + width + "x"

+ height);

//loadTexture("bobrgb888.png",gl);

vertices.put( new float[] { -width/2, -height/2,

width/2, -height/2,

-width/2, height/2,

width/2, height/2});

vertices.position(0);

//定义显示在屏幕上的什么位置(opengl 自动转换)

gl.glViewport(0, 0, glSurfaceView.getWidth(), glSurfaceView.getHeight());

gl.glClear(GL10.GL_COLOR_BUFFER_BIT);

gl.glMatrixMode(GL10.GL_PROJECTION);

gl.glLoadIdentity();

gl.glOrthof(-width/2, width/2, -height/2, height/2, 1, -1);

gl.glEnable(GL10.GL_TEXTURE_2D);

}

@Override

public void onDrawFrame(GL10 gl) {

loadTexture("bobrgb888.png",gl);

//

//绑定纹理IDGL_COLOR_ARRAY

gl.glBindTexture(GL10.GL_TEXTURE_2D, textureId);

gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);

gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY);//

gl.glVertexPointer(2, GL10.GL_FLOAT, 0, vertices);

gl.glTexCoordPointer(2, GL10.GL_FLOAT, 0, texture);

// gl.glRotatef(1, 0, 1, 0);

gl.glDrawElements(GL10.GL_TRIANGLE_STRIP, 6,

GL10.GL_UNSIGNED_SHORT, indices);

gl.glDisableClientState(GL10.GL_TEXTURE_COORD_ARRAY);

// Disable the use of textures.

//gl.glDisable(GL10.GL_TEXTURE_2D);

}

public int createTextureId(GL10 gl)

{

int textureIds[] = new int[1];

gl.glGenTextures(1, textureIds, 0);

int textureId = textureIds[0];

gl.glBindTexture(GL10.GL_TEXTURE_2D, textureId);

return textureId;

}

public int loadTexture(String fileName,GL10 gl) {

try {

i=(i+1)%2;

int[] colors=new int[168*168];

for(int i=0;i<168*168;i++)

colors[i]=0x8F00FF00;

//{0xFFFFFFFF,0xFF000000,0xFF33CCFF};

int[] pixels = new int[Bbitmap1.getWidth()*Bbitmap1.getHeight()];

if(i==0)

Bbitmap1.getPixels(pixels,0,Bbitmap1.getWidth(),0,0,Bbitmap1.getWidth(),Bbitmap1.getHeight());

else

Bbitmap2.getPixels(pixels,0,Bbitmap2.getWidth(),0,0,Bbitmap2.getWidth(),Bbitmap2.getHeight());

Bitmap bitmap = Bitmap.createBitmap( pixels, 168, 168, Config.ARGB_8888);//Bbitmap);//Bbitmap1;//

//Thread.sleep(40);

//Bitmap bitmap = Bitmap.createBitmap( Bbitmap, 0, 0, Bbitmap.getWidth(), Bbitmap.getHeight() );

//Bitmap bitmap = BitmapFactory.decodeStream(getAssets().open( "phone.png"));

//Thread.sleep(80);

//Log.d("loadTexture", bitmap.getHeight()+" "+bitmap.getWidth());

//200, 200, Config.ARGB_8888); //Bitmap.createBitmap(Bbitmap, 0, 0, Bbitmap.getWidth(), Bbitmap.getHeight());

//BitmapFactory.decodeStream( HelloJni.this.getResources().openRawResource(R.drawable.phone));//Bitmap.createBitmap(Bbitmap);//= BitmapFactory.decodeStream(getAssets().open( fileName));

//Bbitmap

//bitmap.

//gl.glDeleteTextures(1, textureIds, 0);//

GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, bitmap, 0);

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_NEAREST);

gl.glBindTexture(GL10.GL_TEXTURE_2D, 0);

bitmap.recycle();

//gl.glDeleteTextures();

return textureId;

} catch (Exception e) {

Log.d("TexturedRectangleTest",

"couldn't load asset 'bobrgb888.png'!");

throw new RuntimeException("couldn't load asset '" + fileName

+ "'");

}

}

}







public class MyRenderer implements GLSurfaceView.Renderer{

private float[] cubeVertices = {

-0.6f, -0.6f, 0.0f,

-0.6f, 0.6f,0.0f,

0.6f, 0.6f, 0.0f,

0.6f, 0.6f, 0.0f,

0.6f, -0.6f, 0.0f,

-0.6f, -0.6f, 0.0f,

};

// 定义立方体所需要的6个面(一共是12个三角形所需的顶点)

private float[] cubeFacets = { 0, 1, 2, 3, 4, 5,

};

// 定义纹理贴图的座标数据

private float[] cubeTextures = {

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.0f,0.0f,

// 0.0f,1.0f,

// 1.0f,1.0f,

// 1.0f,1.0f,

// 1.0f,0.0f,

// 0.0f,0.0f,

};

private Context context;

private FloatBuffer cubeVerticesBuffer;

private FloatBuffer cubeFacetsBuffer;

private FloatBuffer cubeTexturesBuffer;

// 定义本程序所使用的纹理

private int texture;

public MyRenderer( ){

this.context = HelloJni.this.getApplicationContext();

// 将立方体的顶点位置数据数组包装成FloatBuffer;

cubeVerticesBuffer = BufferUtil.floatToBuffer(cubeVertices);

// 将立方体的6个面(12个三角形)的数组包装成ByteBuffer

cubeFacetsBuffer = BufferUtil.floatToBuffer(cubeFacets);

// 将立方体的纹理贴图的座标数据包装成FloatBuffer

cubeTexturesBuffer = BufferUtil.floatToBuffer(cubeTextures);

// 将立方体的顶点位置数据数组包装成FloatBuffer;

// cubeVerticesBuffer = FloatBuffer.wrap(cubeVertices);

// // 将立方体的6个面(12个三角形)的数组包装成ByteBuffer

// cubeFacetsBuffer = ByteBuffer.wrap(cubeFacets);

// // 将立方体的纹理贴图的座标数据包装成FloatBuffer

// cubeTexturesBuffer = FloatBuffer.wrap(cubeTextures);

}

@Override

public void onDrawFrame(GL10 gl) {

// 清除屏幕缓存和深度缓存

gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);

// 启用顶点座标数据

gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);

// 启用贴图座标数组数据

gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY);

// 设置当前矩阵模式为模型视图。

gl.glMatrixMode(GL10.GL_MODELVIEW);

// --------------------绘制第一个图形---------------------

gl.glLoadIdentity();

// 把绘图中心移入屏幕2个单位

gl.glTranslatef(0f, 0.0f, -2.0f);

// 旋转图形

// gl.glRotatef(angley, 0, 1, 0);

// gl.glRotatef(anglex, 1, 0, 0);

// 设置顶点的位置数据

gl.glVertexPointer(3, GL10.GL_FLOAT, 0, cubeVerticesBuffer);

// 设置贴图的的座标数据

gl.glTexCoordPointer(2, GL10.GL_FLOAT, 0, cubeTexturesBuffer);

// 执行纹理贴图

gl.glBindTexture(GL10.GL_TEXTURE_2D, texture);

// 按cubeFacetsBuffer指定的面绘制三角形

gl.glDrawElements(GL10.GL_TRIANGLES, cubeFacetsBuffer.remaining(),

GL10.GL_UNSIGNED_BYTE, cubeFacetsBuffer);

// 绘制结束

gl.glFinish();

// 禁用顶点、纹理座标数组

gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);

gl.glDisableClientState(GL10.GL_TEXTURE_COORD_ARRAY);

}

@Override

public void onSurfaceChanged(GL10 gl, int width, int height) {

// 设置3D视窗的大小及位置

gl.glViewport(0, 0, width, height);

// 将当前矩阵模式设为投影矩阵

gl.glMatrixMode(GL10.GL_PROJECTION);

// 初始化单位矩阵

gl.glLoadIdentity();

// 计算透视视窗的宽度、高度比

float ratio = (float) width / height;

// 调用此方法设置透视视窗的空间大小。

gl.glFrustumf(-ratio, ratio, -1, 1, 1, 10);

}

@Override

public void onSurfaceCreated(GL10 gl, EGLConfig config) {

// 关闭抗抖动

gl.glDisable(GL10.GL_DITHER);

// 设置系统对透视进行修正

gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT, GL10.GL_FASTEST);

gl.glClearColor(0, 0, 0, 0);

// 设置阴影平滑模式

gl.glShadeModel(GL10.GL_SMOOTH);

// 启用深度测试

gl.glEnable(GL10.GL_DEPTH_TEST);

// 设置深度测试的类型

gl.glDepthFunc(GL10.GL_LEQUAL);

// 启用2D纹理贴图

gl.glEnable(GL10.GL_TEXTURE_2D);

// 装载纹理

loadTexture(gl);

}

private void loadTexture(GL10 gl)

{

Bitmap bitmap = null;

try

{

// 加载位图

bitmap = BitmapFactory.decodeResource(context.getResources(), R.drawable.phone);

int[] textures = new int[1];

// 指定生成N个纹理(第一个参数指定生成1个纹理),

// textures数组将负责存储所有纹理的代号。

gl.glGenTextures(1, textures, 0);

// 获取textures纹理数组中的第一个纹理

texture = textures[0];

// 通知OpenGL将texture纹理绑定到GL10.GL_TEXTURE_2D目标中

gl.glBindTexture(GL10.GL_TEXTURE_2D, texture);

// 设置纹理被缩小(距离视点很远时被缩小)时候的滤波方式

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);

// 加载位图生成纹理

GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, bitmap, 0); }

finally

{

// 生成纹理之后,回收位图

if (bitmap != null)

bitmap.recycle();

}

}

}



}

//http://www.baidu.com/s?ie=utf-8&f=8&rsv_bp=1&tn=baiduhome_pg&wd=Opengl%20android%20%20%E7%A4%BA%E4%BE%8B%E7%A8%8B%E5%BA%8F&rsv_spt=1&rsv_enter=1&rsv_sug3=9&rsv_sug4=907&rsv_sug2=0&inputT=3897

//http://www.open-open.com/lib/view/open1368327471219.html

//https://github.com/harism/android_page_curl

//http://www.j2megame.com/html/xwzx/ty/2390.html

Android 3D 游戏学习笔记(1)-openGL基础 http://sishuok.com/forum/blogPost/list/4591.html
被动渲染:

GLSurfaceView.setRenderMode(GLSurfaceView.RENDERMODE_WHEN_DIRTY);

GLSurfaceView.requestRender();
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: