Compare commits
4 Commits
main
...
DICOM_View
| Author | SHA256 | Date | |
|---|---|---|---|
| 3b68d4ff82 | |||
| 9b355f6524 | |||
| 51e4112868 | |||
| c86b8cbd00 |
188
.gitignore
vendored
188
.gitignore
vendored
@@ -1,93 +1,95 @@
|
|||||||
# ---> C++
|
# ---> C++
|
||||||
# Prerequisites
|
# Prerequisites
|
||||||
*.d
|
*.d
|
||||||
|
|
||||||
# Compiled Object files
|
# Compiled Object files
|
||||||
*.slo
|
*.slo
|
||||||
*.lo
|
*.lo
|
||||||
*.o
|
*.o
|
||||||
*.obj
|
*.obj
|
||||||
|
|
||||||
# Precompiled Headers
|
# Precompiled Headers
|
||||||
*.gch
|
*.gch
|
||||||
*.pch
|
*.pch
|
||||||
|
|
||||||
# Compiled Dynamic libraries
|
# Compiled Dynamic libraries
|
||||||
*.so
|
*.so
|
||||||
*.dylib
|
*.dylib
|
||||||
*.dll
|
*.dll
|
||||||
|
|
||||||
# Fortran module files
|
# Fortran module files
|
||||||
*.mod
|
*.mod
|
||||||
*.smod
|
*.smod
|
||||||
|
|
||||||
# Executables
|
# Executables
|
||||||
*.exe
|
*.exe
|
||||||
*.out
|
*.out
|
||||||
*.app
|
*.app
|
||||||
|
|
||||||
# ---> C
|
# ---> C
|
||||||
# Prerequisites
|
# Prerequisites
|
||||||
*.d
|
*.d
|
||||||
|
|
||||||
# Object files
|
# Object files
|
||||||
*.o
|
*.o
|
||||||
*.ko
|
*.ko
|
||||||
*.obj
|
*.obj
|
||||||
*.elf
|
*.elf
|
||||||
|
|
||||||
# Linker output
|
# Linker output
|
||||||
*.ilk
|
*.ilk
|
||||||
*.map
|
*.map
|
||||||
*.exp
|
*.exp
|
||||||
|
|
||||||
# Precompiled Headers
|
# Precompiled Headers
|
||||||
*.gch
|
*.gch
|
||||||
*.pch
|
*.pch
|
||||||
|
|
||||||
# Shared objects (inc. Windows DLLs)
|
# Shared objects (inc. Windows DLLs)
|
||||||
*.dll
|
*.dll
|
||||||
*.so
|
*.so
|
||||||
*.so.*
|
*.so.*
|
||||||
*.dylib
|
*.dylib
|
||||||
|
|
||||||
# Executables
|
# Executables
|
||||||
*.exe
|
*.exe
|
||||||
*.out
|
*.out
|
||||||
*.app
|
*.app
|
||||||
*.i*86
|
*.i*86
|
||||||
*.x86_64
|
*.x86_64
|
||||||
*.hex
|
*.hex
|
||||||
|
|
||||||
# Debug files
|
# Debug files
|
||||||
*.dSYM/
|
*.dSYM/
|
||||||
*.su
|
*.su
|
||||||
*.idb
|
*.idb
|
||||||
*.pdb
|
*.pdb
|
||||||
|
|
||||||
# Kernel Module Compile Results
|
# Kernel Module Compile Results
|
||||||
*.mod*
|
*.mod*
|
||||||
*.cmd
|
*.cmd
|
||||||
.tmp_versions/
|
.tmp_versions/
|
||||||
modules.order
|
modules.order
|
||||||
Module.symvers
|
Module.symvers
|
||||||
Mkfile.old
|
Mkfile.old
|
||||||
dkms.conf
|
dkms.conf
|
||||||
|
|
||||||
# ---> CMake
|
# ---> CMake
|
||||||
CMakeLists.txt.user
|
CMakeLists.txt.user
|
||||||
CMakeCache.txt
|
CMakeCache.txt
|
||||||
CMakeFiles
|
CMakeFiles
|
||||||
CMakeScripts
|
CMakeScripts
|
||||||
Testing
|
Testing
|
||||||
Makefile
|
Makefile
|
||||||
cmake_install.cmake
|
cmake_install.cmake
|
||||||
install_manifest.txt
|
install_manifest.txt
|
||||||
compile_commands.json
|
compile_commands.json
|
||||||
CTestTestfile.cmake
|
CTestTestfile.cmake
|
||||||
_deps
|
_deps
|
||||||
CMakeUserPresets.json
|
CMakeUserPresets.json
|
||||||
|
|
||||||
build
|
build
|
||||||
bin
|
bin
|
||||||
lib
|
lib
|
||||||
|
|
||||||
|
DCM
|
||||||
2
TSE
2
TSE
Submodule TSE updated: d98a70bb19...8c0152c3b4
132
TSE-RTS/Resources/DCMVizPresets/Preset1.json
Normal file
132
TSE-RTS/Resources/DCMVizPresets/Preset1.json
Normal file
@@ -0,0 +1,132 @@
|
|||||||
|
{
|
||||||
|
"transparencyCount": 9,
|
||||||
|
"transparency": [
|
||||||
|
{
|
||||||
|
"index": 0,
|
||||||
|
"transpValue": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"index": 0.485526,
|
||||||
|
"transpValue": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"index": 0.497948,
|
||||||
|
"transpValue": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"index": 0.499458,
|
||||||
|
"transpValue": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"index": 0.500618,
|
||||||
|
"transpValue": 0.0035
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"index": 0.505180,
|
||||||
|
"transpValue": 0.459089
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"index": 0.509820,
|
||||||
|
"transpValue": 0.970381
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"index": 0.519570,
|
||||||
|
"transpValue": 0.966309
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"index": 0.531805,
|
||||||
|
"transpValue": 0.833358
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"index": 0.544899,
|
||||||
|
"transpValue": 0.821918
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"index": 1.0,
|
||||||
|
"transpValue": 0.821918
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"colorCount": 20,
|
||||||
|
"colors": [
|
||||||
|
{
|
||||||
|
"index": 0.000000,
|
||||||
|
"color": { "x": 1.000000, "y": 1.000000, "z": 1.000000 }
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"index": 0.454520,
|
||||||
|
"color": { "x": 1.000000, "y": 1.000000, "z": 1.000000 }
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"index": 0.466438,
|
||||||
|
"color": { "x": 0.000000, "y": 0.000000, "z": 0.000000 }
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"index": 0.486854,
|
||||||
|
"color": { "x": 0.407843, "y": 0.388235, "z": 0.968627 }
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"index": 0.487724,
|
||||||
|
"color": { "x": 0.980392, "y": 0.976471, "z": 0.980392 }
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"index": 0.488182,
|
||||||
|
"color": { "x": 0.796078, "y": 0.682353, "z": 0.611765 }
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"index": 0.495598,
|
||||||
|
"color": { "x": 0.980392, "y": 0.976471, "z": 0.980392 }
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"index": 0.497215,
|
||||||
|
"color": { "x": 0.709804, "y": 0.505882, "z": 0.380392 }
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"index": 0.498283,
|
||||||
|
"color": { "x": 0.874510, "y": 0.254902, "z": 0.000000 }
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"index": 0.498833,
|
||||||
|
"color": { "x": 1.000000, "y": 0.800000, "z": 0.164706 }
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"index": 0.500633,
|
||||||
|
"color": { "x": 0.835294, "y": 0.117647, "z": 0.000000 }
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"index": 0.500755,
|
||||||
|
"color": { "x": 1.000000, "y": 0.478431, "z": 0.313725 }
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"index": 0.502113,
|
||||||
|
"color": { "x": 1.000000, "y": 1.000000, "z": 1.000000 }
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"index": 0.502846,
|
||||||
|
"color": { "x": 0.874510, "y": 0.254902, "z": 0.000000 }
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"index": 0.503441,
|
||||||
|
"color": { "x": 1.000000, "y": 0.866667, "z": 0.400000 }
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"index": 0.503670,
|
||||||
|
"color": { "x": 0.988235, "y": 0.988235, "z": 0.988235 }
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"index": 0.527932,
|
||||||
|
"color": { "x": 0.972549, "y": 0.972549, "z": 0.976471 }
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"index": 0.544366,
|
||||||
|
"color": { "x": 1.000000, "y": 0.819608, "z": 0.188235 }
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"index": 0.549660,
|
||||||
|
"color": { "x": 1.000000, "y": 1.000000, "z": 1.000000 }
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"index": 1.000000,
|
||||||
|
"color": { "x": 1.000000, "y": 1.000000, "z": 1.000000 }
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
283
TSE-RTS/src/elements/visualizationData.cpp
Normal file
283
TSE-RTS/src/elements/visualizationData.cpp
Normal file
@@ -0,0 +1,283 @@
|
|||||||
|
#include "visualizationData.hpp"
|
||||||
|
#include "json.hpp"
|
||||||
|
#include "utils/JsonExports.hpp"
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
|
#include <cmath>
|
||||||
|
#include <filesystem>
|
||||||
|
#include <fstream>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
constexpr int LUT_WIDTH = 256;
|
||||||
|
constexpr int LUT_HEIGHT = 256;
|
||||||
|
constexpr int LUT_PIXEL_COUNT = LUT_WIDTH * LUT_HEIGHT;
|
||||||
|
constexpr float LUT_INV_MAX_INDEX = 1.0f / static_cast<float>(LUT_PIXEL_COUNT - 1);
|
||||||
|
|
||||||
|
inline float Clamp01(const float value)
|
||||||
|
{
|
||||||
|
return std::min(1.0f, std::max(0.0f, value));
|
||||||
|
}
|
||||||
|
|
||||||
|
inline float Lerp(const float a, const float b, const float t)
|
||||||
|
{
|
||||||
|
return a + (b - a) * t;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
VisualizationData VisualizationData::LoadVisualizationSetting(string path)
|
||||||
|
{
|
||||||
|
VisualizationData dataOut{};
|
||||||
|
namespace fs = std::filesystem;
|
||||||
|
|
||||||
|
const fs::path jsonPath = fs::absolute(path);
|
||||||
|
if(!fs::exists(jsonPath) || !fs::is_regular_file(jsonPath))
|
||||||
|
{
|
||||||
|
return dataOut;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::ifstream in(jsonPath, std::ios::in | std::ios::binary);
|
||||||
|
if(!in.is_open())
|
||||||
|
{
|
||||||
|
return dataOut;
|
||||||
|
}
|
||||||
|
|
||||||
|
nlohmann::json json = nlohmann::json::parse(in, nullptr, false);
|
||||||
|
if(json.is_discarded() || !json.is_object())
|
||||||
|
{
|
||||||
|
return dataOut;
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto transpIt = json.find("transparency");
|
||||||
|
const auto colorsIt = json.find("colors");
|
||||||
|
|
||||||
|
const std::size_t transpArrayCount = (transpIt != json.end() && transpIt->is_array()) ? transpIt->size() : 0;
|
||||||
|
const std::size_t colorArrayCount = (colorsIt != json.end() && colorsIt->is_array()) ? colorsIt->size() : 0;
|
||||||
|
|
||||||
|
const std::size_t transpCount = std::min(json.value("transparencyCount", transpArrayCount), transpArrayCount);
|
||||||
|
const std::size_t colorCount = std::min(json.value("colorCount", colorArrayCount), colorArrayCount);
|
||||||
|
|
||||||
|
dataOut.transparencyCount = transpCount;
|
||||||
|
dataOut.colorCount = colorCount;
|
||||||
|
|
||||||
|
if(transpCount > 0)
|
||||||
|
{
|
||||||
|
dataOut.transparency = new TransparencyData[transpCount]();
|
||||||
|
for(std::size_t i = 0; i < transpCount; ++i)
|
||||||
|
{
|
||||||
|
const nlohmann::json& point = (*transpIt)[i];
|
||||||
|
dataOut.transparency[i].index = point.value("index", 0.0f);
|
||||||
|
dataOut.transparency[i].transpValue = point.value("transpValue", 0.0f);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(colorCount > 0)
|
||||||
|
{
|
||||||
|
dataOut.colors = new ColorData[colorCount]();
|
||||||
|
for(std::size_t i = 0; i < colorCount; ++i)
|
||||||
|
{
|
||||||
|
const nlohmann::json& point = (*colorsIt)[i];
|
||||||
|
dataOut.colors[i].index = point.value("index", 0.0f);
|
||||||
|
const auto colorIt = point.find("color");
|
||||||
|
if(colorIt != point.end() && colorIt->is_object() &&
|
||||||
|
colorIt->contains("x") && colorIt->contains("y") && colorIt->contains("z"))
|
||||||
|
{
|
||||||
|
dataOut.colors[i].color = TSE::ImportVector3(*colorIt);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return dataOut;
|
||||||
|
}
|
||||||
|
|
||||||
|
void VisualizationData::FillLUTTexture(Texture& texture) const
|
||||||
|
{
|
||||||
|
if(static_cast<int>(texture.Width()) != LUT_WIDTH || static_cast<int>(texture.Height()) != LUT_HEIGHT)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<TransparencyData> transparencyPoints;
|
||||||
|
std::vector<ColorData> colorPoints;
|
||||||
|
|
||||||
|
if(transparency != nullptr && transparencyCount > 0)
|
||||||
|
{
|
||||||
|
transparencyPoints.assign(transparency, transparency + transparencyCount);
|
||||||
|
std::sort(transparencyPoints.begin(), transparencyPoints.end(), [](const TransparencyData& a, const TransparencyData& b)
|
||||||
|
{
|
||||||
|
return a.index < b.index;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if(colors != nullptr && colorCount > 0)
|
||||||
|
{
|
||||||
|
colorPoints.assign(colors, colors + colorCount);
|
||||||
|
std::sort(colorPoints.begin(), colorPoints.end(), [](const ColorData& a, const ColorData& b)
|
||||||
|
{
|
||||||
|
return a.index < b.index;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
std::size_t transparencySegment = 0;
|
||||||
|
std::size_t colorSegment = 0;
|
||||||
|
|
||||||
|
if(texture.bpp() == 32)
|
||||||
|
{
|
||||||
|
byte* pixel = texture.GetImagePtr();
|
||||||
|
if(pixel == nullptr)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for(int i = 0; i < LUT_PIXEL_COUNT; ++i)
|
||||||
|
{
|
||||||
|
const float value = static_cast<float>(i) * LUT_INV_MAX_INDEX;
|
||||||
|
|
||||||
|
float alpha = 1.0f;
|
||||||
|
if(!transparencyPoints.empty())
|
||||||
|
{
|
||||||
|
if(transparencyPoints.size() == 1 || value <= transparencyPoints.front().index)
|
||||||
|
{
|
||||||
|
alpha = transparencyPoints.front().transpValue;
|
||||||
|
}
|
||||||
|
else if(value >= transparencyPoints.back().index)
|
||||||
|
{
|
||||||
|
alpha = transparencyPoints.back().transpValue;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
while(transparencySegment + 1 < transparencyPoints.size() &&
|
||||||
|
value > transparencyPoints[transparencySegment + 1].index)
|
||||||
|
{
|
||||||
|
++transparencySegment;
|
||||||
|
}
|
||||||
|
|
||||||
|
const TransparencyData& p0 = transparencyPoints[transparencySegment];
|
||||||
|
const TransparencyData& p1 = transparencyPoints[transparencySegment + 1];
|
||||||
|
const float range = p1.index - p0.index;
|
||||||
|
const float t = (std::abs(range) > 1e-7f) ? Clamp01((value - p0.index) / range) : 0.0f;
|
||||||
|
alpha = Lerp(p0.transpValue, p1.transpValue, t);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
float r = 0.0f;
|
||||||
|
float g = 0.0f;
|
||||||
|
float b = 0.0f;
|
||||||
|
if(!colorPoints.empty())
|
||||||
|
{
|
||||||
|
if(colorPoints.size() == 1 || value <= colorPoints.front().index)
|
||||||
|
{
|
||||||
|
r = colorPoints.front().color.x;
|
||||||
|
g = colorPoints.front().color.y;
|
||||||
|
b = colorPoints.front().color.z;
|
||||||
|
}
|
||||||
|
else if(value >= colorPoints.back().index)
|
||||||
|
{
|
||||||
|
r = colorPoints.back().color.x;
|
||||||
|
g = colorPoints.back().color.y;
|
||||||
|
b = colorPoints.back().color.z;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
while(colorSegment + 1 < colorPoints.size() &&
|
||||||
|
value > colorPoints[colorSegment + 1].index)
|
||||||
|
{
|
||||||
|
++colorSegment;
|
||||||
|
}
|
||||||
|
|
||||||
|
const ColorData& p0 = colorPoints[colorSegment];
|
||||||
|
const ColorData& p1 = colorPoints[colorSegment + 1];
|
||||||
|
const float range = p1.index - p0.index;
|
||||||
|
const float t = (std::abs(range) > 1e-7f) ? Clamp01((value - p0.index) / range) : 0.0f;
|
||||||
|
|
||||||
|
r = Lerp(p0.color.x, p1.color.x, t);
|
||||||
|
g = Lerp(p0.color.y, p1.color.y, t);
|
||||||
|
b = Lerp(p0.color.z, p1.color.z, t);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
*pixel++ = static_cast<byte>(Clamp01(b) * 255.0f);
|
||||||
|
*pixel++ = static_cast<byte>(Clamp01(g) * 255.0f);
|
||||||
|
*pixel++ = static_cast<byte>(Clamp01(r) * 255.0f);
|
||||||
|
*pixel++ = static_cast<byte>(Clamp01(alpha) * 255.0f);
|
||||||
|
}
|
||||||
|
|
||||||
|
texture.Apply();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for(int i = 0; i < LUT_PIXEL_COUNT; ++i)
|
||||||
|
{
|
||||||
|
const float value = static_cast<float>(i) * LUT_INV_MAX_INDEX;
|
||||||
|
|
||||||
|
float alpha = 1.0f;
|
||||||
|
if(!transparencyPoints.empty())
|
||||||
|
{
|
||||||
|
if(transparencyPoints.size() == 1 || value <= transparencyPoints.front().index)
|
||||||
|
{
|
||||||
|
alpha = transparencyPoints.front().transpValue;
|
||||||
|
}
|
||||||
|
else if(value >= transparencyPoints.back().index)
|
||||||
|
{
|
||||||
|
alpha = transparencyPoints.back().transpValue;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
while(transparencySegment + 1 < transparencyPoints.size() &&
|
||||||
|
value > transparencyPoints[transparencySegment + 1].index)
|
||||||
|
{
|
||||||
|
++transparencySegment;
|
||||||
|
}
|
||||||
|
|
||||||
|
const TransparencyData& p0 = transparencyPoints[transparencySegment];
|
||||||
|
const TransparencyData& p1 = transparencyPoints[transparencySegment + 1];
|
||||||
|
const float range = p1.index - p0.index;
|
||||||
|
const float t = (std::abs(range) > 1e-7f) ? Clamp01((value - p0.index) / range) : 0.0f;
|
||||||
|
alpha = Lerp(p0.transpValue, p1.transpValue, t);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
float r = 0.0f;
|
||||||
|
float g = 0.0f;
|
||||||
|
float b = 0.0f;
|
||||||
|
if(!colorPoints.empty())
|
||||||
|
{
|
||||||
|
if(colorPoints.size() == 1 || value <= colorPoints.front().index)
|
||||||
|
{
|
||||||
|
r = colorPoints.front().color.x;
|
||||||
|
g = colorPoints.front().color.y;
|
||||||
|
b = colorPoints.front().color.z;
|
||||||
|
}
|
||||||
|
else if(value >= colorPoints.back().index)
|
||||||
|
{
|
||||||
|
r = colorPoints.back().color.x;
|
||||||
|
g = colorPoints.back().color.y;
|
||||||
|
b = colorPoints.back().color.z;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
while(colorSegment + 1 < colorPoints.size() &&
|
||||||
|
value > colorPoints[colorSegment + 1].index)
|
||||||
|
{
|
||||||
|
++colorSegment;
|
||||||
|
}
|
||||||
|
|
||||||
|
const ColorData& p0 = colorPoints[colorSegment];
|
||||||
|
const ColorData& p1 = colorPoints[colorSegment + 1];
|
||||||
|
const float range = p1.index - p0.index;
|
||||||
|
const float t = (std::abs(range) > 1e-7f) ? Clamp01((value - p0.index) / range) : 0.0f;
|
||||||
|
|
||||||
|
r = Lerp(p0.color.x, p1.color.x, t);
|
||||||
|
g = Lerp(p0.color.y, p1.color.y, t);
|
||||||
|
b = Lerp(p0.color.z, p1.color.z, t);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const int x = (i & 255);
|
||||||
|
const int y = (i >> 8);
|
||||||
|
texture.SetPixelNoApply(x, y, Color(Clamp01(r), Clamp01(g), Clamp01(b), Clamp01(alpha)));
|
||||||
|
}
|
||||||
|
|
||||||
|
texture.Apply();
|
||||||
|
}
|
||||||
33
TSE-RTS/src/elements/visualizationData.hpp
Normal file
33
TSE-RTS/src/elements/visualizationData.hpp
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "Types.hpp"
|
||||||
|
#include "Vector3.hpp"
|
||||||
|
#include "elements/Texture.hpp"
|
||||||
|
#include <cstddef>
|
||||||
|
|
||||||
|
using namespace TSE;
|
||||||
|
|
||||||
|
struct TransparencyData
|
||||||
|
{
|
||||||
|
float index;
|
||||||
|
float transpValue;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct ColorData
|
||||||
|
{
|
||||||
|
Vector3 color;
|
||||||
|
float index;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
struct VisualizationData
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
TransparencyData* transparency = nullptr;
|
||||||
|
ColorData* colors = nullptr;
|
||||||
|
std::size_t transparencyCount = 0;
|
||||||
|
std::size_t colorCount = 0;
|
||||||
|
|
||||||
|
static VisualizationData LoadVisualizationSetting(string path);
|
||||||
|
void FillLUTTexture(Texture& texture) const;
|
||||||
|
};
|
||||||
@@ -1,232 +1,291 @@
|
|||||||
#include "game.hpp"
|
#include "game.hpp"
|
||||||
#include "elements/Transformable.hpp"
|
#include "elements/Transformable.hpp"
|
||||||
#include "BehaviourScripts/TileMap.hpp"
|
#include "BehaviourScripts/TileMap.hpp"
|
||||||
#include "BehaviourScripts/OrdererSpriteSet.hpp"
|
#include "BehaviourScripts/OrdererSpriteSet.hpp"
|
||||||
#include "BehaviourScripts/Renderable.hpp"
|
#include "BehaviourScripts/Renderable.hpp"
|
||||||
#include "elements/ShaderRegistry.hpp"
|
#include "elements/ShaderRegistry.hpp"
|
||||||
#include "Vector2.hpp"
|
#include "Vector2.hpp"
|
||||||
#include <cmath>
|
#include "Vector3.hpp"
|
||||||
#include "PerlinNoise.hpp"
|
#include <cmath>
|
||||||
#include "BehaviourScripts/Camera.hpp"
|
#include "PerlinNoise.hpp"
|
||||||
#include "interfaces/IRenderTexture.hpp"
|
#include "BehaviourScripts/Camera.hpp"
|
||||||
#include "BehaviourScripts/MeshContainer.hpp"
|
#include "interfaces/IRenderTexture.hpp"
|
||||||
#include "BehaviourScripts/CameraSizeChangeNotifyer.hpp"
|
#include "BehaviourScripts/MeshContainer.hpp"
|
||||||
#include "BehaviourScripts/RenderTextureResizes.hpp"
|
#include "BehaviourScripts/CameraSizeChangeNotifyer.hpp"
|
||||||
#include "BehaviourScripts/CanvasScaler.hpp"
|
#include "BehaviourScripts/RenderTextureResizes.hpp"
|
||||||
#include "Random.hpp"
|
#include "BehaviourScripts/CanvasScaler.hpp"
|
||||||
|
#include "Random.hpp"
|
||||||
#define circleRadius 32
|
#include "elements/VolumeTexture3D.hpp"
|
||||||
#define circleFallof 25
|
#include "elements/visualizationData.hpp"
|
||||||
#define treeCircleRadius 27
|
|
||||||
#define treeCircleFallof 20
|
#define circleRadius 32
|
||||||
|
#define circleFallof 25
|
||||||
void game::setup(TSE::Scene* s, TSE::IWindow* wnd)
|
#define treeCircleRadius 27
|
||||||
{
|
#define treeCircleFallof 20
|
||||||
using namespace TSE;
|
|
||||||
s->AddLayer(&gameLayer);
|
void game::setup(TSE::Scene* s, TSE::IWindow* wnd)
|
||||||
s->AddLayer(&propsLayer);
|
{
|
||||||
|
using namespace TSE;
|
||||||
TileMap* maps[4];
|
//s->AddLayer(&gameLayer);
|
||||||
OrdererSpriteSet* props;
|
// s->AddLayer(&propsLayer);
|
||||||
Material* tileMapMaterial = new Material("tileSetMat", ShaderRegistry::GetShader("TileMapShader v2"));
|
|
||||||
tileMapMaterial->SetValue("spritePivot", Vector2(0,0));
|
// TileMap* maps[4];
|
||||||
Texture* setTexture = new Texture("tiles.png");
|
// OrdererSpriteSet* props;
|
||||||
TileSet* set = new TileSet(setTexture, 10, 10);
|
// Material* tileMapMaterial = new Material("tileSetMat", ShaderRegistry::GetShader("TileMapShader v2"));
|
||||||
|
// tileMapMaterial->SetValue("spritePivot", Vector2(0,0));
|
||||||
for (int i = 0; i < 4; i++)
|
// Texture* setTexture = new Texture("tiles.png");
|
||||||
{
|
// TileSet* set = new TileSet(setTexture, 10, 10);
|
||||||
Transformable* tileMap = new Transformable("tileMapL" + std::to_string(i));
|
|
||||||
tileMap->position += {0,0.5f * i,0};
|
// for (int i = 0; i < 4; i++)
|
||||||
gameLayer.AddTransformable(tileMap);
|
// {
|
||||||
TileMap* map = new TileMap();
|
// Transformable* tileMap = new Transformable("tileMapL" + std::to_string(i));
|
||||||
map->chunkSize = 12;
|
// tileMap->position += {0,0.5f * i,0};
|
||||||
map->set = set;
|
// gameLayer.AddTransformable(tileMap);
|
||||||
|
// TileMap* map = new TileMap();
|
||||||
Renderable* rnd = new Renderable(tileMapMaterial);
|
// map->chunkSize = 12;
|
||||||
|
// map->set = set;
|
||||||
tileMap->AddBehaviourScript(map);
|
|
||||||
tileMap->AddBehaviourScript(rnd);
|
// Renderable* rnd = new Renderable(tileMapMaterial);
|
||||||
|
|
||||||
maps[i] = map;
|
// tileMap->AddBehaviourScript(map);
|
||||||
}
|
// tileMap->AddBehaviourScript(rnd);
|
||||||
|
|
||||||
Material* objectsMaterial = new Material("objectsTileSetMat", ShaderRegistry::GetShader("Basic Ordered Sprite Set Shader"));
|
// maps[i] = map;
|
||||||
Texture* treeSetTexture = new Texture("trees.png");
|
// }
|
||||||
TileSet* treeSet = new TileSet(treeSetTexture, 6, 2);
|
|
||||||
Transformable* tileMap = new Transformable("propMap");
|
// Material* objectsMaterial = new Material("objectsTileSetMat", ShaderRegistry::GetShader("Basic Ordered Sprite Set Shader"));
|
||||||
propsLayer.AddTransformable(tileMap);
|
// Texture* treeSetTexture = new Texture("trees.png");
|
||||||
OrdererSpriteSet* map = new OrdererSpriteSet();
|
// TileSet* treeSet = new TileSet(treeSetTexture, 6, 2);
|
||||||
map->chunkSize = 12;
|
// Transformable* tileMap = new Transformable("propMap");
|
||||||
map->set = treeSet;
|
// propsLayer.AddTransformable(tileMap);
|
||||||
//map->SpriteScale = Vector2(1,2);
|
// OrdererSpriteSet* map = new OrdererSpriteSet();
|
||||||
|
// map->chunkSize = 12;
|
||||||
Renderable* rend = new Renderable(objectsMaterial);
|
// map->set = treeSet;
|
||||||
|
// //map->SpriteScale = Vector2(1,2);
|
||||||
tileMap->AddBehaviourScript(map);
|
|
||||||
tileMap->AddBehaviourScript(rend);
|
// Renderable* rend = new Renderable(objectsMaterial);
|
||||||
|
|
||||||
props = map;
|
// tileMap->AddBehaviourScript(map);
|
||||||
|
// tileMap->AddBehaviourScript(rend);
|
||||||
|
|
||||||
Random rnd = Random(12345u);
|
// props = map;
|
||||||
|
|
||||||
const siv::PerlinNoise perlin{ rnd.nextUInt() };
|
|
||||||
const siv::PerlinNoise perlin2{ rnd.nextUInt() };
|
// Random rnd = Random(12345u);
|
||||||
|
|
||||||
for (int x = circleRadius * -4; x < circleRadius * 4; x++)
|
// const siv::PerlinNoise perlin{ rnd.nextUInt() };
|
||||||
{
|
// const siv::PerlinNoise perlin2{ rnd.nextUInt() };
|
||||||
for (int y = circleRadius * -4; y < circleRadius * 4; y++)
|
|
||||||
{
|
// for (int x = circleRadius * -4; x < circleRadius * 4; x++)
|
||||||
float noise = (float)perlin.octave2D_01(x * 0.05f,y * 0.05f, 4);
|
// {
|
||||||
float treeNoise = (float)perlin2.octave2D_01(x * 0.05f,y * 0.05f, 2);
|
// for (int y = circleRadius * -4; y < circleRadius * 4; y++)
|
||||||
float noiseFallof = 1;
|
// {
|
||||||
float treeNoiseFallof = 1;
|
// float noise = (float)perlin.octave2D_01(x * 0.05f,y * 0.05f, 4);
|
||||||
Vector2 realpos = maps[0]->TileMapToRealPos(Vector2(x,y));
|
// float treeNoise = (float)perlin2.octave2D_01(x * 0.05f,y * 0.05f, 2);
|
||||||
Vector2 realposprop = (maps[0]->TileMapToRealPos(Vector2(x,y)) + Vector2(0, 0.25f)) * Vector2(1,0.5f);
|
// float noiseFallof = 1;
|
||||||
realpos *= {1,1.5f};
|
// float treeNoiseFallof = 1;
|
||||||
float dist = realpos.Length();
|
// Vector2 realpos = maps[0]->TileMapToRealPos(Vector2(x,y));
|
||||||
if(dist <= circleRadius && dist >= circleFallof)
|
// Vector2 realposprop = (maps[0]->TileMapToRealPos(Vector2(x,y)) + Vector2(0, 0.25f)) * Vector2(1,0.5f);
|
||||||
{
|
// realpos *= {1,1.5f};
|
||||||
float reldist = dist - circleFallof;
|
// float dist = realpos.Length();
|
||||||
noiseFallof = (reldist / (circleRadius - circleFallof) - 1) * -1;
|
// if(dist <= circleRadius && dist >= circleFallof)
|
||||||
}
|
// {
|
||||||
if(dist <= treeCircleRadius && dist >= treeCircleFallof)
|
// float reldist = dist - circleFallof;
|
||||||
{
|
// noiseFallof = (reldist / (circleRadius - circleFallof) - 1) * -1;
|
||||||
float reldist = dist - treeCircleFallof;
|
// }
|
||||||
treeNoiseFallof = (reldist / (treeCircleRadius - treeCircleFallof) - 1) * -1;
|
// if(dist <= treeCircleRadius && dist >= treeCircleFallof)
|
||||||
}
|
// {
|
||||||
else if (dist > treeCircleRadius)
|
// float reldist = dist - treeCircleFallof;
|
||||||
treeNoiseFallof = 0;
|
// treeNoiseFallof = (reldist / (treeCircleRadius - treeCircleFallof) - 1) * -1;
|
||||||
noise *= noiseFallof;
|
// }
|
||||||
treeNoise *= treeNoiseFallof;
|
// else if (dist > treeCircleRadius)
|
||||||
if(dist <= circleRadius && noise >= 0.2f)
|
// treeNoiseFallof = 0;
|
||||||
{
|
// noise *= noiseFallof;
|
||||||
float treernd = rnd.nextFloat01();
|
// treeNoise *= treeNoiseFallof;
|
||||||
int treeid = 0;
|
// if(dist <= circleRadius && noise >= 0.2f)
|
||||||
if(noise >= 0.8f)
|
// {
|
||||||
{
|
// float treernd = rnd.nextFloat01();
|
||||||
if(treeNoise > 0.5f && treernd > 0.4f)
|
// int treeid = 0;
|
||||||
{
|
// if(noise >= 0.8f)
|
||||||
treeid = rnd.nextInt(0,5);
|
// {
|
||||||
props->SetSprite(realposprop + Vector2(0, 0.75f), Vector2(treeid, 1), 4.5f / 10.0f, Vector2(1,2), Vector2(treeid, 0));
|
// if(treeNoise > 0.5f && treernd > 0.4f)
|
||||||
}
|
// {
|
||||||
maps[3]->SetTile(Vector2(x, y), {0,9}, {1,9});
|
// treeid = rnd.nextInt(0,5);
|
||||||
}
|
// props->SetSprite(realposprop + Vector2(0, 0.75f), Vector2(treeid, 1), 4.5f / 10.0f, Vector2(1,2), Vector2(treeid, 0));
|
||||||
else if(noise >= 0.6f)
|
// }
|
||||||
{
|
// maps[3]->SetTile(Vector2(x, y), {0,9}, {1,9});
|
||||||
if(treeNoise > 0.5f && treernd > 0.4f)
|
// }
|
||||||
{
|
// else if(noise >= 0.6f)
|
||||||
treeid = rnd.nextInt(0,5);
|
// {
|
||||||
props->SetSprite(realposprop + Vector2(0, 0.5f), Vector2(treeid, 1), 3.5f / 10.0f, Vector2(1,2), Vector2(treeid, 0));
|
// if(treeNoise > 0.5f && treernd > 0.4f)
|
||||||
}
|
// {
|
||||||
maps[2]->SetTile(Vector2(x, y), {0,9}, {1,9});
|
// treeid = rnd.nextInt(0,5);
|
||||||
}
|
// props->SetSprite(realposprop + Vector2(0, 0.5f), Vector2(treeid, 1), 3.5f / 10.0f, Vector2(1,2), Vector2(treeid, 0));
|
||||||
else if(noise >= 0.4f)
|
// }
|
||||||
{
|
// maps[2]->SetTile(Vector2(x, y), {0,9}, {1,9});
|
||||||
if(treeNoise > 0.5f && treernd > 0.4f)
|
// }
|
||||||
{
|
// else if(noise >= 0.4f)
|
||||||
treeid = rnd.nextInt(0,5);
|
// {
|
||||||
props->SetSprite(realposprop + Vector2(0, 0.25f), Vector2(treeid, 1), 2.5f / 10.0f, Vector2(1,2), Vector2(treeid, 0));
|
// if(treeNoise > 0.5f && treernd > 0.4f)
|
||||||
}
|
// {
|
||||||
maps[1]->SetTile(Vector2(x, y), {0,9}, {1,9});
|
// treeid = rnd.nextInt(0,5);
|
||||||
}
|
// props->SetSprite(realposprop + Vector2(0, 0.25f), Vector2(treeid, 1), 2.5f / 10.0f, Vector2(1,2), Vector2(treeid, 0));
|
||||||
else
|
// }
|
||||||
{
|
// maps[1]->SetTile(Vector2(x, y), {0,9}, {1,9});
|
||||||
if(treeNoise > 0.5f && treernd > 0.4f)
|
// }
|
||||||
{
|
// else
|
||||||
treeid = rnd.nextInt(0,5);
|
// {
|
||||||
props->SetSprite(realposprop, Vector2(treeid, 1), 1.5f / 10.0f, Vector2(1,2), Vector2(treeid, 0));
|
// if(treeNoise > 0.5f && treernd > 0.4f)
|
||||||
}
|
// {
|
||||||
maps[0]->SetTile(Vector2(x, y), {0,9}, {1,9});
|
// treeid = rnd.nextInt(0,5);
|
||||||
}
|
// props->SetSprite(realposprop, Vector2(treeid, 1), 1.5f / 10.0f, Vector2(1,2), Vector2(treeid, 0));
|
||||||
}
|
// }
|
||||||
}
|
// maps[0]->SetTile(Vector2(x, y), {0,9}, {1,9});
|
||||||
}
|
// }
|
||||||
|
// }
|
||||||
//RenderingLayer
|
// }
|
||||||
|
// }
|
||||||
s->AddLayer(&renderingLayer);
|
|
||||||
s->AddLayer(&characterLayer);
|
//RenderingLayer
|
||||||
|
|
||||||
Transformable* player = new Transformable("Player");
|
s->AddLayer(&renderingLayer);
|
||||||
|
|
||||||
Transformable* lastPassCamera = new Transformable("lastPassCamera");
|
float smallDicomDevider = 16.0f;
|
||||||
Camera* lpCam = new Camera();
|
|
||||||
lpCam->SetRenderTarget(wnd);
|
Texture* lutTexture = new Texture(256, 256, 32);
|
||||||
lpCam->SetRenderScale(1);
|
VisualizationData data = VisualizationData::LoadVisualizationSetting("./DCMVizPresets/Preset1.json");
|
||||||
lpCam->layersNotToRender.push_back(gameLayer.GetID());
|
data.FillLUTTexture(*lutTexture);
|
||||||
lpCam->layersNotToRender.push_back(propsLayer.GetID());
|
|
||||||
lpCam->layersNotToRender.push_back(characterLayer.GetID());
|
VolumeTexture3D* dicom = new VolumeTexture3D("./DCM");
|
||||||
lastPassCamera->AddBehaviourScript(lpCam);
|
Vector3 textureSize = {dicom->Width(), dicom->Height(), dicom->Depth()};
|
||||||
CameraSizeChangeNotifyer* camNotifyer = new CameraSizeChangeNotifyer();
|
Vector3 smallTextureSize = { ceilf(textureSize.x / smallDicomDevider), ceilf(textureSize.y / smallDicomDevider), ceilf(textureSize.z / smallDicomDevider)};
|
||||||
camNotifyer->lastSize = {0,0};
|
VolumeTexture3D* dicomSmall = new VolumeTexture3D(smallTextureSize, 32);
|
||||||
camNotifyer->camToObserver = lpCam;
|
|
||||||
lastPassCamera->AddBehaviourScript(camNotifyer);
|
for(int x = 0; x < smallTextureSize.x; x++)
|
||||||
|
{
|
||||||
Vector2 canvasSize = wnd->GetSize() / 4.0f;
|
for(int y = 0; y < smallTextureSize.y; y++)
|
||||||
|
{
|
||||||
IRenderTexture* rt = IRenderTexture::factory->CreateTextureHeap(canvasSize, 3);
|
for(int z = 0; z < smallTextureSize.z; z++)
|
||||||
Transformable* firstPassCamera = new Transformable("firstPassCamera");
|
{
|
||||||
Camera* fpCam = new Camera();
|
float value = 0;
|
||||||
fpCam->SetRenderScale(256);
|
for(int sx = 0; sx < smallDicomDevider; sx++)
|
||||||
fpCam->SetRenderTarget(rt);
|
{
|
||||||
fpCam->layersNotToRender.push_back(renderingLayer.GetID());
|
for(int sy = 0; sy < smallDicomDevider; sy++)
|
||||||
fpCam->layersNotToRender.push_back(propsLayer.GetID());
|
{
|
||||||
fpCam->layersNotToRender.push_back(characterLayer.GetID());
|
for(int sz = 0; sz < smallDicomDevider; sz++)
|
||||||
firstPassCamera->AddBehaviourScript(fpCam);
|
{
|
||||||
RenderTextureResizes* resizer = new RenderTextureResizes();
|
Color c;
|
||||||
resizer->rt = rt;
|
Vector3 pos = Vector3(x * smallDicomDevider + sx, y * smallDicomDevider + sy, z * smallDicomDevider + sz);
|
||||||
camNotifyer->Observe(resizer);
|
if(pos.x < dicom->Width() && pos.y < dicom->Height() && pos.z < dicom->Depth())
|
||||||
firstPassCamera->AddBehaviourScript(resizer);
|
{
|
||||||
firstPassCamera->SetParent(player);
|
dicom->GetPixel(pos, c);
|
||||||
|
ushort index = (ushort)(c.r * 65536.0f);
|
||||||
IRenderTexture* rtProps = IRenderTexture::factory->CreateTextureHeap(canvasSize, 3);
|
int x = index & 0xFF;
|
||||||
Transformable* secondPassCamera = new Transformable("secondPassCamera");
|
int y = index >> 8;
|
||||||
Camera* spCam = new Camera();
|
|
||||||
spCam->SetRenderScale(256);
|
lutTexture->GetPixel(x, y, c);
|
||||||
spCam->SetRenderTarget(rtProps);
|
value = fmax(c.a, value);
|
||||||
spCam->layersNotToRender.push_back(renderingLayer.GetID());
|
}
|
||||||
spCam->layersNotToRender.push_back(gameLayer.GetID());
|
}
|
||||||
spCam->layersNotToRender.push_back(characterLayer.GetID());
|
}
|
||||||
secondPassCamera->AddBehaviourScript(spCam);
|
}
|
||||||
RenderTextureResizes* resizerProps = new RenderTextureResizes();
|
dicomSmall->SetPixelNoApply(x,y,z, Color(value, value, value, value));
|
||||||
resizerProps->rt = rtProps;
|
}
|
||||||
camNotifyer->Observe(resizerProps);
|
}
|
||||||
secondPassCamera->AddBehaviourScript(resizerProps);
|
}
|
||||||
secondPassCamera->SetParent(player);
|
dicomSmall->Apply();
|
||||||
|
|
||||||
//Render pipeline setup
|
//s->AddLayer(&characterLayer);
|
||||||
|
|
||||||
characterLayer.AddTransformable(player);
|
Transformable* player = new Transformable("Player");
|
||||||
renderingLayer.AddTransformable(lastPassCamera);
|
|
||||||
|
Transformable* lastPassCamera = new Transformable("lastPassCamera");
|
||||||
//final
|
Camera* lpCam = new Camera();
|
||||||
|
lpCam->SetRenderTarget(wnd);
|
||||||
Mesh* canvasMesh = new Mesh(Mesh::GetQuadMesh());
|
lpCam->SetRenderScale(0.0025f);
|
||||||
for(auto& vertex : canvasMesh->vertecies)
|
lpCam->SetFarClippingPlane(1000);
|
||||||
{
|
lpCam->layersNotToRender.push_back(gameLayer.GetID());
|
||||||
vertex *= wnd->GetSize();
|
lpCam->layersNotToRender.push_back(propsLayer.GetID());
|
||||||
}
|
lpCam->layersNotToRender.push_back(characterLayer.GetID());
|
||||||
MeshContainer* canvasContainer = new MeshContainer(canvasMesh);
|
lastPassCamera->AddBehaviourScript(lpCam);
|
||||||
|
CameraSizeChangeNotifyer* camNotifyer = new CameraSizeChangeNotifyer();
|
||||||
Material* canvasMat = new Material("canvasMat", ShaderRegistry::GetShader("LastPassShader"));
|
camNotifyer->lastSize = {0,0};
|
||||||
canvasMat->SetValue<float>("threshold", 0.01f);
|
camNotifyer->camToObserver = lpCam;
|
||||||
canvasMat->SetValue<float>("darken", 0.15f);
|
lastPassCamera->AddBehaviourScript(camNotifyer);
|
||||||
canvasMat->SetValue<uint>("colorTextureID", rt->GetTextureId(0));
|
lastPassCamera->position = Vector3(-0.7f, -0.1f, 0);
|
||||||
canvasMat->SetValue<uint>("heightTextureID", rt->GetTextureId(1));
|
lastPassCamera->SetEuler(Vector3(-16.7f, 0.3f, -0.2f));
|
||||||
canvasMat->SetValue<uint>("depthTextureID", rt->GetTextureId(2));
|
|
||||||
canvasMat->SetValue<uint>("colorTexture2ID", rtProps->GetTextureId(0));
|
Vector2 canvasSize = wnd->GetSize() / 4.0f;
|
||||||
canvasMat->SetValue<uint>("heightTexture2ID", rtProps->GetTextureId(1));
|
|
||||||
canvasMat->SetValue<uint>("depthTexture2ID", rtProps->GetTextureId(2));
|
// IRenderTexture* rt = IRenderTexture::factory->CreateTextureHeap(canvasSize, 3);
|
||||||
Renderable* canvasRenderer = new Renderable(canvasMat);
|
// Transformable* firstPassCamera = new Transformable("firstPassCamera");
|
||||||
|
// Camera* fpCam = new Camera();
|
||||||
CanvasScaler* canvasScaler = new CanvasScaler();
|
// fpCam->SetRenderScale(256);
|
||||||
canvasScaler->mesh = canvasMesh;
|
// fpCam->SetRenderTarget(rt);
|
||||||
camNotifyer->Observe(canvasScaler);
|
// fpCam->layersNotToRender.push_back(renderingLayer.GetID());
|
||||||
|
// fpCam->layersNotToRender.push_back(propsLayer.GetID());
|
||||||
lastPassCamera->AddBehaviourScript(canvasContainer);
|
// fpCam->layersNotToRender.push_back(characterLayer.GetID());
|
||||||
lastPassCamera->AddBehaviourScript(canvasRenderer);
|
// firstPassCamera->AddBehaviourScript(fpCam);
|
||||||
lastPassCamera->AddBehaviourScript(canvasScaler);
|
// RenderTextureResizes* resizer = new RenderTextureResizes();
|
||||||
|
// resizer->rt = rt;
|
||||||
//propper resize stuff for prior passes, and canvas, and implement LastPassShader siehe dazu den chat: https://chatgpt.com/c/69985c47-6a50-838b-852d-45bb0b8454e5
|
// camNotifyer->Observe(resizer);
|
||||||
|
// firstPassCamera->AddBehaviourScript(resizer);
|
||||||
|
// firstPassCamera->SetParent(player);
|
||||||
|
|
||||||
|
// IRenderTexture* rtProps = IRenderTexture::factory->CreateTextureHeap(canvasSize, 3);
|
||||||
|
// Transformable* secondPassCamera = new Transformable("secondPassCamera");
|
||||||
|
// Camera* spCam = new Camera();
|
||||||
|
// spCam->SetRenderScale(256);
|
||||||
|
// spCam->SetRenderTarget(rtProps);
|
||||||
|
// spCam->layersNotToRender.push_back(renderingLayer.GetID());
|
||||||
|
// spCam->layersNotToRender.push_back(gameLayer.GetID());
|
||||||
|
// spCam->layersNotToRender.push_back(characterLayer.GetID());
|
||||||
|
// secondPassCamera->AddBehaviourScript(spCam);
|
||||||
|
// RenderTextureResizes* resizerProps = new RenderTextureResizes();
|
||||||
|
// resizerProps->rt = rtProps;
|
||||||
|
// camNotifyer->Observe(resizerProps);
|
||||||
|
// secondPassCamera->AddBehaviourScript(resizerProps);
|
||||||
|
// secondPassCamera->SetParent(player);
|
||||||
|
|
||||||
|
//Render pipeline setup
|
||||||
|
|
||||||
|
// characterLayer.AddTransformable(player);
|
||||||
|
renderingLayer.AddTransformable(lastPassCamera);
|
||||||
|
|
||||||
|
//final
|
||||||
|
|
||||||
|
Mesh* canvasMesh = new Mesh(Mesh::GetQuadMesh());
|
||||||
|
for(auto& vertex : canvasMesh->vertecies)
|
||||||
|
{
|
||||||
|
vertex *= 2;
|
||||||
|
}
|
||||||
|
MeshContainer* canvasContainer = new MeshContainer(canvasMesh);
|
||||||
|
|
||||||
|
Material* canvasMat = new Material("canvasMat", ShaderRegistry::GetShader("DICOMShader"));
|
||||||
|
canvasMat->SetValue<float>("threshold", 0.4f);
|
||||||
|
canvasMat->SetValue<float>("stepSize", 0.01f);
|
||||||
|
canvasMat->SetValue<float>("brickSize", smallDicomDevider);
|
||||||
|
canvasMat->SetValue<Vector3>("texSize", textureSize);
|
||||||
|
canvasMat->SetValue<Vector3>("smallTexSize", smallTextureSize);
|
||||||
|
Vector3 objectScale = Vector3(1,1,1);
|
||||||
|
canvasMat->SetValue<Vector3>("ObjectScale", objectScale);
|
||||||
|
canvasMat->SetValue<ITexture*>("DICOM", dicom);
|
||||||
|
canvasMat->SetValue<ITexture*>("DICOMsmall", dicomSmall);
|
||||||
|
canvasMat->SetValue<ITexture*>("LUT", lutTexture);
|
||||||
|
// canvasMat->SetValue<uint>("heightTextureID", rt->GetTextureId(1));
|
||||||
|
// canvasMat->SetValue<uint>("depthTextureID", rt->GetTextureId(2));
|
||||||
|
// canvasMat->SetValue<uint>("colorTexture2ID", rtProps->GetTextureId(0));
|
||||||
|
// canvasMat->SetValue<uint>("heightTexture2ID", rtProps->GetTextureId(1));
|
||||||
|
// canvasMat->SetValue<uint>("depthTexture2ID", rtProps->GetTextureId(2));
|
||||||
|
Renderable* canvasRenderer = new Renderable(canvasMat);
|
||||||
|
|
||||||
|
CanvasScaler* canvasScaler = new CanvasScaler();
|
||||||
|
canvasScaler->mesh = canvasMesh;
|
||||||
|
camNotifyer->Observe(canvasScaler);
|
||||||
|
|
||||||
|
lastPassCamera->AddBehaviourScript(canvasContainer);
|
||||||
|
lastPassCamera->AddBehaviourScript(canvasRenderer);
|
||||||
|
lastPassCamera->AddBehaviourScript(canvasScaler);
|
||||||
|
|
||||||
|
//propper resize stuff for prior passes, and canvas, and implement LastPassShader siehe dazu den chat: https://chatgpt.com/c/69985c47-6a50-838b-852d-45bb0b8454e5
|
||||||
}
|
}
|
||||||
@@ -1,134 +1,141 @@
|
|||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include "GL/gl3w.h"
|
#include "GL/gl3w.h"
|
||||||
#include "globalVars.hpp"
|
#include "globalVars.hpp"
|
||||||
#include "WindowManager.hpp"
|
#include "WindowManager.hpp"
|
||||||
#if defined(TSE_GLFW)
|
#if defined(TSE_GLFW)
|
||||||
#include "WindowGlfw.hpp"
|
#include "WindowGlfw.hpp"
|
||||||
#elif defined(TSE_SDL3)
|
#elif defined(TSE_SDL3)
|
||||||
#include "WindowSdl3.hpp"
|
#include "WindowSdl3.hpp"
|
||||||
#endif
|
#endif
|
||||||
#include "OpenGLRenderingBackend.hpp"
|
#include "OpenGLRenderingBackend.hpp"
|
||||||
#include "imgui/imgui.h"
|
#include "imgui/imgui.h"
|
||||||
#include "shader/defaultShaderHandler.cpp"
|
#include "shader/defaultShaderHandler.cpp"
|
||||||
#include "DefaultRendererOpenGL.hpp"
|
#include "DefaultRendererOpenGL.hpp"
|
||||||
#include "BehaviourScripts/RectBase.hpp"
|
#include "BehaviourScripts/RectBase.hpp"
|
||||||
#include "BehaviourScripts/Renderable.hpp"
|
#include "BehaviourScripts/Renderable.hpp"
|
||||||
#include "BehaviourScripts/Camera.hpp"
|
#include "BehaviourScripts/Camera.hpp"
|
||||||
#include "elements/Sprite.hpp"
|
#include "elements/Sprite.hpp"
|
||||||
#include "elements/Texture.hpp"
|
#include "elements/Texture.hpp"
|
||||||
#include "elements/Layer.hpp"
|
#include "elements/Layer.hpp"
|
||||||
#include "elements/Scene.hpp"
|
#include "elements/Scene.hpp"
|
||||||
#include "EditorSubsystem.hpp"
|
#include "EditorSubsystem.hpp"
|
||||||
#include "game.hpp"
|
#include "game.hpp"
|
||||||
#include "shaders/TileMapShader.hpp"
|
#include "shaders/TileMapShader.hpp"
|
||||||
#include "shaders/LastPassShader.hpp"
|
#include "shaders/LastPassShader.hpp"
|
||||||
|
#include "shaders/DICOMShader.hpp"
|
||||||
#define USE_EDITOR
|
|
||||||
|
#define USE_EDITOR
|
||||||
using namespace TSE;
|
|
||||||
#if defined(TSE_GLFW)
|
using namespace TSE;
|
||||||
using namespace TSE::GLFW;
|
#if defined(TSE_GLFW)
|
||||||
#elif defined(TSE_SDL3)
|
using namespace TSE::GLFW;
|
||||||
using namespace TSE::SDL3;
|
#elif defined(TSE_SDL3)
|
||||||
#endif
|
using namespace TSE::SDL3;
|
||||||
using namespace TSE::OpenGL;
|
#endif
|
||||||
using namespace TSE::EDITOR;
|
using namespace TSE::OpenGL;
|
||||||
|
using namespace TSE::EDITOR;
|
||||||
IWindow* wnd = nullptr;
|
|
||||||
DefaultRendererOpenGL* rend = nullptr;
|
IWindow* wnd = nullptr;
|
||||||
Scene* currentScene = nullptr;
|
DefaultRendererOpenGL* rend = nullptr;
|
||||||
Layer* planeteryLayer = nullptr;
|
Scene* currentScene = nullptr;
|
||||||
EditorSubsystem* editor;
|
Layer* planeteryLayer = nullptr;
|
||||||
|
EditorSubsystem* editor;
|
||||||
void SetupWindow()
|
|
||||||
{
|
void SetupWindow()
|
||||||
Color backColor(0.0f, 0.0f, 0.0f, 0.0f);
|
{
|
||||||
#if defined(TSE_GLFW)
|
Color backColor(0.0f, 0.0f, 0.0f, 0.0f);
|
||||||
#ifdef USE_EDITOR
|
#if defined(TSE_GLFW)
|
||||||
wnd = new WindowGlfw(PROJECT_NAME, 800, 600, new OpenGLRenderingBackend(backColor, false, 8, true), WindowType::Maximized);
|
#ifdef USE_EDITOR
|
||||||
editor = new EditorSubsystem();
|
wnd = new WindowGlfw(PROJECT_NAME, 800, 600, new OpenGLRenderingBackend(backColor, false, 8, true), WindowType::Maximized);
|
||||||
#else
|
editor = new EditorSubsystem();
|
||||||
wnd = new WindowGlfw(PROJECT_NAME, 1920, 1080, new OpenGLRenderingBackend(backColor, false, 8, false), WindowType::Fullscreen);
|
#else
|
||||||
#endif
|
wnd = new WindowGlfw(PROJECT_NAME, 1920, 1080, new OpenGLRenderingBackend(backColor, false, 8, false), WindowType::Fullscreen);
|
||||||
#elif defined(TSE_SDL3)
|
#endif
|
||||||
#ifdef USE_EDITOR
|
#elif defined(TSE_SDL3)
|
||||||
wnd = new WindowSdl3(PROJECT_NAME, 800, 600, new OpenGLRenderingBackend(backColor, false, 8, true), WindowType::Maximized);
|
#ifdef USE_EDITOR
|
||||||
editor = new EditorSubsystem();
|
wnd = new WindowSdl3(PROJECT_NAME, 800, 600, new OpenGLRenderingBackend(backColor, false, 8, true), WindowType::Maximized);
|
||||||
#else
|
editor = new EditorSubsystem();
|
||||||
wnd = new WindowSdl3(PROJECT_NAME, 1920, 1080, new OpenGLRenderingBackend(backColor, false, 8, false), WindowType::Fullscreen);
|
#else
|
||||||
#endif
|
wnd = new WindowSdl3(PROJECT_NAME, 1920, 1080, new OpenGLRenderingBackend(backColor, false, 8, false), WindowType::Fullscreen);
|
||||||
#endif
|
#endif
|
||||||
|
#endif
|
||||||
LoadBasicShaders(wnd->GetSize().x, wnd->GetSize().y);
|
|
||||||
TileMapShader::Init(wnd->GetSize().x, wnd->GetSize().y);
|
LoadBasicShaders(wnd->GetSize().x, wnd->GetSize().y);
|
||||||
LastPassShader::Init(wnd->GetSize().x, wnd->GetSize().y);
|
TileMapShader::Init(wnd->GetSize().x, wnd->GetSize().y);
|
||||||
ShaderRegistry::SetShader("TileMapShader v2", TileMapShader::Instance());
|
LastPassShader::Init(wnd->GetSize().x, wnd->GetSize().y);
|
||||||
ShaderRegistry::SetShader("LastPassShader", LastPassShader::Instance());
|
DICOMShader::Init(wnd->GetSize().x, wnd->GetSize().y);
|
||||||
|
ShaderRegistry::SetShader("TileMapShader v2", TileMapShader::Instance());
|
||||||
rend = new DefaultRendererOpenGL(*BasicShader::Instance());
|
ShaderRegistry::SetShader("LastPassShader", LastPassShader::Instance());
|
||||||
currentScene = new Scene();
|
ShaderRegistry::SetShader("DICOMShader", DICOMShader::Instance());
|
||||||
|
|
||||||
#ifdef USE_EDITOR
|
rend = new DefaultRendererOpenGL(*BasicShader::Instance());
|
||||||
((Camera*)Transformable::Find(".EditorCamera")->GetBehaviourScript(CAMERA))->layersNotToRender.push_back(game::renderingLayer.GetID());
|
currentScene = new Scene();
|
||||||
((Camera*)Transformable::Find(".EditorCamera")->GetBehaviourScript(CAMERA))->SetRenderScale(128);
|
|
||||||
currentScene->AddLayer(&editor->editorLayer);
|
#ifdef USE_EDITOR
|
||||||
editor->hv.SetScene(currentScene);
|
//((Camera*)Transformable::Find(".EditorCamera")->GetBehaviourScript(CAMERA))->layersNotToRender.push_back(game::renderingLayer.GetID());
|
||||||
#endif
|
((Camera*)Transformable::Find(".EditorCamera")->GetBehaviourScript(CAMERA))->SetRenderScale(0.002f);
|
||||||
|
((Camera*)Transformable::Find(".EditorCamera")->GetBehaviourScript(CAMERA))->SetFarClippingPlane(1000);
|
||||||
|
((Camera*)Transformable::Find(".EditorCamera")->GetBehaviourScript(CAMERA))->SetNearClippingPlane(0.1f);
|
||||||
game::setup(currentScene, wnd);
|
Transformable::Find(".EditorCamera")->position = Vector3(-30.678f, 618.352f, 139.872f);
|
||||||
|
Transformable::Find(".EditorCamera")->rotation = Quaternion::FromEulerAngles(Vector3(86.348f, -0.450f, 9.699f));
|
||||||
wnd->DoneSetup();
|
currentScene->AddLayer(&editor->editorLayer);
|
||||||
}
|
editor->hv.SetScene(currentScene);
|
||||||
|
#endif
|
||||||
void CleanUp()
|
|
||||||
{
|
|
||||||
#ifdef USE_EDITOR
|
game::setup(currentScene, wnd);
|
||||||
delete(editor);
|
|
||||||
#endif
|
wnd->DoneSetup();
|
||||||
|
}
|
||||||
UnLoadBasicShaders();
|
|
||||||
}
|
void CleanUp()
|
||||||
|
{
|
||||||
void GameLoop()
|
#ifdef USE_EDITOR
|
||||||
{
|
delete(editor);
|
||||||
while(!wnd->ShouldClose())
|
#endif
|
||||||
{
|
|
||||||
wnd->Clear();
|
UnLoadBasicShaders();
|
||||||
rend->Begin();
|
}
|
||||||
|
|
||||||
if(currentScene != nullptr)
|
void GameLoop()
|
||||||
currentScene->Render(*rend, *wnd);
|
{
|
||||||
|
while(!wnd->ShouldClose())
|
||||||
rend->End();
|
{
|
||||||
rend->Flush();
|
wnd->Clear();
|
||||||
|
rend->Begin();
|
||||||
if(currentScene != nullptr)
|
|
||||||
currentScene->DoneRender();
|
if(currentScene != nullptr)
|
||||||
|
currentScene->Render(*rend, *wnd);
|
||||||
#ifdef USE_EDITOR
|
|
||||||
editor->controller.Update();
|
rend->End();
|
||||||
#endif
|
rend->Flush();
|
||||||
wnd->Update();
|
|
||||||
if(currentScene != nullptr)
|
if(currentScene != nullptr)
|
||||||
currentScene->Update();
|
currentScene->DoneRender();
|
||||||
}
|
|
||||||
}
|
#ifdef USE_EDITOR
|
||||||
|
editor->controller.Update();
|
||||||
|
#endif
|
||||||
int main(int argc, char** argv)
|
wnd->Update();
|
||||||
{
|
if(currentScene != nullptr)
|
||||||
SetupWindow();
|
currentScene->Update();
|
||||||
|
}
|
||||||
GameLoop();
|
}
|
||||||
|
|
||||||
CleanUp();
|
|
||||||
return 0;
|
int main(int argc, char** argv)
|
||||||
}
|
{
|
||||||
|
SetupWindow();
|
||||||
#if defined(_WIN32)
|
|
||||||
extern "C" {
|
GameLoop();
|
||||||
__declspec(dllexport) unsigned long NvOptimusEnablement = 0x00000001; // NVIDIA
|
|
||||||
__declspec(dllexport) int AmdPowerXpressRequestHighPerformance = 1; // AMD
|
CleanUp();
|
||||||
}
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if defined(_WIN32)
|
||||||
|
extern "C" {
|
||||||
|
__declspec(dllexport) unsigned long NvOptimusEnablement = 0x00000001; // NVIDIA
|
||||||
|
__declspec(dllexport) int AmdPowerXpressRequestHighPerformance = 1; // AMD
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
131
TSE-RTS/src/shaders/DICOMShader.cpp
Normal file
131
TSE-RTS/src/shaders/DICOMShader.cpp
Normal file
@@ -0,0 +1,131 @@
|
|||||||
|
#include "DICOMShader.hpp"
|
||||||
|
|
||||||
|
#include "DICOMShaderGLSL.hpp"
|
||||||
|
#include "BehaviourScripts/Renderable.hpp"
|
||||||
|
#include "Color.hpp"
|
||||||
|
|
||||||
|
using namespace TSE;
|
||||||
|
using namespace TSE::OpenGL;
|
||||||
|
|
||||||
|
#define SHADER_VERTEX_INDEX 0
|
||||||
|
#define SHADER_UV_INDEX 1
|
||||||
|
|
||||||
|
#define SHADER_PACKAGE_SIZE (sizeof(float) * (3 + 2))
|
||||||
|
|
||||||
|
DICOMShader* DICOMShader::instance = nullptr;
|
||||||
|
|
||||||
|
DICOMShader *DICOMShader::Instance()
|
||||||
|
{
|
||||||
|
return instance;
|
||||||
|
}
|
||||||
|
|
||||||
|
void DICOMShader::Destroy()
|
||||||
|
{
|
||||||
|
if(instance != nullptr)
|
||||||
|
delete instance;
|
||||||
|
instance = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
void DICOMShader::Init(float width, float height)
|
||||||
|
{
|
||||||
|
std::vector<std::unique_ptr<ShaderPart>> parts;
|
||||||
|
parts.push_back(ShaderPart::LoadFromString(vertDICOM, GL_VERTEX_SHADER));
|
||||||
|
parts.push_back(ShaderPart::LoadFromString(fragDICOM, GL_FRAGMENT_SHADER));
|
||||||
|
instance = new DICOMShader(std::move(parts));
|
||||||
|
|
||||||
|
instance->Enable();
|
||||||
|
instance->SetUniform("DICOMTexture", 0);
|
||||||
|
instance->SetUniform("SmallDICOMTexture", 1);
|
||||||
|
instance->SetUniform("LUTTexture", 2);
|
||||||
|
instance->SetUniform("Threshold", 0.5f);
|
||||||
|
instance->SetUniform("TexSize", &Vector3::zero);
|
||||||
|
instance->SetUniform("SmallTexSize", &Vector3::zero);
|
||||||
|
instance->SetUniform("StepSize", 0.5f);
|
||||||
|
instance->Disable();
|
||||||
|
}
|
||||||
|
|
||||||
|
DICOMShader::DICOMShader(std::vector<std::unique_ptr<TSE::OpenGL::ShaderPart>> &&parts) : Shader(parts)
|
||||||
|
{
|
||||||
|
PackageSize = SHADER_PACKAGE_SIZE;
|
||||||
|
}
|
||||||
|
|
||||||
|
void DICOMShader::OnEnable() const
|
||||||
|
{
|
||||||
|
glEnableVertexAttribArray(SHADER_VERTEX_INDEX);
|
||||||
|
glVertexAttribPointer(SHADER_VERTEX_INDEX, 3, GL_FLOAT, false, SHADER_PACKAGE_SIZE, (void*)0);
|
||||||
|
glEnableVertexAttribArray(SHADER_UV_INDEX);
|
||||||
|
glVertexAttribPointer(SHADER_UV_INDEX, 2, GL_FLOAT, false, SHADER_PACKAGE_SIZE, (void*)(sizeof(float) * 3));
|
||||||
|
}
|
||||||
|
|
||||||
|
void DICOMShader::OnDisable() const
|
||||||
|
{
|
||||||
|
glDisableVertexAttribArray(SHADER_VERTEX_INDEX);
|
||||||
|
glDisableVertexAttribArray(SHADER_UV_INDEX);
|
||||||
|
}
|
||||||
|
|
||||||
|
void DICOMShader::OnFlush()
|
||||||
|
{
|
||||||
|
glActiveTexture(GL_TEXTURE0);
|
||||||
|
glBindTexture(GL_TEXTURE_3D, DICOM->GetTextureId());
|
||||||
|
glActiveTexture(GL_TEXTURE1);
|
||||||
|
glBindTexture(GL_TEXTURE_3D, SmallDICOM->GetTextureId());
|
||||||
|
glActiveTexture(GL_TEXTURE2);
|
||||||
|
glBindTexture(GL_TEXTURE_2D, LUT->GetTextureId());
|
||||||
|
SetUniform("Threshold", Threshold);
|
||||||
|
if(stepSize < 0.001f) stepSize = 0.001f;
|
||||||
|
SetUniform("StepSize", stepSize);
|
||||||
|
SetUniform("TexSize", &size);
|
||||||
|
SetUniform("SmallTexSize", &smallSize);
|
||||||
|
SetUniform("ObjectScale", &scale);
|
||||||
|
SetUniform("BrickScale", brickSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
void DICOMShader::OnDrawCall(int indexCount)
|
||||||
|
{
|
||||||
|
glDrawElements(GL_TRIANGLES, indexCount, GL_UNSIGNED_SHORT, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
void DICOMShader::OnSubmit(const TSE::Transformable &t, float *&target, TSE::TransformationStack &stack, void (*restartDrawcall)(TSE::IRenderer &), TSE::IRenderer &rnd)
|
||||||
|
{
|
||||||
|
auto* r = dynamic_cast<Renderable*>(t.GetBehaviourScript(RENDERABLE));
|
||||||
|
if (!r) return;
|
||||||
|
if(!r->GetMaterial()->HasValue("threshold")) return;
|
||||||
|
if(!r->GetMaterial()->HasValue("texSize")) return;
|
||||||
|
if(!r->GetMaterial()->HasValue("smallTexSize")) return;
|
||||||
|
if(!r->GetMaterial()->HasValue("DICOM")) return;
|
||||||
|
if(!r->GetMaterial()->HasValue("DICOMsmall")) return;
|
||||||
|
if(!r->GetMaterial()->HasValue("stepSize")) return;
|
||||||
|
if(!r->GetMaterial()->HasValue("ObjectScale")) return;
|
||||||
|
if(!r->GetMaterial()->HasValue("LUT")) return;
|
||||||
|
if(!r->GetMaterial()->HasValue("brickSize")) return;
|
||||||
|
Threshold = r->GetMaterial()->GetValue<float>("threshold");
|
||||||
|
stepSize = r->GetMaterial()->GetValue<float>("stepSize");
|
||||||
|
brickSize = r->GetMaterial()->GetValue<float>("brickSize");
|
||||||
|
size = r->GetMaterial()->GetValue<Vector3>("texSize");
|
||||||
|
smallSize = r->GetMaterial()->GetValue<Vector3>("smallTexSize");
|
||||||
|
scale = r->GetMaterial()->GetValue<Vector3>("ObjectScale");
|
||||||
|
DICOM = r->GetMaterial()->GetValue<ITexture*>("DICOM");
|
||||||
|
LUT = r->GetMaterial()->GetValue<ITexture*>("LUT");
|
||||||
|
SmallDICOM = r->GetMaterial()->GetValue<ITexture*>("DICOMsmall");
|
||||||
|
|
||||||
|
const Vector3* verts = r->GetVertices();
|
||||||
|
const Vector2* uvs = r->GetUVs();
|
||||||
|
ushort vCount = r->GetVertexCount();
|
||||||
|
|
||||||
|
Matrix4x4 matr = t.GetLocalMatrix();
|
||||||
|
|
||||||
|
stack.Push(matr);
|
||||||
|
const Matrix4x4& top = stack.Top();
|
||||||
|
|
||||||
|
for (ushort i = 0; i < vCount; i++) {
|
||||||
|
Vector3 p = top * verts[i];
|
||||||
|
Vector2 uv = uvs[i];
|
||||||
|
*target++ = p.x;
|
||||||
|
*target++ = p.y;
|
||||||
|
*target++ = p.z;
|
||||||
|
*target++ = uv.x;
|
||||||
|
*target++ = uv.y;
|
||||||
|
}
|
||||||
|
|
||||||
|
stack.Pop();
|
||||||
|
}
|
||||||
35
TSE-RTS/src/shaders/DICOMShader.hpp
Normal file
35
TSE-RTS/src/shaders/DICOMShader.hpp
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "GL/gl3w.h"
|
||||||
|
#include "GL/gl.h"
|
||||||
|
#include "shader/Shader.hpp"
|
||||||
|
#include "Types.hpp"
|
||||||
|
#include "interfaces/ITexture.hpp"
|
||||||
|
|
||||||
|
class DICOMShader : public TSE::OpenGL::Shader
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
static DICOMShader* instance;
|
||||||
|
TSE::ITexture* DICOM;
|
||||||
|
TSE::ITexture* SmallDICOM;
|
||||||
|
TSE::ITexture* LUT;
|
||||||
|
TSE::Vector3 size;
|
||||||
|
TSE::Vector3 smallSize;
|
||||||
|
TSE::Vector3 scale;
|
||||||
|
float Threshold;
|
||||||
|
float stepSize;
|
||||||
|
float brickSize;
|
||||||
|
|
||||||
|
public:
|
||||||
|
static DICOMShader* Instance();
|
||||||
|
static void Destroy();
|
||||||
|
static void Init(float width, float height);
|
||||||
|
DICOMShader(std::vector<std::unique_ptr<TSE::OpenGL::ShaderPart>>&& parts);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void OnEnable() const override;
|
||||||
|
void OnDisable() const override;
|
||||||
|
void OnFlush() override;
|
||||||
|
void OnDrawCall(int indexCount) override;
|
||||||
|
void OnSubmit(const TSE::Transformable& t, float*& target, TSE::TransformationStack& stack, void (*restartDrawcall)(TSE::IRenderer&), TSE::IRenderer& rnd) override;
|
||||||
|
};
|
||||||
279
TSE-RTS/src/shaders/DICOMShaderGLSL.hpp
Normal file
279
TSE-RTS/src/shaders/DICOMShaderGLSL.hpp
Normal file
@@ -0,0 +1,279 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
inline const char* vertDICOM = R"(
|
||||||
|
#version 330 core
|
||||||
|
|
||||||
|
layout (location = 0) in vec3 position;
|
||||||
|
layout (location = 1) in vec2 uv;
|
||||||
|
|
||||||
|
uniform mat4 prMatrix;
|
||||||
|
uniform mat4 camMatrix;
|
||||||
|
|
||||||
|
out DATA
|
||||||
|
{
|
||||||
|
vec2 uv_out;
|
||||||
|
} vs_out;
|
||||||
|
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
gl_Position = vec4(position.x, position.y, 0.0, 1.0);
|
||||||
|
vs_out.uv_out = uv;
|
||||||
|
}
|
||||||
|
)";
|
||||||
|
|
||||||
|
inline const char* fragDICOM = R"(
|
||||||
|
#version 330 core
|
||||||
|
layout (location = 0) out vec4 color;
|
||||||
|
|
||||||
|
uniform sampler3D DICOMTexture;
|
||||||
|
uniform sampler3D SmallDICOMTexture;
|
||||||
|
uniform sampler2D LUTTexture;
|
||||||
|
|
||||||
|
uniform vec3 CamPos;
|
||||||
|
uniform vec3 CamRight;
|
||||||
|
uniform vec3 CamUp;
|
||||||
|
uniform vec3 CamForward;
|
||||||
|
|
||||||
|
uniform float OrthoLeft;
|
||||||
|
uniform float OrthoRight;
|
||||||
|
uniform float OrthoBottom;
|
||||||
|
uniform float OrthoTop;
|
||||||
|
uniform float NearPlane;
|
||||||
|
uniform float FarPlane;
|
||||||
|
|
||||||
|
uniform float Threshold;
|
||||||
|
uniform float StepSize;
|
||||||
|
uniform vec3 TexSize;
|
||||||
|
uniform vec3 SmallTexSize;
|
||||||
|
uniform vec3 ObjectScale;
|
||||||
|
|
||||||
|
uniform float BrickScale;
|
||||||
|
|
||||||
|
const float EPSILON = 1e-6;
|
||||||
|
|
||||||
|
in DATA
|
||||||
|
{
|
||||||
|
vec2 uv_out;
|
||||||
|
} fs_in;
|
||||||
|
|
||||||
|
bool IntersectAABB(vec3 rayOrigin, vec3 rayDir, vec3 boxMin, vec3 boxMax, out float tEnter, out float tExit)
|
||||||
|
{
|
||||||
|
vec3 invDir = 1.0 / rayDir;
|
||||||
|
|
||||||
|
vec3 t0 = (boxMin - rayOrigin) * invDir;
|
||||||
|
vec3 t1 = (boxMax - rayOrigin) * invDir;
|
||||||
|
|
||||||
|
vec3 tMin3 = min(t0, t1);
|
||||||
|
vec3 tMax3 = max(t0, t1);
|
||||||
|
|
||||||
|
tEnter = max(max(tMin3.x, tMin3.y), tMin3.z);
|
||||||
|
tExit = min(min(tMax3.x, tMax3.y), tMax3.z);
|
||||||
|
|
||||||
|
return tExit >= max(tEnter, 0.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void BuildOrthoRay(out vec3 rayOrigin, out vec3 rayDir)
|
||||||
|
{
|
||||||
|
vec2 uv = fs_in.uv_out;
|
||||||
|
|
||||||
|
float xView = mix(OrthoLeft, OrthoRight, uv.x);
|
||||||
|
float yView = mix(OrthoBottom, OrthoTop, uv.y);
|
||||||
|
|
||||||
|
rayOrigin = CamPos
|
||||||
|
+ CamRight * xView
|
||||||
|
+ CamUp * yView
|
||||||
|
+ CamForward * NearPlane;
|
||||||
|
|
||||||
|
rayDir = CamForward;
|
||||||
|
}
|
||||||
|
|
||||||
|
vec4 TraverseFineBlock(vec3 rayOrigin, vec3 rayDir, float blockTEnter, float blockTExit, ivec3 brickCoord, float brickScaleF, ivec3 gridSize, vec4 currColor)
|
||||||
|
{
|
||||||
|
int brickSize = int(brickScaleF);
|
||||||
|
|
||||||
|
ivec3 blockVoxelMin = brickCoord * brickSize;
|
||||||
|
ivec3 blockVoxelMax = min(blockVoxelMin + ivec3(brickSize - 1), gridSize - ivec3(1));
|
||||||
|
|
||||||
|
float t = blockTEnter + 1e-4;
|
||||||
|
vec3 pos = rayOrigin + rayDir * t;
|
||||||
|
|
||||||
|
ivec3 voxel = ivec3(floor(pos / ObjectScale));
|
||||||
|
voxel = clamp(voxel, blockVoxelMin, blockVoxelMax);
|
||||||
|
|
||||||
|
ivec3 step;
|
||||||
|
step.x = (rayDir.x > 0.0) ? 1 : ((rayDir.x < 0.0) ? -1 : 0);
|
||||||
|
step.y = (rayDir.y > 0.0) ? 1 : ((rayDir.y < 0.0) ? -1 : 0);
|
||||||
|
step.z = (rayDir.z > 0.0) ? 1 : ((rayDir.z < 0.0) ? -1 : 0);
|
||||||
|
|
||||||
|
vec3 tDelta;
|
||||||
|
tDelta.x = (step.x != 0) ? abs(ObjectScale.x / rayDir.x) : 1e30;
|
||||||
|
tDelta.y = (step.y != 0) ? abs(ObjectScale.y / rayDir.y) : 1e30;
|
||||||
|
tDelta.z = (step.z != 0) ? abs(ObjectScale.z / rayDir.z) : 1e30;
|
||||||
|
|
||||||
|
vec3 nextBoundary;
|
||||||
|
nextBoundary.x = (step.x > 0) ? (float(voxel.x) + 1.0) * ObjectScale.x : float(voxel.x) * ObjectScale.x;
|
||||||
|
nextBoundary.y = (step.y > 0) ? (float(voxel.y) + 1.0) * ObjectScale.y : float(voxel.y) * ObjectScale.y;
|
||||||
|
nextBoundary.z = (step.z > 0) ? (float(voxel.z) + 1.0) * ObjectScale.z : float(voxel.z) * ObjectScale.z;
|
||||||
|
|
||||||
|
vec3 tMax;
|
||||||
|
tMax.x = (step.x != 0) ? ((nextBoundary.x - rayOrigin.x) / rayDir.x) : 1e30;
|
||||||
|
tMax.y = (step.y != 0) ? ((nextBoundary.y - rayOrigin.y) / rayDir.y) : 1e30;
|
||||||
|
tMax.z = (step.z != 0) ? ((nextBoundary.z - rayOrigin.z) / rayDir.z) : 1e30;
|
||||||
|
|
||||||
|
int maxIters = brickSize * 3 + 8;
|
||||||
|
|
||||||
|
for (int i = 0; i < maxIters; ++i)
|
||||||
|
{
|
||||||
|
if (t > blockTExit)
|
||||||
|
break;
|
||||||
|
|
||||||
|
float density = texelFetch(DICOMTexture, voxel, 0).r;
|
||||||
|
uint v = uint(density * 65535.0 + 0.5);
|
||||||
|
uint x = v & 0xFFu;
|
||||||
|
uint y = v >> 8u;
|
||||||
|
|
||||||
|
vec4 lutValue = texelFetch(LUTTexture, ivec2(x, y), 0);
|
||||||
|
if (lutValue.a > EPSILON)
|
||||||
|
{
|
||||||
|
currColor.xyz += (1.0 - currColor.w) * lutValue.rgb * lutValue.a;
|
||||||
|
currColor.w += (1.0 - currColor.w) * lutValue.a;
|
||||||
|
|
||||||
|
if (currColor.w > 0.98)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tMax.x <= tMax.y && tMax.x <= tMax.z)
|
||||||
|
{
|
||||||
|
voxel.x += step.x;
|
||||||
|
if (voxel.x < blockVoxelMin.x || voxel.x > blockVoxelMax.x) break;
|
||||||
|
t = tMax.x;
|
||||||
|
tMax.x += tDelta.x;
|
||||||
|
}
|
||||||
|
else if (tMax.y <= tMax.z)
|
||||||
|
{
|
||||||
|
voxel.y += step.y;
|
||||||
|
if (voxel.y < blockVoxelMin.y || voxel.y > blockVoxelMax.y) break;
|
||||||
|
t = tMax.y;
|
||||||
|
tMax.y += tDelta.y;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
voxel.z += step.z;
|
||||||
|
if (voxel.z < blockVoxelMin.z || voxel.z > blockVoxelMax.z) break;
|
||||||
|
t = tMax.z;
|
||||||
|
tMax.z += tDelta.z;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return currColor;
|
||||||
|
}
|
||||||
|
|
||||||
|
vec4 RenderVoxelDDA(vec3 rayOrigin, vec3 rayDir)
|
||||||
|
{
|
||||||
|
ivec3 gridSize = ivec3(TexSize);
|
||||||
|
ivec3 smallGridSize = ivec3(SmallTexSize);
|
||||||
|
|
||||||
|
float brickScaleF = max(BrickScale, 1.0);
|
||||||
|
int brickSize = int(brickScaleF);
|
||||||
|
|
||||||
|
vec3 scaledSize = TexSize * ObjectScale;
|
||||||
|
vec3 boxMin = vec3(0.0);
|
||||||
|
vec3 boxMax = scaledSize;
|
||||||
|
|
||||||
|
float tEnter, tExit;
|
||||||
|
if (!IntersectAABB(rayOrigin, rayDir, boxMin, boxMax, tEnter, tExit))
|
||||||
|
return vec4(0.0, 0.0, 0.0, 1.0);
|
||||||
|
|
||||||
|
tEnter = max(tEnter, 0.0);
|
||||||
|
tExit = min(tExit, FarPlane - NearPlane);
|
||||||
|
|
||||||
|
vec3 brickWorldSize = ObjectScale * brickScaleF;
|
||||||
|
|
||||||
|
float t = tEnter + 1e-4;
|
||||||
|
vec3 pos = rayOrigin + rayDir * t;
|
||||||
|
|
||||||
|
ivec3 brick = ivec3(floor(pos / brickWorldSize));
|
||||||
|
ivec3 brickMax = smallGridSize - ivec3(1);
|
||||||
|
brick = clamp(brick, ivec3(0), brickMax);
|
||||||
|
|
||||||
|
ivec3 step;
|
||||||
|
step.x = (rayDir.x > 0.0) ? 1 : ((rayDir.x < 0.0) ? -1 : 0);
|
||||||
|
step.y = (rayDir.y > 0.0) ? 1 : ((rayDir.y < 0.0) ? -1 : 0);
|
||||||
|
step.z = (rayDir.z > 0.0) ? 1 : ((rayDir.z < 0.0) ? -1 : 0);
|
||||||
|
|
||||||
|
vec3 tDelta;
|
||||||
|
tDelta.x = (step.x != 0) ? abs(brickWorldSize.x / rayDir.x) : 1e30;
|
||||||
|
tDelta.y = (step.y != 0) ? abs(brickWorldSize.y / rayDir.y) : 1e30;
|
||||||
|
tDelta.z = (step.z != 0) ? abs(brickWorldSize.z / rayDir.z) : 1e30;
|
||||||
|
|
||||||
|
vec3 nextBoundary;
|
||||||
|
nextBoundary.x = (step.x > 0) ? (float(brick.x) + 1.0) * brickWorldSize.x : float(brick.x) * brickWorldSize.x;
|
||||||
|
nextBoundary.y = (step.y > 0) ? (float(brick.y) + 1.0) * brickWorldSize.y : float(brick.y) * brickWorldSize.y;
|
||||||
|
nextBoundary.z = (step.z > 0) ? (float(brick.z) + 1.0) * brickWorldSize.z : float(brick.z) * brickWorldSize.z;
|
||||||
|
|
||||||
|
vec3 tMax;
|
||||||
|
tMax.x = (step.x != 0) ? ((nextBoundary.x - rayOrigin.x) / rayDir.x) : 1e30;
|
||||||
|
tMax.y = (step.y != 0) ? ((nextBoundary.y - rayOrigin.y) / rayDir.y) : 1e30;
|
||||||
|
tMax.z = (step.z != 0) ? ((nextBoundary.z - rayOrigin.z) / rayDir.z) : 1e30;
|
||||||
|
|
||||||
|
int maxIters = smallGridSize.x + smallGridSize.y + smallGridSize.z + 8;
|
||||||
|
|
||||||
|
float count = 0;
|
||||||
|
|
||||||
|
float increment = StepSize;
|
||||||
|
|
||||||
|
vec4 colorAcum = vec4(0.0);
|
||||||
|
|
||||||
|
for (int i = 0; i < maxIters; ++i)
|
||||||
|
{
|
||||||
|
if (t > tExit)
|
||||||
|
break;
|
||||||
|
|
||||||
|
float brickDensity = texelFetch(SmallDICOMTexture, brick, 0).r;
|
||||||
|
|
||||||
|
float cellTExit = min(min(tMax.x, tMax.y), tMax.z);
|
||||||
|
cellTExit = min(cellTExit, tExit);
|
||||||
|
|
||||||
|
if (brickDensity >= EPSILON)
|
||||||
|
{
|
||||||
|
colorAcum = TraverseFineBlock(rayOrigin, rayDir, t, cellTExit, brick, brickScaleF, gridSize, colorAcum);
|
||||||
|
|
||||||
|
if (colorAcum.w > 0.98)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tMax.x <= tMax.y && tMax.x <= tMax.z)
|
||||||
|
{
|
||||||
|
brick.x += step.x;
|
||||||
|
if (brick.x < 0 || brick.x > brickMax.x) break;
|
||||||
|
t = tMax.x;
|
||||||
|
tMax.x += tDelta.x;
|
||||||
|
}
|
||||||
|
else if (tMax.y <= tMax.z)
|
||||||
|
{
|
||||||
|
brick.y += step.y;
|
||||||
|
if (brick.y < 0 || brick.y > brickMax.y) break;
|
||||||
|
t = tMax.y;
|
||||||
|
tMax.y += tDelta.y;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
brick.z += step.z;
|
||||||
|
if (brick.z < 0 || brick.z > brickMax.z) break;
|
||||||
|
t = tMax.z;
|
||||||
|
tMax.z += tDelta.z;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//return vec4(colorAcum.w, colorAcum.w, colorAcum.w, 1.0);
|
||||||
|
return vec4(colorAcum.x, colorAcum.y, colorAcum.z, 1.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
vec3 rayOrigin, rayDir;
|
||||||
|
BuildOrthoRay(rayOrigin, rayDir);
|
||||||
|
color = RenderVoxelDDA(rayOrigin, rayDir);
|
||||||
|
}
|
||||||
|
)";
|
||||||
Reference in New Issue
Block a user