android opengl es 3d世界

额,有nehe的教程,就不用买杨丰盛的视频喽,接着看吧,虽然看英文烦点,不过总比没有好。

 

(1)RealWorld

 

 

package sim.feel;

import java.io.IOException;
import java.io.InputStream;

import android.app.Activity;
import android.content.res.AssetManager;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.opengl.GLSurfaceView;
import android.os.Bundle;
import android.view.KeyEvent;

public class RealWorld extends Activity {
    private MyRenderer renderer = new MyRenderer();
    GLSurfaceView glSurfaceView;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        glSurfaceView = new GLSurfaceView(this);
        LoadImage.load(getResources());
        new LoadTxt(getResources());
        glSurfaceView.setRenderer(renderer);
        setContentView(glSurfaceView);
    }

    @Override
    public boolean onKeyUp(int keyCode, KeyEvent event) {
        renderer.onKeyUp(keyCode, event);
        return super.onKeyUp(keyCode, event);
    }

}

// 载入图片
class LoadImage {
    public static Bitmap bitmap;

    public static void load(Resources res) {
        bitmap = BitmapFactory.decodeResource(res, R.drawable.img);
    }
}
//New
// 读取world.txt文件
class LoadTxt {
    public static Resources res;

    public LoadTxt(Resources res) {
        LoadTxt.res = res;
    }

    public static InputStream getFile(String file) {
        AssetManager am = LoadTxt.res.getAssets();
        try {
            return am.open(file);
        } catch (IOException e) {
            return null;
        }
    }

}

 

 

 

(2)Data类

 

package sim.feel;

import java.util.ArrayList;
import java.util.List;

//区段结构
class SECTOR {
    int numtriangles; // triangle结构数目
    List<TRIANGLE> triangle = new ArrayList<TRIANGLE>(); // triangle的list
}

// 三角形
class TRIANGLE {
    VERTEX vertex[] = new VERTEX[3];
}

// 构建顶点结构
class VERTEX {
    float x, y, z; // 3d坐标
    float u, v; // 纹理坐标

    public VERTEX(float x, float y, float z, float u, float v) {
        super();
        this.x = x;
        this.y = y;
        this.z = z;
        this.u = u;
        this.v = v;
    }
}

 

 

(3)MyRenderer

 

package sim.feel;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;
import java.nio.IntBuffer;

import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10;

import android.opengl.GLSurfaceView.Renderer;
import android.opengl.GLUtils;
import android.view.KeyEvent;

public class MyRenderer implements Renderer {
    SECTOR sector = new SECTOR();

    int[] texture = new int[3];

    public final static float piover180 = 0.0174532925f;
    float heading;
    float xpos;
    float zpos;

    float yrot; // Y Rotation
    float walkbias = 0;
    float walkbiasangle = 0;
    float lookupdown = 0.0f;
    float z = 0.0f;

 

 

   //NEW


   // 读取资源数据
    public void setUp() {
        BufferedReader br = new BufferedReader(new InputStreamReader(
                LoadTxt.getFile("data/world.txt")));
        TRIANGLE triangle = new TRIANGLE();
        int vertexIndex = 0;
        try {
            String line = null;
            // 读完所有数据后循环终止
            while ((line = br.readLine()) != null) {
                // 以"/"字符开始或以空格开始的行跳过
                if (line.startsWith("/") || line.trim().length() <= 0) {
                    continue;
                }
                // //s表示 空格,回车,换行等空白符 ,+号表示一个或多个的意思
                String part[] = line.trim().split("//s+");
                float x = Float.valueOf(part[0]);
                float y = Float.valueOf(part[1]);
                float z = Float.valueOf(part[2]);
                float u = Float.valueOf(part[3]);
                float v = Float.valueOf(part[4]);

                // 不得不说下面的处理的很不错哦
                VERTEX vertex = new VERTEX(x, y, z, u, v);
                triangle.vertex[vertexIndex] = vertex;

                vertexIndex++;
                if (vertexIndex == 3) {
                    vertexIndex = 0;
                    sector.triangle.add(triangle);
                    triangle = new TRIANGLE();
                }
            }
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }

 

    // Texture用这种方法也不错,呵呵
    public void LoadTextures(GL10 gl) {
        // Create Nearest Filtered Texture
        IntBuffer textureBuffer = IntBuffer.allocate(3);
        gl.glGenTextures(1, texture, 0);
        gl.glBindTexture(GL10.GL_TEXTURE_2D, texture[0]);
        gl.glTexParameterx(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MIN_FILTER,
                GL10.GL_NEAREST);
        gl.glTexParameterx(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MAG_FILTER,
                GL10.GL_NEAREST);
        GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, LoadImage.bitmap, 0);

        texture[1] = textureBuffer.get(2);
        gl.glBindTexture(GL10.GL_TEXTURE_2D, texture[1]);
        gl.glTexParameterx(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MIN_FILTER,
                GL10.GL_LINEAR);
        gl.glTexParameterx(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MAG_FILTER,
                GL10.GL_LINEAR);
        GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, LoadImage.bitmap, 0);
    }

    @Override
    public void onDrawFrame(GL10 gl) {
        // 清除屏幕和深度缓存
        gl.glClear(GL10.GL_DEPTH_BUFFER_BIT | GL10.GL_COLOR_BUFFER_BIT);
        gl.glLoadIdentity(); // reset the view

        float xtrans = -xpos;
        float ztrans = -zpos;
        float ytrans = -walkbias - 0.25f;
        float sceneroty = 360.0f - yrot;

        FloatBuffer vertexPointer;
        FloatBuffer texCoordPointer;

        float[] vertex = new float[9];
        float[] coord = new float[6];

        ByteBuffer vertexByteBuffer = ByteBuffer
                .allocateDirect(vertex.length * 4);
        vertexByteBuffer.order(ByteOrder.nativeOrder());
        vertexPointer = vertexByteBuffer.asFloatBuffer();
        vertexPointer.put(vertex);
        vertexPointer.position(0);

        ByteBuffer texCoordByteBuffer = ByteBuffer
                .allocateDirect(coord.length * 4);
        texCoordByteBuffer.order(ByteOrder.nativeOrder());
        texCoordPointer = texCoordByteBuffer.asFloatBuffer();
        texCoordPointer.put(coord);
        texCoordPointer.position(0);

        gl.glVertexPointer(3, GL10.GL_FLOAT, 0, vertexPointer);
        gl.glTexCoordPointer(2, GL10.GL_FLOAT, 0, texCoordPointer);

        gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
        gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY);

        gl.glLoadIdentity();

        gl.glRotatef(lookupdown, 1.0f, 0.0f, 0.0f);
        gl.glRotatef(sceneroty, 0.0f, 1.0f, 0.0f);

        gl.glTranslatef(xtrans, ytrans, ztrans);

        gl.glBindTexture(GL10.GL_TEXTURE_2D, texture[1]);

        for (TRIANGLE triangle : sector.triangle) {
            vertexPointer.clear();
            texCoordPointer.clear();
            gl.glNormal3f(0.0f, 0.0f, 1.0f);
            for (int i = 0; i < 3; i++) {
                VERTEX vt = triangle.vertex[i];
                vertexPointer.put(vt.x);
                vertexPointer.put(vt.y);
                vertexPointer.put(vt.z);
                texCoordPointer.put(vt.u);
                texCoordPointer.put(vt.v);
            }
            gl.glDrawArrays(GL10.GL_TRIANGLES, 0, 4);
        }

        gl.glDisableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
        gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);

    }

    @Override
    public void onSurfaceChanged(GL10 gl, int width, int height) {
        gl.glViewport(0, 0, width, height);
        float ratio = (float) width / height;
        gl.glMatrixMode(GL10.GL_PROJECTION);
        gl.glLoadIdentity();
        gl.glFrustumf(-ratio, ratio, -1, 1, 1, 10);
        gl.glMatrixMode(GL10.GL_MODELVIEW);
        gl.glLoadIdentity();
    }

    @Override
    public void onSurfaceCreated(GL10 gl, EGLConfig arg1) {
        LoadTextures(gl);
        gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT, GL10.GL_FASTEST);
        gl.glClearColorx(0, 0, 0, 0);

        // 开启深度测试
        gl.glEnable(GL10.GL_DEPTH_TEST);
        gl.glDepthFunc(GL10.GL_LESS);
        gl.glShadeModel(GL10.GL_SMOOTH);

        // 开启纹理
        gl.glEnable(GL10.GL_TEXTURE_2D);

        // 开启混合
        gl.glBlendFunc(GL10.GL_SRC_ALPHA, GL10.GL_ONE);

        setUp();
    }

 

//NEW
    public boolean onKeyUp(int keyCode, KeyEvent event) {
        switch (keyCode) {
        case KeyEvent.KEYCODE_DPAD_LEFT:
            yrot -= 1.5f;
            break;
        case KeyEvent.KEYCODE_DPAD_RIGHT:
            yrot += 1.5f;
            break;
        case KeyEvent.KEYCODE_DPAD_UP:
            // 沿游戏者所在的X平面移动
            xpos -= (float) Math.sin(heading * piover180) * 0.05f;
            // 沿游戏者所在的Z平面移动
            zpos -= (float) Math.cos(heading * piover180) * 0.05f;
            if (walkbiasangle >= 359.0f)// 如果walkbiasangle大于359度
            {
                walkbiasangle = 0.0f;// 将 walkbiasangle 设为0
            } else {
                walkbiasangle += 10;// 如果 walkbiasangle < 359 ,则增加 10
            }
            // 使游戏者产生跳跃感
            walkbias = (float) Math.sin(walkbiasangle * piover180) / 20.0f;
            break;
        case KeyEvent.KEYCODE_DPAD_DOWN:
            // 沿游戏者所在的X平面移动
            xpos += (float) Math.sin(heading * piover180) * 0.05f;
            // 沿游戏者所在的Z平面移动
            zpos += (float) Math.cos(heading * piover180) * 0.05f;
            // 如果walkbiasangle小于1度
            if (walkbiasangle <= 1.0f) {
                walkbiasangle = 359.0f;// 使 walkbiasangle 等于 359
            } else {
                walkbiasangle -= 10;// 如果 walkbiasangle > 1 减去 10`
            }
            // 使游戏者产生跳跃感
            walkbias = (float) Math.sin(walkbiasangle * piover180) / 20.0f;
            break;
        }
        return false;
    }


}

 

 

 

 

效果图 :

 

 

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值