您的位置:首页 > 运维架构

3D开发的视觉基础openGL ES

2015-12-09 15:17 316 查看
版权声明:本文为博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明。 本文链接:https://blog.csdn.net/lu6666/article/details/50236789


视口变换
视口:屏幕中的一个矩形显示区域,我们输出的二维图像都会在这个区域显示
默认情况:视口位于坐标原点,大小与屏幕大小一致
注意事项:横竖屏切换的时候要做相应视口变换,以保证图像不会被拉长或者压扁
方法: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;
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: