Compare commits
61 Commits
test-win
...
spacecruft
Author | SHA1 | Date |
---|---|---|
Jeff Moe | d0cec92b62 | |
Jeff Moe | 34a3b5a9cd | |
Jeff Moe | 470cbc3c99 | |
Jeff Moe | 88047d9b06 | |
Jeff Moe | 71cf5dda82 | |
Jeff Moe | 646e755964 | |
Jeff Moe | d00a02c463 | |
Jeff Moe | 791c80d3d0 | |
Jeff Moe | 7693e49057 | |
Jeff Moe | e5c825b5f0 | |
Jeff Moe | 916ac7be22 | |
Jeff Moe | 9878b500b1 | |
Jeff Moe | 9b561aa551 | |
dave-kaye | 804a5de2a7 | |
Andrew Tribick | c6a320d086 | |
Andrew Tribick | 0c177cae01 | |
Andrew Tribick | bc75235150 | |
Hleb Valoshka | 4c6fa126d6 | |
Hleb Valoshka | 698d03cd82 | |
Hleb Valoshka | 6ab7660e0c | |
Levin Li | b4cf176ac3 | |
Georgi | 71a65fb33c | |
Georgi | 704a075d0a | |
Georgi | a87dc1bc62 | |
Hleb Valoshka | f4bd55991f | |
Hleb Valoshka | 746b9e3ef3 | |
Hleb Valoshka | ca80f4448a | |
Hleb Valoshka | dee6a216f7 | |
Andrew Tribick | 2f77629216 | |
Andrew Tribick | d2f53d0a56 | |
Hleb Valoshka | fb08de771a | |
Levin Li | 318b4378a9 | |
Levin Li | 6b856b3352 | |
Heiko Becker | e51f3d5b97 | |
Andrew Tribick | 60ed8238b1 | |
Hleb Valoshka | cbdd9de63f | |
transifex-integration[bot] | a783eee8fe | |
Hleb Valoshka | 9d60f6e660 | |
Hleb Valoshka | b7dd51fc81 | |
Hleb Valoshka | fecc0ca0a9 | |
Hleb Valoshka | c95e554c7a | |
Yasushi SHOJI | 3702250525 | |
Yasushi SHOJI | 3a218976bf | |
SevenSpheres | 38f645ff8f | |
Andrew Tribick | 3a7e6d793b | |
Hleb Valoshka | 8f8a2f7677 | |
Hleb Valoshka | 772fe24e1b | |
Hleb Valoshka | 96e282e161 | |
Hleb Valoshka | 20a4d13328 | |
Hleb Valoshka | 29a2e1ec1c | |
Hleb Valoshka | 2cb9da1085 | |
Hleb Valoshka | 34d18bb316 | |
Hleb Valoshka | f969b37c3e | |
Andrew Tribick | 3c9334ece9 | |
Levin Li | fc561a7927 | |
Levin Li | 9d1bcf14b3 | |
Andrew Tribick | 40ed2011bf | |
Andrew Tribick | 7cf1aac419 | |
Levin Li | 25cbfabba0 | |
Andrew Tribick | 245225dcdf | |
Andrew Tribick | 410f86fc88 |
100
.clang-format
100
.clang-format
|
@ -1,47 +1,63 @@
|
||||||
AccessModifierOffset: -3
|
---
|
||||||
AlignEscapedNewlinesLeft: true
|
AccessModifierOffset: '-4'
|
||||||
AlignTrailingComments: true
|
AlignAfterOpenBracket: AlwaysBreak
|
||||||
AllowAllParametersOfDeclarationOnNextLine: false
|
AlignConsecutiveMacros: 'true'
|
||||||
AllowShortFunctionsOnASingleLine: true
|
AlignConsecutiveAssignments: 'true'
|
||||||
AllowShortIfStatementsOnASingleLine: false
|
AlignConsecutiveDeclarations: 'true'
|
||||||
AllowShortLoopsOnASingleLine: false
|
AlignEscapedNewlines: Left
|
||||||
AlwaysBreakBeforeMultilineStrings: false
|
AlignOperands: 'true'
|
||||||
AlwaysBreakTemplateDeclarations: true
|
AlignTrailingComments: 'true'
|
||||||
BinPackParameters: false
|
AllowAllArgumentsOnNextLine: 'false'
|
||||||
BreakBeforeBinaryOperators: false
|
AllowAllConstructorInitializersOnNextLine: 'false'
|
||||||
|
AllowAllParametersOfDeclarationOnNextLine: 'false'
|
||||||
|
AllowShortBlocksOnASingleLine: 'false'
|
||||||
|
AllowShortCaseLabelsOnASingleLine: 'false'
|
||||||
|
AllowShortFunctionsOnASingleLine: None
|
||||||
|
AllowShortIfStatementsOnASingleLine: 'false'
|
||||||
|
AllowShortLambdasOnASingleLine: All
|
||||||
|
AllowShortLoopsOnASingleLine: 'true'
|
||||||
|
AlwaysBreakAfterReturnType: TopLevelDefinitions
|
||||||
|
AlwaysBreakBeforeMultilineStrings: 'false'
|
||||||
|
AlwaysBreakTemplateDeclarations: 'Yes'
|
||||||
|
BinPackArguments: 'false'
|
||||||
|
BinPackParameters: 'false'
|
||||||
|
BreakBeforeBinaryOperators: All
|
||||||
BreakBeforeBraces: Allman
|
BreakBeforeBraces: Allman
|
||||||
BreakBeforeTernaryOperators: false
|
BreakBeforeTernaryOperators: 'false'
|
||||||
BreakConstructorInitializersBeforeComma: false
|
BreakConstructorInitializers: AfterColon
|
||||||
ColumnLimit: 80
|
BreakInheritanceList: AfterColon
|
||||||
CommentPragmas: ''
|
BreakStringLiterals: 'true'
|
||||||
ConstructorInitializerAllOnOneLineOrOnePerLine: false
|
ColumnLimit: '100'
|
||||||
ConstructorInitializerIndentWidth: 0
|
CompactNamespaces: 'false'
|
||||||
ContinuationIndentWidth: 0
|
ConstructorInitializerAllOnOneLineOrOnePerLine: 'false'
|
||||||
Cpp11BracedListStyle: false
|
Cpp11BracedListStyle: 'false'
|
||||||
DerivePointerBinding: false
|
FixNamespaceComments: 'true'
|
||||||
IndentCaseLabels: false
|
IncludeBlocks: Regroup
|
||||||
IndentFunctionDeclarationAfterType: false
|
IndentCaseLabels: 'false'
|
||||||
IndentWidth: 4
|
IndentPPDirectives: None
|
||||||
|
IndentWidth: '4'
|
||||||
|
IndentWrappedFunctionNames: 'false'
|
||||||
|
KeepEmptyLinesAtTheStartOfBlocks: 'false'
|
||||||
Language: Cpp
|
Language: Cpp
|
||||||
MaxEmptyLinesToKeep: 2
|
MaxEmptyLinesToKeep: '1'
|
||||||
NamespaceIndentation: None
|
NamespaceIndentation: None
|
||||||
ObjCSpaceAfterProperty: true
|
PointerAlignment: Right
|
||||||
ObjCSpaceBeforeProtocolList: true
|
ReflowComments: 'true'
|
||||||
PenaltyBreakBeforeFirstCallParameter: 100
|
SortIncludes: 'true'
|
||||||
PenaltyBreakComment: 100
|
SortUsingDeclarations: 'true'
|
||||||
PenaltyBreakFirstLessLess: 0
|
SpaceAfterLogicalNot: 'false'
|
||||||
PenaltyBreakString: 100
|
SpaceAfterTemplateKeyword: 'false'
|
||||||
PenaltyExcessCharacter: 1
|
SpaceBeforeAssignmentOperators: 'true'
|
||||||
PenaltyReturnTypeOnItsOwnLine: 20
|
SpaceBeforeCtorInitializerColon: 'true'
|
||||||
PointerBindsToType: true
|
SpaceBeforeInheritanceColon: 'true'
|
||||||
SpaceBeforeAssignmentOperators: true
|
|
||||||
SpaceBeforeParens: ControlStatements
|
SpaceBeforeParens: ControlStatements
|
||||||
SpaceInEmptyParentheses: false
|
SpaceBeforeRangeBasedForLoopColon: 'true'
|
||||||
SpacesBeforeTrailingComments: 1
|
SpaceInEmptyParentheses: 'false'
|
||||||
SpacesInAngles: false
|
SpacesBeforeTrailingComments: '1'
|
||||||
SpacesInCStyleCastParentheses: false
|
SpacesInAngles: 'false'
|
||||||
SpacesInContainerLiterals: false
|
SpacesInParentheses: 'false'
|
||||||
SpacesInParentheses: false
|
SpacesInSquareBrackets: 'false'
|
||||||
Standard: Cpp11
|
Standard: c++17
|
||||||
TabWidth: 4
|
TabWidth: '4'
|
||||||
UseTab: Never
|
UseTab: Never
|
||||||
|
UseCRLF: 'false'
|
||||||
|
|
|
@ -9,6 +9,7 @@ Release/
|
||||||
*.la
|
*.la
|
||||||
*.exe
|
*.exe
|
||||||
*.dll
|
*.dll
|
||||||
|
*.swp
|
||||||
.DS_Store
|
.DS_Store
|
||||||
po*/*.gmo
|
po*/*.gmo
|
||||||
po*/POTFILES
|
po*/POTFILES
|
||||||
|
@ -23,3 +24,4 @@ models/
|
||||||
textures/
|
textures/
|
||||||
mingw/
|
mingw/
|
||||||
content/
|
content/
|
||||||
|
CMakeSettings.json
|
||||||
|
|
|
@ -1,9 +1,6 @@
|
||||||
[submodule "thirdparty/Spice"]
|
[submodule "thirdparty/Spice"]
|
||||||
path = thirdparty/Spice
|
path = thirdparty/Spice
|
||||||
url = https://github.com/OpenSpace/Spice.git
|
url = https://github.com/OpenSpace/Spice.git
|
||||||
[submodule "content"]
|
|
||||||
path = content
|
|
||||||
url = https://github.com/CelestiaProject/CelestiaContent.git
|
|
||||||
[submodule "thirdparty/fmt"]
|
[submodule "thirdparty/fmt"]
|
||||||
path = thirdparty/fmt
|
path = thirdparty/fmt
|
||||||
url = https://github.com/fmtlib/fmt.git
|
url = https://github.com/fmtlib/fmt.git
|
||||||
|
|
|
@ -2,6 +2,11 @@ cmake_minimum_required(VERSION 3.8)
|
||||||
|
|
||||||
option(LEGACY_OPENGL_LIBS "Use legacy OpenGL libraries instead of glvnd library (Default: off)" OFF)
|
option(LEGACY_OPENGL_LIBS "Use legacy OpenGL libraries instead of glvnd library (Default: off)" OFF)
|
||||||
|
|
||||||
|
# Plain and keyword target_link_libraries() signatures cannot be mixed
|
||||||
|
if (POLICY CMP0023)
|
||||||
|
cmake_policy(SET CMP0023 NEW)
|
||||||
|
endif()
|
||||||
|
|
||||||
# Honor link flags in try_compile()
|
# Honor link flags in try_compile()
|
||||||
if (POLICY CMP0056)
|
if (POLICY CMP0056)
|
||||||
cmake_policy(SET CMP0056 NEW)
|
cmake_policy(SET CMP0056 NEW)
|
||||||
|
@ -57,6 +62,7 @@ option(FAST_MATH "Build with unsafe fast-math compiller option (Default: of
|
||||||
option(ENABLE_TESTS "Enable unit tests? (Default: off)" OFF)
|
option(ENABLE_TESTS "Enable unit tests? (Default: off)" OFF)
|
||||||
option(ENABLE_GLES "Build for OpenGL ES 2.0 instead of OpenGL 2.1 (Default: off)" OFF)
|
option(ENABLE_GLES "Build for OpenGL ES 2.0 instead of OpenGL 2.1 (Default: off)" OFF)
|
||||||
option(USE_GTKGLEXT "Use libgtkglext1 for GTK2 frontend (Default: on)" ON)
|
option(USE_GTKGLEXT "Use libgtkglext1 for GTK2 frontend (Default: on)" ON)
|
||||||
|
option(USE_QT6 "Use Qt6 in Qt frontend (Default: off)" OFF)
|
||||||
option(USE_GTK3 "Use Gtk3 in GTK2 frontend (Default: off)" OFF)
|
option(USE_GTK3 "Use Gtk3 in GTK2 frontend (Default: off)" OFF)
|
||||||
|
|
||||||
if(ENABLE_GLES)
|
if(ENABLE_GLES)
|
||||||
|
@ -244,6 +250,14 @@ endif()
|
||||||
find_package(Freetype REQUIRED)
|
find_package(Freetype REQUIRED)
|
||||||
link_libraries(Freetype::Freetype)
|
link_libraries(Freetype::Freetype)
|
||||||
|
|
||||||
|
find_package(meshoptimizer CONFIG QUIET)
|
||||||
|
if(meshoptimizer_FOUND)
|
||||||
|
message(STATUS "Found meshoptimizer library")
|
||||||
|
set(HAVE_MESHOPTIMIZER 1)
|
||||||
|
else()
|
||||||
|
message(STATUS "meshoptimizer library is missing")
|
||||||
|
endif()
|
||||||
|
|
||||||
#[[
|
#[[
|
||||||
get_cmake_property(_variableNames VARIABLES)
|
get_cmake_property(_variableNames VARIABLES)
|
||||||
list (SORT _variableNames)
|
list (SORT _variableNames)
|
||||||
|
|
108
ChangeLog
108
ChangeLog
|
@ -246,7 +246,7 @@ Code:
|
||||||
* Windows version: InstallShield setup
|
* Windows version: InstallShield setup
|
||||||
* Windows version: added controls help dialog
|
* Windows version: added controls help dialog
|
||||||
* UNIX version: implemented find object and about dialogs (Gnome/Gtk only)
|
* UNIX version: implemented find object and about dialogs (Gnome/Gtk only)
|
||||||
|
|
||||||
Code:
|
Code:
|
||||||
* Moved star browser and solar system browser code into separate modules
|
* Moved star browser and solar system browser code into separate modules
|
||||||
* Fixed DPRINTF macro so it's not broken in g++
|
* Fixed DPRINTF macro so it's not broken in g++
|
||||||
|
@ -276,7 +276,7 @@ Code:
|
||||||
textures added to OpenGL Info dialog.
|
textures added to OpenGL Info dialog.
|
||||||
* New objects: Comet Borrelly, the giant Kuiper Belt object 2001 KX76,
|
* New objects: Comet Borrelly, the giant Kuiper Belt object 2001 KX76,
|
||||||
and the Hubble Space Telescope
|
and the Hubble Space Telescope
|
||||||
|
|
||||||
Code:
|
Code:
|
||||||
* Rewrote texture and model managers
|
* Rewrote texture and model managers
|
||||||
* Cleaned up simulation.cpp to use frames of reference and eliminated a lot
|
* Cleaned up simulation.cpp to use frames of reference and eliminated a lot
|
||||||
|
@ -393,7 +393,7 @@ Code:
|
||||||
a single modeless dialog.
|
a single modeless dialog.
|
||||||
* Fixed period and rotation of Phoebe
|
* Fixed period and rotation of Phoebe
|
||||||
|
|
||||||
|
|
||||||
1.2.1
|
1.2.1
|
||||||
* Unix: configure.in changes to better find OpenGL libraries by Bruckner.
|
* Unix: configure.in changes to better find OpenGL libraries by Bruckner.
|
||||||
* Added accurate orbital calculations for Galilean satellites.
|
* Added accurate orbital calculations for Galilean satellites.
|
||||||
|
@ -404,7 +404,7 @@ Code:
|
||||||
* Windows: Fixed crash that occurred when recalling a location with
|
* Windows: Fixed crash that occurred when recalling a location with
|
||||||
no selection
|
no selection
|
||||||
|
|
||||||
|
|
||||||
1.2.2
|
1.2.2
|
||||||
* Improved find algorithm for starnames, and combined names from hdnames.dat
|
* Improved find algorithm for starnames, and combined names from hdnames.dat
|
||||||
into starnames.dat. Also added several additional names and variant spellings
|
into starnames.dat. Also added several additional names and variant spellings
|
||||||
|
@ -557,7 +557,7 @@ Code:
|
||||||
* New colors for celestial grid and constellation figures
|
* New colors for celestial grid and constellation figures
|
||||||
* Tuning of Gnome GUI: underlined key accelerators, enabled operation of all
|
* Tuning of Gnome GUI: underlined key accelerators, enabled operation of all
|
||||||
dialogs and menus with ALT <key>, arrow keys, and Tab
|
dialogs and menus with ALT <key>, arrow keys, and Tab
|
||||||
* Linux: GUI now synced with current state of pixel/vertex shaders
|
* Linux: GUI now synced with current state of pixel/vertex shaders
|
||||||
* New keyboard bindings:
|
* New keyboard bindings:
|
||||||
Ctrl+Y : automag toggle
|
Ctrl+Y : automag toggle
|
||||||
Ctrl+T : toggle display of comet tails
|
Ctrl+T : toggle display of comet tails
|
||||||
|
@ -572,16 +572,16 @@ Code:
|
||||||
when building with VS.NET
|
when building with VS.NET
|
||||||
* Cleaned up OpenGL extension initialization
|
* Cleaned up OpenGL extension initialization
|
||||||
* Significantly improved the reliability of object selection via mouse
|
* Significantly improved the reliability of object selection via mouse
|
||||||
click, notably for small fields of view in the arcsec range.
|
click, notably for small fields of view in the arcsec range.
|
||||||
* Fixed the 'move' script command
|
* Fixed the 'move' script command
|
||||||
* New script commands: setfaintestautomag45deg {magnitude float},
|
* New script commands: setfaintestautomag45deg {magnitude float},
|
||||||
lookback {}
|
lookback {}
|
||||||
* [,] keys now adjust the limiting magnitude at 45 degrees
|
* [,] keys now adjust the limiting magnitude at 45 degrees
|
||||||
field of view, if automag is ON. Values displayed via flash messages
|
field of view, if automag is ON. Values displayed via flash messages
|
||||||
* Associated the 'looking back' operation with the '*' key shortcut
|
* Associated the 'looking back' operation with the '*' key shortcut
|
||||||
* Fixed bug in orbits of Galilean moons
|
* Fixed bug in orbits of Galilean moons
|
||||||
* Corrected equatorial planes and rotation offsets for the major planets
|
* Corrected equatorial planes and rotation offsets for the major planets
|
||||||
* Linux: Added KDE interface, all features of the GTK interface are
|
* Linux: Added KDE interface, all features of the GTK interface are
|
||||||
available (except for the Tour Guide), new features include:
|
available (except for the Tour Guide), new features include:
|
||||||
- Bookmarks / URLs;
|
- Bookmarks / URLs;
|
||||||
- History navigation;* Improved drag and drop of cel:// URLs on Windows
|
- History navigation;* Improved drag and drop of cel:// URLs on Windows
|
||||||
|
@ -632,8 +632,8 @@ Code:
|
||||||
- Markers may also be set on objects using the right-click context menu
|
- Markers may also be set on objects using the right-click context menu
|
||||||
- Added mark/unmark commands for scripts
|
- Added mark/unmark commands for scripts
|
||||||
- Bound Ctrl+K to toggle display of markers
|
- Bound Ctrl+K to toggle display of markers
|
||||||
- Added flash messages indicating on|off status of markers
|
- Added flash messages indicating on|off status of markers
|
||||||
- Implemented markers into KDE interface
|
- Implemented markers into KDE interface
|
||||||
* Added triangle-accurate picking of mesh objects
|
* Added triangle-accurate picking of mesh objects
|
||||||
* Multiview
|
* Multiview
|
||||||
- Ctrl+R : split view vertically
|
- Ctrl+R : split view vertically
|
||||||
|
@ -664,7 +664,7 @@ Code:
|
||||||
* Updated configuration files for new versions of autoconf
|
* Updated configuration files for new versions of autoconf
|
||||||
|
|
||||||
1.3.1
|
1.3.1
|
||||||
* Improved inclusion of light travel delay, also in KDE time setting dialog
|
* Improved inclusion of light travel delay, also in KDE time setting dialog
|
||||||
* Fixed lookback command for subsequent changes of target speed
|
* Fixed lookback command for subsequent changes of target speed
|
||||||
* Allow wildcard character * inplace of extension for texture filenames
|
* Allow wildcard character * inplace of extension for texture filenames
|
||||||
* Fix bump mapping (again)
|
* Fix bump mapping (again)
|
||||||
|
@ -706,7 +706,7 @@ Code:
|
||||||
* Made cancel script command stop motion, tracking, and any object-relative
|
* Made cancel script command stop motion, tracking, and any object-relative
|
||||||
coordinate system.
|
coordinate system.
|
||||||
* Adjusted estimates for radii and rotation periods of extrasolar planets;
|
* Adjusted estimates for radii and rotation periods of extrasolar planets;
|
||||||
rotation rates account (somewhat) for the effects of tidal despinning.
|
rotation rates account (somewhat) for the effects of tidal despinning.
|
||||||
* Fixed a bug that was causing precision loss in orientation values; this fixes
|
* Fixed a bug that was causing precision loss in orientation values; this fixes
|
||||||
some of the jerkiness apparent at very low fields of view.
|
some of the jerkiness apparent at very low fields of view.
|
||||||
* Corrected radii of Uranus's rings
|
* Corrected radii of Uranus's rings
|
||||||
|
@ -739,7 +739,7 @@ Code:
|
||||||
* Eliminated obscuring of location labels that occurred low view aspect ratios
|
* Eliminated obscuring of location labels that occurred low view aspect ratios
|
||||||
* Added models of comet Halley and the small moons Pandora and Larissa
|
* Added models of comet Halley and the small moons Pandora and Larissa
|
||||||
* Added limit of knowledge masks for the Galilean moons
|
* Added limit of knowledge masks for the Galilean moons
|
||||||
* Changed spectral class of carbon stars to C, which supercedes and combines
|
* Changed spectral class of carbon stars to C, which supersedes and combines
|
||||||
R and N
|
R and N
|
||||||
* Lua scripting additions
|
* Lua scripting additions
|
||||||
* View management commands
|
* View management commands
|
||||||
|
@ -760,7 +760,7 @@ Code:
|
||||||
* Implemented an algorithm for importance weights to avoid overlapping or
|
* Implemented an algorithm for importance weights to avoid overlapping or
|
||||||
too crowded location labels for Mars, Venus and the Moon
|
too crowded location labels for Mars, Venus and the Moon
|
||||||
* Added new textures for Titan based on recent imaging from the Cassini
|
* Added new textures for Titan based on recent imaging from the Cassini
|
||||||
mission
|
mission
|
||||||
* Improved depth sorting so that hidden surface removal works properly for
|
* Improved depth sorting so that hidden surface removal works properly for
|
||||||
overlapping objects
|
overlapping objects
|
||||||
* Added theoretical estimates of oblateness and rotation rate for extrasolar
|
* Added theoretical estimates of oblateness and rotation rate for extrasolar
|
||||||
|
@ -805,16 +805,16 @@ Code:
|
||||||
* Implemented new GLSL render path; NVIDIA combiners and GeForceFX paths
|
* Implemented new GLSL render path; NVIDIA combiners and GeForceFX paths
|
||||||
deprecated.
|
deprecated.
|
||||||
* Display UTF-8 superscript digits in some star names
|
* Display UTF-8 superscript digits in some star names
|
||||||
* Updated the Titan texture. It accomodates all published high resolution
|
* Updated the Titan texture. It accomodates all published high resolution
|
||||||
imaging from the Cassini mission until and including the flyby of 03/31/05.
|
imaging from the Cassini mission until and including the flyby of 03/31/05.
|
||||||
* Updated the Iapetus texture. It accomodates all published high resolution
|
* Updated the Iapetus texture. It accomodates all published high resolution
|
||||||
imaging from the Cassini mission, including also a unique hires photo taken
|
imaging from the Cassini mission, including also a unique hires photo taken
|
||||||
in "Saturn shine".
|
in "Saturn shine".
|
||||||
* Added catalogs of 163 visual and 39 spectroscopic binary orbits,
|
* Added catalogs of 163 visual and 39 spectroscopic binary orbits,
|
||||||
respectively, (S<>erhjelm 1999, Pourbaix 2000) with known primary/secondary
|
respectively, (S<>erhjelm 1999, Pourbaix 2000) with known primary/secondary
|
||||||
mass ratios.
|
mass ratios.
|
||||||
* Added an extended and precise data base of 942 galaxies
|
* Added an extended and precise data base of 942 galaxies
|
||||||
(Steinicke's rev. NGC/IC, 2005) with a magnitude cutoff Bmag < 12.
|
(Steinicke's rev. NGC/IC, 2005) with a magnitude cutoff Bmag < 12.
|
||||||
* Included the commented PERL scripts used to extract and adapt the binary
|
* Included the commented PERL scripts used to extract and adapt the binary
|
||||||
orbit and galaxy data from published professional catalogs.
|
orbit and galaxy data from published professional catalogs.
|
||||||
* Added --extrasdir command line option for specifying additional directories
|
* Added --extrasdir command line option for specifying additional directories
|
||||||
|
@ -843,13 +843,13 @@ Code:
|
||||||
- fixed automake bug where GConf schema would always install
|
- fixed automake bug where GConf schema would always install
|
||||||
- removed linking against glut for no reason
|
- removed linking against glut for no reason
|
||||||
* Implemented complete precision catalog (Steinicke's revised NGC/IC, 2005) of
|
* Implemented complete precision catalog (Steinicke's revised NGC/IC, 2005) of
|
||||||
10610 galaxies with
|
10610 galaxies with
|
||||||
- distance information from four catalogs ( 6 methods ),
|
- distance information from four catalogs ( 6 methods ),
|
||||||
- <= 4 alternate names,
|
- <= 4 alternate names,
|
||||||
- info-URLs,
|
- info-URLs,
|
||||||
- absolute magnitudes and
|
- absolute magnitudes and
|
||||||
- correct sizes & orientations in space, as calculated from catalog
|
- correct sizes & orientations in space, as calculated from catalog
|
||||||
parameters.
|
parameters.
|
||||||
* Included well commented Perl script (deepsky.pl) as documentation. The used distance determination method is indicated in catalog for each galaxy.
|
* Included well commented Perl script (deepsky.pl) as documentation. The used distance determination method is indicated in catalog for each galaxy.
|
||||||
* Updated binary star data base (visualbins.stc, spectbins.dsc) and respective
|
* Updated binary star data base (visualbins.stc, spectbins.dsc) and respective
|
||||||
PERL catalog extraction scripts (visualbins.pl, spectbins.pl), such as to eliminate double occurences wrto nearstars.stc (, which remained unaffected).
|
PERL catalog extraction scripts (visualbins.pl, spectbins.pl), such as to eliminate double occurences wrto nearstars.stc (, which remained unaffected).
|
||||||
|
@ -890,7 +890,7 @@ Code:
|
||||||
template from S0 disk template via rescaling by (1.0f, 3.8f, 1.0f);
|
template from S0 disk template via rescaling by (1.0f, 3.8f, 1.0f);
|
||||||
- fixed wrong x,y alignment of elliptical rescaling.
|
- fixed wrong x,y alignment of elliptical rescaling.
|
||||||
* Added code to ease compilation with newer Xcode versions (Macintosh).
|
* Added code to ease compilation with newer Xcode versions (Macintosh).
|
||||||
* Updated src/celengine/Makefile.am for Linux building.
|
* Updated src/celengine/Makefile.am for Linux building.
|
||||||
* Introduced a new cel function => renderflags {set "nebulae"}.
|
* Introduced a new cel function => renderflags {set "nebulae"}.
|
||||||
* Reduced the default value of 'faintestAutoMag45deg' from 8.5 to 7.0.
|
* Reduced the default value of 'faintestAutoMag45deg' from 8.5 to 7.0.
|
||||||
* Fixed the visibility of the Milky Way during day-time and the abrupt
|
* Fixed the visibility of the Milky Way during day-time and the abrupt
|
||||||
|
@ -904,10 +904,10 @@ Code:
|
||||||
* Deleted various source code files that became superfluous.
|
* Deleted various source code files that became superfluous.
|
||||||
* Improved comet display. Introduced a neat scheme implementing comet tail
|
* Improved comet display. Introduced a neat scheme implementing comet tail
|
||||||
fading (between 4 and 6 AU for Sol). Systems with several suns and
|
fading (between 4 and 6 AU for Sol). Systems with several suns and
|
||||||
luminosities different from the solar one are accounted for.
|
luminosities different from the solar one are accounted for.
|
||||||
* Implemented a new, simple scheme avoiding overcrowded galaxy labels.
|
* Implemented a new, simple scheme avoiding overcrowded galaxy labels.
|
||||||
Their "importance" is sorted according to apparent magnitude! Thus the
|
Their "importance" is sorted according to apparent magnitude! Thus the
|
||||||
labels of the brightest galaxies pop up first upon zooming in...
|
labels of the brightest galaxies pop up first upon zooming in...
|
||||||
* Fixes/workarounds for OpenGL 2.0 render paths on both nVidia and ATI cards.
|
* Fixes/workarounds for OpenGL 2.0 render paths on both nVidia and ATI cards.
|
||||||
|
|
||||||
|
|
||||||
|
@ -932,7 +932,7 @@ Code:
|
||||||
located inside the galaxy (Milky Way...).
|
located inside the galaxy (Milky Way...).
|
||||||
* Eliminated various incorrect Hubble type acronyms in deepsky.dsc that had
|
* Eliminated various incorrect Hubble type acronyms in deepsky.dsc that had
|
||||||
penetrated the PERL filter.
|
penetrated the PERL filter.
|
||||||
* Add the corrected PERL script deepsky.pl.
|
* Add the corrected PERL script deepsky.pl.
|
||||||
* Mac: Universal binary - runs natively on Intel and PPC
|
* Mac: Universal binary - runs natively on Intel and PPC
|
||||||
* Mac: OpenGL 2.0 render path should now work on many configurations
|
* Mac: OpenGL 2.0 render path should now work on many configurations
|
||||||
(requires OS X 10.4.3 or later)
|
(requires OS X 10.4.3 or later)
|
||||||
|
@ -948,7 +948,7 @@ Code:
|
||||||
* Mac: Fixed crash when LANG or LC environment variables are set
|
* Mac: Fixed crash when LANG or LC environment variables are set
|
||||||
* Mac: Added bona fide English and French help menu
|
* Mac: Added bona fide English and French help menu
|
||||||
* Mac: Cleaned up README in general
|
* Mac: Cleaned up README in general
|
||||||
* Added Phoebe textures in medres and lores directories from recent published
|
* Added Phoebe textures in medres and lores directories from recent published
|
||||||
Ciclops cylindrical maps
|
Ciclops cylindrical maps
|
||||||
* Updated Titan and Iapetus textures in lores directory
|
* Updated Titan and Iapetus textures in lores directory
|
||||||
* Windows: save and restore the last used GL render path
|
* Windows: save and restore the last used GL render path
|
||||||
|
@ -959,10 +959,10 @@ Code:
|
||||||
* KDE: Reverted mouse wheel action to be compatible with the other interfaces.
|
* KDE: Reverted mouse wheel action to be compatible with the other interfaces.
|
||||||
* KDE: New configurable splash screen
|
* KDE: New configurable splash screen
|
||||||
(http://celestia.teyssier.org/splash_spec.html)
|
(http://celestia.teyssier.org/splash_spec.html)
|
||||||
* Updated/added Tethys textures in lores, medres and hires directories.
|
* Updated/added Tethys textures in lores, medres and hires directories.
|
||||||
* Added locations on Phoebe in satmoons2.ssc, as extracted from USGS/IAU
|
* Added locations on Phoebe in satmoons2.ssc, as extracted from USGS/IAU
|
||||||
official data.
|
official data.
|
||||||
* Added Mesh for Phoebe texture.
|
* Added Mesh for Phoebe texture.
|
||||||
* Updated Iapetus texture.
|
* Updated Iapetus texture.
|
||||||
* Moved locations files from extras into data directory for inclusion in
|
* Moved locations files from extras into data directory for inclusion in
|
||||||
standard package.
|
standard package.
|
||||||
|
@ -1002,7 +1002,7 @@ Code:
|
||||||
- HIP 14810 c, HD 185269 b, Gliese 849 b
|
- HIP 14810 c, HD 185269 b, Gliese 849 b
|
||||||
- Mu Ara e
|
- Mu Ara e
|
||||||
- Gliese 581 c & d, HD 175541 b, HD 210702 b, HD192699 b
|
- Gliese 581 c & d, HD 175541 b, HD 210702 b, HD192699 b
|
||||||
- HD 47536 c, XO-2 b, HD 147506 (HAT-P-2), HD 17092 b
|
- HD 47536 c, XO-2 b, HD 147506 (HAT-P-2), HD 17092 b
|
||||||
* Revised orbits of many extrasolar planets to reflect new data
|
* Revised orbits of many extrasolar planets to reflect new data
|
||||||
* Added stars for new extrasolar planets: GSC 92941-01657
|
* Added stars for new extrasolar planets: GSC 92941-01657
|
||||||
* Mac: Show menu bar when moving mouse to top of screen in full screen
|
* Mac: Show menu bar when moving mouse to top of screen in full screen
|
||||||
|
@ -1067,7 +1067,7 @@ Code:
|
||||||
* Added cmodsphere, a utility for producing cmod meshes from height samples
|
* Added cmodsphere, a utility for producing cmod meshes from height samples
|
||||||
regularly spaced in longitude and latitude.
|
regularly spaced in longitude and latitude.
|
||||||
* COPYING, controls.txt, start script, and guide can all be localized
|
* COPYING, controls.txt, start script, and guide can all be localized
|
||||||
* cel and celx scripting:
|
* cel and celx scripting:
|
||||||
- added openclusters and cloudshadows render flags
|
- added openclusters and cloudshadows render flags
|
||||||
- added location, nebulae, openclusers, and i18nconsteallations label flags
|
- added location, nebulae, openclusers, and i18nconsteallations label flags
|
||||||
* Established Barycentric Dynamical Time (TDB) as the time scale used
|
* Established Barycentric Dynamical Time (TDB) as the time scale used
|
||||||
|
@ -1090,12 +1090,12 @@ Code:
|
||||||
spectra
|
spectra
|
||||||
* Made star orbit paths visible
|
* Made star orbit paths visible
|
||||||
* galaxies:
|
* galaxies:
|
||||||
-changed galaxy template format to standard (grayscale) PNG
|
-changed galaxy template format to standard (grayscale) PNG
|
||||||
-allow a custom template for each galaxy in deepsky.dsc
|
-allow a custom template for each galaxy in deepsky.dsc
|
||||||
-new approach to thickness of galaxy (arms): assumed proportional to read-in
|
-new approach to thickness of galaxy (arms): assumed proportional to read-in
|
||||||
brightness values
|
brightness values
|
||||||
-emulate dust lanes around galactic plane (y=0)
|
-emulate dust lanes around galactic plane (y=0)
|
||||||
-considerable improvement of Milky Way appearance as seen from Earth
|
-considerable improvement of Milky Way appearance as seen from Earth
|
||||||
-implement galaxy labels of transparency increasing with distance, thus
|
-implement galaxy labels of transparency increasing with distance, thus
|
||||||
providing a neat 3d effect
|
providing a neat 3d effect
|
||||||
* galaxy templates:
|
* galaxy templates:
|
||||||
|
@ -1114,10 +1114,10 @@ Code:
|
||||||
- Guarded against crash when the JPL ephemeris file can't be found
|
- Guarded against crash when the JPL ephemeris file can't be found
|
||||||
* Generalized rotations
|
* Generalized rotations
|
||||||
- Clear syntax for ssc files
|
- Clear syntax for ssc files
|
||||||
- UniformRotation
|
- UniformRotation
|
||||||
- PrecessingOrientation
|
- PrecessingOrientation
|
||||||
- SampledOrientation - interpolated sequence of quaternion key frames
|
- SampledOrientation - interpolated sequence of quaternion key frames
|
||||||
* Scripting improvements
|
* Scripting improvements
|
||||||
- New celx scripting commands:
|
- New celx scripting commands:
|
||||||
- utctotdb and tdbtoutc
|
- utctotdb and tdbtoutc
|
||||||
- gl commands
|
- gl commands
|
||||||
|
@ -1125,7 +1125,7 @@ Code:
|
||||||
- iterators: celestia:stars and celestia:dsos
|
- iterators: celestia:stars and celestia:dsos
|
||||||
- get/setaltazimuthmode
|
- get/setaltazimuthmode
|
||||||
- Lua hooks for script extensions to Celestia
|
- Lua hooks for script extensions to Celestia
|
||||||
- Script interfaces for orbits and rotation models (ScriptedOrbit and
|
- Script interfaces for orbits and rotation models (ScriptedOrbit and
|
||||||
ScriptedRotation)
|
ScriptedRotation)
|
||||||
- Support Lua 5.1 (5.0 compatibility retained)
|
- Support Lua 5.1 (5.0 compatibility retained)
|
||||||
- Made celestia:loadtexture use relative file names
|
- Made celestia:loadtexture use relative file names
|
||||||
|
@ -1148,7 +1148,7 @@ Code:
|
||||||
* Corrected kilometers per light year constant
|
* Corrected kilometers per light year constant
|
||||||
* Added various improvements to the MilkyWay & other galaxy template display.
|
* Added various improvements to the MilkyWay & other galaxy template display.
|
||||||
* Added E0.png galaxy template that allows for better En, n=1..7 elliptical
|
* Added E0.png galaxy template that allows for better En, n=1..7 elliptical
|
||||||
shapes.
|
shapes.
|
||||||
* Fixed sizes of irregular galaxies (factor of 2!).
|
* Fixed sizes of irregular galaxies (factor of 2!).
|
||||||
* Prevented galaxy code from crashing if a template is missing.
|
* Prevented galaxy code from crashing if a template is missing.
|
||||||
* Improved selection of galaxies by taking into account their 3d shape
|
* Improved selection of galaxies by taking into account their 3d shape
|
||||||
|
@ -1163,11 +1163,11 @@ Code:
|
||||||
* Windows: Fixed crash that occurred when star browser was closed
|
* Windows: Fixed crash that occurred when star browser was closed
|
||||||
* Fixed bug that made moons disappear as a planet approached stellar transit
|
* Fixed bug that made moons disappear as a planet approached stellar transit
|
||||||
* Added a major update of the galaxy database such that close to 100% of the
|
* Added a major update of the galaxy database such that close to 100% of the
|
||||||
galaxies now involve distance measurements
|
galaxies now involve distance measurements
|
||||||
* Included the complete local group of galaxies
|
* Included the complete local group of galaxies
|
||||||
* Added varying label transparency also for stars
|
* Added varying label transparency also for stars
|
||||||
* Added the PERL scripts used for extraction of galaxy and binary orbit data
|
* Added the PERL scripts used for extraction of galaxy and binary orbit data
|
||||||
from scientific sources. They both are useful tools and a concise
|
from scientific sources. They both are useful tools and a concise
|
||||||
documentation of Celestia's data
|
documentation of Celestia's data
|
||||||
* updated binary orbit data (visualbins.stc and spectbins.stc) along with
|
* updated binary orbit data (visualbins.stc and spectbins.stc) along with
|
||||||
respective PERL scripts (visualbins.pl and spectbins.pl)
|
respective PERL scripts (visualbins.pl and spectbins.pl)
|
||||||
|
@ -1220,7 +1220,7 @@ Code:
|
||||||
HD 167042 b, HD 74156 d, HD 285968 b, V391 Peg b,
|
HD 167042 b, HD 74156 d, HD 285968 b, V391 Peg b,
|
||||||
HD 132406 b, HD 43691 b, NGC 2423 3 b, Gliese 317 b & c,
|
HD 132406 b, HD 43691 b, NGC 2423 3 b, Gliese 317 b & c,
|
||||||
TrES-3, HD 155358 b&c, HD 5319 b, HD 75898 b, OGLE-TR-182 b, WASP-3 b,
|
TrES-3, HD 155358 b&c, HD 5319 b, HD 75898 b, OGLE-TR-182 b, WASP-3 b,
|
||||||
55 Cnc f, Lupus-TR-3 b, OGLE-TR-211 b, HD 156846 b, HD 4113 b, Kap CrB b,
|
55 Cnc f, Lupus-TR-3 b, OGLE-TR-211 b, HD 156846 b, HD 4113 b, Kap CrB b,
|
||||||
GD 66 b, XO-3 b, WASP-4 b TW Hya b
|
GD 66 b, XO-3 b, WASP-4 b TW Hya b
|
||||||
removed HD 33636 b
|
removed HD 33636 b
|
||||||
* Set up transit of Gliese 436
|
* Set up transit of Gliese 436
|
||||||
|
@ -1383,7 +1383,7 @@ Bug fixes
|
||||||
* Fixed search path for Lua scripts
|
* Fixed search path for Lua scripts
|
||||||
* Fixed numerous bugs that occurred when an object's orbit center was different
|
* Fixed numerous bugs that occurred when an object's orbit center was different
|
||||||
* Fixed a bug in the celx function celestia:getscreendimension
|
* Fixed a bug in the celx function celestia:getscreendimension
|
||||||
* Fixed bug with returning Hubble type for galaxies
|
* Fixed bug with returning Hubble type for galaxies
|
||||||
* Eliminated error-prone min/max macros; use STL functions instead
|
* Eliminated error-prone min/max macros; use STL functions instead
|
||||||
* Fixed discrepancy between apparent magnitudes shown in the 3D view and
|
* Fixed discrepancy between apparent magnitudes shown in the 3D view and
|
||||||
the star browser.
|
the star browser.
|
||||||
|
@ -1424,9 +1424,9 @@ Data file updates
|
||||||
* Changed class of small outer planet moons to minormoon
|
* Changed class of small outer planet moons to minormoon
|
||||||
* Included new and updated solar system body features from the IAU
|
* Included new and updated solar system body features from the IAU
|
||||||
* Added provisional rotation period for Eris
|
* Added provisional rotation period for Eris
|
||||||
|
|
||||||
Tools
|
Tools
|
||||||
* Added Perl script globulars.pl used to extract the globular data from scientific publications and as documentation
|
* Added Perl script globulars.pl used to extract the globular data from scientific publications and as documentation
|
||||||
* Added spice2xyzv tool for extracting xyzv files from a pool of SPICE kernels
|
* Added spice2xyzv tool for extracting xyzv files from a pool of SPICE kernels
|
||||||
* Added Perl script to build cross-indices
|
* Added Perl script to build cross-indices
|
||||||
* Added Perl script to generate CHARM2 catalog
|
* Added Perl script to generate CHARM2 catalog
|
||||||
|
@ -1557,7 +1557,7 @@ Scripting
|
||||||
- windowbordersvisible, setwindowbordersvisible
|
- windowbordersvisible, setwindowbordersvisible
|
||||||
* Split celx scripting support into several modules
|
* Split celx scripting support into several modules
|
||||||
* Cel scripting
|
* Cel scripting
|
||||||
- splitview, deleteview, singleview, setactiveview
|
- splitview, deleteview, singleview, setactiveview
|
||||||
- setgalaxylightgain
|
- setgalaxylightgain
|
||||||
- setradius
|
- setradius
|
||||||
- setlinecolor
|
- setlinecolor
|
||||||
|
|
|
@ -150,7 +150,7 @@ following option to cmake: -DCMAKE_INSTALL_PREFIX=/another/path.
|
||||||
|
|
||||||
## Celestia Install instructions for Windows (MSVC)
|
## Celestia Install instructions for Windows (MSVC)
|
||||||
|
|
||||||
Currently to build on Windows you need a Visual Studio 2015 or later, CMake
|
Currently to build on Windows you need Visual Studio 2015 or later, CMake
|
||||||
and vcpkg (*).
|
and vcpkg (*).
|
||||||
|
|
||||||
Install required packages:
|
Install required packages:
|
||||||
|
@ -170,6 +170,9 @@ for 64-bit versions.
|
||||||
|
|
||||||
Instead of `luajit` `lua` can be used.
|
Instead of `luajit` `lua` can be used.
|
||||||
|
|
||||||
|
Use `vcpkg list` to ensure that all packages have actually been installed.
|
||||||
|
If not, try installing them one at a time.
|
||||||
|
|
||||||
Configure and build 32-bit version:
|
Configure and build 32-bit version:
|
||||||
|
|
||||||
```
|
```
|
||||||
|
@ -188,8 +191,8 @@ cmake -DCMAKE_GENERATOR_PLATFORM=x64 -DCMAKE_TOOLCHAIN_FILE=c:/tools/vcpkg/scrip
|
||||||
cmake --build . -- /maxcpucount:N /nologo
|
cmake --build . -- /maxcpucount:N /nologo
|
||||||
```
|
```
|
||||||
|
|
||||||
Instead of N in /maxcpucount pass a number of CPU cores you want to use during
|
Instead of N in /maxcpucount pass the number of CPU cores you want to use during
|
||||||
a build.
|
the build.
|
||||||
|
|
||||||
This example assumes that `vcpkg` is installed into `c:/tools/vcpkg`. Update
|
This example assumes that `vcpkg` is installed into `c:/tools/vcpkg`. Update
|
||||||
the path to `vcpkg.cmake` according to your installation.
|
the path to `vcpkg.cmake` according to your installation.
|
||||||
|
|
|
@ -0,0 +1,142 @@
|
||||||
|
| **`Release`** | **`Localized`** | **`License`** | **`Contribute`** |
|
||||||
|
|-------------------|---------------|---------------|---------------|
|
||||||
|
|[![GitHub release](https://img.shields.io/github/v/release/CelestiaProject/Celestia?label=Release)](https://celestia.space/download.html) | [![Localization](https://img.shields.io/badge/Localized-85%25-green.svg)](#) | [![License](https://img.shields.io/github/license/CelestiaProject/Celestia?label=License)](https://github.com/CelestiaProject/Celestia/blob/master/COPYING) | [![Contribute](https://img.shields.io/badge/PRs-Welcome-brightgreen.svg)](#contributing) |
|
||||||
|
|
||||||
|
# Celestia
|
||||||
|
![Celestia](celestia-logo.png)<br>
|
||||||
|
**A real-time space simulation that lets you experience our universe in three dimensions.**
|
||||||
|
|
||||||
|
**Copyright © 2001-2021, Celestia Development Team**<br>
|
||||||
|
**Celestia website: https://celestia.space**<br>
|
||||||
|
**Celestia Wikibook: https://en.wikibooks.org/wiki/Celestia**<br>
|
||||||
|
**Celestia forums: https://celestia.space/forum/**<br>
|
||||||
|
**Celestia Subreddit: https://www.reddit.com/r/Celestiasoftware/**<br>
|
||||||
|
**Celestia Archive Repository: https://github.com/Anthony-B-Russo10/Celestia-Archive**
|
||||||
|
## License
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify it under
|
||||||
|
the terms of the GNU General Public License as published by the Free Software Foundation;
|
||||||
|
either version 2 of the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
This program 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 General Public License for more details,
|
||||||
|
which you should have received along with this program (filename: COPYING).
|
||||||
|
If not, request a copy from:<br>
|
||||||
|
Free Software Foundation, Inc.<br>
|
||||||
|
59 Temple Place - Suite 330<br>
|
||||||
|
Boston, MA 02111-1307<br>
|
||||||
|
USA
|
||||||
|
|
||||||
|
## Getting started
|
||||||
|
|
||||||
|
Celestia will start up in a window, and if everything is working correctly,
|
||||||
|
you'll see Earth in front of a field of stars. Displayed on-screen, is some
|
||||||
|
information about your target (Earth), your speed, and the current time
|
||||||
|
(Universal Time, so it'll probably be a few hours off from your computer's
|
||||||
|
clock).
|
||||||
|
|
||||||
|
Right drag the mouse to orbit Earth and you might see the Moon and some
|
||||||
|
familiar constellations. Left dragging the mouse changes your orientation
|
||||||
|
also, but the camera rotates about its center instead of rotating around
|
||||||
|
Earth. Rolling the mouse wheel will change your distance to Earth--you can
|
||||||
|
move light years away, then roll the wheel in the opposite direction to get
|
||||||
|
back to your starting location. If your mouse lacks a wheel, you can use the
|
||||||
|
Home and End keys instead.
|
||||||
|
|
||||||
|
When running Celestia, you will usually have some object selected. Currently,
|
||||||
|
it's Earth, but it could also be a star, moon, spacecraft, galaxy, or some
|
||||||
|
other object. The simplest way to select an object is to click on it. Try
|
||||||
|
clicking on a star to select it. The information about Earth is replaced with
|
||||||
|
some details about the star. Press G (or use the Navigation menu), and you'll
|
||||||
|
zoom through space toward the selected star. If you press G again, you'll
|
||||||
|
approach the star even closer.
|
||||||
|
|
||||||
|
Press H to select our Sun, and then G to go back to our Sun. Right click on
|
||||||
|
the sun to bring up a menu of planets and other objects in the solar system.
|
||||||
|
After selecting a planet from the menu, hit G again to travel toward it. Once
|
||||||
|
there, hold down the right mouse button and drag to orbit the planet.
|
||||||
|
|
||||||
|
The Tour Guide is a list of some of the more interesting objects you can visit
|
||||||
|
in Celestia. Select the Tour Guide option in the Navigation menu to display
|
||||||
|
the Tour Guide window. Choose a destination from the list, click the Goto
|
||||||
|
button, and you're off.
|
||||||
|
|
||||||
|
That covers the very basics. For a more in-depth look at Celestia and the
|
||||||
|
controls available to you, download the "Celestia User's Guide" (written by
|
||||||
|
Frank Gregorio), available in several languages, from:<br>
|
||||||
|
https://celestia.space/guides.html<br>
|
||||||
|
This web page also includes links to the Celestia README file translated into
|
||||||
|
Japanese.
|
||||||
|
|
||||||
|
### Star browser
|
||||||
|
By default, the Star Browser window displays a table of the 100 nearest stars,
|
||||||
|
along with their Distance, Apparent and Absolute Magnitude, and Type. Clicking
|
||||||
|
on the column headers will sort the stars. The table is not continuously
|
||||||
|
updated, so if you travel to another star, you should press the Refresh button
|
||||||
|
to update the table for your current position. The radio buttons beneath the
|
||||||
|
table let you switch between viewing a list of Nearest, Brightest, or 'With
|
||||||
|
planets' stars. As with the solar system browser, clicking on any star name
|
||||||
|
in the table will select it. Use this feature along with the Center and Go
|
||||||
|
To buttons to tour the stars visible from any night sky in the galaxy.
|
||||||
|
|
||||||
|
### Solar system browser
|
||||||
|
The Solar System Browser displays a window with a tree view of all the objects
|
||||||
|
in the nearest solar system (if there is one within a light year of your current
|
||||||
|
position.) Clicking on the name of any object in the window will select it.
|
||||||
|
You can then use the Center or Go To buttons to display that object in the main
|
||||||
|
Celestia window.
|
||||||
|
|
||||||
|
### Selecting objects by name
|
||||||
|
Celestia provides several ways to select an object by name...
|
||||||
|
1. Choose 'Select Object' from the Navigation menu, type in the object name, and click OK.
|
||||||
|
2. Press Enter, type in the entire object name, and press Enter again.
|
||||||
|
3. Press Enter, type in the first few characters of the object name,
|
||||||
|
press the Tab key to move through the displayed listing until the object is highlighted,
|
||||||
|
then press Enter again.
|
||||||
|
|
||||||
|
You can use common names, Bayer designations or catalog numbers for stars.
|
||||||
|
Celestia currently supports the HIP, HD and SAO catalogs. Catalog numbers must
|
||||||
|
be entered with a space between the prefix and the catalog number.
|
||||||
|
|
||||||
|
### Known issues
|
||||||
|
For up-to-the-minute answers to some common problems encountered when running
|
||||||
|
Celestia, please view either the FAQ in the Help menu or take a look at the
|
||||||
|
"Celestia User's FAQ" located on the Celestia User's Forum:
|
||||||
|
https://celestia.space/forum/
|
||||||
|
|
||||||
|
### User modifiable elements
|
||||||
|
You can modify how Celestia starts up each time you run it, by defining your
|
||||||
|
own start-up settings. Simply open the file "start.cel" in a plain text
|
||||||
|
editor and follow the in-file instructions. Also, view the celestia.cfg file
|
||||||
|
in a plain text editor to see additional settings.
|
||||||
|
|
||||||
|
Celestia allows you to easily add real, hypothetical, or fictional objects
|
||||||
|
by creating new catalog files. It is *not* recommended that you alter the
|
||||||
|
built-in data files; nearly all desired modifications and additions can be
|
||||||
|
made by placing new catalog files in Celestia's extras folders. There are three
|
||||||
|
types of catalog files:
|
||||||
|
* ssc (solar system catalog: planets, moons, spacecraft, etc.)
|
||||||
|
* stc (star catalog)
|
||||||
|
* dsc (deep sky catalog: galaxies, star clusters, and nebulae)
|
||||||
|
|
||||||
|
All three types of catalog file are text files that can be updated with your
|
||||||
|
favorite text editing program.
|
||||||
|
|
||||||
|
### Building from sources
|
||||||
|
See instructions in file [INSTALL.md](INSTALL.md).
|
||||||
|
|
||||||
|
## Contributions
|
||||||
|
| **`Authors`** | **`Contributors`** | **`Documentation`** | **`Other`** |
|
||||||
|
|-----------------|---------------------|------------------|-------------------|
|
||||||
|
| Chris Laurel, Clint Weisbrod, Fridger Schrempp, Bob Ippolito, Christophe Teyssier, Hank Ramsey, Grant Hutchison, Pat Suwalski, Toti, Da Woon Jung, Vincent Giangiulio, Andrew Tribick, Hleb Valoshka, Łukasz Buczyński, Li Linfeng | Deon Ramsey, Christopher Andre, Colin Walters, Peter Chapman, James Holmes, Harald Schmidt, Nils Larsson, Sergey Leonov, Alexell, Dmitry Brant, Janus | Selden Ball, Frank Gregorio, Hitoshi Suzuki, Christophe Teyssier, Diego Rodriguez, Don Goyette, Harald Schmidt | Creators of scientific database, texture maps, 3D models and used libraries, you can see in full README.|
|
||||||
|
|
||||||
|
### Contributing
|
||||||
|
|
||||||
|
**We welcome feedback, bug reports, and pull requests!**
|
||||||
|
|
||||||
|
For pull requests, please stick to the following guidelines:
|
||||||
|
* Be sure to test your code changes.
|
||||||
|
* Follow the existing code style (e.g., indents).
|
||||||
|
* Put a lot of comments into the code, if necessary.
|
||||||
|
* Separate unrelated changes into multiple pull requests.
|
207
README.md
207
README.md
|
@ -1,143 +1,110 @@
|
||||||
| **`Release`** | **`Localized`** | **`License`** | **`Contribute`** |
|
|
||||||
|-------------------|---------------|---------------|---------------|
|
|
||||||
|[![GitHub release](https://img.shields.io/github/v/release/CelestiaProject/Celestia?label=Release)](https://celestia.space/download.html) | [![Localization](https://img.shields.io/badge/Localized-85%25-green.svg)](#) | [![License](https://img.shields.io/github/license/CelestiaProject/Celestia?label=License)](https://github.com/CelestiaProject/Celestia/blob/master/COPYING) | [![Contribute](https://img.shields.io/badge/PRs-Welcome-brightgreen.svg)](#contributing) |
|
|
||||||
|
|
||||||
# Celestia
|
# Celestia
|
||||||
![Celestia](celestia-logo.png)<br>
|
Celestia is a "real-time space simulation that lets you experience
|
||||||
**A real-time space simulation that lets you experience our universe in three dimensions.**
|
our universe in three dimensions".
|
||||||
|
|
||||||
**Copyright © 2001-2021, Celestia Development Team**<br>
|
![celestia-screenshot](pics/celestia-screenshot.png)
|
||||||
**Celestia website: https://celestia.space**<br>
|
|
||||||
**Celestia Wikibook: https://en.wikibooks.org/wiki/Celestia**<br>
|
|
||||||
**Celestia forums: https://celestia.space/forum/**<br>
|
|
||||||
**Celestia Discord Server: https://discordapp.com/invite/WEWDcJh**<br>
|
|
||||||
**Celestia Subreddit: https://www.reddit.com/r/Celestiasoftware/**<br>
|
|
||||||
**Celestia Archive Repository: https://github.com/Anthony-B-Russo10/Celestia-Archive**
|
|
||||||
## License
|
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify it under
|
# Upstream
|
||||||
the terms of the GNU General Public License as published by the Free Software Foundation;
|
This repo is a lesser fork of the upstream project,
|
||||||
either version 2 of the License, or (at your option) any later version.
|
which has been revived.
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful, but WITHOUT
|
* https://celestia.space/
|
||||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
|
||||||
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details,
|
|
||||||
which you should have received along with this program (filename: COPYING).
|
|
||||||
If not, request a copy from:<br>
|
|
||||||
Free Software Foundation, Inc.<br>
|
|
||||||
59 Temple Place - Suite 330<br>
|
|
||||||
Boston, MA 02111-1307<br>
|
|
||||||
USA
|
|
||||||
|
|
||||||
## Getting started
|
* https://github.com/CelestiaProject/Celestia
|
||||||
|
|
||||||
Celestia will start up in a window, and if everything is working correctly,
|
See also: `README-upstream`, `README-upstream.md`.
|
||||||
you'll see Earth in front of a field of stars. Displayed on-screen, is some
|
|
||||||
information about your target (Earth), your speed, and the current time
|
|
||||||
(Universal Time, so it'll probably be a few hours off from your computer's
|
|
||||||
clock).
|
|
||||||
|
|
||||||
Right drag the mouse to orbit Earth and you might see the Moon and some
|
## License/Copyright
|
||||||
familiar constellations. Left dragging the mouse changes your orientation
|
GPLv2+
|
||||||
also, but the camera rotates about its center instead of rotating around
|
|
||||||
Earth. Rolling the mouse wheel will change your distance to Earth--you can
|
|
||||||
move light years away, then roll the wheel in the opposite direction to get
|
|
||||||
back to your starting location. If your mouse lacks a wheel, you can use the
|
|
||||||
Home and End keys instead.
|
|
||||||
|
|
||||||
When running Celestia, you will usually have some object selected. Currently,
|
Copyright © 2001-2021, Celestia Development Team
|
||||||
it's Earth, but it could also be a star, moon, spacecraft, galaxy, or some
|
|
||||||
other object. The simplest way to select an object is to click on it. Try
|
|
||||||
clicking on a star to select it. The information about Earth is replaced with
|
|
||||||
some details about the star. Press G (or use the Navigation menu), and you'll
|
|
||||||
zoom through space toward the selected star. If you press G again, you'll
|
|
||||||
approach the star even closer.
|
|
||||||
|
|
||||||
Press H to select our Sun, and then G to go back to our Sun. Right click on
|
# Debian
|
||||||
the sun to bring up a menu of planets and other objects in the solar system.
|
Package was removed from Debian in the ancient days due to bitrot.
|
||||||
After selecting a planet from the menu, hit G again to travel toward it. Once
|
The upstream code has a new team and active development, using
|
||||||
there, hold down the right mouse button and drag to orbit the planet.
|
recent libraries. The package can be built under Debian Ok, except
|
||||||
|
for the `data/` files.
|
||||||
|
|
||||||
The Tour Guide is a list of some of the more interesting objects you can visit
|
Debian upstream bug:
|
||||||
in Celestia. Select the Tour Guide option in the Navigation menu to display
|
|
||||||
the Tour Guide window. Choose a destination from the list, click the Goto
|
|
||||||
button, and you're off.
|
|
||||||
|
|
||||||
That covers the very basics. For a more in-depth look at Celestia and the
|
* https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=809916
|
||||||
controls available to you, download the "Celestia User's Guide" (written by
|
|
||||||
Frank Gregorio), available in several languages, from:<br>
|
|
||||||
https://celestia.space/guides.html<br>
|
|
||||||
This web page also includes links to the Celestia README file translated into
|
|
||||||
Japanese.
|
|
||||||
|
|
||||||
### Star browser
|
```
|
||||||
By default, the Star Browser window displays a table of the 100 nearest stars,
|
Upstream has not produced any new releases in the last 4 years. In the
|
||||||
along with their Distance, Apparent and Absolute Magnitude, and Type. Clicking
|
mean time, the package is accumulating bugs due to bitrot. It already
|
||||||
on the column headers will sort the stars. The table is not continuously
|
wasn't a trouble-free package, due to some quite important resources not
|
||||||
updated, so if you travel to another star, you should press the Refresh button
|
being DFSG compliant.
|
||||||
to update the table for your current position. The radio buttons beneath the
|
```
|
||||||
table let you switch between viewing a list of Nearest, Brightest, or 'With
|
|
||||||
planets' stars. As with the solar system browser, clicking on any star name
|
|
||||||
in the table will select it. Use this feature along with the Center and Go
|
|
||||||
To buttons to tour the stars visible from any night sky in the galaxy.
|
|
||||||
|
|
||||||
### Solar system browser
|
I do see some of the resources now are CC-by-SA 4.0, a license which
|
||||||
The Solar System Browser displays a window with a tree view of all the objects
|
didn't exist when the Debian bug was created. So it may be that it
|
||||||
in the nearest solar system (if there is one within a light year of your current
|
can be built happily without DFSG issues using new data files.
|
||||||
position.) Clicking on the name of any object in the window will select it.
|
|
||||||
You can then use the Center or Go To buttons to display that object in the main
|
|
||||||
Celestia window.
|
|
||||||
|
|
||||||
### Selecting objects by name
|
|
||||||
Celestia provides several ways to select an object by name...
|
|
||||||
1. Choose 'Select Object' from the Navigation menu, type in the object name, and click OK.
|
|
||||||
2. Press Enter, type in the entire object name, and press Enter again.
|
|
||||||
3. Press Enter, type in the first few characters of the object name,
|
|
||||||
press the Tab key to move through the displayed listing until the object is highlighted,
|
|
||||||
then press Enter again.
|
|
||||||
|
|
||||||
You can use common names, Bayer designations or catalog numbers for stars.
|
|
||||||
Celestia currently supports the HIP, HD and SAO catalogs. Catalog numbers must
|
|
||||||
be entered with a space between the prefix and the catalog number.
|
|
||||||
|
|
||||||
### Known issues
|
Celestia depending on NASA's Spice/NAIF may be afoul of Debian's
|
||||||
For up-to-the-minute answers to some common problems encountered when running
|
DFSG because the terms are unique. It isn't really a standard license.
|
||||||
Celestia, please view either the FAQ in the Help menu or take a look at the
|
|
||||||
"Celestia User's FAQ" located on the Celestia User's Forum:
|
|
||||||
https://celestia.space/forum/
|
|
||||||
|
|
||||||
### User modifiable elements
|
|
||||||
You can modify how Celestia starts up each time you run it, by defining your
|
|
||||||
own start-up settings. Simply open the file "start.cel" in a plain text
|
|
||||||
editor and follow the in-file instructions. Also, view the celestia.cfg file
|
|
||||||
in a plain text editor to see additional settings.
|
|
||||||
|
|
||||||
Celestia allows you to easily add real, hypothetical, or fictional objects
|
Debian tracker link:
|
||||||
by creating new catalog files. It is *not* recommended that you alter the
|
|
||||||
built-in data files; nearly all desired modifications and additions can be
|
|
||||||
made by placing new catalog files in Celestia's extras folders. There are three
|
|
||||||
types of catalog files:
|
|
||||||
* ssc (solar system catalog: planets, moons, spacecraft, etc.)
|
|
||||||
* stc (star catalog)
|
|
||||||
* dsc (deep sky catalog: galaxies, star clusters, and nebulae)
|
|
||||||
|
|
||||||
All three types of catalog file are text files that can be updated with your
|
* https://tracker.debian.org/pkg/celestia
|
||||||
favorite text editing program.
|
|
||||||
|
|
||||||
### Building from sources
|
# Build
|
||||||
See instructions in file [INSTALL.md](INSTALL.md).
|
Mini Debian package build howto.
|
||||||
|
|
||||||
## Contributions
|
```
|
||||||
| **`Authors`** | **`Contributors`** | **`Documentation`** | **`Other`** |
|
# Install deps
|
||||||
|-----------------|---------------------|------------------|-------------------|
|
sudo apt update
|
||||||
| Chris Laurel, Clint Weisbrod, Fridger Schrempp, Bob Ippolito, Christophe Teyssier, Hank Ramsey, Grant Hutchison, Pat Suwalski, Toti, Da Woon Jung, Vincent Giangiulio, Andrew Tribick, Hleb Valoshka, Łukasz Buczyński, Li Linfeng | Deon Ramsey, Christopher Andre, Colin Walters, Peter Chapman, James Holmes, Harald Schmidt, Nils Larsson, Sergey Leonov, Alexell, Dmitry Brant, Janus | Selden Ball, Frank Gregorio, Hitoshi Suzuki, Christophe Teyssier, Diego Rodriguez, Don Goyette, Harald Schmidt | Creators of scientific database, texture maps, 3D models and used libraries, you can see in full README.|
|
sudo apt install build-essential ccache devscripts \
|
||||||
|
debhelper chrpath cmake freeglut3-dev libeigen3-dev libfmt-dev \
|
||||||
|
libfreetype6-dev libepoxy-dev libglu1-mesa-dev libgtk2.0-dev \
|
||||||
|
libgtkglext1-dev libjpeg62-turbo-dev libluajit-5.1-dev libpng-dev \
|
||||||
|
libqt5opengl5-dev libtheora-dev qtbase5-dev qtbase5-dev-tools
|
||||||
|
|
||||||
### Contributing
|
# Add ccache to PATH in ~/.bashrc, and log back in
|
||||||
|
PATH=/usr/lib/ccache:$PATH
|
||||||
|
|
||||||
**We welcome feedback, bug reports, and pull requests!**
|
# Make dirs to put it all, as it writes packages to the *parent* dir.
|
||||||
|
mkdir celestia-deb
|
||||||
|
cd celestia-deb
|
||||||
|
|
||||||
|
git clone https://spacecruft.org/spacecruft/CelestiaContent
|
||||||
|
cd CelestiaContent
|
||||||
|
|
||||||
|
# Build the source package, writes to parent dir
|
||||||
|
dpkg-buildpackage -rfakeroot -S -uc -us -sa
|
||||||
|
|
||||||
|
# Build Debian Packages
|
||||||
|
dpkg-buildpackage -rfakeroot -b -uc
|
||||||
|
|
||||||
|
cd ..
|
||||||
|
|
||||||
|
# Install the data package
|
||||||
|
sudo dpkg -i celestia-data_1.7.0~git20211202+668347e9+0_all.deb
|
||||||
|
|
||||||
|
# Make sure apt is happy
|
||||||
|
sudo apt -f install
|
||||||
|
|
||||||
|
git clone --recursive https://spacecruft.org/spacecruft/celestia
|
||||||
|
cd celestia
|
||||||
|
|
||||||
|
# Build the source package, writes to parent dir
|
||||||
|
dpkg-buildpackage -rfakeroot -S -uc -us -sa
|
||||||
|
|
||||||
|
# Build Debian Packages
|
||||||
|
dpkg-buildpackage -rfakeroot -b -uc
|
||||||
|
|
||||||
|
cd ..
|
||||||
|
|
||||||
|
# Install
|
||||||
|
sudo dpkg -i celestia_1.7.0~git20220520+1_all.deb \
|
||||||
|
celestia-common_1.7.0~git20220520+1_all.deb \
|
||||||
|
celestia-qt_1.7.0~git20220520+1_amd64.deb \
|
||||||
|
celestia-tools_1.7.0~git20220520+1_amd64.deb \
|
||||||
|
libcelestia1.7_1.7.0~git20220520+1_amd64.deb
|
||||||
|
|
||||||
|
# Make sure apt is happy
|
||||||
|
sudo apt -f install
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
For pull requests, please stick to the following guidelines:
|
|
||||||
* Be sure to test your code changes.
|
|
||||||
* Follow the existing code style (e.g., indents).
|
|
||||||
* Put a lot of comments into the code, if necessary.
|
|
||||||
* Separate unrelated changes into multiple pull requests.
|
|
||||||
|
|
|
@ -227,16 +227,17 @@ StarTextures
|
||||||
# text on the display screen. To view the list of fonts available with
|
# text on the display screen. To view the list of fonts available with
|
||||||
# your distribution of Celestia, look in the fonts directory located
|
# your distribution of Celestia, look in the fonts directory located
|
||||||
# under the Celestia root directory. The default fonts are UTF-8
|
# under the Celestia root directory. The default fonts are UTF-8
|
||||||
# compatible in order to display non-English characters.
|
# compatible in order to display non-English characters. Font size is
|
||||||
|
# measured in points to ensure the same sizes on all DPI configurations.
|
||||||
#
|
#
|
||||||
# Font: Used to display all informational text.
|
# Font: Used to display all informational text.
|
||||||
# Default: "sans12.txf"
|
# Default: "DejaVuSans.ttf,9"
|
||||||
#
|
#
|
||||||
# LabelFont: Used to display all label text (objects, locations, etc.).
|
# LabelFont: Used to display all label text (objects, locations, etc.).
|
||||||
# Default "sans12.txf"
|
# Default "DejaVuSans.ttf,9"
|
||||||
#
|
#
|
||||||
# TitleFont: Used to display object names, messages, and script text.
|
# TitleFont: Used to display object names, messages, and script text.
|
||||||
# Default "sansbold20.txf"
|
# Default "DejaVuSans-Bold.ttf,15"
|
||||||
#------------------------------------------------------------------------
|
#------------------------------------------------------------------------
|
||||||
Font "DejaVuSans.ttf,9"
|
Font "DejaVuSans.ttf,9"
|
||||||
LabelFont "DejaVuSans.ttf,9"
|
LabelFont "DejaVuSans.ttf,9"
|
||||||
|
|
|
@ -212,6 +212,7 @@ Source: "locale\controls_zh_CN.txt"; DestDir: "{app}/locale"; Flags: ignor
|
||||||
Source: "locale\controls_zh_TW.txt"; DestDir: "{app}/locale"; Flags: ignoreversion
|
Source: "locale\controls_zh_TW.txt"; DestDir: "{app}/locale"; Flags: ignoreversion
|
||||||
|
|
||||||
Source: "locale\demo_be.cel"; DestDir: "{app}/locale"; Flags: ignoreversion
|
Source: "locale\demo_be.cel"; DestDir: "{app}/locale"; Flags: ignoreversion
|
||||||
|
Source: "locale\demo_bg.cel"; DestDir: "{app}/locale"; Flags: ignoreversion
|
||||||
Source: "locale\demo_de.cel"; DestDir: "{app}/locale"; Flags: ignoreversion
|
Source: "locale\demo_de.cel"; DestDir: "{app}/locale"; Flags: ignoreversion
|
||||||
Source: "locale\demo_es.cel"; DestDir: "{app}/locale"; Flags: ignoreversion
|
Source: "locale\demo_es.cel"; DestDir: "{app}/locale"; Flags: ignoreversion
|
||||||
Source: "locale\demo_fr.cel"; DestDir: "{app}/locale"; Flags: ignoreversion
|
Source: "locale\demo_fr.cel"; DestDir: "{app}/locale"; Flags: ignoreversion
|
||||||
|
|
|
@ -3,4 +3,5 @@
|
||||||
#cmakedefine HAVE_FLOAT_CHARCONV
|
#cmakedefine HAVE_FLOAT_CHARCONV
|
||||||
#cmakedefine HAVE_STD_FILESYSTEM
|
#cmakedefine HAVE_STD_FILESYSTEM
|
||||||
#cmakedefine HAVE_WORDEXP
|
#cmakedefine HAVE_WORDEXP
|
||||||
|
#cmakedefine HAVE_MESHOPTIMIZER
|
||||||
#cmakedefine WORDS_BIGENDIAN
|
#cmakedefine WORDS_BIGENDIAN
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
README
|
README.md
|
||||||
|
README-upstream
|
||||||
|
README-upstream.md
|
||||||
AUTHORS
|
AUTHORS
|
||||||
TRANSLATORS
|
TRANSLATORS
|
||||||
|
|
|
@ -12,7 +12,7 @@ usr/bin/3dstocmod
|
||||||
usr/bin/cmodfix
|
usr/bin/cmodfix
|
||||||
usr/bin/txt2cmod
|
usr/bin/txt2cmod
|
||||||
usr/bin/cmodsphere
|
usr/bin/cmodsphere
|
||||||
usr/bin/qttxf
|
#usr/bin/qttxf
|
||||||
#usr/bin/spice2xyzv
|
#usr/bin/spice2xyzv
|
||||||
usr/bin/vsoptrunc-rect
|
usr/bin/vsoptrunc-rect
|
||||||
usr/bin/vsoptrunc-sph
|
usr/bin/vsoptrunc-sph
|
||||||
|
|
|
@ -1,3 +1,16 @@
|
||||||
|
celestia (1.7.0~git20220520+1) UNRELEASED; urgency=medium
|
||||||
|
|
||||||
|
* Fix control character ^M in perl scripts.
|
||||||
|
|
||||||
|
-- Jeff Moe <moe@spacecruft.org> Fri, 20 May 2022 21:02:00 -0600
|
||||||
|
|
||||||
|
celestia (1.7.0~git20220520+0) UNRELEASED; urgency=medium
|
||||||
|
|
||||||
|
* New snapshot build.
|
||||||
|
* Remove missing qttxf.
|
||||||
|
|
||||||
|
-- Jeff Moe <moe@spacecruft.org> Fri, 20 May 2022 19:55:59 -0600
|
||||||
|
|
||||||
celestia (1.7.0~git20190807+d9746691+0) UNRELEASED; urgency=medium
|
celestia (1.7.0~git20190807+d9746691+0) UNRELEASED; urgency=medium
|
||||||
|
|
||||||
* New snapshot build
|
* New snapshot build
|
||||||
|
|
|
@ -5,6 +5,7 @@ Maintainer: Hleb Valoshka <375gnu@gmail.com>
|
||||||
Build-Depends: debhelper (>= 10~),
|
Build-Depends: debhelper (>= 10~),
|
||||||
chrpath,
|
chrpath,
|
||||||
cmake (>= 3.1~),
|
cmake (>= 3.1~),
|
||||||
|
dos2unix,
|
||||||
freeglut3-dev,
|
freeglut3-dev,
|
||||||
libeigen3-dev (>= 3.3~),
|
libeigen3-dev (>= 3.3~),
|
||||||
libfmt-dev (>= 4),
|
libfmt-dev (>= 4),
|
||||||
|
|
|
@ -26,6 +26,8 @@ override_dh_auto_configure:
|
||||||
|
|
||||||
|
|
||||||
override_dh_install:
|
override_dh_install:
|
||||||
|
dos2unix ./src/tools/stardb/buildstardb.pl
|
||||||
|
dos2unix ./src/tools/xindex/buildxindices.pl
|
||||||
find debian/tmp/usr/bin/ -type f ! -name *.pl -exec chrpath --delete {} ';'
|
find debian/tmp/usr/bin/ -type f ! -name *.pl -exec chrpath --delete {} ';'
|
||||||
chrpath --delete debian/tmp/usr/lib/*/libcelestia.so.*
|
chrpath --delete debian/tmp/usr/lib/*/libcelestia.so.*
|
||||||
dh_install --fail-missing
|
dh_install --fail-missing
|
||||||
|
|
|
@ -3,10 +3,10 @@
|
||||||
labels { clear "planets|minorplanets|stars|constellations" }
|
labels { clear "planets|minorplanets|stars|constellations" }
|
||||||
renderflags { set "stars|planets"
|
renderflags { set "stars|planets"
|
||||||
clear "constellations|orbits|cloudmaps" }
|
clear "constellations|orbits|cloudmaps" }
|
||||||
print { text "Начало на демонстрацията . . .\nНатиснете ESC за край." origin "center" duration 2 }
|
print { text "Начало на демонстрацията...\nНатиснете „Esc“ за край." origin "center" duration 2 }
|
||||||
wait { duration 2.0 }
|
wait { duration 2.0 }
|
||||||
|
|
||||||
print { text "Нека да започнем от нашия дом . . ." row -3 }
|
print { text "Нека да започнем от нашия дом..." row -3 }
|
||||||
select { object "Sol/Earth" }
|
select { object "Sol/Earth" }
|
||||||
cancel {}
|
cancel {}
|
||||||
# goto { time 0 distance 3 upframe "ecliptical" }
|
# goto { time 0 distance 3 upframe "ecliptical" }
|
||||||
|
@ -18,25 +18,25 @@
|
||||||
wait { duration 1.0 }
|
wait { duration 1.0 }
|
||||||
follow {}
|
follow {}
|
||||||
|
|
||||||
print { text "В момента се намираме на 12 500 км над Земята" row -3 duration 5 }
|
print { text "В момента се намираме на 12 500 км. над Земята." row -3 duration 5 }
|
||||||
orbit { axis [ 0 1 0 ] rate 30 duration 10 }
|
orbit { axis [ 0 1 0 ] rate 30 duration 10 }
|
||||||
print { text "Като добавим и облаците, Земята изглежда по позната." row -3}
|
print { text "Като добавим и облаците, Земята изглежда по-позната." row -3}
|
||||||
wait { duration 0.1 }
|
wait { duration 0.1 }
|
||||||
renderflags { set "cloudmaps" }
|
renderflags { set "cloudmaps" }
|
||||||
orbit { axis [ 0 1 0 ] rate 30 duration 6 }
|
orbit { axis [ 0 1 0 ] rate 30 duration 6 }
|
||||||
|
|
||||||
print { text "Следваща спирка: Луната." row -3 }
|
print { text "Следваща спирка: Луната" row -3 }
|
||||||
select { object "Moon" }
|
select { object "Moon" }
|
||||||
goto { time 5 distance 4 upframe "equatorial" }
|
goto { time 5 distance 4 upframe "equatorial" }
|
||||||
wait { duration 5.5 }
|
wait { duration 5.5 }
|
||||||
print { text "Оглеждайте се за Земята и Слънцето, докато се движим около Луната" row -3}
|
print { text "Оглеждайте се за Земята и Слънцето, докато обикаляме около Луната." row -3}
|
||||||
orbit { axis [ 0 1 0 ] rate 30 duration 10 }
|
orbit { axis [ 0 1 0 ] rate 30 duration 10 }
|
||||||
|
|
||||||
print { text "Напред към Слънцето." row -3}
|
print { text "Напред към Слънцето!" row -3}
|
||||||
select { object "Sol" }
|
select { object "Sol" }
|
||||||
goto { time 8 distance 12 upframe "equatorial" up [ 0 1 0 ] }
|
goto { time 8 distance 12 upframe "equatorial" up [ 0 1 0 ] }
|
||||||
wait { duration 8.5 }
|
wait { duration 8.5 }
|
||||||
print { text "От това разстояние могат да се видят тъмните слънчеви петна по повърхността му." row -3}
|
print { text "От това разстояние може да видим тъмните слънчеви петна по повърхността му." row -3}
|
||||||
orbit { axis [ 0 1 0 ] rate 20 duration 10 }
|
orbit { axis [ 0 1 0 ] rate 20 duration 10 }
|
||||||
|
|
||||||
print { text "Нека да се отдалечим и разгледаме вътрешната част на Слънчевата система." row -3}
|
print { text "Нека да се отдалечим и разгледаме вътрешната част на Слънчевата система." row -3}
|
||||||
|
@ -44,10 +44,10 @@
|
||||||
renderflags { set "orbits" }
|
renderflags { set "orbits" }
|
||||||
changedistance { duration 4.0 rate 1.0 }
|
changedistance { duration 4.0 rate 1.0 }
|
||||||
|
|
||||||
print { text "Да включим имената на планетите . . ." row -3}
|
print { text "Да включим имената на планетите..." row -3}
|
||||||
labels { set "planets" }
|
labels { set "planets" }
|
||||||
wait { duration 1.0 }
|
wait { duration 1.0 }
|
||||||
print { text "Можем да ускорим времето за да видим как планетите обикалят около Слънцето." row -3}
|
print { text "Може да ускорим времето за да видим как планетите обикалят около Слънцето." row -3}
|
||||||
timerate { rate 2592000 }
|
timerate { rate 2592000 }
|
||||||
wait { duration 3.0 }
|
wait { duration 3.0 }
|
||||||
print { text "Всяка секунда в реално време е равна на един месец в симулацията." row -3}
|
print { text "Всяка секунда в реално време е равна на един месец в симулацията." row -3}
|
||||||
|
@ -56,7 +56,7 @@
|
||||||
print { text "В момента, времето е спряно." row -3}
|
print { text "В момента, времето е спряно." row -3}
|
||||||
|
|
||||||
wait { duration 1.0 }
|
wait { duration 1.0 }
|
||||||
print { text "Следващата ни дестинация е Сатурн." row -3}
|
print { text "Следваща спирка: Сатурн" row -3}
|
||||||
select { object "Saturn" }
|
select { object "Saturn" }
|
||||||
center { time 2 }
|
center { time 2 }
|
||||||
wait { duration 2 }
|
wait { duration 2 }
|
||||||
|
@ -64,12 +64,12 @@
|
||||||
wait { duration 6.5 }
|
wait { duration 6.5 }
|
||||||
renderflags { clear "orbits" }
|
renderflags { clear "orbits" }
|
||||||
labels { clear "planets" }
|
labels { clear "planets" }
|
||||||
print { text "Няколко от луните на Сатурн са видими като ярки точки" row -3 duration 3}
|
print { text "Няколко от спътниците на Сатурн са видими като ярки точки." row -3 duration 3}
|
||||||
orbit { axis [ 0 1 0 ] rate 30 duration 12 }
|
orbit { axis [ 0 1 0 ] rate 30 duration 12 }
|
||||||
|
|
||||||
select { object "Mimas" }
|
select { object "Mimas" }
|
||||||
goto { time 5 distance 4 upframe "equatorial" }
|
goto { time 5 distance 4 upframe "equatorial" }
|
||||||
print { text "Най-интересната характеристика на Мимас е огромния кратер Хершел." row -3 duration 9 }
|
print { text "Най-интересната характеристика на Мимас е огромният кратер Хершел." row -3 duration 9 }
|
||||||
orbit { axis [ 0 1 0 ] rate 30 duration 12 }
|
orbit { axis [ 0 1 0 ] rate 30 duration 12 }
|
||||||
changedistance { duration 6.0 rate 0.5 }
|
changedistance { duration 6.0 rate 0.5 }
|
||||||
|
|
||||||
|
@ -82,22 +82,22 @@
|
||||||
wait { duration 2 }
|
wait { duration 2 }
|
||||||
select { object "Alpha UMa" }
|
select { object "Alpha UMa" }
|
||||||
center { time 2 }
|
center { time 2 }
|
||||||
print { text "Ако живеете в северното полукълбо, ще разпознаете Колата в съзвездието Голямата мечка." row -3 duration 3 }
|
print { text "Ако живеете в северното полукълбо, ще разпознаете Волската кола в съзвездието Голямата мечка." row -3 duration 3 }
|
||||||
wait { duration 4 }
|
wait { duration 4 }
|
||||||
|
|
||||||
select { object "Polaris" }
|
select { object "Polaris" }
|
||||||
center { time 2 }
|
center { time 2 }
|
||||||
wait { duration 2 }
|
wait { duration 2 }
|
||||||
print { text "А това е Поларис, известна още като Северната звезда." row -3}
|
print { text "Това е Поларис, известна още като Северната звезда." row -3}
|
||||||
wait { duration 1 }
|
wait { duration 1 }
|
||||||
labels { set "stars" }
|
labels { set "stars" }
|
||||||
wait { duration 2 }
|
wait { duration 2 }
|
||||||
print { text "Поларис е част от Малката мечка." row -3}
|
print { text "Поларис е част от Малката мечка." row -3}
|
||||||
wait { duration 2 }
|
wait { duration 2 }
|
||||||
print { text "За по-добра ориентация в небето, Celestia може да активира диаграмите на съзвездията . . ." row -3}
|
print { text "За по-добра ориентация в небето, „Celestia“ може да активира очертанията на съзвездията..." row -3}
|
||||||
renderflags { set "constellations" }
|
renderflags { set "constellations" }
|
||||||
wait { duration 2 }
|
wait { duration 2 }
|
||||||
print { text ". . . и имената на съзвездията" row -3}
|
print { text "...и имената на съзвездията." row -3}
|
||||||
labels { set "constellations" }
|
labels { set "constellations" }
|
||||||
wait { duration 2 }
|
wait { duration 2 }
|
||||||
|
|
||||||
|
@ -114,7 +114,7 @@
|
||||||
wait { duration 4 }
|
wait { duration 4 }
|
||||||
|
|
||||||
rotate { axis [ 0.707 0.707 0 ] rate 20 duration 7 }
|
rotate { axis [ 0.707 0.707 0 ] rate 20 duration 7 }
|
||||||
print { text "Нека да включим рендерирането на галактиките за да видим Млечния път" row -3 duration 4 }
|
print { text "Нека да включим показването на галактиките за да видим Млечния път." row -3 duration 4 }
|
||||||
renderflags { set "galaxies" }
|
renderflags { set "galaxies" }
|
||||||
rotate { axis [ 0.707 0.707 0 ] rate 20 duration 14 }
|
rotate { axis [ 0.707 0.707 0 ] rate 20 duration 14 }
|
||||||
rotate { axis [ 0.707 0.707 0 ] rate 20 duration 10 }
|
rotate { axis [ 0.707 0.707 0 ] rate 20 duration 10 }
|
||||||
|
@ -122,7 +122,7 @@
|
||||||
select { object "Antares" }
|
select { object "Antares" }
|
||||||
center { time 5 }
|
center { time 5 }
|
||||||
wait { duration 3 }
|
wait { duration 3 }
|
||||||
print { text "Сега ще пътуваме до Антарес, това е звезда червен гигант в съзвездието Скорпион." row -3 duration 5 }
|
print { text "Сега ще посетим Антарес, това е звезда червен гигант в съзвездието Скорпион." row -3 duration 5 }
|
||||||
wait { duration 2 }
|
wait { duration 2 }
|
||||||
renderflags { clear "constellations" }
|
renderflags { clear "constellations" }
|
||||||
labels { clear "constellations|stars" }
|
labels { clear "constellations|stars" }
|
||||||
|
@ -134,13 +134,13 @@
|
||||||
print { text "Въпреки че сме 10 пъти по-далече от Антарес\nотколкото Земята е от Слънцето, масивната звезда червен гигант изглежда застрашително голяма." row -3}
|
print { text "Въпреки че сме 10 пъти по-далече от Антарес\nотколкото Земята е от Слънцето, масивната звезда червен гигант изглежда застрашително голяма." row -3}
|
||||||
wait { duration 4.0 }
|
wait { duration 4.0 }
|
||||||
|
|
||||||
print { text "Нека да се отдалечим за да видим как изглежда нашата галактика . . ." row -3}
|
print { text "Нека да се отдалечим за да видим как изглежда нашата галактика..." row -3}
|
||||||
changedistance { duration 10.0 rate 2.0 }
|
changedistance { duration 10.0 rate 2.0 }
|
||||||
|
|
||||||
select { object "Milky Way" }
|
select { object "Milky Way" }
|
||||||
print { text "Това е Млечния път." row -3 duration 6 }
|
print { text "Това е Млечният път." row -3 duration 6 }
|
||||||
orbit { axis [ 1 0 0 ] rate 30 duration 16.0 }
|
orbit { axis [ 1 0 0 ] rate 30 duration 16.0 }
|
||||||
print { text "Време е да се прибираме . . ." row -3}
|
print { text "Време е да се прибираме..." row -3}
|
||||||
|
|
||||||
select { object "Sol/Earth" }
|
select { object "Sol/Earth" }
|
||||||
goto { time 20 distance 10 upframe "equatorial" }
|
goto { time 20 distance 10 upframe "equatorial" }
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
{
|
{
|
||||||
Name "Юпитер"
|
Name "Юпитер"
|
||||||
Target "Sol/Jupiter"
|
Target "Sol/Jupiter"
|
||||||
Description "Юпитер е най-голямата планета в Слънчевата система и е на пета позиция от Слънцето. Както и останалите външни планети, Юпитер е газов гигант без твърда повърхност. Голямото червено петно е най-голямата и най-продължителната буря в турболентната атмосфера на планетата; тази вихрушка с размерите на Земята съществува от около 300 години."
|
Description "Юпитер е най-голямата планета в Слънчевата система и е на пета позиция от Слънцето. Както и останалите външни планети, Юпитер е газов гигант без твърда повърхност. Голямото червено петно е най-голямата и най-продължителната буря в турболентната атмосфера на планетата – тази вихрушка с размерите на Земята съществува от около 300 години."
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
|
@ -9,13 +9,13 @@
|
||||||
Target "Sol/Pluto"
|
Target "Sol/Pluto"
|
||||||
Distance 40000
|
Distance 40000
|
||||||
DistanceUnits "km"
|
DistanceUnits "km"
|
||||||
Description "Плутон обикаля около Слънцето на средно разстояние от шест милиарда километра. Луната му Харон е толкова голяма, че често ги наричат с Плутон 'двойна планета'."
|
Description "Плутон обикаля около Слънцето на средно разстояние от шест милиарда километра. Спътникът му Харон е толкова голям, че често ги наричат заедно с Плутон „двойната планета“."
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
Name "Ерос"
|
Name "Ерос"
|
||||||
Target "Sol/Eros"
|
Target "Sol/Eros"
|
||||||
Description "Ерос е астероид във формата на картоф и е дълъг около 33 км. Благодарение на космическия апарат NEAR Shoemaker, за Ерос знаем повече, отколкото за който и да било друг астероид. На 14 февруари 2001 г. NEAR се спусна на Ерос и стана първият апарат, приземил се на астероид."
|
Description "Ерос е астероид във формата на картоф и е дълъг около 33 км. Благодарение на космическия апарат „NEAR Shoemaker“, за Ерос знаем повече, отколкото за който и да било друг астероид. На 14 Февруари 2001 г., „NEAR“ се спусна на Ерос и стана първият апарат, приземил се на астероид."
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
|
@ -23,7 +23,7 @@
|
||||||
Target "Alpha Centauri"
|
Target "Alpha Centauri"
|
||||||
Distance 90
|
Distance 90
|
||||||
DistanceUnits "au"
|
DistanceUnits "au"
|
||||||
Description "Алфа Кантавър А и Б, заедно с Проксима Кентавър, са най-близката звездна система до Земята. Алфа Кентавър А много прилича на Слънцето, въпреки че е малко по-стара и по-ярка. Б е по-тъмна и по-червеникава, а Проксима е толкова слаба, че не може да се види с невъоръжено око, въпреки, че е най-близката звезда до Слънцето."
|
Description "Алфа Кентавър А и Б, заедно с Проксима Кентавър, са най-близката звездна система до Земята. Алфа Кентавър А много прилича на Слънцето, въпреки че е малко по-стара и по-ярка звезда. Алфа Кентавър Б е по-тъмна и по-червеникава, а Проксима Кентавър е толкова слаба, че не може да се види с невъоръжено око, въпреки, че е най-близката звезда до Слънцето."
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
|
@ -31,7 +31,7 @@
|
||||||
Target "Alcyone"
|
Target "Alcyone"
|
||||||
Distance 35
|
Distance 35
|
||||||
DistanceUnits "ly"
|
DistanceUnits "ly"
|
||||||
Description "Звездния куп Плеяди е група ярки, наскоро формирани звезди. Плеядите носят името на седем сестри от гръцката митология, въпреки, че телескопите са разкрили, че в звездния куп има доста повече от седем звезди."
|
Description "Звездният куп Плеяди е група ярки, наскоро формирани звезди. Плеядите носят името на седем сестри от гръцката митология, въпреки че телескопите са разкрили, че в звездния куп има доста повече от седем звезди."
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
|
@ -39,13 +39,13 @@
|
||||||
Target "63 Tau"
|
Target "63 Tau"
|
||||||
Distance 25
|
Distance 25
|
||||||
DistanceUnits "ly"
|
DistanceUnits "ly"
|
||||||
Description "Носещи името на петте дъщери на Атлас и Аетра, Хиядите са един от най-видните разсеяни звездни купове в небето. Звездите от звездния куп Хияди са на около 660 милиона години - около шест пъти по-стари от по-горещите и по-сини Плеяди."
|
Description "Носещи името на петте дъщери на Атлас и Аетра, Хиядите са един от най-видните разсеяни звездни купове в небето. Звездите от звездния куп Хияди са на около 660 милиона години - около шест пъти по-стари от по-горещите и по-сини Плеяди."
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
Name "Глийзе 876 б"
|
Name "Глийзе 876 б"
|
||||||
Target "Gliese 876/b"
|
Target "Gliese 876/b"
|
||||||
Description "Глийзе 876/б е гигантска планета в орбита около червено джудже. Тя е в резонанс 2:1 с друга планета от същата система."
|
Description "Глийзе 876/б е гигантска планета в орбита около червено джудже. Тя е в резонанс 2:1 с друга планета от същата система."
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
|
@ -53,24 +53,24 @@
|
||||||
Target "Sol/Ida"
|
Target "Sol/Ida"
|
||||||
Distance 200
|
Distance 200
|
||||||
DistanceUnits "km"
|
DistanceUnits "km"
|
||||||
Description "Космическият апарат Галилео фотографира астероида 243 Ида през 1993 г. на път към Юпитер. Снимките разкриха, че Ида има малък сателит, по-късно наречен Дактил. От тогава насам са открити още няколко астероида със спътници."
|
Description "Космическият апарат Галилео засне астероида 243 Ида през 1993 г. на път към Юпитер. Снимките разкриха, че Ида има малък спътник, по-късно наречен Дактил. От тогава до сега са открити още няколко астероида със спътници."
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
Name "51 Пегас б"
|
Name "51 Пегас б"
|
||||||
Target "51 Peg/b"
|
Target "51 Peg/b"
|
||||||
Description "51 Пегас б е първата открита планета, която обикаля около нормална звезда, различна от Слънцето. Тя е планета газов гигант и орбитата ѝ е изключително близо до звездата ѝ - по-малко от една пета от разстоянието между Меркурий и Слънцето. Съществуването на такава планета толкова близо до звезда накара астрономите да преразгледат теориите си за формирането на планетните системи."
|
Description "51 Пегас б е първата открита планета, която обикаля около нормална звезда, различна от Слънцето. Тя е газов гигант и орбитата ѝ е изключително близо до нейната звездата - по-малко от една пета от разстоянието между Меркурий и Слънцето. Съществуването на такава планета толкова близо до звезда накара астрономите да преразгледат теориите си за формирането на планетните системи."
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
Name "Албирео"
|
Name "Албирео"
|
||||||
Target "Albireo"
|
Target "Albireo"
|
||||||
Distance 0.6
|
Distance 0.6
|
||||||
Description "Заради контрастните оранжеви и синьо-бели цветове на съставните ѝ звезди, двойната звездна система Албирео е смятана за една от най-красивите двойки в небето. Оранжевата звезда е клас K гигант, а спътникът ѝ е B джудже."
|
Description "Заради контрастните оранжеви и синьо-бели цветове на съставните ѝ звезди, двойната звездна система Албирео е смятана за една от най-красивите двойки в небето. Оранжевата звезда е гигант от клас K, а спътникът ѝ е джудже от клас B."
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
Name "Кометата Борели"
|
Name "Кометата Борели"
|
||||||
Target "Sol/Borrelly"
|
Target "Sol/Borrelly"
|
||||||
Description "На 22 Септември 2001 г., кометата Борели стана втората комета, която беше снимана от космически апарат от близко разстояние. Въпреки че не беше проектиран да облита комети, Deep Space 1 се приближи на 2 200 километра от ядрото на Борели и ни изпрати най-добрите снимки на ядро на комета, с които разполагаме."
|
Description "На 22 Септември 2001 г., кометата Борели стана втората комета, която е заснета от космически апарат от близко разстояние. Въпреки че не е проектиран за това, „Deep Space“ 1 се приближи на 2 200 километра от ядрото на Борели и изпрати най-добрите снимки на ядро на комета, с които разполагаме."
|
||||||
}
|
}
|
||||||
|
|
Binary file not shown.
After Width: | Height: | Size: 716 KiB |
File diff suppressed because it is too large
Load Diff
|
@ -55,7 +55,8 @@ write_buffer(const char* first, const char* last, chars_format fmt, char* buffer
|
||||||
if (*ptr == 'i' || *ptr == 'I')
|
if (*ptr == 'i' || *ptr == 'I')
|
||||||
{
|
{
|
||||||
if (last - ptr < inf_length) { return { first, std::errc::invalid_argument }; }
|
if (last - ptr < inf_length) { return { first, std::errc::invalid_argument }; }
|
||||||
std::size_t length = std::min(static_cast<std::size_t>(infinity_length), static_cast<std::size_t>(last - ptr));
|
std::size_t length = std::min(infinity_length, static_cast<std::size_t>(last - ptr));
|
||||||
|
static_assert(infinity_length < buffer_size, "Buffer too small to hold 'infinity' literal");
|
||||||
std::memcpy(buffer, ptr, length);
|
std::memcpy(buffer, ptr, length);
|
||||||
buffer += length;
|
buffer += length;
|
||||||
}
|
}
|
||||||
|
|
|
@ -100,7 +100,7 @@ void Nebula::render(const Vector3f& /*offset*/,
|
||||||
getOrientation());
|
getOrientation());
|
||||||
|
|
||||||
GLSLUnlit_RenderContext rc(renderer, getRadius(), &mv, m.projection);
|
GLSLUnlit_RenderContext rc(renderer, getRadius(), &mv, m.projection);
|
||||||
rc.setPointScale(2.0f * getRadius() / pixelSize * renderer->getScreenDpi() / 96.0f);
|
rc.setPointScale(2.0f * getRadius() / pixelSize);
|
||||||
g->render(rc);
|
g->render(rc);
|
||||||
|
|
||||||
renderer->enableBlending();
|
renderer->enableBlending();
|
||||||
|
|
|
@ -25,30 +25,14 @@ template <class OBJ, class PREC> class ObjectRenderer : public OctreeProcessor<O
|
||||||
const Observer* observer { nullptr };
|
const Observer* observer { nullptr };
|
||||||
Renderer* renderer { nullptr };
|
Renderer* renderer { nullptr };
|
||||||
|
|
||||||
Eigen::Vector3f viewNormal;
|
|
||||||
|
|
||||||
float fov { 0.0f };
|
float fov { 0.0f };
|
||||||
float size { 0.0f };
|
|
||||||
float pixelSize { 0.0f };
|
float pixelSize { 0.0f };
|
||||||
float faintestMag { 0.0f };
|
float faintestMag { 0.0f };
|
||||||
float faintestMagNight { 0.0f };
|
|
||||||
float saturationMag { 0.0f };
|
|
||||||
float brightnessScale { 0.0f };
|
|
||||||
float brightnessBias { 0.0f };
|
|
||||||
float distanceLimit { 0.0f };
|
float distanceLimit { 0.0f };
|
||||||
|
|
||||||
// Objects brighter than labelThresholdMag will be labeled
|
// Objects brighter than labelThresholdMag will be labeled
|
||||||
float labelThresholdMag { 0.0f };
|
float labelThresholdMag { 0.0f };
|
||||||
|
|
||||||
// These are not fully used by this template's descendants
|
|
||||||
// but we place them here just in case a more sophisticated
|
|
||||||
// rendering scheme is implemented:
|
|
||||||
int nRendered { 0 };
|
|
||||||
int nClose { 0 };
|
|
||||||
int nBright { 0 };
|
|
||||||
int nProcessed { 0 };
|
|
||||||
int nLabelled { 0 };
|
|
||||||
|
|
||||||
uint64_t renderFlags { 0 };
|
uint64_t renderFlags { 0 };
|
||||||
int labelMode { 0 };
|
int labelMode { 0 };
|
||||||
};
|
};
|
||||||
|
|
|
@ -34,7 +34,8 @@ PointStarRenderer::PointStarRenderer() :
|
||||||
|
|
||||||
void PointStarRenderer::process(const Star& star, float distance, float appMag)
|
void PointStarRenderer::process(const Star& star, float distance, float appMag)
|
||||||
{
|
{
|
||||||
nProcessed++;
|
if (distance > distanceLimit)
|
||||||
|
return;
|
||||||
|
|
||||||
Vector3f starPos = star.getPosition();
|
Vector3f starPos = star.getPosition();
|
||||||
|
|
||||||
|
@ -44,9 +45,6 @@ void PointStarRenderer::process(const Star& star, float distance, float appMag)
|
||||||
float orbitalRadius = star.getOrbitalRadius();
|
float orbitalRadius = star.getOrbitalRadius();
|
||||||
bool hasOrbit = orbitalRadius > 0.0f;
|
bool hasOrbit = orbitalRadius > 0.0f;
|
||||||
|
|
||||||
if (distance > distanceLimit)
|
|
||||||
return;
|
|
||||||
|
|
||||||
// A very rough check to see if the star may be visible: is the star in
|
// A very rough check to see if the star may be visible: is the star in
|
||||||
// front of the viewer? If the star might be close (relPos.x^2 < 0.1) or
|
// front of the viewer? If the star might be close (relPos.x^2 < 0.1) or
|
||||||
// is moving in an orbit, we'll always regard it as potentially visible.
|
// is moving in an orbit, we'll always regard it as potentially visible.
|
||||||
|
@ -69,10 +67,10 @@ void PointStarRenderer::process(const Star& star, float distance, float appMag)
|
||||||
// * It may be large enough that we should render it as a mesh
|
// * It may be large enough that we should render it as a mesh
|
||||||
// instead of a particle
|
// instead of a particle
|
||||||
// It's possible that the second condition might apply for stars
|
// It's possible that the second condition might apply for stars
|
||||||
// further than one light year away if the star is huge, the fov is
|
// further than a solar system size if the star is huge, the fov is
|
||||||
// very small and the resolution is high. We'll ignore this for now
|
// very small and the resolution is high. We'll ignore this for now
|
||||||
// and use the most inexpensive test possible . . .
|
// and use the most inexpensive test possible . . .
|
||||||
if (distance < 1.0f || orbitSizeInPixels > 1.0f)
|
if (distance < SolarSystemMaxDistance || orbitSizeInPixels > 1.0f)
|
||||||
{
|
{
|
||||||
// Compute the position of the observer relative to the star.
|
// Compute the position of the observer relative to the star.
|
||||||
// This is a much more accurate (and expensive) distance
|
// This is a much more accurate (and expensive) distance
|
||||||
|
@ -85,10 +83,9 @@ void PointStarRenderer::process(const Star& star, float distance, float appMag)
|
||||||
distance = relPos.norm();
|
distance = relPos.norm();
|
||||||
|
|
||||||
// Recompute apparent magnitude using new distance computation
|
// Recompute apparent magnitude using new distance computation
|
||||||
appMag = star.getApparentMagnitude((float)distance);
|
appMag = star.getApparentMagnitude(distance);
|
||||||
|
|
||||||
discSizeInPixels = star.getRadius() / astro::lightYearsToKilometers(distance) / pixelSize;
|
discSizeInPixels = star.getRadius() / astro::lightYearsToKilometers(distance) / pixelSize;
|
||||||
++nClose;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Stars closer than the maximum solar system size are actually
|
// Stars closer than the maximum solar system size are actually
|
||||||
|
@ -96,44 +93,19 @@ void PointStarRenderer::process(const Star& star, float distance, float appMag)
|
||||||
// planets.
|
// planets.
|
||||||
if (distance > SolarSystemMaxDistance)
|
if (distance > SolarSystemMaxDistance)
|
||||||
{
|
{
|
||||||
float satPoint = faintestMag - (1.0f - brightnessBias) / brightnessScale; // TODO: precompute this value
|
float pointSize, alpha, glareSize, glareAlpha;
|
||||||
float alpha = (faintestMag - appMag) * brightnessScale + brightnessBias;
|
float size = BaseStarDiscSize * static_cast<float>(renderer->getScreenDpi()) / 96.0f;
|
||||||
|
renderer->calculatePointSize(appMag,
|
||||||
|
size,
|
||||||
|
pointSize,
|
||||||
|
alpha,
|
||||||
|
glareSize,
|
||||||
|
glareAlpha);
|
||||||
|
|
||||||
if (useScaledDiscs)
|
if (glareSize != 0.0f)
|
||||||
{
|
glareVertexBuffer->addStar(relPos, Color(starColor, glareAlpha), glareSize);
|
||||||
float discSize = size;
|
if (pointSize != 0.0f)
|
||||||
if (alpha < 0.0f)
|
starVertexBuffer->addStar(relPos, Color(starColor, alpha), pointSize);
|
||||||
{
|
|
||||||
alpha = 0.0f;
|
|
||||||
}
|
|
||||||
else if (alpha > 1.0f)
|
|
||||||
{
|
|
||||||
float discScale = min(MaxScaledDiscStarSize, (float) pow(2.0f, 0.3f * (satPoint - appMag)));
|
|
||||||
discSize *= discScale;
|
|
||||||
|
|
||||||
float glareAlpha = min(0.5f, discScale / 4.0f);
|
|
||||||
glareVertexBuffer->addStar(relPos, Color(starColor, glareAlpha), discSize * 3.0f);
|
|
||||||
|
|
||||||
alpha = 1.0f;
|
|
||||||
}
|
|
||||||
starVertexBuffer->addStar(relPos, Color(starColor, alpha), discSize);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (alpha < 0.0f)
|
|
||||||
{
|
|
||||||
alpha = 0.0f;
|
|
||||||
}
|
|
||||||
else if (alpha > 1.0f)
|
|
||||||
{
|
|
||||||
float discScale = min(100.0f, satPoint - appMag + 2.0f);
|
|
||||||
float glareAlpha = min(GlareOpacity, (discScale - 2.0f) / 4.0f);
|
|
||||||
glareVertexBuffer->addStar(relPos, Color(starColor, glareAlpha), 2.0f * discScale * size);
|
|
||||||
}
|
|
||||||
starVertexBuffer->addStar(relPos, Color(starColor, alpha), size);
|
|
||||||
}
|
|
||||||
|
|
||||||
++nRendered;
|
|
||||||
|
|
||||||
// Place labels for stars brighter than the specified label threshold brightness
|
// Place labels for stars brighter than the specified label threshold brightness
|
||||||
if (((labelMode & Renderer::StarLabels) != 0) && appMag < labelThresholdMag)
|
if (((labelMode & Renderer::StarLabels) != 0) && appMag < labelThresholdMag)
|
||||||
|
@ -147,7 +119,6 @@ void PointStarRenderer::process(const Star& star, float distance, float appMag)
|
||||||
starDB->getStarName(star, true),
|
starDB->getStarName(star, true),
|
||||||
color,
|
color,
|
||||||
relPos);
|
relPos);
|
||||||
nLabelled++;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -43,13 +43,12 @@ class PointStarRenderer : public ObjectRenderer<Star, float>
|
||||||
void process(const Star &star, float distance, float appMag);
|
void process(const Star &star, float distance, float appMag);
|
||||||
|
|
||||||
Eigen::Vector3d obsPos;
|
Eigen::Vector3d obsPos;
|
||||||
|
Eigen::Vector3f viewNormal;
|
||||||
std::vector<RenderListEntry>* renderList { nullptr };
|
std::vector<RenderListEntry>* renderList { nullptr };
|
||||||
PointStarVertexBuffer* starVertexBuffer { nullptr };
|
PointStarVertexBuffer* starVertexBuffer { nullptr };
|
||||||
PointStarVertexBuffer* glareVertexBuffer { nullptr };
|
PointStarVertexBuffer* glareVertexBuffer { nullptr };
|
||||||
const StarDatabase* starDB { nullptr };
|
const StarDatabase* starDB { nullptr };
|
||||||
const ColorTemperatureTable* colorTemp { nullptr };
|
const ColorTemperatureTable* colorTemp { nullptr };
|
||||||
float SolarSystemMaxDistance { 1.0f };
|
float SolarSystemMaxDistance { 1.0f };
|
||||||
float maxDiscSize { 1.0f };
|
|
||||||
float cosFOV { 1.0f };
|
float cosFOV { 1.0f };
|
||||||
bool useScaledDiscs { false };
|
|
||||||
};
|
};
|
||||||
|
|
|
@ -80,7 +80,7 @@ void PointStarVertexBuffer::makeCurrent()
|
||||||
current->finish();
|
current->finish();
|
||||||
|
|
||||||
program->use();
|
program->use();
|
||||||
program->setMVPMatrices(renderer.getProjectionMatrix(), renderer.getModelViewMatrix());
|
program->setMVPMatrices(renderer.getCurrentProjectionMatrix(), renderer.getCurrentModelViewMatrix());
|
||||||
if (pointSizeFromVertex)
|
if (pointSizeFromVertex)
|
||||||
{
|
{
|
||||||
program->samplerParam("starTex") = 0;
|
program->samplerParam("starTex") = 0;
|
||||||
|
|
|
@ -16,6 +16,7 @@
|
||||||
#include "lightenv.h"
|
#include "lightenv.h"
|
||||||
#include "rendcontext.h"
|
#include "rendcontext.h"
|
||||||
#include "render.h"
|
#include "render.h"
|
||||||
|
#include "shadowmap.h" // GL_ONLY_SHADOWS definition
|
||||||
#include "texmanager.h"
|
#include "texmanager.h"
|
||||||
#include "texture.h"
|
#include "texture.h"
|
||||||
|
|
||||||
|
|
|
@ -1560,6 +1560,13 @@ void Renderer::draw(const Observer& observer,
|
||||||
else
|
else
|
||||||
brightnessScale = 0.1667f;
|
brightnessScale = 0.1667f;
|
||||||
|
|
||||||
|
brightnessScale *= corrFac;
|
||||||
|
if (starStyle == ScaledDiscStars)
|
||||||
|
brightnessScale *= 2.0f;
|
||||||
|
|
||||||
|
// Calculate saturation magnitude
|
||||||
|
satPoint = faintestMag - (1.0f - brightnessBias) / brightnessScale;
|
||||||
|
|
||||||
ambientColor = Color(ambientLightLevel, ambientLightLevel, ambientLightLevel);
|
ambientColor = Color(ambientLightLevel, ambientLightLevel, ambientLightLevel);
|
||||||
|
|
||||||
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
|
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
|
||||||
|
@ -1662,43 +1669,7 @@ void Renderer::draw(const Observer& observer,
|
||||||
enableDepthMask();
|
enableDepthMask();
|
||||||
}
|
}
|
||||||
|
|
||||||
void renderPoint(const Renderer &renderer,
|
static
|
||||||
const Vector3f &position,
|
|
||||||
const Color &color,
|
|
||||||
float size,
|
|
||||||
bool useSprite,
|
|
||||||
const Matrices &m)
|
|
||||||
{
|
|
||||||
auto *prog = renderer.getShaderManager().getShader("star");
|
|
||||||
if (prog == nullptr)
|
|
||||||
return;
|
|
||||||
|
|
||||||
prog->use();
|
|
||||||
prog->samplerParam("starTex") = 0;
|
|
||||||
prog->setMVPMatrices(*m.projection, *m.modelview);
|
|
||||||
|
|
||||||
#ifndef GL_ES
|
|
||||||
glEnable(GL_POINT_SPRITE);
|
|
||||||
glEnable(GL_VERTEX_PROGRAM_POINT_SIZE);
|
|
||||||
#endif
|
|
||||||
// Workaround for macOS to pass a single vertex coord
|
|
||||||
glEnableVertexAttribArray(CelestiaGLProgram::VertexCoordAttributeIndex);
|
|
||||||
glVertexAttribPointer(CelestiaGLProgram::VertexCoordAttributeIndex,
|
|
||||||
3, GL_FLOAT, GL_FALSE, sizeof(position), position.data());
|
|
||||||
|
|
||||||
glVertexAttrib(CelestiaGLProgram::ColorAttributeIndex, color);
|
|
||||||
glVertexAttrib1f(CelestiaGLProgram::PointSizeAttributeIndex, useSprite ? size : renderer.getScreenDpi() / 96.0f);
|
|
||||||
|
|
||||||
glDrawArrays(GL_POINTS, 0, 1);
|
|
||||||
|
|
||||||
glDisableVertexAttribArray(CelestiaGLProgram::VertexCoordAttributeIndex);
|
|
||||||
|
|
||||||
#ifndef GL_ES
|
|
||||||
glDisable(GL_VERTEX_PROGRAM_POINT_SIZE);
|
|
||||||
glDisable(GL_POINT_SPRITE);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
void renderLargePoint(Renderer &renderer,
|
void renderLargePoint(Renderer &renderer,
|
||||||
const Vector3f &position,
|
const Vector3f &position,
|
||||||
const Color &color,
|
const Color &color,
|
||||||
|
@ -1741,6 +1712,64 @@ void renderLargePoint(Renderer &renderer,
|
||||||
vo.unbind();
|
vo.unbind();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static Eigen::Vector3f
|
||||||
|
calculateQuadCenter(const Eigen::Quaternionf &cameraOrientation,
|
||||||
|
const Eigen::Vector3f &position,
|
||||||
|
float radius)
|
||||||
|
{
|
||||||
|
Matrix3f m = cameraOrientation.conjugate().toRotationMatrix();
|
||||||
|
|
||||||
|
// Offset the glare sprite so that it lies in front of the object
|
||||||
|
Vector3f direction = position.normalized();
|
||||||
|
|
||||||
|
// Position the sprite on the the line between the viewer and the
|
||||||
|
// object, and on a plane normal to the view direction.
|
||||||
|
return position + direction * (radius / (m * Vector3f::UnitZ()).dot(direction));
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
Renderer::calculatePointSize(float appMag,
|
||||||
|
float size,
|
||||||
|
float &discSize,
|
||||||
|
float &alpha,
|
||||||
|
float &glareSize,
|
||||||
|
float &glareAlpha) const
|
||||||
|
{
|
||||||
|
alpha = std::max(0.0f, (faintestMag - appMag) * brightnessScale + brightnessBias);
|
||||||
|
|
||||||
|
discSize = size;
|
||||||
|
if (starStyle == ScaledDiscStars)
|
||||||
|
{
|
||||||
|
if (alpha > 1.0f)
|
||||||
|
{
|
||||||
|
float discScale = std::min(MaxScaledDiscStarSize, pow(2.0f, 0.3f * (satPoint - appMag)));
|
||||||
|
discSize *= std::max(1.0f, discScale);
|
||||||
|
|
||||||
|
glareAlpha = std::min(0.5f, discScale / 4.0f);
|
||||||
|
glareSize = discSize * 3.0f;
|
||||||
|
|
||||||
|
alpha = 1.0f;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
glareSize = glareAlpha = 0.0f;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (alpha > 1.0f)
|
||||||
|
{
|
||||||
|
float discScale = std::min(100.0f, satPoint - appMag + 2.0f);
|
||||||
|
glareAlpha = std::min(GlareOpacity, (discScale - 2.0f) / 4.0f);
|
||||||
|
glareSize = 2.0f * discScale * size;
|
||||||
|
alpha = 1.0f;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
glareSize = glareAlpha = 0.0f;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// If the an object occupies a pixel or less of screen space, we don't
|
// If the an object occupies a pixel or less of screen space, we don't
|
||||||
// render its mesh at all and just display a starlike point instead.
|
// render its mesh at all and just display a starlike point instead.
|
||||||
|
@ -1751,95 +1780,49 @@ void renderLargePoint(Renderer &renderer,
|
||||||
void Renderer::renderObjectAsPoint(const Vector3f& position,
|
void Renderer::renderObjectAsPoint(const Vector3f& position,
|
||||||
float radius,
|
float radius,
|
||||||
float appMag,
|
float appMag,
|
||||||
float _faintestMag,
|
|
||||||
float discSizeInPixels,
|
float discSizeInPixels,
|
||||||
const Color &color,
|
const Color &color,
|
||||||
bool useHalos,
|
bool useHalos,
|
||||||
bool emissive,
|
bool emissive,
|
||||||
const Matrices &mvp)
|
const Matrices &mvp)
|
||||||
{
|
{
|
||||||
const float maxSize = MaxScaledDiscStarSize;
|
const bool useScaledDiscs = starStyle == ScaledDiscStars;
|
||||||
float maxDiscSize = (starStyle == ScaledDiscStars) ? maxSize : 1.0f;
|
float maxDiscSize = useScaledDiscs ? MaxScaledDiscStarSize : 1.0f;
|
||||||
float maxBlendDiscSize = maxDiscSize + 3.0f;
|
float maxBlendDiscSize = maxDiscSize + 3.0f;
|
||||||
|
|
||||||
bool useScaledDiscs = starStyle == ScaledDiscStars;
|
|
||||||
|
|
||||||
if (discSizeInPixels < maxBlendDiscSize || useHalos)
|
if (discSizeInPixels < maxBlendDiscSize || useHalos)
|
||||||
{
|
{
|
||||||
float alpha = 1.0f;
|
|
||||||
float fade = 1.0f;
|
float fade = 1.0f;
|
||||||
float size = BaseStarDiscSize * screenDpi / 96.0f;
|
|
||||||
float satPoint = _faintestMag - (1.0f - brightnessBias) / brightnessScale;
|
|
||||||
|
|
||||||
if (discSizeInPixels > maxDiscSize)
|
if (discSizeInPixels > maxDiscSize)
|
||||||
{
|
{
|
||||||
fade = (maxBlendDiscSize - discSizeInPixels) /
|
fade = std::min(1.0f, (maxBlendDiscSize - discSizeInPixels) /
|
||||||
(maxBlendDiscSize - maxDiscSize);
|
(maxBlendDiscSize - maxDiscSize));
|
||||||
if (fade > 1)
|
|
||||||
fade = 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
alpha = (_faintestMag - appMag) * brightnessScale * 2.0f + brightnessBias;
|
float scale = static_cast<float>(screenDpi) / 96.0f;
|
||||||
if (alpha < 0.0f)
|
float pointSize, alpha, glareSize, glareAlpha;
|
||||||
alpha = 0.0f;
|
calculatePointSize(appMag, BaseStarDiscSize * scale, pointSize, alpha, glareSize, glareAlpha);
|
||||||
|
|
||||||
float pointSize = size;
|
if (useScaledDiscs && discSizeInPixels > MaxScaledDiscStarSize)
|
||||||
float glareSize = 0.0f;
|
glareAlpha = std::min(glareAlpha, (MaxScaledDiscStarSize - discSizeInPixels) / MaxScaledDiscStarSize + 1.0f);
|
||||||
float glareAlpha = 0.0f;
|
|
||||||
if (useScaledDiscs)
|
|
||||||
{
|
|
||||||
if (alpha > 1.0f)
|
|
||||||
{
|
|
||||||
float discScale = min(maxSize, (float) pow(2.0f, 0.3f * (satPoint - appMag)));
|
|
||||||
pointSize *= max(1.0f, discScale);
|
|
||||||
|
|
||||||
glareAlpha = min(0.5f, discScale / 4.0f);
|
|
||||||
if (discSizeInPixels > maxSize)
|
|
||||||
glareAlpha = min(glareAlpha, (maxSize - discSizeInPixels) / maxSize + 1.0f);
|
|
||||||
glareSize = pointSize * 3.0f;
|
|
||||||
|
|
||||||
alpha = 1.0f;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (alpha > 1.0f)
|
|
||||||
{
|
|
||||||
float discScale = min(100.0f, satPoint - appMag + 2.0f);
|
|
||||||
glareAlpha = min(GlareOpacity, (discScale - 2.0f) / 4.0f);
|
|
||||||
glareSize = pointSize * discScale * 2.0f ;
|
|
||||||
if (emissive)
|
|
||||||
glareSize = max(glareSize, pointSize * discSizeInPixels / (screenDpi / 96.0f) * 3.0f);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
alpha *= fade;
|
alpha *= fade;
|
||||||
if (!emissive)
|
if (!emissive)
|
||||||
{
|
|
||||||
glareSize = max(glareSize, pointSize * discSizeInPixels / (screenDpi / 96.0f) * 3.0f);
|
|
||||||
glareAlpha *= fade;
|
glareAlpha *= fade;
|
||||||
}
|
|
||||||
|
|
||||||
Matrix3f m = m_cameraOrientation.conjugate().toRotationMatrix();
|
if (glareSize != 0.0f)
|
||||||
Vector3f center = position;
|
glareSize = std::max(glareSize, pointSize * discSizeInPixels / scale * 3.0f);
|
||||||
|
|
||||||
// Offset the glare sprite so that it lies in front of the object
|
|
||||||
Vector3f direction = center.normalized();
|
|
||||||
|
|
||||||
// Position the sprite on the the line between the viewer and the
|
|
||||||
// object, and on a plane normal to the view direction.
|
|
||||||
center = center + direction * (radius / (m * Vector3f::UnitZ()).dot(direction));
|
|
||||||
|
|
||||||
enableDepthTest();
|
enableDepthTest();
|
||||||
disableDepthMask();
|
disableDepthMask();
|
||||||
|
|
||||||
bool useSprites = starStyle != PointStars;
|
if (starStyle != PointStars)
|
||||||
if (useSprites)
|
|
||||||
gaussianDiscTex->bind();
|
gaussianDiscTex->bind();
|
||||||
|
|
||||||
if (pointSize > gl::maxPointSize)
|
if (pointSize > gl::maxPointSize)
|
||||||
renderLargePoint(*this, center, {color, alpha}, pointSize, mvp);
|
renderLargePoint(*this, position, {color, alpha}, pointSize, mvp);
|
||||||
else
|
else
|
||||||
renderPoint(*this, center, {color, alpha}, pointSize, useSprites, mvp);
|
pointStarVertexBuffer->addStar(position, {color, alpha}, pointSize);
|
||||||
|
|
||||||
// If the object is brighter than magnitude 1, add a halo around it to
|
// If the object is brighter than magnitude 1, add a halo around it to
|
||||||
// make it appear more brilliant. This is a hack to compensate for the
|
// make it appear more brilliant. This is a hack to compensate for the
|
||||||
|
@ -1849,11 +1832,12 @@ void Renderer::renderObjectAsPoint(const Vector3f& position,
|
||||||
// with halos.
|
// with halos.
|
||||||
if (useHalos && glareAlpha > 0.0f)
|
if (useHalos && glareAlpha > 0.0f)
|
||||||
{
|
{
|
||||||
|
Eigen::Vector3f center = calculateQuadCenter(m_cameraOrientation, position, radius);
|
||||||
gaussianGlareTex->bind();
|
gaussianGlareTex->bind();
|
||||||
if (glareSize > gl::maxPointSize)
|
if (glareSize > gl::maxPointSize)
|
||||||
renderLargePoint(*this, center, {color, glareAlpha}, glareSize, mvp);
|
renderLargePoint(*this, center, {color, glareAlpha}, glareSize, mvp);
|
||||||
else
|
else
|
||||||
renderPoint(*this, center, {color, glareAlpha}, glareSize, true, mvp);
|
glareVertexBuffer->addStar(center, {color, glareAlpha}, glareSize);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2586,14 +2570,14 @@ void Renderer::renderObject(const Vector3f& pos,
|
||||||
geometryScale = obj.radius;
|
geometryScale = obj.radius;
|
||||||
scaleFactors = obj.radius * obj.semiAxes;
|
scaleFactors = obj.radius * obj.semiAxes;
|
||||||
ringsScaleFactor = obj.radius * obj.semiAxes.maxCoeff();
|
ringsScaleFactor = obj.radius * obj.semiAxes.maxCoeff();
|
||||||
ri.pointScale = 2.0f * obj.radius / pixelSize * screenDpi / 96.0f;
|
ri.pointScale = 2.0f * obj.radius / pixelSize;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
geometryScale = obj.geometryScale;
|
geometryScale = obj.geometryScale;
|
||||||
scaleFactors = Vector3f::Constant(geometryScale);
|
scaleFactors = Vector3f::Constant(geometryScale);
|
||||||
ringsScaleFactor = geometryScale;
|
ringsScaleFactor = geometryScale;
|
||||||
ri.pointScale = 2.0f * geometryScale / pixelSize * screenDpi / 96.0f;
|
ri.pointScale = 2.0f * geometryScale / pixelSize;
|
||||||
}
|
}
|
||||||
// Apply the modelview transform for the object
|
// Apply the modelview transform for the object
|
||||||
Affine3f transform = Translation3f(pos) * obj.orientation.conjugate();
|
Affine3f transform = Translation3f(pos) * obj.orientation.conjugate();
|
||||||
|
@ -3317,7 +3301,6 @@ void Renderer::renderPlanet(Body& body,
|
||||||
renderObjectAsPoint(pos,
|
renderObjectAsPoint(pos,
|
||||||
body.getRadius(),
|
body.getRadius(),
|
||||||
appMag,
|
appMag,
|
||||||
faintestMag,
|
|
||||||
discSizeInPixels,
|
discSizeInPixels,
|
||||||
body.getSurface().color,
|
body.getSurface().color,
|
||||||
false, false, m);
|
false, false, m);
|
||||||
|
@ -3396,7 +3379,6 @@ void Renderer::renderStar(const Star& star,
|
||||||
renderObjectAsPoint(pos,
|
renderObjectAsPoint(pos,
|
||||||
star.getRadius(),
|
star.getRadius(),
|
||||||
appMag,
|
appMag,
|
||||||
faintestMag,
|
|
||||||
discSizeInPixels,
|
discSizeInPixels,
|
||||||
color,
|
color,
|
||||||
star.hasCorona(), true,
|
star.hasCorona(), true,
|
||||||
|
@ -4371,11 +4353,7 @@ void Renderer::renderPointStars(const StarDatabase& starDB,
|
||||||
starRenderer.cosFOV = (float) cos(degToRad(calcMaxFOV(fov, getAspectRatio())) / 2.0f);
|
starRenderer.cosFOV = (float) cos(degToRad(calcMaxFOV(fov, getAspectRatio())) / 2.0f);
|
||||||
|
|
||||||
starRenderer.pixelSize = pixelSize;
|
starRenderer.pixelSize = pixelSize;
|
||||||
starRenderer.brightnessScale = brightnessScale * corrFac;
|
|
||||||
starRenderer.brightnessBias = brightnessBias;
|
|
||||||
starRenderer.faintestMag = faintestMag;
|
starRenderer.faintestMag = faintestMag;
|
||||||
starRenderer.faintestMagNight = faintestMagNight;
|
|
||||||
starRenderer.saturationMag = saturationMag;
|
|
||||||
starRenderer.distanceLimit = distanceLimit;
|
starRenderer.distanceLimit = distanceLimit;
|
||||||
starRenderer.labelMode = labelMode;
|
starRenderer.labelMode = labelMode;
|
||||||
starRenderer.SolarSystemMaxDistance = SolarSystemMaxDistance;
|
starRenderer.SolarSystemMaxDistance = SolarSystemMaxDistance;
|
||||||
|
@ -4384,18 +4362,6 @@ void Renderer::renderPointStars(const StarDatabase& starDB,
|
||||||
float effDistanceToScreen = mmToInches((float) REF_DISTANCE_TO_SCREEN) * pixelSize * getScreenDpi();
|
float effDistanceToScreen = mmToInches((float) REF_DISTANCE_TO_SCREEN) * pixelSize * getScreenDpi();
|
||||||
starRenderer.labelThresholdMag = 1.2f * max(1.0f, (faintestMag - 4.0f) * (1.0f - 0.5f * (float) log10(effDistanceToScreen)));
|
starRenderer.labelThresholdMag = 1.2f * max(1.0f, (faintestMag - 4.0f) * (1.0f - 0.5f * (float) log10(effDistanceToScreen)));
|
||||||
|
|
||||||
starRenderer.size = BaseStarDiscSize * screenDpi / 96.0f;
|
|
||||||
if (starStyle == ScaledDiscStars)
|
|
||||||
{
|
|
||||||
starRenderer.useScaledDiscs = true;
|
|
||||||
starRenderer.brightnessScale *= 2.0f;
|
|
||||||
starRenderer.maxDiscSize = starRenderer.size * MaxScaledDiscStarSize;
|
|
||||||
}
|
|
||||||
else if (starStyle == FuzzyPointStars)
|
|
||||||
{
|
|
||||||
starRenderer.brightnessScale *= 1.0f;
|
|
||||||
}
|
|
||||||
|
|
||||||
starRenderer.colorTemp = colorTemp;
|
starRenderer.colorTemp = colorTemp;
|
||||||
|
|
||||||
gaussianDiscTex->bind();
|
gaussianDiscTex->bind();
|
||||||
|
@ -4455,17 +4421,11 @@ void Renderer::renderDeepSkyObjects(const Universe& universe,
|
||||||
dsoRenderer.orientationMatrix= observer.getOrientationf().conjugate().toRotationMatrix();
|
dsoRenderer.orientationMatrix= observer.getOrientationf().conjugate().toRotationMatrix();
|
||||||
dsoRenderer.observer = &observer;
|
dsoRenderer.observer = &observer;
|
||||||
dsoRenderer.obsPos = obsPos;
|
dsoRenderer.obsPos = obsPos;
|
||||||
dsoRenderer.viewNormal = observer.getOrientationf().conjugate() * -Vector3f::UnitZ();
|
|
||||||
dsoRenderer.fov = fov;
|
dsoRenderer.fov = fov;
|
||||||
// size/pixelSize =0.86 at 120deg, 1.43 at 45deg and 1.6 at 0deg.
|
// size/pixelSize =0.86 at 120deg, 1.43 at 45deg and 1.6 at 0deg.
|
||||||
dsoRenderer.size = pixelSize * 1.6f / corrFac;
|
|
||||||
dsoRenderer.pixelSize = pixelSize;
|
dsoRenderer.pixelSize = pixelSize;
|
||||||
dsoRenderer.brightnessScale = brightnessScale * corrFac;
|
|
||||||
dsoRenderer.brightnessBias = brightnessBias;
|
|
||||||
dsoRenderer.avgAbsMag = dsoDB->getAverageAbsoluteMagnitude();
|
dsoRenderer.avgAbsMag = dsoDB->getAverageAbsoluteMagnitude();
|
||||||
dsoRenderer.faintestMag = faintestMag;
|
dsoRenderer.faintestMag = faintestMag;
|
||||||
dsoRenderer.faintestMagNight = faintestMagNight;
|
|
||||||
dsoRenderer.saturationMag = saturationMag;
|
|
||||||
dsoRenderer.renderFlags = renderFlags;
|
dsoRenderer.renderFlags = renderFlags;
|
||||||
dsoRenderer.labelMode = labelMode;
|
dsoRenderer.labelMode = labelMode;
|
||||||
dsoRenderer.wWidth = windowWidth;
|
dsoRenderer.wWidth = windowWidth;
|
||||||
|
@ -5988,6 +5948,8 @@ Renderer::renderSolarSystemObjects(const Observer &observer,
|
||||||
proj = Perspective(fov, aspectRatio, nearPlaneDistance, farPlaneDistance);
|
proj = Perspective(fov, aspectRatio, nearPlaneDistance, farPlaneDistance);
|
||||||
Matrices m = { &proj, &m_modelMatrix };
|
Matrices m = { &proj, &m_modelMatrix };
|
||||||
|
|
||||||
|
setCurrentProjectionMatrix(proj);
|
||||||
|
|
||||||
Frustum intervalFrustum(degToRad(fov),
|
Frustum intervalFrustum(degToRad(fov),
|
||||||
aspectRatio,
|
aspectRatio,
|
||||||
nearPlaneDistance,
|
nearPlaneDistance,
|
||||||
|
@ -6050,6 +6012,18 @@ Renderer::renderSolarSystemObjects(const Observer &observer,
|
||||||
i--;
|
i--;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PointStarVertexBuffer::enable();
|
||||||
|
glareVertexBuffer->startSprites();
|
||||||
|
glareVertexBuffer->render();
|
||||||
|
glareVertexBuffer->finish();
|
||||||
|
if (starStyle == PointStars)
|
||||||
|
pointStarVertexBuffer->startBasicPoints();
|
||||||
|
else
|
||||||
|
pointStarVertexBuffer->startSprites();
|
||||||
|
pointStarVertexBuffer->render();
|
||||||
|
pointStarVertexBuffer->finish();
|
||||||
|
PointStarVertexBuffer::disable();
|
||||||
|
|
||||||
// Render annotations in this interval
|
// Render annotations in this interval
|
||||||
enableSmoothLines();
|
enableSmoothLines();
|
||||||
annotation = renderSortedAnnotations(annotation,
|
annotation = renderSortedAnnotations(annotation,
|
||||||
|
@ -6062,4 +6036,5 @@ Renderer::renderSolarSystemObjects(const Observer &observer,
|
||||||
|
|
||||||
// reset the depth range
|
// reset the depth range
|
||||||
glDepthRange(0, 1);
|
glDepthRange(0, 1);
|
||||||
|
setDefaultProjectionMatrix();
|
||||||
}
|
}
|
||||||
|
|
|
@ -318,10 +318,12 @@ class Renderer
|
||||||
{
|
{
|
||||||
return m_modelMatrix;
|
return m_modelMatrix;
|
||||||
}
|
}
|
||||||
|
|
||||||
const Eigen::Matrix4f& getProjectionMatrix() const
|
const Eigen::Matrix4f& getProjectionMatrix() const
|
||||||
{
|
{
|
||||||
return m_projMatrix;
|
return m_projMatrix;
|
||||||
}
|
}
|
||||||
|
|
||||||
const Eigen::Matrix4f& getOrthoProjectionMatrix() const
|
const Eigen::Matrix4f& getOrthoProjectionMatrix() const
|
||||||
{
|
{
|
||||||
return m_orthoProjMatrix;
|
return m_orthoProjMatrix;
|
||||||
|
@ -337,6 +339,11 @@ class Renderer
|
||||||
m_modelViewPtr = &m;
|
m_modelViewPtr = &m;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void setDefaultModelViewMatrix()
|
||||||
|
{
|
||||||
|
m_modelViewPtr = &m_modelMatrix;
|
||||||
|
}
|
||||||
|
|
||||||
const Eigen::Matrix4f& getCurrentProjectionMatrix() const
|
const Eigen::Matrix4f& getCurrentProjectionMatrix() const
|
||||||
{
|
{
|
||||||
return *m_projectionPtr;
|
return *m_projectionPtr;
|
||||||
|
@ -347,6 +354,11 @@ class Renderer
|
||||||
m_projectionPtr = &m;
|
m_projectionPtr = &m;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void setDefaultProjectionMatrix()
|
||||||
|
{
|
||||||
|
m_projectionPtr = &m_projMatrix;
|
||||||
|
}
|
||||||
|
|
||||||
void setStarStyle(StarStyle);
|
void setStarStyle(StarStyle);
|
||||||
StarStyle getStarStyle() const;
|
StarStyle getStarStyle() const;
|
||||||
void setResolution(unsigned int resolution);
|
void setResolution(unsigned int resolution);
|
||||||
|
@ -618,10 +630,16 @@ class Renderer
|
||||||
float discSizeInPixels,
|
float discSizeInPixels,
|
||||||
const Matrices&);
|
const Matrices&);
|
||||||
|
|
||||||
|
void calculatePointSize(float appMag,
|
||||||
|
float size,
|
||||||
|
float &discSize,
|
||||||
|
float &alpha,
|
||||||
|
float &glareSize,
|
||||||
|
float &glareAlpha) const;
|
||||||
|
|
||||||
void renderObjectAsPoint(const Eigen::Vector3f& center,
|
void renderObjectAsPoint(const Eigen::Vector3f& center,
|
||||||
float radius,
|
float radius,
|
||||||
float appMag,
|
float appMag,
|
||||||
float _faintestMag,
|
|
||||||
float discSizeInPixels,
|
float discSizeInPixels,
|
||||||
const Color& color,
|
const Color& color,
|
||||||
bool useHalos,
|
bool useHalos,
|
||||||
|
@ -840,6 +858,9 @@ class Renderer
|
||||||
|
|
||||||
std::array<celgl::VertexObject*, static_cast<size_t>(VOType::Count)> m_VertexObjects;
|
std::array<celgl::VertexObject*, static_cast<size_t>(VOType::Count)> m_VertexObjects;
|
||||||
|
|
||||||
|
// Saturation magnitude used to calculate a point star size
|
||||||
|
float satPoint;
|
||||||
|
|
||||||
// Location markers
|
// Location markers
|
||||||
public:
|
public:
|
||||||
celestia::MarkerRepresentation mountainRep;
|
celestia::MarkerRepresentation mountainRep;
|
||||||
|
@ -897,6 +918,8 @@ class Renderer
|
||||||
static Color EclipticColor;
|
static Color EclipticColor;
|
||||||
|
|
||||||
static Color SelectionCursorColor;
|
static Color SelectionCursorColor;
|
||||||
|
|
||||||
|
friend class PointStarRenderer;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -32,6 +32,7 @@
|
||||||
#include "renderglsl.h"
|
#include "renderglsl.h"
|
||||||
#include "renderinfo.h"
|
#include "renderinfo.h"
|
||||||
#include "shadermanager.h"
|
#include "shadermanager.h"
|
||||||
|
#include "shadowmap.h" // GL_ONLY_SHADOWS definition
|
||||||
#include "texture.h"
|
#include "texture.h"
|
||||||
#include "vecgl.h"
|
#include "vecgl.h"
|
||||||
|
|
||||||
|
|
|
@ -387,7 +387,7 @@ static float rotperiod_M[3][10] =
|
||||||
|
|
||||||
|
|
||||||
const char* LumClassNames[StellarClass::Lum_Count] = {
|
const char* LumClassNames[StellarClass::Lum_Count] = {
|
||||||
"I-a0", "I-a", "I-b", "II", "III", "IV", "V", "VI", ""
|
"Ia-0", "Ia", "Ib", "II", "III", "IV", "V", "VI", ""
|
||||||
};
|
};
|
||||||
|
|
||||||
const char* SubclassNames[11] = {
|
const char* SubclassNames[11] = {
|
||||||
|
|
|
@ -17,59 +17,43 @@
|
||||||
using namespace Eigen;
|
using namespace Eigen;
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
|
|
||||||
// TODO: More of the functions in this module should be converted to
|
|
||||||
// methods of the StarBrowser class.
|
|
||||||
|
|
||||||
struct CloserStarPredicate
|
struct CloserStarPredicate
|
||||||
{
|
{
|
||||||
Vector3f pos;
|
Vector3f pos;
|
||||||
bool operator()(const Star* star0, const Star* star1) const
|
bool operator()(const Star* star0, const Star* star1) const
|
||||||
{
|
{
|
||||||
Vector3f p0 = star0->getPosition();
|
return (pos - star0->getPosition()).squaredNorm() < (pos - star1->getPosition()).squaredNorm();
|
||||||
Vector3f p1 = star1->getPosition();
|
|
||||||
|
|
||||||
#if 0
|
|
||||||
Vector3f v0(p0.x * 1e6 - pos.x, p0.y * 1e6 - pos.y, p0.z * 1e6 - pos.z);
|
|
||||||
Vector3f v1(p1.x * 1e6 - pos.x, p1.y * 1e6 - pos.y, p1.z * 1e6 - pos.z);
|
|
||||||
#endif
|
|
||||||
Vector3f v0 = p0 * 1.0e6f - pos;
|
|
||||||
Vector3f v1 = p1 * 1.0e6f - pos;
|
|
||||||
|
|
||||||
return (v0.squaredNorm() < v1.squaredNorm());
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
struct BrighterStarPredicate
|
struct BrighterStarPredicate
|
||||||
{
|
{
|
||||||
Vector3f pos;
|
Vector3f pos;
|
||||||
UniversalCoord ucPos;
|
UniversalCoord ucPos;
|
||||||
bool operator()(const Star* star0, const Star* star1) const
|
bool operator()(const Star* star0, const Star* star1) const
|
||||||
{
|
{
|
||||||
Vector3f p0 = star0->getPosition();
|
float d0 = (pos - star0->getPosition()).norm();
|
||||||
Vector3f p1 = star1->getPosition();
|
float d1 = (pos - star1->getPosition()).norm();
|
||||||
Vector3f v0 = p0 * 1.0e6f - pos;
|
|
||||||
Vector3f v1 = p1 * 1.0e6f - pos;
|
|
||||||
float d0 = v0.norm();
|
|
||||||
float d1 = v1.norm();
|
|
||||||
|
|
||||||
return (star0->getApparentMagnitude(d0) <
|
// If the stars are closer than one light year, use
|
||||||
star1->getApparentMagnitude(d1));
|
// a more precise distance estimate.
|
||||||
|
if (d0 < 1.0f)
|
||||||
|
d0 = ucPos.offsetFromLy(star0->getPosition()).norm();
|
||||||
|
if (d1 < 1.0f)
|
||||||
|
d1 = ucPos.offsetFromLy(star1->getPosition()).norm();
|
||||||
|
|
||||||
|
return star0->getApparentMagnitude(d0) < star1->getApparentMagnitude(d1);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
struct BrightestStarPredicate
|
struct BrightestStarPredicate
|
||||||
{
|
{
|
||||||
bool operator()(const Star* star0, const Star* star1) const
|
bool operator()(const Star* star0, const Star* star1) const
|
||||||
{
|
{
|
||||||
return (star0->getAbsoluteMagnitude() <
|
return star0->getAbsoluteMagnitude() < star1->getAbsoluteMagnitude();
|
||||||
star1->getAbsoluteMagnitude());
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
struct SolarSystemPredicate
|
struct SolarSystemPredicate
|
||||||
{
|
{
|
||||||
Vector3f pos;
|
Vector3f pos;
|
||||||
|
@ -85,11 +69,7 @@ struct SolarSystemPredicate
|
||||||
bool hasPlanets1 = (iter != solarSystems->end());
|
bool hasPlanets1 = (iter != solarSystems->end());
|
||||||
if (hasPlanets1 == hasPlanets0)
|
if (hasPlanets1 == hasPlanets0)
|
||||||
{
|
{
|
||||||
Vector3f p0 = star0->getPosition();
|
return ((pos - star0->getPosition()).squaredNorm() < (pos - star1->getPosition()).squaredNorm());
|
||||||
Vector3f p1 = star1->getPosition();
|
|
||||||
Vector3f v0 = p0 * 1.0e6f - pos;
|
|
||||||
Vector3f v1 = p1 * 1.0e6f - pos;
|
|
||||||
return (v0.squaredNorm() < v1.squaredNorm());
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
|
@ -57,62 +57,6 @@ Color StellarClass::getApparentColor(StellarClass::SpectralClass sc) const
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// The << method of converting the stellar class to a string is
|
|
||||||
// preferred, but it's not always practical, especially when you've
|
|
||||||
// got a completely broken implementation of stringstreams to
|
|
||||||
// deal with (*cough* gcc *cough*).
|
|
||||||
string StellarClass::str() const
|
|
||||||
{
|
|
||||||
char s0, s1;
|
|
||||||
const char* s2 = "";
|
|
||||||
|
|
||||||
switch (getStarType())
|
|
||||||
{
|
|
||||||
case StellarClass::WhiteDwarf:
|
|
||||||
return "WD";
|
|
||||||
case StellarClass::NeutronStar:
|
|
||||||
return "Q";
|
|
||||||
case StellarClass::BlackHole:
|
|
||||||
return "X";
|
|
||||||
case StellarClass::NormalStar:
|
|
||||||
s0 = "OBAFGKMRSNWWW?LTYC"[(unsigned int) getSpectralClass()];
|
|
||||||
s1 = "0123456789"[getSubclass()];
|
|
||||||
switch (getLuminosityClass())
|
|
||||||
{
|
|
||||||
case StellarClass::Lum_Ia0:
|
|
||||||
s2 = " I-a0";
|
|
||||||
break;
|
|
||||||
case StellarClass::Lum_Ia:
|
|
||||||
s2 = " I-a";
|
|
||||||
break;
|
|
||||||
case StellarClass::Lum_Ib:
|
|
||||||
s2 = " I-b";
|
|
||||||
break;
|
|
||||||
case StellarClass::Lum_II:
|
|
||||||
s2 = " II";
|
|
||||||
break;
|
|
||||||
case StellarClass::Lum_III:
|
|
||||||
s2 = " III";
|
|
||||||
break;
|
|
||||||
case StellarClass::Lum_IV:
|
|
||||||
s2 = " IV";
|
|
||||||
break;
|
|
||||||
case StellarClass::Lum_V:
|
|
||||||
s2 = " V";
|
|
||||||
break;
|
|
||||||
case StellarClass::Lum_VI:
|
|
||||||
s2 = " VI";
|
|
||||||
break;
|
|
||||||
default: break; // Do nothing, but prevent GCC4 warnings (Beware: potentially dangerous)
|
|
||||||
}
|
|
||||||
return fmt::sprintf("%c%c%s", s0, s1, s2);
|
|
||||||
}
|
|
||||||
|
|
||||||
return "?";
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
uint16_t
|
uint16_t
|
||||||
StellarClass::packV1() const
|
StellarClass::packV1() const
|
||||||
{
|
{
|
||||||
|
@ -238,14 +182,6 @@ StellarClass::unpackV2(uint16_t st)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
ostream& operator<<(ostream& os, const StellarClass& sc)
|
|
||||||
{
|
|
||||||
os << sc.str();
|
|
||||||
|
|
||||||
return os;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
bool operator<(const StellarClass& sc0, const StellarClass& sc1)
|
bool operator<(const StellarClass& sc0, const StellarClass& sc1)
|
||||||
{
|
{
|
||||||
return sc0.packV2() < sc1.packV2();
|
return sc0.packV2() < sc1.packV2();
|
||||||
|
@ -273,6 +209,7 @@ enum ParseState
|
||||||
LumClassVState,
|
LumClassVState,
|
||||||
LumClassIdashState,
|
LumClassIdashState,
|
||||||
LumClassIaState,
|
LumClassIaState,
|
||||||
|
LumClassIdashaState,
|
||||||
WDTypeState,
|
WDTypeState,
|
||||||
WDExtendedTypeState,
|
WDExtendedTypeState,
|
||||||
WDSubclassState,
|
WDSubclassState,
|
||||||
|
@ -482,6 +419,8 @@ StellarClass::parse(const string& st)
|
||||||
case 'V':
|
case 'V':
|
||||||
state = LumClassVState;
|
state = LumClassVState;
|
||||||
break;
|
break;
|
||||||
|
case ' ':
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
state = EndState;
|
state = EndState;
|
||||||
break;
|
break;
|
||||||
|
@ -535,7 +474,8 @@ StellarClass::parse(const string& st)
|
||||||
switch (c)
|
switch (c)
|
||||||
{
|
{
|
||||||
case 'a':
|
case 'a':
|
||||||
state = LumClassIaState;
|
state = LumClassIdashaState;
|
||||||
|
i++;
|
||||||
break;
|
break;
|
||||||
case 'b':
|
case 'b':
|
||||||
lumClass = StellarClass::Lum_Ib;
|
lumClass = StellarClass::Lum_Ib;
|
||||||
|
@ -549,6 +489,24 @@ StellarClass::parse(const string& st)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case LumClassIaState:
|
case LumClassIaState:
|
||||||
|
switch (c)
|
||||||
|
{
|
||||||
|
case '0':
|
||||||
|
lumClass = StellarClass::Lum_Ia0;
|
||||||
|
state = EndState;
|
||||||
|
break;
|
||||||
|
case '-':
|
||||||
|
state = LumClassIdashaState;
|
||||||
|
i++;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
lumClass = StellarClass::Lum_Ia;
|
||||||
|
state = EndState;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case LumClassIdashaState:
|
||||||
switch (c)
|
switch (c)
|
||||||
{
|
{
|
||||||
case '0':
|
case '0':
|
||||||
|
|
|
@ -35,9 +35,9 @@ public:
|
||||||
Spectral_G = 4,
|
Spectral_G = 4,
|
||||||
Spectral_K = 5,
|
Spectral_K = 5,
|
||||||
Spectral_M = 6,
|
Spectral_M = 6,
|
||||||
Spectral_R = 7, // superceded by class C
|
Spectral_R = 7, // superseded by class C
|
||||||
Spectral_S = 8,
|
Spectral_S = 8,
|
||||||
Spectral_N = 9, // superceded by class C
|
Spectral_N = 9, // superseded by class C
|
||||||
Spectral_WC = 10,
|
Spectral_WC = 10,
|
||||||
Spectral_WN = 11,
|
Spectral_WN = 11,
|
||||||
Spectral_WO = 12,
|
Spectral_WO = 12,
|
||||||
|
@ -98,8 +98,6 @@ public:
|
||||||
Color getApparentColor() const;
|
Color getApparentColor() const;
|
||||||
Color getApparentColor(StellarClass::SpectralClass sc) const;
|
Color getApparentColor(StellarClass::SpectralClass sc) const;
|
||||||
|
|
||||||
std::string str() const;
|
|
||||||
|
|
||||||
static StellarClass parse(const std::string&);
|
static StellarClass parse(const std::string&);
|
||||||
|
|
||||||
friend bool operator<(const StellarClass& sc0, const StellarClass& sc1);
|
friend bool operator<(const StellarClass& sc0, const StellarClass& sc1);
|
||||||
|
@ -123,8 +121,6 @@ private:
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
std::ostream& operator<<(std::ostream& os, const StellarClass& sc);
|
|
||||||
|
|
||||||
// A rough ordering of stellar classes, from 'early' to 'late' . . .
|
// A rough ordering of stellar classes, from 'early' to 'late' . . .
|
||||||
// Useful for organizing a list of stars by spectral class.
|
// Useful for organizing a list of stars by spectral class.
|
||||||
bool operator<(const StellarClass& sc0, const StellarClass& sc1);
|
bool operator<(const StellarClass& sc0, const StellarClass& sc1);
|
||||||
|
|
|
@ -80,6 +80,10 @@ if(ENABLE_FFMPEG)
|
||||||
target_link_libraries(celestia ${FFMPEG_LIBRARIES})
|
target_link_libraries(celestia ${FFMPEG_LIBRARIES})
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
if (HAVE_MESHOPTIMIZER)
|
||||||
|
target_link_libraries(celestia meshoptimizer::meshoptimizer)
|
||||||
|
endif()
|
||||||
|
|
||||||
install(TARGETS celestia LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} NAMELINK_SKIP)
|
install(TARGETS celestia LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} NAMELINK_SKIP)
|
||||||
|
|
||||||
add_subdirectory(glut)
|
add_subdirectory(glut)
|
||||||
|
|
|
@ -4053,14 +4053,10 @@ bool CelestiaCore::initRenderer()
|
||||||
|
|
||||||
if (font == nullptr)
|
if (font == nullptr)
|
||||||
cout << _("Error loading font; text will not be visible.\n");
|
cout << _("Error loading font; text will not be visible.\n");
|
||||||
else
|
|
||||||
font->buildTexture();
|
|
||||||
|
|
||||||
if (!config->titleFont.empty())
|
if (!config->titleFont.empty())
|
||||||
titleFont = LoadFontHelper(renderer, config->titleFont);
|
titleFont = LoadFontHelper(renderer, config->titleFont);
|
||||||
if (titleFont != nullptr)
|
if (titleFont == nullptr)
|
||||||
titleFont->buildTexture();
|
|
||||||
else
|
|
||||||
titleFont = font;
|
titleFont = font;
|
||||||
|
|
||||||
// Set up the overlay
|
// Set up the overlay
|
||||||
|
@ -4074,15 +4070,7 @@ bool CelestiaCore::initRenderer()
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
auto labelFont = LoadFontHelper(renderer, config->labelFont);
|
auto labelFont = LoadFontHelper(renderer, config->labelFont);
|
||||||
if (labelFont == nullptr)
|
renderer->setFont(Renderer::FontNormal, labelFont == nullptr ? font : labelFont);
|
||||||
{
|
|
||||||
renderer->setFont(Renderer::FontNormal, font);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
labelFont->buildTexture();
|
|
||||||
renderer->setFont(Renderer::FontNormal, labelFont);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
renderer->setFont(Renderer::FontLarge, titleFont);
|
renderer->setFont(Renderer::FontLarge, titleFont);
|
||||||
|
@ -4286,26 +4274,34 @@ CelestiaCore::TextDisplayHandler* CelestiaCore::getTextDisplayHandler() const
|
||||||
return textDisplayHandler;
|
return textDisplayHandler;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CelestiaCore::setFont(const fs::path& fontPath, int collectionIndex, int fontSize)
|
bool CelestiaCore::setFont(const fs::path& fontPath, int collectionIndex, int fontSize)
|
||||||
{
|
{
|
||||||
font = LoadTextureFont(renderer, fontPath, collectionIndex, fontSize);
|
if (auto f = LoadTextureFont(renderer, fontPath, collectionIndex, fontSize); f != nullptr)
|
||||||
if (font != nullptr)
|
{
|
||||||
font->buildTexture();
|
font = f;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CelestiaCore::setTitleFont(const fs::path& fontPath, int collectionIndex, int fontSize)
|
bool CelestiaCore::setTitleFont(const fs::path& fontPath, int collectionIndex, int fontSize)
|
||||||
{
|
{
|
||||||
titleFont = LoadTextureFont(renderer, fontPath, collectionIndex, fontSize);
|
if (auto f = LoadTextureFont(renderer, fontPath, collectionIndex, fontSize); f != nullptr)
|
||||||
if (titleFont != nullptr)
|
{
|
||||||
titleFont->buildTexture();
|
titleFont = f;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CelestiaCore::setRendererFont(const fs::path& fontPath, int collectionIndex, int fontSize, Renderer::FontStyle fontStyle)
|
bool CelestiaCore::setRendererFont(const fs::path& fontPath, int collectionIndex, int fontSize, Renderer::FontStyle fontStyle)
|
||||||
{
|
{
|
||||||
auto f = LoadTextureFont(renderer, fontPath, collectionIndex, fontSize);
|
if (auto f = LoadTextureFont(renderer, fontPath, collectionIndex, fontSize); f != nullptr)
|
||||||
if (f != nullptr)
|
{
|
||||||
f->buildTexture();
|
renderer->setFont(fontStyle, f);
|
||||||
renderer->setFont(fontStyle, f);
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CelestiaCore::clearFonts()
|
void CelestiaCore::clearFonts()
|
||||||
|
|
|
@ -368,9 +368,9 @@ class CelestiaCore // : public Watchable<CelestiaCore>
|
||||||
void setTextDisplayHandler(TextDisplayHandler*);
|
void setTextDisplayHandler(TextDisplayHandler*);
|
||||||
TextDisplayHandler* getTextDisplayHandler() const;
|
TextDisplayHandler* getTextDisplayHandler() const;
|
||||||
|
|
||||||
void setFont(const fs::path& fontPath, int collectionIndex, int fontSize);
|
bool setFont(const fs::path& fontPath, int collectionIndex, int fontSize);
|
||||||
void setTitleFont(const fs::path& fontPath, int collectionIndex, int fontSize);
|
bool setTitleFont(const fs::path& fontPath, int collectionIndex, int fontSize);
|
||||||
void setRendererFont(const fs::path& fontPath, int collectionIndex, int fontSize, Renderer::FontStyle fontStyle);
|
bool setRendererFont(const fs::path& fontPath, int collectionIndex, int fontSize, Renderer::FontStyle fontStyle);
|
||||||
void clearFonts();
|
void clearFonts();
|
||||||
|
|
||||||
void toggleReferenceMark(const std::string& refMark, Selection sel = Selection());
|
void toggleReferenceMark(const std::string& refMark, Selection sel = Selection());
|
||||||
|
|
|
@ -943,6 +943,11 @@ void actionRenderSpacecrafts(GtkToggleAction* action, AppData* app)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void actionRenderPlanetRings(GtkToggleAction* action, AppData* app)
|
||||||
|
{
|
||||||
|
setRenderFlag(app, Renderer::ShowPlanetRings, gtk_toggle_action_get_active(action));
|
||||||
|
}
|
||||||
|
|
||||||
void actionRenderRingShadows(GtkToggleAction* action, AppData* app)
|
void actionRenderRingShadows(GtkToggleAction* action, AppData* app)
|
||||||
{
|
{
|
||||||
setRenderFlag(app, Renderer::ShowRingShadows, gtk_toggle_action_get_active(action));
|
setRenderFlag(app, Renderer::ShowRingShadows, gtk_toggle_action_get_active(action));
|
||||||
|
@ -1270,9 +1275,9 @@ void resyncRenderActions(AppData* app)
|
||||||
|
|
||||||
/* Unlike the other interfaces, which go through each menu item and set
|
/* Unlike the other interfaces, which go through each menu item and set
|
||||||
* the corresponding renderFlag, we go the other way and set the menu
|
* the corresponding renderFlag, we go the other way and set the menu
|
||||||
* based on the renderFlag. Last one is ShowFadingOrbits. */
|
* based on the renderFlag. Last one is ShowPlanetRings. */
|
||||||
|
|
||||||
for (uint64_t i = Renderer::ShowStars; i <= Renderer::ShowFadingOrbits; i *= 2)
|
for (uint64_t i = Renderer::ShowStars; i <= Renderer::ShowPlanetRings; i *= 2)
|
||||||
{
|
{
|
||||||
switch (i)
|
switch (i)
|
||||||
{
|
{
|
||||||
|
@ -1294,6 +1299,7 @@ void resyncRenderActions(AppData* app)
|
||||||
case Renderer::ShowAtmospheres: actionName = "RenderAtmospheres"; break;
|
case Renderer::ShowAtmospheres: actionName = "RenderAtmospheres"; break;
|
||||||
case Renderer::ShowSmoothLines: actionName = "RenderAA"; break;
|
case Renderer::ShowSmoothLines: actionName = "RenderAA"; break;
|
||||||
case Renderer::ShowEclipseShadows: actionName = "RenderEclipseShadows"; break;
|
case Renderer::ShowEclipseShadows: actionName = "RenderEclipseShadows"; break;
|
||||||
|
case Renderer::ShowPlanetRings: actionName = "RenderPlanetRings"; break;
|
||||||
case Renderer::ShowRingShadows: actionName = "RenderRingShadows"; break;
|
case Renderer::ShowRingShadows: actionName = "RenderRingShadows"; break;
|
||||||
case Renderer::ShowBoundaries: actionName = "RenderConstellationBoundaries"; break;
|
case Renderer::ShowBoundaries: actionName = "RenderConstellationBoundaries"; break;
|
||||||
case Renderer::ShowAutoMag: actionName = "RenderAutoMagnitude"; break;
|
case Renderer::ShowAutoMag: actionName = "RenderAutoMagnitude"; break;
|
||||||
|
@ -1317,7 +1323,7 @@ void resyncRenderActions(AppData* app)
|
||||||
action = gtk_action_group_get_action(app->agRender, actionName);
|
action = gtk_action_group_get_action(app->agRender, actionName);
|
||||||
|
|
||||||
/* The current i anded with the renderFlags gives state of flag */
|
/* The current i anded with the renderFlags gives state of flag */
|
||||||
gtk_toggle_action_set_active(GTK_TOGGLE_ACTION(action), (i & rf));
|
gtk_toggle_action_set_active(GTK_TOGGLE_ACTION(action), (i & rf) != 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -96,6 +96,7 @@ void actionRenderMinorMoons(GtkToggleAction*, AppData*);
|
||||||
void actionRenderAsteroids(GtkToggleAction*, AppData*);
|
void actionRenderAsteroids(GtkToggleAction*, AppData*);
|
||||||
void actionRenderComets(GtkToggleAction*, AppData*);
|
void actionRenderComets(GtkToggleAction*, AppData*);
|
||||||
void actionRenderSpacecrafts(GtkToggleAction*, AppData*);
|
void actionRenderSpacecrafts(GtkToggleAction*, AppData*);
|
||||||
|
void actionRenderPlanetRings(GtkToggleAction*, AppData*);
|
||||||
void actionRenderRingShadows(GtkToggleAction*, AppData*);
|
void actionRenderRingShadows(GtkToggleAction*, AppData*);
|
||||||
void actionRenderStars(GtkToggleAction*, AppData*);
|
void actionRenderStars(GtkToggleAction*, AppData*);
|
||||||
|
|
||||||
|
|
|
@ -58,6 +58,7 @@
|
||||||
<menuitem action='RenderAsteroids'/>
|
<menuitem action='RenderAsteroids'/>
|
||||||
<menuitem action='RenderComets'/>
|
<menuitem action='RenderComets'/>
|
||||||
<menuitem action='RenderSpacecrafts'/>
|
<menuitem action='RenderSpacecrafts'/>
|
||||||
|
<menuitem action='RenderPlanetRings'/>
|
||||||
<menuitem action='RenderRingShadows'/>
|
<menuitem action='RenderRingShadows'/>
|
||||||
<menuitem action='RenderStars'/>
|
<menuitem action='RenderStars'/>
|
||||||
</menu>
|
</menu>
|
||||||
|
|
|
@ -149,9 +149,15 @@ static void addPlanetarySystemToTree(const PlanetarySystem* sys, GtkTreeStore* s
|
||||||
case Body::Planet:
|
case Body::Planet:
|
||||||
type = "Planet";
|
type = "Planet";
|
||||||
break;
|
break;
|
||||||
|
case Body::DwarfPlanet:
|
||||||
|
type = "Dwarf Planet";
|
||||||
|
break;
|
||||||
case Body::Moon:
|
case Body::Moon:
|
||||||
type = "Moon";
|
type = "Moon";
|
||||||
break;
|
break;
|
||||||
|
case Body::MinorMoon:
|
||||||
|
type = "Minor Moon";
|
||||||
|
break;
|
||||||
case Body::Asteroid:
|
case Body::Asteroid:
|
||||||
type = "Asteroid";
|
type = "Asteroid";
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -155,6 +155,7 @@ void applySettingsFileMain(AppData* app, GKeyFile* file)
|
||||||
getFlag64(file, &rf, Renderer::ShowAtmospheres, "RenderFlags", "atmospheres", &errors);
|
getFlag64(file, &rf, Renderer::ShowAtmospheres, "RenderFlags", "atmospheres", &errors);
|
||||||
getFlag64(file, &rf, Renderer::ShowSmoothLines, "RenderFlags", "smoothLines", &errors);
|
getFlag64(file, &rf, Renderer::ShowSmoothLines, "RenderFlags", "smoothLines", &errors);
|
||||||
getFlag64(file, &rf, Renderer::ShowEclipseShadows, "RenderFlags", "eclipseShadows", &errors);
|
getFlag64(file, &rf, Renderer::ShowEclipseShadows, "RenderFlags", "eclipseShadows", &errors);
|
||||||
|
getFlag64(file, &rf, Renderer::ShowPlanetRings, "RenderFlags", "planetRings", &errors);
|
||||||
getFlag64(file, &rf, Renderer::ShowRingShadows, "RenderFlags", "ringShadows", &errors);
|
getFlag64(file, &rf, Renderer::ShowRingShadows, "RenderFlags", "ringShadows", &errors);
|
||||||
getFlag64(file, &rf, Renderer::ShowBoundaries, "RenderFlags", "boundaries", &errors);
|
getFlag64(file, &rf, Renderer::ShowBoundaries, "RenderFlags", "boundaries", &errors);
|
||||||
getFlag64(file, &rf, Renderer::ShowAutoMag, "RenderFlags", "autoMag", &errors);
|
getFlag64(file, &rf, Renderer::ShowAutoMag, "RenderFlags", "autoMag", &errors);
|
||||||
|
@ -267,6 +268,7 @@ void saveSettingsFile(AppData* app)
|
||||||
g_key_file_set_boolean(file, "RenderFlags", "atmospheres", (rf & Renderer::ShowAtmospheres) != 0);
|
g_key_file_set_boolean(file, "RenderFlags", "atmospheres", (rf & Renderer::ShowAtmospheres) != 0);
|
||||||
g_key_file_set_boolean(file, "RenderFlags", "smoothLines", (rf & Renderer::ShowSmoothLines) != 0);
|
g_key_file_set_boolean(file, "RenderFlags", "smoothLines", (rf & Renderer::ShowSmoothLines) != 0);
|
||||||
g_key_file_set_boolean(file, "RenderFlags", "eclipseShadows", (rf & Renderer::ShowEclipseShadows) != 0);
|
g_key_file_set_boolean(file, "RenderFlags", "eclipseShadows", (rf & Renderer::ShowEclipseShadows) != 0);
|
||||||
|
g_key_file_set_boolean(file, "RenderFlags", "planetRings", (rf & Renderer::ShowPlanetRings) != 0);
|
||||||
g_key_file_set_boolean(file, "RenderFlags", "ringShadows", (rf & Renderer::ShowRingShadows) != 0);
|
g_key_file_set_boolean(file, "RenderFlags", "ringShadows", (rf & Renderer::ShowRingShadows) != 0);
|
||||||
g_key_file_set_boolean(file, "RenderFlags", "boundaries", (rf & Renderer::ShowBoundaries) != 0);
|
g_key_file_set_boolean(file, "RenderFlags", "boundaries", (rf & Renderer::ShowBoundaries) != 0);
|
||||||
g_key_file_set_boolean(file, "RenderFlags", "autoMag", (rf & Renderer::ShowAutoMag) != 0);
|
g_key_file_set_boolean(file, "RenderFlags", "autoMag", (rf & Renderer::ShowAutoMag) != 0);
|
||||||
|
|
|
@ -155,6 +155,7 @@ static const GtkToggleActionEntry actionsRenderFlags[] = {
|
||||||
{ "RenderComets", NULL, "Comets", NULL, NULL, G_CALLBACK(actionRenderComets), FALSE },
|
{ "RenderComets", NULL, "Comets", NULL, NULL, G_CALLBACK(actionRenderComets), FALSE },
|
||||||
{ "RenderAsteroids", NULL, "Asteroids", NULL, NULL, G_CALLBACK(actionRenderAsteroids), FALSE },
|
{ "RenderAsteroids", NULL, "Asteroids", NULL, NULL, G_CALLBACK(actionRenderAsteroids), FALSE },
|
||||||
{ "RenderSpacecrafts", NULL, "Spacecraft", NULL, NULL, G_CALLBACK(actionRenderSpacecrafts), FALSE },
|
{ "RenderSpacecrafts", NULL, "Spacecraft", NULL, NULL, G_CALLBACK(actionRenderSpacecrafts), FALSE },
|
||||||
|
{ "RenderPlanetRings", NULL, "Planet Rings", NULL, NULL, G_CALLBACK(actionRenderPlanetRings), FALSE },
|
||||||
{ "RenderRingShadows", NULL, "Ring Shadows", NULL, NULL, G_CALLBACK(actionRenderRingShadows), FALSE },
|
{ "RenderRingShadows", NULL, "Ring Shadows", NULL, NULL, G_CALLBACK(actionRenderRingShadows), FALSE },
|
||||||
{ "RenderStars", NULL, "Stars", NULL, NULL, G_CALLBACK(actionRenderStars), FALSE },
|
{ "RenderStars", NULL, "Stars", NULL, NULL, G_CALLBACK(actionRenderStars), FALSE },
|
||||||
};
|
};
|
||||||
|
|
|
@ -10,7 +10,11 @@ if(APPLE AND EXISTS /usr/local/opt/qt5)
|
||||||
list(APPEND CMAKE_PREFIX_PATH "/usr/local/opt/qt5")
|
list(APPEND CMAKE_PREFIX_PATH "/usr/local/opt/qt5")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
find_package(Qt5 COMPONENTS Widgets OpenGL CONFIG REQUIRED)
|
if(USE_QT6)
|
||||||
|
find_package(Qt6 COMPONENTS Widgets OpenGLWidgets Core5Compat CONFIG REQUIRED)
|
||||||
|
else()
|
||||||
|
find_package(Qt5 COMPONENTS Widgets CONFIG REQUIRED)
|
||||||
|
endif()
|
||||||
|
|
||||||
set(QT_SOURCES
|
set(QT_SOURCES
|
||||||
qtappwin.cpp
|
qtappwin.cpp
|
||||||
|
@ -58,7 +62,11 @@ set(CMAKE_AUTOMOC ON)
|
||||||
set(CMAKE_AUTOUIC ON)
|
set(CMAKE_AUTOUIC ON)
|
||||||
# Find includes in corresponding build directories
|
# Find includes in corresponding build directories
|
||||||
set(CMAKE_INCLUDE_CURRENT_DIR ON)
|
set(CMAKE_INCLUDE_CURRENT_DIR ON)
|
||||||
qt5_add_resources(RC_SRC "icons.qrc")
|
if(USE_QT6)
|
||||||
|
qt6_add_resources(RC_SRC "icons.qrc")
|
||||||
|
else()
|
||||||
|
qt5_add_resources(RC_SRC "icons.qrc")
|
||||||
|
endif()
|
||||||
|
|
||||||
if(WIN32)
|
if(WIN32)
|
||||||
set (RES celestia.rc)
|
set (RES celestia.rc)
|
||||||
|
@ -66,7 +74,11 @@ endif()
|
||||||
|
|
||||||
add_executable(celestia-qt WIN32 ${QT_SOURCES} ${RC_SRC} ${RES})
|
add_executable(celestia-qt WIN32 ${QT_SOURCES} ${RC_SRC} ${RES})
|
||||||
add_dependencies(celestia-qt celestia)
|
add_dependencies(celestia-qt celestia)
|
||||||
target_link_libraries(celestia-qt Qt5::Widgets Qt5::OpenGL celestia)
|
if(USE_QT6)
|
||||||
|
target_link_libraries(celestia-qt Qt6::Widgets Qt6::OpenGLWidgets Qt6::Core5Compat celestia)
|
||||||
|
else()
|
||||||
|
target_link_libraries(celestia-qt Qt5::Widgets celestia)
|
||||||
|
endif()
|
||||||
if(APPLE)
|
if(APPLE)
|
||||||
set_property(TARGET celestia-qt APPEND_STRING PROPERTY LINK_FLAGS " -framework CoreFoundation")
|
set_property(TARGET celestia-qt APPEND_STRING PROPERTY LINK_FLAGS " -framework CoreFoundation")
|
||||||
set_property(TARGET celestia-qt APPEND_STRING PROPERTY LINK_FLAGS " -framework CoreServices")
|
set_property(TARGET celestia-qt APPEND_STRING PROPERTY LINK_FLAGS " -framework CoreServices")
|
||||||
|
|
|
@ -271,12 +271,11 @@ void CelestiaAppWindow::init(const QString& qConfigFileName,
|
||||||
|
|
||||||
// Enable antialiasing if requested in the config file.
|
// Enable antialiasing if requested in the config file.
|
||||||
// TODO: Make this settable via the GUI
|
// TODO: Make this settable via the GUI
|
||||||
QGLFormat glformat = QGLFormat::defaultFormat();
|
QSurfaceFormat glformat = QSurfaceFormat::defaultFormat();
|
||||||
if (m_appCore->getConfig()->aaSamples > 1)
|
if (m_appCore->getConfig()->aaSamples > 1)
|
||||||
{
|
{
|
||||||
glformat.setSampleBuffers(true);
|
|
||||||
glformat.setSamples(m_appCore->getConfig()->aaSamples);
|
glformat.setSamples(m_appCore->getConfig()->aaSamples);
|
||||||
QGLFormat::setDefaultFormat(glformat);
|
QSurfaceFormat::setDefaultFormat(glformat);
|
||||||
}
|
}
|
||||||
|
|
||||||
glWidget = new CelestiaGlWidget(nullptr, "Celestia", m_appCore);
|
glWidget = new CelestiaGlWidget(nullptr, "Celestia", m_appCore);
|
||||||
|
@ -495,6 +494,7 @@ void CelestiaAppWindow::writeSettings()
|
||||||
QSettings settings;
|
QSettings settings;
|
||||||
|
|
||||||
settings.beginGroup("MainWindow");
|
settings.beginGroup("MainWindow");
|
||||||
|
#ifndef _WIN32
|
||||||
if (isFullScreen())
|
if (isFullScreen())
|
||||||
{
|
{
|
||||||
// Save the normal size, not the fullscreen size; fullscreen will
|
// Save the normal size, not the fullscreen size; fullscreen will
|
||||||
|
@ -503,6 +503,7 @@ void CelestiaAppWindow::writeSettings()
|
||||||
settings.setValue("Pos", normalGeometry().topLeft());
|
settings.setValue("Pos", normalGeometry().topLeft());
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
#endif
|
||||||
{
|
{
|
||||||
settings.setValue("Size", size());
|
settings.setValue("Size", size());
|
||||||
settings.setValue("Pos", pos());
|
settings.setValue("Pos", pos());
|
||||||
|
@ -591,7 +592,7 @@ void CelestiaAppWindow::saveBookmarks()
|
||||||
void CelestiaAppWindow::celestia_tick()
|
void CelestiaAppWindow::celestia_tick()
|
||||||
{
|
{
|
||||||
m_appCore->tick();
|
m_appCore->tick();
|
||||||
glWidget->updateGL();
|
glWidget->update();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -621,8 +622,8 @@ void CelestiaAppWindow::slotGrabImage()
|
||||||
|
|
||||||
if (!saveAsName.isEmpty())
|
if (!saveAsName.isEmpty())
|
||||||
{
|
{
|
||||||
m_appCore->saveScreenShot(saveAsName.toStdString());
|
QImage grabbedImage = glWidget->grabFramebuffer();
|
||||||
settings.setValue("GrabImageDir", QFileInfo(saveAsName).absolutePath());
|
grabbedImage.save(saveAsName);
|
||||||
}
|
}
|
||||||
settings.endGroup();
|
settings.endGroup();
|
||||||
}
|
}
|
||||||
|
@ -750,17 +751,9 @@ static QImage::Format toQFormat(PixelFormat format)
|
||||||
|
|
||||||
void CelestiaAppWindow::slotCopyImage()
|
void CelestiaAppWindow::slotCopyImage()
|
||||||
{
|
{
|
||||||
//glWidget->repaint();
|
QImage grabbedImage = glWidget->grabFramebuffer();
|
||||||
std::array<int, 4> viewport;
|
QApplication::clipboard()->setImage(grabbedImage);
|
||||||
celestia::PixelFormat format;
|
m_appCore->flash(_("Captured screen shot to clipboard"));
|
||||||
m_appCore->getCaptureInfo(viewport, format);
|
|
||||||
QImage grabbedImage = QImage(viewport[2], viewport[3],
|
|
||||||
toQFormat(format));
|
|
||||||
if (m_appCore->captureImage(grabbedImage.bits(), viewport, format))
|
|
||||||
{
|
|
||||||
QApplication::clipboard()->setImage(grabbedImage);
|
|
||||||
m_appCore->flash(_("Captured screen shot to clipboard"));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -944,7 +937,13 @@ void CelestiaAppWindow::slotShowTimeDialog()
|
||||||
|
|
||||||
void CelestiaAppWindow::slotToggleFullScreen()
|
void CelestiaAppWindow::slotToggleFullScreen()
|
||||||
{
|
{
|
||||||
|
#ifdef _WIN32
|
||||||
|
// On Windows, we don't actually use showFullscreen(), so use the presence
|
||||||
|
// of the FramelessWindowHint as an alternative to isFullScreen()
|
||||||
|
if (windowFlags().testFlag(Qt::FramelessWindowHint))
|
||||||
|
#else
|
||||||
if (isFullScreen())
|
if (isFullScreen())
|
||||||
|
#endif
|
||||||
{
|
{
|
||||||
switchToNormal();
|
switchToNormal();
|
||||||
}
|
}
|
||||||
|
@ -966,7 +965,13 @@ void CelestiaAppWindow::switchToNormal()
|
||||||
{
|
{
|
||||||
// Switch to window
|
// Switch to window
|
||||||
menuBar()->setFixedHeight(menuBar()->sizeHint().height());
|
menuBar()->setFixedHeight(menuBar()->sizeHint().height());
|
||||||
|
#ifdef _WIN32
|
||||||
|
Qt::WindowFlags flags = windowFlags().setFlag(Qt::FramelessWindowHint, false);
|
||||||
|
setWindowFlags(flags);
|
||||||
|
show();
|
||||||
|
#else
|
||||||
showNormal();
|
showNormal();
|
||||||
|
#endif
|
||||||
|
|
||||||
QSettings settings;
|
QSettings settings;
|
||||||
settings.beginGroup("MainWindow");
|
settings.beginGroup("MainWindow");
|
||||||
|
@ -994,7 +999,31 @@ void CelestiaAppWindow::switchToFullscreen()
|
||||||
timeToolBar->setVisible(false);
|
timeToolBar->setVisible(false);
|
||||||
guidesToolBar->setVisible(false);
|
guidesToolBar->setVisible(false);
|
||||||
m_bookmarkToolBar->setVisible(false);
|
m_bookmarkToolBar->setVisible(false);
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
// On Windows, we can't use showFullScreen as this prevents widgets
|
||||||
|
// (e.g. context menus) being drawn on top of the window. Instead, draw a
|
||||||
|
// borderless window 1 pixel wider than the screen.
|
||||||
|
QRect newGeometry = QApplication::primaryScreen()->geometry();
|
||||||
|
int intersectionArea = 0;
|
||||||
|
foreach (const QScreen *screen, QGuiApplication::screens())
|
||||||
|
{
|
||||||
|
QRect intersection = screen->geometry().intersected(geometry());
|
||||||
|
int newIntersectionArea = intersection.width() * intersection.height();
|
||||||
|
if (newIntersectionArea > intersectionArea)
|
||||||
|
{
|
||||||
|
newGeometry = screen->geometry();
|
||||||
|
intersectionArea = newIntersectionArea;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Qt::WindowFlags flags = windowFlags().setFlag(Qt::FramelessWindowHint, true);
|
||||||
|
setWindowFlags(flags);
|
||||||
|
show();
|
||||||
|
setGeometry(newGeometry.adjusted(-1, -1, 1, 1));
|
||||||
|
#else
|
||||||
showFullScreen();
|
showFullScreen();
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1030,7 +1059,7 @@ void CelestiaAppWindow::slotAddBookmark()
|
||||||
appState.captureState();
|
appState.captureState();
|
||||||
|
|
||||||
// Capture the current frame buffer to use as a bookmark icon.
|
// Capture the current frame buffer to use as a bookmark icon.
|
||||||
QImage grabbedImage = glWidget->grabFrameBuffer();
|
QImage grabbedImage = glWidget->grabFramebuffer();
|
||||||
int width = grabbedImage.width();
|
int width = grabbedImage.width();
|
||||||
int height = grabbedImage.height();
|
int height = grabbedImage.height();
|
||||||
|
|
||||||
|
@ -1593,7 +1622,7 @@ void CelestiaAppWindow::setCustomFPS()
|
||||||
|
|
||||||
void CelestiaAppWindow::requestContextMenu(float x, float y, Selection sel)
|
void CelestiaAppWindow::requestContextMenu(float x, float y, Selection sel)
|
||||||
{
|
{
|
||||||
float scale = devicePixelRatioF();
|
qreal scale = devicePixelRatioF();
|
||||||
SelectionPopup* menu = new SelectionPopup(sel, m_appCore, this);
|
SelectionPopup* menu = new SelectionPopup(sel, m_appCore, this);
|
||||||
connect(menu, SIGNAL(selectionInfoRequested(Selection&)),
|
connect(menu, SIGNAL(selectionInfoRequested(Selection&)),
|
||||||
this, SLOT(slotShowObjectInfo(Selection&)));
|
this, SLOT(slotShowObjectInfo(Selection&)));
|
||||||
|
|
|
@ -60,7 +60,7 @@ const unsigned int DEFAULT_TEXTURE_RESOLUTION = medres;
|
||||||
|
|
||||||
|
|
||||||
CelestiaGlWidget::CelestiaGlWidget(QWidget* parent, const char* /* name */, CelestiaCore* core) :
|
CelestiaGlWidget::CelestiaGlWidget(QWidget* parent, const char* /* name */, CelestiaCore* core) :
|
||||||
QGLWidget(parent)
|
QOpenGLWidget(parent)
|
||||||
{
|
{
|
||||||
setFocusPolicy(Qt::ClickFocus);
|
setFocusPolicy(Qt::ClickFocus);
|
||||||
|
|
||||||
|
@ -96,7 +96,7 @@ void CelestiaGlWidget::initializeGL()
|
||||||
using namespace celestia;
|
using namespace celestia;
|
||||||
if (!gl::init(appCore->getConfig()->ignoreGLExtensions) || !gl::checkVersion(gl::GL_2_1))
|
if (!gl::init(appCore->getConfig()->ignoreGLExtensions) || !gl::checkVersion(gl::GL_2_1))
|
||||||
{
|
{
|
||||||
QMessageBox::critical(0, "Celestia", _("Celestia was unable to initialize OpenGL 2.1."));
|
QMessageBox::critical(0, "Celestia", _("Celestia was unable to initialize OpenGL 2.1."));
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -133,15 +133,18 @@ void CelestiaGlWidget::initializeGL()
|
||||||
|
|
||||||
void CelestiaGlWidget::resizeGL(int w, int h)
|
void CelestiaGlWidget::resizeGL(int w, int h)
|
||||||
{
|
{
|
||||||
appCore->resize(w, h);
|
qreal scale = devicePixelRatioF();
|
||||||
|
auto width = static_cast<int>(w * scale);
|
||||||
|
auto height = static_cast<int>(h * scale);
|
||||||
|
appCore->resize(width, height);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void CelestiaGlWidget::mouseMoveEvent(QMouseEvent* m)
|
void CelestiaGlWidget::mouseMoveEvent(QMouseEvent* m)
|
||||||
{
|
{
|
||||||
float scale = devicePixelRatioF();
|
qreal scale = devicePixelRatioF();
|
||||||
int x = (int)(m->x() * scale);
|
auto x = static_cast<int>(m->x() * scale);
|
||||||
int y = (int)(m->y() * scale);
|
auto y = static_cast<int>(m->y() * scale);
|
||||||
|
|
||||||
int buttons = 0;
|
int buttons = 0;
|
||||||
if (m->buttons() & LeftButton)
|
if (m->buttons() & LeftButton)
|
||||||
|
@ -198,9 +201,9 @@ void CelestiaGlWidget::mouseMoveEvent(QMouseEvent* m)
|
||||||
|
|
||||||
void CelestiaGlWidget::mousePressEvent( QMouseEvent* m )
|
void CelestiaGlWidget::mousePressEvent( QMouseEvent* m )
|
||||||
{
|
{
|
||||||
float scale = devicePixelRatioF();
|
qreal scale = devicePixelRatioF();
|
||||||
int x = (int)(m->x() * scale);
|
auto x = static_cast<int>(m->x() * scale);
|
||||||
int y = (int)(m->y() * scale);
|
auto y = static_cast<int>(m->y() * scale);
|
||||||
|
|
||||||
if (m->button() == LeftButton)
|
if (m->button() == LeftButton)
|
||||||
appCore->mouseButtonDown(x, y, CelestiaCore::LeftButton);
|
appCore->mouseButtonDown(x, y, CelestiaCore::LeftButton);
|
||||||
|
@ -213,9 +216,9 @@ void CelestiaGlWidget::mousePressEvent( QMouseEvent* m )
|
||||||
|
|
||||||
void CelestiaGlWidget::mouseReleaseEvent( QMouseEvent* m )
|
void CelestiaGlWidget::mouseReleaseEvent( QMouseEvent* m )
|
||||||
{
|
{
|
||||||
float scale = devicePixelRatioF();
|
qreal scale = devicePixelRatioF();
|
||||||
int x = (int)(m->x() * scale);
|
auto x = static_cast<int>(m->x() * scale);
|
||||||
int y = (int)(m->y() * scale);
|
auto y = static_cast<int>(m->y() * scale);
|
||||||
|
|
||||||
if (m->button() == LeftButton)
|
if (m->button() == LeftButton)
|
||||||
{
|
{
|
||||||
|
|
|
@ -14,7 +14,7 @@
|
||||||
#ifndef QTGLWIDGET_H
|
#ifndef QTGLWIDGET_H
|
||||||
#define QTGLWIDGET_H
|
#define QTGLWIDGET_H
|
||||||
|
|
||||||
#include <QGLWidget>
|
#include <QOpenGLWidget>
|
||||||
|
|
||||||
#include "celestia/celestiacore.h"
|
#include "celestia/celestiacore.h"
|
||||||
#include "celengine/simulation.h"
|
#include "celengine/simulation.h"
|
||||||
|
@ -26,7 +26,7 @@
|
||||||
*@author Christophe Teyssier
|
*@author Christophe Teyssier
|
||||||
*/
|
*/
|
||||||
|
|
||||||
class CelestiaGlWidget : public QGLWidget, public CelestiaCore::CursorHandler
|
class CelestiaGlWidget : public QOpenGLWidget, public CelestiaCore::CursorHandler
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
|
|
|
@ -28,7 +28,6 @@
|
||||||
#include <QLibraryInfo>
|
#include <QLibraryInfo>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include "qtappwin.h"
|
#include "qtappwin.h"
|
||||||
#include <qtextcodec.h>
|
|
||||||
#include <fmt/printf.h>
|
#include <fmt/printf.h>
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
|
@ -1,9 +1,20 @@
|
||||||
//#define GL_ES
|
// sdlmain.cpp
|
||||||
|
//
|
||||||
|
// Copyright (C) 2020-present, the Celestia Development Team
|
||||||
|
//
|
||||||
|
// This program is free software; you can redistribute it and/or
|
||||||
|
// modify it under the terms of the GNU General Public License
|
||||||
|
// as published by the Free Software Foundation; either version 2
|
||||||
|
// of the License, or (at your option) any later version.
|
||||||
|
|
||||||
#include <cctype>
|
#include <cctype>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
#include <string_view>
|
||||||
|
#include <system_error>
|
||||||
#include <fmt/printf.h>
|
#include <fmt/printf.h>
|
||||||
|
#include <celcompat/filesystem.h>
|
||||||
#include <celengine/glsupport.h>
|
#include <celengine/glsupport.h>
|
||||||
#include <celutil/gettext.h>
|
#include <celutil/gettext.h>
|
||||||
#include <celutil/tzutil.h>
|
#include <celutil/tzutil.h>
|
||||||
|
@ -13,8 +24,8 @@
|
||||||
#else
|
#else
|
||||||
#include <SDL_opengl.h>
|
#include <SDL_opengl.h>
|
||||||
#endif
|
#endif
|
||||||
#include <unistd.h>
|
|
||||||
#include <celestia/celestiacore.h>
|
#include <celestia/celestiacore.h>
|
||||||
|
#include <celestia/url.h>
|
||||||
|
|
||||||
namespace celestia
|
namespace celestia
|
||||||
{
|
{
|
||||||
|
@ -36,7 +47,7 @@ class SDL_Application
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
SDL_Application() = delete;
|
SDL_Application() = delete;
|
||||||
SDL_Application(const std::string name, int w, int h) :
|
SDL_Application(std::string_view name, int w, int h) :
|
||||||
m_appName { name },
|
m_appName { name },
|
||||||
m_windowWidth { w },
|
m_windowWidth { w },
|
||||||
m_windowHeight { h }
|
m_windowHeight { h }
|
||||||
|
@ -44,13 +55,13 @@ class SDL_Application
|
||||||
}
|
}
|
||||||
~SDL_Application();
|
~SDL_Application();
|
||||||
|
|
||||||
static std::shared_ptr<SDL_Application> init(const std::string, int, int);
|
static std::shared_ptr<SDL_Application> init(std::string_view, int, int);
|
||||||
|
|
||||||
bool createOpenGLWindow();
|
bool createOpenGLWindow();
|
||||||
|
|
||||||
bool initCelestiaCore();
|
bool initCelestiaCore();
|
||||||
void run();
|
void run();
|
||||||
const char* getError() const;
|
std::string_view getError() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void display();
|
void display();
|
||||||
|
@ -67,6 +78,9 @@ class SDL_Application
|
||||||
|
|
||||||
// aux functions
|
// aux functions
|
||||||
void toggleFullscreen();
|
void toggleFullscreen();
|
||||||
|
void copyURL();
|
||||||
|
void pasteURL();
|
||||||
|
void configure() const;
|
||||||
|
|
||||||
// state variables
|
// state variables
|
||||||
std::string m_appName;
|
std::string m_appName;
|
||||||
|
@ -84,7 +98,7 @@ class SDL_Application
|
||||||
};
|
};
|
||||||
|
|
||||||
std::shared_ptr<SDL_Application>
|
std::shared_ptr<SDL_Application>
|
||||||
SDL_Application::init(const std::string name, int w, int h)
|
SDL_Application::init(std::string_view name, int w, int h)
|
||||||
{
|
{
|
||||||
if (SDL_Init(SDL_INIT_VIDEO) < 0)
|
if (SDL_Init(SDL_INIT_VIDEO) < 0)
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
@ -96,7 +110,7 @@ SDL_Application::init(const std::string name, int w, int h)
|
||||||
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 2);
|
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 2);
|
||||||
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 0);
|
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 0);
|
||||||
#endif
|
#endif
|
||||||
return std::shared_ptr<SDL_Application>(new SDL_Application(std::move(name), w, h));
|
return std::make_shared<SDL_Application>(name, w, h);
|
||||||
}
|
}
|
||||||
|
|
||||||
SDL_Application::~SDL_Application()
|
SDL_Application::~SDL_Application()
|
||||||
|
@ -132,7 +146,7 @@ SDL_Application::createOpenGLWindow()
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
const char*
|
std::string_view
|
||||||
SDL_Application::getError() const
|
SDL_Application::getError() const
|
||||||
{
|
{
|
||||||
return SDL_GetError();
|
return SDL_GetError();
|
||||||
|
@ -154,11 +168,22 @@ SDL_Application::initCelestiaCore()
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
SDL_Application::configure() const
|
||||||
|
{
|
||||||
|
auto *renderer = m_appCore->getRenderer();
|
||||||
|
const auto *config = m_appCore->getConfig();
|
||||||
|
|
||||||
|
renderer->setRenderFlags(Renderer::DefaultRenderFlags);
|
||||||
|
renderer->setShadowMapSize(config->ShadowMapSize);
|
||||||
|
renderer->setSolarSystemMaxDistance(config->SolarSystemMaxDistance);
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
SDL_Application::run()
|
SDL_Application::run()
|
||||||
{
|
{
|
||||||
m_appCore->initRenderer();
|
m_appCore->initRenderer();
|
||||||
m_appCore->getRenderer()->setRenderFlags(Renderer::DefaultRenderFlags);
|
configure();
|
||||||
m_appCore->start();
|
m_appCore->start();
|
||||||
|
|
||||||
std::string tzName;
|
std::string tzName;
|
||||||
|
@ -294,8 +319,18 @@ SDL_Application::handleKeyPressEvent(const SDL_KeyboardEvent &event)
|
||||||
int k = tolower(key);
|
int k = tolower(key);
|
||||||
if (k >= 'a' && k <= 'z')
|
if (k >= 'a' && k <= 'z')
|
||||||
{
|
{
|
||||||
key = k + 1 - 'a';
|
switch (k)
|
||||||
m_appCore->charEntered(key, mod);
|
{
|
||||||
|
case 'c':
|
||||||
|
copyURL();
|
||||||
|
break;
|
||||||
|
case 'v':
|
||||||
|
pasteURL();
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
key = k + 1 - 'a';
|
||||||
|
m_appCore->charEntered(key, mod);
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
mod |= CelestiaCore::ControlKey;
|
mod |= CelestiaCore::ControlKey;
|
||||||
|
@ -471,6 +506,29 @@ SDL_Application::toggleFullscreen()
|
||||||
m_fullscreen = true;
|
m_fullscreen = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
SDL_Application::copyURL()
|
||||||
|
{
|
||||||
|
CelestiaState appState(m_appCore);
|
||||||
|
appState.captureState();
|
||||||
|
|
||||||
|
if (SDL_SetClipboardText(Url(appState).getAsString().c_str()) == 0)
|
||||||
|
m_appCore->flash(_("Copied URL"));
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
SDL_Application::pasteURL()
|
||||||
|
{
|
||||||
|
if (SDL_HasClipboardText() != SDL_TRUE)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// on error SDL_GetClipboardText returns a new empty string
|
||||||
|
char *str = SDL_GetClipboardText(); // don't add const due to SDL_free
|
||||||
|
if (*str != '\0' && m_appCore->goToUrl(str))
|
||||||
|
m_appCore->flash(_("Pasting URL"));
|
||||||
|
|
||||||
|
SDL_free(str);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -484,7 +542,8 @@ FatalError(const std::string &message)
|
||||||
std::cerr << message << std::endl;
|
std::cerr << message << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
void DumpGLInfo()
|
void
|
||||||
|
DumpGLInfo()
|
||||||
{
|
{
|
||||||
const char* s;
|
const char* s;
|
||||||
s = reinterpret_cast<const char*>(glGetString(GL_VERSION));
|
s = reinterpret_cast<const char*>(glGetString(GL_VERSION));
|
||||||
|
@ -504,10 +563,8 @@ void DumpGLInfo()
|
||||||
std::cout << s << '\n';
|
std::cout << s << '\n';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int
|
||||||
using namespace celestia;
|
sdlmain(int /* argc */, char ** /* argv */)
|
||||||
|
|
||||||
int main(int argc, char **argv)
|
|
||||||
{
|
{
|
||||||
setlocale(LC_ALL, "");
|
setlocale(LC_ALL, "");
|
||||||
setlocale(LC_NUMERIC, "C");
|
setlocale(LC_NUMERIC, "C");
|
||||||
|
@ -515,10 +572,16 @@ int main(int argc, char **argv)
|
||||||
bind_textdomain_codeset(PACKAGE, "UTF-8");
|
bind_textdomain_codeset(PACKAGE, "UTF-8");
|
||||||
textdomain(PACKAGE);
|
textdomain(PACKAGE);
|
||||||
|
|
||||||
if (chdir(CONFIG_DATA_DIR) == -1)
|
const char *dataDir = getenv("CELESTIA_DATA_DIR");
|
||||||
|
if (dataDir == nullptr)
|
||||||
|
dataDir = CONFIG_DATA_DIR;
|
||||||
|
|
||||||
|
std::error_code ec;
|
||||||
|
fs::current_path(dataDir, ec);
|
||||||
|
if (ec)
|
||||||
{
|
{
|
||||||
FatalError(fmt::sprintf("Cannot chdir to '%s', probably due to improper installation",
|
FatalError(fmt::sprintf("Cannot chdir to '%s', probably due to improper installation",
|
||||||
CONFIG_DATA_DIR));
|
dataDir));
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -557,3 +620,10 @@ int main(int argc, char **argv)
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
int
|
||||||
|
main(int argc, char **argv)
|
||||||
|
{
|
||||||
|
return celestia::sdlmain(argc, argv);
|
||||||
|
}
|
||||||
|
|
|
@ -39,6 +39,8 @@ set(WIN32_HEADERS
|
||||||
winviewoptsdlg.h
|
winviewoptsdlg.h
|
||||||
)
|
)
|
||||||
|
|
||||||
|
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} /MANIFEST:NO")
|
||||||
|
|
||||||
add_library(resources OBJECT res/celestia.rc)
|
add_library(resources OBJECT res/celestia.rc)
|
||||||
target_include_directories(resources PRIVATE "${CMAKE_SOURCE_DIR}/src/celestia/win32/res")
|
target_include_directories(resources PRIVATE "${CMAKE_SOURCE_DIR}/src/celestia/win32/res")
|
||||||
set(RESOURCES $<TARGET_OBJECTS:resources>)
|
set(RESOURCES $<TARGET_OBJECTS:resources>)
|
||||||
|
|
|
@ -2,8 +2,10 @@
|
||||||
//
|
//
|
||||||
|
|
||||||
#include "odmenu.h"
|
#include "odmenu.h"
|
||||||
|
#include "winuiutils.h"
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
using namespace celestia::win32;
|
||||||
|
|
||||||
ODMenu::ODMenu()
|
ODMenu::ODMenu()
|
||||||
{
|
{
|
||||||
|
@ -38,14 +40,6 @@ ODMenu::ODMenu()
|
||||||
if(SystemParametersInfo(SPI_GETNONCLIENTMETRICS, sizeof(NONCLIENTMETRICS), &ncms, 0))
|
if(SystemParametersInfo(SPI_GETNONCLIENTMETRICS, sizeof(NONCLIENTMETRICS), &ncms, 0))
|
||||||
m_hFont = CreateFontIndirect(&ncms.lfMenuFont);
|
m_hFont = CreateFontIndirect(&ncms.lfMenuFont);
|
||||||
|
|
||||||
//Set menu metrics
|
|
||||||
m_iconBarMargin = 3;
|
|
||||||
m_textLeftMargin = 6;
|
|
||||||
m_textRightMargin = 3;
|
|
||||||
m_iconWidth = GetSystemMetrics(SM_CXSMICON);
|
|
||||||
m_iconHeight = GetSystemMetrics(SM_CYSMICON);
|
|
||||||
m_verticalSpacing = 6;
|
|
||||||
|
|
||||||
//Create GDI objects
|
//Create GDI objects
|
||||||
m_hItemBackground = CreateSolidBrush(m_clrItemBackground);
|
m_hItemBackground = CreateSolidBrush(m_clrItemBackground);
|
||||||
m_hIconBarBrush = CreateSolidBrush(m_clrIconBar);
|
m_hIconBarBrush = CreateSolidBrush(m_clrIconBar);
|
||||||
|
@ -86,6 +80,16 @@ bool ODMenu::Init(HWND hOwnerWnd, HMENU hMenu)
|
||||||
{
|
{
|
||||||
m_hRootMenu = hMenu;
|
m_hRootMenu = hMenu;
|
||||||
|
|
||||||
|
auto iconDimension = GetSystemMetricsForWindow(SM_CXSMICON, hOwnerWnd);
|
||||||
|
m_iconWidth = iconDimension;
|
||||||
|
m_iconHeight = iconDimension;
|
||||||
|
|
||||||
|
// Set menu metrics
|
||||||
|
m_iconBarMargin = DpToPixels(3, hOwnerWnd);
|
||||||
|
m_textLeftMargin = DpToPixels(6, hOwnerWnd);
|
||||||
|
m_textRightMargin = DpToPixels(3, hOwnerWnd);
|
||||||
|
m_verticalSpacing = DpToPixels(6, hOwnerWnd);
|
||||||
|
|
||||||
//Traverse through all menu items to allocate a map of ODMENUITEM which
|
//Traverse through all menu items to allocate a map of ODMENUITEM which
|
||||||
//will be subsequently used to measure and draw menu items.
|
//will be subsequently used to measure and draw menu items.
|
||||||
|
|
||||||
|
@ -227,7 +231,7 @@ void ODMenu::DrawItemText(DRAWITEMSTRUCT* lpdis, ODMENUITEM& item)
|
||||||
&rectText, DT_RIGHT | DT_SINGLELINE | DT_VCENTER);
|
&rectText, DT_RIGHT | DT_SINGLELINE | DT_VCENTER);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ODMenu::DrawIconBar(DRAWITEMSTRUCT* lpdis, ODMENUITEM& item)
|
void ODMenu::DrawIconBar(HWND hWnd, DRAWITEMSTRUCT* lpdis, ODMENUITEM& item)
|
||||||
{
|
{
|
||||||
RECT rectBar;
|
RECT rectBar;
|
||||||
memcpy(&rectBar, &lpdis->rcItem, sizeof(RECT));
|
memcpy(&rectBar, &lpdis->rcItem, sizeof(RECT));
|
||||||
|
@ -253,27 +257,27 @@ void ODMenu::DrawIconBar(DRAWITEMSTRUCT* lpdis, ODMENUITEM& item)
|
||||||
//Draw icon for menu item if handle is valid
|
//Draw icon for menu item if handle is valid
|
||||||
if(item.hBitmap)
|
if(item.hBitmap)
|
||||||
{
|
{
|
||||||
x = m_iconBarMargin;
|
x = rectBar.left + m_iconBarMargin + m_iconWidth / 2;
|
||||||
y = rectBar.top + ((rectBar.bottom - rectBar.top - 16) / 2);
|
y = rectBar.top + (rectBar.bottom - rectBar.top) / 2;
|
||||||
|
|
||||||
if(lpdis->itemState & ODS_DISABLED || lpdis->itemState & ODS_GRAYED)
|
if(lpdis->itemState & ODS_DISABLED || lpdis->itemState & ODS_GRAYED)
|
||||||
{
|
{
|
||||||
//Draw disabled icon in normal position
|
//Draw disabled icon in normal position
|
||||||
DrawTransparentBitmap(lpdis->hDC, item.hBitmap, x, y, m_clrTranparent, eDisabled);
|
DrawTransparentBitmap(hWnd, lpdis->hDC, item.hBitmap, x, y, m_clrTranparent, eDisabled);
|
||||||
}
|
}
|
||||||
else if(lpdis->itemState & ODS_SELECTED)
|
else if(lpdis->itemState & ODS_SELECTED)
|
||||||
{
|
{
|
||||||
//Draw icon "raised"
|
//Draw icon "raised"
|
||||||
//Draw shadow right one pixel and down one pixel from normal position
|
//Draw shadow right one pixel and down one pixel from normal position
|
||||||
DrawTransparentBitmap(lpdis->hDC, item.hBitmap, x+1, y+1, m_clrTranparent, eShadow);
|
DrawTransparentBitmap(hWnd, lpdis->hDC, item.hBitmap, x+1, y+1, m_clrTranparent, eShadow);
|
||||||
|
|
||||||
//Draw normal left one pixel and up one pixel from normal position
|
//Draw normal left one pixel and up one pixel from normal position
|
||||||
DrawTransparentBitmap(lpdis->hDC, item.hBitmap, x-1, y-1, m_clrTranparent);
|
DrawTransparentBitmap(hWnd, lpdis->hDC, item.hBitmap, x-1, y-1, m_clrTranparent);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
//Draw faded icon in normal position
|
//Draw faded icon in normal position
|
||||||
DrawTransparentBitmap(lpdis->hDC, item.hBitmap, x, y, m_clrTranparent, eFaded);
|
DrawTransparentBitmap(hWnd, lpdis->hDC, item.hBitmap, x, y, m_clrTranparent, eFaded);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if(lpdis->itemState & ODS_CHECKED)
|
else if(lpdis->itemState & ODS_CHECKED)
|
||||||
|
@ -289,17 +293,17 @@ void ODMenu::DrawIconBar(DRAWITEMSTRUCT* lpdis, ODMENUITEM& item)
|
||||||
hPrevBrush = (HBRUSH)SelectObject(lpdis->hDC, m_hCheckMarkBackgroundBrush);
|
hPrevBrush = (HBRUSH)SelectObject(lpdis->hDC, m_hCheckMarkBackgroundBrush);
|
||||||
hPrevPen = (HPEN)SelectObject(lpdis->hDC, m_hSelectionOutlinePen);
|
hPrevPen = (HPEN)SelectObject(lpdis->hDC, m_hSelectionOutlinePen);
|
||||||
rect.left = m_iconBarMargin;
|
rect.left = m_iconBarMargin;
|
||||||
rect.right = m_iconBarMargin + m_iconWidth;
|
rect.right = rect.left + m_iconWidth;
|
||||||
rect.top = rectBar.top + (rectBar.bottom - rectBar.top - m_iconHeight) / 2;
|
rect.top = rectBar.top + (rectBar.bottom - rectBar.top - m_iconHeight) / 2;
|
||||||
rect.bottom = rect.top + m_iconHeight;
|
rect.bottom = rect.top + m_iconHeight;
|
||||||
Rectangle(lpdis->hDC, rect.left, rect.top, rect.right, rect.bottom);
|
Rectangle(lpdis->hDC, rect.left, rect.top, rect.right, rect.bottom);
|
||||||
SelectObject(lpdis->hDC, hPrevBrush);
|
SelectObject(lpdis->hDC, hPrevBrush);
|
||||||
SelectObject(lpdis->hDC, hPrevPen);
|
SelectObject(lpdis->hDC, hPrevPen);
|
||||||
|
|
||||||
//Draw check mark
|
// Draw check mark
|
||||||
x = (m_iconWidth + 2*m_iconBarMargin - 6) / 2;
|
x = rectBar.left + m_iconBarMargin + m_iconWidth / 2;
|
||||||
y = rectBar.top + ((rectBar.bottom - rectBar.top - 7) / 2) + 1;
|
y = rectBar.top + (rectBar.bottom - rectBar.top) / 2;
|
||||||
DrawCheckMark(lpdis->hDC, x, y, true);
|
DrawCheckMark(hWnd, lpdis->hDC, x, y, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -321,8 +325,8 @@ void ODMenu::ComputeMenuTextPos(DRAWITEMSTRUCT* lpdis, ODMENUITEM& item, int& x,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ODMenu::DrawTransparentBitmap(HDC hDC, HBITMAP hBitmap, short xStart,
|
void ODMenu::DrawTransparentBitmap(HWND hWnd, HDC hDC, HBITMAP hBitmap, short centerX,
|
||||||
short yStart, COLORREF cTransparentColor,
|
short centerY, COLORREF cTransparentColor,
|
||||||
bitmapType eType)
|
bitmapType eType)
|
||||||
{
|
{
|
||||||
BITMAP bm;
|
BITMAP bm;
|
||||||
|
@ -333,8 +337,6 @@ void ODMenu::DrawTransparentBitmap(HDC hDC, HBITMAP hBitmap, short xStart,
|
||||||
POINT ptSize;
|
POINT ptSize;
|
||||||
HBRUSH hOldBrush;
|
HBRUSH hOldBrush;
|
||||||
|
|
||||||
BOOL bRC;
|
|
||||||
|
|
||||||
hdcTemp = CreateCompatibleDC(hDC);
|
hdcTemp = CreateCompatibleDC(hDC);
|
||||||
SelectObject(hdcTemp, hBitmap); // Select the bitmap
|
SelectObject(hdcTemp, hBitmap); // Select the bitmap
|
||||||
|
|
||||||
|
@ -344,6 +346,9 @@ void ODMenu::DrawTransparentBitmap(HDC hDC, HBITMAP hBitmap, short xStart,
|
||||||
DPtoLP(hdcTemp, &ptSize, 1); // Convert from device
|
DPtoLP(hdcTemp, &ptSize, 1); // Convert from device
|
||||||
// to logical points
|
// to logical points
|
||||||
|
|
||||||
|
auto iconWidth = DpToPixels(ptSize.x, hWnd);
|
||||||
|
auto iconHeight = DpToPixels(ptSize.y, hWnd);
|
||||||
|
|
||||||
// Create some DCs to hold temporary data.
|
// Create some DCs to hold temporary data.
|
||||||
hdcBack = CreateCompatibleDC(hDC);
|
hdcBack = CreateCompatibleDC(hDC);
|
||||||
hdcObject = CreateCompatibleDC(hDC);
|
hdcObject = CreateCompatibleDC(hDC);
|
||||||
|
@ -359,7 +364,7 @@ void ODMenu::DrawTransparentBitmap(HDC hDC, HBITMAP hBitmap, short xStart,
|
||||||
// Monochrome DC
|
// Monochrome DC
|
||||||
bmAndObject = CreateBitmap(ptSize.x, ptSize.y, 1, 1, NULL);
|
bmAndObject = CreateBitmap(ptSize.x, ptSize.y, 1, 1, NULL);
|
||||||
|
|
||||||
bmAndMem = CreateCompatibleBitmap(hDC, ptSize.x, ptSize.y);
|
bmAndMem = CreateCompatibleBitmap(hDC, iconWidth, iconHeight);
|
||||||
bmSave = CreateCompatibleBitmap(hDC, ptSize.x, ptSize.y);
|
bmSave = CreateCompatibleBitmap(hDC, ptSize.x, ptSize.y);
|
||||||
|
|
||||||
// Each DC must select a bitmap object to store pixel data.
|
// Each DC must select a bitmap object to store pixel data.
|
||||||
|
@ -372,7 +377,7 @@ void ODMenu::DrawTransparentBitmap(HDC hDC, HBITMAP hBitmap, short xStart,
|
||||||
SetMapMode(hdcTemp, GetMapMode(hDC));
|
SetMapMode(hdcTemp, GetMapMode(hDC));
|
||||||
|
|
||||||
// Save the bitmap sent here, because it will be overwritten.
|
// Save the bitmap sent here, because it will be overwritten.
|
||||||
bRC = BitBlt(hdcSave, 0, 0, ptSize.x, ptSize.y, hdcTemp, 0, 0, SRCCOPY);
|
BitBlt(hdcSave, 0, 0, ptSize.x, ptSize.y, hdcTemp, 0, 0, SRCCOPY);
|
||||||
|
|
||||||
// Create an "AND mask" that contains the mask of the colors to draw
|
// Create an "AND mask" that contains the mask of the colors to draw
|
||||||
// (the nontransparent portions of the image).
|
// (the nontransparent portions of the image).
|
||||||
|
@ -383,21 +388,21 @@ void ODMenu::DrawTransparentBitmap(HDC hDC, HBITMAP hBitmap, short xStart,
|
||||||
|
|
||||||
// Create the object mask for the bitmap by performing a BitBlt
|
// Create the object mask for the bitmap by performing a BitBlt
|
||||||
// from the source bitmap to a monochrome bitmap.
|
// from the source bitmap to a monochrome bitmap.
|
||||||
bRC = BitBlt(hdcObject, 0, 0, ptSize.x, ptSize.y, hdcTemp, 0, 0, SRCCOPY);
|
BitBlt(hdcObject, 0, 0, ptSize.x, ptSize.y, hdcTemp, 0, 0, SRCCOPY);
|
||||||
|
|
||||||
// Set the background color of the source DC back to the original color.
|
// Set the background color of the source DC back to the original color.
|
||||||
SetBkColor(hdcTemp, cColor);
|
SetBkColor(hdcTemp, cColor);
|
||||||
|
|
||||||
// Create the inverse of the object mask.
|
// Create the inverse of the object mask.
|
||||||
bRC = BitBlt(hdcBack, 0, 0, ptSize.x, ptSize.y, hdcObject, 0, 0, NOTSRCCOPY);
|
BitBlt(hdcBack, 0, 0, ptSize.x, ptSize.y, hdcObject, 0, 0, NOTSRCCOPY);
|
||||||
|
|
||||||
// Copy the background of the main DC to the destination.
|
// Copy the background of the main DC to the destination.
|
||||||
bRC = BitBlt(hdcMem, 0, 0, ptSize.x, ptSize.y, hDC, xStart, yStart, SRCCOPY);
|
BitBlt(hdcMem, 0, 0, iconWidth, iconHeight, hDC, centerX - iconWidth / 2, centerY - iconHeight / 2, SRCCOPY);
|
||||||
|
|
||||||
// Mask out the places where the bitmap will be placed.
|
// Mask out the places where the bitmap will be placed.
|
||||||
// hdcMem then contains the background color of hDC only in the places
|
// hdcMem then contains the background color of hDC only in the places
|
||||||
// where the transparent pixels reside.
|
// where the transparent pixels reside.
|
||||||
bRC = BitBlt(hdcMem, 0, 0, ptSize.x, ptSize.y, hdcObject, 0, 0, SRCAND);
|
StretchBlt(hdcMem, 0, 0, iconWidth, iconHeight, hdcObject, 0, 0, ptSize.x, ptSize.y, SRCAND);
|
||||||
|
|
||||||
if(eType == eNormal)
|
if(eType == eNormal)
|
||||||
{
|
{
|
||||||
|
@ -407,7 +412,7 @@ void ODMenu::DrawTransparentBitmap(HDC hDC, HBITMAP hBitmap, short xStart,
|
||||||
|
|
||||||
// XOR the bitmap with the background on the destination DC.
|
// XOR the bitmap with the background on the destination DC.
|
||||||
// hdcMem then contains the required result.
|
// hdcMem then contains the required result.
|
||||||
BitBlt(hdcMem, 0, 0, ptSize.x, ptSize.y, hdcTemp, 0, 0, SRCPAINT);
|
StretchBlt(hdcMem, 0, 0, iconWidth, iconHeight, hdcTemp, 0, 0, ptSize.x, ptSize.y, SRCPAINT);
|
||||||
}
|
}
|
||||||
else if(eType == eShadow)
|
else if(eType == eShadow)
|
||||||
{
|
{
|
||||||
|
@ -415,11 +420,11 @@ void ODMenu::DrawTransparentBitmap(HDC hDC, HBITMAP hBitmap, short xStart,
|
||||||
hOldBrush = (HBRUSH)SelectObject(hdcTemp, m_hIconShadowBrush);
|
hOldBrush = (HBRUSH)SelectObject(hdcTemp, m_hIconShadowBrush);
|
||||||
|
|
||||||
//Copy shadow brush pixels for all non-transparent pixels to hdcTemp
|
//Copy shadow brush pixels for all non-transparent pixels to hdcTemp
|
||||||
bRC = BitBlt(hdcTemp, 0, 0, ptSize.x, ptSize.y, hdcBack, 0, 0, MERGECOPY);
|
BitBlt(hdcTemp, 0, 0, ptSize.x, ptSize.y, hdcBack, 0, 0, MERGECOPY);
|
||||||
|
|
||||||
// XOR the bitmap with the background on the destination DC.
|
// XOR the bitmap with the background on the destination DC.
|
||||||
// hdcMem then contains the required result.
|
// hdcMem then contains the required result.
|
||||||
bRC = BitBlt(hdcMem, 0, 0, ptSize.x, ptSize.y, hdcTemp, 0, 0, SRCPAINT);
|
StretchBlt(hdcMem, 0, 0, iconWidth, iconHeight, hdcTemp, 0, 0, ptSize.x, ptSize.y, SRCPAINT);
|
||||||
|
|
||||||
//Restore the brush in hdcTemp
|
//Restore the brush in hdcTemp
|
||||||
SelectObject(hdcTemp, hOldBrush);
|
SelectObject(hdcTemp, hOldBrush);
|
||||||
|
@ -446,7 +451,7 @@ void ODMenu::DrawTransparentBitmap(HDC hDC, HBITMAP hBitmap, short xStart,
|
||||||
|
|
||||||
// XOR the bitmap with the background on the destination DC.
|
// XOR the bitmap with the background on the destination DC.
|
||||||
// hdcMem then contains the required result.
|
// hdcMem then contains the required result.
|
||||||
BitBlt(hdcMem, 0, 0, ptSize.x, ptSize.y, hdcTemp, 0, 0, SRCPAINT);
|
StretchBlt(hdcMem, 0, 0, iconWidth, iconHeight, hdcTemp, 0, 0, ptSize.x, ptSize.y, SRCPAINT);
|
||||||
}
|
}
|
||||||
else if(eType == eDisabled)
|
else if(eType == eDisabled)
|
||||||
{
|
{
|
||||||
|
@ -479,14 +484,14 @@ void ODMenu::DrawTransparentBitmap(HDC hDC, HBITMAP hBitmap, short xStart,
|
||||||
|
|
||||||
// XOR the bitmap with the background on the destination DC.
|
// XOR the bitmap with the background on the destination DC.
|
||||||
// hdcMem then contains the required result.
|
// hdcMem then contains the required result.
|
||||||
BitBlt(hdcMem, 0, 0, ptSize.x, ptSize.y, hdcTemp, 0, 0, SRCPAINT);
|
StretchBlt(hdcMem, 0, 0, iconWidth, iconHeight, hdcTemp, 0, 0, ptSize.x, ptSize.y, SRCPAINT);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Copy the destination to the screen.
|
// Copy the destination to the screen.
|
||||||
bRC = BitBlt(hDC, xStart, yStart, ptSize.x, ptSize.y, hdcMem, 0, 0, SRCCOPY);
|
BitBlt(hDC, centerX - iconWidth / 2, centerY - iconHeight / 2, iconWidth, iconHeight, hdcMem, 0, 0, SRCCOPY);
|
||||||
|
|
||||||
// Place the original bitmap back into the bitmap sent here.
|
// Place the original bitmap back into the bitmap sent here.
|
||||||
bRC = BitBlt(hdcTemp, 0, 0, ptSize.x, ptSize.y, hdcSave, 0, 0, SRCCOPY);
|
BitBlt(hdcTemp, 0, 0, ptSize.x, ptSize.y, hdcSave, 0, 0, SRCCOPY);
|
||||||
|
|
||||||
// Delete the memory bitmaps.
|
// Delete the memory bitmaps.
|
||||||
DeleteObject(SelectObject(hdcBack, bmBackOld));
|
DeleteObject(SelectObject(hdcBack, bmBackOld));
|
||||||
|
@ -502,7 +507,7 @@ void ODMenu::DrawTransparentBitmap(HDC hDC, HBITMAP hBitmap, short xStart,
|
||||||
DeleteDC(hdcTemp);
|
DeleteDC(hdcTemp);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ODMenu::DrawCheckMark(HDC hDC, short x, short y, bool bNarrow)
|
void ODMenu::DrawCheckMark(HWND hWnd, HDC hDC, short centerX, short centerY, bool bNarrow)
|
||||||
{
|
{
|
||||||
HPEN hOldPen;
|
HPEN hOldPen;
|
||||||
int dp = 0;
|
int dp = 0;
|
||||||
|
@ -510,30 +515,26 @@ void ODMenu::DrawCheckMark(HDC hDC, short x, short y, bool bNarrow)
|
||||||
if(bNarrow)
|
if(bNarrow)
|
||||||
dp = 1;
|
dp = 1;
|
||||||
|
|
||||||
//Select check mark pen
|
// Select check mark pen
|
||||||
hOldPen = (HPEN)SelectObject(hDC, m_hCheckMarkPen);
|
hOldPen = (HPEN)SelectObject(hDC, m_hCheckMarkPen);
|
||||||
|
|
||||||
//Draw the check mark
|
// Draw the check mark
|
||||||
MoveToEx(hDC, x, y + 2, NULL);
|
auto minLeftX = centerX - DpToPixels(4, hWnd);
|
||||||
LineTo(hDC, x, y + 5 - dp);
|
auto maxLeftX = centerX - DpToPixels(1, hWnd);
|
||||||
|
auto x = minLeftX;
|
||||||
|
auto y = centerY - DpToPixels(2, hWnd);
|
||||||
|
for (; x < maxLeftX; x += 1, y += 1)
|
||||||
|
{
|
||||||
|
MoveToEx(hDC, x, y, NULL);
|
||||||
|
LineTo(hDC, x, y + DpToPixels(3 - dp, hWnd));
|
||||||
|
}
|
||||||
|
|
||||||
MoveToEx(hDC, x + 1, y + 3, NULL);
|
auto maxRightX = centerX + DpToPixels(4, hWnd);
|
||||||
LineTo(hDC, x + 1, y + 6 - dp);
|
for (; x < maxRightX; x += 1, y -= 1)
|
||||||
|
{
|
||||||
MoveToEx(hDC, x + 2, y + 4, NULL);
|
MoveToEx(hDC, x, y, NULL);
|
||||||
LineTo(hDC, x + 2, y + 7 - dp);
|
LineTo(hDC, x, y + DpToPixels(3 - dp, hWnd));
|
||||||
|
}
|
||||||
MoveToEx(hDC, x + 3, y + 3, NULL);
|
|
||||||
LineTo(hDC, x + 3, y + 6 - dp);
|
|
||||||
|
|
||||||
MoveToEx(hDC, x + 4, y + 2, NULL);
|
|
||||||
LineTo(hDC, x + 4, y + 5 - dp);
|
|
||||||
|
|
||||||
MoveToEx(hDC, x + 5, y + 1, NULL);
|
|
||||||
LineTo(hDC, x + 5, y + 4 - dp);
|
|
||||||
|
|
||||||
MoveToEx(hDC, x + 6, y, NULL);
|
|
||||||
LineTo(hDC, x + 6, y + 3 - dp);
|
|
||||||
|
|
||||||
//Restore original DC pen
|
//Restore original DC pen
|
||||||
SelectObject(hDC, hOldPen);
|
SelectObject(hDC, hOldPen);
|
||||||
|
@ -622,6 +623,7 @@ void ODMenu::MeasureItem(HWND hWnd, LPARAM lParam)
|
||||||
DrawText(hDC, item.rawText.c_str(), item.rawText.length(), &rect,
|
DrawText(hDC, item.rawText.c_str(), item.rawText.length(), &rect,
|
||||||
DT_SINGLELINE | DT_LEFT | DT_VCENTER | DT_CALCRECT);
|
DT_SINGLELINE | DT_LEFT | DT_VCENTER | DT_CALCRECT);
|
||||||
lpmis->itemWidth = rect.right - rect.left;
|
lpmis->itemWidth = rect.right - rect.left;
|
||||||
|
lpmis->itemHeight = m_iconHeight;
|
||||||
|
|
||||||
if(!item.topMost)
|
if(!item.topMost)
|
||||||
{
|
{
|
||||||
|
@ -727,7 +729,7 @@ void ODMenu::DrawItem(HWND hWnd, LPARAM lParam)
|
||||||
}
|
}
|
||||||
|
|
||||||
//Draw the left icon bar
|
//Draw the left icon bar
|
||||||
DrawIconBar(lpdis, item);
|
DrawIconBar(hWnd, lpdis, item);
|
||||||
|
|
||||||
//Draw selection outline if drawing a selected item
|
//Draw selection outline if drawing a selected item
|
||||||
if(lpdis->itemState & ODS_SELECTED && !(lpdis->itemState & ODS_GRAYED || lpdis->itemState & ODS_DISABLED))
|
if(lpdis->itemState & ODS_SELECTED && !(lpdis->itemState & ODS_GRAYED || lpdis->itemState & ODS_DISABLED))
|
||||||
|
|
|
@ -68,11 +68,11 @@ class ODMenu
|
||||||
void SetMenuItemOwnerDrawn(HMENU hMenu, UINT item, UINT type);
|
void SetMenuItemOwnerDrawn(HMENU hMenu, UINT item, UINT type);
|
||||||
void GenerateDisplayText(ODMENUITEM& item);
|
void GenerateDisplayText(ODMENUITEM& item);
|
||||||
void DrawItemText(DRAWITEMSTRUCT* lpdis, ODMENUITEM& item);
|
void DrawItemText(DRAWITEMSTRUCT* lpdis, ODMENUITEM& item);
|
||||||
void DrawIconBar(DRAWITEMSTRUCT* lpdis, ODMENUITEM& item);
|
void DrawIconBar(HWND hWnd, DRAWITEMSTRUCT* lpdis, ODMENUITEM& item);
|
||||||
void ComputeMenuTextPos(DRAWITEMSTRUCT* lpdis, ODMENUITEM& item, int& x, int& y, SIZE& size);
|
void ComputeMenuTextPos(DRAWITEMSTRUCT* lpdis, ODMENUITEM& item, int& x, int& y, SIZE& size);
|
||||||
void DrawTransparentBitmap(HDC hDC, HBITMAP hBitmap, short xStart, short yStart,
|
void DrawTransparentBitmap(HWND hWnd, HDC hDC, HBITMAP hBitmap, short centerX, short centerY,
|
||||||
COLORREF cTransparentColor, bitmapType eType=eNormal);
|
COLORREF cTransparentColor, bitmapType eType=eNormal);
|
||||||
void DrawCheckMark(HDC hDC, short x, short y, bool bNarrow=true);
|
void DrawCheckMark(HWND hWnd, HDC hDC, short centerX, short centerY, bool bNarrow=true);
|
||||||
COLORREF LightenColor(COLORREF col, double factor);
|
COLORREF LightenColor(COLORREF col, double factor);
|
||||||
COLORREF DarkenColor(COLORREF col, double factor);
|
COLORREF DarkenColor(COLORREF col, double factor);
|
||||||
COLORREF AverageColor(COLORREF col1, COLORREF col2, double weight1=0.5);
|
COLORREF AverageColor(COLORREF col1, COLORREF col2, double weight1=0.5);
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
||||||
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
|
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0" xmlns:asmv3="urn:schemas-microsoft-com:asm.v3">
|
||||||
<assemblyIdentity
|
<assemblyIdentity
|
||||||
version="1.0.0.0"
|
version="1.0.0.0"
|
||||||
processorArchitecture="X86"
|
processorArchitecture="*"
|
||||||
name="Celestia"
|
name="Celestia"
|
||||||
type="win32"
|
type="win32"
|
||||||
/>
|
/>
|
||||||
|
@ -19,4 +19,10 @@
|
||||||
/>
|
/>
|
||||||
</dependentAssembly>
|
</dependentAssembly>
|
||||||
</dependency>
|
</dependency>
|
||||||
</assembly>
|
<asmv3:application>
|
||||||
|
<asmv3:windowsSettings>
|
||||||
|
<dpiAware xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">true</dpiAware>
|
||||||
|
<dpiAwareness xmlns="http://schemas.microsoft.com/SMI/2016/WindowsSettings">PerMonitorV2</dpiAwareness>
|
||||||
|
</asmv3:windowsSettings>
|
||||||
|
</asmv3:application>
|
||||||
|
</assembly>
|
||||||
|
|
|
@ -16,6 +16,8 @@
|
||||||
#define NC_(c, s) s
|
#define NC_(c, s) s
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
CREATEPROCESS_MANIFEST_RESOURCE_ID RT_MANIFEST "celestia.exe.manifest"
|
||||||
|
|
||||||
//
|
//
|
||||||
// Bitmap resources
|
// Bitmap resources
|
||||||
//
|
//
|
||||||
|
|
|
@ -29,11 +29,10 @@
|
||||||
using namespace Eigen;
|
using namespace Eigen;
|
||||||
using namespace std;
|
using namespace std;
|
||||||
using namespace celmath;
|
using namespace celmath;
|
||||||
|
using namespace celestia::win32;
|
||||||
|
|
||||||
static vector<Eclipse> eclipseList;
|
static vector<Eclipse> eclipseList;
|
||||||
|
|
||||||
extern void SetMouseCursor(LPCTSTR lpCursor);
|
|
||||||
|
|
||||||
const char* MonthNames[12] =
|
const char* MonthNames[12] =
|
||||||
{
|
{
|
||||||
"Jan", "Feb", "Mar", "Apr",
|
"Jan", "Feb", "Mar", "Apr",
|
||||||
|
@ -63,15 +62,15 @@ bool InitEclipseFinderColumns(HWND listView)
|
||||||
string header4 = UTF8ToCurrentCP(_("Duration"));
|
string header4 = UTF8ToCurrentCP(_("Duration"));
|
||||||
|
|
||||||
columns[0].pszText = const_cast<char*>(header0.c_str());
|
columns[0].pszText = const_cast<char*>(header0.c_str());
|
||||||
columns[0].cx = 65;
|
columns[0].cx = DpToPixels(65, listView);
|
||||||
columns[1].pszText = const_cast<char*>(header1.c_str());
|
columns[1].pszText = const_cast<char*>(header1.c_str());
|
||||||
columns[1].cx = 65;
|
columns[1].cx = DpToPixels(65, listView);
|
||||||
columns[2].pszText = const_cast<char*>(header2.c_str());
|
columns[2].pszText = const_cast<char*>(header2.c_str());
|
||||||
columns[2].cx = 80;
|
columns[2].cx = DpToPixels(80, listView);
|
||||||
columns[3].pszText = const_cast<char*>(header3.c_str());
|
columns[3].pszText = const_cast<char*>(header3.c_str());
|
||||||
columns[3].cx = 55;
|
columns[3].cx = DpToPixels(55, listView);
|
||||||
columns[4].pszText = const_cast<char*>(header4.c_str());
|
columns[4].pszText = const_cast<char*>(header4.c_str());
|
||||||
columns[4].cx = 135;
|
columns[4].cx = DpToPixels(135, listView);
|
||||||
|
|
||||||
for (i = 0; i < nColumns; i++)
|
for (i = 0; i < nColumns; i++)
|
||||||
{
|
{
|
||||||
|
|
|
@ -68,6 +68,7 @@
|
||||||
using namespace celestia;
|
using namespace celestia;
|
||||||
using namespace celestia::util;
|
using namespace celestia::util;
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
using namespace celestia::win32;
|
||||||
|
|
||||||
typedef pair<int,string> IntStrPair;
|
typedef pair<int,string> IntStrPair;
|
||||||
typedef vector<IntStrPair> IntStrPairVec;
|
typedef vector<IntStrPair> IntStrPairVec;
|
||||||
|
@ -988,7 +989,7 @@ BOOL APIENTRY AddBookmarkProc(HWND hDlg,
|
||||||
if (strstr(text, ">>"))
|
if (strstr(text, ">>"))
|
||||||
{
|
{
|
||||||
//Increase size of dialog
|
//Increase size of dialog
|
||||||
int height = treeRect.bottom - dlgRect.top + 12;
|
int height = treeRect.bottom - dlgRect.top + DpToPixels(12, hDlg);
|
||||||
SetWindowPos(hDlg, HWND_TOP, 0, 0, width, height,
|
SetWindowPos(hDlg, HWND_TOP, 0, 0, width, height,
|
||||||
SWP_NOMOVE | SWP_NOZORDER);
|
SWP_NOMOVE | SWP_NOZORDER);
|
||||||
//Change text in button
|
//Change text in button
|
||||||
|
@ -3186,8 +3187,8 @@ int APIENTRY WinMain(HINSTANCE hInstance,
|
||||||
LoadPreferencesFromRegistry(CelestiaRegKey, prefs);
|
LoadPreferencesFromRegistry(CelestiaRegKey, prefs);
|
||||||
|
|
||||||
// Adjust window dimensions for screen dimensions
|
// Adjust window dimensions for screen dimensions
|
||||||
int screenWidth = GetSystemMetrics(SM_CXSCREEN);
|
int screenWidth = GetSystemMetricsForWindow(SM_CXSCREEN, nullptr);
|
||||||
int screenHeight = GetSystemMetrics(SM_CYSCREEN);
|
int screenHeight = GetSystemMetricsForWindow(SM_CYSCREEN, nullptr);
|
||||||
if (prefs.winWidth > screenWidth)
|
if (prefs.winWidth > screenWidth)
|
||||||
prefs.winWidth = screenWidth;
|
prefs.winWidth = screenWidth;
|
||||||
if (prefs.winHeight > screenHeight)
|
if (prefs.winHeight > screenHeight)
|
||||||
|
@ -3386,6 +3387,8 @@ int APIENTRY WinMain(HINSTANCE hInstance,
|
||||||
extern void RegisterDatePicker();
|
extern void RegisterDatePicker();
|
||||||
RegisterDatePicker();
|
RegisterDatePicker();
|
||||||
|
|
||||||
|
appCore->setScreenDpi(GetDPIForWindow(hWnd));
|
||||||
|
|
||||||
if (!appCore->initRenderer())
|
if (!appCore->initRenderer())
|
||||||
{
|
{
|
||||||
return 1;
|
return 1;
|
||||||
|
|
|
@ -10,6 +10,7 @@
|
||||||
// of the License, or (at your option) any later version.
|
// of the License, or (at your option) any later version.
|
||||||
|
|
||||||
#include "winsplash.h"
|
#include "winsplash.h"
|
||||||
|
#include "winuiutils.h"
|
||||||
#include <celutil/gettext.h>
|
#include <celutil/gettext.h>
|
||||||
#include <celutil/winutil.h>
|
#include <celutil/winutil.h>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
@ -20,6 +21,7 @@
|
||||||
|
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
using namespace celestia::win32;
|
||||||
|
|
||||||
|
|
||||||
// Required for transparent Windows, but not present in VC6 headers. Only present
|
// Required for transparent Windows, but not present in VC6 headers. Only present
|
||||||
|
@ -61,7 +63,9 @@ SplashWindow::SplashWindow(const string& _imageFileName) :
|
||||||
hCompositionBitmap(0),
|
hCompositionBitmap(0),
|
||||||
useLayeredWindow(false),
|
useLayeredWindow(false),
|
||||||
winWidth(640),
|
winWidth(640),
|
||||||
winHeight(480)
|
winHeight(480),
|
||||||
|
imageWidth(0),
|
||||||
|
imageHeight(0)
|
||||||
{
|
{
|
||||||
init();
|
init();
|
||||||
}
|
}
|
||||||
|
@ -108,7 +112,7 @@ SplashWindow::paint(HDC hDC)
|
||||||
HDC hMemDC = ::CreateCompatibleDC(hDC);
|
HDC hMemDC = ::CreateCompatibleDC(hDC);
|
||||||
HBITMAP hOldBitmap = (HBITMAP) ::SelectObject(hMemDC, hBitmap);
|
HBITMAP hOldBitmap = (HBITMAP) ::SelectObject(hMemDC, hBitmap);
|
||||||
|
|
||||||
BitBlt(hDC, 0, 0, winWidth, winHeight, hMemDC, 0, 0, SRCCOPY);
|
StretchBlt(hDC, 0, 0, winWidth, winHeight, hMemDC, 0, 0, imageWidth, imageHeight, SRCCOPY);
|
||||||
|
|
||||||
::SelectObject(hMemDC, hOldBitmap);
|
::SelectObject(hMemDC, hOldBitmap);
|
||||||
::DeleteDC(hMemDC);
|
::DeleteDC(hMemDC);
|
||||||
|
@ -126,10 +130,10 @@ SplashWindow::paint(HDC hDC)
|
||||||
|
|
||||||
// Show the message text
|
// Show the message text
|
||||||
RECT r;
|
RECT r;
|
||||||
r.left = rect.right - 250;
|
r.left = rect.right - DpToPixels(250, hwnd);
|
||||||
r.top = rect.bottom - 70;
|
r.top = rect.bottom - DpToPixels(70, hwnd);
|
||||||
r.right = rect.right;
|
r.right = rect.right;
|
||||||
r.bottom = r.top + 30;
|
r.bottom = r.top + DpToPixels(30, hwnd);
|
||||||
|
|
||||||
HFONT hFont = reinterpret_cast<HFONT>(GetStockObject(DEFAULT_GUI_FONT));
|
HFONT hFont = reinterpret_cast<HFONT>(GetStockObject(DEFAULT_GUI_FONT));
|
||||||
SelectObject(hDC, hFont);
|
SelectObject(hDC, hFont);
|
||||||
|
@ -212,15 +216,18 @@ SplashWindow::createWindow()
|
||||||
if (!RegisterClassEx(&wndclass))
|
if (!RegisterClassEx(&wndclass))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
if (image != NULL)
|
if (image != nullptr)
|
||||||
{
|
{
|
||||||
winWidth = image->getWidth();
|
imageWidth = image->getWidth();
|
||||||
winHeight = image->getHeight();
|
imageHeight = image->getHeight();
|
||||||
|
|
||||||
|
winWidth = DpToPixels(imageWidth, nullptr);
|
||||||
|
winHeight = DpToPixels(imageHeight, nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create the application window centered in the middle of the screen
|
// Create the application window centered in the middle of the screen
|
||||||
DWORD nScrWidth = ::GetSystemMetrics(SM_CXFULLSCREEN);
|
DWORD nScrWidth = GetSystemMetricsForWindow(SM_CXFULLSCREEN, nullptr);
|
||||||
DWORD nScrHeight = ::GetSystemMetrics(SM_CYFULLSCREEN);
|
DWORD nScrHeight = GetSystemMetricsForWindow(SM_CYFULLSCREEN, nullptr);
|
||||||
|
|
||||||
int x = (nScrWidth - winWidth) / 2;
|
int x = (nScrWidth - winWidth) / 2;
|
||||||
int y = (nScrHeight - winHeight) / 2;
|
int y = (nScrHeight - winHeight) / 2;
|
||||||
|
@ -304,7 +311,7 @@ SplashWindow::createBitmap()
|
||||||
// layered window support.)
|
// layered window support.)
|
||||||
if (hBitmap)
|
if (hBitmap)
|
||||||
{
|
{
|
||||||
hCompositionBitmap = CreateCompatibleBitmap(hwndDC, image->getWidth(), image->getHeight());
|
hCompositionBitmap = CreateCompatibleBitmap(hwndDC, winWidth, winHeight);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -43,4 +43,6 @@ private:
|
||||||
std::string message;
|
std::string message;
|
||||||
unsigned int winWidth;
|
unsigned int winWidth;
|
||||||
unsigned int winHeight;
|
unsigned int winHeight;
|
||||||
|
unsigned int imageWidth;
|
||||||
|
unsigned int imageHeight;
|
||||||
};
|
};
|
||||||
|
|
|
@ -21,11 +21,11 @@
|
||||||
#include <celmath/mathlib.h>
|
#include <celmath/mathlib.h>
|
||||||
#include "winstarbrowser.h"
|
#include "winstarbrowser.h"
|
||||||
#include "res/resource.h"
|
#include "res/resource.h"
|
||||||
|
#include "winuiutils.h"
|
||||||
extern void SetMouseCursor(LPCTSTR lpCursor);
|
|
||||||
|
|
||||||
using namespace Eigen;
|
using namespace Eigen;
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
using namespace celestia::win32;
|
||||||
|
|
||||||
static const int MinListStars = 10;
|
static const int MinListStars = 10;
|
||||||
static const int MaxListStars = 500;
|
static const int MaxListStars = 500;
|
||||||
|
@ -49,7 +49,7 @@ bool InitStarBrowserColumns(HWND listView)
|
||||||
|
|
||||||
lvc.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT | LVCF_SUBITEM;
|
lvc.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT | LVCF_SUBITEM;
|
||||||
lvc.fmt = LVCFMT_LEFT;
|
lvc.fmt = LVCFMT_LEFT;
|
||||||
lvc.cx = 60;
|
lvc.cx = DpToPixels(60, listView);
|
||||||
lvc.pszText = const_cast<char*>("");
|
lvc.pszText = const_cast<char*>("");
|
||||||
|
|
||||||
int nColumns = sizeof(columns) / sizeof(columns[0]);
|
int nColumns = sizeof(columns) / sizeof(columns[0]);
|
||||||
|
@ -65,16 +65,16 @@ bool InitStarBrowserColumns(HWND listView)
|
||||||
string header4 = UTF8ToCurrentCP(_("Type"));
|
string header4 = UTF8ToCurrentCP(_("Type"));
|
||||||
|
|
||||||
columns[0].pszText = const_cast<char*>(header0.c_str());
|
columns[0].pszText = const_cast<char*>(header0.c_str());
|
||||||
columns[0].cx = 100;
|
columns[0].cx = DpToPixels(100, listView);
|
||||||
columns[1].pszText = const_cast<char*>(header1.c_str());
|
columns[1].pszText = const_cast<char*>(header1.c_str());
|
||||||
columns[1].fmt = LVCFMT_RIGHT;
|
columns[1].fmt = LVCFMT_RIGHT;
|
||||||
columns[1].cx = 115;
|
columns[1].cx = DpToPixels(115, listView);
|
||||||
columns[2].pszText = const_cast<char*>(header2.c_str());
|
columns[2].pszText = const_cast<char*>(header2.c_str());
|
||||||
columns[2].fmt = LVCFMT_RIGHT;
|
columns[2].fmt = LVCFMT_RIGHT;
|
||||||
columns[2].cx = 65;
|
columns[2].cx = DpToPixels(65, listView);
|
||||||
columns[3].pszText = const_cast<char*>(header3.c_str());
|
columns[3].pszText = const_cast<char*>(header3.c_str());
|
||||||
columns[3].fmt = LVCFMT_RIGHT;
|
columns[3].fmt = LVCFMT_RIGHT;
|
||||||
columns[3].cx = 65;
|
columns[3].cx = DpToPixels(65, listView);
|
||||||
columns[4].pszText = const_cast<char*>(header4.c_str());
|
columns[4].pszText = const_cast<char*>(header4.c_str());
|
||||||
|
|
||||||
for (i = 0; i < nColumns; i++)
|
for (i = 0; i < nColumns; i++)
|
||||||
|
|
|
@ -12,6 +12,34 @@
|
||||||
|
|
||||||
#include "winuiutils.h"
|
#include "winuiutils.h"
|
||||||
|
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
using GetDpiForWindowFn = UINT STDAPICALLTYPE(HWND hWnd);
|
||||||
|
using GetDpiForSystemFn = UINT STDAPICALLTYPE();
|
||||||
|
using GetSystemMetricsForDpiFn = UINT STDAPICALLTYPE(int nIndex, UINT dpi);
|
||||||
|
GetDpiForWindowFn *pfnGetDpiForWindow = nullptr;
|
||||||
|
GetDpiForSystemFn *pfnGetDpiForSystem = nullptr;
|
||||||
|
GetSystemMetricsForDpiFn *pfnGetSystemMetricsForDpi = nullptr;
|
||||||
|
bool dpiFunctionPointersInitialized = false;
|
||||||
|
|
||||||
|
void InitializeDPIFunctionPointersIfNeeded()
|
||||||
|
{
|
||||||
|
if (dpiFunctionPointersInitialized)
|
||||||
|
return;
|
||||||
|
|
||||||
|
HMODULE hUser = GetModuleHandle("user32.dll");
|
||||||
|
if (!hUser)
|
||||||
|
return;
|
||||||
|
pfnGetDpiForWindow = reinterpret_cast<GetDpiForWindowFn *>(GetProcAddress(hUser, "GetDpiForWindow"));
|
||||||
|
pfnGetDpiForSystem = reinterpret_cast<GetDpiForSystemFn *>(GetProcAddress(hUser, "GetDpiForSystem"));
|
||||||
|
pfnGetSystemMetricsForDpi = reinterpret_cast<GetSystemMetricsForDpiFn *>(GetProcAddress(hUser, "GetSystemMetricsForDpi"));
|
||||||
|
dpiFunctionPointersInitialized = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace celestia::win32
|
||||||
|
{
|
||||||
|
|
||||||
void SetMouseCursor(LPCTSTR lpCursor)
|
void SetMouseCursor(LPCTSTR lpCursor)
|
||||||
{
|
{
|
||||||
HCURSOR hNewCrsr;
|
HCURSOR hNewCrsr;
|
||||||
|
@ -53,3 +81,44 @@ void AddButtonDefaultStyle(HWND hWnd)
|
||||||
::GetWindowLong(hWnd, GWL_STYLE) | BS_DEFPUSHBUTTON);
|
::GetWindowLong(hWnd, GWL_STYLE) | BS_DEFPUSHBUTTON);
|
||||||
InvalidateRect(hWnd, nullptr, TRUE);
|
InvalidateRect(hWnd, nullptr, TRUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
UINT GetBaseDPI()
|
||||||
|
{
|
||||||
|
return 96;
|
||||||
|
}
|
||||||
|
|
||||||
|
UINT GetDPIForWindow(HWND hWnd)
|
||||||
|
{
|
||||||
|
InitializeDPIFunctionPointersIfNeeded();
|
||||||
|
if (hWnd && pfnGetDpiForWindow)
|
||||||
|
return pfnGetDpiForWindow(hWnd);
|
||||||
|
if (pfnGetDpiForSystem)
|
||||||
|
return pfnGetDpiForSystem();
|
||||||
|
HDC hDC = GetDC(hWnd);
|
||||||
|
if (hDC)
|
||||||
|
{
|
||||||
|
auto dpi = GetDeviceCaps(hDC, LOGPIXELSX);
|
||||||
|
ReleaseDC(hWnd, hDC);
|
||||||
|
return dpi;
|
||||||
|
}
|
||||||
|
return GetBaseDPI();
|
||||||
|
}
|
||||||
|
|
||||||
|
int DpToPixels(int dp, HWND hWnd)
|
||||||
|
{
|
||||||
|
return dp * GetDPIForWindow(hWnd) / GetBaseDPI();
|
||||||
|
}
|
||||||
|
|
||||||
|
int GetSystemMetricsForWindow(int index, HWND hWnd)
|
||||||
|
{
|
||||||
|
InitializeDPIFunctionPointersIfNeeded();
|
||||||
|
auto dpi = GetDPIForWindow(hWnd);
|
||||||
|
if (pfnGetSystemMetricsForDpi)
|
||||||
|
{
|
||||||
|
return pfnGetSystemMetricsForDpi(index, dpi);
|
||||||
|
}
|
||||||
|
auto systemDpi = GetDPIForWindow(nullptr);
|
||||||
|
return GetSystemMetrics(index) * dpi / systemDpi;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
|
@ -15,7 +15,15 @@
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
#include <commctrl.h>
|
#include <commctrl.h>
|
||||||
|
|
||||||
|
namespace celestia::win32
|
||||||
|
{
|
||||||
|
|
||||||
void SetMouseCursor(LPCTSTR lpCursor);
|
void SetMouseCursor(LPCTSTR lpCursor);
|
||||||
void CenterWindow(HWND hParent, HWND hWnd);
|
void CenterWindow(HWND hParent, HWND hWnd);
|
||||||
void RemoveButtonDefaultStyle(HWND hWnd);
|
void RemoveButtonDefaultStyle(HWND hWnd);
|
||||||
void AddButtonDefaultStyle(HWND hWnd);
|
void AddButtonDefaultStyle(HWND hWnd);
|
||||||
|
int DpToPixels(int dp, HWND hWnd);
|
||||||
|
UINT GetDPIForWindow(HWND hWnd);
|
||||||
|
int GetSystemMetricsForWindow(int index, HWND hWnd);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
|
@ -332,88 +332,59 @@ void ViewOptionsDialog::SetControls(HWND hDlg)
|
||||||
int orbitMask = appCore->getRenderer()->getOrbitMask();
|
int orbitMask = appCore->getRenderer()->getOrbitMask();
|
||||||
|
|
||||||
//Set checkboxes and radiobuttons
|
//Set checkboxes and radiobuttons
|
||||||
SendDlgItemMessage(hDlg, IDC_SHOWATMOSPHERES, BM_SETCHECK,
|
dlgCheck64(hDlg, IDC_SHOWATMOSPHERES, renderFlags, Renderer::ShowAtmospheres);
|
||||||
(renderFlags & Renderer::ShowAtmospheres)? BST_CHECKED:BST_UNCHECKED, 0);
|
dlgCheck64(hDlg, IDC_SHOWCELESTIALGRID, renderFlags, Renderer::ShowCelestialSphere);
|
||||||
SendDlgItemMessage(hDlg, IDC_SHOWCELESTIALGRID, BM_SETCHECK,
|
dlgCheck64(hDlg, IDC_SHOWHORIZONGRID, renderFlags, Renderer::ShowHorizonGrid);
|
||||||
(renderFlags & Renderer::ShowCelestialSphere)? BST_CHECKED:BST_UNCHECKED, 0);
|
dlgCheck64(hDlg, IDC_SHOWGALACTICGRID, renderFlags, Renderer::ShowGalacticGrid);
|
||||||
SendDlgItemMessage(hDlg, IDC_SHOWHORIZONGRID, BM_SETCHECK,
|
dlgCheck64(hDlg, IDC_SHOWECLIPTICGRID, renderFlags, Renderer::ShowEclipticGrid);
|
||||||
(renderFlags & Renderer::ShowHorizonGrid)? BST_CHECKED:BST_UNCHECKED, 0);
|
dlgCheck64(hDlg, IDC_SHOWECLIPTIC, renderFlags, Renderer::ShowEcliptic);
|
||||||
SendDlgItemMessage(hDlg, IDC_SHOWGALACTICGRID, BM_SETCHECK,
|
dlgCheck64(hDlg, IDC_SHOWCLOUDS, renderFlags, Renderer::ShowCloudMaps);
|
||||||
(renderFlags & Renderer::ShowGalacticGrid)? BST_CHECKED:BST_UNCHECKED, 0);
|
dlgCheck64(hDlg, IDC_SHOWCLOUDSHADOWS, renderFlags, Renderer::ShowCloudShadows);
|
||||||
SendDlgItemMessage(hDlg, IDC_SHOWECLIPTICGRID, BM_SETCHECK,
|
dlgCheck64(hDlg, IDC_SHOWCONSTELLATIONS, renderFlags, Renderer::ShowDiagrams);
|
||||||
(renderFlags & Renderer::ShowEclipticGrid)? BST_CHECKED:BST_UNCHECKED, 0);
|
dlgCheck64(hDlg, IDC_SHOWECLIPSESHADOWS, renderFlags, Renderer::ShowEclipseShadows);
|
||||||
SendDlgItemMessage(hDlg, IDC_SHOWECLIPTIC, BM_SETCHECK,
|
dlgCheck64(hDlg, IDC_SHOWGALAXIES, renderFlags, Renderer::ShowGalaxies);
|
||||||
(renderFlags & Renderer::ShowEcliptic)? BST_CHECKED:BST_UNCHECKED, 0);
|
dlgCheck64(hDlg, IDC_SHOWGLOBULARS, renderFlags, Renderer::ShowGlobulars);
|
||||||
SendDlgItemMessage(hDlg, IDC_SHOWCLOUDS, BM_SETCHECK,
|
dlgCheck64(hDlg, IDC_SHOWNEBULAE, renderFlags, Renderer::ShowNebulae);
|
||||||
(renderFlags & Renderer::ShowCloudMaps)? BST_CHECKED:BST_UNCHECKED, 0);
|
dlgCheck64(hDlg, IDC_SHOWOPENCLUSTERS, renderFlags, Renderer::ShowOpenClusters);
|
||||||
SendDlgItemMessage(hDlg, IDC_SHOWCLOUDSHADOWS, BM_SETCHECK,
|
dlgCheck64(hDlg, IDC_SHOWNIGHTSIDELIGHTS, renderFlags, Renderer::ShowNightMaps);
|
||||||
(renderFlags & Renderer::ShowCloudShadows)? BST_CHECKED:BST_UNCHECKED, 0);
|
dlgCheck64(hDlg, IDC_SHOWORBITS, renderFlags, Renderer::ShowOrbits);
|
||||||
SendDlgItemMessage(hDlg, IDC_SHOWCONSTELLATIONS, BM_SETCHECK,
|
|
||||||
(renderFlags & Renderer::ShowDiagrams)? BST_CHECKED:BST_UNCHECKED, 0);
|
|
||||||
SendDlgItemMessage(hDlg, IDC_SHOWECLIPSESHADOWS, BM_SETCHECK,
|
|
||||||
(renderFlags & Renderer::ShowEclipseShadows)? BST_CHECKED:BST_UNCHECKED, 0);
|
|
||||||
SendDlgItemMessage(hDlg, IDC_SHOWGALAXIES, BM_SETCHECK,
|
|
||||||
(renderFlags & Renderer::ShowGalaxies)? BST_CHECKED:BST_UNCHECKED, 0);
|
|
||||||
SendDlgItemMessage(hDlg, IDC_SHOWGLOBULARS, BM_SETCHECK,
|
|
||||||
(renderFlags & Renderer::ShowGlobulars)? BST_CHECKED:BST_UNCHECKED, 0);
|
|
||||||
SendDlgItemMessage(hDlg, IDC_SHOWNEBULAE, BM_SETCHECK,
|
|
||||||
(renderFlags & Renderer::ShowNebulae)? BST_CHECKED:BST_UNCHECKED, 0);
|
|
||||||
SendDlgItemMessage(hDlg, IDC_SHOWOPENCLUSTERS, BM_SETCHECK,
|
|
||||||
(renderFlags & Renderer::ShowOpenClusters)? BST_CHECKED:BST_UNCHECKED, 0);
|
|
||||||
SendDlgItemMessage(hDlg, IDC_SHOWNIGHTSIDELIGHTS, BM_SETCHECK,
|
|
||||||
(renderFlags & Renderer::ShowNightMaps)? BST_CHECKED:BST_UNCHECKED, 0);
|
|
||||||
dlgCheck64(hDlg, IDC_SHOWORBITS, renderFlags, Renderer::ShowOrbits);
|
|
||||||
dlgCheck64(hDlg, IDC_SHOWFADINGORBITS, renderFlags, Renderer::ShowFadingOrbits);
|
dlgCheck64(hDlg, IDC_SHOWFADINGORBITS, renderFlags, Renderer::ShowFadingOrbits);
|
||||||
dlgCheck64(hDlg, IDC_SHOWPARTIALTRAJECTORIES, renderFlags, Renderer::ShowPartialTrajectories);
|
dlgCheck64(hDlg, IDC_SHOWPARTIALTRAJECTORIES, renderFlags, Renderer::ShowPartialTrajectories);
|
||||||
dlgCheck(hDlg, IDC_PLANETORBITS, orbitMask, Body::Planet);
|
dlgCheck(hDlg, IDC_PLANETORBITS, orbitMask, Body::Planet);
|
||||||
dlgCheck(hDlg, IDC_DWARFPLANETORBITS,orbitMask, Body::DwarfPlanet);
|
dlgCheck(hDlg, IDC_DWARFPLANETORBITS,orbitMask, Body::DwarfPlanet);
|
||||||
dlgCheck(hDlg, IDC_MOONORBITS, orbitMask, Body::Moon);
|
dlgCheck(hDlg, IDC_MOONORBITS, orbitMask, Body::Moon);
|
||||||
dlgCheck(hDlg, IDC_MINORMOONORBITS, orbitMask, Body::MinorMoon);
|
dlgCheck(hDlg, IDC_MINORMOONORBITS, orbitMask, Body::MinorMoon);
|
||||||
dlgCheck(hDlg, IDC_ASTEROIDORBITS, orbitMask, Body::Asteroid);
|
dlgCheck(hDlg, IDC_ASTEROIDORBITS, orbitMask, Body::Asteroid);
|
||||||
dlgCheck(hDlg, IDC_COMETORBITS, orbitMask, Body::Comet);
|
dlgCheck(hDlg, IDC_COMETORBITS, orbitMask, Body::Comet);
|
||||||
dlgCheck(hDlg, IDC_SPACECRAFTORBITS, orbitMask, Body::Spacecraft);
|
dlgCheck(hDlg, IDC_SPACECRAFTORBITS, orbitMask, Body::Spacecraft);
|
||||||
dlgCheck(hDlg, IDC_STARORBITS, orbitMask, Body::Stellar);
|
dlgCheck(hDlg, IDC_STARORBITS, orbitMask, Body::Stellar);
|
||||||
SendDlgItemMessage(hDlg, IDC_SHOWPLANETS, BM_SETCHECK,
|
dlgCheck64(hDlg, IDC_SHOWPLANETS, renderFlags, Renderer::ShowPlanets);
|
||||||
(renderFlags & Renderer::ShowPlanets) != 0 ? BST_CHECKED : BST_UNCHECKED, 0);
|
dlgCheck64(hDlg, IDC_SHOWDWARFPLANETS, renderFlags, Renderer::ShowDwarfPlanets);
|
||||||
SendDlgItemMessage(hDlg, IDC_SHOWDWARFPLANETS, BM_SETCHECK,
|
dlgCheck64(hDlg, IDC_SHOWMOONS, renderFlags, Renderer::ShowMoons);
|
||||||
((renderFlags ^ Renderer::ShowDwarfPlanets) != 0) ? BST_CHECKED : BST_UNCHECKED, 0);
|
dlgCheck64(hDlg, IDC_SHOWMINORMOONS, renderFlags, Renderer::ShowMinorMoons);
|
||||||
SendDlgItemMessage(hDlg, IDC_SHOWMOONS, BM_SETCHECK,
|
dlgCheck64(hDlg, IDC_SHOWASTEROIDS, renderFlags, Renderer::ShowAsteroids);
|
||||||
((renderFlags ^ Renderer::ShowMoons) != 0) ? BST_CHECKED : BST_UNCHECKED, 0);
|
dlgCheck64(hDlg, IDC_SHOWCOMETS, renderFlags, Renderer::ShowComets);
|
||||||
SendDlgItemMessage(hDlg, IDC_SHOWMINORMOONS, BM_SETCHECK,
|
dlgCheck64(hDlg, IDC_SHOWSPACECRAFTS, renderFlags, Renderer::ShowSpacecrafts);
|
||||||
((renderFlags ^ Renderer::ShowMinorMoons) != 0) ? BST_CHECKED : BST_UNCHECKED, 0);
|
dlgCheck64(hDlg, IDC_SHOWSTARS, renderFlags, Renderer::ShowStars);
|
||||||
SendDlgItemMessage(hDlg, IDC_SHOWASTEROIDS, BM_SETCHECK,
|
dlgCheck64(hDlg, IDC_SHOWCONSTELLATIONBORDERS, renderFlags, Renderer::ShowBoundaries);
|
||||||
((renderFlags ^ Renderer::ShowAsteroids) != 0) ? BST_CHECKED : BST_UNCHECKED, 0);
|
dlgCheck64(hDlg, IDC_SHOWRINGSHADOWS, renderFlags, Renderer::ShowRingShadows);
|
||||||
SendDlgItemMessage(hDlg, IDC_SHOWCOMETS, BM_SETCHECK,
|
dlgCheck64(hDlg, IDC_SHOWRINGS, renderFlags, Renderer::ShowPlanetRings);
|
||||||
((renderFlags ^ Renderer::ShowComets) != 0) ? BST_CHECKED : BST_UNCHECKED, 0);
|
dlgCheck64(hDlg, IDC_SHOWCOMETTAILS, renderFlags, Renderer::ShowCometTails);
|
||||||
SendDlgItemMessage(hDlg, IDC_SHOWSPACECRAFTS, BM_SETCHECK,
|
dlgCheck64(hDlg, IDC_SHOWMARKERS, renderFlags, Renderer::ShowMarkers);
|
||||||
((renderFlags ^ Renderer::ShowSpacecrafts) != 0) ? BST_CHECKED : BST_UNCHECKED, 0);
|
|
||||||
SendDlgItemMessage(hDlg, IDC_SHOWSTARS, BM_SETCHECK,
|
|
||||||
(renderFlags & Renderer::ShowStars)? BST_CHECKED:BST_UNCHECKED, 0);
|
|
||||||
SendDlgItemMessage(hDlg, IDC_SHOWCONSTELLATIONBORDERS, BM_SETCHECK,
|
|
||||||
(renderFlags & Renderer::ShowBoundaries)? BST_CHECKED:BST_UNCHECKED, 0);
|
|
||||||
SendDlgItemMessage(hDlg, IDC_SHOWRINGSHADOWS, BM_SETCHECK,
|
|
||||||
(renderFlags & Renderer::ShowRingShadows)? BST_CHECKED:BST_UNCHECKED, 0);
|
|
||||||
SendDlgItemMessage(hDlg, IDC_SHOWRINGS, BM_SETCHECK,
|
|
||||||
(renderFlags & Renderer::ShowPlanetRings)? BST_CHECKED:BST_UNCHECKED, 0);
|
|
||||||
SendDlgItemMessage(hDlg, IDC_SHOWCOMETTAILS, BM_SETCHECK,
|
|
||||||
(renderFlags & Renderer::ShowCometTails)? BST_CHECKED:BST_UNCHECKED, 0);
|
|
||||||
SendDlgItemMessage(hDlg, IDC_SHOWMARKERS, BM_SETCHECK,
|
|
||||||
(renderFlags & Renderer::ShowMarkers)? BST_CHECKED:BST_UNCHECKED, 0);
|
|
||||||
|
|
||||||
dlgCheck(hDlg, IDC_LABELCONSTELLATIONS, labelMode, Renderer::ConstellationLabels);
|
dlgCheck(hDlg, IDC_LABELCONSTELLATIONS, labelMode, Renderer::ConstellationLabels);
|
||||||
SendDlgItemMessage(hDlg, IDC_LABELCONSTELLATIONSLATIN, BM_SETCHECK,
|
dlgCheck(hDlg, IDC_LABELCONSTELLATIONSLATIN, ~labelMode, Renderer::I18nConstellationLabels); // check box if flag unset
|
||||||
((labelMode & Renderer::I18nConstellationLabels) == 0) ? BST_CHECKED : BST_UNCHECKED, 0);
|
dlgCheck(hDlg, IDC_LABELGALAXIES, labelMode, Renderer::GalaxyLabels);
|
||||||
dlgCheck(hDlg, IDC_LABELGALAXIES, labelMode, Renderer::GalaxyLabels);
|
|
||||||
dlgCheck(hDlg, IDC_LABELGLOBULARS, labelMode, Renderer::GlobularLabels);
|
dlgCheck(hDlg, IDC_LABELGLOBULARS, labelMode, Renderer::GlobularLabels);
|
||||||
dlgCheck(hDlg, IDC_LABELNEBULAE, labelMode, Renderer::NebulaLabels);
|
dlgCheck(hDlg, IDC_LABELNEBULAE, labelMode, Renderer::NebulaLabels);
|
||||||
dlgCheck(hDlg, IDC_LABELOPENCLUSTERS, labelMode, Renderer::OpenClusterLabels);
|
dlgCheck(hDlg, IDC_LABELOPENCLUSTERS, labelMode, Renderer::OpenClusterLabels);
|
||||||
dlgCheck(hDlg, IDC_LABELSTARS, labelMode, Renderer::StarLabels);
|
dlgCheck(hDlg, IDC_LABELSTARS, labelMode, Renderer::StarLabels);
|
||||||
dlgCheck(hDlg, IDC_LABELPLANETS, labelMode, Renderer::PlanetLabels);
|
dlgCheck(hDlg, IDC_LABELPLANETS, labelMode, Renderer::PlanetLabels);
|
||||||
dlgCheck(hDlg, IDC_LABELDWARFPLANETS, labelMode, Renderer::DwarfPlanetLabels);
|
dlgCheck(hDlg, IDC_LABELDWARFPLANETS, labelMode, Renderer::DwarfPlanetLabels);
|
||||||
dlgCheck(hDlg, IDC_LABELMOONS, labelMode, Renderer::MoonLabels);
|
dlgCheck(hDlg, IDC_LABELMOONS, labelMode, Renderer::MoonLabels);
|
||||||
dlgCheck(hDlg, IDC_LABELMINORMOONS, labelMode, Renderer::MinorMoonLabels);
|
dlgCheck(hDlg, IDC_LABELMINORMOONS, labelMode, Renderer::MinorMoonLabels);
|
||||||
dlgCheck(hDlg, IDC_LABELASTEROIDS, labelMode, Renderer::AsteroidLabels);
|
dlgCheck(hDlg, IDC_LABELASTEROIDS, labelMode, Renderer::AsteroidLabels);
|
||||||
dlgCheck(hDlg, IDC_LABELCOMETS, labelMode, Renderer::CometLabels);
|
dlgCheck(hDlg, IDC_LABELCOMETS, labelMode, Renderer::CometLabels);
|
||||||
dlgCheck(hDlg, IDC_LABELSPACECRAFT, labelMode, Renderer::SpacecraftLabels);
|
dlgCheck(hDlg, IDC_LABELSPACECRAFT, labelMode, Renderer::SpacecraftLabels);
|
||||||
|
|
||||||
CheckRadioButton(hDlg, IDC_INFOTEXT0, IDC_INFOTEXT2, IDC_INFOTEXT0 + hudDetail);
|
CheckRadioButton(hDlg, IDC_INFOTEXT0, IDC_INFOTEXT2, IDC_INFOTEXT0 + hudDetail);
|
||||||
|
|
|
@ -209,11 +209,11 @@ float fractalsum(const Eigen::Vector2f& p, float freq)
|
||||||
float fractalsum(const Eigen::Vector3f& p, float freq)
|
float fractalsum(const Eigen::Vector3f& p, float freq)
|
||||||
{
|
{
|
||||||
float t = 0.0f;
|
float t = 0.0f;
|
||||||
|
while (freq >= 1.0f)
|
||||||
for (t = 0.0f; freq >= 1.0f; freq *= 0.5f)
|
|
||||||
{
|
{
|
||||||
Eigen::Vector3f vec = freq * p;
|
Eigen::Vector3f vec = freq * p;
|
||||||
t += noise(vec) / freq;
|
t += noise(vec) / freq;
|
||||||
|
freq *= 0.5f;
|
||||||
}
|
}
|
||||||
|
|
||||||
return t;
|
return t;
|
||||||
|
|
|
@ -14,9 +14,15 @@
|
||||||
#include <iterator>
|
#include <iterator>
|
||||||
#include <tuple>
|
#include <tuple>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
|
#include <celutil/logger.h>
|
||||||
|
|
||||||
|
#ifdef HAVE_MESHOPTIMIZER
|
||||||
|
#include <meshoptimizer.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "mesh.h"
|
#include "mesh.h"
|
||||||
|
|
||||||
|
using celestia::util::GetLogger;
|
||||||
|
|
||||||
namespace cmod
|
namespace cmod
|
||||||
{
|
{
|
||||||
|
@ -38,6 +44,13 @@ VertexDescription appendingAttributes(const VertexDescription& desc, It begin, I
|
||||||
return VertexDescription(std::move(allAttributes));
|
return VertexDescription(std::move(allAttributes));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
isOpaqueMaterial(const Material &material)
|
||||||
|
{
|
||||||
|
return (!(material.opacity > 0.01f && material.opacity < 1.0f)) &&
|
||||||
|
material.blend != BlendMode::AdditiveBlend;
|
||||||
|
}
|
||||||
|
|
||||||
} // end unnamed namespace
|
} // end unnamed namespace
|
||||||
|
|
||||||
|
|
||||||
|
@ -320,13 +333,7 @@ Mesh::addGroup(PrimitiveGroupType prim,
|
||||||
{
|
{
|
||||||
PrimitiveGroup g;
|
PrimitiveGroup g;
|
||||||
if (prim == PrimitiveGroupType::LineStrip || prim == PrimitiveGroupType::LineList)
|
if (prim == PrimitiveGroupType::LineStrip || prim == PrimitiveGroupType::LineList)
|
||||||
{
|
|
||||||
g = createLinePrimitiveGroup(prim == PrimitiveGroupType::LineStrip, indices);
|
g = createLinePrimitiveGroup(prim == PrimitiveGroupType::LineStrip, indices);
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
g.primOverride = prim;
|
|
||||||
}
|
|
||||||
|
|
||||||
g.indices = std::move(indices);
|
g.indices = std::move(indices);
|
||||||
g.prim = prim;
|
g.prim = prim;
|
||||||
|
@ -393,9 +400,80 @@ Mesh::aggregateByMaterial()
|
||||||
{
|
{
|
||||||
return g0.materialIndex < g1.materialIndex;
|
return g0.materialIndex < g1.materialIndex;
|
||||||
});
|
});
|
||||||
|
mergePrimitiveGroups();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
Mesh::mergePrimitiveGroups()
|
||||||
|
{
|
||||||
|
if (groups.size() < 2)
|
||||||
|
return;
|
||||||
|
|
||||||
|
std::vector<PrimitiveGroup> newGroups;
|
||||||
|
for (size_t i = 0; i < groups.size(); i++)
|
||||||
|
{
|
||||||
|
auto &g = groups[i];
|
||||||
|
|
||||||
|
if (g.vertexCountOverride == 0 && g.prim == PrimitiveGroupType::TriStrip)
|
||||||
|
{
|
||||||
|
std::vector<Index32> newIndices;
|
||||||
|
newIndices.reserve(g.indices.size() * 2);
|
||||||
|
for (size_t j = 0, e = g.indices.size() - 2; j < e; j++)
|
||||||
|
{
|
||||||
|
auto x = g.indices[j + 0];
|
||||||
|
auto y = g.indices[j + 1];
|
||||||
|
auto z = g.indices[j + 2];
|
||||||
|
// skip degenerated triangles
|
||||||
|
if (x == y || y == z || z == x)
|
||||||
|
continue;
|
||||||
|
if ((j & 1) != 0) // FIXME: CCW hardcoded
|
||||||
|
std::swap(y, z);
|
||||||
|
newIndices.push_back(x);
|
||||||
|
newIndices.push_back(y);
|
||||||
|
newIndices.push_back(z);
|
||||||
|
}
|
||||||
|
g.indices = std::move(newIndices);
|
||||||
|
g.prim = PrimitiveGroupType::TriList;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (i == 0 || g.vertexCountOverride != 0 || g.prim != PrimitiveGroupType::TriList)
|
||||||
|
{
|
||||||
|
newGroups.push_back(std::move(g));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
auto &p = newGroups.back();
|
||||||
|
if (p.prim != g.prim || p.materialIndex != g.materialIndex)
|
||||||
|
{
|
||||||
|
newGroups.push_back(std::move(g));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
p.indices.reserve(p.indices.size() + g.indices.size());
|
||||||
|
p.indices.insert(p.indices.end(), g.indices.begin(), g.indices.end());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
GetLogger()->info("Optimized mesh groups: had {} groups, now: {} of them.\n", groups.size(), newGroups.size());
|
||||||
|
groups = std::move(newGroups);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
Mesh::optimize()
|
||||||
|
{
|
||||||
|
#ifdef HAVE_MESHOPTIMIZER
|
||||||
|
if (groups.size() > 1)
|
||||||
|
return;
|
||||||
|
|
||||||
|
auto &g = groups.front();
|
||||||
|
|
||||||
|
meshopt_optimizeVertexCache(g.indices.data(), g.indices.data(), g.indices.size(), nVertices);
|
||||||
|
meshopt_optimizeOverdraw(g.indices.data(), g.indices.data(), g.indices.size(), reinterpret_cast<float*>(vertices.data()), nVertices, vertexDesc.strideBytes, 1.05f);
|
||||||
|
meshopt_optimizeVertexFetch(vertices.data(), g.indices.data(), g.indices.size(), vertices.data(), nVertices, vertexDesc.strideBytes);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
Mesh::pick(const Eigen::Vector3d& rayOrigin, const Eigen::Vector3d& rayDirection, PickResult* result) const
|
Mesh::pick(const Eigen::Vector3d& rayOrigin, const Eigen::Vector3d& rayDirection, PickResult* result) const
|
||||||
{
|
{
|
||||||
|
@ -663,4 +741,52 @@ Mesh::getPrimitiveCount() const
|
||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
Mesh::merge(const Mesh &other)
|
||||||
|
{
|
||||||
|
auto &ti = groups.front().indices;
|
||||||
|
const auto &oi = other.groups.front().indices;
|
||||||
|
|
||||||
|
ti.reserve(ti.size() + oi.size());
|
||||||
|
for (auto i : oi)
|
||||||
|
ti.push_back(i + nVertices);
|
||||||
|
|
||||||
|
vertices.reserve(vertices.size() + other.vertices.size());
|
||||||
|
vertices.insert(vertices.end(), other.vertices.begin(), other.vertices.end());
|
||||||
|
|
||||||
|
nVertices += other.nVertices;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
Mesh::canMerge(const Mesh &other, const std::vector<Material> &materials) const
|
||||||
|
{
|
||||||
|
if (getGroupCount() != 1 || other.getGroupCount() != 1)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
const auto &tg = groups.front();
|
||||||
|
const auto &og = other.groups.front();
|
||||||
|
|
||||||
|
if (tg.vertexCountOverride != 0 || og.vertexCountOverride != 0 || tg.prim != PrimitiveGroupType::TriList)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (std::tie(tg.materialIndex, tg.prim, vertexDesc.strideBytes) !=
|
||||||
|
std::tie(og.materialIndex, og.prim, other.vertexDesc.strideBytes))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (!isOpaqueMaterial(materials[tg.materialIndex]) || !isOpaqueMaterial(materials[og.materialIndex]))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
for (auto i = VertexAttributeSemantic::Position;
|
||||||
|
i < VertexAttributeSemantic::SemanticMax;
|
||||||
|
i = static_cast<VertexAttributeSemantic>(1 + static_cast<uint16_t>(i)))
|
||||||
|
{
|
||||||
|
auto &ta = vertexDesc.getAttribute(i);
|
||||||
|
auto &oa = other.vertexDesc.getAttribute(i);
|
||||||
|
if (ta.format != oa.format || ta.offsetWords != oa.offsetWords)
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
} // end namespace cmod
|
} // end namespace cmod
|
||||||
|
|
|
@ -237,8 +237,13 @@ class Mesh
|
||||||
unsigned int getVertexStrideWords() const { return vertexDesc.strideBytes / sizeof(cmod::VWord); }
|
unsigned int getVertexStrideWords() const { return vertexDesc.strideBytes / sizeof(cmod::VWord); }
|
||||||
unsigned int getPrimitiveCount() const;
|
unsigned int getPrimitiveCount() const;
|
||||||
|
|
||||||
|
void merge(const Mesh&);
|
||||||
|
bool canMerge(const Mesh&, const std::vector<Material> &materials) const;
|
||||||
|
void optimize();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
PrimitiveGroup createLinePrimitiveGroup(bool lineStrip, const std::vector<Index32>& indices);
|
PrimitiveGroup createLinePrimitiveGroup(bool lineStrip, const std::vector<Index32>& indices);
|
||||||
|
void mergePrimitiveGroups();
|
||||||
|
|
||||||
VertexDescription vertexDesc{ };
|
VertexDescription vertexDesc{ };
|
||||||
|
|
||||||
|
|
|
@ -15,8 +15,11 @@
|
||||||
|
|
||||||
#include <Eigen/Geometry>
|
#include <Eigen/Geometry>
|
||||||
|
|
||||||
|
#include <celutil/logger.h>
|
||||||
|
|
||||||
#include "model.h"
|
#include "model.h"
|
||||||
|
|
||||||
|
using celestia::util::GetLogger;
|
||||||
|
|
||||||
namespace cmod
|
namespace cmod
|
||||||
{
|
{
|
||||||
|
@ -315,7 +318,6 @@ Model::usesTextureType(TextureSemantic t) const
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
bool
|
bool
|
||||||
Model::OpacityComparator::operator()(const Mesh& a, const Mesh& b) const
|
Model::OpacityComparator::operator()(const Mesh& a, const Mesh& b) const
|
||||||
{
|
{
|
||||||
|
@ -335,6 +337,25 @@ Model::sortMeshes(const MeshComparator& comparator)
|
||||||
|
|
||||||
// Sort the meshes so that completely opaque ones are first
|
// Sort the meshes so that completely opaque ones are first
|
||||||
std::sort(meshes.begin(), meshes.end(), std::ref(comparator));
|
std::sort(meshes.begin(), meshes.end(), std::ref(comparator));
|
||||||
|
|
||||||
|
std::vector<Mesh> newMeshes;
|
||||||
|
newMeshes.push_back(meshes[0].clone());
|
||||||
|
|
||||||
|
for (size_t i = 1; i < meshes.size(); i++)
|
||||||
|
{
|
||||||
|
auto &p = newMeshes.back();
|
||||||
|
if (!p.canMerge(meshes[i], materials))
|
||||||
|
{
|
||||||
|
newMeshes.push_back(meshes[i].clone());
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
p.merge(meshes[i]);
|
||||||
|
}
|
||||||
|
GetLogger()->info("Merged similar meshes: {} -> {}.\n", meshes.size(), newMeshes.size());
|
||||||
|
|
||||||
|
for (auto &mesh : newMeshes)
|
||||||
|
mesh.optimize();
|
||||||
|
meshes = std::move(newMeshes);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // end namespace cmod
|
} // end namespace cmod
|
||||||
|
|
|
@ -266,6 +266,9 @@ static void checkTimeslice(lua_State* l, lua_Debug* /*ar*/)
|
||||||
// allow the script to perform cleanup
|
// allow the script to perform cleanup
|
||||||
void LuaState::cleanup()
|
void LuaState::cleanup()
|
||||||
{
|
{
|
||||||
|
if (!costate)
|
||||||
|
return;
|
||||||
|
|
||||||
if (ioMode == Asking)
|
if (ioMode == Asking)
|
||||||
{
|
{
|
||||||
// Restore renderflags:
|
// Restore renderflags:
|
||||||
|
|
|
@ -2296,7 +2296,6 @@ static int celestia_loadfont(lua_State* l)
|
||||||
CelestiaCore* appCore = getAppCore(l, AllErrors);
|
CelestiaCore* appCore = getAppCore(l, AllErrors);
|
||||||
auto font = LoadTextureFont(appCore->getRenderer(), s);
|
auto font = LoadTextureFont(appCore->getRenderer(), s);
|
||||||
if (font == nullptr) return 0;
|
if (font == nullptr) return 0;
|
||||||
font->buildTexture();
|
|
||||||
return celx.pushClass(font);
|
return celx.pushClass(font);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
// truetypefont.cpp
|
// truetypefont.cpp
|
||||||
//
|
//
|
||||||
// Copyright (C) 2019, Celestia Development Team
|
// Copyright (C) 2019-2022, Celestia Development Team
|
||||||
//
|
//
|
||||||
// This program is free software; you can redistribute it and/or
|
// This program is free software; you can redistribute it and/or
|
||||||
// modify it under the terms of the GNU General Public License
|
// modify it under the terms of the GNU General Public License
|
||||||
|
@ -9,13 +9,15 @@
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <array>
|
#include <array>
|
||||||
#include <iostream>
|
#include <celcompat/charconv.h>
|
||||||
#include <vector>
|
|
||||||
#include <celutil/logger.h>
|
|
||||||
#include <celutil/utf8.h>
|
|
||||||
#include <celengine/glsupport.h>
|
#include <celengine/glsupport.h>
|
||||||
#include <celengine/render.h>
|
#include <celengine/render.h>
|
||||||
|
#include <celutil/logger.h>
|
||||||
|
#include <celutil/utf8.h>
|
||||||
#include <ft2build.h>
|
#include <ft2build.h>
|
||||||
|
#include <map>
|
||||||
|
#include <system_error>
|
||||||
|
#include <vector>
|
||||||
#include FT_FREETYPE_H
|
#include FT_FREETYPE_H
|
||||||
#include "truetypefont.h"
|
#include "truetypefont.h"
|
||||||
|
|
||||||
|
@ -25,26 +27,24 @@
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
using namespace std;
|
using celestia::compat::from_chars;
|
||||||
using celestia::util::GetLogger;
|
using celestia::util::GetLogger;
|
||||||
|
|
||||||
static FT_Library ft = nullptr;
|
|
||||||
|
|
||||||
struct Glyph
|
struct Glyph
|
||||||
{
|
{
|
||||||
wchar_t ch;
|
wchar_t ch;
|
||||||
|
|
||||||
int ax; // advance.x
|
int ax; // advance.x
|
||||||
int ay; // advance.y
|
int ay; // advance.y
|
||||||
|
|
||||||
int bw; // bitmap.width;
|
unsigned int bw; // bitmap.width;
|
||||||
int bh; // bitmap.height;
|
unsigned int bh; // bitmap.height;
|
||||||
|
|
||||||
int bl; // bitmap_left;
|
int bl; // bitmap_left;
|
||||||
int bt; // bitmap_top;
|
int bt; // bitmap_top;
|
||||||
|
|
||||||
float tx; // x offset of glyph in texture coordinates
|
float tx; // x offset of glyph in texture coordinates
|
||||||
float ty; // y offset of glyph in texture coordinates
|
float ty; // y offset of glyph in texture coordinates
|
||||||
};
|
};
|
||||||
|
|
||||||
struct UnicodeBlock
|
struct UnicodeBlock
|
||||||
|
@ -56,75 +56,82 @@ struct TextureFontPrivate
|
||||||
{
|
{
|
||||||
struct FontVertex
|
struct FontVertex
|
||||||
{
|
{
|
||||||
FontVertex(float _x, float _y, float _u, float _v) :
|
FontVertex(float _x, float _y, float _u, float _v) : x(_x), y(_y), u(_u), v(_v)
|
||||||
x(_x), y(_y), u(_u), v(_v)
|
{
|
||||||
{}
|
}
|
||||||
float x, y;
|
float x, y;
|
||||||
float u, v;
|
float u, v;
|
||||||
};
|
};
|
||||||
|
|
||||||
TextureFontPrivate() = delete;
|
|
||||||
TextureFontPrivate(const Renderer *renderer);
|
TextureFontPrivate(const Renderer *renderer);
|
||||||
~TextureFontPrivate();
|
~TextureFontPrivate();
|
||||||
TextureFontPrivate(const TextureFontPrivate&) = default;
|
TextureFontPrivate() = delete;
|
||||||
TextureFontPrivate(TextureFontPrivate&&) = default;
|
TextureFontPrivate(const TextureFontPrivate &) = default;
|
||||||
TextureFontPrivate& operator=(const TextureFontPrivate&) = default;
|
TextureFontPrivate(TextureFontPrivate &&) = default;
|
||||||
TextureFontPrivate& operator=(TextureFontPrivate&&) = default;
|
TextureFontPrivate &operator=(const TextureFontPrivate &) = default;
|
||||||
|
TextureFontPrivate &operator=(TextureFontPrivate &&) = default;
|
||||||
|
|
||||||
float render(const string &s, float x, float y);
|
float render(std::string_view s, float x, float y);
|
||||||
float render(wchar_t ch, float xoffset, float yoffset);
|
float render(wchar_t ch, float xoffset, float yoffset);
|
||||||
|
|
||||||
bool buildAtlas();
|
bool buildAtlas();
|
||||||
void computeTextureSize();
|
void computeTextureSize();
|
||||||
bool loadGlyphInfo(wchar_t, Glyph&);
|
bool loadGlyphInfo(wchar_t /*ch*/, Glyph & /*c*/) const;
|
||||||
void initCommonGlyphs();
|
void initCommonGlyphs();
|
||||||
int getCommonGlyphsCount();
|
int getCommonGlyphsCount();
|
||||||
Glyph& getGlyph(wchar_t);
|
Glyph & getGlyph(wchar_t /*ch*/);
|
||||||
Glyph& getGlyph(wchar_t, wchar_t);
|
Glyph & getGlyph(wchar_t /*ch*/, wchar_t /*fallback*/);
|
||||||
int toPos(wchar_t) const;
|
[[nodiscard]] int toPos(wchar_t /*ch*/) const;
|
||||||
void optimize();
|
void optimize();
|
||||||
CelestiaGLProgram* getProgram();
|
CelestiaGLProgram *getProgram();
|
||||||
void flush();
|
void flush();
|
||||||
|
|
||||||
const Renderer *m_renderer;
|
const Renderer *m_renderer;
|
||||||
CelestiaGLProgram *m_prog { nullptr };
|
CelestiaGLProgram *m_prog{ nullptr };
|
||||||
|
|
||||||
FT_Face m_face; // font face
|
FT_Face m_face; // font face
|
||||||
|
|
||||||
int m_maxAscent;
|
int m_maxAscent{ 0 };
|
||||||
int m_maxDescent;
|
int m_maxDescent{ 0 };
|
||||||
int m_maxWidth;
|
int m_maxWidth{ 0 };
|
||||||
|
|
||||||
int m_texWidth;
|
int m_texWidth{ 0 };
|
||||||
int m_texHeight;
|
int m_texHeight{ 0 };
|
||||||
|
|
||||||
GLuint m_texName { 0 }; // texture object
|
GLuint m_texName{ 0 }; // texture object
|
||||||
vector<Glyph> m_glyphs; // character information
|
std::vector<Glyph> m_glyphs; // character information
|
||||||
GLint m_maxTextureSize; // max supported texture size
|
GLint m_maxTextureSize; // max supported texture size
|
||||||
|
|
||||||
array<UnicodeBlock, 2> m_unicodeBlocks;
|
std::array<UnicodeBlock, 2> m_unicodeBlocks;
|
||||||
int m_commonGlyphsCount { 0 };
|
int m_commonGlyphsCount{ 0 };
|
||||||
|
|
||||||
int m_inserted { 0 };
|
int m_inserted{ 0 };
|
||||||
|
|
||||||
Eigen::Matrix4f m_projection;
|
Eigen::Matrix4f m_projection;
|
||||||
Eigen::Matrix4f m_modelView;
|
Eigen::Matrix4f m_modelView;
|
||||||
bool m_shaderInUse { false };
|
bool m_shaderInUse{ false };
|
||||||
vector<FontVertex> m_fontVertices;
|
std::vector<FontVertex> m_fontVertices;
|
||||||
};
|
};
|
||||||
|
|
||||||
inline float pt_to_px(float pt, int dpi = 96)
|
namespace
|
||||||
{
|
{
|
||||||
return dpi == 0 ? pt : pt / 72.0 * dpi;
|
|
||||||
|
inline float
|
||||||
|
pt_to_px(float pt, int dpi = 96)
|
||||||
|
{
|
||||||
|
return dpi == 0 ? pt : pt / 72.0f * static_cast<float>(dpi);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Glyph g_badGlyph = { 0, 0, 0, 0, 0, 0, 0, 0.0f, 0.0f };
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
/*
|
/*
|
||||||
first = ((c / 32) + 1) * 32 == c & ~0xdf
|
first = ((c / 32) + 1) * 32 == c & ~0xdf
|
||||||
last = first + 32
|
last = first + 32
|
||||||
*/
|
*/
|
||||||
|
|
||||||
TextureFontPrivate::TextureFontPrivate(const Renderer *renderer) :
|
TextureFontPrivate::TextureFontPrivate(const Renderer *renderer) : m_renderer(renderer)
|
||||||
m_renderer(renderer)
|
|
||||||
{
|
{
|
||||||
m_unicodeBlocks[0] = { 0x0020, 0x007E }; // Basic Latin
|
m_unicodeBlocks[0] = { 0x0020, 0x007E }; // Basic Latin
|
||||||
m_unicodeBlocks[1] = { 0x03B1, 0x03CF }; // Lower case Greek
|
m_unicodeBlocks[1] = { 0x03B1, 0x03CF }; // Lower case Greek
|
||||||
|
@ -134,13 +141,12 @@ TextureFontPrivate::TextureFontPrivate(const Renderer *renderer) :
|
||||||
|
|
||||||
TextureFontPrivate::~TextureFontPrivate()
|
TextureFontPrivate::~TextureFontPrivate()
|
||||||
{
|
{
|
||||||
if (m_face)
|
if (m_face != nullptr) FT_Done_Face(m_face);
|
||||||
FT_Done_Face(m_face);
|
if (m_texName != 0) glDeleteTextures(1, &m_texName);
|
||||||
if (m_texName != 0)
|
|
||||||
glDeleteTextures(1, &m_texName);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool TextureFontPrivate::loadGlyphInfo(wchar_t ch, Glyph &c)
|
bool
|
||||||
|
TextureFontPrivate::loadGlyphInfo(wchar_t ch, Glyph &c) const
|
||||||
{
|
{
|
||||||
FT_GlyphSlot g = m_face->glyph;
|
FT_GlyphSlot g = m_face->glyph;
|
||||||
if (FT_Load_Char(m_face, ch, FT_LOAD_RENDER) != 0)
|
if (FT_Load_Char(m_face, ch, FT_LOAD_RENDER) != 0)
|
||||||
|
@ -159,10 +165,10 @@ bool TextureFontPrivate::loadGlyphInfo(wchar_t ch, Glyph &c)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void TextureFontPrivate::initCommonGlyphs()
|
void
|
||||||
|
TextureFontPrivate::initCommonGlyphs()
|
||||||
{
|
{
|
||||||
if (m_glyphs.size() > 0)
|
if (!m_glyphs.empty()) return;
|
||||||
return;
|
|
||||||
|
|
||||||
m_glyphs.reserve(256);
|
m_glyphs.reserve(256);
|
||||||
|
|
||||||
|
@ -178,12 +184,13 @@ void TextureFontPrivate::initCommonGlyphs()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void TextureFontPrivate::computeTextureSize()
|
void
|
||||||
|
TextureFontPrivate::computeTextureSize()
|
||||||
{
|
{
|
||||||
int roww = 0;
|
int roww = 0;
|
||||||
int rowh = 0;
|
int rowh = 0;
|
||||||
int w = 0;
|
int w = 0;
|
||||||
int h = 0;
|
int h = 0;
|
||||||
|
|
||||||
// Find minimum size for a texture holding all visible ASCII characters
|
// Find minimum size for a texture holding all visible ASCII characters
|
||||||
for (const auto &c : m_glyphs)
|
for (const auto &c : m_glyphs)
|
||||||
|
@ -192,23 +199,24 @@ void TextureFontPrivate::computeTextureSize()
|
||||||
|
|
||||||
if (roww + c.bw + 1 >= m_maxTextureSize)
|
if (roww + c.bw + 1 >= m_maxTextureSize)
|
||||||
{
|
{
|
||||||
w = max(w, roww);
|
w = std::max(w, roww);
|
||||||
h += rowh;
|
h += rowh;
|
||||||
roww = 0;
|
roww = 0;
|
||||||
rowh = 0;
|
rowh = 0;
|
||||||
}
|
}
|
||||||
roww += c.bw + 1;
|
roww += c.bw + 1;
|
||||||
rowh = max(rowh, (int)c.bh);
|
rowh = std::max(rowh, static_cast<int>(c.bh));
|
||||||
}
|
}
|
||||||
|
|
||||||
w = max(w, roww);
|
w = std::max(w, roww);
|
||||||
h += rowh;
|
h += rowh;
|
||||||
|
|
||||||
m_texWidth = w;
|
m_texWidth = w;
|
||||||
m_texHeight = h;
|
m_texHeight = h;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool TextureFontPrivate::buildAtlas()
|
bool
|
||||||
|
TextureFontPrivate::buildAtlas()
|
||||||
{
|
{
|
||||||
FT_GlyphSlot g = m_face->glyph;
|
FT_GlyphSlot g = m_face->glyph;
|
||||||
|
|
||||||
|
@ -217,14 +225,20 @@ bool TextureFontPrivate::buildAtlas()
|
||||||
|
|
||||||
// Create a texture that will be used to hold all glyphs
|
// Create a texture that will be used to hold all glyphs
|
||||||
glActiveTexture(GL_TEXTURE0);
|
glActiveTexture(GL_TEXTURE0);
|
||||||
if (m_texName != 0)
|
if (m_texName != 0) glDeleteTextures(1, &m_texName);
|
||||||
glDeleteTextures(1, &m_texName);
|
|
||||||
glGenTextures(1, &m_texName);
|
glGenTextures(1, &m_texName);
|
||||||
if (m_texName == 0)
|
if (m_texName == 0) return false;
|
||||||
return false;
|
|
||||||
|
|
||||||
glBindTexture(GL_TEXTURE_2D, m_texName);
|
glBindTexture(GL_TEXTURE_2D, m_texName);
|
||||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, m_texWidth, m_texHeight, 0, GL_ALPHA, GL_UNSIGNED_BYTE, 0);
|
glTexImage2D(GL_TEXTURE_2D,
|
||||||
|
0,
|
||||||
|
GL_ALPHA,
|
||||||
|
m_texWidth,
|
||||||
|
m_texHeight,
|
||||||
|
0,
|
||||||
|
GL_ALPHA,
|
||||||
|
GL_UNSIGNED_BYTE,
|
||||||
|
nullptr);
|
||||||
|
|
||||||
// We require 1 byte alignment when uploading texture data
|
// We require 1 byte alignment when uploading texture data
|
||||||
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
|
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
|
||||||
|
@ -247,42 +261,53 @@ bool TextureFontPrivate::buildAtlas()
|
||||||
{
|
{
|
||||||
if (c.ch == 0) continue; // skip bad glyphs
|
if (c.ch == 0) continue; // skip bad glyphs
|
||||||
|
|
||||||
if (FT_Load_Char(m_face, c.ch, FT_LOAD_RENDER))
|
if (FT_Load_Char(m_face, c.ch, FT_LOAD_RENDER) != 0)
|
||||||
{
|
{
|
||||||
GetLogger()->warn("Loading character {:x} failed!\n", static_cast<unsigned>(c.ch));
|
GetLogger()->warn("Loading character {:x} failed!\n", static_cast<unsigned>(c.ch));
|
||||||
c.ch = 0;
|
c.ch = 0;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ox + int(g->bitmap.width) > int(m_texWidth))
|
if (ox + int(g->bitmap.width) > int(m_texWidth))
|
||||||
{
|
{
|
||||||
oy += rowh;
|
oy += rowh;
|
||||||
rowh = 0;
|
rowh = 0;
|
||||||
ox = 0;
|
ox = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
glTexSubImage2D(GL_TEXTURE_2D, 0, ox, oy, g->bitmap.width, g->bitmap.rows, GL_ALPHA, GL_UNSIGNED_BYTE, g->bitmap.buffer);
|
glTexSubImage2D(GL_TEXTURE_2D,
|
||||||
c.tx = (float)ox / (float)m_texWidth;
|
0,
|
||||||
c.ty = (float)oy / (float)m_texHeight;
|
ox,
|
||||||
|
oy,
|
||||||
|
g->bitmap.width,
|
||||||
|
g->bitmap.rows,
|
||||||
|
GL_ALPHA,
|
||||||
|
GL_UNSIGNED_BYTE,
|
||||||
|
g->bitmap.buffer);
|
||||||
|
c.tx = static_cast<float>(ox) / static_cast<float>(m_texWidth);
|
||||||
|
c.ty = static_cast<float>(oy) / static_cast<float>(m_texHeight);
|
||||||
|
|
||||||
rowh = max(rowh, (int)g->bitmap.rows);
|
rowh = std::max(rowh, static_cast<int>(g->bitmap.rows));
|
||||||
ox += g->bitmap.width + 1;
|
ox += g->bitmap.width + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if DUMP_TEXTURE
|
#if DUMP_TEXTURE
|
||||||
fmt::printf(cout/*cerr*/, "Generated a {} x {} ({} kb) texture atlas\n", m_texWidth, m_texHeight, m_texWidth * m_texHeight / 1024);
|
fmt::print("Generated a {} x {} ({} kb) texture atlas\n",
|
||||||
size_t img_size = sizeof(uint8_t) * m_texWidth * m_texHeight * 4;
|
m_texWidth, m_texHeight,
|
||||||
uint8_t *raw_img = new uint8_t[img_size];
|
m_texWidth * m_texHeight / 1024);
|
||||||
|
size_t img_size = sizeof(uint8_t) * m_texWidth * m_texHeight * 4;
|
||||||
|
uint8_t *raw_img = new uint8_t[img_size];
|
||||||
glGetTexImage(GL_TEXTURE_2D, 0, GL_BGRA, GL_UNSIGNED_BYTE, raw_img);
|
glGetTexImage(GL_TEXTURE_2D, 0, GL_BGRA, GL_UNSIGNED_BYTE, raw_img);
|
||||||
ofstream f(fmt::format("/tmp/texture_{}x{}.data", m_texWidth, m_texHeight), ios::binary);
|
ofstream f(fmt::format("/tmp/texture_{}x{}.data", m_texWidth, m_texHeight), ios::binary);
|
||||||
f.write(reinterpret_cast<char*>(raw_img), img_size);
|
f.write(reinterpret_cast<char *>(raw_img), img_size);
|
||||||
f.close();
|
f.close();
|
||||||
delete[] raw_img;
|
delete[] raw_img;
|
||||||
#endif
|
#endif
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
int TextureFontPrivate::getCommonGlyphsCount()
|
int
|
||||||
|
TextureFontPrivate::getCommonGlyphsCount()
|
||||||
{
|
{
|
||||||
if (m_commonGlyphsCount == 0)
|
if (m_commonGlyphsCount == 0)
|
||||||
{
|
{
|
||||||
|
@ -292,17 +317,16 @@ int TextureFontPrivate::getCommonGlyphsCount()
|
||||||
return m_commonGlyphsCount;
|
return m_commonGlyphsCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
int TextureFontPrivate::toPos(wchar_t ch) const
|
int
|
||||||
|
TextureFontPrivate::toPos(wchar_t ch) const
|
||||||
{
|
{
|
||||||
int pos = 0;
|
int pos = 0;
|
||||||
|
|
||||||
if (ch > m_unicodeBlocks.back().last)
|
if (ch > m_unicodeBlocks.back().last) return -1;
|
||||||
return -1;
|
|
||||||
|
|
||||||
for (const auto &r : m_unicodeBlocks)
|
for (const auto &r : m_unicodeBlocks)
|
||||||
{
|
{
|
||||||
if (ch < r.first)
|
if (ch < r.first) return -1;
|
||||||
return -1;
|
|
||||||
|
|
||||||
if (ch <= r.last)
|
if (ch <= r.last)
|
||||||
{
|
{
|
||||||
|
@ -314,22 +338,22 @@ int TextureFontPrivate::toPos(wchar_t ch) const
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
Glyph& TextureFontPrivate::getGlyph(wchar_t ch, wchar_t fallback)
|
Glyph &
|
||||||
|
TextureFontPrivate::getGlyph(wchar_t ch, wchar_t fallback)
|
||||||
{
|
{
|
||||||
auto &g = getGlyph(ch);
|
auto &g = getGlyph(ch);
|
||||||
return g.ch == ch ? g : getGlyph(fallback);
|
return g.ch == ch ? g : getGlyph(fallback);
|
||||||
}
|
}
|
||||||
|
|
||||||
Glyph g_badGlyph = {0, 0, 0, 0, 0, 0, 0, 0.0f, 0.0f};
|
Glyph &
|
||||||
Glyph& TextureFontPrivate::getGlyph(wchar_t ch)
|
TextureFontPrivate::getGlyph(wchar_t ch)
|
||||||
{
|
{
|
||||||
auto pos = toPos(ch);
|
if (auto pos = toPos(ch); pos != -1)
|
||||||
if (pos != -1)
|
|
||||||
return m_glyphs[pos];
|
return m_glyphs[pos];
|
||||||
|
|
||||||
auto it = find_if(m_glyphs.begin() + getCommonGlyphsCount(),
|
auto it = find_if(m_glyphs.begin() + getCommonGlyphsCount(),
|
||||||
m_glyphs.end(),
|
m_glyphs.end(),
|
||||||
[ch](Glyph &g) { return g.ch == ch; });
|
[ch](const Glyph &g) { return g.ch == ch; });
|
||||||
|
|
||||||
if (it != m_glyphs.end())
|
if (it != m_glyphs.end())
|
||||||
return *it;
|
return *it;
|
||||||
|
@ -341,14 +365,14 @@ Glyph& TextureFontPrivate::getGlyph(wchar_t ch)
|
||||||
flush(); // render text to avoid garbled output due to changed texture
|
flush(); // render text to avoid garbled output due to changed texture
|
||||||
|
|
||||||
m_glyphs.push_back(c);
|
m_glyphs.push_back(c);
|
||||||
if (++m_inserted == 10)
|
if (++m_inserted == 10) optimize();
|
||||||
optimize();
|
|
||||||
buildAtlas();
|
buildAtlas();
|
||||||
|
|
||||||
return m_glyphs.back();
|
return m_glyphs.back();
|
||||||
}
|
}
|
||||||
|
|
||||||
void TextureFontPrivate::optimize()
|
void
|
||||||
|
TextureFontPrivate::optimize()
|
||||||
{
|
{
|
||||||
m_inserted = 0;
|
m_inserted = 0;
|
||||||
}
|
}
|
||||||
|
@ -358,34 +382,33 @@ void TextureFontPrivate::optimize()
|
||||||
* Rendering starts at coordinates (x, y), z is always 0.
|
* Rendering starts at coordinates (x, y), z is always 0.
|
||||||
* The pixel coordinates that the FreeType2 library uses are scaled by (sx, sy).
|
* The pixel coordinates that the FreeType2 library uses are scaled by (sx, sy).
|
||||||
*/
|
*/
|
||||||
float TextureFontPrivate::render(const string &s, float x, float y)
|
float
|
||||||
|
TextureFontPrivate::render(std::string_view s, float x, float y)
|
||||||
{
|
{
|
||||||
if (m_texName == 0)
|
if (m_texName == 0) return 0;
|
||||||
return 0;
|
|
||||||
|
|
||||||
// Use the texture containing the atlas
|
// Use the texture containing the atlas
|
||||||
glBindTexture(GL_TEXTURE_2D, m_texName);
|
glBindTexture(GL_TEXTURE_2D, m_texName);
|
||||||
|
|
||||||
// Loop through all characters
|
// Loop through all characters
|
||||||
int len = s.length();
|
int len = s.length();
|
||||||
bool validChar = true;
|
bool validChar = true;
|
||||||
int i = 0;
|
int i = 0;
|
||||||
|
|
||||||
while (i < len && validChar)
|
while (i < len && validChar)
|
||||||
{
|
{
|
||||||
wchar_t ch = 0;
|
wchar_t ch = 0;
|
||||||
validChar = UTF8Decode(s, i, ch);
|
validChar = UTF8Decode(s, i, ch);
|
||||||
if (!validChar)
|
if (!validChar) break;
|
||||||
break;
|
|
||||||
i += UTF8EncodedSize(ch);
|
i += UTF8EncodedSize(ch);
|
||||||
|
|
||||||
auto& g = getGlyph(ch, L'?');
|
auto &g = getGlyph(ch, L'?');
|
||||||
|
|
||||||
// Calculate the vertex and texture coordinates
|
// Calculate the vertex and texture coordinates
|
||||||
const float x1 = x + g.bl;
|
const float x1 = x + g.bl;
|
||||||
const float y1 = y + g.bt - g.bh;
|
const float y1 = y + g.bt - g.bh;
|
||||||
const float w = g.bw;
|
const float w = g.bw;
|
||||||
const float h = g.bh;
|
const float h = g.bh;
|
||||||
const float x2 = x1 + w;
|
const float x2 = x1 + w;
|
||||||
const float y2 = y1 + h;
|
const float y2 = y1 + h;
|
||||||
|
|
||||||
|
@ -394,27 +417,26 @@ float TextureFontPrivate::render(const string &s, float x, float y)
|
||||||
y += g.ay;
|
y += g.ay;
|
||||||
|
|
||||||
// Skip glyphs that have no pixels
|
// Skip glyphs that have no pixels
|
||||||
if (g.bw == 0 || g.bh == 0)
|
if (g.bw == 0 || g.bh == 0) continue;
|
||||||
continue;
|
|
||||||
|
|
||||||
const float tx1 = g.tx;
|
const float tx1 = g.tx;
|
||||||
const float ty1 = g.ty;
|
const float ty1 = g.ty;
|
||||||
const float tx2 = tx1 + w / m_texWidth;
|
const float tx2 = tx1 + w / m_texWidth;
|
||||||
const float ty2 = ty1 + h / m_texHeight;
|
const float ty2 = ty1 + h / m_texHeight;
|
||||||
|
|
||||||
m_fontVertices.emplace_back(FontVertex(x1, y1, tx1, ty2));
|
m_fontVertices.emplace_back(x1, y1, tx1, ty2);
|
||||||
m_fontVertices.emplace_back(FontVertex(x2, y1, tx2, ty2));
|
m_fontVertices.emplace_back(x2, y1, tx2, ty2);
|
||||||
m_fontVertices.emplace_back(FontVertex(x1, y2, tx1, ty1));
|
m_fontVertices.emplace_back(x1, y2, tx1, ty1);
|
||||||
m_fontVertices.emplace_back(FontVertex(x2, y2, tx2, ty1));
|
m_fontVertices.emplace_back(x2, y2, tx2, ty1);
|
||||||
}
|
}
|
||||||
|
|
||||||
return x;
|
return x;
|
||||||
}
|
}
|
||||||
|
|
||||||
float TextureFontPrivate::render(wchar_t ch, float xoffset, float yoffset)
|
float
|
||||||
|
TextureFontPrivate::render(wchar_t ch, float xoffset, float yoffset)
|
||||||
{
|
{
|
||||||
|
auto &g = getGlyph(ch, L'?');
|
||||||
auto& g = getGlyph(ch, L'?');
|
|
||||||
|
|
||||||
// Calculate the vertex and texture coordinates
|
// Calculate the vertex and texture coordinates
|
||||||
const float x1 = xoffset + g.bl;
|
const float x1 = xoffset + g.bl;
|
||||||
|
@ -427,32 +449,30 @@ float TextureFontPrivate::render(wchar_t ch, float xoffset, float yoffset)
|
||||||
const float tx2 = tx1 + static_cast<float>(g.bw) / m_texWidth;
|
const float tx2 = tx1 + static_cast<float>(g.bw) / m_texWidth;
|
||||||
const float ty2 = ty1 + static_cast<float>(g.bh) / m_texHeight;
|
const float ty2 = ty1 + static_cast<float>(g.bh) / m_texHeight;
|
||||||
|
|
||||||
m_fontVertices.emplace_back(FontVertex(x1, y1, tx1, ty2));
|
m_fontVertices.emplace_back(x1, y1, tx1, ty2);
|
||||||
m_fontVertices.emplace_back(FontVertex(x2, y1, tx2, ty2));
|
m_fontVertices.emplace_back(x2, y1, tx2, ty2);
|
||||||
m_fontVertices.emplace_back(FontVertex(x1, y2, tx1, ty1));
|
m_fontVertices.emplace_back(x1, y2, tx1, ty1);
|
||||||
m_fontVertices.emplace_back(FontVertex(x2, y2, tx2, ty1));
|
m_fontVertices.emplace_back(x2, y2, tx2, ty1);
|
||||||
|
|
||||||
return g.ax;
|
return g.ax;
|
||||||
}
|
}
|
||||||
|
|
||||||
CelestiaGLProgram* TextureFontPrivate::getProgram()
|
CelestiaGLProgram *
|
||||||
|
TextureFontPrivate::getProgram()
|
||||||
{
|
{
|
||||||
if (m_prog != nullptr)
|
if (m_prog != nullptr) return m_prog;
|
||||||
return m_prog;
|
|
||||||
m_prog = m_renderer->getShaderManager().getShader("text");
|
m_prog = m_renderer->getShaderManager().getShader("text");
|
||||||
return m_prog;
|
return m_prog;
|
||||||
}
|
}
|
||||||
|
|
||||||
void TextureFontPrivate::flush()
|
void
|
||||||
|
TextureFontPrivate::flush()
|
||||||
{
|
{
|
||||||
if (m_fontVertices.size() < 4)
|
if (m_fontVertices.size() < 4) return;
|
||||||
return;
|
|
||||||
|
|
||||||
vector<unsigned short> indexes;
|
std::vector<unsigned short> indexes;
|
||||||
indexes.reserve(m_fontVertices.size() / 4 * 6);
|
indexes.reserve(m_fontVertices.size() / 4 * 6);
|
||||||
for (unsigned short index = 0;
|
for (unsigned short index = 0; index < static_cast<unsigned short>(m_fontVertices.size()); index += 4)
|
||||||
index < (unsigned short) m_fontVertices.size();
|
|
||||||
index += 4)
|
|
||||||
{
|
{
|
||||||
indexes.push_back(index + 0);
|
indexes.push_back(index + 0);
|
||||||
indexes.push_back(index + 1);
|
indexes.push_back(index + 1);
|
||||||
|
@ -465,9 +485,17 @@ void TextureFontPrivate::flush()
|
||||||
glEnableVertexAttribArray(CelestiaGLProgram::VertexCoordAttributeIndex);
|
glEnableVertexAttribArray(CelestiaGLProgram::VertexCoordAttributeIndex);
|
||||||
glEnableVertexAttribArray(CelestiaGLProgram::TextureCoord0AttributeIndex);
|
glEnableVertexAttribArray(CelestiaGLProgram::TextureCoord0AttributeIndex);
|
||||||
glVertexAttribPointer(CelestiaGLProgram::VertexCoordAttributeIndex,
|
glVertexAttribPointer(CelestiaGLProgram::VertexCoordAttributeIndex,
|
||||||
2, GL_FLOAT, GL_FALSE, sizeof(FontVertex), &m_fontVertices[0].x);
|
2,
|
||||||
|
GL_FLOAT,
|
||||||
|
GL_FALSE,
|
||||||
|
sizeof(FontVertex),
|
||||||
|
&m_fontVertices[0].x);
|
||||||
glVertexAttribPointer(CelestiaGLProgram::TextureCoord0AttributeIndex,
|
glVertexAttribPointer(CelestiaGLProgram::TextureCoord0AttributeIndex,
|
||||||
2, GL_FLOAT, GL_FALSE, sizeof(FontVertex), &m_fontVertices[0].u);
|
2,
|
||||||
|
GL_FLOAT,
|
||||||
|
GL_FALSE,
|
||||||
|
sizeof(FontVertex),
|
||||||
|
&m_fontVertices[0].u);
|
||||||
glDrawElements(GL_TRIANGLES, indexes.size(), GL_UNSIGNED_SHORT, indexes.data());
|
glDrawElements(GL_TRIANGLES, indexes.size(), GL_UNSIGNED_SHORT, indexes.data());
|
||||||
glDisableVertexAttribArray(CelestiaGLProgram::VertexCoordAttributeIndex);
|
glDisableVertexAttribArray(CelestiaGLProgram::VertexCoordAttributeIndex);
|
||||||
glDisableVertexAttribArray(CelestiaGLProgram::TextureCoord0AttributeIndex);
|
glDisableVertexAttribArray(CelestiaGLProgram::TextureCoord0AttributeIndex);
|
||||||
|
@ -475,17 +503,11 @@ void TextureFontPrivate::flush()
|
||||||
m_fontVertices.clear();
|
m_fontVertices.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
TextureFont::TextureFont(const Renderer *renderer) :
|
TextureFont::TextureFont(const Renderer *renderer) :
|
||||||
impl(new TextureFontPrivate(renderer))
|
impl(std::make_unique<TextureFontPrivate>(renderer))
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
TextureFont::~TextureFont()
|
|
||||||
{
|
|
||||||
delete impl;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Render a single character of the font with offset
|
* Render a single character of the font with offset
|
||||||
*
|
*
|
||||||
|
@ -496,7 +518,8 @@ TextureFont::~TextureFont()
|
||||||
* @param xoffset -- horizontal offset
|
* @param xoffset -- horizontal offset
|
||||||
* @param yoffset -- vertical offset
|
* @param yoffset -- vertical offset
|
||||||
*/
|
*/
|
||||||
float TextureFont::render(wchar_t ch, float xoffset, float yoffset) const
|
float
|
||||||
|
TextureFont::render(wchar_t ch, float xoffset, float yoffset) const
|
||||||
{
|
{
|
||||||
return impl->render(ch, xoffset, yoffset);
|
return impl->render(ch, xoffset, yoffset);
|
||||||
}
|
}
|
||||||
|
@ -511,7 +534,8 @@ float TextureFont::render(wchar_t ch, float xoffset, float yoffset) const
|
||||||
* @param xoffset -- horizontal offset
|
* @param xoffset -- horizontal offset
|
||||||
* @param yoffset -- vertical offset
|
* @param yoffset -- vertical offset
|
||||||
*/
|
*/
|
||||||
float TextureFont::render(const string &s, float xoffset, float yoffset) const
|
float
|
||||||
|
TextureFont::render(std::string_view s, float xoffset, float yoffset) const
|
||||||
{
|
{
|
||||||
return impl->render(s, xoffset, yoffset);
|
return impl->render(s, xoffset, yoffset);
|
||||||
}
|
}
|
||||||
|
@ -524,69 +548,92 @@ float TextureFont::render(const string &s, float xoffset, float yoffset) const
|
||||||
* @param s -- string to calculate width
|
* @param s -- string to calculate width
|
||||||
* @return string width in pixels
|
* @return string width in pixels
|
||||||
*/
|
*/
|
||||||
int TextureFont::getWidth(const string& s) const
|
int
|
||||||
|
TextureFont::getWidth(std::string_view s) const
|
||||||
{
|
{
|
||||||
int width = 0;
|
int width = 0;
|
||||||
int len = s.length();
|
int len = s.length();
|
||||||
bool validChar = true;
|
bool validChar = true;
|
||||||
int i = 0;
|
int i = 0;
|
||||||
|
|
||||||
while (i < len && validChar)
|
while (i < len && validChar)
|
||||||
{
|
{
|
||||||
wchar_t ch = 0;
|
wchar_t ch = 0;
|
||||||
validChar = UTF8Decode(s, i, ch);
|
validChar = UTF8Decode(s, i, ch);
|
||||||
if (!validChar)
|
if (!validChar) break;
|
||||||
break;
|
|
||||||
|
|
||||||
i += UTF8EncodedSize(ch);
|
i += UTF8EncodedSize(ch);
|
||||||
|
|
||||||
auto& g = impl->getGlyph(ch, L'?');
|
auto &g = impl->getGlyph(ch, L'?');
|
||||||
width += g.ax;
|
width += g.ax;
|
||||||
}
|
}
|
||||||
|
|
||||||
return width;
|
return width;
|
||||||
}
|
}
|
||||||
|
|
||||||
int TextureFont::getHeight() const
|
/**
|
||||||
|
* Return line height for the current font as sum of the maximal ascent and the
|
||||||
|
* maximal descent.
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
TextureFont::getHeight() const
|
||||||
{
|
{
|
||||||
return impl->m_maxAscent + impl->m_maxDescent;
|
return impl->m_maxAscent + impl->m_maxDescent;
|
||||||
}
|
}
|
||||||
|
|
||||||
int TextureFont::getMaxWidth() const
|
/**
|
||||||
|
* Return the maximal character width for the current font.
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
TextureFont::getMaxWidth() const
|
||||||
{
|
{
|
||||||
return impl->m_maxWidth;
|
return impl->m_maxWidth;
|
||||||
}
|
}
|
||||||
|
|
||||||
int TextureFont::getMaxAscent() const
|
/**
|
||||||
|
* Return the maximal ascent for the current font.
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
TextureFont::getMaxAscent() const
|
||||||
{
|
{
|
||||||
return impl->m_maxAscent;
|
return impl->m_maxAscent;
|
||||||
}
|
}
|
||||||
|
|
||||||
void TextureFont::setMaxAscent(int _maxAscent)
|
/**
|
||||||
|
* Set the maximal ascent for the current font.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
TextureFont::setMaxAscent(int _maxAscent)
|
||||||
{
|
{
|
||||||
impl->m_maxAscent = _maxAscent;
|
impl->m_maxAscent = _maxAscent;
|
||||||
}
|
}
|
||||||
|
|
||||||
int TextureFont::getMaxDescent() const
|
/**
|
||||||
|
* Return the maximal descent for the current font.
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
TextureFont::getMaxDescent() const
|
||||||
{
|
{
|
||||||
return impl->m_maxDescent;
|
return impl->m_maxDescent;
|
||||||
}
|
}
|
||||||
|
|
||||||
void TextureFont::setMaxDescent(int _maxDescent)
|
/**
|
||||||
|
* Set the maximal descent for the current font.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
TextureFont::setMaxDescent(int _maxDescent)
|
||||||
{
|
{
|
||||||
impl->m_maxDescent = _maxDescent;
|
impl->m_maxDescent = _maxDescent;
|
||||||
}
|
}
|
||||||
|
|
||||||
int TextureFont::getTextureName() const
|
/**
|
||||||
{
|
* Use the current font for text rendering.
|
||||||
return impl->m_texName;
|
*/
|
||||||
}
|
void
|
||||||
|
TextureFont::bind()
|
||||||
void TextureFont::bind()
|
|
||||||
{
|
{
|
||||||
auto *prog = impl->getProgram();
|
auto *prog = impl->getProgram();
|
||||||
if (prog == nullptr)
|
if (prog == nullptr) return;
|
||||||
return;
|
|
||||||
|
|
||||||
if (impl->m_texName != 0)
|
if (impl->m_texName != 0)
|
||||||
{
|
{
|
||||||
|
@ -594,16 +641,20 @@ void TextureFont::bind()
|
||||||
glBindTexture(GL_TEXTURE_2D, impl->m_texName);
|
glBindTexture(GL_TEXTURE_2D, impl->m_texName);
|
||||||
prog->use();
|
prog->use();
|
||||||
prog->samplerParam("atlasTex") = 0;
|
prog->samplerParam("atlasTex") = 0;
|
||||||
impl->m_shaderInUse = true;
|
impl->m_shaderInUse = true;
|
||||||
prog->setMVPMatrices(impl->m_projection, impl->m_modelView);
|
prog->setMVPMatrices(impl->m_projection, impl->m_modelView);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void TextureFont::setMVPMatrices(const Eigen::Matrix4f& p, const Eigen::Matrix4f& m)
|
/**
|
||||||
|
* Assign Projection and ModelView matrices for the current font.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
TextureFont::setMVPMatrices(const Eigen::Matrix4f &p, const Eigen::Matrix4f &m)
|
||||||
{
|
{
|
||||||
impl->m_projection = p;
|
impl->m_projection = p;
|
||||||
impl->m_modelView = m;
|
impl->m_modelView = m;
|
||||||
auto *prog = impl->getProgram();
|
auto *prog = impl->getProgram();
|
||||||
if (prog != nullptr && impl->m_shaderInUse)
|
if (prog != nullptr && impl->m_shaderInUse)
|
||||||
{
|
{
|
||||||
flush();
|
flush();
|
||||||
|
@ -611,29 +662,40 @@ void TextureFont::setMVPMatrices(const Eigen::Matrix4f& p, const Eigen::Matrix4f
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void TextureFont::unbind()
|
/**
|
||||||
|
* Stop the current font usage.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
TextureFont::unbind()
|
||||||
{
|
{
|
||||||
flush();
|
flush();
|
||||||
impl->m_shaderInUse = false;
|
impl->m_shaderInUse = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
short TextureFont::getAdvance(wchar_t ch) const
|
/**
|
||||||
|
* Return the advance for the wide character `ch`.
|
||||||
|
*/
|
||||||
|
short
|
||||||
|
TextureFont::getAdvance(wchar_t ch) const
|
||||||
{
|
{
|
||||||
auto& g = impl->getGlyph(ch, L'?');
|
auto &g = impl->getGlyph(ch, L'?');
|
||||||
return g.ax;
|
return g.ax;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool TextureFont::buildTexture()
|
/**
|
||||||
{
|
* Perform all delayed text rendering operations.
|
||||||
return true;
|
*/
|
||||||
}
|
void
|
||||||
|
TextureFont::flush()
|
||||||
void TextureFont::flush()
|
|
||||||
{
|
{
|
||||||
impl->flush();
|
impl->flush();
|
||||||
}
|
}
|
||||||
|
|
||||||
TextureFont* TextureFont::load(const Renderer *r, const fs::path &path, int index, int size, int dpi)
|
namespace
|
||||||
|
{
|
||||||
|
|
||||||
|
FT_Face
|
||||||
|
LoadFontFace(FT_Library ft, const fs::path &path, int index, int size, int dpi)
|
||||||
{
|
{
|
||||||
FT_Face face;
|
FT_Face face;
|
||||||
|
|
||||||
|
@ -646,69 +708,89 @@ TextureFont* TextureFont::load(const Renderer *r, const fs::path &path, int inde
|
||||||
if (!FT_IS_SCALABLE(face))
|
if (!FT_IS_SCALABLE(face))
|
||||||
{
|
{
|
||||||
GetLogger()->error("Font is not scalable: {}\n", path);
|
GetLogger()->error("Font is not scalable: {}\n", path);
|
||||||
|
FT_Done_Face(face);
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (FT_Set_Char_Size(face, 0, size << 6, dpi, dpi) != 0)
|
if (FT_Set_Char_Size(face, 0, size << 6, dpi, dpi) != 0)
|
||||||
{
|
{
|
||||||
GetLogger()->error("Could not set font size {}\n", size);
|
GetLogger()->error("Could not set font size {}\n", size);
|
||||||
|
FT_Done_Face(face);
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto* font = new TextureFont(r);
|
return face;
|
||||||
font->impl->m_face = face;
|
|
||||||
|
|
||||||
if (!font->impl->buildAtlas())
|
|
||||||
return nullptr;
|
|
||||||
|
|
||||||
font->setMaxAscent(face->size->metrics.ascender >> 6);
|
|
||||||
font->setMaxDescent(-face->size->metrics.descender >> 6);
|
|
||||||
|
|
||||||
return font;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// temporary while no fontconfig support
|
// temporary while no fontconfig support
|
||||||
static fs::path ParseFontName(const fs::path &filename, int &collectionIndex, int &size)
|
fs::path
|
||||||
|
ParseFontName(const fs::path &filename, int &index, int &size)
|
||||||
{
|
{
|
||||||
// Format with font path/collection index(if any)/font size(if any)
|
// Format with font path/collection index(if any)/font size(if any)
|
||||||
auto fn = filename.string();
|
auto fn = filename.string();
|
||||||
auto pos = fn.rfind(',');
|
if (auto ps = fn.rfind(','); ps != std::string::npos)
|
||||||
if (pos != string::npos)
|
|
||||||
{
|
{
|
||||||
size = (int) stof(fn.substr(pos + 1));
|
if (from_chars(&fn[ps + 1], &fn[fn.size()], size).ec == std::errc())
|
||||||
auto rest = fn.substr(0, pos);
|
|
||||||
|
|
||||||
pos = rest.rfind(',');
|
|
||||||
if (pos != string::npos)
|
|
||||||
{
|
{
|
||||||
collectionIndex = stof(rest.substr(pos + 1));
|
if (auto pi = fn.rfind(',', ps - 1); pi != std::string::npos)
|
||||||
return rest.substr(0, pos);
|
{
|
||||||
}
|
if (from_chars(&fn[pi + 1], &fn[pi], index).ec == std::errc())
|
||||||
else
|
return fn.substr(0, pi);
|
||||||
{
|
}
|
||||||
return rest;
|
return fn.substr(0, ps);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
return filename;
|
||||||
{
|
|
||||||
size = 12;
|
|
||||||
return filename;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<TextureFont> LoadTextureFont(const Renderer *r, const fs::path &filename, int index, int size)
|
} // namespace
|
||||||
|
|
||||||
|
using FontCache = std::map<fs::path, std::weak_ptr<TextureFont>>;
|
||||||
|
|
||||||
|
std::shared_ptr<TextureFont>
|
||||||
|
LoadTextureFont(const Renderer *r, const fs::path &filename, int index, int size)
|
||||||
{
|
{
|
||||||
if (ft == nullptr)
|
// Init FreeType library
|
||||||
|
static FT_Library ftlib = nullptr;
|
||||||
|
if (ftlib == nullptr && FT_Init_FreeType(&ftlib) != 0)
|
||||||
{
|
{
|
||||||
if (FT_Init_FreeType(&ft))
|
GetLogger()->error("Could not init freetype library\n");
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Init FontCache
|
||||||
|
static FontCache *fontCache = nullptr;
|
||||||
|
if (fontCache == nullptr)
|
||||||
|
fontCache = new FontCache;
|
||||||
|
|
||||||
|
// Lookup for an existing cached font
|
||||||
|
std::weak_ptr<TextureFont> &font = (*fontCache)[filename];
|
||||||
|
std::shared_ptr<TextureFont> ret = font.lock();
|
||||||
|
if (ret == nullptr)
|
||||||
|
{
|
||||||
|
int psize = 12; // default size if missing
|
||||||
|
int pindex = 0;
|
||||||
|
auto nameonly = ParseFontName(filename, pindex, psize);
|
||||||
|
auto face = LoadFontFace(ftlib, nameonly,
|
||||||
|
index > 0 ? index : pindex,
|
||||||
|
size > 0 ? size : psize,
|
||||||
|
r->getScreenDpi());
|
||||||
|
if (face == nullptr)
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
|
ret = std::make_shared<TextureFont>(r);
|
||||||
|
ret->impl->m_face = face;
|
||||||
|
|
||||||
|
if (!ret->impl->buildAtlas())
|
||||||
{
|
{
|
||||||
GetLogger()->error("Could not init freetype library\n");
|
FT_Done_Face(face);
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
int psize = 0;
|
ret->setMaxAscent(static_cast<int>(face->size->metrics.ascender >> 6));
|
||||||
int pcollectionIndex = 0;
|
ret->setMaxDescent(static_cast<int>(-face->size->metrics.descender >> 6));
|
||||||
auto nameonly = ParseFontName(filename, pcollectionIndex, psize);
|
|
||||||
return std::shared_ptr<TextureFont>(TextureFont::load(r, nameonly, index > 0 ? index : pcollectionIndex, size > 0 ? size : psize, r->getScreenDpi()));
|
font = ret;
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
// truetypefont.h
|
// truetypefont.h
|
||||||
//
|
//
|
||||||
// Copyright (C) 2019, Celestia Development Team
|
// Copyright (C) 2019-2022, Celestia Development Team
|
||||||
//
|
//
|
||||||
// This program is free software; you can redistribute it and/or
|
// This program is free software; you can redistribute it and/or
|
||||||
// modify it under the terms of the GNU General Public License
|
// modify it under the terms of the GNU General Public License
|
||||||
|
@ -9,51 +9,53 @@
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <string>
|
|
||||||
#include <celcompat/filesystem.h>
|
|
||||||
#include <Eigen/Core>
|
#include <Eigen/Core>
|
||||||
|
#include <celcompat/filesystem.h>
|
||||||
|
#include <string_view>
|
||||||
|
|
||||||
class Renderer;
|
class Renderer;
|
||||||
|
class TextureFont;
|
||||||
|
|
||||||
|
std::shared_ptr<TextureFont>
|
||||||
|
LoadTextureFont(const Renderer *, const fs::path &, int index = 0, int size = 0);
|
||||||
|
|
||||||
struct TextureFontPrivate;
|
struct TextureFontPrivate;
|
||||||
class TextureFont
|
class TextureFont
|
||||||
{
|
{
|
||||||
TextureFont(const Renderer*);
|
|
||||||
public:
|
public:
|
||||||
|
TextureFont(const Renderer *);
|
||||||
TextureFont() = delete;
|
TextureFont() = delete;
|
||||||
~TextureFont();
|
~TextureFont() = default;
|
||||||
TextureFont(const TextureFont&) = delete;
|
TextureFont(const TextureFont &) = delete;
|
||||||
TextureFont(TextureFont&&) = delete;
|
TextureFont(TextureFont &&) = delete;
|
||||||
TextureFont& operator=(const TextureFont&) = delete;
|
TextureFont &operator=(const TextureFont &) = delete;
|
||||||
TextureFont& operator=(TextureFont&&) = delete;
|
TextureFont &operator=(TextureFont &&) = delete;
|
||||||
|
|
||||||
void setMVPMatrices(const Eigen::Matrix4f& p, const Eigen::Matrix4f& m = Eigen::Matrix4f::Identity());
|
void setMVPMatrices(const Eigen::Matrix4f &p,
|
||||||
|
const Eigen::Matrix4f &m = Eigen::Matrix4f::Identity());
|
||||||
|
|
||||||
float render(wchar_t c, float xoffset = 0.0f, float yoffset = 0.0f) const;
|
float render(wchar_t c, float xoffset = 0.0f, float yoffset = 0.0f) const;
|
||||||
float render(const std::string& str, float xoffset = 0.0f, float yoffset = 0.0f) const;
|
float render(std::string_view str, float xoffset = 0.0f, float yoffset = 0.0f) const;
|
||||||
|
|
||||||
int getWidth(const std::string&) const;
|
int getWidth(std::string_view) const;
|
||||||
int getWidth(int c) const;
|
int getWidth(int c) const;
|
||||||
int getMaxWidth() const;
|
int getMaxWidth() const;
|
||||||
int getHeight() const;
|
int getHeight() const;
|
||||||
|
|
||||||
int getMaxAscent() const;
|
int getMaxAscent() const;
|
||||||
void setMaxAscent(int);
|
void setMaxAscent(int);
|
||||||
int getMaxDescent() const;
|
int getMaxDescent() const;
|
||||||
void setMaxDescent(int);
|
void setMaxDescent(int);
|
||||||
|
|
||||||
short getAdvance(wchar_t c) const;
|
short getAdvance(wchar_t c) const;
|
||||||
|
|
||||||
int getTextureName() const;
|
|
||||||
void bind();
|
void bind();
|
||||||
void unbind();
|
void unbind();
|
||||||
bool buildTexture();
|
|
||||||
void flush();
|
void flush();
|
||||||
|
|
||||||
static TextureFont* load(const Renderer*, const fs::path&, int index, int size, int dpi);
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
TextureFontPrivate *impl;
|
std::unique_ptr<TextureFontPrivate> impl;
|
||||||
};
|
|
||||||
|
|
||||||
std::shared_ptr<TextureFont> LoadTextureFont(const Renderer*, const fs::path&, int index = 0, int size = 0);
|
friend std::shared_ptr<TextureFont>
|
||||||
|
LoadTextureFont(const Renderer*, const fs::path&, int, int);
|
||||||
|
};
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
// as published by the Free Software Foundation; either version 2
|
// as published by the Free Software Foundation; either version 2
|
||||||
// of the License, or (at your option) any later version.
|
// of the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
#include <cassert>
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
@ -15,6 +16,7 @@
|
||||||
|
|
||||||
// HACK: MS Visual C++ has _snprintf declared in stdio.h but not snprintf
|
// HACK: MS Visual C++ has _snprintf declared in stdio.h but not snprintf
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
|
#include <celutil/winutil.h>
|
||||||
#define snprintf _snprintf
|
#define snprintf _snprintf
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -58,9 +60,30 @@ std::ostream& operator<<(std::ostream& out, const FormattedNumber& num)
|
||||||
char obuf[64];
|
char obuf[64];
|
||||||
int fmtPrecision;
|
int fmtPrecision;
|
||||||
double value = num.getRoundedValue();
|
double value = num.getRoundedValue();
|
||||||
char *decimal_point = localeconv()->decimal_point;
|
const char *grouping = localeconv()->grouping;
|
||||||
char *thousands_sep = localeconv()->thousands_sep;
|
#ifndef _WIN32
|
||||||
char *grouping = localeconv()->grouping;
|
const char *decimal_point = localeconv()->decimal_point;
|
||||||
|
const char *thousands_sep = localeconv()->thousands_sep;
|
||||||
|
#else
|
||||||
|
static bool initialized = false;
|
||||||
|
static char decimal_point[8] = {};
|
||||||
|
static char thousands_sep[8] = {};
|
||||||
|
|
||||||
|
if (!initialized)
|
||||||
|
{
|
||||||
|
std::string s = CurrentCPToUTF8(localeconv()->decimal_point);
|
||||||
|
assert(s.length() < 8);
|
||||||
|
strncpy(decimal_point, s.c_str(), sizeof(decimal_point) - 1);
|
||||||
|
decimal_point[sizeof(decimal_point) - 1 ] = '\0';
|
||||||
|
|
||||||
|
s = CurrentCPToUTF8(localeconv()->thousands_sep);
|
||||||
|
assert(s.length() < 8);
|
||||||
|
strncpy(thousands_sep, s.c_str(), sizeof(thousands_sep) - 1);
|
||||||
|
thousands_sep[sizeof(thousands_sep) - 1] = '\0';
|
||||||
|
|
||||||
|
initialized = true;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
memset(obuf, 0, sizeof(obuf));
|
memset(obuf, 0, sizeof(obuf));
|
||||||
|
|
||||||
|
|
|
@ -15,11 +15,13 @@
|
||||||
|
|
||||||
#include <cel3ds/3dsread.h>
|
#include <cel3ds/3dsread.h>
|
||||||
#include <celmath/mathlib.h>
|
#include <celmath/mathlib.h>
|
||||||
|
#include <celutil/logger.h>
|
||||||
|
|
||||||
#include "cmodops.h"
|
#include "cmodops.h"
|
||||||
#include "convert3ds.h"
|
#include "convert3ds.h"
|
||||||
#include "pathmanager.h"
|
#include "pathmanager.h"
|
||||||
|
|
||||||
|
using celestia::util::CreateLogger;
|
||||||
|
|
||||||
void usage()
|
void usage()
|
||||||
{
|
{
|
||||||
|
@ -35,6 +37,8 @@ int main(int argc, char* argv[])
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CreateLogger();
|
||||||
|
|
||||||
std::string inputFileName = argv[1];
|
std::string inputFileName = argv[1];
|
||||||
|
|
||||||
std::cerr << "Reading...\n";
|
std::cerr << "Reading...\n";
|
||||||
|
|
|
@ -1,5 +1,10 @@
|
||||||
if(NOT ENABLE_QT)
|
if(NOT ENABLE_QT)
|
||||||
message("Qt frontend is disabled, not building cmodview.")
|
message("Qt5 frontend is disabled, not building cmodview.")
|
||||||
|
return()
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if(USE_QT6)
|
||||||
|
message("Qt tools not supported on Qt6, not building cmodview.")
|
||||||
return()
|
return()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
|
|
@ -11,7 +11,9 @@
|
||||||
#include "mainwindow.h"
|
#include "mainwindow.h"
|
||||||
#include <QApplication>
|
#include <QApplication>
|
||||||
#include <QGLFormat>
|
#include <QGLFormat>
|
||||||
|
#include <celutil/logger.h>
|
||||||
|
|
||||||
|
using celestia::util::CreateLogger;
|
||||||
|
|
||||||
int
|
int
|
||||||
main(int argc, char *argv[])
|
main(int argc, char *argv[])
|
||||||
|
@ -51,5 +53,7 @@ main(int argc, char *argv[])
|
||||||
// open events.
|
// open events.
|
||||||
app.installEventFilter(&window);
|
app.installEventFilter(&window);
|
||||||
|
|
||||||
|
CreateLogger();
|
||||||
|
|
||||||
return app.exec();
|
return app.exec();
|
||||||
}
|
}
|
||||||
|
|
|
@ -363,7 +363,7 @@ joinVertices(std::vector<Face>& faces,
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// Must have a position
|
// Must have a position
|
||||||
assert(desc.getAttribute(cmod::Mesh::Position).format == cmod::Mesh::Float3);
|
assert(desc.getAttribute(cmod::VertexAttributeSemantic::Position).format == cmod::VertexAttributeFormat::Float3);
|
||||||
|
|
||||||
std::uint32_t posOffset = desc.getAttribute(cmod::VertexAttributeSemantic::Position).offsetWords;
|
std::uint32_t posOffset = desc.getAttribute(cmod::VertexAttributeSemantic::Position).offsetWords;
|
||||||
const cmod::VWord* vertexPoints = vertexData + posOffset;
|
const cmod::VWord* vertexPoints = vertexData + posOffset;
|
||||||
|
|
|
@ -1,23 +0,0 @@
|
||||||
if(NOT ENABLE_QT)
|
|
||||||
message("Qt frontend is disabled, not building qttxf.")
|
|
||||||
return()
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if(APPLE AND EXISTS /usr/local/opt/qt5)
|
|
||||||
# Homebrew installs Qt5 (up to at least 5.9.1) in
|
|
||||||
# /usr/local/qt5, ensure it can be found by CMake since
|
|
||||||
# it is not in the default /usr/local prefix.
|
|
||||||
list(APPEND CMAKE_PREFIX_PATH "/usr/local/opt/qt5")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
set(QT_LIBS Widgets)
|
|
||||||
find_package(Qt5 COMPONENTS ${QT_LIBS} CONFIG REQUIRED)
|
|
||||||
|
|
||||||
# Instruct CMake to run moc automatically when needed
|
|
||||||
set(CMAKE_AUTOMOC ON)
|
|
||||||
# Find includes in corresponding build directories
|
|
||||||
set(CMAKE_INCLUDE_CURRENT_DIR ON)
|
|
||||||
|
|
||||||
add_executable(qttxf WIN32 main.cpp mainwindow.cpp)
|
|
||||||
install(TARGETS qttxf RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
|
|
||||||
qt5_use_modules(qttxf ${QT_LIBS})
|
|
|
@ -1,10 +0,0 @@
|
||||||
qttxf is a simple GUI tool for creating bitmap font files for use with
|
|
||||||
Celestia and other applications. The font files are saved in the TXF format
|
|
||||||
introduced by Mark Kilgard in his GLUT toolkit.
|
|
||||||
|
|
||||||
qttxf is Copyright (C) 2009 by Chris Laurel, and is distributed under the
|
|
||||||
terms of the GNU General Public License version 2. Please forward comments
|
|
||||||
and patches to claurel@gmail.com.
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,23 +0,0 @@
|
||||||
// qttxf - a Qt-based application to generate GLUT txf files from
|
|
||||||
// system fonts
|
|
||||||
//
|
|
||||||
// Copyright (C) 2009, Chris Laurel <claurel@gmail.com>
|
|
||||||
//
|
|
||||||
// This program is free software; you can redistribute it and/or
|
|
||||||
// modify it under the terms of the GNU General Public License
|
|
||||||
// as published by the Free Software Foundation; either version 2
|
|
||||||
// of the License, or (at your option) any later version.
|
|
||||||
|
|
||||||
#include <QApplication>
|
|
||||||
#include "mainwindow.h"
|
|
||||||
|
|
||||||
|
|
||||||
int
|
|
||||||
main(int argc, char *argv[])
|
|
||||||
{
|
|
||||||
QApplication app(argc, argv);
|
|
||||||
MainWindow window;
|
|
||||||
window.show();
|
|
||||||
|
|
||||||
return app.exec();
|
|
||||||
}
|
|
|
@ -1,391 +0,0 @@
|
||||||
// qttxf - a Qt-based application to generate GLUT txf files from
|
|
||||||
// system fonts
|
|
||||||
//
|
|
||||||
// Copyright (C) 2009, Chris Laurel <claurel@gmail.com>
|
|
||||||
//
|
|
||||||
// This program is free software; you can redistribute it and/or
|
|
||||||
// modify it under the terms of the GNU General Public License
|
|
||||||
// as published by the Free Software Foundation; either version 2
|
|
||||||
// of the License, or (at your option) any later version.
|
|
||||||
|
|
||||||
#include "mainwindow.h"
|
|
||||||
#include <QComboBox>
|
|
||||||
#include <QFontComboBox>
|
|
||||||
#include <QScrollArea>
|
|
||||||
#include <QLabel>
|
|
||||||
#include <QFont>
|
|
||||||
#include <QDataStream>
|
|
||||||
#include <QDebug>
|
|
||||||
#include <QMessageBox>
|
|
||||||
#include <QFile>
|
|
||||||
#include <QAction>
|
|
||||||
#include <QMenuBar>
|
|
||||||
#include <QMenu>
|
|
||||||
#include <QHBoxLayout>
|
|
||||||
#include <QVBoxLayout>
|
|
||||||
#include <QFileDialog>
|
|
||||||
#include <QPainter>
|
|
||||||
|
|
||||||
// TXF format constants
|
|
||||||
const char* TXF_HEADER_BYTES = "\377txf";
|
|
||||||
const quint32 TXF_ENDIANNESS_TEST = 0x12345678;
|
|
||||||
|
|
||||||
|
|
||||||
MainWindow::MainWindow() :
|
|
||||||
m_scrollArea(nullptr),
|
|
||||||
m_imageWidget(nullptr),
|
|
||||||
m_fontCombo(nullptr),
|
|
||||||
m_sizeCombo(nullptr),
|
|
||||||
m_styleCombo(nullptr),
|
|
||||||
m_saveAction(nullptr)
|
|
||||||
{
|
|
||||||
QWidget *centralWidget = new QWidget();
|
|
||||||
|
|
||||||
QLabel *fontLabel = new QLabel(tr("Font:"));
|
|
||||||
m_fontCombo = new QFontComboBox;
|
|
||||||
QLabel *sizeLabel = new QLabel(tr("Size:"));
|
|
||||||
m_sizeCombo = new QComboBox;
|
|
||||||
QLabel *styleLabel = new QLabel(tr("Style:"));
|
|
||||||
m_styleCombo = new QComboBox;
|
|
||||||
|
|
||||||
m_scrollArea = new QScrollArea();
|
|
||||||
m_imageWidget = new QLabel();
|
|
||||||
|
|
||||||
m_scrollArea->setWidget(m_imageWidget);
|
|
||||||
|
|
||||||
findStyles(m_fontCombo->currentFont());
|
|
||||||
findSizes(m_fontCombo->currentFont());
|
|
||||||
|
|
||||||
connect(m_fontCombo, SIGNAL(currentFontChanged(const QFont &)),
|
|
||||||
this, SLOT(findStyles(const QFont &)));
|
|
||||||
connect(m_fontCombo, SIGNAL(currentFontChanged(const QFont &)),
|
|
||||||
this, SLOT(findSizes(const QFont &)));
|
|
||||||
connect(m_fontCombo, SIGNAL(currentFontChanged(const QFont &)),
|
|
||||||
this, SLOT(updateFont(const QFont &)));
|
|
||||||
connect(m_sizeCombo, SIGNAL(currentIndexChanged(const QString &)),
|
|
||||||
this, SLOT(updateSize(const QString &)));
|
|
||||||
connect(m_styleCombo, SIGNAL(currentIndexChanged(const QString &)),
|
|
||||||
this, SLOT(updateStyle(const QString &)));
|
|
||||||
|
|
||||||
QHBoxLayout *controlsLayout = new QHBoxLayout;
|
|
||||||
controlsLayout->addWidget(fontLabel);
|
|
||||||
controlsLayout->addWidget(m_fontCombo, 1);
|
|
||||||
controlsLayout->addWidget(sizeLabel);
|
|
||||||
controlsLayout->addWidget(m_sizeCombo, 1);
|
|
||||||
controlsLayout->addWidget(styleLabel);
|
|
||||||
controlsLayout->addWidget(m_styleCombo, 1);
|
|
||||||
|
|
||||||
QVBoxLayout *centralLayout = new QVBoxLayout();
|
|
||||||
centralLayout->addLayout(controlsLayout);
|
|
||||||
centralLayout->addWidget(m_scrollArea, 1);
|
|
||||||
centralWidget->setLayout(centralLayout);
|
|
||||||
|
|
||||||
setCentralWidget(centralWidget);
|
|
||||||
setWindowTitle("QtTXF");
|
|
||||||
|
|
||||||
QMenuBar* menuBar = new QMenuBar(this);
|
|
||||||
|
|
||||||
QMenu* fileMenu = new QMenu(tr("File"));
|
|
||||||
m_saveAction = new QAction(tr("&Save..."), this);
|
|
||||||
QAction* quitAction = new QAction(tr("&Quit"), this);
|
|
||||||
fileMenu->addAction(m_saveAction);
|
|
||||||
fileMenu->addAction(quitAction);
|
|
||||||
menuBar->addMenu(fileMenu);
|
|
||||||
|
|
||||||
setMenuBar(menuBar);
|
|
||||||
|
|
||||||
m_saveAction->setShortcut(QKeySequence::Save);
|
|
||||||
connect(m_saveAction, SIGNAL(triggered()), this, SLOT(saveFont()));
|
|
||||||
quitAction->setShortcut(QKeySequence("Ctrl+Q"));
|
|
||||||
connect(quitAction, SIGNAL(triggered()), this, SLOT(close()));
|
|
||||||
|
|
||||||
buildTxf();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void MainWindow::findStyles(const QFont &font)
|
|
||||||
{
|
|
||||||
QFontDatabase fontDatabase;
|
|
||||||
QString currentItem = m_styleCombo->currentText();
|
|
||||||
m_styleCombo->clear();
|
|
||||||
|
|
||||||
QString style;
|
|
||||||
foreach (style, fontDatabase.styles(font.family()))
|
|
||||||
{
|
|
||||||
m_styleCombo->addItem(style);
|
|
||||||
}
|
|
||||||
|
|
||||||
int styleIndex = m_styleCombo->findText(currentItem);
|
|
||||||
|
|
||||||
if (styleIndex == -1)
|
|
||||||
m_styleCombo->setCurrentIndex(0);
|
|
||||||
else
|
|
||||||
m_styleCombo->setCurrentIndex(styleIndex);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void MainWindow::findSizes(const QFont &font)
|
|
||||||
{
|
|
||||||
QFontDatabase fontDatabase;
|
|
||||||
QString currentSize = m_sizeCombo->currentText();
|
|
||||||
m_sizeCombo->blockSignals(true);
|
|
||||||
m_sizeCombo->clear();
|
|
||||||
|
|
||||||
int size;
|
|
||||||
if (fontDatabase.isSmoothlyScalable(font.family(), fontDatabase.styleString(font)))
|
|
||||||
{
|
|
||||||
foreach(size, QFontDatabase::standardSizes())
|
|
||||||
{
|
|
||||||
m_sizeCombo->addItem(QVariant(size).toString());
|
|
||||||
m_sizeCombo->setEditable(true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
foreach (size, fontDatabase.smoothSizes(font.family(), fontDatabase.styleString(font)))
|
|
||||||
{
|
|
||||||
m_sizeCombo->addItem(QVariant(size).toString());
|
|
||||||
m_sizeCombo->setEditable(false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
m_sizeCombo->blockSignals(false);
|
|
||||||
|
|
||||||
int sizeIndex = m_sizeCombo->findText(currentSize);
|
|
||||||
if (sizeIndex == -1)
|
|
||||||
{
|
|
||||||
m_sizeCombo->setCurrentIndex(qMax(0, m_sizeCombo->count() / 3));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
m_sizeCombo->setCurrentIndex(sizeIndex);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void
|
|
||||||
MainWindow::updateFont(const QFont& font)
|
|
||||||
{
|
|
||||||
qDebug() << font.family() << " match: " << font.exactMatch();
|
|
||||||
m_currentFont.setFamily(font.family());
|
|
||||||
buildTxf();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void
|
|
||||||
MainWindow::updateSize(const QString& sizeString)
|
|
||||||
{
|
|
||||||
m_currentFont.setPointSize(sizeString.toInt());
|
|
||||||
buildTxf();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void
|
|
||||||
MainWindow::updateStyle(const QString& /* styleName */)
|
|
||||||
{
|
|
||||||
buildTxf();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void
|
|
||||||
MainWindow::saveFont()
|
|
||||||
{
|
|
||||||
if (!m_fontData.isEmpty())
|
|
||||||
{
|
|
||||||
QString fileName = QFileDialog::getSaveFileName(this,
|
|
||||||
tr("Save Font File"),
|
|
||||||
"",
|
|
||||||
tr("Texture Fonts (*.txf)"));
|
|
||||||
QFile file(fileName);
|
|
||||||
if (!file.open(QIODevice::WriteOnly))
|
|
||||||
{
|
|
||||||
QMessageBox::warning(this, tr("File Error"), tr("Error writing to %1").arg(fileName));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
QDataStream out(&file);
|
|
||||||
out.writeRawData(m_fontData.data(), m_fontData.length());
|
|
||||||
file.close();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
struct BasicGlyphInfo
|
|
||||||
{
|
|
||||||
QChar ch;
|
|
||||||
int height;
|
|
||||||
};
|
|
||||||
|
|
||||||
bool operator<(const BasicGlyphInfo& info0, const BasicGlyphInfo& info1)
|
|
||||||
{
|
|
||||||
return info0.height > info1.height;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
bool
|
|
||||||
MainWindow::buildTxf()
|
|
||||||
{
|
|
||||||
// Build a txf font from the current system font. Attempt to fit it into a 128x128
|
|
||||||
// texture, progressively increasing the texture size until it fits.
|
|
||||||
bool fitsInTexture = false;
|
|
||||||
int textureWidth = 128;
|
|
||||||
int textureHeight = 128;
|
|
||||||
|
|
||||||
while (textureWidth <= 1024 && !fitsInTexture)
|
|
||||||
{
|
|
||||||
m_fontData.clear();
|
|
||||||
QDataStream out(&m_fontData, QIODevice::WriteOnly);
|
|
||||||
if (buildTxf(m_currentFont, out, textureWidth, textureHeight))
|
|
||||||
{
|
|
||||||
fitsInTexture = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (textureWidth == textureHeight)
|
|
||||||
textureWidth *= 2;
|
|
||||||
else
|
|
||||||
textureHeight *= 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!fitsInTexture)
|
|
||||||
{
|
|
||||||
QMessageBox::warning(this,
|
|
||||||
tr("Font Error"),
|
|
||||||
tr("Font is too large to fit in texture"));
|
|
||||||
m_fontData.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
m_saveAction->setEnabled(fitsInTexture);
|
|
||||||
|
|
||||||
return fitsInTexture;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
QString characterRange(unsigned int firstChar, unsigned int lastChar)
|
|
||||||
{
|
|
||||||
QString s;
|
|
||||||
for (unsigned int i = firstChar; i <= lastChar; ++i)
|
|
||||||
{
|
|
||||||
s += QChar(i);
|
|
||||||
}
|
|
||||||
|
|
||||||
return s;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
bool
|
|
||||||
MainWindow::buildTxf(const QFont& font, QDataStream& out, int texWidth, int texHeight)
|
|
||||||
{
|
|
||||||
QString charset;
|
|
||||||
|
|
||||||
charset += characterRange(0x0020, 0x007e); // ASCII
|
|
||||||
charset += characterRange(0x00a0, 0x00ff); // Latin-1 supplement
|
|
||||||
charset += characterRange(0x0100, 0x017f); // Latin Extended-A
|
|
||||||
charset += characterRange(0x0391, 0x03ce); // Greek
|
|
||||||
|
|
||||||
QPixmap pixmap(texWidth, texHeight);
|
|
||||||
QPainter painter(&pixmap);
|
|
||||||
|
|
||||||
QVector<BasicGlyphInfo> glyphInfoList;
|
|
||||||
|
|
||||||
QFont devFont(font, &pixmap);
|
|
||||||
QFontMetrics fm(devFont);
|
|
||||||
for (int i = 0; i < charset.length(); i++)
|
|
||||||
{
|
|
||||||
QChar ch = charset[i];
|
|
||||||
if (fm.inFont(ch))
|
|
||||||
{
|
|
||||||
BasicGlyphInfo info;
|
|
||||||
info.ch = ch;
|
|
||||||
info.height = fm.boundingRect(ch).height();
|
|
||||||
glyphInfoList << info;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Sort the glyphs by height so that they pack more compactly
|
|
||||||
// into the available space.
|
|
||||||
std::sort(glyphInfoList.begin(), glyphInfoList.end());
|
|
||||||
|
|
||||||
if (glyphInfoList.isEmpty())
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Write txf file header
|
|
||||||
int maxAscent = 0;
|
|
||||||
int maxDescent = 0;
|
|
||||||
out.writeRawData(TXF_HEADER_BYTES, 4);
|
|
||||||
out << TXF_ENDIANNESS_TEST;
|
|
||||||
out << (quint32) 0;
|
|
||||||
out << (quint32) texWidth << (quint32) texHeight;
|
|
||||||
out << (quint32) maxAscent << (quint32) maxDescent;
|
|
||||||
out << (quint32) glyphInfoList.size();
|
|
||||||
|
|
||||||
// Clear the image
|
|
||||||
painter.fillRect(0, 0, texWidth, texHeight, Qt::black);
|
|
||||||
|
|
||||||
int rowHeight = glyphInfoList.first().height;
|
|
||||||
int x = 1;
|
|
||||||
int y = rowHeight;
|
|
||||||
int xSpacing = 3;
|
|
||||||
int ySpacing = 3;
|
|
||||||
|
|
||||||
painter.setFont(devFont);
|
|
||||||
foreach (BasicGlyphInfo info, glyphInfoList)
|
|
||||||
{
|
|
||||||
QRect bounds = fm.boundingRect(info.ch);
|
|
||||||
if (x + bounds.width() >= texWidth)
|
|
||||||
{
|
|
||||||
y += rowHeight + ySpacing;
|
|
||||||
rowHeight = bounds.height();
|
|
||||||
x = 1;
|
|
||||||
|
|
||||||
if (y >= texHeight)
|
|
||||||
{
|
|
||||||
qDebug() << "Not enough room in font glyph texture.";
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
painter.setPen(Qt::white);
|
|
||||||
painter.drawText(x - bounds.left(), y - bounds.bottom(), QString(info.ch));
|
|
||||||
|
|
||||||
#if 0
|
|
||||||
// Show bounding rectangles for debugging
|
|
||||||
painter.setPen(Qt::red);
|
|
||||||
QRect glyphRect = bounds;
|
|
||||||
glyphRect.translate(x - bounds.left(), y - bounds.bottom());
|
|
||||||
painter.drawRect(glyphRect);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Write out the glyph record;
|
|
||||||
out << (quint16) info.ch.unicode();
|
|
||||||
out << (quint8) (bounds.width() + 2) << (quint8) (bounds.height() + 2);
|
|
||||||
out << (qint8) bounds.left() << (qint8) (-bounds.bottom());
|
|
||||||
#if QT_VERSION >= QT_VERSION_CHECK(5, 11, 0)
|
|
||||||
out << (qint8) fm.horizontalAdvance(info.ch);
|
|
||||||
#else
|
|
||||||
out << (qint8) fm.width(info.ch);
|
|
||||||
#endif
|
|
||||||
out << (quint8) 0; /* unused */
|
|
||||||
out << (quint16) (x - 1) << (quint16) (texHeight - y - 2);
|
|
||||||
|
|
||||||
x += bounds.width() + xSpacing;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Write out the glyph texture map
|
|
||||||
QImage glyphImage = pixmap.toImage();
|
|
||||||
for (int iy = 0; iy < texHeight; iy++)
|
|
||||||
{
|
|
||||||
for (int ix = 0; ix < texWidth; ix++)
|
|
||||||
{
|
|
||||||
QRgb rgb = glyphImage.pixel(ix, texHeight - iy - 1);
|
|
||||||
out << (quint8) qGreen(rgb);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
QLabel* label = new QLabel(m_scrollArea);
|
|
||||||
label->setPixmap(pixmap);
|
|
||||||
m_scrollArea->setWidget(label);
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
|
@ -1,54 +0,0 @@
|
||||||
// qttxf - a Qt-based application to generate GLUT txf files from
|
|
||||||
// system fonts
|
|
||||||
//
|
|
||||||
// Copyright (C) 2009, Chris Laurel <claurel@gmail.com>
|
|
||||||
//
|
|
||||||
// This program is free software; you can redistribute it and/or
|
|
||||||
// modify it under the terms of the GNU General Public License
|
|
||||||
// as published by the Free Software Foundation; either version 2
|
|
||||||
// of the License, or (at your option) any later version.
|
|
||||||
|
|
||||||
#ifndef _QTTXF_MAINWINDOW_H_
|
|
||||||
#define _QTTXF_MAINWINDOW_H_
|
|
||||||
|
|
||||||
#include <QMainWindow>
|
|
||||||
#include <QString>
|
|
||||||
|
|
||||||
class QComboBox;
|
|
||||||
class QFontComboBox;
|
|
||||||
class QScrollArea;
|
|
||||||
class QLabel;
|
|
||||||
class QFont;
|
|
||||||
class QDataStream;
|
|
||||||
|
|
||||||
class MainWindow : public QMainWindow
|
|
||||||
{
|
|
||||||
Q_OBJECT
|
|
||||||
|
|
||||||
public:
|
|
||||||
MainWindow();
|
|
||||||
|
|
||||||
bool buildTxf();
|
|
||||||
bool buildTxf(const QFont& font, QDataStream& out, int texWidth, int texHeight);
|
|
||||||
|
|
||||||
public slots:
|
|
||||||
void findStyles(const QFont& font);
|
|
||||||
void findSizes(const QFont& font);
|
|
||||||
void updateFont(const QFont& font);
|
|
||||||
void updateSize(const QString& sizeString);
|
|
||||||
void updateStyle(const QString& styleName);
|
|
||||||
void saveFont();
|
|
||||||
|
|
||||||
private:
|
|
||||||
QScrollArea *m_scrollArea;
|
|
||||||
QLabel* m_imageWidget;
|
|
||||||
QFontComboBox* m_fontCombo;
|
|
||||||
QComboBox* m_sizeCombo;
|
|
||||||
QComboBox* m_styleCombo;
|
|
||||||
QAction* m_saveAction;
|
|
||||||
QFont m_currentFont;
|
|
||||||
QByteArray m_fontData;
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif // _QTTXF_MAINWINDOW_H_
|
|
||||||
|
|
|
@ -1,15 +0,0 @@
|
||||||
TEMPLATE = app
|
|
||||||
TARGET = qttxf
|
|
||||||
|
|
||||||
QT += widgets
|
|
||||||
|
|
||||||
DESTDIR = build
|
|
||||||
OBJECTS_DIR = build
|
|
||||||
MOC_DIR = build
|
|
||||||
|
|
||||||
HEADERS = \
|
|
||||||
mainwindow.h
|
|
||||||
|
|
||||||
SOURCES = \
|
|
||||||
mainwindow.cpp \
|
|
||||||
main.cpp
|
|
|
@ -161,13 +161,13 @@ void printStellarClass(uint16_t sc, ostream& out)
|
||||||
switch (luminosityClass) //without this questionmark a nullchar is written to the file
|
switch (luminosityClass) //without this questionmark a nullchar is written to the file
|
||||||
{ //causing that a dump of stardb is not a textfile but binary.
|
{ //causing that a dump of stardb is not a textfile but binary.
|
||||||
case StellarClass::Lum_Ia0:
|
case StellarClass::Lum_Ia0:
|
||||||
out << "I-a0";
|
out << "Ia-0";
|
||||||
break;
|
break;
|
||||||
case StellarClass::Lum_Ia:
|
case StellarClass::Lum_Ia:
|
||||||
out << "I-a";
|
out << "Ia";
|
||||||
break;
|
break;
|
||||||
case StellarClass::Lum_Ib:
|
case StellarClass::Lum_Ib:
|
||||||
out << "I-b";
|
out << "Ib";
|
||||||
break;
|
break;
|
||||||
case StellarClass::Lum_II:
|
case StellarClass::Lum_II:
|
||||||
out << "II";
|
out << "II";
|
||||||
|
|
|
@ -111,13 +111,13 @@ void printStellarClass(uint16_t sc, ostream& out)
|
||||||
switch (luminosityClass)
|
switch (luminosityClass)
|
||||||
{
|
{
|
||||||
case StellarClass::Lum_Ia0:
|
case StellarClass::Lum_Ia0:
|
||||||
out << "I-a0";
|
out << "Ia-0";
|
||||||
break;
|
break;
|
||||||
case StellarClass::Lum_Ia:
|
case StellarClass::Lum_Ia:
|
||||||
out << "I-a";
|
out << "Ia";
|
||||||
break;
|
break;
|
||||||
case StellarClass::Lum_Ib:
|
case StellarClass::Lum_Ib:
|
||||||
out << "I-b";
|
out << "Ib";
|
||||||
break;
|
break;
|
||||||
case StellarClass::Lum_II:
|
case StellarClass::Lum_II:
|
||||||
out << "II";
|
out << "II";
|
||||||
|
|
Binary file not shown.
|
@ -0,0 +1,37 @@
|
||||||
|
#include <cstdint>
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
#include <catch.hpp>
|
||||||
|
|
||||||
|
#include <cel3ds/3dsmodel.h>
|
||||||
|
#include <cel3ds/3dsread.h>
|
||||||
|
|
||||||
|
TEST_CASE("Load a 3DS file", "[3ds] [integration]")
|
||||||
|
{
|
||||||
|
std::unique_ptr<M3DScene> scene = Read3DSFile("huygens.3ds");
|
||||||
|
REQUIRE(scene != nullptr);
|
||||||
|
REQUIRE(scene->getMaterialCount() == 4);
|
||||||
|
|
||||||
|
REQUIRE(scene->getModelCount() == UINT32_C(8));
|
||||||
|
|
||||||
|
std::uint32_t meshCount = 0;
|
||||||
|
std::uint32_t faceCount = 0;
|
||||||
|
std::uint32_t vertexCount = 0;
|
||||||
|
for (std::uint32_t i = 0; i < scene->getModelCount(); ++i)
|
||||||
|
{
|
||||||
|
const M3DModel* model = scene->getModel(i);
|
||||||
|
REQUIRE(model != nullptr);
|
||||||
|
meshCount += model->getTriMeshCount();
|
||||||
|
for (std::uint32_t j = 0; j < model->getTriMeshCount(); ++j)
|
||||||
|
{
|
||||||
|
const M3DTriangleMesh* mesh = model->getTriMesh(j);
|
||||||
|
REQUIRE(mesh != nullptr);
|
||||||
|
faceCount += static_cast<std::uint32_t>(mesh->getFaceCount());
|
||||||
|
vertexCount += static_cast<std::uint32_t>(mesh->getVertexCount());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
REQUIRE(meshCount == 8);
|
||||||
|
REQUIRE(faceCount == 6098);
|
||||||
|
REQUIRE(vertexCount == 3263);
|
||||||
|
}
|
|
@ -1,4 +1,7 @@
|
||||||
|
test_case(3ds_load)
|
||||||
test_case(cmod_bin_ascii_roundtrip)
|
test_case(cmod_bin_ascii_roundtrip)
|
||||||
|
|
||||||
|
file(COPY "${CMAKE_SOURCE_DIR}/test/data/huygens.3ds"
|
||||||
|
DESTINATION "${CMAKE_CURRENT_BINARY_DIR}")
|
||||||
file(COPY "${CMAKE_SOURCE_DIR}/test/data/iss/models/iss.cmod"
|
file(COPY "${CMAKE_SOURCE_DIR}/test/data/iss/models/iss.cmod"
|
||||||
DESTINATION "${CMAKE_CURRENT_BINARY_DIR}")
|
DESTINATION "${CMAKE_CURRENT_BINARY_DIR}")
|
||||||
|
|
|
@ -1,4 +1,6 @@
|
||||||
test_case(charconv_compat)
|
if(NOT HAVE_FLOAT_CHARCONV)
|
||||||
|
test_case(charconv_compat)
|
||||||
|
endif()
|
||||||
test_case(greek)
|
test_case(greek)
|
||||||
test_case(hash)
|
test_case(hash)
|
||||||
test_case(logger)
|
test_case(logger)
|
||||||
|
|
|
@ -1,22 +1,22 @@
|
||||||
#include <celengine/stellarclass.h>
|
#include <cstdint>
|
||||||
|
|
||||||
#include <catch.hpp>
|
#include <catch.hpp>
|
||||||
|
|
||||||
#define CHECK_NORMAL_STAR(u, _class, _str) \
|
#include <celengine/stellarclass.h>
|
||||||
|
|
||||||
|
#define CHECK_NORMAL_STAR(u, _class) \
|
||||||
REQUIRE(u.getStarType() == StellarClass::NormalStar); \
|
REQUIRE(u.getStarType() == StellarClass::NormalStar); \
|
||||||
REQUIRE(u.getSpectralClass() == _class); \
|
REQUIRE(u.getSpectralClass() == _class); \
|
||||||
REQUIRE(u.getSubclass() == 5); \
|
REQUIRE(u.getSubclass() == 5); \
|
||||||
REQUIRE(u.getLuminosityClass() == StellarClass::Lum_Ia0); \
|
REQUIRE(u.getLuminosityClass() == StellarClass::Lum_Ia0);
|
||||||
REQUIRE(u.str() == _str);
|
|
||||||
|
|
||||||
#define CHECK_WHITE_DWARF(u, _class, _str) \
|
#define CHECK_WHITE_DWARF(u, _class) \
|
||||||
REQUIRE(u.getStarType() == StellarClass::WhiteDwarf); \
|
REQUIRE(u.getStarType() == StellarClass::WhiteDwarf); \
|
||||||
REQUIRE(u.getSpectralClass() == _class); \
|
REQUIRE(u.getSpectralClass() == _class); \
|
||||||
REQUIRE(u.getSubclass() == 5); \
|
REQUIRE(u.getSubclass() == 5); \
|
||||||
REQUIRE(u.getLuminosityClass() == StellarClass::Lum_Unknown); \
|
REQUIRE(u.getLuminosityClass() == StellarClass::Lum_Unknown);
|
||||||
REQUIRE(u.str() == _str);
|
|
||||||
|
|
||||||
TEST_CASE("StellarClass", "[StellarClass]")
|
TEST_CASE("StellarClass packing", "[StellarClass]")
|
||||||
{
|
{
|
||||||
SECTION("StellarClass::Spectral_WO")
|
SECTION("StellarClass::Spectral_WO")
|
||||||
{
|
{
|
||||||
|
@ -25,21 +25,21 @@ TEST_CASE("StellarClass", "[StellarClass]")
|
||||||
5,
|
5,
|
||||||
StellarClass::Lum_Ia0);
|
StellarClass::Lum_Ia0);
|
||||||
|
|
||||||
uint16_t packed;
|
std::uint16_t packed;
|
||||||
StellarClass u;
|
StellarClass u;
|
||||||
|
|
||||||
SECTION("Packed as V1")
|
SECTION("Packed as V1")
|
||||||
{
|
{
|
||||||
packed = sc.packV1();
|
packed = sc.packV1();
|
||||||
REQUIRE(u.unpackV1(packed));
|
REQUIRE(u.unpackV1(packed));
|
||||||
CHECK_NORMAL_STAR(u, StellarClass::Spectral_Unknown, "?5 I-a0");
|
CHECK_NORMAL_STAR(u, StellarClass::Spectral_Unknown);
|
||||||
}
|
}
|
||||||
|
|
||||||
SECTION("Packed as V2")
|
SECTION("Packed as V2")
|
||||||
{
|
{
|
||||||
packed = sc.packV2();
|
packed = sc.packV2();
|
||||||
REQUIRE(u.unpackV2(packed));
|
REQUIRE(u.unpackV2(packed));
|
||||||
CHECK_NORMAL_STAR(u, StellarClass::Spectral_WO, "W5 I-a0");
|
CHECK_NORMAL_STAR(u, StellarClass::Spectral_WO);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -50,21 +50,21 @@ TEST_CASE("StellarClass", "[StellarClass]")
|
||||||
5,
|
5,
|
||||||
StellarClass::Lum_Ia0);
|
StellarClass::Lum_Ia0);
|
||||||
|
|
||||||
uint16_t packed;
|
std::uint16_t packed;
|
||||||
StellarClass u;
|
StellarClass u;
|
||||||
|
|
||||||
SECTION("Packed as V1")
|
SECTION("Packed as V1")
|
||||||
{
|
{
|
||||||
packed = sc.packV1();
|
packed = sc.packV1();
|
||||||
REQUIRE(u.unpackV1(packed));
|
REQUIRE(u.unpackV1(packed));
|
||||||
CHECK_NORMAL_STAR(u, StellarClass::Spectral_Unknown, "?5 I-a0");
|
CHECK_NORMAL_STAR(u, StellarClass::Spectral_Unknown);
|
||||||
}
|
}
|
||||||
|
|
||||||
SECTION("Packed as V2")
|
SECTION("Packed as V2")
|
||||||
{
|
{
|
||||||
packed = sc.packV2();
|
packed = sc.packV2();
|
||||||
REQUIRE(u.unpackV2(packed));
|
REQUIRE(u.unpackV2(packed));
|
||||||
CHECK_NORMAL_STAR(u, StellarClass::Spectral_Y, "Y5 I-a0");
|
CHECK_NORMAL_STAR(u, StellarClass::Spectral_Y);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -75,21 +75,21 @@ TEST_CASE("StellarClass", "[StellarClass]")
|
||||||
5,
|
5,
|
||||||
StellarClass::Lum_Ia0);
|
StellarClass::Lum_Ia0);
|
||||||
|
|
||||||
uint16_t packed;
|
std::uint16_t packed;
|
||||||
StellarClass u;
|
StellarClass u;
|
||||||
|
|
||||||
SECTION("Packed as V1")
|
SECTION("Packed as V1")
|
||||||
{
|
{
|
||||||
packed = sc.packV1();
|
packed = sc.packV1();
|
||||||
REQUIRE(u.unpackV1(packed));
|
REQUIRE(u.unpackV1(packed));
|
||||||
CHECK_NORMAL_STAR(u, StellarClass::Spectral_Unknown, "?5 I-a0");
|
CHECK_NORMAL_STAR(u, StellarClass::Spectral_Unknown);
|
||||||
}
|
}
|
||||||
|
|
||||||
SECTION("Packed as V2")
|
SECTION("Packed as V2")
|
||||||
{
|
{
|
||||||
packed = sc.packV2();
|
packed = sc.packV2();
|
||||||
REQUIRE(u.unpackV2(packed));
|
REQUIRE(u.unpackV2(packed));
|
||||||
CHECK_NORMAL_STAR(u, StellarClass::Spectral_Unknown, "?5 I-a0");
|
CHECK_NORMAL_STAR(u, StellarClass::Spectral_Unknown);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -100,21 +100,21 @@ TEST_CASE("StellarClass", "[StellarClass]")
|
||||||
5,
|
5,
|
||||||
StellarClass::Lum_Ia0);
|
StellarClass::Lum_Ia0);
|
||||||
|
|
||||||
uint16_t packed;
|
std::uint16_t packed;
|
||||||
StellarClass u;
|
StellarClass u;
|
||||||
|
|
||||||
SECTION("Packed as V1")
|
SECTION("Packed as V1")
|
||||||
{
|
{
|
||||||
packed = sc.packV1();
|
packed = sc.packV1();
|
||||||
REQUIRE(u.unpackV1(packed));
|
REQUIRE(u.unpackV1(packed));
|
||||||
CHECK_NORMAL_STAR(u, StellarClass::Spectral_C, "C5 I-a0");
|
CHECK_NORMAL_STAR(u, StellarClass::Spectral_C);
|
||||||
}
|
}
|
||||||
|
|
||||||
SECTION("Packed as V2")
|
SECTION("Packed as V2")
|
||||||
{
|
{
|
||||||
packed = sc.packV2();
|
packed = sc.packV2();
|
||||||
REQUIRE(u.unpackV2(packed));
|
REQUIRE(u.unpackV2(packed));
|
||||||
CHECK_NORMAL_STAR(u, StellarClass::Spectral_C, "C5 I-a0");
|
CHECK_NORMAL_STAR(u, StellarClass::Spectral_C);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -125,21 +125,21 @@ TEST_CASE("StellarClass", "[StellarClass]")
|
||||||
5,
|
5,
|
||||||
StellarClass::Lum_Ia0);
|
StellarClass::Lum_Ia0);
|
||||||
|
|
||||||
uint16_t packed;
|
std::uint16_t packed;
|
||||||
StellarClass u;
|
StellarClass u;
|
||||||
|
|
||||||
SECTION("Packed as V1")
|
SECTION("Packed as V1")
|
||||||
{
|
{
|
||||||
packed = sc.packV1();
|
packed = sc.packV1();
|
||||||
REQUIRE(u.unpackV1(packed));
|
REQUIRE(u.unpackV1(packed));
|
||||||
CHECK_NORMAL_STAR(u, StellarClass::Spectral_L, "L5 I-a0");
|
CHECK_NORMAL_STAR(u, StellarClass::Spectral_L);
|
||||||
}
|
}
|
||||||
|
|
||||||
SECTION("Packed as V2")
|
SECTION("Packed as V2")
|
||||||
{
|
{
|
||||||
packed = sc.packV2();
|
packed = sc.packV2();
|
||||||
REQUIRE(u.unpackV2(packed));
|
REQUIRE(u.unpackV2(packed));
|
||||||
CHECK_NORMAL_STAR(u, StellarClass::Spectral_L, "L5 I-a0");
|
CHECK_NORMAL_STAR(u, StellarClass::Spectral_L);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -151,21 +151,21 @@ TEST_CASE("StellarClass", "[StellarClass]")
|
||||||
5,
|
5,
|
||||||
StellarClass::Lum_Ia0);
|
StellarClass::Lum_Ia0);
|
||||||
|
|
||||||
uint16_t packed;
|
std::uint16_t packed;
|
||||||
StellarClass u;
|
StellarClass u;
|
||||||
|
|
||||||
SECTION("Packed as V1")
|
SECTION("Packed as V1")
|
||||||
{
|
{
|
||||||
packed = sc.packV1();
|
packed = sc.packV1();
|
||||||
REQUIRE(u.unpackV1(packed));
|
REQUIRE(u.unpackV1(packed));
|
||||||
CHECK_NORMAL_STAR(u, StellarClass::Spectral_T, "T5 I-a0");
|
CHECK_NORMAL_STAR(u, StellarClass::Spectral_T);
|
||||||
}
|
}
|
||||||
|
|
||||||
SECTION("Packed as V2")
|
SECTION("Packed as V2")
|
||||||
{
|
{
|
||||||
packed = sc.packV2();
|
packed = sc.packV2();
|
||||||
REQUIRE(u.unpackV2(packed));
|
REQUIRE(u.unpackV2(packed));
|
||||||
CHECK_NORMAL_STAR(u, StellarClass::Spectral_T, "T5 I-a0");
|
CHECK_NORMAL_STAR(u, StellarClass::Spectral_T);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -176,22 +176,87 @@ TEST_CASE("StellarClass", "[StellarClass]")
|
||||||
5,
|
5,
|
||||||
StellarClass::Lum_Ia0);
|
StellarClass::Lum_Ia0);
|
||||||
|
|
||||||
uint16_t packed;
|
std::uint16_t packed;
|
||||||
StellarClass u;
|
StellarClass u;
|
||||||
|
|
||||||
SECTION("Packed as V1")
|
SECTION("Packed as V1")
|
||||||
{
|
{
|
||||||
packed = sc.packV1();
|
packed = sc.packV1();
|
||||||
REQUIRE(u.unpackV1(packed));
|
REQUIRE(u.unpackV1(packed));
|
||||||
CHECK_WHITE_DWARF(u, StellarClass::Spectral_DO, "WD");
|
CHECK_WHITE_DWARF(u, StellarClass::Spectral_DO);
|
||||||
}
|
}
|
||||||
|
|
||||||
SECTION("Packed as V2")
|
SECTION("Packed as V2")
|
||||||
{
|
{
|
||||||
packed = sc.packV2();
|
packed = sc.packV2();
|
||||||
REQUIRE(u.unpackV2(packed));
|
REQUIRE(u.unpackV2(packed));
|
||||||
CHECK_WHITE_DWARF(u, StellarClass::Spectral_DO, "WD");
|
CHECK_WHITE_DWARF(u, StellarClass::Spectral_DO);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE("StellarClass parsing", "[StellarClass]")
|
||||||
|
{
|
||||||
|
SECTION("Luminosity class I-a0")
|
||||||
|
{
|
||||||
|
StellarClass sc = StellarClass::parse("A9I-a0");
|
||||||
|
REQUIRE(sc.getStarType() == StellarClass::NormalStar);
|
||||||
|
REQUIRE(sc.getSpectralClass() == StellarClass::Spectral_A);
|
||||||
|
REQUIRE(sc.getSubclass() == 9);
|
||||||
|
REQUIRE(sc.getLuminosityClass() == StellarClass::Lum_Ia0);
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION("Luminosity class Ia-0")
|
||||||
|
{
|
||||||
|
StellarClass sc = StellarClass::parse("K Ia-0");
|
||||||
|
REQUIRE(sc.getStarType() == StellarClass::NormalStar);
|
||||||
|
REQUIRE(sc.getSpectralClass() == StellarClass::Spectral_K);
|
||||||
|
REQUIRE(sc.getSubclass() == StellarClass::Subclass_Unknown);
|
||||||
|
REQUIRE(sc.getLuminosityClass() == StellarClass::Lum_Ia0);
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION("Luminosity class Ia0")
|
||||||
|
{
|
||||||
|
StellarClass sc = StellarClass::parse("M3Ia0");
|
||||||
|
REQUIRE(sc.getStarType() == StellarClass::NormalStar);
|
||||||
|
REQUIRE(sc.getSpectralClass() == StellarClass::Spectral_M);
|
||||||
|
REQUIRE(sc.getSubclass() == 3);
|
||||||
|
REQUIRE(sc.getLuminosityClass() == StellarClass::Lum_Ia0);
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION("Luminosity class Ia")
|
||||||
|
{
|
||||||
|
StellarClass sc = StellarClass::parse("F7Ia");
|
||||||
|
REQUIRE(sc.getStarType() == StellarClass::NormalStar);
|
||||||
|
REQUIRE(sc.getSpectralClass() == StellarClass::Spectral_F);
|
||||||
|
REQUIRE(sc.getSubclass() == 7);
|
||||||
|
REQUIRE(sc.getLuminosityClass() == StellarClass::Lum_Ia);
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION("Luminosity class I-a")
|
||||||
|
{
|
||||||
|
StellarClass sc = StellarClass::parse("G4 I-a");
|
||||||
|
REQUIRE(sc.getStarType() == StellarClass::NormalStar);
|
||||||
|
REQUIRE(sc.getSpectralClass() == StellarClass::Spectral_G);
|
||||||
|
REQUIRE(sc.getSubclass() == 4);
|
||||||
|
REQUIRE(sc.getLuminosityClass() == StellarClass::Lum_Ia);
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION("Luminosity class Ib")
|
||||||
|
{
|
||||||
|
StellarClass sc = StellarClass::parse("B6 Ib");
|
||||||
|
REQUIRE(sc.getStarType() == StellarClass::NormalStar);
|
||||||
|
REQUIRE(sc.getSpectralClass() == StellarClass::Spectral_B);
|
||||||
|
REQUIRE(sc.getSubclass() == 6);
|
||||||
|
REQUIRE(sc.getLuminosityClass() == StellarClass::Lum_Ib);
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION("Luminosity class I-b")
|
||||||
|
{
|
||||||
|
StellarClass sc = StellarClass::parse("O5I-b");
|
||||||
|
REQUIRE(sc.getStarType() == StellarClass::NormalStar);
|
||||||
|
REQUIRE(sc.getSpectralClass() == StellarClass::Spectral_O);
|
||||||
|
REQUIRE(sc.getSubclass() == 5);
|
||||||
|
REQUIRE(sc.getLuminosityClass() == StellarClass::Lum_Ib);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue