原文 混合语言编程—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绘图的更多相关文章

  1. DirectX标准规定 DirectX和OpenGL的不同

    DirectX标准规定 DirectX使用左手坐标系. X轴正向指向右,Y轴正向指向上,Z轴正向垂直纸面向内. 编写Direct3D应用程序时,通常只使用4×4的矩阵和1×4的行向量,相乘时行向量在前 ...

  2. 矩阵-DirectX与OpenGL的不同

    http://www.cnblogs.com/graphics/archive/2012/08/02/2616017.html 矩阵是三维图形学中不可或缺的部分,几乎所有和变换相关的操作都涉及矩阵,世 ...

  3. (转)思考:矩阵及变换,以及矩阵在DirectX和OpenGL中的运用问题:左乘/右乘,行优先/列优先,...

    转自:http://www.cnblogs.com/soroman/archive/2008/03/21/1115571.html 思考:矩阵及变换,以及矩阵在DirectX和OpenGL中的运用1. ...

  4. (转)Windows 支持 DirectX 和 OpenGL,为什么大多数 PC 游戏还是 DirectX 开发?

    事实上在早年OpenGL即使在游戏领域也是对DirectX压倒性的优势.John Carmack曾嘲讽DirectX是"horribly broken" 的API.直到Direct ...

  5. iOS 使用Quartz和OpenGL绘图

    http://blog.csdn.net/coder9999/article/details/7641701 第十二章 使用Quartz和OpenGL绘图 有时应用程序需要能够自定义绘图.一个库是Qu ...

  6. openGL绘图基本框架

    openGL绘图入门和导入外部文件 本文主要介绍通用绘图软件openGL的数据类型和基本的绘图框架,此外还提供了导入obj外部文件的方法,提供的代码稍作修改即可使用,希望能方便初学者快速上手. ope ...

  7. 比较DirectX和OpenGL的区别(比较详细)

    OpenGL是个专业的3D程序接口,是一个功能强大,调用方便的底层3D图形库.OpenGL的前身是SGI公司为其图形工作站开发的IRIS GL.IRIS GL是一个工业标准的3D图形软件接口,功能虽然 ...

  8. 如何检查显卡类型,DirectX和OpenGL的版本

    How To: Check the graphics card type and OpenGL version From: http://support.esri.com/technical-arti ...

  9. 61.H5---利用canvas+原生js进行鼠标跟随绘图

    <!doctype html><html lang="en"><head> <meta charset="UTF-8" ...

随机推荐

  1. 《Java程序设计》第4周学习总结

    学号20145220 <Java程序设计>第4周学习总结 6.1.1 继承共同行为 •定义:继承基本上就是避免多个类间重复定义共同行为. •优点:1.提高了代码的复用性.2.让类与类之间产 ...

  2. linux之mysql启动问题

    网站总是挂掉,查看到原来是mysql总是莫名其妙的挂掉 1.查看mysql日志的位置 mysql> show VARIABLES like '%log%'; +----------------- ...

  3. phpmyadmin的安装和使用

    首先在phpmyadmin的官方网站的下载页面根据自己的PHP以及MYSQL的版本下载对应的phpmyadmin版本. 图中红框部分标识此版本支持度额PHP版本以及MYADL版本. 比如此版本就是支持 ...

  4. javascript输出图的简单路径

    <script> //图的构建 function vnode() { this.visited=0; this.vertex=0; this.arcs=new Array(); } fun ...

  5. jquery获取高度错误(可以获取到宽度,但获取不到高度),及解决办法

    <div class="foo"> <div style="display: none;"> 3333333 </div> ...

  6. cookies的理解

    设置cookie 每个cookie都是一个名/值对,可以把下面这样一个字符串赋值给document.cookie: document.cookie="userId=828"; 如果 ...

  7. 委托,C#本身的委托(Action Func)

    1.Action 分为带泛型的和不带泛型的,带泛型可传入任何类型的参数. 格式如下: using System; using System.Collections.Generic; using Sys ...

  8. ABBYY FineReader的图像编辑器功能使用方法

    日常工作中,有时可能需要对图像进行编辑,可是正常情况下大家都知道图像是不能直接编辑的,需要借助工具.ABBYY FineReader 12 OCR文字识别软件可以实现图像的手动编辑,接下来就具体给大家 ...

  9. vs2012 Nuget错误:“未能解析此远程名称api.nuget.org”

    今天在使用vs2012的Nuget功能向新建MVC项目中添加bootstrap时出现一个错误:“未能解析此远程名称api.nuget.org”: 网上查阅资料得知:nuget.org使用的godadd ...

  10. 【转载】springMVC表单校验+全注解

    在这篇文章中,我们将学习如何使用Spring表单标签, 表单验证使用 JSR303 的验证注解,hibernate-validators,提供了使用MessageSource和访问静态资源(如CSS, ...