Browse Source

Merge branch 'master' into console

console
Nico de Poel 5 years ago
parent
commit
2de4c7af98
  1. 1221
      Assets/Scenes/SplitScreenTest.unity
  2. 7
      Assets/Scenes/SplitScreenTest.unity.meta
  3. 3
      Assets/Scripts/Data/QConstants.cs
  4. 8
      Assets/Scripts/Game/Entity.cs
  5. 41
      Assets/Scripts/Game/GameAssets.cs
  6. 51
      Assets/Scripts/Game/GameState.cs
  7. 9
      Assets/Scripts/Layers.cs
  8. 6
      Assets/Scripts/Modules/GameModule.Interop.cs
  9. 4
      Assets/Scripts/Modules/GameModule.cs
  10. 16
      Assets/Scripts/Modules/RenderModule.Interop.cs
  11. 9
      Assets/Scripts/Modules/RenderModule.cs
  12. 63
      Assets/Scripts/SplitScreenTest.cs
  13. 11
      Assets/Scripts/SplitScreenTest.cs.meta
  14. 62
      Assets/Scripts/Support/AliasModel.cs
  15. 11
      Assets/Scripts/UniQuake.Interop.cs
  16. 3
      Assets/Scripts/UniQuake.cs
  17. 52
      Assets/Scripts/VisualStyle.cs
  18. 8
      Assets/Shaders.meta
  19. 122
      Assets/Shaders/Quake.shader
  20. 10
      Assets/Shaders/Quake.shader.meta
  21. 157
      Assets/Shaders/QuakeForwardPass.hlsl
  22. 10
      Assets/Shaders/QuakeForwardPass.hlsl.meta
  23. 51
      Assets/Shaders/QuakeInput.hlsl
  24. 10
      Assets/Shaders/QuakeInput.hlsl.meta
  25. 4
      Assets/Styles/GLQuake/GLQuake.asset
  26. 13
      Assets/Styles/GLQuake/Materials/GLQuake_Entity.mat
  27. 13
      Assets/Styles/GLQuake/Materials/GLQuake_World.mat
  28. 26
      Assets/Styles/GLQuake/Software.asset
  29. 8
      Assets/Styles/GLQuake/Software.asset.meta
  30. 2
      ProjectSettings/GraphicsSettings.asset
  31. 2
      ProjectSettings/ProjectSettings.asset
  32. 12
      ProjectSettings/TagManager.asset
  33. 2
      engine/Quake/client.h
  34. 1
      engine/Quake/gl_texmgr.h
  35. 5
      engine/Quake/r_alias.c
  36. 4
      engine/Quake/r_brush.c
  37. 6
      engine/UniQuake/game_uniquake.c
  38. 6
      engine/UniQuake/gl_uniquake.c
  39. 5
      engine/UniQuake/vid_uniquake.c

1221
Assets/Scenes/SplitScreenTest.unity
File diff suppressed because it is too large
View File

7
Assets/Scenes/SplitScreenTest.unity.meta

@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 4ca6e7235b69a0d4dbe7cadc2b23fb6e
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

3
Assets/Scripts/Data/QConstants.cs

@ -5,4 +5,7 @@
public const int MaxSkins = 32; // Should correspond to MAX_SKINS
public const int MaxDLights = 64; // Should correspond to MAX_DLIGHTS
public const int MaxLightmaps = 4; // Should correspond to MAXLIGHTMAPS
public const int LightmapBlockWidth = 256; // Should correspond to LMBLOCK_WIDTH
public const int LightmapBlockHeight = 256; // Should correspond to LMBLOCK_HEIGHT
}

8
Assets/Scripts/Game/Entity.cs

@ -79,7 +79,7 @@ public class Entity
AssignMeshRenderer();
// Set a default pose based on the first animation frame
UpdateAnimation(0);
UpdateAnimation(0, 0, 0f);
if (model.AutoAnimate)
{
@ -103,11 +103,11 @@ public class Entity
worldModel.transform.SetParent(gameObject.transform);
}
public void UpdateAnimation(float frameNum)
public void UpdateAnimation(int pose1, int pose2, float blend)
{
if (aliasModel != null)
{
aliasModel.Animate(frameNum, out Mesh mesh, out float blendWeight);
aliasModel.Animate(pose1, pose2, blend, out Mesh mesh, out float blendWeight);
if (skinnedMeshRenderer.enabled)
{
@ -151,7 +151,7 @@ public class Entity
private void AssignMeshRenderer()
{
material = visualStyle.CreateEntityMaterial();
material = visualStyle.CreateEntityMaterial(true);
if (aliasModel.IsAnimated)
{

41
Assets/Scripts/Game/GameAssets.cs

@ -7,6 +7,7 @@ public class GameAssets
private readonly UniQuake uq;
private readonly Dictionary<uint, Texture2D> textures = new Dictionary<uint, Texture2D>();
private readonly Dictionary<int, Texture2D> lightmaps = new Dictionary<int, Texture2D>();
private BrushModel worldModel;
private readonly List<BrushModel> brushModels = new List<BrushModel>();
@ -46,6 +47,39 @@ public class GameAssets
return texNum > 0 && textures.TryGetValue(texNum, out texture);
}
public bool TryGetTexture(string texName, out Texture2D texture)
{
foreach (var tex in textures.Values)
{
if (tex.name == texName)
{
texture = tex;
return true;
}
}
texture = null;
return false;
}
public void UploadLightmap(int lightmapNum, int width, int height, byte[] data)
{
if (!lightmaps.TryGetValue(lightmapNum, out var lightmap))
{
lightmap = new Texture2D(width, height, TextureFormat.RGBA32, false) { name = $"Lightmap_{lightmapNum}", wrapMode = TextureWrapMode.Clamp };
lightmaps.Add(lightmapNum, lightmap);
}
lightmap.SetPixelData(data, 0);
lightmap.Apply();
}
public bool TryGetLightmap(int lightmapNum, out Texture2D lightmap)
{
lightmap = null;
return lightmapNum >= 0 && lightmaps.TryGetValue(lightmapNum, out lightmap);
}
public void AddAliasModel(AliasModel aliasModel)
{
aliasModels.Add(aliasModel);
@ -126,6 +160,13 @@ public class GameAssets
aliasModels.Clear();
foreach (var lightmap in lightmaps.Values)
{
Object.Destroy(lightmap);
}
lightmaps.Clear();
foreach (var texture in textures.Values)
{
Object.Destroy(texture);

51
Assets/Scripts/Game/GameState.cs

@ -31,11 +31,11 @@ public class GameState
// The first sub-model contains all of the static geometry
var subModel = worldModel.GetSubModel(0);
var subModelGO = CreateBrushGameObject(subModel);
var subModelGO = CreateWorldBrushObject(subModel);
subModelGO.transform.SetParent(worldGameObject.transform);
}
private GameObject CreateBrushGameObject(BrushModel.SubModel subModel)
private GameObject CreateWorldBrushObject(BrushModel.SubModel subModel)
{
var subModelGO = new GameObject(subModel.Name) { layer = (int)uq.GameLayer };
@ -44,21 +44,50 @@ public class GameState
var meshGO = new GameObject(surfaceMesh.Mesh.name) { layer = (int)uq.GameLayer };
meshGO.transform.SetParent(subModelGO.transform);
var mf = meshGO.AddComponent<MeshFilter>();
var mr = meshGO.AddComponent<MeshRenderer>();
mf.sharedMesh = surfaceMesh.Mesh;
var meshFilter = meshGO.AddComponent<MeshFilter>();
meshFilter.sharedMesh = surfaceMesh.Mesh;
// TODO FIXME This is wrong for brush model entities
uq.CurrentStyle.SetupWorldRenderer(mr);
mr.material = uq.CurrentStyle.CreateWorldMaterial(surfaceMesh.Flags); // TODO FIXME this currently leaks Materials
var meshRenderer = meshGO.AddComponent<MeshRenderer>();
uq.CurrentStyle.SetupWorldRenderer(meshRenderer);
meshRenderer.material = uq.CurrentStyle.CreateWorldMaterial(surfaceMesh.Flags); // TODO FIXME this currently leaks Materials
uint texNum = surfaceMesh.TextureNum;
if (uq.GameAssets.TryGetTexture(texNum, out var texture))
{
uint fbNum = surfaceMesh.FullBrightNum;
uq.GameAssets.TryGetTexture(fbNum, out var fullBright);
uq.GameAssets.TryGetLightmap(surfaceMesh.Lightmap, out var lightmap);
uq.CurrentStyle.SetWorldTextures(mr.material, texture, fullBright, null);
uq.CurrentStyle.SetWorldTextures(meshRenderer.material, texture, fullBright, lightmap);
}
}
return subModelGO;
}
private GameObject CreateEntityBrushObject(BrushModel.SubModel subModel)
{
var subModelGO = new GameObject(subModel.Name) { layer = (int)uq.GameLayer };
foreach (var surfaceMesh in subModel.SurfaceMeshes)
{
var meshGO = new GameObject(surfaceMesh.Mesh.name) { layer = (int)uq.GameLayer };
meshGO.transform.SetParent(subModelGO.transform);
var meshFilter = meshGO.AddComponent<MeshFilter>();
meshFilter.sharedMesh = surfaceMesh.Mesh;
var meshRenderer = meshGO.AddComponent<MeshRenderer>();
uq.CurrentStyle.SetupEntityRenderer(meshRenderer);
meshRenderer.material = uq.CurrentStyle.CreateEntityMaterial(false); // TODO FIXME this currently leaks Materials
uint texNum = surfaceMesh.TextureNum;
if (uq.GameAssets.TryGetTexture(texNum, out var texture))
{
uint fbNum = surfaceMesh.FullBrightNum;
uq.GameAssets.TryGetTexture(fbNum, out var fullBright);
uq.CurrentStyle.SetEntityTextures(meshRenderer.material, texture, fullBright);
}
}
@ -111,7 +140,7 @@ public class GameState
var brushModelGO = new GameObject(brushModel.Name) { layer = (int)Layers.Game1 };
for (int i = 0; i < brushModel.SubModelCount; ++i)
{
var subModelGO = CreateBrushGameObject(brushModel.GetSubModel(i));
var subModelGO = CreateEntityBrushObject(brushModel.GetSubModel(i));
subModelGO.transform.SetParent(brushModelGO.transform);
}
@ -131,7 +160,7 @@ public class GameState
// TODO: these relatively complex world game objects are going to get destroyed and re-created all the time
// as the player moves through the map and moves in and out of range of these entities. This can and should
// be done more efficiently by creating the game objects only once and enabling/disabling them on demand.
var worldModelGO = CreateBrushGameObject(subModel);
var worldModelGO = CreateWorldBrushObject(subModel);
entity.SetWorldModel(worldModelGO);
}

9
Assets/Scripts/Layers.cs

@ -2,6 +2,15 @@
{
Game1 = 6,
ViewModel1 = 7,
Game2 = 9,
ViewModel2 = 10,
Game3 = 12,
ViewModel3 = 13,
Game4 = 15,
ViewModel4 = 16,
}
public static class LayerExtensions

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

@ -66,12 +66,12 @@ public partial class GameModule : CallbackHandler<GameModule>
}
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
private delegate void GameUpdateEntityAnimationCallback(IntPtr target, int entityNum, float frameNum);
private delegate void GameUpdateEntityAnimationCallback(IntPtr target, int entityNum, int pose1, int pose2, float blend);
[MonoPInvokeCallback(typeof(GameUpdateEntityAnimationCallback))]
private static void Callback_GameUpdateEntityAnimation(IntPtr target, int entityNum, float frameNum)
private static void Callback_GameUpdateEntityAnimation(IntPtr target, int entityNum, int pose1, int pose2, float blend)
{
GetSelf(target).UpdateEntityAnimation(entityNum, frameNum);
GetSelf(target).UpdateEntityAnimation(entityNum, pose1, pose2, blend);
}
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]

4
Assets/Scripts/Modules/GameModule.cs

@ -58,9 +58,9 @@ public partial class GameModule
uq.GameState.RemoveEntity(entityNum);
}
private void UpdateEntityAnimation(int entityNum, float frameNum)
private void UpdateEntityAnimation(int entityNum, int pose1, int pose2, float blend)
{
uq.GameState.GetEntity(entityNum)?.UpdateAnimation(frameNum);
uq.GameState.GetEntity(entityNum)?.UpdateAnimation(pose1, pose2, blend);
}
private void SetEntitySkin(int entityNum, int skinNum)

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

@ -18,6 +18,7 @@ public partial class RenderModule: CallbackHandler<RenderModule>
UploadWorldModel = CreateCallback<UploadWorldModelCallback>(Callback_UploadWorldModel),
UploadTexture = CreateCallback<UploadTextureCallback>(Callback_UploadTexture),
UploadLightmap = CreateCallback<UploadLightmapCallback>(Callback_UploadLightmap),
SetupView = CreateCallback<SetupViewCallback>(Callback_SetupView),
};
@ -36,6 +37,7 @@ public partial class RenderModule: CallbackHandler<RenderModule>
public IntPtr UploadBrushModel;
public IntPtr UploadWorldModel;
public IntPtr UploadTexture;
public IntPtr UploadLightmap;
public IntPtr SetupView;
}
@ -123,6 +125,20 @@ public partial class RenderModule: CallbackHandler<RenderModule>
return GetSelf(target).UploadTexture(texture, dataBytes, ref texNum);
}
private readonly byte[] lightmapBytes = new byte[QConstants.LightmapBlockWidth * QConstants.LightmapBlockHeight * 4]; // 32 bits per pixel
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
private delegate bool UploadLightmapCallback(IntPtr target, int lmap, IntPtr data);
[MonoPInvokeCallback(typeof(UploadLightmapCallback))]
private static bool Callback_UploadLightmap(IntPtr target, int lmap, IntPtr data)
{
// TODO: this is a fairly pointless additional data copy step; we could probably make this faster by wrapping the IntPtr directly into a NativeArray
var self = GetSelf(target);
Marshal.Copy(data, self.lightmapBytes, 0, self.lightmapBytes.Length);
return self.UploadLightmap(lmap, QConstants.LightmapBlockWidth, QConstants.LightmapBlockHeight, self.lightmapBytes);
}
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
private delegate void SetupViewCallback(IntPtr target, ref QVec3 origin, ref QVec3 angles, ref QLeaf viewLeaf);

9
Assets/Scripts/Modules/RenderModule.cs

@ -68,6 +68,15 @@ public partial class RenderModule
return true;
}
private bool UploadLightmap(int lightmapNum, int width, int height, byte[] data)
{
if (width == 0 || height == 0)
return false;
uq.GameAssets.UploadLightmap(lightmapNum, width, height, data);
return true;
}
private void SetupView(QVec3 origin, QVec3 angles, QLeaf viewLeaf)
{
var cam = uq.Camera;

63
Assets/Scripts/SplitScreenTest.cs

@ -0,0 +1,63 @@
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class SplitScreenTest : MonoBehaviour
{
[SerializeField]
private GameInstance[] gameInstances = new GameInstance[4];
[SerializeField]
private List<VisualStyle> visualStyles = new List<VisualStyle>();
private void Start()
{
Debug.Log($"Running in {IntPtr.Size * 8}-bit mode");
Layers gameLayer = Layers.Game1;
Layers viewLayer = Layers.ViewModel1;
int layerStride = Layers.Game2 - Layers.Game1;
foreach (var gameInstance in gameInstances)
{
if (gameInstance == null || gameInstance.mainCamera == null)
continue;
var uq = gameObject.AddComponent<UniQuake>();
uq.BaseGame = gameInstance.baseGame;
uq.ModDirectory = gameInstance.modPath;
uq.AdditionalArguments = ParseArgs(gameInstance.arguments);
uq.Camera = gameInstance.mainCamera;
uq.GameLayer = gameLayer;
uq.ViewModelLayer = viewLayer;
uq.LibraryOverride = gameInstance.libraryName;
uq.SetVisualStyle(visualStyles[0]);
gameLayer += layerStride;
viewLayer += layerStride;
}
}
private string[] ParseArgs(string args)
{
if (args == null)
return new string[0];
return args.Split(new[] {' ', '\t', '\r', '\n'}, StringSplitOptions.RemoveEmptyEntries);
}
[Serializable]
public class GameInstance
{
public Camera mainCamera;
public MissionPack baseGame;
public string modPath;
public string arguments;
public string libraryName;
}
}

11
Assets/Scripts/SplitScreenTest.cs.meta

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

62
Assets/Scripts/Support/AliasModel.cs

@ -26,7 +26,9 @@ public class AliasModel
public int GetAnimationFrameCount(float frameNum)
{
if (!FindAnimation((int)frameNum, out Mesh mesh, out int startFrame))
GetAnimationMesh((int)frameNum, out Mesh mesh, out int startFrame);
if (mesh == null)
return 0;
if (mesh.blendShapeCount == 0)
@ -37,34 +39,74 @@ public class AliasModel
public void Animate(float frameNum, out Mesh mesh, out float blendWeight)
{
GetAnimationMesh((int)frameNum, out mesh, out int startFrame);
if (mesh == null || mesh.blendShapeCount == 0)
{
blendWeight = 0;
return;
}
int numFrames = mesh.GetBlendShapeFrameCount(0);
blendWeight = ((frameNum - startFrame) / numFrames) % 1;
}
public void Animate(int pose1, int pose2, float blend, out Mesh mesh, out float blendWeight)
{
int startFrame, numFrames;
blendWeight = 0;
int frameIndex = (int)frameNum;
if (!FindAnimation(frameIndex, out mesh, out int startFrame))
// Don't interpolate if we're on a fixed pose
if (pose1 == pose2)
{
GetAnimationMesh(pose1, out mesh, out startFrame);
if (mesh == null || mesh.blendShapeCount == 0)
return;
numFrames = mesh.GetBlendShapeFrameCount(0);
blendWeight = ((float)pose1 - startFrame) / numFrames % 1;
return;
}
GetAnimationMesh(pose1, out var mesh1, out int startFrame1);
GetAnimationMesh(pose2, out var mesh2, out int startFrame2);
float pose;
if (mesh1 != mesh2)
{
// We cannot blend from one animation sequence to another, since each sequence is a separate Unity mesh.
// Therefore when transitioning between sequences, we hold the previous and next pose for half a frame each.
mesh = blend > 0.5f ? mesh2 : mesh1;
startFrame = blend > 0.5f ? startFrame2 : startFrame1;
pose = blend > 0.5f ? pose2 : pose1;
}
else
{
mesh = mesh1;
startFrame = startFrame1;
pose = pose1 + blend;
}
if (mesh == null || mesh.blendShapeCount == 0)
return;
int numFrames = mesh.GetBlendShapeFrameCount(0);
blendWeight = ((frameNum - startFrame) / numFrames) % 1;
numFrames = mesh.GetBlendShapeFrameCount(0);
blendWeight = (pose - startFrame) / numFrames % 1;
}
private bool FindAnimation(int frameIndex, out Mesh mesh, out int startFrame)
private void GetAnimationMesh(int pose, out Mesh mesh, out int startFrame)
{
mesh = null;
startFrame = 0;
for (int i = 0; i < animationMeshes.Count; ++i)
{
if (animationMeshes[i].Item1 > frameIndex)
return true;
if (animationMeshes[i].Item1 > pose)
return;
startFrame = animationMeshes[i].Item1;
mesh = animationMeshes[i].Item2;
}
return true;
}
public void Dispose()

11
Assets/Scripts/UniQuake.Interop.cs

@ -42,11 +42,12 @@ public partial class UniQuake
string dllFile = Path.Combine(Application.dataPath, DllPath);
// Experimental code to allow running multiple instances of Quake next to each other
// string dllName = Path.GetFileNameWithoutExtension(dllFile);
// string dllExt = Path.GetExtension(dllFile);
// string dllCopy = Path.Combine(Application.persistentDataPath, $"{dllName}{GetInstanceID()}{dllExt}");
// File.Copy(dllFile, dllCopy, true);
// dllFile = dllCopy;
if (!string.IsNullOrEmpty(LibraryOverride))
{
string directory = Path.GetDirectoryName(dllFile);
string extension = Path.GetExtension(dllFile);
dllFile = Path.Combine(directory, LibraryOverride + extension);
}
libraryHandle = SystemLibrary.LoadLibrary(dllFile);
if (libraryHandle == IntPtr.Zero)

3
Assets/Scripts/UniQuake.cs

@ -28,6 +28,8 @@ public partial class UniQuake: MonoBehaviour
public string ModDirectory { get; set; }
public string[] AdditionalArguments { get; set; }
public string LibraryOverride { get; set; }
/// <summary>
/// Time since startup for this particular instance of Quake
/// </summary>
@ -214,6 +216,7 @@ public partial class UniQuake: MonoBehaviour
if (CurrentStyle == null)
{
CurrentStyle = style;
CurrentStyle.Activate();
return;
}

52
Assets/Scripts/VisualStyle.cs

@ -15,6 +15,12 @@ public class VisualStyle : ScriptableObject
[SerializeField]
protected Material liquidMaterial;
[SerializeField]
protected bool pointSampling;
[SerializeField]
protected bool affineTexturing;
[SerializeField]
protected LiquidProperties liquidProperties = new LiquidProperties();
@ -22,13 +28,30 @@ public class VisualStyle : ScriptableObject
protected ParticleSystems particles = new ParticleSystems();
public ParticleSystems Particles => particles;
public virtual Material CreateEntityMaterial()
public virtual void Activate()
{
if (pointSampling)
Shader.EnableKeyword("_POINT_SAMPLING");
else
Shader.DisableKeyword("_POINT_SAMPLING");
}
public virtual Material CreateEntityMaterial(bool aliasModel)
{
return new Material(entityMaterial);
var material = new Material(entityMaterial);
if (aliasModel && affineTexturing)
material.EnableKeyword("_AFFINE_ON");
else
material.DisableKeyword("_AFFINE_ON");
return material;
}
public virtual Material CreateWorldMaterial(QSurfaceFlags surfaceFlags)
{
Material material;
if (surfaceFlags.HasFlag(QSurfaceFlags.DrawTurbulence) && liquidMaterial != null)
{
float alpha = 1f;
@ -39,14 +62,22 @@ public class VisualStyle : ScriptableObject
else if (surfaceFlags.HasFlag(QSurfaceFlags.DrawLava))
alpha = liquidProperties.lavaAlpha;
else if (surfaceFlags.HasFlag(QSurfaceFlags.DrawTeleporter))
alpha = liquidProperties.teleporterAlpha;
alpha = liquidProperties.teleAlpha;
var material = new Material(liquidMaterial);
material = new Material(liquidMaterial);
material.SetColor("_BaseColor", new Color(1, 1, 1, alpha));
return material;
}
else
{
material = new Material(worldMaterial);
}
return new Material(worldMaterial);
if (surfaceFlags.HasFlag(QSurfaceFlags.DrawFence))
{
material.EnableKeyword("_ALPHATEST_ON");
}
return material;
}
public virtual void SetupEntityRenderer(MeshRenderer meshRenderer)
@ -98,7 +129,12 @@ public class VisualStyle : ScriptableObject
else
material.DisableKeyword("_EMISSION");
// TODO: lightmap texture
material.SetTexture("_LightMap", lightmap);
if (lightmap != null)
material.EnableKeyword("_QLIGHTMAP_ON");
else
material.DisableKeyword("_QLIGHTMAP_ON");
}
}
@ -110,7 +146,7 @@ public class LiquidProperties
waterAlpha = 0.85f,
slimeAlpha = 0.9f,
lavaAlpha = 0.95f,
teleporterAlpha = 1.0f;
teleAlpha = 1.0f;
}
[System.Serializable]

8
Assets/Shaders.meta

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

122
Assets/Shaders/Quake.shader

@ -0,0 +1,122 @@
// Shader targeted for low end devices. Single Pass Forward Rendering.
Shader "UniQuake/Quake"
{
Properties
{
[MainTexture] _BaseMap("Base Map (RGB) Alpha (A)", 2D) = "white" {}
[MainColor] _BaseColor("Base Color", Color) = (1, 1, 1, 1)
[NoScaleOffset] _LightMap("Lightmap (RGBA)", 2D) = "white" {}
_Cutoff("Alpha Clipping", Range(0.0, 1.0)) = 0.666
[HDR] _EmissionColor("Emission Color", Color) = (0,0,0)
[NoScaleOffset]_EmissionMap("Emission Map", 2D) = "white" {}
// Blending state
[HideInInspector] _Surface("__surface", Float) = 0.0
[HideInInspector] _Blend("__blend", Float) = 0.0
[HideInInspector] _AlphaClip("__clip", Float) = 0.0
[HideInInspector] _SrcBlend("__src", Float) = 1.0
[HideInInspector] _DstBlend("__dst", Float) = 0.0
[HideInInspector] _ZWrite("__zw", Float) = 1.0
[HideInInspector] _Cull("__cull", Float) = 2.0
}
SubShader
{
Tags { "RenderType" = "Opaque" "RenderPipeline" = "UniversalPipeline" "UniversalMaterialType" = "SimpleLit" "IgnoreProjector" = "True" "ShaderModel"="4.5"}
LOD 300
Pass
{
Name "ForwardLit"
Tags { "LightMode" = "UniversalForward" }
// Use same blending / depth states as Standard shader
Blend[_SrcBlend][_DstBlend]
ZWrite[_ZWrite]
Cull[_Cull]
HLSLPROGRAM
#pragma exclude_renderers gles gles3 glcore
#pragma target 4.5
// -------------------------------------
// Material Keywords
#pragma multi_compile_local __ _ALPHATEST_ON
#pragma multi_compile_local __ _EMISSION
#pragma multi_compile_local __ _QLIGHTMAP_ON _AFFINE_ON // Lightmapping and affine texturing are mutually exclusive
// -------------------------------------
// Universal Pipeline keywords
#pragma multi_compile _ _ADDITIONAL_LIGHTS_VERTEX _ADDITIONAL_LIGHTS
#pragma multi_compile _ _POINT_SAMPLING
// -------------------------------------
// Unity defined keywords
#pragma multi_compile_fog
#pragma vertex LitPassVertexSimple
#pragma fragment LitPassFragmentSimple
#define BUMP_SCALE_NOT_SUPPORTED 1
#include "QuakeInput.hlsl"
#include "QuakeForwardPass.hlsl"
ENDHLSL
}
Pass
{
Name "DepthOnly"
Tags{"LightMode" = "DepthOnly"}
ZWrite On
ColorMask 0
Cull[_Cull]
HLSLPROGRAM
#pragma exclude_renderers gles gles3 glcore
#pragma target 4.5
#pragma vertex DepthOnlyVertex
#pragma fragment DepthOnlyFragment
// -------------------------------------
// Material Keywords
#pragma multi_compile_local __ _ALPHATEST_ON
#include "QuakeInput.hlsl"
#include "Packages/com.unity.render-pipelines.universal/Shaders/DepthOnlyPass.hlsl"
ENDHLSL
}
// This pass is used when drawing to a _CameraNormalsTexture texture
Pass
{
Name "DepthNormals"
Tags{"LightMode" = "DepthNormals"}
ZWrite On
Cull[_Cull]
HLSLPROGRAM
#pragma exclude_renderers gles gles3 glcore
#pragma target 4.5
#pragma vertex DepthNormalsVertex
#pragma fragment DepthNormalsFragment
// -------------------------------------
// Material Keywords
#pragma multi_compile_local __ _ALPHATEST_ON
#include "QuakeInput.hlsl"
#include "Packages/com.unity.render-pipelines.universal/Shaders/DepthNormalsPass.hlsl"
ENDHLSL
}
}
Fallback "Hidden/Universal Render Pipeline/FallbackError"
//CustomEditor "UnityEditor.Rendering.Universal.ShaderGUI.SimpleLitShader"
}

10
Assets/Shaders/Quake.shader.meta

@ -0,0 +1,10 @@
fileFormatVersion: 2
guid: eb7abeca30cd4fb4cb8be05eca69f850
ShaderImporter:
externalObjects: {}
defaultTextures: []
nonModifiableTextures: []
preprocessorOverride: 0
userData:
assetBundleName:
assetBundleVariant:

157
Assets/Shaders/QuakeForwardPass.hlsl

@ -0,0 +1,157 @@
#ifndef UNIVERSAL_SIMPLE_LIT_PASS_INCLUDED
#define UNIVERSAL_SIMPLE_LIT_PASS_INCLUDED
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Lighting.hlsl"
struct Attributes
{
float4 positionOS : POSITION;
float3 normalOS : NORMAL;
float4 tangentOS : TANGENT;
float2 texcoord : TEXCOORD0;
#ifdef _QLIGHTMAP_ON
float2 lightmapUV : TEXCOORD1;
#endif
UNITY_VERTEX_INPUT_INSTANCE_ID
};
struct Varyings
{
#ifdef _AFFINE_ON
noperspective
#endif
float2 uv : TEXCOORD0;
#ifdef _QLIGHTMAP_ON
float2 lightmapUV : TEXCOORD1;
#else
half3 vertexSH : TEXCOORD1;
#endif
float3 posWS : TEXCOORD2; // xyz: posWS
float3 normal : TEXCOORD3;
float3 viewDir : TEXCOORD4;
half4 fogFactorAndVertexLight : TEXCOORD6; // x: fogFactor, yzw: vertex light
float4 positionCS : SV_POSITION;
UNITY_VERTEX_INPUT_INSTANCE_ID
UNITY_VERTEX_OUTPUT_STEREO
};
void InitializeInputData(Varyings input, out InputData inputData)
{
inputData.positionWS = input.posWS;
half3 viewDirWS = input.viewDir;
inputData.normalWS = input.normal;
inputData.normalWS = NormalizeNormalPerPixel(inputData.normalWS);
viewDirWS = SafeNormalize(viewDirWS);
inputData.viewDirectionWS = viewDirWS;
inputData.shadowCoord = float4(0, 0, 0, 0);
inputData.fogCoord = input.fogFactorAndVertexLight.x;
inputData.vertexLighting = input.fogFactorAndVertexLight.yzw;
#ifdef _QLIGHTMAP_ON
inputData.bakedGI = 0.0;
#else
inputData.bakedGI = SampleSHPixel(input.vertexSH, inputData.normalWS);
#endif
inputData.normalizedScreenSpaceUV = GetNormalizedScreenSpaceUV(input.positionCS);
inputData.shadowMask = 0.0;
}
///////////////////////////////////////////////////////////////////////////////
// Vertex and Fragment functions //
///////////////////////////////////////////////////////////////////////////////
// Used in Standard (Simple Lighting) shader
Varyings LitPassVertexSimple(Attributes input)
{
Varyings output = (Varyings)0;
UNITY_SETUP_INSTANCE_ID(input);
UNITY_TRANSFER_INSTANCE_ID(input, output);
UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(output);
VertexPositionInputs vertexInput = GetVertexPositionInputs(input.positionOS.xyz);
VertexNormalInputs normalInput = GetVertexNormalInputs(input.normalOS, input.tangentOS);
half3 viewDirWS = GetWorldSpaceViewDir(vertexInput.positionWS);
half3 vertexLight = VertexLighting(vertexInput.positionWS, normalInput.normalWS);
half fogFactor = ComputeFogFactor(vertexInput.positionCS.z);
output.uv = TRANSFORM_TEX(input.texcoord, _BaseMap);
output.posWS.xyz = vertexInput.positionWS;
output.positionCS = vertexInput.positionCS;
output.normal = NormalizeNormalPerVertex(normalInput.normalWS);
output.viewDir = viewDirWS;
#ifdef _QLIGHTMAP_ON
output.lightmapUV.xy = input.lightmapUV.xy;
#else
output.vertexSH.xyz = SampleSHVertex(output.normal.xyz);
#endif
output.fogFactorAndVertexLight = half4(fogFactor, vertexLight);
return output;
}
// Used for StandardSimpleLighting shader
half4 LitPassFragmentSimple(Varyings input) : SV_Target
{
UNITY_SETUP_INSTANCE_ID(input);
UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(input);
float2 uv = input.uv.xy;
half4 diffuseAlpha = SampleAlbedoAlpha(uv,
#if _POINT_SAMPLING
TEXTURE2D_ARGS(_BaseMap, point_repeat_sampler)
#else
TEXTURE2D_ARGS(_BaseMap, sampler_BaseMap)
#endif
);
half3 diffuse = diffuseAlpha.rgb * _BaseColor.rgb;
half alpha = diffuseAlpha.a * _BaseColor.a;
AlphaDiscard(alpha, _Cutoff);
InputData inputData;
InitializeInputData(input, inputData);
#ifdef _QLIGHTMAP_ON
half4 lightmapColor = SAMPLE_TEXTURE2D(_LightMap, sampler_LightMap, input.lightmapUV);
half3 finalColor = diffuse * lightmapColor.rgb * 2.0f;
#else
// Specular and smoothness are some bogus values just to make models not appear completely black on one side
half3 finalColor = UniversalFragmentBlinnPhong(inputData, diffuse, half4(0.2, 0.2, 0.2, 1), 0.5, 0.0, alpha).rgb;
// Light light = GetMainLight();
// half3 diffuseColor = LightingLambert(light.color, light.direction, inputData.normalWS);
// half3 finalColor = diffuse * diffuseColor;
#endif
#ifdef _EMISSION
finalColor += SampleEmission(uv, _EmissionColor.rgb,
#if _POINT_SAMPLING
TEXTURE2D_ARGS(_EmissionMap, point_repeat_sampler)
#else
TEXTURE2D_ARGS(_EmissionMap, sampler_EmissionMap)
#endif
);
#endif
half4 color = half4(finalColor, alpha);
color.rgb = MixFog(color.rgb, inputData.fogCoord);
color.a = OutputAlpha(color.a, _Surface);
return color;
}
#endif

10
Assets/Shaders/QuakeForwardPass.hlsl.meta

@ -0,0 +1,10 @@
fileFormatVersion: 2
guid: 6aa574d369884d24e8f28b300a86fcb3
ShaderImporter:
externalObjects: {}
defaultTextures: []
nonModifiableTextures: []
preprocessorOverride: 0
userData:
assetBundleName:
assetBundleVariant:

51
Assets/Shaders/QuakeInput.hlsl

@ -0,0 +1,51 @@
#ifndef UNIVERSAL_SIMPLE_LIT_INPUT_INCLUDED
#define UNIVERSAL_SIMPLE_LIT_INPUT_INCLUDED
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/SurfaceInput.hlsl"
CBUFFER_START(UnityPerMaterial)
float4 _BaseMap_ST;
float4 _LightMap_ST;
half4 _BaseColor;
half4 _EmissionColor;
half _Cutoff;
half _Surface;
CBUFFER_END
#ifdef UNITY_DOTS_INSTANCING_ENABLED
UNITY_DOTS_INSTANCING_START(MaterialPropertyMetadata)
UNITY_DOTS_INSTANCED_PROP(float4, _BaseColor)
UNITY_DOTS_INSTANCED_PROP(float4, _EmissionColor)
UNITY_DOTS_INSTANCED_PROP(float , _Cutoff)
UNITY_DOTS_INSTANCED_PROP(float , _Surface)
UNITY_DOTS_INSTANCING_END(MaterialPropertyMetadata)
#define _BaseColor UNITY_ACCESS_DOTS_INSTANCED_PROP_FROM_MACRO(float4 , Metadata__BaseColor)
#define _EmissionColor UNITY_ACCESS_DOTS_INSTANCED_PROP_FROM_MACRO(float4 , Metadata__EmissionColor)
#define _Cutoff UNITY_ACCESS_DOTS_INSTANCED_PROP_FROM_MACRO(float , Metadata__Cutoff)
#define _Surface UNITY_ACCESS_DOTS_INSTANCED_PROP_FROM_MACRO(float , Metadata__Surface)
#endif
SAMPLER(point_repeat_sampler);
TEXTURE2D(_LightMap); SAMPLER(sampler_LightMap);
inline void InitializeSimpleLitSurfaceData(float2 uv, out SurfaceData outSurfaceData)
{
outSurfaceData = (SurfaceData)0;
half4 albedoAlpha = SampleAlbedoAlpha(uv, TEXTURE2D_ARGS(_BaseMap, sampler_BaseMap));
outSurfaceData.alpha = albedoAlpha.a * _BaseColor.a;
AlphaDiscard(outSurfaceData.alpha, _Cutoff);
outSurfaceData.albedo = albedoAlpha.rgb * _BaseColor.rgb;
outSurfaceData.metallic = 0.0; // unused
outSurfaceData.specular = 0.0; // unused
outSurfaceData.smoothness = 0.0; // unused
//outSurfaceData.normalTS = SampleNormal(uv, TEXTURE2D_ARGS(_BumpMap, sampler_BumpMap));
outSurfaceData.occlusion = 1.0; // unused
outSurfaceData.emission = SampleEmission(uv, _EmissionColor.rgb, TEXTURE2D_ARGS(_EmissionMap, sampler_EmissionMap));
}
#endif

10
Assets/Shaders/QuakeInput.hlsl.meta

@ -0,0 +1,10 @@
fileFormatVersion: 2
guid: 209b8f66e5d711946ba4c4ccb9e0a9b4
ShaderImporter:
externalObjects: {}
defaultTextures: []
nonModifiableTextures: []
preprocessorOverride: 0
userData:
assetBundleName:
assetBundleVariant:

4
Assets/Styles/GLQuake/GLQuake.asset

@ -15,10 +15,12 @@ MonoBehaviour:
entityMaterial: {fileID: 2100000, guid: 4d7703ac1adf3534f89b4041b779ff5e, type: 2}
worldMaterial: {fileID: 2100000, guid: fcbaf32c00bea2344bbb1419c61364b6, type: 2}
liquidMaterial: {fileID: 2100000, guid: cd59502a1689c0847a1963c60e347987, type: 2}
pointSampling: 0
affineTexturing: 0
liquidProperties:
waterAlpha: 0.8
slimeAlpha: 0.85
lavaAlpha: 0.9
teleporterAlpha: 1
teleAlpha: 1
particles:
explosion: {fileID: 0}

13
Assets/Styles/GLQuake/Materials/GLQuake_Entity.mat

@ -8,14 +8,13 @@ Material:
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_Name: GLQuake_Entity
m_Shader: {fileID: 4800000, guid: 8d2bb70cbf9db8d4da26e15b26e74248, type: 3}
m_Shader: {fileID: 4800000, guid: eb7abeca30cd4fb4cb8be05eca69f850, type: 3}
m_ShaderKeywords: _EMISSION _RECEIVE_SHADOWS_OFF
m_LightmapFlags: 2
m_EnableInstancingVariants: 0
m_DoubleSidedGI: 0
m_CustomRenderQueue: 2000
stringTagMap:
RenderType: Opaque
m_CustomRenderQueue: -1
stringTagMap: {}
disabledShaderPasses: []
m_SavedProperties:
serializedVersion: 3
@ -44,6 +43,10 @@ Material:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _LightMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _MainTex:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
@ -83,7 +86,7 @@ Material:
- _ClearCoatMask: 0
- _ClearCoatSmoothness: 0
- _Cull: 2
- _Cutoff: 0.5
- _Cutoff: 0.666
- _DetailAlbedoMapScale: 1
- _DetailNormalMapScale: 1
- _DstBlend: 0

13
Assets/Styles/GLQuake/Materials/GLQuake_World.mat

@ -21,14 +21,13 @@ Material:
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_Name: GLQuake_World
m_Shader: {fileID: 4800000, guid: 8d2bb70cbf9db8d4da26e15b26e74248, type: 3}
m_Shader: {fileID: 4800000, guid: eb7abeca30cd4fb4cb8be05eca69f850, type: 3}
m_ShaderKeywords: _EMISSION _RECEIVE_SHADOWS_OFF
m_LightmapFlags: 2
m_EnableInstancingVariants: 0
m_DoubleSidedGI: 0
m_CustomRenderQueue: 2000
stringTagMap:
RenderType: Opaque
m_CustomRenderQueue: -1
stringTagMap: {}
disabledShaderPasses: []
m_SavedProperties:
serializedVersion: 3
@ -61,6 +60,10 @@ Material:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _LightMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _MainTex:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
@ -101,7 +104,7 @@ Material:
- _ClearCoatMask: 0
- _ClearCoatSmoothness: 0
- _Cull: 2
- _Cutoff: 0.5
- _Cutoff: 0.666
- _DetailAlbedoMapScale: 1
- _DetailNormalMapScale: 1
- _DstBlend: 0

26
Assets/Styles/GLQuake/Software.asset

@ -0,0 +1,26 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!114 &11400000
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 0}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 2df0cbad06a6ed5489201e395f9c5bb3, type: 3}
m_Name: Software
m_EditorClassIdentifier:
entityMaterial: {fileID: 2100000, guid: 4d7703ac1adf3534f89b4041b779ff5e, type: 2}
worldMaterial: {fileID: 2100000, guid: fcbaf32c00bea2344bbb1419c61364b6, type: 2}
liquidMaterial: {fileID: 2100000, guid: cd59502a1689c0847a1963c60e347987, type: 2}
pointSampling: 1
affineTexturing: 1
liquidProperties:
waterAlpha: 1
slimeAlpha: 1
lavaAlpha: 1
teleAlpha: 1
particles:
explosion: {fileID: 0}

8
Assets/Styles/GLQuake/Software.asset.meta

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 9f4246ec8cb97bd4d98b1f583ac1d2cd
NativeFormatImporter:
externalObjects: {}
mainObjectFileID: 11400000
userData:
assetBundleName:
assetBundleVariant:

2
ProjectSettings/GraphicsSettings.asset

@ -60,7 +60,7 @@ GraphicsSettings:
m_FogKeepExp: 1
m_FogKeepExp2: 1
m_AlbedoSwatchInfos: []
m_LightsUseLinearIntensity: 1
m_LightsUseLinearIntensity: 0
m_LightsUseColorTemperature: 0
m_DefaultRenderingLayerMask: 1
m_LogWhenShaderIsCompiled: 0

2
ProjectSettings/ProjectSettings.asset

@ -47,7 +47,7 @@ PlayerSettings:
defaultScreenWidthWeb: 960
defaultScreenHeightWeb: 600
m_StereoRenderingPath: 0
m_ActiveColorSpace: 1
m_ActiveColorSpace: 0
m_MTRendering: 1
mipStripping: 0
numberOfMipsStripped: 0

12
ProjectSettings/TagManager.asset

@ -14,14 +14,14 @@ TagManager:
- Game1
- ViewModel1
-
- Game2
- ViewModel2
-
- Game3
- ViewModel3
-
-
-
-
-
-
-
- Game4
- ViewModel4
-
-
-

2
engine/Quake/client.h

@ -375,7 +375,7 @@ void Chase_UpdateForDrawing (void); //johnfitz
void UQ_Game_SetEntityModel(int entityNum, const char *modelName);
void UQ_Game_SetEntityTransform(int entityNum, vec3_t origin, vec3_t angles);
void UQ_Game_RemoveEntity(int entityNum);
void UQ_Game_UpdateEntityAnimation(int entityNum, float frameNum);
void UQ_Game_UpdateEntityAnimation(int entityNum, int pose1, int pose2, float blend);
void UQ_Game_SetEntitySkin(int entityNum, int skinNum);
#endif /* _CLIENT_H_ */

1
engine/Quake/gl_texmgr.h

@ -107,6 +107,7 @@ void GL_Bind (gltexture_t *texture);
void GL_ClearBindings (void);
extern qboolean UQ_GL_UploadTexture(gltexture_t *texture, unsigned *data);
extern qboolean UQ_GL_UploadLightmap(int lmap, byte *data);
#endif /* _GL_TEXMAN_H */

5
engine/Quake/r_alias.c

@ -642,10 +642,7 @@ void R_DrawAliasModel (entity_t *e)
R_SetupEntityTransform (e, &lerpdata);
UQ_Game_SetEntityTransform(e->num, lerpdata.origin, lerpdata.angles);
if (lerpdata.pose1 == lerpdata.pose2)
UQ_Game_UpdateEntityAnimation(e->num, (float)lerpdata.pose1); // Fixed pose, don't lerp
else
UQ_Game_UpdateEntityAnimation(e->num, (float)lerpdata.pose1 + lerpdata.blend);
UQ_Game_UpdateEntityAnimation(e->num, lerpdata.pose1, lerpdata.pose2, lerpdata.blend);
//
// cull it

4
engine/Quake/r_brush.c

@ -940,6 +940,8 @@ void GL_BuildLightmaps (void)
lm->texture = TexMgr_LoadImage (cl.worldmodel, name, LMBLOCK_WIDTH, LMBLOCK_HEIGHT,
SRC_LIGHTMAP, lm->data, "", (src_offset_t)lm->data, TEXPREF_LINEAR | TEXPREF_NOPICMIP);
//johnfitz
UQ_GL_UploadLightmap(i, lm->data);
}
//johnfitz -- warn about exceeding old limits
@ -1270,6 +1272,8 @@ static void R_UploadLightmap(int lmap)
lm->rectchange.h = 0;
lm->rectchange.w = 0;
UQ_GL_UploadLightmap(lmap, lm->data);
rs_dynamiclightmaps++;
}

6
engine/UniQuake/game_uniquake.c

@ -9,7 +9,7 @@ typedef struct unity_gamecalls_s
void(*SetEntityModel)(void *target, int entityNum, const char *modelName);
void(*SetEntityTransform)(void *target, int entityNum, vec3_t origin, vec3_t angles);
void(*RemoveEntity)(void *target, int entityNum);
void(*UpdateEntityAnimation)(void *target, int entityNum, float frameNum);
void(*UpdateEntityAnimation)(void *target, int entityNum, int pose1, int pose2, float blend);
void(*SetEntitySkin)(void *target, int entityNum, int skinNum);
} unity_gamecalls_t;
@ -30,9 +30,9 @@ void UQ_Game_RemoveEntity(int entityNum)
unity_gamecalls->RemoveEntity(unity_gamecalls->target, entityNum);
}
void UQ_Game_UpdateEntityAnimation(int entityNum, float frameNum)
void UQ_Game_UpdateEntityAnimation(int entityNum, int pose1, int pose2, float blend)
{
unity_gamecalls->UpdateEntityAnimation(unity_gamecalls->target, entityNum, frameNum);
unity_gamecalls->UpdateEntityAnimation(unity_gamecalls->target, entityNum, pose1, pose2, blend);
}
void UQ_Game_SetEntitySkin(int entityNum, int skinNum)

6
engine/UniQuake/gl_uniquake.c

@ -11,6 +11,7 @@ typedef struct unity_glcalls_s
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);
qboolean(*UploadLightmap)(void *target, int lmap, byte *data);
void(*SetupView)(void *target, vec3_t origin, vec3_t angles, mleaf_t *viewLeaf);
} unity_glcalls_t;
@ -39,6 +40,11 @@ qboolean UQ_GL_UploadTexture(gltexture_t *texture, unsigned *data)
return unity_glcalls->UploadTexture(unity_glcalls->target, texture, data, &texture->texnum);
}
qboolean UQ_GL_UploadLightmap(int lmap, byte *data)
{
return unity_glcalls->UploadLightmap(unity_glcalls->target, lmap, data);
}
void UQ_GL_SetupView(vec3_t origin, vec3_t angles, mleaf_t *viewLeaf)
{
unity_glcalls->SetupView(unity_glcalls->target, origin, angles, viewLeaf);

5
engine/UniQuake/vid_uniquake.c

@ -31,6 +31,8 @@ void VID_Init(void)
vid.colormap = host_colormap;
vid.fullbright = 256 - LittleLong(*((int *)vid.colormap + 2048));
vid.recalc_refdef = 1;
}
void VID_Shutdown(void)
@ -47,6 +49,9 @@ void VID_Lock(void)
void GL_BeginRendering(int *x, int *y, int *width, int *height)
{
*x = *y = 0;
*width = vid.width;
*height = vid.height;
}
void GL_EndRendering(void)

Loading…
Cancel
Save