windows graphics - DXGI 介绍(DirectX Graphics Infrastructure)

DXGI 概述

Microsoft DirectX 图形基础结构 (DXGI) 认识到,某些图形部分的发展速度比其他部分更慢。 DXGI 的主要目的是管理可独立于 DirectX 图形运行时的低级别任务。 DXGI 为未来图形组件提供了通用框架;使用 DXGI 的第一个组件是 Microsoft Direct3D 10。

在以前版本的 Direct3D 中,诸如一下功能,等底层任务都包含在 Direct3D 运行时中。 这些任务现在在 DXGI 中实现。

  • 硬件设备的枚举、
  • 将呈现的帧呈现到输出、
  • 控制伽玛
  • 管理全屏转换

DXGI 的用途是与内核模式驱动程序和系统硬件进行通信,如下图所示。
在这里插入图片描述
应用程序可以直接访问 DXGI,或调用 D3D11 D3D11、D3D10 和 D3D10 中的 Direct3D Api, _ _ 后者可处理与 DXGI 通信的情况。 如果你的应用程序需要枚举设备或控制向输出显示数据的方式,你可能想要直接使用 DXGI。

总结

在以前图形子系统都归D3D,结果D3D8/D3D9分别有一套代码用来管理swap chain。图形API越来越多,D3D9/D3D10/D3D11/D3D12,都来一套swap chain太没意义了。于是重构成所有API可以共享一份swap chain的代码,这就放在DXGI。除此之外,窗口全屏化之类的事情也都归DXGI了,你可以认为屏幕输出的部分都归DXGI。

不论是 OGL 还是 D3D,都没有包含与窗口(HWND)打交道的函数,光是程序里画好是不够的,还得拷贝到屏幕上呢!
OGL 需要 EGL、WGL、GLX 等在窗口和 API 之间交流交流。
类似的 D3D (10 之后)需要 DXGI 来做这件事情。

参考:
msdn DXGI
D3D中的DXGI是做什么用的?
在这里插入图片描述

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是一个使用 DirectX Graphics Infrastructure (DXGI) 捕获鼠标指针位置的示例代码: ```cpp #include <Windows.h> #include <d3d11.h> #include <dxgi.h> #include <iostream> #pragma comment(lib, "d3d11.lib") #pragma comment(lib, "dxgi.lib") int main() { // 创建 DXGI 工厂 IDXGIFactory* dxgiFactory = nullptr; HRESULT hr = CreateDXGIFactory(__uuidof(IDXGIFactory), (void**)&dxgiFactory); if (FAILED(hr)) { std::cerr << "Failed to create DXGI factory." << std::endl; return 1; } // 获取默认显示适配器 IDXGIAdapter* adapter = nullptr; hr = dxgiFactory->EnumAdapters(0, &adapter); if (FAILED(hr)) { std::cerr << "Failed to get adapter." << std::endl; return 1; } // 创建 D3D11 设备和设备上下文 ID3D11Device* device = nullptr; ID3D11DeviceContext* context = nullptr; hr = D3D11CreateDevice( adapter, D3D_DRIVER_TYPE_UNKNOWN, nullptr, 0, nullptr, 0, D3D11_SDK_VERSION, &device, nullptr, &context ); if (FAILED(hr)) { std::cerr << "Failed to create D3D11 device and context." << std::endl; return 1; } // 释放 DXGI 工厂和显示适配器 adapter->Release(); dxgiFactory->Release(); // 创建一个窗口并使其可见 HWND hwnd = CreateWindowEx( 0, L"STATIC", L"DXGI Mouse Capture", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, 640, 480, nullptr, nullptr, nullptr, nullptr ); ShowWindow(hwnd, SW_SHOWDEFAULT); // 获取窗口客户区域大小 RECT clientRect; GetClientRect(hwnd, &clientRect); UINT width = clientRect.right - clientRect.left; UINT height = clientRect.bottom - clientRect.top; // 创建 DXGI 交换链 DXGI_SWAP_CHAIN_DESC swapChainDesc = {}; swapChainDesc.BufferCount = 1; swapChainDesc.BufferDesc.Width = width; swapChainDesc.BufferDesc.Height = height; swapChainDesc.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; swapChainDesc.BufferDesc.RefreshRate.Numerator = 60; swapChainDesc.BufferDesc.RefreshRate.Denominator = 1; swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; swapChainDesc.OutputWindow = hwnd; swapChainDesc.SampleDesc.Count = 1; swapChainDesc.SampleDesc.Quality = 0; swapChainDesc.Windowed = TRUE; IDXGISwapChain* swapChain = nullptr; hr = dxgiFactory->CreateSwapChain(device, &swapChainDesc, &swapChain); if (FAILED(hr)) { std::cerr << "Failed to create DXGI swap chain." << std::endl; return 1; } // 释放 D3D11 设备上下文 context->Release(); // 获取 DXGI 捕获鼠标指针的设备 IDXGIDevice* dxgiDevice = nullptr; hr = device->QueryInterface(__uuidof(IDXGIDevice), (void**)&dxgiDevice); if (FAILED(hr)) { std::cerr << "Failed to get DXGI device." << std::endl; return 1; } // 获取 DXGI 设备的父对象(通常是 ID3D11DeviceContext) IUnknown* parent = nullptr; hr = dxgiDevice->GetParent(__uuidof(IUnknown), (void**)&parent); if (FAILED(hr)) { std::cerr << "Failed to get DXGI device parent." << std::endl; return 1; } // 释放 DXGI 设备和 D3D11 设备 dxgiDevice->Release(); device->Release(); // 获取 DXGI 父对象的设备上下文 ID3D11DeviceContext* dxgiContext = nullptr; hr = parent->QueryInterface(__uuidof(ID3D11DeviceContext), (void**)&dxgiContext); if (FAILED(hr)) { std::cerr << "Failed to get DXGI context." << std::endl; return 1; } // 创建后备缓冲区并设置为渲染目标 ID3D11Texture2D* backBuffer = nullptr; hr = swapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), (void**)&backBuffer); if (FAILED(hr)) { std::cerr << "Failed to get back buffer." << std::endl; return 1; } ID3D11RenderTargetView* renderTargetView = nullptr; hr = device->CreateRenderTargetView(backBuffer, nullptr, &renderTargetView); if (FAILED(hr)) { std::cerr << "Failed to create render target view." << std::endl; return 1; } backBuffer->Release(); dxgiContext->OMSetRenderTargets(1, &renderTargetView, nullptr); // 设置视口 D3D11_VIEWPORT viewport = {}; viewport.Width = (float)width; viewport.Height = (float)height; viewport.MaxDepth = 1.0f; dxgiContext->RSSetViewports(1, &viewport); // 清除后备缓冲区 float clearColor[4] = { 0.0f, 0.0f, 0.0f, 1.0f }; dxgiContext->ClearRenderTargetView(renderTargetView, clearColor); // 显示后备缓冲区 swapChain->Present(1, 0); // 捕获鼠标指针位置 POINT point; GetCursorPos(&point); ScreenToClient(hwnd, &point); std::cout << "Mouse position: " << point.x << ", " << point.y << std::endl; // 释放资源 renderTargetView->Release(); swapChain->Release(); dxgiContext->Release(); return 0; } ``` 这个示例代码创建了一个窗口和一个 DXGI 交换链,并捕获了鼠标指针位置。需要注意的是,DXGI 只能捕获指针位置,而不能捕获指针形状或其他信息。如果需要获取更多鼠标信息,可以考虑使用 Windows 消息循环或 DirectInput API。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值