android opengl es 3d世界

OpenGL实现三维迷宫游戏(一) 《计算机图形学》这门课的第二个实验,觉得还挺有意思的…实验要求设计一个OpenGL程序,创建一个三维迷宫,支持替身通过一定交互手段在迷宫中漫游,基本功能包括: - 迷宫应当至少包含10 * 10 个Cell,不能过于简单,下图给出一种示例。 - 读取给定的替身模型,加载到场景中。 - 键盘方向键控制替身转向与漫游。 - 有碰撞检测,替身不应当穿墙。 - 支持切换第一视角和第三视角 阅读详情

额,有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;
    }


}

 

 

 

 

效果图 :

 

 

 

Android 3D游戏开发(基础篇)——Opengl ES游戏引擎实现(送源码) Android 3D游戏开发(基础篇)——Opengl ES游戏引擎实现(送源码)课程描述:     本教程可以带领大家从一个普通的Android应用开发者进入3D应用的世界,从3D应用开发基础知识开始,完成受众多手机用户所喜爱的3D应用的开发。定价:224元(1年有效) 阅读详情

相关推荐

Android OpenGL ES 开发教程 14 三维坐标系及坐标变换初步

Android OpenGL ES 开发教程 14 三维坐标系及坐标变换初步

bcghgfr的博客 237

游戏设计之基于高程图的三维地形绘制

2015年完成的游戏设计课程大型实验论文(基础应用) —— 引用请联系博主 一、概述 地形绘制是室外三维游戏中必须面对的问题。三维真实感地形是虚拟场景中的基础部分,利用Visual C++,以通用的标准三维图形函数库OpenGL为工具,通过在位图的灰度值与地形高程数据之间建立相应的映射关系,建立标准的地形高程数据组,并依托OpenGL平台快速建立生成三维网格地形,然后经过纹理贴图形成真实感...

Shang1031 3565

android 用OPENGL ES 实现投影效果(正交投影与透视投影)

正交投影:          在OPENGL ES中只支持正交投影与透视投影,正交投影是平行投影的一种,特点是和观察者的视线是平行的,不会产生真               实世界中远大近小的的透视效果。在此做个假设:          I与Z是一个分别具有二阶矩的 n维和m唯的随机向量。如果存在一个与I同纬的随机向量“X;”,如果满足下列三个条件则将“X;”称             为 是

刘国栋的博客 4692

Android OpenGL ES 2.0 屏幕坐标和3D世界坐标转换

Android OpenGL ES 2.0 屏幕坐标和3D世界坐标转换 本文转载自: https://blog.youkuaiyun.com/u012943767/article/details/51122785 背景 由于项目中需要用到屏幕坐标和3d坐标相互转换的功能。经过我查询大量资料,发现很多文章都只是说明了OpenGL的坐标系统和坐标变换的过程。并没有实现转换坐标的代码示例。介绍坐标...

weixin_42914285的博客 1072

用腾讯混元3D-Lite模型给商品做3D展示:安卓手机扫描生成教程

本文详细介绍了如何利用腾讯混元3D世界模型Lite版,在搭载骁龙8 Gen3的安卓手机上,通过摄像头扫描商品并实时生成可用于电商展示的3D模型。教程涵盖了从模型获取、转换到安卓应用集成的全流程,并提供了针对移动端部署的优化技巧,为中小商家提供了一套低成本、高效率的3D内容生成解决方案。

weixin_29051193的博客 640

Android游戏开发实战:3D游戏案例教程

开发一款引人入胜的3D游戏不仅需要扎实的编程知识,还需要对图形渲染和物理模拟等方面有深入的了解。本篇博客将带你进入Android游戏开发的精彩世界,通过一个完整的3D游戏案例教程,详细讲解游戏开发的各个方面,并提供相应的代码示例。通过本篇博客的指导,我们完成了一个简单的Android 3D游戏案例教程。在这个案例中,我们学习了如何集成OpenGL ES、绘制3D物体、添加触摸控制、添加纹理和光照效果,以及简单的物理模拟和游戏逻辑。在这个步骤中,我们将绘制第一个3D物体,以了解OpenGL ES的基本使用。

2201_76125261的博客 914

探索Android-3D-Layout:为你的应用增添立体动感

探索Android-3D-Layout:为你的应用增添立体动感 项目介绍 Android-3D-Layout 是一个正在开发中的开源项目,旨在为Android开发者提供一种全新的UI布局体验。通过该库,开发者可以轻松实现3D效果的布局,为应用界面增添立体感和动态效果。无论是简单的旋转动画,还是复杂的触摸交互,Android-3D-Layout 都能帮助你实现。 项目技术分析 Android-3D-...

gitblog_00218的博客 1084

C#实现简单地形生成器实战:高度图到3D地形转换

本文还有配套的精品资源,点击获取 简介:在游戏开发中,地形生成是关键任务之一,负责创造游戏世界的多样性和一致性。本文将指导如何利用C#和高度图(Heighmap)来创建一个简单的地形生成器。首先,介绍高度图概念及其在3D图形中的应用。然后,说明如何在C#中加载和解析高度图数据,以及将这些数据转换为3D网格的过程。接着,探讨在地形生成过程中应用平滑处理和噪声函数,以增加地形的...

weixin_42153793的博客 2071

android opengl 自定义,Android使用OpenGL ES显示图像

Android框架提供了大量的标准工具,用来创建吸引人的,功能丰富的图形界面。然而,如果我们希望应用在屏幕上所绘制的内容进行更多的控制,或者正在尝试建立三维图像,那么我们就需要一个不同的工具了。由Android框架提供的OpenGL ES接口给予我们一组可以显示高级动画和图形的工具集,它的功能仅仅受限于我们自身的想象力。同时,在许多Android设备上搭载的图形处理单元(GPU)都能为其提供GPU...

weixin_39621695的博客 228

OpenGL 3D地形渲染实战源代码解析

本文还有配套的精品资源,点击获取 简介:OpenGL是一种用于3D图形编程的接口,常用于游戏开发和可视化。提供的源代码展示了如何使用OpenGL技术进行复杂3D场景的地形渲染,涵盖了从高度图读取到地形构建的全过程。源代码中可能包含了数据加载、顶点与片段着色器的应用、地形细分、纹理贴图、光照计算、性能优化以及渲染技术等多个方面。此外,还可能提供交互功能,让用户能够与渲染的地形...

weixin_42388898的博客 1376

OpenGL毕业设计:实现分形基础的山地地形绘制

OpenGL(Open Graphics Library)是一个跨语言、跨平台的应用程序编程接口(API),用于渲染2D和3D矢量图形。由于其开放性、稳定性和强大的图形处理能力,OpenGL成为游戏、虚拟现实和可视化等领域的重要工具。它是独立于硬件的,这意味着同一段代码可以在不同类型的图形硬件上运行。分形理论是计算机图形学中的一种重要理论,它帮助我们生成具有复杂结构的自然景观。下面详细介绍分形理论的基础知识及其在计算机图形学中的应用。

weixin_28746457的博客 839

Android 3D 游戏学习笔记(1)-openGL基础

小满(billman)个人原创,欢迎转载,转载请注明地址,小满(billman)的专栏地址http://blog.youkuaiyun.com/bill_man 1.openGLES openGLES(OpenGLforEmbeddedSystem)是专为嵌入式设备设计的OpenGL的一个子集,也加入了一些扩展功能,可以达到移动设备降低功耗的目的。 2.多边形和三角形 3...

weixin_30530339的博客 61

Android端摩天大楼3D建造游戏源码,含完整工程结构与可运行APK

一套开箱即用的Android平台3D建造类游戏源码,主打摩天大楼从地基到封顶的全流程搭建体验。项目采用标准Eclipse兼容结构,包含src/wyf下的Java逻辑代码、res目录下分密度drawable资源(ldpi/hdpi/mdpi)、layout界面布局、values字符串与样式定义、raw中预留音效或关卡数据位,以及assets扩展资源入口。AndroidManifest.xml已配置基础权限与启动Activity,default.properties、.classpath和.project支持直

x2y3z4a5b的博客 243

Android OpenGL ES 学习(九) – 坐标系统和。实现3D效果

为了将坐标从一个坐标系变换到另一个坐标系,我们需要用到几个变换矩阵,最重要的几个分别是模型(Model)、观察(View)、投影(Projection)三个矩阵。我们的顶点坐标起始于局部空间(Local Space),在这里它称为局部坐标(Local Coordinate),它在之后会变为世界坐标(World Coordinate)观察坐标(View Coordinate),裁剪坐标(Clip Coordinate),并最后以屏幕坐标(Screen Coordinate)的形式结束。

gowcage的博客 550

opengles绘制灰度地形图

使用opengles绘制灰度地形图

LabVIEW多设备采集实战:1个程序同时控制3个RS485 Modbus仪表

本文详细介绍了如何使用LabVIEW实现多设备RS485 Modbus同步采集,涵盖硬件架构设计、多线程通信框架搭建、数据帧解析技巧及性能优化策略。通过实际项目案例,展示如何解决端口冲突、数据解析错误等工业自动化常见问题,提升采集系统实时性与可靠性。

qsc901234的博客 298

OpenGL Android课程五:介绍混合(Blending)

翻译文 原文标题:Android Lesson Five: An Introduction to Blending 原文链接:www.learnopengles.com/android-les… 介绍混合(Blending) 这节课,我们来学习混合(blending)在OpenGL中的基本使用。我们来看看如何打开或关闭混合,怎样设置不同的混合模式,以及不同的混合模式如何模...

weixin_34301132的博客 903

模板匹配加速之金字塔分层搜索

图像金字塔是一种多分辨率图像表示方法,它通过一系列逐渐缩小或放大的图像来表示原始图像的不同尺度。高斯金字塔(Gaussian Pyramid):通过不断下采样(降采样)生成更小的图像。拉普拉斯金字塔(Laplacian Pyramid):通过高斯金字塔和差分操作生成一组残差图像。在模板匹配中,我们主要使用高斯金字塔来实现多尺度匹配。金字塔灰度模板匹配通过多尺度搜索策略,在保持较高准确率的同时显著提升匹配速度,尤其适用于:高分辨率图像处理实时检测系统移动端设备等资源受限场景。

weixin_44969144的博客 1732

用腾讯混元3D世界模型Lite版快速搭建虚拟展厅:Android手机端完整教程

本文提供了一份详尽的Android端教程,指导开发者利用腾讯混元3D世界模型Lite版快速搭建虚拟展厅。教程涵盖从环境配置、模型转换与量化,到移动端集成、OpenGL ES渲染及深度性能调优的全流程,旨在帮助开发者在骁龙8 Gen3等设备上实现轻量、高效的本地部署与3D场景生成。

red88的博客 1188

【硬件开源实战】STM32G070RBT6开发板从设计到避坑全解析

本文全面解析了STM32G070RBT6开发板从硬件设计到避坑的实战经验。详细介绍了电源设计、时钟电路、PCB布局等关键环节,分享了成本控制、焊接测试、软件开发和外设驱动的实用技巧,帮助开发者高效完成项目开发。

weixin_26897585的博客 235

20240128 C#与SCPI协议实战:轻量级仪器控制库ScpiNet应用指南

本文详细介绍了轻量级C#库ScpiNet在仪器控制中的应用。相较于传统的NI-VISA,ScpiNet无需安装庞大运行时,通过纯C#实现直接与USB或以太网设备通信,支持跨厂商SCPI仪器。文章提供了从快速连接到实战封装、错误处理的完整指南,帮助开发者构建简洁高效的自动化测试系统。

h9j8k7l6m5n的博客 546
上一篇: android opengl es 七彩星星效果
下一篇: android opengl es 飘动的flag
评论 4
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值