enablerbr's picture

Leadwerks integration (was: I need help converting method from Tao to OpenTK.)

this is the method i'm trying to convert from Tao to OpenTK.

public static void MakeCurrent()
        {
            Wgl.wglMakeCurrent(Wgl.wglGetCurrentDC(), Wgl.wglGetCurrentContext());
        }

what is the OpenTK versions of the above Tao Wgl methods? if it helps i'm using a gamewindow.

forgot to mention i'm using svn version of OpenTK and coding in c#.


Comments

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.
the Fiddler's picture

Fancy that. In that case, use:

        public static void MakeCurrent()
        {
            if (Window != null)
                Window.Context.MakeCurrent(Window.WindowInfo);
        }

I am just following the Leadwerks documentation here. It seems that the Leadwerks.GetSize callback uses unsafe code, so there's no way around that.

Edit: The issue with unsafe code is that it is not verifiable, i.e. the runtime engine cannot verify that your code does not do illegal things. Because of this, unverifiable code requires "full trust", which means (by default) that it can only run from your hard disk - not inside a browser or a network share.

It does not mean that unverifiable code is unsafe per se. An IntPtr is worse than a real pointer, because you lose all type information. With int* you know it's a pointer to an int; IntPtr is something akin to void*.

To clear up the confusion, the unsafe code means "not verifiable", not "unsafe". There are many ways to write "unsafe" but verifiable code, without ever using the unsafe keyword.

To sum up, if the Leadwerks C# wrapper requires unverifiable code, you have no choice but to use the unsafe keyword.

enablerbr's picture

well the code executes the createcustumbuffer command then the app just freezes.

i wrote my own wrapper for the Leadwerks dll.

the Fiddler's picture

I thought Leadwerks already contained a C# wrapper? The most probable cause is that the GetSize and/or CreateCustomBuffer wrapper does not match the unmanaged function 100%.

Can you post the code for these wrappers?

enablerbr's picture

i can't due to the fact only payed licence holders can have access. as for the offical c# wrapper. i started mine way before there was an official wrapper.

the Fiddler's picture

Not the complete wrappers, obviously, just for the GetSize delegate and the CreateCustomBuffer functions.

enablerbr's picture

from the offical wrapper.

public delegate void GetSize(int _width, int _height);
 
 
        public delegate void MakeCurrent();
 
        [DllImport(LEADWERKS_DLL, EntryPoint = "CreateCustomBuffer", CallingConvention = CallingConvention.Cdecl)]
        public static extern IntPtr CreateCustomBuffer(GetSize _GetSize, MakeCurrent _MakeCurrent);

from my wrapper.

 public IntPtr CreateCustom(TBuffer.GetSize getsize, TBuffer.MakeCurrent makecurrent)
        {
            return this.Buffer = SafeNativeMethods.TCreateCustomBuffer(getsize, makecurrent);
        }
 
        [SuppressUnmanagedCodeSecurityAttribute]
        [DllImport(ENGINE_DLL, EntryPoint = "CreateCustomBuffer", CallingConvention = CallingConvention.StdCall)]
        internal static extern IntPtr TCreateCustomBuffer(TBuffer.GetSize getsize, TBuffer.MakeCurrent makecurrent);

i had my original code that only used OnRenderFrame to run on v0.9.6 of OpenTK without using createcustumbuffer. that version i only used createbuffer(800,600,TBuffer.BUFFER_COLOR0 | TBuffer.BUFFER_DEPTH | TBuffer.BUFFER_NORMAL) but that was with my static code version of my wrapper and not my instance opp version of my wrapper.

the Fiddler's picture

Try changing the calling convention to CallingConvention.Cdecl (this could be the cause of the access violation).

Moreover, GetSize should probably be:

public delegate void GetSize(out int width, out int height);

or

public delegate void GetSize(int* width, int* height);

if this tutorial is correct.

enablerbr's picture

none of them stop the app from freezing after the createcustom buffer command execution.

the engine creates a log file. when i run my console app version of this code. log reads as follows.

Leadwerks Engine 2.23
Initializing Renderer...
OpenGL Version: 3.0.0
GLSL Version: 1.30 NVIDIA via Cg compiler
Render device: GeForce 8800 GTX/PCI/SSE2
Vendor: NVIDIA Corporation
DrawBuffers2 supported: 0
32 texture units supported.
GPU instancing supported: 1
Max batch size: 1024
Shader model 4.0 supported: 1
Loading shader "zip::c:/users/sammie/documents/visual studio 2008/projects/deepfreezetestapp/deepfreezetestapp/bin/x86/release/shaders.pak//query.vert", ""...
Loading shader "zip::c:/users/sammie/documents/visual studio 2008/projects/deepfreezetestapp/deepfreezetestapp/bin/x86/release/shaders.pak//mesh/mesh_shadow.vert", ""...
Loading shader "zip::c:/users/sammie/documents/visual studio 2008/projects/deepfreezetestapp/deepfreezetestapp/bin/x86/release/shaders.pak//mesh/mesh.vert", "zip::c:/users/sammie/documents/visual studio 2008/projects/deepfreezetestapp/deepfreezetestapp/bin/x86/release/shaders.pak//mesh/mesh.frag"...
Loading shader "zip::c:/users/sammie/documents/visual studio 2008/projects/deepfreezetestapp/deepfreezetestapp/bin/x86/release/shaders.pak//postfilters/postfilter.vert", "zip::c:/users/sammie/documents/visual studio 2008/projects/deepfreezetestapp/deepfreezetestapp/bin/x86/release/shaders.pak//postfilters/depthblit.frag"...
Loading texture "incbin::noise.dds"...
Loading shader "zip::c:/users/sammie/documents/visual studio 2008/projects/deepfreezetestapp/deepfreezetestapp/bin/x86/release/shaders.pak//postfilters/postfilter.vert", "zip::c:/users/sammie/documents/visual studio 2008/projects/deepfreezetestapp/deepfreezetestapp/bin/x86/release/shaders.pak//lighting/ambientlight.frag"...
Loading shader "zip::c:/users/sammie/documents/visual studio 2008/projects/deepfreezetestapp/deepfreezetestapp/bin/x86/release/shaders.pak//lighting/lightvolume.vert", "zip::c:/users/sammie/documents/visual studio 2008/projects/deepfreezetestapp/deepfreezetestapp/bin/x86/release/shaders.pak//lighting/spotlight.frag"...

this is the log for the OpenTK version that is freezing.

Leadwerks Engine 2.23
Initializing Renderer...
OpenGL Version: 2.1.2
GLSL Version: 1.20 NVIDIA via Cg compiler
Render device: GeForce 8800 GTX/PCI/SSE2
Vendor: NVIDIA Corporation
DrawBuffers2 supported: 0
32 texture units supported.
GPU instancing supported: 1
Max batch size: 1024
Shader model 4.0 supported: 1
Loading shader "zip::c:/users/sammie/documents/visual studio 2008/projects/dfopentkapp/dfopentkapp/bin/x86/release/shaders.pak//query.vert", ""...
Loading shader "zip::c:/users/sammie/documents/visual studio 2008/projects/dfopentkapp/dfopentkapp/bin/x86/release/shaders.pak//mesh/mesh_shadow.vert", ""...
Loading shader "zip::c:/users/sammie/documents/visual studio 2008/projects/dfopentkapp/dfopentkapp/bin/x86/release/shaders.pak//mesh/mesh.vert", "zip::c:/users/sammie/documents/visual studio 2008/projects/dfopentkapp/dfopentkapp/bin/x86/release/shaders.pak//mesh/mesh.frag"...

when it freezes it does not get to the OnRenderFrame code.

the Fiddler's picture

Freezes of this kind tend to be linked with stack corruption, which can happen if:

  • the p/invoke does not match the unmanaged signature 100%, or
  • a managed exception escapes into unmanaged code through a callback.

If you try to run the application outside of VS, there is a good chance that it will crash instead of freezing.

Suggestions:

  1. As a test, try calling DGetSize and DMakeCurrent directly during the OnLoad event (comment out CreateCustom etc and step through the debugger). Do they throw any exceptions?
  2. Make sure that the two delegates cannot be collected while CreateCustom is running (i.e. store them into class fields, not temporary variables).
  3. Double check that the delegates match what Leadwerks expects in number of parameters and parameter / return types.
  4. Mark the delegate parameters in CreateCustom with [MarshalAs(UnmanagedType.FunctionPtr)]. I think this is done automatically, but it never hurts to make sure.
  5. Alternatively, define and use CreateCustom like this:
    [DllImport(ENGINE_DLL, EntryPoint = "CreateCustomBuffer", CallingConvention = CallingConvention.StdCall)]
    internal static extern IntPtr TCreateCustomBuffer(IntPtr getsize, IntPtr makecurrent);
    ...
    IntPtr getsize = Marshal.GetFunctionPointerForDelegate(DGetSize);
    IntPtr makecurrent = Marshal.GetFunctionPointerForDelegate(DMakeCurrent);
    buff.CreateCustom(getsize, makecurrent);
  6. Check whether you should use CallingConvention.StdCall or CallingConvention.Cdecl.
enablerbr's picture

taken from the c header file.

typedef unsigned char* BP;		// byte pointer
typedef BP TBuffer;				// unified syntax
typedef	TBuffer		(_stdcall *TCreateCustomBuffer)		(byte* GetSize, byte* MakeCurrent);

i'll try what you have suggested.

suggestion 1 doesn't throw up any exceptions.
suggestion 5 still causes the app to feeze when it's finished OnLoad.