初次提交
This commit is contained in:
@@ -0,0 +1,7 @@
|
||||
<?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="output" path="bin"/>
|
||||
</classpath>
|
||||
@@ -0,0 +1,33 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<projectDescription>
|
||||
<name>Sample13_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,12 @@
|
||||
#Wed Jan 05 21:56:15 CST 2011
|
||||
eclipse.preferences.version=1
|
||||
org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
|
||||
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6
|
||||
org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
|
||||
org.eclipse.jdt.core.compiler.compliance=1.6
|
||||
org.eclipse.jdt.core.compiler.debug.lineNumber=generate
|
||||
org.eclipse.jdt.core.compiler.debug.localVariable=generate
|
||||
org.eclipse.jdt.core.compiler.debug.sourceFile=generate
|
||||
org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
|
||||
org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
|
||||
org.eclipse.jdt.core.compiler.source=1.6
|
||||
@@ -0,0 +1,15 @@
|
||||
<?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.Sample13_1">
|
||||
<application android:icon="@drawable/icon" android:label="@string/app_name">
|
||||
<activity android:name=".Sample13_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>
|
||||
<uses-sdk android:targetSdkVersion="8"/>
|
||||
</manifest>
|
||||
@@ -0,0 +1,8 @@
|
||||
precision mediump float;
|
||||
varying vec2 vTextureCoord; //接收从顶点着色器过来的参数
|
||||
uniform sampler2D sTexture;//纹理内容数据
|
||||
void main()
|
||||
{
|
||||
//给此片元从纹理中采样出颜色值
|
||||
gl_FragColor =texture2D(sTexture, vTextureCoord);
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
uniform mat4 uMVPMatrix; //总变换矩阵
|
||||
uniform float uStartAngle;//本帧起始角度
|
||||
uniform float uWidthSpan;//横向长度总跨度
|
||||
attribute vec3 aPosition; //顶点位置
|
||||
attribute vec2 aTexCoor; //顶点纹理坐标
|
||||
varying vec2 vTextureCoord; //用于传递给片元着色器的变量
|
||||
void main()
|
||||
{
|
||||
//计算X向波浪
|
||||
float angleSpanH=4.0*3.14159265;//横向角度总跨度
|
||||
float startX=-uWidthSpan/2.0;//起始X坐标
|
||||
//根据横向角度总跨度、横向长度总跨度及当前点X坐标折算出当前点X坐标对应的角度
|
||||
float currAngle=uStartAngle+((aPosition.x-startX)/uWidthSpan)*angleSpanH;
|
||||
float tz=sin(currAngle)*0.1;
|
||||
|
||||
//根据总变换矩阵计算此次绘制此顶点位置
|
||||
gl_Position = uMVPMatrix * vec4(aPosition.x,aPosition.y,tz,1);
|
||||
vTextureCoord = aTexCoor;//将接收的纹理坐标传递给片元着色器
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
uniform mat4 uMVPMatrix; //总变换矩阵
|
||||
uniform float uStartAngle;//本帧起始角度
|
||||
uniform float uWidthSpan;//横向长度总跨度
|
||||
attribute vec3 aPosition; //顶点位置
|
||||
attribute vec2 aTexCoor; //顶点纹理坐标
|
||||
varying vec2 vTextureCoord; //用于传递给片元着色器的变量
|
||||
void main()
|
||||
{
|
||||
//计算X向角度
|
||||
float angleSpanH=4.0*3.14159265;//横向角度总跨度
|
||||
float startX=-uWidthSpan/2.0;//起始X坐标
|
||||
//根据横向角度总跨度、横向长度总跨度及当前点X坐标折算出当前点X坐标对应的角度
|
||||
float currAngleH=uStartAngle+((aPosition.x-startX)/uWidthSpan)*angleSpanH;
|
||||
|
||||
//计算出随Y向发展起始角度的扰动值
|
||||
float angleSpanZ=4.0*3.14159265;//纵向角度总跨度
|
||||
float uHeightSpan=0.75*uWidthSpan;//纵向长度总跨度
|
||||
float startY=-uHeightSpan/2.0;//起始Y坐标
|
||||
//根据纵向角度总跨度、纵向长度总跨度及当前点Y坐标折算出当前点Y坐标对应的角度
|
||||
float currAngleZ=((aPosition.y-startY)/uHeightSpan)*angleSpanZ;
|
||||
|
||||
//计算斜向波浪
|
||||
float tzH=sin(currAngleH-currAngleZ)*0.1;
|
||||
//根据总变换矩阵计算此次绘制此顶点位置
|
||||
gl_Position = uMVPMatrix * vec4(aPosition.x,aPosition.y,tzH,1);
|
||||
vTextureCoord = aTexCoor;//将接收的纹理坐标传递给片元着色器
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
uniform mat4 uMVPMatrix; //总变换矩阵
|
||||
uniform float uStartAngle;//本帧起始角度
|
||||
uniform float uWidthSpan;//横向长度总跨度
|
||||
attribute vec3 aPosition; //顶点位置
|
||||
attribute vec2 aTexCoor; //顶点纹理坐标
|
||||
varying vec2 vTextureCoord; //用于传递给片元着色器的变量
|
||||
void main()
|
||||
{
|
||||
//计算X向波浪
|
||||
float angleSpanH=4.0*3.14159265;//横向角度总跨度
|
||||
float startX=-uWidthSpan/2.0;//起始X坐标
|
||||
//根据横向角度总跨度、横向长度总跨度及当前点X坐标折算出当前点X坐标对应的角度
|
||||
float currAngleH=uStartAngle+((aPosition.x-startX)/uWidthSpan)*angleSpanH;
|
||||
float tzH=sin(currAngleH)*0.1;
|
||||
|
||||
//计算Y向波浪
|
||||
float angleSpanZ=4.0*3.14159265;//纵向角度总跨度
|
||||
float uHeightSpan=0.75*uWidthSpan;//纵向长度总跨度
|
||||
float startY=-uHeightSpan/2.0;//起始Y坐标
|
||||
//根据纵向角度总跨度、纵向长度总跨度及当前点Y坐标折算出当前点Y坐标对应的角度
|
||||
float currAngleZ=uStartAngle+3.14159265/3.0+((aPosition.y-startY)/uHeightSpan)*angleSpanZ;
|
||||
float tzZ=sin(currAngleZ)*0.1;
|
||||
|
||||
//根据总变换矩阵计算此次绘制此顶点位置
|
||||
gl_Position = uMVPMatrix * vec4(aPosition.x,aPosition.y,tzH+tzZ,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.
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,30 @@
|
||||
/* 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.Sample13_1;
|
||||
|
||||
public final class R {
|
||||
public static final class attr {
|
||||
}
|
||||
public static final class drawable {
|
||||
public static final int android_flag=0x7f020000;
|
||||
public static final int icon=0x7f020001;
|
||||
}
|
||||
public static final class id {
|
||||
public static final int RadioGroup01=0x7f050001;
|
||||
public static final int main_liner=0x7f050000;
|
||||
public static final int x1=0x7f050002;
|
||||
public static final int x2=0x7f050003;
|
||||
public static final int x3=0x7f050004;
|
||||
}
|
||||
public static final class layout {
|
||||
public static final int main=0x7f030000;
|
||||
}
|
||||
public static final class string {
|
||||
public static final int app_name=0x7f040000;
|
||||
}
|
||||
}
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 99 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 4.0 KiB |
@@ -0,0 +1,33 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:orientation="horizontal"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="fill_parent"
|
||||
android:id="@+id/main_liner"
|
||||
>
|
||||
<RadioGroup
|
||||
android:id="@+id/RadioGroup01"
|
||||
android:orientation="vertical"
|
||||
android:layout_width="100dip"
|
||||
android:layout_height="fill_parent">
|
||||
<RadioButton
|
||||
android:text="X方向"
|
||||
android:id="@+id/x1"
|
||||
android:checked="true"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content">
|
||||
</RadioButton>
|
||||
<RadioButton
|
||||
android:text="斜向下"
|
||||
android:id="@+id/x2"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content">
|
||||
</RadioButton>
|
||||
<RadioButton
|
||||
android:text="XY双向"
|
||||
android:id="@+id/x3"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content">
|
||||
</RadioButton>
|
||||
</RadioGroup>
|
||||
</LinearLayout>
|
||||
@@ -0,0 +1,4 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<string name="app_name">Sample13_1</string>
|
||||
</resources>
|
||||
@@ -0,0 +1,6 @@
|
||||
package com.bn.Sample13_1;
|
||||
//³£Á¿Àà
|
||||
public class Constant
|
||||
{
|
||||
public static boolean threadFlag=true;//ÆìÖÄ»»Ö¡Ï̹߳¤×÷±ê־λ
|
||||
}
|
||||
@@ -0,0 +1,118 @@
|
||||
package com.bn.Sample13_1;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.ByteOrder;
|
||||
import java.nio.FloatBuffer;
|
||||
import java.util.*;
|
||||
import android.opengl.Matrix;
|
||||
|
||||
//存储系统矩阵状态的类
|
||||
public class MatrixState
|
||||
{
|
||||
private static float[] mProjMatrix = new float[16];//4x4矩阵 投影用
|
||||
private static float[] mVMatrix = new float[16];//摄像机位置朝向9参数矩阵
|
||||
private static float[] currMatrix;//当前变换矩阵
|
||||
public static float[] lightLocationSun=new float[]{0,0,0};//太阳定位光光源位置
|
||||
public static FloatBuffer cameraFB;
|
||||
public static Stack<float[]> mStack=new Stack<float[]>();//保护变换矩阵的栈
|
||||
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 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 float[] getMMatrix()
|
||||
{
|
||||
return currMatrix;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,147 @@
|
||||
package com.bn.Sample13_1;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import android.opengl.GLSurfaceView;
|
||||
import android.opengl.GLUtils;
|
||||
import android.opengl.GLES20;
|
||||
import android.view.MotionEvent;
|
||||
|
||||
import javax.microedition.khronos.egl.EGLConfig;
|
||||
import javax.microedition.khronos.opengles.GL10;
|
||||
|
||||
import com.bn.Sample13_1.R;
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.BitmapFactory;
|
||||
|
||||
class MySurfaceView extends GLSurfaceView
|
||||
{
|
||||
SceneRenderer mRenderer;//场景渲染器
|
||||
int textureFlagId;//系统分配的国旗纹理id
|
||||
private final float TOUCH_SCALE_FACTOR = 180.0f/320;//角度缩放比例
|
||||
float xAngle;//整体场景绕X轴旋转的角度
|
||||
float yAngle;//整体场景绕Y轴旋转的角度
|
||||
private float mPreviousX;//上次的触控位置X坐标
|
||||
private float mPreviousY;//上次的触控位置X坐标
|
||||
|
||||
//触摸事件回调方法
|
||||
@Override
|
||||
public boolean onTouchEvent(MotionEvent e)
|
||||
{
|
||||
float x = e.getX();
|
||||
float y = e.getY();
|
||||
switch (e.getAction()) {
|
||||
case MotionEvent.ACTION_MOVE:
|
||||
float dx = x - mPreviousX;//计算触控笔X位移
|
||||
float dy = y - mPreviousY;//计算触控笔Y位移
|
||||
yAngle += dx * TOUCH_SCALE_FACTOR;//设置整体场景绕Y轴旋转角度
|
||||
xAngle += dy * TOUCH_SCALE_FACTOR;//设置绕整体场景X轴旋转角度
|
||||
requestRender();//重绘画面
|
||||
}
|
||||
mPreviousX = x;//记录触控笔位置
|
||||
mPreviousY = y;//记录触控笔位置
|
||||
return true;
|
||||
}
|
||||
|
||||
public MySurfaceView(Context context) {
|
||||
super(context);
|
||||
this.setEGLContextClientVersion(2); //设置使用OPENGL ES2.0
|
||||
mRenderer = new SceneRenderer(); //创建场景渲染器
|
||||
setRenderer(mRenderer); //设置渲染器
|
||||
setRenderMode(GLSurfaceView.RENDERMODE_CONTINUOUSLY);//设置渲染模式为主动渲染
|
||||
setKeepScreenOn(true);
|
||||
}
|
||||
|
||||
class SceneRenderer implements GLSurfaceView.Renderer
|
||||
{
|
||||
TextureRect texRect;//表示国旗的纹理矩形
|
||||
|
||||
public void onDrawFrame(GL10 gl)
|
||||
{
|
||||
//清除深度缓冲与颜色缓冲
|
||||
GLES20.glClear( GLES20.GL_DEPTH_BUFFER_BIT | GLES20.GL_COLOR_BUFFER_BIT);
|
||||
MatrixState.pushMatrix();
|
||||
MatrixState.translate(0, 0, -1);
|
||||
MatrixState.rotate(yAngle,0,1,0);
|
||||
MatrixState.rotate(xAngle,1,0,0);
|
||||
//绘制纹理矩形
|
||||
texRect.drawSelf(textureFlagId);
|
||||
MatrixState.popMatrix();
|
||||
}
|
||||
|
||||
public void onSurfaceChanged(GL10 gl, int width, int height) {
|
||||
//设置视窗大小及位置
|
||||
GLES20.glViewport(0, 0, width, height);
|
||||
//计算GLSurfaceView的宽高比
|
||||
float ratio = (float) width / height;
|
||||
//调用此方法计算产生透视投影矩阵
|
||||
MatrixState.setProjectFrustum(-ratio, ratio, -1, 1, 4, 100);
|
||||
//调用此方法产生摄像机9参数位置矩阵
|
||||
MatrixState.setCamera(0,0,5,0f,0f,0f,0f,1.0f,0.0f);
|
||||
}
|
||||
|
||||
public void onSurfaceCreated(GL10 gl, EGLConfig config) {
|
||||
//设置屏幕背景色RGBA
|
||||
GLES20.glClearColor(0.0f,0.0f,0.0f,1.0f);
|
||||
// GLES20.glClearColor(1.0f,1.0f,1.0f,1.0f);
|
||||
//创建纹理矩形对对象
|
||||
texRect=new TextureRect(MySurfaceView.this);
|
||||
//打开深度检测
|
||||
GLES20.glEnable(GLES20.GL_DEPTH_TEST);
|
||||
//初始化纹理
|
||||
textureFlagId=initTexture(R.drawable.android_flag);
|
||||
//关闭背面剪裁
|
||||
GLES20.glDisable(GLES20.GL_CULL_FACE);
|
||||
//初始化变换矩阵
|
||||
MatrixState.setInitStack();
|
||||
}
|
||||
}
|
||||
|
||||
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();
|
||||
}
|
||||
}
|
||||
//实际加载纹理
|
||||
GLUtils.texImage2D
|
||||
(
|
||||
GLES20.GL_TEXTURE_2D, //纹理类型,在OpenGL ES中必须为GL10.GL_TEXTURE_2D
|
||||
0, //纹理的层次,0表示基本图像层,可以理解为直接贴图
|
||||
bitmapTmp, //纹理图像
|
||||
0 //纹理边框尺寸
|
||||
);
|
||||
bitmapTmp.recycle(); //纹理加载成功后释放图片
|
||||
return textureId;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,100 @@
|
||||
package com.bn.Sample13_1;
|
||||
import com.bn.Sample13_1.R;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.pm.ActivityInfo;
|
||||
import android.os.Bundle;
|
||||
import android.view.Window;
|
||||
import android.view.WindowManager;
|
||||
import android.widget.CompoundButton;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.RadioButton;
|
||||
import android.widget.CompoundButton.OnCheckedChangeListener;
|
||||
|
||||
public class Sample13_1_Activity extends Activity {
|
||||
private MySurfaceView mGLSurfaceView;
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState)
|
||||
{
|
||||
super.onCreate(savedInstanceState);
|
||||
//设置为全屏
|
||||
requestWindowFeature(Window.FEATURE_NO_TITLE);
|
||||
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN ,
|
||||
WindowManager.LayoutParams.FLAG_FULLSCREEN);
|
||||
//设置为横屏模式
|
||||
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
|
||||
//切换到主界面
|
||||
|
||||
//切换到主界面
|
||||
setContentView(R.layout.main);
|
||||
//初始化GLSurfaceView
|
||||
mGLSurfaceView = new MySurfaceView(this);
|
||||
mGLSurfaceView.requestFocus();//获取焦点
|
||||
mGLSurfaceView.setFocusableInTouchMode(true);//设置为可触控
|
||||
//将自定义的GLSurfaceView添加到外层LinearLayout中
|
||||
LinearLayout ll=(LinearLayout)findViewById(R.id.main_liner);
|
||||
ll.addView(mGLSurfaceView);
|
||||
//为RadioButton添加监听器及着色器选择代码
|
||||
RadioButton rb=(RadioButton)findViewById(R.id.x1);
|
||||
rb.setOnCheckedChangeListener(
|
||||
new OnCheckedChangeListener()
|
||||
{
|
||||
@Override
|
||||
public void onCheckedChanged(CompoundButton buttonView,boolean isChecked)
|
||||
{
|
||||
if(isChecked)
|
||||
{//设置波浪为X方向
|
||||
mGLSurfaceView.mRenderer.texRect.currIndex=0;
|
||||
}
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
rb=(RadioButton)findViewById(R.id.x2);
|
||||
rb.setOnCheckedChangeListener(
|
||||
new OnCheckedChangeListener()
|
||||
{
|
||||
@Override
|
||||
public void onCheckedChanged(CompoundButton buttonView,boolean isChecked)
|
||||
{
|
||||
if(isChecked)
|
||||
{//设置波浪为斜向
|
||||
mGLSurfaceView.mRenderer.texRect.currIndex=1;
|
||||
}
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
rb=(RadioButton)findViewById(R.id.x3);
|
||||
rb.setOnCheckedChangeListener(
|
||||
new OnCheckedChangeListener()
|
||||
{
|
||||
@Override
|
||||
public void onCheckedChanged(CompoundButton buttonView,boolean isChecked)
|
||||
{
|
||||
if(isChecked)
|
||||
{//设置波浪为XY双向波浪
|
||||
mGLSurfaceView.mRenderer.texRect.currIndex=2;
|
||||
}
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onResume() {
|
||||
super.onResume();
|
||||
mGLSurfaceView.onResume();
|
||||
Constant.threadFlag=true;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPause() {
|
||||
super.onPause();
|
||||
mGLSurfaceView.onPause();
|
||||
Constant.threadFlag=false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,126 @@
|
||||
package com.bn.Sample13_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,205 @@
|
||||
package com.bn.Sample13_1;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.ByteOrder;
|
||||
import java.nio.FloatBuffer;
|
||||
import android.opengl.GLES20;
|
||||
|
||||
//有波浪效果的纹理矩形
|
||||
public class TextureRect
|
||||
{
|
||||
int[] mPrograms=new int[3];//自定义渲染管线着色器程序id
|
||||
int[] muMVPMatrixHandle=new int[3];//总变换矩阵引用
|
||||
int[] maPositionHandle=new int[3]; //顶点位置属性引用
|
||||
int[] maTexCoorHandle=new int[3]; //顶点纹理坐标属性引用
|
||||
int[] maStartAngleHandle=new int[3]; //本帧起始角度属性引用
|
||||
int[] muWidthSpanHandle=new int[3];//横向长度总跨度引用
|
||||
int currIndex=0;//当前着色器索引
|
||||
FloatBuffer mVertexBuffer;//顶点坐标数据缓冲
|
||||
FloatBuffer mTexCoorBuffer;//顶点纹理坐标数据缓冲
|
||||
int vCount=0;
|
||||
final float WIDTH_SPAN=3.3f;//2.8f;//横向长度总跨度
|
||||
float currStartAngle=0;//当前帧的起始角度0~2PI
|
||||
|
||||
public TextureRect(MySurfaceView mv)
|
||||
{
|
||||
//初始化顶点坐标与着色数据
|
||||
initVertexData();
|
||||
//初始化shader
|
||||
initShader(mv,0,"vertex_tex_x.sh");
|
||||
initShader(mv,1,"vertex_tex_xie.sh");
|
||||
initShader(mv,2,"vertex_tex_xy.sh");
|
||||
//启动一个线程定时换帧
|
||||
new Thread()
|
||||
{
|
||||
public void run()
|
||||
{
|
||||
while(Constant.threadFlag)
|
||||
{
|
||||
currStartAngle+=(float) (Math.PI/16);
|
||||
try
|
||||
{
|
||||
Thread.sleep(50);
|
||||
} catch (InterruptedException e)
|
||||
{
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
}.start();
|
||||
}
|
||||
//初始化顶点坐标与着色数据的方法
|
||||
public void initVertexData()
|
||||
{
|
||||
final int cols=12;//列数
|
||||
final int rows=cols*3/4;//行数
|
||||
final float UNIT_SIZE=WIDTH_SPAN/cols;//每格的单位长度
|
||||
//顶点坐标数据的初始化================begin============================
|
||||
vCount=cols*rows*6;//每个格子两个三角形,每个三角形3个顶点
|
||||
float vertices[]=new float[vCount*3];//每个顶点xyz三个坐标
|
||||
int count=0;//顶点计数器
|
||||
for(int j=0;j<rows;j++)
|
||||
{
|
||||
for(int i=0;i<cols;i++)
|
||||
{
|
||||
//计算当前格子左上侧点坐标
|
||||
float zsx=-UNIT_SIZE*cols/2+i*UNIT_SIZE;
|
||||
float zsy=UNIT_SIZE*rows/2-j*UNIT_SIZE;
|
||||
float zsz=0;
|
||||
|
||||
vertices[count++]=zsx;
|
||||
vertices[count++]=zsy;
|
||||
vertices[count++]=zsz;
|
||||
|
||||
vertices[count++]=zsx;
|
||||
vertices[count++]=zsy-UNIT_SIZE;
|
||||
vertices[count++]=zsz;
|
||||
|
||||
vertices[count++]=zsx+UNIT_SIZE;
|
||||
vertices[count++]=zsy;
|
||||
vertices[count++]=zsz;
|
||||
|
||||
vertices[count++]=zsx+UNIT_SIZE;
|
||||
vertices[count++]=zsy;
|
||||
vertices[count++]=zsz;
|
||||
|
||||
vertices[count++]=zsx;
|
||||
vertices[count++]=zsy-UNIT_SIZE;
|
||||
vertices[count++]=zsz;
|
||||
|
||||
vertices[count++]=zsx+UNIT_SIZE;
|
||||
vertices[count++]=zsy-UNIT_SIZE;
|
||||
vertices[count++]=zsz;
|
||||
}
|
||||
}
|
||||
//创建顶点坐标数据缓冲
|
||||
//vertices.length*4是因为一个整数四个字节
|
||||
ByteBuffer vbb = ByteBuffer.allocateDirect(vertices.length*4);
|
||||
vbb.order(ByteOrder.nativeOrder());//设置字节顺序
|
||||
mVertexBuffer = vbb.asFloatBuffer();//转换为Float型缓冲
|
||||
mVertexBuffer.put(vertices);//向缓冲区中放入顶点坐标数据
|
||||
mVertexBuffer.position(0);//设置缓冲区起始位置
|
||||
//顶点纹理坐标数据的初始化================begin============================
|
||||
float texCoor[]=generateTexCoor(cols,rows);
|
||||
//创建顶点纹理坐标数据缓冲
|
||||
ByteBuffer cbb = ByteBuffer.allocateDirect(texCoor.length*4);
|
||||
cbb.order(ByteOrder.nativeOrder());//设置字节顺序
|
||||
mTexCoorBuffer = cbb.asFloatBuffer();//转换为Float型缓冲
|
||||
mTexCoorBuffer.put(texCoor);//向缓冲区中放入顶点着色数据
|
||||
mTexCoorBuffer.position(0);//设置缓冲区起始位置
|
||||
}
|
||||
//初始化shader
|
||||
public void initShader(MySurfaceView mv,int index,String vertexName)
|
||||
{
|
||||
//加载顶点着色器的脚本内容
|
||||
String mVertexShader=ShaderUtil.loadFromAssetsFile(vertexName, mv.getResources());
|
||||
//加载片元着色器的脚本内容
|
||||
String mFragmentShader=ShaderUtil.loadFromAssetsFile("frag_tex.sh", mv.getResources());
|
||||
//基于顶点着色器与片元着色器创建程序
|
||||
mPrograms[index] = ShaderUtil.createProgram(mVertexShader, mFragmentShader);
|
||||
//获取程序中顶点位置属性引用
|
||||
maPositionHandle[index] = GLES20.glGetAttribLocation(mPrograms[index], "aPosition");
|
||||
//获取程序中顶点纹理坐标属性引用
|
||||
maTexCoorHandle[index]= GLES20.glGetAttribLocation(mPrograms[index], "aTexCoor");
|
||||
//获取程序中总变换矩阵引用
|
||||
muMVPMatrixHandle[index] = GLES20.glGetUniformLocation(mPrograms[index], "uMVPMatrix");
|
||||
//获取本帧起始角度属性引用
|
||||
maStartAngleHandle[index]=GLES20.glGetUniformLocation(mPrograms[index], "uStartAngle");
|
||||
//获取横向长度总跨度引用
|
||||
muWidthSpanHandle[index]=GLES20.glGetUniformLocation(mPrograms[index], "uWidthSpan");
|
||||
}
|
||||
public void drawSelf(int texId)
|
||||
{
|
||||
//制定使用某套shader程序
|
||||
GLES20.glUseProgram(mPrograms[currIndex]);
|
||||
//将最终变换矩阵传入shader程序
|
||||
GLES20.glUniformMatrix4fv(muMVPMatrixHandle[currIndex], 1, false, MatrixState.getFinalMatrix(), 0);
|
||||
//将本帧起始角度传入shader程序
|
||||
GLES20.glUniform1f(maStartAngleHandle[currIndex], currStartAngle);
|
||||
//将横向长度总跨度传入shader程序
|
||||
GLES20.glUniform1f(muWidthSpanHandle[currIndex], WIDTH_SPAN);
|
||||
//将顶点位置数据传入渲染管线
|
||||
GLES20.glVertexAttribPointer
|
||||
(
|
||||
maPositionHandle[currIndex],
|
||||
3,
|
||||
GLES20.GL_FLOAT,
|
||||
false,
|
||||
3*4,
|
||||
mVertexBuffer
|
||||
);
|
||||
//将顶点纹理坐标数据传入渲染管线
|
||||
GLES20.glVertexAttribPointer
|
||||
(
|
||||
maTexCoorHandle[currIndex],
|
||||
2,
|
||||
GLES20.GL_FLOAT,
|
||||
false,
|
||||
2*4,
|
||||
mTexCoorBuffer
|
||||
);
|
||||
//启用顶点位置、纹理坐标数据
|
||||
GLES20.glEnableVertexAttribArray(maPositionHandle[currIndex]);
|
||||
GLES20.glEnableVertexAttribArray(maTexCoorHandle[currIndex]);
|
||||
//绑定纹理
|
||||
GLES20.glActiveTexture(GLES20.GL_TEXTURE0);
|
||||
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, texId);
|
||||
GLES20.glDrawArrays(GLES20.GL_TRIANGLES, 0, vCount);
|
||||
}
|
||||
//自动切分纹理产生纹理数组的方法
|
||||
public float[] generateTexCoor(int bw,int bh)
|
||||
{
|
||||
float[] result=new float[bw*bh*6*2];
|
||||
float sizew=1.0f/bw;//列数
|
||||
float sizeh=0.75f/bh;//行数
|
||||
int c=0;
|
||||
for(int i=0;i<bh;i++)
|
||||
{
|
||||
for(int j=0;j<bw;j++)
|
||||
{
|
||||
//每行列一个矩形,由两个三角形构成,共六个点,12个纹理坐标
|
||||
float s=j*sizew;
|
||||
float t=i*sizeh;
|
||||
|
||||
result[c++]=s;
|
||||
result[c++]=t;
|
||||
|
||||
result[c++]=s;
|
||||
result[c++]=t+sizeh;
|
||||
|
||||
result[c++]=s+sizew;
|
||||
result[c++]=t;
|
||||
|
||||
|
||||
result[c++]=s+sizew;
|
||||
result[c++]=t;
|
||||
|
||||
result[c++]=s;
|
||||
result[c++]=t+sizeh;
|
||||
|
||||
result[c++]=s+sizew;
|
||||
result[c++]=t+sizeh;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user