OpenGL ES2.0粒子系统(附有源码)



刚学OpenGL 2个多星期,也算是入门了吧
在看了老外写的书 OpenGL ES 2 for Android A Quick - Start Guide.pdf
后,由于这本书上给的代码不够全, 自己功力太浅,对于一些了解有点疑惑,
费了差不多两天才调出想要的结果,下面就分享一下我的经历,若有问题,希望大家多多交流

本代码中包含的内容还是比较多的,使用OpenGL ES2.0编写,包含有顶点 shader和片段shader,
还包含了VBO(vertex  buffer object),这里是我当时最疑惑的地方,因为对VBO的用法不熟悉,上网搜索了导致出不来结果, 后来还是在一个外国网站上找到答案的。

粒子系统是通过将时间作为一个变量绑定到绘制的点的位置信息中,由于时间是在流动的,因此粒子也会跟着在移动;从而就形成了粒子流,这里比较难理解
不废话了,直接上代码吧;

本程序代码结构:


先看MainActivity.java

package com.cxy.particles;
import android.app.Activity;
import android.opengl.GLSurfaceView;
import android.os.Bundle;
public class MainActivity extends Activity {
    GLSurfaceView glSurfaceView;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        glSurfaceView = new GLSurfaceView(this);
        // 设置OpenGLES版本为2.0
        glSurfaceView.setEGLContextClientVersion(2);
        // 设置渲染器 渲染模式
        MyRenderer mRenderer = new MyRenderer(this,glSurfaceView);
        glSurfaceView.setRenderer(mRenderer);
        glSurfaceView.setRenderMode(GLSurfaceView.RENDERMODE_CONTINUOUSLY);
        // 显示渲染内容
        setContentView(glSurfaceView);
    }
}  


最重要的渲染的文件MyRenderer.java


package com.cxy.particles;
import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10;
import android.content.Context;
import android.graphics.Color;
import android.opengl.GLES20;
import android.opengl.GLSurfaceView;
import android.opengl.Matrix;
public class MyRenderer implements GLSurfaceView.Renderer {
    
    GLSurfaceView glView;    
    private Context context;
    
    //视图矩阵
    private final float[] projectionMatrix=new float[16];
    private final float[] viewMatrix=new float[16];
    private final float[] viewProjectionMatrix=new float[16];
    
    private ParticleShaderProgram particleProgram;
    private ParticleSystem particleSystem;
    private ParticleShooter redParticleShooter;
    private ParticleShooter greenParticleShooter;
    private ParticleShooter blueParticleShooter;
    private long globalStartTime;
    //private float globalStartTime;
    
    public MyRenderer(Context context,GLSurfaceView view){
        //保存上下文,个GLSurfaceView;  
        this.context=context;
        this.glView = view;
    }
      
    @Override
    public void onSurfaceCreated(GL10 gl, EGLConfig config) {
        //设置屏幕背景色      
        GLES20.glClearColor(0.0f,0.0f,0.0f,0.0f);
        //获取GLSL脚本语言编译好后的programID
        particleProgram=new ParticleShaderProgram(context,glView);
        //获取粒子系统的实例,初始化粒子系统包含10000个粒子
        particleSystem=new ParticleSystem(10000);
        //获取系统时间
        globalStartTime=System.nanoTime();
        //globalStartTime = System.nanoTime()/1000000000f;
        
        //设置粒子发射的方向,Y轴向上
        final Vector3 particleDirection=new Vector3(0f,0.5f,0f);
        //新建粒子发射器(红色粒子),获取实例
        redParticleShooter=new ParticleShooter(
                new Point3(-1f,0f,0f),
                particleDirection,
                Color.rgb(255,50,5));
        //新建粒子发射器(绿色粒子),获取实例
        greenParticleShooter=new ParticleShooter(
                new Point3(0f,0f,0f),
                particleDirection,
                Color.rgb(25,255,25));
        //新建粒子发射器(蓝色粒子),获取实例
        blueParticleShooter=new ParticleShooter(
                new Point3(1f,0f,0f),
                particleDirection,
                Color.rgb(5,50,255));
    }
    
    @Override
    public void onSurfaceChanged(GL10 gl, int width, int height) {
        //设置当前的视点适应新的尺寸
        GLES20.glViewport(0,0,width,height);
        Matrix.perspectiveM(
                projectionMatrix, 
                0, 
                45,
                (float)width/(float)height,
                1f,
                10f);
        Matrix.setIdentityM(viewMatrix,0);
        Matrix.translateM(viewMatrix,0,0f,-1.5f,-5f);
        //设置最终的视点
        Matrix.multiplyMM(
                viewProjectionMatrix,
                0,
                projectionMatrix,
                0,
                viewMatrix,
                0);
    }
    
    @Override
    public void onDrawFrame(GL10 gl) {
        //清除位缓存
        GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT);
        float currentTime=(System.nanoTime()-globalStartTime)/1000000000f;
        //float currentTime=(System.nanoTime()/1000000000f);
        //Log.d("cxy", "CurrentTime = "+currentTime);
        
        /*为粒子发射器添加粒子*/
        redParticleShooter.addParticles(particleSystem,currentTime,5);
        greenParticleShooter.addParticles(particleSystem,currentTime,5);
        blueParticleShooter.addParticles(particleSystem,currentTime,5);
        
        /*redParticleShooter.addParticles(particleSystem,globalStartTime,5);
        greenParticleShooter.addParticles(particleSystem,globalStartTime,5);
        blueParticleShooter.addParticles(particleSystem,globalStartTime,5);*/
    
        //使用着色器绘制粒子,
        particleProgram.useProgram();
        //这是
        particleProgram.setUniforms(viewProjectionMatrix,currentTime);
        
        /**必须在USE progrem之后,才能进行数据绑定,即操作glVertexAttribPointer之类的函数
         * bindData()将所有的数据:粒子顶点数据、颜色数据、方向数据、时间捆绑在一个VBO中,然后
         * 通过这个VBO绘制的,
         **/
        particleSystem.bindData(particleProgram);
        
        //绘制粒子
        particleSystem.draw(particleProgram);
    }
}

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值