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) 现实生活中的点光源都是随着距离衰减的,比如一个电灯泡在近处会照的很亮,远处光线就很弱.本节中我们在前面光公式的基础上,再给漫反射和 ... 
随机推荐
- 深入protoBuf
			ProtoBuf 官方文档翻译 [翻译] ProtoBuf 官方文档(一)- 开发者指南 [翻译] ProtoBuf 官方文档(二)- 语法指引(proto2) [翻译] ProtoBuf 官方文档( ... 
- MFC 双缓存绘图
			在SDI应用程序中,当我们需要时刻动态刷新界面的时候,如果我们一直使用,UpdateAllView()那么就会出现屏幕不停闪烁.闪屏非常严重,特别是一直在动态刷新的时候.并且在闪屏的过程中 我们根本就 ... 
- independent set 1
			independent set 1 时间限制:C/C++ 1秒,其他语言2秒空间限制:C/C++ 102400K,其他语言204800K64bit IO Format: %lld 题目描述 Note: ... 
- Leetcode543.Diameter of Binary Tree二叉树的直径
			给定一棵二叉树,你需要计算它的直径长度.一棵二叉树的直径长度是任意两个结点路径长度中的最大值.这条路径可能穿过根结点. 示例 : 给定二叉树 1 / \ 2 3 / \ 4 5 返回 3, 它 ... 
- LUOGU P1779 魔鬼杀手_NOI导刊2010提高(03)
			传送门 解题思路 背包,首先先用aoe都打残然后单伤补刀,用f[i]表示AOE打了i的伤害的最小花费,g[i]表示单伤打了i的伤害的最小花费. 代码 #include<iostream> ... 
- iscroll的滑动效果
			<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ... 
- PHP--年龄转生日、生日转年龄
			/** * 年龄转生日(模糊结果) * @parameter int age(年龄) * @parameter string symbol(分隔符) * @return string (yyyy*mm ... 
- xampp中tomcat服务器无法启动
			xampp中的Tomcat服务器无法启动的问题... 我的Java中自己安装了Tomcat服务器,webstorm中还有一个php服务器,,,xampp中的能不能用我就不需要去理会了...反正tomc ... 
- $\mathcal{Miemeng}$的病态码风计划
			晚上困的要命,先写个码风计划提提神. 计划目标 抵制无理压行. 抵制不可读代码. 倡导代码艺术化,分层化 具体的一些细节和展示 1>整体 首先要把预读部分(我这么叫的),命名域使用,全局变量定义 ... 
- 实用Jupyter Notebook扩展工具——提升你的工作效率
			Jupyter Notebook 现已成为数据分析,机器学习的必备工具.因为它可以让数据分析师集中精力向用户解释整个分析过程.通过安装一些扩展工具,可以让你在Jupyter Notebook上的工作效 ... 
