初次提交
This commit is contained in:
@@ -0,0 +1,9 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<classpath>
|
||||
<classpathentry kind="src" path="src"/>
|
||||
<classpathentry kind="src" path="gen"/>
|
||||
<classpathentry kind="con" path="com.android.ide.eclipse.adt.ANDROID_FRAMEWORK"/>
|
||||
<classpathentry kind="lib" path="lib/jbullet.jar"/>
|
||||
<classpathentry kind="lib" path="lib/vecmath.jar"/>
|
||||
<classpathentry kind="output" path="bin"/>
|
||||
</classpath>
|
||||
@@ -0,0 +1,33 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<projectDescription>
|
||||
<name>Sample17_1</name>
|
||||
<comment></comment>
|
||||
<projects>
|
||||
</projects>
|
||||
<buildSpec>
|
||||
<buildCommand>
|
||||
<name>com.android.ide.eclipse.adt.ResourceManagerBuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
<buildCommand>
|
||||
<name>com.android.ide.eclipse.adt.PreCompilerBuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.jdt.core.javabuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
<buildCommand>
|
||||
<name>com.android.ide.eclipse.adt.ApkBuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
</buildSpec>
|
||||
<natures>
|
||||
<nature>com.android.ide.eclipse.adt.AndroidNature</nature>
|
||||
<nature>org.eclipse.jdt.core.javanature</nature>
|
||||
</natures>
|
||||
</projectDescription>
|
||||
@@ -0,0 +1,18 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:versionCode="1"
|
||||
android:versionName="1.0" package="com.bn.Sample17_1">
|
||||
<uses-sdk android:targetSdkVersion="8" android:minSdkVersion="8"></uses-sdk>
|
||||
<application android:icon="@drawable/icon" android:label="@string/app_name">
|
||||
<activity android:name="com.bn.Sample17_1.Sample17_1_Activity"
|
||||
android:label="@string/app_name">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN" />
|
||||
<category android:name="android.intent.category.LAUNCHER" />
|
||||
</intent-filter>
|
||||
</activity>
|
||||
|
||||
</application>
|
||||
|
||||
|
||||
</manifest>
|
||||
@@ -0,0 +1,9 @@
|
||||
precision mediump float;
|
||||
varying vec2 vTextureCoord;//接收从顶点着色器过来的参数
|
||||
uniform sampler2D sTexture;//纹理内容数据
|
||||
|
||||
void main()
|
||||
{
|
||||
//给此片元颜色值
|
||||
gl_FragColor = texture2D(sTexture, vTextureCoord);
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
uniform mat4 uMVPMatrix; //总变换矩阵
|
||||
attribute vec3 aPosition; //顶点位置
|
||||
attribute vec2 aTexCoor; //顶点纹理坐标
|
||||
varying vec2 vTextureCoord; //传给着色器的纹理坐标
|
||||
|
||||
|
||||
void main()
|
||||
{
|
||||
gl_Position = uMVPMatrix * vec4(aPosition,1); //根据总变换矩阵计算此次绘制此顶点位置
|
||||
|
||||
vTextureCoord=aTexCoor;
|
||||
}
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,13 @@
|
||||
# This file is automatically generated by Android Tools.
|
||||
# Do not modify this file -- YOUR CHANGES WILL BE ERASED!
|
||||
#
|
||||
# This file must be checked in Version Control Systems.
|
||||
#
|
||||
# To customize properties used by the Ant build system use,
|
||||
# "build.properties", and override values to adapt the script to your
|
||||
# project structure.
|
||||
|
||||
# Indicates whether an apk should be generated for each density.
|
||||
split.density=false
|
||||
# Project target.
|
||||
target=android-8
|
||||
@@ -0,0 +1,24 @@
|
||||
/* AUTO-GENERATED FILE. DO NOT MODIFY.
|
||||
*
|
||||
* This class was automatically generated by the
|
||||
* aapt tool from the resource data it found. It
|
||||
* should not be modified by hand.
|
||||
*/
|
||||
|
||||
package com.bn.Sample17_1;
|
||||
|
||||
public final class R {
|
||||
public static final class attr {
|
||||
}
|
||||
public static final class drawable {
|
||||
public static final int f6=0x7f020000;
|
||||
public static final int floor=0x7f020001;
|
||||
public static final int icon=0x7f020002;
|
||||
public static final int wood_bin0=0x7f020003;
|
||||
public static final int wood_bin1=0x7f020004;
|
||||
public static final int wood_bin2=0x7f020005;
|
||||
}
|
||||
public static final class string {
|
||||
public static final int app_name=0x7f030000;
|
||||
}
|
||||
}
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
After Width: | Height: | Size: 66 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 40 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 2.5 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 22 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 34 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 20 KiB |
@@ -0,0 +1,4 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<string name="app_name">Sample17_1</string>
|
||||
</resources>
|
||||
@@ -0,0 +1,16 @@
|
||||
package com.bn.Sample17_1;
|
||||
|
||||
public class Constant
|
||||
{
|
||||
final static float UNIT_SIZE=0.5f;//基本尺寸单元
|
||||
final static float TIME_STEP=1.0f/60;//模拟的周期
|
||||
final static int MAX_SUB_STEPS=5;//最大的子步数
|
||||
|
||||
final static float EYE_X=-3;//观察者的位置x
|
||||
final static float EYE_Y=4;//观察者的位置y
|
||||
final static float EYE_Z=3;//观察者的位置z
|
||||
|
||||
final static float TARGET_X=1;//目标的位置x
|
||||
final static float TARGET_Y=1;//目的位置Y
|
||||
final static float TARGET_Z=-3;//目标的位置Z
|
||||
}
|
||||
@@ -0,0 +1,169 @@
|
||||
package com.bn.Sample17_1;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.ByteOrder;
|
||||
import java.nio.FloatBuffer;
|
||||
import java.util.Stack;
|
||||
import android.opengl.Matrix;
|
||||
|
||||
//存储系统矩阵状态的类
|
||||
public class MatrixState
|
||||
{
|
||||
private static float[] mProjMatrix = new float[16];//4x4矩阵 投影用
|
||||
static float[] mVMatrix = new float[16];//摄像机位置朝向9参数矩阵
|
||||
static float[] mMVPMatrix;//最后起作用的总变换矩阵
|
||||
public static float[] lightLocationRed=new float[]{0,0,0};//红色定位光光源位置
|
||||
public static float[] lightLocationGreenBlue=new float[]{0,0,0};//天蓝色定位光光源位置
|
||||
public static FloatBuffer cameraFB;
|
||||
public static FloatBuffer lightPositionFBRed;
|
||||
public static FloatBuffer lightPositionFBGreenBlue;
|
||||
|
||||
//设置摄像机
|
||||
public static void setCamera
|
||||
(
|
||||
float cx, //摄像机位置x
|
||||
float cy, //摄像机位置y
|
||||
float cz, //摄像机位置z
|
||||
float tx, //摄像机目标点x
|
||||
float ty, //摄像机目标点y
|
||||
float tz, //摄像机目标点z
|
||||
float upx, //摄像机UP向量X分量
|
||||
float upy, //摄像机UP向量Y分量
|
||||
float upz //摄像机UP向量Z分量
|
||||
)
|
||||
{
|
||||
Matrix.setLookAtM
|
||||
(
|
||||
mVMatrix,
|
||||
0,
|
||||
cx,
|
||||
cy,
|
||||
cz,
|
||||
tx,
|
||||
ty,
|
||||
tz,
|
||||
upx,
|
||||
upy,
|
||||
upz
|
||||
);
|
||||
|
||||
float[] cameraLocation=new float[3];//摄像机位置
|
||||
cameraLocation[0]=cx;
|
||||
cameraLocation[1]=cy;
|
||||
cameraLocation[2]=cz;
|
||||
//摄像机位置矩阵
|
||||
ByteBuffer llbb = ByteBuffer.allocateDirect(3*4);
|
||||
llbb.order(ByteOrder.nativeOrder());//设置字节顺序
|
||||
cameraFB=llbb.asFloatBuffer();
|
||||
cameraFB.put(cameraLocation);
|
||||
cameraFB.position(0);
|
||||
}
|
||||
|
||||
//设置透视投影参数
|
||||
public static void setProjectFrustum
|
||||
(
|
||||
float left, //near面的left
|
||||
float right, //near面的right
|
||||
float bottom, //near面的bottom
|
||||
float top, //near面的top
|
||||
float near, //near面距离
|
||||
float far //far面距离
|
||||
)
|
||||
{
|
||||
Matrix.frustumM(mProjMatrix, 0, left, right, bottom, top, near, far);
|
||||
}
|
||||
|
||||
//设置正交投影参数
|
||||
public static void setProjectOrtho
|
||||
(
|
||||
float left, //near面的left
|
||||
float right, //near面的right
|
||||
float bottom, //near面的bottom
|
||||
float top, //near面的top
|
||||
float near, //near面距离
|
||||
float far //far面距离
|
||||
)
|
||||
{
|
||||
Matrix.orthoM(mProjMatrix, 0, left, right, bottom, top, near, far);
|
||||
}
|
||||
|
||||
//获取具体物体的总变换矩阵
|
||||
public static float[] getFinalMatrix()
|
||||
{
|
||||
float[] mMVPMatrix=new float[16];
|
||||
Matrix.multiplyMM(mMVPMatrix, 0, mVMatrix, 0, currMatrix, 0);
|
||||
Matrix.multiplyMM(mMVPMatrix, 0, mProjMatrix, 0, mMVPMatrix, 0);
|
||||
return mMVPMatrix;
|
||||
}
|
||||
|
||||
//设置红色灯光位置的方法
|
||||
public static void setLightLocationRed(float x,float y,float z)
|
||||
{
|
||||
lightLocationRed[0]=x;
|
||||
lightLocationRed[1]=y;
|
||||
lightLocationRed[2]=z;
|
||||
ByteBuffer llbb = ByteBuffer.allocateDirect(3*4);
|
||||
llbb.order(ByteOrder.nativeOrder());//设置字节顺序
|
||||
lightPositionFBRed=llbb.asFloatBuffer();
|
||||
lightPositionFBRed.put(lightLocationRed);
|
||||
lightPositionFBRed.position(0);
|
||||
}
|
||||
|
||||
//设置天蓝色灯光位置的方法
|
||||
public static void setLightLocationGreenBlue(float x,float y,float z)
|
||||
{
|
||||
lightLocationGreenBlue[0]=x;
|
||||
lightLocationGreenBlue[1]=y;
|
||||
lightLocationGreenBlue[2]=z;
|
||||
ByteBuffer llbb = ByteBuffer.allocateDirect(3*4);
|
||||
llbb.order(ByteOrder.nativeOrder());//设置字节顺序
|
||||
lightPositionFBGreenBlue=llbb.asFloatBuffer();
|
||||
lightPositionFBGreenBlue.put(lightLocationGreenBlue);
|
||||
lightPositionFBGreenBlue.position(0);
|
||||
}
|
||||
|
||||
public static Stack<float[]> mStack=new Stack<float[]>();//保护变换矩阵的栈
|
||||
static float[] currMatrix;//当前变换矩阵
|
||||
|
||||
public static void setInitStack()//获取不变换初始矩阵
|
||||
{
|
||||
currMatrix=new float[16];
|
||||
Matrix.setRotateM(currMatrix, 0, 0, 1, 0, 0);
|
||||
}
|
||||
|
||||
public static void pushMatrix()//保护变换矩阵
|
||||
{
|
||||
mStack.push(currMatrix.clone());
|
||||
}
|
||||
|
||||
public static void popMatrix()//恢复变换矩阵
|
||||
{
|
||||
currMatrix=mStack.pop();
|
||||
}
|
||||
|
||||
public static void translate(float x,float y,float z)//设置沿xyz轴移动
|
||||
{
|
||||
Matrix.translateM(currMatrix, 0, x, y, z);
|
||||
}
|
||||
|
||||
public static void rotate(float angle,float x,float y,float z)//设置绕xyz轴移动
|
||||
{
|
||||
Matrix.rotateM(currMatrix,0,angle,x,y,z);
|
||||
}
|
||||
|
||||
public static void scale(float x,float y,float z){
|
||||
Matrix.scaleM(currMatrix, 0, x, y, z);
|
||||
}
|
||||
|
||||
//插入自带矩阵
|
||||
public static void matrix(float[] self)
|
||||
{
|
||||
float[] result=new float[16];
|
||||
Matrix.multiplyMM(result,0,currMatrix,0,self,0);
|
||||
currMatrix=result;
|
||||
}
|
||||
|
||||
public static float[] getMMatrix() {
|
||||
return currMatrix;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,333 @@
|
||||
package com.bn.Sample17_1;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.ArrayList;
|
||||
|
||||
import android.opengl.GLES20;
|
||||
import android.opengl.GLSurfaceView;
|
||||
import android.opengl.GLUtils;
|
||||
import android.view.MotionEvent;
|
||||
import javax.microedition.khronos.egl.EGLConfig;
|
||||
import javax.microedition.khronos.opengles.GL10;
|
||||
import javax.vecmath.Vector3f;
|
||||
import com.bn.Sample17_1.R;
|
||||
import com.bulletphysics.collision.broadphase.AxisSweep3;
|
||||
import com.bulletphysics.collision.dispatch.CollisionConfiguration;
|
||||
import com.bulletphysics.collision.dispatch.CollisionDispatcher;
|
||||
import com.bulletphysics.collision.dispatch.DefaultCollisionConfiguration;
|
||||
import com.bulletphysics.dynamics.DiscreteDynamicsWorld;
|
||||
import com.bulletphysics.dynamics.RigidBody;
|
||||
import com.bulletphysics.dynamics.constraintsolver.SequentialImpulseConstraintSolver;
|
||||
import android.content.Context;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.BitmapFactory;
|
||||
import com.bulletphysics.collision.shapes.BoxShape;
|
||||
import com.bulletphysics.collision.shapes.CollisionShape;
|
||||
import com.bulletphysics.collision.shapes.StaticPlaneShape;
|
||||
|
||||
import static com.bn.Sample17_1.Constant.*;
|
||||
|
||||
class MySurfaceView extends GLSurfaceView
|
||||
{
|
||||
private SceneRenderer mRenderer;//场景渲染器
|
||||
DiscreteDynamicsWorld dynamicsWorld;//世界对象
|
||||
ArrayList<TexCube> tca=new ArrayList<TexCube>();
|
||||
ArrayList<TexCube> tcaForAdd=new ArrayList<TexCube>();
|
||||
CollisionShape boxShape;//共用的立方体
|
||||
CollisionShape planeShape;//共用的平面形状
|
||||
Sample17_1_Activity activity;
|
||||
|
||||
public MySurfaceView(Context context)
|
||||
{
|
||||
super(context);
|
||||
this.activity=(Sample17_1_Activity) context;
|
||||
this.setEGLContextClientVersion(2);
|
||||
//初始化物理世界
|
||||
initWorld();
|
||||
mRenderer = new SceneRenderer(); //创建场景渲染器
|
||||
setRenderer(mRenderer); //设置渲染器
|
||||
setRenderMode(GLSurfaceView.RENDERMODE_CONTINUOUSLY);//设置渲染模式为主动渲染
|
||||
}
|
||||
|
||||
//初始化物理世界的方法
|
||||
public void initWorld()
|
||||
{
|
||||
//创建碰撞检测配置信息对象
|
||||
CollisionConfiguration collisionConfiguration = new DefaultCollisionConfiguration();
|
||||
//创建碰撞检测算法分配者对象,其功能为扫描所有的碰撞检测对,并确定适用的检测策略对应的算法
|
||||
CollisionDispatcher dispatcher = new CollisionDispatcher(collisionConfiguration);
|
||||
//设置整个物理世界的边界信息
|
||||
Vector3f worldAabbMin = new Vector3f(-10000, -10000, -10000);
|
||||
Vector3f worldAabbMax = new Vector3f(10000, 10000, 10000);
|
||||
int maxProxies = 1024;
|
||||
//创建碰撞检测粗测阶段的加速算法对象
|
||||
AxisSweep3 overlappingPairCache =new AxisSweep3(worldAabbMin, worldAabbMax, maxProxies);
|
||||
//创建推动约束解决者对象
|
||||
SequentialImpulseConstraintSolver solver = new SequentialImpulseConstraintSolver();
|
||||
//创建物理世界对象
|
||||
dynamicsWorld = new DiscreteDynamicsWorld(dispatcher, overlappingPairCache, solver,collisionConfiguration);
|
||||
//设置重力加速度
|
||||
dynamicsWorld.setGravity(new Vector3f(0, -10, 0));
|
||||
//创建共用的立方体
|
||||
boxShape=new BoxShape(new Vector3f(Constant.UNIT_SIZE,Constant.UNIT_SIZE,Constant.UNIT_SIZE));
|
||||
//创建共用的平面形状
|
||||
planeShape=new StaticPlaneShape(new Vector3f(0, 1, 0), 0);
|
||||
}
|
||||
|
||||
private class SceneRenderer implements GLSurfaceView.Renderer
|
||||
{
|
||||
int[] cubeTextureId=new int[2];//箱子面纹理
|
||||
int floorTextureId;//地面纹理
|
||||
TexFloor floor;//纹理矩形1
|
||||
|
||||
public void onDrawFrame(GL10 gl) {
|
||||
//清除颜色缓存于深度缓存
|
||||
GLES20.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
|
||||
//绘制箱子
|
||||
synchronized(tca)
|
||||
{
|
||||
for(TexCube tc:tca)
|
||||
{
|
||||
MatrixState.pushMatrix();
|
||||
tc.drawSelf(cubeTextureId);
|
||||
MatrixState.popMatrix();
|
||||
}
|
||||
}
|
||||
|
||||
//绘制地板
|
||||
MatrixState.pushMatrix();
|
||||
floor.drawSelf( floorTextureId);
|
||||
MatrixState.popMatrix();
|
||||
}
|
||||
|
||||
public void onSurfaceChanged(GL10 gl, int width, int height) {
|
||||
//设置视窗大小及位置
|
||||
GLES20.glViewport(0, 0, width, height);
|
||||
//计算透视投影的比例
|
||||
float ratio = (float) width / height;
|
||||
//调用此方法计算产生透视投影矩阵
|
||||
MatrixState.setProjectFrustum(-ratio, ratio, -1, 1, 2, 100);
|
||||
|
||||
}
|
||||
|
||||
public void onSurfaceCreated(GL10 gl, EGLConfig config) {
|
||||
//设置屏幕背景色黑色RGBA
|
||||
GLES20.glClearColor(0,0,0,0);
|
||||
//启用深度测试
|
||||
GLES20.glEnable(GL10.GL_DEPTH_TEST);
|
||||
//设置为打开背面剪裁
|
||||
GLES20.glEnable(GL10.GL_CULL_FACE);
|
||||
//初始化变换矩阵
|
||||
MatrixState.setInitStack();
|
||||
MatrixState.setCamera(
|
||||
EYE_X, //人眼位置的X
|
||||
EYE_Y, //人眼位置的Y
|
||||
EYE_Z, //人眼位置的Z
|
||||
TARGET_X, //人眼球看的点X
|
||||
TARGET_Y, //人眼球看的点Y
|
||||
TARGET_Z, //人眼球看的点Z
|
||||
0,
|
||||
1,
|
||||
0);
|
||||
//初始化所用到的shader程序
|
||||
ShaderManager.loadCodeFromFile(activity.getResources());
|
||||
ShaderManager.compileShader();
|
||||
//初始化纹理
|
||||
cubeTextureId[0]=initTexture(R.drawable.wood_bin2);
|
||||
cubeTextureId[1]=initTexture(R.drawable.wood_bin1);
|
||||
floorTextureId=initTextureRepeat(R.drawable.f6);
|
||||
|
||||
//创建地面矩形
|
||||
floor=new TexFloor(ShaderManager.getTextureShaderProgram(),80*Constant.UNIT_SIZE,-Constant.UNIT_SIZE,planeShape,dynamicsWorld);
|
||||
|
||||
//创建立方体
|
||||
int size=2; //立方体尺寸
|
||||
float xStart=(-size/2.0f+0.5f)*(2+0.4f)*Constant.UNIT_SIZE;//x坐标起始值
|
||||
float yStart=0.02f;//y坐标起始值
|
||||
float zStart=(-size/2.0f+0.5f)*(2+0.4f)*Constant.UNIT_SIZE-4f;//z坐标起始值
|
||||
for(int i=0;i<size;i++)
|
||||
{
|
||||
for(int j=0;j<size;j++)
|
||||
{
|
||||
for(int k=0;k<size;k++)
|
||||
{
|
||||
TexCube tcTemp=new TexCube //创建纹理立方体
|
||||
(
|
||||
MySurfaceView.this, //MySurfaceView的引用
|
||||
Constant.UNIT_SIZE, //尺寸
|
||||
boxShape, //碰撞形状
|
||||
dynamicsWorld, //物理世界
|
||||
1, //刚体质量
|
||||
xStart+i*(2+0.4f)*Constant.UNIT_SIZE,//起始x坐标
|
||||
yStart+j*(2.02f)*Constant.UNIT_SIZE, //起始y坐标
|
||||
zStart+k*(2+0.4f)*Constant.UNIT_SIZE,//起始z坐标
|
||||
ShaderManager.getTextureShaderProgram()//着色器程序引用
|
||||
);
|
||||
tca.add(tcTemp);
|
||||
//使得立方体一开始是不激活的
|
||||
tcTemp.body.forceActivationState(RigidBody.WANTS_DEACTIVATION);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
new Thread()
|
||||
{
|
||||
public void run()
|
||||
{
|
||||
while(true)
|
||||
{
|
||||
try
|
||||
{
|
||||
synchronized(tcaForAdd)//锁定新箱子所在集合
|
||||
{
|
||||
synchronized(tca)//锁定当前箱子的集合
|
||||
{
|
||||
for(TexCube tc:tcaForAdd)
|
||||
{
|
||||
tca.add(tc); //向箱子集合中添加箱子
|
||||
}
|
||||
}
|
||||
tcaForAdd.clear(); //将新箱子的集合清空
|
||||
}
|
||||
//开始模拟
|
||||
dynamicsWorld.stepSimulation(TIME_STEP, MAX_SUB_STEPS);
|
||||
Thread.sleep(20); //当前线程睡眠20毫秒
|
||||
} catch (Exception e)
|
||||
{
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
}.start(); //启动线程
|
||||
}
|
||||
}
|
||||
|
||||
//触摸事件回调方法
|
||||
@Override public boolean onTouchEvent(MotionEvent e)
|
||||
{
|
||||
switch (e.getAction())
|
||||
{
|
||||
case MotionEvent.ACTION_DOWN: //处理屏幕被按下的事件
|
||||
TexCube tcTemp=new TexCube //创建一个纹理立方体
|
||||
(
|
||||
this, //MySurfaceView的引用
|
||||
Constant.UNIT_SIZE, //尺寸
|
||||
boxShape, //碰撞形状
|
||||
dynamicsWorld, //物理世界
|
||||
1, //刚体质量
|
||||
0, //起始x坐标
|
||||
2, //起始y坐标
|
||||
4, //起始z坐标
|
||||
ShaderManager.getTextureShaderProgram()//着色器程序引用
|
||||
);
|
||||
//设置箱子的初始速度
|
||||
tcTemp.body.setLinearVelocity(new Vector3f(0,2,-12));//箱子直线运动的速度--Vx,Vy,Vz三个分量
|
||||
tcTemp.body.setAngularVelocity(new Vector3f(0,0,0)); //箱子自身旋转的速度--绕箱子自身的x,y,x三轴旋转的速度
|
||||
//将新立方体加入到列表中
|
||||
synchronized(tcaForAdd)//锁定集合
|
||||
{
|
||||
tcaForAdd.add(tcTemp);//添加箱子
|
||||
}
|
||||
break;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
public int initTexture(int drawableId)//textureId
|
||||
{
|
||||
//生成纹理ID
|
||||
int[] textures = new int[1];
|
||||
GLES20.glGenTextures
|
||||
(
|
||||
1, //产生的纹理id的数量
|
||||
textures, //纹理id的数组
|
||||
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);
|
||||
|
||||
//通过输入流加载图片===============begin===================
|
||||
InputStream is = this.getResources().openRawResource(drawableId);
|
||||
Bitmap bitmapTmp;
|
||||
try
|
||||
{
|
||||
bitmapTmp = BitmapFactory.decodeStream(is);
|
||||
}
|
||||
finally
|
||||
{
|
||||
try
|
||||
{
|
||||
is.close();
|
||||
}
|
||||
catch(IOException e)
|
||||
{
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
//通过输入流加载图片===============end=====================
|
||||
|
||||
//实际加载纹理
|
||||
GLUtils.texImage2D
|
||||
(
|
||||
GLES20.GL_TEXTURE_2D, //纹理类型,在OpenGL ES中必须为GL10.GL_TEXTURE_2D
|
||||
0, //纹理的层次,0表示基本图像层,可以理解为直接贴图
|
||||
bitmapTmp, //纹理图像
|
||||
0 //纹理边框尺寸
|
||||
);
|
||||
bitmapTmp.recycle(); //纹理加载成功后释放图片
|
||||
|
||||
return textureId;
|
||||
}
|
||||
public int initTextureRepeat(int drawableId)//textureId
|
||||
{
|
||||
//生成纹理ID
|
||||
int[] textures = new int[1];
|
||||
GLES20.glGenTextures
|
||||
(
|
||||
1, //产生的纹理id的数量
|
||||
textures, //纹理id的数组
|
||||
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_REPEAT);
|
||||
GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_T,GLES20.GL_REPEAT);
|
||||
|
||||
//通过输入流加载图片===============begin===================
|
||||
InputStream is = this.getResources().openRawResource(drawableId);
|
||||
Bitmap bitmapTmp;
|
||||
try
|
||||
{
|
||||
bitmapTmp = BitmapFactory.decodeStream(is);
|
||||
}
|
||||
finally
|
||||
{
|
||||
try
|
||||
{
|
||||
is.close();
|
||||
}
|
||||
catch(IOException e)
|
||||
{
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
//通过输入流加载图片===============end=====================
|
||||
|
||||
//实际加载纹理
|
||||
GLUtils.texImage2D
|
||||
(
|
||||
GLES20.GL_TEXTURE_2D, //纹理类型,在OpenGL ES中必须为GL10.GL_TEXTURE_2D
|
||||
0, //纹理的层次,0表示基本图像层,可以理解为直接贴图
|
||||
bitmapTmp, //纹理图像
|
||||
0 //纹理边框尺寸
|
||||
);
|
||||
bitmapTmp.recycle(); //纹理加载成功后释放图片
|
||||
|
||||
return textureId;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
package com.bn.Sample17_1;
|
||||
|
||||
import javax.vecmath.Quat4f;
|
||||
public class SYSUtil
|
||||
{
|
||||
//将四元数转换为角度及转轴向量
|
||||
public static float[] fromSYStoAXYZ(Quat4f q4)
|
||||
{
|
||||
double sitaHalf=Math.acos(q4.w);
|
||||
float nx=(float) (q4.x/Math.sin(sitaHalf));
|
||||
float ny=(float) (q4.y/Math.sin(sitaHalf));
|
||||
float nz=(float) (q4.z/Math.sin(sitaHalf));
|
||||
|
||||
return new float[]{(float) Math.toDegrees(sitaHalf*2),nx,ny,nz};
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
package com.bn.Sample17_1;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.pm.ActivityInfo;
|
||||
import android.os.Bundle;
|
||||
import android.view.KeyEvent;
|
||||
import android.view.Window;
|
||||
import android.view.WindowManager;
|
||||
|
||||
public class Sample17_1_Activity extends Activity {
|
||||
private MySurfaceView mGLSurfaceView;
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
this.requestWindowFeature(Window.FEATURE_NO_TITLE);//去掉标题
|
||||
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
|
||||
WindowManager.LayoutParams.FLAG_FULLSCREEN);//去掉标头
|
||||
this.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);//强制横屏
|
||||
|
||||
mGLSurfaceView = new MySurfaceView(this);
|
||||
mGLSurfaceView.requestFocus();//获取焦点
|
||||
mGLSurfaceView.setFocusableInTouchMode(true);//设置为可触控
|
||||
|
||||
setContentView(mGLSurfaceView);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onResume() {
|
||||
super.onResume();
|
||||
mGLSurfaceView.onResume();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPause() {
|
||||
super.onPause();
|
||||
mGLSurfaceView.onPause();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onKeyDown(int keyCode, KeyEvent e)
|
||||
{
|
||||
if(keyCode==4)
|
||||
{
|
||||
System.exit(0);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
package com.bn.Sample17_1;
|
||||
|
||||
import android.content.res.Resources;
|
||||
|
||||
public class ShaderManager
|
||||
{
|
||||
final static int shaderCount=1;
|
||||
final static String[][] shaderName=
|
||||
{
|
||||
{"vertex.sh","frag.sh"}
|
||||
};
|
||||
static String[]mVertexShader=new String[shaderCount];
|
||||
static String[]mFragmentShader=new String[shaderCount];
|
||||
static int[] program=new int[shaderCount];
|
||||
|
||||
public static void loadCodeFromFile(Resources r)
|
||||
{
|
||||
for(int i=0;i<shaderCount;i++)
|
||||
{
|
||||
//加载顶点着色器的脚本内容
|
||||
mVertexShader[i]=ShaderUtil.loadFromAssetsFile(shaderName[i][0],r);
|
||||
//加载片元着色器的脚本内容
|
||||
mFragmentShader[i]=ShaderUtil.loadFromAssetsFile(shaderName[i][1], r);
|
||||
}
|
||||
}
|
||||
|
||||
//编译3D物体的shader
|
||||
public static void compileShader()
|
||||
{
|
||||
for(int i=0;i<shaderCount;i++)
|
||||
{
|
||||
program[i]=ShaderUtil.createProgram(mVertexShader[i], mFragmentShader[i]);
|
||||
System.out.println("mProgram "+program[i]);
|
||||
}
|
||||
}
|
||||
//这里返回的是纹理的shader程序
|
||||
public static int getTextureShaderProgram()
|
||||
{
|
||||
return program[0];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,120 @@
|
||||
package com.bn.Sample17_1;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.InputStream;
|
||||
import android.content.res.Resources;
|
||||
import android.opengl.GLES20;
|
||||
import android.util.Log;
|
||||
|
||||
//加载顶点Shader与片元Shader的工具类
|
||||
public class ShaderUtil
|
||||
{
|
||||
//加载制定shader的方法
|
||||
public static int loadShader
|
||||
(
|
||||
int shaderType, //shader的类型 GLES20.GL_VERTEX_SHADER GLES20.GL_FRAGMENT_SHADER
|
||||
String source //shader的脚本字符串
|
||||
)
|
||||
{
|
||||
//创建一个新shader
|
||||
int shader = GLES20.glCreateShader(shaderType);
|
||||
//若创建成功则加载shader
|
||||
if (shader != 0)
|
||||
{
|
||||
//加载shader的源代码
|
||||
GLES20.glShaderSource(shader, source);
|
||||
//编译shader
|
||||
GLES20.glCompileShader(shader);
|
||||
//存放编译成功shader数量的数组
|
||||
int[] compiled = new int[1];
|
||||
//获取Shader的编译情况
|
||||
GLES20.glGetShaderiv(shader, GLES20.GL_COMPILE_STATUS, compiled, 0);
|
||||
if (compiled[0] == 0)
|
||||
{//若编译失败则显示错误日志并删除此shader
|
||||
Log.e("ES20_ERROR", "Could not compile shader " + shaderType + ":");
|
||||
Log.e("ES20_ERROR", GLES20.glGetShaderInfoLog(shader));
|
||||
GLES20.glDeleteShader(shader);
|
||||
shader = 0;
|
||||
}
|
||||
}
|
||||
return shader;
|
||||
}
|
||||
//创建shader程序的方法
|
||||
public static int createProgram(String vertexSource, String fragmentSource)
|
||||
{
|
||||
//加载顶点着色器
|
||||
int vertexShader = loadShader(GLES20.GL_VERTEX_SHADER, vertexSource);
|
||||
if (vertexShader == 0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
//加载片元着色器
|
||||
int pixelShader = loadShader(GLES20.GL_FRAGMENT_SHADER, fragmentSource);
|
||||
if (pixelShader == 0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
//创建程序
|
||||
int program = GLES20.glCreateProgram();
|
||||
//若程序创建成功则向程序中加入顶点着色器与片元着色器
|
||||
if (program != 0)
|
||||
{
|
||||
//向程序中加入顶点着色器
|
||||
GLES20.glAttachShader(program, vertexShader);
|
||||
checkGlError("glAttachShader");
|
||||
//向程序中加入片元着色器
|
||||
GLES20.glAttachShader(program, pixelShader);
|
||||
checkGlError("glAttachShader");
|
||||
//链接程序
|
||||
GLES20.glLinkProgram(program);
|
||||
//存放链接成功program数量的数组
|
||||
int[] linkStatus = new int[1];
|
||||
//获取program的链接情况
|
||||
GLES20.glGetProgramiv(program, GLES20.GL_LINK_STATUS, linkStatus, 0);
|
||||
//若链接失败则报错并删除程序
|
||||
if (linkStatus[0] != GLES20.GL_TRUE)
|
||||
{
|
||||
Log.e("ES20_ERROR", "Could not link program: ");
|
||||
Log.e("ES20_ERROR", GLES20.glGetProgramInfoLog(program));
|
||||
GLES20.glDeleteProgram(program);
|
||||
program = 0;
|
||||
}
|
||||
}
|
||||
return program;
|
||||
}
|
||||
//检查每一步操作是否有错误的方法
|
||||
public static void checkGlError(String op)
|
||||
{
|
||||
int error;
|
||||
while ((error = GLES20.glGetError()) != GLES20.GL_NO_ERROR)
|
||||
{
|
||||
Log.e("ES20_ERROR", op + ": glError " + error);
|
||||
throw new RuntimeException(op + ": glError " + error);
|
||||
}
|
||||
}
|
||||
//从sh脚本中加载shader内容的方法
|
||||
public static String loadFromAssetsFile(String fname,Resources r)
|
||||
{
|
||||
String result=null;
|
||||
try
|
||||
{
|
||||
InputStream in=r.getAssets().open(fname);
|
||||
int ch=0;
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
while((ch=in.read())!=-1)
|
||||
{
|
||||
baos.write(ch);
|
||||
}
|
||||
byte[] buff=baos.toByteArray();
|
||||
baos.close();
|
||||
in.close();
|
||||
result=new String(buff,"UTF-8");
|
||||
result=result.replaceAll("\\r\\n","\n");
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
e.printStackTrace();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,90 @@
|
||||
package com.bn.Sample17_1;
|
||||
import javax.vecmath.Quat4f;
|
||||
import javax.vecmath.Vector3f;
|
||||
import com.bulletphysics.collision.shapes.CollisionShape;
|
||||
import com.bulletphysics.dynamics.DiscreteDynamicsWorld;
|
||||
import com.bulletphysics.dynamics.RigidBody;
|
||||
import com.bulletphysics.dynamics.RigidBodyConstructionInfo;
|
||||
import com.bulletphysics.linearmath.DefaultMotionState;
|
||||
import com.bulletphysics.linearmath.Transform;
|
||||
public class TexCube
|
||||
{
|
||||
TextureRect tr;//用于绘制各个面的纹理矩形
|
||||
float halfSize;//立方体的半边长
|
||||
RigidBody body;//对应的刚体对象
|
||||
int mProgram;
|
||||
MySurfaceView mv;
|
||||
public TexCube(MySurfaceView mv,float halfSize,CollisionShape colShape,
|
||||
DiscreteDynamicsWorld dynamicsWorld,float mass,float cx,float cy,float cz,int mProgram)
|
||||
{
|
||||
boolean isDynamic = (mass != 0f);//物体是否可以运动
|
||||
Vector3f localInertia = new Vector3f(0, 0, 0);//惯性向量
|
||||
if(isDynamic) //如果物体可以运动
|
||||
{
|
||||
colShape.calculateLocalInertia(mass, localInertia);//计算惯性
|
||||
}
|
||||
Transform startTransform = new Transform();//创建刚体的初始变换对象
|
||||
startTransform.setIdentity();//变换初始化
|
||||
startTransform.origin.set(new Vector3f(cx, cy, cz));//设置初始的位置
|
||||
//创建刚体的运动状态对象
|
||||
DefaultMotionState myMotionState = new DefaultMotionState(startTransform);
|
||||
//创建刚体信息对象
|
||||
RigidBodyConstructionInfo rbInfo = new RigidBodyConstructionInfo
|
||||
(mass, myMotionState, colShape, localInertia);
|
||||
body = new RigidBody(rbInfo);//创建刚体
|
||||
body.setRestitution(0.6f);//设置反弹系数
|
||||
body.setFriction(0.8f);//设置摩擦系数
|
||||
dynamicsWorld.addRigidBody(body);//将刚体添加进物理世界
|
||||
this.mv=mv; //保存MySurfaceView引用
|
||||
tr=new TextureRect(halfSize);//创建纹理矩形
|
||||
this.mProgram=mProgram;//保存着色器程序引用
|
||||
this.halfSize=halfSize; //保存半长
|
||||
}
|
||||
public void drawSelf(int[] texIda)
|
||||
{
|
||||
tr.initShader(mv, mProgram);//纹理矩形初始化着色器
|
||||
int texId=texIda[0];//物体运动时的纹理id
|
||||
if(!body.isActive()){texId=texIda[1];}//物体静止时的纹理id
|
||||
MatrixState.pushMatrix();//保护现场
|
||||
//获取这个箱子的变换信息对象
|
||||
Transform trans = body.getMotionState().getWorldTransform(new Transform());
|
||||
//进行移位变换
|
||||
MatrixState.translate(trans.origin.x,trans.origin.y, trans.origin.z);
|
||||
Quat4f ro=trans.getRotation(new Quat4f());//获取当前变换的旋转信息
|
||||
if(ro.x!=0||ro.y!=0||ro.z!=0)
|
||||
{
|
||||
float[] fa=SYSUtil.fromSYStoAXYZ(ro);//将四元数转换成AXYZ的形式
|
||||
MatrixState.rotate(fa[0], fa[1], fa[2], fa[3]);//执行旋转
|
||||
}
|
||||
MatrixState.pushMatrix();//保护现场
|
||||
MatrixState.translate(0, halfSize, 0);//执行平移
|
||||
MatrixState.rotate(-90, 1, 0, 0);//执行旋转
|
||||
tr.drawSelf( texId);//绘制上面
|
||||
MatrixState.popMatrix();//恢复现场
|
||||
MatrixState.pushMatrix();//保护现场
|
||||
MatrixState.translate(0, -halfSize, 0);//执行平移
|
||||
MatrixState.rotate(90, 1, 0, 0);//执行旋转
|
||||
tr.drawSelf( texId);//绘制下面
|
||||
MatrixState.popMatrix();//恢复现场
|
||||
MatrixState.pushMatrix();//保护现场
|
||||
MatrixState.translate(-halfSize, 0, 0);//执行平移
|
||||
MatrixState.rotate(-90, 0, 1, 0);//执行旋转
|
||||
tr.drawSelf( texId);//绘制左面
|
||||
MatrixState.popMatrix();//恢复现场
|
||||
MatrixState.pushMatrix();//保护现场
|
||||
MatrixState.translate(halfSize, 0, 0);//执行平移
|
||||
MatrixState.rotate(90, 0, 1, 0);//执行旋转
|
||||
tr.drawSelf( texId);//绘制右面
|
||||
MatrixState.popMatrix();//恢复现场
|
||||
MatrixState.pushMatrix();//保护现场
|
||||
MatrixState.translate(0, 0, halfSize);//执行平移
|
||||
tr.drawSelf(texId);//绘制前面
|
||||
MatrixState.popMatrix();//恢复现场
|
||||
MatrixState.pushMatrix();//保护现场
|
||||
MatrixState.translate(0, 0, -halfSize);//执行平移
|
||||
MatrixState.rotate(180, 0, 1, 0);//执行旋转
|
||||
tr.drawSelf( texId);//绘制后面
|
||||
MatrixState.popMatrix();//恢复现场
|
||||
MatrixState.popMatrix();//恢复现场
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,157 @@
|
||||
package com.bn.Sample17_1;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.ByteOrder;
|
||||
import java.nio.FloatBuffer;
|
||||
import android.opengl.GLES20;
|
||||
import com.bulletphysics.collision.shapes.*;
|
||||
import com.bulletphysics.dynamics.DiscreteDynamicsWorld;
|
||||
import com.bulletphysics.dynamics.RigidBody;
|
||||
import com.bulletphysics.dynamics.RigidBodyConstructionInfo;
|
||||
import com.bulletphysics.linearmath.DefaultMotionState;
|
||||
import com.bulletphysics.linearmath.Transform;
|
||||
import javax.vecmath.Vector3f;
|
||||
|
||||
public class TexFloor {
|
||||
|
||||
int mProgram;//自定义渲染管线程序id
|
||||
int muMVPMatrixHandle;//总变换矩阵引用id
|
||||
int muMMatrixHandle;//位置、旋转变换矩阵
|
||||
int maTexCoorHandle; //顶点纹理坐标属性引用id
|
||||
int uTexHandle;//外观纹理属性引用id
|
||||
int maCameraHandle; //摄像机位置属性引用id
|
||||
int maPositionHandle; //顶点位置属性引用id
|
||||
|
||||
String mVertexShader;//顶点着色器
|
||||
String mFragmentShader;//片元着色器
|
||||
|
||||
private FloatBuffer mVertexBuffer;//顶点坐标数据缓冲
|
||||
private FloatBuffer mTextureBuffer;//顶点着色数据缓冲
|
||||
|
||||
int vCount;
|
||||
float yOffset;
|
||||
|
||||
public TexFloor(int mProgram,final float UNIT_SIZE, float yOffset,CollisionShape groundShape,DiscreteDynamicsWorld dynamicsWorld)
|
||||
{
|
||||
this.mProgram=mProgram;
|
||||
this.yOffset=yOffset;
|
||||
//创建刚体的初始变换对象
|
||||
Transform groundTransform = new Transform();
|
||||
groundTransform.setIdentity();
|
||||
groundTransform.origin.set(new Vector3f(0.f, yOffset, 0.f));
|
||||
Vector3f localInertia = new Vector3f(0, 0, 0);//惯性
|
||||
//创建刚体的运动状态对象
|
||||
DefaultMotionState myMotionState = new DefaultMotionState(groundTransform);
|
||||
//创建刚体信息对象
|
||||
RigidBodyConstructionInfo rbInfo = new RigidBodyConstructionInfo(0, myMotionState, groundShape, localInertia);
|
||||
//创建刚体
|
||||
RigidBody body = new RigidBody(rbInfo);
|
||||
//设置反弹系数
|
||||
body.setRestitution(0.4f);
|
||||
//设置摩擦系数
|
||||
body.setFriction(0.8f);
|
||||
//将刚体添加进物理世界
|
||||
dynamicsWorld.addRigidBody(body);
|
||||
initVertexData(UNIT_SIZE);
|
||||
initShader(mProgram);
|
||||
}
|
||||
|
||||
public void initVertexData(final float UNIT_SIZE){
|
||||
//顶点坐标数据的初始化================begin============================
|
||||
vCount=6;
|
||||
float vertices[]=new float[]
|
||||
{
|
||||
1*UNIT_SIZE,yOffset,1*UNIT_SIZE,
|
||||
-1*UNIT_SIZE,yOffset,-1*UNIT_SIZE,
|
||||
-1*UNIT_SIZE,yOffset,1*UNIT_SIZE,
|
||||
|
||||
1*UNIT_SIZE,yOffset,1*UNIT_SIZE,
|
||||
1*UNIT_SIZE,yOffset,-1*UNIT_SIZE,
|
||||
-1*UNIT_SIZE,yOffset,-1*UNIT_SIZE,
|
||||
};
|
||||
|
||||
//创建顶点坐标数据缓冲
|
||||
//vertices.length*4是因为一个整数四个字节
|
||||
ByteBuffer vbb = ByteBuffer.allocateDirect(vertices.length*4);
|
||||
vbb.order(ByteOrder.nativeOrder());//设置字节顺序
|
||||
mVertexBuffer = vbb.asFloatBuffer();//转换为int型缓冲
|
||||
mVertexBuffer.put(vertices);//向缓冲区中放入顶点坐标数据
|
||||
mVertexBuffer.position(0);//设置缓冲区起始位置
|
||||
//特别提示:由于不同平台字节顺序不同数据单元不是字节的一定要经过ByteBuffer
|
||||
//转换,关键是要通过ByteOrder设置nativeOrder(),否则有可能会出问题
|
||||
//顶点坐标数据的初始化================end============================
|
||||
//顶点纹理数据的初始化================begin============================
|
||||
float textures[]=new float[]
|
||||
{
|
||||
UNIT_SIZE/2,UNIT_SIZE/2, 0,0, 0,UNIT_SIZE/2,
|
||||
UNIT_SIZE/2,UNIT_SIZE/2, UNIT_SIZE/2,0, 0,0
|
||||
};
|
||||
|
||||
//创建顶点纹理数据缓冲
|
||||
ByteBuffer tbb = ByteBuffer.allocateDirect(textures.length*4);
|
||||
tbb.order(ByteOrder.nativeOrder());//设置字节顺序
|
||||
mTextureBuffer= tbb.asFloatBuffer();//转换为Float型缓冲
|
||||
mTextureBuffer.put(textures);//向缓冲区中放入顶点着色数据
|
||||
mTextureBuffer.position(0);//设置缓冲区起始位置
|
||||
//特别提示:由于不同平台字节顺序不同数据单元不是字节的一定要经过ByteBuffer
|
||||
//转换,关键是要通过ByteOrder设置nativeOrder(),否则有可能会出问题
|
||||
//顶点纹理数据的初始化================end============================
|
||||
}
|
||||
//初始化shader
|
||||
public void initShader(int mProgram)
|
||||
{
|
||||
//获取程序中顶点位置属性引用id
|
||||
maPositionHandle = GLES20.glGetAttribLocation(mProgram, "aPosition");
|
||||
//获取程序中顶点经纬度属性引用id
|
||||
maTexCoorHandle=GLES20.glGetAttribLocation(mProgram, "aTexCoor");
|
||||
//获取程序中总变换矩阵引用id
|
||||
muMVPMatrixHandle = GLES20.glGetUniformLocation(mProgram, "uMVPMatrix");
|
||||
//获取位置、旋转变换矩阵引用id
|
||||
muMMatrixHandle = GLES20.glGetUniformLocation(mProgram, "uMMatrix");
|
||||
//获取程序中摄像机位置引用id
|
||||
maCameraHandle=GLES20.glGetUniformLocation(mProgram, "uCamera");
|
||||
uTexHandle=GLES20.glGetUniformLocation(mProgram, "sTexture");
|
||||
}
|
||||
|
||||
public void drawSelf(int texId)
|
||||
{
|
||||
//制定使用某套shader程序
|
||||
GLES20.glUseProgram(mProgram);
|
||||
//将最终变换矩阵传入shader程序
|
||||
GLES20.glUniformMatrix4fv(muMVPMatrixHandle, 1, false, MatrixState.getFinalMatrix(), 0);
|
||||
//将位置、旋转变换矩阵传入shader程序
|
||||
GLES20.glUniformMatrix4fv(muMMatrixHandle, 1, false, MatrixState.getMMatrix(), 0);
|
||||
//将摄像机位置传入shader程序
|
||||
GLES20.glUniform3fv(maCameraHandle, 1, MatrixState.cameraFB);
|
||||
|
||||
//为画笔指定顶点位置数据
|
||||
GLES20.glVertexAttribPointer
|
||||
(
|
||||
maPositionHandle,
|
||||
3,
|
||||
GLES20.GL_FLOAT,
|
||||
false,
|
||||
3*4,
|
||||
mVertexBuffer
|
||||
);
|
||||
//为画笔指定顶点纹理坐标数据
|
||||
GLES20.glVertexAttribPointer
|
||||
(
|
||||
maTexCoorHandle,
|
||||
2,
|
||||
GLES20.GL_FLOAT,
|
||||
false,
|
||||
2*4,
|
||||
mTextureBuffer
|
||||
);
|
||||
//允许顶点位置数据数组
|
||||
GLES20.glEnableVertexAttribArray(maPositionHandle);
|
||||
GLES20.glEnableVertexAttribArray(maTexCoorHandle);
|
||||
//绑定纹理
|
||||
GLES20.glActiveTexture(GLES20.GL_TEXTURE0);
|
||||
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, texId);
|
||||
GLES20.glUniform1i(uTexHandle, 0);
|
||||
|
||||
//绘制三角形
|
||||
GLES20.glDrawArrays(GLES20.GL_TRIANGLES, 0, vCount);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,131 @@
|
||||
package com.bn.Sample17_1;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.ByteOrder;
|
||||
import java.nio.FloatBuffer;
|
||||
import android.opengl.GLES20;
|
||||
|
||||
public class TextureRect {
|
||||
|
||||
int mProgram;//自定义渲染管线程序id
|
||||
int muMVPMatrixHandle;//总变换矩阵引用id
|
||||
int muMMatrixHandle;//位置、旋转变换矩阵
|
||||
int uTexHandle;//外观纹理属性引用id
|
||||
|
||||
int maCameraHandle; //摄像机位置属性引用id
|
||||
int maPositionHandle; //顶点位置属性引用id
|
||||
int maTexCoorHandle; //顶点纹理坐标属性引用id
|
||||
|
||||
String mVertexShader;//顶点着色器
|
||||
String mFragmentShader;//片元着色器
|
||||
|
||||
private FloatBuffer mVertexBuffer;//顶点坐标数据缓冲
|
||||
private FloatBuffer mTextureBuffer;//顶点着色数据缓冲
|
||||
int vCount;
|
||||
|
||||
public TextureRect(final float UNIT_SIZE)
|
||||
{
|
||||
//初始化顶点坐标与着色数据
|
||||
initVertexData(UNIT_SIZE);
|
||||
}
|
||||
|
||||
public void initVertexData(final float UNIT_SIZE){
|
||||
//顶点坐标数据的初始化================begin============================
|
||||
vCount=6;
|
||||
float vertices[]=new float[]
|
||||
{
|
||||
-1*UNIT_SIZE,1*UNIT_SIZE,0,
|
||||
-1*UNIT_SIZE,-1*UNIT_SIZE,0,
|
||||
1*UNIT_SIZE,1*UNIT_SIZE,0,
|
||||
|
||||
-1*UNIT_SIZE,-1*UNIT_SIZE,0,
|
||||
1*UNIT_SIZE,-1*UNIT_SIZE,0,
|
||||
1*UNIT_SIZE,1*UNIT_SIZE,0
|
||||
};
|
||||
|
||||
//创建顶点坐标数据缓冲
|
||||
//vertices.length*4是因为一个整数四个字节
|
||||
ByteBuffer vbb = ByteBuffer.allocateDirect(vertices.length*4);
|
||||
vbb.order(ByteOrder.nativeOrder());//设置字节顺序
|
||||
mVertexBuffer = vbb.asFloatBuffer();//转换为int型缓冲
|
||||
mVertexBuffer.put(vertices);//向缓冲区中放入顶点坐标数据
|
||||
mVertexBuffer.position(0);//设置缓冲区起始位置
|
||||
//特别提示:由于不同平台字节顺序不同数据单元不是字节的一定要经过ByteBuffer
|
||||
//转换,关键是要通过ByteOrder设置nativeOrder(),否则有可能会出问题
|
||||
//顶点坐标数据的初始化================end============================
|
||||
//顶点纹理数据的初始化================begin============================
|
||||
float textures[]=new float[]
|
||||
{
|
||||
0,1, 0,0, 1,1,
|
||||
0,0, 1,0, 1,1
|
||||
};
|
||||
//创建顶点纹理数据缓冲
|
||||
ByteBuffer tbb = ByteBuffer.allocateDirect(textures.length*4);
|
||||
tbb.order(ByteOrder.nativeOrder());//设置字节顺序
|
||||
mTextureBuffer= tbb.asFloatBuffer();//转换为Float型缓冲
|
||||
mTextureBuffer.put(textures);//向缓冲区中放入顶点着色数据
|
||||
mTextureBuffer.position(0);//设置缓冲区起始位置
|
||||
//特别提示:由于不同平台字节顺序不同数据单元不是字节的一定要经过ByteBuffer
|
||||
//转换,关键是要通过ByteOrder设置nativeOrder(),否则有可能会出问题
|
||||
//顶点纹理数据的初始化================end============================
|
||||
}
|
||||
|
||||
//初始化shader
|
||||
public void initShader(MySurfaceView mv,int mProgram)
|
||||
{
|
||||
this.mProgram=mProgram;
|
||||
//获取程序中顶点位置属性引用id
|
||||
maPositionHandle = GLES20.glGetAttribLocation(mProgram, "aPosition");
|
||||
//获取程序中顶点经纬度属性引用id
|
||||
maTexCoorHandle=GLES20.glGetAttribLocation(mProgram, "aTexCoor");
|
||||
//获取程序中总变换矩阵引用id
|
||||
muMVPMatrixHandle = GLES20.glGetUniformLocation(mProgram, "uMVPMatrix");
|
||||
//获取位置、旋转变换矩阵引用id
|
||||
muMMatrixHandle = GLES20.glGetUniformLocation(mProgram, "uMMatrix");
|
||||
//获取程序中摄像机位置引用id
|
||||
maCameraHandle=GLES20.glGetUniformLocation(mProgram, "uCamera");
|
||||
uTexHandle=GLES20.glGetUniformLocation(mProgram, "sTexture");
|
||||
}
|
||||
|
||||
public void drawSelf(int texId)
|
||||
{
|
||||
//制定使用某套shader程序
|
||||
GLES20.glUseProgram(mProgram);
|
||||
//将最终变换矩阵传入shader程序
|
||||
GLES20.glUniformMatrix4fv(muMVPMatrixHandle, 1, false, MatrixState.getFinalMatrix(), 0);
|
||||
//将位置、旋转变换矩阵传入shader程序
|
||||
GLES20.glUniformMatrix4fv(muMMatrixHandle, 1, false, MatrixState.getMMatrix(), 0);
|
||||
//将摄像机位置传入shader程序
|
||||
GLES20.glUniform3fv(maCameraHandle, 1, MatrixState.cameraFB);
|
||||
|
||||
//为画笔指定顶点位置数据
|
||||
GLES20.glVertexAttribPointer
|
||||
(
|
||||
maPositionHandle,
|
||||
3,
|
||||
GLES20.GL_FLOAT,
|
||||
false,
|
||||
3*4,
|
||||
mVertexBuffer
|
||||
);
|
||||
//为画笔指定顶点纹理坐标数据
|
||||
GLES20.glVertexAttribPointer
|
||||
(
|
||||
maTexCoorHandle,
|
||||
2,
|
||||
GLES20.GL_FLOAT,
|
||||
false,
|
||||
2*4,
|
||||
mTextureBuffer
|
||||
);
|
||||
//允许顶点位置数据数组
|
||||
GLES20.glEnableVertexAttribArray(maPositionHandle);
|
||||
GLES20.glEnableVertexAttribArray(maTexCoorHandle);
|
||||
//绑定纹理
|
||||
GLES20.glActiveTexture(GLES20.GL_TEXTURE0);
|
||||
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, texId);
|
||||
GLES20.glUniform1i(uTexHandle, 0);
|
||||
|
||||
//绘制三角形
|
||||
GLES20.glDrawArrays(GLES20.GL_TRIANGLES, 0, vCount);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user