栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 前沿技术 > 大数据 > 大数据系统

[java] [OpenGL ES 3.2] 一群三角形

[java] [OpenGL ES 3.2] 一群三角形

源代码

Axis.java

package com.Diamond.gl02;

import android.opengl.GLES32;
import java.nio.FloatBuffer;
import com.Diamond.gl02.Program;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import android.renderscript.Float4;
import android.opengl.Matrix;
import android.renderscript.Matrix4f;

public class Axis {
    public FloatBuffer vfb;
	public GLES32 gl;
	public Matrix4f model;
	
	public Axis() {
		float[] ver = new float[]{
			-100,0,0,
			100,0,0,
			0,-100,0,
			0,100,0,
			0,0,-100,
			0,0,100
		};
		ByteBuffer vbb = ByteBuffer.allocateDirect(ver.length * 4);
		vbb.order(ByteOrder.nativeOrder());
		vfb = vbb.asFloatBuffer();
		vfb.put(ver);
		vfb.position(0);
		
		model = new Matrix4f();
		model.loadIdentity();
	}
	
	public void draw(Program program) {
		program.setUniform("u_model",model.getArray());
		gl.glEnableVertexAttribArray(0);
		gl.glVertexAttribPointer(0,3,gl.GL_FLOAT,false,0,vfb);
		program.setUniform("u_color",1,0,0,1);
		gl.glDrawArrays(gl.GL_LINES,0,2);
		program.setUniform("u_color",0,1,0,1);
		gl.glDrawArrays(gl.GL_LINES,2,2);
		program.setUniform("u_color",0,0,1,1);
		gl.glDrawArrays(gl.GL_LINES,4,2);
	}
}

Camera.java

package com.Diamond.gl02;

import android.opengl.Matrix;
import android.renderscript.Matrix4f;
import android.renderscript.Float3;

public class Camera {
	private Float3 mPosition;
	private Float3 mCenter;
	private Float3 mUp;
	private Matrix4f mProjection;
    
	public Camera(Float3 position,Float3 center,Float3 up) {
		mPosition = position;
		mCenter = center;
		mUp = up;
		mProjection = new Matrix4f();
	}
	
	public Camera setPosition(Float3 position) {
		mPosition = position;
		return this;
	}
	
	public Camera move(Float3 distance) {
		mPosition.x += distance.x;
		mPosition.y += distance.y;
		mPosition.z += distance.z;
		return this;
	}
	
	public Camera moveX(float distance) {
		mPosition.x += distance;
		return this;
	}
	
	public Camera moveY(float distance) {
		mPosition.y += distance;
		return this;
	}
	
	public Camera moveZ(float distance) {
		mPosition.z += distance;
		return this;
	}
	
	public Camera setCenter(Float3 center) {
		mCenter = center;
		return this;
	}
	
	public Camera setUp(Float3 up) {
		mUp = up;
		return this;
	}
	
	public Camera setPerspective(float fovy,float aspect,float near,float far) {
		mProjection.loadPerspective(fovy,aspect,near,far);
		return this;
	}
	
	public Camera setOrtho(float l,float r,float b,float t,float n,float f) {
		mProjection.loadOrtho(l,r,b,t,n,f);
		return this;
	}
	
	public float[] getProjectionMatrix() {
		return mProjection.getArray();
	}
	
	public float[] getViewMatrix() {
		float[] view = new float[16];
		Matrix.setLookAtM(
						view,0,
						mPosition.x,mPosition.y,mPosition.z,
						mCenter.x,mCenter.y,mCenter.z,
						mUp.x,mUp.y,mUp.z
						);
		return view;
	}
}

MainActivity.java

package com.Diamond.gl02;

import android.app.Activity;
import android.os.Bundle;
import com.Diamond.gl02.MySurfaceView;
import android.widget.RelativeLayout;
import android.view.Menu;
import android.view.MenuItem;
import android.renderscript.Float3;
import android.view.View;
import android.view.MotionEvent;
import android.util.Log;
import android.content.pm.ActivityInfo;
import android.view.WindowManager;
import android.view.Window;

public class MainActivity extends Activity {
    public MySurfaceView surfaceView;
	public RelativeLayout relativeLayout1;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
		relativeLayout1 = (RelativeLayout)findViewById(R.id.activitymainRelativeLayout1);

        surfaceView = new MySurfaceView(this);
        surfaceView.requestFocus();
        surfaceView.setFocusableInTouchMode(true);
		surfaceView.setClickable(true);

		relativeLayout1.addView(surfaceView);

		setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
		getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
    }

    @Override
    protected void onResume() {
        super.onResume();
        surfaceView.onResume();
    }

    @Override
    protected void onPause() {
        super.onPause();
        surfaceView.onPause();
    }

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		menu.add(0, 0, 0, "前进");
		menu.add(0, 1, 0, "后退");
		menu.add(0, 2, 0, "左移");
		menu.add(0, 3, 0, "右移");
		menu.add(0, 4, 0, "向上");
		menu.add(0, 5, 0, "向下");

		menu.add(0, 6, 0, "更新三角形");

		return super.onCreateOptionsMenu(menu);
	}

	@Override
	public boolean onOptionsItemSelected(MenuItem item) {
		switch (item.getItemId()) {
			case 0:
				surfaceView.renderer.camera.moveX(0.5f);
				break;
			case 1:
				surfaceView.renderer.camera.moveX(-0.5f);
				break;
			case 2:
				surfaceView.renderer.camera.moveZ(0.5f);
				break;
			case 3:
				surfaceView.renderer.camera.moveZ(-0.5f);
				break;
			case 4:
				surfaceView.renderer.camera.moveY(0.5f);
				break;
			case 5:
				surfaceView.renderer.camera.moveY(-0.5f);
				break;
			case 6:
				surfaceView.renderer.initTriangles();
				break;
		}
		return super.onOptionsItemSelected(item);
	}
} 

MySurfaceView.java

package com.Diamond.gl02;

import android.opengl.*;
import android.opengl.GLES32;
import android.opengl.GLSurfaceView;
import android.content.Context;
import javax.microedition.khronos.opengles.GL10;
import javax.microedition.khronos.egl.EGLConfig;
import com.Diamond.gl02.Triangle;
import android.renderscript.Float3;
import android.content.res.Resources;
import com.Diamond.gl02.Camera;
import android.renderscript.Float4;
import android.view.MotionEvent;
import android.util.Log;
import com.Diamond.gl02.Axis;

public class MySurfaceView extends GLSurfaceView {
    public class MyRenderer implements GLSurfaceView.Renderer {
		public Triangle[] triangles;
		public Resources resources;
		public GLES32 gl;
		public Camera camera;
		public Program program;
		public float lastX,lastY,x,y;
		public double yaw;
		public Axis axis;

		public MyRenderer() {
			x = 0;
			y = 0;
			yaw = 0;
		}

        @Override
        public void onSurfaceCreated(GL10 p1, EGLConfig p2) {
			String vString = Program.loadFromAssetsFile("v.vert", getResources());
			String fString = Program.loadFromAssetsFile("f.frag", getResources());
			program = new Program(vString, fString);

			camera = new Camera(new Float3(1.0f, 1.0f, 1.0f), new Float3(0, 0, 0), new Float3(0, 1, 0));
			camera.setPerspective(120.0f, 2.0f, 0.1f, 100.0f);
			
			axis = new Axis();

			gl.glEnable(gl.GL_DEPTH_TEST);
			
			initTriangles();
		}
		
		public void initTriangles() {
            triangles = new Triangle[1000];
			for(int i = 0;i < triangles.length;i++) {
				float x = (float)Math.random() * 10 - 5;
				float y = (float)Math.random() * 10 - 5;
				float z = (float)Math.random() * 10 - 5;
				
				float r = (float)Math.random();
				float g = (float)Math.random();
				float b = (float)Math.random();
				
				float rx = (float)Math.random() * 360;
				float ry = (float)Math.random() * 360;
				float rz = (float)Math.random() * 360;
				
				Triangle t = new Triangle(new Float4(r,g,b,1));
				t.model.translate(x,y,z);
				t.model.scale(0.5f,0.5f,0.5f);
				t.model.rotate(rx,1,0,0);
				t.model.rotate(ry,0,1,0);
				t.model.rotate(rz,0,0,1);
				
				triangles[i] = t;
			}
        }

        @Override
        public void onSurfaceChanged(GL10 p1, int p2, int p3) {

        }

        @Override
        public void onDrawframe(GL10 p1) {
			gl.glClear(gl.GL_COLOR_BUFFER_BIT | gl.GL_DEPTH_BUFFER_BIT);
			gl.glClearColor(0.1f, 0.1f, 0.1f, 1.0f);
			program.useProgram();
			program.setUniform("u_projection",camera.getProjectionMatrix());
			program.setUniform("u_view",camera.getViewMatrix());
			axis.draw(program);
            for(Triangle i : triangles) {
				i.draw(program);
			}
        }
    }

    public MyRenderer renderer;
    public MySurfaceView(Context context) {
        super(context);
        this.setEGLContextClientVersion(3);
        renderer = new MyRenderer();
        this.setRenderer(renderer);
        this.setRenderMode(GLSurfaceView.RENDERMODE_CONTINUOUSLY);
    }
}

Program.java

package com.Diamond.gl02;

import android.opengl.GLES32;
import android.util.Log;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStreamReader;
import java.io.IOException;
import android.renderscript.Float2;
import android.renderscript.Float3;
import android.renderscript.Float4;
import java.io.InputStream;
import android.content.res.Resources;
import java.io.ByteArrayOutputStream;

public class Program {
    public class Shader {
        private int program;
        private int type;
        public final String tag = "failed to load shader";

        private void loadShader(String resource) {
            program = GLES32.glCreateShader(type);
            if (program == 0) {
                Log.e(tag, "shader program type:" + type);
                Log.e(tag, "error:" + GLES32.glGetError());
                return;
            }
            GLES32.glShaderSource(program, resource);
            GLES32.glCompileShader(program);
            int[] compiled = new int[1];
            GLES32.glGetShaderiv(program, GLES32.GL_COMPILE_STATUS, compiled, 0);
            if (compiled[0] == 0) {
                Log.e(tag, GLES32.glGetShaderInfoLog(program));
                GLES32.glDeleteShader(program);
                program = 0;
            }
        }

        public Shader(int programType) {
            program = 0;
            type = programType;
        }
        public Shader(int programType, String resource) {
            type = programType;
            loadShader(resource);
        }

        public int getProgram() {
            return program;
        }
    }

    private Shader vShader;
    private Shader fShader;
    private Shader gShader;
    private int program;
    private final String tag = "failed to create program";

    private void linkProgram() {
        int vp = vShader.getProgram();
        int fp = fShader.getProgram();
        int gp = gShader.getProgram();
        program = GLES32.glCreateProgram();
        if (program == 0) {
            Log.e(tag, "" + GLES32.glGetError());
            return;
        }
        GLES32.glAttachShader(program, vp);
        GLES32.glAttachShader(program, fp);
        if (gp != 0) {
            GLES32.glAttachShader(program, gp);
        }
        GLES32.gllinkProgram(program);
        int[] linkStatus = new int[1];
        GLES32.glGetProgramiv(program, GLES32.GL_link_STATUS, linkStatus, 0);
        if (linkStatus[0] == GLES32.GL_FALSE) {
            Log.e(tag, GLES32.glGetProgramInfoLog(program));
            GLES32.glDeleteProgram(program);
            program = 0;
        }
    }

    public Program() {
        vShader = new Shader(GLES32.GL_VERTEX_SHADER);
        fShader = new Shader(GLES32.GL_FRAGMENT_SHADER);
        gShader = new Shader(GLES32.GL_GEOMETRY_SHADER);
        linkProgram();
    }
    public Program(String vResource, String fResource) {
        vShader = new Shader(GLES32.GL_VERTEX_SHADER, vResource);
        fShader = new Shader(GLES32.GL_FRAGMENT_SHADER, fResource);
        gShader = new Shader(GLES32.GL_GEOMETRY_SHADER);
        linkProgram();
    }
    public Program(String vResource, String fResource, String gResource) {
        vShader = new Shader(GLES32.GL_VERTEX_SHADER, vResource);
        fShader = new Shader(GLES32.GL_FRAGMENT_SHADER, fResource);
        gShader = new Shader(GLES32.GL_GEOMETRY_SHADER, gResource);
        linkProgram();
    }

    public int getProgram() {
        return program;
    }
    public void useProgram() {
        GLES32.glUseProgram(program);
    }

	public static String loadFromAssetsFile(String fname, Resources resources) {
		String result=null;    	
		try {
			InputStream in=resources.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;
	}

    public int getUniformLocation(String name) {
        return GLES32.glGetUniformLocation(program, name);
    }
    public void setUniform(String name, float value) {
        int location = getUniformLocation(name);
        GLES32.glUniform1f(location, value);
    }
    public void setUniform(String name, int value) {
        int location = getUniformLocation(name);
        GLES32.glUniform1i(location, value);
    }
    public void setUniform(String name, float value1, float value2) {
        int location = getUniformLocation(name);
        GLES32.glUniform2f(location, value1, value2);
    }
    public void setUniform(String name, Float2 value) {
        setUniform(name, value.x, value.y);
    }
    public void setUniform(String name, float value1, float value2, float value3) {
        int location = getUniformLocation(name);
        GLES32.glUniform3f(location, value1, value2, value3);
    }
    public void setUniform(String name, Float3 value) {
        setUniform(name, value.x, value.y, value.z);
    }
    public void setUniform(String name, float value1, float value2, float value3, float value4) {
        int location = getUniformLocation(name);
        GLES32.glUniform4f(location, value1, value2, value3, value4);
    }
    public void setUniform(String name, Float4 value) {
        setUniform(name, value.x, value.y, value.z, value.w);
    }
    public void setUniform(String name, float[] matrix) {
        int location = getUniformLocation(name);
        GLES32.glUniformMatrix4fv(location, 1, false, matrix, 0);
    }
}

Triangle.java

package com.Diamond.gl02;

import com.Diamond.gl02.Program;
import android.opengl.GLES32;
import android.content.res.Resources;
import java.nio.FloatBuffer;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import com.Diamond.gl02.Camera;
import android.renderscript.Matrix4f;
import android.renderscript.Float3;
import android.renderscript.Float4;

public class Triangle{
	public FloatBuffer vfb;
	public GLES32 gl;
	public Matrix4f model;
	public Float4 color;
	
	public Triangle(Float4 c) {
		color = c;
		
		float[] ver = new float[]{
			0.0f,0.5f,0.0f,
			-0.5f,-0.5f,0.0f,
			0.5f,-0.5f,0.0f
		};
		ByteBuffer vbb = ByteBuffer.allocateDirect(ver.length * 4);
		vbb.order(ByteOrder.nativeOrder());
		vfb = vbb.asFloatBuffer();
		vfb.put(ver);
		vfb.position(0);
		
		model = new Matrix4f();
	}
	
	public void draw(Program program) {
		program.setUniform("u_model",model.getArray());
		gl.glEnableVertexAttribArray(0);
		gl.glVertexAttribPointer(0,3,gl.GL_FLOAT,false,3 * 4,vfb);
		program.setUniform("u_color",color);
		gl.glDrawArrays(gl.GL_TRIANGLES,0,3);
	}
}

v.vert

#version 320 es
layout(location=0)in vec3 a_position;
uniform mat4 u_projection;
uniform mat4 u_view;
uniform mat4 u_model;
void main()
{
gl_Position = u_projection * u_view * u_model * vec4(a_position,1.0f);
}

f.frag

#version 320 es
precision mediump float;
uniform vec4 u_color;
out vec4 o_color;
void main()
{
o_color = u_color;
}

效果

如果没有问题,最后的结果应该如图所示


转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/707304.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号