12_opengl学习
来源:互联网 发布:oracle数据库考试 编辑:程序博客网 时间:2024/06/14 12:24
#1 opengl学习资料:
(1.1)百度huachao1001,选择他的专栏,可以看到几篇很好的入门文章!
#2 入门demo:http://www.jianshu.com/p/442682fda917
再配上这个入门文章,http://blog.csdn.net/jason0539/article/details/9164885
上面两样东西可以让你很清晰地入门!
入门之前先看一下View,SurfaceView,GLSurfaceView的概念及区别:http://blog.csdn.net/androidwubo/article/details/60469183
#3 开始绘制第一个图形:三角形
demo及原理: http://blog.csdn.net/huachao1001/article/details/52044602
#4 绘制一个3d图形,而且让这个3d图形一直会动!(从网上随便下载一个.stl文件,存到手机sd卡中,然后读取这个.stl文件绘出对应的3d图!)
demo参考处: http://blog.csdn.net/huachao1001/article/details/52054334
自己的代码:
(4.1)布局文件不需要、清单文件中读sd卡权限;
(4.2)Model类:
package com.example.y81022671.a15_opengl_third;import java.nio.FloatBuffer;/** * Created by y81022671 on 2017/7/4. */public class Model { private int facetCount; private float[] verts; private float[] vnorms; private short[] remarks; private FloatBuffer vertBuffer; private FloatBuffer vnormBuffer; float maxX; float minX; float maxY; float minY; float maxZ; float minZ; public Point getCenterPoint() { float cx = minX + (maxX - minX) / 2; float cy = minY + (maxY - minY) / 2; float cz = minZ + (maxZ - minZ) / 2; return new Point(cx, cy, cz); } public float getR() { float dx = (maxX - minX); float dy = (maxY - minY); float dz = (maxZ - minZ); float max = dx; if (dy > max) { max = dy; } if (dz > max) { max = dz; } return max; } public float[] getVerts(float[] verts) { return verts; } public void setVerts(float[] verts) { this.verts = verts; vertBuffer = Util.floatToBuffer(verts); } public float[] getVnorms(float[] vnorms) { return vnorms; } public void setVnorms(float[] vnorms) { this.vnorms = vnorms; this.vnormBuffer = Util.floatToBuffer(vnorms); } public int getFacetCount() { return facetCount; } public void setFacetCount(int facetCount) { this.facetCount = facetCount; } public short[] getRemarks() { return remarks; } public void setRemarks(short[] remarks) { this.remarks = remarks; } public FloatBuffer getVertBuffer() { return vertBuffer; } public FloatBuffer getVnormBuffer() { return vnormBuffer; }}
(4.3)Util类:
package com.example.y81022671.a15_opengl_third;import java.nio.ByteBuffer;import java.nio.ByteOrder;import java.nio.FloatBuffer;/** * Created by y81022671 on 2017/7/4. */public class Util { public static FloatBuffer floatToBuffer(float[] a) { ByteBuffer bb = ByteBuffer.allocateDirect(a.length * 4); bb.order(ByteOrder.nativeOrder()); FloatBuffer buffer = bb.asFloatBuffer(); buffer.put(a); buffer.position(0); return buffer; } //根据stl文件的第81-第84这四个字节,求出该stl文件中有多少个三角面的个数! public static int byte4ToInt(byte[] bytes, int offset) { int b3 = bytes[offset + 3] & 0xFF; int b2 = bytes[offset + 2] & 0xFF; int b1 = bytes[offset + 1] & 0xFF; int b0 = bytes[offset + 0] & 0xFF; return (b3 << 24) | (b2 << 16) | (b1 << 8) | (b0); } //拿到bytes字节数组,从offset这个下标开始,数4个字节,然后将这4个字节转化成1个float类型的数值! public static float byte4ToFloat(byte[] bytes, int offset) { return Float.intBitsToFloat(byte4ToInt(bytes, offset)); } public static int byte2ToShort(byte[] bytes, int offset) { int b1 = bytes[offset + 1] & 0xFF; int b0 = bytes[offset + 0] & 0xFF; return (short) ((b1 << 8) | b0); }}
(4.4)STLReader类:
package com.example.y81022671.a15_opengl_third;import android.content.Context;import java.io.File;import java.io.FileInputStream;import java.io.IOException;import java.io.InputStream;/** * Created by y81022671 on 2017/7/4. */public class STLReader { private StlLoadListener stlLoadListener = new StlLoadListener() { @Override public void onstart() { System.out.println("StlLoadListener onstart"); } @Override public void onLoading(int cur, int total) { System.out.println("StlLoadListener onLoading"); } @Override public void onFinished() { System.out.println("StlLoadListener onFinished"); } @Override public void onFailure(Exception e) { System.out.println("StlLoadListener onFailure"); } }; public Model parserBinStlInSDCard(String path) throws IOException { File file = new File(path); FileInputStream fis = new FileInputStream(file); return parserBinStl(fis); } public Model parserBinStlInAssets(Context context, String fileName) throws IOException { InputStream is = context.getAssets().open(fileName); return parserBinStl(is); } //根据二进制的stl文件读出它的相关数据!即解析二进制的stl文件 public Model parserBinStl(InputStream in) throws IOException { if (null != stlLoadListener) { stlLoadListener.onstart(); } Model model = new Model(); in.skip(80); byte[] bytes = new byte[4]; in.read(bytes); int facetCount = Util.byte4ToInt(bytes, 0); model.setFacetCount(facetCount); if (facetCount == 0) { in.close(); return model; } byte[] facetBytes = new byte[50 * facetCount]; in.read(facetBytes); in.close(); //定义一个新的方法解析后面那些关于三角面的字节 parseModel(model, facetBytes); if (null != stlLoadListener) { stlLoadListener.onFinished(); } return model; } //定义的一个新的方法,它的作用是:解析stl二进制文件的后面那些字节(所有三角面信息的那些字节!) private void parseModel(Model model, byte[] facetBytes) { int facetCount = model.getFacetCount(); float[] verts = new float[facetCount * 3 * 3]; float[] vnorms = new float[facetCount * 3 * 3]; short[] remarks = new short[facetCount]; int stlOffset = 0; try { for (int i = 0; i < facetCount; i++) { if (null != stlLoadListener) { stlLoadListener.onLoading(i, facetCount); } for (int j = 0; j < 4; j++) { float x = Util.byte4ToFloat(facetBytes, stlOffset + 0); float y = Util.byte4ToFloat(facetBytes, stlOffset + 4); float z = Util.byte4ToFloat(facetBytes, stlOffset + 8); stlOffset = stlOffset + 12; if (j == 0) { vnorms[i * 9 + 0] = x; vnorms[i * 9 + 1] = y; vnorms[i * 9 + 2] = z; vnorms[i * 9 + 3] = x; vnorms[i * 9 + 4] = y; vnorms[i * 9 + 5] = z; vnorms[i * 9 + 6] = x; vnorms[i * 9 + 7] = y; vnorms[i * 9 + 8] = z; } else { verts[i * 9 + (j - 1) * 3 + 0] = x; verts[i * 9 + (j - 1) * 3 + 1] = y; verts[i * 9 + (j - 1) * 3 + 2] = z; } if (i == 0 && j == 1) { model.minX = model.maxX = x; model.minY = model.maxY = y; model.minZ = model.maxZ = z; } else { model.minX = Math.min(model.minX, x); model.minY = Math.min(model.minY, y); model.minZ = Math.min(model.minZ, z); model.maxX = Math.max(model.maxX, x); model.maxY = Math.max(model. maxY, y); model.maxZ = Math.max(model.maxZ, z); } } //stl文件的注释说明部分! short r = (short) Util.byte2ToShort(facetBytes, facetCount); stlOffset = stlOffset + 2; remarks[i] = r; } } catch (Exception e) { if (null != stlLoadListener) { stlLoadListener.onFailure(e); } else { e.printStackTrace(); } } model.setVerts(verts); model.setVnorms(vnorms); model.setRemarks(remarks); } public static interface StlLoadListener { void onstart(); void onLoading(int cur, int total); void onFinished(); void onFailure(Exception e); }}
(4.5)MyRenderer类:
package com.example.y81022671.a15_opengl_third;import android.content.Context;import android.opengl.GLSurfaceView;import android.opengl.GLU;import android.os.Environment;import java.io.File;import java.io.IOException;import javax.microedition.khronos.egl.EGLConfig;import javax.microedition.khronos.opengles.GL10;/** * Created by y81022671 on 2017/7/5. */public class MyRenderer implements GLSurfaceView.Renderer { private Model model; private float mScalef = 1; private Point mCenterPoint; private Point eye = new Point(0, 0, -3); private Point up = new Point(0, 1, 0); private Point center = new Point(0, 0, 0); private float mDegree = 0; public MyRenderer(Context context) { try { String name0 = Environment.getExternalStorageDirectory() + "00"; String name1 = Environment.getExternalStorageDirectory() + File.pathSeparator + "smile.stl"; String name = new File(Environment.getExternalStorageDirectory() + File.separator + "smile.stl").getAbsolutePath(); String name2 = new File(Environment.getExternalStorageDirectory() + File.separator + "smile.txt").getName(); //model = new STLReader().parserBinStlInAssets(context, name); //model = new STLReader().parserBinStlInAssets(context, name); model = new STLReader().parserBinStlInSDCard(name); } catch (IOException e) { e.printStackTrace(); } } public void rotate(float degree) { mDegree = degree; } @Override public void onSurfaceCreated(GL10 gl, EGLConfig config) { gl.glEnable(GL10.GL_DEPTH_TEST); gl.glClearDepthf(1.0f); gl.glDepthFunc(GL10.GL_LEQUAL); gl.glShadeModel(GL10.GL_SMOOTH); float r = model.getR(); mScalef = 0.5f / r; mCenterPoint = model.getCenterPoint(); } @Override public void onSurfaceChanged(GL10 gl, int width, int height) { gl.glViewport(0, 0, width, height); gl.glMatrixMode(GL10.GL_PROJECTION); gl.glLoadIdentity(); GLU.gluPerspective(gl, 45.0f, ((float) width / height), 1f, 100f); gl.glMatrixMode(GL10.GL_MODELVIEW); gl.glLoadIdentity(); } @Override public void onDrawFrame(GL10 gl) { gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT); gl.glLoadIdentity(); GLU.gluLookAt(gl, eye.x, eye.y, eye.z, center.x, center.y, center.z, up.x, up.y, up.z); gl.glRotatef(mDegree, 0, 1, 0); gl.glScalef(mScalef, mScalef, mScalef); gl.glTranslatef(-mCenterPoint.x, -mCenterPoint.y, -mCenterPoint.z); gl.glEnableClientState(GL10.GL_NORMAL_ARRAY); gl.glEnableClientState(GL10.GL_VERTEX_ARRAY); gl.glNormalPointer(GL10.GL_FLOAT, 0, model.getVnormBuffer()); gl.glVertexPointer(3, GL10.GL_FLOAT, 0, model.getVertBuffer()); gl.glDrawArrays(GL10.GL_TRIANGLES, 0, model.getFacetCount() * 3); gl.glDisableClientState(GL10.GL_VERTEX_ARRAY); gl.glDisableClientState(GL10.GL_NORMAL_ARRAY); }}
(4.6) MainActivity类:
package com.example.y81022671.a15_opengl_third;import android.app.ActivityManager;import android.content.pm.ConfigurationInfo;import android.opengl.GLSurfaceView;import android.os.Build;import android.os.Handler;import android.os.Message;import android.support.v7.app.AppCompatActivity;import android.os.Bundle;import android.widget.Toast;public class MainActivity extends AppCompatActivity { private boolean isSupportsEs2; private GLSurfaceView glView; private MyRenderer myRenderer; private float rotateDegreen = 0; private Handler handler = new Handler() { @Override public void handleMessage(Message msg) { rotate(rotateDegreen); } }; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); checkSupported(); if (isSupportsEs2) { glView = new GLSurfaceView(this); myRenderer = new MyRenderer(this); glView.setRenderer(myRenderer); setContentView(glView); } else { setContentView(R.layout.activity_main); Toast.makeText(this, "当前设备不支持OpenGL ES 2.0!", Toast.LENGTH_SHORT).show(); } } @Override protected void onResume() { super.onResume(); if (null != glView) { glView.onResume(); new Thread() { @Override public void run() { while (true) { try { sleep(100); rotateDegreen += 5; handler.sendEmptyMessage(0x001); } catch (InterruptedException e) { e.printStackTrace(); } } } }.start(); } } @Override protected void onPause() { super.onPause(); if (null != glView) { glView.onPause(); } } private void rotate(float rotateDegreen) { myRenderer.rotate(rotateDegreen); glView.invalidate(); } private void checkSupported() { ActivityManager activityManager = (ActivityManager) getSystemService(ACTIVITY_SERVICE); ConfigurationInfo configurationInfo = activityManager.getDeviceConfigurationInfo(); isSupportsEs2 = configurationInfo.reqGlEsVersion >= 0x2000; boolean isEmulator = Build.VERSION.SDK_INT > Build.VERSION_CODES.ICE_CREAM_SANDWICH_MR1 && (Build.FINGERPRINT.startsWith("generic") || Build.FINGERPRINT.startsWith("unknown") || Build.MODEL.contains("google_sdk") || Build.MODEL.contains("Emulator") || Build.MODEL.contains("Android SDK built for x86")); isSupportsEs2 = isSupportsEs2 || isEmulator; }}
#5
阅读全文
0 0
- 12_opengl学习
- OpenGL学习日记0_OpenGL,环境搭建
- 代码_多媒体_OPENGL
- 三维变换到二维投影_OpenGL版本
- 三维变换到二维投影_OpenGL版本
- 24位彩图直方图均衡化处理_opengl
- IOS:Camera的特性分析与使用3_OPENGL特效
- 学习12
- 学习MongoDB--(12):学习总结
- JavaScript学习 jquery学习12 键盘事件
- AD学习笔记12
- 学习ARM开发(12)
- Java学习笔记12
- EJB学习日记(12)
- 学习ARM开发(12)
- stl 学习笔记 12
- Oracle 学习12(完结)
- JAVA 学习12
- Unity创建自定义窗口
- 来科普啦,对于软件测试,你知道多少?
- Can't install via pip because of egg_info error
- App启动加载广告页面思路
- Oracle中的SQL分页查询原理和方法详解
- 12_opengl学习
- gulp 安装 gulp-css-spriter
- 【python学习笔记】Dataframe和类SQL的merge函数(一)
- UVA11802-All Your Bases Belong to Us
- Class org.apache.struts2.json.JSONWriter can not access a member of class
- 微信图片预览的小经验
- mui框架 页面无法滚动解决方法
- hive安装过程全程解析、hive常规操作、说明
- 最不擅长等分布局