Browse Source

First steps in reorganizing the project, so that assets and game state are managed separately from the interop modules. This will allow for a clearer picture of where gameplay-related interactions should take place, and how entities and such should be linked to their associated assets.

console
Nico de Poel 5 years ago
parent
commit
a886f3d993
  1. 8
      Assets/Scripts/Game.meta
  2. 88
      Assets/Scripts/Game/GameAssets.cs
  3. 11
      Assets/Scripts/Game/GameAssets.cs.meta
  4. 13
      Assets/Scripts/Game/GameState.cs
  5. 11
      Assets/Scripts/Game/GameState.cs.meta
  6. 27
      Assets/Scripts/Modules/GameModule.Interop.cs
  7. 11
      Assets/Scripts/Modules/GameModule.Interop.cs.meta
  8. 14
      Assets/Scripts/Modules/GameModule.cs
  9. 11
      Assets/Scripts/Modules/GameModule.cs.meta
  10. 15
      Assets/Scripts/Modules/RenderModule.Interop.cs
  11. 83
      Assets/Scripts/Modules/RenderModule.cs
  12. 14
      Assets/Scripts/UniQuake.cs
  13. 1
      engine/Quake/gl_model.h
  14. 2
      engine/Quake/gl_rmisc.c
  15. 6
      engine/UniQuake/gl_uniquake.c

8
Assets/Scripts/Game.meta

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 3f9fc42dc891bc547be3172cab9c8ade
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

88
Assets/Scripts/Game/GameAssets.cs

@ -0,0 +1,88 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class GameAssets
{
private readonly UniQuake uq;
private readonly Dictionary<uint, Texture2D> textures = new Dictionary<uint, Texture2D>();
private BrushModel worldModel;
private readonly List<BrushModel> brushModels = new List<BrushModel>();
private readonly List<AliasModel> aliasModels = new List<AliasModel>();
private uint nextTexNum = 0x10001;
public GameAssets(UniQuake uniQuake)
{
uq = uniQuake;
}
public uint SetTexture(uint texNum, Texture2D texture)
{
if (texNum == 0)
{
// Assign a new texture number
while (textures.ContainsKey(nextTexNum))
++nextTexNum;
texNum = nextTexNum++;
}
textures[texNum] = texture;
return texNum;
}
public bool TryGetTexture(uint texNum, out Texture2D texture)
{
texture = null;
return texNum > 0 && textures.TryGetValue(texNum, out texture);
}
public void AddAliasModel(AliasModel aliasModel)
{
aliasModels.Add(aliasModel);
}
public void AddBrushModel(BrushModel brushModel)
{
brushModels.Add(brushModel);
}
public void SetWorldModel(BrushModel brushModel)
{
worldModel?.Dispose(); // TODO: also need to clean up any GameObjects made from this
worldModel = brushModel;
}
public void Destroy()
{
if (worldModel != null)
{
worldModel.Dispose();
worldModel = null;
}
foreach (var brushModel in brushModels)
{
// brushModel.Dispose(); // TODO: reactivate when done testing in editor
}
brushModels.Clear();
foreach (var aliasModel in aliasModels)
{
// aliasModel.Dispose(); // TODO: reactivate when done testing in editor
}
aliasModels.Clear();
foreach (var texture in textures.Values)
{
// Object.Destroy(texture); // TODO: reactivate when done testing in editor
}
textures.Clear();
}
}

11
Assets/Scripts/Game/GameAssets.cs.meta

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 3821114b8377e3a458eebb55f1363672
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

13
Assets/Scripts/Game/GameState.cs

@ -0,0 +1,13 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class GameState
{
private readonly UniQuake uq;
public GameState(UniQuake uniQuake)
{
uq = uniQuake;
}
}

11
Assets/Scripts/Game/GameState.cs.meta

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 27dd2ba6514f88c4bb767eb1765546de
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

27
Assets/Scripts/Modules/GameModule.Interop.cs

@ -0,0 +1,27 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using UnityEngine;
public partial class GameModule : CallbackHandler<GameModule>
{
private void BuildCallbacks()
{
var callbacks = new Callbacks
{
target = TargetPtr,
};
RegisterCallbacks(callbacks);
}
/// <summary>
/// This matches unity_gamecalls_t from mod_uniquake.c in native code.
/// </summary>
[StructLayout(LayoutKind.Sequential, Pack = 0)]
private class Callbacks
{
public IntPtr target;
}
}

11
Assets/Scripts/Modules/GameModule.Interop.cs.meta

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: b8d9b402c1d6a3d4a8634a85bece7d77
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

14
Assets/Scripts/Modules/GameModule.cs

@ -0,0 +1,14 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public partial class GameModule
{
private readonly UniQuake uq;
public GameModule(UniQuake uniQuake)
{
uq = uniQuake;
BuildCallbacks();
}
}

11
Assets/Scripts/Modules/GameModule.cs.meta

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 204138db5cbbd944ebc9bd1c5adfadcc
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

15
Assets/Scripts/Modules/RenderModule.Interop.cs

@ -15,6 +15,8 @@ public partial class RenderModule: CallbackHandler<RenderModule>
UploadAliasModel = CreateCallback<UploadAliasModelCallback>(Callback_UploadAliasModel),
UploadBrushModel = CreateCallback<UploadBrushModelCallback>(Callback_UploadBrushModel),
UploadWorldModel = CreateCallback<UploadWorldModelCallback>(Callback_UploadWorldModel),
UploadTexture = CreateCallback<UploadTextureCallback>(Callback_UploadTexture),
SetupView = CreateCallback<SetupViewCallback>(Callback_SetupView),
};
@ -32,6 +34,7 @@ public partial class RenderModule: CallbackHandler<RenderModule>
public IntPtr UploadAliasModel;
public IntPtr UploadBrushModel;
public IntPtr UploadWorldModel;
public IntPtr UploadTexture;
public IntPtr SetupView;
}
@ -96,6 +99,18 @@ public partial class RenderModule: CallbackHandler<RenderModule>
return GetSelf(target).UploadBrushModel(model);
}
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
private delegate int UploadWorldModelCallback(IntPtr target, QModel model);
[MonoPInvokeCallback(typeof(UploadBrushModelCallback))]
private static int Callback_UploadWorldModel(IntPtr target, QModel model)
{
if (model == null || model.type != QModelType.Brush)
return -1;
return GetSelf(target).UploadWorldModel(model);
}
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
private delegate bool UploadTextureCallback(IntPtr target, QGLTexture texture, IntPtr data, ref uint texNum);

83
Assets/Scripts/Modules/RenderModule.cs

@ -5,12 +5,7 @@ using UnityEngine.Rendering;
public partial class RenderModule
{
private readonly UniQuake uq;
private readonly List<BrushModel> brushModels = new List<BrushModel>();
private readonly List<AliasModel> aliasModels = new List<AliasModel>();
private readonly Dictionary<uint, Texture2D> textures = new Dictionary<uint, Texture2D>();
private BrushModel worldModel;
public RenderModule(UniQuake uniQuake)
{
uq = uniQuake;
@ -20,33 +15,6 @@ public partial class RenderModule
globalZPos -= 256f;
}
public override void Destroy()
{
base.Destroy();
foreach (var brushModel in brushModels)
{
// brushModel.Dispose(); // TODO: reactivate when done testing in editor
}
brushModels.Clear();
worldModel = null;
foreach (var aliasModel in aliasModels)
{
// aliasModel.Dispose(); // TODO: reactivate when done testing in editor
}
aliasModels.Clear();
foreach (var texture in textures.Values)
{
// Object.Destroy(texture); // TODO: reactivate when done testing in editor
}
textures.Clear();
}
private float xPos = -2048f;
private float zPos = 0f;
private static float globalZPos = 0f;
@ -66,7 +34,8 @@ public partial class RenderModule
string modelName = System.IO.Path.GetFileNameWithoutExtension(name);
AliasModel aliasModel = new AliasModel(modelName, frameType);
aliasModel.ImportMeshData(header, poseVertices, triangles, stVertices);
aliasModels.Add(aliasModel);
uq.GameAssets.AddAliasModel(aliasModel);
var go = new GameObject(modelName);
go.transform.SetPositionAndRotation(new Vector3(xPos, 0, zPos), Quaternion.identity);
@ -75,18 +44,18 @@ public partial class RenderModule
var material = new Material(Shader.Find("Universal Render Pipeline/Simple Lit"));
uint texNum = glTextures[0][0].texNum;
if (texNum > 0 && textures.ContainsKey(texNum))
if (uq.GameAssets.TryGetTexture(texNum, out var texture))
{
material.mainTexture = textures[texNum];
material.mainTexture = texture;
}
if (fbTextures != null && fbTextures[0] != null && fbTextures[0][0] != null)
{
var fbTexNum = fbTextures[0][0].texNum;
if (fbTexNum > 0 && textures.ContainsKey(fbTexNum))
if (uq.GameAssets.TryGetTexture(fbTexNum, out var fbTexture))
{
material.EnableKeyword("_EMISSION");
material.SetTexture("_EmissionMap", textures[fbTexNum]);
material.SetTexture("_EmissionMap", fbTexture);
material.SetColor("_EmissionColor", Color.white);
}
}
@ -119,15 +88,29 @@ public partial class RenderModule
}
xPos += 128f;
return aliasModels.Count;
return 1;
}
private int UploadBrushModel(QModel model)
{
Debug.Log($"Brush model '{model.name}' with {model.numVertices} vertices, {model.numEdges} edges, {model.numSurfaces} surfaces");
var brushModel = new BrushModel(model.name);
brushModel.ImportMeshData(model);
uq.GameAssets.AddBrushModel(brushModel);
return 1;
}
private int UploadWorldModel(QModel model)
{
Debug.Log($"World model '{model.name}' with {model.numVertices} vertices, {model.numEdges} edges, {model.numSurfaces} surfaces");
var brushModel = new BrushModel(model.name);
brushModel.ImportMeshData(model);
uq.GameAssets.SetWorldModel(brushModel);
// DEBUG
var worldGO = new GameObject(model.name);
@ -147,9 +130,9 @@ public partial class RenderModule
var material = new Material(Shader.Find("Universal Render Pipeline/Simple Lit"));
uint texNum = surfaceMesh.Texture.TextureNum;
if (texNum > 0 && textures.ContainsKey(texNum))
if (uq.GameAssets.TryGetTexture(texNum, out var texture))
{
material.mainTexture = textures[texNum];
material.mainTexture = texture;
}
var mr = meshGO.AddComponent<MeshRenderer>();
@ -161,34 +144,22 @@ public partial class RenderModule
}
}
brushModels.Add(brushModel);
return brushModels.Count;
return 1;
}
private uint nextTexNum = 0x10001;
private bool UploadTexture(QGLTexture texture, byte[] data, ref uint texNum)
{
Debug.Log($"Texture '{texture.name}' with dimensions {texture.width}x{texture.height}, data size = {data.Length} bytes");
if (texture.width == 0 || texture.height == 0)
return false;
if (texNum == 0)
{
// Assign a new texture number
while (textures.ContainsKey(nextTexNum))
++nextTexNum;
texNum = nextTexNum++;
}
var tex = new Texture2D((int)texture.width, (int)texture.height, TextureFormat.RGBA32, texture.flags.HasFlag(QTexPrefs.Mipmap));
tex.name = texture.name;
tex.SetPixelData(data, 0);
tex.Apply();
textures[texNum] = tex;
texNum = uq.GameAssets.SetTexture(texNum, tex);
return true;
}

14
Assets/Scripts/UniQuake.cs

@ -12,6 +12,7 @@ public partial class UniQuake: MonoBehaviour
private QuakeParms quakeParms;
private SystemModule systemModule;
private RenderModule renderModule;
private GameModule gameModule;
private bool initialized = false;
private double startTime;
@ -29,6 +30,9 @@ public partial class UniQuake: MonoBehaviour
/// Time since startup for this particular instance of Quake
/// </summary>
public double CurrentTime => Time.realtimeSinceStartupAsDouble - startTime;
public GameAssets GameAssets { get; private set; }
public GameState GameState { get; private set; }
private Action<string> logHandler;
private StringBuilder logBuffer = new StringBuilder();
@ -39,15 +43,19 @@ public partial class UniQuake: MonoBehaviour
systemModule = new SystemModule(this);
renderModule = new RenderModule(this);
gameModule = new GameModule(this);
GameAssets = new GameAssets(this);
GameState = new GameState(this);
LoadLibrary();
List<string> arguments = new List<string>
{
"",
"-window",
"-width", "1440",
"-height", "1080",
//"-fullscreen", "-width", "1920", "-height", "1080",
"-window", "-width", "1440", "-height", "1080",
//"-window", "-width", "2240", "-height", "1260",
};
switch (BaseGame)

1
engine/Quake/gl_model.h

@ -518,5 +518,6 @@ void Mod_SetExtraFlags (qmodel_t *mod);
int UQ_GL_UploadAliasModel(qmodel_t *model, aliashdr_t *aliashdr, aliasframetype_t frametype, trivertx_t **poseVerts, mtriangle_t *triangles, stvert_t *stVerts);
int UQ_GL_UploadBrushModel(qmodel_t *model);
int UQ_GL_UploadWorldModel(qmodel_t *model);
#endif // __MODEL__

2
engine/Quake/gl_rmisc.c

@ -404,7 +404,7 @@ void R_NewMap (void)
//ericw -- no longer load alias models into a VBO here, it's done in Mod_LoadAliasModel
#endif // USE_OPENGL
UQ_GL_UploadBrushModel(cl.worldmodel);
UQ_GL_UploadWorldModel(cl.worldmodel);
r_framecount = 0; //johnfitz -- paranoid?
r_visframecount = 0; //johnfitz -- paranoid?

6
engine/UniQuake/gl_uniquake.c

@ -9,6 +9,7 @@ typedef struct unity_glcalls_s
int(*UploadAliasModel)(void *target, const char *name, aliashdr_t *aliashdr, aliasframetype_t frametype, maliasframedesc_t *frames, trivertx_t **poseVerts, mtriangle_t *triangles, stvert_t *stVerts);
int(*UploadBrushModel)(void *target, qmodel_t *model);
int(*UploadWorldModel)(void *target, qmodel_t *model);
qboolean(*UploadTexture)(void *target, gltexture_t *texture, unsigned *data, GLuint *texnum);
void(*SetupView)(void *target, vec3_t origin, vec3_t angles, mleaf_t *viewLeaf);
} unity_glcalls_t;
@ -27,6 +28,11 @@ int UQ_GL_UploadBrushModel(qmodel_t *model)
return unity_glcalls->UploadBrushModel(unity_glcalls->target, model);
}
int UQ_GL_UploadWorldModel(qmodel_t *model)
{
return unity_glcalls->UploadWorldModel(unity_glcalls->target, model);
}
qboolean UQ_GL_UploadTexture(gltexture_t *texture, unsigned *data)
{
// Allow UniQuake to either sync up its internal texture reference number, or assign a new one.

Loading…
Cancel
Save