Merge remote-tracking branch 'origin/master' into renderer_refactoring

This commit is contained in:
Benau 2016-10-28 21:41:49 +08:00
commit 2f0252be98
295 changed files with 9828 additions and 6612 deletions

View File

@ -1 +0,0 @@
See the file data/CREDITS .

View File

@ -1,82 +0,0 @@
# SuperTuxKart Installation Instructions
Note: If you obtained this source code from Github, you also need to download
the game assets from Sourceforge using SVN.
`svn checkout https://svn.code.sf.net/p/supertuxkart/code/stk-assets stk-assets`
Place the `stk-assets` folder next to the source root `stk-code` folder.
See <https://supertuxkart.net/Source_control> for more information
## Building STK on Linux
First, make sure that you have the following packages installed:
* OpenGL (mesa)
* OpenAL (recommended: openal-soft-devel)
* Ogg (libogg-dev)
* Vorbis (libvorbis-dev)
* Freetype (libfreetype6-dev)
* libcurl (libcurl-devel)
* libbluetooth (bluez-devel)
* libpng (libpng-devel)
* zlib (zlib-devel)
* jpeg (libjpeg-turbo-devel)
Ubuntu command:
```
sudo apt-get install build-essential cmake libbluetooth-dev \
libcurl4-gnutls-dev libfreetype6-dev libfribidi-dev libgl1-mesa-dev \
libjpeg-dev libogg-dev libopenal-dev libpng-dev libvorbis-dev libxrandr-dev \
mesa-common-dev pkg-config zlib1g-dev
```
Unpack the files from the tarball like this:
```
tar xzf supertuxkart-*.tar.gz
cd supertuxkart-*
```
where `*` is the version of SuperTuxkart you downloaded - eg `0.8.0`. Then:
Compile SuperTuxKart:
```
mkdir cmake_build
cd cmake_build
cmake ..
make VERBOSE=1 -j2
```
To create a debug version of STK, use:
```
cmake .. -DCMAKE_BUILD_TYPE=Debug
```
To test the compilation, supertuxkart can be run from the build
directory by ./bin/supertuxkart
To install the file, as root execute:
```
make install
```
The default install location is `/usr/local`, i.e. the data files will
be written to `/usr/local/share/games/supertuxkart`, the executable
will be copied to `/usr/local/bin`. To change the default installation
location, specify `CMAKE_INSTALL_PREFIX` when running cmake, e.g.:
`cmake .. -DCMAKE_INSTALL_PREFIX=/opt/stk`
## Building STK on OS X
See <https://supertuxkart.net/Building_and_packaging_on_OSX>
## Building STK on Windows
See <https://supertuxkart.net/How_to_build_the_Windows_version>

184
README.md
View File

@ -3,13 +3,7 @@
SuperTuxKart is a free kart racing game. It focuses on fun and not on realistic kart physics. Instructions can be found on the in-game help page.
The SuperTuxKart homepage can be found at: <https://supertuxkart.net/>
The official SuperTuxKart forum is at <http://forum.freegamedev.net/viewforum.php?f=16>. If you need support, this would be the best place to start.
Hope you enjoy the game.
-- The SuperTuxKart development team.
The SuperTuxKart homepage can be found at <https://supertuxkart.net/>. There is also our [FAQ](https://supertuxkart.net/FAQ) and information on how get in touch with the [community](https://supertuxkart.net/Community)
## Hardware Requirements
* You need a 3D graphics card. (NVIDIA GeForce 8xxx and higher, ATI Radeon HD 4xxx and higher or Intel HD 3000 and higher.)
@ -18,28 +12,6 @@ Hope you enjoy the game.
* Disk space: 400MB
* Ideally, you want a joystick with at least 6 buttons.
## Compiling SuperTuxKart
### Windows
1. Install VS 2013 (or later). The free express versions work fine.
2. Download and install a source package - either a released package or from our [git/svn repositories](https://supertuxkart.net/Source_control).
3. Download the latest dependency package from [here](https://sourceforge.net/projects/supertuxkart/files/SuperTuxKart%20Dependencies/Windows/). Unzip it in the root directory, so that the dependencies directory is next to the src and data directories (if you are updating from a previous dependency package, you can delete the .dll files in the root directory, they are not needed anymore).
4. Download cmake and install it. Then start cmake-gui and select the STK root directory as 'Where is the source code', and a new directory in the root directory (next to src, data etc) as the build directory (for now I assume that this directory is called bld).
5. Click on configure. You will be asked to create the directory (yes), then for your VS version. Make sure you select the right version (be aware of the easy to confuse version numbers: VS 2013 = version 12). Click on configure, then generate. This will create the directory 'bld', and a VS solution in that directory.
6. In Visual Studio open the project file generated in the 'bld' folder.
7. Right click on the supertuxkart project in the solution explorer, and select "Set as StartUp Project".
8. Select Build->Build Solution (or press F7) to compile.
See <https://supertuxkart.net/How_to_build_the_Windows_version> for more information.
Compilation with cygwin is not officially supported, but this has been done (check with the forum for details).
### Mac OS X
The latest information about compilation on Mac are at our site: <https://supertuxkart.net/Building_and_packaging_on_OSX>
### UNIX
See [`INSTALL.md`](INSTALL.md) for details.
## License
This software is released under the GNU General Public License (GPL) which can be found in the file [`COPYING`](/COPYING) in the same directory as this file. Information about the licenses for artwork are contained in `data/licenses`.
@ -51,3 +23,157 @@ STK : X right, Y up, Z forwards
Blender: X right, Y forwards, Z up
The exporters perform the needed transform, so in Blender you just work with XY plane as ground, and things will appear fine in STK (using XZ as ground in the code, obviously).
## Building from source
First, you need both the code and the assets (See <https://supertuxkart.net/Source_control> for more information):
```
git clone https://github.com/supertuxkart/stk-code
svn checkout https://svn.code.sf.net/p/supertuxkart/code/stk-assets stk-assets
```
## Building on Linux
### Dependencies
Install the following packages:
* OpenGL (mesa)
* OpenAL (recommended: openal-soft-devel)
* Ogg (libogg-dev)
* Vorbis (libvorbis-dev)
* Freetype (libfreetype6-dev)
* libcurl (libcurl-devel)
* libbluetooth (bluez-devel)
* libpng (libpng-devel)
* zlib (zlib-devel)
* jpeg (libjpeg-turbo-devel)
Ubuntu command:
```
sudo apt-get install build-essential cmake libbluetooth-dev \
libcurl4-gnutls-dev libfreetype6-dev libfribidi-dev libgl1-mesa-dev \
libjpeg-dev libogg-dev libopenal-dev libpng-dev libvorbis-dev libxrandr-dev \
mesa-common-dev pkg-config zlib1g-dev
```
### Compiling
Compile SuperTuxKart:
```
mkdir cmake_build
cd cmake_build
cmake ..
make -j4
```
STK can then be run from the build directory with `bin/supertuxkart`
### Further options
To create a debug version of STK, use:
```
cmake .. -DCMAKE_BUILD_TYPE=Debug
```
You can install your build system-wide:
```
sudo make install
```
The default install location is `/usr/local`, i.e. the data files will
be written to `/usr/local/share/games/supertuxkart`, the executable
will be copied to `/usr/local/bin`. To change the default installation
location, specify `CMAKE_INSTALL_PREFIX` when running cmake, e.g.:
`cmake .. -DCMAKE_INSTALL_PREFIX=/opt/stk`
## Windows
1. Install VS 2013 (or later). The free express versions work fine.
2. Download and install a source package - either a released package or from our [git/svn repositories](https://supertuxkart.net/Source_control).
3. Download the latest dependency package from [here](https://sourceforge.net/projects/supertuxkart/files/SuperTuxKart%20Dependencies/Windows/). Unzip it in the root directory, so that the dependencies directory is next to the src and data directories (if you are updating from a previous dependency package, you can delete the .dll files in the root directory, they are not needed anymore).
4. Download cmake and install it. Then start cmake-gui and select the STK root directory as 'Where is the source code', and a new directory in the root directory (next to src, data etc) as the build directory (for now I assume that this directory is called bld).
5. Click on configure. You will be asked to create the directory (yes), then for your VS version. Make sure you select the right version (be aware of the easy to confuse version numbers: VS 2013 = version 12). Click on configure, then generate. This will create the directory 'bld', and a VS solution in that directory.
6. In Visual Studio open the project file generated in the 'bld' folder.
7. Right click on the supertuxkart project in the solution explorer, and select "Set as StartUp Project".
8. Select Build->Build Solution (or press F7) to compile.
## OS X
### Getting Started
Install developer tools, either from the OS X Install DVD or from Apple's website.
If you have never built anything before, you have create `/usr/local/include/` first:
```bash
sudo mkdir -p /usr/local/include/
```
Symlink the `include`-folder of OpenGL framework to `/usr/local/include/GL` (Unix programs have an easier time finding it this way):
```bash
sudo ln -s /System/Library/Frameworks/OpenGL.framework/Versions/A/Headers/ /usr/local/include/GL
```
On OS X 10.9.5, you might need the following workaround:
```bash
sudo ln -s `xcrun --show-sdk-path`/usr/include/ /usr/include
sudo ln -s `xcrun --show-sdk-path`/System/Library/Frameworks/OpenGL.framework/Headers/ /usr/local/include/OpenGL
```
The first link is required in order to find libcurl, the second to find opengl.
Download pre-built dependencies from [here](https://sourceforge.net/projects/supertuxkart/files/SuperTuxKart%20Dependencies/OSX/) and put the frameworks in [hard disk root]/Library/Frameworks
### CMake
CMake is used to build STK. At this time CMake will not make a binary that is ready for distribution.
You'll have to run these commands inside your stk-code directory.
### Building
With clang:
```
mkdir cmake_build
cd cmake_build
cmake ..
make
```
With GCC :
```
mkdir cmake_build
cd cmake_build
cmake .. -DCMAKE_CXX_COMPILER=/usr/bin/g++ -DCMAKE_C_COMPILER=/usr/bin/gcc
make
```
Building on 10.10 with 10.9 compat
```
cmake .. -DCMAKE_OSX_SYSROOT=/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.9.sdk -DCMAKE_OSX_DEPLOYMENT_TARGET=10.9
```
### Xcode
Place an additional copy of the dependencies into `Users/<YOUR_USERNAME>/Library/Frameworks`.
Then cd to your cloned stk-code directory and execute the following commands:
```bash
mkdir xcode_build && cd xcode_build
cmake .. -GXcode
```
Use Finder to navigate to your stk-code/xcode_build folder and open the newly generated Xcode project (SuperTuxKart.xcodeproj).
You can then build the project in Xcode using Product -> Build
Note: Xcode is much less well tested than makefiles, so there may be issues when trying to use Xcode.

View File

@ -1,34 +0,0 @@
# Please, make sure your SVN client uses something that matches the
# following config. Specially the autoprops part, that way new files
# will be added with the right settings. Default config for command line
# svn is in ~/.subversion/config. If you use SVN for multiple projects
# simultaneously, remember you can use different configs, at least in
# cmd line (via --config-dir and for example ~/.subversion/supertuxkart/
# with a new config file inside).
[miscellany]
global-ignores = *.o *.lo *.la #*# .*.rej *.rej .*~ *~ .#* ._* .DS_Store *.blend1 *.blend2
enable-auto-props = yes
[auto-props]
*.c = svn:eol-style=native;svn:keywords=Author Date Id Revision
*.cpp = svn:eol-style=native;svn:keywords=Author Date Id Revision
*.h = svn:eol-style=native;svn:keywords=Author Date Id Revision
*.hpp = svn:eol-style=native;svn:keywords=Author Date Id Revision
*.dsp = svn:eol-style=CRLF
*.dsw = svn:eol-style=CRLF
*.sh = svn:eol-style=native;svn:executable;svn:keywords=Author Date Id Revision
*.txt = svn:eol-style=native
*.png = svn:mime-type=image/png
*.jpg = svn:mime-type=image/jpeg
Makefile = svn:eol-style=native;svn:keywords=Author Date Id Revision
*.jpeg = svn:mime-type=image/jpeg
*.gif = svn:mime-type=image/gif
*.svg = svn:mime-type=image/svg+xml
*.htm = svn:mime-type=text/html
*.html = svn:mime-type=text/html
*.css = svn:mime-type=text/css
*.pdf = svn:mime-type=application/pdf
SConstruct = svn:eol-style=native;svn:keywords=Author Date Id Revision
*.xml = svn:eol-style=LF;svn:mime-type=text/xml
*.py = svn:eol-style=native;svn:keywords=Author Date Id Revision

30
TODO.md
View File

@ -1,30 +0,0 @@
##TODO
SuperTuxKart is looking for additional man power to make this
one of the best free linux games out there :) We need (in
no particular order):
- Musicians/sound engineers
- Create additional background soundtracks
- Create sound effects
- Artists and track designer
- Create additional tracks
- Create additional artwork for tracks and background images
- Developers
- Work on network play support
- Check our bug and enhancement request tracker on
https://github.com/supertuxkart/stk-code/issues
- Extend the current web page and keep it up to date
- Testers
- For just about everything, especially different platforms and graphics cards
- Writers
- Write documentation, ranging from man page, to a description for the web, to a design document, etc...
If you want to help the SuperTuxKart Project, please contact us on the email list: [supertuxkart-devel@lists.sourceforge.net](mailto:supertuxkart-devel@lists.sourceforge.net)
Thanks in advance!
-- The SuperTuxKart Team
For details, see <http://supertuxkart.net/Community>

Binary file not shown.

View File

@ -3,6 +3,7 @@
<card is="Intel(R) HD Graphics 3000" os="windows" disable="UniformBufferObject"/>
<card is="Intel(R) HD Graphics 3000" os="windows" disable="AdvancedPipeline"/>
<card is="Intel(R) HD Graphics 3000" os="windows" disable="FramebufferSRGBWorking"/>
<card is="Intel(R) HD Graphics" os="windows" disable="ForceLegacyDevice"/>
<card contains="Intel" os="osx" disable="GI"/>
<card contains="Intel" os="linux" version="<11.2" disable="ComputeShader"/>
<card contains="Intel" os="linux" version="<11.2" disable="GeometryShader"/>
@ -27,5 +28,7 @@
<card contains="Radeon" os="linux" version="<14.300" disable="DriverRecentEnough"/>
<card contains="Radeon" os="windows" version="<14.300" disable="DriverRecentEnough"/>
<card contains="ATI" os="windows" version="<14.300" disable="DriverRecentEnough"/>
<card contains="ATI" os="windows" version="<=3.1.8787" disable="ForceLegacyDevice"/>
<card os="android" disable="TextureFormatBGRA8888"/>
<card os="android" disable="ColorBufferFloat"/>
</graphical-restrictions>

View File

@ -12,6 +12,8 @@ mode_tt, released under Creative-Commons BY-SA 3, incorporatings artwork from ye
mode_easter, mode_ftl, mode_soccer, mode_normal, race_giveup: by Totoplus62, released under CC-BY-SA 3.0
soccer balls released under CC-BY-SA 3.0 by Néd J. Édoire
tutorial.png by Totoplus62, released under CC-BY-SA 3.0
Logo and Logo_slim : under CC-BY-SA 3.0+ by 'rastapax'

View File

@ -33,5 +33,8 @@
<box proportion="1" width="98%" align="center" layout="vertical-row" padding="6">
<list id="list_addons" x="0" y="0" width="100%" height="100%"/>
</box>
<bright width="97%" id="tips_label" text="" align="center"/>
</div>
</stkgui>

BIN
data/gui/heart.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.5 KiB

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.8 KiB

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.6 KiB

After

Width:  |  Height:  |  Size: 16 KiB

View File

@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: supertuxkart\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2016-05-30 18:52-0400\n"
"POT-Creation-Date: 2016-08-23 20:00-0400\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
@ -437,7 +437,7 @@ msgstr ""
#. I18N: ./data/gui/user_screen_tab.stkgui
#. I18N: In the user screen
#: src/states_screens/dialogs/message_dialog.cpp:123
#: src/states_screens/dialogs/message_dialog.cpp:136
#: src/states_screens/dialogs/message_dialog.cpp:135
msgid "OK"
msgstr ""
@ -825,7 +825,7 @@ msgstr ""
#. I18N: ./data/gui/main_menu.stkgui
#. I18N: In the main screen
#: src/states_screens/race_gui_overworld.cpp:462
#: src/states_screens/race_gui_overworld.cpp:465
msgid "Tutorial"
msgstr ""
@ -996,7 +996,8 @@ msgstr ""
#. I18N: ./data/gui/online/guest_login.stkgui
#. I18N: ./data/gui/user_screen.stkgui
#: src/states_screens/main_menu_screen.cpp:79
#. I18N: Used as a verb, appears on the main menu (login button)
#: src/states_screens/main_menu_screen.cpp:80
msgid "Login"
msgstr ""
@ -1317,7 +1318,7 @@ msgstr ""
#. I18N: Section in the settings menu
#: src/states_screens/options_screen_device.cpp:86
#: src/states_screens/options_screen_input.cpp:140
#: src/states_screens/options_screen_ui.cpp:119
#: src/states_screens/options_screen_ui.cpp:122
#: src/states_screens/options_screen_video.cpp:172
#: src/states_screens/user_screen.cpp:660
msgid "Audio"
@ -1351,7 +1352,7 @@ msgstr ""
#. I18N: ./data/gui/options_input.stkgui
#. I18N: Section in the settings menu
#: src/states_screens/options_screen_audio.cpp:68
#: src/states_screens/options_screen_ui.cpp:121
#: src/states_screens/options_screen_ui.cpp:124
#: src/states_screens/options_screen_video.cpp:175
#: src/states_screens/user_screen.cpp:662
msgid "Controls"
@ -1393,7 +1394,7 @@ msgstr ""
#: src/states_screens/options_screen_audio.cpp:67
#: src/states_screens/options_screen_device.cpp:88
#: src/states_screens/options_screen_input.cpp:142
#: src/states_screens/options_screen_ui.cpp:120
#: src/states_screens/options_screen_ui.cpp:123
#: src/states_screens/options_screen_video.cpp:174
#: src/states_screens/server_selection.cpp:103
msgid "Players"
@ -1405,7 +1406,7 @@ msgstr ""
#. I18N: ./data/gui/options_players.stkgui
#. I18N: In the player configuration screen
msgid "Press enter or double-click on a player to edit him/her"
msgid "Press enter or double-click on a player to edit their settings"
msgstr ""
#. I18N: ./data/gui/options_players.stkgui
@ -1458,7 +1459,7 @@ msgstr ""
#: src/states_screens/options_screen_audio.cpp:65
#: src/states_screens/options_screen_device.cpp:85
#: src/states_screens/options_screen_input.cpp:139
#: src/states_screens/options_screen_ui.cpp:118
#: src/states_screens/options_screen_ui.cpp:121
#: src/states_screens/user_screen.cpp:659
msgid "Graphics"
msgstr ""
@ -1871,46 +1872,47 @@ msgstr ""
msgid "Completed achievement \"%s\"."
msgstr ""
#: src/addons/addons_manager.cpp:97 src/addons/news_manager.cpp:317
#: src/addons/addons_manager.cpp:104 src/addons/news_manager.cpp:325
msgid "Can't access stkaddons server..."
msgstr ""
#: src/addons/news_manager.cpp:174
#: src/addons/news_manager.cpp:182
#, c-format
msgid "Error downloading news: '%s'."
msgstr ""
#. I18N: number of laps to race in a challenge
#: src/challenges/challenge_data.cpp:259
#: src/challenges/challenge_data.cpp:266
#: src/states_screens/race_result_gui.cpp:1422
#, c-format
msgid "Laps : %i"
msgid "Laps: %i"
msgstr ""
#: src/challenges/challenge_data.cpp:265
#: src/challenges/challenge_data.cpp:272
msgid "Follow the leader"
msgstr ""
#: src/challenges/challenge_data.cpp:511
#: src/challenges/challenge_data.cpp:518
#, c-format
msgid "New track '%s' now available"
msgstr ""
#: src/challenges/challenge_data.cpp:516
#: src/challenges/challenge_data.cpp:523
#, c-format
msgid "New game mode '%s' now available"
msgstr ""
#: src/challenges/challenge_data.cpp:526
#: src/challenges/challenge_data.cpp:533
#, c-format
msgid "New Grand Prix '%s' now available"
msgstr ""
#: src/challenges/challenge_data.cpp:530
#: src/challenges/challenge_data.cpp:537
#, c-format
msgid "New difficulty '%s' now available"
msgstr ""
#: src/challenges/challenge_data.cpp:540
#: src/challenges/challenge_data.cpp:547
#, c-format
msgid "New kart '%s' now available"
msgstr ""
@ -1942,17 +1944,17 @@ msgid ""
"created."
msgstr ""
#: src/graphics/irr_driver.cpp:1896
#: src/graphics/irr_driver.cpp:1950
#, c-format
msgid "FPS: %d/%d/%d - PolyCount: %d Solid, %d Shadows - LightDist : %d"
msgstr ""
#: src/graphics/irr_driver.cpp:1907
#: src/graphics/irr_driver.cpp:1961
#, c-format
msgid "FPS: %d/%d/%d - %d KTris"
msgstr ""
#: src/guiengine/engine.cpp:1346
#: src/guiengine/engine.cpp:1289
msgid "Loading"
msgstr ""
@ -2467,11 +2469,11 @@ msgid "Mouse axis %d %s"
msgstr ""
#. I18N: shown when config file is too old
#: src/input/device_manager.cpp:500
#: src/input/device_manager.cpp:501
msgid "Please re-configure your key bindings."
msgstr ""
#: src/input/device_manager.cpp:501
#: src/input/device_manager.cpp:502
msgid "Your input config file is not compatible with this version of STK."
msgstr ""
@ -2586,25 +2588,25 @@ msgstr ""
msgid "Left thumb up"
msgstr ""
#: src/input/input_manager.cpp:776
#: src/input/input_manager.cpp:768
#, c-format
msgid "Ignoring '%s'. You needed to join earlier to play!"
msgstr ""
#: src/input/input_manager.cpp:806
#: src/input/input_manager.cpp:798
msgid "Only the Game Master may act at this point!"
msgstr ""
#: src/input/wiimote_manager.cpp:389
msgid ""
"Connect your wiimote to the Bluetooth manager, then click on Ok.Detailed "
"Connect your wiimote to the Bluetooth manager, then click on Ok. Detailed "
"instructions at supertuxkart.net/Wiimote"
msgstr ""
#: src/input/wiimote_manager.cpp:392
msgid ""
"Press the buttons 1+2 simultaneously on your wiimote to put it in discovery "
"mode, then click on Ok.Detailed instructions at supertuxkart.net/Wiimote"
"mode, then click on Ok. Detailed instructions at supertuxkart.net/Wiimote"
msgstr ""
#: src/input/wiimote_manager.cpp:415
@ -2618,23 +2620,23 @@ msgstr[1] ""
msgid "Could not detect any wiimote :/"
msgstr ""
#: src/karts/controller/local_player_controller.cpp:204
#: src/karts/controller/local_player_controller.cpp:206
msgid "Penalty time!!"
msgstr ""
#: src/karts/controller/local_player_controller.cpp:206
#: src/karts/controller/local_player_controller.cpp:208
msgid "Don't accelerate before go"
msgstr ""
#: src/karts/kart.cpp:867 src/karts/kart.cpp:872
#: src/karts/kart.cpp:852 src/karts/kart.cpp:857
msgid "You won the race!"
msgstr ""
#: src/karts/kart.cpp:872
#: src/karts/kart.cpp:857
msgid "You finished the race!"
msgstr ""
#: src/main.cpp:1296
#: src/main.cpp:1413
msgid ""
"SuperTuxKart may connect to a server to download add-ons and notify you of "
"updates. We also collect anonymous hardware statistics to help with the "
@ -2644,15 +2646,16 @@ msgid ""
"edit \"Connect to the Internet\" and \"Send anonymous HW statistics\")."
msgstr ""
#: src/main.cpp:1446
#: src/main.cpp:1563
msgid ""
"Your driver version is too old. Please install the latest video drivers."
msgstr ""
#: src/main.cpp:1458
#: src/main.cpp:1580
#, c-format
msgid ""
"Your OpenGL version appears to be too old. Please verify if an update for "
"your video driver is available. SuperTuxKart requires OpenGL 3.1 or better."
"your video driver is available. SuperTuxKart requires %s or better."
msgstr ""
#: src/modes/easter_egg_hunt.cpp:202
@ -2660,7 +2663,7 @@ msgstr ""
msgid "Eggs: %d / %d"
msgstr ""
#: src/modes/follow_the_leader.cpp:61 src/modes/follow_the_leader.cpp:293
#: src/modes/follow_the_leader.cpp:61 src/modes/follow_the_leader.cpp:284
msgid "Leader"
msgstr ""
@ -2687,11 +2690,11 @@ msgstr ""
msgid "WRONG WAY!"
msgstr ""
#: src/modes/world.cpp:1208
#: src/modes/world.cpp:1207
msgid "You have been eliminated!"
msgstr ""
#: src/modes/world.cpp:1211
#: src/modes/world.cpp:1210
#, c-format
msgid "'%s' has been eliminated."
msgstr ""
@ -2700,7 +2703,7 @@ msgstr ""
msgid "Failed to register server"
msgstr ""
#: src/network/servers_manager.cpp:195
#: src/network/servers_manager.cpp:197
msgid "No LAN server detected"
msgstr ""
@ -2815,27 +2818,33 @@ msgstr ""
msgid "2 years"
msgstr ""
#: src/states_screens/addons_screen.cpp:110
#: src/states_screens/addons_screen.cpp:115
msgid "Add-on name"
msgstr ""
#: src/states_screens/addons_screen.cpp:111
#: src/states_screens/addons_screen.cpp:116
msgid "Updated date"
msgstr ""
#: src/states_screens/addons_screen.cpp:147
msgid ""
"Access to the Internet is disabled. (To enable it, go to options and select "
"tab 'User Interface')"
msgstr ""
#. I18N: as in: The Old Island by Johannes Sjolund
#: src/states_screens/addons_screen.cpp:304
#: src/states_screens/addons_screen.cpp:343
#, c-format
msgctxt "addons"
msgid "%s by %s"
msgstr ""
#: src/states_screens/addons_screen.cpp:435
#: src/states_screens/addons_screen.cpp:474
msgid "Please wait while addons are updated"
msgstr ""
#: src/states_screens/addons_screen.cpp:512
#: src/states_screens/main_menu_screen.cpp:553
#: src/states_screens/addons_screen.cpp:551
#: src/states_screens/main_menu_screen.cpp:554
msgid ""
"Sorry, an error occurred while contacting the add-ons website. Make sure you "
"are connected to the Internet and that SuperTuxKart is not blocked by a "
@ -3210,32 +3219,32 @@ msgstr ""
msgid "Select a track"
msgstr ""
#: src/states_screens/feature_unlocked.cpp:199
#: src/states_screens/feature_unlocked.cpp:200
#, c-format
msgid "You completed the easy challenge! Points earned on this level: %i/%i"
msgstr ""
#: src/states_screens/feature_unlocked.cpp:203
#: src/states_screens/feature_unlocked.cpp:204
#, c-format
msgid ""
"You completed the intermediate challenge! Points earned on this level: %i/%i"
msgstr ""
#: src/states_screens/feature_unlocked.cpp:207
#: src/states_screens/feature_unlocked.cpp:208
#, c-format
msgid ""
"You completed the difficult challenge! Points earned on this level: %i/%i"
msgstr ""
#: src/states_screens/feature_unlocked.cpp:492
#: src/states_screens/feature_unlocked.cpp:493
msgid "Challenge Completed"
msgstr ""
#: src/states_screens/feature_unlocked.cpp:529
#: src/states_screens/feature_unlocked.cpp:530
msgid "You unlocked track %0"
msgstr ""
#: src/states_screens/feature_unlocked.cpp:567
#: src/states_screens/feature_unlocked.cpp:568
msgid "You unlocked grand prix %0"
msgstr ""
@ -3271,16 +3280,16 @@ msgid "User defined"
msgstr ""
#. I18N: when failing a GP
#: src/states_screens/grand_prix_lose.cpp:153
#: src/states_screens/grand_prix_lose.cpp:154
msgid "Better luck next time!"
msgstr ""
#: src/states_screens/grand_prix_win.cpp:126
#: src/states_screens/grand_prix_win.cpp:127
#: src/states_screens/race_result_gui.cpp:194
msgid "You completed a challenge!"
msgstr ""
#: src/states_screens/grand_prix_win.cpp:283
#: src/states_screens/grand_prix_win.cpp:284
msgid "You completed the Grand Prix!"
msgstr ""
@ -3299,25 +3308,25 @@ msgid ""
"Press the 'Select' button to join the game"
msgstr ""
#: src/states_screens/main_menu_screen.cpp:492
#: src/states_screens/main_menu_screen.cpp:493
msgid ""
"You can not play online without internet access. If you want to play online, "
"go to options, select tab 'User Interface', and edit \"Connect to the "
"Internet\"."
msgstr ""
#: src/states_screens/main_menu_screen.cpp:516
#: src/states_screens/main_menu_screen.cpp:517
msgid ""
"You can not download addons without internet access. If you want to download "
"addons, go to options, select tab 'User Interface', and edit \"Connect to "
"the Internet\"."
msgstr ""
#: src/states_screens/main_menu_screen.cpp:548
#: src/states_screens/main_menu_screen.cpp:549
msgid "The add-ons module is currently disabled in the Options screen"
msgstr ""
#: src/states_screens/main_menu_screen.cpp:560
#: src/states_screens/main_menu_screen.cpp:561
msgid "Please wait while the add-ons are loading"
msgstr ""
@ -3505,14 +3514,14 @@ msgstr ""
msgid "Keyboard %i"
msgstr ""
#: src/states_screens/options_screen_ui.cpp:155
#: src/states_screens/options_screen_ui.cpp:158
msgid ""
"In multiplayer mode, players can select handicapped (more difficult) "
"profiles on the kart selection screen"
msgstr ""
#. I18N: in the language choice, to select the same language as the OS
#: src/states_screens/options_screen_ui.cpp:187
#: src/states_screens/options_screen_ui.cpp:190
msgid "System Language"
msgstr ""
@ -3642,20 +3651,20 @@ msgid "GOAL!"
msgstr ""
#. I18N: string used to show the author of the music. (e.g. "Sunny Song" by "John Doe")
#: src/states_screens/race_gui_base.cpp:504
#: src/states_screens/race_gui_base.cpp:496
msgid "by"
msgstr ""
#: src/states_screens/race_gui_base.cpp:612
#: src/states_screens/race_gui_base.cpp:604
msgid "Collect nitro!"
msgstr ""
#: src/states_screens/race_gui_base.cpp:614
#: src/states_screens/race_gui_base.cpp:606
msgid "Follow the leader!"
msgstr ""
#. I18N: When some GlobalPlayerIcons are hidden, write "Top 10" to show it
#: src/states_screens/race_gui_base.cpp:780
#: src/states_screens/race_gui_base.cpp:772
#, c-format
msgid "Top %i"
msgstr ""
@ -3669,15 +3678,15 @@ msgstr ""
msgid "Rank"
msgstr ""
#: src/states_screens/race_gui_overworld.cpp:469
#: src/states_screens/race_gui_overworld.cpp:472
msgid "Press fire to play the tutorial"
msgstr ""
#: src/states_screens/race_gui_overworld.cpp:508
#: src/states_screens/race_gui_overworld.cpp:511
msgid "Type: Grand Prix"
msgstr ""
#: src/states_screens/race_gui_overworld.cpp:539
#: src/states_screens/race_gui_overworld.cpp:548
msgid "Press fire to start the challenge"
msgstr ""
@ -3745,10 +3754,20 @@ msgstr ""
msgid "Grand Prix progress:"
msgstr ""
#: src/states_screens/race_result_gui.cpp:1341
#: src/states_screens/race_result_gui.cpp:1344
msgid "Highscores"
msgstr ""
#: src/states_screens/race_result_gui.cpp:1430
#, c-format
msgid "Difficulty: %s"
msgstr ""
#: src/states_screens/race_result_gui.cpp:1438
#, c-format
msgid "Best lap time: %s"
msgstr ""
#: src/states_screens/race_setup_screen.cpp:87
msgid "All blows allowed, so catch weapons and make clever use of them!"
msgstr ""
@ -3767,7 +3786,7 @@ msgid "Hit others with weapons until they lose all their lives."
msgstr ""
#: src/states_screens/race_setup_screen.cpp:119
msgid "Push the ball to the opposite cage to score goals."
msgid "Push the ball into the opposite cage to score goals."
msgstr ""
#: src/states_screens/race_setup_screen.cpp:129

View File

@ -1,23 +0,0 @@
#!/bin/sh
# Library directory
LIBDIR="bin"
# If we are launching from a symlink, such as /usr/local/bin/run_supertux.sh, we need to get where
# the symlink points to
pth="`readlink $0`"
# $pth will be empty if our start path wasnt a symlink
if [ $pth ]; then
GAMEDIR="`dirname $pth`"
else
GAMEDIR="`dirname $0`"
fi
# Change to the game dir, and go!
cd $GAMEDIR
# export game library directory
test -n "${LIBDIR}" && export LD_LIBRARY_PATH="${LD_LIBRARY_PATH}:${GAMEDIR}/${LIBDIR}"
bin/supertuxkart $*

View File

@ -1,8 +1,13 @@
uniform sampler2D ntex;
uniform sampler2D dtex;
#ifdef GL_ES
layout (location = 0) out vec4 Diff;
layout (location = 1) out vec4 Spec;
#else
out vec4 Diff;
out vec4 Spec;
#endif
#stk_include "utils/decodeNormal.frag"
#stk_include "utils/getPosFromUVDepth.frag"

View File

@ -1,7 +1,12 @@
uniform sampler2D ntex;
#ifdef GL_ES
layout (location = 0) out vec4 Diff;
layout (location = 1) out vec4 Spec;
#else
out vec4 Diff;
out vec4 Spec;
#endif
#stk_include "utils/decodeNormal.frag"
#stk_include "utils/getPosFromUVDepth.frag"

View File

@ -1,5 +1,7 @@
#version 300 es
precision mediump float;
in vec3 Position;
in vec2 Texcoord;
out vec2 uv;

View File

@ -6,8 +6,13 @@ flat in float energy;
flat in vec3 col;
flat in float radius;
#ifdef GL_ES
layout (location = 0) out vec4 Diff;
layout (location = 1) out vec4 Spec;
#else
out vec4 Diff;
out vec4 Spec;
#endif
#stk_include "utils/decodeNormal.frag"
#stk_include "utils/SpecularBRDF.frag"

View File

@ -1,8 +1,13 @@
uniform sampler2D ntex;
uniform sampler2D dtex;
#ifdef GL_ES
layout (location = 0) out vec4 Diff;
layout (location = 1) out vec4 Spec;
#else
out vec4 Diff;
out vec4 Spec;
#endif
#stk_include "utils/decodeNormal.frag"
#stk_include "utils/SpecularBRDF.frag"

View File

@ -9,8 +9,13 @@ uniform float splitmax;
uniform float shadow_res;
in vec2 uv;
#ifdef GL_ES
layout (location = 0) out vec4 Diff;
layout (location = 1) out vec4 Spec;
#else
out vec4 Diff;
out vec4 Spec;
#endif
#stk_include "utils/decodeNormal.frag"
#stk_include "utils/SpecularBRDF.frag"

View File

@ -8,8 +8,13 @@ uniform float split2;
uniform float splitmax;
in vec2 uv;
#ifdef GL_ES
layout (location = 0) out vec4 Diff;
layout (location = 1) out vec4 Spec;
#else
out vec4 Diff;
out vec4 Spec;
#endif
#stk_include "utils/decodeNormal.frag"
#stk_include "utils/SpecularBRDF.frag"

View File

@ -3,6 +3,7 @@ layout(bindless_sampler) uniform sampler2D tex;
#else
uniform sampler2D tex;
#endif
uniform float custom_alpha;
in vec2 uv;
in vec4 color;
@ -18,5 +19,5 @@ void main()
Color.xyz *= pow(color.xyz, vec3(2.2));
Color.a *= color.a;
// Premultiply alpha
FragColor = vec4(Color.rgb * Color.a, Color.a);
FragColor = vec4(Color.rgb * (Color.a * custom_alpha), Color.a * custom_alpha);
}

View File

@ -1,25 +0,0 @@
Here are the guidelines to follow when coding SuperTuxKart:
Filenames
=========
The filenames should be, with underscores between words. Use the .cpp
extension for C++ implementation files and .hpp for C++ headers, .c for
C files and .h for C headers.
Coding style
============
The coding style used in Super Tux Kart can be found at
http://supertuxkart.net/Coding_Style
Documentation line length
=========================
All the documentation files should have at most 80 characters, because
on some displays and on paper you often are limited to 80 characters, and
also under some conditions appendices (for example, line numbers) are
added. The exception if the player's manual, because it's long, so to
understand it better it should be limited to 65 characters.

View File

@ -67,6 +67,7 @@ set(ANGELSCRIPT_SOURCE
../../source/as_builder.cpp
../../source/as_bytecode.cpp
../../source/as_callfunc.cpp
../../source/as_callfunc_mips.cpp
../../source/as_callfunc_x86.cpp
../../source/as_callfunc_x64_gcc.cpp
../../source/as_callfunc_x64_msvc.cpp

View File

@ -844,7 +844,7 @@
#define THISCALL_PASS_OBJECT_POINTER_ON_THE_STACK
#define AS_X86
#undef AS_NO_THISCALL_FUNCTOR_METHOD
#elif defined(__LP64__) && !defined(__arm64__)
#elif defined(__x86_64__)
#define AS_X64_GCC
#undef AS_NO_THISCALL_FUNCTOR_METHOD
#define HAS_128_BIT_PRIMITIVES

View File

@ -16,3 +16,5 @@ add_library(glew STATIC
include/GL/glew.h include/GL/glxew.h include/GL/wglew.h
src/glew.c src/glewinfo.c
)
target_link_libraries(glew ${OPENGL_LIBRARIES})

View File

@ -86,7 +86,7 @@ CIrrDeviceLinux::CIrrDeviceLinux(const SIrrlichtCreationParameters& param)
: CIrrDeviceStub(param),
#ifdef _IRR_COMPILE_WITH_X11_
display(0), visual(0), screennr(0), window(0), StdHints(0), SoftwareImage(0),
XInputMethod(0), XInputContext(0),
XInputMethod(0), XInputContext(0), numlock_mask(0),
#ifdef _IRR_COMPILE_WITH_OPENGL_
glxWin(0),
Context(0),
@ -140,6 +140,7 @@ CIrrDeviceLinux::CIrrDeviceLinux(const SIrrlichtCreationParameters& param)
#ifdef _IRR_COMPILE_WITH_X11_
createInputContext();
numlock_mask = getNumlockMask(display);
#endif
createGUIAndScene();
@ -898,7 +899,7 @@ bool CIrrDeviceLinux::createWindow()
WMCheck, 0L, 1L, False, XA_WINDOW,
&type, &form, &len, &remain,
(unsigned char **)&list);
XFree(list);
bool netWM = (s == Success) && len;
attributes.override_redirect = !netWM && CreationParams.Fullscreen;
@ -1260,13 +1261,59 @@ void CIrrDeviceLinux::destroyInputContext()
}
}
int CIrrDeviceLinux::getNumlockMask(Display* display)
{
int mask_table[8] = {ShiftMask, LockMask, ControlMask, Mod1Mask,
Mod2Mask, Mod3Mask, Mod4Mask, Mod5Mask};
if (!display)
return 0;
KeyCode numlock_keycode = XKeysymToKeycode(display, XK_Num_Lock);
if (numlock_keycode == NoSymbol)
return 0;
XModifierKeymap* map = XGetModifierMapping(display);
if (!map)
return 0;
int mask = 0;
for (int i = 0; i < 8 * map->max_keypermod; i++)
{
if (map->modifiermap[i] != numlock_keycode)
continue;
mask = mask_table[i/map->max_keypermod];
break;
}
XFreeModifiermap(map);
return mask;
}
EKEY_CODE CIrrDeviceLinux::getKeyCode(XEvent &event)
{
EKEY_CODE keyCode = (EKEY_CODE)0;
SKeyMap mp;
mp.X11Key = XkbKeycodeToKeysym(display, event.xkey.keycode, 0, 0);
// mp.X11Key = XKeycodeToKeysym(XDisplay, event.xkey.keycode, 0); // deprecated, if we still find platforms which need that we have to use some define
// First check for numpad keys
bool is_numpad_key = false;
if (event.xkey.state & numlock_mask)
{
mp.X11Key = XkbKeycodeToKeysym(display, event.xkey.keycode, 0, 1);
if (mp.X11Key >=XK_KP_0 && mp.X11Key <= XK_KP_9)
is_numpad_key = true;
}
// If it's not numpad key, then get keycode in typical way
if (!is_numpad_key)
{
mp.X11Key = XkbKeycodeToKeysym(display, event.xkey.keycode, 0, 0);
}
const s32 idx = KeyMap.binary_search(mp);
if (idx != -1)
{

View File

@ -156,6 +156,7 @@ namespace irr
#ifdef _IRR_COMPILE_WITH_X11_
bool createInputContext();
void destroyInputContext();
int getNumlockMask(Display* display);
EKEY_CODE getKeyCode(XEvent &event);
#endif
@ -399,6 +400,7 @@ namespace irr
XIM XInputMethod;
XIC XInputContext;
mutable core::stringc Clipboard;
int numlock_mask;
#ifdef _IRR_LINUX_X11_VIDMODE_
XF86VidModeModeInfo oldVideoMode;
#endif

View File

@ -123,13 +123,6 @@ namespace video
EGL_NONE, 0
#endif
};
EGLint contextAttrib[] =
{
#ifdef EGL_VERSION_1_3
EGL_CONTEXT_CLIENT_VERSION, 2,
#endif
EGL_NONE, 0
};
EGLConfig config;
EGLint num_configs;
@ -242,11 +235,41 @@ namespace video
eglBindAPI(EGL_OPENGL_ES_API);
#endif
os::Printer::log("Creating EglContext...");
EglContext = eglCreateContext(EglDisplay, config, EGL_NO_CONTEXT, contextAttrib);
EglContext = EGL_NO_CONTEXT;
if (!Params.ForceLegacyDevice)
{
os::Printer::log("Trying to create Context for OpenGL-ES3.");
EGLint contextAttrib[] =
{
#ifdef EGL_VERSION_1_3
EGL_CONTEXT_CLIENT_VERSION, 3,
#endif
EGL_NONE, 0
};
EglContext = eglCreateContext(EglDisplay, config, EGL_NO_CONTEXT, contextAttrib);
}
if (EGL_NO_CONTEXT == EglContext)
{
os::Printer::log("FAILED\n");
os::Printer::log("Could not create Context for OpenGL-ES2 display.");
os::Printer::log("Trying to create Context for OpenGL-ES2.");
EGLint contextAttrib[] =
{
#ifdef EGL_VERSION_1_3
EGL_CONTEXT_CLIENT_VERSION, 2,
#endif
EGL_NONE, 0
};
EglContext = eglCreateContext(EglDisplay, config, EGL_NO_CONTEXT, contextAttrib);
if (EGL_NO_CONTEXT == EglContext)
{
os::Printer::log("FAILED\n");
os::Printer::log("Could not create Context for OpenGL-ES2 display.");
}
}
eglMakeCurrent(EglDisplay, EglSurface, EglSurface, EglContext);

View File

@ -1474,77 +1474,6 @@ void CSkinnedMesh::calculateTangents(
}
}
// ----------------------------------------------------------------------------
/** Copies a mesh.
*/
CSkinnedMesh *CSkinnedMesh::clone()
{
CSkinnedMesh* skinned_mesh = new CSkinnedMesh();
for (u32 i = 0; i < getMeshBuffers().size(); i++)
{
SSkinMeshBuffer * buffer = skinned_mesh->addMeshBuffer();
*buffer = *(getMeshBuffers()[i]);
}
for (u32 j = 0; j < getAllJoints().size(); ++j)
{
ISkinnedMesh::SJoint *joint = skinned_mesh->addJoint();
*joint = *(getAllJoints()[j]);
}
// fix children pointers (they still have old pointers)
core::array<ISkinnedMesh::SJoint*> & new_joints = skinned_mesh->getAllJoints();
for (u32 i = 0; i < new_joints.size(); ++i)
{
ISkinnedMesh::SJoint * joint = new_joints[i];
for (u32 c = 0; c < joint->Children.size(); ++c)
{
// the child is one of the oldJoints and must be replaced by the newjoint on the same index
bool found = false;
for (u32 k = 0; k < AllJoints.size(); ++k)
{
if (joint->Children[c] == AllJoints[k])
{
joint->Children[c] = new_joints[k];
found = true;
break;
}
} // k < old_joints.size
if (!found)
found = true;
} // c < joint->Children.size()
} // i < new_joints.size()
// In finalize the values from LocalBuffers are copied into
// Weights[].StaticPos. Since skinned_mesh already has the correct
// values in Weights, we have to copy the values from Weights
// into LocalBuffer (so that in the copy from LocalBuffer to weights
// no values are overwritten).
// FIXME: Not ideal, better would be not to copy the values in
// finalize().
for (unsigned int i = 0; i<AllJoints.size(); ++i)
{
SJoint *joint = AllJoints[i];
for (unsigned int j = 0; j<joint->Weights.size(); ++j)
{
const u16 buffer_id = joint->Weights[j].buffer_id;
const u32 vertex_id = joint->Weights[j].vertex_id;
skinned_mesh->LocalBuffers[buffer_id]->getVertex(vertex_id)->Pos = joint->Weights[j].StaticPos;
skinned_mesh->LocalBuffers[buffer_id]->getVertex(vertex_id)->Normal = joint->Weights[j].StaticNormal;
}
}
skinned_mesh->finalize();
return skinned_mesh;
} // clone
} // end namespace scene
} // end namespace irr

View File

@ -159,7 +159,6 @@ namespace scene
void addJoints(core::array<IBoneSceneNode*> &jointChildSceneNodes,
IAnimatedMeshSceneNode* node,
ISceneManager* smgr);
CSkinnedMesh *clone();
private:
void checkForAnimation();

View File

@ -333,11 +333,10 @@ bool MusicOggStream::streamIntoBuffer(ALuint buffer)
int size = 0;
int portion;
int result;
while(size < m_buffer_size)
{
result = ov_read(&m_oggStream, pcm + size, m_buffer_size - size,
int result = ov_read(&m_oggStream, pcm + size, m_buffer_size - size,
isBigEndian, 2, 1, &portion);
if(result > 0)

View File

@ -424,7 +424,7 @@ void SFXOpenAL::setPosition(const Vec3 &position)
{
// Don't send a position command to the thread if the sound is not playing
// (or sfx disabled or the sound was not initialised correctly)
// if (m_status != SFX_PLAYING|| !SFXManager::get()->sfxAllowed()) return;
if (!SFXManager::get()->sfxAllowed()) return;
SFXManager::get()->queue(SFXManager::SFX_POSITION, this, position);
} // setPosition

View File

@ -516,7 +516,6 @@ const irr::core::stringw
if (track == NULL) return irr::core::stringw( L"????" );
return _("New track '%s' now available", track->getName());
break;
}
case UNLOCK_MODE:
{

View File

@ -678,7 +678,7 @@ namespace UserConfigParams
"Enable Screen Space Ambient Occlusion") );
PARAM_PREFIX IntUserConfigParam m_shadows_resolution
PARAM_DEFAULT( IntUserConfigParam(0,
"shadows_resoltion", &m_graphics_quality,
"shadows_resolution", &m_graphics_quality,
"Shadow resolution (0 = disabled") );
PARAM_PREFIX BoolUserConfigParam m_degraded_IBL
PARAM_DEFAULT(BoolUserConfigParam(true,

View File

@ -18,9 +18,10 @@
#include "font/bold_face.hpp"
#include "font/face_ttf.hpp"
// ----------------------------------------------------------------------------
/** Constructor of BoldFace.
* \param ttf \ref FaceTTF for BoldFace to use.
*/
BoldFace::BoldFace(FaceTTF* ttf) : FontWithFace("BoldFace", ttf)
{
} // BoldFace
@ -53,3 +54,12 @@ void BoldFace::reset()
insertCharacters(preload_chars.c_str());
updateCharactersList();
} // reset
// ----------------------------------------------------------------------------
/** Embolden the glyph to make bold font using FT_Outline_Embolden.
* \return A FT_Error value.
*/
int BoldFace::shapeOutline(FT_Outline* outline) const
{
return FT_Outline_Embolden(outline, getDPI() * 2);
} // shapeOutline

View File

@ -23,24 +23,28 @@
class FaceTTF;
/** A font which uses regular TTFs to render title or important message in STK
* with a bold outline, it shares the same \ref FaceTTF with \ref RegularFace.
* \ingroup font
*/
class BoldFace : public FontWithFace
{
private:
virtual bool supportLazyLoadChar() const OVERRIDE { return true; }
// ------------------------------------------------------------------------
virtual unsigned int getGlyphPageSize() const OVERRIDE { return 1024; }
// ------------------------------------------------------------------------
virtual float getScalingFactorOne() const OVERRIDE { return 0.2f; }
// ------------------------------------------------------------------------
virtual unsigned int getScalingFactorTwo() const OVERRIDE { return 120; }
// ------------------------------------------------------------------------
virtual bool isBold() const { return true; }
// ------------------------------------------------------------------------
virtual int shapeOutline(FT_Outline* outline) const OVERRIDE;
public:
LEAK_CHECK()
// ------------------------------------------------------------------------
BoldFace(FaceTTF* ttf);
// ------------------------------------------------------------------------
virtual ~BoldFace() {}
// ------------------------------------------------------------------------
virtual void init() OVERRIDE;
// ------------------------------------------------------------------------
virtual void reset() OVERRIDE;

View File

@ -18,9 +18,10 @@
#include "font/digit_face.hpp"
#include "font/face_ttf.hpp"
// ----------------------------------------------------------------------------
/** Constructor of DigitFace.
* \param ttf \ref FaceTTF for DigitFace to use.
*/
DigitFace::DigitFace(FaceTTF* ttf) : FontWithFace("DigitFace", ttf)
{
} // DigitFace

View File

@ -23,6 +23,9 @@
class FaceTTF;
/** A font which uses a more cartonish style TTF to render big numbers in STK.
* \ingroup font
*/
class DigitFace : public FontWithFace
{
private:
@ -39,8 +42,6 @@ public:
// ------------------------------------------------------------------------
DigitFace(FaceTTF* ttf);
// ------------------------------------------------------------------------
virtual ~DigitFace() {}
// ------------------------------------------------------------------------
virtual void init() OVERRIDE;
// ------------------------------------------------------------------------
virtual void reset() OVERRIDE;

View File

@ -18,22 +18,29 @@
#include "font/face_ttf.hpp"
#include "font/font_manager.hpp"
#include "io/file_manager.hpp"
// ----------------------------------------------------------------------------
/** Constructor. Load all TTFs from a list.
* \param ttf_list List of TTFs to be loaded.
*/
FaceTTF::FaceTTF(const std::vector<std::string>& ttf_list)
{
for (const std::string& font : ttf_list)
{
FT_Face face = NULL;
const std::string loc = file_manager
->getAssetChecked(FileManager::TTF, font.c_str(), true);
font_manager->checkFTError(FT_New_Face(font_manager->getFTLibrary(),
(file_manager->getAssetChecked(FileManager::TTF,
font.c_str(), true)).c_str(), 0, &face), "loading fonts");
loc.c_str(), 0, &face), loc + " is loaded");
m_faces.push_back(face);
}
} // FaceTTF
// ----------------------------------------------------------------------------
/** Destructor. Clears all TTFs.
*/
FaceTTF::~FaceTTF()
{
for (unsigned int i = 0; i < m_faces.size(); i++)
@ -42,6 +49,9 @@ FaceTTF::~FaceTTF()
}
} // ~FaceTTF
// ----------------------------------------------------------------------------
/** Return a TTF in \ref m_faces.
* \param i index of TTF file in \ref m_faces.
*/
FT_Face FaceTTF::getFace(unsigned int i) const
{
assert(i < m_faces.size());

View File

@ -19,15 +19,30 @@
#ifndef HEADER_FACE_TTF_HPP
#define HEADER_FACE_TTF_HPP
#include "font/font_manager.hpp"
#include "utils/leak_check.hpp"
#include "utils/no_copy.hpp"
#include <string>
#include <vector>
#include <ft2build.h>
#include FT_FREETYPE_H
/** This class will load a list of TTF files from \ref STKConfig, and save
* them inside \ref m_faces for \ref FontWithFace to load glyph.
* Each FaceTTF can be used more than once in each instantiation of \ref
* FontWithFace, so it can render characters differently using the same TTF
* file to save memory, for example different outline size.
* \ingroup font
*/
class FaceTTF : public NoCopy
{
private:
/** Contains all TTF files loaded. */
std::vector<FT_Face> m_faces;
public:
LEAK_CHECK();
LEAK_CHECK()
// ------------------------------------------------------------------------
FaceTTF(const std::vector<std::string>& ttf_list);
// ------------------------------------------------------------------------
@ -35,6 +50,7 @@ public:
// ------------------------------------------------------------------------
FT_Face getFace(unsigned int i) const;
// ------------------------------------------------------------------------
/** Return the total TTF files loaded. */
unsigned int getTotalFaces() const { return m_faces.size(); }
}; // FaceTTF

View File

@ -28,15 +28,22 @@
FontManager *font_manager = NULL;
// ----------------------------------------------------------------------------
/** Constructor. It will initialize the \ref m_ft_library.
*/
FontManager::FontManager()
{
checkFTError(FT_Init_FreeType(&m_ft_library), "loading freetype library");
} // FontManager
// ----------------------------------------------------------------------------
/** Destructor. Clears all fonts and related stuff.
*/
FontManager::~FontManager()
{
m_fonts.clearAndDeleteAll();
for (unsigned int i = 0; i < m_fonts.size(); i++)
delete m_fonts[i];
m_fonts.clear();
delete m_normal_ttf;
m_normal_ttf = NULL;
delete m_digit_ttf;
@ -47,6 +54,8 @@ FontManager::~FontManager()
} // ~FontManager
// ----------------------------------------------------------------------------
/** Initialize all \ref FaceTTF and \ref FontWithFace members.
*/
void FontManager::loadFonts()
{
// First load the TTF files required by each font
@ -72,15 +81,10 @@ void FontManager::loadFonts()
} // loadFonts
// ----------------------------------------------------------------------------
void FontManager::checkFTError(FT_Error err, const std::string& desc) const
{
if (err > 0)
{
Log::error("FontManager", "Something wrong when %s!", desc.c_str());
}
} // checkFTError
// ----------------------------------------------------------------------------
/** Unit testing that will try to load all translations in STK, and discover if
* there is any characters required by it are not supported in \ref
* m_normal_ttf.
*/
void FontManager::unitTesting()
{
std::vector<std::string> list = *(translations->getLanguageList());

View File

@ -19,14 +19,18 @@
#ifndef HEADER_FONT_MANAGER_HPP
#define HEADER_FONT_MANAGER_HPP
/** \defgroup font Font
* This module stores font files and tools used to draw characters in STK.
*/
#include "utils/leak_check.hpp"
#include "utils/log.hpp"
#include "utils/no_copy.hpp"
#include "utils/ptr_vector.hpp"
#include <string>
#include <typeindex>
#include <unordered_map>
#include <vector>
#include <ft2build.h>
#include FT_FREETYPE_H
@ -34,17 +38,26 @@
class FaceTTF;
class FontWithFace;
/** This class stores all font files required in STK.
* \ingroup font
*/
class FontManager : public NoCopy
{
private:
PtrVector<FontWithFace> m_fonts;
/** Stores all \ref FontWithFace used in STK. */
std::vector<FontWithFace*> m_fonts;
/** A FreeType library, it holds the FT_Face internally inside freetype. */
FT_Library m_ft_library;
/** TTF files used in \ref BoldFace and \ref RegularFace. */
FaceTTF* m_normal_ttf;
/** TTF files used in \ref DigitFace. */
FaceTTF* m_digit_ttf;
/** Map type for each \ref FontWithFace with a index, save getting time in
* \ref getFont. */
std::unordered_map<std::type_index, int> m_font_type_map;
public:
@ -54,11 +67,12 @@ public:
// ------------------------------------------------------------------------
~FontManager();
// ------------------------------------------------------------------------
/** Return a specfic type of \ref FontWithFace found in \ref m_fonts. */
template <typename T> T* getFont()
{
T* out = NULL;
const unsigned int n = m_font_type_map[std::type_index(typeid(T))];
out = dynamic_cast<T*>(m_fonts.get(n));
out = dynamic_cast<T*>(m_fonts[n]);
if (out != NULL)
{
return out;
@ -68,16 +82,23 @@ public:
}
// ------------------------------------------------------------------------
/** Check for any error discovered in a freetype function that will return
* a FT_Error value.
* a FT_Error value, and log into the terminal.
* \param err The Freetype function.
* \param desc The description of what is the function doing.
*/
void checkFTError(FT_Error err, const std::string& desc) const;
* \param desc The description of what is the function doing. */
void checkFTError(FT_Error err, const std::string& desc) const
{
if (err > 0)
{
Log::error("FontManager", "Something wrong when %s! The error "
"code was %d.", desc.c_str(), err);
}
}
// ------------------------------------------------------------------------
void loadFonts();
// ------------------------------------------------------------------------
void unitTesting();
// ------------------------------------------------------------------------
/** Return the \ref m_ft_library. */
FT_Library getFTLibrary() const { return m_ft_library; }
}; // FontManager

View File

@ -25,21 +25,34 @@
using namespace irr;
/** This class stores settings when rendering fonts, used when instantiating
* \ref irr::gui::ScalableFont.
* \ingroup font
*/
class FontSettings
{
private:
/** True if black border will be drawn when rendering. */
bool m_black_border;
/** If true, characters will have right alignment when rendering, for RTL
* language. */
bool m_rtl;
/** Scaling when rendering. */
float m_scale;
/** True if shadow will be drawn when rendering. */
bool m_shadow;
/** Save the color of shadow when rendering. */
video::SColor m_shadow_color;
public:
LEAK_CHECK()
// ------------------------------------------------------------------------
/** Constructor. It will initialize all members with default values if no
* parameter is given. */
FontSettings(bool black_border = false, bool rtl = false,
float scale = 1.0f, bool shadow = false,
const video::SColor& color = video::SColor(0, 0, 0, 0))
@ -51,26 +64,39 @@ public:
m_shadow_color = color;
}
// ------------------------------------------------------------------------
~FontSettings() {}
// ------------------------------------------------------------------------
/** Set the scaling.
* \param scale Scaling to be set. */
void setScale(float scale) { m_scale = scale; }
// ------------------------------------------------------------------------
/** Return the scaling. */
float getScale() const { return m_scale; }
// ------------------------------------------------------------------------
/** Set the color of shadow.
* \param col The color of shadow to be set. */
void setShadowColor(const video::SColor &col) { m_shadow_color = col; }
// ------------------------------------------------------------------------
/** Return the color of shadow. */
const video::SColor& getShadowColor() const { return m_shadow_color; }
// ------------------------------------------------------------------------
/** Return if shadow is enabled. */
bool useShadow() const { return m_shadow; }
// ------------------------------------------------------------------------
/** Set whether shadow is enabled.
* \param shadow If it's enabled. */
void setShadow(bool shadow) { m_shadow = shadow; }
// ------------------------------------------------------------------------
/** Set whether black border is enabled.
* \param border If it's enabled. */
void setBlackBorder(bool border) { m_black_border = border; }
// ------------------------------------------------------------------------
/** Return if black border is enabled. */
bool useBlackBorder() const { return m_black_border; }
// ------------------------------------------------------------------------
/** Set right text alignment for RTL language.
* \param rtl If it's enabled. */
void setRTL(bool rtl) { m_rtl = rtl; }
// ------------------------------------------------------------------------
/** Return if right text alignment for RTL language is enabled. */
bool isRTL() const { return m_rtl; }
}; // FontSettings

View File

@ -18,17 +18,20 @@
#include "font/font_with_face.hpp"
#include "font/bold_face.hpp"
#include "font/face_ttf.hpp"
#include "font/font_manager.hpp"
#include "font/font_settings.hpp"
#include "graphics/2dutils.hpp"
#include "graphics/irr_driver.hpp"
#include "guiengine/engine.hpp"
#include "guiengine/skin.hpp"
#include "utils/string_utils.hpp"
#include FT_OUTLINE_H
// ----------------------------------------------------------------------------
/** Constructor. It will initialize the \ref m_spritebank and TTF files to use.
* \param name The name of face, used by irrlicht to distinguish spritebank.
* \param ttf \ref FaceTTF for this face to use.
*/
FontWithFace::FontWithFace(const std::string& name, FaceTTF* ttf)
{
m_spritebank = irr_driver->getGUI()->addEmptySpriteBank(name.c_str());
@ -43,6 +46,8 @@ FontWithFace::FontWithFace(const std::string& name, FaceTTF* ttf)
} // FontWithFace
// ----------------------------------------------------------------------------
/** Destructor. Clears the glyph page and sprite bank.
*/
FontWithFace::~FontWithFace()
{
m_page->drop();
@ -56,6 +61,8 @@ FontWithFace::~FontWithFace()
} // ~FontWithFace
// ----------------------------------------------------------------------------
/** Initialize the font structure, but don't load glyph here.
*/
void FontWithFace::init()
{
setDPI();
@ -83,7 +90,11 @@ void FontWithFace::init()
reset();
} // init
// ----------------------------------------------------------------------------
/** Clear all the loaded characters, sub-class can do pre-loading of characters
* after this.
*/
void FontWithFace::reset()
{
m_new_char_holder.clear();
@ -94,6 +105,12 @@ void FontWithFace::reset()
} // reset
// ----------------------------------------------------------------------------
/** Convert a character to a glyph index in one of the font in \ref m_face_ttf,
* it will find the first TTF that supports this character, if the final
* glyph_index is 0, this means such character is not supported by all TTFs in
* \ref m_face_ttf.
* \param c The character to be loaded.
*/
void FontWithFace::loadGlyphInfo(wchar_t c)
{
unsigned int font_number = 0;
@ -108,11 +125,12 @@ void FontWithFace::loadGlyphInfo(wchar_t c)
} // loadGlyphInfo
// ----------------------------------------------------------------------------
/** Create a new glyph page by filling it with transparent content.
*/
void FontWithFace::createNewGlyphPage()
{
// Clean the current glyph page by filling it with transparent content
m_page->fill(video::SColor(0, 255, 255, 255));
m_temp_height = 0;
m_current_height = 0;
m_used_width = 0;
m_used_height = 0;
@ -140,6 +158,10 @@ void FontWithFace::createNewGlyphPage()
} // createNewGlyphPage
// ----------------------------------------------------------------------------
/** Render a glyph for a character into bitmap and save it into the glyph page.
* \param c The character to be loaded.
* \param c \ref GlyphInfo for the character.
*/
void FontWithFace::insertGlyph(wchar_t c, const GlyphInfo& gi)
{
assert(gi.glyph_index > 0);
@ -147,7 +169,7 @@ void FontWithFace::insertGlyph(wchar_t c, const GlyphInfo& gi)
FT_Face cur_face = m_face_ttf->getFace(gi.font_number);
FT_GlyphSlot slot = cur_face->glyph;
// Faces may be shared across regular and bold,
// Same face may be shared across the different FontWithFace,
// so reset dpi each time
font_manager->checkFTError(FT_Set_Pixel_Sizes(cur_face, 0, getDPI()),
"setting DPI");
@ -155,15 +177,11 @@ void FontWithFace::insertGlyph(wchar_t c, const GlyphInfo& gi)
font_manager->checkFTError(FT_Load_Glyph(cur_face, gi.glyph_index,
FT_LOAD_DEFAULT), "loading a glyph");
if (dynamic_cast<BoldFace*>(this) != NULL)
{
// Embolden the outline of the glyph
font_manager->checkFTError(FT_Outline_Embolden(&(slot->outline),
getDPI() * 2), "embolden a glyph");
}
font_manager->checkFTError(shapeOutline(&(slot->outline)),
"shaping outline");
font_manager->checkFTError(FT_Render_Glyph(slot, FT_RENDER_MODE_NORMAL),
"render a glyph to bitmap");
"rendering a glyph to bitmap");
// Convert to an anti-aliased bitmap
FT_Bitmap bits = slot->bitmap;
@ -176,7 +194,7 @@ void FontWithFace::insertGlyph(wchar_t c, const GlyphInfo& gi)
true, 0);
if ((m_used_width + texture_size.Width > getGlyphPageSize() &&
m_used_height + m_temp_height + texture_size.Height >
m_used_height + m_current_height + texture_size.Height >
getGlyphPageSize()) ||
m_used_height + texture_size.Height > getGlyphPageSize())
{
@ -244,8 +262,8 @@ void FontWithFace::insertGlyph(wchar_t c, const GlyphInfo& gi)
if (m_used_width + texture_size.Width > getGlyphPageSize())
{
m_used_width = 0;
m_used_height += m_temp_height;
m_temp_height = 0;
m_used_height += m_current_height;
m_current_height = 0;
}
// Copy to the full glyph page
@ -283,11 +301,13 @@ void FontWithFace::insertGlyph(wchar_t c, const GlyphInfo& gi)
// Store used area
m_used_width += texture_size.Width;
if (m_temp_height < texture_size.Height)
m_temp_height = texture_size.Height;
if (m_current_height < texture_size.Height)
m_current_height = texture_size.Height;
} // insertGlyph
// ----------------------------------------------------------------------------
/** Update the supported characters for this font if required.
*/
void FontWithFace::updateCharactersList()
{
if (m_fallback_font != NULL)
@ -321,6 +341,10 @@ void FontWithFace::updateCharactersList()
} // updateCharactersList
// ----------------------------------------------------------------------------
/** Write the current glyph page in png inside current running directory.
* Mainly for debug use.
* \param name The file name.
*/
void FontWithFace::dumpGlyphPage(const std::string& name)
{
for (unsigned int i = 0; i < m_spritebank->getTextureCount(); i++)
@ -341,20 +365,23 @@ void FontWithFace::dumpGlyphPage(const std::string& name)
} // dumpGlyphPage
// ----------------------------------------------------------------------------
/** Write the current glyph page in png inside current running directory.
* Useful in gdb without parameter.
*/
void FontWithFace::dumpGlyphPage()
{
dumpGlyphPage("face");
} // dumpGlyphPage
// ----------------------------------------------------------------------------
/** Set the face dpi which is resolution-dependent.
* Normal text will range from 0.8, in 640x* resolutions (won't scale below
* that) to 1.0, in 1024x* resolutions, and linearly up.
* Bold text will range from 0.2, in 640x* resolutions (won't scale below
* that) to 0.4, in 1024x* resolutions, and linearly up.
*/
void FontWithFace::setDPI()
{
// Set face dpi:
// Font size is resolution-dependent.
// Normal text will range from 0.8, in 640x* resolutions (won't scale
// below that) to 1.0, in 1024x* resolutions, and linearly up
// Bold text will range from 0.2, in 640x* resolutions (won't scale
// below that) to 0.4, in 1024x* resolutions, and linearly up
const int screen_width = irr_driver->getFrameSize().Width;
const int screen_height = irr_driver->getFrameSize().Height;
float scale = std::max(0, screen_width - 640) / 564.0f;
@ -371,6 +398,10 @@ void FontWithFace::setDPI()
} // setDPI
// ----------------------------------------------------------------------------
/** Return the \ref FontArea about a character.
* \param c The character to get.
* \param[out] fallback_font Whether fallback font is used.
*/
const FontWithFace::FontArea&
FontWithFace::getAreaFromCharacter(const wchar_t c,
bool* fallback_font) const
@ -397,6 +428,12 @@ const FontWithFace::FontArea&
} // getAreaFromCharacter
// ----------------------------------------------------------------------------
/** Get the dimension of text with support to different \ref FontSettings,
* it will also do checking for missing characters in font and lazy load them.
* \param text The text to be calculated.
* \param font_settings \ref FontSettings to use.
* \return The dimension of text
*/
core::dimension2d<u32> FontWithFace::getDimension(const wchar_t* text,
FontSettings* font_settings)
{
@ -441,6 +478,12 @@ core::dimension2d<u32> FontWithFace::getDimension(const wchar_t* text,
} // getDimension
// ----------------------------------------------------------------------------
/** Calculate the index of the character in the text on a specific position.
* \param text The text to be calculated.
* \param pixel_x The specific position.
* \param font_settings \ref FontSettings to use.
* \return The index of the character, -1 means no character in such position.
*/
int FontWithFace::getCharacterFromPos(const wchar_t* text, int pixel_x,
FontSettings* font_settings) const
{
@ -466,6 +509,17 @@ int FontWithFace::getCharacterFromPos(const wchar_t* text, int pixel_x,
} // getCharacterFromPos
// ----------------------------------------------------------------------------
/** Render text and clip it to the specified rectangle if wanted, it will also
* do checking for missing characters in font and lazy load them.
* \param text The text to be rendering.
* \param position The position to be rendering.
* \param color The color used when rendering.
* \param hcenter If rendered horizontally center.
* \param vcenter If rendered vertically center.
* \param clip If clipping is needed.
* \param font_settings \ref FontSettings to use.
* \param char_collector \ref FontCharCollector to render billboard text.
*/
void FontWithFace::render(const core::stringw& text,
const core::rect<s32>& position,
const video::SColor& color, bool hcenter,
@ -473,7 +527,6 @@ void FontWithFace::render(const core::stringw& text,
FontSettings* font_settings,
FontCharCollector* char_collector)
{
const bool is_bold_face = (dynamic_cast<BoldFace*>(this) != NULL);
const bool black_border = font_settings ?
font_settings->useBlackBorder() : false;
const bool rtl = font_settings ? font_settings->isRTL() : false;
@ -621,7 +674,7 @@ void FontWithFace::render(const core::stringw& text,
const int sprite_amount = sprites.size();
if ((black_border || is_bold_face) && char_collector == NULL)
if ((black_border || isBold()) && char_collector == NULL)
{
// Draw black border first, to make it behind the real character
// which make script language display better
@ -693,7 +746,7 @@ void FontWithFace::render(const core::stringw& text,
m_fallback_font->m_spritebank->getTexture(tex_id) :
m_spritebank->getTexture(tex_id));
if (fallback[n] || is_bold_face)
if (fallback[n] || isBold())
{
video::SColor top = GUIEngine::getSkin()->getColor("font::top");
video::SColor bottom = GUIEngine::getSkin()

View File

@ -19,47 +19,84 @@
#ifndef HEADER_FONT_WITH_FACE_HPP
#define HEADER_FONT_WITH_FACE_HPP
#include "font/font_manager.hpp"
#include "font/font_settings.hpp"
#include "utils/cpp2011.hpp"
#include "utils/leak_check.hpp"
#include "utils/no_copy.hpp"
#include <algorithm>
#include <cassert>
#include <map>
#include <set>
#include <ft2build.h>
#include FT_FREETYPE_H
#include FT_OUTLINE_H
#include <irrlicht.h>
using namespace irr;
const int BEARING = 64;
class FaceTTF;
class FontSettings;
/** An abstract class which contains functions which convert vector fonts into
* bitmap and render them in STK. To make STK draw characters with different
* render option (like scaling, shadow) using a same FontWithFace, you need
* to wrap this with \ref irr::gui::ScalableFont and configure the
* \ref FontSettings for it.
* \ingroup font
*/
class FontWithFace : public NoCopy
{
public:
/** A class for \ref STKTextBillboard to get font info to render billboard
* text. */
class FontCharCollector
{
public:
/** Collect the character info for billboard text.
* \param texture The texture of the character.
* \param destRect The destination rectangle
* \param sourceRect The source rectangle in the glyph page
* \param colors The color to render it. */
virtual void collectChar(video::ITexture* texture,
const core::rect<float>& destRect,
const core::rect<s32>& sourceRect,
const video::SColor* const colors) = 0;
};
/** Glyph metrics for each glyph loaded. */
struct FontArea
{
FontArea() : advance_x(0), bearing_x(0) ,offset_y(0), offset_y_bt(0),
spriteno(0) {}
/** Advance width for horizontal layout. */
int advance_x;
/** Left side bearing for horizontal layout. */
int bearing_x;
/** Top side bearing for horizontal layout. */
int offset_y;
/** Top side bearing for horizontal layout used in billboard text. */
int offset_y_bt;
/** Index number in sprite bank. */
int spriteno;
};
protected:
int m_font_max_height;
/** Used in vertical dimension calculation. */
int m_font_max_height;
int m_glyph_max_height;
/** Used in top side bearing calculation. */
int m_glyph_max_height;
// ------------------------------------------------------------------------
/** Check characters to see if they are loaded in font, if not load them.
* For font that doesn't need lazy loading, nothing will be done.
* \param in_ptr Characters to check.
* \param first_load If true, it will ignore \ref supportLazyLoadChar,
* which is called in \ref reset. */
void insertCharacters(const wchar_t* in_ptr, bool first_load = false)
{
if (!supportLazyLoadChar() && !first_load) return;
@ -88,44 +125,69 @@ protected:
// ------------------------------------------------------------------------
void updateCharactersList();
// ------------------------------------------------------------------------
/** Set the fallback font for this font, so if some character is missing in
* this font, it will use that fallback font to try rendering it.
* \param face A \ref FontWithFace font. */
void setFallbackFont(FontWithFace* face) { m_fallback_font = face; }
// ------------------------------------------------------------------------
/** Set the scaling of fallback font.
* \param scale The scaling to set. */
void setFallbackFontScale(float scale) { m_fallback_font_scale = scale; }
private:
/** Mapping of glyph index to a TTF in \ref FaceTTF. */
struct GlyphInfo
{
GlyphInfo(unsigned int font_num = 0, unsigned int glyph_idx = 0) :
font_number(font_num), glyph_index(glyph_idx) {}
/** Index to a TTF in \ref FaceTTF. */
unsigned int font_number;
/** Glyph index in the TTF, 0 means no such glyph. */
unsigned int glyph_index;
GlyphInfo(unsigned int first = 0, unsigned int second = 0)
{
font_number = first;
glyph_index = second;
}
};
/** \ref FaceTTF to load glyph from. */
FaceTTF* m_face_ttf;
/** Fallback font to use if some character isn't supported by this font. */
FontWithFace* m_fallback_font;
/** Scaling for fallback font. */
float m_fallback_font_scale;
/** A temporary holder stored new char to be inserted. */
/** A temporary holder to store new characters to be inserted. */
std::set<wchar_t> m_new_char_holder;
/** Sprite bank to store each glyph. */
gui::IGUISpriteBank* m_spritebank;
/** A full glyph page for this font. */
video::IImage* m_page;
unsigned int m_temp_height;
/** The current max height at current drawing line in glyph page. */
unsigned int m_current_height;
/** The used width in glyph page. */
unsigned int m_used_width;
/** The used height in glyph page. */
unsigned int m_used_height;
/** The dpi of this font. */
unsigned int m_face_dpi;
/** Store a list of supported character to a \ref FontArea. */
std::map<wchar_t, FontArea> m_character_area_map;
/** Store a list of loaded and tested character to a \ref GlyphInfo. */
std::map<wchar_t, GlyphInfo> m_character_glyph_info_map;
// ------------------------------------------------------------------------
/** Return a character width.
* \param area \ref FontArea to get glyph metrics.
* \param fallback If fallback font is used.
* \param scale The scaling of the character.
* \return The calculated width with suitable scaling. */
float getCharWidth(const FontArea& area, bool fallback, float scale) const
{
if (fallback)
@ -134,6 +196,9 @@ private:
return area.advance_x * scale;
}
// ------------------------------------------------------------------------
/** Test if a character has already been tried to be loaded.
* \param c Character to test.
* \return True if tested. */
bool loadedChar(wchar_t c) const
{
std::map<wchar_t, GlyphInfo>::const_iterator n =
@ -143,6 +208,10 @@ private:
return false;
}
// ------------------------------------------------------------------------
/** Get the \ref GlyphInfo from \ref m_character_glyph_info_map about a
* character.
* \param c Character to get.
* \return \ref GlyphInfo of this character. */
const GlyphInfo& getGlyphInfo(wchar_t c) const
{
std::map<wchar_t, GlyphInfo>::const_iterator n =
@ -152,6 +221,10 @@ private:
return n->second;
}
// ------------------------------------------------------------------------
/** Tells whether a character is supported by all TTFs in \ref m_face_ttf
* which is determined by \ref GlyphInfo of this character.
* \param c Character to test.
* \return True if it's supported. */
bool supportChar(wchar_t c)
{
std::map<wchar_t, GlyphInfo>::const_iterator n =
@ -167,22 +240,36 @@ private:
// ------------------------------------------------------------------------
void createNewGlyphPage();
// ------------------------------------------------------------------------
/** Add a character into \ref m_new_char_holder for lazy loading later. */
void addLazyLoadChar(wchar_t c) { m_new_char_holder.insert(c); }
// ------------------------------------------------------------------------
void insertGlyph(wchar_t c, const GlyphInfo& gi);
// ------------------------------------------------------------------------
void setDPI();
// ------------------------------------------------------------------------
virtual bool supportLazyLoadChar() const = 0;
/** Override it if sub-class should not do lazy loading characters. */
virtual bool supportLazyLoadChar() const { return true; }
// ------------------------------------------------------------------------
/** Defined by sub-class about the texture size of glyph page, it should be
* a power of two. */
virtual unsigned int getGlyphPageSize() const = 0;
// ------------------------------------------------------------------------
/** Defined by sub-class about the scaling factor 1. */
virtual float getScalingFactorOne() const = 0;
// ------------------------------------------------------------------------
/** Defined by sub-class about the scaling factor 2. */
virtual unsigned int getScalingFactorTwo() const = 0;
// ------------------------------------------------------------------------
/** Override it if sub-class has bold outline. */
virtual bool isBold() const { return false; }
// ------------------------------------------------------------------------
/** Override it if any outline shaping is needed to be done before
* rendering the glyph into bitmap.
* \return A FT_Error value if needed. */
virtual int shapeOutline(FT_Outline* outline) const { return 0; }
public:
LEAK_CHECK();
LEAK_CHECK()
// ------------------------------------------------------------------------
FontWithFace(const std::string& name, FaceTTF* ttf);
// ------------------------------------------------------------------------
@ -204,22 +291,17 @@ public:
FontSettings* font_settings,
FontCharCollector* char_collector = NULL);
// ------------------------------------------------------------------------
/** Write the current glyph page in png inside current running directory.
* Mainly for debug use.
* \param name The file name.
*/
void dumpGlyphPage(const std::string& name);
// ------------------------------------------------------------------------
/** Write the current glyph page in png inside current running directory.
* Useful in gdb without parameter.
*/
void dumpGlyphPage();
// ------------------------------------------------------------------------
/** Return the sprite bank. */
gui::IGUISpriteBank* getSpriteBank() const { return m_spritebank; }
// ------------------------------------------------------------------------
const FontArea& getAreaFromCharacter(const wchar_t c,
bool* fallback_font) const;
// ------------------------------------------------------------------------
/** Return the dpi of this face. */
unsigned int getDPI() const { return m_face_dpi; }
}; // FontWithFace

View File

@ -16,11 +16,12 @@
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include "font/face_ttf.hpp"
#include "font/regular_face.hpp"
// ----------------------------------------------------------------------------
/** Constructor of RegularFace.
* \param ttf \ref FaceTTF for RegularFace to use.
*/
RegularFace::RegularFace(FaceTTF* ttf) : FontWithFace("RegularFace", ttf)
{
} // RegularFace

View File

@ -23,11 +23,12 @@
class FaceTTF;
/** A font which uses regular TTFs to render most text in STK.
* \ingroup font
*/
class RegularFace : public FontWithFace
{
private:
virtual bool supportLazyLoadChar() const OVERRIDE { return true; }
// ------------------------------------------------------------------------
virtual unsigned int getGlyphPageSize() const OVERRIDE { return 512; }
// ------------------------------------------------------------------------
virtual float getScalingFactorOne() const OVERRIDE { return 0.7f; }
@ -39,8 +40,6 @@ public:
// ------------------------------------------------------------------------
RegularFace(FaceTTF* ttf);
// ------------------------------------------------------------------------
virtual ~RegularFace() {}
// ------------------------------------------------------------------------
virtual void init() OVERRIDE;
// ------------------------------------------------------------------------
virtual void reset() OVERRIDE;

View File

@ -34,14 +34,14 @@
// ============================================================================
class Primitive2DList : public TextureShader<Primitive2DList, 1>
class Primitive2DList : public TextureShader<Primitive2DList, 1, float>
{
public:
Primitive2DList()
{
loadProgram(OBJECT, GL_VERTEX_SHADER, "primitive2dlist.vert",
GL_FRAGMENT_SHADER, "transparent.frag");
assignUniforms();
assignUniforms("custom_alpha");
assignSamplerNames(0, "tex", ST_BILINEAR_FILTERED);
} // Primitive2DList
}; //Primitive2DList
@ -703,7 +703,7 @@ void draw2DVertexPrimitiveList(video::ITexture *tex, const void* vertices,
VertexUtils::bindVertexArrayAttrib(vType);
Primitive2DList::getInstance()->use();
Primitive2DList::getInstance()->setUniforms();
Primitive2DList::getInstance()->setUniforms(1.0f);
compressTexture(tex, false);
Primitive2DList::getInstance()->setTextureUnits(getTextureGLuint(tex));
glDrawElements(GL_TRIANGLE_FAN, primitiveCount, GL_UNSIGNED_SHORT, 0);

View File

@ -245,8 +245,11 @@ void Camera::setMode(Mode mode)
{
Vec3 start_offset(0, 1.6f, -3);
Vec3 current_position = m_kart->getTrans()(start_offset);
Vec3 target_position = m_kart->getTrans()(Vec3(0, 0, 1));
// Don't set position and target the same, otherwise
// nan values will be calculated in ViewArea of camera
m_camera->setPosition(current_position.toIrrVector());
m_camera->setTarget(m_camera->getPosition());
m_camera->setTarget(target_position.toIrrVector());
}
m_mode = mode;
@ -291,9 +294,9 @@ void Camera::setInitialTransform()
// direction till smoothMoveCamera has corrected this. Setting target
// to position doesn't make sense, but smoothMoves will adjust the
// value before the first frame is rendered
m_camera->setTarget(m_camera->getPosition());
Vec3 target_position = m_kart->getTrans()(Vec3(0, 0, 1));
m_camera->setTarget(target_position.toIrrVector());
m_camera->setRotation(core::vector3df(0, 0, 0));
m_camera->setRotation( core::vector3df( 0.0f, 0.0f, 0.0f ) );
m_camera->setFOV(m_fov);
} // setInitialTransform

View File

@ -20,7 +20,7 @@
#include "karts/abstract_kart.hpp"
#include "karts/kart_properties.hpp"
#include "tracks/quad_graph.hpp"
#include "tracks/drive_graph.hpp"
#include "ICameraSceneNode.h"
@ -62,7 +62,7 @@ void CameraEnd::readEndCamera(const XMLNode &root)
unsigned int index = i;
// In reverse mode, reverse the order in which the
// end cameras are read.
if(QuadGraph::get()->isReverse())
if(DriveGraph::get() != NULL && DriveGraph::get()->isReverse())
index = root.getNumNodes() - 1 - i;
const XMLNode *node = root.getNode(index);
EndCameraInformation eci;

View File

@ -81,7 +81,7 @@ void CameraNormal::smoothMoveCamera(float dt)
const KartProperties *kp = m_kart->getKartProperties();
float max_increase_with_zipper = kp->getZipperMaxSpeedIncrease();
float max_speed_without_zipper = kp->getEngineMaxSpeed();
float current_speed = m_kart->getSpeed();
float current_speed = m_kart->getSmoothedSpeed();
const Skidding *ks = m_kart->getSkidding();
float skid_factor = ks->getVisualSkidRotation();
@ -101,16 +101,15 @@ void CameraNormal::smoothMoveCamera(float dt)
Vec3 m_kart_camera_position_with_offset = m_kart->getTrans()(camera_offset);
// next target
core::vector3df current_target = m_kart->getXYZ().toIrrVector();
current_target.Y += 0.5f;
Vec3 current_target = m_kart->getTrans()(Vec3(0, 0.5f, 0));
// new required position of camera
core::vector3df wanted_position = m_kart_camera_position_with_offset.toIrrVector();
float f = 5.0f;
if ((m_kart->getSpeed() > 5 ) || (m_kart->getSpeed() < 0 ))
if ((current_speed > 5 ) || (current_speed < 0 ))
{
f = m_kart->getSpeed()>0 ? m_kart->getSpeed()/3 + 1.0f
: -1.5f * m_kart->getSpeed() + 2.0f;
f = current_speed >0 ? current_speed/3 + 1.0f
: -1.5f * current_speed + 2.0f;
}
current_position += (wanted_position - current_position) * (dt *f);
@ -128,7 +127,7 @@ void CameraNormal::smoothMoveCamera(float dt)
if(getMode()!=CM_FALLING)
m_camera->setPosition(current_position);
m_camera->setTarget(current_target);//set new target
m_camera->setTarget(current_target.toIrrVector());//set new target
assert(!std::isnan(m_camera->getPosition().X));
assert(!std::isnan(m_camera->getPosition().Y));
@ -252,8 +251,7 @@ void CameraNormal::positionCamera(float dt, float above_kart, float cam_angle,
float side_way, float distance, float smoothing)
{
Vec3 wanted_position;
Vec3 wanted_target = m_kart->getXYZ();
wanted_target.setY(wanted_target.getY() + above_kart);
Vec3 wanted_target = m_kart->getTrans()(Vec3(0, above_kart, 0));
float tan_up = tan(cam_angle);
Vec3 relative_position(side_way,

View File

@ -49,6 +49,12 @@ void CentralVideoSettings::init()
hasUBO = false;
hasExplicitAttribLocation = false;
hasGS = false;
hasTextureFilterAnisotropic = false;
#if defined(USE_GLES2)
hasBGRA = false;
hasColorBufferFloat = false;
#endif
m_GI_has_artifact = false;
m_need_rh_workaround = false;
@ -84,7 +90,7 @@ void CentralVideoSettings::init()
std::string card((char*)(glGetString(GL_RENDERER)));
GraphicsRestrictions::init(driver, card);
#if !defined(USE_GLES2)
#if !defined(USE_GLES2)
if (hasGLExtension("GL_AMD_vertex_shader_layer")) {
hasVSLayer = true;
Log::info("GLDriver", "AMD Vertex Shader Layer Present");
@ -165,6 +171,11 @@ void CentralVideoSettings::init()
hasExplicitAttribLocation = true;
Log::info("GLDriver", "ARB Explicit Attrib Location Present");
}
if (!GraphicsRestrictions::isDisabled(GraphicsRestrictions::GR_TEXTURE_FILTER_ANISOTROPIC) &&
hasGLExtension("GL_EXT_texture_filter_anisotropic")) {
hasTextureFilterAnisotropic = true;
Log::info("GLDriver", "EXT Texture Filter Anisotropic Present");
}
if (!GraphicsRestrictions::isDisabled(GraphicsRestrictions::GR_GEOMETRY_SHADER) &&
(m_gl_major_version > 3 || (m_gl_major_version == 3 && m_gl_minor_version >= 2))) {
hasGS = true;
@ -218,6 +229,21 @@ void CentralVideoSettings::init()
hasAtomics = true;
hasSSBO = true;
}
if (!GraphicsRestrictions::isDisabled(GraphicsRestrictions::GR_TEXTURE_FORMAT_BGRA8888) &&
(hasGLExtension("GL_IMG_texture_format_BGRA8888") ||
hasGLExtension("GL_EXT_texture_format_BGRA8888")))
{
hasBGRA = true;
Log::info("GLDriver", "EXT texture format BGRA8888 Present");
}
if (!GraphicsRestrictions::isDisabled(GraphicsRestrictions::GR_COLOR_BUFFER_FLOAT) &&
hasGLExtension("GL_EXT_color_buffer_float"))
{
hasColorBufferFloat = true;
Log::info("GLDriver", "EXT Color Buffer Float Present");
}
#endif
}
}
@ -337,6 +363,23 @@ bool CentralVideoSettings::isARBMultiDrawIndirectUsable() const
return hasMultiDrawIndirect;
}
bool CentralVideoSettings::isEXTTextureFilterAnisotropicUsable() const
{
return hasTextureFilterAnisotropic;
}
#if defined(USE_GLES2)
bool CentralVideoSettings::isEXTTextureFormatBGRA8888Usable() const
{
return hasBGRA;
}
bool CentralVideoSettings::isEXTColorBufferFloatUsable() const
{
return hasColorBufferFloat;
}
#endif
bool CentralVideoSettings::supportsShadows() const
{
return isARBGeometryShadersUsable() && isARBUniformBufferObjectUsable() && isARBExplicitAttribLocationUsable();

View File

@ -42,6 +42,12 @@ private:
bool hasSSBO;
bool hasImageLoadStore;
bool hasMultiDrawIndirect;
bool hasTextureFilterAnisotropic;
#if defined(USE_GLES2)
bool hasBGRA;
bool hasColorBufferFloat;
#endif
bool m_need_rh_workaround;
bool m_need_srgb_workaround;
@ -75,6 +81,12 @@ public:
bool isARBImageLoadStoreUsable() const;
bool isARBMultiDrawIndirectUsable() const;
bool isARBExplicitAttribLocationUsable() const;
bool isEXTTextureFilterAnisotropicUsable() const;
#if defined(USE_GLES2)
bool isEXTTextureFormatBGRA8888Usable() const;
bool isEXTColorBufferFloatUsable() const;
#endif
// Are all required extensions available for feature support

View File

@ -27,32 +27,8 @@
#include "graphics/vao_manager.hpp"
#include <irrlicht.h>
#include <array>
#include <functional>
#include <unordered_map>
class MeshRenderInfoHash
{
public:
size_t operator() (const std::pair<scene::IMeshBuffer*, RenderInfo*> &p) const
{
return (std::hash<scene::IMeshBuffer*>()(p.first) ^
(std::hash<RenderInfo*>()(p.second) << 1));
}
};
struct MeshRenderInfoEquals : std::binary_function
<const std::pair<scene::IMeshBuffer*, RenderInfo*>&,
const std::pair<scene::IMeshBuffer*, RenderInfo*>&, bool>
{
result_type operator() (first_argument_type lhs,
second_argument_type rhs) const
{
return (lhs.first == rhs.first) &&
(lhs.second == rhs.second);
}
};
struct InstanceList
{
GLMesh *m_mesh;

View File

@ -50,6 +50,8 @@ void DrawCalls::clearLists()
{
ListBlendTransparent::getInstance()->clear();
ListAdditiveTransparent::getInstance()->clear();
ListGhostKart::getInstance()->clear();
ListGhostKartTangents::getInstance()->clear();
ListBlendTransparentFog::getInstance()->clear();
ListAdditiveTransparentFog::getInstance()->clear();
ListDisplacement::getInstance()->clear();
@ -159,10 +161,24 @@ void DrawCalls::handleSTKCommon(scene::ISceneNode *Node,
else
{
for (GLMesh *mesh : node->TransparentMesh[TM_DEFAULT])
pushVector(ListBlendTransparent::getInstance(), mesh, Node->getAbsoluteTransformation(), mesh->TextureMatrix);
pushVector(ListBlendTransparent::getInstance(), mesh, Node->getAbsoluteTransformation(), mesh->TextureMatrix, 1.0f);
for (GLMesh *mesh : node->TransparentMesh[TM_ADDITIVE])
pushVector(ListAdditiveTransparent::getInstance(), mesh, Node->getAbsoluteTransformation(), mesh->TextureMatrix);
pushVector(ListAdditiveTransparent::getInstance(), mesh, Node->getAbsoluteTransformation(), mesh->TextureMatrix, 1.0f);
}
// Use sun color to determine custom alpha for ghost karts
float custom_alpha = 1.0f;
if (World::getWorld())
{
const video::SColor& c = World::getWorld()->getTrack()->getSunColor();
float y = 0.2126f * c.getRed() + 0.7152f * c.getGreen() + 0.0722f * c.getBlue();
custom_alpha = y > 128.0f ? 0.5f : 0.35f;
}
for (GLMesh *mesh : node->TransparentMesh[TM_GHOST_KART])
pushVector(ListGhostKart::getInstance(), mesh, Node->getAbsoluteTransformation(), mesh->TextureMatrix, custom_alpha);
for (GLMesh *mesh : node->TransparentMesh[TM_GHOST_KART_TANGENTS])
pushVector(ListGhostKartTangents::getInstance(), mesh, Node->getAbsoluteTransformation(), mesh->TextureMatrix, custom_alpha);
for (GLMesh *mesh : node->TransparentMesh[TM_DISPLACEMENT])
pushVector(ListDisplacement::getInstance(), mesh, Node->getAbsoluteTransformation());
@ -532,10 +548,13 @@ void DrawCalls::prepareDrawCalls( ShadowMatrices& shadow_matrices,
PROFILER_PUSH_CPU_MARKER("- Sync Stall", 0xFF, 0x0, 0x0);
GLenum reason = glClientWaitSync(m_sync, GL_SYNC_FLUSH_COMMANDS_BIT, 0);
while (reason != GL_ALREADY_SIGNALED)
if (reason != GL_ALREADY_SIGNALED)
{
if (reason == GL_WAIT_FAILED) break;
reason = glClientWaitSync(m_sync, GL_SYNC_FLUSH_COMMANDS_BIT, 1000000);
do
{
reason = glClientWaitSync(m_sync, GL_SYNC_FLUSH_COMMANDS_BIT, 1000000);
}
while (reason == GL_TIMEOUT_EXPIRED);
}
glDeleteSync(m_sync);
PROFILER_POP_CPU_MARKER();

View File

@ -1,4 +1,4 @@
// SuperTuxKart - a fun racing game with go-kart
// SuperTuxKart - a fun racing game with go-kart
// Copyright (C) 2015 SuperTuxKart-Team
//
// This program is free software; you can redistribute it and/or
@ -241,15 +241,24 @@ void AbstractGeometryPasses::renderTransparent(const DrawCalls& draw_calls,
const FrameBuffer& colors_framebuffer,
const PostProcessing* post_processing)
{
glEnable(GL_DEPTH_TEST);
glDepthMask(GL_FALSE);
glEnable(GL_BLEND);
glBlendEquation(GL_FUNC_ADD);
glDisable(GL_CULL_FACE);
irr_driver->setPhase(TRANSPARENT_PASS);
glEnable(GL_DEPTH_TEST);
glDepthMask(GL_TRUE);
glEnable(GL_BLEND);
glBlendEquation(GL_FUNC_ADD);
glEnable(GL_CULL_FACE);
glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
renderTransparenPass<Shaders::TransparentShader, video::EVT_STANDARD, 3, 2, 1>(
TexUnits(RenderGeometry::TexUnit(0, true)),
ListGhostKart::getInstance());
renderTransparenPass<Shaders::TransparentShader, video::EVT_TANGENTS, 3, 2, 1>(
TexUnits(RenderGeometry::TexUnit(0, true)),
ListGhostKartTangents::getInstance());
glDepthMask(GL_FALSE);
glDisable(GL_CULL_FACE);
draw_calls.renderImmediateDrawList();
if (CVS->isARBBaseInstanceUsable())
@ -263,20 +272,20 @@ void AbstractGeometryPasses::renderTransparent(const DrawCalls& draw_calls,
TexUnits(RenderGeometry::TexUnit(0, true)),
ListBlendTransparentFog::getInstance());
glBlendFunc(GL_ONE, GL_ONE);
renderTransparenPass<Shaders::TransparentFogShader,
renderTransparenPass<Shaders::TransparentFogShader,
video::EVT_STANDARD, 8, 7, 6, 5, 4, 3, 2, 1>(
TexUnits(RenderGeometry::TexUnit(0, true)),
TexUnits(RenderGeometry::TexUnit(0, true)),
ListAdditiveTransparentFog::getInstance());
}
else
{
glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
renderTransparenPass<Shaders::TransparentShader,
video::EVT_STANDARD, 2, 1>(
video::EVT_STANDARD, 3, 2, 1>(
TexUnits(RenderGeometry::TexUnit(0, true)),
ListBlendTransparent::getInstance());
glBlendFunc(GL_ONE, GL_ONE);
renderTransparenPass<Shaders::TransparentShader, video::EVT_STANDARD, 2, 1>(
renderTransparenPass<Shaders::TransparentShader, video::EVT_STANDARD, 3, 2, 1>(
TexUnits(RenderGeometry::TexUnit(0, true)),
ListAdditiveTransparent::getInstance());
}

View File

@ -57,12 +57,18 @@ namespace GraphicsRestrictions
"TextureCompressionS3TC",
"AMDVertexShaderLayer",
"ExplicitAttribLocation",
"TextureFilterAnisotropic",
#if defined(USE_GLES2)
"TextureFormatBGRA8888",
"ColorBufferFloat",
#endif
"DriverRecentEnough",
"HighDefinitionTextures",
"AdvancedPipeline",
"FramebufferSRGBWorking",
"FramebufferSRGBCapable",
"GI",
"ForceLegacyDevice"
};
} // namespace Private
using namespace Private;
@ -272,7 +278,7 @@ class Rule : public NoCopy
{
private:
/** Operators to test for a card. */
enum {CARD_IS, CARD_CONTAINS} m_card_test;
enum {CARD_IGNORE, CARD_IS, CARD_CONTAINS} m_card_test;
/** Name of the card for which this rule applies. */
std::string m_card_name;
@ -293,6 +299,8 @@ public:
Rule(const XMLNode *rule)
{
m_version_test = VERSION_IGNORE;
m_card_test = CARD_IGNORE;
if(rule->get("is", &m_card_name))
{
m_card_test = CARD_IS;
@ -340,7 +348,7 @@ public:
// -----------
if(m_os.size()>0)
{
#ifdef __linux__
#if defined(__linux__) && !defined(ANDROID)
if(m_os!="linux") return false;
#endif
#ifdef WIN32
@ -351,6 +359,9 @@ public:
#endif
#ifdef BSD
if(m_os!="bsd") return false;
#endif
#ifdef ANDROID
if(m_os!="android") return false;
#endif
} // m_os.size()>0
@ -358,6 +369,7 @@ public:
// -------------
switch(m_card_test)
{
case CARD_IGNORE: break; // always true
case CARD_IS:
if(card!=m_card_name) return false;
break;

View File

@ -32,7 +32,7 @@ namespace GraphicsRestrictions
* the variable m_names_of_restrictions in the cpp file contains the
* string representation used in the XML files. Any change to this
* type declaration needs a change in that variable as well. */
enum GraphicsRestrictionsType
enum GraphicsRestrictionsType
{
GR_UNIFORM_BUFFER_OBJECT,
GR_GEOMETRY_SHADER,
@ -51,12 +51,18 @@ namespace GraphicsRestrictions
GR_EXT_TEXTURE_COMPRESSION_S3TC,
GR_AMD_VERTEX_SHADER_LAYER,
GR_EXPLICIT_ATTRIB_LOCATION,
GR_TEXTURE_FILTER_ANISOTROPIC,
#if defined(USE_GLES2)
GR_TEXTURE_FORMAT_BGRA8888,
GR_COLOR_BUFFER_FLOAT,
#endif
GR_DRIVER_RECENT_ENOUGH,
GR_HIGHDEFINITION_TEXTURES,
GR_ADVANCED_PIPELINE,
GR_FRAMEBUFFER_SRGB_WORKING,
GR_FRAMEBUFFER_SRGB_CAPABLE,
GR_GI,
GR_FORCE_LEGACY_DEVICE,
GR_COUNT /** MUST be last entry. */
} ;

View File

@ -143,6 +143,7 @@ IrrDriver::~IrrDriver()
{
assert(m_device != NULL);
cleanUnicolorTextures();
m_device->drop();
m_device = NULL;
m_modes.clear();
@ -329,7 +330,7 @@ void IrrDriver::createListOfVideoModes()
void IrrDriver::initDevice()
{
SIrrlichtCreationParameters params;
// If --no-graphics option was used, the null device can still be used.
if (!ProfileWorld::isNoGraphics())
{
@ -412,7 +413,7 @@ void IrrDriver::initDevice()
m_device->drop();
m_device = NULL;
params.ForceLegacyDevice = (UserConfigParams::m_force_legacy_device ||
params.ForceLegacyDevice = (UserConfigParams::m_force_legacy_device ||
UserConfigParams::m_gamepad_visualisation);
// Try 32 and, upon failure, 24 then 16 bit per pixels
@ -437,9 +438,9 @@ void IrrDriver::initDevice()
core::dimension2du(UserConfigParams::m_width,
UserConfigParams::m_height);
params.HandleSRGB = true;
params.ShadersPath = (file_manager->getShadersDir() +
params.ShadersPath = (file_manager->getShadersDir() +
"irrlicht/").c_str();
/*
switch ((int)UserConfigParams::m_antialiasing)
{
@ -500,29 +501,54 @@ void IrrDriver::initDevice()
{
Log::fatal("irr_driver", "Couldn't initialise irrlicht device. Quitting.\n");
}
CVS->init();
bool recreate_device = false;
// Some drivers are able to create OpenGL 3.1 context, but shader-based
// pipeline doesn't work for them. For example some radeon drivers
// support only GLSL 1.3 and it causes STK to crash. We should force to use
// fixed pipeline in this case.
if (!ProfileWorld::isNoGraphics() &&
GraphicsRestrictions::isDisabled(GraphicsRestrictions::GR_FORCE_LEGACY_DEVICE))
{
Log::warn("irr_driver", "Driver doesn't support shader-based pipeline. "
"Re-creating device to workaround the issue.");
params.ForceLegacyDevice = true;
recreate_device = true;
}
// This is the ugly hack for intel driver on linux, which doesn't
// use sRGB-capable visual, even if we request it. This causes
// the screen to be darker than expected. It affects mesa 10.6 and newer.
// Though we are able to force to use the proper format on mesa side by
// the screen to be darker than expected. It affects mesa 10.6 and newer.
// Though we are able to force to use the proper format on mesa side by
// setting WithAlphaChannel parameter.
if (!ProfileWorld::isNoGraphics() && CVS->needsSRGBCapableVisualWorkaround())
else if (CVS->needsSRGBCapableVisualWorkaround())
{
Log::warn("irr_driver", "Created visual is not sRGB-capable. "
"Re-creating device to workaround the issue.");
m_device->closeDevice();
m_device->drop();
params.WithAlphaChannel = true;
recreate_device = true;
}
if (!ProfileWorld::isNoGraphics() && recreate_device)
{
m_device->closeDevice();
m_device->clearSystemMessages();
m_device->run();
m_device->drop();
m_device = createDeviceEx(params);
if(!m_device)
{
Log::fatal("irr_driver", "Couldn't initialise irrlicht device. Quitting.\n");
}
CVS->init();
}
m_scene_manager = m_device->getSceneManager();
@ -540,7 +566,7 @@ void IrrDriver::initDevice()
(UserConfigParams::m_shadows_resolution < 512 ||
UserConfigParams::m_shadows_resolution > 2048))
{
Log::warn("irr_driver",
Log::warn("irr_driver",
"Invalid value for UserConfigParams::m_shadows_resolution : %i",
(int)UserConfigParams::m_shadows_resolution);
UserConfigParams::m_shadows_resolution = 0;
@ -646,7 +672,7 @@ void IrrDriver::setMaxTextureSize()
{
io::IAttributes &att = m_video_driver->getNonConstDriverAttributes();
att.setAttribute("MAX_TEXTURE_SIZE", core::dimension2du(
UserConfigParams::m_max_texture_size,
UserConfigParams::m_max_texture_size,
UserConfigParams::m_max_texture_size));
}
} // setMaxTextureSize
@ -674,7 +700,7 @@ void IrrDriver::createSunInterposer()
mb->getMaterial().setTexture(7,
getUnicolorTexture(video::SColor(0, 0, 0, 0)));
}
m_sun_interposer = new STKMeshSceneNode(sphere,
m_sun_interposer = new STKMeshSceneNode(sphere,
m_scene_manager->getRootSceneNode(),
NULL, -1, "sun_interposer");
@ -816,11 +842,11 @@ void IrrDriver::applyResolutionSettings()
UserConfigParams::m_prev_height) );
m_video_driver->endScene();
track_manager->removeAllCachedData();
attachment_manager->removeTextures();
delete attachment_manager;
projectile_manager->removeTextures();
ItemManager::removeTextures();
kart_properties_manager->unloadAllKarts();
powerup_manager->unloadPowerups();
delete powerup_manager;
Referee::cleanup();
ParticleKindManager::get()->cleanup();
delete input_manager;
@ -843,11 +869,13 @@ void IrrDriver::applyResolutionSettings()
ShaderBase::updateShaders();
VAOManager::getInstance()->kill();
resetTextureTable();
cleanUnicolorTextures();
// initDevice will drop the current device.
if (CVS->isGLSL())
{
Shaders::destroy();
}
delete m_renderer;
initDevice();
font_manager = new FontManager();
@ -860,6 +888,8 @@ void IrrDriver::applyResolutionSettings()
material_manager->loadMaterial();
input_manager = new InputManager ();
input_manager->setMode(InputManager::MENU);
powerup_manager = new PowerupManager();
attachment_manager = new AttachmentManager();
GUIEngine::addLoadingIcon(
irr_driver->getTexture(file_manager
@ -997,28 +1027,6 @@ scene::IMesh *IrrDriver::getMesh(const std::string &filename)
return am->getMesh(0);
} // getMesh
// ----------------------------------------------------------------------------
/** Create a skinned mesh which has copied all meshbuffers and joints of the
* original mesh. Note, that this will not copy any other information like
* joints data.
* \param mesh Original mesh
* \return Newly created skinned mesh. You should call drop() when you don't
* need it anymore.
*/
scene::IAnimatedMesh *IrrDriver::copyAnimatedMesh(scene::IAnimatedMesh *orig)
{
using namespace scene;
CSkinnedMesh *mesh = dynamic_cast<CSkinnedMesh*>(orig);
if (!mesh)
{
Log::error("copyAnimatedMesh", "Given mesh was not a skinned mesh.");
return NULL;
}
scene::IAnimatedMesh* out = mesh->clone();
return out;
} // copyAnimatedMesh
// ----------------------------------------------------------------------------
/** Sets the material flags in this mesh depending on the settings in
* material_manager.
@ -1121,7 +1129,7 @@ scene::IMeshSceneNode *IrrDriver::addSphere(float radius,
{
scene::IMesh *mesh = m_scene_manager->getGeometryCreator()
->createSphereMesh(radius);
mesh->setMaterialFlag(video::EMF_COLOR_MATERIAL, true);
video::SMaterial &m = mesh->getMeshBuffer(0)->getMaterial();
m.AmbientColor = color;
@ -1164,7 +1172,8 @@ scene::IMeshSceneNode *IrrDriver::addMesh(scene::IMesh *mesh,
const std::string& debug_name,
scene::ISceneNode *parent,
RenderInfo* render_info,
bool all_parts_colorized)
bool all_parts_colorized,
int frame_for_mesh)
{
if (!CVS->isGLSL())
return m_scene_manager->addMeshSceneNode(mesh, parent);
@ -1172,14 +1181,15 @@ scene::IMeshSceneNode *IrrDriver::addMesh(scene::IMesh *mesh,
if (!parent)
parent = m_scene_manager->getRootSceneNode();
scene::IMeshSceneNode* node = new STKMeshSceneNode(mesh, parent,
scene::IMeshSceneNode* node = new STKMeshSceneNode(mesh, parent,
m_scene_manager, -1,
debug_name,
core::vector3df(0, 0, 0),
core::vector3df(0, 0, 0),
core::vector3df(1.0f, 1.0f, 1.0f),
true, render_info,
all_parts_colorized);
all_parts_colorized,
frame_for_mesh);
node->drop();
return node;
@ -1211,7 +1221,7 @@ scene::ISceneNode *IrrDriver::addBillboard(const core::dimension2d< f32 > size,
if (!parent)
parent = m_scene_manager->getRootSceneNode();
node = new STKBillboard(parent, m_scene_manager, -1,
node = new STKBillboard(parent, m_scene_manager, -1,
vector3df(0., 0., 0.), size);
node->drop();
}
@ -1424,7 +1434,7 @@ scene::ISceneNode *IrrDriver::addSkyBox(const std::vector<video::ITexture*> &tex
assert(texture.size() == 6);
m_renderer->addSkyBox(texture, spherical_harmonics_textures);
return m_scene_manager->addSkyBoxSceneNode(texture[0], texture[1],
texture[2], texture[3],
texture[4], texture[5]);
@ -1534,7 +1544,7 @@ std::string IrrDriver::getSmallerTexture(const std::string& filename)
{
core::dimension2d<u32> dim = img->getDimension();
core::dimension2d<u32> new_dim; // Dimension of the cached texture
const int scale_factor = 2;
const unsigned scale_factor = 2;
// Resize the texture only if it can be done properly
if (dim.Width < scale_factor || dim.Height < scale_factor)
new_dim = dim;
@ -1982,13 +1992,13 @@ void IrrDriver::update(float dt)
if (world)
{
m_renderer->render(dt);
GUIEngine::Screen* current_screen = GUIEngine::getCurrentScreen();
if (current_screen != NULL && current_screen->needs3D())
{
GUIEngine::render(dt);
}
if (world->getPhysics() != NULL)
{
IrrDebugDrawer* debug_drawer = world->getPhysics()->getDebugDrawer();
@ -2007,7 +2017,7 @@ void IrrDriver::update(float dt)
m_video_driver->endScene();
}
if (m_request_screenshot) doScreenShot();
// Enable this next print statement to get render information printed
@ -2070,7 +2080,6 @@ bool IrrDriver::supportsSplatting()
}
// ----------------------------------------------------------------------------
void IrrDriver::applyObjectPassShader(scene::ISceneNode * const node, bool rimlit)
{
if (!CVS->isGLSL())
@ -2083,9 +2092,9 @@ void IrrDriver::applyObjectPassShader(scene::ISceneNode * const node, bool rimli
const u32 mcount = node->getMaterialCount();
u32 i;
const video::E_MATERIAL_TYPE ref =
const video::E_MATERIAL_TYPE ref =
Shaders::getShader(rimlit ? ES_OBJECTPASS_RIMLIT : ES_OBJECTPASS_REF);
const video::E_MATERIAL_TYPE pass =
const video::E_MATERIAL_TYPE pass =
Shaders::getShader(rimlit ? ES_OBJECTPASS_RIMLIT : ES_OBJECTPASS);
const video::E_MATERIAL_TYPE origref = Shaders::getShader(ES_OBJECTPASS_REF);
@ -2112,7 +2121,7 @@ void IrrDriver::applyObjectPassShader(scene::ISceneNode * const node, bool rimli
for (i = 0; i < mcount; i++)
{
video::SMaterial &nodemat = node->getMaterial(i);
video::SMaterial &mbmat = mesh ? mesh->getMeshBuffer(i)->getMaterial()
video::SMaterial &mbmat = mesh ? mesh->getMeshBuffer(i)->getMaterial()
: nodemat;
video::SMaterial *mat = &nodemat;
@ -2166,8 +2175,6 @@ scene::ISceneNode *IrrDriver::addLight(const core::vector3df &pos,
else
light = new SunNode(m_scene_manager, parent, r, g, b);
light->grab();
light->setPosition(pos);
light->updateAbsolutePosition();
@ -2197,9 +2204,7 @@ scene::ISceneNode *IrrDriver::addLight(const core::vector3df &pos,
void IrrDriver::clearLights()
{
u32 i;
const u32 max = (int)m_lights.size();
for (i = 0; i < max; i++)
for (unsigned int i = 0; i < m_lights.size(); i++)
{
m_lights[i]->drop();
}

View File

@ -72,7 +72,6 @@ class ShadowImportance;
class ShadowMatrices;
class RenderTarget;
/**
* \brief class that creates the irrLicht device and offers higher-level
* ways to manage the 3D scene
@ -215,7 +214,6 @@ public:
void setAllMaterialFlags(scene::IMesh *mesh) const;
scene::IAnimatedMesh *getAnimatedMesh(const std::string &name);
scene::IMesh *getMesh(const std::string &name);
scene::IAnimatedMesh *copyAnimatedMesh(scene::IAnimatedMesh *orig);
video::ITexture *applyMask(video::ITexture* texture,
const std::string& mask_path);
void displayFPS();
@ -251,7 +249,8 @@ public:
const std::string& debug_name,
scene::ISceneNode *parent = NULL,
RenderInfo* render_info = NULL,
bool all_parts_colorized = false);
bool all_parts_colorized = false,
int frame_for_mesh = -1);
PerCameraNode *addPerCameraNode(scene::ISceneNode* node,
scene::ICameraSceneNode* cam,
scene::ISceneNode *parent = NULL);

View File

@ -740,6 +740,26 @@ void Material::setMaterialProperties(video::SMaterial *m, scene::IMeshBuffer* m
m->setTexture(7, colorization_mask_tex);
}
if (race_manager->getReverseTrack() &&
m_mirror_axis_when_reverse != ' ')
{
if (m_mirrorred_mesh_buffers.find((void*)mb) == m_mirrorred_mesh_buffers.end())
{
m_mirrorred_mesh_buffers[(void*)mb] = true;
//irr::video::S3DVertex* mbVertices = (video::S3DVertex*)mb->getVertices();
for (unsigned int i = 0; i < mb->getVertexCount(); i++)
{
core::vector2df &tc = mb->getTCoords(i);
if (m_mirror_axis_when_reverse == 'V')
tc.Y = 1 - tc.Y;
else
tc.X = 1 - tc.X;
}
}
} // reverse track and texture needs mirroring
switch (m_shader_type)
{
case SHADERTYPE_SOLID_UNLIT:
@ -986,21 +1006,6 @@ void Material::setMaterialProperties(video::SMaterial *m, scene::IMeshBuffer* m
}
#endif
if (race_manager->getReverseTrack() &&
m_mirror_axis_when_reverse != ' ')
{
//irr::video::S3DVertex* mbVertices = (video::S3DVertex*)mb->getVertices();
for (unsigned int i = 0; i < mb->getVertexCount(); i++)
{
core::vector2df &tc = mb->getTCoords(i);
if (m_mirror_axis_when_reverse == 'V')
tc.Y = 1 - tc.Y;
else
tc.X = 1 - tc.X;
}
} // reverse track and texture needs mirroring
} // setMaterialProperties
//-----------------------------------------------------------------------------

View File

@ -162,6 +162,12 @@ private:
* the direction. */
char m_mirror_axis_when_reverse;
/**
* Associated with m_mirror_axis_when_reverse, to avoid mirroring the same material twice
* (setAllMaterialFlags can be called multiple times on the same mesh buffer)
*/
std::map<void*, bool> m_mirrorred_mesh_buffers;
ParticleKind* m_particles_effects[EMIT_KINDS_COUNT];
/** For normal maps */

View File

@ -28,6 +28,7 @@
#include <irrlicht.h>
#include <IMesh.h>
#include <IMeshBuffer.h>
#include <SSkinMeshBuffer.h>
void MeshTools::minMax3D(scene::IMesh* mesh, Vec3 *min, Vec3 *max) {
@ -444,29 +445,86 @@ scene::IMesh* MeshTools::createMeshWithTangents(scene::IMesh* mesh,
clone->recalculateBoundingBox();
if (calculate_tangents)
recalculateTangents(clone, recalculate_normals, smooth, angle_weighted);
int mbcount = clone->getMeshBufferCount();
for (int i = 0; i < mbcount; i++)
{
scene::IMeshBuffer* mb = clone->getMeshBuffer(i);
for (u32 t = 0; t < video::MATERIAL_MAX_TEXTURES; t++)
{
video::ITexture* texture = mb->getMaterial().TextureLayer[t].Texture;
if (texture != NULL)
texture->grab();
}
}
scene::IMeshCache* meshCache = irr_driver->getSceneManager()->getMeshCache();
io::SNamedPath path = meshCache->getMeshName(mesh);
irr_driver->removeMeshFromCache(mesh);
if (path.getPath() == "")
{
// This mesh is not in irrlicht cache, drop it directly
assert(mesh->getReferenceCount() == 1);
mesh->drop();
return clone;
}
else
{
// Cache the calcuated tangent mesh with path
irr_driver->removeMeshFromCache(mesh);
scene::SAnimatedMesh* amesh = new scene::SAnimatedMesh(clone);
clone->drop();
meshCache->addMesh(path, amesh);
if (World::getWorld())
{
irr_driver->grabAllTextures(amesh);
World::getWorld()->getTrack()->addCachedMesh(amesh);
return amesh;
}
amesh->drop();
return amesh;
}
scene::SAnimatedMesh* amesh = new scene::SAnimatedMesh(clone);
meshCache->addMesh(path, amesh);
World::getWorld()->getTrack()->addCachedMesh(amesh);
return clone;
}
void MeshTools::createSkinnedMeshWithTangents(scene::ISkinnedMesh* mesh,
bool(*predicate)(scene::IMeshBuffer*))
{
core::array<scene::SSkinMeshBuffer*>& all_mb = mesh->getMeshBuffers();
const int all_mb_size = all_mb.size();
for (int i = 0; i < all_mb_size; i++)
{
scene::SSkinMeshBuffer* mb = all_mb[i];
if (mb && predicate(mb))
{
mb->convertToTangents();
const int index_count = mb->getIndexCount();
uint16_t* idx = mb->getIndices();
video::S3DVertexTangents* v =
(video::S3DVertexTangents*)mb->getVertices();
for (int i = 0; i < index_count; i += 3)
{
calculateTangents(
v[idx[i+0]].Normal,
v[idx[i+0]].Tangent,
v[idx[i+0]].Binormal,
v[idx[i+0]].Pos,
v[idx[i+1]].Pos,
v[idx[i+2]].Pos,
v[idx[i+0]].TCoords,
v[idx[i+1]].TCoords,
v[idx[i+2]].TCoords);
calculateTangents(
v[idx[i+1]].Normal,
v[idx[i+1]].Tangent,
v[idx[i+1]].Binormal,
v[idx[i+1]].Pos,
v[idx[i+2]].Pos,
v[idx[i+0]].Pos,
v[idx[i+1]].TCoords,
v[idx[i+2]].TCoords,
v[idx[i+0]].TCoords);
calculateTangents(
v[idx[i+2]].Normal,
v[idx[i+2]].Tangent,
v[idx[i+2]].Binormal,
v[idx[i+2]].Pos,
v[idx[i+0]].Pos,
v[idx[i+1]].Pos,
v[idx[i+2]].TCoords,
v[idx[i+0]].TCoords,
v[idx[i+1]].TCoords);
}
}
}
}

View File

@ -21,7 +21,7 @@
namespace irr
{
namespace scene { class IMesh; class IMeshBuffer; }
namespace scene { class IMesh; class IMeshBuffer; class ISkinnedMesh; }
}
using namespace irr;
@ -37,8 +37,14 @@ namespace MeshTools
bool isNormalMap(scene::IMeshBuffer* mb);
// Copied from irrlicht
scene::IMesh* createMeshWithTangents(scene::IMesh* mesh, bool(*predicate)(scene::IMeshBuffer*),
bool recalculateNormals = false, bool smooth = false, bool angleWeighted = false, bool calculateTangents = true);
scene::IMesh* createMeshWithTangents(scene::IMesh* mesh,
bool(*predicate)(scene::IMeshBuffer*), bool recalculateNormals = false,
bool smooth = false, bool angleWeighted = false,
bool calculateTangents = true);
void createSkinnedMeshWithTangents(scene::ISkinnedMesh* mesh,
bool(*predicate)(scene::IMeshBuffer*));
} // MeshTools
#endif

View File

@ -78,45 +78,70 @@ RTT::RTT(size_t width, size_t height)
// All RTTs are currently RGBA16F mostly with stencil. The four tmp RTTs are the same size
// as the screen, for use in post-processing.
GLint rgba_internal_format = GL_RGBA16F;
GLint rgba_format = GL_BGRA;
GLint red_internal_format = GL_R16F;
GLint red32_internal_format = GL_R32F;
GLint red_format = GL_RED;
GLint rgb_format = GL_BGR;
GLint diffuse_specular_internal_format = GL_R11F_G11F_B10F;
GLint type = GL_FLOAT;
#if defined(USE_GLES2)
if (!CVS->isEXTColorBufferFloatUsable())
{
rgba_internal_format = GL_RGBA8;
rgba_format = GL_RGBA;
red_internal_format = GL_R8;
red32_internal_format = GL_R8;
red_format = GL_RED;
rgb_format = GL_RGB;
diffuse_specular_internal_format = GL_RGBA8;
type = GL_UNSIGNED_BYTE;
}
#endif
RenderTargetTextures[RTT_TMP1] = generateRTT(res, GL_RGBA16F, GL_BGRA, GL_FLOAT);
RenderTargetTextures[RTT_TMP2] = generateRTT(res, GL_RGBA16F, GL_BGRA, GL_FLOAT);
RenderTargetTextures[RTT_TMP3] = generateRTT(res, GL_RGBA16F, GL_BGRA, GL_FLOAT);
RenderTargetTextures[RTT_TMP4] = generateRTT(res, GL_R16F, GL_RED, GL_FLOAT);
RenderTargetTextures[RTT_LINEAR_DEPTH] = generateRTT(res, GL_R32F, GL_RED, GL_FLOAT, linear_depth_mip_levels);
RenderTargetTextures[RTT_NORMAL_AND_DEPTH] = generateRTT(res, GL_RGBA16F, GL_RGBA, GL_FLOAT);
RenderTargetTextures[RTT_COLOR] = generateRTT(res, GL_RGBA16F, GL_BGRA, GL_FLOAT);
RenderTargetTextures[RTT_MLAA_COLORS] = generateRTT(res, GL_SRGB8_ALPHA8, GL_BGR, GL_UNSIGNED_BYTE);
RenderTargetTextures[RTT_MLAA_TMP] = generateRTT(res, GL_SRGB8_ALPHA8, GL_BGR, GL_UNSIGNED_BYTE);
RenderTargetTextures[RTT_MLAA_BLEND] = generateRTT(res, GL_SRGB8_ALPHA8, GL_BGR, GL_UNSIGNED_BYTE);
RenderTargetTextures[RTT_SSAO] = generateRTT(res, GL_R16F, GL_RED, GL_FLOAT);
RenderTargetTextures[RTT_DISPLACE] = generateRTT(res, GL_RGBA16F, GL_BGRA, GL_FLOAT);
RenderTargetTextures[RTT_DIFFUSE] = generateRTT(res, GL_R11F_G11F_B10F, GL_BGR, GL_FLOAT);
RenderTargetTextures[RTT_SPECULAR] = generateRTT(res, GL_R11F_G11F_B10F, GL_BGR, GL_FLOAT);
RenderTargetTextures[RTT_TMP1] = generateRTT(res, rgba_internal_format, rgba_format, type);
RenderTargetTextures[RTT_TMP2] = generateRTT(res, rgba_internal_format, rgba_format, type);
RenderTargetTextures[RTT_TMP3] = generateRTT(res, rgba_internal_format, rgba_format, type);
RenderTargetTextures[RTT_TMP4] = generateRTT(res, red_internal_format, red_format, type);
RenderTargetTextures[RTT_LINEAR_DEPTH] = generateRTT(res, red32_internal_format, red_format, type, linear_depth_mip_levels);
RenderTargetTextures[RTT_NORMAL_AND_DEPTH] = generateRTT(res, rgba_internal_format, GL_RGBA, type);
RenderTargetTextures[RTT_COLOR] = generateRTT(res, rgba_internal_format, rgba_format, type);
RenderTargetTextures[RTT_MLAA_COLORS] = generateRTT(res, GL_SRGB8_ALPHA8, rgb_format, GL_UNSIGNED_BYTE);
RenderTargetTextures[RTT_MLAA_TMP] = generateRTT(res, GL_SRGB8_ALPHA8, rgb_format, GL_UNSIGNED_BYTE);
RenderTargetTextures[RTT_MLAA_BLEND] = generateRTT(res, GL_SRGB8_ALPHA8, rgb_format, GL_UNSIGNED_BYTE);
RenderTargetTextures[RTT_SSAO] = generateRTT(res, red_internal_format, red_format, type);
RenderTargetTextures[RTT_DISPLACE] = generateRTT(res, rgba_internal_format, rgba_format, type);
RenderTargetTextures[RTT_DIFFUSE] = generateRTT(res, diffuse_specular_internal_format, rgb_format, type);
RenderTargetTextures[RTT_SPECULAR] = generateRTT(res, diffuse_specular_internal_format, rgb_format, type);
RenderTargetTextures[RTT_HALF1] = generateRTT(half, GL_RGBA16F, GL_BGRA, GL_FLOAT);
RenderTargetTextures[RTT_QUARTER1] = generateRTT(quarter, GL_RGBA16F, GL_BGRA, GL_FLOAT);
RenderTargetTextures[RTT_EIGHTH1] = generateRTT(eighth, GL_RGBA16F, GL_BGRA, GL_FLOAT);
RenderTargetTextures[RTT_HALF1_R] = generateRTT(half, GL_R16F, GL_RED, GL_FLOAT);
RenderTargetTextures[RTT_HALF1] = generateRTT(half, rgba_internal_format, rgba_format, type);
RenderTargetTextures[RTT_QUARTER1] = generateRTT(quarter, rgba_internal_format, rgba_format, type);
RenderTargetTextures[RTT_EIGHTH1] = generateRTT(eighth, rgba_internal_format, rgba_format, type);
RenderTargetTextures[RTT_HALF1_R] = generateRTT(half, red_internal_format, red_format, type);
RenderTargetTextures[RTT_HALF2] = generateRTT(half, GL_RGBA16F, GL_BGRA, GL_FLOAT);
RenderTargetTextures[RTT_QUARTER2] = generateRTT(quarter, GL_RGBA16F, GL_BGRA, GL_FLOAT);
RenderTargetTextures[RTT_EIGHTH2] = generateRTT(eighth, GL_RGBA16F, GL_BGRA, GL_FLOAT);
RenderTargetTextures[RTT_HALF2_R] = generateRTT(half, GL_R16F, GL_RED, GL_FLOAT);
RenderTargetTextures[RTT_HALF2] = generateRTT(half, rgba_internal_format, rgba_format, type);
RenderTargetTextures[RTT_QUARTER2] = generateRTT(quarter, rgba_internal_format, rgba_format, type);
RenderTargetTextures[RTT_EIGHTH2] = generateRTT(eighth, rgba_internal_format, rgba_format, type);
RenderTargetTextures[RTT_HALF2_R] = generateRTT(half, red_internal_format, red_format, type);
RenderTargetTextures[RTT_BLOOM_1024] = generateRTT(shadowsize0, GL_RGBA16F, GL_BGR, GL_FLOAT);
RenderTargetTextures[RTT_SCALAR_1024] = generateRTT(shadowsize0, GL_R32F, GL_RED, GL_FLOAT);
RenderTargetTextures[RTT_BLOOM_512] = generateRTT(shadowsize1, GL_RGBA16F, GL_BGR, GL_FLOAT);
RenderTargetTextures[RTT_TMP_512] = generateRTT(shadowsize1, GL_RGBA16F, GL_BGR, GL_FLOAT);
RenderTargetTextures[RTT_LENS_512] = generateRTT(shadowsize1, GL_RGBA16F, GL_BGR, GL_FLOAT);
RenderTargetTextures[RTT_BLOOM_1024] = generateRTT(shadowsize0, rgba_internal_format, rgb_format, type);
#if !defined(USE_GLES2)
RenderTargetTextures[RTT_SCALAR_1024] = generateRTT(shadowsize0, red32_internal_format, red_format, type);
#endif
RenderTargetTextures[RTT_BLOOM_512] = generateRTT(shadowsize1, rgba_internal_format, rgb_format, type);
RenderTargetTextures[RTT_TMP_512] = generateRTT(shadowsize1, rgba_internal_format, rgb_format, type);
RenderTargetTextures[RTT_LENS_512] = generateRTT(shadowsize1, rgba_internal_format, rgb_format, type);
RenderTargetTextures[RTT_BLOOM_256] = generateRTT(shadowsize2, GL_RGBA16F, GL_BGR, GL_FLOAT);
RenderTargetTextures[RTT_TMP_256] = generateRTT(shadowsize2, GL_RGBA16F, GL_BGR, GL_FLOAT);
RenderTargetTextures[RTT_LENS_256] = generateRTT(shadowsize2, GL_RGBA16F, GL_BGR, GL_FLOAT);
RenderTargetTextures[RTT_BLOOM_256] = generateRTT(shadowsize2, rgba_internal_format, rgb_format, type);
RenderTargetTextures[RTT_TMP_256] = generateRTT(shadowsize2, rgba_internal_format, rgb_format, type);
RenderTargetTextures[RTT_LENS_256] = generateRTT(shadowsize2, rgba_internal_format, rgb_format, type);
RenderTargetTextures[RTT_BLOOM_128] = generateRTT(shadowsize3, GL_RGBA16F, GL_BGR, GL_FLOAT);
RenderTargetTextures[RTT_TMP_128] = generateRTT(shadowsize3, GL_RGBA16F, GL_BGR, GL_FLOAT);
RenderTargetTextures[RTT_LENS_128] = generateRTT(shadowsize3, GL_RGBA16F, GL_BGR, GL_FLOAT);
RenderTargetTextures[RTT_BLOOM_128] = generateRTT(shadowsize3, rgba_internal_format, rgb_format, type);
RenderTargetTextures[RTT_TMP_128] = generateRTT(shadowsize3, rgba_internal_format, rgb_format, type);
RenderTargetTextures[RTT_LENS_128] = generateRTT(shadowsize3, rgba_internal_format, rgb_format, type);
std::vector<GLuint> somevector;
somevector.push_back(RenderTargetTextures[RTT_SSAO]);
@ -191,9 +216,11 @@ RTT::RTT(size_t width, size_t height)
somevector.push_back(RenderTargetTextures[RTT_BLOOM_1024]);
FrameBuffers.push_back(new FrameBuffer(somevector, shadowsize0.Width, shadowsize0.Height));
somevector.clear();
#if !defined(USE_GLES2)
somevector.push_back(RenderTargetTextures[RTT_SCALAR_1024]);
FrameBuffers.push_back(new FrameBuffer(somevector, shadowsize0.Width, shadowsize0.Height));
somevector.clear();
#endif
somevector.push_back(RenderTargetTextures[RTT_BLOOM_512]);
FrameBuffers.push_back(new FrameBuffer(somevector, shadowsize1.Width, shadowsize1.Height));
@ -244,7 +271,7 @@ RTT::RTT(size_t width, size_t height)
somevector.clear();
somevector.push_back(RSM_Color);
somevector.push_back(RSM_Normal);
m_RSM = new FrameBuffer(somevector, RSM_Depth, 1024, 1024, true);
m_RSM = new FrameBuffer(somevector, RSM_Depth, shadowsize0.Width, shadowsize0.Height, true);
RH_Red = generateRTT3D(GL_TEXTURE_3D, 32, 16, 32, GL_RGBA16F, GL_RGBA, GL_FLOAT);
RH_Green = generateRTT3D(GL_TEXTURE_3D, 32, 16, 32, GL_RGBA16F, GL_RGBA, GL_FLOAT);

View File

@ -60,7 +60,9 @@ enum TypeFBO
FBO_EIGHTH2,
FBO_DISPLACE,
FBO_BLOOM_1024,
#if !defined(USE_GLES2)
FBO_SCALAR_1024,
#endif
FBO_BLOOM_512,
FBO_TMP_512,
FBO_LENS_512,
@ -122,7 +124,9 @@ enum TypeRTT
RTT_MLAA_TMP,
RTT_BLOOM_1024,
#if !defined(USE_GLES2)
RTT_SCALAR_1024,
#endif
RTT_BLOOM_512,
RTT_TMP_512,
RTT_LENS_512,

View File

@ -62,7 +62,7 @@ const std::string& ShaderBase::getHeader()
GLuint ShaderBase::loadShader(const std::string &file, unsigned type)
{
GLuint id = glCreateShader(type);
std::ostringstream code;
#if !defined(USE_GLES2)
code << "#version " << CVS->getGLSLVersion()<<"\n";
@ -87,13 +87,13 @@ GLuint ShaderBase::loadShader(const std::string &file, unsigned type)
code << "#extension GL_ARB_arrays_of_arrays : enable\n";
}
#endif
if (CVS->isAMDVertexShaderLayerUsable())
code << "#extension GL_AMD_vertex_shader_layer : enable\n";
if (CVS->isARBExplicitAttribLocationUsable())
code << "#extension GL_ARB_explicit_attrib_location : enable\n";
if (CVS->isAZDOEnabled())
{
code << "#extension GL_ARB_bindless_texture : enable\n";
@ -107,10 +107,20 @@ GLuint ShaderBase::loadShader(const std::string &file, unsigned type)
if (CVS->needsRGBBindlessWorkaround())
code << "#define SRGBBindlessFix\n";
#if !defined(USE_GLES2)
//shader compilation fails with some drivers if there is no precision qualifier
if (type == GL_FRAGMENT_SHADER)
code << "precision mediump float;\n";
#else
int range[2], precision;
glGetShaderPrecisionFormat(GL_FRAGMENT_SHADER, GL_HIGH_FLOAT, range, &precision);
if (precision > 0)
code << "precision highp float;\n";
else
code << "precision mediump float;\n";
#endif
code << getHeader();
std::ifstream stream(file_manager->getShader(file), std::ios::in);
@ -129,31 +139,31 @@ GLuint ShaderBase::loadShader(const std::string &file, unsigned type)
Log::error("shader", "Invalid #stk_include line: '%s'.", Line.c_str());
continue;
}
std::string filename = Line.substr(pos+1);
pos = filename.find("\"");
if (pos == std::string::npos)
{
Log::error("shader", "Invalid #stk_include line: '%s'.", Line.c_str());
continue;
}
filename = filename.substr(0, pos);
std::ifstream include_stream(file_manager->getShader(filename), std::ios::in);
if (!include_stream.is_open())
{
Log::error("shader", "Couldn't open included shader: '%s'.", filename.c_str());
continue;
}
std::string include_line = "";
while (getline(include_stream, include_line))
{
code << "\n" << include_line;
}
include_stream.close();
}
else
@ -161,7 +171,7 @@ GLuint ShaderBase::loadShader(const std::string &file, unsigned type)
code << "\n" << Line;
}
}
stream.close();
}
else
@ -201,7 +211,7 @@ GLuint ShaderBase::loadShader(const std::string &file, unsigned type)
/** Loads a transform feedback buffer shader with a given number of varying
* parameters.
*/
int ShaderBase::loadTFBProgram(const std::string &shader_name,
int ShaderBase::loadTFBProgram(const std::string &shader_name,
const char **varyings,
unsigned varying_count)
{
@ -250,7 +260,7 @@ void ShaderBase::bypassUBO() const
glUniformMatrix4fv(IPM, 1, GL_FALSE, irr_driver->getInvProjMatrix().pointer());
GLint Screen = glGetUniformLocation(m_program, "screen");
glUniform2f(Screen, irr_driver->getCurrentScreenSize().X,
glUniform2f(Screen, irr_driver->getCurrentScreenSize().X,
irr_driver->getCurrentScreenSize().Y);
const SHCoefficients* sh_coeff = irr_driver->getSHCoefficients();

View File

@ -231,11 +231,11 @@ void ShaderBasedRenderer::uploadLightingData() const
void ShaderBasedRenderer::computeMatrixesAndCameras(scene::ICameraSceneNode *const camnode,
size_t width, size_t height)
{
float w = width * UserConfigParams::m_scale_rtts_factor;
float h = height * UserConfigParams::m_scale_rtts_factor;
m_current_screen_size = core::vector2df(w, h);
m_shadow_matrices.computeMatrixesAndCameras(camnode, w, h, m_rtts->getDepthStencilTexture());
m_shadow_matrices.computeMatrixesAndCameras(camnode, int(w), int(h),
m_rtts->getDepthStencilTexture());
} // computeMatrixesAndCameras
// ----------------------------------------------------------------------------
@ -250,6 +250,11 @@ void ShaderBasedRenderer::renderSkybox(const scene::ICameraSceneNode *camera) co
// ----------------------------------------------------------------------------
void ShaderBasedRenderer::renderSSAO() const
{
#if defined(USE_GLES2)
if (!CVS->isEXTColorBufferFloatUsable())
return;
#endif
m_rtts->getFBO(FBO_SSAO).bind();
glClearColor(1., 1., 1., 1.);
glClear(GL_COLOR_BUFFER_BIT);
@ -607,19 +612,32 @@ void ShaderBasedRenderer::renderPostProcessing(Camera * const camera)
bool isRace = StateManager::get()->getGameState() == GUIEngine::GAME;
FrameBuffer *fbo = m_post_processing->render(camnode, isRace, m_rtts);
// The viewport has been changed using glViewport function directly
// during scene rendering, but irrlicht thinks that nothing changed
// when single camera is used. In this case we set the viewport
// to whole screen manually.
glViewport(0, 0, irr_driver->getActualScreenSize().Width,
irr_driver->getActualScreenSize().Height);
if (irr_driver->getNormals())
m_rtts->getFBO(FBO_NORMAL_AND_DEPTHS).BlitToDefault(viewport.UpperLeftCorner.X, viewport.UpperLeftCorner.Y, viewport.LowerRightCorner.X, viewport.LowerRightCorner.Y);
{
m_rtts->getFBO(FBO_NORMAL_AND_DEPTHS).BlitToDefault(
viewport.UpperLeftCorner.X,
irr_driver->getActualScreenSize().Height - viewport.LowerRightCorner.Y,
viewport.LowerRightCorner.X,
irr_driver->getActualScreenSize().Height - viewport.UpperLeftCorner.Y);
}
else if (irr_driver->getSSAOViz())
{
glBindFramebuffer(GL_FRAMEBUFFER, 0);
glViewport(viewport.UpperLeftCorner.X, viewport.UpperLeftCorner.Y, viewport.LowerRightCorner.X, viewport.LowerRightCorner.Y);
camera->activate();
m_post_processing->renderPassThrough(m_rtts->getFBO(FBO_HALF1_R).getRTT()[0], viewport.LowerRightCorner.X - viewport.UpperLeftCorner.X, viewport.LowerRightCorner.Y - viewport.UpperLeftCorner.Y);
}
else if (irr_driver->getRSM())
{
glBindFramebuffer(GL_FRAMEBUFFER, 0);
glViewport(viewport.UpperLeftCorner.X, viewport.UpperLeftCorner.Y, viewport.LowerRightCorner.X, viewport.LowerRightCorner.Y);
camera->activate();
m_post_processing->renderPassThrough(m_rtts->getReflectiveShadowMapFrameBuffer().getRTT()[0], viewport.LowerRightCorner.X - viewport.UpperLeftCorner.X, viewport.LowerRightCorner.Y - viewport.UpperLeftCorner.Y);
}
else if (irr_driver->getShadowViz())
@ -631,7 +649,6 @@ void ShaderBasedRenderer::renderPostProcessing(Camera * const camera)
glEnable(GL_FRAMEBUFFER_SRGB);
glBindFramebuffer(GL_FRAMEBUFFER, 0);
camera->activate();
glViewport(viewport.UpperLeftCorner.X, viewport.UpperLeftCorner.Y, viewport.LowerRightCorner.X, viewport.LowerRightCorner.Y);
m_post_processing->renderPassThrough(fbo->getRTT()[0], viewport.LowerRightCorner.X - viewport.UpperLeftCorner.X, viewport.LowerRightCorner.Y - viewport.UpperLeftCorner.Y);
glDisable(GL_FRAMEBUFFER_SRGB);
}

View File

@ -365,7 +365,7 @@ Shaders::TransparentShader::TransparentShader()
{
loadProgram(OBJECT, GL_VERTEX_SHADER, "object_pass.vert",
GL_FRAGMENT_SHADER, "transparent.frag");
assignUniforms("ModelMatrix", "TextureMatrix");
assignUniforms("ModelMatrix", "TextureMatrix", "custom_alpha");
assignSamplerNames(0, "tex", ST_TRILINEAR_ANISOTROPIC_FILTERED);
} // TransparentShader

View File

@ -120,7 +120,8 @@ public:
// ========================================================================
class TransparentShader : public TextureShader<TransparentShader, 1,
core::matrix4, core::matrix4 >
core::matrix4, core::matrix4,
float >
{
public:
TransparentShader();

View File

@ -125,15 +125,34 @@ ShadowMatrices::ShadowMatrices()
m_shadow_cam_nodes[1] = NULL;
m_shadow_cam_nodes[2] = NULL;
m_shadow_cam_nodes[3] = NULL;
m_rsm_map_available = false;
m_rsm_matrix_initialized = false;
} // ShadowMatrices
// ----------------------------------------------------------------------------
ShadowMatrices::~ShadowMatrices()
{
resetShadowCamNodes();
m_sun_cam->drop();
} // ~ShadowMatrices
// ----------------------------------------------------------------------------
void ShadowMatrices::resetShadowCamNodes()
{
for (unsigned i = 0; i < 4; i++)
{
if (m_shadow_cam_nodes[i])
{
m_shadow_cam_nodes[i]->drop();
m_shadow_cam_nodes[i] = NULL;
}
}
} // resetShadowCamNodes
// ----------------------------------------------------------------------------
void ShadowMatrices::addLight(const core::vector3df &pos)
{
m_sun_cam->setPosition(pos);
m_sun_cam->updateAbsolutePosition();
m_rsm_matrix_initialized = false;
} // addLight
// ----------------------------------------------------------------------------
@ -315,20 +334,6 @@ void ShadowMatrices::computeMatrixesAndCameras(scene::ICameraSceneNode *const ca
const float oldfar = camnode->getFarValue();
const float oldnear = camnode->getNearValue();
float FarValues[] =
{
ShadowMatrices::m_shadow_split[1],
ShadowMatrices::m_shadow_split[2],
ShadowMatrices::m_shadow_split[3],
ShadowMatrices::m_shadow_split[4],
};
float NearValues[] =
{
ShadowMatrices::m_shadow_split[0],
ShadowMatrices::m_shadow_split[1],
ShadowMatrices::m_shadow_split[2],
ShadowMatrices::m_shadow_split[3]
};
float tmp[16 * 9 + 2];
memcpy(tmp, irr_driver->getViewMatrix().pointer(), 16 * sizeof(float));
@ -349,16 +354,20 @@ void ShadowMatrices::computeMatrixesAndCameras(scene::ICameraSceneNode *const ca
if (World::getWorld() && World::getWorld()->getTrack())
{
// Compute track extent
btVector3 btmin, btmax;
if (World::getWorld()->getTrack()->getPtrTriangleMesh())
float FarValues[] =
{
World::getWorld()->getTrack()->getTriangleMesh().getCollisionShape()
.getAabb(btTransform::getIdentity(), btmin, btmax);
}
const Vec3 vmin = btmin, vmax = btmax;
core::aabbox3df trackbox(vmin.toIrrVector(), vmax.toIrrVector() -
core::vector3df(0, 30, 0));
ShadowMatrices::m_shadow_split[1],
ShadowMatrices::m_shadow_split[2],
ShadowMatrices::m_shadow_split[3],
ShadowMatrices::m_shadow_split[4],
};
float NearValues[] =
{
ShadowMatrices::m_shadow_split[0],
ShadowMatrices::m_shadow_split[1],
ShadowMatrices::m_shadow_split[2],
ShadowMatrices::m_shadow_split[3]
};
// Shadow Matrixes and cameras
for (unsigned i = 0; i < 4; i++)
@ -411,8 +420,16 @@ void ShadowMatrices::computeMatrixesAndCameras(scene::ICameraSceneNode *const ca
}
// Rsm Matrix and camera
if (!m_rsm_matrix_initialized)
if (!m_rsm_matrix_initialized &&
World::getWorld()->getTrack()->getPtrTriangleMesh())
{
// Compute track extent
Vec3 vmin, vmax;
World::getWorld()->getTrack()->getTriangleMesh().getCollisionShape()
.getAabb(btTransform::getIdentity(), vmin, vmax);
core::aabbox3df trackbox(vmin.toIrrVector(), vmax.toIrrVector() -
core::vector3df(0, 30, 0));
if (trackbox.MinEdge.X != trackbox.MaxEdge.X &&
trackbox.MinEdge.Y != trackbox.MaxEdge.Y &&
// Cover the case where sun_cam_view_matrix is null

View File

@ -64,6 +64,7 @@ private:
public:
ShadowMatrices();
~ShadowMatrices();
void computeMatrixesAndCameras(scene::ICameraSceneNode *const camnode,
unsigned int width, unsigned int height,
@ -74,10 +75,7 @@ public:
const PostProcessing *post_processing);
// ------------------------------------------------------------------------
void resetShadowCamNodes()
{
memset(m_shadow_cam_nodes, 0, 4 * sizeof(void*));
} // resetShadowCamNodes
void resetShadowCamNodes();
// ------------------------------------------------------------------------
scene::ICameraSceneNode** getShadowCamNodes()
{

View File

@ -153,9 +153,9 @@ void SkidMarks::update(float dt, bool force_skid_marks,
float distance = (newPoint - start).length();
m_left [m_current]->add(raycast_left-delta, raycast_left+delta,
distance);
m_kart.getNormal(), distance);
m_right[m_current]->add(raycast_right-delta, raycast_right+delta,
distance);
m_kart.getNormal(), distance);
// Adjust the boundary box of the mesh to include the
// adjusted aabb of its buffers.
core::aabbox3df aabb=m_nodes[m_current]->getMesh()
@ -180,14 +180,16 @@ void SkidMarks::update(float dt, bool force_skid_marks,
delta *= m_width*0.5f;
SkidMarkQuads *smq_left =
new SkidMarkQuads(raycast_left-delta, raycast_left+delta ,
m_material, m_avoid_z_fighting, custom_color);
new SkidMarkQuads(raycast_left-delta, raycast_left+delta,
m_kart.getNormal(), m_material, m_avoid_z_fighting,
custom_color);
scene::SMesh *new_mesh = new scene::SMesh();
new_mesh->addMeshBuffer(smq_left);
SkidMarkQuads *smq_right =
new SkidMarkQuads(raycast_right-delta, raycast_right+delta,
m_material, m_avoid_z_fighting, custom_color);
m_kart.getNormal(), m_material, m_avoid_z_fighting,
custom_color);
new_mesh->addMeshBuffer(smq_right);
scene::IMeshSceneNode *new_node = irr_driver->addMesh(new_mesh, "skidmark");
if (STKMeshSceneNode* stkm = dynamic_cast<STKMeshSceneNode*>(new_node))
@ -233,6 +235,7 @@ void SkidMarks::update(float dt, bool force_skid_marks,
//=============================================================================
SkidMarks::SkidMarkQuads::SkidMarkQuads(const Vec3 &left,
const Vec3 &right,
const Vec3 &normal,
video::SMaterial *material,
float z_offset,
video::SColor* custom_color)
@ -250,7 +253,7 @@ SkidMarks::SkidMarkQuads::SkidMarkQuads(const Vec3 &left,
Material = *material;
m_aabb = core::aabbox3df(left.toIrrVector());
add(left, right, 0.0f);
add(left, right, normal, 0.0f);
} // SkidMarkQuads
@ -261,6 +264,7 @@ SkidMarks::SkidMarkQuads::SkidMarkQuads(const Vec3 &left,
*/
void SkidMarks::SkidMarkQuads::add(const Vec3 &left,
const Vec3 &right,
const Vec3 &normal,
float distance)
{
// The skid marks must be raised slightly higher, otherwise it blends
@ -280,13 +284,11 @@ void SkidMarks::SkidMarkQuads::add(const Vec3 &left,
Vertices[n - 2].Color.setAlpha(m_start_alpha);
}
v.Pos = left.toIrrVector();
v.Pos.Y += m_z_offset;
v.Normal = core::vector3df(0, 1, 0);
v.Pos = Vec3(left + normal * m_z_offset).toIrrVector();
v.Normal = normal.toIrrVector();
v.TCoords = core::vector2df(0.0f, distance*0.5f);
Vertices.push_back(v);
v.Pos = right.toIrrVector();
v.Pos.Y += m_z_offset;
v.Pos = Vec3(right + normal * m_z_offset).toIrrVector();
v.TCoords = core::vector2df(1.0f, distance*0.5f);
Vertices.push_back(v);
// Out of the box Irrlicht only supports triangle meshes and not

View File

@ -85,10 +85,11 @@ private:
public:
SkidMarkQuads (const Vec3 &left, const Vec3 &right,
video::SMaterial *material, float z_offset,
video::SColor* custom_color = NULL);
const Vec3 &normal, video::SMaterial *material,
float z_offset, video::SColor* custom_color = NULL);
void add (const Vec3 &left,
const Vec3 &right,
const Vec3 &normal,
float distance);
void fade (float f);
/** Returns the aabb of this skid mark quads. */

View File

@ -170,6 +170,15 @@ void Skybox::generateCubeMapFromTextures()
image->copyToScaling(rgba[i], size, size);
image->drop();
#if defined(USE_GLES2)
for (unsigned int j = 0; j < size * size; j++)
{
char tmp_val = rgba[i][j*4];
rgba[i][j*4] = rgba[i][j*4 + 2];
rgba[i][j*4 + 2] = tmp_val;
}
#endif
if (i == 2 || i == 3)
{
char *tmp = new char[size * size * 4];
@ -188,15 +197,14 @@ void Skybox::generateCubeMapFromTextures()
#if !defined(USE_GLES2)
GLint internal_format = CVS->isTextureCompressionEnabled() ?
GL_COMPRESSED_SRGB_ALPHA : GL_SRGB_ALPHA;
GLint format = GL_BGRA;
#else
// The GL_SRGB_ALPHA_EXT and GL_SRGB8_ALPHA8 formats are available in
// OpenGL ES, but they produce black texture for some reason.
// The basic GL_RGBA format works fine though.
GLint internal_format = GL_RGBA;
GLint internal_format = GL_RGBA8;
GLint format = GL_RGBA;
#endif
glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0,
internal_format, size, size, 0, GL_BGRA,
internal_format, size, size, 0, format,
GL_UNSIGNED_BYTE, (GLvoid*)rgba[i]);
}
glGenerateMipmap(GL_TEXTURE_CUBE_MAP);
@ -213,8 +221,13 @@ void Skybox::generateSpecularCubemap()
size_t cubemap_size = 256;
for (int i = 0; i < 6; i++)
{
#if !defined(USE_GLES2)
glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, GL_RGBA16F,
cubemap_size, cubemap_size, 0, GL_BGRA, GL_FLOAT, 0);
#else
glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, GL_RGBA8,
cubemap_size, cubemap_size, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
#endif
}
glGenerateMipmap(GL_TEXTURE_CUBE_MAP);

View File

@ -77,7 +77,6 @@ SlipStream::SlipStream(AbstractKart* kart) : MovingTexture(0, 0), m_kart(kart)
p[1]=Vec3(-ew*0.5f, 0, -kl*0.5f-length);
p[2]=Vec3( ew*0.5f, 0, -kl*0.5f-length);
p[3]=Vec3( kw*0.5f, 0, -kl*0.5f );
m_slipstream_original_quad = new Quad(p[0], p[1], p[2], p[3]);
m_slipstream_quad = new Quad(p[0], p[1], p[2], p[3]);
if(UserConfigParams::m_slipstream_debug)
{
@ -127,7 +126,6 @@ SlipStream::~SlipStream()
m_debug_node->drop();
m_debug_mesh->drop();
}
delete m_slipstream_original_quad;
delete m_slipstream_quad;
} // ~SlipStream
@ -369,12 +367,6 @@ void SlipStream::update(float dt)
MovingTexture::update(dt);
// Update this karts slipstream quad (even for low level AI which don't
// use slipstream, since even then player karts can get slipstream,
// and so have to compare with the modified slipstream quad.
m_slipstream_original_quad->transform(m_kart->getTrans(),
m_slipstream_quad);
if(m_slipstream_mode==SS_USE)
{
m_slipstream_time -= dt;
@ -418,12 +410,13 @@ void SlipStream::update(float dt)
m_target_kart->getKartAnimation() ||
m_target_kart->isEliminated() ) continue;
float diff = fabsf(m_target_kart->getXYZ().getY()
- m_kart->getXYZ().getY() );
// Transform this kart location into target kart point of view
Vec3 lc = m_target_kart->getTrans().inverse()(m_kart->getXYZ());
// If the kart is 'on top' of this kart (e.g. up on a bridge),
// don't consider it for slipstreaming.
if (fabsf(lc.y()) > 6.0f) continue;
if(diff>6.0f) continue;
// If the kart we are testing against is too slow, no need to test
// slipstreaming. Note: We compare the speed of the other kart
// against the minimum slipstream speed kart of this kart - not
@ -447,7 +440,7 @@ void SlipStream::update(float dt)
float l = kp->getSlipstreamLength()
+ 0.5f*( m_target_kart->getKartLength()
+m_kart->getKartLength() );
if(delta.length2_2d() > l*l)
if(delta.length2() > l*l)
{
if(UserConfigParams::m_slipstream_debug &&
m_kart->getController()->isLocalPlayerController())
@ -457,7 +450,7 @@ void SlipStream::update(float dt)
}
// Real test: if in slipstream quad of other kart
if(m_target_kart->getSlipstream()->m_slipstream_quad
->pointInQuad(m_kart->getXYZ()))
->pointInside(lc))
{
is_sstreaming = true;
break;

View File

@ -66,14 +66,9 @@ private:
* 'slipstream credits', or the kart is using accumulated credits. */
enum {SS_NONE, SS_COLLECT, SS_USE} m_slipstream_mode;
/** The quad inside which another kart is considered to be slipstreaming.
* This value is current area, i.e. takes the kart position into account. */
/** This is slipstream area if the kart is at 0,0,0 without rotation. */
Quad *m_slipstream_quad;
/** This is slipstream area if the kart is at 0,0,0 without rotation. From
* this value m_slipstream_area is computed by applying the kart transform. */
Quad *m_slipstream_original_quad;
/** The kart from which this kart gets slipstream. Used by the AI to
** overtake the right kart. */
AbstractKart* m_target_kart;

View File

@ -99,6 +99,16 @@ void STKAnimatedMesh::updateNoGL()
if (!isMaterialInitialized)
{
// Use a default render info to distinguish same mesh buffer created by
// different animated mesh node in vao manager when using instanced
// rendering
RenderInfo* default_ri = NULL;
if (CVS->isARBBaseInstanceUsable())
{
default_ri = new RenderInfo();
m_static_render_info.push_back(default_ri);
}
video::IVideoDriver* driver = SceneManager->getVideoDriver();
const u32 mb_count = m->getMeshBufferCount();
for (u32 i = 0; i < mb_count; ++i)
@ -121,7 +131,7 @@ void STKAnimatedMesh::updateNoGL()
}
else
{
cur_ri = NULL;
cur_ri = default_ri;
}
}
else
@ -137,7 +147,7 @@ void STKAnimatedMesh::updateNoGL()
assert(cur_ri ? cur_ri->isStatic() : true);
GLmeshes.push_back(allocateMeshBuffer(mb, m_debug_name,
affected || m_all_parts_colorized || (cur_ri
&& cur_ri->isTransparent()) ? cur_ri : NULL));
&& cur_ri->isTransparent()) ? cur_ri : default_ri));
}
for (u32 i = 0; i < m->getMeshBufferCount(); ++i)
@ -165,11 +175,14 @@ void STKAnimatedMesh::updateNoGL()
}
else if (mesh.m_render_info != NULL && mesh.m_render_info->isTransparent())
{
TransparentMesh[TM_ADDITIVE].push_back(&mesh);
if (mesh.VAOType == video::EVT_TANGENTS)
TransparentMesh[TM_GHOST_KART_TANGENTS].push_back(&mesh);
else
TransparentMesh[TM_GHOST_KART].push_back(&mesh);
}
else
{
Material::ShaderType MatType = material->getShaderType();// getMeshMaterialFromType(type, mb->getVertexType(), material);
Material::ShaderType MatType = getMeshMaterialFromType(type, mb->getVertexType(), material, NULL);
MeshSolidMaterial[MatType].push_back(&mesh);
}
}
@ -218,7 +231,7 @@ void STKAnimatedMesh::updateGL()
if (CVS->isARBBaseInstanceUsable())
{
std::pair<unsigned, unsigned> p = VAOManager::getInstance()->getBase(mb);
std::pair<unsigned, unsigned> p = VAOManager::getInstance()->getBase(mb, GLmeshes[i].m_render_info);
mesh.vaoBaseVertex = p.first;
mesh.vaoOffset = p.second;
}

View File

@ -37,6 +37,8 @@ enum TransparentMaterial
TM_DEFAULT,
TM_ADDITIVE,
TM_DISPLACEMENT,
TM_GHOST_KART,
TM_GHOST_KART_TANGENTS,
TM_COUNT
}; // TransparentMaterial
@ -156,13 +158,26 @@ class MiscList : public Singleton<T>, public std::vector<STK::Tuple<Args...> >
// ----------------------------------------------------------------------------
class ListBlendTransparent : public MiscList<ListBlendTransparent, GLMesh *,
core::matrix4, core::matrix4>
core::matrix4, core::matrix4,
float>
{};
// ----------------------------------------------------------------------------
class ListAdditiveTransparent : public MiscList<ListAdditiveTransparent,
GLMesh *, core::matrix4,
core::matrix4>
core::matrix4, float>
{};
// ----------------------------------------------------------------------------
class ListGhostKart : public MiscList<ListGhostKart,
GLMesh *, core::matrix4,
core::matrix4, float>
{};
// ----------------------------------------------------------------------------
class ListGhostKartTangents : public MiscList<ListGhostKartTangents,
GLMesh *, core::matrix4,
core::matrix4, float>
{};
// ----------------------------------------------------------------------------

View File

@ -32,8 +32,8 @@
#include "utils/helpers.hpp"
#include "utils/tuple.hpp"
#include <ISceneManager.h>
#include <IMaterialRenderer.h>
#include <ISceneManager.h>
// ============================================================================
class ColorizeShader : public Shader<ColorizeShader, core::matrix4,
@ -54,12 +54,14 @@ STKMeshSceneNode::STKMeshSceneNode(irr::scene::IMesh* mesh, ISceneNode* parent,
irr::s32 id, const std::string& debug_name,
const irr::core::vector3df& position,
const irr::core::vector3df& rotation,
const irr::core::vector3df& scale, bool createGLMeshes, RenderInfo* render_info, bool all_parts_colorized) :
const irr::core::vector3df& scale, bool createGLMeshes, RenderInfo* render_info, bool all_parts_colorized,
int frame_for_mesh) :
CMeshSceneNode(mesh, parent, mgr, id, position, rotation, scale)
{
isDisplacement = false;
immediate_draw = false;
update_each_frame = false;
m_frame_for_mesh = frame_for_mesh;
isGlow = false;
m_debug_name = debug_name;
@ -207,12 +209,13 @@ void STKMeshSceneNode::updateNoGL()
GLMesh &mesh = GLmeshes[i];
Material* material = material_manager->getMaterialFor(mb->getMaterial().getTexture(0), mb);
if (mesh.m_render_info != NULL && mesh.m_render_info->isTransparent())
if (mesh.m_render_info != NULL && mesh.m_render_info->isTransparent() && !rnd->isTransparent())
{
if (!immediate_draw)
TransparentMesh[TM_ADDITIVE].push_back(&mesh);
assert(!immediate_draw);
if (mesh.VAOType == video::EVT_TANGENTS)
TransparentMesh[TM_GHOST_KART_TANGENTS].push_back(&mesh);
else
additive = true;
TransparentMesh[TM_GHOST_KART].push_back(&mesh);
}
else if (rnd->isTransparent())
{
@ -249,9 +252,18 @@ void STKMeshSceneNode::updateGL()
{
if (isGLInitialized)
return;
for (u32 i = 0; i < Mesh->getMeshBufferCount(); ++i)
scene::IAnimatedMesh* am = dynamic_cast<scene::IAnimatedMesh*>(Mesh);
scene::IMesh* m = Mesh;
if (am && m_frame_for_mesh > -1)
{
scene::IMeshBuffer* mb = Mesh->getMeshBuffer(i);
// Get the correct frame of animation for animated mesh
m = am->getMesh(m_frame_for_mesh);
}
for (u32 i = 0; i < m->getMeshBufferCount(); ++i)
{
scene::IMeshBuffer* mb = m->getMeshBuffer(i);
if (!mb)
continue;
GLMesh &mesh = GLmeshes[i];
@ -561,7 +573,7 @@ void STKMeshSceneNode::render()
#endif
Shaders::TransparentShader::getInstance()->setTextureUnits(getTextureGLuint(mesh.textures[0]));
Shaders::TransparentShader::getInstance()->setUniforms(AbsoluteTransformation, mesh.TextureMatrix);
Shaders::TransparentShader::getInstance()->setUniforms(AbsoluteTransformation, mesh.TextureMatrix, 1.0f);
assert(mesh.vao);
glBindVertexArray(mesh.vao);
glDrawElements(ptype, count, itype, 0);

View File

@ -29,6 +29,7 @@ class STKMeshSceneNode : public irr::scene::CMeshSceneNode, public STKMeshCommon
{
protected:
PtrVector<RenderInfo> m_static_render_info;
int m_frame_for_mesh;
std::vector<GLMesh> GLmeshes;
core::matrix4 ModelViewProjectionMatrix;
core::vector3df windDir;
@ -58,7 +59,8 @@ public:
const irr::core::vector3df& rotation = irr::core::vector3df(0, 0, 0),
const irr::core::vector3df& scale = irr::core::vector3df(1.0f, 1.0f, 1.0f),
bool createGLMeshes = true,
RenderInfo* render_info = NULL, bool all_parts_colorized = false);
RenderInfo* render_info = NULL, bool all_parts_colorized = false,
int frame_for_mesh = -1);
virtual void render();
virtual void setMesh(irr::scene::IMesh* mesh);
virtual void OnRegisterSceneNode();

View File

@ -43,7 +43,6 @@ void addEdge(const core::vector3df &P0, const core::vector3df &P1)
BoundingBoxes.push_back(P1.Z);
}
bool isCulledPrecise(const scene::ICameraSceneNode *cam, const scene::ISceneNode *node)
{
if (!node->getAutomaticCulling())

View File

@ -50,14 +50,28 @@ STKTextBillboard::STKTextBillboard(core::stringw text, FontWithFace* font,
void STKTextBillboard::updateAbsolutePosition()
{
// Make billboard always face the camera
scene::ICameraSceneNode* curr_cam =
irr_driver->getSceneManager()->getActiveCamera();
if (!curr_cam) return;
core::quaternion q(curr_cam->getViewMatrix());
q.W = -q.W;
if (Parent)
{
// Override to not use the parent's rotation
AbsoluteTransformation = getRelativeTransformation();
AbsoluteTransformation.setTranslation(AbsoluteTransformation.getTranslation() + Parent->getAbsolutePosition());
core::vector3df wc = RelativeTranslation;
Parent->getAbsoluteTransformation().transformVect(wc);
AbsoluteTransformation.setTranslation(wc);
q.getMatrix(AbsoluteTransformation, wc);
}
else
AbsoluteTransformation = getRelativeTransformation();
{
q.getMatrix(AbsoluteTransformation, RelativeTranslation);
}
core::matrix4 m;
m.setScale(RelativeScale);
AbsoluteTransformation *= m;
}
scene::IMesh* STKTextBillboard::getTextMesh(core::stringw text, FontWithFace* font)
@ -171,18 +185,6 @@ scene::IMesh* STKTextBillboard::getTextMesh(core::stringw text, FontWithFace* fo
return Mesh;
}
void STKTextBillboard::updateNoGL()
{
scene::ICameraSceneNode* curr_cam = irr_driver->getSceneManager()->getActiveCamera();
core::vector3df cam_pos = curr_cam->getPosition();
core::vector3df text_pos = this->getAbsolutePosition();
float angle = atan2(text_pos.X - cam_pos.X, text_pos.Z - cam_pos.Z);
this->setRotation(core::vector3df(0.0f, angle * 180.0f / M_PI, 0.0f));
updateAbsolutePosition();
STKMeshSceneNode::updateNoGL();
}
void STKTextBillboard::collectChar(video::ITexture* texture,
const core::rect<float>& destRect,
const core::rect<s32>& sourceRect,

View File

@ -74,8 +74,6 @@ public:
const irr::core::vector3df& position,
const irr::core::vector3df& size);
virtual void updateNoGL() OVERRIDE;
virtual scene::ESCENE_NODE_TYPE getType() const OVERRIDE
{
return scene::ESNT_TEXT;

View File

@ -34,6 +34,8 @@
GLuint getTextureGLuint(irr::video::ITexture *tex)
{
if (tex == NULL)
return 0;
#if defined(USE_GLES2)
return static_cast<irr::video::COGLES2Texture*>(tex)->getOpenGLTextureName();
#else
@ -57,6 +59,14 @@ static std::map<int, video::ITexture*> unicolor_cache;
void resetTextureTable()
{
AlreadyTransformedTexture.clear();
}
void cleanUnicolorTextures()
{
for (std::pair<const int, video::ITexture*>& uc : unicolor_cache)
{
uc.second->drop();
}
unicolor_cache.clear();
}
@ -87,10 +97,20 @@ void compressTexture(irr::video::ITexture *tex, bool srgb, bool premul_alpha)
memcpy(data, tex->lock(), w * h * 4);
tex->unlock();
unsigned internalFormat, Format;
if (tex->hasAlpha())
Format = GL_BGRA;
else
Format = GL_BGR;
Format = tex->hasAlpha() ? GL_BGRA : GL_BGR;
#if defined(USE_GLES2)
if (!CVS->isEXTTextureFormatBGRA8888Usable())
{
Format = tex->hasAlpha() ? GL_RGBA : GL_RGB;
for (unsigned int i = 0; i < w * h; i++)
{
char tmp_val = data[i*4];
data[i*4] = data[i*4 + 2];
data[i*4 + 2] = tmp_val;
}
}
#endif
if (premul_alpha)
{
@ -216,7 +236,6 @@ video::ITexture* getUnicolorTexture(const video::SColor &c)
std::map<int, video::ITexture*>::iterator it = unicolor_cache.find(c.color);
if (it != unicolor_cache.end())
{
it->second->grab();
return it->second;
}
else
@ -228,10 +247,12 @@ video::ITexture* getUnicolorTexture(const video::SColor &c)
c.color
};
video::IImage *img = irr_driver->getVideoDriver()->createImageFromData(video::ECF_A8R8G8B8, core::dimension2d<u32>(2, 2), tmp);
img->grab();
std::stringstream name;
name << "color" << c.color;
video::ITexture* tex = irr_driver->getVideoDriver()->addTexture(name.str().c_str(), img);
tex->grab();
// Only let our map hold the unicolor texture
irr_driver->getVideoDriver()->removeTexture(tex);
unicolor_cache[c.color] = tex;
img->drop();
return tex;

View File

@ -26,6 +26,7 @@
GLuint getTextureGLuint(irr::video::ITexture *tex);
GLuint getDepthTexture(irr::video::ITexture *tex);
void resetTextureTable();
void cleanUnicolorTextures();
void compressTexture(irr::video::ITexture *tex, bool srgb, bool premul_alpha = false);
bool loadCompressedTexture(const std::string& compressed_tex);
void saveCompressedTexture(const std::string& compressed_tex);

View File

@ -17,6 +17,7 @@
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include "graphics/texture_shader.hpp"
#include "graphics/central_settings.hpp"
#include "config/user_config.hpp"
@ -33,7 +34,7 @@ TextureShaderBase::BindFunction TextureShaderBase::m_all_bind_functions[] =
/* ST_SEMI_TRILINEAR */ &TextureShaderBase::bindTextureSemiTrilinear
};
GLuint TextureShaderBase::m_all_texture_types[] =
GLuint TextureShaderBase::m_all_texture_types[] =
{ /* ST_NEAREST_FILTERED */ GL_TEXTURE_2D,
/* ST_TRILINEAR_ANISOTROPIC_FILTERED */ GL_TEXTURE_2D,
/* ST_TRILINEAR_CUBEMAP */ GL_TEXTURE_CUBE_MAP,
@ -55,7 +56,8 @@ void TextureShaderBase::bindTextureNearest(GLuint texture_unit, GLuint tex)
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, 1.);
if (CVS->isEXTTextureFilterAnisotropicUsable())
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, 1.);
} // bindTextureNearest
@ -69,9 +71,13 @@ void TextureShaderBase::bindTextureTrilinearAnisotropic(GLuint tex_unit, GLuint
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
int aniso = UserConfigParams::m_anisotropic;
if (aniso == 0) aniso = 1;
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, (float)aniso);
if (CVS->isEXTTextureFilterAnisotropicUsable())
{
int aniso = UserConfigParams::m_anisotropic;
if (aniso == 0) aniso = 1;
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT,
(float)aniso);
}
} // bindTextureTrilinearAnisotropic
// ----------------------------------------------------------------------------
@ -84,10 +90,13 @@ void TextureShaderBase::bindCubemapTrilinear(unsigned tex_unit, unsigned tex)
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_REPEAT);
int aniso = UserConfigParams::m_anisotropic;
if (aniso == 0) aniso = 1;
glTexParameterf(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAX_ANISOTROPY_EXT,
(float)aniso);
if (CVS->isEXTTextureFilterAnisotropicUsable())
{
int aniso = UserConfigParams::m_anisotropic;
if (aniso == 0) aniso = 1;
glTexParameterf(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAX_ANISOTROPY_EXT,
(float)aniso);
}
} // bindCubemapTrilinear
// ----------------------------------------------------------------------------
@ -100,7 +109,8 @@ void TextureShaderBase::bindTextureNearestClamped(GLuint texture_unit,
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, 1.);
if (CVS->isEXTTextureFilterAnisotropicUsable())
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, 1.);
} // bindTextureNearestClamped
// ----------------------------------------------------------------------------
@ -114,7 +124,8 @@ void TextureShaderBase::bindTextureBilinear(GLuint texture_unit, GLuint tex)
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, 1.);
if (CVS->isEXTTextureFilterAnisotropicUsable())
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, 1.);
} // bindTextureBilinear
// ----------------------------------------------------------------------------
@ -126,7 +137,8 @@ void TextureShaderBase::bindTextureBilinearClamped(GLuint tex_unit, GLuint tex)
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, 1.);
if (CVS->isEXTTextureFilterAnisotropicUsable())
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, 1.);
} // bindTextureBilinearClamped
// ----------------------------------------------------------------------------
@ -138,7 +150,8 @@ void TextureShaderBase::bindTextureSemiTrilinear(GLuint tex_unit, GLuint tex_id)
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, 1.);
if (CVS->isEXTTextureFilterAnisotropicUsable())
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, 1.);
} // bindTextureSemiTrilinear
// ----------------------------------------------------------------------------
@ -165,9 +178,13 @@ void TextureShaderBase::bindTrilinearClampedArrayTexture(unsigned tex_unit,
glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
int aniso = UserConfigParams::m_anisotropic;
if (aniso == 0) aniso = 1;
glTexParameterf(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAX_ANISOTROPY_EXT, (float)aniso);
if (CVS->isEXTTextureFilterAnisotropicUsable())
{
int aniso = UserConfigParams::m_anisotropic;
if (aniso == 0) aniso = 1;
glTexParameterf(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAX_ANISOTROPY_EXT,
(float)aniso);
}
} // bindTrilinearClampedArrayTexture
// ----------------------------------------------------------------------------
@ -179,7 +196,8 @@ void TextureShaderBase::bindTextureVolume(unsigned tex_unit, unsigned tex_id)
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, 1.);
if (CVS->isEXTTextureFilterAnisotropicUsable())
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, 1.);
} // bindTextureVolume
// ----------------------------------------------------------------------------
@ -211,7 +229,8 @@ GLuint TextureShaderBase::createSamplers(SamplerTypeNew sampler_type)
glSamplerParameteri(id, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glSamplerParameteri(id, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glSamplerParameteri(id, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glSamplerParameterf(id, GL_TEXTURE_MAX_ANISOTROPY_EXT, 1.);
if (CVS->isEXTTextureFilterAnisotropicUsable())
glSamplerParameterf(id, GL_TEXTURE_MAX_ANISOTROPY_EXT, 1.);
return createNearestSampler();
}
case ST_BILINEAR_CLAMPED_FILTERED:
@ -234,7 +253,8 @@ GLuint TextureShaderBase::createNearestSampler()
glSamplerParameteri(id, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glSamplerParameteri(id, GL_TEXTURE_WRAP_S, GL_REPEAT);
glSamplerParameteri(id, GL_TEXTURE_WRAP_T, GL_REPEAT);
glSamplerParameterf(id, GL_TEXTURE_MAX_ANISOTROPY_EXT, 1.);
if (CVS->isEXTTextureFilterAnisotropicUsable())
glSamplerParameterf(id, GL_TEXTURE_MAX_ANISOTROPY_EXT, 1.);
return id;
#endif
} // createNearestSampler
@ -250,9 +270,12 @@ GLuint TextureShaderBase::createTrilinearSampler()
glSamplerParameteri(id, GL_TEXTURE_WRAP_S, GL_REPEAT);
glSamplerParameteri(id, GL_TEXTURE_WRAP_T, GL_REPEAT);
int aniso = UserConfigParams::m_anisotropic;
if (aniso == 0) aniso = 1;
glSamplerParameterf(id, GL_TEXTURE_MAX_ANISOTROPY_EXT, (float)aniso);
if (CVS->isEXTTextureFilterAnisotropicUsable())
{
int aniso = UserConfigParams::m_anisotropic;
if (aniso == 0) aniso = 1;
glSamplerParameterf(id, GL_TEXTURE_MAX_ANISOTROPY_EXT, (float)aniso);
}
return id;
#endif
} // createTrilinearSampler
@ -267,7 +290,8 @@ GLuint TextureShaderBase::createBilinearSampler()
glSamplerParameteri(id, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glSamplerParameteri(id, GL_TEXTURE_WRAP_S, GL_REPEAT);
glSamplerParameteri(id, GL_TEXTURE_WRAP_T, GL_REPEAT);
glSamplerParameterf(id, GL_TEXTURE_MAX_ANISOTROPY_EXT, 1.);
if (CVS->isEXTTextureFilterAnisotropicUsable())
glSamplerParameterf(id, GL_TEXTURE_MAX_ANISOTROPY_EXT, 1.);
return id;
#endif
} // createBilinearSampler
@ -297,7 +321,8 @@ GLuint TextureShaderBase::createBilinearClampedSampler()
glSamplerParameteri(id, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glSamplerParameteri(id, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glSamplerParameteri(id, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glSamplerParameterf(id, GL_TEXTURE_MAX_ANISOTROPY_EXT, 1.);
if (CVS->isEXTTextureFilterAnisotropicUsable())
glSamplerParameterf(id, GL_TEXTURE_MAX_ANISOTROPY_EXT, 1.);
return id;
#endif
} // createBilinearClampedSampler
@ -314,9 +339,12 @@ GLuint TextureShaderBase::createTrilinearClampedArray()
glSamplerParameteri(id, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glSamplerParameteri(id, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
int aniso = UserConfigParams::m_anisotropic;
if (aniso == 0) aniso = 1;
glSamplerParameterf(id, GL_TEXTURE_MAX_ANISOTROPY_EXT, (float)aniso);
if (CVS->isEXTTextureFilterAnisotropicUsable())
{
int aniso = UserConfigParams::m_anisotropic;
if (aniso == 0) aniso = 1;
glSamplerParameterf(id, GL_TEXTURE_MAX_ANISOTROPY_EXT, (float)aniso);
}
return id;
#endif
} // createTrilinearClampedArray
@ -330,7 +358,8 @@ GLuint TextureShaderBase::createSemiTrilinearSampler()
glSamplerParameteri(id, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
glSamplerParameteri(id, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glSamplerParameteri(id, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glSamplerParameterf(id, GL_TEXTURE_MAX_ANISOTROPY_EXT, 1.);
if (CVS->isEXTTextureFilterAnisotropicUsable())
glSamplerParameterf(id, GL_TEXTURE_MAX_ANISOTROPY_EXT, 1.);
return id;
#endif
} // createSemiTrilinearSampler

View File

@ -287,7 +287,7 @@ irr::video::E_VERTEX_TYPE VAOManager::getVertexType(enum VTXTYPE tp)
}
}
void VAOManager::append(scene::IMeshBuffer *mb, VTXTYPE tp)
void VAOManager::append(scene::IMeshBuffer *mb, VTXTYPE tp, RenderInfo* ri)
{
size_t old_vtx_cnt = last_vertex[tp];
size_t old_idx_cnt = last_index[tp];
@ -318,26 +318,28 @@ void VAOManager::append(scene::IMeshBuffer *mb, VTXTYPE tp)
glBufferSubData(GL_ELEMENT_ARRAY_BUFFER, old_idx_cnt * sizeof(u16), mb->getIndexCount() * sizeof(u16), mb->getIndices());
}
mappedBaseVertex[tp][mb] = old_vtx_cnt;
mappedBaseIndex[tp][mb] = old_idx_cnt * sizeof(u16);
std::pair<scene::IMeshBuffer*, RenderInfo*> key(mb, ri);
mappedBaseVertex[tp][key] = old_vtx_cnt;
mappedBaseIndex[tp][key] = old_idx_cnt * sizeof(u16);
}
std::pair<unsigned, unsigned> VAOManager::getBase(scene::IMeshBuffer *mb)
std::pair<unsigned, unsigned> VAOManager::getBase(scene::IMeshBuffer *mb, RenderInfo* ri)
{
VTXTYPE tp = getVTXTYPE(mb->getVertexType());
if (mappedBaseVertex[tp].find(mb) == mappedBaseVertex[tp].end())
std::pair<scene::IMeshBuffer*, RenderInfo*> key(mb, ri);
if (mappedBaseVertex[tp].find(key) == mappedBaseVertex[tp].end())
{
assert(mappedBaseIndex[tp].find(mb) == mappedBaseIndex[tp].end());
append(mb, tp);
assert(mappedBaseIndex[tp].find(key) == mappedBaseIndex[tp].end());
append(mb, tp, ri);
regenerateVAO(tp);
regenerateInstancedVAO();
}
std::unordered_map<scene::IMeshBuffer*, unsigned>::iterator It;
It = mappedBaseVertex[tp].find(mb);
std::unordered_map<std::pair<scene::IMeshBuffer*, RenderInfo*>, unsigned, MeshRenderInfoHash, MeshRenderInfoEquals>::iterator It;
It = mappedBaseVertex[tp].find(key);
assert(It != mappedBaseVertex[tp].end());
unsigned vtx = It->second;
It = mappedBaseIndex[tp].find(mb);
It = mappedBaseIndex[tp].find(key);
assert(It != mappedBaseIndex[tp].end());
return std::pair<unsigned, unsigned>(vtx, It->second);
}

View File

@ -26,6 +26,8 @@
#include <map>
#include <unordered_map>
class RenderInfo;
enum InstanceType
{
InstanceTypeDualTex,
@ -153,6 +155,30 @@ struct GlowInstanceData
#pragma pack(pop)
#endif
#include <functional>
class MeshRenderInfoHash
{
public:
size_t operator() (const std::pair<irr::scene::IMeshBuffer*, RenderInfo*> &p) const
{
return (std::hash<irr::scene::IMeshBuffer*>()(p.first) ^
(std::hash<RenderInfo*>()(p.second) << 1));
}
};
struct MeshRenderInfoEquals : std::binary_function
<const std::pair<irr::scene::IMeshBuffer*, RenderInfo*>&,
const std::pair<irr::scene::IMeshBuffer*, RenderInfo*>&, bool>
{
result_type operator() (first_argument_type lhs,
second_argument_type rhs) const
{
return (lhs.first == rhs.first) &&
(lhs.second == rhs.second);
}
};
class VAOManager : public Singleton<VAOManager>
{
enum VTXTYPE { VTXTYPE_STANDARD, VTXTYPE_TCOORD, VTXTYPE_TANGENT, VTXTYPE_COUNT };
@ -162,7 +188,7 @@ class VAOManager : public Singleton<VAOManager>
void *VBOPtr[VTXTYPE_COUNT], *IBOPtr[VTXTYPE_COUNT];
size_t RealVBOSize[VTXTYPE_COUNT], RealIBOSize[VTXTYPE_COUNT];
size_t last_vertex[VTXTYPE_COUNT], last_index[VTXTYPE_COUNT];
std::unordered_map<irr::scene::IMeshBuffer*, unsigned> mappedBaseVertex[VTXTYPE_COUNT], mappedBaseIndex[VTXTYPE_COUNT];
std::unordered_map <std::pair<irr::scene::IMeshBuffer*, RenderInfo*>, unsigned, MeshRenderInfoHash, MeshRenderInfoEquals> mappedBaseVertex[VTXTYPE_COUNT], mappedBaseIndex[VTXTYPE_COUNT];
std::map<std::pair<irr::video::E_VERTEX_TYPE, InstanceType>, GLuint> InstanceVAO;
void cleanInstanceVAOs();
@ -172,10 +198,10 @@ class VAOManager : public Singleton<VAOManager>
size_t getVertexPitch(enum VTXTYPE) const;
VTXTYPE getVTXTYPE(irr::video::E_VERTEX_TYPE type);
irr::video::E_VERTEX_TYPE getVertexType(enum VTXTYPE tp);
void append(irr::scene::IMeshBuffer *, VTXTYPE tp);
void append(irr::scene::IMeshBuffer *, VTXTYPE tp, RenderInfo* ri = NULL);
public:
VAOManager();
std::pair<unsigned, unsigned> getBase(irr::scene::IMeshBuffer *);
std::pair<unsigned, unsigned> getBase(irr::scene::IMeshBuffer *, RenderInfo* ri = NULL);
GLuint getInstanceBuffer(InstanceType it) { return instance_vbo[it]; }
void *getInstanceBufferPtr(InstanceType it) { return Ptr[it]; }
unsigned getVBO(irr::video::E_VERTEX_TYPE type) { return vbo[getVTXTYPE(type)]; }

View File

@ -659,6 +659,8 @@ namespace GUIEngine
#include "config/user_config.hpp"
#include "font/bold_face.hpp"
#include "font/digit_face.hpp"
#include "font/font_manager.hpp"
#include "font/font_settings.hpp"
#include "font/regular_face.hpp"
#include "input/input_manager.hpp"
#include "io/file_manager.hpp"

View File

@ -387,7 +387,7 @@ const bool NAVIGATION_DEBUG = false;
*/
void EventHandler::navigate(const int playerID, Input::InputType type, const bool pressedDown, const bool reverse)
{
IGUIElement *el = NULL, *closest = NULL;
IGUIElement *el = NULL;
if (type == Input::IT_STICKBUTTON && !pressedDown)
return;
@ -450,7 +450,7 @@ void EventHandler::navigate(const int playerID, Input::InputType type, const boo
// Down: if the current widget is e.g. 5, search for widget 6, 7, 8, 9, ..., 15 (up to 10 IDs may be missing)
for (int n = 1; n < 10 && !found; n++)
{
closest = GUIEngine::getGUIEnv()->getRootGUIElement()->getElementFromId(el->getTabOrder() + (reverse ? -n : n), true);
IGUIElement *closest = GUIEngine::getGUIEnv()->getRootGUIElement()->getElementFromId(el->getTabOrder() + (reverse ? -n : n), true);
if (closest != NULL && Widget::isFocusableId(closest->getID()))
{

View File

@ -18,6 +18,7 @@
#include "guiengine/scalable_font.hpp"
#include "font/font_settings.hpp"
#include "font/font_with_face.hpp"
#include "utils/translation.hpp"

View File

@ -927,7 +927,6 @@ void Skin::drawRibbonChild(const core::recti &rect, Widget* widget,
//if (widget->m_deactivated) return;
bool mark_selected = widget->isSelected(PLAYER_ID_GAME_MASTER);
bool always_show_selection = false;
IGUIElement* focusedElem = NULL;
if (GUIEngine::getFocusForPlayer(PLAYER_ID_GAME_MASTER) != NULL)
@ -1007,6 +1006,7 @@ void Skin::drawRibbonChild(const core::recti &rect, Widget* widget,
/* in combo ribbons, always show selection */
RibbonWidget* parentRibbonWidget = NULL;
bool always_show_selection = false;
if (widget->m_event_handler != NULL &&
widget->m_event_handler->m_type == WTYPE_RIBBON)

View File

@ -1321,11 +1321,10 @@ void CGUIEditBox::breakText()
s32 size = Text.size();
s32 length = 0;
s32 elWidth = RelativeRect.getWidth() - 6;
wchar_t c;
for (s32 i=0; i<size; ++i)
{
c = Text[i];
wchar_t c = Text[i];
bool lineBreak = false;
if (c == L'\r') // Mac or Windows breaks

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