Direct-X学习笔记--三维摄像机

Direct-X学习笔记--深度缓存 今天来学习一下深度测试,不过这个东东貌似暂时就是了解一下原理啦,因为DX默认是打开深度测试的,即我们不需要额外进行设置就可以使用深度测试的功能,不过这个还是有必要了解一下,一是对DX的流程更加了解,二是我们可以手动设置深度测试的参数以及函数,达到一些自己想要实现的效果。 一.简介 三维的世界中,有各种物体,而这些物体难免会有遮挡,而且同一个物体不同部分也会有遮挡的关系,要想表现出来更加 阅读详情

一.介绍

哇!到了传说中的3D摄像机啦!

之前我们写的东东,都是观察点不动,通过世界变换让东西动,今天,通过三维摄像机我们就可以改变我们的观察点,观察方向,随意在三维空间中驰骋。之前我们所设定的视角都是通过D3DXMatrixLookAtLH这个函数,通过几个设定好的向量,将视角初始化的,而在程序真正运行时,视角就不再改变了,而这次,我们要实时的生成视角变换矩阵,实时的改变我们的视角,我们所谓的摄像机就是这个原理。

我们通过一个类来封装摄像机,这个类主要的字段就是用四个分量:右分量(rightvector)、上分量(up vector)、观察分量(lookvector)和位置分量(position vector),来确定一个摄像机相对于世界坐标系的位置和朝向。并根据这四个分量计算出一个取景变换矩阵,然后通过取景变换(VIEWTRANSFORM)实现改变视角。


通过这些分量,我们可以确定摄像机的位置和朝向。操作有平移和旋转,那么一共就有6中操作:

(1)沿着观察分量平移(前进后退)

(2)沿着观察分量旋转(左右翻滚)

(3)沿着右分量平移(左右移动)

(4)沿着右分量旋转(朝上下看)

(5)沿着上分量平移(上下移动)

(6)沿着上分量旋转(朝左右看)


二.操作

这里,我们把摄像机的功能封装成一个类,这样,我们就可以非常方便的使用摄像机的功能,而不需要写一大堆代码啦。

要用到几个函数:

(1)D3DXVec3Normalize 将向量单位化
(2)D3DXVec3Cross        叉乘,第二个,第三个参数为参加运算的向量,生成的结果为垂直与两个向量构成平面的向量,由一个参数输出结果
(3)D3DXVec3Dot  点乘,结果返回
(4)D3DXMatrixRotationAxis 创建一个绕任意轴旋转一定角度的矩阵,第一个参数为输出矩阵,第二个参数为轴,第三个参数为角度
(5)D3DXVec3TransformCoord 根据矩阵变换一个向量,第一个参数为输出向量,第二个参数为被变化向量,第三个参数为矩阵
(6)D3DXVec3Length      获得向量的长度,返回

取景变换所解决的其实就是世界坐标系中的物体在以摄像机为中心的坐标系中如何来表示的问题。这就是说,需要将世界坐标系中的物体随着摄像机一起进行变换,这样摄像机的坐标系就与世界坐标系完全重合了。摄像机其实也相当于三维世界中的一个物体,和我们绘制的东西一样。我们把摄像机移动到世界坐标系的原点,然后让右向量与世界坐标系的x方向重合,上向量与世界坐标系的y方向重合,观察向量与世界坐标系的z方向重合,这样,我们就能生成一个矩阵。
当然这个矩阵感觉比较麻烦,我们照抄下来,生成即可。

计算取景变换矩阵的方法如下:
void CCamera::CalculateViewMatrix(D3DXMATRIX *pMatrix)
{
	//规范化三个向量使之成为正交矩阵

	//规范化观察向量
	D3DXVec3Normalize(&m_vLookVector, &m_vLookVector);
	//使上向量与观察向量垂直
	D3DXVec3Cross(&m_vUpVector, &m_vLookVector, &m_vRightVector);
	//规范化上向量
	D3DXVec3Normalize(&m_vUpVector, &m_vUpVector);
	//右向量与上向量垂直
	D3DXVec3Cross(&m_vRightVector, &m_vUpVector, &m_vLookVector);
	//规范化右向量
	D3DXVec3Normalize(&m_vRightVector, &m_vRightVector);

	//创建取景变换矩阵
	pMatrix->_11 = m_vRightVector.x;
	pMatrix->_12 = m_vUpVector.x;
	pMatrix->_13 = m_vLookVector.x;
	pMatrix->_14 = 0.0f;

	pMatrix->_21 = m_vRightVector.y;
	pMatrix->_22 = m_vUpVector.y;
	pMatrix->_23 = m_vLookVector.y;
	pMatrix->_24 = 0.0f;

	pMatrix->_31 = m_vRightVector.z;
	pMatrix->_32 = m_vUpVector.z;
	pMatrix->_33 = m_vLookVector.z;
	pMatrix->_34 = 0.0f;

	pMatrix->_41 = -D3DXVec3Dot(&m_vRightVector, &m_vCameraPosition);
	pMatrix->_42 = -D3DXVec3Dot(&m_vUpVector, &m_vCameraPosition);
	pMatrix->_43 = -D3DXVec3Dot(&m_vLookVector, &m_vCameraPosition);
	pMatrix->_44 = 1.0f;
}
这样,我们就可以根据摄像机类中的四个向量(相机位置,上分量,右分量,观察分量)获得取景变换的矩阵,通过指针传递参数。这样,我们实时的根据这个矩阵进行取景变换,就可以得到实时的画面情况。而我们在逻辑部分要做的就是改变摄像机类中的各个分量即可。

整个摄像机类的设计如下:

.h文件
/************************************************************************/
/* 封装一个摄像机类                                                     */
/************************************************************************/
#ifndef __CCAMERA_H_
#define __CCAMERA_H_
#include "stdafx.h"
#pragma once
class CCamera
{
private:
	//成员变量
	IDirect3DDevice9* m_pDevice;		//D3D设备对象
	D3DXVECTOR3 m_vRightVector;	        //右分量向量
	D3DXVECTOR3 m_vUpVector;			//上分量向量
	D3DXVECTOR3 m_vLookVector;			//观察分量向量
	D3DXVECTOR3 m_vCameraPosition;		//摄像机位置
	D3DXVECTOR3 m_vTargetPosition;		//观察目标位置
	D3DXMATRIX  m_matView;				//取景变换矩阵
	D3DXMATRIX  m_matProj;				//投影变换矩阵

public:
	CCamera(IDirect3DDevice9* pDevice);
	~CCamera(void);

	//计算取景变换矩阵
	void CalculateViewMatrix(D3DXMATRIX *pMatrix);
	//获得投影矩阵
	void GetProjectionMatrix(D3DXMATRIX* pMatrix){*pMatrix = m_matProj;}
	//获得当前摄像机位置向量
	void GetCameraPosition(D3DXVECTOR3* pVector){*pVector = m_vCameraPosition;}
	//返回当前观察向量
	void GetLookVector(D3DXVECTOR3* pVector){*pVector = m_vLookVector;}
	//设置摄像机观察位置向量(默认参数为NULL)
	void  SetTargetPosition(D3DXVECTOR3* pVector = NULL);
	//设置摄像机所在位置向量(默认参数为NULL)
	void SetCameraPosition(D3DXVECTOR3* pVector = NULL);
	//设置取景变换矩阵(默认参数为NULL)
	void SetViewMatrix(D3DXMATRIX* pMatrix = NULL);
	//设置投影变换矩阵(默认参数为NULL)
	void SetProjectionMartix(D3DMATRIX* pMatrix = NULL);


	
	//沿着right分量平移
	void MoveAlongRightVec(float fUnits);
	//沿着up分量平移
	void MoveAlongUpVec(float fUnits);
	//沿着look分量平移
	void MoveAlongLookVec(float fUnits);


	//沿着right分量旋转
	void RotationRightVec(float fAngle);
	//沿着up分量旋转
	void RotationUpVec(float fAngle);
	//沿着look分量旋转
	void RotationLookVec(float fAngle);
};

#endif // !__CCAMERA_H_


.cpp文件:
#include "stdafx.h"
#include "Camera.h"


CCamera::CCamera(IDirect3DDevice9* 
摄像机标定 阅读详情

相关推荐

DirectX学习笔记(十四):三维地形系统的实现

本系列文章由zhmxy555(毛星云)编写,转载请注明出处。   文章链接: http://blog.youkuaiyun.com/zhmxy555/article/details/8685546 作者:毛星云(浅墨)    邮箱: happylifemxy@163.com      上个星期浅墨写的介绍三维摄像机的文章和示例程序放出以后,大家似乎都表现出了很高涨的热情,

lishuzhai的专栏 5525

HttpClient vs OkHttpClient:哪个更适合你的Java项目?(附性能对比实测)

本文深度对比了Apache HttpClient与OkHttpClient在Java项目中的性能表现与适用场景。通过实际性能测试,OkHttp在连接复用、高并发吞吐量及内存占用方面表现更优,尤其适合现代微服务与Spring生态。HttpClient则凭借其高度可配置性,在需要精细控制HTTP协议细节的场景中更具优势。文章提供了清晰的选型指南,帮助开发者根据项目需求做出最佳决策。

onion的博客 508

如何让 RTX 5090 开启 PCIE P2P 以加速多卡通信

RTX 5090 基于新的 Blackwell 架构。NVIDIA 出于对某些主板兼容性(如 IOMMU、Resizable BAR 策略)的保守考虑,**屏蔽了 5090 的 BAR1 P2P 功能**。 我们需要通过 Patch 驱动源码,强制开启这一隐藏功能。 开启 P2P 后,PyTorch 的集合通信算子(Multi-GPU 训练的核心)延迟显著降低,**All-Reduce 甚至降低了 60% 以上**。

Hi20240217的博客 1712

VLA、世界模型与端到端在智驾中的本质关系与工程落地

世界模型并非3D重建,而是对环境状态转移函数的可微分建模;VLA不是视觉+语言+动作的简单拼接,核心在于跨模态语义对齐。二者共同支撑具身智能系统实现从感知到行动的闭环推演,其技术价值体现在长尾场景泛化能力提升与决策延迟降低。在自动驾驶领域,真实量产方案均采用VLA架构作为多模态感知基础,嵌入轻量级世界模型以支持反事实轨迹推演,并通过WA硬件封装保障实时性,最终由端到端控制层完成像素到扭矩的语义贯通。这种混合架构已成L2+/L3智驾系统的工程共识。

weixin_34163553的博客 365

华北理工大学以升实验班蓝桥杯选拔赛题解

文章目录华北理工大学以升实验班蓝桥杯选拔赛题解A:期末考试题目描述题目讲解代码B:月份题目描述题目讲解代码C:打饭题目描述题目讲解代码D : 正弦波信号题目描述题目讲解代码E : 亲爱的长方形题目描述题目讲解代码F:挖金子题目描述题目讲解代码G : 金金的游戏题目描述题目讲解代码H : 区间和题目描述题目讲解代码详细视频讲解请关注华北理工大学b站账号。 华北理工大学以升实验班蓝桥杯选拔赛题解 A:期末考试 题目描述 Description 期末考试过去许多天了,如今成绩都出来了,那么现在让我们对成绩我分个类

Qq1739206233的博客 1127

在Visual Studio中搭建Dynamo Python开发环境,效率飞一般的增长

在Visual Studio中搭建Dynamo Python开发环境,效率飞一般的增长

BIM的乐趣 1729

第 5 篇:责任链模式 (Chain of Responsibility) —— 协议栈的流水线

本文介绍了责任链模式在嵌入式通信协议解析中的应用。针对传统"面条式"代码维护困难的问题,提出将各协议解析器解耦为独立处理单元,通过链表形式串联。文章详细展示了模式实现:定义抽象处理者接口、实现具体协议处理器、构建链表管理器。该方案具有内存占用低(O(1)栈空间)、可动态扩展、支持优先级调整等优势,并探讨了性能优化策略及动态插件系统等扩展应用,为嵌入式通信协议处理提供了清晰的架构方案。

一路往蓝-Anbo 的博客 176

基于STM32设计的太阳能智慧路灯_444

本文设计并实现了一种基于 STM32 的太阳能智慧路灯系统。系统以 STM32F103C8T6 单片机为核心,集成温湿度检测、空气质量检测、环境光照检测、行人检测和路灯故障检测等功能,实现对路灯运行环境和工作状态的实时感知。

460

STM32 BOOTLOADER配置以及APP跳转实现(裸机)

Bootloader是硬件启动的引导程序,是运行操作系统的前提。在操作系统内核或用户应用程序运行之前运行的一段小代码。对硬件进行相应的初始化和设定,最终为操作系统准备好环境。APP就是我们的应用程序,经过硬件引导程序之后跳转到系统程序运行。

吻等离子的博客 3355

ET2012新版免狗免安装绿色软件

ET2012新版免狗免安祖昂绿色软件。,新界面,新视觉,

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

VC中sqlite的使用

在VC中对sqlite的使用,实现数据库大批数据的快速插入,读取数据库中的数据在ListCtrl中显示

大中型超市收银系统(可直接运行)

光步前台收银系统系统功能:商品销售、商品退货、挂单、收银员权限、会员销售、单品取消、整单取消、商品查询、脱机销售、脱机数据上传,基本资料下载,开钱箱、小票打印、收款结算,支持多币种付款方式(现金、储值卡、礼券、微信等),支持多种促销。运行环境:.net 4.0登陆信息用户名:1001 密码:123456内置商品信息,商品编码可输入00001000 - 00010000,测试效果相关功能键F5 结算 F9挂单 F11商品查询 F8退货 Insert单品取消 Del整单取消 F12开钱箱F2 会员 Ctrl+Z退出系统 Home 锁屏 相关源码待公开

上一篇: Direct-X学习笔记--X模型导入
下一篇: VS调试技巧
puppet_master
puppet_master 领域专家: C/C++技术领域 领域专家: C/C++技术领域
博客等级 码龄12年 2695粉丝 161原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值