5-OpenGLES绘制棱锥深度测试表面剔除

三角形
    triangles:三角形集
    triangle_strip:三角形带(用的最多)
    triangle_fan:扇面

顶点着色模式:
    1.smooth:平滑模式(渐变过渡)。默认。
    2.flat:单调(跟最后一个点的颜色相同)。

深度轴:z轴
深度缓冲区:每个像素的深度值。
深度测试:启用z值,被遮挡的物体看不见。

剔除:如果看不见的部分,告诉openGL不要绘图,提高性能。

public class MyActivity extends Activity {private MyRenderer render;private MyGLSurfaceView view;@Overridepublic void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);view = new MyGLSurfaceView(this);render = new MyRenderer();view.setRenderer(render);view.setRenderMode(GLSurfaceView.RENDERMODE_WHEN_DIRTY);// 脏渲染,命令渲染setContentView(view);}class MyGLSurfaceView extends GLSurfaceView {public MyGLSurfaceView(Context context) {super(context);}public MyGLSurfaceView(Context context, AttributeSet attrs) {super(context, attrs);}}class MyRenderer implements GLSurfaceView.Renderer {private float ratio, xrotate, yrotate;@Overridepublic void onSurfaceCreated(GL10 gl, EGLConfig config) {// 清屏色gl.glClearColor(0f, 0f, 0f, 1f);// 启用顶点缓冲区gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);// 启用颜色缓冲区gl.glEnableClientState(GL10.GL_COLOR_ARRAY);}@Overridepublic void onSurfaceChanged(GL10 gl, int width, int height) {// 设置视口gl.glViewport(0, 0, width, height);ratio = (float) width / (float) height;// 投影矩阵gl.glMatrixMode(GL10.GL_PROJECTION);// 加载单位矩阵gl.glLoadIdentity();// 设置平截头体gl.glFrustumf(-ratio, ratio, -1, 1, 3f, 7f);}@Overridepublic void onDrawFrame(GL10 gl) {// 清除颜色缓冲区和深度缓冲区gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);// 设置绘图颜色gl.glColor4f(1f, 0f, 0f, 1f);// 启用深度测试;否则最后绘制底面的始终显示,不管是否被遮挡,总能看见!gl.glEnable(GL10.GL_DEPTH_TEST);// 启用表面剔除gl.glEnable(GL10.GL_CULL_FACE);// CCW:counter clock wise-->逆时针// CW:clock wise--> 顺时针gl.glFrontFace(GL10.GL_CCW);// 指定逆时针为正面(锥面是逆时针绘制的)// 剔除背面(圆锥体里面)gl.glCullFace(GL10.GL_BACK);// GL10.GL_SMOOTH:平滑着色(默认)// GL10.GL_FLAT:单调模式着色gl.glShadeModel(GL10.GL_FLAT);// 操作模型视图矩阵gl.glMatrixMode(GL10.GL_MODELVIEW);gl.glLoadIdentity();// 设置眼球的参数GLU.gluLookAt(gl, 0f, 0f, 5f, 0f, 0f, 0f, 0f, 1f, 0f);// 旋转角度gl.glRotatef(xrotate, 1, 0, 0);gl.glRotatef(yrotate, 0, 1, 0);// 计算点坐标float r = 0.5f;// 半径float x = 0f, y = 0f, z = -0.5f;/******************** 锥面 ************************/// 顶点坐标集合List coordsList = new ArrayList();// 添加锥顶点coordsList.add(0f);coordsList.add(0f);coordsList.add(0.5f);// 顶点颜色集合List colorList = new ArrayList();colorList.add(1f);// rcolorList.add(0f);// gcolorList.add(0f);// bcolorList.add(1f);// a/******************** 锥底 ************************/// 锥底坐标List coordsConeBottomList = new ArrayList();coordsConeBottomList.add(0f);coordsConeBottomList.add(0f);coordsConeBottomList.add(-0.5f);boolean flag = false;// 底面for (float alpha = 0f; alpha < Math.PI * 6; alpha += (float) (Math.PI / 8)) {// 锥面x = (float) (r * Math.cos(alpha));y = (float) (r * Math.sin(alpha));coordsList.add(x);coordsList.add(y);coordsList.add(z);// 锥底坐标coordsConeBottomList.add(x);coordsConeBottomList.add(y);coordsConeBottomList.add(z);// 点颜色值if (flag = !flag) {// 黄色colorList.add(1f);colorList.add(1f);colorList.add(0f);colorList.add(1f);} else {// 红色colorList.add(1f);colorList.add(0f);colorList.add(0f);colorList.add(1f);}}// 在颜色缓冲区增加一个颜色if (flag = !flag) {// 黄色colorList.add(1f);colorList.add(1f);colorList.add(0f);colorList.add(1f);} else {// 红色colorList.add(1f);colorList.add(0f);colorList.add(0f);colorList.add(1f);}// 颜色缓冲区ByteBuffer colorBuffer = list2ByteBuffer(colorList);gl.glColorPointer(4, GL10.GL_FLOAT, 0, colorBuffer);// 绘制锥面gl.glVertexPointer(3, GL10.GL_FLOAT, 0, list2ByteBuffer(coordsList));gl.glDrawArrays(GL10.GL_TRIANGLE_FAN, 0, coordsList.size() / 3);// 锥底也是逆时针绘制,是从锥体里面绘制的,所以要剔除正面,留背面(即外底表面可视表面)gl.glCullFace(GL10.GL_FRONT);// 绘制锥底colorBuffer.position(4 * 4);//单位:字节(字节缓冲区),定位到:4个分量×floatSize,即下一个颜色//如果是浮点缓冲区,则position()参数值为4.gl.glColorPointer(4, GL10.GL_FLOAT, 0, colorBuffer);gl.glVertexPointer(3, GL10.GL_FLOAT, 0, list2ByteBuffer(coordsConeBottomList));gl.glDrawArrays(GL10.GL_TRIANGLE_FAN, 0, coordsConeBottomList.size() / 3);}}private ByteBuffer list2ByteBuffer(List list) {ByteBuffer ibb = ByteBuffer.allocateDirect(list.size() * 4);ibb.order(ByteOrder.nativeOrder());FloatBuffer fbb = ibb.asFloatBuffer();for (Float f : list) {fbb.put(f);}ibb.position(0);return ibb;}@Overridepublic boolean onKeyDown(int keyCode, KeyEvent event) {float step = 5f;if (keyCode == KeyEvent.KEYCODE_DPAD_UP) {render.xrotate -= step;} else if (keyCode == KeyEvent.KEYCODE_DPAD_DOWN) {render.xrotate += step;} else if (keyCode == KeyEvent.KEYCODE_DPAD_LEFT) {render.yrotate += step;} else if (keyCode == KeyEvent.KEYCODE_DPAD_RIGHT) {render.yrotate -= step;}// 请求渲染,和脏渲染配合使用view.requestRender();return super.onKeyDown(keyCode, event);}
}


本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!

相关文章

立即
投稿

微信公众账号

微信扫一扫加关注

返回
顶部