Closed Revan1985 closed 1 year ago
Hi,
There's a problem with this interface definition. This is because the code is auto-generated from Windows SDK's header and these headers (DirectX9) are very old and miss annotations to help generators understand the semantics of the methods in question (actually, for newer projects you shouldn't use DirectX9, but DirectX11 or DirectX19).
Anyway. Ideally, the method should be like this. Note the out attribute on ppbData parameter because the pointer is given to the caller by the method implementation (you don't allocate for the call):
HRESULT Lock(uint OffsetToLock, uint SizeToLock, out IntPtr ppbData, uint Flags);
To workaround this small issue, you just need one more indirection, so what you can do so is something like this (untested):
IDirect3DVertexBuffer9 buffer = ...
var vertexArray = new float[whatever];
// allocate memory for a pointer which will be the array pointer
using (var ppbData = new ComMemory(IntPtr.Size)) // ComMemory is provided by DirectN, memory will be free'd automatically
{
buffer.Lock(0, 0, ppbData.Pointer, Constants.D3DLOCK_DISCARD);
try
{
// get array pointer & copy
var arrayPtr = Marshal.ReadIntPtr(ppbData.Pointer);
CopyMemory(Marshal.UnsafeAddrOfPinnedArrayElement(vertexArray, 0), arrayPtr, (IntPtr)(vertexArray.Length * Marshal.SizeOf<float>()));
}
finally
{
buffer.Unlock();
}
}
// need to declare this somewhere
[DllImport("kernel32", ExactSpelling = true, EntryPoint = "RtlMoveMemory")]
private static extern void CopyMemory(IntPtr destination, IntPtr source, IntPtr length);
Thank you, this is what i needed to know. Thank you for your speedy answer 😃
Hello,
I am sorry, but i need to reopen this issue, just to not open a new one...
I am having a similar problem now.
I need to create pixel\vertex shaders, but signature for creation is this...
new HRESULT CreatePixelShader(ref uint pFunction, out IDirect3DPixelShader9 ppShader);
How can i use it? I was trying a similar way, cause i need to create the pixelbuffer from a ReadOnlySpan
Thank you for your support, but the d3d9 wrapper is cryptical 😅
And another question. How can i get the pointer of a IDirect3DSurface9 to use it with a Wpf D3DImage? StructureToPtr fails, so i don't understand how to get it...
Hi,
This is not the same issue, next time please create a new question.
Anyway, it's again caused by legacy C headers for DirectX9. This is how is defined the method in d3d9.h
STDMETHOD(CreatePixelShader)(THIS_ CONST DWORD* pFunction,IDirect3DPixelShader9** ppShader) PURE;
C# ref int
seems equivalent, but pFunction
is in fact an array so the header is indeed not sufficient to generate an equivalent C# code.
I've updated the code https://github.com/smourier/DirectN/commit/839cb42ee7b958cf3e1ab8284a58d34069dbb35c and published new nugets, and it's now generated in C# as
HRESULT CreatePixelShader(IntPtr pFunction, out IDirect3DPixelShader9 ppShader);
thank you for your answer. Yes, you have reason, I should have opened a new issue. Anyway thank you for your patience and support.
Hello, I need an help for using DirectN with Directx9. I am using the IDirect3DVertexBuffer9 Lock method, but since this required an IntPtr, I am not able to understand how translate from c++ to c# code. In c++ I am using this code
VERTEX* vertices; HR(m_pVertexBuffer->Lock(0, 0, (void**)&vertices, D3DLOCK_DISCARD)); ::memcpy(vertices, vertexArray, sizeof(vertexArray)); return m_pVertexBuffer->Unlock();
while in c# should become something similar `nint ppbData = nint.Zero; if ((hr = _vertexBuffer.Object.Lock(0, 0, ppbData, Constants.D3DLOCK_DISCARD)).IsError) { return hr; } var gc = GCHandle.Alloc(vertexArray, GCHandleType.Pinned);I don't understand if I am on right way, or is totally messed up. How should I complete it? I don't know if i need to "allocate" the lock ppbData, and in which way.
Thank you for any support.