Fix errors
This commit is contained in:
86
CLAUDE.md
86
CLAUDE.md
@@ -661,11 +661,87 @@ PPIScope : public Scope (abstract) — shared PPI behavior:
|
||||
- Cursor range/bearing readout under scope (white text)
|
||||
- Bearing offset for boat mode (k/j)
|
||||
- Cursor range clamped to max range
|
||||
- Range rings and labels are beam-painted per sweep sector, NOT a static overlay;
|
||||
the sweep shader evaluates ring radii for the CURRENT max range at the moment
|
||||
each beam angle is rendered; the phosphor buffer retains whatever was last
|
||||
written, so old ring positions fade naturally as the sweep overwrites them with
|
||||
new geometry — no special transition code required
|
||||
- Range rings are beam-painted per sweep sector with P7 persistence and decay;
|
||||
however they are stored in the GAIN-INDEPENDENT G channel of the phosphor FBO
|
||||
(see PHOSPHOR FBO ARCHITECTURE below) so operator gain does not dim the rings
|
||||
- renderRingLabels() — virtual method (default no-op); concrete PPI scopes that
|
||||
have labelled range rings override this to render mile-distance text labels in
|
||||
P7 fresh-blue colour at a fixed bearing (RING_LABEL_BRG_DEG = 045°)
|
||||
|
||||
IMPLEMENTER CHECKLIST — required in every new PPIScope subclass:
|
||||
1. computeRingRadii(): multiply each normalised ring radius by
|
||||
GRAT_INNER_RING_FRAC (same as MarinePPIScope). Omitting this
|
||||
places the outer ring at the scope boundary where it is clipped
|
||||
and hidden behind the graticule. Target positions are scaled
|
||||
automatically by PhosphorRenderer::update(); ring radii are not.
|
||||
2. Override renderRingLabels() using the same pattern as
|
||||
MarinePPIScope::renderRingLabels() but with the scope's own
|
||||
ring-mile table. The base-class no-op produces no labels.
|
||||
The p7Color() fix, two-channel FBO gain-separation, and target
|
||||
position scaling are all automatic via the shared PhosphorRenderer
|
||||
and shaders — no per-scope action required for those.
|
||||
|
||||
==================================================================
|
||||
|
||||
PHOSPHOR FBO ARCHITECTURE
|
||||
|
||||
==================================================================
|
||||
|
||||
The phosphor FBO is GL_RG32F (two independent float channels):
|
||||
|
||||
R channel — signal energy
|
||||
Written by: target echoes in the sweep shader
|
||||
Multiplied by: u_gain in the display shader
|
||||
Effect: operator gain knob dims/brightens received echoes without
|
||||
affecting the sweep beam or range rings
|
||||
|
||||
G channel — timing/geometry energy
|
||||
Written by: range rings + sweep background glow in the sweep shader
|
||||
NOT multiplied by gain in the display shader
|
||||
Effect: rings always appear at a fixed brightness; the rotating
|
||||
sweep-line glow is always visible even at minimum gain
|
||||
|
||||
Both channels decay at the same P7 rate (P7_DECAY_RATE in settings.h).
|
||||
The display shader combines them: totalEnergy = max(R * gain, G).
|
||||
This produces the correct visual priority: a strong target echo always
|
||||
shows above the ring but a dim echo below gain threshold fades away
|
||||
while the ring stays steady.
|
||||
|
||||
RANGE POSITION NORMALISATION
|
||||
|
||||
All ring radii and target range values are normalised so that
|
||||
max-range maps to GRAT_INNER_RING_FRAC (0.915), NOT 1.0.
|
||||
|
||||
Normalised 1.0 is the outer edge of the phosphor circle (scope boundary).
|
||||
The bearing graticule overlay occupies 0.915 to 0.985 of scope radius.
|
||||
If max-range mapped to 1.0, the outer ring would sit at the scope
|
||||
boundary — half-clipped by the sweep shader's rng > 1.0 early-exit and
|
||||
visually hidden behind the graticule outer ring.
|
||||
|
||||
Mapping max-range → GRAT_INNER_RING_FRAC keeps all rings and targets
|
||||
within the clean active display area inside the bearing scale overlay.
|
||||
|
||||
Scale is applied in two places:
|
||||
1. PhosphorRenderer::update() — target range: × GRAT_INNER_RING_FRAC
|
||||
2. computeRingRadii() in each concrete PPI scope — ring radii: × GRAT_INNER_RING_FRAC
|
||||
|
||||
P7 COLOUR FUNCTION
|
||||
|
||||
p7Color() in phosphor.frag is a piecewise linear ramp over [0, 1]:
|
||||
e ≥ T_BLUE (0.82) → pure C_BLUE
|
||||
[T_GREEN, T_BLUE) → mix(C_GREEN, C_BLUE, normalised within range)
|
||||
[T_YGREE, T_GREEN) → mix(C_YGREE, C_GREEN, normalised within range)
|
||||
[T_DARK, T_YGREE) → mix(C_YELLW, C_YGREE, normalised within range)
|
||||
[0, T_DARK) → mix(C_BLACK, C_YELLW, normalised within range)
|
||||
|
||||
Each mix() factor is in [0, 1] and the function is continuous at every
|
||||
threshold boundary. An earlier version had each branch using the formula
|
||||
of the branch below it (off-by-one), which caused SWEEP_BACKGROUND_ENERGY
|
||||
= 0.10 to render as saturated yellow (factor 3.33) instead of dim
|
||||
yellow-green, producing an unwanted solid-yellow band behind the sweep.
|
||||
|
||||
==================================================================
|
||||
|
||||
|
||||
MarinePPIScope : public PPIScope
|
||||
- Sweep time: 4 seconds
|
||||
|
||||
@@ -351,6 +351,8 @@ CMAKE_C_FLAGS_RELWITHDEBINFO-ADVANCED:INTERNAL=1
|
||||
CMAKE_DLLTOOL-ADVANCED:INTERNAL=1
|
||||
//Path to cache edit program executable.
|
||||
CMAKE_EDIT_COMMAND:INTERNAL=/usr/bin/cmake-gui
|
||||
//Whether to issue deprecation errors for macros and functions.
|
||||
CMAKE_ERROR_DEPRECATED:INTERNAL=FALSE
|
||||
//Executable file format
|
||||
CMAKE_EXECUTABLE_FORMAT:INTERNAL=ELF
|
||||
//ADVANCED property for variable: CMAKE_EXE_LINKER_FLAGS
|
||||
@@ -440,12 +442,20 @@ CMAKE_STATIC_LINKER_FLAGS_RELEASE-ADVANCED:INTERNAL=1
|
||||
CMAKE_STATIC_LINKER_FLAGS_RELWITHDEBINFO-ADVANCED:INTERNAL=1
|
||||
//ADVANCED property for variable: CMAKE_STRIP
|
||||
CMAKE_STRIP-ADVANCED:INTERNAL=1
|
||||
//Suppress errors that are meant for the author of the CMakeLists.txt
|
||||
// files.
|
||||
CMAKE_SUPPRESS_DEVELOPER_ERRORS:INTERNAL=TRUE
|
||||
//Suppress Warnings that are meant for the author of the CMakeLists.txt
|
||||
// files.
|
||||
CMAKE_SUPPRESS_DEVELOPER_WARNINGS:INTERNAL=TRUE
|
||||
//ADVANCED property for variable: CMAKE_TAPI
|
||||
CMAKE_TAPI-ADVANCED:INTERNAL=1
|
||||
//uname command
|
||||
CMAKE_UNAME:INTERNAL=/usr/bin/uname
|
||||
//ADVANCED property for variable: CMAKE_VERBOSE_MAKEFILE
|
||||
CMAKE_VERBOSE_MAKEFILE-ADVANCED:INTERNAL=1
|
||||
//Whether to issue warnings for deprecated functionality.
|
||||
CMAKE_WARN_DEPRECATED:INTERNAL=FALSE
|
||||
//Details about finding Freetype
|
||||
FIND_PACKAGE_MESSAGE_DETAILS_Freetype:INTERNAL=[/usr/lib/x86_64-linux-gnu/libfreetype.so][/usr/include/freetype2][v2.14.2()]
|
||||
//Details about finding OpenGL
|
||||
|
||||
@@ -11,98 +11,21 @@ set(CMAKE_MAKEFILE_DEPENDS
|
||||
"CMakeFiles/4.2.3/CMakeCCompiler.cmake"
|
||||
"CMakeFiles/4.2.3/CMakeCXXCompiler.cmake"
|
||||
"CMakeFiles/4.2.3/CMakeSystem.cmake"
|
||||
"/usr/share/cmake-4.2/Modules/CMakeCCompiler.cmake.in"
|
||||
"/usr/share/cmake-4.2/Modules/CMakeCCompilerABI.c"
|
||||
"/usr/share/cmake-4.2/Modules/CMakeCInformation.cmake"
|
||||
"/usr/share/cmake-4.2/Modules/CMakeCXXCompiler.cmake.in"
|
||||
"/usr/share/cmake-4.2/Modules/CMakeCXXCompilerABI.cpp"
|
||||
"/usr/share/cmake-4.2/Modules/CMakeCXXInformation.cmake"
|
||||
"/usr/share/cmake-4.2/Modules/CMakeCommonLanguageInclude.cmake"
|
||||
"/usr/share/cmake-4.2/Modules/CMakeCompilerIdDetection.cmake"
|
||||
"/usr/share/cmake-4.2/Modules/CMakeDetermineCCompiler.cmake"
|
||||
"/usr/share/cmake-4.2/Modules/CMakeDetermineCXXCompiler.cmake"
|
||||
"/usr/share/cmake-4.2/Modules/CMakeDetermineCompiler.cmake"
|
||||
"/usr/share/cmake-4.2/Modules/CMakeDetermineCompilerABI.cmake"
|
||||
"/usr/share/cmake-4.2/Modules/CMakeDetermineCompilerId.cmake"
|
||||
"/usr/share/cmake-4.2/Modules/CMakeDetermineCompilerSupport.cmake"
|
||||
"/usr/share/cmake-4.2/Modules/CMakeDetermineSystem.cmake"
|
||||
"/usr/share/cmake-4.2/Modules/CMakeFindBinUtils.cmake"
|
||||
"/usr/share/cmake-4.2/Modules/CMakeGenericSystem.cmake"
|
||||
"/usr/share/cmake-4.2/Modules/CMakeInitializeConfigs.cmake"
|
||||
"/usr/share/cmake-4.2/Modules/CMakeLanguageInformation.cmake"
|
||||
"/usr/share/cmake-4.2/Modules/CMakeParseImplicitIncludeInfo.cmake"
|
||||
"/usr/share/cmake-4.2/Modules/CMakeParseImplicitLinkInfo.cmake"
|
||||
"/usr/share/cmake-4.2/Modules/CMakeParseLibraryArchitecture.cmake"
|
||||
"/usr/share/cmake-4.2/Modules/CMakeSystem.cmake.in"
|
||||
"/usr/share/cmake-4.2/Modules/CMakeSystemSpecificInformation.cmake"
|
||||
"/usr/share/cmake-4.2/Modules/CMakeSystemSpecificInitialize.cmake"
|
||||
"/usr/share/cmake-4.2/Modules/CMakeTestCCompiler.cmake"
|
||||
"/usr/share/cmake-4.2/Modules/CMakeTestCXXCompiler.cmake"
|
||||
"/usr/share/cmake-4.2/Modules/CMakeTestCompilerCommon.cmake"
|
||||
"/usr/share/cmake-4.2/Modules/CMakeUnixFindMake.cmake"
|
||||
"/usr/share/cmake-4.2/Modules/CheckCSourceCompiles.cmake"
|
||||
"/usr/share/cmake-4.2/Modules/CheckIncludeFile.cmake"
|
||||
"/usr/share/cmake-4.2/Modules/CheckLibraryExists.cmake"
|
||||
"/usr/share/cmake-4.2/Modules/Compiler/ADSP-DetermineCompiler.cmake"
|
||||
"/usr/share/cmake-4.2/Modules/Compiler/ARMCC-DetermineCompiler.cmake"
|
||||
"/usr/share/cmake-4.2/Modules/Compiler/ARMClang-DetermineCompiler.cmake"
|
||||
"/usr/share/cmake-4.2/Modules/Compiler/AppleClang-DetermineCompiler.cmake"
|
||||
"/usr/share/cmake-4.2/Modules/Compiler/Borland-DetermineCompiler.cmake"
|
||||
"/usr/share/cmake-4.2/Modules/Compiler/Bruce-C-DetermineCompiler.cmake"
|
||||
"/usr/share/cmake-4.2/Modules/Compiler/CMakeCommonCompilerMacros.cmake"
|
||||
"/usr/share/cmake-4.2/Modules/Compiler/Clang-DetermineCompiler.cmake"
|
||||
"/usr/share/cmake-4.2/Modules/Compiler/Clang-DetermineCompilerInternal.cmake"
|
||||
"/usr/share/cmake-4.2/Modules/Compiler/Compaq-C-DetermineCompiler.cmake"
|
||||
"/usr/share/cmake-4.2/Modules/Compiler/Compaq-CXX-DetermineCompiler.cmake"
|
||||
"/usr/share/cmake-4.2/Modules/Compiler/Cray-DetermineCompiler.cmake"
|
||||
"/usr/share/cmake-4.2/Modules/Compiler/CrayClang-DetermineCompiler.cmake"
|
||||
"/usr/share/cmake-4.2/Modules/Compiler/Diab-DetermineCompiler.cmake"
|
||||
"/usr/share/cmake-4.2/Modules/Compiler/Embarcadero-DetermineCompiler.cmake"
|
||||
"/usr/share/cmake-4.2/Modules/Compiler/Fujitsu-DetermineCompiler.cmake"
|
||||
"/usr/share/cmake-4.2/Modules/Compiler/FujitsuClang-DetermineCompiler.cmake"
|
||||
"/usr/share/cmake-4.2/Modules/Compiler/GHS-DetermineCompiler.cmake"
|
||||
"/usr/share/cmake-4.2/Modules/Compiler/GNU-C-DetermineCompiler.cmake"
|
||||
"/usr/share/cmake-4.2/Modules/Compiler/GNU-C.cmake"
|
||||
"/usr/share/cmake-4.2/Modules/Compiler/GNU-CXX-DetermineCompiler.cmake"
|
||||
"/usr/share/cmake-4.2/Modules/Compiler/GNU-CXX.cmake"
|
||||
"/usr/share/cmake-4.2/Modules/Compiler/GNU-FindBinUtils.cmake"
|
||||
"/usr/share/cmake-4.2/Modules/Compiler/GNU.cmake"
|
||||
"/usr/share/cmake-4.2/Modules/Compiler/HP-C-DetermineCompiler.cmake"
|
||||
"/usr/share/cmake-4.2/Modules/Compiler/HP-CXX-DetermineCompiler.cmake"
|
||||
"/usr/share/cmake-4.2/Modules/Compiler/IAR-DetermineCompiler.cmake"
|
||||
"/usr/share/cmake-4.2/Modules/Compiler/IBMCPP-C-DetermineVersionInternal.cmake"
|
||||
"/usr/share/cmake-4.2/Modules/Compiler/IBMCPP-CXX-DetermineVersionInternal.cmake"
|
||||
"/usr/share/cmake-4.2/Modules/Compiler/IBMClang-C-DetermineCompiler.cmake"
|
||||
"/usr/share/cmake-4.2/Modules/Compiler/IBMClang-CXX-DetermineCompiler.cmake"
|
||||
"/usr/share/cmake-4.2/Modules/Compiler/Intel-DetermineCompiler.cmake"
|
||||
"/usr/share/cmake-4.2/Modules/Compiler/IntelLLVM-DetermineCompiler.cmake"
|
||||
"/usr/share/cmake-4.2/Modules/Compiler/LCC-C-DetermineCompiler.cmake"
|
||||
"/usr/share/cmake-4.2/Modules/Compiler/LCC-CXX-DetermineCompiler.cmake"
|
||||
"/usr/share/cmake-4.2/Modules/Compiler/MSVC-DetermineCompiler.cmake"
|
||||
"/usr/share/cmake-4.2/Modules/Compiler/NVHPC-DetermineCompiler.cmake"
|
||||
"/usr/share/cmake-4.2/Modules/Compiler/NVIDIA-DetermineCompiler.cmake"
|
||||
"/usr/share/cmake-4.2/Modules/Compiler/OpenWatcom-DetermineCompiler.cmake"
|
||||
"/usr/share/cmake-4.2/Modules/Compiler/OrangeC-DetermineCompiler.cmake"
|
||||
"/usr/share/cmake-4.2/Modules/Compiler/PGI-DetermineCompiler.cmake"
|
||||
"/usr/share/cmake-4.2/Modules/Compiler/PathScale-DetermineCompiler.cmake"
|
||||
"/usr/share/cmake-4.2/Modules/Compiler/Renesas-DetermineCompiler.cmake"
|
||||
"/usr/share/cmake-4.2/Modules/Compiler/SCO-DetermineCompiler.cmake"
|
||||
"/usr/share/cmake-4.2/Modules/Compiler/SDCC-C-DetermineCompiler.cmake"
|
||||
"/usr/share/cmake-4.2/Modules/Compiler/SunPro-C-DetermineCompiler.cmake"
|
||||
"/usr/share/cmake-4.2/Modules/Compiler/SunPro-CXX-DetermineCompiler.cmake"
|
||||
"/usr/share/cmake-4.2/Modules/Compiler/TI-DetermineCompiler.cmake"
|
||||
"/usr/share/cmake-4.2/Modules/Compiler/TIClang-DetermineCompiler.cmake"
|
||||
"/usr/share/cmake-4.2/Modules/Compiler/Tasking-DetermineCompiler.cmake"
|
||||
"/usr/share/cmake-4.2/Modules/Compiler/TinyCC-C-DetermineCompiler.cmake"
|
||||
"/usr/share/cmake-4.2/Modules/Compiler/VisualAge-C-DetermineCompiler.cmake"
|
||||
"/usr/share/cmake-4.2/Modules/Compiler/VisualAge-CXX-DetermineCompiler.cmake"
|
||||
"/usr/share/cmake-4.2/Modules/Compiler/Watcom-DetermineCompiler.cmake"
|
||||
"/usr/share/cmake-4.2/Modules/Compiler/XL-C-DetermineCompiler.cmake"
|
||||
"/usr/share/cmake-4.2/Modules/Compiler/XL-CXX-DetermineCompiler.cmake"
|
||||
"/usr/share/cmake-4.2/Modules/Compiler/XLClang-C-DetermineCompiler.cmake"
|
||||
"/usr/share/cmake-4.2/Modules/Compiler/XLClang-CXX-DetermineCompiler.cmake"
|
||||
"/usr/share/cmake-4.2/Modules/Compiler/zOS-C-DetermineCompiler.cmake"
|
||||
"/usr/share/cmake-4.2/Modules/Compiler/zOS-CXX-DetermineCompiler.cmake"
|
||||
"/usr/share/cmake-4.2/Modules/FindFreetype.cmake"
|
||||
"/usr/share/cmake-4.2/Modules/FindOpenGL.cmake"
|
||||
"/usr/share/cmake-4.2/Modules/FindPackageHandleStandardArgs.cmake"
|
||||
@@ -112,11 +35,7 @@ set(CMAKE_MAKEFILE_DEPENDS
|
||||
"/usr/share/cmake-4.2/Modules/Internal/CMakeCLinkerInformation.cmake"
|
||||
"/usr/share/cmake-4.2/Modules/Internal/CMakeCXXLinkerInformation.cmake"
|
||||
"/usr/share/cmake-4.2/Modules/Internal/CMakeCommonLinkerInformation.cmake"
|
||||
"/usr/share/cmake-4.2/Modules/Internal/CMakeDetermineLinkerId.cmake"
|
||||
"/usr/share/cmake-4.2/Modules/Internal/CMakeInspectCLinker.cmake"
|
||||
"/usr/share/cmake-4.2/Modules/Internal/CMakeInspectCXXLinker.cmake"
|
||||
"/usr/share/cmake-4.2/Modules/Internal/CheckSourceCompiles.cmake"
|
||||
"/usr/share/cmake-4.2/Modules/Internal/FeatureTesting.cmake"
|
||||
"/usr/share/cmake-4.2/Modules/Linker/GNU-C.cmake"
|
||||
"/usr/share/cmake-4.2/Modules/Linker/GNU-CXX.cmake"
|
||||
"/usr/share/cmake-4.2/Modules/Linker/GNU.cmake"
|
||||
@@ -124,7 +43,6 @@ set(CMAKE_MAKEFILE_DEPENDS
|
||||
"/usr/share/cmake-4.2/Modules/Platform/Linker/Linux-GNU-C.cmake"
|
||||
"/usr/share/cmake-4.2/Modules/Platform/Linker/Linux-GNU-CXX.cmake"
|
||||
"/usr/share/cmake-4.2/Modules/Platform/Linker/Linux-GNU.cmake"
|
||||
"/usr/share/cmake-4.2/Modules/Platform/Linux-Determine-CXX.cmake"
|
||||
"/usr/share/cmake-4.2/Modules/Platform/Linux-GNU-C.cmake"
|
||||
"/usr/share/cmake-4.2/Modules/Platform/Linux-GNU-CXX.cmake"
|
||||
"/usr/share/cmake-4.2/Modules/Platform/Linux-GNU.cmake"
|
||||
@@ -142,13 +60,6 @@ set(CMAKE_MAKEFILE_OUTPUTS
|
||||
|
||||
# Byproducts of CMake generate step:
|
||||
set(CMAKE_MAKEFILE_PRODUCTS
|
||||
"CMakeFiles/4.2.3/CMakeSystem.cmake"
|
||||
"CMakeFiles/4.2.3/CMakeCCompiler.cmake"
|
||||
"CMakeFiles/4.2.3/CMakeCXXCompiler.cmake"
|
||||
"CMakeFiles/4.2.3/CMakeCCompiler.cmake"
|
||||
"CMakeFiles/4.2.3/CMakeCCompiler.cmake"
|
||||
"CMakeFiles/4.2.3/CMakeCXXCompiler.cmake"
|
||||
"CMakeFiles/4.2.3/CMakeCXXCompiler.cmake"
|
||||
"CMakeFiles/CMakeDirectoryInformation.cmake"
|
||||
)
|
||||
|
||||
|
||||
@@ -2432,6 +2432,7 @@ CMakeFiles/radar.dir/src/scope_marine_ppi.cpp.o
|
||||
/usr/include/c++/15/bits/ranges_util.h
|
||||
/usr/include/c++/15/bits/refwrap.h
|
||||
/usr/include/c++/15/bits/requires_hosted.h
|
||||
/usr/include/c++/15/bits/specfun.h
|
||||
/usr/include/c++/15/bits/std_abs.h
|
||||
/usr/include/c++/15/bits/std_mutex.h
|
||||
/usr/include/c++/15/bits/stl_algobase.h
|
||||
@@ -2457,13 +2458,13 @@ CMakeFiles/radar.dir/src/scope_marine_ppi.cpp.o
|
||||
/usr/include/c++/15/cerrno
|
||||
/usr/include/c++/15/climits
|
||||
/usr/include/c++/15/clocale
|
||||
/usr/include/c++/15/cmath
|
||||
/usr/include/c++/15/compare
|
||||
/usr/include/c++/15/concepts
|
||||
/usr/include/c++/15/cstddef
|
||||
/usr/include/c++/15/cstdint
|
||||
/usr/include/c++/15/cstdio
|
||||
/usr/include/c++/15/cstdlib
|
||||
/usr/include/c++/15/cstring
|
||||
/usr/include/c++/15/ctime
|
||||
/usr/include/c++/15/cwchar
|
||||
/usr/include/c++/15/debug/assertions.h
|
||||
@@ -2484,6 +2485,18 @@ CMakeFiles/radar.dir/src/scope_marine_ppi.cpp.o
|
||||
/usr/include/c++/15/ratio
|
||||
/usr/include/c++/15/string
|
||||
/usr/include/c++/15/string_view
|
||||
/usr/include/c++/15/tr1/bessel_function.tcc
|
||||
/usr/include/c++/15/tr1/beta_function.tcc
|
||||
/usr/include/c++/15/tr1/ell_integral.tcc
|
||||
/usr/include/c++/15/tr1/exp_integral.tcc
|
||||
/usr/include/c++/15/tr1/gamma.tcc
|
||||
/usr/include/c++/15/tr1/hypergeometric.tcc
|
||||
/usr/include/c++/15/tr1/legendre_function.tcc
|
||||
/usr/include/c++/15/tr1/modified_bessel_func.tcc
|
||||
/usr/include/c++/15/tr1/poly_hermite.tcc
|
||||
/usr/include/c++/15/tr1/poly_laguerre.tcc
|
||||
/usr/include/c++/15/tr1/riemann_zeta.tcc
|
||||
/usr/include/c++/15/tr1/special_function_util.h
|
||||
/usr/include/c++/15/tuple
|
||||
/usr/include/c++/15/type_traits
|
||||
/usr/include/c++/15/unordered_map
|
||||
@@ -2502,14 +2515,13 @@ CMakeFiles/radar.dir/src/scope_marine_ppi.cpp.o
|
||||
/usr/include/linux/stddef.h
|
||||
/usr/include/linux/types.h
|
||||
/usr/include/locale.h
|
||||
/usr/include/math.h
|
||||
/usr/include/pthread.h
|
||||
/usr/include/sched.h
|
||||
/usr/include/stdc-predef.h
|
||||
/usr/include/stdint.h
|
||||
/usr/include/stdio.h
|
||||
/usr/include/stdlib.h
|
||||
/usr/include/string.h
|
||||
/usr/include/strings.h
|
||||
/usr/include/syscall.h
|
||||
/usr/include/time.h
|
||||
/usr/include/unistd.h
|
||||
@@ -2531,12 +2543,22 @@ CMakeFiles/radar.dir/src/scope_marine_ppi.cpp.o
|
||||
/usr/include/x86_64-linux-gnu/bits/errno.h
|
||||
/usr/include/x86_64-linux-gnu/bits/floatn-common.h
|
||||
/usr/include/x86_64-linux-gnu/bits/floatn.h
|
||||
/usr/include/x86_64-linux-gnu/bits/flt-eval-method.h
|
||||
/usr/include/x86_64-linux-gnu/bits/fp-fast.h
|
||||
/usr/include/x86_64-linux-gnu/bits/fp-logb.h
|
||||
/usr/include/x86_64-linux-gnu/bits/getopt_core.h
|
||||
/usr/include/x86_64-linux-gnu/bits/getopt_posix.h
|
||||
/usr/include/x86_64-linux-gnu/bits/iscanonical.h
|
||||
/usr/include/x86_64-linux-gnu/bits/libc-header-start.h
|
||||
/usr/include/x86_64-linux-gnu/bits/libm-simd-decl-stubs.h
|
||||
/usr/include/x86_64-linux-gnu/bits/local_lim.h
|
||||
/usr/include/x86_64-linux-gnu/bits/locale.h
|
||||
/usr/include/x86_64-linux-gnu/bits/long-double.h
|
||||
/usr/include/x86_64-linux-gnu/bits/math-vector.h
|
||||
/usr/include/x86_64-linux-gnu/bits/mathcalls-helper-functions.h
|
||||
/usr/include/x86_64-linux-gnu/bits/mathcalls-macros.h
|
||||
/usr/include/x86_64-linux-gnu/bits/mathcalls-narrow.h
|
||||
/usr/include/x86_64-linux-gnu/bits/mathcalls.h
|
||||
/usr/include/x86_64-linux-gnu/bits/posix1_lim.h
|
||||
/usr/include/x86_64-linux-gnu/bits/posix2_lim.h
|
||||
/usr/include/x86_64-linux-gnu/bits/posix_opt.h
|
||||
|
||||
@@ -2421,6 +2421,7 @@ CMakeFiles/radar.dir/src/scope_marine_ppi.cpp.o: /home/maallyn/new-radar/src/sco
|
||||
/usr/include/c++/15/bits/ranges_util.h \
|
||||
/usr/include/c++/15/bits/refwrap.h \
|
||||
/usr/include/c++/15/bits/requires_hosted.h \
|
||||
/usr/include/c++/15/bits/specfun.h \
|
||||
/usr/include/c++/15/bits/std_abs.h \
|
||||
/usr/include/c++/15/bits/std_mutex.h \
|
||||
/usr/include/c++/15/bits/stl_algobase.h \
|
||||
@@ -2446,13 +2447,13 @@ CMakeFiles/radar.dir/src/scope_marine_ppi.cpp.o: /home/maallyn/new-radar/src/sco
|
||||
/usr/include/c++/15/cerrno \
|
||||
/usr/include/c++/15/climits \
|
||||
/usr/include/c++/15/clocale \
|
||||
/usr/include/c++/15/cmath \
|
||||
/usr/include/c++/15/compare \
|
||||
/usr/include/c++/15/concepts \
|
||||
/usr/include/c++/15/cstddef \
|
||||
/usr/include/c++/15/cstdint \
|
||||
/usr/include/c++/15/cstdio \
|
||||
/usr/include/c++/15/cstdlib \
|
||||
/usr/include/c++/15/cstring \
|
||||
/usr/include/c++/15/ctime \
|
||||
/usr/include/c++/15/cwchar \
|
||||
/usr/include/c++/15/debug/assertions.h \
|
||||
@@ -2473,6 +2474,18 @@ CMakeFiles/radar.dir/src/scope_marine_ppi.cpp.o: /home/maallyn/new-radar/src/sco
|
||||
/usr/include/c++/15/ratio \
|
||||
/usr/include/c++/15/string \
|
||||
/usr/include/c++/15/string_view \
|
||||
/usr/include/c++/15/tr1/bessel_function.tcc \
|
||||
/usr/include/c++/15/tr1/beta_function.tcc \
|
||||
/usr/include/c++/15/tr1/ell_integral.tcc \
|
||||
/usr/include/c++/15/tr1/exp_integral.tcc \
|
||||
/usr/include/c++/15/tr1/gamma.tcc \
|
||||
/usr/include/c++/15/tr1/hypergeometric.tcc \
|
||||
/usr/include/c++/15/tr1/legendre_function.tcc \
|
||||
/usr/include/c++/15/tr1/modified_bessel_func.tcc \
|
||||
/usr/include/c++/15/tr1/poly_hermite.tcc \
|
||||
/usr/include/c++/15/tr1/poly_laguerre.tcc \
|
||||
/usr/include/c++/15/tr1/riemann_zeta.tcc \
|
||||
/usr/include/c++/15/tr1/special_function_util.h \
|
||||
/usr/include/c++/15/tuple \
|
||||
/usr/include/c++/15/type_traits \
|
||||
/usr/include/c++/15/unordered_map \
|
||||
@@ -2491,14 +2504,13 @@ CMakeFiles/radar.dir/src/scope_marine_ppi.cpp.o: /home/maallyn/new-radar/src/sco
|
||||
/usr/include/linux/stddef.h \
|
||||
/usr/include/linux/types.h \
|
||||
/usr/include/locale.h \
|
||||
/usr/include/math.h \
|
||||
/usr/include/pthread.h \
|
||||
/usr/include/sched.h \
|
||||
/usr/include/stdc-predef.h \
|
||||
/usr/include/stdint.h \
|
||||
/usr/include/stdio.h \
|
||||
/usr/include/stdlib.h \
|
||||
/usr/include/string.h \
|
||||
/usr/include/strings.h \
|
||||
/usr/include/syscall.h \
|
||||
/usr/include/time.h \
|
||||
/usr/include/unistd.h \
|
||||
@@ -2520,12 +2532,22 @@ CMakeFiles/radar.dir/src/scope_marine_ppi.cpp.o: /home/maallyn/new-radar/src/sco
|
||||
/usr/include/x86_64-linux-gnu/bits/errno.h \
|
||||
/usr/include/x86_64-linux-gnu/bits/floatn-common.h \
|
||||
/usr/include/x86_64-linux-gnu/bits/floatn.h \
|
||||
/usr/include/x86_64-linux-gnu/bits/flt-eval-method.h \
|
||||
/usr/include/x86_64-linux-gnu/bits/fp-fast.h \
|
||||
/usr/include/x86_64-linux-gnu/bits/fp-logb.h \
|
||||
/usr/include/x86_64-linux-gnu/bits/getopt_core.h \
|
||||
/usr/include/x86_64-linux-gnu/bits/getopt_posix.h \
|
||||
/usr/include/x86_64-linux-gnu/bits/iscanonical.h \
|
||||
/usr/include/x86_64-linux-gnu/bits/libc-header-start.h \
|
||||
/usr/include/x86_64-linux-gnu/bits/libm-simd-decl-stubs.h \
|
||||
/usr/include/x86_64-linux-gnu/bits/local_lim.h \
|
||||
/usr/include/x86_64-linux-gnu/bits/locale.h \
|
||||
/usr/include/x86_64-linux-gnu/bits/long-double.h \
|
||||
/usr/include/x86_64-linux-gnu/bits/math-vector.h \
|
||||
/usr/include/x86_64-linux-gnu/bits/mathcalls-helper-functions.h \
|
||||
/usr/include/x86_64-linux-gnu/bits/mathcalls-macros.h \
|
||||
/usr/include/x86_64-linux-gnu/bits/mathcalls-narrow.h \
|
||||
/usr/include/x86_64-linux-gnu/bits/mathcalls.h \
|
||||
/usr/include/x86_64-linux-gnu/bits/posix1_lim.h \
|
||||
/usr/include/x86_64-linux-gnu/bits/posix2_lim.h \
|
||||
/usr/include/x86_64-linux-gnu/bits/posix_opt.h \
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -199,4 +199,26 @@ CMakeFiles/radar.dir/src/scope_marine_ppi.cpp.o: \
|
||||
/home/maallyn/new-radar/include/KHR/khrplatform.h \
|
||||
/home/maallyn/new-radar/src/phosphor.h \
|
||||
/home/maallyn/new-radar/src/graticule.h /usr/include/GLFW/glfw3.h \
|
||||
/usr/include/c++/15/cstring /usr/include/string.h /usr/include/strings.h
|
||||
/usr/include/c++/15/cmath /usr/include/math.h \
|
||||
/usr/include/x86_64-linux-gnu/bits/math-vector.h \
|
||||
/usr/include/x86_64-linux-gnu/bits/libm-simd-decl-stubs.h \
|
||||
/usr/include/x86_64-linux-gnu/bits/flt-eval-method.h \
|
||||
/usr/include/x86_64-linux-gnu/bits/fp-logb.h \
|
||||
/usr/include/x86_64-linux-gnu/bits/fp-fast.h \
|
||||
/usr/include/x86_64-linux-gnu/bits/mathcalls-macros.h \
|
||||
/usr/include/x86_64-linux-gnu/bits/mathcalls-helper-functions.h \
|
||||
/usr/include/x86_64-linux-gnu/bits/mathcalls.h \
|
||||
/usr/include/x86_64-linux-gnu/bits/mathcalls-narrow.h \
|
||||
/usr/include/x86_64-linux-gnu/bits/iscanonical.h \
|
||||
/usr/include/c++/15/bits/specfun.h /usr/include/c++/15/tr1/gamma.tcc \
|
||||
/usr/include/c++/15/tr1/special_function_util.h \
|
||||
/usr/include/c++/15/tr1/bessel_function.tcc \
|
||||
/usr/include/c++/15/tr1/beta_function.tcc \
|
||||
/usr/include/c++/15/tr1/ell_integral.tcc \
|
||||
/usr/include/c++/15/tr1/exp_integral.tcc \
|
||||
/usr/include/c++/15/tr1/hypergeometric.tcc \
|
||||
/usr/include/c++/15/tr1/legendre_function.tcc \
|
||||
/usr/include/c++/15/tr1/modified_bessel_func.tcc \
|
||||
/usr/include/c++/15/tr1/poly_hermite.tcc \
|
||||
/usr/include/c++/15/tr1/poly_laguerre.tcc \
|
||||
/usr/include/c++/15/tr1/riemann_zeta.tcc
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
build/radar
BIN
build/radar
Binary file not shown.
@@ -2,9 +2,15 @@
|
||||
* MIT License
|
||||
* Author: Mark Allyn
|
||||
*
|
||||
* phosphor.frag — maps the single-channel phosphor energy texture to
|
||||
* the P7 colour sequence (blue → green → yellow-green → dark) and
|
||||
* applies a simple inline bloom (box-filter glow) to bright pixels.
|
||||
* phosphor.frag — maps the two-channel phosphor energy texture to the
|
||||
* P7 colour sequence (blue → green → yellow-green → dark) and applies
|
||||
* a simple inline bloom (box-filter glow) to bright pixels.
|
||||
*
|
||||
* The phosphor FBO is GL_RG32F:
|
||||
* R channel — signal energy (target echoes, sweep background)
|
||||
* multiplied by u_gain before display
|
||||
* G channel — range ring energy, gain-independent; mixed with signal
|
||||
* after gain is applied so rings never dim with gain
|
||||
*
|
||||
* Coordinate system: gl_FragCoord.xy in GL viewport pixels (origin
|
||||
* bottom-left). Scope centre is passed as u_scopeCenter in the same
|
||||
@@ -14,17 +20,19 @@
|
||||
|
||||
out vec4 fragColor;
|
||||
|
||||
uniform sampler2D u_phosphor; // GL_R32F phosphor energy FBO
|
||||
uniform sampler2D u_phosphor; // GL_RG32F phosphor energy FBO
|
||||
uniform vec2 u_scopeCenter; // scope centre in GL viewport pixels (bottom-left origin)
|
||||
uniform float u_scopeRadius; // scope radius in pixels
|
||||
uniform float u_gain; // receiver gain [0,1] — scales brightness
|
||||
uniform float u_gain; // receiver gain [0,1] — scales signal (R) channel only
|
||||
uniform float u_bloomStep; // UV step for bloom sample (≈ 2.5 / FBO_SIZE)
|
||||
uniform float u_bloomStrength; // additive blend weight for bloom
|
||||
|
||||
// P7 energy thresholds (match settings.h)
|
||||
// P7 energy thresholds — MUST match settings.h P7_THRESH_* constants.
|
||||
// T_YGREE is intentionally low (0.05) to keep most of the decay in the
|
||||
// GREEN zone; see the comment in settings.h for the full rationale.
|
||||
const float T_BLUE = 0.82;
|
||||
const float T_GREEN = 0.55;
|
||||
const float T_YGREE = 0.22;
|
||||
const float T_YGREE = 0.05;
|
||||
const float T_DARK = 0.03;
|
||||
|
||||
// P7 colour anchors
|
||||
@@ -34,16 +42,22 @@ const vec3 C_YGREE = vec3(0.50, 1.00, 0.05);
|
||||
const vec3 C_YELLW = vec3(0.70, 0.70, 0.00);
|
||||
const vec3 C_BLACK = vec3(0.00, 0.00, 0.00);
|
||||
|
||||
// P7 colour ramp: hue selected by energy level, then scaled by energy so
|
||||
// brightness decreases monotonically from fresh strike (peak) to dark.
|
||||
// This prevents intermediate decay colours (yellow-green) from appearing
|
||||
// brighter than the initial blue flash.
|
||||
vec3 p7Color(float e) {
|
||||
if (e < T_DARK) return C_BLACK;
|
||||
vec3 hue;
|
||||
if (e >= T_BLUE)
|
||||
return mix(C_GREEN, C_BLUE, (e - T_GREEN) / (T_BLUE - T_GREEN));
|
||||
if (e >= T_GREEN)
|
||||
return mix(C_YGREE, C_GREEN, (e - T_YGREE) / (T_GREEN - T_YGREE));
|
||||
if (e >= T_YGREE)
|
||||
return mix(C_YELLW, C_YGREE, (e - T_DARK ) / (T_YGREE - T_DARK ));
|
||||
if (e >= T_DARK)
|
||||
return mix(C_BLACK, C_YELLW, e / T_DARK);
|
||||
return C_BLACK;
|
||||
hue = C_BLUE;
|
||||
else if (e >= T_GREEN)
|
||||
hue = mix(C_GREEN, C_BLUE, (e - T_GREEN) / (T_BLUE - T_GREEN));
|
||||
else if (e >= T_YGREE)
|
||||
hue = mix(C_YGREE, C_GREEN, (e - T_YGREE) / (T_GREEN - T_YGREE));
|
||||
else
|
||||
hue = mix(C_YELLW, C_YGREE, (e - T_DARK) / (T_YGREE - T_DARK));
|
||||
return hue * e;
|
||||
}
|
||||
|
||||
void main() {
|
||||
@@ -57,10 +71,12 @@ void main() {
|
||||
}
|
||||
|
||||
// Map from PPI delta [-1,+1] to phosphor texture UV [0,1]
|
||||
// delta.x = east, delta.y = north (both y directions already match)
|
||||
vec2 uv = delta * 0.5 + 0.5;
|
||||
|
||||
float energy = texture(u_phosphor, uv).r * u_gain;
|
||||
vec2 rg = texture(u_phosphor, uv).rg;
|
||||
// Signal (R): gain-scaled received echoes.
|
||||
// Ring (G): gain-independent timing reference; always at full brightness.
|
||||
float energy = max(rg.r * u_gain, rg.g);
|
||||
|
||||
// Inline bloom: weighted box-filter over a 5×5 neighbourhood
|
||||
float bloom = 0.0;
|
||||
@@ -68,7 +84,8 @@ void main() {
|
||||
for (int dx = -2; dx <= 2; dx++) {
|
||||
for (int dy = -2; dy <= 2; dy++) {
|
||||
float w = exp(-float(dx*dx + dy*dy) * 0.45);
|
||||
float e = texture(u_phosphor, uv + vec2(dx, dy) * u_bloomStep).r;
|
||||
vec2 srg = texture(u_phosphor, uv + vec2(dx, dy) * u_bloomStep).rg;
|
||||
float e = max(srg.r * u_gain, srg.g);
|
||||
bloom += e * w;
|
||||
wsum += w;
|
||||
}
|
||||
|
||||
@@ -4,13 +4,16 @@
|
||||
*
|
||||
* sweep.frag — phosphor accumulation update shader.
|
||||
*
|
||||
* For each texel in the 1024×1024 phosphor FBO:
|
||||
* 1. Decay the previous frame's energy by u_decayFactor.
|
||||
* 2. If the texel's PPI bearing falls within the current sweep arc
|
||||
* [u_beamAnglePrev, u_beamAngle], add contributions from:
|
||||
* - range rings (beam-painted per the P7 spec)
|
||||
* - target echoes
|
||||
* 3. Output the updated single-channel energy value.
|
||||
* The FBO is GL_RG32F (two independent energy channels):
|
||||
* R — signal energy: target echoes + sweep-background glow.
|
||||
* Multiplied by u_gain in the display pass so operators can
|
||||
* adjust received-signal brightness without touching rings.
|
||||
* G — range-ring energy: written at u_ringBrightness; NOT scaled
|
||||
* by gain. Rings are a precision timing reference, not a
|
||||
* received echo. Both channels decay at the same P7 rate.
|
||||
*
|
||||
* The sweep background (u_sweepBg) goes into the G channel so the
|
||||
* rotating beam is always visible regardless of the gain setting.
|
||||
*
|
||||
* PPI convention: north = +y, east = +x; bearing = atan2(x, y)
|
||||
* in degrees, clockwise from north.
|
||||
@@ -19,13 +22,13 @@
|
||||
|
||||
in vec2 vTexCoord;
|
||||
|
||||
layout(location = 0) out vec4 fragOut; // .r = energy; .gba unused
|
||||
layout(location = 0) out vec4 fragOut; // .r = signal; .g = ring+sweep; .ba unused
|
||||
|
||||
uniform sampler2D u_prevPhosphor; // previous frame's energy texture (GL_R32F)
|
||||
uniform sampler2D u_prevPhosphor; // previous frame's energy texture (GL_RG32F)
|
||||
uniform float u_decayFactor; // exp(-decay_rate * dt)
|
||||
uniform float u_beamAngle; // current beam angle, degrees CW from north
|
||||
uniform float u_beamAnglePrev; // beam angle at previous frame
|
||||
uniform float u_sweepBg; // ambient sweep-line energy (makes beam visible)
|
||||
uniform float u_sweepBg; // ambient sweep-line energy (gain-independent)
|
||||
uniform float u_halfBeamDeg; // half-beamwidth for target blobs (display widening)
|
||||
|
||||
// Targets: .x = range_norm (0-1), .y = bearing_deg, .z = brightness, .w = size_norm
|
||||
@@ -71,23 +74,25 @@ void main() {
|
||||
float brg = degrees(atan(pos.x, pos.y));
|
||||
if (brg < 0.0) brg += 360.0;
|
||||
|
||||
// Decay previous value
|
||||
float energy = texture(u_prevPhosphor, vTexCoord).r * u_decayFactor;
|
||||
vec2 prev = texture(u_prevPhosphor, vTexCoord).rg;
|
||||
float signal = prev.r * u_decayFactor;
|
||||
float ring = prev.g * u_decayFactor;
|
||||
|
||||
if (inSweep(brg, u_beamAnglePrev, u_beamAngle)) {
|
||||
|
||||
float contrib = u_sweepBg; // beam passage gives a faint ambient glow
|
||||
|
||||
// ---- Range rings (painted at every bearing as beam sweeps) ----
|
||||
// ---- Range rings → G channel (gain-independent) ----
|
||||
float ringContrib = u_sweepBg; // sweep-background glow also in G channel
|
||||
for (int i = 0; i < u_ringCount; i++) {
|
||||
float d = abs(rng - u_ringRadii[i]);
|
||||
if (d < u_ringWidth) {
|
||||
float w = 1.0 - d / u_ringWidth;
|
||||
contrib = max(contrib, u_ringBrightness * w * w);
|
||||
ringContrib = max(ringContrib, u_ringBrightness * w * w);
|
||||
}
|
||||
}
|
||||
ring = max(ring, ringContrib);
|
||||
|
||||
// ---- Target echoes ----
|
||||
// ---- Target echoes → R channel (gain-scaled in display pass) ----
|
||||
float sigContrib = 0.0;
|
||||
for (int i = 0; i < u_targetCount; i++) {
|
||||
float tRng = u_targets[i].x;
|
||||
float tBrg = u_targets[i].y;
|
||||
@@ -96,21 +101,18 @@ void main() {
|
||||
|
||||
if (tRng <= 0.0 || tBrt <= 0.0) continue;
|
||||
|
||||
// Angular proximity: beam must be sweeping over the target's bearing
|
||||
float dBrg = angleDiff(brg, tBrg);
|
||||
if (dBrg >= u_halfBeamDeg) continue;
|
||||
|
||||
// Range proximity: pixel must be within the target blob
|
||||
float dRng = abs(rng - tRng);
|
||||
if (dRng >= tSize) continue;
|
||||
|
||||
float bw = 1.0 - dBrg / u_halfBeamDeg; // angular taper
|
||||
float rw = 1.0 - dRng / tSize; // range taper
|
||||
contrib = max(contrib, tBrt * bw * rw);
|
||||
float bw = 1.0 - dBrg / u_halfBeamDeg;
|
||||
float rw = 1.0 - dRng / tSize;
|
||||
sigContrib = max(sigContrib, tBrt * bw * rw);
|
||||
}
|
||||
signal = max(signal, sigContrib);
|
||||
}
|
||||
|
||||
energy = max(energy, contrib);
|
||||
}
|
||||
|
||||
fragOut = vec4(clamp(energy, 0.0, 1.0), 0.0, 0.0, 1.0);
|
||||
fragOut = vec4(clamp(signal, 0.0, 1.0), clamp(ring, 0.0, 1.0), 0.0, 1.0);
|
||||
}
|
||||
|
||||
8
issues
Normal file
8
issues
Normal file
@@ -0,0 +1,8 @@
|
||||
Only one range ring no matter the max range. Range ring has no number indicating ring (I forgot if I mentioned that)
|
||||
|
||||
It seems that the empty scan line is excessively strong, along with the range rings. The gain does affect the range rings. I wonder
|
||||
if this is how things are normal of a period radar. I thought that the gain would be only for targets and noise and land. Not the scan beam
|
||||
itself and the range rings. Also the cursor seems to be the same color as the p7 fading. It should be more white, like an incandescent light.
|
||||
|
||||
At 1/2 on the gain control, the sweeping beams leave a solid yellow for about 1/3 of a sweep. It is solid, not varying due to noise.
|
||||
|
||||
@@ -2,9 +2,15 @@
|
||||
* MIT License
|
||||
* Author: Mark Allyn
|
||||
*
|
||||
* phosphor.frag — maps the single-channel phosphor energy texture to
|
||||
* the P7 colour sequence (blue → green → yellow-green → dark) and
|
||||
* applies a simple inline bloom (box-filter glow) to bright pixels.
|
||||
* phosphor.frag — maps the two-channel phosphor energy texture to the
|
||||
* P7 colour sequence (blue → green → yellow-green → dark) and applies
|
||||
* a simple inline bloom (box-filter glow) to bright pixels.
|
||||
*
|
||||
* The phosphor FBO is GL_RG32F:
|
||||
* R channel — signal energy (target echoes, sweep background)
|
||||
* multiplied by u_gain before display
|
||||
* G channel — range ring energy, gain-independent; mixed with signal
|
||||
* after gain is applied so rings never dim with gain
|
||||
*
|
||||
* Coordinate system: gl_FragCoord.xy in GL viewport pixels (origin
|
||||
* bottom-left). Scope centre is passed as u_scopeCenter in the same
|
||||
@@ -14,17 +20,19 @@
|
||||
|
||||
out vec4 fragColor;
|
||||
|
||||
uniform sampler2D u_phosphor; // GL_R32F phosphor energy FBO
|
||||
uniform sampler2D u_phosphor; // GL_RG32F phosphor energy FBO
|
||||
uniform vec2 u_scopeCenter; // scope centre in GL viewport pixels (bottom-left origin)
|
||||
uniform float u_scopeRadius; // scope radius in pixels
|
||||
uniform float u_gain; // receiver gain [0,1] — scales brightness
|
||||
uniform float u_gain; // receiver gain [0,1] — scales signal (R) channel only
|
||||
uniform float u_bloomStep; // UV step for bloom sample (≈ 2.5 / FBO_SIZE)
|
||||
uniform float u_bloomStrength; // additive blend weight for bloom
|
||||
|
||||
// P7 energy thresholds (match settings.h)
|
||||
// P7 energy thresholds — MUST match settings.h P7_THRESH_* constants.
|
||||
// T_YGREE is intentionally low (0.05) to keep most of the decay in the
|
||||
// GREEN zone; see the comment in settings.h for the full rationale.
|
||||
const float T_BLUE = 0.82;
|
||||
const float T_GREEN = 0.55;
|
||||
const float T_YGREE = 0.22;
|
||||
const float T_YGREE = 0.05;
|
||||
const float T_DARK = 0.03;
|
||||
|
||||
// P7 colour anchors
|
||||
@@ -34,16 +42,22 @@ const vec3 C_YGREE = vec3(0.50, 1.00, 0.05);
|
||||
const vec3 C_YELLW = vec3(0.70, 0.70, 0.00);
|
||||
const vec3 C_BLACK = vec3(0.00, 0.00, 0.00);
|
||||
|
||||
// P7 colour ramp: hue selected by energy level, then scaled by energy so
|
||||
// brightness decreases monotonically from fresh strike (peak) to dark.
|
||||
// This prevents intermediate decay colours (yellow-green) from appearing
|
||||
// brighter than the initial blue flash.
|
||||
vec3 p7Color(float e) {
|
||||
if (e < T_DARK) return C_BLACK;
|
||||
vec3 hue;
|
||||
if (e >= T_BLUE)
|
||||
return mix(C_GREEN, C_BLUE, (e - T_GREEN) / (T_BLUE - T_GREEN));
|
||||
if (e >= T_GREEN)
|
||||
return mix(C_YGREE, C_GREEN, (e - T_YGREE) / (T_GREEN - T_YGREE));
|
||||
if (e >= T_YGREE)
|
||||
return mix(C_YELLW, C_YGREE, (e - T_DARK ) / (T_YGREE - T_DARK ));
|
||||
if (e >= T_DARK)
|
||||
return mix(C_BLACK, C_YELLW, e / T_DARK);
|
||||
return C_BLACK;
|
||||
hue = C_BLUE;
|
||||
else if (e >= T_GREEN)
|
||||
hue = mix(C_GREEN, C_BLUE, (e - T_GREEN) / (T_BLUE - T_GREEN));
|
||||
else if (e >= T_YGREE)
|
||||
hue = mix(C_YGREE, C_GREEN, (e - T_YGREE) / (T_GREEN - T_YGREE));
|
||||
else
|
||||
hue = mix(C_YELLW, C_YGREE, (e - T_DARK) / (T_YGREE - T_DARK));
|
||||
return hue * e;
|
||||
}
|
||||
|
||||
void main() {
|
||||
@@ -57,10 +71,12 @@ void main() {
|
||||
}
|
||||
|
||||
// Map from PPI delta [-1,+1] to phosphor texture UV [0,1]
|
||||
// delta.x = east, delta.y = north (both y directions already match)
|
||||
vec2 uv = delta * 0.5 + 0.5;
|
||||
|
||||
float energy = texture(u_phosphor, uv).r * u_gain;
|
||||
vec2 rg = texture(u_phosphor, uv).rg;
|
||||
// Signal (R): gain-scaled received echoes.
|
||||
// Ring (G): gain-independent timing reference; always at full brightness.
|
||||
float energy = max(rg.r * u_gain, rg.g);
|
||||
|
||||
// Inline bloom: weighted box-filter over a 5×5 neighbourhood
|
||||
float bloom = 0.0;
|
||||
@@ -68,7 +84,8 @@ void main() {
|
||||
for (int dx = -2; dx <= 2; dx++) {
|
||||
for (int dy = -2; dy <= 2; dy++) {
|
||||
float w = exp(-float(dx*dx + dy*dy) * 0.45);
|
||||
float e = texture(u_phosphor, uv + vec2(dx, dy) * u_bloomStep).r;
|
||||
vec2 srg = texture(u_phosphor, uv + vec2(dx, dy) * u_bloomStep).rg;
|
||||
float e = max(srg.r * u_gain, srg.g);
|
||||
bloom += e * w;
|
||||
wsum += w;
|
||||
}
|
||||
|
||||
@@ -4,13 +4,16 @@
|
||||
*
|
||||
* sweep.frag — phosphor accumulation update shader.
|
||||
*
|
||||
* For each texel in the 1024×1024 phosphor FBO:
|
||||
* 1. Decay the previous frame's energy by u_decayFactor.
|
||||
* 2. If the texel's PPI bearing falls within the current sweep arc
|
||||
* [u_beamAnglePrev, u_beamAngle], add contributions from:
|
||||
* - range rings (beam-painted per the P7 spec)
|
||||
* - target echoes
|
||||
* 3. Output the updated single-channel energy value.
|
||||
* The FBO is GL_RG32F (two independent energy channels):
|
||||
* R — signal energy: target echoes + sweep-background glow.
|
||||
* Multiplied by u_gain in the display pass so operators can
|
||||
* adjust received-signal brightness without touching rings.
|
||||
* G — range-ring energy: written at u_ringBrightness; NOT scaled
|
||||
* by gain. Rings are a precision timing reference, not a
|
||||
* received echo. Both channels decay at the same P7 rate.
|
||||
*
|
||||
* The sweep background (u_sweepBg) goes into the G channel so the
|
||||
* rotating beam is always visible regardless of the gain setting.
|
||||
*
|
||||
* PPI convention: north = +y, east = +x; bearing = atan2(x, y)
|
||||
* in degrees, clockwise from north.
|
||||
@@ -19,17 +22,18 @@
|
||||
|
||||
in vec2 vTexCoord;
|
||||
|
||||
layout(location = 0) out vec4 fragOut; // .r = energy; .gba unused
|
||||
layout(location = 0) out vec4 fragOut; // .r = signal; .g = ring+sweep; .ba unused
|
||||
|
||||
uniform sampler2D u_prevPhosphor; // previous frame's energy texture (GL_R32F)
|
||||
uniform sampler2D u_prevPhosphor; // previous frame's energy texture (GL_RG32F)
|
||||
uniform float u_decayFactor; // exp(-decay_rate * dt)
|
||||
uniform float u_beamAngle; // current beam angle, degrees CW from north
|
||||
uniform float u_beamAnglePrev; // beam angle at previous frame
|
||||
uniform float u_sweepBg; // ambient sweep-line energy (makes beam visible)
|
||||
uniform float u_sweepBg; // ambient sweep-line energy (gain-independent)
|
||||
uniform float u_halfBeamDeg; // half-beamwidth for target blobs (display widening)
|
||||
|
||||
// Targets: .x = range_norm (0-1), .y = bearing_deg, .z = brightness, .w = size_norm
|
||||
// Targets: .x = range_norm (0-1), .y = bearing_deg, .z = brightness, .w = radial_size_norm
|
||||
uniform vec4 u_targets[32];
|
||||
uniform float u_targetAngHalfDeg[32]; // per-target azimuthal half-width (degrees)
|
||||
uniform int u_targetCount;
|
||||
|
||||
// Range rings: up to 4 normalised radii
|
||||
@@ -71,23 +75,25 @@ void main() {
|
||||
float brg = degrees(atan(pos.x, pos.y));
|
||||
if (brg < 0.0) brg += 360.0;
|
||||
|
||||
// Decay previous value
|
||||
float energy = texture(u_prevPhosphor, vTexCoord).r * u_decayFactor;
|
||||
vec2 prev = texture(u_prevPhosphor, vTexCoord).rg;
|
||||
float signal = prev.r * u_decayFactor;
|
||||
float ring = prev.g * u_decayFactor;
|
||||
|
||||
if (inSweep(brg, u_beamAnglePrev, u_beamAngle)) {
|
||||
|
||||
float contrib = u_sweepBg; // beam passage gives a faint ambient glow
|
||||
|
||||
// ---- Range rings (painted at every bearing as beam sweeps) ----
|
||||
// ---- Range rings → G channel (gain-independent) ----
|
||||
float ringContrib = u_sweepBg; // sweep-background glow also in G channel
|
||||
for (int i = 0; i < u_ringCount; i++) {
|
||||
float d = abs(rng - u_ringRadii[i]);
|
||||
if (d < u_ringWidth) {
|
||||
float w = 1.0 - d / u_ringWidth;
|
||||
contrib = max(contrib, u_ringBrightness * w * w);
|
||||
ringContrib = max(ringContrib, u_ringBrightness * w * w);
|
||||
}
|
||||
}
|
||||
ring = max(ring, ringContrib);
|
||||
|
||||
// ---- Target echoes ----
|
||||
// ---- Target echoes → R channel (gain-scaled in display pass) ----
|
||||
float sigContrib = 0.0;
|
||||
for (int i = 0; i < u_targetCount; i++) {
|
||||
float tRng = u_targets[i].x;
|
||||
float tBrg = u_targets[i].y;
|
||||
@@ -96,21 +102,19 @@ void main() {
|
||||
|
||||
if (tRng <= 0.0 || tBrt <= 0.0) continue;
|
||||
|
||||
// Angular proximity: beam must be sweeping over the target's bearing
|
||||
float tAngHalf = u_targetAngHalfDeg[i];
|
||||
float dBrg = angleDiff(brg, tBrg);
|
||||
if (dBrg >= u_halfBeamDeg) continue;
|
||||
if (dBrg >= tAngHalf) continue;
|
||||
|
||||
// Range proximity: pixel must be within the target blob
|
||||
float dRng = abs(rng - tRng);
|
||||
if (dRng >= tSize) continue;
|
||||
|
||||
float bw = 1.0 - dBrg / u_halfBeamDeg; // angular taper
|
||||
float rw = 1.0 - dRng / tSize; // range taper
|
||||
contrib = max(contrib, tBrt * bw * rw);
|
||||
float bw = 1.0 - dBrg / tAngHalf;
|
||||
float rw = 1.0 - dRng / tSize;
|
||||
sigContrib = max(sigContrib, tBrt * bw * rw);
|
||||
}
|
||||
signal = max(signal, sigContrib);
|
||||
}
|
||||
|
||||
energy = max(energy, contrib);
|
||||
}
|
||||
|
||||
fragOut = vec4(clamp(energy, 0.0, 1.0), 0.0, 0.0, 1.0);
|
||||
fragOut = vec4(clamp(signal, 0.0, 1.0), clamp(ring, 0.0, 1.0), 0.0, 1.0);
|
||||
}
|
||||
|
||||
@@ -102,9 +102,9 @@ bool PhosphorRenderer::init(const std::string& shaderDir) {
|
||||
glGenTextures(1, &tex_[i]);
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, tex_[i]);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_R32F,
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RG32F,
|
||||
fboSize_, fboSize_, 0,
|
||||
GL_RED, GL_FLOAT, nullptr);
|
||||
GL_RG, GL_FLOAT, nullptr);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
@@ -193,15 +193,18 @@ void PhosphorRenderer::update(
|
||||
|
||||
// Target array: pack into vec4 array
|
||||
float tdata[MAX_TARGETS * 4] = {};
|
||||
float angData[MAX_TARGETS] = {};
|
||||
int tCount = (targetCount < MAX_TARGETS) ? targetCount : MAX_TARGETS;
|
||||
float invRange = (maxRangeM > 0.f) ? 1.0f / maxRangeM : 0.f;
|
||||
for (int i = 0; i < tCount; ++i) {
|
||||
tdata[i*4+0] = targets[i].range_m * invRange; // normalised 0-1
|
||||
tdata[i*4+0] = targets[i].range_m * invRange * GRAT_INNER_RING_FRAC;
|
||||
tdata[i*4+1] = targets[i].bearing_deg;
|
||||
tdata[i*4+2] = targets[i].brightness;
|
||||
tdata[i*4+3] = targets[i].size_m * invRange; // normalised blob half-radius
|
||||
tdata[i*4+3] = targets[i].size_m * invRange * GRAT_INNER_RING_FRAC;
|
||||
angData[i] = targets[i].ang_half_deg;
|
||||
}
|
||||
glUniform4fv(glGetUniformLocation(sweepProg_, "u_targets"), tCount, tdata);
|
||||
glUniform1fv(glGetUniformLocation(sweepProg_, "u_targetAngHalfDeg"), tCount, angData);
|
||||
glUniform1i (glGetUniformLocation(sweepProg_, "u_targetCount"), tCount);
|
||||
|
||||
glBindVertexArray(quadVAO_);
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
|
||||
#include "scope_marine_ppi.h"
|
||||
#include <GLFW/glfw3.h>
|
||||
#include <cstring>
|
||||
#include <cmath>
|
||||
|
||||
// ----------------------------------------------------------------
|
||||
|
||||
@@ -18,8 +18,14 @@ float MarinePPIScope::maxRangeM() const {
|
||||
void MarinePPIScope::computeRingRadii() {
|
||||
int n = MARINE_RING_COUNT[maxRangeIdx_];
|
||||
float maxMi = MARINE_RANGE_STEPS[maxRangeIdx_];
|
||||
for (int i = 0; i < n; ++i)
|
||||
ringRadiiNorm_[i] = MARINE_RING_MILES[maxRangeIdx_][i] / maxMi;
|
||||
for (int i = 0; i < n; ++i) {
|
||||
// Scale by GRAT_INNER_RING_FRAC so max-range maps to the inner
|
||||
// graticule ring boundary. Targets use the same scale factor
|
||||
// (applied in PhosphorRenderer::update), so rings and targets
|
||||
// remain co-registered in the display.
|
||||
ringRadiiNorm_[i] = (MARINE_RING_MILES[maxRangeIdx_][i] / maxMi)
|
||||
* GRAT_INNER_RING_FRAC;
|
||||
}
|
||||
}
|
||||
|
||||
void MarinePPIScope::handleKeyRange(int key, int /*action*/) {
|
||||
|
||||
@@ -185,9 +185,16 @@ void PPIScope::render(float dt, float viewportW, float viewportH) {
|
||||
}
|
||||
graticule_.render(viewportW, viewportH, gratI, brgOffsetDeg_);
|
||||
|
||||
// 3. Yellow cursor overlay
|
||||
// 3. Yellow cursor overlay — clamp cursor to max range each frame so it
|
||||
// never escapes the active display area regardless of how it was set.
|
||||
{
|
||||
float maxMi = maxM / MILES_TO_METERS;
|
||||
if (cursorRngMi_ > maxMi) cursorRngMi_ = maxMi;
|
||||
}
|
||||
// Map cursor range [0, maxM] → normalised radius [0, GRAT_INNER_RING_FRAC]
|
||||
// so the cursor at max range sits on the outer ring, not on the bezel.
|
||||
float cursorNorm = (maxM > 0.f)
|
||||
? std::min((cursorRngMi_ * MILES_TO_METERS) / maxM, 1.0f)
|
||||
? (cursorRngMi_ * MILES_TO_METERS / maxM) * GRAT_INNER_RING_FRAC
|
||||
: 0.f;
|
||||
// Cursor bearing in display coordinates (subtract offset so it tracks the display)
|
||||
float dispBrg = std::fmod(cursorBrgDeg_ - brgOffsetDeg_ + 360.f, 360.f);
|
||||
|
||||
@@ -31,9 +31,16 @@ constexpr int PHOSPHOR_FBO_SIZE = 1024; // texels per side for phospho
|
||||
constexpr float P7_DECAY_RATE = 1.1513f; // s^-1; <1% remains after 4 s
|
||||
|
||||
// Energy thresholds that define colour transitions in the display shader
|
||||
// T_YGREE is deliberately low (0.05) so that the ring spends the vast
|
||||
// majority of the 4-second sweep period in the GREEN zone rather than
|
||||
// in the yellow-green/yellow zone. With exponential decay (rate 1.15),
|
||||
// a ring painted at 0.72 stays green for ~2.5 s, dips through a faint
|
||||
// yellow-green for ~0.45 s (≈ 40° of arc), then goes black. Setting
|
||||
// T_YGREE = 0.22 (old value) extended the yellow zone to ~1.75 s (44%
|
||||
// of the scope arc), which is the source of the "solid yellow" report.
|
||||
constexpr float P7_THRESH_BLUE = 0.82f; // above this: blue strike
|
||||
constexpr float P7_THRESH_GREEN = 0.55f; // above this: green persistence
|
||||
constexpr float P7_THRESH_YELLOW_GR = 0.22f; // above this: yellow-green fade
|
||||
constexpr float P7_THRESH_YELLOW_GR = 0.05f; // above this: yellow-green fade
|
||||
constexpr float P7_THRESH_DARK = 0.03f; // below this: essentially black
|
||||
|
||||
// Colour anchors (RGB)
|
||||
@@ -42,8 +49,12 @@ constexpr float P7_GREEN_R = 0.05f, P7_GREEN_G = 1.00f, P7_GREEN_B = 0.30f;
|
||||
constexpr float P7_YGREE_R = 0.50f, P7_YGREE_G = 1.00f, P7_YGREE_B = 0.05f;
|
||||
constexpr float P7_YELLW_R = 0.70f, P7_YELLW_G = 0.70f, P7_YELLW_B = 0.00f;
|
||||
|
||||
// Sweep background energy — gives the rotating beam its visible glow
|
||||
constexpr float SWEEP_BACKGROUND_ENERGY = 0.10f;
|
||||
// Sweep background energy written to the G channel each frame the beam
|
||||
// sweeps over a texel. Kept just above T_DARK so the rotating beam is
|
||||
// barely visible as a dim trace; it decays to black in ~0.3 s (7% of
|
||||
// the 4-second sweep arc). 0.10 (old value) left a visible glow for
|
||||
// ~1.3 s (33% of arc) — major contributor to the "solid yellow" report.
|
||||
constexpr float SWEEP_BACKGROUND_ENERGY = 0.04f;
|
||||
// Half-beamwidth used by sweep shader for target blob display (degrees)
|
||||
constexpr float SWEEP_HALF_BEAM_DEG = 1.0f;
|
||||
|
||||
@@ -83,7 +94,13 @@ constexpr int GRAT_SEGMENTS = 360; // circle tessellation segm
|
||||
// RANGE RINGS (beam-painted; widths in normalised 0-1 scope space)
|
||||
// ================================================================
|
||||
constexpr float RING_WIDTH_NORM = 0.005f;
|
||||
constexpr float RING_BRIGHTNESS = 0.72f;
|
||||
constexpr float RING_BRIGHTNESS = 1.0f;
|
||||
|
||||
// Range-ring distance labels
|
||||
// Labels appear at a fixed bearing so they don't clutter the display.
|
||||
// Colour uses the P7 fresh-blue constants (P7_BLUE_R/G/B) already above.
|
||||
constexpr float RING_LABEL_BRG_DEG = 45.0f; // NE: clear of bearing-mark clusters
|
||||
constexpr int RING_LABEL_FONT_SIZE = 14; // pixels (matches graticule labels)
|
||||
|
||||
// Marine PPI range steps (miles) and ring definitions
|
||||
// Index: 0 (max 2 mi) 1 (max 4 mi) 2 (max 6 mi)
|
||||
|
||||
@@ -67,6 +67,11 @@ Simulator::Simulator() {
|
||||
// 7. Large barge under tow N — bearing 355°, 4.8 mi
|
||||
targets_[n++] = { 7, 48.8127f, -122.5739f, 3.08f, 175.0f, 1000.0f, 30.0f };
|
||||
|
||||
// 8. DEBUG: large broadside cargo ship NE — bearing 045°, 1.0 mi
|
||||
// Stationary (speed=0). RCS 500,000 m² (big steel hull broadside).
|
||||
// sizeM=150 so the blob is clearly visible even in no-persistence mode.
|
||||
targets_[n++] = { 8, 48.7538f, -122.5492f, 0.0f, 0.0f, 500000.0f, 150.0f };
|
||||
|
||||
targetCount_ = n;
|
||||
}
|
||||
|
||||
|
||||
@@ -27,7 +27,8 @@ struct SimTarget {
|
||||
float speedMps; // metres per second
|
||||
float headingDeg; // true heading, CW from north
|
||||
float sigmaM2; // RCS in m²
|
||||
float sizeM; // physical blob half-radius in metres
|
||||
float sizeM; // radial blob half-width in metres (range direction)
|
||||
float angHalfDeg; // azimuthal half-width in degrees (bearing direction)
|
||||
};
|
||||
|
||||
class Simulator {
|
||||
|
||||
@@ -23,7 +23,8 @@ struct TargetState {
|
||||
float range_m = 0.0f; // metres from radar origin
|
||||
float bearing_deg = 0.0f; // degrees true, CW from north
|
||||
float brightness = 0.0f; // 0-1, from radar equation
|
||||
float size_m = 50.0f; // physical blob half-radius in metres; scope normalises to [0,1]
|
||||
float size_m = 50.0f; // radial blob half-width in metres (range direction)
|
||||
float ang_half_deg = SWEEP_HALF_BEAM_DEG; // azimuthal half-width in degrees
|
||||
bool valid = false;
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user