Directx 11中垂直同步的设置

1、什么是垂直同步?

     垂直同步又称场同步(Vertical Hold),从CRT显示器的显示原理来看,单个象素组成了水平扫描线,水平扫描线在垂直方向的堆积形成了完整的画面。显示器的刷新率受显卡DAC控制,显卡DAC完成一帧的扫描后就会产生一个垂直同步信号。

当我们选择\"等待垂直同步信号"(即打开垂直同步)时,显卡绘制3D图形前会等待垂直同步信号,性能强劲的显卡则会提前完成渲染,并在下个垂直信号之前进行等待。由此可见,当打开垂直同步时,游戏的FPS要受刷新率的制约,对于高端显卡而言,限制了其性能的发挥。

    当我们选择\"不等待垂直同步信号"(即关闭垂直同步)时,3D引擎将全速运行,不再等待垂直同步信号的到来,显卡性能得到了最大的发挥。所以我们测试显卡3D性能时,一定要关闭垂直同步。不少的朋友认为在游戏中关闭垂直同步可以得到更高的帧速,其实不然,这虚高的帧速不仅要受到显示器刷新率的制约,更会对游戏画面产生不良的影响。一般来说,关闭垂直同步会导致游戏画面产生以下两种问题:

(1)画面撕裂
在打cs的时候会碰到这种情况,图像断裂
(2)跳帧
假如显示器设定的刷新率是80Hz,显卡以100FPS循环显示0-9数字,那么,在开始的0.1秒内,显卡显示了10个数字而显示器只刷新了8次。可见,由于显示器刷新率跟不上游戏的FPS,只能舍弃一部分画面,这种现象表现在游戏里就是跳帧。鬼武者3等一些移植到PC上的游戏在关闭垂直同步时通常会出现这种问题。

2、directx 11中设置垂直同步的代码:

bool D3DClass::Initialize(int screenWidth, int screenHeight, bool vsync, HWND hwnd, bool fullscreen, float screenDepth, float screenNear){    HRESULT result;    IDXGIFactory* factory;    IDXGIAdapter* adapter;    IDXGIOutput* adapterOutput;unsigned int numModes, i, numerator, denominator, stringLength;    DXGI_MODE_DESC* displayModeList;    DXGI_ADAPTER_DESC adapterDesc;int error;    DXGI_SWAP_CHAIN_DESC swapChainDesc;    D3D_FEATURE_LEVEL featureLevel;    ID3D11Texture2D* backBufferPtr;    D3D11_TEXTURE2D_DESC depthBufferDesc;    D3D11_DEPTH_STENCIL_DESC depthStencilDesc;    D3D11_DEPTH_STENCIL_VIEW_DESC depthStencilViewDesc;    D3D11_RASTERIZER_DESC rasterDesc;    D3D11_VIEWPORT viewport;float fieldOfView, screenAspect;

// Store the vsync setting.    m_vsync_enabled = vsync;

// Create a DirectX graphics interface factory.    result = CreateDXGIFactory(__uuidof(IDXGIFactory), (void**)&factory);if(FAILED(result))    {return false;    }

// Use the factory to create an adapter for the primary graphics interface (video card).    result = factory->EnumAdapters(0, &adapter);if(FAILED(result))    {return false;    }

// Enumerate the primary adapter output (monitor).    result = adapter->EnumOutputs(0, &adapterOutput);if(FAILED(result))    {return false;    }

// Get the number of modes that fit the DXGI_FORMAT_R8G8B8A8_UNORM display format for the adapter output (monitor).    result = adapterOutput->GetDisplayModeList(DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_ENUM_MODES_INTERLACED, &numModes, NULL);if(FAILED(result))    {return false;    }

// Create a list to hold all the possible display modes for this monitor/video card combination.    displayModeList = new DXGI_MODE_DESC[numModes];if(!displayModeList)    {return false;    }

// Now fill the display mode list structures.    result = adapterOutput->GetDisplayModeList(DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_ENUM_MODES_INTERLACED, &numModes, displayModeList);if(FAILED(result))    {return false;    }

// Now go through all the display modes and find the one that matches the screen width and height.// When a match is found store the numerator and denominator of the refresh rate for that monitor.for(i=0; i<numModes; i++)    {if(displayModeList[i].Width == (unsigned int)screenWidth)        {if(displayModeList[i].Height == (unsigned int)screenHeight)            {                numerator = displayModeList[i].RefreshRate.Numerator;                denominator = displayModeList[i].RefreshRate.Denominator;            }        }    }

// Get the adapter (video card) description.    result = adapter->GetDesc(&adapterDesc);if(FAILED(result))    {return false;    }

// Store the dedicated video card memory in megabytes.    m_videoCardMemory = (int)(adapterDesc.DedicatedVideoMemory / 1024 / 1024);

// Convert the name of the video card to a character array and store it.    error = wcstombs_s(&stringLength, m_videoCardDescription, 128, adapterDesc.Description, 128);if(error != 0)    {return false;    }

// Release the display mode list.delete [] displayModeList;    displayModeList = 0;

// Release the adapter output.    adapterOutput->Release();    adapterOutput = 0;

// Release the adapter.    adapter->Release();    adapter = 0;

// Release the factory.    factory->Release();    factory = 0;

// Initialize the swap chain description.    ZeroMemory(&swapChainDesc, sizeof(swapChainDesc));

// Set to a single back buffer.    swapChainDesc.BufferCount = 1;

// Set the width and height of the back buffer.    swapChainDesc.BufferDesc.Width = screenWidth;    swapChainDesc.BufferDesc.Height = screenHeight;

// Set regular 32-bit surface for the back buffer.    swapChainDesc.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;

// Set the refresh rate of the back buffer.if(m_vsync_enabled)    {        swapChainDesc.BufferDesc.RefreshRate.Numerator = numerator;        swapChainDesc.BufferDesc.RefreshRate.Denominator = denominator;    }else    {        swapChainDesc.BufferDesc.RefreshRate.Numerator = 0;        swapChainDesc.BufferDesc.RefreshRate.Denominator = 1;    }

// Set the usage of the back buffer.    swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;

// Set the handle for the window to render to.    swapChainDesc.OutputWindow = hwnd;

// Turn multisampling off.    swapChainDesc.SampleDesc.Count = 1;    swapChainDesc.SampleDesc.Quality = 0;

// Set to full screen or windowed mode.if(fullscreen)    {        swapChainDesc.Windowed = false;    }else    {        swapChainDesc.Windowed = true;    }

// Set the scan line ordering and scaling to unspecified.    swapChainDesc.BufferDesc.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED;    swapChainDesc.BufferDesc.Scaling = DXGI_MODE_SCALING_UNSPECIFIED;

// Discard the back buffer contents after presenting.    swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_DISCARD;

// Don't set the advanced flags.    swapChainDesc.Flags = 0;

// Set the feature level to DirectX 11.    featureLevel = D3D_FEATURE_LEVEL_11_0;

// Create the swap chain, Direct3D device, and Direct3D device context.    result = D3D11CreateDeviceAndSwapChain(NULL, D3D_DRIVER_TYPE_HARDWARE, NULL, 0, &featureLevel, 1,                                            D3D11_SDK_VERSION, &swapChainDesc, &m_swapChain, &m_device, NULL, &m_deviceContext);if(FAILED(result))    {return false;    }

// Get the pointer to the back buffer.    result = m_swapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), (LPVOID*)&backBufferPtr);if(FAILED(result))    {return false;    }

// Create the render target view with the back buffer pointer.    result = m_device->CreateRenderTargetView(backBufferPtr, NULL, &m_renderTargetView);if(FAILED(result))    {return false;    }

// Release pointer to the back buffer as we no longer need it.    backBufferPtr->Release();    backBufferPtr = 0;

// Initialize the description of the depth buffer.    ZeroMemory(&depthBufferDesc, sizeof(depthBufferDesc));

// Set up the description of the depth buffer.    depthBufferDesc.Width = screenWidth;    depthBufferDesc.Height = screenHeight;    depthBufferDesc.MipLevels = 1;    depthBufferDesc.ArraySize = 1;    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;

// Create the texture for the depth buffer using the filled out description.    result = m_device->CreateTexture2D(&depthBufferDesc, NULL, &m_depthStencilBuffer);if(FAILED(result))    {return false;    }

// Initialize the description of the stencil state.    ZeroMemory(&depthStencilDesc, sizeof(depthStencilDesc));

// Set up the description of the stencil state.    depthStencilDesc.DepthEnable = true;    depthStencilDesc.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ALL;    depthStencilDesc.DepthFunc = D3D11_COMPARISON_LESS;

depthStencilDesc.StencilEnable = true;    depthStencilDesc.StencilReadMask = 0xFF;    depthStencilDesc.StencilWriteMask = 0xFF;

// Stencil operations if pixel is front-facing.    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;

// Stencil operations if pixel is back-facing.    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;

// Create the depth stencil state.    result = m_device->CreateDepthStencilState(&depthStencilDesc, &m_depthStencilState);if(FAILED(result))    {return false;    }

// Set the depth stencil state.    m_deviceContext->OMSetDepthStencilState(m_depthStencilState, 1);

// Initialize the depth stencil view.    ZeroMemory(&depthStencilViewDesc, sizeof(depthStencilViewDesc));

// Set up the depth stencil view description.    depthStencilViewDesc.Format = DXGI_FORMAT_D24_UNORM_S8_UINT;    depthStencilViewDesc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2D;    depthStencilViewDesc.Texture2D.MipSlice = 0;

// Create the depth stencil view.    result = m_device->CreateDepthStencilView(m_depthStencilBuffer, &depthStencilViewDesc, &m_depthStencilView);if(FAILED(result))    {return false;    }

// Bind the render target view and depth stencil buffer to the output render pipeline.    m_deviceContext->OMSetRenderTargets(1, &m_renderTargetView, m_depthStencilView);

// Setup the raster description which will determine how and what polygons will be drawn.    rasterDesc.AntialiasedLineEnable = false;    rasterDesc.CullMode = D3D11_CULL_BACK;    rasterDesc.DepthBias = 0;    rasterDesc.DepthBiasClamp = 0.0f;    rasterDesc.DepthClipEnable = true;    rasterDesc.FillMode = D3D11_FILL_SOLID;    rasterDesc.FrontCounterClockwise = false;    rasterDesc.MultisampleEnable = false;    rasterDesc.ScissorEnable = false;    rasterDesc.SlopeScaledDepthBias = 0.0f;

// Create the rasterizer state from the description we just filled out.    result = m_device->CreateRasterizerState(&rasterDesc, &m_rasterState);if(FAILED(result))    {return false;    }

// Now set the rasterizer state.    m_deviceContext->RSSetState(m_rasterState);

// Setup the viewport for rendering.    viewport.Width = (float)screenWidth;    viewport.Height = (float)screenHeight;    viewport.MinDepth = 0.0f;    viewport.MaxDepth = 1.0f;    viewport.TopLeftX = 0.0f;    viewport.TopLeftY = 0.0f;

// Create the viewport.    m_deviceContext->RSSetViewports(1, &viewport);

// Setup the projection matrix.    fieldOfView = (float)D3DX_PI / 4.0f;    screenAspect = (float)screenWidth / (float)screenHeight;

// Create the projection matrix for 3D rendering.    D3DXMatrixPerspectiveFovLH(&m_projectionMatrix, fieldOfView, screenAspect, screenNear, screenDepth);

// Initialize the world matrix to the identity matrix.    D3DXMatrixIdentity(&m_worldMatrix);

// Create an orthographic projection matrix for 2D rendering.    D3DXMatrixOrthoLH(&m_orthoMatrix, (float)screenWidth, (float)screenHeight, screenNear, screenDepth);

return true;}
时间: 2024-10-22 08:03:53

Directx 11中垂直同步的设置的相关文章

微软为Win7用户提供DirectX 11.1

几天前,有消息称DirectX 11.1仅支持最新的Win8.Windows RT和Windows Server 2012,微软暂时没有为Win7提供DirectX 11.1的计划. 这一消息引起了众多Win7用户的不满,为了平息众怒,微软特意在官方博客中进行了澄清.在今天发布的一篇官方博客中,微软表示,他们其实悄悄为Win7提供了一种方法,用户可以获取部分DirectX 11.1功能.这个秘密功能就隐藏在昨日为Win7用户发布的IE10中. 微软在博客中表示,Win8包含最新的DirectX

Windows 7怎么安装DirectX 11.1?

  几天前,有消息称DirectX 11.1仅支持最新的Windows 8.Windows RT和Windows Server 2012,微软暂时没有为Windows 7提供DirectX 11.1的计划. 这一消息引起了众多Windows 7用户的不满,为了平息众怒,微软特意在官方博客中进行了澄清.在今天发布的一篇官方博客中,微软表示,他们其实悄悄为Windows 7提供了一种方法,用户可以获取部分DirectX 11.1功能.这个秘密功能就隐藏在昨日为Windows 7用户发布的IE10中.

C++11中的mutex, lock,condition variable实现分析

本文分析的是llvm libc++的实现:http://libcxx.llvm.org/ C++11中的各种mutex, lock对象,实际上都是对posix的mutex,condition的封装.不过里面也有很多细节值得学习. std::mutex 先来看下std::mutex: 包增了一个pthread_mutex_t __m_,很简单,每个函数该干嘛就干嘛. class mutex { pthread_mutex_t __m_; public: mutex() _NOEXCEPT {__m

Flex中如何通过设置GridLines对象的horizontalAlternateFill样式交错显示LineSeries图表背景颜色的例子

原文 http://blog.minidx.com/2008/11/27/1652.html 接下来的例子演示了Flex中如何通过设置GridLines对象的horizontalAlternateFill样式,交错显示LineSeries图表背景颜色. 让我们先来看一下Demo(可以右键View Source或点击这里察看源代码):     下面是完整代码(或点击这里察看): Download: main.mxml <?xmlversion="1.0"?> <mx:A

全面认识Eclipse中JVM内存设置(转)

    这里向大家描述一下Eclipse中如何进行JVM内存设置,JVM主要管理两种类型的内存:堆和非堆.简单来说堆就是Java代码可及的内存,是留给开发人员使用的:非堆就是JVM留给自己用的,所以方法区.JVM内部处理或优化所需的内存(如JIT编译后的代码缓存).每个类结构(如运行时常数池.字段和方法数据)以及方法和构造方法的代码都在非堆内存中. Eclipse中JVM内存设置 eclipse.ini内存设置 -vmargs-Xms128M-Xmx512M-XX:PermSize=64M-XX

C++11中貌似有理的右值

C++11中貌似有理的右值 C++11非常重要的一个概念是引入了右值right value(rvalue)概念,这篇文章不是长篇大论rvalue的文章,而是在我阅读c++头文件type_traits时看到一些代码的由感而发的. right value顾名思义是右值的意思,估计你能体会到这是"即将消失"的意思,如果你还不明白,可以看这个例子: Object f() { Object o; return o; } int main() { Object obj = f(); } 你可以想象

Android开发中的简单设置技巧集锦_Android

本文实例总结了Android开发中的简单设置技巧.分享给大家供大家参考,具体如下: 1开机图片: android-logo-mask.png android-logo-shine.png 这两个图片一个在上一个在下 ./out/target/common/obj/JAVA_LIBRARIES/android_stubs_current_intermediates/classes/assets/images/android-logo-shine.png ./frameworks/base/core

新一代数据库技术在双11中的黑科技

分享嘉宾: 张瑞:阿里巴巴研究员,阿里集团数据库技术团队负责人,经历阿里数据库技术变革历程,连续六年作为数据库总负责人参与双11备战工作. 双11是一场技术大练兵,是互联网界的超级工程.需要做到支撑尽可能高的零点峰值,给用户最好的体验:也要做到成本尽可能低,要求极致的弹性能力:还要做到整体系统的稳定.   数据库如何实现极致弹性能力 数据库上云 数据库实现弹性是比较难的,数据库对性能要求非常高,因此,必须实现数据库上云,但是如何上云呢? 数据库上云面临以下几个难点: 1.         数据库

PHP 5.6.11中CURL模块问题的解决方法

按照网上的教程写了一个cURL的小例子,在apache环境下执行,一点反应也没有,放在IIS环境里就ok的,感觉问题一定出在动态连接库上,因为配置文件里的php_curl.dll已经打开了,而且在iis上ok: 网上找了一些解决方案: 设置了[环境变量]:phpext,PHPRC:无效 把php_curl.dll 放到apache/bin下:无效 检查了一下apache/bin目录下也有这两个libeay32.dll,ssleay32.dll个文件:没问题 最后试了一下,把当前php根目录下的l