Directx教程(30) 如何保证渲染物体不会变形
在Directx11教程(6)中, 我们曾经实现过这个功能,但那时是在SystemClass中,处理WM_SIZE时候,重新调用m_Graphics的初始化函数,这样的话,它的成员变量D3D类还有其它几个成员类,都会重新创建,所以我们的场景等于是从头重新渲染。对于静态场景,这没有问题,但是对于动画场景,我们一改变窗口大小,动画就会从头播放,这显然不是我们所希望的。
本章中,我们在D3DClass类中新建一个函数,每次改变窗口大小时候,我们就改变framebuffer大小,然后重新建立目标渲染视图、深度模版视图等等。代码是在myTutorialD3D_23的基础上改写的。
最关键的代码就是这一行:
m_swapChain->ResizeBuffers(1, screenWidth, screenHeight, DXGI_FORMAT_R8G8B8A8_UNORM, 0);
D3Class类中增加的函数为:
bool D3DClass::ResizeBuffer(int screenWidth, int screenHeight)
{
HRESULT result;
//交换链为空直接返回
if(!m_swapChain)
return false;
//窗口最小化时候为0,会创建缓冲失败
if(screenHeight < 1)
screenHeight = 1;
if(screenWidth < 1)
screenWidth = 1;
if(m_renderTargetView)
{
m_renderTargetView->Release();
m_renderTargetView = 0;
}
if(m_depthStencilView)
{
m_depthStencilView->Release();
m_depthStencilView = 0;
}
if(m_depthStencilBuffer)
{
m_depthStencilBuffer->Release();
m_depthStencilBuffer = 0;
}
//改变交换链中后后缓冲大小后,重新创建渲染目标视图
result = m_swapChain->ResizeBuffers(1, screenWidth, screenHeight, DXGI_FORMAT_R8G8B8A8_UNORM, 0);
if(FAILED(result))
{
HR(result);
return false;
}
// 得到交换链中的后缓冲指针.
ID3D11Texture2D* backBufferPtr;
result = m_swapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), (LPVOID*)&backBufferPtr);
if(FAILED(result))
{
HR(result);
return false;
}
// 用后缓冲创建渲染目标视图.
result = m_device->CreateRenderTargetView(backBufferPtr, NULL, &m_renderTargetView);
if(FAILED(result))
{
HR(result);
return false;
}
//释放后缓冲.(引用计数减1)
backBufferPtr->Release();
backBufferPtr = 0;
D3D11_TEXTURE2D_DESC depthBufferDesc;
D3D11_DEPTH_STENCIL_DESC depthStencilDesc;
D3D11_DEPTH_STENCIL_VIEW_DESC depthStencilViewDesc;
D3D11_RASTERIZER_DESC rasterDesc;
D3D11_VIEWPORT viewport;
//创建深度模版视图
// 初始化深度缓冲描述.
// 初始化深度缓冲描述.
ZeroMemory(&depthBufferDesc, sizeof(depthBufferDesc));
//设置深度缓冲描述
depthBufferDesc.Width = screenWidth;
depthBufferDesc.Height = screenHeight;
depthBufferDesc.MipLevels = 1; //对于深度缓冲为1
depthBufferDesc.ArraySize = 1; //对于深度缓冲为1,对于纹理,这2个参数有更多用途
depthBufferDesc.Format = DXGI_FORMAT_D24_UNORM_S8_UINT;
depthBufferDesc.SampleDesc.Count = 1;
depthBufferDesc.SampleDesc.Quality = 0;
depthBufferDesc.Usage = D3D11_USAGE_DEFAULT;
depthBufferDesc.BindFlags = D3D11_BIND_DEPTH_STENCIL;
depthBufferDesc.CPUAccessFlags = 0;
depthBufferDesc.MiscFlags = 0;
// 创建深度缓冲.
result = m_device->CreateTexture2D(&depthBufferDesc, NULL, &m_depthStencilBuffer);
if(FAILED(result))
{
HR(result);
return false;
}
// 初始化深度模版状态描述.
ZeroMemory(&depthStencilDesc, sizeof(depthStencilDesc));
// 设置深度模版状态描述.
depthStencilDesc.DepthEnable = true;
depthStencilDesc.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ALL;//D3D11_DEPTH_WRITE_MASK_ZERO禁止写深度缓冲
depthStencilDesc.DepthFunc = D3D11_COMPARISON_LESS;
depthStencilDesc.StencilEnable = true;
depthStencilDesc.StencilReadMask = 0xFF;
depthStencilDesc.StencilWriteMask = 0xFF;
// 对于front face 像素使用的模版操作操作.
depthStencilDesc.FrontFace.StencilFailOp = D3D11_STENCIL_OP_KEEP;
depthStencilDesc.FrontFace.StencilDepthFailOp = D3D11_STENCIL_OP_INCR;
depthStencilDesc.FrontFace.StencilPassOp = D3D11_STENCIL_OP_KEEP;
depthStencilDesc.FrontFace.StencilFunc = D3D11_COMPARISON_ALWAYS;
// 对于back face像素使用的模版操作模式.
depthStencilDesc.BackFace.StencilFailOp = D3D11_STENCIL_OP_KEEP;
depthStencilDesc.BackFace.StencilDepthFailOp = D3D11_STENCIL_OP_DECR;
depthStencilDesc.BackFace.StencilPassOp = D3D11_STENCIL_OP_KEEP;
depthStencilDesc.BackFace.StencilFunc = D3D11_COMPARISON_ALWAYS;
// 创建深度模版状态,使其生效
result = m_device->CreateDepthStencilState(&depthStencilDesc, &m_depthStencilState);
if(FAILED(result))
{
HR(result);
return false;
}
// 设置深度模版状态.
m_deviceContext->OMSetDepthStencilState(m_depthStencilState, 1);
// 初始化深度模版视图.
ZeroMemory(&depthStencilViewDesc, sizeof(depthStencilViewDesc));
// 设置深度模版视图描述.
depthStencilViewDesc.Format = DXGI_FORMAT_D24_UNORM_S8_UINT;
depthStencilViewDesc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2D;
depthStencilViewDesc.Texture2D.MipSlice = 0;
// 创建深度模版视图.
result = m_device->CreateDepthStencilView(m_depthStencilBuffer, &depthStencilViewDesc, &m_depthStencilView);
if(FAILED(result))
{
HR(result);
return false;
}
// 绑定渲染目标视图和深度缓冲到渲染管线.
m_deviceContext->OMSetRenderTargets(1, &m_renderTargetView, m_depthStencilView);
// 设置光栅化描述,指定多边形如何被渲染.
rasterDesc.AntialiasedLineEnable = false;
rasterDesc.CullMode = D3D11_CULL_BACK;
rasterDesc.DepthBias = 0;
rasterDesc.DepthBiasClamp = 0.0f;
rasterDesc.DepthClipEnable = true;
rasterDesc.FillMode = D3D11_FILL_SOLID; //D3D11_FILL_SOLID
rasterDesc.FrontCounterClockwise = false;
rasterDesc.MultisampleEnable = false;
rasterDesc.ScissorEnable = false;
rasterDesc.SlopeScaledDepthBias = 0.0f;
// 创建光栅化状态
result = m_device->CreateRasterizerState(&rasterDesc, &m_rasterState);
if(FAILED(result))
{
HR(result);
return false;
}
//设置光栅化状态,使其生效
m_deviceContext->RSSetState(m_rasterState);
// 设置视口,显示全部后缓冲内容
viewport.Width = (float)screenWidth;
viewport.Height = (float)screenHeight;
viewport.MinDepth = 0.0f;
viewport.MaxDepth = 1.0f;
viewport.TopLeftX = 0.0f;
viewport.TopLeftY = 0.0f;
// 创建视口
m_deviceContext->RSSetViewports(1, &viewport);
}
// 设置透视投影矩阵
fieldOfView = (float)D3DX_PI / 4.0f;
screenAspect = (float)screenWidth / (float)screenHeight;
// 创建透视投影矩阵.
D3DXMatrixPerspectiveFovLH(&m_projectionMatrix, fieldOfView, screenAspect, m_screenNear, m_screenDepth);
//初始化world矩阵为单位矩阵.
//该矩阵实现局部坐标到世界坐标的转换
D3DXMatrixIdentity(&m_worldMatrix);
// 创建正交投影矩阵,主要用来实施2D渲染.
D3DXMatrixOrthoLH(&m_orthoMatrix, (float)screenWidth, (float)screenHeight, m_screenNear, m_screenDepth);
注意:m_screenNear,m_screenDepth是D3DClass增加的两个成员变量,在初始化函数中,它们被用来保存screenNear和screenDetph。
另外一点小变动就是在GraphicsClass中把m_D3D设置为public,还有就是SystemClass中
if(m_Graphics)
{
bool result = m_Graphics->m_D3D->ResizeBuffer(screenWidth, screenHeight);
if(!result)
{
return false;
}
}
完整的代码请参考:
工程文件myTutorialD3D11_26
代码下载:
http://files.cnblogs.com/mikewolf2002/myTutorialD3D11_26.zip
Directx教程(30) 如何保证渲染物体不会变形的更多相关文章
- 【Visual C++】游戏开发五十六 浅墨DirectX教程二十三 打造游戏GUI界面(一)
本系列文章由zhmxy555(毛星云)编写,转载请注明出处. 文章链接:http://blog.csdn.net/poem_qianmo/article/details/16384009 作者:毛星云 ...
- [译]Vulkan教程(30)深度缓存
[译]Vulkan教程(30)深度缓存 Depth buffering 深度缓存 Introduction 入门 The geometry we've worked with so far is pr ...
- Directx教程(22) 简单的光照模型(1)
原文:Directx教程(22) 简单的光照模型(1) 在前面的教程中,我们在顶点属性中直接给顶点赋颜色,这样生成的三维物体缺乏真实感,如下图中两个立方体,左边的是通过光照生成物体表面颜色的 ...
- Directx教程(27) 简单的光照模型(6)
原文:Directx教程(27) 简单的光照模型(6) 从myTutorialD3D11_15到myTutorialD3D11_19的工程中,我们都只有一个光源,光源的位置在LightCla ...
- Directx教程(23) 简单的光照模型(2)
原文:Directx教程(23) 简单的光照模型(2) 在工程myTutorialD3D11_16中,我在文件light.vs中定义了一个材质光源属性常量缓冲. //const buffer最好 ...
- CSharpGL(30)用条件渲染(Conditional Rendering)来提升OpenGL的渲染效率
CSharpGL(30)用条件渲染(Conditional Rendering)来提升OpenGL的渲染效率 当场景中有比较复杂的模型时,条件渲染能够加速对复杂模型的渲染. 条件渲染(Conditio ...
- PS网页设计教程——30个优秀的PS网页设计教程的中文翻译教程
PS网页设计教程--30个优秀的PS网页设计教程的中文翻译教程 作为编码者,美工基础是偏弱的.我们可以参考一些成熟的网页PS教程,提高自身的设计能力.套用一句话,"熟读唐诗三百首,不会作 ...
- Directx教程(29) 简单的光照模型(8)
原文:Directx教程(29) 简单的光照模型(8) 现在我们新建一个工程myTutorialD3D_23,在这个工程中,对前面一章的代码进行一些整理: 1.我们在顶点属性中增加材质的的漫 ...
- Directx教程(28) 简单的光照模型(7)
原文:Directx教程(28) 简单的光照模型(7) 现实生活中的点光源都是随着距离衰减的,比如一个电灯泡在近处会照的很亮,远处光线就很弱.本节中我们在前面光公式的基础上,再给漫反射和 ...
随机推荐
- vue.js_11_路由的2中参数传递和路由的嵌套
1.以?的形式传递参数 <router-link to="/login?id=10&name=zs">登录</router-link> 发送参数 ...
- utils03_clone远程仓库
1.Bash here 克隆方式 复制要克隆远程仓库的SSH或者HTTPS 使用Bash here克隆文件 2.使用git同步
- BM线性递推
#include<bits/stdc++.h> using namespace std; #define rep(i,a,n) for (int i=a;i<n;i++) #defi ...
- 转:PLL 锁相环
原地址:http://fangjian0518.blog.163.com/blog/static/559196562011210103455430/ PLL的作用? 答:LPC2000系列ARM内部 ...
- PhoneInfoga---用于电话号码的信息收集和OSINT侦察工具
PhoneInfoga 是仅使用免费资源扫描电话号码的最先进工具之一. 目标是首先在任何国际电话号码上收集标准信息, 如国家,地区,运营商和线路类型,并且准确性非常高. 然后在搜索引擎上搜索足迹以尝试 ...
- .h头文件 .lib动态链接库文件 .dll 动态链接库
(1).h头文件是编译时必须的,lib是链接时需要的,dll是运行时需要的. 附加依赖项的是.lib 不是.dll 若生成了DLL ,则肯定也生成 LIB文件 如果要完成源代码的编译和链接,有头文件和 ...
- java基础之自定义单链表练习
一.单链表 1.单链表是一种链式存取的数据结构,用一组地址任意的存储单元存放线性表中的数据元素.链表中的数据是以结点来表示的,每个结点的构成:元素(数据元素的映象) + 指针(指示后继元素存储位置), ...
- Mybatis编写初始化Dao代码
第一步:创建User实体类(POJO) package com.xu.pojo; import java.util.Date; /** * * @author 徐亮亮 * Title: User * ...
- 2019-8-8-WPF-非客户区的触摸和鼠标点击响应
title author date CreateTime categories WPF 非客户区的触摸和鼠标点击响应 lindexi 2019-08-08 16:48:31 +0800 2019-07 ...
- Leetcode89. Gray Code格雷编码
给定一个代表编码总位数的非负整数 n,打印其格雷编码序列.格雷编码序列必须以 0 开头. 示例 1: 输入: 2 输出: [0,1,3,2] 解释: 00 - 0 01 - 1 11 - 3 10 - ...