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" ...
随机推荐
- URAL 1137 Bus Routes(欧拉回路路径)
1137. Bus Routes Time limit: 1.0 secondMemory limit: 64 MB Several bus routes were in the city of Fi ...
- 数字字符与金钱RMB之间的转换
FormatMoney() 函数,直接将一个数字字符串,转化为 万元,并且格式化小数点保留两位 如右->¥(元.角.分) sprintf("%.2f", $value) ...
- JAVA的UML
1. UML概念 Unified Modeling Language (UML) 又称统一建模语言或标准建模语言 是一个支持模型化和软件系统开发的图形化语言 2. UML图示 UML2.2中一共定义了 ...
- IE6 7 8BUG锦集
1.浮动元素的双倍margin 说明:这是IE6及其以下版本的一个经典的BUG,触发这个BUG产生的条件是给元素设置了浮动并且同一方向设置了margin值.来看以下代码: <style type ...
- ID3算法 决策树的生成(2)
# coding:utf-8 import matplotlib.pyplot as plt import numpy as np import pylab def createDataSet(): ...
- FSM, VISIBILITY MAP AND VACUUM
Update: Heikki’s slides are here! Heikki Linnakangas gave a presentation this past Sunday at FOSDEM ...
- IE下必须点击一下页面空白的地方才可以激活onchange事件
checkbox在IE下必须点击一下页面空白的地方才可以激活onchange事件. 解决办法把onchange换成onclick
- Web前端开发笔试&面试_04_20161019MTBS
1.运用CSS3 ,实现div 沿Y 轴上下循环运动的动画. 我写是:-webkit-animation:xz 3s linear 1s infinite //即XZ轴变化,Y轴不变 正确答案是: & ...
- unity 合并skinnedMeshRenderer中遇到的一个大坑
将多个skinnedMeshRenderer合并成一个skinnedMeshRenderer,主要涉及的mesh合并.骨骼列表合并.重定向顶点骨骼索引.其中重定向顶点骨骼索引只是通过加偏值即可完成,所 ...
- 一个关于正整数x的约数个数的结论
分析理解:x的每一个约数都是由x的若干个质因数的积构成. 再根据乘法原理,每个质因数Pi的选择可以是0~Ni个,所以上述结论成立.