Compare commits

...

126 Commits

Author SHA1 Message Date
cc1cdfac39 Upscale textures when using overlay with grouped textures
Some checks failed
android / build (push) Has been cancelled
cpp_lint / clang_tidy (push) Has been cancelled
linux / gcc_7 (push) Has been cancelled
linux / gcc_14 (push) Has been cancelled
linux / clang_7 (push) Has been cancelled
linux / clang_18 (push) Has been cancelled
linux / clang_11 (PROMETHEUS=1) (push) Has been cancelled
macos / build-intel-macos (push) Has been cancelled
macos / build-arm-macos-xcode (push) Has been cancelled
whitespace_checks / trailing_whitespaces (push) Has been cancelled
whitespace_checks / tabs_lua_api_files (push) Has been cancelled
windows / MinGW cross-compiler (${{ matrix.bits }}-bit) (32) (push) Has been cancelled
windows / MinGW cross-compiler (${{ matrix.bits }}-bit) (64) (push) Has been cancelled
windows / VS 2019 ${{ matrix.config.arch }}-${{ matrix.type }} (map[arch:x64 generator:-G'Visual Studio 16 2019' -A x64 vcpkg_triplet:x64-windows], portable) (push) Has been cancelled
windows / VS 2019 ${{ matrix.config.arch }}-${{ matrix.type }} (map[arch:x86 generator:-G'Visual Studio 16 2019' -A Win32 vcpkg_triplet:x86-windows], portable) (push) Has been cancelled
Signed-off-by: tour <tour@noreply.your-land.de>
2025-01-02 19:54:59 +00:00
cx384
c4d624083d Main menu server tab search improvements 2025-01-02 15:22:49 +01:00
wozrer
a1b8d20f18 Rename getMapSettingNoiseParams to getNoiseParams 2025-01-02 14:59:19 +01:00
sfan5
0a67e6180d Disable failing unit test for the time being
see #15598
2025-01-02 12:42:19 +01:00
lhofhansl
2db4ad8c77
Fix MSAA and bloom flashing artifacts (#15610)
* Mark varColor and nightratio as centroids
* Leave old workaround in place for GLES
2025-01-01 14:18:05 -08:00
grorp
f54d209bc8
Remove normal map leftovers (#15609)
leftovers from #10487 / ed22260822
2024-12-31 19:28:57 +01:00
sfan5
a4d2633ac6 Minor improvements in ImageSource code 2024-12-31 14:47:46 +01:00
sfan5
f37f9a6f0b Optimize getImageAverageColor
also fixes a bug with non-square handling

before:
  getImageAverageColor [us] _____________________  804x  11.253

after:
  imageAverageColorInline [us] __________________  804x   0.557
2024-12-31 14:47:46 +01:00
sfan5
ded8c25e34 Change default post_processing_texture_bits to 10
Since the legacy GL driver is no longer the default,
we don't run into a situation where an unintended fallback to 8-bit happens.
2024-12-31 14:47:46 +01:00
sfan5
1a6ae148b7 Update texture_min_size description 2024-12-31 14:47:46 +01:00
sfan5
8c52d5f2dd Implement LODBias in GL3 driver
(currently unused)
2024-12-31 14:47:46 +01:00
sfan5
1ea8763259 Clean up Irrlicht shader API 2024-12-31 14:47:46 +01:00
sfan5
40afc84597 Replace data structure for HW buffer book-keeping
before
  time in endScene ÷ num hw buf ________________  199x   0.128
after
  time in endScene ÷ num hw buf ________________  199x   0.057
2024-12-31 14:47:46 +01:00
sfan5
a2058f7f3a Avoid some inefficiencies when handling ItemStack(Metadata) 2024-12-31 14:47:46 +01:00
sfan5
d884a1624f Show active HW buffers in profiler 2024-12-31 14:47:46 +01:00
grorp
b50b619be7
Add explanation to touchscreen item tooltip code (#15607)
this explains some cryptic inventory code I wrote in #14029 / 771da80bbb
2024-12-31 14:11:17 +01:00
grorp
27c3aade5d
TouchControls: More methods instead of static functions (#15602) 2024-12-30 19:03:32 +01:00
sfan5
f2b1cc3e61
Fix situation around aabbox3d default constructor (#15586)
Co-authored-by: JosiahWI <41302989+JosiahWI@users.noreply.github.com>
2024-12-29 14:36:30 +01:00
wrrrzr
cca65fde08
Controls: extract init_joysticks (#15597) 2024-12-28 22:05:01 +01:00
SmallJoker
35bc217ba8
IrrlichtMt: Move OpenGL 3+ transformation matrix to shaders (#15591)
This replaces annoying calculations on C++-side and eases the
implementation of 2D geometry batch rendering a lot.
2024-12-28 22:04:05 +01:00
Lars Müller
412cc96bc9
Fix some compiler warnings (#15596) 2024-12-26 11:29:00 +01:00
sfan5
d2a7875b5b Group sparse mesh buffers over entire scene for rendering 2024-12-24 15:27:08 +01:00
sfan5
612d4f9656 Improve quicktune feature a bit 2024-12-24 15:27:08 +01:00
sfan5
33b8307119 OpenGL: allow uploads of buffers to hardware ahead-of-time 2024-12-24 15:27:08 +01:00
sfan5
bb550158fc OpenGL: encapsulate VBOs into a class
internal only for now but this will be handy
2024-12-24 15:27:08 +01:00
Lars Müller
b087e2554f
Add glTF STEP interpolation support (#15525) 2024-12-24 15:25:07 +01:00
SmallJoker
d1dd044455
Reorder client initialization (#15554)
Previously, ServerEnv created a player instance before they're fully initialized.
This commit moves all initialization steps and callbacks into TOSERVER_CLIENT_READY
^ which includes StageTwoClientInit for player loading or creation
2024-12-24 15:24:56 +01:00
sfan5
c49ff76955
IGUIFont / CGUITTFont code cleanups (#15581) 2024-12-23 12:49:47 +01:00
sfan5
0bfd9bc09e Condense renderer information into a single string 2024-12-23 12:49:31 +01:00
sfan5
9f52f84f2b Prefer GL3 driver over legacy GL driver 2024-12-23 12:49:31 +01:00
cx384
83bc27d99d Move formspec code from game.cpp to separate file 2024-12-21 18:43:05 +01:00
sfan5
d4ccc8de79 Fix incorrect handling of skinned meshes as mesh nodes
fixes #15576
2024-12-20 19:04:56 +01:00
siliconsniffer
7bf0b1fc7e
Add server url button to main menu (#15536)
Co-authored-by: Zughy <63455151+Zughy@users.noreply.github.com>
2024-12-20 15:04:26 +01:00
sfan5
a6293b9861 Initial refactoring on shader usage and generation
`IShaderSource` was designed with the idea that if you want a shader,
you must want it for a node. So it depends heavily on being given a tile
material and the node drawtype. But this doesn't make sense neither in theory
nor in practice.
This commit takes a small step towards removing the incorrect abstraction.
2024-12-20 15:04:08 +01:00
sfan5
eb8beb335e Fix bloom with post_processing_texture_bits < 16 2024-12-20 15:04:08 +01:00
sfan5
7354cbe463 Fix core::array::reallocate when shrinking 2024-12-20 15:04:08 +01:00
cx384
f06383f78c
Minor API reference fixes 2024-12-20 15:03:55 +01:00
cx384
b172e67295
Remove game_ui from Client class 2024-12-20 15:03:45 +01:00
sfan5
10f1e142f6
Fix threshold value for imageCleanTransparent
fixes #15401
2024-12-20 15:03:30 +01:00
Lars Müller
a37bdbf8b7
Restore .x models to working state (#15550)
* Add "lava flan" (.x model) smoke test

* Fix double finalize in `.x` mesh loader

* Use reserve instead of resize again

The weights are added indirectly via `AnimatedMesh->addWeight`
2024-12-18 20:29:35 +01:00
Lars Müller
f99a1a7c7c Revert "Optimize raycast performance (#15233)"
This reverts commit f7a695c212.
2024-12-14 19:29:00 +01:00
Lars Müller
52a6673dab
Get rid of obsolete workaround for collision detection bugs (#15540) 2024-12-14 17:04:12 +01:00
Lars Müller
fef28aced9
Irrlicht: Get rid of obsolete setDebugName (#15541)
Co-authored-by: sfan5 <sfan5@live.de>
2024-12-14 17:03:08 +01:00
Lars Müller
23e502fa0e
Test & document conventions used by matrix4::setRotation* (#15542)
Also includes a minor `matrix4::transformVect` refactor to make testing easier.
2024-12-14 17:02:16 +01:00
sfence
f7a695c212
Optimize raycast performance (#15233)
by skipping nodes not on the ray with selection boxes smaller than 1x1x1 early on
2024-12-14 17:01:06 +01:00
Wuzzy
ba63c1505a
Docs: Change translation example from NS to PS (#15476)
The currently established convention uses `NS` for "translation no-ops", i.e., it will be collected by a string-collecting utility but not be translated by Luanti at this place.

We don't want to mislead modders with this example into using `NS` for plural forms instead, breaking with the established convention and making use of automated tools harder.

See also: https://github.com/minetest/modtools/pull/11
2024-12-14 16:59:29 +01:00
y5nw
ac7406c8a1
Fixup parsing for Plural-Forms (#15519) 2024-12-12 15:33:34 +01:00
Lars Müller
1e59b9a756
Refactor SkinnedMesh (#15522) 2024-12-12 15:33:08 +01:00
SmallJoker
d123bc0951
Main menu: show favorite removal button for offline servers (#15530)
This fixes a regression from 6c324cb871.
2024-12-12 15:31:48 +01:00
Timur1324
9f71e74158
Get server list over https (#15538) 2024-12-12 15:31:12 +01:00
DS
bcbee873e8
Use openssl's sha1 and sha256, optionally (#15472) 2024-12-10 22:00:43 +01:00
sfan5
4f800dd2b4 Change VoxelArea volume to be u32 2024-12-10 22:00:28 +01:00
sfan5
67126cbd1b Fix meaning of VoxelArea::hasEmptyExtent() 2024-12-10 22:00:28 +01:00
sfan5
8957739cdf Use appropriate sized type for VoxelArea extent 2024-12-10 22:00:28 +01:00
3c5e0d10fc Rotate meshnode normals correctly instead of recalculating 2024-12-10 22:00:18 +01:00
sfan5
21437090b8 Don't recalculate meshnode normals unnecessarily 2024-12-10 22:00:18 +01:00
siliconsniffer
eb6731bdc6
Main menu: Add server favorite button (#15486)
This adopts PR 13446.
2024-12-08 20:28:37 +01:00
SmallJoker
480eb7d816 Mapgen: Fix biome Y calculation regression
BiomeGen::getNextTransitionY(y) did not guarantee the condition (y < biome_y_min)
of the next loop because the function may return the value (biome_y_min - 1).
Hence, the biome was not updated until one Y coordinate after.
2024-12-08 20:27:33 +01:00
SmallJoker
50928b9759 Mapgen: Add rudimentary unittests 2024-12-08 20:27:33 +01:00
cx384
c7fe2ee5c9
Add core.spawn_tree_on_vmanip (#15415)
This function works like `core.spawn_tree`, but spawns an L-system tree onto a VoxelManip object instead on the map.
2024-12-08 20:27:22 +01:00
Lars Müller
8d43ad2522
Migrate rendered Lua API docs CNAME to api.luanti.org 2024-12-08 19:48:52 +01:00
Lars Müller
ae96a8d4fa
Fix mainmenu crash if no servers match search
fixes a regression caused by 6c324cb
2024-12-06 22:01:31 +01:00
veprogames
b857798848
Fix distorted Sun, Moon and Star visuals based on Orbit Tilt (#15459) 2024-12-06 22:00:06 +01:00
SmallJoker
5a8412dd23
Formspec: Move tooltip above cursor when lacking space (#15470) 2024-12-06 21:59:51 +01:00
cx384
88c845166c
Fix L-System trees fruit node regression (#15513) 2024-12-06 18:06:27 +01:00
Lars Müller
05d31222f7
Allow non-normalized weights in glTF models (#15310)
We are being lax here, but the glTF specification just requires that "when the weights are stored using float component type, their linear sum SHOULD be as close as reasonably possible to 1.0 for a given vertex"

In particular weights > 1 and weight sums well below or above 1 can be observed in models exported by Blender if they aren't manually normalized.
These fail the glTF validator but Irrlicht normalizes weights itself so we can support them just fine.

The docs have been updated to recommend normalizing weights (as well as documenting the status of interpolation support).

Weights < 0, most of them close to 0, also occur. Consistent with Irrlicht, we ignore them, but we also raise a warning.
2024-12-06 18:05:03 +01:00
Lars Müller
3e10d9ccf5
Refactor: Merge [IC]SkinnedMesh into SkinnedMesh (#15511) 2024-12-06 18:03:44 +01:00
sfan5
810f39767c Move SMaterial std::hash impl to its header 2024-12-04 18:20:34 +01:00
sfan5
a799a54894 Fix some issues with mt_opengl 2024-12-04 18:20:34 +01:00
sfan5
1fb7202028 GL: fix and clean up some code 2024-12-04 18:20:34 +01:00
sfan5
36edc3f161 Add 10-bit texture format and setting to chose PP color depth
(and move some settings to the advanced category)
2024-12-04 18:20:34 +01:00
AFCMS
e545e96d2b
Make string to v3f parsing consistent, replace core.setting_get_pos() by core.settings:get_pos() (#15438)
Co-authored-by: sfan5 <sfan5@live.de>
Co-authored-by: Lars Müller <34514239+appgurueu@users.noreply.github.com>
2024-12-04 18:19:46 +01:00
Lars Müller
18caf3a18d
Fix false positive compiler warning 2024-12-04 18:19:12 +01:00
HybridDog
a45b04ffb4
Less explicit memory management in Irrlicht image writer classes (#15493)
CImageWriterPNG::writeImage() and writeJPEGFile() explicitly allocate
and deallocate memory with `new` and `delete`, which is prone to programming errors.
The code also has non-functional error handling:
When memory allocation fails, `new` throws an `std::bad_alloc` exception
and never returns `nullptr`, so the check for `nullptr` is always false.

Co-authored-by: DS <ds.desour@proton.me>
2024-12-03 16:52:48 +01:00
JosiahWI
03813a5b5e
Use CMake list directives where appropriate
I think this communicates the intent a little better than using a `set`
directive, and it makes the code a little less verbose, too.
2024-12-03 16:52:15 +01:00
JosiahWI
818bca68d1
Use add_compile_options where appropriate 2024-12-03 16:51:53 +01:00
sfan5
a4d1b5b155
Fix script security path normalization in presence of links (#15481) 2024-12-03 16:51:34 +01:00
wrrrzr
e9080f91f2
Cleanup ban.cpp/h (#15496)
Make BanManager more const correctly
Delete unused includes
2024-12-01 20:52:13 +01:00
Kevin @ Sesam Solutions
7cc5a6ec68
Add Minetest keyword for backwards compatibility (#15491)
This helps people looking for `minetest`
2024-12-01 20:51:33 +01:00
JosiahWI
c3db9492a7
Update CMakeLists to use add_compile_definitions (#15483)
This is a newer feature introduced in CMake 3.12, which is now our
minimum version. It supercedes `add_definitions`. I've also replaced
some calls to set `CMAKE_<LANG>_FLAGS` that were used to set
definitions. This is a fairly trivial routine build maintenance that
is not intended to have any behavioral effects.
2024-11-29 12:02:48 +01:00
Lars Müller
d068f34753
Get rid of definitelyIdentityMatrix (#15480) 2024-11-29 12:00:09 +01:00
DS
df4e70b2c7
Add a setting to group transparency sorted triangles by buffer (#15115) 2024-11-28 14:22:53 +01:00
SmallJoker
c175046d30
Network: Fix serialization version checks (#15477)
This fixes some incorrect assumptions that the read and write version ranges are identical - whereas they're in fact not.
2024-11-27 18:39:57 +01:00
Lars Müller
6c324cb871
Main menu: Fix server selection (#15466)
Server selections are now always correct (no more arbitrarily changing selections if the order of the serverlist changes) and consistent with the address + port in the sidebar.
2024-11-27 18:39:28 +01:00
lhofhansl
8c56434bd3
Clamp pre-bloom color to valid range (#15453)
That avoids flashing artifacts when combining MSAA and bloom.
2024-11-25 11:56:32 -08:00
Lars Müller
b77ad82fb9
Sanitize invalid particle spawner time (#15465) 2024-11-24 19:23:53 +01:00
veprogames
11b19cd126
Doc: Add missing jpeg package for Arch Linux (#15461) 2024-11-24 19:23:32 +01:00
grorp
6a1d22b2c5
Implement an editor to customize the touchscreen controls (#14933)
- The editor is accessible via the pause menu and the settings menu.
- Buttons can be moved via drag & drop.
- Buttons can be added/removed. The grid menu added by #14918 is used to show
  all buttons not included in the layout.
- Custom layouts are responsive and adapt to changed screen size / DPI /
  hud_scaling.
- The layout is saved as JSON in the "touch_layout" setting.
2024-11-24 11:33:39 +01:00
luk3yx
4faa16fe0d
Clarify behaviour of core.hypertext_escape (#15464) 2024-11-22 17:56:35 +01:00
siliconsniffer
b6eaf7b5a4
Main menu: Player list for public servers (#15425) 2024-11-21 20:34:40 +01:00
Richard Try
946b3a4222
Typo in lua_api.md (#15440)
Duplicate text removed.
2024-11-20 18:36:35 +00:00
Christian Betancourt Dias
b63e988bd6
Fix naming conventions for CMatrix4::set(Inverse)RotationRadians() (#15204) 2024-11-19 13:38:19 +01:00
Lars Müller
15e8f9e6a0
Fix rendering regression with TGA type 1 files with BGRA8 color (#15402)
TGA uses BGR(A)8, stored in memory in that order. Irrlicht typically expects 0xAARRGGBB, which depends on endianness.
(This means that on little endian, no [B][G][R][A] -> 0xAARRGGBB conversion needs to be done, but Irrlicht was swapping the bytes.)

This makes both conversion functions consistently convert from [B][G][R]([A]) to 0xAARRGGBB (SColor), documents them properly and moves them to CImageLoaderTGA.cpp
so no poor soul shall be fooled by them in the near future.

---------

Co-authored-by: Ælla Chiana Moskopp <erle@dieweltistgarnichtso.net>
2024-11-19 13:37:05 +01:00
Lars Müller
138052adfc
Add particle blend mode "clip" (#15444)
This lets modders avoid alpha blending rendering bugs as well as potential (future) performance issues.
The appropriate blend modes are also used for node dig particles.

---------

Co-authored-by: sfan5 <sfan5@live.de>
2024-11-19 13:30:17 +01:00
sfan5
f493e73aeb Fix changing secure settings from mainmenu
forgotten in ea4ae55e24
closes #15454
2024-11-18 23:58:42 +01:00
grorp
9b6a399011
Implement support for FSAA in combination with post-processing (#15392)
- Actually it's MSAA I think, or perhaps the terms are equivalent
- I've made it fit into the existing Irrlicht architecture, but that has resulted in code duplication compared to my original "hacky" approach
- OpenGL 3.2+ and OpenGL ES 3.1+ are supported
- EDT_OPENGL3 is not required, EDT_OPENGL works too
- Helpful tutorial: https://learnopengl.com/Advanced-OpenGL/Anti-Aliasing, section "Off-screen MSAA"
- This may be rough around the edges, but in general it works
2024-11-18 14:06:48 +01:00
veprogames
a8ea165042
Replace occurences of 'wiki.minetest.net' with 'wiki.luanti.org' 2024-11-18 00:04:32 +01:00
HybridDog
7295b6c88c
Remove unused and rarely used irrlicht color functions (#15442)
SColor.h contains many functions which are unused and/or perform linear
operations on non-linear 8 bit sRGB color values, such as the plus operator and
`SColor::getInterpolated()`, and there is no documentation about missing gamma
correction.
Some of these functions are not called or called only once:
* `getAverage(s16 color)`: Unused
* `SColor::getLightness()`: Unused
* `SColor::getAverage()`: Claims to determine a color's average intensity but
  calculates something significantly different since SColor represents
  non-linear sRGB values.
* `SColor::getInterpolated_quadratic()`: Claims to interpolate between colors
  but uses the sRGB color space, which is neither physically nor perceptually
  linear.
* `SColorf::getInterpolated_quadratic()`: Unused
* `SColorf::setColorComponentValue()`: Unused

Removing or inlining these functions can simplify the code and documenting
gamma-incorrect operations can reduce confusion about what the functions do.

This commit does the following:
* Remove the above-mentioned unused functions
* Inline `SColor::getAverage()` into
  `CIrrDeviceLinux::TextureToMonochromeCursor()`
* Rename `SColor::getLuminance()` into `SColor::getBrightness()` since it does
  not determine a color's luminance but calculates something which differs
  significantly from physical luminance since SColor represents non-linear sRGB
  values.
* Inline `SColor::getInterpolated_quadratic()` into `GameUI::update()`,
  where it is only used for the alpha value calculation for fading
* Document gamma-incorrect behaviour in docstrings
2024-11-18 00:02:53 +01:00
sfan5
8d2e770361 Minor corrections in gl3/gles2 drivers 2024-11-16 16:54:22 +01:00
sfan5
cc8c3d501c Don't keep a copy of all texture images around 2024-11-16 16:54:22 +01:00
sfan5
58ccf0ba82 Fix some smaller issues with texture/image handling 2024-11-16 16:54:22 +01:00
sfan5
4aae31ad5e Add support for ECF_D24 texture format
and prefer it over D32 for our depth buffer, this can have performance benefits
2024-11-16 16:54:22 +01:00
sfan5
3c42cc8684 Revive texture download code and fix it on GLES 2024-11-16 16:54:22 +01:00
sfan5
11837d4623
Remove BMP image support (#15434)
Co-authored-by: Lars Mueller <appgurulars@gmx.de>
2024-11-15 12:21:30 +01:00
Erich Schubert
46f0baff09
Improve documentation of liquid_surface (#15012) 2024-11-15 12:19:41 +01:00
SmallJoker
8f03b70584 IrrlichtMt: Document Driver/Device compatibility 2024-11-15 12:18:48 +01:00
SmallJoker
4838eb2f7d Non-SDL: Add opengl3 support 2024-11-15 12:18:48 +01:00
SmallJoker
87ac32edea Dynamic shadows: whitelist the 'opengl3' driver 2024-11-15 12:18:48 +01:00
sfence
58dd42166d
Add some info to compiling README 2024-11-15 11:39:08 +01:00
grorp
a9fe83126a
Get rid of depth buffer workaround in the render pipeline code (#15407)
I originally wanted to get of the legacy IVideoDriver::setRenderTarget altogether,
but that ended up being too much work.
The remaining usage is in "dynamicshadowsrender.cpp".

Here's a comment I wrote about the workaround:

----------------------------------------

Use legacy call when there's single texture without depth texture
This means Irrlicht creates a depth texture for us and binds it to the FBO

This is currently necessary for a working depth buffer in the following cases:

- post-processing disabled, undersampling enabled
  (addUpscaling specifies no depth texture)

- post-processing disabled, 3d_mode = sidebyside / topbottom / crossview
  (populateSideBySidePipeline specifies no depth texture)

- post-processing disabled, 3d_mode = interlaced
  (probably, can't test since it's broken)
  (populateInterlacedPipeline specifies no depth texture)

With post-processing disabled, the world is rendered to the TextureBufferOutput
created in the functions listed above, so a depth buffer is needed
(-> this workaround is needed).
With post-processing enabled, only a fullscreen rectangle is rendered to
this TextureBufferOutput, so a depth buffer isn't actually needed.
But: These pipeline steps shouldn't rely on what ends up being rendered to
the TextureBufferOutput they provide, since that may change.

This workaround was added in 1e96403954 /
https://irc.minetest.net/minetest-dev/2022-10-04#i_6021940

This workaround should be replaced by explicitly configuring depth
textures where needed.

----------------------------------------
2024-11-15 11:38:56 +01:00
cx384
d4378a74d3
Fix register_ore ore_type error handling 2024-11-15 11:37:17 +01:00
sfan5
0c3117f9b3 Fix mainmenu settings crash caused by last commit
closes #15432
2024-11-13 18:39:10 +01:00
sfan5
794aea8e92
Drop fixed pipeline support code (#15421)
OpenGL 2.0 is now mandatory.
2024-11-13 14:24:01 +01:00
veprogames
0fde9ab7e8
Change minetest.net to luanti.org in 'Further documentation' 2024-11-13 14:23:39 +01:00
grorp
11e04ec113
Replace forgotten SEvent memset 2024-11-13 14:23:13 +01:00
sfan5
ea4ae55e24 Implement script sandboxing for main menu 2024-11-13 14:22:41 +01:00
sfan5
1fd4e0b82d Refactor ScriptApiSecurity for cleaner separation of concerns 2024-11-13 14:22:41 +01:00
Erich Schubert
4c44942a39
Add weights to biomes (#15142) 2024-11-12 10:53:17 +01:00
cx384
44b261d136
Luacheck: add VoxelManip to globals 2024-11-12 10:53:04 +01:00
sfan5
c00129360e Remove unused pos_max_d 2024-11-12 10:52:46 +01:00
sfan5
9a44d835d6 Remove redundant CollisionInfo::plane 2024-11-12 10:52:46 +01:00
sfan5
f916f5de78 Add basic unit tests for collisionMoveSimple 2024-11-12 10:52:46 +01:00
wrrrzr
1c92d6243f
MainMenuManager: fix FIXME (#15414) 2024-11-12 10:52:37 +01:00
grorp
af61de7777
Minor rendering code fixes (#15399)
* Fix line numbers in shader errors
* Fix uninitialized variables in shadow code
2024-11-12 10:52:20 +01:00
sfan5
a5e3fca40c Revert "Disable SDL2 for 5.10.0 (#15284)"
This reverts commit 6d7a519740.
2024-11-10 20:56:09 +01:00
sfan5
8503d8de5e Continue with 5.11.0-dev 2024-11-10 19:17:56 +01:00
397 changed files with 11390 additions and 8321 deletions

1
.gitattributes vendored
View File

@ -5,3 +5,4 @@
*.h diff=cpp *.h diff=cpp
*.gltf binary *.gltf binary
*.x binary

View File

@ -34,13 +34,6 @@ body:
render: "true" render: "true"
validations: validations:
required: true required: true
- type: input
attributes:
label: Irrlicht device
description:
placeholder: "Example: X11"
validations:
required: false
- type: input - type: input
attributes: attributes:
label: Operating system and version label: Operating system and version
@ -69,7 +62,7 @@ body:
attributes: attributes:
label: Active renderer label: Active renderer
description: You can find this in the "About" tab in the main menu. description: You can find this in the "About" tab in the main menu.
placeholder: "Example: OpenGL 4.6.0" placeholder: "Example: ES 3.2 / ogles2 / X11"
validations: validations:
required: false required: false
- type: textarea - type: textarea

View File

@ -49,6 +49,8 @@ jobs:
env: env:
CC: gcc-7 CC: gcc-7
CXX: g++-7 CXX: g++-7
# Test fallback SHA implementations
CMAKE_FLAGS: '-DENABLE_OPENSSL=0'
- name: Test - name: Test
run: | run: |

View File

@ -73,7 +73,7 @@ jobs:
env: env:
VCPKG_VERSION: 01f602195983451bc83e72f4214af2cbc495aa94 VCPKG_VERSION: 01f602195983451bc83e72f4214af2cbc495aa94
# 2024.05.24 # 2024.05.24
vcpkg_packages: zlib zstd curl[winssl] openal-soft libvorbis libogg libjpeg-turbo sqlite3 freetype luajit gmp jsoncpp opengl-registry vcpkg_packages: zlib zstd curl[winssl] openal-soft libvorbis libogg libjpeg-turbo sqlite3 freetype luajit gmp jsoncpp sdl2
strategy: strategy:
fail-fast: false fail-fast: false
matrix: matrix:

View File

@ -15,6 +15,7 @@ read_globals = {
"fgettext", "fgettext_ne", "fgettext", "fgettext_ne",
"vector", "vector",
"VoxelArea", "VoxelArea",
"VoxelManip",
"profiler", "profiler",
"Settings", "Settings",
"PerlinNoise", "PerlinNoiseMap", "PerlinNoise", "PerlinNoiseMap",

View File

@ -11,12 +11,12 @@ set(CLANG_MINIMUM_VERSION "7.0.1")
# You should not need to edit these manually, use util/bump_version.sh # You should not need to edit these manually, use util/bump_version.sh
set(VERSION_MAJOR 5) set(VERSION_MAJOR 5)
set(VERSION_MINOR 10) set(VERSION_MINOR 11)
set(VERSION_PATCH 0) set(VERSION_PATCH 0)
set(VERSION_EXTRA "" CACHE STRING "Stuff to append to version string") set(VERSION_EXTRA "" CACHE STRING "Stuff to append to version string")
# Change to false for releases # Change to false for releases
set(DEVELOPMENT_BUILD FALSE) set(DEVELOPMENT_BUILD TRUE)
set(VERSION_STRING "${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH}") set(VERSION_STRING "${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH}")
if(VERSION_EXTRA) if(VERSION_EXTRA)

2
CNAME
View File

@ -1 +1 @@
api.minetest.net api.luanti.org

View File

@ -63,6 +63,8 @@ Zughy:
textures/base/pack/settings_btn.png textures/base/pack/settings_btn.png
textures/base/pack/settings_info.png textures/base/pack/settings_info.png
textures/base/pack/settings_reset.png textures/base/pack/settings_reset.png
textures/base/pack/server_url.png
textures/base/pack/server_view_clients.png
appgurueu: appgurueu:
textures/base/pack/server_incompatible.png textures/base/pack/server_incompatible.png

View File

@ -25,8 +25,8 @@ Table of Contents
Further documentation Further documentation
---------------------- ----------------------
- Website: https://www.minetest.net/ - Website: https://www.luanti.org/
- Wiki: https://wiki.minetest.net/ - Wiki: https://wiki.luanti.org/
- Forum: https://forum.luanti.org/ - Forum: https://forum.luanti.org/
- GitHub: https://github.com/minetest/minetest/ - GitHub: https://github.com/minetest/minetest/
- [Developer documentation](doc/developing/) - [Developer documentation](doc/developing/)

View File

@ -1,7 +1,7 @@
// Top-level build file where you can add configuration options common to all sub-projects/modules. // Top-level build file where you can add configuration options common to all sub-projects/modules.
project.ext.set("versionMajor", 5) // Version Major project.ext.set("versionMajor", 5) // Version Major
project.ext.set("versionMinor", 10) // Version Minor project.ext.set("versionMinor", 11) // Version Minor
project.ext.set("versionPatch", 0) // Version Patch project.ext.set("versionPatch", 0) // Version Patch
// ^ keep in sync with cmake // ^ keep in sync with cmake

View File

@ -43,6 +43,8 @@ core.features = {
hotbar_hud_element = true, hotbar_hud_element = true,
bulk_lbms = true, bulk_lbms = true,
abm_without_neighbors = true, abm_without_neighbors = true,
biome_weights = true,
particle_blend_clip = true,
} }
function core.has_feature(arg) function core.has_feature(arg)

View File

@ -36,11 +36,7 @@ end
function core.setting_get_pos(name) function core.setting_get_pos(name)
local value = core.settings:get(name) return core.settings:get_pos(name)
if not value then
return nil
end
return core.string_to_pos(value)
end end

View File

@ -1,7 +1,7 @@
local static_spawnpoint_string = core.settings:get("static_spawnpoint") local static_spawnpoint_string = core.settings:get("static_spawnpoint")
if static_spawnpoint_string and if static_spawnpoint_string and
static_spawnpoint_string ~= "" and static_spawnpoint_string ~= "" and
not core.setting_get_pos("static_spawnpoint") then not core.settings:get_pos("static_spawnpoint") then
error('The static_spawnpoint setting is invalid: "' .. error('The static_spawnpoint setting is invalid: "' ..
static_spawnpoint_string .. '"') static_spawnpoint_string .. '"')
end end

View File

@ -11,11 +11,6 @@ end
core.async_event_handler = handle_job core.async_event_handler = handle_job
function core.handle_async(func, parameter, callback) function core.handle_async(func, parameter, callback)
-- Serialize function
local serialized_func = string.dump(func)
assert(serialized_func ~= nil)
-- Serialize parameters -- Serialize parameters
local serialized_param = core.serialize(parameter) local serialized_param = core.serialize(parameter)
@ -23,7 +18,7 @@ function core.handle_async(func, parameter, callback)
return false return false
end end
local jobid = core.do_async_callback(serialized_func, serialized_param) local jobid = core.do_async_callback(func, serialized_param)
core.async_jobs[jobid] = callback core.async_jobs[jobid] = callback

View File

@ -392,7 +392,7 @@ function contentdb.resolve_dependencies(package, game, callback)
end end
local function fetch_pkgs(params) local function fetch_pkgs()
local version = core.get_version() local version = core.get_version()
local base_url = core.settings:get("contentdb_url") local base_url = core.settings:get("contentdb_url")
local url = base_url .. local url = base_url ..
@ -429,41 +429,43 @@ local function fetch_pkgs(params)
if not packages or #packages == 0 then if not packages or #packages == 0 then
return return
end end
local aliases = {} return packages
end
function contentdb.set_packages_from_api(packages)
contentdb.package_by_id = {}
contentdb.aliases = {}
for _, package in pairs(packages) do for _, package in pairs(packages) do
package.id = params.calculate_package_id(package.type, package.author, package.name) package.id = contentdb.calculate_package_id(package.type, package.author, package.name)
package.url_part = core.urlencode(package.author) .. "/" .. core.urlencode(package.name) package.url_part = core.urlencode(package.author) .. "/" .. core.urlencode(package.name)
contentdb.package_by_id[package.id] = package
if package.aliases then if package.aliases then
for _, alias in ipairs(package.aliases) do for _, alias in ipairs(package.aliases) do
-- We currently don't support name changing -- We currently don't support name changing
local suffix = "/" .. package.name local suffix = "/" .. package.name
if alias:sub(-#suffix) == suffix then if alias:sub(-#suffix) == suffix then
aliases[alias:lower()] = package.id contentdb.aliases[alias:lower()] = package.id
end end
end end
end end
end end
return { packages = packages, aliases = aliases } contentdb.load_ok = true
contentdb.load_error = false
contentdb.packages = packages
contentdb.packages_full = packages
contentdb.packages_full_unordered = packages
end end
function contentdb.fetch_pkgs(callback) function contentdb.fetch_pkgs(callback)
contentdb.loading = true contentdb.loading = true
core.handle_async(fetch_pkgs, { calculate_package_id = contentdb.calculate_package_id }, function(result) core.handle_async(fetch_pkgs, nil, function(result)
if result then if result then
contentdb.load_ok = true contentdb.set_packages_from_api(result)
contentdb.load_error = false
contentdb.packages = result.packages
contentdb.packages_full = result.packages
contentdb.packages_full_unordered = result.packages
contentdb.aliases = result.aliases
for _, package in ipairs(result.packages) do
contentdb.package_by_id[package.id] = package
end
else else
contentdb.load_error = true contentdb.load_error = true
end end

View File

@ -0,0 +1,49 @@
-- Luanti
-- Copyright (C) 2024 siliconsniffer
-- SPDX-License-Identifier: LGPL-2.1-or-later
local function clients_list_formspec(dialogdata)
local TOUCH_GUI = core.settings:get_bool("touch_gui")
local clients_list = dialogdata.server.clients_list
local servername = dialogdata.server.name
local function fmt_formspec_list(clients_list)
local escaped = {}
for i, str in ipairs(clients_list) do
escaped[i] = core.formspec_escape(str)
end
return table.concat(escaped, ",")
end
local formspec = {
"formspec_version[8]",
"size[6,9.5]",
TOUCH_GUI and "padding[0.01,0.01]" or "",
"hypertext[0,0;6,1.5;;<global margin=5 halign=center valign=middle>",
fgettext("This is the list of clients connected to\n$1",
"<b>" .. core.hypertext_escape(servername) .. "</b>") .. "]",
"textlist[0.5,1.5;5,6.8;;" .. fmt_formspec_list(clients_list) .. "]",
"button[1.5,8.5;3,0.8;quit;OK]"
}
return table.concat(formspec, "")
end
local function clients_list_buttonhandler(this, fields)
if fields.quit then
this:delete()
return true
end
return false
end
function create_clientslist_dialog(server)
local retval = dialog_create("dlg_clients_list",
clients_list_formspec,
clients_list_buttonhandler,
nil)
retval.data.server = server
return retval
end

View File

@ -55,6 +55,7 @@ dofile(menupath .. DIR_DELIM .. "dlg_register.lua")
dofile(menupath .. DIR_DELIM .. "dlg_rename_modpack.lua") dofile(menupath .. DIR_DELIM .. "dlg_rename_modpack.lua")
dofile(menupath .. DIR_DELIM .. "dlg_version_info.lua") dofile(menupath .. DIR_DELIM .. "dlg_version_info.lua")
dofile(menupath .. DIR_DELIM .. "dlg_reinstall_mtg.lua") dofile(menupath .. DIR_DELIM .. "dlg_reinstall_mtg.lua")
dofile(menupath .. DIR_DELIM .. "dlg_clients_list.lua")
local tabs = { local tabs = {
content = dofile(menupath .. DIR_DELIM .. "tab_content.lua"), content = dofile(menupath .. DIR_DELIM .. "tab_content.lua"),
@ -133,4 +134,5 @@ local function init_globals()
check_new_version() check_new_version()
end end
assert(os.execute == nil)
init_globals() init_globals()

View File

@ -19,8 +19,6 @@
local component_funcs = dofile(core.get_mainmenu_path() .. DIR_DELIM .. local component_funcs = dofile(core.get_mainmenu_path() .. DIR_DELIM ..
"settings" .. DIR_DELIM .. "components.lua") "settings" .. DIR_DELIM .. "components.lua")
local shader_warning_component = dofile(core.get_mainmenu_path() .. DIR_DELIM ..
"settings" .. DIR_DELIM .. "shader_warning_component.lua")
local shadows_component = dofile(core.get_mainmenu_path() .. DIR_DELIM .. local shadows_component = dofile(core.get_mainmenu_path() .. DIR_DELIM ..
"settings" .. DIR_DELIM .. "shadows_component.lua") "settings" .. DIR_DELIM .. "shadows_component.lua")
@ -125,6 +123,22 @@ local function load()
end, end,
} }
local touchscreen_layout = {
query_text = "Touchscreen layout",
requires = {
touchscreen = true,
},
get_formspec = function(self, avail_w)
local btn_w = math.min(avail_w, 6)
return ("button[0,0;%f,0.8;btn_touch_layout;%s]"):format(btn_w, fgettext("Touchscreen layout")), 0.8
end,
on_submit = function(self, fields)
if fields.btn_touch_layout then
core.show_touchscreen_layout()
end
end,
}
add_page({ add_page({
id = "accessibility", id = "accessibility",
title = fgettext_ne("Accessibility"), title = fgettext_ne("Accessibility"),
@ -153,13 +167,10 @@ local function load()
load_settingtypes() load_settingtypes()
table.insert(page_by_id.controls_keyboard_and_mouse.content, 1, change_keys) table.insert(page_by_id.controls_keyboard_and_mouse.content, 1, change_keys)
-- insert after "touch_controls"
table.insert(page_by_id.controls_touchscreen.content, 2, touchscreen_layout)
do do
local content = page_by_id.graphics_and_audio_graphics.content local content = page_by_id.graphics_and_audio_effects.content
table.insert(content, 1, shader_warning_component)
content = page_by_id.graphics_and_audio_effects.content
table.insert(content, 1, shader_warning_component)
local idx = table.indexof(content, "enable_dynamic_shadows") local idx = table.indexof(content, "enable_dynamic_shadows")
table.insert(content, idx, shadows_component) table.insert(content, idx, shadows_component)
@ -348,7 +359,6 @@ local function check_requirements(name, requires)
end end
local video_driver = core.get_active_driver() local video_driver = core.get_active_driver()
local shaders_support = video_driver == "opengl" or video_driver == "opengl3" or video_driver == "ogles2"
local touch_support = core.irrlicht_device_supports_touch() local touch_support = core.irrlicht_device_supports_touch()
local touch_controls = core.settings:get("touch_controls") local touch_controls = core.settings:get("touch_controls")
local special = { local special = {
@ -359,9 +369,7 @@ local function check_requirements(name, requires)
-- be used, so we show settings for both. -- be used, so we show settings for both.
touchscreen = touch_support and (touch_controls == "auto" or core.is_yes(touch_controls)), touchscreen = touch_support and (touch_controls == "auto" or core.is_yes(touch_controls)),
keyboard_mouse = not touch_support or (touch_controls == "auto" or not core.is_yes(touch_controls)), keyboard_mouse = not touch_support or (touch_controls == "auto" or not core.is_yes(touch_controls)),
shaders_support = shaders_support, opengl = (video_driver == "opengl" or video_driver == "opengl3"),
shaders = core.settings:get_bool("enable_shaders") and shaders_support,
opengl = video_driver == "opengl",
gles = video_driver:sub(1, 5) == "ogles", gles = video_driver:sub(1, 5) == "ogles",
} }
@ -369,7 +377,7 @@ local function check_requirements(name, requires)
if special[req_key] == nil then if special[req_key] == nil then
local required_setting = get_setting_info(req_key) local required_setting = get_setting_info(req_key)
if required_setting == nil then if required_setting == nil then
core.log("warning", "Unknown setting " .. req_key .. " required by " .. name) core.log("warning", "Unknown setting " .. req_key .. " required by " .. (name or "???"))
end end
local actual_value = core.settings:get_bool(req_key, local actual_value = core.settings:get_bool(req_key,
required_setting and core.is_yes(required_setting.default)) required_setting and core.is_yes(required_setting.default))

View File

@ -16,7 +16,7 @@ local minetest_example_header = [[
# to the program, eg. "luanti.exe --config ../minetest.conf.example". # to the program, eg. "luanti.exe --config ../minetest.conf.example".
# Further documentation: # Further documentation:
# https://wiki.minetest.net/ # https://wiki.luanti.org/
]] ]]

View File

@ -1,26 +0,0 @@
-- Luanti
-- SPDX-License-Identifier: LGPL-2.1-or-later
return {
query_text = "Shaders",
requires = {
shaders_support = true,
shaders = false,
},
full_width = true,
get_formspec = function(self, avail_w)
local fs = {
"box[0,0;", avail_w, ",1.2;", mt_color_orange, "]",
"label[0.2,0.4;", fgettext("Shaders are disabled."), "]",
"label[0.2,0.8;", fgettext("This is not a recommended configuration."), "]",
"button[", avail_w - 2.2, ",0.2;2,0.8;fix_shader_warning;", fgettext("Enable"), "]",
}
return table.concat(fs, ""), 1.2
end,
on_submit = function(self, fields)
if fields.fix_shader_warning then
core.settings:remove("enable_shaders") -- default value is true
return true
end
end,
}

View File

@ -82,7 +82,6 @@ end
return { return {
query_text = "Shadows", query_text = "Shadows",
requires = { requires = {
shaders = true,
opengl = true, opengl = true,
}, },
get_formspec = function(self, avail_w) get_formspec = function(self, avail_w)

View File

@ -32,6 +32,27 @@ local function get_credits()
return json return json
end end
local function get_renderer_info()
local ret = {}
-- OpenGL version, stripped to just the important part
local s1 = core.get_active_renderer()
if s1:sub(1, 7) == "OpenGL " then
s1 = s1:sub(8)
end
local m = s1:match("^[%d.]+")
if not m then
m = s1:match("^ES [%d.]+")
end
ret[#ret+1] = m or s1
-- video driver
ret[#ret+1] = core.get_active_driver():lower()
-- irrlicht device
ret[#ret+1] = core.get_active_irrlicht_device():upper()
return table.concat(ret, " / ")
end
return { return {
name = "about", name = "about",
caption = fgettext("About"), caption = fgettext("About"),
@ -81,20 +102,12 @@ return {
"button_url[1.5,4.1;2.5,0.8;homepage;luanti.org;https://www.luanti.org/]" .. "button_url[1.5,4.1;2.5,0.8;homepage;luanti.org;https://www.luanti.org/]" ..
"hypertext[5.5,0.25;9.75,6.6;credits;" .. core.formspec_escape(hypertext) .. "]" "hypertext[5.5,0.25;9.75,6.6;credits;" .. core.formspec_escape(hypertext) .. "]"
-- Render information local active_renderer_info = fgettext("Active renderer:") .. "\n" ..
local active_renderer_info = fgettext("Active renderer:") .. " " .. core.formspec_escape(get_renderer_info())
core.formspec_escape(core.get_active_renderer())
fs = fs .. "style[label_button2;border=false]" .. fs = fs .. "style[label_button2;border=false]" ..
"button[0.1,6;5.3,0.5;label_button2;" .. active_renderer_info .. "]".. "button[0.1,6;5.3,1;label_button2;" .. active_renderer_info .. "]"..
"tooltip[label_button2;" .. active_renderer_info .. "]" "tooltip[label_button2;" .. active_renderer_info .. "]"
-- Irrlicht device information
local irrlicht_device_info = fgettext("Irrlicht device:") .. " " ..
core.formspec_escape(core.get_active_irrlicht_device())
fs = fs .. "style[label_button3;border=false]" ..
"button[0.1,6.5;5.3,0.5;label_button3;" .. irrlicht_device_info .. "]"..
"tooltip[label_button3;" .. irrlicht_device_info .. "]"
if PLATFORM == "Android" then if PLATFORM == "Android" then
fs = fs .. "button[0.5,5.1;4.5,0.8;share_debug;" .. fgettext("Share debug log") .. "]" fs = fs .. "button[0.5,5.1;4.5,0.8;share_debug;" .. fgettext("Share debug log") .. "]"
else else

View File

@ -55,6 +55,51 @@ local function get_sorted_servers()
return servers return servers
end end
local function is_selected_fav(server)
local address = core.settings:get("address")
local port = tonumber(core.settings:get("remote_port"))
for _, fav in ipairs(serverlistmgr.get_favorites()) do
if address == fav.address and port == fav.port then
return true
end
end
return false
end
-- Persists the selected server in the "address" and "remote_port" settings
local function set_selected_server(server)
if server == nil then -- reset selection
core.settings:remove("address")
core.settings:remove("remote_port")
return
end
local address = server.address
local port = server.port
gamedata.serverdescription = server.description
if address and port then
core.settings:set("address", address)
core.settings:set("remote_port", port)
end
end
local function find_selected_server()
local address = core.settings:get("address")
local port = tonumber(core.settings:get("remote_port"))
for _, server in ipairs(serverlistmgr.servers) do
if server.address == address and server.port == port then
return server
end
end
for _, server in ipairs(serverlistmgr.get_favorites()) do
if server.address == address and server.port == port then
return server
end
end
end
local function get_formspec(tabview, name, tabdata) local function get_formspec(tabview, name, tabdata)
-- Update the cached supported proto info, -- Update the cached supported proto info,
-- it may have changed after a change by the settings menu. -- it may have changed after a change by the settings menu.
@ -67,6 +112,7 @@ local function get_formspec(tabview, name, tabdata)
local retval = local retval =
-- Search -- Search
"field[0.25,0.25;7,0.75;te_search;;" .. core.formspec_escape(tabdata.search_for) .. "]" .. "field[0.25,0.25;7,0.75;te_search;;" .. core.formspec_escape(tabdata.search_for) .. "]" ..
"tooltip[te_search;" .. fgettext("Possible filters\ngame:<name>\nmod:<name>\nplayer:<name>") .. "]" ..
"field_enter_after_edit[te_search;true]" .. "field_enter_after_edit[te_search;true]" ..
"container[7.25,0.25]" .. "container[7.25,0.25]" ..
"image_button[0,0;0.75,0.75;" .. core.formspec_escape(defaulttexturedir .. "search.png") .. ";btn_mp_search;]" .. "image_button[0,0;0.75,0.75;" .. core.formspec_escape(defaulttexturedir .. "search.png") .. ";btn_mp_search;]" ..
@ -107,17 +153,51 @@ local function get_formspec(tabview, name, tabdata)
retval = retval .. "button[0.25,6;2.5,0.75;btn_mp_register;" .. fgettext("Register") .. "]" retval = retval .. "button[0.25,6;2.5,0.75;btn_mp_register;" .. fgettext("Register") .. "]"
end end
if tabdata.selected then local selected_server = find_selected_server()
if gamedata.fav then
retval = retval .. "tooltip[btn_delete_favorite;" .. fgettext("Remove favorite") .. "]" if selected_server then
retval = retval .. "style[btn_delete_favorite;padding=6]"
retval = retval .. "image_button[5,1.3;0.5,0.5;" .. core.formspec_escape(defaulttexturedir ..
"server_favorite_delete.png") .. ";btn_delete_favorite;]"
end
if gamedata.serverdescription then if gamedata.serverdescription then
retval = retval .. "textarea[0.25,1.85;5.25,2.7;;;" .. retval = retval .. "textarea[0.25,1.85;5.25,2.7;;;" ..
core.formspec_escape(gamedata.serverdescription) .. "]" core.formspec_escape(gamedata.serverdescription) .. "]"
end end
local clients_list = selected_server.clients_list
local can_view_clients_list = clients_list and #clients_list > 0
if can_view_clients_list then
table.sort(clients_list, function(a, b)
return a:lower() < b:lower()
end)
local max_clients = 5
if #clients_list > max_clients then
retval = retval .. "tooltip[btn_view_clients;" ..
fgettext("Clients:\n$1", table.concat(clients_list, "\n", 1, max_clients)) .. "\n..." .. "]"
else
retval = retval .. "tooltip[btn_view_clients;" ..
fgettext("Clients:\n$1", table.concat(clients_list, "\n")) .. "]"
end
retval = retval .. "style[btn_view_clients;padding=6]"
retval = retval .. "image_button[4.5,1.3;0.5,0.5;" .. core.formspec_escape(defaulttexturedir ..
"server_view_clients.png") .. ";btn_view_clients;]"
end
if selected_server.url then
retval = retval .. "tooltip[btn_server_url;" .. fgettext("Open server website") .. "]"
retval = retval .. "style[btn_server_url;padding=6]"
retval = retval .. "image_button[" .. (can_view_clients_list and "4" or "4.5") .. ",1.3;0.5,0.5;" ..
core.formspec_escape(defaulttexturedir .. "server_url.png") .. ";btn_server_url;]"
end
if is_selected_fav() then
retval = retval .. "tooltip[btn_delete_favorite;" .. fgettext("Remove favorite") .. "]"
retval = retval .. "style[btn_delete_favorite;padding=6]"
retval = retval .. "image_button[5,1.3;0.5,0.5;" ..
core.formspec_escape(defaulttexturedir .. "server_favorite_delete.png") .. ";btn_delete_favorite;]"
else
retval = retval .. "tooltip[btn_add_favorite;" .. fgettext("Add favorite") .. "]"
retval = retval .. "style[btn_add_favorite;padding=6]"
retval = retval .. "image_button[5,1.3;0.5,0.5;" ..
core.formspec_escape(defaulttexturedir .. "server_favorite.png") .. ";btn_add_favorite;]"
end
end end
retval = retval .. "container_end[]" retval = retval .. "container_end[]"
@ -175,30 +255,123 @@ local function get_formspec(tabview, name, tabdata)
retval = retval .. table.concat(rows, ",") retval = retval .. table.concat(rows, ",")
if tabdata.selected then local selected_row_idx = 0
retval = retval .. ";" .. tabdata.selected .. "]" if selected_server then
else for i, server in pairs(tabdata.lookup) do
retval = retval .. ";0]" if selected_server.address == server.address and
selected_server.port == server.port then
selected_row_idx = i
break
end
end
end end
retval = retval .. ";" .. selected_row_idx .. "]"
return retval return retval
end end
-------------------------------------------------------------------------------- --------------------------------------------------------------------------------
local function parse_search_input(input)
if not input:find("%S") then
return -- Return nil if nothing to search for
end
-- Search is not case sensitive
input = input:lower()
local query = {keywords = {}, mods = {}, players = {}}
-- Process quotation enclosed parts
input = input:gsub('(%S?)"([^"]*)"(%S?)', function(before, match, after)
if before == "" and after == "" then -- Also have be separated by spaces
table.insert(query.keywords, match)
return " "
end
return before..'"'..match..'"'..after
end)
-- Separate by space characters and handle special prefixes
-- (words with special prefixes need an exact match and none of them can contain spaces)
for word in input:gmatch("%S+") do
local mod = word:match("^mod:(.*)")
table.insert(query.mods, mod)
local player = word:match("^player:(.*)")
table.insert(query.players, player)
local game = word:match("^game:(.*)")
query.game = query.game or game
if not (mod or player or game) then
table.insert(query.keywords, word)
end
end
return query
end
-- Prepares the server to be used for searching
local function uncapitalize_server(server)
local function table_lower(t)
local r = {}
for i, s in ipairs(t or {}) do
r[i] = s:lower()
end
return r
end
return {
name = (server.name or ""):lower(),
description = (server.description or ""):lower(),
gameid = (server.gameid or ""):lower(),
mods = table_lower(server.mods),
clients_list = table_lower(server.clients_list),
}
end
-- Returns false if the query does not match
-- otherwise returns a number to adjust the sorting priority
local function matches_query(server, query)
-- Search is not case sensitive
server = uncapitalize_server(server)
-- Check if mods found
for _, mod in ipairs(query.mods) do
if table.indexof(server.mods, mod) < 0 then
return false
end
end
-- Check if players found
for _, player in ipairs(query.players) do
if table.indexof(server.clients_list, player) < 0 then
return false
end
end
-- Check if game matches
if query.game and query.game ~= server.gameid then
return false
end
-- Check if keyword found
local name_matches = true
local description_matches = true
for _, keyword in ipairs(query.keywords) do
name_matches = name_matches and server.name:find(keyword, 1, true)
description_matches = description_matches and server.description:find(keyword, 1, true)
end
return name_matches and 50 or description_matches and 0
end
local function search_server_list(input) local function search_server_list(input)
menudata.search_result = nil menudata.search_result = nil
if #serverlistmgr.servers < 2 then if #serverlistmgr.servers < 2 then
return return
end end
-- setup the keyword list -- setup the search query
local keywords = {} local query = parse_search_input(input)
for word in input:gmatch("%S+") do if not query then
table.insert(keywords, word:lower())
end
if #keywords == 0 then
return return
end end
@ -207,16 +380,9 @@ local function search_server_list(input)
-- Search the serverlist -- Search the serverlist
local search_result = {} local search_result = {}
for i, server in ipairs(serverlistmgr.servers) do for i, server in ipairs(serverlistmgr.servers) do
local name_matches, description_matches = true, true local match = matches_query(server, query)
for _, keyword in ipairs(keywords) do if match then
name_matches = name_matches and not not server.points = #serverlistmgr.servers - i + match
(server.name or ""):lower():find(keyword, 1, true)
description_matches = description_matches and not not
(server.description or ""):lower():find(keyword, 1, true)
end
if name_matches or description_matches then
server.points = #serverlistmgr.servers - i
+ (name_matches and 50 or 0)
table.insert(search_result, server) table.insert(search_result, server)
end end
end end
@ -231,35 +397,6 @@ local function search_server_list(input)
menudata.search_result = search_result menudata.search_result = search_result
end end
local function set_selected_server(tabdata, idx, server)
-- reset selection
if idx == nil or server == nil then
tabdata.selected = nil
core.settings:set("address", "")
core.settings:set("remote_port", "30000")
return
end
local address = server.address
local port = server.port
gamedata.serverdescription = server.description
gamedata.fav = false
for _, fav in ipairs(serverlistmgr.get_favorites()) do
if address == fav.address and port == fav.port then
gamedata.fav = true
break
end
end
if address and port then
core.settings:set("address", address)
core.settings:set("remote_port", port)
end
tabdata.selected = idx
end
local function main_button_handler(tabview, fields, name, tabdata) local function main_button_handler(tabview, fields, name, tabdata)
if fields.te_name then if fields.te_name then
gamedata.playername = fields.te_name gamedata.playername = fields.te_name
@ -290,19 +427,23 @@ local function main_button_handler(tabview, fields, name, tabdata)
gamedata.serverdescription = server.description gamedata.serverdescription = server.description
if gamedata.address and gamedata.port then if gamedata.address and gamedata.port then
core.settings:set("address", gamedata.address) set_selected_server(server)
core.settings:set("remote_port", gamedata.port)
core.start() core.start()
end end
return true return true
end end
if event.type == "CHG" then if event.type == "CHG" then
set_selected_server(tabdata, event.row, server) set_selected_server(server)
return true return true
end end
end end
end end
if fields.btn_add_favorite then
serverlistmgr.add_favorite(find_selected_server())
return true
end
if fields.btn_delete_favorite then if fields.btn_delete_favorite then
local idx = core.get_table_index("servers") local idx = core.get_table_index("servers")
if not idx then return end if not idx then return end
@ -310,8 +451,20 @@ local function main_button_handler(tabview, fields, name, tabdata)
if not server then return end if not server then return end
serverlistmgr.delete_favorite(server) serverlistmgr.delete_favorite(server)
-- the server at [idx+1] will be at idx once list is refreshed set_selected_server(server)
set_selected_server(tabdata, idx, tabdata.lookup[idx+1]) return true
end
if fields.btn_server_url then
core.open_url_dialog(find_selected_server().url)
return true
end
if fields.btn_view_clients then
local dlg = create_clientslist_dialog(find_selected_server())
dlg:set_parent(tabview)
tabview:hide()
dlg:show()
return true return true
end end
@ -323,10 +476,10 @@ local function main_button_handler(tabview, fields, name, tabdata)
if fields.btn_mp_search or fields.key_enter_field == "te_search" then if fields.btn_mp_search or fields.key_enter_field == "te_search" then
tabdata.search_for = fields.te_search tabdata.search_for = fields.te_search
search_server_list(fields.te_search:lower()) search_server_list(fields.te_search)
if menudata.search_result then if menudata.search_result then
-- first server in row 2 due to header -- Note: This clears the selection if there are no results
set_selected_server(tabdata, 2, menudata.search_result[1]) set_selected_server(menudata.search_result[1])
end end
return true return true
@ -353,8 +506,6 @@ local function main_button_handler(tabview, fields, name, tabdata)
local idx = core.get_table_index("servers") local idx = core.get_table_index("servers")
local server = idx and tabdata.lookup[idx] local server = idx and tabdata.lookup[idx]
set_selected_server(tabdata)
if server and server.address == gamedata.address and if server and server.address == gamedata.address and
server.port == gamedata.port then server.port == gamedata.port then

View File

@ -61,7 +61,7 @@
# #
# # This is a comment # # This is a comment
# # # #
# # Requires: shaders, enable_dynamic_shadows, !enable_waving_leaves # # Requires: enable_dynamic_shadows, !enable_waving_leaves
# name (Readable name) type type_args # name (Readable name) type type_args
# #
# A requirement can be the name of a boolean setting or an engine-defined value. # A requirement can be the name of a boolean setting or an engine-defined value.
@ -69,8 +69,6 @@
# #
# * The value of a boolean setting, such as enable_dynamic_shadows # * The value of a boolean setting, such as enable_dynamic_shadows
# * An engine-defined value: # * An engine-defined value:
# * shaders_support (a video driver that supports shaders, may not be enabled)
# * shaders (both enable_shaders and shaders_support)
# * desktop / android # * desktop / android
# * touchscreen / keyboard_mouse # * touchscreen / keyboard_mouse
# * opengl / gles # * opengl / gles
@ -79,8 +77,11 @@
# Sections are marked by a single line in the format: [Section Name] # Sections are marked by a single line in the format: [Section Name]
# Sub-section are marked by adding * in front of the section name: [*Sub-section] # Sub-section are marked by adding * in front of the section name: [*Sub-section]
# Sub-sub-sections have two * etc. # Sub-sub-sections have two * etc.
# There shouldn't be too much settings per category; settings that shouldn't be # There shouldn't be too many settings per category.
# modified by the "average user" should be in (sub-)categories called "Advanced". #
# The top-level categories "Advanced", "Client and Server" and "Mapgen" are
# handled specially and its contents only shown when a checkbox is checked.
# They contain settings not intended for the "average user".
[Controls] [Controls]
@ -265,6 +266,8 @@ viewing_range (Viewing range) int 190 20 4000
# to the game world only, keeping the GUI intact. # to the game world only, keeping the GUI intact.
# It should give a significant performance boost at the cost of less detailed image. # It should give a significant performance boost at the cost of less detailed image.
# Higher values result in a less detailed image. # Higher values result in a less detailed image.
# Note: Undersampling is currently not supported if the "3d_mode" setting is set
# to a non-default value.
undersampling (Undersampling) int 1 1 8 undersampling (Undersampling) int 1 1 8
[**3D] [**3D]
@ -277,7 +280,6 @@ undersampling (Undersampling) int 1 1 8
# - topbottom: split screen top/bottom. # - topbottom: split screen top/bottom.
# - sidebyside: split screen side by side. # - sidebyside: split screen side by side.
# - crossview: Cross-eyed 3d # - crossview: Cross-eyed 3d
# Note that the interlaced mode requires shaders to be enabled.
3d_mode (3D mode) enum none none,anaglyph,interlaced,topbottom,sidebyside,crossview 3d_mode (3D mode) enum none none,anaglyph,interlaced,topbottom,sidebyside,crossview
# Strength of 3D mode parallax. # Strength of 3D mode parallax.
@ -404,6 +406,7 @@ bilinear_filter (Bilinear filtering) bool false
trilinear_filter (Trilinear filtering) bool false trilinear_filter (Trilinear filtering) bool false
# Use anisotropic filtering when looking at textures from an angle. # Use anisotropic filtering when looking at textures from an angle.
# This provides a significant improvement when used together with mipmapping.
anisotropic_filter (Anisotropic filtering) bool false anisotropic_filter (Anisotropic filtering) bool false
# Select the antialiasing method to apply. # Select the antialiasing method to apply.
@ -411,16 +414,18 @@ anisotropic_filter (Anisotropic filtering) bool false
# * None - No antialiasing (default) # * None - No antialiasing (default)
# #
# * FSAA - Hardware-provided full-screen antialiasing # * FSAA - Hardware-provided full-screen antialiasing
# (incompatible with Post Processing and Undersampling)
# A.K.A multi-sample antialiasing (MSAA) # A.K.A multi-sample antialiasing (MSAA)
# Smoothens out block edges but does not affect the insides of textures. # Smoothens out block edges but does not affect the insides of textures.
# A restart is required to change this option.
# #
# * FXAA - Fast approximate antialiasing (requires shaders) # If Post Processing is disabled, changing FSAA requires a restart.
# Also, if Post Processing is disabled, FSAA will not work together with
# undersampling or a non-default "3d_mode" setting.
#
# * FXAA - Fast approximate antialiasing
# Applies a post-processing filter to detect and smoothen high-contrast edges. # Applies a post-processing filter to detect and smoothen high-contrast edges.
# Provides balance between speed and image quality. # Provides balance between speed and image quality.
# #
# * SSAA - Super-sampling antialiasing (requires shaders) # * SSAA - Super-sampling antialiasing
# Renders higher-resolution image of the scene, then scales down to reduce # Renders higher-resolution image of the scene, then scales down to reduce
# the aliasing effects. This is the slowest and the most accurate method. # the aliasing effects. This is the slowest and the most accurate method.
antialiasing (Antialiasing method) enum none none,fsaa,fxaa,ssaa antialiasing (Antialiasing method) enum none none,fsaa,fxaa,ssaa
@ -470,21 +475,16 @@ performance_tradeoffs (Tradeoffs for performance) bool false
# Adds particles when digging a node. # Adds particles when digging a node.
enable_particles (Digging particles) bool true enable_particles (Digging particles) bool true
[**Waving Nodes] [**Waving Nodes]
# Set to true to enable waving leaves. # Set to true to enable waving leaves.
#
# Requires: shaders
enable_waving_leaves (Waving leaves) bool false enable_waving_leaves (Waving leaves) bool false
# Set to true to enable waving plants. # Set to true to enable waving plants.
#
# Requires: shaders
enable_waving_plants (Waving plants) bool false enable_waving_plants (Waving plants) bool false
# Set to true to enable waving liquids (like water). # Set to true to enable waving liquids (like water).
#
# Requires: shaders
enable_waving_water (Waving liquids) bool false enable_waving_water (Waving liquids) bool false
# The maximum height of the surface of waving liquids. # The maximum height of the surface of waving liquids.
@ -492,99 +492,83 @@ enable_waving_water (Waving liquids) bool false
# 0.0 = Wave doesn't move at all. # 0.0 = Wave doesn't move at all.
# Default is 1.0 (1/2 node). # Default is 1.0 (1/2 node).
# #
# Requires: shaders, enable_waving_water # Requires: enable_waving_water
water_wave_height (Waving liquids wave height) float 1.0 0.0 4.0 water_wave_height (Waving liquids wave height) float 1.0 0.0 4.0
# Length of liquid waves. # Length of liquid waves.
# #
# Requires: shaders, enable_waving_water # Requires: enable_waving_water
water_wave_length (Waving liquids wavelength) float 20.0 0.1 water_wave_length (Waving liquids wavelength) float 20.0 0.1
# How fast liquid waves will move. Higher = faster. # How fast liquid waves will move. Higher = faster.
# If negative, liquid waves will move backwards. # If negative, liquid waves will move backwards.
# #
# Requires: shaders, enable_waving_water # Requires: enable_waving_water
water_wave_speed (Waving liquids wave speed) float 5.0 water_wave_speed (Waving liquids wave speed) float 5.0
[**Dynamic shadows] [**Dynamic shadows]
# Set to true to enable Shadow Mapping. # Set to true to enable Shadow Mapping.
# #
# Requires: shaders, opengl # Requires: opengl
enable_dynamic_shadows (Dynamic shadows) bool false enable_dynamic_shadows (Dynamic shadows) bool false
# Set the shadow strength gamma. # Set the shadow strength gamma.
# Adjusts the intensity of in-game dynamic shadows. # Adjusts the intensity of in-game dynamic shadows.
# Lower value means lighter shadows, higher value means darker shadows. # Lower value means lighter shadows, higher value means darker shadows.
# #
# Requires: shaders, enable_dynamic_shadows, opengl # Requires: enable_dynamic_shadows, opengl
shadow_strength_gamma (Shadow strength gamma) float 1.0 0.1 10.0 shadow_strength_gamma (Shadow strength gamma) float 1.0 0.1 10.0
# Maximum distance to render shadows. # Maximum distance to render shadows.
# #
# Requires: shaders, enable_dynamic_shadows, opengl # Requires: enable_dynamic_shadows, opengl
shadow_map_max_distance (Shadow map max distance in nodes to render shadows) float 140.0 10.0 1000.0 shadow_map_max_distance (Shadow map max distance in nodes to render shadows) float 140.0 10.0 1000.0
# Texture size to render the shadow map on. # Texture size to render the shadow map on.
# This must be a power of two. # This must be a power of two.
# Bigger numbers create better shadows but it is also more expensive. # Bigger numbers create better shadows but it is also more expensive.
# #
# Requires: shaders, enable_dynamic_shadows, opengl # Requires: enable_dynamic_shadows, opengl
shadow_map_texture_size (Shadow map texture size) int 2048 128 8192 shadow_map_texture_size (Shadow map texture size) int 2048 128 8192
# Sets shadow texture quality to 32 bits. # Sets shadow texture quality to 32 bits.
# On false, 16 bits texture will be used. # On false, 16 bits texture will be used.
# This can cause much more artifacts in the shadow. # This can cause much more artifacts in the shadow.
# #
# Requires: shaders, enable_dynamic_shadows, opengl # Requires: enable_dynamic_shadows, opengl
shadow_map_texture_32bit (Shadow map texture in 32 bits) bool true shadow_map_texture_32bit (Shadow map texture in 32 bits) bool true
# Enable Poisson disk filtering.
# On true uses Poisson disk to make "soft shadows". Otherwise uses PCF filtering.
#
# Requires: shaders, enable_dynamic_shadows, opengl
shadow_poisson_filter (Poisson filtering) bool true
# Define shadow filtering quality. # Define shadow filtering quality.
# This simulates the soft shadows effect by applying a PCF or Poisson disk # This simulates the soft shadows effect by applying a PCF or Poisson disk
# but also uses more resources. # but also uses more resources.
# #
# Requires: shaders, enable_dynamic_shadows, opengl # Requires: enable_dynamic_shadows, opengl
shadow_filters (Shadow filter quality) enum 1 0,1,2 shadow_filters (Shadow filter quality) enum 1 0,1,2
# Enable colored shadows. # Enable colored shadows.
# On true translucent nodes cast colored shadows. This is expensive. # On true translucent nodes cast colored shadows. This is expensive.
# #
# Requires: shaders, enable_dynamic_shadows, opengl # Requires: enable_dynamic_shadows, opengl
shadow_map_color (Colored shadows) bool false shadow_map_color (Colored shadows) bool false
# Spread a complete update of shadow map over given number of frames.
# Higher values might make shadows laggy, lower values
# will consume more resources.
# Minimum value: 1; maximum value: 16
#
# Requires: shaders, enable_dynamic_shadows, opengl
shadow_update_frames (Map shadows update frames) int 8 1 16
# Set the soft shadow radius size. # Set the soft shadow radius size.
# Lower values mean sharper shadows, bigger values mean softer shadows. # Lower values mean sharper shadows, bigger values mean softer shadows.
# Minimum value: 1.0; maximum value: 15.0 # Minimum value: 1.0; maximum value: 15.0
# #
# Requires: shaders, enable_dynamic_shadows, opengl # Requires: enable_dynamic_shadows, opengl
shadow_soft_radius (Soft shadow radius) float 5.0 1.0 15.0 shadow_soft_radius (Soft shadow radius) float 5.0 1.0 15.0
# Set the default tilt of Sun/Moon orbit in degrees. # Set the default tilt of Sun/Moon orbit in degrees.
# Games may change orbit tilt via API. # Games may change orbit tilt via API.
# Value of 0 means no tilt / vertical orbit. # Value of 0 means no tilt / vertical orbit.
# #
# Requires: shaders, enable_dynamic_shadows, opengl # Requires: enable_dynamic_shadows, opengl
shadow_sky_body_orbit_tilt (Sky Body Orbit Tilt) float 0.0 -60.0 60.0 shadow_sky_body_orbit_tilt (Sky Body Orbit Tilt) float 0.0 -60.0 60.0
[**Post Processing] [**Post Processing]
# Enables the post processing pipeline. # Enables the post processing pipeline.
#
# Requires: shaders
enable_post_processing (Enable Post Processing) bool true enable_post_processing (Enable Post Processing) bool true
# Enables Hable's 'Uncharted 2' filmic tone mapping. # Enables Hable's 'Uncharted 2' filmic tone mapping.
@ -592,7 +576,7 @@ enable_post_processing (Enable Post Processing) bool true
# appearance of high dynamic range images. Mid-range contrast is slightly # appearance of high dynamic range images. Mid-range contrast is slightly
# enhanced, highlights and shadows are gradually compressed. # enhanced, highlights and shadows are gradually compressed.
# #
# Requires: shaders, enable_post_processing # Requires: enable_post_processing
tone_mapping (Filmic tone mapping) bool false tone_mapping (Filmic tone mapping) bool false
# Enable automatic exposure correction # Enable automatic exposure correction
@ -600,14 +584,14 @@ tone_mapping (Filmic tone mapping) bool false
# automatically adjust to the brightness of the scene, # automatically adjust to the brightness of the scene,
# simulating the behavior of human eye. # simulating the behavior of human eye.
# #
# Requires: shaders, enable_post_processing # Requires: enable_post_processing
enable_auto_exposure (Enable Automatic Exposure) bool false enable_auto_exposure (Enable Automatic Exposure) bool false
# Set the exposure compensation in EV units. # Set the exposure compensation in EV units.
# Value of 0.0 (default) means no exposure compensation. # Value of 0.0 (default) means no exposure compensation.
# Range: from -1 to 1.0 # Range: from -1 to 1.0
# #
# Requires: shaders, enable_post_processing, enable_auto_exposure # Requires: enable_post_processing, enable_auto_exposure
exposure_compensation (Exposure compensation) float 0.0 -1.0 1.0 exposure_compensation (Exposure compensation) float 0.0 -1.0 1.0
# Apply dithering to reduce color banding artifacts. # Apply dithering to reduce color banding artifacts.
@ -618,35 +602,35 @@ exposure_compensation (Exposure compensation) float 0.0 -1.0 1.0
# With OpenGL ES, dithering only works if the shader supports high # With OpenGL ES, dithering only works if the shader supports high
# floating-point precision and it may have a higher performance impact. # floating-point precision and it may have a higher performance impact.
# #
# Requires: shaders, enable_post_processing # Requires: enable_post_processing
debanding (Enable Debanding) bool true debanding (Enable Debanding) bool true
# Set to true to enable bloom effect. # Set to true to enable bloom effect.
# Bright colors will bleed over the neighboring objects. # Bright colors will bleed over the neighboring objects.
# #
# Requires: shaders, enable_post_processing # Requires: enable_post_processing
enable_bloom (Enable Bloom) bool false enable_bloom (Enable Bloom) bool false
# Set to true to enable volumetric lighting effect (a.k.a. "Godrays"). # Set to true to enable volumetric lighting effect (a.k.a. "Godrays").
# #
# Requires: shaders, enable_post_processing, enable_bloom # Requires: enable_post_processing, enable_bloom
enable_volumetric_lighting (Volumetric lighting) bool false enable_volumetric_lighting (Volumetric lighting) bool false
[**Other Effects] [**Other Effects]
# Simulate translucency when looking at foliage in the sunlight. # Simulate translucency when looking at foliage in the sunlight.
# #
# Requires: shaders, enable_dynamic_shadows # Requires: enable_dynamic_shadows
enable_translucent_foliage (Translucent foliage) bool false enable_translucent_foliage (Translucent foliage) bool false
# Apply specular shading to nodes. # Apply specular shading to nodes.
# #
# Requires: shaders, enable_dynamic_shadows # Requires: enable_dynamic_shadows
enable_node_specular (Node specular) bool false enable_node_specular (Node specular) bool false
# When enabled, liquid reflections are simulated. # When enabled, liquid reflections are simulated.
# #
# Requires: shaders, enable_waving_water, enable_dynamic_shadows # Requires: enable_waving_water, enable_dynamic_shadows
enable_water_reflections (Liquid reflections) bool false enable_water_reflections (Liquid reflections) bool false
[*Audio] [*Audio]
@ -789,7 +773,7 @@ contentdb_max_concurrent_downloads (ContentDB Max Concurrent Downloads) int 3 1
enable_local_map_saving (Saving map received from server) bool false enable_local_map_saving (Saving map received from server) bool false
# URL to the server list displayed in the Multiplayer Tab. # URL to the server list displayed in the Multiplayer Tab.
serverlist_url (Serverlist URL) string servers.luanti.org serverlist_url (Serverlist URL) string https://servers.luanti.org
# If enabled, account registration is separate from login in the UI. # If enabled, account registration is separate from login in the UI.
# If disabled, new accounts will be registered automatically when logging in. # If disabled, new accounts will be registered automatically when logging in.
@ -827,7 +811,7 @@ server_announce (Announce server) bool false
server_announce_send_players (Send player names to the server list) bool true server_announce_send_players (Send player names to the server list) bool true
# Announce to this serverlist. # Announce to this serverlist.
serverlist_url (Serverlist URL) string servers.luanti.org serverlist_url (Serverlist URL) string https://servers.luanti.org
# Message of the day displayed to players connecting. # Message of the day displayed to players connecting.
motd (Message of the day) string motd (Message of the day) string
@ -1837,14 +1821,10 @@ ignore_world_load_errors (Ignore world errors) bool false
[**Graphics] [**Graphics]
# Shaders are a fundamental part of rendering and enable advanced visual effects. # Enables debug and error-checking in the OpenGL driver.
# opengl_debug (OpenGL debug) bool false
# Requires: shaders_support
enable_shaders (Shaders) bool true
# Path to shader directory. If no path is defined, default location will be used. # Path to shader directory. If no path is defined, default location will be used.
#
# Requires: shaders
shader_path (Shader path) path shader_path (Shader path) path
# The rendering back-end. # The rendering back-end.
@ -1857,6 +1837,11 @@ video_driver (Video driver) enum ,opengl,opengl3,ogles2
# Set to 0 to disable it entirely. # Set to 0 to disable it entirely.
transparency_sorting_distance (Transparency Sorting Distance) int 16 0 128 transparency_sorting_distance (Transparency Sorting Distance) int 16 0 128
# Draw transparency sorted triangles grouped by their mesh buffers.
# This breaks transparency sorting between mesh buffers, but avoids situations
# where transparency sorting would be very slow otherwise.
transparency_sorting_group_by_buffers (Transparency Sorting Group by Buffers) bool true
# Radius of cloud area stated in number of 64 node cloud squares. # Radius of cloud area stated in number of 64 node cloud squares.
# Values larger than 26 will start to produce sharp cutoffs at cloud area corners. # Values larger than 26 will start to produce sharp cutoffs at cloud area corners.
cloud_radius (Cloud radius) int 12 1 62 cloud_radius (Cloud radius) int 12 1 62
@ -1864,10 +1849,6 @@ cloud_radius (Cloud radius) int 12 1 62
# Whether node texture animations should be desynchronized per mapblock. # Whether node texture animations should be desynchronized per mapblock.
desynchronize_mapblock_texture_animation (Desynchronize block animation) bool false desynchronize_mapblock_texture_animation (Desynchronize block animation) bool false
# Enables caching of facedir rotated meshes.
# This is only effective with shaders disabled.
enable_mesh_cache (Mesh cache) bool false
# Delay between mesh updates on the client in ms. Increasing this will slow # Delay between mesh updates on the client in ms. Increasing this will slow
# down the rate of mesh updates, thus reducing jitter on slower clients. # down the rate of mesh updates, thus reducing jitter on slower clients.
mesh_generation_interval (Mapblock mesh generation delay) int 0 0 50 mesh_generation_interval (Mapblock mesh generation delay) int 0 0 50
@ -1876,6 +1857,10 @@ mesh_generation_interval (Mapblock mesh generation delay) int 0 0 50
# Value of 0 (default) will let Luanti autodetect the number of available threads. # Value of 0 (default) will let Luanti autodetect the number of available threads.
mesh_generation_threads (Mapblock mesh generation threads) int 0 0 8 mesh_generation_threads (Mapblock mesh generation threads) int 0 0 8
# All mesh buffers with less than this number of vertices will be merged
# during map rendering. This improves rendering performance.
mesh_buffer_min_vertices (Minimum vertex count for mesh buffers) int 100 0 1000
# True = 256 # True = 256
# False = 128 # False = 128
# Usable to make minimap smoother on slower machines. # Usable to make minimap smoother on slower machines.
@ -1897,12 +1882,11 @@ world_aligned_mode (World-aligned textures mode) enum enable disable,enable,forc
# Warning: This option is EXPERIMENTAL! # Warning: This option is EXPERIMENTAL!
autoscale_mode (Autoscaling mode) enum disable disable,enable,force autoscale_mode (Autoscaling mode) enum disable disable,enable,force
# When using bilinear/trilinear/anisotropic filters, low-resolution textures # When using bilinear/trilinear filtering, low-resolution textures
# can be blurred, so automatically upscale them with nearest-neighbor # can be blurred, so this option automatically upscales them to preserve
# interpolation to preserve crisp pixels. This sets the minimum texture size # crisp pixels. This defines the minimum texture size for the upscaled textures;
# for the upscaled textures; higher values look sharper, but require more # higher values look sharper, but require more memory.
# memory. Powers of 2 are recommended. This setting is ONLY applied if # This setting is ONLY applied if any of the mentioned filters are enabled.
# bilinear/trilinear/anisotropic filtering is enabled.
# This is also used as the base node texture size for world-aligned # This is also used as the base node texture size for world-aligned
# texture autoscaling. # texture autoscaling.
texture_min_size (Base texture size) int 64 1 32768 texture_min_size (Base texture size) int 64 1 32768
@ -1914,15 +1898,33 @@ texture_min_size (Base texture size) int 64 1 32768
# Systems with a low-end GPU (or no GPU) would benefit from smaller values. # Systems with a low-end GPU (or no GPU) would benefit from smaller values.
client_mesh_chunk (Client Mesh Chunksize) int 1 1 16 client_mesh_chunk (Client Mesh Chunksize) int 1 1 16
# Enables debug and error-checking in the OpenGL driver. # Decide the color depth of the texture used for the post-processing pipeline.
opengl_debug (OpenGL debug) bool false # Reducing this can improve performance, but might cause some effects (e.g. bloom)
# to not work.
#
# Requires: enable_post_processing
post_processing_texture_bits (Color depth for post-processing texture) enum 16 8,10,16
# Enable Poisson disk filtering.
# On true uses Poisson disk to make "soft shadows". Otherwise uses PCF filtering.
#
# Requires: enable_dynamic_shadows, opengl
shadow_poisson_filter (Poisson filtering) bool true
# Spread a complete update of shadow map over given number of frames.
# Higher values might make shadows laggy, lower values
# will consume more resources.
# Minimum value: 1; maximum value: 16
#
# Requires: enable_dynamic_shadows, opengl
shadow_update_frames (Map shadows update frames) int 8 1 16
# Set to true to render debugging breakdown of the bloom effect. # Set to true to render debugging breakdown of the bloom effect.
# In debug mode, the screen is split into 4 quadrants: # In debug mode, the screen is split into 4 quadrants:
# top-left - processed base image, top-right - final image # top-left - processed base image, top-right - final image
# bottom-left - raw base image, bottom-right - bloom texture. # bottom-left - raw base image, bottom-right - bloom texture.
# #
# Requires: shaders, enable_post_processing, enable_bloom # Requires: enable_post_processing, enable_bloom
enable_bloom_debug (Enable Bloom Debug) bool false enable_bloom_debug (Enable Bloom Debug) bool false
[**Sound] [**Sound]

View File

@ -9,6 +9,7 @@ attribute vec2 inTexCoord0;
/* Uniforms */ /* Uniforms */
uniform float uThickness; uniform float uThickness;
uniform mat4 uProjection;
/* Varyings */ /* Varyings */
@ -17,7 +18,7 @@ varying vec4 vVertexColor;
void main() void main()
{ {
gl_Position = inVertexPosition; gl_Position = uProjection * inVertexPosition;
gl_PointSize = uThickness; gl_PointSize = uThickness;
vTextureCoord = inTexCoord0; vTextureCoord = inTexCoord0;
vVertexColor = inVertexColor.bgra; vVertexColor = inVertexColor.bgra;

View File

@ -1,6 +0,0 @@
varying lowp vec4 varColor;
void main(void)
{
gl_FragData[0] = varColor;
}

View File

@ -1,7 +0,0 @@
varying lowp vec4 varColor;
void main(void)
{
gl_Position = mWorldViewProj * inVertexPosition;
varColor = inVertexColor;
}

View File

@ -23,7 +23,12 @@ void main(void)
vec2 uv = varTexCoord.st; vec2 uv = varTexCoord.st;
vec3 color = texture2D(rendered, uv).rgb; vec3 color = texture2D(rendered, uv).rgb;
// translate to linear colorspace (approximate) // translate to linear colorspace (approximate)
#ifdef GL_ES
// clamp color to [0,1] range in lieu of centroids
color = pow(clamp(color, 0.0, 1.0), vec3(2.2));
#else
color = pow(color, vec3(2.2)); color = pow(color, vec3(2.2));
#endif
color *= exposureParams.compensationFactor * bloomStrength; color *= exposureParams.compensationFactor * bloomStrength;

View File

@ -1,7 +1,3 @@
#if (MATERIAL_TYPE == TILE_MATERIAL_WAVING_LIQUID_TRANSPARENT || MATERIAL_TYPE == TILE_MATERIAL_WAVING_LIQUID_OPAQUE || MATERIAL_TYPE == TILE_MATERIAL_WAVING_LIQUID_BASIC || MATERIAL_TYPE == TILE_MATERIAL_LIQUID_TRANSPARENT)
#define MATERIAL_WAVING_LIQUID 1
#endif
uniform sampler2D baseTexture; uniform sampler2D baseTexture;
uniform vec3 dayLight; uniform vec3 dayLight;
@ -43,17 +39,19 @@ varying vec3 vPosition;
// cameraOffset + worldPosition (for large coordinates the limits of float // cameraOffset + worldPosition (for large coordinates the limits of float
// precision must be considered). // precision must be considered).
varying vec3 worldPosition; varying vec3 worldPosition;
varying lowp vec4 varColor;
#ifdef GL_ES #ifdef GL_ES
varying lowp vec4 varColor;
varying mediump vec2 varTexCoord; varying mediump vec2 varTexCoord;
varying float nightRatio;
#else #else
centroid varying lowp vec4 varColor;
centroid varying vec2 varTexCoord; centroid varying vec2 varTexCoord;
centroid varying float nightRatio;
#endif #endif
varying highp vec3 eyeVec; varying highp vec3 eyeVec;
varying float nightRatio;
#ifdef ENABLE_DYNAMIC_SHADOWS #ifdef ENABLE_DYNAMIC_SHADOWS
#if (defined(MATERIAL_WAVING_LIQUID) && defined(ENABLE_WATER_REFLECTIONS) && ENABLE_WAVING_WATER) #if (defined(ENABLE_WATER_REFLECTIONS) && MATERIAL_WAVING_LIQUID && ENABLE_WAVING_WATER)
vec4 perm(vec4 x) vec4 perm(vec4 x)
{ {
return mod(((x * 34.0) + 1.0) * x, 289.0); return mod(((x * 34.0) + 1.0) * x, 289.0);
@ -504,7 +502,7 @@ void main(void)
vec3 viewVec = normalize(worldPosition + cameraOffset - cameraPosition); vec3 viewVec = normalize(worldPosition + cameraOffset - cameraPosition);
// Water reflections // Water reflections
#if (defined(MATERIAL_WAVING_LIQUID) && defined(ENABLE_WATER_REFLECTIONS) && ENABLE_WAVING_WATER) #if (defined(ENABLE_WATER_REFLECTIONS) && MATERIAL_WAVING_LIQUID && ENABLE_WAVING_WATER)
vec3 wavePos = worldPosition * vec3(2.0, 0.0, 2.0); vec3 wavePos = worldPosition * vec3(2.0, 0.0, 2.0);
float off = animationTimer * WATER_WAVE_SPEED * 10.0; float off = animationTimer * WATER_WAVE_SPEED * 10.0;
wavePos.x /= WATER_WAVE_LENGTH * 3.0; wavePos.x /= WATER_WAVE_LENGTH * 3.0;
@ -532,7 +530,7 @@ void main(void)
col.rgb += water_reflect_color * f_adj_shadow_strength * brightness_factor; col.rgb += water_reflect_color * f_adj_shadow_strength * brightness_factor;
#endif #endif
#if (defined(ENABLE_NODE_SPECULAR) && !defined(MATERIAL_WAVING_LIQUID)) #if (defined(ENABLE_NODE_SPECULAR) && !MATERIAL_WAVING_LIQUID)
// Apply specular to blocks. // Apply specular to blocks.
if (dot(v_LightDirection, vNormal) < 0.0) { if (dot(v_LightDirection, vNormal) < 0.0) {
float intensity = 2.0 * (1.0 - (base.r * varColor.r)); float intensity = 2.0 * (1.0 - (base.r * varColor.r));

View File

@ -14,14 +14,17 @@ varying vec3 vPosition;
// cameraOffset + worldPosition (for large coordinates the limits of float // cameraOffset + worldPosition (for large coordinates the limits of float
// precision must be considered). // precision must be considered).
varying vec3 worldPosition; varying vec3 worldPosition;
varying lowp vec4 varColor;
// The centroid keyword ensures that after interpolation the texture coordinates // The centroid keyword ensures that after interpolation the texture coordinates
// lie within the same bounds when MSAA is en- and disabled. // lie within the same bounds when MSAA is en- and disabled.
// This fixes the stripes problem with nearest-neighbor textures and MSAA. // This fixes the stripes problem with nearest-neighbor textures and MSAA.
#ifdef GL_ES #ifdef GL_ES
varying lowp vec4 varColor;
varying mediump vec2 varTexCoord; varying mediump vec2 varTexCoord;
varying float nightRatio;
#else #else
centroid varying lowp vec4 varColor;
centroid varying vec2 varTexCoord; centroid varying vec2 varTexCoord;
centroid varying float nightRatio;
#endif #endif
#ifdef ENABLE_DYNAMIC_SHADOWS #ifdef ENABLE_DYNAMIC_SHADOWS
// shadow uniforms // shadow uniforms
@ -44,7 +47,6 @@ centroid varying vec2 varTexCoord;
varying float area_enable_parallax; varying float area_enable_parallax;
varying highp vec3 eyeVec; varying highp vec3 eyeVec;
varying float nightRatio;
// Color of the light emitted by the light sources. // Color of the light emitted by the light sources.
const vec3 artificialLight = vec3(1.04, 1.04, 1.04); const vec3 artificialLight = vec3(1.04, 1.04, 1.04);
const float e = 2.718281828459; const float e = 2.718281828459;
@ -108,8 +110,7 @@ float smoothTriangleWave(float x)
return smoothCurve(triangleWave(x)) * 2.0 - 1.0; return smoothCurve(triangleWave(x)) * 2.0 - 1.0;
} }
// OpenGL < 4.3 does not support continued preprocessor lines #if MATERIAL_WAVING_LIQUID && ENABLE_WAVING_WATER
#if (MATERIAL_TYPE == TILE_MATERIAL_WAVING_LIQUID_TRANSPARENT || MATERIAL_TYPE == TILE_MATERIAL_WAVING_LIQUID_OPAQUE || MATERIAL_TYPE == TILE_MATERIAL_WAVING_LIQUID_BASIC) && ENABLE_WAVING_WATER
// //
// Simple, fast noise function. // Simple, fast noise function.
@ -166,8 +167,7 @@ void main(void)
#endif #endif
vec4 pos = inVertexPosition; vec4 pos = inVertexPosition;
// OpenGL < 4.3 does not support continued preprocessor lines #if MATERIAL_WAVING_LIQUID && ENABLE_WAVING_WATER
#if (MATERIAL_TYPE == TILE_MATERIAL_WAVING_LIQUID_TRANSPARENT || MATERIAL_TYPE == TILE_MATERIAL_WAVING_LIQUID_OPAQUE || MATERIAL_TYPE == TILE_MATERIAL_WAVING_LIQUID_BASIC) && ENABLE_WAVING_WATER
// Generate waves with Perlin-type noise. // Generate waves with Perlin-type noise.
// The constants are calibrated such that they roughly // The constants are calibrated such that they roughly
// correspond to the old sine waves. // correspond to the old sine waves.

View File

@ -3,8 +3,6 @@ All Luanti builds, including the Android variant, are based on the same code.
However, additional Java code is used for proper Android integration. However, additional Java code is used for proper Android integration.
## Controls ## Controls
Compared to Luanti binaries for PC, the Android port has limited functionality
due to limited capabilities of common devices. What can be done is described below:
While you're playing the game normally (that is, no menu or inventory is While you're playing the game normally (that is, no menu or inventory is
shown), the following controls are available: shown), the following controls are available:
@ -44,7 +42,7 @@ configuration file can usually be found at:
* After 5.4.2: * After 5.4.2:
* `/sdcard/Android/data/net.minetest.minetest/` or `/storage/emulated/0/Android/data/net.minetest.minetest/` if stored on the device * `/sdcard/Android/data/net.minetest.minetest/` or `/storage/emulated/0/Android/data/net.minetest.minetest/` if stored on the device
* `/storage/emulated/(varying folder name)/Android/data/net.minetest.minetest/` if stored on the SD card * `/storage/emulated/(varying folder name)/Android/data/net.minetest.minetest/` if stored on the SD card
* [Learn more about Android directory](https://wiki.minetest.net/Accessing_Android_Data_Directory) * [Learn more about Android directory](https://wiki.luanti.org/Accessing_Android_Data_Directory)
## Useful settings ## Useful settings
@ -58,35 +56,25 @@ Mobile device generally have less RAM than PC, this setting limit how many mapbl
this setting limit max FPS (Frame per second). Default value is 60, which lowest Android device screen refresh rate commonly found, but if you're using an device have lower refresh rate, change this this setting limit max FPS (Frame per second). Default value is 60, which lowest Android device screen refresh rate commonly found, but if you're using an device have lower refresh rate, change this
## Requirements ## Requirements
The minimal and recommended system requirements for Luanti are listed below. The recommended system requirements for Luanti are listed below.
### CPU ### CPU
Supported architectures: Supported architectures:
1. ARM v7 1. ARMv7
2. ARM v8 2. AArch64
3. x86 3. x86
4. x86_64 4. x86_64
CPU architectures similar to ARM or x86 might run Luanti but are not tested.
### Minimum
1. Graphics API: OpenGL ES 1.0
* Shaders might not work correctly or work at all on OpenGL ES 1.0.
2. Android version: Android 4.1 (API Level 16)
3. Free RAM: 500 MB
4. Free storage: 100 MB
* More storage is highly recommended
### Recommended ### Recommended
1. Graphics API: OpenGL ES 2.0 1. Graphics API: OpenGL ES 2.0
2. Android version: Android 4.4 (API Level 19) or newer 2. Android version: Android 5 (API Level 21) or newer
3. Empty RAM: 850 MB 3. Free RAM: 1 GB
4. Free storage: 480 MB 4. Free storage: 500 MB
## Rendering ## Rendering
Unlike on PC, Android devices use OpenGL ES which less powerful than OpenGL, thus Unlike on PC, Android devices use OpenGL ES which less powerful than OpenGL, thus
some shader settings cannot be used on OpenGL ES. some shader settings cannot be used on OpenGL ES.
Changing the graphic driver setting to OpenGL will result in undesirable behavior. Changing the graphic driver setting to OpenGL will not work.
## Building Requirements ## Building Requirements
In order to build, your PC has to be set up to build Luanti in the usual In order to build, your PC has to be set up to build Luanti in the usual

View File

@ -21,3 +21,4 @@ This list is largely advisory and items may be reevaluated once the time comes.
* merge `sound` and `sounds` table in itemdef * merge `sound` and `sounds` table in itemdef
* remove `DIR_DELIM` from Lua * remove `DIR_DELIM` from Lua
* stop reading initial properties from bare entity def * stop reading initial properties from bare entity def
* change particle default blend mode to `clip`

View File

@ -1,4 +1,4 @@
Luanti Lua Client Modding API Reference 5.10.0 Luanti Lua Client Modding API Reference 5.11.0
============================================== ==============================================
**WARNING**: if you're looking for the `minetest` namespace (e.g. `minetest.something`), **WARNING**: if you're looking for the `minetest` namespace (e.g. `minetest.something`),

View File

@ -30,6 +30,7 @@ General options and their default values:
ENABLE_POSTGRESQL=ON - Build with libpq; Enables use of PostgreSQL map backend (PostgreSQL 9.5 or greater recommended) ENABLE_POSTGRESQL=ON - Build with libpq; Enables use of PostgreSQL map backend (PostgreSQL 9.5 or greater recommended)
ENABLE_REDIS=ON - Build with libhiredis; Enables use of Redis map backend ENABLE_REDIS=ON - Build with libhiredis; Enables use of Redis map backend
ENABLE_SPATIAL=ON - Build with LibSpatial; Speeds up AreaStores ENABLE_SPATIAL=ON - Build with LibSpatial; Speeds up AreaStores
ENABLE_OPENSSL=ON - Build with OpenSSL; Speeds up SHA1 and SHA2 hashing
ENABLE_SOUND=ON - Build with OpenAL, libogg & libvorbis; in-game sounds ENABLE_SOUND=ON - Build with OpenAL, libogg & libvorbis; in-game sounds
ENABLE_LTO=<varies> - Build with IPO/LTO optimizations (smaller and more efficient than regular build) ENABLE_LTO=<varies> - Build with IPO/LTO optimizations (smaller and more efficient than regular build)
ENABLE_LUAJIT=ON - Build with LuaJIT (much faster than non-JIT Lua) ENABLE_LUAJIT=ON - Build with LuaJIT (much faster than non-JIT Lua)
@ -61,7 +62,14 @@ Library specific options:
GETTEXT_INCLUDE_DIR - Only when building with gettext; directory that contains libintl.h GETTEXT_INCLUDE_DIR - Only when building with gettext; directory that contains libintl.h
GETTEXT_LIBRARY - Optional/platform-dependent with gettext; path to libintl.so/libintl.dll.a GETTEXT_LIBRARY - Optional/platform-dependent with gettext; path to libintl.so/libintl.dll.a
GETTEXT_MSGFMT - Only when building with gettext; path to msgfmt/msgfmt.exe GETTEXT_MSGFMT - Only when building with gettext; path to msgfmt/msgfmt.exe
GMP_INCLUDE_DIR - Directory that contains gmp.h
GMP_LIBRARY - Path to libgmp.a/libgmp.so/libgmp.lib
ICONV_LIBRARY - Optional/platform-dependent; path to libiconv.so/libiconv.dylib ICONV_LIBRARY - Optional/platform-dependent; path to libiconv.so/libiconv.dylib
JPEG_DLL - Only on Windows; path to libjpeg.dll
JPEG_INCLUDE_DIR - Directory that contains jpeg.h
JPEG_LIBRARY - Path to libjpeg.a/libjpeg.so/libjpeg.lib
JSON_INCLUDE_DIR - Directory that contains json/allocator.h
JSON_LIBRARY - Path to libjson.a/libjson.so/libjson.lib
LEVELDB_INCLUDE_DIR - Only when building with LevelDB; directory that contains db.h LEVELDB_INCLUDE_DIR - Only when building with LevelDB; directory that contains db.h
LEVELDB_LIBRARY - Only when building with LevelDB; path to libleveldb.a/libleveldb.so/libleveldb.dll.a LEVELDB_LIBRARY - Only when building with LevelDB; path to libleveldb.a/libleveldb.so/libleveldb.dll.a
LEVELDB_DLL - Only when building with LevelDB on Windows; path to libleveldb.dll LEVELDB_DLL - Only when building with LevelDB on Windows; path to libleveldb.dll
@ -79,6 +87,12 @@ Library specific options:
OPENAL_DLL - Only if building with sound on Windows; path to OpenAL32.dll OPENAL_DLL - Only if building with sound on Windows; path to OpenAL32.dll
OPENAL_INCLUDE_DIR - Only if building with sound; directory where al.h is located OPENAL_INCLUDE_DIR - Only if building with sound; directory where al.h is located
OPENAL_LIBRARY - Only if building with sound; path to libopenal.a/libopenal.so/OpenAL32.lib OPENAL_LIBRARY - Only if building with sound; path to libopenal.a/libopenal.so/OpenAL32.lib
PNG_DLL - Only on Windows; path to libpng.dll
PNG_INCLUDE_DIR - Directory that contains png.h
PNG_LIBRARY - Path to libpng.a/libpng.so/libpng.lib
PROMETHEUS_PULL_LIBRARY - Only if building with prometheus; path to prometheus-cpp-pull
PROMETHEUS_CORE_LIBRARY - Only if building with prometheus; path to prometheus-cpp-core
PROMETHEUS_CPP_INCLUDE_DIR - Only if building with prometheus; directory where prometheus/counter.h is located
SQLITE3_INCLUDE_DIR - Directory that contains sqlite3.h SQLITE3_INCLUDE_DIR - Directory that contains sqlite3.h
SQLITE3_LIBRARY - Path to libsqlite3.a/libsqlite3.so/sqlite3.lib SQLITE3_LIBRARY - Path to libsqlite3.a/libsqlite3.so/sqlite3.lib
VORBISFILE_LIBRARY - Only if building with sound; path to libvorbisfile.a/libvorbisfile.so/libvorbisfile.dll.a VORBISFILE_LIBRARY - Only if building with sound; path to libvorbisfile.a/libvorbisfile.so/libvorbisfile.dll.a

View File

@ -18,30 +18,31 @@
| JsonCPP | 1.0.0+ | Bundled JsonCPP is used if not present | | JsonCPP | 1.0.0+ | Bundled JsonCPP is used if not present |
| Curl | 7.56.0+ | Optional | | Curl | 7.56.0+ | Optional |
| gettext | - | Optional | | gettext | - | Optional |
| OpenSSL | 3.0+ | Optional (only libcrypto used) |
For Debian/Ubuntu users: For Debian/Ubuntu users:
sudo apt install g++ make libc6-dev cmake libpng-dev libjpeg-dev libxi-dev libgl1-mesa-dev libsqlite3-dev libogg-dev libvorbis-dev libopenal-dev libcurl4-gnutls-dev libfreetype6-dev zlib1g-dev libgmp-dev libjsoncpp-dev libzstd-dev libluajit-5.1-dev gettext sudo apt install g++ make libc6-dev cmake libpng-dev libjpeg-dev libgl1-mesa-dev libsqlite3-dev libogg-dev libvorbis-dev libopenal-dev libcurl4-gnutls-dev libfreetype6-dev zlib1g-dev libgmp-dev libjsoncpp-dev libzstd-dev libluajit-5.1-dev gettext libsdl2-dev
For Fedora users: For Fedora users:
sudo dnf install make automake gcc gcc-c++ kernel-devel cmake libcurl-devel openal-soft-devel libpng-devel libjpeg-devel libvorbis-devel libXi-devel libogg-devel freetype-devel mesa-libGL-devel zlib-devel jsoncpp-devel gmp-devel sqlite-devel luajit-devel leveldb-devel ncurses-devel spatialindex-devel libzstd-devel gettext sudo dnf install make automake gcc gcc-c++ kernel-devel cmake libcurl-devel openal-soft-devel libpng-devel libjpeg-devel libvorbis-devel libogg-devel freetype-devel mesa-libGL-devel zlib-devel jsoncpp-devel gmp-devel sqlite-devel luajit-devel leveldb-devel ncurses-devel spatialindex-devel libzstd-devel gettext SDL2-devel
For openSUSE users: For openSUSE users:
sudo zypper install gcc gcc-c++ cmake libjpeg8-devel libpng16-devel openal-soft-devel libcurl-devel sqlite3-devel luajit-devel libzstd-devel Mesa-libGL-devel libXi-devel libvorbis-devel freetype2-devel sudo zypper install gcc gcc-c++ cmake libjpeg8-devel libpng16-devel openal-soft-devel libcurl-devel sqlite3-devel luajit-devel libzstd-devel Mesa-libGL-devel libvorbis-devel freetype2-devel SDL2-devel
For Arch users: For Arch users:
sudo pacman -S --needed base-devel libcurl-gnutls cmake libxi libpng sqlite libogg libvorbis openal freetype2 jsoncpp gmp luajit leveldb ncurses zstd gettext sudo pacman -S --needed base-devel libcurl-gnutls cmake libpng libjpeg-turbo sqlite libogg libvorbis openal freetype2 jsoncpp gmp luajit leveldb ncurses zstd gettext sdl2
For Alpine users: For Alpine users:
sudo apk add build-base cmake libpng-dev jpeg-dev libxi-dev mesa-dev sqlite-dev libogg-dev libvorbis-dev openal-soft-dev curl-dev freetype-dev zlib-dev gmp-dev jsoncpp-dev luajit-dev zstd-dev gettext sudo apk add build-base cmake libpng-dev jpeg-dev mesa-dev sqlite-dev libogg-dev libvorbis-dev openal-soft-dev curl-dev freetype-dev zlib-dev gmp-dev jsoncpp-dev luajit-dev zstd-dev gettext sdl2-dev
For Void users: For Void users:
sudo xbps-install cmake libpng-devel jpeg-devel libXi-devel mesa sqlite-devel libogg-devel libvorbis-devel libopenal-devel libcurl-devel freetype-devel zlib-devel gmp-devel jsoncpp-devel LuaJIT-devel zstd libzstd-devel gettext sudo xbps-install cmake libpng-devel jpeg-devel mesa sqlite-devel libogg-devel libvorbis-devel libopenal-devel libcurl-devel freetype-devel zlib-devel gmp-devel jsoncpp-devel LuaJIT-devel zstd libzstd-devel gettext SDL2-devel
## Download ## Download

View File

@ -13,9 +13,8 @@
It is highly recommended to use vcpkg as package manager. It is highly recommended to use vcpkg as package manager.
After you successfully built vcpkg you can easily install the required libraries: After you successfully built vcpkg you can easily install the required libraries:
```powershell ```powershell
vcpkg install zlib zstd curl[winssl] openal-soft libvorbis libogg libjpeg-turbo sqlite3 freetype luajit gmp jsoncpp gettext[tools] opengl-registry --triplet x64-windows vcpkg install zlib zstd curl[winssl] openal-soft libvorbis libogg libjpeg-turbo sqlite3 freetype luajit gmp jsoncpp gettext[tools] sdl2 --triplet x64-windows
``` ```
- `curl` is optional, but required to read the serverlist, `curl[winssl]` is required to use the content store. - `curl` is optional, but required to read the serverlist, `curl[winssl]` is required to use the content store.

View File

@ -23,4 +23,4 @@ Notable pages:
Oftentimes knowledge hasn't been written down (yet) and your best bet is to ask someone experienced and/or the core developers. Oftentimes knowledge hasn't been written down (yet) and your best bet is to ask someone experienced and/or the core developers.
Feel free to join the [#minetest-dev IRC](https://wiki.minetest.net/IRC) and ask questions related to **engine development**. Feel free to join the [#minetest-dev IRC](https://wiki.luanti.org/IRC) and ask questions related to **engine development**.

View File

@ -45,13 +45,8 @@ There's usually no reason to raise this unless the NDK drops older versions.
**Compilers**: gcc, clang and MSVC (exceptions exist) **Compilers**: gcc, clang and MSVC (exceptions exist)
**OpenGL** is an entirely different beast, there is no formal consensus on changing the requirements We require **OpenGL** 2.0 or ES 2.0, so shaders can be relied on.
and neither do we have an exact set of requirements. Graphics code should generally work on both. Newer features can be used as long as a fallback exists.
We still support OpenGL 1.4 without shaders (fixed-pipeline), which could be considered very unreasonable in 2024.
OpenGL ES 2.0 is supported for the sake of mobile platforms.
It has been [proposed](https://irc.minetest.net/minetest-dev/2022-08-18) moving to OpenGL 2.x or 3.0 with shaders required.
General **system requirements** are not bounded either. General **system requirements** are not bounded either.
Being able to play Luanti on a recent low-end phone is a reasonable target. Being able to play Luanti on a recent low-end phone is a reasonable target.

View File

@ -188,7 +188,6 @@ Mod directory structure
│   ├── models │   ├── models
│   ├── textures │   ├── textures
│   │   ├── modname_stuff.png │   │   ├── modname_stuff.png
│   │   ├── modname_stuff_normal.png
│   │   ├── modname_something_else.png │   │   ├── modname_something_else.png
│   │   ├── subfolder_foo │   │   ├── subfolder_foo
│   │   │ ├── modname_more_stuff.png │   │   │ ├── modname_more_stuff.png
@ -276,7 +275,7 @@ the clients (see [Translations]). Accepted characters for names are:
Accepted formats are: Accepted formats are:
images: .png, .jpg, .tga, (deprecated:) .bmp images: .png, .jpg, .tga
sounds: .ogg vorbis sounds: .ogg vorbis
models: .x, .b3d, .obj, (since version 5.10:) .gltf, .glb models: .x, .b3d, .obj, (since version 5.10:) .gltf, .glb
@ -309,17 +308,24 @@ it unlocks no special rendering features.
Binary glTF (`.glb`) files are supported and recommended over `.gltf` files Binary glTF (`.glb`) files are supported and recommended over `.gltf` files
due to their space savings. due to their space savings.
This means that many glTF features are not supported *yet*, including: Bone weights should be normalized, e.g. using ["normalize all" in Blender](https://docs.blender.org/manual/en/4.2/grease_pencil/modes/weight_paint/weights_menu.html#normalize-all).
You can use the [Khronos glTF validator](https://github.com/KhronosGroup/glTF-Validator)
to check whether a model is a valid glTF file.
Many glTF features are not supported *yet*, including:
* Animations * Animations
* Only a single animation is supported, use frame ranges within this animation. * Only a single animation is supported, use frame ranges within this animation.
* `CUBICSPLINE` interpolation is not supported.
* Cameras * Cameras
* Materials * Materials
* Only base color textures are supported * Only base color textures are supported
* Backface culling is overridden * Backface culling is overridden
* Double-sided materials don't work * Double-sided materials don't work
* Alternative means of supplying data * Alternative means of supplying data
* Embedded images * Embedded images. You can use `gltfutil.py` from the
[modding tools](https://github.com/minetest/modtools) to strip or extract embedded images.
* References to files via URIs * References to files via URIs
Textures are supplied solely via the same means as for the other model file formats: Textures are supplied solely via the same means as for the other model file formats:
@ -486,9 +492,7 @@ stripping out the file extension:
* e.g. `foomod_foothing.png` * e.g. `foomod_foothing.png`
* e.g. `foomod_foothing` * e.g. `foomod_foothing`
Supported texture formats are PNG (`.png`), JPEG (`.jpg`), Bitmap (`.bmp`) Supported texture formats are PNG (`.png`), JPEG (`.jpg`) and Targa (`.tga`).
and Targa (`.tga`).
Since better alternatives exist, the latter two may be removed in the future.
Texture modifiers Texture modifiers
----------------- -----------------
@ -4185,14 +4189,14 @@ Two functions are provided to translate strings: `core.translate` and
* `core.get_translator(textdomain)` is a simple wrapper around * `core.get_translator(textdomain)` is a simple wrapper around
`core.translate` and `core.translate_n`. `core.translate` and `core.translate_n`.
After `local S, NS = core.get_translator(textdomain)`, we have After `local S, PS = core.get_translator(textdomain)`, we have
`S(str, ...)` equivalent to `core.translate(textdomain, str, ...)`, and `S(str, ...)` equivalent to `core.translate(textdomain, str, ...)`, and
`NS(str, str_plural, n, ...)` to `core.translate_n(textdomain, str, str_plural, n, ...)`. `PS(str, str_plural, n, ...)` to `core.translate_n(textdomain, str, str_plural, n, ...)`.
It is intended to be used in the following way, so that it avoids verbose It is intended to be used in the following way, so that it avoids verbose
repetitions of `core.translate`: repetitions of `core.translate`:
```lua ```lua
local S, NS = core.get_translator(textdomain) local S, PS = core.get_translator(textdomain)
S(str, ...) S(str, ...)
``` ```
@ -4226,7 +4230,7 @@ command that shows the amount of time since the player joined. We can do the
following: following:
```lua ```lua
local S, NS = core.get_translator("hello") local S, PS = core.get_translator("hello")
core.register_on_joinplayer(function(player) core.register_on_joinplayer(function(player)
local name = player:get_player_name() local name = player:get_player_name()
core.chat_send_player(name, S("Hello @1, how are you today?", name)) core.chat_send_player(name, S("Hello @1, how are you today?", name))
@ -4235,7 +4239,7 @@ core.register_chatcommand("playtime", {
func = function(name) func = function(name)
local last_login = core.get_auth_handler().get_auth(name).last_login local last_login = core.get_auth_handler().get_auth(name).last_login
local playtime = math.floor((last_login-os.time())/60) local playtime = math.floor((last_login-os.time())/60)
return true, NS( return true, PS(
"You have been playing for @1 minute.", "You have been playing for @1 minute.",
"You have been playing for @1 minutes.", "You have been playing for @1 minutes.",
minutes, tostring(minutes)) minutes, tostring(minutes))
@ -4282,7 +4286,7 @@ After creating the `locale` directory, a translation template for the above
example using the following command: example using the following command:
```sh ```sh
xgettext -L lua -kS -kNS:1,2 -kcore.translate:1c,2 -kcore.translate_n:1c,2,3 \ xgettext -L lua -kS -kPS:1,2 -kcore.translate:1c,2 -kcore.translate_n:1c,2,3 \
-d hello -o locale/hello.pot *.lua -d hello -o locale/hello.pot *.lua
``` ```
@ -5657,6 +5661,10 @@ Utilities
bulk_lbms = true, bulk_lbms = true,
-- ABM supports field without_neighbors (5.10.0) -- ABM supports field without_neighbors (5.10.0)
abm_without_neighbors = true, abm_without_neighbors = true,
-- biomes have a weight parameter (5.11.0)
biome_weights = true,
-- Particles can specify a "clip" blend mode (5.11.0)
particle_blend_clip = true,
} }
``` ```
@ -6178,7 +6186,7 @@ Setting-related
* `core.settings`: Settings object containing all of the settings from the * `core.settings`: Settings object containing all of the settings from the
main config file (`minetest.conf`). See [`Settings`]. main config file (`minetest.conf`). See [`Settings`].
* `core.setting_get_pos(name)`: Loads a setting from the main settings and * `core.setting_get_pos(name)`: Loads a setting from the main settings and
parses it as a position (in the format `(1,2,3)`). Returns a position or nil. parses it as a position (in the format `(1,2,3)`). Returns a position or nil. **Deprecated: use `core.settings:get_pos()` instead**
Authentication Authentication
-------------- --------------
@ -6557,7 +6565,7 @@ Environment access
* `pointabilities`: Allows overriding the `pointable` property of * `pointabilities`: Allows overriding the `pointable` property of
nodes and objects. Uses the same format as the `pointabilities` property nodes and objects. Uses the same format as the `pointabilities` property
of item definitions. Default is `nil`. of item definitions. Default is `nil`.
* `core.find_path(pos1,pos2,searchdistance,max_jump,max_drop,algorithm)` * `core.find_path(pos1, pos2, searchdistance, max_jump, max_drop, algorithm)`
* returns table containing path that can be walked on * returns table containing path that can be walked on
* returns a table of 3D points representing a path from `pos1` to `pos2` or * returns a table of 3D points representing a path from `pos1` to `pos2` or
`nil` on failure. `nil` on failure.
@ -6577,8 +6585,11 @@ Environment access
Difference between `"A*"` and `"A*_noprefetch"` is that Difference between `"A*"` and `"A*_noprefetch"` is that
`"A*"` will pre-calculate the cost-data, the other will calculate it `"A*"` will pre-calculate the cost-data, the other will calculate it
on-the-fly on-the-fly
* `core.spawn_tree (pos, {treedef})` * `core.spawn_tree(pos, treedef)`
* spawns L-system tree at given `pos` with definition in `treedef` table * spawns L-system tree at given `pos` with definition in `treedef` table
* `core.spawn_tree_on_vmanip(vmanip, pos, treedef)`
* analogous to `core.spawn_tree`, but spawns a L-system tree onto the specified
VoxelManip object `vmanip` instead of the map.
* `core.transforming_liquid_add(pos)` * `core.transforming_liquid_add(pos)`
* add node to liquid flow update queue * add node to liquid flow update queue
* `core.get_node_max_level(pos)` * `core.get_node_max_level(pos)`
@ -6697,6 +6708,9 @@ Formspec
* `core.hypertext_escape(string)`: returns a string * `core.hypertext_escape(string)`: returns a string
* escapes the characters "\", "<", and ">" to show text in a hypertext element. * escapes the characters "\", "<", and ">" to show text in a hypertext element.
* not safe for use with tag attributes. * not safe for use with tag attributes.
* this function does not do formspec escaping, you will likely need to do
`core.formspec_escape(core.hypertext_escape(string))` if the hypertext is
not already being formspec escaped.
* `core.explode_table_event(string)`: returns a table * `core.explode_table_event(string)`: returns a table
* returns e.g. `{type="CHG", row=1, column=2}` * returns e.g. `{type="CHG", row=1, column=2}`
* `type` is one of: * `type` is one of:
@ -8890,7 +8904,7 @@ For `core.get_perlin_map()`, the actual seed used is the noiseparams seed
plus the world seed, to create world-specific noise. plus the world seed, to create world-specific noise.
Format of `size` is `{x=dimx, y=dimy, z=dimz}`. The `z` component is omitted Format of `size` is `{x=dimx, y=dimy, z=dimz}`. The `z` component is omitted
for 2D noise, and it must be must be larger than 1 for 3D noise (otherwise for 2D noise, and it must be larger than 1 for 3D noise (otherwise
`nil` is returned). `nil` is returned).
For each of the functions with an optional `buffer` parameter: If `buffer` is For each of the functions with an optional `buffer` parameter: If `buffer` is
@ -9046,6 +9060,9 @@ means that no defaults will be returned for mod settings.
* Is currently limited to mapgen flags `mg_flags` and mapgen-specific * Is currently limited to mapgen flags `mg_flags` and mapgen-specific
flags like `mgv5_spflags`. flags like `mgv5_spflags`.
* Returns `nil` if `key` is not found. * Returns `nil` if `key` is not found.
* `get_pos(key)`:
* Returns a `vector`
* Returns `nil` if no value is found or parsing failed.
* `set(key, value)` * `set(key, value)`
* Setting names can't contain whitespace or any of `="{}#`. * Setting names can't contain whitespace or any of `="{}#`.
* Setting values can't contain the sequence `\n"""`. * Setting values can't contain the sequence `\n"""`.
@ -9056,6 +9073,9 @@ means that no defaults will be returned for mod settings.
* `set_np_group(key, value)` * `set_np_group(key, value)`
* `value` is a NoiseParams table. * `value` is a NoiseParams table.
* Also, see documentation for `set()` above. * Also, see documentation for `set()` above.
* `set_pos(key, value)`
* `value` is a `vector`.
* Also, see documentation for `set()` above.
* `remove(key)`: returns a boolean (`true` for success) * `remove(key)`: returns a boolean (`true` for success)
* `get_names()`: returns `{key1,...}` * `get_names()`: returns `{key1,...}`
* `has(key)`: * `has(key)`:
@ -10709,6 +10729,10 @@ performance and computing power the practical limit is much lower.
-- distribution of the biomes. -- distribution of the biomes.
-- Heat and humidity have average values of 50, vary mostly between -- Heat and humidity have average values of 50, vary mostly between
-- 0 and 100 but can exceed these values. -- 0 and 100 but can exceed these values.
weight = 1.0,
-- Relative weight of the biome in the Voronoi diagram.
-- A value of 0 (or less) is ignored and equivalent to 1.0.
} }
``` ```
@ -10782,10 +10806,9 @@ See [Decoration types]. Used by `core.register_decoration`.
flags = "liquid_surface, force_placement, all_floors, all_ceilings", flags = "liquid_surface, force_placement, all_floors, all_ceilings",
-- Flags for all decoration types. -- Flags for all decoration types.
-- "liquid_surface": Instead of placement on the highest solid surface -- "liquid_surface": Find the highest liquid (not solid) surface under
-- in a mapchunk column, placement is on the highest liquid surface. -- open air. Search stops and fails on the first solid node.
-- Placement is disabled if solid nodes are found above the liquid -- Cannot be used with "all_floors" or "all_ceilings" below.
-- surface.
-- "force_placement": Nodes other than "air" and "ignore" are replaced -- "force_placement": Nodes other than "air" and "ignore" are replaced
-- by the decoration. -- by the decoration.
-- "all_floors", "all_ceilings": Instead of placement on the highest -- "all_floors", "all_ceilings": Instead of placement on the highest
@ -11480,6 +11503,14 @@ texture = {
-- (default) blends transparent pixels with those they are drawn atop -- (default) blends transparent pixels with those they are drawn atop
-- according to the alpha channel of the source texture. useful for -- according to the alpha channel of the source texture. useful for
-- e.g. material objects like rocks, dirt, smoke, or node chunks -- e.g. material objects like rocks, dirt, smoke, or node chunks
-- note: there will be rendering bugs when particles interact with
-- translucent nodes. particles are also not transparency-sorted
-- relative to each other.
blend = "clip",
-- pixels are either fully opaque or fully transparent,
-- depending on whether alpha is greater than or less than 50%
-- (just like `use_texture_alpha = "clip"` for nodes).
-- you should prefer this if you don't need semi-transparency, as it's faster.
blend = "add", blend = "add",
-- adds the value of pixels to those underneath them, modulo the sources -- adds the value of pixels to those underneath them, modulo the sources
-- alpha channel. useful for e.g. bright light effects like sparks or fire -- alpha channel. useful for e.g. bright light effects like sparks or fire

View File

@ -1,4 +1,4 @@
Luanti Lua Mainmenu API Reference 5.10.0 Luanti Lua Mainmenu API Reference 5.11.0
======================================== ========================================
Introduction Introduction
@ -223,6 +223,7 @@ GUI
* `core.set_clouds(<true/false>)` * `core.set_clouds(<true/false>)`
* `core.set_topleft_text(text)` * `core.set_topleft_text(text)`
* `core.show_keys_menu()` * `core.show_keys_menu()`
* `core.show_touchscreen_layout()`
* `core.show_path_select_dialog(formname, caption, is_file_select)` * `core.show_path_select_dialog(formname, caption, is_file_select)`
* shows a path select dialog * shows a path select dialog
* `formname` is base name of dialog response returned in fields * `formname` is base name of dialog response returned in fields

View File

@ -23,6 +23,7 @@ read_globals = {
"fgettext", "fgettext_ne", "fgettext", "fgettext_ne",
"vector", "vector",
"VoxelArea", "VoxelArea",
"VoxelManip",
"profiler", "profiler",
"Settings", "Settings",
"check", "check",

View File

@ -55,6 +55,20 @@ core.register_entity("gltf:simple_skin", {
end end
}) })
core.register_entity("gltf:simple_skin_step", {
initial_properties = {
infotext = "Simple skin, but using STEP interpolation",
visual = "mesh",
visual_size = vector.new(5, 5, 5),
mesh = "gltf_simple_skin_step.gltf",
textures = {},
backface_culling = false
},
on_activate = function(self)
self.object:set_animation({x = 0, y = 5.5}, 1)
end
})
-- The claws rendering incorrectly from one side is expected behavior: -- The claws rendering incorrectly from one side is expected behavior:
-- They use an unsupported double-sided material. -- They use an unsupported double-sided material.
core.register_entity("gltf:frog", { core.register_entity("gltf:frog", {

View File

@ -0,0 +1 @@
{"scene":0,"scenes":[{"nodes":[0,1]}],"nodes":[{"skin":0,"mesh":0},{"children":[2]},{"translation":[0.0,1.0,0.0],"rotation":[0.0,0.0,0.0,1.0]}],"meshes":[{"primitives":[{"attributes":{"POSITION":1,"JOINTS_0":2,"WEIGHTS_0":3},"indices":0}]}],"skins":[{"inverseBindMatrices":4,"joints":[1,2]}],"animations":[{"channels":[{"sampler":0,"target":{"node":2,"path":"rotation"}}],"samplers":[{"input":5,"interpolation":"STEP","output":6}]}],"buffers":[{"uri":"data:application/gltf-buffer;base64,AAABAAMAAAADAAIAAgADAAUAAgAFAAQABAAFAAcABAAHAAYABgAHAAkABgAJAAgAAAAAvwAAAAAAAAAAAAAAPwAAAAAAAAAAAAAAvwAAAD8AAAAAAAAAPwAAAD8AAAAAAAAAvwAAgD8AAAAAAAAAPwAAgD8AAAAAAAAAvwAAwD8AAAAAAAAAPwAAwD8AAAAAAAAAvwAAAEAAAAAAAAAAPwAAAEAAAAAA","byteLength":168},{"uri":"data:application/gltf-buffer;base64,AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAABAPwAAgD4AAAAAAAAAAAAAQD8AAIA+AAAAAAAAAAAAAAA/AAAAPwAAAAAAAAAAAAAAPwAAAD8AAAAAAAAAAAAAgD4AAEA/AAAAAAAAAAAAAIA+AABAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAA=","byteLength":320},{"uri":"data:application/gltf-buffer;base64,AACAPwAAAAAAAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAAAAAACAPwAAgD8AAAAAAAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAIC/AAAAAAAAgD8=","byteLength":128},{"uri":"data:application/gltf-buffer;base64,AAAAAAAAAD8AAIA/AADAPwAAAEAAACBAAABAQAAAYEAAAIBAAACQQAAAoEAAALBAAAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAkxjEPkSLbD8AAAAAAAAAAPT9ND/0/TQ/AAAAAAAAAAD0/TQ/9P00PwAAAAAAAAAAkxjEPkSLbD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAkxjEvkSLbD8AAAAAAAAAAPT9NL/0/TQ/AAAAAAAAAAD0/TS/9P00PwAAAAAAAAAAkxjEvkSLbD8AAAAAAAAAAAAAAAAAAIA/","byteLength":240}],"bufferViews":[{"buffer":0,"byteLength":48,"target":34963},{"buffer":0,"byteOffset":48,"byteLength":120,"target":34962},{"buffer":1,"byteLength":320,"byteStride":16},{"buffer":2,"byteLength":128},{"buffer":3,"byteLength":240}],"accessors":[{"bufferView":0,"componentType":5123,"count":24,"type":"SCALAR"},{"bufferView":1,"componentType":5126,"count":10,"type":"VEC3","max":[0.5,2.0,0.0],"min":[-0.5,0.0,0.0]},{"bufferView":2,"componentType":5123,"count":10,"type":"VEC4"},{"bufferView":2,"byteOffset":160,"componentType":5126,"count":10,"type":"VEC4"},{"bufferView":3,"componentType":5126,"count":2,"type":"MAT4"},{"bufferView":4,"componentType":5126,"count":12,"type":"SCALAR","max":[5.5],"min":[0.0]},{"bufferView":4,"byteOffset":48,"componentType":5126,"count":12,"type":"VEC4","max":[0.0,0.0,0.707,1.0],"min":[0.0,0.0,-0.707,0.707]}],"asset":{"version":"2.0"}}

View File

@ -1,3 +1,5 @@
"Minetest Sam":
Original model by MirceaKitsune (CC BY-SA 3.0). Original model by MirceaKitsune (CC BY-SA 3.0).
Various alterations and fixes by kilbith, sofar, xunto, Rogier-5, TeTpaAka, Desour, Various alterations and fixes by kilbith, sofar, xunto, Rogier-5, TeTpaAka, Desour,
stujones11, An0n3m0us (CC BY-SA 3.0): stujones11, An0n3m0us (CC BY-SA 3.0):
@ -5,3 +7,9 @@ stujones11, An0n3m0us (CC BY-SA 3.0):
Jordach (CC BY-SA 3.0): Jordach (CC BY-SA 3.0):
testentities_sam.png testentities_sam.png
"Lava Flan":
Zeg9 (CC BY-SA 3.0):
testentities_lava_flan.x
testentities_lava_flan.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

File diff suppressed because it is too large Load Diff

View File

@ -79,6 +79,20 @@ core.register_entity("testentities:sam", {
end, end,
}) })
core.register_entity("testentities:lava_flan", {
initial_properties = {
infotext = "Lava Flan (smoke test .x)",
visual = "mesh",
mesh = "testentities_lava_flan.x",
textures = {
"testentities_lava_flan.png"
},
},
on_activate = function(self)
self.object:set_animation({x = 0, y = 28}, 15, 0, true)
end,
})
-- Advanced visual tests -- Advanced visual tests
-- An entity for testing animated and yaw-modulated sprites -- An entity for testing animated and yaw-modulated sprites

View File

@ -105,3 +105,68 @@ core.register_craftitem("testitems:telescope_stick", {
return itemstack return itemstack
end, end,
}) })
-- Tree spawners
local tree_def={
axiom="Af",
rules_a="TT[&GB][&+GB][&++GB][&+++GB]A",
rules_b="[+GB]fB",
trunk="basenodes:tree",
leaves="basenodes:leaves",
angle=90,
iterations=4,
trunk_type="single",
thin_branches=true,
}
core.register_craftitem("testitems:tree_spawner", {
description = S("Tree Spawner"),
inventory_image = "testitems_tree_spawner.png",
on_place = function(itemstack, placer, pointed_thing)
if (not pointed_thing or pointed_thing.type ~= "node") then
return
end
core.spawn_tree(pointed_thing.above, tree_def)
end,
})
local vmanip_for_trees = {} -- per player
core.register_craftitem("testitems:tree_spawner_vmanip", {
description = S("Tree Spawner using VoxelManip"),
inventory_image = "testitems_tree_spawner_vmanip.png",
on_place = function(itemstack, placer, pointed_thing)
if (not pointed_thing or pointed_thing.type ~= "node" or
not core.is_player(placer)) then
return
end
local name = placer:get_player_name()
local vm = vmanip_for_trees[name]
if not vm then
vm = VoxelManip(vector.add(pointed_thing.above, 20),
vector.subtract(pointed_thing.above, 20))
vmanip_for_trees[name] = vm
core.chat_send_player(name,
"Tree in new VoxelManip spawned, left click to apply to map, "..
"or right click to add more trees.")
end
core.spawn_tree_on_vmanip(vm, pointed_thing.above, tree_def)
end,
on_use = function(itemstack, user, pointed_thing)
if not core.is_player(user) then
return
end
local name = user:get_player_name()
local vm = vmanip_for_trees[name]
if vm then
vm:write_to_map()
vmanip_for_trees[name] = nil
core.chat_send_player(name, "VoxelManip written to map.")
end
end,
})
core.register_on_leaveplayer(function(player, timed_out)
vmanip_for_trees[player:get_player_name()] = nil
end)

Binary file not shown.

After

Width:  |  Height:  |  Size: 120 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 150 B

View File

@ -1,14 +1,27 @@
local function spawn_clip_test_particle(pos)
core.add_particle({
pos = pos,
size = 5,
expirationtime = 10,
texture = {
name = "testtools_particle_clip.png",
blend = "clip",
},
})
end
core.register_tool("testtools:particle_spawner", { core.register_tool("testtools:particle_spawner", {
description = "Particle Spawner".."\n".. description = table.concat({
"Particle Spawner",
"Punch: Spawn random test particle", "Punch: Spawn random test particle",
"Place: Spawn clip test particle",
}, "\n"),
inventory_image = "testtools_particle_spawner.png", inventory_image = "testtools_particle_spawner.png",
groups = { testtool = 1, disable_repair = 1 }, groups = { testtool = 1, disable_repair = 1 },
on_use = function(itemstack, user, pointed_thing) on_use = function(itemstack, user, pointed_thing)
local pos = core.get_pointed_thing_position(pointed_thing, true) local pos = core.get_pointed_thing_position(pointed_thing, true)
if pos == nil then if pos == nil then
if user then pos = assert(user):get_pos()
pos = user:get_pos()
end
end end
pos = vector.add(pos, {x=0, y=0.5, z=0}) pos = vector.add(pos, {x=0, y=0.5, z=0})
local tex, anim local tex, anim
@ -32,5 +45,12 @@ core.register_tool("testtools:particle_spawner", {
glow = math.random(0, 5), glow = math.random(0, 5),
}) })
end, end,
on_place = function(itemstack, user, pointed_thing)
local pos = assert(core.get_pointed_thing_position(pointed_thing, true))
spawn_clip_test_particle(pos)
end,
on_secondary_use = function(_, user)
spawn_clip_test_particle(assert(user):get_pos())
end,
}) })

Binary file not shown.

After

Width:  |  Height:  |  Size: 179 B

View File

@ -21,7 +21,7 @@ Aside from standard search options (`ZLIB_INCLUDE_DIR`, `ZLIB_LIBRARY`, ...) the
* `ENABLE_OPENGL` - Enable OpenGL driver * `ENABLE_OPENGL` - Enable OpenGL driver
* `ENABLE_OPENGL3` (default: `OFF`) - Enable OpenGL 3+ driver * `ENABLE_OPENGL3` (default: `OFF`) - Enable OpenGL 3+ driver
* `ENABLE_GLES2` - Enable OpenGL ES 2+ driver * `ENABLE_GLES2` - Enable OpenGL ES 2+ driver
* `USE_SDL2` (default: ON for Android, OFF for other platforms) - Use SDL2 instead of older native device code * `USE_SDL2` (default: platform-dependent, usually `ON`) - Use SDL2 instead of older native device code
However, IrrlichtMt cannot be built or installed separately. However, IrrlichtMt cannot be built or installed separately.
@ -36,6 +36,27 @@ We aim to support these platforms:
This doesn't mean other platforms don't work or won't be supported, if you find something that doesn't work contributions are welcome. This doesn't mean other platforms don't work or won't be supported, if you find something that doesn't work contributions are welcome.
Compatibility matrix
--------------------
Driver (rows) vs Device (columns)
| | SDL [1] | Linux [2] | OSX [3] | Win32 [4] |
|---------------------------|----------|----------------|------------------|-----------------|
| OpenGL 1.2 (to 2.1) | Works | Works (GLX) | Works (NSOpenGL) | Works (WGL) |
| OpenGL 3.2+ | Works | Testing (GLX) | Not implemented | Testing (WGL) |
| OpenGL ES 2.x | Works | Untested (EGL) | Not implemented | Untested (EGL) |
| WebGL 1 | Untested | Untested (EGL) | Not implemented | Not implemented |
| Null (no graphics output) | Works | Works | Works | Works |
Notes:
* [1] `CIrrDeviceSDL`: supports Android, Linux, macOS, Windows
* [2] `CIrrDeviceLinux`: supports Linux
* [3] `CIrrDeviceOSX`: supports macOS
* [4] `CIrrDeviceWin32`: supports Windows
License License
------- -------

View File

@ -24,12 +24,7 @@ class CIndexBuffer final : public IIndexBuffer
{ {
public: public:
//! Default constructor for empty buffer //! Default constructor for empty buffer
CIndexBuffer() CIndexBuffer() {}
{
#ifdef _DEBUG
setDebugName("CIndexBuffer");
#endif
}
video::E_INDEX_TYPE getType() const override video::E_INDEX_TYPE getType() const override
{ {

View File

@ -22,9 +22,6 @@ public:
CMeshBuffer() : CMeshBuffer() :
PrimitiveType(EPT_TRIANGLES) PrimitiveType(EPT_TRIANGLES)
{ {
#ifdef _DEBUG
setDebugName("CMeshBuffer");
#endif
Vertices = new CVertexBuffer<T>(); Vertices = new CVertexBuffer<T>();
Indices = new SIndexBuffer(); Indices = new SIndexBuffer();
} }
@ -137,7 +134,7 @@ public:
//! Index buffer //! Index buffer
SIndexBuffer *Indices; SIndexBuffer *Indices;
//! Bounding box of this meshbuffer. //! Bounding box of this meshbuffer.
core::aabbox3d<f32> BoundingBox; core::aabbox3d<f32> BoundingBox{{0, 0, 0}};
//! Primitive type used for rendering (triangles, lines, ...) //! Primitive type used for rendering (triangles, lines, ...)
E_PRIMITIVE_TYPE PrimitiveType; E_PRIMITIVE_TYPE PrimitiveType;
}; };

View File

@ -24,12 +24,7 @@ class CVertexBuffer final : public IVertexBuffer
{ {
public: public:
//! Default constructor for empty buffer //! Default constructor for empty buffer
CVertexBuffer() CVertexBuffer() {}
{
#ifdef _DEBUG
setDebugName("CVertexBuffer");
#endif
}
const void *getData() const override const void *getData() const override
{ {

View File

@ -129,6 +129,9 @@ enum E_VIDEO_DRIVER_FEATURE
//! Support for clamping vertices beyond far-plane to depth instead of capping them. //! Support for clamping vertices beyond far-plane to depth instead of capping them.
EVDF_DEPTH_CLAMP, EVDF_DEPTH_CLAMP,
//! Support for multisample textures.
EVDF_TEXTURE_MULTISAMPLE,
//! Only used for counting the elements of this enum //! Only used for counting the elements of this enum
EVDF_COUNT EVDF_COUNT
}; };

View File

@ -1,85 +0,0 @@
#pragma once
#include "irrTypes.h"
namespace irr
{
namespace video
{
//! Compile target enumeration for the addHighLevelShaderMaterial() method.
enum E_VERTEX_SHADER_TYPE
{
EVST_VS_1_1 = 0,
EVST_VS_2_0,
EVST_VS_2_a,
EVST_VS_3_0,
EVST_VS_4_0,
EVST_VS_4_1,
EVST_VS_5_0,
//! This is not a type, but a value indicating how much types there are.
EVST_COUNT
};
//! Names for all vertex shader types, each entry corresponds to a E_VERTEX_SHADER_TYPE entry.
const c8 *const VERTEX_SHADER_TYPE_NAMES[] = {
"vs_1_1",
"vs_2_0",
"vs_2_a",
"vs_3_0",
"vs_4_0",
"vs_4_1",
"vs_5_0",
0};
//! Compile target enumeration for the addHighLevelShaderMaterial() method.
enum E_PIXEL_SHADER_TYPE
{
EPST_PS_1_1 = 0,
EPST_PS_1_2,
EPST_PS_1_3,
EPST_PS_1_4,
EPST_PS_2_0,
EPST_PS_2_a,
EPST_PS_2_b,
EPST_PS_3_0,
EPST_PS_4_0,
EPST_PS_4_1,
EPST_PS_5_0,
//! This is not a type, but a value indicating how much types there are.
EPST_COUNT
};
//! Names for all pixel shader types, each entry corresponds to a E_PIXEL_SHADER_TYPE entry.
const c8 *const PIXEL_SHADER_TYPE_NAMES[] = {
"ps_1_1",
"ps_1_2",
"ps_1_3",
"ps_1_4",
"ps_2_0",
"ps_2_a",
"ps_2_b",
"ps_3_0",
"ps_4_0",
"ps_4_1",
"ps_5_0",
0};
//! Enum for supported geometry shader types
enum E_GEOMETRY_SHADER_TYPE
{
EGST_GS_4_0 = 0,
//! This is not a type, but a value indicating how much types there are.
EGST_COUNT
};
//! String names for supported geometry shader types
const c8 *const GEOMETRY_SHADER_TYPE_NAMES[] = {
"gs_4_0",
0};
} // end namespace video
} // end namespace irr

View File

@ -48,7 +48,7 @@ const c8 *const BoneAnimationModeNames[] = {
}; };
//! Interface for bones used for skeletal animation. //! Interface for bones used for skeletal animation.
/** Used with ISkinnedMesh and IAnimatedMeshSceneNode. */ /** Used with SkinnedMesh and IAnimatedMeshSceneNode. */
class IBoneSceneNode : public ISceneNode class IBoneSceneNode : public ISceneNode
{ {
public: public:

View File

@ -4,7 +4,6 @@
#pragma once #pragma once
#include "EShaderTypes.h"
#include "EMaterialTypes.h" #include "EMaterialTypes.h"
#include "EPrimitiveTypes.h" #include "EPrimitiveTypes.h"
#include "path.h" #include "path.h"
@ -31,26 +30,15 @@ public:
virtual ~IGPUProgrammingServices() {} virtual ~IGPUProgrammingServices() {}
//! Adds a new high-level shading material renderer to the VideoDriver. //! Adds a new high-level shading material renderer to the VideoDriver.
/** Currently only HLSL/D3D9 and GLSL/OpenGL are supported. /**
\param vertexShaderProgram String containing the source of the vertex \param vertexShaderProgram String containing the source of the vertex
shader program. This can be 0 if no vertex program shall be used. shader program. This can be 0 if no vertex program shall be used.
\param vertexShaderEntryPointName Name of the entry function of the
vertexShaderProgram (p.e. "main")
\param vsCompileTarget Vertex shader version the high level shader
shall be compiled to.
\param pixelShaderProgram String containing the source of the pixel \param pixelShaderProgram String containing the source of the pixel
shader program. This can be 0 if no pixel shader shall be used. shader program. This can be 0 if no pixel shader shall be used.
\param pixelShaderEntryPointName Entry name of the function of the
pixelShaderProgram (p.e. "main")
\param psCompileTarget Pixel shader version the high level shader
shall be compiled to.
\param geometryShaderProgram String containing the source of the \param geometryShaderProgram String containing the source of the
geometry shader program. This can be 0 if no geometry shader shall be geometry shader program. This can be 0 if no geometry shader shall be
used. used.
\param geometryShaderEntryPointName Entry name of the function of the \param shaderName Name of the shader for debug purposes
geometryShaderProgram (p.e. "main")
\param gsCompileTarget Geometry shader version the high level shader
shall be compiled to.
\param inType Type of vertices passed to geometry shader \param inType Type of vertices passed to geometry shader
\param outType Type of vertices created by geometry shader \param outType Type of vertices created by geometry shader
\param verticesOut Maximal number of vertices created by geometry \param verticesOut Maximal number of vertices created by geometry
@ -73,108 +61,43 @@ public:
error log and can be caught with a custom event receiver. */ error log and can be caught with a custom event receiver. */
virtual s32 addHighLevelShaderMaterial( virtual s32 addHighLevelShaderMaterial(
const c8 *vertexShaderProgram, const c8 *vertexShaderProgram,
const c8 *vertexShaderEntryPointName,
E_VERTEX_SHADER_TYPE vsCompileTarget,
const c8 *pixelShaderProgram, const c8 *pixelShaderProgram,
const c8 *pixelShaderEntryPointName,
E_PIXEL_SHADER_TYPE psCompileTarget,
const c8 *geometryShaderProgram, const c8 *geometryShaderProgram,
const c8 *geometryShaderEntryPointName = "main", const c8 *shaderName = nullptr,
E_GEOMETRY_SHADER_TYPE gsCompileTarget = EGST_GS_4_0,
scene::E_PRIMITIVE_TYPE inType = scene::EPT_TRIANGLES, scene::E_PRIMITIVE_TYPE inType = scene::EPT_TRIANGLES,
scene::E_PRIMITIVE_TYPE outType = scene::EPT_TRIANGLE_STRIP, scene::E_PRIMITIVE_TYPE outType = scene::EPT_TRIANGLE_STRIP,
u32 verticesOut = 0, u32 verticesOut = 0,
IShaderConstantSetCallBack *callback = 0, IShaderConstantSetCallBack *callback = nullptr,
E_MATERIAL_TYPE baseMaterial = video::EMT_SOLID, E_MATERIAL_TYPE baseMaterial = video::EMT_SOLID,
s32 userData = 0) = 0; s32 userData = 0) = 0;
//! convenience function for use without geometry shaders //! convenience function for use without geometry shaders
s32 addHighLevelShaderMaterial( s32 addHighLevelShaderMaterial(
const c8 *vertexShaderProgram, const c8 *vertexShaderProgram,
const c8 *vertexShaderEntryPointName = "main", const c8 *pixelShaderProgram = nullptr,
E_VERTEX_SHADER_TYPE vsCompileTarget = EVST_VS_1_1, const c8 *shaderName = nullptr,
const c8 *pixelShaderProgram = 0, IShaderConstantSetCallBack *callback = nullptr,
const c8 *pixelShaderEntryPointName = "main",
E_PIXEL_SHADER_TYPE psCompileTarget = EPST_PS_1_1,
IShaderConstantSetCallBack *callback = 0,
E_MATERIAL_TYPE baseMaterial = video::EMT_SOLID, E_MATERIAL_TYPE baseMaterial = video::EMT_SOLID,
s32 userData = 0) s32 userData = 0)
{ {
return addHighLevelShaderMaterial( return addHighLevelShaderMaterial(
vertexShaderProgram, vertexShaderEntryPointName, vertexShaderProgram, pixelShaderProgram,
vsCompileTarget, pixelShaderProgram, nullptr, shaderName,
pixelShaderEntryPointName, psCompileTarget,
0, "main", EGST_GS_4_0,
scene::EPT_TRIANGLES, scene::EPT_TRIANGLE_STRIP, 0, scene::EPT_TRIANGLES, scene::EPT_TRIANGLE_STRIP, 0,
callback, baseMaterial, userData); callback, baseMaterial, userData);
} }
//! convenience function for use with many defaults, without geometry shader
/** All shader names are set to "main" and compile targets are shader
type 1.1.
*/
s32 addHighLevelShaderMaterial(
const c8 *vertexShaderProgram,
const c8 *pixelShaderProgram = 0,
IShaderConstantSetCallBack *callback = 0,
E_MATERIAL_TYPE baseMaterial = video::EMT_SOLID,
s32 userData = 0)
{
return addHighLevelShaderMaterial(
vertexShaderProgram, "main",
EVST_VS_1_1, pixelShaderProgram,
"main", EPST_PS_1_1,
0, "main", EGST_GS_4_0,
scene::EPT_TRIANGLES, scene::EPT_TRIANGLE_STRIP, 0,
callback, baseMaterial, userData);
}
//! convenience function for use with many defaults, with geometry shader
/** All shader names are set to "main" and compile targets are shader
type 1.1 and geometry shader 4.0.
*/
s32 addHighLevelShaderMaterial(
const c8 *vertexShaderProgram,
const c8 *pixelShaderProgram = 0,
const c8 *geometryShaderProgram = 0,
scene::E_PRIMITIVE_TYPE inType = scene::EPT_TRIANGLES,
scene::E_PRIMITIVE_TYPE outType = scene::EPT_TRIANGLE_STRIP,
u32 verticesOut = 0,
IShaderConstantSetCallBack *callback = 0,
E_MATERIAL_TYPE baseMaterial = video::EMT_SOLID,
s32 userData = 0)
{
return addHighLevelShaderMaterial(
vertexShaderProgram, "main",
EVST_VS_1_1, pixelShaderProgram,
"main", EPST_PS_1_1,
geometryShaderProgram, "main", EGST_GS_4_0,
inType, outType, verticesOut,
callback, baseMaterial, userData);
}
//! Like addHighLevelShaderMaterial(), but loads from files. //! Like addHighLevelShaderMaterial(), but loads from files.
/** \param vertexShaderProgramFileName Text file containing the source /** \param vertexShaderProgramFileName Text file containing the source
of the vertex shader program. Set to empty string if no vertex shader of the vertex shader program. Set to empty string if no vertex shader
shall be created. shall be created.
\param vertexShaderEntryPointName Name of the entry function of the
vertexShaderProgram (p.e. "main")
\param vsCompileTarget Vertex shader version the high level shader
shall be compiled to.
\param pixelShaderProgramFileName Text file containing the source of \param pixelShaderProgramFileName Text file containing the source of
the pixel shader program. Set to empty string if no pixel shader shall the pixel shader program. Set to empty string if no pixel shader shall
be created. be created.
\param pixelShaderEntryPointName Entry name of the function of the
pixelShaderProgram (p.e. "main")
\param psCompileTarget Pixel shader version the high level shader
shall be compiled to.
\param geometryShaderProgramFileName Name of the source of \param geometryShaderProgramFileName Name of the source of
the geometry shader program. Set to empty string if no geometry shader the geometry shader program. Set to empty string if no geometry shader
shall be created. shall be created.
\param geometryShaderEntryPointName Entry name of the function of the \param shaderName Name of the shader for debug purposes
geometryShaderProgram (p.e. "main")
\param gsCompileTarget Geometry shader version the high level shader
shall be compiled to.
\param inType Type of vertices passed to geometry shader \param inType Type of vertices passed to geometry shader
\param outType Type of vertices created by geometry shader \param outType Type of vertices created by geometry shader
\param verticesOut Maximal number of vertices created by geometry \param verticesOut Maximal number of vertices created by geometry
@ -197,164 +120,16 @@ public:
error log and can be caught with a custom event receiver. */ error log and can be caught with a custom event receiver. */
virtual s32 addHighLevelShaderMaterialFromFiles( virtual s32 addHighLevelShaderMaterialFromFiles(
const io::path &vertexShaderProgramFileName, const io::path &vertexShaderProgramFileName,
const c8 *vertexShaderEntryPointName,
E_VERTEX_SHADER_TYPE vsCompileTarget,
const io::path &pixelShaderProgramFileName, const io::path &pixelShaderProgramFileName,
const c8 *pixelShaderEntryPointName,
E_PIXEL_SHADER_TYPE psCompileTarget,
const io::path &geometryShaderProgramFileName, const io::path &geometryShaderProgramFileName,
const c8 *geometryShaderEntryPointName = "main", const c8 *shaderName = nullptr,
E_GEOMETRY_SHADER_TYPE gsCompileTarget = EGST_GS_4_0,
scene::E_PRIMITIVE_TYPE inType = scene::EPT_TRIANGLES, scene::E_PRIMITIVE_TYPE inType = scene::EPT_TRIANGLES,
scene::E_PRIMITIVE_TYPE outType = scene::EPT_TRIANGLE_STRIP, scene::E_PRIMITIVE_TYPE outType = scene::EPT_TRIANGLE_STRIP,
u32 verticesOut = 0, u32 verticesOut = 0,
IShaderConstantSetCallBack *callback = 0, IShaderConstantSetCallBack *callback = nullptr,
E_MATERIAL_TYPE baseMaterial = video::EMT_SOLID, E_MATERIAL_TYPE baseMaterial = video::EMT_SOLID,
s32 userData = 0) = 0; s32 userData = 0) = 0;
//! convenience function for use without geometry shaders
s32 addHighLevelShaderMaterialFromFiles(
const io::path &vertexShaderProgramFileName,
const c8 *vertexShaderEntryPointName = "main",
E_VERTEX_SHADER_TYPE vsCompileTarget = EVST_VS_1_1,
const io::path &pixelShaderProgramFileName = "",
const c8 *pixelShaderEntryPointName = "main",
E_PIXEL_SHADER_TYPE psCompileTarget = EPST_PS_1_1,
IShaderConstantSetCallBack *callback = 0,
E_MATERIAL_TYPE baseMaterial = video::EMT_SOLID,
s32 userData = 0)
{
return addHighLevelShaderMaterialFromFiles(
vertexShaderProgramFileName, vertexShaderEntryPointName,
vsCompileTarget, pixelShaderProgramFileName,
pixelShaderEntryPointName, psCompileTarget,
"", "main", EGST_GS_4_0,
scene::EPT_TRIANGLES, scene::EPT_TRIANGLE_STRIP, 0,
callback, baseMaterial, userData);
}
//! convenience function for use with many defaults, without geometry shader
/** All shader names are set to "main" and compile targets are shader
type 1.1.
*/
s32 addHighLevelShaderMaterialFromFiles(
const io::path &vertexShaderProgramFileName,
const io::path &pixelShaderProgramFileName = "",
IShaderConstantSetCallBack *callback = 0,
E_MATERIAL_TYPE baseMaterial = video::EMT_SOLID,
s32 userData = 0)
{
return addHighLevelShaderMaterialFromFiles(
vertexShaderProgramFileName, "main",
EVST_VS_1_1, pixelShaderProgramFileName,
"main", EPST_PS_1_1,
"", "main", EGST_GS_4_0,
scene::EPT_TRIANGLES, scene::EPT_TRIANGLE_STRIP, 0,
callback, baseMaterial, userData);
}
//! convenience function for use with many defaults, with geometry shader
/** All shader names are set to "main" and compile targets are shader
type 1.1 and geometry shader 4.0.
*/
s32 addHighLevelShaderMaterialFromFiles(
const io::path &vertexShaderProgramFileName,
const io::path &pixelShaderProgramFileName = "",
const io::path &geometryShaderProgramFileName = "",
scene::E_PRIMITIVE_TYPE inType = scene::EPT_TRIANGLES,
scene::E_PRIMITIVE_TYPE outType = scene::EPT_TRIANGLE_STRIP,
u32 verticesOut = 0,
IShaderConstantSetCallBack *callback = 0,
E_MATERIAL_TYPE baseMaterial = video::EMT_SOLID,
s32 userData = 0)
{
return addHighLevelShaderMaterialFromFiles(
vertexShaderProgramFileName, "main",
EVST_VS_1_1, pixelShaderProgramFileName,
"main", EPST_PS_1_1,
geometryShaderProgramFileName, "main", EGST_GS_4_0,
inType, outType, verticesOut,
callback, baseMaterial, userData);
}
//! Like addHighLevelShaderMaterial(), but loads from files.
/** \param vertexShaderProgram Text file handle containing the source
of the vertex shader program. Set to 0 if no vertex shader shall be
created.
\param vertexShaderEntryPointName Name of the entry function of the
vertexShaderProgram
\param vsCompileTarget Vertex shader version the high level shader
shall be compiled to.
\param pixelShaderProgram Text file handle containing the source of
the pixel shader program. Set to 0 if no pixel shader shall be created.
\param pixelShaderEntryPointName Entry name of the function of the
pixelShaderProgram (p.e. "main")
\param psCompileTarget Pixel shader version the high level shader
shall be compiled to.
\param geometryShaderProgram Text file handle containing the source of
the geometry shader program. Set to 0 if no geometry shader shall be
created.
\param geometryShaderEntryPointName Entry name of the function of the
geometryShaderProgram (p.e. "main")
\param gsCompileTarget Geometry shader version the high level shader
shall be compiled to.
\param inType Type of vertices passed to geometry shader
\param outType Type of vertices created by geometry shader
\param verticesOut Maximal number of vertices created by geometry
shader. If 0, maximal number supported is assumed.
\param callback Pointer to an implementation of
IShaderConstantSetCallBack in which you can set the needed vertex and
pixel shader program constants. Set this to 0 if you don't need this.
\param baseMaterial Base material which renderstates will be used to
shade the material.
\param userData a user data int. This int can be set to any value and
will be set as parameter in the callback method when calling
OnSetConstants(). In this way it is easily possible to use the same
callback method for multiple materials and distinguish between them
during the call.
\return Number of the material type which can be set in
SMaterial::MaterialType to use the renderer. -1 is returned if an
error occurred, e.g. if a shader program could not be compiled or a
compile target is not reachable. The error strings are then printed to
the error log and can be caught with a custom event receiver. */
virtual s32 addHighLevelShaderMaterialFromFiles(
io::IReadFile *vertexShaderProgram,
const c8 *vertexShaderEntryPointName,
E_VERTEX_SHADER_TYPE vsCompileTarget,
io::IReadFile *pixelShaderProgram,
const c8 *pixelShaderEntryPointName,
E_PIXEL_SHADER_TYPE psCompileTarget,
io::IReadFile *geometryShaderProgram,
const c8 *geometryShaderEntryPointName = "main",
E_GEOMETRY_SHADER_TYPE gsCompileTarget = EGST_GS_4_0,
scene::E_PRIMITIVE_TYPE inType = scene::EPT_TRIANGLES,
scene::E_PRIMITIVE_TYPE outType = scene::EPT_TRIANGLE_STRIP,
u32 verticesOut = 0,
IShaderConstantSetCallBack *callback = 0,
E_MATERIAL_TYPE baseMaterial = video::EMT_SOLID,
s32 userData = 0) = 0;
//! convenience function for use without geometry shaders
s32 addHighLevelShaderMaterialFromFiles(
io::IReadFile *vertexShaderProgram,
const c8 *vertexShaderEntryPointName = "main",
E_VERTEX_SHADER_TYPE vsCompileTarget = EVST_VS_1_1,
io::IReadFile *pixelShaderProgram = 0,
const c8 *pixelShaderEntryPointName = "main",
E_PIXEL_SHADER_TYPE psCompileTarget = EPST_PS_1_1,
IShaderConstantSetCallBack *callback = 0,
E_MATERIAL_TYPE baseMaterial = video::EMT_SOLID,
s32 userData = 0)
{
return addHighLevelShaderMaterialFromFiles(
vertexShaderProgram, vertexShaderEntryPointName,
vsCompileTarget, pixelShaderProgram,
pixelShaderEntryPointName, psCompileTarget,
0, "main", EGST_GS_4_0,
scene::EPT_TRIANGLES, scene::EPT_TRIANGLE_STRIP, 0,
callback, baseMaterial, userData);
}
//! Delete a shader material and associated data. //! Delete a shader material and associated data.
/** /**
After you have deleted a material it is invalid to still use and doing After you have deleted a material it is invalid to still use and doing

View File

@ -34,10 +34,6 @@ public:
AlignLeft(EGUIA_UPPERLEFT), AlignRight(EGUIA_UPPERLEFT), AlignTop(EGUIA_UPPERLEFT), AlignBottom(EGUIA_UPPERLEFT), AlignLeft(EGUIA_UPPERLEFT), AlignRight(EGUIA_UPPERLEFT), AlignTop(EGUIA_UPPERLEFT), AlignBottom(EGUIA_UPPERLEFT),
Environment(environment), Type(type) Environment(environment), Type(type)
{ {
#ifdef _DEBUG
setDebugName("IGUIElement");
#endif
// if we were given a parent to attach to // if we were given a parent to attach to
if (parent) { if (parent) {
parent->addChildToEnd(this); parent->addChildToEnd(this);

View File

@ -53,7 +53,7 @@ public:
//! Calculates the width and height of a given string of text. //! Calculates the width and height of a given string of text.
/** \return Returns width and height of the area covered by the text if /** \return Returns width and height of the area covered by the text if
it would be drawn. */ it would be drawn. */
virtual core::dimension2d<u32> getDimension(const wchar_t *text) const = 0; virtual core::dimension2du getDimension(const wchar_t *text) const = 0;
//! Calculates the index of the character in the text which is on a specific position. //! Calculates the index of the character in the text which is on a specific position.
/** \param text: Text string. /** \param text: Text string.
@ -82,10 +82,7 @@ public:
which supports kerning pairs a string such as 'Wo' may have the 'o' which supports kerning pairs a string such as 'Wo' may have the 'o'
tucked neatly under the 'W'. tucked neatly under the 'W'.
*/ */
virtual s32 getKerningWidth(const wchar_t *thisLetter = 0, const wchar_t *previousLetter = 0) const = 0; virtual core::vector2di getKerning(const wchar_t thisLetter = 0, const wchar_t previousLetter = 0) const = 0;
//! Returns the distance between letters
virtual s32 getKerningHeight() const = 0;
//! Define which characters should not be drawn by the font. //! Define which characters should not be drawn by the font.
/** For example " " would not draw any space which is usually blank in /** For example " " would not draw any space which is usually blank in

View File

@ -24,17 +24,6 @@ public:
//! returns the sprite number from a given character //! returns the sprite number from a given character
virtual u32 getSpriteNoFromChar(const wchar_t *c) const = 0; virtual u32 getSpriteNoFromChar(const wchar_t *c) const = 0;
//! Gets kerning values (distance between letters) for the font. If no parameters are provided,
/** the global kerning distance is returned.
\param thisLetter: If this parameter is provided, the left side kerning for this letter is added
to the global kerning value. For example, a space might only be one pixel wide, but it may
be displayed as several pixels.
\param previousLetter: If provided, kerning is calculated for both letters and added to the global
kerning value. For example, EGFT_BITMAP will add the right kerning value of previousLetter to the
left side kerning value of thisLetter, then add the global value.
*/
s32 getKerningWidth(const wchar_t *thisLetter = 0, const wchar_t *previousLetter = 0) const override = 0;
}; };
} // end namespace gui } // end namespace gui

View File

@ -328,6 +328,8 @@ public:
return 32; return 32;
case ECF_D16: case ECF_D16:
return 16; return 16;
case ECF_D24:
return 32;
case ECF_D32: case ECF_D32:
return 32; return 32;
case ECF_D24S8: case ECF_D24S8:
@ -340,6 +342,8 @@ public:
return 16; return 16;
case ECF_R16G16: case ECF_R16G16:
return 32; return 32;
case ECF_A2R10G10B10:
return 32;
case ECF_R16F: case ECF_R16F:
return 16; return 16;
case ECF_G16R16F: case ECF_G16R16F:
@ -378,6 +382,7 @@ public:
{ {
switch (format) { switch (format) {
case ECF_D16: case ECF_D16:
case ECF_D24:
case ECF_D32: case ECF_D32:
case ECF_D24S8: case ECF_D24S8:
return true; return true;

View File

@ -108,7 +108,7 @@ public:
if (!mesh) if (!mesh)
return true; return true;
bool result = true; bool result = true;
core::aabbox3df bufferbox; core::aabbox3df bufferbox{{0, 0, 0}};
for (u32 i = 0; i < mesh->getMeshBufferCount(); ++i) { for (u32 i = 0; i < mesh->getMeshBufferCount(); ++i) {
result &= apply(func, mesh->getMeshBuffer(i), boundingBoxUpdate); result &= apply(func, mesh->getMeshBuffer(i), boundingBoxUpdate);
if (boundingBoxUpdate) { if (boundingBoxUpdate) {
@ -136,7 +136,7 @@ protected:
if (!buffer) if (!buffer)
return true; return true;
core::aabbox3df bufferbox; core::aabbox3df bufferbox{{0, 0, 0}};
for (u32 i = 0; i < buffer->getVertexCount(); ++i) { for (u32 i = 0; i < buffer->getVertexCount(); ++i) {
switch (buffer->getVertexType()) { switch (buffer->getVertexType()) {
case video::EVT_STANDARD: { case video::EVT_STANDARD: {

View File

@ -136,31 +136,6 @@ public:
return ReferenceCounter; return ReferenceCounter;
} }
#ifdef _DEBUG
//! Returns the debug name of the object.
/** The Debugname may only be set and changed by the object
itself. This method should only be used in Debug mode.
\return Returns a string, previously set by setDebugName(); */
const c8 *getDebugName() const
{
return DebugName;
}
protected:
//! Sets the debug name of the object.
/** The Debugname may only be set and changed by the object
itself. This method should only be used in Debug mode.
\param newName: New debug name to set. */
void setDebugName(const c8 *newName)
{
DebugName = newName;
}
private:
//! The debug name.
const c8 *DebugName = nullptr;
#endif
private: private:
//! The reference counter. Mutable to do reference counting on const objects. //! The reference counter. Mutable to do reference counting on const objects.

View File

@ -26,6 +26,7 @@ enum E_CUBE_SURFACE
}; };
//! Interface of a Render Target. //! Interface of a Render Target.
/** This is a framebuffer object (FBO) in OpenGL. */
class IRenderTarget : public virtual IReferenceCounted class IRenderTarget : public virtual IReferenceCounted
{ {
public: public:
@ -108,11 +109,6 @@ protected:
//! Driver type of render target. //! Driver type of render target.
E_DRIVER_TYPE DriverType; E_DRIVER_TYPE DriverType;
private:
// no copying (IReferenceCounted still allows that for reasons which take some time to work around)
IRenderTarget(const IRenderTarget &);
IRenderTarget &operator=(const IRenderTarget &);
}; };
} }

View File

@ -11,7 +11,6 @@
#include "SColor.h" #include "SColor.h"
#include "ESceneNodeTypes.h" #include "ESceneNodeTypes.h"
#include "SceneParameters.h" // IWYU pragma: export #include "SceneParameters.h" // IWYU pragma: export
#include "ISkinnedMesh.h"
namespace irr namespace irr
{ {
@ -55,9 +54,6 @@ enum E_SCENE_NODE_RENDER_PASS
//! Camera pass. The active view is set up here. The very first pass. //! Camera pass. The active view is set up here. The very first pass.
ESNRP_CAMERA = 1, ESNRP_CAMERA = 1,
//! In this pass, lights are transformed into camera space and added to the driver
ESNRP_LIGHT = 2,
//! This is used for sky boxes. //! This is used for sky boxes.
ESNRP_SKY_BOX = 4, ESNRP_SKY_BOX = 4,
@ -85,9 +81,6 @@ enum E_SCENE_NODE_RENDER_PASS
//! Transparent effect scene nodes, drawn after Transparent nodes. They are sorted from back to front and drawn in that order. //! Transparent effect scene nodes, drawn after Transparent nodes. They are sorted from back to front and drawn in that order.
ESNRP_TRANSPARENT_EFFECT = 32, ESNRP_TRANSPARENT_EFFECT = 32,
//! Drawn after the solid nodes, before the transparent nodes, the time for drawing shadow volumes
ESNRP_SHADOW = 64,
//! Drawn after transparent effect nodes. For custom gui's. Unsorted (in order nodes registered themselves). //! Drawn after transparent effect nodes. For custom gui's. Unsorted (in order nodes registered themselves).
ESNRP_GUI = 128 ESNRP_GUI = 128
@ -99,6 +92,7 @@ class IBillboardSceneNode;
class ICameraSceneNode; class ICameraSceneNode;
class IDummyTransformationSceneNode; class IDummyTransformationSceneNode;
class IMesh; class IMesh;
class SkinnedMesh;
class IMeshBuffer; class IMeshBuffer;
class IMeshCache; class IMeshCache;
class ISceneCollisionManager; class ISceneCollisionManager;
@ -127,189 +121,6 @@ public:
//! Get pointer to an animatable mesh. Loads the file if not loaded already. //! Get pointer to an animatable mesh. Loads the file if not loaded already.
/** /**
* If you want to remove a loaded mesh from the cache again, use removeMesh(). * If you want to remove a loaded mesh from the cache again, use removeMesh().
* Currently there are the following mesh formats supported:
* <TABLE border="1" cellpadding="2" cellspacing="0">
* <TR>
* <TD>Format</TD>
* <TD>Description</TD>
* </TR>
* <TR>
* <TD>3D Studio (.3ds)</TD>
* <TD>Loader for 3D-Studio files which lots of 3D packages
* are able to export. Only static meshes are currently
* supported by this importer.</TD>
* </TR>
* <TR>
* <TD>3D World Studio (.smf)</TD>
* <TD>Loader for Leadwerks SMF mesh files, a simple mesh format
* containing static geometry for games. The proprietary .STF texture format
* is not supported yet. This loader was originally written by Joseph Ellis. </TD>
* </TR>
* <TR>
* <TD>Bliz Basic B3D (.b3d)</TD>
* <TD>Loader for blitz basic files, developed by Mark
* Sibly. This is the ideal animated mesh format for game
* characters as it is both rigidly defined and widely
* supported by modeling and animation software.
* As this format supports skeletal animations, an
* ISkinnedMesh will be returned by this importer.</TD>
* </TR>
* <TR>
* <TD>Cartography shop 4 (.csm)</TD>
* <TD>Cartography Shop is a modeling program for creating
* architecture and calculating lighting. Irrlicht can
* directly import .csm files thanks to the IrrCSM library
* created by Saurav Mohapatra which is now integrated
* directly in Irrlicht.
* </TR>
* <TR>
* <TD>Delgine DeleD (.dmf)</TD>
* <TD>DeleD (delgine.com) is a 3D editor and level-editor
* combined into one and is specifically designed for 3D
* game-development. With this loader, it is possible to
* directly load all geometry is as well as textures and
* lightmaps from .dmf files. To set texture and
* material paths, see scene::DMF_USE_MATERIALS_DIRS.
* It is also possible to flip the alpha texture by setting
* scene::DMF_FLIP_ALPHA_TEXTURES to true and to set the
* material transparent reference value by setting
* scene::DMF_ALPHA_CHANNEL_REF to a float between 0 and
* 1. The loader is based on Salvatore Russo's .dmf
* loader, I just changed some parts of it. Thanks to
* Salvatore for his work and for allowing me to use his
* code in Irrlicht and put it under Irrlicht's license.
* For newer and more enhanced versions of the loader,
* take a look at delgine.com.
* </TD>
* </TR>
* <TR>
* <TD>DirectX (.x)</TD>
* <TD>Platform independent importer (so not D3D-only) for
* .x files. Most 3D packages can export these natively
* and there are several tools for them available, e.g.
* the Maya exporter included in the DX SDK.
* .x files can include skeletal animations and Irrlicht
* is able to play and display them, users can manipulate
* the joints via the ISkinnedMesh interface. Currently,
* Irrlicht only supports uncompressed .x files.</TD>
* </TR>
* <TR>
* <TD>Half-Life model (.mdl)</TD>
* <TD>This loader opens Half-life 1 models, it was contributed
* by Fabio Concas and adapted by Thomas Alten.</TD>
* </TR>
* <TR>
* <TD>LightWave (.lwo)</TD>
* <TD>Native to NewTek's LightWave 3D, the LWO format is well
* known and supported by many exporters. This loader will
* import LWO2 models including lightmaps, bumpmaps and
* reflection textures.</TD>
* </TR>
* <TR>
* <TD>Maya (.obj)</TD>
* <TD>Most 3D software can create .obj files which contain
* static geometry without material data. The material
* files .mtl are also supported. This importer for
* Irrlicht can load them directly. </TD>
* </TR>
* <TR>
* <TD>Milkshape (.ms3d)</TD>
* <TD>.MS3D files contain models and sometimes skeletal
* animations from the Milkshape 3D modeling and animation
* software. Like the other skeletal mesh loaders, joints
* are exposed via the ISkinnedMesh animated mesh type.</TD>
* </TR>
* <TR>
* <TD>My3D (.my3d)</TD>
* <TD>.my3D is a flexible 3D file format. The My3DTools
* contains plug-ins to export .my3D files from several
* 3D packages. With this built-in importer, Irrlicht
* can read and display those files directly. This
* loader was written by Zhuck Dimitry who also created
* the whole My3DTools package.
* </TD>
* </TR>
* <TR>
* <TD>OCT (.oct)</TD>
* <TD>The oct file format contains 3D geometry and
* lightmaps and can be loaded directly by Irrlicht. OCT
* files<br> can be created by FSRad, Paul Nette's
* radiosity processor or exported from Blender using
* OCTTools which can be found in the exporters/OCTTools
* directory of the SDK. Thanks to Murphy McCauley for
* creating all this.</TD>
* </TR>
* <TR>
* <TD>OGRE Meshes (.mesh)</TD>
* <TD>Ogre .mesh files contain 3D data for the OGRE 3D
* engine. Irrlicht can read and display them directly
* with this importer. To define materials for the mesh,
* copy a .material file named like the corresponding
* .mesh file where the .mesh file is. (For example
* ogrehead.material for ogrehead.mesh). Thanks to
* Christian Stehno who wrote and contributed this
* loader.</TD>
* </TR>
* <TR>
* <TD>Pulsar LMTools (.lmts)</TD>
* <TD>LMTools is a set of tools (Windows &amp; Linux) for
* creating lightmaps. Irrlicht can directly read .lmts
* files thanks to<br> the importer created by Jonas
* Petersen.
* Notes for<br> this version of the loader:<br>
* - It does not recognize/support user data in the
* *.lmts files.<br>
* - The TGAs generated by LMTools don't work in
* Irrlicht for some reason (the textures are upside
* down). Opening and resaving them in a graphics app
* will solve the problem.</TD>
* </TR>
* <TR>
* <TD>Quake 3 levels (.bsp)</TD>
* <TD>Quake 3 is a popular game by IDSoftware, and .pk3
* files contain .bsp files and textures/lightmaps
* describing huge prelighted levels. Irrlicht can read
* .pk3 and .bsp files directly and thus render Quake 3
* levels directly. Written by Nikolaus Gebhardt
* enhanced by Dean P. Macri with the curved surfaces
* feature. </TD>
* </TR>
* <TR>
* <TD>Quake 2 models (.md2)</TD>
* <TD>Quake 2 models are characters with morph target
* animation. Irrlicht can read, display and animate
* them directly with this importer. </TD>
* </TR>
* <TR>
* <TD>Quake 3 models (.md3)</TD>
* <TD>Quake 3 models are characters with morph target
* animation, they contain mount points for weapons and body
* parts and are typically made of several sections which are
* manually joined together.</TD>
* </TR>
* <TR>
* <TD>Stanford Triangle (.ply)</TD>
* <TD>Invented by Stanford University and known as the native
* format of the infamous "Stanford Bunny" model, this is a
* popular static mesh format used by 3D scanning hardware
* and software. This loader supports extremely large models
* in both ASCII and binary format, but only has rudimentary
* material support in the form of vertex colors and texture
* coordinates.</TD>
* </TR>
* <TR>
* <TD>Stereolithography (.stl)</TD>
* <TD>The STL format is used for rapid prototyping and
* computer-aided manufacturing, thus has no support for
* materials.</TD>
* </TR>
* </TABLE>
*
* To load and display a mesh quickly, just do this:
* \code
* SceneManager->addAnimatedMeshSceneNode(
* SceneManager->getMesh("yourmesh.3ds"));
* \endcode
* If you would like to implement and add your own file format loader to Irrlicht, * If you would like to implement and add your own file format loader to Irrlicht,
* see addExternalMeshLoader(). * see addExternalMeshLoader().
* \param file File handle of the mesh to load. * \param file File handle of the mesh to load.
@ -600,13 +411,7 @@ public:
//! Get a skinned mesh, which is not available as header-only code //! Get a skinned mesh, which is not available as header-only code
/** Note: You need to drop() the pointer after use again, see IReferenceCounted::drop() /** Note: You need to drop() the pointer after use again, see IReferenceCounted::drop()
for details. */ for details. */
virtual ISkinnedMesh *createSkinnedMesh() = 0; virtual SkinnedMesh *createSkinnedMesh() = 0;
//! Sets ambient color of the scene
virtual void setAmbientLight(const video::SColorf &ambientColor) = 0;
//! Get ambient color of the scene
virtual const video::SColorf &getAmbientLight() const = 0;
//! Get current render pass. //! Get current render pass.
virtual E_SCENE_NODE_RENDER_PASS getCurrentRenderPass() const = 0; virtual E_SCENE_NODE_RENDER_PASS getCurrentRenderPass() const = 0;

View File

@ -1,226 +0,0 @@
// Copyright (C) 2002-2012 Nikolaus Gebhardt
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in irrlicht.h
#pragma once
#include "irrArray.h"
#include "IAnimatedMesh.h"
#include "SSkinMeshBuffer.h"
#include "quaternion.h"
#include <optional>
#include <string>
namespace irr
{
namespace scene
{
enum E_INTERPOLATION_MODE
{
// constant does use the current key-values without interpolation
EIM_CONSTANT = 0,
// linear interpolation
EIM_LINEAR,
//! count of all available interpolation modes
EIM_COUNT
};
//! Interface for using some special functions of Skinned meshes
class ISkinnedMesh : public IAnimatedMesh
{
public:
//! Gets joint count.
/** \return Amount of joints in the skeletal animated mesh. */
virtual u32 getJointCount() const = 0;
//! Gets the name of a joint.
/** \param number: Zero based index of joint. The last joint
has the number getJointCount()-1;
\return Name of joint and null if an error happened. */
virtual const std::optional<std::string> &getJointName(u32 number) const = 0;
//! Gets a joint number from its name
/** \param name: Name of the joint.
\return Number of the joint or std::nullopt if not found. */
virtual std::optional<u32> getJointNumber(const std::string &name) const = 0;
//! Use animation from another mesh
/** The animation is linked (not copied) based on joint names
so make sure they are unique.
\return True if all joints in this mesh were
matched up (empty names will not be matched, and it's case
sensitive). Unmatched joints will not be animated. */
virtual bool useAnimationFrom(const ISkinnedMesh *mesh) = 0;
//! Update Normals when Animating
/** \param on If false don't animate, which is faster.
Else update normals, which allows for proper lighting of
animated meshes. */
virtual void updateNormalsWhenAnimating(bool on) = 0;
//! Sets Interpolation Mode
virtual void setInterpolationMode(E_INTERPOLATION_MODE mode) = 0;
//! Animates this mesh's joints based on frame input
virtual void animateMesh(f32 frame, f32 blend) = 0;
//! Preforms a software skin on this mesh based of joint positions
virtual void skinMesh() = 0;
//! converts the vertex type of all meshbuffers to tangents.
/** E.g. used for bump mapping. */
virtual void convertMeshToTangents() = 0;
//! Allows to enable hardware skinning.
/* This feature is not implemented in Irrlicht yet */
virtual bool setHardwareSkinning(bool on) = 0;
//! Refreshes vertex data cached in joints such as positions and normals
virtual void refreshJointCache() = 0;
//! Moves the mesh into static position.
virtual void resetAnimation() = 0;
//! A vertex weight
struct SWeight
{
//! Index of the mesh buffer
u16 buffer_id; // I doubt 32bits is needed
//! Index of the vertex
u32 vertex_id; // Store global ID here
//! Weight Strength/Percentage (0-1)
f32 strength;
private:
//! Internal members used by CSkinnedMesh
friend class CSkinnedMesh;
char *Moved;
core::vector3df StaticPos;
core::vector3df StaticNormal;
};
//! Animation keyframe which describes a new position
struct SPositionKey
{
f32 frame;
core::vector3df position;
};
//! Animation keyframe which describes a new scale
struct SScaleKey
{
f32 frame;
core::vector3df scale;
};
//! Animation keyframe which describes a new rotation
struct SRotationKey
{
f32 frame;
core::quaternion rotation;
};
//! Joints
struct SJoint
{
SJoint() :
UseAnimationFrom(0), GlobalSkinningSpace(false),
positionHint(-1), scaleHint(-1), rotationHint(-1)
{
}
//! The name of this joint
std::optional<std::string> Name;
//! Local matrix of this joint
core::matrix4 LocalMatrix;
//! List of child joints
core::array<SJoint *> Children;
//! List of attached meshes
core::array<u32> AttachedMeshes;
//! Animation keys causing translation change
core::array<SPositionKey> PositionKeys;
//! Animation keys causing scale change
core::array<SScaleKey> ScaleKeys;
//! Animation keys causing rotation change
core::array<SRotationKey> RotationKeys;
//! Skin weights
core::array<SWeight> Weights;
//! Unnecessary for loaders, will be overwritten on finalize
core::matrix4 GlobalMatrix; // loaders may still choose to set this (temporarily) to calculate absolute vertex data.
core::matrix4 GlobalAnimatedMatrix;
core::matrix4 LocalAnimatedMatrix;
//! These should be set by loaders.
core::vector3df Animatedposition;
core::vector3df Animatedscale;
core::quaternion Animatedrotation;
// The .x and .gltf formats pre-calculate this
std::optional<core::matrix4> GlobalInversedMatrix;
private:
//! Internal members used by CSkinnedMesh
friend class CSkinnedMesh;
SJoint *UseAnimationFrom;
bool GlobalSkinningSpace;
s32 positionHint;
s32 scaleHint;
s32 rotationHint;
};
// Interface for the mesh loaders (finalize should lock these functions, and they should have some prefix like loader_
// these functions will use the needed arrays, set values, etc to help the loaders
//! exposed for loaders: to add mesh buffers
virtual core::array<SSkinMeshBuffer *> &getMeshBuffers() = 0;
//! exposed for loaders: joints list
virtual core::array<SJoint *> &getAllJoints() = 0;
//! exposed for loaders: joints list
virtual const core::array<SJoint *> &getAllJoints() const = 0;
//! loaders should call this after populating the mesh
virtual void finalize() = 0;
//! Adds a new meshbuffer to the mesh, access it as last one
virtual SSkinMeshBuffer *addMeshBuffer() = 0;
//! Adds a new meshbuffer to the mesh, access it as last one
virtual void addMeshBuffer(SSkinMeshBuffer *meshbuf) = 0;
//! Adds a new joint to the mesh, access it as last one
virtual SJoint *addJoint(SJoint *parent = 0) = 0;
//! Adds a new weight to the mesh, access it as last one
virtual SWeight *addWeight(SJoint *joint) = 0;
//! Adds a new position key to the mesh, access it as last one
virtual SPositionKey *addPositionKey(SJoint *joint) = 0;
//! Adds a new scale key to the mesh, access it as last one
virtual SScaleKey *addScaleKey(SJoint *joint) = 0;
//! Adds a new rotation key to the mesh, access it as last one
virtual SRotationKey *addRotationKey(SJoint *joint) = 0;
//! Check if the mesh is non-animated
virtual bool isStatic() = 0;
};
} // end namespace scene
} // end namespace irr

View File

@ -74,9 +74,7 @@ enum E_TEXTURE_CREATION_FLAG
//! Allow the driver to keep a copy of the texture in memory //! Allow the driver to keep a copy of the texture in memory
/** Enabling this makes calls to ITexture::lock a lot faster, but costs main memory. /** Enabling this makes calls to ITexture::lock a lot faster, but costs main memory.
Currently only used in combination with OpenGL drivers. This is disabled by default.
NOTE: Disabling this does not yet work correctly with alpha-textures.
So the default is on for now (but might change with Irrlicht 1.9 if we get the alpha-troubles fixed).
*/ */
ETCF_ALLOW_MEMORY_COPY = 0x00000080, ETCF_ALLOW_MEMORY_COPY = 0x00000080,
@ -158,6 +156,9 @@ enum E_TEXTURE_TYPE
//! 2D texture. //! 2D texture.
ETT_2D, ETT_2D,
//! 2D texture with multisampling.
ETT_2D_MS,
//! Cubemap texture. //! Cubemap texture.
ETT_CUBEMAP ETT_CUBEMAP
}; };
@ -184,7 +185,7 @@ public:
//! Lock function. //! Lock function.
/** Locks the Texture and returns a pointer to access the /** Locks the Texture and returns a pointer to access the
pixels. After lock() has been called and all operations on the pixels pixels. After lock() has been called and all operations on the pixels
are done, you must call unlock(). are done, you must call unlock(). Afterwards the pointer becomes invalid.
Locks are not accumulating, hence one unlock will do for an arbitrary Locks are not accumulating, hence one unlock will do for an arbitrary
number of previous locks. You should avoid locking different levels without number of previous locks. You should avoid locking different levels without
unlocking in between, though, because only the last level locked will be unlocking in between, though, because only the last level locked will be

View File

@ -61,8 +61,8 @@ struct SFrameStats {
u32 PrimitivesDrawn = 0; u32 PrimitivesDrawn = 0;
//! Number of hardware buffers uploaded (new or updated) //! Number of hardware buffers uploaded (new or updated)
u32 HWBuffersUploaded = 0; u32 HWBuffersUploaded = 0;
//! Sum of uploaded hardware buffer size //! Number of active hardware buffers
u32 HWBuffersUploadedSize = 0; u32 HWBuffersActive = 0;
}; };
//! Interface to driver which is able to perform 2d and 3d graphics functions. //! Interface to driver which is able to perform 2d and 3d graphics functions.
@ -131,7 +131,6 @@ public:
/** The following names can be queried for the given types: /** The following names can be queried for the given types:
MaxTextures (int) The maximum number of simultaneous textures supported by the driver. This can be less than the supported number of textures of the driver. Use _IRR_MATERIAL_MAX_TEXTURES_ to adapt the number. MaxTextures (int) The maximum number of simultaneous textures supported by the driver. This can be less than the supported number of textures of the driver. Use _IRR_MATERIAL_MAX_TEXTURES_ to adapt the number.
MaxSupportedTextures (int) The maximum number of simultaneous textures supported by the fixed function pipeline of the (hw) driver. The actual supported number of textures supported by the engine can be lower. MaxSupportedTextures (int) The maximum number of simultaneous textures supported by the fixed function pipeline of the (hw) driver. The actual supported number of textures supported by the engine can be lower.
MaxLights (int) Number of hardware lights supported in the fixed function pipeline of the driver, typically 6-8. Use light manager or deferred shading for more.
MaxAnisotropy (int) Number of anisotropy levels supported for filtering. At least 1, max is typically at 16 or 32. MaxAnisotropy (int) Number of anisotropy levels supported for filtering. At least 1, max is typically at 16 or 32.
MaxAuxBuffers (int) Special render buffers, which are currently not really usable inside Irrlicht. Only supported by OpenGL MaxAuxBuffers (int) Special render buffers, which are currently not really usable inside Irrlicht. Only supported by OpenGL
MaxMultipleRenderTargets (int) Number of render targets which can be bound simultaneously. Rendering to MRTs is done via shaders. MaxMultipleRenderTargets (int) Number of render targets which can be bound simultaneously. Rendering to MRTs is done via shaders.
@ -273,6 +272,14 @@ public:
virtual ITexture *addRenderTargetTexture(const core::dimension2d<u32> &size, virtual ITexture *addRenderTargetTexture(const core::dimension2d<u32> &size,
const io::path &name = "rt", const ECOLOR_FORMAT format = ECF_UNKNOWN) = 0; const io::path &name = "rt", const ECOLOR_FORMAT format = ECF_UNKNOWN) = 0;
//! Adds a multisampled render target texture to the texture cache.
/** \param msaa The number of samples to use, values that make sense are > 1.
Only works if the driver supports the EVDF_TEXTURE_MULTISAMPLE feature,
check via queryFeature.
\see addRenderTargetTexture */
virtual ITexture *addRenderTargetTextureMs(const core::dimension2d<u32> &size, u8 msaa,
const io::path &name = "rt", const ECOLOR_FORMAT format = ECF_UNKNOWN) = 0;
//! Adds a new render target texture with 6 sides for a cubemap map to the texture cache. //! Adds a new render target texture with 6 sides for a cubemap map to the texture cache.
/** \param sideLen Length of one cubemap side. /** \param sideLen Length of one cubemap side.
\param name A name for the texture. Later calls of getTexture() with this name will return this texture. \param name A name for the texture. Later calls of getTexture() with this name will return this texture.
@ -303,6 +310,18 @@ public:
0 or another texture first. */ 0 or another texture first. */
virtual void removeAllTextures() = 0; virtual void removeAllTextures() = 0;
//! Eagerly upload buffer to hardware
/** This can be a good idea if you have a newly created or modified buffer,
which you know you will draw in the near future (e.g. end of same frame,
or next frame), because it gives the GPU driver to copy the contents. */
virtual void updateHardwareBuffer(const scene::IVertexBuffer *vb) = 0;
//! Eagerly upload buffer to hardware
/** This can be a good idea if you have a newly created or modified buffer,
which you know you will draw in the near future (e.g. end of same frame,
or next frame), because it gives the GPU driver to copy the contents. */
virtual void updateHardwareBuffer(const scene::IIndexBuffer *ib) = 0;
//! Remove hardware buffer //! Remove hardware buffer
virtual void removeHardwareBuffer(const scene::IVertexBuffer *vb) = 0; virtual void removeHardwareBuffer(const scene::IVertexBuffer *vb) = 0;
@ -358,6 +377,10 @@ public:
//! Remove all render targets. //! Remove all render targets.
virtual void removeAllRenderTargets() = 0; virtual void removeAllRenderTargets() = 0;
//! Blit contents of one render target to another one.
/** This is glBlitFramebuffer in OpenGL. */
virtual void blitRenderTarget(IRenderTarget *from, IRenderTarget *to) = 0;
//! Sets a boolean alpha channel on the texture based on a color key. //! Sets a boolean alpha channel on the texture based on a color key.
/** This makes the texture fully transparent at the texels where /** This makes the texture fully transparent at the texels where
this color key can be found when using for example draw2DImage this color key can be found when using for example draw2DImage
@ -1098,15 +1121,6 @@ public:
//! Get the graphics card vendor name. //! Get the graphics card vendor name.
virtual core::stringc getVendorInfo() = 0; virtual core::stringc getVendorInfo() = 0;
//! Only used by the engine internally.
/** The ambient color is set in the scene manager, see
scene::ISceneManager::setAmbientLight().
\param color New color of the ambient light. */
virtual void setAmbientLight(const SColorf &color) = 0;
//! Get the global ambient light currently used by the driver
virtual const SColorf &getAmbientLight() const = 0;
//! Only used by the engine internally. //! Only used by the engine internally.
/** Passes the global material flag AllowZWriteOnTransparent. /** Passes the global material flag AllowZWriteOnTransparent.
Use the SceneManager attribute to set this value from your app. Use the SceneManager attribute to set this value from your app.
@ -1116,19 +1130,6 @@ public:
//! Get the maximum texture size supported. //! Get the maximum texture size supported.
virtual core::dimension2du getMaxTextureSize() const = 0; virtual core::dimension2du getMaxTextureSize() const = 0;
//! Color conversion convenience function
/** Convert an image (as array of pixels) from source to destination
array, thereby converting the color format. The pixel size is
determined by the color formats.
\param sP Pointer to source
\param sF Color format of source
\param sN Number of pixels to convert, both array must be large enough
\param dP Pointer to destination
\param dF Color format of destination
*/
virtual void convertColor(const void *sP, ECOLOR_FORMAT sF, s32 sN,
void *dP, ECOLOR_FORMAT dF) const = 0;
//! Check if the driver supports creating textures with the given color format //! Check if the driver supports creating textures with the given color format
/** \return True if the format is available, false if not. */ /** \return True if the format is available, false if not. */
virtual bool queryTextureFormat(ECOLOR_FORMAT format) const = 0; virtual bool queryTextureFormat(ECOLOR_FORMAT format) const = 0;

View File

@ -21,9 +21,6 @@ struct SAnimatedMesh final : public IAnimatedMesh
SAnimatedMesh(scene::IMesh *mesh = 0, scene::E_ANIMATED_MESH_TYPE type = scene::EAMT_UNKNOWN) : SAnimatedMesh(scene::IMesh *mesh = 0, scene::E_ANIMATED_MESH_TYPE type = scene::EAMT_UNKNOWN) :
IAnimatedMesh(), FramesPerSecond(25.f), Type(type) IAnimatedMesh(), FramesPerSecond(25.f), Type(type)
{ {
#ifdef _DEBUG
setDebugName("SAnimatedMesh");
#endif
addMesh(mesh); addMesh(mesh);
recalculateBoundingBox(); recalculateBoundingBox();
} }
@ -157,7 +154,7 @@ struct SAnimatedMesh final : public IAnimatedMesh
std::vector<IMesh *> Meshes; std::vector<IMesh *> Meshes;
//! The bounding box of this mesh //! The bounding box of this mesh
core::aabbox3d<f32> Box; core::aabbox3d<f32> Box{{0.0f, 0.0f, 0.0f}};
//! Default animation speed of this mesh. //! Default animation speed of this mesh.
f32 FramesPerSecond; f32 FramesPerSecond;

View File

@ -72,11 +72,17 @@ enum ECOLOR_FORMAT
//! 32 bit format using 16 bits for the red and green channels. //! 32 bit format using 16 bits for the red and green channels.
ECF_R16G16, ECF_R16G16,
//! 32 bit format using 10 bits for R, G, B and 2 for alpha.
ECF_A2R10G10B10,
/** Depth and stencil formats. */ /** Depth and stencil formats. */
//! 16 bit format using 16 bits for depth. //! 16 bit format using 16 bits for depth.
ECF_D16, ECF_D16,
//! 32 bit(?) format using 24 bits for depth.
ECF_D24,
//! 32 bit format using 32 bits for depth. //! 32 bit format using 32 bits for depth.
ECF_D32, ECF_D32,
@ -88,7 +94,7 @@ enum ECOLOR_FORMAT
}; };
//! Names for ECOLOR_FORMAT types //! Names for ECOLOR_FORMAT types
const c8 *const ColorFormatNames[ECF_UNKNOWN + 2] = { const c8 *const ColorFormatNames[] = {
"A1R5G5B5", "A1R5G5B5",
"R5G6B5", "R5G6B5",
"R8G8B8", "R8G8B8",
@ -103,13 +109,18 @@ const c8 *const ColorFormatNames[ECF_UNKNOWN + 2] = {
"R8G8", "R8G8",
"R16", "R16",
"R16G16", "R16G16",
"A2R10G10B10",
"D16", "D16",
"D24",
"D32", "D32",
"D24S8", "D24S8",
"UNKNOWN", "UNKNOWN",
0, 0,
}; };
static_assert(sizeof(ColorFormatNames) / sizeof(ColorFormatNames[0])
== ECF_UNKNOWN + 2, "name table size mismatch");
//! Creates a 16 bit A1R5G5B5 color //! Creates a 16 bit A1R5G5B5 color
inline u16 RGBA16(u32 r, u32 g, u32 b, u32 a = 0xFF) inline u16 RGBA16(u32 r, u32 g, u32 b, u32 a = 0xFF)
{ {
@ -220,12 +231,6 @@ inline u32 getBlue(u16 color)
return (color & 0x1F); return (color & 0x1F);
} }
//! Returns the average from a 16 bit A1R5G5B5 color
inline s32 getAverage(s16 color)
{
return ((getRed(color) << 3) + (getGreen(color) << 3) + (getBlue(color) << 3)) / 3;
}
//! Class representing a 32 bit ARGB color. //! Class representing a 32 bit ARGB color.
/** The color values for alpha, red, green, and blue are /** The color values for alpha, red, green, and blue are
stored in a single u32. So all four values may be between 0 and 255. stored in a single u32. So all four values may be between 0 and 255.
@ -271,24 +276,12 @@ public:
0 means no blue, 255 means full blue. */ 0 means no blue, 255 means full blue. */
u32 getBlue() const { return color & 0xff; } u32 getBlue() const { return color & 0xff; }
//! Get lightness of the color in the range [0,255] //! Get an approximate brightness value of the color in the range [0,255]
f32 getLightness() const f32 getBrightness() const
{
return 0.5f * (core::max_(core::max_(getRed(), getGreen()), getBlue()) + core::min_(core::min_(getRed(), getGreen()), getBlue()));
}
//! Get luminance of the color in the range [0,255].
f32 getLuminance() const
{ {
return 0.3f * getRed() + 0.59f * getGreen() + 0.11f * getBlue(); return 0.3f * getRed() + 0.59f * getGreen() + 0.11f * getBlue();
} }
//! Get average intensity of the color in the range [0,255].
u32 getAverage() const
{
return (getRed() + getGreen() + getBlue()) / 3;
}
//! Sets the alpha component of the Color. //! Sets the alpha component of the Color.
/** The alpha component defines how transparent a color should be. /** The alpha component defines how transparent a color should be.
\param a The alpha value of the color. 0 is fully transparent, 255 is fully opaque. */ \param a The alpha value of the color. 0 is fully transparent, 255 is fully opaque. */
@ -358,9 +351,9 @@ public:
/** \return True if this color is smaller than the other one */ /** \return True if this color is smaller than the other one */
bool operator<(const SColor &other) const { return (color < other.color); } bool operator<(const SColor &other) const { return (color < other.color); }
//! Adds two colors, result is clamped to 0..255 values //! Adds two colors in a gamma-incorrect way
/** \param other Color to add to this color /** \param other Color to add to this color
\return Addition of the two colors, clamped to 0..255 values */ \return Sum of the two non-linear colors, clamped to 0..255 values */
SColor operator+(const SColor &other) const SColor operator+(const SColor &other) const
{ {
return SColor(core::min_(getAlpha() + other.getAlpha(), 255u), return SColor(core::min_(getAlpha() + other.getAlpha(), 255u),
@ -370,7 +363,9 @@ public:
} }
//! Interpolates the color with a f32 value to another color //! Interpolates the color with a f32 value to another color
/** \param other: Other color /** Note that the interpolation is neither physically nor perceptually
linear since it happens directly in the sRGB color space.
\param other: Other color
\param d: value between 0.0f and 1.0f. d=0 returns other, d=1 returns this, values between interpolate. \param d: value between 0.0f and 1.0f. d=0 returns other, d=1 returns this, values between interpolate.
\return Interpolated color. */ \return Interpolated color. */
SColor getInterpolated(const SColor &other, f32 d) const SColor getInterpolated(const SColor &other, f32 d) const
@ -383,34 +378,6 @@ public:
(u32)core::round32(other.getBlue() * inv + getBlue() * d)); (u32)core::round32(other.getBlue() * inv + getBlue() * d));
} }
//! Returns interpolated color. ( quadratic )
/** \param c1: first color to interpolate with
\param c2: second color to interpolate with
\param d: value between 0.0f and 1.0f. */
SColor getInterpolated_quadratic(const SColor &c1, const SColor &c2, f32 d) const
{
// this*(1-d)*(1-d) + 2 * c1 * (1-d) + c2 * d * d;
d = core::clamp(d, 0.f, 1.f);
const f32 inv = 1.f - d;
const f32 mul0 = inv * inv;
const f32 mul1 = 2.f * d * inv;
const f32 mul2 = d * d;
return SColor(
core::clamp(core::floor32(
getAlpha() * mul0 + c1.getAlpha() * mul1 + c2.getAlpha() * mul2),
0, 255),
core::clamp(core::floor32(
getRed() * mul0 + c1.getRed() * mul1 + c2.getRed() * mul2),
0, 255),
core::clamp(core::floor32(
getGreen() * mul0 + c1.getGreen() * mul1 + c2.getGreen() * mul2),
0, 255),
core::clamp(core::floor32(
getBlue() * mul0 + c1.getBlue() * mul1 + c2.getBlue() * mul2),
0, 255));
}
//! set the color by expecting data in the given format //! set the color by expecting data in the given format
/** \param data: must point to valid memory containing color information in the given format /** \param data: must point to valid memory containing color information in the given format
\param format: tells the format in which data is available \param format: tells the format in which data is available
@ -504,7 +471,7 @@ public:
SColorf(f32 r, f32 g, f32 b, f32 a = 1.0f) : SColorf(f32 r, f32 g, f32 b, f32 a = 1.0f) :
r(r), g(g), b(b), a(a) {} r(r), g(g), b(b), a(a) {}
//! Constructs a color from 32 bit Color. //! Constructs a color from 32 bit Color without gamma correction
/** \param c: 32 bit color from which this SColorf class is /** \param c: 32 bit color from which this SColorf class is
constructed from. */ constructed from. */
SColorf(SColor c) SColorf(SColor c)
@ -516,7 +483,7 @@ public:
a = c.getAlpha() * inv; a = c.getAlpha() * inv;
} }
//! Converts this color to a SColor without floats. //! Converts this color to a SColor without gamma correction
SColor toSColor() const SColor toSColor() const
{ {
return SColor((u32)core::round32(a * 255.0f), (u32)core::round32(r * 255.0f), (u32)core::round32(g * 255.0f), (u32)core::round32(b * 255.0f)); return SColor((u32)core::round32(a * 255.0f), (u32)core::round32(r * 255.0f), (u32)core::round32(g * 255.0f), (u32)core::round32(b * 255.0f));
@ -554,7 +521,9 @@ public:
} }
//! Interpolates the color with a f32 value to another color //! Interpolates the color with a f32 value to another color
/** \param other: Other color /** Note that the interpolation is neither physically nor perceptually
linear if it happens directly in the sRGB color space.
\param other: Other color
\param d: value between 0.0f and 1.0f \param d: value between 0.0f and 1.0f
\return Interpolated color. */ \return Interpolated color. */
SColorf getInterpolated(const SColorf &other, f32 d) const SColorf getInterpolated(const SColorf &other, f32 d) const
@ -565,45 +534,6 @@ public:
other.g * inv + g * d, other.b * inv + b * d, other.a * inv + a * d); other.g * inv + g * d, other.b * inv + b * d, other.a * inv + a * d);
} }
//! Returns interpolated color. ( quadratic )
/** \param c1: first color to interpolate with
\param c2: second color to interpolate with
\param d: value between 0.0f and 1.0f. */
inline SColorf getInterpolated_quadratic(const SColorf &c1, const SColorf &c2,
f32 d) const
{
d = core::clamp(d, 0.f, 1.f);
// this*(1-d)*(1-d) + 2 * c1 * (1-d) + c2 * d * d;
const f32 inv = 1.f - d;
const f32 mul0 = inv * inv;
const f32 mul1 = 2.f * d * inv;
const f32 mul2 = d * d;
return SColorf(r * mul0 + c1.r * mul1 + c2.r * mul2,
g * mul0 + c1.g * mul1 + c2.g * mul2,
b * mul0 + c1.b * mul1 + c2.b * mul2,
a * mul0 + c1.a * mul1 + c2.a * mul2);
}
//! Sets a color component by index. R=0, G=1, B=2, A=3
void setColorComponentValue(s32 index, f32 value)
{
switch (index) {
case 0:
r = value;
break;
case 1:
g = value;
break;
case 2:
b = value;
break;
case 3:
a = value;
break;
}
}
//! Returns the alpha component of the color in the range 0.0 (transparent) to 1.0 (opaque) //! Returns the alpha component of the color in the range 0.0 (transparent) to 1.0 (opaque)
f32 getAlpha() const { return a; } f32 getAlpha() const { return a; }

View File

@ -230,14 +230,14 @@ const c8 *const ZWriteNames[] = {
/** SMaterial might ignore some textures in most function, like assignment and comparison, /** SMaterial might ignore some textures in most function, like assignment and comparison,
when SIrrlichtCreationParameters::MaxTextureUnits is set to a lower number. when SIrrlichtCreationParameters::MaxTextureUnits is set to a lower number.
*/ */
const u32 MATERIAL_MAX_TEXTURES = 4; constexpr static u32 MATERIAL_MAX_TEXTURES = 4;
//! Struct for holding parameters for a material renderer //! Struct for holding parameters for a material renderer
// Note for implementors: Serialization is in CNullDriver // Note for implementors: Serialization is in CNullDriver
class SMaterial class SMaterial
{ {
public: public:
//! Default constructor. Creates a solid, lit material with white colors //! Default constructor. Creates a solid material
SMaterial() : SMaterial() :
MaterialType(EMT_SOLID), ColorParam(0, 0, 0, 0), MaterialType(EMT_SOLID), ColorParam(0, 0, 0, 0),
MaterialTypeParam(0.0f), Thickness(1.0f), ZBuffer(ECFN_LESSEQUAL), MaterialTypeParam(0.0f), Thickness(1.0f), ZBuffer(ECFN_LESSEQUAL),
@ -257,7 +257,7 @@ public:
E_MATERIAL_TYPE MaterialType; E_MATERIAL_TYPE MaterialType;
//! Custom color parameter, can be used by custom shader materials. //! Custom color parameter, can be used by custom shader materials.
// See MainShaderConstantSetter in Minetest. // See MainShaderConstantSetter in Luanti.
SColor ColorParam; SColor ColorParam;
//! Free parameter, dependent on the material type. //! Free parameter, dependent on the material type.
@ -427,10 +427,13 @@ public:
PolygonOffsetDepthBias != b.PolygonOffsetDepthBias || PolygonOffsetDepthBias != b.PolygonOffsetDepthBias ||
PolygonOffsetSlopeScale != b.PolygonOffsetSlopeScale || PolygonOffsetSlopeScale != b.PolygonOffsetSlopeScale ||
UseMipMaps != b.UseMipMaps; UseMipMaps != b.UseMipMaps;
for (u32 i = 0; (i < MATERIAL_MAX_TEXTURES) && !different; ++i) { if (different)
different |= (TextureLayers[i] != b.TextureLayers[i]); return true;
for (u32 i = 0; i < MATERIAL_MAX_TEXTURES; ++i) {
if (TextureLayers[i] != b.TextureLayers[i])
return true;
} }
return different; return false;
} }
//! Equality operator //! Equality operator
@ -477,5 +480,19 @@ public:
//! global const identity Material //! global const identity Material
IRRLICHT_API extern SMaterial IdentityMaterial; IRRLICHT_API extern SMaterial IdentityMaterial;
} // end namespace video } // end namespace video
} // end namespace irr } // end namespace irr
template<>
struct std::hash<irr::video::SMaterial>
{
/// @brief std::hash specialization for video::SMaterial
std::size_t operator()(const irr::video::SMaterial &m) const noexcept
{
// basic implementation that hashes the two things most likely to differ
auto h1 = std::hash<irr::video::ITexture*>{}(m.getTexture(0));
auto h2 = std::hash<int>{}(m.MaterialType);
return (h1 << 1) ^ h2;
}
};

View File

@ -17,12 +17,7 @@ namespace scene
struct SMesh final : public IMesh struct SMesh final : public IMesh
{ {
//! constructor //! constructor
SMesh() SMesh() {}
{
#ifdef _DEBUG
setDebugName("SMesh");
#endif
}
//! destructor //! destructor
virtual ~SMesh() virtual ~SMesh()
@ -138,7 +133,7 @@ struct SMesh final : public IMesh
std::vector<u32> TextureSlots; std::vector<u32> TextureSlots;
//! The bounding box of this mesh //! The bounding box of this mesh
core::aabbox3d<f32> BoundingBox; core::aabbox3d<f32> BoundingBox{{0, 0, 0}};
}; };
} // end namespace scene } // end namespace scene

View File

@ -22,9 +22,6 @@ struct SSkinMeshBuffer final : public IMeshBuffer
VertexType(vt), PrimitiveType(EPT_TRIANGLES), VertexType(vt), PrimitiveType(EPT_TRIANGLES),
BoundingBoxNeedsRecalculated(true) BoundingBoxNeedsRecalculated(true)
{ {
#ifdef _DEBUG
setDebugName("SSkinMeshBuffer");
#endif
Vertices_Tangents = new SVertexBufferTangents(); Vertices_Tangents = new SVertexBufferTangents();
Vertices_2TCoords = new SVertexBufferLightMap(); Vertices_2TCoords = new SVertexBufferLightMap();
Vertices_Standard = new SVertexBuffer(); Vertices_Standard = new SVertexBuffer();
@ -231,7 +228,7 @@ public:
video::SMaterial Material; video::SMaterial Material;
video::E_VERTEX_TYPE VertexType; video::E_VERTEX_TYPE VertexType;
core::aabbox3d<f32> BoundingBox; core::aabbox3d<f32> BoundingBox{{0, 0, 0}};
//! Primitive type used for rendering (triangles, lines, ...) //! Primitive type used for rendering (triangles, lines, ...)
E_PRIMITIVE_TYPE PrimitiveType; E_PRIMITIVE_TYPE PrimitiveType;

View File

@ -117,7 +117,7 @@ struct SViewFrustum
core::plane3d<f32> planes[VF_PLANE_COUNT]; core::plane3d<f32> planes[VF_PLANE_COUNT];
//! bounding box around the view frustum //! bounding box around the view frustum
core::aabbox3d<f32> boundingBox; core::aabbox3d<f32> boundingBox{{0, 0, 0}};
private: private:
//! Hold a copy of important transform matrices //! Hold a copy of important transform matrices

419
irr/include/SkinnedMesh.h Normal file
View File

@ -0,0 +1,419 @@
// Copyright (C) 2002-2012 Nikolaus Gebhardt
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in irrlicht.h
#pragma once
#include "IAnimatedMesh.h"
#include "ISceneManager.h"
#include "SMeshBuffer.h"
#include "SSkinMeshBuffer.h"
#include "quaternion.h"
#include "vector3d.h"
#include <optional>
#include <string>
namespace irr
{
namespace scene
{
class IAnimatedMeshSceneNode;
class IBoneSceneNode;
class ISceneManager;
class SkinnedMesh : public IAnimatedMesh
{
public:
//! constructor
SkinnedMesh() :
EndFrame(0.f), FramesPerSecond(25.f),
LastAnimatedFrame(-1), SkinnedLastFrame(false),
HasAnimation(false), PreparedForSkinning(false),
AnimateNormals(true), HardwareSkinning(false)
{
SkinningBuffers = &LocalBuffers;
}
//! destructor
virtual ~SkinnedMesh();
//! If the duration is 0, it is a static (=non animated) mesh.
f32 getMaxFrameNumber() const override;
//! Gets the default animation speed of the animated mesh.
/** \return Amount of frames per second. If the amount is 0, it is a static, non animated mesh. */
f32 getAnimationSpeed() const override;
//! Gets the frame count of the animated mesh.
/** \param fps Frames per second to play the animation with. If the amount is 0, it is not animated.
The actual speed is set in the scene node the mesh is instantiated in.*/
void setAnimationSpeed(f32 fps) override;
//! returns the animated mesh for the given frame
IMesh *getMesh(f32) override;
//! Animates joints based on frame input
void animateMesh(f32 frame);
//! Performs a software skin on this mesh based of joint positions
void skinMesh();
//! returns amount of mesh buffers.
u32 getMeshBufferCount() const override;
//! returns pointer to a mesh buffer
IMeshBuffer *getMeshBuffer(u32 nr) const override;
//! Returns pointer to a mesh buffer which fits a material
/** \param material: material to search for
\return Returns the pointer to the mesh buffer or
NULL if there is no such mesh buffer. */
IMeshBuffer *getMeshBuffer(const video::SMaterial &material) const override;
u32 getTextureSlot(u32 meshbufNr) const override;
void setTextureSlot(u32 meshbufNr, u32 textureSlot);
//! returns an axis aligned bounding box
const core::aabbox3d<f32> &getBoundingBox() const override {
return BoundingBox;
}
//! set user axis aligned bounding box
void setBoundingBox(const core::aabbox3df &box) override {
BoundingBox = box;
}
//! set the hardware mapping hint, for driver
void setHardwareMappingHint(E_HARDWARE_MAPPING newMappingHint, E_BUFFER_TYPE buffer = EBT_VERTEX_AND_INDEX) override;
//! flags the meshbuffer as changed, reloads hardware buffers
void setDirty(E_BUFFER_TYPE buffer = EBT_VERTEX_AND_INDEX) override;
//! Returns the type of the animated mesh.
E_ANIMATED_MESH_TYPE getMeshType() const override {
return EAMT_SKINNED;
}
//! Gets joint count.
u32 getJointCount() const;
//! Gets the name of a joint.
/** \param number: Zero based index of joint.
\return Name of joint and null if an error happened. */
const std::optional<std::string> &getJointName(u32 number) const;
//! Gets a joint number from its name
/** \param name: Name of the joint.
\return Number of the joint or std::nullopt if not found. */
std::optional<u32> getJointNumber(const std::string &name) const;
//! Update Normals when Animating
/** \param on If false don't animate, which is faster.
Else update normals, which allows for proper lighting of
animated meshes (default). */
void updateNormalsWhenAnimating(bool on) {
AnimateNormals = on;
}
//! converts the vertex type of all meshbuffers to tangents.
/** E.g. used for bump mapping. */
void convertMeshToTangents();
//! Does the mesh have no animation
bool isStatic() const {
return !HasAnimation;
}
//! Allows to enable hardware skinning.
/* This feature is not implemented in Irrlicht yet */
bool setHardwareSkinning(bool on);
//! Refreshes vertex data cached in joints such as positions and normals
void refreshJointCache();
//! Moves the mesh into static position.
void resetAnimation();
void updateBoundingBox();
//! Recovers the joints from the mesh
void recoverJointsFromMesh(std::vector<IBoneSceneNode *> &jointChildSceneNodes);
//! Transfers the joint data to the mesh
void transferJointsToMesh(const std::vector<IBoneSceneNode *> &jointChildSceneNodes);
//! Creates an array of joints from this mesh as children of node
void addJoints(std::vector<IBoneSceneNode *> &jointChildSceneNodes,
IAnimatedMeshSceneNode *node,
ISceneManager *smgr);
//! A vertex weight
struct SWeight
{
//! Index of the mesh buffer
u16 buffer_id; // I doubt 32bits is needed
//! Index of the vertex
u32 vertex_id; // Store global ID here
//! Weight Strength/Percentage (0-1)
f32 strength;
private:
//! Internal members used by SkinnedMesh
friend class SkinnedMesh;
char *Moved;
core::vector3df StaticPos;
core::vector3df StaticNormal;
};
template <class T>
struct Channel {
struct Frame {
f32 time;
T value;
};
std::vector<Frame> frames;
bool interpolate = true;
bool empty() const {
return frames.empty();
}
f32 getEndFrame() const {
return frames.empty() ? 0 : frames.back().time;
}
void pushBack(f32 time, const T &value) {
frames.push_back({time, value});
}
void append(const Channel<T> &other) {
frames.insert(frames.end(), other.frames.begin(), other.frames.end());
}
void cleanup() {
if (frames.empty())
return;
std::vector<Frame> ordered;
ordered.push_back(frames.front());
// Drop out-of-order frames
for (auto it = frames.begin() + 1; it != frames.end(); ++it) {
if (it->time > ordered.back().time) {
ordered.push_back(*it);
}
}
frames.clear();
// Drop redundant middle keys
frames.push_back(ordered.front());
for (u32 i = 1; i < ordered.size() - 1; ++i) {
if (ordered[i - 1].value != ordered[i].value
|| ordered[i + 1].value != ordered[i].value) {
frames.push_back(ordered[i]);
}
}
if (ordered.size() > 1)
frames.push_back(ordered.back());
frames.shrink_to_fit();
}
static core::quaternion interpolateValue(core::quaternion from, core::quaternion to, f32 time) {
core::quaternion result;
result.slerp(from, to, time, 0.001f);
return result;
}
static core::vector3df interpolateValue(core::vector3df from, core::vector3df to, f32 time) {
// Note: `from` and `to` are swapped here compared to quaternion slerp
return to.getInterpolated(from, time);
}
std::optional<T> get(f32 time) const {
if (frames.empty())
return std::nullopt;
const auto next = std::lower_bound(frames.begin(), frames.end(), time, [](const auto& frame, f32 time) {
return frame.time < time;
});
if (next == frames.begin())
return next->value;
if (next == frames.end())
return frames.back().value;
const auto prev = next - 1;
if (!interpolate)
return prev->value;
return interpolateValue(prev->value, next->value, (time - prev->time) / (next->time - prev->time));
}
};
struct Keys {
Channel<core::vector3df> position;
Channel<core::quaternion> rotation;
Channel<core::vector3df> scale;
bool empty() const {
return position.empty() && rotation.empty() && scale.empty();
}
void append(const Keys &other) {
position.append(other.position);
rotation.append(other.rotation);
scale.append(other.scale);
}
f32 getEndFrame() const {
return std::max({
position.getEndFrame(),
rotation.getEndFrame(),
scale.getEndFrame()
});
}
void updateTransform(f32 frame,
core::vector3df &t, core::quaternion &r, core::vector3df &s) const
{
if (auto pos = position.get(frame))
t = *pos;
if (auto rot = rotation.get(frame))
r = *rot;
if (auto scl = scale.get(frame))
s = *scl;
}
void cleanup() {
position.cleanup();
rotation.cleanup();
scale.cleanup();
}
};
//! Joints
struct SJoint
{
SJoint() : GlobalSkinningSpace(false) {}
//! The name of this joint
std::optional<std::string> Name;
//! Local matrix of this joint
core::matrix4 LocalMatrix;
//! List of child joints
std::vector<SJoint *> Children;
//! List of attached meshes
std::vector<u32> AttachedMeshes;
// Animation keyframes for translation, rotation, scale
Keys keys;
//! Skin weights
std::vector<SWeight> Weights;
//! Unnecessary for loaders, will be overwritten on finalize
core::matrix4 GlobalMatrix; // loaders may still choose to set this (temporarily) to calculate absolute vertex data.
core::matrix4 GlobalAnimatedMatrix;
core::matrix4 LocalAnimatedMatrix;
//! These should be set by loaders.
core::vector3df Animatedposition;
core::vector3df Animatedscale;
core::quaternion Animatedrotation;
// The .x and .gltf formats pre-calculate this
std::optional<core::matrix4> GlobalInversedMatrix;
private:
//! Internal members used by SkinnedMesh
friend class SkinnedMesh;
bool GlobalSkinningSpace;
};
const std::vector<SJoint *> &getAllJoints() const {
return AllJoints;
}
protected:
void checkForAnimation();
void normalizeWeights();
void buildAllLocalAnimatedMatrices();
void buildAllGlobalAnimatedMatrices(SJoint *Joint = 0, SJoint *ParentJoint = 0);
void calculateGlobalMatrices(SJoint *Joint, SJoint *ParentJoint);
void skinJoint(SJoint *Joint, SJoint *ParentJoint);
void calculateTangents(core::vector3df &normal,
core::vector3df &tangent, core::vector3df &binormal,
const core::vector3df &vt1, const core::vector3df &vt2, const core::vector3df &vt3,
const core::vector2df &tc1, const core::vector2df &tc2, const core::vector2df &tc3);
std::vector<SSkinMeshBuffer *> *SkinningBuffers; // Meshbuffer to skin, default is to skin localBuffers
std::vector<SSkinMeshBuffer *> LocalBuffers;
//! Mapping from meshbuffer number to bindable texture slot
std::vector<u32> TextureSlots;
std::vector<SJoint *> AllJoints;
std::vector<SJoint *> RootJoints;
// bool can't be used here because std::vector<bool>
// doesn't allow taking a reference to individual elements.
std::vector<std::vector<char>> Vertices_Moved;
core::aabbox3d<f32> BoundingBox{{0, 0, 0}};
f32 EndFrame;
f32 FramesPerSecond;
f32 LastAnimatedFrame;
bool SkinnedLastFrame;
bool HasAnimation;
bool PreparedForSkinning;
bool AnimateNormals;
bool HardwareSkinning;
};
// Interface for mesh loaders
class SkinnedMeshBuilder : public SkinnedMesh {
public:
SkinnedMeshBuilder() : SkinnedMesh() {}
//! loaders should call this after populating the mesh
// returns *this, so do not try to drop the mesh builder instance
SkinnedMesh *finalize();
//! alternative method for adding joints
std::vector<SJoint *> &getAllJoints() {
return AllJoints;
}
//! Adds a new meshbuffer to the mesh, access it as last one
SSkinMeshBuffer *addMeshBuffer();
//! Adds a new meshbuffer to the mesh, access it as last one
void addMeshBuffer(SSkinMeshBuffer *meshbuf);
//! Adds a new joint to the mesh, access it as last one
SJoint *addJoint(SJoint *parent = nullptr);
void addPositionKey(SJoint *joint, f32 frame, core::vector3df pos);
void addRotationKey(SJoint *joint, f32 frame, core::quaternion rotation);
void addScaleKey(SJoint *joint, f32 frame, core::vector3df scale);
//! Adds a new weight to the mesh, access it as last one
SWeight *addWeight(SJoint *joint);
};
} // end namespace scene
} // end namespace irr

View File

@ -20,9 +20,7 @@ template <class T>
class aabbox3d class aabbox3d
{ {
public: public:
//! Default Constructor. constexpr aabbox3d() = delete;
constexpr aabbox3d() :
MinEdge(-1, -1, -1), MaxEdge(1, 1, 1) {}
//! Constructor with min edge and max edge. //! Constructor with min edge and max edge.
constexpr aabbox3d(const vector3d<T> &min, const vector3d<T> &max) : constexpr aabbox3d(const vector3d<T> &min, const vector3d<T> &max) :
MinEdge(min), MaxEdge(max) {} MinEdge(min), MaxEdge(max) {}

View File

@ -59,8 +59,12 @@ public:
{ {
size_t allocated = m_data.capacity(); size_t allocated = m_data.capacity();
if (new_size < allocated) { if (new_size < allocated) {
if (canShrink) if (canShrink) {
m_data.resize(new_size); // since capacity != size don't accidentally make it bigger
if (m_data.size() > new_size)
m_data.resize(new_size);
m_data.shrink_to_fit();
}
} else { } else {
m_data.reserve(new_size); m_data.reserve(new_size);
} }

View File

@ -36,119 +36,6 @@
#include "SIrrCreationParameters.h" #include "SIrrCreationParameters.h"
#include "IrrCompileConfig.h" // for IRRLICHT_API and IRRCALLCONV #include "IrrCompileConfig.h" // for IRRLICHT_API and IRRCALLCONV
/*! \mainpage Irrlicht Engine 1.9 API documentation
*
* <div align="center"><img src="logobig.png" ></div>
*
* \section intro Introduction
*
* Welcome to the Irrlicht Engine API documentation.
* Here you'll find any information you'll need to develop applications with
* the Irrlicht Engine. If you are looking for a tutorial on how to start, you'll
* find some on the homepage of the Irrlicht Engine at
* <A HREF="http://irrlicht.sourceforge.net" >irrlicht.sourceforge.net</A>
* or inside the SDK in the examples directory.
*
* The Irrlicht Engine is intended to be an easy-to-use 3d engine, so
* this documentation is an important part of it. If you have any questions or
* suggestions, just send a email to the author of the engine, Nikolaus Gebhardt
* (niko (at) irrlicht3d.org).
*
*
* \section links Links
*
* <A HREF="namespaces.html">Namespaces</A>: A very good place to start reading
* the documentation.<BR>
* <A HREF="annotated.html">Class list</A>: List of all classes with descriptions.<BR>
* <A HREF="functions.html">Class members</A>: Good place to find forgotten features.<BR>
*
* \section irrexample Short example
*
* A simple application, starting up the engine, loading a Quake 2 animated
* model file and the corresponding texture, animating and displaying it
* in front of a blue background and placing a user controlable 3d camera
* would look like the following code. I think this example shows the usage
* of the engine quite well:
*
* \code
* #include <irrlicht.h>
* // include a bunch of other stuff...
*
* using namespace irr;
*
* int main()
* {
* // start up the engine
* IrrlichtDevice *device = createDevice(video::EDT_OPENGL,
* core::dimension2d<u32>(640,480));
*
* video::IVideoDriver* driver = device->getVideoDriver();
* scene::ISceneManager* scenemgr = device->getSceneManager();
*
* device->setWindowCaption(L"Hello World!");
*
* // load and show quake2 .md2 model
* scene::ISceneNode* node = scenemgr->addAnimatedMeshSceneNode(
* scenemgr->getMesh("quake2model.md2"));
*
* // if everything worked, add a texture and disable lighting
* if (node)
* {
* node->setMaterialTexture(0, driver->getTexture("texture.bmp"));
* node->setMaterialFlag(video::EMF_LIGHTING, false);
* }
*
* // add a first person shooter style user controlled camera
* scenemgr->addCameraSceneNodeFPS();
*
* // draw everything
* while(device->run() && driver)
* {
* driver->beginScene(video::ECBF_COLOR | video::ECBF_DEPTH, video::SColor(255,0,0,255));
* scenemgr->drawAll();
* driver->endScene();
* }
*
* // delete device
* device->drop();
* return 0;
* }
* \endcode
*
* Irrlicht can load a lot of file formats automatically, see irr::scene::ISceneManager::getMesh()
* for a detailed list. So if you would like to replace the simple blue screen background by
* a cool Quake 3 Map, optimized by an octree, just insert this code
* somewhere before the while loop:
*
* \code
* // add .pk3 archive to the file system
* device->getFileSystem()->addZipFileArchive("quake3map.pk3");
*
* // load .bsp file and show it using an octree
* scenemgr->addOctreeSceneNode(
* scenemgr->getMesh("quake3map.bsp"));
* \endcode
*
* As you can see, the engine uses namespaces. Everything in the engine is
* placed into the namespace 'irr', but there are also 5 sub namespaces.
* You can find a list of all namespaces with descriptions at the
* <A HREF="namespaces.html"> namespaces page</A>.
* This is also a good place to start reading the documentation. If you
* don't want to write the namespace names all the time, just use all namespaces like
* this:
* \code
* using namespace core;
* using namespace scene;
* using namespace video;
* using namespace io;
* using namespace gui;
* \endcode
*
* There is a lot more the engine can do, but I hope this gave a short
* overview over the basic features of the engine. For more examples, please take
* a look into the examples directory of the SDK.
*/
//! Everything in the Irrlicht Engine can be found in this namespace. //! Everything in the Irrlicht Engine can be found in this namespace.
namespace irr namespace irr
{ {

View File

@ -13,11 +13,6 @@
#include "rect.h" #include "rect.h"
#include "IrrCompileConfig.h" // for IRRLICHT_API #include "IrrCompileConfig.h" // for IRRLICHT_API
// enable this to keep track of changes to the matrix
// and make simpler identity check for seldom changing matrices
// otherwise identity check will always compare the elements
// #define USE_MATRIX_TEST
namespace irr namespace irr
{ {
namespace core namespace core
@ -81,9 +76,6 @@ public:
//! Simple operator for directly accessing every element of the matrix. //! Simple operator for directly accessing every element of the matrix.
T &operator()(const s32 row, const s32 col) T &operator()(const s32 row, const s32 col)
{ {
#if defined(USE_MATRIX_TEST)
definitelyIdentityMatrix = false;
#endif
return M[row * 4 + col]; return M[row * 4 + col];
} }
@ -93,9 +85,6 @@ public:
//! Simple operator for linearly accessing every element of the matrix. //! Simple operator for linearly accessing every element of the matrix.
T &operator[](u32 index) T &operator[](u32 index)
{ {
#if defined(USE_MATRIX_TEST)
definitelyIdentityMatrix = false;
#endif
return M[index]; return M[index];
} }
@ -112,19 +101,12 @@ public:
const T *pointer() const { return M; } const T *pointer() const { return M; }
T *pointer() T *pointer()
{ {
#if defined(USE_MATRIX_TEST)
definitelyIdentityMatrix = false;
#endif
return M; return M;
} }
//! Returns true if other matrix is equal to this matrix. //! Returns true if other matrix is equal to this matrix.
constexpr bool operator==(const CMatrix4<T> &other) const constexpr bool operator==(const CMatrix4<T> &other) const
{ {
#if defined(USE_MATRIX_TEST)
if (definitelyIdentityMatrix && other.definitelyIdentityMatrix)
return true;
#endif
for (s32 i = 0; i < 16; ++i) for (s32 i = 0; i < 16; ++i)
if (M[i] != other.M[i]) if (M[i] != other.M[i])
return false; return false;
@ -196,9 +178,13 @@ public:
CMatrix4<T> &setInverseTranslation(const vector3d<T> &translation); CMatrix4<T> &setInverseTranslation(const vector3d<T> &translation);
//! Make a rotation matrix from Euler angles. The 4th row and column are unmodified. //! Make a rotation matrix from Euler angles. The 4th row and column are unmodified.
//! NOTE: Rotation order is ZYX. This means that vectors are
//! first rotated around the X, then the Y, and finally the Z axis.
//! NOTE: The rotation is done as per the right-hand rule.
//! See test_irr_matrix4.cpp if you're still unsure about the conventions used here.
inline CMatrix4<T> &setRotationRadians(const vector3d<T> &rotation); inline CMatrix4<T> &setRotationRadians(const vector3d<T> &rotation);
//! Make a rotation matrix from Euler angles. The 4th row and column are unmodified. //! Same as `setRotationRadians`, but uses degrees.
CMatrix4<T> &setRotationDegrees(const vector3d<T> &rotation); CMatrix4<T> &setRotationDegrees(const vector3d<T> &rotation);
//! Get the rotation, as set by setRotation() when you already know the scale used to create the matrix //! Get the rotation, as set by setRotation() when you already know the scale used to create the matrix
@ -254,12 +240,21 @@ public:
[[nodiscard]] vector3d<T> rotateAndScaleVect(const vector3d<T> &vect) const; [[nodiscard]] vector3d<T> rotateAndScaleVect(const vector3d<T> &vect) const;
//! Transforms the vector by this matrix //! Transforms the vector by this matrix
/** This operation is performed as if the vector was 4d with the 4th component =1 */ /** This operation is performed as if the vector was 4d with the 4th component = 1 */
void transformVect(vector3df &vect) const; [[nodiscard]] vector3d<T> transformVect(const vector3d<T> &v) const;
//! Transforms the vector by this matrix
/** This operation is performed as if the vector was 4d with the 4th component = 1 */
void transformVect(vector3d<T> &vect) const {
const vector3d<T> &v = vect;
vect = transformVect(v);
}
//! Transforms input vector by this matrix and stores result in output vector //! Transforms input vector by this matrix and stores result in output vector
/** This operation is performed as if the vector was 4d with the 4th component =1 */ /** This operation is performed as if the vector was 4d with the 4th component = 1 */
void transformVect(vector3df &out, const vector3df &in) const; void transformVect(vector3d<T> &out, const vector3d<T> &in) const {
out = transformVect(in);
}
//! An alternate transform vector method, writing into an array of 4 floats //! An alternate transform vector method, writing into an array of 4 floats
/** This operation is performed as if the vector was 4d with the 4th component =1. /** This operation is performed as if the vector was 4d with the 4th component =1.
@ -443,31 +438,17 @@ public:
//! Sets all matrix data members at once //! Sets all matrix data members at once
CMatrix4<T> &setM(const T *data); CMatrix4<T> &setM(const T *data);
//! Sets if the matrix is definitely identity matrix
void setDefinitelyIdentityMatrix(bool isDefinitelyIdentityMatrix);
//! Gets if the matrix is definitely identity matrix
bool getDefinitelyIdentityMatrix() const;
//! Compare two matrices using the equal method //! Compare two matrices using the equal method
bool equals(const core::CMatrix4<T> &other, const T tolerance = (T)ROUNDING_ERROR_f64) const; bool equals(const core::CMatrix4<T> &other, const T tolerance = (T)ROUNDING_ERROR_f64) const;
private: private:
//! Matrix data, stored in row-major order //! Matrix data, stored in row-major order
T M[16]; T M[16];
#if defined(USE_MATRIX_TEST)
//! Flag is this matrix is identity matrix
mutable u32 definitelyIdentityMatrix;
#endif
}; };
// Default constructor // Default constructor
template <class T> template <class T>
inline CMatrix4<T>::CMatrix4(eConstructor constructor) inline CMatrix4<T>::CMatrix4(eConstructor constructor)
#if defined(USE_MATRIX_TEST)
:
definitelyIdentityMatrix(BIT_UNTESTED)
#endif
{ {
switch (constructor) { switch (constructor) {
case EM4CONST_NOTHING: case EM4CONST_NOTHING:
@ -484,10 +465,6 @@ inline CMatrix4<T>::CMatrix4(eConstructor constructor)
// Copy constructor // Copy constructor
template <class T> template <class T>
inline CMatrix4<T>::CMatrix4(const CMatrix4<T> &other, eConstructor constructor) inline CMatrix4<T>::CMatrix4(const CMatrix4<T> &other, eConstructor constructor)
#if defined(USE_MATRIX_TEST)
:
definitelyIdentityMatrix(BIT_UNTESTED)
#endif
{ {
switch (constructor) { switch (constructor) {
case EM4CONST_IDENTITY: case EM4CONST_IDENTITY:
@ -713,9 +690,6 @@ inline CMatrix4<T> &CMatrix4<T>::setbyproduct_nocheck(const CMatrix4<T> &other_a
M[13] = m1[1] * m2[12] + m1[5] * m2[13] + m1[9] * m2[14] + m1[13] * m2[15]; M[13] = m1[1] * m2[12] + m1[5] * m2[13] + m1[9] * m2[14] + m1[13] * m2[15];
M[14] = m1[2] * m2[12] + m1[6] * m2[13] + m1[10] * m2[14] + m1[14] * m2[15]; M[14] = m1[2] * m2[12] + m1[6] * m2[13] + m1[10] * m2[14] + m1[14] * m2[15];
M[15] = m1[3] * m2[12] + m1[7] * m2[13] + m1[11] * m2[14] + m1[15] * m2[15]; M[15] = m1[3] * m2[12] + m1[7] * m2[13] + m1[11] * m2[14] + m1[15] * m2[15];
#if defined(USE_MATRIX_TEST)
definitelyIdentityMatrix = false;
#endif
return *this; return *this;
} }
@ -787,9 +761,6 @@ inline CMatrix4<T> &CMatrix4<T>::setTranslation(const vector3d<T> &translation)
M[12] = translation.X; M[12] = translation.X;
M[13] = translation.Y; M[13] = translation.Y;
M[14] = translation.Z; M[14] = translation.Z;
#if defined(USE_MATRIX_TEST)
definitelyIdentityMatrix = false;
#endif
return *this; return *this;
} }
@ -799,9 +770,6 @@ inline CMatrix4<T> &CMatrix4<T>::setInverseTranslation(const vector3d<T> &transl
M[12] = -translation.X; M[12] = -translation.X;
M[13] = -translation.Y; M[13] = -translation.Y;
M[14] = -translation.Z; M[14] = -translation.Z;
#if defined(USE_MATRIX_TEST)
definitelyIdentityMatrix = false;
#endif
return *this; return *this;
} }
@ -811,9 +779,6 @@ inline CMatrix4<T> &CMatrix4<T>::setScale(const vector3d<T> &scale)
M[0] = scale.X; M[0] = scale.X;
M[5] = scale.Y; M[5] = scale.Y;
M[10] = scale.Z; M[10] = scale.Z;
#if defined(USE_MATRIX_TEST)
definitelyIdentityMatrix = false;
#endif
return *this; return *this;
} }
@ -856,30 +821,27 @@ inline CMatrix4<T> &CMatrix4<T>::setInverseRotationDegrees(const vector3d<T> &ro
template <class T> template <class T>
inline CMatrix4<T> &CMatrix4<T>::setRotationRadians(const vector3d<T> &rotation) inline CMatrix4<T> &CMatrix4<T>::setRotationRadians(const vector3d<T> &rotation)
{ {
const f64 cr = cos(rotation.X); const f64 cPitch = cos(rotation.X);
const f64 sr = sin(rotation.X); const f64 sPitch = sin(rotation.X);
const f64 cp = cos(rotation.Y); const f64 cYaw = cos(rotation.Y);
const f64 sp = sin(rotation.Y); const f64 sYaw = sin(rotation.Y);
const f64 cy = cos(rotation.Z); const f64 cRoll = cos(rotation.Z);
const f64 sy = sin(rotation.Z); const f64 sRoll = sin(rotation.Z);
M[0] = (T)(cp * cy); M[0] = (T)(cYaw * cRoll);
M[1] = (T)(cp * sy); M[1] = (T)(cYaw * sRoll);
M[2] = (T)(-sp); M[2] = (T)(-sYaw);
const f64 srsp = sr * sp; const f64 sPitch_sYaw = sPitch * sYaw;
const f64 crsp = cr * sp; const f64 cPitch_sYaw = cPitch * sYaw;
M[4] = (T)(srsp * cy - cr * sy); M[4] = (T)(sPitch_sYaw * cRoll - cPitch * sRoll);
M[5] = (T)(srsp * sy + cr * cy); M[5] = (T)(sPitch_sYaw * sRoll + cPitch * cRoll);
M[6] = (T)(sr * cp); M[6] = (T)(sPitch * cYaw);
M[8] = (T)(crsp * cy + sr * sy); M[8] = (T)(cPitch_sYaw * cRoll + sPitch * sRoll);
M[9] = (T)(crsp * sy - sr * cy); M[9] = (T)(cPitch_sYaw * sRoll - sPitch * cRoll);
M[10] = (T)(cr * cp); M[10] = (T)(cPitch * cYaw);
#if defined(USE_MATRIX_TEST)
definitelyIdentityMatrix = false;
#endif
return *this; return *this;
} }
@ -960,30 +922,27 @@ inline core::vector3d<T> CMatrix4<T>::getRotationDegrees() const
template <class T> template <class T>
inline CMatrix4<T> &CMatrix4<T>::setInverseRotationRadians(const vector3d<T> &rotation) inline CMatrix4<T> &CMatrix4<T>::setInverseRotationRadians(const vector3d<T> &rotation)
{ {
f64 cr = cos(rotation.X); f64 cPitch = cos(rotation.X);
f64 sr = sin(rotation.X); f64 sPitch = sin(rotation.X);
f64 cp = cos(rotation.Y); f64 cYaw = cos(rotation.Y);
f64 sp = sin(rotation.Y); f64 sYaw = sin(rotation.Y);
f64 cy = cos(rotation.Z); f64 cRoll = cos(rotation.Z);
f64 sy = sin(rotation.Z); f64 sRoll = sin(rotation.Z);
M[0] = (T)(cp * cy); M[0] = (T)(cYaw * cRoll);
M[4] = (T)(cp * sy); M[4] = (T)(cYaw * sRoll);
M[8] = (T)(-sp); M[8] = (T)(-sYaw);
f64 srsp = sr * sp; f64 sPitch_sYaw = sPitch * sYaw;
f64 crsp = cr * sp; f64 cPitch_sYaw = cPitch * sYaw;
M[1] = (T)(srsp * cy - cr * sy); M[1] = (T)(sPitch_sYaw * cRoll - cPitch * sRoll);
M[5] = (T)(srsp * sy + cr * cy); M[5] = (T)(sPitch_sYaw * sRoll + cPitch * cRoll);
M[9] = (T)(sr * cp); M[9] = (T)(sPitch * cYaw);
M[2] = (T)(crsp * cy + sr * sy); M[2] = (T)(cPitch_sYaw * cRoll + sPitch * sRoll);
M[6] = (T)(crsp * sy - sr * cy); M[6] = (T)(cPitch_sYaw * sRoll - sPitch * cRoll);
M[10] = (T)(cr * cp); M[10] = (T)(cPitch * cYaw);
#if defined(USE_MATRIX_TEST)
definitelyIdentityMatrix = false;
#endif
return *this; return *this;
} }
@ -1015,9 +974,6 @@ inline CMatrix4<T> &CMatrix4<T>::setRotationAxisRadians(const T &angle, const ve
M[9] = (T)(tz * axis.Y - sx); M[9] = (T)(tz * axis.Y - sx);
M[10] = (T)(tz * axis.Z + c); M[10] = (T)(tz * axis.Z + c);
#if defined(USE_MATRIX_TEST)
definitelyIdentityMatrix = false;
#endif
return *this; return *this;
} }
@ -1028,9 +984,6 @@ inline CMatrix4<T> &CMatrix4<T>::makeIdentity()
{ {
memset(M, 0, 16 * sizeof(T)); memset(M, 0, 16 * sizeof(T));
M[0] = M[5] = M[10] = M[15] = (T)1; M[0] = M[5] = M[10] = M[15] = (T)1;
#if defined(USE_MATRIX_TEST)
definitelyIdentityMatrix = true;
#endif
return *this; return *this;
} }
@ -1041,10 +994,6 @@ inline CMatrix4<T> &CMatrix4<T>::makeIdentity()
template <class T> template <class T>
inline bool CMatrix4<T>::isIdentity() const inline bool CMatrix4<T>::isIdentity() const
{ {
#if defined(USE_MATRIX_TEST)
if (definitelyIdentityMatrix)
return true;
#endif
if (!core::equals(M[12], (T)0) || !core::equals(M[13], (T)0) || !core::equals(M[14], (T)0) || !core::equals(M[15], (T)1)) if (!core::equals(M[12], (T)0) || !core::equals(M[13], (T)0) || !core::equals(M[14], (T)0) || !core::equals(M[15], (T)1))
return false; return false;
@ -1068,9 +1017,6 @@ inline bool CMatrix4<T>::isIdentity() const
if ((j != i) && (!iszero((*this)(i,j)))) if ((j != i) && (!iszero((*this)(i,j))))
return false; return false;
*/ */
#if defined(USE_MATRIX_TEST)
definitelyIdentityMatrix = true;
#endif
return true; return true;
} }
@ -1106,10 +1052,6 @@ inline bool CMatrix4<T>::isOrthogonal() const
template <class T> template <class T>
inline bool CMatrix4<T>::isIdentity_integer_base() const inline bool CMatrix4<T>::isIdentity_integer_base() const
{ {
#if defined(USE_MATRIX_TEST)
if (definitelyIdentityMatrix)
return true;
#endif
if (IR(M[0]) != F32_VALUE_1) if (IR(M[0]) != F32_VALUE_1)
return false; return false;
if (IR(M[1]) != 0) if (IR(M[1]) != 0)
@ -1146,9 +1088,6 @@ inline bool CMatrix4<T>::isIdentity_integer_base() const
if (IR(M[15]) != F32_VALUE_1) if (IR(M[15]) != F32_VALUE_1)
return false; return false;
#if defined(USE_MATRIX_TEST)
definitelyIdentityMatrix = true;
#endif
return true; return true;
} }
@ -1173,25 +1112,13 @@ inline vector3d<T> CMatrix4<T>::scaleThenInvRotVect(const vector3d<T> &v) const
} }
template <class T> template <class T>
inline void CMatrix4<T>::transformVect(vector3df &vect) const inline vector3d<T> CMatrix4<T>::transformVect(const vector3d<T> &v) const
{ {
T vector[3]; return {
v.X * M[0] + v.Y * M[4] + v.Z * M[8] + M[12],
vector[0] = vect.X * M[0] + vect.Y * M[4] + vect.Z * M[8] + M[12]; v.X * M[1] + v.Y * M[5] + v.Z * M[9] + M[13],
vector[1] = vect.X * M[1] + vect.Y * M[5] + vect.Z * M[9] + M[13]; v.X * M[2] + v.Y * M[6] + v.Z * M[10] + M[14],
vector[2] = vect.X * M[2] + vect.Y * M[6] + vect.Z * M[10] + M[14]; };
vect.X = static_cast<f32>(vector[0]);
vect.Y = static_cast<f32>(vector[1]);
vect.Z = static_cast<f32>(vector[2]);
}
template <class T>
inline void CMatrix4<T>::transformVect(vector3df &out, const vector3df &in) const
{
out.X = in.X * M[0] + in.Y * M[4] + in.Z * M[8] + M[12];
out.Y = in.X * M[1] + in.Y * M[5] + in.Z * M[9] + M[13];
out.Z = in.X * M[2] + in.Y * M[6] + in.Z * M[10] + M[14];
} }
template <class T> template <class T>
@ -1402,9 +1329,6 @@ inline bool CMatrix4<T>::getInverse(CMatrix4<T> &out) const
m[1] * (m[6] * m[8] - m[4] * m[10]) + m[1] * (m[6] * m[8] - m[4] * m[10]) +
m[2] * (m[4] * m[9] - m[5] * m[8])); m[2] * (m[4] * m[9] - m[5] * m[8]));
#if defined(USE_MATRIX_TEST)
out.definitelyIdentityMatrix = definitelyIdentityMatrix;
#endif
return true; return true;
} }
@ -1433,9 +1357,6 @@ inline bool CMatrix4<T>::getInversePrimitive(CMatrix4<T> &out) const
out.M[14] = (T) - (M[12] * M[8] + M[13] * M[9] + M[14] * M[10]); out.M[14] = (T) - (M[12] * M[8] + M[13] * M[9] + M[14] * M[10]);
out.M[15] = 1; out.M[15] = 1;
#if defined(USE_MATRIX_TEST)
out.definitelyIdentityMatrix = definitelyIdentityMatrix;
#endif
return true; return true;
} }
@ -1444,10 +1365,6 @@ inline bool CMatrix4<T>::getInversePrimitive(CMatrix4<T> &out) const
template <class T> template <class T>
inline bool CMatrix4<T>::makeInverse() inline bool CMatrix4<T>::makeInverse()
{ {
#if defined(USE_MATRIX_TEST)
if (definitelyIdentityMatrix)
return true;
#endif
CMatrix4<T> temp(EM4CONST_NOTHING); CMatrix4<T> temp(EM4CONST_NOTHING);
if (getInverse(temp)) { if (getInverse(temp)) {
@ -1464,9 +1381,6 @@ inline CMatrix4<T> &CMatrix4<T>::operator=(const T &scalar)
for (s32 i = 0; i < 16; ++i) for (s32 i = 0; i < 16; ++i)
M[i] = scalar; M[i] = scalar;
#if defined(USE_MATRIX_TEST)
definitelyIdentityMatrix = false;
#endif
return *this; return *this;
} }
@ -1509,9 +1423,6 @@ inline CMatrix4<T> &CMatrix4<T>::buildProjectionMatrixPerspectiveFovRH(
M[14] = (T)(2.0f * zNear * zFar / (zNear - zFar)); M[14] = (T)(2.0f * zNear * zFar / (zNear - zFar));
} }
#if defined(USE_MATRIX_TEST)
definitelyIdentityMatrix = false;
#endif
return *this; return *this;
} }
@ -1554,9 +1465,6 @@ inline CMatrix4<T> &CMatrix4<T>::buildProjectionMatrixPerspectiveFovLH(
M[14] = (T)(2.0f * zNear * zFar / (zNear - zFar)); M[14] = (T)(2.0f * zNear * zFar / (zNear - zFar));
} }
#if defined(USE_MATRIX_TEST)
definitelyIdentityMatrix = false;
#endif
return *this; return *this;
} }
@ -1589,9 +1497,6 @@ inline CMatrix4<T> &CMatrix4<T>::buildProjectionMatrixPerspectiveFovInfinityLH(
M[14] = (T)(zNear * (epsilon - 1.f)); M[14] = (T)(zNear * (epsilon - 1.f));
M[15] = 0; M[15] = 0;
#if defined(USE_MATRIX_TEST)
definitelyIdentityMatrix = false;
#endif
return *this; return *this;
} }
@ -1631,9 +1536,6 @@ inline CMatrix4<T> &CMatrix4<T>::buildProjectionMatrixOrthoLH(
M[14] = (T) - (zFar + zNear) / (zFar - zNear); M[14] = (T) - (zFar + zNear) / (zFar - zNear);
} }
#if defined(USE_MATRIX_TEST)
definitelyIdentityMatrix = false;
#endif
return *this; return *this;
} }
@ -1673,9 +1575,6 @@ inline CMatrix4<T> &CMatrix4<T>::buildProjectionMatrixOrthoRH(
M[14] = (T) - (zFar + zNear) / (zFar - zNear); M[14] = (T) - (zFar + zNear) / (zFar - zNear);
} }
#if defined(USE_MATRIX_TEST)
definitelyIdentityMatrix = false;
#endif
return *this; return *this;
} }
@ -1716,9 +1615,6 @@ inline CMatrix4<T> &CMatrix4<T>::buildProjectionMatrixPerspectiveRH(
M[14] = (T)(2.0f * zNear * zFar / (zNear - zFar)); M[14] = (T)(2.0f * zNear * zFar / (zNear - zFar));
} }
#if defined(USE_MATRIX_TEST)
definitelyIdentityMatrix = false;
#endif
return *this; return *this;
} }
@ -1759,9 +1655,6 @@ inline CMatrix4<T> &CMatrix4<T>::buildProjectionMatrixPerspectiveLH(
M[14] = (T)(2.0f * zNear * zFar / (zNear - zFar)); M[14] = (T)(2.0f * zNear * zFar / (zNear - zFar));
} }
#if defined(USE_MATRIX_TEST)
definitelyIdentityMatrix = false;
#endif
return *this; return *this;
} }
@ -1791,9 +1684,7 @@ inline CMatrix4<T> &CMatrix4<T>::buildShadowMatrix(const core::vector3df &light,
M[13] = (T)(-plane.D * light.Y); M[13] = (T)(-plane.D * light.Y);
M[14] = (T)(-plane.D * light.Z); M[14] = (T)(-plane.D * light.Z);
M[15] = (T)(-plane.D * point + d); M[15] = (T)(-plane.D * point + d);
#if defined(USE_MATRIX_TEST)
definitelyIdentityMatrix = false;
#endif
return *this; return *this;
} }
@ -1831,9 +1722,7 @@ inline CMatrix4<T> &CMatrix4<T>::buildCameraLookAtMatrixLH(
M[13] = (T)-yaxis.dotProduct(position); M[13] = (T)-yaxis.dotProduct(position);
M[14] = (T)-zaxis.dotProduct(position); M[14] = (T)-zaxis.dotProduct(position);
M[15] = 1; M[15] = 1;
#if defined(USE_MATRIX_TEST)
definitelyIdentityMatrix = false;
#endif
return *this; return *this;
} }
@ -1871,9 +1760,7 @@ inline CMatrix4<T> &CMatrix4<T>::buildCameraLookAtMatrixRH(
M[13] = (T)-yaxis.dotProduct(position); M[13] = (T)-yaxis.dotProduct(position);
M[14] = (T)-zaxis.dotProduct(position); M[14] = (T)-zaxis.dotProduct(position);
M[15] = 1; M[15] = 1;
#if defined(USE_MATRIX_TEST)
definitelyIdentityMatrix = false;
#endif
return *this; return *this;
} }
@ -1924,9 +1811,6 @@ inline void CMatrix4<T>::getTransposed(CMatrix4<T> &o) const
o[13] = M[7]; o[13] = M[7];
o[14] = M[11]; o[14] = M[11];
o[15] = M[15]; o[15] = M[15];
#if defined(USE_MATRIX_TEST)
o.definitelyIdentityMatrix = definitelyIdentityMatrix;
#endif
} }
// used to scale <-1,-1><1,1> to viewport // used to scale <-1,-1><1,1> to viewport
@ -2064,9 +1948,6 @@ inline void CMatrix4<T>::setRotationCenter(const core::vector3df &center, const
M[13] = -M[1] * center.X - M[5] * center.Y - M[9] * center.Z + (center.Y - translation.Y); M[13] = -M[1] * center.X - M[5] * center.Y - M[9] * center.Z + (center.Y - translation.Y);
M[14] = -M[2] * center.X - M[6] * center.Y - M[10] * center.Z + (center.Z - translation.Z); M[14] = -M[2] * center.X - M[6] * center.Y - M[10] * center.Z + (center.Z - translation.Z);
M[15] = (T)1.0; M[15] = (T)1.0;
#if defined(USE_MATRIX_TEST)
definitelyIdentityMatrix = false;
#endif
} }
/*! /*!
@ -2108,9 +1989,7 @@ inline CMatrix4<T> &CMatrix4<T>::buildTextureTransform(f32 rotateRad,
M[13] = 0; M[13] = 0;
M[14] = 0; M[14] = 0;
M[15] = 1; M[15] = 1;
#if defined(USE_MATRIX_TEST)
definitelyIdentityMatrix = false;
#endif
return *this; return *this;
} }
@ -2129,9 +2008,6 @@ inline CMatrix4<T> &CMatrix4<T>::setTextureRotationCenter(f32 rotateRad)
M[8] = (T)(0.5f * (s - c) + 0.5f); M[8] = (T)(0.5f * (s - c) + 0.5f);
M[9] = (T)(-0.5f * (s + c) + 0.5f); M[9] = (T)(-0.5f * (s + c) + 0.5f);
#if defined(USE_MATRIX_TEST)
definitelyIdentityMatrix = definitelyIdentityMatrix && (rotateRad == 0.0f);
#endif
return *this; return *this;
} }
@ -2141,9 +2017,6 @@ inline CMatrix4<T> &CMatrix4<T>::setTextureTranslate(f32 x, f32 y)
M[8] = (T)x; M[8] = (T)x;
M[9] = (T)y; M[9] = (T)y;
#if defined(USE_MATRIX_TEST)
definitelyIdentityMatrix = definitelyIdentityMatrix && (x == 0.0f) && (y == 0.0f);
#endif
return *this; return *this;
} }
@ -2159,10 +2032,6 @@ inline CMatrix4<T> &CMatrix4<T>::setTextureTranslateTransposed(f32 x, f32 y)
{ {
M[2] = (T)x; M[2] = (T)x;
M[6] = (T)y; M[6] = (T)y;
#if defined(USE_MATRIX_TEST)
definitelyIdentityMatrix = definitelyIdentityMatrix && (x == 0.0f) && (y == 0.0f);
#endif
return *this; return *this;
} }
@ -2171,9 +2040,6 @@ inline CMatrix4<T> &CMatrix4<T>::setTextureScale(f32 sx, f32 sy)
{ {
M[0] = (T)sx; M[0] = (T)sx;
M[5] = (T)sy; M[5] = (T)sy;
#if defined(USE_MATRIX_TEST)
definitelyIdentityMatrix = definitelyIdentityMatrix && (sx == 1.0f) && (sy == 1.0f);
#endif
return *this; return *this;
} }
@ -2191,10 +2057,6 @@ inline CMatrix4<T> &CMatrix4<T>::setTextureScaleCenter(f32 sx, f32 sy)
M[5] = (T)sy; M[5] = (T)sy;
M[8] = (T)(0.5f - 0.5f * sx); M[8] = (T)(0.5f - 0.5f * sx);
M[9] = (T)(0.5f - 0.5f * sy); M[9] = (T)(0.5f - 0.5f * sy);
#if defined(USE_MATRIX_TEST)
definitelyIdentityMatrix = definitelyIdentityMatrix && (sx == 1.0f) && (sy == 1.0f);
#endif
return *this; return *this;
} }
@ -2203,43 +2065,13 @@ template <class T>
inline CMatrix4<T> &CMatrix4<T>::setM(const T *data) inline CMatrix4<T> &CMatrix4<T>::setM(const T *data)
{ {
memcpy(M, data, 16 * sizeof(T)); memcpy(M, data, 16 * sizeof(T));
#if defined(USE_MATRIX_TEST)
definitelyIdentityMatrix = false;
#endif
return *this; return *this;
} }
// sets if the matrix is definitely identity matrix
template <class T>
inline void CMatrix4<T>::setDefinitelyIdentityMatrix(bool isDefinitelyIdentityMatrix)
{
#if defined(USE_MATRIX_TEST)
definitelyIdentityMatrix = isDefinitelyIdentityMatrix;
#else
(void)isDefinitelyIdentityMatrix; // prevent compiler warning
#endif
}
// gets if the matrix is definitely identity matrix
template <class T>
inline bool CMatrix4<T>::getDefinitelyIdentityMatrix() const
{
#if defined(USE_MATRIX_TEST)
return definitelyIdentityMatrix;
#else
return false;
#endif
}
//! Compare two matrices using the equal method //! Compare two matrices using the equal method
template <class T> template <class T>
inline bool CMatrix4<T>::equals(const core::CMatrix4<T> &other, const T tolerance) const inline bool CMatrix4<T>::equals(const core::CMatrix4<T> &other, const T tolerance) const
{ {
#if defined(USE_MATRIX_TEST)
if (definitelyIdentityMatrix && other.definitelyIdentityMatrix)
return true;
#endif
for (s32 i = 0; i < 16; ++i) for (s32 i = 0; i < 16; ++i)
if (!core::equals(M[i], other.M[i], tolerance)) if (!core::equals(M[i], other.M[i], tolerance))
return false; return false;

View File

@ -15,11 +15,18 @@
#ifndef APIENTRYP #ifndef APIENTRYP
#define APIENTRYP APIENTRY * #define APIENTRYP APIENTRY *
#endif #endif
#ifndef GLAPI // undefine a few names that can easily clash with system headers
#define GLAPI extern #ifdef NO_ERROR
#undef NO_ERROR
#endif
#ifdef ZERO
#undef ZERO
#endif
#ifdef ONE
#undef ONE
#endif #endif
class OpenGLProcedures { class OpenGLProcedures final {
private: private:
// ./glcorearb.h // ./glcorearb.h
typedef void GLvoid; typedef void GLvoid;
@ -49,8 +56,6 @@ private:
typedef khronos_int64_t GLint64EXT; typedef khronos_int64_t GLint64EXT;
typedef void *GLeglClientBufferEXT; typedef void *GLeglClientBufferEXT;
// The script will miss this particular typedef thinking it's a PFN,
// so we have to paste it in manually. It's the only such type in OpenGL.
typedef void (APIENTRY *GLDEBUGPROC) typedef void (APIENTRY *GLDEBUGPROC)
(GLenum source,GLenum type,GLuint id,GLenum severity,GLsizei length,const GLchar *message,const void *userParam); (GLenum source,GLenum type,GLuint id,GLenum severity,GLsizei length,const GLchar *message,const void *userParam);
@ -775,10 +780,12 @@ private:
typedef void (APIENTRYP PFNGLTEXPAGECOMMITMENTPROC_MT) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLboolean commit); typedef void (APIENTRYP PFNGLTEXPAGECOMMITMENTPROC_MT) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLboolean commit);
std::unordered_set<std::string> extensions; std::unordered_set<std::string> extensions;
public: public:
// Call this once after creating the context. // Call this once after creating the context.
void LoadAllProcedures(irr::video::IContextManager *cmgr); void LoadAllProcedures(irr::video::IContextManager *cmgr);
// Check if an extension is supported. /// Check if an extension is supported.
/// @param ext full extension name e.g. "GL_KHR_no_error"
inline bool IsExtensionPresent(const std::string &ext) const inline bool IsExtensionPresent(const std::string &ext) const
{ {
return extensions.count(ext) > 0; return extensions.count(ext) > 0;
@ -3185,6 +3192,7 @@ public:
static constexpr const GLenum STATE_RESTORE = 0x8BDC; static constexpr const GLenum STATE_RESTORE = 0x8BDC;
static constexpr const GLenum SHADER_BINARY_VIV = 0x8FC4; static constexpr const GLenum SHADER_BINARY_VIV = 0x8FC4;
static constexpr const GLenum NO_ERROR = 0;
static constexpr const GLenum ZERO = 0; static constexpr const GLenum ZERO = 0;
static constexpr const GLenum ONE = 1; static constexpr const GLenum ONE = 1;
static constexpr const GLenum NONE = 0; static constexpr const GLenum NONE = 0;

View File

@ -358,8 +358,6 @@ inline void quaternion::getMatrixFast(matrix4 &dest) const
dest[13] = 0.f; dest[13] = 0.f;
dest[14] = 0.f; dest[14] = 0.f;
dest[15] = 1.f; dest[15] = 1.f;
dest.setDefinitelyIdentityMatrix(false);
} }
/*! /*!
@ -397,8 +395,6 @@ inline void quaternion::getMatrix(matrix4 &dest,
dest[13] = center.Y; dest[13] = center.Y;
dest[14] = center.Z; dest[14] = center.Z;
dest[15] = 1.f; dest[15] = 1.f;
dest.setDefinitelyIdentityMatrix(false);
} }
/*! /*!
@ -471,8 +467,6 @@ inline void quaternion::getMatrix_transposed(matrix4 &dest) const
dest[7] = 0.f; dest[7] = 0.f;
dest[11] = 0.f; dest[11] = 0.f;
dest[15] = 1.f; dest[15] = 1.f;
dest.setDefinitelyIdentityMatrix(false);
} }
// Inverts this quaternion // Inverts this quaternion

View File

@ -219,11 +219,11 @@ local function ParseHeader( path, into, apiRegex, defs, consts, nameSet, noNewNa
}; };
end end
elseif ( line:find( "#" ) and not line:find( "#include" ) ) then elseif ( line:find( "#" ) and not line:find( "#include" ) ) then
local rawName, value = line:match( "#define%s+GL_([_%w]+)%s+0x(%w+)" ); local rawName, value = line:match( "#define%s+GL_([_%w]+)%s+(0x%w+)" );
if rawName and value then if rawName and value then
local name, vendor = StripVendorSuffix( rawName, true ); local name, vendor = StripVendorSuffix( rawName, true );
if not constBanned[vendor] then if not constBanned[vendor] then
consts:Add{ name = name, vendor = vendor, value = "0x"..value }; consts:Add{ name = name, vendor = vendor, value = value };
end end
end end
::skip:: ::skip::
@ -359,21 +359,28 @@ f:write[[
#ifndef APIENTRYP #ifndef APIENTRYP
#define APIENTRYP APIENTRY * #define APIENTRYP APIENTRY *
#endif #endif
#ifndef GLAPI // undefine a few names that can easily clash with system headers
#define GLAPI extern #ifdef NO_ERROR
#undef NO_ERROR
#endif
#ifdef ZERO
#undef ZERO
#endif
#ifdef ONE
#undef ONE
#endif #endif
]]; ]];
f:write[[ f:write[[
class OpenGLProcedures { class OpenGLProcedures final {
private: private:
]]; ]];
f:write( definitions:Concat( "\n" ) ); f:write( definitions:Concat( "\n" ) );
f:write( "\n" ); f:write( "\n" );
-- The script will miss this particular typedef thinking it's a PFN,
-- so we have to paste it in manually. It's the only such type in OpenGL.
f:write[[ f:write[[
// The script will miss this particular typedef thinking it's a PFN,
// so we have to paste it in manually. It's the only such type in OpenGL.
typedef void (APIENTRY *GLDEBUGPROC) typedef void (APIENTRY *GLDEBUGPROC)
(GLenum source,GLenum type,GLuint id,GLenum severity,GLsizei length,const GLchar *message,const void *userParam); (GLenum source,GLenum type,GLuint id,GLenum severity,GLsizei length,const GLchar *message,const void *userParam);
@ -382,10 +389,12 @@ f:write( typedefs:Concat( "\n" ) );
f:write( "\n\n" ); f:write( "\n\n" );
f:write [[ f:write [[
std::unordered_set<std::string> extensions; std::unordered_set<std::string> extensions;
public: public:
// Call this once after creating the context. // Call this once after creating the context.
void LoadAllProcedures(irr::video::IContextManager *cmgr); void LoadAllProcedures(irr::video::IContextManager *cmgr);
// Check if an extension is supported. /// Check if an extension is supported.
/// @param ext full extension name e.g. "GL_KHR_no_error"
inline bool IsExtensionPresent(const std::string &ext) const inline bool IsExtensionPresent(const std::string &ext) const
{ {
return extensions.count(ext) > 0; return extensions.count(ext) > 0;
@ -396,7 +405,10 @@ f:write( pointers:Concat( "\n" ) );
f:write( "\n\n" ); f:write( "\n\n" );
f:write( cppConsts:Concat( "\n" ) ); f:write( cppConsts:Concat( "\n" ) );
f:write( "\n\n" ); f:write( "\n\n" );
-- We filter constants not in hex format to avoid the VERSION_X_X and extension
-- defines, but that means we miss these.
f:write[[ f:write[[
static constexpr const GLenum NO_ERROR = 0;
static constexpr const GLenum ZERO = 0; static constexpr const GLenum ZERO = 0;
static constexpr const GLenum ONE = 1; static constexpr const GLenum ONE = 1;
static constexpr const GLenum NONE = 0; static constexpr const GLenum NONE = 0;
@ -416,7 +428,7 @@ f:write[[
#include <string> #include <string>
#include <sstream> #include <sstream>
OpenGLProcedures GL = OpenGLProcedures(); OpenGLProcedures GL;
void OpenGLProcedures::LoadAllProcedures(irr::video::IContextManager *cmgr) void OpenGLProcedures::LoadAllProcedures(irr::video::IContextManager *cmgr)
{ {
@ -425,9 +437,11 @@ void OpenGLProcedures::LoadAllProcedures(irr::video::IContextManager *cmgr)
f:write( loader:Concat() ); f:write( loader:Concat() );
f:write[[ f:write[[
// OpenGL 3 way to enumerate extensions /* OpenGL 3 & ES 3 way to enumerate extensions */
GLint ext_count = 0; GLint ext_count = 0;
GetIntegerv(NUM_EXTENSIONS, &ext_count); GetIntegerv(NUM_EXTENSIONS, &ext_count);
// clear error which is raised if unsupported
while (GetError() != GL.NO_ERROR) {}
extensions.reserve(ext_count); extensions.reserve(ext_count);
for (GLint k = 0; k < ext_count; k++) { for (GLint k = 0; k < ext_count; k++) {
auto tmp = GetStringi(EXTENSIONS, k); auto tmp = GetStringi(EXTENSIONS, k);
@ -437,16 +451,15 @@ f:write[[
if (!extensions.empty()) if (!extensions.empty())
return; return;
// OpenGL 2 / ES 2 way to enumerate extensions /* OpenGL 2 / ES 2 way to enumerate extensions */
auto ext_str = GetString(EXTENSIONS); auto ext_str = GetString(EXTENSIONS);
if (!ext_str) if (!ext_str)
return; return;
// get the extension string, chop it up // get the extension string, chop it up
std::stringstream ext_ss((char*)ext_str); std::istringstream ext_ss((char*)ext_str);
std::string tmp; std::string tmp;
while (std::getline(ext_ss, tmp, ' ')) while (std::getline(ext_ss, tmp, ' '))
extensions.emplace(tmp); extensions.emplace(tmp);
} }
]]; ]];
f:close(); f:close();

View File

@ -7,7 +7,7 @@
#include "ISceneManager.h" #include "ISceneManager.h"
#include "S3DVertex.h" #include "S3DVertex.h"
#include "os.h" #include "os.h"
#include "CSkinnedMesh.h" #include "SkinnedMesh.h"
#include "IDummyTransformationSceneNode.h" #include "IDummyTransformationSceneNode.h"
#include "IBoneSceneNode.h" #include "IBoneSceneNode.h"
#include "IMaterialRenderer.h" #include "IMaterialRenderer.h"
@ -38,10 +38,6 @@ CAnimatedMeshSceneNode::CAnimatedMeshSceneNode(IAnimatedMesh *mesh,
Looping(true), ReadOnlyMaterials(false), RenderFromIdentity(false), Looping(true), ReadOnlyMaterials(false), RenderFromIdentity(false),
LoopCallBack(0), PassCount(0) LoopCallBack(0), PassCount(0)
{ {
#ifdef _DEBUG
setDebugName("CAnimatedMeshSceneNode");
#endif
setMesh(mesh); setMesh(mesh);
} }
@ -165,12 +161,12 @@ IMesh *CAnimatedMeshSceneNode::getMeshForCurrentFrame()
// As multiple scene nodes may be sharing the same skinned mesh, we have to // As multiple scene nodes may be sharing the same skinned mesh, we have to
// re-animate it every frame to ensure that this node gets the mesh that it needs. // re-animate it every frame to ensure that this node gets the mesh that it needs.
CSkinnedMesh *skinnedMesh = static_cast<CSkinnedMesh *>(Mesh); SkinnedMesh *skinnedMesh = static_cast<SkinnedMesh *>(Mesh);
if (JointMode == EJUOR_CONTROL) // write to mesh if (JointMode == EJUOR_CONTROL) // write to mesh
skinnedMesh->transferJointsToMesh(JointChildSceneNodes); skinnedMesh->transferJointsToMesh(JointChildSceneNodes);
else else
skinnedMesh->animateMesh(getFrameNr(), 1.0f); skinnedMesh->animateMesh(getFrameNr());
// Update the skinned mesh for the current joint transforms. // Update the skinned mesh for the current joint transforms.
skinnedMesh->skinMesh(); skinnedMesh->skinMesh();
@ -227,7 +223,7 @@ void CAnimatedMeshSceneNode::render()
Box = m->getBoundingBox(); Box = m->getBoundingBox();
} else { } else {
#ifdef _DEBUG #ifdef _DEBUG
os::Printer::log("Animated Mesh returned no mesh to render.", Mesh->getDebugName(), ELL_WARNING); os::Printer::log("Animated Mesh returned no mesh to render.", ELL_WARNING);
#endif #endif
return; return;
} }
@ -299,12 +295,10 @@ void CAnimatedMeshSceneNode::render()
if (Mesh->getMeshType() == EAMT_SKINNED) { if (Mesh->getMeshType() == EAMT_SKINNED) {
// draw skeleton // draw skeleton
for (u32 g = 0; g < ((ISkinnedMesh *)Mesh)->getAllJoints().size(); ++g) { for (auto *joint : ((SkinnedMesh *)Mesh)->getAllJoints()) {
ISkinnedMesh::SJoint *joint = ((ISkinnedMesh *)Mesh)->getAllJoints()[g]; for (const auto *childJoint : joint->Children) {
for (u32 n = 0; n < joint->Children.size(); ++n) {
driver->draw3DLine(joint->GlobalAnimatedMatrix.getTranslation(), driver->draw3DLine(joint->GlobalAnimatedMatrix.getTranslation(),
joint->Children[n]->GlobalAnimatedMatrix.getTranslation(), childJoint->GlobalAnimatedMatrix.getTranslation(),
video::SColor(255, 51, 66, 255)); video::SColor(255, 51, 66, 255));
} }
} }
@ -404,7 +398,7 @@ IBoneSceneNode *CAnimatedMeshSceneNode::getJointNode(const c8 *jointName)
checkJoints(); checkJoints();
ISkinnedMesh *skinnedMesh = (ISkinnedMesh *)Mesh; auto *skinnedMesh = (SkinnedMesh *)Mesh;
const std::optional<u32> number = skinnedMesh->getJointNumber(jointName); const std::optional<u32> number = skinnedMesh->getJointNumber(jointName);
@ -446,7 +440,7 @@ u32 CAnimatedMeshSceneNode::getJointCount() const
if (!Mesh || Mesh->getMeshType() != EAMT_SKINNED) if (!Mesh || Mesh->getMeshType() != EAMT_SKINNED)
return 0; return 0;
ISkinnedMesh *skinnedMesh = (ISkinnedMesh *)Mesh; auto *skinnedMesh = (SkinnedMesh *)Mesh;
return skinnedMesh->getJointCount(); return skinnedMesh->getJointCount();
} }
@ -596,10 +590,9 @@ void CAnimatedMeshSceneNode::animateJoints(bool CalculateAbsolutePositions)
checkJoints(); checkJoints();
const f32 frame = getFrameNr(); // old? const f32 frame = getFrameNr(); // old?
CSkinnedMesh *skinnedMesh = static_cast<CSkinnedMesh *>(Mesh); SkinnedMesh *skinnedMesh = static_cast<SkinnedMesh *>(Mesh);
skinnedMesh->transferOnlyJointsHintsToMesh(JointChildSceneNodes); skinnedMesh->animateMesh(frame);
skinnedMesh->animateMesh(frame, 1.0f);
skinnedMesh->recoverJointsFromMesh(JointChildSceneNodes); skinnedMesh->recoverJointsFromMesh(JointChildSceneNodes);
//----------------------------------------- //-----------------------------------------
@ -671,8 +664,8 @@ void CAnimatedMeshSceneNode::checkJoints()
JointChildSceneNodes.clear(); JointChildSceneNodes.clear();
// Create joints for SkinnedMesh // Create joints for SkinnedMesh
((CSkinnedMesh *)Mesh)->addJoints(JointChildSceneNodes, this, SceneManager); ((SkinnedMesh *)Mesh)->addJoints(JointChildSceneNodes, this, SceneManager);
((CSkinnedMesh *)Mesh)->recoverJointsFromMesh(JointChildSceneNodes); ((SkinnedMesh *)Mesh)->recoverJointsFromMesh(JointChildSceneNodes);
JointsUsed = true; JointsUsed = true;
JointMode = EJUOR_READ; JointMode = EJUOR_READ;

View File

@ -145,7 +145,7 @@ private:
void beginTransition(); void beginTransition();
core::array<video::SMaterial> Materials; core::array<video::SMaterial> Materials;
core::aabbox3d<f32> Box; core::aabbox3d<f32> Box{{0.0f, 0.0f, 0.0f}};
IAnimatedMesh *Mesh; IAnimatedMesh *Mesh;
f32 StartFrame; f32 StartFrame;
@ -169,7 +169,7 @@ private:
IAnimationEndCallBack *LoopCallBack; IAnimationEndCallBack *LoopCallBack;
s32 PassCount; s32 PassCount;
core::array<IBoneSceneNode *> JointChildSceneNodes; std::vector<IBoneSceneNode *> JointChildSceneNodes;
core::array<core::matrix4> PretransitingSave; core::array<core::matrix4> PretransitingSave;
}; };

View File

@ -12,12 +12,7 @@ namespace irr
namespace io namespace io
{ {
CAttributes::CAttributes() CAttributes::CAttributes() {}
{
#ifdef _DEBUG
setDebugName("CAttributes");
#endif
}
CAttributes::~CAttributes() CAttributes::~CAttributes()
{ {

View File

@ -10,6 +10,7 @@
#include "IVideoDriver.h" #include "IVideoDriver.h"
#include "IFileSystem.h" #include "IFileSystem.h"
#include "SkinnedMesh.h"
#include "coreutil.h" #include "coreutil.h"
#include "os.h" #include "os.h"
@ -28,11 +29,7 @@ namespace scene
CB3DMeshFileLoader::CB3DMeshFileLoader(scene::ISceneManager *smgr) : CB3DMeshFileLoader::CB3DMeshFileLoader(scene::ISceneManager *smgr) :
AnimatedMesh(0), B3DFile(0), VerticesStart(0), NormalsInFile(false), AnimatedMesh(0), B3DFile(0), VerticesStart(0), NormalsInFile(false),
HasVertexColors(false), ShowWarning(true) HasVertexColors(false), ShowWarning(true)
{ {}
#ifdef _DEBUG
setDebugName("CB3DMeshFileLoader");
#endif
}
//! returns true if the file maybe is able to be loaded by this class //! returns true if the file maybe is able to be loaded by this class
//! based on the file extension (e.g. ".bsp") //! based on the file extension (e.g. ".bsp")
@ -51,12 +48,12 @@ IAnimatedMesh *CB3DMeshFileLoader::createMesh(io::IReadFile *file)
return 0; return 0;
B3DFile = file; B3DFile = file;
AnimatedMesh = new scene::CSkinnedMesh(); AnimatedMesh = new scene::SkinnedMeshBuilder();
ShowWarning = true; // If true a warning is issued if too many textures are used ShowWarning = true; // If true a warning is issued if too many textures are used
VerticesStart = 0; VerticesStart = 0;
if (load()) { if (load()) {
AnimatedMesh->finalize(); return AnimatedMesh->finalize();
} else { } else {
AnimatedMesh->drop(); AnimatedMesh->drop();
AnimatedMesh = 0; AnimatedMesh = 0;
@ -111,7 +108,7 @@ bool CB3DMeshFileLoader::load()
if (!readChunkBRUS()) if (!readChunkBRUS())
return false; return false;
} else if (strncmp(B3dStack.getLast().name, "NODE", 4) == 0) { } else if (strncmp(B3dStack.getLast().name, "NODE", 4) == 0) {
if (!readChunkNODE((CSkinnedMesh::SJoint *)0)) if (!readChunkNODE((SkinnedMesh::SJoint *)0))
return false; return false;
} else { } else {
os::Printer::log("Unknown chunk found in mesh base - skipping"); os::Printer::log("Unknown chunk found in mesh base - skipping");
@ -133,9 +130,9 @@ bool CB3DMeshFileLoader::load()
return true; return true;
} }
bool CB3DMeshFileLoader::readChunkNODE(CSkinnedMesh::SJoint *inJoint) bool CB3DMeshFileLoader::readChunkNODE(SkinnedMesh::SJoint *inJoint)
{ {
CSkinnedMesh::SJoint *joint = AnimatedMesh->addJoint(inJoint); SkinnedMesh::SJoint *joint = AnimatedMesh->addJoint(inJoint);
joint->Name = readString(); joint->Name = readString();
#ifdef _B3D_READER_DEBUG #ifdef _B3D_READER_DEBUG
@ -211,7 +208,7 @@ bool CB3DMeshFileLoader::readChunkNODE(CSkinnedMesh::SJoint *inJoint)
return true; return true;
} }
bool CB3DMeshFileLoader::readChunkMESH(CSkinnedMesh::SJoint *inJoint) bool CB3DMeshFileLoader::readChunkMESH(SkinnedMesh::SJoint *inJoint)
{ {
#ifdef _B3D_READER_DEBUG #ifdef _B3D_READER_DEBUG
core::stringc logStr; core::stringc logStr;
@ -254,7 +251,7 @@ bool CB3DMeshFileLoader::readChunkMESH(CSkinnedMesh::SJoint *inJoint)
meshBuffer->Material = Materials[brushID].Material; meshBuffer->Material = Materials[brushID].Material;
} }
if (readChunkTRIS(meshBuffer, AnimatedMesh->getMeshBuffers().size() - 1, VerticesStart) == false) if (readChunkTRIS(meshBuffer, AnimatedMesh->getMeshBufferCount() - 1, VerticesStart) == false)
return false; return false;
if (!NormalsInFile) { if (!NormalsInFile) {
@ -302,7 +299,7 @@ VRTS:
float tex_coords[tex_coord_sets][tex_coord_set_size] ;tex coords float tex_coords[tex_coord_sets][tex_coord_set_size] ;tex coords
} }
*/ */
bool CB3DMeshFileLoader::readChunkVRTS(CSkinnedMesh::SJoint *inJoint) bool CB3DMeshFileLoader::readChunkVRTS(SkinnedMesh::SJoint *inJoint)
{ {
#ifdef _B3D_READER_DEBUG #ifdef _B3D_READER_DEBUG
core::stringc logStr; core::stringc logStr;
@ -521,7 +518,7 @@ bool CB3DMeshFileLoader::readChunkTRIS(scene::SSkinMeshBuffer *meshBuffer, u32 m
return true; return true;
} }
bool CB3DMeshFileLoader::readChunkBONE(CSkinnedMesh::SJoint *inJoint) bool CB3DMeshFileLoader::readChunkBONE(SkinnedMesh::SJoint *inJoint)
{ {
#ifdef _B3D_READER_DEBUG #ifdef _B3D_READER_DEBUG
core::stringc logStr; core::stringc logStr;
@ -552,7 +549,7 @@ bool CB3DMeshFileLoader::readChunkBONE(CSkinnedMesh::SJoint *inJoint)
if (AnimatedVertices_VertexID[globalVertexID] == -1) { if (AnimatedVertices_VertexID[globalVertexID] == -1) {
os::Printer::log("B3dMeshLoader: Weight has bad vertex id (no link to meshbuffer index found)"); os::Printer::log("B3dMeshLoader: Weight has bad vertex id (no link to meshbuffer index found)");
} else if (strength > 0) { } else if (strength > 0) {
CSkinnedMesh::SWeight *weight = AnimatedMesh->addWeight(inJoint); SkinnedMesh::SWeight *weight = AnimatedMesh->addWeight(inJoint);
weight->strength = strength; weight->strength = strength;
// Find the meshbuffer and Vertex index from the Global Vertex ID: // Find the meshbuffer and Vertex index from the Global Vertex ID:
weight->vertex_id = AnimatedVertices_VertexID[globalVertexID]; weight->vertex_id = AnimatedVertices_VertexID[globalVertexID];
@ -565,11 +562,11 @@ bool CB3DMeshFileLoader::readChunkBONE(CSkinnedMesh::SJoint *inJoint)
return true; return true;
} }
bool CB3DMeshFileLoader::readChunkKEYS(CSkinnedMesh::SJoint *inJoint) bool CB3DMeshFileLoader::readChunkKEYS(SkinnedMesh::SJoint *inJoint)
{ {
#ifdef _B3D_READER_DEBUG #ifdef _B3D_READER_DEBUG
// Only print first, that's just too much output otherwise // Only print first, that's just too much output otherwise
if (!inJoint || (inJoint->PositionKeys.empty() && inJoint->ScaleKeys.empty() && inJoint->RotationKeys.empty())) { if (!inJoint || inJoint->keys.empty()) {
core::stringc logStr; core::stringc logStr;
for (u32 i = 1; i < B3dStack.size(); ++i) for (u32 i = 1; i < B3dStack.size(); ++i)
logStr += "-"; logStr += "-";
@ -584,13 +581,6 @@ bool CB3DMeshFileLoader::readChunkKEYS(CSkinnedMesh::SJoint *inJoint)
flags = os::Byteswap::byteswap(flags); flags = os::Byteswap::byteswap(flags);
#endif #endif
CSkinnedMesh::SPositionKey *oldPosKey = 0;
core::vector3df oldPos[2];
CSkinnedMesh::SScaleKey *oldScaleKey = 0;
core::vector3df oldScale[2];
CSkinnedMesh::SRotationKey *oldRotKey = 0;
core::quaternion oldRot[2];
bool isFirst[3] = {true, true, true};
while ((B3dStack.getLast().startposition + B3dStack.getLast().length) > B3DFile->getPos()) // this chunk repeats while ((B3dStack.getLast().startposition + B3dStack.getLast().length) > B3DFile->getPos()) // this chunk repeats
{ {
s32 frame; s32 frame;
@ -600,91 +590,24 @@ bool CB3DMeshFileLoader::readChunkKEYS(CSkinnedMesh::SJoint *inJoint)
frame = os::Byteswap::byteswap(frame); frame = os::Byteswap::byteswap(frame);
#endif #endif
if (frame < 1) {
os::Printer::log("Illegal frame number found", B3DFile->getFileName(), ELL_ERROR);
frame = 1;
}
// Add key frames, frames in Irrlicht are zero-based // Add key frames, frames in Irrlicht are zero-based
f32 data[4]; f32 data[4];
if (flags & 1) { if (flags & 1) {
readFloats(data, 3); readFloats(data, 3);
if ((oldPosKey != 0) && (oldPos[0] == oldPos[1])) { AnimatedMesh->addPositionKey(inJoint, frame - 1, {data[0], data[1], data[2]});
const core::vector3df pos(data[0], data[1], data[2]);
if (oldPos[1] == pos)
oldPosKey->frame = (f32)frame - 1;
else {
oldPos[0] = oldPos[1];
oldPosKey = AnimatedMesh->addPositionKey(inJoint);
oldPosKey->frame = (f32)frame - 1;
oldPos[1].set(oldPosKey->position.set(pos));
}
} else if (oldPosKey == 0 && isFirst[0]) {
oldPosKey = AnimatedMesh->addPositionKey(inJoint);
oldPosKey->frame = (f32)frame - 1;
oldPos[0].set(oldPosKey->position.set(data[0], data[1], data[2]));
oldPosKey = 0;
isFirst[0] = false;
} else {
if (oldPosKey != 0)
oldPos[0] = oldPos[1];
oldPosKey = AnimatedMesh->addPositionKey(inJoint);
oldPosKey->frame = (f32)frame - 1;
oldPos[1].set(oldPosKey->position.set(data[0], data[1], data[2]));
}
} }
if (flags & 2) { if (flags & 2) {
readFloats(data, 3); readFloats(data, 3);
if ((oldScaleKey != 0) && (oldScale[0] == oldScale[1])) { AnimatedMesh->addScaleKey(inJoint, frame - 1, {data[0], data[1], data[2]});
const core::vector3df scale(data[0], data[1], data[2]);
if (oldScale[1] == scale)
oldScaleKey->frame = (f32)frame - 1;
else {
oldScale[0] = oldScale[1];
oldScaleKey = AnimatedMesh->addScaleKey(inJoint);
oldScaleKey->frame = (f32)frame - 1;
oldScale[1].set(oldScaleKey->scale.set(scale));
}
} else if (oldScaleKey == 0 && isFirst[1]) {
oldScaleKey = AnimatedMesh->addScaleKey(inJoint);
oldScaleKey->frame = (f32)frame - 1;
oldScale[0].set(oldScaleKey->scale.set(data[0], data[1], data[2]));
oldScaleKey = 0;
isFirst[1] = false;
} else {
if (oldScaleKey != 0)
oldScale[0] = oldScale[1];
oldScaleKey = AnimatedMesh->addScaleKey(inJoint);
oldScaleKey->frame = (f32)frame - 1;
oldScale[1].set(oldScaleKey->scale.set(data[0], data[1], data[2]));
}
} }
if (flags & 4) { if (flags & 4) {
readFloats(data, 4); readFloats(data, 4);
if ((oldRotKey != 0) && (oldRot[0] == oldRot[1])) { AnimatedMesh->addRotationKey(inJoint, frame - 1, core::quaternion(data[1], data[2], data[3], data[0]));
// meant to be in this order since b3d stores W first
const core::quaternion rot(data[1], data[2], data[3], data[0]);
if (oldRot[1] == rot)
oldRotKey->frame = (f32)frame - 1;
else {
oldRot[0] = oldRot[1];
oldRotKey = AnimatedMesh->addRotationKey(inJoint);
oldRotKey->frame = (f32)frame - 1;
oldRot[1].set(oldRotKey->rotation.set(data[1], data[2], data[3], data[0]));
oldRot[1].normalize();
}
} else if (oldRotKey == 0 && isFirst[2]) {
oldRotKey = AnimatedMesh->addRotationKey(inJoint);
oldRotKey->frame = (f32)frame - 1;
// meant to be in this order since b3d stores W first
oldRot[0].set(oldRotKey->rotation.set(data[1], data[2], data[3], data[0]));
oldRot[0].normalize();
oldRotKey = 0;
isFirst[2] = false;
} else {
if (oldRotKey != 0)
oldRot[0] = oldRot[1];
oldRotKey = AnimatedMesh->addRotationKey(inJoint);
oldRotKey->frame = (f32)frame - 1;
// meant to be in this order since b3d stores W first
oldRot[1].set(oldRotKey->rotation.set(data[1], data[2], data[3], data[0]));
oldRot[1].normalize();
}
} }
} }

View File

@ -10,7 +10,7 @@
#include "IMeshLoader.h" #include "IMeshLoader.h"
#include "ISceneManager.h" #include "ISceneManager.h"
#include "CSkinnedMesh.h" #include "SkinnedMesh.h"
#include "SB3DStructs.h" #include "SB3DStructs.h"
#include "IReadFile.h" #include "IReadFile.h"
@ -39,12 +39,12 @@ public:
private: private:
bool load(); bool load();
bool readChunkNODE(CSkinnedMesh::SJoint *InJoint); bool readChunkNODE(SkinnedMesh::SJoint *InJoint);
bool readChunkMESH(CSkinnedMesh::SJoint *InJoint); bool readChunkMESH(SkinnedMesh::SJoint *InJoint);
bool readChunkVRTS(CSkinnedMesh::SJoint *InJoint); bool readChunkVRTS(SkinnedMesh::SJoint *InJoint);
bool readChunkTRIS(scene::SSkinMeshBuffer *MeshBuffer, u32 MeshBufferID, s32 Vertices_Start); bool readChunkTRIS(scene::SSkinMeshBuffer *MeshBuffer, u32 MeshBufferID, s32 Vertices_Start);
bool readChunkBONE(CSkinnedMesh::SJoint *InJoint); bool readChunkBONE(SkinnedMesh::SJoint *InJoint);
bool readChunkKEYS(CSkinnedMesh::SJoint *InJoint); bool readChunkKEYS(SkinnedMesh::SJoint *InJoint);
bool readChunkANIM(); bool readChunkANIM();
bool readChunkTEXS(); bool readChunkTEXS();
bool readChunkBRUS(); bool readChunkBRUS();
@ -63,7 +63,7 @@ private:
core::array<video::S3DVertex2TCoords> BaseVertices; core::array<video::S3DVertex2TCoords> BaseVertices;
CSkinnedMesh *AnimatedMesh; SkinnedMeshBuilder *AnimatedMesh;
io::IReadFile *B3DFile; io::IReadFile *B3DFile;
// B3Ds have Vertex ID's local within the mesh I don't want this // B3Ds have Vertex ID's local within the mesh I don't want this

View File

@ -20,10 +20,6 @@ CBillboardSceneNode::CBillboardSceneNode(ISceneNode *parent, ISceneManager *mgr,
IBillboardSceneNode(parent, mgr, id, position), IBillboardSceneNode(parent, mgr, id, position),
Buffer(new SMeshBuffer()) Buffer(new SMeshBuffer())
{ {
#ifdef _DEBUG
setDebugName("CBillboardSceneNode");
#endif
setSize(size); setSize(size);
auto &Vertices = Buffer->Vertices->Data; auto &Vertices = Buffer->Vertices->Data;

View File

@ -104,7 +104,7 @@ private:
/** Note that we can't use the real boundingbox for culling because at that point /** Note that we can't use the real boundingbox for culling because at that point
the camera which is used to calculate the billboard is not yet updated. So we only the camera which is used to calculate the billboard is not yet updated. So we only
know the real boundingbox after rendering - which is too late for culling. */ know the real boundingbox after rendering - which is too late for culling. */
core::aabbox3d<f32> BBoxSafe; core::aabbox3d<f32> BBoxSafe{{0.0f, 0.0f, 0.0f}};
scene::SMeshBuffer *Buffer; scene::SMeshBuffer *Buffer;
}; };

View File

@ -18,9 +18,6 @@ CBoneSceneNode::CBoneSceneNode(ISceneNode *parent, ISceneManager *mgr, s32 id,
BoneIndex(boneIndex), BoneIndex(boneIndex),
AnimationMode(EBAM_AUTOMATIC), SkinningSpace(EBSS_LOCAL) AnimationMode(EBAM_AUTOMATIC), SkinningSpace(EBSS_LOCAL)
{ {
#ifdef _DEBUG
setDebugName("CBoneSceneNode");
#endif
setName(boneName); setName(boneName);
} }

View File

@ -60,7 +60,7 @@ private:
u32 BoneIndex; u32 BoneIndex;
core::aabbox3d<f32> Box; core::aabbox3d<f32> Box{-1.0f, -1.0f, -1.0f, 1.0f, 1.0f, 1.0f};
E_BONE_ANIMATION_MODE AnimationMode; E_BONE_ANIMATION_MODE AnimationMode;
E_BONE_SKINNING_SPACE SkinningSpace; E_BONE_SKINNING_SPACE SkinningSpace;

View File

@ -20,10 +20,6 @@ CCameraSceneNode::CCameraSceneNode(ISceneNode *parent, ISceneManager *mgr, s32 i
Target(lookat), UpVector(0.0f, 1.0f, 0.0f), ZNear(1.0f), ZFar(3000.0f), Target(lookat), UpVector(0.0f, 1.0f, 0.0f), ZNear(1.0f), ZFar(3000.0f),
InputReceiverEnabled(true), TargetAndRotationAreBound(false) InputReceiverEnabled(true), TargetAndRotationAreBound(false)
{ {
#ifdef _DEBUG
setDebugName("CCameraSceneNode");
#endif
// set default projection // set default projection
Fovy = core::PI / 2.5f; // Field of view, in radians. Fovy = core::PI / 2.5f; // Field of view, in radians.
Aspect = 4.0f / 3.0f; // Aspect ratio. Aspect = 4.0f / 3.0f; // Aspect ratio.

View File

@ -7,98 +7,20 @@
#include "os.h" #include "os.h"
#include "irrString.h" #include "irrString.h"
// Warning: The naming of Irrlicht color formats
// is not consistent regarding actual component order in memory.
// E.g. in CImage, ECF_R8G8B8 is handled per-byte and stored as [R][G][B] in memory
// while ECF_A8R8G8B8 is handled as an u32 0xAARRGGBB so [B][G][R][A] (little endian) in memory.
// The conversions suffer from the same inconsistencies, e.g.
// convert_R8G8B8toA8R8G8B8 converts [R][G][B] into 0xFFRRGGBB = [B][G][R][FF] (little endian);
// convert_A1R5G5B5toR8G8B8 converts 0bARRRRRGGGGGBBBBB into [R][G][B].
// This also means many conversions may be broken on big endian.
namespace irr namespace irr
{ {
namespace video namespace video
{ {
//! converts a monochrome bitmap to A1R5G5B5 data
void CColorConverter::convert1BitTo16Bit(const u8 *in, s16 *out, s32 width, s32 height, s32 linepad, bool flip)
{
if (!in || !out)
return;
if (flip)
out += width * height;
for (s32 y = 0; y < height; ++y) {
s32 shift = 7;
if (flip)
out -= width;
for (s32 x = 0; x < width; ++x) {
out[x] = *in >> shift & 0x01 ? (s16)0xffff : (s16)0x8000;
if ((--shift) < 0) { // 8 pixel done
shift = 7;
++in;
}
}
if (shift != 7) // width did not fill last byte
++in;
if (!flip)
out += width;
in += linepad;
}
}
//! converts a 4 bit palettized image to A1R5G5B5
void CColorConverter::convert4BitTo16Bit(const u8 *in, s16 *out, s32 width, s32 height, const s32 *palette, s32 linepad, bool flip)
{
if (!in || !out || !palette)
return;
if (flip)
out += width * height;
for (s32 y = 0; y < height; ++y) {
s32 shift = 4;
if (flip)
out -= width;
for (s32 x = 0; x < width; ++x) {
out[x] = X8R8G8B8toA1R5G5B5(palette[(u8)((*in >> shift) & 0xf)]);
if (shift == 0) {
shift = 4;
++in;
} else
shift = 0;
}
if (shift == 0) // odd width
++in;
if (!flip)
out += width;
in += linepad;
}
}
//! converts a 8 bit palettized image into A1R5G5B5
void CColorConverter::convert8BitTo16Bit(const u8 *in, s16 *out, s32 width, s32 height, const s32 *palette, s32 linepad, bool flip)
{
if (!in || !out || !palette)
return;
if (flip)
out += width * height;
for (s32 y = 0; y < height; ++y) {
if (flip)
out -= width; // one line back
for (s32 x = 0; x < width; ++x) {
out[x] = X8R8G8B8toA1R5G5B5(palette[(u8)(*in)]);
++in;
}
if (!flip)
out += width;
in += linepad;
}
}
//! converts a 8 bit palettized or non palettized image (A8) into R8G8B8 //! converts a 8 bit palettized or non palettized image (A8) into R8G8B8
void CColorConverter::convert8BitTo24Bit(const u8 *in, u8 *out, s32 width, s32 height, const u8 *palette, s32 linepad, bool flip) void CColorConverter::convert8BitTo24Bit(const u8 *in, u8 *out, s32 width, s32 height, const u8 *palette, s32 linepad, bool flip)
{ {
@ -480,19 +402,6 @@ void CColorConverter::convert_R8G8B8toA1R5G5B5(const void *sP, s32 sN, void *dP)
} }
} }
void CColorConverter::convert_B8G8R8toA8R8G8B8(const void *sP, s32 sN, void *dP)
{
u8 *sB = (u8 *)sP;
u32 *dB = (u32 *)dP;
for (s32 x = 0; x < sN; ++x) {
*dB = 0xff000000 | (sB[2] << 16) | (sB[1] << 8) | sB[0];
sB += 3;
++dB;
}
}
void CColorConverter::convert_A8R8G8B8toR8G8B8A8(const void *sP, s32 sN, void *dP) void CColorConverter::convert_A8R8G8B8toR8G8B8A8(const void *sP, s32 sN, void *dP)
{ {
const u32 *sB = (const u32 *)sP; const u32 *sB = (const u32 *)sP;
@ -515,22 +424,6 @@ void CColorConverter::convert_A8R8G8B8toA8B8G8R8(const void *sP, s32 sN, void *d
} }
} }
void CColorConverter::convert_B8G8R8A8toA8R8G8B8(const void *sP, s32 sN, void *dP)
{
u8 *sB = (u8 *)sP;
u8 *dB = (u8 *)dP;
for (s32 x = 0; x < sN; ++x) {
dB[0] = sB[3];
dB[1] = sB[2];
dB[2] = sB[1];
dB[3] = sB[0];
sB += 4;
dB += 4;
}
}
void CColorConverter::convert_R8G8B8toB8G8R8(const void *sP, s32 sN, void *dP) void CColorConverter::convert_R8G8B8toB8G8R8(const void *sP, s32 sN, void *dP)
{ {
u8 *sB = (u8 *)sP; u8 *sB = (u8 *)sP;

View File

@ -15,14 +15,6 @@ namespace video
class CColorConverter class CColorConverter
{ {
public: public:
//! converts a monochrome bitmap to A1R5G5B5
static void convert1BitTo16Bit(const u8 *in, s16 *out, s32 width, s32 height, s32 linepad = 0, bool flip = false);
//! converts a 4 bit palettized image to A1R5G5B5
static void convert4BitTo16Bit(const u8 *in, s16 *out, s32 width, s32 height, const s32 *palette, s32 linepad = 0, bool flip = false);
//! converts a 8 bit palettized image to A1R5G5B5
static void convert8BitTo16Bit(const u8 *in, s16 *out, s32 width, s32 height, const s32 *palette, s32 linepad = 0, bool flip = false);
//! converts a 8 bit palettized or non palettized image (A8) into R8G8B8 //! converts a 8 bit palettized or non palettized image (A8) into R8G8B8
static void convert8BitTo24Bit(const u8 *in, u8 *out, s32 width, s32 height, const u8 *palette, s32 linepad = 0, bool flip = false); static void convert8BitTo24Bit(const u8 *in, u8 *out, s32 width, s32 height, const u8 *palette, s32 linepad = 0, bool flip = false);
@ -74,8 +66,6 @@ public:
static void convert_R8G8B8toA1R5G5B5(const void *sP, s32 sN, void *dP); static void convert_R8G8B8toA1R5G5B5(const void *sP, s32 sN, void *dP);
static void convert_R8G8B8toB8G8R8(const void *sP, s32 sN, void *dP); static void convert_R8G8B8toB8G8R8(const void *sP, s32 sN, void *dP);
static void convert_R8G8B8toR5G6B5(const void *sP, s32 sN, void *dP); static void convert_R8G8B8toR5G6B5(const void *sP, s32 sN, void *dP);
static void convert_B8G8R8toA8R8G8B8(const void *sP, s32 sN, void *dP);
static void convert_B8G8R8A8toA8R8G8B8(const void *sP, s32 sN, void *dP);
static void convert_A8R8G8B8toR8G8B8A8(const void *sP, s32 sN, void *dP); static void convert_A8R8G8B8toR8G8B8A8(const void *sP, s32 sN, void *dP);
static void convert_A8R8G8B8toA8B8G8R8(const void *sP, s32 sN, void *dP); static void convert_A8R8G8B8toA8B8G8R8(const void *sP, s32 sN, void *dP);

View File

@ -15,10 +15,6 @@ CDummyTransformationSceneNode::CDummyTransformationSceneNode(
ISceneNode *parent, ISceneManager *mgr, s32 id) : ISceneNode *parent, ISceneManager *mgr, s32 id) :
IDummyTransformationSceneNode(parent, mgr, id) IDummyTransformationSceneNode(parent, mgr, id)
{ {
#ifdef _DEBUG
setDebugName("CDummyTransformationSceneNode");
#endif
setAutomaticCulling(scene::EAC_OFF); setAutomaticCulling(scene::EAC_OFF);
} }

View File

@ -48,7 +48,7 @@ private:
void setPosition(const core::vector3df &newpos) override; void setPosition(const core::vector3df &newpos) override;
core::matrix4 RelativeTransformationMatrix; core::matrix4 RelativeTransformationMatrix;
core::aabbox3d<f32> Box; core::aabbox3d<f32> Box{{0, 0, 0}};
}; };
} // end namespace scene } // end namespace scene

View File

@ -18,11 +18,7 @@ namespace video
CEGLManager::CEGLManager() : CEGLManager::CEGLManager() :
IContextManager(), EglWindow(0), EglDisplay(EGL_NO_DISPLAY), IContextManager(), EglWindow(0), EglDisplay(EGL_NO_DISPLAY),
EglSurface(EGL_NO_SURFACE), EglContext(EGL_NO_CONTEXT), EglConfig(0), MajorVersion(0), MinorVersion(0) EglSurface(EGL_NO_SURFACE), EglContext(EGL_NO_CONTEXT), EglConfig(0), MajorVersion(0), MinorVersion(0)
{ {}
#ifdef _DEBUG
setDebugName("CEGLManager");
#endif
}
CEGLManager::~CEGLManager() CEGLManager::~CEGLManager()
{ {

Some files were not shown because too many files have changed in this diff Show More