初次提交
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_5</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,19 @@
|
||||
<?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_5">
|
||||
<application android:icon="@drawable/icon" android:label="@string/app_name">
|
||||
<activity android:name=".Sample13_5_Activity"
|
||||
android:label="@string/app_name"
|
||||
android:theme="@android:style/Theme.NoTitleBar.Fullscreen"
|
||||
>
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN" />
|
||||
<category android:name="android.intent.category.LAUNCHER" />
|
||||
</intent-filter>
|
||||
</activity>
|
||||
|
||||
</application>
|
||||
<uses-sdk android:minSdkVersion="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,39 @@
|
||||
uniform mat4 uMVPMatrix; //总变换矩阵
|
||||
attribute vec3 aPosition; //顶点位置
|
||||
attribute vec2 aTexCoor; //顶点纹理坐标
|
||||
varying vec2 vTextureCoord; //用于传递给片元着色器的变量
|
||||
uniform float ratio;
|
||||
void main()
|
||||
{
|
||||
float pi = 3.1415926;
|
||||
//-----------------------这里要进行二维扭动----------------
|
||||
//中心点的X坐标和Y坐标
|
||||
float centerX=0.0;
|
||||
float centerY=-5.0;
|
||||
//获取当前点的X坐标和Y坐标
|
||||
float currX = aPosition.x;
|
||||
float currY = aPosition.y;
|
||||
//计算X和Y的偏移量
|
||||
float spanX = currX - centerX;
|
||||
float spanY = currY - centerY;
|
||||
//计算极径
|
||||
float currRadius = sqrt(spanX * spanX + spanY * spanY);
|
||||
//计算当前点的极角
|
||||
float currRadians;//用弧度表示
|
||||
if(spanX != 0.0)
|
||||
{
|
||||
currRadians = atan(spanY , spanX);
|
||||
}
|
||||
else
|
||||
{
|
||||
currRadians = spanY > 0.0 ? pi/2.0 : 3.0*pi/2.0;
|
||||
}
|
||||
//进行扭曲
|
||||
float resultRadians = currRadians + ratio*currRadius;
|
||||
//计算结果点
|
||||
float resultX = centerX + currRadius * cos(resultRadians);
|
||||
float resultY = centerY + currRadius * sin(resultRadians);
|
||||
//构造结果点
|
||||
gl_Position = uMVPMatrix * vec4(resultX,resultY,0.0,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.
@@ -0,0 +1,11 @@
|
||||
# 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.
|
||||
|
||||
# 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.Sample13_5;
|
||||
|
||||
public final class R {
|
||||
public static final class attr {
|
||||
}
|
||||
public static final class drawable {
|
||||
public static final int android=0x7f020000;
|
||||
public static final int icon=0x7f020001;
|
||||
}
|
||||
public static final class layout {
|
||||
public static final int main=0x7f030000;
|
||||
}
|
||||
public static final class string {
|
||||
public static final int app_name=0x7f040001;
|
||||
public static final int hello=0x7f040000;
|
||||
}
|
||||
}
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 32 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 4.0 KiB |
@@ -0,0 +1,12 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:orientation="vertical"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="fill_parent"
|
||||
>
|
||||
<TextView
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/hello"
|
||||
/>
|
||||
</LinearLayout>
|
||||
@@ -0,0 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<string name="hello">Hello World, TrangleTwisting_Activity!</string>
|
||||
<string name="app_name">Sample13_5</string>
|
||||
</resources>
|
||||
@@ -0,0 +1,62 @@
|
||||
package com.bn.Sample13_5;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import android.content.res.Resources;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.BitmapFactory;
|
||||
import android.opengl.GLES20;
|
||||
import android.opengl.GLUtils;
|
||||
//常量类
|
||||
public class Constant
|
||||
{
|
||||
//三角形边长
|
||||
public static float triangle_edgeLength=8f;
|
||||
//三角形组层数
|
||||
public static int triangle_levelNum=40;
|
||||
//加载纹理的方法
|
||||
public static int initTexture(Resources r,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 = r.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,155 @@
|
||||
package com.bn.Sample13_5;
|
||||
import javax.microedition.khronos.egl.EGLConfig;
|
||||
import javax.microedition.khronos.opengles.GL10;
|
||||
|
||||
import com.bn.Sample13_5.R;
|
||||
|
||||
import static com.bn.Sample13_5.Constant.*;
|
||||
import android.content.Context;
|
||||
import android.content.res.Resources;
|
||||
import android.opengl.GLES20;
|
||||
import android.opengl.GLSurfaceView;
|
||||
import android.view.MotionEvent;
|
||||
class GameSurfaceView extends GLSurfaceView
|
||||
{
|
||||
private SceneRenderer mRenderer;//场景渲染器
|
||||
float mPreviousY;
|
||||
float mPreviousX;
|
||||
//-----纹理
|
||||
int tex_trangleId;//系统分配的草地纹理id
|
||||
//-----物体对象组件
|
||||
MultiTrangle trangle;
|
||||
static float tx=0;//观察目标点x坐标
|
||||
static float ty=0;//观察目标点y坐标
|
||||
static float tz=0;//观察目标点z坐标
|
||||
static float cx=0;//摄像机x坐标
|
||||
static float cy=0;//摄像机y坐标
|
||||
static float cz=30;//摄像机z坐标
|
||||
float currY;
|
||||
float rotation;
|
||||
float twistingRatio;//三角形扭转的缩放比例
|
||||
int symbol=1;
|
||||
float currRatio=0.05f;
|
||||
public GameSurfaceView(Context context)
|
||||
{
|
||||
super(context);
|
||||
this.setEGLContextClientVersion(2); //设置使用OPENGL ES2.0
|
||||
mRenderer = new SceneRenderer(); //创建场景渲染器
|
||||
setRenderer(mRenderer); //设置渲染器
|
||||
setRenderMode(GLSurfaceView.RENDERMODE_CONTINUOUSLY);//设置渲染模式为主动渲染
|
||||
setKeepScreenOn(true);
|
||||
}
|
||||
//触摸事件回调方法
|
||||
@Override
|
||||
public boolean onTouchEvent(MotionEvent e)
|
||||
{
|
||||
float x = e.getX();
|
||||
switch (e.getAction())
|
||||
{
|
||||
case MotionEvent.ACTION_DOWN://按下动作
|
||||
break;
|
||||
case MotionEvent.ACTION_UP://抬起动作
|
||||
break;
|
||||
case MotionEvent.ACTION_MOVE:
|
||||
float dx = x - mPreviousX;//计算触控笔X位移
|
||||
if(dx<-10)//左转弯
|
||||
{
|
||||
rotation-=5f;
|
||||
}
|
||||
else if(dx>10)//右转弯
|
||||
{
|
||||
rotation+=5f;
|
||||
}
|
||||
break;
|
||||
}
|
||||
mPreviousX = x;//记录触控笔位置
|
||||
return true;
|
||||
}
|
||||
class SceneRenderer implements GLSurfaceView.Renderer
|
||||
{
|
||||
public void onDrawFrame(GL10 gl)
|
||||
{
|
||||
//清除深度缓冲与颜色缓冲
|
||||
GLES20.glClear( GLES20.GL_DEPTH_BUFFER_BIT | GLES20.GL_COLOR_BUFFER_BIT);
|
||||
MatrixState.setCamera(cx,cy,cz,tx,ty,tz,0f,1.0f,0.0f);
|
||||
MatrixState.pushMatrix();
|
||||
//将三角形移动到屏幕中心
|
||||
float upOffset= (float) (triangle_edgeLength/2/Math.cos(Math.PI/6));
|
||||
MatrixState.translate(0, upOffset, 0);
|
||||
MatrixState.rotate(rotation, 0, 1, 0);
|
||||
trangle.drawSelf(tex_trangleId,twistingRatio);
|
||||
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, 3, 1000);
|
||||
//调用此方法产生摄像机9参数位置矩阵
|
||||
MatrixState.setCamera(cx,cy,cz,tx,ty,tz,0f,1.0f,0.0f);
|
||||
}
|
||||
public void onSurfaceCreated(GL10 gl, EGLConfig config)
|
||||
{
|
||||
//设置屏幕背景色RGBA
|
||||
GLES20.glClearColor(0.0f,0.0f,0.0f,1.0f);
|
||||
//打开深度检测
|
||||
GLES20.glEnable(GLES20.GL_DEPTH_TEST);
|
||||
//打开背面剪裁
|
||||
GLES20.glDisable(GLES20.GL_CULL_FACE);
|
||||
//初始化变换矩阵
|
||||
MatrixState.setInitStack();
|
||||
//加载shader
|
||||
ShaderManager.loadCodeFromFile(GameSurfaceView.this.getResources());
|
||||
//编译shader
|
||||
ShaderManager.compileShader();
|
||||
initAllObject();//初始化纹理组件
|
||||
initAllTexture();//初始化纹理
|
||||
|
||||
//创建一个线程,定时摆动树干
|
||||
new Thread()
|
||||
{
|
||||
@Override
|
||||
public void run()
|
||||
{
|
||||
while(true)
|
||||
{
|
||||
twistingRatio=twistingRatio+symbol*currRatio;
|
||||
if(twistingRatio>1.0f)
|
||||
{
|
||||
twistingRatio=1.0f;
|
||||
symbol=-symbol;
|
||||
}
|
||||
if(twistingRatio<-1.0f)
|
||||
{
|
||||
twistingRatio=-1.0f;
|
||||
symbol=-symbol;
|
||||
}
|
||||
try
|
||||
{
|
||||
Thread.sleep(100);
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
}.start();
|
||||
}
|
||||
}
|
||||
//创建所有的物体组件对象
|
||||
public void initAllObject()
|
||||
{
|
||||
trangle=new MultiTrangle(ShaderManager.getTrangleShaderProgram(),
|
||||
triangle_edgeLength,triangle_levelNum);
|
||||
}
|
||||
//初始化所有的纹理图形
|
||||
public void initAllTexture()
|
||||
{
|
||||
Resources r=this.getResources();//获取资源
|
||||
tex_trangleId=initTexture(r,R.drawable.android);//草地纹理
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,138 @@
|
||||
package com.bn.Sample13_5;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.ByteOrder;
|
||||
import java.nio.FloatBuffer;
|
||||
import java.util.*;
|
||||
import android.opengl.Matrix;
|
||||
|
||||
//存储系统矩阵状态的类
|
||||
public class MatrixState
|
||||
{
|
||||
static float[] mProjMatrix = new float[16];//4x4矩阵 投影用
|
||||
static float[] mVMatrix = new float[16];//摄像机位置朝向9参数矩阵
|
||||
private static float[] currMatrix;//当前变换矩阵
|
||||
public static FloatBuffer cameraFB;
|
||||
public static float[] lightLocation=new float[]{0,0,0};//定位光光源位置
|
||||
public static FloatBuffer lightPositionFB;//燈光的位置
|
||||
|
||||
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;
|
||||
}
|
||||
//设置灯光位置的方法
|
||||
public static void setLightLocation(float x,float y,float z)
|
||||
{
|
||||
lightLocation[0]=x;
|
||||
lightLocation[1]=y;
|
||||
lightLocation[2]=z;
|
||||
ByteBuffer llbb = ByteBuffer.allocateDirect(3*4);
|
||||
llbb.order(ByteOrder.nativeOrder());//设置字节顺序
|
||||
lightPositionFB=llbb.asFloatBuffer();
|
||||
lightPositionFB.put(lightLocation);
|
||||
lightPositionFB.position(0);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,203 @@
|
||||
package com.bn.Sample13_5;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.ByteOrder;
|
||||
import java.nio.FloatBuffer;
|
||||
import java.util.ArrayList;
|
||||
|
||||
import android.opengl.GLES20;
|
||||
|
||||
/*
|
||||
* 自动生成三角形组 等边三角形
|
||||
* 当前三角形组的最上边点位于原点,并且关于Y轴负方向轴对称
|
||||
*/
|
||||
public class MultiTrangle
|
||||
{
|
||||
int program;//自定义渲染管线着色器程序id
|
||||
int maPositionHandle;//获取程序中顶点位置属性引用
|
||||
int maTexCoorHandle;//获取程序中顶点纹理坐标属性引用
|
||||
int muMVPMatrixHandle;//获取程序中总变换矩阵引用
|
||||
int fuRatioHandle;//三角形的缩放比例id
|
||||
|
||||
FloatBuffer fVertexBuffer;//顶点数据buffer
|
||||
FloatBuffer fTextureBuffer;//纹理数据buffer
|
||||
int vCount;//顶点的个数
|
||||
public MultiTrangle(int program,float edgeLength,int levelNum)//程序id,三角形边长,三角形的层数
|
||||
{
|
||||
this.program=program;
|
||||
initVertexData(edgeLength,levelNum);
|
||||
initShader();
|
||||
}
|
||||
//初始化顶点信息
|
||||
public void initVertexData(float edgeLength,int levelNum)
|
||||
{
|
||||
ArrayList<Float> al_vertex=new ArrayList<Float>();//存储顶点信息
|
||||
ArrayList<Float> al_texture=new ArrayList<Float>();//存储纹理信息
|
||||
float perLength = edgeLength/levelNum;
|
||||
for(int i=0;i<levelNum;i++)//每层进行扫描
|
||||
{
|
||||
//当前层顶端边数
|
||||
int currTopEdgeNum=i;
|
||||
//当前层底端边数
|
||||
int currBottomEdgeNum=i+1;
|
||||
//每个三角形的高度
|
||||
float currTrangleHeight=(float) (perLength*Math.sin(Math.PI/3));
|
||||
//当前层顶端最左边点的坐标
|
||||
float topEdgeFirstPointX=-perLength*currTopEdgeNum/2;
|
||||
float topEdgeFirstPointY=-i*currTrangleHeight;
|
||||
float topEdgeFirstPointZ=0;
|
||||
|
||||
//当前层底端最左边点的坐标
|
||||
float bottomEdgeFirstPointX=-perLength*currBottomEdgeNum/2;
|
||||
float bottomEdgeFirstPointY=-(i+1)*currTrangleHeight;
|
||||
float bottomEdgeFirstPointZ=0;
|
||||
//---------------纹理----------------
|
||||
float horSpan=1/(float)levelNum;//横向纹理的偏移量
|
||||
float verSpan=1/(float)levelNum;//纵向纹理的偏移量
|
||||
//当前层顶端第一个纹理坐标相关参数问题
|
||||
float topFirstS=0.5f-currTopEdgeNum*horSpan/2;
|
||||
float topFirstT=i*verSpan;
|
||||
//当前层底端第一个纹理坐标的相关参数
|
||||
float bottomFirstS=0.5f-currBottomEdgeNum*horSpan/2;
|
||||
float bottomFirstT=(i+1)*verSpan;
|
||||
//底层三角形卷绕建模
|
||||
for(int j=0;j<currBottomEdgeNum;j++)//对每个三角形进行卷绕
|
||||
{
|
||||
//顶点
|
||||
float topX=topEdgeFirstPointX+j*perLength;
|
||||
float topY=topEdgeFirstPointY;
|
||||
float topZ=topEdgeFirstPointZ;
|
||||
float topS=topFirstS+j*horSpan;
|
||||
float topT=topFirstT;
|
||||
//左下点
|
||||
float leftBottomX=bottomEdgeFirstPointX+j*perLength;
|
||||
float leftBottomY=bottomEdgeFirstPointY;
|
||||
float leftBottomZ=bottomEdgeFirstPointZ;
|
||||
float leftBottomS=bottomFirstS+j*horSpan;
|
||||
float leftBottomT=bottomFirstT;
|
||||
//右下点
|
||||
float rightBottomX=leftBottomX+perLength;
|
||||
float rightBottomY=bottomEdgeFirstPointY;
|
||||
float rightBottomZ=bottomEdgeFirstPointZ;
|
||||
float rightBottomS=leftBottomS+horSpan;
|
||||
float rightBottomT=leftBottomT;
|
||||
//逆时针卷绕----- 纹理绘制方式
|
||||
al_vertex.add(topX);al_vertex.add(topY);al_vertex.add(topZ);
|
||||
al_vertex.add(leftBottomX);al_vertex.add(leftBottomY);al_vertex.add(leftBottomZ);
|
||||
al_vertex.add(rightBottomX);al_vertex.add(rightBottomY);al_vertex.add(rightBottomZ);
|
||||
//-------纹理绘制方式
|
||||
al_texture.add(topS);al_texture.add(topT);
|
||||
al_texture.add(leftBottomS);al_texture.add(leftBottomT);
|
||||
al_texture.add(rightBottomS);al_texture.add(rightBottomT);
|
||||
|
||||
}
|
||||
//顶层三角形卷绕建模
|
||||
for(int k=0;k<currTopEdgeNum;k++)
|
||||
{
|
||||
//左上点
|
||||
float leftTopX=topEdgeFirstPointX+k*perLength;
|
||||
float leftTopY=topEdgeFirstPointY;
|
||||
float leftTopZ=topEdgeFirstPointZ;
|
||||
float leftTopS=topFirstS+k*horSpan;
|
||||
float leftTopT=topFirstT;
|
||||
//底端点
|
||||
float bottomX=bottomEdgeFirstPointX+(k+1)*perLength;
|
||||
float bottomY=bottomEdgeFirstPointY;
|
||||
float bottomZ=bottomEdgeFirstPointZ;
|
||||
float bottomS=bottomFirstS+(k+1)*horSpan;
|
||||
float bottomT=bottomFirstT;
|
||||
//右上点
|
||||
float rightTopX=leftTopX+perLength;
|
||||
float rightTopY=leftTopY;
|
||||
float rightTopZ=leftTopZ;
|
||||
float rightTopS=leftTopS+horSpan;
|
||||
float rightTopT=topFirstT;
|
||||
//逆时针卷绕-----
|
||||
al_vertex.add(leftTopX);al_vertex.add(leftTopY);al_vertex.add(leftTopZ);
|
||||
al_vertex.add(bottomX);al_vertex.add(bottomY);al_vertex.add(bottomZ);
|
||||
al_vertex.add(rightTopX);al_vertex.add(rightTopY);al_vertex.add(rightTopZ);
|
||||
|
||||
al_texture.add(leftTopS);al_texture.add(leftTopT);
|
||||
al_texture.add(bottomS);al_texture.add(bottomT);
|
||||
al_texture.add(rightTopS);al_texture.add(rightTopT);
|
||||
}
|
||||
}
|
||||
//加载进顶点缓冲
|
||||
int vertexSize=al_vertex.size();
|
||||
vCount=vertexSize/3;//确定顶点的个数
|
||||
float vertexs[]=new float[vertexSize];
|
||||
for(int i=0;i<vertexSize;i++)
|
||||
{
|
||||
vertexs[i]=al_vertex.get(i);
|
||||
}
|
||||
ByteBuffer vbb=ByteBuffer.allocateDirect(vertexSize*4);
|
||||
vbb.order(ByteOrder.nativeOrder());
|
||||
fVertexBuffer=vbb.asFloatBuffer();
|
||||
fVertexBuffer.put(vertexs);
|
||||
fVertexBuffer.position(0);
|
||||
al_vertex=null;
|
||||
//加载进纹理缓冲
|
||||
int textureSize=al_texture.size();
|
||||
float textures[]=new float[textureSize];
|
||||
for(int i=0;i<textureSize;i++)
|
||||
{
|
||||
textures[i]=al_texture.get(i);
|
||||
}
|
||||
ByteBuffer tbb=ByteBuffer.allocateDirect(textureSize*4);
|
||||
tbb.order(ByteOrder.nativeOrder());
|
||||
fTextureBuffer=tbb.asFloatBuffer();
|
||||
fTextureBuffer.put(textures);
|
||||
fTextureBuffer.position(0);
|
||||
al_texture=null;
|
||||
}
|
||||
//初始化着色器
|
||||
public void initShader()
|
||||
{
|
||||
//获取程序中顶点位置属性引用
|
||||
maPositionHandle = GLES20.glGetAttribLocation(program, "aPosition");
|
||||
//获取程序中顶点纹理坐标属性引用
|
||||
maTexCoorHandle= GLES20.glGetAttribLocation(program, "aTexCoor");
|
||||
//获取程序中总变换矩阵引用
|
||||
muMVPMatrixHandle = GLES20.glGetUniformLocation(program, "uMVPMatrix");
|
||||
//获取程序中三角形的缩放比例
|
||||
fuRatioHandle = GLES20.glGetUniformLocation(program, "ratio");
|
||||
}
|
||||
//绘制方法
|
||||
public void drawSelf(int texId,float twistingRatio)
|
||||
{
|
||||
//制定使用某套shader程序
|
||||
GLES20.glUseProgram(program);
|
||||
//将最终变换矩阵传入shader程序
|
||||
GLES20.glUniformMatrix4fv(muMVPMatrixHandle, 1, false, MatrixState.getFinalMatrix(), 0);
|
||||
//将缩放比例传入shader程序
|
||||
GLES20.glUniform1f(fuRatioHandle, twistingRatio);
|
||||
//将顶点位置数据传入渲染管线
|
||||
GLES20.glVertexAttribPointer
|
||||
(
|
||||
maPositionHandle,
|
||||
3,
|
||||
GLES20.GL_FLOAT,
|
||||
false,
|
||||
3*4,
|
||||
fVertexBuffer
|
||||
);
|
||||
//将纹理坐标数据传入渲染管线
|
||||
GLES20.glVertexAttribPointer
|
||||
(
|
||||
maTexCoorHandle,
|
||||
2,
|
||||
GLES20.GL_FLOAT,
|
||||
false,
|
||||
2*4,
|
||||
fTextureBuffer
|
||||
);
|
||||
//启用顶点位置数据
|
||||
GLES20.glEnableVertexAttribArray(maPositionHandle);
|
||||
GLES20.glEnableVertexAttribArray(maTexCoorHandle);
|
||||
//绑定纹理
|
||||
GLES20.glActiveTexture(GLES20.GL_TEXTURE0);
|
||||
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, texId);
|
||||
//绘制纹理矩形
|
||||
GLES20.glDrawArrays(GLES20.GL_TRIANGLES, 0, vCount);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
package com.bn.Sample13_5;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.os.Bundle;
|
||||
|
||||
public class Sample13_5_Activity extends Activity
|
||||
{
|
||||
GameSurfaceView gameView;
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState)
|
||||
{
|
||||
super.onCreate(savedInstanceState);
|
||||
gameView = new GameSurfaceView(this);
|
||||
setContentView(gameView);
|
||||
gameView.requestFocus();//ťńČĄ˝šľă
|
||||
gameView.setFocusableInTouchMode(true);//ÉčÖĂÎŞżÉ´ĽżŘ
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected void onResume() {
|
||||
super.onResume();
|
||||
gameView.onResume();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPause() {
|
||||
super.onPause();
|
||||
gameView.onPause();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
package com.bn.Sample13_5;
|
||||
|
||||
import android.content.res.Resources;
|
||||
/*
|
||||
* 该shader管理器主要是用于加载shader和编译shader
|
||||
*/
|
||||
public class ShaderManager
|
||||
{
|
||||
final static String[][] shaderName=
|
||||
{
|
||||
{"vertex_tex.sh","frag_tex.sh"},
|
||||
};
|
||||
static String[]mVertexShader=new String[shaderName.length];//顶点着色器字符串数组
|
||||
static String[]mFragmentShader=new String[shaderName.length];//片元着色器字符串数组
|
||||
static int[] program=new int[shaderName.length];//程序数组
|
||||
//加载shader字符串
|
||||
public static void loadCodeFromFile(Resources r)
|
||||
{
|
||||
for(int i=0;i<shaderName.length;i++)
|
||||
{
|
||||
//加载顶点着色器的脚本内容
|
||||
mVertexShader[i]=ShaderUtil.loadFromAssetsFile(shaderName[i][0],r);
|
||||
//加载片元着色器的脚本内容
|
||||
mFragmentShader[i]=ShaderUtil.loadFromAssetsFile(shaderName[i][1], r);
|
||||
}
|
||||
}
|
||||
//编译shader
|
||||
public static void compileShader()
|
||||
{
|
||||
for(int i=0;i<shaderName.length;i++)
|
||||
{
|
||||
program[i]=ShaderUtil.createProgram(mVertexShader[i], mFragmentShader[i]);
|
||||
}
|
||||
}
|
||||
//这里返回三角形shader
|
||||
public static int getTrangleShaderProgram()
|
||||
{
|
||||
return program[0];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,126 @@
|
||||
package com.bn.Sample13_5;
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user