3D开发的视觉基础openGL ES
视口变换
视口:屏幕中的一个矩形显示区域,我们输出的二维图像都会在这个区域显示
默认情况:视口位于坐标原点,大小与屏幕大小一致
注意事项:横竖屏切换的时候要做相应视口变换,以保证图像不会被拉长或者压扁
方法:glViewPort(int x ,int y ,int width,int height)
投影变换
投影变换可以选择使用平行投影和透视投影
平行投影包括 : 正投影,斜投影
透视投影包括:一点透视,两点透视,三点透视
平行投影
方法:glOrthof(float left,float right,float bottom,float top,float zNear,float zFar)
透视投影
方法:glFrustumf(float left,float right,float bottom,float top,float zNear,float zFar)
gluPerspective(GL10 gl ,float fovy,float aspect,float zNear,float zFar)//fovy 为yoz平面上视野角度,aspect物体截面横纵比例
模型变换
模型平移
方法:glTranslate(float x ,float y,float z)
使用方式:
gl.glMatrixMode(gl.GL_MODELVIEW)
gl.glLoadIdentity();
gl.glTranslatef(1.0f,1.0f.1.0f)
模型旋转
方法:glRotate(float angle,float x,float y,float z)//x,y,z 为绕哪个坐标轴旋转
模型缩放
方法:glScale(float x ,float y ,float z )//以坐标原点作为中心进行缩放
摄像机取景
方法:gluLookAt(GL10 gl,float eyeX,float eyeY,float eyeZ,float centerX,float centerY,float centerZ,float upX,float upY,float upZ)// eyesX… 摄像机的位置, center …聚焦的位置, up摄像机的上方,用来确定摄像机方向
深度测试
利用深度缓冲区,只缓冲与观察点最近的像素,解决遮挡不合理问题
方法:
//清除深度缓存
gl.glClearDepthf(1.0f)
//启动深度测试
gl.glEnable(GL10.GL_DEPTH_TEST)
//设置深度测试类型
gl.glDepthFunc(GL10.GL_LEQUAL)
GL10.GL_NEVER 总是不能通过深度测试
GL10.GL_ALWAYS 总是能通过深度测试
GL10.GL_LESS 当前像素 z坐标小于等于深度测试对应位置z坐标,则通过深度测试
GL10.GL_LEQUAL z坐标小于等于
GL10.GL_GEQUAL 等于
GL10.GL_GREATER 大于
GL10.GL_NOTEQUAL 不等于
背面剔除
为了提高渲染效率,不渲染看不见的那些面,建模型的时候必须是顺时针,或逆时针
方法:
gl.glEnable(GL10.GL_CULL_FACE)//开启背面剔除
gl.glCullFace(GL10.GL_BACK)//剔除背面
GL10.GL_BACK 背面剔除
GL10.GL_FRONT 正面剔除
抗锯齿
方法:
gl.glEnable(GL10.GL_LINE_SMOOTH)
package com.example.wudanfeng.openglproject; import android.opengl.GLSurfaceView; import android.opengl.GLU; import com.example.wudanfeng.openglproject.com.example.wudanfeng.opengl.module.CirclePlane; import com.example.wudanfeng.openglproject.com.example.wudanfeng.opengl.module.Cone; import com.example.wudanfeng.openglproject.com.example.wudanfeng.opengl.module.RectanglePlane; import java.nio.FloatBuffer; import javax.microedition.khronos.egl.EGLConfig; import javax.microedition.khronos.opengles.GL10; /** * Created by wudanfeng on 15/11/18. */ public class GLShadowRender implements GLSurfaceView.Renderer { float xrot, yrot, zrot; FloatBuffer vertextBuffer; private RectanglePlane rectanglePlane = new RectanglePlane(5,5,10,10); private CirclePlane circlePlane = new CirclePlane(1f,4f,50); //环境光 private FloatBuffer lightAmbint = FloatBuffer.wrap(new float[]{0.5f,0.5f,0.5f,1f}); //漫射光 private FloatBuffer lightDefuse = FloatBuffer.wrap(new float[]{1f,1f,1f,1f}); //光源位置 private FloatBuffer lightPosition = FloatBuffer.wrap(new float[]{0f,0f,2f,1f}); private RectanglePlane ground = new RectanglePlane(10.f,10f,10,10); private Cone pillar = new Cone(0.5f,2f,10,50); @Override public void onSurfaceCreated(GL10 gl, EGLConfig config) { gl.glClearColor(0, 0, 0, 0); //启动阴影平滑 gl.glShadeModel(GL10.GL_SMOOTH); //启动深度测试 gl.glEnable(GL10.GL_DEPTH_TEST); //设置深度缓存 gl.glClearDepthf(1.0f); //所做深度测试的类型 gl.glDepthFunc(GL10.GL_LEQUAL); //系统透视修正 gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT, GL10.GL_FASTEST); //设置环境光 gl.glLightfv(GL10.GL_LIGHT1, GL10.GL_AMBIENT, lightAmbint); //设置漫射光 gl.glLightfv(GL10.GL_LIGHT1,GL10.GL_DIFFUSE,lightDefuse); //设置光源位置 gl.glLightfv(GL10.GL_LIGHT1,GL10.GL_POSITION,lightPosition); //启动一号光源 gl.glEnable(GL10.GL_LIGHT1); //开启光源 gl.glEnable(GL10.GL_LIGHTING); } @Override public void onDrawFrame(GL10 gl) { //清除屏幕和深度缓存 gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT); //重置当前模型观察矩阵 gl.glLoadIdentity(); gl.glTranslatef(0, 0, -6.0f); gl.glRotatef(xrot, 1.0f, 0.0f, 0.0f); gl.glRotatef(yrot, 0.0f, 1.0f, 0.0f); gl.glRotatef(zrot, 0.0f, 0.0f, 1.0f); ground.draw(gl); float dy = -3.0f; for(int i =0;i <4;i++){ gl.glPushMatrix(); gl.glTranslatef(-2.0f, dy, 1.0f); pillar.draw(gl); gl.glPopMatrix(); //绘制右侧柱子 gl.glPushMatrix();; gl.glTranslatef(2.0f, dy, 10.f); pillar.draw(gl); gl.glPopMatrix(); } gl.glLoadIdentity(); } @Override public void onSurfaceChanged(GL10 gl, int width, int height) { float ratio = (float) width / height; //设置视口大小 gl.glViewport(0, 0, width, height); //设置摄影矩阵 gl.glMatrixMode(GL10.GL_PROJECTION); //重置投影矩阵 gl.glLoadIdentity(); //设置透视投影 gl.glFrustumf(-ratio, ratio, -1, 1, 1, 10); GLU.gluLookAt(gl, 0f, -4f, 5f, 0, 0, 0, 0, 1, 0); gl.glMatrixMode(GL10.GL_MODELVIEW); gl.glLoadIdentity(); } }
package com.example.wudanfeng.openglproject; import android.content.Context; import android.opengl.GLSurfaceView; import android.view.MotionEvent; /** * Created by wudanfeng on 15/11/18. */ public class MySurfaceView extends GLSurfaceView { private final float TOUCH_SCALE_FACOTOR = 180.0F/320; private GLShadowRender render = new GLShadowRender(); private float preX = 0.0f; private float preY = 0.0f; public MySurfaceView(Context context) { super(context); this.setRenderer(render); } public boolean onTouchEvent(MotionEvent event) { float x = event.getX(); float y = event.getY(); switch (event.getAction()) { case MotionEvent.ACTION_MOVE: float dx = x - preX; float dy = y - preY; render.zrot += dx * TOUCH_SCALE_FACOTOR; render.xrot += dy * TOUCH_SCALE_FACOTOR; this.requestRender(); } preX = x; preY = y; return true; } }
- [3D数学基础:图形与游戏开发]专栏前言
- Molehill 初识--flash 3d 开发基础
- Android OpenGL(二) 学习《Android 3D 游戏开发技术宝典 -openGL ES 2.0》
- 3D开发学习-着色语言 Shading Language基础(二) 使用
- 【Android 应用开发】OpenGL ES 2.0 -- 制作 3D 彩色旋转三角形 - 顶点着色器 片元着色器 使用详解
- 3D Math Primer for Graphics and Game Development -- 图形与游戏开发(3D数学基础) (简介)
- 【Android开发学习09】Android OpenGL ES 基础
- 零基础开发OpenGL ES 2.0学习笔记-Android篇(二)
- 视觉SLAM中的数学基础 第一篇 3D空间的位置表示
- 【Android 应用开发】OpenGL ES 2.0 -- 制作 3D 彩色旋转三角形 - 顶点着色器 片元着色器 使用详解
- 《Android 3D游戏开发技术宝典:OpenGL ES 2.0》
- 3D程序开发数学基础之向量
- Unity 3D开发-C#脚本语言的一些基础用法
- Android OpenGL ES 简明开发教程三:3D绘图基本概念
- 【Unity3d游戏开发】Unity3D中的3D数学基础---向量
- Android OpenGL ES 简明开发教程三:3D绘图基本概念
- Android OpenGL ES 简明开发教程四:3D 坐标变换
- DirectX&Direct 3D 游戏开发之3D图形的数学基础
- 【笔记】《DirectX 9.0 3D游戏开发编程基础》:Direct3D初始化
- Android 3D游戏开发——Opengl ES游戏引擎实现