Add everything.
Some checks failed
Build C++ Project with Fedora Container and Create Release / build (push) Has been cancelled
Some checks failed
Build C++ Project with Fedora Container and Create Release / build (push) Has been cancelled
This commit is contained in:
77
.github/workflows/thing.yaml
vendored
Normal file
77
.github/workflows/thing.yaml
vendored
Normal file
@@ -0,0 +1,77 @@
|
||||
name: Build C++ Project with Fedora Container and Create Release
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- main # Trigger on push to the main branch
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest # GitHub-hosted Ubuntu runner
|
||||
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v2
|
||||
|
||||
- name: Set up Docker
|
||||
run: |
|
||||
sudo apt-get update
|
||||
sudo apt-get remove -y containerd containerd.io
|
||||
sudo apt-get install docker.io # Install Docker if it's not available
|
||||
|
||||
- name: Build project in Fedora container
|
||||
run: |
|
||||
# Pull the Fedora image from Docker Hub
|
||||
docker pull fedora:latest
|
||||
|
||||
# Run the Fedora container and install dependencies
|
||||
docker run --rm -v ${{ github.workspace }}:/workspace -w /workspace fedora:latest bash -c "
|
||||
# Update the package list and install necessary dependencies
|
||||
dnf update -y && \
|
||||
dnf install -y \
|
||||
cmake \
|
||||
gcc \
|
||||
g++ \
|
||||
glfw-devel \
|
||||
make \
|
||||
git && \
|
||||
|
||||
# Run the build script (adjust if you have specific build steps)
|
||||
mkdir -p build
|
||||
cd build
|
||||
cmake .. && \
|
||||
make
|
||||
"
|
||||
|
||||
- name: Create GitHub Release and Upload Executable
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} # This token is automatically available for authenticated actions
|
||||
run: |
|
||||
# Set the release version (adjust this as per your versioning strategy)
|
||||
VERSION=$(git describe --tags --abbrev=0 || echo "v1.0.0")
|
||||
|
||||
# Create a new release
|
||||
RELEASE_RESPONSE=$(curl -X POST \
|
||||
-H "Authorization: token $GITHUB_TOKEN" \
|
||||
-H "Accept: application/vnd.github.v3+json" \
|
||||
https://api.github.com/repos/${{ github.repository }}/releases \
|
||||
-d '{
|
||||
"tag_name": "v'$VERSION'",
|
||||
"target_commitish": "main",
|
||||
"name": "Release v'$VERSION'",
|
||||
"body": "Automated release of the C++ project.",
|
||||
"draft": false,
|
||||
"prerelease": false
|
||||
}')
|
||||
|
||||
# Extract the upload URL from the release response
|
||||
UPLOAD_URL=$(echo $RELEASE_RESPONSE | jq -r .upload_url | sed -e "s/{?name,label}//")
|
||||
|
||||
# Upload the executable file
|
||||
curl -X POST \
|
||||
-H "Authorization: token $GITHUB_TOKEN" \
|
||||
-H "Content-Type: application/octet-stream" \
|
||||
--data-binary @./build/main \
|
||||
"$UPLOAD_URL?name=main-linux-x86_64"
|
||||
|
||||
echo "Release v$VERSION created and 'main' executable uploaded."
|
||||
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
||||
Build/
|
||||
10
.gitmodules
vendored
Normal file
10
.gitmodules
vendored
Normal file
@@ -0,0 +1,10 @@
|
||||
[submodule "src/ThirdParty/imgui"]
|
||||
path = src/ThirdParty/imgui
|
||||
url = https://github.com/ocornut/imgui.git
|
||||
branch = docking
|
||||
[submodule "src/ThirdParty/glfw"]
|
||||
path = src/ThirdParty/glfw
|
||||
url = https://github.com/TheCherno/glfw.git
|
||||
[submodule "src/ThirdParty/ImGuizmo"]
|
||||
path = src/ThirdParty/ImGuizmo
|
||||
url = https://github.com/CedricGuillemet/ImGuizmo.git
|
||||
33
.vscode/c_cpp_properties.json
vendored
Normal file
33
.vscode/c_cpp_properties.json
vendored
Normal file
@@ -0,0 +1,33 @@
|
||||
{
|
||||
"configurations": [
|
||||
{
|
||||
"name": "Linux",
|
||||
"includePath": [
|
||||
"${workspaceFolder}/**",
|
||||
"${workspaceFolder}/include"
|
||||
],
|
||||
"defines": [],
|
||||
"compilerPath": "/usr/bin/gcc",
|
||||
"cStandard": "c17",
|
||||
"cppStandard": "gnu++17",
|
||||
"intelliSenseMode": "linux-gcc-x64"
|
||||
},
|
||||
{
|
||||
"name": "Windows",
|
||||
"includePath": [
|
||||
"${workspaceFolder}/**"
|
||||
],
|
||||
"defines": [
|
||||
"_DEBUG",
|
||||
"UNICODE",
|
||||
"_UNICODE"
|
||||
],
|
||||
"windowsSdkVersion": "10.0.26100.0",
|
||||
"compilerPath": "C:/Program Files/Microsoft Visual Studio/18/Community/VC/Tools/MSVC/14.50.35717/bin/Hostx64/x64/cl.exe",
|
||||
"cStandard": "c17",
|
||||
"cppStandard": "c++17",
|
||||
"intelliSenseMode": "windows-msvc-x64"
|
||||
}
|
||||
],
|
||||
"version": 4
|
||||
}
|
||||
16
.vscode/settings.json
vendored
Normal file
16
.vscode/settings.json
vendored
Normal file
@@ -0,0 +1,16 @@
|
||||
{
|
||||
"files.associations": {
|
||||
"iostream": "cpp",
|
||||
"sstream": "cpp"
|
||||
},
|
||||
<<<<<<< HEAD
|
||||
<<<<<<< HEAD
|
||||
"makefile.configureOnOpen": true
|
||||
=======
|
||||
"cmake.sourceDirectory": "/home/thesona/Modularity/modularitylauncher"
|
||||
>>>>>>> 1ec3aa52144b306094f1119dfd3899de9664f7b8
|
||||
=======
|
||||
"cmake.sourceDirectory": "/home/theonesonakrie/Modularity",
|
||||
"C_Cpp.errorSquiggles": "disabled"
|
||||
>>>>>>> 834c6b5c445f3c715524cf257564f06da5555aa6
|
||||
}
|
||||
87
CMakeLists.txt
Normal file
87
CMakeLists.txt
Normal file
@@ -0,0 +1,87 @@
|
||||
cmake_minimum_required(VERSION 3.16)
|
||||
project(Modularity LANGUAGES C CXX)
|
||||
|
||||
set(CMAKE_CXX_STANDARD 17)
|
||||
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||
|
||||
# ==================== WINDOWS FIXES (only active on Windows) ====================
|
||||
if(WIN32)
|
||||
add_compile_definitions(
|
||||
NOMINMAX # Fixes std::min/std::max clash with Windows.h
|
||||
WIN32_LEAN_AND_MEAN # Speeds up Windows.h includes
|
||||
_CRT_SECURE_NO_WARNINGS # Silences strncpy, sscanf, etc. warnings
|
||||
)
|
||||
endif()
|
||||
|
||||
# ==================== Compiler flags ====================
|
||||
if(MSVC)
|
||||
add_compile_options(/W4 /O2 /permissive- /MP)
|
||||
else()
|
||||
add_compile_options(-Wall -Wextra -Wpedantic -O2)
|
||||
endif()
|
||||
|
||||
# ==================== Third-party libraries ====================
|
||||
|
||||
add_subdirectory(src/ThirdParty/glfw EXCLUDE_FROM_ALL)
|
||||
find_package(OpenGL REQUIRED)
|
||||
|
||||
# GLAD
|
||||
add_library(glad STATIC src/ThirdParty/glad/glad.c)
|
||||
target_include_directories(glad PUBLIC src/ThirdParty/glad)
|
||||
|
||||
# GLM (header-only)
|
||||
add_library(glm INTERFACE)
|
||||
target_include_directories(glm INTERFACE src/ThirdParty/glm)
|
||||
|
||||
# ImGuizmo ←←← THIS WAS THE BUG
|
||||
add_library(imguizmo STATIC
|
||||
src/ThirdParty/ImGuizmo/ImGuizmo.cpp
|
||||
)
|
||||
target_include_directories(imguizmo PUBLIC src/ThirdParty/ImGuizmo)
|
||||
target_link_libraries(imguizmo PUBLIC imgui glm) # ImGuizmo uses ImGui + GLM
|
||||
|
||||
# Dear ImGui
|
||||
set(IMGUI_DIR ${PROJECT_SOURCE_DIR}/src/ThirdParty/imgui)
|
||||
add_library(imgui STATIC
|
||||
${IMGUI_DIR}/imgui.cpp
|
||||
${IMGUI_DIR}/imgui_demo.cpp
|
||||
${IMGUI_DIR}/imgui_draw.cpp
|
||||
${IMGUI_DIR}/imgui_tables.cpp
|
||||
${IMGUI_DIR}/imgui_widgets.cpp
|
||||
${IMGUI_DIR}/backends/imgui_impl_glfw.cpp
|
||||
${IMGUI_DIR}/backends/imgui_impl_opengl3.cpp
|
||||
)
|
||||
target_include_directories(imgui PUBLIC ${IMGUI_DIR} ${IMGUI_DIR}/backends)
|
||||
target_link_libraries(imgui PRIVATE glfw)
|
||||
|
||||
# ==================== Your code ====================
|
||||
file(GLOB_RECURSE PROJECT_SOURCES
|
||||
src/*.cpp
|
||||
src/*.c
|
||||
)
|
||||
list(FILTER PROJECT_SOURCES EXCLUDE REGEX "src/ThirdParty/|src/main\\.cpp")
|
||||
|
||||
add_library(core STATIC ${PROJECT_SOURCES})
|
||||
target_include_directories(core PUBLIC include)
|
||||
target_link_libraries(core PUBLIC glad glm imgui imguizmo)
|
||||
|
||||
# ==================== Executable ====================
|
||||
add_executable(main src/main.cpp)
|
||||
target_link_libraries(main PRIVATE core glfw OpenGL::GL)
|
||||
|
||||
# Optional: remove console window on Windows (uncomment if you want GUI-only app)
|
||||
#if(WIN32)
|
||||
# set_target_properties(main PROPERTIES WIN32_EXECUTABLE TRUE)
|
||||
#endif()
|
||||
|
||||
# Linux needs these extra libs
|
||||
if(NOT WIN32)
|
||||
target_link_libraries(main PRIVATE dl pthread X11)
|
||||
endif()
|
||||
|
||||
# ==================== Copy Resources folder after build ====================
|
||||
add_custom_command(TARGET main POST_BUILD
|
||||
COMMAND ${CMAKE_COMMAND} -E copy_directory
|
||||
${CMAKE_SOURCE_DIR}/Resources
|
||||
$<TARGET_FILE_DIR:main>/Resources
|
||||
)
|
||||
29
LICENSE
Normal file
29
LICENSE
Normal file
@@ -0,0 +1,29 @@
|
||||
Copyright (c) 2025 Shock Interactive LLC
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this engine and associated documentation files (the "Engine"), to use, copy,
|
||||
modify, merge, publish, distribute, sublicense, and/or sell copies of software
|
||||
that *uses* the Engine (for example, a game or application) under the following conditions:
|
||||
|
||||
1. Use in Commercial Games:
|
||||
- You may use the Engine to develop commercial or closed-source games.
|
||||
- You may not sell or distribute the Engine itself or any substantial part of it as a standalone product.
|
||||
|
||||
2. Modifications to the Engine:
|
||||
- Any modifications to the Engine’s source code must be released under this same license.
|
||||
- Modifications must include a notice describing the changes made.
|
||||
|
||||
3. Distribution:
|
||||
- You may distribute games or software that uses the Engine under any terms you choose.
|
||||
- Distribution of the Engine or derivative Engine code must remain open source under this license.
|
||||
|
||||
4. Disclaimer:
|
||||
- The Engine is provided "as is", without warranty of any kind, express or implied, including but not limited to the warranties of merchantability, fitness for a particular purpose, and noninfringement.
|
||||
- In no event shall the authors or copyright holders be liable for any claim, damages, or other liability arising from the use of the Engine.
|
||||
|
||||
5. Attribution:
|
||||
- You must include a visible attribution to the original Engine in your software documentation or about section.
|
||||
|
||||
---
|
||||
|
||||
This license is designed to keep the Engine itself open source, allow closed-source commercial games, and prevent selling the Engine as a product.
|
||||
46
Resources/Shaders/frag.glsl
Normal file
46
Resources/Shaders/frag.glsl
Normal file
@@ -0,0 +1,46 @@
|
||||
#version 330 core
|
||||
out vec4 FragColor;
|
||||
|
||||
in vec3 FragPos;
|
||||
in vec3 Normal;
|
||||
in vec2 TexCoord;
|
||||
|
||||
uniform sampler2D texture1;
|
||||
uniform sampler2D texture2;
|
||||
uniform float mixAmount = 0.2;
|
||||
|
||||
uniform vec3 lightPos;
|
||||
uniform vec3 viewPos;
|
||||
uniform vec3 lightColor = vec3(1.0);
|
||||
|
||||
uniform float ambientStrength = 0.2;
|
||||
uniform float specularStrength = 0.5;
|
||||
uniform float shininess = 32.0;
|
||||
|
||||
void main()
|
||||
{
|
||||
vec3 norm = normalize(Normal);
|
||||
vec3 lightDir = normalize(lightPos - FragPos);
|
||||
vec3 viewDir = normalize(viewPos - FragPos);
|
||||
|
||||
// Ambient
|
||||
vec3 ambient = ambientStrength * lightColor;
|
||||
|
||||
// Diffuse
|
||||
float diff = max(dot(norm, lightDir), 0.0);
|
||||
vec3 diffuse = diff * lightColor;
|
||||
|
||||
// Specular (Blinn-Phong)
|
||||
vec3 halfwayDir = normalize(lightDir + viewDir);
|
||||
float spec = pow(max(dot(norm, halfwayDir), 0.0), shininess);
|
||||
vec3 specular = specularStrength * spec * lightColor;
|
||||
|
||||
// Texture mixing (corrected)
|
||||
vec4 tex1 = texture(texture1, TexCoord);
|
||||
vec4 tex2 = texture(texture2, TexCoord);
|
||||
vec4 mixedTex = mix(tex1, tex2, mixAmount);
|
||||
vec3 texColor = mixedTex.rgb;
|
||||
|
||||
vec3 result = (ambient + diffuse + specular) * texColor;
|
||||
FragColor = vec4(result, mixedTex.a); // Preserve alpha if needed
|
||||
}
|
||||
98
Resources/Shaders/skybox_frag.glsl
Normal file
98
Resources/Shaders/skybox_frag.glsl
Normal file
@@ -0,0 +1,98 @@
|
||||
#version 330 core
|
||||
out vec4 FragColor;
|
||||
in vec3 fragPos;
|
||||
|
||||
uniform float timeOfDay; // 0..1 (0.0 = midnight)
|
||||
|
||||
float hash(vec3 p) {
|
||||
p = fract(p * 0.3183099 + 0.1);
|
||||
p *= 17.0;
|
||||
return fract(p.x * p.y * p.z * (p.x + p.y + p.z));
|
||||
}
|
||||
|
||||
vec3 getSkyColor(vec3 dir, float tod) {
|
||||
float height = dir.y;
|
||||
|
||||
// Continuous rotation – no midnight jump
|
||||
float t = fract(tod);
|
||||
float angle = t * 6.28318530718;
|
||||
vec3 sunDir = normalize(vec3(cos(angle), sin(angle) * 0.5, sin(angle)));
|
||||
float sunDot = max(dot(dir, sunDir), 0.0);
|
||||
|
||||
// Your original colors (unchanged)
|
||||
vec3 nightTop = vec3(0.01, 0.01, 0.05);
|
||||
vec3 nightHorizon = vec3(0.05, 0.05, 0.15);
|
||||
vec3 dayTop = vec3(0.3, 0.5, 0.9);
|
||||
vec3 dayHorizon = vec3(0.6, 0.7, 0.9);
|
||||
vec3 sunriseTop = vec3(0.4, 0.3, 0.5);
|
||||
vec3 sunriseHorizon= vec3(1.0, 0.5, 0.3);
|
||||
vec3 sunsetTop = vec3(0.5, 0.3, 0.4);
|
||||
vec3 sunsetHorizon = vec3(1.0, 0.4, 0.2);
|
||||
|
||||
// Same 4-phase interpolation as you had
|
||||
vec3 skyTop, skyHorizon;
|
||||
if (t < 0.25) {
|
||||
float f = t * 4.0;
|
||||
skyTop = mix(nightTop, sunriseTop, f);
|
||||
skyHorizon = mix(nightHorizon, sunriseHorizon, f);
|
||||
} else if (t < 0.5) {
|
||||
float f = (t-0.25)*4.0;
|
||||
skyTop = mix(sunriseTop, dayTop, f);
|
||||
skyHorizon = mix(sunriseHorizon, dayHorizon, f);
|
||||
} else if (t < 0.75) {
|
||||
float f = (t-0.5)*4.0;
|
||||
skyTop = mix(dayTop, sunsetTop, f);
|
||||
skyHorizon = mix(dayHorizon, sunsetHorizon, f);
|
||||
} else {
|
||||
float f = (t-0.75)*4.0;
|
||||
skyTop = mix(sunsetTop, nightTop, f);
|
||||
skyHorizon = mix(sunsetHorizon, nightHorizon, f);
|
||||
}
|
||||
|
||||
vec3 skyColor = mix(skyHorizon, skyTop, smoothstep(-0.3, 0.3, height));
|
||||
|
||||
// Sun (exactly like yours)
|
||||
vec3 sunCol = vec3(1.0, 0.95, 0.8);
|
||||
float sunGlow = pow(sunDot, 128.0) * 2.0;
|
||||
float sunDisc = smoothstep(0.9995, 0.9998, sunDot);
|
||||
float atmGlow = pow(sunDot, 8.0) * 0.5;
|
||||
|
||||
float sunVisibility = smoothstep(-0.12, 0.15, sunDir.y); // smooth fade in/out
|
||||
skyColor += sunCol * (sunDisc + atmGlow + sunGlow*0.3) * sunVisibility;
|
||||
|
||||
// ——— STARS: now actually visible and pretty ———
|
||||
float night = 1.0 - sunVisibility;
|
||||
if (night > 0.0) {
|
||||
vec3 p = dir * 160.0; // denser grid
|
||||
vec3 i = floor(p);
|
||||
vec3 f = fract(p);
|
||||
|
||||
float stars = 0.0;
|
||||
for (int z=-1; z<=1; z++)
|
||||
for (int y=-1; y<=1; y++)
|
||||
for (int x=-1; x<=1; x++) {
|
||||
vec3 o = vec3(x,y,z);
|
||||
vec3 pos = i + o;
|
||||
float h = hash(pos);
|
||||
if (h > 0.99) { // only the brightest 1%
|
||||
vec3 center = o + 0.5 + (hash(pos+vec3(7,13,21))-0.5)*0.8;
|
||||
float d = length(f - center);
|
||||
float star = 1.0 - smoothstep(0.0, 0.12, d); // tiny sharp dot
|
||||
star *= (h - 0.99)*100.0; // brightness variation
|
||||
stars += star;
|
||||
}
|
||||
}
|
||||
stars = pow(stars, 1.4);
|
||||
stars *= night;
|
||||
stars *= smoothstep(-0.1, 0.25, height); // fade near horizon
|
||||
skyColor += vec3(1.0, 0.95, 0.9) * stars * 2.5;
|
||||
}
|
||||
|
||||
return skyColor;
|
||||
}
|
||||
|
||||
void main() {
|
||||
vec3 dir = normalize(fragPos);
|
||||
vec3 col = getSkyColor(dir, timeOfDay);
|
||||
FragColor = vec4(col, 1.0);
|
||||
}
|
||||
14
Resources/Shaders/skybox_vert.glsl
Normal file
14
Resources/Shaders/skybox_vert.glsl
Normal file
@@ -0,0 +1,14 @@
|
||||
#version 330 core
|
||||
layout (location = 0) in vec3 aPos;
|
||||
|
||||
out vec3 fragPos;
|
||||
|
||||
uniform mat4 projection;
|
||||
uniform mat4 view;
|
||||
|
||||
void main()
|
||||
{
|
||||
fragPos = aPos;
|
||||
vec4 pos = projection * view * vec4(aPos, 1.0);
|
||||
gl_Position = pos.xyww; // Trick to ensure skybox depth is always 1.0 (furthest)
|
||||
}
|
||||
20
Resources/Shaders/vert.glsl
Normal file
20
Resources/Shaders/vert.glsl
Normal file
@@ -0,0 +1,20 @@
|
||||
#version 330 core
|
||||
layout (location = 0) in vec3 aPos;
|
||||
layout (location = 1) in vec3 aNormal;
|
||||
layout (location = 2) in vec2 aTexCoord;
|
||||
|
||||
out vec3 FragPos;
|
||||
out vec3 Normal;
|
||||
out vec2 TexCoord;
|
||||
|
||||
uniform mat4 model;
|
||||
uniform mat4 view;
|
||||
uniform mat4 projection;
|
||||
|
||||
void main()
|
||||
{
|
||||
FragPos = vec3(model * vec4(aPos, 1.0));
|
||||
Normal = mat3(transpose(inverse(model))) * aNormal;
|
||||
TexCoord = aTexCoord;
|
||||
gl_Position = projection * view * vec4(FragPos, 1.0);
|
||||
}
|
||||
BIN
Resources/Textures/awesomeface.png
Normal file
BIN
Resources/Textures/awesomeface.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 58 KiB |
BIN
Resources/Textures/container.jpg
Normal file
BIN
Resources/Textures/container.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 181 KiB |
BIN
Resources/Textures/wall.jpg
Normal file
BIN
Resources/Textures/wall.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 251 KiB |
67
Resources/imgui.ini
Normal file
67
Resources/imgui.ini
Normal file
@@ -0,0 +1,67 @@
|
||||
[Window][Debug##Default]
|
||||
Pos=60,60
|
||||
Size=400,400
|
||||
Collapsed=0
|
||||
|
||||
[Window][Modularity - Project Launcher]
|
||||
Pos=569,288
|
||||
Size=720,480
|
||||
Collapsed=0
|
||||
|
||||
[Window][New Project]
|
||||
Pos=679,403
|
||||
Size=500,250
|
||||
Collapsed=0
|
||||
|
||||
[Window][DockSpace]
|
||||
Pos=0,21
|
||||
Size=1858,1036
|
||||
Collapsed=0
|
||||
|
||||
[Window][Viewport]
|
||||
Pos=307,42
|
||||
Size=1202,792
|
||||
Collapsed=0
|
||||
DockId=0x00000002,0
|
||||
|
||||
[Window][Hierarchy]
|
||||
Pos=0,42
|
||||
Size=305,792
|
||||
Collapsed=0
|
||||
DockId=0x00000001,0
|
||||
|
||||
[Window][Inspector]
|
||||
Pos=1511,42
|
||||
Size=347,1015
|
||||
Collapsed=0
|
||||
DockId=0x00000008,0
|
||||
|
||||
[Window][File Browser]
|
||||
Pos=787,836
|
||||
Size=722,221
|
||||
Collapsed=0
|
||||
DockId=0x00000006,0
|
||||
|
||||
[Window][Console]
|
||||
Pos=0,836
|
||||
Size=785,221
|
||||
Collapsed=0
|
||||
DockId=0x00000005,0
|
||||
|
||||
[Window][Project]
|
||||
Pos=787,836
|
||||
Size=722,221
|
||||
Collapsed=0
|
||||
DockId=0x00000006,1
|
||||
|
||||
[Docking][Data]
|
||||
DockSpace ID=0xCCBD8CF7 Window=0x3DA2F1DE Pos=0,42 Size=1858,1015 Split=X Selected=0xC450F867
|
||||
DockNode ID=0x00000007 Parent=0xCCBD8CF7 SizeRef=1509,1015 Split=Y
|
||||
DockNode ID=0x00000003 Parent=0x00000007 SizeRef=1858,792 Split=X
|
||||
DockNode ID=0x00000001 Parent=0x00000003 SizeRef=305,1015 Selected=0xBABDAE5E
|
||||
DockNode ID=0x00000002 Parent=0x00000003 SizeRef=1202,1015 CentralNode=1 Selected=0xC450F867
|
||||
DockNode ID=0x00000004 Parent=0x00000007 SizeRef=1858,221 Split=X Selected=0xEA83D666
|
||||
DockNode ID=0x00000005 Parent=0x00000004 SizeRef=785,221 Selected=0xEA83D666
|
||||
DockNode ID=0x00000006 Parent=0x00000004 SizeRef=722,221 Selected=0x9C21DE82
|
||||
DockNode ID=0x00000008 Parent=0xCCBD8CF7 SizeRef=347,1015 Selected=0x36DC96AB
|
||||
|
||||
48
build.bat
Normal file
48
build.bat
Normal file
@@ -0,0 +1,48 @@
|
||||
@echo off
|
||||
setlocal
|
||||
|
||||
echo.
|
||||
echo ================================
|
||||
echo Modularity - VS 2026 Build
|
||||
echo ================================
|
||||
echo.
|
||||
|
||||
git submodule update --init --recursive
|
||||
|
||||
:: Clean old build
|
||||
if exist build rmdir /s /q build
|
||||
|
||||
echo [INFO] Creating fresh build directory...
|
||||
mkdir build
|
||||
cd build
|
||||
|
||||
echo [INFO] Configuring with CMake (Visual Studio 18 2026)...
|
||||
cmake -G "Visual Studio 18 2026" -A x64 ..
|
||||
|
||||
if errorlevel 1 (
|
||||
echo.
|
||||
echo [ERROR] CMake configuration failed!
|
||||
pause
|
||||
exit /b 1
|
||||
)
|
||||
|
||||
echo [INFO] Building Release (using all CPU cores)...
|
||||
cmake --build . --config Release -- /m
|
||||
|
||||
if errorlevel 1 (
|
||||
echo.
|
||||
echo [ERROR] Build failed!
|
||||
pause
|
||||
exit /b 1
|
||||
)
|
||||
|
||||
echo [INFO] Copying Resources...
|
||||
xcopy /e /i /y "..\Resources" "Resources\" >nul
|
||||
|
||||
echo.
|
||||
echo =========================================
|
||||
echo SUCCESS! Your game is ready!
|
||||
echo At build\Release\main.exe
|
||||
echo =========================================
|
||||
echo.
|
||||
pause
|
||||
23
build.sh
Executable file
23
build.sh
Executable file
@@ -0,0 +1,23 @@
|
||||
#!/bin/bash
|
||||
|
||||
if [ -d "build" ]; then
|
||||
echo ================================
|
||||
echo Modularity - VS 2026 Build
|
||||
echo ================================
|
||||
git submodule update --init --recursive
|
||||
echo "found existing!! Removing..."
|
||||
rm -rf build/
|
||||
mkdir build
|
||||
cd build
|
||||
cmake ..
|
||||
cmake --build . -- -j$(nproc)
|
||||
cp -r ../Resources .
|
||||
echo "Build Done!"
|
||||
else
|
||||
mkdir build
|
||||
cd build
|
||||
cmake ..
|
||||
cmake --build . -- -j$(nproc)
|
||||
cp -r ../Resources .
|
||||
echo "Build Done!"
|
||||
fi
|
||||
7
buildandrun.sh
Executable file
7
buildandrun.sh
Executable file
@@ -0,0 +1,7 @@
|
||||
#!/bin/bash
|
||||
set -e # Exit on any error
|
||||
|
||||
./build.sh || { echo "Build failed"; exit 1; }
|
||||
cd build || { echo "Cannot cd to build/"; exit 1; }
|
||||
./main || { echo "main failed"; exit 1; }
|
||||
cd .. || echo "Warning: failed to return to parent dir"
|
||||
4
include/General/GlobalHeaders.h
Normal file
4
include/General/GlobalHeaders.h
Normal file
@@ -0,0 +1,4 @@
|
||||
#pragma once
|
||||
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
28
include/Shaders/Shader.h
Normal file
28
include/Shaders/Shader.h
Normal file
@@ -0,0 +1,28 @@
|
||||
#ifndef SHADER_H
|
||||
#define SHADER_H
|
||||
|
||||
#include <string>
|
||||
#include "../../ThirdParty/glm/glm.hpp"
|
||||
|
||||
class Shader
|
||||
{
|
||||
public:
|
||||
unsigned int ID;
|
||||
|
||||
Shader(const char* vertexPath, const char* fragmentPath);
|
||||
|
||||
void use();
|
||||
|
||||
void setBool(const std::string &name, bool value) const;
|
||||
void setInt(const std::string &name, int value) const;
|
||||
void setFloat(const std::string &name, float value) const;
|
||||
void setVec3(const std::string &name, const glm::vec3 &value) const;
|
||||
void setMat4(const std::string &name, const glm::mat4 &mat) const;
|
||||
|
||||
private:
|
||||
std::string readShaderFile(const char* filePath);
|
||||
void compileShaders(const char* vertexSource, const char* fragmentSource);
|
||||
void checkCompileErrors(unsigned int shader, std::string type);
|
||||
};
|
||||
|
||||
#endif
|
||||
23
include/Skybox/Skybox.h
Normal file
23
include/Skybox/Skybox.h
Normal file
@@ -0,0 +1,23 @@
|
||||
#ifndef SKYBOX_H
|
||||
#define SKYBOX_H
|
||||
|
||||
class Shader;
|
||||
|
||||
class Skybox {
|
||||
private:
|
||||
unsigned int VAO, VBO;
|
||||
Shader* skyboxShader;
|
||||
float timeOfDay = 0.5f; // 0.0 = night, 0.25 = sunrise, 0.5 = day, 0.75 = sunset, 1.0 = midnight
|
||||
|
||||
void setupMesh();
|
||||
|
||||
public:
|
||||
Skybox();
|
||||
~Skybox();
|
||||
|
||||
void draw(const float* view, const float* projection);
|
||||
void setTimeOfDay(float time); // 0.0 to 1.0
|
||||
float getTimeOfDay() const { return timeOfDay; }
|
||||
};
|
||||
|
||||
#endif
|
||||
34
include/Textures/Texture.h
Normal file
34
include/Textures/Texture.h
Normal file
@@ -0,0 +1,34 @@
|
||||
#ifndef TEXTURE_H
|
||||
#define TEXTURE_H
|
||||
|
||||
#include <string>
|
||||
#include <glad/glad.h>
|
||||
|
||||
class Texture
|
||||
{
|
||||
public:
|
||||
// load from file; format and wrap/filter are optional
|
||||
Texture(const std::string& path,
|
||||
GLenum wrapS = GL_REPEAT,
|
||||
GLenum wrapT = GL_REPEAT,
|
||||
GLenum minFilter = GL_LINEAR_MIPMAP_LINEAR,
|
||||
GLenum magFilter = GL_LINEAR);
|
||||
~Texture();
|
||||
|
||||
void Bind(GLenum unit = GL_TEXTURE0) const;
|
||||
void Unbind() const;
|
||||
|
||||
GLuint GetID() const { return m_ID; }
|
||||
int GetWidth() const { return m_Width; }
|
||||
int GetHeight() const { return m_Height; }
|
||||
|
||||
private:
|
||||
GLuint m_ID = 0;
|
||||
int m_Width = 0;
|
||||
int m_Height = 0;
|
||||
int m_Channels = 0;
|
||||
GLenum m_InternalFormat = GL_RGBA;
|
||||
GLenum m_DataFormat = GL_RGBA;
|
||||
};
|
||||
|
||||
#endif
|
||||
7988
include/ThirdParty/stb_image.h
vendored
Normal file
7988
include/ThirdParty/stb_image.h
vendored
Normal file
File diff suppressed because it is too large
Load Diff
3517
include/ThirdParty/tiny_obj_loader.h
vendored
Normal file
3517
include/ThirdParty/tiny_obj_loader.h
vendored
Normal file
File diff suppressed because it is too large
Load Diff
12
include/Window/Window.h
Normal file
12
include/Window/Window.h
Normal file
@@ -0,0 +1,12 @@
|
||||
#ifndef WINDOW_H
|
||||
#define WINDOW_H
|
||||
#include "../General/GlobalHeaders.h"
|
||||
#include <glad/glad.h>
|
||||
#include "../../src/ThirdParty/glfw/include/GLFW/glfw3.h"
|
||||
|
||||
class Window {
|
||||
public:
|
||||
GLFWwindow* makeWindow();
|
||||
};
|
||||
|
||||
#endif
|
||||
113
src/Shaders/Shader_Manager/Shader.cpp
Normal file
113
src/Shaders/Shader_Manager/Shader.cpp
Normal file
@@ -0,0 +1,113 @@
|
||||
#include "../../../include/Shaders/Shader.h"
|
||||
#include <glad/glad.h>
|
||||
#include "../../ThirdParty/glm/glm.hpp"
|
||||
#include "../../ThirdParty/glm/gtc/matrix_transform.hpp"
|
||||
#include "../../ThirdParty/glm/gtc/type_ptr.hpp"
|
||||
#include <fstream>
|
||||
#include <sstream>
|
||||
#include <iostream>
|
||||
|
||||
Shader::Shader(const char* vertexPath, const char* fragmentPath)
|
||||
{
|
||||
std::string vertexCode = readShaderFile(vertexPath);
|
||||
std::string fragmentCode = readShaderFile(fragmentPath);
|
||||
|
||||
compileShaders(vertexCode.c_str(), fragmentCode.c_str());
|
||||
}
|
||||
|
||||
std::string Shader::readShaderFile(const char* filePath)
|
||||
{
|
||||
std::ifstream shaderFile;
|
||||
shaderFile.exceptions(std::ifstream::failbit | std::ifstream::badbit);
|
||||
|
||||
try
|
||||
{
|
||||
shaderFile.open(filePath);
|
||||
std::stringstream shaderStream;
|
||||
shaderStream << shaderFile.rdbuf();
|
||||
shaderFile.close();
|
||||
return shaderStream.str();
|
||||
}
|
||||
catch (std::ifstream::failure& e)
|
||||
{
|
||||
std::cerr << "ERROR: Shader file not found: " << filePath << std::endl;
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
void Shader::compileShaders(const char* vertexSource, const char* fragmentSource)
|
||||
{
|
||||
unsigned int vertex = glCreateShader(GL_VERTEX_SHADER);
|
||||
glShaderSource(vertex, 1, &vertexSource, NULL);
|
||||
glCompileShader(vertex);
|
||||
checkCompileErrors(vertex, "VERTEX");
|
||||
|
||||
unsigned int fragment = glCreateShader(GL_FRAGMENT_SHADER);
|
||||
glShaderSource(fragment, 1, &fragmentSource, NULL);
|
||||
glCompileShader(fragment);
|
||||
checkCompileErrors(fragment, "FRAGMENT");
|
||||
|
||||
ID = glCreateProgram();
|
||||
glAttachShader(ID, vertex);
|
||||
glAttachShader(ID, fragment);
|
||||
glLinkProgram(ID);
|
||||
checkCompileErrors(ID, "PROGRAM");
|
||||
|
||||
glDeleteShader(vertex);
|
||||
glDeleteShader(fragment);
|
||||
}
|
||||
|
||||
void Shader::use()
|
||||
{
|
||||
glUseProgram(ID);
|
||||
}
|
||||
|
||||
void Shader::checkCompileErrors(unsigned int shader, std::string type)
|
||||
{
|
||||
int success;
|
||||
char infoLog[1024];
|
||||
|
||||
if (type != "PROGRAM")
|
||||
{
|
||||
glGetShaderiv(shader, GL_COMPILE_STATUS, &success);
|
||||
if (!success)
|
||||
{
|
||||
glGetShaderInfoLog(shader, 1024, NULL, infoLog);
|
||||
std::cerr << "ERROR::SHADER_COMPILATION_ERROR of type: " << type << "\n" << infoLog << std::endl;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
glGetProgramiv(shader, GL_LINK_STATUS, &success);
|
||||
if (!success)
|
||||
{
|
||||
glGetProgramInfoLog(shader, 1024, NULL, infoLog);
|
||||
std::cerr << "ERROR::PROGRAM_LINKING_ERROR of type: " << type << "\n" << infoLog << std::endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Shader::setBool(const std::string &name, bool value) const
|
||||
{
|
||||
glUniform1i(glGetUniformLocation(ID, name.c_str()), (int)value);
|
||||
}
|
||||
|
||||
void Shader::setInt(const std::string &name, int value) const
|
||||
{
|
||||
glUniform1i(glGetUniformLocation(ID, name.c_str()), value);
|
||||
}
|
||||
|
||||
void Shader::setFloat(const std::string &name, float value) const
|
||||
{
|
||||
glUniform1f(glGetUniformLocation(ID, name.c_str()), value);
|
||||
}
|
||||
|
||||
void Shader::setVec3(const std::string &name, const glm::vec3 &value) const
|
||||
{
|
||||
glUniform3fv(glGetUniformLocation(ID, name.c_str()), 1, &value[0]);
|
||||
}
|
||||
|
||||
void Shader::setMat4(const std::string &name, const glm::mat4 &mat) const
|
||||
{
|
||||
glUniformMatrix4fv(glGetUniformLocation(ID, name.c_str()), 1, GL_FALSE, glm::value_ptr(mat));
|
||||
}
|
||||
101
src/Skybox/Skybox.cpp
Normal file
101
src/Skybox/Skybox.cpp
Normal file
@@ -0,0 +1,101 @@
|
||||
#include "../../include/Skybox/Skybox.h"
|
||||
#include "../../include/Shaders/Shader.h"
|
||||
#include <glad/glad.h>
|
||||
#include <iostream>
|
||||
#include "../../src/ThirdParty/glm/glm.hpp"
|
||||
#include "../../src/ThirdParty/glm/gtc/type_ptr.hpp"
|
||||
|
||||
// Skybox cube vertices (positions only, no normals/UVs needed)
|
||||
float skyboxVertices[] = {
|
||||
// positions
|
||||
-1.0f, 1.0f, -1.0f,
|
||||
-1.0f, -1.0f, -1.0f,
|
||||
1.0f, -1.0f, -1.0f,
|
||||
1.0f, -1.0f, -1.0f,
|
||||
1.0f, 1.0f, -1.0f,
|
||||
-1.0f, 1.0f, -1.0f,
|
||||
|
||||
-1.0f, -1.0f, 1.0f,
|
||||
-1.0f, -1.0f, -1.0f,
|
||||
-1.0f, 1.0f, -1.0f,
|
||||
-1.0f, 1.0f, -1.0f,
|
||||
-1.0f, 1.0f, 1.0f,
|
||||
-1.0f, -1.0f, 1.0f,
|
||||
|
||||
1.0f, -1.0f, -1.0f,
|
||||
1.0f, -1.0f, 1.0f,
|
||||
1.0f, 1.0f, 1.0f,
|
||||
1.0f, 1.0f, 1.0f,
|
||||
1.0f, 1.0f, -1.0f,
|
||||
1.0f, -1.0f, -1.0f,
|
||||
|
||||
-1.0f, -1.0f, 1.0f,
|
||||
-1.0f, 1.0f, 1.0f,
|
||||
1.0f, 1.0f, 1.0f,
|
||||
1.0f, 1.0f, 1.0f,
|
||||
1.0f, -1.0f, 1.0f,
|
||||
-1.0f, -1.0f, 1.0f,
|
||||
|
||||
-1.0f, 1.0f, -1.0f,
|
||||
1.0f, 1.0f, -1.0f,
|
||||
1.0f, 1.0f, 1.0f,
|
||||
1.0f, 1.0f, 1.0f,
|
||||
-1.0f, 1.0f, 1.0f,
|
||||
-1.0f, 1.0f, -1.0f,
|
||||
|
||||
-1.0f, -1.0f, -1.0f,
|
||||
-1.0f, -1.0f, 1.0f,
|
||||
1.0f, -1.0f, -1.0f,
|
||||
1.0f, -1.0f, -1.0f,
|
||||
-1.0f, -1.0f, 1.0f,
|
||||
1.0f, -1.0f, 1.0f
|
||||
};
|
||||
|
||||
Skybox::Skybox() {
|
||||
skyboxShader = new Shader("Resources/Shaders/skybox_vert.glsl", "Resources/Shaders/skybox_frag.glsl");
|
||||
setupMesh();
|
||||
}
|
||||
|
||||
Skybox::~Skybox() {
|
||||
delete skyboxShader;
|
||||
glDeleteVertexArrays(1, &VAO);
|
||||
glDeleteBuffers(1, &VBO);
|
||||
}
|
||||
|
||||
void Skybox::setupMesh() {
|
||||
glGenVertexArrays(1, &VAO);
|
||||
glGenBuffers(1, &VBO);
|
||||
|
||||
glBindVertexArray(VAO);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, VBO);
|
||||
glBufferData(GL_ARRAY_BUFFER, sizeof(skyboxVertices), &skyboxVertices, GL_STATIC_DRAW);
|
||||
|
||||
glEnableVertexAttribArray(0);
|
||||
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0);
|
||||
|
||||
glBindVertexArray(0);
|
||||
}
|
||||
|
||||
void Skybox::setTimeOfDay(float time) {
|
||||
timeOfDay = time;
|
||||
}
|
||||
|
||||
void Skybox::draw(const float* view, const float* projection) {
|
||||
// Properly reconstruct the view matrix from the float array
|
||||
glm::mat4 viewMat = glm::make_mat4(view);
|
||||
glm::mat4 projMat = glm::make_mat4(projection);
|
||||
|
||||
// Remove translation from view matrix (keep only rotation)
|
||||
viewMat = glm::mat4(glm::mat3(viewMat));
|
||||
|
||||
glDepthFunc(GL_LEQUAL);
|
||||
skyboxShader->use();
|
||||
skyboxShader->setMat4("view", viewMat);
|
||||
skyboxShader->setMat4("projection", projMat);
|
||||
skyboxShader->setFloat("timeOfDay", timeOfDay);
|
||||
|
||||
glBindVertexArray(VAO);
|
||||
glDrawArrays(GL_TRIANGLES, 0, 36);
|
||||
glBindVertexArray(0);
|
||||
glDepthFunc(GL_LESS);
|
||||
}
|
||||
72
src/Textures/Texture.cpp
Normal file
72
src/Textures/Texture.cpp
Normal file
@@ -0,0 +1,72 @@
|
||||
#include "../../include/Textures/Texture.h"
|
||||
|
||||
#define STB_IMAGE_IMPLEMENTATION
|
||||
#include "../../include/ThirdParty/stb_image.h"
|
||||
|
||||
#include <iostream>
|
||||
|
||||
Texture::Texture(const std::string& path,
|
||||
GLenum wrapS,
|
||||
GLenum wrapT,
|
||||
GLenum minFilter,
|
||||
GLenum magFilter)
|
||||
{
|
||||
stbi_set_flip_vertically_on_load(1);
|
||||
unsigned char* data = stbi_load(path.c_str(), &m_Width, &m_Height, &m_Channels, 0);
|
||||
if (!data) {
|
||||
std::cerr << "Failed to load texture: " << path << "\n";
|
||||
return;
|
||||
}
|
||||
|
||||
// choose formats based on channels
|
||||
if (m_Channels == 1) {
|
||||
m_InternalFormat = m_DataFormat = GL_RED;
|
||||
} else if (m_Channels == 3) {
|
||||
m_InternalFormat = GL_RGB8;
|
||||
m_DataFormat = GL_RGB;
|
||||
} else if (m_Channels == 4) {
|
||||
m_InternalFormat = GL_RGBA8;
|
||||
m_DataFormat = GL_RGBA;
|
||||
} else {
|
||||
// fallback
|
||||
m_InternalFormat = GL_RGBA8;
|
||||
m_DataFormat = GL_RGBA;
|
||||
}
|
||||
|
||||
glGenTextures(1, &m_ID);
|
||||
glBindTexture(GL_TEXTURE_2D, m_ID);
|
||||
|
||||
// upload
|
||||
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, m_InternalFormat, m_Width, m_Height, 0, m_DataFormat, GL_UNSIGNED_BYTE, data);
|
||||
glGenerateMipmap(GL_TEXTURE_2D);
|
||||
|
||||
// params
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, wrapS);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, wrapT);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, minFilter);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, magFilter);
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
|
||||
stbi_image_free(data);
|
||||
}
|
||||
|
||||
Texture::~Texture()
|
||||
{
|
||||
if (m_ID) {
|
||||
glDeleteTextures(1, &m_ID);
|
||||
m_ID = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void Texture::Bind(GLenum unit) const
|
||||
{
|
||||
glActiveTexture(unit);
|
||||
glBindTexture(GL_TEXTURE_2D, m_ID);
|
||||
}
|
||||
|
||||
void Texture::Unbind() const
|
||||
{
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
}
|
||||
1111
src/ThirdParty/ImGuizmo/GraphEditor.cpp
vendored
Normal file
1111
src/ThirdParty/ImGuizmo/GraphEditor.cpp
vendored
Normal file
File diff suppressed because it is too large
Load Diff
151
src/ThirdParty/ImGuizmo/GraphEditor.h
vendored
Normal file
151
src/ThirdParty/ImGuizmo/GraphEditor.h
vendored
Normal file
@@ -0,0 +1,151 @@
|
||||
// https://github.com/CedricGuillemet/ImGuizmo
|
||||
// v1.92.5 WIP
|
||||
//
|
||||
// The MIT License(MIT)
|
||||
//
|
||||
// Copyright(c) 2016-2021 Cedric Guillemet
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files(the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and / or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions :
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in all
|
||||
// copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
// SOFTWARE.
|
||||
//
|
||||
#pragma once
|
||||
|
||||
#include <vector>
|
||||
#include <stdint.h>
|
||||
#include <string>
|
||||
#include "imgui.h"
|
||||
#include "imgui_internal.h"
|
||||
|
||||
namespace GraphEditor {
|
||||
|
||||
typedef size_t NodeIndex;
|
||||
typedef size_t SlotIndex;
|
||||
typedef size_t LinkIndex;
|
||||
typedef size_t TemplateIndex;
|
||||
|
||||
// Force the view to be respositionned and zoom to fit nodes with Show function.
|
||||
// Parameter value will be changed to Fit_None by the function.
|
||||
enum FitOnScreen
|
||||
{
|
||||
Fit_None,
|
||||
Fit_AllNodes,
|
||||
Fit_SelectedNodes
|
||||
};
|
||||
|
||||
// Display options and colors
|
||||
struct Options
|
||||
{
|
||||
ImRect mMinimap{{0.75f, 0.8f, 0.99f, 0.99f}}; // rectangle coordinates of minimap
|
||||
ImU32 mBackgroundColor{ IM_COL32(40, 40, 40, 255) }; // full background color
|
||||
ImU32 mGridColor{ IM_COL32(0, 0, 0, 60) }; // grid lines color
|
||||
ImU32 mGridColor2{ IM_COL32(0, 0, 0, 160) }; // grid lines color every 10th
|
||||
ImU32 mSelectedNodeBorderColor{ IM_COL32(255, 130, 30, 255) }; // node border color when it's selected
|
||||
ImU32 mNodeBorderColor{ IM_COL32(100, 100, 100, 0) }; // node border color when it's not selected
|
||||
ImU32 mQuadSelection{ IM_COL32(255, 32, 32, 64) }; // quad selection inside color
|
||||
ImU32 mQuadSelectionBorder{ IM_COL32(255, 32, 32, 255) }; // quad selection border color
|
||||
ImU32 mDefaultSlotColor{ IM_COL32(128, 128, 128, 255) }; // when no color is provided in node template, use this value
|
||||
ImU32 mFrameFocus{ IM_COL32(64, 128, 255, 255) }; // rectangle border when graph editor has focus
|
||||
float mLineThickness{ 5 }; // links width in pixels when zoom value is 1
|
||||
float mGridSize{ 64.f }; // background grid size in pixels when zoom value is 1
|
||||
float mRounding{ 3.f }; // rounding at node corners
|
||||
float mZoomRatio{ 0.1f }; // factor per mouse wheel delta
|
||||
float mZoomLerpFactor{ 0.25f }; // the smaller, the smoother
|
||||
float mBorderSelectionThickness{ 6.f }; // thickness of selection border around nodes
|
||||
float mBorderThickness{ 6.f }; // thickness of selection border around nodes
|
||||
float mNodeSlotRadius{ 8.f }; // circle radius for inputs and outputs
|
||||
float mNodeSlotHoverFactor{ 1.2f }; // increase size when hovering
|
||||
float mMinZoom{ 0.2f }, mMaxZoom { 1.1f };
|
||||
float mSnap{ 5.f };
|
||||
bool mDisplayLinksAsCurves{ true }; // false is straight and 45deg lines
|
||||
bool mAllowQuadSelection{ true }; // multiple selection using drag and drop
|
||||
bool mRenderGrid{ true }; // grid or nothing
|
||||
bool mDrawIONameOnHover{ true }; // only draw node input/output when hovering
|
||||
};
|
||||
|
||||
// View state: scroll position and zoom factor
|
||||
struct ViewState
|
||||
{
|
||||
ImVec2 mPosition{0.0f, 0.0f}; // scroll position
|
||||
float mFactor{ 1.0f }; // current zoom factor
|
||||
float mFactorTarget{ 1.0f }; // targeted zoom factor interpolated using Options.mZoomLerpFactor
|
||||
};
|
||||
|
||||
struct Template
|
||||
{
|
||||
ImU32 mHeaderColor;
|
||||
ImU32 mBackgroundColor;
|
||||
ImU32 mBackgroundColorOver;
|
||||
ImU8 mInputCount;
|
||||
const char** mInputNames; // can be nullptr. No text displayed.
|
||||
ImU32* mInputColors; // can be nullptr, default slot color will be used.
|
||||
ImU8 mOutputCount;
|
||||
const char** mOutputNames; // can be nullptr. No text displayed.
|
||||
ImU32* mOutputColors; // can be nullptr, default slot color will be used.
|
||||
};
|
||||
|
||||
struct Node
|
||||
{
|
||||
const char* mName;
|
||||
TemplateIndex mTemplateIndex;
|
||||
ImRect mRect;
|
||||
bool mSelected{ false };
|
||||
};
|
||||
|
||||
struct Link
|
||||
{
|
||||
NodeIndex mInputNodeIndex;
|
||||
SlotIndex mInputSlotIndex;
|
||||
NodeIndex mOutputNodeIndex;
|
||||
SlotIndex mOutputSlotIndex;
|
||||
};
|
||||
|
||||
struct Delegate
|
||||
{
|
||||
virtual bool AllowedLink(NodeIndex from, NodeIndex to) = 0;
|
||||
|
||||
virtual void SelectNode(NodeIndex nodeIndex, bool selected) = 0;
|
||||
virtual void MoveSelectedNodes(const ImVec2 delta) = 0;
|
||||
|
||||
virtual void AddLink(NodeIndex inputNodeIndex, SlotIndex inputSlotIndex, NodeIndex outputNodeIndex, SlotIndex outputSlotIndex) = 0;
|
||||
virtual void DelLink(LinkIndex linkIndex) = 0;
|
||||
|
||||
// user is responsible for clipping
|
||||
virtual void CustomDraw(ImDrawList* drawList, ImRect rectangle, NodeIndex nodeIndex) = 0;
|
||||
|
||||
// use mouse position to open context menu
|
||||
// if nodeIndex != -1, right click happens on the specified node
|
||||
virtual void RightClick(NodeIndex nodeIndex, SlotIndex slotIndexInput, SlotIndex slotIndexOutput) = 0;
|
||||
|
||||
virtual const size_t GetTemplateCount() = 0;
|
||||
virtual const Template GetTemplate(TemplateIndex index) = 0;
|
||||
|
||||
virtual const size_t GetNodeCount() = 0;
|
||||
virtual const Node GetNode(NodeIndex index) = 0;
|
||||
|
||||
virtual const size_t GetLinkCount() = 0;
|
||||
virtual const Link GetLink(LinkIndex index) = 0;
|
||||
|
||||
virtual ~Delegate() = default;
|
||||
};
|
||||
|
||||
void Show(Delegate& delegate, const Options& options, ViewState& viewState, bool enabled, FitOnScreen* fit = nullptr);
|
||||
void GraphEditorClear();
|
||||
|
||||
bool EditOptions(Options& options);
|
||||
|
||||
} // namespace
|
||||
458
src/ThirdParty/ImGuizmo/ImCurveEdit.cpp
vendored
Normal file
458
src/ThirdParty/ImGuizmo/ImCurveEdit.cpp
vendored
Normal file
@@ -0,0 +1,458 @@
|
||||
// https://github.com/CedricGuillemet/ImGuizmo
|
||||
// v1.92.5 WIP
|
||||
//
|
||||
// The MIT License(MIT)
|
||||
//
|
||||
// Copyright(c) 2016-2021 Cedric Guillemet
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files(the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and / or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions :
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in all
|
||||
// copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
// SOFTWARE.
|
||||
//
|
||||
#include "ImCurveEdit.h"
|
||||
#include "imgui.h"
|
||||
#include "imgui_internal.h"
|
||||
#include <stdint.h>
|
||||
#include <set>
|
||||
#include <vector>
|
||||
|
||||
#if defined(_MSC_VER) || defined(__MINGW32__)
|
||||
#include <malloc.h>
|
||||
#endif
|
||||
#if !defined(_MSC_VER) && !defined(__MINGW64_VERSION_MAJOR)
|
||||
#define _malloca(x) alloca(x)
|
||||
#define _freea(x)
|
||||
#endif
|
||||
|
||||
namespace ImCurveEdit
|
||||
{
|
||||
|
||||
#ifndef IMGUI_DEFINE_MATH_OPERATORS
|
||||
static ImVec2 operator+(const ImVec2& a, const ImVec2& b) {
|
||||
return ImVec2(a.x + b.x, a.y + b.y);
|
||||
}
|
||||
|
||||
static ImVec2 operator-(const ImVec2& a, const ImVec2& b) {
|
||||
return ImVec2(a.x - b.x, a.y - b.y);
|
||||
}
|
||||
|
||||
static ImVec2 operator*(const ImVec2& a, const ImVec2& b) {
|
||||
return ImVec2(a.x * b.x, a.y * b.y);
|
||||
}
|
||||
|
||||
static ImVec2 operator/(const ImVec2& a, const ImVec2& b) {
|
||||
return ImVec2(a.x / b.x, a.y / b.y);
|
||||
}
|
||||
|
||||
static ImVec2 operator*(const ImVec2& a, const float b) {
|
||||
return ImVec2(a.x * b, a.y * b);
|
||||
}
|
||||
#endif
|
||||
|
||||
static float smoothstep(float edge0, float edge1, float x)
|
||||
{
|
||||
x = ImClamp((x - edge0) / (edge1 - edge0), 0.0f, 1.0f);
|
||||
return x * x * (3 - 2 * x);
|
||||
}
|
||||
|
||||
static float distance(float x, float y, float x1, float y1, float x2, float y2)
|
||||
{
|
||||
float A = x - x1;
|
||||
float B = y - y1;
|
||||
float C = x2 - x1;
|
||||
float D = y2 - y1;
|
||||
|
||||
float dot = A * C + B * D;
|
||||
float len_sq = C * C + D * D;
|
||||
float param = -1.f;
|
||||
if (len_sq > FLT_EPSILON)
|
||||
param = dot / len_sq;
|
||||
|
||||
float xx, yy;
|
||||
|
||||
if (param < 0.f) {
|
||||
xx = x1;
|
||||
yy = y1;
|
||||
}
|
||||
else if (param > 1.f) {
|
||||
xx = x2;
|
||||
yy = y2;
|
||||
}
|
||||
else {
|
||||
xx = x1 + param * C;
|
||||
yy = y1 + param * D;
|
||||
}
|
||||
|
||||
float dx = x - xx;
|
||||
float dy = y - yy;
|
||||
return sqrtf(dx * dx + dy * dy);
|
||||
}
|
||||
|
||||
static int DrawPoint(ImDrawList* draw_list, ImVec2 pos, const ImVec2 size, const ImVec2 offset, bool edited)
|
||||
{
|
||||
int ret = 0;
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
|
||||
static const ImVec2 localOffsets[4] = { ImVec2(1,0), ImVec2(0,1), ImVec2(-1,0), ImVec2(0,-1) };
|
||||
ImVec2 offsets[4];
|
||||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
offsets[i] = pos * size + localOffsets[i] * 4.5f + offset;
|
||||
}
|
||||
|
||||
const ImVec2 center = pos * size + offset;
|
||||
const ImRect anchor(center - ImVec2(5, 5), center + ImVec2(5, 5));
|
||||
draw_list->AddConvexPolyFilled(offsets, 4, 0xFF000000);
|
||||
if (anchor.Contains(io.MousePos))
|
||||
{
|
||||
ret = 1;
|
||||
if (io.MouseDown[0])
|
||||
ret = 2;
|
||||
}
|
||||
if (edited)
|
||||
draw_list->AddPolyline(offsets, 4, 0xFFFFFFFF, true, 3.0f);
|
||||
else if (ret)
|
||||
draw_list->AddPolyline(offsets, 4, 0xFF80B0FF, true, 2.0f);
|
||||
else
|
||||
draw_list->AddPolyline(offsets, 4, 0xFF0080FF, true, 2.0f);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int Edit(Delegate& delegate, const ImVec2& size, unsigned int id, const ImRect* clippingRect, ImVector<EditPoint>* selectedPoints)
|
||||
{
|
||||
static bool selectingQuad = false;
|
||||
static ImVec2 quadSelection;
|
||||
static int overCurve = -1;
|
||||
static int movingCurve = -1;
|
||||
static bool scrollingV = false;
|
||||
static std::set<EditPoint> selection;
|
||||
static bool overSelectedPoint = false;
|
||||
|
||||
int ret = 0;
|
||||
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(0, 0));
|
||||
ImGui::PushStyleColor(ImGuiCol_Border, 0);
|
||||
ImGui::BeginChild(id, size, ImGuiChildFlags_FrameStyle);
|
||||
delegate.focused = ImGui::IsWindowFocused();
|
||||
ImDrawList* draw_list = ImGui::GetWindowDrawList();
|
||||
if (clippingRect)
|
||||
draw_list->PushClipRect(clippingRect->Min, clippingRect->Max, true);
|
||||
|
||||
const ImVec2 offset = ImGui::GetCursorScreenPos() + ImVec2(0.f, size.y);
|
||||
const ImVec2 ssize(size.x, -size.y);
|
||||
const ImRect container(offset + ImVec2(0.f, ssize.y), offset + ImVec2(ssize.x, 0.f));
|
||||
ImVec2& min = delegate.GetMin();
|
||||
ImVec2& max = delegate.GetMax();
|
||||
|
||||
// handle zoom and VScroll
|
||||
if (container.Contains(io.MousePos))
|
||||
{
|
||||
if (fabsf(io.MouseWheel) > FLT_EPSILON)
|
||||
{
|
||||
const float r = (io.MousePos.y - offset.y) / ssize.y;
|
||||
float ratioY = ImLerp(min.y, max.y, r);
|
||||
auto scaleValue = [&](float v) {
|
||||
v -= ratioY;
|
||||
v *= (1.f - io.MouseWheel * 0.05f);
|
||||
v += ratioY;
|
||||
return v;
|
||||
};
|
||||
min.y = scaleValue(min.y);
|
||||
max.y = scaleValue(max.y);
|
||||
}
|
||||
if (!scrollingV && ImGui::IsMouseDown(2))
|
||||
{
|
||||
scrollingV = true;
|
||||
}
|
||||
}
|
||||
ImVec2 range = max - min + ImVec2(1.f, 0.f); // +1 because of inclusive last frame
|
||||
|
||||
const ImVec2 viewSize(size.x, -size.y);
|
||||
const ImVec2 sizeOfPixel = ImVec2(1.f, 1.f) / viewSize;
|
||||
const size_t curveCount = delegate.GetCurveCount();
|
||||
|
||||
if (scrollingV)
|
||||
{
|
||||
float deltaH = io.MouseDelta.y * range.y * sizeOfPixel.y;
|
||||
min.y -= deltaH;
|
||||
max.y -= deltaH;
|
||||
if (!ImGui::IsMouseDown(2))
|
||||
scrollingV = false;
|
||||
}
|
||||
|
||||
draw_list->AddRectFilled(offset, offset + ssize, delegate.GetBackgroundColor());
|
||||
|
||||
auto pointToRange = [&](ImVec2 pt) { return (pt - min) / range; };
|
||||
auto rangeToPoint = [&](ImVec2 pt) { return (pt * range) + min; };
|
||||
|
||||
draw_list->AddLine(ImVec2(-1.f, -min.y / range.y) * viewSize + offset, ImVec2(1.f, -min.y / range.y) * viewSize + offset, 0xFF000000, 1.5f);
|
||||
bool overCurveOrPoint = false;
|
||||
|
||||
int localOverCurve = -1;
|
||||
// make sure highlighted curve is rendered last
|
||||
int* curvesIndex = (int*)_malloca(sizeof(int) * curveCount);
|
||||
for (size_t c = 0; c < curveCount; c++)
|
||||
curvesIndex[c] = int(c);
|
||||
int highLightedCurveIndex = -1;
|
||||
if (overCurve != -1 && curveCount)
|
||||
{
|
||||
ImSwap(curvesIndex[overCurve], curvesIndex[curveCount - 1]);
|
||||
highLightedCurveIndex = overCurve;
|
||||
}
|
||||
|
||||
for (size_t cur = 0; cur < curveCount; cur++)
|
||||
{
|
||||
int c = curvesIndex[cur];
|
||||
if (!delegate.IsVisible(c))
|
||||
continue;
|
||||
const size_t ptCount = delegate.GetPointCount(c);
|
||||
if (ptCount < 1)
|
||||
continue;
|
||||
CurveType curveType = delegate.GetCurveType(c);
|
||||
if (curveType == CurveNone)
|
||||
continue;
|
||||
const ImVec2* pts = delegate.GetPoints(c);
|
||||
uint32_t curveColor = delegate.GetCurveColor(c);
|
||||
if ((c == highLightedCurveIndex && selection.empty() && !selectingQuad) || movingCurve == c)
|
||||
curveColor = 0xFFFFFFFF;
|
||||
|
||||
for (size_t p = 0; p < ptCount - 1; p++)
|
||||
{
|
||||
const ImVec2 p1 = pointToRange(pts[p]);
|
||||
const ImVec2 p2 = pointToRange(pts[p + 1]);
|
||||
|
||||
if (curveType == CurveSmooth || curveType == CurveLinear)
|
||||
{
|
||||
size_t subStepCount = (curveType == CurveSmooth) ? 20 : 2;
|
||||
float step = 1.f / float(subStepCount - 1);
|
||||
for (size_t substep = 0; substep < subStepCount - 1; substep++)
|
||||
{
|
||||
float t = float(substep) * step;
|
||||
|
||||
const ImVec2 sp1 = ImLerp(p1, p2, t);
|
||||
const ImVec2 sp2 = ImLerp(p1, p2, t + step);
|
||||
|
||||
const float rt1 = smoothstep(p1.x, p2.x, sp1.x);
|
||||
const float rt2 = smoothstep(p1.x, p2.x, sp2.x);
|
||||
|
||||
const ImVec2 pos1 = ImVec2(sp1.x, ImLerp(p1.y, p2.y, rt1)) * viewSize + offset;
|
||||
const ImVec2 pos2 = ImVec2(sp2.x, ImLerp(p1.y, p2.y, rt2)) * viewSize + offset;
|
||||
|
||||
if (distance(io.MousePos.x, io.MousePos.y, pos1.x, pos1.y, pos2.x, pos2.y) < 8.f && !scrollingV)
|
||||
{
|
||||
localOverCurve = int(c);
|
||||
overCurve = int(c);
|
||||
overCurveOrPoint = true;
|
||||
}
|
||||
|
||||
draw_list->AddLine(pos1, pos2, curveColor, 1.3f);
|
||||
} // substep
|
||||
}
|
||||
else if (curveType == CurveDiscrete)
|
||||
{
|
||||
ImVec2 dp1 = p1 * viewSize + offset;
|
||||
ImVec2 dp2 = ImVec2(p2.x, p1.y) * viewSize + offset;
|
||||
ImVec2 dp3 = p2 * viewSize + offset;
|
||||
draw_list->AddLine(dp1, dp2, curveColor, 1.3f);
|
||||
draw_list->AddLine(dp2, dp3, curveColor, 1.3f);
|
||||
|
||||
if ((distance(io.MousePos.x, io.MousePos.y, dp1.x, dp1.y, dp3.x, dp1.y) < 8.f ||
|
||||
distance(io.MousePos.x, io.MousePos.y, dp3.x, dp1.y, dp3.x, dp3.y) < 8.f)
|
||||
/*&& localOverCurve == -1*/)
|
||||
{
|
||||
localOverCurve = int(c);
|
||||
overCurve = int(c);
|
||||
overCurveOrPoint = true;
|
||||
}
|
||||
}
|
||||
} // point loop
|
||||
|
||||
for (size_t p = 0; p < ptCount; p++)
|
||||
{
|
||||
const int drawState = DrawPoint(draw_list, pointToRange(pts[p]), viewSize, offset, (selection.find({ int(c), int(p) }) != selection.end() && movingCurve == -1 && !scrollingV));
|
||||
if (drawState && movingCurve == -1 && !selectingQuad)
|
||||
{
|
||||
overCurveOrPoint = true;
|
||||
overSelectedPoint = true;
|
||||
overCurve = -1;
|
||||
if (drawState == 2)
|
||||
{
|
||||
if (!io.KeyShift && selection.find({ int(c), int(p) }) == selection.end())
|
||||
selection.clear();
|
||||
selection.insert({ int(c), int(p) });
|
||||
}
|
||||
}
|
||||
}
|
||||
} // curves loop
|
||||
|
||||
if (localOverCurve == -1)
|
||||
overCurve = -1;
|
||||
|
||||
// move selection
|
||||
static bool pointsMoved = false;
|
||||
static ImVec2 mousePosOrigin;
|
||||
static std::vector<ImVec2> originalPoints;
|
||||
if (overSelectedPoint && io.MouseDown[0])
|
||||
{
|
||||
if ((fabsf(io.MouseDelta.x) > 0.f || fabsf(io.MouseDelta.y) > 0.f) && !selection.empty())
|
||||
{
|
||||
if (!pointsMoved)
|
||||
{
|
||||
delegate.BeginEdit(0);
|
||||
mousePosOrigin = io.MousePos;
|
||||
originalPoints.resize(selection.size());
|
||||
int index = 0;
|
||||
for (auto& sel : selection)
|
||||
{
|
||||
const ImVec2* pts = delegate.GetPoints(sel.curveIndex);
|
||||
originalPoints[index++] = pts[sel.pointIndex];
|
||||
}
|
||||
}
|
||||
pointsMoved = true;
|
||||
ret = 1;
|
||||
auto prevSelection = selection;
|
||||
int originalIndex = 0;
|
||||
for (auto& sel : prevSelection)
|
||||
{
|
||||
const ImVec2 p = rangeToPoint(pointToRange(originalPoints[originalIndex]) + (io.MousePos - mousePosOrigin) * sizeOfPixel);
|
||||
const int newIndex = delegate.EditPoint(sel.curveIndex, sel.pointIndex, p);
|
||||
if (newIndex != sel.pointIndex)
|
||||
{
|
||||
selection.erase(sel);
|
||||
selection.insert({ sel.curveIndex, newIndex });
|
||||
}
|
||||
originalIndex++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (overSelectedPoint && !io.MouseDown[0])
|
||||
{
|
||||
overSelectedPoint = false;
|
||||
if (pointsMoved)
|
||||
{
|
||||
pointsMoved = false;
|
||||
delegate.EndEdit();
|
||||
}
|
||||
}
|
||||
|
||||
// add point
|
||||
if (overCurve != -1 && io.MouseDoubleClicked[0])
|
||||
{
|
||||
const ImVec2 np = rangeToPoint((io.MousePos - offset) / viewSize);
|
||||
delegate.BeginEdit(overCurve);
|
||||
delegate.AddPoint(overCurve, np);
|
||||
delegate.EndEdit();
|
||||
ret = 1;
|
||||
}
|
||||
|
||||
// move curve
|
||||
|
||||
if (movingCurve != -1)
|
||||
{
|
||||
const size_t ptCount = delegate.GetPointCount(movingCurve);
|
||||
const ImVec2* pts = delegate.GetPoints(movingCurve);
|
||||
if (!pointsMoved)
|
||||
{
|
||||
mousePosOrigin = io.MousePos;
|
||||
pointsMoved = true;
|
||||
originalPoints.resize(ptCount);
|
||||
for (size_t index = 0; index < ptCount; index++)
|
||||
{
|
||||
originalPoints[index] = pts[index];
|
||||
}
|
||||
}
|
||||
if (ptCount >= 1)
|
||||
{
|
||||
for (size_t p = 0; p < ptCount; p++)
|
||||
{
|
||||
delegate.EditPoint(movingCurve, int(p), rangeToPoint(pointToRange(originalPoints[p]) + (io.MousePos - mousePosOrigin) * sizeOfPixel));
|
||||
}
|
||||
ret = 1;
|
||||
}
|
||||
if (!io.MouseDown[0])
|
||||
{
|
||||
movingCurve = -1;
|
||||
pointsMoved = false;
|
||||
delegate.EndEdit();
|
||||
}
|
||||
}
|
||||
if (movingCurve == -1 && overCurve != -1 && ImGui::IsMouseClicked(0) && selection.empty() && !selectingQuad)
|
||||
{
|
||||
movingCurve = overCurve;
|
||||
delegate.BeginEdit(overCurve);
|
||||
}
|
||||
|
||||
// quad selection
|
||||
if (selectingQuad)
|
||||
{
|
||||
const ImVec2 bmin = ImMin(quadSelection, io.MousePos);
|
||||
const ImVec2 bmax = ImMax(quadSelection, io.MousePos);
|
||||
draw_list->AddRectFilled(bmin, bmax, 0x40FF0000, 1.f);
|
||||
draw_list->AddRect(bmin, bmax, 0xFFFF0000, 1.f);
|
||||
const ImRect selectionQuad(bmin, bmax);
|
||||
if (!io.MouseDown[0])
|
||||
{
|
||||
if (!io.KeyShift)
|
||||
selection.clear();
|
||||
// select everythnig is quad
|
||||
for (size_t c = 0; c < curveCount; c++)
|
||||
{
|
||||
if (!delegate.IsVisible(c))
|
||||
continue;
|
||||
|
||||
const size_t ptCount = delegate.GetPointCount(c);
|
||||
if (ptCount < 1)
|
||||
continue;
|
||||
|
||||
const ImVec2* pts = delegate.GetPoints(c);
|
||||
for (size_t p = 0; p < ptCount; p++)
|
||||
{
|
||||
const ImVec2 center = pointToRange(pts[p]) * viewSize + offset;
|
||||
if (selectionQuad.Contains(center))
|
||||
selection.insert({ int(c), int(p) });
|
||||
}
|
||||
}
|
||||
// done
|
||||
selectingQuad = false;
|
||||
}
|
||||
}
|
||||
if (!overCurveOrPoint && ImGui::IsMouseClicked(0) && !selectingQuad && movingCurve == -1 && !overSelectedPoint && container.Contains(io.MousePos))
|
||||
{
|
||||
selectingQuad = true;
|
||||
quadSelection = io.MousePos;
|
||||
}
|
||||
if (clippingRect)
|
||||
draw_list->PopClipRect();
|
||||
|
||||
ImGui::EndChild();
|
||||
ImGui::PopStyleVar();
|
||||
ImGui::PopStyleColor(1);
|
||||
|
||||
if (selectedPoints)
|
||||
{
|
||||
selectedPoints->resize(int(selection.size()));
|
||||
int index = 0;
|
||||
for (auto& point : selection)
|
||||
(*selectedPoints)[index++] = point;
|
||||
}
|
||||
_freea(curvesIndex);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
82
src/ThirdParty/ImGuizmo/ImCurveEdit.h
vendored
Normal file
82
src/ThirdParty/ImGuizmo/ImCurveEdit.h
vendored
Normal file
@@ -0,0 +1,82 @@
|
||||
// https://github.com/CedricGuillemet/ImGuizmo
|
||||
// v1.92.5 WIP
|
||||
//
|
||||
// The MIT License(MIT)
|
||||
//
|
||||
// Copyright(c) 2016-2021 Cedric Guillemet
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files(the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and / or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions :
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in all
|
||||
// copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
// SOFTWARE.
|
||||
//
|
||||
#pragma once
|
||||
#include <stdint.h>
|
||||
#include "imgui.h"
|
||||
|
||||
struct ImRect;
|
||||
|
||||
namespace ImCurveEdit
|
||||
{
|
||||
enum CurveType
|
||||
{
|
||||
CurveNone,
|
||||
CurveDiscrete,
|
||||
CurveLinear,
|
||||
CurveSmooth,
|
||||
CurveBezier,
|
||||
};
|
||||
|
||||
struct EditPoint
|
||||
{
|
||||
int curveIndex;
|
||||
int pointIndex;
|
||||
bool operator <(const EditPoint& other) const
|
||||
{
|
||||
if (curveIndex < other.curveIndex)
|
||||
return true;
|
||||
if (curveIndex > other.curveIndex)
|
||||
return false;
|
||||
|
||||
if (pointIndex < other.pointIndex)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
struct Delegate
|
||||
{
|
||||
bool focused = false;
|
||||
virtual size_t GetCurveCount() = 0;
|
||||
virtual bool IsVisible(size_t /*curveIndex*/) { return true; }
|
||||
virtual CurveType GetCurveType(size_t /*curveIndex*/) const { return CurveLinear; }
|
||||
virtual ImVec2& GetMin() = 0;
|
||||
virtual ImVec2& GetMax() = 0;
|
||||
virtual size_t GetPointCount(size_t curveIndex) = 0;
|
||||
virtual uint32_t GetCurveColor(size_t curveIndex) = 0;
|
||||
virtual ImVec2* GetPoints(size_t curveIndex) = 0;
|
||||
virtual int EditPoint(size_t curveIndex, int pointIndex, ImVec2 value) = 0;
|
||||
virtual void AddPoint(size_t curveIndex, ImVec2 value) = 0;
|
||||
virtual unsigned int GetBackgroundColor() { return 0xFF202020; }
|
||||
// handle undo/redo thru this functions
|
||||
virtual void BeginEdit(int /*index*/) {}
|
||||
virtual void EndEdit() {}
|
||||
|
||||
virtual ~Delegate() = default;
|
||||
};
|
||||
|
||||
int Edit(Delegate& delegate, const ImVec2& size, unsigned int id, const ImRect* clippingRect = NULL, ImVector<EditPoint>* selectedPoints = NULL);
|
||||
}
|
||||
116
src/ThirdParty/ImGuizmo/ImGradient.cpp
vendored
Normal file
116
src/ThirdParty/ImGuizmo/ImGradient.cpp
vendored
Normal file
@@ -0,0 +1,116 @@
|
||||
// https://github.com/CedricGuillemet/ImGuizmo
|
||||
// v1.92.5 WIP
|
||||
//
|
||||
// The MIT License(MIT)
|
||||
//
|
||||
// Copyright(c) 2016-2021 Cedric Guillemet
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files(the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and / or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions :
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in all
|
||||
// copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
// SOFTWARE.
|
||||
//
|
||||
#include "ImGradient.h"
|
||||
#include "imgui.h"
|
||||
#include "imgui_internal.h"
|
||||
|
||||
namespace ImGradient
|
||||
{
|
||||
#ifndef IMGUI_DEFINE_MATH_OPERATORS
|
||||
static inline ImVec2 operator*(const ImVec2& lhs, const float rhs) { return ImVec2(lhs.x * rhs, lhs.y * rhs); }
|
||||
static inline ImVec2 operator/(const ImVec2& lhs, const float rhs) { return ImVec2(lhs.x / rhs, lhs.y / rhs); }
|
||||
static inline ImVec2 operator+(const ImVec2& lhs, const ImVec2& rhs) { return ImVec2(lhs.x + rhs.x, lhs.y + rhs.y); }
|
||||
static inline ImVec2 operator-(const ImVec2& lhs, const ImVec2& rhs) { return ImVec2(lhs.x - rhs.x, lhs.y - rhs.y); }
|
||||
static inline ImVec2 operator*(const ImVec2& lhs, const ImVec2& rhs) { return ImVec2(lhs.x * rhs.x, lhs.y * rhs.y); }
|
||||
static inline ImVec2 operator/(const ImVec2& lhs, const ImVec2& rhs) { return ImVec2(lhs.x / rhs.x, lhs.y / rhs.y); }
|
||||
#endif
|
||||
|
||||
static int DrawPoint(ImDrawList* draw_list, ImVec4 color, const ImVec2 size, bool editing, ImVec2 pos)
|
||||
{
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
|
||||
ImVec2 p1 = ImLerp(pos, ImVec2(pos + ImVec2(size.x - size.y, 0.f)), color.w) + ImVec2(3, 3);
|
||||
ImVec2 p2 = ImLerp(pos + ImVec2(size.y, size.y), ImVec2(pos + size), color.w) - ImVec2(3, 3);
|
||||
ImRect rc(p1, p2);
|
||||
|
||||
color.w = 1.f;
|
||||
draw_list->AddRectFilled(p1, p2, ImColor(color));
|
||||
if (editing)
|
||||
draw_list->AddRect(p1, p2, 0xFFFFFFFF, 2.f, 15, 2.5f);
|
||||
else
|
||||
draw_list->AddRect(p1, p2, 0x80FFFFFF, 2.f, 15, 1.25f);
|
||||
|
||||
if (rc.Contains(io.MousePos))
|
||||
{
|
||||
if (io.MouseClicked[0])
|
||||
return 2;
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool Edit(Delegate& delegate, const ImVec2& size, int& selection)
|
||||
{
|
||||
bool ret = false;
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(0, 0));
|
||||
ImGui::BeginChild(137, size, ImGuiChildFlags_FrameStyle);
|
||||
|
||||
ImDrawList* draw_list = ImGui::GetWindowDrawList();
|
||||
const ImVec2 offset = ImGui::GetCursorScreenPos();
|
||||
|
||||
const ImVec4* pts = delegate.GetPoints();
|
||||
static int currentSelection = -1;
|
||||
static int movingPt = -1;
|
||||
if (currentSelection >= int(delegate.GetPointCount()))
|
||||
currentSelection = -1;
|
||||
if (movingPt != -1)
|
||||
{
|
||||
ImVec4 current = pts[movingPt];
|
||||
current.w += io.MouseDelta.x / size.x;
|
||||
current.w = ImClamp(current.w, 0.f, 1.f);
|
||||
delegate.EditPoint(movingPt, current);
|
||||
ret = true;
|
||||
if (!io.MouseDown[0])
|
||||
movingPt = -1;
|
||||
}
|
||||
for (size_t i = 0; i < delegate.GetPointCount(); i++)
|
||||
{
|
||||
int ptSel = DrawPoint(draw_list, pts[i], size, i == currentSelection, offset);
|
||||
if (ptSel == 2)
|
||||
{
|
||||
currentSelection = int(i);
|
||||
ret = true;
|
||||
}
|
||||
if (ptSel == 1 && io.MouseDown[0] && movingPt == -1)
|
||||
{
|
||||
movingPt = int(i);
|
||||
}
|
||||
}
|
||||
ImRect rc(offset, offset + size);
|
||||
if (rc.Contains(io.MousePos) && io.MouseDoubleClicked[0])
|
||||
{
|
||||
float t = (io.MousePos.x - offset.x) / size.x;
|
||||
delegate.AddPoint(delegate.GetPoint(t));
|
||||
ret = true;
|
||||
}
|
||||
ImGui::EndChild();
|
||||
ImGui::PopStyleVar();
|
||||
|
||||
selection = currentSelection;
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
45
src/ThirdParty/ImGuizmo/ImGradient.h
vendored
Normal file
45
src/ThirdParty/ImGuizmo/ImGradient.h
vendored
Normal file
@@ -0,0 +1,45 @@
|
||||
// https://github.com/CedricGuillemet/ImGuizmo
|
||||
// v1.92.5 WIP
|
||||
//
|
||||
// The MIT License(MIT)
|
||||
//
|
||||
// Copyright(c) 2016-2021 Cedric Guillemet
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files(the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and / or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions :
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in all
|
||||
// copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
// SOFTWARE.
|
||||
//
|
||||
#pragma once
|
||||
#include <cstddef>
|
||||
|
||||
struct ImVec4;
|
||||
struct ImVec2;
|
||||
|
||||
namespace ImGradient
|
||||
{
|
||||
struct Delegate
|
||||
{
|
||||
virtual size_t GetPointCount() = 0;
|
||||
virtual ImVec4* GetPoints() = 0;
|
||||
virtual int EditPoint(int pointIndex, ImVec4 value) = 0;
|
||||
virtual ImVec4 GetPoint(float t) = 0;
|
||||
virtual void AddPoint(ImVec4 value) = 0;
|
||||
virtual ~Delegate() = default;
|
||||
};
|
||||
|
||||
bool Edit(Delegate& delegate, const ImVec2& size, int& selection);
|
||||
}
|
||||
3164
src/ThirdParty/ImGuizmo/ImGuizmo.cpp
vendored
Executable file
3164
src/ThirdParty/ImGuizmo/ImGuizmo.cpp
vendored
Executable file
File diff suppressed because it is too large
Load Diff
306
src/ThirdParty/ImGuizmo/ImGuizmo.h
vendored
Normal file
306
src/ThirdParty/ImGuizmo/ImGuizmo.h
vendored
Normal file
@@ -0,0 +1,306 @@
|
||||
// https://github.com/CedricGuillemet/ImGuizmo
|
||||
// v1.92.5 WIP
|
||||
//
|
||||
// The MIT License(MIT)
|
||||
//
|
||||
// Copyright(c) 2016-2021 Cedric Guillemet
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files(the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and / or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions :
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in all
|
||||
// copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
// SOFTWARE.
|
||||
//
|
||||
// -------------------------------------------------------------------------------------------
|
||||
// History :
|
||||
// 2019/11/03 View gizmo
|
||||
// 2016/09/11 Behind camera culling. Scaling Delta matrix not multiplied by source matrix scales. local/world rotation and translation fixed. Display message is incorrect (X: ... Y:...) in local mode.
|
||||
// 2016/09/09 Hatched negative axis. Snapping. Documentation update.
|
||||
// 2016/09/04 Axis switch and translation plan autohiding. Scale transform stability improved
|
||||
// 2016/09/01 Mogwai changed to Manipulate. Draw debug cube. Fixed inverted scale. Mixing scale and translation/rotation gives bad results.
|
||||
// 2016/08/31 First version
|
||||
//
|
||||
// -------------------------------------------------------------------------------------------
|
||||
// Future (no order):
|
||||
//
|
||||
// - Multi view
|
||||
// - display rotation/translation/scale infos in local/world space and not only local
|
||||
// - finish local/world matrix application
|
||||
// - OPERATION as bitmask
|
||||
//
|
||||
// -------------------------------------------------------------------------------------------
|
||||
// Example
|
||||
#if 0
|
||||
void EditTransform(const Camera& camera, matrix_t& matrix)
|
||||
{
|
||||
static ImGuizmo::OPERATION mCurrentGizmoOperation(ImGuizmo::ROTATE);
|
||||
static ImGuizmo::MODE mCurrentGizmoMode(ImGuizmo::WORLD);
|
||||
if (ImGui::IsKeyPressed(90))
|
||||
mCurrentGizmoOperation = ImGuizmo::TRANSLATE;
|
||||
if (ImGui::IsKeyPressed(69))
|
||||
mCurrentGizmoOperation = ImGuizmo::ROTATE;
|
||||
if (ImGui::IsKeyPressed(82)) // r Key
|
||||
mCurrentGizmoOperation = ImGuizmo::SCALE;
|
||||
if (ImGui::RadioButton("Translate", mCurrentGizmoOperation == ImGuizmo::TRANSLATE))
|
||||
mCurrentGizmoOperation = ImGuizmo::TRANSLATE;
|
||||
ImGui::SameLine();
|
||||
if (ImGui::RadioButton("Rotate", mCurrentGizmoOperation == ImGuizmo::ROTATE))
|
||||
mCurrentGizmoOperation = ImGuizmo::ROTATE;
|
||||
ImGui::SameLine();
|
||||
if (ImGui::RadioButton("Scale", mCurrentGizmoOperation == ImGuizmo::SCALE))
|
||||
mCurrentGizmoOperation = ImGuizmo::SCALE;
|
||||
float matrixTranslation[3], matrixRotation[3], matrixScale[3];
|
||||
ImGuizmo::DecomposeMatrixToComponents(matrix.m16, matrixTranslation, matrixRotation, matrixScale);
|
||||
ImGui::InputFloat3("Tr", matrixTranslation, 3);
|
||||
ImGui::InputFloat3("Rt", matrixRotation, 3);
|
||||
ImGui::InputFloat3("Sc", matrixScale, 3);
|
||||
ImGuizmo::RecomposeMatrixFromComponents(matrixTranslation, matrixRotation, matrixScale, matrix.m16);
|
||||
|
||||
if (mCurrentGizmoOperation != ImGuizmo::SCALE)
|
||||
{
|
||||
if (ImGui::RadioButton("Local", mCurrentGizmoMode == ImGuizmo::LOCAL))
|
||||
mCurrentGizmoMode = ImGuizmo::LOCAL;
|
||||
ImGui::SameLine();
|
||||
if (ImGui::RadioButton("World", mCurrentGizmoMode == ImGuizmo::WORLD))
|
||||
mCurrentGizmoMode = ImGuizmo::WORLD;
|
||||
}
|
||||
static bool useSnap(false);
|
||||
if (ImGui::IsKeyPressed(83))
|
||||
useSnap = !useSnap;
|
||||
ImGui::Checkbox("", &useSnap);
|
||||
ImGui::SameLine();
|
||||
vec_t snap;
|
||||
switch (mCurrentGizmoOperation)
|
||||
{
|
||||
case ImGuizmo::TRANSLATE:
|
||||
snap = config.mSnapTranslation;
|
||||
ImGui::InputFloat3("Snap", &snap.x);
|
||||
break;
|
||||
case ImGuizmo::ROTATE:
|
||||
snap = config.mSnapRotation;
|
||||
ImGui::InputFloat("Angle Snap", &snap.x);
|
||||
break;
|
||||
case ImGuizmo::SCALE:
|
||||
snap = config.mSnapScale;
|
||||
ImGui::InputFloat("Scale Snap", &snap.x);
|
||||
break;
|
||||
}
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
ImGuizmo::SetRect(0, 0, io.DisplaySize.x, io.DisplaySize.y);
|
||||
ImGuizmo::Manipulate(camera.mView.m16, camera.mProjection.m16, mCurrentGizmoOperation, mCurrentGizmoMode, matrix.m16, NULL, useSnap ? &snap.x : NULL);
|
||||
}
|
||||
#endif
|
||||
#pragma once
|
||||
|
||||
#ifdef USE_IMGUI_API
|
||||
#include "imconfig.h"
|
||||
#endif
|
||||
#ifndef IMGUI_API
|
||||
#define IMGUI_API
|
||||
#endif
|
||||
|
||||
#ifndef IMGUIZMO_NAMESPACE
|
||||
#define IMGUIZMO_NAMESPACE ImGuizmo
|
||||
#endif
|
||||
|
||||
struct ImGuiWindow;
|
||||
|
||||
namespace IMGUIZMO_NAMESPACE
|
||||
{
|
||||
// call inside your own window and before Manipulate() in order to draw gizmo to that window.
|
||||
// Or pass a specific ImDrawList to draw to (e.g. ImGui::GetForegroundDrawList()).
|
||||
IMGUI_API void SetDrawlist(ImDrawList* drawlist = nullptr);
|
||||
|
||||
// call BeginFrame right after ImGui_XXXX_NewFrame();
|
||||
IMGUI_API void BeginFrame();
|
||||
|
||||
// this is necessary because when imguizmo is compiled into a dll, and imgui into another
|
||||
// globals are not shared between them.
|
||||
// More details at https://stackoverflow.com/questions/19373061/what-happens-to-global-and-static-variables-in-a-shared-library-when-it-is-dynam
|
||||
// expose method to set imgui context
|
||||
IMGUI_API void SetImGuiContext(ImGuiContext* ctx);
|
||||
|
||||
// return true if mouse cursor is over any gizmo control (axis, plan or screen component)
|
||||
IMGUI_API bool IsOver();
|
||||
|
||||
// return true if mouse IsOver or if the gizmo is in moving state
|
||||
IMGUI_API bool IsUsing();
|
||||
|
||||
// return true if the view gizmo is in moving state
|
||||
IMGUI_API bool IsUsingViewManipulate();
|
||||
// only check if your mouse is over the view manipulator - no matter whether it's active or not
|
||||
IMGUI_API bool IsViewManipulateHovered();
|
||||
|
||||
// return true if any gizmo is in moving state
|
||||
IMGUI_API bool IsUsingAny();
|
||||
|
||||
// enable/disable the gizmo. Stay in the state until next call to Enable.
|
||||
// gizmo is rendered with gray half transparent color when disabled
|
||||
IMGUI_API void Enable(bool enable);
|
||||
|
||||
// helper functions for manualy editing translation/rotation/scale with an input float
|
||||
// translation, rotation and scale float points to 3 floats each
|
||||
// Angles are in degrees (more suitable for human editing)
|
||||
// example:
|
||||
// float matrixTranslation[3], matrixRotation[3], matrixScale[3];
|
||||
// ImGuizmo::DecomposeMatrixToComponents(gizmoMatrix.m16, matrixTranslation, matrixRotation, matrixScale);
|
||||
// ImGui::InputFloat3("Tr", matrixTranslation, 3);
|
||||
// ImGui::InputFloat3("Rt", matrixRotation, 3);
|
||||
// ImGui::InputFloat3("Sc", matrixScale, 3);
|
||||
// ImGuizmo::RecomposeMatrixFromComponents(matrixTranslation, matrixRotation, matrixScale, gizmoMatrix.m16);
|
||||
//
|
||||
// These functions have some numerical stability issues for now. Use with caution.
|
||||
IMGUI_API void DecomposeMatrixToComponents(const float* matrix, float* translation, float* rotation, float* scale);
|
||||
IMGUI_API void RecomposeMatrixFromComponents(const float* translation, const float* rotation, const float* scale, float* matrix);
|
||||
|
||||
IMGUI_API void SetRect(float x, float y, float width, float height);
|
||||
// default is false
|
||||
IMGUI_API void SetOrthographic(bool isOrthographic);
|
||||
|
||||
// Render a cube with face color corresponding to face normal. Usefull for debug/tests
|
||||
IMGUI_API void DrawCubes(const float* view, const float* projection, const float* matrices, int matrixCount);
|
||||
IMGUI_API void DrawGrid(const float* view, const float* projection, const float* matrix, const float gridSize);
|
||||
|
||||
// call it when you want a gizmo
|
||||
// Needs view and projection matrices.
|
||||
// matrix parameter is the source matrix (where will be gizmo be drawn) and might be transformed by the function. Return deltaMatrix is optional
|
||||
// translation is applied in world space
|
||||
enum OPERATION
|
||||
{
|
||||
TRANSLATE_X = (1u << 0),
|
||||
TRANSLATE_Y = (1u << 1),
|
||||
TRANSLATE_Z = (1u << 2),
|
||||
ROTATE_X = (1u << 3),
|
||||
ROTATE_Y = (1u << 4),
|
||||
ROTATE_Z = (1u << 5),
|
||||
ROTATE_SCREEN = (1u << 6),
|
||||
SCALE_X = (1u << 7),
|
||||
SCALE_Y = (1u << 8),
|
||||
SCALE_Z = (1u << 9),
|
||||
BOUNDS = (1u << 10),
|
||||
SCALE_XU = (1u << 11),
|
||||
SCALE_YU = (1u << 12),
|
||||
SCALE_ZU = (1u << 13),
|
||||
|
||||
TRANSLATE = TRANSLATE_X | TRANSLATE_Y | TRANSLATE_Z,
|
||||
ROTATE = ROTATE_X | ROTATE_Y | ROTATE_Z | ROTATE_SCREEN,
|
||||
SCALE = SCALE_X | SCALE_Y | SCALE_Z,
|
||||
SCALEU = SCALE_XU | SCALE_YU | SCALE_ZU, // universal
|
||||
UNIVERSAL = TRANSLATE | ROTATE | SCALEU
|
||||
};
|
||||
|
||||
inline OPERATION operator|(OPERATION lhs, OPERATION rhs)
|
||||
{
|
||||
return static_cast<OPERATION>(static_cast<int>(lhs) | static_cast<int>(rhs));
|
||||
}
|
||||
|
||||
enum MODE
|
||||
{
|
||||
LOCAL,
|
||||
WORLD
|
||||
};
|
||||
|
||||
IMGUI_API bool Manipulate(const float* view, const float* projection, OPERATION operation, MODE mode, float* matrix, float* deltaMatrix = NULL, const float* snap = NULL, const float* localBounds = NULL, const float* boundsSnap = NULL);
|
||||
//
|
||||
// Please note that this cubeview is patented by Autodesk : https://patents.google.com/patent/US7782319B2/en
|
||||
// It seems to be a defensive patent in the US. I don't think it will bring troubles using it as
|
||||
// other software are using the same mechanics. But just in case, you are now warned!
|
||||
//
|
||||
IMGUI_API void ViewManipulate(float* view, float length, ImVec2 position, ImVec2 size, ImU32 backgroundColor);
|
||||
|
||||
// use this version if you did not call Manipulate before and you are just using ViewManipulate
|
||||
IMGUI_API void ViewManipulate(float* view, const float* projection, OPERATION operation, MODE mode, float* matrix, float length, ImVec2 position, ImVec2 size, ImU32 backgroundColor);
|
||||
|
||||
IMGUI_API void SetAlternativeWindow(ImGuiWindow* window);
|
||||
|
||||
[[deprecated("Use PushID/PopID instead.")]]
|
||||
IMGUI_API void SetID(int id);
|
||||
|
||||
// ID stack/scopes
|
||||
// Read the FAQ (docs/FAQ.md or http://dearimgui.org/faq) for more details about how ID are handled in dear imgui.
|
||||
// - Those questions are answered and impacted by understanding of the ID stack system:
|
||||
// - "Q: Why is my widget not reacting when I click on it?"
|
||||
// - "Q: How can I have widgets with an empty label?"
|
||||
// - "Q: How can I have multiple widgets with the same label?"
|
||||
// - Short version: ID are hashes of the entire ID stack. If you are creating widgets in a loop you most likely
|
||||
// want to push a unique identifier (e.g. object pointer, loop index) to uniquely differentiate them.
|
||||
// - You can also use the "Label##foobar" syntax within widget label to distinguish them from each others.
|
||||
// - In this header file we use the "label"/"name" terminology to denote a string that will be displayed + used as an ID,
|
||||
// whereas "str_id" denote a string that is only used as an ID and not normally displayed.
|
||||
IMGUI_API void PushID(const char* str_id); // push string into the ID stack (will hash string).
|
||||
IMGUI_API void PushID(const char* str_id_begin, const char* str_id_end); // push string into the ID stack (will hash string).
|
||||
IMGUI_API void PushID(const void* ptr_id); // push pointer into the ID stack (will hash pointer).
|
||||
IMGUI_API void PushID(int int_id); // push integer into the ID stack (will hash integer).
|
||||
IMGUI_API void PopID(); // pop from the ID stack.
|
||||
IMGUI_API ImGuiID GetID(const char* str_id); // calculate unique ID (hash of whole ID stack + given parameter). e.g. if you want to query into ImGuiStorage yourself
|
||||
IMGUI_API ImGuiID GetID(const char* str_id_begin, const char* str_id_end);
|
||||
IMGUI_API ImGuiID GetID(const void* ptr_id);
|
||||
|
||||
// return true if the cursor is over the operation's gizmo
|
||||
IMGUI_API bool IsOver(OPERATION op);
|
||||
IMGUI_API void SetGizmoSizeClipSpace(float value);
|
||||
|
||||
// Allow axis to flip
|
||||
// When true (default), the guizmo axis flip for better visibility
|
||||
// When false, they always stay along the positive world/local axis
|
||||
IMGUI_API void AllowAxisFlip(bool value);
|
||||
|
||||
// Configure the limit where axis are hidden
|
||||
IMGUI_API void SetAxisLimit(float value);
|
||||
// Set an axis mask to permanently hide a given axis (true -> hidden, false -> shown)
|
||||
IMGUI_API void SetAxisMask(bool x, bool y, bool z);
|
||||
// Configure the limit where planes are hiden
|
||||
IMGUI_API void SetPlaneLimit(float value);
|
||||
// from a x,y,z point in space and using Manipulation view/projection matrix, check if mouse is in pixel radius distance of that projected point
|
||||
IMGUI_API bool IsOver(float* position, float pixelRadius);
|
||||
|
||||
enum COLOR
|
||||
{
|
||||
DIRECTION_X, // directionColor[0]
|
||||
DIRECTION_Y, // directionColor[1]
|
||||
DIRECTION_Z, // directionColor[2]
|
||||
PLANE_X, // planeColor[0]
|
||||
PLANE_Y, // planeColor[1]
|
||||
PLANE_Z, // planeColor[2]
|
||||
SELECTION, // selectionColor
|
||||
INACTIVE, // inactiveColor
|
||||
TRANSLATION_LINE, // translationLineColor
|
||||
SCALE_LINE,
|
||||
ROTATION_USING_BORDER,
|
||||
ROTATION_USING_FILL,
|
||||
HATCHED_AXIS_LINES,
|
||||
TEXT,
|
||||
TEXT_SHADOW,
|
||||
COUNT
|
||||
};
|
||||
|
||||
struct Style
|
||||
{
|
||||
IMGUI_API Style();
|
||||
|
||||
float TranslationLineThickness; // Thickness of lines for translation gizmo
|
||||
float TranslationLineArrowSize; // Size of arrow at the end of lines for translation gizmo
|
||||
float RotationLineThickness; // Thickness of lines for rotation gizmo
|
||||
float RotationOuterLineThickness; // Thickness of line surrounding the rotation gizmo
|
||||
float ScaleLineThickness; // Thickness of lines for scale gizmo
|
||||
float ScaleLineCircleSize; // Size of circle at the end of lines for scale gizmo
|
||||
float HatchedAxisLineThickness; // Thickness of hatched axis lines
|
||||
float CenterCircleSize; // Size of circle at the center of the translate/scale gizmo
|
||||
|
||||
ImVec4 Colors[COLOR::COUNT];
|
||||
};
|
||||
|
||||
IMGUI_API Style& GetStyle();
|
||||
}
|
||||
695
src/ThirdParty/ImGuizmo/ImSequencer.cpp
vendored
Normal file
695
src/ThirdParty/ImGuizmo/ImSequencer.cpp
vendored
Normal file
@@ -0,0 +1,695 @@
|
||||
// https://github.com/CedricGuillemet/ImGuizmo
|
||||
// v1.92.5 WIP
|
||||
//
|
||||
// The MIT License(MIT)
|
||||
//
|
||||
// Copyright(c) 2016-2021 Cedric Guillemet
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files(the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and / or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions :
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in all
|
||||
// copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
// SOFTWARE.
|
||||
//
|
||||
#include "ImSequencer.h"
|
||||
#include "imgui.h"
|
||||
#include "imgui_internal.h"
|
||||
#include <cstdlib>
|
||||
|
||||
namespace ImSequencer
|
||||
{
|
||||
#ifndef IMGUI_DEFINE_MATH_OPERATORS
|
||||
static ImVec2 operator+(const ImVec2& a, const ImVec2& b) {
|
||||
return ImVec2(a.x + b.x, a.y + b.y);
|
||||
}
|
||||
#endif
|
||||
static bool SequencerAddDelButton(ImDrawList* draw_list, ImVec2 pos, bool add = true)
|
||||
{
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
ImRect btnRect(pos, ImVec2(pos.x + 16, pos.y + 16));
|
||||
bool overBtn = btnRect.Contains(io.MousePos);
|
||||
bool containedClick = overBtn && btnRect.Contains(io.MouseClickedPos[0]);
|
||||
bool clickedBtn = containedClick && io.MouseReleased[0];
|
||||
int btnColor = overBtn ? 0xAAEAFFAA : 0x77A3B2AA;
|
||||
if (containedClick && io.MouseDownDuration[0] > 0)
|
||||
btnRect.Expand(2.0f);
|
||||
|
||||
float midy = pos.y + 16 / 2 - 0.5f;
|
||||
float midx = pos.x + 16 / 2 - 0.5f;
|
||||
draw_list->AddRect(btnRect.Min, btnRect.Max, btnColor, 4);
|
||||
draw_list->AddLine(ImVec2(btnRect.Min.x + 3, midy), ImVec2(btnRect.Max.x - 3, midy), btnColor, 2);
|
||||
if (add)
|
||||
draw_list->AddLine(ImVec2(midx, btnRect.Min.y + 3), ImVec2(midx, btnRect.Max.y - 3), btnColor, 2);
|
||||
return clickedBtn;
|
||||
}
|
||||
|
||||
bool Sequencer(SequenceInterface* sequence, int* currentFrame, bool* expanded, int* selectedEntry, int* firstFrame, int sequenceOptions)
|
||||
{
|
||||
bool ret = false;
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
int cx = (int)(io.MousePos.x);
|
||||
int cy = (int)(io.MousePos.y);
|
||||
static float framePixelWidth = 10.f;
|
||||
static float framePixelWidthTarget = 10.f;
|
||||
int legendWidth = 200;
|
||||
|
||||
static int movingEntry = -1;
|
||||
static int movingPos = -1;
|
||||
static int movingPart = -1;
|
||||
int delEntry = -1;
|
||||
int dupEntry = -1;
|
||||
int ItemHeight = 20;
|
||||
|
||||
bool popupOpened = false;
|
||||
int sequenceCount = sequence->GetItemCount();
|
||||
if (!sequenceCount)
|
||||
return false;
|
||||
ImGui::BeginGroup();
|
||||
|
||||
ImDrawList* draw_list = ImGui::GetWindowDrawList();
|
||||
ImVec2 canvas_pos = ImGui::GetCursorScreenPos(); // ImDrawList API uses screen coordinates!
|
||||
ImVec2 canvas_size = ImGui::GetContentRegionAvail(); // Resize canvas to what's available
|
||||
int firstFrameUsed = firstFrame ? *firstFrame : 0;
|
||||
|
||||
|
||||
int controlHeight = sequenceCount * ItemHeight;
|
||||
for (int i = 0; i < sequenceCount; i++)
|
||||
controlHeight += int(sequence->GetCustomHeight(i));
|
||||
int frameCount = ImMax(sequence->GetFrameMax() - sequence->GetFrameMin(), 1);
|
||||
|
||||
static bool MovingScrollBar = false;
|
||||
static bool MovingCurrentFrame = false;
|
||||
struct CustomDraw
|
||||
{
|
||||
int index;
|
||||
ImRect customRect;
|
||||
ImRect legendRect;
|
||||
ImRect clippingRect;
|
||||
ImRect legendClippingRect;
|
||||
};
|
||||
ImVector<CustomDraw> customDraws;
|
||||
ImVector<CustomDraw> compactCustomDraws;
|
||||
// zoom in/out
|
||||
const int visibleFrameCount = (int)floorf((canvas_size.x - legendWidth) / framePixelWidth);
|
||||
const float barWidthRatio = ImMin(visibleFrameCount / (float)frameCount, 1.f);
|
||||
const float barWidthInPixels = barWidthRatio * (canvas_size.x - legendWidth);
|
||||
|
||||
ImRect regionRect(canvas_pos, canvas_pos + canvas_size);
|
||||
|
||||
static bool panningView = false;
|
||||
static ImVec2 panningViewSource;
|
||||
static int panningViewFrame;
|
||||
if (ImGui::IsWindowFocused() && io.KeyAlt && io.MouseDown[2])
|
||||
{
|
||||
if (!panningView)
|
||||
{
|
||||
panningViewSource = io.MousePos;
|
||||
panningView = true;
|
||||
panningViewFrame = *firstFrame;
|
||||
}
|
||||
*firstFrame = panningViewFrame - int((io.MousePos.x - panningViewSource.x) / framePixelWidth);
|
||||
*firstFrame = ImClamp(*firstFrame, sequence->GetFrameMin(), sequence->GetFrameMax() - visibleFrameCount);
|
||||
}
|
||||
if (panningView && !io.MouseDown[2])
|
||||
{
|
||||
panningView = false;
|
||||
}
|
||||
framePixelWidthTarget = ImClamp(framePixelWidthTarget, 0.1f, 50.f);
|
||||
|
||||
framePixelWidth = ImLerp(framePixelWidth, framePixelWidthTarget, 0.33f);
|
||||
|
||||
frameCount = sequence->GetFrameMax() - sequence->GetFrameMin();
|
||||
if (visibleFrameCount >= frameCount && firstFrame)
|
||||
*firstFrame = sequence->GetFrameMin();
|
||||
|
||||
|
||||
// --
|
||||
if (expanded && !*expanded)
|
||||
{
|
||||
ImGui::InvisibleButton("canvas", ImVec2(canvas_size.x - canvas_pos.x, (float)ItemHeight));
|
||||
draw_list->AddRectFilled(canvas_pos, ImVec2(canvas_size.x + canvas_pos.x, canvas_pos.y + ItemHeight), 0xFF3D3837, 0);
|
||||
char tmps[512];
|
||||
ImFormatString(tmps, IM_ARRAYSIZE(tmps), sequence->GetCollapseFmt(), frameCount, sequenceCount);
|
||||
draw_list->AddText(ImVec2(canvas_pos.x + 26, canvas_pos.y + 2), 0xFFFFFFFF, tmps);
|
||||
}
|
||||
else
|
||||
{
|
||||
bool hasScrollBar(true);
|
||||
/*
|
||||
int framesPixelWidth = int(frameCount * framePixelWidth);
|
||||
if ((framesPixelWidth + legendWidth) >= canvas_size.x)
|
||||
{
|
||||
hasScrollBar = true;
|
||||
}
|
||||
*/
|
||||
// test scroll area
|
||||
ImVec2 headerSize(canvas_size.x, (float)ItemHeight);
|
||||
ImVec2 scrollBarSize(canvas_size.x, 14.f);
|
||||
ImGui::InvisibleButton("topBar", headerSize);
|
||||
draw_list->AddRectFilled(canvas_pos, canvas_pos + headerSize, 0xFFFF0000, 0);
|
||||
ImVec2 childFramePos = ImGui::GetCursorScreenPos();
|
||||
ImVec2 childFrameSize(canvas_size.x, canvas_size.y - 8.f - headerSize.y - (hasScrollBar ? scrollBarSize.y : 0));
|
||||
ImGui::PushStyleColor(ImGuiCol_FrameBg, 0);
|
||||
ImGui::BeginChild(889, childFrameSize, ImGuiChildFlags_FrameStyle);
|
||||
sequence->focused = ImGui::IsWindowFocused();
|
||||
ImGui::InvisibleButton("contentBar", ImVec2(canvas_size.x, float(controlHeight)));
|
||||
const ImVec2 contentMin = ImGui::GetItemRectMin();
|
||||
const ImVec2 contentMax = ImGui::GetItemRectMax();
|
||||
const ImRect contentRect(contentMin, contentMax);
|
||||
const float contentHeight = contentMax.y - contentMin.y;
|
||||
|
||||
// full background
|
||||
draw_list->AddRectFilled(canvas_pos, canvas_pos + canvas_size, 0xFF242424, 0);
|
||||
|
||||
// current frame top
|
||||
ImRect topRect(ImVec2(canvas_pos.x + legendWidth, canvas_pos.y), ImVec2(canvas_pos.x + canvas_size.x, canvas_pos.y + ItemHeight));
|
||||
|
||||
if (!MovingCurrentFrame && !MovingScrollBar && movingEntry == -1 && sequenceOptions & SEQUENCER_CHANGE_FRAME && currentFrame && *currentFrame >= 0 && topRect.Contains(io.MousePos) && io.MouseDown[0])
|
||||
{
|
||||
MovingCurrentFrame = true;
|
||||
}
|
||||
if (MovingCurrentFrame)
|
||||
{
|
||||
if (frameCount)
|
||||
{
|
||||
*currentFrame = (int)((io.MousePos.x - topRect.Min.x) / framePixelWidth) + firstFrameUsed;
|
||||
if (*currentFrame < sequence->GetFrameMin())
|
||||
*currentFrame = sequence->GetFrameMin();
|
||||
if (*currentFrame >= sequence->GetFrameMax())
|
||||
*currentFrame = sequence->GetFrameMax();
|
||||
}
|
||||
if (!io.MouseDown[0])
|
||||
MovingCurrentFrame = false;
|
||||
}
|
||||
|
||||
//header
|
||||
draw_list->AddRectFilled(canvas_pos, ImVec2(canvas_size.x + canvas_pos.x, canvas_pos.y + ItemHeight), 0xFF3D3837, 0);
|
||||
if (sequenceOptions & SEQUENCER_ADD)
|
||||
{
|
||||
if (SequencerAddDelButton(draw_list, ImVec2(canvas_pos.x + legendWidth - ItemHeight, canvas_pos.y + 2), true))
|
||||
ImGui::OpenPopup("addEntry");
|
||||
|
||||
if (ImGui::BeginPopup("addEntry"))
|
||||
{
|
||||
for (int i = 0; i < sequence->GetItemTypeCount(); i++)
|
||||
if (ImGui::Selectable(sequence->GetItemTypeName(i)))
|
||||
{
|
||||
sequence->Add(i);
|
||||
*selectedEntry = sequence->GetItemCount() - 1;
|
||||
}
|
||||
|
||||
ImGui::EndPopup();
|
||||
popupOpened = true;
|
||||
}
|
||||
}
|
||||
|
||||
//header frame number and lines
|
||||
int modFrameCount = 10;
|
||||
int frameStep = 1;
|
||||
while ((modFrameCount * framePixelWidth) < 150)
|
||||
{
|
||||
modFrameCount *= 2;
|
||||
frameStep *= 2;
|
||||
};
|
||||
int halfModFrameCount = modFrameCount / 2;
|
||||
|
||||
auto drawLine = [&](int i, int regionHeight) {
|
||||
bool baseIndex = ((i % modFrameCount) == 0) || (i == sequence->GetFrameMax() || i == sequence->GetFrameMin());
|
||||
bool halfIndex = (i % halfModFrameCount) == 0;
|
||||
int px = (int)canvas_pos.x + int(i * framePixelWidth) + legendWidth - int(firstFrameUsed * framePixelWidth);
|
||||
int tiretStart = baseIndex ? 4 : (halfIndex ? 10 : 14);
|
||||
int tiretEnd = baseIndex ? regionHeight : ItemHeight;
|
||||
|
||||
if (px <= (canvas_size.x + canvas_pos.x) && px >= (canvas_pos.x + legendWidth))
|
||||
{
|
||||
draw_list->AddLine(ImVec2((float)px, canvas_pos.y + (float)tiretStart), ImVec2((float)px, canvas_pos.y + (float)tiretEnd - 1), 0xFF606060, 1);
|
||||
|
||||
draw_list->AddLine(ImVec2((float)px, canvas_pos.y + (float)ItemHeight), ImVec2((float)px, canvas_pos.y + (float)regionHeight - 1), 0x30606060, 1);
|
||||
}
|
||||
|
||||
if (baseIndex && px > (canvas_pos.x + legendWidth))
|
||||
{
|
||||
char tmps[512];
|
||||
ImFormatString(tmps, IM_ARRAYSIZE(tmps), "%d", i);
|
||||
draw_list->AddText(ImVec2((float)px + 3.f, canvas_pos.y), 0xFFBBBBBB, tmps);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
auto drawLineContent = [&](int i, int /*regionHeight*/) {
|
||||
int px = (int)canvas_pos.x + int(i * framePixelWidth) + legendWidth - int(firstFrameUsed * framePixelWidth);
|
||||
int tiretStart = int(contentMin.y);
|
||||
int tiretEnd = int(contentMax.y);
|
||||
|
||||
if (px <= (canvas_size.x + canvas_pos.x) && px >= (canvas_pos.x + legendWidth))
|
||||
{
|
||||
//draw_list->AddLine(ImVec2((float)px, canvas_pos.y + (float)tiretStart), ImVec2((float)px, canvas_pos.y + (float)tiretEnd - 1), 0xFF606060, 1);
|
||||
|
||||
draw_list->AddLine(ImVec2(float(px), float(tiretStart)), ImVec2(float(px), float(tiretEnd)), 0x30606060, 1);
|
||||
}
|
||||
};
|
||||
for (int i = sequence->GetFrameMin(); i <= sequence->GetFrameMax(); i += frameStep)
|
||||
{
|
||||
drawLine(i, ItemHeight);
|
||||
}
|
||||
drawLine(sequence->GetFrameMin(), ItemHeight);
|
||||
drawLine(sequence->GetFrameMax(), ItemHeight);
|
||||
/*
|
||||
draw_list->AddLine(canvas_pos, ImVec2(canvas_pos.x, canvas_pos.y + controlHeight), 0xFF000000, 1);
|
||||
draw_list->AddLine(ImVec2(canvas_pos.x, canvas_pos.y + ItemHeight), ImVec2(canvas_size.x, canvas_pos.y + ItemHeight), 0xFF000000, 1);
|
||||
*/
|
||||
// clip content
|
||||
|
||||
draw_list->PushClipRect(childFramePos, childFramePos + childFrameSize, true);
|
||||
|
||||
// draw item names in the legend rect on the left
|
||||
size_t customHeight = 0;
|
||||
for (int i = 0; i < sequenceCount; i++)
|
||||
{
|
||||
int type;
|
||||
sequence->Get(i, NULL, NULL, &type, NULL);
|
||||
ImVec2 tpos(contentMin.x + 3, contentMin.y + i * ItemHeight + 2 + customHeight);
|
||||
draw_list->AddText(tpos, 0xFFFFFFFF, sequence->GetItemLabel(i));
|
||||
|
||||
if (sequenceOptions & SEQUENCER_DEL)
|
||||
{
|
||||
if (SequencerAddDelButton(draw_list, ImVec2(contentMin.x + legendWidth - ItemHeight + 2 - 10, tpos.y + 2), false))
|
||||
delEntry = i;
|
||||
|
||||
if (SequencerAddDelButton(draw_list, ImVec2(contentMin.x + legendWidth - ItemHeight - ItemHeight + 2 - 10, tpos.y + 2), true))
|
||||
dupEntry = i;
|
||||
}
|
||||
customHeight += sequence->GetCustomHeight(i);
|
||||
}
|
||||
|
||||
// slots background
|
||||
customHeight = 0;
|
||||
for (int i = 0; i < sequenceCount; i++)
|
||||
{
|
||||
unsigned int col = (i & 1) ? 0xFF3A3636 : 0xFF413D3D;
|
||||
|
||||
size_t localCustomHeight = sequence->GetCustomHeight(i);
|
||||
ImVec2 pos = ImVec2(contentMin.x + legendWidth, contentMin.y + ItemHeight * i + 1 + customHeight);
|
||||
ImVec2 sz = ImVec2(canvas_size.x + canvas_pos.x, pos.y + ItemHeight - 1 + localCustomHeight);
|
||||
if (!popupOpened && cy >= pos.y && cy < pos.y + (ItemHeight + localCustomHeight) && movingEntry == -1 && cx>contentMin.x && cx < contentMin.x + canvas_size.x)
|
||||
{
|
||||
col += 0x80201008;
|
||||
pos.x -= legendWidth;
|
||||
}
|
||||
draw_list->AddRectFilled(pos, sz, col, 0);
|
||||
customHeight += localCustomHeight;
|
||||
}
|
||||
|
||||
draw_list->PushClipRect(childFramePos + ImVec2(float(legendWidth), 0.f), childFramePos + childFrameSize, true);
|
||||
|
||||
// vertical frame lines in content area
|
||||
for (int i = sequence->GetFrameMin(); i <= sequence->GetFrameMax(); i += frameStep)
|
||||
{
|
||||
drawLineContent(i, int(contentHeight));
|
||||
}
|
||||
drawLineContent(sequence->GetFrameMin(), int(contentHeight));
|
||||
drawLineContent(sequence->GetFrameMax(), int(contentHeight));
|
||||
|
||||
// selection
|
||||
bool selected = selectedEntry && (*selectedEntry >= 0);
|
||||
if (selected)
|
||||
{
|
||||
customHeight = 0;
|
||||
for (int i = 0; i < *selectedEntry; i++)
|
||||
customHeight += sequence->GetCustomHeight(i);
|
||||
draw_list->AddRectFilled(ImVec2(contentMin.x, contentMin.y + ItemHeight * *selectedEntry + customHeight), ImVec2(contentMin.x + canvas_size.x, contentMin.y + ItemHeight * (*selectedEntry + 1) + customHeight), 0x801080FF, 1.f);
|
||||
}
|
||||
|
||||
// slots
|
||||
customHeight = 0;
|
||||
for (int i = 0; i < sequenceCount; i++)
|
||||
{
|
||||
int* start, * end;
|
||||
unsigned int color;
|
||||
sequence->Get(i, &start, &end, NULL, &color);
|
||||
size_t localCustomHeight = sequence->GetCustomHeight(i);
|
||||
|
||||
ImVec2 pos = ImVec2(contentMin.x + legendWidth - firstFrameUsed * framePixelWidth, contentMin.y + ItemHeight * i + 1 + customHeight);
|
||||
ImVec2 slotP1(pos.x + *start * framePixelWidth, pos.y + 2);
|
||||
ImVec2 slotP2(pos.x + *end * framePixelWidth + framePixelWidth, pos.y + ItemHeight - 2);
|
||||
ImVec2 slotP3(pos.x + *end * framePixelWidth + framePixelWidth, pos.y + ItemHeight - 2 + localCustomHeight);
|
||||
unsigned int slotColor = color | 0xFF000000;
|
||||
unsigned int slotColorHalf = (color & 0xFFFFFF) | 0x40000000;
|
||||
|
||||
if (slotP1.x <= (canvas_size.x + contentMin.x) && slotP2.x >= (contentMin.x + legendWidth))
|
||||
{
|
||||
draw_list->AddRectFilled(slotP1, slotP3, slotColorHalf, 2);
|
||||
draw_list->AddRectFilled(slotP1, slotP2, slotColor, 2);
|
||||
}
|
||||
if (ImRect(slotP1, slotP2).Contains(io.MousePos) && io.MouseDoubleClicked[0])
|
||||
{
|
||||
sequence->DoubleClick(i);
|
||||
}
|
||||
// Ensure grabbable handles
|
||||
const float max_handle_width = slotP2.x - slotP1.x / 3.0f;
|
||||
const float min_handle_width = ImMin(10.0f, max_handle_width);
|
||||
const float handle_width = ImClamp(framePixelWidth / 2.0f, min_handle_width, max_handle_width);
|
||||
ImRect rects[3] = { ImRect(slotP1, ImVec2(slotP1.x + handle_width, slotP2.y))
|
||||
, ImRect(ImVec2(slotP2.x - handle_width, slotP1.y), slotP2)
|
||||
, ImRect(slotP1, slotP2) };
|
||||
|
||||
const unsigned int quadColor[] = { 0xFFFFFFFF, 0xFFFFFFFF, slotColor + (selected ? 0 : 0x202020) };
|
||||
if (movingEntry == -1 && (sequenceOptions & SEQUENCER_EDIT_STARTEND))// TODOFOCUS && backgroundRect.Contains(io.MousePos))
|
||||
{
|
||||
for (int j = 2; j >= 0; j--)
|
||||
{
|
||||
ImRect& rc = rects[j];
|
||||
if (!rc.Contains(io.MousePos))
|
||||
continue;
|
||||
draw_list->AddRectFilled(rc.Min, rc.Max, quadColor[j], 2);
|
||||
}
|
||||
|
||||
for (int j = 0; j < 3; j++)
|
||||
{
|
||||
ImRect& rc = rects[j];
|
||||
if (!rc.Contains(io.MousePos))
|
||||
continue;
|
||||
if (!ImRect(childFramePos, childFramePos + childFrameSize).Contains(io.MousePos))
|
||||
continue;
|
||||
if (ImGui::IsMouseClicked(0) && !MovingScrollBar && !MovingCurrentFrame)
|
||||
{
|
||||
movingEntry = i;
|
||||
movingPos = cx;
|
||||
movingPart = j + 1;
|
||||
sequence->BeginEdit(movingEntry);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// custom draw
|
||||
if (localCustomHeight > 0)
|
||||
{
|
||||
ImVec2 rp(canvas_pos.x, contentMin.y + ItemHeight * i + 1 + customHeight);
|
||||
ImRect customRect(rp + ImVec2(legendWidth - (firstFrameUsed - sequence->GetFrameMin() - 0.5f) * framePixelWidth, float(ItemHeight)),
|
||||
rp + ImVec2(legendWidth + (sequence->GetFrameMax() - firstFrameUsed - 0.5f + 2.f) * framePixelWidth, float(localCustomHeight + ItemHeight)));
|
||||
ImRect clippingRect(rp + ImVec2(float(legendWidth), float(ItemHeight)), rp + ImVec2(canvas_size.x, float(localCustomHeight + ItemHeight)));
|
||||
|
||||
ImRect legendRect(rp + ImVec2(0.f, float(ItemHeight)), rp + ImVec2(float(legendWidth), float(localCustomHeight)));
|
||||
ImRect legendClippingRect(canvas_pos + ImVec2(0.f, float(ItemHeight)), canvas_pos + ImVec2(float(legendWidth), float(localCustomHeight + ItemHeight)));
|
||||
customDraws.push_back({ i, customRect, legendRect, clippingRect, legendClippingRect });
|
||||
}
|
||||
else
|
||||
{
|
||||
ImVec2 rp(canvas_pos.x, contentMin.y + ItemHeight * i + customHeight);
|
||||
ImRect customRect(rp + ImVec2(legendWidth - (firstFrameUsed - sequence->GetFrameMin() - 0.5f) * framePixelWidth, float(0.f)),
|
||||
rp + ImVec2(legendWidth + (sequence->GetFrameMax() - firstFrameUsed - 0.5f + 2.f) * framePixelWidth, float(ItemHeight)));
|
||||
ImRect clippingRect(rp + ImVec2(float(legendWidth), float(0.f)), rp + ImVec2(canvas_size.x, float(ItemHeight)));
|
||||
|
||||
compactCustomDraws.push_back({ i, customRect, ImRect(), clippingRect, ImRect() });
|
||||
}
|
||||
customHeight += localCustomHeight;
|
||||
}
|
||||
|
||||
|
||||
// moving
|
||||
if (/*backgroundRect.Contains(io.MousePos) && */movingEntry >= 0)
|
||||
{
|
||||
#if IMGUI_VERSION_NUM >= 18723
|
||||
ImGui::SetNextFrameWantCaptureMouse(true);
|
||||
#else
|
||||
ImGui::CaptureMouseFromApp();
|
||||
#endif
|
||||
int diffFrame = int((cx - movingPos) / framePixelWidth);
|
||||
if (std::abs(diffFrame) > 0)
|
||||
{
|
||||
int* start, * end;
|
||||
sequence->Get(movingEntry, &start, &end, NULL, NULL);
|
||||
if (selectedEntry)
|
||||
*selectedEntry = movingEntry;
|
||||
int& l = *start;
|
||||
int& r = *end;
|
||||
if (movingPart & 1)
|
||||
l += diffFrame;
|
||||
if (movingPart & 2)
|
||||
r += diffFrame;
|
||||
if (l < 0)
|
||||
{
|
||||
if (movingPart & 2)
|
||||
r -= l;
|
||||
l = 0;
|
||||
}
|
||||
if (movingPart & 1 && l > r)
|
||||
l = r;
|
||||
if (movingPart & 2 && r < l)
|
||||
r = l;
|
||||
movingPos += int(diffFrame * framePixelWidth);
|
||||
}
|
||||
if (!io.MouseDown[0])
|
||||
{
|
||||
// single select
|
||||
if (!diffFrame && movingPart && selectedEntry)
|
||||
{
|
||||
*selectedEntry = movingEntry;
|
||||
ret = true;
|
||||
}
|
||||
|
||||
movingEntry = -1;
|
||||
sequence->EndEdit();
|
||||
}
|
||||
}
|
||||
|
||||
// cursor
|
||||
if (currentFrame && firstFrame && *currentFrame >= *firstFrame && *currentFrame <= sequence->GetFrameMax())
|
||||
{
|
||||
static const float cursorWidth = 8.f;
|
||||
float cursorOffset = contentMin.x + legendWidth + (*currentFrame - firstFrameUsed) * framePixelWidth + framePixelWidth / 2 - cursorWidth * 0.5f;
|
||||
draw_list->AddLine(ImVec2(cursorOffset, canvas_pos.y), ImVec2(cursorOffset, contentMax.y), 0xA02A2AFF, cursorWidth);
|
||||
char tmps[512];
|
||||
ImFormatString(tmps, IM_ARRAYSIZE(tmps), "%d", *currentFrame);
|
||||
draw_list->AddText(ImVec2(cursorOffset + 10, canvas_pos.y + 2), 0xFF2A2AFF, tmps);
|
||||
}
|
||||
|
||||
draw_list->PopClipRect();
|
||||
draw_list->PopClipRect();
|
||||
|
||||
for (auto& customDraw : customDraws)
|
||||
sequence->CustomDraw(customDraw.index, draw_list, customDraw.customRect, customDraw.legendRect, customDraw.clippingRect, customDraw.legendClippingRect);
|
||||
for (auto& customDraw : compactCustomDraws)
|
||||
sequence->CustomDrawCompact(customDraw.index, draw_list, customDraw.customRect, customDraw.clippingRect);
|
||||
|
||||
// copy paste
|
||||
if (sequenceOptions & SEQUENCER_COPYPASTE)
|
||||
{
|
||||
ImRect rectCopy(ImVec2(contentMin.x + 100, canvas_pos.y + 2)
|
||||
, ImVec2(contentMin.x + 100 + 30, canvas_pos.y + ItemHeight - 2));
|
||||
bool inRectCopy = rectCopy.Contains(io.MousePos);
|
||||
unsigned int copyColor = inRectCopy ? 0xFF1080FF : 0xFF000000;
|
||||
draw_list->AddText(rectCopy.Min, copyColor, "Copy");
|
||||
|
||||
ImRect rectPaste(ImVec2(contentMin.x + 140, canvas_pos.y + 2)
|
||||
, ImVec2(contentMin.x + 140 + 30, canvas_pos.y + ItemHeight - 2));
|
||||
bool inRectPaste = rectPaste.Contains(io.MousePos);
|
||||
unsigned int pasteColor = inRectPaste ? 0xFF1080FF : 0xFF000000;
|
||||
draw_list->AddText(rectPaste.Min, pasteColor, "Paste");
|
||||
|
||||
if (inRectCopy && io.MouseReleased[0])
|
||||
{
|
||||
sequence->Copy();
|
||||
}
|
||||
if (inRectPaste && io.MouseReleased[0])
|
||||
{
|
||||
sequence->Paste();
|
||||
}
|
||||
}
|
||||
//
|
||||
|
||||
ImGui::EndChild();
|
||||
ImGui::PopStyleColor();
|
||||
if (hasScrollBar)
|
||||
{
|
||||
ImGui::InvisibleButton("scrollBar", scrollBarSize);
|
||||
ImVec2 scrollBarMin = ImGui::GetItemRectMin();
|
||||
ImVec2 scrollBarMax = ImGui::GetItemRectMax();
|
||||
|
||||
// ratio = number of frames visible in control / number to total frames
|
||||
|
||||
float startFrameOffset = ((float)(firstFrameUsed - sequence->GetFrameMin()) / (float)frameCount) * (canvas_size.x - legendWidth);
|
||||
ImVec2 scrollBarA(scrollBarMin.x + legendWidth, scrollBarMin.y - 2);
|
||||
ImVec2 scrollBarB(scrollBarMin.x + canvas_size.x, scrollBarMax.y - 1);
|
||||
draw_list->AddRectFilled(scrollBarA, scrollBarB, 0xFF222222, 0);
|
||||
|
||||
ImRect scrollBarRect(scrollBarA, scrollBarB);
|
||||
bool inScrollBar = scrollBarRect.Contains(io.MousePos);
|
||||
|
||||
draw_list->AddRectFilled(scrollBarA, scrollBarB, 0xFF101010, 8);
|
||||
|
||||
|
||||
ImVec2 scrollBarC(scrollBarMin.x + legendWidth + startFrameOffset, scrollBarMin.y);
|
||||
ImVec2 scrollBarD(scrollBarMin.x + legendWidth + barWidthInPixels + startFrameOffset, scrollBarMax.y - 2);
|
||||
draw_list->AddRectFilled(scrollBarC, scrollBarD, (inScrollBar || MovingScrollBar) ? 0xFF606060 : 0xFF505050, 6);
|
||||
|
||||
ImRect barHandleLeft(scrollBarC, ImVec2(scrollBarC.x + 14, scrollBarD.y));
|
||||
ImRect barHandleRight(ImVec2(scrollBarD.x - 14, scrollBarC.y), scrollBarD);
|
||||
|
||||
bool onLeft = barHandleLeft.Contains(io.MousePos);
|
||||
bool onRight = barHandleRight.Contains(io.MousePos);
|
||||
|
||||
static bool sizingRBar = false;
|
||||
static bool sizingLBar = false;
|
||||
|
||||
draw_list->AddRectFilled(barHandleLeft.Min, barHandleLeft.Max, (onLeft || sizingLBar) ? 0xFFAAAAAA : 0xFF666666, 6);
|
||||
draw_list->AddRectFilled(barHandleRight.Min, barHandleRight.Max, (onRight || sizingRBar) ? 0xFFAAAAAA : 0xFF666666, 6);
|
||||
|
||||
ImRect scrollBarThumb(scrollBarC, scrollBarD);
|
||||
static const float MinBarWidth = 44.f;
|
||||
if (sizingRBar)
|
||||
{
|
||||
if (!io.MouseDown[0])
|
||||
{
|
||||
sizingRBar = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
float barNewWidth = ImMax(barWidthInPixels + io.MouseDelta.x, MinBarWidth);
|
||||
float barRatio = barNewWidth / barWidthInPixels;
|
||||
framePixelWidthTarget = framePixelWidth = framePixelWidth / barRatio;
|
||||
int newVisibleFrameCount = int((canvas_size.x - legendWidth) / framePixelWidthTarget);
|
||||
int lastFrame = *firstFrame + newVisibleFrameCount;
|
||||
if (lastFrame > sequence->GetFrameMax())
|
||||
{
|
||||
framePixelWidthTarget = framePixelWidth = (canvas_size.x - legendWidth) / float(sequence->GetFrameMax() - *firstFrame);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (sizingLBar)
|
||||
{
|
||||
if (!io.MouseDown[0])
|
||||
{
|
||||
sizingLBar = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (fabsf(io.MouseDelta.x) > FLT_EPSILON)
|
||||
{
|
||||
float barNewWidth = ImMax(barWidthInPixels - io.MouseDelta.x, MinBarWidth);
|
||||
float barRatio = barNewWidth / barWidthInPixels;
|
||||
float previousFramePixelWidthTarget = framePixelWidthTarget;
|
||||
framePixelWidthTarget = framePixelWidth = framePixelWidth / barRatio;
|
||||
int newVisibleFrameCount = int(visibleFrameCount / barRatio);
|
||||
int newFirstFrame = *firstFrame + newVisibleFrameCount - visibleFrameCount;
|
||||
newFirstFrame = ImClamp(newFirstFrame, sequence->GetFrameMin(), ImMax(sequence->GetFrameMax() - visibleFrameCount, sequence->GetFrameMin()));
|
||||
if (newFirstFrame == *firstFrame)
|
||||
{
|
||||
framePixelWidth = framePixelWidthTarget = previousFramePixelWidthTarget;
|
||||
}
|
||||
else
|
||||
{
|
||||
*firstFrame = newFirstFrame;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (MovingScrollBar)
|
||||
{
|
||||
if (!io.MouseDown[0])
|
||||
{
|
||||
MovingScrollBar = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
float framesPerPixelInBar = barWidthInPixels / (float)visibleFrameCount;
|
||||
*firstFrame = int((io.MousePos.x - panningViewSource.x) / framesPerPixelInBar) - panningViewFrame;
|
||||
*firstFrame = ImClamp(*firstFrame, sequence->GetFrameMin(), ImMax(sequence->GetFrameMax() - visibleFrameCount, sequence->GetFrameMin()));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (scrollBarThumb.Contains(io.MousePos) && ImGui::IsMouseClicked(0) && firstFrame && !MovingCurrentFrame && movingEntry == -1)
|
||||
{
|
||||
MovingScrollBar = true;
|
||||
panningViewSource = io.MousePos;
|
||||
panningViewFrame = -*firstFrame;
|
||||
}
|
||||
if (!sizingRBar && onRight && ImGui::IsMouseClicked(0))
|
||||
sizingRBar = true;
|
||||
if (!sizingLBar && onLeft && ImGui::IsMouseClicked(0))
|
||||
sizingLBar = true;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ImGui::EndGroup();
|
||||
|
||||
if (regionRect.Contains(io.MousePos))
|
||||
{
|
||||
bool overCustomDraw = false;
|
||||
for (auto& custom : customDraws)
|
||||
{
|
||||
if (custom.customRect.Contains(io.MousePos))
|
||||
{
|
||||
overCustomDraw = true;
|
||||
}
|
||||
}
|
||||
if (overCustomDraw)
|
||||
{
|
||||
}
|
||||
else
|
||||
{
|
||||
#if 0
|
||||
frameOverCursor = *firstFrame + (int)(visibleFrameCount * ((io.MousePos.x - (float)legendWidth - canvas_pos.x) / (canvas_size.x - legendWidth)));
|
||||
//frameOverCursor = max(min(*firstFrame - visibleFrameCount / 2, frameCount - visibleFrameCount), 0);
|
||||
|
||||
/**firstFrame -= frameOverCursor;
|
||||
*firstFrame *= framePixelWidthTarget / framePixelWidth;
|
||||
*firstFrame += frameOverCursor;*/
|
||||
if (io.MouseWheel < -FLT_EPSILON)
|
||||
{
|
||||
*firstFrame -= frameOverCursor;
|
||||
*firstFrame = int(*firstFrame * 1.1f);
|
||||
framePixelWidthTarget *= 0.9f;
|
||||
*firstFrame += frameOverCursor;
|
||||
}
|
||||
|
||||
if (io.MouseWheel > FLT_EPSILON)
|
||||
{
|
||||
*firstFrame -= frameOverCursor;
|
||||
*firstFrame = int(*firstFrame * 0.9f);
|
||||
framePixelWidthTarget *= 1.1f;
|
||||
*firstFrame += frameOverCursor;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
if (expanded)
|
||||
{
|
||||
if (SequencerAddDelButton(draw_list, ImVec2(canvas_pos.x + 2, canvas_pos.y + 2), !*expanded))
|
||||
*expanded = !*expanded;
|
||||
}
|
||||
|
||||
if (delEntry != -1)
|
||||
{
|
||||
sequence->Del(delEntry);
|
||||
if (selectedEntry && (*selectedEntry == delEntry || *selectedEntry >= sequence->GetItemCount()))
|
||||
*selectedEntry = -1;
|
||||
}
|
||||
|
||||
if (dupEntry != -1)
|
||||
{
|
||||
sequence->Duplicate(dupEntry);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
79
src/ThirdParty/ImGuizmo/ImSequencer.h
vendored
Normal file
79
src/ThirdParty/ImGuizmo/ImSequencer.h
vendored
Normal file
@@ -0,0 +1,79 @@
|
||||
// https://github.com/CedricGuillemet/ImGuizmo
|
||||
// v1.92.5 WIP
|
||||
//
|
||||
// The MIT License(MIT)
|
||||
//
|
||||
// Copyright(c) 2016-2021 Cedric Guillemet
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files(the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and / or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions :
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in all
|
||||
// copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
// SOFTWARE.
|
||||
//
|
||||
#pragma once
|
||||
|
||||
#include <cstddef>
|
||||
|
||||
struct ImDrawList;
|
||||
struct ImRect;
|
||||
namespace ImSequencer
|
||||
{
|
||||
enum SEQUENCER_OPTIONS
|
||||
{
|
||||
SEQUENCER_EDIT_NONE = 0,
|
||||
SEQUENCER_EDIT_STARTEND = 1 << 1,
|
||||
SEQUENCER_CHANGE_FRAME = 1 << 3,
|
||||
SEQUENCER_ADD = 1 << 4,
|
||||
SEQUENCER_DEL = 1 << 5,
|
||||
SEQUENCER_COPYPASTE = 1 << 6,
|
||||
SEQUENCER_EDIT_ALL = SEQUENCER_EDIT_STARTEND | SEQUENCER_CHANGE_FRAME
|
||||
};
|
||||
|
||||
struct SequenceInterface
|
||||
{
|
||||
bool focused = false;
|
||||
virtual int GetFrameMin() const = 0;
|
||||
virtual int GetFrameMax() const = 0;
|
||||
virtual int GetItemCount() const = 0;
|
||||
|
||||
virtual void BeginEdit(int /*index*/) {}
|
||||
virtual void EndEdit() {}
|
||||
virtual int GetItemTypeCount() const { return 0; }
|
||||
virtual const char* GetItemTypeName(int /*typeIndex*/) const { return ""; }
|
||||
virtual const char* GetItemLabel(int /*index*/) const { return ""; }
|
||||
virtual const char* GetCollapseFmt() const { return "%d Frames / %d entries"; }
|
||||
|
||||
virtual void Get(int index, int** start, int** end, int* type, unsigned int* color) = 0;
|
||||
virtual void Add(int /*type*/) {}
|
||||
virtual void Del(int /*index*/) {}
|
||||
virtual void Duplicate(int /*index*/) {}
|
||||
|
||||
virtual void Copy() {}
|
||||
virtual void Paste() {}
|
||||
|
||||
virtual size_t GetCustomHeight(int /*index*/) { return 0; }
|
||||
virtual void DoubleClick(int /*index*/) {}
|
||||
virtual void CustomDraw(int /*index*/, ImDrawList* /*draw_list*/, const ImRect& /*rc*/, const ImRect& /*legendRect*/, const ImRect& /*clippingRect*/, const ImRect& /*legendClippingRect*/) {}
|
||||
virtual void CustomDrawCompact(int /*index*/, ImDrawList* /*draw_list*/, const ImRect& /*rc*/, const ImRect& /*clippingRect*/) {}
|
||||
|
||||
virtual ~SequenceInterface() = default;
|
||||
};
|
||||
|
||||
|
||||
// return true if selection is made
|
||||
bool Sequencer(SequenceInterface* sequence, int* currentFrame, bool* expanded, int* selectedEntry, int* firstFrame, int sequenceOptions);
|
||||
|
||||
}
|
||||
245
src/ThirdParty/ImGuizmo/ImZoomSlider.h
vendored
Normal file
245
src/ThirdParty/ImGuizmo/ImZoomSlider.h
vendored
Normal file
@@ -0,0 +1,245 @@
|
||||
// https://github.com/CedricGuillemet/ImGuizmo
|
||||
// v1.92.5 WIP
|
||||
//
|
||||
// The MIT License(MIT)
|
||||
//
|
||||
// Copyright(c) 2016-2021 Cedric Guillemet
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files(the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and / or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions :
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in all
|
||||
// copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
// SOFTWARE.
|
||||
//
|
||||
#pragma once
|
||||
|
||||
namespace ImZoomSlider
|
||||
{
|
||||
typedef int ImGuiZoomSliderFlags;
|
||||
enum ImGuiPopupFlags_
|
||||
{
|
||||
ImGuiZoomSliderFlags_None = 0,
|
||||
ImGuiZoomSliderFlags_Vertical = 1,
|
||||
ImGuiZoomSliderFlags_NoAnchors = 2,
|
||||
ImGuiZoomSliderFlags_NoMiddleCarets = 4,
|
||||
ImGuiZoomSliderFlags_NoWheel = 8,
|
||||
};
|
||||
|
||||
template<typename T> bool ImZoomSlider(const T lower, const T higher, T& viewLower, T& viewHigher, float wheelRatio = 0.01f, ImGuiZoomSliderFlags flags = ImGuiZoomSliderFlags_None)
|
||||
{
|
||||
bool interacted = false;
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
ImDrawList* draw_list = ImGui::GetWindowDrawList();
|
||||
|
||||
static const float handleSize = 12;
|
||||
static const float roundRadius = 3.f;
|
||||
static const char* controlName = "ImZoomSlider";
|
||||
|
||||
static bool movingScrollBarSvg = false;
|
||||
static bool sizingRBarSvg = false;
|
||||
static bool sizingLBarSvg = false;
|
||||
static ImGuiID editingId = (ImGuiID)-1;
|
||||
static float scrollingSource = 0.f;
|
||||
static float saveViewLower;
|
||||
static float saveViewHigher;
|
||||
|
||||
const bool isVertical = flags & ImGuiZoomSliderFlags_Vertical;
|
||||
const ImVec2 canvasPos = ImGui::GetCursorScreenPos();
|
||||
const ImVec2 canvasSize = ImGui::GetContentRegionAvail();
|
||||
const float canvasSizeLength = isVertical ? ImGui::GetItemRectSize().y : canvasSize.x;
|
||||
const ImVec2 scrollBarSize = isVertical ? ImVec2(14.f, canvasSizeLength) : ImVec2(canvasSizeLength, 14.f);
|
||||
|
||||
ImGui::InvisibleButton(controlName, scrollBarSize);
|
||||
const ImGuiID currentId = ImGui::GetID(controlName);
|
||||
|
||||
const bool usingEditingId = currentId == editingId;
|
||||
const bool canUseControl = usingEditingId || editingId == -1;
|
||||
const bool movingScrollBar = usingEditingId ? movingScrollBarSvg : false;
|
||||
const bool sizingRBar = usingEditingId ? sizingRBarSvg : false;
|
||||
const bool sizingLBar = usingEditingId ? sizingLBarSvg : false;
|
||||
const int componentIndex = isVertical ? 1 : 0;
|
||||
const ImVec2 scrollBarMin = ImGui::GetItemRectMin();
|
||||
const ImVec2 scrollBarMax = ImGui::GetItemRectMax();
|
||||
const ImVec2 scrollBarA = ImVec2(scrollBarMin.x, scrollBarMin.y) - (isVertical ? ImVec2(2,0) : ImVec2(0,2));
|
||||
const ImVec2 scrollBarB = isVertical ? ImVec2(scrollBarMax.x - 1.f, scrollBarMin.y + canvasSizeLength) : ImVec2(scrollBarMin.x + canvasSizeLength, scrollBarMax.y - 1.f);
|
||||
const float scrollStart = ((viewLower - lower) / (higher - lower)) * canvasSizeLength + scrollBarMin[componentIndex];
|
||||
const float scrollEnd = ((viewHigher - lower) / (higher - lower)) * canvasSizeLength + scrollBarMin[componentIndex];
|
||||
const float screenSize = scrollEnd - scrollStart;
|
||||
const ImVec2 scrollTopLeft = isVertical ? ImVec2(scrollBarMin.x, scrollStart) : ImVec2(scrollStart, scrollBarMin.y);
|
||||
const ImVec2 scrollBottomRight = isVertical ? ImVec2(scrollBarMax.x - 2.f, scrollEnd) : ImVec2(scrollEnd, scrollBarMax.y - 2.f);
|
||||
const bool inScrollBar = canUseControl && ImRect(scrollTopLeft, scrollBottomRight).Contains(io.MousePos);
|
||||
const ImRect scrollBarRect(scrollBarA, scrollBarB);
|
||||
const float deltaScreen = io.MousePos[componentIndex] - scrollingSource;
|
||||
const float deltaView = ((higher - lower) / canvasSizeLength) * deltaScreen;
|
||||
const uint32_t barColor = ImGui::GetColorU32((inScrollBar || movingScrollBar) ? ImGuiCol_FrameBgHovered : ImGuiCol_FrameBg);
|
||||
const float middleCoord = (scrollStart + scrollEnd) * 0.5f;
|
||||
const bool insideControl = canUseControl && ImRect(scrollBarMin, scrollBarMax).Contains(io.MousePos);
|
||||
const bool hasAnchors = !(flags & ImGuiZoomSliderFlags_NoAnchors);
|
||||
const float viewMinSize = ((3.f * handleSize) / canvasSizeLength) * (higher - lower);
|
||||
const auto ClipView = [lower, higher, &viewLower, &viewHigher]() {
|
||||
if (viewLower < lower)
|
||||
{
|
||||
const float deltaClip = lower - viewLower;
|
||||
viewLower += deltaClip;
|
||||
viewHigher += deltaClip;
|
||||
}
|
||||
if (viewHigher > higher)
|
||||
{
|
||||
const float deltaClip = viewHigher - higher;
|
||||
viewLower -= deltaClip;
|
||||
viewHigher -= deltaClip;
|
||||
}
|
||||
};
|
||||
|
||||
bool onLeft = false;
|
||||
bool onRight = false;
|
||||
|
||||
draw_list->AddRectFilled(scrollBarA, scrollBarB, 0xFF101010, roundRadius);
|
||||
draw_list->AddRectFilled(scrollBarA, scrollBarB, 0xFF222222, 0);
|
||||
draw_list->AddRectFilled(scrollTopLeft, scrollBottomRight, barColor, roundRadius);
|
||||
|
||||
if (!(flags & ImGuiZoomSliderFlags_NoMiddleCarets))
|
||||
{
|
||||
for (float i = 0.5f; i < 3.f; i += 1.f)
|
||||
{
|
||||
const float coordA = middleCoord - handleSize * 0.5f;
|
||||
const float coordB = middleCoord + handleSize * 0.5f;
|
||||
ImVec2 base = scrollBarMin;
|
||||
base.x += scrollBarSize.x * 0.25f * i;
|
||||
base.y += scrollBarSize.y * 0.25f * i;
|
||||
|
||||
if (isVertical)
|
||||
{
|
||||
draw_list->AddLine(ImVec2(base.x, coordA), ImVec2(base.x, coordB), ImGui::GetColorU32(ImGuiCol_SliderGrab));
|
||||
}
|
||||
else
|
||||
{
|
||||
draw_list->AddLine(ImVec2(coordA, base.y), ImVec2(coordB, base.y), ImGui::GetColorU32(ImGuiCol_SliderGrab));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Mouse wheel
|
||||
if (io.MouseClicked[0] && insideControl && !inScrollBar)
|
||||
{
|
||||
const float ratio = (io.MousePos[componentIndex] - scrollBarMin[componentIndex]) / (scrollBarMax[componentIndex] - scrollBarMin[componentIndex]);
|
||||
const float size = (higher - lower);
|
||||
const float halfViewSize = (viewHigher - viewLower) * 0.5f;
|
||||
const float middle = ratio * size + lower;
|
||||
viewLower = middle - halfViewSize;
|
||||
viewHigher = middle + halfViewSize;
|
||||
ClipView();
|
||||
interacted = true;
|
||||
}
|
||||
|
||||
if (!(flags & ImGuiZoomSliderFlags_NoWheel) && inScrollBar && fabsf(io.MouseWheel) > 0.f)
|
||||
{
|
||||
const float ratio = (io.MousePos[componentIndex] - scrollStart) / (scrollEnd - scrollStart);
|
||||
const float amount = io.MouseWheel * wheelRatio * (viewHigher - viewLower);
|
||||
|
||||
viewLower -= ratio * amount;
|
||||
viewHigher += (1.f - ratio) * amount;
|
||||
ClipView();
|
||||
interacted = true;
|
||||
}
|
||||
|
||||
if (screenSize > handleSize * 2.f && hasAnchors)
|
||||
{
|
||||
const ImRect barHandleLeft(scrollTopLeft, isVertical ? ImVec2(scrollBottomRight.x, scrollTopLeft.y + handleSize) : ImVec2(scrollTopLeft.x + handleSize, scrollBottomRight.y));
|
||||
const ImRect barHandleRight(isVertical ? ImVec2(scrollTopLeft.x, scrollBottomRight.y - handleSize) : ImVec2(scrollBottomRight.x - handleSize, scrollTopLeft.y), scrollBottomRight);
|
||||
|
||||
onLeft = barHandleLeft.Contains(io.MousePos);
|
||||
onRight = barHandleRight.Contains(io.MousePos);
|
||||
|
||||
draw_list->AddRectFilled(barHandleLeft.Min, barHandleLeft.Max, ImGui::GetColorU32((onLeft || sizingLBar) ? ImGuiCol_SliderGrabActive : ImGuiCol_SliderGrab), roundRadius);
|
||||
draw_list->AddRectFilled(barHandleRight.Min, barHandleRight.Max, ImGui::GetColorU32((onRight || sizingRBar) ? ImGuiCol_SliderGrabActive : ImGuiCol_SliderGrab), roundRadius);
|
||||
}
|
||||
|
||||
if (sizingRBar)
|
||||
{
|
||||
if (!io.MouseDown[0])
|
||||
{
|
||||
sizingRBarSvg = false;
|
||||
editingId = (ImGuiID)-1;
|
||||
}
|
||||
else
|
||||
{
|
||||
viewHigher = ImMin(saveViewHigher + deltaView, higher);
|
||||
}
|
||||
}
|
||||
else if (sizingLBar)
|
||||
{
|
||||
if (!io.MouseDown[0])
|
||||
{
|
||||
sizingLBarSvg = false;
|
||||
editingId = (ImGuiID)-1;
|
||||
}
|
||||
else
|
||||
{
|
||||
viewLower = ImMax(saveViewLower + deltaView, lower);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (movingScrollBar)
|
||||
{
|
||||
if (!io.MouseDown[0])
|
||||
{
|
||||
movingScrollBarSvg = false;
|
||||
editingId = (ImGuiID)-1;
|
||||
}
|
||||
else
|
||||
{
|
||||
viewLower = saveViewLower + deltaView;
|
||||
viewHigher = saveViewHigher + deltaView;
|
||||
ClipView();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (inScrollBar && ImGui::IsMouseClicked(0))
|
||||
{
|
||||
movingScrollBarSvg = true;
|
||||
scrollingSource = io.MousePos[componentIndex];
|
||||
saveViewLower = viewLower;
|
||||
saveViewHigher = viewHigher;
|
||||
editingId = currentId;
|
||||
}
|
||||
if (!sizingRBar && onRight && ImGui::IsMouseClicked(0) && hasAnchors)
|
||||
{
|
||||
sizingRBarSvg = true;
|
||||
editingId = currentId;
|
||||
}
|
||||
if (!sizingLBar && onLeft && ImGui::IsMouseClicked(0) && hasAnchors)
|
||||
{
|
||||
sizingLBarSvg = true;
|
||||
editingId = currentId;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// minimal size check
|
||||
if ((viewHigher - viewLower) < viewMinSize)
|
||||
{
|
||||
const float middle = (viewLower + viewHigher) * 0.5f;
|
||||
viewLower = middle - viewMinSize * 0.5f;
|
||||
viewHigher = middle + viewMinSize * 0.5f;
|
||||
ClipView();
|
||||
}
|
||||
|
||||
return movingScrollBar || sizingRBar || sizingLBar || interacted;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
BIN
src/ThirdParty/ImGuizmo/Images/nodeeditor.jpg
vendored
Normal file
BIN
src/ThirdParty/ImGuizmo/Images/nodeeditor.jpg
vendored
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 43 KiB |
21
src/ThirdParty/ImGuizmo/LICENSE
vendored
Normal file
21
src/ThirdParty/ImGuizmo/LICENSE
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2016 Cedric Guillemet
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
19
src/ThirdParty/ImGuizmo/Makefile
vendored
Normal file
19
src/ThirdParty/ImGuizmo/Makefile
vendored
Normal file
@@ -0,0 +1,19 @@
|
||||
CXXFLAGS=-std=c++11
|
||||
CPPFLAGS=-I. -Iexample
|
||||
|
||||
LIB_OBJS = ImGuizmo.o GraphEditor.o ImCurveEdit.o ImGradient.o ImSequencer.o
|
||||
EXAMPLE_OBJS = example/imgui.o example/imgui_draw.o example/imgui_tables.o example/imgui_widgets.o example/main.o
|
||||
|
||||
EXAMPLE_NAME = example.exe
|
||||
LDFLAGS=-mwindows -static-libgcc -static-libstdc++
|
||||
LIBS=-limm32 -lopengl32 -lgdi32
|
||||
|
||||
$(EXAMPLE_NAME): $(LIB_OBJS) $(EXAMPLE_OBJS)
|
||||
$(CXX) $(LDFLAGS) -o $@ $^ $(LIBS)
|
||||
|
||||
example/main.o: CXXFLAGS := -std=c++17
|
||||
|
||||
clean:
|
||||
$(RM) $(LIB_OBJS)
|
||||
$(RM) $(EXAMPLE_OBJS)
|
||||
$(RM) $(EXAMPLE_NAME)
|
||||
194
src/ThirdParty/ImGuizmo/README.md
vendored
Normal file
194
src/ThirdParty/ImGuizmo/README.md
vendored
Normal file
@@ -0,0 +1,194 @@
|
||||
# ImGuizmo
|
||||
|
||||
Latest stable tagged version is 1.83. Current master version is 1.84 WIP.
|
||||
|
||||
What started with the gizmo is now a collection of dear imgui widgets and more advanced controls.
|
||||
|
||||
## Guizmos
|
||||
|
||||
### ImViewGizmo
|
||||
|
||||
Manipulate view orientation with 1 single line of code
|
||||
|
||||

|
||||
|
||||
### ImGuizmo
|
||||
|
||||
ImGuizmo is a small (.h and .cpp) library built ontop of Dear ImGui that allow you to manipulate(Rotate & translate at the moment) 4x4 float matrices. No other dependancies. Coded with Immediate Mode (IM) philosophy in mind.
|
||||
|
||||
Built against DearImgui 1.53WIP
|
||||
|
||||

|
||||

|
||||

|
||||
|
||||
There is now a sample for Win32/OpenGL ! With a binary in bin directory.
|
||||

|
||||
|
||||
### ImSequencer
|
||||
|
||||
A WIP little sequencer used to edit frame start/end for different events in a timeline.
|
||||

|
||||
Check the sample for the documentation. More to come...
|
||||
|
||||
### Graph Editor
|
||||
|
||||
Nodes + connections. Custom draw inside nodes is possible with the delegate system in place.
|
||||

|
||||
|
||||
### API doc
|
||||
|
||||
Call BeginFrame right after ImGui_XXXX_NewFrame();
|
||||
|
||||
```C++
|
||||
void BeginFrame();
|
||||
```
|
||||
|
||||
return true if mouse cursor is over any gizmo control (axis, plan or screen component)
|
||||
|
||||
```C++
|
||||
bool IsOver();**
|
||||
```
|
||||
|
||||
return true if mouse IsOver or if the gizmo is in moving state
|
||||
|
||||
```C++
|
||||
bool IsUsing();**
|
||||
```
|
||||
|
||||
enable/disable the gizmo. Stay in the state until next call to Enable. gizmo is rendered with gray half transparent color when disabled
|
||||
|
||||
```C++
|
||||
void Enable(bool enable);**
|
||||
```
|
||||
|
||||
helper functions for manualy editing translation/rotation/scale with an input float
|
||||
translation, rotation and scale float points to 3 floats each
|
||||
Angles are in degrees (more suitable for human editing)
|
||||
example:
|
||||
|
||||
```C++
|
||||
float matrixTranslation[3], matrixRotation[3], matrixScale[3];
|
||||
ImGuizmo::DecomposeMatrixToComponents(gizmoMatrix.m16, matrixTranslation, matrixRotation, matrixScale);
|
||||
ImGui::InputFloat3("Tr", matrixTranslation, 3);
|
||||
ImGui::InputFloat3("Rt", matrixRotation, 3);
|
||||
ImGui::InputFloat3("Sc", matrixScale, 3);
|
||||
ImGuizmo::RecomposeMatrixFromComponents(matrixTranslation, matrixRotation, matrixScale, gizmoMatrix.m16);
|
||||
```
|
||||
|
||||
These functions have some numerical stability issues for now. Use with caution.
|
||||
|
||||
```C++
|
||||
void DecomposeMatrixToComponents(const float *matrix, float *translation, float *rotation, float *scale);
|
||||
void RecomposeMatrixFromComponents(const float *translation, const float *rotation, const float *scale, float *matrix);**
|
||||
```
|
||||
|
||||
Render a cube with face color corresponding to face normal. Usefull for debug/test
|
||||
|
||||
```C++
|
||||
void DrawCube(const float *view, const float *projection, float *matrix);**
|
||||
```
|
||||
|
||||
Call it when you want a gizmo
|
||||
Needs view and projection matrices.
|
||||
Matrix parameter is the source matrix (where will be gizmo be drawn) and might be transformed by the function. Return deltaMatrix is optional. snap points to a float[3] for translation and to a single float for scale or rotation. Snap angle is in Euler Degrees.
|
||||
|
||||
```C++
|
||||
enum OPERATION
|
||||
{
|
||||
TRANSLATE,
|
||||
ROTATE,
|
||||
SCALE
|
||||
};
|
||||
|
||||
enum MODE
|
||||
{
|
||||
LOCAL,
|
||||
WORLD
|
||||
};
|
||||
|
||||
void Manipulate(const float *view, const float *projection, OPERATION operation, MODE mode, float *matrix, float *deltaMatrix = 0, float *snap = 0);**
|
||||
```
|
||||
|
||||
### ImGui Example
|
||||
|
||||
Code for :
|
||||
|
||||

|
||||
|
||||
```C++
|
||||
void EditTransform(float* cameraView, float* cameraProjection, float* matrix)
|
||||
{
|
||||
static ImGuizmo::OPERATION mCurrentGizmoOperation(ImGuizmo::ROTATE);
|
||||
static ImGuizmo::MODE mCurrentGizmoMode(ImGuizmo::WORLD);
|
||||
if (ImGui::IsKeyPressed(ImGuiKey_T))
|
||||
mCurrentGizmoOperation = ImGuizmo::TRANSLATE;
|
||||
if (ImGui::IsKeyPressed(ImGuiKey_E))
|
||||
mCurrentGizmoOperation = ImGuizmo::ROTATE;
|
||||
if (ImGui::IsKeyPressed(ImGuiKey_R))
|
||||
mCurrentGizmoOperation = ImGuizmo::SCALE;
|
||||
if (ImGui::RadioButton("Translate", mCurrentGizmoOperation == ImGuizmo::TRANSLATE))
|
||||
mCurrentGizmoOperation = ImGuizmo::TRANSLATE;
|
||||
ImGui::SameLine();
|
||||
if (ImGui::RadioButton("Rotate", mCurrentGizmoOperation == ImGuizmo::ROTATE))
|
||||
mCurrentGizmoOperation = ImGuizmo::ROTATE;
|
||||
ImGui::SameLine();
|
||||
if (ImGui::RadioButton("Scale", mCurrentGizmoOperation == ImGuizmo::SCALE))
|
||||
mCurrentGizmoOperation = ImGuizmo::SCALE;
|
||||
float matrixTranslation[3], matrixRotation[3], matrixScale[3];
|
||||
ImGuizmo::DecomposeMatrixToComponents(matrix, matrixTranslation, matrixRotation, matrixScale);
|
||||
ImGui::InputFloat3("Tr", matrixTranslation);
|
||||
ImGui::InputFloat3("Rt", matrixRotation);
|
||||
ImGui::InputFloat3("Sc", matrixScale);
|
||||
ImGuizmo::RecomposeMatrixFromComponents(matrixTranslation, matrixRotation, matrixScale, matrix);
|
||||
|
||||
if (mCurrentGizmoOperation != ImGuizmo::SCALE)
|
||||
{
|
||||
if (ImGui::RadioButton("Local", mCurrentGizmoMode == ImGuizmo::LOCAL))
|
||||
mCurrentGizmoMode = ImGuizmo::LOCAL;
|
||||
ImGui::SameLine();
|
||||
if (ImGui::RadioButton("World", mCurrentGizmoMode == ImGuizmo::WORLD))
|
||||
mCurrentGizmoMode = ImGuizmo::WORLD;
|
||||
}
|
||||
static bool useSnap(false);
|
||||
if (ImGui::IsKeyPressed(ImGuiKey_S))
|
||||
useSnap = !useSnap;
|
||||
ImGui::Checkbox("##useSnap", &useSnap);
|
||||
ImGui::SameLine();
|
||||
vec_t snap;
|
||||
switch (mCurrentGizmoOperation)
|
||||
{
|
||||
case ImGuizmo::TRANSLATE:
|
||||
snap = config.mSnapTranslation;
|
||||
ImGui::InputFloat3("Snap", &snap.x);
|
||||
break;
|
||||
case ImGuizmo::ROTATE:
|
||||
snap = config.mSnapRotation;
|
||||
ImGui::InputFloat("Angle Snap", &snap.x);
|
||||
break;
|
||||
case ImGuizmo::SCALE:
|
||||
snap = config.mSnapScale;
|
||||
ImGui::InputFloat("Scale Snap", &snap.x);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
ImGuizmo::SetRect(0, 0, io.DisplaySize.x, io.DisplaySize.y);
|
||||
ImGuizmo::Manipulate(cameraView, cameraProjection, mCurrentGizmoOperation, mCurrentGizmoMode, matrix, NULL, useSnap ? &snap.x : NULL);
|
||||
}
|
||||
```
|
||||
|
||||
## Install
|
||||
|
||||
ImGuizmo can be installed via [vcpkg](https://github.com/microsoft/vcpkg) and used cmake
|
||||
|
||||
```bash
|
||||
vcpkg install imguizmo
|
||||
```
|
||||
|
||||
See the [vcpkg example](/vcpkg-example) for more details
|
||||
|
||||
## License
|
||||
|
||||
ImGuizmo is licensed under the MIT License, see [LICENSE](/LICENSE) for more information.
|
||||
BIN
src/ThirdParty/ImGuizmo/bin/ImGuizmoSample.exe
vendored
Normal file
BIN
src/ThirdParty/ImGuizmo/bin/ImGuizmoSample.exe
vendored
Normal file
Binary file not shown.
25
src/ThirdParty/ImGuizmo/bin/imgui.ini
vendored
Normal file
25
src/ThirdParty/ImGuizmo/bin/imgui.ini
vendored
Normal file
@@ -0,0 +1,25 @@
|
||||
[Window][Debug##Default]
|
||||
Pos=60,60
|
||||
Size=400,400
|
||||
Collapsed=0
|
||||
|
||||
[Window][Editor]
|
||||
Pos=10,10
|
||||
Size=320,340
|
||||
Collapsed=0
|
||||
|
||||
[Window][Gizmo]
|
||||
Pos=400,20
|
||||
Size=800,400
|
||||
Collapsed=0
|
||||
|
||||
[Window][Graph Editor]
|
||||
Pos=981,294
|
||||
Size=787,580
|
||||
Collapsed=0
|
||||
|
||||
[Window][Other controls]
|
||||
Pos=10,350
|
||||
Size=693,395
|
||||
Collapsed=0
|
||||
|
||||
3755
src/ThirdParty/ImGuizmo/example/ImApp.h
vendored
Normal file
3755
src/ThirdParty/ImGuizmo/example/ImApp.h
vendored
Normal file
File diff suppressed because it is too large
Load Diff
184
src/ThirdParty/ImGuizmo/example/ImGuizmoSample.vcxproj
vendored
Normal file
184
src/ThirdParty/ImGuizmo/example/ImGuizmoSample.vcxproj
vendored
Normal file
@@ -0,0 +1,184 @@
|
||||
<?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>
|
||||
<ProjectConfiguration Include="Debug|x64">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|x64">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<ProjectGuid>{A7359EC9-7DB5-44A1-91A5-38F499DA6D23}</ProjectGuid>
|
||||
<Keyword>Win32Proj</Keyword>
|
||||
<RootNamespace>ImGuizmoSample</RootNamespace>
|
||||
<WindowsTargetPlatformVersion>10.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>v143</PlatformToolset>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v143</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v143</PlatformToolset>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v143</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>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<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|x64'">
|
||||
<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)'=='Debug|x64'">
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<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>..\;.</AdditionalIncludeDirectories>
|
||||
<LanguageStandard>stdcpp17</LanguageStandard>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<PreprocessorDefinitions>_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<AdditionalIncludeDirectories>.\;..\</AdditionalIncludeDirectories>
|
||||
<LanguageStandard>stdcpp17</LanguageStandard>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
</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>..\;.</AdditionalIncludeDirectories>
|
||||
<LanguageStandard>stdcpp17</LanguageStandard>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
<Optimization>MaxSpeed</Optimization>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<PreprocessorDefinitions>NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<AdditionalIncludeDirectories>.\;..\</AdditionalIncludeDirectories>
|
||||
<LanguageStandard>stdcpp17</LanguageStandard>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="..\GraphEditor.h" />
|
||||
<ClInclude Include="..\ImCurveEdit.h" />
|
||||
<ClInclude Include="..\ImGradient.h" />
|
||||
<ClInclude Include="..\ImGuizmo.h" />
|
||||
<ClInclude Include="..\ImSequencer.h" />
|
||||
<ClInclude Include="..\ImZoomSlider.h" />
|
||||
<ClInclude Include="ImApp.h" />
|
||||
<ClInclude Include="imconfig.h" />
|
||||
<ClInclude Include="imgui.h" />
|
||||
<ClInclude Include="imgui_internal.h" />
|
||||
<ClInclude Include="stb_image.h" />
|
||||
<ClInclude Include="stb_rect_pack.h" />
|
||||
<ClInclude Include="stb_textedit.h" />
|
||||
<ClInclude Include="stb_truetype.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="..\GraphEditor.cpp" />
|
||||
<ClCompile Include="..\ImCurveEdit.cpp" />
|
||||
<ClCompile Include="..\ImGradient.cpp" />
|
||||
<ClCompile Include="..\ImGuizmo.cpp" />
|
||||
<ClCompile Include="..\ImSequencer.cpp" />
|
||||
<ClCompile Include="imgui.cpp" />
|
||||
<ClCompile Include="imgui_demo.cpp" />
|
||||
<ClCompile Include="imgui_draw.cpp" />
|
||||
<ClCompile Include="imgui_tables.cpp" />
|
||||
<ClCompile Include="imgui_widgets.cpp" />
|
||||
<ClCompile Include="main.cpp" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
||||
147
src/ThirdParty/ImGuizmo/example/imconfig.h
vendored
Normal file
147
src/ThirdParty/ImGuizmo/example/imconfig.h
vendored
Normal file
@@ -0,0 +1,147 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
// DEAR IMGUI COMPILE-TIME OPTIONS
|
||||
// Runtime options (clipboard callbacks, enabling various features, etc.) can generally be set via the ImGuiIO structure.
|
||||
// You can use ImGui::SetAllocatorFunctions() before calling ImGui::CreateContext() to rewire memory allocation functions.
|
||||
//-----------------------------------------------------------------------------
|
||||
// A) You may edit imconfig.h (and not overwrite it when updating Dear ImGui, or maintain a patch/rebased branch with your modifications to it)
|
||||
// B) or '#define IMGUI_USER_CONFIG "my_imgui_config.h"' in your project and then add directives in your own file without touching this template.
|
||||
//-----------------------------------------------------------------------------
|
||||
// You need to make sure that configuration settings are defined consistently _everywhere_ Dear ImGui is used, which include the imgui*.cpp
|
||||
// files but also _any_ of your code that uses Dear ImGui. This is because some compile-time options have an affect on data structures.
|
||||
// Defining those options in imconfig.h will ensure every compilation unit gets to see the same data structure layouts.
|
||||
// Call IMGUI_CHECKVERSION() from your .cpp file to verify that the data structures your files are using are matching the ones imgui.cpp is using.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#pragma once
|
||||
|
||||
//---- Define assertion handler. Defaults to calling assert().
|
||||
// - If your macro uses multiple statements, make sure is enclosed in a 'do { .. } while (0)' block so it can be used as a single statement.
|
||||
// - Compiling with NDEBUG will usually strip out assert() to nothing, which is NOT recommended because we use asserts to notify of programmer mistakes.
|
||||
//#define IM_ASSERT(_EXPR) MyAssert(_EXPR)
|
||||
//#define IM_ASSERT(_EXPR) ((void)(_EXPR)) // Disable asserts
|
||||
|
||||
//---- Define attributes of all API symbols declarations, e.g. for DLL under Windows
|
||||
// Using Dear ImGui via a shared library is not recommended, because of function call overhead and because we don't guarantee backward nor forward ABI compatibility.
|
||||
// - Windows DLL users: heaps and globals are not shared across DLL boundaries! You will need to call SetCurrentContext() + SetAllocatorFunctions()
|
||||
// for each static/DLL boundary you are calling from. Read "Context and Memory Allocators" section of imgui.cpp for more details.
|
||||
//#define IMGUI_API __declspec(dllexport) // MSVC Windows: DLL export
|
||||
//#define IMGUI_API __declspec(dllimport) // MSVC Windows: DLL import
|
||||
//#define IMGUI_API __attribute__((visibility("default"))) // GCC/Clang: override visibility when set is hidden
|
||||
|
||||
//---- Don't define obsolete functions/enums/behaviors. Consider enabling from time to time after updating to clean your code of obsolete function/names.
|
||||
//#define IMGUI_DISABLE_OBSOLETE_FUNCTIONS
|
||||
|
||||
//---- Disable all of Dear ImGui or don't implement standard windows/tools.
|
||||
// It is very strongly recommended to NOT disable the demo windows and debug tool during development. They are extremely useful in day to day work. Please read comments in imgui_demo.cpp.
|
||||
//#define IMGUI_DISABLE // Disable everything: all headers and source files will be empty.
|
||||
//#define IMGUI_DISABLE_DEMO_WINDOWS // Disable demo windows: ShowDemoWindow()/ShowStyleEditor() will be empty.
|
||||
//#define IMGUI_DISABLE_DEBUG_TOOLS // Disable metrics/debugger and other debug tools: ShowMetricsWindow(), ShowDebugLogWindow() and ShowIDStackToolWindow() will be empty.
|
||||
|
||||
//---- Don't implement some functions to reduce linkage requirements.
|
||||
//#define IMGUI_DISABLE_WIN32_DEFAULT_CLIPBOARD_FUNCTIONS // [Win32] Don't implement default clipboard handler. Won't use and link with OpenClipboard/GetClipboardData/CloseClipboard etc. (user32.lib/.a, kernel32.lib/.a)
|
||||
//#define IMGUI_ENABLE_WIN32_DEFAULT_IME_FUNCTIONS // [Win32] [Default with Visual Studio] Implement default IME handler (require imm32.lib/.a, auto-link for Visual Studio, -limm32 on command-line for MinGW)
|
||||
//#define IMGUI_DISABLE_WIN32_DEFAULT_IME_FUNCTIONS // [Win32] [Default with non-Visual Studio compilers] Don't implement default IME handler (won't require imm32.lib/.a)
|
||||
//#define IMGUI_DISABLE_WIN32_FUNCTIONS // [Win32] Won't use and link with any Win32 function (clipboard, IME).
|
||||
//#define IMGUI_ENABLE_OSX_DEFAULT_CLIPBOARD_FUNCTIONS // [OSX] Implement default OSX clipboard handler (need to link with '-framework ApplicationServices', this is why this is not the default).
|
||||
//#define IMGUI_DISABLE_DEFAULT_SHELL_FUNCTIONS // Don't implement default platform_io.Platform_OpenInShellFn() handler (Win32: ShellExecute(), require shell32.lib/.a, Mac/Linux: use system("")).
|
||||
//#define IMGUI_DISABLE_DEFAULT_FORMAT_FUNCTIONS // Don't implement ImFormatString/ImFormatStringV so you can implement them yourself (e.g. if you don't want to link with vsnprintf)
|
||||
//#define IMGUI_DISABLE_DEFAULT_MATH_FUNCTIONS // Don't implement ImFabs/ImSqrt/ImPow/ImFmod/ImCos/ImSin/ImAcos/ImAtan2 so you can implement them yourself.
|
||||
//#define IMGUI_DISABLE_FILE_FUNCTIONS // Don't implement ImFileOpen/ImFileClose/ImFileRead/ImFileWrite and ImFileHandle at all (replace them with dummies)
|
||||
//#define IMGUI_DISABLE_DEFAULT_FILE_FUNCTIONS // Don't implement ImFileOpen/ImFileClose/ImFileRead/ImFileWrite and ImFileHandle so you can implement them yourself if you don't want to link with fopen/fclose/fread/fwrite. This will also disable the LogToTTY() function.
|
||||
//#define IMGUI_DISABLE_DEFAULT_ALLOCATORS // Don't implement default allocators calling malloc()/free() to avoid linking with them. You will need to call ImGui::SetAllocatorFunctions().
|
||||
//#define IMGUI_DISABLE_DEFAULT_FONT // Disable default embedded font (ProggyClean.ttf), remove ~9.5 KB from output binary. AddFontDefault() will assert.
|
||||
//#define IMGUI_DISABLE_SSE // Disable use of SSE intrinsics even if available
|
||||
|
||||
//---- Enable Test Engine / Automation features.
|
||||
//#define IMGUI_ENABLE_TEST_ENGINE // Enable imgui_test_engine hooks. Generally set automatically by include "imgui_te_config.h", see Test Engine for details.
|
||||
|
||||
//---- Include imgui_user.h at the end of imgui.h as a convenience
|
||||
// May be convenient for some users to only explicitly include vanilla imgui.h and have extra stuff included.
|
||||
//#define IMGUI_INCLUDE_IMGUI_USER_H
|
||||
//#define IMGUI_USER_H_FILENAME "my_folder/my_imgui_user.h"
|
||||
|
||||
//---- Pack vertex colors as BGRA8 instead of RGBA8 (to avoid converting from one to another). Need dedicated backend support.
|
||||
//#define IMGUI_USE_BGRA_PACKED_COLOR
|
||||
|
||||
//---- Use legacy CRC32-adler tables (used before 1.91.6), in order to preserve old .ini data that you cannot afford to invalidate.
|
||||
//#define IMGUI_USE_LEGACY_CRC32_ADLER
|
||||
|
||||
//---- Use 32-bit for ImWchar (default is 16-bit) to support Unicode planes 1-16. (e.g. point beyond 0xFFFF like emoticons, dingbats, symbols, shapes, ancient languages, etc...)
|
||||
//#define IMGUI_USE_WCHAR32
|
||||
|
||||
//---- Avoid multiple STB libraries implementations, or redefine path/filenames to prioritize another version
|
||||
// By default the embedded implementations are declared static and not available outside of Dear ImGui sources files.
|
||||
//#define IMGUI_STB_TRUETYPE_FILENAME "my_folder/stb_truetype.h"
|
||||
//#define IMGUI_STB_RECT_PACK_FILENAME "my_folder/stb_rect_pack.h"
|
||||
//#define IMGUI_STB_SPRINTF_FILENAME "my_folder/stb_sprintf.h" // only used if IMGUI_USE_STB_SPRINTF is defined.
|
||||
//#define IMGUI_DISABLE_STB_TRUETYPE_IMPLEMENTATION
|
||||
//#define IMGUI_DISABLE_STB_RECT_PACK_IMPLEMENTATION
|
||||
//#define IMGUI_DISABLE_STB_SPRINTF_IMPLEMENTATION // only disabled if IMGUI_USE_STB_SPRINTF is defined.
|
||||
|
||||
//---- Use stb_sprintf.h for a faster implementation of vsnprintf instead of the one from libc (unless IMGUI_DISABLE_DEFAULT_FORMAT_FUNCTIONS is defined)
|
||||
// Compatibility checks of arguments and formats done by clang and GCC will be disabled in order to support the extra formats provided by stb_sprintf.h.
|
||||
//#define IMGUI_USE_STB_SPRINTF
|
||||
|
||||
//---- Use FreeType to build and rasterize the font atlas (instead of stb_truetype which is embedded by default in Dear ImGui)
|
||||
// Requires FreeType headers to be available in the include path. Requires program to be compiled with 'misc/freetype/imgui_freetype.cpp' (in this repository) + the FreeType library (not provided).
|
||||
// Note that imgui_freetype.cpp may be used _without_ this define, if you manually call ImFontAtlas::SetFontLoader(). The define is simply a convenience.
|
||||
// On Windows you may use vcpkg with 'vcpkg install freetype --triplet=x64-windows' + 'vcpkg integrate install'.
|
||||
//#define IMGUI_ENABLE_FREETYPE
|
||||
|
||||
//---- Use FreeType + plutosvg or lunasvg to render OpenType SVG fonts (SVGinOT)
|
||||
// Only works in combination with IMGUI_ENABLE_FREETYPE.
|
||||
// - plutosvg is currently easier to install, as e.g. it is part of vcpkg. It will support more fonts and may load them faster. See misc/freetype/README for instructions.
|
||||
// - Both require headers to be available in the include path + program to be linked with the library code (not provided).
|
||||
// - (note: lunasvg implementation is based on Freetype's rsvg-port.c which is licensed under CeCILL-C Free Software License Agreement)
|
||||
//#define IMGUI_ENABLE_FREETYPE_PLUTOSVG
|
||||
//#define IMGUI_ENABLE_FREETYPE_LUNASVG
|
||||
|
||||
//---- Use stb_truetype to build and rasterize the font atlas (default)
|
||||
// The only purpose of this define is if you want force compilation of the stb_truetype backend ALONG with the FreeType backend.
|
||||
//#define IMGUI_ENABLE_STB_TRUETYPE
|
||||
|
||||
//---- Define constructor and implicit cast operators to convert back<>forth between your math types and ImVec2/ImVec4.
|
||||
// This will be inlined as part of ImVec2 and ImVec4 class declarations.
|
||||
/*
|
||||
#define IM_VEC2_CLASS_EXTRA \
|
||||
constexpr ImVec2(const MyVec2& f) : x(f.x), y(f.y) {} \
|
||||
operator MyVec2() const { return MyVec2(x,y); }
|
||||
|
||||
#define IM_VEC4_CLASS_EXTRA \
|
||||
constexpr ImVec4(const MyVec4& f) : x(f.x), y(f.y), z(f.z), w(f.w) {} \
|
||||
operator MyVec4() const { return MyVec4(x,y,z,w); }
|
||||
*/
|
||||
//---- ...Or use Dear ImGui's own very basic math operators.
|
||||
//#define IMGUI_DEFINE_MATH_OPERATORS
|
||||
|
||||
//---- Use 32-bit vertex indices (default is 16-bit) is one way to allow large meshes with more than 64K vertices.
|
||||
// Your renderer backend will need to support it (most example renderer backends support both 16/32-bit indices).
|
||||
// Another way to allow large meshes while keeping 16-bit indices is to handle ImDrawCmd::VtxOffset in your renderer.
|
||||
// Read about ImGuiBackendFlags_RendererHasVtxOffset for details.
|
||||
//#define ImDrawIdx unsigned int
|
||||
|
||||
//---- Override ImDrawCallback signature (will need to modify renderer backends accordingly)
|
||||
//struct ImDrawList;
|
||||
//struct ImDrawCmd;
|
||||
//typedef void (*MyImDrawCallback)(const ImDrawList* draw_list, const ImDrawCmd* cmd, void* my_renderer_user_data);
|
||||
//#define ImDrawCallback MyImDrawCallback
|
||||
|
||||
//---- Debug Tools: Macro to break in Debugger (we provide a default implementation of this in the codebase)
|
||||
// (use 'Metrics->Tools->Item Picker' to pick widgets with the mouse and break into them for easy debugging.)
|
||||
//#define IM_DEBUG_BREAK IM_ASSERT(0)
|
||||
//#define IM_DEBUG_BREAK __debugbreak()
|
||||
|
||||
//---- Debug Tools: Enable highlight ID conflicts _before_ hovering items. When io.ConfigDebugHighlightIdConflicts is set.
|
||||
// (THIS WILL SLOW DOWN DEAR IMGUI. Only use occasionally and disable after use)
|
||||
//#define IMGUI_DEBUG_HIGHLIGHT_ALL_ID_CONFLICTS
|
||||
|
||||
//---- Debug Tools: Enable slower asserts
|
||||
//#define IMGUI_DEBUG_PARANOID
|
||||
|
||||
//---- Tip: You can add extra functions within the ImGui:: namespace from anywhere (e.g. your own sources/header files)
|
||||
/*
|
||||
namespace ImGui
|
||||
{
|
||||
void MyFunction(const char* name, MyMatrix44* mtx);
|
||||
}
|
||||
*/
|
||||
18049
src/ThirdParty/ImGuizmo/example/imgui.cpp
vendored
Normal file
18049
src/ThirdParty/ImGuizmo/example/imgui.cpp
vendored
Normal file
File diff suppressed because it is too large
Load Diff
4173
src/ThirdParty/ImGuizmo/example/imgui.h
vendored
Normal file
4173
src/ThirdParty/ImGuizmo/example/imgui.h
vendored
Normal file
File diff suppressed because it is too large
Load Diff
10886
src/ThirdParty/ImGuizmo/example/imgui_demo.cpp
vendored
Normal file
10886
src/ThirdParty/ImGuizmo/example/imgui_demo.cpp
vendored
Normal file
File diff suppressed because it is too large
Load Diff
6342
src/ThirdParty/ImGuizmo/example/imgui_draw.cpp
vendored
Normal file
6342
src/ThirdParty/ImGuizmo/example/imgui_draw.cpp
vendored
Normal file
File diff suppressed because it is too large
Load Diff
3950
src/ThirdParty/ImGuizmo/example/imgui_internal.h
vendored
Normal file
3950
src/ThirdParty/ImGuizmo/example/imgui_internal.h
vendored
Normal file
File diff suppressed because it is too large
Load Diff
4569
src/ThirdParty/ImGuizmo/example/imgui_tables.cpp
vendored
Normal file
4569
src/ThirdParty/ImGuizmo/example/imgui_tables.cpp
vendored
Normal file
File diff suppressed because it is too large
Load Diff
10784
src/ThirdParty/ImGuizmo/example/imgui_widgets.cpp
vendored
Normal file
10784
src/ThirdParty/ImGuizmo/example/imgui_widgets.cpp
vendored
Normal file
File diff suppressed because it is too large
Load Diff
627
src/ThirdParty/ImGuizmo/example/imstb_rectpack.h
vendored
Normal file
627
src/ThirdParty/ImGuizmo/example/imstb_rectpack.h
vendored
Normal file
@@ -0,0 +1,627 @@
|
||||
// [DEAR IMGUI]
|
||||
// This is a slightly modified version of stb_rect_pack.h 1.01.
|
||||
// Grep for [DEAR IMGUI] to find the changes.
|
||||
//
|
||||
// stb_rect_pack.h - v1.01 - public domain - rectangle packing
|
||||
// Sean Barrett 2014
|
||||
//
|
||||
// Useful for e.g. packing rectangular textures into an atlas.
|
||||
// Does not do rotation.
|
||||
//
|
||||
// Before #including,
|
||||
//
|
||||
// #define STB_RECT_PACK_IMPLEMENTATION
|
||||
//
|
||||
// in the file that you want to have the implementation.
|
||||
//
|
||||
// Not necessarily the awesomest packing method, but better than
|
||||
// the totally naive one in stb_truetype (which is primarily what
|
||||
// this is meant to replace).
|
||||
//
|
||||
// Has only had a few tests run, may have issues.
|
||||
//
|
||||
// More docs to come.
|
||||
//
|
||||
// No memory allocations; uses qsort() and assert() from stdlib.
|
||||
// Can override those by defining STBRP_SORT and STBRP_ASSERT.
|
||||
//
|
||||
// This library currently uses the Skyline Bottom-Left algorithm.
|
||||
//
|
||||
// Please note: better rectangle packers are welcome! Please
|
||||
// implement them to the same API, but with a different init
|
||||
// function.
|
||||
//
|
||||
// Credits
|
||||
//
|
||||
// Library
|
||||
// Sean Barrett
|
||||
// Minor features
|
||||
// Martins Mozeiko
|
||||
// github:IntellectualKitty
|
||||
//
|
||||
// Bugfixes / warning fixes
|
||||
// Jeremy Jaussaud
|
||||
// Fabian Giesen
|
||||
//
|
||||
// Version history:
|
||||
//
|
||||
// 1.01 (2021-07-11) always use large rect mode, expose STBRP__MAXVAL in public section
|
||||
// 1.00 (2019-02-25) avoid small space waste; gracefully fail too-wide rectangles
|
||||
// 0.99 (2019-02-07) warning fixes
|
||||
// 0.11 (2017-03-03) return packing success/fail result
|
||||
// 0.10 (2016-10-25) remove cast-away-const to avoid warnings
|
||||
// 0.09 (2016-08-27) fix compiler warnings
|
||||
// 0.08 (2015-09-13) really fix bug with empty rects (w=0 or h=0)
|
||||
// 0.07 (2015-09-13) fix bug with empty rects (w=0 or h=0)
|
||||
// 0.06 (2015-04-15) added STBRP_SORT to allow replacing qsort
|
||||
// 0.05: added STBRP_ASSERT to allow replacing assert
|
||||
// 0.04: fixed minor bug in STBRP_LARGE_RECTS support
|
||||
// 0.01: initial release
|
||||
//
|
||||
// LICENSE
|
||||
//
|
||||
// See end of file for license information.
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// INCLUDE SECTION
|
||||
//
|
||||
|
||||
#ifndef STB_INCLUDE_STB_RECT_PACK_H
|
||||
#define STB_INCLUDE_STB_RECT_PACK_H
|
||||
|
||||
#define STB_RECT_PACK_VERSION 1
|
||||
|
||||
#ifdef STBRP_STATIC
|
||||
#define STBRP_DEF static
|
||||
#else
|
||||
#define STBRP_DEF extern
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct stbrp_context stbrp_context;
|
||||
typedef struct stbrp_node stbrp_node;
|
||||
typedef struct stbrp_rect stbrp_rect;
|
||||
|
||||
typedef int stbrp_coord;
|
||||
|
||||
#define STBRP__MAXVAL 0x7fffffff
|
||||
// Mostly for internal use, but this is the maximum supported coordinate value.
|
||||
|
||||
STBRP_DEF int stbrp_pack_rects (stbrp_context *context, stbrp_rect *rects, int num_rects);
|
||||
// Assign packed locations to rectangles. The rectangles are of type
|
||||
// 'stbrp_rect' defined below, stored in the array 'rects', and there
|
||||
// are 'num_rects' many of them.
|
||||
//
|
||||
// Rectangles which are successfully packed have the 'was_packed' flag
|
||||
// set to a non-zero value and 'x' and 'y' store the minimum location
|
||||
// on each axis (i.e. bottom-left in cartesian coordinates, top-left
|
||||
// if you imagine y increasing downwards). Rectangles which do not fit
|
||||
// have the 'was_packed' flag set to 0.
|
||||
//
|
||||
// You should not try to access the 'rects' array from another thread
|
||||
// while this function is running, as the function temporarily reorders
|
||||
// the array while it executes.
|
||||
//
|
||||
// To pack into another rectangle, you need to call stbrp_init_target
|
||||
// again. To continue packing into the same rectangle, you can call
|
||||
// this function again. Calling this multiple times with multiple rect
|
||||
// arrays will probably produce worse packing results than calling it
|
||||
// a single time with the full rectangle array, but the option is
|
||||
// available.
|
||||
//
|
||||
// The function returns 1 if all of the rectangles were successfully
|
||||
// packed and 0 otherwise.
|
||||
|
||||
struct stbrp_rect
|
||||
{
|
||||
// reserved for your use:
|
||||
int id;
|
||||
|
||||
// input:
|
||||
stbrp_coord w, h;
|
||||
|
||||
// output:
|
||||
stbrp_coord x, y;
|
||||
int was_packed; // non-zero if valid packing
|
||||
|
||||
}; // 16 bytes, nominally
|
||||
|
||||
|
||||
STBRP_DEF void stbrp_init_target (stbrp_context *context, int width, int height, stbrp_node *nodes, int num_nodes);
|
||||
// Initialize a rectangle packer to:
|
||||
// pack a rectangle that is 'width' by 'height' in dimensions
|
||||
// using temporary storage provided by the array 'nodes', which is 'num_nodes' long
|
||||
//
|
||||
// You must call this function every time you start packing into a new target.
|
||||
//
|
||||
// There is no "shutdown" function. The 'nodes' memory must stay valid for
|
||||
// the following stbrp_pack_rects() call (or calls), but can be freed after
|
||||
// the call (or calls) finish.
|
||||
//
|
||||
// Note: to guarantee best results, either:
|
||||
// 1. make sure 'num_nodes' >= 'width'
|
||||
// or 2. call stbrp_allow_out_of_mem() defined below with 'allow_out_of_mem = 1'
|
||||
//
|
||||
// If you don't do either of the above things, widths will be quantized to multiples
|
||||
// of small integers to guarantee the algorithm doesn't run out of temporary storage.
|
||||
//
|
||||
// If you do #2, then the non-quantized algorithm will be used, but the algorithm
|
||||
// may run out of temporary storage and be unable to pack some rectangles.
|
||||
|
||||
STBRP_DEF void stbrp_setup_allow_out_of_mem (stbrp_context *context, int allow_out_of_mem);
|
||||
// Optionally call this function after init but before doing any packing to
|
||||
// change the handling of the out-of-temp-memory scenario, described above.
|
||||
// If you call init again, this will be reset to the default (false).
|
||||
|
||||
|
||||
STBRP_DEF void stbrp_setup_heuristic (stbrp_context *context, int heuristic);
|
||||
// Optionally select which packing heuristic the library should use. Different
|
||||
// heuristics will produce better/worse results for different data sets.
|
||||
// If you call init again, this will be reset to the default.
|
||||
|
||||
enum
|
||||
{
|
||||
STBRP_HEURISTIC_Skyline_default=0,
|
||||
STBRP_HEURISTIC_Skyline_BL_sortHeight = STBRP_HEURISTIC_Skyline_default,
|
||||
STBRP_HEURISTIC_Skyline_BF_sortHeight
|
||||
};
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// the details of the following structures don't matter to you, but they must
|
||||
// be visible so you can handle the memory allocations for them
|
||||
|
||||
struct stbrp_node
|
||||
{
|
||||
stbrp_coord x,y;
|
||||
stbrp_node *next;
|
||||
};
|
||||
|
||||
struct stbrp_context
|
||||
{
|
||||
int width;
|
||||
int height;
|
||||
int align;
|
||||
int init_mode;
|
||||
int heuristic;
|
||||
int num_nodes;
|
||||
stbrp_node *active_head;
|
||||
stbrp_node *free_head;
|
||||
stbrp_node extra[2]; // we allocate two extra nodes so optimal user-node-count is 'width' not 'width+2'
|
||||
};
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// IMPLEMENTATION SECTION
|
||||
//
|
||||
|
||||
#ifdef STB_RECT_PACK_IMPLEMENTATION
|
||||
#ifndef STBRP_SORT
|
||||
#include <stdlib.h>
|
||||
#define STBRP_SORT qsort
|
||||
#endif
|
||||
|
||||
#ifndef STBRP_ASSERT
|
||||
#include <assert.h>
|
||||
#define STBRP_ASSERT assert
|
||||
#endif
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#define STBRP__NOTUSED(v) (void)(v)
|
||||
#define STBRP__CDECL __cdecl
|
||||
#else
|
||||
#define STBRP__NOTUSED(v) (void)sizeof(v)
|
||||
#define STBRP__CDECL
|
||||
#endif
|
||||
|
||||
enum
|
||||
{
|
||||
STBRP__INIT_skyline = 1
|
||||
};
|
||||
|
||||
STBRP_DEF void stbrp_setup_heuristic(stbrp_context *context, int heuristic)
|
||||
{
|
||||
switch (context->init_mode) {
|
||||
case STBRP__INIT_skyline:
|
||||
STBRP_ASSERT(heuristic == STBRP_HEURISTIC_Skyline_BL_sortHeight || heuristic == STBRP_HEURISTIC_Skyline_BF_sortHeight);
|
||||
context->heuristic = heuristic;
|
||||
break;
|
||||
default:
|
||||
STBRP_ASSERT(0);
|
||||
}
|
||||
}
|
||||
|
||||
STBRP_DEF void stbrp_setup_allow_out_of_mem(stbrp_context *context, int allow_out_of_mem)
|
||||
{
|
||||
if (allow_out_of_mem)
|
||||
// if it's ok to run out of memory, then don't bother aligning them;
|
||||
// this gives better packing, but may fail due to OOM (even though
|
||||
// the rectangles easily fit). @TODO a smarter approach would be to only
|
||||
// quantize once we've hit OOM, then we could get rid of this parameter.
|
||||
context->align = 1;
|
||||
else {
|
||||
// if it's not ok to run out of memory, then quantize the widths
|
||||
// so that num_nodes is always enough nodes.
|
||||
//
|
||||
// I.e. num_nodes * align >= width
|
||||
// align >= width / num_nodes
|
||||
// align = ceil(width/num_nodes)
|
||||
|
||||
context->align = (context->width + context->num_nodes-1) / context->num_nodes;
|
||||
}
|
||||
}
|
||||
|
||||
STBRP_DEF void stbrp_init_target(stbrp_context *context, int width, int height, stbrp_node *nodes, int num_nodes)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i=0; i < num_nodes-1; ++i)
|
||||
nodes[i].next = &nodes[i+1];
|
||||
nodes[i].next = NULL;
|
||||
context->init_mode = STBRP__INIT_skyline;
|
||||
context->heuristic = STBRP_HEURISTIC_Skyline_default;
|
||||
context->free_head = &nodes[0];
|
||||
context->active_head = &context->extra[0];
|
||||
context->width = width;
|
||||
context->height = height;
|
||||
context->num_nodes = num_nodes;
|
||||
stbrp_setup_allow_out_of_mem(context, 0);
|
||||
|
||||
// node 0 is the full width, node 1 is the sentinel (lets us not store width explicitly)
|
||||
context->extra[0].x = 0;
|
||||
context->extra[0].y = 0;
|
||||
context->extra[0].next = &context->extra[1];
|
||||
context->extra[1].x = (stbrp_coord) width;
|
||||
context->extra[1].y = (1<<30);
|
||||
context->extra[1].next = NULL;
|
||||
}
|
||||
|
||||
// find minimum y position if it starts at x1
|
||||
static int stbrp__skyline_find_min_y(stbrp_context *c, stbrp_node *first, int x0, int width, int *pwaste)
|
||||
{
|
||||
stbrp_node *node = first;
|
||||
int x1 = x0 + width;
|
||||
int min_y, visited_width, waste_area;
|
||||
|
||||
STBRP__NOTUSED(c);
|
||||
|
||||
STBRP_ASSERT(first->x <= x0);
|
||||
|
||||
#if 0
|
||||
// skip in case we're past the node
|
||||
while (node->next->x <= x0)
|
||||
++node;
|
||||
#else
|
||||
STBRP_ASSERT(node->next->x > x0); // we ended up handling this in the caller for efficiency
|
||||
#endif
|
||||
|
||||
STBRP_ASSERT(node->x <= x0);
|
||||
|
||||
min_y = 0;
|
||||
waste_area = 0;
|
||||
visited_width = 0;
|
||||
while (node->x < x1) {
|
||||
if (node->y > min_y) {
|
||||
// raise min_y higher.
|
||||
// we've accounted for all waste up to min_y,
|
||||
// but we'll now add more waste for everything we've visted
|
||||
waste_area += visited_width * (node->y - min_y);
|
||||
min_y = node->y;
|
||||
// the first time through, visited_width might be reduced
|
||||
if (node->x < x0)
|
||||
visited_width += node->next->x - x0;
|
||||
else
|
||||
visited_width += node->next->x - node->x;
|
||||
} else {
|
||||
// add waste area
|
||||
int under_width = node->next->x - node->x;
|
||||
if (under_width + visited_width > width)
|
||||
under_width = width - visited_width;
|
||||
waste_area += under_width * (min_y - node->y);
|
||||
visited_width += under_width;
|
||||
}
|
||||
node = node->next;
|
||||
}
|
||||
|
||||
*pwaste = waste_area;
|
||||
return min_y;
|
||||
}
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int x,y;
|
||||
stbrp_node **prev_link;
|
||||
} stbrp__findresult;
|
||||
|
||||
static stbrp__findresult stbrp__skyline_find_best_pos(stbrp_context *c, int width, int height)
|
||||
{
|
||||
int best_waste = (1<<30), best_x, best_y = (1 << 30);
|
||||
stbrp__findresult fr;
|
||||
stbrp_node **prev, *node, *tail, **best = NULL;
|
||||
|
||||
// align to multiple of c->align
|
||||
width = (width + c->align - 1);
|
||||
width -= width % c->align;
|
||||
STBRP_ASSERT(width % c->align == 0);
|
||||
|
||||
// if it can't possibly fit, bail immediately
|
||||
if (width > c->width || height > c->height) {
|
||||
fr.prev_link = NULL;
|
||||
fr.x = fr.y = 0;
|
||||
return fr;
|
||||
}
|
||||
|
||||
node = c->active_head;
|
||||
prev = &c->active_head;
|
||||
while (node->x + width <= c->width) {
|
||||
int y,waste;
|
||||
y = stbrp__skyline_find_min_y(c, node, node->x, width, &waste);
|
||||
if (c->heuristic == STBRP_HEURISTIC_Skyline_BL_sortHeight) { // actually just want to test BL
|
||||
// bottom left
|
||||
if (y < best_y) {
|
||||
best_y = y;
|
||||
best = prev;
|
||||
}
|
||||
} else {
|
||||
// best-fit
|
||||
if (y + height <= c->height) {
|
||||
// can only use it if it first vertically
|
||||
if (y < best_y || (y == best_y && waste < best_waste)) {
|
||||
best_y = y;
|
||||
best_waste = waste;
|
||||
best = prev;
|
||||
}
|
||||
}
|
||||
}
|
||||
prev = &node->next;
|
||||
node = node->next;
|
||||
}
|
||||
|
||||
best_x = (best == NULL) ? 0 : (*best)->x;
|
||||
|
||||
// if doing best-fit (BF), we also have to try aligning right edge to each node position
|
||||
//
|
||||
// e.g, if fitting
|
||||
//
|
||||
// ____________________
|
||||
// |____________________|
|
||||
//
|
||||
// into
|
||||
//
|
||||
// | |
|
||||
// | ____________|
|
||||
// |____________|
|
||||
//
|
||||
// then right-aligned reduces waste, but bottom-left BL is always chooses left-aligned
|
||||
//
|
||||
// This makes BF take about 2x the time
|
||||
|
||||
if (c->heuristic == STBRP_HEURISTIC_Skyline_BF_sortHeight) {
|
||||
tail = c->active_head;
|
||||
node = c->active_head;
|
||||
prev = &c->active_head;
|
||||
// find first node that's admissible
|
||||
while (tail->x < width)
|
||||
tail = tail->next;
|
||||
while (tail) {
|
||||
int xpos = tail->x - width;
|
||||
int y,waste;
|
||||
STBRP_ASSERT(xpos >= 0);
|
||||
// find the left position that matches this
|
||||
while (node->next->x <= xpos) {
|
||||
prev = &node->next;
|
||||
node = node->next;
|
||||
}
|
||||
STBRP_ASSERT(node->next->x > xpos && node->x <= xpos);
|
||||
y = stbrp__skyline_find_min_y(c, node, xpos, width, &waste);
|
||||
if (y + height <= c->height) {
|
||||
if (y <= best_y) {
|
||||
if (y < best_y || waste < best_waste || (waste==best_waste && xpos < best_x)) {
|
||||
best_x = xpos;
|
||||
//STBRP_ASSERT(y <= best_y); [DEAR IMGUI]
|
||||
best_y = y;
|
||||
best_waste = waste;
|
||||
best = prev;
|
||||
}
|
||||
}
|
||||
}
|
||||
tail = tail->next;
|
||||
}
|
||||
}
|
||||
|
||||
fr.prev_link = best;
|
||||
fr.x = best_x;
|
||||
fr.y = best_y;
|
||||
return fr;
|
||||
}
|
||||
|
||||
static stbrp__findresult stbrp__skyline_pack_rectangle(stbrp_context *context, int width, int height)
|
||||
{
|
||||
// find best position according to heuristic
|
||||
stbrp__findresult res = stbrp__skyline_find_best_pos(context, width, height);
|
||||
stbrp_node *node, *cur;
|
||||
|
||||
// bail if:
|
||||
// 1. it failed
|
||||
// 2. the best node doesn't fit (we don't always check this)
|
||||
// 3. we're out of memory
|
||||
if (res.prev_link == NULL || res.y + height > context->height || context->free_head == NULL) {
|
||||
res.prev_link = NULL;
|
||||
return res;
|
||||
}
|
||||
|
||||
// on success, create new node
|
||||
node = context->free_head;
|
||||
node->x = (stbrp_coord) res.x;
|
||||
node->y = (stbrp_coord) (res.y + height);
|
||||
|
||||
context->free_head = node->next;
|
||||
|
||||
// insert the new node into the right starting point, and
|
||||
// let 'cur' point to the remaining nodes needing to be
|
||||
// stiched back in
|
||||
|
||||
cur = *res.prev_link;
|
||||
if (cur->x < res.x) {
|
||||
// preserve the existing one, so start testing with the next one
|
||||
stbrp_node *next = cur->next;
|
||||
cur->next = node;
|
||||
cur = next;
|
||||
} else {
|
||||
*res.prev_link = node;
|
||||
}
|
||||
|
||||
// from here, traverse cur and free the nodes, until we get to one
|
||||
// that shouldn't be freed
|
||||
while (cur->next && cur->next->x <= res.x + width) {
|
||||
stbrp_node *next = cur->next;
|
||||
// move the current node to the free list
|
||||
cur->next = context->free_head;
|
||||
context->free_head = cur;
|
||||
cur = next;
|
||||
}
|
||||
|
||||
// stitch the list back in
|
||||
node->next = cur;
|
||||
|
||||
if (cur->x < res.x + width)
|
||||
cur->x = (stbrp_coord) (res.x + width);
|
||||
|
||||
#ifdef _DEBUG
|
||||
cur = context->active_head;
|
||||
while (cur->x < context->width) {
|
||||
STBRP_ASSERT(cur->x < cur->next->x);
|
||||
cur = cur->next;
|
||||
}
|
||||
STBRP_ASSERT(cur->next == NULL);
|
||||
|
||||
{
|
||||
int count=0;
|
||||
cur = context->active_head;
|
||||
while (cur) {
|
||||
cur = cur->next;
|
||||
++count;
|
||||
}
|
||||
cur = context->free_head;
|
||||
while (cur) {
|
||||
cur = cur->next;
|
||||
++count;
|
||||
}
|
||||
STBRP_ASSERT(count == context->num_nodes+2);
|
||||
}
|
||||
#endif
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
static int STBRP__CDECL rect_height_compare(const void *a, const void *b)
|
||||
{
|
||||
const stbrp_rect *p = (const stbrp_rect *) a;
|
||||
const stbrp_rect *q = (const stbrp_rect *) b;
|
||||
if (p->h > q->h)
|
||||
return -1;
|
||||
if (p->h < q->h)
|
||||
return 1;
|
||||
return (p->w > q->w) ? -1 : (p->w < q->w);
|
||||
}
|
||||
|
||||
static int STBRP__CDECL rect_original_order(const void *a, const void *b)
|
||||
{
|
||||
const stbrp_rect *p = (const stbrp_rect *) a;
|
||||
const stbrp_rect *q = (const stbrp_rect *) b;
|
||||
return (p->was_packed < q->was_packed) ? -1 : (p->was_packed > q->was_packed);
|
||||
}
|
||||
|
||||
STBRP_DEF int stbrp_pack_rects(stbrp_context *context, stbrp_rect *rects, int num_rects)
|
||||
{
|
||||
int i, all_rects_packed = 1;
|
||||
|
||||
// we use the 'was_packed' field internally to allow sorting/unsorting
|
||||
for (i=0; i < num_rects; ++i) {
|
||||
rects[i].was_packed = i;
|
||||
}
|
||||
|
||||
// sort according to heuristic
|
||||
STBRP_SORT(rects, num_rects, sizeof(rects[0]), rect_height_compare);
|
||||
|
||||
for (i=0; i < num_rects; ++i) {
|
||||
if (rects[i].w == 0 || rects[i].h == 0) {
|
||||
rects[i].x = rects[i].y = 0; // empty rect needs no space
|
||||
} else {
|
||||
stbrp__findresult fr = stbrp__skyline_pack_rectangle(context, rects[i].w, rects[i].h);
|
||||
if (fr.prev_link) {
|
||||
rects[i].x = (stbrp_coord) fr.x;
|
||||
rects[i].y = (stbrp_coord) fr.y;
|
||||
} else {
|
||||
rects[i].x = rects[i].y = STBRP__MAXVAL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// unsort
|
||||
STBRP_SORT(rects, num_rects, sizeof(rects[0]), rect_original_order);
|
||||
|
||||
// set was_packed flags and all_rects_packed status
|
||||
for (i=0; i < num_rects; ++i) {
|
||||
rects[i].was_packed = !(rects[i].x == STBRP__MAXVAL && rects[i].y == STBRP__MAXVAL);
|
||||
if (!rects[i].was_packed)
|
||||
all_rects_packed = 0;
|
||||
}
|
||||
|
||||
// return the all_rects_packed status
|
||||
return all_rects_packed;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
------------------------------------------------------------------------------
|
||||
This software is available under 2 licenses -- choose whichever you prefer.
|
||||
------------------------------------------------------------------------------
|
||||
ALTERNATIVE A - MIT License
|
||||
Copyright (c) 2017 Sean Barrett
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
this software and associated documentation files (the "Software"), to deal in
|
||||
the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
of the Software, and to permit persons to whom the Software is furnished to do
|
||||
so, subject to the following conditions:
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
------------------------------------------------------------------------------
|
||||
ALTERNATIVE B - Public Domain (www.unlicense.org)
|
||||
This is free and unencumbered software released into the public domain.
|
||||
Anyone is free to copy, modify, publish, use, compile, sell, or distribute this
|
||||
software, either in source code form or as a compiled binary, for any purpose,
|
||||
commercial or non-commercial, and by any means.
|
||||
In jurisdictions that recognize copyright laws, the author or authors of this
|
||||
software dedicate any and all copyright interest in the software to the public
|
||||
domain. We make this dedication for the benefit of the public at large and to
|
||||
the detriment of our heirs and successors. We intend this dedication to be an
|
||||
overt act of relinquishment in perpetuity of all present and future rights to
|
||||
this software under copyright law.
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
||||
ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
------------------------------------------------------------------------------
|
||||
*/
|
||||
1527
src/ThirdParty/ImGuizmo/example/imstb_textedit.h
vendored
Normal file
1527
src/ThirdParty/ImGuizmo/example/imstb_textedit.h
vendored
Normal file
File diff suppressed because it is too large
Load Diff
5085
src/ThirdParty/ImGuizmo/example/imstb_truetype.h
vendored
Normal file
5085
src/ThirdParty/ImGuizmo/example/imstb_truetype.h
vendored
Normal file
File diff suppressed because it is too large
Load Diff
927
src/ThirdParty/ImGuizmo/example/main.cpp
vendored
Normal file
927
src/ThirdParty/ImGuizmo/example/main.cpp
vendored
Normal file
@@ -0,0 +1,927 @@
|
||||
// https://github.com/CedricGuillemet/ImGuizmo
|
||||
// v1.92.5 WIP
|
||||
//
|
||||
// The MIT License(MIT)
|
||||
//
|
||||
// Copyright(c) 2016-2021 Cedric Guillemet
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files(the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and / or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions :
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in all
|
||||
// copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
// SOFTWARE.
|
||||
//
|
||||
#define IMGUI_DEFINE_MATH_OPERATORS
|
||||
#include "imgui.h"
|
||||
#include "imgui_internal.h"
|
||||
#define IMAPP_IMPL
|
||||
#include "ImApp.h"
|
||||
|
||||
#include "ImGuizmo.h"
|
||||
#include "ImSequencer.h"
|
||||
#include "ImZoomSlider.h"
|
||||
#include "ImCurveEdit.h"
|
||||
#include "GraphEditor.h"
|
||||
#include <cmath>
|
||||
#include <vector>
|
||||
#include <algorithm>
|
||||
|
||||
bool useWindow = true;
|
||||
int gizmoCount = 1;
|
||||
float camDistance = 8.f;
|
||||
static ImGuizmo::OPERATION mCurrentGizmoOperation(ImGuizmo::TRANSLATE);
|
||||
static ImGuizmo::MODE mCurrentGizmoMode(ImGuizmo::WORLD);
|
||||
static bool useSnap(false);
|
||||
static float snap[3] = { 1.f, 1.f, 1.f };
|
||||
|
||||
float objectMatrix[4][16] = {
|
||||
{ 1.f, 0.f, 0.f, 0.f,
|
||||
0.f, 1.f, 0.f, 0.f,
|
||||
0.f, 0.f, 1.f, 0.f,
|
||||
0.f, 0.f, 0.f, 1.f },
|
||||
|
||||
{ 1.f, 0.f, 0.f, 0.f,
|
||||
0.f, 1.f, 0.f, 0.f,
|
||||
0.f, 0.f, 1.f, 0.f,
|
||||
2.f, 0.f, 0.f, 1.f },
|
||||
|
||||
{ 1.f, 0.f, 0.f, 0.f,
|
||||
0.f, 1.f, 0.f, 0.f,
|
||||
0.f, 0.f, 1.f, 0.f,
|
||||
2.f, 0.f, 2.f, 1.f },
|
||||
|
||||
{ 1.f, 0.f, 0.f, 0.f,
|
||||
0.f, 1.f, 0.f, 0.f,
|
||||
0.f, 0.f, 1.f, 0.f,
|
||||
0.f, 0.f, 2.f, 1.f }
|
||||
};
|
||||
|
||||
static const float identityMatrix[16] =
|
||||
{ 1.f, 0.f, 0.f, 0.f,
|
||||
0.f, 1.f, 0.f, 0.f,
|
||||
0.f, 0.f, 1.f, 0.f,
|
||||
0.f, 0.f, 0.f, 1.f };
|
||||
|
||||
void Frustum(float left, float right, float bottom, float top, float znear, float zfar, float* m16)
|
||||
{
|
||||
float temp, temp2, temp3, temp4;
|
||||
temp = 2.0f * znear;
|
||||
temp2 = right - left;
|
||||
temp3 = top - bottom;
|
||||
temp4 = zfar - znear;
|
||||
m16[0] = temp / temp2;
|
||||
m16[1] = 0.0;
|
||||
m16[2] = 0.0;
|
||||
m16[3] = 0.0;
|
||||
m16[4] = 0.0;
|
||||
m16[5] = temp / temp3;
|
||||
m16[6] = 0.0;
|
||||
m16[7] = 0.0;
|
||||
m16[8] = (right + left) / temp2;
|
||||
m16[9] = (top + bottom) / temp3;
|
||||
m16[10] = (-zfar - znear) / temp4;
|
||||
m16[11] = -1.0f;
|
||||
m16[12] = 0.0;
|
||||
m16[13] = 0.0;
|
||||
m16[14] = (-temp * zfar) / temp4;
|
||||
m16[15] = 0.0;
|
||||
}
|
||||
|
||||
void Perspective(float fovyInDegrees, float aspectRatio, float znear, float zfar, float* m16)
|
||||
{
|
||||
float ymax, xmax;
|
||||
ymax = znear * tanf(fovyInDegrees * 3.141592f / 180.0f);
|
||||
xmax = ymax * aspectRatio;
|
||||
Frustum(-xmax, xmax, -ymax, ymax, znear, zfar, m16);
|
||||
}
|
||||
|
||||
void Cross(const float* a, const float* b, float* r)
|
||||
{
|
||||
r[0] = a[1] * b[2] - a[2] * b[1];
|
||||
r[1] = a[2] * b[0] - a[0] * b[2];
|
||||
r[2] = a[0] * b[1] - a[1] * b[0];
|
||||
}
|
||||
|
||||
float Dot(const float* a, const float* b)
|
||||
{
|
||||
return a[0] * b[0] + a[1] * b[1] + a[2] * b[2];
|
||||
}
|
||||
|
||||
void Normalize(const float* a, float* r)
|
||||
{
|
||||
float il = 1.f / (sqrtf(Dot(a, a)) + FLT_EPSILON);
|
||||
r[0] = a[0] * il;
|
||||
r[1] = a[1] * il;
|
||||
r[2] = a[2] * il;
|
||||
}
|
||||
|
||||
void LookAt(const float* eye, const float* at, const float* up, float* m16)
|
||||
{
|
||||
float X[3], Y[3], Z[3], tmp[3];
|
||||
|
||||
tmp[0] = eye[0] - at[0];
|
||||
tmp[1] = eye[1] - at[1];
|
||||
tmp[2] = eye[2] - at[2];
|
||||
Normalize(tmp, Z);
|
||||
Normalize(up, Y);
|
||||
|
||||
Cross(Y, Z, tmp);
|
||||
Normalize(tmp, X);
|
||||
|
||||
Cross(Z, X, tmp);
|
||||
Normalize(tmp, Y);
|
||||
|
||||
m16[0] = X[0];
|
||||
m16[1] = Y[0];
|
||||
m16[2] = Z[0];
|
||||
m16[3] = 0.0f;
|
||||
m16[4] = X[1];
|
||||
m16[5] = Y[1];
|
||||
m16[6] = Z[1];
|
||||
m16[7] = 0.0f;
|
||||
m16[8] = X[2];
|
||||
m16[9] = Y[2];
|
||||
m16[10] = Z[2];
|
||||
m16[11] = 0.0f;
|
||||
m16[12] = -Dot(X, eye);
|
||||
m16[13] = -Dot(Y, eye);
|
||||
m16[14] = -Dot(Z, eye);
|
||||
m16[15] = 1.0f;
|
||||
}
|
||||
|
||||
void OrthoGraphic(const float l, float r, float b, const float t, float zn, const float zf, float* m16)
|
||||
{
|
||||
m16[0] = 2 / (r - l);
|
||||
m16[1] = 0.0f;
|
||||
m16[2] = 0.0f;
|
||||
m16[3] = 0.0f;
|
||||
m16[4] = 0.0f;
|
||||
m16[5] = 2 / (t - b);
|
||||
m16[6] = 0.0f;
|
||||
m16[7] = 0.0f;
|
||||
m16[8] = 0.0f;
|
||||
m16[9] = 0.0f;
|
||||
m16[10] = 1.0f / (zf - zn);
|
||||
m16[11] = 0.0f;
|
||||
m16[12] = (l + r) / (l - r);
|
||||
m16[13] = (t + b) / (b - t);
|
||||
m16[14] = zn / (zn - zf);
|
||||
m16[15] = 1.0f;
|
||||
}
|
||||
|
||||
inline void rotationY(const float angle, float* m16)
|
||||
{
|
||||
float c = cosf(angle);
|
||||
float s = sinf(angle);
|
||||
|
||||
m16[0] = c;
|
||||
m16[1] = 0.0f;
|
||||
m16[2] = -s;
|
||||
m16[3] = 0.0f;
|
||||
m16[4] = 0.0f;
|
||||
m16[5] = 1.f;
|
||||
m16[6] = 0.0f;
|
||||
m16[7] = 0.0f;
|
||||
m16[8] = s;
|
||||
m16[9] = 0.0f;
|
||||
m16[10] = c;
|
||||
m16[11] = 0.0f;
|
||||
m16[12] = 0.f;
|
||||
m16[13] = 0.f;
|
||||
m16[14] = 0.f;
|
||||
m16[15] = 1.0f;
|
||||
}
|
||||
|
||||
void TransformStart(float* cameraView, float* cameraProjection, float* matrix)
|
||||
{
|
||||
static float bounds[] = { -0.5f, -0.5f, -0.5f, 0.5f, 0.5f, 0.5f };
|
||||
static float boundsSnap[] = { 0.1f, 0.1f, 0.1f };
|
||||
static bool boundSizing = false;
|
||||
static bool boundSizingSnap = false;
|
||||
|
||||
if (ImGui::IsKeyPressed(ImGuiKey_T))
|
||||
mCurrentGizmoOperation = ImGuizmo::TRANSLATE;
|
||||
if (ImGui::IsKeyPressed(ImGuiKey_E))
|
||||
mCurrentGizmoOperation = ImGuizmo::ROTATE;
|
||||
if (ImGui::IsKeyPressed(ImGuiKey_R)) // r Key
|
||||
mCurrentGizmoOperation = ImGuizmo::SCALE;
|
||||
if (ImGui::RadioButton("Translate", mCurrentGizmoOperation == ImGuizmo::TRANSLATE))
|
||||
mCurrentGizmoOperation = ImGuizmo::TRANSLATE;
|
||||
ImGui::SameLine();
|
||||
if (ImGui::RadioButton("Rotate", mCurrentGizmoOperation == ImGuizmo::ROTATE))
|
||||
mCurrentGizmoOperation = ImGuizmo::ROTATE;
|
||||
ImGui::SameLine();
|
||||
if (ImGui::RadioButton("Scale", mCurrentGizmoOperation == ImGuizmo::SCALE))
|
||||
mCurrentGizmoOperation = ImGuizmo::SCALE;
|
||||
float matrixTranslation[3], matrixRotation[3], matrixScale[3];
|
||||
ImGuizmo::DecomposeMatrixToComponents(matrix, matrixTranslation, matrixRotation, matrixScale);
|
||||
ImGui::InputFloat3("Tr", matrixTranslation);
|
||||
ImGui::InputFloat3("Rt", matrixRotation);
|
||||
ImGui::InputFloat3("Sc", matrixScale);
|
||||
ImGuizmo::RecomposeMatrixFromComponents(matrixTranslation, matrixRotation, matrixScale, matrix);
|
||||
|
||||
if (mCurrentGizmoOperation != ImGuizmo::SCALE)
|
||||
{
|
||||
if (ImGui::RadioButton("Local", mCurrentGizmoMode == ImGuizmo::LOCAL))
|
||||
mCurrentGizmoMode = ImGuizmo::LOCAL;
|
||||
ImGui::SameLine();
|
||||
if (ImGui::RadioButton("World", mCurrentGizmoMode == ImGuizmo::WORLD))
|
||||
mCurrentGizmoMode = ImGuizmo::WORLD;
|
||||
}
|
||||
|
||||
if (ImGui::IsKeyPressed(ImGuiKey_S))
|
||||
useSnap = !useSnap;
|
||||
ImGui::Checkbox("##useSnap", &useSnap);
|
||||
ImGui::SameLine();
|
||||
switch (mCurrentGizmoOperation)
|
||||
{
|
||||
case ImGuizmo::TRANSLATE:
|
||||
ImGui::InputFloat3("Snap", &snap[0]);
|
||||
break;
|
||||
case ImGuizmo::ROTATE:
|
||||
ImGui::InputFloat("Angle Snap", &snap[0]);
|
||||
break;
|
||||
case ImGuizmo::SCALE:
|
||||
ImGui::InputFloat("Scale Snap", &snap[0]);
|
||||
break;
|
||||
}
|
||||
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
float viewManipulateRight = io.DisplaySize.x;
|
||||
float viewManipulateTop = 0;
|
||||
static ImGuiWindowFlags gizmoWindowFlags = 0;
|
||||
ImGui::SetNextWindowSize(ImVec2(800, 400), ImGuiCond_Appearing);
|
||||
ImGui::SetNextWindowPos(ImVec2(400, 20), ImGuiCond_Appearing);
|
||||
ImGui::PushStyleColor(ImGuiCol_WindowBg, (ImVec4)ImColor(0.35f, 0.3f, 0.3f));
|
||||
if (useWindow)
|
||||
{
|
||||
ImGui::Begin("Gizmo", 0, gizmoWindowFlags);
|
||||
ImGuizmo::SetDrawlist();
|
||||
}
|
||||
float windowWidth = (float)ImGui::GetWindowWidth();
|
||||
float windowHeight = (float)ImGui::GetWindowHeight();
|
||||
|
||||
if (!useWindow)
|
||||
{
|
||||
ImGuizmo::SetRect(0, 0, io.DisplaySize.x, io.DisplaySize.y);
|
||||
}
|
||||
else
|
||||
{
|
||||
ImGuizmo::SetRect(ImGui::GetWindowPos().x, ImGui::GetWindowPos().y, windowWidth, windowHeight);
|
||||
}
|
||||
viewManipulateRight = ImGui::GetWindowPos().x + windowWidth;
|
||||
viewManipulateTop = ImGui::GetWindowPos().y;
|
||||
ImGuiWindow* window = ImGui::GetCurrentWindow();
|
||||
gizmoWindowFlags = ImGui::IsWindowHovered() && ImGui::IsMouseHoveringRect(window->InnerRect.Min, window->InnerRect.Max) ? ImGuiWindowFlags_NoMove : 0;
|
||||
|
||||
ImGuizmo::DrawGrid(cameraView, cameraProjection, identityMatrix, 100.f);
|
||||
ImGuizmo::DrawCubes(cameraView, cameraProjection, &objectMatrix[0][0], gizmoCount);
|
||||
|
||||
ImGuizmo::ViewManipulate(cameraView, camDistance, ImVec2(viewManipulateRight - 128, viewManipulateTop), ImVec2(128, 128), 0x10101010);
|
||||
}
|
||||
|
||||
void TransformEnd()
|
||||
{
|
||||
if (useWindow)
|
||||
{
|
||||
ImGui::End();
|
||||
}
|
||||
ImGui::PopStyleColor(1);
|
||||
}
|
||||
|
||||
void EditTransform(float* cameraView, float* cameraProjection, float* matrix)
|
||||
{
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
float windowWidth = (float)ImGui::GetWindowWidth();
|
||||
float windowHeight = (float)ImGui::GetWindowHeight();
|
||||
if (!useWindow)
|
||||
{
|
||||
ImGuizmo::SetRect(0, 0, io.DisplaySize.x, io.DisplaySize.y);
|
||||
}
|
||||
else
|
||||
{
|
||||
ImGuizmo::SetRect(ImGui::GetWindowPos().x, ImGui::GetWindowPos().y, windowWidth, windowHeight);
|
||||
}
|
||||
ImGuizmo::Manipulate(cameraView, cameraProjection, mCurrentGizmoOperation, mCurrentGizmoMode, matrix, NULL, useSnap ? &snap[0] : NULL);
|
||||
}
|
||||
|
||||
//
|
||||
//
|
||||
// ImSequencer interface
|
||||
//
|
||||
//
|
||||
static const char* SequencerItemTypeNames[] = { "Camera","Music", "ScreenEffect", "FadeIn", "Animation" };
|
||||
|
||||
struct RampEdit : public ImCurveEdit::Delegate
|
||||
{
|
||||
RampEdit()
|
||||
{
|
||||
mPts[0][0] = ImVec2(-10.f, 0);
|
||||
mPts[0][1] = ImVec2(20.f, 0.6f);
|
||||
mPts[0][2] = ImVec2(25.f, 0.2f);
|
||||
mPts[0][3] = ImVec2(70.f, 0.4f);
|
||||
mPts[0][4] = ImVec2(120.f, 1.f);
|
||||
mPointCount[0] = 5;
|
||||
|
||||
mPts[1][0] = ImVec2(-50.f, 0.2f);
|
||||
mPts[1][1] = ImVec2(33.f, 0.7f);
|
||||
mPts[1][2] = ImVec2(80.f, 0.2f);
|
||||
mPts[1][3] = ImVec2(82.f, 0.8f);
|
||||
mPointCount[1] = 4;
|
||||
|
||||
|
||||
mPts[2][0] = ImVec2(40.f, 0);
|
||||
mPts[2][1] = ImVec2(60.f, 0.1f);
|
||||
mPts[2][2] = ImVec2(90.f, 0.82f);
|
||||
mPts[2][3] = ImVec2(150.f, 0.24f);
|
||||
mPts[2][4] = ImVec2(200.f, 0.34f);
|
||||
mPts[2][5] = ImVec2(250.f, 0.12f);
|
||||
mPointCount[2] = 6;
|
||||
mbVisible[0] = mbVisible[1] = mbVisible[2] = true;
|
||||
mMax = ImVec2(1.f, 1.f);
|
||||
mMin = ImVec2(0.f, 0.f);
|
||||
}
|
||||
size_t GetCurveCount()
|
||||
{
|
||||
return 3;
|
||||
}
|
||||
|
||||
bool IsVisible(size_t curveIndex)
|
||||
{
|
||||
return mbVisible[curveIndex];
|
||||
}
|
||||
size_t GetPointCount(size_t curveIndex)
|
||||
{
|
||||
return mPointCount[curveIndex];
|
||||
}
|
||||
|
||||
uint32_t GetCurveColor(size_t curveIndex)
|
||||
{
|
||||
uint32_t cols[] = { 0xFF0000FF, 0xFF00FF00, 0xFFFF0000 };
|
||||
return cols[curveIndex];
|
||||
}
|
||||
ImVec2* GetPoints(size_t curveIndex)
|
||||
{
|
||||
return mPts[curveIndex];
|
||||
}
|
||||
virtual ImCurveEdit::CurveType GetCurveType(size_t curveIndex) const { return ImCurveEdit::CurveSmooth; }
|
||||
virtual int EditPoint(size_t curveIndex, int pointIndex, ImVec2 value)
|
||||
{
|
||||
mPts[curveIndex][pointIndex] = ImVec2(value.x, value.y);
|
||||
SortValues(curveIndex);
|
||||
for (size_t i = 0; i < GetPointCount(curveIndex); i++)
|
||||
{
|
||||
if (mPts[curveIndex][i].x == value.x)
|
||||
return (int)i;
|
||||
}
|
||||
return pointIndex;
|
||||
}
|
||||
virtual void AddPoint(size_t curveIndex, ImVec2 value)
|
||||
{
|
||||
if (mPointCount[curveIndex] >= 8)
|
||||
return;
|
||||
mPts[curveIndex][mPointCount[curveIndex]++] = value;
|
||||
SortValues(curveIndex);
|
||||
}
|
||||
virtual ImVec2& GetMax() { return mMax; }
|
||||
virtual ImVec2& GetMin() { return mMin; }
|
||||
virtual unsigned int GetBackgroundColor() { return 0; }
|
||||
ImVec2 mPts[3][8];
|
||||
size_t mPointCount[3];
|
||||
bool mbVisible[3];
|
||||
ImVec2 mMin;
|
||||
ImVec2 mMax;
|
||||
private:
|
||||
void SortValues(size_t curveIndex)
|
||||
{
|
||||
auto b = std::begin(mPts[curveIndex]);
|
||||
auto e = std::begin(mPts[curveIndex]) + GetPointCount(curveIndex);
|
||||
std::sort(b, e, [](ImVec2 a, ImVec2 b) { return a.x < b.x; });
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
struct MySequence : public ImSequencer::SequenceInterface
|
||||
{
|
||||
// interface with sequencer
|
||||
|
||||
virtual int GetFrameMin() const {
|
||||
return mFrameMin;
|
||||
}
|
||||
virtual int GetFrameMax() const {
|
||||
return mFrameMax;
|
||||
}
|
||||
virtual int GetItemCount() const { return (int)myItems.size(); }
|
||||
|
||||
virtual int GetItemTypeCount() const { return sizeof(SequencerItemTypeNames) / sizeof(char*); }
|
||||
virtual const char* GetItemTypeName(int typeIndex) const { return SequencerItemTypeNames[typeIndex]; }
|
||||
virtual const char* GetItemLabel(int index) const
|
||||
{
|
||||
static char tmps[512];
|
||||
snprintf(tmps, 512, "[%02d] %s", index, SequencerItemTypeNames[myItems[index].mType]);
|
||||
return tmps;
|
||||
}
|
||||
|
||||
virtual void Get(int index, int** start, int** end, int* type, unsigned int* color)
|
||||
{
|
||||
MySequenceItem& item = myItems[index];
|
||||
if (color)
|
||||
*color = 0xFFAA8080; // same color for everyone, return color based on type
|
||||
if (start)
|
||||
*start = &item.mFrameStart;
|
||||
if (end)
|
||||
*end = &item.mFrameEnd;
|
||||
if (type)
|
||||
*type = item.mType;
|
||||
}
|
||||
virtual void Add(int type) { myItems.push_back(MySequenceItem{ type, 0, 10, false }); };
|
||||
virtual void Del(int index) { myItems.erase(myItems.begin() + index); }
|
||||
virtual void Duplicate(int index) { myItems.push_back(myItems[index]); }
|
||||
|
||||
virtual size_t GetCustomHeight(int index) { return myItems[index].mExpanded ? 300 : 0; }
|
||||
|
||||
// my datas
|
||||
MySequence() : mFrameMin(0), mFrameMax(0) {}
|
||||
int mFrameMin, mFrameMax;
|
||||
struct MySequenceItem
|
||||
{
|
||||
int mType;
|
||||
int mFrameStart, mFrameEnd;
|
||||
bool mExpanded;
|
||||
};
|
||||
std::vector<MySequenceItem> myItems;
|
||||
RampEdit rampEdit;
|
||||
|
||||
virtual void DoubleClick(int index) {
|
||||
if (myItems[index].mExpanded)
|
||||
{
|
||||
myItems[index].mExpanded = false;
|
||||
return;
|
||||
}
|
||||
for (auto& item : myItems)
|
||||
item.mExpanded = false;
|
||||
myItems[index].mExpanded = !myItems[index].mExpanded;
|
||||
}
|
||||
|
||||
virtual void CustomDraw(int index, ImDrawList* draw_list, const ImRect& rc, const ImRect& legendRect, const ImRect& clippingRect, const ImRect& legendClippingRect)
|
||||
{
|
||||
static const char* labels[] = { "Translation", "Rotation" , "Scale" };
|
||||
|
||||
rampEdit.mMax = ImVec2(float(mFrameMax), 1.f);
|
||||
rampEdit.mMin = ImVec2(float(mFrameMin), 0.f);
|
||||
draw_list->PushClipRect(legendClippingRect.Min, legendClippingRect.Max, true);
|
||||
for (int i = 0; i < 3; i++)
|
||||
{
|
||||
ImVec2 pta(legendRect.Min.x + 30, legendRect.Min.y + i * 14.f);
|
||||
ImVec2 ptb(legendRect.Max.x, legendRect.Min.y + (i + 1) * 14.f);
|
||||
draw_list->AddText(pta, rampEdit.mbVisible[i] ? 0xFFFFFFFF : 0x80FFFFFF, labels[i]);
|
||||
if (ImRect(pta, ptb).Contains(ImGui::GetMousePos()) && ImGui::IsMouseClicked(0))
|
||||
rampEdit.mbVisible[i] = !rampEdit.mbVisible[i];
|
||||
}
|
||||
draw_list->PopClipRect();
|
||||
|
||||
ImGui::SetCursorScreenPos(rc.Min);
|
||||
ImCurveEdit::Edit(rampEdit, rc.Max - rc.Min, 137 + index, &clippingRect);
|
||||
}
|
||||
|
||||
virtual void CustomDrawCompact(int index, ImDrawList* draw_list, const ImRect& rc, const ImRect& clippingRect)
|
||||
{
|
||||
rampEdit.mMax = ImVec2(float(mFrameMax), 1.f);
|
||||
rampEdit.mMin = ImVec2(float(mFrameMin), 0.f);
|
||||
draw_list->PushClipRect(clippingRect.Min, clippingRect.Max, true);
|
||||
for (int i = 0; i < 3; i++)
|
||||
{
|
||||
for (unsigned int j = 0; j < rampEdit.mPointCount[i]; j++)
|
||||
{
|
||||
float p = rampEdit.mPts[i][j].x;
|
||||
if (p < myItems[index].mFrameStart || p > myItems[index].mFrameEnd)
|
||||
continue;
|
||||
float r = (p - mFrameMin) / float(mFrameMax - mFrameMin);
|
||||
float x = ImLerp(rc.Min.x, rc.Max.x, r);
|
||||
draw_list->AddLine(ImVec2(x, rc.Min.y + 6), ImVec2(x, rc.Max.y - 4), 0xAA000000, 4.f);
|
||||
}
|
||||
}
|
||||
draw_list->PopClipRect();
|
||||
}
|
||||
};
|
||||
|
||||
//
|
||||
//
|
||||
// GraphEditor interface
|
||||
//
|
||||
//
|
||||
|
||||
|
||||
template <typename T, std::size_t N>
|
||||
struct Array
|
||||
{
|
||||
T data[N];
|
||||
const size_t size() const { return N; }
|
||||
|
||||
const T operator [] (size_t index) const { return data[index]; }
|
||||
operator T* () {
|
||||
T* p = new T[N];
|
||||
memcpy(p, data, sizeof(data));
|
||||
return p;
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T, typename ... U> Array(T, U...)->Array<T, 1 + sizeof...(U)>;
|
||||
|
||||
struct GraphEditorDelegate : public GraphEditor::Delegate
|
||||
{
|
||||
bool AllowedLink(GraphEditor::NodeIndex from, GraphEditor::NodeIndex to) override
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
void SelectNode(GraphEditor::NodeIndex nodeIndex, bool selected) override
|
||||
{
|
||||
mNodes[nodeIndex].mSelected = selected;
|
||||
}
|
||||
|
||||
void MoveSelectedNodes(const ImVec2 delta) override
|
||||
{
|
||||
for (auto& node : mNodes)
|
||||
{
|
||||
if (!node.mSelected)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
node.x += delta.x;
|
||||
node.y += delta.y;
|
||||
}
|
||||
}
|
||||
|
||||
virtual void RightClick(GraphEditor::NodeIndex nodeIndex, GraphEditor::SlotIndex slotIndexInput, GraphEditor::SlotIndex slotIndexOutput) override
|
||||
{
|
||||
}
|
||||
|
||||
void AddLink(GraphEditor::NodeIndex inputNodeIndex, GraphEditor::SlotIndex inputSlotIndex, GraphEditor::NodeIndex outputNodeIndex, GraphEditor::SlotIndex outputSlotIndex) override
|
||||
{
|
||||
mLinks.push_back({ inputNodeIndex, inputSlotIndex, outputNodeIndex, outputSlotIndex });
|
||||
}
|
||||
|
||||
void DelLink(GraphEditor::LinkIndex linkIndex) override
|
||||
{
|
||||
mLinks.erase(mLinks.begin() + linkIndex);
|
||||
}
|
||||
|
||||
void CustomDraw(ImDrawList* drawList, ImRect rectangle, GraphEditor::NodeIndex nodeIndex) override
|
||||
{
|
||||
drawList->AddLine(rectangle.Min, rectangle.Max, IM_COL32(0, 0, 0, 255));
|
||||
drawList->AddText(rectangle.Min, IM_COL32(255, 128, 64, 255), "Draw");
|
||||
}
|
||||
|
||||
const size_t GetTemplateCount() override
|
||||
{
|
||||
return sizeof(mTemplates) / sizeof(GraphEditor::Template);
|
||||
}
|
||||
|
||||
const GraphEditor::Template GetTemplate(GraphEditor::TemplateIndex index) override
|
||||
{
|
||||
return mTemplates[index];
|
||||
}
|
||||
|
||||
const size_t GetNodeCount() override
|
||||
{
|
||||
return mNodes.size();
|
||||
}
|
||||
|
||||
const GraphEditor::Node GetNode(GraphEditor::NodeIndex index) override
|
||||
{
|
||||
const auto& myNode = mNodes[index];
|
||||
return GraphEditor::Node
|
||||
{
|
||||
myNode.name,
|
||||
myNode.templateIndex,
|
||||
ImRect(ImVec2(myNode.x, myNode.y), ImVec2(myNode.x + 200, myNode.y + 200)),
|
||||
myNode.mSelected
|
||||
};
|
||||
}
|
||||
|
||||
const size_t GetLinkCount() override
|
||||
{
|
||||
return mLinks.size();
|
||||
}
|
||||
|
||||
const GraphEditor::Link GetLink(GraphEditor::LinkIndex index) override
|
||||
{
|
||||
return mLinks[index];
|
||||
}
|
||||
|
||||
// Graph datas
|
||||
static const inline GraphEditor::Template mTemplates[] = {
|
||||
{
|
||||
IM_COL32(160, 160, 180, 255),
|
||||
IM_COL32(100, 100, 140, 255),
|
||||
IM_COL32(110, 110, 150, 255),
|
||||
1,
|
||||
Array{"MyInput"},
|
||||
nullptr,
|
||||
2,
|
||||
Array{"MyOutput0", "MyOuput1"},
|
||||
nullptr
|
||||
},
|
||||
|
||||
{
|
||||
IM_COL32(180, 160, 160, 255),
|
||||
IM_COL32(140, 100, 100, 255),
|
||||
IM_COL32(150, 110, 110, 255),
|
||||
3,
|
||||
nullptr,
|
||||
Array{ IM_COL32(200,100,100,255), IM_COL32(100,200,100,255), IM_COL32(100,100,200,255) },
|
||||
1,
|
||||
Array{"MyOutput0"},
|
||||
Array{ IM_COL32(200,200,200,255)}
|
||||
}
|
||||
};
|
||||
|
||||
struct Node
|
||||
{
|
||||
const char* name;
|
||||
GraphEditor::TemplateIndex templateIndex;
|
||||
float x, y;
|
||||
bool mSelected;
|
||||
};
|
||||
|
||||
std::vector<Node> mNodes = {
|
||||
{
|
||||
"My Node 0",
|
||||
0,
|
||||
0, 0,
|
||||
false
|
||||
},
|
||||
|
||||
{
|
||||
"My Node 1",
|
||||
0,
|
||||
400, 0,
|
||||
false
|
||||
},
|
||||
|
||||
{
|
||||
"My Node 2",
|
||||
1,
|
||||
400, 400,
|
||||
false
|
||||
}
|
||||
};
|
||||
|
||||
std::vector<GraphEditor::Link> mLinks = { {0, 0, 1, 0} };
|
||||
};
|
||||
|
||||
|
||||
int main(int, char**)
|
||||
{
|
||||
ImApp::ImApp imApp;
|
||||
|
||||
ImApp::Config config;
|
||||
config.mWidth = 1280;
|
||||
config.mHeight = 720;
|
||||
//config.mFullscreen = true;
|
||||
imApp.Init(config);
|
||||
|
||||
int lastUsing = 0;
|
||||
|
||||
float cameraView[16] =
|
||||
{ 1.f, 0.f, 0.f, 0.f,
|
||||
0.f, 1.f, 0.f, 0.f,
|
||||
0.f, 0.f, 1.f, 0.f,
|
||||
0.f, 0.f, 0.f, 1.f };
|
||||
|
||||
float cameraProjection[16];
|
||||
|
||||
// build a procedural texture. Copy/pasted and adapted from https://rosettacode.org/wiki/Plasma_effect#Graphics_version
|
||||
unsigned int procTexture;
|
||||
glGenTextures(1, &procTexture);
|
||||
glBindTexture(GL_TEXTURE_2D, procTexture);
|
||||
uint32_t* tempBitmap = new uint32_t[256 * 256];
|
||||
int index = 0;
|
||||
for (int y = 0; y < 256; y++)
|
||||
{
|
||||
for (int x = 0; x < 256; x++)
|
||||
{
|
||||
float dx = x + .5f;
|
||||
float dy = y + .5f;
|
||||
float dv = sinf(x * 0.02f) + sinf(0.03f * (x + y)) + sinf(sqrtf(0.4f * (dx * dx + dy * dy) + 1.f));
|
||||
|
||||
tempBitmap[index] = 0xFF000000 +
|
||||
(int(255 * fabsf(sinf(dv * 3.141592f))) << 16) +
|
||||
(int(255 * fabsf(sinf(dv * 3.141592f + 2 * 3.141592f / 3))) << 8) +
|
||||
(int(255 * fabs(sin(dv * 3.141592f + 4.f * 3.141592f / 3.f))));
|
||||
|
||||
index++;
|
||||
}
|
||||
}
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 256, 256, 0, GL_RGBA, GL_UNSIGNED_BYTE, tempBitmap);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
delete [] tempBitmap;
|
||||
|
||||
// sequence with default values
|
||||
MySequence mySequence;
|
||||
mySequence.mFrameMin = -100;
|
||||
mySequence.mFrameMax = 1000;
|
||||
mySequence.myItems.push_back(MySequence::MySequenceItem{ 0, 10, 30, false });
|
||||
mySequence.myItems.push_back(MySequence::MySequenceItem{ 1, 20, 30, true });
|
||||
mySequence.myItems.push_back(MySequence::MySequenceItem{ 3, 12, 60, false });
|
||||
mySequence.myItems.push_back(MySequence::MySequenceItem{ 2, 61, 90, false });
|
||||
mySequence.myItems.push_back(MySequence::MySequenceItem{ 4, 90, 99, false });
|
||||
|
||||
// Camera projection
|
||||
bool isPerspective = true;
|
||||
float fov = 27.f;
|
||||
float viewWidth = 10.f; // for orthographic
|
||||
float camYAngle = 165.f / 180.f * 3.14159f;
|
||||
float camXAngle = 32.f / 180.f * 3.14159f;
|
||||
|
||||
bool firstFrame = true;
|
||||
|
||||
// Main loop
|
||||
while (!imApp.Done())
|
||||
{
|
||||
imApp.NewFrame();
|
||||
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
if (isPerspective)
|
||||
{
|
||||
Perspective(fov, io.DisplaySize.x / io.DisplaySize.y, 0.1f, 100.f, cameraProjection);
|
||||
}
|
||||
else
|
||||
{
|
||||
float viewHeight = viewWidth * io.DisplaySize.y / io.DisplaySize.x;
|
||||
OrthoGraphic(-viewWidth, viewWidth, -viewHeight, viewHeight, 1000.f, -1000.f, cameraProjection);
|
||||
}
|
||||
ImGuizmo::SetOrthographic(!isPerspective);
|
||||
ImGuizmo::BeginFrame();
|
||||
|
||||
ImGui::SetNextWindowPos(ImVec2(1024, 100), ImGuiCond_Appearing);
|
||||
ImGui::SetNextWindowSize(ImVec2(256, 256), ImGuiCond_Appearing);
|
||||
|
||||
// create a window and insert the inspector
|
||||
ImGui::SetNextWindowPos(ImVec2(10, 10), ImGuiCond_Appearing);
|
||||
ImGui::SetNextWindowSize(ImVec2(320, 340), ImGuiCond_Appearing);
|
||||
ImGui::Begin("Editor");
|
||||
if (ImGui::RadioButton("Full view", !useWindow)) useWindow = false;
|
||||
ImGui::SameLine();
|
||||
if (ImGui::RadioButton("Window", useWindow)) useWindow = true;
|
||||
|
||||
ImGui::Text("Camera");
|
||||
bool viewDirty = false;
|
||||
if (ImGui::RadioButton("Perspective", isPerspective)) isPerspective = true;
|
||||
ImGui::SameLine();
|
||||
if (ImGui::RadioButton("Orthographic", !isPerspective)) isPerspective = false;
|
||||
if (isPerspective)
|
||||
{
|
||||
ImGui::SliderFloat("Fov", &fov, 20.f, 110.f);
|
||||
}
|
||||
else
|
||||
{
|
||||
ImGui::SliderFloat("Ortho width", &viewWidth, 1, 20);
|
||||
}
|
||||
viewDirty |= ImGui::SliderFloat("Distance", &camDistance, 1.f, 10.f);
|
||||
ImGui::SliderInt("Gizmo count", &gizmoCount, 1, 4);
|
||||
|
||||
if (viewDirty || firstFrame)
|
||||
{
|
||||
float eye[] = { cosf(camYAngle) * cosf(camXAngle) * camDistance, sinf(camXAngle) * camDistance, sinf(camYAngle) * cosf(camXAngle) * camDistance };
|
||||
float at[] = { 0.f, 0.f, 0.f };
|
||||
float up[] = { 0.f, 1.f, 0.f };
|
||||
LookAt(eye, at, up, cameraView);
|
||||
firstFrame = false;
|
||||
}
|
||||
|
||||
ImGui::Text("X: %f Y: %f", io.MousePos.x, io.MousePos.y);
|
||||
if (ImGuizmo::IsUsing())
|
||||
{
|
||||
ImGui::Text("Using gizmo");
|
||||
}
|
||||
else
|
||||
{
|
||||
ImGui::Text(ImGuizmo::IsOver()?"Over gizmo":"");
|
||||
ImGui::SameLine();
|
||||
ImGui::Text(ImGuizmo::IsOver(ImGuizmo::TRANSLATE) ? "Over translate gizmo" : "");
|
||||
ImGui::SameLine();
|
||||
ImGui::Text(ImGuizmo::IsOver(ImGuizmo::ROTATE) ? "Over rotate gizmo" : "");
|
||||
ImGui::SameLine();
|
||||
ImGui::Text(ImGuizmo::IsOver(ImGuizmo::SCALE) ? "Over scale gizmo" : "");
|
||||
}
|
||||
ImGui::Separator();
|
||||
|
||||
TransformStart(cameraView, cameraProjection, objectMatrix[lastUsing]);
|
||||
for (int matId = 0; matId < gizmoCount; matId++)
|
||||
{
|
||||
ImGuizmo::PushID(matId);
|
||||
|
||||
EditTransform(cameraView, cameraProjection, objectMatrix[matId]);
|
||||
if (ImGuizmo::IsUsing())
|
||||
{
|
||||
lastUsing = matId;
|
||||
}
|
||||
ImGuizmo::PopID();
|
||||
}
|
||||
TransformEnd();
|
||||
|
||||
ImGui::End();
|
||||
|
||||
ImGui::SetNextWindowPos(ImVec2(10, 350), ImGuiCond_Appearing);
|
||||
|
||||
ImGui::SetNextWindowSize(ImVec2(940, 480), ImGuiCond_Appearing);
|
||||
ImGui::Begin("Other controls");
|
||||
if (ImGui::CollapsingHeader("Zoom Slider"))
|
||||
{
|
||||
static float uMin = 0.4f, uMax = 0.6f;
|
||||
static float vMin = 0.4f, vMax = 0.6f;
|
||||
ImGui::Image((ImTextureID)(uint64_t)procTexture, ImVec2(900,300), ImVec2(uMin, vMin), ImVec2(uMax, vMax));
|
||||
{
|
||||
ImGui::SameLine();
|
||||
ImGui::PushID(18);
|
||||
ImZoomSlider::ImZoomSlider(0.f, 1.f, vMin, vMax, 0.01f, ImZoomSlider::ImGuiZoomSliderFlags_Vertical);
|
||||
ImGui::PopID();
|
||||
}
|
||||
|
||||
{
|
||||
ImGui::PushID(19);
|
||||
ImZoomSlider::ImZoomSlider(0.f, 1.f, uMin, uMax);
|
||||
ImGui::PopID();
|
||||
}
|
||||
}
|
||||
if (ImGui::CollapsingHeader("Sequencer"))
|
||||
{
|
||||
// let's create the sequencer
|
||||
static int selectedEntry = -1;
|
||||
static int firstFrame = 0;
|
||||
static bool expanded = true;
|
||||
static int currentFrame = 100;
|
||||
|
||||
ImGui::PushItemWidth(130);
|
||||
ImGui::InputInt("Frame Min", &mySequence.mFrameMin);
|
||||
ImGui::SameLine();
|
||||
ImGui::InputInt("Frame ", ¤tFrame);
|
||||
ImGui::SameLine();
|
||||
ImGui::InputInt("Frame Max", &mySequence.mFrameMax);
|
||||
ImGui::PopItemWidth();
|
||||
Sequencer(&mySequence, ¤tFrame, &expanded, &selectedEntry, &firstFrame, ImSequencer::SEQUENCER_EDIT_STARTEND | ImSequencer::SEQUENCER_ADD | ImSequencer::SEQUENCER_DEL | ImSequencer::SEQUENCER_COPYPASTE | ImSequencer::SEQUENCER_CHANGE_FRAME);
|
||||
// add a UI to edit that particular item
|
||||
if (selectedEntry != -1)
|
||||
{
|
||||
const MySequence::MySequenceItem &item = mySequence.myItems[selectedEntry];
|
||||
ImGui::Text("I am a %s, please edit me", SequencerItemTypeNames[item.mType]);
|
||||
// switch (type) ....
|
||||
}
|
||||
}
|
||||
|
||||
// Graph Editor
|
||||
static GraphEditor::Options options;
|
||||
static GraphEditorDelegate delegate;
|
||||
static GraphEditor::ViewState viewState;
|
||||
static GraphEditor::FitOnScreen fit = GraphEditor::Fit_None;
|
||||
static bool showGraphEditor = true;
|
||||
|
||||
if (ImGui::CollapsingHeader("Graph Editor"))
|
||||
{
|
||||
ImGui::Checkbox("Show GraphEditor", &showGraphEditor);
|
||||
GraphEditor::EditOptions(options);
|
||||
}
|
||||
|
||||
ImGui::End();
|
||||
|
||||
if (showGraphEditor)
|
||||
{
|
||||
ImGui::Begin("Graph Editor", NULL, 0);
|
||||
if (ImGui::Button("Fit all nodes"))
|
||||
{
|
||||
fit = GraphEditor::Fit_AllNodes;
|
||||
}
|
||||
ImGui::SameLine();
|
||||
if (ImGui::Button("Fit selected nodes"))
|
||||
{
|
||||
fit = GraphEditor::Fit_SelectedNodes;
|
||||
}
|
||||
GraphEditor::Show(delegate, options, viewState, true, &fit);
|
||||
|
||||
ImGui::End();
|
||||
}
|
||||
|
||||
// render everything
|
||||
glClearColor(0.45f, 0.4f, 0.4f, 1.f);
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
imApp.EndFrame();
|
||||
}
|
||||
|
||||
imApp.Finish();
|
||||
|
||||
return 0;
|
||||
}
|
||||
7187
src/ThirdParty/ImGuizmo/example/stb_image.h
vendored
Normal file
7187
src/ThirdParty/ImGuizmo/example/stb_image.h
vendored
Normal file
File diff suppressed because it is too large
Load Diff
24
src/ThirdParty/ImGuizmo/vcpkg-example/CMakeLists.txt
vendored
Normal file
24
src/ThirdParty/ImGuizmo/vcpkg-example/CMakeLists.txt
vendored
Normal file
@@ -0,0 +1,24 @@
|
||||
cmake_minimum_required(VERSION 3.16)
|
||||
|
||||
project(vcpkg-example)
|
||||
|
||||
add_definitions(-DSTB_IMAGE_IMPLEMENTATION)
|
||||
find_path(STB_INCLUDE_DIRS "stb.h")
|
||||
|
||||
find_package(imgui CONFIG REQUIRED)
|
||||
find_package(imguizmo CONFIG REQUIRED)
|
||||
|
||||
add_executable(example-app)
|
||||
|
||||
target_sources(example-app PRIVATE main.cpp)
|
||||
|
||||
target_compile_options(example-app PRIVATE "/std:c++17")
|
||||
|
||||
target_include_directories(example-app PRIVATE
|
||||
${STB_INCLUDE_DIRS}
|
||||
)
|
||||
|
||||
target_link_libraries(example-app PRIVATE
|
||||
imgui::imgui
|
||||
imguizmo::imguizmo
|
||||
)
|
||||
3597
src/ThirdParty/ImGuizmo/vcpkg-example/ImApp.h
vendored
Normal file
3597
src/ThirdParty/ImGuizmo/vcpkg-example/ImApp.h
vendored
Normal file
File diff suppressed because it is too large
Load Diff
52
src/ThirdParty/ImGuizmo/vcpkg-example/README.md
vendored
Normal file
52
src/ThirdParty/ImGuizmo/vcpkg-example/README.md
vendored
Normal file
@@ -0,0 +1,52 @@
|
||||
# ImGuizmo example
|
||||
|
||||
ImGuizmo example app that uses [cmake][cmake] and [vcpkg][vcpkg]
|
||||
|
||||
## Setup
|
||||
|
||||
Assuming cmake and vcpkg are installed, all that is required is to add the vcpkg toolchain file to
|
||||
the cmake configure and all dependencies will be downloaded and installed into the project
|
||||
|
||||
```bash
|
||||
mkdir build
|
||||
cd build
|
||||
cmake .. -DCMAKE_TOOLCHAIN_FILE=C:/dev/vcpkg/scripts/buildsystem/vcpkg.cmake
|
||||
```
|
||||
|
||||
### Visual Studio
|
||||
|
||||
Rather than running directly, IDEs usually configure the cmake. Visual studio can be integrated
|
||||
directly with the `vcpkg integrate install` command or by specifying the path to the toolchain file
|
||||
in the project cmake settings
|
||||
|
||||
### VSCode
|
||||
|
||||
When using the cmake tools extension the command can be added to the `.vscode/settings.json` file as
|
||||
follows
|
||||
|
||||
```json
|
||||
{
|
||||
"cmake.configureArgs": [
|
||||
"-DCMAKE_TOOLCHAIN_FILE=C:\\dev\\vcpkg\\scripts\\buildsystems\\vcpkg.cmake"
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
> :heavy_check_mark: If you include the settings file in your repo, a good practice would be to use
|
||||
an environment variable for the path to the vcpkg install and variable substitution in the toolchain
|
||||
file path so the settings work across machines. eg `"-DCMAKE_TOOLCHAIN_FILE={$env:VCPKG_ROOT}\\scripts\\buildsystems\\vcpkg.cmake"`
|
||||
|
||||
This can also be added to the system-wide settings rather than added to each project individually
|
||||
|
||||
## How It Works
|
||||
|
||||
The example contains a `vcpkg.json` manifest file that contains the dependencices. When cmake is
|
||||
supplied with the vcpkg toolchain file, the script detects this manifest file and then downloads and
|
||||
compiles the dependencies there-in
|
||||
|
||||
In `CMakeLists.txt` the `find_package(imguizmo CONFIG REQUIRED)` command finds the cmake config
|
||||
added by the vcpkg install and `target_link_libraries(example-app PRIVATE imguizmo::imguizmo)` adds
|
||||
the includes and lib to the target
|
||||
|
||||
[cmake]: https://cmake.org/
|
||||
[vcpkg]: https://github.com/microsoft/vcpkg
|
||||
25
src/ThirdParty/ImGuizmo/vcpkg-example/imgui.ini
vendored
Normal file
25
src/ThirdParty/ImGuizmo/vcpkg-example/imgui.ini
vendored
Normal file
@@ -0,0 +1,25 @@
|
||||
[Window][Debug##Default]
|
||||
Pos=60,60
|
||||
Size=400,400
|
||||
Collapsed=0
|
||||
|
||||
[Window][Editor]
|
||||
Pos=10,10
|
||||
Size=320,340
|
||||
Collapsed=0
|
||||
|
||||
[Window][Graph Editor]
|
||||
Pos=976,359
|
||||
Size=1325,844
|
||||
Collapsed=0
|
||||
|
||||
[Window][Other controls]
|
||||
Pos=10,350
|
||||
Size=940,480
|
||||
Collapsed=0
|
||||
|
||||
[Window][Gizmo]
|
||||
Pos=400,20
|
||||
Size=800,400
|
||||
Collapsed=0
|
||||
|
||||
888
src/ThirdParty/ImGuizmo/vcpkg-example/main.cpp
vendored
Normal file
888
src/ThirdParty/ImGuizmo/vcpkg-example/main.cpp
vendored
Normal file
@@ -0,0 +1,888 @@
|
||||
#define IMGUI_DEFINE_MATH_OPERATORS
|
||||
#include "imgui.h"
|
||||
#include "imgui_internal.h"
|
||||
#define IMAPP_IMPL
|
||||
#include "ImApp.h"
|
||||
|
||||
#include "ImGuizmo.h"
|
||||
#include "ImSequencer.h"
|
||||
#include "ImZoomSlider.h"
|
||||
#include "ImCurveEdit.h"
|
||||
#include "GraphEditor.h"
|
||||
|
||||
#include <cmath>
|
||||
#include <vector>
|
||||
#include <algorithm>
|
||||
|
||||
bool useWindow = true;
|
||||
int gizmoCount = 1;
|
||||
float camDistance = 8.f;
|
||||
static ImGuizmo::OPERATION mCurrentGizmoOperation(ImGuizmo::TRANSLATE);
|
||||
|
||||
float objectMatrix[4][16] = {
|
||||
{ 1.f, 0.f, 0.f, 0.f,
|
||||
0.f, 1.f, 0.f, 0.f,
|
||||
0.f, 0.f, 1.f, 0.f,
|
||||
0.f, 0.f, 0.f, 1.f },
|
||||
|
||||
{ 1.f, 0.f, 0.f, 0.f,
|
||||
0.f, 1.f, 0.f, 0.f,
|
||||
0.f, 0.f, 1.f, 0.f,
|
||||
2.f, 0.f, 0.f, 1.f },
|
||||
|
||||
{ 1.f, 0.f, 0.f, 0.f,
|
||||
0.f, 1.f, 0.f, 0.f,
|
||||
0.f, 0.f, 1.f, 0.f,
|
||||
2.f, 0.f, 2.f, 1.f },
|
||||
|
||||
{ 1.f, 0.f, 0.f, 0.f,
|
||||
0.f, 1.f, 0.f, 0.f,
|
||||
0.f, 0.f, 1.f, 0.f,
|
||||
0.f, 0.f, 2.f, 1.f }
|
||||
};
|
||||
|
||||
static const float identityMatrix[16] =
|
||||
{ 1.f, 0.f, 0.f, 0.f,
|
||||
0.f, 1.f, 0.f, 0.f,
|
||||
0.f, 0.f, 1.f, 0.f,
|
||||
0.f, 0.f, 0.f, 1.f };
|
||||
|
||||
void Frustum(float left, float right, float bottom, float top, float znear, float zfar, float* m16)
|
||||
{
|
||||
float temp, temp2, temp3, temp4;
|
||||
temp = 2.0f * znear;
|
||||
temp2 = right - left;
|
||||
temp3 = top - bottom;
|
||||
temp4 = zfar - znear;
|
||||
m16[0] = temp / temp2;
|
||||
m16[1] = 0.0;
|
||||
m16[2] = 0.0;
|
||||
m16[3] = 0.0;
|
||||
m16[4] = 0.0;
|
||||
m16[5] = temp / temp3;
|
||||
m16[6] = 0.0;
|
||||
m16[7] = 0.0;
|
||||
m16[8] = (right + left) / temp2;
|
||||
m16[9] = (top + bottom) / temp3;
|
||||
m16[10] = (-zfar - znear) / temp4;
|
||||
m16[11] = -1.0f;
|
||||
m16[12] = 0.0;
|
||||
m16[13] = 0.0;
|
||||
m16[14] = (-temp * zfar) / temp4;
|
||||
m16[15] = 0.0;
|
||||
}
|
||||
|
||||
void Perspective(float fovyInDegrees, float aspectRatio, float znear, float zfar, float* m16)
|
||||
{
|
||||
float ymax, xmax;
|
||||
ymax = znear * tanf(fovyInDegrees * 3.141592f / 180.0f);
|
||||
xmax = ymax * aspectRatio;
|
||||
Frustum(-xmax, xmax, -ymax, ymax, znear, zfar, m16);
|
||||
}
|
||||
|
||||
void Cross(const float* a, const float* b, float* r)
|
||||
{
|
||||
r[0] = a[1] * b[2] - a[2] * b[1];
|
||||
r[1] = a[2] * b[0] - a[0] * b[2];
|
||||
r[2] = a[0] * b[1] - a[1] * b[0];
|
||||
}
|
||||
|
||||
float Dot(const float* a, const float* b)
|
||||
{
|
||||
return a[0] * b[0] + a[1] * b[1] + a[2] * b[2];
|
||||
}
|
||||
|
||||
void Normalize(const float* a, float* r)
|
||||
{
|
||||
float il = 1.f / (sqrtf(Dot(a, a)) + FLT_EPSILON);
|
||||
r[0] = a[0] * il;
|
||||
r[1] = a[1] * il;
|
||||
r[2] = a[2] * il;
|
||||
}
|
||||
|
||||
void LookAt(const float* eye, const float* at, const float* up, float* m16)
|
||||
{
|
||||
float X[3], Y[3], Z[3], tmp[3];
|
||||
|
||||
tmp[0] = eye[0] - at[0];
|
||||
tmp[1] = eye[1] - at[1];
|
||||
tmp[2] = eye[2] - at[2];
|
||||
Normalize(tmp, Z);
|
||||
Normalize(up, Y);
|
||||
|
||||
Cross(Y, Z, tmp);
|
||||
Normalize(tmp, X);
|
||||
|
||||
Cross(Z, X, tmp);
|
||||
Normalize(tmp, Y);
|
||||
|
||||
m16[0] = X[0];
|
||||
m16[1] = Y[0];
|
||||
m16[2] = Z[0];
|
||||
m16[3] = 0.0f;
|
||||
m16[4] = X[1];
|
||||
m16[5] = Y[1];
|
||||
m16[6] = Z[1];
|
||||
m16[7] = 0.0f;
|
||||
m16[8] = X[2];
|
||||
m16[9] = Y[2];
|
||||
m16[10] = Z[2];
|
||||
m16[11] = 0.0f;
|
||||
m16[12] = -Dot(X, eye);
|
||||
m16[13] = -Dot(Y, eye);
|
||||
m16[14] = -Dot(Z, eye);
|
||||
m16[15] = 1.0f;
|
||||
}
|
||||
|
||||
void OrthoGraphic(const float l, float r, float b, const float t, float zn, const float zf, float* m16)
|
||||
{
|
||||
m16[0] = 2 / (r - l);
|
||||
m16[1] = 0.0f;
|
||||
m16[2] = 0.0f;
|
||||
m16[3] = 0.0f;
|
||||
m16[4] = 0.0f;
|
||||
m16[5] = 2 / (t - b);
|
||||
m16[6] = 0.0f;
|
||||
m16[7] = 0.0f;
|
||||
m16[8] = 0.0f;
|
||||
m16[9] = 0.0f;
|
||||
m16[10] = 1.0f / (zf - zn);
|
||||
m16[11] = 0.0f;
|
||||
m16[12] = (l + r) / (l - r);
|
||||
m16[13] = (t + b) / (b - t);
|
||||
m16[14] = zn / (zn - zf);
|
||||
m16[15] = 1.0f;
|
||||
}
|
||||
|
||||
inline void rotationY(const float angle, float* m16)
|
||||
{
|
||||
float c = cosf(angle);
|
||||
float s = sinf(angle);
|
||||
|
||||
m16[0] = c;
|
||||
m16[1] = 0.0f;
|
||||
m16[2] = -s;
|
||||
m16[3] = 0.0f;
|
||||
m16[4] = 0.0f;
|
||||
m16[5] = 1.f;
|
||||
m16[6] = 0.0f;
|
||||
m16[7] = 0.0f;
|
||||
m16[8] = s;
|
||||
m16[9] = 0.0f;
|
||||
m16[10] = c;
|
||||
m16[11] = 0.0f;
|
||||
m16[12] = 0.f;
|
||||
m16[13] = 0.f;
|
||||
m16[14] = 0.f;
|
||||
m16[15] = 1.0f;
|
||||
}
|
||||
|
||||
void EditTransform(float* cameraView, float* cameraProjection, float* matrix, bool editTransformDecomposition)
|
||||
{
|
||||
static ImGuizmo::MODE mCurrentGizmoMode(ImGuizmo::LOCAL);
|
||||
static bool useSnap = false;
|
||||
static float snap[3] = { 1.f, 1.f, 1.f };
|
||||
static float bounds[] = { -0.5f, -0.5f, -0.5f, 0.5f, 0.5f, 0.5f };
|
||||
static float boundsSnap[] = { 0.1f, 0.1f, 0.1f };
|
||||
static bool boundSizing = false;
|
||||
static bool boundSizingSnap = false;
|
||||
|
||||
if (editTransformDecomposition)
|
||||
{
|
||||
if (ImGui::IsKeyPressed(90))
|
||||
mCurrentGizmoOperation = ImGuizmo::TRANSLATE;
|
||||
if (ImGui::IsKeyPressed(69))
|
||||
mCurrentGizmoOperation = ImGuizmo::ROTATE;
|
||||
if (ImGui::IsKeyPressed(82)) // r Key
|
||||
mCurrentGizmoOperation = ImGuizmo::SCALE;
|
||||
if (ImGui::RadioButton("Translate", mCurrentGizmoOperation == ImGuizmo::TRANSLATE))
|
||||
mCurrentGizmoOperation = ImGuizmo::TRANSLATE;
|
||||
ImGui::SameLine();
|
||||
if (ImGui::RadioButton("Rotate", mCurrentGizmoOperation == ImGuizmo::ROTATE))
|
||||
mCurrentGizmoOperation = ImGuizmo::ROTATE;
|
||||
ImGui::SameLine();
|
||||
if (ImGui::RadioButton("Scale", mCurrentGizmoOperation == ImGuizmo::SCALE))
|
||||
mCurrentGizmoOperation = ImGuizmo::SCALE;
|
||||
float matrixTranslation[3], matrixRotation[3], matrixScale[3];
|
||||
ImGuizmo::DecomposeMatrixToComponents(matrix, matrixTranslation, matrixRotation, matrixScale);
|
||||
ImGui::InputFloat3("Tr", matrixTranslation);
|
||||
ImGui::InputFloat3("Rt", matrixRotation);
|
||||
ImGui::InputFloat3("Sc", matrixScale);
|
||||
ImGuizmo::RecomposeMatrixFromComponents(matrixTranslation, matrixRotation, matrixScale, matrix);
|
||||
|
||||
if (mCurrentGizmoOperation != ImGuizmo::SCALE)
|
||||
{
|
||||
if (ImGui::RadioButton("Local", mCurrentGizmoMode == ImGuizmo::LOCAL))
|
||||
mCurrentGizmoMode = ImGuizmo::LOCAL;
|
||||
ImGui::SameLine();
|
||||
if (ImGui::RadioButton("World", mCurrentGizmoMode == ImGuizmo::WORLD))
|
||||
mCurrentGizmoMode = ImGuizmo::WORLD;
|
||||
}
|
||||
if (ImGui::IsKeyPressed(83))
|
||||
useSnap = !useSnap;
|
||||
ImGui::Checkbox("", &useSnap);
|
||||
ImGui::SameLine();
|
||||
|
||||
switch (mCurrentGizmoOperation)
|
||||
{
|
||||
case ImGuizmo::TRANSLATE:
|
||||
ImGui::InputFloat3("Snap", &snap[0]);
|
||||
break;
|
||||
case ImGuizmo::ROTATE:
|
||||
ImGui::InputFloat("Angle Snap", &snap[0]);
|
||||
break;
|
||||
case ImGuizmo::SCALE:
|
||||
ImGui::InputFloat("Scale Snap", &snap[0]);
|
||||
break;
|
||||
}
|
||||
ImGui::Checkbox("Bound Sizing", &boundSizing);
|
||||
if (boundSizing)
|
||||
{
|
||||
ImGui::PushID(3);
|
||||
ImGui::Checkbox("", &boundSizingSnap);
|
||||
ImGui::SameLine();
|
||||
ImGui::InputFloat3("Snap", boundsSnap);
|
||||
ImGui::PopID();
|
||||
}
|
||||
}
|
||||
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
float viewManipulateRight = io.DisplaySize.x;
|
||||
float viewManipulateTop = 0;
|
||||
if (useWindow)
|
||||
{
|
||||
ImGui::SetNextWindowSize(ImVec2(800, 400));
|
||||
ImGui::SetNextWindowPos(ImVec2(400,20));
|
||||
ImGui::PushStyleColor(ImGuiCol_WindowBg, (ImVec4)ImColor(0.35f, 0.3f, 0.3f));
|
||||
ImGui::Begin("Gizmo", 0, ImGuiWindowFlags_NoMove);
|
||||
ImGuizmo::SetDrawlist();
|
||||
float windowWidth = (float)ImGui::GetWindowWidth();
|
||||
float windowHeight = (float)ImGui::GetWindowHeight();
|
||||
ImGuizmo::SetRect(ImGui::GetWindowPos().x, ImGui::GetWindowPos().y, windowWidth, windowHeight);
|
||||
viewManipulateRight = ImGui::GetWindowPos().x + windowWidth;
|
||||
viewManipulateTop = ImGui::GetWindowPos().y;
|
||||
}
|
||||
else
|
||||
{
|
||||
ImGuizmo::SetRect(0, 0, io.DisplaySize.x, io.DisplaySize.y);
|
||||
}
|
||||
|
||||
ImGuizmo::DrawGrid(cameraView, cameraProjection, identityMatrix, 100.f);
|
||||
ImGuizmo::DrawCubes(cameraView, cameraProjection, &objectMatrix[0][0], gizmoCount);
|
||||
ImGuizmo::Manipulate(cameraView, cameraProjection, mCurrentGizmoOperation, mCurrentGizmoMode, matrix, NULL, useSnap ? &snap[0] : NULL, boundSizing ? bounds : NULL, boundSizingSnap ? boundsSnap : NULL);
|
||||
|
||||
ImGuizmo::ViewManipulate(cameraView, camDistance, ImVec2(viewManipulateRight - 128, viewManipulateTop), ImVec2(128, 128), 0x10101010);
|
||||
|
||||
if (useWindow)
|
||||
{
|
||||
ImGui::End();
|
||||
ImGui::PopStyleColor(1);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
//
|
||||
// ImSequencer interface
|
||||
//
|
||||
//
|
||||
static const char* SequencerItemTypeNames[] = { "Camera","Music", "ScreenEffect", "FadeIn", "Animation" };
|
||||
|
||||
struct RampEdit : public ImCurveEdit::Delegate
|
||||
{
|
||||
RampEdit()
|
||||
{
|
||||
mPts[0][0] = ImVec2(-10.f, 0);
|
||||
mPts[0][1] = ImVec2(20.f, 0.6f);
|
||||
mPts[0][2] = ImVec2(25.f, 0.2f);
|
||||
mPts[0][3] = ImVec2(70.f, 0.4f);
|
||||
mPts[0][4] = ImVec2(120.f, 1.f);
|
||||
mPointCount[0] = 5;
|
||||
|
||||
mPts[1][0] = ImVec2(-50.f, 0.2f);
|
||||
mPts[1][1] = ImVec2(33.f, 0.7f);
|
||||
mPts[1][2] = ImVec2(80.f, 0.2f);
|
||||
mPts[1][3] = ImVec2(82.f, 0.8f);
|
||||
mPointCount[1] = 4;
|
||||
|
||||
|
||||
mPts[2][0] = ImVec2(40.f, 0);
|
||||
mPts[2][1] = ImVec2(60.f, 0.1f);
|
||||
mPts[2][2] = ImVec2(90.f, 0.82f);
|
||||
mPts[2][3] = ImVec2(150.f, 0.24f);
|
||||
mPts[2][4] = ImVec2(200.f, 0.34f);
|
||||
mPts[2][5] = ImVec2(250.f, 0.12f);
|
||||
mPointCount[2] = 6;
|
||||
mbVisible[0] = mbVisible[1] = mbVisible[2] = true;
|
||||
mMax = ImVec2(1.f, 1.f);
|
||||
mMin = ImVec2(0.f, 0.f);
|
||||
}
|
||||
size_t GetCurveCount()
|
||||
{
|
||||
return 3;
|
||||
}
|
||||
|
||||
bool IsVisible(size_t curveIndex)
|
||||
{
|
||||
return mbVisible[curveIndex];
|
||||
}
|
||||
size_t GetPointCount(size_t curveIndex)
|
||||
{
|
||||
return mPointCount[curveIndex];
|
||||
}
|
||||
|
||||
uint32_t GetCurveColor(size_t curveIndex)
|
||||
{
|
||||
uint32_t cols[] = { 0xFF0000FF, 0xFF00FF00, 0xFFFF0000 };
|
||||
return cols[curveIndex];
|
||||
}
|
||||
ImVec2* GetPoints(size_t curveIndex)
|
||||
{
|
||||
return mPts[curveIndex];
|
||||
}
|
||||
virtual ImCurveEdit::CurveType GetCurveType(size_t curveIndex) const { return ImCurveEdit::CurveSmooth; }
|
||||
virtual int EditPoint(size_t curveIndex, int pointIndex, ImVec2 value)
|
||||
{
|
||||
mPts[curveIndex][pointIndex] = ImVec2(value.x, value.y);
|
||||
SortValues(curveIndex);
|
||||
for (size_t i = 0; i < GetPointCount(curveIndex); i++)
|
||||
{
|
||||
if (mPts[curveIndex][i].x == value.x)
|
||||
return (int)i;
|
||||
}
|
||||
return pointIndex;
|
||||
}
|
||||
virtual void AddPoint(size_t curveIndex, ImVec2 value)
|
||||
{
|
||||
if (mPointCount[curveIndex] >= 8)
|
||||
return;
|
||||
mPts[curveIndex][mPointCount[curveIndex]++] = value;
|
||||
SortValues(curveIndex);
|
||||
}
|
||||
virtual ImVec2& GetMax() { return mMax; }
|
||||
virtual ImVec2& GetMin() { return mMin; }
|
||||
virtual unsigned int GetBackgroundColor() { return 0; }
|
||||
ImVec2 mPts[3][8];
|
||||
size_t mPointCount[3];
|
||||
bool mbVisible[3];
|
||||
ImVec2 mMin;
|
||||
ImVec2 mMax;
|
||||
private:
|
||||
void SortValues(size_t curveIndex)
|
||||
{
|
||||
auto b = std::begin(mPts[curveIndex]);
|
||||
auto e = std::begin(mPts[curveIndex]) + GetPointCount(curveIndex);
|
||||
std::sort(b, e, [](ImVec2 a, ImVec2 b) { return a.x < b.x; });
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
struct MySequence : public ImSequencer::SequenceInterface
|
||||
{
|
||||
// interface with sequencer
|
||||
|
||||
virtual int GetFrameMin() const {
|
||||
return mFrameMin;
|
||||
}
|
||||
virtual int GetFrameMax() const {
|
||||
return mFrameMax;
|
||||
}
|
||||
virtual int GetItemCount() const { return (int)myItems.size(); }
|
||||
|
||||
virtual int GetItemTypeCount() const { return sizeof(SequencerItemTypeNames) / sizeof(char*); }
|
||||
virtual const char* GetItemTypeName(int typeIndex) const { return SequencerItemTypeNames[typeIndex]; }
|
||||
virtual const char* GetItemLabel(int index) const
|
||||
{
|
||||
static char tmps[512];
|
||||
snprintf(tmps, 512, "[%02d] %s", index, SequencerItemTypeNames[myItems[index].mType]);
|
||||
return tmps;
|
||||
}
|
||||
|
||||
virtual void Get(int index, int** start, int** end, int* type, unsigned int* color)
|
||||
{
|
||||
MySequenceItem& item = myItems[index];
|
||||
if (color)
|
||||
*color = 0xFFAA8080; // same color for everyone, return color based on type
|
||||
if (start)
|
||||
*start = &item.mFrameStart;
|
||||
if (end)
|
||||
*end = &item.mFrameEnd;
|
||||
if (type)
|
||||
*type = item.mType;
|
||||
}
|
||||
virtual void Add(int type) { myItems.push_back(MySequenceItem{ type, 0, 10, false }); };
|
||||
virtual void Del(int index) { myItems.erase(myItems.begin() + index); }
|
||||
virtual void Duplicate(int index) { myItems.push_back(myItems[index]); }
|
||||
|
||||
virtual size_t GetCustomHeight(int index) { return myItems[index].mExpanded ? 300 : 0; }
|
||||
|
||||
// my datas
|
||||
MySequence() : mFrameMin(0), mFrameMax(0) {}
|
||||
int mFrameMin, mFrameMax;
|
||||
struct MySequenceItem
|
||||
{
|
||||
int mType;
|
||||
int mFrameStart, mFrameEnd;
|
||||
bool mExpanded;
|
||||
};
|
||||
std::vector<MySequenceItem> myItems;
|
||||
RampEdit rampEdit;
|
||||
|
||||
virtual void DoubleClick(int index) {
|
||||
if (myItems[index].mExpanded)
|
||||
{
|
||||
myItems[index].mExpanded = false;
|
||||
return;
|
||||
}
|
||||
for (auto& item : myItems)
|
||||
item.mExpanded = false;
|
||||
myItems[index].mExpanded = !myItems[index].mExpanded;
|
||||
}
|
||||
|
||||
virtual void CustomDraw(int index, ImDrawList* draw_list, const ImRect& rc, const ImRect& legendRect, const ImRect& clippingRect, const ImRect& legendClippingRect)
|
||||
{
|
||||
static const char* labels[] = { "Translation", "Rotation" , "Scale" };
|
||||
|
||||
rampEdit.mMax = ImVec2(float(mFrameMax), 1.f);
|
||||
rampEdit.mMin = ImVec2(float(mFrameMin), 0.f);
|
||||
draw_list->PushClipRect(legendClippingRect.Min, legendClippingRect.Max, true);
|
||||
for (int i = 0; i < 3; i++)
|
||||
{
|
||||
ImVec2 pta(legendRect.Min.x + 30, legendRect.Min.y + i * 14.f);
|
||||
ImVec2 ptb(legendRect.Max.x, legendRect.Min.y + (i + 1) * 14.f);
|
||||
draw_list->AddText(pta, rampEdit.mbVisible[i] ? 0xFFFFFFFF : 0x80FFFFFF, labels[i]);
|
||||
if (ImRect(pta, ptb).Contains(ImGui::GetMousePos()) && ImGui::IsMouseClicked(0))
|
||||
rampEdit.mbVisible[i] = !rampEdit.mbVisible[i];
|
||||
}
|
||||
draw_list->PopClipRect();
|
||||
|
||||
ImGui::SetCursorScreenPos(rc.Min);
|
||||
ImCurveEdit::Edit(rampEdit, rc.Max - rc.Min, 137 + index, &clippingRect);
|
||||
}
|
||||
|
||||
virtual void CustomDrawCompact(int index, ImDrawList* draw_list, const ImRect& rc, const ImRect& clippingRect)
|
||||
{
|
||||
rampEdit.mMax = ImVec2(float(mFrameMax), 1.f);
|
||||
rampEdit.mMin = ImVec2(float(mFrameMin), 0.f);
|
||||
draw_list->PushClipRect(clippingRect.Min, clippingRect.Max, true);
|
||||
for (int i = 0; i < 3; i++)
|
||||
{
|
||||
for (int j = 0; j < rampEdit.mPointCount[i]; j++)
|
||||
{
|
||||
float p = rampEdit.mPts[i][j].x;
|
||||
if (p < myItems[index].mFrameStart || p > myItems[index].mFrameEnd)
|
||||
continue;
|
||||
float r = (p - mFrameMin) / float(mFrameMax - mFrameMin);
|
||||
float x = ImLerp(rc.Min.x, rc.Max.x, r);
|
||||
draw_list->AddLine(ImVec2(x, rc.Min.y + 6), ImVec2(x, rc.Max.y - 4), 0xAA000000, 4.f);
|
||||
}
|
||||
}
|
||||
draw_list->PopClipRect();
|
||||
}
|
||||
};
|
||||
|
||||
//
|
||||
//
|
||||
// GraphEditor interface
|
||||
//
|
||||
//
|
||||
|
||||
|
||||
template <typename T, std::size_t N>
|
||||
struct Array
|
||||
{
|
||||
T data[N];
|
||||
const size_t size() const { return N; }
|
||||
|
||||
const T operator [] (size_t index) const { return data[index]; }
|
||||
operator T* () {
|
||||
T* p = new T[N];
|
||||
memcpy(p, data, sizeof(data));
|
||||
return p;
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T, typename ... U>
|
||||
Array(T, U...) -> Array<T, 1 + sizeof...(U)>;
|
||||
|
||||
struct GraphEditorDelegate : public GraphEditor::Delegate
|
||||
{
|
||||
bool AllowedLink(GraphEditor::NodeIndex from, GraphEditor::NodeIndex to) override
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
void SelectNode(GraphEditor::NodeIndex nodeIndex, bool selected) override
|
||||
{
|
||||
mNodes[nodeIndex].mSelected = selected;
|
||||
}
|
||||
|
||||
void MoveSelectedNodes(const ImVec2 delta) override
|
||||
{
|
||||
for (auto& node : mNodes)
|
||||
{
|
||||
if (!node.mSelected)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
node.x += delta.x;
|
||||
node.y += delta.y;
|
||||
}
|
||||
}
|
||||
|
||||
virtual void RightClick(GraphEditor::NodeIndex nodeIndex, GraphEditor::SlotIndex slotIndexInput, GraphEditor::SlotIndex slotIndexOutput) override
|
||||
{
|
||||
}
|
||||
|
||||
void AddLink(GraphEditor::NodeIndex inputNodeIndex, GraphEditor::SlotIndex inputSlotIndex, GraphEditor::NodeIndex outputNodeIndex, GraphEditor::SlotIndex outputSlotIndex) override
|
||||
{
|
||||
mLinks.push_back({ inputNodeIndex, inputSlotIndex, outputNodeIndex, outputSlotIndex });
|
||||
}
|
||||
|
||||
void DelLink(GraphEditor::LinkIndex linkIndex) override
|
||||
{
|
||||
mLinks.erase(mLinks.begin() + linkIndex);
|
||||
}
|
||||
|
||||
void CustomDraw(ImDrawList* drawList, ImRect rectangle, GraphEditor::NodeIndex nodeIndex) override
|
||||
{
|
||||
drawList->AddLine(rectangle.Min, rectangle.Max, IM_COL32(0, 0, 0, 255));
|
||||
drawList->AddText(rectangle.Min, IM_COL32(255, 128, 64, 255), "Draw");
|
||||
}
|
||||
|
||||
const size_t GetTemplateCount() override
|
||||
{
|
||||
return sizeof(mTemplates) / sizeof(GraphEditor::Template);
|
||||
}
|
||||
|
||||
const GraphEditor::Template GetTemplate(GraphEditor::TemplateIndex index) override
|
||||
{
|
||||
return mTemplates[index];
|
||||
}
|
||||
|
||||
const size_t GetNodeCount() override
|
||||
{
|
||||
return mNodes.size();
|
||||
}
|
||||
|
||||
const GraphEditor::Node GetNode(GraphEditor::NodeIndex index) override
|
||||
{
|
||||
const auto& myNode = mNodes[index];
|
||||
return GraphEditor::Node
|
||||
{
|
||||
myNode.name,
|
||||
myNode.templateIndex,
|
||||
ImRect(ImVec2(myNode.x, myNode.y), ImVec2(myNode.x + 200, myNode.y + 200)),
|
||||
myNode.mSelected
|
||||
};
|
||||
}
|
||||
|
||||
const size_t GetLinkCount() override
|
||||
{
|
||||
return mLinks.size();
|
||||
}
|
||||
|
||||
const GraphEditor::Link GetLink(GraphEditor::LinkIndex index) override
|
||||
{
|
||||
return mLinks[index];
|
||||
}
|
||||
|
||||
// Graph datas
|
||||
static const inline GraphEditor::Template mTemplates[] = {
|
||||
{
|
||||
IM_COL32(160, 160, 180, 255),
|
||||
IM_COL32(100, 100, 140, 255),
|
||||
IM_COL32(110, 110, 150, 255),
|
||||
1,
|
||||
Array{"MyInput"},
|
||||
nullptr,
|
||||
2,
|
||||
Array{"MyOutput0", "MyOuput1"},
|
||||
nullptr
|
||||
},
|
||||
|
||||
{
|
||||
IM_COL32(180, 160, 160, 255),
|
||||
IM_COL32(140, 100, 100, 255),
|
||||
IM_COL32(150, 110, 110, 255),
|
||||
3,
|
||||
nullptr,
|
||||
Array{ IM_COL32(200,100,100,255), IM_COL32(100,200,100,255), IM_COL32(100,100,200,255) },
|
||||
1,
|
||||
Array{"MyOutput0"},
|
||||
Array{ IM_COL32(200,200,200,255)}
|
||||
}
|
||||
};
|
||||
|
||||
struct Node
|
||||
{
|
||||
const char* name;
|
||||
GraphEditor::TemplateIndex templateIndex;
|
||||
float x, y;
|
||||
bool mSelected;
|
||||
};
|
||||
|
||||
std::vector<Node> mNodes = {
|
||||
{
|
||||
"My Node 0",
|
||||
0,
|
||||
0, 0,
|
||||
false
|
||||
},
|
||||
|
||||
{
|
||||
"My Node 1",
|
||||
0,
|
||||
400, 0,
|
||||
false
|
||||
},
|
||||
|
||||
{
|
||||
"My Node 2",
|
||||
1,
|
||||
400, 400,
|
||||
false
|
||||
}
|
||||
};
|
||||
|
||||
std::vector<GraphEditor::Link> mLinks = { {0, 0, 1, 0} };
|
||||
};
|
||||
|
||||
|
||||
int main(int, char**)
|
||||
{
|
||||
ImApp::ImApp imApp;
|
||||
|
||||
ImApp::Config config;
|
||||
config.mWidth = 1280;
|
||||
config.mHeight = 720;
|
||||
//config.mFullscreen = true;
|
||||
imApp.Init(config);
|
||||
|
||||
int lastUsing = 0;
|
||||
|
||||
float cameraView[16] =
|
||||
{ 1.f, 0.f, 0.f, 0.f,
|
||||
0.f, 1.f, 0.f, 0.f,
|
||||
0.f, 0.f, 1.f, 0.f,
|
||||
0.f, 0.f, 0.f, 1.f };
|
||||
|
||||
float cameraProjection[16];
|
||||
|
||||
// build a procedural texture. Copy/pasted and adapted from https://rosettacode.org/wiki/Plasma_effect#Graphics_version
|
||||
unsigned int procTexture;
|
||||
glGenTextures(1, &procTexture);
|
||||
glBindTexture(GL_TEXTURE_2D, procTexture);
|
||||
uint32_t* tempBitmap = new uint32_t[256 * 256];
|
||||
int index = 0;
|
||||
for (int y = 0; y < 256; y++)
|
||||
{
|
||||
for (int x = 0; x < 256; x++)
|
||||
{
|
||||
float dx = x + .5f;
|
||||
float dy = y + .5f;
|
||||
float dv = sinf(x * 0.02f) + sinf(0.03f * (x + y)) + sinf(sqrtf(0.4f * (dx * dx + dy * dy) + 1.f));
|
||||
|
||||
tempBitmap[index] = 0xFF000000 +
|
||||
(int(255 * fabsf(sinf(dv * 3.141592f))) << 16) +
|
||||
(int(255 * fabsf(sinf(dv * 3.141592f + 2 * 3.141592f / 3))) << 8) +
|
||||
(int(255 * fabs(sin(dv * 3.141592f + 4.f * 3.141592f / 3.f))));
|
||||
|
||||
index++;
|
||||
}
|
||||
}
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 256, 256, 0, GL_RGBA, GL_UNSIGNED_BYTE, tempBitmap);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
delete [] tempBitmap;
|
||||
|
||||
// sequence with default values
|
||||
MySequence mySequence;
|
||||
mySequence.mFrameMin = -100;
|
||||
mySequence.mFrameMax = 1000;
|
||||
mySequence.myItems.push_back(MySequence::MySequenceItem{ 0, 10, 30, false });
|
||||
mySequence.myItems.push_back(MySequence::MySequenceItem{ 1, 20, 30, true });
|
||||
mySequence.myItems.push_back(MySequence::MySequenceItem{ 3, 12, 60, false });
|
||||
mySequence.myItems.push_back(MySequence::MySequenceItem{ 2, 61, 90, false });
|
||||
mySequence.myItems.push_back(MySequence::MySequenceItem{ 4, 90, 99, false });
|
||||
|
||||
// Camera projection
|
||||
bool isPerspective = true;
|
||||
float fov = 27.f;
|
||||
float viewWidth = 10.f; // for orthographic
|
||||
float camYAngle = 165.f / 180.f * 3.14159f;
|
||||
float camXAngle = 32.f / 180.f * 3.14159f;
|
||||
|
||||
bool firstFrame = true;
|
||||
|
||||
// Main loop
|
||||
while (!imApp.Done())
|
||||
{
|
||||
imApp.NewFrame();
|
||||
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
if (isPerspective)
|
||||
{
|
||||
Perspective(fov, io.DisplaySize.x / io.DisplaySize.y, 0.1f, 100.f, cameraProjection);
|
||||
}
|
||||
else
|
||||
{
|
||||
float viewHeight = viewWidth * io.DisplaySize.y / io.DisplaySize.x;
|
||||
OrthoGraphic(-viewWidth, viewWidth, -viewHeight, viewHeight, 1000.f, -1000.f, cameraProjection);
|
||||
}
|
||||
ImGuizmo::SetOrthographic(!isPerspective);
|
||||
ImGuizmo::BeginFrame();
|
||||
|
||||
ImGui::SetNextWindowPos(ImVec2(1024, 100));
|
||||
ImGui::SetNextWindowSize(ImVec2(256, 256));
|
||||
|
||||
// create a window and insert the inspector
|
||||
ImGui::SetNextWindowPos(ImVec2(10, 10));
|
||||
ImGui::SetNextWindowSize(ImVec2(320, 340));
|
||||
ImGui::Begin("Editor");
|
||||
if (ImGui::RadioButton("Full view", !useWindow)) useWindow = false;
|
||||
ImGui::SameLine();
|
||||
if (ImGui::RadioButton("Window", useWindow)) useWindow = true;
|
||||
|
||||
ImGui::Text("Camera");
|
||||
bool viewDirty = false;
|
||||
if (ImGui::RadioButton("Perspective", isPerspective)) isPerspective = true;
|
||||
ImGui::SameLine();
|
||||
if (ImGui::RadioButton("Orthographic", !isPerspective)) isPerspective = false;
|
||||
if (isPerspective)
|
||||
{
|
||||
ImGui::SliderFloat("Fov", &fov, 20.f, 110.f);
|
||||
}
|
||||
else
|
||||
{
|
||||
ImGui::SliderFloat("Ortho width", &viewWidth, 1, 20);
|
||||
}
|
||||
viewDirty |= ImGui::SliderFloat("Distance", &camDistance, 1.f, 10.f);
|
||||
ImGui::SliderInt("Gizmo count", &gizmoCount, 1, 4);
|
||||
|
||||
if (viewDirty || firstFrame)
|
||||
{
|
||||
float eye[] = { cosf(camYAngle) * cosf(camXAngle) * camDistance, sinf(camXAngle) * camDistance, sinf(camYAngle) * cosf(camXAngle) * camDistance };
|
||||
float at[] = { 0.f, 0.f, 0.f };
|
||||
float up[] = { 0.f, 1.f, 0.f };
|
||||
LookAt(eye, at, up, cameraView);
|
||||
firstFrame = false;
|
||||
}
|
||||
|
||||
ImGui::Text("X: %f Y: %f", io.MousePos.x, io.MousePos.y);
|
||||
if (ImGuizmo::IsUsing())
|
||||
{
|
||||
ImGui::Text("Using gizmo");
|
||||
}
|
||||
else
|
||||
{
|
||||
ImGui::Text(ImGuizmo::IsOver()?"Over gizmo":"");
|
||||
ImGui::SameLine();
|
||||
ImGui::Text(ImGuizmo::IsOver(ImGuizmo::TRANSLATE) ? "Over translate gizmo" : "");
|
||||
ImGui::SameLine();
|
||||
ImGui::Text(ImGuizmo::IsOver(ImGuizmo::ROTATE) ? "Over rotate gizmo" : "");
|
||||
ImGui::SameLine();
|
||||
ImGui::Text(ImGuizmo::IsOver(ImGuizmo::SCALE) ? "Over scale gizmo" : "");
|
||||
}
|
||||
ImGui::Separator();
|
||||
for (int matId = 0; matId < gizmoCount; matId++)
|
||||
{
|
||||
ImGuizmo::SetID(matId);
|
||||
|
||||
EditTransform(cameraView, cameraProjection, objectMatrix[matId], lastUsing == matId);
|
||||
if (ImGuizmo::IsUsing())
|
||||
{
|
||||
lastUsing = matId;
|
||||
}
|
||||
}
|
||||
|
||||
ImGui::End();
|
||||
|
||||
ImGui::SetNextWindowPos(ImVec2(10, 350));
|
||||
|
||||
ImGui::SetNextWindowSize(ImVec2(940, 480));
|
||||
ImGui::Begin("Other controls");
|
||||
if (ImGui::CollapsingHeader("Zoom Slider"))
|
||||
{
|
||||
static float uMin = 0.4f, uMax = 0.6f;
|
||||
static float vMin = 0.4f, vMax = 0.6f;
|
||||
ImGui::Image((ImTextureID)(uint64_t)procTexture, ImVec2(900,300), ImVec2(uMin, vMin), ImVec2(uMax, vMax));
|
||||
{
|
||||
ImGui::SameLine();
|
||||
ImGui::PushID(18);
|
||||
ImZoomSlider::ImZoomSlider(0.f, 1.f, vMin, vMax, 0.01f, ImZoomSlider::ImGuiZoomSliderFlags_Vertical);
|
||||
ImGui::PopID();
|
||||
}
|
||||
|
||||
{
|
||||
ImGui::PushID(19);
|
||||
ImZoomSlider::ImZoomSlider(0.f, 1.f, uMin, uMax);
|
||||
ImGui::PopID();
|
||||
}
|
||||
}
|
||||
if (ImGui::CollapsingHeader("Sequencer"))
|
||||
{
|
||||
// let's create the sequencer
|
||||
static int selectedEntry = -1;
|
||||
static int firstFrame = 0;
|
||||
static bool expanded = true;
|
||||
static int currentFrame = 100;
|
||||
|
||||
ImGui::PushItemWidth(130);
|
||||
ImGui::InputInt("Frame Min", &mySequence.mFrameMin);
|
||||
ImGui::SameLine();
|
||||
ImGui::InputInt("Frame ", ¤tFrame);
|
||||
ImGui::SameLine();
|
||||
ImGui::InputInt("Frame Max", &mySequence.mFrameMax);
|
||||
ImGui::PopItemWidth();
|
||||
Sequencer(&mySequence, ¤tFrame, &expanded, &selectedEntry, &firstFrame, ImSequencer::SEQUENCER_EDIT_STARTEND | ImSequencer::SEQUENCER_ADD | ImSequencer::SEQUENCER_DEL | ImSequencer::SEQUENCER_COPYPASTE | ImSequencer::SEQUENCER_CHANGE_FRAME);
|
||||
// add a UI to edit that particular item
|
||||
if (selectedEntry != -1)
|
||||
{
|
||||
const MySequence::MySequenceItem &item = mySequence.myItems[selectedEntry];
|
||||
ImGui::Text("I am a %s, please edit me", SequencerItemTypeNames[item.mType]);
|
||||
// switch (type) ....
|
||||
}
|
||||
}
|
||||
|
||||
// Graph Editor
|
||||
static GraphEditor::Options options;
|
||||
static GraphEditorDelegate delegate;
|
||||
static GraphEditor::ViewState viewState;
|
||||
static GraphEditor::FitOnScreen fit = GraphEditor::Fit_None;
|
||||
static bool showGraphEditor = true;
|
||||
|
||||
if (ImGui::CollapsingHeader("Graph Editor"))
|
||||
{
|
||||
ImGui::Checkbox("Show GraphEditor", &showGraphEditor);
|
||||
GraphEditor::EditOptions(options);
|
||||
}
|
||||
|
||||
ImGui::End();
|
||||
|
||||
if (showGraphEditor)
|
||||
{
|
||||
ImGui::Begin("Graph Editor", NULL, 0);
|
||||
if (ImGui::Button("Fit all nodes"))
|
||||
{
|
||||
fit = GraphEditor::Fit_AllNodes;
|
||||
}
|
||||
ImGui::SameLine();
|
||||
if (ImGui::Button("Fit selected nodes"))
|
||||
{
|
||||
fit = GraphEditor::Fit_SelectedNodes;
|
||||
}
|
||||
GraphEditor::Show(delegate, options, viewState, true, &fit);
|
||||
|
||||
ImGui::End();
|
||||
}
|
||||
|
||||
|
||||
// render everything
|
||||
glClearColor(0.45f, 0.4f, 0.4f, 1.f);
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
imApp.EndFrame();
|
||||
}
|
||||
|
||||
imApp.Finish();
|
||||
|
||||
return 0;
|
||||
}
|
||||
9
src/ThirdParty/ImGuizmo/vcpkg-example/vcpkg.json
vendored
Normal file
9
src/ThirdParty/ImGuizmo/vcpkg-example/vcpkg.json
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"name": "vcpkg-example",
|
||||
"version": "1.83",
|
||||
"dependencies": [
|
||||
"imgui",
|
||||
"imguizmo",
|
||||
"stb"
|
||||
]
|
||||
}
|
||||
311
src/ThirdParty/glad/KHR/khrplatform.h
vendored
Normal file
311
src/ThirdParty/glad/KHR/khrplatform.h
vendored
Normal file
@@ -0,0 +1,311 @@
|
||||
#ifndef __khrplatform_h_
|
||||
#define __khrplatform_h_
|
||||
|
||||
/*
|
||||
** Copyright (c) 2008-2018 The Khronos Group Inc.
|
||||
**
|
||||
** Permission is hereby granted, free of charge, to any person obtaining a
|
||||
** copy of this software and/or associated documentation files (the
|
||||
** "Materials"), to deal in the Materials without restriction, including
|
||||
** without limitation the rights to use, copy, modify, merge, publish,
|
||||
** distribute, sublicense, and/or sell copies of the Materials, and to
|
||||
** permit persons to whom the Materials are furnished to do so, subject to
|
||||
** the following conditions:
|
||||
**
|
||||
** The above copyright notice and this permission notice shall be included
|
||||
** in all copies or substantial portions of the Materials.
|
||||
**
|
||||
** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
|
||||
*/
|
||||
|
||||
/* Khronos platform-specific types and definitions.
|
||||
*
|
||||
* The master copy of khrplatform.h is maintained in the Khronos EGL
|
||||
* Registry repository at https://github.com/KhronosGroup/EGL-Registry
|
||||
* The last semantic modification to khrplatform.h was at commit ID:
|
||||
* 67a3e0864c2d75ea5287b9f3d2eb74a745936692
|
||||
*
|
||||
* Adopters may modify this file to suit their platform. Adopters are
|
||||
* encouraged to submit platform specific modifications to the Khronos
|
||||
* group so that they can be included in future versions of this file.
|
||||
* Please submit changes by filing pull requests or issues on
|
||||
* the EGL Registry repository linked above.
|
||||
*
|
||||
*
|
||||
* See the Implementer's Guidelines for information about where this file
|
||||
* should be located on your system and for more details of its use:
|
||||
* http://www.khronos.org/registry/implementers_guide.pdf
|
||||
*
|
||||
* This file should be included as
|
||||
* #include <KHR/khrplatform.h>
|
||||
* by Khronos client API header files that use its types and defines.
|
||||
*
|
||||
* The types in khrplatform.h should only be used to define API-specific types.
|
||||
*
|
||||
* Types defined in khrplatform.h:
|
||||
* khronos_int8_t signed 8 bit
|
||||
* khronos_uint8_t unsigned 8 bit
|
||||
* khronos_int16_t signed 16 bit
|
||||
* khronos_uint16_t unsigned 16 bit
|
||||
* khronos_int32_t signed 32 bit
|
||||
* khronos_uint32_t unsigned 32 bit
|
||||
* khronos_int64_t signed 64 bit
|
||||
* khronos_uint64_t unsigned 64 bit
|
||||
* khronos_intptr_t signed same number of bits as a pointer
|
||||
* khronos_uintptr_t unsigned same number of bits as a pointer
|
||||
* khronos_ssize_t signed size
|
||||
* khronos_usize_t unsigned size
|
||||
* khronos_float_t signed 32 bit floating point
|
||||
* khronos_time_ns_t unsigned 64 bit time in nanoseconds
|
||||
* khronos_utime_nanoseconds_t unsigned time interval or absolute time in
|
||||
* nanoseconds
|
||||
* khronos_stime_nanoseconds_t signed time interval in nanoseconds
|
||||
* khronos_boolean_enum_t enumerated boolean type. This should
|
||||
* only be used as a base type when a client API's boolean type is
|
||||
* an enum. Client APIs which use an integer or other type for
|
||||
* booleans cannot use this as the base type for their boolean.
|
||||
*
|
||||
* Tokens defined in khrplatform.h:
|
||||
*
|
||||
* KHRONOS_FALSE, KHRONOS_TRUE Enumerated boolean false/true values.
|
||||
*
|
||||
* KHRONOS_SUPPORT_INT64 is 1 if 64 bit integers are supported; otherwise 0.
|
||||
* KHRONOS_SUPPORT_FLOAT is 1 if floats are supported; otherwise 0.
|
||||
*
|
||||
* Calling convention macros defined in this file:
|
||||
* KHRONOS_APICALL
|
||||
* KHRONOS_APIENTRY
|
||||
* KHRONOS_APIATTRIBUTES
|
||||
*
|
||||
* These may be used in function prototypes as:
|
||||
*
|
||||
* KHRONOS_APICALL void KHRONOS_APIENTRY funcname(
|
||||
* int arg1,
|
||||
* int arg2) KHRONOS_APIATTRIBUTES;
|
||||
*/
|
||||
|
||||
#if defined(__SCITECH_SNAP__) && !defined(KHRONOS_STATIC)
|
||||
# define KHRONOS_STATIC 1
|
||||
#endif
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
* Definition of KHRONOS_APICALL
|
||||
*-------------------------------------------------------------------------
|
||||
* This precedes the return type of the function in the function prototype.
|
||||
*/
|
||||
#if defined(KHRONOS_STATIC)
|
||||
/* If the preprocessor constant KHRONOS_STATIC is defined, make the
|
||||
* header compatible with static linking. */
|
||||
# define KHRONOS_APICALL
|
||||
#elif defined(_WIN32)
|
||||
# define KHRONOS_APICALL __declspec(dllimport)
|
||||
#elif defined (__SYMBIAN32__)
|
||||
# define KHRONOS_APICALL IMPORT_C
|
||||
#elif defined(__ANDROID__)
|
||||
# define KHRONOS_APICALL __attribute__((visibility("default")))
|
||||
#else
|
||||
# define KHRONOS_APICALL
|
||||
#endif
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
* Definition of KHRONOS_APIENTRY
|
||||
*-------------------------------------------------------------------------
|
||||
* This follows the return type of the function and precedes the function
|
||||
* name in the function prototype.
|
||||
*/
|
||||
#if defined(_WIN32) && !defined(_WIN32_WCE) && !defined(__SCITECH_SNAP__)
|
||||
/* Win32 but not WinCE */
|
||||
# define KHRONOS_APIENTRY __stdcall
|
||||
#else
|
||||
# define KHRONOS_APIENTRY
|
||||
#endif
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
* Definition of KHRONOS_APIATTRIBUTES
|
||||
*-------------------------------------------------------------------------
|
||||
* This follows the closing parenthesis of the function prototype arguments.
|
||||
*/
|
||||
#if defined (__ARMCC_2__)
|
||||
#define KHRONOS_APIATTRIBUTES __softfp
|
||||
#else
|
||||
#define KHRONOS_APIATTRIBUTES
|
||||
#endif
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
* basic type definitions
|
||||
*-----------------------------------------------------------------------*/
|
||||
#if (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L) || defined(__GNUC__) || defined(__SCO__) || defined(__USLC__)
|
||||
|
||||
|
||||
/*
|
||||
* Using <stdint.h>
|
||||
*/
|
||||
#include <stdint.h>
|
||||
typedef int32_t khronos_int32_t;
|
||||
typedef uint32_t khronos_uint32_t;
|
||||
typedef int64_t khronos_int64_t;
|
||||
typedef uint64_t khronos_uint64_t;
|
||||
#define KHRONOS_SUPPORT_INT64 1
|
||||
#define KHRONOS_SUPPORT_FLOAT 1
|
||||
/*
|
||||
* To support platform where unsigned long cannot be used interchangeably with
|
||||
* inptr_t (e.g. CHERI-extended ISAs), we can use the stdint.h intptr_t.
|
||||
* Ideally, we could just use (u)intptr_t everywhere, but this could result in
|
||||
* ABI breakage if khronos_uintptr_t is changed from unsigned long to
|
||||
* unsigned long long or similar (this results in different C++ name mangling).
|
||||
* To avoid changes for existing platforms, we restrict usage of intptr_t to
|
||||
* platforms where the size of a pointer is larger than the size of long.
|
||||
*/
|
||||
#if defined(__SIZEOF_LONG__) && defined(__SIZEOF_POINTER__)
|
||||
#if __SIZEOF_POINTER__ > __SIZEOF_LONG__
|
||||
#define KHRONOS_USE_INTPTR_T
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#elif defined(__VMS ) || defined(__sgi)
|
||||
|
||||
/*
|
||||
* Using <inttypes.h>
|
||||
*/
|
||||
#include <inttypes.h>
|
||||
typedef int32_t khronos_int32_t;
|
||||
typedef uint32_t khronos_uint32_t;
|
||||
typedef int64_t khronos_int64_t;
|
||||
typedef uint64_t khronos_uint64_t;
|
||||
#define KHRONOS_SUPPORT_INT64 1
|
||||
#define KHRONOS_SUPPORT_FLOAT 1
|
||||
|
||||
#elif defined(_WIN32) && !defined(__SCITECH_SNAP__)
|
||||
|
||||
/*
|
||||
* Win32
|
||||
*/
|
||||
typedef __int32 khronos_int32_t;
|
||||
typedef unsigned __int32 khronos_uint32_t;
|
||||
typedef __int64 khronos_int64_t;
|
||||
typedef unsigned __int64 khronos_uint64_t;
|
||||
#define KHRONOS_SUPPORT_INT64 1
|
||||
#define KHRONOS_SUPPORT_FLOAT 1
|
||||
|
||||
#elif defined(__sun__) || defined(__digital__)
|
||||
|
||||
/*
|
||||
* Sun or Digital
|
||||
*/
|
||||
typedef int khronos_int32_t;
|
||||
typedef unsigned int khronos_uint32_t;
|
||||
#if defined(__arch64__) || defined(_LP64)
|
||||
typedef long int khronos_int64_t;
|
||||
typedef unsigned long int khronos_uint64_t;
|
||||
#else
|
||||
typedef long long int khronos_int64_t;
|
||||
typedef unsigned long long int khronos_uint64_t;
|
||||
#endif /* __arch64__ */
|
||||
#define KHRONOS_SUPPORT_INT64 1
|
||||
#define KHRONOS_SUPPORT_FLOAT 1
|
||||
|
||||
#elif 0
|
||||
|
||||
/*
|
||||
* Hypothetical platform with no float or int64 support
|
||||
*/
|
||||
typedef int khronos_int32_t;
|
||||
typedef unsigned int khronos_uint32_t;
|
||||
#define KHRONOS_SUPPORT_INT64 0
|
||||
#define KHRONOS_SUPPORT_FLOAT 0
|
||||
|
||||
#else
|
||||
|
||||
/*
|
||||
* Generic fallback
|
||||
*/
|
||||
#include <stdint.h>
|
||||
typedef int32_t khronos_int32_t;
|
||||
typedef uint32_t khronos_uint32_t;
|
||||
typedef int64_t khronos_int64_t;
|
||||
typedef uint64_t khronos_uint64_t;
|
||||
#define KHRONOS_SUPPORT_INT64 1
|
||||
#define KHRONOS_SUPPORT_FLOAT 1
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
* Types that are (so far) the same on all platforms
|
||||
*/
|
||||
typedef signed char khronos_int8_t;
|
||||
typedef unsigned char khronos_uint8_t;
|
||||
typedef signed short int khronos_int16_t;
|
||||
typedef unsigned short int khronos_uint16_t;
|
||||
|
||||
/*
|
||||
* Types that differ between LLP64 and LP64 architectures - in LLP64,
|
||||
* pointers are 64 bits, but 'long' is still 32 bits. Win64 appears
|
||||
* to be the only LLP64 architecture in current use.
|
||||
*/
|
||||
#ifdef KHRONOS_USE_INTPTR_T
|
||||
typedef intptr_t khronos_intptr_t;
|
||||
typedef uintptr_t khronos_uintptr_t;
|
||||
#elif defined(_WIN64)
|
||||
typedef signed long long int khronos_intptr_t;
|
||||
typedef unsigned long long int khronos_uintptr_t;
|
||||
#else
|
||||
typedef signed long int khronos_intptr_t;
|
||||
typedef unsigned long int khronos_uintptr_t;
|
||||
#endif
|
||||
|
||||
#if defined(_WIN64)
|
||||
typedef signed long long int khronos_ssize_t;
|
||||
typedef unsigned long long int khronos_usize_t;
|
||||
#else
|
||||
typedef signed long int khronos_ssize_t;
|
||||
typedef unsigned long int khronos_usize_t;
|
||||
#endif
|
||||
|
||||
#if KHRONOS_SUPPORT_FLOAT
|
||||
/*
|
||||
* Float type
|
||||
*/
|
||||
typedef float khronos_float_t;
|
||||
#endif
|
||||
|
||||
#if KHRONOS_SUPPORT_INT64
|
||||
/* Time types
|
||||
*
|
||||
* These types can be used to represent a time interval in nanoseconds or
|
||||
* an absolute Unadjusted System Time. Unadjusted System Time is the number
|
||||
* of nanoseconds since some arbitrary system event (e.g. since the last
|
||||
* time the system booted). The Unadjusted System Time is an unsigned
|
||||
* 64 bit value that wraps back to 0 every 584 years. Time intervals
|
||||
* may be either signed or unsigned.
|
||||
*/
|
||||
typedef khronos_uint64_t khronos_utime_nanoseconds_t;
|
||||
typedef khronos_int64_t khronos_stime_nanoseconds_t;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Dummy value used to pad enum types to 32 bits.
|
||||
*/
|
||||
#ifndef KHRONOS_MAX_ENUM
|
||||
#define KHRONOS_MAX_ENUM 0x7FFFFFFF
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Enumerated boolean type
|
||||
*
|
||||
* Values other than zero should be considered to be true. Therefore
|
||||
* comparisons should not be made against KHRONOS_TRUE.
|
||||
*/
|
||||
typedef enum {
|
||||
KHRONOS_FALSE = 0,
|
||||
KHRONOS_TRUE = 1,
|
||||
KHRONOS_BOOLEAN_ENUM_FORCE_SIZE = KHRONOS_MAX_ENUM
|
||||
} khronos_boolean_enum_t;
|
||||
|
||||
#endif /* __khrplatform_h_ */
|
||||
2532
src/ThirdParty/glad/glad.c
vendored
Normal file
2532
src/ThirdParty/glad/glad.c
vendored
Normal file
File diff suppressed because it is too large
Load Diff
5169
src/ThirdParty/glad/glad/glad.h
vendored
Normal file
5169
src/ThirdParty/glad/glad/glad.h
vendored
Normal file
File diff suppressed because it is too large
Load Diff
48
src/ThirdParty/glfw/CMake/GenerateMappings.cmake
vendored
Normal file
48
src/ThirdParty/glfw/CMake/GenerateMappings.cmake
vendored
Normal file
@@ -0,0 +1,48 @@
|
||||
# Usage:
|
||||
# cmake -P GenerateMappings.cmake <path/to/mappings.h.in> <path/to/mappings.h>
|
||||
|
||||
set(source_url "https://raw.githubusercontent.com/gabomdq/SDL_GameControllerDB/master/gamecontrollerdb.txt")
|
||||
set(source_path "${CMAKE_CURRENT_BINARY_DIR}/gamecontrollerdb.txt")
|
||||
set(template_path "${CMAKE_ARGV3}")
|
||||
set(target_path "${CMAKE_ARGV4}")
|
||||
|
||||
if (NOT EXISTS "${template_path}")
|
||||
message(FATAL_ERROR "Failed to find template file ${template_path}")
|
||||
endif()
|
||||
|
||||
file(DOWNLOAD "${source_url}" "${source_path}"
|
||||
STATUS download_status
|
||||
TLS_VERIFY on)
|
||||
|
||||
list(GET download_status 0 status_code)
|
||||
list(GET download_status 1 status_message)
|
||||
|
||||
if (status_code)
|
||||
message(FATAL_ERROR "Failed to download ${source_url}: ${status_message}")
|
||||
endif()
|
||||
|
||||
file(STRINGS "${source_path}" lines)
|
||||
foreach(line ${lines})
|
||||
if (line MATCHES "^[0-9a-fA-F]")
|
||||
if (line MATCHES "platform:Windows")
|
||||
if (GLFW_WIN32_MAPPINGS)
|
||||
string(APPEND GLFW_WIN32_MAPPINGS "\n")
|
||||
endif()
|
||||
string(APPEND GLFW_WIN32_MAPPINGS "\"${line}\",")
|
||||
elseif (line MATCHES "platform:Mac OS X")
|
||||
if (GLFW_COCOA_MAPPINGS)
|
||||
string(APPEND GLFW_COCOA_MAPPINGS "\n")
|
||||
endif()
|
||||
string(APPEND GLFW_COCOA_MAPPINGS "\"${line}\",")
|
||||
elseif (line MATCHES "platform:Linux")
|
||||
if (GLFW_LINUX_MAPPINGS)
|
||||
string(APPEND GLFW_LINUX_MAPPINGS "\n")
|
||||
endif()
|
||||
string(APPEND GLFW_LINUX_MAPPINGS "\"${line}\",")
|
||||
endif()
|
||||
endif()
|
||||
endforeach()
|
||||
|
||||
configure_file("${template_path}" "${target_path}" @ONLY NEWLINE_STYLE UNIX)
|
||||
file(REMOVE "${source_path}")
|
||||
|
||||
38
src/ThirdParty/glfw/CMake/Info.plist.in
vendored
Normal file
38
src/ThirdParty/glfw/CMake/Info.plist.in
vendored
Normal file
@@ -0,0 +1,38 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>CFBundleDevelopmentRegion</key>
|
||||
<string>English</string>
|
||||
<key>CFBundleExecutable</key>
|
||||
<string>${MACOSX_BUNDLE_EXECUTABLE_NAME}</string>
|
||||
<key>CFBundleGetInfoString</key>
|
||||
<string>${MACOSX_BUNDLE_INFO_STRING}</string>
|
||||
<key>CFBundleIconFile</key>
|
||||
<string>${MACOSX_BUNDLE_ICON_FILE}</string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>${MACOSX_BUNDLE_GUI_IDENTIFIER}</string>
|
||||
<key>CFBundleInfoDictionaryVersion</key>
|
||||
<string>6.0</string>
|
||||
<key>CFBundleLongVersionString</key>
|
||||
<string>${MACOSX_BUNDLE_LONG_VERSION_STRING}</string>
|
||||
<key>CFBundleName</key>
|
||||
<string>${MACOSX_BUNDLE_BUNDLE_NAME}</string>
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>APPL</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>${MACOSX_BUNDLE_SHORT_VERSION_STRING}</string>
|
||||
<key>CFBundleSignature</key>
|
||||
<string>????</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>${MACOSX_BUNDLE_BUNDLE_VERSION}</string>
|
||||
<key>CSResourcesFileMapped</key>
|
||||
<true/>
|
||||
<key>LSRequiresCarbon</key>
|
||||
<true/>
|
||||
<key>NSHumanReadableCopyright</key>
|
||||
<string>${MACOSX_BUNDLE_COPYRIGHT}</string>
|
||||
<key>NSHighResolutionCapable</key>
|
||||
<true/>
|
||||
</dict>
|
||||
</plist>
|
||||
29
src/ThirdParty/glfw/CMake/cmake_uninstall.cmake.in
vendored
Normal file
29
src/ThirdParty/glfw/CMake/cmake_uninstall.cmake.in
vendored
Normal file
@@ -0,0 +1,29 @@
|
||||
|
||||
if (NOT EXISTS "@GLFW_BINARY_DIR@/install_manifest.txt")
|
||||
message(FATAL_ERROR "Cannot find install manifest: \"@GLFW_BINARY_DIR@/install_manifest.txt\"")
|
||||
endif()
|
||||
|
||||
file(READ "@GLFW_BINARY_DIR@/install_manifest.txt" files)
|
||||
string(REGEX REPLACE "\n" ";" files "${files}")
|
||||
|
||||
foreach (file ${files})
|
||||
message(STATUS "Uninstalling \"$ENV{DESTDIR}${file}\"")
|
||||
if (EXISTS "$ENV{DESTDIR}${file}")
|
||||
exec_program("@CMAKE_COMMAND@" ARGS "-E remove \"$ENV{DESTDIR}${file}\""
|
||||
OUTPUT_VARIABLE rm_out
|
||||
RETURN_VALUE rm_retval)
|
||||
if (NOT "${rm_retval}" STREQUAL 0)
|
||||
MESSAGE(FATAL_ERROR "Problem when removing \"$ENV{DESTDIR}${file}\"")
|
||||
endif()
|
||||
elseif (IS_SYMLINK "$ENV{DESTDIR}${file}")
|
||||
EXEC_PROGRAM("@CMAKE_COMMAND@" ARGS "-E remove \"$ENV{DESTDIR}${file}\""
|
||||
OUTPUT_VARIABLE rm_out
|
||||
RETURN_VALUE rm_retval)
|
||||
if (NOT "${rm_retval}" STREQUAL 0)
|
||||
message(FATAL_ERROR "Problem when removing symlink \"$ENV{DESTDIR}${file}\"")
|
||||
endif()
|
||||
else()
|
||||
message(STATUS "File \"$ENV{DESTDIR}${file}\" does not exist.")
|
||||
endif()
|
||||
endforeach()
|
||||
|
||||
13
src/ThirdParty/glfw/CMake/glfw3.pc.in
vendored
Normal file
13
src/ThirdParty/glfw/CMake/glfw3.pc.in
vendored
Normal file
@@ -0,0 +1,13 @@
|
||||
prefix=@CMAKE_INSTALL_PREFIX@
|
||||
exec_prefix=${prefix}
|
||||
includedir=@CMAKE_INSTALL_FULL_INCLUDEDIR@
|
||||
libdir=@CMAKE_INSTALL_FULL_LIBDIR@
|
||||
|
||||
Name: GLFW
|
||||
Description: A multi-platform library for OpenGL, window and input
|
||||
Version: @GLFW_VERSION@
|
||||
URL: https://www.glfw.org/
|
||||
Requires.private: @GLFW_PKG_CONFIG_REQUIRES_PRIVATE@
|
||||
Libs: -L${libdir} -l@GLFW_LIB_NAME@
|
||||
Libs.private: @GLFW_PKG_CONFIG_LIBS_PRIVATE@
|
||||
Cflags: -I${includedir}
|
||||
3
src/ThirdParty/glfw/CMake/glfw3Config.cmake.in
vendored
Normal file
3
src/ThirdParty/glfw/CMake/glfw3Config.cmake.in
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
include(CMakeFindDependencyMacro)
|
||||
find_dependency(Threads)
|
||||
include("${CMAKE_CURRENT_LIST_DIR}/glfw3Targets.cmake")
|
||||
13
src/ThirdParty/glfw/CMake/i686-w64-mingw32-clang.cmake
vendored
Normal file
13
src/ThirdParty/glfw/CMake/i686-w64-mingw32-clang.cmake
vendored
Normal file
@@ -0,0 +1,13 @@
|
||||
# Define the environment for cross-compiling with 32-bit MinGW-w64 Clang
|
||||
SET(CMAKE_SYSTEM_NAME Windows) # Target system name
|
||||
SET(CMAKE_SYSTEM_VERSION 1)
|
||||
SET(CMAKE_C_COMPILER "i686-w64-mingw32-clang")
|
||||
SET(CMAKE_CXX_COMPILER "i686-w64-mingw32-clang++")
|
||||
SET(CMAKE_RC_COMPILER "i686-w64-mingw32-windres")
|
||||
SET(CMAKE_RANLIB "i686-w64-mingw32-ranlib")
|
||||
|
||||
# Configure the behaviour of the find commands
|
||||
SET(CMAKE_FIND_ROOT_PATH "/usr/i686-w64-mingw32")
|
||||
SET(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
|
||||
SET(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
|
||||
SET(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
|
||||
13
src/ThirdParty/glfw/CMake/i686-w64-mingw32.cmake
vendored
Normal file
13
src/ThirdParty/glfw/CMake/i686-w64-mingw32.cmake
vendored
Normal file
@@ -0,0 +1,13 @@
|
||||
# Define the environment for cross-compiling with 32-bit MinGW-w64 GCC
|
||||
SET(CMAKE_SYSTEM_NAME Windows) # Target system name
|
||||
SET(CMAKE_SYSTEM_VERSION 1)
|
||||
SET(CMAKE_C_COMPILER "i686-w64-mingw32-gcc")
|
||||
SET(CMAKE_CXX_COMPILER "i686-w64-mingw32-g++")
|
||||
SET(CMAKE_RC_COMPILER "i686-w64-mingw32-windres")
|
||||
SET(CMAKE_RANLIB "i686-w64-mingw32-ranlib")
|
||||
|
||||
# Configure the behaviour of the find commands
|
||||
SET(CMAKE_FIND_ROOT_PATH "/usr/i686-w64-mingw32")
|
||||
SET(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
|
||||
SET(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
|
||||
SET(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
|
||||
17
src/ThirdParty/glfw/CMake/modules/FindEpollShim.cmake
vendored
Normal file
17
src/ThirdParty/glfw/CMake/modules/FindEpollShim.cmake
vendored
Normal file
@@ -0,0 +1,17 @@
|
||||
# Find EpollShim
|
||||
# Once done, this will define
|
||||
#
|
||||
# EPOLLSHIM_FOUND - System has EpollShim
|
||||
# EPOLLSHIM_INCLUDE_DIRS - The EpollShim include directories
|
||||
# EPOLLSHIM_LIBRARIES - The libraries needed to use EpollShim
|
||||
|
||||
find_path(EPOLLSHIM_INCLUDE_DIRS NAMES sys/epoll.h sys/timerfd.h HINTS /usr/local/include/libepoll-shim)
|
||||
find_library(EPOLLSHIM_LIBRARIES NAMES epoll-shim libepoll-shim HINTS /usr/local/lib)
|
||||
|
||||
if (EPOLLSHIM_INCLUDE_DIRS AND EPOLLSHIM_LIBRARIES)
|
||||
set(EPOLLSHIM_FOUND TRUE)
|
||||
endif (EPOLLSHIM_INCLUDE_DIRS AND EPOLLSHIM_LIBRARIES)
|
||||
|
||||
include(FindPackageHandleStandardArgs)
|
||||
find_package_handle_standard_args(EpollShim DEFAULT_MSG EPOLLSHIM_LIBRARIES EPOLLSHIM_INCLUDE_DIRS)
|
||||
mark_as_advanced(EPOLLSHIM_INCLUDE_DIRS EPOLLSHIM_LIBRARIES)
|
||||
18
src/ThirdParty/glfw/CMake/modules/FindOSMesa.cmake
vendored
Normal file
18
src/ThirdParty/glfw/CMake/modules/FindOSMesa.cmake
vendored
Normal file
@@ -0,0 +1,18 @@
|
||||
# Try to find OSMesa on a Unix system
|
||||
#
|
||||
# This will define:
|
||||
#
|
||||
# OSMESA_LIBRARIES - Link these to use OSMesa
|
||||
# OSMESA_INCLUDE_DIR - Include directory for OSMesa
|
||||
#
|
||||
# Copyright (c) 2014 Brandon Schaefer <brandon.schaefer@canonical.com>
|
||||
|
||||
if (NOT WIN32)
|
||||
|
||||
find_package (PkgConfig)
|
||||
pkg_check_modules (PKG_OSMESA QUIET osmesa)
|
||||
|
||||
set (OSMESA_INCLUDE_DIR ${PKG_OSMESA_INCLUDE_DIRS})
|
||||
set (OSMESA_LIBRARIES ${PKG_OSMESA_LIBRARIES})
|
||||
|
||||
endif ()
|
||||
13
src/ThirdParty/glfw/CMake/x86_64-w64-mingw32-clang.cmake
vendored
Normal file
13
src/ThirdParty/glfw/CMake/x86_64-w64-mingw32-clang.cmake
vendored
Normal file
@@ -0,0 +1,13 @@
|
||||
# Define the environment for cross-compiling with 64-bit MinGW-w64 Clang
|
||||
SET(CMAKE_SYSTEM_NAME Windows) # Target system name
|
||||
SET(CMAKE_SYSTEM_VERSION 1)
|
||||
SET(CMAKE_C_COMPILER "x86_64-w64-mingw32-clang")
|
||||
SET(CMAKE_CXX_COMPILER "x86_64-w64-mingw32-clang++")
|
||||
SET(CMAKE_RC_COMPILER "x86_64-w64-mingw32-windres")
|
||||
SET(CMAKE_RANLIB "x86_64-w64-mingw32-ranlib")
|
||||
|
||||
# Configure the behaviour of the find commands
|
||||
SET(CMAKE_FIND_ROOT_PATH "/usr/x86_64-w64-mingw32")
|
||||
SET(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
|
||||
SET(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
|
||||
SET(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
|
||||
13
src/ThirdParty/glfw/CMake/x86_64-w64-mingw32.cmake
vendored
Normal file
13
src/ThirdParty/glfw/CMake/x86_64-w64-mingw32.cmake
vendored
Normal file
@@ -0,0 +1,13 @@
|
||||
# Define the environment for cross-compiling with 64-bit MinGW-w64 GCC
|
||||
SET(CMAKE_SYSTEM_NAME Windows) # Target system name
|
||||
SET(CMAKE_SYSTEM_VERSION 1)
|
||||
SET(CMAKE_C_COMPILER "x86_64-w64-mingw32-gcc")
|
||||
SET(CMAKE_CXX_COMPILER "x86_64-w64-mingw32-g++")
|
||||
SET(CMAKE_RC_COMPILER "x86_64-w64-mingw32-windres")
|
||||
SET(CMAKE_RANLIB "x86_64-w64-mingw32-ranlib")
|
||||
|
||||
# Configure the behaviour of the find commands
|
||||
SET(CMAKE_FIND_ROOT_PATH "/usr/x86_64-w64-mingw32")
|
||||
SET(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
|
||||
SET(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
|
||||
SET(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
|
||||
179
src/ThirdParty/glfw/CMakeLists.txt
vendored
Normal file
179
src/ThirdParty/glfw/CMakeLists.txt
vendored
Normal file
@@ -0,0 +1,179 @@
|
||||
cmake_minimum_required(VERSION 3.4...3.20 FATAL_ERROR)
|
||||
|
||||
project(GLFW VERSION 3.4.0 LANGUAGES C)
|
||||
|
||||
set(CMAKE_LEGACY_CYGWIN_WIN32 OFF)
|
||||
|
||||
if (POLICY CMP0054)
|
||||
cmake_policy(SET CMP0054 NEW)
|
||||
endif()
|
||||
|
||||
if (POLICY CMP0069)
|
||||
cmake_policy(SET CMP0069 NEW)
|
||||
endif()
|
||||
|
||||
if (POLICY CMP0077)
|
||||
cmake_policy(SET CMP0077 NEW)
|
||||
endif()
|
||||
|
||||
set_property(GLOBAL PROPERTY USE_FOLDERS ON)
|
||||
|
||||
if (CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR)
|
||||
set(GLFW_STANDALONE TRUE)
|
||||
endif()
|
||||
|
||||
option(BUILD_SHARED_LIBS "Build shared libraries" OFF)
|
||||
option(GLFW_BUILD_EXAMPLES "Build the GLFW example programs" ${GLFW_STANDALONE})
|
||||
option(GLFW_BUILD_TESTS "Build the GLFW test programs" ${GLFW_STANDALONE})
|
||||
option(GLFW_BUILD_DOCS "Build the GLFW documentation" ON)
|
||||
option(GLFW_INSTALL "Generate installation target" ON)
|
||||
|
||||
include(GNUInstallDirs)
|
||||
include(CMakeDependentOption)
|
||||
|
||||
if (GLFW_USE_OSMESA)
|
||||
message(FATAL_ERROR "GLFW_USE_OSMESA has been removed; set the GLFW_PLATFORM init hint")
|
||||
endif()
|
||||
|
||||
cmake_dependent_option(GLFW_BUILD_WIN32 "Build support for Win32" ON "WIN32" OFF)
|
||||
cmake_dependent_option(GLFW_BUILD_COCOA "Build support for Cocoa" ON "APPLE" OFF)
|
||||
cmake_dependent_option(GLFW_BUILD_X11 "Build support for X11" ON "UNIX;NOT APPLE" OFF)
|
||||
cmake_dependent_option(GLFW_BUILD_WAYLAND "Build support for Wayland"
|
||||
"${GLFW_USE_WAYLAND}" "UNIX;NOT APPLE" OFF)
|
||||
|
||||
cmake_dependent_option(GLFW_USE_HYBRID_HPG "Force use of high-performance GPU on hybrid systems" OFF
|
||||
"WIN32" OFF)
|
||||
cmake_dependent_option(USE_MSVC_RUNTIME_LIBRARY_DLL "Use MSVC runtime library DLL" ON
|
||||
"MSVC" OFF)
|
||||
|
||||
set(GLFW_LIBRARY_TYPE "${GLFW_LIBRARY_TYPE}" CACHE STRING
|
||||
"Library type override for GLFW (SHARED, STATIC, OBJECT, or empty to follow BUILD_SHARED_LIBS)")
|
||||
|
||||
if (GLFW_LIBRARY_TYPE)
|
||||
if (GLFW_LIBRARY_TYPE STREQUAL "SHARED")
|
||||
set(GLFW_BUILD_SHARED_LIBRARY TRUE)
|
||||
else()
|
||||
set(GLFW_BUILD_SHARED_LIBRARY FALSE)
|
||||
endif()
|
||||
else()
|
||||
set(GLFW_BUILD_SHARED_LIBRARY ${BUILD_SHARED_LIBS})
|
||||
endif()
|
||||
|
||||
list(APPEND CMAKE_MODULE_PATH "${GLFW_SOURCE_DIR}/CMake/modules")
|
||||
|
||||
find_package(Threads REQUIRED)
|
||||
|
||||
if (GLFW_BUILD_DOCS)
|
||||
set(DOXYGEN_SKIP_DOT TRUE)
|
||||
find_package(Doxygen)
|
||||
endif()
|
||||
|
||||
#--------------------------------------------------------------------
|
||||
# Report backend selection
|
||||
#--------------------------------------------------------------------
|
||||
if (GLFW_BUILD_WIN32)
|
||||
message(STATUS "Including Win32 support")
|
||||
endif()
|
||||
if (GLFW_BUILD_COCOA)
|
||||
message(STATUS "Including Cocoa support")
|
||||
endif()
|
||||
if (GLFW_BUILD_WAYLAND)
|
||||
message(STATUS "Including Wayland support")
|
||||
endif()
|
||||
if (GLFW_BUILD_X11)
|
||||
message(STATUS "Including X11 support")
|
||||
endif()
|
||||
|
||||
#--------------------------------------------------------------------
|
||||
# Apply Microsoft C runtime library option
|
||||
# This is here because it also applies to tests and examples
|
||||
#--------------------------------------------------------------------
|
||||
if (MSVC AND NOT USE_MSVC_RUNTIME_LIBRARY_DLL)
|
||||
if (CMAKE_VERSION VERSION_LESS 3.15)
|
||||
foreach (flag CMAKE_C_FLAGS
|
||||
CMAKE_C_FLAGS_DEBUG
|
||||
CMAKE_C_FLAGS_RELEASE
|
||||
CMAKE_C_FLAGS_MINSIZEREL
|
||||
CMAKE_C_FLAGS_RELWITHDEBINFO)
|
||||
|
||||
if (flag MATCHES "/MD")
|
||||
string(REGEX REPLACE "/MD" "/MT" ${flag} "${${flag}}")
|
||||
endif()
|
||||
if (flag MATCHES "/MDd")
|
||||
string(REGEX REPLACE "/MDd" "/MTd" ${flag} "${${flag}}")
|
||||
endif()
|
||||
|
||||
endforeach()
|
||||
else()
|
||||
set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
#--------------------------------------------------------------------
|
||||
# Create generated files
|
||||
#--------------------------------------------------------------------
|
||||
include(CMakePackageConfigHelpers)
|
||||
|
||||
set(GLFW_CONFIG_PATH "${CMAKE_INSTALL_LIBDIR}/cmake/glfw3")
|
||||
|
||||
configure_package_config_file(CMake/glfw3Config.cmake.in
|
||||
src/glfw3Config.cmake
|
||||
INSTALL_DESTINATION "${GLFW_CONFIG_PATH}"
|
||||
NO_CHECK_REQUIRED_COMPONENTS_MACRO)
|
||||
|
||||
write_basic_package_version_file(src/glfw3ConfigVersion.cmake
|
||||
VERSION ${GLFW_VERSION}
|
||||
COMPATIBILITY SameMajorVersion)
|
||||
|
||||
#--------------------------------------------------------------------
|
||||
# Add subdirectories
|
||||
#--------------------------------------------------------------------
|
||||
add_subdirectory(src)
|
||||
|
||||
if (GLFW_BUILD_EXAMPLES)
|
||||
add_subdirectory(examples)
|
||||
endif()
|
||||
|
||||
if (GLFW_BUILD_TESTS)
|
||||
add_subdirectory(tests)
|
||||
endif()
|
||||
|
||||
if (DOXYGEN_FOUND AND GLFW_BUILD_DOCS)
|
||||
add_subdirectory(docs)
|
||||
endif()
|
||||
|
||||
#--------------------------------------------------------------------
|
||||
# Install files other than the library
|
||||
# The library is installed by src/CMakeLists.txt
|
||||
#--------------------------------------------------------------------
|
||||
if (GLFW_INSTALL)
|
||||
install(DIRECTORY include/GLFW DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}
|
||||
FILES_MATCHING PATTERN glfw3.h PATTERN glfw3native.h)
|
||||
|
||||
install(FILES "${GLFW_BINARY_DIR}/src/glfw3Config.cmake"
|
||||
"${GLFW_BINARY_DIR}/src/glfw3ConfigVersion.cmake"
|
||||
DESTINATION "${GLFW_CONFIG_PATH}")
|
||||
|
||||
install(EXPORT glfwTargets FILE glfw3Targets.cmake
|
||||
EXPORT_LINK_INTERFACE_LIBRARIES
|
||||
DESTINATION "${GLFW_CONFIG_PATH}")
|
||||
install(FILES "${GLFW_BINARY_DIR}/src/glfw3.pc"
|
||||
DESTINATION "${CMAKE_INSTALL_LIBDIR}/pkgconfig")
|
||||
|
||||
if (DOXYGEN_FOUND AND GLFW_BUILD_DOCS)
|
||||
install(DIRECTORY "${GLFW_BINARY_DIR}/docs/html"
|
||||
DESTINATION "${CMAKE_INSTALL_DOCDIR}")
|
||||
endif()
|
||||
|
||||
# Only generate this target if no higher-level project already has
|
||||
if (NOT TARGET uninstall)
|
||||
configure_file(CMake/cmake_uninstall.cmake.in
|
||||
cmake_uninstall.cmake IMMEDIATE @ONLY)
|
||||
|
||||
add_custom_target(uninstall
|
||||
"${CMAKE_COMMAND}" -P
|
||||
"${GLFW_BINARY_DIR}/cmake_uninstall.cmake")
|
||||
set_target_properties(uninstall PROPERTIES FOLDER "GLFW3")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
235
src/ThirdParty/glfw/CONTRIBUTORS.md
vendored
Normal file
235
src/ThirdParty/glfw/CONTRIBUTORS.md
vendored
Normal file
@@ -0,0 +1,235 @@
|
||||
# Acknowledgements
|
||||
|
||||
GLFW exists because people around the world donated their time and lent their
|
||||
skills. This list only includes contributions to the main repository and
|
||||
excludes other invaluable contributions like language bindings and text and
|
||||
video tutorials.
|
||||
|
||||
- Bobyshev Alexander
|
||||
- Laurent Aphecetche
|
||||
- Matt Arsenault
|
||||
- ashishgamedev
|
||||
- David Avedissian
|
||||
- Keith Bauer
|
||||
- John Bartholomew
|
||||
- Coşku Baş
|
||||
- Niklas Behrens
|
||||
- Andrew Belt
|
||||
- Nevyn Bengtsson
|
||||
- Niklas Bergström
|
||||
- Denis Bernard
|
||||
- Doug Binks
|
||||
- blanco
|
||||
- Waris Boonyasiriwat
|
||||
- Kyle Brenneman
|
||||
- Rok Breulj
|
||||
- Kai Burjack
|
||||
- Martin Capitanio
|
||||
- Nicolas Caramelli
|
||||
- David Carlier
|
||||
- Arturo Castro
|
||||
- Chi-kwan Chan
|
||||
- Joseph Chua
|
||||
- Ian Clarkson
|
||||
- Michał Cichoń
|
||||
- Lambert Clara
|
||||
- Anna Clarke
|
||||
- Josh Codd
|
||||
- Yaron Cohen-Tal
|
||||
- Omar Cornut
|
||||
- Andrew Corrigan
|
||||
- Bailey Cosier
|
||||
- Noel Cower
|
||||
- CuriouserThing
|
||||
- Jason Daly
|
||||
- Jarrod Davis
|
||||
- Olivier Delannoy
|
||||
- Paul R. Deppe
|
||||
- Michael Dickens
|
||||
- Роман Донченко
|
||||
- Mario Dorn
|
||||
- Wolfgang Draxinger
|
||||
- Jonathan Dummer
|
||||
- Ralph Eastwood
|
||||
- Fredrik Ehnbom
|
||||
- Robin Eklind
|
||||
- Jan Ekström
|
||||
- Siavash Eliasi
|
||||
- Ahmad Fatoum
|
||||
- Felipe Ferreira
|
||||
- Michael Fogleman
|
||||
- Jason Francis
|
||||
- Gerald Franz
|
||||
- Mário Freitas
|
||||
- GeO4d
|
||||
- Marcus Geelnard
|
||||
- ghuser404
|
||||
- Charles Giessen
|
||||
- Ryan C. Gordon
|
||||
- Stephen Gowen
|
||||
- Kovid Goyal
|
||||
- Eloi Marín Gratacós
|
||||
- Stefan Gustavson
|
||||
- Andrew Gutekanst
|
||||
- Stephen Gutekanst
|
||||
- Jonathan Hale
|
||||
- hdf89shfdfs
|
||||
- Sylvain Hellegouarch
|
||||
- Matthew Henry
|
||||
- heromyth
|
||||
- Lucas Hinderberger
|
||||
- Paul Holden
|
||||
- Warren Hu
|
||||
- Charles Huber
|
||||
- InKryption
|
||||
- IntellectualKitty
|
||||
- Aaron Jacobs
|
||||
- Erik S. V. Jansson
|
||||
- Toni Jovanoski
|
||||
- Arseny Kapoulkine
|
||||
- Cem Karan
|
||||
- Osman Keskin
|
||||
- Koray Kilinc
|
||||
- Josh Kilmer
|
||||
- Byunghoon Kim
|
||||
- Cameron King
|
||||
- Peter Knut
|
||||
- Christoph Kubisch
|
||||
- Yuri Kunde Schlesner
|
||||
- Rokas Kupstys
|
||||
- Konstantin Käfer
|
||||
- Eric Larson
|
||||
- Francis Lecavalier
|
||||
- Jong Won Lee
|
||||
- Robin Leffmann
|
||||
- Glenn Lewis
|
||||
- Shane Liesegang
|
||||
- Anders Lindqvist
|
||||
- Leon Linhart
|
||||
- Marco Lizza
|
||||
- Eyal Lotem
|
||||
- Aaron Loucks
|
||||
- Luflosi
|
||||
- lukect
|
||||
- Tristam MacDonald
|
||||
- Hans Mackowiak
|
||||
- Дмитри Малышев
|
||||
- Zbigniew Mandziejewicz
|
||||
- Adam Marcus
|
||||
- Célestin Marot
|
||||
- Kyle McDonald
|
||||
- David V. McKay
|
||||
- David Medlock
|
||||
- Bryce Mehring
|
||||
- Jonathan Mercier
|
||||
- Marcel Metz
|
||||
- Liam Middlebrook
|
||||
- Ave Milia
|
||||
- Jonathan Miller
|
||||
- Kenneth Miller
|
||||
- Bruce Mitchener
|
||||
- Jack Moffitt
|
||||
- Jeff Molofee
|
||||
- Alexander Monakov
|
||||
- Pierre Morel
|
||||
- Jon Morton
|
||||
- Pierre Moulon
|
||||
- Martins Mozeiko
|
||||
- Pascal Muetschard
|
||||
- Julian Møller
|
||||
- ndogxj
|
||||
- n3rdopolis
|
||||
- Kristian Nielsen
|
||||
- Kamil Nowakowski
|
||||
- onox
|
||||
- Denis Ovod
|
||||
- Ozzy
|
||||
- Andri Pálsson
|
||||
- luz paz
|
||||
- Peoro
|
||||
- Braden Pellett
|
||||
- Christopher Pelloux
|
||||
- Arturo J. Pérez
|
||||
- Vladimir Perminov
|
||||
- Anthony Pesch
|
||||
- Orson Peters
|
||||
- Emmanuel Gil Peyrot
|
||||
- Cyril Pichard
|
||||
- Keith Pitt
|
||||
- Stanislav Podgorskiy
|
||||
- Konstantin Podsvirov
|
||||
- Nathan Poirier
|
||||
- Alexandre Pretyman
|
||||
- Pablo Prietz
|
||||
- przemekmirek
|
||||
- pthom
|
||||
- Guillaume Racicot
|
||||
- Philip Rideout
|
||||
- Eddie Ringle
|
||||
- Max Risuhin
|
||||
- Jorge Rodriguez
|
||||
- Jari Ronkainen
|
||||
- Luca Rood
|
||||
- Ed Ropple
|
||||
- Aleksey Rybalkin
|
||||
- Mikko Rytkönen
|
||||
- Riku Salminen
|
||||
- Brandon Schaefer
|
||||
- Sebastian Schuberth
|
||||
- Christian Sdunek
|
||||
- Matt Sealey
|
||||
- Steve Sexton
|
||||
- Arkady Shapkin
|
||||
- Ali Sherief
|
||||
- Yoshiki Shibukawa
|
||||
- Dmitri Shuralyov
|
||||
- Daniel Sieger
|
||||
- Daniel Skorupski
|
||||
- Anthony Smith
|
||||
- Bradley Smith
|
||||
- Cliff Smolinsky
|
||||
- Patrick Snape
|
||||
- Erlend Sogge Heggen
|
||||
- Julian Squires
|
||||
- Johannes Stein
|
||||
- Pontus Stenetorp
|
||||
- Michael Stocker
|
||||
- Justin Stoecker
|
||||
- Elviss Strazdins
|
||||
- Paul Sultana
|
||||
- Nathan Sweet
|
||||
- TTK-Bandit
|
||||
- Jared Tiala
|
||||
- Sergey Tikhomirov
|
||||
- Arthur Tombs
|
||||
- Ioannis Tsakpinis
|
||||
- Samuli Tuomola
|
||||
- Matthew Turner
|
||||
- urraka
|
||||
- Elias Vanderstuyft
|
||||
- Stef Velzel
|
||||
- Jari Vetoniemi
|
||||
- Ricardo Vieira
|
||||
- Nicholas Vitovitch
|
||||
- Simon Voordouw
|
||||
- Corentin Wallez
|
||||
- Torsten Walluhn
|
||||
- Patrick Walton
|
||||
- Xo Wang
|
||||
- Jay Weisskopf
|
||||
- Frank Wille
|
||||
- Andy Williams
|
||||
- Joel Winarske
|
||||
- Richard A. Wilkes
|
||||
- Tatsuya Yatagawa
|
||||
- Ryogo Yoshimura
|
||||
- Lukas Zanner
|
||||
- Andrey Zholos
|
||||
- Aihui Zhu
|
||||
- Santi Zupancic
|
||||
- Jonas Ådahl
|
||||
- Lasse Öörni
|
||||
- Leonard König
|
||||
- All the unmentioned and anonymous contributors in the GLFW community, for bug
|
||||
reports, patches, feedback, testing and encouragement
|
||||
|
||||
23
src/ThirdParty/glfw/LICENSE.md
vendored
Normal file
23
src/ThirdParty/glfw/LICENSE.md
vendored
Normal file
@@ -0,0 +1,23 @@
|
||||
Copyright (c) 2002-2006 Marcus Geelnard
|
||||
|
||||
Copyright (c) 2006-2019 Camilla Löwy
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgment in the product documentation would
|
||||
be appreciated but is not required.
|
||||
|
||||
2. Altered source versions must be plainly marked as such, and must not
|
||||
be misrepresented as being the original software.
|
||||
|
||||
3. This notice may not be removed or altered from any source
|
||||
distribution.
|
||||
|
||||
324
src/ThirdParty/glfw/README.md
vendored
Normal file
324
src/ThirdParty/glfw/README.md
vendored
Normal file
@@ -0,0 +1,324 @@
|
||||
# GLFW
|
||||
|
||||
[](https://github.com/glfw/glfw/actions)
|
||||
[](https://ci.appveyor.com/project/elmindreda/glfw)
|
||||
[](https://scan.coverity.com/projects/glfw-glfw)
|
||||
|
||||
## Introduction
|
||||
|
||||
GLFW is an Open Source, multi-platform library for OpenGL, OpenGL ES and Vulkan
|
||||
application development. It provides a simple, platform-independent API for
|
||||
creating windows, contexts and surfaces, reading input, handling events, etc.
|
||||
|
||||
GLFW natively supports Windows, macOS and Linux and other Unix-like systems. On
|
||||
Linux both X11 and Wayland are supported.
|
||||
|
||||
GLFW is licensed under the [zlib/libpng
|
||||
license](https://www.glfw.org/license.html).
|
||||
|
||||
You can [download](https://www.glfw.org/download.html) the latest stable release
|
||||
as source or Windows binaries, or fetch the `latest` branch from GitHub. Each
|
||||
release starting with 3.0 also has a corresponding [annotated
|
||||
tag](https://github.com/glfw/glfw/releases) with source and binary archives.
|
||||
|
||||
The [documentation](https://www.glfw.org/docs/latest/) is available online and is
|
||||
included in all source and binary archives. See the [release
|
||||
notes](https://www.glfw.org/docs/latest/news.html) for new features, caveats and
|
||||
deprecations in the latest release. For more details see the [version
|
||||
history](https://www.glfw.org/changelog.html).
|
||||
|
||||
The `master` branch is the stable integration branch and _should_ always compile
|
||||
and run on all supported platforms, although details of newly added features may
|
||||
change until they have been included in a release. New features and many bug
|
||||
fixes live in [other branches](https://github.com/glfw/glfw/branches/all) until
|
||||
they are stable enough to merge.
|
||||
|
||||
If you are new to GLFW, you may find the
|
||||
[tutorial](https://www.glfw.org/docs/latest/quick.html) for GLFW 3 useful. If
|
||||
you have used GLFW 2 in the past, there is a [transition
|
||||
guide](https://www.glfw.org/docs/latest/moving.html) for moving to the GLFW
|
||||
3 API.
|
||||
|
||||
GLFW exists because of the contributions of [many people](CONTRIBUTORS.md)
|
||||
around the world, whether by reporting bugs, providing community support, adding
|
||||
features, reviewing or testing code, debugging, proofreading docs, suggesting
|
||||
features or fixing bugs.
|
||||
|
||||
|
||||
## Compiling GLFW
|
||||
|
||||
GLFW itself requires only the headers and libraries for your OS and window
|
||||
system. It does not need the headers for any context creation API (WGL, GLX,
|
||||
EGL, NSGL, OSMesa) or rendering API (OpenGL, OpenGL ES, Vulkan) to enable
|
||||
support for them.
|
||||
|
||||
GLFW supports compilation on Windows with Visual C++ 2010 and later, MinGW and
|
||||
MinGW-w64, on macOS with Clang and on Linux and other Unix-like systems with GCC
|
||||
and Clang. It will likely compile in other environments as well, but this is
|
||||
not regularly tested.
|
||||
|
||||
There are [pre-compiled Windows binaries](https://www.glfw.org/download.html)
|
||||
available for all supported compilers.
|
||||
|
||||
See the [compilation guide](https://www.glfw.org/docs/latest/compile.html) for
|
||||
more information about how to compile GLFW yourself.
|
||||
|
||||
|
||||
## Using GLFW
|
||||
|
||||
See the [documentation](https://www.glfw.org/docs/latest/) for tutorials, guides
|
||||
and the API reference.
|
||||
|
||||
|
||||
## Contributing to GLFW
|
||||
|
||||
See the [contribution
|
||||
guide](https://github.com/glfw/glfw/blob/master/docs/CONTRIBUTING.md) for
|
||||
more information.
|
||||
|
||||
|
||||
## System requirements
|
||||
|
||||
GLFW supports Windows XP and later and macOS 10.8 and later. Linux and other
|
||||
Unix-like systems running the X Window System are supported even without
|
||||
a desktop environment or modern extensions, although some features require
|
||||
a running window or clipboard manager. The OSMesa backend requires Mesa 6.3.
|
||||
|
||||
See the [compatibility guide](https://www.glfw.org/docs/latest/compat.html)
|
||||
in the documentation for more information.
|
||||
|
||||
|
||||
## Dependencies
|
||||
|
||||
GLFW itself needs only CMake 3.1 or later and the headers and libraries for your
|
||||
OS and window system.
|
||||
|
||||
The examples and test programs depend on a number of tiny libraries. These are
|
||||
located in the `deps/` directory.
|
||||
|
||||
- [getopt\_port](https://github.com/kimgr/getopt_port/) for examples
|
||||
with command-line options
|
||||
- [TinyCThread](https://github.com/tinycthread/tinycthread) for threaded
|
||||
examples
|
||||
- [glad2](https://github.com/Dav1dde/glad) for loading OpenGL and Vulkan
|
||||
functions
|
||||
- [linmath.h](https://github.com/datenwolf/linmath.h) for linear algebra in
|
||||
examples
|
||||
- [Nuklear](https://github.com/Immediate-Mode-UI/Nuklear) for test and example UI
|
||||
- [stb\_image\_write](https://github.com/nothings/stb) for writing images to disk
|
||||
|
||||
The documentation is generated with [Doxygen](https://doxygen.org/) if CMake can
|
||||
find that tool.
|
||||
|
||||
|
||||
## Reporting bugs
|
||||
|
||||
Bugs are reported to our [issue tracker](https://github.com/glfw/glfw/issues).
|
||||
Please check the [contribution
|
||||
guide](https://github.com/glfw/glfw/blob/master/docs/CONTRIBUTING.md) for
|
||||
information on what to include when reporting a bug.
|
||||
|
||||
|
||||
## Changelog
|
||||
|
||||
- Added `GLFW_PLATFORM` init hint for runtime platform selection (#1958)
|
||||
- Added `GLFW_ANY_PLATFORM`, `GLFW_PLATFORM_WIN32`, `GLFW_PLATFORM_COCOA`,
|
||||
`GLFW_PLATFORM_WAYLAND`, `GLFW_PLATFORM_X11` and `GLFW_PLATFORM_NULL` symbols to
|
||||
specify the desired platform (#1958)
|
||||
- Added `glfwGetPlatform` function to query what platform was selected (#1655,#1958)
|
||||
- Added `glfwPlatformSupported` function to query if a platform is supported
|
||||
(#1655,#1958)
|
||||
- Added `glfwInitAllocator` for setting a custom memory allocator (#544,#1628,#1947)
|
||||
- Added `GLFWallocator` struct and `GLFWallocatefun`, `GLFWreallocatefun` and
|
||||
`GLFWdeallocatefun` types (#544,#1628,#1947)
|
||||
- Added `glfwInitVulkanLoader` for using a non-default Vulkan loader (#1374,#1890)
|
||||
- Added `GLFW_RESIZE_NWSE_CURSOR`, `GLFW_RESIZE_NESW_CURSOR`,
|
||||
`GLFW_RESIZE_ALL_CURSOR` and `GLFW_NOT_ALLOWED_CURSOR` cursor shapes (#427)
|
||||
- Added `GLFW_RESIZE_EW_CURSOR` alias for `GLFW_HRESIZE_CURSOR` (#427)
|
||||
- Added `GLFW_RESIZE_NS_CURSOR` alias for `GLFW_VRESIZE_CURSOR` (#427)
|
||||
- Added `GLFW_POINTING_HAND_CURSOR` alias for `GLFW_HAND_CURSOR` (#427)
|
||||
- Added `GLFW_MOUSE_PASSTHROUGH` window hint for letting mouse input pass
|
||||
through the window (#1236,#1568)
|
||||
- Added `GLFW_PLATFORM_UNAVAILABLE` error for platform detection failures (#1958)
|
||||
- Added `GLFW_FEATURE_UNAVAILABLE` error for platform limitations (#1692)
|
||||
- Added `GLFW_FEATURE_UNIMPLEMENTED` error for incomplete backends (#1692)
|
||||
- Added `GLFW_ANGLE_PLATFORM_TYPE` init hint and `GLFW_ANGLE_PLATFORM_TYPE_*`
|
||||
values to select ANGLE backend (#1380)
|
||||
- Added `GLFW_X11_XCB_VULKAN_SURFACE` init hint for selecting X11 Vulkan
|
||||
surface extension (#1793)
|
||||
- Added `GLFW_BUILD_WIN32` CMake option for enabling Win32 support (#1958)
|
||||
- Added `GLFW_BUILD_COCOA` CMake option for enabling Cocoa support (#1958)
|
||||
- Added `GLFW_BUILD_X11` CMake option for enabling X11 support (#1958)
|
||||
- Added `GLFW_LIBRARY_TYPE` CMake variable for overriding the library type
|
||||
(#279,#1307,#1497,#1574,#1928)
|
||||
- Added `GLFW_PKG_CONFIG_REQUIRES_PRIVATE` and `GLFW_PKG_CONFIG_LIBS_PRIVATE` CMake
|
||||
variables exposing pkg-config dependencies (#1307)
|
||||
- Made joystick subsystem initialize at first use (#1284,#1646)
|
||||
- Made `GLFW_DOUBLEBUFFER` a read-only window attribute
|
||||
- Updated the minimum required CMake version to 3.1
|
||||
- Updated gamepad mappings from upstream
|
||||
- Disabled tests and examples by default when built as a CMake subdirectory
|
||||
- Renamed `GLFW_USE_WAYLAND` CMake option to `GLFW_BUILD_WAYLAND` (#1958)
|
||||
- Removed `GLFW_USE_OSMESA` CMake option enabling the Null platform (#1958)
|
||||
- Removed CMake generated configuration header
|
||||
- Bugfix: The CMake config-file package used an absolute path and was not
|
||||
relocatable (#1470)
|
||||
- Bugfix: Video modes with a duplicate screen area were discarded (#1555,#1556)
|
||||
- Bugfix: Compiling with -Wextra-semi caused warnings (#1440)
|
||||
- Bugfix: Built-in mappings failed because some OEMs re-used VID/PID (#1583)
|
||||
- Bugfix: Some extension loader headers did not prevent default OpenGL header
|
||||
inclusion (#1695)
|
||||
- Bugfix: Buffers were swapped at creation on single-buffered windows (#1873)
|
||||
- Bugfix: Gamepad mapping updates could spam `GLFW_INVALID_VALUE` due to
|
||||
incompatible controllers sharing hardware ID (#1763)
|
||||
- Bugfix: Native access functions for context handles did not check that the API matched
|
||||
- [Win32] Added the `GLFW_WIN32_KEYBOARD_MENU` window hint for enabling access
|
||||
to the window menu
|
||||
- [Win32] Added a version info resource to the GLFW DLL
|
||||
- [Win32] Disabled framebuffer transparency on Windows 7 when DWM windows are
|
||||
opaque (#1512)
|
||||
- [Win32] Bugfix: `GLFW_INCLUDE_VULKAN` plus `VK_USE_PLATFORM_WIN32_KHR` caused
|
||||
symbol redefinition (#1524)
|
||||
- [Win32] Bugfix: The cursor position event was emitted before its cursor enter
|
||||
event (#1490)
|
||||
- [Win32] Bugfix: The window hint `GLFW_MAXIMIZED` did not move or resize the
|
||||
window (#1499)
|
||||
- [Win32] Bugfix: Disabled cursor mode interfered with some non-client actions
|
||||
- [Win32] Bugfix: Super key was not released after Win+V hotkey (#1622)
|
||||
- [Win32] Bugfix: `glfwGetKeyName` could access out of bounds and return an
|
||||
invalid pointer
|
||||
- [Win32] Bugfix: Some synthetic key events were reported as `GLFW_KEY_UNKNOWN`
|
||||
(#1623)
|
||||
- [Win32] Bugfix: Non-BMP Unicode codepoint input was reported as UTF-16
|
||||
- [Win32] Bugfix: Monitor functions could return invalid values after
|
||||
configuration change (#1761)
|
||||
- [Win32] Bugfix: Initialization would segfault on Windows 8 (not 8.1) (#1775)
|
||||
- [Win32] Bugfix: Duplicate size events were not filtered (#1610)
|
||||
- [Win32] Bugfix: Full screen windows were incorrectly resized by DPI changes
|
||||
(#1582)
|
||||
- [Win32] Bugfix: `GLFW_SCALE_TO_MONITOR` had no effect on systems older than
|
||||
Windows 10 version 1703 (#1511)
|
||||
- [Win32] Bugfix: `USE_MSVC_RUNTIME_LIBRARY_DLL` had no effect on CMake 3.15 or
|
||||
later (#1783,#1796)
|
||||
- [Win32] Bugfix: Compilation with LLVM for Windows failed (#1807,#1824,#1874)
|
||||
- [Win32] Bugfix: The foreground lock timeout was overridden, ignoring the user
|
||||
- [Win32] Bugfix: Content scale queries could fail silently (#1615)
|
||||
- [Win32] Bugfix: Content scales could have garbage values if monitor was recently
|
||||
disconnected (#1615)
|
||||
- [Cocoa] Added support for `VK_EXT_metal_surface` (#1619)
|
||||
- [Cocoa] Added locating the Vulkan loader at runtime in an application bundle
|
||||
- [Cocoa] Moved main menu creation to GLFW initialization time (#1649)
|
||||
- [Cocoa] Changed `EGLNativeWindowType` from `NSView` to `CALayer` (#1169)
|
||||
- [Cocoa] Changed F13 key to report Print Screen for cross-platform consistency
|
||||
(#1786)
|
||||
- [Cocoa] Removed dependency on the CoreVideo framework
|
||||
- [Cocoa] Bugfix: `glfwSetWindowSize` used a bottom-left anchor point (#1553)
|
||||
- [Cocoa] Bugfix: Window remained on screen after destruction until event poll
|
||||
(#1412)
|
||||
- [Cocoa] Bugfix: Event processing before window creation would assert (#1543)
|
||||
- [Cocoa] Bugfix: Undecorated windows could not be iconified on recent macOS
|
||||
- [Cocoa] Bugfix: Touching event queue from secondary thread before main thread
|
||||
would abort (#1649)
|
||||
- [Cocoa] Bugfix: Non-BMP Unicode codepoint input was reported as UTF-16
|
||||
(#1635)
|
||||
- [Cocoa] Bugfix: Failing to retrieve the refresh rate of built-in displays
|
||||
could leak memory
|
||||
- [Cocoa] Bugfix: Objective-C files were compiled as C with CMake 3.19 (#1787)
|
||||
- [Cocoa] Bugfix: Duplicate video modes were not filtered out (#1830)
|
||||
- [Cocoa] Bugfix: Menu bar was not clickable on macOS 10.15+ until it lost and
|
||||
regained focus (#1648,#1802)
|
||||
- [Cocoa] Bugfix: Monitor name query could segfault on macOS 11 (#1809,#1833)
|
||||
- [Cocoa] Bugfix: The install name of the installed dylib was relative (#1504)
|
||||
- [Cocoa] Bugfix: The MoltenVK layer contents scale was updated only after
|
||||
related events were emitted
|
||||
- [Cocoa] Bugfix: Moving the cursor programmatically would freeze it for
|
||||
a fraction of a second (#1962)
|
||||
- [Cocoa] Bugfix: `kIOMasterPortDefault` was deprecated in macOS 12.0 (#1980)
|
||||
- [Cocoa] Bugfix: `kUTTypeURL` was deprecated in macOS 12.0 (#2003)
|
||||
- [X11] Bugfix: The CMake files did not check for the XInput headers (#1480)
|
||||
- [X11] Bugfix: Key names were not updated when the keyboard layout changed
|
||||
(#1462,#1528)
|
||||
- [X11] Bugfix: Decorations could not be enabled after window creation (#1566)
|
||||
- [X11] Bugfix: Content scale fallback value could be inconsistent (#1578)
|
||||
- [X11] Bugfix: `glfwMaximizeWindow` had no effect on hidden windows
|
||||
- [X11] Bugfix: Clearing `GLFW_FLOATING` on a hidden window caused invalid read
|
||||
- [X11] Bugfix: Changing `GLFW_FLOATING` on a hidden window could silently fail
|
||||
- [X11] Bugfix: Disabled cursor mode was interrupted by indicator windows
|
||||
- [X11] Bugfix: Monitor physical dimensions could be reported as zero mm
|
||||
- [X11] Bugfix: Window position events were not emitted during resizing (#1613)
|
||||
- [X11] Bugfix: `glfwFocusWindow` could terminate on older WMs or without a WM
|
||||
- [X11] Bugfix: Querying a disconnected monitor could segfault (#1602)
|
||||
- [X11] Bugfix: IME input of CJK was broken for "C" locale (#1587,#1636)
|
||||
- [X11] Bugfix: Termination would segfault if the IM had been destroyed
|
||||
- [X11] Bugfix: Any IM started after initialization would not be detected
|
||||
- [X11] Bugfix: Xlib errors caused by other parts of the application could be
|
||||
reported as GLFW errors
|
||||
- [X11] Bugfix: A handle race condition could cause a `BadWindow` error (#1633)
|
||||
- [X11] Bugfix: XKB path used keysyms instead of physical locations for
|
||||
non-printable keys (#1598)
|
||||
- [X11] Bugfix: Function keys were mapped to `GLFW_KEY_UNKNOWN` for some layout
|
||||
combinations (#1598)
|
||||
- [X11] Bugfix: Keys pressed simultaneously with others were not always
|
||||
reported (#1112,#1415,#1472,#1616)
|
||||
- [X11] Bugfix: Some window attributes were not applied on leaving fullscreen
|
||||
(#1863)
|
||||
- [X11] Bugfix: Changing `GLFW_FLOATING` could leak memory
|
||||
- [X11] Bugfix: Icon pixel format conversion worked only by accident, relying on
|
||||
undefined behavior (#1986)
|
||||
- [X11] Bugfix: Dynamic loading on OpenBSD failed due to soname differences
|
||||
- [Wayland] Added dynamic loading of all Wayland libraries
|
||||
- [Wayland] Added support for key names via xkbcommon
|
||||
- [Wayland] Removed support for `wl_shell` (#1443)
|
||||
- [Wayland] Bugfix: The `GLFW_HAND_CURSOR` shape used the wrong image (#1432)
|
||||
- [Wayland] Bugfix: `CLOCK_MONOTONIC` was not correctly enabled
|
||||
- [Wayland] Bugfix: Repeated keys could be reported with `NULL` window (#1704)
|
||||
- [Wayland] Bugfix: Retrieving partial framebuffer size would segfault
|
||||
- [Wayland] Bugfix: Scrolling offsets were inverted compared to other platforms
|
||||
(#1463)
|
||||
- [Wayland] Bugfix: Client-Side Decorations were destroyed in the wrong order
|
||||
(#1798)
|
||||
- [Wayland] Bugfix: Monitors physical size could report zero (#1784,#1792)
|
||||
- [Wayland] Bugfix: Some keys were not repeating in Wayland (#1908)
|
||||
- [Wayland] Bugfix: Non-arrow cursors are offset from the hotspot (#1706,#1899)
|
||||
- [Wayland] Bugfix: The `O_CLOEXEC` flag was not defined on FreeBSD
|
||||
- [Wayland] Bugfix: Key repeat could lead to a race condition (#1710)
|
||||
- [Wayland] Bugfix: Activating a window would emit two input focus events
|
||||
- [Wayland] Bugfix: Disable key repeat mechanism when window loses input focus
|
||||
- [Wayland] Bugfix: Window hiding and showing did not work (#1492,#1731)
|
||||
- [Wayland] Bugfix: A key being repeated was not released when window lost focus
|
||||
- [Wayland] Bugfix: Showing a hidden window did not emit a window refresh event
|
||||
- [Wayland] Bugfix: Full screen window creation did not ignore `GLFW_VISIBLE`
|
||||
- [Wayland] Bugfix: Some keys were reported as wrong key or `GLFW_KEY_UNKNOWN`
|
||||
- [Wayland] Bugfix: Text input did not repeat along with key repeat
|
||||
- [POSIX] Removed use of deprecated function `gettimeofday`
|
||||
- [POSIX] Bugfix: `CLOCK_MONOTONIC` was not correctly tested for or enabled
|
||||
- [WGL] Disabled the DWM swap interval hack for Windows 8 and later (#1072)
|
||||
- [NSGL] Removed enforcement of forward-compatible flag for core contexts
|
||||
- [NSGL] Bugfix: `GLFW_COCOA_RETINA_FRAMEBUFFER` had no effect on newer
|
||||
macOS versions (#1442)
|
||||
- [NSGL] Bugfix: Workaround for swap interval on 10.14 broke on 10.12 (#1483)
|
||||
- [NSGL] Bugfix: Defining `GL_SILENCE_DEPRECATION` externally caused
|
||||
a duplicate definition warning (#1840)
|
||||
- [EGL] Added platform selection via the `EGL_EXT_platform_base` extension
|
||||
(#442)
|
||||
- [EGL] Added ANGLE backend selection via `EGL_ANGLE_platform_angle` extension
|
||||
(#1380)
|
||||
- [EGL] Bugfix: The `GLFW_DOUBLEBUFFER` context attribute was ignored (#1843)
|
||||
|
||||
|
||||
## Contact
|
||||
|
||||
On [glfw.org](https://www.glfw.org/) you can find the latest version of GLFW, as
|
||||
well as news, documentation and other information about the project.
|
||||
|
||||
If you have questions related to the use of GLFW, we have a
|
||||
[forum](https://discourse.glfw.org/), and the `#glfw` IRC channel on
|
||||
[Libera.Chat](https://libera.chat/).
|
||||
|
||||
If you have a bug to report, a patch to submit or a feature you'd like to
|
||||
request, please file it in the
|
||||
[issue tracker](https://github.com/glfw/glfw/issues) on GitHub.
|
||||
|
||||
Finally, if you're interested in helping out with the development of GLFW or
|
||||
porting it to your favorite platform, join us on the forum, GitHub or IRC.
|
||||
|
||||
230
src/ThirdParty/glfw/deps/getopt.c
vendored
Normal file
230
src/ThirdParty/glfw/deps/getopt.c
vendored
Normal file
@@ -0,0 +1,230 @@
|
||||
/* Copyright (c) 2012, Kim Gräsman
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* * Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
* * Neither the name of Kim Gräsman nor the names of contributors may be used
|
||||
* to endorse or promote products derived from this software without specific
|
||||
* prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL KIM GRÄSMAN BE LIABLE FOR ANY DIRECT,
|
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "getopt.h"
|
||||
|
||||
#include <stddef.h>
|
||||
#include <string.h>
|
||||
|
||||
const int no_argument = 0;
|
||||
const int required_argument = 1;
|
||||
const int optional_argument = 2;
|
||||
|
||||
char* optarg;
|
||||
int optopt;
|
||||
/* The variable optind [...] shall be initialized to 1 by the system. */
|
||||
int optind = 1;
|
||||
int opterr;
|
||||
|
||||
static char* optcursor = NULL;
|
||||
|
||||
/* Implemented based on [1] and [2] for optional arguments.
|
||||
optopt is handled FreeBSD-style, per [3].
|
||||
Other GNU and FreeBSD extensions are purely accidental.
|
||||
|
||||
[1] http://pubs.opengroup.org/onlinepubs/000095399/functions/getopt.html
|
||||
[2] http://www.kernel.org/doc/man-pages/online/pages/man3/getopt.3.html
|
||||
[3] http://www.freebsd.org/cgi/man.cgi?query=getopt&sektion=3&manpath=FreeBSD+9.0-RELEASE
|
||||
*/
|
||||
int getopt(int argc, char* const argv[], const char* optstring) {
|
||||
int optchar = -1;
|
||||
const char* optdecl = NULL;
|
||||
|
||||
optarg = NULL;
|
||||
opterr = 0;
|
||||
optopt = 0;
|
||||
|
||||
/* Unspecified, but we need it to avoid overrunning the argv bounds. */
|
||||
if (optind >= argc)
|
||||
goto no_more_optchars;
|
||||
|
||||
/* If, when getopt() is called argv[optind] is a null pointer, getopt()
|
||||
shall return -1 without changing optind. */
|
||||
if (argv[optind] == NULL)
|
||||
goto no_more_optchars;
|
||||
|
||||
/* If, when getopt() is called *argv[optind] is not the character '-',
|
||||
getopt() shall return -1 without changing optind. */
|
||||
if (*argv[optind] != '-')
|
||||
goto no_more_optchars;
|
||||
|
||||
/* If, when getopt() is called argv[optind] points to the string "-",
|
||||
getopt() shall return -1 without changing optind. */
|
||||
if (strcmp(argv[optind], "-") == 0)
|
||||
goto no_more_optchars;
|
||||
|
||||
/* If, when getopt() is called argv[optind] points to the string "--",
|
||||
getopt() shall return -1 after incrementing optind. */
|
||||
if (strcmp(argv[optind], "--") == 0) {
|
||||
++optind;
|
||||
goto no_more_optchars;
|
||||
}
|
||||
|
||||
if (optcursor == NULL || *optcursor == '\0')
|
||||
optcursor = argv[optind] + 1;
|
||||
|
||||
optchar = *optcursor;
|
||||
|
||||
/* FreeBSD: The variable optopt saves the last known option character
|
||||
returned by getopt(). */
|
||||
optopt = optchar;
|
||||
|
||||
/* The getopt() function shall return the next option character (if one is
|
||||
found) from argv that matches a character in optstring, if there is
|
||||
one that matches. */
|
||||
optdecl = strchr(optstring, optchar);
|
||||
if (optdecl) {
|
||||
/* [I]f a character is followed by a colon, the option takes an
|
||||
argument. */
|
||||
if (optdecl[1] == ':') {
|
||||
optarg = ++optcursor;
|
||||
if (*optarg == '\0') {
|
||||
/* GNU extension: Two colons mean an option takes an
|
||||
optional arg; if there is text in the current argv-element
|
||||
(i.e., in the same word as the option name itself, for example,
|
||||
"-oarg"), then it is returned in optarg, otherwise optarg is set
|
||||
to zero. */
|
||||
if (optdecl[2] != ':') {
|
||||
/* If the option was the last character in the string pointed to by
|
||||
an element of argv, then optarg shall contain the next element
|
||||
of argv, and optind shall be incremented by 2. If the resulting
|
||||
value of optind is greater than argc, this indicates a missing
|
||||
option-argument, and getopt() shall return an error indication.
|
||||
|
||||
Otherwise, optarg shall point to the string following the
|
||||
option character in that element of argv, and optind shall be
|
||||
incremented by 1.
|
||||
*/
|
||||
if (++optind < argc) {
|
||||
optarg = argv[optind];
|
||||
} else {
|
||||
/* If it detects a missing option-argument, it shall return the
|
||||
colon character ( ':' ) if the first character of optstring
|
||||
was a colon, or a question-mark character ( '?' ) otherwise.
|
||||
*/
|
||||
optarg = NULL;
|
||||
optchar = (optstring[0] == ':') ? ':' : '?';
|
||||
}
|
||||
} else {
|
||||
optarg = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
optcursor = NULL;
|
||||
}
|
||||
} else {
|
||||
/* If getopt() encounters an option character that is not contained in
|
||||
optstring, it shall return the question-mark ( '?' ) character. */
|
||||
optchar = '?';
|
||||
}
|
||||
|
||||
if (optcursor == NULL || *++optcursor == '\0')
|
||||
++optind;
|
||||
|
||||
return optchar;
|
||||
|
||||
no_more_optchars:
|
||||
optcursor = NULL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Implementation based on [1].
|
||||
|
||||
[1] http://www.kernel.org/doc/man-pages/online/pages/man3/getopt.3.html
|
||||
*/
|
||||
int getopt_long(int argc, char* const argv[], const char* optstring,
|
||||
const struct option* longopts, int* longindex) {
|
||||
const struct option* o = longopts;
|
||||
const struct option* match = NULL;
|
||||
int num_matches = 0;
|
||||
size_t argument_name_length = 0;
|
||||
const char* current_argument = NULL;
|
||||
int retval = -1;
|
||||
|
||||
optarg = NULL;
|
||||
optopt = 0;
|
||||
|
||||
if (optind >= argc)
|
||||
return -1;
|
||||
|
||||
if (strlen(argv[optind]) < 3 || strncmp(argv[optind], "--", 2) != 0)
|
||||
return getopt(argc, argv, optstring);
|
||||
|
||||
/* It's an option; starts with -- and is longer than two chars. */
|
||||
current_argument = argv[optind] + 2;
|
||||
argument_name_length = strcspn(current_argument, "=");
|
||||
for (; o->name; ++o) {
|
||||
if (strncmp(o->name, current_argument, argument_name_length) == 0) {
|
||||
match = o;
|
||||
++num_matches;
|
||||
}
|
||||
}
|
||||
|
||||
if (num_matches == 1) {
|
||||
/* If longindex is not NULL, it points to a variable which is set to the
|
||||
index of the long option relative to longopts. */
|
||||
if (longindex)
|
||||
*longindex = (int) (match - longopts);
|
||||
|
||||
/* If flag is NULL, then getopt_long() shall return val.
|
||||
Otherwise, getopt_long() returns 0, and flag shall point to a variable
|
||||
which shall be set to val if the option is found, but left unchanged if
|
||||
the option is not found. */
|
||||
if (match->flag)
|
||||
*(match->flag) = match->val;
|
||||
|
||||
retval = match->flag ? 0 : match->val;
|
||||
|
||||
if (match->has_arg != no_argument) {
|
||||
optarg = strchr(argv[optind], '=');
|
||||
if (optarg != NULL)
|
||||
++optarg;
|
||||
|
||||
if (match->has_arg == required_argument) {
|
||||
/* Only scan the next argv for required arguments. Behavior is not
|
||||
specified, but has been observed with Ubuntu and Mac OSX. */
|
||||
if (optarg == NULL && ++optind < argc) {
|
||||
optarg = argv[optind];
|
||||
}
|
||||
|
||||
if (optarg == NULL)
|
||||
retval = ':';
|
||||
}
|
||||
} else if (strchr(argv[optind], '=')) {
|
||||
/* An argument was provided to a non-argument option.
|
||||
I haven't seen this specified explicitly, but both GNU and BSD-based
|
||||
implementations show this behavior.
|
||||
*/
|
||||
retval = '?';
|
||||
}
|
||||
} else {
|
||||
/* Unknown option or ambiguous match. */
|
||||
retval = '?';
|
||||
}
|
||||
|
||||
++optind;
|
||||
return retval;
|
||||
}
|
||||
57
src/ThirdParty/glfw/deps/getopt.h
vendored
Normal file
57
src/ThirdParty/glfw/deps/getopt.h
vendored
Normal file
@@ -0,0 +1,57 @@
|
||||
/* Copyright (c) 2012, Kim Gräsman
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* * Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
* * Neither the name of Kim Gräsman nor the names of contributors may be used
|
||||
* to endorse or promote products derived from this software without specific
|
||||
* prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL KIM GRÄSMAN BE LIABLE FOR ANY DIRECT,
|
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef INCLUDED_GETOPT_PORT_H
|
||||
#define INCLUDED_GETOPT_PORT_H
|
||||
|
||||
#if defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
extern const int no_argument;
|
||||
extern const int required_argument;
|
||||
extern const int optional_argument;
|
||||
|
||||
extern char* optarg;
|
||||
extern int optind, opterr, optopt;
|
||||
|
||||
struct option {
|
||||
const char* name;
|
||||
int has_arg;
|
||||
int* flag;
|
||||
int val;
|
||||
};
|
||||
|
||||
int getopt(int argc, char* const argv[], const char* optstring);
|
||||
|
||||
int getopt_long(int argc, char* const argv[],
|
||||
const char* optstring, const struct option* longopts, int* longindex);
|
||||
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // INCLUDED_GETOPT_PORT_H
|
||||
5996
src/ThirdParty/glfw/deps/glad/gl.h
vendored
Normal file
5996
src/ThirdParty/glfw/deps/glad/gl.h
vendored
Normal file
File diff suppressed because it is too large
Load Diff
1805
src/ThirdParty/glfw/deps/glad/gles2.h
vendored
Normal file
1805
src/ThirdParty/glfw/deps/glad/gles2.h
vendored
Normal file
File diff suppressed because it is too large
Load Diff
4612
src/ThirdParty/glfw/deps/glad/vulkan.h
vendored
Normal file
4612
src/ThirdParty/glfw/deps/glad/vulkan.h
vendored
Normal file
File diff suppressed because it is too large
Load Diff
606
src/ThirdParty/glfw/deps/linmath.h
vendored
Normal file
606
src/ThirdParty/glfw/deps/linmath.h
vendored
Normal file
@@ -0,0 +1,606 @@
|
||||
#ifndef LINMATH_H
|
||||
#define LINMATH_H
|
||||
|
||||
#include <string.h>
|
||||
#include <math.h>
|
||||
#include <string.h>
|
||||
|
||||
/* 2021-03-21 Camilla Löwy <elmindreda@elmindreda.org>
|
||||
* - Replaced double constants with float equivalents
|
||||
*/
|
||||
|
||||
#ifdef LINMATH_NO_INLINE
|
||||
#define LINMATH_H_FUNC static
|
||||
#else
|
||||
#define LINMATH_H_FUNC static inline
|
||||
#endif
|
||||
|
||||
#define LINMATH_H_DEFINE_VEC(n) \
|
||||
typedef float vec##n[n]; \
|
||||
LINMATH_H_FUNC void vec##n##_add(vec##n r, vec##n const a, vec##n const b) \
|
||||
{ \
|
||||
int i; \
|
||||
for(i=0; i<n; ++i) \
|
||||
r[i] = a[i] + b[i]; \
|
||||
} \
|
||||
LINMATH_H_FUNC void vec##n##_sub(vec##n r, vec##n const a, vec##n const b) \
|
||||
{ \
|
||||
int i; \
|
||||
for(i=0; i<n; ++i) \
|
||||
r[i] = a[i] - b[i]; \
|
||||
} \
|
||||
LINMATH_H_FUNC void vec##n##_scale(vec##n r, vec##n const v, float const s) \
|
||||
{ \
|
||||
int i; \
|
||||
for(i=0; i<n; ++i) \
|
||||
r[i] = v[i] * s; \
|
||||
} \
|
||||
LINMATH_H_FUNC float vec##n##_mul_inner(vec##n const a, vec##n const b) \
|
||||
{ \
|
||||
float p = 0.f; \
|
||||
int i; \
|
||||
for(i=0; i<n; ++i) \
|
||||
p += b[i]*a[i]; \
|
||||
return p; \
|
||||
} \
|
||||
LINMATH_H_FUNC float vec##n##_len(vec##n const v) \
|
||||
{ \
|
||||
return sqrtf(vec##n##_mul_inner(v,v)); \
|
||||
} \
|
||||
LINMATH_H_FUNC void vec##n##_norm(vec##n r, vec##n const v) \
|
||||
{ \
|
||||
float k = 1.f / vec##n##_len(v); \
|
||||
vec##n##_scale(r, v, k); \
|
||||
} \
|
||||
LINMATH_H_FUNC void vec##n##_min(vec##n r, vec##n const a, vec##n const b) \
|
||||
{ \
|
||||
int i; \
|
||||
for(i=0; i<n; ++i) \
|
||||
r[i] = a[i]<b[i] ? a[i] : b[i]; \
|
||||
} \
|
||||
LINMATH_H_FUNC void vec##n##_max(vec##n r, vec##n const a, vec##n const b) \
|
||||
{ \
|
||||
int i; \
|
||||
for(i=0; i<n; ++i) \
|
||||
r[i] = a[i]>b[i] ? a[i] : b[i]; \
|
||||
} \
|
||||
LINMATH_H_FUNC void vec##n##_dup(vec##n r, vec##n const src) \
|
||||
{ \
|
||||
int i; \
|
||||
for(i=0; i<n; ++i) \
|
||||
r[i] = src[i]; \
|
||||
}
|
||||
|
||||
LINMATH_H_DEFINE_VEC(2)
|
||||
LINMATH_H_DEFINE_VEC(3)
|
||||
LINMATH_H_DEFINE_VEC(4)
|
||||
|
||||
LINMATH_H_FUNC void vec3_mul_cross(vec3 r, vec3 const a, vec3 const b)
|
||||
{
|
||||
r[0] = a[1]*b[2] - a[2]*b[1];
|
||||
r[1] = a[2]*b[0] - a[0]*b[2];
|
||||
r[2] = a[0]*b[1] - a[1]*b[0];
|
||||
}
|
||||
|
||||
LINMATH_H_FUNC void vec3_reflect(vec3 r, vec3 const v, vec3 const n)
|
||||
{
|
||||
float p = 2.f * vec3_mul_inner(v, n);
|
||||
int i;
|
||||
for(i=0;i<3;++i)
|
||||
r[i] = v[i] - p*n[i];
|
||||
}
|
||||
|
||||
LINMATH_H_FUNC void vec4_mul_cross(vec4 r, vec4 const a, vec4 const b)
|
||||
{
|
||||
r[0] = a[1]*b[2] - a[2]*b[1];
|
||||
r[1] = a[2]*b[0] - a[0]*b[2];
|
||||
r[2] = a[0]*b[1] - a[1]*b[0];
|
||||
r[3] = 1.f;
|
||||
}
|
||||
|
||||
LINMATH_H_FUNC void vec4_reflect(vec4 r, vec4 const v, vec4 const n)
|
||||
{
|
||||
float p = 2.f*vec4_mul_inner(v, n);
|
||||
int i;
|
||||
for(i=0;i<4;++i)
|
||||
r[i] = v[i] - p*n[i];
|
||||
}
|
||||
|
||||
typedef vec4 mat4x4[4];
|
||||
LINMATH_H_FUNC void mat4x4_identity(mat4x4 M)
|
||||
{
|
||||
int i, j;
|
||||
for(i=0; i<4; ++i)
|
||||
for(j=0; j<4; ++j)
|
||||
M[i][j] = i==j ? 1.f : 0.f;
|
||||
}
|
||||
LINMATH_H_FUNC void mat4x4_dup(mat4x4 M, mat4x4 const N)
|
||||
{
|
||||
int i;
|
||||
for(i=0; i<4; ++i)
|
||||
vec4_dup(M[i], N[i]);
|
||||
}
|
||||
LINMATH_H_FUNC void mat4x4_row(vec4 r, mat4x4 const M, int i)
|
||||
{
|
||||
int k;
|
||||
for(k=0; k<4; ++k)
|
||||
r[k] = M[k][i];
|
||||
}
|
||||
LINMATH_H_FUNC void mat4x4_col(vec4 r, mat4x4 const M, int i)
|
||||
{
|
||||
int k;
|
||||
for(k=0; k<4; ++k)
|
||||
r[k] = M[i][k];
|
||||
}
|
||||
LINMATH_H_FUNC void mat4x4_transpose(mat4x4 M, mat4x4 const N)
|
||||
{
|
||||
// Note: if M and N are the same, the user has to
|
||||
// explicitly make a copy of M and set it to N.
|
||||
int i, j;
|
||||
for(j=0; j<4; ++j)
|
||||
for(i=0; i<4; ++i)
|
||||
M[i][j] = N[j][i];
|
||||
}
|
||||
LINMATH_H_FUNC void mat4x4_add(mat4x4 M, mat4x4 const a, mat4x4 const b)
|
||||
{
|
||||
int i;
|
||||
for(i=0; i<4; ++i)
|
||||
vec4_add(M[i], a[i], b[i]);
|
||||
}
|
||||
LINMATH_H_FUNC void mat4x4_sub(mat4x4 M, mat4x4 const a, mat4x4 const b)
|
||||
{
|
||||
int i;
|
||||
for(i=0; i<4; ++i)
|
||||
vec4_sub(M[i], a[i], b[i]);
|
||||
}
|
||||
LINMATH_H_FUNC void mat4x4_scale(mat4x4 M, mat4x4 const a, float k)
|
||||
{
|
||||
int i;
|
||||
for(i=0; i<4; ++i)
|
||||
vec4_scale(M[i], a[i], k);
|
||||
}
|
||||
LINMATH_H_FUNC void mat4x4_scale_aniso(mat4x4 M, mat4x4 const a, float x, float y, float z)
|
||||
{
|
||||
vec4_scale(M[0], a[0], x);
|
||||
vec4_scale(M[1], a[1], y);
|
||||
vec4_scale(M[2], a[2], z);
|
||||
vec4_dup(M[3], a[3]);
|
||||
}
|
||||
LINMATH_H_FUNC void mat4x4_mul(mat4x4 M, mat4x4 const a, mat4x4 const b)
|
||||
{
|
||||
mat4x4 temp;
|
||||
int k, r, c;
|
||||
for(c=0; c<4; ++c) for(r=0; r<4; ++r) {
|
||||
temp[c][r] = 0.f;
|
||||
for(k=0; k<4; ++k)
|
||||
temp[c][r] += a[k][r] * b[c][k];
|
||||
}
|
||||
mat4x4_dup(M, temp);
|
||||
}
|
||||
LINMATH_H_FUNC void mat4x4_mul_vec4(vec4 r, mat4x4 const M, vec4 const v)
|
||||
{
|
||||
int i, j;
|
||||
for(j=0; j<4; ++j) {
|
||||
r[j] = 0.f;
|
||||
for(i=0; i<4; ++i)
|
||||
r[j] += M[i][j] * v[i];
|
||||
}
|
||||
}
|
||||
LINMATH_H_FUNC void mat4x4_translate(mat4x4 T, float x, float y, float z)
|
||||
{
|
||||
mat4x4_identity(T);
|
||||
T[3][0] = x;
|
||||
T[3][1] = y;
|
||||
T[3][2] = z;
|
||||
}
|
||||
LINMATH_H_FUNC void mat4x4_translate_in_place(mat4x4 M, float x, float y, float z)
|
||||
{
|
||||
vec4 t = {x, y, z, 0};
|
||||
vec4 r;
|
||||
int i;
|
||||
for (i = 0; i < 4; ++i) {
|
||||
mat4x4_row(r, M, i);
|
||||
M[3][i] += vec4_mul_inner(r, t);
|
||||
}
|
||||
}
|
||||
LINMATH_H_FUNC void mat4x4_from_vec3_mul_outer(mat4x4 M, vec3 const a, vec3 const b)
|
||||
{
|
||||
int i, j;
|
||||
for(i=0; i<4; ++i) for(j=0; j<4; ++j)
|
||||
M[i][j] = i<3 && j<3 ? a[i] * b[j] : 0.f;
|
||||
}
|
||||
LINMATH_H_FUNC void mat4x4_rotate(mat4x4 R, mat4x4 const M, float x, float y, float z, float angle)
|
||||
{
|
||||
float s = sinf(angle);
|
||||
float c = cosf(angle);
|
||||
vec3 u = {x, y, z};
|
||||
|
||||
if(vec3_len(u) > 1e-4) {
|
||||
vec3_norm(u, u);
|
||||
mat4x4 T;
|
||||
mat4x4_from_vec3_mul_outer(T, u, u);
|
||||
|
||||
mat4x4 S = {
|
||||
{ 0, u[2], -u[1], 0},
|
||||
{-u[2], 0, u[0], 0},
|
||||
{ u[1], -u[0], 0, 0},
|
||||
{ 0, 0, 0, 0}
|
||||
};
|
||||
mat4x4_scale(S, S, s);
|
||||
|
||||
mat4x4 C;
|
||||
mat4x4_identity(C);
|
||||
mat4x4_sub(C, C, T);
|
||||
|
||||
mat4x4_scale(C, C, c);
|
||||
|
||||
mat4x4_add(T, T, C);
|
||||
mat4x4_add(T, T, S);
|
||||
|
||||
T[3][3] = 1.f;
|
||||
mat4x4_mul(R, M, T);
|
||||
} else {
|
||||
mat4x4_dup(R, M);
|
||||
}
|
||||
}
|
||||
LINMATH_H_FUNC void mat4x4_rotate_X(mat4x4 Q, mat4x4 const M, float angle)
|
||||
{
|
||||
float s = sinf(angle);
|
||||
float c = cosf(angle);
|
||||
mat4x4 R = {
|
||||
{1.f, 0.f, 0.f, 0.f},
|
||||
{0.f, c, s, 0.f},
|
||||
{0.f, -s, c, 0.f},
|
||||
{0.f, 0.f, 0.f, 1.f}
|
||||
};
|
||||
mat4x4_mul(Q, M, R);
|
||||
}
|
||||
LINMATH_H_FUNC void mat4x4_rotate_Y(mat4x4 Q, mat4x4 const M, float angle)
|
||||
{
|
||||
float s = sinf(angle);
|
||||
float c = cosf(angle);
|
||||
mat4x4 R = {
|
||||
{ c, 0.f, -s, 0.f},
|
||||
{ 0.f, 1.f, 0.f, 0.f},
|
||||
{ s, 0.f, c, 0.f},
|
||||
{ 0.f, 0.f, 0.f, 1.f}
|
||||
};
|
||||
mat4x4_mul(Q, M, R);
|
||||
}
|
||||
LINMATH_H_FUNC void mat4x4_rotate_Z(mat4x4 Q, mat4x4 const M, float angle)
|
||||
{
|
||||
float s = sinf(angle);
|
||||
float c = cosf(angle);
|
||||
mat4x4 R = {
|
||||
{ c, s, 0.f, 0.f},
|
||||
{ -s, c, 0.f, 0.f},
|
||||
{ 0.f, 0.f, 1.f, 0.f},
|
||||
{ 0.f, 0.f, 0.f, 1.f}
|
||||
};
|
||||
mat4x4_mul(Q, M, R);
|
||||
}
|
||||
LINMATH_H_FUNC void mat4x4_invert(mat4x4 T, mat4x4 const M)
|
||||
{
|
||||
float s[6];
|
||||
float c[6];
|
||||
s[0] = M[0][0]*M[1][1] - M[1][0]*M[0][1];
|
||||
s[1] = M[0][0]*M[1][2] - M[1][0]*M[0][2];
|
||||
s[2] = M[0][0]*M[1][3] - M[1][0]*M[0][3];
|
||||
s[3] = M[0][1]*M[1][2] - M[1][1]*M[0][2];
|
||||
s[4] = M[0][1]*M[1][3] - M[1][1]*M[0][3];
|
||||
s[5] = M[0][2]*M[1][3] - M[1][2]*M[0][3];
|
||||
|
||||
c[0] = M[2][0]*M[3][1] - M[3][0]*M[2][1];
|
||||
c[1] = M[2][0]*M[3][2] - M[3][0]*M[2][2];
|
||||
c[2] = M[2][0]*M[3][3] - M[3][0]*M[2][3];
|
||||
c[3] = M[2][1]*M[3][2] - M[3][1]*M[2][2];
|
||||
c[4] = M[2][1]*M[3][3] - M[3][1]*M[2][3];
|
||||
c[5] = M[2][2]*M[3][3] - M[3][2]*M[2][3];
|
||||
|
||||
/* Assumes it is invertible */
|
||||
float idet = 1.0f/( s[0]*c[5]-s[1]*c[4]+s[2]*c[3]+s[3]*c[2]-s[4]*c[1]+s[5]*c[0] );
|
||||
|
||||
T[0][0] = ( M[1][1] * c[5] - M[1][2] * c[4] + M[1][3] * c[3]) * idet;
|
||||
T[0][1] = (-M[0][1] * c[5] + M[0][2] * c[4] - M[0][3] * c[3]) * idet;
|
||||
T[0][2] = ( M[3][1] * s[5] - M[3][2] * s[4] + M[3][3] * s[3]) * idet;
|
||||
T[0][3] = (-M[2][1] * s[5] + M[2][2] * s[4] - M[2][3] * s[3]) * idet;
|
||||
|
||||
T[1][0] = (-M[1][0] * c[5] + M[1][2] * c[2] - M[1][3] * c[1]) * idet;
|
||||
T[1][1] = ( M[0][0] * c[5] - M[0][2] * c[2] + M[0][3] * c[1]) * idet;
|
||||
T[1][2] = (-M[3][0] * s[5] + M[3][2] * s[2] - M[3][3] * s[1]) * idet;
|
||||
T[1][3] = ( M[2][0] * s[5] - M[2][2] * s[2] + M[2][3] * s[1]) * idet;
|
||||
|
||||
T[2][0] = ( M[1][0] * c[4] - M[1][1] * c[2] + M[1][3] * c[0]) * idet;
|
||||
T[2][1] = (-M[0][0] * c[4] + M[0][1] * c[2] - M[0][3] * c[0]) * idet;
|
||||
T[2][2] = ( M[3][0] * s[4] - M[3][1] * s[2] + M[3][3] * s[0]) * idet;
|
||||
T[2][3] = (-M[2][0] * s[4] + M[2][1] * s[2] - M[2][3] * s[0]) * idet;
|
||||
|
||||
T[3][0] = (-M[1][0] * c[3] + M[1][1] * c[1] - M[1][2] * c[0]) * idet;
|
||||
T[3][1] = ( M[0][0] * c[3] - M[0][1] * c[1] + M[0][2] * c[0]) * idet;
|
||||
T[3][2] = (-M[3][0] * s[3] + M[3][1] * s[1] - M[3][2] * s[0]) * idet;
|
||||
T[3][3] = ( M[2][0] * s[3] - M[2][1] * s[1] + M[2][2] * s[0]) * idet;
|
||||
}
|
||||
LINMATH_H_FUNC void mat4x4_orthonormalize(mat4x4 R, mat4x4 const M)
|
||||
{
|
||||
mat4x4_dup(R, M);
|
||||
float s = 1.f;
|
||||
vec3 h;
|
||||
|
||||
vec3_norm(R[2], R[2]);
|
||||
|
||||
s = vec3_mul_inner(R[1], R[2]);
|
||||
vec3_scale(h, R[2], s);
|
||||
vec3_sub(R[1], R[1], h);
|
||||
vec3_norm(R[1], R[1]);
|
||||
|
||||
s = vec3_mul_inner(R[0], R[2]);
|
||||
vec3_scale(h, R[2], s);
|
||||
vec3_sub(R[0], R[0], h);
|
||||
|
||||
s = vec3_mul_inner(R[0], R[1]);
|
||||
vec3_scale(h, R[1], s);
|
||||
vec3_sub(R[0], R[0], h);
|
||||
vec3_norm(R[0], R[0]);
|
||||
}
|
||||
|
||||
LINMATH_H_FUNC void mat4x4_frustum(mat4x4 M, float l, float r, float b, float t, float n, float f)
|
||||
{
|
||||
M[0][0] = 2.f*n/(r-l);
|
||||
M[0][1] = M[0][2] = M[0][3] = 0.f;
|
||||
|
||||
M[1][1] = 2.f*n/(t-b);
|
||||
M[1][0] = M[1][2] = M[1][3] = 0.f;
|
||||
|
||||
M[2][0] = (r+l)/(r-l);
|
||||
M[2][1] = (t+b)/(t-b);
|
||||
M[2][2] = -(f+n)/(f-n);
|
||||
M[2][3] = -1.f;
|
||||
|
||||
M[3][2] = -2.f*(f*n)/(f-n);
|
||||
M[3][0] = M[3][1] = M[3][3] = 0.f;
|
||||
}
|
||||
LINMATH_H_FUNC void mat4x4_ortho(mat4x4 M, float l, float r, float b, float t, float n, float f)
|
||||
{
|
||||
M[0][0] = 2.f/(r-l);
|
||||
M[0][1] = M[0][2] = M[0][3] = 0.f;
|
||||
|
||||
M[1][1] = 2.f/(t-b);
|
||||
M[1][0] = M[1][2] = M[1][3] = 0.f;
|
||||
|
||||
M[2][2] = -2.f/(f-n);
|
||||
M[2][0] = M[2][1] = M[2][3] = 0.f;
|
||||
|
||||
M[3][0] = -(r+l)/(r-l);
|
||||
M[3][1] = -(t+b)/(t-b);
|
||||
M[3][2] = -(f+n)/(f-n);
|
||||
M[3][3] = 1.f;
|
||||
}
|
||||
LINMATH_H_FUNC void mat4x4_perspective(mat4x4 m, float y_fov, float aspect, float n, float f)
|
||||
{
|
||||
/* NOTE: Degrees are an unhandy unit to work with.
|
||||
* linmath.h uses radians for everything! */
|
||||
float const a = 1.f / tanf(y_fov / 2.f);
|
||||
|
||||
m[0][0] = a / aspect;
|
||||
m[0][1] = 0.f;
|
||||
m[0][2] = 0.f;
|
||||
m[0][3] = 0.f;
|
||||
|
||||
m[1][0] = 0.f;
|
||||
m[1][1] = a;
|
||||
m[1][2] = 0.f;
|
||||
m[1][3] = 0.f;
|
||||
|
||||
m[2][0] = 0.f;
|
||||
m[2][1] = 0.f;
|
||||
m[2][2] = -((f + n) / (f - n));
|
||||
m[2][3] = -1.f;
|
||||
|
||||
m[3][0] = 0.f;
|
||||
m[3][1] = 0.f;
|
||||
m[3][2] = -((2.f * f * n) / (f - n));
|
||||
m[3][3] = 0.f;
|
||||
}
|
||||
LINMATH_H_FUNC void mat4x4_look_at(mat4x4 m, vec3 const eye, vec3 const center, vec3 const up)
|
||||
{
|
||||
/* Adapted from Android's OpenGL Matrix.java. */
|
||||
/* See the OpenGL GLUT documentation for gluLookAt for a description */
|
||||
/* of the algorithm. We implement it in a straightforward way: */
|
||||
|
||||
/* TODO: The negation of of can be spared by swapping the order of
|
||||
* operands in the following cross products in the right way. */
|
||||
vec3 f;
|
||||
vec3_sub(f, center, eye);
|
||||
vec3_norm(f, f);
|
||||
|
||||
vec3 s;
|
||||
vec3_mul_cross(s, f, up);
|
||||
vec3_norm(s, s);
|
||||
|
||||
vec3 t;
|
||||
vec3_mul_cross(t, s, f);
|
||||
|
||||
m[0][0] = s[0];
|
||||
m[0][1] = t[0];
|
||||
m[0][2] = -f[0];
|
||||
m[0][3] = 0.f;
|
||||
|
||||
m[1][0] = s[1];
|
||||
m[1][1] = t[1];
|
||||
m[1][2] = -f[1];
|
||||
m[1][3] = 0.f;
|
||||
|
||||
m[2][0] = s[2];
|
||||
m[2][1] = t[2];
|
||||
m[2][2] = -f[2];
|
||||
m[2][3] = 0.f;
|
||||
|
||||
m[3][0] = 0.f;
|
||||
m[3][1] = 0.f;
|
||||
m[3][2] = 0.f;
|
||||
m[3][3] = 1.f;
|
||||
|
||||
mat4x4_translate_in_place(m, -eye[0], -eye[1], -eye[2]);
|
||||
}
|
||||
|
||||
typedef float quat[4];
|
||||
#define quat_add vec4_add
|
||||
#define quat_sub vec4_sub
|
||||
#define quat_norm vec4_norm
|
||||
#define quat_scale vec4_scale
|
||||
#define quat_mul_inner vec4_mul_inner
|
||||
|
||||
LINMATH_H_FUNC void quat_identity(quat q)
|
||||
{
|
||||
q[0] = q[1] = q[2] = 0.f;
|
||||
q[3] = 1.f;
|
||||
}
|
||||
LINMATH_H_FUNC void quat_mul(quat r, quat const p, quat const q)
|
||||
{
|
||||
vec3 w;
|
||||
vec3_mul_cross(r, p, q);
|
||||
vec3_scale(w, p, q[3]);
|
||||
vec3_add(r, r, w);
|
||||
vec3_scale(w, q, p[3]);
|
||||
vec3_add(r, r, w);
|
||||
r[3] = p[3]*q[3] - vec3_mul_inner(p, q);
|
||||
}
|
||||
LINMATH_H_FUNC void quat_conj(quat r, quat const q)
|
||||
{
|
||||
int i;
|
||||
for(i=0; i<3; ++i)
|
||||
r[i] = -q[i];
|
||||
r[3] = q[3];
|
||||
}
|
||||
LINMATH_H_FUNC void quat_rotate(quat r, float angle, vec3 const axis) {
|
||||
vec3 axis_norm;
|
||||
vec3_norm(axis_norm, axis);
|
||||
float s = sinf(angle / 2);
|
||||
float c = cosf(angle / 2);
|
||||
vec3_scale(r, axis_norm, s);
|
||||
r[3] = c;
|
||||
}
|
||||
LINMATH_H_FUNC void quat_mul_vec3(vec3 r, quat const q, vec3 const v)
|
||||
{
|
||||
/*
|
||||
* Method by Fabian 'ryg' Giessen (of Farbrausch)
|
||||
t = 2 * cross(q.xyz, v)
|
||||
v' = v + q.w * t + cross(q.xyz, t)
|
||||
*/
|
||||
vec3 t;
|
||||
vec3 q_xyz = {q[0], q[1], q[2]};
|
||||
vec3 u = {q[0], q[1], q[2]};
|
||||
|
||||
vec3_mul_cross(t, q_xyz, v);
|
||||
vec3_scale(t, t, 2);
|
||||
|
||||
vec3_mul_cross(u, q_xyz, t);
|
||||
vec3_scale(t, t, q[3]);
|
||||
|
||||
vec3_add(r, v, t);
|
||||
vec3_add(r, r, u);
|
||||
}
|
||||
LINMATH_H_FUNC void mat4x4_from_quat(mat4x4 M, quat const q)
|
||||
{
|
||||
float a = q[3];
|
||||
float b = q[0];
|
||||
float c = q[1];
|
||||
float d = q[2];
|
||||
float a2 = a*a;
|
||||
float b2 = b*b;
|
||||
float c2 = c*c;
|
||||
float d2 = d*d;
|
||||
|
||||
M[0][0] = a2 + b2 - c2 - d2;
|
||||
M[0][1] = 2.f*(b*c + a*d);
|
||||
M[0][2] = 2.f*(b*d - a*c);
|
||||
M[0][3] = 0.f;
|
||||
|
||||
M[1][0] = 2*(b*c - a*d);
|
||||
M[1][1] = a2 - b2 + c2 - d2;
|
||||
M[1][2] = 2.f*(c*d + a*b);
|
||||
M[1][3] = 0.f;
|
||||
|
||||
M[2][0] = 2.f*(b*d + a*c);
|
||||
M[2][1] = 2.f*(c*d - a*b);
|
||||
M[2][2] = a2 - b2 - c2 + d2;
|
||||
M[2][3] = 0.f;
|
||||
|
||||
M[3][0] = M[3][1] = M[3][2] = 0.f;
|
||||
M[3][3] = 1.f;
|
||||
}
|
||||
|
||||
LINMATH_H_FUNC void mat4x4o_mul_quat(mat4x4 R, mat4x4 const M, quat const q)
|
||||
{
|
||||
/* XXX: The way this is written only works for orthogonal matrices. */
|
||||
/* TODO: Take care of non-orthogonal case. */
|
||||
quat_mul_vec3(R[0], q, M[0]);
|
||||
quat_mul_vec3(R[1], q, M[1]);
|
||||
quat_mul_vec3(R[2], q, M[2]);
|
||||
|
||||
R[3][0] = R[3][1] = R[3][2] = 0.f;
|
||||
R[0][3] = M[0][3];
|
||||
R[1][3] = M[1][3];
|
||||
R[2][3] = M[2][3];
|
||||
R[3][3] = M[3][3]; // typically 1.0, but here we make it general
|
||||
}
|
||||
LINMATH_H_FUNC void quat_from_mat4x4(quat q, mat4x4 const M)
|
||||
{
|
||||
float r=0.f;
|
||||
int i;
|
||||
|
||||
int perm[] = { 0, 1, 2, 0, 1 };
|
||||
int *p = perm;
|
||||
|
||||
for(i = 0; i<3; i++) {
|
||||
float m = M[i][i];
|
||||
if( m < r )
|
||||
continue;
|
||||
m = r;
|
||||
p = &perm[i];
|
||||
}
|
||||
|
||||
r = sqrtf(1.f + M[p[0]][p[0]] - M[p[1]][p[1]] - M[p[2]][p[2]] );
|
||||
|
||||
if(r < 1e-6) {
|
||||
q[0] = 1.f;
|
||||
q[1] = q[2] = q[3] = 0.f;
|
||||
return;
|
||||
}
|
||||
|
||||
q[0] = r/2.f;
|
||||
q[1] = (M[p[0]][p[1]] - M[p[1]][p[0]])/(2.f*r);
|
||||
q[2] = (M[p[2]][p[0]] - M[p[0]][p[2]])/(2.f*r);
|
||||
q[3] = (M[p[2]][p[1]] - M[p[1]][p[2]])/(2.f*r);
|
||||
}
|
||||
|
||||
LINMATH_H_FUNC void mat4x4_arcball(mat4x4 R, mat4x4 const M, vec2 const _a, vec2 const _b, float s)
|
||||
{
|
||||
vec2 a; memcpy(a, _a, sizeof(a));
|
||||
vec2 b; memcpy(b, _b, sizeof(b));
|
||||
|
||||
float z_a = 0.f;
|
||||
float z_b = 0.f;
|
||||
|
||||
if(vec2_len(a) < 1.f) {
|
||||
z_a = sqrtf(1.f - vec2_mul_inner(a, a));
|
||||
} else {
|
||||
vec2_norm(a, a);
|
||||
}
|
||||
|
||||
if(vec2_len(b) < 1.f) {
|
||||
z_b = sqrtf(1.f - vec2_mul_inner(b, b));
|
||||
} else {
|
||||
vec2_norm(b, b);
|
||||
}
|
||||
|
||||
vec3 a_ = {a[0], a[1], z_a};
|
||||
vec3 b_ = {b[0], b[1], z_b};
|
||||
|
||||
vec3 c_;
|
||||
vec3_mul_cross(c_, a_, b_);
|
||||
|
||||
float const angle = acos(vec3_mul_inner(a_, b_)) * s;
|
||||
mat4x4_rotate(R, M, c_[0], c_[1], c_[2], angle);
|
||||
}
|
||||
#endif
|
||||
117
src/ThirdParty/glfw/deps/mingw/_mingw_dxhelper.h
vendored
Normal file
117
src/ThirdParty/glfw/deps/mingw/_mingw_dxhelper.h
vendored
Normal file
@@ -0,0 +1,117 @@
|
||||
/**
|
||||
* This file has no copyright assigned and is placed in the Public Domain.
|
||||
* This file is part of the mingw-w64 runtime package.
|
||||
* No warranty is given; refer to the file DISCLAIMER within this package.
|
||||
*/
|
||||
|
||||
#if defined(_MSC_VER) && !defined(_MSC_EXTENSIONS)
|
||||
#define NONAMELESSUNION 1
|
||||
#endif
|
||||
#if defined(NONAMELESSSTRUCT) && \
|
||||
!defined(NONAMELESSUNION)
|
||||
#define NONAMELESSUNION 1
|
||||
#endif
|
||||
#if defined(NONAMELESSUNION) && \
|
||||
!defined(NONAMELESSSTRUCT)
|
||||
#define NONAMELESSSTRUCT 1
|
||||
#endif
|
||||
#if !defined(__GNU_EXTENSION)
|
||||
#if defined(__GNUC__) || defined(__GNUG__)
|
||||
#define __GNU_EXTENSION __extension__
|
||||
#else
|
||||
#define __GNU_EXTENSION
|
||||
#endif
|
||||
#endif /* __extension__ */
|
||||
|
||||
#ifndef __ANONYMOUS_DEFINED
|
||||
#define __ANONYMOUS_DEFINED
|
||||
#if defined(__GNUC__) || defined(__GNUG__)
|
||||
#define _ANONYMOUS_UNION __extension__
|
||||
#define _ANONYMOUS_STRUCT __extension__
|
||||
#else
|
||||
#define _ANONYMOUS_UNION
|
||||
#define _ANONYMOUS_STRUCT
|
||||
#endif
|
||||
#ifndef NONAMELESSUNION
|
||||
#define _UNION_NAME(x)
|
||||
#define _STRUCT_NAME(x)
|
||||
#else /* NONAMELESSUNION */
|
||||
#define _UNION_NAME(x) x
|
||||
#define _STRUCT_NAME(x) x
|
||||
#endif
|
||||
#endif /* __ANONYMOUS_DEFINED */
|
||||
|
||||
#ifndef DUMMYUNIONNAME
|
||||
# ifdef NONAMELESSUNION
|
||||
# define DUMMYUNIONNAME u
|
||||
# define DUMMYUNIONNAME1 u1 /* Wine uses this variant */
|
||||
# define DUMMYUNIONNAME2 u2
|
||||
# define DUMMYUNIONNAME3 u3
|
||||
# define DUMMYUNIONNAME4 u4
|
||||
# define DUMMYUNIONNAME5 u5
|
||||
# define DUMMYUNIONNAME6 u6
|
||||
# define DUMMYUNIONNAME7 u7
|
||||
# define DUMMYUNIONNAME8 u8
|
||||
# define DUMMYUNIONNAME9 u9
|
||||
# else /* NONAMELESSUNION */
|
||||
# define DUMMYUNIONNAME
|
||||
# define DUMMYUNIONNAME1 /* Wine uses this variant */
|
||||
# define DUMMYUNIONNAME2
|
||||
# define DUMMYUNIONNAME3
|
||||
# define DUMMYUNIONNAME4
|
||||
# define DUMMYUNIONNAME5
|
||||
# define DUMMYUNIONNAME6
|
||||
# define DUMMYUNIONNAME7
|
||||
# define DUMMYUNIONNAME8
|
||||
# define DUMMYUNIONNAME9
|
||||
# endif
|
||||
#endif /* DUMMYUNIONNAME */
|
||||
|
||||
#if !defined(DUMMYUNIONNAME1) /* MinGW does not define this one */
|
||||
# ifdef NONAMELESSUNION
|
||||
# define DUMMYUNIONNAME1 u1 /* Wine uses this variant */
|
||||
# else
|
||||
# define DUMMYUNIONNAME1 /* Wine uses this variant */
|
||||
# endif
|
||||
#endif /* DUMMYUNIONNAME1 */
|
||||
|
||||
#ifndef DUMMYSTRUCTNAME
|
||||
# ifdef NONAMELESSUNION
|
||||
# define DUMMYSTRUCTNAME s
|
||||
# define DUMMYSTRUCTNAME1 s1 /* Wine uses this variant */
|
||||
# define DUMMYSTRUCTNAME2 s2
|
||||
# define DUMMYSTRUCTNAME3 s3
|
||||
# define DUMMYSTRUCTNAME4 s4
|
||||
# define DUMMYSTRUCTNAME5 s5
|
||||
# else
|
||||
# define DUMMYSTRUCTNAME
|
||||
# define DUMMYSTRUCTNAME1 /* Wine uses this variant */
|
||||
# define DUMMYSTRUCTNAME2
|
||||
# define DUMMYSTRUCTNAME3
|
||||
# define DUMMYSTRUCTNAME4
|
||||
# define DUMMYSTRUCTNAME5
|
||||
# endif
|
||||
#endif /* DUMMYSTRUCTNAME */
|
||||
|
||||
/* These are for compatibility with the Wine source tree */
|
||||
|
||||
#ifndef WINELIB_NAME_AW
|
||||
# ifdef __MINGW_NAME_AW
|
||||
# define WINELIB_NAME_AW __MINGW_NAME_AW
|
||||
# else
|
||||
# ifdef UNICODE
|
||||
# define WINELIB_NAME_AW(func) func##W
|
||||
# else
|
||||
# define WINELIB_NAME_AW(func) func##A
|
||||
# endif
|
||||
# endif
|
||||
#endif /* WINELIB_NAME_AW */
|
||||
|
||||
#ifndef DECL_WINELIB_TYPE_AW
|
||||
# ifdef __MINGW_TYPEDEF_AW
|
||||
# define DECL_WINELIB_TYPE_AW __MINGW_TYPEDEF_AW
|
||||
# else
|
||||
# define DECL_WINELIB_TYPE_AW(type) typedef WINELIB_NAME_AW(type) type;
|
||||
# endif
|
||||
#endif /* DECL_WINELIB_TYPE_AW */
|
||||
|
||||
2467
src/ThirdParty/glfw/deps/mingw/dinput.h
vendored
Normal file
2467
src/ThirdParty/glfw/deps/mingw/dinput.h
vendored
Normal file
File diff suppressed because it is too large
Load Diff
239
src/ThirdParty/glfw/deps/mingw/xinput.h
vendored
Normal file
239
src/ThirdParty/glfw/deps/mingw/xinput.h
vendored
Normal file
@@ -0,0 +1,239 @@
|
||||
/*
|
||||
* The Wine project - Xinput Joystick Library
|
||||
* Copyright 2008 Andrew Fenn
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#ifndef __WINE_XINPUT_H
|
||||
#define __WINE_XINPUT_H
|
||||
|
||||
#include <windef.h>
|
||||
|
||||
/*
|
||||
* Bitmasks for the joysticks buttons, determines what has
|
||||
* been pressed on the joystick, these need to be mapped
|
||||
* to whatever device you're using instead of an xbox 360
|
||||
* joystick
|
||||
*/
|
||||
|
||||
#define XINPUT_GAMEPAD_DPAD_UP 0x0001
|
||||
#define XINPUT_GAMEPAD_DPAD_DOWN 0x0002
|
||||
#define XINPUT_GAMEPAD_DPAD_LEFT 0x0004
|
||||
#define XINPUT_GAMEPAD_DPAD_RIGHT 0x0008
|
||||
#define XINPUT_GAMEPAD_START 0x0010
|
||||
#define XINPUT_GAMEPAD_BACK 0x0020
|
||||
#define XINPUT_GAMEPAD_LEFT_THUMB 0x0040
|
||||
#define XINPUT_GAMEPAD_RIGHT_THUMB 0x0080
|
||||
#define XINPUT_GAMEPAD_LEFT_SHOULDER 0x0100
|
||||
#define XINPUT_GAMEPAD_RIGHT_SHOULDER 0x0200
|
||||
#define XINPUT_GAMEPAD_A 0x1000
|
||||
#define XINPUT_GAMEPAD_B 0x2000
|
||||
#define XINPUT_GAMEPAD_X 0x4000
|
||||
#define XINPUT_GAMEPAD_Y 0x8000
|
||||
|
||||
/*
|
||||
* Defines the flags used to determine if the user is pushing
|
||||
* down on a button, not holding a button, etc
|
||||
*/
|
||||
|
||||
#define XINPUT_KEYSTROKE_KEYDOWN 0x0001
|
||||
#define XINPUT_KEYSTROKE_KEYUP 0x0002
|
||||
#define XINPUT_KEYSTROKE_REPEAT 0x0004
|
||||
|
||||
/*
|
||||
* Defines the codes which are returned by XInputGetKeystroke
|
||||
*/
|
||||
|
||||
#define VK_PAD_A 0x5800
|
||||
#define VK_PAD_B 0x5801
|
||||
#define VK_PAD_X 0x5802
|
||||
#define VK_PAD_Y 0x5803
|
||||
#define VK_PAD_RSHOULDER 0x5804
|
||||
#define VK_PAD_LSHOULDER 0x5805
|
||||
#define VK_PAD_LTRIGGER 0x5806
|
||||
#define VK_PAD_RTRIGGER 0x5807
|
||||
#define VK_PAD_DPAD_UP 0x5810
|
||||
#define VK_PAD_DPAD_DOWN 0x5811
|
||||
#define VK_PAD_DPAD_LEFT 0x5812
|
||||
#define VK_PAD_DPAD_RIGHT 0x5813
|
||||
#define VK_PAD_START 0x5814
|
||||
#define VK_PAD_BACK 0x5815
|
||||
#define VK_PAD_LTHUMB_PRESS 0x5816
|
||||
#define VK_PAD_RTHUMB_PRESS 0x5817
|
||||
#define VK_PAD_LTHUMB_UP 0x5820
|
||||
#define VK_PAD_LTHUMB_DOWN 0x5821
|
||||
#define VK_PAD_LTHUMB_RIGHT 0x5822
|
||||
#define VK_PAD_LTHUMB_LEFT 0x5823
|
||||
#define VK_PAD_LTHUMB_UPLEFT 0x5824
|
||||
#define VK_PAD_LTHUMB_UPRIGHT 0x5825
|
||||
#define VK_PAD_LTHUMB_DOWNRIGHT 0x5826
|
||||
#define VK_PAD_LTHUMB_DOWNLEFT 0x5827
|
||||
#define VK_PAD_RTHUMB_UP 0x5830
|
||||
#define VK_PAD_RTHUMB_DOWN 0x5831
|
||||
#define VK_PAD_RTHUMB_RIGHT 0x5832
|
||||
#define VK_PAD_RTHUMB_LEFT 0x5833
|
||||
#define VK_PAD_RTHUMB_UPLEFT 0x5834
|
||||
#define VK_PAD_RTHUMB_UPRIGHT 0x5835
|
||||
#define VK_PAD_RTHUMB_DOWNRIGHT 0x5836
|
||||
#define VK_PAD_RTHUMB_DOWNLEFT 0x5837
|
||||
|
||||
/*
|
||||
* Deadzones are for analogue joystick controls on the joypad
|
||||
* which determine when input should be assumed to be in the
|
||||
* middle of the pad. This is a threshold to stop a joypad
|
||||
* controlling the game when the player isn't touching the
|
||||
* controls.
|
||||
*/
|
||||
|
||||
#define XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE 7849
|
||||
#define XINPUT_GAMEPAD_RIGHT_THUMB_DEADZONE 8689
|
||||
#define XINPUT_GAMEPAD_TRIGGER_THRESHOLD 30
|
||||
|
||||
|
||||
/*
|
||||
* Defines what type of abilities the type of joystick has
|
||||
* DEVTYPE_GAMEPAD is available for all joysticks, however
|
||||
* there may be more specific identifiers for other joysticks
|
||||
* which are being used.
|
||||
*/
|
||||
|
||||
#define XINPUT_DEVTYPE_GAMEPAD 0x01
|
||||
#define XINPUT_DEVSUBTYPE_GAMEPAD 0x01
|
||||
#define XINPUT_DEVSUBTYPE_WHEEL 0x02
|
||||
#define XINPUT_DEVSUBTYPE_ARCADE_STICK 0x03
|
||||
#define XINPUT_DEVSUBTYPE_FLIGHT_SICK 0x04
|
||||
#define XINPUT_DEVSUBTYPE_DANCE_PAD 0x05
|
||||
#define XINPUT_DEVSUBTYPE_GUITAR 0x06
|
||||
#define XINPUT_DEVSUBTYPE_DRUM_KIT 0x08
|
||||
|
||||
/*
|
||||
* These are used with the XInputGetCapabilities function to
|
||||
* determine the abilities to the joystick which has been
|
||||
* plugged in.
|
||||
*/
|
||||
|
||||
#define XINPUT_CAPS_VOICE_SUPPORTED 0x0004
|
||||
#define XINPUT_FLAG_GAMEPAD 0x00000001
|
||||
|
||||
/*
|
||||
* Defines the status of the battery if one is used in the
|
||||
* attached joystick. The first two define if the joystick
|
||||
* supports a battery. Disconnected means that the joystick
|
||||
* isn't connected. Wired shows that the joystick is a wired
|
||||
* joystick.
|
||||
*/
|
||||
|
||||
#define BATTERY_DEVTYPE_GAMEPAD 0x00
|
||||
#define BATTERY_DEVTYPE_HEADSET 0x01
|
||||
#define BATTERY_TYPE_DISCONNECTED 0x00
|
||||
#define BATTERY_TYPE_WIRED 0x01
|
||||
#define BATTERY_TYPE_ALKALINE 0x02
|
||||
#define BATTERY_TYPE_NIMH 0x03
|
||||
#define BATTERY_TYPE_UNKNOWN 0xFF
|
||||
#define BATTERY_LEVEL_EMPTY 0x00
|
||||
#define BATTERY_LEVEL_LOW 0x01
|
||||
#define BATTERY_LEVEL_MEDIUM 0x02
|
||||
#define BATTERY_LEVEL_FULL 0x03
|
||||
|
||||
/*
|
||||
* How many joysticks can be used with this library. Games that
|
||||
* use the xinput library will not go over this number.
|
||||
*/
|
||||
|
||||
#define XUSER_MAX_COUNT 4
|
||||
#define XUSER_INDEX_ANY 0x000000FF
|
||||
|
||||
/*
|
||||
* Defines the structure of an xbox 360 joystick.
|
||||
*/
|
||||
|
||||
typedef struct _XINPUT_GAMEPAD {
|
||||
WORD wButtons;
|
||||
BYTE bLeftTrigger;
|
||||
BYTE bRightTrigger;
|
||||
SHORT sThumbLX;
|
||||
SHORT sThumbLY;
|
||||
SHORT sThumbRX;
|
||||
SHORT sThumbRY;
|
||||
} XINPUT_GAMEPAD, *PXINPUT_GAMEPAD;
|
||||
|
||||
typedef struct _XINPUT_STATE {
|
||||
DWORD dwPacketNumber;
|
||||
XINPUT_GAMEPAD Gamepad;
|
||||
} XINPUT_STATE, *PXINPUT_STATE;
|
||||
|
||||
/*
|
||||
* Defines the structure of how much vibration is set on both the
|
||||
* right and left motors in a joystick. If you're not using a 360
|
||||
* joystick you will have to map these to your device.
|
||||
*/
|
||||
|
||||
typedef struct _XINPUT_VIBRATION {
|
||||
WORD wLeftMotorSpeed;
|
||||
WORD wRightMotorSpeed;
|
||||
} XINPUT_VIBRATION, *PXINPUT_VIBRATION;
|
||||
|
||||
/*
|
||||
* Defines the structure for what kind of abilities the joystick has
|
||||
* such abilities are things such as if the joystick has the ability
|
||||
* to send and receive audio, if the joystick is in fact a driving
|
||||
* wheel or perhaps if the joystick is some kind of dance pad or
|
||||
* guitar.
|
||||
*/
|
||||
|
||||
typedef struct _XINPUT_CAPABILITIES {
|
||||
BYTE Type;
|
||||
BYTE SubType;
|
||||
WORD Flags;
|
||||
XINPUT_GAMEPAD Gamepad;
|
||||
XINPUT_VIBRATION Vibration;
|
||||
} XINPUT_CAPABILITIES, *PXINPUT_CAPABILITIES;
|
||||
|
||||
/*
|
||||
* Defines the structure for a joystick input event which is
|
||||
* retrieved using the function XInputGetKeystroke
|
||||
*/
|
||||
typedef struct _XINPUT_KEYSTROKE {
|
||||
WORD VirtualKey;
|
||||
WCHAR Unicode;
|
||||
WORD Flags;
|
||||
BYTE UserIndex;
|
||||
BYTE HidCode;
|
||||
} XINPUT_KEYSTROKE, *PXINPUT_KEYSTROKE;
|
||||
|
||||
typedef struct _XINPUT_BATTERY_INFORMATION
|
||||
{
|
||||
BYTE BatteryType;
|
||||
BYTE BatteryLevel;
|
||||
} XINPUT_BATTERY_INFORMATION, *PXINPUT_BATTERY_INFORMATION;
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
void WINAPI XInputEnable(WINBOOL);
|
||||
DWORD WINAPI XInputSetState(DWORD, XINPUT_VIBRATION*);
|
||||
DWORD WINAPI XInputGetState(DWORD, XINPUT_STATE*);
|
||||
DWORD WINAPI XInputGetKeystroke(DWORD, DWORD, PXINPUT_KEYSTROKE);
|
||||
DWORD WINAPI XInputGetCapabilities(DWORD, DWORD, XINPUT_CAPABILITIES*);
|
||||
DWORD WINAPI XInputGetDSoundAudioDeviceGuids(DWORD, GUID*, GUID*);
|
||||
DWORD WINAPI XInputGetBatteryInformation(DWORD, BYTE, XINPUT_BATTERY_INFORMATION*);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __WINE_XINPUT_H */
|
||||
25778
src/ThirdParty/glfw/deps/nuklear.h
vendored
Normal file
25778
src/ThirdParty/glfw/deps/nuklear.h
vendored
Normal file
File diff suppressed because it is too large
Load Diff
381
src/ThirdParty/glfw/deps/nuklear_glfw_gl2.h
vendored
Normal file
381
src/ThirdParty/glfw/deps/nuklear_glfw_gl2.h
vendored
Normal file
@@ -0,0 +1,381 @@
|
||||
/*
|
||||
* Nuklear - v1.32.0 - public domain
|
||||
* no warrenty implied; use at your own risk.
|
||||
* authored from 2015-2017 by Micha Mettke
|
||||
*/
|
||||
/*
|
||||
* ==============================================================
|
||||
*
|
||||
* API
|
||||
*
|
||||
* ===============================================================
|
||||
*/
|
||||
#ifndef NK_GLFW_GL2_H_
|
||||
#define NK_GLFW_GL2_H_
|
||||
|
||||
#include <GLFW/glfw3.h>
|
||||
|
||||
enum nk_glfw_init_state{
|
||||
NK_GLFW3_DEFAULT = 0,
|
||||
NK_GLFW3_INSTALL_CALLBACKS
|
||||
};
|
||||
NK_API struct nk_context* nk_glfw3_init(GLFWwindow *win, enum nk_glfw_init_state);
|
||||
NK_API void nk_glfw3_font_stash_begin(struct nk_font_atlas **atlas);
|
||||
NK_API void nk_glfw3_font_stash_end(void);
|
||||
|
||||
NK_API void nk_glfw3_new_frame(void);
|
||||
NK_API void nk_glfw3_render(enum nk_anti_aliasing);
|
||||
NK_API void nk_glfw3_shutdown(void);
|
||||
|
||||
NK_API void nk_glfw3_char_callback(GLFWwindow *win, unsigned int codepoint);
|
||||
NK_API void nk_gflw3_scroll_callback(GLFWwindow *win, double xoff, double yoff);
|
||||
|
||||
#endif
|
||||
|
||||
/*
|
||||
* ==============================================================
|
||||
*
|
||||
* IMPLEMENTATION
|
||||
*
|
||||
* ===============================================================
|
||||
*/
|
||||
#ifdef NK_GLFW_GL2_IMPLEMENTATION
|
||||
|
||||
#ifndef NK_GLFW_TEXT_MAX
|
||||
#define NK_GLFW_TEXT_MAX 256
|
||||
#endif
|
||||
#ifndef NK_GLFW_DOUBLE_CLICK_LO
|
||||
#define NK_GLFW_DOUBLE_CLICK_LO 0.02
|
||||
#endif
|
||||
#ifndef NK_GLFW_DOUBLE_CLICK_HI
|
||||
#define NK_GLFW_DOUBLE_CLICK_HI 0.2
|
||||
#endif
|
||||
|
||||
struct nk_glfw_device {
|
||||
struct nk_buffer cmds;
|
||||
struct nk_draw_null_texture null;
|
||||
GLuint font_tex;
|
||||
};
|
||||
|
||||
struct nk_glfw_vertex {
|
||||
float position[2];
|
||||
float uv[2];
|
||||
nk_byte col[4];
|
||||
};
|
||||
|
||||
static struct nk_glfw {
|
||||
GLFWwindow *win;
|
||||
int width, height;
|
||||
int display_width, display_height;
|
||||
struct nk_glfw_device ogl;
|
||||
struct nk_context ctx;
|
||||
struct nk_font_atlas atlas;
|
||||
struct nk_vec2 fb_scale;
|
||||
unsigned int text[NK_GLFW_TEXT_MAX];
|
||||
int text_len;
|
||||
struct nk_vec2 scroll;
|
||||
double last_button_click;
|
||||
int is_double_click_down;
|
||||
struct nk_vec2 double_click_pos;
|
||||
} glfw;
|
||||
|
||||
NK_INTERN void
|
||||
nk_glfw3_device_upload_atlas(const void *image, int width, int height)
|
||||
{
|
||||
struct nk_glfw_device *dev = &glfw.ogl;
|
||||
glGenTextures(1, &dev->font_tex);
|
||||
glBindTexture(GL_TEXTURE_2D, dev->font_tex);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, (GLsizei)width, (GLsizei)height, 0,
|
||||
GL_RGBA, GL_UNSIGNED_BYTE, image);
|
||||
}
|
||||
|
||||
NK_API void
|
||||
nk_glfw3_render(enum nk_anti_aliasing AA)
|
||||
{
|
||||
/* setup global state */
|
||||
struct nk_glfw_device *dev = &glfw.ogl;
|
||||
glPushAttrib(GL_ENABLE_BIT|GL_COLOR_BUFFER_BIT|GL_TRANSFORM_BIT);
|
||||
glDisable(GL_CULL_FACE);
|
||||
glDisable(GL_DEPTH_TEST);
|
||||
glEnable(GL_SCISSOR_TEST);
|
||||
glEnable(GL_BLEND);
|
||||
glEnable(GL_TEXTURE_2D);
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
|
||||
/* setup viewport/project */
|
||||
glViewport(0,0,(GLsizei)glfw.display_width,(GLsizei)glfw.display_height);
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glPushMatrix();
|
||||
glLoadIdentity();
|
||||
glOrtho(0.0f, glfw.width, glfw.height, 0.0f, -1.0f, 1.0f);
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glPushMatrix();
|
||||
glLoadIdentity();
|
||||
|
||||
glEnableClientState(GL_VERTEX_ARRAY);
|
||||
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||
glEnableClientState(GL_COLOR_ARRAY);
|
||||
{
|
||||
GLsizei vs = sizeof(struct nk_glfw_vertex);
|
||||
size_t vp = offsetof(struct nk_glfw_vertex, position);
|
||||
size_t vt = offsetof(struct nk_glfw_vertex, uv);
|
||||
size_t vc = offsetof(struct nk_glfw_vertex, col);
|
||||
|
||||
/* convert from command queue into draw list and draw to screen */
|
||||
const struct nk_draw_command *cmd;
|
||||
const nk_draw_index *offset = NULL;
|
||||
struct nk_buffer vbuf, ebuf;
|
||||
|
||||
/* fill convert configuration */
|
||||
struct nk_convert_config config;
|
||||
static const struct nk_draw_vertex_layout_element vertex_layout[] = {
|
||||
{NK_VERTEX_POSITION, NK_FORMAT_FLOAT, NK_OFFSETOF(struct nk_glfw_vertex, position)},
|
||||
{NK_VERTEX_TEXCOORD, NK_FORMAT_FLOAT, NK_OFFSETOF(struct nk_glfw_vertex, uv)},
|
||||
{NK_VERTEX_COLOR, NK_FORMAT_R8G8B8A8, NK_OFFSETOF(struct nk_glfw_vertex, col)},
|
||||
{NK_VERTEX_LAYOUT_END}
|
||||
};
|
||||
NK_MEMSET(&config, 0, sizeof(config));
|
||||
config.vertex_layout = vertex_layout;
|
||||
config.vertex_size = sizeof(struct nk_glfw_vertex);
|
||||
config.vertex_alignment = NK_ALIGNOF(struct nk_glfw_vertex);
|
||||
config.null = dev->null;
|
||||
config.circle_segment_count = 22;
|
||||
config.curve_segment_count = 22;
|
||||
config.arc_segment_count = 22;
|
||||
config.global_alpha = 1.0f;
|
||||
config.shape_AA = AA;
|
||||
config.line_AA = AA;
|
||||
|
||||
/* convert shapes into vertexes */
|
||||
nk_buffer_init_default(&vbuf);
|
||||
nk_buffer_init_default(&ebuf);
|
||||
nk_convert(&glfw.ctx, &dev->cmds, &vbuf, &ebuf, &config);
|
||||
|
||||
/* setup vertex buffer pointer */
|
||||
{const void *vertices = nk_buffer_memory_const(&vbuf);
|
||||
glVertexPointer(2, GL_FLOAT, vs, (const void*)((const nk_byte*)vertices + vp));
|
||||
glTexCoordPointer(2, GL_FLOAT, vs, (const void*)((const nk_byte*)vertices + vt));
|
||||
glColorPointer(4, GL_UNSIGNED_BYTE, vs, (const void*)((const nk_byte*)vertices + vc));}
|
||||
|
||||
/* iterate over and execute each draw command */
|
||||
offset = (const nk_draw_index*)nk_buffer_memory_const(&ebuf);
|
||||
nk_draw_foreach(cmd, &glfw.ctx, &dev->cmds)
|
||||
{
|
||||
if (!cmd->elem_count) continue;
|
||||
glBindTexture(GL_TEXTURE_2D, (GLuint)cmd->texture.id);
|
||||
glScissor(
|
||||
(GLint)(cmd->clip_rect.x * glfw.fb_scale.x),
|
||||
(GLint)((glfw.height - (GLint)(cmd->clip_rect.y + cmd->clip_rect.h)) * glfw.fb_scale.y),
|
||||
(GLint)(cmd->clip_rect.w * glfw.fb_scale.x),
|
||||
(GLint)(cmd->clip_rect.h * glfw.fb_scale.y));
|
||||
glDrawElements(GL_TRIANGLES, (GLsizei)cmd->elem_count, GL_UNSIGNED_SHORT, offset);
|
||||
offset += cmd->elem_count;
|
||||
}
|
||||
nk_clear(&glfw.ctx);
|
||||
nk_buffer_free(&vbuf);
|
||||
nk_buffer_free(&ebuf);
|
||||
}
|
||||
|
||||
/* default OpenGL state */
|
||||
glDisableClientState(GL_VERTEX_ARRAY);
|
||||
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||
glDisableClientState(GL_COLOR_ARRAY);
|
||||
|
||||
glDisable(GL_CULL_FACE);
|
||||
glDisable(GL_DEPTH_TEST);
|
||||
glDisable(GL_SCISSOR_TEST);
|
||||
glDisable(GL_BLEND);
|
||||
glDisable(GL_TEXTURE_2D);
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glPopMatrix();
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glPopMatrix();
|
||||
glPopAttrib();
|
||||
}
|
||||
|
||||
NK_API void
|
||||
nk_glfw3_char_callback(GLFWwindow *win, unsigned int codepoint)
|
||||
{
|
||||
(void)win;
|
||||
if (glfw.text_len < NK_GLFW_TEXT_MAX)
|
||||
glfw.text[glfw.text_len++] = codepoint;
|
||||
}
|
||||
|
||||
NK_API void
|
||||
nk_gflw3_scroll_callback(GLFWwindow *win, double xoff, double yoff)
|
||||
{
|
||||
(void)win; (void)xoff;
|
||||
glfw.scroll.x += (float)xoff;
|
||||
glfw.scroll.y += (float)yoff;
|
||||
}
|
||||
|
||||
NK_API void
|
||||
nk_glfw3_mouse_button_callback(GLFWwindow* window, int button, int action, int mods)
|
||||
{
|
||||
double x, y;
|
||||
if (button != GLFW_MOUSE_BUTTON_LEFT) return;
|
||||
glfwGetCursorPos(window, &x, &y);
|
||||
if (action == GLFW_PRESS) {
|
||||
double dt = glfwGetTime() - glfw.last_button_click;
|
||||
if (dt > NK_GLFW_DOUBLE_CLICK_LO && dt < NK_GLFW_DOUBLE_CLICK_HI) {
|
||||
glfw.is_double_click_down = nk_true;
|
||||
glfw.double_click_pos = nk_vec2((float)x, (float)y);
|
||||
}
|
||||
glfw.last_button_click = glfwGetTime();
|
||||
} else glfw.is_double_click_down = nk_false;
|
||||
}
|
||||
|
||||
NK_INTERN void
|
||||
nk_glfw3_clipboard_paste(nk_handle usr, struct nk_text_edit *edit)
|
||||
{
|
||||
const char *text = glfwGetClipboardString(glfw.win);
|
||||
if (text) nk_textedit_paste(edit, text, nk_strlen(text));
|
||||
(void)usr;
|
||||
}
|
||||
|
||||
NK_INTERN void
|
||||
nk_glfw3_clipboard_copy(nk_handle usr, const char *text, int len)
|
||||
{
|
||||
char *str = 0;
|
||||
(void)usr;
|
||||
if (!len) return;
|
||||
str = (char*)malloc((size_t)len+1);
|
||||
if (!str) return;
|
||||
NK_MEMCPY(str, text, (size_t)len);
|
||||
str[len] = '\0';
|
||||
glfwSetClipboardString(glfw.win, str);
|
||||
free(str);
|
||||
}
|
||||
|
||||
NK_API struct nk_context*
|
||||
nk_glfw3_init(GLFWwindow *win, enum nk_glfw_init_state init_state)
|
||||
{
|
||||
glfw.win = win;
|
||||
if (init_state == NK_GLFW3_INSTALL_CALLBACKS) {
|
||||
glfwSetScrollCallback(win, nk_gflw3_scroll_callback);
|
||||
glfwSetCharCallback(win, nk_glfw3_char_callback);
|
||||
glfwSetMouseButtonCallback(win, nk_glfw3_mouse_button_callback);
|
||||
}
|
||||
nk_init_default(&glfw.ctx, 0);
|
||||
glfw.ctx.clip.copy = nk_glfw3_clipboard_copy;
|
||||
glfw.ctx.clip.paste = nk_glfw3_clipboard_paste;
|
||||
glfw.ctx.clip.userdata = nk_handle_ptr(0);
|
||||
nk_buffer_init_default(&glfw.ogl.cmds);
|
||||
|
||||
glfw.is_double_click_down = nk_false;
|
||||
glfw.double_click_pos = nk_vec2(0, 0);
|
||||
|
||||
return &glfw.ctx;
|
||||
}
|
||||
|
||||
NK_API void
|
||||
nk_glfw3_font_stash_begin(struct nk_font_atlas **atlas)
|
||||
{
|
||||
nk_font_atlas_init_default(&glfw.atlas);
|
||||
nk_font_atlas_begin(&glfw.atlas);
|
||||
*atlas = &glfw.atlas;
|
||||
}
|
||||
|
||||
NK_API void
|
||||
nk_glfw3_font_stash_end(void)
|
||||
{
|
||||
const void *image; int w, h;
|
||||
image = nk_font_atlas_bake(&glfw.atlas, &w, &h, NK_FONT_ATLAS_RGBA32);
|
||||
nk_glfw3_device_upload_atlas(image, w, h);
|
||||
nk_font_atlas_end(&glfw.atlas, nk_handle_id((int)glfw.ogl.font_tex), &glfw.ogl.null);
|
||||
if (glfw.atlas.default_font)
|
||||
nk_style_set_font(&glfw.ctx, &glfw.atlas.default_font->handle);
|
||||
}
|
||||
|
||||
NK_API void
|
||||
nk_glfw3_new_frame(void)
|
||||
{
|
||||
int i;
|
||||
double x, y;
|
||||
struct nk_context *ctx = &glfw.ctx;
|
||||
struct GLFWwindow *win = glfw.win;
|
||||
|
||||
glfwGetWindowSize(win, &glfw.width, &glfw.height);
|
||||
glfwGetFramebufferSize(win, &glfw.display_width, &glfw.display_height);
|
||||
glfw.fb_scale.x = (float)glfw.display_width/(float)glfw.width;
|
||||
glfw.fb_scale.y = (float)glfw.display_height/(float)glfw.height;
|
||||
|
||||
nk_input_begin(ctx);
|
||||
for (i = 0; i < glfw.text_len; ++i)
|
||||
nk_input_unicode(ctx, glfw.text[i]);
|
||||
|
||||
/* optional grabbing behavior */
|
||||
if (ctx->input.mouse.grab)
|
||||
glfwSetInputMode(glfw.win, GLFW_CURSOR, GLFW_CURSOR_HIDDEN);
|
||||
else if (ctx->input.mouse.ungrab)
|
||||
glfwSetInputMode(glfw.win, GLFW_CURSOR, GLFW_CURSOR_NORMAL);
|
||||
|
||||
nk_input_key(ctx, NK_KEY_DEL, glfwGetKey(win, GLFW_KEY_DELETE) == GLFW_PRESS);
|
||||
nk_input_key(ctx, NK_KEY_ENTER, glfwGetKey(win, GLFW_KEY_ENTER) == GLFW_PRESS);
|
||||
nk_input_key(ctx, NK_KEY_TAB, glfwGetKey(win, GLFW_KEY_TAB) == GLFW_PRESS);
|
||||
nk_input_key(ctx, NK_KEY_BACKSPACE, glfwGetKey(win, GLFW_KEY_BACKSPACE) == GLFW_PRESS);
|
||||
nk_input_key(ctx, NK_KEY_UP, glfwGetKey(win, GLFW_KEY_UP) == GLFW_PRESS);
|
||||
nk_input_key(ctx, NK_KEY_DOWN, glfwGetKey(win, GLFW_KEY_DOWN) == GLFW_PRESS);
|
||||
nk_input_key(ctx, NK_KEY_TEXT_START, glfwGetKey(win, GLFW_KEY_HOME) == GLFW_PRESS);
|
||||
nk_input_key(ctx, NK_KEY_TEXT_END, glfwGetKey(win, GLFW_KEY_END) == GLFW_PRESS);
|
||||
nk_input_key(ctx, NK_KEY_SCROLL_START, glfwGetKey(win, GLFW_KEY_HOME) == GLFW_PRESS);
|
||||
nk_input_key(ctx, NK_KEY_SCROLL_END, glfwGetKey(win, GLFW_KEY_END) == GLFW_PRESS);
|
||||
nk_input_key(ctx, NK_KEY_SCROLL_DOWN, glfwGetKey(win, GLFW_KEY_PAGE_DOWN) == GLFW_PRESS);
|
||||
nk_input_key(ctx, NK_KEY_SCROLL_UP, glfwGetKey(win, GLFW_KEY_PAGE_UP) == GLFW_PRESS);
|
||||
nk_input_key(ctx, NK_KEY_SHIFT, glfwGetKey(win, GLFW_KEY_LEFT_SHIFT) == GLFW_PRESS||
|
||||
glfwGetKey(win, GLFW_KEY_RIGHT_SHIFT) == GLFW_PRESS);
|
||||
|
||||
if (glfwGetKey(win, GLFW_KEY_LEFT_CONTROL) == GLFW_PRESS ||
|
||||
glfwGetKey(win, GLFW_KEY_RIGHT_CONTROL) == GLFW_PRESS) {
|
||||
nk_input_key(ctx, NK_KEY_COPY, glfwGetKey(win, GLFW_KEY_C) == GLFW_PRESS);
|
||||
nk_input_key(ctx, NK_KEY_PASTE, glfwGetKey(win, GLFW_KEY_V) == GLFW_PRESS);
|
||||
nk_input_key(ctx, NK_KEY_CUT, glfwGetKey(win, GLFW_KEY_X) == GLFW_PRESS);
|
||||
nk_input_key(ctx, NK_KEY_TEXT_UNDO, glfwGetKey(win, GLFW_KEY_Z) == GLFW_PRESS);
|
||||
nk_input_key(ctx, NK_KEY_TEXT_REDO, glfwGetKey(win, GLFW_KEY_R) == GLFW_PRESS);
|
||||
nk_input_key(ctx, NK_KEY_TEXT_WORD_LEFT, glfwGetKey(win, GLFW_KEY_LEFT) == GLFW_PRESS);
|
||||
nk_input_key(ctx, NK_KEY_TEXT_WORD_RIGHT, glfwGetKey(win, GLFW_KEY_RIGHT) == GLFW_PRESS);
|
||||
nk_input_key(ctx, NK_KEY_TEXT_LINE_START, glfwGetKey(win, GLFW_KEY_B) == GLFW_PRESS);
|
||||
nk_input_key(ctx, NK_KEY_TEXT_LINE_END, glfwGetKey(win, GLFW_KEY_E) == GLFW_PRESS);
|
||||
} else {
|
||||
nk_input_key(ctx, NK_KEY_LEFT, glfwGetKey(win, GLFW_KEY_LEFT) == GLFW_PRESS);
|
||||
nk_input_key(ctx, NK_KEY_RIGHT, glfwGetKey(win, GLFW_KEY_RIGHT) == GLFW_PRESS);
|
||||
nk_input_key(ctx, NK_KEY_COPY, 0);
|
||||
nk_input_key(ctx, NK_KEY_PASTE, 0);
|
||||
nk_input_key(ctx, NK_KEY_CUT, 0);
|
||||
nk_input_key(ctx, NK_KEY_SHIFT, 0);
|
||||
}
|
||||
|
||||
glfwGetCursorPos(win, &x, &y);
|
||||
nk_input_motion(ctx, (int)x, (int)y);
|
||||
if (ctx->input.mouse.grabbed) {
|
||||
glfwSetCursorPos(glfw.win, (double)ctx->input.mouse.prev.x, (double)ctx->input.mouse.prev.y);
|
||||
ctx->input.mouse.pos.x = ctx->input.mouse.prev.x;
|
||||
ctx->input.mouse.pos.y = ctx->input.mouse.prev.y;
|
||||
}
|
||||
|
||||
nk_input_button(ctx, NK_BUTTON_LEFT, (int)x, (int)y, glfwGetMouseButton(win, GLFW_MOUSE_BUTTON_LEFT) == GLFW_PRESS);
|
||||
nk_input_button(ctx, NK_BUTTON_MIDDLE, (int)x, (int)y, glfwGetMouseButton(win, GLFW_MOUSE_BUTTON_MIDDLE) == GLFW_PRESS);
|
||||
nk_input_button(ctx, NK_BUTTON_RIGHT, (int)x, (int)y, glfwGetMouseButton(win, GLFW_MOUSE_BUTTON_RIGHT) == GLFW_PRESS);
|
||||
nk_input_button(ctx, NK_BUTTON_DOUBLE, (int)glfw.double_click_pos.x, (int)glfw.double_click_pos.y, glfw.is_double_click_down);
|
||||
nk_input_scroll(ctx, glfw.scroll);
|
||||
nk_input_end(&glfw.ctx);
|
||||
glfw.text_len = 0;
|
||||
glfw.scroll = nk_vec2(0,0);
|
||||
}
|
||||
|
||||
NK_API
|
||||
void nk_glfw3_shutdown(void)
|
||||
{
|
||||
struct nk_glfw_device *dev = &glfw.ogl;
|
||||
nk_font_atlas_clear(&glfw.atlas);
|
||||
nk_free(&glfw.ctx);
|
||||
glDeleteTextures(1, &dev->font_tex);
|
||||
nk_buffer_free(&dev->cmds);
|
||||
NK_MEMSET(&glfw, 0, sizeof(glfw));
|
||||
}
|
||||
|
||||
#endif
|
||||
1048
src/ThirdParty/glfw/deps/stb_image_write.h
vendored
Normal file
1048
src/ThirdParty/glfw/deps/stb_image_write.h
vendored
Normal file
File diff suppressed because it is too large
Load Diff
594
src/ThirdParty/glfw/deps/tinycthread.c
vendored
Normal file
594
src/ThirdParty/glfw/deps/tinycthread.c
vendored
Normal file
@@ -0,0 +1,594 @@
|
||||
/* -*- mode: c; tab-width: 2; indent-tabs-mode: nil; -*-
|
||||
Copyright (c) 2012 Marcus Geelnard
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
|
||||
3. This notice may not be removed or altered from any source
|
||||
distribution.
|
||||
*/
|
||||
|
||||
/* 2013-01-06 Camilla Löwy <elmindreda@glfw.org>
|
||||
*
|
||||
* Added casts from time_t to DWORD to avoid warnings on VC++.
|
||||
* Fixed time retrieval on POSIX systems.
|
||||
*/
|
||||
|
||||
#include "tinycthread.h"
|
||||
#include <stdlib.h>
|
||||
|
||||
/* Platform specific includes */
|
||||
#if defined(_TTHREAD_POSIX_)
|
||||
#include <signal.h>
|
||||
#include <sched.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/time.h>
|
||||
#include <errno.h>
|
||||
#elif defined(_TTHREAD_WIN32_)
|
||||
#include <process.h>
|
||||
#include <sys/timeb.h>
|
||||
#endif
|
||||
|
||||
/* Standard, good-to-have defines */
|
||||
#ifndef NULL
|
||||
#define NULL (void*)0
|
||||
#endif
|
||||
#ifndef TRUE
|
||||
#define TRUE 1
|
||||
#endif
|
||||
#ifndef FALSE
|
||||
#define FALSE 0
|
||||
#endif
|
||||
|
||||
int mtx_init(mtx_t *mtx, int type)
|
||||
{
|
||||
#if defined(_TTHREAD_WIN32_)
|
||||
mtx->mAlreadyLocked = FALSE;
|
||||
mtx->mRecursive = type & mtx_recursive;
|
||||
InitializeCriticalSection(&mtx->mHandle);
|
||||
return thrd_success;
|
||||
#else
|
||||
int ret;
|
||||
pthread_mutexattr_t attr;
|
||||
pthread_mutexattr_init(&attr);
|
||||
if (type & mtx_recursive)
|
||||
{
|
||||
pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
|
||||
}
|
||||
ret = pthread_mutex_init(mtx, &attr);
|
||||
pthread_mutexattr_destroy(&attr);
|
||||
return ret == 0 ? thrd_success : thrd_error;
|
||||
#endif
|
||||
}
|
||||
|
||||
void mtx_destroy(mtx_t *mtx)
|
||||
{
|
||||
#if defined(_TTHREAD_WIN32_)
|
||||
DeleteCriticalSection(&mtx->mHandle);
|
||||
#else
|
||||
pthread_mutex_destroy(mtx);
|
||||
#endif
|
||||
}
|
||||
|
||||
int mtx_lock(mtx_t *mtx)
|
||||
{
|
||||
#if defined(_TTHREAD_WIN32_)
|
||||
EnterCriticalSection(&mtx->mHandle);
|
||||
if (!mtx->mRecursive)
|
||||
{
|
||||
while(mtx->mAlreadyLocked) Sleep(1000); /* Simulate deadlock... */
|
||||
mtx->mAlreadyLocked = TRUE;
|
||||
}
|
||||
return thrd_success;
|
||||
#else
|
||||
return pthread_mutex_lock(mtx) == 0 ? thrd_success : thrd_error;
|
||||
#endif
|
||||
}
|
||||
|
||||
int mtx_timedlock(mtx_t *mtx, const struct timespec *ts)
|
||||
{
|
||||
/* FIXME! */
|
||||
(void)mtx;
|
||||
(void)ts;
|
||||
return thrd_error;
|
||||
}
|
||||
|
||||
int mtx_trylock(mtx_t *mtx)
|
||||
{
|
||||
#if defined(_TTHREAD_WIN32_)
|
||||
int ret = TryEnterCriticalSection(&mtx->mHandle) ? thrd_success : thrd_busy;
|
||||
if ((!mtx->mRecursive) && (ret == thrd_success) && mtx->mAlreadyLocked)
|
||||
{
|
||||
LeaveCriticalSection(&mtx->mHandle);
|
||||
ret = thrd_busy;
|
||||
}
|
||||
return ret;
|
||||
#else
|
||||
return (pthread_mutex_trylock(mtx) == 0) ? thrd_success : thrd_busy;
|
||||
#endif
|
||||
}
|
||||
|
||||
int mtx_unlock(mtx_t *mtx)
|
||||
{
|
||||
#if defined(_TTHREAD_WIN32_)
|
||||
mtx->mAlreadyLocked = FALSE;
|
||||
LeaveCriticalSection(&mtx->mHandle);
|
||||
return thrd_success;
|
||||
#else
|
||||
return pthread_mutex_unlock(mtx) == 0 ? thrd_success : thrd_error;;
|
||||
#endif
|
||||
}
|
||||
|
||||
#if defined(_TTHREAD_WIN32_)
|
||||
#define _CONDITION_EVENT_ONE 0
|
||||
#define _CONDITION_EVENT_ALL 1
|
||||
#endif
|
||||
|
||||
int cnd_init(cnd_t *cond)
|
||||
{
|
||||
#if defined(_TTHREAD_WIN32_)
|
||||
cond->mWaitersCount = 0;
|
||||
|
||||
/* Init critical section */
|
||||
InitializeCriticalSection(&cond->mWaitersCountLock);
|
||||
|
||||
/* Init events */
|
||||
cond->mEvents[_CONDITION_EVENT_ONE] = CreateEvent(NULL, FALSE, FALSE, NULL);
|
||||
if (cond->mEvents[_CONDITION_EVENT_ONE] == NULL)
|
||||
{
|
||||
cond->mEvents[_CONDITION_EVENT_ALL] = NULL;
|
||||
return thrd_error;
|
||||
}
|
||||
cond->mEvents[_CONDITION_EVENT_ALL] = CreateEvent(NULL, TRUE, FALSE, NULL);
|
||||
if (cond->mEvents[_CONDITION_EVENT_ALL] == NULL)
|
||||
{
|
||||
CloseHandle(cond->mEvents[_CONDITION_EVENT_ONE]);
|
||||
cond->mEvents[_CONDITION_EVENT_ONE] = NULL;
|
||||
return thrd_error;
|
||||
}
|
||||
|
||||
return thrd_success;
|
||||
#else
|
||||
return pthread_cond_init(cond, NULL) == 0 ? thrd_success : thrd_error;
|
||||
#endif
|
||||
}
|
||||
|
||||
void cnd_destroy(cnd_t *cond)
|
||||
{
|
||||
#if defined(_TTHREAD_WIN32_)
|
||||
if (cond->mEvents[_CONDITION_EVENT_ONE] != NULL)
|
||||
{
|
||||
CloseHandle(cond->mEvents[_CONDITION_EVENT_ONE]);
|
||||
}
|
||||
if (cond->mEvents[_CONDITION_EVENT_ALL] != NULL)
|
||||
{
|
||||
CloseHandle(cond->mEvents[_CONDITION_EVENT_ALL]);
|
||||
}
|
||||
DeleteCriticalSection(&cond->mWaitersCountLock);
|
||||
#else
|
||||
pthread_cond_destroy(cond);
|
||||
#endif
|
||||
}
|
||||
|
||||
int cnd_signal(cnd_t *cond)
|
||||
{
|
||||
#if defined(_TTHREAD_WIN32_)
|
||||
int haveWaiters;
|
||||
|
||||
/* Are there any waiters? */
|
||||
EnterCriticalSection(&cond->mWaitersCountLock);
|
||||
haveWaiters = (cond->mWaitersCount > 0);
|
||||
LeaveCriticalSection(&cond->mWaitersCountLock);
|
||||
|
||||
/* If we have any waiting threads, send them a signal */
|
||||
if(haveWaiters)
|
||||
{
|
||||
if (SetEvent(cond->mEvents[_CONDITION_EVENT_ONE]) == 0)
|
||||
{
|
||||
return thrd_error;
|
||||
}
|
||||
}
|
||||
|
||||
return thrd_success;
|
||||
#else
|
||||
return pthread_cond_signal(cond) == 0 ? thrd_success : thrd_error;
|
||||
#endif
|
||||
}
|
||||
|
||||
int cnd_broadcast(cnd_t *cond)
|
||||
{
|
||||
#if defined(_TTHREAD_WIN32_)
|
||||
int haveWaiters;
|
||||
|
||||
/* Are there any waiters? */
|
||||
EnterCriticalSection(&cond->mWaitersCountLock);
|
||||
haveWaiters = (cond->mWaitersCount > 0);
|
||||
LeaveCriticalSection(&cond->mWaitersCountLock);
|
||||
|
||||
/* If we have any waiting threads, send them a signal */
|
||||
if(haveWaiters)
|
||||
{
|
||||
if (SetEvent(cond->mEvents[_CONDITION_EVENT_ALL]) == 0)
|
||||
{
|
||||
return thrd_error;
|
||||
}
|
||||
}
|
||||
|
||||
return thrd_success;
|
||||
#else
|
||||
return pthread_cond_signal(cond) == 0 ? thrd_success : thrd_error;
|
||||
#endif
|
||||
}
|
||||
|
||||
#if defined(_TTHREAD_WIN32_)
|
||||
static int _cnd_timedwait_win32(cnd_t *cond, mtx_t *mtx, DWORD timeout)
|
||||
{
|
||||
int result, lastWaiter;
|
||||
|
||||
/* Increment number of waiters */
|
||||
EnterCriticalSection(&cond->mWaitersCountLock);
|
||||
++ cond->mWaitersCount;
|
||||
LeaveCriticalSection(&cond->mWaitersCountLock);
|
||||
|
||||
/* Release the mutex while waiting for the condition (will decrease
|
||||
the number of waiters when done)... */
|
||||
mtx_unlock(mtx);
|
||||
|
||||
/* Wait for either event to become signaled due to cnd_signal() or
|
||||
cnd_broadcast() being called */
|
||||
result = WaitForMultipleObjects(2, cond->mEvents, FALSE, timeout);
|
||||
if (result == WAIT_TIMEOUT)
|
||||
{
|
||||
return thrd_timeout;
|
||||
}
|
||||
else if (result == (int)WAIT_FAILED)
|
||||
{
|
||||
return thrd_error;
|
||||
}
|
||||
|
||||
/* Check if we are the last waiter */
|
||||
EnterCriticalSection(&cond->mWaitersCountLock);
|
||||
-- cond->mWaitersCount;
|
||||
lastWaiter = (result == (WAIT_OBJECT_0 + _CONDITION_EVENT_ALL)) &&
|
||||
(cond->mWaitersCount == 0);
|
||||
LeaveCriticalSection(&cond->mWaitersCountLock);
|
||||
|
||||
/* If we are the last waiter to be notified to stop waiting, reset the event */
|
||||
if (lastWaiter)
|
||||
{
|
||||
if (ResetEvent(cond->mEvents[_CONDITION_EVENT_ALL]) == 0)
|
||||
{
|
||||
return thrd_error;
|
||||
}
|
||||
}
|
||||
|
||||
/* Re-acquire the mutex */
|
||||
mtx_lock(mtx);
|
||||
|
||||
return thrd_success;
|
||||
}
|
||||
#endif
|
||||
|
||||
int cnd_wait(cnd_t *cond, mtx_t *mtx)
|
||||
{
|
||||
#if defined(_TTHREAD_WIN32_)
|
||||
return _cnd_timedwait_win32(cond, mtx, INFINITE);
|
||||
#else
|
||||
return pthread_cond_wait(cond, mtx) == 0 ? thrd_success : thrd_error;
|
||||
#endif
|
||||
}
|
||||
|
||||
int cnd_timedwait(cnd_t *cond, mtx_t *mtx, const struct timespec *ts)
|
||||
{
|
||||
#if defined(_TTHREAD_WIN32_)
|
||||
struct timespec now;
|
||||
if (clock_gettime(CLOCK_REALTIME, &now) == 0)
|
||||
{
|
||||
DWORD delta = (DWORD) ((ts->tv_sec - now.tv_sec) * 1000 +
|
||||
(ts->tv_nsec - now.tv_nsec + 500000) / 1000000);
|
||||
return _cnd_timedwait_win32(cond, mtx, delta);
|
||||
}
|
||||
else
|
||||
return thrd_error;
|
||||
#else
|
||||
int ret;
|
||||
ret = pthread_cond_timedwait(cond, mtx, ts);
|
||||
if (ret == ETIMEDOUT)
|
||||
{
|
||||
return thrd_timeout;
|
||||
}
|
||||
return ret == 0 ? thrd_success : thrd_error;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/** Information to pass to the new thread (what to run). */
|
||||
typedef struct {
|
||||
thrd_start_t mFunction; /**< Pointer to the function to be executed. */
|
||||
void * mArg; /**< Function argument for the thread function. */
|
||||
} _thread_start_info;
|
||||
|
||||
/* Thread wrapper function. */
|
||||
#if defined(_TTHREAD_WIN32_)
|
||||
static unsigned WINAPI _thrd_wrapper_function(void * aArg)
|
||||
#elif defined(_TTHREAD_POSIX_)
|
||||
static void * _thrd_wrapper_function(void * aArg)
|
||||
#endif
|
||||
{
|
||||
thrd_start_t fun;
|
||||
void *arg;
|
||||
int res;
|
||||
#if defined(_TTHREAD_POSIX_)
|
||||
void *pres;
|
||||
#endif
|
||||
|
||||
/* Get thread startup information */
|
||||
_thread_start_info *ti = (_thread_start_info *) aArg;
|
||||
fun = ti->mFunction;
|
||||
arg = ti->mArg;
|
||||
|
||||
/* The thread is responsible for freeing the startup information */
|
||||
free((void *)ti);
|
||||
|
||||
/* Call the actual client thread function */
|
||||
res = fun(arg);
|
||||
|
||||
#if defined(_TTHREAD_WIN32_)
|
||||
return res;
|
||||
#else
|
||||
pres = malloc(sizeof(int));
|
||||
if (pres != NULL)
|
||||
{
|
||||
*(int*)pres = res;
|
||||
}
|
||||
return pres;
|
||||
#endif
|
||||
}
|
||||
|
||||
int thrd_create(thrd_t *thr, thrd_start_t func, void *arg)
|
||||
{
|
||||
/* Fill out the thread startup information (passed to the thread wrapper,
|
||||
which will eventually free it) */
|
||||
_thread_start_info* ti = (_thread_start_info*)malloc(sizeof(_thread_start_info));
|
||||
if (ti == NULL)
|
||||
{
|
||||
return thrd_nomem;
|
||||
}
|
||||
ti->mFunction = func;
|
||||
ti->mArg = arg;
|
||||
|
||||
/* Create the thread */
|
||||
#if defined(_TTHREAD_WIN32_)
|
||||
*thr = (HANDLE)_beginthreadex(NULL, 0, _thrd_wrapper_function, (void *)ti, 0, NULL);
|
||||
#elif defined(_TTHREAD_POSIX_)
|
||||
if(pthread_create(thr, NULL, _thrd_wrapper_function, (void *)ti) != 0)
|
||||
{
|
||||
*thr = 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Did we fail to create the thread? */
|
||||
if(!*thr)
|
||||
{
|
||||
free(ti);
|
||||
return thrd_error;
|
||||
}
|
||||
|
||||
return thrd_success;
|
||||
}
|
||||
|
||||
thrd_t thrd_current(void)
|
||||
{
|
||||
#if defined(_TTHREAD_WIN32_)
|
||||
return GetCurrentThread();
|
||||
#else
|
||||
return pthread_self();
|
||||
#endif
|
||||
}
|
||||
|
||||
int thrd_detach(thrd_t thr)
|
||||
{
|
||||
/* FIXME! */
|
||||
(void)thr;
|
||||
return thrd_error;
|
||||
}
|
||||
|
||||
int thrd_equal(thrd_t thr0, thrd_t thr1)
|
||||
{
|
||||
#if defined(_TTHREAD_WIN32_)
|
||||
return thr0 == thr1;
|
||||
#else
|
||||
return pthread_equal(thr0, thr1);
|
||||
#endif
|
||||
}
|
||||
|
||||
void thrd_exit(int res)
|
||||
{
|
||||
#if defined(_TTHREAD_WIN32_)
|
||||
ExitThread(res);
|
||||
#else
|
||||
void *pres = malloc(sizeof(int));
|
||||
if (pres != NULL)
|
||||
{
|
||||
*(int*)pres = res;
|
||||
}
|
||||
pthread_exit(pres);
|
||||
#endif
|
||||
}
|
||||
|
||||
int thrd_join(thrd_t thr, int *res)
|
||||
{
|
||||
#if defined(_TTHREAD_WIN32_)
|
||||
if (WaitForSingleObject(thr, INFINITE) == WAIT_FAILED)
|
||||
{
|
||||
return thrd_error;
|
||||
}
|
||||
if (res != NULL)
|
||||
{
|
||||
DWORD dwRes;
|
||||
GetExitCodeThread(thr, &dwRes);
|
||||
*res = dwRes;
|
||||
}
|
||||
#elif defined(_TTHREAD_POSIX_)
|
||||
void *pres;
|
||||
int ires = 0;
|
||||
if (pthread_join(thr, &pres) != 0)
|
||||
{
|
||||
return thrd_error;
|
||||
}
|
||||
if (pres != NULL)
|
||||
{
|
||||
ires = *(int*)pres;
|
||||
free(pres);
|
||||
}
|
||||
if (res != NULL)
|
||||
{
|
||||
*res = ires;
|
||||
}
|
||||
#endif
|
||||
return thrd_success;
|
||||
}
|
||||
|
||||
int thrd_sleep(const struct timespec *time_point, struct timespec *remaining)
|
||||
{
|
||||
struct timespec now;
|
||||
#if defined(_TTHREAD_WIN32_)
|
||||
DWORD delta;
|
||||
#else
|
||||
long delta;
|
||||
#endif
|
||||
|
||||
/* Get the current time */
|
||||
if (clock_gettime(CLOCK_REALTIME, &now) != 0)
|
||||
return -2; // FIXME: Some specific error code?
|
||||
|
||||
#if defined(_TTHREAD_WIN32_)
|
||||
/* Delta in milliseconds */
|
||||
delta = (DWORD) ((time_point->tv_sec - now.tv_sec) * 1000 +
|
||||
(time_point->tv_nsec - now.tv_nsec + 500000) / 1000000);
|
||||
if (delta > 0)
|
||||
{
|
||||
Sleep(delta);
|
||||
}
|
||||
#else
|
||||
/* Delta in microseconds */
|
||||
delta = (time_point->tv_sec - now.tv_sec) * 1000000L +
|
||||
(time_point->tv_nsec - now.tv_nsec + 500L) / 1000L;
|
||||
|
||||
/* On some systems, the usleep argument must be < 1000000 */
|
||||
while (delta > 999999L)
|
||||
{
|
||||
usleep(999999);
|
||||
delta -= 999999L;
|
||||
}
|
||||
if (delta > 0L)
|
||||
{
|
||||
usleep((useconds_t)delta);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* We don't support waking up prematurely (yet) */
|
||||
if (remaining)
|
||||
{
|
||||
remaining->tv_sec = 0;
|
||||
remaining->tv_nsec = 0;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void thrd_yield(void)
|
||||
{
|
||||
#if defined(_TTHREAD_WIN32_)
|
||||
Sleep(0);
|
||||
#else
|
||||
sched_yield();
|
||||
#endif
|
||||
}
|
||||
|
||||
int tss_create(tss_t *key, tss_dtor_t dtor)
|
||||
{
|
||||
#if defined(_TTHREAD_WIN32_)
|
||||
/* FIXME: The destructor function is not supported yet... */
|
||||
if (dtor != NULL)
|
||||
{
|
||||
return thrd_error;
|
||||
}
|
||||
*key = TlsAlloc();
|
||||
if (*key == TLS_OUT_OF_INDEXES)
|
||||
{
|
||||
return thrd_error;
|
||||
}
|
||||
#else
|
||||
if (pthread_key_create(key, dtor) != 0)
|
||||
{
|
||||
return thrd_error;
|
||||
}
|
||||
#endif
|
||||
return thrd_success;
|
||||
}
|
||||
|
||||
void tss_delete(tss_t key)
|
||||
{
|
||||
#if defined(_TTHREAD_WIN32_)
|
||||
TlsFree(key);
|
||||
#else
|
||||
pthread_key_delete(key);
|
||||
#endif
|
||||
}
|
||||
|
||||
void *tss_get(tss_t key)
|
||||
{
|
||||
#if defined(_TTHREAD_WIN32_)
|
||||
return TlsGetValue(key);
|
||||
#else
|
||||
return pthread_getspecific(key);
|
||||
#endif
|
||||
}
|
||||
|
||||
int tss_set(tss_t key, void *val)
|
||||
{
|
||||
#if defined(_TTHREAD_WIN32_)
|
||||
if (TlsSetValue(key, val) == 0)
|
||||
{
|
||||
return thrd_error;
|
||||
}
|
||||
#else
|
||||
if (pthread_setspecific(key, val) != 0)
|
||||
{
|
||||
return thrd_error;
|
||||
}
|
||||
#endif
|
||||
return thrd_success;
|
||||
}
|
||||
|
||||
#if defined(_TTHREAD_EMULATE_CLOCK_GETTIME_)
|
||||
int _tthread_clock_gettime(clockid_t clk_id, struct timespec *ts)
|
||||
{
|
||||
#if defined(_TTHREAD_WIN32_)
|
||||
struct _timeb tb;
|
||||
_ftime(&tb);
|
||||
ts->tv_sec = (time_t)tb.time;
|
||||
ts->tv_nsec = 1000000L * (long)tb.millitm;
|
||||
#else
|
||||
struct timeval tv;
|
||||
gettimeofday(&tv, NULL);
|
||||
ts->tv_sec = (time_t)tv.tv_sec;
|
||||
ts->tv_nsec = 1000L * (long)tv.tv_usec;
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
#endif // _TTHREAD_EMULATE_CLOCK_GETTIME_
|
||||
|
||||
443
src/ThirdParty/glfw/deps/tinycthread.h
vendored
Normal file
443
src/ThirdParty/glfw/deps/tinycthread.h
vendored
Normal file
@@ -0,0 +1,443 @@
|
||||
/* -*- mode: c; tab-width: 2; indent-tabs-mode: nil; -*-
|
||||
Copyright (c) 2012 Marcus Geelnard
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
|
||||
3. This notice may not be removed or altered from any source
|
||||
distribution.
|
||||
*/
|
||||
|
||||
#ifndef _TINYCTHREAD_H_
|
||||
#define _TINYCTHREAD_H_
|
||||
|
||||
/**
|
||||
* @file
|
||||
* @mainpage TinyCThread API Reference
|
||||
*
|
||||
* @section intro_sec Introduction
|
||||
* TinyCThread is a minimal, portable implementation of basic threading
|
||||
* classes for C.
|
||||
*
|
||||
* They closely mimic the functionality and naming of the C11 standard, and
|
||||
* should be easily replaceable with the corresponding standard variants.
|
||||
*
|
||||
* @section port_sec Portability
|
||||
* The Win32 variant uses the native Win32 API for implementing the thread
|
||||
* classes, while for other systems, the POSIX threads API (pthread) is used.
|
||||
*
|
||||
* @section misc_sec Miscellaneous
|
||||
* The following special keywords are available: #_Thread_local.
|
||||
*
|
||||
* For more detailed information, browse the different sections of this
|
||||
* documentation. A good place to start is:
|
||||
* tinycthread.h.
|
||||
*/
|
||||
|
||||
/* Which platform are we on? */
|
||||
#if !defined(_TTHREAD_PLATFORM_DEFINED_)
|
||||
#if defined(_WIN32) || defined(__WIN32__) || defined(__WINDOWS__)
|
||||
#define _TTHREAD_WIN32_
|
||||
#else
|
||||
#define _TTHREAD_POSIX_
|
||||
#endif
|
||||
#define _TTHREAD_PLATFORM_DEFINED_
|
||||
#endif
|
||||
|
||||
/* Activate some POSIX functionality (e.g. clock_gettime and recursive mutexes) */
|
||||
#if defined(_TTHREAD_POSIX_)
|
||||
#undef _FEATURES_H
|
||||
#if !defined(_GNU_SOURCE)
|
||||
#define _GNU_SOURCE
|
||||
#endif
|
||||
#if !defined(_POSIX_C_SOURCE) || ((_POSIX_C_SOURCE - 0) < 199309L)
|
||||
#undef _POSIX_C_SOURCE
|
||||
#define _POSIX_C_SOURCE 199309L
|
||||
#endif
|
||||
#if !defined(_XOPEN_SOURCE) || ((_XOPEN_SOURCE - 0) < 500)
|
||||
#undef _XOPEN_SOURCE
|
||||
#define _XOPEN_SOURCE 500
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* Generic includes */
|
||||
#include <time.h>
|
||||
|
||||
/* Platform specific includes */
|
||||
#if defined(_TTHREAD_POSIX_)
|
||||
#include <sys/time.h>
|
||||
#include <pthread.h>
|
||||
#elif defined(_TTHREAD_WIN32_)
|
||||
#ifndef WIN32_LEAN_AND_MEAN
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#define __UNDEF_LEAN_AND_MEAN
|
||||
#endif
|
||||
#include <windows.h>
|
||||
#ifdef __UNDEF_LEAN_AND_MEAN
|
||||
#undef WIN32_LEAN_AND_MEAN
|
||||
#undef __UNDEF_LEAN_AND_MEAN
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* Workaround for missing TIME_UTC: If time.h doesn't provide TIME_UTC,
|
||||
it's quite likely that libc does not support it either. Hence, fall back to
|
||||
the only other supported time specifier: CLOCK_REALTIME (and if that fails,
|
||||
we're probably emulating clock_gettime anyway, so anything goes). */
|
||||
#ifndef TIME_UTC
|
||||
#ifdef CLOCK_REALTIME
|
||||
#define TIME_UTC CLOCK_REALTIME
|
||||
#else
|
||||
#define TIME_UTC 0
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* Workaround for missing clock_gettime (most Windows compilers, afaik) */
|
||||
#if defined(_TTHREAD_WIN32_) || defined(__APPLE_CC__)
|
||||
#define _TTHREAD_EMULATE_CLOCK_GETTIME_
|
||||
/* Emulate struct timespec */
|
||||
#if defined(_TTHREAD_WIN32_)
|
||||
struct _ttherad_timespec {
|
||||
time_t tv_sec;
|
||||
long tv_nsec;
|
||||
};
|
||||
#define timespec _ttherad_timespec
|
||||
#endif
|
||||
|
||||
/* Emulate clockid_t */
|
||||
typedef int _tthread_clockid_t;
|
||||
#define clockid_t _tthread_clockid_t
|
||||
|
||||
/* Emulate clock_gettime */
|
||||
int _tthread_clock_gettime(clockid_t clk_id, struct timespec *ts);
|
||||
#define clock_gettime _tthread_clock_gettime
|
||||
#ifndef CLOCK_REALTIME
|
||||
#define CLOCK_REALTIME 0
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
/** TinyCThread version (major number). */
|
||||
#define TINYCTHREAD_VERSION_MAJOR 1
|
||||
/** TinyCThread version (minor number). */
|
||||
#define TINYCTHREAD_VERSION_MINOR 1
|
||||
/** TinyCThread version (full version). */
|
||||
#define TINYCTHREAD_VERSION (TINYCTHREAD_VERSION_MAJOR * 100 + TINYCTHREAD_VERSION_MINOR)
|
||||
|
||||
/**
|
||||
* @def _Thread_local
|
||||
* Thread local storage keyword.
|
||||
* A variable that is declared with the @c _Thread_local keyword makes the
|
||||
* value of the variable local to each thread (known as thread-local storage,
|
||||
* or TLS). Example usage:
|
||||
* @code
|
||||
* // This variable is local to each thread.
|
||||
* _Thread_local int variable;
|
||||
* @endcode
|
||||
* @note The @c _Thread_local keyword is a macro that maps to the corresponding
|
||||
* compiler directive (e.g. @c __declspec(thread)).
|
||||
* @note This directive is currently not supported on Mac OS X (it will give
|
||||
* a compiler error), since compile-time TLS is not supported in the Mac OS X
|
||||
* executable format. Also, some older versions of MinGW (before GCC 4.x) do
|
||||
* not support this directive.
|
||||
* @hideinitializer
|
||||
*/
|
||||
|
||||
/* FIXME: Check for a PROPER value of __STDC_VERSION__ to know if we have C11 */
|
||||
#if !(defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 201102L)) && !defined(_Thread_local)
|
||||
#if defined(__GNUC__) || defined(__INTEL_COMPILER) || defined(__SUNPRO_CC) || defined(__IBMCPP__)
|
||||
#define _Thread_local __thread
|
||||
#else
|
||||
#define _Thread_local __declspec(thread)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* Macros */
|
||||
#define TSS_DTOR_ITERATIONS 0
|
||||
|
||||
/* Function return values */
|
||||
#define thrd_error 0 /**< The requested operation failed */
|
||||
#define thrd_success 1 /**< The requested operation succeeded */
|
||||
#define thrd_timeout 2 /**< The time specified in the call was reached without acquiring the requested resource */
|
||||
#define thrd_busy 3 /**< The requested operation failed because a tesource requested by a test and return function is already in use */
|
||||
#define thrd_nomem 4 /**< The requested operation failed because it was unable to allocate memory */
|
||||
|
||||
/* Mutex types */
|
||||
#define mtx_plain 1
|
||||
#define mtx_timed 2
|
||||
#define mtx_try 4
|
||||
#define mtx_recursive 8
|
||||
|
||||
/* Mutex */
|
||||
#if defined(_TTHREAD_WIN32_)
|
||||
typedef struct {
|
||||
CRITICAL_SECTION mHandle; /* Critical section handle */
|
||||
int mAlreadyLocked; /* TRUE if the mutex is already locked */
|
||||
int mRecursive; /* TRUE if the mutex is recursive */
|
||||
} mtx_t;
|
||||
#else
|
||||
typedef pthread_mutex_t mtx_t;
|
||||
#endif
|
||||
|
||||
/** Create a mutex object.
|
||||
* @param mtx A mutex object.
|
||||
* @param type Bit-mask that must have one of the following six values:
|
||||
* @li @c mtx_plain for a simple non-recursive mutex
|
||||
* @li @c mtx_timed for a non-recursive mutex that supports timeout
|
||||
* @li @c mtx_try for a non-recursive mutex that supports test and return
|
||||
* @li @c mtx_plain | @c mtx_recursive (same as @c mtx_plain, but recursive)
|
||||
* @li @c mtx_timed | @c mtx_recursive (same as @c mtx_timed, but recursive)
|
||||
* @li @c mtx_try | @c mtx_recursive (same as @c mtx_try, but recursive)
|
||||
* @return @ref thrd_success on success, or @ref thrd_error if the request could
|
||||
* not be honored.
|
||||
*/
|
||||
int mtx_init(mtx_t *mtx, int type);
|
||||
|
||||
/** Release any resources used by the given mutex.
|
||||
* @param mtx A mutex object.
|
||||
*/
|
||||
void mtx_destroy(mtx_t *mtx);
|
||||
|
||||
/** Lock the given mutex.
|
||||
* Blocks until the given mutex can be locked. If the mutex is non-recursive, and
|
||||
* the calling thread already has a lock on the mutex, this call will block
|
||||
* forever.
|
||||
* @param mtx A mutex object.
|
||||
* @return @ref thrd_success on success, or @ref thrd_error if the request could
|
||||
* not be honored.
|
||||
*/
|
||||
int mtx_lock(mtx_t *mtx);
|
||||
|
||||
/** NOT YET IMPLEMENTED.
|
||||
*/
|
||||
int mtx_timedlock(mtx_t *mtx, const struct timespec *ts);
|
||||
|
||||
/** Try to lock the given mutex.
|
||||
* The specified mutex shall support either test and return or timeout. If the
|
||||
* mutex is already locked, the function returns without blocking.
|
||||
* @param mtx A mutex object.
|
||||
* @return @ref thrd_success on success, or @ref thrd_busy if the resource
|
||||
* requested is already in use, or @ref thrd_error if the request could not be
|
||||
* honored.
|
||||
*/
|
||||
int mtx_trylock(mtx_t *mtx);
|
||||
|
||||
/** Unlock the given mutex.
|
||||
* @param mtx A mutex object.
|
||||
* @return @ref thrd_success on success, or @ref thrd_error if the request could
|
||||
* not be honored.
|
||||
*/
|
||||
int mtx_unlock(mtx_t *mtx);
|
||||
|
||||
/* Condition variable */
|
||||
#if defined(_TTHREAD_WIN32_)
|
||||
typedef struct {
|
||||
HANDLE mEvents[2]; /* Signal and broadcast event HANDLEs. */
|
||||
unsigned int mWaitersCount; /* Count of the number of waiters. */
|
||||
CRITICAL_SECTION mWaitersCountLock; /* Serialize access to mWaitersCount. */
|
||||
} cnd_t;
|
||||
#else
|
||||
typedef pthread_cond_t cnd_t;
|
||||
#endif
|
||||
|
||||
/** Create a condition variable object.
|
||||
* @param cond A condition variable object.
|
||||
* @return @ref thrd_success on success, or @ref thrd_error if the request could
|
||||
* not be honored.
|
||||
*/
|
||||
int cnd_init(cnd_t *cond);
|
||||
|
||||
/** Release any resources used by the given condition variable.
|
||||
* @param cond A condition variable object.
|
||||
*/
|
||||
void cnd_destroy(cnd_t *cond);
|
||||
|
||||
/** Signal a condition variable.
|
||||
* Unblocks one of the threads that are blocked on the given condition variable
|
||||
* at the time of the call. If no threads are blocked on the condition variable
|
||||
* at the time of the call, the function does nothing and return success.
|
||||
* @param cond A condition variable object.
|
||||
* @return @ref thrd_success on success, or @ref thrd_error if the request could
|
||||
* not be honored.
|
||||
*/
|
||||
int cnd_signal(cnd_t *cond);
|
||||
|
||||
/** Broadcast a condition variable.
|
||||
* Unblocks all of the threads that are blocked on the given condition variable
|
||||
* at the time of the call. If no threads are blocked on the condition variable
|
||||
* at the time of the call, the function does nothing and return success.
|
||||
* @param cond A condition variable object.
|
||||
* @return @ref thrd_success on success, or @ref thrd_error if the request could
|
||||
* not be honored.
|
||||
*/
|
||||
int cnd_broadcast(cnd_t *cond);
|
||||
|
||||
/** Wait for a condition variable to become signaled.
|
||||
* The function atomically unlocks the given mutex and endeavors to block until
|
||||
* the given condition variable is signaled by a call to cnd_signal or to
|
||||
* cnd_broadcast. When the calling thread becomes unblocked it locks the mutex
|
||||
* before it returns.
|
||||
* @param cond A condition variable object.
|
||||
* @param mtx A mutex object.
|
||||
* @return @ref thrd_success on success, or @ref thrd_error if the request could
|
||||
* not be honored.
|
||||
*/
|
||||
int cnd_wait(cnd_t *cond, mtx_t *mtx);
|
||||
|
||||
/** Wait for a condition variable to become signaled.
|
||||
* The function atomically unlocks the given mutex and endeavors to block until
|
||||
* the given condition variable is signaled by a call to cnd_signal or to
|
||||
* cnd_broadcast, or until after the specified time. When the calling thread
|
||||
* becomes unblocked it locks the mutex before it returns.
|
||||
* @param cond A condition variable object.
|
||||
* @param mtx A mutex object.
|
||||
* @param xt A point in time at which the request will time out (absolute time).
|
||||
* @return @ref thrd_success upon success, or @ref thrd_timeout if the time
|
||||
* specified in the call was reached without acquiring the requested resource, or
|
||||
* @ref thrd_error if the request could not be honored.
|
||||
*/
|
||||
int cnd_timedwait(cnd_t *cond, mtx_t *mtx, const struct timespec *ts);
|
||||
|
||||
/* Thread */
|
||||
#if defined(_TTHREAD_WIN32_)
|
||||
typedef HANDLE thrd_t;
|
||||
#else
|
||||
typedef pthread_t thrd_t;
|
||||
#endif
|
||||
|
||||
/** Thread start function.
|
||||
* Any thread that is started with the @ref thrd_create() function must be
|
||||
* started through a function of this type.
|
||||
* @param arg The thread argument (the @c arg argument of the corresponding
|
||||
* @ref thrd_create() call).
|
||||
* @return The thread return value, which can be obtained by another thread
|
||||
* by using the @ref thrd_join() function.
|
||||
*/
|
||||
typedef int (*thrd_start_t)(void *arg);
|
||||
|
||||
/** Create a new thread.
|
||||
* @param thr Identifier of the newly created thread.
|
||||
* @param func A function pointer to the function that will be executed in
|
||||
* the new thread.
|
||||
* @param arg An argument to the thread function.
|
||||
* @return @ref thrd_success on success, or @ref thrd_nomem if no memory could
|
||||
* be allocated for the thread requested, or @ref thrd_error if the request
|
||||
* could not be honored.
|
||||
* @note A thread’s identifier may be reused for a different thread once the
|
||||
* original thread has exited and either been detached or joined to another
|
||||
* thread.
|
||||
*/
|
||||
int thrd_create(thrd_t *thr, thrd_start_t func, void *arg);
|
||||
|
||||
/** Identify the calling thread.
|
||||
* @return The identifier of the calling thread.
|
||||
*/
|
||||
thrd_t thrd_current(void);
|
||||
|
||||
/** NOT YET IMPLEMENTED.
|
||||
*/
|
||||
int thrd_detach(thrd_t thr);
|
||||
|
||||
/** Compare two thread identifiers.
|
||||
* The function determines if two thread identifiers refer to the same thread.
|
||||
* @return Zero if the two thread identifiers refer to different threads.
|
||||
* Otherwise a nonzero value is returned.
|
||||
*/
|
||||
int thrd_equal(thrd_t thr0, thrd_t thr1);
|
||||
|
||||
/** Terminate execution of the calling thread.
|
||||
* @param res Result code of the calling thread.
|
||||
*/
|
||||
void thrd_exit(int res);
|
||||
|
||||
/** Wait for a thread to terminate.
|
||||
* The function joins the given thread with the current thread by blocking
|
||||
* until the other thread has terminated.
|
||||
* @param thr The thread to join with.
|
||||
* @param res If this pointer is not NULL, the function will store the result
|
||||
* code of the given thread in the integer pointed to by @c res.
|
||||
* @return @ref thrd_success on success, or @ref thrd_error if the request could
|
||||
* not be honored.
|
||||
*/
|
||||
int thrd_join(thrd_t thr, int *res);
|
||||
|
||||
/** Put the calling thread to sleep.
|
||||
* Suspend execution of the calling thread.
|
||||
* @param time_point A point in time at which the thread will resume (absolute time).
|
||||
* @param remaining If non-NULL, this parameter will hold the remaining time until
|
||||
* time_point upon return. This will typically be zero, but if
|
||||
* the thread was woken up by a signal that is not ignored before
|
||||
* time_point was reached @c remaining will hold a positive
|
||||
* time.
|
||||
* @return 0 (zero) on successful sleep, or -1 if an interrupt occurred.
|
||||
*/
|
||||
int thrd_sleep(const struct timespec *time_point, struct timespec *remaining);
|
||||
|
||||
/** Yield execution to another thread.
|
||||
* Permit other threads to run, even if the current thread would ordinarily
|
||||
* continue to run.
|
||||
*/
|
||||
void thrd_yield(void);
|
||||
|
||||
/* Thread local storage */
|
||||
#if defined(_TTHREAD_WIN32_)
|
||||
typedef DWORD tss_t;
|
||||
#else
|
||||
typedef pthread_key_t tss_t;
|
||||
#endif
|
||||
|
||||
/** Destructor function for a thread-specific storage.
|
||||
* @param val The value of the destructed thread-specific storage.
|
||||
*/
|
||||
typedef void (*tss_dtor_t)(void *val);
|
||||
|
||||
/** Create a thread-specific storage.
|
||||
* @param key The unique key identifier that will be set if the function is
|
||||
* successful.
|
||||
* @param dtor Destructor function. This can be NULL.
|
||||
* @return @ref thrd_success on success, or @ref thrd_error if the request could
|
||||
* not be honored.
|
||||
* @note The destructor function is not supported under Windows. If @c dtor is
|
||||
* not NULL when calling this function under Windows, the function will fail
|
||||
* and return @ref thrd_error.
|
||||
*/
|
||||
int tss_create(tss_t *key, tss_dtor_t dtor);
|
||||
|
||||
/** Delete a thread-specific storage.
|
||||
* The function releases any resources used by the given thread-specific
|
||||
* storage.
|
||||
* @param key The key that shall be deleted.
|
||||
*/
|
||||
void tss_delete(tss_t key);
|
||||
|
||||
/** Get the value for a thread-specific storage.
|
||||
* @param key The thread-specific storage identifier.
|
||||
* @return The value for the current thread held in the given thread-specific
|
||||
* storage.
|
||||
*/
|
||||
void *tss_get(tss_t key);
|
||||
|
||||
/** Set the value for a thread-specific storage.
|
||||
* @param key The thread-specific storage identifier.
|
||||
* @param val The value of the thread-specific storage to set for the current
|
||||
* thread.
|
||||
* @return @ref thrd_success on success, or @ref thrd_error if the request could
|
||||
* not be honored.
|
||||
*/
|
||||
int tss_set(tss_t key, void *val);
|
||||
|
||||
|
||||
#endif /* _TINYTHREAD_H_ */
|
||||
|
||||
247
src/ThirdParty/glfw/deps/vs2008/stdint.h
vendored
Normal file
247
src/ThirdParty/glfw/deps/vs2008/stdint.h
vendored
Normal file
@@ -0,0 +1,247 @@
|
||||
// ISO C9x compliant stdint.h for Microsoft Visual Studio
|
||||
// Based on ISO/IEC 9899:TC2 Committee draft (May 6, 2005) WG14/N1124
|
||||
//
|
||||
// Copyright (c) 2006-2008 Alexander Chemeris
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are met:
|
||||
//
|
||||
// 1. Redistributions of source code must retain the above copyright notice,
|
||||
// this list of conditions and the following disclaimer.
|
||||
//
|
||||
// 2. Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
//
|
||||
// 3. The name of the author may be used to endorse or promote products
|
||||
// derived from this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||
// WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
|
||||
// EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||
// OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
// ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef _MSC_VER // [
|
||||
#error "Use this header only with Microsoft Visual C++ compilers!"
|
||||
#endif // _MSC_VER ]
|
||||
|
||||
#ifndef _MSC_STDINT_H_ // [
|
||||
#define _MSC_STDINT_H_
|
||||
|
||||
#if _MSC_VER > 1000
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include <limits.h>
|
||||
|
||||
// For Visual Studio 6 in C++ mode and for many Visual Studio versions when
|
||||
// compiling for ARM we should wrap <wchar.h> include with 'extern "C++" {}'
|
||||
// or compiler give many errors like this:
|
||||
// error C2733: second C linkage of overloaded function 'wmemchr' not allowed
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
# include <wchar.h>
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
// Define _W64 macros to mark types changing their size, like intptr_t.
|
||||
#ifndef _W64
|
||||
# if !defined(__midl) && (defined(_X86_) || defined(_M_IX86)) && _MSC_VER >= 1300
|
||||
# define _W64 __w64
|
||||
# else
|
||||
# define _W64
|
||||
# endif
|
||||
#endif
|
||||
|
||||
|
||||
// 7.18.1 Integer types
|
||||
|
||||
// 7.18.1.1 Exact-width integer types
|
||||
|
||||
// Visual Studio 6 and Embedded Visual C++ 4 doesn't
|
||||
// realize that, e.g. char has the same size as __int8
|
||||
// so we give up on __intX for them.
|
||||
#if (_MSC_VER < 1300)
|
||||
typedef signed char int8_t;
|
||||
typedef signed short int16_t;
|
||||
typedef signed int int32_t;
|
||||
typedef unsigned char uint8_t;
|
||||
typedef unsigned short uint16_t;
|
||||
typedef unsigned int uint32_t;
|
||||
#else
|
||||
typedef signed __int8 int8_t;
|
||||
typedef signed __int16 int16_t;
|
||||
typedef signed __int32 int32_t;
|
||||
typedef unsigned __int8 uint8_t;
|
||||
typedef unsigned __int16 uint16_t;
|
||||
typedef unsigned __int32 uint32_t;
|
||||
#endif
|
||||
typedef signed __int64 int64_t;
|
||||
typedef unsigned __int64 uint64_t;
|
||||
|
||||
|
||||
// 7.18.1.2 Minimum-width integer types
|
||||
typedef int8_t int_least8_t;
|
||||
typedef int16_t int_least16_t;
|
||||
typedef int32_t int_least32_t;
|
||||
typedef int64_t int_least64_t;
|
||||
typedef uint8_t uint_least8_t;
|
||||
typedef uint16_t uint_least16_t;
|
||||
typedef uint32_t uint_least32_t;
|
||||
typedef uint64_t uint_least64_t;
|
||||
|
||||
// 7.18.1.3 Fastest minimum-width integer types
|
||||
typedef int8_t int_fast8_t;
|
||||
typedef int16_t int_fast16_t;
|
||||
typedef int32_t int_fast32_t;
|
||||
typedef int64_t int_fast64_t;
|
||||
typedef uint8_t uint_fast8_t;
|
||||
typedef uint16_t uint_fast16_t;
|
||||
typedef uint32_t uint_fast32_t;
|
||||
typedef uint64_t uint_fast64_t;
|
||||
|
||||
// 7.18.1.4 Integer types capable of holding object pointers
|
||||
#ifdef _WIN64 // [
|
||||
typedef signed __int64 intptr_t;
|
||||
typedef unsigned __int64 uintptr_t;
|
||||
#else // _WIN64 ][
|
||||
typedef _W64 signed int intptr_t;
|
||||
typedef _W64 unsigned int uintptr_t;
|
||||
#endif // _WIN64 ]
|
||||
|
||||
// 7.18.1.5 Greatest-width integer types
|
||||
typedef int64_t intmax_t;
|
||||
typedef uint64_t uintmax_t;
|
||||
|
||||
|
||||
// 7.18.2 Limits of specified-width integer types
|
||||
|
||||
#if !defined(__cplusplus) || defined(__STDC_LIMIT_MACROS) // [ See footnote 220 at page 257 and footnote 221 at page 259
|
||||
|
||||
// 7.18.2.1 Limits of exact-width integer types
|
||||
#define INT8_MIN ((int8_t)_I8_MIN)
|
||||
#define INT8_MAX _I8_MAX
|
||||
#define INT16_MIN ((int16_t)_I16_MIN)
|
||||
#define INT16_MAX _I16_MAX
|
||||
#define INT32_MIN ((int32_t)_I32_MIN)
|
||||
#define INT32_MAX _I32_MAX
|
||||
#define INT64_MIN ((int64_t)_I64_MIN)
|
||||
#define INT64_MAX _I64_MAX
|
||||
#define UINT8_MAX _UI8_MAX
|
||||
#define UINT16_MAX _UI16_MAX
|
||||
#define UINT32_MAX _UI32_MAX
|
||||
#define UINT64_MAX _UI64_MAX
|
||||
|
||||
// 7.18.2.2 Limits of minimum-width integer types
|
||||
#define INT_LEAST8_MIN INT8_MIN
|
||||
#define INT_LEAST8_MAX INT8_MAX
|
||||
#define INT_LEAST16_MIN INT16_MIN
|
||||
#define INT_LEAST16_MAX INT16_MAX
|
||||
#define INT_LEAST32_MIN INT32_MIN
|
||||
#define INT_LEAST32_MAX INT32_MAX
|
||||
#define INT_LEAST64_MIN INT64_MIN
|
||||
#define INT_LEAST64_MAX INT64_MAX
|
||||
#define UINT_LEAST8_MAX UINT8_MAX
|
||||
#define UINT_LEAST16_MAX UINT16_MAX
|
||||
#define UINT_LEAST32_MAX UINT32_MAX
|
||||
#define UINT_LEAST64_MAX UINT64_MAX
|
||||
|
||||
// 7.18.2.3 Limits of fastest minimum-width integer types
|
||||
#define INT_FAST8_MIN INT8_MIN
|
||||
#define INT_FAST8_MAX INT8_MAX
|
||||
#define INT_FAST16_MIN INT16_MIN
|
||||
#define INT_FAST16_MAX INT16_MAX
|
||||
#define INT_FAST32_MIN INT32_MIN
|
||||
#define INT_FAST32_MAX INT32_MAX
|
||||
#define INT_FAST64_MIN INT64_MIN
|
||||
#define INT_FAST64_MAX INT64_MAX
|
||||
#define UINT_FAST8_MAX UINT8_MAX
|
||||
#define UINT_FAST16_MAX UINT16_MAX
|
||||
#define UINT_FAST32_MAX UINT32_MAX
|
||||
#define UINT_FAST64_MAX UINT64_MAX
|
||||
|
||||
// 7.18.2.4 Limits of integer types capable of holding object pointers
|
||||
#ifdef _WIN64 // [
|
||||
# define INTPTR_MIN INT64_MIN
|
||||
# define INTPTR_MAX INT64_MAX
|
||||
# define UINTPTR_MAX UINT64_MAX
|
||||
#else // _WIN64 ][
|
||||
# define INTPTR_MIN INT32_MIN
|
||||
# define INTPTR_MAX INT32_MAX
|
||||
# define UINTPTR_MAX UINT32_MAX
|
||||
#endif // _WIN64 ]
|
||||
|
||||
// 7.18.2.5 Limits of greatest-width integer types
|
||||
#define INTMAX_MIN INT64_MIN
|
||||
#define INTMAX_MAX INT64_MAX
|
||||
#define UINTMAX_MAX UINT64_MAX
|
||||
|
||||
// 7.18.3 Limits of other integer types
|
||||
|
||||
#ifdef _WIN64 // [
|
||||
# define PTRDIFF_MIN _I64_MIN
|
||||
# define PTRDIFF_MAX _I64_MAX
|
||||
#else // _WIN64 ][
|
||||
# define PTRDIFF_MIN _I32_MIN
|
||||
# define PTRDIFF_MAX _I32_MAX
|
||||
#endif // _WIN64 ]
|
||||
|
||||
#define SIG_ATOMIC_MIN INT_MIN
|
||||
#define SIG_ATOMIC_MAX INT_MAX
|
||||
|
||||
#ifndef SIZE_MAX // [
|
||||
# ifdef _WIN64 // [
|
||||
# define SIZE_MAX _UI64_MAX
|
||||
# else // _WIN64 ][
|
||||
# define SIZE_MAX _UI32_MAX
|
||||
# endif // _WIN64 ]
|
||||
#endif // SIZE_MAX ]
|
||||
|
||||
// WCHAR_MIN and WCHAR_MAX are also defined in <wchar.h>
|
||||
#ifndef WCHAR_MIN // [
|
||||
# define WCHAR_MIN 0
|
||||
#endif // WCHAR_MIN ]
|
||||
#ifndef WCHAR_MAX // [
|
||||
# define WCHAR_MAX _UI16_MAX
|
||||
#endif // WCHAR_MAX ]
|
||||
|
||||
#define WINT_MIN 0
|
||||
#define WINT_MAX _UI16_MAX
|
||||
|
||||
#endif // __STDC_LIMIT_MACROS ]
|
||||
|
||||
|
||||
// 7.18.4 Limits of other integer types
|
||||
|
||||
#if !defined(__cplusplus) || defined(__STDC_CONSTANT_MACROS) // [ See footnote 224 at page 260
|
||||
|
||||
// 7.18.4.1 Macros for minimum-width integer constants
|
||||
|
||||
#define INT8_C(val) val##i8
|
||||
#define INT16_C(val) val##i16
|
||||
#define INT32_C(val) val##i32
|
||||
#define INT64_C(val) val##i64
|
||||
|
||||
#define UINT8_C(val) val##ui8
|
||||
#define UINT16_C(val) val##ui16
|
||||
#define UINT32_C(val) val##ui32
|
||||
#define UINT64_C(val) val##ui64
|
||||
|
||||
// 7.18.4.2 Macros for greatest-width integer constants
|
||||
#define INTMAX_C INT64_C
|
||||
#define UINTMAX_C UINT64_C
|
||||
|
||||
#endif // __STDC_CONSTANT_MACROS ]
|
||||
|
||||
|
||||
#endif // _MSC_STDINT_H_ ]
|
||||
46
src/ThirdParty/glfw/docs/CMakeLists.txt
vendored
Normal file
46
src/ThirdParty/glfw/docs/CMakeLists.txt
vendored
Normal file
@@ -0,0 +1,46 @@
|
||||
|
||||
# NOTE: The order of this list determines the order of items in the Guides
|
||||
# (i.e. Pages) list in the generated documentation
|
||||
set(source_files
|
||||
main.dox
|
||||
news.dox
|
||||
quick.dox
|
||||
moving.dox
|
||||
compile.dox
|
||||
build.dox
|
||||
intro.dox
|
||||
context.dox
|
||||
monitor.dox
|
||||
window.dox
|
||||
input.dox
|
||||
vulkan.dox
|
||||
compat.dox
|
||||
internal.dox)
|
||||
|
||||
set(extra_files DoxygenLayout.xml header.html footer.html extra.css spaces.svg)
|
||||
|
||||
set(header_paths
|
||||
"${GLFW_SOURCE_DIR}/include/GLFW/glfw3.h"
|
||||
"${GLFW_SOURCE_DIR}/include/GLFW/glfw3native.h")
|
||||
|
||||
# Format the source list into a Doxyfile INPUT value that Doxygen can parse
|
||||
foreach(path IN LISTS header_paths)
|
||||
string(APPEND GLFW_DOXYGEN_INPUT " \\\n\"${path}\"")
|
||||
endforeach()
|
||||
foreach(file IN LISTS source_files)
|
||||
string(APPEND GLFW_DOXYGEN_INPUT " \\\n\"${CMAKE_CURRENT_SOURCE_DIR}/${file}\"")
|
||||
endforeach()
|
||||
|
||||
configure_file(Doxyfile.in Doxyfile @ONLY)
|
||||
|
||||
add_custom_command(OUTPUT "html/index.html"
|
||||
COMMAND "${DOXYGEN_EXECUTABLE}"
|
||||
WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}"
|
||||
MAIN_DEPENDENCY Doxyfile
|
||||
DEPENDS ${header_paths} ${source_files} ${extra_files}
|
||||
COMMENT "Generating HTML documentation"
|
||||
VERBATIM)
|
||||
|
||||
add_custom_target(docs ALL SOURCES "html/index.html")
|
||||
set_target_properties(docs PROPERTIES FOLDER "GLFW3")
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user