You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

105 lines
4.0 KiB

using System;
using System.Runtime.InteropServices;
using AOT;
using UnityEngine;
public partial class RenderModule: CallbackHandler<RenderModule>
{
private const int MaxAliasFrames = 256; // Should match MAXALIASFRAMES
private void BuildCallbacks()
{
var callbacks = new Callbacks
{
target = TargetPtr,
UploadAliasModel = CreateCallback<UploadAliasModelCallback>(Callback_UploadAliasModel),
UploadBrushModel = CreateCallback<UploadBrushModelCallback>(Callback_UploadBrushModel),
UploadTexture = CreateCallback<UploadTextureCallback>(Callback_UploadTexture),
};
RegisterCallbacks(callbacks);
}
/// <summary>
/// This matches unity_modcalls_t from mod_uniquake.c in native code.
/// </summary>
[StructLayout(LayoutKind.Sequential, Pack = 0)]
private class Callbacks
{
public IntPtr target;
public IntPtr UploadAliasModel;
public IntPtr UploadBrushModel;
public IntPtr UploadTexture;
}
[UnmanagedFunctionPointer(CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
private delegate int UploadAliasModelCallback(IntPtr target, [MarshalAs(UnmanagedType.LPStr)] string name,
QAliasHeader header, QAliasFrameType frameType, IntPtr frames,
[MarshalAs(UnmanagedType.LPArray, SizeConst = MaxAliasFrames)] IntPtr[] poseVerts, IntPtr triangles, IntPtr stVerts);
[MonoPInvokeCallback(typeof(UploadAliasModelCallback))]
private static int Callback_UploadAliasModel(IntPtr target,
string name, QAliasHeader header, QAliasFrameType frameType, IntPtr frames,
IntPtr[] poseVerts, IntPtr triangles, IntPtr stVerts)
{
if (header == null)
{
Debug.LogWarning($"Uploading invalid alias model, name = {name}");
return 0;
}
if (header.numFrames > MaxAliasFrames)
header.numFrames = MaxAliasFrames;
if (frames != IntPtr.Zero)
header.frames = frames.ToStructArray<QAliasFrameDesc>(header.numFrames);
header.numPoses = 0;
for (int i = 0; i < header.numFrames; ++i)
{
header.numPoses += header.frames[i].numPoses;
}
var poseVertices = new QTriVertex[header.numPoses][];
for (int i = 0; i < header.numPoses; ++i)
{
poseVertices[i] = poseVerts[i].ToStructArray<QTriVertex>(header.numVerts);
}
var glTextures = new QGLTexture[QConstants.MaxSkins][];
var fbTextures = new QGLTexture[QConstants.MaxSkins][];
for (int i = 0; i < QConstants.MaxSkins; ++i)
{
glTextures[i] = header.glTextures[i].ToStructArray<QGLTexture>(4);
fbTextures[i] = header.fbTextures[i].ToStructArray<QGLTexture>(4);
}
return GetSelf(target).UploadAliasModel(
name, header, frameType, poseVertices,
triangles.ToStructArray<QTriangle>(header.numTriangles),
stVerts.ToStructArray<QSTVert>(header.numVerts),
glTextures, fbTextures);
}
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
private delegate int UploadBrushModelCallback(IntPtr target, QModel model);
[MonoPInvokeCallback(typeof(UploadBrushModelCallback))]
private static int Callback_UploadBrushModel(IntPtr target, QModel model)
{
return GetSelf(target).UploadBrushModel(model);
}
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
private delegate bool UploadTextureCallback(IntPtr target, QGLTexture texture, IntPtr data, ref uint texNum);
[MonoPInvokeCallback(typeof(UploadTextureCallback))]
private static bool Callback_UploadTexture(IntPtr target, QGLTexture texture, IntPtr data, ref uint texNum)
{
byte[] dataBytes = new byte[texture.width * texture.height * 4]; // 32 bits per pixel
Marshal.Copy(data, dataBytes, 0, dataBytes.Length);
return GetSelf(target).UploadTexture(texture, dataBytes, ref texNum);
}
}