Skip to content

Commit

Permalink
Add gui project
Browse files Browse the repository at this point in the history
Adds gui project that gives more accessible support for emblem json pre-processing, such as chroma keying
  • Loading branch information
pawREP committed Sep 8, 2023
1 parent 45d2f05 commit d0eb099
Show file tree
Hide file tree
Showing 16 changed files with 25,663 additions and 1 deletion.
8 changes: 7 additions & 1 deletion .gitmodules
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
[submodule "thirdparty/zlib"]
path = libEmblem/thirdparty/zlib
url = https://github.com/madler/zlib.git
url = https://github.com/madler/zlib.git
[submodule "gui/thirdparty/DirectXTK"]
path = gui/thirdparty/DirectXTK
url = https://github.com/microsoft/DirectXTK.git
[submodule "gui/thirdparty/imgui"]
path = gui/thirdparty/imgui
url = https://github.com/ocornut/imgui.git
1 change: 1 addition & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,4 @@ SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /D_UNICODE /DUNICODE")

set(LIBEMBLEM_BUILD_STATIC_LIB ON CACHE BOOL "")
add_subdirectory(${PROJECT_SOURCE_DIR}/libEmblem)
add_subdirectory(${PROJECT_SOURCE_DIR}/gui)
34 changes: 34 additions & 0 deletions gui/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
cmake_minimum_required(VERSION 3.13)
project(EmblemCreator)

set(CMAKE_CXX_STANDARD 23)
set(CMAKE_CXX20_STANDARD_COMPILE_OPTION "-std:c++latest")
set(CMAKE_CXX20_EXTENSION_COMPILE_OPTION "-std:c++latest")
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /D_UNICODE /DUNICODE")

file(GLOB SRC_FILES ${CMAKE_CURRENT_SOURCE_DIR}/src/*.c
${CMAKE_CURRENT_SOURCE_DIR}/src/*.h
${CMAKE_CURRENT_SOURCE_DIR}/src/*.hpp
${CMAKE_CURRENT_SOURCE_DIR}/src/*.cpp
${CMAKE_CURRENT_SOURCE_DIR}/src/*.rc
${CMAKE_CURRENT_SOURCE_DIR}/thirdparty/imgui/*.cpp
${CMAKE_CURRENT_SOURCE_DIR}/thirdparty/imgui/backends/imgui_impl_dx11.cpp
${CMAKE_CURRENT_SOURCE_DIR}/thirdparty/imgui/backends/imgui_impl_win32.cpp
${CMAKE_CURRENT_SOURCE_DIR}/thirdparty/imgui/misc/imgui_stdlib.cpp
)

set(BUILD_TESTING OFF CACHE BOOL "")
set(BUILD_TOOLS OFF CACHE BOOL "")
set(BUILD_XAUDIO_WIN10 ON CACHE BOOL "")
set(BUILD_XAUDIO_WIN8 OFF CACHE BOOL "")
add_subdirectory(thirdparty/DirectXTK)

add_executable(EmblemCreator ${SRC_FILES})

target_link_options(EmblemCreator PRIVATE "/SUBSYSTEM:WINDOWS" "/ENTRY:mainCRTStartup")

set(LIBEMBLEM_BUILD_STATIC_LIB ON CACHE BOOL "")
target_link_libraries(EmblemCreator PUBLIC DirectXTK)
target_link_libraries(EmblemCreator PUBLIC libEmblem)

target_include_directories(EmblemCreator PRIVATE thirdparty/imgui)
70 changes: 70 additions & 0 deletions gui/src/BatchRenderer.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
#include "BatchRenderer.h"
#include "DirectXHelpers.h"
#include "PlatformHelpers.h"
#include "VertexTypes.h"
#include <d3d11.h>

using Microsoft::WRL::ComPtr;

std::unique_ptr<Geom::BatchRenderer> Geom::BatchRenderer::create(ID3D11Device* device, AAMode aaMode) {
auto renderer = std::unique_ptr<BatchRenderer>(new BatchRenderer());

// switch(aaMode) {
// case AAMode::Msaa4x: {
// CD3D11_RASTERIZER_DESC msaaRasterizerDesc(D3D11_FILL_SOLID, D3D11_CULL_NONE, FALSE, D3D11_DEFAULT_DEPTH_BIAS,
// D3D11_DEFAULT_DEPTH_BIAS_CLAMP,
// D3D11_DEFAULT_SLOPE_SCALED_DEPTH_BIAS, TRUE, FALSE, TRUE, FALSE);

// ThrowIfFailed(device->CreateRasterizerState(&msaaRasterizerDesc, renderer->rasterizer.ReleaseAndGetAddressOf()));
//} break;
// case AAMode::None:
// default:
// //throw std::logic_error("Not implemented");
//}

renderer->commonStates = std::make_unique<DirectX::CommonStates>(device);

ID3D11DeviceContext* context;
device->GetImmediateContext(&context);
renderer->batch = std::make_unique<DirectX::PrimitiveBatch<VertexType>>(context);
context->Release();

renderer->effect = std::make_unique<DirectX::BasicEffect>(device);
renderer->effect->SetVertexColorEnabled(true);

DirectX::CreateInputLayoutFromEffect<VertexType>(device, renderer->effect.get(), renderer->inputLayout.ReleaseAndGetAddressOf());

return renderer;
}

void Geom::BatchRenderer::begin(ID3D11DeviceContext* context) {
context->OMSetBlendState(commonStates->AlphaBlend(), nullptr, 0xFFFFFFFF);
context->OMSetBlendState(nullptr, nullptr, 0xFFFFFFFF);
context->OMSetDepthStencilState(commonStates->DepthNone(), 0);

auto sampler = commonStates->LinearClamp();
context->PSSetSamplers(0, 1, &sampler);

// context->RSSetState(rasterizer.Get());
context->RSSetState(commonStates->CullNone());
context->IASetInputLayout(inputLayout.Get());

effect->Apply(context);
batch->Begin();
}

void Geom::BatchRenderer::draw(D3D11_PRIMITIVE_TOPOLOGY topology, const VertexType* vertices, int32_t vertexCount) {
batch->Draw(topology, vertices, vertexCount);
}

void Geom::BatchRenderer::drawIndexed(D3D11_PRIMITIVE_TOPOLOGY topology,
const uint16_t* indices,
int32_t indexCount,
const VertexType* vertices,
int32_t vertexCount) {
batch->DrawIndexed(topology, indices, indexCount, vertices, vertexCount);
}

void Geom::BatchRenderer::end() {
batch->End();
}
41 changes: 41 additions & 0 deletions gui/src/BatchRenderer.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
#pragma once
#include "BatchRenderer.h"
#include "CommonStates.h"
#include "Effects.h"
#include "PrimitiveBatch.h"
#include "VertexTypes.h"
#include <d3d11.h>
#include <memory>
#include <wrl.h>

namespace Geom {

enum class AAMode {
None,
Msaa4x,
};

class BatchRenderer {
public:
using VertexType = DirectX::VertexPositionColor;

static std::unique_ptr<BatchRenderer> create(ID3D11Device* device, AAMode aaMode);

void begin(ID3D11DeviceContext* context);
void draw(D3D11_PRIMITIVE_TOPOLOGY topology, const VertexType* vertices, int32_t vertexCount);
void drawIndexed(D3D11_PRIMITIVE_TOPOLOGY topology, const uint16_t* indices, int32_t indexCount, const VertexType* vertices, int32_t vertexCount);
void end();

//DirectX::PrimitiveBatch<VertexType>* getPrimitiveBatch(); // TODO: remove

private:
BatchRenderer() = default;

Microsoft::WRL::ComPtr<ID3D11RasterizerState> rasterizer = nullptr;
Microsoft::WRL::ComPtr<ID3D11InputLayout> inputLayout = nullptr;

std::unique_ptr<DirectX::CommonStates> commonStates = nullptr;
std::unique_ptr<DirectX::PrimitiveBatch<VertexType>> batch = nullptr;
std::unique_ptr<DirectX::BasicEffect> effect = nullptr;
};
} // namespace Geom
22 changes: 22 additions & 0 deletions gui/src/ChromaKey.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
#include "ChromaKey.h"
#include "SimpleMath.h"
#include <bit>
#include <cstdlib>

using DirectX::SimpleMath::Vector3;
using DirectX::SimpleMath::Vector4;

bool ChromaKey::match(const Vector4& rgba_) {
Vector3 rgb{ rgba_ };
auto distance = Vector3::Distance(rgb, key);
if(distance <= distanceThreshold)
return true;

Vector3 absDiff{ XMVectorAbs(rgb - key) };
Vector3 result{};
Vector3::Max(absDiff, elementThresholds, result);
if(result != absDiff)
return true;

return false;
}
11 changes: 11 additions & 0 deletions gui/src/ChromaKey.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
#pragma once
#include "SimpleMath.h"

class ChromaKey {
public:
bool match(const DirectX::SimpleMath::Vector4& rgba);

DirectX::SimpleMath::Vector3 elementThresholds = { 0.f, 0.f, 0.f };
float distanceThreshold = 0.f;
DirectX::SimpleMath::Vector3 key = { 0.f, 1.f, 0.f };
};
16 changes: 16 additions & 0 deletions gui/src/Define.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
#pragma once

#define CONCAT_(x, y) x##y
#define CONCAT(x, y) CONCAT_(x, y)

#define ANONYMOUS CONCAT(_anonymous, __COUNTER__)

#define MAKE_NONCOPYABLE(cls) \
private: \
cls(const cls&) = delete; \
cls& operator=(const cls&) = delete

#define MAKE_NONMOVABLE(cls) \
private: \
cls(cls&&) = delete; \
cls& operator=(cls&&) = delete
8 changes: 8 additions & 0 deletions gui/src/PlatformHelpers.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
#include "PlatformHelpers.h"
#include <stdexcept>

void ThrowIfFailed(HRESULT hr) {
if(FAILED(hr)) {
throw std::runtime_error("bad hr");
}
}
4 changes: 4 additions & 0 deletions gui/src/PlatformHelpers.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
#pragma once
#include <Windows.h>

void ThrowIfFailed(HRESULT hr);
111 changes: 111 additions & 0 deletions gui/src/RenderPrim.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
#include "RenderPrim.h"
#include <cmath>
#include <vector>

namespace {

enum class GeometrizeShapeType {
Rectangle = 0,
RotatedRectangle = 1,
Triangle = 2,
Ellipse = 3,
RotatedEllipse = 4,
Circle = 5,
};

}

void rotatePoint(float& x, float& y, float theta) {
double tempX = x;
x = x * cos(theta) - y * sin(theta);
y = tempX * sin(theta) + y * cos(theta);
}

std::vector<ShapeDesc> fromGeomtrizeJson(const nlohmann::json& json) {
std::vector<ShapeDesc> shapes;

struct BoundingBox {
int minX = (std::numeric_limits<int>::max)();
int minY = (std::numeric_limits<int>::max)();
int maxX = (std::numeric_limits<int>::min)();
int maxY = (std::numeric_limits<int>::min)();
} bb;

bb.minX = json[0]["data"][0];
bb.minY = json[0]["data"][1];
bb.maxX = json[0]["data"][2];
bb.maxY = json[0]["data"][3];

float scaleX = bb.maxX - bb.minX;
float scaleY = bb.maxY - bb.minY;

for(int i = 0; i < json.size(); ++i) {
const auto& shapeJson = json[i];

auto type = shapeJson["type"].get<GeometrizeShapeType>();
switch(type) {
case GeometrizeShapeType::Rectangle: {
case GeometrizeShapeType::RotatedRectangle:
RectangleDesc desc;
auto scale = 1.5f;

auto minX = (scale * (shapeJson["data"][0].get<float>() / scaleX)) - scale * 0.5f;
auto minY = (scale * (shapeJson["data"][1].get<float>() / scaleY)) - scale * 0.5f;
auto maxX = (scale * (shapeJson["data"][2].get<float>() / scaleX)) - scale * 0.5f;
auto maxY = (scale * (shapeJson["data"][3].get<float>() / scaleY)) - scale * 0.5f;

desc.w = (maxX - minX);
desc.h = (maxY - minY);

desc.cx = minX + desc.w / 2;
desc.cy = minY + desc.h / 2;

if(type == GeometrizeShapeType::RotatedRectangle)
desc.angle = shapeJson["data"][4].get<float>();
else
desc.angle = 0.f;

desc.rgba.r = shapeJson["color"][0] / 255.f;
desc.rgba.g = shapeJson["color"][1] / 255.f;
desc.rgba.b = shapeJson["color"][2] / 255.f;
desc.rgba.a = shapeJson["color"][3] / 255.f; // TODO: q

shapes.push_back(desc);
} break;
case GeometrizeShapeType::Circle:
case GeometrizeShapeType::Ellipse:
case GeometrizeShapeType::RotatedEllipse: {
float scale = 1.5f;
EllipseDesc desc;

desc.rgba.r = shapeJson["color"][0] / 255.f;
desc.rgba.g = shapeJson["color"][1] / 255.f;
desc.rgba.b = shapeJson["color"][2] / 255.f;
desc.rgba.a = shapeJson["color"][3] / 255.f; // TODO: q

desc.cx = scale * (shapeJson["data"][0].get<float>() / scaleX) - scale * .5f;
desc.cy = scale * ((1.f - shapeJson["data"][1].get<float>() / scaleY)) - scale * .5f;
desc.ax = scale * (shapeJson["data"][2].get<float>() / scaleX);

switch(type) {
case GeometrizeShapeType::Circle:
desc.ay = desc.ax;
desc.angle = 0.f;
break;
case GeometrizeShapeType::Ellipse:
desc.ay = scale * (shapeJson["data"][3].get<float>() / scaleY);
desc.angle = 0.f;
break;
case GeometrizeShapeType::RotatedEllipse:
desc.ay = scale * (shapeJson["data"][3].get<float>() / scaleY);
desc.angle = -1.f * shapeJson["data"][4].get<float>();
break;
}
shapes.push_back(desc);
} break;
default:
throw std::runtime_error("Unreachable");
}
}
return shapes;
}
Loading

0 comments on commit d0eb099

Please sign in to comment.