OpenGL ES2.0---凿岩车钻臂3D案例之MatrixState类详解

先附上源代码。

import java.nio.ByteBuffer;

import java.nio.ByteOrder;
import java.nio.FloatBuffer;
import java.util.*;
import android.opengl.Matrix;


//存储系统矩阵状态的类
public class MatrixState 
{
private static float[] mProjMatrix = new float[16];//4x4矩阵 投影用
    private static float[] mVMatrix = new float[16];//摄像机位置朝向9参数矩阵   
    private static float[] currMatrix;//当前变换矩阵
    public static float[] lightLocation=new float[]{0,0,0};//定位光光源位置
    public static FloatBuffer cameraFB;    
    public static FloatBuffer lightPositionFB;
    
    public static Stack<float[]> mStack=new Stack<float[]>();//保护变换矩阵的栈
    
    public static void setInitStack()//获取不变换初始矩阵
    {
    currMatrix=new float[16];
    Matrix.setRotateM(currMatrix, 0, 0, 1, 0, 0);
    }
    
    public static void pushMatrix()//保护变换矩阵
    {
    mStack.push(currMatrix.clone());
    }
    
    public static void popMatrix()//恢复变换矩阵
    {
    currMatrix=mStack.pop();
    }
    
    public static void translate(float x,float y,float z)//设置沿xyz轴移动
    {
    Matrix.translateM(currMatrix, 0, x, y, z);
    }
    
    public static void rotate(float angle,float x,float y,float z)//设置绕xyz轴移动
    {
    Matrix.rotateM(currMatrix,0,angle,x,y,z);
    }
    
    
    //设置摄像机
    public static void setCamera
    (
    float cx, //摄像机位置x
    float cy,   //摄像机位置y
    float cz,   //摄像机位置z
    float tx,   //摄像机目标点x
    float ty,   //摄像机目标点y
    float tz,   //摄像机目标点z
    float upx,  //摄像机UP向量X分量
    float upy,  //摄像机UP向量Y分量
    float upz   //摄像机UP向量Z分量
    )
    {
    Matrix.setLookAtM
        (
        mVMatrix, 
        0, 
        cx,
        cy,
        cz,
        tx,
        ty,
        tz,
        upx,
        upy,
        upz
        );
   
    float[] cameraLocation=new float[3];//摄像机位置
    cameraLocation[0]=cx;
    cameraLocation[1]=cy;
    cameraLocation[2]=cz;
   
    ByteBuffer llbb = ByteBuffer.allocateDirect(3*4);
        llbb.order(ByteOrder.nativeOrder());//设置字节顺序
        cameraFB=llbb.asFloatBuffer();
        cameraFB.put(cameraLocation);
        cameraFB.position(0);  
    }
    
    //设置透视投影参数
    public static void setProjectFrustum
    (
    float left, //near面的left
    float right,    //near面的right
    float bottom,   //near面的bottom
    float top,      //near面的top
    float near, //near面距离
    float far       //far面距离
    )
    {
    Matrix.frustumM(mProjMatrix, 0, left, right, bottom, top, near, far);    
    }
    
    //设置正交投影参数
    public static void setProjectOrtho
    (
    float left, //near面的left
    float right,    //near面的right
    float bottom,   //near面的bottom
    float top,      //near面的top
    float near, //near面距离
    float far       //far面距离
    )
    {    
    Matrix.orthoM(mProjMatrix, 0, left, right, bottom, top, near, far);
    }   
   
    //获取具体物体的总变换矩阵
    public static float[] getFinalMatrix()
    {
    float[] mMVPMatrix=new float[16];
    Matrix.multiplyMM(mMVPMatrix, 0, mVMatrix, 0, currMatrix, 0);
        Matrix.multiplyMM(mMVPMatrix, 0, mProjMatrix, 0, mMVPMatrix, 0);        
        return mMVPMatrix;
    }
    
    //获取具体物体的变换矩阵
    public static float[] getMMatrix()
    {       
        return currMatrix;
    }
    
    //设置灯光位置的方法
    public static void setLightLocation(float x,float y,float z)
    {
    lightLocation[0]=x;
    lightLocation[1]=y;
    lightLocation[2]=z;
    ByteBuffer llbb = ByteBuffer.allocateDirect(3*4);
        llbb.order(ByteOrder.nativeOrder());//设置字节顺序
        lightPositionFB=llbb.asFloatBuffer();
        lightPositionFB.put(lightLocation);
        lightPositionFB.position(0);
    }

}

主要问题有三个:

一是总矩阵由当前矩阵、摄像机矩阵、投影矩阵相乘得来的理由?

二是相机位置和灯光位置要分配内存的理由?

三是要好好学习下Matrix矩阵类,看其提供些什么功能?

我们先来第三个问题:



java.lang.Object
   ↳ android.opengl.Matrix 没有构造函数,其方法都是静态方法,无非是对4x4矩阵(列为主)、4维向量的运算。


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值