如何在如何获取最新的咨询DX11或者Direct2D中获取显存并写入像素

3561人阅读
ShaderX(9)
&Dx11中的2D显示抛弃了Dx8和Dx9中的 ID3DxSprite 绘制精灵,也出乎意料的(出乎我的意料 :) )没有采用顶点方式而是返璞归真走向了表面。现在的Direct2D更像是GDI了~~~
DX11上Direct2D的第一个例题就是绘制一个笔刷~~这在原来是不可能实现的;原来的ID3DxSprite 只能够绘制基于纹理的格式,比如我们要做一个效果,当选中一个Button的时候,这个Button边界线会高亮显示,这在原来必须依靠制作这样的纹理来实现,现在不同了,你可以定义一个线条笔刷,给他个范围,画一个矩形就完成了!~~
Creating a Simple Direct2D Application
这个立体绘制了一个矩形框,一个蓝色填充的矩形和网格的背景;这些都是Direct2D自己绘制的,没有用任何的纹理。
我们这个程序使用的是一个标准的Win32API程序,和微软标准的例题不一样,要比那个简单。
// Windows Header Files:
#pragma once
// Windows 头文件:
#include &windows.h&
#include &tchar.h&
这几个头文件是win32平台必须的头文件,外加Dx11的2D头文件,这里不用倒入Dx11的头文件,因为Direct2D和Dx11的3D库是相对独立的。
#include &d2d1.h&
与之相关的lib库是D2d1.lib,它的名字是D2d1,估计也是尝试性的一个库,以后还会出D2d2,D2d3.....
&//-----------------全局变量------------------------------
// 当前实例
ID2D1Factory*
pD2DFactory = NULL;
ID2D1SolidColorBrush*
pBlackBrush = NULL;
// 实例笔刷
ID2D1HwndRenderTarget*
m_pRenderTarget = NULL;
创建一个函数,初始化2D环境
LRESULT InItD2D(HWND hWnd)
//创建一个单线程irect2D资源指针
HRESULT hr = D2D1CreateFactory(D2D1_FACTORY_TYPE_SINGLE_THREADED,&pD2DFactory);
// Obtain the size of the drawing area.
GetClientRect(hWnd, &rc);
// Create a Direct2D render target
根据窗口大小生成一个渲染表面
hr = pD2DFactory-&CreateHwndRenderTarget(D2D1::RenderTargetProperties(),
D2D1::HwndRenderTargetProperties(hWnd,D2D1::SizeU(rc.right - rc.left, rc.bottom - rc.top)),
&m_pRenderTarget);
在表面上加入3个笔刷
if (SUCCEEDED(hr))
m_pRenderTarget-&CreateSolidColorBrush(D2D1::ColorF(D2D1::ColorF::SteelBlue),&pBlackBrush);
m_pRenderTarget-&CreateSolidColorBrush(D2D1::ColorF(D2D1::ColorF::Gray),&pSteelBlueBrush);
m_pRenderTarget-&CreateSolidColorBrush(D2D1::ColorF(D2D1::ColorF::GreenYellow),&pGreenBrush);
生成笔刷以后,就可以绘制表面了
VOID Rander()
if(!m_pRenderTarget)
m_pRenderTarget-&BeginDraw();
m_pRenderTarget-&SetTransform(D2D1::Matrix3x2F::Identity());
m_pRenderTarget-&Clear(D2D1::ColorF(D2D1::ColorF::White));
// Draw a grid background
for (int x = 0; x & x += 10)
//画格子线
m_pRenderTarget-&DrawLine(
D2D1::Point2F(static_cast&FLOAT&(x), 0.0f),
D2D1::Point2F(static_cast&FLOAT&(x), height),
pGreenBrush,
for (int y = 0; y & y += 10)
m_pRenderTarget-&DrawLine(
D2D1::Point2F(0.0f, static_cast&FLOAT&(y)),
D2D1::Point2F(width, static_cast&FLOAT&(y)),
pGreenBrush,
// 画矩形线框
m_pRenderTarget-&DrawRectangle( D2D1::RectF(rc.left + 200.0f,rc.top + 200.0f,rc.right - 200.0f,rc.bottom - 200.0f), pSteelBlueBrush);
// 画矩形区域
m_pRenderTarget-&FillRectangle( D2D1::RectF(rc.left + 300.0f,rc.top + 300.0f,rc.right - 300.0f,rc.bottom - 300.0f), pBlackBrush);
m_pRenderTarget-&EndDraw();
&&相关文章推荐
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:118118次
积分:1876
积分:1876
排名:千里之外
原创:47篇
评论:42条
(1)(2)(1)(1)(2)(2)(2)(4)(4)(1)(5)(1)(2)(1)(2)(7)(14)(3)(1)
(window.slotbydup = window.slotbydup || []).push({
id: '4740881',
container: s,
size: '200,200',
display: 'inlay-fix'请问如何在最新的DX11或者Direct2D中获取显存(表面)并写入像素? - 知乎19被浏览1148分享邀请回答21 条评论分享收藏感谢收起0添加评论分享收藏感谢收起查看更多回答在Unity中可能需要在纹理上面绘制文字、图像等。比如游戏中的显示器,手机等等等等等。太多了。
Unity的Textute2D类提供了设置像素的操作,但是这效率实在不敢恭维。
汉字数量巨大,全部贴在一张图上既耗空间,不方便改变字体样式。
使用FreeType2等CPU计算的文字库一帧又画不了多少,毕竟还要提交到显存
于是瞄准了Direct2D,当初学习这图像接口时就被微软说的“能与Direct3D进行完美交互”所吸引。
好在Unity支持DX11了,我们能够在Unity上面使用Direct2D了。所以只能在支持DX11的机器上面运行。
首先得说一下授权许可,毕竟Unity是一款商业软件。
Unity明确指出:Unity Pro才能使用Plug-in,即插件。Unity Free版本是不可以使用的。
但是,它说的是“插件”,而不是“本地代码”。
有童鞋肯定就会说我这是咬文嚼字了。非也非也,“插件”是指遵循当前环境并按照其对接口的相关规定写的代码。
那么,Unity插件有什么规定呢?
需要提供UnitySetGraphicsDevice与UnityRenderEvent
前者获取图形设备信息与图像设备相关事件,后者提供渲染事件。这两个接口是Unity自动调用的(或者也算半自动),
不能显式调用——因为没意义.....
你的本地代码提供了这两个接口就算插件,否则就是普通的本地代码库。
作为本地代码库不能放在plugin文件夹内,不能调用,因为Unity会认为是个插件,而应该直接放在工厂目录下。
再者,假设你写了个插件却放在这个目录下,那么那两个接口不能自动被调用。
好了,就这样可以创建Direct2D了,那个版本的?1.0?1.1?甚至1.2?随意啦!
但是,我建议这样做:
#include &windows.h&&
& HMODULE WINAPI LoadLibraryWrapA(char* file_name){&
&&& return LoadLibraryA(file_name);&
}& & HMODULE WINAPI LoadLibraryWrapW(wchar_t* file_name){&
&&& return LoadLibraryW(file_name);&
}& & BOOL WINAPI FreeLibraryWrap(HMODULE hLibModule){&
&&& return FreeLibrary(hLibModule);&
}& & FARPROC WINAPI GetProcAddressWrap(HMODULE hModule,
char* lpProcName){& &&& return GetProcAddress(hModule, lpProcName);&
#include &windows.h&
HMODULE WINAPI LoadLibraryWrapA(char* file_name){
return LoadLibraryA(file_name);
HMODULE WINAPI LoadLibraryWrapW(wchar_t* file_name){
return LoadLibraryW(file_name);
BOOL WINAPI FreeLibraryWrap(HMODULE hLibModule){
return FreeLibrary(hLibModule);
FARPROC WINAPI GetProcAddressWrap(HMODULE hModule, char* lpProcName){
return GetProcAddress(hModule, lpProcName);
面的代码封装成dll文件,这样像C++一样显式调用dll文件。
1. 方便: 不知道是不是Unity的原因,反正假设你想一般dll一样使用Unity C#中的DllImport,
使用后除非关闭Unity,否则不能再次修改dll文件。这简直蛋疼,修改一行代码就需要:
关闭Unity -& 复制dll -& 打开Unity
2. 方便调试,在VS Express 2013 for Windows Desktop中,选择
工具——附加到进程,选择Unity进程
就能直接调试dll文件了,很方便。
使用GetProcAddressWrap获取函数指针之后使用C#中的
Marshal.GetDelegateForFunctionPointer
就能将函数指针换成C#中的托管方法。
比如先定义:
& public delegate System.UInt32 D2DManagerInit();&
public D2DManagerInit m_D2DManagerI&
// 初始化 D2D 管理器
public delegate System.UInt32 D2DManagerInit();
public D2DManagerInit m_D2DManagerI
proc = GetProcAddressWrap(m_unityd2ddll, &D2DManagerInit&);&
m_D2DManagerInit = (D2DManagerInit)Marshal.GetDelegateForFunctionPointer(proc,
typeof(D2DManagerInit));&
proc = GetProcAddressWrap(m_unityd2ddll, &D2DManagerInit&);
m_D2DManagerInit = (D2DManagerInit)Marshal.GetDelegateForFunctionPointer(proc, typeof(D2DManagerInit));
之后使用m_D2DManagerInit()就能调用dll文件中的D2DManagerInit函数了。
最后在OnApplicationQuit里面释放即可。
创建 D2D 1.0 的 流程:
首先创建一个公共的& D2D工厂& ,毕竟可能创建多个
Unity中 Texture2D::GetNativeTextureID在DX11环境下就能获取一个ID3D11Texture2D的指针
这个指针能获取&&&& D3D11设备& ,D3D11设备 能获取当前&&& D3D11设备上下文。
D3D与D2D交互要D3D设备有D3D11_CREATE_DEVICE_BGRA_SUPPORT(D3D11环境下)
D3D11设备&& -------& 创建Texture2D,D3D11_TEXTURE2D_DESC参考如下:
sharedTextureDesc.Width = 512;& sharedTextureDesc.Height = 512;& sharedTextureDesc.MipLevels = 1;& sharedTextureDesc.ArraySize = 1;& sharedTextureDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;&
sharedTextureDesc.SampleDesc.Count = 1;& sharedTextureDesc.Usage = D3D11_USAGE_DEFAULT;& sharedTextureDesc.BindFlags = D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET;&
sharedTextureDesc.Width = 512;
sharedTextureDesc.Height = 512;
sharedTextureDesc.MipLevels = 1;
sharedTextureDesc.ArraySize = 1;
sharedTextureDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
sharedTextureDesc.SampleDesc.Count = 1;
sharedTextureDesc.Usage = D3D11_USAGE_DEFAULT;
sharedTextureDesc.BindFlags = D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET;
必须有D3D11_BIND_RENDER_TARGET,否则不能创建渲染目标呈现器。记得保留这个指针。
然后对 D3D11Textue2D 使用QueryInterface获取 Dxgi表面
使用这个Dxgi表面利用D2D工厂CreateDxgiSurfaceRenderTarget创建RT
就好了,记得释放这个Dxgi表面:
如同一般那样,不过由于变成了dll,可能一些习惯要改成C语言那样。
渲染完成后,使用
D3D11设备上下文的CopyResource方法就能拷贝渲染结果到目标纹理了:
DirectWrite简直不错:
稍微写点代码就能模仿某游戏那样的效果:
嗯,看来还不够完善,再加油吧:
话说自带的Sprite着色器很不错,简直赞
本文已收录于以下专栏:
相关文章推荐
在Unity中使用高效率的Direct2D作为纹理渲染接口
Direct 2D 1.1开发笔记 : 如何初始化Direct2D 1.1
& &    使用Direct3D渲染2D图素    中国游戏开发者.CN   
图片及源代码请登陆下面网站:
合作翻译:
中国游戏开发者.CN  ...
写在前面:最近要做一个有关于地图的项目[C#],开始选择 GDI+ 作图,不知是算法问题还是 GDI+ 本身问题,加载非常慢而且拖动各种闪烁。迫于无奈最终放弃了 GDI+ 方式而尝试 Direct2D...
如何在Direct2D中实现一个简单的自定义特效
#pragma comment(lib, &dwrite.lib&)
#pragma comment(lib, &d2d...
#pragma comment(lib, &dwrite.lib&)
#pragma comment(lib, &d2d...
#pragma comment(lib, &dwrite.lib&)
#pragma comment(lib, &d2d...
/zh-cn/library/dd317121(v=vs.85).aspx
Direct2D 1.1 特效: 径向模糊, 基本算法解释.
他的最新文章
讲师:刘文志
讲师:陈伟
您举报文章:
举报原因:
原文地址:
原因补充:
(最多只允许输入30个字)

我要回帖

更多关于 如何获取最新的资讯 的文章

 

随机推荐