C#使用原生的Directx和OpenGL绘图
原文 混合语言编程—C#使用原生的Directx和OpenGL绘图的方法
由于项目需要做一些图形展示,所以就想到了使用Directx和OpenGL来绘图,但项目准备使用C#来开发(大家比较熟悉C#),在网上看了相关的资料,有一些第三方的控件可用,试用了下,一运行就占了几百M的内存,而且也不知道是否稳定,教程也少,还不如直接使用原生的。在网上看的Directx和OpenGL的教程基本上都是C/C++的,找了很久也就找到相关介绍,只能自己研究下。
我以前做过C#和C++混合语言编程相关的东西,在C++实现一些C#不好实现的功能,C#动态调用DLL文件,所以也想到了用C++的代码来控制Winform控件的绘画,这样就可实现用Direct和OpenGL在Winform的控件上绘画了。
由于我对Direct和OpenGL都不熟悉,没有这方面的编程经验,只能去瞎折腾,下面分别说说最近在Directx和OpenGL怎么试验的。
Directx:
之前没学过Directx,拿了同学的代码来看,也是雾里看花啊,不过有一点启示了我,在初始化的时候,要传入一个句柄去创建设备(CreateDevice),通常都是传入窗口的设备,我想如果传入一个控件的句柄,那所有的绘画都将在这个控件上实现,因为控件也是继承自Window的。而Winform的控件在底层的实现应该和WIN32是一样的。这样的话只要把Winform的控件的句柄传入C++代码进行初始化,那么绘画的结果将显示在这个控件上。结果一试,还真行。关键代码如下:
extern "C" _declspec(dllexport) HRESULT InitD3D( HWND hWnd );
extern "C" _declspec(dllexport) VOID Render();
在InitD3D传入控件的句柄进行初始化,C#再调用Render进行绘画,以下是C#代码:
HWND handle = this.button1.Handle;
InitD3D(handle);
private void Draw()
{
for (; ; )
{
Render();
}
}
效果图:
OpenGL:
查看了OpenGL的相关教程(推荐http://www.yakergong.net/nehe/),OpenGL是通过RC来执行的,创建RC时就必须指定一个DC,还要设置DC的像素格式。每个线程有且只能拥有一个RC。
如果在初始化OpenGL的绘画环境时传入一个Winform的控件句柄,再通过这个句柄取到HDC,就可使用这个HDC来创建RC,这样OpenGL的绘画环境就准备好了,并且这个RC关联到Winform的控件上。
在给制前,先为当前线程选择RC(之前通过HDC创建的),再进行绘制,这样绘制的结果将显示在这个Winform控件上。
关键代码如下:
C++:
extern "C" _declspec(dllexport) void Init( HWND hWnd);
extern "C" _declspec(dllexport) void Render();
void Init(HWND hWnd)
{
int PixelFormat;
int bits = 16;
hDC = GetDC(hWnd);
static PIXELFORMATDESCRIPTOR pfd= // pfd Tells Windows How We Want Things To Be
{
sizeof(PIXELFORMATDESCRIPTOR), // Size Of This Pixel Format Descriptor
1, // Version Number
PFD_DRAW_TO_WINDOW | // Format Must Support Window
PFD_SUPPORT_OPENGL | // Format Must Support OpenGL
PFD_DOUBLEBUFFER, // Must Support Double Buffering
PFD_TYPE_RGBA, // Request An RGBA Format
bits, // Select Our Color Depth
0, 0, 0, 0, 0, 0, // Color Bits Ignored
0, // No Alpha Buffer
0, // Shift Bit Ignored
0, // No Accumulation Buffer
0, 0, 0, 0, // Accumulation Bits Ignored
16, // 16Bit Z-Buffer (Depth Buffer)
0, // No Stencil Buffer
0, // No Auxiliary Buffer
PFD_MAIN_PLANE, // Main Drawing Layer
0, // Reserved
0, 0, 0 // Layer Masks Ignored
};
PixelFormat=ChoosePixelFormat(hDC,&pfd);
SetPixelFormat(hDC,PixelFormat,&pfd);
hRC=wglCreateContext(hDC);
}
void Render()
{
wglMakeCurrent(hDC, hRC);
draw();
SwapBuffers(hDC);
wglMakeCurrent(NULL, NULL);
}
Init(this.pictureBox1.Handle);
//开始绘制
var timer = new System.Timers.Timer();
timer.Interval = 100;
timer.Elapsed += (tsender, te) =>
{
Render();
};
timer.AutoReset = true;
timer.Enabled = true;
效果图:
WPF:WPF的控件没有句柄,但是可以换个思路,把绘画代码封装在Winform控件上,在WPF使用自定义的Winform控件。
C#使用原生的Directx和OpenGL绘图的更多相关文章
- DirectX标准规定 DirectX和OpenGL的不同
DirectX标准规定 DirectX使用左手坐标系. X轴正向指向右,Y轴正向指向上,Z轴正向垂直纸面向内. 编写Direct3D应用程序时,通常只使用4×4的矩阵和1×4的行向量,相乘时行向量在前 ...
- 矩阵-DirectX与OpenGL的不同
http://www.cnblogs.com/graphics/archive/2012/08/02/2616017.html 矩阵是三维图形学中不可或缺的部分,几乎所有和变换相关的操作都涉及矩阵,世 ...
- (转)思考:矩阵及变换,以及矩阵在DirectX和OpenGL中的运用问题:左乘/右乘,行优先/列优先,...
转自:http://www.cnblogs.com/soroman/archive/2008/03/21/1115571.html 思考:矩阵及变换,以及矩阵在DirectX和OpenGL中的运用1. ...
- (转)Windows 支持 DirectX 和 OpenGL,为什么大多数 PC 游戏还是 DirectX 开发?
事实上在早年OpenGL即使在游戏领域也是对DirectX压倒性的优势.John Carmack曾嘲讽DirectX是"horribly broken" 的API.直到Direct ...
- iOS 使用Quartz和OpenGL绘图
http://blog.csdn.net/coder9999/article/details/7641701 第十二章 使用Quartz和OpenGL绘图 有时应用程序需要能够自定义绘图.一个库是Qu ...
- openGL绘图基本框架
openGL绘图入门和导入外部文件 本文主要介绍通用绘图软件openGL的数据类型和基本的绘图框架,此外还提供了导入obj外部文件的方法,提供的代码稍作修改即可使用,希望能方便初学者快速上手. ope ...
- 比较DirectX和OpenGL的区别(比较详细)
OpenGL是个专业的3D程序接口,是一个功能强大,调用方便的底层3D图形库.OpenGL的前身是SGI公司为其图形工作站开发的IRIS GL.IRIS GL是一个工业标准的3D图形软件接口,功能虽然 ...
- 如何检查显卡类型,DirectX和OpenGL的版本
How To: Check the graphics card type and OpenGL version From: http://support.esri.com/technical-arti ...
- 61.H5---利用canvas+原生js进行鼠标跟随绘图
<!doctype html><html lang="en"><head> <meta charset="UTF-8" ...
随机推荐
- nginx下的rewrite
一.正则表达式匹配,其中: * ~ 为区分大小写匹配 * ~* 为不区分大小写匹配 * !~和!~*分别为区分大小写不匹配及不区分大小写不匹配 二.文件及目录匹配,其中: * -f和!-f用来判断是否 ...
- Python学习(4)——for语句
Python中range()函数的用法 >>> range(5) [0, 1, 2, 3, 4] >>> range(0,5) [0, 1, 2, 3, 4] &g ...
- kuangbin_ShortPath P (HDU 4725)
很有挑战的一题 直接暴力建图的话毫无疑问O(n^2)会TLE 每层虚拟一个点又会让没有点的层也能连过去 参考kuangbin菊苣的方法每层用了两个虚拟点 n+i*2-1 是入口 n+i*2 是出口 然 ...
- DuiLib——第一篇UIManager
DUiLib 源码分析 --以UiLib 1.01版为分析目标 -------------------------------------------------------------------- ...
- display:none,overflow:hidden,visibility:hidden之间的区别
一,display:none; 隐藏元素,不占网页中的任何空间,让这个元素彻底消失(看不见也摸不着) 二,overflow:hidden; 让超出的元素隐藏,就是在设置该属性的时候他会根据你设置的宽高 ...
- Unity Meshes
1. Unity 没有自带建模工具 2. 导入 Mesh 时,Unity 会自动寻找所引用的纹理,查找文件夹名为 Textures 的.先在本目录下找 -> 上溯在parent查找 ==> ...
- mount挂载错误
错误信息: usa@usa-desktop:~/svn/aispeech/speechplatform/trunk/proxy/src$ sudo mount -t tmpfs -o size=200 ...
- java 锁讲解
每个锁对象都有两个队列,一个是就绪队列,一个是阻塞队列,就绪队列存储了将要获得锁的线程,阻塞队列存储了被阻塞的线程,当一个被线程被唤醒 (notify)后,才会进入到就绪队列,等待获得锁.当一开始线程 ...
- Druid是什么和用StatViewServlet用于展示Druid的统计信息
Druid是一个JDBC组件,它包括三部分: DruidDriver 代理Driver,能够提供基于Filter-Chain模式的插件体系. DruidDataSource 高效可管理的数据库连接池 ...
- asterisk
http://www.asterisk.org/ asterisk is the world's most widely adopted open source commnuctions platfo ...