open glHelloWorld之旋转的三角形(android)
来源:互联网 发布:淘宝图库 编辑:程序博客网 时间:2024/06/07 23:52
这两天在看open GL相关的东西,很多人都感觉有点高深莫测,包括自己对他也有些敬畏了。准备花一点时间,好好研究下。
就当是Hello World,上代码,大家来看看,其实有很多自己目前也不是太懂,先上代码分享下,如果大家有什么意见和建议,也记得给我评论和分享下哈...
下面代码是基于android的,不是Unity,也不是C++,笔者技术比较偏于android,故,希望大家不要介意哈,其实应该都差不多吧~
运行后效果描述:
这是动态图,沿z轴正方向旋转。
代码一(FirstGLActivity):
public class FirstGLActivity extends Activity { MyTDView mView; public void onCreate(Bundle savedInstanceState){ super.onCreate(savedInstanceState); setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT); mView = new MyTDView(this); mView.requestFocus(); mView.setFocusableInTouchMode(true); setContentView(mView); } public void onResume(){ super.onResume(); mView.onResume(); } public void onPause(){ super.onPause(); mView.onPause(); }}
package com.clark.gldemo;import android.content.Context;import android.opengl.GLES20;import android.opengl.GLSurfaceView;import android.opengl.Matrix;import com.clark.matrix.Triangle;import javax.microedition.khronos.egl.EGLConfig;import javax.microedition.khronos.opengles.GL10;public class MyTDView extends GLSurfaceView { //每次三角形旋转的角度 final float ANGLE_SPAN = 0.375f; //自定义线程类RotateThread的引用 RotateThread rotateThread; //自定义渲染器的引用 SceneRenderer mRenderer; private class SceneRenderer implements GLSurfaceView.Renderer{ Triangle tie;//声明Triangle的引用 @Override public void onSurfaceCreated(GL10 gl10, EGLConfig eglConfig) { GLES20.glClearColor(0,0,0,1.0f);//设置屏幕背景色 tie = new Triangle(MyTDView.this);//创建Triangle类的对象 GLES20.glEnable(GLES20.GL_DEPTH_TEST); rotateThread = new RotateThread();//创建RotateThread对象 rotateThread.start();//开启线程 } @Override public void onSurfaceChanged(GL10 gl10, int width, int height) { GLES20.glViewport(0,0,width,height);//设置视口 float ratio = (float) width/height;//计算屏幕的宽度和高度比例 Matrix.frustumM(Triangle.mProjMatrix,0,-ratio,ratio,-1,1,1,10);//设置透视投影 Matrix.setLookAtM(Triangle.mVMatrix,0,0,0,3,0f,0f,0f,0f,1.0f,0.0f);//设置摄像机 } @Override public void onDrawFrame(GL10 gl10) { GLES20.glClear(GLES20.GL_DEPTH_BUFFER_BIT| GLES20.GL_COLOR_BUFFER_BIT); tie.drawSelf();//通过Triangle的对象调用drawSelf绘制三角形 } } public MyTDView(Context context) { super(context); this.setEGLContextClientVersion(2);//使用open GL ES2.0需要该设置该值为2 mRenderer = new SceneRenderer();//创建SceneRenderer类的对象 this.setRenderer(mRenderer);//设置渲染器 this.setRenderMode(GLSurfaceView.RENDERMODE_CONTINUOUSLY); } /** * 自定义内部类线程 */ public class RotateThread extends Thread{ public boolean flag = true;//设置循环标志位 public void run(){ while(flag){ mRenderer.tie.xAngle = mRenderer.tie.xAngle + ANGLE_SPAN; try { Thread.sleep(20); } catch (InterruptedException e) { e.printStackTrace(); } } } }}
package com.clark.matrix;import java.nio.ByteBuffer;import java.nio.ByteOrder;import java.nio.FloatBuffer;import android.opengl.GLES20;import android.opengl.Matrix;import com.clark.gldemo.MyTDView;import com.clark.utils.ShadeUtil;//三角形public class Triangle{ public static float[] mProjMatrix = new float[16];//4x4矩阵 投影用 public static float[] mVMatrix = new float[16];//摄像机位置朝向9参数矩阵 public static float[] mMVPMatrix;//最后起作用的总变换矩阵 int mProgram;//自定义渲染管线程序id int muMVPMatrixHandle;//总变换矩阵引用id int maPositionHandle; //顶点位置属性引用id int maColorHandle; //顶点颜色属性引用id String mVertexShader;//顶点着色器 String mFragmentShader;//片元着色器 static float[] mMMatrix = new float[16];//具体物体的移动旋转矩阵,旋转、平移 FloatBuffer mVertexBuffer;//顶点坐标数据缓冲 FloatBuffer mColorBuffer;//顶点着色数据缓冲 int vCount=0; public float xAngle=0;//绕x轴旋转的角度 public Triangle(MyTDView mv) { //初始化顶点坐标与着色数据 initVertexData(); //初始化shader initShader(mv); } public void initVertexData() { //顶点坐标数据的初始化 vCount=3; final float UNIT_SIZE=0.2f; float vertices[]=new float[] { -4*UNIT_SIZE,0, 0,0,-4*UNIT_SIZE, 0,4*UNIT_SIZE,0,0 }; ByteBuffer vbb = ByteBuffer.allocateDirect(vertices.length*4); vbb.order(ByteOrder.nativeOrder()); mVertexBuffer = vbb.asFloatBuffer(); mVertexBuffer.put(vertices); mVertexBuffer.position(0); float colors[]=new float[]{ 1,1,1,0, 0,0,1,0, 0,1,0,0 }; ByteBuffer cbb = ByteBuffer.allocateDirect(colors.length*4); cbb.order(ByteOrder.nativeOrder()); mColorBuffer = cbb.asFloatBuffer(); mColorBuffer.put(colors); mColorBuffer.position(0); } //初始化shader public void initShader(MyTDView mv){ //加载顶点着色器的脚本内容 mVertexShader=ShadeUtil.loadFromAssetsFile("vertex.sh", mv.getResources()); //加载片元着色器的脚本内容 mFragmentShader= ShadeUtil.loadFromAssetsFile("frag.sh", mv.getResources()); //基于顶点着色器与片元着色器创建程序 mProgram = ShadeUtil.createProgram(mVertexShader, mFragmentShader); //获取程序中顶点位置属性引用id maPositionHandle = GLES20.glGetAttribLocation(mProgram, "aPosition"); //获取程序中顶点颜色属性引用id maColorHandle= GLES20.glGetAttribLocation(mProgram, "aColor"); //获取程序中总变换矩阵引用id muMVPMatrixHandle = GLES20.glGetUniformLocation(mProgram, "uMVPMatrix"); } public void drawSelf() { //制定使用某套shader程序 GLES20.glUseProgram(mProgram); //初始化变换矩阵 Matrix.setRotateM(mMMatrix,0,0,0,1,0); //设置沿Z轴正向位移1 Matrix.translateM(mMMatrix,0,0,0,1); //设置绕x轴旋转 Matrix.rotateM(mMMatrix,0,xAngle,1,0,0); // GLES20.glUniformMatrix4fv(muMVPMatrixHandle, 1, false, Triangle.getFinalMatrix(mMMatrix), 0); //为画笔指定顶点位置数据 GLES20.glVertexAttribPointer( maPositionHandle, 3, GLES20.GL_FLOAT, false, 3*4, mVertexBuffer ); GLES20.glVertexAttribPointer ( maColorHandle, 4, GLES20.GL_FLOAT, false, 4*4, mColorBuffer ); //允许顶点位置数据数组 GLES20.glEnableVertexAttribArray(maPositionHandle); GLES20.glEnableVertexAttribArray(maColorHandle); //绘制三角形 GLES20.glDrawArrays(GLES20.GL_TRIANGLES, 0, vCount); } public static float[] getFinalMatrix(float[] spec) { mMVPMatrix=new float[16]; Matrix.multiplyMM(mMVPMatrix, 0, mVMatrix, 0, spec, 0); Matrix.multiplyMM(mMVPMatrix, 0, mProjMatrix, 0, mMVPMatrix, 0); return mMVPMatrix; }}
代码四(ShadeUtil):
package com.clark.utils;import android.content.res.Resources;import android.opengl.GLES20;import android.util.Log;import java.io.ByteArrayOutputStream;import java.io.InputStream;/** * 加载顶点和片元着色器的类 */public class ShadeUtil { private static final String GLES_ERROR = "ES_20_ERROR"; /** * 加载着色器方法 * @param shaderType 着色器类型 * @param source 着色器的脚本字符串 * @return 着色器id -- 0 错误 其他 成功 */ public static int loadShader(int shaderType,String source){ //创建着色器 int shader = GLES20.glCreateShader(shaderType); //创建成功 if(shader != 0){ GLES20.glShaderSource(shader,source); GLES20.glCompileShader(shader); int[] compiled = new int[1]; //编译着色器 GLES20.glGetShaderiv(shader,GLES20.GL_COMPILE_STATUS,compiled,0); //编译失败 if(compiled[0] == 0){ Log.e(GLES_ERROR,"Could not compile shader " + shaderType + ";"); Log.e(GLES_ERROR,GLES20.glGetShaderInfoLog(shader)); GLES20.glDeleteShader(shader); shader = 0; } } return shader; } /** * 创建着色器程序的方法 * @param vertexSource 顶点着色器资源 * @param frgmentSource 片元着色器资源 * @return 着色器程序结果 0-失败 其他-成功 */ public static int createProgram(String vertexSource,String frgmentSource){ //加载顶点着色器 int vertexShader = loadShader(GLES20.GL_VERTEX_SHADER,vertexSource); if(vertexShader == 0){ return 0; } //加载片元着色器 int pixelShader = loadShader(GLES20.GL_FRAGMENT_SHADER,frgmentSource); if(pixelShader == 0){ return 0; } //GPU 加载完毕 //创建着色器程序 int program = GLES20.glCreateProgram(); //程序创建成功,则向程序中加入顶点着色器和片元着色器 if(program != 0){ //加入顶点着色器 GLES20.glAttachShader(program,vertexShader); checkGLError("glAttachShader"); //加入片元着色器 GLES20.glAttachShader(program,pixelShader); checkGLError("glAtaachShader"); //链接程序 GLES20.glLinkProgram(program); int [] linkStatus = new int [1]; GLES20.glGetProgramiv(program,GLES20.GL_LINK_STATUS,linkStatus,0); //链接失败,删除程序 if(linkStatus[0] != GLES20.GL_TRUE){ Log.e(GLES_ERROR,"Could not link program:"); Log.e(GLES_ERROR,GLES20.glGetProgramInfoLog(program)); GLES20.glDeleteProgram(program); program = 0; } } return program; } /** * 检查每一步操作是否有错误方法 * @param op 错误原因 */ public static void checkGLError(String op){ int error; while((error = GLES20.glGetError()) != GLES20.GL_NO_ERROR){ Log.e(GLES_ERROR,op+": glError:" + error); throw new RuntimeException(op+": glError:" + error); } } /** * 从sh脚本加载着色器内容的方法 * @param fname assets下文件的名字 * @param r 资源 * @return 着色器内容文本 */ 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; }}
在assets/vetex.sh中添加顶点着色器代码:
uniform mat4 uMVPMatrix;//总变换矩阵attribute vec3 aPosition;//顶点位置attribute vec4 aColor;//顶点颜色varying vec4 vColor;//用于传给片元着色器的易变变量void main() { gl_Position = uMVPMatrix * vec4(aPosition,1);//根据总变换矩阵计算此次绘制此顶点的位置 vColor = aColor;//接收的顶点颜色传递给片元着色器}
precision mediump float;varying vec4 vColor;//接收从顶点着色器过来的易变变量void main(){ gl_FragColor = vColor;}
ps,记得打赏哦~~~
0 0
- open glHelloWorld之旋转的三角形(android)
- WebGL之旋转三角形
- 【附源码】【Android 3D OpenGL】开发之二——旋转的三角形【MacroCheng原创】
- 制作一个旋转的三角形
- android opengl es 三角形、正方形自动旋转
- Android Open GL ES - 绘制三角形
- d3d实现一个旋转的三角形
- opengl es 实现旋转的三角形
- Java编程实例:向内旋转的三角形
- 3D编程-旋转的三角形
- CSS实现三角形的动画旋转
- 使用unity绘制旋转的三角形
- GLSL记录(1)-实时旋转的三角形
- Android之可旋转的轮盘菜单
- Android 学习之Bitmap位图的旋转
- Android之图片旋转
- poj2079 Triangle (旋转卡壳之最大三角形)
- Android OpenGL学习笔记(二)之----三角形的绘制.
- 二叉树的链式实现(插入,查找,遍历,删除)
- 信息管理系统的登录注册
- 黑帽SEO中的蜘蛛池是什么?
- 347. Top K Frequent Elements
- 停止线程
- open glHelloWorld之旋转的三角形(android)
- ios 开发学习日志 自定义alertView 1
- HDu4847
- 三级菜单制作
- poj 2387 Til the Cows Come Home -- 最短路dijstra
- yum 安装php,mysql,php-fpm,nginx
- linux 下的磁盘分区,格式化及其挂载
- Linux中线程与CPU核的绑定
- html5图形组合