1. 程式人生 > >Directx11地形渲染教程一之FirstCamera(第一人稱相機)

Directx11地形渲染教程一之FirstCamera(第一人稱相機)

#include"FirstCameraClass.h"

FirstCameraClass::FirstCameraClass()
{
	//初始化第一人稱相機的引數,剛開始相機是位於中間的
	mPosition = XMFLOAT3(0.f, 0.0f, -5.0f);
	mRight = XMFLOAT3(1.0f, 0.0f, 0.0f);
	mUp = XMFLOAT3(0.0f, 1.0f, 0.0f);
    mLook= XMFLOAT3(0.0f, 0.0f, 1.0f);
}

FirstCameraClass::FirstCameraClass(const FirstCameraClass&other)
{

}

FirstCameraClass::~FirstCameraClass()
{

}

//相機位置
void FirstCameraClass::SetPosition(float x, float y, float z)
{
	mPosition.x = x;
	mPosition.y = y;
	mPosition.z = z;
}


void FirstCameraClass::SetPosition(const XMFLOAT3& v)
{
	mPosition = v;
}


XMFLOAT3 FirstCameraClass::GetPosition()const
{
	return mPosition;
}

XMVECTOR FirstCameraClass::GetPositionXM()const
{
	return XMLoadFloat3(&mPosition);
}



//獲取相機的基礎向量(Up,Look,Right)
XMFLOAT3 FirstCameraClass::GetUp()const
{
	return mUp;
}
XMVECTOR FirstCameraClass::GetUpXM()const
{
	return XMLoadFloat3(&mUp);
}


XMFLOAT3 FirstCameraClass::GetLook()const
{
	return mLook;
}
XMVECTOR FirstCameraClass::GetLookXM()const
{
	return XMLoadFloat3(&mLook);
}


XMFLOAT3 FirstCameraClass::GetRight()const
{

	return mRight;
}

XMVECTOR FirstCameraClass::GetRightXM()const
{
	return XMLoadFloat3(&mRight);
}

//獲取相機變換矩陣
XMMATRIX FirstCameraClass::GetViewMatrix()const
{
	return mViewMatrix;
}

//通過相機在世界空間的位置,目標點,以及上向量來定義相機變換矩陣
void FirstCameraClass::LookAt(FXMVECTOR pos, FXMVECTOR target, FXMVECTOR worldUp)
{
	
	XMVECTOR Look = XMVectorSubtract(target, pos);
	XMVECTOR Up = worldUp;
	XMVECTOR Right = XMVector3Cross(Up, Look);
	Up = XMVector3Cross(Look, Right);

	//規格化三個先來
	XMVector3Normalize(Look);
	XMVector3Normalize(Up);
	XMVector3Normalize(Right);

	//將引數存入Camera類中
	XMStoreFloat3(&mPosition, pos);
	XMStoreFloat3(&mLook, Look);
	XMStoreFloat3(&mUp, Up);
	XMStoreFloat3(&mRight, Right);

}


//往相機座標系Look的方向前進或者後退,然後此時Look,Up,Right都不改變,僅僅是位置在改變
void FirstCameraClass::Walk(float d)
{
	//mPosition+=d*mLook
	//XMVectorReplicate返回的是XMVECTOR(d,d,d,d)
	XMVECTOR s = XMVectorReplicate(d);
	XMVECTOR l = XMLoadFloat3(&mLook);
	XMVECTOR p = XMLoadFloat3(&mPosition);
    
	//XMVectorMultiplyAdd(v1,v2,v3)=v1*v2+v3
	XMStoreFloat3(&mPosition, XMVectorMultiplyAdd(s, l, p));
}

//往相機座標系Right方向前進或者後退,然後此時Look,Up,Right都不改變,僅僅是位置在改變
void FirstCameraClass::Strafe(float d)
{
	//mPosition+=d*mRight
	//XMVectorReplicate返回的是XMVECTOR(d,d,d,d)
	XMVECTOR s = XMVectorReplicate(d);
	XMVECTOR r = XMLoadFloat3(&mRight);
	XMVECTOR p = XMLoadFloat3(&mPosition);

	//XMVectorMultiplyAdd(v1,v2,v3)=v1*v2+v3
	XMStoreFloat3(&mPosition, XMVectorMultiplyAdd(s, r, p));
}

//相機上下的移動是位置在Y值上的改變,而Look,Up,Right都不改變,僅僅是位置在改變
void FirstCameraClass::UpDown(float d)
{

	//mPosition+=d*up
	//XMVectorReplicate返回的是XMVECTOR(d,d,d,d)
	XMVECTOR s = XMVectorReplicate(d);
	XMVECTOR up = XMVectorSet(0.0f, 1.0f, 0.0f,0.0f);
	XMVECTOR p = XMLoadFloat3(&mPosition);

	//XMVectorMultiplyAdd(v1,v2,v3)=v1*v2+v3
	XMStoreFloat3(&mPosition, XMVectorMultiplyAdd(s, up, p));
}


//Look和Up向量繞相機座標系的right向量進行旋轉,此時look和up向量改變,而right和poisiton不改變
void FirstCameraClass::Pitch(float angle)
{
	XMMATRIX R = XMMatrixRotationAxis(XMLoadFloat3(&mRight), angle);
	XMStoreFloat3(&mLook, XMVector3TransformNormal(XMLoadFloat3(&mLook), R));
	XMStoreFloat3(&mUp, XMVector3TransformNormal(XMLoadFloat3(&mUp), R));
} 

//繞世界座標系的Y軸進行旋轉(而非相機座標系的Up向量,這點容易受到慣性思維而誤解,實在無法理解就用人的視角在現實世界是怎麼旋轉的粒子解釋),look,up,right繞Y軸進行旋轉,位置不變
void FirstCameraClass::RotateY(float angle)
{
	XMMATRIX R = XMMatrixRotationY(angle);
	XMStoreFloat3(&mLook, XMVector3TransformNormal(XMLoadFloat3(&mLook), R));
	XMStoreFloat3(&mUp, XMVector3TransformNormal(XMLoadFloat3(&mUp), R));
	XMStoreFloat3(&mRight, XMVector3TransformNormal(XMLoadFloat3(&mRight), R));
}

void FirstCameraClass::UpdateViewMatrix()
{
	XMVECTOR R = XMLoadFloat3(&mRight);
	XMVECTOR U = XMLoadFloat3(&mUp);
	XMVECTOR L = XMLoadFloat3(&mLook);
	XMVECTOR P = XMLoadFloat3(&mPosition);

	//正交規格化right,look,up
	
	//規格化look向量
	L = XMVector3Normalize(L);
	
	//U=look(X)right
	U = XMVector3Normalize(XMVector3Cross(L, R));

	//R=up(X)look
	R= XMVector3Normalize(XMVector3Cross(U, L));

	//求出相機變換矩陣某些引數裡面的點積
	float x = -XMVectorGetX(XMVector3Dot(P, R));
	float y = -XMVectorGetX(XMVector3Dot(P, U));
	float z = -XMVectorGetX(XMVector3Dot(P, L));

	//第一列
	mViewMatrix(0, 0) = mRight.x;
	mViewMatrix(1, 0) = mRight.y;
	mViewMatrix(2, 0) = mRight.z;
	mViewMatrix(3, 0) = x;

	//第二列
	mViewMatrix(0, 1) = mUp.x;
	mViewMatrix(1, 1) = mUp.y;
	mViewMatrix(2, 1) = mUp.z;
	mViewMatrix(3, 1) = y;

	//第三列
	mViewMatrix(0, 2) = mLook.x;
	mViewMatrix(1, 2) = mLook.y;
	mViewMatrix(2, 2) = mLook.z;
	mViewMatrix(3, 2) = z;

	//第四列
	mViewMatrix(0, 3) = 0;
	mViewMatrix(1, 3) = 0;
	mViewMatrix(2, 3) = 0;
	mViewMatrix(3, 3) = 1.0f;
}


XMMATRIX FirstCameraClass::GetBaseViewMatrix()const
{
	return mBaseViewMatrix;
}

//更新相機變換矩陣
void FirstCameraClass::UpdateBaseViewMatrix()
{
	//上向量,位置向量,觀察向量
	XMVECTOR Up, Postion, LookAt;

	//設定相機的位置
	Postion = XMVectorSet(0.0f, 0.0f, -1.0f, 0.0f);
	LookAt = XMVectorSet(0.0f, 0.0f, 1.0f, 0.0f);
	Up = XMVectorSet(0.0f, 1.0f, 0.0f, 0.0f);

	//最後建立ViewMatrix
	mBaseViewMatrix = XMMatrixLookAtLH(Postion, LookAt, Up);
}


相關推薦

Directx11地形渲染教程FirstCamera(第一人稱相機)

#include"FirstCameraClass.h" FirstCameraClass::FirstCameraClass() { //初始化第一人稱相機的引數,剛開始相機是位於中間的 mPosition = XMFLOAT3(0.f, 0.0f, -5.0f); mRight = XMFLOAT

Android Studio 使用教程()怎麼新建一個java介面

android開發androidstudio怎麼新建一個介面 右鍵點選你想新建的目錄,選擇"New"->"Java Class" 接著會彈出一個對話方塊: 在Kind中選

我的Unity 3D旅——第一人稱射擊遊戲(2)

三、主角 因為是第一人稱射擊遊戲,所以主角在視野中是不可見的,但我們依然需要為主角建立碰撞體並控制其移動。 1. 在選單欄選擇【GameObject】→【Create Empty】建立一個空的遊戲體,在Inspector視窗將它的Tag設為Player,這就是我們的主角。

我的Unity 3D旅——第一人稱射擊遊戲(3)

四、敵人 1. 自動尋路。光有一個主角,我們的第一人稱射擊遊戲肯定是沒法玩的,所以還需要新增敵人。而為了遊戲更具有可玩性,敵人需要能夠追擊主角並攻擊主角。在很多遊戲中,經常需要敵人在複雜的地形環境中追著主角跑。而場景中經常會存在很多障礙物,這就AI要能夠找出到達目標地點的最

Unreal Engine 4 —— 在UE4中實現真實第一人稱相機

這篇部落格來自於Fabrice Piquet,翻譯工作已獲得作者授權,原文傳送門。 我決定分享一下我在當前專案中處理真實第一人稱相機的方法。針對真實第一人稱視角,目

基於Unity3D的相機功能的實現(三)——第一人稱相機(FPS)

在遊戲開發中,角色視野跟隨滑鼠位置即第一人稱相機(FPS)是一個很常見的需求,我們今天來實現該功能。 掛載到相機上即可,程式碼如下: using UnityEngine; using System.

Directx11教程AlphaMap(混合貼圖)

先看看本次教程的構架吧, 構架其實與前兩個教程差不多,就是前兩個教程的紋理資源為兩個,這次變為三個. 一,AlphaMap(混合貼圖)的簡介. AlphaMap(混合貼圖)用於實現貼圖的混合效果,其實AlphaMap跟黑白色的光照貼圖差不多, 如圖:        

Directx11教程2D渲染

這個教程沿用了D3D11紋理那節教程的架構,再次貼出來看看 其中這次:ModelClass int mScrrenWidth, mScrrenHeight; int mBitmapWidth, mBitmapHeight; 增加了這四個私有屬性 先講一講W

fiddler使用教程()

瀏覽器設置 lte -s 選擇 amp 過濾器 技術 htm ron 一. 什麽是fiddler&它可以做什麽 fiddler是位於客戶端和服務器端的HTTP代理,也是目前最常用的http抓包工具之一。它能夠記錄客戶端和服務器之間的所有HTTP請求,可以針對特定的

【vue大師晉級第一集:Vue基礎】第6章——條件渲染

條件渲染 v-if 在字串模板中,比如 Handlebars,我們得像這樣寫一個條件塊: <!-- Handlebars 模板 --> {{#if ok}} <h1>Yes</h1> {{/if}} 在 Vue 中,我們使用 v-if

()MFC學習建立第一個視窗

環境:windows10+vs2017 需要兩個類: 1,CMyWnd,繼承自CFrameWnd(視窗框架類,視窗有就是這個類的例項化物件) 2,CMyApp,繼承自CWinApp(app類,在這個類中的InitInstance方法中例項化視窗,初始化自己的視窗型別成員變數) 使

Android 學習第一行程式碼》第二版 筆記(九)探究碎片(

一、碎片 1. 碎片是什麼: 碎片(Fragment)是一種可以嵌入在活動當中的UI片段,能讓程式更加合理和充分地利用大螢幕的空間。(可以理解成迷你型活動) 2. 簡單用法: 在一個活動當中新增兩個碎片,並讓這兩個碎片平分活動空間。 1.)效果圖(沒錢買平板,CPU不支援

Android 學習第一行程式碼》第二版 筆記(十)詳解廣播機制(

一、廣播機制簡介 1. 四大元件之一 2. Android 提供了一套完整的API,允許應用程式自由地傳送和接收廣播。 A. 傳送廣播藉助Intent B. 接收廣播藉助廣播接收器(Broadcast Receiver) 3. 廣播型別: A. 標準廣播: 完全非同步執行

Okhttp3簡單使用教程()

一,HTTP請求、響應報文格式 要弄明白網路框架,首先需要先掌握Http請求的,響應的報文格式。 HTTP請求報文格式: HTTP請求報文主要由請求行、請求頭部、請求正文3部分組成. request.png   請求行:由請求方法,URL,協議版本三部分

Directx11基礎教程VertexShader,PixelShader,buffer

一,看本節教程前應該掌握:      (1)D3D11基礎教程二之D3D11初始化      (2)瞭解3D渲染流水線的知識,如世界變換,相機變換,透視投影變換,視口變換,光柵化,線性插值,gouraud著色等,最好具備一定的圖形學基礎,我推薦一本書<3D遊戲程式設計大

OpenLayers官方示例詳解十在自定義canvas元素上渲染OpenLayers的幾何圖形(Render geometries to a canvas)

目錄 一、示例簡介 二、程式碼詳解 一、示例簡介     這個示例展示瞭如何將OpenLayers的幾何圖形渲染到任意的canvas元素上。 二、程式碼詳解     ol.render.toContext()方法能夠將任意ca

IOS Swift教程() -入門語法(常量、變數)

Swift常量、變數的定義和使用 眾所周知大家在使用其他語言時也有常量和變數的區分,因此swift也不列外. 常量和變數把一個名字(比如maxNumber or minNumber)和一個指定型別的值(比如整形10,浮點型10.0,字串”hello Worl

每天一個演算法尋找第一個只出現次的數

雜湊技術是在記錄的儲存位置和它的關鍵字之間建立一個確定的對應關係f,使得每個關鍵字key 對應一個儲存位置f (key)。查詢時,根據這個確定的對應關係找到給定值key 的對映f (key) ,若查詢

ASP.NET MVC 重點教程週年版 第八回 Helper演化

凡事出現必有原因 就像Filter,它是為了解決在一類的Action之前或之後執行統一的程式碼而產生的。 而Helper則是為了方便View的開發而產生的。 下面我們來解決幾個問題,來看看Helper是怎麼演化出來的。 起 題目:如何在View中寫一個超級連線連線到主頁? 這個問題看起來很好回答:

中文程式碼示例Vuejs入門教程()

為了檢驗中文命名在主流框架中的支援程度, 在vuejs官方入門教程第一部分的示例程式碼中儘量使用了中文命名. 所有演示都在本地測試通過, 原始碼在這裡. 下面省略了很多原教程的說明內容, 而著重於程式碼示例本身. 歡迎問題/批評. 宣告式渲染 {% raw %} <div id