mirror of
https://github.com/aharabada/glitchy-engine-beef.git
synced 2026-09-05 13:01:52 +00:00
Added GLTF submodule and start of ModelLoader
This commit is contained in:
@@ -16,3 +16,6 @@
|
||||
[submodule "GlitchyEngine/vendor/freetype"]
|
||||
path = GlitchyEngine/vendor/freetype
|
||||
url = https://github.com/aharabada/FreeType-beef.git
|
||||
[submodule "GlitchyEngine/vendor/gltf"]
|
||||
path = GlitchyEngine/vendor/gltf
|
||||
url = https://github.com/aharabada/cgltf-beef.git
|
||||
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
FileVersion = 1
|
||||
Projects = {Sandbox = {Path = "Sandbox"}, GlitchyEngine = {Path = "GlitchyEngine"}, GlitchLog = {Path = "GlitchLog"}, DirectX = {Path = "GlitchyEngine/vendor/directx/DirectX"}, ImGui = {Path = "GlitchyEngine/vendor/imgui-beef/ImGui"}, ImGuiImplWin32 = {Path = "GlitchyEngine/vendor/imgui-beef/ImGuiImplWin32"}, ImGuiImplDX11 = {Path = "GlitchyEngine/vendor/imgui-beef/ImGuiImplDX11"}, DirectXTK = {Path = "GlitchyEngine/vendor/DirectXTK/DirectXTK-beef"}, LodePng = {Path = "vendor/lodepng-beef/lodepng-beef"}, FreeType = {Path = "GlitchyEngine/vendor/freetype"}}
|
||||
Projects = {Sandbox = {Path = "Sandbox"}, GlitchyEngine = {Path = "GlitchyEngine"}, GlitchLog = {Path = "GlitchLog"}, DirectX = {Path = "GlitchyEngine/vendor/directx/DirectX"}, ImGui = {Path = "GlitchyEngine/vendor/imgui-beef/ImGui"}, ImGuiImplWin32 = {Path = "GlitchyEngine/vendor/imgui-beef/ImGuiImplWin32"}, ImGuiImplDX11 = {Path = "GlitchyEngine/vendor/imgui-beef/ImGuiImplDX11"}, DirectXTK = {Path = "GlitchyEngine/vendor/DirectXTK/DirectXTK-beef"}, LodePng = {Path = "vendor/lodepng-beef/lodepng-beef"}, FreeType = {Path = "GlitchyEngine/vendor/freetype"}, cgltf-beef = {Path = "GlitchyEngine/vendor/gltf/cgltf-beef"}}
|
||||
|
||||
[Workspace]
|
||||
StartupProject = "Sandbox"
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
FileVersion = 1
|
||||
Dependencies = {GlitchLog = "*", corlib = "*", DirectX = "*", ImGui = "*", ImGuiImplWin32 = "*", ImGuiImplDX11 = "*", DirectXTK = "*", FreeType = "*"}
|
||||
Dependencies = {GlitchLog = "*", corlib = "*", DirectX = "*", ImGui = "*", ImGuiImplWin32 = "*", ImGuiImplDX11 = "*", DirectXTK = "*", FreeType = "*", cgltf-beef = "*"}
|
||||
|
||||
[Project]
|
||||
Name = "GlitchyEngine"
|
||||
|
||||
@@ -0,0 +1,217 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using cgltf;
|
||||
using GlitchyEngine.Math;
|
||||
using GlitchyEngine.Renderer;
|
||||
|
||||
namespace GlitchyEngine.Content
|
||||
{
|
||||
public static class ModelLoader
|
||||
{
|
||||
public static void LoadModel(String filename, GraphicsContext context, Effect validationEffect, List<(Matrix Transform, GeometryBinding Model)> output)
|
||||
{
|
||||
CGLTF.Options options = .();
|
||||
CGLTF.Data* data;
|
||||
CGLTF.Result result = CGLTF.ParseFile(options, filename, out data);
|
||||
|
||||
Log.EngineLogger.Assert(result == .Success, "Failed to load model.");
|
||||
|
||||
result = CGLTF.LoadBuffers(options, data, filename);
|
||||
|
||||
Log.EngineLogger.Assert(result == .Success, "Failed to load buffers");
|
||||
|
||||
for(var node in data.Nodes)
|
||||
{
|
||||
if(node.Mesh != null)
|
||||
{
|
||||
Matrix transform = ?;
|
||||
CGLTF.NodeTransformWorld(&node, (float*)&transform);
|
||||
|
||||
for(var primitive in node.Mesh.Primitives)
|
||||
{
|
||||
GeometryBinding binding = ModelLoader.PrimitiveToGeoBinding(context, primitive, validationEffect);
|
||||
|
||||
output.Add((transform, binding));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* TODO make awesome stuff */
|
||||
CGLTF.Free(data);
|
||||
}
|
||||
|
||||
public static GeometryBinding PrimitiveToGeoBinding(GraphicsContext context, CGLTF.Primitive primitive, Effect validationEffect)
|
||||
{
|
||||
GeometryBinding binding = new GeometryBinding(context);
|
||||
|
||||
// primitive topology
|
||||
switch(primitive.Type)
|
||||
{
|
||||
case .Points:
|
||||
binding.SetPrimitiveTopology(.PointList);
|
||||
case .Lines:
|
||||
binding.SetPrimitiveTopology(.LineList);
|
||||
case .LineStrip:
|
||||
binding.SetPrimitiveTopology(.LineStrip);
|
||||
case .Triangles:
|
||||
binding.SetPrimitiveTopology(.TriangleList);
|
||||
case .TriangleStrip:
|
||||
binding.SetPrimitiveTopology(.TriangleStrip);
|
||||
default:
|
||||
Log.EngineLogger.Assert(false, scope $"{primitive.Type} not supported.");
|
||||
}
|
||||
|
||||
// indices
|
||||
{
|
||||
CGLTF.Accessor* indices = primitive.Indices;
|
||||
|
||||
if(indices != null)
|
||||
{
|
||||
bool is16bit = indices.ComponentType == .R_16u || indices.ComponentType == .R_16;
|
||||
|
||||
IndexBuffer ib = new IndexBuffer(context, (.)indices.Count, .Immutable, .None, is16bit ? .Index16Bit : .Index32Bit);
|
||||
|
||||
uint8* bufferData = (uint8*)indices.BufferView.Buffer.Data;
|
||||
bufferData += indices.BufferView.Offset;
|
||||
|
||||
ib.SetData<uint8>(bufferData, (.)indices.BufferView.Size);
|
||||
|
||||
binding.SetIndexBuffer(ib);
|
||||
|
||||
ib.ReleaseRef();
|
||||
}
|
||||
}
|
||||
|
||||
// vertices
|
||||
{
|
||||
List<VertexElement> elements = scope .(primitive.Attributes.Length);
|
||||
Dictionary<CGLTF.BufferView*, VertexBuffer> buffers = scope .();
|
||||
List<VertexBufferBinding> bindings = scope .();
|
||||
|
||||
for(var attribute in primitive.Attributes)
|
||||
{
|
||||
// Get Input Element format
|
||||
Format format = FormatFromVectorComponent(attribute.Data.Type, attribute.Data.ComponentType);
|
||||
Log.EngineLogger.AssertDebug(format != .Unknown, "Vertex element format must not be \"Unknown.\"");
|
||||
|
||||
VertexBuffer vertexBuffer = null;
|
||||
|
||||
// Get vertex buffer
|
||||
{
|
||||
CGLTF.BufferView* bufferView = attribute.Data.BufferView;
|
||||
|
||||
// if buffer doesn't exist -> create
|
||||
if(!buffers.TryGetValue(bufferView, out vertexBuffer))
|
||||
{
|
||||
vertexBuffer = new VertexBuffer(context, 1, (uint32)bufferView.Size, .Immutable)..ReleaseRefNoDelete();
|
||||
|
||||
uint8* bufferData = (uint8*)bufferView.Buffer.Data;
|
||||
bufferData += bufferView.Offset;
|
||||
|
||||
vertexBuffer.SetData(bufferData, (.)bufferView.Size);
|
||||
|
||||
buffers.Add(attribute.Data.BufferView, vertexBuffer);
|
||||
}
|
||||
|
||||
Log.EngineLogger.AssertDebug(vertexBuffer != null);
|
||||
}
|
||||
|
||||
VertexBufferBinding bufferBinding = .(vertexBuffer, (.)attribute.Data.Stride, (.)attribute.Data.Offset);
|
||||
|
||||
// get slot of bufferBinding
|
||||
int bindingSlot = bindings.IndexOf(bufferBinding);
|
||||
|
||||
// binding has no slot -> add to list
|
||||
if(bindingSlot == -1)
|
||||
{
|
||||
bindingSlot = bindings.Count;
|
||||
bindings.Add(bufferBinding);
|
||||
|
||||
binding.SetVertexBufferSlot(bufferBinding, (.)bindingSlot);
|
||||
}
|
||||
|
||||
VertexElement element = .(format, new String(attribute.Name), true, (.)attribute.Index, (.)bindingSlot);
|
||||
elements.Add(element);
|
||||
}
|
||||
|
||||
VertexElement[] vertexElements = new VertexElement[elements.Count];
|
||||
for(int i < elements.Count)
|
||||
{
|
||||
vertexElements[i] = elements[i];
|
||||
}
|
||||
|
||||
// TODO: validate vertex layout somewhere else
|
||||
|
||||
VertexLayout layout = new VertexLayout(context, vertexElements, true, validationEffect.VertexShader);
|
||||
binding.SetVertexLayout(layout..ReleaseRefNoDelete());
|
||||
}
|
||||
|
||||
return binding;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts the vector and component type to the corresponding Format.
|
||||
*/
|
||||
static Format FormatFromVectorComponent(CGLTF.Type vectorType, CGLTF.ComponentType componentType)
|
||||
{
|
||||
switch((vectorType, componentType))
|
||||
{
|
||||
case (.Scalar, .R_8):
|
||||
return .R8_SInt;
|
||||
case (.Scalar, .R_8u):
|
||||
return .R8_UInt;
|
||||
case (.Scalar, .R_16):
|
||||
return .R16_SInt;
|
||||
case (.Scalar, .R_16u):
|
||||
return .R16_UInt;
|
||||
case (.Scalar, .R_32u):
|
||||
return .R32_UInt;
|
||||
case (.Scalar, .R_32f):
|
||||
return .R32_Float;
|
||||
|
||||
case (.Vec2, .R_8):
|
||||
return .R8G8_SInt;
|
||||
case (.Vec2, .R_8u):
|
||||
return .R8G8_UInt;
|
||||
case (.Vec2, .R_16):
|
||||
return .R16G16_SInt;
|
||||
case (.Vec2, .R_16u):
|
||||
return .R16G16_UInt;
|
||||
case (.Vec2, .R_32u):
|
||||
return .R32G32_UInt;
|
||||
case (.Vec2, .R_32f):
|
||||
return .R32G32_Float;
|
||||
|
||||
//case (.Vec3, .R_8):
|
||||
//case (.Vec3, .R_8u):
|
||||
//case (.Vec3, .R_16):
|
||||
//case (.Vec3, .R_16u):
|
||||
case (.Vec3, .R_32u):
|
||||
return .R32G32B32_UInt;
|
||||
case (.Vec3, .R_32f):
|
||||
return .R32G32B32_Float;
|
||||
|
||||
case (.Vec4, .R_8):
|
||||
return .R8G8B8A8_SInt;
|
||||
case (.Vec4, .R_8u):
|
||||
return .R8G8B8A8_UInt;
|
||||
case (.Vec4, .R_16):
|
||||
return .R16G16B16A16_SInt;
|
||||
case (.Vec4, .R_16u):
|
||||
return .R16G16B16A16_UInt;
|
||||
case (.Vec4, .R_32u):
|
||||
return .R32G32B32A32_UInt;
|
||||
case (.Vec4, .R_32f):
|
||||
return .R32G32B32A32_Float;
|
||||
|
||||
case (.Mat4, .R_32f):
|
||||
return .R32G32B32A32_Float;
|
||||
|
||||
default:
|
||||
Log.EngineLogger.Assert(false, scope $"Unhandled vector - componenttype combination. ({vectorType}, {componentType})");
|
||||
}
|
||||
|
||||
return .Unknown;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,142 @@
|
||||
{
|
||||
"asset": {
|
||||
"generator": "COLLADA2GLTF",
|
||||
"version": "2.0"
|
||||
},
|
||||
"scene": 0,
|
||||
"scenes": [
|
||||
{
|
||||
"nodes": [
|
||||
0
|
||||
]
|
||||
}
|
||||
],
|
||||
"nodes": [
|
||||
{
|
||||
"children": [
|
||||
1
|
||||
],
|
||||
"matrix": [
|
||||
1.0,
|
||||
0.0,
|
||||
0.0,
|
||||
0.0,
|
||||
0.0,
|
||||
0.0,
|
||||
-1.0,
|
||||
0.0,
|
||||
0.0,
|
||||
1.0,
|
||||
0.0,
|
||||
0.0,
|
||||
0.0,
|
||||
0.0,
|
||||
0.0,
|
||||
1.0
|
||||
]
|
||||
},
|
||||
{
|
||||
"mesh": 0
|
||||
}
|
||||
],
|
||||
"meshes": [
|
||||
{
|
||||
"primitives": [
|
||||
{
|
||||
"attributes": {
|
||||
"NORMAL": 1,
|
||||
"POSITION": 2
|
||||
},
|
||||
"indices": 0,
|
||||
"mode": 4,
|
||||
"material": 0
|
||||
}
|
||||
],
|
||||
"name": "Mesh"
|
||||
}
|
||||
],
|
||||
"accessors": [
|
||||
{
|
||||
"bufferView": 0,
|
||||
"byteOffset": 0,
|
||||
"componentType": 5123,
|
||||
"count": 36,
|
||||
"max": [
|
||||
23
|
||||
],
|
||||
"min": [
|
||||
0
|
||||
],
|
||||
"type": "SCALAR"
|
||||
},
|
||||
{
|
||||
"bufferView": 1,
|
||||
"byteOffset": 0,
|
||||
"componentType": 5126,
|
||||
"count": 24,
|
||||
"max": [
|
||||
1.0,
|
||||
1.0,
|
||||
1.0
|
||||
],
|
||||
"min": [
|
||||
-1.0,
|
||||
-1.0,
|
||||
-1.0
|
||||
],
|
||||
"type": "VEC3"
|
||||
},
|
||||
{
|
||||
"bufferView": 1,
|
||||
"byteOffset": 288,
|
||||
"componentType": 5126,
|
||||
"count": 24,
|
||||
"max": [
|
||||
0.5,
|
||||
0.5,
|
||||
0.5
|
||||
],
|
||||
"min": [
|
||||
-0.5,
|
||||
-0.5,
|
||||
-0.5
|
||||
],
|
||||
"type": "VEC3"
|
||||
}
|
||||
],
|
||||
"materials": [
|
||||
{
|
||||
"pbrMetallicRoughness": {
|
||||
"baseColorFactor": [
|
||||
0.800000011920929,
|
||||
0.0,
|
||||
0.0,
|
||||
1.0
|
||||
],
|
||||
"metallicFactor": 0.0
|
||||
},
|
||||
"name": "Red"
|
||||
}
|
||||
],
|
||||
"bufferViews": [
|
||||
{
|
||||
"buffer": 0,
|
||||
"byteOffset": 576,
|
||||
"byteLength": 72,
|
||||
"target": 34963
|
||||
},
|
||||
{
|
||||
"buffer": 0,
|
||||
"byteOffset": 0,
|
||||
"byteLength": 576,
|
||||
"byteStride": 12,
|
||||
"target": 34962
|
||||
}
|
||||
],
|
||||
"buffers": [
|
||||
{
|
||||
"byteLength": 648,
|
||||
"uri": "Box0.bin"
|
||||
}
|
||||
]
|
||||
}
|
||||
Binary file not shown.
@@ -0,0 +1,54 @@
|
||||
cbuffer SceneConstants
|
||||
{
|
||||
float4x4 ViewProjection = float4x4(1, 0, 0, 0,
|
||||
0, 1, 0, 0,
|
||||
0, 0, 1, 0,
|
||||
0, 0, 0, 1);
|
||||
}
|
||||
|
||||
cbuffer ObjectConstants
|
||||
{
|
||||
float4x4 Transform;
|
||||
}
|
||||
|
||||
cbuffer Constants
|
||||
{
|
||||
float4 BaseColor;
|
||||
float3 LightDir;
|
||||
}
|
||||
|
||||
struct VS_IN
|
||||
{
|
||||
float3 Position : POSITION;
|
||||
float3 Normal : NORMAL;
|
||||
};
|
||||
|
||||
struct PS_IN
|
||||
{
|
||||
float4 Position : SV_POSITION;
|
||||
float3 Normal : NORMAL;
|
||||
};
|
||||
|
||||
PS_IN VS(VS_IN input)
|
||||
{
|
||||
PS_IN output;
|
||||
|
||||
float4 worldPosition = mul(Transform, float4(input.Position, 1));
|
||||
|
||||
output.Position = mul(ViewProjection, worldPosition);
|
||||
output.Normal = mul((float3x3)Transform, input.Normal);
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
float4 PS(PS_IN input) : SV_TARGET
|
||||
{
|
||||
input.Normal = normalize(input.Normal);
|
||||
|
||||
float shading = dot(LightDir, input.Normal);
|
||||
shading = clamp(shading, 0.0f, 1.0f);
|
||||
|
||||
return BaseColor * shading;
|
||||
}
|
||||
|
||||
#effect[VS=VS,PS=PS]
|
||||
@@ -8,6 +8,8 @@ using ImGui;
|
||||
using GlitchyEngine.Renderer;
|
||||
using GlitchyEngine.Math;
|
||||
using GlitchyEngine.World;
|
||||
using System.Collections;
|
||||
using GlitchyEngine.Content;
|
||||
|
||||
namespace Sandbox
|
||||
{
|
||||
@@ -55,8 +57,10 @@ namespace Sandbox
|
||||
GeometryBinding _quadGeometryBinding ~ _?.ReleaseRef();
|
||||
|
||||
RasterizerState _rasterizerState ~ _?.ReleaseRef();
|
||||
RasterizerState _rasterizerStateClockWise ~ _?.ReleaseRef();
|
||||
|
||||
GraphicsContext _context ~ _?.ReleaseRef();
|
||||
DepthStencilTarget _depthTarget ~ _?.ReleaseRef();
|
||||
|
||||
Texture2D _texture ~ _?.ReleaseRef();
|
||||
Texture2D _ge_logo ~ _?.ReleaseRef();
|
||||
@@ -85,8 +89,12 @@ namespace Sandbox
|
||||
|
||||
_effectLibrary.LoadNoRefInc("content\\Shaders\\basicShader.hlsl");
|
||||
|
||||
_effectLibrary.LoadNoRefInc("content\\Shaders\\testShader.hlsl");
|
||||
|
||||
var textureEffect = _effectLibrary.Load("content\\Shaders\\textureShader.hlsl");
|
||||
|
||||
_depthTarget = new DepthStencilTarget(_context, _context.SwapChain.Width, _context.SwapChain.Height);
|
||||
|
||||
// Create Input Layout
|
||||
|
||||
VertexLayout vertexLayout = new VertexLayout(_context, VertexColorTexture.VertexElements, false, textureEffect.VertexShader);
|
||||
@@ -163,6 +171,9 @@ namespace Sandbox
|
||||
RasterizerStateDescription rsDesc = .(.Solid, .Back, true);
|
||||
_rasterizerState = new RasterizerState(_context, rsDesc);
|
||||
|
||||
rsDesc.FrontCounterClockwise = false;
|
||||
_rasterizerStateClockWise = new RasterizerState(_context, rsDesc);
|
||||
|
||||
_texture = new Texture2D(_context, "content/Textures/Checkerboard.dds");
|
||||
_ge_logo = new Texture2D(_context, "content/Textures/GE_Logo.dds");
|
||||
|
||||
@@ -190,6 +201,53 @@ namespace Sandbox
|
||||
_cameraController = new .(Application.Get().Window.Context.SwapChain.BackbufferViewport.Width /
|
||||
Application.Get().Window.Context.SwapChain.BackbufferViewport.Height);
|
||||
_cameraController.CameraPosition = .(0, 0, -5);
|
||||
|
||||
TestLoadModel();
|
||||
}
|
||||
|
||||
//GeometryBinding _modelTest ~ _?.ReleaseRef();
|
||||
|
||||
List<(Matrix Transform, GeometryBinding Model)> _modelTest = new .() ~ UnloadModelTest!();
|
||||
|
||||
mixin UnloadModelTest()
|
||||
{
|
||||
for(var entry in _modelTest)
|
||||
{
|
||||
entry.Model?.ReleaseRef();
|
||||
}
|
||||
|
||||
delete _modelTest;
|
||||
}
|
||||
|
||||
void TestLoadModel()
|
||||
{
|
||||
var testEffect = _effectLibrary.Get("testShader");
|
||||
|
||||
ModelLoader.LoadModel("content\\Models\\box.gltf", _context, testEffect, _modelTest);
|
||||
|
||||
testEffect.ReleaseRef();
|
||||
|
||||
/*
|
||||
CGLTF.Options options = .();
|
||||
CGLTF.Data* data;
|
||||
CGLTF.Result result = CGLTF.ParseFile(options, "content\\Models\\box.gltf", out data);
|
||||
|
||||
CGLTF.LoadBuffers(options, data, "content\\Models\\box.gltf");
|
||||
|
||||
Log.EngineLogger.Assert(result == .Success, "Failed to load model");
|
||||
|
||||
var mesh = data.Meshes[0];
|
||||
var primitive = mesh.Primitives[0];
|
||||
|
||||
var testEffect = _effectLibrary.Get("testShader");
|
||||
|
||||
_modelTest = ModelLoader.PrimitiveToGeoBinding(_context, primitive, testEffect);
|
||||
|
||||
testEffect.ReleaseRef();
|
||||
|
||||
/* TODO make awesome stuff */
|
||||
CGLTF.Free(data);
|
||||
*/
|
||||
}
|
||||
|
||||
void InitEcs()
|
||||
@@ -217,13 +275,13 @@ namespace Sandbox
|
||||
_cameraController.Update(gameTime);
|
||||
|
||||
RenderCommand.Clear(null, .(0.2f, 0.2f, 0.2f));
|
||||
_depthTarget.Clear(1.0f, 0, .Depth);
|
||||
|
||||
// Draw test geometry
|
||||
_context.SetRenderTarget(null);
|
||||
_depthTarget.Bind();
|
||||
_context.BindRenderTargets();
|
||||
|
||||
_context.SetRasterizerState(_rasterizerState);
|
||||
|
||||
_context.SetViewport(_context.SwapChain.BackbufferViewport);
|
||||
|
||||
Renderer.BeginScene(_cameraController.Camera);
|
||||
@@ -233,6 +291,24 @@ namespace Sandbox
|
||||
var basicEffect = _effectLibrary.Get("basicShader");
|
||||
var textureEffect = _effectLibrary.Get("textureShader");
|
||||
|
||||
// Model test
|
||||
{
|
||||
_context.SetRasterizerState(_rasterizerStateClockWise);
|
||||
|
||||
var testEffect = _effectLibrary.Get("testShader");
|
||||
testEffect.Variables["BaseColor"].SetData(Color.White);
|
||||
testEffect.Variables["LightDir"].SetData(Vector3(-1, 1, -0.5f).Normalized());
|
||||
|
||||
for(var entry in _modelTest)
|
||||
{
|
||||
Renderer.Submit(entry.Model, testEffect, entry.Transform);
|
||||
}
|
||||
|
||||
testEffect.ReleaseRef();
|
||||
}
|
||||
|
||||
_context.SetRasterizerState(_rasterizerState);
|
||||
|
||||
for(var entity in _world.Enumerate(typeof(TransformComponent)))
|
||||
{
|
||||
var transform = _world.GetComponent<TransformComponent>(entity);
|
||||
@@ -281,6 +357,7 @@ namespace Sandbox
|
||||
EventDispatcher dispatcher = EventDispatcher(event);
|
||||
|
||||
dispatcher.Dispatch<ImGuiRenderEvent>(scope (e) => OnImGuiRender(e));
|
||||
dispatcher.Dispatch<WindowResizeEvent>(scope (e) => OnWindowResize(e));
|
||||
}
|
||||
|
||||
private bool OnImGuiRender(ImGuiRenderEvent e)
|
||||
@@ -295,6 +372,14 @@ namespace Sandbox
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private bool OnWindowResize(WindowResizeEvent e)
|
||||
{
|
||||
_depthTarget.ReleaseRef();
|
||||
_depthTarget = new DepthStencilTarget(_context, _context.SwapChain.Width, _context.SwapChain.Height);
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
class SandboxApp : Application
|
||||
|
||||
Reference in New Issue
Block a user