C#中使用OpenGL:(八)OpenGL扩展函数

一般而言,扩展函数指的是没有正式发布但已经存在于显卡驱动中的函数,这里指的是已经正式发布的,但版本号高于1.1的OpenGL函数。前面的文章已经探讨过在C#中使用1.1版本的OpenGL函数,也研究过如何在C#中搭建OpenGL渲染环境。如果对性能没什么要求,也不打算做太复杂的东西,那么前面所做的工作已经够用了。如果想做更酷的东西,那么使用高版本的扩展函数是必不可少的。下面将粗略地说明如何在C#程序中使用高版本的OpenGL函数。

对于1.1版本的OpenGL,只需声明一个外部的方法即可对其引用。对于高于1.1版本的OpenGL,要引用它还需要多做一些工作。如果是使用C语言,通常需要先查询该扩展是否存在,若存在则获取函数指针,然后通过函数指针来执行该函数。而在C#中,不支持C语言中的函数指针,因此需要将函数指针转变为C#的委托,通过委托来执行该函数。

由于使用的是正式发布的函数,不出意外的话,这些函数都是存在于显卡驱动中的,因此这里跳过查询这一步。其引用步骤如下:

1、通过函数名称获取函数指针;

2、声明委托;

3、将函数指针转变为委托;

4、通过委托执行函数。

基本上,通过以上四步走就可以引用高版本的OpenGL了。

一、获取OpenGL函数指针

获取OpenGL函数中指针需要用到一个wgl函数,该函数在opengl32.dll中,其C语言声明如下:

PROC WINAPI wglGetProcAddress(
   LPCSTR lpszProc
);
WINAPI表示调用约定是StdCall。参数是指向字符串的指针,如果成功则返回函数的指针,否则返回NULL。

C#方法声明如下:

[DllImport("opengl32.dll", ExactSpelling = false, EntryPoint = "wglGetProcAddress", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.StdCall)]
internal static extern IntPtr wglGetProcAddress(string funcName);
例如获取glActiveTexture的函数指针:

IntPtr funcPointer;
funcPointer=wglGetProcAddress("glActiveTexture");

二、声明委托

C#的委托跟C语言的函数指针的作用类似。每一个函数指针,都对应一个委托,换句话说,有多少个OpenGL函数,就要声明多少个委托。例子是声明glActiveTexture函数的委托,基本上跟声明方法是一样的,有返回值,也有参数,不一样的是需要在前面加上delegate(委托)这个关键字。

internal delegate void ActiveTexture(uint texture);

由于函数众多,手动输入会耗费很多时间,因此采用代码自动生成。下图是代码自动生成的结果:


三、将函数指针转变为委托

C#不能直接使用函数中指针,而是要通过委托,因此在获取函数指针之后要将其转换为委托。C#提供了将函数中指针转换为委托的方法,要是用这个方法首先要引用名称空间:

using System.Runtime.InteropServices;
下面通过例子来说明:

前面已经声明了委托ActiveTexture。

IntPtr funcPointer;
ActiveTexture dele;
funcPointer=wglGetProcAddress("glActiveTexture");
dele=Marshal.GetDelegateForFunctionPointer(funcPointer,typeof(ActiveTexture));

四、通过委托执行函数

声明一个方法glActiveTexture,该方法的目的是封装委托。

public void glActiveTexture(uint texture)
{
  IntPtr funcPointer;
  ActiveTexture dele;
  funcPointer=wglGetProcAddress("glActiveTexture");
  dele=Marshal.GetDelegateForFunctionPointer(funcPointer,typeof(ActiveTexture));
  dele(texture);
 }

五、总结

C#中引用OpenGL高版本函数的关键在于如何获取函数指针,和将函数指针转变为委托。只要解决了这两个问题,其他的就没什么难度的了。鉴于高本版的OpenGL有上千个函数,而每个函数都要声明一个委托和一个方法,我是通过分析glew.h这个头文件,然后编程自动生成所有的代码。本文只是粗略地介绍方法,如果要了解详细的操作,可以浏览我的源码。到目前为止,基本上已经实现C语言版的OpenGL向C#版的转变。下一步的工作就是开发一些实用的类和方法,使得在C#中使用OpenGL变得更方便。

上一篇:C#中使用OpenGL:(七)创建OpenGL渲染环境










猜你喜欢

转载自blog.csdn.net/qq_28249373/article/details/79047236