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控件。

 

没有整理与归纳的知识,一文不值!高度概括与梳理的知识,才是自己真正的知识与技能。 永远不要让自己的自由、好奇、充满创造力的想法被现实的框架所束缚,让创造力自由成长吧! 多花时间,关心他(她)人,正如别人所关心你的。理想的腾飞与实现,没有别人的支持与帮助,是万万不能的。






    本文转自wenglabs博客园博客,原文链接:http://www.cnblogs.com/arxive/p/6225686.html ,如需转载请自行联系原作者




相关文章
|
1月前
|
Linux API iOS开发
【Qt 渲染引擎】一文带你了解qt的三种 渲染引擎,包括栅格引擎(Raster)、OpenGL 和本地绘图系统
【Qt 渲染引擎】一文带你了解qt的三种 渲染引擎,包括栅格引擎(Raster)、OpenGL 和本地绘图系统
28 0
|
缓存 图形学
计算机图形学——实验一 VS+OpenGL绘图环境及基本图形绘制
VS+OpenGL绘图环境及基本图形绘制 1、 熟悉OpenGL的主要功能; 2、 掌握OpenGL的绘图流程和原理; 3、 掌握OpenGL核心函数的使用; 4、 熟悉OpenGL基本图形元素的绘制函数。 二. 实验内容 1、 如预备知识所述,创建一个OpenGL工程,修改第一个程序中的Display()函数,如下: 该程序是在窗口中画两条线,分别用黄色和红色绘制。如上所述,OpenGL是一个状态机,glBegin(UINT State)可以设定如下状态: GL_POINTS 画点 GL_LINES 画线
398 0
计算机图形学——实验一 VS+OpenGL绘图环境及基本图形绘制
|
索引
OpenGL ES 案例08:GLKit使用索引绘图 + 纹理颜色混合
OpenGL ES 案例08:GLKit使用索引绘图 + 纹理颜色混合
83 0
OpenGL ES 案例08:GLKit使用索引绘图 + 纹理颜色混合
|
索引
OpenGL ES 案例07:GLSL使用索引绘图 + 纹理颜色混合
OpenGL ES 案例07:GLSL使用索引绘图 + 纹理颜色混合
287 0
OpenGL ES 案例07:GLSL使用索引绘图 + 纹理颜色混合
|
缓存 Swift 开发者
OpenGL ES 案例06:GLKit使用索引绘图
OpenGL ES 案例06:GLKit使用索引绘图
115 0
OpenGL ES 案例06:GLKit使用索引绘图
|
存储 缓存 异构计算
OpenGL ES 案例05:GLSL使用索引绘图
OpenGL ES 案例05:GLSL使用索引绘图
230 0
OpenGL ES 案例05:GLSL使用索引绘图
|
缓存 索引 Windows
|
Android开发
Android官方开发文档Training系列课程中文版:OpenGL绘图之添加动态效果
原文地址:http://android.xsoftlab.net/training/graphics/opengl/motion.html 在屏幕上绘制物体只是OpenGL基础的基础,除了OpenGL,你还可以使用Canvas及Drawable对象做到同样的功能。
946 0
|
Android开发
Android官方开发文档Training系列课程中文版:OpenGL绘图之响应触摸事件
原文地址:http://android.xsoftlab.net/training/graphics/opengl/touch.html 使图形按照程序设计的轨迹旋转对OpenGL来说还是不能发挥出它应有的实力。
1000 0