*
This commit is contained in:
+11
@@ -0,0 +1,11 @@
|
|||||||
|
*.sdf
|
||||||
|
Debug/
|
||||||
|
*.filters
|
||||||
|
*.suo
|
||||||
|
DirectXTex/
|
||||||
|
*.error
|
||||||
|
ipch/
|
||||||
|
*.user
|
||||||
|
*.opensdf
|
||||||
|
*.opendb
|
||||||
|
*.db
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
# 3ds Max Wavefront OBJ Exporter v0.97b - (c)2007 guruware
|
||||||
|
# File Created: 22.09.2015 22:34:25
|
||||||
|
|
||||||
|
newmtl RedCube
|
||||||
|
Ns 9.999999
|
||||||
|
Ni 1.500000
|
||||||
|
d 1.000000
|
||||||
|
Tr 0.000000
|
||||||
|
Tf 1.000000 1.000000 1.000000
|
||||||
|
illum 2
|
||||||
|
Ka 1.000000 0.000000 0.000000
|
||||||
|
Kd 1.000000 0.000000 0.000000
|
||||||
|
Ks 0.000000 0.000000 0.000000
|
||||||
|
Ke 0.000000 0.000000 0.000000
|
||||||
|
|
||||||
|
newmtl BlueCube
|
||||||
|
Ns 9.999999
|
||||||
|
Ni 1.500000
|
||||||
|
d 1.000000
|
||||||
|
Tr 0.000000
|
||||||
|
Tf 1.000000 1.000000 1.000000
|
||||||
|
illum 2
|
||||||
|
Ka 0.047059 0.000000 1.000000
|
||||||
|
Kd 0.047059 0.000000 1.000000
|
||||||
|
Ks 0.000000 0.000000 0.000000
|
||||||
|
Ke 0.000000 0.000000 0.000000
|
||||||
@@ -0,0 +1,105 @@
|
|||||||
|
# 3dA Max Wavefront OBJ Exporter v0.97b - (c)2007 guruware
|
||||||
|
# File Created: 22.09.2015 22:34:25
|
||||||
|
|
||||||
|
mtllib Boxes.mtl
|
||||||
|
|
||||||
|
#
|
||||||
|
# object RedBox
|
||||||
|
#
|
||||||
|
|
||||||
|
v -0.500000 0.000000 0.500000
|
||||||
|
v -0.500000 0.000000 -0.500000
|
||||||
|
v 0.500000 0.000000 -0.500000
|
||||||
|
v 0.500000 0.000000 0.500000
|
||||||
|
v -0.500000 1.000000 0.500000
|
||||||
|
v 0.500000 1.000000 0.500000
|
||||||
|
v 0.500000 1.000000 -0.500000
|
||||||
|
v -0.500000 1.000000 -0.500000
|
||||||
|
# 8 vertices
|
||||||
|
|
||||||
|
vn 0.000000 -1.000000 -0.000000
|
||||||
|
vn 0.000000 1.000000 -0.000000
|
||||||
|
vn 0.000000 0.000000 1.000000
|
||||||
|
vn 1.000000 0.000000 -0.000000
|
||||||
|
vn 0.000000 0.000000 -1.000000
|
||||||
|
vn -1.000000 0.000000 -0.000000
|
||||||
|
# 6 vertex normals
|
||||||
|
|
||||||
|
vt 1.000000 0.000000 0.000000
|
||||||
|
vt 1.000000 1.000000 0.000000
|
||||||
|
vt 0.000000 1.000000 0.000000
|
||||||
|
vt 0.000000 0.000000 0.000000
|
||||||
|
# 4 texture coords
|
||||||
|
|
||||||
|
g RedBox
|
||||||
|
usemtl RedCube
|
||||||
|
s 2
|
||||||
|
f 1/1/1 2/2/1 3/3/1
|
||||||
|
f 3/3/1 4/4/1 1/1/1
|
||||||
|
s 4
|
||||||
|
f 5/4/2 6/1/2 7/2/2
|
||||||
|
f 7/2/2 8/3/2 5/4/2
|
||||||
|
s 8
|
||||||
|
f 1/4/3 4/1/3 6/2/3
|
||||||
|
f 6/2/3 5/3/3 1/4/3
|
||||||
|
s 16
|
||||||
|
f 4/4/4 3/1/4 7/2/4
|
||||||
|
f 7/2/4 6/3/4 4/4/4
|
||||||
|
s 32
|
||||||
|
f 3/4/5 2/1/5 8/2/5
|
||||||
|
f 8/2/5 7/3/5 3/4/5
|
||||||
|
s 64
|
||||||
|
f 2/4/6 1/1/6 5/2/6
|
||||||
|
f 5/2/6 8/3/6 2/4/6
|
||||||
|
# 12 faces
|
||||||
|
|
||||||
|
#
|
||||||
|
# object BlueBox
|
||||||
|
#
|
||||||
|
|
||||||
|
v -0.500000 0.000000 1.978305
|
||||||
|
v -0.500000 0.000000 0.978305
|
||||||
|
v 0.500000 0.000000 0.978305
|
||||||
|
v 0.500000 0.000000 1.978305
|
||||||
|
v -0.500000 1.000000 1.978305
|
||||||
|
v 0.500000 1.000000 1.978305
|
||||||
|
v 0.500000 1.000000 0.978305
|
||||||
|
v -0.500000 1.000000 0.978305
|
||||||
|
# 8 vertices
|
||||||
|
|
||||||
|
vn 0.000000 -1.000000 -0.000000
|
||||||
|
vn 0.000000 1.000000 -0.000000
|
||||||
|
vn 0.000000 0.000000 1.000000
|
||||||
|
vn 1.000000 0.000000 -0.000000
|
||||||
|
vn 0.000000 0.000000 -1.000000
|
||||||
|
vn -1.000000 0.000000 -0.000000
|
||||||
|
# 6 vertex normals
|
||||||
|
|
||||||
|
vt 1.000000 0.000000 0.000000
|
||||||
|
vt 1.000000 1.000000 0.000000
|
||||||
|
vt 0.000000 1.000000 0.000000
|
||||||
|
vt 0.000000 0.000000 0.000000
|
||||||
|
# 4 texture coords
|
||||||
|
|
||||||
|
g BlueBox
|
||||||
|
usemtl BlueCube
|
||||||
|
s 2
|
||||||
|
f 9/5/7 10/6/7 11/7/7
|
||||||
|
f 11/7/7 12/8/7 9/5/7
|
||||||
|
s 4
|
||||||
|
f 13/8/8 14/5/8 15/6/8
|
||||||
|
f 15/6/8 16/7/8 13/8/8
|
||||||
|
s 8
|
||||||
|
f 9/8/9 12/5/9 14/6/9
|
||||||
|
f 14/6/9 13/7/9 9/8/9
|
||||||
|
s 16
|
||||||
|
f 12/8/10 11/5/10 15/6/10
|
||||||
|
f 15/6/10 14/7/10 12/8/10
|
||||||
|
s 32
|
||||||
|
f 11/8/11 10/5/11 16/6/11
|
||||||
|
f 16/6/11 15/7/11 11/8/11
|
||||||
|
s 64
|
||||||
|
f 10/8/12 9/5/12 13/6/12
|
||||||
|
f 13/6/12 16/7/12 10/8/12
|
||||||
|
# 12 faces
|
||||||
|
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
1.0
|
||||||
|
{6799A53E-CBB1-451A-82C7-E5F10C33EBCA}
|
||||||
|
14435573237290376
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
#ifndef BoundsView_h__
|
||||||
|
#define BoundsView_h__
|
||||||
|
|
||||||
|
#include "ObjectsFactory.h"
|
||||||
|
|
||||||
|
LOBJECT(BoundsView, Component)
|
||||||
|
public:
|
||||||
|
void tick(float deltaTime) override {
|
||||||
|
LEngine::Instance()->GetActiveScene()->GetGizmos().SetMatrix(transform()->GetGlobalTransform());
|
||||||
|
LEngine::Instance()->GetActiveScene()->GetGizmos().DrawBounds(gameObject->GetComponent<MeshRenderer>()->GetMesh()->GetBounds());
|
||||||
|
}
|
||||||
|
};
|
||||||
|
#endif // BoundsView_h__
|
||||||
@@ -0,0 +1,67 @@
|
|||||||
|
#ifndef FreeCameraController_h__
|
||||||
|
#define FreeCameraController_h__
|
||||||
|
|
||||||
|
#include "Component.h"
|
||||||
|
#include "lframework/Input.h"
|
||||||
|
#include <iostream>
|
||||||
|
#include "Transform.h"
|
||||||
|
#include "ObjectsFactory.h"
|
||||||
|
|
||||||
|
LOBJECT(FreeCameraController, Component)
|
||||||
|
public:
|
||||||
|
float mouse_speed;
|
||||||
|
float move_speed = 3.0f;
|
||||||
|
static constexpr float pi = 3.14159265358979f;
|
||||||
|
|
||||||
|
FreeCameraController() : mouse_speed(0.01f){
|
||||||
|
_angle_x = _angle_y = 0.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void tick(float deltaTime) override {
|
||||||
|
auto mice = Input::Instance()->mice();
|
||||||
|
auto mouse = mice[0];
|
||||||
|
_angle_x += mouse_speed * mouse->GetDx();
|
||||||
|
_angle_y += mouse_speed * mouse->GetDy();
|
||||||
|
|
||||||
|
_angle_y = clamp(_angle_y, -pi / 2.0f, pi / 2.0f);
|
||||||
|
|
||||||
|
auto rv = Quaternion_f::angleAxis(_angle_y, float3(1.0f, 0.0f, 0.0f));
|
||||||
|
auto rh = Quaternion_f::angleAxis(_angle_x, float3(0.0f, 1.0f, 0.0f));
|
||||||
|
|
||||||
|
/* if (mouse->GetDx() != 0) {
|
||||||
|
std::cout << "Mouse DX: " << mouse->GetDx() << std::endl;
|
||||||
|
}
|
||||||
|
if (mouse->GetDy() != 0) {
|
||||||
|
std::cout << "Mouse DY: " << mouse->GetDy() << std::endl;
|
||||||
|
}*/
|
||||||
|
|
||||||
|
gameObject->transform->SetLocalRotation(lm::mul(rh, rv));
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
auto keyboards = Input::Instance()->keyboards();
|
||||||
|
auto keyboard = keyboards[0];
|
||||||
|
|
||||||
|
if(keyboard->GetKeyState(0x57)){
|
||||||
|
gameObject->transform->SetLocalPosition(gameObject->transform->GetLocalPosition() + gameObject->transform->forward() * (deltaTime * move_speed));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (keyboard->GetKeyState(0x53)) {
|
||||||
|
gameObject->transform->SetLocalPosition(gameObject->transform->GetLocalPosition() - gameObject->transform->forward() * (deltaTime * move_speed));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (keyboard->GetKeyState(0x41)) {
|
||||||
|
gameObject->transform->SetLocalPosition(gameObject->transform->GetLocalPosition() - gameObject->transform->right() * (deltaTime * move_speed));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (keyboard->GetKeyState(0x44)) {
|
||||||
|
gameObject->transform->SetLocalPosition(gameObject->transform->GetLocalPosition() + gameObject->transform->right() * (deltaTime * move_speed));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
private:
|
||||||
|
float _angle_x;
|
||||||
|
float _angle_y;
|
||||||
|
};
|
||||||
|
#endif // FreeCameraController_h__
|
||||||
Binary file not shown.
@@ -0,0 +1,167 @@
|
|||||||
|
#include <Windows.h>
|
||||||
|
#include "LEditor.h"
|
||||||
|
#include <tchar.h>
|
||||||
|
#include "LEngine.h"
|
||||||
|
#include "Ui.h"
|
||||||
|
#include "Controls/UiHwndCoreWindow.h"
|
||||||
|
#include "Controls/UiSwapChainWindow.h"
|
||||||
|
#include "RenderTargetOutput.h"
|
||||||
|
#include "SwapChainOutput.h"
|
||||||
|
#include "Mesh.h"
|
||||||
|
#include "GameObject.h"
|
||||||
|
#include "SceneRenderer.h"
|
||||||
|
#include "AssetManager.h"
|
||||||
|
#include "ObjMeshLoader.h"
|
||||||
|
#include "FreeCameraController.h"
|
||||||
|
#include "Input.h"
|
||||||
|
#include <chrono>
|
||||||
|
#include "BoundsView.h"
|
||||||
|
#include <objbase.h>
|
||||||
|
#include "AssetDatabase.h"
|
||||||
|
#include "AssetMetadata.h"
|
||||||
|
#include "OutputArchive.h"
|
||||||
|
#include "InputArchive.h"
|
||||||
|
#include "Asset.h"
|
||||||
|
#include "AssetFile.h"
|
||||||
|
#include <sstream>
|
||||||
|
|
||||||
|
#pragma comment(lib, "lframework.lib")
|
||||||
|
|
||||||
|
GameObjectPtr CreateCube() {
|
||||||
|
auto cubeObject = GameObject::create();
|
||||||
|
cubeObject->AddComponent<MeshRenderer>()->SetMesh(Mesh::Create([](MeshPtr mesh) {MeshGenerator::Cube(mesh, true); }));
|
||||||
|
return cubeObject;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct TestObject : public Object {
|
||||||
|
uint8_t uint8_t_;
|
||||||
|
uint16_t uint16_t_;
|
||||||
|
uint32_t uint32_t_;
|
||||||
|
uint64_t uint64_t_;
|
||||||
|
std::string string_;
|
||||||
|
std::wstring wstring_;
|
||||||
|
|
||||||
|
std::shared_ptr<TestObject> next;
|
||||||
|
|
||||||
|
virtual void serialize(Archive& archive) override {
|
||||||
|
archive << uint8_t_ << uint16_t_ << uint32_t_;
|
||||||
|
archive << uint64_t_ << string_ << wstring_;
|
||||||
|
archive << std::static_pointer_cast<Object>(next);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
void SaveScene(const std::wstring& path){
|
||||||
|
AssetDatabase::get().open_asset_file(path);
|
||||||
|
|
||||||
|
AssetFile asset(Guid(1, 2, 3, 4), path);
|
||||||
|
|
||||||
|
//find all game objects
|
||||||
|
auto scene_objects = Object::FindObjectsOfType<GameObject>();
|
||||||
|
|
||||||
|
//add all game objects and components to scene asset
|
||||||
|
for(auto obj : scene_objects){
|
||||||
|
asset.AddObject(obj);
|
||||||
|
auto components = obj->GetComponents<Component>();
|
||||||
|
for (auto component : components) {
|
||||||
|
asset.AddObject(component);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
asset.Save();
|
||||||
|
}
|
||||||
|
|
||||||
|
void CreateTestScene(){
|
||||||
|
auto cameraGo = GameObject::create();
|
||||||
|
cameraGo->SetName(L"Main camera");
|
||||||
|
cameraGo->AddComponent<Camera>()->fov = 45.0f;
|
||||||
|
cameraGo->transform->SetLocalPosition(float3(0.0f, 4.0f, -4.0f));
|
||||||
|
cameraGo->AddComponent<FreeCameraController>();
|
||||||
|
}
|
||||||
|
|
||||||
|
void LoadScene(const std::wstring& path){
|
||||||
|
auto archive = AssetDatabase::get().open_asset_file(path);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int APIENTRY _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow) {
|
||||||
|
AllocConsole();
|
||||||
|
freopen("CONOUT$", "w", stdout);
|
||||||
|
|
||||||
|
auto ints = Input::Instance();
|
||||||
|
AssetDatabase::get().set_root_path(L"D:\\lengine\\Assets");
|
||||||
|
|
||||||
|
auto editorWindow = UiSwapChainWindow::Create(L"LEngineEditorWindow");
|
||||||
|
auto engine = LEngine::Instance();
|
||||||
|
engine->Init(L"D:/lengine/LEngine/");
|
||||||
|
engine->LoadScene("");
|
||||||
|
|
||||||
|
std::wstring scene = L"TestScene.asset";
|
||||||
|
|
||||||
|
CreateTestScene();
|
||||||
|
//SaveScene(scene);
|
||||||
|
|
||||||
|
//LoadScene(scene);
|
||||||
|
|
||||||
|
auto outputs = engine->GetRenderer()->EnumOutputs();
|
||||||
|
auto modes = engine->GetRenderer()->GetDisplayModes(DXGI_FORMAT_B8G8R8A8_UNORM, outputs[0]);
|
||||||
|
|
||||||
|
editorWindow->size = UiSize(640, 480);
|
||||||
|
|
||||||
|
|
||||||
|
auto output = std::make_shared<SwapChainOutput>(engine->GetRenderer(), editorWindow->GetWindow()->GetHwnd(), 640, 480, false);
|
||||||
|
engine->AddOutput(output);
|
||||||
|
|
||||||
|
auto sceneRenderer = std::make_shared<SceneRenderer>();
|
||||||
|
|
||||||
|
ObjMeshLoader loader;
|
||||||
|
auto ob = loader.Load(L"D:\\lengine\\Assets\\Boxes.obj");
|
||||||
|
//ob[0]->AddComponent<BoundsView>();
|
||||||
|
|
||||||
|
auto mat = Material::Create(Shader::Create(L"shaders/shader.fx"), "");
|
||||||
|
auto tex = AssetManager::Instance()->LoadTexture(L"textures/1_store.dds");
|
||||||
|
mat->GetParametersBlock().SetTexture("diffuse", tex);
|
||||||
|
|
||||||
|
|
||||||
|
for(auto o : ob)
|
||||||
|
{
|
||||||
|
o->GetComponent<MeshRenderer>()->SetMaterial(mat, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*AssetMetadata meta(L"D:\\lengine\\Assets\\Boxes.obj");
|
||||||
|
meta.Save();
|
||||||
|
|
||||||
|
auto& factory = ObjectsFactory::instance();
|
||||||
|
|
||||||
|
*/
|
||||||
|
auto cameras = Object::FindObjectsOfType<Camera>();
|
||||||
|
|
||||||
|
auto cameraGo = cameras[0]->gameObject;
|
||||||
|
|
||||||
|
cameraGo->transform->SetLocalPosition(float3(0.0f, 0.0f, -4.0f));
|
||||||
|
|
||||||
|
typedef std::chrono::high_resolution_clock clock;
|
||||||
|
|
||||||
|
auto last_time = clock::now();
|
||||||
|
float delta_time = 0.0f;
|
||||||
|
|
||||||
|
float totalTime = 0;
|
||||||
|
while (true) {
|
||||||
|
auto now_time = clock::now();
|
||||||
|
delta_time = (float)((double)std::chrono::duration_cast<std::chrono::microseconds>(now_time - last_time).count() / 1000000.0);
|
||||||
|
last_time = now_time;
|
||||||
|
totalTime += delta_time;
|
||||||
|
if(totalTime >= 30.0f)
|
||||||
|
{
|
||||||
|
//sceneRenderer->createPSO = false;
|
||||||
|
}
|
||||||
|
std::chrono::high_resolution_clock::now();
|
||||||
|
LEngine::Instance()->GetActiveScene()->tick(delta_time);
|
||||||
|
sceneRenderer->RenderScene(engine->GetRenderer(), engine->GetActiveScene(), cameraGo->GetComponent<Camera>(), output);
|
||||||
|
editorWindow->Update(1);
|
||||||
|
Input::Instance()->strobe();
|
||||||
|
//output->Present();
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "resource.h"
|
||||||
+250091
File diff suppressed because one or more lines are too long
Binary file not shown.
|
After Width: | Height: | Size: 418 KiB |
Binary file not shown.
@@ -0,0 +1,105 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
|
<ItemGroup Label="ProjectConfigurations">
|
||||||
|
<ProjectConfiguration Include="Debug|Win32">
|
||||||
|
<Configuration>Debug</Configuration>
|
||||||
|
<Platform>Win32</Platform>
|
||||||
|
</ProjectConfiguration>
|
||||||
|
<ProjectConfiguration Include="Release|Win32">
|
||||||
|
<Configuration>Release</Configuration>
|
||||||
|
<Platform>Win32</Platform>
|
||||||
|
</ProjectConfiguration>
|
||||||
|
</ItemGroup>
|
||||||
|
<PropertyGroup Label="Globals">
|
||||||
|
<ProjectGuid>{B7F1D57A-B85B-46CC-80F5-14DE9E2C69DA}</ProjectGuid>
|
||||||
|
<Keyword>Win32Proj</Keyword>
|
||||||
|
<RootNamespace>LEditor</RootNamespace>
|
||||||
|
<WindowsTargetPlatformVersion>10.0.14393.0</WindowsTargetPlatformVersion>
|
||||||
|
</PropertyGroup>
|
||||||
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||||
|
<ConfigurationType>Application</ConfigurationType>
|
||||||
|
<UseDebugLibraries>true</UseDebugLibraries>
|
||||||
|
<PlatformToolset>v141</PlatformToolset>
|
||||||
|
<CharacterSet>Unicode</CharacterSet>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||||
|
<ConfigurationType>Application</ConfigurationType>
|
||||||
|
<UseDebugLibraries>false</UseDebugLibraries>
|
||||||
|
<PlatformToolset>v141</PlatformToolset>
|
||||||
|
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||||
|
<CharacterSet>Unicode</CharacterSet>
|
||||||
|
</PropertyGroup>
|
||||||
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||||
|
<ImportGroup Label="ExtensionSettings">
|
||||||
|
</ImportGroup>
|
||||||
|
<ImportGroup Label="Shared">
|
||||||
|
</ImportGroup>
|
||||||
|
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||||
|
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||||
|
</ImportGroup>
|
||||||
|
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||||
|
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||||
|
</ImportGroup>
|
||||||
|
<PropertyGroup Label="UserMacros" />
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||||
|
<LinkIncremental>true</LinkIncremental>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||||
|
<LinkIncremental>false</LinkIncremental>
|
||||||
|
</PropertyGroup>
|
||||||
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||||
|
<ClCompile>
|
||||||
|
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||||
|
<WarningLevel>Level3</WarningLevel>
|
||||||
|
<Optimization>Disabled</Optimization>
|
||||||
|
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
|
<AdditionalIncludeDirectories>../LEngine;../../nativelinq/nativelinq/nativelinq;D:\directui\DirectUI;D:\github\lframework;%(AdditionalIncludeDirectories);D:\lmath\lmath;D:\github\lframework\lframework</AdditionalIncludeDirectories>
|
||||||
|
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
|
||||||
|
</ClCompile>
|
||||||
|
<Link>
|
||||||
|
<SubSystem>Windows</SubSystem>
|
||||||
|
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||||
|
<AdditionalLibraryDirectories>../Debug;D:\directui\Debug;D:\github\lframework\Debug;D:\DirectXTex\DirectXTex\Bin\Desktop_2015_Win10\Win32\Debug</AdditionalLibraryDirectories>
|
||||||
|
<AdditionalDependencies>DXGUID.LIB;DXGI.lib;DirectXTex.lib;DirectUI.lib;d3d11.lib;d3d12.lib;LEngine.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||||
|
</Link>
|
||||||
|
</ItemDefinitionGroup>
|
||||||
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||||
|
<ClCompile>
|
||||||
|
<WarningLevel>Level3</WarningLevel>
|
||||||
|
<PrecompiledHeader>Use</PrecompiledHeader>
|
||||||
|
<Optimization>MaxSpeed</Optimization>
|
||||||
|
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||||
|
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||||
|
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
|
<AdditionalIncludeDirectories>../LEngine;../../nativelinq/nativelinq/nativelinq;D:\directui\DirectUI;%(AdditionalIncludeDirectories);D:\lmath\lmath;D:\github\lframework\lframework</AdditionalIncludeDirectories>
|
||||||
|
</ClCompile>
|
||||||
|
<Link>
|
||||||
|
<SubSystem>Windows</SubSystem>
|
||||||
|
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||||
|
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||||
|
<OptimizeReferences>true</OptimizeReferences>
|
||||||
|
<AdditionalLibraryDirectories>../Release;../../NettleCode/DirectUI/Release;%(AdditionalIncludeDirectories)</AdditionalLibraryDirectories>
|
||||||
|
<AdditionalDependencies>DirectUI.lib;d3d12.lib;LEngine.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||||
|
</Link>
|
||||||
|
</ItemDefinitionGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ClInclude Include="BoundsView.h" />
|
||||||
|
<ClInclude Include="FreeCameraController.h" />
|
||||||
|
<ClInclude Include="LEditor.h" />
|
||||||
|
<ClInclude Include="Resource.h" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ClCompile Include="LEditor.cpp" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ResourceCompile Include="LEditor.rc" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<Image Include="LEditor.ico" />
|
||||||
|
<Image Include="small.ico" />
|
||||||
|
</ItemGroup>
|
||||||
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||||
|
<ImportGroup Label="ExtensionTargets">
|
||||||
|
</ImportGroup>
|
||||||
|
</Project>
|
||||||
@@ -0,0 +1,31 @@
|
|||||||
|
//{{NO_DEPENDENCIES}}
|
||||||
|
// Microsoft Visual C++ generated include file.
|
||||||
|
// Used by LEditor.rc
|
||||||
|
//
|
||||||
|
|
||||||
|
#define IDS_APP_TITLE 103
|
||||||
|
|
||||||
|
#define IDR_MAINFRAME 128
|
||||||
|
#define IDD_LEDITOR_DIALOG 102
|
||||||
|
#define IDD_ABOUTBOX 103
|
||||||
|
#define IDM_ABOUT 104
|
||||||
|
#define IDM_EXIT 105
|
||||||
|
#define IDI_LEDITOR 107
|
||||||
|
#define IDI_SMALL 108
|
||||||
|
#define IDC_LEDITOR 109
|
||||||
|
#define IDC_MYICON 2
|
||||||
|
#ifndef IDC_STATIC
|
||||||
|
#define IDC_STATIC -1
|
||||||
|
#endif
|
||||||
|
// Next default values for new objects
|
||||||
|
//
|
||||||
|
#ifdef APSTUDIO_INVOKED
|
||||||
|
#ifndef APSTUDIO_READONLY_SYMBOLS
|
||||||
|
|
||||||
|
#define _APS_NO_MFC 130
|
||||||
|
#define _APS_NEXT_RESOURCE_VALUE 129
|
||||||
|
#define _APS_NEXT_COMMAND_VALUE 32771
|
||||||
|
#define _APS_NEXT_CONTROL_VALUE 1000
|
||||||
|
#define _APS_NEXT_SYMED_VALUE 110
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
Binary file not shown.
|
After Width: | Height: | Size: 418 KiB |
+37
@@ -0,0 +1,37 @@
|
|||||||
|
|
||||||
|
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||||
|
# Visual Studio 14
|
||||||
|
VisualStudioVersion = 14.0.23107.0
|
||||||
|
MinimumVisualStudioVersion = 10.0.40219.1
|
||||||
|
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "LEngine", "LEngine\LEngine.vcxproj", "{91440EE0-7471-4D73-A6FD-3DCB64E56C13}"
|
||||||
|
EndProject
|
||||||
|
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "LEditor", "LEditor\LEditor.vcxproj", "{B7F1D57A-B85B-46CC-80F5-14DE9E2C69DA}"
|
||||||
|
ProjectSection(ProjectDependencies) = postProject
|
||||||
|
{91440EE0-7471-4D73-A6FD-3DCB64E56C13} = {91440EE0-7471-4D73-A6FD-3DCB64E56C13}
|
||||||
|
EndProjectSection
|
||||||
|
EndProject
|
||||||
|
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "LEnginePlayer", "LEnginePlayer\LEnginePlayer.vcxproj", "{845A038A-8163-4851-95E1-78EFFD5F0AAF}"
|
||||||
|
EndProject
|
||||||
|
Global
|
||||||
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
|
Debug|x86 = Debug|x86
|
||||||
|
Release|x86 = Release|x86
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||||
|
{91440EE0-7471-4D73-A6FD-3DCB64E56C13}.Debug|x86.ActiveCfg = Debug|Win32
|
||||||
|
{91440EE0-7471-4D73-A6FD-3DCB64E56C13}.Debug|x86.Build.0 = Debug|Win32
|
||||||
|
{91440EE0-7471-4D73-A6FD-3DCB64E56C13}.Release|x86.ActiveCfg = Release|Win32
|
||||||
|
{91440EE0-7471-4D73-A6FD-3DCB64E56C13}.Release|x86.Build.0 = Release|Win32
|
||||||
|
{B7F1D57A-B85B-46CC-80F5-14DE9E2C69DA}.Debug|x86.ActiveCfg = Debug|Win32
|
||||||
|
{B7F1D57A-B85B-46CC-80F5-14DE9E2C69DA}.Debug|x86.Build.0 = Debug|Win32
|
||||||
|
{B7F1D57A-B85B-46CC-80F5-14DE9E2C69DA}.Release|x86.ActiveCfg = Release|Win32
|
||||||
|
{B7F1D57A-B85B-46CC-80F5-14DE9E2C69DA}.Release|x86.Build.0 = Release|Win32
|
||||||
|
{845A038A-8163-4851-95E1-78EFFD5F0AAF}.Debug|x86.ActiveCfg = Debug|Win32
|
||||||
|
{845A038A-8163-4851-95E1-78EFFD5F0AAF}.Debug|x86.Build.0 = Debug|Win32
|
||||||
|
{845A038A-8163-4851-95E1-78EFFD5F0AAF}.Release|x86.ActiveCfg = Release|Win32
|
||||||
|
{845A038A-8163-4851-95E1-78EFFD5F0AAF}.Release|x86.Build.0 = Release|Win32
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
|
HideSolutionNode = FALSE
|
||||||
|
EndGlobalSection
|
||||||
|
EndGlobal
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
#include "Archive.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Archive& Archive::operator << (AssetFileLink& value) {
|
||||||
|
serialize(&value, sizeof(value)); return *this;
|
||||||
|
}
|
||||||
@@ -0,0 +1,109 @@
|
|||||||
|
#ifndef Archive_h__
|
||||||
|
#define Archive_h__
|
||||||
|
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
#include <string>
|
||||||
|
#include <functional>
|
||||||
|
#include <memory>
|
||||||
|
#include "Asset.h"
|
||||||
|
#include "lmath.h"
|
||||||
|
#include <type_traits>
|
||||||
|
#include "Object.h"
|
||||||
|
#include <cstdint>
|
||||||
|
#define POD_SERIALIZE(_type) Archive& operator << (_type& value) { serialize(&value, sizeof(value)); return *this; }
|
||||||
|
|
||||||
|
class Object;
|
||||||
|
class Archive {
|
||||||
|
public:
|
||||||
|
typedef uint64_t size_type;
|
||||||
|
std::function<void(std::shared_ptr<Object>)> SaveReferenceCallback;
|
||||||
|
std::function<std::shared_ptr<Object>(const AssetFileLink&)> LoadReferenceCallback;
|
||||||
|
|
||||||
|
Archive():SaveReferenceCallback(nullptr){
|
||||||
|
|
||||||
|
}
|
||||||
|
virtual ~Archive() {}
|
||||||
|
virtual bool is_loading() const = 0;
|
||||||
|
virtual void serialize(void* data, size_t size) = 0;
|
||||||
|
|
||||||
|
virtual size_type get_offset() const = 0;
|
||||||
|
virtual void set_offset(size_type offset) = 0;
|
||||||
|
|
||||||
|
virtual void flush() {}
|
||||||
|
|
||||||
|
POD_SERIALIZE(uint8_t);
|
||||||
|
POD_SERIALIZE(uint16_t);
|
||||||
|
POD_SERIALIZE(uint32_t);
|
||||||
|
POD_SERIALIZE(uint64_t);
|
||||||
|
POD_SERIALIZE(int8_t);
|
||||||
|
POD_SERIALIZE(int16_t);
|
||||||
|
POD_SERIALIZE(int32_t);
|
||||||
|
POD_SERIALIZE(int64_t);
|
||||||
|
POD_SERIALIZE(float);
|
||||||
|
POD_SERIALIZE(double);
|
||||||
|
POD_SERIALIZE(lm::float2);
|
||||||
|
POD_SERIALIZE(lm::float3);
|
||||||
|
POD_SERIALIZE(lm::float4);
|
||||||
|
POD_SERIALIZE(lm::double2);
|
||||||
|
POD_SERIALIZE(lm::double3);
|
||||||
|
POD_SERIALIZE(lm::double4);
|
||||||
|
|
||||||
|
POD_SERIALIZE(lm::Quaternion_f);
|
||||||
|
|
||||||
|
Archive& operator << (std::string& value) {
|
||||||
|
uint32_t string_len = 0;
|
||||||
|
if (is_loading()) {
|
||||||
|
serialize(&string_len, sizeof(string_len));
|
||||||
|
value.resize(string_len);
|
||||||
|
serialize(&value[0], string_len);
|
||||||
|
} else {
|
||||||
|
string_len = value.size();
|
||||||
|
serialize(&string_len, sizeof(string_len));
|
||||||
|
serialize(&value[0], string_len);
|
||||||
|
}
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
Archive& operator << (std::wstring& value) {
|
||||||
|
uint32_t string_len = 0;
|
||||||
|
if (is_loading()) {
|
||||||
|
serialize(&string_len, sizeof(string_len));
|
||||||
|
value.resize(string_len);
|
||||||
|
serialize(&value[0], string_len * sizeof(std::wstring::value_type));
|
||||||
|
} else {
|
||||||
|
string_len = value.size();
|
||||||
|
serialize(&string_len, sizeof(string_len));
|
||||||
|
serialize(&value[0], string_len * sizeof(std::wstring::value_type));
|
||||||
|
}
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T, typename = typename std::enable_if<std::is_base_of<Object, T>::value>::type>
|
||||||
|
Archive& operator << (std::shared_ptr<T>& value) {
|
||||||
|
if (is_loading()) {
|
||||||
|
AssetFileLink link;
|
||||||
|
(*this) << link;
|
||||||
|
if(link.localId == -1)
|
||||||
|
{
|
||||||
|
value = nullptr;
|
||||||
|
}else
|
||||||
|
{
|
||||||
|
auto pos = get_offset();
|
||||||
|
value = LoadReferenceCallback == nullptr ? nullptr : std::dynamic_pointer_cast<T>(LoadReferenceCallback(link));
|
||||||
|
set_offset(pos);
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
if (SaveReferenceCallback != nullptr) {
|
||||||
|
SaveReferenceCallback(value);
|
||||||
|
}
|
||||||
|
AssetFileLink link = value == nullptr ? AssetFileLink() : value->GetFileLink();
|
||||||
|
(*this) << link;
|
||||||
|
}
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
private:
|
||||||
|
Archive& operator << (AssetFileLink& value);
|
||||||
|
};
|
||||||
|
#endif // Archive_h__
|
||||||
@@ -0,0 +1,45 @@
|
|||||||
|
#ifndef Asset_h__
|
||||||
|
#define Asset_h__
|
||||||
|
|
||||||
|
#include <Windows.h>
|
||||||
|
#include <cstdint>
|
||||||
|
#include <array>
|
||||||
|
#include <algorithm>
|
||||||
|
#include "Guid.h"
|
||||||
|
|
||||||
|
class AssetFileLink {
|
||||||
|
public:
|
||||||
|
using LocalFileID = std::uint32_t;
|
||||||
|
static constexpr LocalFileID InvalidID = -1;
|
||||||
|
|
||||||
|
Guid fileGuid;
|
||||||
|
LocalFileID localId;
|
||||||
|
|
||||||
|
AssetFileLink():localId(InvalidID){}
|
||||||
|
|
||||||
|
AssetFileLink(const AssetFileLink& link) :fileGuid(link.fileGuid), localId(link.localId) {}
|
||||||
|
|
||||||
|
AssetFileLink(Guid _fileGuid, LocalFileID _localId) :fileGuid(_fileGuid), localId(_localId) {}
|
||||||
|
|
||||||
|
AssetFileLink& operator=(const AssetFileLink& link) {
|
||||||
|
fileGuid = link.fileGuid;
|
||||||
|
localId = link.localId;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool operator==(const AssetFileLink& link) const {
|
||||||
|
return (fileGuid == link.fileGuid) && (localId == link.localId);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool operator!=(const AssetFileLink& link) const {
|
||||||
|
return (fileGuid != link.fileGuid) || (localId != link.localId);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool IsValid() const{
|
||||||
|
return (localId != InvalidID) && !fileGuid.IsZero();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#endif // Asset_h__
|
||||||
@@ -0,0 +1,101 @@
|
|||||||
|
#include "AssetDatabase.h"
|
||||||
|
#include <filesystem>
|
||||||
|
#include <iostream>
|
||||||
|
#include "ModelImporter.h"
|
||||||
|
#include "TextureImporter.h"
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
|
AssetDatabase::AssetDatabase()
|
||||||
|
{
|
||||||
|
_importers.push_back(std::make_shared<ModelImporter>());
|
||||||
|
//_importers.push_back(std::make_shared<TextureImporter>());
|
||||||
|
}
|
||||||
|
|
||||||
|
void AssetDatabase::set_root_path(const std::wstring& path)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
std::wstring AssetDatabase::asset_to_meta_path(const std::wstring& asset_path)
|
||||||
|
{
|
||||||
|
std::tr2::sys::path src(asset_path);
|
||||||
|
return src.parent_path().append(src.filename().wstring() + L".meta").wstring();
|
||||||
|
}
|
||||||
|
|
||||||
|
void AssetDatabase::register_importer(std::shared_ptr<AssetImporter> importer)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<std::shared_ptr<Object>> AssetDatabase::load_all_objects(std::shared_ptr<AssetFile> asset)
|
||||||
|
{
|
||||||
|
std::vector<std::shared_ptr<Object>> result;
|
||||||
|
auto table = asset->objectsTable;
|
||||||
|
for (auto& obj : table.objects)
|
||||||
|
{
|
||||||
|
result.push_back(LoadObject(AssetFileLink(asset->guid(), obj.localId)));
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
std::shared_ptr<AssetImporter> AssetDatabase::find_importer(const std::wstring& asset_path) const
|
||||||
|
{
|
||||||
|
auto importer = std::find_if(_importers.begin(), _importers.end(), [asset_path](std::shared_ptr<AssetImporter> im) { return im->can_import(asset_path); });
|
||||||
|
if (importer != _importers.end())
|
||||||
|
{
|
||||||
|
return *importer;
|
||||||
|
}
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
Guid AssetDatabase::file_to_guid(const std::wstring& path) const
|
||||||
|
{
|
||||||
|
return AssetMetadata(path).get_guid();
|
||||||
|
}
|
||||||
|
|
||||||
|
std::shared_ptr<AssetFile> AssetDatabase::open_asset_file(const std::wstring& path)
|
||||||
|
{
|
||||||
|
return std::make_shared<AssetFile>(file_to_guid(path), path);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::shared_ptr<Object> AssetDatabase::LoadReference(const AssetFileLink& link)
|
||||||
|
{
|
||||||
|
return LoadObject(link);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
std::wstring guid_to_path(Guid guid)
|
||||||
|
{//TODO: fix hardcode
|
||||||
|
return LR"(C:\Users\Sergey\Desktop\Assets\test.asset)";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
std::shared_ptr<AssetFile> AssetDatabase::OpenArchive(Guid guid)
|
||||||
|
{ //TODO: fix hardcode
|
||||||
|
if (open_archives.empty())
|
||||||
|
{
|
||||||
|
auto a = std::make_shared<AssetFile>(guid, guid_to_path(guid));
|
||||||
|
a->input->LoadReferenceCallback = std::bind(&AssetDatabase::LoadReference, this, std::placeholders::_1);
|
||||||
|
open_archives.push_back(a);
|
||||||
|
}
|
||||||
|
return open_archives[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
std::shared_ptr<Object> AssetDatabase::LoadObject(AssetFileLink link)
|
||||||
|
{
|
||||||
|
auto f = Object::Find(link);
|
||||||
|
if (f != nullptr) { return f; }
|
||||||
|
|
||||||
|
auto archive = OpenArchive(link.fileGuid);
|
||||||
|
archive->SeekToFile(link.localId);
|
||||||
|
|
||||||
|
std::wstring type_name;
|
||||||
|
(*archive->input) << type_name;
|
||||||
|
|
||||||
|
auto obj = ObjectsFactory::instance().create_object(type_name);
|
||||||
|
obj->SetLink(link);
|
||||||
|
|
||||||
|
obj->serialize(*archive->input);
|
||||||
|
|
||||||
|
|
||||||
|
return obj;
|
||||||
|
}
|
||||||
@@ -0,0 +1,36 @@
|
|||||||
|
#ifndef AssetDatabase_h__
|
||||||
|
#define AssetDatabase_h__
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <memory>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#include "AssetMetadata.h"
|
||||||
|
#include "AssetImporter.h"
|
||||||
|
#include "AssetFile.h"
|
||||||
|
|
||||||
|
|
||||||
|
class AssetDatabase{
|
||||||
|
public:
|
||||||
|
static AssetDatabase& get() {
|
||||||
|
static AssetDatabase instance;
|
||||||
|
return instance;
|
||||||
|
}
|
||||||
|
static std::wstring asset_to_meta_path(const std::wstring& asset_path);
|
||||||
|
Guid file_to_guid(const std::wstring& path) const;
|
||||||
|
std::shared_ptr<AssetFile> open_asset_file(const std::wstring& path);
|
||||||
|
void set_root_path(const std::wstring& path);
|
||||||
|
static void register_importer(std::shared_ptr<AssetImporter> importer);
|
||||||
|
std::shared_ptr<AssetImporter> find_importer(const std::wstring& asset_path) const;
|
||||||
|
|
||||||
|
std::shared_ptr<Object> LoadReference(const AssetFileLink& link);
|
||||||
|
std::shared_ptr<AssetFile> OpenArchive(Guid guid);
|
||||||
|
std::shared_ptr<Object> LoadObject(AssetFileLink link);
|
||||||
|
|
||||||
|
std::vector<std::shared_ptr<Object>> load_all_objects(std::shared_ptr<AssetFile> asset);
|
||||||
|
private:
|
||||||
|
std::vector<std::shared_ptr<AssetFile>> open_archives;
|
||||||
|
AssetDatabase();
|
||||||
|
std::vector<std::shared_ptr<AssetImporter>> _importers;
|
||||||
|
};
|
||||||
|
#endif // AssetDatabase_h__
|
||||||
@@ -0,0 +1,225 @@
|
|||||||
|
#ifndef AssetFile_h__
|
||||||
|
#define AssetFile_h__
|
||||||
|
|
||||||
|
#include "InputArchive.h"
|
||||||
|
#include "OutputArchive.h"
|
||||||
|
#include "Asset.h"
|
||||||
|
#include <vector>
|
||||||
|
#include <sstream>
|
||||||
|
#include <filesystem>
|
||||||
|
|
||||||
|
namespace fs = std::experimental::filesystem::v1;
|
||||||
|
|
||||||
|
class AssetObjectDescriptor : public Object {
|
||||||
|
public:
|
||||||
|
uint64_t localId;
|
||||||
|
int64_t offset;
|
||||||
|
uint64_t length;
|
||||||
|
AssetObjectDescriptor():localId(0), offset(0), length(0)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
AssetObjectDescriptor(uint64_t _localId, int64_t _offset, uint64_t _length):localId(_localId), offset(_offset), length(_length){
|
||||||
|
|
||||||
|
}
|
||||||
|
virtual void serialize(Archive& archive) override {
|
||||||
|
archive << localId << offset << length;
|
||||||
|
}
|
||||||
|
virtual std::wstring get_type_name() const override {
|
||||||
|
return L"AssetObjectDescriptor";
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class AssetObjectsTable : public Object{
|
||||||
|
public:
|
||||||
|
uint64_t lastId;
|
||||||
|
std::vector<AssetObjectDescriptor> objects;
|
||||||
|
|
||||||
|
AssetObjectsTable():lastId(0)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
bool GetFileDescriptor(uint64_t localId, AssetObjectDescriptor& desc){
|
||||||
|
for (auto& o : objects) {
|
||||||
|
if (o.localId == localId) {
|
||||||
|
desc = o;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Contains(uint64_t localId) const {
|
||||||
|
for (auto& o : objects) {
|
||||||
|
if (o.localId == localId) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void serialize(Archive& archive) override {
|
||||||
|
archive << lastId;
|
||||||
|
if(archive.is_loading()){
|
||||||
|
uint64_t objectsCount = 0;
|
||||||
|
archive << objectsCount;
|
||||||
|
objects.clear();
|
||||||
|
for(uint64_t i = 0; i < objectsCount; ++i){
|
||||||
|
AssetObjectDescriptor d;
|
||||||
|
d.serialize(archive);
|
||||||
|
objects.push_back(d);
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
uint64_t objectsCount = objects.size();
|
||||||
|
archive << objectsCount;
|
||||||
|
for (auto& o : objects){
|
||||||
|
o.serialize(archive);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
virtual std::wstring get_type_name() const override {
|
||||||
|
return L"AssetObjectsTable";
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
inline std::shared_ptr<OutputArchive> CreateMemoryOutArchive(){
|
||||||
|
return std::make_shared<OutputArchive>(std::make_shared<std::stringstream>(std::ios::in | std::ios::out | std::ios::binary));
|
||||||
|
}
|
||||||
|
|
||||||
|
class AssetFile {
|
||||||
|
public:
|
||||||
|
typedef uint64_t table_offset_t;
|
||||||
|
AssetObjectsTable objectsTable;
|
||||||
|
std::shared_ptr<InputArchive> input;
|
||||||
|
std::shared_ptr<OutputArchive> output;
|
||||||
|
std::shared_ptr<std::fstream> stream;
|
||||||
|
|
||||||
|
AssetFile(Guid fileGuid, const std::wstring& path):_fileGuid(fileGuid), _path(path){
|
||||||
|
OpenFile(false);
|
||||||
|
|
||||||
|
if(stream->is_open()){
|
||||||
|
stream->seekg(0, std::ios::end);
|
||||||
|
if((int)stream->tellg() == 0){
|
||||||
|
std::cout << "Empty asset created!" << std::endl;
|
||||||
|
SaveFooter();
|
||||||
|
}
|
||||||
|
ReadFooter();
|
||||||
|
}
|
||||||
|
//input = std::make_shared<InputArchive>(path);
|
||||||
|
}
|
||||||
|
|
||||||
|
void OpenFile(bool trunc){
|
||||||
|
input = nullptr;
|
||||||
|
output = nullptr;
|
||||||
|
stream = std::make_shared<std::fstream>(_path, (trunc ? std::ios::trunc : std::ios::app) | std::ios::in | std::ios::out | std::ios::binary);
|
||||||
|
if (stream->is_open()) {
|
||||||
|
input = std::make_shared<InputArchive>(stream);
|
||||||
|
output = std::make_shared<OutputArchive>(stream);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CloseFile()
|
||||||
|
{
|
||||||
|
input = nullptr;
|
||||||
|
output = nullptr;
|
||||||
|
if(stream != nullptr && stream->is_open()){
|
||||||
|
stream->close();
|
||||||
|
}
|
||||||
|
stream = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Save(){
|
||||||
|
auto tmpOut = CreateMemoryOutArchive();
|
||||||
|
//save objects
|
||||||
|
int64_t objectOffset = 0;
|
||||||
|
for(auto& v : objectsTable.objects){
|
||||||
|
auto object = Object::Find(AssetFileLink(_fileGuid, v.localId));
|
||||||
|
|
||||||
|
v.offset = objectOffset;
|
||||||
|
|
||||||
|
auto startOffset = objectOffset = tmpOut->GetStream()->tellp();
|
||||||
|
//save all loaded objects, copy not loaded
|
||||||
|
if(object != nullptr){
|
||||||
|
(*tmpOut) << object->get_type_name();
|
||||||
|
object->serialize(*tmpOut);
|
||||||
|
}else{
|
||||||
|
stream->seekg(v.offset, std::ios::beg);
|
||||||
|
std::vector<uint8_t> objectBytes(v.length);
|
||||||
|
stream->read((char*)&objectBytes[0], objectBytes.size());
|
||||||
|
tmpOut->GetStream()->write((char*)&objectBytes[0], objectBytes.size());
|
||||||
|
}
|
||||||
|
objectOffset = tmpOut->GetStream()->tellp();
|
||||||
|
v.length = objectOffset - startOffset;
|
||||||
|
}
|
||||||
|
|
||||||
|
CloseFile();
|
||||||
|
OpenFile(true);
|
||||||
|
|
||||||
|
auto content = std::static_pointer_cast<std::stringstream>(tmpOut->GetStream())->str();
|
||||||
|
stream->write(&content[0], content.size());
|
||||||
|
stream->seekg(0, std::ios::end);
|
||||||
|
//save footer
|
||||||
|
SaveFooter();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SeekToFile(uint64_t fileId) {
|
||||||
|
AssetObjectDescriptor desc;
|
||||||
|
if (objectsTable.GetFileDescriptor(fileId, desc)) {
|
||||||
|
if (desc.offset >= 0) {
|
||||||
|
stream->seekg(desc.offset, std::ios::beg);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ReadFooter()
|
||||||
|
{
|
||||||
|
std::cout << "Read footer" << std::endl;
|
||||||
|
//read table offset
|
||||||
|
auto off = -((std::streamoff)sizeof(table_offset_t));
|
||||||
|
stream->seekg(off, std::ios::end);
|
||||||
|
table_offset_t offset = 0;
|
||||||
|
(*input) << offset;
|
||||||
|
|
||||||
|
auto table_file_offset = off - (std::streamoff)offset;
|
||||||
|
stream->seekg(table_file_offset, std::ios::end);
|
||||||
|
objectsTable.serialize(*input);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SaveFooter(){
|
||||||
|
std::cout << "Save footer" << std::endl;
|
||||||
|
stream->seekg(0, std::ios::end);
|
||||||
|
auto tmpArchive = CreateMemoryOutArchive();
|
||||||
|
objectsTable.serialize(*tmpArchive);
|
||||||
|
auto data = std::static_pointer_cast<std::stringstream>(tmpArchive->GetStream())->str();
|
||||||
|
table_offset_t size = data.size();
|
||||||
|
stream->write(&data[0], size);
|
||||||
|
(*output) << size;
|
||||||
|
|
||||||
|
output->flush();
|
||||||
|
}
|
||||||
|
|
||||||
|
void AddObject(std::shared_ptr<Object> obj){
|
||||||
|
if (obj->GetFileLink().IsValid()) {
|
||||||
|
if (obj->GetFileLink().fileGuid == _fileGuid) {
|
||||||
|
std::wcout << "Object " << obj->get_name() << " is already in current asset. Can't add twice" << std::endl;
|
||||||
|
} else {
|
||||||
|
std::wcout << "Object " << obj->get_name() << " is already in another asset. Can't add." << std::endl;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
obj->SetLink(AssetFileLink(_fileGuid, objectsTable.lastId++));
|
||||||
|
objectsTable.objects.push_back(AssetObjectDescriptor(obj->GetFileLink().localId, 0, 0));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const Guid& guid() const
|
||||||
|
{
|
||||||
|
return _fileGuid;
|
||||||
|
}
|
||||||
|
private:
|
||||||
|
Guid _fileGuid;
|
||||||
|
std::wstring _path;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // AssetFile_h__
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
#ifndef AssetImporter_h__
|
||||||
|
#define AssetImporter_h__
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
#include <filesystem>
|
||||||
|
|
||||||
|
class AssetImporter {
|
||||||
|
public:
|
||||||
|
virtual void import(std::wstring asset_path) = 0;
|
||||||
|
virtual bool can_import(const std::wstring& path) const = 0;
|
||||||
|
virtual bool set_parameters(std::wstring params) = 0;
|
||||||
|
virtual std::wstring get_parameters() const = 0;
|
||||||
|
virtual std::wstring name() = 0;
|
||||||
|
};
|
||||||
|
#endif // AssetImporter_h__
|
||||||
@@ -0,0 +1,73 @@
|
|||||||
|
#include "AssetManager.h"
|
||||||
|
#include "DirectXTex.h"
|
||||||
|
#include "DDSTextureLoader12.h"
|
||||||
|
#include "LEngine.h"
|
||||||
|
#include "Texture.h"
|
||||||
|
|
||||||
|
std::shared_ptr<AssetManager> AssetManager::_instance = nullptr;
|
||||||
|
|
||||||
|
TexturePtr AssetManager::LoadTexture(const std::wstring& path) const
|
||||||
|
{
|
||||||
|
auto renderer = LEngine::Instance()->GetRenderer();
|
||||||
|
auto device = renderer->GetDevice();
|
||||||
|
|
||||||
|
ID3D12ResourcePtr resource;
|
||||||
|
|
||||||
|
std::unique_ptr<uint8_t[]> data;
|
||||||
|
std::vector<D3D12_SUBRESOURCE_DATA> srData;
|
||||||
|
DirectX::LoadDDSTextureFromFile(device.Get(), GetFullAssetPath(path).c_str(), &resource, data, srData);
|
||||||
|
|
||||||
|
//auto cmdList = renderer->BeginCommandList();
|
||||||
|
|
||||||
|
|
||||||
|
//create upload heap
|
||||||
|
D3D12_RESOURCE_DESC desc;
|
||||||
|
desc = resource->GetDesc();
|
||||||
|
|
||||||
|
UINT64 textureUploadBufferSize;
|
||||||
|
device->GetCopyableFootprints(&desc, 0, srData.size(), 0, nullptr, nullptr, nullptr, &textureUploadBufferSize);
|
||||||
|
|
||||||
|
// now we create an upload heap to upload our texture to the GPU
|
||||||
|
ID3D12ResourcePtr textureBufferUploadHeap;
|
||||||
|
auto hr = device->CreateCommittedResource(
|
||||||
|
&CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_UPLOAD), // upload heap
|
||||||
|
D3D12_HEAP_FLAG_NONE, // no flags
|
||||||
|
&CD3DX12_RESOURCE_DESC::Buffer(textureUploadBufferSize), // resource description for a buffer (storing the image data in this heap just to copy to the default heap)
|
||||||
|
D3D12_RESOURCE_STATE_GENERIC_READ, // We will copy the contents from this heap to the default heap above
|
||||||
|
nullptr,
|
||||||
|
IID_PPV_ARGS(&textureBufferUploadHeap));
|
||||||
|
if (FAILED(hr))
|
||||||
|
{
|
||||||
|
FatalError(L"Failed to create upload heap");
|
||||||
|
}
|
||||||
|
textureBufferUploadHeap->SetName(L"Texture Buffer Upload Resource Heap");
|
||||||
|
|
||||||
|
auto commandList = renderer->BeginCommandList();
|
||||||
|
//copy subresource
|
||||||
|
UpdateSubresources(commandList.Get(), resource.Get(), textureBufferUploadHeap.Get(), 0, 0, srData.size(), &srData[0]);
|
||||||
|
commandList->ResourceBarrier(1, &CD3DX12_RESOURCE_BARRIER::Transition(resource.Get(), D3D12_RESOURCE_STATE_COPY_DEST, D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE));
|
||||||
|
|
||||||
|
|
||||||
|
renderer->EndCommandList();
|
||||||
|
renderer->WaitCommandsQueue();
|
||||||
|
|
||||||
|
//create shader resource view
|
||||||
|
auto srvMemory = renderer->getSrvDescriptorsAllocator()->alloc();
|
||||||
|
|
||||||
|
D3D12_RESOURCE_DESC texDesc;
|
||||||
|
texDesc = resource->GetDesc();
|
||||||
|
|
||||||
|
|
||||||
|
D3D12_SHADER_RESOURCE_VIEW_DESC srvDesc = {};
|
||||||
|
srvDesc.Shader4ComponentMapping = D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING;
|
||||||
|
srvDesc.Format = texDesc.Format;
|
||||||
|
srvDesc.ViewDimension = D3D12_SRV_DIMENSION_TEXTURE2D;
|
||||||
|
srvDesc.Texture2D.MipLevels = texDesc.MipLevels;
|
||||||
|
device->CreateShaderResourceView(resource.Get(), &srvDesc, srvMemory);
|
||||||
|
|
||||||
|
|
||||||
|
auto result = std::make_shared<Texture>(resource, srvMemory);
|
||||||
|
|
||||||
|
//DirectX::CreateTexture(renderer->GetDevice(), image.GetImages(), image.GetImageCount(), metadata, &resource);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
@@ -0,0 +1,30 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
#include <string>
|
||||||
|
#include "d3d11_types.h"
|
||||||
|
#include "Texture.h"
|
||||||
|
#include "ForwardDeclarations.h"
|
||||||
|
|
||||||
|
class AssetManager {
|
||||||
|
public:
|
||||||
|
static std::shared_ptr<AssetManager> Instance() {
|
||||||
|
if (_instance == nullptr) {
|
||||||
|
_instance = std::make_shared<AssetManager>();
|
||||||
|
}
|
||||||
|
return _instance;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SetAssetsFolder(const std::wstring& folder) {
|
||||||
|
_assetsFolder = folder;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::wstring GetFullAssetPath(const std::wstring& relativePath) const
|
||||||
|
{
|
||||||
|
return _assetsFolder + relativePath;
|
||||||
|
}
|
||||||
|
TexturePtr LoadTexture(const std::wstring& path) const;
|
||||||
|
private:
|
||||||
|
static std::shared_ptr<AssetManager> _instance;
|
||||||
|
std::wstring _assetsFolder;
|
||||||
|
};
|
||||||
@@ -0,0 +1,75 @@
|
|||||||
|
#include "AssetMetadata.h"
|
||||||
|
#include <fstream>
|
||||||
|
#include <combaseapi.h>
|
||||||
|
#include <iostream>
|
||||||
|
#include <string>
|
||||||
|
#include <sstream>
|
||||||
|
#include "AssetDatabase.h"
|
||||||
|
#include <Windows.h>
|
||||||
|
#include <wrl.h>
|
||||||
|
using namespace Microsoft::WRL;
|
||||||
|
|
||||||
|
AssetMetadata::AssetMetadata(const std::wstring& asset_path) : _asset_path(asset_path) {
|
||||||
|
_meta_path = AssetDatabase::asset_to_meta_path(_asset_path);
|
||||||
|
|
||||||
|
if (std::tr2::sys::exists(std::tr2::sys::path(_meta_path))) {
|
||||||
|
Load();
|
||||||
|
} else {
|
||||||
|
create();
|
||||||
|
Save();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void AssetMetadata::create() {
|
||||||
|
CoCreateGuid((GUID*)&_guid);
|
||||||
|
_modification_time = std::tr2::sys::last_write_time(std::tr2::sys::path(_asset_path)).time_since_epoch().count();
|
||||||
|
_importer = AssetDatabase::get().find_importer(_asset_path);
|
||||||
|
}
|
||||||
|
|
||||||
|
void AssetMetadata::Load() {
|
||||||
|
std::wifstream file(_meta_path);
|
||||||
|
|
||||||
|
std::wstring v;
|
||||||
|
std::getline(file, v);
|
||||||
|
|
||||||
|
std::wstring guid_str;
|
||||||
|
std::getline(file, guid_str);
|
||||||
|
_guid = str_to_guid(guid_str);
|
||||||
|
|
||||||
|
std::wstring time_str;
|
||||||
|
std::getline(file, time_str);
|
||||||
|
_modification_time = std::stoull(time_str);
|
||||||
|
|
||||||
|
file.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
void AssetMetadata::Save() {
|
||||||
|
std::wofstream file;
|
||||||
|
file.open(_meta_path, std::ios::trunc);
|
||||||
|
file << version << std::endl;
|
||||||
|
file << guid_to_str(_guid) << std::endl;
|
||||||
|
file << _modification_time << std::endl;
|
||||||
|
//file << _importer->name();
|
||||||
|
file.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
Guid AssetMetadata::str_to_guid(const std::wstring& guid) {
|
||||||
|
Guid iid;
|
||||||
|
IIDFromString(guid.c_str(), (GUID*)&iid);
|
||||||
|
return iid;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::wstring AssetMetadata::guid_to_str(const Guid& guid) {
|
||||||
|
LPOLESTR guid_str = nullptr;
|
||||||
|
StringFromIID(*((const GUID*)&guid), &guid_str);
|
||||||
|
|
||||||
|
//Microsoft::WRL::Wrappers::HStringReference
|
||||||
|
|
||||||
|
std::wstring result(guid_str);
|
||||||
|
CoTaskMemFree(guid_str);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
const Guid& AssetMetadata::get_guid() const {
|
||||||
|
return _guid;
|
||||||
|
}
|
||||||
@@ -0,0 +1,29 @@
|
|||||||
|
#ifndef AssetMetadata_h__
|
||||||
|
#define AssetMetadata_h__
|
||||||
|
|
||||||
|
#include <filesystem>
|
||||||
|
#include <cstdint>
|
||||||
|
#include <memory>
|
||||||
|
#include "Guid.h"
|
||||||
|
#include "AssetImporter.h"
|
||||||
|
|
||||||
|
class AssetMetadata {
|
||||||
|
public:
|
||||||
|
typedef uint64_t file_time_t;
|
||||||
|
const std::wstring version = L"1.0";
|
||||||
|
|
||||||
|
AssetMetadata(const std::wstring& asset_path);
|
||||||
|
void Save();
|
||||||
|
void Load();
|
||||||
|
static std::wstring guid_to_str(const Guid& guid);
|
||||||
|
static Guid str_to_guid(const std::wstring& guid);
|
||||||
|
const Guid& get_guid() const;
|
||||||
|
private:
|
||||||
|
std::shared_ptr<AssetImporter> _importer;
|
||||||
|
void create();
|
||||||
|
std::wstring _asset_path;
|
||||||
|
std::wstring _meta_path;
|
||||||
|
file_time_t _modification_time;
|
||||||
|
Guid _guid;
|
||||||
|
};
|
||||||
|
#endif // AssetMetadata_h__
|
||||||
@@ -0,0 +1,44 @@
|
|||||||
|
#ifndef Bounds_h__
|
||||||
|
#define Bounds_h__
|
||||||
|
|
||||||
|
#include "lmath.h"
|
||||||
|
using namespace lm;
|
||||||
|
|
||||||
|
class Bounds {
|
||||||
|
public:
|
||||||
|
Bounds()
|
||||||
|
:_center(0.0f,0.0f,0.0f), _size(0.0f,0.0f,0.0f) {
|
||||||
|
|
||||||
|
}
|
||||||
|
Bounds(float3 center, float3 size)
|
||||||
|
:_center(center), _size(size)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
float3 GetSize() {
|
||||||
|
return _size;
|
||||||
|
}
|
||||||
|
float3 GetCenter() {
|
||||||
|
return _center;
|
||||||
|
}
|
||||||
|
void SetSize(const float3& size) {
|
||||||
|
_size = size;
|
||||||
|
}
|
||||||
|
void SetCenter(const float3& center) {
|
||||||
|
_center = center;
|
||||||
|
}
|
||||||
|
void Scale(float value) {
|
||||||
|
_size *= value;
|
||||||
|
}
|
||||||
|
float3 Minimum() const {
|
||||||
|
return _size * -0.5f + _center;
|
||||||
|
}
|
||||||
|
float3 Maximum() const {
|
||||||
|
return _size * 0.5f + _center;
|
||||||
|
}
|
||||||
|
private:
|
||||||
|
float3 _center;
|
||||||
|
float3 _size;
|
||||||
|
};
|
||||||
|
#endif // Bounds_h__
|
||||||
@@ -0,0 +1,31 @@
|
|||||||
|
#include "Camera.h"
|
||||||
|
#include "Transform.h"
|
||||||
|
#include "Mathf.h"
|
||||||
|
#include "Archive.h"
|
||||||
|
|
||||||
|
float4x4 Camera::worldToCameraMatrix() {
|
||||||
|
auto world = transform()->GetGlobalTransform();
|
||||||
|
|
||||||
|
//TODO: why not affine ?
|
||||||
|
world = inverse(world, false);
|
||||||
|
|
||||||
|
// auto test = lookatlh(transform()->GetGlobalPosition(), float3(0, 1, 1), float3(0, 1, 0));
|
||||||
|
|
||||||
|
return world;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void Camera::serialize(Archive& archive) {
|
||||||
|
Component::serialize(archive);
|
||||||
|
archive << nearClipPlane << farClipPlane << fov << aspect;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Camera::UpdateProjectionMatrix() {
|
||||||
|
_projection = matrix4x4Perspective(fov * Mathf::DegToRad(), aspect, nearClipPlane, farClipPlane);
|
||||||
|
}
|
||||||
|
|
||||||
|
float4x4 Camera::projectionMatrix() {
|
||||||
|
UpdateProjectionMatrix();
|
||||||
|
return _projection;
|
||||||
|
}
|
||||||
@@ -0,0 +1,29 @@
|
|||||||
|
#ifndef Camera_h__
|
||||||
|
#define Camera_h__
|
||||||
|
|
||||||
|
#include "ObjectsFactory.h"
|
||||||
|
#include "lmath.h"
|
||||||
|
#include "Component.h"
|
||||||
|
using namespace lm;
|
||||||
|
|
||||||
|
LOBJECT(Camera, Component)
|
||||||
|
public:
|
||||||
|
float nearClipPlane = 0.03f;
|
||||||
|
float farClipPlane = 100.0f;
|
||||||
|
float fov = 45.0f;
|
||||||
|
float aspect = 1.333333333f;
|
||||||
|
|
||||||
|
virtual void serialize(Archive& archive) override;
|
||||||
|
|
||||||
|
float4x4 worldToCameraMatrix();
|
||||||
|
float4x4 projectionMatrix();
|
||||||
|
void test() {
|
||||||
|
construct();
|
||||||
|
}
|
||||||
|
private:
|
||||||
|
float4x4 _projection;
|
||||||
|
void UpdateProjectionMatrix();
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef std::shared_ptr<Camera> CameraPtr;
|
||||||
|
#endif // Camera_h__
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
#include "Component.h"
|
||||||
|
#include "GameObject.h"
|
||||||
|
|
||||||
|
TransformPtr Component::transform() {
|
||||||
|
return gameObject->transform;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Component::serialize(Archive& archive) {
|
||||||
|
auto ptr = std::static_pointer_cast<Object>(gameObject);
|
||||||
|
archive << ptr;
|
||||||
|
|
||||||
|
if (archive.is_loading()) {
|
||||||
|
gameObject = std::static_pointer_cast<GameObject>(ptr);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
#ifndef Component_h__
|
||||||
|
#define Component_h__
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
#include "ObjectsFactory.h"
|
||||||
|
|
||||||
|
LOBJECT(Component, Object)
|
||||||
|
public:
|
||||||
|
GameObjectPtr gameObject;
|
||||||
|
TransformPtr transform();
|
||||||
|
virtual void tick(float deltaTime) {}
|
||||||
|
Component(){}
|
||||||
|
|
||||||
|
void serialize(Archive& archive) override;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#endif // Component_h__
|
||||||
@@ -0,0 +1,83 @@
|
|||||||
|
#ifndef D3d12DescriptorHeap_h__
|
||||||
|
#define D3d12DescriptorHeap_h__
|
||||||
|
|
||||||
|
#include <d3d12.h>
|
||||||
|
#include "d3d11_helper.h"
|
||||||
|
#include "FatalError.h"
|
||||||
|
#include <vector>
|
||||||
|
#include "ForwardListItem.h"
|
||||||
|
#include <wrl.h>
|
||||||
|
|
||||||
|
using namespace Microsoft::WRL;
|
||||||
|
|
||||||
|
class D3d12DescriptorHeapAllocator {
|
||||||
|
public:
|
||||||
|
//Assuming that heap is EMPTY!
|
||||||
|
D3d12DescriptorHeapAllocator(ComPtr<ID3D12DescriptorHeap> heap):_heap(heap)
|
||||||
|
{
|
||||||
|
_descriptor = heap->GetDesc();
|
||||||
|
_heapStartAddress = heap->GetCPUDescriptorHandleForHeapStart().ptr;
|
||||||
|
ID3D12DevicePtr device;
|
||||||
|
heap->GetDevice(IID_PPV_ARGS(&device));
|
||||||
|
_itemSize = device->GetDescriptorHandleIncrementSize(_descriptor.Type);
|
||||||
|
|
||||||
|
_items.resize(_descriptor.NumDescriptors);
|
||||||
|
//init free items list
|
||||||
|
for(size_t i = 0; i < _descriptor.NumDescriptors - 1; ++i){
|
||||||
|
_items[i].next = &_items[i + 1];
|
||||||
|
}
|
||||||
|
_items[_descriptor.NumDescriptors - 1].next = nullptr;
|
||||||
|
_listHead = &_items[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
D3D12_CPU_DESCRIPTOR_HANDLE alloc(){
|
||||||
|
if(_listHead == nullptr){
|
||||||
|
return {0};
|
||||||
|
}
|
||||||
|
auto allocatedId = getItemIndex(_listHead);
|
||||||
|
auto resultAddress = _heapStartAddress + (allocatedId * _itemSize);
|
||||||
|
_listHead = _listHead->next;
|
||||||
|
return{ resultAddress };
|
||||||
|
}
|
||||||
|
void free(D3D12_CPU_DESCRIPTOR_HANDLE handle){
|
||||||
|
auto itemId = getDescriptorId(handle);
|
||||||
|
if (itemId >= _items.size()) {
|
||||||
|
throw std::exception("Invalid handle");
|
||||||
|
}
|
||||||
|
auto freeItem = &_items[itemId];
|
||||||
|
freeItem->next = _listHead;
|
||||||
|
_listHead = freeItem;
|
||||||
|
|
||||||
|
}
|
||||||
|
ComPtr<ID3D12DescriptorHeap> getHeap()
|
||||||
|
{
|
||||||
|
return _heap;
|
||||||
|
}
|
||||||
|
size_t getItemSize() const
|
||||||
|
{
|
||||||
|
return _itemSize;
|
||||||
|
}
|
||||||
|
size_t getDescriptorId(D3D12_CPU_DESCRIPTOR_HANDLE handle) const
|
||||||
|
{
|
||||||
|
if (handle.ptr < _heapStartAddress) {
|
||||||
|
throw std::exception("Invalid handle");
|
||||||
|
}
|
||||||
|
return (handle.ptr - _heapStartAddress) / _itemSize;
|
||||||
|
}
|
||||||
|
size_t getDescriptorsCount() const
|
||||||
|
{
|
||||||
|
return _descriptor.NumDescriptors;
|
||||||
|
}
|
||||||
|
private:
|
||||||
|
size_t getItemIndex(const ForwardListItem* item) const noexcept{
|
||||||
|
return (item - &_items[0]);
|
||||||
|
}
|
||||||
|
ComPtr<ID3D12DescriptorHeap> _heap;
|
||||||
|
ForwardListItem* _listHead = nullptr;
|
||||||
|
std::vector<ForwardListItem> _items;
|
||||||
|
D3D12_DESCRIPTOR_HEAP_DESC _descriptor;
|
||||||
|
size_t _itemSize;
|
||||||
|
size_t _heapStartAddress;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // D3d12DescriptorHeap_h__
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,88 @@
|
|||||||
|
//--------------------------------------------------------------------------------------
|
||||||
|
// File: DDSTextureLoader12.h
|
||||||
|
//
|
||||||
|
// Functions for loading a DDS texture and creating a Direct3D 12 runtime resource for it
|
||||||
|
//
|
||||||
|
// Note these functions are useful as a light-weight runtime loader for DDS files. For
|
||||||
|
// a full-featured DDS file reader, writer, and texture processing pipeline see
|
||||||
|
// the 'Texconv' sample and the 'DirectXTex' library.
|
||||||
|
//
|
||||||
|
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
|
||||||
|
// ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
|
||||||
|
// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
|
||||||
|
// PARTICULAR PURPOSE.
|
||||||
|
//
|
||||||
|
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||||
|
//
|
||||||
|
// http://go.microsoft.com/fwlink/?LinkId=248926
|
||||||
|
// http://go.microsoft.com/fwlink/?LinkID=615561
|
||||||
|
//--------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <d3d12.h>
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
#include <vector>
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
|
||||||
|
namespace DirectX
|
||||||
|
{
|
||||||
|
enum DDS_ALPHA_MODE
|
||||||
|
{
|
||||||
|
DDS_ALPHA_MODE_UNKNOWN = 0,
|
||||||
|
DDS_ALPHA_MODE_STRAIGHT = 1,
|
||||||
|
DDS_ALPHA_MODE_PREMULTIPLIED = 2,
|
||||||
|
DDS_ALPHA_MODE_OPAQUE = 3,
|
||||||
|
DDS_ALPHA_MODE_CUSTOM = 4,
|
||||||
|
};
|
||||||
|
|
||||||
|
// Standard version
|
||||||
|
HRESULT __cdecl LoadDDSTextureFromMemory(
|
||||||
|
_In_ ID3D12Device* d3dDevice,
|
||||||
|
_In_reads_bytes_(ddsDataSize) const uint8_t* ddsData,
|
||||||
|
size_t ddsDataSize,
|
||||||
|
_Outptr_ ID3D12Resource** texture,
|
||||||
|
std::vector<D3D12_SUBRESOURCE_DATA>& subresources,
|
||||||
|
size_t maxsize = 0,
|
||||||
|
_Out_opt_ DDS_ALPHA_MODE* alphaMode = nullptr,
|
||||||
|
_Out_opt_ bool* isCubeMap = nullptr);
|
||||||
|
|
||||||
|
HRESULT __cdecl LoadDDSTextureFromFile(
|
||||||
|
_In_ ID3D12Device* d3dDevice,
|
||||||
|
_In_z_ const wchar_t* szFileName,
|
||||||
|
_Outptr_ ID3D12Resource** texture,
|
||||||
|
std::unique_ptr<uint8_t[]>& ddsData,
|
||||||
|
std::vector<D3D12_SUBRESOURCE_DATA>& subresources,
|
||||||
|
size_t maxsize = 0,
|
||||||
|
_Out_opt_ DDS_ALPHA_MODE* alphaMode = nullptr,
|
||||||
|
_Out_opt_ bool* isCubeMap = nullptr);
|
||||||
|
|
||||||
|
// Extended version
|
||||||
|
HRESULT __cdecl LoadDDSTextureFromMemoryEx(
|
||||||
|
_In_ ID3D12Device* d3dDevice,
|
||||||
|
_In_reads_bytes_(ddsDataSize) const uint8_t* ddsData,
|
||||||
|
size_t ddsDataSize,
|
||||||
|
size_t maxsize,
|
||||||
|
D3D12_RESOURCE_FLAGS flags,
|
||||||
|
bool forceSRGB,
|
||||||
|
bool reserveFullMipChain,
|
||||||
|
_Outptr_ ID3D12Resource** texture,
|
||||||
|
std::vector<D3D12_SUBRESOURCE_DATA>& subresources,
|
||||||
|
_Out_opt_ DDS_ALPHA_MODE* alphaMode = nullptr,
|
||||||
|
_Out_opt_ bool* isCubeMap = nullptr);
|
||||||
|
|
||||||
|
HRESULT __cdecl LoadDDSTextureFromFileEx(
|
||||||
|
_In_ ID3D12Device* d3dDevice,
|
||||||
|
_In_z_ const wchar_t* szFileName,
|
||||||
|
size_t maxsize,
|
||||||
|
D3D12_RESOURCE_FLAGS flags,
|
||||||
|
bool forceSRGB,
|
||||||
|
bool reserveFullMipChain,
|
||||||
|
_Outptr_ ID3D12Resource** texture,
|
||||||
|
std::unique_ptr<uint8_t[]>& ddsData,
|
||||||
|
std::vector<D3D12_SUBRESOURCE_DATA>& subresources,
|
||||||
|
_Out_opt_ DDS_ALPHA_MODE* alphaMode = nullptr,
|
||||||
|
_Out_opt_ bool* isCubeMap = nullptr);
|
||||||
|
}
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
#ifndef FatalError_h__
|
||||||
|
#define FatalError_h__
|
||||||
|
|
||||||
|
#include <Windows.h>
|
||||||
|
|
||||||
|
inline void FatalError(const TCHAR* message) {
|
||||||
|
int b1 = 12750;
|
||||||
|
int b2 = 4750;
|
||||||
|
int len = 80;
|
||||||
|
|
||||||
|
for(int i = 0; i < 2; ++i) {
|
||||||
|
Beep(b1, len);
|
||||||
|
Beep(b2, len);
|
||||||
|
}
|
||||||
|
|
||||||
|
MessageBox(NULL, message, TEXT("Error"), MB_OK);
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
|
#endif // FatalError_h__
|
||||||
@@ -0,0 +1,46 @@
|
|||||||
|
#ifndef File_h__
|
||||||
|
#define File_h__
|
||||||
|
|
||||||
|
#include <fstream>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
uint32_t FileSize(const std::wstring& path) {
|
||||||
|
std::ifstream file(path, std::ios_base::binary);
|
||||||
|
if (!file.good()) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
std::streampos current_position = file.tellg();
|
||||||
|
file.seekg(0, std::ios::end);
|
||||||
|
std::streampos ending_position = file.tellg();
|
||||||
|
file.seekg(current_position);
|
||||||
|
file.close();
|
||||||
|
return (uint32_t)(ending_position - current_position);
|
||||||
|
}
|
||||||
|
|
||||||
|
void FileReadAllText(const std::wstring& path, std::string& result) {
|
||||||
|
auto size = FileSize(path);
|
||||||
|
if (size == 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::ifstream file(path, std::ios::in);
|
||||||
|
result.reserve(size);
|
||||||
|
result.assign(std::istreambuf_iterator<char>(file), std::istreambuf_iterator<char>());
|
||||||
|
file.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
void FileReadAllBytes(const std::wstring& path, std::vector<char>& result) {
|
||||||
|
auto size = FileSize(path);
|
||||||
|
if (size == 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::ifstream file(path, std::ios::in | std::ios::binary);
|
||||||
|
result.reserve(size);
|
||||||
|
result.assign(std::istreambuf_iterator<char>(file), std::istreambuf_iterator<char>());
|
||||||
|
file.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#endif // File_h__
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
#ifndef Filesystem_h__
|
||||||
|
#define Filesystem_h__
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
class Filesystem {
|
||||||
|
public:
|
||||||
|
//static std::shared_ptr<Filesystem> Create(const std::string& assetsFolder);
|
||||||
|
|
||||||
|
private:
|
||||||
|
//Filesystem();
|
||||||
|
};
|
||||||
|
#endif // Filesystem_h__
|
||||||
@@ -0,0 +1,35 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
#include <memory>
|
||||||
|
#include "lmath.h"
|
||||||
|
|
||||||
|
class GameObject;
|
||||||
|
typedef std::shared_ptr<GameObject> GameObjectPtr;
|
||||||
|
|
||||||
|
class Component;
|
||||||
|
typedef std::shared_ptr<Component> ComponentPtr;
|
||||||
|
|
||||||
|
class Scene;
|
||||||
|
typedef std::shared_ptr<Scene> ScenePtr;
|
||||||
|
|
||||||
|
class Transform;
|
||||||
|
typedef std::shared_ptr<Transform> TransformPtr;
|
||||||
|
|
||||||
|
class Shader;
|
||||||
|
typedef std::shared_ptr<Shader> ShaderPtr;
|
||||||
|
|
||||||
|
class Mesh;
|
||||||
|
typedef std::shared_ptr<Mesh> MeshPtr;
|
||||||
|
|
||||||
|
class Material;
|
||||||
|
typedef std::shared_ptr<Material> MaterialPtr;
|
||||||
|
|
||||||
|
class Mouse;
|
||||||
|
typedef std::shared_ptr<Mouse> MousePtr;
|
||||||
|
|
||||||
|
class Keyboard;
|
||||||
|
typedef std::shared_ptr<Keyboard> KeyboardPtr;
|
||||||
|
|
||||||
|
class Texture;
|
||||||
|
typedef std::shared_ptr<Texture> TexturePtr;
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
#ifndef ForwardListItem_h__
|
||||||
|
#define ForwardListItem_h__
|
||||||
|
|
||||||
|
class ForwardListItem{
|
||||||
|
public:
|
||||||
|
ForwardListItem* next;
|
||||||
|
};
|
||||||
|
#endif // ForwardListItem_h__
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
|
||||||
|
#include "Transform.h"
|
||||||
|
#include "LEngine.h"
|
||||||
|
#include "Component.h"
|
||||||
|
#include "GameObject.h"
|
||||||
|
|
||||||
|
void GameObject::tick(float deltaTime) {
|
||||||
|
for (auto c : components) {
|
||||||
|
c->tick(deltaTime);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void GameObject::construct2() {
|
||||||
|
Object::construct();
|
||||||
|
auto this_ptr = std::static_pointer_cast<GameObject>(shared_from_this());
|
||||||
|
LEngine::Instance()->GetActiveScene()->objects.push_back(this_ptr);
|
||||||
|
this_ptr->transform = this_ptr->AddComponent<Transform>();
|
||||||
|
}
|
||||||
@@ -0,0 +1,94 @@
|
|||||||
|
#ifndef GameObject___h__
|
||||||
|
#define GameObject___h__
|
||||||
|
|
||||||
|
#include "ForwardDeclarations.h"
|
||||||
|
#include <memory>
|
||||||
|
#include <vector>
|
||||||
|
#include <typeinfo>
|
||||||
|
#include "ObjectsFactory.h"
|
||||||
|
#include "OutputArchive.h"
|
||||||
|
#include "Transform.h"
|
||||||
|
|
||||||
|
LOBJECT(GameObject, Object)
|
||||||
|
public:
|
||||||
|
TransformPtr transform;
|
||||||
|
|
||||||
|
void tick(float deltaTime);
|
||||||
|
|
||||||
|
virtual void serialize(Archive& archive) override {
|
||||||
|
Object::serialize(archive);
|
||||||
|
|
||||||
|
if (archive.is_loading()) {
|
||||||
|
components.clear();
|
||||||
|
transform = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
Archive::size_type cnt = components.size();
|
||||||
|
archive << cnt;
|
||||||
|
|
||||||
|
if (archive.is_loading()) {
|
||||||
|
for (Archive::size_type i = 0; i < cnt; ++i) {
|
||||||
|
std::shared_ptr<Object> obj;
|
||||||
|
archive << obj;
|
||||||
|
components.push_back(std::static_pointer_cast<Component>(obj));
|
||||||
|
|
||||||
|
auto tp = std::dynamic_pointer_cast<Transform>(obj);
|
||||||
|
if (tp != nullptr) {
|
||||||
|
transform = tp;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
for (auto component : components) {
|
||||||
|
archive << std::static_pointer_cast<Object>(component);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::shared_ptr<GameObject> as_game_object() {
|
||||||
|
return std::static_pointer_cast<GameObject>(shared_from_this());
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
std::shared_ptr<T> AddComponent() {
|
||||||
|
auto component = T::create();
|
||||||
|
component->gameObject = as_game_object();
|
||||||
|
components.push_back(component);
|
||||||
|
return component;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
std::shared_ptr<T> GetComponent() {
|
||||||
|
for (auto c : components) {
|
||||||
|
auto tmp = std::dynamic_pointer_cast<T>(c);
|
||||||
|
if (tmp != nullptr) {
|
||||||
|
return tmp;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
std::vector<std::shared_ptr<T>> GetComponents() {
|
||||||
|
std::vector<std::shared_ptr<T>> result;
|
||||||
|
for (auto c : components) {
|
||||||
|
auto tmp = std::dynamic_pointer_cast<T>(c);
|
||||||
|
if (tmp != nullptr) {
|
||||||
|
result.push_back(tmp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
void construct() override {
|
||||||
|
construct2();
|
||||||
|
}
|
||||||
|
void construct2();
|
||||||
|
|
||||||
|
private:
|
||||||
|
GameObject() {}
|
||||||
|
std::vector<ComponentPtr> components;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#endif // GameObject___h__
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
#ifndef GizmoVertex_h__
|
||||||
|
#define GizmoVertex_h__
|
||||||
|
|
||||||
|
#include "lmath.h"
|
||||||
|
|
||||||
|
using namespace lm;
|
||||||
|
|
||||||
|
struct GizmoVertex {
|
||||||
|
float4 position;
|
||||||
|
float4 color;
|
||||||
|
|
||||||
|
GizmoVertex(float4 _position, float4 _color)
|
||||||
|
:position(_position), color(_color)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
GizmoVertex(float3 _position, float4 _color)
|
||||||
|
:position(_position.x(), _position.y(), _position.z(), 1.0f), color(_color)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
};
|
||||||
|
#endif // GizmoVertex_h__
|
||||||
@@ -0,0 +1,131 @@
|
|||||||
|
#include "Gizmos.h"
|
||||||
|
#include "GameObject.h"
|
||||||
|
#include "LEngine.h"
|
||||||
|
#include "d3d11_helper.h"
|
||||||
|
#include "LEngine.h"
|
||||||
|
|
||||||
|
Gizmos::Gizmos()
|
||||||
|
:_color(0.0f, 1.0f, 0.0f, 1.0f)
|
||||||
|
{
|
||||||
|
_matrix = float4x4::identity();
|
||||||
|
}
|
||||||
|
void Gizmos::SetMatrix(const float4x4& matrix) {
|
||||||
|
_matrix = matrix;
|
||||||
|
}
|
||||||
|
float4x4 Gizmos::GetMatrix() {
|
||||||
|
return _matrix;
|
||||||
|
}
|
||||||
|
void Gizmos::DrawBounds(const Bounds& bounds) {
|
||||||
|
auto b = bounds;
|
||||||
|
b.Scale(1.01f);
|
||||||
|
auto bMin = b.Minimum();
|
||||||
|
auto bMax = b.Maximum();
|
||||||
|
|
||||||
|
DrawLine(float3(bMin.x(), bMax.y(), bMax.z()), float3(bMax.x(), bMax.y(), bMax.z()));
|
||||||
|
DrawLine(float3(bMin.x(), bMax.y(), bMin.z()), float3(bMax.x(), bMax.y(), bMin.z()));
|
||||||
|
DrawLine(float3(bMin.x(), bMax.y(), bMax.z()), float3(bMin.x(), bMax.y(), bMin.z()));
|
||||||
|
DrawLine(float3(bMax.x(), bMax.y(), bMax.z()), float3(bMax.x(), bMax.y(), bMin.z()));
|
||||||
|
|
||||||
|
DrawLine(float3(bMin.x(), bMin.y(), bMax.z()), float3(bMax.x(), bMin.y(), bMax.z()));
|
||||||
|
DrawLine(float3(bMin.x(), bMin.y(), bMin.z()), float3(bMax.x(), bMin.y(), bMin.z()));
|
||||||
|
DrawLine(float3(bMin.x(), bMin.y(), bMax.z()), float3(bMin.x(), bMin.y(), bMin.z()));
|
||||||
|
DrawLine(float3(bMax.x(), bMin.y(), bMax.z()), float3(bMax.x(), bMin.y(), bMin.z()));
|
||||||
|
|
||||||
|
DrawLine(float3(bMin.x(), bMin.y(), bMin.z()), float3(bMin.x(), bMax.y(), bMin.z()));
|
||||||
|
DrawLine(float3(bMax.x(), bMin.y(), bMin.z()), float3(bMax.x(), bMax.y(), bMin.z()));
|
||||||
|
|
||||||
|
DrawLine(float3(bMin.x(), bMin.y(), bMax.z()), float3(bMin.x(), bMax.y(), bMax.z()));
|
||||||
|
DrawLine(float3(bMax.x(), bMin.y(), bMax.z()), float3(bMax.x(), bMax.y(), bMax.z()));
|
||||||
|
|
||||||
|
}
|
||||||
|
void Gizmos::Init() {
|
||||||
|
/*_backMaterial = Material::Create(Shader::Create(L"shaders/gizmos.fx"), "gizmo_back");
|
||||||
|
|
||||||
|
_frontMaterial = Material::Create(_backMaterial->GetShader(), "gizmo_front");
|
||||||
|
|
||||||
|
_backMaterial->GetParametersBlock().SetValue("alphaMul", 0.2f);
|
||||||
|
_frontMaterial->GetParametersBlock().SetValue("alphaMul", 1.0f);
|
||||||
|
|
||||||
|
D3D11_INPUT_ELEMENT_DESC ied[] = {
|
||||||
|
{ "POSITION", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 },
|
||||||
|
{ "COLOR", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, 16, D3D11_INPUT_PER_VERTEX_DATA, 0 },
|
||||||
|
};
|
||||||
|
|
||||||
|
auto vs = _backMaterial->GetShader()->GetShader(ShaderType::Vs);
|
||||||
|
auto device = LEngine::Instance()->GetRenderer()->GetDevice();
|
||||||
|
auto hr = device->CreateInputLayout(ied, 2, vs->blob->GetBufferPointer(), vs->blob->GetBufferSize(), &_inputLayout);
|
||||||
|
|
||||||
|
D3D11_DEPTH_STENCIL_DESC desc;
|
||||||
|
d3d11_helper::DefaultDepthStencilDesc(desc);
|
||||||
|
hr = device->CreateDepthStencilState(&desc, &_frontLineDepthState);
|
||||||
|
desc.DepthFunc = D3D11_COMPARISON_GREATER;
|
||||||
|
hr = device->CreateDepthStencilState(&desc, &_backLineDepthState);*/
|
||||||
|
}
|
||||||
|
void Gizmos::DrawLine(const float3& from, const float3& to) {
|
||||||
|
/*_vertices.push_back(GizmoVertex(lm::mul(_matrix, from), _color));
|
||||||
|
_vertices.push_back(GizmoVertex(lm::mul(_matrix, to), _color));*/
|
||||||
|
}
|
||||||
|
void Gizmos::DrawAll(CameraPtr camera) {
|
||||||
|
/*auto renderer = LEngine::Instance()->GetRenderer();
|
||||||
|
|
||||||
|
renderer->GetImmediateContext()->OMSetDepthStencilState(_frontLineDepthState, 0);
|
||||||
|
DrawImpl(camera, _frontMaterial);
|
||||||
|
renderer->GetImmediateContext()->OMSetDepthStencilState(_backLineDepthState, 0);
|
||||||
|
DrawImpl(camera, _backMaterial);
|
||||||
|
renderer->GetImmediateContext()->OMSetDepthStencilState(_frontLineDepthState, 0);*/
|
||||||
|
}
|
||||||
|
void Gizmos::DrawImpl(CameraPtr camera, MaterialPtr material) {
|
||||||
|
/*if (_vertices.size() < 2) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
//set system variables
|
||||||
|
auto& params = material->GetParametersBlock();
|
||||||
|
float4x4 matrix = float4x4::identity();
|
||||||
|
params.SetValue("mWorld", matrix);
|
||||||
|
params.SetValue("mView", camera->worldToCameraMatrix());
|
||||||
|
params.SetValue("mProjection", camera->projectionMatrix());
|
||||||
|
|
||||||
|
auto renderer = LEngine::Instance()->GetRenderer();
|
||||||
|
|
||||||
|
material->Apply(renderer->GetImmediateContext());
|
||||||
|
|
||||||
|
ID3D11Buffer* vb[1] = { _vertexBuffer };
|
||||||
|
UINT stride = sizeof(GizmoVertex);
|
||||||
|
UINT offset = 0;
|
||||||
|
|
||||||
|
renderer->GetImmediateContext()->IASetInputLayout(_inputLayout);
|
||||||
|
renderer->GetImmediateContext()->IASetVertexBuffers(0, 1, vb, &stride, &offset);
|
||||||
|
renderer->GetImmediateContext()->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_LINELIST);
|
||||||
|
renderer->GetImmediateContext()->Draw(_vertices.size(), 0);*/
|
||||||
|
}
|
||||||
|
void Gizmos::Clear() {
|
||||||
|
/*_vertices.clear();
|
||||||
|
_matrix = float4x4::identity();*/
|
||||||
|
}
|
||||||
|
void Gizmos::PrepareRender() {
|
||||||
|
/*_vertexBuffer = nullptr;
|
||||||
|
|
||||||
|
if (_vertices.size() < 2) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
//vertex buffer
|
||||||
|
D3D11_BUFFER_DESC desc = { 0 };
|
||||||
|
desc.Usage = D3D11_USAGE_DEFAULT;
|
||||||
|
desc.ByteWidth = sizeof(_vertices[0])* _vertices.size();
|
||||||
|
desc.BindFlags = D3D11_BIND_VERTEX_BUFFER;
|
||||||
|
desc.CPUAccessFlags = 0;
|
||||||
|
desc.MiscFlags = 0;
|
||||||
|
|
||||||
|
D3D11_SUBRESOURCE_DATA data;
|
||||||
|
data.pSysMem = &_vertices[0];
|
||||||
|
data.SysMemPitch = 0;
|
||||||
|
|
||||||
|
_vertexBuffer = nullptr;
|
||||||
|
LEngine::Instance()->GetRenderer()->GetDevice()->CreateBuffer(&desc, &data, &_vertexBuffer);*/
|
||||||
|
}
|
||||||
|
float4 Gizmos::GetColor() {
|
||||||
|
return _color;
|
||||||
|
}
|
||||||
|
void Gizmos::SetColor(float4 color) {
|
||||||
|
_color = color;
|
||||||
|
}
|
||||||
@@ -0,0 +1,41 @@
|
|||||||
|
#ifndef Gizmos_h__
|
||||||
|
#define Gizmos_h__
|
||||||
|
|
||||||
|
#include "GizmoVertex.h"
|
||||||
|
#include <vector>
|
||||||
|
#include "Material.h"
|
||||||
|
#include "Shader.h"
|
||||||
|
#include "d3d11_types.h"
|
||||||
|
|
||||||
|
#include "lmath.h"
|
||||||
|
#include "Camera.h"
|
||||||
|
#include "Bounds.h"
|
||||||
|
|
||||||
|
using namespace lm;
|
||||||
|
|
||||||
|
class Gizmos {
|
||||||
|
public:
|
||||||
|
Gizmos();
|
||||||
|
void Init();
|
||||||
|
void DrawLine(const float3& from, const float3& to);
|
||||||
|
void DrawBounds(const Bounds& bounds);
|
||||||
|
void DrawAll(CameraPtr camera);
|
||||||
|
void Clear();
|
||||||
|
void PrepareRender();
|
||||||
|
float4 GetColor();
|
||||||
|
void SetColor(float4 color);
|
||||||
|
void SetMatrix(const float4x4& matrix);
|
||||||
|
float4x4 GetMatrix();
|
||||||
|
private:
|
||||||
|
void DrawImpl(CameraPtr camera, MaterialPtr material);
|
||||||
|
ID3D11InputLayoutPtr _inputLayout;
|
||||||
|
ID3D11BufferPtr _vertexBuffer;
|
||||||
|
ID3D11DepthStencilStatePtr _backLineDepthState;
|
||||||
|
ID3D11DepthStencilStatePtr _frontLineDepthState;
|
||||||
|
MaterialPtr _backMaterial;
|
||||||
|
MaterialPtr _frontMaterial;
|
||||||
|
float4 _color;
|
||||||
|
float4x4 _matrix;
|
||||||
|
std::vector<GizmoVertex> _vertices;
|
||||||
|
};
|
||||||
|
#endif // Gizmos_h__
|
||||||
@@ -0,0 +1,43 @@
|
|||||||
|
#ifndef Guid_h__
|
||||||
|
#define Guid_h__
|
||||||
|
|
||||||
|
#include <array>
|
||||||
|
#include <cstdint>
|
||||||
|
|
||||||
|
struct Guid {
|
||||||
|
union {
|
||||||
|
std::array<uint8_t, 16> data;
|
||||||
|
std::array<uint32_t, 4> datai;
|
||||||
|
};
|
||||||
|
|
||||||
|
Guid() :datai{ 0,0,0,0 } {
|
||||||
|
|
||||||
|
}
|
||||||
|
Guid(uint32_t i0, uint32_t i1, uint32_t i2, uint32_t i3) : datai{ i0,i1,i2,i3 } {
|
||||||
|
|
||||||
|
}
|
||||||
|
Guid(const std::array<uint32_t, 4>& data_i) : datai(data_i) {
|
||||||
|
|
||||||
|
}
|
||||||
|
Guid(const std::array<uint8_t, 16>& data) : data(data) {
|
||||||
|
|
||||||
|
}
|
||||||
|
Guid(const Guid& guid) : data(guid.data) {
|
||||||
|
|
||||||
|
}
|
||||||
|
Guid& operator =(const Guid& right) {
|
||||||
|
data = right.data;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
bool operator ==(const Guid& right) const {
|
||||||
|
return std::equal(data.begin(), data.end(), right.data.begin());
|
||||||
|
}
|
||||||
|
bool operator !=(const Guid& right) const {
|
||||||
|
return !std::equal(data.begin(), data.end(), right.data.begin());
|
||||||
|
}
|
||||||
|
bool IsZero() const {
|
||||||
|
return (datai[0] == 0) && (datai[1] == 0) && (datai[2] == 0) && (datai[3] == 0);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // Guid_h__
|
||||||
@@ -0,0 +1,49 @@
|
|||||||
|
#ifndef InputArchive_h__
|
||||||
|
#define InputArchive_h__
|
||||||
|
|
||||||
|
|
||||||
|
#include "Archive.h"
|
||||||
|
#include "Object.h"
|
||||||
|
#include <vector>
|
||||||
|
#include <cstdint>
|
||||||
|
#include <algorithm>
|
||||||
|
#include <fstream>
|
||||||
|
|
||||||
|
class InputArchive : public Archive {
|
||||||
|
public:
|
||||||
|
InputArchive(std::shared_ptr<std::istream> stream)
|
||||||
|
:_stream(stream) {
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual bool is_loading() const override {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void serialize(void* data, size_t size) override {
|
||||||
|
|
||||||
|
_stream->read(reinterpret_cast<char*>(data), size);
|
||||||
|
if(!_stream)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
size_type get_offset() const override
|
||||||
|
{
|
||||||
|
return _stream->tellg();
|
||||||
|
}
|
||||||
|
|
||||||
|
void set_offset(size_type offset) override {
|
||||||
|
_stream->seekg(offset, std::ios::beg);
|
||||||
|
}
|
||||||
|
|
||||||
|
~InputArchive() {}
|
||||||
|
|
||||||
|
std::shared_ptr<std::istream> GetStream(){
|
||||||
|
return _stream;
|
||||||
|
}
|
||||||
|
private:
|
||||||
|
std::shared_ptr<std::istream> _stream;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // InputArchive_h__
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
#include "LEngine.h"
|
||||||
|
#include "AssetManager.h"
|
||||||
|
|
||||||
|
std::shared_ptr<LEngine> LEngine::_instance = nullptr;
|
||||||
|
|
||||||
|
std::shared_ptr<LEngine> LEngine::Instance() {
|
||||||
|
if (_instance == nullptr) {
|
||||||
|
_instance = std::shared_ptr<LEngine>(new LEngine());
|
||||||
|
}
|
||||||
|
return _instance;
|
||||||
|
}
|
||||||
|
|
||||||
|
ScenePtr LEngine::GetActiveScene() {
|
||||||
|
return _activeScene;
|
||||||
|
}
|
||||||
|
|
||||||
|
void LEngine::Init(const std::wstring& assetsPath) {
|
||||||
|
AssetManager::Instance()->SetAssetsFolder(assetsPath);
|
||||||
|
_renderer->Init();
|
||||||
|
}
|
||||||
|
|
||||||
|
void LEngine::LoadScene(const std::string& path) {
|
||||||
|
_activeScene = nullptr;
|
||||||
|
_activeScene = std::make_shared<Scene>();
|
||||||
|
_activeScene->SetName("New scene");
|
||||||
|
}
|
||||||
@@ -0,0 +1,37 @@
|
|||||||
|
#ifndef Application_h__
|
||||||
|
#define Application_h__
|
||||||
|
|
||||||
|
#include "Scene.h"
|
||||||
|
#include "ForwardDeclarations.h"
|
||||||
|
#include <string>
|
||||||
|
#include "Renderer.h"
|
||||||
|
#include "RenderOutput.h"
|
||||||
|
|
||||||
|
class LEngine {
|
||||||
|
public:
|
||||||
|
static std::shared_ptr<LEngine> Instance();
|
||||||
|
friend class Scene;
|
||||||
|
ScenePtr GetActiveScene();
|
||||||
|
void LoadScene(const std::string& path);
|
||||||
|
void Init(const std::wstring& assetsPath);
|
||||||
|
RendererPtr& GetRenderer() {
|
||||||
|
return _renderer;
|
||||||
|
}
|
||||||
|
void AddOutput(RenderOutputPtr output) {
|
||||||
|
_outputs.push_back(output);
|
||||||
|
}
|
||||||
|
std::vector<RenderOutputPtr> GetOutputs() {
|
||||||
|
return _outputs;
|
||||||
|
}
|
||||||
|
private:
|
||||||
|
LEngine()
|
||||||
|
{
|
||||||
|
_renderer = std::make_shared<Renderer>();
|
||||||
|
}
|
||||||
|
RendererPtr _renderer;
|
||||||
|
ScenePtr _activeScene;
|
||||||
|
static std::shared_ptr<LEngine> _instance;
|
||||||
|
std::vector<RenderOutputPtr> _outputs;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // Application_h__
|
||||||
@@ -0,0 +1,185 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
|
<ItemGroup Label="ProjectConfigurations">
|
||||||
|
<ProjectConfiguration Include="Debug|Win32">
|
||||||
|
<Configuration>Debug</Configuration>
|
||||||
|
<Platform>Win32</Platform>
|
||||||
|
</ProjectConfiguration>
|
||||||
|
<ProjectConfiguration Include="Release|Win32">
|
||||||
|
<Configuration>Release</Configuration>
|
||||||
|
<Platform>Win32</Platform>
|
||||||
|
</ProjectConfiguration>
|
||||||
|
</ItemGroup>
|
||||||
|
<PropertyGroup Label="Globals">
|
||||||
|
<ProjectGuid>{91440EE0-7471-4D73-A6FD-3DCB64E56C13}</ProjectGuid>
|
||||||
|
<Keyword>Win32Proj</Keyword>
|
||||||
|
<RootNamespace>StereoTest</RootNamespace>
|
||||||
|
<WindowsTargetPlatformVersion>10.0.14393.0</WindowsTargetPlatformVersion>
|
||||||
|
</PropertyGroup>
|
||||||
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||||
|
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||||
|
<UseDebugLibraries>true</UseDebugLibraries>
|
||||||
|
<PlatformToolset>v141</PlatformToolset>
|
||||||
|
<CharacterSet>Unicode</CharacterSet>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||||
|
<ConfigurationType>Application</ConfigurationType>
|
||||||
|
<UseDebugLibraries>false</UseDebugLibraries>
|
||||||
|
<PlatformToolset>v140_clang_3_7</PlatformToolset>
|
||||||
|
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||||
|
<CharacterSet>Unicode</CharacterSet>
|
||||||
|
</PropertyGroup>
|
||||||
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||||
|
<ImportGroup Label="ExtensionSettings">
|
||||||
|
</ImportGroup>
|
||||||
|
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||||
|
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||||
|
</ImportGroup>
|
||||||
|
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||||
|
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||||
|
</ImportGroup>
|
||||||
|
<PropertyGroup Label="UserMacros" />
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||||
|
<LinkIncremental>true</LinkIncremental>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||||
|
<LinkIncremental>false</LinkIncremental>
|
||||||
|
</PropertyGroup>
|
||||||
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||||
|
<ClCompile>
|
||||||
|
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||||
|
<WarningLevel>Level3</WarningLevel>
|
||||||
|
<Optimization>Disabled</Optimization>
|
||||||
|
<PreprocessorDefinitions>NMATH_SWIZZLE_ENABLE;WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
|
<SDLCheck>true</SDLCheck>
|
||||||
|
<AdditionalIncludeDirectories>D:\nettlemath;D:\nativelinq\nativelinq\nativelinq;D:\github\lframework;D:\lmath\lmath;D:\DirectXTex\DirectXTex</AdditionalIncludeDirectories>
|
||||||
|
<MultiProcessorCompilation>true</MultiProcessorCompilation>
|
||||||
|
<MinimalRebuild>false</MinimalRebuild>
|
||||||
|
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
|
||||||
|
</ClCompile>
|
||||||
|
<Link>
|
||||||
|
<SubSystem>Windows</SubSystem>
|
||||||
|
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||||
|
<AdditionalLibraryDirectories>
|
||||||
|
</AdditionalLibraryDirectories>
|
||||||
|
</Link>
|
||||||
|
<Lib>
|
||||||
|
<AdditionalLibraryDirectories>D:\github\lframework\Debug;D:\DirectXTex\DirectXTex\Bin\Desktop_2015_Win10\Win32\Debug</AdditionalLibraryDirectories>
|
||||||
|
</Lib>
|
||||||
|
</ItemDefinitionGroup>
|
||||||
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||||
|
<ClCompile>
|
||||||
|
<WarningLevel>Level3</WarningLevel>
|
||||||
|
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||||
|
<Optimization>MaxSpeed</Optimization>
|
||||||
|
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||||
|
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||||
|
<PreprocessorDefinitions>NMATH_SWIZZLE_ENABLE;WIN32;NDEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
|
<SDLCheck>true</SDLCheck>
|
||||||
|
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||||
|
<AdditionalIncludeDirectories>D:\DirectXTex\DirectXTex;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||||
|
</ClCompile>
|
||||||
|
<Link>
|
||||||
|
<SubSystem>Windows</SubSystem>
|
||||||
|
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||||
|
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||||
|
<OptimizeReferences>true</OptimizeReferences>
|
||||||
|
</Link>
|
||||||
|
</ItemDefinitionGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ClCompile Include="Archive.cpp" />
|
||||||
|
<ClCompile Include="AssetDatabase.cpp" />
|
||||||
|
<ClCompile Include="AssetManager.cpp" />
|
||||||
|
<ClCompile Include="AssetMetadata.cpp" />
|
||||||
|
<ClCompile Include="DDSTextureLoader12.cpp" />
|
||||||
|
<ClCompile Include="GameObject.cpp" />
|
||||||
|
<ClCompile Include="ObjectsFactory.cpp" />
|
||||||
|
<ClCompile Include="LEngine.cpp" />
|
||||||
|
<ClCompile Include="Camera.cpp" />
|
||||||
|
<ClCompile Include="Component.cpp" />
|
||||||
|
<ClCompile Include="Material.cpp" />
|
||||||
|
<ClCompile Include="Mesh.cpp" />
|
||||||
|
<ClCompile Include="MeshGenerator.cpp" />
|
||||||
|
<ClCompile Include="MeshRenderer.cpp" />
|
||||||
|
<ClCompile Include="Object.cpp" />
|
||||||
|
<ClCompile Include="Renderer.cpp" />
|
||||||
|
<ClCompile Include="RenderTargetOutput.cpp" />
|
||||||
|
<ClCompile Include="Scene.cpp" />
|
||||||
|
<ClCompile Include="SceneRenderer.cpp" />
|
||||||
|
<ClCompile Include="Shader.cpp" />
|
||||||
|
<ClCompile Include="Gizmos.cpp" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ClInclude Include="Archive.h" />
|
||||||
|
<ClInclude Include="Asset.h" />
|
||||||
|
<ClInclude Include="AssetDatabase.h" />
|
||||||
|
<ClInclude Include="AssetFile.h" />
|
||||||
|
<ClInclude Include="AssetImporter.h" />
|
||||||
|
<ClInclude Include="AssetMetadata.h" />
|
||||||
|
<ClInclude Include="D3d12DescriptorHeapAllocator.h" />
|
||||||
|
<ClInclude Include="d3dx12.h" />
|
||||||
|
<ClInclude Include="DDSTextureLoader12.h" />
|
||||||
|
<ClInclude Include="ForwardListItem.h" />
|
||||||
|
<ClInclude Include="Guid.h" />
|
||||||
|
<ClInclude Include="InputArchive.h" />
|
||||||
|
<ClInclude Include="ModelImporter.h" />
|
||||||
|
<ClInclude Include="ObjectsFactory.h" />
|
||||||
|
<ClInclude Include="Object.h" />
|
||||||
|
<ClInclude Include="AssetManager.h" />
|
||||||
|
<ClInclude Include="Filesystem.h" />
|
||||||
|
<ClInclude Include="LEngine.h" />
|
||||||
|
<ClInclude Include="Camera.h" />
|
||||||
|
<ClInclude Include="Component.h" />
|
||||||
|
<ClInclude Include="d3d11_types.h" />
|
||||||
|
<ClInclude Include="File.h" />
|
||||||
|
<ClInclude Include="ForwardDeclarations.h" />
|
||||||
|
<ClInclude Include="GameObject.h" />
|
||||||
|
<ClInclude Include="FatalError.h" />
|
||||||
|
<ClInclude Include="Material.h" />
|
||||||
|
<ClInclude Include="Mathf.h" />
|
||||||
|
<ClInclude Include="Mesh.h" />
|
||||||
|
<ClInclude Include="MeshGenerator.h" />
|
||||||
|
<ClInclude Include="MeshRenderer.h" />
|
||||||
|
<ClInclude Include="ObjMeshLoader.h" />
|
||||||
|
<ClInclude Include="OutputArchive.h" />
|
||||||
|
<ClInclude Include="Renderer.h" />
|
||||||
|
<ClInclude Include="RenderTargetOutput.h" />
|
||||||
|
<ClInclude Include="Scene.h" />
|
||||||
|
<ClInclude Include="RenderOutput.h" />
|
||||||
|
<ClInclude Include="SceneRenderer.h" />
|
||||||
|
<ClInclude Include="Shader.h" />
|
||||||
|
<ClInclude Include="ShaderInclude.h" />
|
||||||
|
<ClInclude Include="ShaderParametersBlock.h" />
|
||||||
|
<ClInclude Include="Gizmos.h" />
|
||||||
|
<ClInclude Include="GizmoVertex.h" />
|
||||||
|
<ClInclude Include="d3d11_helper.h" />
|
||||||
|
<ClInclude Include="Bounds.h" />
|
||||||
|
<ClInclude Include="shaders\car_shader.fx" />
|
||||||
|
<ClInclude Include="Submesh.h" />
|
||||||
|
<ClInclude Include="SwapChainOutput.h" />
|
||||||
|
<ClInclude Include="Texture.h" />
|
||||||
|
<ClInclude Include="TextureImporter.h" />
|
||||||
|
<ClInclude Include="Transform.h" />
|
||||||
|
<ClInclude Include="Vertex.h" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<None Include="shaders\f1\f2\test.inc" />
|
||||||
|
<None Include="shaders\lighting\cook_torrance_term.inc" />
|
||||||
|
<None Include="shaders\red_shader.fx" />
|
||||||
|
<None Include="shaders\shader.fx" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<None Include="shaders\gizmos.fx">
|
||||||
|
<FileType>Document</FileType>
|
||||||
|
</None>
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<None Include="shaders\default.fx">
|
||||||
|
<FileType>Document</FileType>
|
||||||
|
</None>
|
||||||
|
</ItemGroup>
|
||||||
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||||
|
<ImportGroup Label="ExtensionTargets">
|
||||||
|
</ImportGroup>
|
||||||
|
</Project>
|
||||||
@@ -0,0 +1,198 @@
|
|||||||
|
#include "Material.h"
|
||||||
|
#include <d3d11.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include "nativelinq.h"
|
||||||
|
#include <cassert>
|
||||||
|
#include <cstring>
|
||||||
|
#include "d3dx12.h"
|
||||||
|
#include "FatalError.h"
|
||||||
|
|
||||||
|
void Material::SetShader(ShaderPtr _shader) {
|
||||||
|
shader = _shader;
|
||||||
|
RebuildBuffers();
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string Material::DiffuseMapName() {
|
||||||
|
return "_DiffuseMap";
|
||||||
|
}
|
||||||
|
std::string Material::NormalMapName() {
|
||||||
|
return "_NormalMap";
|
||||||
|
}
|
||||||
|
std::string Material::DiffuseColorName() {
|
||||||
|
return "_DiffuseColor";
|
||||||
|
}
|
||||||
|
MaterialPtr Material::Create(std::string name) {
|
||||||
|
return std::shared_ptr<Material>(new Material(name));
|
||||||
|
}
|
||||||
|
|
||||||
|
MaterialPtr Material::Create(ShaderPtr shader, std::string name) {
|
||||||
|
auto material = Create(name);
|
||||||
|
material->SetShader(shader);
|
||||||
|
return material;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Material::Apply() {
|
||||||
|
for(int i = 0; i < (int)ShaderType::Count; ++i) {
|
||||||
|
auto s = shader->GetShader((ShaderType)i);
|
||||||
|
if(s != nullptr) {
|
||||||
|
|
||||||
|
//apply shaders
|
||||||
|
//s->Apply(context);
|
||||||
|
|
||||||
|
auto& p = shaderParameters[i];
|
||||||
|
//update and apply buffers
|
||||||
|
for (auto& bufferCtx : p.buffers) {
|
||||||
|
|
||||||
|
D3D12_RANGE range;
|
||||||
|
range.Begin = range.End = 0;
|
||||||
|
|
||||||
|
uint8_t* data = nullptr;
|
||||||
|
|
||||||
|
auto hr = bufferCtx.buffer->Map(0, &range, (void**)&data);
|
||||||
|
assert(hr == S_OK);
|
||||||
|
|
||||||
|
//write all variables
|
||||||
|
for (auto& variable : bufferCtx.variables) {
|
||||||
|
auto param = parameters.GetParameterByName(variable.name);
|
||||||
|
if (param != nullptr) {
|
||||||
|
memcpy(data + variable.offset, param->GetPointer(), variable.size);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
range.End = bufferCtx.size;
|
||||||
|
bufferCtx.buffer->Unmap(0, &range);
|
||||||
|
assert(hr == S_OK);
|
||||||
|
/*context->Unmap(bufferCtx.buffer, 0);
|
||||||
|
ID3D11Buffer* buffers[1] = { bufferCtx.buffer };
|
||||||
|
|
||||||
|
switch ((ShaderType)i)
|
||||||
|
{
|
||||||
|
case ShaderType::Vs:
|
||||||
|
context->VSSetConstantBuffers(bufferCtx.bindPoint, 1, buffers);
|
||||||
|
break;
|
||||||
|
case ShaderType::Ps:
|
||||||
|
context->PSSetConstantBuffers(bufferCtx.bindPoint, 1, buffers);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
assert(false && "not implemented");
|
||||||
|
}*/
|
||||||
|
|
||||||
|
//sr.pData
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
//apply shader resources
|
||||||
|
/*for (auto& resourceCtx : p.resources) {
|
||||||
|
auto param = parameters.GetParameterByName(resourceCtx.name);
|
||||||
|
if (param != nullptr) {
|
||||||
|
auto resourceParam = std::dynamic_pointer_cast<ShaderResourceParameter>(param);
|
||||||
|
|
||||||
|
ID3D11ShaderResourceView* resources[1] = { resourceParam->value };
|
||||||
|
|
||||||
|
switch ((ShaderType)i)
|
||||||
|
{
|
||||||
|
case ShaderType::Vs:
|
||||||
|
context->VSSetShaderResources(resourceCtx.bindPoint, 1, resources);
|
||||||
|
break;
|
||||||
|
case ShaderType::Ps:
|
||||||
|
context->PSSetShaderResources(resourceCtx.bindPoint, 1, resources);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
assert(false && "not implemented");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}*/
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Material::RebuildShaderParameters(ShaderParametersContext& params, ComPtr<ID3D12ShaderReflection> reflection) {
|
||||||
|
|
||||||
|
|
||||||
|
D3D12_SHADER_DESC d;
|
||||||
|
reflection->GetDesc(&d);
|
||||||
|
|
||||||
|
params.Clear();
|
||||||
|
|
||||||
|
//get resource variables
|
||||||
|
for(uint32_t i = 0; i < d.BoundResources; ++i) {
|
||||||
|
D3D12_SHADER_INPUT_BIND_DESC bindDesc;
|
||||||
|
reflection->GetResourceBindingDesc(i, &bindDesc);
|
||||||
|
|
||||||
|
ShaderResourceVariable var;
|
||||||
|
var.bindPoint = bindDesc.BindPoint;
|
||||||
|
var.name = bindDesc.Name;
|
||||||
|
var.type = bindDesc.Type;
|
||||||
|
params.resources.push_back(var);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//get constant buffers
|
||||||
|
for(uint32_t i = 0; i < d.ConstantBuffers; ++i) {
|
||||||
|
ShaderBufferContext ctx;
|
||||||
|
ID3D12ShaderReflectionConstantBuffer* cb = reflection->GetConstantBufferByIndex(i);
|
||||||
|
|
||||||
|
auto device = shader->GetDevice();
|
||||||
|
D3D12_SHADER_BUFFER_DESC bufferDesc;
|
||||||
|
cb->GetDesc(&bufferDesc);
|
||||||
|
|
||||||
|
ctx.name = bufferDesc.Name;
|
||||||
|
|
||||||
|
D3D11_BUFFER_DESC cbDesc;
|
||||||
|
cbDesc.ByteWidth = bufferDesc.Size;
|
||||||
|
cbDesc.Usage = D3D11_USAGE_DYNAMIC;
|
||||||
|
cbDesc.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
|
||||||
|
cbDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
|
||||||
|
cbDesc.MiscFlags = 0;
|
||||||
|
cbDesc.StructureByteStride = 0;
|
||||||
|
|
||||||
|
|
||||||
|
auto hr = device->CreateCommittedResource(
|
||||||
|
&CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_UPLOAD), // this heap will be used to upload the constant buffer data
|
||||||
|
D3D12_HEAP_FLAG_NONE, // no flags
|
||||||
|
&CD3DX12_RESOURCE_DESC::Buffer(1024 * 64), // Must be a multiple of 64KB for single-textures and constant buffers. TODO: handle size overflow o_O Maybe.
|
||||||
|
D3D12_RESOURCE_STATE_GENERIC_READ,
|
||||||
|
nullptr,
|
||||||
|
IID_PPV_ARGS(&ctx.buffer));
|
||||||
|
|
||||||
|
ctx.buffer->SetName(L"Constant Buffer Upload Resource Heap");
|
||||||
|
|
||||||
|
|
||||||
|
//device->CreateBuffer(&cbDesc, nullptr, &ctx.buffer);
|
||||||
|
|
||||||
|
for(uint32_t j = 0; j < bufferDesc.Variables; ++j) {
|
||||||
|
auto variable = cb->GetVariableByIndex(j);
|
||||||
|
D3D12_SHADER_VARIABLE_DESC varDesc;
|
||||||
|
variable->GetDesc(&varDesc);
|
||||||
|
ctx.variables.push_back(ShaderBufferVariable(varDesc.Name, varDesc.StartOffset, varDesc.Size));
|
||||||
|
}
|
||||||
|
|
||||||
|
//find buffer's bind point
|
||||||
|
|
||||||
|
auto res = Where(params.resources, [ctx](ShaderResourceVariable srv) {return srv.name == ctx.name && srv.type == D3D_SIT_CBUFFER; })->ToVector();
|
||||||
|
ctx.bindPoint = res[0].bindPoint;
|
||||||
|
ctx.type = res[0].type;
|
||||||
|
ctx.size = cbDesc.ByteWidth;
|
||||||
|
params.buffers.push_back(ctx);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Material::RebuildBuffers() {
|
||||||
|
ComPtr<ID3D12ShaderReflection> reflection;
|
||||||
|
for(int i = 0; i < (int)ShaderType::Count; ++i) {
|
||||||
|
auto& vs = shader->GetShader((ShaderType)i);
|
||||||
|
if(vs != nullptr) {
|
||||||
|
reflection = nullptr;
|
||||||
|
D3DReflect(vs->blob->GetBufferPointer(), vs->blob->GetBufferSize(), __uuidof(reflection), (void**)&reflection);
|
||||||
|
RebuildShaderParameters(shaderParameters[i], reflection);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Material::SetParametersBlock(ShaderParametersBlock& block) {
|
||||||
|
parameters = block;
|
||||||
|
}
|
||||||
@@ -0,0 +1,57 @@
|
|||||||
|
#ifndef Material_h__
|
||||||
|
#define Material_h__
|
||||||
|
|
||||||
|
#include "Shader.h"
|
||||||
|
#include <vector>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <d3dcompiler.h>
|
||||||
|
#include "ForwardDeclarations.h"
|
||||||
|
#include "ShaderParametersBlock.h"
|
||||||
|
#include "Object.h"
|
||||||
|
|
||||||
|
#include <wrl.h>
|
||||||
|
|
||||||
|
using namespace Microsoft::WRL;
|
||||||
|
|
||||||
|
class Material : public Object {
|
||||||
|
public:
|
||||||
|
std::wstring class_name() const {
|
||||||
|
return L"Material";
|
||||||
|
}
|
||||||
|
void SetShader(ShaderPtr _shader);
|
||||||
|
ShaderPtr GetShader() {
|
||||||
|
return shader;
|
||||||
|
}
|
||||||
|
void SetParametersBlock(ShaderParametersBlock& block);
|
||||||
|
ShaderParametersBlock& GetParametersBlock() {
|
||||||
|
return parameters;
|
||||||
|
}
|
||||||
|
void Apply();
|
||||||
|
static MaterialPtr Create(std::string name);
|
||||||
|
static MaterialPtr Create(ShaderPtr shader, std::string name);
|
||||||
|
static std::string DiffuseMapName();
|
||||||
|
static std::string NormalMapName();
|
||||||
|
static std::string DiffuseColorName();
|
||||||
|
ShaderParametersContext& GetCompiledParameters(ShaderType shader_type)
|
||||||
|
{
|
||||||
|
return shaderParameters[(uint32_t)shader_type];
|
||||||
|
}
|
||||||
|
private:
|
||||||
|
|
||||||
|
Material(std::string name)
|
||||||
|
:_name(name)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
std::string _name;
|
||||||
|
ShaderPtr shader;
|
||||||
|
ShaderParametersContext shaderParameters[(uint32_t)ShaderType::Count];
|
||||||
|
ShaderParametersBlock parameters;
|
||||||
|
|
||||||
|
|
||||||
|
void RebuildBuffers();
|
||||||
|
void RebuildShaderParameters(ShaderParametersContext& params, ComPtr<ID3D12ShaderReflection> reflection);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#endif // Material_h__
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
class Mathf {
|
||||||
|
public:
|
||||||
|
static float Pi() {
|
||||||
|
return 3.1415926535897932384626f;
|
||||||
|
}
|
||||||
|
static float RadToDeg() {
|
||||||
|
return 180.0f / Pi();
|
||||||
|
}
|
||||||
|
static float DegToRad() {
|
||||||
|
return Pi() / 180.0f;
|
||||||
|
}
|
||||||
|
};
|
||||||
@@ -0,0 +1,148 @@
|
|||||||
|
#include "Mesh.h"
|
||||||
|
#include "LEngine.h"
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
Mesh::Mesh(ID3D12DevicePtr dev) {
|
||||||
|
_device = dev;
|
||||||
|
SetSubmeshCount(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
MeshPtr Mesh::Create() {
|
||||||
|
return std::shared_ptr<Mesh>(new Mesh(LEngine::Instance()->GetRenderer()->GetDevice()));
|
||||||
|
}
|
||||||
|
|
||||||
|
ID3D12ResourcePtr Mesh::GetVertexBuffer() {
|
||||||
|
return _vertexBuffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
ID3D12DevicePtr Mesh::GetDevice() {
|
||||||
|
return _device;
|
||||||
|
}
|
||||||
|
|
||||||
|
MeshPtr Mesh::Create(MeshProcessFunction initFunction) {
|
||||||
|
auto mesh = Create();
|
||||||
|
if (initFunction != nullptr) {
|
||||||
|
initFunction(mesh);
|
||||||
|
mesh->RecalculateBounds();
|
||||||
|
}
|
||||||
|
return mesh;
|
||||||
|
}
|
||||||
|
|
||||||
|
Bounds Mesh::GetBounds() const {
|
||||||
|
return _bounds;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<Vertex> Mesh::GetVertices() {
|
||||||
|
std::vector<Vertex> result;
|
||||||
|
/*if (_vertexBuffer == nullptr) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
D3D11_BUFFER_DESC desc;
|
||||||
|
_vertexBuffer->GetDesc(&desc);
|
||||||
|
desc.CPUAccessFlags = D3D11_CPU_ACCESS_READ;
|
||||||
|
desc.Usage = D3D11_USAGE_STAGING;
|
||||||
|
desc.BindFlags = 0;
|
||||||
|
ID3D11BufferPtr stagingBuffer;
|
||||||
|
_device->CreateBuffer(&desc, nullptr, &stagingBuffer);
|
||||||
|
ID3D11DeviceContextPtr ctx;
|
||||||
|
_device->GetImmediateContext(&ctx);
|
||||||
|
|
||||||
|
ctx->CopyResource(stagingBuffer, _vertexBuffer);
|
||||||
|
D3D11_MAPPED_SUBRESOURCE sr;
|
||||||
|
ctx->Map(stagingBuffer, 0, D3D11_MAP_READ, 0, &sr);
|
||||||
|
result.resize(desc.ByteWidth / sizeof(Vertex));
|
||||||
|
memcpy_s(&result[0], desc.ByteWidth, sr.pData, desc.ByteWidth);
|
||||||
|
ctx->Unmap(stagingBuffer, 0);*/
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
D3D12_VERTEX_BUFFER_VIEW Mesh::GetVertexBufferView(){
|
||||||
|
D3D12_VERTEX_BUFFER_VIEW result;
|
||||||
|
result.BufferLocation = _vertexBuffer->GetGPUVirtualAddress();
|
||||||
|
result.SizeInBytes = _vertexCount * sizeof(Vertex);
|
||||||
|
result.StrideInBytes = sizeof(Vertex);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Mesh::SetVertices(const std::vector<Vertex>& vertices) {
|
||||||
|
auto bytesCount = sizeof(vertices[0])* vertices.size();
|
||||||
|
_vertexCount = vertices.size();
|
||||||
|
|
||||||
|
|
||||||
|
//create vertex buffer
|
||||||
|
_device->CreateCommittedResource(
|
||||||
|
&CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_DEFAULT),
|
||||||
|
D3D12_HEAP_FLAG_NONE,
|
||||||
|
&CD3DX12_RESOURCE_DESC::Buffer(bytesCount),
|
||||||
|
D3D12_RESOURCE_STATE_COPY_DEST,
|
||||||
|
nullptr,
|
||||||
|
IID_PPV_ARGS(&_vertexBuffer));
|
||||||
|
|
||||||
|
|
||||||
|
//create upload buffer
|
||||||
|
ComPtr<ID3D12Resource> vBufferUploadHeap;
|
||||||
|
_device->CreateCommittedResource(
|
||||||
|
&CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_UPLOAD),
|
||||||
|
D3D12_HEAP_FLAG_NONE,
|
||||||
|
&CD3DX12_RESOURCE_DESC::Buffer(bytesCount),
|
||||||
|
D3D12_RESOURCE_STATE_GENERIC_READ,
|
||||||
|
nullptr,
|
||||||
|
IID_PPV_ARGS(&vBufferUploadHeap));
|
||||||
|
vBufferUploadHeap->SetName(L"Vertex Buffer Upload Resource Heap");
|
||||||
|
|
||||||
|
|
||||||
|
D3D12_SUBRESOURCE_DATA vertexData = {};
|
||||||
|
vertexData.pData = reinterpret_cast<const BYTE*>(&vertices[0]); // pointer to our vertex array
|
||||||
|
vertexData.RowPitch = bytesCount; // size of all our triangle vertex data
|
||||||
|
vertexData.SlicePitch = bytesCount; // also the size of our triangle vertex data
|
||||||
|
|
||||||
|
|
||||||
|
auto renderer = LEngine::Instance()->GetRenderer();
|
||||||
|
auto cl = renderer->BeginCommandList();
|
||||||
|
UpdateSubresources(cl.Get(), _vertexBuffer.Get(), vBufferUploadHeap.Get(), 0, 0, 1, &vertexData);
|
||||||
|
cl->ResourceBarrier(1, &CD3DX12_RESOURCE_BARRIER::Transition(_vertexBuffer.Get(), D3D12_RESOURCE_STATE_COPY_DEST, D3D12_RESOURCE_STATE_VERTEX_AND_CONSTANT_BUFFER));
|
||||||
|
renderer->EndCommandList();
|
||||||
|
renderer->WaitCommandsQueue();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Mesh::SetIndices(const Submesh::index_array_t& indices, MeshTopology topology, uint32_t submeshId) {
|
||||||
|
if (submeshId >= GetSubmeshCount()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
_submeshes[submeshId]->Set(indices, topology);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t Mesh::GetSubmeshCount() const {
|
||||||
|
return _submeshes.size();
|
||||||
|
}
|
||||||
|
void Mesh::SetSubmeshCount(uint32_t count) {
|
||||||
|
auto oldSize = _submeshes.size();
|
||||||
|
_submeshes.resize(count);
|
||||||
|
for (auto i = oldSize; i < count; ++i) {
|
||||||
|
_submeshes[i] = std::make_shared<Submesh>();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const std::vector<SubmeshPtr>& Mesh::GetSubmeshes() {
|
||||||
|
return _submeshes;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Mesh::RecalculateBounds() {
|
||||||
|
/*auto vertices = GetVertices();
|
||||||
|
if (vertices.size() == 0) {
|
||||||
|
_bounds.SetSize(float3(0, 0, 0));
|
||||||
|
_bounds.SetCenter(float3(0, 0, 0));
|
||||||
|
}
|
||||||
|
|
||||||
|
float3 minPoint = vertices[0].position.xyz;
|
||||||
|
float3 maxPoint = vertices[0].position.xyz;
|
||||||
|
|
||||||
|
for (size_t i = 1; i < vertices.size(); ++i) {
|
||||||
|
minPoint = lm::min(minPoint, vertices[i].position.xyz);
|
||||||
|
maxPoint = lm::max(maxPoint, vertices[i].position.xyz);
|
||||||
|
}
|
||||||
|
|
||||||
|
_bounds.SetCenter((minPoint + maxPoint) * 0.5f);
|
||||||
|
_bounds.SetSize(maxPoint - minPoint);*/
|
||||||
|
}
|
||||||
@@ -0,0 +1,49 @@
|
|||||||
|
#ifndef Mesh_h__
|
||||||
|
#define Mesh_h__
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <memory>
|
||||||
|
#include <functional>
|
||||||
|
#include "ForwardDeclarations.h"
|
||||||
|
#include "Vertex.h"
|
||||||
|
#include "Submesh.h"
|
||||||
|
#include "Bounds.h"
|
||||||
|
#include "Object.h"
|
||||||
|
|
||||||
|
#include <wrl.h>
|
||||||
|
|
||||||
|
using namespace Microsoft::WRL;
|
||||||
|
|
||||||
|
typedef std::function<void(MeshPtr)> MeshProcessFunction;
|
||||||
|
|
||||||
|
class Mesh : public Object {
|
||||||
|
public:
|
||||||
|
Mesh():_vertexCount(0)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
std::vector<Vertex> GetVertices();
|
||||||
|
void SetVertices(const std::vector<Vertex>& vertices);
|
||||||
|
void SetIndices(const Submesh::index_array_t& indices, MeshTopology topology, uint32_t submeshId);
|
||||||
|
void RecalculateBounds();
|
||||||
|
ID3D12ResourcePtr GetVertexBuffer();
|
||||||
|
ID3D12DevicePtr GetDevice();
|
||||||
|
static MeshPtr Create();
|
||||||
|
static MeshPtr Create(MeshProcessFunction initFunction);
|
||||||
|
uint32_t GetSubmeshCount() const;
|
||||||
|
void SetSubmeshCount(uint32_t count);
|
||||||
|
const std::vector<SubmeshPtr>& GetSubmeshes();
|
||||||
|
Bounds GetBounds() const;
|
||||||
|
D3D12_VERTEX_BUFFER_VIEW GetVertexBufferView();
|
||||||
|
private:
|
||||||
|
size_t _vertexCount;
|
||||||
|
Bounds _bounds;
|
||||||
|
Mesh(ID3D12DevicePtr dev);
|
||||||
|
ID3D12ResourcePtr _vertexBuffer;
|
||||||
|
ID3D12DevicePtr _device;
|
||||||
|
std::vector<SubmeshPtr> _submeshes;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#endif // Mesh_h__
|
||||||
@@ -0,0 +1,80 @@
|
|||||||
|
#include "MeshGenerator.h"
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
void MeshGenerator::Cube(MeshPtr mesh, bool splitFaces){
|
||||||
|
if (mesh == nullptr) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<Vertex> vertices;
|
||||||
|
std::vector<uint32_t> indices;
|
||||||
|
|
||||||
|
float3 corners[8];
|
||||||
|
for (int i = 0; i < 2; ++i) {
|
||||||
|
for (int j = 0; j < 4; ++j) {
|
||||||
|
int id = i * 4 + j;
|
||||||
|
corners[id].x() = ((j == 0) || (j == 3)) ? -0.5f : 0.5f;
|
||||||
|
corners[id].y() = -((float)(j >> 1) - 0.5f);
|
||||||
|
corners[id].z() =(float)i - 0.5f;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int vid[] = { 0,1,2,3, 5,4,7,6, 1,5,6,2, 4,0,3,7, 4,5,1,0, 3,2,6,7 };
|
||||||
|
for (int i = 0; i < 24; ++i) {
|
||||||
|
Vertex v;
|
||||||
|
v.position.x() = corners[vid[i]].x();
|
||||||
|
v.position.y() = corners[vid[i]].y();
|
||||||
|
v.position.z() = corners[vid[i]].z();
|
||||||
|
vertices.push_back(v);
|
||||||
|
}
|
||||||
|
|
||||||
|
float3 normals[6] = { float3(0.0f,0.0f,-1.0f), float3(0.0f,0.0f,1.0f), float3(1.0f,0.0f,0.0f), float3(-1.0f,0.0f,0.0f), float3(0.0f,1.0f,0.0f), float3(0.0f,-1.0f,0.0f) };
|
||||||
|
int indicesBase[] = { 0,1,3,1,2,3 };
|
||||||
|
float2 uvBase[] = { float2(0.0f,0.0f), float2(1.0f,0.0f), float2(1.0f,1.0f), float2(0.0f,1.0f) };
|
||||||
|
|
||||||
|
mesh->SetSubmeshCount(splitFaces ? 6 : 1);
|
||||||
|
|
||||||
|
for (int i = 0; i < 6; ++i) {
|
||||||
|
for (int j = 0; j < 4; ++j) {
|
||||||
|
vertices[i * 4 + j].normal = normals[i];
|
||||||
|
vertices[i * 4 + j].uv0 = uvBase[j];
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int j = 0; j < 6; ++j) {
|
||||||
|
indices.push_back(indicesBase[j] + i * 4);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (splitFaces) {
|
||||||
|
mesh->SetIndices(indices, MeshTopology::TriangleList, i);
|
||||||
|
indices.resize(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
mesh->SetVertices(vertices);
|
||||||
|
|
||||||
|
if (!splitFaces) {
|
||||||
|
mesh->SetIndices(indices, MeshTopology::TriangleList, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void MeshGenerator::Plane(MeshPtr mesh) {
|
||||||
|
if (mesh == nullptr) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
float3 normal(0.0f, 1.0f, 0.0f);
|
||||||
|
float extend = 0.5f;
|
||||||
|
|
||||||
|
std::vector<Vertex> vertices = {
|
||||||
|
Vertex(float4(-extend, 0.0f, extend, 1.0f), normal, float2(0.0f,0.0f)),
|
||||||
|
Vertex(float4(extend, 0.0f, extend, 1.0f), normal, float2(1.0f,0.0f)),
|
||||||
|
Vertex(float4(extend, 0.0f, -extend, 1.0f), normal, float2(1.0f,1.0f)),
|
||||||
|
Vertex(float4(-extend, 0.0f, -extend, 1.0f), normal, float2(0.0f,1.0f)),
|
||||||
|
};
|
||||||
|
|
||||||
|
std::vector<uint32_t> indices = { 0,1,3,1,2,3 };
|
||||||
|
|
||||||
|
mesh->SetSubmeshCount(1);
|
||||||
|
mesh->SetVertices(vertices);
|
||||||
|
mesh->SetIndices(indices, MeshTopology::TriangleList, 0);
|
||||||
|
}
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
#ifndef MeshGenerator_h__
|
||||||
|
#define MeshGenerator_h__
|
||||||
|
|
||||||
|
#include "Mesh.h"
|
||||||
|
#include "ForwardDeclarations.h"
|
||||||
|
|
||||||
|
class MeshGenerator
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static void Cube(MeshPtr mesh, bool splitFaces);
|
||||||
|
|
||||||
|
static void Plane(MeshPtr mesh);
|
||||||
|
};
|
||||||
|
#endif // MeshGenerator_h__
|
||||||
|
|
||||||
@@ -0,0 +1,54 @@
|
|||||||
|
#include "MeshRenderer.h"
|
||||||
|
#include <cassert>
|
||||||
|
|
||||||
|
void MeshRenderer::SyncMaterialSlots() {
|
||||||
|
if (mesh == nullptr) {
|
||||||
|
_materials.resize(0);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
_materials.resize(mesh->GetSubmeshCount());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::shared_ptr<MeshRenderer> MeshRenderer::SetMesh(MeshPtr m) {
|
||||||
|
mesh = m;
|
||||||
|
SyncMaterialSlots();
|
||||||
|
UpdateInputLayouts();
|
||||||
|
return std::static_pointer_cast<MeshRenderer>(shared_from_this());
|
||||||
|
}
|
||||||
|
|
||||||
|
MeshPtr MeshRenderer::GetMesh() {
|
||||||
|
return mesh;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MeshRenderer::SetMaterial(MaterialPtr material, int id){
|
||||||
|
SyncMaterialSlots();
|
||||||
|
_materials[id] = material;
|
||||||
|
UpdateInputLayouts();
|
||||||
|
}
|
||||||
|
|
||||||
|
void MeshRenderer::UpdateInputLayouts(){
|
||||||
|
|
||||||
|
if (mesh == nullptr) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_materials.size() == 0 || _materials[0] == nullptr) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
//D3D12_APPEND_ALIGNED_ELEMENT
|
||||||
|
_inputElements.clear();
|
||||||
|
_inputElements.push_back({ "POSITION", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, 0, D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0 });
|
||||||
|
_inputElements.push_back({ "NORMAL", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 16, D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0 });
|
||||||
|
_inputElements.push_back({ "UV", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 28, D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0 });
|
||||||
|
_inputElements.push_back({ "UV", 1, DXGI_FORMAT_R32G32_FLOAT, 0, 36, D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0 });
|
||||||
|
|
||||||
|
|
||||||
|
_inputLayoutDesc.NumElements = _inputElements.size();
|
||||||
|
_inputLayoutDesc.pInputElementDescs = &_inputElements[0];
|
||||||
|
|
||||||
|
//auto vs = _materials[0]->GetShader()->GetShader(ShaderType::Vs);
|
||||||
|
//auto hr = mesh->GetDevice()->CreateInputLayout(ied, 4, vs->blob->GetBufferPointer(), vs->blob->GetBufferSize(), &_inputLayout);
|
||||||
|
//assert(hr == S_OK);
|
||||||
|
}
|
||||||
@@ -0,0 +1,31 @@
|
|||||||
|
#ifndef MeshRenderer_h__
|
||||||
|
#define MeshRenderer_h__
|
||||||
|
|
||||||
|
#include "ObjectsFactory.h"
|
||||||
|
#include "Mesh.h"
|
||||||
|
#include "Material.h"
|
||||||
|
#include <vector>
|
||||||
|
#include "ForwardDeclarations.h"
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
|
||||||
|
LOBJECT(MeshRenderer, Component)
|
||||||
|
public:
|
||||||
|
std::shared_ptr<MeshRenderer> SetMesh(MeshPtr m);
|
||||||
|
MeshPtr GetMesh();
|
||||||
|
void SetMaterial(MaterialPtr material, int id);
|
||||||
|
std::vector<MaterialPtr> GetMaterials() {
|
||||||
|
return _materials;
|
||||||
|
}
|
||||||
|
D3D12_INPUT_LAYOUT_DESC GetInputLayout() {
|
||||||
|
return _inputLayoutDesc;
|
||||||
|
}
|
||||||
|
private:
|
||||||
|
void UpdateInputLayouts();
|
||||||
|
void SyncMaterialSlots();
|
||||||
|
MeshPtr mesh;
|
||||||
|
std::vector<MaterialPtr> _materials;
|
||||||
|
std::vector<D3D12_INPUT_ELEMENT_DESC> _inputElements;
|
||||||
|
D3D12_INPUT_LAYOUT_DESC _inputLayoutDesc;
|
||||||
|
};
|
||||||
|
#endif // MeshRenderer_h__
|
||||||
@@ -0,0 +1,36 @@
|
|||||||
|
#ifndef ModelImporter_h__
|
||||||
|
#define ModelImporter_h__
|
||||||
|
|
||||||
|
#include "AssetImporter.h"
|
||||||
|
#include <filesystem>
|
||||||
|
#include <vector>
|
||||||
|
#include <string>
|
||||||
|
#include "ObjMeshLoader.h"
|
||||||
|
#include "AssetDatabase.h"
|
||||||
|
|
||||||
|
class ModelImporter : public AssetImporter {
|
||||||
|
public:
|
||||||
|
virtual bool can_import(const std::wstring& path) const override {
|
||||||
|
std::tr2::sys::path src_path(path);
|
||||||
|
return src_path.extension() == ".obj";
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual std::wstring name() override {
|
||||||
|
return L"ModelImporter";
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual bool set_parameters(std::wstring params) override {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual std::wstring get_parameters() const override {
|
||||||
|
return L"";
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void import(std::wstring asset_path) override {
|
||||||
|
ObjMeshLoader loader;
|
||||||
|
loader.Load(asset_path);
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
#endif // ModelImporter_h__
|
||||||
@@ -0,0 +1,416 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "Mesh.h"
|
||||||
|
#include "GameObject.h"
|
||||||
|
#include <fstream>
|
||||||
|
#include <iostream>
|
||||||
|
#include "lmath.h"
|
||||||
|
#include <stack>
|
||||||
|
#include <sstream>
|
||||||
|
#include <array>
|
||||||
|
#include <tuple>
|
||||||
|
#include <map>
|
||||||
|
#include <cstdio>
|
||||||
|
#include <filesystem>
|
||||||
|
|
||||||
|
#include "MeshRenderer.h"
|
||||||
|
using namespace lm;
|
||||||
|
|
||||||
|
|
||||||
|
struct ObjVertex {
|
||||||
|
int32_t vid;
|
||||||
|
int32_t tid;
|
||||||
|
int32_t nid;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct ObjFace {
|
||||||
|
int32_t sid;
|
||||||
|
int32_t mid;
|
||||||
|
std::array<ObjVertex, 3> vertices;
|
||||||
|
};
|
||||||
|
|
||||||
|
class ObjGroup {
|
||||||
|
public:
|
||||||
|
ObjGroup(std::string objName)
|
||||||
|
:name(objName), smoothGroupsEnabled(true), activeSmoothGroup(0)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
void AddFace(int32_t matId, const ObjVertex& v0, const ObjVertex& v1, const ObjVertex& v2) {
|
||||||
|
ObjFace f;
|
||||||
|
f.vertices[0] = v0;
|
||||||
|
f.vertices[1] = v1;
|
||||||
|
f.vertices[2] = v2;
|
||||||
|
f.mid = matId;
|
||||||
|
f.sid = activeSmoothGroup;
|
||||||
|
faces.push_back(f);
|
||||||
|
|
||||||
|
if (std::find(materials.begin(), materials.end(), matId) == materials.end()) {
|
||||||
|
materials.push_back(matId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
std::vector<uint32_t> materials;
|
||||||
|
std::string name;
|
||||||
|
std::vector<ObjFace> faces;
|
||||||
|
int32_t activeSmoothGroup;
|
||||||
|
bool smoothGroupsEnabled;
|
||||||
|
};
|
||||||
|
|
||||||
|
class ObjMeshLoader {
|
||||||
|
public:
|
||||||
|
friend class ObjGroup;
|
||||||
|
ObjMeshLoader() : _activeMatId(-1){
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string read_file(std::wstring path)
|
||||||
|
{
|
||||||
|
FILE* file = nullptr;
|
||||||
|
auto err = _wfopen_s(&file, path.c_str(), L"rb");
|
||||||
|
|
||||||
|
fseek(file, 0, SEEK_END);
|
||||||
|
auto file_size = ftell(file);
|
||||||
|
|
||||||
|
std::string str;
|
||||||
|
str.resize(file_size);
|
||||||
|
fseek(file, 0, SEEK_SET);
|
||||||
|
|
||||||
|
auto done = fread_s(&str[0], file_size, 1, file_size, file);
|
||||||
|
fclose(file);
|
||||||
|
return str;
|
||||||
|
}
|
||||||
|
std::vector<GameObjectPtr> Load(const std::wstring& path) {
|
||||||
|
std::vector<GameObjectPtr> result;
|
||||||
|
|
||||||
|
/*if (!file1.good()) {
|
||||||
|
return result;
|
||||||
|
}*/
|
||||||
|
|
||||||
|
auto str = read_file(path);
|
||||||
|
|
||||||
|
|
||||||
|
std::stringstream buffer(str);
|
||||||
|
std::vector<char> line_buffer;
|
||||||
|
line_buffer.resize(8192);
|
||||||
|
|
||||||
|
|
||||||
|
std::string previous_line;
|
||||||
|
std::string line;
|
||||||
|
//while (buffer.getline(&line_buffer[0], line_buffer.size())) {
|
||||||
|
while (std::getline(buffer, line)) {
|
||||||
|
|
||||||
|
//std::string line(&line_buffer[0]);
|
||||||
|
if (line.size() < 3) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
switch(line[0]){
|
||||||
|
case 'v':
|
||||||
|
switch (line[1]) {
|
||||||
|
case ' ': {
|
||||||
|
float3 v;
|
||||||
|
sscanf_s(&line[2], "%f%f%f", &v.x(), &v.y(), &v.z());
|
||||||
|
_vertices.push_back(v);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 'n': {
|
||||||
|
float3 n;
|
||||||
|
sscanf_s(&line[2], "%f%f%f", &n.x(), &n.y(), &n.z());
|
||||||
|
_normals.push_back(n);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 't':
|
||||||
|
float3 t;
|
||||||
|
sscanf_s(&line[2], "%f%f%f", &t.x(), &t.y(), &t.z());
|
||||||
|
_texcoords.push_back(t);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 'f': {
|
||||||
|
bool is_open = false;
|
||||||
|
size_t start = 2;
|
||||||
|
int slash_pos_0 = 0;
|
||||||
|
int slash_pos_1 = 0;
|
||||||
|
|
||||||
|
if(line[line.size() - 1] == '\r')
|
||||||
|
{
|
||||||
|
line[line.size() - 1] = ' ';
|
||||||
|
}else
|
||||||
|
{
|
||||||
|
line += " ";
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<ObjVertex> fVertices;
|
||||||
|
for (size_t i = 2; i < line.size(); ++i) {
|
||||||
|
if (line[i] == ' ') {
|
||||||
|
if (is_open) { //finalize chunk
|
||||||
|
is_open = false;
|
||||||
|
ObjVertex v;
|
||||||
|
if (slash_pos_0 == -1) {
|
||||||
|
auto pos2 = (int)buffer.tellg();
|
||||||
|
sscanf_s(&line[start], "%d", &v.vid);
|
||||||
|
v.tid = v.nid = -1;
|
||||||
|
} else if (slash_pos_1 == -1) {
|
||||||
|
sscanf_s(&line[start], "%d/%d", &v.vid, &v.tid);
|
||||||
|
v.nid = -1;
|
||||||
|
} else {
|
||||||
|
if (slash_pos_1 - slash_pos_0 == 1) {
|
||||||
|
sscanf_s(&line[start], "%d//%d", &v.vid, &v.nid);
|
||||||
|
v.tid = -1;
|
||||||
|
} else {
|
||||||
|
sscanf_s(&line[start], "%d/%d/%d", &v.vid, &v.tid, &v.nid);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fVertices.push_back(v);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (!is_open) {
|
||||||
|
start = i;
|
||||||
|
slash_pos_0 = -1;
|
||||||
|
slash_pos_1 = -1;
|
||||||
|
is_open = true;
|
||||||
|
} else {
|
||||||
|
if (line[i] == '/') {
|
||||||
|
if (slash_pos_0 == -1) {
|
||||||
|
slash_pos_0 = i;
|
||||||
|
} else {
|
||||||
|
slash_pos_1 = i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
//emit triangles (split if quads)
|
||||||
|
if (fVertices.size() == 3) {
|
||||||
|
_groups[_groups.size() - 1].AddFace(_activeMatId, fVertices[0], fVertices[1], fVertices[2]);
|
||||||
|
} else if (fVertices.size() == 4) {
|
||||||
|
_groups[_groups.size() - 1].AddFace(_activeMatId, fVertices[0], fVertices[1], fVertices[2]);
|
||||||
|
_groups[_groups.size() - 1].AddFace(_activeMatId, fVertices[0], fVertices[2], fVertices[3]);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 'g': {
|
||||||
|
auto name = line.substr(2);
|
||||||
|
_groups.push_back(ObjGroup(name));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 's':
|
||||||
|
if (line.find("off") != std::string::npos) {
|
||||||
|
_groups[_groups.size() - 1].smoothGroupsEnabled = false;
|
||||||
|
} else {
|
||||||
|
sscanf_s(&line[2], "%d", &_groups[_groups.size() - 1].activeSmoothGroup);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 'm': {
|
||||||
|
std::stringstream ss(line);
|
||||||
|
std::string key, value;
|
||||||
|
ss >> key;
|
||||||
|
ss >> value;
|
||||||
|
_mtlLibName = value;
|
||||||
|
std::cout << "Found material library: " << value << std::endl;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 'u': {
|
||||||
|
std::stringstream ss(line);
|
||||||
|
std::string key, value;
|
||||||
|
ss >> key;
|
||||||
|
ss >> value;
|
||||||
|
SetActiveMaterial(value);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
previous_line = line;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
auto mtllib_path = obj_to_mtl_path(path);
|
||||||
|
|
||||||
|
_mats = load_mtllib(mtllib_path);
|
||||||
|
|
||||||
|
for (auto& group : _groups) {
|
||||||
|
result.push_back(UnpackGroup(group));
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
private:
|
||||||
|
std::vector<MaterialPtr> _mats;
|
||||||
|
std::wstring obj_to_mtl_path(const std::wstring& obj_path){
|
||||||
|
std::tr2::sys::path src(obj_path);
|
||||||
|
auto dst = src.parent_path();
|
||||||
|
return dst.append(_mtlLibName).wstring();
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<MaterialPtr> load_mtllib(const std::wstring& path){
|
||||||
|
std::vector<MaterialPtr> result;
|
||||||
|
|
||||||
|
auto text = std::ifstream(path);
|
||||||
|
|
||||||
|
std::string line;
|
||||||
|
auto default_shader = Shader::Create(L"shaders/default.fx");
|
||||||
|
|
||||||
|
MaterialPtr active_material;
|
||||||
|
while(std::getline(text, line))
|
||||||
|
{
|
||||||
|
if(line[0] == '#' || line.empty()){
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string word;
|
||||||
|
std::stringstream ls(line);
|
||||||
|
ls >> word;
|
||||||
|
|
||||||
|
if (word == "newmtl") {
|
||||||
|
std::string mat_name;
|
||||||
|
ls >> mat_name;
|
||||||
|
if(active_material != nullptr)
|
||||||
|
{
|
||||||
|
result.push_back(active_material);
|
||||||
|
}
|
||||||
|
active_material = Material::Create(default_shader, mat_name);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
if (active_material == nullptr) {
|
||||||
|
continue;
|
||||||
|
} else {
|
||||||
|
if(word == "Kd")
|
||||||
|
{
|
||||||
|
std::vector<float> color;
|
||||||
|
float tmp = 0.0f;
|
||||||
|
while(ls >> tmp)
|
||||||
|
{
|
||||||
|
color.push_back(tmp);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(color.size() == 3)
|
||||||
|
{
|
||||||
|
active_material->GetParametersBlock().SetValue(Material::DiffuseColorName(), float4(color[0], color[1], color[2], 1.0f));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (active_material != nullptr) {
|
||||||
|
result.push_back(active_material);
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
typedef std::tuple<ObjVertex, Vertex> VertexPair;
|
||||||
|
GameObjectPtr UnpackGroup(const ObjGroup& group) {
|
||||||
|
std::vector<std::vector<ObjFace*>> facesTable;
|
||||||
|
facesTable.resize(_vertices.size());
|
||||||
|
std::vector<Vertex> vertices;
|
||||||
|
std::map<size_t, std::vector<uint32_t>> submeshes;
|
||||||
|
|
||||||
|
//EmitGeometry(group, vertices, submeshes);
|
||||||
|
EmitGeometrySimple(group, vertices, submeshes);
|
||||||
|
|
||||||
|
auto mesh = Mesh::Create();
|
||||||
|
mesh->SetSubmeshCount(group.materials.size());
|
||||||
|
mesh->SetVertices(vertices);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
int id = 0;
|
||||||
|
for(auto& p : submeshes)
|
||||||
|
{
|
||||||
|
mesh->SetIndices(p.second, MeshTopology::TriangleList, id);
|
||||||
|
id++;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto obj = GameObject::create();
|
||||||
|
obj->AddComponent<MeshRenderer>()->SetMesh(mesh);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
for (size_t i = 0; i < group.materials.size(); ++i){
|
||||||
|
auto mat_id = group.materials[i];
|
||||||
|
|
||||||
|
obj->GetComponent<MeshRenderer>()->SetMaterial(_mats[mat_id], i);
|
||||||
|
}
|
||||||
|
|
||||||
|
mesh->RecalculateBounds();
|
||||||
|
return obj;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*MeshPtr BuildMesh(ObjGroup& group) {
|
||||||
|
std::vector<Vertex> vertices;
|
||||||
|
std::vector<int32_t> indices;
|
||||||
|
EmitGeometry(group, vertices, indices);
|
||||||
|
|
||||||
|
auto mesh = Mesh::Create();
|
||||||
|
mesh->SetSubmeshCount(group.materials.size());
|
||||||
|
return mesh;
|
||||||
|
}*/
|
||||||
|
|
||||||
|
void EmitGeometry(const ObjGroup& group, std::vector<Vertex>& vertices, std::map<size_t, std::vector<uint32_t>>& submeshes) {
|
||||||
|
auto vComp = [](ObjVertex v1, ObjVertex v2) {
|
||||||
|
return (v1.vid == v2.vid) && (v1.tid == v2.tid) && (v1.nid && v2.nid);
|
||||||
|
};
|
||||||
|
|
||||||
|
std::vector<ObjVertex> tmpVertices;
|
||||||
|
|
||||||
|
for (auto& f : group.faces) {
|
||||||
|
for (auto& v : f.vertices) {
|
||||||
|
int id = -1;
|
||||||
|
for (size_t i = 0; i < tmpVertices.size(); ++i) {
|
||||||
|
if (vComp(tmpVertices[i], v)) {
|
||||||
|
id = i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (id == -1) {
|
||||||
|
id = tmpVertices.size();
|
||||||
|
tmpVertices.push_back(v);
|
||||||
|
Vertex vertex;
|
||||||
|
vertex.position = float4(_vertices[v.vid - 1], 1.0f);
|
||||||
|
vertex.normal = _normals[v.nid - 1];
|
||||||
|
vertex.uv0 = _texcoords[v.tid - 1].xy();
|
||||||
|
vertices.push_back(vertex);
|
||||||
|
}
|
||||||
|
|
||||||
|
submeshes[f.mid].push_back(id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void EmitGeometrySimple(const ObjGroup& group, std::vector<Vertex>& vertices, std::map<size_t, std::vector<uint32_t>>& submeshes) {
|
||||||
|
int id = 0;
|
||||||
|
for (auto& f : group.faces) {
|
||||||
|
for (auto& v : f.vertices) {
|
||||||
|
Vertex vertex;
|
||||||
|
vertex.position = float4(_vertices[v.vid - 1], 1.0f);
|
||||||
|
vertex.normal = _normals[v.nid - 1];
|
||||||
|
vertex.uv0 = _texcoords[v.tid - 1].xy();
|
||||||
|
vertices.push_back(vertex);
|
||||||
|
submeshes[f.mid].push_back(id);
|
||||||
|
++id;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void SetActiveMaterial(const std::string& name) {
|
||||||
|
for (size_t i = 0; i < _materials.size(); ++i) {
|
||||||
|
if (_materials[i] == name) {
|
||||||
|
_activeMatId = i;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_activeMatId = _materials.size();
|
||||||
|
_materials.push_back(name);
|
||||||
|
}
|
||||||
|
int _activeMatId;
|
||||||
|
std::string _mtlLibName;
|
||||||
|
std::vector<float3> _vertices;
|
||||||
|
std::vector<float3> _normals;
|
||||||
|
std::vector<float3> _texcoords;
|
||||||
|
std::vector<std::string> _materials;
|
||||||
|
std::vector<ObjGroup> _groups;
|
||||||
|
};
|
||||||
@@ -0,0 +1,39 @@
|
|||||||
|
#include "Object.h"
|
||||||
|
#include "Archive.h"
|
||||||
|
|
||||||
|
std::map<ObjectRegistry::instance_id_t, std::weak_ptr<Object>> ObjectRegistry::_registry;
|
||||||
|
|
||||||
|
std::atomic<ObjectRegistry::instance_id_t> ObjectRegistry::_last_index = 0;
|
||||||
|
|
||||||
|
Object::Object():_instance_id(-1){
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
std::shared_ptr<Object> Object::create(){
|
||||||
|
auto result = std::shared_ptr<Object>(new Object());
|
||||||
|
result->Register();
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
Object::~Object(){
|
||||||
|
ObjectRegistry::remove_object(_instance_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Object::Register(){
|
||||||
|
_instance_id = ObjectRegistry::add_object(shared_from_this());
|
||||||
|
}
|
||||||
|
|
||||||
|
void Object::serialize(Archive& archive) {
|
||||||
|
archive << _name;
|
||||||
|
}
|
||||||
|
|
||||||
|
ObjectRegistry::instance_id_t ObjectRegistry::add_object(std::shared_ptr<Object> object) {
|
||||||
|
auto result = _last_index++;
|
||||||
|
_registry[result] = object;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ObjectRegistry::remove_object(instance_id_t object) {
|
||||||
|
_registry.erase(object);
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,104 @@
|
|||||||
|
#ifndef Object_h__
|
||||||
|
#define Object_h__
|
||||||
|
|
||||||
|
#include <cstdint>
|
||||||
|
#include <string>
|
||||||
|
#include <fstream>
|
||||||
|
#include <memory>
|
||||||
|
#include <windows.h>
|
||||||
|
#include <functional>
|
||||||
|
#include <map>
|
||||||
|
#include <vector>
|
||||||
|
#include <atomic>
|
||||||
|
#include "Asset.h"
|
||||||
|
|
||||||
|
class Object;
|
||||||
|
class OutputArchive;
|
||||||
|
|
||||||
|
class ObjectRegistry {
|
||||||
|
public:
|
||||||
|
using instance_id_t = uint64_t;
|
||||||
|
friend class Object;
|
||||||
|
private:
|
||||||
|
static instance_id_t add_object(std::shared_ptr<Object> object);
|
||||||
|
static void remove_object(instance_id_t object);
|
||||||
|
static std::map<instance_id_t, std::weak_ptr<Object>> _registry;
|
||||||
|
static std::atomic<instance_id_t> _last_index;
|
||||||
|
};
|
||||||
|
|
||||||
|
class Archive;
|
||||||
|
class Object : public std::enable_shared_from_this<Object>{
|
||||||
|
public:
|
||||||
|
using instance_id_t = ObjectRegistry::instance_id_t;
|
||||||
|
virtual void serialize(Archive& archive);
|
||||||
|
|
||||||
|
virtual void construct() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual std::wstring get_type_name() const{
|
||||||
|
return L"Object";
|
||||||
|
}
|
||||||
|
|
||||||
|
std::shared_ptr<Object> as_object(){
|
||||||
|
return shared_from_this();
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
static std::vector<std::shared_ptr<T>> FindObjectsOfType() {
|
||||||
|
std::vector<std::shared_ptr<T>> result;
|
||||||
|
auto& registry = ObjectRegistry::_registry;
|
||||||
|
for(auto& pair : registry){
|
||||||
|
auto obj = pair.second.lock();
|
||||||
|
auto targetObj = std::dynamic_pointer_cast<T>(obj);
|
||||||
|
if(targetObj != nullptr){
|
||||||
|
result.push_back(targetObj);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
static std::shared_ptr<Object> Find(const AssetFileLink& link)
|
||||||
|
{
|
||||||
|
auto& registry = ObjectRegistry::_registry;
|
||||||
|
for (auto& pair : registry) {
|
||||||
|
auto obj = pair.second.lock();
|
||||||
|
if(obj != nullptr && obj->GetFileLink() == link)
|
||||||
|
{
|
||||||
|
return obj;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
static std::shared_ptr<Object> create();
|
||||||
|
virtual ~Object();
|
||||||
|
|
||||||
|
const std::wstring& get_name() const{
|
||||||
|
return _name;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SetName(const std::wstring& name){
|
||||||
|
_name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
instance_id_t GetInstanceId() const{
|
||||||
|
return _instance_id;
|
||||||
|
}
|
||||||
|
|
||||||
|
const AssetFileLink& GetFileLink() const{
|
||||||
|
return _fileLink;
|
||||||
|
}
|
||||||
|
void SetLink(const AssetFileLink& link){
|
||||||
|
_fileLink = link;
|
||||||
|
}
|
||||||
|
protected:
|
||||||
|
void Register();
|
||||||
|
Object();
|
||||||
|
AssetFileLink _fileLink;
|
||||||
|
instance_id_t _instance_id;
|
||||||
|
private:
|
||||||
|
std::wstring _name;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // Object_h__
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
#include "ObjectsFactory.h"
|
||||||
|
|
||||||
|
|
||||||
|
void ObjectsFactory::register_factory(factory_function factory, const std::wstring& class_name) {
|
||||||
|
|
||||||
|
_factory_functions[class_name] = factory;
|
||||||
|
}
|
||||||
|
|
||||||
|
ObjectsFactory& ObjectsFactory::instance()
|
||||||
|
{
|
||||||
|
static ObjectsFactory instance;
|
||||||
|
return instance;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::shared_ptr<Object> ObjectsFactory::create_object(const std::wstring& class_name) const {
|
||||||
|
try {
|
||||||
|
return _factory_functions.at(class_name)();
|
||||||
|
} catch (...) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,58 @@
|
|||||||
|
#ifndef ComponentFactory_h__
|
||||||
|
#define ComponentFactory_h__
|
||||||
|
|
||||||
|
#include "ForwardDeclarations.h"
|
||||||
|
#include <functional>
|
||||||
|
#include <map>
|
||||||
|
#include "Object.h"
|
||||||
|
|
||||||
|
class ObjectsFactory {
|
||||||
|
public:
|
||||||
|
typedef std::function<std::shared_ptr<Object>()> factory_function;
|
||||||
|
typedef std::map<std::wstring, factory_function> factory_container;
|
||||||
|
|
||||||
|
static ObjectsFactory& instance();
|
||||||
|
void register_factory(factory_function factory, const std::wstring& class_name);
|
||||||
|
std::shared_ptr<Object> create_object(const std::wstring& class_name) const;
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
std::shared_ptr<T> create_object(){
|
||||||
|
return std::dynamic_pointer_cast<T>(create_object(T::type_name(), game_object));
|
||||||
|
}
|
||||||
|
private:
|
||||||
|
factory_container _factory_functions;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
struct ObjectFactory {
|
||||||
|
typedef std::shared_ptr<T> object_pointer_t;
|
||||||
|
ObjectFactory() {
|
||||||
|
ObjectsFactory::instance().register_factory(&factory_func, T::type_name());
|
||||||
|
}
|
||||||
|
static std::shared_ptr<Object> factory_func() {
|
||||||
|
return std::static_pointer_cast<Object>(T::create());
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#define LOBJECT(__type_name, __base_type) \
|
||||||
|
class __type_name;\
|
||||||
|
static ObjectFactory<__type_name> __type_name##_factory;\
|
||||||
|
class __type_name : public __base_type {\
|
||||||
|
public:\
|
||||||
|
static std::wstring type_name() {\
|
||||||
|
return L#__type_name;\
|
||||||
|
}\
|
||||||
|
std::wstring get_type_name() const override{\
|
||||||
|
return L#__type_name;\
|
||||||
|
}\
|
||||||
|
static std::shared_ptr<__type_name> create() {\
|
||||||
|
auto result = std::shared_ptr<__type_name>(new __type_name());\
|
||||||
|
result->Register();\
|
||||||
|
result->construct();\
|
||||||
|
return result;\
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#endif // ComponentFactory_h__
|
||||||
@@ -0,0 +1,53 @@
|
|||||||
|
#ifndef OutputArchive_h__
|
||||||
|
#define OutputArchive_h__
|
||||||
|
|
||||||
|
#include "Archive.h"
|
||||||
|
#include "Object.h"
|
||||||
|
#include <vector>
|
||||||
|
#include <cstdint>
|
||||||
|
#include <algorithm>
|
||||||
|
#include <fstream>
|
||||||
|
|
||||||
|
class OutputArchive : public Archive {
|
||||||
|
public:
|
||||||
|
OutputArchive(std::shared_ptr<std::ostream> stream)
|
||||||
|
:_stream(stream) {
|
||||||
|
// _stream = std::ofstream(path, std::ios::binary);
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual bool is_loading() const override {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_type get_offset() const override {
|
||||||
|
return _stream->tellp();
|
||||||
|
}
|
||||||
|
|
||||||
|
void set_offset(size_type offset) override {
|
||||||
|
_stream->seekp(offset, std::ios::beg);
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void serialize(void* data, size_t size) override {
|
||||||
|
_stream->write(reinterpret_cast<char*>(data), size);
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void flush() override {
|
||||||
|
if(_stream->good()){
|
||||||
|
_stream->flush();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
~OutputArchive() {
|
||||||
|
flush();
|
||||||
|
}
|
||||||
|
std::shared_ptr<std::ostream> GetStream()
|
||||||
|
{
|
||||||
|
return _stream;
|
||||||
|
}
|
||||||
|
private:
|
||||||
|
std::shared_ptr<std::ostream> _stream;
|
||||||
|
std::vector<std::shared_ptr<Object>> _processed_objects;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#endif // OutputArchive_h__
|
||||||
@@ -0,0 +1,39 @@
|
|||||||
|
#ifndef Screen_h__
|
||||||
|
#define Screen_h__
|
||||||
|
|
||||||
|
#include <d3d11.h>
|
||||||
|
#include <cassert>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include "Renderer.h"
|
||||||
|
#include "d3d11_types.h"
|
||||||
|
#include <memory>
|
||||||
|
#include "d3dx12.h"
|
||||||
|
#include <vector>
|
||||||
|
#include <wrl.h>
|
||||||
|
|
||||||
|
using namespace Microsoft::WRL;
|
||||||
|
|
||||||
|
class RenderOutput {
|
||||||
|
public:
|
||||||
|
|
||||||
|
virtual ~RenderOutput() {
|
||||||
|
}
|
||||||
|
virtual uint32_t GetWidth() = 0;
|
||||||
|
virtual uint32_t GetHeight() = 0;
|
||||||
|
|
||||||
|
virtual CD3DX12_CPU_DESCRIPTOR_HANDLE GetRenderTargetDescriptor(uint32_t id) = 0;
|
||||||
|
virtual CD3DX12_CPU_DESCRIPTOR_HANDLE GetDepthStencilDescriptor(uint32_t id) = 0;
|
||||||
|
|
||||||
|
virtual ID3D12ResourcePtr GetRenderTarget(uint32_t id) = 0;
|
||||||
|
virtual ID3D12ResourcePtr GetDepthBuffer(uint32_t id) = 0;
|
||||||
|
|
||||||
|
virtual void Present() = 0;
|
||||||
|
virtual void OnPreRender(RendererPtr renderer) = 0;
|
||||||
|
|
||||||
|
virtual uint32_t GetCurrentBufferIndex() = 0;
|
||||||
|
virtual uint32_t GetBuffersCount() = 0;
|
||||||
|
protected:
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef std::shared_ptr<RenderOutput> RenderOutputPtr;
|
||||||
|
#endif // Screen_h__
|
||||||
@@ -0,0 +1,81 @@
|
|||||||
|
#include "RenderTargetOutput.h"
|
||||||
|
/*
|
||||||
|
std::shared_ptr<RenderTargetOutput> RenderTargetOutput::Create(RendererPtr renderer) {
|
||||||
|
return std::shared_ptr<RenderTargetOutput>(new RenderTargetOutput(renderer));
|
||||||
|
}
|
||||||
|
RenderTargetOutput::RenderTargetOutput(RendererPtr renderer)
|
||||||
|
:_renderer(renderer) {
|
||||||
|
|
||||||
|
}
|
||||||
|
uint32_t RenderTargetOutput::GetWidth() {
|
||||||
|
if (_rt == nullptr) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
D3D11_TEXTURE2D_DESC desc;
|
||||||
|
_rt->GetDesc(&desc);
|
||||||
|
return desc.Width;
|
||||||
|
}
|
||||||
|
uint32_t RenderTargetOutput::GetHeight() {
|
||||||
|
if (_rt == nullptr) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
D3D11_TEXTURE2D_DESC desc;
|
||||||
|
_rt->GetDesc(&desc);
|
||||||
|
return desc.Height;
|
||||||
|
}
|
||||||
|
ID3D11RenderTargetViewPtr RenderTargetOutput::GetRenderTargetView() {
|
||||||
|
return _rtView;
|
||||||
|
}
|
||||||
|
ID3D11DepthStencilViewPtr RenderTargetOutput::GetDepthStencilView() {
|
||||||
|
return _dsView;
|
||||||
|
}
|
||||||
|
void RenderTargetOutput::Present() {
|
||||||
|
|
||||||
|
}
|
||||||
|
void RenderTargetOutput::OnPreRender(RendererPtr renderer) {
|
||||||
|
|
||||||
|
}
|
||||||
|
void RenderTargetOutput::Resize(uint32_t width, uint32_t height) {
|
||||||
|
if (_rt != nullptr) {
|
||||||
|
D3D11_TEXTURE2D_DESC desc;
|
||||||
|
_rt->GetDesc(&desc);
|
||||||
|
if (desc.Width == width && desc.Height == height) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_rt = nullptr;
|
||||||
|
_ds = nullptr;
|
||||||
|
_rtView = nullptr;
|
||||||
|
_dsView = nullptr;
|
||||||
|
|
||||||
|
D3D11_TEXTURE2D_DESC desc = { 0 };
|
||||||
|
desc.Width = width;
|
||||||
|
desc.Height = height;
|
||||||
|
desc.MipLevels = 1;
|
||||||
|
desc.ArraySize = 1;
|
||||||
|
desc.Format = DXGI_FORMAT_B8G8R8A8_UNORM;
|
||||||
|
desc.SampleDesc.Count = 1;
|
||||||
|
desc.Usage = D3D11_USAGE_DEFAULT;
|
||||||
|
desc.BindFlags = D3D11_BIND_RENDER_TARGET | D3D11_BIND_SHADER_RESOURCE;
|
||||||
|
desc.CPUAccessFlags = 0;
|
||||||
|
desc.MiscFlags = 0;
|
||||||
|
|
||||||
|
auto hr = _renderer->GetDevice()->CreateTexture2D(&desc, nullptr, &_rt);
|
||||||
|
hr = _renderer->GetDevice()->CreateRenderTargetView(_rt, nullptr, &_rtView);
|
||||||
|
|
||||||
|
D3D11_TEXTURE2D_DESC descDepth;
|
||||||
|
descDepth.Width = width;
|
||||||
|
descDepth.Height = height;
|
||||||
|
descDepth.MipLevels = 1;
|
||||||
|
descDepth.ArraySize = 1;
|
||||||
|
descDepth.Format = DXGI_FORMAT_D24_UNORM_S8_UINT;
|
||||||
|
descDepth.SampleDesc.Count = 1;
|
||||||
|
descDepth.SampleDesc.Quality = 0;
|
||||||
|
descDepth.Usage = D3D11_USAGE_DEFAULT;
|
||||||
|
descDepth.BindFlags = D3D11_BIND_DEPTH_STENCIL;
|
||||||
|
descDepth.CPUAccessFlags = 0;
|
||||||
|
descDepth.MiscFlags = 0;
|
||||||
|
hr = _renderer->GetDevice()->CreateTexture2D(&descDepth, NULL, &_ds);
|
||||||
|
hr = _renderer->GetDevice()->CreateDepthStencilView(_ds, nullptr, &_dsView);
|
||||||
|
}*/
|
||||||
@@ -0,0 +1,28 @@
|
|||||||
|
#ifndef RenderTargetOutput_h__
|
||||||
|
#define RenderTargetOutput_h__
|
||||||
|
|
||||||
|
#include "RenderOutput.h"
|
||||||
|
#include "d3d11_types.h"
|
||||||
|
#include "Renderer.h"
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
class RenderTargetOutput : public RenderOutput {
|
||||||
|
public:
|
||||||
|
static std::shared_ptr<RenderTargetOutput> Create(RendererPtr renderer);
|
||||||
|
virtual uint32_t GetWidth() override;
|
||||||
|
virtual uint32_t GetHeight() override;
|
||||||
|
virtual ID3D11RenderTargetViewPtr GetRenderTargetView() override;
|
||||||
|
virtual ID3D11DepthStencilViewPtr GetDepthStencilView() override;
|
||||||
|
virtual void Present() override;
|
||||||
|
virtual void OnPreRender(RendererPtr renderer) override;
|
||||||
|
void Resize(uint32_t width, uint32_t height);
|
||||||
|
private:
|
||||||
|
RenderTargetOutput(RendererPtr renderer);
|
||||||
|
ID3D11DepthStencilViewPtr _dsView;
|
||||||
|
ID3D11RenderTargetViewPtr _rtView;
|
||||||
|
ID3D11Texture2DPtr _ds;
|
||||||
|
ID3D11Texture2DPtr _rt;
|
||||||
|
RendererPtr _renderer;
|
||||||
|
};*/
|
||||||
|
#endif // RenderTargetOutput_h__
|
||||||
@@ -0,0 +1,179 @@
|
|||||||
|
#include "Renderer.h"
|
||||||
|
#include <iostream>
|
||||||
|
#include "d3dx12.h"
|
||||||
|
#include <dxgidebug.h>
|
||||||
|
|
||||||
|
bool Renderer::Init() {
|
||||||
|
ComPtr<ID3D12Debug> debugController;
|
||||||
|
if (SUCCEEDED(D3D12GetDebugInterface(IID_PPV_ARGS(&debugController)))) {
|
||||||
|
debugController->EnableDebugLayer();
|
||||||
|
}
|
||||||
|
|
||||||
|
//Enable DXGI debug layer
|
||||||
|
if (SUCCEEDED(DXGIGetDebugInterface1(0, IID_PPV_ARGS(&dxgiInfoQueue)))) {
|
||||||
|
dxgiInfoQueue->SetBreakOnSeverity(DXGI_DEBUG_ALL, DXGI_INFO_QUEUE_MESSAGE_SEVERITY_ERROR, true);
|
||||||
|
dxgiInfoQueue->SetBreakOnSeverity(DXGI_DEBUG_ALL, DXGI_INFO_QUEUE_MESSAGE_SEVERITY_CORRUPTION, true);
|
||||||
|
dxgiInfoQueue->SetMuteDebugOutput(DXGI_DEBUG_ALL, FALSE);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
auto hr = CreateDXGIFactory2(DXGI_CREATE_FACTORY_DEBUG, IID_PPV_ARGS(&dxgiFactory));
|
||||||
|
dxgiFactory->EnumAdapters1(0, &dxgiAdapter);
|
||||||
|
|
||||||
|
IDXGIAdapter1Ptr warpAdapter;
|
||||||
|
//dxgiFactory->EnumWarpAdapter(IID_PPV_ARGS(&warpAdapter));
|
||||||
|
warpAdapter = dxgiAdapter;
|
||||||
|
|
||||||
|
DXGI_ADAPTER_DESC desc;
|
||||||
|
warpAdapter->GetDesc(&desc);
|
||||||
|
std::wcout << "Using adapter: " << desc.Description << std::endl;
|
||||||
|
|
||||||
|
HR_ASSERT(D3D12CreateDevice(warpAdapter.Get(), D3D_FEATURE_LEVEL_11_0, IID_PPV_ARGS(&device)));
|
||||||
|
|
||||||
|
// Describe and create the command queue.
|
||||||
|
D3D12_COMMAND_QUEUE_DESC queueDesc = {};
|
||||||
|
queueDesc.Flags = D3D12_COMMAND_QUEUE_FLAG_NONE;
|
||||||
|
queueDesc.Type = D3D12_COMMAND_LIST_TYPE_DIRECT;
|
||||||
|
|
||||||
|
device->CreateCommandQueue(&queueDesc, IID_PPV_ARGS(&_directCommandQueue));
|
||||||
|
device->CreateCommandAllocator(D3D12_COMMAND_LIST_TYPE_DIRECT, IID_PPV_ARGS(&_directCommandAllocator));
|
||||||
|
device->CreateCommandList(0, D3D12_COMMAND_LIST_TYPE_DIRECT, _directCommandAllocator.Get(), nullptr, IID_PPV_ARGS(&_directCommandList));
|
||||||
|
|
||||||
|
|
||||||
|
//create descriptor heaps
|
||||||
|
|
||||||
|
constexpr size_t descriptorHeapsSize = 512;
|
||||||
|
|
||||||
|
D3D12_DESCRIPTOR_HEAP_DESC srvHeapDesc = {};
|
||||||
|
srvHeapDesc.NumDescriptors = descriptorHeapsSize;
|
||||||
|
srvHeapDesc.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_SHADER_VISIBLE;
|
||||||
|
srvHeapDesc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV;
|
||||||
|
hr = device->CreateDescriptorHeap(&srvHeapDesc, IID_PPV_ARGS(&_srvDescriptorsHeap));
|
||||||
|
if (FAILED(hr))
|
||||||
|
{
|
||||||
|
FatalError(L"Failed to create SRV descriptors heap");
|
||||||
|
}
|
||||||
|
_srvDescriptorsHeap->SetName(L"SRV Heap");
|
||||||
|
|
||||||
|
_srvDescriptorAllocator = std::make_shared<D3d12DescriptorHeapAllocator>(_srvDescriptorsHeap);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Renderer::reportLiveObjects() const
|
||||||
|
{
|
||||||
|
IDXGIDebug1* pDebug = nullptr;
|
||||||
|
if (SUCCEEDED(DXGIGetDebugInterface1(0, IID_PPV_ARGS(&pDebug)))) {
|
||||||
|
pDebug->ReportLiveObjects(DXGI_DEBUG_ALL, DXGI_DEBUG_RLO_ALL);
|
||||||
|
pDebug->Release();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::shared_ptr<D3d12DescriptorHeapAllocator> Renderer::getSrvDescriptorsAllocator(){
|
||||||
|
return _srvDescriptorAllocator;
|
||||||
|
}
|
||||||
|
|
||||||
|
ComPtr<ID3D12GraphicsCommandList> Renderer::BeginCommandList(){
|
||||||
|
auto HR = _directCommandAllocator->Reset();
|
||||||
|
HR = _directCommandList->Reset(_directCommandAllocator.Get(), nullptr);
|
||||||
|
return _directCommandList;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Renderer::EndCommandList(){
|
||||||
|
_directCommandList->Close();
|
||||||
|
ID3D12CommandList* ppCommandLists[] = { _directCommandList.Get()};
|
||||||
|
_directCommandQueue->ExecuteCommandLists(_countof(ppCommandLists), ppCommandLists);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Renderer::WaitCommandsQueue(){
|
||||||
|
ID3D12Fence* fence = nullptr;
|
||||||
|
HRESULT hr = device->CreateFence(0, D3D12_FENCE_FLAG_NONE, IID_PPV_ARGS(&fence));
|
||||||
|
if (hr)
|
||||||
|
return;
|
||||||
|
|
||||||
|
auto eventHandle = CreateEvent(NULL, FALSE, FALSE, NULL);
|
||||||
|
|
||||||
|
_directCommandQueue->Signal(fence, 1);
|
||||||
|
fence->SetEventOnCompletion(1, eventHandle);
|
||||||
|
WaitForSingleObject(eventHandle, INFINITE);
|
||||||
|
|
||||||
|
CloseHandle(eventHandle);
|
||||||
|
fence->Release();
|
||||||
|
}
|
||||||
|
|
||||||
|
ID3D12DevicePtr Renderer::GetDevice() {
|
||||||
|
return device;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<IDXGIOutput1Ptr> Renderer::EnumOutputs() {
|
||||||
|
IDXGIOutput1Ptr pOutput;
|
||||||
|
std::vector<IDXGIOutput1Ptr> vOutputs;
|
||||||
|
int outputId = 0;
|
||||||
|
|
||||||
|
IDXGIOutputPtr o;
|
||||||
|
while (GetAdapter()->EnumOutputs(outputId, &o) != DXGI_ERROR_NOT_FOUND) {
|
||||||
|
o->QueryInterface(IID_PPV_ARGS(&pOutput));
|
||||||
|
vOutputs.push_back(pOutput);
|
||||||
|
pOutput = nullptr;
|
||||||
|
o = nullptr;
|
||||||
|
++outputId;
|
||||||
|
}
|
||||||
|
return vOutputs;
|
||||||
|
}
|
||||||
|
|
||||||
|
IDXGISwapChain1Ptr Renderer::CreateSwapChain(HWND window, bool windowed, uint32_t width, uint32_t height, uint32_t buffers_count, bool stereo) {
|
||||||
|
DXGI_SWAP_CHAIN_DESC1 swapChainDesc = { 0 };
|
||||||
|
swapChainDesc.Width = width;
|
||||||
|
swapChainDesc.Height = height;
|
||||||
|
swapChainDesc.Format = DXGI_FORMAT_B8G8R8A8_UNORM;
|
||||||
|
swapChainDesc.Stereo = stereo;
|
||||||
|
swapChainDesc.SampleDesc.Count = 1;
|
||||||
|
swapChainDesc.SampleDesc.Quality = 0;
|
||||||
|
swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
|
||||||
|
swapChainDesc.BufferCount = buffers_count;
|
||||||
|
swapChainDesc.Scaling = DXGI_SCALING_STRETCH;
|
||||||
|
swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL;
|
||||||
|
swapChainDesc.Flags = 0;
|
||||||
|
swapChainDesc.AlphaMode = DXGI_ALPHA_MODE_UNSPECIFIED;
|
||||||
|
|
||||||
|
/*DXGI_SWAP_CHAIN_FULLSCREEN_DESC fullscreenDesc = { 0 };
|
||||||
|
fullscreenDesc.RefreshRate = {60 ,0};
|
||||||
|
fullscreenDesc.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED;
|
||||||
|
fullscreenDesc.Scaling = DXGI_MODE_SCALING_UNSPECIFIED;
|
||||||
|
fullscreenDesc.Windowed = windowed;*/
|
||||||
|
|
||||||
|
IDXGISwapChain1Ptr result;
|
||||||
|
auto hr = GetFactory()->CreateSwapChainForHwnd(_directCommandQueue.Get(), window, &swapChainDesc, nullptr, nullptr, &result);
|
||||||
|
if (S_OK != hr){
|
||||||
|
FatalError(TEXT("Failed to create swap chain"));
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
//auto backBufferFormat = DXGI_FORMAT_B8G8R8A8_UNORM;
|
||||||
|
|
||||||
|
std::vector<DXGI_MODE_DESC1> Renderer::GetDisplayModes(DXGI_FORMAT format, IDXGIOutput1Ptr output) {
|
||||||
|
std::vector<DXGI_MODE_DESC1> result;
|
||||||
|
UINT numStereoModes = 0;
|
||||||
|
DXGI_MODE_DESC1 modes[1024];
|
||||||
|
auto enumFlags = DXGI_ENUM_MODES_STEREO;
|
||||||
|
|
||||||
|
output->GetDisplayModeList1(format, enumFlags, &numStereoModes, 0);
|
||||||
|
output->GetDisplayModeList1(format, enumFlags, &numStereoModes, modes);
|
||||||
|
|
||||||
|
for (UINT i = 0; i < numStereoModes; ++i) {
|
||||||
|
result.push_back(modes[i]);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<DXGI_MODE_DESC1> Renderer::GetStereoModes(std::vector<DXGI_MODE_DESC1>& modes) {
|
||||||
|
std::vector<DXGI_MODE_DESC1> result;
|
||||||
|
for (auto& m : modes) {
|
||||||
|
if (m.Stereo) {
|
||||||
|
result.push_back(m);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
@@ -0,0 +1,79 @@
|
|||||||
|
#ifndef Renderer_h__
|
||||||
|
#define Renderer_h__
|
||||||
|
|
||||||
|
#include <dxgi1_3.h>
|
||||||
|
#include <dxgi1_4.h>
|
||||||
|
#include <dxgi1_5.h>
|
||||||
|
#include <d3d11.h>
|
||||||
|
#include <d3d12.h>
|
||||||
|
#include <vector>
|
||||||
|
#include "FatalError.h"
|
||||||
|
#include <memory>
|
||||||
|
#include "d3d11_types.h"
|
||||||
|
#include <dxgidebug.h>
|
||||||
|
#include <sstream>
|
||||||
|
#include "D3d12DescriptorHeapAllocator.h"
|
||||||
|
|
||||||
|
#include <wrl.h>
|
||||||
|
|
||||||
|
using namespace Microsoft::WRL;
|
||||||
|
|
||||||
|
#define HR_ASSERT_MSG(__hr_expression, __message)\
|
||||||
|
while(true){\
|
||||||
|
HRESULT hr_ = (__hr_expression);\
|
||||||
|
if (FAILED(hr_)) {\
|
||||||
|
std::wstringstream ss; \
|
||||||
|
ss << L"Application fail with HRESULT:" << hr_ << " in file " << TEXT(__FILE__) << " at line " << __LINE__ << L" with message: " << __message; \
|
||||||
|
FatalError(ss.str().c_str()); \
|
||||||
|
}\
|
||||||
|
break;\
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#define HR_ASSERT(__hr_expression) HR_ASSERT_MSG(__hr_expression, "")
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
class Renderer {
|
||||||
|
public:
|
||||||
|
bool Init();
|
||||||
|
|
||||||
|
ID3D12DevicePtr GetDevice();
|
||||||
|
|
||||||
|
ComPtr<IDXGIAdapter1> GetAdapter() {
|
||||||
|
return dxgiAdapter;
|
||||||
|
}
|
||||||
|
ComPtr<IDXGIFactory4> GetFactory() {
|
||||||
|
return dxgiFactory;
|
||||||
|
}
|
||||||
|
|
||||||
|
ComPtr<ID3D12GraphicsCommandList> BeginCommandList();
|
||||||
|
void EndCommandList();
|
||||||
|
|
||||||
|
std::vector<IDXGIOutput1Ptr> EnumOutputs();
|
||||||
|
IDXGISwapChain1Ptr CreateSwapChain(HWND window, bool windowed, uint32_t width, uint32_t height, uint32_t buffers_count, bool stereo);
|
||||||
|
std::vector<DXGI_MODE_DESC1> GetDisplayModes(DXGI_FORMAT format, IDXGIOutput1Ptr output);
|
||||||
|
std::vector<DXGI_MODE_DESC1> GetStereoModes(std::vector<DXGI_MODE_DESC1>& modes);
|
||||||
|
void WaitCommandsQueue();
|
||||||
|
|
||||||
|
std::shared_ptr<D3d12DescriptorHeapAllocator> getSrvDescriptorsAllocator();
|
||||||
|
|
||||||
|
void reportLiveObjects() const;
|
||||||
|
private:
|
||||||
|
ComPtr<IDXGIInfoQueue> dxgiInfoQueue;
|
||||||
|
ID3D12DevicePtr device;
|
||||||
|
IDXGIAdapter1Ptr dxgiAdapter;
|
||||||
|
IDXGIFactory4Ptr dxgiFactory;
|
||||||
|
|
||||||
|
ComPtr<ID3D12CommandQueue> _directCommandQueue;
|
||||||
|
ComPtr<ID3D12GraphicsCommandList> _directCommandList;
|
||||||
|
ComPtr<ID3D12CommandAllocator> _directCommandAllocator;
|
||||||
|
|
||||||
|
ComPtr<ID3D12DescriptorHeap> _srvDescriptorsHeap;
|
||||||
|
std::shared_ptr<D3d12DescriptorHeapAllocator> _srvDescriptorAllocator;
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef std::shared_ptr<Renderer> RendererPtr;
|
||||||
|
|
||||||
|
|
||||||
|
#endif // Renderer_h__
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
#include "Scene.h"
|
||||||
|
#include "GameObject.h"
|
||||||
|
|
||||||
|
void Scene::tick(float deltaTime) {
|
||||||
|
for (auto go : objects) {
|
||||||
|
go->tick(deltaTime);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void Scene::SetName(const std::string& name) {
|
||||||
|
_name = name;
|
||||||
|
}
|
||||||
|
std::string Scene::GetName() {
|
||||||
|
return _name;
|
||||||
|
}
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
#ifndef Scene_h__
|
||||||
|
#define Scene_h__
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#include "ForwardDeclarations.h"
|
||||||
|
#include <string>
|
||||||
|
#include "Gizmos.h"
|
||||||
|
|
||||||
|
class Scene {
|
||||||
|
public:
|
||||||
|
Scene() {
|
||||||
|
_gizmos.Init();
|
||||||
|
}
|
||||||
|
std::vector<GameObjectPtr> objects;
|
||||||
|
void tick(float deltaTime);
|
||||||
|
void SetName(const std::string& name);
|
||||||
|
std::string GetName();
|
||||||
|
Gizmos& GetGizmos() {
|
||||||
|
return _gizmos;
|
||||||
|
}
|
||||||
|
private:
|
||||||
|
Gizmos _gizmos;
|
||||||
|
std::string _name;
|
||||||
|
};
|
||||||
|
#endif // Scene_h__
|
||||||
@@ -0,0 +1,308 @@
|
|||||||
|
#include "SceneRenderer.h"
|
||||||
|
#include "GameObject.h"
|
||||||
|
#include "Transform.h"
|
||||||
|
#include "Texture.h"
|
||||||
|
|
||||||
|
SceneRenderer::SceneRenderer()
|
||||||
|
{
|
||||||
|
auto renderer = LEngine::Instance()->GetRenderer();
|
||||||
|
auto device = renderer->GetDevice();
|
||||||
|
|
||||||
|
//create samplers heap
|
||||||
|
D3D12_DESCRIPTOR_HEAP_DESC samplers_heap_desc;
|
||||||
|
samplers_heap_desc.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_SHADER_VISIBLE;
|
||||||
|
samplers_heap_desc.NodeMask = 0;
|
||||||
|
samplers_heap_desc.NumDescriptors = 1;
|
||||||
|
samplers_heap_desc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER;
|
||||||
|
HR_ASSERT(device->CreateDescriptorHeap(&samplers_heap_desc, IID_PPV_ARGS(&samplers_heap)));
|
||||||
|
samplers_heap->SetName(L"Samplers heap");
|
||||||
|
|
||||||
|
//create texture sampler
|
||||||
|
D3D12_SAMPLER_DESC sampler_desc = {};
|
||||||
|
sampler_desc.Filter = D3D12_FILTER_MIN_MAG_MIP_LINEAR;
|
||||||
|
sampler_desc.AddressU = D3D12_TEXTURE_ADDRESS_MODE_WRAP;
|
||||||
|
sampler_desc.AddressV = D3D12_TEXTURE_ADDRESS_MODE_WRAP;
|
||||||
|
sampler_desc.AddressW = D3D12_TEXTURE_ADDRESS_MODE_WRAP;
|
||||||
|
sampler_desc.MinLOD = 0;
|
||||||
|
sampler_desc.MaxLOD = D3D12_FLOAT32_MAX;
|
||||||
|
sampler_desc.MipLODBias = 0.0f;
|
||||||
|
sampler_desc.MaxAnisotropy = 1;
|
||||||
|
sampler_desc.ComparisonFunc = D3D12_COMPARISON_FUNC_ALWAYS;
|
||||||
|
|
||||||
|
renderer->GetDevice()->CreateSampler(&sampler_desc, samplers_heap->GetCPUDescriptorHandleForHeapStart());
|
||||||
|
}
|
||||||
|
|
||||||
|
void SceneRenderer::RenderScene(RendererPtr renderer, ScenePtr scene, CameraPtr camera, std::shared_ptr<RenderOutput> renderScreen) {
|
||||||
|
camera->aspect = (float)renderScreen->GetWidth() / (float)renderScreen->GetHeight();
|
||||||
|
renderScreen->OnPreRender(renderer);
|
||||||
|
|
||||||
|
D3D12_VIEWPORT viewport = {};
|
||||||
|
viewport.TopLeftX = 0;
|
||||||
|
viewport.TopLeftY = 0;
|
||||||
|
viewport.Width = (float)renderScreen->GetWidth();
|
||||||
|
viewport.Height = (float)renderScreen->GetHeight();
|
||||||
|
viewport.MinDepth = 0;
|
||||||
|
viewport.MaxDepth = 1;
|
||||||
|
|
||||||
|
|
||||||
|
D3D12_RECT scissorRect = {};
|
||||||
|
scissorRect.left = 0;
|
||||||
|
scissorRect.top = 0;
|
||||||
|
scissorRect.right = renderScreen->GetWidth();
|
||||||
|
scissorRect.bottom = renderScreen->GetHeight();
|
||||||
|
|
||||||
|
auto commandList = renderer->BeginCommandList();
|
||||||
|
auto rt = renderScreen->GetRenderTarget(renderScreen->GetCurrentBufferIndex());
|
||||||
|
commandList->ResourceBarrier(1, &CD3DX12_RESOURCE_BARRIER::Transition(rt.Get(), D3D12_RESOURCE_STATE_PRESENT, D3D12_RESOURCE_STATE_RENDER_TARGET));
|
||||||
|
auto rtvHandle = renderScreen->GetRenderTargetDescriptor(renderScreen->GetCurrentBufferIndex());
|
||||||
|
auto dsvHandle = renderScreen->GetDepthStencilDescriptor(renderScreen->GetCurrentBufferIndex());
|
||||||
|
commandList->OMSetRenderTargets(1, &rtvHandle, FALSE, &dsvHandle);
|
||||||
|
|
||||||
|
const float clearColor[] = { 0.1f, 0.1f, 0.14f, 1.0f };
|
||||||
|
commandList->ClearRenderTargetView(rtvHandle, clearColor, 0, nullptr);
|
||||||
|
commandList->ClearDepthStencilView(dsvHandle, D3D12_CLEAR_FLAG_DEPTH | D3D12_CLEAR_FLAG_STENCIL, 1.0f, 0, 0, nullptr);
|
||||||
|
|
||||||
|
//renderer->EndCommandList();
|
||||||
|
// renderer->WaitCommandsQueue();
|
||||||
|
|
||||||
|
commandList->RSSetViewports(1, &viewport);
|
||||||
|
commandList->RSSetScissorRects(1, &scissorRect);
|
||||||
|
|
||||||
|
std::vector<ComPtr<ID3D12RootSignature>> signatures;
|
||||||
|
std::vector<ComPtr<ID3D12PipelineState>> pso;
|
||||||
|
|
||||||
|
|
||||||
|
//draw all objects
|
||||||
|
for (auto obj : scene->objects) {
|
||||||
|
auto mr = obj->GetComponent<MeshRenderer>();
|
||||||
|
if (mr != nullptr) {
|
||||||
|
auto mesh = mr->GetMesh();
|
||||||
|
if (mesh != nullptr) {
|
||||||
|
for (uint32_t i = 0; i < mesh->GetSubmeshCount(); ++i) {
|
||||||
|
auto mat = mr->GetMaterials()[i];
|
||||||
|
auto submesh = mesh->GetSubmeshes()[i];
|
||||||
|
if (mat == nullptr || submesh == nullptr) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
auto& params = mat->GetParametersBlock();
|
||||||
|
|
||||||
|
//params.SetShaderResource()
|
||||||
|
|
||||||
|
//set system variables
|
||||||
|
auto tf = obj->transform->GetGlobalTransform();
|
||||||
|
auto view = camera->worldToCameraMatrix();
|
||||||
|
auto proj = camera->projectionMatrix();
|
||||||
|
params.SetValue("mWorld", transpose(tf));
|
||||||
|
params.SetValue("mView", transpose(view));
|
||||||
|
params.SetValue("mProjection", transpose(proj));
|
||||||
|
|
||||||
|
auto camPos = camera->transform()->GetGlobalPosition();
|
||||||
|
params.SetValue("cameraWorldPos", float4(camPos.x(), camPos.y(), camPos.z(), 0.0f));
|
||||||
|
|
||||||
|
mat->Apply();
|
||||||
|
|
||||||
|
|
||||||
|
//create single element ranges for constant buffers
|
||||||
|
std::vector<D3D12_ROOT_PARAMETER> root_parameters;
|
||||||
|
|
||||||
|
auto compiled_params = mat->GetCompiledParameters(ShaderType::Vs);
|
||||||
|
|
||||||
|
for(auto p : compiled_params.buffers)
|
||||||
|
{
|
||||||
|
D3D12_ROOT_DESCRIPTOR rootCBVDescriptor;
|
||||||
|
rootCBVDescriptor.RegisterSpace = 0;
|
||||||
|
rootCBVDescriptor.ShaderRegister = p.bindPoint;
|
||||||
|
|
||||||
|
D3D12_ROOT_PARAMETER root_param = {};
|
||||||
|
root_param.ParameterType = D3D12_ROOT_PARAMETER_TYPE_CBV;
|
||||||
|
root_param.Descriptor = rootCBVDescriptor;
|
||||||
|
|
||||||
|
root_parameters.push_back(root_param);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
size_t srvParamOffset = root_parameters.size();
|
||||||
|
size_t srvParamCount = 0;
|
||||||
|
|
||||||
|
auto srvHeapAllocator = renderer->getSrvDescriptorsAllocator();
|
||||||
|
auto srvHeap = srvHeapAllocator->getHeap();
|
||||||
|
|
||||||
|
std::vector<D3D12_DESCRIPTOR_RANGE> srvRanges[2];
|
||||||
|
//size_t srvParamCount =
|
||||||
|
//VS + PS
|
||||||
|
for(int id = 0; id < 2; ++id){
|
||||||
|
auto shader_params = mat->GetCompiledParameters((ShaderType)id);
|
||||||
|
|
||||||
|
for(auto r : shader_params.resources){
|
||||||
|
if(r.type == D3D_SIT_TEXTURE)
|
||||||
|
{
|
||||||
|
auto param = mat->GetParametersBlock().GetParameterByName(r.name);
|
||||||
|
auto texParam = std::static_pointer_cast<ShaderTextureParameter>(param);
|
||||||
|
auto tex = texParam == nullptr ? nullptr : texParam->value;
|
||||||
|
|
||||||
|
D3D12_DESCRIPTOR_RANGE range{};
|
||||||
|
range.RangeType = D3D12_DESCRIPTOR_RANGE_TYPE_SRV;
|
||||||
|
range.RegisterSpace = 0;
|
||||||
|
range.NumDescriptors = 1;
|
||||||
|
range.BaseShaderRegister = r.bindPoint;
|
||||||
|
range.OffsetInDescriptorsFromTableStart = srvHeapAllocator->getDescriptorId(tex->srvDescriptor);
|
||||||
|
srvRanges[id].push_back(range);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//for each shader => create root table parameter
|
||||||
|
for(size_t s = 0; s < 2; ++s)
|
||||||
|
{
|
||||||
|
auto& ranges = srvRanges[s];
|
||||||
|
if(!ranges.empty())
|
||||||
|
{
|
||||||
|
D3D12_ROOT_DESCRIPTOR_TABLE srvTable;
|
||||||
|
srvTable.NumDescriptorRanges = ranges.size();
|
||||||
|
srvTable.pDescriptorRanges = &ranges[0];
|
||||||
|
|
||||||
|
D3D12_ROOT_PARAMETER srvParameter;
|
||||||
|
srvParameter.ParameterType = D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE;
|
||||||
|
srvParameter.ShaderVisibility = ((ShaderType)s == ShaderType::Vs) ? D3D12_SHADER_VISIBILITY_VERTEX : D3D12_SHADER_VISIBILITY_PIXEL;
|
||||||
|
srvParameter.DescriptorTable = srvTable;
|
||||||
|
root_parameters.push_back(srvParameter);
|
||||||
|
|
||||||
|
srvParamCount++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// create a static sampler
|
||||||
|
D3D12_STATIC_SAMPLER_DESC sampler = {};
|
||||||
|
sampler.Filter = D3D12_FILTER_MIN_MAG_MIP_POINT;
|
||||||
|
sampler.AddressU = D3D12_TEXTURE_ADDRESS_MODE_BORDER;
|
||||||
|
sampler.AddressV = D3D12_TEXTURE_ADDRESS_MODE_BORDER;
|
||||||
|
sampler.AddressW = D3D12_TEXTURE_ADDRESS_MODE_BORDER;
|
||||||
|
sampler.MipLODBias = 0;
|
||||||
|
sampler.MaxAnisotropy = 0;
|
||||||
|
sampler.ComparisonFunc = D3D12_COMPARISON_FUNC_NEVER;
|
||||||
|
sampler.BorderColor = D3D12_STATIC_BORDER_COLOR_TRANSPARENT_BLACK;
|
||||||
|
sampler.MinLOD = 0.0f;
|
||||||
|
sampler.MaxLOD = D3D12_FLOAT32_MAX;
|
||||||
|
sampler.ShaderRegister = 0;
|
||||||
|
sampler.RegisterSpace = 0;
|
||||||
|
sampler.ShaderVisibility = D3D12_SHADER_VISIBILITY_PIXEL;
|
||||||
|
|
||||||
|
|
||||||
|
//create root signature
|
||||||
|
CD3DX12_ROOT_SIGNATURE_DESC rootSignatureDesc;
|
||||||
|
rootSignatureDesc.Init(root_parameters.size(), // we have 1 root parameter
|
||||||
|
&root_parameters[0], // a pointer to the beginning of our root parameters array
|
||||||
|
1,
|
||||||
|
&sampler,
|
||||||
|
D3D12_ROOT_SIGNATURE_FLAG_ALLOW_INPUT_ASSEMBLER_INPUT_LAYOUT | // we can deny shader stages here for better performance
|
||||||
|
D3D12_ROOT_SIGNATURE_FLAG_DENY_HULL_SHADER_ROOT_ACCESS |
|
||||||
|
D3D12_ROOT_SIGNATURE_FLAG_DENY_DOMAIN_SHADER_ROOT_ACCESS |
|
||||||
|
D3D12_ROOT_SIGNATURE_FLAG_DENY_GEOMETRY_SHADER_ROOT_ACCESS);
|
||||||
|
|
||||||
|
|
||||||
|
ComPtr<ID3DBlob> signature;
|
||||||
|
ComPtr<ID3DBlob> signatureErrors;
|
||||||
|
auto hr = D3D12SerializeRootSignature(&rootSignatureDesc, D3D_ROOT_SIGNATURE_VERSION_1, &signature, &signatureErrors);
|
||||||
|
if (FAILED(hr)) {
|
||||||
|
FatalError(L"Failed to serialize root signature");
|
||||||
|
}
|
||||||
|
|
||||||
|
ComPtr<ID3D12RootSignature> rootSignature;
|
||||||
|
hr = renderer->GetDevice()->CreateRootSignature(0, signature->GetBufferPointer(), signature->GetBufferSize(), IID_PPV_ARGS(&rootSignature));
|
||||||
|
if (FAILED(hr)) {
|
||||||
|
FatalError(L"Failed to create root signature");
|
||||||
|
}
|
||||||
|
|
||||||
|
signatures.push_back(rootSignature);
|
||||||
|
|
||||||
|
|
||||||
|
//create PSO
|
||||||
|
DXGI_SAMPLE_DESC sampleDesc = {};
|
||||||
|
sampleDesc.Count = 1;
|
||||||
|
|
||||||
|
D3D12_GRAPHICS_PIPELINE_STATE_DESC psoDesc = {};
|
||||||
|
psoDesc.pRootSignature = rootSignature.Get();
|
||||||
|
psoDesc.InputLayout = mr->GetInputLayout();
|
||||||
|
psoDesc.VS = mat->GetShader()->GetShader(ShaderType::Vs)->get_bytecode();
|
||||||
|
psoDesc.PS = mat->GetShader()->GetShader(ShaderType::Ps)->get_bytecode();
|
||||||
|
psoDesc.PrimitiveTopologyType = D3D12_PRIMITIVE_TOPOLOGY_TYPE_TRIANGLE;
|
||||||
|
psoDesc.RTVFormats[0] = DXGI_FORMAT_B8G8R8A8_UNORM;
|
||||||
|
psoDesc.SampleDesc = sampleDesc;
|
||||||
|
psoDesc.SampleMask = 0xffffffff;
|
||||||
|
psoDesc.RasterizerState = CD3DX12_RASTERIZER_DESC(D3D12_DEFAULT);
|
||||||
|
psoDesc.BlendState = CD3DX12_BLEND_DESC(D3D12_DEFAULT);
|
||||||
|
psoDesc.NumRenderTargets = 1;
|
||||||
|
psoDesc.DepthStencilState = CD3DX12_DEPTH_STENCIL_DESC(D3D12_DEFAULT);
|
||||||
|
psoDesc.DSVFormat = DXGI_FORMAT_D24_UNORM_S8_UINT;
|
||||||
|
|
||||||
|
auto device = renderer->GetDevice();
|
||||||
|
|
||||||
|
|
||||||
|
if (FAILED(hr)) {
|
||||||
|
FatalError(L"Failed to create PSO");
|
||||||
|
}
|
||||||
|
|
||||||
|
ComPtr<ID3D12PipelineState> pipelineStateObject;
|
||||||
|
hr = device->CreateGraphicsPipelineState(&psoDesc, IID_PPV_ARGS(&pipelineStateObject));
|
||||||
|
pipelineStateObject->SetName(L"PSO");
|
||||||
|
|
||||||
|
|
||||||
|
pso.push_back(pipelineStateObject);
|
||||||
|
|
||||||
|
|
||||||
|
//commandList = renderer->BeginCommandList();
|
||||||
|
|
||||||
|
commandList->SetPipelineState(pipelineStateObject.Get());
|
||||||
|
|
||||||
|
commandList->SetGraphicsRootSignature(rootSignature.Get());
|
||||||
|
|
||||||
|
commandList->IASetPrimitiveTopology(D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
|
||||||
|
auto vbView = mesh->GetVertexBufferView();
|
||||||
|
|
||||||
|
commandList->IASetVertexBuffers(0, 1, &vbView);
|
||||||
|
|
||||||
|
auto ibView = submesh->GetIndexBufferView();
|
||||||
|
commandList->IASetIndexBuffer(&ibView);
|
||||||
|
|
||||||
|
//commandList->SetGraphicsRootShaderResourceView()
|
||||||
|
|
||||||
|
|
||||||
|
ID3D12DescriptorHeap* descriptorHeaps[] = { srvHeap.Get() };
|
||||||
|
commandList->SetDescriptorHeaps(_countof(descriptorHeaps), descriptorHeaps);
|
||||||
|
|
||||||
|
|
||||||
|
for (size_t p = srvParamOffset; p < srvParamOffset + srvParamCount; ++p) {
|
||||||
|
commandList->SetGraphicsRootDescriptorTable(p, srvHeap->GetGPUDescriptorHandleForHeapStart());
|
||||||
|
}
|
||||||
|
|
||||||
|
//apply constant buffers
|
||||||
|
for (size_t k = 0; k < compiled_params.buffers.size(); ++k) {
|
||||||
|
commandList->SetGraphicsRootConstantBufferView(k, compiled_params.buffers[k].buffer->GetGPUVirtualAddress());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
commandList->DrawIndexedInstanced(submesh->GetIndicesCount(), 1, 0, 0, 0);
|
||||||
|
|
||||||
|
//renderer->EndCommandList();
|
||||||
|
//renderer->WaitCommandsQueue();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//commandList = renderer->BeginCommandList();
|
||||||
|
commandList->ResourceBarrier(1, &CD3DX12_RESOURCE_BARRIER::Transition(rt.Get(), D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_PRESENT));
|
||||||
|
renderer->EndCommandList();
|
||||||
|
renderer->WaitCommandsQueue();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
renderScreen->Present();
|
||||||
|
//signatures.clear();
|
||||||
|
//renderer->reportLiveObjects();
|
||||||
|
|
||||||
|
scene->GetGizmos().PrepareRender();
|
||||||
|
scene->GetGizmos().DrawAll(camera);
|
||||||
|
scene->GetGizmos().Clear();
|
||||||
|
}
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
#pragma once
|
||||||
|
#include "LEngine.h"
|
||||||
|
#include "Mesh.h"
|
||||||
|
#include "MeshGenerator.h"
|
||||||
|
#include "Scene.h"
|
||||||
|
#include "Renderer.h"
|
||||||
|
#include "Camera.h"
|
||||||
|
#include "FatalError.h"
|
||||||
|
#include "MeshRenderer.h"
|
||||||
|
|
||||||
|
#pragma comment(lib, "d3d11.lib")
|
||||||
|
|
||||||
|
class SceneRenderer {
|
||||||
|
public:
|
||||||
|
SceneRenderer();
|
||||||
|
void RenderScene(RendererPtr renderer, ScenePtr scene, CameraPtr camera, std::shared_ptr<RenderOutput> renderScreen);
|
||||||
|
private:
|
||||||
|
ComPtr<ID3D12DescriptorHeap> samplers_heap;
|
||||||
|
};
|
||||||
|
|
||||||
@@ -0,0 +1,76 @@
|
|||||||
|
#include "Shader.h"
|
||||||
|
#include <d3dcompiler.h>
|
||||||
|
#include <fstream>
|
||||||
|
#include "File.h"
|
||||||
|
#include "LEngine.h"
|
||||||
|
#include "AssetManager.h"
|
||||||
|
#include "ShaderInclude.h"
|
||||||
|
#include <filesystem>
|
||||||
|
|
||||||
|
#pragma comment(lib, "D3dcompiler.lib")
|
||||||
|
|
||||||
|
namespace fs = std::experimental::filesystem::v1;
|
||||||
|
|
||||||
|
ComPtr<ID3DBlob> Shader::CompileSHader(const std::wstring& filename, const std::string& entry, const std::string& profile) {
|
||||||
|
std::ifstream file(filename);
|
||||||
|
if(!file.good()) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
fs::path p(filename);
|
||||||
|
auto parent = p.parent_path();
|
||||||
|
|
||||||
|
ShaderInclude inc(parent.wstring());
|
||||||
|
|
||||||
|
std::string shaderCode;
|
||||||
|
FileReadAllText(filename, shaderCode);
|
||||||
|
|
||||||
|
ComPtr<ID3DBlob> blob;
|
||||||
|
ComPtr<ID3DBlob> errorBlob;
|
||||||
|
|
||||||
|
//compile vertex shader
|
||||||
|
if(S_OK != D3DCompile(shaderCode.c_str(), shaderCode.size(), "", nullptr, &inc, entry.c_str(), profile.c_str(), D3DCOMPILE_DEBUG | D3DCOMPILE_SKIP_OPTIMIZATION, 0, &blob, &errorBlob)) {
|
||||||
|
char* ptr = (char*)errorBlob->GetBufferPointer();
|
||||||
|
throw std::exception((char*)errorBlob->GetBufferPointer());
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
return blob;
|
||||||
|
}
|
||||||
|
|
||||||
|
Shader::Shader(ComPtr<ID3D12Device> dev) :device(dev) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
ShaderPtr Shader::Create() {
|
||||||
|
return std::shared_ptr<Shader>(new Shader(LEngine::Instance()->GetRenderer()->GetDevice()));
|
||||||
|
}
|
||||||
|
|
||||||
|
ShaderPtr Shader::Create(const std::wstring& filePath) {
|
||||||
|
auto shader = Create();
|
||||||
|
shader->FromFile(AssetManager::Instance()->GetFullAssetPath(filePath));
|
||||||
|
return shader;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Shader::FromFile(const std::wstring& shaderFilePath) {
|
||||||
|
auto vsBlob = CompileSHader(shaderFilePath, "main_vs", "vs_5_0");
|
||||||
|
if(vsBlob != nullptr) {
|
||||||
|
ShaderDataPtr shader(new ShaderData());
|
||||||
|
shader->blob = vsBlob;
|
||||||
|
shaders[(int)ShaderType::Vs] = shader;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto psBlob = CompileSHader(shaderFilePath, "main_ps", "ps_5_0");
|
||||||
|
if(psBlob != nullptr) {
|
||||||
|
ShaderDataPtr shader(new ShaderData());
|
||||||
|
shader->blob = psBlob;
|
||||||
|
shaders[(int)ShaderType::Ps] = shader;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ShaderDataPtr Shader::GetShader(ShaderType type) {
|
||||||
|
return shaders[(uint32_t)type];
|
||||||
|
}
|
||||||
|
|
||||||
|
ComPtr<ID3D12Device> Shader::GetDevice() {
|
||||||
|
return device;
|
||||||
|
}
|
||||||
@@ -0,0 +1,56 @@
|
|||||||
|
#ifndef Shader_h__
|
||||||
|
#define Shader_h__
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <memory>
|
||||||
|
#include <cassert>
|
||||||
|
#include "ForwardDeclarations.h"
|
||||||
|
#include <d3d12.h>
|
||||||
|
#include <d3d11.h>
|
||||||
|
#include <wrl.h>
|
||||||
|
|
||||||
|
using namespace Microsoft::WRL;
|
||||||
|
|
||||||
|
class ShaderData {
|
||||||
|
public:
|
||||||
|
ComPtr<ID3DBlob> blob;
|
||||||
|
|
||||||
|
D3D12_SHADER_BYTECODE get_bytecode() {
|
||||||
|
D3D12_SHADER_BYTECODE bytecode = {};
|
||||||
|
bytecode.BytecodeLength = blob->GetBufferSize();
|
||||||
|
bytecode.pShaderBytecode = blob->GetBufferPointer();
|
||||||
|
return bytecode;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef std::shared_ptr<ShaderData> ShaderDataPtr;
|
||||||
|
|
||||||
|
enum class ShaderType {
|
||||||
|
Vs,
|
||||||
|
Ps,
|
||||||
|
Gs,
|
||||||
|
Hull,
|
||||||
|
Domain,
|
||||||
|
Count
|
||||||
|
};
|
||||||
|
|
||||||
|
class Shader {
|
||||||
|
public:
|
||||||
|
std::wstring class_name() const {
|
||||||
|
return L"Shader";
|
||||||
|
}
|
||||||
|
static ShaderPtr Create();
|
||||||
|
static ShaderPtr Create(const std::wstring& filePath);
|
||||||
|
void FromFile(const std::wstring& shaderFilePath);
|
||||||
|
ShaderDataPtr GetShader(ShaderType type);
|
||||||
|
ComPtr<ID3D12Device> GetDevice();
|
||||||
|
private:
|
||||||
|
Shader(ComPtr<ID3D12Device> dev);
|
||||||
|
ShaderDataPtr shaders[(uint32_t)ShaderType::Count];
|
||||||
|
ComPtr<ID3D12Device> device;
|
||||||
|
ComPtr<ID3DBlob> CompileSHader(const std::wstring& filename, const std::string& entry, const std::string& profile);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#endif // Shader_h__
|
||||||
@@ -0,0 +1,68 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <d3dcommon.h>
|
||||||
|
#include <vector>
|
||||||
|
#include <cstdint>
|
||||||
|
#include <string>
|
||||||
|
#include <codecvt>
|
||||||
|
#include <locale>
|
||||||
|
#include "File.h"
|
||||||
|
#include <memory>
|
||||||
|
#include <stack>
|
||||||
|
#include <filesystem>
|
||||||
|
|
||||||
|
namespace fs = std::experimental::filesystem::v1;
|
||||||
|
|
||||||
|
class ShaderIncludeFile {
|
||||||
|
public:
|
||||||
|
std::wstring fullPath;
|
||||||
|
std::vector<char> data;
|
||||||
|
};
|
||||||
|
|
||||||
|
class ShaderInclude : public ID3DInclude {
|
||||||
|
public:
|
||||||
|
ShaderInclude(std::wstring localDirectory){
|
||||||
|
_localPathStack.push(localDirectory);
|
||||||
|
}
|
||||||
|
|
||||||
|
STDOVERRIDEMETHODIMP Open(THIS_ D3D_INCLUDE_TYPE IncludeType, LPCSTR pFileName, LPCVOID pParentData, LPCVOID *ppData, UINT *pBytes){
|
||||||
|
std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>> converter;
|
||||||
|
std::wstring wideFileName = converter.from_bytes(pFileName);
|
||||||
|
std::wstring fullPath;
|
||||||
|
|
||||||
|
switch (IncludeType) {
|
||||||
|
case D3D_INCLUDE_LOCAL:
|
||||||
|
case D3D_INCLUDE_SYSTEM:
|
||||||
|
fullPath = _localPathStack.top() + L"/" + wideFileName;
|
||||||
|
|
||||||
|
fs::path p(fullPath);
|
||||||
|
auto parent = p.parent_path();
|
||||||
|
_localPathStack.push(parent.wstring());
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (auto& f : _files) {
|
||||||
|
if (f->fullPath == fullPath) {
|
||||||
|
throw std::exception("Circular dependency detected!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
auto file = std::make_shared<ShaderIncludeFile>();
|
||||||
|
file->fullPath = fullPath;
|
||||||
|
FileReadAllBytes(fullPath, file->data);
|
||||||
|
_files.push_back(file);
|
||||||
|
|
||||||
|
*ppData = &file->data[0];
|
||||||
|
*pBytes = file->data.size();
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
STDOVERRIDEMETHODIMP Close(THIS_ LPCVOID pData){
|
||||||
|
_localPathStack.pop();
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::stack<std::wstring> _localPathStack;
|
||||||
|
std::vector<std::shared_ptr<ShaderIncludeFile>> _files;
|
||||||
|
};
|
||||||
@@ -0,0 +1,159 @@
|
|||||||
|
#ifndef ShaderParametersBlock_h__
|
||||||
|
#define ShaderParametersBlock_h__
|
||||||
|
|
||||||
|
#include "Shader.h"
|
||||||
|
#include <vector>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <d3dcompiler.h>
|
||||||
|
#include "ForwardDeclarations.h"
|
||||||
|
#include "d3d11_types.h"
|
||||||
|
|
||||||
|
class ShaderBufferVariable {
|
||||||
|
public:
|
||||||
|
std::string name;
|
||||||
|
uint32_t offset;
|
||||||
|
uint32_t size;
|
||||||
|
|
||||||
|
ShaderBufferVariable() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
ShaderBufferVariable(const std::string& _name, uint32_t _offset, uint32_t _size)
|
||||||
|
:name(_name), size(_size), offset(_offset){
|
||||||
|
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class ShaderResourceVariable {
|
||||||
|
public:
|
||||||
|
std::string name;
|
||||||
|
uint32_t bindPoint;
|
||||||
|
D3D_SHADER_INPUT_TYPE type;
|
||||||
|
};
|
||||||
|
|
||||||
|
class ShaderBufferContext {
|
||||||
|
public:
|
||||||
|
ID3D12ResourcePtr buffer;
|
||||||
|
size_t size;
|
||||||
|
std::vector<ShaderBufferVariable> variables;
|
||||||
|
std::string name;
|
||||||
|
uint32_t bindPoint;
|
||||||
|
D3D_SHADER_INPUT_TYPE type;
|
||||||
|
};
|
||||||
|
|
||||||
|
class ShaderParametersContext {
|
||||||
|
public:
|
||||||
|
void Clear() {
|
||||||
|
buffers.clear();
|
||||||
|
resources.clear();
|
||||||
|
}
|
||||||
|
std::vector<ShaderBufferContext> buffers;
|
||||||
|
std::vector<ShaderResourceVariable> resources;
|
||||||
|
};
|
||||||
|
|
||||||
|
class ShaderParameter {
|
||||||
|
public:
|
||||||
|
virtual ~ShaderParameter()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
ShaderParameter(const std::string& _name) :name(_name) {
|
||||||
|
|
||||||
|
}
|
||||||
|
virtual void* GetPointer() = 0;
|
||||||
|
std::string name;
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef std::shared_ptr<ShaderParameter> ShaderParameterPtr;
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
class ShaderValueParameter : public ShaderParameter {
|
||||||
|
public:
|
||||||
|
ShaderValueParameter(const std::string& _name) :ShaderParameter(_name)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
void* GetPointer() override {
|
||||||
|
return &value;
|
||||||
|
}
|
||||||
|
T value;
|
||||||
|
};
|
||||||
|
|
||||||
|
class ShaderResourceParameter : public ShaderParameter {
|
||||||
|
public:
|
||||||
|
ShaderResourceParameter(const std::string& _name) :ShaderParameter(_name) {
|
||||||
|
|
||||||
|
}
|
||||||
|
ShaderResourceParameter(const std::string& _name, ID3D11ShaderResourceViewPtr view) : value(view), ShaderParameter(_name) {
|
||||||
|
name = _name;
|
||||||
|
}
|
||||||
|
ID3D11ShaderResourceViewPtr value;
|
||||||
|
void* GetPointer() override {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class ShaderTextureParameter : public ShaderParameter {
|
||||||
|
public:
|
||||||
|
ShaderTextureParameter(const std::string& _name) :ShaderParameter(_name) {
|
||||||
|
|
||||||
|
}
|
||||||
|
ShaderTextureParameter(const std::string& _name, TexturePtr view) : ShaderParameter(_name), value(view){
|
||||||
|
name = _name;
|
||||||
|
}
|
||||||
|
TexturePtr value;
|
||||||
|
void* GetPointer() override {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef std::shared_ptr<ShaderResourceParameter> ShaderResourceParameterPtr;
|
||||||
|
typedef std::shared_ptr<ShaderTextureParameter> ShaderTextureParameterPtr;
|
||||||
|
|
||||||
|
class ShaderParametersBlock {
|
||||||
|
public:
|
||||||
|
void SetTexture(const std::string& name, TexturePtr texture) {
|
||||||
|
/*ID3D11ResourcePtr resourcePtr;
|
||||||
|
|
||||||
|
D3D11_TEXTURE2D_DESC desc;
|
||||||
|
texture->GetDesc(&desc);
|
||||||
|
texture.QueryInterface(&resourcePtr);
|
||||||
|
SetShaderResource(name, resourcePtr);*/
|
||||||
|
|
||||||
|
ShaderTextureParameterPtr parameter(new ShaderTextureParameter(name, texture));
|
||||||
|
for (auto it = parameters.begin(); it != parameters.end(); ++it) {
|
||||||
|
if ((*it)->name == name) {
|
||||||
|
*it = parameter;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
parameters.push_back(parameter);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
void SetValue(const std::string& name, const T& value) {
|
||||||
|
std::shared_ptr<ShaderValueParameter<T>> param(new ShaderValueParameter<T>(name));
|
||||||
|
param->value = value;
|
||||||
|
for (auto it = parameters.begin(); it != parameters.end(); ++it) {
|
||||||
|
if ((*it)->name == name) {
|
||||||
|
*it = param;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
parameters.push_back(param);
|
||||||
|
}
|
||||||
|
|
||||||
|
ShaderParameterPtr GetParameterByName(const std::string& name) {
|
||||||
|
for (auto p : parameters) {
|
||||||
|
if (p->name == name) {
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
private:
|
||||||
|
std::vector<ShaderParameterPtr> parameters;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // ShaderParametersBlock_h__
|
||||||
@@ -0,0 +1,118 @@
|
|||||||
|
#ifndef Submesh_h__
|
||||||
|
#define Submesh_h__
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
#include "LEngine.h"
|
||||||
|
#include "d3d11_types.h"
|
||||||
|
#include <memory>
|
||||||
|
#include "d3dx12.h"
|
||||||
|
|
||||||
|
enum class MeshTopology {
|
||||||
|
TriangleList,
|
||||||
|
TriangleStrip,
|
||||||
|
LineList,
|
||||||
|
LineStrip
|
||||||
|
};
|
||||||
|
|
||||||
|
class Submesh {
|
||||||
|
public:
|
||||||
|
typedef uint32_t index_count_t;
|
||||||
|
typedef uint32_t index_t;
|
||||||
|
typedef std::vector<index_t> index_array_t;
|
||||||
|
|
||||||
|
Submesh()
|
||||||
|
:_indexCount(0)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
ID3D12ResourcePtr GetIndexBuffer() const{
|
||||||
|
return _indexBuffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
MeshTopology GetTopology() const{
|
||||||
|
return _topology;
|
||||||
|
}
|
||||||
|
|
||||||
|
D3D12_INDEX_BUFFER_VIEW GetIndexBufferView()
|
||||||
|
{
|
||||||
|
return _indexBufferView;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Set(index_array_t indices, MeshTopology topology) {
|
||||||
|
_indexCount = indices.size();
|
||||||
|
_topology = topology;
|
||||||
|
_indexBuffer = nullptr;
|
||||||
|
|
||||||
|
if (_indexCount == 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
D3D11_BUFFER_DESC desc = { 0 };
|
||||||
|
D3D11_SUBRESOURCE_DATA data = { 0 };
|
||||||
|
|
||||||
|
//index buffer
|
||||||
|
desc.Usage = D3D11_USAGE_DEFAULT;
|
||||||
|
desc.ByteWidth = sizeof(indices[0]) * indices.size();
|
||||||
|
desc.BindFlags = D3D11_BIND_INDEX_BUFFER;
|
||||||
|
desc.CPUAccessFlags = 0;
|
||||||
|
desc.MiscFlags = 0;
|
||||||
|
|
||||||
|
data.pSysMem = &indices[0];
|
||||||
|
data.SysMemPitch = 0;
|
||||||
|
data.SysMemSlicePitch = 0;
|
||||||
|
|
||||||
|
auto renderer = LEngine::Instance()->GetRenderer();
|
||||||
|
auto device = renderer->GetDevice();
|
||||||
|
auto cmdList = renderer->BeginCommandList();
|
||||||
|
|
||||||
|
//create temporal upload resource
|
||||||
|
ComPtr<ID3D12Resource> uploadBuffer;
|
||||||
|
device->CreateCommittedResource(&CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_UPLOAD),
|
||||||
|
D3D12_HEAP_FLAG_ALLOW_ALL_BUFFERS_AND_TEXTURES,
|
||||||
|
&CD3DX12_RESOURCE_DESC::Buffer(desc.ByteWidth),
|
||||||
|
D3D12_RESOURCE_STATE_GENERIC_READ, nullptr, IID_PPV_ARGS(&uploadBuffer));
|
||||||
|
|
||||||
|
|
||||||
|
//upload data to temporal resource
|
||||||
|
void* p;
|
||||||
|
uploadBuffer->Map(0, nullptr, &p);
|
||||||
|
memcpy(p, &indices[0], desc.ByteWidth);
|
||||||
|
uploadBuffer->Unmap(0, nullptr);
|
||||||
|
|
||||||
|
device->CreateCommittedResource(&CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_DEFAULT),
|
||||||
|
D3D12_HEAP_FLAG_NONE,
|
||||||
|
&CD3DX12_RESOURCE_DESC::Buffer(desc.ByteWidth),
|
||||||
|
D3D12_RESOURCE_STATE_COPY_DEST,
|
||||||
|
nullptr,
|
||||||
|
IID_PPV_ARGS(&_indexBuffer));
|
||||||
|
|
||||||
|
|
||||||
|
_indexBufferView.BufferLocation = _indexBuffer->GetGPUVirtualAddress();
|
||||||
|
_indexBufferView.SizeInBytes = desc.ByteWidth;
|
||||||
|
_indexBufferView.Format = DXGI_FORMAT_R32_UINT;
|
||||||
|
|
||||||
|
|
||||||
|
cmdList->CopyBufferRegion(_indexBuffer.Get(), 0, uploadBuffer.Get(), 0, desc.ByteWidth);
|
||||||
|
|
||||||
|
CD3DX12_RESOURCE_BARRIER barriers[1] = {
|
||||||
|
CD3DX12_RESOURCE_BARRIER::Transition(_indexBuffer.Get(),
|
||||||
|
D3D12_RESOURCE_STATE_COPY_DEST, D3D12_RESOURCE_STATE_INDEX_BUFFER)
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
cmdList->ResourceBarrier(1, barriers);
|
||||||
|
renderer->EndCommandList();
|
||||||
|
renderer->WaitCommandsQueue();
|
||||||
|
}
|
||||||
|
index_count_t GetIndicesCount() const {
|
||||||
|
return _indexCount;
|
||||||
|
}
|
||||||
|
private:
|
||||||
|
index_count_t _indexCount;
|
||||||
|
MeshTopology _topology;
|
||||||
|
ID3D12ResourcePtr _indexBuffer;
|
||||||
|
D3D12_INDEX_BUFFER_VIEW _indexBufferView;
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef std::shared_ptr<Submesh> SubmeshPtr;
|
||||||
|
#endif // Submesh_h__
|
||||||
@@ -0,0 +1,124 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "RenderOutput.h"
|
||||||
|
#include "d3d11_types.h"
|
||||||
|
#include "Renderer.h"
|
||||||
|
#include "d3dx12.h"
|
||||||
|
|
||||||
|
|
||||||
|
class SwapChainOutput : public RenderOutput {
|
||||||
|
public:
|
||||||
|
SwapChainOutput(RendererPtr renderer, HWND window, uint32_t width, uint32_t height, bool stereo) : _activeBuffer(0){
|
||||||
|
_buffersCount = 2;
|
||||||
|
_swapChain = renderer->CreateSwapChain(window, true, width, height, _buffersCount, stereo);
|
||||||
|
auto device = renderer->GetDevice();
|
||||||
|
|
||||||
|
//create RTV descriptors heap
|
||||||
|
D3D12_DESCRIPTOR_HEAP_DESC heap_desc = {};
|
||||||
|
heap_desc.NumDescriptors = _buffersCount;
|
||||||
|
heap_desc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_RTV;
|
||||||
|
heap_desc.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_NONE;
|
||||||
|
|
||||||
|
HR_ASSERT_MSG(device->CreateDescriptorHeap(&heap_desc, IID_PPV_ARGS(&rtvDescriptorHeap)), L"Failed to allocate RTV descriptors heap");
|
||||||
|
rtvDescriptorHeap->SetName(L"RTV Heap");
|
||||||
|
|
||||||
|
rtvDescSize = device->GetDescriptorHandleIncrementSize(D3D12_DESCRIPTOR_HEAP_TYPE_RTV);
|
||||||
|
CD3DX12_CPU_DESCRIPTOR_HANDLE rtvHandle(rtvDescriptorHeap->GetCPUDescriptorHandleForHeapStart());
|
||||||
|
|
||||||
|
|
||||||
|
//create DSV descriptors heap
|
||||||
|
heap_desc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_DSV;
|
||||||
|
HR_ASSERT_MSG(device->CreateDescriptorHeap(&heap_desc, IID_PPV_ARGS(&dsvDescriptorHeap)), L"Failed to allocate DSV descriptors heap");
|
||||||
|
dsvDescriptorHeap->SetName(L"DSV Heap");
|
||||||
|
|
||||||
|
dsvDescSize = device->GetDescriptorHandleIncrementSize(D3D12_DESCRIPTOR_HEAP_TYPE_DSV);
|
||||||
|
CD3DX12_CPU_DESCRIPTOR_HANDLE dsvHandle(dsvDescriptorHeap->GetCPUDescriptorHandleForHeapStart());
|
||||||
|
|
||||||
|
for(uint32_t i = 0; i < _buffersCount; ++i){
|
||||||
|
//get back buffer
|
||||||
|
ID3D12ResourcePtr _backBuffer;
|
||||||
|
if (FAILED(_swapChain->GetBuffer(i, IID_PPV_ARGS(&_backBuffer)))){
|
||||||
|
FatalError(TEXT("Failed to get swap chain's bffer"));
|
||||||
|
}
|
||||||
|
device->CreateRenderTargetView(_backBuffer.Get(), nullptr, rtvHandle);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//create depth buffer
|
||||||
|
D3D12_CLEAR_VALUE depthOptimizedClearValue = {};
|
||||||
|
depthOptimizedClearValue.Format = DXGI_FORMAT_D24_UNORM_S8_UINT;
|
||||||
|
depthOptimizedClearValue.DepthStencil.Depth = 1.0f;
|
||||||
|
depthOptimizedClearValue.DepthStencil.Stencil = 0;
|
||||||
|
|
||||||
|
ComPtr<ID3D12Resource> depthStencilBuffer;
|
||||||
|
device->CreateCommittedResource(
|
||||||
|
&CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_DEFAULT),
|
||||||
|
D3D12_HEAP_FLAG_NONE,
|
||||||
|
&CD3DX12_RESOURCE_DESC::Tex2D(DXGI_FORMAT_D24_UNORM_S8_UINT, width, height, 1, 0, 1, 0, D3D12_RESOURCE_FLAG_ALLOW_DEPTH_STENCIL),
|
||||||
|
D3D12_RESOURCE_STATE_DEPTH_WRITE,
|
||||||
|
&depthOptimizedClearValue,
|
||||||
|
IID_PPV_ARGS(&depthStencilBuffer)
|
||||||
|
);
|
||||||
|
|
||||||
|
device->CreateDepthStencilView(depthStencilBuffer.Get(), nullptr, dsvHandle);
|
||||||
|
|
||||||
|
rtvHandle.Offset(1, rtvDescSize);
|
||||||
|
dsvHandle.Offset(1, dsvDescSize);
|
||||||
|
_buffers.push_back({ _backBuffer, depthStencilBuffer });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
virtual uint32_t GetWidth() override{
|
||||||
|
return GetDesc().Width;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual uint32_t GetHeight() override
|
||||||
|
{
|
||||||
|
return GetDesc().Height;
|
||||||
|
}
|
||||||
|
|
||||||
|
CD3DX12_CPU_DESCRIPTOR_HANDLE GetRenderTargetDescriptor(uint32_t id) override {
|
||||||
|
return CD3DX12_CPU_DESCRIPTOR_HANDLE(rtvDescriptorHeap->GetCPUDescriptorHandleForHeapStart(), id, rtvDescSize);
|
||||||
|
}
|
||||||
|
CD3DX12_CPU_DESCRIPTOR_HANDLE GetDepthStencilDescriptor(uint32_t id) override {
|
||||||
|
return CD3DX12_CPU_DESCRIPTOR_HANDLE(dsvDescriptorHeap->GetCPUDescriptorHandleForHeapStart(), id, dsvDescSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
ID3D12ResourcePtr GetRenderTarget(uint32_t id) override{
|
||||||
|
return _buffers[id].first;
|
||||||
|
}
|
||||||
|
|
||||||
|
ID3D12ResourcePtr GetDepthBuffer(uint32_t id) override {
|
||||||
|
return _buffers[id].second;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void Present() override{
|
||||||
|
_swapChain->Present(0, 0);
|
||||||
|
_activeBuffer = (_activeBuffer + 1) % _buffersCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void OnPreRender(RendererPtr renderer) override{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
DXGI_SWAP_CHAIN_DESC1 GetDesc() {
|
||||||
|
DXGI_SWAP_CHAIN_DESC1 desc;
|
||||||
|
_swapChain->GetDesc1(&desc);
|
||||||
|
return desc;
|
||||||
|
}
|
||||||
|
uint32_t GetCurrentBufferIndex() override{
|
||||||
|
return _activeBuffer;
|
||||||
|
}
|
||||||
|
uint32_t GetBuffersCount() override{
|
||||||
|
return _buffersCount;
|
||||||
|
}
|
||||||
|
private:
|
||||||
|
std::vector<std::pair<ID3D12ResourcePtr, ID3D12ResourcePtr>> _buffers;
|
||||||
|
uint32_t _activeBuffer;
|
||||||
|
uint32_t _buffersCount;
|
||||||
|
UINT rtvDescSize;
|
||||||
|
UINT dsvDescSize;
|
||||||
|
ComPtr<ID3D12DescriptorHeap> rtvDescriptorHeap;
|
||||||
|
ComPtr<ID3D12DescriptorHeap> dsvDescriptorHeap;
|
||||||
|
IDXGISwapChain1Ptr _swapChain;
|
||||||
|
|
||||||
|
};
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
#ifndef Texture_h__
|
||||||
|
#define Texture_h__
|
||||||
|
|
||||||
|
#include <d3d12.h>
|
||||||
|
#include "d3d11_types.h"
|
||||||
|
|
||||||
|
class Texture
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Texture(ID3D12ResourcePtr _resource, D3D12_CPU_DESCRIPTOR_HANDLE _srvDescriptor)
|
||||||
|
:resource(_resource), srvDescriptor(_srvDescriptor)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
ID3D12ResourcePtr resource;
|
||||||
|
D3D12_CPU_DESCRIPTOR_HANDLE srvDescriptor;
|
||||||
|
};
|
||||||
|
#endif // Texture_h__
|
||||||
@@ -0,0 +1,33 @@
|
|||||||
|
#ifndef TextureImporter_h__
|
||||||
|
#define TextureImporter_h__
|
||||||
|
|
||||||
|
#include "AssetImporter.h"
|
||||||
|
#include <filesystem>
|
||||||
|
|
||||||
|
/*
|
||||||
|
class TextureImporter : public AssetImporter {
|
||||||
|
public:
|
||||||
|
virtual bool can_import(const std::wstring& path) const override {
|
||||||
|
std::tr2::sys::path file_path(path);
|
||||||
|
if (!file_path.has_extension()) {
|
||||||
|
return false;
|
||||||
|
} else {
|
||||||
|
return file_path.extension() == ".bmp";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual bool load_parameters(const std::wstring& params) override {
|
||||||
|
throw std::logic_error("The method or operation is not implemented.");
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual std::wstring save_parameters() override {
|
||||||
|
throw std::logic_error("The method or operation is not implemented.");
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual std::wstring name() override {
|
||||||
|
return L"TextureImporter";
|
||||||
|
}
|
||||||
|
|
||||||
|
};*/
|
||||||
|
|
||||||
|
#endif // TextureImporter_h__
|
||||||
@@ -0,0 +1,94 @@
|
|||||||
|
#ifndef Transform_h__
|
||||||
|
#define Transform_h__
|
||||||
|
|
||||||
|
#include "lmath.h"
|
||||||
|
#include "Mathf.h"
|
||||||
|
#include "ObjectsFactory.h"
|
||||||
|
#include "Component.h"
|
||||||
|
#include "Archive.h"
|
||||||
|
|
||||||
|
using namespace lm;
|
||||||
|
|
||||||
|
LOBJECT(Transform, Component)
|
||||||
|
public:
|
||||||
|
std::shared_ptr<Transform> parent;
|
||||||
|
Quaternion_f _rotation;
|
||||||
|
float3 _position;
|
||||||
|
float3 _scale;
|
||||||
|
|
||||||
|
Transform()
|
||||||
|
:_scale(1.0f,1.0f,1.0f), _position(0.0f,0.0f,0.0f), _rotation(0.0f,0.0f,0.0f,1.0f){
|
||||||
|
}
|
||||||
|
|
||||||
|
void serialize(Archive& archive) override{
|
||||||
|
Component::serialize(archive);
|
||||||
|
archive << parent;
|
||||||
|
archive << _rotation << _position << _scale;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::wstring class_name() const {
|
||||||
|
return L"Transform";
|
||||||
|
}
|
||||||
|
|
||||||
|
void SetLocalPosition(const float3& position) {
|
||||||
|
_position = position;
|
||||||
|
}
|
||||||
|
float3 GetLocalPosition() {
|
||||||
|
return _position;
|
||||||
|
}
|
||||||
|
|
||||||
|
float3 forward() const{
|
||||||
|
return GetGlobalTransform().z().xyz();
|
||||||
|
}
|
||||||
|
|
||||||
|
float3 right() const {
|
||||||
|
return GetGlobalTransform().x().xyz();
|
||||||
|
}
|
||||||
|
|
||||||
|
float3 up() const {
|
||||||
|
return GetGlobalTransform().y().xyz();
|
||||||
|
}
|
||||||
|
|
||||||
|
void SetLocalRotation(const Quaternion_f& rotation) {
|
||||||
|
_rotation = rotation;
|
||||||
|
}
|
||||||
|
|
||||||
|
Quaternion_f GetLocalRotation() {
|
||||||
|
return _rotation;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SetLocalScale(const float3& scale) {
|
||||||
|
_scale = scale;
|
||||||
|
}
|
||||||
|
|
||||||
|
float3 GetLocalScale() {
|
||||||
|
return _scale;
|
||||||
|
}
|
||||||
|
|
||||||
|
float4x4 GetLocalTransform() const{
|
||||||
|
auto scaleMatrix = matrix4x4Scale(_scale);
|
||||||
|
auto rotationMatrix = matrix4x4RotationQuaternion(_rotation);
|
||||||
|
auto positionMatrix = matrix4x4Translation(_position);
|
||||||
|
return lm::mul(lm::mul(scaleMatrix, rotationMatrix), positionMatrix);
|
||||||
|
}
|
||||||
|
|
||||||
|
float4x4 GetGlobalTransform() const{
|
||||||
|
if(parent == nullptr) {
|
||||||
|
return GetLocalTransform();
|
||||||
|
}
|
||||||
|
return lm::mul(GetLocalTransform(), parent->GetGlobalTransform());
|
||||||
|
}
|
||||||
|
|
||||||
|
float3 GetGlobalPosition() {
|
||||||
|
auto tf = GetGlobalTransform();
|
||||||
|
return float3(tf[0][3], tf[1][3], tf[2][3]);
|
||||||
|
}
|
||||||
|
|
||||||
|
void RotateLocal(const Quaternion_f& rotation) {
|
||||||
|
_rotation = lm::mul(_rotation, rotation);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#endif // Transform_h__
|
||||||
@@ -0,0 +1,27 @@
|
|||||||
|
#ifndef Vertex_h__
|
||||||
|
#define Vertex_h__
|
||||||
|
|
||||||
|
#include "lmath.h"
|
||||||
|
|
||||||
|
using namespace lm;
|
||||||
|
struct Vertex {
|
||||||
|
float4 position;
|
||||||
|
float3 normal;
|
||||||
|
float2 uv0;
|
||||||
|
float2 uv1;
|
||||||
|
|
||||||
|
Vertex() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
Vertex(float4 _pos, float3 _norm) {
|
||||||
|
position = _pos;
|
||||||
|
normal = _norm;
|
||||||
|
}
|
||||||
|
Vertex(float4 _pos, float3 _norm, float2 _uv0) {
|
||||||
|
position = _pos;
|
||||||
|
normal = _norm;
|
||||||
|
uv0 = _uv0;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
#endif // Vertex_h__
|
||||||
@@ -0,0 +1,242 @@
|
|||||||
|
#include "WindowRenderOutput.h"
|
||||||
|
#include <d3d11.h>
|
||||||
|
#include <dxgi.h>
|
||||||
|
#include <dxgi1_2.h>
|
||||||
|
#include "LEngine.h"
|
||||||
|
/*
|
||||||
|
std::vector<DXGI_MODE_DESC1> GetDisplayModes(DXGI_FORMAT format, CComPtr<IDXGIOutput1> output) {
|
||||||
|
std::vector<DXGI_MODE_DESC1> result;
|
||||||
|
UINT numStereoModes = 0;
|
||||||
|
DXGI_MODE_DESC1 modes[1024];
|
||||||
|
auto enumFlags = DXGI_ENUM_MODES_STEREO;
|
||||||
|
|
||||||
|
output->GetDisplayModeList1(format, enumFlags, &numStereoModes, 0);
|
||||||
|
output->GetDisplayModeList1(format, enumFlags, &numStereoModes, modes);
|
||||||
|
|
||||||
|
for (UINT i = 0; i < numStereoModes; ++i) {
|
||||||
|
result.push_back(modes[i]);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<DXGI_MODE_DESC1> GetStereoModes(std::vector<DXGI_MODE_DESC1>& modes) {
|
||||||
|
std::vector<DXGI_MODE_DESC1> result;
|
||||||
|
for (auto& m : modes) {
|
||||||
|
if (m.Stereo) {
|
||||||
|
result.push_back(m);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<DXGI_MODE_DESC1> GetModesByResolution(std::vector<DXGI_MODE_DESC1>& modes, UINT width, UINT height) {
|
||||||
|
std::vector<DXGI_MODE_DESC1> result;
|
||||||
|
for (auto& m : modes) {
|
||||||
|
if (m.Width == width && m.Height == height) {
|
||||||
|
result.push_back(m);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool FindModeByRefreshRate(UINT targetRate, std::vector<DXGI_MODE_DESC1>& modes, DXGI_MODE_DESC1& mode) {
|
||||||
|
for (auto& m : modes) {
|
||||||
|
auto refreshRate = m.RefreshRate.Numerator / m.RefreshRate.Denominator;
|
||||||
|
int range = 2;
|
||||||
|
//test if in range
|
||||||
|
if ((refreshRate >= (targetRate - range)) && (refreshRate <= (targetRate + range))) {
|
||||||
|
mode = m;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
WindowRenderOutput::WindowRenderOutput(){
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
WindowRenderOutput::~WindowRenderOutput()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
Window& WindowRenderOutput::GetWindow() {
|
||||||
|
return _window;
|
||||||
|
}
|
||||||
|
|
||||||
|
void WindowRenderOutput::Init(){
|
||||||
|
_window.Init();*/
|
||||||
|
/*NettleDisplayManager::EDID edid;
|
||||||
|
NettleDisplayManager::ReadEdidForDxgiOutput(vOutputs[0], edid);
|
||||||
|
auto& mainEdidBlock = edid.GetMainBlock();
|
||||||
|
|
||||||
|
auto hSize = mainEdidBlock.detailedTimingDescriptions.detailedTimingDescription1.horizontalBlanking.GetActivePixels();
|
||||||
|
auto vSize = mainEdidBlock.detailedTimingDescriptions.detailedTimingDescription1.verticalBlanking.GetActivePixels();*/
|
||||||
|
/*
|
||||||
|
auto hSize = 640;
|
||||||
|
auto vSize = 480;
|
||||||
|
|
||||||
|
auto backBufferFormat = DXGI_FORMAT_B8G8R8A8_UNORM;
|
||||||
|
|
||||||
|
CComPtr<IDXGIOutput> pOutput;
|
||||||
|
std::vector<CComPtr<IDXGIOutput>> vOutputs;
|
||||||
|
int outputId = 0;
|
||||||
|
while (LEngine::Instance()->GetRenderer()->GetAdapter()->EnumOutputs(outputId, &pOutput) != DXGI_ERROR_NOT_FOUND) {
|
||||||
|
vOutputs.push_back(pOutput);
|
||||||
|
pOutput = nullptr;
|
||||||
|
++outputId;
|
||||||
|
}
|
||||||
|
|
||||||
|
DXGI_OUTPUT_DESC desc;
|
||||||
|
vOutputs[0]->GetDesc(&desc);
|
||||||
|
_output = vOutputs[0];
|
||||||
|
|
||||||
|
CComPtr<IDXGIOutput1> testOutput;
|
||||||
|
vOutputs[0].QueryInterface(&testOutput);
|
||||||
|
auto displayModes = GetDisplayModes(backBufferFormat, testOutput);
|
||||||
|
//auto stereoModes = GetModesByResolution(GetStereoModes(displayModes), 1920, 1080);
|
||||||
|
auto stereoModes = GetModesByResolution(displayModes, hSize, vSize);
|
||||||
|
|
||||||
|
DXGI_MODE_DESC1 targetMode = { 0 };
|
||||||
|
if (!FindModeByRefreshRate(60, stereoModes, targetMode)) {
|
||||||
|
FatalError(TEXT("Failed to find 1920 x 1080 stereo 60Hz mode!"));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Allocate a descriptor.
|
||||||
|
DXGI_SWAP_CHAIN_DESC1 swapChainDesc = { 0 };
|
||||||
|
swapChainDesc.Width = targetMode.Width;
|
||||||
|
swapChainDesc.Height = targetMode.Height;
|
||||||
|
swapChainDesc.Format = targetMode.Format;
|
||||||
|
swapChainDesc.Stereo = targetMode.Stereo;
|
||||||
|
swapChainDesc.SampleDesc.Count = 1;
|
||||||
|
swapChainDesc.SampleDesc.Quality = 0;
|
||||||
|
swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
|
||||||
|
swapChainDesc.BufferCount = 1;
|
||||||
|
swapChainDesc.Scaling = DXGI_SCALING_STRETCH;
|
||||||
|
swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_DISCARD;
|
||||||
|
swapChainDesc.Flags = 0;
|
||||||
|
|
||||||
|
DXGI_SWAP_CHAIN_FULLSCREEN_DESC fullscreenDesc = { 0 };
|
||||||
|
fullscreenDesc.RefreshRate = targetMode.RefreshRate;
|
||||||
|
fullscreenDesc.ScanlineOrdering = targetMode.ScanlineOrdering;
|
||||||
|
fullscreenDesc.Scaling = targetMode.Scaling;
|
||||||
|
fullscreenDesc.Windowed = TRUE;
|
||||||
|
|
||||||
|
//create swap chain
|
||||||
|
if (S_OK != LEngine::Instance()->GetRenderer()->GetFactory()->CreateSwapChainForHwnd(LEngine::Instance()->GetRenderer()->GetDevice(), _window.GetHwnd(), &swapChainDesc, &fullscreenDesc, nullptr, &_swapChain)) {
|
||||||
|
FatalError(TEXT("Failed to create swap chain"));
|
||||||
|
}
|
||||||
|
|
||||||
|
//get back buffer
|
||||||
|
|
||||||
|
_swapChain->GetBuffer(0, IID_PPV_ARGS(&_backBuffer));
|
||||||
|
|
||||||
|
//left eye
|
||||||
|
|
||||||
|
CD3D11_RENDER_TARGET_VIEW_DESC renderTargetViewDescLeft(D3D11_RTV_DIMENSION_TEXTURE2DARRAY, DXGI_FORMAT_B8G8R8A8_UNORM, 0, 0, 1);
|
||||||
|
if (S_OK != LEngine::Instance()->GetRenderer()->GetDevice()->CreateRenderTargetView(_backBuffer, &renderTargetViewDescLeft, &_leftRtv)) {
|
||||||
|
FatalError(TEXT("Failed to create left eye RTV"));
|
||||||
|
}
|
||||||
|
|
||||||
|
bool forceStereo = false;
|
||||||
|
|
||||||
|
|
||||||
|
D3D11_TEXTURE2D_DESC descDepth;
|
||||||
|
descDepth.Width = swapChainDesc.Width;
|
||||||
|
descDepth.Height = swapChainDesc.Height;
|
||||||
|
descDepth.MipLevels = 1;
|
||||||
|
descDepth.ArraySize = 1;
|
||||||
|
descDepth.Format = DXGI_FORMAT_D24_UNORM_S8_UINT;
|
||||||
|
descDepth.SampleDesc.Count = 1;
|
||||||
|
descDepth.SampleDesc.Quality = 0;
|
||||||
|
descDepth.Usage = D3D11_USAGE_DEFAULT;
|
||||||
|
descDepth.BindFlags = D3D11_BIND_DEPTH_STENCIL;
|
||||||
|
descDepth.CPUAccessFlags = 0;
|
||||||
|
descDepth.MiscFlags = 0;
|
||||||
|
auto hr = LEngine::Instance()->GetRenderer()->GetDevice()->CreateTexture2D(&descDepth, NULL, &_depthBuffer);
|
||||||
|
|
||||||
|
LEngine::Instance()->GetRenderer()->GetDevice()->CreateDepthStencilView(_depthBuffer, nullptr, &_depthStencilView);
|
||||||
|
*/
|
||||||
|
//right eye
|
||||||
|
/*CD3D11_RENDER_TARGET_VIEW_DESC renderTargetViewDescRight(D3D11_RTV_DIMENSION_TEXTURE2DARRAY, DXGI_FORMAT_B8G8R8A8_UNORM, 0, 1, 1);
|
||||||
|
if(S_OK != device->CreateRenderTargetView(backBuffer, &renderTargetViewDescRight, &rightRtv)) {
|
||||||
|
if(forceStereo) {
|
||||||
|
FatalError(TEXT("Failed to create right eye RTV"));
|
||||||
|
} else {
|
||||||
|
rightRtv = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
}*//*
|
||||||
|
}
|
||||||
|
|
||||||
|
ID3D11DepthStencilViewPtr WindowRenderOutput::GetDepthStencilView() {
|
||||||
|
return _depthStencilView;
|
||||||
|
}
|
||||||
|
|
||||||
|
void WindowRenderOutput::Update() {
|
||||||
|
_window.ProcessMessages();
|
||||||
|
}
|
||||||
|
|
||||||
|
void WindowRenderOutput::OnPreRender(RendererPtr renderer){
|
||||||
|
uint32_t w, h;
|
||||||
|
_window.GetWindowSize(w, h);
|
||||||
|
D3D11_TEXTURE2D_DESC desc;
|
||||||
|
_backBuffer->GetDesc(&desc);
|
||||||
|
|
||||||
|
if (desc.Width != w || desc.Height != h) {
|
||||||
|
_backBuffer = nullptr;
|
||||||
|
_leftRtv = nullptr;
|
||||||
|
_rightRtv = nullptr;
|
||||||
|
auto hr = _swapChain->ResizeBuffers(0, w, h, DXGI_FORMAT_UNKNOWN, 0);
|
||||||
|
if (hr != S_OK) {
|
||||||
|
assert(false && "Can't resize BB");
|
||||||
|
}
|
||||||
|
|
||||||
|
_swapChain->GetBuffer(0, IID_PPV_ARGS(&_backBuffer));
|
||||||
|
|
||||||
|
//left eye
|
||||||
|
CD3D11_RENDER_TARGET_VIEW_DESC renderTargetViewDescLeft(D3D11_RTV_DIMENSION_TEXTURE2DARRAY, DXGI_FORMAT_B8G8R8A8_UNORM, 0, 0, 1);
|
||||||
|
if (S_OK != renderer->GetDevice()->CreateRenderTargetView(_backBuffer, &renderTargetViewDescLeft, &_leftRtv)) {
|
||||||
|
FatalError(TEXT("Failed to create left eye RTV"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
D3D11_VIEWPORT viewport;
|
||||||
|
ZeroMemory(&viewport, sizeof(D3D11_VIEWPORT));
|
||||||
|
|
||||||
|
viewport.TopLeftX = 0;
|
||||||
|
viewport.TopLeftY = 0;
|
||||||
|
viewport.Width = (float)w;
|
||||||
|
viewport.Height = (float)h;
|
||||||
|
viewport.MinDepth = 0;
|
||||||
|
viewport.MaxDepth = 1;
|
||||||
|
|
||||||
|
renderer->GetImmediateContext()->RSSetViewports(1, &viewport);
|
||||||
|
}
|
||||||
|
|
||||||
|
void WindowRenderOutput::Present() {
|
||||||
|
DXGI_PRESENT_PARAMETERS parameters = { 0 };
|
||||||
|
parameters.DirtyRectsCount = 0;
|
||||||
|
parameters.pDirtyRects = nullptr;
|
||||||
|
parameters.pScrollRect = nullptr;
|
||||||
|
parameters.pScrollOffset = nullptr;
|
||||||
|
HRESULT hr = _swapChain->Present1(0, 0, ¶meters);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t WindowRenderOutput::GetWidth(){
|
||||||
|
D3D11_TEXTURE2D_DESC desc;
|
||||||
|
_backBuffer->GetDesc(&desc);
|
||||||
|
return desc.Width;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t WindowRenderOutput::GetHeight(){
|
||||||
|
D3D11_TEXTURE2D_DESC desc;
|
||||||
|
_backBuffer->GetDesc(&desc);
|
||||||
|
return desc.Height;
|
||||||
|
}
|
||||||
|
|
||||||
|
CComPtr<ID3D11RenderTargetView> WindowRenderOutput::GetRenderTargetView(){
|
||||||
|
return _leftRtv;
|
||||||
|
}
|
||||||
|
*/
|
||||||
@@ -0,0 +1,32 @@
|
|||||||
|
#ifndef WindowScreen_h__
|
||||||
|
#define WindowScreen_h__
|
||||||
|
/*
|
||||||
|
#include "RenderOutput.h"
|
||||||
|
#include "Renderer.h"
|
||||||
|
#include "d3d11_types.h"
|
||||||
|
|
||||||
|
class WindowRenderOutput : public RenderOutput
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
WindowRenderOutput();
|
||||||
|
~WindowRenderOutput();
|
||||||
|
void Init();
|
||||||
|
void OnPreRender(RendererPtr renderer) override;
|
||||||
|
void Present() override;
|
||||||
|
void Update();
|
||||||
|
virtual uint32_t GetWidth() override;
|
||||||
|
virtual uint32_t GetHeight() override;
|
||||||
|
virtual ID3D11RenderTargetViewPtr GetRenderTargetView() override;
|
||||||
|
virtual ID3D11DepthStencilViewPtr GetDepthStencilView() override;
|
||||||
|
Window& GetWindow();
|
||||||
|
private:
|
||||||
|
Window _window;
|
||||||
|
IDXGIOutputPtr _output;
|
||||||
|
ID3D11Texture2DPtr _backBuffer;
|
||||||
|
ID3D11Texture2DPtr _depthBuffer;
|
||||||
|
ID3D11RenderTargetViewPtr _leftRtv;
|
||||||
|
ID3D11RenderTargetViewPtr _rightRtv;
|
||||||
|
ID3D11DepthStencilViewPtr _depthStencilView;
|
||||||
|
IDXGISwapChain1Ptr _swapChain;
|
||||||
|
};*/
|
||||||
|
#endif // WindowScreen_h__
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
#ifndef d3d11_helper_h__
|
||||||
|
#define d3d11_helper_h__
|
||||||
|
|
||||||
|
#include "d3d11_types.h"
|
||||||
|
|
||||||
|
class d3d11_helper {
|
||||||
|
public:
|
||||||
|
static void DefaultDepthStencilDesc(D3D11_DEPTH_STENCIL_DESC& desc) {
|
||||||
|
desc.DepthEnable = TRUE;
|
||||||
|
desc.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ALL;
|
||||||
|
desc.DepthFunc = D3D11_COMPARISON_LESS;
|
||||||
|
desc.StencilEnable = FALSE;
|
||||||
|
desc.StencilReadMask = D3D11_DEFAULT_STENCIL_READ_MASK;
|
||||||
|
desc.StencilWriteMask = D3D11_DEFAULT_STENCIL_WRITE_MASK;
|
||||||
|
desc.FrontFace.StencilFunc = D3D11_COMPARISON_ALWAYS;
|
||||||
|
desc.BackFace.StencilFunc = D3D11_COMPARISON_ALWAYS;
|
||||||
|
desc.FrontFace.StencilDepthFailOp = D3D11_STENCIL_OP_KEEP;
|
||||||
|
desc.BackFace.StencilDepthFailOp = D3D11_STENCIL_OP_KEEP;
|
||||||
|
desc.FrontFace.StencilPassOp = D3D11_STENCIL_OP_KEEP;
|
||||||
|
desc.BackFace.StencilPassOp = D3D11_STENCIL_OP_KEEP;
|
||||||
|
desc.FrontFace.StencilFailOp = D3D11_STENCIL_OP_KEEP;
|
||||||
|
desc.BackFace.StencilFailOp = D3D11_STENCIL_OP_KEEP;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
#endif // d3d11_helper_h__
|
||||||
@@ -0,0 +1,44 @@
|
|||||||
|
#ifndef d3d11_types_h__
|
||||||
|
#define d3d11_types_h__
|
||||||
|
|
||||||
|
#include <d3d11.h>
|
||||||
|
#include <dxgi1_2.h>
|
||||||
|
#include <d3d12.h>
|
||||||
|
#include <dxgi1_4.h>
|
||||||
|
|
||||||
|
#include <wrl.h>
|
||||||
|
|
||||||
|
using namespace Microsoft::WRL;
|
||||||
|
|
||||||
|
typedef ComPtr<ID3D11Buffer> ID3D11BufferPtr;
|
||||||
|
typedef ComPtr<ID3D11Device> ID3D11DevicePtr;
|
||||||
|
typedef ComPtr<ID3D11InputLayout> ID3D11InputLayoutPtr;
|
||||||
|
typedef ComPtr<ID3D11DepthStencilState> ID3D11DepthStencilStatePtr;
|
||||||
|
|
||||||
|
typedef ComPtr<ID3D11DeviceContext> ID3D11DeviceContextPtr;
|
||||||
|
|
||||||
|
typedef ComPtr<ID3D11ShaderResourceView> ID3D11ShaderResourceViewPtr;
|
||||||
|
|
||||||
|
typedef ComPtr<IDXGIOutput> IDXGIOutputPtr;
|
||||||
|
typedef ComPtr<ID3D11Texture2D> ID3D11Texture2DPtr;
|
||||||
|
typedef ComPtr<ID3D11Resource> ID3D11ResourcePtr;
|
||||||
|
typedef ComPtr<ID3D12Resource> ID3D12ResourcePtr;
|
||||||
|
|
||||||
|
typedef ComPtr<ID3D11RenderTargetView> ID3D11RenderTargetViewPtr;
|
||||||
|
typedef ComPtr<IDXGISwapChain1> IDXGISwapChain1Ptr;
|
||||||
|
typedef ComPtr<IDXGISwapChain> IDXGISwapChainPtr;
|
||||||
|
typedef ComPtr<ID3D11DepthStencilView> ID3D11DepthStencilViewPtr;
|
||||||
|
|
||||||
|
typedef ComPtr<IDXGIOutput1> IDXGIOutput1Ptr;
|
||||||
|
|
||||||
|
|
||||||
|
typedef ComPtr<IDXGIDevice1> IDXGIDevice1Ptr;
|
||||||
|
typedef ComPtr<IDXGIAdapter> IDXGIAdapterPtr;
|
||||||
|
typedef ComPtr<IDXGIAdapter1> IDXGIAdapter1Ptr;
|
||||||
|
typedef ComPtr<IDXGIFactory2> IDXGIFactory2Ptr;
|
||||||
|
typedef ComPtr<IDXGIFactory4> IDXGIFactory4Ptr;
|
||||||
|
|
||||||
|
|
||||||
|
typedef ComPtr<ID3D12Device> ID3D12DevicePtr;
|
||||||
|
|
||||||
|
#endif // d3d11_types_h__
|
||||||
+1766
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,57 @@
|
|||||||
|
struct VS_INPUT {
|
||||||
|
float4 vPosition : POSITION;
|
||||||
|
float3 normal : NORMAL;
|
||||||
|
float2 uv0 : UV0;
|
||||||
|
float2 uv1 : UV1;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct VS_OUTPUT {
|
||||||
|
float4 vPosition : SV_POSITION;
|
||||||
|
float3 normal : TEXCOORD0;
|
||||||
|
float2 uv0 : TEXCOORD1;
|
||||||
|
float2 uv1 : TEXCOORD2;
|
||||||
|
float3 worldPos : TEXCOORD3;
|
||||||
|
};
|
||||||
|
|
||||||
|
cbuffer TestBuffer : register(b3) {
|
||||||
|
float4x4 mWorld;
|
||||||
|
float4x4 mView;
|
||||||
|
float4x4 mProjection;
|
||||||
|
float4 cameraWorldPos;
|
||||||
|
}
|
||||||
|
|
||||||
|
Texture2D diffuse : register(t0);
|
||||||
|
Texture2D tex2 : register(t1);
|
||||||
|
SamplerState MeshTextureSampler;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
VS_OUTPUT main_vs(VS_INPUT v) {
|
||||||
|
VS_OUTPUT o;
|
||||||
|
|
||||||
|
float4x4 wvp = mul(mul(mProjection, mView), mWorld);
|
||||||
|
|
||||||
|
o.vPosition = mul(wvp, float4(v.vPosition.xyz, 1));
|
||||||
|
|
||||||
|
o.normal = mul((float3x3)mWorld, v.normal);
|
||||||
|
o.uv0 = v.uv0;
|
||||||
|
o.uv1 = v.uv1;
|
||||||
|
o.worldPos = mul((float3x3)mWorld, v.vPosition.xyz);
|
||||||
|
return o;
|
||||||
|
}
|
||||||
|
|
||||||
|
#include "lighting/cook_torrance_term.inc"
|
||||||
|
|
||||||
|
float4 main_ps(VS_OUTPUT input) : SV_Target
|
||||||
|
{
|
||||||
|
float3 ambient = float3(0.3f, 0.3f, 0.4f);
|
||||||
|
|
||||||
|
float4 diffuseColor = 1.0f;// diffuse.Sample(MeshTextureSampler, input.uv0);
|
||||||
|
float3 worldPos = input.worldPos;
|
||||||
|
float3 camPos = cameraWorldPos.xyz;
|
||||||
|
float3 viewDir = normalize(camPos - worldPos);
|
||||||
|
float3 sun = normalize(float3(-1, 1, -1));
|
||||||
|
|
||||||
|
float3 surfaceColor = cook_torrance(normalize(input.normal), viewDir, sun, 0.1f, 1.0f, float3(1,1,1), diffuseColor.rgb);
|
||||||
|
return float4(surfaceColor + ambient * diffuseColor, 1);
|
||||||
|
}
|
||||||
@@ -0,0 +1,64 @@
|
|||||||
|
struct VS_INPUT
|
||||||
|
{
|
||||||
|
float4 vPosition : POSITION;
|
||||||
|
float3 normal : NORMAL;
|
||||||
|
float2 uv0 : UV0;
|
||||||
|
float2 uv1 : UV1;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct VS_OUTPUT {
|
||||||
|
float4 vPosition : SV_POSITION;
|
||||||
|
float3 normal : TEXCOORD0;
|
||||||
|
float2 uv0 : TEXCOORD1;
|
||||||
|
float2 uv1 : TEXCOORD2;
|
||||||
|
float3 worldPos : TEXCOORD3;
|
||||||
|
float3 viewPos : TEXCOORD4;
|
||||||
|
};
|
||||||
|
|
||||||
|
cbuffer TestBuffer : register(b3) {
|
||||||
|
float4x4 mWorld;
|
||||||
|
float4x4 mView;
|
||||||
|
float4x4 mProjection;
|
||||||
|
float4 cameraWorldPos;
|
||||||
|
float4 _DiffuseColor;
|
||||||
|
}
|
||||||
|
|
||||||
|
Texture2D diffuse : register(t0);
|
||||||
|
Texture2D tex2 : register(t1);
|
||||||
|
SamplerState MeshTextureSampler;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
VS_OUTPUT main_vs(VS_INPUT v){
|
||||||
|
VS_OUTPUT o;
|
||||||
|
|
||||||
|
|
||||||
|
float4x4 wv = mul(mView, mWorld);
|
||||||
|
float4x4 wvp = mul(mul(mProjection, mView), mWorld);
|
||||||
|
|
||||||
|
o.vPosition = mul(wvp, float4(v.vPosition.xyz,1));
|
||||||
|
|
||||||
|
o.normal = mul((float3x3)mWorld, v.normal);
|
||||||
|
o.uv0 = v.uv0;
|
||||||
|
o.uv1 = v.uv1;
|
||||||
|
o.worldPos = mul((float3x3)mWorld, v.vPosition.xyz);
|
||||||
|
o.viewPos = mul(wv, float4(v.vPosition.xyz, 1));
|
||||||
|
return o;
|
||||||
|
}
|
||||||
|
|
||||||
|
#include "lighting/cook_torrance_term.inc"
|
||||||
|
|
||||||
|
float4 main_ps(VS_OUTPUT input) : SV_Target
|
||||||
|
{
|
||||||
|
float3 ambient = float3(0.3f, 0.3f, 0.4f);
|
||||||
|
|
||||||
|
float4 diffuseColor = _DiffuseColor * diffuse.Sample(MeshTextureSampler, input.uv0);
|
||||||
|
float3 worldPos = input.worldPos;
|
||||||
|
float3 camPos = cameraWorldPos.xyz;
|
||||||
|
float3 viewDir = normalize(camPos - worldPos);
|
||||||
|
float3 sun = normalize(float3(-1, 1, -1));
|
||||||
|
|
||||||
|
float3 surfaceColor = cook_torrance(normalize(input.normal), viewDir, sun, 0.7f, 0.1f, diffuseColor.rgb, diffuseColor.rgb);
|
||||||
|
|
||||||
|
return float4(surfaceColor + ambient * diffuseColor, 1);
|
||||||
|
}
|
||||||
@@ -0,0 +1,32 @@
|
|||||||
|
struct VS_INPUT
|
||||||
|
{
|
||||||
|
float4 position : POSITION;
|
||||||
|
float4 color : COLOR;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct VS_OUTPUT {
|
||||||
|
float4 position : SV_POSITION;
|
||||||
|
float4 color : TEXCOORD0;
|
||||||
|
};
|
||||||
|
|
||||||
|
cbuffer TestBuffer : register(b3) {
|
||||||
|
float4x4 mWorld;
|
||||||
|
float4x4 mView;
|
||||||
|
float4x4 mProjection;
|
||||||
|
float alphaMul;
|
||||||
|
}
|
||||||
|
|
||||||
|
VS_OUTPUT main_vs(VS_INPUT v) {
|
||||||
|
VS_OUTPUT o;
|
||||||
|
|
||||||
|
float4x4 wvp = mul(mul(mProjection, mView), mWorld);
|
||||||
|
o.position = mul(wvp, float4(v.position.xyz, 1));
|
||||||
|
o.color = v.color;
|
||||||
|
return o;
|
||||||
|
}
|
||||||
|
|
||||||
|
float4 main_ps(VS_OUTPUT input) : SV_Target{
|
||||||
|
float4 color = input.color;
|
||||||
|
color *= alphaMul;
|
||||||
|
return color;
|
||||||
|
}
|
||||||
@@ -0,0 +1,70 @@
|
|||||||
|
#ifndef COOK_TORRANCE_TERM
|
||||||
|
#define COOK_TORRANCE_TERM
|
||||||
|
|
||||||
|
float4 cook_torrance(
|
||||||
|
in float3 normal,
|
||||||
|
in float3 viewer,
|
||||||
|
in float3 light, float roughness_value, float ref_at_norm_incidence, float3 cSpecular, float3 cDiffuse)
|
||||||
|
{
|
||||||
|
// Compute any aliases and intermediary values
|
||||||
|
// -------------------------------------------
|
||||||
|
float3 half_vector = normalize( light + viewer );
|
||||||
|
float NdotL = saturate( dot( normal, light ) );
|
||||||
|
float NdotH = max( dot( normal, half_vector ) , 1.0e-7);
|
||||||
|
float NdotV = saturate( dot( normal, viewer ) );
|
||||||
|
float VdotH = saturate( dot( viewer, half_vector ) );
|
||||||
|
float r_sq = roughness_value * roughness_value;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// Evaluate the geometric term
|
||||||
|
// --------------------------------
|
||||||
|
float geo_numerator = 2.0f * NdotH;
|
||||||
|
float geo_denominator = VdotH;
|
||||||
|
|
||||||
|
float geo_b = (geo_numerator * NdotV ) / geo_denominator;
|
||||||
|
float geo_c = (geo_numerator * NdotL ) / geo_denominator;
|
||||||
|
float geo = min( 1.0f, min( geo_b, geo_c ) );
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// Now evaluate the roughness term
|
||||||
|
// -------------------------------
|
||||||
|
float roughness;
|
||||||
|
float roughness_a = 1.0f / ( 4.0f * r_sq * pow( NdotH, 4 ) );
|
||||||
|
float roughness_b = NdotH * NdotH - 1.0f;
|
||||||
|
float roughness_c = r_sq * NdotH * NdotH;
|
||||||
|
roughness = roughness_a * exp( roughness_b / roughness_c );
|
||||||
|
|
||||||
|
|
||||||
|
// Next evaluate the Fresnel value
|
||||||
|
// -------------------------------
|
||||||
|
float fresnel = pow( 1.0f - VdotH, 5.0f );
|
||||||
|
fresnel *= ( 1.0f - ref_at_norm_incidence );
|
||||||
|
fresnel += ref_at_norm_incidence;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// Put all the terms together to compute
|
||||||
|
// the specular term in the equation
|
||||||
|
// -------------------------------------
|
||||||
|
float3 Rs_numerator = ( fresnel * geo * roughness );
|
||||||
|
float Rs_denominator = max(1.0e-7, NdotV * NdotL);
|
||||||
|
float3 Rs = Rs_numerator/ Rs_denominator;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// Put all the parts together to generate
|
||||||
|
// the final colour
|
||||||
|
// --------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
Rs = max(0, Rs);
|
||||||
|
float3 final = max(0.0f, NdotL) *cDiffuse + (1 * Rs );
|
||||||
|
|
||||||
|
// Return the result
|
||||||
|
// -----------------
|
||||||
|
return float4( final, 1.0f );
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,47 @@
|
|||||||
|
struct VS_INPUT
|
||||||
|
{
|
||||||
|
float4 vPosition : POSITION;
|
||||||
|
float3 normal : NORMAL;
|
||||||
|
float2 uv0 : UV0;
|
||||||
|
float2 uv1 : UV1;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct VS_OUTPUT {
|
||||||
|
float4 vPosition : SV_POSITION;
|
||||||
|
float3 normal : TEXCOORD0;
|
||||||
|
float2 uv0 : TEXCOORD1;
|
||||||
|
float2 uv1 : TEXCOORD2;
|
||||||
|
};
|
||||||
|
|
||||||
|
cbuffer TestBuffer : register(b3) {
|
||||||
|
float4x4 mWorld;
|
||||||
|
float4x4 mView;
|
||||||
|
float4x4 mProjection;
|
||||||
|
}
|
||||||
|
|
||||||
|
Texture2D tex : register(t0);
|
||||||
|
Texture2D tex2 : register(t1);
|
||||||
|
SamplerState MeshTextureSampler;
|
||||||
|
|
||||||
|
VS_OUTPUT main_vs(VS_INPUT v) {
|
||||||
|
VS_OUTPUT o;
|
||||||
|
|
||||||
|
float4x4 wvp = mul(mul(mProjection, mView), mWorld);
|
||||||
|
|
||||||
|
o.vPosition = mul(wvp, float4(v.vPosition.xyz, 1));
|
||||||
|
|
||||||
|
o.normal = mul((float3x3)mWorld, v.normal);
|
||||||
|
o.uv0 = v.uv0;
|
||||||
|
o.uv1 = v.uv1;
|
||||||
|
return o;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
float4 main_ps(VS_OUTPUT input) : SV_Target
|
||||||
|
{
|
||||||
|
float3 sun = normalize(float3(-1,1,-1));
|
||||||
|
float lit = dot(sun, input.normal);
|
||||||
|
float3 diffuse = float3(1, 0, 0);
|
||||||
|
|
||||||
|
return float4(diffuse * lit, 1);
|
||||||
|
}
|
||||||
@@ -0,0 +1,63 @@
|
|||||||
|
struct VS_INPUT
|
||||||
|
{
|
||||||
|
float4 vPosition : POSITION;
|
||||||
|
float3 normal : NORMAL;
|
||||||
|
float2 uv0 : UV0;
|
||||||
|
float2 uv1 : UV1;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct VS_OUTPUT {
|
||||||
|
float4 vPosition : SV_POSITION;
|
||||||
|
float3 normal : TEXCOORD0;
|
||||||
|
float2 uv0 : TEXCOORD1;
|
||||||
|
float2 uv1 : TEXCOORD2;
|
||||||
|
float3 worldPos : TEXCOORD3;
|
||||||
|
float3 viewPos : TEXCOORD4;
|
||||||
|
};
|
||||||
|
|
||||||
|
cbuffer TestBuffer : register(b3) {
|
||||||
|
float4x4 mWorld;
|
||||||
|
float4x4 mView;
|
||||||
|
float4x4 mProjection;
|
||||||
|
float4 cameraWorldPos;
|
||||||
|
}
|
||||||
|
|
||||||
|
Texture2D diffuse : register(t0);
|
||||||
|
SamplerState MeshTextureSampler : register(s0);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
VS_OUTPUT main_vs(VS_INPUT v){
|
||||||
|
VS_OUTPUT o;
|
||||||
|
|
||||||
|
|
||||||
|
float4x4 wv = mul(mView, mWorld);
|
||||||
|
float4x4 wvp = mul(mul(mProjection, mView), mWorld);
|
||||||
|
|
||||||
|
o.vPosition = mul(wvp, float4(v.vPosition.xyz,1));
|
||||||
|
|
||||||
|
o.normal = mul((float3x3)mWorld, v.normal);
|
||||||
|
o.uv0 = v.uv0;
|
||||||
|
o.uv1 = v.uv1;
|
||||||
|
o.worldPos = mul((float3x3)mWorld, v.vPosition.xyz);
|
||||||
|
o.viewPos = mul(wv, float4(v.vPosition.xyz, 1));
|
||||||
|
return o;
|
||||||
|
}
|
||||||
|
|
||||||
|
#include "lighting/cook_torrance_term.inc"
|
||||||
|
|
||||||
|
float4 main_ps(VS_OUTPUT input) : SV_Target
|
||||||
|
{
|
||||||
|
float3 ambient = float3(0.3f, 0.3f, 0.4f);
|
||||||
|
|
||||||
|
float4 diffuseColor = diffuse.Sample(MeshTextureSampler, input.uv0);
|
||||||
|
return diffuseColor;
|
||||||
|
float3 worldPos = input.worldPos;
|
||||||
|
float3 camPos = cameraWorldPos.xyz;
|
||||||
|
float3 viewDir = normalize(camPos - worldPos);
|
||||||
|
float3 sun = normalize(float3(-1, 1, -1));
|
||||||
|
|
||||||
|
float3 surfaceColor = cook_torrance(normalize(input.normal), viewDir, sun, 0.7f, 0.1f, diffuseColor.rgb, diffuseColor.rgb);
|
||||||
|
|
||||||
|
return float4(surfaceColor + ambient * diffuseColor, 1);
|
||||||
|
}
|
||||||
Binary file not shown.
@@ -0,0 +1,7 @@
|
|||||||
|
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,90 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
|
<ItemGroup Label="ProjectConfigurations">
|
||||||
|
<ProjectConfiguration Include="Debug|Win32">
|
||||||
|
<Configuration>Debug</Configuration>
|
||||||
|
<Platform>Win32</Platform>
|
||||||
|
</ProjectConfiguration>
|
||||||
|
<ProjectConfiguration Include="Release|Win32">
|
||||||
|
<Configuration>Release</Configuration>
|
||||||
|
<Platform>Win32</Platform>
|
||||||
|
</ProjectConfiguration>
|
||||||
|
</ItemGroup>
|
||||||
|
<PropertyGroup Label="Globals">
|
||||||
|
<ProjectGuid>{845A038A-8163-4851-95E1-78EFFD5F0AAF}</ProjectGuid>
|
||||||
|
<Keyword>Win32Proj</Keyword>
|
||||||
|
<RootNamespace>LEnginePlayer</RootNamespace>
|
||||||
|
</PropertyGroup>
|
||||||
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||||
|
<ConfigurationType>Application</ConfigurationType>
|
||||||
|
<UseDebugLibraries>true</UseDebugLibraries>
|
||||||
|
<PlatformToolset>v140</PlatformToolset>
|
||||||
|
<CharacterSet>Unicode</CharacterSet>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||||
|
<ConfigurationType>Application</ConfigurationType>
|
||||||
|
<UseDebugLibraries>false</UseDebugLibraries>
|
||||||
|
<PlatformToolset>v140</PlatformToolset>
|
||||||
|
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||||
|
<CharacterSet>Unicode</CharacterSet>
|
||||||
|
</PropertyGroup>
|
||||||
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||||
|
<ImportGroup Label="ExtensionSettings">
|
||||||
|
</ImportGroup>
|
||||||
|
<ImportGroup Label="Shared">
|
||||||
|
</ImportGroup>
|
||||||
|
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||||
|
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||||
|
</ImportGroup>
|
||||||
|
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||||
|
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||||
|
</ImportGroup>
|
||||||
|
<PropertyGroup Label="UserMacros" />
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||||
|
<LinkIncremental>true</LinkIncremental>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||||
|
<LinkIncremental>false</LinkIncremental>
|
||||||
|
</PropertyGroup>
|
||||||
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||||
|
<ClCompile>
|
||||||
|
<PrecompiledHeader>
|
||||||
|
</PrecompiledHeader>
|
||||||
|
<WarningLevel>Level3</WarningLevel>
|
||||||
|
<Optimization>Disabled</Optimization>
|
||||||
|
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
|
<AdditionalIncludeDirectories>../LEngine;../../nettlemath;../../nativelinq/nativelinq/nativelinq;</AdditionalIncludeDirectories>
|
||||||
|
</ClCompile>
|
||||||
|
<Link>
|
||||||
|
<SubSystem>Console</SubSystem>
|
||||||
|
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||||
|
<AdditionalLibraryDirectories>../Debug;</AdditionalLibraryDirectories>
|
||||||
|
<AdditionalDependencies>LEngine.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||||
|
</Link>
|
||||||
|
</ItemDefinitionGroup>
|
||||||
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||||
|
<ClCompile>
|
||||||
|
<WarningLevel>Level3</WarningLevel>
|
||||||
|
<PrecompiledHeader>
|
||||||
|
</PrecompiledHeader>
|
||||||
|
<Optimization>MaxSpeed</Optimization>
|
||||||
|
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||||
|
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||||
|
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
|
<AdditionalIncludeDirectories>../LEngine;../../nettlemath;../../nativelinq/nativelinq/nativelinq;</AdditionalIncludeDirectories>
|
||||||
|
</ClCompile>
|
||||||
|
<Link>
|
||||||
|
<SubSystem>Console</SubSystem>
|
||||||
|
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||||
|
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||||
|
<OptimizeReferences>true</OptimizeReferences>
|
||||||
|
</Link>
|
||||||
|
</ItemDefinitionGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ClCompile Include="LEnginePlayer.cpp" />
|
||||||
|
</ItemGroup>
|
||||||
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||||
|
<ImportGroup Label="ExtensionTargets">
|
||||||
|
</ImportGroup>
|
||||||
|
</Project>
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user