mirror of
https://github.com/DrBeef/JKXR.git
synced 2025-04-29 21:11:33 +00:00
commit0c85ac4704
Author: Petr Bartos <petr.bartos@plus4u.net> Date: Sat Apr 15 18:47:10 2023 +0200 Menu updates commit35b89acc87
Author: Simon <simonbrown77@googlemail.com> Date: Sat Apr 15 12:32:35 2023 +0100 Support for changeable fresh rate commit539bfa8956
Author: Petr Bartos <petr.bartos@plus4u.net> Date: Sat Apr 15 00:02:59 2023 +0200 Ensure proper menu defaults on the very first start commit216a225aa6
Author: Petr Bartos <petr.bartos@plus4u.net> Date: Fri Apr 14 22:41:24 2023 +0200 Fix storing of force crosshair option commit48c2486aad
Merge:a72ca45
fcb9169
Author: Petr Bartos <petr.bartos@plus4u.net> Date: Fri Apr 14 22:23:24 2023 +0200 Merge remote-tracking branch 'origin/main' into contributions commita72ca459c5
Author: Petr Bartos <petr.bartos@plus4u.net> Date: Fri Apr 14 22:19:47 2023 +0200 Intern all default values; Remove no longer needed configuration files commit32c4e6eac1
Author: Petr Bartos <petr.bartos@plus4u.net> Date: Fri Apr 14 20:59:41 2023 +0200 Ensure weapon adjustment is applied when resetting to defaults commitfcb9169955
Author: Grant Bagwell <general@grantbagwell.co.uk> Date: Fri Apr 14 18:58:32 2023 +0200 Increased default force motion trigger commit2433ae4110
Author: Grant Bagwell <general@grantbagwell.co.uk> Date: Fri Apr 14 18:55:56 2023 +0200 Change Force Crosshair commit4ab6a6024a
Author: Grant Bagwell <general@grantbagwell.co.uk> Date: Fri Apr 14 17:01:16 2023 +0200 Fixed player knockback.... hopefully commit7deeee7a6f
Author: Grant Bagwell <general@grantbagwell.co.uk> Date: Fri Apr 14 17:01:00 2023 +0200 Increased Force Power Visibility commit1fdcb7c48f
Author: Grant Bagwell <general@grantbagwell.co.uk> Date: Fri Apr 14 15:16:34 2023 +0200 Changed Brightness Range and Default commitfada09a0bb
Author: Petr Bartos <petr.bartos@plus4u.net> Date: Thu Apr 13 20:38:13 2023 +0200 Fix remote turret on-screen help commit82af313786
Merge:7680cb1
d13176c
Author: Petr Bartos <petr.bartos@plus4u.net> Date: Thu Apr 13 18:59:46 2023 +0200 Merge branch 'main' into contributions commitd13176c9ba
Author: Grant Bagwell <general@grantbagwell.co.uk> Date: Thu Apr 13 13:29:49 2023 +0200 New Quick Save / Load Video commit7680cb1288
Author: Petr Bartos <petr.bartos@plus4u.net> Date: Wed Apr 12 22:26:44 2023 +0200 Fix use action when controlling droid; fix droid view help commit4d90595139
Author: Grant Bagwell <general@grantbagwell.co.uk> Date: Wed Apr 12 18:21:10 2023 +0200 Fencing Speed on Pico default commit37d5ac4184
Author: Grant Bagwell <general@grantbagwell.co.uk> Date: Wed Apr 12 18:12:07 2023 +0200 Changes to TBDC Different menu text + added vanilla mode commitd6e40ead64
Author: Grant Bagwell <general@grantbagwell.co.uk> Date: Wed Apr 12 17:44:29 2023 +0200 Set Fencing Speed back to Default (by Default) commit3f7d116e25
Merge:7424628
c7c66e4
Author: Grant Bagwell <general@grantbagwell.co.uk> Date: Wed Apr 12 14:50:26 2023 +0200 Merge branch 'main' of https://github.com/DrBeef/JKXR commit7424628a5d
Author: Grant Bagwell <general@grantbagwell.co.uk> Date: Wed Apr 12 14:50:23 2023 +0200 Updated Weapons + Shader fix for FX mod commitc7c66e46a7
Author: Simon <simonbrown77@googlemail.com> Date: Wed Apr 12 08:37:36 2023 +0100 Revert "Arrange quick save icons horizontally" This reverts commit20f8fff3fe
. Also make the icons white commitfa54045159
Author: Simon <simonbrown77@googlemail.com> Date: Tue Apr 11 21:02:29 2023 +0100 Update .gitignore commit20f8fff3fe
Author: Simon <simonbrown77@googlemail.com> Date: Tue Apr 11 21:00:09 2023 +0100 Arrange quick save icons horizontally commitd3dcac8f9d
Author: Simon <simonbrown77@googlemail.com> Date: Tue Apr 11 20:58:56 2023 +0100 Save game crash fix in JKO commit6314561b52
Author: Simon <simonbrown77@googlemail.com> Date: Tue Apr 11 08:49:42 2023 +0100 Switch selector on offhand using offhand thumbstick commit3b2ffd7289
Author: Simon <simonbrown77@googlemail.com> Date: Tue Apr 11 08:39:32 2023 +0100 Attempted fix for save game crash - Not really a proper fix, but might at least workaround it commitc135eefa05
Author: Simon <simonbrown77@googlemail.com> Date: Tue Apr 11 08:38:54 2023 +0100 Fixed save/load icon image size commitf51270a294
Merge:a2ff16b
e243d0b
Author: Simon <simonbrown77@googlemail.com> Date: Mon Apr 10 19:42:11 2023 +0100 Merge branch 'main' of https://github.com/DrBeef/JKXR commita2ff16b576
Author: Simon <simonbrown77@googlemail.com> Date: Mon Apr 10 19:42:06 2023 +0100 Quick Save/Load in Selector Haven't been able to test yet! commite243d0bdfa
Author: Grant Bagwell <general@grantbagwell.co.uk> Date: Mon Apr 10 18:29:18 2023 +0200 Update README.md commitb9d0314a6a
Author: Petr Bartos <petr.bartos@plus4u.net> Date: Sun Apr 9 19:38:32 2023 +0200 Make getting into AT-ST easier commitd121206f83
Author: Petr Bartos <petr.bartos@plus4u.net> Date: Sat Apr 8 22:49:28 2023 +0200 Tune touch gesture distance; Improve use interaction in 3rd person. commit260d501776
Author: Petr Bartos <petr.bartos@plus4u.net> Date: Sat Apr 8 22:34:59 2023 +0200 Fix and improve weapon adjustment helper axes commita6318867bb
Author: Grant Bagwell <general@grantbagwell.co.uk> Date: Thu Apr 6 20:35:02 2023 +0200 Update README.md commit4a1d90e729
Merge:425db0f
821a56d
Author: Petr Bartos <petr.bartos@plus4u.net> Date: Thu Apr 6 19:12:07 2023 +0200 Merge branch 'main' into contributions commit821a56d4b9
Author: Simon Brown <simonbrown77@googlemail.com> Date: Thu Apr 6 17:24:20 2023 +0100 Update README.md commit67b7d26de8
Merge:b407932
ccd63d4
Author: Simon Brown <simonbrown77@googlemail.com> Date: Thu Apr 6 16:54:01 2023 +0100 Merge pull request #4 from DrBeef/TBDC TBDC Scales in Code commitb407932bb2
Author: Grant Bagwell <general@grantbagwell.co.uk> Date: Thu Apr 6 17:43:26 2023 +0200 Update README.md commit174c3ce96c
Author: Grant Bagwell <general@grantbagwell.co.uk> Date: Thu Apr 6 17:33:33 2023 +0200 Update README.md commite9af8e87c2
Author: Grant Bagwell <general@grantbagwell.co.uk> Date: Thu Apr 6 17:23:36 2023 +0200 Update README.md commitccd63d4eec
Author: Grant Bagwell <general@grantbagwell.co.uk> Date: Thu Apr 6 16:57:36 2023 +0200 Forced for Extended Menu commitd6b3e8eb65
Author: Grant Bagwell <general@grantbagwell.co.uk> Date: Thu Apr 6 16:55:02 2023 +0200 TBDC Scales in Code commita5f3adf725
Author: Simon Brown <simonbrown77@googlemail.com> Date: Thu Apr 6 15:04:07 2023 +0100 Update README.md commit316c2a2904
Merge:387c34b
90b694f
Author: Simon Brown <simonbrown77@googlemail.com> Date: Thu Apr 6 10:02:01 2023 +0100 Merge pull request #2 from DrBeef/TBDC Team Beef Directors Cut commit387c34b53e
Author: Simon <simonbrown77@googlemail.com> Date: Thu Apr 6 09:59:18 2023 +0100 Update Beef Crawl commita271b61ac7
Author: Simon <simonbrown77@googlemail.com> Date: Thu Apr 6 09:58:18 2023 +0100 Switch to use Bummser's NPC file if TBDC is disabled commita2f1644d72
Author: Simon <simonbrown77@googlemail.com> Date: Thu Apr 6 08:39:02 2023 +0100 Update version to 1.0.0 for release commitf785fdc393
Author: Simon <simonbrown77@googlemail.com> Date: Thu Apr 6 08:00:11 2023 +0100 update github banner Update README.md Update README.md Update README.md Update README.md Update README.md Added Team Beef Patreon banner commit90b694ff60
Author: Grant Bagwell <general@grantbagwell.co.uk> Date: Wed Apr 5 22:21:41 2023 +0200 Last Cleanup commit70468332d6
Author: Grant Bagwell <general@grantbagwell.co.uk> Date: Wed Apr 5 22:19:45 2023 +0200 TBDC Cleanup commit6660e8c984
Author: Grant Bagwell <general@grantbagwell.co.uk> Date: Wed Apr 5 21:58:00 2023 +0200 Credits / NPC Scale commite1b03fdcc6
Author: Grant Bagwell <general@grantbagwell.co.uk> Date: Wed Apr 5 21:57:07 2023 +0200 Fixing Quick Save commit95950f2390
Author: Grant Bagwell <general@grantbagwell.co.uk> Date: Wed Apr 5 20:08:10 2023 +0200 Updated ratios per difficulty commitd6235ef199
Author: Grant Bagwell <general@grantbagwell.co.uk> Date: Wed Apr 5 00:30:35 2023 +0200 Darkened Menu GFX commita3fdb460c4
Author: Simon <simonbrown77@googlemail.com> Date: Tue Apr 4 23:03:31 2023 +0100 Prevent crash when throwing Saber seems it is indexing the g2 model surface that doesn't exist, might be something to do with the new hilt and the old hilt being in the save. Not sure, but this stops it crashing. commit4c751fcb59
Author: Grant Bagwell <general@grantbagwell.co.uk> Date: Tue Apr 4 23:59:12 2023 +0200 Y Close Datapad commita1216665c8
Merge:1939a26
d841464
Author: Grant Bagwell <general@grantbagwell.co.uk> Date: Tue Apr 4 23:48:20 2023 +0200 Merge pull request #1 from DrBeef/main Main -> TDBC commit1939a26542
Author: Grant Bagwell <general@grantbagwell.co.uk> Date: Tue Apr 4 23:37:41 2023 +0200 TBDC Laser Saber deflections Guns balancing. commitd841464924
Author: Petr Bartos <petr.bartos@plus4u.net> Date: Tue Apr 4 21:59:31 2023 +0200 Update help resources and menu commit425db0f108
Author: Petr Bartos <petr.bartos@plus4u.net> Date: Tue Apr 4 21:59:31 2023 +0200 Update help resources and menu commit3c895d27de
Merge:fe9e12a
c3819fa
Author: Petr Bartos <petr.bartos@plus4u.net> Date: Tue Apr 4 21:05:48 2023 +0200 Merge branch 'main' into contributions commitc3819fa407
Author: Grant Bagwell <general@grantbagwell.co.uk> Date: Mon Apr 3 00:36:57 2023 +0200 Demo folder assets fix commitfe9e12a3f9
Merge:d79f57b
2b255ac
Author: Petr Bartos <petr.bartos@plus4u.net> Date: Mon Apr 3 22:55:29 2023 +0200 Merge branch 'main' into contributions commit2b255ac3ea
Author: Simon <simonbrown77@googlemail.com> Date: Mon Apr 3 21:26:39 2023 +0100 Improved version string commit62284414d0
Author: Simon <simonbrown77@googlemail.com> Date: Mon Apr 3 21:26:20 2023 +0100 Ensure intro vid can be skipped without having to press trigger first commit65674abe2a
Author: Grant Bagwell <general@grantbagwell.co.uk> Date: Mon Apr 3 21:36:35 2023 +0200 Fix Controller Location Buzz for Quick Save / Load commitba2e726a79
Author: Grant Bagwell <general@grantbagwell.co.uk> Date: Mon Apr 3 00:36:57 2023 +0200 Demo folder assets fix commit7175c872a9
Author: Grant Bagwell <general@grantbagwell.co.uk> Date: Mon Apr 3 00:36:46 2023 +0200 Knockback settings TBDC commitcc7e73d04a
Author: Simon <simonbrown77@googlemail.com> Date: Sun Apr 2 22:59:47 2023 +0100 Update beef_crawl.tga commitdd71a05e36
Author: Simon <simonbrown77@googlemail.com> Date: Sun Apr 2 22:51:49 2023 +0100 Put version at the bottom of the main menu commitcb52d310c1
Author: Grant Bagwell <general@grantbagwell.co.uk> Date: Sun Apr 2 23:18:28 2023 +0200 TBDC Weapons commitac71f24e78
Author: Petr Bartos <petr.bartos@plus4u.net> Date: Sun Apr 2 18:43:10 2023 +0200 Updated control scheme picture commit3f5c767e8d
Author: Simon <simonbrown77@googlemail.com> Date: Sun Apr 2 19:42:42 2023 +0100 Update AndroidManifest.xml commit64ab392fc5
Author: Simon <simonbrown77@googlemail.com> Date: Sun Apr 2 19:42:39 2023 +0100 JKA: Some CVAR change to increase performance commitd43de53e8a
Author: Simon <simonbrown77@googlemail.com> Date: Sun Apr 2 19:41:50 2023 +0100 Added missed saber blocking check might explain why some people find JKA a bit easy if it is auto-blocking in 1st person commit8b23e255d8
Author: Simon <simonbrown77@googlemail.com> Date: Sun Apr 2 19:41:16 2023 +0100 Update open xr headers commitd79f57ba2d
Author: Petr Bartos <petr.bartos@plus4u.net> Date: Sun Apr 2 18:43:10 2023 +0200 Updated control scheme picture commite3524e8e48
Author: Petr Bartos <petr.bartos@plus4u.net> Date: Sat Apr 1 18:48:42 2023 +0200 Add use haptic feedback; Fix use in 3rd person mode commit05fc4d5ab4
Author: Petr Bartos <petr.bartos@plus4u.net> Date: Sat Apr 1 12:07:13 2023 +0200 Fix menu haptics commiteec46c183d
Author: Petr Bartos <petr.bartos@plus4u.net> Date: Sat Apr 1 18:48:42 2023 +0200 Add use haptic feedback; Fix use in 3rd person mode commitfe9891f8db
Author: Petr Bartos <petr.bartos@plus4u.net> Date: Sat Apr 1 12:07:13 2023 +0200 Fix menu haptics commit21483d0d5a
Author: Petr Bartos <petr.bartos@plus4u.net> Date: Sat Apr 1 11:25:11 2023 +0200 Make weapon adjustment mode independent for each weapon; Optimize loading of weapon adjustments commitbaec8832ab
Merge:82706df
52fcc8a
Author: Petr Bartos <petr.bartos@plus4u.net> Date: Sat Apr 1 11:15:25 2023 +0200 Merge branch 'main' into contributions commit52fcc8a49e
Author: Simon <simonbrown77@googlemail.com> Date: Sat Apr 1 09:47:48 2023 +0100 Revert "Removed the no-backface-culling for weapons as it is no longer needed" This reverts commitb899b99178
. commit5e66ebf6fc
Author: Petr Bartos <petr.bartos@plus4u.net> Date: Fri Mar 31 15:40:54 2023 +0200 Allow to skip cinematics also by triggers commit587277fa7f
Author: Petr Bartos <petr.bartos@plus4u.net> Date: Fri Mar 31 14:52:40 2023 +0200 Fix use/crouch buttons on switched control schemes commit82706df34f
Author: Petr Bartos <petr.bartos@plus4u.net> Date: Fri Mar 31 15:40:54 2023 +0200 Allow to skip cinematics also by triggers commit1111766032
Author: Petr Bartos <petr.bartos@plus4u.net> Date: Fri Mar 31 14:52:40 2023 +0200 Fix use/crouch buttons on switched control schemes commit822d1ddbba
Merge:a1a7d54
5f56cf4
Author: Petr Bartos <petr.bartos@plus4u.net> Date: Fri Mar 31 08:43:50 2023 +0200 Merge branch 'main' into contributions commit5f56cf48fc
Author: Simon <simonbrown77@googlemail.com> Date: Thu Mar 30 22:16:37 2023 +0100 Camera shake fix part 2 commit3dd7833cd0
Author: Simon <simonbrown77@googlemail.com> Date: Thu Mar 30 22:06:18 2023 +0100 Disable camera shake when charging a weapon's alt fire commit6202017b6a
Author: Petr Bartos <petr.bartos@plus4u.net> Date: Thu Mar 30 21:52:44 2023 +0200 Fix virtual gun stock commit6d49f87150
Author: Petr Bartos <petr.bartos@plus4u.net> Date: Thu Mar 30 19:26:36 2023 +0200 Do not check angle on non-facing triggers commit926c64c691
Author: Petr Bartos <petr.bartos@plus4u.net> Date: Thu Mar 30 17:54:33 2023 +0200 Add angle check for triggers touched by hand commit78f7d9bcfc
Author: Petr Bartos <petr.bartos@plus4u.net> Date: Wed Mar 29 22:59:27 2023 +0200 JKA mod menu warning commit4219f996e9
Author: Petr Bartos <petr.bartos@plus4u.net> Date: Wed Mar 29 22:42:11 2023 +0200 JKO mod menu warning commitb899b99178
Author: Simon <simonbrown77@googlemail.com> Date: Thu Mar 30 21:45:10 2023 +0100 Removed the no-backface-culling for weapons as it is no longer needed used only for hand models now commit9877859676
Author: Simon <simonbrown77@googlemail.com> Date: Thu Mar 30 21:44:36 2023 +0100 Update to the VC+Elin weapons pack includes a sweet new saber hilt commita1a7d541fa
Author: Petr Bartos <petr.bartos@plus4u.net> Date: Thu Mar 30 21:52:44 2023 +0200 Fix virtual gun stock commit15d932c75f
Author: Petr Bartos <petr.bartos@plus4u.net> Date: Thu Mar 30 19:26:36 2023 +0200 Do not check angle on non-facing triggers commit402277e717
Author: Petr Bartos <petr.bartos@plus4u.net> Date: Thu Mar 30 17:54:33 2023 +0200 Add angle check for triggers touched by hand commit9b22378c88
Author: Petr Bartos <petr.bartos@plus4u.net> Date: Thu Mar 30 17:52:26 2023 +0200 Add special delay for re-triggering security cameras commitc4cc218f8b
Author: Simon <simonbrown77@googlemail.com> Date: Wed Mar 29 22:44:50 2023 +0100 Turn the stun baton into an "always active" weapon movement still triggers the sound, but it will always shock an enemy when it makes contact commita4e99c20f9
Author: Petr Bartos <petr.bartos@plus4u.net> Date: Wed Mar 29 22:59:27 2023 +0200 JKA mod menu warning commit442a1fc8e2
Author: Petr Bartos <petr.bartos@plus4u.net> Date: Wed Mar 29 22:42:11 2023 +0200 JKO mod menu warning commit02261c57f0
Merge:3c64fa7
51c703a
Author: Petr Bartos <petr.bartos@plus4u.net> Date: Wed Mar 29 20:51:42 2023 +0200 Merge branch 'contributions' of github.com:DrBeef/JKXR into contributions commit3c64fa7e3e
Author: Simon <simonbrown77@googlemail.com> Date: Tue Mar 28 23:19:29 2023 +0100 Lowered Stun Baton trigger velocity commit43192a355d
Author: Simon <simonbrown77@googlemail.com> Date: Tue Mar 28 23:03:17 2023 +0100 Move beef_crawl back into the game specific assets as we will be fixing the JKO one on release, but updating JKA commit94e82c2da3
Author: Petr Bartos <petr.bartos@plus4u.net> Date: Tue Mar 28 23:21:28 2023 +0200 Fix subtitles rendering; Fix rendering of other centered texts commit40128567be
Author: Petr Bartos <petr.bartos@plus4u.net> Date: Tue Mar 28 18:02:08 2023 +0200 Add help to menu commit4f1b6b5f07
Author: Petr Bartos <petr.bartos@plus4u.net> Date: Tue Mar 28 17:36:13 2023 +0200 Split vr asset packs to avoid duplicates commit51c703a481
Author: Petr Bartos <petr.bartos@plus4u.net> Date: Tue Mar 28 23:21:28 2023 +0200 Fix subtitles rendering; Fix rendering of other centered texts commit04a539f890
Author: Petr Bartos <petr.bartos@plus4u.net> Date: Tue Mar 28 18:02:08 2023 +0200 Add help to menu commitd9126738d3
Author: Petr Bartos <petr.bartos@plus4u.net> Date: Tue Mar 28 17:36:13 2023 +0200 Split vr asset packs to avoid duplicates commit62b9a0bfab
Author: Simon <simonbrown77@googlemail.com> Date: Tue Mar 28 13:52:45 2023 +0100 Hide force power aura when item selector is shown commit0a9206642e
Author: Simon <simonbrown77@googlemail.com> Date: Tue Mar 28 13:52:23 2023 +0100 Slight adjustment to muzzle position based on whether scoped/two-handed commitf452b9cf06
Author: Simon <simonbrown77@googlemail.com> Date: Tue Mar 28 13:51:49 2023 +0100 Slight tweak to NPC Combat commit20de6ec478
Author: Simon <simonbrown77@googlemail.com> Date: Tue Mar 28 13:50:54 2023 +0100 Added simple readme and license commit77672f612b
Author: Simon <simonbrown77@googlemail.com> Date: Tue Mar 28 07:20:22 2023 +0100 Updated website link to be the patreon commit2a1cd0e6e7
Author: Simon <simonbrown77@googlemail.com> Date: Tue Mar 28 07:20:10 2023 +0100 Don't send roll to the server, this might be causing gradual roll drift commit1b22652e5c
Author: Simon <simonbrown77@googlemail.com> Date: Mon Mar 27 21:38:46 2023 +0100 Fixed aiming of bowcaster and demp alt fire commit895b09041f
Author: Simon <simonbrown77@googlemail.com> Date: Mon Mar 27 21:38:25 2023 +0100 JKA - Ensure UseVR Position is only true when in first person commit3897531544
Author: Simon <simonbrown77@googlemail.com> Date: Mon Mar 27 21:38:17 2023 +0100 JKO - Ensure UseVR Position is only true when in first person commit3b5121e349
Author: Simon <simonbrown77@googlemail.com> Date: Mon Mar 27 21:37:49 2023 +0100 Render Special Effects on hand/weapon when force power is activated for protection etc commit50db9039df
Author: Simon <simonbrown77@googlemail.com> Date: Sun Mar 26 16:33:52 2023 +0100 Separate no copy file flag for JK3 commit1968a7d8ba
Author: Simon <simonbrown77@googlemail.com> Date: Sun Mar 26 16:33:22 2023 +0100 Always use right hand as saber home commit74dcd955d2
Author: Simon <simonbrown77@googlemail.com> Date: Sun Mar 26 16:32:49 2023 +0100 Fix crash in JKA commit1e4692d04a
Author: Simon <simonbrown77@googlemail.com> Date: Sun Mar 26 16:32:16 2023 +0100 Update z_Crusty_and_Elin_vr_weapons.pk3 commit134dec8264
Author: Simon <simonbrown77@googlemail.com> Date: Sun Mar 26 16:31:53 2023 +0100 Fix possible crash on JK2 commitf6dc432f6a
Author: Simon <simonbrown77@googlemail.com> Date: Sat Mar 25 15:36:01 2023 +0000 Copy mods to jk2demo if it exists to resolve the issue with mods not being picked up from the base folder
2253 lines
68 KiB
C++
2253 lines
68 KiB
C++
/*
|
|
===========================================================================
|
|
Copyright (C) 1999 - 2005, Id Software, Inc.
|
|
Copyright (C) 2000 - 2013, Raven Software, Inc.
|
|
Copyright (C) 2001 - 2013, Activision, Inc.
|
|
Copyright (C) 2005 - 2015, ioquake3 contributors
|
|
Copyright (C) 2013 - 2015, OpenJK contributors
|
|
|
|
This file is part of the OpenJK source code.
|
|
|
|
OpenJK is free software; you can redistribute it and/or modify it
|
|
under the terms of the GNU General Public License version 2 as
|
|
published by the Free Software Foundation.
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
GNU General Public License for more details.
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
along with this program; if not, see <http://www.gnu.org/licenses/>.
|
|
===========================================================================
|
|
*/
|
|
|
|
// tr_init.c -- functions that are not called every frame
|
|
|
|
#include "../server/exe_headers.h"
|
|
|
|
#include "tr_local.h"
|
|
#include "../rd-common/tr_common.h"
|
|
#include "tr_stl.h"
|
|
#include "../rd-common/tr_font.h"
|
|
#include "tr_WorldEffects.h"
|
|
|
|
glconfig_t glConfig;
|
|
jk_glstate_t glState;
|
|
window_t window;
|
|
|
|
static void GfxInfo_f( void );
|
|
|
|
cvar_t *r_verbose;
|
|
cvar_t *r_ignore;
|
|
|
|
cvar_t *r_detailTextures;
|
|
|
|
cvar_t *r_znear;
|
|
|
|
cvar_t *r_skipBackEnd;
|
|
|
|
cvar_t *r_measureOverdraw;
|
|
|
|
cvar_t *r_fastsky;
|
|
cvar_t *r_drawSun;
|
|
cvar_t *r_dynamiclight;
|
|
// rjr - removed for hacking cvar_t *r_dlightBacks;
|
|
|
|
cvar_t *r_lodbias;
|
|
cvar_t *r_lodscale;
|
|
|
|
cvar_t *r_norefresh;
|
|
cvar_t *r_drawentities;
|
|
cvar_t *r_drawworld;
|
|
cvar_t *r_drawfog;
|
|
cvar_t *r_speeds;
|
|
cvar_t *r_fullbright;
|
|
cvar_t *r_novis;
|
|
cvar_t *r_nocull;
|
|
cvar_t *r_facePlaneCull;
|
|
cvar_t *r_showcluster;
|
|
cvar_t *r_nocurves;
|
|
|
|
cvar_t *r_dlightStyle;
|
|
cvar_t *r_surfaceSprites;
|
|
cvar_t *r_surfaceWeather;
|
|
|
|
cvar_t *r_windSpeed;
|
|
cvar_t *r_windAngle;
|
|
cvar_t *r_windGust;
|
|
cvar_t *r_windDampFactor;
|
|
cvar_t *r_windPointForce;
|
|
cvar_t *r_windPointX;
|
|
cvar_t *r_windPointY;
|
|
|
|
cvar_t *r_allowExtensions;
|
|
|
|
cvar_t *r_ext_compressed_textures;
|
|
cvar_t *r_ext_compressed_lightmaps;
|
|
cvar_t *r_ext_preferred_tc_method;
|
|
cvar_t *r_ext_gamma_control;
|
|
cvar_t *r_ext_multitexture;
|
|
cvar_t *r_ext_compiled_vertex_array;
|
|
cvar_t *r_ext_texture_env_add;
|
|
cvar_t *r_ext_texture_filter_anisotropic;
|
|
|
|
cvar_t *r_DynamicGlow;
|
|
cvar_t *r_DynamicGlowPasses;
|
|
cvar_t *r_DynamicGlowDelta;
|
|
cvar_t *r_DynamicGlowIntensity;
|
|
cvar_t *r_DynamicGlowSoft;
|
|
cvar_t *r_DynamicGlowWidth;
|
|
cvar_t *r_DynamicGlowHeight;
|
|
|
|
cvar_t *r_ignoreGLErrors;
|
|
cvar_t *r_logFile;
|
|
|
|
cvar_t *r_primitives;
|
|
cvar_t *r_texturebits;
|
|
cvar_t *r_texturebitslm;
|
|
|
|
cvar_t *r_lightmap;
|
|
cvar_t *r_vertexLight;
|
|
cvar_t *r_shadows;
|
|
cvar_t *r_shadowRange;
|
|
cvar_t *r_flares;
|
|
cvar_t *r_nobind;
|
|
cvar_t *r_singleShader;
|
|
cvar_t *r_colorMipLevels;
|
|
cvar_t *r_picmip;
|
|
cvar_t *r_showtris;
|
|
cvar_t *r_showtriscolor;
|
|
cvar_t *r_showsky;
|
|
cvar_t *r_shownormals;
|
|
cvar_t *r_finish;
|
|
cvar_t *r_clear;
|
|
cvar_t *r_textureMode;
|
|
cvar_t *r_offsetFactor;
|
|
cvar_t *r_offsetUnits;
|
|
cvar_t *r_gamma;
|
|
cvar_t *r_intensity;
|
|
cvar_t *r_lockpvs;
|
|
cvar_t *r_noportals;
|
|
cvar_t *r_portalOnly;
|
|
|
|
cvar_t *r_subdivisions;
|
|
cvar_t *r_lodCurveError;
|
|
|
|
cvar_t *r_overBrightBits;
|
|
cvar_t *r_mapOverBrightBits;
|
|
|
|
cvar_t *r_debugSurface;
|
|
cvar_t *r_simpleMipMaps;
|
|
|
|
cvar_t *r_showImages;
|
|
|
|
cvar_t *r_ambientScale;
|
|
cvar_t *r_directedScale;
|
|
cvar_t *r_debugLight;
|
|
cvar_t *r_debugSort;
|
|
cvar_t *r_debugStyle;
|
|
|
|
cvar_t *r_modelpoolmegs;
|
|
|
|
cvar_t *r_noGhoul2;
|
|
cvar_t *r_Ghoul2AnimSmooth;
|
|
cvar_t *r_Ghoul2UnSqash;
|
|
cvar_t *r_Ghoul2TimeBase=0;
|
|
cvar_t *r_Ghoul2NoLerp;
|
|
cvar_t *r_Ghoul2NoBlend;
|
|
cvar_t *r_Ghoul2BlendMultiplier=0;
|
|
cvar_t *r_Ghoul2UnSqashAfterSmooth;
|
|
|
|
cvar_t *broadsword;
|
|
cvar_t *broadsword_kickbones;
|
|
cvar_t *broadsword_kickorigin;
|
|
cvar_t *broadsword_playflop;
|
|
cvar_t *broadsword_dontstopanim;
|
|
cvar_t *broadsword_waitforshot;
|
|
cvar_t *broadsword_smallbbox;
|
|
cvar_t *broadsword_extra1;
|
|
cvar_t *broadsword_extra2;
|
|
|
|
cvar_t *broadsword_effcorr;
|
|
cvar_t *broadsword_ragtobase;
|
|
cvar_t *broadsword_dircap;
|
|
|
|
// More bullshit needed for the proper modular renderer --eez
|
|
cvar_t *sv_mapname;
|
|
cvar_t *sv_mapChecksum;
|
|
cvar_t *se_language; // JKA
|
|
#ifdef JK2_MODE
|
|
cvar_t *sp_language; // JK2
|
|
#endif
|
|
cvar_t *com_buildScript;
|
|
|
|
cvar_t *r_environmentMapping;
|
|
cvar_t *r_screenshotJpegQuality;
|
|
|
|
void ( APIENTRY * qglMultiTexCoord2fARB )( GLenum texture, GLfloat s, GLfloat t );
|
|
void ( APIENTRY * qglActiveTextureARB )( GLenum texture );
|
|
void ( APIENTRY * qglClientActiveTextureARB )( GLenum texture );
|
|
|
|
void ( APIENTRY * qglLockArraysEXT )( GLint, GLint );
|
|
void ( APIENTRY * qglUnlockArraysEXT )( void );
|
|
|
|
#ifndef HAVE_GLES
|
|
#if !defined(__APPLE__)
|
|
PFNGLSTENCILOPSEPARATEPROC qglStencilOpSeparate;
|
|
#endif
|
|
|
|
PFNGLACTIVETEXTUREARBPROC qglActiveTextureARB;
|
|
PFNGLCLIENTACTIVETEXTUREARBPROC qglClientActiveTextureARB;
|
|
PFNGLMULTITEXCOORD2FARBPROC qglMultiTexCoord2fARB;
|
|
|
|
PFNGLCOMBINERPARAMETERFVNVPROC qglCombinerParameterfvNV;
|
|
PFNGLCOMBINERPARAMETERIVNVPROC qglCombinerParameterivNV;
|
|
PFNGLCOMBINERPARAMETERFNVPROC qglCombinerParameterfNV;
|
|
PFNGLCOMBINERPARAMETERINVPROC qglCombinerParameteriNV;
|
|
PFNGLCOMBINERINPUTNVPROC qglCombinerInputNV;
|
|
PFNGLCOMBINEROUTPUTNVPROC qglCombinerOutputNV;
|
|
|
|
PFNGLFINALCOMBINERINPUTNVPROC qglFinalCombinerInputNV;
|
|
PFNGLGETCOMBINERINPUTPARAMETERFVNVPROC qglGetCombinerInputParameterfvNV;
|
|
PFNGLGETCOMBINERINPUTPARAMETERIVNVPROC qglGetCombinerInputParameterivNV;
|
|
PFNGLGETCOMBINEROUTPUTPARAMETERFVNVPROC qglGetCombinerOutputParameterfvNV;
|
|
PFNGLGETCOMBINEROUTPUTPARAMETERIVNVPROC qglGetCombinerOutputParameterivNV;
|
|
PFNGLGETFINALCOMBINERINPUTPARAMETERFVNVPROC qglGetFinalCombinerInputParameterfvNV;
|
|
PFNGLGETFINALCOMBINERINPUTPARAMETERIVNVPROC qglGetFinalCombinerInputParameterivNV;
|
|
#endif
|
|
|
|
PFNGLPROGRAMSTRINGARBPROC qglProgramStringARB;
|
|
PFNGLBINDPROGRAMARBPROC qglBindProgramARB;
|
|
PFNGLDELETEPROGRAMSARBPROC qglDeleteProgramsARB;
|
|
PFNGLGENPROGRAMSARBPROC qglGenProgramsARB;
|
|
PFNGLPROGRAMENVPARAMETER4DARBPROC qglProgramEnvParameter4dARB;
|
|
PFNGLPROGRAMENVPARAMETER4DVARBPROC qglProgramEnvParameter4dvARB;
|
|
PFNGLPROGRAMENVPARAMETER4FARBPROC qglProgramEnvParameter4fARB;
|
|
PFNGLPROGRAMENVPARAMETER4FVARBPROC qglProgramEnvParameter4fvARB;
|
|
PFNGLPROGRAMLOCALPARAMETER4DARBPROC qglProgramLocalParameter4dARB;
|
|
PFNGLPROGRAMLOCALPARAMETER4DVARBPROC qglProgramLocalParameter4dvARB;
|
|
PFNGLPROGRAMLOCALPARAMETER4FARBPROC qglProgramLocalParameter4fARB;
|
|
PFNGLPROGRAMLOCALPARAMETER4FVARBPROC qglProgramLocalParameter4fvARB;
|
|
PFNGLGETPROGRAMENVPARAMETERDVARBPROC qglGetProgramEnvParameterdvARB;
|
|
PFNGLGETPROGRAMENVPARAMETERFVARBPROC qglGetProgramEnvParameterfvARB;
|
|
PFNGLGETPROGRAMLOCALPARAMETERDVARBPROC qglGetProgramLocalParameterdvARB;
|
|
PFNGLGETPROGRAMLOCALPARAMETERFVARBPROC qglGetProgramLocalParameterfvARB;
|
|
PFNGLGETPROGRAMIVARBPROC qglGetProgramivARB;
|
|
PFNGLGETPROGRAMSTRINGARBPROC qglGetProgramStringARB;
|
|
PFNGLISPROGRAMARBPROC qglIsProgramARB;
|
|
|
|
#ifndef HAVE_GLES
|
|
PFNGLLOCKARRAYSEXTPROC qglLockArraysEXT;
|
|
PFNGLUNLOCKARRAYSEXTPROC qglUnlockArraysEXT;
|
|
#endif
|
|
|
|
bool g_bTextureRectangleHack = false;
|
|
|
|
void RE_SetLightStyle(int style, int color);
|
|
|
|
void R_Splash()
|
|
{
|
|
image_t *pImage = R_FindImageFile( "menu/splash", qfalse, qfalse, qfalse, GL_CLAMP);
|
|
|
|
if ( !pImage )
|
|
{
|
|
// Can't find the splash image so just clear to black
|
|
qglClearColor( 0.0f, 0.0f, 0.0f, 1.0f );
|
|
qglClear( GL_COLOR_BUFFER_BIT );
|
|
}
|
|
else
|
|
{
|
|
extern void RB_SetGL2D (void);
|
|
RB_SetGL2D();
|
|
|
|
GL_Bind( pImage );
|
|
GL_State(GLS_SRCBLEND_ONE | GLS_DSTBLEND_ZERO);
|
|
|
|
const int width = 640;
|
|
const int height = 480;
|
|
const float x1 = 320 - width / 2;
|
|
const float x2 = 320 + width / 2;
|
|
const float y1 = 240 - height / 2;
|
|
const float y2 = 240 + height / 2;
|
|
|
|
#ifdef HAVE_GLES
|
|
//GLimp_EndFrame();
|
|
GLfloat tex[] = {
|
|
0,0 ,
|
|
1,0,
|
|
0,1,
|
|
1,1
|
|
};
|
|
GLfloat vtx[] = {
|
|
x1, y1,
|
|
x2, y1,
|
|
x1, y2,
|
|
x2, y2
|
|
};
|
|
GLboolean text = qglIsEnabled(GL_TEXTURE_COORD_ARRAY);
|
|
GLboolean glcol = qglIsEnabled(GL_COLOR_ARRAY);
|
|
if (glcol)
|
|
qglDisableClientState(GL_COLOR_ARRAY);
|
|
if (!text)
|
|
qglEnableClientState( GL_TEXTURE_COORD_ARRAY );
|
|
qglEnableClientState( GL_VERTEX_ARRAY );
|
|
qglTexCoordPointer( 2, GL_FLOAT, 0, tex );
|
|
qglVertexPointer ( 2, GL_FLOAT, 0, vtx );
|
|
qglDrawArrays( GL_TRIANGLE_STRIP, 0, 4 );
|
|
if (glcol)
|
|
qglDisableClientState(GL_COLOR_ARRAY);
|
|
if (!text)
|
|
qglDisableClientState( GL_TEXTURE_COORD_ARRAY );
|
|
#else
|
|
qglBegin (GL_TRIANGLE_STRIP);
|
|
qglTexCoord2f( 0, 0 );
|
|
qglVertex2f(x1, y1);
|
|
qglTexCoord2f( 1 , 0 );
|
|
qglVertex2f(x2, y1);
|
|
qglTexCoord2f( 0, 1 );
|
|
qglVertex2f(x1, y2);
|
|
qglTexCoord2f( 1, 1 );
|
|
qglVertex2f(x2, y2);
|
|
qglEnd();
|
|
#endif
|
|
}
|
|
|
|
ri.WIN_Present( &window );
|
|
}
|
|
|
|
/*
|
|
** GLW_CheckForExtension
|
|
|
|
Cannot use strstr directly to differentiate between (for eg) reg_combiners and reg_combiners2
|
|
*/
|
|
|
|
static void GLW_InitTextureCompression( void )
|
|
{
|
|
glConfig.textureCompression = TC_NONE;
|
|
return;
|
|
|
|
|
|
bool newer_tc, old_tc;
|
|
// Check for available tc methods.
|
|
newer_tc = ri.GL_ExtensionSupported("GL_ARB_texture_compression") && ri.GL_ExtensionSupported("GL_EXT_texture_compression_s3tc");
|
|
old_tc = ri.GL_ExtensionSupported("GL_S3_s3tc");
|
|
|
|
if ( old_tc )
|
|
{
|
|
Com_Printf ("...GL_S3_s3tc available\n" );
|
|
}
|
|
|
|
if ( newer_tc )
|
|
{
|
|
Com_Printf ("...GL_EXT_texture_compression_s3tc available\n" );
|
|
}
|
|
|
|
if ( !r_ext_compressed_textures->value )
|
|
{
|
|
// Compressed textures are off
|
|
glConfig.textureCompression = TC_NONE;
|
|
Com_Printf ("...ignoring texture compression\n" );
|
|
}
|
|
else if ( !old_tc && !newer_tc )
|
|
{
|
|
// Requesting texture compression, but no method found
|
|
glConfig.textureCompression = TC_NONE;
|
|
Com_Printf ("...no supported texture compression method found\n" );
|
|
Com_Printf (".....ignoring texture compression\n" );
|
|
}
|
|
else
|
|
{
|
|
// some form of supported texture compression is avaiable, so see if the user has a preference
|
|
if ( r_ext_preferred_tc_method->integer == TC_NONE )
|
|
{
|
|
// No preference, so pick the best
|
|
if ( newer_tc )
|
|
{
|
|
Com_Printf ("...no tc preference specified\n" );
|
|
Com_Printf (".....using GL_EXT_texture_compression_s3tc\n" );
|
|
glConfig.textureCompression = TC_S3TC_DXT;
|
|
}
|
|
else
|
|
{
|
|
Com_Printf ("...no tc preference specified\n" );
|
|
Com_Printf (".....using GL_S3_s3tc\n" );
|
|
glConfig.textureCompression = TC_S3TC;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// User has specified a preference, now see if this request can be honored
|
|
if ( old_tc && newer_tc )
|
|
{
|
|
// both are avaiable, so we can use the desired tc method
|
|
if ( r_ext_preferred_tc_method->integer == TC_S3TC )
|
|
{
|
|
Com_Printf ("...using preferred tc method, GL_S3_s3tc\n" );
|
|
glConfig.textureCompression = TC_S3TC;
|
|
}
|
|
else
|
|
{
|
|
Com_Printf ("...using preferred tc method, GL_EXT_texture_compression_s3tc\n" );
|
|
glConfig.textureCompression = TC_S3TC_DXT;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// Both methods are not available, so this gets trickier
|
|
if ( r_ext_preferred_tc_method->integer == TC_S3TC )
|
|
{
|
|
// Preferring to user older compression
|
|
if ( old_tc )
|
|
{
|
|
Com_Printf ("...using GL_S3_s3tc\n" );
|
|
glConfig.textureCompression = TC_S3TC;
|
|
}
|
|
else
|
|
{
|
|
// Drat, preference can't be honored
|
|
Com_Printf ("...preferred tc method, GL_S3_s3tc not available\n" );
|
|
Com_Printf (".....falling back to GL_EXT_texture_compression_s3tc\n" );
|
|
glConfig.textureCompression = TC_S3TC_DXT;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// Preferring to user newer compression
|
|
if ( newer_tc )
|
|
{
|
|
Com_Printf ("...using GL_EXT_texture_compression_s3tc\n" );
|
|
glConfig.textureCompression = TC_S3TC_DXT;
|
|
}
|
|
else
|
|
{
|
|
// Drat, preference can't be honored
|
|
Com_Printf ("...preferred tc method, GL_EXT_texture_compression_s3tc not available\n" );
|
|
Com_Printf (".....falling back to GL_S3_s3tc\n" );
|
|
glConfig.textureCompression = TC_S3TC;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/*
|
|
===============
|
|
GLimp_InitExtensions
|
|
===============
|
|
*/
|
|
extern bool g_bDynamicGlowSupported;
|
|
static void GLimp_InitExtensions( void )
|
|
{
|
|
if ( !r_allowExtensions->integer )
|
|
{
|
|
Com_Printf ("*** IGNORING OPENGL EXTENSIONS ***\n" );
|
|
g_bDynamicGlowSupported = false;
|
|
ri.Cvar_Set( "r_DynamicGlow","0" );
|
|
return;
|
|
}
|
|
|
|
Com_Printf ("Initializing OpenGL extensions\n" );
|
|
|
|
// Select our tc scheme
|
|
GLW_InitTextureCompression();
|
|
|
|
// GL_EXT_texture_env_add
|
|
glConfig.textureEnvAddAvailable = qfalse;
|
|
if ( ri.GL_ExtensionSupported( "GL_EXT_texture_env_add" ) )
|
|
{
|
|
if ( r_ext_texture_env_add->integer )
|
|
{
|
|
glConfig.textureEnvAddAvailable = qtrue;
|
|
Com_Printf ("...using GL_EXT_texture_env_add\n" );
|
|
}
|
|
else
|
|
{
|
|
glConfig.textureEnvAddAvailable = qfalse;
|
|
Com_Printf ("...ignoring GL_EXT_texture_env_add\n" );
|
|
}
|
|
}
|
|
else
|
|
{
|
|
Com_Printf ("...GL_EXT_texture_env_add not found\n" );
|
|
}
|
|
|
|
// GL_EXT_texture_filter_anisotropic
|
|
glConfig.maxTextureFilterAnisotropy = 0;
|
|
if ( ri.GL_ExtensionSupported( "GL_EXT_texture_filter_anisotropic" ) )
|
|
{
|
|
qglGetFloatv( GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &glConfig.maxTextureFilterAnisotropy );
|
|
Com_Printf ("...GL_EXT_texture_filter_anisotropic available\n" );
|
|
|
|
if ( r_ext_texture_filter_anisotropic->integer > 1 )
|
|
{
|
|
Com_Printf ("...using GL_EXT_texture_filter_anisotropic\n" );
|
|
}
|
|
else
|
|
{
|
|
Com_Printf ("...ignoring GL_EXT_texture_filter_anisotropic\n" );
|
|
}
|
|
ri.Cvar_SetValue( "r_ext_texture_filter_anisotropic_avail", glConfig.maxTextureFilterAnisotropy );
|
|
if ( r_ext_texture_filter_anisotropic->value > glConfig.maxTextureFilterAnisotropy )
|
|
{
|
|
ri.Cvar_SetValue( "r_ext_texture_filter_anisotropic_avail", glConfig.maxTextureFilterAnisotropy );
|
|
}
|
|
}
|
|
else
|
|
{
|
|
Com_Printf ("...GL_EXT_texture_filter_anisotropic not found\n" );
|
|
ri.Cvar_Set( "r_ext_texture_filter_anisotropic_avail", "0" );
|
|
}
|
|
|
|
// GL_EXT_clamp_to_edge
|
|
glConfig.clampToEdgeAvailable = qtrue;
|
|
Com_Printf ("...using GL_EXT_texture_edge_clamp\n" );
|
|
|
|
#ifndef HAVE_GLES
|
|
// GL_ARB_multitexture
|
|
qglMultiTexCoord2fARB = NULL;
|
|
qglActiveTextureARB = NULL;
|
|
qglClientActiveTextureARB = NULL;
|
|
if ( ri.GL_ExtensionSupported( "GL_ARB_multitexture" ) )
|
|
{
|
|
if ( r_ext_multitexture->integer )
|
|
{
|
|
qglMultiTexCoord2fARB = ( PFNGLMULTITEXCOORD2FARBPROC ) ri.GL_GetProcAddress( "glMultiTexCoord2fARB" );
|
|
qglActiveTextureARB = ( PFNGLACTIVETEXTUREARBPROC ) ri.GL_GetProcAddress( "glActiveTextureARB" );
|
|
qglClientActiveTextureARB = ( PFNGLCLIENTACTIVETEXTUREARBPROC ) ri.GL_GetProcAddress( "glClientActiveTextureARB" );
|
|
|
|
if ( qglActiveTextureARB )
|
|
{
|
|
qglGetIntegerv( GL_MAX_TEXTURE_UNITS_ARB, &glConfig.maxActiveTextures );
|
|
|
|
if ( glConfig.maxActiveTextures > 1 )
|
|
{
|
|
Com_Printf ("...using GL_ARB_multitexture\n" );
|
|
}
|
|
else
|
|
{
|
|
qglMultiTexCoord2fARB = NULL;
|
|
qglActiveTextureARB = NULL;
|
|
qglClientActiveTextureARB = NULL;
|
|
Com_Printf ("...not using GL_ARB_multitexture, < 2 texture units\n" );
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
Com_Printf ("...ignoring GL_ARB_multitexture\n" );
|
|
}
|
|
}
|
|
else
|
|
{
|
|
Com_Printf ("...GL_ARB_multitexture not found\n" );
|
|
}
|
|
|
|
// GL_EXT_compiled_vertex_array
|
|
qglLockArraysEXT = NULL;
|
|
qglUnlockArraysEXT = NULL;
|
|
if ( ri.GL_ExtensionSupported( "GL_EXT_compiled_vertex_array" ) )
|
|
{
|
|
if ( r_ext_compiled_vertex_array->integer )
|
|
{
|
|
Com_Printf ("...using GL_EXT_compiled_vertex_array\n" );
|
|
qglLockArraysEXT = ( PFNGLLOCKARRAYSEXTPROC ) ri.GL_GetProcAddress( "glLockArraysEXT" );
|
|
qglUnlockArraysEXT = ( PFNGLUNLOCKARRAYSEXTPROC ) ri.GL_GetProcAddress( "glUnlockArraysEXT" );
|
|
if (!qglLockArraysEXT || !qglUnlockArraysEXT) {
|
|
Com_Error (ERR_FATAL, "bad getprocaddress");
|
|
}
|
|
}
|
|
else
|
|
{
|
|
Com_Printf ("...ignoring GL_EXT_compiled_vertex_array\n" );
|
|
}
|
|
}
|
|
else
|
|
{
|
|
Com_Printf ("...GL_EXT_compiled_vertex_array not found\n" );
|
|
}
|
|
|
|
bool bNVRegisterCombiners = false;
|
|
|
|
// Register Combiners.
|
|
if ( ri.GL_ExtensionSupported( "GL_NV_register_combiners" ) )
|
|
{
|
|
// NOTE: This extension requires multitexture support (over 2 units).
|
|
if ( glConfig.maxActiveTextures >= 2 )
|
|
{
|
|
bNVRegisterCombiners = true;
|
|
// Register Combiners function pointer address load. - AReis
|
|
// NOTE: VV guys will _definetly_ not be able to use regcoms. Pixel Shaders are just as good though :-)
|
|
// NOTE: Also, this is an nVidia specific extension (of course), so fragment shaders would serve the same purpose
|
|
// if we needed some kind of fragment/pixel manipulation support.
|
|
qglCombinerParameterfvNV = (PFNGLCOMBINERPARAMETERFVNVPROC)ri.GL_GetProcAddress( "glCombinerParameterfvNV" );
|
|
qglCombinerParameterivNV = (PFNGLCOMBINERPARAMETERIVNVPROC)ri.GL_GetProcAddress( "glCombinerParameterivNV" );
|
|
qglCombinerParameterfNV = (PFNGLCOMBINERPARAMETERFNVPROC)ri.GL_GetProcAddress( "glCombinerParameterfNV" );
|
|
qglCombinerParameteriNV = (PFNGLCOMBINERPARAMETERINVPROC)ri.GL_GetProcAddress( "glCombinerParameteriNV" );
|
|
qglCombinerInputNV = (PFNGLCOMBINERINPUTNVPROC)ri.GL_GetProcAddress( "glCombinerInputNV" );
|
|
qglCombinerOutputNV = (PFNGLCOMBINEROUTPUTNVPROC)ri.GL_GetProcAddress( "glCombinerOutputNV" );
|
|
qglFinalCombinerInputNV = (PFNGLFINALCOMBINERINPUTNVPROC)ri.GL_GetProcAddress( "glFinalCombinerInputNV" );
|
|
qglGetCombinerInputParameterfvNV = (PFNGLGETCOMBINERINPUTPARAMETERFVNVPROC)ri.GL_GetProcAddress( "glGetCombinerInputParameterfvNV" );
|
|
qglGetCombinerInputParameterivNV = (PFNGLGETCOMBINERINPUTPARAMETERIVNVPROC)ri.GL_GetProcAddress( "glGetCombinerInputParameterivNV" );
|
|
qglGetCombinerOutputParameterfvNV = (PFNGLGETCOMBINEROUTPUTPARAMETERFVNVPROC)ri.GL_GetProcAddress( "glGetCombinerOutputParameterfvNV" );
|
|
qglGetCombinerOutputParameterivNV = (PFNGLGETCOMBINEROUTPUTPARAMETERIVNVPROC)ri.GL_GetProcAddress( "glGetCombinerOutputParameterivNV" );
|
|
qglGetFinalCombinerInputParameterfvNV = (PFNGLGETFINALCOMBINERINPUTPARAMETERFVNVPROC)ri.GL_GetProcAddress( "glGetFinalCombinerInputParameterfvNV" );
|
|
qglGetFinalCombinerInputParameterivNV = (PFNGLGETFINALCOMBINERINPUTPARAMETERIVNVPROC)ri.GL_GetProcAddress( "glGetFinalCombinerInputParameterivNV" );
|
|
|
|
// Validate the functions we need.
|
|
if ( !qglCombinerParameterfvNV || !qglCombinerParameterivNV || !qglCombinerParameterfNV || !qglCombinerParameteriNV || !qglCombinerInputNV ||
|
|
!qglCombinerOutputNV || !qglFinalCombinerInputNV || !qglGetCombinerInputParameterfvNV || !qglGetCombinerInputParameterivNV ||
|
|
!qglGetCombinerOutputParameterfvNV || !qglGetCombinerOutputParameterivNV || !qglGetFinalCombinerInputParameterfvNV || !qglGetFinalCombinerInputParameterivNV )
|
|
{
|
|
bNVRegisterCombiners = false;
|
|
qglCombinerParameterfvNV = NULL;
|
|
qglCombinerParameteriNV = NULL;
|
|
Com_Printf ("...GL_NV_register_combiners failed\n" );
|
|
}
|
|
}
|
|
else
|
|
{
|
|
bNVRegisterCombiners = false;
|
|
Com_Printf ("...ignoring GL_NV_register_combiners\n" );
|
|
}
|
|
}
|
|
else
|
|
{
|
|
bNVRegisterCombiners = false;
|
|
Com_Printf ("...GL_NV_register_combiners not found\n" );
|
|
}
|
|
#endif
|
|
// NOTE: Vertex and Fragment Programs are very dependant on each other - this is actually a
|
|
// good thing! So, just check to see which we support (one or the other) and load the shared
|
|
// function pointers. ARB rocks!
|
|
|
|
// Vertex Programs.
|
|
bool bARBVertexProgram = false;
|
|
if ( ri.GL_ExtensionSupported( "GL_ARB_vertex_program" ) )
|
|
{
|
|
bARBVertexProgram = true;
|
|
}
|
|
else
|
|
{
|
|
bARBVertexProgram = false;
|
|
Com_Printf ("...GL_ARB_vertex_program not found\n" );
|
|
}
|
|
|
|
// Fragment Programs.
|
|
bool bARBFragmentProgram = false;
|
|
if ( ri.GL_ExtensionSupported( "GL_ARB_fragment_program" ) )
|
|
{
|
|
bARBFragmentProgram = true;
|
|
}
|
|
else
|
|
{
|
|
bARBFragmentProgram = false;
|
|
Com_Printf ("...GL_ARB_fragment_program not found\n" );
|
|
}
|
|
|
|
// If we support one or the other, load the shared function pointers.
|
|
if ( bARBVertexProgram || bARBFragmentProgram )
|
|
{
|
|
qglProgramStringARB = (PFNGLPROGRAMSTRINGARBPROC) ri.GL_GetProcAddress("glProgramStringARB");
|
|
qglBindProgramARB = (PFNGLBINDPROGRAMARBPROC) ri.GL_GetProcAddress("glBindProgramARB");
|
|
qglDeleteProgramsARB = (PFNGLDELETEPROGRAMSARBPROC) ri.GL_GetProcAddress("glDeleteProgramsARB");
|
|
qglGenProgramsARB = (PFNGLGENPROGRAMSARBPROC) ri.GL_GetProcAddress("glGenProgramsARB");
|
|
qglProgramEnvParameter4dARB = (PFNGLPROGRAMENVPARAMETER4DARBPROC) ri.GL_GetProcAddress("glProgramEnvParameter4dARB");
|
|
qglProgramEnvParameter4dvARB = (PFNGLPROGRAMENVPARAMETER4DVARBPROC) ri.GL_GetProcAddress("glProgramEnvParameter4dvARB");
|
|
qglProgramEnvParameter4fARB = (PFNGLPROGRAMENVPARAMETER4FARBPROC) ri.GL_GetProcAddress("glProgramEnvParameter4fARB");
|
|
qglProgramEnvParameter4fvARB = (PFNGLPROGRAMENVPARAMETER4FVARBPROC) ri.GL_GetProcAddress("glProgramEnvParameter4fvARB");
|
|
qglProgramLocalParameter4dARB = (PFNGLPROGRAMLOCALPARAMETER4DARBPROC) ri.GL_GetProcAddress("glProgramLocalParameter4dARB");
|
|
qglProgramLocalParameter4dvARB = (PFNGLPROGRAMLOCALPARAMETER4DVARBPROC) ri.GL_GetProcAddress("glProgramLocalParameter4dvARB");
|
|
qglProgramLocalParameter4fARB = (PFNGLPROGRAMLOCALPARAMETER4FARBPROC) ri.GL_GetProcAddress("glProgramLocalParameter4fARB");
|
|
qglProgramLocalParameter4fvARB = (PFNGLPROGRAMLOCALPARAMETER4FVARBPROC) ri.GL_GetProcAddress("glProgramLocalParameter4fvARB");
|
|
qglGetProgramEnvParameterdvARB = (PFNGLGETPROGRAMENVPARAMETERDVARBPROC) ri.GL_GetProcAddress("glGetProgramEnvParameterdvARB");
|
|
qglGetProgramEnvParameterfvARB = (PFNGLGETPROGRAMENVPARAMETERFVARBPROC) ri.GL_GetProcAddress("glGetProgramEnvParameterfvARB");
|
|
qglGetProgramLocalParameterdvARB = (PFNGLGETPROGRAMLOCALPARAMETERDVARBPROC) ri.GL_GetProcAddress("glGetProgramLocalParameterdvARB");
|
|
qglGetProgramLocalParameterfvARB = (PFNGLGETPROGRAMLOCALPARAMETERFVARBPROC) ri.GL_GetProcAddress("glGetProgramLocalParameterfvARB");
|
|
qglGetProgramivARB = (PFNGLGETPROGRAMIVARBPROC) ri.GL_GetProcAddress("glGetProgramivARB");
|
|
qglGetProgramStringARB = (PFNGLGETPROGRAMSTRINGARBPROC) ri.GL_GetProcAddress("glGetProgramStringARB");
|
|
qglIsProgramARB = (PFNGLISPROGRAMARBPROC) ri.GL_GetProcAddress("glIsProgramARB");
|
|
|
|
// Validate the functions we need.
|
|
if ( !qglProgramStringARB || !qglBindProgramARB || !qglDeleteProgramsARB || !qglGenProgramsARB ||
|
|
!qglProgramEnvParameter4dARB || !qglProgramEnvParameter4dvARB || !qglProgramEnvParameter4fARB ||
|
|
!qglProgramEnvParameter4fvARB || !qglProgramLocalParameter4dARB || !qglProgramLocalParameter4dvARB ||
|
|
!qglProgramLocalParameter4fARB || !qglProgramLocalParameter4fvARB || !qglGetProgramEnvParameterdvARB ||
|
|
!qglGetProgramEnvParameterfvARB || !qglGetProgramLocalParameterdvARB || !qglGetProgramLocalParameterfvARB ||
|
|
!qglGetProgramivARB || !qglGetProgramStringARB || !qglIsProgramARB )
|
|
{
|
|
bARBVertexProgram = false;
|
|
bARBFragmentProgram = false;
|
|
qglGenProgramsARB = NULL; //clear ptrs that get checked
|
|
qglProgramEnvParameter4fARB = NULL;
|
|
Com_Printf ("...ignoring GL_ARB_vertex_program\n" );
|
|
Com_Printf ("...ignoring GL_ARB_fragment_program\n" );
|
|
}
|
|
}
|
|
|
|
// Figure out which texture rectangle extension to use.
|
|
bool bTexRectSupported = false;
|
|
if ( Q_stricmpn( glConfig.vendor_string, "ATI Technologies",16 )==0
|
|
&& Q_stricmpn( glConfig.version_string, "1.3.3",5 )==0
|
|
&& glConfig.version_string[5] < '9' ) //1.3.34 and 1.3.37 and 1.3.38 are broken for sure, 1.3.39 is not
|
|
{
|
|
g_bTextureRectangleHack = true;
|
|
}
|
|
|
|
if ( ri.GL_ExtensionSupported( "GL_NV_texture_rectangle" ) || ri.GL_ExtensionSupported( "GL_EXT_texture_rectangle" ) )
|
|
{
|
|
bTexRectSupported = true;
|
|
}
|
|
|
|
// Find out how many general combiners they have.
|
|
#define GL_MAX_GENERAL_COMBINERS_NV 0x854D
|
|
GLint iNumGeneralCombiners = 0;
|
|
bool bNVRegisterCombiners = false;
|
|
if(bNVRegisterCombiners)
|
|
qglGetIntegerv( GL_MAX_GENERAL_COMBINERS_NV, &iNumGeneralCombiners );
|
|
|
|
// Only allow dynamic glows/flares if they have the hardware
|
|
if ( bTexRectSupported && bARBVertexProgram && qglActiveTextureARB && glConfig.maxActiveTextures >= 4 &&
|
|
( ( bNVRegisterCombiners && iNumGeneralCombiners >= 2 ) || bARBFragmentProgram ) )
|
|
{
|
|
g_bDynamicGlowSupported = true;
|
|
// this would overwrite any achived setting gwg
|
|
// ri.Cvar_Set( "r_DynamicGlow", "1" );
|
|
}
|
|
else
|
|
{
|
|
g_bDynamicGlowSupported = false;
|
|
ri.Cvar_Set( "r_DynamicGlow","0" );
|
|
}
|
|
|
|
#if !defined(__APPLE__)
|
|
#ifndef HAVE_GLES
|
|
qglStencilOpSeparate = (PFNGLSTENCILOPSEPARATEPROC)ri.GL_GetProcAddress("glStencilOpSeparate");
|
|
if (qglStencilOpSeparate)
|
|
{
|
|
glConfig.doStencilShadowsInOneDrawcall = qtrue;
|
|
}
|
|
#endif
|
|
#else
|
|
glConfig.doStencilShadowsInOneDrawcall = qtrue;
|
|
#endif
|
|
}
|
|
|
|
/*
|
|
** InitOpenGL
|
|
**
|
|
** This function is responsible for initializing a valid OpenGL subsystem. This
|
|
** is done by calling GLimp_Init (which gives us a working OGL subsystem) then
|
|
** setting variables, checking GL constants, and reporting the gfx system config
|
|
** to the user.
|
|
*/
|
|
static void InitOpenGL( void )
|
|
{
|
|
//
|
|
// initialize OS specific portions of the renderer
|
|
//
|
|
// GLimp_Init directly or indirectly references the following cvars:
|
|
// - r_fullscreen
|
|
// - r_mode
|
|
// - r_(color|depth|stencil)bits
|
|
// - r_ignorehwgamma
|
|
// - r_gamma
|
|
//
|
|
|
|
if ( glConfig.vidWidth == 0 )
|
|
{
|
|
windowDesc_t windowDesc = { GRAPHICS_API_OPENGL };
|
|
memset(&glConfig, 0, sizeof(glConfig));
|
|
|
|
window = ri.WIN_Init(&windowDesc, &glConfig);
|
|
|
|
// get our config strings
|
|
glConfig.vendor_string = (const char *)qglGetString (GL_VENDOR);
|
|
glConfig.renderer_string = (const char *)qglGetString (GL_RENDERER);
|
|
glConfig.version_string = (const char *)qglGetString (GL_VERSION);
|
|
glConfig.extensions_string = (const char *)qglGetString (GL_EXTENSIONS);
|
|
|
|
// OpenGL driver constants
|
|
qglGetIntegerv( GL_MAX_TEXTURE_SIZE, &glConfig.maxTextureSize );
|
|
|
|
// stubbed or broken drivers may have reported 0...
|
|
glConfig.maxTextureSize = Q_max(0, glConfig.maxTextureSize);
|
|
|
|
// initialize extensions
|
|
GLimp_InitExtensions( );
|
|
|
|
// set default state
|
|
GL_SetDefaultState();
|
|
//R_Splash(); //get something on screen asap
|
|
}
|
|
else
|
|
{
|
|
// set default state
|
|
GL_SetDefaultState();
|
|
}
|
|
}
|
|
|
|
/*
|
|
==================
|
|
GL_CheckErrors
|
|
==================
|
|
*/
|
|
void GL_CheckErrors( void ) {
|
|
int err;
|
|
char s[64];
|
|
|
|
err = qglGetError();
|
|
if ( err == GL_NO_ERROR ) {
|
|
return;
|
|
}
|
|
if ( r_ignoreGLErrors->integer ) {
|
|
return;
|
|
}
|
|
switch( err ) {
|
|
case GL_INVALID_ENUM:
|
|
strcpy( s, "GL_INVALID_ENUM" );
|
|
break;
|
|
case GL_INVALID_VALUE:
|
|
strcpy( s, "GL_INVALID_VALUE" );
|
|
break;
|
|
case GL_INVALID_OPERATION:
|
|
strcpy( s, "GL_INVALID_OPERATION" );
|
|
break;
|
|
case GL_STACK_OVERFLOW:
|
|
strcpy( s, "GL_STACK_OVERFLOW" );
|
|
break;
|
|
case GL_STACK_UNDERFLOW:
|
|
strcpy( s, "GL_STACK_UNDERFLOW" );
|
|
break;
|
|
case GL_OUT_OF_MEMORY:
|
|
strcpy( s, "GL_OUT_OF_MEMORY" );
|
|
break;
|
|
default:
|
|
Com_sprintf( s, sizeof(s), "%i", err);
|
|
break;
|
|
}
|
|
|
|
Com_Error( ERR_FATAL, "GL_CheckErrors: %s", s );
|
|
}
|
|
|
|
/*
|
|
==============================================================================
|
|
|
|
SCREEN SHOTS
|
|
|
|
==============================================================================
|
|
*/
|
|
|
|
/*
|
|
==================
|
|
|
|
RB_ReadPixels
|
|
|
|
Reads an image but takes care of alignment issues for reading RGB images.
|
|
|
|
Reads a minimum offset for where the RGB data starts in the image from
|
|
integer stored at pointer offset. When the function has returned the actual
|
|
offset was written back to address offset. This address will always have an
|
|
alignment of packAlign to ensure efficient copying.
|
|
|
|
Stores the length of padding after a line of pixels to address padlen
|
|
|
|
Return value must be freed with Hunk_FreeTempMemory()
|
|
==================
|
|
*/
|
|
|
|
byte *RB_ReadPixels(int x, int y, int width, int height, size_t *offset, int *padlen)
|
|
{
|
|
byte *buffer, *bufstart;
|
|
int padwidth, linelen;
|
|
GLint packAlign;
|
|
|
|
qglGetIntegerv(GL_PACK_ALIGNMENT, &packAlign);
|
|
|
|
linelen = width * 3;
|
|
padwidth = PAD(linelen, packAlign);
|
|
|
|
// Allocate a few more bytes so that we can choose an alignment we like
|
|
buffer = (byte *) R_Malloc(padwidth * height + *offset + packAlign - 1, TAG_TEMP_WORKSPACE, qfalse);
|
|
|
|
bufstart = (byte *)PADP((intptr_t) buffer + *offset, packAlign);
|
|
qglReadPixels(x, y, width, height, GL_RGB, GL_UNSIGNED_BYTE, bufstart);
|
|
|
|
*offset = bufstart - buffer;
|
|
*padlen = padwidth - linelen;
|
|
|
|
return buffer;
|
|
}
|
|
|
|
/*
|
|
==================
|
|
R_TakeScreenshot
|
|
==================
|
|
*/
|
|
void R_TakeScreenshot( int x, int y, int width, int height, char *fileName ) {
|
|
byte *allbuf, *buffer;
|
|
byte *srcptr, *destptr;
|
|
byte *endline, *endmem;
|
|
byte temp;
|
|
|
|
int linelen, padlen;
|
|
size_t offset = 18, memcount;
|
|
|
|
allbuf = RB_ReadPixels(x, y, width, height, &offset, &padlen);
|
|
buffer = allbuf + offset - 18;
|
|
|
|
Com_Memset (buffer, 0, 18);
|
|
buffer[2] = 2; // uncompressed type
|
|
buffer[12] = width & 255;
|
|
buffer[13] = width >> 8;
|
|
buffer[14] = height & 255;
|
|
buffer[15] = height >> 8;
|
|
buffer[16] = 24; // pixel size
|
|
|
|
// swap rgb to bgr and remove padding from line endings
|
|
linelen = width * 3;
|
|
|
|
srcptr = destptr = allbuf + offset;
|
|
endmem = srcptr + (linelen + padlen) * height;
|
|
|
|
while(srcptr < endmem)
|
|
{
|
|
endline = srcptr + linelen;
|
|
|
|
while(srcptr < endline)
|
|
{
|
|
temp = srcptr[0];
|
|
*destptr++ = srcptr[2];
|
|
*destptr++ = srcptr[1];
|
|
*destptr++ = temp;
|
|
|
|
srcptr += 3;
|
|
}
|
|
|
|
// Skip the pad
|
|
srcptr += padlen;
|
|
}
|
|
|
|
memcount = linelen * height;
|
|
|
|
// gamma correct
|
|
if(glConfig.deviceSupportsGamma)
|
|
R_GammaCorrect(allbuf + offset, memcount);
|
|
|
|
ri.FS_WriteFile(fileName, buffer, memcount + 18);
|
|
|
|
R_Free(allbuf);
|
|
}
|
|
|
|
/*
|
|
==================
|
|
R_TakeScreenshotPNG
|
|
==================
|
|
*/
|
|
void R_TakeScreenshotPNG( int x, int y, int width, int height, char *fileName ) {
|
|
byte *buffer=NULL;
|
|
size_t offset=0;
|
|
int padlen=0;
|
|
|
|
buffer = RB_ReadPixels( x, y, width, height, &offset, &padlen );
|
|
RE_SavePNG( fileName, buffer, width, height, 3 );
|
|
R_Free( buffer );
|
|
}
|
|
|
|
/*
|
|
==================
|
|
R_TakeScreenshotJPEG
|
|
==================
|
|
*/
|
|
void R_TakeScreenshotJPEG( int x, int y, int width, int height, char *fileName ) {
|
|
byte *buffer;
|
|
size_t offset = 0, memcount;
|
|
int padlen;
|
|
|
|
buffer = RB_ReadPixels(x, y, width, height, &offset, &padlen);
|
|
memcount = (width * 3 + padlen) * height;
|
|
|
|
// gamma correct
|
|
if(glConfig.deviceSupportsGamma)
|
|
R_GammaCorrect(buffer + offset, memcount);
|
|
|
|
RE_SaveJPG(fileName, r_screenshotJpegQuality->integer, width, height, buffer + offset, padlen);
|
|
R_Free(buffer);
|
|
}
|
|
|
|
/*
|
|
==================
|
|
R_ScreenshotFilename
|
|
==================
|
|
*/
|
|
void R_ScreenshotFilename( char *buf, int bufSize, const char *ext ) {
|
|
time_t rawtime;
|
|
char timeStr[32] = {0}; // should really only reach ~19 chars
|
|
|
|
time( &rawtime );
|
|
strftime( timeStr, sizeof( timeStr ), "%Y-%m-%d_%H-%M-%S", localtime( &rawtime ) ); // or gmtime
|
|
|
|
Com_sprintf( buf, bufSize, "screenshots/shot%s%s", timeStr, ext );
|
|
}
|
|
|
|
/*
|
|
====================
|
|
R_LevelShot
|
|
|
|
levelshots are specialized 256*256 thumbnails for
|
|
the menu system, sampled down from full screen distorted images
|
|
====================
|
|
*/
|
|
#define LEVELSHOTSIZE 256
|
|
static void R_LevelShot( void ) {
|
|
char checkname[MAX_OSPATH];
|
|
byte *buffer;
|
|
byte *source, *allsource;
|
|
byte *src, *dst;
|
|
size_t offset = 0;
|
|
int padlen;
|
|
int x, y;
|
|
int r, g, b;
|
|
float xScale, yScale;
|
|
int xx, yy;
|
|
|
|
Com_sprintf( checkname, sizeof(checkname), "levelshots/%s.tga", tr.world->baseName );
|
|
|
|
allsource = RB_ReadPixels(0, 0, glConfig.vidWidth, glConfig.vidHeight, &offset, &padlen);
|
|
source = allsource + offset;
|
|
|
|
buffer = (byte *) R_Malloc(LEVELSHOTSIZE * LEVELSHOTSIZE*3 + 18, TAG_TEMP_WORKSPACE, qfalse);
|
|
Com_Memset (buffer, 0, 18);
|
|
buffer[2] = 2; // uncompressed type
|
|
buffer[12] = LEVELSHOTSIZE & 255;
|
|
buffer[13] = LEVELSHOTSIZE >> 8;
|
|
buffer[14] = LEVELSHOTSIZE & 255;
|
|
buffer[15] = LEVELSHOTSIZE >> 8;
|
|
buffer[16] = 24; // pixel size
|
|
|
|
// resample from source
|
|
xScale = glConfig.vidWidth / (4.0*LEVELSHOTSIZE);
|
|
yScale = glConfig.vidHeight / (3.0*LEVELSHOTSIZE);
|
|
for ( y = 0 ; y < LEVELSHOTSIZE ; y++ ) {
|
|
for ( x = 0 ; x < LEVELSHOTSIZE ; x++ ) {
|
|
r = g = b = 0;
|
|
for ( yy = 0 ; yy < 3 ; yy++ ) {
|
|
for ( xx = 0 ; xx < 4 ; xx++ ) {
|
|
src = source + 3 * ( glConfig.vidWidth * (int)( (y*3+yy)*yScale ) + (int)( (x*4+xx)*xScale ) );
|
|
r += src[0];
|
|
g += src[1];
|
|
b += src[2];
|
|
}
|
|
}
|
|
dst = buffer + 18 + 3 * ( y * LEVELSHOTSIZE + x );
|
|
dst[0] = b / 12;
|
|
dst[1] = g / 12;
|
|
dst[2] = r / 12;
|
|
}
|
|
}
|
|
|
|
// gamma correct
|
|
if ( ( tr.overbrightBits > 0 ) && glConfig.deviceSupportsGamma ) {
|
|
R_GammaCorrect( buffer + 18, LEVELSHOTSIZE * LEVELSHOTSIZE * 3 );
|
|
}
|
|
|
|
ri.FS_WriteFile( checkname, buffer, LEVELSHOTSIZE * LEVELSHOTSIZE*3 + 18 );
|
|
|
|
R_Free( buffer );
|
|
R_Free( allsource );
|
|
|
|
Com_Printf ("Wrote %s\n", checkname );
|
|
}
|
|
|
|
/*
|
|
==================
|
|
R_ScreenShotTGA_f
|
|
|
|
screenshot
|
|
screenshot [silent]
|
|
screenshot [levelshot]
|
|
screenshot [filename]
|
|
|
|
Doesn't print the pacifier message if there is a second arg
|
|
==================
|
|
*/
|
|
void R_ScreenShotTGA_f (void) {
|
|
char checkname[MAX_OSPATH] = {0};
|
|
qboolean silent = qfalse;
|
|
|
|
if ( !strcmp( ri.Cmd_Argv(1), "levelshot" ) ) {
|
|
R_LevelShot();
|
|
return;
|
|
}
|
|
|
|
if ( !strcmp( ri.Cmd_Argv(1), "silent" ) )
|
|
silent = qtrue;
|
|
|
|
if ( ri.Cmd_Argc() == 2 && !silent ) {
|
|
// explicit filename
|
|
Com_sprintf( checkname, sizeof( checkname ), "screenshots/%s.tga", ri.Cmd_Argv( 1 ) );
|
|
}
|
|
else {
|
|
// timestamp the file
|
|
R_ScreenshotFilename( checkname, sizeof( checkname ), ".tga" );
|
|
|
|
if ( ri.FS_FileExists( checkname ) ) {
|
|
Com_Printf( "ScreenShot: Couldn't create a file\n");
|
|
return;
|
|
}
|
|
}
|
|
|
|
R_TakeScreenshot( 0, 0, glConfig.vidWidth, glConfig.vidHeight, checkname );
|
|
|
|
if ( !silent )
|
|
Com_Printf( "Wrote %s\n", checkname );
|
|
}
|
|
|
|
/*
|
|
==================
|
|
R_ScreenShotPNG_f
|
|
|
|
screenshot
|
|
screenshot [silent]
|
|
screenshot [levelshot]
|
|
screenshot [filename]
|
|
|
|
Doesn't print the pacifier message if there is a second arg
|
|
==================
|
|
*/
|
|
void R_ScreenShotPNG_f (void) {
|
|
char checkname[MAX_OSPATH] = {0};
|
|
qboolean silent = qfalse;
|
|
|
|
if ( !strcmp( ri.Cmd_Argv(1), "levelshot" ) ) {
|
|
R_LevelShot();
|
|
return;
|
|
}
|
|
|
|
if ( !strcmp( ri.Cmd_Argv(1), "silent" ) )
|
|
silent = qtrue;
|
|
|
|
if ( ri.Cmd_Argc() == 2 && !silent ) {
|
|
// explicit filename
|
|
Com_sprintf( checkname, sizeof( checkname ), "screenshots/%s.png", ri.Cmd_Argv( 1 ) );
|
|
}
|
|
else {
|
|
// timestamp the file
|
|
R_ScreenshotFilename( checkname, sizeof( checkname ), ".png" );
|
|
|
|
if ( ri.FS_FileExists( checkname ) ) {
|
|
Com_Printf( "ScreenShot: Couldn't create a file\n");
|
|
return;
|
|
}
|
|
}
|
|
|
|
R_TakeScreenshotPNG( 0, 0, glConfig.vidWidth, glConfig.vidHeight, checkname );
|
|
|
|
if ( !silent )
|
|
Com_Printf( "Wrote %s\n", checkname );
|
|
}
|
|
|
|
void R_ScreenShot_f (void) {
|
|
char checkname[MAX_OSPATH] = {0};
|
|
qboolean silent = qfalse;
|
|
|
|
if ( !strcmp( ri.Cmd_Argv(1), "levelshot" ) ) {
|
|
R_LevelShot();
|
|
return;
|
|
}
|
|
if ( !strcmp( ri.Cmd_Argv(1), "silent" ) )
|
|
silent = qtrue;
|
|
|
|
if ( ri.Cmd_Argc() == 2 && !silent ) {
|
|
// explicit filename
|
|
Com_sprintf( checkname, sizeof( checkname ), "screenshots/%s.jpg", ri.Cmd_Argv( 1 ) );
|
|
}
|
|
else {
|
|
// timestamp the file
|
|
R_ScreenshotFilename( checkname, sizeof( checkname ), ".jpg" );
|
|
|
|
if ( ri.FS_FileExists( checkname ) ) {
|
|
Com_Printf( "ScreenShot: Couldn't create a file\n" );
|
|
return;
|
|
}
|
|
}
|
|
|
|
R_TakeScreenshotJPEG( 0, 0, glConfig.vidWidth, glConfig.vidHeight, checkname );
|
|
|
|
if ( !silent )
|
|
Com_Printf( "Wrote %s\n", checkname );
|
|
}
|
|
|
|
//============================================================================
|
|
|
|
/*
|
|
** GL_SetDefaultState
|
|
*/
|
|
void GL_SetDefaultState( void )
|
|
{
|
|
qglClearDepth( 1.0f );
|
|
|
|
qglCullFace(GL_FRONT);
|
|
|
|
qglColor4f (1,1,1,1);
|
|
|
|
// initialize downstream texture unit if we're running
|
|
// in a multitexture environment
|
|
if ( qglActiveTextureARB ) {
|
|
GL_SelectTexture( 1 );
|
|
GL_TextureMode( r_textureMode->string );
|
|
GL_TexEnv( GL_MODULATE );
|
|
qglDisable( GL_TEXTURE_2D );
|
|
GL_SelectTexture( 0 );
|
|
}
|
|
|
|
qglEnable(GL_TEXTURE_2D);
|
|
GL_TextureMode( r_textureMode->string );
|
|
GL_TexEnv( GL_MODULATE );
|
|
|
|
qglShadeModel( GL_SMOOTH );
|
|
qglDepthFunc( GL_LEQUAL );
|
|
|
|
// the vertex array is always enabled, but the color and texture
|
|
// arrays are enabled and disabled around the compiled vertex array call
|
|
qglEnableClientState (GL_VERTEX_ARRAY);
|
|
|
|
//
|
|
// make sure our GL state vector is set correctly
|
|
//
|
|
glState.glStateBits = GLS_DEPTHTEST_DISABLE | GLS_DEPTHMASK_TRUE;
|
|
|
|
#ifndef HAVE_GLES
|
|
qglPolygonMode (GL_FRONT_AND_BACK, GL_FILL);
|
|
#endif
|
|
qglDepthMask( GL_TRUE );
|
|
qglDisable( GL_DEPTH_TEST );
|
|
qglEnable( GL_SCISSOR_TEST );
|
|
qglDisable( GL_CULL_FACE );
|
|
qglDisable( GL_BLEND );
|
|
|
|
#ifdef HAVE_GLES
|
|
glPixelStorei(GL_PACK_ALIGNMENT, 1);
|
|
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
|
|
#endif
|
|
}
|
|
|
|
|
|
/*
|
|
================
|
|
R_PrintLongString
|
|
|
|
Workaround for Com_Printf's 1024 characters buffer limit.
|
|
================
|
|
*/
|
|
void R_PrintLongString(const char *string)
|
|
{
|
|
char buffer[1024];
|
|
const char *p = string;
|
|
int remainingLength = strlen(string);
|
|
|
|
while (remainingLength > 0)
|
|
{
|
|
// Take as much characters as possible from the string without splitting words between buffers
|
|
// This avoids the client console splitting a word up when one half fits on the current line,
|
|
// but the second half would have to be written on a new line
|
|
int charsToTake = sizeof(buffer) - 1;
|
|
if (remainingLength > charsToTake) {
|
|
while (p[charsToTake - 1] > ' ' && p[charsToTake] > ' ') {
|
|
charsToTake--;
|
|
if (charsToTake == 0) {
|
|
charsToTake = sizeof(buffer) - 1;
|
|
break;
|
|
}
|
|
}
|
|
} else if (remainingLength < charsToTake) {
|
|
charsToTake = remainingLength;
|
|
}
|
|
|
|
Q_strncpyz( buffer, p, charsToTake + 1 );
|
|
Com_Printf( "%s", buffer );
|
|
remainingLength -= charsToTake;
|
|
p += charsToTake;
|
|
}
|
|
}
|
|
|
|
/*
|
|
================
|
|
GfxInfo_f
|
|
================
|
|
*/
|
|
extern bool g_bTextureRectangleHack;
|
|
|
|
void GfxInfo_f( void )
|
|
{
|
|
const char *enablestrings[] =
|
|
{
|
|
"disabled",
|
|
"enabled"
|
|
};
|
|
const char *fsstrings[] =
|
|
{
|
|
"windowed",
|
|
"fullscreen"
|
|
};
|
|
const char *noborderstrings[] =
|
|
{
|
|
"",
|
|
"noborder "
|
|
};
|
|
|
|
const char *tc_table[] =
|
|
{
|
|
"None",
|
|
"GL_S3_s3tc",
|
|
"GL_EXT_texture_compression_s3tc",
|
|
};
|
|
|
|
int fullscreen = ri.Cvar_VariableIntegerValue("r_fullscreen");
|
|
int noborder = ri.Cvar_VariableIntegerValue("r_noborder");
|
|
|
|
ri.Printf( PRINT_ALL, "\nGL_VENDOR: %s\n", glConfig.vendor_string );
|
|
ri.Printf( PRINT_ALL, "GL_RENDERER: %s\n", glConfig.renderer_string );
|
|
ri.Printf( PRINT_ALL, "GL_VERSION: %s\n", glConfig.version_string );
|
|
R_PrintLongString(glConfig.extensions_string);
|
|
Com_Printf ("\n");
|
|
ri.Printf( PRINT_ALL, "GL_MAX_TEXTURE_SIZE: %d\n", glConfig.maxTextureSize );
|
|
ri.Printf( PRINT_ALL, "GL_MAX_ACTIVE_TEXTURES_ARB: %d\n", glConfig.maxActiveTextures );
|
|
ri.Printf( PRINT_ALL, "\nPIXELFORMAT: color(%d-bits) Z(%d-bit) stencil(%d-bits)\n", glConfig.colorBits, glConfig.depthBits, glConfig.stencilBits );
|
|
ri.Printf( PRINT_ALL, "MODE: %d, %d x %d %s%s hz:",
|
|
ri.Cvar_VariableIntegerValue("r_mode"),
|
|
glConfig.vidWidth, glConfig.vidHeight,
|
|
fullscreen == 0 ? noborderstrings[noborder == 1] : noborderstrings[0],
|
|
fsstrings[fullscreen == 1] );
|
|
if ( glConfig.displayFrequency )
|
|
{
|
|
ri.Printf( PRINT_ALL, "%d\n", glConfig.displayFrequency );
|
|
}
|
|
else
|
|
{
|
|
ri.Printf( PRINT_ALL, "N/A\n" );
|
|
}
|
|
if ( glConfig.deviceSupportsGamma )
|
|
{
|
|
ri.Printf( PRINT_ALL, "GAMMA: hardware w/ %d overbright bits\n", tr.overbrightBits );
|
|
}
|
|
else
|
|
{
|
|
ri.Printf( PRINT_ALL, "GAMMA: software w/ %d overbright bits\n", tr.overbrightBits );
|
|
}
|
|
|
|
// rendering primitives
|
|
{
|
|
int primitives;
|
|
|
|
// default is to use triangles if compiled vertex arrays are present
|
|
ri.Printf( PRINT_ALL, "rendering primitives: " );
|
|
primitives = r_primitives->integer;
|
|
if ( primitives == 0 ) {
|
|
if ( qglLockArraysEXT ) {
|
|
primitives = 2;
|
|
} else {
|
|
primitives = 1;
|
|
}
|
|
}
|
|
if ( primitives == -1 ) {
|
|
ri.Printf( PRINT_ALL, "none\n" );
|
|
} else if ( primitives == 2 ) {
|
|
ri.Printf( PRINT_ALL, "single glDrawElements\n" );
|
|
} else if ( primitives == 1 ) {
|
|
ri.Printf( PRINT_ALL, "multiple glArrayElement\n" );
|
|
} else if ( primitives == 3 ) {
|
|
ri.Printf( PRINT_ALL, "multiple glColor4ubv + glTexCoord2fv + glVertex3fv\n" );
|
|
}
|
|
}
|
|
|
|
ri.Printf( PRINT_ALL, "texturemode: %s\n", r_textureMode->string );
|
|
ri.Printf( PRINT_ALL, "picmip: %d\n", r_picmip->integer );
|
|
ri.Printf( PRINT_ALL, "texture bits: %d\n", r_texturebits->integer );
|
|
if ( r_texturebitslm->integer > 0 )
|
|
ri.Printf( PRINT_ALL, "lightmap texture bits: %d\n", r_texturebitslm->integer );
|
|
ri.Printf( PRINT_ALL, "multitexture: %s\n", enablestrings[qglActiveTextureARB != 0] );
|
|
ri.Printf( PRINT_ALL, "compiled vertex arrays: %s\n", enablestrings[qglLockArraysEXT != 0 ] );
|
|
ri.Printf( PRINT_ALL, "texenv add: %s\n", enablestrings[glConfig.textureEnvAddAvailable != 0] );
|
|
ri.Printf( PRINT_ALL, "compressed textures: %s\n", enablestrings[glConfig.textureCompression != TC_NONE] );
|
|
ri.Printf( PRINT_ALL, "compressed lightmaps: %s\n", enablestrings[(r_ext_compressed_lightmaps->integer != 0 && glConfig.textureCompression != TC_NONE)] );
|
|
ri.Printf( PRINT_ALL, "texture compression method: %s\n", tc_table[glConfig.textureCompression] );
|
|
ri.Printf( PRINT_ALL, "anisotropic filtering: %s ", enablestrings[(r_ext_texture_filter_anisotropic->integer != 0) && glConfig.maxTextureFilterAnisotropy] );
|
|
if (r_ext_texture_filter_anisotropic->integer != 0 && glConfig.maxTextureFilterAnisotropy)
|
|
{
|
|
if (Q_isintegral(r_ext_texture_filter_anisotropic->value))
|
|
ri.Printf( PRINT_ALL, "(%i of ", (int)r_ext_texture_filter_anisotropic->value);
|
|
else
|
|
ri.Printf( PRINT_ALL, "(%f of ", r_ext_texture_filter_anisotropic->value);
|
|
|
|
if (Q_isintegral(glConfig.maxTextureFilterAnisotropy))
|
|
ri.Printf( PRINT_ALL, "%i)\n", (int)glConfig.maxTextureFilterAnisotropy);
|
|
else
|
|
ri.Printf( PRINT_ALL, "%f)\n", glConfig.maxTextureFilterAnisotropy);
|
|
}
|
|
ri.Printf( PRINT_ALL, "Dynamic Glow: %s\n", enablestrings[r_DynamicGlow->integer ? 1 : 0] );
|
|
if (g_bTextureRectangleHack) Com_Printf ("Dynamic Glow ATI BAD DRIVER HACK %s\n", enablestrings[g_bTextureRectangleHack] );
|
|
|
|
if ( r_finish->integer ) {
|
|
ri.Printf( PRINT_ALL, "Forcing glFinish\n" );
|
|
}
|
|
|
|
int displayRefresh = ri.Cvar_VariableIntegerValue("r_displayRefresh");
|
|
if ( displayRefresh ) {
|
|
ri.Printf( PRINT_ALL, "Display refresh set to %d\n", displayRefresh);
|
|
}
|
|
if (tr.world)
|
|
{
|
|
ri.Printf( PRINT_ALL, "Light Grid size set to (%.2f %.2f %.2f)\n", tr.world->lightGridSize[0], tr.world->lightGridSize[1], tr.world->lightGridSize[2] );
|
|
}
|
|
}
|
|
|
|
void R_AtiHackToggle_f(void)
|
|
{
|
|
g_bTextureRectangleHack = !g_bTextureRectangleHack;
|
|
}
|
|
|
|
/************************************************************************************************
|
|
* R_FogDistance_f *
|
|
* Console command to change the global fog opacity distance. If you specify nothing on the *
|
|
* command line, it will display the current fog opacity distance. Specifying a float *
|
|
* representing the world units away the fog should be completely opaque will change the *
|
|
* value. *
|
|
* *
|
|
* Input *
|
|
* none *
|
|
* *
|
|
* Output / Return *
|
|
* none *
|
|
* *
|
|
************************************************************************************************/
|
|
void R_FogDistance_f(void)
|
|
{
|
|
float distance;
|
|
|
|
if (!tr.world)
|
|
{
|
|
ri.Printf(PRINT_ALL, "R_FogDistance_f: World is not initialized\n");
|
|
return;
|
|
}
|
|
|
|
if (tr.world->globalFog == -1)
|
|
{
|
|
ri.Printf(PRINT_ALL, "R_FogDistance_f: World does not have a global fog\n");
|
|
return;
|
|
}
|
|
|
|
if (ri.Cmd_Argc() <= 1)
|
|
{
|
|
// should not ever be 0.0
|
|
// if (tr.world->fogs[tr.world->globalFog].tcScale == 0.0)
|
|
// {
|
|
// distance = 0.0;
|
|
// }
|
|
// else
|
|
{
|
|
distance = 1.0 / (8.0 * tr.world->fogs[tr.world->globalFog].tcScale);
|
|
}
|
|
|
|
ri.Printf(PRINT_ALL, "R_FogDistance_f: Current Distance: %.0f\n", distance);
|
|
return;
|
|
}
|
|
|
|
if (ri.Cmd_Argc() != 2)
|
|
{
|
|
ri.Printf(PRINT_ALL, "R_FogDistance_f: Invalid number of arguments to set distance\n");
|
|
return;
|
|
}
|
|
|
|
distance = atof(ri.Cmd_Argv(1));
|
|
if (distance < 1.0)
|
|
{
|
|
distance = 1.0;
|
|
}
|
|
tr.world->fogs[tr.world->globalFog].parms.depthForOpaque = distance;
|
|
tr.world->fogs[tr.world->globalFog].tcScale = 1.0 / ( distance * 8 );
|
|
}
|
|
|
|
/************************************************************************************************
|
|
* R_FogColor_f *
|
|
* Console command to change the global fog color. Specifying nothing on the command will *
|
|
* display the current global fog color. Specifying a float R G B values between 0.0 and *
|
|
* 1.0 will change the fog color. *
|
|
* *
|
|
* Input *
|
|
* none *
|
|
* *
|
|
* Output / Return *
|
|
* none *
|
|
* *
|
|
************************************************************************************************/
|
|
void R_FogColor_f(void)
|
|
{
|
|
if (!tr.world)
|
|
{
|
|
ri.Printf(PRINT_ALL, "R_FogColor_f: World is not initialized\n");
|
|
return;
|
|
}
|
|
|
|
if (tr.world->globalFog == -1)
|
|
{
|
|
ri.Printf(PRINT_ALL, "R_FogColor_f: World does not have a global fog\n");
|
|
return;
|
|
}
|
|
|
|
if (ri.Cmd_Argc() <= 1)
|
|
{
|
|
unsigned i = tr.world->fogs[tr.world->globalFog].colorInt;
|
|
|
|
ri.Printf(PRINT_ALL, "R_FogColor_f: Current Color: %0f %0f %0f\n",
|
|
( (byte *)&i )[0] / 255.0,
|
|
( (byte *)&i )[1] / 255.0,
|
|
( (byte *)&i )[2] / 255.0);
|
|
return;
|
|
}
|
|
|
|
if (ri.Cmd_Argc() != 4)
|
|
{
|
|
ri.Printf(PRINT_ALL, "R_FogColor_f: Invalid number of arguments to set color\n");
|
|
return;
|
|
}
|
|
|
|
tr.world->fogs[tr.world->globalFog].parms.color[0] = atof(ri.Cmd_Argv(1));
|
|
tr.world->fogs[tr.world->globalFog].parms.color[1] = atof(ri.Cmd_Argv(2));
|
|
tr.world->fogs[tr.world->globalFog].parms.color[2] = atof(ri.Cmd_Argv(3));
|
|
tr.world->fogs[tr.world->globalFog].colorInt = ColorBytes4 ( atof(ri.Cmd_Argv(1)) * tr.identityLight,
|
|
atof(ri.Cmd_Argv(2)) * tr.identityLight,
|
|
atof(ri.Cmd_Argv(3)) * tr.identityLight, 1.0 );
|
|
}
|
|
|
|
typedef struct consoleCommand_s {
|
|
const char *cmd;
|
|
xcommand_t func;
|
|
} consoleCommand_t;
|
|
|
|
void R_ReloadFonts_f( void );
|
|
|
|
static consoleCommand_t commands[] = {
|
|
{ "imagelist", R_ImageList_f },
|
|
{ "shaderlist", R_ShaderList_f },
|
|
{ "skinlist", R_SkinList_f },
|
|
{ "fontlist", R_FontList_f },
|
|
{ "screenshot", R_ScreenShot_f },
|
|
{ "screenshot_png", R_ScreenShotPNG_f },
|
|
{ "screenshot_tga", R_ScreenShotTGA_f },
|
|
{ "gfxinfo", GfxInfo_f },
|
|
{ "r_atihack", R_AtiHackToggle_f },
|
|
{ "r_we", R_WorldEffect_f },
|
|
{ "imagecacheinfo", RE_RegisterImages_Info_f },
|
|
{ "modellist", R_Modellist_f },
|
|
{ "modelcacheinfo", RE_RegisterModels_Info_f },
|
|
{ "r_fogDistance", R_FogDistance_f },
|
|
{ "r_fogColor", R_FogColor_f },
|
|
{ "r_reloadfonts", R_ReloadFonts_f },
|
|
};
|
|
|
|
static const size_t numCommands = ARRAY_LEN( commands );
|
|
|
|
#ifdef _DEBUG
|
|
#define MIN_PRIMITIVES -1
|
|
#else
|
|
#define MIN_PRIMITIVES 0
|
|
#endif
|
|
#define MAX_PRIMITIVES 3
|
|
|
|
/*
|
|
===============
|
|
R_Register
|
|
===============
|
|
*/
|
|
void R_Register( void )
|
|
{
|
|
//
|
|
// latched and archived variables
|
|
//
|
|
|
|
r_allowExtensions = ri.Cvar_Get( "r_allowExtensions", "1", CVAR_ARCHIVE_ND | CVAR_LATCH );
|
|
r_ext_compressed_textures = ri.Cvar_Get( "r_ext_compress_textures", "0", CVAR_ARCHIVE_ND | CVAR_LATCH );
|
|
r_ext_compressed_lightmaps = ri.Cvar_Get( "r_ext_compress_lightmaps", "0", CVAR_ARCHIVE_ND | CVAR_LATCH );
|
|
r_ext_preferred_tc_method = ri.Cvar_Get( "r_ext_preferred_tc_method", "0", CVAR_ARCHIVE_ND | CVAR_LATCH );
|
|
r_ext_gamma_control = ri.Cvar_Get( "r_ext_gamma_control", "0", CVAR_ARCHIVE_ND | CVAR_LATCH );
|
|
r_ext_multitexture = ri.Cvar_Get( "r_ext_multitexture", "1", CVAR_ARCHIVE_ND | CVAR_LATCH );
|
|
r_ext_compiled_vertex_array = ri.Cvar_Get( "r_ext_compiled_vertex_array", "1", CVAR_ARCHIVE_ND | CVAR_LATCH);
|
|
r_ext_texture_env_add = ri.Cvar_Get( "r_ext_texture_env_add", "1", CVAR_ARCHIVE_ND | CVAR_LATCH);
|
|
r_ext_texture_filter_anisotropic = ri.Cvar_Get( "r_ext_texture_filter_anisotropic", "16", CVAR_ARCHIVE_ND );
|
|
|
|
r_DynamicGlow = ri.Cvar_Get( "r_DynamicGlow", "0", CVAR_ARCHIVE_ND );
|
|
r_DynamicGlowPasses = ri.Cvar_Get( "r_DynamicGlowPasses", "5", CVAR_ARCHIVE_ND );
|
|
r_DynamicGlowDelta = ri.Cvar_Get( "r_DynamicGlowDelta", "0.8f", CVAR_ARCHIVE_ND );
|
|
r_DynamicGlowIntensity = ri.Cvar_Get( "r_DynamicGlowIntensity", "1.13f", CVAR_ARCHIVE_ND );
|
|
r_DynamicGlowSoft = ri.Cvar_Get( "r_DynamicGlowSoft", "1", CVAR_ARCHIVE_ND );
|
|
r_DynamicGlowWidth = ri.Cvar_Get( "r_DynamicGlowWidth", "320", CVAR_ARCHIVE_ND | CVAR_LATCH );
|
|
r_DynamicGlowHeight = ri.Cvar_Get( "r_DynamicGlowHeight", "240", CVAR_ARCHIVE_ND | CVAR_LATCH );
|
|
|
|
#ifndef JK2_MODE
|
|
r_picmip = ri.Cvar_Get ("r_picmip", "1", CVAR_ARCHIVE | CVAR_LATCH );
|
|
r_detailTextures = ri.Cvar_Get( "r_detailtextures", "0", CVAR_ARCHIVE_ND | CVAR_LATCH );
|
|
#else
|
|
r_picmip = ri.Cvar_Get ("r_picmip", "0", CVAR_ARCHIVE | CVAR_LATCH );
|
|
r_detailTextures = ri.Cvar_Get( "r_detailtextures", "1", CVAR_ARCHIVE_ND | CVAR_LATCH );
|
|
#endif
|
|
ri.Cvar_CheckRange( r_picmip, 0, 16, qtrue );
|
|
r_colorMipLevels = ri.Cvar_Get ("r_colorMipLevels", "0", CVAR_LATCH );
|
|
r_texturebits = ri.Cvar_Get( "r_texturebits", "0", CVAR_ARCHIVE_ND | CVAR_LATCH );
|
|
r_texturebitslm = ri.Cvar_Get( "r_texturebitslm", "0", CVAR_ARCHIVE_ND | CVAR_LATCH );
|
|
r_overBrightBits = ri.Cvar_Get ("r_overBrightBits", "1", CVAR_ARCHIVE_ND | CVAR_LATCH );
|
|
r_mapOverBrightBits = ri.Cvar_Get( "r_mapOverBrightBits", "0", CVAR_ARCHIVE_ND|CVAR_LATCH );
|
|
r_simpleMipMaps = ri.Cvar_Get( "r_simpleMipMaps", "1", CVAR_ARCHIVE_ND | CVAR_LATCH );
|
|
r_vertexLight = ri.Cvar_Get( "r_vertexLight", "0", CVAR_ARCHIVE | CVAR_LATCH );
|
|
r_subdivisions = ri.Cvar_Get ("r_subdivisions", "4", CVAR_ARCHIVE_ND | CVAR_LATCH);
|
|
ri.Cvar_CheckRange( r_subdivisions, 0, 80, qfalse );
|
|
r_intensity = ri.Cvar_Get ("r_intensity", "1.07", CVAR_LATCH|CVAR_ARCHIVE );
|
|
|
|
//
|
|
// temporary latched variables that can only change over a restart
|
|
//
|
|
r_fullbright = ri.Cvar_Get ("r_fullbright", "0", CVAR_LATCH );
|
|
r_singleShader = ri.Cvar_Get ("r_singleShader", "0", CVAR_CHEAT | CVAR_LATCH );
|
|
|
|
//
|
|
// archived variables that can change at any time
|
|
//
|
|
r_lodCurveError = ri.Cvar_Get( "r_lodCurveError", "1000", CVAR_ARCHIVE_ND );
|
|
r_lodbias = ri.Cvar_Get( "r_lodbias", "0", CVAR_ARCHIVE_ND );
|
|
#ifndef JK2_MODE
|
|
r_flares = ri.Cvar_Get ("r_flares", "0", CVAR_ARCHIVE_ND );
|
|
#else
|
|
r_flares = ri.Cvar_Get ("r_flares", "1", CVAR_ARCHIVE_ND );
|
|
#endif
|
|
r_lodscale = ri.Cvar_Get( "r_lodscale", "10", CVAR_ARCHIVE_ND );
|
|
|
|
r_znear = ri.Cvar_Get( "r_znear", "4", CVAR_ARCHIVE_ND ); //if set any lower, you lose a lot of precision in the distance
|
|
ri.Cvar_CheckRange( r_znear, 0.001f, 10, qfalse ); // was qtrue in JA, is qfalse properly in ioq3
|
|
r_ignoreGLErrors = ri.Cvar_Get( "r_ignoreGLErrors", "1", CVAR_ARCHIVE_ND );
|
|
r_fastsky = ri.Cvar_Get( "r_fastsky", "0", CVAR_ARCHIVE_ND );
|
|
r_drawSun = ri.Cvar_Get( "r_drawSun", "0", CVAR_ARCHIVE_ND );
|
|
r_dynamiclight = ri.Cvar_Get( "r_dynamiclight", "1", CVAR_ARCHIVE );
|
|
// rjr - removed for hacking
|
|
// r_dlightBacks = ri.Cvar_Get( "r_dlightBacks", "0", CVAR_ARCHIVE );
|
|
r_finish = ri.Cvar_Get ("r_finish", "0", CVAR_ARCHIVE_ND);
|
|
r_textureMode = ri.Cvar_Get( "r_textureMode", "GL_LINEAR_MIPMAP_LINEAR", CVAR_ARCHIVE );
|
|
if (strstr(ri.Cvar_VariableString("openXRHMD"), "pico") != NULL) {
|
|
r_gamma = ri.Cvar_Get( "r_gamma", "1.30", CVAR_ARCHIVE );
|
|
} else {
|
|
r_gamma = ri.Cvar_Get( "r_gamma", "1.15", CVAR_ARCHIVE );
|
|
}
|
|
r_facePlaneCull = ri.Cvar_Get ("r_facePlaneCull", "1", CVAR_ARCHIVE_ND );
|
|
|
|
r_dlightStyle = ri.Cvar_Get ("r_dlightStyle", "1", CVAR_ARCHIVE_ND);
|
|
r_surfaceSprites = ri.Cvar_Get ("r_surfaceSprites", "1", CVAR_ARCHIVE_ND);
|
|
r_surfaceWeather = ri.Cvar_Get ("r_surfaceWeather", "0", CVAR_TEMP);
|
|
|
|
r_windSpeed = ri.Cvar_Get ("r_windSpeed", "0", 0);
|
|
r_windAngle = ri.Cvar_Get ("r_windAngle", "0", 0);
|
|
r_windGust = ri.Cvar_Get ("r_windGust", "0", 0);
|
|
r_windDampFactor = ri.Cvar_Get ("r_windDampFactor", "0.1", 0);
|
|
r_windPointForce = ri.Cvar_Get ("r_windPointForce", "0", 0);
|
|
r_windPointX = ri.Cvar_Get ("r_windPointX", "0", 0);
|
|
r_windPointY = ri.Cvar_Get ("r_windPointY", "0", 0);
|
|
|
|
r_primitives = ri.Cvar_Get( "r_primitives", "0", CVAR_ARCHIVE_ND );
|
|
ri.Cvar_CheckRange( r_primitives, MIN_PRIMITIVES, MAX_PRIMITIVES, qtrue );
|
|
|
|
r_ambientScale = ri.Cvar_Get( "r_ambientScale", "0.5", CVAR_CHEAT );
|
|
r_directedScale = ri.Cvar_Get( "r_directedScale", "1", CVAR_CHEAT );
|
|
|
|
//
|
|
// temporary variables that can change at any time
|
|
//
|
|
r_showImages = ri.Cvar_Get( "r_showImages", "0", CVAR_CHEAT );
|
|
|
|
r_debugLight = ri.Cvar_Get( "r_debuglight", "0", CVAR_TEMP );
|
|
r_debugStyle = ri.Cvar_Get( "r_debugStyle", "-1", CVAR_CHEAT );
|
|
r_debugSort = ri.Cvar_Get( "r_debugSort", "0", CVAR_CHEAT );
|
|
|
|
r_nocurves = ri.Cvar_Get ("r_nocurves", "0", CVAR_CHEAT );
|
|
r_drawworld = ri.Cvar_Get ("r_drawworld", "1", CVAR_CHEAT );
|
|
#ifdef JK2_MODE
|
|
r_drawfog = ri.Cvar_Get ("r_drawfog", "1", CVAR_CHEAT );
|
|
#else
|
|
r_drawfog = ri.Cvar_Get ("r_drawfog", "2", CVAR_CHEAT );
|
|
#endif
|
|
r_lightmap = ri.Cvar_Get ("r_lightmap", "0", CVAR_CHEAT );
|
|
r_portalOnly = ri.Cvar_Get ("r_portalOnly", "0", CVAR_CHEAT );
|
|
|
|
r_skipBackEnd = ri.Cvar_Get ("r_skipBackEnd", "0", CVAR_CHEAT);
|
|
|
|
r_measureOverdraw = ri.Cvar_Get( "r_measureOverdraw", "0", CVAR_CHEAT );
|
|
r_norefresh = ri.Cvar_Get ("r_norefresh", "0", CVAR_CHEAT);
|
|
r_drawentities = ri.Cvar_Get ("r_drawentities", "1", CVAR_CHEAT );
|
|
r_ignore = ri.Cvar_Get( "r_ignore", "1", CVAR_TEMP );
|
|
r_nocull = ri.Cvar_Get ("r_nocull", "0", CVAR_CHEAT);
|
|
r_novis = ri.Cvar_Get ("r_novis", "0", CVAR_CHEAT);
|
|
r_showcluster = ri.Cvar_Get ("r_showcluster", "0", CVAR_CHEAT);
|
|
r_speeds = ri.Cvar_Get ("r_speeds", "0", CVAR_CHEAT);
|
|
r_verbose = ri.Cvar_Get( "r_verbose", "0", CVAR_CHEAT );
|
|
r_logFile = ri.Cvar_Get( "r_logFile", "0", CVAR_CHEAT );
|
|
r_debugSurface = ri.Cvar_Get ("r_debugSurface", "0", CVAR_CHEAT);
|
|
r_nobind = ri.Cvar_Get ("r_nobind", "0", CVAR_CHEAT);
|
|
r_showtris = ri.Cvar_Get ("r_showtris", "0", CVAR_CHEAT);
|
|
r_showtriscolor = ri.Cvar_Get ("r_showtriscolor", "0", CVAR_ARCHIVE_ND);
|
|
r_showsky = ri.Cvar_Get ("r_showsky", "0", CVAR_CHEAT);
|
|
r_shownormals = ri.Cvar_Get ("r_shownormals", "0", CVAR_CHEAT);
|
|
r_clear = ri.Cvar_Get ("r_clear", "0", CVAR_CHEAT);
|
|
r_offsetFactor = ri.Cvar_Get( "r_offsetfactor", "-1", CVAR_CHEAT );
|
|
r_offsetUnits = ri.Cvar_Get( "r_offsetunits", "-2", CVAR_CHEAT );
|
|
r_lockpvs = ri.Cvar_Get ("r_lockpvs", "0", CVAR_CHEAT);
|
|
r_noportals = ri.Cvar_Get ("r_noportals", "0", CVAR_CHEAT);
|
|
r_shadows = ri.Cvar_Get( "cg_shadows", "1", 0 );
|
|
r_shadowRange = ri.Cvar_Get( "r_shadowRange", "1000", CVAR_ARCHIVE_ND );
|
|
|
|
/*
|
|
Ghoul2 Insert Start
|
|
*/
|
|
r_noGhoul2 = ri.Cvar_Get( "r_noghoul2", "0", CVAR_CHEAT);
|
|
r_Ghoul2AnimSmooth = ri.Cvar_Get( "r_ghoul2animsmooth", "0.25", 0);
|
|
r_Ghoul2UnSqash = ri.Cvar_Get( "r_ghoul2unsquash", "1", 0);
|
|
r_Ghoul2TimeBase = ri.Cvar_Get( "r_ghoul2timebase", "2", 0);
|
|
r_Ghoul2NoLerp = ri.Cvar_Get( "r_ghoul2nolerp", "0", 0);
|
|
r_Ghoul2NoBlend = ri.Cvar_Get( "r_ghoul2noblend", "0", 0);
|
|
r_Ghoul2BlendMultiplier = ri.Cvar_Get( "r_ghoul2blendmultiplier", "1", 0);
|
|
r_Ghoul2UnSqashAfterSmooth = ri.Cvar_Get( "r_ghoul2unsquashaftersmooth", "1", 0);
|
|
|
|
broadsword = ri.Cvar_Get( "broadsword", "1", 0);
|
|
broadsword_kickbones = ri.Cvar_Get( "broadsword_kickbones", "1", 0);
|
|
broadsword_kickorigin = ri.Cvar_Get( "broadsword_kickorigin", "1", 0);
|
|
broadsword_dontstopanim = ri.Cvar_Get( "broadsword_dontstopanim", "0", 0);
|
|
broadsword_waitforshot = ri.Cvar_Get( "broadsword_waitforshot", "0", 0);
|
|
broadsword_playflop = ri.Cvar_Get( "broadsword_playflop", "1", 0);
|
|
broadsword_smallbbox = ri.Cvar_Get( "broadsword_smallbbox", "0", 0);
|
|
broadsword_extra1 = ri.Cvar_Get( "broadsword_extra1", "0", 0);
|
|
broadsword_extra2 = ri.Cvar_Get( "broadsword_extra2", "0", 0);
|
|
broadsword_effcorr = ri.Cvar_Get( "broadsword_effcorr", "1", 0);
|
|
broadsword_ragtobase = ri.Cvar_Get( "broadsword_ragtobase", "2", 0);
|
|
broadsword_dircap = ri.Cvar_Get( "broadsword_dircap", "64", 0);
|
|
|
|
/*
|
|
Ghoul2 Insert End
|
|
*/
|
|
|
|
sv_mapname = ri.Cvar_Get ( "mapname", "nomap", CVAR_SERVERINFO | CVAR_ROM );
|
|
sv_mapChecksum = ri.Cvar_Get ( "sv_mapChecksum", "", CVAR_ROM );
|
|
se_language = ri.Cvar_Get ( "se_language", "english", CVAR_ARCHIVE | CVAR_NORESTART );
|
|
#ifdef JK2_MODE
|
|
sp_language = ri.Cvar_Get ( "sp_language", va("%d", SP_LANGUAGE_ENGLISH), CVAR_ARCHIVE | CVAR_NORESTART );
|
|
#endif
|
|
com_buildScript = ri.Cvar_Get ( "com_buildScript", "0", 0 );
|
|
|
|
r_modelpoolmegs = ri.Cvar_Get("r_modelpoolmegs", "20", CVAR_ARCHIVE);
|
|
if (ri.LowPhysicalMemory() )
|
|
{
|
|
ri.Cvar_Set("r_modelpoolmegs", "0");
|
|
}
|
|
|
|
r_environmentMapping = ri.Cvar_Get( "r_environmentMapping", "1", CVAR_ARCHIVE_ND );
|
|
|
|
r_screenshotJpegQuality = ri.Cvar_Get( "r_screenshotJpegQuality", "95", CVAR_ARCHIVE_ND );
|
|
|
|
ri.Cvar_CheckRange( r_screenshotJpegQuality, 10, 100, qtrue );
|
|
|
|
for ( size_t i = 0; i < numCommands; i++ )
|
|
ri.Cmd_AddCommand( commands[i].cmd, commands[i].func );
|
|
}
|
|
|
|
// need to do this hackery so ghoul2 doesn't crash the game because of ITS hackery...
|
|
//
|
|
void R_ClearStuffToStopGhoul2CrashingThings(void)
|
|
{
|
|
memset( &tr, 0, sizeof( tr ) );
|
|
}
|
|
|
|
/*
|
|
===============
|
|
R_Init
|
|
===============
|
|
*/
|
|
extern void R_InitWorldEffects();
|
|
void R_Init( void ) {
|
|
int err;
|
|
int i;
|
|
|
|
//ri.Printf( PRINT_ALL, "----- R_Init -----\n" );
|
|
|
|
ShaderEntryPtrs_Clear();
|
|
|
|
// clear all our internal state
|
|
memset( &tr, 0, sizeof( tr ) );
|
|
memset( &backEnd, 0, sizeof( backEnd ) );
|
|
memset( &tess, 0, sizeof( tess ) );
|
|
|
|
#ifndef FINAL_BUILD
|
|
if ( (intptr_t)tess.xyz & 15 ) {
|
|
Com_Printf( "WARNING: tess.xyz not 16 byte aligned\n" );
|
|
}
|
|
#endif
|
|
|
|
//
|
|
// init function tables
|
|
//
|
|
for ( i = 0; i < FUNCTABLE_SIZE; i++ )
|
|
{
|
|
tr.sinTable[i] = sin( DEG2RAD( i * 360.0f / ( ( float ) ( FUNCTABLE_SIZE - 1 ) ) ) );
|
|
tr.squareTable[i] = ( i < FUNCTABLE_SIZE/2 ) ? 1.0f : -1.0f;
|
|
tr.sawToothTable[i] = (float)i / FUNCTABLE_SIZE;
|
|
tr.inverseSawToothTable[i] = 1.0f - tr.sawToothTable[i];
|
|
|
|
if ( i < FUNCTABLE_SIZE / 2 )
|
|
{
|
|
if ( i < FUNCTABLE_SIZE / 4 )
|
|
{
|
|
tr.triangleTable[i] = ( float ) i / ( FUNCTABLE_SIZE / 4 );
|
|
}
|
|
else
|
|
{
|
|
tr.triangleTable[i] = 1.0f - tr.triangleTable[i-FUNCTABLE_SIZE / 4];
|
|
}
|
|
}
|
|
else
|
|
{
|
|
tr.triangleTable[i] = -tr.triangleTable[i-FUNCTABLE_SIZE/2];
|
|
}
|
|
}
|
|
R_InitFogTable();
|
|
|
|
R_ImageLoader_Init();
|
|
R_NoiseInit();
|
|
R_Register();
|
|
|
|
backEndData = (backEndData_t *) R_Hunk_Alloc( sizeof( backEndData_t ), qtrue );
|
|
R_InitNextFrame();
|
|
|
|
const color4ub_t color = {0xff, 0xff, 0xff, 0xff};
|
|
for ( i = 0; i < MAX_LIGHT_STYLES; i++ ) {
|
|
byteAlias_t *ba = (byteAlias_t *)&color;
|
|
RE_SetLightStyle( i, ba->i );
|
|
}
|
|
InitOpenGL();
|
|
|
|
R_InitImages();
|
|
R_InitShaders();
|
|
R_InitSkins();
|
|
R_ModelInit();
|
|
R_InitWorldEffects();
|
|
R_InitFonts();
|
|
|
|
err = qglGetError();
|
|
if ( err != GL_NO_ERROR )
|
|
ri.Printf (PRINT_ALL, "glGetError() = 0x%x\n", err);
|
|
|
|
RestoreGhoul2InfoArray();
|
|
// print info
|
|
GfxInfo_f();
|
|
|
|
//ri.Printf( PRINT_ALL, "----- finished R_Init -----\n" );
|
|
}
|
|
|
|
/*
|
|
===============
|
|
RE_Shutdown
|
|
===============
|
|
*/
|
|
extern void R_ShutdownWorldEffects(void);
|
|
void RE_Shutdown( qboolean destroyWindow, qboolean restarting ) {
|
|
for ( size_t i = 0; i < numCommands; i++ )
|
|
ri.Cmd_RemoveCommand( commands[i].cmd );
|
|
|
|
#ifndef HAVE_GLES
|
|
if ( r_DynamicGlow && r_DynamicGlow->integer )
|
|
{
|
|
// Release the Glow Vertex Shader.
|
|
if ( tr.glowVShader )
|
|
{
|
|
qglDeleteProgramsARB( 1, &tr.glowVShader );
|
|
}
|
|
|
|
// Release Pixel Shader.
|
|
if ( tr.glowPShader )
|
|
{
|
|
if ( qglCombinerParameteriNV )
|
|
{
|
|
// Release the Glow Regcom call list.
|
|
qglDeleteLists( tr.glowPShader, 1 );
|
|
}
|
|
else if ( qglGenProgramsARB )
|
|
{
|
|
// Release the Glow Fragment Shader.
|
|
qglDeleteProgramsARB( 1, &tr.glowPShader );
|
|
}
|
|
}
|
|
|
|
// Release the scene glow texture.
|
|
qglDeleteTextures( 1, &tr.screenGlow );
|
|
|
|
// Release the scene texture.
|
|
qglDeleteTextures( 1, &tr.sceneImage );
|
|
|
|
// Release the blur texture.
|
|
qglDeleteTextures( 1, &tr.blurImage );
|
|
}
|
|
#endif
|
|
|
|
R_ShutdownWorldEffects();
|
|
R_ShutdownFonts();
|
|
if ( tr.registered )
|
|
{
|
|
R_IssuePendingRenderCommands();
|
|
if ( destroyWindow )
|
|
{
|
|
R_DeleteTextures(); // only do this for vid_restart now, not during things like map load
|
|
|
|
if ( restarting )
|
|
{
|
|
SaveGhoul2InfoArray();
|
|
}
|
|
}
|
|
}
|
|
|
|
// shut down platform specific OpenGL stuff
|
|
if ( destroyWindow ) {
|
|
ri.WIN_Shutdown();
|
|
}
|
|
tr.registered = qfalse;
|
|
}
|
|
|
|
/*
|
|
=============
|
|
RE_EndRegistration
|
|
|
|
Touch all images to make sure they are resident
|
|
=============
|
|
*/
|
|
void RE_EndRegistration( void ) {
|
|
R_IssuePendingRenderCommands();
|
|
}
|
|
|
|
|
|
void RE_GetLightStyle(int style, color4ub_t color)
|
|
{
|
|
if (style >= MAX_LIGHT_STYLES)
|
|
{
|
|
Com_Error( ERR_FATAL, "RE_GetLightStyle: %d is out of range", (int)style );
|
|
return;
|
|
}
|
|
|
|
byteAlias_t *baDest = (byteAlias_t *)&color, *baSource = (byteAlias_t *)&styleColors[style];
|
|
baDest->i = baSource->i;
|
|
}
|
|
|
|
void RE_SetLightStyle(int style, int color)
|
|
{
|
|
if (style >= MAX_LIGHT_STYLES)
|
|
{
|
|
Com_Error( ERR_FATAL, "RE_SetLightStyle: %d is out of range", (int)style );
|
|
return;
|
|
}
|
|
|
|
byteAlias_t *ba = (byteAlias_t *)&styleColors[style];
|
|
if ( ba->i != color) {
|
|
ba->i = color;
|
|
styleUpdated[style] = true;
|
|
}
|
|
}
|
|
|
|
/*
|
|
=====================
|
|
tr_distortionX
|
|
|
|
DLL glue
|
|
=====================
|
|
*/
|
|
|
|
extern float tr_distortionAlpha;
|
|
extern float tr_distortionStretch;
|
|
extern qboolean tr_distortionPrePost;
|
|
extern qboolean tr_distortionNegate;
|
|
|
|
float *get_tr_distortionAlpha( void )
|
|
{
|
|
return &tr_distortionAlpha;
|
|
}
|
|
|
|
float *get_tr_distortionStretch( void )
|
|
{
|
|
return &tr_distortionStretch;
|
|
}
|
|
|
|
qboolean *get_tr_distortionPrePost( void )
|
|
{
|
|
return &tr_distortionPrePost;
|
|
}
|
|
|
|
qboolean *get_tr_distortionNegate( void )
|
|
{
|
|
return &tr_distortionNegate;
|
|
}
|
|
|
|
float g_oldRangedFog = 0.0f;
|
|
void RE_SetRangedFog( float dist )
|
|
{
|
|
if (tr.rangedFog <= 0.0f)
|
|
{
|
|
g_oldRangedFog = tr.rangedFog;
|
|
}
|
|
tr.rangedFog = dist;
|
|
if (tr.rangedFog == 0.0f && g_oldRangedFog)
|
|
{ //restore to previous state if applicable
|
|
tr.rangedFog = g_oldRangedFog;
|
|
}
|
|
}
|
|
|
|
//bool inServer = false;
|
|
void RE_SVModelInit( void )
|
|
{
|
|
tr.numModels = 0;
|
|
tr.numShaders = 0;
|
|
tr.numSkins = 0;
|
|
R_InitImages();
|
|
//inServer = true;
|
|
R_InitShaders();
|
|
//inServer = false;
|
|
R_ModelInit();
|
|
}
|
|
|
|
/*
|
|
@@@@@@@@@@@@@@@@@@@@@
|
|
GetRefAPI
|
|
|
|
@@@@@@@@@@@@@@@@@@@@@
|
|
*/
|
|
extern void R_LoadImage( const char *shortname, byte **pic, int *width, int *height );
|
|
extern void R_WorldEffectCommand(const char *command);
|
|
extern qboolean R_inPVS( vec3_t p1, vec3_t p2 );
|
|
extern void RE_GetModelBounds(refEntity_t *refEnt, vec3_t bounds1, vec3_t bounds2);
|
|
extern void G2API_AnimateG2Models(CGhoul2Info_v &ghoul2, int AcurrentTime,CRagDollUpdateParams *params);
|
|
extern qboolean G2API_GetRagBonePos(CGhoul2Info_v &ghoul2, const char *boneName, vec3_t pos, vec3_t entAngles, vec3_t entPos, vec3_t entScale);
|
|
extern qboolean G2API_RagEffectorKick(CGhoul2Info_v &ghoul2, const char *boneName, vec3_t velocity);
|
|
extern qboolean G2API_RagForceSolve(CGhoul2Info_v &ghoul2, qboolean force);
|
|
extern qboolean G2API_SetBoneIKState(CGhoul2Info_v &ghoul2, int time, const char *boneName, int ikState, sharedSetBoneIKStateParams_t *params);
|
|
extern qboolean G2API_IKMove(CGhoul2Info_v &ghoul2, int time, sharedIKMoveParams_t *params);
|
|
extern qboolean G2API_RagEffectorGoal(CGhoul2Info_v &ghoul2, const char *boneName, vec3_t pos);
|
|
extern qboolean G2API_RagPCJGradientSpeed(CGhoul2Info_v &ghoul2, const char *boneName, const float speed);
|
|
extern qboolean G2API_RagPCJConstraint(CGhoul2Info_v &ghoul2, const char *boneName, vec3_t min, vec3_t max);
|
|
extern void G2API_SetRagDoll(CGhoul2Info_v &ghoul2,CRagDollParams *parms);
|
|
#ifdef G2_PERFORMANCE_ANALYSIS
|
|
extern void G2Time_ResetTimers(void);
|
|
extern void G2Time_ReportTimers(void);
|
|
#endif
|
|
extern IGhoul2InfoArray &TheGhoul2InfoArray();
|
|
|
|
#ifdef JK2_MODE
|
|
unsigned int AnyLanguage_ReadCharFromString_JK2 ( char **text, qboolean *pbIsTrailingPunctuation ) {
|
|
return AnyLanguage_ReadCharFromString (text, pbIsTrailingPunctuation);
|
|
}
|
|
#endif
|
|
|
|
extern "C" Q_EXPORT refexport_t* QDECL GetRefAPI ( int apiVersion, refimport_t *refimp ) {
|
|
static refexport_t re;
|
|
|
|
ri = *refimp;
|
|
|
|
memset( &re, 0, sizeof( re ) );
|
|
|
|
if ( apiVersion != REF_API_VERSION ) {
|
|
ri.Printf(PRINT_ALL, "Mismatched REF_API_VERSION: expected %i, got %i\n",
|
|
REF_API_VERSION, apiVersion );
|
|
return NULL;
|
|
}
|
|
|
|
// the RE_ functions are Renderer Entry points
|
|
|
|
#define REX(x) re.x = RE_##x
|
|
|
|
REX(Shutdown);
|
|
|
|
REX(BeginRegistration);
|
|
REX(RegisterModel);
|
|
REX(RegisterSkin);
|
|
REX(GetAnimationCFG);
|
|
REX(RegisterShader);
|
|
REX(RegisterShaderNoMip);
|
|
re.LoadWorld = RE_LoadWorldMap;
|
|
re.R_LoadImage = R_LoadImage;
|
|
|
|
REX(RegisterMedia_LevelLoadBegin);
|
|
REX(RegisterMedia_LevelLoadEnd);
|
|
REX(RegisterMedia_GetLevel);
|
|
REX(RegisterImages_LevelLoadEnd);
|
|
REX(RegisterModels_LevelLoadEnd);
|
|
|
|
REX(SetWorldVisData);
|
|
|
|
REX(EndRegistration);
|
|
|
|
REX(ClearScene);
|
|
REX(AddRefEntityToScene);
|
|
REX(GetLighting);
|
|
REX(AddPolyToScene);
|
|
REX(AddLightToScene);
|
|
REX(RenderScene);
|
|
REX(GetLighting);
|
|
|
|
REX(SetColor);
|
|
re.DrawStretchPic = RE_StretchPic;
|
|
re.DrawRotatePic = RE_RotatePic;
|
|
re.DrawRotatePic2 = RE_RotatePic2;
|
|
REX(LAGoggles);
|
|
REX(Scissor);
|
|
|
|
re.DrawStretchRaw = RE_StretchRaw;
|
|
REX(UploadCinematic);
|
|
|
|
REX(BeginFrame);
|
|
REX(EndFrame);
|
|
REX(SubmitStereoFrame);
|
|
|
|
REX(ProcessDissolve);
|
|
REX(InitDissolve);
|
|
|
|
REX(GetScreenShot);
|
|
#ifdef JK2_MODE
|
|
REX(SaveJPGToBuffer);
|
|
re.LoadJPGFromBuffer = LoadJPGFromBuffer;
|
|
#endif
|
|
REX(TempRawImage_ReadFromFile);
|
|
REX(TempRawImage_CleanUp);
|
|
|
|
re.MarkFragments = R_MarkFragments;
|
|
re.LerpTag = R_LerpTag;
|
|
re.ModelBounds = R_ModelBounds;
|
|
REX(GetLightStyle);
|
|
REX(SetLightStyle);
|
|
REX(GetBModelVerts);
|
|
re.WorldEffectCommand = R_WorldEffectCommand;
|
|
REX(GetModelBounds);
|
|
|
|
REX(SVModelInit);
|
|
|
|
REX(RegisterFont);
|
|
REX(Font_HeightPixels);
|
|
REX(Font_StrLenPixels);
|
|
REX(Font_DrawString);
|
|
REX(Font_StrLenChars);
|
|
re.Language_IsAsian = Language_IsAsian;
|
|
re.Language_UsesSpaces = Language_UsesSpaces;
|
|
re.AnyLanguage_ReadCharFromString = AnyLanguage_ReadCharFromString;
|
|
#ifdef JK2_MODE
|
|
re.AnyLanguage_ReadCharFromString2 = AnyLanguage_ReadCharFromString_JK2;
|
|
#endif
|
|
|
|
re.R_InitWorldEffects = R_InitWorldEffects;
|
|
re.R_ClearStuffToStopGhoul2CrashingThings = R_ClearStuffToStopGhoul2CrashingThings;
|
|
re.R_inPVS = R_inPVS;
|
|
|
|
re.tr_distortionAlpha = get_tr_distortionAlpha;
|
|
re.tr_distortionStretch = get_tr_distortionStretch;
|
|
re.tr_distortionPrePost = get_tr_distortionPrePost;
|
|
re.tr_distortionNegate = get_tr_distortionNegate;
|
|
|
|
re.GetWindVector = R_GetWindVector;
|
|
re.GetWindGusting = R_GetWindGusting;
|
|
re.IsOutside = R_IsOutside;
|
|
re.IsOutsideCausingPain = R_IsOutsideCausingPain;
|
|
re.GetChanceOfSaberFizz = R_GetChanceOfSaberFizz;
|
|
re.IsShaking = R_IsShaking;
|
|
re.AddWeatherZone = R_AddWeatherZone;
|
|
re.SetTempGlobalFogColor = R_SetTempGlobalFogColor;
|
|
|
|
REX(SetRangedFog);
|
|
|
|
re.TheGhoul2InfoArray = TheGhoul2InfoArray;
|
|
|
|
#define G2EX(x) re.G2API_##x = G2API_##x
|
|
|
|
G2EX(AddBolt);
|
|
G2EX(AddBoltSurfNum);
|
|
G2EX(AddSurface);
|
|
G2EX(AnimateG2Models);
|
|
G2EX(AttachEnt);
|
|
G2EX(AttachG2Model);
|
|
G2EX(CollisionDetect);
|
|
G2EX(CleanGhoul2Models);
|
|
G2EX(CopyGhoul2Instance);
|
|
G2EX(DetachEnt);
|
|
G2EX(DetachG2Model);
|
|
G2EX(GetAnimFileName);
|
|
G2EX(GetAnimFileNameIndex);
|
|
G2EX(GetAnimFileInternalNameIndex);
|
|
G2EX(GetAnimIndex);
|
|
G2EX(GetAnimRange);
|
|
G2EX(GetAnimRangeIndex);
|
|
G2EX(GetBoneAnim);
|
|
G2EX(GetBoneAnimIndex);
|
|
G2EX(GetBoneIndex);
|
|
G2EX(GetBoltMatrix);
|
|
G2EX(GetGhoul2ModelFlags);
|
|
G2EX(GetGLAName);
|
|
G2EX(GetParentSurface);
|
|
G2EX(GetRagBonePos);
|
|
G2EX(GetSurfaceIndex);
|
|
G2EX(GetSurfaceName);
|
|
G2EX(GetSurfaceRenderStatus);
|
|
G2EX(GetTime);
|
|
G2EX(GiveMeVectorFromMatrix);
|
|
G2EX(HaveWeGhoul2Models);
|
|
G2EX(IKMove);
|
|
G2EX(InitGhoul2Model);
|
|
G2EX(IsPaused);
|
|
G2EX(ListBones);
|
|
G2EX(ListSurfaces);
|
|
G2EX(LoadGhoul2Models);
|
|
G2EX(LoadSaveCodeDestructGhoul2Info);
|
|
G2EX(PauseBoneAnim);
|
|
G2EX(PauseBoneAnimIndex);
|
|
G2EX(PrecacheGhoul2Model);
|
|
G2EX(RagEffectorGoal);
|
|
G2EX(RagEffectorKick);
|
|
G2EX(RagForceSolve);
|
|
G2EX(RagPCJConstraint);
|
|
G2EX(RagPCJGradientSpeed);
|
|
G2EX(RemoveBolt);
|
|
G2EX(RemoveBone);
|
|
G2EX(RemoveGhoul2Model);
|
|
G2EX(RemoveSurface);
|
|
G2EX(SaveGhoul2Models);
|
|
G2EX(SetAnimIndex);
|
|
G2EX(SetBoneAnim);
|
|
G2EX(SetBoneAnimIndex);
|
|
G2EX(SetBoneAngles);
|
|
G2EX(SetBoneAnglesIndex);
|
|
G2EX(SetBoneAnglesMatrix);
|
|
G2EX(SetBoneIKState);
|
|
G2EX(SetGhoul2ModelFlags);
|
|
G2EX(SetGhoul2ModelIndexes);
|
|
G2EX(SetLodBias);
|
|
//G2EX(SetModelIndexes);
|
|
G2EX(SetNewOrigin);
|
|
G2EX(SetRagDoll);
|
|
G2EX(SetRootSurface);
|
|
G2EX(SetShader);
|
|
G2EX(SetSkin);
|
|
G2EX(SetSurfaceOnOff);
|
|
G2EX(SetTime);
|
|
G2EX(StopBoneAnim);
|
|
G2EX(StopBoneAnimIndex);
|
|
G2EX(StopBoneAngles);
|
|
G2EX(StopBoneAnglesIndex);
|
|
#ifdef _G2_GORE
|
|
G2EX(AddSkinGore);
|
|
G2EX(ClearSkinGore);
|
|
#endif
|
|
|
|
#ifdef G2_PERFORMANCE_ANALYSIS
|
|
re.G2Time_ReportTimers = G2Time_ReportTimers;
|
|
re.G2Time_ResetTimers = G2Time_ResetTimers;
|
|
#endif
|
|
|
|
//Swap_Init();
|
|
|
|
return &re;
|
|
}
|