2016-05-04 65 views
0

我想在OpenGL上使用C#中的一些本地函數。 我需要畫一個球,我瞭解gluSphere看着它GL \ glu.h,但收到一個struct對象作爲參數:導入並使用openGL GLUQuadric?

typedef struct GLUquadric GLUquadric; 

void APIENTRY gluSphere(GLUquadric *qobj,GLdouble radius,GLint slices,GLint stacks); 

我需要建立一個結構,所以我可以把它送到gluSphere。 是否有一些地方或信息是如何定義的GLUquadric,所以我可以寫它,並將其發送到gluSphere

[StructLayout(LayoutKind.Sequential)] 
    struct GLUquadric{ 
      //What's here??? 
    } 

回答

0

看起來像谷歌的

「結構GLUquadric」 搜索

沒有給出任何信息或線索......但尋找

「 struct GLUquadric {「

帶我到我想要的地方:

OGLES_GLU.h

結構,我發現和使用,工作原理是:

[StructLayout(LayoutKind.Sequential)] 
     public struct GLUquadric 
     { 
      int normals; 
      bool textureCoords; 
      int orientation; 
      int drawStyle; 
     } 

所以,現在我可以使用:

[DllImport("glu32.dll")] 
static extern void gluSphere(ref GLUquadric qobj, double radius, int slices, int stacks); 
     public static void Sphere(ref GLUquadric qobject, double Radius, int Slices, int Stacks) 
     { 
      gluSphere(ref qobject, Radius, Slices, Stacks); 
     } 

的OpenGL現在繪製領域。

注:在進口openGL的功能繪製球體,不要叫gluDeleteQuadric(); 讓GC做的工作,只是聲明瞭一個新的GLUQuadric()並把它作爲一個refgluSphere,否則你會在你的程序內存問題。

恭維datenwolf的回答這是不是在我的情況下有效:

我計劃的實施是這樣:

[StructLayout(LayoutKind.Sequential)] 
    public struct GLUquadric 
    { 
     int normals; 
     bool textureCoords; 
     int orientation; 
     int drawStyle; 

     public void Init(int norm, int draw, int orient, bool textCoor) 
     { 
      normals = norm; 
      drawStyle = draw; 
      orientation = orient; 
      textureCoords = textCoor; 
     } 
    } 

使用方法是:

  public static void DrawSphere(T Radius, Int32 Slices, Int32 Stacks, 
      GLU.QuadricDrawStyles Style, GLU.QuadricNormals Normal, Color color) 
     { 
      OpenGL.SetColor(color); 
      GLU.GLUquadric quadric = new GLU.GLUquadric(); 
      quadric.Init((int)Normal, (int)Style, 0, false); 
      GLU.Sphere(ref quadric, (dynamic)Radius, Slices, Stacks); 
     } 

實現滿OO ,因此每個球體都與靜態GL函數分離爲gluQuadricDrawStylegluQuadricNormals,所以將struct留空是無效的,因爲它不會畫任何東西。

+0

這種方法的問題是,你不知道GLUquadric的內部存儲器佈局。你發現了* some * GLU實現的結構定義,但是你最終可能會在已安裝的GLU實現使用完全不同的結構佈局的系統上運行,並且如果發生這種情況,則調用C未定義的行爲,即** BAD * *(大寫鎖定所有大膽的壞)。 *永遠不要這樣做!*如果你這樣做,你正在進入一個痛苦的世界。 C代碼在調用UB時的態度的插圖:https://imgur.com/ZlB9kHD – datenwolf

+0

正如我所說,這是工作和屬性是正確的。 我不需要更多的調用glu函數,因爲結構是*正確的* 發送此結構引用可以完全控制屬性,避免調用P/Invoke。 –

+0

它只能巧妙地工作,因爲系統上的GLU的實現碰巧使用與您找到的結構佈局相同的結構佈局。但是,如果你更新你的操作系統,或者分發你的程序,你最終可能會在一個使用完全不同的內部結構佈局的系統上,然後*一切都會中斷。這真的很難理解嗎?你正在處理一個* opaque *數據類型。你不是不應該知道它在內部的外觀。實際上禁止做出任何假設。 – datenwolf

0

更大的問題是,如果你真的想要使用GLU。 GLU幾十年來一直沒有維護,並沒有跟上OpenGL API的發展。 GLU不是OpenGL本身的一部分,它是由SGI和OpenGL共同開發的伴隨庫,與OpenGL-1.1規範一起發佈。 GLU的第一個和最新版本仍然假設存在固定功能管線和即時繪圖模式。兩者都已從現代OpenGL中刪除。

我需要創建一個結構,所以我可以將它發送給gluNewQuadric。

其實沒有必要知道這個結構裏面有什麼。它被定義爲一個不透明的指針類型。把它看作你沒有接口的類實例句柄;你仍然可以將它傳遞給實現這個類的模塊並調用它的全局方法,但是你不能往裏看。從C#的角度來看,這是一個非託管的指針

編輯一個代碼示例(我希望是有效的C#)

[DllImport("glu32.dll")] 
static extern IntPtr gluNewQuadric(); 
[DllImport("glu32.dll")] 
static extern void gluDeleteQuadric(IntPtr quadric); 
[DllImport("glu32.dll")] 
static extern void gluSphere(IntPtr quadric, double radius, int slices, int stacks); 

IntPtr quadric = gluNewQuadric(); 
gluSphere(quadric, 1, 10, 10); 
gluDeleteQuadric(quadric); 

也就是說,如果你接受這些告誡我不知道它會不會有些GLU落實到更有意義的端口被稱.net/CLI,以便它可以從C#本地使用。

你當然也可以通過非託管接口訪問GLU。現在我對C#的個人經驗很少(我對F#有更多的經驗),我從來沒有離開管理理由做非託管的事情。但從我的理解你必須做的只是定義一個整數變量足夠大到保持一個本地指針(如果我沒有弄錯,已經應該有這樣一個整數類型用於保存非託管指針),並使用爲GLUQuadric*類型。

+0

感謝您的信息,我已經知道它,但是您可以將它作爲評論發佈,因爲這不是我的問題的答案 –

+0

@c_str:很明顯,您並沒有真正閱讀我的答案。如果你想使用本地GLU,你不需要知道結構定義。這是一個不透明的指針。從技術上講,它的行爲就像一個句柄。你可以調用gluNewQuadric,它返回一個指向「某物」的指針,稱爲「GLUquadric」結構。但是你不應該看結構;事實上,實際的結構佈局是不確定的,你發現的任何定義都可能與你特定的GLU安裝使用的完全不同。對於什麼值得這個不透明指針只是一個指針大小的整數的數字。 – datenwolf

+0

我讀過它,但它不能幫助我,因爲struct爲null,所以引用將爲空,因爲我正在隔離OpenGL形狀。我不會調用gluSetQuadricNormals或gluSetQuadricDrawStyle。 我所做的是從這些功能中分離出來的。如果我把struct留空,它將不會畫任何東西。如果我創建結構,我可以修改靜態dll導入函數的法線,drawstyle,方向和紋理,並繪製它。 結構對我來說是必要的。 –