winforms - How do I call openGL from C#? -


i programming application in c# using winforms gui. want create control displays 3d graphics using opengl.

i experimented bit opentk , found simple use glcontrol display opengl graphics; had implement method handled paint event of glcontrol , within method call opentk wrapper methods, e.g instead of

glvertex2d(0.0, 0.0); 

i call:

gl.vertex2(0.0, 0.0); 

i found possible mix opentk calls directly opengl using p/invoke:

using system; using system.runtime.interopservices; public class gl {     [dllimport("opengl32")]     public static extern void glvertex2d(double x, double y); };  ... gl.vertex2(0.0, 0.0);    // opentk gl.glvertex2d(1.0, 1.0); // opengl directly using pinvoke 

however, wish remove dependence on opentk alltogether. not want use external library instead call opengl directly.

how opengl "paint" on winform? in other words; how implement glcontrol myself?

how implement glcontrol myself?

more or less how opentk do; since has source open, can study it!

i warn you: won't easy. must synchronize window/control creation opengl context creation (overriding createhandle, onhandlecreated, onhandledestroyed), , override onpaint routine in order make opengl context current (indeed allowing drawing in paint phase).

just give idea: usercontrol (partial) implementation:

protected override void createhandle() {     // create render window     mrenderwindow = new renderwindow(this);     mrenderwindow.width = (uint)base.clientsize.width;     mrenderwindow.height = (uint)base.clientsize.height;      // "select" device pixel format before creating control handle     switch (environment.osversion.platform) {         case platformid.win32windows:         case platformid.win32nt:             mrenderwindow.precreateobjectwgl(surfaceformat);             break;         case platformid.unix:             mrenderwindow.precreateobjectx11(surfaceformat);             break;     }      // override default swap interval     mrenderwindow.swapinterval = swapinterval;      // base implementation     base.createhandle(); }  /// <summary> /// raises <see cref="e:system.windows.forms.control.handlecreated"/> event. /// </summary> /// <param name="e"> /// <see cref="t:system.eventargs"/> contains event data. /// </param> protected override void onhandlecreated(eventargs e) {     if (designmode == false) {         // finalize control handle creation         // - wgl: setpixelformat         // - glx: store fbconfig , xvisualinfo selected in createhandle()         // ...         // - setup swap interval, if supported         mrenderwindow.create((rendercontext)null);         // create render context (before event handling)         mrendercontext = new rendercontext(mrenderwindow.getdevicecontext(), mrendercontextflags);     }     // base implementation     base.onhandlecreated(e);     // raise createcontext event     if (designmode == false) {         mrendercontext.makecurrent(true);         raisecreatecontextevent(new rendereventargs(mrendercontext, mrenderwindow));         mrendercontext.makecurrent(false);     } }  /// <summary> ///  /// </summary> /// <param name="e"></param> protected override void onhandledestroyed(eventargs e) {     if (designmode == false) {         if (mrendercontext != null) {             // raise destroycontext event             mrendercontext.makecurrent(true);             raisedestroycontextevent(new rendereventargs(mrendercontext, mrenderwindow));             mrendercontext.makecurrent(false);             // dispose renderer context             mrendercontext.dispose();             mrendercontext = null;         }         // dispose renderer window         if (mrenderwindow != null) {             mrenderwindow.dispose();             mrenderwindow = null;         }     }     // base implementation     base.onhandledestroyed(e); }  /// <summary> ///  /// </summary> /// <param name="e"></param> protected override void onpaint(painteventargs e) {     if (designmode == false) {         if (mrendercontext != null) {             // render usercontrol             mrendercontext.makecurrent(true);             // define viewport             opengl.gl.viewport(0, 0, clientsize.width, clientsize.height);              // derived class implementation             try {                 renderthis(mrendercontext);             } catch (exception exception) {              }              // render event             raiserenderevent(new rendereventargs(mrendercontext, mrenderwindow));              // swap buffers if double-buffering             surface.swapsurface();              // base implementation             base.onpaint(e);              mrendercontext.makecurrent(false);         } else {             e.graphics.drawlines(mfailurepen, new point[] {                 new point(e.cliprectangle.left, e.cliprectangle.bottom), new point(e.cliprectangle.right, e.cliprectangle.top),                 new point(e.cliprectangle.left, e.cliprectangle.top), new point(e.cliprectangle.right, e.cliprectangle.bottom),             });              // base implementation             base.onpaint(e);         }     } else {         e.graphics.clear(color.black);         e.graphics.drawlines(mdesignpen, new point[] {                 new point(e.cliprectangle.left, e.cliprectangle.bottom), new point(e.cliprectangle.right, e.cliprectangle.top),                 new point(e.cliprectangle.left, e.cliprectangle.top), new point(e.cliprectangle.right, e.cliprectangle.bottom),             });          // base implementation         base.onpaint(e);     } }  protected override void onclientsizechanged(eventargs e) {     if (mrenderwindow != null) {         mrenderwindow.width = (uint)base.clientsize.width;         mrenderwindow.height = (uint)base.clientsize.height;     }      // base implementation     base.onclientsizechanged(e); }  private static readonly pen mfailurepen = new pen(color.red, 1.5f);  private static readonly pen mdesignpen = new pen(color.green, 1.0f);  #endregion 

(renderwindow utility class selecting device pixel format). key of implementation need mimic same calls classical c++ program does, integrated actual system.windows.forms implementation (.net , mono).

but big task opengl api definition p/invokes: opengl defines lot of enumerants (constants) , entry points (thousands...); human kind, cannot write declaration manually (mainly limited time, error prone). if don't opentk, can start tao framework. if have time waste , lot of patience, can generate c# bindings yourself, using opengl registry.

but... wait, big news (you lucky): xml opengl api definition publicly accessible! (!)

(!) don't understand enthusiastic answer: i'm waiting many, many, many years!!!


Comments

Popular posts from this blog

c++ - Creating new partition disk winapi -

Android Prevent Bluetooth Pairing Dialog -

VBA function to include CDATA -