zoukankan      html  css  js  c++  java
  • DirectX11 学习笔记7

    如今将又一次制定一个camera摄像机。能够自由移动。

    比方前进 后退,上游 下潜。 各个方向渲染之类的。

    首先设置按键。

    这个时候须要在

    XWindow.h 里面

    bool XWindow::frame()
    {
    	//推断是否按下ESC键
    	if(x_input->isKeyDown(VK_ESCAPE))
    		return false;
    	//假设A,S,D,W,Q,E,Z,X,C键按下。移动摄像机 
    	if(GetAsyncKeyState('W') & 0x8000)    //前后 
    		x_graphics->x_camera->walk(-0.1f); 
    	if(GetAsyncKeyState('S') & 0x8000)    
    		x_graphics->x_camera->walk(0.1f); 
    	if(GetAsyncKeyState('A') & 0x8000)    //左右 
    		x_graphics->x_camera->strafe(-0.1f); 
    	if(GetAsyncKeyState('D') & 0x8000)    
    		x_graphics->x_camera->strafe(0.1f); 
    	//if(GetAsyncKeyState('Q') & 0x8000)    //上下 
    	//	x_graphics->x_camera->fly(-0.1f); 
    	//if(GetAsyncKeyState('E') & 0x8000)    
    	//	x_graphics->x_camera->fly(0.1f); 
    	//if(GetAsyncKeyState('Z') & 0x8000)    
    	//	x_graphics->x_camera->pitch(PI/180); 
    	//if(GetAsyncKeyState('X') & 0x8000)    
    	//	x_graphics->x_camera->yaw(PI/180); 
    	//if(GetAsyncKeyState('C') & 0x8000)    
    	//	x_graphics->x_camera->roll(PI/180);
    
    
    	//动画。旋转摄像机 
    	//x_graphics->x_camera->roll(PI/180);
    
    
    	//開始渲染
    	return x_graphics->frame();
    }
    加入一些按键。假设报错的话, 可能是x_camera 在XGraphics.h 类里面是私有的,能够设置成公有

    private: 
    	bool render(); 
    public:
    	XCamera *x_camera;//摄像机
    private:
    	XD3Device *x_d3d;//3D设备
    	XModel *x_model;//模型
    	XShader *x_shader;//渲染器
    	HWND hwnd;


    然后非常easy吧

    然后就是改动摄像机了

    先上代码再解说吧

    #pragma once
    #include <xnamath.h>
    class XCamera
    {
    public:
    	enum CameraType { LANDOBJECT, AIRCRAFT };
    	XCamera();
    	void strafe(float units); // l左右
    	//void fly(float units);    // 上下
    	void walk(float units);   // 前后
    
    	//void pitch(float angle); // 旋转view坐标系right向量
    	//void yaw(float angle);   // 旋转up向量
    	//void roll(float angle);  // 旋转look向量
    
    	void getViewMatrix(XMMATRIX& V); 
    	void setCameraType(CameraType cameraType); 
    	void getPosition(XMFLOAT3* pos); 
    	void setPosition(XMFLOAT3* pos); 
    
    	void getRight(XMFLOAT3* right);
    	void getUp(XMFLOAT3* up);
    	void getLook(XMFLOAT3* look);
    private:
    	CameraType _cameraType;
    	XMFLOAT3 _right,_up,_look,_pos;
    };
    XCamera::XCamera()
    {
    	_cameraType=AIRCRAFT;
    	_pos=XMFLOAT3(0.0f, 0.0f, -10.0f);
    	_right=XMFLOAT3(1.0f,0.0f,0.0f);
    	_up=XMFLOAT3(0.0f,1.0f,0.0f);
    	_look=XMFLOAT3(0.0f,0.0f,1.0f);
    }
    void XCamera::getPosition(XMFLOAT3* pos)
    {
    	*pos = _pos;
    }
    
    void XCamera::setPosition(XMFLOAT3* pos)
    {
    	_pos = *pos;
    }
    
    void XCamera::getRight(XMFLOAT3* right)
    {
    	*right = _right;
    }
    
    void XCamera::getUp(XMFLOAT3* up)
    {
    	*up = _up;
    }
    
    void XCamera::getLook(XMFLOAT3* look)
    {
    	*look = _look;
    }
    
    //行走,沿着摄像机观察方向的移动
    void XCamera::walk(float units)
    {
    	XMVECTOR vpos,vlook;
    	vpos=XMLoadFloat3(&_pos);
    	vlook=XMLoadFloat3(&_look);
    	// 仅在x,z平面移动
    	if( _cameraType == LANDOBJECT )
    	{
    		vpos += XMVectorSet(_look.x, 0.0f, _look.z,0)*units;
    	}
    	if( _cameraType == AIRCRAFT )
    		vpos += vlook * units;
    	XMStoreFloat3(&_pos,vpos);
    }
    
    //扫视。是指保持观察方向不变,沿向量right方向从一边平移到还有一边
    void XCamera::strafe(float units)
    {
    	XMVECTOR vpos,vright;
    	vpos=XMLoadFloat3(&_pos);
    	vright=XMLoadFloat3(&_right);
    	// 仅在x,z平面移动
    	if( _cameraType == LANDOBJECT )
    		vpos += XMVectorSet(_right.x, 0.0f, _right.z,0.0f) * units;
    
    	if( _cameraType == AIRCRAFT )
    		vpos += vright * units;
    	XMStoreFloat3(&_pos,vpos);
    }/*
    //飞行模式,升降,指沿着向量up方向的移动
    void XCamera::fly(float units)
    {
    	// 仅在y轴移动
    	if( _cameraType == LANDOBJECT )
    		_pos.y += units;
    
    	if( _cameraType == AIRCRAFT )
    		_pos += _up * units;
    }
    
    void XCamera::pitch(float angle)
    {
    	XMMATRIX T;
    	T=XMMatrixRotationAxis( _right, angle);
    
    	// 绕着right向量。旋转up和look
    	_up=XMVector3TransformCoord(_up,_up, T);
    	_look=XMVector3TransformCoord(_look, T);
    }
    
    void XCamera::yaw(float angle)
    {
    	D3DXMATRIX T;
    
    	//对LANDOBJECT,总是绕着(0,1,0)旋转。

    if( _cameraType == LANDOBJECT ) T=XMMatrixRotationY(angle); //对于aircraft,绕着up向量旋转 if( _cameraType == AIRCRAFT ) T=XMMatrixRotationAxis(_up, angle); // 绕着up或者y轴,旋转right和look _right=XMVector3TransformCoord(_right, T); _look=XMVector3TransformCoord(_look, T); } void XCamera::roll(float angle) { //仅仅对aircraft模式才左roll旋转 if( _cameraType == AIRCRAFT ) { D3DXMATRIX T; T=XMMatrixRotationAxis(_look, angle); // 绕着look向量,旋转up和right _right=XMVector3TransformCoord(_right, T); _up=XMVector3TransformCoord(_up, T); } } */ void XCamera::getViewMatrix(XMMATRIX &V) { XMVECTOR vlook,vup,vright,vpos; vpos=XMLoadFloat3(&_pos); vlook=XMLoadFloat3(&_look); vup=XMLoadFloat3(&_up); vright=XMLoadFloat3(&_right); // 保持view局部坐标系,各轴的彼此正交 vlook=XMVector3Normalize(vlook); // look X right vup=XMVector3Cross(vlook, vright); vup=XMVector3Normalize(vup); vright=XMVector3Cross(vup, vlook); vright=XMVector3Normalize(vright); V=XMMatrixLookAtLH( vpos,vlook, vup); // 生成view矩阵: //float x = -D3DXVec3Dot(&_right, &_pos); //float y = -D3DXVec3Dot(&_up, &_pos); //float z = -D3DXVec3Dot(&_look, &_pos); //(*V)(0,0) = _right.x; (*V)(0, 1) = _up.x; (*V)(0, 2) = _look.x; (*V)(0, 3) = 0.0f; //(*V)(1,0) = _right.y; (*V)(1, 1) = _up.y; (*V)(1, 2) = _look.y; (*V)(1, 3) = 0.0f; //(*V)(2,0) = _right.z; (*V)(2, 1) = _up.z; (*V)(2, 2) = _look.z; (*V)(2, 3) = 0.0f; //(*V)(3,0) = x; (*V)(3, 1) = y; (*V)(3, 2) = z; (*V)(3, 3) = 1.0f; } void XCamera::setCameraType(CameraType cameraType) { _cameraType = cameraType; }


    凝视掉的地方是一个坑。为什么呢。

    以下就要讲XMVECTOR 和XMFloat3的差别

    前者是向量。后者就是一个点结构

    前者支持各种运算。

    差 点  乘 加减

    后者 仅仅能赋值啊什么的。

    是不是特别奇怪。

    由于XMVECTOR

    看源代码

    // Vector intrinsic: Four 32 bit floating point components aligned on a 16 byte 
    // boundary and mapped to hardware vector registers
    #if defined(_XM_SSE_INTRINSICS_) && !defined(_XM_NO_INTRINSICS_)
    typedef __m128 XMVECTOR;
    #else

    128位懂了吧。不能随便玩, 不然会报错 涉及到对齐问题

    上节说了。全局变量和局部变量能够用XMVECTOR 可是类变量不建议用

    偏偏这个摄像机是类变量。

    作死啊。仅仅有设成XMFloat3了

    看源代码

    // 3D Vector; 32 bit floating point components
    typedef struct _XMFLOAT3
    {
        FLOAT x;
        FLOAT y;
        FLOAT z;
    
    #ifdef __cplusplus
    
        _XMFLOAT3() {};
        _XMFLOAT3(FLOAT _x, FLOAT _y, FLOAT _z) : x(_x), y(_y), z(_z) {};
        _XMFLOAT3(CONST FLOAT *pArray);
    
        _XMFLOAT3& operator= (CONST _XMFLOAT3& Float3);
    
    #endif // __cplusplus

    32位的 仅仅能赋值 怎么玩 怎么玩 

    上面摄像机类加凝视了的函数是之前悲剧了的,我以为Float能够做运算。结果悲剧了。

    后来查了一下。 能够用一个转换

    XMVECTOR vpos,vright;
    	vpos=XMLoadFloat3(&_pos);
    	vright=XMLoadFloat3(&_right);
    	// 仅在x,z平面移动
    	if( _cameraType == LANDOBJECT )
    		vpos += XMVectorSet(_right.x, 0.0f, _right.z,0.0f) * units;
    
    	if( _cameraType == AIRCRAFT )
    		vpos += vright * units;
    	XMStoreFloat3(&_pos,vpos);

    看懂了吗 看懂了吗。 先load 把float装到vector局部变量  然后进行运算

    运算完毕后  再store 

    是不是非常烦

    是不是

    没办法。

    眼下我仅仅会这样弄。你嫌烦 直接全局变量吧。

    或者回归dx10math.h 

    废话不说 效果图。

    仅仅改了walk函数。 其它自己改改吧,锻炼下自己

    //(*V)(0,0) = _right.x; (*V)(0, 1) = _up.x; (*V)(0, 2) = _look.x; (*V)(0, 3) = 0.0f;
    	//(*V)(1,0) = _right.y; (*V)(1, 1) = _up.y; (*V)(1, 2) = _look.y; (*V)(1, 3) = 0.0f;
    	//(*V)(2,0) = _right.z; (*V)(2, 1) = _up.z; (*V)(2, 2) = _look.z; (*V)(2, 3) = 0.0f;
    	//(*V)(3,0) = x;        (*V)(3, 1) = y;     (*V)(3, 2) = z;       (*V)(3, 3) = 1.0f;

    对了还有上面这个。原教程是直接这样算的一个矩阵,麻烦吧。

    麻烦吧。 懂不起含义了吧 快看龙书就懂了。

    懂了之后怎么办。还敲这么多??

    V=XMMatrixLookAtLH( vpos,vlook, vup);

    一句话搞定。就不要造轮子了

  • 相关阅读:
    Windows 8 应用的页面导航(1)
    开发 Windows 8 Bing地图应用(6)
    Windows 8 应用的页面导航(2)
    Windows 8 生命周期管理(4)
    删除DataTable重复列,只针对删除其中的一列重复的行
    Silverlight 数据库 Silverlight Database
    广告费用 会计处理及其改进
    Query to Join Delivery Details and MTL Material Table
    SAVEPOINT
    SYNCHRONIZE
  • 原文地址:https://www.cnblogs.com/jhcelue/p/7141917.html
Copyright © 2011-2022 走看看