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
|
||||
AlignTrailingComments: true
|
||||
AllowAllParametersOfDeclarationOnNextLine: false
|
||||
AllowShortFunctionsOnASingleLine: true
|
||||
AllowShortIfStatementsOnASingleLine: false
|
||||
AllowShortLoopsOnASingleLine: false
|
||||
AlwaysBreakBeforeMultilineStrings: false
|
||||
AlwaysBreakTemplateDeclarations: true
|
||||
BinPackParameters: false
|
||||
BreakBeforeBinaryOperators: false
|
||||
---
|
||||
AccessModifierOffset: '-4'
|
||||
AlignAfterOpenBracket: AlwaysBreak
|
||||
AlignConsecutiveMacros: 'true'
|
||||
AlignConsecutiveAssignments: 'true'
|
||||
AlignConsecutiveDeclarations: 'true'
|
||||
AlignEscapedNewlines: Left
|
||||
AlignOperands: 'true'
|
||||
AlignTrailingComments: 'true'
|
||||
AllowAllArgumentsOnNextLine: '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
|
||||
BreakBeforeTernaryOperators: false
|
||||
BreakConstructorInitializersBeforeComma: false
|
||||
ColumnLimit: 80
|
||||
CommentPragmas: ''
|
||||
ConstructorInitializerAllOnOneLineOrOnePerLine: false
|
||||
ConstructorInitializerIndentWidth: 0
|
||||
ContinuationIndentWidth: 0
|
||||
Cpp11BracedListStyle: false
|
||||
DerivePointerBinding: false
|
||||
IndentCaseLabels: false
|
||||
IndentFunctionDeclarationAfterType: false
|
||||
IndentWidth: 4
|
||||
BreakBeforeTernaryOperators: 'false'
|
||||
BreakConstructorInitializers: AfterColon
|
||||
BreakInheritanceList: AfterColon
|
||||
BreakStringLiterals: 'true'
|
||||
ColumnLimit: '100'
|
||||
CompactNamespaces: 'false'
|
||||
ConstructorInitializerAllOnOneLineOrOnePerLine: 'false'
|
||||
Cpp11BracedListStyle: 'false'
|
||||
FixNamespaceComments: 'true'
|
||||
IncludeBlocks: Regroup
|
||||
IndentCaseLabels: 'false'
|
||||
IndentPPDirectives: None
|
||||
IndentWidth: '4'
|
||||
IndentWrappedFunctionNames: 'false'
|
||||
KeepEmptyLinesAtTheStartOfBlocks: 'false'
|
||||
Language: Cpp
|
||||
MaxEmptyLinesToKeep: 2
|
||||
MaxEmptyLinesToKeep: '1'
|
||||
NamespaceIndentation: None
|
||||
ObjCSpaceAfterProperty: true
|
||||
ObjCSpaceBeforeProtocolList: true
|
||||
PenaltyBreakBeforeFirstCallParameter: 100
|
||||
PenaltyBreakComment: 100
|
||||
PenaltyBreakFirstLessLess: 0
|
||||
PenaltyBreakString: 100
|
||||
PenaltyExcessCharacter: 1
|
||||
PenaltyReturnTypeOnItsOwnLine: 20
|
||||
PointerBindsToType: true
|
||||
SpaceBeforeAssignmentOperators: true
|
||||
PointerAlignment: Right
|
||||
ReflowComments: 'true'
|
||||
SortIncludes: 'true'
|
||||
SortUsingDeclarations: 'true'
|
||||
SpaceAfterLogicalNot: 'false'
|
||||
SpaceAfterTemplateKeyword: 'false'
|
||||
SpaceBeforeAssignmentOperators: 'true'
|
||||
SpaceBeforeCtorInitializerColon: 'true'
|
||||
SpaceBeforeInheritanceColon: 'true'
|
||||
SpaceBeforeParens: ControlStatements
|
||||
SpaceInEmptyParentheses: false
|
||||
SpacesBeforeTrailingComments: 1
|
||||
SpacesInAngles: false
|
||||
SpacesInCStyleCastParentheses: false
|
||||
SpacesInContainerLiterals: false
|
||||
SpacesInParentheses: false
|
||||
Standard: Cpp11
|
||||
TabWidth: 4
|
||||
SpaceBeforeRangeBasedForLoopColon: 'true'
|
||||
SpaceInEmptyParentheses: 'false'
|
||||
SpacesBeforeTrailingComments: '1'
|
||||
SpacesInAngles: 'false'
|
||||
SpacesInParentheses: 'false'
|
||||
SpacesInSquareBrackets: 'false'
|
||||
Standard: c++17
|
||||
TabWidth: '4'
|
||||
UseTab: Never
|
||||
UseCRLF: 'false'
|
||||
|
|
|
@ -9,6 +9,7 @@ Release/
|
|||
*.la
|
||||
*.exe
|
||||
*.dll
|
||||
*.swp
|
||||
.DS_Store
|
||||
po*/*.gmo
|
||||
po*/POTFILES
|
||||
|
@ -23,3 +24,4 @@ models/
|
|||
textures/
|
||||
mingw/
|
||||
content/
|
||||
CMakeSettings.json
|
||||
|
|
|
@ -1,9 +1,6 @@
|
|||
[submodule "thirdparty/Spice"]
|
||||
path = thirdparty/Spice
|
||||
url = https://github.com/OpenSpace/Spice.git
|
||||
[submodule "content"]
|
||||
path = content
|
||||
url = https://github.com/CelestiaProject/CelestiaContent.git
|
||||
[submodule "thirdparty/fmt"]
|
||||
path = thirdparty/fmt
|
||||
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)
|
||||
|
||||
# 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()
|
||||
if (POLICY CMP0056)
|
||||
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_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_QT6 "Use Qt6 in Qt frontend (Default: off)" OFF)
|
||||
option(USE_GTK3 "Use Gtk3 in GTK2 frontend (Default: off)" OFF)
|
||||
|
||||
if(ENABLE_GLES)
|
||||
|
@ -244,6 +250,14 @@ endif()
|
|||
find_package(Freetype REQUIRED)
|
||||
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)
|
||||
list (SORT _variableNames)
|
||||
|
|
108
ChangeLog
108
ChangeLog
|
@ -246,7 +246,7 @@ Code:
|
|||
* Windows version: InstallShield setup
|
||||
* Windows version: added controls help dialog
|
||||
* UNIX version: implemented find object and about dialogs (Gnome/Gtk only)
|
||||
|
||||
|
||||
Code:
|
||||
* Moved star browser and solar system browser code into separate modules
|
||||
* Fixed DPRINTF macro so it's not broken in g++
|
||||
|
@ -276,7 +276,7 @@ Code:
|
|||
textures added to OpenGL Info dialog.
|
||||
* New objects: Comet Borrelly, the giant Kuiper Belt object 2001 KX76,
|
||||
and the Hubble Space Telescope
|
||||
|
||||
|
||||
Code:
|
||||
* Rewrote texture and model managers
|
||||
* Cleaned up simulation.cpp to use frames of reference and eliminated a lot
|
||||
|
@ -393,7 +393,7 @@ Code:
|
|||
a single modeless dialog.
|
||||
* Fixed period and rotation of Phoebe
|
||||
|
||||
|
||||
|
||||
1.2.1
|
||||
* Unix: configure.in changes to better find OpenGL libraries by Bruckner.
|
||||
* Added accurate orbital calculations for Galilean satellites.
|
||||
|
@ -404,7 +404,7 @@ Code:
|
|||
* Windows: Fixed crash that occurred when recalling a location with
|
||||
no selection
|
||||
|
||||
|
||||
|
||||
1.2.2
|
||||
* Improved find algorithm for starnames, and combined names from hdnames.dat
|
||||
into starnames.dat. Also added several additional names and variant spellings
|
||||
|
@ -557,7 +557,7 @@ Code:
|
|||
* New colors for celestial grid and constellation figures
|
||||
* Tuning of Gnome GUI: underlined key accelerators, enabled operation of all
|
||||
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:
|
||||
Ctrl+Y : automag toggle
|
||||
Ctrl+T : toggle display of comet tails
|
||||
|
@ -572,16 +572,16 @@ Code:
|
|||
when building with VS.NET
|
||||
* Cleaned up OpenGL extension initialization
|
||||
* 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
|
||||
* New script commands: setfaintestautomag45deg {magnitude float},
|
||||
lookback {}
|
||||
* [,] keys now adjust the limiting magnitude at 45 degrees
|
||||
field of view, if automag is ON. Values displayed via flash messages
|
||||
* New script commands: setfaintestautomag45deg {magnitude float},
|
||||
lookback {}
|
||||
* [,] keys now adjust the limiting magnitude at 45 degrees
|
||||
field of view, if automag is ON. Values displayed via flash messages
|
||||
* Associated the 'looking back' operation with the '*' key shortcut
|
||||
* Fixed bug in orbits of Galilean moons
|
||||
* 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:
|
||||
- Bookmarks / URLs;
|
||||
- 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
|
||||
- Added mark/unmark commands for scripts
|
||||
- Bound Ctrl+K to toggle display of markers
|
||||
- Added flash messages indicating on|off status of markers
|
||||
- Implemented markers into KDE interface
|
||||
- Added flash messages indicating on|off status of markers
|
||||
- Implemented markers into KDE interface
|
||||
* Added triangle-accurate picking of mesh objects
|
||||
* Multiview
|
||||
- Ctrl+R : split view vertically
|
||||
|
@ -664,7 +664,7 @@ Code:
|
|||
* Updated configuration files for new versions of autoconf
|
||||
|
||||
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
|
||||
* Allow wildcard character * inplace of extension for texture filenames
|
||||
* Fix bump mapping (again)
|
||||
|
@ -706,7 +706,7 @@ Code:
|
|||
* Made cancel script command stop motion, tracking, and any object-relative
|
||||
coordinate system.
|
||||
* 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
|
||||
some of the jerkiness apparent at very low fields of view.
|
||||
* Corrected radii of Uranus's rings
|
||||
|
@ -739,7 +739,7 @@ Code:
|
|||
* Eliminated obscuring of location labels that occurred low view aspect ratios
|
||||
* Added models of comet Halley and the small moons Pandora and Larissa
|
||||
* 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
|
||||
* Lua scripting additions
|
||||
* View management commands
|
||||
|
@ -760,7 +760,7 @@ Code:
|
|||
* Implemented an algorithm for importance weights to avoid overlapping or
|
||||
too crowded location labels for Mars, Venus and the Moon
|
||||
* 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
|
||||
overlapping objects
|
||||
* 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
|
||||
deprecated.
|
||||
* Display UTF-8 superscript digits in some star names
|
||||
* Updated the Titan texture. It accomodates all published high resolution
|
||||
imaging from the Cassini mission until and including the flyby of 03/31/05.
|
||||
* Updated the Titan texture. It accomodates all published high resolution
|
||||
imaging from the Cassini mission until and including the flyby of 03/31/05.
|
||||
* Updated the Iapetus texture. It accomodates all published high resolution
|
||||
imaging from the Cassini mission, including also a unique hires photo taken
|
||||
in "Saturn shine".
|
||||
imaging from the Cassini mission, including also a unique hires photo taken
|
||||
in "Saturn shine".
|
||||
* Added catalogs of 163 visual and 39 spectroscopic binary orbits,
|
||||
respectively, (S<>erhjelm 1999, Pourbaix 2000) with known primary/secondary
|
||||
mass ratios.
|
||||
* Added an extended and precise data base of 942 galaxies
|
||||
(Steinicke's rev. NGC/IC, 2005) with a magnitude cutoff Bmag < 12.
|
||||
* Added an extended and precise data base of 942 galaxies
|
||||
(Steinicke's rev. NGC/IC, 2005) with a magnitude cutoff Bmag < 12.
|
||||
* Included the commented PERL scripts used to extract and adapt the binary
|
||||
orbit and galaxy data from published professional catalogs.
|
||||
* Added --extrasdir command line option for specifying additional directories
|
||||
|
@ -843,13 +843,13 @@ Code:
|
|||
- fixed automake bug where GConf schema would always install
|
||||
- removed linking against glut for no reason
|
||||
* Implemented complete precision catalog (Steinicke's revised NGC/IC, 2005) of
|
||||
10610 galaxies with
|
||||
- distance information from four catalogs ( 6 methods ),
|
||||
- <= 4 alternate names,
|
||||
- info-URLs,
|
||||
- absolute magnitudes and
|
||||
10610 galaxies with
|
||||
- distance information from four catalogs ( 6 methods ),
|
||||
- <= 4 alternate names,
|
||||
- info-URLs,
|
||||
- absolute magnitudes and
|
||||
- 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.
|
||||
* 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).
|
||||
|
@ -890,7 +890,7 @@ Code:
|
|||
template from S0 disk template via rescaling by (1.0f, 3.8f, 1.0f);
|
||||
- fixed wrong x,y alignment of elliptical rescaling.
|
||||
* 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"}.
|
||||
* 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
|
||||
|
@ -904,10 +904,10 @@ Code:
|
|||
* Deleted various source code files that became superfluous.
|
||||
* Improved comet display. Introduced a neat scheme implementing comet tail
|
||||
fading (between 4 and 6 AU for Sol). Systems with several suns and
|
||||
luminosities different from the solar one are accounted for.
|
||||
* Implemented a new, simple scheme avoiding overcrowded galaxy labels.
|
||||
luminosities different from the solar one are accounted for.
|
||||
* Implemented a new, simple scheme avoiding overcrowded galaxy labels.
|
||||
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.
|
||||
|
||||
|
||||
|
@ -932,7 +932,7 @@ Code:
|
|||
located inside the galaxy (Milky Way...).
|
||||
* Eliminated various incorrect Hubble type acronyms in deepsky.dsc that had
|
||||
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: OpenGL 2.0 render path should now work on many configurations
|
||||
(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: Added bona fide English and French help menu
|
||||
* 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
|
||||
* Updated Titan and Iapetus textures in lores directory
|
||||
* 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: New configurable splash screen
|
||||
(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
|
||||
official data.
|
||||
* Added Mesh for Phoebe texture.
|
||||
* Added Mesh for Phoebe texture.
|
||||
* Updated Iapetus texture.
|
||||
* Moved locations files from extras into data directory for inclusion in
|
||||
standard package.
|
||||
|
@ -1002,7 +1002,7 @@ Code:
|
|||
- HIP 14810 c, HD 185269 b, Gliese 849 b
|
||||
- Mu Ara e
|
||||
- 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
|
||||
* Added stars for new extrasolar planets: GSC 92941-01657
|
||||
* 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
|
||||
regularly spaced in longitude and latitude.
|
||||
* 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 location, nebulae, openclusers, and i18nconsteallations label flags
|
||||
* Established Barycentric Dynamical Time (TDB) as the time scale used
|
||||
|
@ -1090,12 +1090,12 @@ Code:
|
|||
spectra
|
||||
* Made star orbit paths visible
|
||||
* 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
|
||||
-new approach to thickness of galaxy (arms): assumed proportional to read-in
|
||||
brightness values
|
||||
brightness values
|
||||
-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
|
||||
providing a neat 3d effect
|
||||
* galaxy templates:
|
||||
|
@ -1114,10 +1114,10 @@ Code:
|
|||
- Guarded against crash when the JPL ephemeris file can't be found
|
||||
* Generalized rotations
|
||||
- Clear syntax for ssc files
|
||||
- UniformRotation
|
||||
- UniformRotation
|
||||
- PrecessingOrientation
|
||||
- SampledOrientation - interpolated sequence of quaternion key frames
|
||||
* Scripting improvements
|
||||
* Scripting improvements
|
||||
- New celx scripting commands:
|
||||
- utctotdb and tdbtoutc
|
||||
- gl commands
|
||||
|
@ -1125,7 +1125,7 @@ Code:
|
|||
- iterators: celestia:stars and celestia:dsos
|
||||
- get/setaltazimuthmode
|
||||
- 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)
|
||||
- Support Lua 5.1 (5.0 compatibility retained)
|
||||
- Made celestia:loadtexture use relative file names
|
||||
|
@ -1148,7 +1148,7 @@ Code:
|
|||
* Corrected kilometers per light year constant
|
||||
* Added various improvements to the MilkyWay & other galaxy template display.
|
||||
* Added E0.png galaxy template that allows for better En, n=1..7 elliptical
|
||||
shapes.
|
||||
shapes.
|
||||
* Fixed sizes of irregular galaxies (factor of 2!).
|
||||
* Prevented galaxy code from crashing if a template is missing.
|
||||
* 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
|
||||
* 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
|
||||
galaxies now involve distance measurements
|
||||
* Included the complete local group of galaxies
|
||||
galaxies now involve distance measurements
|
||||
* Included the complete local group of galaxies
|
||||
* Added varying label transparency also for stars
|
||||
* 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
|
||||
* updated binary orbit data (visualbins.stc and spectbins.stc) along with
|
||||
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 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,
|
||||
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
|
||||
removed HD 33636 b
|
||||
* Set up transit of Gliese 436
|
||||
|
@ -1383,7 +1383,7 @@ Bug fixes
|
|||
* Fixed search path for Lua scripts
|
||||
* Fixed numerous bugs that occurred when an object's orbit center was different
|
||||
* 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
|
||||
* Fixed discrepancy between apparent magnitudes shown in the 3D view and
|
||||
the star browser.
|
||||
|
@ -1424,9 +1424,9 @@ Data file updates
|
|||
* Changed class of small outer planet moons to minormoon
|
||||
* Included new and updated solar system body features from the IAU
|
||||
* Added provisional rotation period for Eris
|
||||
|
||||
|
||||
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 Perl script to build cross-indices
|
||||
* Added Perl script to generate CHARM2 catalog
|
||||
|
@ -1557,7 +1557,7 @@ Scripting
|
|||
- windowbordersvisible, setwindowbordersvisible
|
||||
* Split celx scripting support into several modules
|
||||
* Cel scripting
|
||||
- splitview, deleteview, singleview, setactiveview
|
||||
- splitview, deleteview, singleview, setactiveview
|
||||
- setgalaxylightgain
|
||||
- setradius
|
||||
- setlinecolor
|
||||
|
|
|
@ -150,7 +150,7 @@ following option to cmake: -DCMAKE_INSTALL_PREFIX=/another/path.
|
|||
|
||||
## 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 (*).
|
||||
|
||||
Install required packages:
|
||||
|
@ -170,6 +170,9 @@ for 64-bit versions.
|
|||
|
||||
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:
|
||||
|
||||
```
|
||||
|
@ -188,8 +191,8 @@ cmake -DCMAKE_GENERATOR_PLATFORM=x64 -DCMAKE_TOOLCHAIN_FILE=c:/tools/vcpkg/scrip
|
|||
cmake --build . -- /maxcpucount:N /nologo
|
||||
```
|
||||
|
||||
Instead of N in /maxcpucount pass a number of CPU cores you want to use during
|
||||
a build.
|
||||
Instead of N in /maxcpucount pass the number of CPU cores you want to use during
|
||||
the build.
|
||||
|
||||
This example assumes that `vcpkg` is installed into `c:/tools/vcpkg`. Update
|
||||
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-logo.png)<br>
|
||||
**A real-time space simulation that lets you experience our universe in three dimensions.**
|
||||
Celestia is 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 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
|
||||
![celestia-screenshot](pics/celestia-screenshot.png)
|
||||
|
||||
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.
|
||||
# Upstream
|
||||
This repo is a lesser fork of the upstream project,
|
||||
which has been revived.
|
||||
|
||||
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
|
||||
* https://celestia.space/
|
||||
|
||||
## Getting started
|
||||
* https://github.com/CelestiaProject/Celestia
|
||||
|
||||
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).
|
||||
See also: `README-upstream`, `README-upstream.md`.
|
||||
|
||||
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.
|
||||
## License/Copyright
|
||||
GPLv2+
|
||||
|
||||
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.
|
||||
Copyright © 2001-2021, Celestia Development Team
|
||||
|
||||
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.
|
||||
# Debian
|
||||
Package was removed from Debian in the ancient days due to bitrot.
|
||||
The upstream code has a new team and active development, using
|
||||
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
|
||||
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.
|
||||
Debian upstream bug:
|
||||
|
||||
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.
|
||||
* https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=809916
|
||||
|
||||
### 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.
|
||||
```
|
||||
Upstream has not produced any new releases in the last 4 years. In the
|
||||
mean time, the package is accumulating bugs due to bitrot. It already
|
||||
wasn't a trouble-free package, due to some quite important resources not
|
||||
being DFSG compliant.
|
||||
```
|
||||
|
||||
### 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.
|
||||
I do see some of the resources now are CC-by-SA 4.0, a license which
|
||||
didn't exist when the Debian bug was created. So it may be that it
|
||||
can be built happily without DFSG issues using new data files.
|
||||
|
||||
### 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/
|
||||
Celestia depending on NASA's Spice/NAIF may be afoul of Debian's
|
||||
DFSG because the terms are unique. It isn't really a standard license.
|
||||
|
||||
### 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)
|
||||
Debian tracker link:
|
||||
|
||||
All three types of catalog file are text files that can be updated with your
|
||||
favorite text editing program.
|
||||
* https://tracker.debian.org/pkg/celestia
|
||||
|
||||
### Building from sources
|
||||
See instructions in file [INSTALL.md](INSTALL.md).
|
||||
# Build
|
||||
Mini Debian package build howto.
|
||||
|
||||
## 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.|
|
||||
```
|
||||
# Install deps
|
||||
sudo apt update
|
||||
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
|
||||
# your distribution of Celestia, look in the fonts directory located
|
||||
# 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.
|
||||
# Default: "sans12.txf"
|
||||
# Default: "DejaVuSans.ttf,9"
|
||||
#
|
||||
# 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.
|
||||
# Default "sansbold20.txf"
|
||||
# Default "DejaVuSans-Bold.ttf,15"
|
||||
#------------------------------------------------------------------------
|
||||
Font "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\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_es.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_STD_FILESYSTEM
|
||||
#cmakedefine HAVE_WORDEXP
|
||||
#cmakedefine HAVE_MESHOPTIMIZER
|
||||
#cmakedefine WORDS_BIGENDIAN
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
README
|
||||
README.md
|
||||
README-upstream
|
||||
README-upstream.md
|
||||
AUTHORS
|
||||
TRANSLATORS
|
||||
|
|
|
@ -12,7 +12,7 @@ usr/bin/3dstocmod
|
|||
usr/bin/cmodfix
|
||||
usr/bin/txt2cmod
|
||||
usr/bin/cmodsphere
|
||||
usr/bin/qttxf
|
||||
#usr/bin/qttxf
|
||||
#usr/bin/spice2xyzv
|
||||
usr/bin/vsoptrunc-rect
|
||||
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
|
||||
|
||||
* New snapshot build
|
||||
|
|
|
@ -5,6 +5,7 @@ Maintainer: Hleb Valoshka <375gnu@gmail.com>
|
|||
Build-Depends: debhelper (>= 10~),
|
||||
chrpath,
|
||||
cmake (>= 3.1~),
|
||||
dos2unix,
|
||||
freeglut3-dev,
|
||||
libeigen3-dev (>= 3.3~),
|
||||
libfmt-dev (>= 4),
|
||||
|
|
|
@ -26,6 +26,8 @@ override_dh_auto_configure:
|
|||
|
||||
|
||||
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 {} ';'
|
||||
chrpath --delete debian/tmp/usr/lib/*/libcelestia.so.*
|
||||
dh_install --fail-missing
|
||||
|
|
|
@ -3,10 +3,10 @@
|
|||
labels { clear "planets|minorplanets|stars|constellations" }
|
||||
renderflags { set "stars|planets"
|
||||
clear "constellations|orbits|cloudmaps" }
|
||||
print { text "Начало на демонстрацията . . .\nНатиснете ESC за край." origin "center" duration 2 }
|
||||
print { text "Начало на демонстрацията...\nНатиснете „Esc“ за край." origin "center" duration 2 }
|
||||
wait { duration 2.0 }
|
||||
|
||||
print { text "Нека да започнем от нашия дом . . ." row -3 }
|
||||
print { text "Нека да започнем от нашия дом..." row -3 }
|
||||
select { object "Sol/Earth" }
|
||||
cancel {}
|
||||
# goto { time 0 distance 3 upframe "ecliptical" }
|
||||
|
@ -18,25 +18,25 @@
|
|||
wait { duration 1.0 }
|
||||
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 }
|
||||
print { text "Като добавим и облаците, Земята изглежда по позната." row -3}
|
||||
print { text "Като добавим и облаците, Земята изглежда по-позната." row -3}
|
||||
wait { duration 0.1 }
|
||||
renderflags { set "cloudmaps" }
|
||||
orbit { axis [ 0 1 0 ] rate 30 duration 6 }
|
||||
|
||||
print { text "Следваща спирка: Луната." row -3 }
|
||||
print { text "Следваща спирка: Луната" row -3 }
|
||||
select { object "Moon" }
|
||||
goto { time 5 distance 4 upframe "equatorial" }
|
||||
wait { duration 5.5 }
|
||||
print { text "Оглеждайте се за Земята и Слънцето, докато се движим около Луната" row -3}
|
||||
print { text "Оглеждайте се за Земята и Слънцето, докато обикаляме около Луната." row -3}
|
||||
orbit { axis [ 0 1 0 ] rate 30 duration 10 }
|
||||
|
||||
print { text "Напред към Слънцето." row -3}
|
||||
print { text "Напред към Слънцето!" row -3}
|
||||
select { object "Sol" }
|
||||
goto { time 8 distance 12 upframe "equatorial" up [ 0 1 0 ] }
|
||||
wait { duration 8.5 }
|
||||
print { text "От това разстояние могат да се видят тъмните слънчеви петна по повърхността му." row -3}
|
||||
print { text "От това разстояние може да видим тъмните слънчеви петна по повърхността му." row -3}
|
||||
orbit { axis [ 0 1 0 ] rate 20 duration 10 }
|
||||
|
||||
print { text "Нека да се отдалечим и разгледаме вътрешната част на Слънчевата система." row -3}
|
||||
|
@ -44,10 +44,10 @@
|
|||
renderflags { set "orbits" }
|
||||
changedistance { duration 4.0 rate 1.0 }
|
||||
|
||||
print { text "Да включим имената на планетите . . ." row -3}
|
||||
print { text "Да включим имената на планетите..." row -3}
|
||||
labels { set "planets" }
|
||||
wait { duration 1.0 }
|
||||
print { text "Можем да ускорим времето за да видим как планетите обикалят около Слънцето." row -3}
|
||||
print { text "Може да ускорим времето за да видим как планетите обикалят около Слънцето." row -3}
|
||||
timerate { rate 2592000 }
|
||||
wait { duration 3.0 }
|
||||
print { text "Всяка секунда в реално време е равна на един месец в симулацията." row -3}
|
||||
|
@ -56,7 +56,7 @@
|
|||
print { text "В момента, времето е спряно." row -3}
|
||||
|
||||
wait { duration 1.0 }
|
||||
print { text "Следващата ни дестинация е Сатурн." row -3}
|
||||
print { text "Следваща спирка: Сатурн" row -3}
|
||||
select { object "Saturn" }
|
||||
center { time 2 }
|
||||
wait { duration 2 }
|
||||
|
@ -64,12 +64,12 @@
|
|||
wait { duration 6.5 }
|
||||
renderflags { clear "orbits" }
|
||||
labels { clear "planets" }
|
||||
print { text "Няколко от луните на Сатурн са видими като ярки точки" row -3 duration 3}
|
||||
print { text "Няколко от спътниците на Сатурн са видими като ярки точки." row -3 duration 3}
|
||||
orbit { axis [ 0 1 0 ] rate 30 duration 12 }
|
||||
|
||||
select { object "Mimas" }
|
||||
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 }
|
||||
changedistance { duration 6.0 rate 0.5 }
|
||||
|
||||
|
@ -82,22 +82,22 @@
|
|||
wait { duration 2 }
|
||||
select { object "Alpha UMa" }
|
||||
center { time 2 }
|
||||
print { text "Ако живеете в северното полукълбо, ще разпознаете Колата в съзвездието Голямата мечка." row -3 duration 3 }
|
||||
print { text "Ако живеете в северното полукълбо, ще разпознаете Волската кола в съзвездието Голямата мечка." row -3 duration 3 }
|
||||
wait { duration 4 }
|
||||
|
||||
select { object "Polaris" }
|
||||
center { time 2 }
|
||||
wait { duration 2 }
|
||||
print { text "А това е Поларис, известна още като Северната звезда." row -3}
|
||||
print { text "Това е Поларис, известна още като Северната звезда." row -3}
|
||||
wait { duration 1 }
|
||||
labels { set "stars" }
|
||||
wait { duration 2 }
|
||||
print { text "Поларис е част от Малката мечка." row -3}
|
||||
wait { duration 2 }
|
||||
print { text "За по-добра ориентация в небето, Celestia може да активира диаграмите на съзвездията . . ." row -3}
|
||||
print { text "За по-добра ориентация в небето, „Celestia“ може да активира очертанията на съзвездията..." row -3}
|
||||
renderflags { set "constellations" }
|
||||
wait { duration 2 }
|
||||
print { text ". . . и имената на съзвездията" row -3}
|
||||
print { text "...и имената на съзвездията." row -3}
|
||||
labels { set "constellations" }
|
||||
wait { duration 2 }
|
||||
|
||||
|
@ -114,7 +114,7 @@
|
|||
wait { duration 4 }
|
||||
|
||||
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" }
|
||||
rotate { axis [ 0.707 0.707 0 ] rate 20 duration 14 }
|
||||
rotate { axis [ 0.707 0.707 0 ] rate 20 duration 10 }
|
||||
|
@ -122,7 +122,7 @@
|
|||
select { object "Antares" }
|
||||
center { time 5 }
|
||||
wait { duration 3 }
|
||||
print { text "Сега ще пътуваме до Антарес, това е звезда червен гигант в съзвездието Скорпион." row -3 duration 5 }
|
||||
print { text "Сега ще посетим Антарес, това е звезда червен гигант в съзвездието Скорпион." row -3 duration 5 }
|
||||
wait { duration 2 }
|
||||
renderflags { clear "constellations" }
|
||||
labels { clear "constellations|stars" }
|
||||
|
@ -134,13 +134,13 @@
|
|||
print { text "Въпреки че сме 10 пъти по-далече от Антарес\nотколкото Земята е от Слънцето, масивната звезда червен гигант изглежда застрашително голяма." row -3}
|
||||
wait { duration 4.0 }
|
||||
|
||||
print { text "Нека да се отдалечим за да видим как изглежда нашата галактика . . ." row -3}
|
||||
print { text "Нека да се отдалечим за да видим как изглежда нашата галактика..." row -3}
|
||||
changedistance { duration 10.0 rate 2.0 }
|
||||
|
||||
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 }
|
||||
print { text "Време е да се прибираме . . ." row -3}
|
||||
print { text "Време е да се прибираме..." row -3}
|
||||
|
||||
select { object "Sol/Earth" }
|
||||
goto { time 20 distance 10 upframe "equatorial" }
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
Name "Юпитер"
|
||||
Target "Sol/Jupiter"
|
||||
Description "Юпитер е най-голямата планета в Слънчевата система и е на пета позиция от Слънцето. Както и останалите външни планети, Юпитер е газов гигант без твърда повърхност. Голямото червено петно е най-голямата и най-продължителната буря в турболентната атмосфера на планетата; тази вихрушка с размерите на Земята съществува от около 300 години."
|
||||
Description "Юпитер е най-голямата планета в Слънчевата система и е на пета позиция от Слънцето. Както и останалите външни планети, Юпитер е газов гигант без твърда повърхност. Голямото червено петно е най-голямата и най-продължителната буря в турболентната атмосфера на планетата – тази вихрушка с размерите на Земята съществува от около 300 години."
|
||||
}
|
||||
|
||||
{
|
||||
|
@ -9,13 +9,13 @@
|
|||
Target "Sol/Pluto"
|
||||
Distance 40000
|
||||
DistanceUnits "km"
|
||||
Description "Плутон обикаля около Слънцето на средно разстояние от шест милиарда километра. Луната му Харон е толкова голяма, че често ги наричат с Плутон 'двойна планета'."
|
||||
Description "Плутон обикаля около Слънцето на средно разстояние от шест милиарда километра. Спътникът му Харон е толкова голям, че често ги наричат заедно с Плутон „двойната планета“."
|
||||
}
|
||||
|
||||
{
|
||||
Name "Ерос"
|
||||
Target "Sol/Eros"
|
||||
Description "Ерос е астероид във формата на картоф и е дълъг около 33 км. Благодарение на космическия апарат NEAR Shoemaker, за Ерос знаем повече, отколкото за който и да било друг астероид. На 14 февруари 2001 г. NEAR се спусна на Ерос и стана първият апарат, приземил се на астероид."
|
||||
Description "Ерос е астероид във формата на картоф и е дълъг около 33 км. Благодарение на космическия апарат „NEAR Shoemaker“, за Ерос знаем повече, отколкото за който и да било друг астероид. На 14 Февруари 2001 г., „NEAR“ се спусна на Ерос и стана първият апарат, приземил се на астероид."
|
||||
}
|
||||
|
||||
{
|
||||
|
@ -23,7 +23,7 @@
|
|||
Target "Alpha Centauri"
|
||||
Distance 90
|
||||
DistanceUnits "au"
|
||||
Description "Алфа Кантавър А и Б, заедно с Проксима Кентавър, са най-близката звездна система до Земята. Алфа Кентавър А много прилича на Слънцето, въпреки че е малко по-стара и по-ярка. Б е по-тъмна и по-червеникава, а Проксима е толкова слаба, че не може да се види с невъоръжено око, въпреки, че е най-близката звезда до Слънцето."
|
||||
Description "Алфа Кентавър А и Б, заедно с Проксима Кентавър, са най-близката звездна система до Земята. Алфа Кентавър А много прилича на Слънцето, въпреки че е малко по-стара и по-ярка звезда. Алфа Кентавър Б е по-тъмна и по-червеникава, а Проксима Кентавър е толкова слаба, че не може да се види с невъоръжено око, въпреки, че е най-близката звезда до Слънцето."
|
||||
}
|
||||
|
||||
{
|
||||
|
@ -31,7 +31,7 @@
|
|||
Target "Alcyone"
|
||||
Distance 35
|
||||
DistanceUnits "ly"
|
||||
Description "Звездния куп Плеяди е група ярки, наскоро формирани звезди. Плеядите носят името на седем сестри от гръцката митология, въпреки, че телескопите са разкрили, че в звездния куп има доста повече от седем звезди."
|
||||
Description "Звездният куп Плеяди е група ярки, наскоро формирани звезди. Плеядите носят името на седем сестри от гръцката митология, въпреки че телескопите са разкрили, че в звездния куп има доста повече от седем звезди."
|
||||
}
|
||||
|
||||
{
|
||||
|
@ -39,13 +39,13 @@
|
|||
Target "63 Tau"
|
||||
Distance 25
|
||||
DistanceUnits "ly"
|
||||
Description "Носещи името на петте дъщери на Атлас и Аетра, Хиядите са един от най-видните разсеяни звездни купове в небето. Звездите от звездния куп Хияди са на около 660 милиона години - около шест пъти по-стари от по-горещите и по-сини Плеяди."
|
||||
Description "Носещи името на петте дъщери на Атлас и Аетра, Хиядите са един от най-видните разсеяни звездни купове в небето. Звездите от звездния куп Хияди са на около 660 милиона години - около шест пъти по-стари от по-горещите и по-сини Плеяди."
|
||||
}
|
||||
|
||||
{
|
||||
Name "Глийзе 876 б"
|
||||
Target "Gliese 876/b"
|
||||
Description "Глийзе 876/б е гигантска планета в орбита около червено джудже. Тя е в резонанс 2:1 с друга планета от същата система."
|
||||
Description "Глийзе 876/б е гигантска планета в орбита около червено джудже. Тя е в резонанс 2:1 с друга планета от същата система."
|
||||
}
|
||||
|
||||
{
|
||||
|
@ -53,24 +53,24 @@
|
|||
Target "Sol/Ida"
|
||||
Distance 200
|
||||
DistanceUnits "km"
|
||||
Description "Космическият апарат Галилео фотографира астероида 243 Ида през 1993 г. на път към Юпитер. Снимките разкриха, че Ида има малък сателит, по-късно наречен Дактил. От тогава насам са открити още няколко астероида със спътници."
|
||||
Description "Космическият апарат Галилео засне астероида 243 Ида през 1993 г. на път към Юпитер. Снимките разкриха, че Ида има малък спътник, по-късно наречен Дактил. От тогава до сега са открити още няколко астероида със спътници."
|
||||
}
|
||||
|
||||
{
|
||||
Name "51 Пегас б"
|
||||
Target "51 Peg/b"
|
||||
Description "51 Пегас б е първата открита планета, която обикаля около нормална звезда, различна от Слънцето. Тя е планета газов гигант и орбитата ѝ е изключително близо до звездата ѝ - по-малко от една пета от разстоянието между Меркурий и Слънцето. Съществуването на такава планета толкова близо до звезда накара астрономите да преразгледат теориите си за формирането на планетните системи."
|
||||
Description "51 Пегас б е първата открита планета, която обикаля около нормална звезда, различна от Слънцето. Тя е газов гигант и орбитата ѝ е изключително близо до нейната звездата - по-малко от една пета от разстоянието между Меркурий и Слънцето. Съществуването на такава планета толкова близо до звезда накара астрономите да преразгледат теориите си за формирането на планетните системи."
|
||||
}
|
||||
|
||||
{
|
||||
Name "Албирео"
|
||||
Target "Albireo"
|
||||
Distance 0.6
|
||||
Description "Заради контрастните оранжеви и синьо-бели цветове на съставните ѝ звезди, двойната звездна система Албирео е смятана за една от най-красивите двойки в небето. Оранжевата звезда е клас K гигант, а спътникът ѝ е B джудже."
|
||||
Description "Заради контрастните оранжеви и синьо-бели цветове на съставните ѝ звезди, двойната звездна система Албирео е смятана за една от най-красивите двойки в небето. Оранжевата звезда е гигант от клас K, а спътникът ѝ е джудже от клас B."
|
||||
}
|
||||
|
||||
{
|
||||
Name "Кометата Борели"
|
||||
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 (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);
|
||||
buffer += length;
|
||||
}
|
||||
|
|
|
@ -100,7 +100,7 @@ void Nebula::render(const Vector3f& /*offset*/,
|
|||
getOrientation());
|
||||
|
||||
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);
|
||||
|
||||
renderer->enableBlending();
|
||||
|
|
|
@ -25,30 +25,14 @@ template <class OBJ, class PREC> class ObjectRenderer : public OctreeProcessor<O
|
|||
const Observer* observer { nullptr };
|
||||
Renderer* renderer { nullptr };
|
||||
|
||||
Eigen::Vector3f viewNormal;
|
||||
|
||||
float fov { 0.0f };
|
||||
float size { 0.0f };
|
||||
float pixelSize { 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 };
|
||||
|
||||
// Objects brighter than labelThresholdMag will be labeled
|
||||
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 };
|
||||
int labelMode { 0 };
|
||||
};
|
||||
|
|
|
@ -34,7 +34,8 @@ PointStarRenderer::PointStarRenderer() :
|
|||
|
||||
void PointStarRenderer::process(const Star& star, float distance, float appMag)
|
||||
{
|
||||
nProcessed++;
|
||||
if (distance > distanceLimit)
|
||||
return;
|
||||
|
||||
Vector3f starPos = star.getPosition();
|
||||
|
||||
|
@ -44,9 +45,6 @@ void PointStarRenderer::process(const Star& star, float distance, float appMag)
|
|||
float orbitalRadius = star.getOrbitalRadius();
|
||||
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
|
||||
// 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.
|
||||
|
@ -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
|
||||
// instead of a particle
|
||||
// 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
|
||||
// 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.
|
||||
// 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();
|
||||
|
||||
// Recompute apparent magnitude using new distance computation
|
||||
appMag = star.getApparentMagnitude((float)distance);
|
||||
appMag = star.getApparentMagnitude(distance);
|
||||
|
||||
discSizeInPixels = star.getRadius() / astro::lightYearsToKilometers(distance) / pixelSize;
|
||||
++nClose;
|
||||
}
|
||||
|
||||
// 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.
|
||||
if (distance > SolarSystemMaxDistance)
|
||||
{
|
||||
float satPoint = faintestMag - (1.0f - brightnessBias) / brightnessScale; // TODO: precompute this value
|
||||
float alpha = (faintestMag - appMag) * brightnessScale + brightnessBias;
|
||||
float pointSize, alpha, glareSize, glareAlpha;
|
||||
float size = BaseStarDiscSize * static_cast<float>(renderer->getScreenDpi()) / 96.0f;
|
||||
renderer->calculatePointSize(appMag,
|
||||
size,
|
||||
pointSize,
|
||||
alpha,
|
||||
glareSize,
|
||||
glareAlpha);
|
||||
|
||||
if (useScaledDiscs)
|
||||
{
|
||||
float discSize = size;
|
||||
if (alpha < 0.0f)
|
||||
{
|
||||
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;
|
||||
if (glareSize != 0.0f)
|
||||
glareVertexBuffer->addStar(relPos, Color(starColor, glareAlpha), glareSize);
|
||||
if (pointSize != 0.0f)
|
||||
starVertexBuffer->addStar(relPos, Color(starColor, alpha), pointSize);
|
||||
|
||||
// Place labels for stars brighter than the specified label threshold brightness
|
||||
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),
|
||||
color,
|
||||
relPos);
|
||||
nLabelled++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -43,13 +43,12 @@ class PointStarRenderer : public ObjectRenderer<Star, float>
|
|||
void process(const Star &star, float distance, float appMag);
|
||||
|
||||
Eigen::Vector3d obsPos;
|
||||
Eigen::Vector3f viewNormal;
|
||||
std::vector<RenderListEntry>* renderList { nullptr };
|
||||
PointStarVertexBuffer* starVertexBuffer { nullptr };
|
||||
PointStarVertexBuffer* glareVertexBuffer { nullptr };
|
||||
const StarDatabase* starDB { nullptr };
|
||||
const ColorTemperatureTable* colorTemp { nullptr };
|
||||
float SolarSystemMaxDistance { 1.0f };
|
||||
float maxDiscSize { 1.0f };
|
||||
float cosFOV { 1.0f };
|
||||
bool useScaledDiscs { false };
|
||||
};
|
||||
|
|
|
@ -80,7 +80,7 @@ void PointStarVertexBuffer::makeCurrent()
|
|||
current->finish();
|
||||
|
||||
program->use();
|
||||
program->setMVPMatrices(renderer.getProjectionMatrix(), renderer.getModelViewMatrix());
|
||||
program->setMVPMatrices(renderer.getCurrentProjectionMatrix(), renderer.getCurrentModelViewMatrix());
|
||||
if (pointSizeFromVertex)
|
||||
{
|
||||
program->samplerParam("starTex") = 0;
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
#include "lightenv.h"
|
||||
#include "rendcontext.h"
|
||||
#include "render.h"
|
||||
#include "shadowmap.h" // GL_ONLY_SHADOWS definition
|
||||
#include "texmanager.h"
|
||||
#include "texture.h"
|
||||
|
||||
|
|
|
@ -1560,6 +1560,13 @@ void Renderer::draw(const Observer& observer,
|
|||
else
|
||||
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);
|
||||
|
||||
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
|
||||
|
@ -1662,43 +1669,7 @@ void Renderer::draw(const Observer& observer,
|
|||
enableDepthMask();
|
||||
}
|
||||
|
||||
void renderPoint(const Renderer &renderer,
|
||||
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
|
||||
}
|
||||
|
||||
static
|
||||
void renderLargePoint(Renderer &renderer,
|
||||
const Vector3f &position,
|
||||
const Color &color,
|
||||
|
@ -1741,6 +1712,64 @@ void renderLargePoint(Renderer &renderer,
|
|||
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
|
||||
// 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,
|
||||
float radius,
|
||||
float appMag,
|
||||
float _faintestMag,
|
||||
float discSizeInPixels,
|
||||
const Color &color,
|
||||
bool useHalos,
|
||||
bool emissive,
|
||||
const Matrices &mvp)
|
||||
{
|
||||
const float maxSize = MaxScaledDiscStarSize;
|
||||
float maxDiscSize = (starStyle == ScaledDiscStars) ? maxSize : 1.0f;
|
||||
const bool useScaledDiscs = starStyle == ScaledDiscStars;
|
||||
float maxDiscSize = useScaledDiscs ? MaxScaledDiscStarSize : 1.0f;
|
||||
float maxBlendDiscSize = maxDiscSize + 3.0f;
|
||||
|
||||
bool useScaledDiscs = starStyle == ScaledDiscStars;
|
||||
|
||||
if (discSizeInPixels < maxBlendDiscSize || useHalos)
|
||||
{
|
||||
float alpha = 1.0f;
|
||||
float fade = 1.0f;
|
||||
float size = BaseStarDiscSize * screenDpi / 96.0f;
|
||||
float satPoint = _faintestMag - (1.0f - brightnessBias) / brightnessScale;
|
||||
|
||||
if (discSizeInPixels > maxDiscSize)
|
||||
{
|
||||
fade = (maxBlendDiscSize - discSizeInPixels) /
|
||||
(maxBlendDiscSize - maxDiscSize);
|
||||
if (fade > 1)
|
||||
fade = 1;
|
||||
fade = std::min(1.0f, (maxBlendDiscSize - discSizeInPixels) /
|
||||
(maxBlendDiscSize - maxDiscSize));
|
||||
}
|
||||
|
||||
alpha = (_faintestMag - appMag) * brightnessScale * 2.0f + brightnessBias;
|
||||
if (alpha < 0.0f)
|
||||
alpha = 0.0f;
|
||||
float scale = static_cast<float>(screenDpi) / 96.0f;
|
||||
float pointSize, alpha, glareSize, glareAlpha;
|
||||
calculatePointSize(appMag, BaseStarDiscSize * scale, pointSize, alpha, glareSize, glareAlpha);
|
||||
|
||||
float pointSize = size;
|
||||
float glareSize = 0.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);
|
||||
}
|
||||
}
|
||||
if (useScaledDiscs && discSizeInPixels > MaxScaledDiscStarSize)
|
||||
glareAlpha = std::min(glareAlpha, (MaxScaledDiscStarSize - discSizeInPixels) / MaxScaledDiscStarSize + 1.0f);
|
||||
|
||||
alpha *= fade;
|
||||
if (!emissive)
|
||||
{
|
||||
glareSize = max(glareSize, pointSize * discSizeInPixels / (screenDpi / 96.0f) * 3.0f);
|
||||
glareAlpha *= fade;
|
||||
}
|
||||
|
||||
Matrix3f m = m_cameraOrientation.conjugate().toRotationMatrix();
|
||||
Vector3f center = position;
|
||||
|
||||
// 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));
|
||||
if (glareSize != 0.0f)
|
||||
glareSize = std::max(glareSize, pointSize * discSizeInPixels / scale * 3.0f);
|
||||
|
||||
enableDepthTest();
|
||||
disableDepthMask();
|
||||
|
||||
bool useSprites = starStyle != PointStars;
|
||||
if (useSprites)
|
||||
if (starStyle != PointStars)
|
||||
gaussianDiscTex->bind();
|
||||
|
||||
if (pointSize > gl::maxPointSize)
|
||||
renderLargePoint(*this, center, {color, alpha}, pointSize, mvp);
|
||||
renderLargePoint(*this, position, {color, alpha}, pointSize, mvp);
|
||||
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
|
||||
// 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.
|
||||
if (useHalos && glareAlpha > 0.0f)
|
||||
{
|
||||
Eigen::Vector3f center = calculateQuadCenter(m_cameraOrientation, position, radius);
|
||||
gaussianGlareTex->bind();
|
||||
if (glareSize > gl::maxPointSize)
|
||||
renderLargePoint(*this, center, {color, glareAlpha}, glareSize, mvp);
|
||||
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;
|
||||
scaleFactors = obj.radius * obj.semiAxes;
|
||||
ringsScaleFactor = obj.radius * obj.semiAxes.maxCoeff();
|
||||
ri.pointScale = 2.0f * obj.radius / pixelSize * screenDpi / 96.0f;
|
||||
ri.pointScale = 2.0f * obj.radius / pixelSize;
|
||||
}
|
||||
else
|
||||
{
|
||||
geometryScale = obj.geometryScale;
|
||||
scaleFactors = Vector3f::Constant(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
|
||||
Affine3f transform = Translation3f(pos) * obj.orientation.conjugate();
|
||||
|
@ -3317,7 +3301,6 @@ void Renderer::renderPlanet(Body& body,
|
|||
renderObjectAsPoint(pos,
|
||||
body.getRadius(),
|
||||
appMag,
|
||||
faintestMag,
|
||||
discSizeInPixels,
|
||||
body.getSurface().color,
|
||||
false, false, m);
|
||||
|
@ -3396,7 +3379,6 @@ void Renderer::renderStar(const Star& star,
|
|||
renderObjectAsPoint(pos,
|
||||
star.getRadius(),
|
||||
appMag,
|
||||
faintestMag,
|
||||
discSizeInPixels,
|
||||
color,
|
||||
star.hasCorona(), true,
|
||||
|
@ -4371,11 +4353,7 @@ void Renderer::renderPointStars(const StarDatabase& starDB,
|
|||
starRenderer.cosFOV = (float) cos(degToRad(calcMaxFOV(fov, getAspectRatio())) / 2.0f);
|
||||
|
||||
starRenderer.pixelSize = pixelSize;
|
||||
starRenderer.brightnessScale = brightnessScale * corrFac;
|
||||
starRenderer.brightnessBias = brightnessBias;
|
||||
starRenderer.faintestMag = faintestMag;
|
||||
starRenderer.faintestMagNight = faintestMagNight;
|
||||
starRenderer.saturationMag = saturationMag;
|
||||
starRenderer.distanceLimit = distanceLimit;
|
||||
starRenderer.labelMode = labelMode;
|
||||
starRenderer.SolarSystemMaxDistance = SolarSystemMaxDistance;
|
||||
|
@ -4384,18 +4362,6 @@ void Renderer::renderPointStars(const StarDatabase& starDB,
|
|||
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.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;
|
||||
|
||||
gaussianDiscTex->bind();
|
||||
|
@ -4455,17 +4421,11 @@ void Renderer::renderDeepSkyObjects(const Universe& universe,
|
|||
dsoRenderer.orientationMatrix= observer.getOrientationf().conjugate().toRotationMatrix();
|
||||
dsoRenderer.observer = &observer;
|
||||
dsoRenderer.obsPos = obsPos;
|
||||
dsoRenderer.viewNormal = observer.getOrientationf().conjugate() * -Vector3f::UnitZ();
|
||||
dsoRenderer.fov = fov;
|
||||
// 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.brightnessScale = brightnessScale * corrFac;
|
||||
dsoRenderer.brightnessBias = brightnessBias;
|
||||
dsoRenderer.avgAbsMag = dsoDB->getAverageAbsoluteMagnitude();
|
||||
dsoRenderer.faintestMag = faintestMag;
|
||||
dsoRenderer.faintestMagNight = faintestMagNight;
|
||||
dsoRenderer.saturationMag = saturationMag;
|
||||
dsoRenderer.renderFlags = renderFlags;
|
||||
dsoRenderer.labelMode = labelMode;
|
||||
dsoRenderer.wWidth = windowWidth;
|
||||
|
@ -5988,6 +5948,8 @@ Renderer::renderSolarSystemObjects(const Observer &observer,
|
|||
proj = Perspective(fov, aspectRatio, nearPlaneDistance, farPlaneDistance);
|
||||
Matrices m = { &proj, &m_modelMatrix };
|
||||
|
||||
setCurrentProjectionMatrix(proj);
|
||||
|
||||
Frustum intervalFrustum(degToRad(fov),
|
||||
aspectRatio,
|
||||
nearPlaneDistance,
|
||||
|
@ -6050,6 +6012,18 @@ Renderer::renderSolarSystemObjects(const Observer &observer,
|
|||
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
|
||||
enableSmoothLines();
|
||||
annotation = renderSortedAnnotations(annotation,
|
||||
|
@ -6062,4 +6036,5 @@ Renderer::renderSolarSystemObjects(const Observer &observer,
|
|||
|
||||
// reset the depth range
|
||||
glDepthRange(0, 1);
|
||||
setDefaultProjectionMatrix();
|
||||
}
|
||||
|
|
|
@ -318,10 +318,12 @@ class Renderer
|
|||
{
|
||||
return m_modelMatrix;
|
||||
}
|
||||
|
||||
const Eigen::Matrix4f& getProjectionMatrix() const
|
||||
{
|
||||
return m_projMatrix;
|
||||
}
|
||||
|
||||
const Eigen::Matrix4f& getOrthoProjectionMatrix() const
|
||||
{
|
||||
return m_orthoProjMatrix;
|
||||
|
@ -337,6 +339,11 @@ class Renderer
|
|||
m_modelViewPtr = &m;
|
||||
}
|
||||
|
||||
void setDefaultModelViewMatrix()
|
||||
{
|
||||
m_modelViewPtr = &m_modelMatrix;
|
||||
}
|
||||
|
||||
const Eigen::Matrix4f& getCurrentProjectionMatrix() const
|
||||
{
|
||||
return *m_projectionPtr;
|
||||
|
@ -347,6 +354,11 @@ class Renderer
|
|||
m_projectionPtr = &m;
|
||||
}
|
||||
|
||||
void setDefaultProjectionMatrix()
|
||||
{
|
||||
m_projectionPtr = &m_projMatrix;
|
||||
}
|
||||
|
||||
void setStarStyle(StarStyle);
|
||||
StarStyle getStarStyle() const;
|
||||
void setResolution(unsigned int resolution);
|
||||
|
@ -618,10 +630,16 @@ class Renderer
|
|||
float discSizeInPixels,
|
||||
const Matrices&);
|
||||
|
||||
void calculatePointSize(float appMag,
|
||||
float size,
|
||||
float &discSize,
|
||||
float &alpha,
|
||||
float &glareSize,
|
||||
float &glareAlpha) const;
|
||||
|
||||
void renderObjectAsPoint(const Eigen::Vector3f& center,
|
||||
float radius,
|
||||
float appMag,
|
||||
float _faintestMag,
|
||||
float discSizeInPixels,
|
||||
const Color& color,
|
||||
bool useHalos,
|
||||
|
@ -840,6 +858,9 @@ class Renderer
|
|||
|
||||
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
|
||||
public:
|
||||
celestia::MarkerRepresentation mountainRep;
|
||||
|
@ -897,6 +918,8 @@ class Renderer
|
|||
static Color EclipticColor;
|
||||
|
||||
static Color SelectionCursorColor;
|
||||
|
||||
friend class PointStarRenderer;
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -32,6 +32,7 @@
|
|||
#include "renderglsl.h"
|
||||
#include "renderinfo.h"
|
||||
#include "shadermanager.h"
|
||||
#include "shadowmap.h" // GL_ONLY_SHADOWS definition
|
||||
#include "texture.h"
|
||||
#include "vecgl.h"
|
||||
|
||||
|
|
|
@ -387,7 +387,7 @@ static float rotperiod_M[3][10] =
|
|||
|
||||
|
||||
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] = {
|
||||
|
|
|
@ -17,59 +17,43 @@
|
|||
using namespace Eigen;
|
||||
using namespace std;
|
||||
|
||||
|
||||
// TODO: More of the functions in this module should be converted to
|
||||
// methods of the StarBrowser class.
|
||||
|
||||
struct CloserStarPredicate
|
||||
{
|
||||
Vector3f pos;
|
||||
bool operator()(const Star* star0, const Star* star1) const
|
||||
{
|
||||
Vector3f p0 = star0->getPosition();
|
||||
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());
|
||||
return (pos - star0->getPosition()).squaredNorm() < (pos - star1->getPosition()).squaredNorm();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
struct BrighterStarPredicate
|
||||
{
|
||||
Vector3f pos;
|
||||
UniversalCoord ucPos;
|
||||
bool operator()(const Star* star0, const Star* star1) const
|
||||
{
|
||||
Vector3f p0 = star0->getPosition();
|
||||
Vector3f p1 = star1->getPosition();
|
||||
Vector3f v0 = p0 * 1.0e6f - pos;
|
||||
Vector3f v1 = p1 * 1.0e6f - pos;
|
||||
float d0 = v0.norm();
|
||||
float d1 = v1.norm();
|
||||
float d0 = (pos - star0->getPosition()).norm();
|
||||
float d1 = (pos - star1->getPosition()).norm();
|
||||
|
||||
return (star0->getApparentMagnitude(d0) <
|
||||
star1->getApparentMagnitude(d1));
|
||||
// If the stars are closer than one light year, use
|
||||
// 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
|
||||
{
|
||||
bool operator()(const Star* star0, const Star* star1) const
|
||||
{
|
||||
return (star0->getAbsoluteMagnitude() <
|
||||
star1->getAbsoluteMagnitude());
|
||||
return star0->getAbsoluteMagnitude() < star1->getAbsoluteMagnitude();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
struct SolarSystemPredicate
|
||||
{
|
||||
Vector3f pos;
|
||||
|
@ -85,11 +69,7 @@ struct SolarSystemPredicate
|
|||
bool hasPlanets1 = (iter != solarSystems->end());
|
||||
if (hasPlanets1 == hasPlanets0)
|
||||
{
|
||||
Vector3f p0 = star0->getPosition();
|
||||
Vector3f p1 = star1->getPosition();
|
||||
Vector3f v0 = p0 * 1.0e6f - pos;
|
||||
Vector3f v1 = p1 * 1.0e6f - pos;
|
||||
return (v0.squaredNorm() < v1.squaredNorm());
|
||||
return ((pos - star0->getPosition()).squaredNorm() < (pos - star1->getPosition()).squaredNorm());
|
||||
}
|
||||
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
|
||||
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)
|
||||
{
|
||||
return sc0.packV2() < sc1.packV2();
|
||||
|
@ -273,6 +209,7 @@ enum ParseState
|
|||
LumClassVState,
|
||||
LumClassIdashState,
|
||||
LumClassIaState,
|
||||
LumClassIdashaState,
|
||||
WDTypeState,
|
||||
WDExtendedTypeState,
|
||||
WDSubclassState,
|
||||
|
@ -482,6 +419,8 @@ StellarClass::parse(const string& st)
|
|||
case 'V':
|
||||
state = LumClassVState;
|
||||
break;
|
||||
case ' ':
|
||||
break;
|
||||
default:
|
||||
state = EndState;
|
||||
break;
|
||||
|
@ -535,7 +474,8 @@ StellarClass::parse(const string& st)
|
|||
switch (c)
|
||||
{
|
||||
case 'a':
|
||||
state = LumClassIaState;
|
||||
state = LumClassIdashaState;
|
||||
i++;
|
||||
break;
|
||||
case 'b':
|
||||
lumClass = StellarClass::Lum_Ib;
|
||||
|
@ -549,6 +489,24 @@ StellarClass::parse(const string& st)
|
|||
break;
|
||||
|
||||
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)
|
||||
{
|
||||
case '0':
|
||||
|
|
|
@ -35,9 +35,9 @@ public:
|
|||
Spectral_G = 4,
|
||||
Spectral_K = 5,
|
||||
Spectral_M = 6,
|
||||
Spectral_R = 7, // superceded by class C
|
||||
Spectral_R = 7, // superseded by class C
|
||||
Spectral_S = 8,
|
||||
Spectral_N = 9, // superceded by class C
|
||||
Spectral_N = 9, // superseded by class C
|
||||
Spectral_WC = 10,
|
||||
Spectral_WN = 11,
|
||||
Spectral_WO = 12,
|
||||
|
@ -98,8 +98,6 @@ public:
|
|||
Color getApparentColor() const;
|
||||
Color getApparentColor(StellarClass::SpectralClass sc) const;
|
||||
|
||||
std::string str() const;
|
||||
|
||||
static StellarClass parse(const std::string&);
|
||||
|
||||
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' . . .
|
||||
// Useful for organizing a list of stars by spectral class.
|
||||
bool operator<(const StellarClass& sc0, const StellarClass& sc1);
|
||||
|
|
|
@ -80,6 +80,10 @@ if(ENABLE_FFMPEG)
|
|||
target_link_libraries(celestia ${FFMPEG_LIBRARIES})
|
||||
endif()
|
||||
|
||||
if (HAVE_MESHOPTIMIZER)
|
||||
target_link_libraries(celestia meshoptimizer::meshoptimizer)
|
||||
endif()
|
||||
|
||||
install(TARGETS celestia LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} NAMELINK_SKIP)
|
||||
|
||||
add_subdirectory(glut)
|
||||
|
|
|
@ -4053,14 +4053,10 @@ bool CelestiaCore::initRenderer()
|
|||
|
||||
if (font == nullptr)
|
||||
cout << _("Error loading font; text will not be visible.\n");
|
||||
else
|
||||
font->buildTexture();
|
||||
|
||||
if (!config->titleFont.empty())
|
||||
titleFont = LoadFontHelper(renderer, config->titleFont);
|
||||
if (titleFont != nullptr)
|
||||
titleFont->buildTexture();
|
||||
else
|
||||
if (titleFont == nullptr)
|
||||
titleFont = font;
|
||||
|
||||
// Set up the overlay
|
||||
|
@ -4074,15 +4070,7 @@ bool CelestiaCore::initRenderer()
|
|||
else
|
||||
{
|
||||
auto labelFont = LoadFontHelper(renderer, config->labelFont);
|
||||
if (labelFont == nullptr)
|
||||
{
|
||||
renderer->setFont(Renderer::FontNormal, font);
|
||||
}
|
||||
else
|
||||
{
|
||||
labelFont->buildTexture();
|
||||
renderer->setFont(Renderer::FontNormal, labelFont);
|
||||
}
|
||||
renderer->setFont(Renderer::FontNormal, labelFont == nullptr ? font : labelFont);
|
||||
}
|
||||
|
||||
renderer->setFont(Renderer::FontLarge, titleFont);
|
||||
|
@ -4286,26 +4274,34 @@ CelestiaCore::TextDisplayHandler* CelestiaCore::getTextDisplayHandler() const
|
|||
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 (font != nullptr)
|
||||
font->buildTexture();
|
||||
if (auto f = LoadTextureFont(renderer, fontPath, collectionIndex, fontSize); f != nullptr)
|
||||
{
|
||||
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 (titleFont != nullptr)
|
||||
titleFont->buildTexture();
|
||||
if (auto f = LoadTextureFont(renderer, fontPath, collectionIndex, fontSize); f != nullptr)
|
||||
{
|
||||
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 (f != nullptr)
|
||||
f->buildTexture();
|
||||
renderer->setFont(fontStyle, f);
|
||||
if (auto f = LoadTextureFont(renderer, fontPath, collectionIndex, fontSize); f != nullptr)
|
||||
{
|
||||
renderer->setFont(fontStyle, f);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void CelestiaCore::clearFonts()
|
||||
|
|
|
@ -368,9 +368,9 @@ class CelestiaCore // : public Watchable<CelestiaCore>
|
|||
void setTextDisplayHandler(TextDisplayHandler*);
|
||||
TextDisplayHandler* getTextDisplayHandler() const;
|
||||
|
||||
void setFont(const fs::path& fontPath, int collectionIndex, int fontSize);
|
||||
void setTitleFont(const fs::path& fontPath, int collectionIndex, int fontSize);
|
||||
void setRendererFont(const fs::path& fontPath, int collectionIndex, int fontSize, Renderer::FontStyle fontStyle);
|
||||
bool setFont(const fs::path& fontPath, int collectionIndex, int fontSize);
|
||||
bool setTitleFont(const fs::path& fontPath, int collectionIndex, int fontSize);
|
||||
bool setRendererFont(const fs::path& fontPath, int collectionIndex, int fontSize, Renderer::FontStyle fontStyle);
|
||||
void clearFonts();
|
||||
|
||||
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)
|
||||
{
|
||||
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
|
||||
* 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)
|
||||
{
|
||||
|
@ -1294,6 +1299,7 @@ void resyncRenderActions(AppData* app)
|
|||
case Renderer::ShowAtmospheres: actionName = "RenderAtmospheres"; break;
|
||||
case Renderer::ShowSmoothLines: actionName = "RenderAA"; break;
|
||||
case Renderer::ShowEclipseShadows: actionName = "RenderEclipseShadows"; break;
|
||||
case Renderer::ShowPlanetRings: actionName = "RenderPlanetRings"; break;
|
||||
case Renderer::ShowRingShadows: actionName = "RenderRingShadows"; break;
|
||||
case Renderer::ShowBoundaries: actionName = "RenderConstellationBoundaries"; break;
|
||||
case Renderer::ShowAutoMag: actionName = "RenderAutoMagnitude"; break;
|
||||
|
@ -1317,7 +1323,7 @@ void resyncRenderActions(AppData* app)
|
|||
action = gtk_action_group_get_action(app->agRender, actionName);
|
||||
|
||||
/* 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 actionRenderComets(GtkToggleAction*, AppData*);
|
||||
void actionRenderSpacecrafts(GtkToggleAction*, AppData*);
|
||||
void actionRenderPlanetRings(GtkToggleAction*, AppData*);
|
||||
void actionRenderRingShadows(GtkToggleAction*, AppData*);
|
||||
void actionRenderStars(GtkToggleAction*, AppData*);
|
||||
|
||||
|
|
|
@ -58,6 +58,7 @@
|
|||
<menuitem action='RenderAsteroids'/>
|
||||
<menuitem action='RenderComets'/>
|
||||
<menuitem action='RenderSpacecrafts'/>
|
||||
<menuitem action='RenderPlanetRings'/>
|
||||
<menuitem action='RenderRingShadows'/>
|
||||
<menuitem action='RenderStars'/>
|
||||
</menu>
|
||||
|
|
|
@ -149,9 +149,15 @@ static void addPlanetarySystemToTree(const PlanetarySystem* sys, GtkTreeStore* s
|
|||
case Body::Planet:
|
||||
type = "Planet";
|
||||
break;
|
||||
case Body::DwarfPlanet:
|
||||
type = "Dwarf Planet";
|
||||
break;
|
||||
case Body::Moon:
|
||||
type = "Moon";
|
||||
break;
|
||||
case Body::MinorMoon:
|
||||
type = "Minor Moon";
|
||||
break;
|
||||
case Body::Asteroid:
|
||||
type = "Asteroid";
|
||||
break;
|
||||
|
|
|
@ -155,6 +155,7 @@ void applySettingsFileMain(AppData* app, GKeyFile* file)
|
|||
getFlag64(file, &rf, Renderer::ShowAtmospheres, "RenderFlags", "atmospheres", &errors);
|
||||
getFlag64(file, &rf, Renderer::ShowSmoothLines, "RenderFlags", "smoothLines", &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::ShowBoundaries, "RenderFlags", "boundaries", &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", "smoothLines", (rf & Renderer::ShowSmoothLines) != 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", "boundaries", (rf & Renderer::ShowBoundaries) != 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 },
|
||||
{ "RenderAsteroids", NULL, "Asteroids", NULL, NULL, G_CALLBACK(actionRenderAsteroids), 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 },
|
||||
{ "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")
|
||||
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
|
||||
qtappwin.cpp
|
||||
|
@ -58,7 +62,11 @@ set(CMAKE_AUTOMOC ON)
|
|||
set(CMAKE_AUTOUIC ON)
|
||||
# Find includes in corresponding build directories
|
||||
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)
|
||||
set (RES celestia.rc)
|
||||
|
@ -66,7 +74,11 @@ endif()
|
|||
|
||||
add_executable(celestia-qt WIN32 ${QT_SOURCES} ${RC_SRC} ${RES})
|
||||
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)
|
||||
set_property(TARGET celestia-qt APPEND_STRING PROPERTY LINK_FLAGS " -framework CoreFoundation")
|
||||
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.
|
||||
// TODO: Make this settable via the GUI
|
||||
QGLFormat glformat = QGLFormat::defaultFormat();
|
||||
QSurfaceFormat glformat = QSurfaceFormat::defaultFormat();
|
||||
if (m_appCore->getConfig()->aaSamples > 1)
|
||||
{
|
||||
glformat.setSampleBuffers(true);
|
||||
glformat.setSamples(m_appCore->getConfig()->aaSamples);
|
||||
QGLFormat::setDefaultFormat(glformat);
|
||||
QSurfaceFormat::setDefaultFormat(glformat);
|
||||
}
|
||||
|
||||
glWidget = new CelestiaGlWidget(nullptr, "Celestia", m_appCore);
|
||||
|
@ -495,6 +494,7 @@ void CelestiaAppWindow::writeSettings()
|
|||
QSettings settings;
|
||||
|
||||
settings.beginGroup("MainWindow");
|
||||
#ifndef _WIN32
|
||||
if (isFullScreen())
|
||||
{
|
||||
// Save the normal size, not the fullscreen size; fullscreen will
|
||||
|
@ -503,6 +503,7 @@ void CelestiaAppWindow::writeSettings()
|
|||
settings.setValue("Pos", normalGeometry().topLeft());
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
settings.setValue("Size", size());
|
||||
settings.setValue("Pos", pos());
|
||||
|
@ -591,7 +592,7 @@ void CelestiaAppWindow::saveBookmarks()
|
|||
void CelestiaAppWindow::celestia_tick()
|
||||
{
|
||||
m_appCore->tick();
|
||||
glWidget->updateGL();
|
||||
glWidget->update();
|
||||
}
|
||||
|
||||
|
||||
|
@ -621,8 +622,8 @@ void CelestiaAppWindow::slotGrabImage()
|
|||
|
||||
if (!saveAsName.isEmpty())
|
||||
{
|
||||
m_appCore->saveScreenShot(saveAsName.toStdString());
|
||||
settings.setValue("GrabImageDir", QFileInfo(saveAsName).absolutePath());
|
||||
QImage grabbedImage = glWidget->grabFramebuffer();
|
||||
grabbedImage.save(saveAsName);
|
||||
}
|
||||
settings.endGroup();
|
||||
}
|
||||
|
@ -750,17 +751,9 @@ static QImage::Format toQFormat(PixelFormat format)
|
|||
|
||||
void CelestiaAppWindow::slotCopyImage()
|
||||
{
|
||||
//glWidget->repaint();
|
||||
std::array<int, 4> viewport;
|
||||
celestia::PixelFormat format;
|
||||
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"));
|
||||
}
|
||||
QImage grabbedImage = glWidget->grabFramebuffer();
|
||||
QApplication::clipboard()->setImage(grabbedImage);
|
||||
m_appCore->flash(_("Captured screen shot to clipboard"));
|
||||
}
|
||||
|
||||
|
||||
|
@ -944,7 +937,13 @@ void CelestiaAppWindow::slotShowTimeDialog()
|
|||
|
||||
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())
|
||||
#endif
|
||||
{
|
||||
switchToNormal();
|
||||
}
|
||||
|
@ -966,7 +965,13 @@ void CelestiaAppWindow::switchToNormal()
|
|||
{
|
||||
// Switch to window
|
||||
menuBar()->setFixedHeight(menuBar()->sizeHint().height());
|
||||
#ifdef _WIN32
|
||||
Qt::WindowFlags flags = windowFlags().setFlag(Qt::FramelessWindowHint, false);
|
||||
setWindowFlags(flags);
|
||||
show();
|
||||
#else
|
||||
showNormal();
|
||||
#endif
|
||||
|
||||
QSettings settings;
|
||||
settings.beginGroup("MainWindow");
|
||||
|
@ -994,7 +999,31 @@ void CelestiaAppWindow::switchToFullscreen()
|
|||
timeToolBar->setVisible(false);
|
||||
guidesToolBar->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();
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
@ -1030,7 +1059,7 @@ void CelestiaAppWindow::slotAddBookmark()
|
|||
appState.captureState();
|
||||
|
||||
// Capture the current frame buffer to use as a bookmark icon.
|
||||
QImage grabbedImage = glWidget->grabFrameBuffer();
|
||||
QImage grabbedImage = glWidget->grabFramebuffer();
|
||||
int width = grabbedImage.width();
|
||||
int height = grabbedImage.height();
|
||||
|
||||
|
@ -1593,7 +1622,7 @@ void CelestiaAppWindow::setCustomFPS()
|
|||
|
||||
void CelestiaAppWindow::requestContextMenu(float x, float y, Selection sel)
|
||||
{
|
||||
float scale = devicePixelRatioF();
|
||||
qreal scale = devicePixelRatioF();
|
||||
SelectionPopup* menu = new SelectionPopup(sel, m_appCore, this);
|
||||
connect(menu, SIGNAL(selectionInfoRequested(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) :
|
||||
QGLWidget(parent)
|
||||
QOpenGLWidget(parent)
|
||||
{
|
||||
setFocusPolicy(Qt::ClickFocus);
|
||||
|
||||
|
@ -96,7 +96,7 @@ void CelestiaGlWidget::initializeGL()
|
|||
using namespace celestia;
|
||||
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);
|
||||
}
|
||||
|
||||
|
@ -133,15 +133,18 @@ void CelestiaGlWidget::initializeGL()
|
|||
|
||||
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)
|
||||
{
|
||||
float scale = devicePixelRatioF();
|
||||
int x = (int)(m->x() * scale);
|
||||
int y = (int)(m->y() * scale);
|
||||
qreal scale = devicePixelRatioF();
|
||||
auto x = static_cast<int>(m->x() * scale);
|
||||
auto y = static_cast<int>(m->y() * scale);
|
||||
|
||||
int buttons = 0;
|
||||
if (m->buttons() & LeftButton)
|
||||
|
@ -198,9 +201,9 @@ void CelestiaGlWidget::mouseMoveEvent(QMouseEvent* m)
|
|||
|
||||
void CelestiaGlWidget::mousePressEvent( QMouseEvent* m )
|
||||
{
|
||||
float scale = devicePixelRatioF();
|
||||
int x = (int)(m->x() * scale);
|
||||
int y = (int)(m->y() * scale);
|
||||
qreal scale = devicePixelRatioF();
|
||||
auto x = static_cast<int>(m->x() * scale);
|
||||
auto y = static_cast<int>(m->y() * scale);
|
||||
|
||||
if (m->button() == LeftButton)
|
||||
appCore->mouseButtonDown(x, y, CelestiaCore::LeftButton);
|
||||
|
@ -213,9 +216,9 @@ void CelestiaGlWidget::mousePressEvent( QMouseEvent* m )
|
|||
|
||||
void CelestiaGlWidget::mouseReleaseEvent( QMouseEvent* m )
|
||||
{
|
||||
float scale = devicePixelRatioF();
|
||||
int x = (int)(m->x() * scale);
|
||||
int y = (int)(m->y() * scale);
|
||||
qreal scale = devicePixelRatioF();
|
||||
auto x = static_cast<int>(m->x() * scale);
|
||||
auto y = static_cast<int>(m->y() * scale);
|
||||
|
||||
if (m->button() == LeftButton)
|
||||
{
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
#ifndef QTGLWIDGET_H
|
||||
#define QTGLWIDGET_H
|
||||
|
||||
#include <QGLWidget>
|
||||
#include <QOpenGLWidget>
|
||||
|
||||
#include "celestia/celestiacore.h"
|
||||
#include "celengine/simulation.h"
|
||||
|
@ -26,7 +26,7 @@
|
|||
*@author Christophe Teyssier
|
||||
*/
|
||||
|
||||
class CelestiaGlWidget : public QGLWidget, public CelestiaCore::CursorHandler
|
||||
class CelestiaGlWidget : public QOpenGLWidget, public CelestiaCore::CursorHandler
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
|
|
|
@ -28,7 +28,6 @@
|
|||
#include <QLibraryInfo>
|
||||
#include <vector>
|
||||
#include "qtappwin.h"
|
||||
#include <qtextcodec.h>
|
||||
#include <fmt/printf.h>
|
||||
|
||||
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 <cstring>
|
||||
#include <iostream>
|
||||
#include <memory>
|
||||
#include <string_view>
|
||||
#include <system_error>
|
||||
#include <fmt/printf.h>
|
||||
#include <celcompat/filesystem.h>
|
||||
#include <celengine/glsupport.h>
|
||||
#include <celutil/gettext.h>
|
||||
#include <celutil/tzutil.h>
|
||||
|
@ -13,8 +24,8 @@
|
|||
#else
|
||||
#include <SDL_opengl.h>
|
||||
#endif
|
||||
#include <unistd.h>
|
||||
#include <celestia/celestiacore.h>
|
||||
#include <celestia/url.h>
|
||||
|
||||
namespace celestia
|
||||
{
|
||||
|
@ -36,7 +47,7 @@ class SDL_Application
|
|||
{
|
||||
public:
|
||||
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_windowWidth { w },
|
||||
m_windowHeight { h }
|
||||
|
@ -44,13 +55,13 @@ class 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 initCelestiaCore();
|
||||
void run();
|
||||
const char* getError() const;
|
||||
std::string_view getError() const;
|
||||
|
||||
private:
|
||||
void display();
|
||||
|
@ -67,6 +78,9 @@ class SDL_Application
|
|||
|
||||
// aux functions
|
||||
void toggleFullscreen();
|
||||
void copyURL();
|
||||
void pasteURL();
|
||||
void configure() const;
|
||||
|
||||
// state variables
|
||||
std::string m_appName;
|
||||
|
@ -84,7 +98,7 @@ class 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)
|
||||
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_MINOR_VERSION, 0);
|
||||
#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()
|
||||
|
@ -132,7 +146,7 @@ SDL_Application::createOpenGLWindow()
|
|||
return true;
|
||||
}
|
||||
|
||||
const char*
|
||||
std::string_view
|
||||
SDL_Application::getError() const
|
||||
{
|
||||
return SDL_GetError();
|
||||
|
@ -154,11 +168,22 @@ SDL_Application::initCelestiaCore()
|
|||
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
|
||||
SDL_Application::run()
|
||||
{
|
||||
m_appCore->initRenderer();
|
||||
m_appCore->getRenderer()->setRenderFlags(Renderer::DefaultRenderFlags);
|
||||
configure();
|
||||
m_appCore->start();
|
||||
|
||||
std::string tzName;
|
||||
|
@ -294,8 +319,18 @@ SDL_Application::handleKeyPressEvent(const SDL_KeyboardEvent &event)
|
|||
int k = tolower(key);
|
||||
if (k >= 'a' && k <= 'z')
|
||||
{
|
||||
key = k + 1 - 'a';
|
||||
m_appCore->charEntered(key, mod);
|
||||
switch (k)
|
||||
{
|
||||
case 'c':
|
||||
copyURL();
|
||||
break;
|
||||
case 'v':
|
||||
pasteURL();
|
||||
break;
|
||||
default:
|
||||
key = k + 1 - 'a';
|
||||
m_appCore->charEntered(key, mod);
|
||||
}
|
||||
return;
|
||||
}
|
||||
mod |= CelestiaCore::ControlKey;
|
||||
|
@ -471,6 +506,29 @@ SDL_Application::toggleFullscreen()
|
|||
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
|
||||
|
@ -484,7 +542,8 @@ FatalError(const std::string &message)
|
|||
std::cerr << message << std::endl;
|
||||
}
|
||||
|
||||
void DumpGLInfo()
|
||||
void
|
||||
DumpGLInfo()
|
||||
{
|
||||
const char* s;
|
||||
s = reinterpret_cast<const char*>(glGetString(GL_VERSION));
|
||||
|
@ -504,10 +563,8 @@ void DumpGLInfo()
|
|||
std::cout << s << '\n';
|
||||
}
|
||||
|
||||
|
||||
using namespace celestia;
|
||||
|
||||
int main(int argc, char **argv)
|
||||
int
|
||||
sdlmain(int /* argc */, char ** /* argv */)
|
||||
{
|
||||
setlocale(LC_ALL, "");
|
||||
setlocale(LC_NUMERIC, "C");
|
||||
|
@ -515,10 +572,16 @@ int main(int argc, char **argv)
|
|||
bind_textdomain_codeset(PACKAGE, "UTF-8");
|
||||
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",
|
||||
CONFIG_DATA_DIR));
|
||||
dataDir));
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -557,3 +620,10 @@ int main(int argc, char **argv)
|
|||
|
||||
return 0;
|
||||
}
|
||||
} // namespace
|
||||
|
||||
int
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
return celestia::sdlmain(argc, argv);
|
||||
}
|
||||
|
|
|
@ -39,6 +39,8 @@ set(WIN32_HEADERS
|
|||
winviewoptsdlg.h
|
||||
)
|
||||
|
||||
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} /MANIFEST:NO")
|
||||
|
||||
add_library(resources OBJECT res/celestia.rc)
|
||||
target_include_directories(resources PRIVATE "${CMAKE_SOURCE_DIR}/src/celestia/win32/res")
|
||||
set(RESOURCES $<TARGET_OBJECTS:resources>)
|
||||
|
|
|
@ -2,8 +2,10 @@
|
|||
//
|
||||
|
||||
#include "odmenu.h"
|
||||
#include "winuiutils.h"
|
||||
|
||||
using namespace std;
|
||||
using namespace celestia::win32;
|
||||
|
||||
ODMenu::ODMenu()
|
||||
{
|
||||
|
@ -38,14 +40,6 @@ ODMenu::ODMenu()
|
|||
if(SystemParametersInfo(SPI_GETNONCLIENTMETRICS, sizeof(NONCLIENTMETRICS), &ncms, 0))
|
||||
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
|
||||
m_hItemBackground = CreateSolidBrush(m_clrItemBackground);
|
||||
m_hIconBarBrush = CreateSolidBrush(m_clrIconBar);
|
||||
|
@ -86,6 +80,16 @@ bool ODMenu::Init(HWND hOwnerWnd, HMENU 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
|
||||
//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);
|
||||
}
|
||||
|
||||
void ODMenu::DrawIconBar(DRAWITEMSTRUCT* lpdis, ODMENUITEM& item)
|
||||
void ODMenu::DrawIconBar(HWND hWnd, DRAWITEMSTRUCT* lpdis, ODMENUITEM& item)
|
||||
{
|
||||
RECT rectBar;
|
||||
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
|
||||
if(item.hBitmap)
|
||||
{
|
||||
x = m_iconBarMargin;
|
||||
y = rectBar.top + ((rectBar.bottom - rectBar.top - 16) / 2);
|
||||
x = rectBar.left + m_iconBarMargin + m_iconWidth / 2;
|
||||
y = rectBar.top + (rectBar.bottom - rectBar.top) / 2;
|
||||
|
||||
if(lpdis->itemState & ODS_DISABLED || lpdis->itemState & ODS_GRAYED)
|
||||
{
|
||||
//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)
|
||||
{
|
||||
//Draw icon "raised"
|
||||
//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
|
||||
DrawTransparentBitmap(lpdis->hDC, item.hBitmap, x-1, y-1, m_clrTranparent);
|
||||
DrawTransparentBitmap(hWnd, lpdis->hDC, item.hBitmap, x-1, y-1, m_clrTranparent);
|
||||
}
|
||||
else
|
||||
{
|
||||
//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)
|
||||
|
@ -289,17 +293,17 @@ void ODMenu::DrawIconBar(DRAWITEMSTRUCT* lpdis, ODMENUITEM& item)
|
|||
hPrevBrush = (HBRUSH)SelectObject(lpdis->hDC, m_hCheckMarkBackgroundBrush);
|
||||
hPrevPen = (HPEN)SelectObject(lpdis->hDC, m_hSelectionOutlinePen);
|
||||
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.bottom = rect.top + m_iconHeight;
|
||||
Rectangle(lpdis->hDC, rect.left, rect.top, rect.right, rect.bottom);
|
||||
SelectObject(lpdis->hDC, hPrevBrush);
|
||||
SelectObject(lpdis->hDC, hPrevPen);
|
||||
|
||||
//Draw check mark
|
||||
x = (m_iconWidth + 2*m_iconBarMargin - 6) / 2;
|
||||
y = rectBar.top + ((rectBar.bottom - rectBar.top - 7) / 2) + 1;
|
||||
DrawCheckMark(lpdis->hDC, x, y, true);
|
||||
// Draw check mark
|
||||
x = rectBar.left + m_iconBarMargin + m_iconWidth / 2;
|
||||
y = rectBar.top + (rectBar.bottom - rectBar.top) / 2;
|
||||
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,
|
||||
short yStart, COLORREF cTransparentColor,
|
||||
void ODMenu::DrawTransparentBitmap(HWND hWnd, HDC hDC, HBITMAP hBitmap, short centerX,
|
||||
short centerY, COLORREF cTransparentColor,
|
||||
bitmapType eType)
|
||||
{
|
||||
BITMAP bm;
|
||||
|
@ -333,8 +337,6 @@ void ODMenu::DrawTransparentBitmap(HDC hDC, HBITMAP hBitmap, short xStart,
|
|||
POINT ptSize;
|
||||
HBRUSH hOldBrush;
|
||||
|
||||
BOOL bRC;
|
||||
|
||||
hdcTemp = CreateCompatibleDC(hDC);
|
||||
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
|
||||
// to logical points
|
||||
|
||||
auto iconWidth = DpToPixels(ptSize.x, hWnd);
|
||||
auto iconHeight = DpToPixels(ptSize.y, hWnd);
|
||||
|
||||
// Create some DCs to hold temporary data.
|
||||
hdcBack = CreateCompatibleDC(hDC);
|
||||
hdcObject = CreateCompatibleDC(hDC);
|
||||
|
@ -359,7 +364,7 @@ void ODMenu::DrawTransparentBitmap(HDC hDC, HBITMAP hBitmap, short xStart,
|
|||
// Monochrome DC
|
||||
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);
|
||||
|
||||
// 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));
|
||||
|
||||
// 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
|
||||
// (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
|
||||
// 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.
|
||||
SetBkColor(hdcTemp, cColor);
|
||||
|
||||
// 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.
|
||||
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.
|
||||
// hdcMem then contains the background color of hDC only in the places
|
||||
// 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)
|
||||
{
|
||||
|
@ -407,7 +412,7 @@ void ODMenu::DrawTransparentBitmap(HDC hDC, HBITMAP hBitmap, short xStart,
|
|||
|
||||
// XOR the bitmap with the background on the destination DC.
|
||||
// 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)
|
||||
{
|
||||
|
@ -415,11 +420,11 @@ void ODMenu::DrawTransparentBitmap(HDC hDC, HBITMAP hBitmap, short xStart,
|
|||
hOldBrush = (HBRUSH)SelectObject(hdcTemp, m_hIconShadowBrush);
|
||||
|
||||
//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.
|
||||
// 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
|
||||
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.
|
||||
// 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)
|
||||
{
|
||||
|
@ -479,14 +484,14 @@ void ODMenu::DrawTransparentBitmap(HDC hDC, HBITMAP hBitmap, short xStart,
|
|||
|
||||
// XOR the bitmap with the background on the destination DC.
|
||||
// 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.
|
||||
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.
|
||||
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.
|
||||
DeleteObject(SelectObject(hdcBack, bmBackOld));
|
||||
|
@ -502,7 +507,7 @@ void ODMenu::DrawTransparentBitmap(HDC hDC, HBITMAP hBitmap, short xStart,
|
|||
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;
|
||||
int dp = 0;
|
||||
|
@ -510,30 +515,26 @@ void ODMenu::DrawCheckMark(HDC hDC, short x, short y, bool bNarrow)
|
|||
if(bNarrow)
|
||||
dp = 1;
|
||||
|
||||
//Select check mark pen
|
||||
// Select check mark pen
|
||||
hOldPen = (HPEN)SelectObject(hDC, m_hCheckMarkPen);
|
||||
|
||||
//Draw the check mark
|
||||
MoveToEx(hDC, x, y + 2, NULL);
|
||||
LineTo(hDC, x, y + 5 - dp);
|
||||
// Draw the check mark
|
||||
auto minLeftX = centerX - DpToPixels(4, hWnd);
|
||||
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);
|
||||
LineTo(hDC, x + 1, y + 6 - dp);
|
||||
|
||||
MoveToEx(hDC, x + 2, y + 4, NULL);
|
||||
LineTo(hDC, x + 2, y + 7 - dp);
|
||||
|
||||
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);
|
||||
auto maxRightX = centerX + DpToPixels(4, hWnd);
|
||||
for (; x < maxRightX; x += 1, y -= 1)
|
||||
{
|
||||
MoveToEx(hDC, x, y, NULL);
|
||||
LineTo(hDC, x, y + DpToPixels(3 - dp, hWnd));
|
||||
}
|
||||
|
||||
//Restore original DC pen
|
||||
SelectObject(hDC, hOldPen);
|
||||
|
@ -622,6 +623,7 @@ void ODMenu::MeasureItem(HWND hWnd, LPARAM lParam)
|
|||
DrawText(hDC, item.rawText.c_str(), item.rawText.length(), &rect,
|
||||
DT_SINGLELINE | DT_LEFT | DT_VCENTER | DT_CALCRECT);
|
||||
lpmis->itemWidth = rect.right - rect.left;
|
||||
lpmis->itemHeight = m_iconHeight;
|
||||
|
||||
if(!item.topMost)
|
||||
{
|
||||
|
@ -727,7 +729,7 @@ void ODMenu::DrawItem(HWND hWnd, LPARAM lParam)
|
|||
}
|
||||
|
||||
//Draw the left icon bar
|
||||
DrawIconBar(lpdis, item);
|
||||
DrawIconBar(hWnd, lpdis, item);
|
||||
|
||||
//Draw selection outline if drawing a selected item
|
||||
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 GenerateDisplayText(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 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);
|
||||
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 DarkenColor(COLORREF col, double factor);
|
||||
COLORREF AverageColor(COLORREF col1, COLORREF col2, double weight1=0.5);
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
<?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
|
||||
version="1.0.0.0"
|
||||
processorArchitecture="X86"
|
||||
processorArchitecture="*"
|
||||
name="Celestia"
|
||||
type="win32"
|
||||
/>
|
||||
|
@ -19,4 +19,10 @@
|
|||
/>
|
||||
</dependentAssembly>
|
||||
</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
|
||||
#endif
|
||||
|
||||
CREATEPROCESS_MANIFEST_RESOURCE_ID RT_MANIFEST "celestia.exe.manifest"
|
||||
|
||||
//
|
||||
// Bitmap resources
|
||||
//
|
||||
|
|
|
@ -29,11 +29,10 @@
|
|||
using namespace Eigen;
|
||||
using namespace std;
|
||||
using namespace celmath;
|
||||
using namespace celestia::win32;
|
||||
|
||||
static vector<Eclipse> eclipseList;
|
||||
|
||||
extern void SetMouseCursor(LPCTSTR lpCursor);
|
||||
|
||||
const char* MonthNames[12] =
|
||||
{
|
||||
"Jan", "Feb", "Mar", "Apr",
|
||||
|
@ -63,15 +62,15 @@ bool InitEclipseFinderColumns(HWND listView)
|
|||
string header4 = UTF8ToCurrentCP(_("Duration"));
|
||||
|
||||
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].cx = 65;
|
||||
columns[1].cx = DpToPixels(65, listView);
|
||||
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].cx = 55;
|
||||
columns[3].cx = DpToPixels(55, listView);
|
||||
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++)
|
||||
{
|
||||
|
|
|
@ -68,6 +68,7 @@
|
|||
using namespace celestia;
|
||||
using namespace celestia::util;
|
||||
using namespace std;
|
||||
using namespace celestia::win32;
|
||||
|
||||
typedef pair<int,string> IntStrPair;
|
||||
typedef vector<IntStrPair> IntStrPairVec;
|
||||
|
@ -988,7 +989,7 @@ BOOL APIENTRY AddBookmarkProc(HWND hDlg,
|
|||
if (strstr(text, ">>"))
|
||||
{
|
||||
//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,
|
||||
SWP_NOMOVE | SWP_NOZORDER);
|
||||
//Change text in button
|
||||
|
@ -3186,8 +3187,8 @@ int APIENTRY WinMain(HINSTANCE hInstance,
|
|||
LoadPreferencesFromRegistry(CelestiaRegKey, prefs);
|
||||
|
||||
// Adjust window dimensions for screen dimensions
|
||||
int screenWidth = GetSystemMetrics(SM_CXSCREEN);
|
||||
int screenHeight = GetSystemMetrics(SM_CYSCREEN);
|
||||
int screenWidth = GetSystemMetricsForWindow(SM_CXSCREEN, nullptr);
|
||||
int screenHeight = GetSystemMetricsForWindow(SM_CYSCREEN, nullptr);
|
||||
if (prefs.winWidth > screenWidth)
|
||||
prefs.winWidth = screenWidth;
|
||||
if (prefs.winHeight > screenHeight)
|
||||
|
@ -3386,6 +3387,8 @@ int APIENTRY WinMain(HINSTANCE hInstance,
|
|||
extern void RegisterDatePicker();
|
||||
RegisterDatePicker();
|
||||
|
||||
appCore->setScreenDpi(GetDPIForWindow(hWnd));
|
||||
|
||||
if (!appCore->initRenderer())
|
||||
{
|
||||
return 1;
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
// of the License, or (at your option) any later version.
|
||||
|
||||
#include "winsplash.h"
|
||||
#include "winuiutils.h"
|
||||
#include <celutil/gettext.h>
|
||||
#include <celutil/winutil.h>
|
||||
#include <string>
|
||||
|
@ -20,6 +21,7 @@
|
|||
|
||||
|
||||
using namespace std;
|
||||
using namespace celestia::win32;
|
||||
|
||||
|
||||
// Required for transparent Windows, but not present in VC6 headers. Only present
|
||||
|
@ -61,7 +63,9 @@ SplashWindow::SplashWindow(const string& _imageFileName) :
|
|||
hCompositionBitmap(0),
|
||||
useLayeredWindow(false),
|
||||
winWidth(640),
|
||||
winHeight(480)
|
||||
winHeight(480),
|
||||
imageWidth(0),
|
||||
imageHeight(0)
|
||||
{
|
||||
init();
|
||||
}
|
||||
|
@ -108,7 +112,7 @@ SplashWindow::paint(HDC hDC)
|
|||
HDC hMemDC = ::CreateCompatibleDC(hDC);
|
||||
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);
|
||||
::DeleteDC(hMemDC);
|
||||
|
@ -126,10 +130,10 @@ SplashWindow::paint(HDC hDC)
|
|||
|
||||
// Show the message text
|
||||
RECT r;
|
||||
r.left = rect.right - 250;
|
||||
r.top = rect.bottom - 70;
|
||||
r.left = rect.right - DpToPixels(250, hwnd);
|
||||
r.top = rect.bottom - DpToPixels(70, hwnd);
|
||||
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));
|
||||
SelectObject(hDC, hFont);
|
||||
|
@ -212,15 +216,18 @@ SplashWindow::createWindow()
|
|||
if (!RegisterClassEx(&wndclass))
|
||||
return NULL;
|
||||
|
||||
if (image != NULL)
|
||||
if (image != nullptr)
|
||||
{
|
||||
winWidth = image->getWidth();
|
||||
winHeight = image->getHeight();
|
||||
imageWidth = image->getWidth();
|
||||
imageHeight = image->getHeight();
|
||||
|
||||
winWidth = DpToPixels(imageWidth, nullptr);
|
||||
winHeight = DpToPixels(imageHeight, nullptr);
|
||||
}
|
||||
|
||||
// Create the application window centered in the middle of the screen
|
||||
DWORD nScrWidth = ::GetSystemMetrics(SM_CXFULLSCREEN);
|
||||
DWORD nScrHeight = ::GetSystemMetrics(SM_CYFULLSCREEN);
|
||||
DWORD nScrWidth = GetSystemMetricsForWindow(SM_CXFULLSCREEN, nullptr);
|
||||
DWORD nScrHeight = GetSystemMetricsForWindow(SM_CYFULLSCREEN, nullptr);
|
||||
|
||||
int x = (nScrWidth - winWidth) / 2;
|
||||
int y = (nScrHeight - winHeight) / 2;
|
||||
|
@ -304,7 +311,7 @@ SplashWindow::createBitmap()
|
|||
// layered window support.)
|
||||
if (hBitmap)
|
||||
{
|
||||
hCompositionBitmap = CreateCompatibleBitmap(hwndDC, image->getWidth(), image->getHeight());
|
||||
hCompositionBitmap = CreateCompatibleBitmap(hwndDC, winWidth, winHeight);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -43,4 +43,6 @@ private:
|
|||
std::string message;
|
||||
unsigned int winWidth;
|
||||
unsigned int winHeight;
|
||||
unsigned int imageWidth;
|
||||
unsigned int imageHeight;
|
||||
};
|
||||
|
|
|
@ -21,11 +21,11 @@
|
|||
#include <celmath/mathlib.h>
|
||||
#include "winstarbrowser.h"
|
||||
#include "res/resource.h"
|
||||
|
||||
extern void SetMouseCursor(LPCTSTR lpCursor);
|
||||
#include "winuiutils.h"
|
||||
|
||||
using namespace Eigen;
|
||||
using namespace std;
|
||||
using namespace celestia::win32;
|
||||
|
||||
static const int MinListStars = 10;
|
||||
static const int MaxListStars = 500;
|
||||
|
@ -49,7 +49,7 @@ bool InitStarBrowserColumns(HWND listView)
|
|||
|
||||
lvc.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT | LVCF_SUBITEM;
|
||||
lvc.fmt = LVCFMT_LEFT;
|
||||
lvc.cx = 60;
|
||||
lvc.cx = DpToPixels(60, listView);
|
||||
lvc.pszText = const_cast<char*>("");
|
||||
|
||||
int nColumns = sizeof(columns) / sizeof(columns[0]);
|
||||
|
@ -65,16 +65,16 @@ bool InitStarBrowserColumns(HWND listView)
|
|||
string header4 = UTF8ToCurrentCP(_("Type"));
|
||||
|
||||
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].fmt = LVCFMT_RIGHT;
|
||||
columns[1].cx = 115;
|
||||
columns[1].cx = DpToPixels(115, listView);
|
||||
columns[2].pszText = const_cast<char*>(header2.c_str());
|
||||
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].fmt = LVCFMT_RIGHT;
|
||||
columns[3].cx = 65;
|
||||
columns[3].cx = DpToPixels(65, listView);
|
||||
columns[4].pszText = const_cast<char*>(header4.c_str());
|
||||
|
||||
for (i = 0; i < nColumns; i++)
|
||||
|
|
|
@ -12,6 +12,34 @@
|
|||
|
||||
#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)
|
||||
{
|
||||
HCURSOR hNewCrsr;
|
||||
|
@ -53,3 +81,44 @@ void AddButtonDefaultStyle(HWND hWnd)
|
|||
::GetWindowLong(hWnd, GWL_STYLE) | BS_DEFPUSHBUTTON);
|
||||
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 <commctrl.h>
|
||||
|
||||
namespace celestia::win32
|
||||
{
|
||||
|
||||
void SetMouseCursor(LPCTSTR lpCursor);
|
||||
void CenterWindow(HWND hParent, HWND hWnd);
|
||||
void RemoveButtonDefaultStyle(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();
|
||||
|
||||
//Set checkboxes and radiobuttons
|
||||
SendDlgItemMessage(hDlg, IDC_SHOWATMOSPHERES, BM_SETCHECK,
|
||||
(renderFlags & Renderer::ShowAtmospheres)? BST_CHECKED:BST_UNCHECKED, 0);
|
||||
SendDlgItemMessage(hDlg, IDC_SHOWCELESTIALGRID, BM_SETCHECK,
|
||||
(renderFlags & Renderer::ShowCelestialSphere)? BST_CHECKED:BST_UNCHECKED, 0);
|
||||
SendDlgItemMessage(hDlg, IDC_SHOWHORIZONGRID, BM_SETCHECK,
|
||||
(renderFlags & Renderer::ShowHorizonGrid)? BST_CHECKED:BST_UNCHECKED, 0);
|
||||
SendDlgItemMessage(hDlg, IDC_SHOWGALACTICGRID, BM_SETCHECK,
|
||||
(renderFlags & Renderer::ShowGalacticGrid)? BST_CHECKED:BST_UNCHECKED, 0);
|
||||
SendDlgItemMessage(hDlg, IDC_SHOWECLIPTICGRID, BM_SETCHECK,
|
||||
(renderFlags & Renderer::ShowEclipticGrid)? BST_CHECKED:BST_UNCHECKED, 0);
|
||||
SendDlgItemMessage(hDlg, IDC_SHOWECLIPTIC, BM_SETCHECK,
|
||||
(renderFlags & Renderer::ShowEcliptic)? BST_CHECKED:BST_UNCHECKED, 0);
|
||||
SendDlgItemMessage(hDlg, IDC_SHOWCLOUDS, BM_SETCHECK,
|
||||
(renderFlags & Renderer::ShowCloudMaps)? BST_CHECKED:BST_UNCHECKED, 0);
|
||||
SendDlgItemMessage(hDlg, IDC_SHOWCLOUDSHADOWS, BM_SETCHECK,
|
||||
(renderFlags & Renderer::ShowCloudShadows)? BST_CHECKED:BST_UNCHECKED, 0);
|
||||
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_SHOWATMOSPHERES, renderFlags, Renderer::ShowAtmospheres);
|
||||
dlgCheck64(hDlg, IDC_SHOWCELESTIALGRID, renderFlags, Renderer::ShowCelestialSphere);
|
||||
dlgCheck64(hDlg, IDC_SHOWHORIZONGRID, renderFlags, Renderer::ShowHorizonGrid);
|
||||
dlgCheck64(hDlg, IDC_SHOWGALACTICGRID, renderFlags, Renderer::ShowGalacticGrid);
|
||||
dlgCheck64(hDlg, IDC_SHOWECLIPTICGRID, renderFlags, Renderer::ShowEclipticGrid);
|
||||
dlgCheck64(hDlg, IDC_SHOWECLIPTIC, renderFlags, Renderer::ShowEcliptic);
|
||||
dlgCheck64(hDlg, IDC_SHOWCLOUDS, renderFlags, Renderer::ShowCloudMaps);
|
||||
dlgCheck64(hDlg, IDC_SHOWCLOUDSHADOWS, renderFlags, Renderer::ShowCloudShadows);
|
||||
dlgCheck64(hDlg, IDC_SHOWCONSTELLATIONS, renderFlags, Renderer::ShowDiagrams);
|
||||
dlgCheck64(hDlg, IDC_SHOWECLIPSESHADOWS, renderFlags, Renderer::ShowEclipseShadows);
|
||||
dlgCheck64(hDlg, IDC_SHOWGALAXIES, renderFlags, Renderer::ShowGalaxies);
|
||||
dlgCheck64(hDlg, IDC_SHOWGLOBULARS, renderFlags, Renderer::ShowGlobulars);
|
||||
dlgCheck64(hDlg, IDC_SHOWNEBULAE, renderFlags, Renderer::ShowNebulae);
|
||||
dlgCheck64(hDlg, IDC_SHOWOPENCLUSTERS, renderFlags, Renderer::ShowOpenClusters);
|
||||
dlgCheck64(hDlg, IDC_SHOWNIGHTSIDELIGHTS, renderFlags, Renderer::ShowNightMaps);
|
||||
dlgCheck64(hDlg, IDC_SHOWORBITS, renderFlags, Renderer::ShowOrbits);
|
||||
dlgCheck64(hDlg, IDC_SHOWFADINGORBITS, renderFlags, Renderer::ShowFadingOrbits);
|
||||
dlgCheck64(hDlg, IDC_SHOWPARTIALTRAJECTORIES, renderFlags, Renderer::ShowPartialTrajectories);
|
||||
dlgCheck(hDlg, IDC_PLANETORBITS, orbitMask, Body::Planet);
|
||||
dlgCheck(hDlg, IDC_DWARFPLANETORBITS,orbitMask, Body::DwarfPlanet);
|
||||
dlgCheck(hDlg, IDC_MOONORBITS, orbitMask, Body::Moon);
|
||||
dlgCheck(hDlg, IDC_MINORMOONORBITS, orbitMask, Body::MinorMoon);
|
||||
dlgCheck(hDlg, IDC_ASTEROIDORBITS, orbitMask, Body::Asteroid);
|
||||
dlgCheck(hDlg, IDC_COMETORBITS, orbitMask, Body::Comet);
|
||||
dlgCheck(hDlg, IDC_SPACECRAFTORBITS, orbitMask, Body::Spacecraft);
|
||||
dlgCheck(hDlg, IDC_STARORBITS, orbitMask, Body::Stellar);
|
||||
SendDlgItemMessage(hDlg, IDC_SHOWPLANETS, BM_SETCHECK,
|
||||
(renderFlags & Renderer::ShowPlanets) != 0 ? BST_CHECKED : BST_UNCHECKED, 0);
|
||||
SendDlgItemMessage(hDlg, IDC_SHOWDWARFPLANETS, BM_SETCHECK,
|
||||
((renderFlags ^ Renderer::ShowDwarfPlanets) != 0) ? BST_CHECKED : BST_UNCHECKED, 0);
|
||||
SendDlgItemMessage(hDlg, IDC_SHOWMOONS, BM_SETCHECK,
|
||||
((renderFlags ^ Renderer::ShowMoons) != 0) ? BST_CHECKED : BST_UNCHECKED, 0);
|
||||
SendDlgItemMessage(hDlg, IDC_SHOWMINORMOONS, BM_SETCHECK,
|
||||
((renderFlags ^ Renderer::ShowMinorMoons) != 0) ? BST_CHECKED : BST_UNCHECKED, 0);
|
||||
SendDlgItemMessage(hDlg, IDC_SHOWASTEROIDS, BM_SETCHECK,
|
||||
((renderFlags ^ Renderer::ShowAsteroids) != 0) ? BST_CHECKED : BST_UNCHECKED, 0);
|
||||
SendDlgItemMessage(hDlg, IDC_SHOWCOMETS, BM_SETCHECK,
|
||||
((renderFlags ^ Renderer::ShowComets) != 0) ? BST_CHECKED : BST_UNCHECKED, 0);
|
||||
SendDlgItemMessage(hDlg, IDC_SHOWSPACECRAFTS, BM_SETCHECK,
|
||||
((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_PLANETORBITS, orbitMask, Body::Planet);
|
||||
dlgCheck(hDlg, IDC_DWARFPLANETORBITS,orbitMask, Body::DwarfPlanet);
|
||||
dlgCheck(hDlg, IDC_MOONORBITS, orbitMask, Body::Moon);
|
||||
dlgCheck(hDlg, IDC_MINORMOONORBITS, orbitMask, Body::MinorMoon);
|
||||
dlgCheck(hDlg, IDC_ASTEROIDORBITS, orbitMask, Body::Asteroid);
|
||||
dlgCheck(hDlg, IDC_COMETORBITS, orbitMask, Body::Comet);
|
||||
dlgCheck(hDlg, IDC_SPACECRAFTORBITS, orbitMask, Body::Spacecraft);
|
||||
dlgCheck(hDlg, IDC_STARORBITS, orbitMask, Body::Stellar);
|
||||
dlgCheck64(hDlg, IDC_SHOWPLANETS, renderFlags, Renderer::ShowPlanets);
|
||||
dlgCheck64(hDlg, IDC_SHOWDWARFPLANETS, renderFlags, Renderer::ShowDwarfPlanets);
|
||||
dlgCheck64(hDlg, IDC_SHOWMOONS, renderFlags, Renderer::ShowMoons);
|
||||
dlgCheck64(hDlg, IDC_SHOWMINORMOONS, renderFlags, Renderer::ShowMinorMoons);
|
||||
dlgCheck64(hDlg, IDC_SHOWASTEROIDS, renderFlags, Renderer::ShowAsteroids);
|
||||
dlgCheck64(hDlg, IDC_SHOWCOMETS, renderFlags, Renderer::ShowComets);
|
||||
dlgCheck64(hDlg, IDC_SHOWSPACECRAFTS, renderFlags, Renderer::ShowSpacecrafts);
|
||||
dlgCheck64(hDlg, IDC_SHOWSTARS, renderFlags, Renderer::ShowStars);
|
||||
dlgCheck64(hDlg, IDC_SHOWCONSTELLATIONBORDERS, renderFlags, Renderer::ShowBoundaries);
|
||||
dlgCheck64(hDlg, IDC_SHOWRINGSHADOWS, renderFlags, Renderer::ShowRingShadows);
|
||||
dlgCheck64(hDlg, IDC_SHOWRINGS, renderFlags, Renderer::ShowPlanetRings);
|
||||
dlgCheck64(hDlg, IDC_SHOWCOMETTAILS, renderFlags, Renderer::ShowCometTails);
|
||||
dlgCheck64(hDlg, IDC_SHOWMARKERS, renderFlags, Renderer::ShowMarkers);
|
||||
|
||||
dlgCheck(hDlg, IDC_LABELCONSTELLATIONS, labelMode, Renderer::ConstellationLabels);
|
||||
SendDlgItemMessage(hDlg, IDC_LABELCONSTELLATIONSLATIN, BM_SETCHECK,
|
||||
((labelMode & Renderer::I18nConstellationLabels) == 0) ? BST_CHECKED : BST_UNCHECKED, 0);
|
||||
dlgCheck(hDlg, IDC_LABELGALAXIES, labelMode, Renderer::GalaxyLabels);
|
||||
dlgCheck(hDlg, IDC_LABELCONSTELLATIONSLATIN, ~labelMode, Renderer::I18nConstellationLabels); // check box if flag unset
|
||||
dlgCheck(hDlg, IDC_LABELGALAXIES, labelMode, Renderer::GalaxyLabels);
|
||||
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_LABELSTARS, labelMode, Renderer::StarLabels);
|
||||
dlgCheck(hDlg, IDC_LABELPLANETS, labelMode, Renderer::PlanetLabels);
|
||||
dlgCheck(hDlg, IDC_LABELDWARFPLANETS, labelMode, Renderer::DwarfPlanetLabels);
|
||||
dlgCheck(hDlg, IDC_LABELMOONS, labelMode, Renderer::MoonLabels);
|
||||
dlgCheck(hDlg, IDC_LABELMINORMOONS, labelMode, Renderer::MinorMoonLabels);
|
||||
dlgCheck(hDlg, IDC_LABELASTEROIDS, labelMode, Renderer::AsteroidLabels);
|
||||
dlgCheck(hDlg, IDC_LABELCOMETS, labelMode, Renderer::CometLabels);
|
||||
dlgCheck(hDlg, IDC_LABELSTARS, labelMode, Renderer::StarLabels);
|
||||
dlgCheck(hDlg, IDC_LABELPLANETS, labelMode, Renderer::PlanetLabels);
|
||||
dlgCheck(hDlg, IDC_LABELDWARFPLANETS, labelMode, Renderer::DwarfPlanetLabels);
|
||||
dlgCheck(hDlg, IDC_LABELMOONS, labelMode, Renderer::MoonLabels);
|
||||
dlgCheck(hDlg, IDC_LABELMINORMOONS, labelMode, Renderer::MinorMoonLabels);
|
||||
dlgCheck(hDlg, IDC_LABELASTEROIDS, labelMode, Renderer::AsteroidLabels);
|
||||
dlgCheck(hDlg, IDC_LABELCOMETS, labelMode, Renderer::CometLabels);
|
||||
dlgCheck(hDlg, IDC_LABELSPACECRAFT, labelMode, Renderer::SpacecraftLabels);
|
||||
|
||||
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 t = 0.0f;
|
||||
|
||||
for (t = 0.0f; freq >= 1.0f; freq *= 0.5f)
|
||||
while (freq >= 1.0f)
|
||||
{
|
||||
Eigen::Vector3f vec = freq * p;
|
||||
t += noise(vec) / freq;
|
||||
freq *= 0.5f;
|
||||
}
|
||||
|
||||
return t;
|
||||
|
|
|
@ -14,9 +14,15 @@
|
|||
#include <iterator>
|
||||
#include <tuple>
|
||||
#include <utility>
|
||||
#include <celutil/logger.h>
|
||||
|
||||
#ifdef HAVE_MESHOPTIMIZER
|
||||
#include <meshoptimizer.h>
|
||||
#endif
|
||||
|
||||
#include "mesh.h"
|
||||
|
||||
using celestia::util::GetLogger;
|
||||
|
||||
namespace cmod
|
||||
{
|
||||
|
@ -38,6 +44,13 @@ VertexDescription appendingAttributes(const VertexDescription& desc, It begin, I
|
|||
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
|
||||
|
||||
|
||||
|
@ -320,13 +333,7 @@ Mesh::addGroup(PrimitiveGroupType prim,
|
|||
{
|
||||
PrimitiveGroup g;
|
||||
if (prim == PrimitiveGroupType::LineStrip || prim == PrimitiveGroupType::LineList)
|
||||
{
|
||||
g = createLinePrimitiveGroup(prim == PrimitiveGroupType::LineStrip, indices);
|
||||
}
|
||||
else
|
||||
{
|
||||
g.primOverride = prim;
|
||||
}
|
||||
|
||||
g.indices = std::move(indices);
|
||||
g.prim = prim;
|
||||
|
@ -393,9 +400,80 @@ Mesh::aggregateByMaterial()
|
|||
{
|
||||
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
|
||||
Mesh::pick(const Eigen::Vector3d& rayOrigin, const Eigen::Vector3d& rayDirection, PickResult* result) const
|
||||
{
|
||||
|
@ -663,4 +741,52 @@ Mesh::getPrimitiveCount() const
|
|||
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
|
||||
|
|
|
@ -237,8 +237,13 @@ class Mesh
|
|||
unsigned int getVertexStrideWords() const { return vertexDesc.strideBytes / sizeof(cmod::VWord); }
|
||||
unsigned int getPrimitiveCount() const;
|
||||
|
||||
void merge(const Mesh&);
|
||||
bool canMerge(const Mesh&, const std::vector<Material> &materials) const;
|
||||
void optimize();
|
||||
|
||||
private:
|
||||
PrimitiveGroup createLinePrimitiveGroup(bool lineStrip, const std::vector<Index32>& indices);
|
||||
void mergePrimitiveGroups();
|
||||
|
||||
VertexDescription vertexDesc{ };
|
||||
|
||||
|
|
|
@ -15,8 +15,11 @@
|
|||
|
||||
#include <Eigen/Geometry>
|
||||
|
||||
#include <celutil/logger.h>
|
||||
|
||||
#include "model.h"
|
||||
|
||||
using celestia::util::GetLogger;
|
||||
|
||||
namespace cmod
|
||||
{
|
||||
|
@ -315,7 +318,6 @@ Model::usesTextureType(TextureSemantic t) const
|
|||
}
|
||||
|
||||
|
||||
|
||||
bool
|
||||
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
|
||||
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
|
||||
|
|
|
@ -266,6 +266,9 @@ static void checkTimeslice(lua_State* l, lua_Debug* /*ar*/)
|
|||
// allow the script to perform cleanup
|
||||
void LuaState::cleanup()
|
||||
{
|
||||
if (!costate)
|
||||
return;
|
||||
|
||||
if (ioMode == Asking)
|
||||
{
|
||||
// Restore renderflags:
|
||||
|
|
|
@ -2296,7 +2296,6 @@ static int celestia_loadfont(lua_State* l)
|
|||
CelestiaCore* appCore = getAppCore(l, AllErrors);
|
||||
auto font = LoadTextureFont(appCore->getRenderer(), s);
|
||||
if (font == nullptr) return 0;
|
||||
font->buildTexture();
|
||||
return celx.pushClass(font);
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
// 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
|
||||
// modify it under the terms of the GNU General Public License
|
||||
|
@ -9,13 +9,15 @@
|
|||
|
||||
#include <algorithm>
|
||||
#include <array>
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
#include <celutil/logger.h>
|
||||
#include <celutil/utf8.h>
|
||||
#include <celcompat/charconv.h>
|
||||
#include <celengine/glsupport.h>
|
||||
#include <celengine/render.h>
|
||||
#include <celutil/logger.h>
|
||||
#include <celutil/utf8.h>
|
||||
#include <ft2build.h>
|
||||
#include <map>
|
||||
#include <system_error>
|
||||
#include <vector>
|
||||
#include FT_FREETYPE_H
|
||||
#include "truetypefont.h"
|
||||
|
||||
|
@ -25,26 +27,24 @@
|
|||
#include <fstream>
|
||||
#endif
|
||||
|
||||
using namespace std;
|
||||
using celestia::compat::from_chars;
|
||||
using celestia::util::GetLogger;
|
||||
|
||||
static FT_Library ft = nullptr;
|
||||
|
||||
struct Glyph
|
||||
{
|
||||
wchar_t ch;
|
||||
|
||||
int ax; // advance.x
|
||||
int ay; // advance.y
|
||||
int ax; // advance.x
|
||||
int ay; // advance.y
|
||||
|
||||
int bw; // bitmap.width;
|
||||
int bh; // bitmap.height;
|
||||
unsigned int bw; // bitmap.width;
|
||||
unsigned int bh; // bitmap.height;
|
||||
|
||||
int bl; // bitmap_left;
|
||||
int bt; // bitmap_top;
|
||||
int bl; // bitmap_left;
|
||||
int bt; // bitmap_top;
|
||||
|
||||
float tx; // x offset of glyph in texture coordinates
|
||||
float ty; // y offset of glyph in texture coordinates
|
||||
float tx; // x offset of glyph in texture coordinates
|
||||
float ty; // y offset of glyph in texture coordinates
|
||||
};
|
||||
|
||||
struct UnicodeBlock
|
||||
|
@ -56,75 +56,82 @@ struct TextureFontPrivate
|
|||
{
|
||||
struct FontVertex
|
||||
{
|
||||
FontVertex(float _x, float _y, float _u, float _v) :
|
||||
x(_x), y(_y), u(_u), v(_v)
|
||||
{}
|
||||
FontVertex(float _x, float _y, float _u, float _v) : x(_x), y(_y), u(_u), v(_v)
|
||||
{
|
||||
}
|
||||
float x, y;
|
||||
float u, v;
|
||||
};
|
||||
|
||||
TextureFontPrivate() = delete;
|
||||
TextureFontPrivate(const Renderer *renderer);
|
||||
~TextureFontPrivate();
|
||||
TextureFontPrivate(const TextureFontPrivate&) = default;
|
||||
TextureFontPrivate(TextureFontPrivate&&) = default;
|
||||
TextureFontPrivate& operator=(const TextureFontPrivate&) = default;
|
||||
TextureFontPrivate& operator=(TextureFontPrivate&&) = default;
|
||||
TextureFontPrivate() = delete;
|
||||
TextureFontPrivate(const TextureFontPrivate &) = default;
|
||||
TextureFontPrivate(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);
|
||||
|
||||
bool buildAtlas();
|
||||
void computeTextureSize();
|
||||
bool loadGlyphInfo(wchar_t, Glyph&);
|
||||
void initCommonGlyphs();
|
||||
int getCommonGlyphsCount();
|
||||
Glyph& getGlyph(wchar_t);
|
||||
Glyph& getGlyph(wchar_t, wchar_t);
|
||||
int toPos(wchar_t) const;
|
||||
void optimize();
|
||||
CelestiaGLProgram* getProgram();
|
||||
void flush();
|
||||
bool buildAtlas();
|
||||
void computeTextureSize();
|
||||
bool loadGlyphInfo(wchar_t /*ch*/, Glyph & /*c*/) const;
|
||||
void initCommonGlyphs();
|
||||
int getCommonGlyphsCount();
|
||||
Glyph & getGlyph(wchar_t /*ch*/);
|
||||
Glyph & getGlyph(wchar_t /*ch*/, wchar_t /*fallback*/);
|
||||
[[nodiscard]] int toPos(wchar_t /*ch*/) const;
|
||||
void optimize();
|
||||
CelestiaGLProgram *getProgram();
|
||||
void flush();
|
||||
|
||||
const Renderer *m_renderer;
|
||||
CelestiaGLProgram *m_prog { nullptr };
|
||||
const Renderer *m_renderer;
|
||||
CelestiaGLProgram *m_prog{ nullptr };
|
||||
|
||||
FT_Face m_face; // font face
|
||||
FT_Face m_face; // font face
|
||||
|
||||
int m_maxAscent;
|
||||
int m_maxDescent;
|
||||
int m_maxWidth;
|
||||
int m_maxAscent{ 0 };
|
||||
int m_maxDescent{ 0 };
|
||||
int m_maxWidth{ 0 };
|
||||
|
||||
int m_texWidth;
|
||||
int m_texHeight;
|
||||
int m_texWidth{ 0 };
|
||||
int m_texHeight{ 0 };
|
||||
|
||||
GLuint m_texName { 0 }; // texture object
|
||||
vector<Glyph> m_glyphs; // character information
|
||||
GLint m_maxTextureSize; // max supported texture size
|
||||
GLuint m_texName{ 0 }; // texture object
|
||||
std::vector<Glyph> m_glyphs; // character information
|
||||
GLint m_maxTextureSize; // max supported texture size
|
||||
|
||||
array<UnicodeBlock, 2> m_unicodeBlocks;
|
||||
int m_commonGlyphsCount { 0 };
|
||||
std::array<UnicodeBlock, 2> m_unicodeBlocks;
|
||||
int m_commonGlyphsCount{ 0 };
|
||||
|
||||
int m_inserted { 0 };
|
||||
int m_inserted{ 0 };
|
||||
|
||||
Eigen::Matrix4f m_projection;
|
||||
Eigen::Matrix4f m_modelView;
|
||||
bool m_shaderInUse { false };
|
||||
vector<FontVertex> m_fontVertices;
|
||||
Eigen::Matrix4f m_projection;
|
||||
Eigen::Matrix4f m_modelView;
|
||||
bool m_shaderInUse{ false };
|
||||
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
|
||||
last = first + 32
|
||||
*/
|
||||
|
||||
TextureFontPrivate::TextureFontPrivate(const Renderer *renderer) :
|
||||
m_renderer(renderer)
|
||||
TextureFontPrivate::TextureFontPrivate(const Renderer *renderer) : m_renderer(renderer)
|
||||
{
|
||||
m_unicodeBlocks[0] = { 0x0020, 0x007E }; // Basic Latin
|
||||
m_unicodeBlocks[1] = { 0x03B1, 0x03CF }; // Lower case Greek
|
||||
|
@ -134,13 +141,12 @@ TextureFontPrivate::TextureFontPrivate(const Renderer *renderer) :
|
|||
|
||||
TextureFontPrivate::~TextureFontPrivate()
|
||||
{
|
||||
if (m_face)
|
||||
FT_Done_Face(m_face);
|
||||
if (m_texName != 0)
|
||||
glDeleteTextures(1, &m_texName);
|
||||
if (m_face != nullptr) FT_Done_Face(m_face);
|
||||
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;
|
||||
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;
|
||||
}
|
||||
|
||||
void TextureFontPrivate::initCommonGlyphs()
|
||||
void
|
||||
TextureFontPrivate::initCommonGlyphs()
|
||||
{
|
||||
if (m_glyphs.size() > 0)
|
||||
return;
|
||||
if (!m_glyphs.empty()) return;
|
||||
|
||||
m_glyphs.reserve(256);
|
||||
|
||||
|
@ -178,12 +184,13 @@ void TextureFontPrivate::initCommonGlyphs()
|
|||
}
|
||||
}
|
||||
|
||||
void TextureFontPrivate::computeTextureSize()
|
||||
void
|
||||
TextureFontPrivate::computeTextureSize()
|
||||
{
|
||||
int roww = 0;
|
||||
int rowh = 0;
|
||||
int w = 0;
|
||||
int h = 0;
|
||||
int w = 0;
|
||||
int h = 0;
|
||||
|
||||
// Find minimum size for a texture holding all visible ASCII characters
|
||||
for (const auto &c : m_glyphs)
|
||||
|
@ -192,23 +199,24 @@ void TextureFontPrivate::computeTextureSize()
|
|||
|
||||
if (roww + c.bw + 1 >= m_maxTextureSize)
|
||||
{
|
||||
w = max(w, roww);
|
||||
w = std::max(w, roww);
|
||||
h += rowh;
|
||||
roww = 0;
|
||||
rowh = 0;
|
||||
}
|
||||
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;
|
||||
|
||||
m_texWidth = w;
|
||||
m_texWidth = w;
|
||||
m_texHeight = h;
|
||||
}
|
||||
|
||||
bool TextureFontPrivate::buildAtlas()
|
||||
bool
|
||||
TextureFontPrivate::buildAtlas()
|
||||
{
|
||||
FT_GlyphSlot g = m_face->glyph;
|
||||
|
||||
|
@ -217,14 +225,20 @@ bool TextureFontPrivate::buildAtlas()
|
|||
|
||||
// Create a texture that will be used to hold all glyphs
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
if (m_texName != 0)
|
||||
glDeleteTextures(1, &m_texName);
|
||||
if (m_texName != 0) glDeleteTextures(1, &m_texName);
|
||||
glGenTextures(1, &m_texName);
|
||||
if (m_texName == 0)
|
||||
return false;
|
||||
if (m_texName == 0) return false;
|
||||
|
||||
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
|
||||
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
|
||||
|
@ -247,42 +261,53 @@ bool TextureFontPrivate::buildAtlas()
|
|||
{
|
||||
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));
|
||||
c.ch = 0;
|
||||
continue;
|
||||
GetLogger()->warn("Loading character {:x} failed!\n", static_cast<unsigned>(c.ch));
|
||||
c.ch = 0;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (ox + int(g->bitmap.width) > int(m_texWidth))
|
||||
{
|
||||
oy += rowh;
|
||||
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);
|
||||
c.tx = (float)ox / (float)m_texWidth;
|
||||
c.ty = (float)oy / (float)m_texHeight;
|
||||
glTexSubImage2D(GL_TEXTURE_2D,
|
||||
0,
|
||||
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;
|
||||
}
|
||||
|
||||
#if DUMP_TEXTURE
|
||||
fmt::printf(cout/*cerr*/, "Generated a {} x {} ({} kb) texture atlas\n", m_texWidth, m_texHeight, 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];
|
||||
fmt::print("Generated a {} x {} ({} kb) texture atlas\n",
|
||||
m_texWidth, m_texHeight,
|
||||
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);
|
||||
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();
|
||||
delete[] raw_img;
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
|
||||
int TextureFontPrivate::getCommonGlyphsCount()
|
||||
int
|
||||
TextureFontPrivate::getCommonGlyphsCount()
|
||||
{
|
||||
if (m_commonGlyphsCount == 0)
|
||||
{
|
||||
|
@ -292,17 +317,16 @@ int TextureFontPrivate::getCommonGlyphsCount()
|
|||
return m_commonGlyphsCount;
|
||||
}
|
||||
|
||||
int TextureFontPrivate::toPos(wchar_t ch) const
|
||||
int
|
||||
TextureFontPrivate::toPos(wchar_t ch) const
|
||||
{
|
||||
int pos = 0;
|
||||
|
||||
if (ch > m_unicodeBlocks.back().last)
|
||||
return -1;
|
||||
if (ch > m_unicodeBlocks.back().last) return -1;
|
||||
|
||||
for (const auto &r : m_unicodeBlocks)
|
||||
{
|
||||
if (ch < r.first)
|
||||
return -1;
|
||||
if (ch < r.first) return -1;
|
||||
|
||||
if (ch <= r.last)
|
||||
{
|
||||
|
@ -314,22 +338,22 @@ int TextureFontPrivate::toPos(wchar_t ch) const
|
|||
return -1;
|
||||
}
|
||||
|
||||
Glyph& TextureFontPrivate::getGlyph(wchar_t ch, wchar_t fallback)
|
||||
Glyph &
|
||||
TextureFontPrivate::getGlyph(wchar_t ch, wchar_t fallback)
|
||||
{
|
||||
auto &g = getGlyph(ch);
|
||||
return g.ch == ch ? g : getGlyph(fallback);
|
||||
}
|
||||
|
||||
Glyph g_badGlyph = {0, 0, 0, 0, 0, 0, 0, 0.0f, 0.0f};
|
||||
Glyph& TextureFontPrivate::getGlyph(wchar_t ch)
|
||||
Glyph &
|
||||
TextureFontPrivate::getGlyph(wchar_t ch)
|
||||
{
|
||||
auto pos = toPos(ch);
|
||||
if (pos != -1)
|
||||
if (auto pos = toPos(ch); pos != -1)
|
||||
return m_glyphs[pos];
|
||||
|
||||
auto it = find_if(m_glyphs.begin() + getCommonGlyphsCount(),
|
||||
m_glyphs.end(),
|
||||
[ch](Glyph &g) { return g.ch == ch; });
|
||||
[ch](const Glyph &g) { return g.ch == ch; });
|
||||
|
||||
if (it != m_glyphs.end())
|
||||
return *it;
|
||||
|
@ -341,14 +365,14 @@ Glyph& TextureFontPrivate::getGlyph(wchar_t ch)
|
|||
flush(); // render text to avoid garbled output due to changed texture
|
||||
|
||||
m_glyphs.push_back(c);
|
||||
if (++m_inserted == 10)
|
||||
optimize();
|
||||
if (++m_inserted == 10) optimize();
|
||||
buildAtlas();
|
||||
|
||||
return m_glyphs.back();
|
||||
}
|
||||
|
||||
void TextureFontPrivate::optimize()
|
||||
void
|
||||
TextureFontPrivate::optimize()
|
||||
{
|
||||
m_inserted = 0;
|
||||
}
|
||||
|
@ -358,34 +382,33 @@ void TextureFontPrivate::optimize()
|
|||
* Rendering starts at coordinates (x, y), z is always 0.
|
||||
* 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)
|
||||
return 0;
|
||||
if (m_texName == 0) return 0;
|
||||
|
||||
// Use the texture containing the atlas
|
||||
glBindTexture(GL_TEXTURE_2D, m_texName);
|
||||
|
||||
// Loop through all characters
|
||||
int len = s.length();
|
||||
int len = s.length();
|
||||
bool validChar = true;
|
||||
int i = 0;
|
||||
int i = 0;
|
||||
|
||||
while (i < len && validChar)
|
||||
{
|
||||
wchar_t ch = 0;
|
||||
validChar = UTF8Decode(s, i, ch);
|
||||
if (!validChar)
|
||||
break;
|
||||
validChar = UTF8Decode(s, i, ch);
|
||||
if (!validChar) break;
|
||||
i += UTF8EncodedSize(ch);
|
||||
|
||||
auto& g = getGlyph(ch, L'?');
|
||||
auto &g = getGlyph(ch, L'?');
|
||||
|
||||
// Calculate the vertex and texture coordinates
|
||||
const float x1 = x + g.bl;
|
||||
const float y1 = y + g.bt - g.bh;
|
||||
const float w = g.bw;
|
||||
const float h = g.bh;
|
||||
const float w = g.bw;
|
||||
const float h = g.bh;
|
||||
const float x2 = x1 + w;
|
||||
const float y2 = y1 + h;
|
||||
|
||||
|
@ -394,27 +417,26 @@ float TextureFontPrivate::render(const string &s, float x, float y)
|
|||
y += g.ay;
|
||||
|
||||
// Skip glyphs that have no pixels
|
||||
if (g.bw == 0 || g.bh == 0)
|
||||
continue;
|
||||
if (g.bw == 0 || g.bh == 0) continue;
|
||||
|
||||
const float tx1 = g.tx;
|
||||
const float ty1 = g.ty;
|
||||
const float tx2 = tx1 + w / m_texWidth;
|
||||
const float ty2 = ty1 + h / m_texHeight;
|
||||
|
||||
m_fontVertices.emplace_back(FontVertex(x1, y1, tx1, ty2));
|
||||
m_fontVertices.emplace_back(FontVertex(x2, y1, tx2, ty2));
|
||||
m_fontVertices.emplace_back(FontVertex(x1, y2, tx1, ty1));
|
||||
m_fontVertices.emplace_back(FontVertex(x2, y2, tx2, ty1));
|
||||
m_fontVertices.emplace_back(x1, y1, tx1, ty2);
|
||||
m_fontVertices.emplace_back(x2, y1, tx2, ty2);
|
||||
m_fontVertices.emplace_back(x1, y2, tx1, ty1);
|
||||
m_fontVertices.emplace_back(x2, y2, tx2, ty1);
|
||||
}
|
||||
|
||||
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
|
||||
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 ty2 = ty1 + static_cast<float>(g.bh) / m_texHeight;
|
||||
|
||||
m_fontVertices.emplace_back(FontVertex(x1, y1, tx1, ty2));
|
||||
m_fontVertices.emplace_back(FontVertex(x2, y1, tx2, ty2));
|
||||
m_fontVertices.emplace_back(FontVertex(x1, y2, tx1, ty1));
|
||||
m_fontVertices.emplace_back(FontVertex(x2, y2, tx2, ty1));
|
||||
m_fontVertices.emplace_back(x1, y1, tx1, ty2);
|
||||
m_fontVertices.emplace_back(x2, y1, tx2, ty2);
|
||||
m_fontVertices.emplace_back(x1, y2, tx1, ty1);
|
||||
m_fontVertices.emplace_back(x2, y2, tx2, ty1);
|
||||
|
||||
return g.ax;
|
||||
}
|
||||
|
||||
CelestiaGLProgram* TextureFontPrivate::getProgram()
|
||||
CelestiaGLProgram *
|
||||
TextureFontPrivate::getProgram()
|
||||
{
|
||||
if (m_prog != nullptr)
|
||||
return m_prog;
|
||||
if (m_prog != nullptr) return m_prog;
|
||||
m_prog = m_renderer->getShaderManager().getShader("text");
|
||||
return m_prog;
|
||||
}
|
||||
|
||||
void TextureFontPrivate::flush()
|
||||
void
|
||||
TextureFontPrivate::flush()
|
||||
{
|
||||
if (m_fontVertices.size() < 4)
|
||||
return;
|
||||
if (m_fontVertices.size() < 4) return;
|
||||
|
||||
vector<unsigned short> indexes;
|
||||
std::vector<unsigned short> indexes;
|
||||
indexes.reserve(m_fontVertices.size() / 4 * 6);
|
||||
for (unsigned short index = 0;
|
||||
index < (unsigned short) m_fontVertices.size();
|
||||
index += 4)
|
||||
for (unsigned short index = 0; index < static_cast<unsigned short>(m_fontVertices.size()); index += 4)
|
||||
{
|
||||
indexes.push_back(index + 0);
|
||||
indexes.push_back(index + 1);
|
||||
|
@ -465,9 +485,17 @@ void TextureFontPrivate::flush()
|
|||
glEnableVertexAttribArray(CelestiaGLProgram::VertexCoordAttributeIndex);
|
||||
glEnableVertexAttribArray(CelestiaGLProgram::TextureCoord0AttributeIndex);
|
||||
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,
|
||||
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());
|
||||
glDisableVertexAttribArray(CelestiaGLProgram::VertexCoordAttributeIndex);
|
||||
glDisableVertexAttribArray(CelestiaGLProgram::TextureCoord0AttributeIndex);
|
||||
|
@ -475,17 +503,11 @@ void TextureFontPrivate::flush()
|
|||
m_fontVertices.clear();
|
||||
}
|
||||
|
||||
|
||||
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
|
||||
*
|
||||
|
@ -496,7 +518,8 @@ TextureFont::~TextureFont()
|
|||
* @param xoffset -- horizontal 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);
|
||||
}
|
||||
|
@ -511,7 +534,8 @@ float TextureFont::render(wchar_t ch, float xoffset, float yoffset) const
|
|||
* @param xoffset -- horizontal 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);
|
||||
}
|
||||
|
@ -524,69 +548,92 @@ float TextureFont::render(const string &s, float xoffset, float yoffset) const
|
|||
* @param s -- string to calculate width
|
||||
* @return string width in pixels
|
||||
*/
|
||||
int TextureFont::getWidth(const string& s) const
|
||||
int
|
||||
TextureFont::getWidth(std::string_view s) const
|
||||
{
|
||||
int width = 0;
|
||||
int len = s.length();
|
||||
int width = 0;
|
||||
int len = s.length();
|
||||
bool validChar = true;
|
||||
int i = 0;
|
||||
int i = 0;
|
||||
|
||||
while (i < len && validChar)
|
||||
{
|
||||
wchar_t ch = 0;
|
||||
validChar = UTF8Decode(s, i, ch);
|
||||
if (!validChar)
|
||||
break;
|
||||
validChar = UTF8Decode(s, i, ch);
|
||||
if (!validChar) break;
|
||||
|
||||
i += UTF8EncodedSize(ch);
|
||||
|
||||
auto& g = impl->getGlyph(ch, L'?');
|
||||
auto &g = impl->getGlyph(ch, L'?');
|
||||
width += g.ax;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
int TextureFont::getMaxWidth() const
|
||||
/**
|
||||
* Return the maximal character width for the current font.
|
||||
*/
|
||||
int
|
||||
TextureFont::getMaxWidth() const
|
||||
{
|
||||
return impl->m_maxWidth;
|
||||
}
|
||||
|
||||
int TextureFont::getMaxAscent() const
|
||||
/**
|
||||
* Return the maximal ascent for the current font.
|
||||
*/
|
||||
int
|
||||
TextureFont::getMaxAscent() const
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
int TextureFont::getMaxDescent() const
|
||||
/**
|
||||
* Return the maximal descent for the current font.
|
||||
*/
|
||||
int
|
||||
TextureFont::getMaxDescent() const
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
int TextureFont::getTextureName() const
|
||||
{
|
||||
return impl->m_texName;
|
||||
}
|
||||
|
||||
void TextureFont::bind()
|
||||
/**
|
||||
* Use the current font for text rendering.
|
||||
*/
|
||||
void
|
||||
TextureFont::bind()
|
||||
{
|
||||
auto *prog = impl->getProgram();
|
||||
if (prog == nullptr)
|
||||
return;
|
||||
if (prog == nullptr) return;
|
||||
|
||||
if (impl->m_texName != 0)
|
||||
{
|
||||
|
@ -594,16 +641,20 @@ void TextureFont::bind()
|
|||
glBindTexture(GL_TEXTURE_2D, impl->m_texName);
|
||||
prog->use();
|
||||
prog->samplerParam("atlasTex") = 0;
|
||||
impl->m_shaderInUse = true;
|
||||
impl->m_shaderInUse = true;
|
||||
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_modelView = m;
|
||||
auto *prog = impl->getProgram();
|
||||
impl->m_modelView = m;
|
||||
auto *prog = impl->getProgram();
|
||||
if (prog != nullptr && impl->m_shaderInUse)
|
||||
{
|
||||
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();
|
||||
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;
|
||||
}
|
||||
|
||||
bool TextureFont::buildTexture()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
void TextureFont::flush()
|
||||
/**
|
||||
* Perform all delayed text rendering operations.
|
||||
*/
|
||||
void
|
||||
TextureFont::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;
|
||||
|
||||
|
@ -646,69 +708,89 @@ TextureFont* TextureFont::load(const Renderer *r, const fs::path &path, int inde
|
|||
if (!FT_IS_SCALABLE(face))
|
||||
{
|
||||
GetLogger()->error("Font is not scalable: {}\n", path);
|
||||
FT_Done_Face(face);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (FT_Set_Char_Size(face, 0, size << 6, dpi, dpi) != 0)
|
||||
{
|
||||
GetLogger()->error("Could not set font size {}\n", size);
|
||||
FT_Done_Face(face);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
auto* font = new TextureFont(r);
|
||||
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;
|
||||
return face;
|
||||
}
|
||||
|
||||
// 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)
|
||||
auto fn = filename.string();
|
||||
auto pos = fn.rfind(',');
|
||||
if (pos != string::npos)
|
||||
if (auto ps = fn.rfind(','); ps != std::string::npos)
|
||||
{
|
||||
size = (int) stof(fn.substr(pos + 1));
|
||||
auto rest = fn.substr(0, pos);
|
||||
|
||||
pos = rest.rfind(',');
|
||||
if (pos != string::npos)
|
||||
if (from_chars(&fn[ps + 1], &fn[fn.size()], size).ec == std::errc())
|
||||
{
|
||||
collectionIndex = stof(rest.substr(pos + 1));
|
||||
return rest.substr(0, pos);
|
||||
}
|
||||
else
|
||||
{
|
||||
return rest;
|
||||
if (auto pi = fn.rfind(',', ps - 1); pi != std::string::npos)
|
||||
{
|
||||
if (from_chars(&fn[pi + 1], &fn[pi], index).ec == std::errc())
|
||||
return fn.substr(0, pi);
|
||||
}
|
||||
return fn.substr(0, ps);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
size = 12;
|
||||
return filename;
|
||||
}
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
int psize = 0;
|
||||
int pcollectionIndex = 0;
|
||||
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()));
|
||||
ret->setMaxAscent(static_cast<int>(face->size->metrics.ascender >> 6));
|
||||
ret->setMaxDescent(static_cast<int>(-face->size->metrics.descender >> 6));
|
||||
|
||||
font = ret;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
// 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
|
||||
// modify it under the terms of the GNU General Public License
|
||||
|
@ -9,51 +9,53 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <celcompat/filesystem.h>
|
||||
#include <Eigen/Core>
|
||||
#include <celcompat/filesystem.h>
|
||||
#include <string_view>
|
||||
|
||||
class Renderer;
|
||||
class TextureFont;
|
||||
|
||||
std::shared_ptr<TextureFont>
|
||||
LoadTextureFont(const Renderer *, const fs::path &, int index = 0, int size = 0);
|
||||
|
||||
struct TextureFontPrivate;
|
||||
class TextureFont
|
||||
{
|
||||
TextureFont(const Renderer*);
|
||||
public:
|
||||
TextureFont(const Renderer *);
|
||||
TextureFont() = delete;
|
||||
~TextureFont();
|
||||
TextureFont(const TextureFont&) = delete;
|
||||
TextureFont(TextureFont&&) = delete;
|
||||
TextureFont& operator=(const TextureFont&) = delete;
|
||||
TextureFont& operator=(TextureFont&&) = delete;
|
||||
~TextureFont() = default;
|
||||
TextureFont(const TextureFont &) = delete;
|
||||
TextureFont(TextureFont &&) = delete;
|
||||
TextureFont &operator=(const 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(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 getMaxWidth() const;
|
||||
int getHeight() const;
|
||||
|
||||
int getMaxAscent() const;
|
||||
int getMaxAscent() const;
|
||||
void setMaxAscent(int);
|
||||
int getMaxDescent() const;
|
||||
int getMaxDescent() const;
|
||||
void setMaxDescent(int);
|
||||
|
||||
short getAdvance(wchar_t c) const;
|
||||
|
||||
int getTextureName() const;
|
||||
void bind();
|
||||
void unbind();
|
||||
bool buildTexture();
|
||||
void flush();
|
||||
|
||||
static TextureFont* load(const Renderer*, const fs::path&, int index, int size, int dpi);
|
||||
|
||||
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
|
||||
// of the License, or (at your option) any later version.
|
||||
|
||||
#include <cassert>
|
||||
#include <cmath>
|
||||
#include <cstdio>
|
||||
#include <cstring>
|
||||
|
@ -15,6 +16,7 @@
|
|||
|
||||
// HACK: MS Visual C++ has _snprintf declared in stdio.h but not snprintf
|
||||
#ifdef _WIN32
|
||||
#include <celutil/winutil.h>
|
||||
#define snprintf _snprintf
|
||||
#endif
|
||||
|
||||
|
@ -58,9 +60,30 @@ std::ostream& operator<<(std::ostream& out, const FormattedNumber& num)
|
|||
char obuf[64];
|
||||
int fmtPrecision;
|
||||
double value = num.getRoundedValue();
|
||||
char *decimal_point = localeconv()->decimal_point;
|
||||
char *thousands_sep = localeconv()->thousands_sep;
|
||||
char *grouping = localeconv()->grouping;
|
||||
const char *grouping = localeconv()->grouping;
|
||||
#ifndef _WIN32
|
||||
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));
|
||||
|
||||
|
|
|
@ -15,11 +15,13 @@
|
|||
|
||||
#include <cel3ds/3dsread.h>
|
||||
#include <celmath/mathlib.h>
|
||||
#include <celutil/logger.h>
|
||||
|
||||
#include "cmodops.h"
|
||||
#include "convert3ds.h"
|
||||
#include "pathmanager.h"
|
||||
|
||||
using celestia::util::CreateLogger;
|
||||
|
||||
void usage()
|
||||
{
|
||||
|
@ -35,6 +37,8 @@ int main(int argc, char* argv[])
|
|||
return 1;
|
||||
}
|
||||
|
||||
CreateLogger();
|
||||
|
||||
std::string inputFileName = argv[1];
|
||||
|
||||
std::cerr << "Reading...\n";
|
||||
|
|
|
@ -1,5 +1,10 @@
|
|||
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()
|
||||
endif()
|
||||
|
||||
|
|
|
@ -11,7 +11,9 @@
|
|||
#include "mainwindow.h"
|
||||
#include <QApplication>
|
||||
#include <QGLFormat>
|
||||
#include <celutil/logger.h>
|
||||
|
||||
using celestia::util::CreateLogger;
|
||||
|
||||
int
|
||||
main(int argc, char *argv[])
|
||||
|
@ -51,5 +53,7 @@ main(int argc, char *argv[])
|
|||
// open events.
|
||||
app.installEventFilter(&window);
|
||||
|
||||
CreateLogger();
|
||||
|
||||
return app.exec();
|
||||
}
|
||||
|
|
|
@ -363,7 +363,7 @@ joinVertices(std::vector<Face>& faces,
|
|||
return;
|
||||
|
||||
// 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;
|
||||
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
|
||||
{ //causing that a dump of stardb is not a textfile but binary.
|
||||
case StellarClass::Lum_Ia0:
|
||||
out << "I-a0";
|
||||
out << "Ia-0";
|
||||
break;
|
||||
case StellarClass::Lum_Ia:
|
||||
out << "I-a";
|
||||
out << "Ia";
|
||||
break;
|
||||
case StellarClass::Lum_Ib:
|
||||
out << "I-b";
|
||||
out << "Ib";
|
||||
break;
|
||||
case StellarClass::Lum_II:
|
||||
out << "II";
|
||||
|
|
|
@ -111,13 +111,13 @@ void printStellarClass(uint16_t sc, ostream& out)
|
|||
switch (luminosityClass)
|
||||
{
|
||||
case StellarClass::Lum_Ia0:
|
||||
out << "I-a0";
|
||||
out << "Ia-0";
|
||||
break;
|
||||
case StellarClass::Lum_Ia:
|
||||
out << "I-a";
|
||||
out << "Ia";
|
||||
break;
|
||||
case StellarClass::Lum_Ib:
|
||||
out << "I-b";
|
||||
out << "Ib";
|
||||
break;
|
||||
case StellarClass::Lum_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)
|
||||
|
||||
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"
|
||||
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(hash)
|
||||
test_case(logger)
|
||||
|
|
|
@ -1,22 +1,22 @@
|
|||
#include <celengine/stellarclass.h>
|
||||
#include <cstdint>
|
||||
|
||||
#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.getSpectralClass() == _class); \
|
||||
REQUIRE(u.getSubclass() == 5); \
|
||||
REQUIRE(u.getLuminosityClass() == StellarClass::Lum_Ia0); \
|
||||
REQUIRE(u.str() == _str);
|
||||
REQUIRE(u.getLuminosityClass() == StellarClass::Lum_Ia0);
|
||||
|
||||
#define CHECK_WHITE_DWARF(u, _class, _str) \
|
||||
#define CHECK_WHITE_DWARF(u, _class) \
|
||||
REQUIRE(u.getStarType() == StellarClass::WhiteDwarf); \
|
||||
REQUIRE(u.getSpectralClass() == _class); \
|
||||
REQUIRE(u.getSubclass() == 5); \
|
||||
REQUIRE(u.getLuminosityClass() == StellarClass::Lum_Unknown); \
|
||||
REQUIRE(u.str() == _str);
|
||||
REQUIRE(u.getLuminosityClass() == StellarClass::Lum_Unknown);
|
||||
|
||||
TEST_CASE("StellarClass", "[StellarClass]")
|
||||
TEST_CASE("StellarClass packing", "[StellarClass]")
|
||||
{
|
||||
SECTION("StellarClass::Spectral_WO")
|
||||
{
|
||||
|
@ -25,21 +25,21 @@ TEST_CASE("StellarClass", "[StellarClass]")
|
|||
5,
|
||||
StellarClass::Lum_Ia0);
|
||||
|
||||
uint16_t packed;
|
||||
std::uint16_t packed;
|
||||
StellarClass u;
|
||||
|
||||
SECTION("Packed as V1")
|
||||
{
|
||||
packed = sc.packV1();
|
||||
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")
|
||||
{
|
||||
packed = sc.packV2();
|
||||
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,
|
||||
StellarClass::Lum_Ia0);
|
||||
|
||||
uint16_t packed;
|
||||
std::uint16_t packed;
|
||||
StellarClass u;
|
||||
|
||||
SECTION("Packed as V1")
|
||||
{
|
||||
packed = sc.packV1();
|
||||
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")
|
||||
{
|
||||
packed = sc.packV2();
|
||||
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,
|
||||
StellarClass::Lum_Ia0);
|
||||
|
||||
uint16_t packed;
|
||||
std::uint16_t packed;
|
||||
StellarClass u;
|
||||
|
||||
SECTION("Packed as V1")
|
||||
{
|
||||
packed = sc.packV1();
|
||||
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")
|
||||
{
|
||||
packed = sc.packV2();
|
||||
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,
|
||||
StellarClass::Lum_Ia0);
|
||||
|
||||
uint16_t packed;
|
||||
std::uint16_t packed;
|
||||
StellarClass u;
|
||||
|
||||
SECTION("Packed as V1")
|
||||
{
|
||||
packed = sc.packV1();
|
||||
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")
|
||||
{
|
||||
packed = sc.packV2();
|
||||
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,
|
||||
StellarClass::Lum_Ia0);
|
||||
|
||||
uint16_t packed;
|
||||
std::uint16_t packed;
|
||||
StellarClass u;
|
||||
|
||||
SECTION("Packed as V1")
|
||||
{
|
||||
packed = sc.packV1();
|
||||
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")
|
||||
{
|
||||
packed = sc.packV2();
|
||||
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,
|
||||
StellarClass::Lum_Ia0);
|
||||
|
||||
uint16_t packed;
|
||||
std::uint16_t packed;
|
||||
StellarClass u;
|
||||
|
||||
SECTION("Packed as V1")
|
||||
{
|
||||
packed = sc.packV1();
|
||||
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")
|
||||
{
|
||||
packed = sc.packV2();
|
||||
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,
|
||||
StellarClass::Lum_Ia0);
|
||||
|
||||
uint16_t packed;
|
||||
std::uint16_t packed;
|
||||
StellarClass u;
|
||||
|
||||
SECTION("Packed as V1")
|
||||
{
|
||||
packed = sc.packV1();
|
||||
REQUIRE(u.unpackV1(packed));
|
||||
CHECK_WHITE_DWARF(u, StellarClass::Spectral_DO, "WD");
|
||||
CHECK_WHITE_DWARF(u, StellarClass::Spectral_DO);
|
||||
}
|
||||
|
||||
SECTION("Packed as V2")
|
||||
{
|
||||
packed = sc.packV2();
|
||||
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