mirror of
https://github.com/ReactionQuake3/reaction.git
synced 2024-11-21 20:01:43 +00:00
Updating to ioq3 git dated 21 Jan 2014
This commit is contained in:
parent
45e82a1618
commit
4b2fe84e40
81 changed files with 3737 additions and 4182 deletions
4
Makefile
4
Makefile
|
@ -2677,6 +2677,10 @@ ifneq ($(BUILD_CLIENT),0)
|
|||
ifneq ($(BUILD_RENDERER_OPENGL2),0)
|
||||
$(INSTALL) $(STRIP_FLAG) -m 0755 $(BR)/renderer_opengl2_$(SHLIBNAME) $(COPYBINDIR)/renderer_opengl2_$(SHLIBNAME)
|
||||
endif
|
||||
else
|
||||
ifneq ($(BUILD_RENDERER_OPENGL2),0)
|
||||
$(INSTALL) $(STRIP_FLAG) -m 0755 $(BR)/$(CLIENTBIN)_opengl2$(FULLBINEXT) $(COPYBINDIR)/$(CLIENTBIN)_opengl2$(FULLBINEXT)
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
|
||||
|
|
|
@ -39,7 +39,7 @@ renamed to id-readme.txt so as to prevent confusion. Please refer to the
|
|||
web-site for updated status.
|
||||
|
||||
|
||||
--------------------------------------------- Compilation and installation -----
|
||||
# Compilation and installation
|
||||
|
||||
For *nix
|
||||
1. Change to the directory containing this readme.
|
||||
|
@ -73,6 +73,7 @@ x86_64.
|
|||
The following variables may be set, either on the command line or in
|
||||
Makefile.local:
|
||||
|
||||
```
|
||||
CFLAGS - use this for custom CFLAGS
|
||||
V - set to show cc command line when building
|
||||
DEFAULT_BASEDIR - extra path to search for baseq3 and such
|
||||
|
@ -108,13 +109,16 @@ Makefile.local:
|
|||
DEBUG_CFLAGS - C compiler flags to use for building debug version
|
||||
COPYDIR - the target installation directory
|
||||
TEMPDIR - specify user defined directory for temp files
|
||||
```
|
||||
|
||||
The defaults for these variables differ depending on the target platform.
|
||||
|
||||
|
||||
------------------------------------------------------------------ Console -----
|
||||
# Console
|
||||
|
||||
New cvars
|
||||
## New cvars
|
||||
|
||||
```
|
||||
cl_autoRecordDemo - record a new demo on each map change
|
||||
cl_aviFrameRate - the framerate to use when capturing video
|
||||
cl_aviMotionJpeg - use the mjpeg codec when capturing video
|
||||
|
@ -271,8 +275,11 @@ New cvars
|
|||
cl_aviMotionJpeg is enabled
|
||||
r_mode -2 - This new video mode automatically uses the
|
||||
desktop resolution.
|
||||
```
|
||||
|
||||
New commands
|
||||
## New commands
|
||||
|
||||
```
|
||||
video [filename] - start video capture (use with demo command)
|
||||
stopvideo - stop video capture
|
||||
stopmusic - stop background music
|
||||
|
@ -307,132 +314,150 @@ New commands
|
|||
all bots even if someone is named "allbots")
|
||||
|
||||
tell <client num> <msg> - send message to a single client (new to server)
|
||||
```
|
||||
|
||||
|
||||
--------------------------------------------------------- README for Users -----
|
||||
# README for Users
|
||||
|
||||
Using shared libraries instead of qvm
|
||||
To force Q3 to use shared libraries instead of qvms run it with the following
|
||||
parameters: +set sv_pure 0 +set vm_cgame 0 +set vm_game 0 +set vm_ui 0
|
||||
## Using shared libraries instead of qvm
|
||||
|
||||
Using Demo Data Files
|
||||
Copy demoq3/pak0.pk3 from the demo installer to your baseq3 directory. The
|
||||
qvm files in this pak0.pk3 will not work, so you have to use the native
|
||||
shared libraries or qvms from this project. To use the new qvms, they must be
|
||||
put into a pk3 file. A pk3 file is just a zip file, so any compression tool
|
||||
that can create such files will work. The shared libraries should already be
|
||||
in the correct place. Use the instructions above to use them.
|
||||
To force Q3 to use shared libraries instead of qvms run it with the following
|
||||
parameters: `+set sv_pure 0 +set vm_cgame 0 +set vm_game 0 +set vm_ui 0`
|
||||
|
||||
Please bear in mind that you will not be able to play online using the demo
|
||||
data, nor is it something that we like to spend much time maintaining or
|
||||
supporting.
|
||||
## Using Demo Data Files
|
||||
|
||||
Help! Ioquake3 won't give me an fps of X anymore when setting com_maxfps!
|
||||
Ioquake3 now uses the select() system call to wait for the rendering of the
|
||||
next frame when com_maxfps was hit. This will improve your CPU load
|
||||
considerably in these cases. However, not all systems may support a
|
||||
granularity for its timing functions that is required to perform this waiting
|
||||
correctly. For instance, ioquake3 tells select() to wait 2 milliseconds, but
|
||||
really it can only wait for a multiple of 5ms, i.e. 5, 10, 15, 20... ms.
|
||||
In this case you can always revert back to the old behaviour by setting the
|
||||
cvar com_busyWait to 1.
|
||||
Copy demoq3/pak0.pk3 from the demo installer to your baseq3 directory. The
|
||||
qvm files in this pak0.pk3 will not work, so you have to use the native
|
||||
shared libraries or qvms from this project. To use the new qvms, they must be
|
||||
put into a pk3 file. A pk3 file is just a zip file, so any compression tool
|
||||
that can create such files will work. The shared libraries should already be
|
||||
in the correct place. Use the instructions above to use them.
|
||||
|
||||
Using HTTP/FTP Download Support (Server)
|
||||
You can enable redirected downloads on your server even if it's not
|
||||
an ioquake3 server. You simply need to use the 'sets' command to put
|
||||
the sv_dlURL cvar into your SERVERINFO string and ensure sv_allowDownloads
|
||||
is set to 1
|
||||
Please bear in mind that you will not be able to play online using the demo
|
||||
data, nor is it something that we like to spend much time maintaining or
|
||||
supporting.
|
||||
|
||||
sv_dlURL is the base of the URL that contains your custom .pk3 files
|
||||
the client will append both fs_game and the filename to the end of
|
||||
this value. For example, if you have sv_dlURL set to
|
||||
"http://ioquake3.org", fs_game is "baseq3", and the client is
|
||||
missing "test.pk3", it will attempt to download from the URL
|
||||
"http://ioquake3.org/baseq3/test.pk3"
|
||||
## Help! Ioquake3 won't give me an fps of X anymore when setting com_maxfps!
|
||||
|
||||
sv_allowDownload's value is now a bitmask made up of the following
|
||||
flags:
|
||||
1 - ENABLE
|
||||
4 - do not use UDP downloads
|
||||
8 - do not ask the client to disconnect when using HTTP/FTP
|
||||
Ioquake3 now uses the select() system call to wait for the rendering of the
|
||||
next frame when com_maxfps was hit. This will improve your CPU load
|
||||
considerably in these cases. However, not all systems may support a
|
||||
granularity for its timing functions that is required to perform this waiting
|
||||
correctly. For instance, ioquake3 tells select() to wait 2 milliseconds, but
|
||||
really it can only wait for a multiple of 5ms, i.e. 5, 10, 15, 20... ms.
|
||||
In this case you can always revert back to the old behaviour by setting the
|
||||
cvar com_busyWait to 1.
|
||||
|
||||
Server operators who are concerned about potential "leeching" from their
|
||||
HTTP servers from other ioquake3 servers can make use of the HTTP_REFERER
|
||||
that ioquake3 sets which is "ioQ3://{SERVER_IP}:{SERVER_PORT}". For,
|
||||
example, Apache's mod_rewrite can restrict access based on HTTP_REFERER.
|
||||
## Using HTTP/FTP Download Support (Server)
|
||||
|
||||
On a sidenote, downloading via UDP has been improved and yields higher data
|
||||
rates now. You can configure the maximum bandwidth for UDP downloads via the
|
||||
cvar sv_dlRate. Due to system-specific limits the download rate is capped
|
||||
at about 1 Mbyte/s per client, so curl downloading may still be faster.
|
||||
You can enable redirected downloads on your server even if it's not
|
||||
an ioquake3 server. You simply need to use the 'sets' command to put
|
||||
the sv_dlURL cvar into your SERVERINFO string and ensure sv_allowDownloads
|
||||
is set to 1
|
||||
|
||||
Using HTTP/FTP Download Support (Client)
|
||||
Simply setting cl_allowDownload to 1 will enable HTTP/FTP downloads
|
||||
assuming ioquake3 was compiled with USE_CURL=1 (the default).
|
||||
like sv_allowDownload, cl_allowDownload also uses a bitmask value
|
||||
supporting the following flags:
|
||||
1 - ENABLE
|
||||
2 - do not use HTTP/FTP downloads
|
||||
4 - do not use UDP downloads
|
||||
sv_dlURL is the base of the URL that contains your custom .pk3 files
|
||||
the client will append both fs_game and the filename to the end of
|
||||
this value. For example, if you have sv_dlURL set to
|
||||
`"http://ioquake3.org"`, fs_game is `"baseq3"`, and the client is
|
||||
missing `"test.pk3"`, it will attempt to download from the URL
|
||||
`"http://ioquake3.org/baseq3/test.pk3"`
|
||||
|
||||
When ioquake3 is built with USE_CURL_DLOPEN=1 (default on some platforms),
|
||||
it will use the value of the cvar cl_cURLLib as the filename of the cURL
|
||||
library to dynamically load.
|
||||
sv_allowDownload's value is now a bitmask made up of the following
|
||||
flags:
|
||||
|
||||
Multiuser Support on Windows systems
|
||||
On Windows, all user specific files such as autogenerated configuration,
|
||||
demos, videos, screenshots, and autodownloaded pk3s are now saved in a
|
||||
directory specific to the user who is running ioquake3.
|
||||
* 1 - ENABLE
|
||||
* 4 - do not use UDP downloads
|
||||
* 8 - do not ask the client to disconnect when using HTTP/FTP
|
||||
|
||||
On NT-based such as Windows XP, this is usually a directory named:
|
||||
"C:\Documents and Settings\%USERNAME%\Application Data\Quake3\"
|
||||
Server operators who are concerned about potential "leeching" from their
|
||||
HTTP servers from other ioquake3 servers can make use of the HTTP_REFERER
|
||||
that ioquake3 sets which is `"ioQ3://{SERVER_IP}:{SERVER_PORT}"`. For,
|
||||
example, Apache's mod_rewrite can restrict access based on HTTP_REFERER.
|
||||
|
||||
Windows 95, Windows 98, and Windows ME will use a directory like:
|
||||
"C:\Windows\Application Data\Quake3"
|
||||
in single-user mode, or:
|
||||
"C:\Windows\Profiles\%USERNAME%\Application Data\Quake3"
|
||||
if multiple logins have been enabled.
|
||||
On a sidenote, downloading via UDP has been improved and yields higher data
|
||||
rates now. You can configure the maximum bandwidth for UDP downloads via the
|
||||
cvar sv_dlRate. Due to system-specific limits the download rate is capped
|
||||
at about 1 Mbyte/s per client, so curl downloading may still be faster.
|
||||
|
||||
In order to access this directory more easily, the installer may create a
|
||||
Shortcut which has its target set to:
|
||||
"%APPDATA%\Quake3\"
|
||||
This Shortcut would work for all users on the system regardless of the
|
||||
locale settings. Unfortunately, this environment variable is only
|
||||
present on Windows NT based systems.
|
||||
## Using HTTP/FTP Download Support (Client)
|
||||
|
||||
Simply setting cl_allowDownload to 1 will enable HTTP/FTP downloads
|
||||
assuming ioquake3 was compiled with USE_CURL=1 (the default).
|
||||
like sv_allowDownload, cl_allowDownload also uses a bitmask value
|
||||
supporting the following flags:
|
||||
|
||||
* 1 - ENABLE
|
||||
* 2 - do not use HTTP/FTP downloads
|
||||
* 4 - do not use UDP downloads
|
||||
|
||||
When ioquake3 is built with USE_CURL_DLOPEN=1 (default on some platforms),
|
||||
it will use the value of the cvar cl_cURLLib as the filename of the cURL
|
||||
library to dynamically load.
|
||||
|
||||
## Multiuser Support on Windows systems
|
||||
On Windows, all user specific files such as autogenerated configuration,
|
||||
demos, videos, screenshots, and autodownloaded pk3s are now saved in a
|
||||
directory specific to the user who is running ioquake3.
|
||||
|
||||
On NT-based such as Windows XP, this is usually a directory named:
|
||||
|
||||
C:\Documents and Settings\%USERNAME%\Application Data\Quake3\
|
||||
|
||||
Windows 95, Windows 98, and Windows ME will use a directory like:
|
||||
|
||||
C:\Windows\Application Data\Quake3
|
||||
|
||||
in single-user mode, or:
|
||||
|
||||
C:\Windows\Profiles\%USERNAME%\Application Data\Quake3
|
||||
|
||||
if multiple logins have been enabled.
|
||||
|
||||
In order to access this directory more easily, the installer may create a
|
||||
Shortcut which has its target set to:
|
||||
|
||||
%APPDATA%\Quake3\
|
||||
|
||||
This Shortcut would work for all users on the system regardless of the
|
||||
locale settings. Unfortunately, this environment variable is only
|
||||
present on Windows NT based systems.
|
||||
|
||||
You can revert to the old single-user behaviour by setting the fs_homepath
|
||||
cvar to the directory where ioquake3 is installed. For example:
|
||||
|
||||
You can revert to the old single-user behaviour by setting the fs_homepath
|
||||
cvar to the directory where ioquake3 is installed. For example:
|
||||
ioquake3.exe +set fs_homepath "c:\ioquake3"
|
||||
Note that this cvar MUST be set as a command line parameter.
|
||||
|
||||
SDL Keyboard Differences
|
||||
ioquake3 clients have different keyboard behaviour compared to the original
|
||||
Quake3 clients.
|
||||
Note that this cvar MUST be set as a command line parameter.
|
||||
|
||||
* "Caps Lock" and "Num Lock" can not be used as normal binds since they
|
||||
## SDL Keyboard Differences
|
||||
|
||||
ioquake3 clients have different keyboard behaviour compared to the original
|
||||
Quake3 clients.
|
||||
|
||||
* "Caps Lock" and "Num Lock" can not be used as normal binds since they
|
||||
do not send a KEYUP event until the key is pressed again.
|
||||
|
||||
* SDL > 1.2.9 does not support disabling dead key recognition. In order to
|
||||
* SDL > 1.2.9 does not support disabling dead key recognition. In order to
|
||||
send dead key characters (e.g. ~, ', `, and ^), you must key a Space (or
|
||||
sometimes the same character again) after the character to send it on
|
||||
many international keyboard layouts.
|
||||
|
||||
* The SDL client supports many more keys than the original Quake3 client.
|
||||
* The SDL client supports many more keys than the original Quake3 client.
|
||||
For example the keys: "Windows", "SysReq", "ScrollLock", and "Break".
|
||||
For non-US keyboards, all of the so called "World" keys are now supported
|
||||
as well as F13, F14, F15, and the country-specific mode/meta keys.
|
||||
|
||||
On many international layouts the default console toggle keys are also dead
|
||||
keys, meaning that dropping the console potentially results in
|
||||
unintentionally initiating the keying of a dead key. Furthermore SDL 1.2's
|
||||
dead key support is broken by design and Q3 doesn't support non-ASCII text
|
||||
entry, so the chances are you won't get the correct character anyway.
|
||||
On many international layouts the default console toggle keys are also dead
|
||||
keys, meaning that dropping the console potentially results in
|
||||
unintentionally initiating the keying of a dead key. Furthermore SDL 1.2's
|
||||
dead key support is broken by design and Q3 doesn't support non-ASCII text
|
||||
entry, so the chances are you won't get the correct character anyway.
|
||||
|
||||
If you use such a keyboard layout, you can set the cvar cl_consoleKeys. This
|
||||
is a space delimited list of key names that will toggle the console. The key
|
||||
names are the usual Q3 names e.g. "~", "`", "c", "BACKSPACE", "PAUSE",
|
||||
"WINDOWS" etc. It's also possible to use ASCII characters, by hexadecimal
|
||||
number. Some example values for cl_consoleKeys:
|
||||
If you use such a keyboard layout, you can set the cvar cl_consoleKeys. This
|
||||
is a space delimited list of key names that will toggle the console. The key
|
||||
names are the usual Q3 names e.g. "~", "`", "c", "BACKSPACE", "PAUSE",
|
||||
"WINDOWS" etc. It's also possible to use ASCII characters, by hexadecimal
|
||||
number. Some example values for cl_consoleKeys:
|
||||
|
||||
"~ ` 0x7e 0x60" Toggle on ~ or ` (the default)
|
||||
"WINDOWS" Toggle on the Windows key
|
||||
|
@ -440,75 +465,79 @@ SDL Keyboard Differences
|
|||
"0x43" Toggle on the C character (Shift-c)
|
||||
"PAUSE F1 PGUP" Toggle on the Pause, F1 or Page Up keys
|
||||
|
||||
Note that when you elect a set of console keys or characters, they cannot
|
||||
then be used for binding, nor will they generate characters when entering
|
||||
text. Also, in addition to the nominated console keys, Shift-ESC is hard
|
||||
coded to always toggle the console.
|
||||
Note that when you elect a set of console keys or characters, they cannot
|
||||
then be used for binding, nor will they generate characters when entering
|
||||
text. Also, in addition to the nominated console keys, Shift-ESC is hard
|
||||
coded to always toggle the console.
|
||||
|
||||
QuakeLive mouse acceleration (patch and this text written by TTimo from id)
|
||||
I've been using an experimental mouse acceleration code for a while, and
|
||||
decided to make it available to everyone. Don't be too worried if you don't
|
||||
understand the explanations below, this is mostly intended for advanced
|
||||
players:
|
||||
To enable it, set cl_mouseAccelStyle 1 (0 is the default/legacy behavior)
|
||||
## QuakeLive mouse acceleration
|
||||
(patch and this text written by TTimo from id)
|
||||
|
||||
New style is controlled with 3 cvars:
|
||||
I've been using an experimental mouse acceleration code for a while, and
|
||||
decided to make it available to everyone. Don't be too worried if you don't
|
||||
understand the explanations below, this is mostly intended for advanced
|
||||
players:
|
||||
To enable it, set cl_mouseAccelStyle 1 (0 is the default/legacy behavior)
|
||||
|
||||
sensitivity
|
||||
cl_mouseAccel
|
||||
cl_mouseAccelOffset
|
||||
New style is controlled with 3 cvars:
|
||||
|
||||
The old code (cl_mouseAccelStyle 0) can be difficult to calibrate because if
|
||||
you have a base sensitivity setup, as soon as you set a non zero acceleration
|
||||
your base sensitivity at low speeds will change as well. The other problem
|
||||
with style 0 is that you are stuck on a square (power of two) acceleration
|
||||
curve.
|
||||
sensitivity
|
||||
cl_mouseAccel
|
||||
cl_mouseAccelOffset
|
||||
|
||||
The new code tries to solve both problems:
|
||||
The old code (cl_mouseAccelStyle 0) can be difficult to calibrate because if
|
||||
you have a base sensitivity setup, as soon as you set a non zero acceleration
|
||||
your base sensitivity at low speeds will change as well. The other problem
|
||||
with style 0 is that you are stuck on a square (power of two) acceleration
|
||||
curve.
|
||||
|
||||
Once you setup your sensitivity to feel comfortable and accurate enough for
|
||||
low mouse deltas with no acceleration (cl_mouseAccel 0), you can start
|
||||
increasing cl_mouseAccel and tweaking cl_mouseAccelOffset to get the
|
||||
amplification you want for high deltas with little effect on low mouse deltas.
|
||||
The new code tries to solve both problems:
|
||||
|
||||
cl_mouseAccel is a power value. Should be >= 1, 2 will be the same power curve
|
||||
as style 0. The higher the value, the faster the amplification grows with the
|
||||
mouse delta.
|
||||
Once you setup your sensitivity to feel comfortable and accurate enough for
|
||||
low mouse deltas with no acceleration (cl_mouseAccel 0), you can start
|
||||
increasing cl_mouseAccel and tweaking cl_mouseAccelOffset to get the
|
||||
amplification you want for high deltas with little effect on low mouse deltas.
|
||||
|
||||
cl_mouseAccelOffset sets how much base mouse delta will be doubled by
|
||||
acceleration. The closer to zero you bring it, the more acceleration will
|
||||
happen at low speeds. This is also very useful if you are changing to a new
|
||||
mouse with higher dpi, if you go from 500 to 1000 dpi, you can divide your
|
||||
cl_mouseAccelOffset by two to keep the same overall 'feel' (you will likely
|
||||
gain in precision when you do that, but that is not related to mouse
|
||||
acceleration).
|
||||
cl_mouseAccel is a power value. Should be >= 1, 2 will be the same power curve
|
||||
as style 0. The higher the value, the faster the amplification grows with the
|
||||
mouse delta.
|
||||
|
||||
Mouse acceleration is tricky to configure, and when you do you'll have to
|
||||
re-learn your aiming. But you will find that it's very much forth it in the
|
||||
long run.
|
||||
cl_mouseAccelOffset sets how much base mouse delta will be doubled by
|
||||
acceleration. The closer to zero you bring it, the more acceleration will
|
||||
happen at low speeds. This is also very useful if you are changing to a new
|
||||
mouse with higher dpi, if you go from 500 to 1000 dpi, you can divide your
|
||||
cl_mouseAccelOffset by two to keep the same overall 'feel' (you will likely
|
||||
gain in precision when you do that, but that is not related to mouse
|
||||
acceleration).
|
||||
|
||||
If you try the new acceleration code and start using it, I'd be very
|
||||
interested by your feedback.
|
||||
Mouse acceleration is tricky to configure, and when you do you'll have to
|
||||
re-learn your aiming. But you will find that it's very much forth it in the
|
||||
long run.
|
||||
|
||||
If you try the new acceleration code and start using it, I'd be very
|
||||
interested by your feedback.
|
||||
|
||||
|
||||
---------------------------------------------------- README for Developers -----
|
||||
# README for Developers
|
||||
|
||||
pk3dir
|
||||
ioquake3 has a useful new feature for mappers. Paths in a game directory with
|
||||
the extension ".pk3dir" are treated like pk3 files. This means you can keep
|
||||
all files specific to your map in one directory tree and easily zip this
|
||||
folder for distribution.
|
||||
## pk3dir
|
||||
|
||||
64bit mods
|
||||
If you wish to compile external mods as shared libraries on a 64bit platform,
|
||||
and the mod source is derived from the id Q3 SDK, you will need to modify the
|
||||
interface code a little. Open the files ending in _syscalls.c and change
|
||||
every instance of int to intptr_t in the declaration of the syscall function
|
||||
pointer and the dllEntry function. Also find the vmMain function for each
|
||||
module (usually in cg_main.c g_main.c etc.) and similarly replace the return
|
||||
value in the prototype with intptr_t (arg0, arg1, ...stay int).
|
||||
ioquake3 has a useful new feature for mappers. Paths in a game directory with
|
||||
the extension ".pk3dir" are treated like pk3 files. This means you can keep
|
||||
all files specific to your map in one directory tree and easily zip this
|
||||
folder for distribution.
|
||||
|
||||
Add the following code snippet to q_shared.h:
|
||||
## 64bit mods
|
||||
|
||||
If you wish to compile external mods as shared libraries on a 64bit platform,
|
||||
and the mod source is derived from the id Q3 SDK, you will need to modify the
|
||||
interface code a little. Open the files ending in _syscalls.c and change
|
||||
every instance of int to intptr_t in the declaration of the syscall function
|
||||
pointer and the dllEntry function. Also find the vmMain function for each
|
||||
module (usually in cg_main.c g_main.c etc.) and similarly replace the return
|
||||
value in the prototype with intptr_t (arg0, arg1, ...stay int).
|
||||
|
||||
Add the following code snippet to q_shared.h:
|
||||
|
||||
#ifdef Q3_VM
|
||||
typedef int intptr_t;
|
||||
|
@ -516,165 +545,173 @@ pk3dir
|
|||
#include <stdint.h>
|
||||
#endif
|
||||
|
||||
Note if you simply wish to run mods on a 64bit platform you do not need to
|
||||
recompile anything since by default Q3 uses a virtual machine system.
|
||||
Note if you simply wish to run mods on a 64bit platform you do not need to
|
||||
recompile anything since by default Q3 uses a virtual machine system.
|
||||
|
||||
Creating mods compatible with Q3 1.32b
|
||||
If you're using this package to create mods for the last official release of
|
||||
Q3, it is necessary to pass the commandline option '-vq3' to your invocation
|
||||
of q3asm. This is because by default q3asm outputs an updated qvm format that
|
||||
is necessary to fix a bug involving the optimizing pass of the x86 vm JIT
|
||||
compiler.
|
||||
## Creating mods compatible with Q3 1.32b
|
||||
|
||||
Creating standalone games
|
||||
Have you finished the daunting task of removing all dependencies on the Q3
|
||||
game data? You probably now want to give your users the opportunity to play
|
||||
the game without owning a copy of Q3, which consequently means removing cd-key
|
||||
and authentication server checks. In addition to being a straightforward Q3
|
||||
client, ioquake3 also purports to be a reliable and stable code base on which
|
||||
to base your game project.
|
||||
If you're using this package to create mods for the last official release of
|
||||
Q3, it is necessary to pass the commandline option '-vq3' to your invocation
|
||||
of q3asm. This is because by default q3asm outputs an updated qvm format that
|
||||
is necessary to fix a bug involving the optimizing pass of the x86 vm JIT
|
||||
compiler.
|
||||
|
||||
However, before you start compiling your own version of ioquake3, you have to
|
||||
ask yourself: Have we changed or will we need to change anything of importance
|
||||
in the engine?
|
||||
## Creating standalone games
|
||||
|
||||
If your answer to this question is "no", it probably makes no sense to build
|
||||
your own binaries. Instead, you can just use the pre-built binaries on the
|
||||
website. Just make sure the game is called with:
|
||||
Have you finished the daunting task of removing all dependencies on the Q3
|
||||
game data? You probably now want to give your users the opportunity to play
|
||||
the game without owning a copy of Q3, which consequently means removing cd-key
|
||||
and authentication server checks. In addition to being a straightforward Q3
|
||||
client, ioquake3 also purports to be a reliable and stable code base on which
|
||||
to base your game project.
|
||||
|
||||
However, before you start compiling your own version of ioquake3, you have to
|
||||
ask yourself: Have we changed or will we need to change anything of importance
|
||||
in the engine?
|
||||
|
||||
If your answer to this question is "no", it probably makes no sense to build
|
||||
your own binaries. Instead, you can just use the pre-built binaries on the
|
||||
website. Just make sure the game is called with:
|
||||
|
||||
+set com_basegame <yournewbase>
|
||||
|
||||
in any links/scripts you install for your users to start the game. The
|
||||
binary must not detect any original quake3 game pak files. If this
|
||||
condition is met, the game will set com_standalone to 1 and is then running
|
||||
in stand alone mode.
|
||||
|
||||
If you want the engine to use a different directory in your homepath than
|
||||
e.g. "Quake3" on Windows or ".q3a" on Linux, then set a new name at startup
|
||||
by adding
|
||||
in any links/scripts you install for your users to start the game. The
|
||||
binary must not detect any original quake3 game pak files. If this
|
||||
condition is met, the game will set com_standalone to 1 and is then running
|
||||
in stand alone mode.
|
||||
|
||||
If you want the engine to use a different directory in your homepath than
|
||||
e.g. "Quake3" on Windows or ".q3a" on Linux, then set a new name at startup
|
||||
by adding
|
||||
|
||||
+set com_homepath <homedirname>
|
||||
|
||||
to the command line. You can also control which game name to use when talking
|
||||
to the master server:
|
||||
|
||||
|
||||
to the command line. You can also control which game name to use when talking
|
||||
to the master server:
|
||||
|
||||
+set com_gamename <gamename>
|
||||
|
||||
So clients requesting a server list will only receive servers that have a
|
||||
matching game name.
|
||||
|
||||
Example line:
|
||||
|
||||
|
||||
So clients requesting a server list will only receive servers that have a
|
||||
matching game name.
|
||||
|
||||
Example line:
|
||||
|
||||
+set com_basegame basefoo +set com_homepath .foo
|
||||
+set com_gamename foo
|
||||
|
||||
If you really changed parts that would make vanilla ioquake3 incompatible with
|
||||
your mod, we have included another way to conveniently build a stand-alone
|
||||
binary. Just run make with the option BUILD_STANDALONE=1. Don't forget to edit
|
||||
the PRODUCT_NAME and subsequent #defines in qcommon/q_shared.h with
|
||||
information appropriate for your project.
|
||||
|
||||
If you really changed parts that would make vanilla ioquake3 incompatible with
|
||||
your mod, we have included another way to conveniently build a stand-alone
|
||||
binary. Just run make with the option BUILD_STANDALONE=1. Don't forget to edit
|
||||
the PRODUCT_NAME and subsequent #defines in qcommon/q_shared.h with
|
||||
information appropriate for your project.
|
||||
## Standalone game licensing
|
||||
|
||||
While a lot of work has been put into ioquake3 that you can benefit from free
|
||||
of charge, it does not mean that you have no obligations to fulfill. Please be
|
||||
aware that as soon as you start distributing your game with an engine based on
|
||||
our sources we expect you to fully comply with the requirements as stated in
|
||||
the GPL. That includes making sources and modifications you made to the
|
||||
ioquake3 engine as well as the game-code used to compile the .qvm files for
|
||||
the game logic freely available to everyone. Furthermore, note that the "QIIIA
|
||||
Game Source License" prohibits distribution of mods that are intended to
|
||||
operate on a version of Q3 not sanctioned by id software:
|
||||
While a lot of work has been put into ioquake3 that you can benefit from free
|
||||
of charge, it does not mean that you have no obligations to fulfill. Please be
|
||||
aware that as soon as you start distributing your game with an engine based on
|
||||
our sources we expect you to fully comply with the requirements as stated in
|
||||
the GPL. That includes making sources and modifications you made to the
|
||||
ioquake3 engine as well as the game-code used to compile the .qvm files for
|
||||
the game logic freely available to everyone. Furthermore, note that the "QIIIA
|
||||
Game Source License" prohibits distribution of mods that are intended to
|
||||
operate on a version of Q3 not sanctioned by id software:
|
||||
|
||||
"with this Agreement, ID grants to you the non-exclusive and limited right
|
||||
to distribute copies of the Software ... for operation only with the full
|
||||
version of the software game QUAKE III ARENA"
|
||||
|
||||
This means that if you're creating a standalone game, you cannot use said
|
||||
license on any portion of the product. As the only other license this code has
|
||||
been released under is the GPL, this is the only option.
|
||||
This means that if you're creating a standalone game, you cannot use said
|
||||
license on any portion of the product. As the only other license this code has
|
||||
been released under is the GPL, this is the only option.
|
||||
|
||||
This does NOT mean that you cannot market this game commercially. The GPL does
|
||||
not prohibit commercial exploitation and all assets (e.g. textures, sounds,
|
||||
maps) created by yourself are your property and can be sold like every other
|
||||
game you find in stores.
|
||||
This does NOT mean that you cannot market this game commercially. The GPL does
|
||||
not prohibit commercial exploitation and all assets (e.g. textures, sounds,
|
||||
maps) created by yourself are your property and can be sold like every other
|
||||
game you find in stores.
|
||||
|
||||
Network protocols
|
||||
There are now two cvars that give you some degree of freedom over the reported
|
||||
protocol versions between clients and servers: "com_protocol" and
|
||||
"com_legacyprotocol".
|
||||
The reason for this is that some standalone games increased the protocol
|
||||
number even though nothing really changed in their protocol and the ioquake3
|
||||
engine is still fully compatible.
|
||||
## Network protocols
|
||||
|
||||
In order to harden the network protocol against UDP spoofing attacks a new
|
||||
network protocol was introduced that defends against such attacks.
|
||||
Unfortunately, this protocol will be incompatible to the original quake3 1.32c
|
||||
which is the latest official release from id.
|
||||
Luckily, ioquake3 has backwards compatibility, on the client as well as on the
|
||||
server. This means ioquake3 players can play on old servers just as ioquake3
|
||||
servers are able to service old clients.
|
||||
There are now two cvars that give you some degree of freedom over the reported
|
||||
protocol versions between clients and servers: "com_protocol" and
|
||||
"com_legacyprotocol".
|
||||
The reason for this is that some standalone games increased the protocol
|
||||
number even though nothing really changed in their protocol and the ioquake3
|
||||
engine is still fully compatible.
|
||||
|
||||
The cvar "com_protocol" denotes the protocol version for the new hardened
|
||||
protocol, whereas the "com_legacyprotocol" cvar denotes the protocol version
|
||||
for the legacy protocol.
|
||||
If the value for "com_protocol" and "com_legacyprotocol" is identical, then
|
||||
the legacy protocol is always used. If "com_legacyprotocol" is set to 0, then
|
||||
support for the legacy protocol is disabled.
|
||||
|
||||
Mods that use a standalone engine obviously do not require dual protocol
|
||||
support, and it is turned off if the engine is compiled with STANDALONE per
|
||||
default. If you desire backwards compatibility to older versions of your
|
||||
game you can still enable it in q_shared.h by defining
|
||||
LEGACY_PROTOCOL.
|
||||
In order to harden the network protocol against UDP spoofing attacks a new
|
||||
network protocol was introduced that defends against such attacks.
|
||||
Unfortunately, this protocol will be incompatible to the original quake3 1.32c
|
||||
which is the latest official release from id.
|
||||
Luckily, ioquake3 has backwards compatibility, on the client as well as on the
|
||||
server. This means ioquake3 players can play on old servers just as ioquake3
|
||||
servers are able to service old clients.
|
||||
|
||||
cl_guid Support
|
||||
cl_guid is a cvar which is part of the client's USERINFO string. Its value
|
||||
is a 32 character string made up of [a-f] and [0-9] characters. This
|
||||
value is pseudo-unique for every player. Id's Quake 3 Arena client also
|
||||
sets cl_guid, but only if Punkbuster is enabled on the client.
|
||||
The cvar "com_protocol" denotes the protocol version for the new hardened
|
||||
protocol, whereas the "com_legacyprotocol" cvar denotes the protocol version
|
||||
for the legacy protocol.
|
||||
If the value for "com_protocol" and "com_legacyprotocol" is identical, then
|
||||
the legacy protocol is always used. If "com_legacyprotocol" is set to 0, then
|
||||
support for the legacy protocol is disabled.
|
||||
|
||||
If cl_guidServerUniq is non-zero (the default), then this value is also
|
||||
pseudo-unique for each server a client connects to (based on IP:PORT of
|
||||
the server).
|
||||
Mods that use a standalone engine obviously do not require dual protocol
|
||||
support, and it is turned off if the engine is compiled with STANDALONE per
|
||||
default. If you desire backwards compatibility to older versions of your
|
||||
game you can still enable it in q_shared.h by defining
|
||||
LEGACY_PROTOCOL.
|
||||
|
||||
The purpose of cl_guid is to add an identifier for each player on
|
||||
a server. This value can be reset by the client at any time so it's not
|
||||
useful for blocking access. However, it can have at least two uses in
|
||||
your mod's game code:
|
||||
1) improve logging to allow statistical tools to index players by more
|
||||
## cl_guid Support
|
||||
|
||||
cl_guid is a cvar which is part of the client's USERINFO string. Its value
|
||||
is a 32 character string made up of [a-f] and [0-9] characters. This
|
||||
value is pseudo-unique for every player. Id's Quake 3 Arena client also
|
||||
sets cl_guid, but only if Punkbuster is enabled on the client.
|
||||
|
||||
If cl_guidServerUniq is non-zero (the default), then this value is also
|
||||
pseudo-unique for each server a client connects to (based on IP:PORT of
|
||||
the server).
|
||||
|
||||
The purpose of cl_guid is to add an identifier for each player on
|
||||
a server. This value can be reset by the client at any time so it's not
|
||||
useful for blocking access. However, it can have at least two uses in
|
||||
your mod's game code:
|
||||
|
||||
1. improve logging to allow statistical tools to index players by more
|
||||
than just name
|
||||
2) granting some weak admin rights to players without requiring passwords
|
||||
2. granting some weak admin rights to players without requiring passwords
|
||||
|
||||
PNG support
|
||||
ioquake3 supports the use of PNG (Portable Network Graphic) images as
|
||||
textures. It should be noted that the use of such images in a map will
|
||||
result in missing placeholder textures where the map is used with the id
|
||||
Quake 3 client or earlier versions of ioquake3.
|
||||
## PNG support
|
||||
|
||||
Recent versions of GtkRadiant and q3map2 support PNG images without
|
||||
modification. However GtkRadiant is not aware that PNG textures are supported
|
||||
by ioquake3. To change this behaviour open the file 'q3.game' in the 'games'
|
||||
directory of the GtkRadiant base directory with an editor and change the
|
||||
line:
|
||||
ioquake3 supports the use of PNG (Portable Network Graphic) images as
|
||||
textures. It should be noted that the use of such images in a map will
|
||||
result in missing placeholder textures where the map is used with the id
|
||||
Quake 3 client or earlier versions of ioquake3.
|
||||
|
||||
Recent versions of GtkRadiant and q3map2 support PNG images without
|
||||
modification. However GtkRadiant is not aware that PNG textures are supported
|
||||
by ioquake3. To change this behaviour open the file 'q3.game' in the 'games'
|
||||
directory of the GtkRadiant base directory with an editor and change the
|
||||
line:
|
||||
|
||||
texturetypes="tga jpg"
|
||||
|
||||
to
|
||||
to
|
||||
|
||||
texturetypes="tga jpg png"
|
||||
|
||||
Restart GtkRadiant and PNG textures are now available.
|
||||
Restart GtkRadiant and PNG textures are now available.
|
||||
|
||||
Building with MinGW for pre Windows XP
|
||||
IPv6 support requires a header named "wspiapi.h" to abstract away from
|
||||
differences in earlier versions of Windows' IPv6 stack. There is no MinGW
|
||||
equivalent of this header and the Microsoft version is obviously not
|
||||
redistributable, so in its absence we're forced to require Windows XP.
|
||||
However if this header is acquired separately and placed in the qcommon/
|
||||
directory, this restriction is lifted.
|
||||
## Building with MinGW for pre Windows XP
|
||||
|
||||
IPv6 support requires a header named "wspiapi.h" to abstract away from
|
||||
differences in earlier versions of Windows' IPv6 stack. There is no MinGW
|
||||
equivalent of this header and the Microsoft version is obviously not
|
||||
redistributable, so in its absence we're forced to require Windows XP.
|
||||
However if this header is acquired separately and placed in the qcommon/
|
||||
directory, this restriction is lifted.
|
||||
|
||||
|
||||
------------------------------------------------------------- Contributing -----
|
||||
# Contributing
|
||||
|
||||
Please send all patches to bugzilla (https://bugzilla.icculus.org), or join the
|
||||
mailing list (http://lists.ioquake.org/listinfo.cgi/ioquake3-ioquake.org) and
|
||||
|
@ -689,7 +726,7 @@ accepted as long as they are entirely optional, do not require new media and
|
|||
are off by default.
|
||||
|
||||
|
||||
--------------------------------------------- Building Official Installers -----
|
||||
# Building Official Installers
|
||||
|
||||
We need help getting automated installers on all the platforms that ioquake3
|
||||
supports. We don't necessarily care about all the installers being identical,
|
||||
|
@ -722,22 +759,28 @@ but we have some general guidelines:
|
|||
* Your installer will be mirrored to an "official" directory, thus making it
|
||||
a done deal.
|
||||
|
||||
------------------------------------------------------------------ Credits -----
|
||||
|
||||
# Credits
|
||||
|
||||
Maintainers
|
||||
James Canete <use.less01@gmail.com>
|
||||
Ludwig Nussel <ludwig.nussel@suse.de>
|
||||
Thilo Schulz <arny@ats.s.bawue.de>
|
||||
Tim Angus <tim@ngus.net>
|
||||
Tony J. White <tjw@tjw.org>
|
||||
Zachary J. Slater <zachary@ioquake.org>
|
||||
Zack Middleton <zturtleman@gmail.com>
|
||||
|
||||
* James Canete <use.less01@gmail.com>
|
||||
* Ludwig Nussel <ludwig.nussel@suse.de>
|
||||
* Thilo Schulz <arny@ats.s.bawue.de>
|
||||
* Tim Angus <tim@ngus.net>
|
||||
* Tony J. White <tjw@tjw.org>
|
||||
* Zachary J. Slater <zachary@ioquake.org>
|
||||
* Zack Middleton <zturtleman@gmail.com>
|
||||
|
||||
Significant contributions from
|
||||
Ryan C. Gordon <icculus@icculus.org>
|
||||
Andreas Kohn <andreas@syndrom23.de>
|
||||
Joerg Dietrich <Dietrich_Joerg@t-online.de>
|
||||
Stuart Dalton <badcdev@gmail.com>
|
||||
Vincent S. Cojot <vincent at cojot dot name>
|
||||
optical <alex@rigbo.se>
|
||||
Aaron Gyes <floam@aaron.gy>
|
||||
|
||||
* Ryan C. Gordon <icculus@icculus.org>
|
||||
* Andreas Kohn <andreas@syndrom23.de>
|
||||
* Joerg Dietrich <Dietrich_Joerg@t-online.de>
|
||||
* Stuart Dalton <badcdev@gmail.com>
|
||||
* Vincent S. Cojot <vincent at cojot dot name>
|
||||
* optical <alex@rigbo.se>
|
||||
* Aaron Gyes <floam@aaron.gy>
|
||||
|
||||
|
||||
[![githalytics.com alpha](https://cruel-carlota.pagodabox.com/6d196bd663b47049a25dcb8caef95949 "githalytics.com")](http://githalytics.com/ioquake/ioq3)
|
|
@ -1472,7 +1472,9 @@ int CIN_PlayCinematic( const char *arg, int x, int y, int w, int h, int systemBi
|
|||
|
||||
Con_Close();
|
||||
|
||||
s_rawend[0] = s_soundtime;
|
||||
if (!cinTable[currentHandle].silent) {
|
||||
s_rawend[0] = s_soundtime;
|
||||
}
|
||||
|
||||
return currentHandle;
|
||||
}
|
||||
|
|
|
@ -112,7 +112,6 @@ cvar_t *cl_conXOffset;
|
|||
cvar_t *cl_inGameVideo;
|
||||
|
||||
cvar_t *cl_serverStatusResendTime;
|
||||
cvar_t *cl_trn;
|
||||
|
||||
cvar_t *cl_lanForcePackets;
|
||||
|
||||
|
@ -671,7 +670,7 @@ void CL_StopRecord_f( void ) {
|
|||
CL_DemoFilename
|
||||
==================
|
||||
*/
|
||||
void CL_DemoFilename( int number, char *fileName ) {
|
||||
void CL_DemoFilename( int number, char *fileName, int fileNameSize ) {
|
||||
int a,b,c,d;
|
||||
|
||||
if(number < 0 || number > 9999)
|
||||
|
@ -685,7 +684,7 @@ void CL_DemoFilename( int number, char *fileName ) {
|
|||
number -= c*10;
|
||||
d = number;
|
||||
|
||||
Com_sprintf( fileName, MAX_OSPATH, "demo%i%i%i%i"
|
||||
Com_sprintf( fileName, fileNameSize, "demo%i%i%i%i"
|
||||
, a, b, c, d );
|
||||
}
|
||||
|
||||
|
@ -745,7 +744,7 @@ void CL_Record_f( void ) {
|
|||
|
||||
// scan for a free demo name
|
||||
for ( number = 0 ; number <= 9999 ; number++ ) {
|
||||
CL_DemoFilename( number, demoName );
|
||||
CL_DemoFilename( number, demoName, sizeof( demoName ) );
|
||||
#ifdef LEGACY_PROTOCOL
|
||||
if(clc.compat)
|
||||
Com_sprintf(name, sizeof(name), "demos/%s.%s%d", demoName, DEMOEXT, com_legacyprotocol->integer);
|
||||
|
@ -2429,6 +2428,9 @@ void CL_InitServerInfo( serverInfo_t *server, netadr_t *address ) {
|
|||
server->game[0] = '\0';
|
||||
server->gameType = 0;
|
||||
server->netType = 0;
|
||||
server->punkbuster = 0;
|
||||
server->g_humanplayers = 0;
|
||||
server->g_needpass = 0;
|
||||
}
|
||||
|
||||
#define MAX_SERVERSPERPACKET 256
|
||||
|
@ -2937,13 +2939,13 @@ void CL_Frame ( int msec ) {
|
|||
if ( CL_VideoRecording( ) && cl_aviFrameRate->integer && msec) {
|
||||
// save the current screen
|
||||
if ( clc.state == CA_ACTIVE || cl_forceavidemo->integer) {
|
||||
float fps = MIN(cl_aviFrameRate->value * com_timescale->value, 1000.0f);
|
||||
float frameDuration = MAX(1000.0f / fps, 1.0f) + clc.aviVideoFrameRemainder;
|
||||
|
||||
CL_TakeVideoFrame( );
|
||||
|
||||
// fixed time for next frame'
|
||||
msec = (int)ceil( (1000.0f / cl_aviFrameRate->value) * com_timescale->value );
|
||||
if (msec == 0) {
|
||||
msec = 1;
|
||||
}
|
||||
msec = (int)frameDuration;
|
||||
clc.aviVideoFrameRemainder = frameDuration - msec;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3836,21 +3838,8 @@ void CL_ServerInfoPacket( netadr_t from, msg_t *msg ) {
|
|||
|
||||
// add this to the list
|
||||
cls.numlocalservers = i+1;
|
||||
cls.localServers[i].adr = from;
|
||||
cls.localServers[i].clients = 0;
|
||||
cls.localServers[i].hostName[0] = '\0';
|
||||
cls.localServers[i].mapName[0] = '\0';
|
||||
cls.localServers[i].maxClients = 0;
|
||||
cls.localServers[i].maxPing = 0;
|
||||
cls.localServers[i].minPing = 0;
|
||||
cls.localServers[i].ping = -1;
|
||||
cls.localServers[i].game[0] = '\0';
|
||||
cls.localServers[i].gameType = 0;
|
||||
cls.localServers[i].netType = from.type;
|
||||
cls.localServers[i].punkbuster = 0;
|
||||
cls.localServers[i].g_humanplayers = 0;
|
||||
cls.localServers[i].g_needpass = 0;
|
||||
|
||||
CL_InitServerInfo( &cls.localServers[i], &from );
|
||||
|
||||
Q_strncpyz( info, MSG_ReadString( msg ), MAX_INFO_STRING );
|
||||
if (strlen(info)) {
|
||||
if (info[strlen(info)-1] != '\n') {
|
||||
|
|
|
@ -709,7 +709,7 @@ void CL_ParseVoip ( msg_t *msg ) {
|
|||
const int packetsize = MSG_ReadShort(msg);
|
||||
const int flags = MSG_ReadBits(msg, VOIP_FLAGCNT);
|
||||
char encoded[1024];
|
||||
int seqdiff = sequence - clc.voipIncomingSequence[sender];
|
||||
int seqdiff;
|
||||
int written = 0;
|
||||
int i;
|
||||
|
||||
|
@ -753,6 +753,8 @@ void CL_ParseVoip ( msg_t *msg ) {
|
|||
|
||||
Com_DPrintf("VoIP: packet accepted!\n");
|
||||
|
||||
seqdiff = sequence - clc.voipIncomingSequence[sender];
|
||||
|
||||
// This is a new "generation" ... a new recording started, reset the bits.
|
||||
if (generation != clc.voipIncomingGeneration[sender]) {
|
||||
Com_DPrintf("VoIP: new generation %d!\n", generation);
|
||||
|
|
|
@ -233,6 +233,9 @@ typedef struct {
|
|||
int timeDemoMaxDuration; // maximum frame duration
|
||||
unsigned char timeDemoDurations[ MAX_TIMEDEMO_DURATIONS ]; // log of frame durations
|
||||
|
||||
float aviVideoFrameRemainder;
|
||||
float aviSoundFrameRemainder;
|
||||
|
||||
#ifdef USE_VOIP
|
||||
qboolean voipEnabled;
|
||||
qboolean speexInitialized;
|
||||
|
|
|
@ -157,11 +157,8 @@ int S_OGG_Callback_seek(void *datasource, ogg_int64_t offset, int whence)
|
|||
|
||||
case SEEK_END :
|
||||
{
|
||||
// Quake 3 seems to have trouble with FS_SEEK_END
|
||||
// so we use the file length and FS_SEEK_SET
|
||||
|
||||
// set the file position in the actual file with the Q3 function
|
||||
retVal = FS_Seek(stream->file, (long) stream->length + (long) offset, FS_SEEK_SET);
|
||||
retVal = FS_Seek(stream->file, (long) offset, FS_SEEK_END);
|
||||
|
||||
// something has gone wrong, so we return here
|
||||
if(retVal < 0)
|
||||
|
|
|
@ -146,11 +146,8 @@ int S_OggOpus_Callback_seek(void *datasource, opus_int64 offset, int whence)
|
|||
|
||||
case SEEK_END :
|
||||
{
|
||||
// Quake 3 seems to have trouble with FS_SEEK_END
|
||||
// so we use the file length and FS_SEEK_SET
|
||||
|
||||
// set the file position in the actual file with the Q3 function
|
||||
retVal = FS_Seek(stream->file, (long) stream->length + (long) offset, FS_SEEK_SET);
|
||||
retVal = FS_Seek(stream->file, (long) offset, FS_SEEK_END);
|
||||
|
||||
// something has gone wrong, so we return here
|
||||
if(retVal < 0)
|
||||
|
|
|
@ -271,6 +271,11 @@ static sfx_t *S_FindName( const char *name ) {
|
|||
return NULL;
|
||||
}
|
||||
|
||||
if (name[0] == '*') {
|
||||
Com_Printf( S_COLOR_YELLOW "WARNING: Tried to load player sound directly: %s\n", name );
|
||||
return NULL;
|
||||
}
|
||||
|
||||
hash = S_HashSFXName(name);
|
||||
|
||||
sfx = sfxHash[hash];
|
||||
|
@ -977,29 +982,34 @@ void S_Base_RawSamples( int stream, int samples, int rate, int width, int s_chan
|
|||
int i;
|
||||
int src, dst;
|
||||
float scale;
|
||||
int intVolume;
|
||||
int intVolumeLeft, intVolumeRight;
|
||||
portable_samplepair_t *rawsamples;
|
||||
|
||||
if ( !s_soundStarted || s_soundMuted ) {
|
||||
return;
|
||||
}
|
||||
|
||||
if(entityNum >= 0)
|
||||
{
|
||||
// FIXME: support spatialized raw streams, e.g. for VoIP
|
||||
return;
|
||||
}
|
||||
|
||||
if ( (stream < 0) || (stream >= MAX_RAW_STREAMS) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
rawsamples = s_rawsamples[stream];
|
||||
|
||||
if(s_muted->integer)
|
||||
intVolume = 0;
|
||||
else
|
||||
intVolume = 256 * volume * s_volume->value;
|
||||
if ( s_muted->integer ) {
|
||||
intVolumeLeft = intVolumeRight = 0;
|
||||
} else {
|
||||
int leftvol, rightvol;
|
||||
|
||||
if ( entityNum >= 0 && entityNum < MAX_GENTITIES ) {
|
||||
// support spatialized raw streams, e.g. for VoIP
|
||||
S_SpatializeOrigin( loopSounds[ entityNum ].origin, 256, &leftvol, &rightvol );
|
||||
} else {
|
||||
leftvol = rightvol = 256;
|
||||
}
|
||||
|
||||
intVolumeLeft = leftvol * volume * s_volume->value;
|
||||
intVolumeRight = rightvol * volume * s_volume->value;
|
||||
}
|
||||
|
||||
if ( s_rawend[stream] < s_soundtime ) {
|
||||
Com_DPrintf( "S_Base_RawSamples: resetting minimum: %i < %i\n", s_rawend[stream], s_soundtime );
|
||||
|
@ -1017,8 +1027,8 @@ void S_Base_RawSamples( int stream, int samples, int rate, int width, int s_chan
|
|||
{
|
||||
dst = s_rawend[stream]&(MAX_RAW_SAMPLES-1);
|
||||
s_rawend[stream]++;
|
||||
rawsamples[dst].left = ((short *)data)[i*2] * intVolume;
|
||||
rawsamples[dst].right = ((short *)data)[i*2+1] * intVolume;
|
||||
rawsamples[dst].left = ((short *)data)[i*2] * intVolumeLeft;
|
||||
rawsamples[dst].right = ((short *)data)[i*2+1] * intVolumeRight;
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -1030,8 +1040,8 @@ void S_Base_RawSamples( int stream, int samples, int rate, int width, int s_chan
|
|||
break;
|
||||
dst = s_rawend[stream]&(MAX_RAW_SAMPLES-1);
|
||||
s_rawend[stream]++;
|
||||
rawsamples[dst].left = ((short *)data)[src*2] * intVolume;
|
||||
rawsamples[dst].right = ((short *)data)[src*2+1] * intVolume;
|
||||
rawsamples[dst].left = ((short *)data)[src*2] * intVolumeLeft;
|
||||
rawsamples[dst].right = ((short *)data)[src*2+1] * intVolumeRight;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1044,13 +1054,14 @@ void S_Base_RawSamples( int stream, int samples, int rate, int width, int s_chan
|
|||
break;
|
||||
dst = s_rawend[stream]&(MAX_RAW_SAMPLES-1);
|
||||
s_rawend[stream]++;
|
||||
rawsamples[dst].left = ((short *)data)[src] * intVolume;
|
||||
rawsamples[dst].right = ((short *)data)[src] * intVolume;
|
||||
rawsamples[dst].left = ((short *)data)[src] * intVolumeLeft;
|
||||
rawsamples[dst].right = ((short *)data)[src] * intVolumeRight;
|
||||
}
|
||||
}
|
||||
else if (s_channels == 2 && width == 1)
|
||||
{
|
||||
intVolume *= 256;
|
||||
intVolumeLeft *= 256;
|
||||
intVolumeRight *= 256;
|
||||
|
||||
for (i=0 ; ; i++)
|
||||
{
|
||||
|
@ -1059,13 +1070,14 @@ void S_Base_RawSamples( int stream, int samples, int rate, int width, int s_chan
|
|||
break;
|
||||
dst = s_rawend[stream]&(MAX_RAW_SAMPLES-1);
|
||||
s_rawend[stream]++;
|
||||
rawsamples[dst].left = ((char *)data)[src*2] * intVolume;
|
||||
rawsamples[dst].right = ((char *)data)[src*2+1] * intVolume;
|
||||
rawsamples[dst].left = ((char *)data)[src*2] * intVolumeLeft;
|
||||
rawsamples[dst].right = ((char *)data)[src*2+1] * intVolumeRight;
|
||||
}
|
||||
}
|
||||
else if (s_channels == 1 && width == 1)
|
||||
{
|
||||
intVolume *= 256;
|
||||
intVolumeLeft *= 256;
|
||||
intVolumeRight *= 256;
|
||||
|
||||
for (i=0 ; ; i++)
|
||||
{
|
||||
|
@ -1074,8 +1086,8 @@ void S_Base_RawSamples( int stream, int samples, int rate, int width, int s_chan
|
|||
break;
|
||||
dst = s_rawend[stream]&(MAX_RAW_SAMPLES-1);
|
||||
s_rawend[stream]++;
|
||||
rawsamples[dst].left = (((byte *)data)[src]-128) * intVolume;
|
||||
rawsamples[dst].right = (((byte *)data)[src]-128) * intVolume;
|
||||
rawsamples[dst].left = (((byte *)data)[src]-128) * intVolumeLeft;
|
||||
rawsamples[dst].right = (((byte *)data)[src]-128) * intVolumeRight;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1237,7 +1249,13 @@ void S_GetSoundtime(void)
|
|||
|
||||
if( CL_VideoRecording( ) )
|
||||
{
|
||||
s_soundtime += (int)ceil( dma.speed / cl_aviFrameRate->value );
|
||||
float fps = MIN(cl_aviFrameRate->value, 1000.0f);
|
||||
float frameDuration = MAX(dma.speed / fps, 1.0f) + clc.aviSoundFrameRemainder;
|
||||
|
||||
int msec = (int)frameDuration;
|
||||
s_soundtime += msec;
|
||||
clc.aviSoundFrameRemainder = frameDuration - msec;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -1360,6 +1378,32 @@ void S_Base_StopBackgroundTrack( void ) {
|
|||
s_rawend[0] = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
======================
|
||||
S_OpenBackgroundStream
|
||||
======================
|
||||
*/
|
||||
static void S_OpenBackgroundStream( const char *filename ) {
|
||||
// close the background track, but DON'T reset s_rawend
|
||||
// if restarting the same back ground track
|
||||
if(s_backgroundStream)
|
||||
{
|
||||
S_CodecCloseStream(s_backgroundStream);
|
||||
s_backgroundStream = NULL;
|
||||
}
|
||||
|
||||
// Open stream
|
||||
s_backgroundStream = S_CodecOpenStream(filename);
|
||||
if(!s_backgroundStream) {
|
||||
Com_Printf( S_COLOR_YELLOW "WARNING: couldn't open music file %s\n", filename );
|
||||
return;
|
||||
}
|
||||
|
||||
if(s_backgroundStream->info.channels != 2 || s_backgroundStream->info.rate != 22050) {
|
||||
Com_Printf(S_COLOR_YELLOW "WARNING: music file %s is not 22k stereo\n", filename );
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
======================
|
||||
S_StartBackgroundTrack
|
||||
|
@ -1380,30 +1424,9 @@ void S_Base_StartBackgroundTrack( const char *intro, const char *loop ){
|
|||
return;
|
||||
}
|
||||
|
||||
if( !loop ) {
|
||||
s_backgroundLoop[0] = 0;
|
||||
} else {
|
||||
Q_strncpyz( s_backgroundLoop, loop, sizeof( s_backgroundLoop ) );
|
||||
}
|
||||
Q_strncpyz( s_backgroundLoop, loop, sizeof( s_backgroundLoop ) );
|
||||
|
||||
// close the background track, but DON'T reset s_rawend
|
||||
// if restarting the same back ground track
|
||||
if(s_backgroundStream)
|
||||
{
|
||||
S_CodecCloseStream(s_backgroundStream);
|
||||
s_backgroundStream = NULL;
|
||||
}
|
||||
|
||||
// Open stream
|
||||
s_backgroundStream = S_CodecOpenStream(intro);
|
||||
if(!s_backgroundStream) {
|
||||
Com_Printf( S_COLOR_YELLOW "WARNING: couldn't open music file %s\n", intro );
|
||||
return;
|
||||
}
|
||||
|
||||
if(s_backgroundStream->info.channels != 2 || s_backgroundStream->info.rate != 22050) {
|
||||
Com_Printf(S_COLOR_YELLOW "WARNING: music file %s is not 22k stereo\n", intro );
|
||||
}
|
||||
S_OpenBackgroundStream( intro );
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -1466,9 +1489,7 @@ void S_UpdateBackgroundTrack( void ) {
|
|||
// loop
|
||||
if(s_backgroundLoop[0])
|
||||
{
|
||||
S_CodecCloseStream(s_backgroundStream);
|
||||
s_backgroundStream = NULL;
|
||||
S_Base_StartBackgroundTrack( s_backgroundLoop, s_backgroundLoop );
|
||||
S_OpenBackgroundStream( s_backgroundLoop );
|
||||
if(!s_backgroundStream)
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -56,6 +56,7 @@ typedef struct sfx_s {
|
|||
qboolean soundCompressed; // not in Memory
|
||||
int soundCompressionMethod;
|
||||
int soundLength;
|
||||
int soundChannels;
|
||||
char soundName[MAX_QPATH];
|
||||
int lastTimeUsed;
|
||||
struct sfx_s *next;
|
||||
|
|
|
@ -113,47 +113,51 @@ ResampleSfx
|
|||
resample / decimate to the current source rate
|
||||
================
|
||||
*/
|
||||
static void ResampleSfx( sfx_t *sfx, int inrate, int inwidth, byte *data, qboolean compressed ) {
|
||||
static int ResampleSfx( sfx_t *sfx, int channels, int inrate, int inwidth, int samples, byte *data, qboolean compressed ) {
|
||||
int outcount;
|
||||
int srcsample;
|
||||
float stepscale;
|
||||
int i;
|
||||
int i, j;
|
||||
int sample, samplefrac, fracstep;
|
||||
int part;
|
||||
sndBuffer *chunk;
|
||||
|
||||
stepscale = (float)inrate / dma.speed; // this is usually 0.5, 1, or 2
|
||||
|
||||
outcount = sfx->soundLength / stepscale;
|
||||
sfx->soundLength = outcount;
|
||||
outcount = samples / stepscale;
|
||||
|
||||
samplefrac = 0;
|
||||
fracstep = stepscale * 256;
|
||||
fracstep = stepscale * 256 * channels;
|
||||
chunk = sfx->soundData;
|
||||
|
||||
for (i=0 ; i<outcount ; i++)
|
||||
{
|
||||
srcsample = samplefrac >> 8;
|
||||
samplefrac += fracstep;
|
||||
if( inwidth == 2 ) {
|
||||
sample = ( ((short *)data)[srcsample] );
|
||||
} else {
|
||||
sample = (int)( (unsigned char)(data[srcsample]) - 128) << 8;
|
||||
}
|
||||
part = (i&(SND_CHUNK_SIZE-1));
|
||||
if (part == 0) {
|
||||
sndBuffer *newchunk;
|
||||
newchunk = SND_malloc();
|
||||
if (chunk == NULL) {
|
||||
sfx->soundData = newchunk;
|
||||
for (j=0 ; j<channels ; j++)
|
||||
{
|
||||
if( inwidth == 2 ) {
|
||||
sample = ( ((short *)data)[srcsample+j] );
|
||||
} else {
|
||||
chunk->next = newchunk;
|
||||
sample = (int)( (unsigned char)(data[srcsample+j]) - 128) << 8;
|
||||
}
|
||||
part = (i*channels+j)&(SND_CHUNK_SIZE-1);
|
||||
if (part == 0) {
|
||||
sndBuffer *newchunk;
|
||||
newchunk = SND_malloc();
|
||||
if (chunk == NULL) {
|
||||
sfx->soundData = newchunk;
|
||||
} else {
|
||||
chunk->next = newchunk;
|
||||
}
|
||||
chunk = newchunk;
|
||||
}
|
||||
chunk = newchunk;
|
||||
}
|
||||
|
||||
chunk->sndChunk[part] = sample;
|
||||
chunk->sndChunk[part] = sample;
|
||||
}
|
||||
}
|
||||
|
||||
return outcount;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -163,11 +167,11 @@ ResampleSfx
|
|||
resample / decimate to the current source rate
|
||||
================
|
||||
*/
|
||||
static int ResampleSfxRaw( short *sfx, int inrate, int inwidth, int samples, byte *data ) {
|
||||
static int ResampleSfxRaw( short *sfx, int channels, int inrate, int inwidth, int samples, byte *data ) {
|
||||
int outcount;
|
||||
int srcsample;
|
||||
float stepscale;
|
||||
int i;
|
||||
int i, j;
|
||||
int sample, samplefrac, fracstep;
|
||||
|
||||
stepscale = (float)inrate / dma.speed; // this is usually 0.5, 1, or 2
|
||||
|
@ -175,18 +179,21 @@ static int ResampleSfxRaw( short *sfx, int inrate, int inwidth, int samples, byt
|
|||
outcount = samples / stepscale;
|
||||
|
||||
samplefrac = 0;
|
||||
fracstep = stepscale * 256;
|
||||
fracstep = stepscale * 256 * channels;
|
||||
|
||||
for (i=0 ; i<outcount ; i++)
|
||||
{
|
||||
srcsample = samplefrac >> 8;
|
||||
samplefrac += fracstep;
|
||||
if( inwidth == 2 ) {
|
||||
sample = LittleShort ( ((short *)data)[srcsample] );
|
||||
} else {
|
||||
sample = (int)( (unsigned char)(data[srcsample]) - 128) << 8;
|
||||
for (j=0 ; j<channels ; j++)
|
||||
{
|
||||
if( inwidth == 2 ) {
|
||||
sample = LittleShort ( ((short *)data)[srcsample+j] );
|
||||
} else {
|
||||
sample = (int)( (unsigned char)(data[srcsample+j]) - 128) << 8;
|
||||
}
|
||||
sfx[i*channels+j] = sample;
|
||||
}
|
||||
sfx[i] = sample;
|
||||
}
|
||||
return outcount;
|
||||
}
|
||||
|
@ -208,11 +215,6 @@ qboolean S_LoadSound( sfx_t *sfx )
|
|||
snd_info_t info;
|
||||
// int size;
|
||||
|
||||
// player specific sounds are never directly loaded
|
||||
if ( sfx->soundName[0] == '*') {
|
||||
return qfalse;
|
||||
}
|
||||
|
||||
// load it in
|
||||
data = S_CodecLoad(sfx->soundName, &info);
|
||||
if(!data)
|
||||
|
@ -226,7 +228,7 @@ qboolean S_LoadSound( sfx_t *sfx )
|
|||
Com_DPrintf(S_COLOR_YELLOW "WARNING: %s is not a 22kHz audio file\n", sfx->soundName);
|
||||
}
|
||||
|
||||
samples = Hunk_AllocateTempMemory(info.samples * sizeof(short) * 2);
|
||||
samples = Hunk_AllocateTempMemory(info.channels * info.samples * sizeof(short) * 2);
|
||||
|
||||
sfx->lastTimeUsed = Com_Milliseconds()+1;
|
||||
|
||||
|
@ -236,29 +238,30 @@ qboolean S_LoadSound( sfx_t *sfx )
|
|||
// manager to do the right thing for us and page
|
||||
// sound in as needed
|
||||
|
||||
if( sfx->soundCompressed == qtrue) {
|
||||
if( info.channels == 1 && sfx->soundCompressed == qtrue) {
|
||||
sfx->soundCompressionMethod = 1;
|
||||
sfx->soundData = NULL;
|
||||
sfx->soundLength = ResampleSfxRaw( samples, info.rate, info.width, info.samples, data + info.dataofs );
|
||||
sfx->soundLength = ResampleSfxRaw( samples, info.channels, info.rate, info.width, info.samples, data + info.dataofs );
|
||||
S_AdpcmEncodeSound(sfx, samples);
|
||||
#if 0
|
||||
} else if (info.samples>(SND_CHUNK_SIZE*16) && info.width >1) {
|
||||
} else if (info.channels == 1 && info.samples>(SND_CHUNK_SIZE*16) && info.width >1) {
|
||||
sfx->soundCompressionMethod = 3;
|
||||
sfx->soundData = NULL;
|
||||
sfx->soundLength = ResampleSfxRaw( samples, info.rate, info.width, info.samples, (data + info.dataofs) );
|
||||
sfx->soundLength = ResampleSfxRaw( samples, info.channels, info.rate, info.width, info.samples, (data + info.dataofs) );
|
||||
encodeMuLaw( sfx, samples);
|
||||
} else if (info.samples>(SND_CHUNK_SIZE*6400) && info.width >1) {
|
||||
} else if (info.channels == 1 && info.samples>(SND_CHUNK_SIZE*6400) && info.width >1) {
|
||||
sfx->soundCompressionMethod = 2;
|
||||
sfx->soundData = NULL;
|
||||
sfx->soundLength = ResampleSfxRaw( samples, info.rate, info.width, info.samples, (data + info.dataofs) );
|
||||
sfx->soundLength = ResampleSfxRaw( samples, info.channels, info.rate, info.width, info.samples, (data + info.dataofs) );
|
||||
encodeWavelet( sfx, samples);
|
||||
#endif
|
||||
} else {
|
||||
sfx->soundCompressionMethod = 0;
|
||||
sfx->soundLength = info.samples;
|
||||
sfx->soundData = NULL;
|
||||
ResampleSfx( sfx, info.rate, info.width, data + info.dataofs, qfalse );
|
||||
sfx->soundLength = ResampleSfx( sfx, info.channels, info.rate, info.width, info.samples, data + info.dataofs, qfalse );
|
||||
}
|
||||
|
||||
sfx->soundChannels = info.channels;
|
||||
|
||||
Hunk_FreeTempMemory(samples);
|
||||
Hunk_FreeTempMemory(data);
|
||||
|
|
|
@ -234,7 +234,7 @@ static void S_PaintChannelFrom16_altivec( channel_t *ch, const sfx_t *sc, int co
|
|||
portable_samplepair_t *samp;
|
||||
sndBuffer *chunk;
|
||||
short *samples;
|
||||
float ooff, fdata, fdiv, fleftvol, frightvol;
|
||||
float ooff, fdata[2], fdiv, fleftvol, frightvol;
|
||||
|
||||
samp = &paintbuffer[ bufferOffset ];
|
||||
|
||||
|
@ -242,6 +242,14 @@ static void S_PaintChannelFrom16_altivec( channel_t *ch, const sfx_t *sc, int co
|
|||
sampleOffset = sampleOffset*ch->oldDopplerScale;
|
||||
}
|
||||
|
||||
if ( sc->soundChannels == 2 ) {
|
||||
sampleOffset *= sc->soundChannels;
|
||||
|
||||
if ( sampleOffset & 1 ) {
|
||||
sampleOffset &= ~1;
|
||||
}
|
||||
}
|
||||
|
||||
chunk = sc->soundData;
|
||||
while (sampleOffset>=SND_CHUNK_SIZE) {
|
||||
chunk = chunk->next;
|
||||
|
@ -274,6 +282,10 @@ static void S_PaintChannelFrom16_altivec( channel_t *ch, const sfx_t *sc, int co
|
|||
while(i < count && (((unsigned long)&samp[i] & 0x1f) || ((count-i) < 8) || ((SND_CHUNK_SIZE - sampleOffset) < 8))) {
|
||||
data = samples[sampleOffset++];
|
||||
samp[i].left += (data * leftvol)>>8;
|
||||
|
||||
if ( sc->soundChannels == 2 ) {
|
||||
data = samples[sampleOffset++];
|
||||
}
|
||||
samp[i].right += (data * rightvol)>>8;
|
||||
|
||||
if (sampleOffset == SND_CHUNK_SIZE) {
|
||||
|
@ -373,10 +385,10 @@ static void S_PaintChannelFrom16_altivec( channel_t *ch, const sfx_t *sc, int co
|
|||
for ( i=0 ; i<count ; i++ ) {
|
||||
|
||||
aoff = ooff;
|
||||
ooff = ooff + ch->dopplerScale;
|
||||
ooff = ooff + ch->dopplerScale * sc->soundChannels;
|
||||
boff = ooff;
|
||||
fdata = 0;
|
||||
for (j=aoff; j<boff; j++) {
|
||||
fdata[0] = fdata[1] = 0;
|
||||
for (j=aoff; j<boff; j += sc->soundChannels) {
|
||||
if (j == SND_CHUNK_SIZE) {
|
||||
chunk = chunk->next;
|
||||
if (!chunk) {
|
||||
|
@ -385,11 +397,17 @@ static void S_PaintChannelFrom16_altivec( channel_t *ch, const sfx_t *sc, int co
|
|||
samples = chunk->sndChunk;
|
||||
ooff -= SND_CHUNK_SIZE;
|
||||
}
|
||||
fdata += samples[j&(SND_CHUNK_SIZE-1)];
|
||||
if ( sc->soundChannels == 2 ) {
|
||||
fdata[0] += samples[j&(SND_CHUNK_SIZE-1)];
|
||||
fdata[1] += samples[(j+1)&(SND_CHUNK_SIZE-1)];
|
||||
} else {
|
||||
fdata[0] += samples[j&(SND_CHUNK_SIZE-1)];
|
||||
fdata[1] += samples[j&(SND_CHUNK_SIZE-1)];
|
||||
}
|
||||
}
|
||||
fdiv = 256 * (boff-aoff);
|
||||
samp[i].left += (fdata * fleftvol)/fdiv;
|
||||
samp[i].right += (fdata * frightvol)/fdiv;
|
||||
fdiv = 256 * (boff-aoff) / sc->soundChannels;
|
||||
samp[i].left += (fdata[0] * fleftvol)/fdiv;
|
||||
samp[i].right += (fdata[1] * frightvol)/fdiv;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -402,7 +420,7 @@ static void S_PaintChannelFrom16_scalar( channel_t *ch, const sfx_t *sc, int cou
|
|||
portable_samplepair_t *samp;
|
||||
sndBuffer *chunk;
|
||||
short *samples;
|
||||
float ooff, fdata, fdiv, fleftvol, frightvol;
|
||||
float ooff, fdata[2], fdiv, fleftvol, frightvol;
|
||||
|
||||
samp = &paintbuffer[ bufferOffset ];
|
||||
|
||||
|
@ -410,6 +428,14 @@ static void S_PaintChannelFrom16_scalar( channel_t *ch, const sfx_t *sc, int cou
|
|||
sampleOffset = sampleOffset*ch->oldDopplerScale;
|
||||
}
|
||||
|
||||
if ( sc->soundChannels == 2 ) {
|
||||
sampleOffset *= sc->soundChannels;
|
||||
|
||||
if ( sampleOffset & 1 ) {
|
||||
sampleOffset &= ~1;
|
||||
}
|
||||
}
|
||||
|
||||
chunk = sc->soundData;
|
||||
while (sampleOffset>=SND_CHUNK_SIZE) {
|
||||
chunk = chunk->next;
|
||||
|
@ -426,6 +452,10 @@ static void S_PaintChannelFrom16_scalar( channel_t *ch, const sfx_t *sc, int cou
|
|||
for ( i=0 ; i<count ; i++ ) {
|
||||
data = samples[sampleOffset++];
|
||||
samp[i].left += (data * leftvol)>>8;
|
||||
|
||||
if ( sc->soundChannels == 2 ) {
|
||||
data = samples[sampleOffset++];
|
||||
}
|
||||
samp[i].right += (data * rightvol)>>8;
|
||||
|
||||
if (sampleOffset == SND_CHUNK_SIZE) {
|
||||
|
@ -447,10 +477,10 @@ static void S_PaintChannelFrom16_scalar( channel_t *ch, const sfx_t *sc, int cou
|
|||
for ( i=0 ; i<count ; i++ ) {
|
||||
|
||||
aoff = ooff;
|
||||
ooff = ooff + ch->dopplerScale;
|
||||
ooff = ooff + ch->dopplerScale * sc->soundChannels;
|
||||
boff = ooff;
|
||||
fdata = 0;
|
||||
for (j=aoff; j<boff; j++) {
|
||||
fdata[0] = fdata[1] = 0;
|
||||
for (j=aoff; j<boff; j += sc->soundChannels) {
|
||||
if (j == SND_CHUNK_SIZE) {
|
||||
chunk = chunk->next;
|
||||
if (!chunk) {
|
||||
|
@ -459,11 +489,17 @@ static void S_PaintChannelFrom16_scalar( channel_t *ch, const sfx_t *sc, int cou
|
|||
samples = chunk->sndChunk;
|
||||
ooff -= SND_CHUNK_SIZE;
|
||||
}
|
||||
fdata += samples[j&(SND_CHUNK_SIZE-1)];
|
||||
if ( sc->soundChannels == 2 ) {
|
||||
fdata[0] += samples[j&(SND_CHUNK_SIZE-1)];
|
||||
fdata[1] += samples[(j+1)&(SND_CHUNK_SIZE-1)];
|
||||
} else {
|
||||
fdata[0] += samples[j&(SND_CHUNK_SIZE-1)];
|
||||
fdata[1] += samples[j&(SND_CHUNK_SIZE-1)];
|
||||
}
|
||||
}
|
||||
fdiv = 256 * (boff-aoff);
|
||||
samp[i].left += (fdata * fleftvol)/fdiv;
|
||||
samp[i].right += (fdata * frightvol)/fdiv;
|
||||
fdiv = 256 * (boff-aoff) / sc->soundChannels;
|
||||
samp[i].left += (fdata[0] * fleftvol)/fdiv;
|
||||
samp[i].right += (fdata[1] * frightvol)/fdiv;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -318,6 +318,11 @@ static sfxHandle_t S_AL_BufferFind(const char *filename)
|
|||
return 0;
|
||||
}
|
||||
|
||||
if ( filename[0] == '*' ) {
|
||||
Com_Printf( S_COLOR_YELLOW "WARNING: Tried to load player sound directly: %s\n", filename );
|
||||
return 0;
|
||||
}
|
||||
|
||||
for(i = 0; i < numSfx; i++)
|
||||
{
|
||||
if(!Q_stricmp(knownSfx[i].filename, filename))
|
||||
|
@ -417,6 +422,44 @@ static qboolean S_AL_BufferEvict( void )
|
|||
return qfalse;
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
S_AL_GenBuffers
|
||||
=================
|
||||
*/
|
||||
static qboolean S_AL_GenBuffers(ALsizei numBuffers, ALuint *buffers, const char *name)
|
||||
{
|
||||
ALenum error;
|
||||
|
||||
S_AL_ClearError( qfalse );
|
||||
qalGenBuffers( numBuffers, buffers );
|
||||
error = qalGetError();
|
||||
|
||||
// If we ran out of buffers, start evicting the least recently used sounds
|
||||
while( error == AL_INVALID_VALUE )
|
||||
{
|
||||
if( !S_AL_BufferEvict( ) )
|
||||
{
|
||||
Com_Printf( S_COLOR_RED "ERROR: Out of audio buffers\n");
|
||||
return qfalse;
|
||||
}
|
||||
|
||||
// Try again
|
||||
S_AL_ClearError( qfalse );
|
||||
qalGenBuffers( numBuffers, buffers );
|
||||
error = qalGetError();
|
||||
}
|
||||
|
||||
if( error != AL_NO_ERROR )
|
||||
{
|
||||
Com_Printf( S_COLOR_RED "ERROR: Can't create a sound buffer for %s - %s\n",
|
||||
name, S_AL_ErrorMsg(error));
|
||||
return qfalse;
|
||||
}
|
||||
|
||||
return qtrue;
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
S_AL_BufferLoad
|
||||
|
@ -435,10 +478,6 @@ static void S_AL_BufferLoad(sfxHandle_t sfx, qboolean cache)
|
|||
if(curSfx->filename[0] == '\0')
|
||||
return;
|
||||
|
||||
// Player SFX
|
||||
if(curSfx->filename[0] == '*')
|
||||
return;
|
||||
|
||||
// Already done?
|
||||
if((curSfx->inMemory) || (curSfx->isDefault) || (!cache && curSfx->isDefaultChecked))
|
||||
return;
|
||||
|
@ -463,14 +502,10 @@ static void S_AL_BufferLoad(sfxHandle_t sfx, qboolean cache)
|
|||
format = S_AL_Format(info.width, info.channels);
|
||||
|
||||
// Create a buffer
|
||||
S_AL_ClearError( qfalse );
|
||||
qalGenBuffers(1, &curSfx->buffer);
|
||||
if((error = qalGetError()) != AL_NO_ERROR)
|
||||
if (!S_AL_GenBuffers(1, &curSfx->buffer, curSfx->filename))
|
||||
{
|
||||
S_AL_BufferUseDefault(sfx);
|
||||
Hunk_FreeTempMemory(data);
|
||||
Com_Printf( S_COLOR_RED "ERROR: Can't create a sound buffer for %s - %s\n",
|
||||
curSfx->filename, S_AL_ErrorMsg(error));
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -492,6 +527,7 @@ static void S_AL_BufferLoad(sfxHandle_t sfx, qboolean cache)
|
|||
{
|
||||
if( !S_AL_BufferEvict( ) )
|
||||
{
|
||||
qalDeleteBuffers(1, &curSfx->buffer);
|
||||
S_AL_BufferUseDefault(sfx);
|
||||
Hunk_FreeTempMemory(data);
|
||||
Com_Printf( S_COLOR_RED "ERROR: Out of memory loading %s\n", curSfx->filename);
|
||||
|
@ -506,6 +542,7 @@ static void S_AL_BufferLoad(sfxHandle_t sfx, qboolean cache)
|
|||
// Some other error condition
|
||||
if(error != AL_NO_ERROR)
|
||||
{
|
||||
qalDeleteBuffers(1, &curSfx->buffer);
|
||||
S_AL_BufferUseDefault(sfx);
|
||||
Hunk_FreeTempMemory(data);
|
||||
Com_Printf( S_COLOR_RED "ERROR: Can't fill sound buffer for %s - %s\n",
|
||||
|
@ -1091,7 +1128,7 @@ static void S_AL_SrcKill(srcHandle_t src)
|
|||
curSource->isPlaying = qfalse;
|
||||
}
|
||||
|
||||
// Remove the buffer
|
||||
// Detach any buffers
|
||||
qalSourcei(curSource->alSource, AL_BUFFER, 0);
|
||||
|
||||
curSource->sfx = 0;
|
||||
|
@ -1621,6 +1658,10 @@ void S_AL_SrcUpdate( void )
|
|||
|
||||
if(!curSource->isPlaying)
|
||||
{
|
||||
qalSourcei(curSource->alSource, AL_LOOPING, AL_TRUE);
|
||||
curSource->isPlaying = qtrue;
|
||||
qalSourcePlay(curSource->alSource);
|
||||
|
||||
if(curSource->priority == SRCPRI_AMBIENT)
|
||||
{
|
||||
// If there are other ambient looping sources with the same sound,
|
||||
|
@ -1678,10 +1719,6 @@ void S_AL_SrcUpdate( void )
|
|||
}
|
||||
|
||||
curSfx->loopActiveCnt++;
|
||||
|
||||
qalSourcei(curSource->alSource, AL_LOOPING, AL_TRUE);
|
||||
curSource->isPlaying = qtrue;
|
||||
qalSourcePlay(curSource->alSource);
|
||||
}
|
||||
|
||||
// Update locality
|
||||
|
@ -1763,9 +1800,15 @@ ALuint S_AL_SrcGet(srcHandle_t src)
|
|||
|
||||
//===========================================================================
|
||||
|
||||
// Q3A cinematics use up to 12 buffers at once
|
||||
#define MAX_STREAM_BUFFERS 20
|
||||
|
||||
static srcHandle_t streamSourceHandles[MAX_RAW_STREAMS];
|
||||
static qboolean streamPlaying[MAX_RAW_STREAMS];
|
||||
static ALuint streamSources[MAX_RAW_STREAMS];
|
||||
static ALuint streamBuffers[MAX_RAW_STREAMS][MAX_STREAM_BUFFERS];
|
||||
static int streamNumBuffers[MAX_RAW_STREAMS];
|
||||
static int streamBufIndex[MAX_RAW_STREAMS];
|
||||
|
||||
/*
|
||||
=================
|
||||
|
@ -1823,6 +1866,9 @@ static void S_AL_AllocateStreamChannel(int stream, int entityNum)
|
|||
|
||||
streamSourceHandles[stream] = cursrc;
|
||||
streamSources[stream] = alsrc;
|
||||
|
||||
streamNumBuffers[stream] = 0;
|
||||
streamBufIndex[stream] = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -1835,6 +1881,15 @@ static void S_AL_FreeStreamChannel( int stream )
|
|||
if ((stream < 0) || (stream >= MAX_RAW_STREAMS))
|
||||
return;
|
||||
|
||||
// Detach any buffers
|
||||
qalSourcei(streamSources[stream], AL_BUFFER, 0);
|
||||
|
||||
// Delete the buffers
|
||||
if (streamNumBuffers[stream] > 0) {
|
||||
qalDeleteBuffers(streamNumBuffers[stream], streamBuffers[stream]);
|
||||
streamNumBuffers[stream] = 0;
|
||||
}
|
||||
|
||||
// Release the output streamSource
|
||||
S_AL_SrcUnlock(streamSourceHandles[stream]);
|
||||
S_AL_SrcKill(streamSourceHandles[stream]);
|
||||
|
@ -1850,6 +1905,7 @@ S_AL_RawSamples
|
|||
static
|
||||
void S_AL_RawSamples(int stream, int samples, int rate, int width, int channels, const byte *data, float volume, int entityNum)
|
||||
{
|
||||
int numBuffers;
|
||||
ALuint buffer;
|
||||
ALuint format;
|
||||
|
||||
|
@ -1871,8 +1927,40 @@ void S_AL_RawSamples(int stream, int samples, int rate, int width, int channels,
|
|||
}
|
||||
}
|
||||
|
||||
// Create a buffer, and stuff the data into it
|
||||
qalGenBuffers(1, &buffer);
|
||||
qalGetSourcei(streamSources[stream], AL_BUFFERS_QUEUED, &numBuffers);
|
||||
|
||||
if (numBuffers == MAX_STREAM_BUFFERS)
|
||||
{
|
||||
Com_DPrintf(S_COLOR_RED"WARNING: Steam dropping raw samples, reached MAX_STREAM_BUFFERS\n");
|
||||
return;
|
||||
}
|
||||
|
||||
// Allocate a new AL buffer if needed
|
||||
if (numBuffers == streamNumBuffers[stream])
|
||||
{
|
||||
ALuint oldBuffers[MAX_STREAM_BUFFERS];
|
||||
int i;
|
||||
|
||||
if (!S_AL_GenBuffers(1, &buffer, "stream"))
|
||||
return;
|
||||
|
||||
Com_Memcpy(oldBuffers, &streamBuffers[stream], sizeof (oldBuffers));
|
||||
|
||||
// Reorder buffer array in order of oldest to newest
|
||||
for ( i = 0; i < streamNumBuffers[stream]; ++i )
|
||||
streamBuffers[stream][i] = oldBuffers[(streamBufIndex[stream] + i) % streamNumBuffers[stream]];
|
||||
|
||||
// Add the new buffer to end
|
||||
streamBuffers[stream][streamNumBuffers[stream]] = buffer;
|
||||
streamBufIndex[stream] = streamNumBuffers[stream];
|
||||
streamNumBuffers[stream]++;
|
||||
}
|
||||
|
||||
// Select next buffer in loop
|
||||
buffer = streamBuffers[stream][ streamBufIndex[stream] ];
|
||||
streamBufIndex[stream] = (streamBufIndex[stream] + 1) % streamNumBuffers[stream];
|
||||
|
||||
// Fill buffer
|
||||
qalBufferData(buffer, format, (ALvoid *)data, (samples * width * channels), rate);
|
||||
|
||||
// Shove the data onto the streamSource
|
||||
|
@ -1883,6 +1971,13 @@ void S_AL_RawSamples(int stream, int samples, int rate, int width, int channels,
|
|||
// Volume
|
||||
S_AL_Gain (streamSources[stream], volume * s_volume->value * s_alGain->value);
|
||||
}
|
||||
|
||||
// Start stream
|
||||
if(!streamPlaying[stream])
|
||||
{
|
||||
qalSourcePlay( streamSources[stream] );
|
||||
streamPlaying[stream] = qtrue;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -1902,13 +1997,12 @@ void S_AL_StreamUpdate( int stream )
|
|||
if(streamSourceHandles[stream] == -1)
|
||||
return;
|
||||
|
||||
// Un-queue any buffers, and delete them
|
||||
// Un-queue any buffers
|
||||
qalGetSourcei( streamSources[stream], AL_BUFFERS_PROCESSED, &numBuffers );
|
||||
while( numBuffers-- )
|
||||
{
|
||||
ALuint buffer;
|
||||
qalSourceUnqueueBuffers(streamSources[stream], 1, &buffer);
|
||||
qalDeleteBuffers(1, &buffer);
|
||||
}
|
||||
|
||||
// Start the streamSource playing if necessary
|
||||
|
@ -1939,8 +2033,6 @@ S_AL_StreamDie
|
|||
static
|
||||
void S_AL_StreamDie( int stream )
|
||||
{
|
||||
int numBuffers;
|
||||
|
||||
if ((stream < 0) || (stream >= MAX_RAW_STREAMS))
|
||||
return;
|
||||
|
||||
|
@ -1950,15 +2042,6 @@ void S_AL_StreamDie( int stream )
|
|||
streamPlaying[stream] = qfalse;
|
||||
qalSourceStop(streamSources[stream]);
|
||||
|
||||
// Un-queue any buffers, and delete them
|
||||
qalGetSourcei( streamSources[stream], AL_BUFFERS_PROCESSED, &numBuffers );
|
||||
while( numBuffers-- )
|
||||
{
|
||||
ALuint buffer;
|
||||
qalSourceUnqueueBuffers(streamSources[stream], 1, &buffer);
|
||||
qalDeleteBuffers(1, &buffer);
|
||||
}
|
||||
|
||||
S_AL_FreeStreamChannel(stream);
|
||||
}
|
||||
|
||||
|
@ -2050,22 +2133,17 @@ S_AL_StopBackgroundTrack
|
|||
static
|
||||
void S_AL_StopBackgroundTrack( void )
|
||||
{
|
||||
int numBuffers;
|
||||
|
||||
if(!musicPlaying)
|
||||
return;
|
||||
|
||||
// Stop playing
|
||||
qalSourceStop(musicSource);
|
||||
|
||||
// Un-queue any buffers, and delete them
|
||||
qalGetSourcei( musicSource, AL_BUFFERS_PROCESSED, &numBuffers );
|
||||
while( numBuffers-- )
|
||||
{
|
||||
ALuint buffer;
|
||||
qalSourceUnqueueBuffers(musicSource, 1, &buffer);
|
||||
qalDeleteBuffers(1, &buffer);
|
||||
}
|
||||
// Detach any buffers
|
||||
qalSourcei(musicSource, AL_BUFFER, 0);
|
||||
|
||||
// Delete the buffers
|
||||
qalDeleteBuffers(NUM_MUSIC_BUFFERS, musicBuffers);
|
||||
|
||||
// Free the musicSource
|
||||
S_AL_MusicSourceFree();
|
||||
|
@ -2198,7 +2276,8 @@ void S_AL_StartBackgroundTrack( const char *intro, const char *loop )
|
|||
}
|
||||
|
||||
// Generate the musicBuffers
|
||||
qalGenBuffers(NUM_MUSIC_BUFFERS, musicBuffers);
|
||||
if (!S_AL_GenBuffers(NUM_MUSIC_BUFFERS, musicBuffers, "music"))
|
||||
return;
|
||||
|
||||
// Queue the musicBuffers up
|
||||
for(i = 0; i < NUM_MUSIC_BUFFERS; i++)
|
||||
|
@ -3155,6 +3234,8 @@ qboolean S_AL_Init( soundInterface_t *si )
|
|||
streamSourceHandles[i] = -1;
|
||||
streamPlaying[i] = qfalse;
|
||||
streamSources[i] = 0;
|
||||
streamNumBuffers[i] = 0;
|
||||
streamBufIndex[i] = 0;
|
||||
}
|
||||
|
||||
// New console variables
|
||||
|
@ -3328,11 +3409,14 @@ qboolean S_AL_Init( soundInterface_t *si )
|
|||
defaultinputdevice = qalcGetString(NULL, ALC_CAPTURE_DEFAULT_DEVICE_SPECIFIER);
|
||||
|
||||
// dump a list of available devices to a cvar for the user to see.
|
||||
while((curlen = strlen(inputdevicelist)))
|
||||
if (inputdevicelist)
|
||||
{
|
||||
Q_strcat(inputdevicenames, sizeof(inputdevicenames), inputdevicelist);
|
||||
Q_strcat(inputdevicenames, sizeof(inputdevicenames), "\n");
|
||||
inputdevicelist += curlen + 1;
|
||||
while((curlen = strlen(inputdevicelist)))
|
||||
{
|
||||
Q_strcat(inputdevicenames, sizeof(inputdevicenames), inputdevicelist);
|
||||
Q_strcat(inputdevicenames, sizeof(inputdevicenames), "\n");
|
||||
inputdevicelist += curlen + 1;
|
||||
}
|
||||
}
|
||||
|
||||
s_alAvailableInputDevices = Cvar_Get("s_alAvailableInputDevices", inputdevicenames, CVAR_ROM | CVAR_NORESTART);
|
||||
|
@ -3341,7 +3425,7 @@ qboolean S_AL_Init( soundInterface_t *si )
|
|||
// !!! FIXME: should probably open the capture device after
|
||||
// !!! FIXME: initializing Speex so we can change to wideband
|
||||
// !!! FIXME: if we like.
|
||||
Com_Printf("OpenAL default capture device is '%s'\n", defaultinputdevice);
|
||||
Com_Printf("OpenAL default capture device is '%s'\n", defaultinputdevice ? defaultinputdevice : "none");
|
||||
alCaptureDevice = qalcCaptureOpenDevice(inputdevice, 8000, AL_FORMAT_MONO16, 4096);
|
||||
if( !alCaptureDevice && inputdevice )
|
||||
{
|
||||
|
|
|
@ -275,9 +275,9 @@ typedef struct qfile_us {
|
|||
typedef struct {
|
||||
qfile_ut handleFiles;
|
||||
qboolean handleSync;
|
||||
int baseOffset;
|
||||
int fileSize;
|
||||
int zipFilePos;
|
||||
int zipFileLen;
|
||||
qboolean zipFile;
|
||||
qboolean streamed;
|
||||
char name[MAX_ZPATH];
|
||||
|
@ -1262,6 +1262,7 @@ long FS_FOpenFileReadDir(const char *filename, searchpath_t *search, fileHandle_
|
|||
// open the file in the zip
|
||||
unzOpenCurrentFile(fsh[*file].handleFiles.file.z);
|
||||
fsh[*file].zipFilePos = pakFile->pos;
|
||||
fsh[*file].zipFileLen = pakFile->len;
|
||||
|
||||
if(fs_debug->integer)
|
||||
{
|
||||
|
@ -1628,29 +1629,60 @@ int FS_Seek( fileHandle_t f, long offset, int origin ) {
|
|||
}
|
||||
|
||||
if (fsh[f].streamed) {
|
||||
int r;
|
||||
fsh[f].streamed = qfalse;
|
||||
FS_Seek( f, offset, origin );
|
||||
r = FS_Seek( f, offset, origin );
|
||||
fsh[f].streamed = qtrue;
|
||||
return r;
|
||||
}
|
||||
|
||||
if (fsh[f].zipFile == qtrue) {
|
||||
//FIXME: this is incomplete and really, really
|
||||
//crappy (but better than what was here before)
|
||||
//FIXME: this is really, really crappy
|
||||
//(but better than what was here before)
|
||||
byte buffer[PK3_SEEK_BUFFER_SIZE];
|
||||
int remainder = offset;
|
||||
int remainder;
|
||||
int currentPosition = FS_FTell( f );
|
||||
|
||||
if( offset < 0 || origin == FS_SEEK_END ) {
|
||||
Com_Error( ERR_FATAL, "Negative offsets and FS_SEEK_END not implemented "
|
||||
"for FS_Seek on pk3 file contents" );
|
||||
return -1;
|
||||
// change negative offsets into FS_SEEK_SET
|
||||
if ( offset < 0 ) {
|
||||
switch( origin ) {
|
||||
case FS_SEEK_END:
|
||||
remainder = fsh[f].zipFileLen + offset;
|
||||
break;
|
||||
|
||||
case FS_SEEK_CUR:
|
||||
remainder = currentPosition + offset;
|
||||
break;
|
||||
|
||||
case FS_SEEK_SET:
|
||||
default:
|
||||
remainder = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
if ( remainder < 0 ) {
|
||||
remainder = 0;
|
||||
}
|
||||
|
||||
origin = FS_SEEK_SET;
|
||||
} else {
|
||||
if ( origin == FS_SEEK_END ) {
|
||||
remainder = fsh[f].zipFileLen - currentPosition + offset;
|
||||
} else {
|
||||
remainder = offset;
|
||||
}
|
||||
}
|
||||
|
||||
switch( origin ) {
|
||||
case FS_SEEK_SET:
|
||||
if ( remainder == currentPosition ) {
|
||||
return offset;
|
||||
}
|
||||
unzSetOffset(fsh[f].handleFiles.file.z, fsh[f].zipFilePos);
|
||||
unzOpenCurrentFile(fsh[f].handleFiles.file.z);
|
||||
//fallthrough
|
||||
|
||||
case FS_SEEK_END:
|
||||
case FS_SEEK_CUR:
|
||||
while( remainder > PK3_SEEK_BUFFER_SIZE ) {
|
||||
FS_Read( buffer, PK3_SEEK_BUFFER_SIZE, f );
|
||||
|
@ -1658,12 +1690,10 @@ int FS_Seek( fileHandle_t f, long offset, int origin ) {
|
|||
}
|
||||
FS_Read( buffer, remainder, f );
|
||||
return offset;
|
||||
break;
|
||||
|
||||
default:
|
||||
Com_Error( ERR_FATAL, "Bad origin in FS_Seek" );
|
||||
return -1;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
FILE *file;
|
||||
|
@ -4012,11 +4042,6 @@ int FS_FOpenFileByMode( const char *qpath, fileHandle_t *f, fsMode_t mode ) {
|
|||
}
|
||||
|
||||
if ( *f ) {
|
||||
if (fsh[*f].zipFile == qtrue) {
|
||||
fsh[*f].baseOffset = unztell(fsh[*f].handleFiles.file.z);
|
||||
} else {
|
||||
fsh[*f].baseOffset = ftell(fsh[*f].handleFiles.file.o);
|
||||
}
|
||||
fsh[*f].fileSize = r;
|
||||
fsh[*f].streamed = qfalse;
|
||||
|
||||
|
|
|
@ -76,8 +76,12 @@ COM_StripExtension
|
|||
void COM_StripExtension( const char *in, char *out, int destsize )
|
||||
{
|
||||
const char *dot = strrchr(in, '.'), *slash;
|
||||
|
||||
if (dot && (!(slash = strrchr(in, '/')) || slash < dot))
|
||||
Q_strncpyz(out, in, (destsize < dot-in+1 ? destsize : dot-in+1));
|
||||
destsize = (destsize < dot-in+1 ? destsize : dot-in+1);
|
||||
|
||||
if ( in == out && destsize > 1 )
|
||||
out[destsize-1] = '\0';
|
||||
else
|
||||
Q_strncpyz(out, in, destsize);
|
||||
}
|
||||
|
|
|
@ -694,7 +694,7 @@ int FS_FOpenFileByMode( const char *qpath, fileHandle_t *f, fsMode_t mode );
|
|||
// opens a file for reading, writing, or appending depending on the value of mode
|
||||
|
||||
int FS_Seek( fileHandle_t f, long offset, int origin );
|
||||
// seek on a file (doesn't work for zip files!!!!!!!!)
|
||||
// seek on a file
|
||||
|
||||
qboolean FS_FilenameCompare( const char *s1, const char *s2 );
|
||||
|
||||
|
@ -1063,19 +1063,6 @@ void * QDECL Sys_LoadGameDll( const char *name, intptr_t (QDECL **entryPoint)(in
|
|||
intptr_t (QDECL *systemcalls)(intptr_t, ...) );
|
||||
void Sys_UnloadDll( void *dllHandle );
|
||||
|
||||
void Sys_UnloadGame( void );
|
||||
void *Sys_GetGameAPI( void *parms );
|
||||
|
||||
void Sys_UnloadCGame( void );
|
||||
void *Sys_GetCGameAPI( void );
|
||||
|
||||
void Sys_UnloadUI( void );
|
||||
void *Sys_GetUIAPI( void );
|
||||
|
||||
//bot libraries
|
||||
void Sys_UnloadBotLib( void );
|
||||
void *Sys_GetBotLibAPI( void *parms );
|
||||
|
||||
char *Sys_GetCurrentUser( void );
|
||||
|
||||
void QDECL Sys_Error( const char *error, ...) __attribute__ ((noreturn, format (printf, 1, 2)));
|
||||
|
|
|
@ -179,94 +179,11 @@ typedef struct {
|
|||
/*
|
||||
==============================================================================
|
||||
|
||||
MD4 file format
|
||||
MDR file format
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
#define MD4_IDENT (('4'<<24)+('P'<<16)+('D'<<8)+'I')
|
||||
#define MD4_VERSION 1
|
||||
#define MD4_MAX_BONES 128
|
||||
|
||||
typedef struct {
|
||||
int boneIndex; // these are indexes into the boneReferences,
|
||||
float boneWeight; // not the global per-frame bone list
|
||||
vec3_t offset;
|
||||
} md4Weight_t;
|
||||
|
||||
typedef struct {
|
||||
vec3_t normal;
|
||||
vec2_t texCoords;
|
||||
int numWeights;
|
||||
md4Weight_t weights[1]; // variable sized
|
||||
} md4Vertex_t;
|
||||
|
||||
typedef struct {
|
||||
int indexes[3];
|
||||
} md4Triangle_t;
|
||||
|
||||
typedef struct {
|
||||
int ident;
|
||||
|
||||
char name[MAX_QPATH]; // polyset name
|
||||
char shader[MAX_QPATH];
|
||||
int shaderIndex; // for in-game use
|
||||
|
||||
int ofsHeader; // this will be a negative number
|
||||
|
||||
int numVerts;
|
||||
int ofsVerts;
|
||||
|
||||
int numTriangles;
|
||||
int ofsTriangles;
|
||||
|
||||
// Bone references are a set of ints representing all the bones
|
||||
// present in any vertex weights for this surface. This is
|
||||
// needed because a model may have surfaces that need to be
|
||||
// drawn at different sort times, and we don't want to have
|
||||
// to re-interpolate all the bones for each surface.
|
||||
int numBoneReferences;
|
||||
int ofsBoneReferences;
|
||||
|
||||
int ofsEnd; // next surface follows
|
||||
} md4Surface_t;
|
||||
|
||||
typedef struct {
|
||||
float matrix[3][4];
|
||||
} md4Bone_t;
|
||||
|
||||
typedef struct {
|
||||
vec3_t bounds[2]; // bounds of all surfaces of all LOD's for this frame
|
||||
vec3_t localOrigin; // midpoint of bounds, used for sphere cull
|
||||
float radius; // dist from localOrigin to corner
|
||||
md4Bone_t bones[1]; // [numBones]
|
||||
} md4Frame_t;
|
||||
|
||||
typedef struct {
|
||||
int numSurfaces;
|
||||
int ofsSurfaces; // first surface, others follow
|
||||
int ofsEnd; // next lod follows
|
||||
} md4LOD_t;
|
||||
|
||||
typedef struct {
|
||||
int ident;
|
||||
int version;
|
||||
|
||||
char name[MAX_QPATH]; // model name
|
||||
|
||||
// frames and bones are shared by all levels of detail
|
||||
int numFrames;
|
||||
int numBones;
|
||||
int ofsBoneNames; // char name[ MAX_QPATH ]
|
||||
int ofsFrames; // md4Frame_t[numFrames]
|
||||
|
||||
// each level of detail has completely separate sets of surfaces
|
||||
int numLODs;
|
||||
int ofsLODs;
|
||||
|
||||
int ofsEnd; // end of file
|
||||
} md4Header_t;
|
||||
|
||||
/*
|
||||
* Here are the definitions for Ravensoft's model format of md4. Raven stores their
|
||||
* playermodels in .mdr files, in some games, which are pretty much like the md4
|
||||
|
|
|
@ -2274,7 +2274,7 @@ void R_LoadPNG(const char *name, byte **pic, int *width, int *height)
|
|||
{
|
||||
case PNG_ColourType_Grey :
|
||||
{
|
||||
if(!ChunkHeaderLength == 2)
|
||||
if(ChunkHeaderLength != 2)
|
||||
{
|
||||
CloseBufferedFile(ThePNG);
|
||||
|
||||
|
@ -2296,7 +2296,7 @@ void R_LoadPNG(const char *name, byte **pic, int *width, int *height)
|
|||
|
||||
case PNG_ColourType_True :
|
||||
{
|
||||
if(!ChunkHeaderLength == 6)
|
||||
if(ChunkHeaderLength != 6)
|
||||
{
|
||||
CloseBufferedFile(ThePNG);
|
||||
|
||||
|
|
|
@ -33,140 +33,6 @@ frame.
|
|||
|
||||
*/
|
||||
|
||||
/*
|
||||
==============
|
||||
R_AddAnimSurfaces
|
||||
==============
|
||||
*/
|
||||
void R_AddAnimSurfaces( trRefEntity_t *ent ) {
|
||||
md4Header_t *header;
|
||||
md4Surface_t *surface;
|
||||
md4LOD_t *lod;
|
||||
shader_t *shader;
|
||||
int i;
|
||||
|
||||
header = (md4Header_t *) tr.currentModel->modelData;
|
||||
lod = (md4LOD_t *)( (byte *)header + header->ofsLODs );
|
||||
|
||||
surface = (md4Surface_t *)( (byte *)lod + lod->ofsSurfaces );
|
||||
for ( i = 0 ; i < lod->numSurfaces ; i++ ) {
|
||||
shader = R_GetShaderByHandle( surface->shaderIndex );
|
||||
R_AddDrawSurf( (void *)surface, shader, 0 /*fogNum*/, qfalse );
|
||||
surface = (md4Surface_t *)( (byte *)surface + surface->ofsEnd );
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
==============
|
||||
RB_SurfaceAnim
|
||||
==============
|
||||
*/
|
||||
void RB_SurfaceAnim( md4Surface_t *surface ) {
|
||||
int i, j, k;
|
||||
float frontlerp, backlerp;
|
||||
int *triangles;
|
||||
int indexes;
|
||||
int baseIndex, baseVertex;
|
||||
int numVerts;
|
||||
md4Vertex_t *v;
|
||||
md4Bone_t bones[MD4_MAX_BONES];
|
||||
md4Bone_t *bonePtr, *bone;
|
||||
md4Header_t *header;
|
||||
md4Frame_t *frame;
|
||||
md4Frame_t *oldFrame;
|
||||
int frameSize;
|
||||
|
||||
|
||||
if ( backEnd.currentEntity->e.oldframe == backEnd.currentEntity->e.frame ) {
|
||||
backlerp = 0;
|
||||
frontlerp = 1;
|
||||
} else {
|
||||
backlerp = backEnd.currentEntity->e.backlerp;
|
||||
frontlerp = 1.0f - backlerp;
|
||||
}
|
||||
header = (md4Header_t *)((byte *)surface + surface->ofsHeader);
|
||||
|
||||
frameSize = (size_t)( &((md4Frame_t *)0)->bones[ header->numBones ] );
|
||||
|
||||
frame = (md4Frame_t *)((byte *)header + header->ofsFrames +
|
||||
backEnd.currentEntity->e.frame * frameSize );
|
||||
oldFrame = (md4Frame_t *)((byte *)header + header->ofsFrames +
|
||||
backEnd.currentEntity->e.oldframe * frameSize );
|
||||
|
||||
RB_CheckOverflow( surface->numVerts, surface->numTriangles * 3 );
|
||||
|
||||
triangles = (int *) ((byte *)surface + surface->ofsTriangles);
|
||||
indexes = surface->numTriangles * 3;
|
||||
baseIndex = tess.numIndexes;
|
||||
baseVertex = tess.numVertexes;
|
||||
for (j = 0 ; j < indexes ; j++) {
|
||||
tess.indexes[baseIndex + j] = baseIndex + triangles[j];
|
||||
}
|
||||
tess.numIndexes += indexes;
|
||||
|
||||
//
|
||||
// lerp all the needed bones
|
||||
//
|
||||
if ( !backlerp ) {
|
||||
// no lerping needed
|
||||
bonePtr = frame->bones;
|
||||
} else {
|
||||
bonePtr = bones;
|
||||
for ( i = 0 ; i < header->numBones*12 ; i++ ) {
|
||||
((float *)bonePtr)[i] = frontlerp * ((float *)frame->bones)[i]
|
||||
+ backlerp * ((float *)oldFrame->bones)[i];
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// deform the vertexes by the lerped bones
|
||||
//
|
||||
numVerts = surface->numVerts;
|
||||
// FIXME
|
||||
// This makes TFC's skeletons work. Shouldn't be necessary anymore, but left
|
||||
// in for reference.
|
||||
//v = (md4Vertex_t *) ((byte *)surface + surface->ofsVerts + 12);
|
||||
v = (md4Vertex_t *) ((byte *)surface + surface->ofsVerts);
|
||||
for ( j = 0; j < numVerts; j++ ) {
|
||||
vec3_t tempVert, tempNormal;
|
||||
md4Weight_t *w;
|
||||
|
||||
VectorClear( tempVert );
|
||||
VectorClear( tempNormal );
|
||||
w = v->weights;
|
||||
for ( k = 0 ; k < v->numWeights ; k++, w++ ) {
|
||||
bone = bonePtr + w->boneIndex;
|
||||
|
||||
tempVert[0] += w->boneWeight * ( DotProduct( bone->matrix[0], w->offset ) + bone->matrix[0][3] );
|
||||
tempVert[1] += w->boneWeight * ( DotProduct( bone->matrix[1], w->offset ) + bone->matrix[1][3] );
|
||||
tempVert[2] += w->boneWeight * ( DotProduct( bone->matrix[2], w->offset ) + bone->matrix[2][3] );
|
||||
|
||||
tempNormal[0] += w->boneWeight * DotProduct( bone->matrix[0], v->normal );
|
||||
tempNormal[1] += w->boneWeight * DotProduct( bone->matrix[1], v->normal );
|
||||
tempNormal[2] += w->boneWeight * DotProduct( bone->matrix[2], v->normal );
|
||||
}
|
||||
|
||||
tess.xyz[baseVertex + j][0] = tempVert[0];
|
||||
tess.xyz[baseVertex + j][1] = tempVert[1];
|
||||
tess.xyz[baseVertex + j][2] = tempVert[2];
|
||||
|
||||
tess.normal[baseVertex + j][0] = tempNormal[0];
|
||||
tess.normal[baseVertex + j][1] = tempNormal[1];
|
||||
tess.normal[baseVertex + j][2] = tempNormal[2];
|
||||
|
||||
tess.texCoords[baseVertex + j][0][0] = v->texCoords[0];
|
||||
tess.texCoords[baseVertex + j][0][1] = v->texCoords[1];
|
||||
|
||||
// FIXME
|
||||
// This makes TFC's skeletons work. Shouldn't be necessary anymore, but left
|
||||
// in for reference.
|
||||
//v = (md4Vertex_t *)( ( byte * )&v->weights[v->numWeights] + 12 );
|
||||
v = (md4Vertex_t *)&v->weights[v->numWeights];
|
||||
}
|
||||
|
||||
tess.numVertexes += surface->numVerts;
|
||||
}
|
||||
|
||||
|
||||
// copied and adapted from tr_mesh.c
|
||||
|
||||
|
@ -195,7 +61,7 @@ static int R_MDRCullModel( mdrHeader_t *header, trRefEntity_t *ent ) {
|
|||
switch ( R_CullLocalPointAndRadius( newFrame->localOrigin, newFrame->radius ) )
|
||||
{
|
||||
// Ummm... yeah yeah I know we don't really have an md3 here.. but we pretend
|
||||
// we do. After all, the purpose of md4s are not that different, are they?
|
||||
// we do. After all, the purpose of mdrs are not that different, are they?
|
||||
|
||||
case CULL_OUT:
|
||||
tr.pc.c_sphere_cull_md3_out++;
|
||||
|
@ -442,7 +308,7 @@ void R_MDRAddAnimSurfaces( trRefEntity_t *ent ) {
|
|||
RB_MDRSurfaceAnim
|
||||
==============
|
||||
*/
|
||||
void RB_MDRSurfaceAnim( md4Surface_t *surface )
|
||||
void RB_MDRSurfaceAnim( mdrSurface_t *surface )
|
||||
{
|
||||
int i, j, k;
|
||||
float frontlerp, backlerp;
|
||||
|
@ -454,7 +320,7 @@ void RB_MDRSurfaceAnim( md4Surface_t *surface )
|
|||
mdrHeader_t *header;
|
||||
mdrFrame_t *frame;
|
||||
mdrFrame_t *oldFrame;
|
||||
mdrBone_t bones[MD4_MAX_BONES], *bonePtr, *bone;
|
||||
mdrBone_t bones[MDR_MAX_BONES], *bonePtr, *bone;
|
||||
|
||||
int frameSize;
|
||||
|
||||
|
|
|
@ -737,6 +737,10 @@ void RE_StretchRaw (int x, int y, int w, int h, int cols, int rows, const byte *
|
|||
}
|
||||
R_IssuePendingRenderCommands();
|
||||
|
||||
if ( tess.numIndexes ) {
|
||||
RB_EndSurface();
|
||||
}
|
||||
|
||||
// we definately want to sync every frame for the cinematics
|
||||
qglFinish();
|
||||
|
||||
|
|
|
@ -86,6 +86,19 @@ flare_t *r_activeFlares, *r_inactiveFlares;
|
|||
|
||||
int flareCoeff;
|
||||
|
||||
/*
|
||||
==================
|
||||
R_SetFlareCoeff
|
||||
==================
|
||||
*/
|
||||
static void R_SetFlareCoeff( void ) {
|
||||
|
||||
if(r_flareCoeff->value == 0.0f)
|
||||
flareCoeff = atof(FLARE_STDCOEFF);
|
||||
else
|
||||
flareCoeff = r_flareCoeff->value;
|
||||
}
|
||||
|
||||
/*
|
||||
==================
|
||||
R_ClearFlares
|
||||
|
@ -102,6 +115,8 @@ void R_ClearFlares( void ) {
|
|||
r_flareStructs[i].next = r_inactiveFlares;
|
||||
r_inactiveFlares = &r_flareStructs[i];
|
||||
}
|
||||
|
||||
R_SetFlareCoeff();
|
||||
}
|
||||
|
||||
|
||||
|
@ -450,11 +465,7 @@ void RB_RenderFlares (void) {
|
|||
|
||||
if(r_flareCoeff->modified)
|
||||
{
|
||||
if(r_flareCoeff->value == 0.0f)
|
||||
flareCoeff = atof(FLARE_STDCOEFF);
|
||||
else
|
||||
flareCoeff = r_flareCoeff->value;
|
||||
|
||||
R_SetFlareCoeff();
|
||||
r_flareCoeff->modified = qfalse;
|
||||
}
|
||||
|
||||
|
|
|
@ -900,6 +900,8 @@ image_t *R_CreateImage( const char *name, byte *pic, int width, int height,
|
|||
qglTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, glWrapClampMode );
|
||||
qglTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, glWrapClampMode );
|
||||
|
||||
// FIXME: this stops fog from setting border color?
|
||||
glState.currenttextures[glState.currenttmu] = 0;
|
||||
qglBindTexture( GL_TEXTURE_2D, 0 );
|
||||
|
||||
if ( image->TMU == 1 ) {
|
||||
|
|
|
@ -872,16 +872,6 @@ void GL_SetDefaultState( void )
|
|||
qglEnable( GL_SCISSOR_TEST );
|
||||
qglDisable( GL_CULL_FACE );
|
||||
qglDisable( GL_BLEND );
|
||||
|
||||
qglColorMask( GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE );
|
||||
qglClearColor( 0.0f, 0.0f, 0.0f, 1.0f );
|
||||
qglClearDepth( 1.0 );
|
||||
|
||||
qglDrawBuffer( GL_FRONT );
|
||||
qglClear( GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_ACCUM_BUFFER_BIT|GL_STENCIL_BUFFER_BIT );
|
||||
|
||||
qglDrawBuffer( GL_BACK );
|
||||
qglClear( GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_ACCUM_BUFFER_BIT|GL_STENCIL_BUFFER_BIT );
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -1039,7 +1029,7 @@ void R_Register( void )
|
|||
r_ignorehwgamma = ri.Cvar_Get( "r_ignorehwgamma", "0", CVAR_ARCHIVE | CVAR_LATCH);
|
||||
r_mode = ri.Cvar_Get( "r_mode", "3", CVAR_ARCHIVE | CVAR_LATCH );
|
||||
r_fullscreen = ri.Cvar_Get( "r_fullscreen", "1", CVAR_ARCHIVE );
|
||||
r_noborder = ri.Cvar_Get("r_noborder", "0", CVAR_ARCHIVE);
|
||||
r_noborder = ri.Cvar_Get("r_noborder", "0", CVAR_ARCHIVE | CVAR_LATCH);
|
||||
r_customwidth = ri.Cvar_Get( "r_customwidth", "1600", CVAR_ARCHIVE | CVAR_LATCH );
|
||||
r_customheight = ri.Cvar_Get( "r_customheight", "1024", CVAR_ARCHIVE | CVAR_LATCH );
|
||||
r_customPixelAspect = ri.Cvar_Get( "r_customPixelAspect", "1", CVAR_ARCHIVE | CVAR_LATCH );
|
||||
|
|
|
@ -41,10 +41,6 @@ typedef unsigned int glIndex_t;
|
|||
#define SHADERNUM_BITS 14
|
||||
#define MAX_SHADERS (1<<SHADERNUM_BITS)
|
||||
|
||||
//#define MAX_SHADER_STATES 2048
|
||||
#define MAX_STATES_PER_SHADER 32
|
||||
#define MAX_STATE_NAME 32
|
||||
|
||||
|
||||
|
||||
typedef struct dlight_s {
|
||||
|
@ -266,7 +262,6 @@ typedef struct {
|
|||
|
||||
int videoMapHandle;
|
||||
qboolean isLightmap;
|
||||
qboolean vertexLightmap;
|
||||
qboolean isVideoMap;
|
||||
} textureBundle_t;
|
||||
|
||||
|
@ -370,27 +365,11 @@ typedef struct shader_s {
|
|||
float clampTime; // time this shader is clamped to
|
||||
float timeOffset; // current time offset for this shader
|
||||
|
||||
int numStates; // if non-zero this is a state shader
|
||||
struct shader_s *currentShader; // current state if this is a state shader
|
||||
struct shader_s *parentShader; // current state if this is a state shader
|
||||
int currentState; // current state index for cycle purposes
|
||||
long expireTime; // time in milliseconds this expires
|
||||
|
||||
struct shader_s *remappedShader; // current shader this one is remapped too
|
||||
|
||||
int shaderStates[MAX_STATES_PER_SHADER]; // index to valid shader states
|
||||
|
||||
struct shader_s *next;
|
||||
} shader_t;
|
||||
|
||||
typedef struct shaderState_s {
|
||||
char shaderName[MAX_QPATH]; // name of shader this state belongs to
|
||||
char name[MAX_STATE_NAME]; // name of this state
|
||||
char stateShader[MAX_QPATH]; // shader this name invokes
|
||||
int cycleTime; // time this cycle lasts, <= 0 is forever
|
||||
shader_t *shader;
|
||||
} shaderState_t;
|
||||
|
||||
|
||||
// trRefdef_t holds everything that comes in refdef_t,
|
||||
// as well as the locally generated scene information
|
||||
|
@ -494,7 +473,6 @@ typedef enum {
|
|||
SF_TRIANGLES,
|
||||
SF_POLY,
|
||||
SF_MD3,
|
||||
SF_MD4,
|
||||
SF_MDR,
|
||||
SF_IQM,
|
||||
SF_FLARE,
|
||||
|
@ -610,6 +588,7 @@ typedef struct {
|
|||
int num_frames;
|
||||
int num_surfaces;
|
||||
int num_joints;
|
||||
int num_poses;
|
||||
struct srfIQModel_s *surfaces;
|
||||
|
||||
float *positions;
|
||||
|
@ -617,10 +596,18 @@ typedef struct {
|
|||
float *normals;
|
||||
float *tangents;
|
||||
byte *blendIndexes;
|
||||
byte *blendWeights;
|
||||
union {
|
||||
float *f;
|
||||
byte *b;
|
||||
} blendWeights;
|
||||
byte *colors;
|
||||
int *triangles;
|
||||
|
||||
// depending upon the exporter, blend indices and weights might be int/float
|
||||
// as opposed to the recommended byte/byte, for example Noesis exports
|
||||
// int/float whereas the official IQM tool exports byte/byte
|
||||
byte blendWeightsType; // IQM_UBYTE or IQM_FLOAT
|
||||
|
||||
int *jointParents;
|
||||
float *jointMats;
|
||||
float *poseMats;
|
||||
|
@ -744,7 +731,6 @@ typedef enum {
|
|||
MOD_BAD,
|
||||
MOD_BRUSH,
|
||||
MOD_MESH,
|
||||
MOD_MD4,
|
||||
MOD_MDR,
|
||||
MOD_IQM
|
||||
} modtype_t;
|
||||
|
@ -757,7 +743,7 @@ typedef struct model_s {
|
|||
int dataSize; // just for listing purposes
|
||||
bmodel_t *bmodel; // only if type == MOD_BRUSH
|
||||
md3Header_t *md3[MD3_MAX_LODS]; // only if type == MOD_MESH
|
||||
void *modelData; // only if type == (MOD_MD4 | MOD_MDR | MOD_IQM)
|
||||
void *modelData; // only if type == (MOD_MDR | MOD_IQM)
|
||||
|
||||
int numLods;
|
||||
} model_t;
|
||||
|
@ -1401,11 +1387,8 @@ ANIMATED MODELS
|
|||
=============================================================
|
||||
*/
|
||||
|
||||
// void R_MakeAnimModel( model_t *model ); haven't seen this one really, so not needed I guess.
|
||||
void R_AddAnimSurfaces( trRefEntity_t *ent );
|
||||
void RB_SurfaceAnim( md4Surface_t *surfType );
|
||||
void R_MDRAddAnimSurfaces( trRefEntity_t *ent );
|
||||
void RB_MDRSurfaceAnim( md4Surface_t *surface );
|
||||
void RB_MDRSurfaceAnim( mdrSurface_t *surface );
|
||||
qboolean R_LoadIQM (model_t *mod, void *buffer, int filesize, const char *name );
|
||||
void R_AddIQMSurfaces( trRefEntity_t *ent );
|
||||
void RB_IQMSurfaceAnim( surfaceType_t *surface );
|
||||
|
|
|
@ -1242,9 +1242,6 @@ void R_AddEntitySurfaces (void) {
|
|||
case MOD_MESH:
|
||||
R_AddMD3Surfaces( ent );
|
||||
break;
|
||||
case MOD_MD4:
|
||||
R_AddAnimSurfaces( ent );
|
||||
break;
|
||||
case MOD_MDR:
|
||||
R_MDRAddAnimSurfaces( ent );
|
||||
break;
|
||||
|
|
|
@ -26,7 +26,6 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|||
#define LL(x) x=LittleLong(x)
|
||||
|
||||
static qboolean R_LoadMD3(model_t *mod, int lod, void *buffer, const char *name );
|
||||
static qboolean R_LoadMD4(model_t *mod, void *buffer, const char *name );
|
||||
static qboolean R_LoadMDR(model_t *mod, void *buffer, int filesize, const char *name );
|
||||
|
||||
/*
|
||||
|
@ -72,15 +71,10 @@ qhandle_t R_RegisterMD3(const char *name, model_t *mod)
|
|||
continue;
|
||||
|
||||
ident = LittleLong(* (unsigned *) buf.u);
|
||||
if (ident == MD4_IDENT)
|
||||
loaded = R_LoadMD4(mod, buf.u, name);
|
||||
if (ident == MD3_IDENT)
|
||||
loaded = R_LoadMD3(mod, lod, buf.u, name);
|
||||
else
|
||||
{
|
||||
if (ident == MD3_IDENT)
|
||||
loaded = R_LoadMD3(mod, lod, buf.u, name);
|
||||
else
|
||||
ri.Printf(PRINT_WARNING,"R_RegisterMD3: unknown fileid for %s\n", name);
|
||||
}
|
||||
ri.Printf(PRINT_WARNING,"R_RegisterMD3: unknown fileid for %s\n", name);
|
||||
|
||||
ri.FS_FreeFile(buf.v);
|
||||
|
||||
|
@ -200,7 +194,6 @@ static modelExtToLoaderMap_t modelLoaders[ ] =
|
|||
{
|
||||
{ "iqm", R_RegisterIQM },
|
||||
{ "mdr", R_RegisterMDR },
|
||||
{ "md4", R_RegisterMD3 },
|
||||
{ "md3", R_RegisterMD3 }
|
||||
};
|
||||
|
||||
|
@ -576,7 +569,7 @@ static qboolean R_LoadMDR( model_t *mod, void *buffer, int filesize, const char
|
|||
LL(pinmodel->ofsFrames);
|
||||
|
||||
// This is a model that uses some type of compressed Bones. We don't want to uncompress every bone for each rendered frame
|
||||
// over and over again, we'll uncompress it in this function already, so we must adjust the size of the target md4.
|
||||
// over and over again, we'll uncompress it in this function already, so we must adjust the size of the target mdr.
|
||||
if(pinmodel->ofsFrames < 0)
|
||||
{
|
||||
// mdrFrame_t is larger than mdrCompFrame_t:
|
||||
|
@ -873,162 +866,6 @@ static qboolean R_LoadMDR( model_t *mod, void *buffer, int filesize, const char
|
|||
return qtrue;
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
R_LoadMD4
|
||||
=================
|
||||
*/
|
||||
|
||||
static qboolean R_LoadMD4( model_t *mod, void *buffer, const char *mod_name ) {
|
||||
int i, j, k, lodindex;
|
||||
md4Header_t *pinmodel, *md4;
|
||||
md4Frame_t *frame;
|
||||
md4LOD_t *lod;
|
||||
md4Surface_t *surf;
|
||||
md4Triangle_t *tri;
|
||||
md4Vertex_t *v;
|
||||
int version;
|
||||
int size;
|
||||
shader_t *sh;
|
||||
int frameSize;
|
||||
|
||||
pinmodel = (md4Header_t *)buffer;
|
||||
|
||||
version = LittleLong (pinmodel->version);
|
||||
if (version != MD4_VERSION) {
|
||||
ri.Printf( PRINT_WARNING, "R_LoadMD4: %s has wrong version (%i should be %i)\n",
|
||||
mod_name, version, MD4_VERSION);
|
||||
return qfalse;
|
||||
}
|
||||
|
||||
mod->type = MOD_MD4;
|
||||
size = LittleLong(pinmodel->ofsEnd);
|
||||
mod->dataSize += size;
|
||||
mod->modelData = md4 = ri.Hunk_Alloc( size, h_low );
|
||||
|
||||
Com_Memcpy(md4, buffer, size);
|
||||
|
||||
LL(md4->ident);
|
||||
LL(md4->version);
|
||||
LL(md4->numFrames);
|
||||
LL(md4->numBones);
|
||||
LL(md4->numLODs);
|
||||
LL(md4->ofsFrames);
|
||||
LL(md4->ofsLODs);
|
||||
md4->ofsEnd = size;
|
||||
|
||||
if ( md4->numFrames < 1 ) {
|
||||
ri.Printf( PRINT_WARNING, "R_LoadMD4: %s has no frames\n", mod_name );
|
||||
return qfalse;
|
||||
}
|
||||
|
||||
// we don't need to swap tags in the renderer, they aren't used
|
||||
|
||||
// swap all the frames
|
||||
frameSize = (size_t)( &((md4Frame_t *)0)->bones[ md4->numBones ] );
|
||||
for ( i = 0 ; i < md4->numFrames ; i++) {
|
||||
frame = (md4Frame_t *) ( (byte *)md4 + md4->ofsFrames + i * frameSize );
|
||||
frame->radius = LittleFloat( frame->radius );
|
||||
for ( j = 0 ; j < 3 ; j++ ) {
|
||||
frame->bounds[0][j] = LittleFloat( frame->bounds[0][j] );
|
||||
frame->bounds[1][j] = LittleFloat( frame->bounds[1][j] );
|
||||
frame->localOrigin[j] = LittleFloat( frame->localOrigin[j] );
|
||||
}
|
||||
for ( j = 0 ; j < md4->numBones * sizeof( md4Bone_t ) / 4 ; j++ ) {
|
||||
((float *)frame->bones)[j] = LittleFloat( ((float *)frame->bones)[j] );
|
||||
}
|
||||
}
|
||||
|
||||
// swap all the LOD's
|
||||
lod = (md4LOD_t *) ( (byte *)md4 + md4->ofsLODs );
|
||||
for ( lodindex = 0 ; lodindex < md4->numLODs ; lodindex++ ) {
|
||||
|
||||
// swap all the surfaces
|
||||
surf = (md4Surface_t *) ( (byte *)lod + lod->ofsSurfaces );
|
||||
for ( i = 0 ; i < lod->numSurfaces ; i++) {
|
||||
LL(surf->ident);
|
||||
LL(surf->numTriangles);
|
||||
LL(surf->ofsTriangles);
|
||||
LL(surf->numVerts);
|
||||
LL(surf->ofsVerts);
|
||||
LL(surf->ofsEnd);
|
||||
|
||||
if ( surf->numVerts >= SHADER_MAX_VERTEXES ) {
|
||||
ri.Printf(PRINT_WARNING, "R_LoadMD4: %s has more than %i verts on %s (%i).\n",
|
||||
mod_name, SHADER_MAX_VERTEXES - 1, surf->name[0] ? surf->name : "a surface",
|
||||
surf->numVerts );
|
||||
return qfalse;
|
||||
}
|
||||
if ( surf->numTriangles*3 >= SHADER_MAX_INDEXES ) {
|
||||
ri.Printf(PRINT_WARNING, "R_LoadMD4: %s has more than %i triangles on %s (%i).\n",
|
||||
mod_name, ( SHADER_MAX_INDEXES / 3 ) - 1, surf->name[0] ? surf->name : "a surface",
|
||||
surf->numTriangles );
|
||||
return qfalse;
|
||||
}
|
||||
|
||||
// change to surface identifier
|
||||
surf->ident = SF_MD4;
|
||||
|
||||
// lowercase the surface name so skin compares are faster
|
||||
Q_strlwr( surf->name );
|
||||
|
||||
// register the shaders
|
||||
sh = R_FindShader( surf->shader, LIGHTMAP_NONE, qtrue );
|
||||
if ( sh->defaultShader ) {
|
||||
surf->shaderIndex = 0;
|
||||
} else {
|
||||
surf->shaderIndex = sh->index;
|
||||
}
|
||||
|
||||
// swap all the triangles
|
||||
tri = (md4Triangle_t *) ( (byte *)surf + surf->ofsTriangles );
|
||||
for ( j = 0 ; j < surf->numTriangles ; j++, tri++ ) {
|
||||
LL(tri->indexes[0]);
|
||||
LL(tri->indexes[1]);
|
||||
LL(tri->indexes[2]);
|
||||
}
|
||||
|
||||
// swap all the vertexes
|
||||
// FIXME
|
||||
// This makes TFC's skeletons work. Shouldn't be necessary anymore, but left
|
||||
// in for reference.
|
||||
//v = (md4Vertex_t *) ( (byte *)surf + surf->ofsVerts + 12);
|
||||
v = (md4Vertex_t *) ( (byte *)surf + surf->ofsVerts);
|
||||
for ( j = 0 ; j < surf->numVerts ; j++ ) {
|
||||
v->normal[0] = LittleFloat( v->normal[0] );
|
||||
v->normal[1] = LittleFloat( v->normal[1] );
|
||||
v->normal[2] = LittleFloat( v->normal[2] );
|
||||
|
||||
v->texCoords[0] = LittleFloat( v->texCoords[0] );
|
||||
v->texCoords[1] = LittleFloat( v->texCoords[1] );
|
||||
|
||||
v->numWeights = LittleLong( v->numWeights );
|
||||
|
||||
for ( k = 0 ; k < v->numWeights ; k++ ) {
|
||||
v->weights[k].boneIndex = LittleLong( v->weights[k].boneIndex );
|
||||
v->weights[k].boneWeight = LittleFloat( v->weights[k].boneWeight );
|
||||
v->weights[k].offset[0] = LittleFloat( v->weights[k].offset[0] );
|
||||
v->weights[k].offset[1] = LittleFloat( v->weights[k].offset[1] );
|
||||
v->weights[k].offset[2] = LittleFloat( v->weights[k].offset[2] );
|
||||
}
|
||||
// FIXME
|
||||
// This makes TFC's skeletons work. Shouldn't be necessary anymore, but left
|
||||
// in for reference.
|
||||
//v = (md4Vertex_t *)( ( byte * )&v->weights[v->numWeights] + 12 );
|
||||
v = (md4Vertex_t *)( ( byte * )&v->weights[v->numWeights]);
|
||||
}
|
||||
|
||||
// find the next surface
|
||||
surf = (md4Surface_t *)( (byte *)surf + surf->ofsEnd );
|
||||
}
|
||||
|
||||
// find the next LOD
|
||||
lod = (md4LOD_t *)( (byte *)lod + lod->ofsEnd );
|
||||
}
|
||||
|
||||
return qtrue;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//=============================================================================
|
||||
|
@ -1049,11 +886,6 @@ void RE_BeginRegistration( glconfig_t *glconfigOut ) {
|
|||
RE_ClearScene();
|
||||
|
||||
tr.registered = qtrue;
|
||||
|
||||
// NOTE: this sucks, for some reason the first stretch pic is never drawn
|
||||
// without this we'd see a white flash on a level load because the very
|
||||
// first time the level shot would not be drawn
|
||||
// RE_StretchPic(0, 0, 0, 0, 0, 0, 1, 1, 0);
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
|
@ -1265,17 +1097,6 @@ void R_ModelBounds( qhandle_t handle, vec3_t mins, vec3_t maxs ) {
|
|||
VectorCopy( frame->bounds[0], mins );
|
||||
VectorCopy( frame->bounds[1], maxs );
|
||||
|
||||
return;
|
||||
} else if (model->type == MOD_MD4) {
|
||||
md4Header_t *header;
|
||||
md4Frame_t *frame;
|
||||
|
||||
header = (md4Header_t *)model->modelData;
|
||||
frame = (md4Frame_t *) ((byte *)header + header->ofsFrames);
|
||||
|
||||
VectorCopy( frame->bounds[0], mins );
|
||||
VectorCopy( frame->bounds[1], maxs );
|
||||
|
||||
return;
|
||||
} else if (model->type == MOD_MDR) {
|
||||
mdrHeader_t *header;
|
||||
|
|
|
@ -25,6 +25,13 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|||
|
||||
#define LL(x) x=LittleLong(x)
|
||||
|
||||
// 3x4 identity matrix
|
||||
static float identityMatrix[12] = {
|
||||
1, 0, 0, 0,
|
||||
0, 1, 0, 0,
|
||||
0, 0, 1, 0
|
||||
};
|
||||
|
||||
static qboolean IQM_CheckRange( iqmHeader_t *header, int offset,
|
||||
int count,int size ) {
|
||||
// return true if the range specified by offset, count and size
|
||||
|
@ -143,6 +150,7 @@ qboolean R_LoadIQM( model_t *mod, void *buffer, int filesize, const char *mod_na
|
|||
iqmData_t *iqmData;
|
||||
srfIQModel_t *surface;
|
||||
char meshName[MAX_QPATH];
|
||||
byte blendIndexesType, blendWeightsType;
|
||||
|
||||
if( filesize < sizeof(iqmHeader_t) ) {
|
||||
return qfalse;
|
||||
|
@ -198,6 +206,8 @@ qboolean R_LoadIQM( model_t *mod, void *buffer, int filesize, const char *mod_na
|
|||
return qfalse;
|
||||
}
|
||||
|
||||
blendIndexesType = blendWeightsType = IQM_UBYTE;
|
||||
|
||||
// check and swap vertex arrays
|
||||
if( IQM_CheckRange( header, header->ofs_vertexarrays,
|
||||
header->num_vertexarrays,
|
||||
|
@ -264,11 +274,20 @@ qboolean R_LoadIQM( model_t *mod, void *buffer, int filesize, const char *mod_na
|
|||
}
|
||||
break;
|
||||
case IQM_BLENDINDEXES:
|
||||
if( (vertexarray->format != IQM_INT &&
|
||||
vertexarray->format != IQM_UBYTE) ||
|
||||
vertexarray->size != 4 ) {
|
||||
return qfalse;
|
||||
}
|
||||
blendIndexesType = vertexarray->format;
|
||||
break;
|
||||
case IQM_BLENDWEIGHTS:
|
||||
if( vertexarray->format != IQM_UBYTE ||
|
||||
if( (vertexarray->format != IQM_FLOAT &&
|
||||
vertexarray->format != IQM_UBYTE) ||
|
||||
vertexarray->size != 4 ) {
|
||||
return qfalse;
|
||||
}
|
||||
blendWeightsType = vertexarray->format;
|
||||
break;
|
||||
case IQM_COLOR:
|
||||
if( vertexarray->format != IQM_UBYTE ||
|
||||
|
@ -343,7 +362,9 @@ qboolean R_LoadIQM( model_t *mod, void *buffer, int filesize, const char *mod_na
|
|||
}
|
||||
}
|
||||
|
||||
if( header->num_poses != header->num_joints ) {
|
||||
if( header->num_poses != header->num_joints && header->num_poses != 0 ) {
|
||||
ri.Printf(PRINT_WARNING, "R_LoadIQM: %s has %d poses and %d joints, must have the same number or 0 poses\n",
|
||||
mod_name, header->num_poses, header->num_joints );
|
||||
return qfalse;
|
||||
}
|
||||
|
||||
|
@ -379,7 +400,10 @@ qboolean R_LoadIQM( model_t *mod, void *buffer, int filesize, const char *mod_na
|
|||
joint_names += strlen( (char *)header + header->ofs_text +
|
||||
joint->name ) + 1;
|
||||
}
|
||||
}
|
||||
|
||||
if ( header->num_poses )
|
||||
{
|
||||
// check and swap poses
|
||||
if( IQM_CheckRange( header, header->ofs_poses,
|
||||
header->num_poses, sizeof(iqmPose_t) ) ) {
|
||||
|
@ -438,7 +462,7 @@ qboolean R_LoadIQM( model_t *mod, void *buffer, int filesize, const char *mod_na
|
|||
size = sizeof(iqmData_t);
|
||||
size += header->num_meshes * sizeof( srfIQModel_t );
|
||||
size += header->num_joints * 12 * sizeof( float ); // joint mats
|
||||
size += header->num_joints * header->num_frames * 12 * sizeof( float ); // pose mats
|
||||
size += header->num_poses * header->num_frames * 12 * sizeof( float ); // pose mats
|
||||
if(header->ofs_bounds)
|
||||
size += header->num_frames * 6 * sizeof(float); // model bounds
|
||||
size += header->num_vertexes * 3 * sizeof(float); // positions
|
||||
|
@ -446,12 +470,18 @@ qboolean R_LoadIQM( model_t *mod, void *buffer, int filesize, const char *mod_na
|
|||
size += header->num_vertexes * 3 * sizeof(float); // normals
|
||||
size += header->num_vertexes * 4 * sizeof(float); // tangents
|
||||
size += header->num_vertexes * 4 * sizeof(byte); // blendIndexes
|
||||
size += header->num_vertexes * 4 * sizeof(byte); // blendWeights
|
||||
size += header->num_vertexes * 4 * sizeof(byte); // colors
|
||||
size += header->num_joints * sizeof(int); // parents
|
||||
size += header->num_triangles * 3 * sizeof(int); // triangles
|
||||
size += joint_names; // joint names
|
||||
|
||||
// blendWeights
|
||||
if (blendWeightsType == IQM_FLOAT) {
|
||||
size += header->num_vertexes * 4 * sizeof(float);
|
||||
} else {
|
||||
size += header->num_vertexes * 4 * sizeof(byte);
|
||||
}
|
||||
|
||||
mod->type = MOD_IQM;
|
||||
iqmData = (iqmData_t *)ri.Hunk_Alloc( size, h_low );
|
||||
mod->modelData = iqmData;
|
||||
|
@ -462,28 +492,40 @@ qboolean R_LoadIQM( model_t *mod, void *buffer, int filesize, const char *mod_na
|
|||
iqmData->num_frames = header->num_frames;
|
||||
iqmData->num_surfaces = header->num_meshes;
|
||||
iqmData->num_joints = header->num_joints;
|
||||
iqmData->num_poses = header->num_poses;
|
||||
iqmData->blendWeightsType = blendWeightsType;
|
||||
iqmData->surfaces = (srfIQModel_t *)(iqmData + 1);
|
||||
iqmData->jointMats = (float *) (iqmData->surfaces + iqmData->num_surfaces);
|
||||
iqmData->poseMats = iqmData->jointMats + 12 * header->num_joints;
|
||||
if(header->ofs_bounds)
|
||||
{
|
||||
iqmData->bounds = iqmData->poseMats + 12 * header->num_joints * header->num_frames;
|
||||
iqmData->bounds = iqmData->poseMats + 12 * header->num_poses * header->num_frames;
|
||||
iqmData->positions = iqmData->bounds + 6 * header->num_frames;
|
||||
}
|
||||
else
|
||||
iqmData->positions = iqmData->poseMats + 12 * header->num_joints * header->num_frames;
|
||||
iqmData->positions = iqmData->poseMats + 12 * header->num_poses * header->num_frames;
|
||||
iqmData->texcoords = iqmData->positions + 3 * header->num_vertexes;
|
||||
iqmData->normals = iqmData->texcoords + 2 * header->num_vertexes;
|
||||
iqmData->tangents = iqmData->normals + 3 * header->num_vertexes;
|
||||
iqmData->blendIndexes = (byte *)(iqmData->tangents + 4 * header->num_vertexes);
|
||||
iqmData->blendWeights = iqmData->blendIndexes + 4 * header->num_vertexes;
|
||||
iqmData->colors = iqmData->blendWeights + 4 * header->num_vertexes;
|
||||
|
||||
if(blendWeightsType == IQM_FLOAT) {
|
||||
iqmData->blendWeights.f = (float *)(iqmData->blendIndexes + 4 * header->num_vertexes);
|
||||
iqmData->colors = (byte *)(iqmData->blendWeights.f + 4 * header->num_vertexes);
|
||||
} else {
|
||||
iqmData->blendWeights.b = iqmData->blendIndexes + 4 * header->num_vertexes;
|
||||
iqmData->colors = iqmData->blendWeights.b + 4 * header->num_vertexes;
|
||||
}
|
||||
|
||||
iqmData->jointParents = (int *)(iqmData->colors + 4 * header->num_vertexes);
|
||||
iqmData->triangles = iqmData->jointParents + header->num_joints;
|
||||
iqmData->names = (char *)(iqmData->triangles + 3 * header->num_triangles);
|
||||
|
||||
if ( header->num_joints == 0 )
|
||||
iqmData->jointMats = iqmData->poseMats = NULL;
|
||||
iqmData->jointMats = NULL;
|
||||
|
||||
if ( header->num_poses == 0 )
|
||||
iqmData->poseMats = NULL;
|
||||
|
||||
// calculate joint matrices and their inverses
|
||||
// joint inverses are needed only until the pose matrices are calculated
|
||||
|
@ -620,14 +662,27 @@ qboolean R_LoadIQM( model_t *mod, void *buffer, int filesize, const char *mod_na
|
|||
n * sizeof(float) );
|
||||
break;
|
||||
case IQM_BLENDINDEXES:
|
||||
Com_Memcpy( iqmData->blendIndexes,
|
||||
(byte *)header + vertexarray->offset,
|
||||
n * sizeof(byte) );
|
||||
if( blendIndexesType == IQM_INT ) {
|
||||
int *data = (int*)((byte*)header + vertexarray->offset);
|
||||
for ( j = 0; j < n; j++ ) {
|
||||
iqmData->blendIndexes[j] = (byte)data[j];
|
||||
}
|
||||
} else {
|
||||
Com_Memcpy( iqmData->blendIndexes,
|
||||
(byte *)header + vertexarray->offset,
|
||||
n * sizeof(byte) );
|
||||
}
|
||||
break;
|
||||
case IQM_BLENDWEIGHTS:
|
||||
Com_Memcpy( iqmData->blendWeights,
|
||||
(byte *)header + vertexarray->offset,
|
||||
n * sizeof(byte) );
|
||||
if( blendWeightsType == IQM_FLOAT ) {
|
||||
Com_Memcpy( iqmData->blendWeights.f,
|
||||
(byte *)header + vertexarray->offset,
|
||||
n * sizeof(float) );
|
||||
} else {
|
||||
Com_Memcpy( iqmData->blendWeights.b,
|
||||
(byte *)header + vertexarray->offset,
|
||||
n * sizeof(byte) );
|
||||
}
|
||||
break;
|
||||
case IQM_COLOR:
|
||||
Com_Memcpy( iqmData->colors,
|
||||
|
@ -892,9 +947,21 @@ static void ComputePoseMats( iqmData_t *data, int frame, int oldframe,
|
|||
int *joint = data->jointParents;
|
||||
int i;
|
||||
|
||||
if ( oldframe == frame ) {
|
||||
mat1 = data->poseMats + 12 * data->num_joints * frame;
|
||||
if ( data->num_poses == 0 ) {
|
||||
for( i = 0; i < data->num_joints; i++, joint++ ) {
|
||||
if( *joint >= 0 ) {
|
||||
Matrix34Multiply( mat + 12 * *joint,
|
||||
identityMatrix, mat + 12*i );
|
||||
} else {
|
||||
Com_Memcpy( mat + 12*i, identityMatrix, 12 * sizeof(float) );
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if ( oldframe == frame ) {
|
||||
mat1 = data->poseMats + 12 * data->num_poses * frame;
|
||||
for( i = 0; i < data->num_poses; i++, joint++ ) {
|
||||
if( *joint >= 0 ) {
|
||||
Matrix34Multiply( mat + 12 * *joint,
|
||||
mat1 + 12*i, mat + 12*i );
|
||||
|
@ -903,10 +970,10 @@ static void ComputePoseMats( iqmData_t *data, int frame, int oldframe,
|
|||
}
|
||||
}
|
||||
} else {
|
||||
mat1 = data->poseMats + 12 * data->num_joints * frame;
|
||||
mat2 = data->poseMats + 12 * data->num_joints * oldframe;
|
||||
mat1 = data->poseMats + 12 * data->num_poses * frame;
|
||||
mat2 = data->poseMats + 12 * data->num_poses * oldframe;
|
||||
|
||||
for( i = 0; i < data->num_joints; i++, joint++ ) {
|
||||
for( i = 0; i < data->num_poses; i++, joint++ ) {
|
||||
if( *joint >= 0 ) {
|
||||
float tmpMat[12];
|
||||
InterpolateMatrix( mat1 + 12*i, mat2 + 12*i,
|
||||
|
@ -974,7 +1041,7 @@ void RB_IQMSurfaceAnim( surfaceType_t *surface ) {
|
|||
outColor = &tess.vertexColors[tess.numVertexes];
|
||||
|
||||
// compute interpolated joint matrices
|
||||
if ( data->num_joints > 0 ) {
|
||||
if ( data->num_poses > 0 ) {
|
||||
ComputePoseMats( data, frame, oldframe, backlerp, jointMats );
|
||||
}
|
||||
|
||||
|
@ -985,28 +1052,31 @@ void RB_IQMSurfaceAnim( surfaceType_t *surface ) {
|
|||
float vtxMat[12];
|
||||
float nrmMat[9];
|
||||
int vtx = i + surf->first_vertex;
|
||||
float blendWeights[4];
|
||||
int numWeights;
|
||||
|
||||
if ( data->num_joints == 0 || data->blendWeights[4*vtx] <= 0 ) {
|
||||
for ( numWeights = 0; numWeights < 4; numWeights++ ) {
|
||||
if ( data->blendWeightsType == IQM_FLOAT )
|
||||
blendWeights[numWeights] = data->blendWeights.f[4*vtx + numWeights];
|
||||
else
|
||||
blendWeights[numWeights] = (float)data->blendWeights.b[4*vtx + numWeights] / 255.0f;
|
||||
|
||||
if ( blendWeights[numWeights] <= 0 )
|
||||
break;
|
||||
}
|
||||
|
||||
if ( data->num_poses == 0 || numWeights == 0 ) {
|
||||
// no blend joint, use identity matrix.
|
||||
for( j = 0; j < 3; j++ ) {
|
||||
for( k = 0; k < 4; k++ )
|
||||
vtxMat[4*j+k] = ( k == j ) ? 1 : 0;
|
||||
}
|
||||
Com_Memcpy( vtxMat, identityMatrix, 12 * sizeof (float) );
|
||||
} else {
|
||||
// compute the vertex matrix by blending the up to
|
||||
// four blend weights
|
||||
for( k = 0; k < 12; k++ )
|
||||
vtxMat[k] = data->blendWeights[4*vtx]
|
||||
* jointMats[12*data->blendIndexes[4*vtx] + k];
|
||||
for( j = 1; j < 4; j++ ) {
|
||||
if( data->blendWeights[4*vtx + j] <= 0 )
|
||||
break;
|
||||
for( k = 0; k < 12; k++ )
|
||||
vtxMat[k] += data->blendWeights[4*vtx + j]
|
||||
* jointMats[12*data->blendIndexes[4*vtx + j] + k];
|
||||
Com_Memset( vtxMat, 0, 12 * sizeof (float) );
|
||||
for( j = 0; j < numWeights; j++ ) {
|
||||
for( k = 0; k < 12; k++ ) {
|
||||
vtxMat[k] += blendWeights[j] * jointMats[12*data->blendIndexes[4*vtx + j] + k];
|
||||
}
|
||||
}
|
||||
for( k = 0; k < 12; k++ )
|
||||
vtxMat[k] *= 1.0f / 255.0f;
|
||||
}
|
||||
|
||||
// compute the normal matrix as transpose of the adjoint
|
||||
|
|
|
@ -1145,12 +1145,7 @@ static void RB_IterateStagesGeneric( shaderCommands_t *input )
|
|||
//
|
||||
// set state
|
||||
//
|
||||
if ( pStage->bundle[0].vertexLightmap && ( (r_vertexLight->integer && !r_uiFullScreen->integer) || glConfig.hardwareType == GLHW_PERMEDIA2 ) && r_lightmap->integer )
|
||||
{
|
||||
GL_Bind( tr.whiteImage );
|
||||
}
|
||||
else
|
||||
R_BindAnimatedImage( &pStage->bundle[0] );
|
||||
R_BindAnimatedImage( &pStage->bundle[0] );
|
||||
|
||||
GL_State( pStage->stateBits );
|
||||
|
||||
|
@ -1160,7 +1155,7 @@ static void RB_IterateStagesGeneric( shaderCommands_t *input )
|
|||
R_DrawElements( input->numIndexes, input->indexes );
|
||||
}
|
||||
// allow skipping out to show just lightmaps during development
|
||||
if ( r_lightmap->integer && ( pStage->bundle[0].isLightmap || pStage->bundle[1].isLightmap || pStage->bundle[0].vertexLightmap ) )
|
||||
if ( r_lightmap->integer && ( pStage->bundle[0].isLightmap || pStage->bundle[1].isLightmap ) )
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -1233,7 +1233,6 @@ void (*rb_surfaceTable[SF_NUM_SURFACE_TYPES])( void *) = {
|
|||
(void(*)(void*))RB_SurfaceTriangles, // SF_TRIANGLES,
|
||||
(void(*)(void*))RB_SurfacePolychain, // SF_POLY,
|
||||
(void(*)(void*))RB_SurfaceMesh, // SF_MD3,
|
||||
(void(*)(void*))RB_SurfaceAnim, // SF_MD4,
|
||||
(void(*)(void*))RB_MDRSurfaceAnim, // SF_MDR,
|
||||
(void(*)(void*))RB_IQMSurfaceAnim, // SF_IQM,
|
||||
(void(*)(void*))RB_SurfaceFlare, // SF_FLARE,
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
attribute vec4 attr_Position;
|
||||
attribute vec3 attr_Position;
|
||||
attribute vec4 attr_TexCoord0;
|
||||
|
||||
uniform mat4 u_ModelViewProjectionMatrix;
|
||||
|
@ -8,6 +8,6 @@ varying vec2 var_TexCoords;
|
|||
|
||||
void main()
|
||||
{
|
||||
gl_Position = u_ModelViewProjectionMatrix * attr_Position;
|
||||
gl_Position = u_ModelViewProjectionMatrix * vec4(attr_Position, 1.0);
|
||||
var_TexCoords = attr_TexCoord0.st;
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
attribute vec4 attr_Position;
|
||||
attribute vec3 attr_Position;
|
||||
attribute vec4 attr_TexCoord0;
|
||||
|
||||
uniform mat4 u_ModelViewProjectionMatrix;
|
||||
|
@ -8,6 +8,6 @@ varying vec2 var_TexCoords;
|
|||
|
||||
void main()
|
||||
{
|
||||
gl_Position = u_ModelViewProjectionMatrix * attr_Position;
|
||||
gl_Position = u_ModelViewProjectionMatrix * vec4(attr_Position, 1.0);
|
||||
var_TexCoords = attr_TexCoord0.st;
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
attribute vec4 attr_Position;
|
||||
attribute vec3 attr_Position;
|
||||
attribute vec4 attr_TexCoord0;
|
||||
attribute vec3 attr_Normal;
|
||||
|
||||
|
@ -32,7 +32,7 @@ vec3 DeformPosition(const vec3 pos, const vec3 normal, const vec2 st)
|
|||
|
||||
if (u_DeformGen == DGEN_BULGE)
|
||||
{
|
||||
phase *= M_PI * 0.25 * st.x;
|
||||
phase *= st.x;
|
||||
}
|
||||
else // if (u_DeformGen <= DGEN_WAVE_INVERSE_SAWTOOTH)
|
||||
{
|
||||
|
@ -48,7 +48,7 @@ vec3 DeformPosition(const vec3 pos, const vec3 normal, const vec2 st)
|
|||
}
|
||||
else if (u_DeformGen == DGEN_WAVE_SQUARE)
|
||||
{
|
||||
func = sign(sin(value * 2.0 * M_PI));
|
||||
func = sign(0.5 - fract(value));
|
||||
}
|
||||
else if (u_DeformGen == DGEN_WAVE_TRIANGLE)
|
||||
{
|
||||
|
@ -62,7 +62,7 @@ vec3 DeformPosition(const vec3 pos, const vec3 normal, const vec2 st)
|
|||
{
|
||||
func = (1.0 - fract(value));
|
||||
}
|
||||
else if (u_DeformGen == DGEN_BULGE)
|
||||
else // if (u_DeformGen == DGEN_BULGE)
|
||||
{
|
||||
func = sin(value);
|
||||
}
|
||||
|
@ -73,16 +73,16 @@ vec3 DeformPosition(const vec3 pos, const vec3 normal, const vec2 st)
|
|||
|
||||
void main()
|
||||
{
|
||||
vec4 position = attr_Position;
|
||||
vec3 normal = attr_Normal;
|
||||
vec3 position = attr_Position;
|
||||
vec3 normal = attr_Normal * 2.0 - vec3(1.0);
|
||||
|
||||
#if defined(USE_DEFORM_VERTEXES)
|
||||
position.xyz = DeformPosition(position.xyz, normal, attr_TexCoord0.st);
|
||||
position = DeformPosition(position, normal, attr_TexCoord0.st);
|
||||
#endif
|
||||
|
||||
gl_Position = u_ModelViewProjectionMatrix * position;
|
||||
gl_Position = u_ModelViewProjectionMatrix * vec4(position, 1.0);
|
||||
|
||||
vec3 dist = u_DlightInfo.xyz - position.xyz;
|
||||
vec3 dist = u_DlightInfo.xyz - position;
|
||||
|
||||
var_Tex1 = dist.xy * u_DlightInfo.a + vec2(0.5);
|
||||
float dlightmod = step(0.0, dot(dist, normal));
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
attribute vec4 attr_Position;
|
||||
attribute vec3 attr_Position;
|
||||
attribute vec4 attr_TexCoord0;
|
||||
|
||||
uniform mat4 u_ModelViewProjectionMatrix;
|
||||
|
@ -8,6 +8,6 @@ varying vec2 var_TexCoords;
|
|||
|
||||
void main()
|
||||
{
|
||||
gl_Position = u_ModelViewProjectionMatrix * attr_Position;
|
||||
gl_Position = u_ModelViewProjectionMatrix * vec4(attr_Position, 1.0);
|
||||
var_TexCoords = attr_TexCoord0.st;
|
||||
}
|
||||
|
|
|
@ -5,5 +5,5 @@ varying float var_Scale;
|
|||
void main()
|
||||
{
|
||||
gl_FragColor = u_Color;
|
||||
gl_FragColor.a *= sqrt(clamp(var_Scale, 0.0, 1.0));
|
||||
gl_FragColor.a = sqrt(clamp(var_Scale, 0.0, 1.0));
|
||||
}
|
||||
|
|
|
@ -1,27 +1,30 @@
|
|||
attribute vec4 attr_Position;
|
||||
attribute vec3 attr_Position;
|
||||
attribute vec3 attr_Normal;
|
||||
|
||||
attribute vec4 attr_TexCoord0;
|
||||
|
||||
//#if defined(USE_VERTEX_ANIMATION)
|
||||
attribute vec4 attr_Position2;
|
||||
#if defined(USE_VERTEX_ANIMATION)
|
||||
attribute vec3 attr_Position2;
|
||||
attribute vec3 attr_Normal2;
|
||||
//#endif
|
||||
#endif
|
||||
|
||||
uniform vec4 u_FogDistance;
|
||||
uniform vec4 u_FogDepth;
|
||||
uniform float u_FogEyeT;
|
||||
|
||||
//#if defined(USE_DEFORM_VERTEXES)
|
||||
#if defined(USE_DEFORM_VERTEXES)
|
||||
uniform int u_DeformGen;
|
||||
uniform float u_DeformParams[5];
|
||||
//#endif
|
||||
#endif
|
||||
|
||||
uniform float u_Time;
|
||||
uniform mat4 u_ModelViewProjectionMatrix;
|
||||
|
||||
//#if defined(USE_VERTEX_ANIMATION)
|
||||
#if defined(USE_VERTEX_ANIMATION)
|
||||
uniform float u_VertexLerp;
|
||||
//#endif
|
||||
#endif
|
||||
|
||||
uniform vec4 u_Color;
|
||||
|
||||
varying float var_Scale;
|
||||
|
||||
|
@ -41,7 +44,7 @@ vec3 DeformPosition(const vec3 pos, const vec3 normal, const vec2 st)
|
|||
|
||||
if (u_DeformGen == DGEN_BULGE)
|
||||
{
|
||||
phase *= M_PI * 0.25 * st.x;
|
||||
phase *= st.x;
|
||||
}
|
||||
else // if (u_DeformGen <= DGEN_WAVE_INVERSE_SAWTOOTH)
|
||||
{
|
||||
|
@ -57,7 +60,7 @@ vec3 DeformPosition(const vec3 pos, const vec3 normal, const vec2 st)
|
|||
}
|
||||
else if (u_DeformGen == DGEN_WAVE_SQUARE)
|
||||
{
|
||||
func = sign(sin(value * 2.0 * M_PI));
|
||||
func = sign(0.5 - fract(value));
|
||||
}
|
||||
else if (u_DeformGen == DGEN_WAVE_TRIANGLE)
|
||||
{
|
||||
|
@ -71,7 +74,7 @@ vec3 DeformPosition(const vec3 pos, const vec3 normal, const vec2 st)
|
|||
{
|
||||
func = (1.0 - fract(value));
|
||||
}
|
||||
else if (u_DeformGen == DGEN_BULGE)
|
||||
else // if (u_DeformGen == DGEN_BULGE)
|
||||
{
|
||||
func = sin(value);
|
||||
}
|
||||
|
@ -80,35 +83,36 @@ vec3 DeformPosition(const vec3 pos, const vec3 normal, const vec2 st)
|
|||
}
|
||||
#endif
|
||||
|
||||
float CalcFog(vec4 position)
|
||||
float CalcFog(vec3 position)
|
||||
{
|
||||
float s = dot(position, u_FogDistance) * 8.0;
|
||||
float t = dot(position, u_FogDepth);
|
||||
float s = dot(vec4(position, 1.0), u_FogDistance) * 8.0;
|
||||
float t = dot(vec4(position, 1.0), u_FogDepth);
|
||||
|
||||
bool eyeOutside = u_FogEyeT < 0.0;
|
||||
float t2 = float(t >= float(eyeOutside));
|
||||
float eyeOutside = float(u_FogEyeT < 0.0);
|
||||
float fogged = float(t >= eyeOutside);
|
||||
|
||||
if (eyeOutside)
|
||||
t2 *= t / (t - u_FogEyeT);
|
||||
t += 1e-6;
|
||||
t *= fogged / (t - u_FogEyeT * eyeOutside);
|
||||
|
||||
return s * t2;
|
||||
return s * t;
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
#if defined(USE_VERTEX_ANIMATION)
|
||||
vec4 position = mix(attr_Position, attr_Position2, u_VertexLerp);
|
||||
vec3 normal = normalize(mix(attr_Normal, attr_Normal2, u_VertexLerp));
|
||||
vec3 position = mix(attr_Position, attr_Position2, u_VertexLerp);
|
||||
vec3 normal = mix(attr_Normal, attr_Normal2, u_VertexLerp);
|
||||
normal = normalize(normal - vec3(0.5));
|
||||
#else
|
||||
vec4 position = attr_Position;
|
||||
vec3 normal = attr_Normal;
|
||||
vec3 position = attr_Position;
|
||||
vec3 normal = attr_Normal * 2.0 - vec3(1.0);
|
||||
#endif
|
||||
|
||||
#if defined(USE_DEFORM_VERTEXES)
|
||||
position.xyz = DeformPosition(position.xyz, normal, attr_TexCoord0.st);
|
||||
#endif
|
||||
|
||||
gl_Position = u_ModelViewProjectionMatrix * position;
|
||||
gl_Position = u_ModelViewProjectionMatrix * vec4(position, 1.0);
|
||||
|
||||
var_Scale = CalcFog(position);
|
||||
var_Scale = CalcFog(position) * u_Color.a * u_Color.a;
|
||||
}
|
||||
|
|
|
@ -37,6 +37,8 @@ void main()
|
|||
{
|
||||
color = color2;
|
||||
}
|
||||
|
||||
//color = color * (u_Texture1Env.xxxx + color2 * u_Texture1Env.z) + color2 * u_Texture1Env.y;
|
||||
#endif
|
||||
|
||||
gl_FragColor = color * var_Color;
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
attribute vec4 attr_Position;
|
||||
attribute vec3 attr_Position;
|
||||
attribute vec3 attr_Normal;
|
||||
|
||||
#if defined(USE_VERTEX_ANIMATION)
|
||||
attribute vec4 attr_Position2;
|
||||
attribute vec3 attr_Position2;
|
||||
attribute vec3 attr_Normal2;
|
||||
#endif
|
||||
|
||||
|
@ -17,7 +17,7 @@ uniform vec4 u_DiffuseTexMatrix;
|
|||
uniform vec4 u_DiffuseTexOffTurb;
|
||||
|
||||
#if defined(USE_TCGEN) || defined(USE_RGBAGEN)
|
||||
uniform vec3 u_ViewOrigin;
|
||||
uniform vec3 u_LocalViewOrigin;
|
||||
#endif
|
||||
|
||||
#if defined(USE_TCGEN)
|
||||
|
@ -48,7 +48,7 @@ uniform int u_ColorGen;
|
|||
uniform int u_AlphaGen;
|
||||
uniform vec3 u_AmbientLight;
|
||||
uniform vec3 u_DirectedLight;
|
||||
uniform vec4 u_LightOrigin;
|
||||
uniform vec3 u_ModelLightDir;
|
||||
uniform float u_PortalRange;
|
||||
#endif
|
||||
|
||||
|
@ -73,7 +73,7 @@ vec3 DeformPosition(const vec3 pos, const vec3 normal, const vec2 st)
|
|||
|
||||
if (u_DeformGen == DGEN_BULGE)
|
||||
{
|
||||
phase *= M_PI * 0.25 * st.x;
|
||||
phase *= st.x;
|
||||
}
|
||||
else // if (u_DeformGen <= DGEN_WAVE_INVERSE_SAWTOOTH)
|
||||
{
|
||||
|
@ -89,7 +89,7 @@ vec3 DeformPosition(const vec3 pos, const vec3 normal, const vec2 st)
|
|||
}
|
||||
else if (u_DeformGen == DGEN_WAVE_SQUARE)
|
||||
{
|
||||
func = sign(sin(value * 2.0 * M_PI));
|
||||
func = sign(fract(0.5 - value));
|
||||
}
|
||||
else if (u_DeformGen == DGEN_WAVE_TRIANGLE)
|
||||
{
|
||||
|
@ -103,7 +103,7 @@ vec3 DeformPosition(const vec3 pos, const vec3 normal, const vec2 st)
|
|||
{
|
||||
func = (1.0 - fract(value));
|
||||
}
|
||||
else if (u_DeformGen == DGEN_BULGE)
|
||||
else // if (u_DeformGen == DGEN_BULGE)
|
||||
{
|
||||
func = sin(value);
|
||||
}
|
||||
|
@ -123,8 +123,10 @@ vec2 GenTexCoords(int TCGen, vec3 position, vec3 normal, vec3 TCGenVector0, vec3
|
|||
}
|
||||
else if (TCGen == TCGEN_ENVIRONMENT_MAPPED)
|
||||
{
|
||||
vec3 viewer = normalize(u_ViewOrigin - position);
|
||||
tex = -reflect(viewer, normal).yz * vec2(0.5, -0.5) + 0.5;
|
||||
vec3 viewer = normalize(u_LocalViewOrigin - position);
|
||||
vec2 ref = reflect(viewer, normal).yz;
|
||||
tex.s = ref.x * -0.5 + 0.5;
|
||||
tex.t = ref.y * 0.5 + 0.5;
|
||||
}
|
||||
else if (TCGen == TCGEN_VECTOR)
|
||||
{
|
||||
|
@ -139,13 +141,14 @@ vec2 GenTexCoords(int TCGen, vec3 position, vec3 normal, vec3 TCGenVector0, vec3
|
|||
vec2 ModTexCoords(vec2 st, vec3 position, vec4 texMatrix, vec4 offTurb)
|
||||
{
|
||||
float amplitude = offTurb.z;
|
||||
float phase = offTurb.w;
|
||||
vec2 st2 = vec2(dot(st, texMatrix.xz), dot(st, texMatrix.yw)) + offTurb.xy;
|
||||
float phase = offTurb.w * 2.0 * M_PI;
|
||||
vec2 st2;
|
||||
st2.x = st.x * texMatrix.x + (st.y * texMatrix.z + offTurb.x);
|
||||
st2.y = st.x * texMatrix.y + (st.y * texMatrix.w + offTurb.y);
|
||||
|
||||
vec3 offsetPos = position / 1024.0;
|
||||
offsetPos.x += offsetPos.z;
|
||||
vec2 offsetPos = vec2(position.x + position.z, position.y);
|
||||
|
||||
vec2 texOffset = sin((offsetPos.xy + vec2(phase)) * 2.0 * M_PI);
|
||||
vec2 texOffset = sin(offsetPos * (2.0 * M_PI / 1024.0) + vec2(phase));
|
||||
|
||||
return st2 + texOffset * amplitude;
|
||||
}
|
||||
|
@ -158,30 +161,25 @@ vec4 CalcColor(vec3 position, vec3 normal)
|
|||
|
||||
if (u_ColorGen == CGEN_LIGHTING_DIFFUSE)
|
||||
{
|
||||
float incoming = clamp(dot(normal, u_LightOrigin.xyz), 0.0, 1.0);
|
||||
float incoming = clamp(dot(normal, u_ModelLightDir), 0.0, 1.0);
|
||||
|
||||
color.rgb = clamp(u_DirectedLight * incoming + u_AmbientLight, 0.0, 1.0);
|
||||
}
|
||||
|
||||
vec3 toView = u_ViewOrigin - position;
|
||||
vec3 viewer = normalize(u_ViewOrigin - position);
|
||||
vec3 viewer = u_LocalViewOrigin - position;
|
||||
|
||||
if (u_AlphaGen == AGEN_LIGHTING_SPECULAR)
|
||||
{
|
||||
vec3 lightDir = normalize(vec3(-960.0, -1980.0, 96.0) - position.xyz);
|
||||
vec3 halfangle = normalize(lightDir + viewer);
|
||||
vec3 lightDir = normalize(vec3(-960.0, 1980.0, 96.0) - position);
|
||||
vec3 reflected = -reflect(lightDir, normal);
|
||||
|
||||
color.a = pow(max(dot(normal, halfangle), 0.0), 8.0);
|
||||
color.a = clamp(dot(reflected, normalize(viewer)), 0.0, 1.0);
|
||||
color.a *= color.a;
|
||||
color.a *= color.a;
|
||||
}
|
||||
else if (u_AlphaGen == AGEN_PORTAL)
|
||||
{
|
||||
float alpha = length(toView) / u_PortalRange;
|
||||
|
||||
color.a = clamp(alpha, 0.0, 1.0);
|
||||
}
|
||||
else if (u_AlphaGen == AGEN_FRESNEL)
|
||||
{
|
||||
color.a = 0.10 + 0.90 * pow(1.0 - dot(normal, viewer), 5);
|
||||
color.a = clamp(length(viewer) / u_PortalRange, 0.0, 1.0);
|
||||
}
|
||||
|
||||
return color;
|
||||
|
@ -189,45 +187,46 @@ vec4 CalcColor(vec3 position, vec3 normal)
|
|||
#endif
|
||||
|
||||
#if defined(USE_FOG)
|
||||
float CalcFog(vec4 position)
|
||||
float CalcFog(vec3 position)
|
||||
{
|
||||
float s = dot(position, u_FogDistance) * 8.0;
|
||||
float t = dot(position, u_FogDepth);
|
||||
float s = dot(vec4(position, 1.0), u_FogDistance) * 8.0;
|
||||
float t = dot(vec4(position, 1.0), u_FogDepth);
|
||||
|
||||
bool eyeOutside = u_FogEyeT < 0.0;
|
||||
float t2 = float(t >= float(eyeOutside));
|
||||
float eyeOutside = float(u_FogEyeT < 0.0);
|
||||
float fogged = float(t < eyeOutside);
|
||||
|
||||
if (eyeOutside)
|
||||
t2 *= t / (t - u_FogEyeT);
|
||||
t += 1e-6;
|
||||
t *= fogged / (t - u_FogEyeT * eyeOutside);
|
||||
|
||||
return s * t2;
|
||||
return s * t;
|
||||
}
|
||||
#endif
|
||||
|
||||
void main()
|
||||
{
|
||||
#if defined(USE_VERTEX_ANIMATION)
|
||||
vec4 position = mix(attr_Position, attr_Position2, u_VertexLerp);
|
||||
vec3 normal = normalize(mix(attr_Normal, attr_Normal2, u_VertexLerp));
|
||||
vec3 position = mix(attr_Position, attr_Position2, u_VertexLerp);
|
||||
vec3 normal = mix(attr_Normal, attr_Normal2, u_VertexLerp);
|
||||
normal = normalize(normal - vec3(0.5));
|
||||
#else
|
||||
vec4 position = attr_Position;
|
||||
vec3 normal = attr_Normal;
|
||||
vec3 position = attr_Position;
|
||||
vec3 normal = attr_Normal * 2.0 - vec3(1.0);
|
||||
#endif
|
||||
|
||||
#if defined(USE_DEFORM_VERTEXES)
|
||||
position.xyz = DeformPosition(position.xyz, normal, attr_TexCoord0.st);
|
||||
position = DeformPosition(position, normal, attr_TexCoord0.st);
|
||||
#endif
|
||||
|
||||
gl_Position = u_ModelViewProjectionMatrix * position;
|
||||
gl_Position = u_ModelViewProjectionMatrix * vec4(position, 1.0);
|
||||
|
||||
#if defined(USE_TCGEN)
|
||||
vec2 tex = GenTexCoords(u_TCGen0, position.xyz, normal, u_TCGen0Vector0, u_TCGen0Vector1);
|
||||
vec2 tex = GenTexCoords(u_TCGen0, position, normal, u_TCGen0Vector0, u_TCGen0Vector1);
|
||||
#else
|
||||
vec2 tex = attr_TexCoord0.st;
|
||||
#endif
|
||||
|
||||
#if defined(USE_TCMOD)
|
||||
var_DiffuseTex = ModTexCoords(tex, position.xyz, u_DiffuseTexMatrix, u_DiffuseTexOffTurb);
|
||||
var_DiffuseTex = ModTexCoords(tex, position, u_DiffuseTexMatrix, u_DiffuseTexOffTurb);
|
||||
#else
|
||||
var_DiffuseTex = tex;
|
||||
#endif
|
||||
|
@ -237,7 +236,7 @@ void main()
|
|||
#endif
|
||||
|
||||
#if defined(USE_RGBAGEN)
|
||||
var_Color = CalcColor(position.xyz, normal);
|
||||
var_Color = CalcColor(position, normal);
|
||||
#else
|
||||
var_Color = u_VertColor * attr_Color + u_BaseColor;
|
||||
#endif
|
||||
|
|
|
@ -24,45 +24,49 @@ uniform sampler2D u_ShadowMap;
|
|||
uniform samplerCube u_CubeMap;
|
||||
#endif
|
||||
|
||||
#if defined(USE_LIGHT_VECTOR)
|
||||
#if defined(USE_NORMALMAP) || defined(USE_DELUXEMAP) || defined(USE_SPECULARMAP) || defined(USE_CUBEMAP)
|
||||
uniform vec4 u_EnableTextures; // x = normal, y = deluxe, z = specular, w = cube
|
||||
#endif
|
||||
|
||||
#if defined(USE_LIGHT_VECTOR) && !defined(USE_FAST_LIGHT)
|
||||
uniform vec3 u_DirectedLight;
|
||||
uniform vec3 u_AmbientLight;
|
||||
uniform float u_LightRadius;
|
||||
#endif
|
||||
|
||||
#if defined(USE_PRIMARY_LIGHT) || defined(USE_SHADOWMAP)
|
||||
uniform vec3 u_PrimaryLightColor;
|
||||
uniform vec3 u_PrimaryLightAmbient;
|
||||
uniform float u_PrimaryLightRadius;
|
||||
#endif
|
||||
|
||||
#if defined(USE_LIGHT)
|
||||
#if defined(USE_LIGHT) && !defined(USE_FAST_LIGHT)
|
||||
uniform vec2 u_MaterialInfo;
|
||||
#endif
|
||||
|
||||
varying vec2 var_DiffuseTex;
|
||||
#if defined(USE_LIGHTMAP)
|
||||
varying vec2 var_LightTex;
|
||||
#endif
|
||||
varying vec4 var_TexCoords;
|
||||
|
||||
varying vec4 var_Color;
|
||||
|
||||
#if (defined(USE_LIGHT) && !defined(USE_FAST_LIGHT)) || defined(USE_PARALLAXMAP)
|
||||
varying vec3 var_ViewDir;
|
||||
varying vec3 var_Normal;
|
||||
varying vec3 var_Tangent;
|
||||
varying vec3 var_Bitangent;
|
||||
#if (defined(USE_LIGHT) && !defined(USE_FAST_LIGHT))
|
||||
#if defined(USE_VERT_TANGENT_SPACE)
|
||||
varying vec4 var_Normal;
|
||||
varying vec4 var_Tangent;
|
||||
varying vec4 var_Bitangent;
|
||||
#else
|
||||
varying vec3 var_Normal;
|
||||
varying vec3 var_ViewDir;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(USE_LIGHT_VERTEX) && !defined(USE_FAST_LIGHT)
|
||||
varying vec3 var_lightColor;
|
||||
varying vec3 var_LightColor;
|
||||
#endif
|
||||
|
||||
#if defined(USE_LIGHT) && !defined(USE_DELUXEMAP)
|
||||
#if defined(USE_LIGHT) && !defined(USE_FAST_LIGHT)
|
||||
varying vec4 var_LightDir;
|
||||
#endif
|
||||
|
||||
#if defined(USE_PRIMARY_LIGHT) || defined(USE_SHADOWMAP)
|
||||
varying vec3 var_PrimaryLightDir;
|
||||
varying vec4 var_PrimaryLightDir;
|
||||
#endif
|
||||
|
||||
|
||||
|
@ -162,36 +166,59 @@ vec3 EnvironmentBRDF(float gloss, float NE, vec3 specular)
|
|||
float a1 = t.w;
|
||||
return clamp( a0 + specular * ( a1 - a0 ), 0.0, 1.0 );
|
||||
#elif 0
|
||||
// from http://seblagarde.wordpress.com/2011/08/17/hello-world/
|
||||
// from http://seblagarde.wordpress.com/2011/08/17/hello-world/
|
||||
return mix(specular.rgb, max(specular.rgb, vec3(gloss)), CalcFresnel(NE));
|
||||
#else
|
||||
// from http://advances.realtimerendering.com/s2011/Lazarov-Physically-Based-Lighting-in-Black-Ops%20%28Siggraph%202011%20Advances%20in%20Real-Time%20Rendering%20Course%29.pptx
|
||||
// from http://advances.realtimerendering.com/s2011/Lazarov-Physically-Based-Lighting-in-Black-Ops%20%28Siggraph%202011%20Advances%20in%20Real-Time%20Rendering%20Course%29.pptx
|
||||
return mix(specular.rgb, vec3(1.0), CalcFresnel(NE) / (4.0 - 3.0 * gloss));
|
||||
#endif
|
||||
}
|
||||
|
||||
float CalcBlinn(float NH, float shininess)
|
||||
{
|
||||
#if 0
|
||||
// from http://seblagarde.wordpress.com/2012/06/03/spherical-gaussien-approximation-for-blinn-phong-phong-and-fresnel/
|
||||
float a = shininess + 0.775;
|
||||
return exp(a * NH - a);
|
||||
#if defined(USE_BLINN) || defined(USE_BLINN_FRESNEL)
|
||||
// Normalized Blinn-Phong
|
||||
float norm = shininess * 0.125 + 1.0;
|
||||
#elif defined(USE_MCAULEY)
|
||||
// Cook-Torrance as done by Stephen McAuley
|
||||
// http://blog.selfshadow.com/publications/s2012-shading-course/mcauley/s2012_pbs_farcry3_notes_v2.pdf
|
||||
float norm = shininess * 0.25 + 0.125;
|
||||
#elif defined(USE_GOTANDA)
|
||||
// Neumann-Neumann as done by Yoshiharu Gotanda
|
||||
// http://research.tri-ace.com/Data/s2012_beyond_CourseNotes.pdf
|
||||
float norm = shininess * 0.124858 + 0.269182;
|
||||
#elif defined(USE_LAZAROV)
|
||||
// Cook-Torrance as done by Dimitar Lazarov
|
||||
// http://blog.selfshadow.com/publications/s2013-shading-course/lazarov/s2013_pbs_black_ops_2_notes.pdf
|
||||
float norm = shininess * 0.125 + 0.25;
|
||||
#else
|
||||
return pow(NH, shininess);
|
||||
float norm = 1.0;
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
// from http://seblagarde.wordpress.com/2012/06/03/spherical-gaussien-approximation-for-blinn-phong-phong-and-fresnel/
|
||||
float a = shininess + 0.775;
|
||||
return norm * exp(a * NH - a);
|
||||
#else
|
||||
return norm * pow(NH, shininess);
|
||||
#endif
|
||||
}
|
||||
|
||||
float CalcGGX(float NH, float shininess)
|
||||
float CalcGGX(float NH, float gloss)
|
||||
{
|
||||
// from http://blog.selfshadow.com/publications/s2013-shading-course/karis/s2013_pbs_epic_notes.pdf
|
||||
float m_sq = 2.0 / shininess;
|
||||
float d = ((NH * NH) * (m_sq - 1.0) + 1.0);
|
||||
return m_sq / (d * d);
|
||||
// from http://blog.selfshadow.com/publications/s2013-shading-course/karis/s2013_pbs_epic_notes_v2.pdf
|
||||
float a_sq = exp2(gloss * -13.0 + 1.0);
|
||||
float d = ((NH * NH) * (a_sq - 1.0) + 1.0);
|
||||
return a_sq / (d * d);
|
||||
}
|
||||
|
||||
float CalcFresnel(float EH)
|
||||
{
|
||||
#if 1
|
||||
// From http://blog.selfshadow.com/publications/s2013-shading-course/lazarov/s2013_pbs_black_ops_2_notes.pdf
|
||||
// not accurate, but fast
|
||||
return exp2(-10.0 * EH);
|
||||
#elif 0
|
||||
// From http://seblagarde.wordpress.com/2012/06/03/spherical-gaussien-approximation-for-blinn-phong-phong-and-fresnel/
|
||||
return exp2((-5.55473 * EH - 6.98316) * EH);
|
||||
#elif 0
|
||||
|
@ -201,133 +228,137 @@ float CalcFresnel(float EH)
|
|||
|
||||
return blend;
|
||||
#else
|
||||
return pow(1.0 - NH, 5.0);
|
||||
return pow(1.0 - EH, 5.0);
|
||||
#endif
|
||||
}
|
||||
|
||||
float CalcVisibility(float NH, float NL, float NE, float EH, float shininess)
|
||||
float CalcVisibility(float NH, float NL, float NE, float EH, float gloss)
|
||||
{
|
||||
#if 0
|
||||
float geo = 2.0 * NH * min(NE, NL);
|
||||
geo /= max(EH, geo);
|
||||
|
||||
return geo;
|
||||
#else
|
||||
// Modified from http://blog.selfshadow.com/publications/s2013-shading-course/karis/s2013_pbs_epic_notes.pdf
|
||||
#if defined(USE_GOTANDA)
|
||||
// Neumann-Neumann as done by Yoshiharu Gotanda
|
||||
// http://research.tri-ace.com/Data/s2012_beyond_CourseNotes.pdf
|
||||
return 1.0 / max(max(NL, NE), EPSILON);
|
||||
#elif defined(USE_LAZAROV)
|
||||
// Cook-Torrance as done by Dimitar Lazarov
|
||||
// http://blog.selfshadow.com/publications/s2013-shading-course/lazarov/s2013_pbs_black_ops_2_notes.pdf
|
||||
float k = min(1.0, gloss + 0.545);
|
||||
return 1.0 / (k * (EH * EH - 1.0) + 1.0);
|
||||
#elif defined(USE_GGX)
|
||||
float roughness = exp2(gloss * -6.5);
|
||||
|
||||
// Modified from http://blog.selfshadow.com/publications/s2013-shading-course/karis/s2013_pbs_epic_notes_v2.pdf
|
||||
// NL, NE in numerator factored out from cook-torrance
|
||||
#if defined(USE_GGX)
|
||||
float roughness = sqrt(2.0 / (shininess + 2.0));
|
||||
float k = (roughness + 1.0);
|
||||
float k = roughness + 1.0;
|
||||
k *= k * 0.125;
|
||||
#else
|
||||
float k = 2.0 / sqrt(3.1415926535 * (shininess + 2.0));
|
||||
#endif
|
||||
|
||||
float k2 = 1.0 - k;
|
||||
|
||||
float invGeo1 = NL * k2 + k;
|
||||
float invGeo2 = NE * k2 + k;
|
||||
|
||||
|
||||
return 1.0 / (invGeo1 * invGeo2);
|
||||
#endif
|
||||
#else
|
||||
return 1.0;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
vec3 CalcSpecular(vec3 specular, float NH, float NL, float NE, float EH, float shininess)
|
||||
vec3 CalcSpecular(vec3 specular, float NH, float NL, float NE, float EH, float gloss, float shininess)
|
||||
{
|
||||
float blinn = CalcBlinn(NH, shininess);
|
||||
#if defined(USE_GGX)
|
||||
float distrib = CalcGGX(NH, gloss);
|
||||
#else
|
||||
float distrib = CalcBlinn(NH, shininess);
|
||||
#endif
|
||||
|
||||
#if defined(USE_BLINN)
|
||||
vec3 fSpecular = specular;
|
||||
#else
|
||||
vec3 fSpecular = mix(specular, vec3(1.0), CalcFresnel(EH));
|
||||
float vis = CalcVisibility(NH, NL, NE, EH, shininess);
|
||||
#endif
|
||||
|
||||
#if defined(USE_BLINN)
|
||||
// Normalized Blinn-Phong
|
||||
return specular * blinn * (shininess * 0.125 + 1.0);
|
||||
#elif defined(USE_BLINN_FRESNEL)
|
||||
// Normalized Blinn-Phong with Fresnel
|
||||
return fSpecular * blinn * (shininess * 0.125 + 1.0);
|
||||
#elif defined(USE_MCAULEY)
|
||||
// Cook-Torrance as done by Stephen McAuley
|
||||
// http://blog.selfshadow.com/publications/s2012-shading-course/mcauley/s2012_pbs_farcry3_notes_v2.pdf
|
||||
return fSpecular * blinn * (shininess * 0.25 + 0.125);
|
||||
#elif defined(USE_GOTANDA)
|
||||
// Neumann-Neumann as done by Yoshiharu Gotanda
|
||||
// http://research.tri-ace.com/Data/s2012_beyond_CourseNotes.pdf
|
||||
return fSpecular * blinn * (shininess * 0.124858 + 0.269182) / max(max(NL, NE), EPSILON);
|
||||
#elif defined(USE_LAZAROV)
|
||||
// Cook-Torrance as done by Dimitar Lazarov
|
||||
// http://blog.selfshadow.com/publications/s2013-shading-course/lazarov/s2013_pbs_black_ops_2_notes.pdf
|
||||
return fSpecular * blinn * (shininess * 0.125 + 0.25) * vis;
|
||||
#endif
|
||||
|
||||
return vec3(0.0);
|
||||
float vis = CalcVisibility(NH, NL, NE, EH, gloss);
|
||||
|
||||
return fSpecular * (distrib * vis);
|
||||
}
|
||||
|
||||
|
||||
float CalcLightAttenuation(vec3 dir, float sqrRadius)
|
||||
float CalcLightAttenuation(float point, float normDist)
|
||||
{
|
||||
// point light at >0 radius, directional otherwise
|
||||
float point = float(sqrRadius > 0.0);
|
||||
|
||||
// inverse square light
|
||||
float attenuation = sqrRadius / dot(dir, dir);
|
||||
|
||||
// zero light at radius, approximating q3 style
|
||||
// zero light at 1.0, approximating q3 style
|
||||
// also don't attenuate directional light
|
||||
attenuation = (0.5 * attenuation - 1.5) * point + 1.0;
|
||||
|
||||
float attenuation = (0.5 * normDist - 1.5) * point + 1.0;
|
||||
|
||||
// clamp attenuation
|
||||
#if defined(NO_LIGHT_CLAMP)
|
||||
attenuation *= float(attenuation > 0.0);
|
||||
attenuation = max(attenuation, 0.0);
|
||||
#else
|
||||
attenuation = clamp(attenuation, 0.0, 1.0);
|
||||
#endif
|
||||
|
||||
|
||||
return attenuation;
|
||||
}
|
||||
|
||||
// from http://www.thetenthplanet.de/archives/1180
|
||||
mat3 cotangent_frame( vec3 N, vec3 p, vec2 uv )
|
||||
{
|
||||
// get edge vectors of the pixel triangle
|
||||
vec3 dp1 = dFdx( p );
|
||||
vec3 dp2 = dFdy( p );
|
||||
vec2 duv1 = dFdx( uv );
|
||||
vec2 duv2 = dFdy( uv );
|
||||
|
||||
// solve the linear system
|
||||
vec3 dp2perp = cross( dp2, N );
|
||||
vec3 dp1perp = cross( N, dp1 );
|
||||
vec3 T = dp2perp * duv1.x + dp1perp * duv2.x;
|
||||
vec3 B = dp2perp * duv1.y + dp1perp * duv2.y;
|
||||
|
||||
// construct a scale-invariant frame
|
||||
float invmax = inversesqrt( max( dot(T,T), dot(B,B) ) );
|
||||
return mat3( T * invmax, B * invmax, N );
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
vec3 L, N, E, H;
|
||||
float NL, NH, NE, EH;
|
||||
|
||||
#if (defined(USE_LIGHT) && !defined(USE_FAST_LIGHT)) || defined(USE_PARALLAXMAP)
|
||||
mat3 tangentToWorld = mat3(var_Tangent, var_Bitangent, var_Normal);
|
||||
#endif
|
||||
|
||||
#if defined(USE_DELUXEMAP)
|
||||
L = (2.0 * texture2D(u_DeluxeMap, var_LightTex).xyz - vec3(1.0));
|
||||
#if defined(USE_TANGENT_SPACE_LIGHT)
|
||||
L = L * tangentToWorld;
|
||||
#if defined(USE_LIGHT) && !defined(USE_FAST_LIGHT)
|
||||
#if defined(USE_VERT_TANGENT_SPACE)
|
||||
mat3 tangentToWorld = mat3(var_Tangent.xyz, var_Bitangent.xyz, var_Normal.xyz);
|
||||
E = vec3(var_Normal.w, var_Tangent.w, var_Bitangent.w);
|
||||
#else
|
||||
mat3 tangentToWorld = cotangent_frame(var_Normal, -var_ViewDir, var_TexCoords.xy);
|
||||
E = var_ViewDir;
|
||||
#endif
|
||||
#elif defined(USE_LIGHT) && !defined(USE_FAST_LIGHT)
|
||||
L = var_LightDir.xyz;
|
||||
#endif
|
||||
|
||||
#if (defined(USE_LIGHT) && !defined(USE_FAST_LIGHT)) || defined(USE_PARALLAXMAP)
|
||||
E = normalize(var_ViewDir);
|
||||
E = normalize(E);
|
||||
|
||||
L = var_LightDir.xyz;
|
||||
#if defined(USE_DELUXEMAP)
|
||||
L += (texture2D(u_DeluxeMap, var_TexCoords.zw).xyz - vec3(0.5)) * u_EnableTextures.y;
|
||||
#endif
|
||||
float sqrLightDist = dot(L, L);
|
||||
#endif
|
||||
|
||||
#if defined(USE_LIGHTMAP)
|
||||
vec4 lightSample = texture2D(u_LightMap, var_LightTex).rgba;
|
||||
#if defined(RGBM_LIGHTMAP)
|
||||
lightSample.rgb *= 32.0 * lightSample.a;
|
||||
#endif
|
||||
vec4 lightSample = texture2D(u_LightMap, var_TexCoords.zw);
|
||||
vec3 lightColor = lightSample.rgb;
|
||||
#if defined(RGBM_LIGHTMAP)
|
||||
lightColor *= 32.0 * lightSample.a;
|
||||
#endif
|
||||
#elif defined(USE_LIGHT_VECTOR) && !defined(USE_FAST_LIGHT)
|
||||
vec3 lightColor = u_DirectedLight * CalcLightAttenuation(L, u_LightRadius * u_LightRadius);
|
||||
vec3 lightColor = u_DirectedLight * CalcLightAttenuation(float(var_LightDir.w > 0.0), var_LightDir.w / sqrLightDist);
|
||||
vec3 ambientColor = u_AmbientLight;
|
||||
#elif defined(USE_LIGHT_VERTEX) && !defined(USE_FAST_LIGHT)
|
||||
vec3 lightColor = var_lightColor;
|
||||
vec3 lightColor = var_LightColor;
|
||||
#endif
|
||||
|
||||
vec2 texCoords = var_DiffuseTex;
|
||||
vec2 texCoords = var_TexCoords.xy;
|
||||
|
||||
#if defined(USE_PARALLAXMAP)
|
||||
#if defined(USE_TANGENT_SPACE_LIGHT)
|
||||
vec3 offsetDir = E;
|
||||
#else
|
||||
vec3 offsetDir = E * tangentToWorld;
|
||||
#endif
|
||||
vec3 offsetDir = normalize(E * tangentToWorld);
|
||||
|
||||
offsetDir.xy *= -0.05 / offsetDir.z;
|
||||
|
||||
|
@ -335,49 +366,42 @@ void main()
|
|||
#endif
|
||||
|
||||
vec4 diffuse = texture2D(u_DiffuseMap, texCoords);
|
||||
#if defined(USE_GAMMA2_TEXTURES)
|
||||
diffuse.rgb *= diffuse.rgb;
|
||||
#endif
|
||||
|
||||
|
||||
#if defined(USE_LIGHT) && !defined(USE_FAST_LIGHT)
|
||||
|
||||
#if defined(USE_LINEAR_LIGHT)
|
||||
diffuse.rgb *= diffuse.rgb;
|
||||
#endif
|
||||
|
||||
#if defined(USE_NORMALMAP)
|
||||
#if defined(SWIZZLE_NORMALMAP)
|
||||
N.xy = 2.0 * texture2D(u_NormalMap, texCoords).ag - vec2(1.0);
|
||||
N.xy = texture2D(u_NormalMap, texCoords).ag - vec2(0.5);
|
||||
#else
|
||||
N.xy = 2.0 * texture2D(u_NormalMap, texCoords).rg - vec2(1.0);
|
||||
N.xy = texture2D(u_NormalMap, texCoords).rg - vec2(0.5);
|
||||
#endif
|
||||
N.z = sqrt(1.0 - clamp(dot(N.xy, N.xy), 0.0, 1.0));
|
||||
#if !defined(USE_TANGENT_SPACE_LIGHT)
|
||||
N = normalize(tangentToWorld * N);
|
||||
#endif
|
||||
#elif defined(USE_TANGENT_SPACE_LIGHT)
|
||||
N = vec3(0.0, 0.0, 1.0);
|
||||
N.xy *= u_EnableTextures.x;
|
||||
N.z = sqrt((0.25 - N.x * N.x) - N.y * N.y);
|
||||
N = tangentToWorld * N;
|
||||
#else
|
||||
N = normalize(var_Normal);
|
||||
N = var_Normal.xyz;
|
||||
#endif
|
||||
|
||||
L = normalize(L);
|
||||
|
||||
N = normalize(N);
|
||||
L /= sqrt(sqrLightDist);
|
||||
|
||||
#if defined(USE_SHADOWMAP)
|
||||
vec2 shadowTex = gl_FragCoord.xy * r_FBufScale;
|
||||
float shadowValue = texture2D(u_ShadowMap, shadowTex).r;
|
||||
|
||||
// surfaces not facing the light are always shadowed
|
||||
#if defined(USE_TANGENT_SPACE_LIGHT)
|
||||
shadowValue *= float(var_PrimaryLightDir.z > 0.0);
|
||||
#else
|
||||
shadowValue *= float(dot(var_Normal, var_PrimaryLightDir) > 0.0);
|
||||
#endif
|
||||
|
||||
shadowValue *= float(dot(var_Normal.xyz, var_PrimaryLightDir.xyz) > 0.0);
|
||||
|
||||
#if defined(SHADOWMAP_MODULATE)
|
||||
//vec3 shadowColor = min(u_PrimaryLightAmbient, lightColor);
|
||||
vec3 shadowColor = u_PrimaryLightAmbient * lightColor;
|
||||
|
||||
#if 0
|
||||
// Only shadow when the world light is parallel to the primary light
|
||||
shadowValue = 1.0 + (shadowValue - 1.0) * clamp(dot(L, var_PrimaryLightDir), 0.0, 1.0);
|
||||
shadowValue = 1.0 + (shadowValue - 1.0) * clamp(dot(L, var_PrimaryLightDir.xyz), 0.0, 1.0);
|
||||
#endif
|
||||
lightColor = mix(shadowColor, lightColor, shadowValue);
|
||||
#endif
|
||||
|
@ -385,12 +409,7 @@ void main()
|
|||
|
||||
#if defined(USE_LIGHTMAP) || defined(USE_LIGHT_VERTEX)
|
||||
vec3 ambientColor = lightColor;
|
||||
|
||||
#if defined(USE_TANGENT_SPACE_LIGHT)
|
||||
float surfNL = L.z;
|
||||
#else
|
||||
float surfNL = clamp(dot(var_Normal, L), 0.0, 1.0);
|
||||
#endif
|
||||
float surfNL = clamp(dot(var_Normal.xyz, L), 0.0, 1.0);
|
||||
|
||||
// Scale the incoming light to compensate for the baked-in light angle
|
||||
// attenuation.
|
||||
|
@ -406,105 +425,104 @@ void main()
|
|||
NL = clamp(dot(N, L), 0.0, 1.0);
|
||||
NE = clamp(dot(N, E), 0.0, 1.0);
|
||||
|
||||
#if defined(USE_SPECULARMAP)
|
||||
vec4 specular = texture2D(u_SpecularMap, texCoords);
|
||||
#if defined(USE_LINEAR_LIGHT)
|
||||
specular.rgb *= specular.rgb;
|
||||
#endif
|
||||
#else
|
||||
vec4 specular = vec4(1.0);
|
||||
#if defined(USE_SPECULARMAP)
|
||||
specular += texture2D(u_SpecularMap, texCoords) * u_EnableTextures.z - u_EnableTextures.zzzz;
|
||||
#if defined(USE_GAMMA2_TEXTURES)
|
||||
specular.rgb *= specular.rgb;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
specular *= u_MaterialInfo.xxxy;
|
||||
|
||||
|
||||
float gloss = specular.a;
|
||||
float shininess = exp2(gloss * 13.0);
|
||||
float localOcclusion = clamp((diffuse.r + diffuse.g + diffuse.b) * 16.0f, 0.0, 1.0);
|
||||
|
||||
#if defined(SPECULAR_IS_METALLIC)
|
||||
// diffuse is actually base color, and red of specular is metallicness
|
||||
// diffuse is actually base color, and red of specular is metallicness
|
||||
float metallic = specular.r;
|
||||
|
||||
specular.rgb = vec3(0.04) + 0.96 * diffuse.rgb * metallic;
|
||||
|
||||
specular.rgb = (0.96 * metallic) * diffuse.rgb + vec3(0.04);
|
||||
diffuse.rgb *= 1.0 - metallic;
|
||||
#else
|
||||
// adjust diffuse by specular reflectance, to maintain energy conservation
|
||||
diffuse.rgb *= vec3(1.0) - specular.rgb;
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
reflectance = CalcDiffuse(diffuse.rgb, N, L, E, NE, NL, shininess);
|
||||
|
||||
#if defined(r_deluxeSpecular) || defined(USE_LIGHT_VECTOR)
|
||||
float adjGloss = gloss;
|
||||
float adjShininess = shininess;
|
||||
|
||||
#if !defined(USE_LIGHT_VECTOR)
|
||||
adjShininess = exp2(gloss * r_deluxeSpecular * 13.0);
|
||||
#endif
|
||||
|
||||
|
||||
#if !defined(USE_LIGHT_VECTOR)
|
||||
adjGloss *= r_deluxeSpecular;
|
||||
adjShininess = exp2(adjGloss * 13.0);
|
||||
#endif
|
||||
|
||||
H = normalize(L + E);
|
||||
|
||||
EH = clamp(dot(E, H), 0.0, 1.0);
|
||||
NH = clamp(dot(N, H), 0.0, 1.0);
|
||||
|
||||
#if !defined(USE_LIGHT_VECTOR)
|
||||
reflectance += CalcSpecular(specular.rgb, NH, NL, NE, EH, adjShininess) * r_deluxeSpecular * localOcclusion;
|
||||
reflectance += CalcSpecular(specular.rgb, NH, NL, NE, EH, adjGloss, adjShininess) * r_deluxeSpecular;
|
||||
#else
|
||||
reflectance += CalcSpecular(specular.rgb, NH, NL, NE, EH, adjShininess) * localOcclusion;
|
||||
reflectance += CalcSpecular(specular.rgb, NH, NL, NE, EH, adjGloss, adjShininess);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
gl_FragColor.rgb = lightColor * reflectance * NL;
|
||||
|
||||
gl_FragColor.rgb = lightColor * reflectance * NL;
|
||||
gl_FragColor.rgb += ambientColor * (diffuse.rgb + specular.rgb);
|
||||
|
||||
|
||||
#if defined(USE_CUBEMAP)
|
||||
reflectance = EnvironmentBRDF(gloss, NE, specular.rgb);
|
||||
|
||||
vec3 R = reflect(E, N);
|
||||
#if defined(USE_TANGENT_SPACE_LIGHT)
|
||||
R = tangentToWorld * R;
|
||||
#endif
|
||||
|
||||
vec3 cubeLightColor = textureCubeLod(u_CubeMap, R, 7.0 - gloss * 7.0).rgb;
|
||||
|
||||
#if defined(USE_LINEAR_LIGHT)
|
||||
cubeLightColor *= cubeLightColor;
|
||||
#endif
|
||||
vec3 cubeLightColor = textureCubeLod(u_CubeMap, R, 7.0 - gloss * 7.0).rgb * u_EnableTextures.w;
|
||||
|
||||
#if defined(USE_LIGHTMAP)
|
||||
cubeLightColor *= lightSample.rgb;
|
||||
#elif defined (USE_LIGHT_VERTEX)
|
||||
cubeLightColor *= var_lightColor;
|
||||
cubeLightColor *= var_LightColor;
|
||||
#else
|
||||
cubeLightColor *= lightColor * NL + ambientColor;
|
||||
#endif
|
||||
|
||||
//gl_FragColor.rgb += diffuse.rgb * textureCubeLod(u_CubeMap, N, 7.0).rgb;
|
||||
gl_FragColor.rgb += cubeLightColor * reflectance * localOcclusion;
|
||||
|
||||
//gl_FragColor.rgb += diffuse.rgb * textureCubeLod(u_CubeMap, N, 7.0).rgb * u_EnableTextures.w;
|
||||
gl_FragColor.rgb += cubeLightColor * reflectance;
|
||||
#endif
|
||||
|
||||
#if defined(USE_PRIMARY_LIGHT)
|
||||
L = normalize(var_PrimaryLightDir);
|
||||
NL = clamp(dot(N, L), 0.0, 1.0);
|
||||
vec3 L2, H2;
|
||||
float NL2, EH2, NH2;
|
||||
|
||||
H = normalize(L + E);
|
||||
EH = clamp(dot(E, H), 0.0, 1.0);
|
||||
NH = clamp(dot(N, H), 0.0, 1.0);
|
||||
L2 = var_PrimaryLightDir.xyz;
|
||||
|
||||
reflectance = CalcDiffuse(diffuse.rgb, N, L, E, NE, NL, shininess);
|
||||
reflectance += CalcSpecular(specular.rgb, NH, NL, NE, EH, shininess);
|
||||
// enable when point lights are supported as primary lights
|
||||
//sqrLightDist = dot(L2, L2);
|
||||
//L2 /= sqrt(sqrLightDist);
|
||||
|
||||
NL2 = clamp(dot(N, L2), 0.0, 1.0);
|
||||
|
||||
H2 = normalize(L2 + E);
|
||||
EH2 = clamp(dot(E, H2), 0.0, 1.0);
|
||||
NH2 = clamp(dot(N, H2), 0.0, 1.0);
|
||||
|
||||
reflectance = CalcDiffuse(diffuse.rgb, N, L2, E, NE, NL2, shininess);
|
||||
reflectance += CalcSpecular(specular.rgb, NH2, NL2, NE, EH2, gloss, shininess);
|
||||
|
||||
lightColor = u_PrimaryLightColor;
|
||||
|
||||
// enable when point lights are supported as primary lights
|
||||
//lightColor *= CalcLightAttenuation(float(u_PrimaryLightDir.w > 0.0), u_PrimaryLightDir.w / sqrLightDist);
|
||||
|
||||
lightColor = u_PrimaryLightColor; // * CalcLightAttenuation(L, u_PrimaryLightRadius * u_PrimaryLightRadius);
|
||||
|
||||
#if defined(USE_SHADOWMAP)
|
||||
lightColor *= shadowValue;
|
||||
#endif
|
||||
|
||||
gl_FragColor.rgb += lightColor * reflectance * NL;
|
||||
#endif
|
||||
|
||||
#if defined(USE_LINEAR_LIGHT)
|
||||
gl_FragColor.rgb = sqrt(gl_FragColor.rgb);
|
||||
gl_FragColor.rgb += lightColor * reflectance * NL2;
|
||||
#endif
|
||||
|
||||
gl_FragColor.a = diffuse.a;
|
||||
|
|
|
@ -6,21 +6,27 @@ attribute vec4 attr_Color;
|
|||
|
||||
attribute vec3 attr_Position;
|
||||
attribute vec3 attr_Normal;
|
||||
attribute vec3 attr_Tangent;
|
||||
attribute vec3 attr_Bitangent;
|
||||
#if defined(USE_VERT_TANGENT_SPACE)
|
||||
attribute vec4 attr_Tangent;
|
||||
#endif
|
||||
|
||||
#if defined(USE_VERTEX_ANIMATION)
|
||||
attribute vec3 attr_Position2;
|
||||
attribute vec3 attr_Normal2;
|
||||
attribute vec3 attr_Tangent2;
|
||||
attribute vec3 attr_Bitangent2;
|
||||
#if defined(USE_VERT_TANGENT_SPACE)
|
||||
attribute vec4 attr_Tangent2;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(USE_LIGHT) && !defined(USE_LIGHT_VECTOR)
|
||||
attribute vec3 attr_LightDirection;
|
||||
#endif
|
||||
|
||||
#if defined(USE_TCGEN) || defined(USE_NORMALMAP) || defined(USE_LIGHT) && !defined(USE_FAST_LIGHT)
|
||||
#if defined(USE_DELUXEMAP)
|
||||
uniform vec4 u_EnableTextures; // x = normal, y = deluxe, z = specular, w = cube
|
||||
#endif
|
||||
|
||||
#if defined(USE_LIGHT) && !defined(USE_FAST_LIGHT)
|
||||
uniform vec3 u_ViewOrigin;
|
||||
#endif
|
||||
|
||||
|
@ -28,6 +34,7 @@ uniform vec3 u_ViewOrigin;
|
|||
uniform int u_TCGen0;
|
||||
uniform vec3 u_TCGen0Vector0;
|
||||
uniform vec3 u_TCGen0Vector1;
|
||||
uniform vec3 u_LocalViewOrigin;
|
||||
#endif
|
||||
|
||||
#if defined(USE_TCMOD)
|
||||
|
@ -49,45 +56,43 @@ uniform float u_VertexLerp;
|
|||
|
||||
#if defined(USE_LIGHT_VECTOR)
|
||||
uniform vec4 u_LightOrigin;
|
||||
uniform float u_LightRadius;
|
||||
#if defined(USE_FAST_LIGHT)
|
||||
uniform vec3 u_DirectedLight;
|
||||
uniform vec3 u_AmbientLight;
|
||||
uniform float u_LightRadius;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(USE_PRIMARY_LIGHT) || defined(USE_SHADOWMAP)
|
||||
uniform vec4 u_PrimaryLightOrigin;
|
||||
uniform float u_PrimaryLightRadius;
|
||||
#endif
|
||||
|
||||
varying vec2 var_DiffuseTex;
|
||||
|
||||
#if defined(USE_LIGHTMAP)
|
||||
varying vec2 var_LightTex;
|
||||
#endif
|
||||
|
||||
#if defined(USE_NORMALMAP) || (defined(USE_LIGHT) && !defined(USE_FAST_LIGHT))
|
||||
varying vec3 var_ViewDir;
|
||||
#endif
|
||||
varying vec4 var_TexCoords;
|
||||
|
||||
varying vec4 var_Color;
|
||||
|
||||
#if (defined(USE_LIGHT) && !defined(USE_FAST_LIGHT)) || defined(USE_PARALLAXMAP)
|
||||
#if defined(USE_LIGHT) && !defined(USE_FAST_LIGHT)
|
||||
#if defined(USE_VERT_TANGENT_SPACE)
|
||||
varying vec4 var_Normal;
|
||||
varying vec4 var_Tangent;
|
||||
varying vec4 var_Bitangent;
|
||||
#else
|
||||
varying vec3 var_Normal;
|
||||
varying vec3 var_Tangent;
|
||||
varying vec3 var_Bitangent;
|
||||
varying vec3 var_ViewDir;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(USE_LIGHT_VERTEX) && !defined(USE_FAST_LIGHT)
|
||||
varying vec3 var_lightColor;
|
||||
varying vec3 var_LightColor;
|
||||
#endif
|
||||
|
||||
#if defined(USE_LIGHT) && !defined(USE_DELUXEMAP) && !defined(USE_FAST_LIGHT)
|
||||
#if defined(USE_LIGHT) && !defined(USE_FAST_LIGHT)
|
||||
varying vec4 var_LightDir;
|
||||
#endif
|
||||
|
||||
#if defined(USE_PRIMARY_LIGHT) || defined(USE_SHADOWMAP)
|
||||
varying vec3 var_PrimaryLightDir;
|
||||
varying vec4 var_PrimaryLightDir;
|
||||
#endif
|
||||
|
||||
#if defined(USE_TCGEN)
|
||||
|
@ -101,14 +106,16 @@ vec2 GenTexCoords(int TCGen, vec3 position, vec3 normal, vec3 TCGenVector0, vec3
|
|||
}
|
||||
else if (TCGen == TCGEN_ENVIRONMENT_MAPPED)
|
||||
{
|
||||
vec3 viewer = normalize(u_ViewOrigin - position);
|
||||
tex = -reflect(viewer, normal).yz * vec2(0.5, -0.5) + 0.5;
|
||||
vec3 viewer = normalize(u_LocalViewOrigin - position);
|
||||
vec2 ref = reflect(viewer, normal).yz;
|
||||
tex.s = ref.x * -0.5 + 0.5;
|
||||
tex.t = ref.y * 0.5 + 0.5;
|
||||
}
|
||||
else if (TCGen == TCGEN_VECTOR)
|
||||
{
|
||||
tex = vec2(dot(position, TCGenVector0), dot(position, TCGenVector1));
|
||||
}
|
||||
|
||||
|
||||
return tex;
|
||||
}
|
||||
#endif
|
||||
|
@ -117,38 +124,33 @@ vec2 GenTexCoords(int TCGen, vec3 position, vec3 normal, vec3 TCGenVector0, vec3
|
|||
vec2 ModTexCoords(vec2 st, vec3 position, vec4 texMatrix, vec4 offTurb)
|
||||
{
|
||||
float amplitude = offTurb.z;
|
||||
float phase = offTurb.w;
|
||||
vec2 st2 = vec2(dot(st, texMatrix.xz), dot(st, texMatrix.yw)) + offTurb.xy;
|
||||
float phase = offTurb.w * 2.0 * M_PI;
|
||||
vec2 st2;
|
||||
st2.x = st.x * texMatrix.x + (st.y * texMatrix.z + offTurb.x);
|
||||
st2.y = st.x * texMatrix.y + (st.y * texMatrix.w + offTurb.y);
|
||||
|
||||
vec2 offsetPos = vec2(position.x + position.z, position.y);
|
||||
|
||||
vec2 texOffset = sin(offsetPos * (2.0 * M_PI / 1024.0) + vec2(phase));
|
||||
|
||||
vec3 offsetPos = position * 0.0009765625;
|
||||
offsetPos.x += offsetPos.z;
|
||||
|
||||
vec2 texOffset = sin((offsetPos.xy + vec2(phase)) * 2.0 * M_PI);
|
||||
|
||||
return st2 + texOffset * amplitude;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
float CalcLightAttenuation(vec3 dir, float sqrRadius)
|
||||
float CalcLightAttenuation(float point, float normDist)
|
||||
{
|
||||
// point light at >0 radius, directional otherwise
|
||||
float point = float(sqrRadius > 0.0);
|
||||
|
||||
// inverse square light
|
||||
float attenuation = sqrRadius / dot(dir, dir);
|
||||
|
||||
// zero light at radius, approximating q3 style
|
||||
// zero light at 1.0, approximating q3 style
|
||||
// also don't attenuate directional light
|
||||
attenuation = (0.5 * attenuation - 1.5) * point + 1.0;
|
||||
|
||||
float attenuation = (0.5 * normDist - 1.5) * point + 1.0;
|
||||
|
||||
// clamp attenuation
|
||||
#if defined(NO_LIGHT_CLAMP)
|
||||
attenuation *= float(attenuation > 0.0);
|
||||
attenuation = max(attenuation, 0.0);
|
||||
#else
|
||||
attenuation = clamp(attenuation, 0.0, 1.0);
|
||||
#endif
|
||||
|
||||
|
||||
return attenuation;
|
||||
}
|
||||
|
||||
|
@ -156,15 +158,22 @@ float CalcLightAttenuation(vec3 dir, float sqrRadius)
|
|||
void main()
|
||||
{
|
||||
#if defined(USE_VERTEX_ANIMATION)
|
||||
vec3 position = mix(attr_Position, attr_Position2, u_VertexLerp);
|
||||
vec3 normal = normalize(mix(attr_Normal, attr_Normal2, u_VertexLerp));
|
||||
vec3 tangent = normalize(mix(attr_Tangent, attr_Tangent2, u_VertexLerp));
|
||||
vec3 bitangent = normalize(mix(attr_Bitangent, attr_Bitangent2, u_VertexLerp));
|
||||
vec3 position = mix(attr_Position, attr_Position2, u_VertexLerp);
|
||||
vec3 normal = mix(attr_Normal, attr_Normal2, u_VertexLerp);
|
||||
#if defined(USE_VERT_TANGENT_SPACE) && defined(USE_LIGHT) && !defined(USE_FAST_LIGHT)
|
||||
vec3 tangent = mix(attr_Tangent.xyz, attr_Tangent2.xyz, u_VertexLerp);
|
||||
#endif
|
||||
#else
|
||||
vec3 position = attr_Position;
|
||||
vec3 normal = attr_Normal;
|
||||
vec3 tangent = attr_Tangent;
|
||||
vec3 bitangent = attr_Bitangent;
|
||||
#if defined(USE_VERT_TANGENT_SPACE) && defined(USE_LIGHT) && !defined(USE_FAST_LIGHT)
|
||||
vec3 tangent = attr_Tangent.xyz;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
normal = normal * 2.0 - vec3(1.0);
|
||||
#if defined(USE_VERT_TANGENT_SPACE) && defined(USE_LIGHT) && !defined(USE_FAST_LIGHT)
|
||||
tangent = tangent * 2.0 - vec3(1.0);
|
||||
#endif
|
||||
|
||||
#if defined(USE_TCGEN)
|
||||
|
@ -174,83 +183,78 @@ void main()
|
|||
#endif
|
||||
|
||||
#if defined(USE_TCMOD)
|
||||
var_DiffuseTex = ModTexCoords(texCoords, position, u_DiffuseTexMatrix, u_DiffuseTexOffTurb);
|
||||
var_TexCoords.xy = ModTexCoords(texCoords, position, u_DiffuseTexMatrix, u_DiffuseTexOffTurb);
|
||||
#else
|
||||
var_DiffuseTex = texCoords;
|
||||
var_TexCoords.xy = texCoords;
|
||||
#endif
|
||||
|
||||
gl_Position = u_ModelViewProjectionMatrix * vec4(position, 1.0);
|
||||
|
||||
#if defined(USE_MODELMATRIX)
|
||||
position = (u_ModelMatrix * vec4(position, 1.0)).xyz;
|
||||
normal = (u_ModelMatrix * vec4(normal, 0.0)).xyz;
|
||||
tangent = (u_ModelMatrix * vec4(tangent, 0.0)).xyz;
|
||||
bitangent = (u_ModelMatrix * vec4(bitangent, 0.0)).xyz;
|
||||
position = (u_ModelMatrix * vec4(position, 1.0)).xyz;
|
||||
normal = (u_ModelMatrix * vec4(normal, 0.0)).xyz;
|
||||
#if defined(USE_VERT_TANGENT_SPACE) && defined(USE_LIGHT) && !defined(USE_FAST_LIGHT)
|
||||
tangent = (u_ModelMatrix * vec4(tangent, 0.0)).xyz;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(USE_VERT_TANGENT_SPACE) && defined(USE_LIGHT) && !defined(USE_FAST_LIGHT)
|
||||
vec3 bitangent = cross(normal, tangent) * (attr_Tangent.w * 2.0 - 1.0);
|
||||
#endif
|
||||
|
||||
#if defined(USE_LIGHT_VECTOR)
|
||||
vec3 L = u_LightOrigin.xyz - (position * u_LightOrigin.w);
|
||||
#elif defined(USE_LIGHT) && !defined(USE_LIGHT_VECTOR)
|
||||
vec3 L = attr_LightDirection;
|
||||
#elif defined(USE_LIGHT) && !defined(USE_FAST_LIGHT)
|
||||
vec3 L = attr_LightDirection * 2.0 - vec3(1.0);
|
||||
#if defined(USE_MODELMATRIX)
|
||||
L = (u_ModelMatrix * vec4(L, 0.0)).xyz;
|
||||
L = (u_ModelMatrix * vec4(L, 0.0)).xyz;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(USE_LIGHTMAP)
|
||||
var_LightTex = attr_TexCoord1.st;
|
||||
var_TexCoords.zw = attr_TexCoord1.st;
|
||||
#endif
|
||||
|
||||
#if defined(USE_LIGHT_VERTEX) && !defined(USE_FAST_LIGHT)
|
||||
var_lightColor = u_VertColor.rgb * attr_Color.rgb;
|
||||
var_Color.rgb = vec3(1.0);
|
||||
var_Color.a = u_VertColor.a * attr_Color.a + u_BaseColor.a;
|
||||
#else
|
||||
|
||||
var_Color = u_VertColor * attr_Color + u_BaseColor;
|
||||
#if defined(USE_LIGHT_VERTEX) && !defined(USE_FAST_LIGHT)
|
||||
var_LightColor = var_Color.rgb;
|
||||
var_Color.rgb = vec3(1.0);
|
||||
#endif
|
||||
|
||||
#if defined(USE_LIGHT_VECTOR) && defined(USE_FAST_LIGHT)
|
||||
float attenuation = CalcLightAttenuation(L, u_LightRadius * u_LightRadius);
|
||||
float NL = clamp(dot(normal, normalize(L)), 0.0, 1.0);
|
||||
float sqrLightDist = dot(L, L);
|
||||
float attenuation = CalcLightAttenuation(u_LightOrigin.w, u_LightRadius * u_LightRadius / sqrLightDist);
|
||||
float NL = clamp(dot(normalize(normal), L) / sqrt(sqrLightDist), 0.0, 1.0);
|
||||
|
||||
var_Color.rgb *= u_DirectedLight * attenuation * NL + u_AmbientLight;
|
||||
#endif
|
||||
|
||||
#if (defined(USE_LIGHT) && !defined(USE_FAST_LIGHT)) || defined(USE_PARALLAXMAP)
|
||||
var_Normal = normal;
|
||||
var_Tangent = tangent;
|
||||
var_Bitangent = bitangent;
|
||||
var_Color.rgb *= u_DirectedLight * (attenuation * NL) + u_AmbientLight;
|
||||
#endif
|
||||
|
||||
#if defined(USE_PRIMARY_LIGHT) || defined(USE_SHADOWMAP)
|
||||
var_PrimaryLightDir = (u_PrimaryLightOrigin.xyz - (position * u_PrimaryLightOrigin.w));
|
||||
var_PrimaryLightDir.xyz = u_PrimaryLightOrigin.xyz - (position * u_PrimaryLightOrigin.w);
|
||||
var_PrimaryLightDir.w = u_PrimaryLightRadius * u_PrimaryLightRadius;
|
||||
#endif
|
||||
|
||||
#if defined(USE_LIGHT) && !defined(USE_DELUXEMAP) && !defined(USE_FAST_LIGHT)
|
||||
#if defined(USE_LIGHT) && !defined(USE_FAST_LIGHT)
|
||||
#if defined(USE_LIGHT_VECTOR)
|
||||
var_LightDir = vec4(L, u_LightOrigin.w);
|
||||
var_LightDir = vec4(L, u_LightRadius * u_LightRadius);
|
||||
#else
|
||||
var_LightDir = vec4(L, 0.0);
|
||||
#endif
|
||||
#if defined(USE_DELUXEMAP)
|
||||
var_LightDir -= u_EnableTextures.y * var_LightDir;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(USE_NORMALMAP) || (defined(USE_LIGHT) && !defined(USE_FAST_LIGHT))
|
||||
var_ViewDir = (u_ViewOrigin - position);
|
||||
#endif
|
||||
|
||||
#if defined(USE_TANGENT_SPACE_LIGHT)
|
||||
mat3 tangentToWorld = mat3(tangent, bitangent, normal);
|
||||
|
||||
#if defined(USE_PRIMARY_LIGHT) || defined(USE_SHADOWMAP)
|
||||
var_PrimaryLightDir = var_PrimaryLightDir * tangentToWorld;
|
||||
#endif
|
||||
|
||||
#if defined(USE_LIGHT) && !defined(USE_DELUXEMAP) && !defined(USE_FAST_LIGHT)
|
||||
var_LightDir.xyz = var_LightDir.xyz * tangentToWorld;
|
||||
#endif
|
||||
|
||||
#if defined(USE_NORMALMAP) || (defined(USE_LIGHT) && !defined(USE_FAST_LIGHT))
|
||||
var_ViewDir = var_ViewDir * tangentToWorld;
|
||||
#if defined(USE_LIGHT) && !defined(USE_FAST_LIGHT)
|
||||
vec3 viewDir = u_ViewOrigin - position;
|
||||
#if defined(USE_VERT_TANGENT_SPACE)
|
||||
// store view direction in tangent space to save on varyings
|
||||
var_Normal = vec4(normal, viewDir.x);
|
||||
var_Tangent = vec4(tangent, viewDir.y);
|
||||
var_Bitangent = vec4(bitangent, viewDir.z);
|
||||
#else
|
||||
var_Normal = normal;
|
||||
var_ViewDir = viewDir;
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
attribute vec4 attr_Position;
|
||||
attribute vec3 attr_Position;
|
||||
attribute vec3 attr_Normal;
|
||||
|
||||
uniform mat4 u_ModelViewProjectionMatrix;
|
||||
|
@ -8,10 +8,8 @@ varying vec3 var_Normal;
|
|||
|
||||
void main()
|
||||
{
|
||||
vec4 position = attr_Position;
|
||||
gl_Position = u_ModelViewProjectionMatrix * vec4(attr_Position, 1.0);
|
||||
|
||||
gl_Position = u_ModelViewProjectionMatrix * position;
|
||||
|
||||
var_Position = position.xyz;
|
||||
var_Normal = attr_Normal;
|
||||
var_Position = attr_Position;
|
||||
var_Normal = attr_Normal * 2.0 - vec3(1.0);
|
||||
}
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
attribute vec4 attr_Position;
|
||||
attribute vec3 attr_Position;
|
||||
attribute vec3 attr_Normal;
|
||||
attribute vec4 attr_TexCoord0;
|
||||
|
||||
//#if defined(USE_VERTEX_ANIMATION)
|
||||
attribute vec4 attr_Position2;
|
||||
attribute vec3 attr_Position2;
|
||||
attribute vec3 attr_Normal2;
|
||||
//#endif
|
||||
|
||||
|
@ -38,7 +38,7 @@ vec3 DeformPosition(const vec3 pos, const vec3 normal, const vec2 st)
|
|||
|
||||
if (u_DeformGen == DGEN_BULGE)
|
||||
{
|
||||
phase *= M_PI * 0.25 * st.x;
|
||||
phase *= st.x;
|
||||
}
|
||||
else // if (u_DeformGen <= DGEN_WAVE_INVERSE_SAWTOOTH)
|
||||
{
|
||||
|
@ -54,7 +54,7 @@ vec3 DeformPosition(const vec3 pos, const vec3 normal, const vec2 st)
|
|||
}
|
||||
else if (u_DeformGen == DGEN_WAVE_SQUARE)
|
||||
{
|
||||
func = sign(sin(value * 2.0 * M_PI));
|
||||
func = sign(0.5 - fract(value));
|
||||
}
|
||||
else if (u_DeformGen == DGEN_WAVE_TRIANGLE)
|
||||
{
|
||||
|
@ -68,7 +68,7 @@ vec3 DeformPosition(const vec3 pos, const vec3 normal, const vec2 st)
|
|||
{
|
||||
func = (1.0 - fract(value));
|
||||
}
|
||||
else if (u_DeformGen == DGEN_BULGE)
|
||||
else // if (u_DeformGen == DGEN_BULGE)
|
||||
{
|
||||
func = sin(value);
|
||||
}
|
||||
|
@ -78,12 +78,13 @@ vec3 DeformPosition(const vec3 pos, const vec3 normal, const vec2 st)
|
|||
|
||||
void main()
|
||||
{
|
||||
vec4 position = mix(attr_Position, attr_Position2, u_VertexLerp);
|
||||
vec3 normal = normalize(mix(attr_Normal, attr_Normal2, u_VertexLerp));
|
||||
vec3 position = mix(attr_Position, attr_Position2, u_VertexLerp);
|
||||
vec3 normal = mix(attr_Normal, attr_Normal2, u_VertexLerp);
|
||||
normal = normalize(normal - vec3(0.5));
|
||||
|
||||
position.xyz = DeformPosition(position.xyz, normal, attr_TexCoord0.st);
|
||||
position = DeformPosition(position, normal, attr_TexCoord0.st);
|
||||
|
||||
gl_Position = u_ModelViewProjectionMatrix * position;
|
||||
gl_Position = u_ModelViewProjectionMatrix * vec4(position, 1.0);
|
||||
|
||||
var_Position = (u_ModelMatrix * position).xyz;
|
||||
var_Position = (u_ModelMatrix * vec4(position, 1.0)).xyz;
|
||||
}
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
uniform sampler2D u_DiffuseMap;
|
||||
uniform vec4 u_Color;
|
||||
|
||||
varying vec2 var_Tex1;
|
||||
varying vec2 var_Tex1;
|
||||
|
||||
|
||||
void main()
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
#version 120
|
||||
|
||||
attribute vec4 attr_Position;
|
||||
attribute vec3 attr_Position;
|
||||
attribute vec4 attr_TexCoord0;
|
||||
|
||||
uniform mat4 u_ModelViewProjectionMatrix;
|
||||
|
@ -10,6 +10,6 @@ varying vec2 var_Tex1;
|
|||
|
||||
void main()
|
||||
{
|
||||
gl_Position = u_ModelViewProjectionMatrix * attr_Position;
|
||||
gl_Position = u_ModelViewProjectionMatrix * vec4(attr_Position, 1.0);
|
||||
var_Tex1 = attr_TexCoord0.st;
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
attribute vec4 attr_Position;
|
||||
attribute vec3 attr_Position;
|
||||
attribute vec4 attr_TexCoord0;
|
||||
|
||||
uniform mat4 u_ModelViewProjectionMatrix;
|
||||
|
@ -8,6 +8,6 @@ varying vec2 var_TexCoords;
|
|||
|
||||
void main()
|
||||
{
|
||||
gl_Position = u_ModelViewProjectionMatrix * attr_Position;
|
||||
gl_Position = u_ModelViewProjectionMatrix * vec4(attr_Position, 1.0);
|
||||
var_TexCoords = attr_TexCoord0.st;
|
||||
}
|
||||
|
|
|
@ -33,143 +33,6 @@ frame.
|
|||
|
||||
*/
|
||||
|
||||
/*
|
||||
==============
|
||||
R_AddAnimSurfaces
|
||||
==============
|
||||
*/
|
||||
void R_AddAnimSurfaces( trRefEntity_t *ent ) {
|
||||
md4Header_t *header;
|
||||
md4Surface_t *surface;
|
||||
md4LOD_t *lod;
|
||||
shader_t *shader;
|
||||
int cubemapIndex;
|
||||
int i;
|
||||
|
||||
header = (md4Header_t *) tr.currentModel->modelData;
|
||||
lod = (md4LOD_t *)( (byte *)header + header->ofsLODs );
|
||||
cubemapIndex = R_CubemapForPoint(ent->e.origin);
|
||||
|
||||
surface = (md4Surface_t *)( (byte *)lod + lod->ofsSurfaces );
|
||||
for ( i = 0 ; i < lod->numSurfaces ; i++ ) {
|
||||
shader = R_GetShaderByHandle( surface->shaderIndex );
|
||||
R_AddDrawSurf( (void *)surface, shader, 0 /*fogNum*/, qfalse, qfalse, cubemapIndex );
|
||||
surface = (md4Surface_t *)( (byte *)surface + surface->ofsEnd );
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
==============
|
||||
RB_SurfaceAnim
|
||||
==============
|
||||
*/
|
||||
void RB_SurfaceAnim( md4Surface_t *surface ) {
|
||||
int i, j, k;
|
||||
float frontlerp, backlerp;
|
||||
int *triangles;
|
||||
int indexes;
|
||||
int baseIndex, baseVertex;
|
||||
int numVerts;
|
||||
md4Vertex_t *v;
|
||||
md4Bone_t bones[MD4_MAX_BONES];
|
||||
md4Bone_t *bonePtr, *bone;
|
||||
md4Header_t *header;
|
||||
md4Frame_t *frame;
|
||||
md4Frame_t *oldFrame;
|
||||
int frameSize;
|
||||
|
||||
|
||||
if ( backEnd.currentEntity->e.oldframe == backEnd.currentEntity->e.frame ) {
|
||||
backlerp = 0;
|
||||
frontlerp = 1;
|
||||
} else {
|
||||
backlerp = backEnd.currentEntity->e.backlerp;
|
||||
frontlerp = 1.0f - backlerp;
|
||||
}
|
||||
header = (md4Header_t *)((byte *)surface + surface->ofsHeader);
|
||||
|
||||
frameSize = (size_t)( &((md4Frame_t *)0)->bones[ header->numBones ] );
|
||||
|
||||
frame = (md4Frame_t *)((byte *)header + header->ofsFrames +
|
||||
backEnd.currentEntity->e.frame * frameSize );
|
||||
oldFrame = (md4Frame_t *)((byte *)header + header->ofsFrames +
|
||||
backEnd.currentEntity->e.oldframe * frameSize );
|
||||
|
||||
RB_CheckOverflow( surface->numVerts, surface->numTriangles * 3 );
|
||||
|
||||
triangles = (int *) ((byte *)surface + surface->ofsTriangles);
|
||||
indexes = surface->numTriangles * 3;
|
||||
baseIndex = tess.numIndexes;
|
||||
baseVertex = tess.numVertexes;
|
||||
for (j = 0 ; j < indexes ; j++) {
|
||||
tess.indexes[baseIndex + j] = baseIndex + triangles[j];
|
||||
}
|
||||
tess.numIndexes += indexes;
|
||||
|
||||
//
|
||||
// lerp all the needed bones
|
||||
//
|
||||
if ( !backlerp ) {
|
||||
// no lerping needed
|
||||
bonePtr = frame->bones;
|
||||
} else {
|
||||
bonePtr = bones;
|
||||
for ( i = 0 ; i < header->numBones*12 ; i++ ) {
|
||||
((float *)bonePtr)[i] = frontlerp * ((float *)frame->bones)[i]
|
||||
+ backlerp * ((float *)oldFrame->bones)[i];
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// deform the vertexes by the lerped bones
|
||||
//
|
||||
numVerts = surface->numVerts;
|
||||
// FIXME
|
||||
// This makes TFC's skeletons work. Shouldn't be necessary anymore, but left
|
||||
// in for reference.
|
||||
//v = (md4Vertex_t *) ((byte *)surface + surface->ofsVerts + 12);
|
||||
v = (md4Vertex_t *) ((byte *)surface + surface->ofsVerts);
|
||||
for ( j = 0; j < numVerts; j++ ) {
|
||||
vec3_t tempVert, tempNormal;
|
||||
md4Weight_t *w;
|
||||
|
||||
VectorClear( tempVert );
|
||||
VectorClear( tempNormal );
|
||||
w = v->weights;
|
||||
for ( k = 0 ; k < v->numWeights ; k++, w++ ) {
|
||||
bone = bonePtr + w->boneIndex;
|
||||
|
||||
tempVert[0] += w->boneWeight * ( DotProduct( bone->matrix[0], w->offset ) + bone->matrix[0][3] );
|
||||
tempVert[1] += w->boneWeight * ( DotProduct( bone->matrix[1], w->offset ) + bone->matrix[1][3] );
|
||||
tempVert[2] += w->boneWeight * ( DotProduct( bone->matrix[2], w->offset ) + bone->matrix[2][3] );
|
||||
|
||||
tempNormal[0] += w->boneWeight * DotProduct( bone->matrix[0], v->normal );
|
||||
tempNormal[1] += w->boneWeight * DotProduct( bone->matrix[1], v->normal );
|
||||
tempNormal[2] += w->boneWeight * DotProduct( bone->matrix[2], v->normal );
|
||||
}
|
||||
|
||||
tess.xyz[baseVertex + j][0] = tempVert[0];
|
||||
tess.xyz[baseVertex + j][1] = tempVert[1];
|
||||
tess.xyz[baseVertex + j][2] = tempVert[2];
|
||||
|
||||
tess.normal[baseVertex + j][0] = tempNormal[0];
|
||||
tess.normal[baseVertex + j][1] = tempNormal[1];
|
||||
tess.normal[baseVertex + j][2] = tempNormal[2];
|
||||
|
||||
tess.texCoords[baseVertex + j][0][0] = v->texCoords[0];
|
||||
tess.texCoords[baseVertex + j][0][1] = v->texCoords[1];
|
||||
|
||||
// FIXME
|
||||
// This makes TFC's skeletons work. Shouldn't be necessary anymore, but left
|
||||
// in for reference.
|
||||
//v = (md4Vertex_t *)( ( byte * )&v->weights[v->numWeights] + 12 );
|
||||
v = (md4Vertex_t *)&v->weights[v->numWeights];
|
||||
}
|
||||
|
||||
tess.numVertexes += surface->numVerts;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// copied and adapted from tr_mesh.c
|
||||
|
||||
|
@ -198,7 +61,7 @@ static int R_MDRCullModel( mdrHeader_t *header, trRefEntity_t *ent ) {
|
|||
switch ( R_CullLocalPointAndRadius( newFrame->localOrigin, newFrame->radius ) )
|
||||
{
|
||||
// Ummm... yeah yeah I know we don't really have an md3 here.. but we pretend
|
||||
// we do. After all, the purpose of md4s are not that different, are they?
|
||||
// we do. After all, the purpose of mdrs are not that different, are they?
|
||||
|
||||
case CULL_OUT:
|
||||
tr.pc.c_sphere_cull_md3_out++;
|
||||
|
@ -448,7 +311,7 @@ void R_MDRAddAnimSurfaces( trRefEntity_t *ent ) {
|
|||
RB_MDRSurfaceAnim
|
||||
==============
|
||||
*/
|
||||
void RB_MDRSurfaceAnim( md4Surface_t *surface )
|
||||
void RB_MDRSurfaceAnim( mdrSurface_t *surface )
|
||||
{
|
||||
int i, j, k;
|
||||
float frontlerp, backlerp;
|
||||
|
@ -460,7 +323,7 @@ void RB_MDRSurfaceAnim( md4Surface_t *surface )
|
|||
mdrHeader_t *header;
|
||||
mdrFrame_t *frame;
|
||||
mdrFrame_t *oldFrame;
|
||||
mdrBone_t bones[MD4_MAX_BONES], *bonePtr, *bone;
|
||||
mdrBone_t bones[MDR_MAX_BONES], *bonePtr, *bone;
|
||||
|
||||
int frameSize;
|
||||
|
||||
|
@ -548,9 +411,7 @@ void RB_MDRSurfaceAnim( md4Surface_t *surface )
|
|||
tess.xyz[baseVertex + j][1] = tempVert[1];
|
||||
tess.xyz[baseVertex + j][2] = tempVert[2];
|
||||
|
||||
tess.normal[baseVertex + j][0] = tempNormal[0];
|
||||
tess.normal[baseVertex + j][1] = tempNormal[1];
|
||||
tess.normal[baseVertex + j][2] = tempNormal[2];
|
||||
tess.normal[baseVertex + j] = R_VboPackNormal(tempNormal);
|
||||
|
||||
tess.texCoords[baseVertex + j][0][0] = v->texCoords[0];
|
||||
tess.texCoords[baseVertex + j][0][1] = v->texCoords[1];
|
||||
|
|
|
@ -371,17 +371,17 @@ void GL_State( unsigned long stateBits )
|
|||
}
|
||||
|
||||
|
||||
void GL_SetProjectionMatrix(matrix_t matrix)
|
||||
void GL_SetProjectionMatrix(mat4_t matrix)
|
||||
{
|
||||
Matrix16Copy(matrix, glState.projection);
|
||||
Matrix16Multiply(glState.projection, glState.modelview, glState.modelviewProjection);
|
||||
Mat4Copy(matrix, glState.projection);
|
||||
Mat4Multiply(glState.projection, glState.modelview, glState.modelviewProjection);
|
||||
}
|
||||
|
||||
|
||||
void GL_SetModelviewMatrix(matrix_t matrix)
|
||||
void GL_SetModelviewMatrix(mat4_t matrix)
|
||||
{
|
||||
Matrix16Copy(matrix, glState.modelview);
|
||||
Matrix16Multiply(glState.projection, glState.modelview, glState.modelviewProjection);
|
||||
Mat4Copy(matrix, glState.modelview);
|
||||
Mat4Multiply(glState.projection, glState.modelview, glState.modelviewProjection);
|
||||
}
|
||||
|
||||
|
||||
|
@ -449,7 +449,7 @@ void RB_BeginDrawingView (void) {
|
|||
{
|
||||
if (!tr.renderFbo || (backEnd.framePostProcessed && (backEnd.refdef.rdflags & RDF_NOWORLDMODEL)))
|
||||
{
|
||||
FBO_Bind(tr.screenScratchFbo);
|
||||
FBO_Bind(NULL);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -461,7 +461,7 @@ void RB_BeginDrawingView (void) {
|
|||
FBO_Bind(backEnd.viewParms.targetFbo);
|
||||
|
||||
// FIXME: hack for cubemap testing
|
||||
if (backEnd.viewParms.targetFbo == tr.renderCubeFbo)
|
||||
if (tr.renderCubeFbo && backEnd.viewParms.targetFbo == tr.renderCubeFbo)
|
||||
{
|
||||
//qglFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_CUBE_MAP_POSITIVE_X + backEnd.viewParms.targetFboLayer, backEnd.viewParms.targetFbo->colorImage[0]->texnum, 0);
|
||||
qglFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_CUBE_MAP_POSITIVE_X + backEnd.viewParms.targetFboLayer, tr.cubemaps[backEnd.viewParms.targetFboCubemapIndex]->texnum, 0);
|
||||
|
@ -501,7 +501,7 @@ void RB_BeginDrawingView (void) {
|
|||
}
|
||||
|
||||
// clear to black for cube maps
|
||||
if (backEnd.viewParms.targetFbo == tr.renderCubeFbo)
|
||||
if (tr.renderCubeFbo && backEnd.viewParms.targetFbo == tr.renderCubeFbo)
|
||||
{
|
||||
clearBits |= GL_COLOR_BUFFER_BIT;
|
||||
qglClearColor( 0.0f, 0.0f, 0.0f, 1.0f );
|
||||
|
@ -765,7 +765,7 @@ RB_SetGL2D
|
|||
================
|
||||
*/
|
||||
void RB_SetGL2D (void) {
|
||||
matrix_t matrix;
|
||||
mat4_t matrix;
|
||||
int width, height;
|
||||
|
||||
if (backEnd.projection2D && backEnd.last2DFBO == glState.currentFBO)
|
||||
|
@ -789,9 +789,9 @@ void RB_SetGL2D (void) {
|
|||
qglViewport( 0, 0, width, height );
|
||||
qglScissor( 0, 0, width, height );
|
||||
|
||||
Matrix16Ortho(0, width, height, 0, 0, 1, matrix);
|
||||
Mat4Ortho(0, width, height, 0, 0, 1, matrix);
|
||||
GL_SetProjectionMatrix(matrix);
|
||||
Matrix16Identity(matrix);
|
||||
Mat4Identity(matrix);
|
||||
GL_SetModelviewMatrix(matrix);
|
||||
|
||||
GL_State( GLS_DEPTHTEST_DISABLE |
|
||||
|
@ -830,6 +830,10 @@ void RE_StretchRaw (int x, int y, int w, int h, int cols, int rows, const byte *
|
|||
}
|
||||
R_IssuePendingRenderCommands();
|
||||
|
||||
if ( tess.numIndexes ) {
|
||||
RB_EndSurface();
|
||||
}
|
||||
|
||||
// we definately want to sync every frame for the cinematics
|
||||
qglFinish();
|
||||
|
||||
|
@ -859,7 +863,7 @@ void RE_StretchRaw (int x, int y, int w, int h, int cols, int rows, const byte *
|
|||
{
|
||||
if (!tr.renderFbo || backEnd.framePostProcessed)
|
||||
{
|
||||
FBO_Bind(tr.screenScratchFbo);
|
||||
FBO_Bind(NULL);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -881,7 +885,7 @@ void RE_StretchRaw (int x, int y, int w, int h, int cols, int rows, const byte *
|
|||
|
||||
GLSL_BindProgram(&tr.textureColorShader);
|
||||
|
||||
GLSL_SetUniformMatrix16(&tr.textureColorShader, UNIFORM_MODELVIEWPROJECTIONMATRIX, glState.modelviewProjection);
|
||||
GLSL_SetUniformMat4(&tr.textureColorShader, UNIFORM_MODELVIEWPROJECTIONMATRIX, glState.modelviewProjection);
|
||||
GLSL_SetUniformVec4(&tr.textureColorShader, UNIFORM_COLOR, colorWhite);
|
||||
|
||||
RB_InstantQuad2(quadVerts, texCoords);
|
||||
|
@ -946,7 +950,7 @@ const void *RB_StretchPic ( const void *data ) {
|
|||
{
|
||||
if (!tr.renderFbo || backEnd.framePostProcessed)
|
||||
{
|
||||
FBO_Bind(tr.screenScratchFbo);
|
||||
FBO_Bind(NULL);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -1077,7 +1081,7 @@ const void *RB_DrawSurfs( const void *data ) {
|
|||
FBO_BlitFromTexture(tr.renderDepthImage, NULL, NULL, tr.hdrDepthFbo, NULL, NULL, NULL, 0);
|
||||
}
|
||||
|
||||
if (backEnd.viewParms.flags & VPF_USESUNLIGHT)
|
||||
if (r_sunlightMode->integer && backEnd.viewParms.flags & VPF_USESUNLIGHT)
|
||||
{
|
||||
vec4_t quadVerts[4];
|
||||
vec2_t texCoords[4];
|
||||
|
@ -1122,9 +1126,9 @@ const void *RB_DrawSurfs( const void *data ) {
|
|||
GL_BindToTMU(tr.sunShadowDepthImage[1], TB_SHADOWMAP2);
|
||||
GL_BindToTMU(tr.sunShadowDepthImage[2], TB_SHADOWMAP3);
|
||||
|
||||
GLSL_SetUniformMatrix16(&tr.shadowmaskShader, UNIFORM_SHADOWMVP, backEnd.refdef.sunShadowMvp[0]);
|
||||
GLSL_SetUniformMatrix16(&tr.shadowmaskShader, UNIFORM_SHADOWMVP2, backEnd.refdef.sunShadowMvp[1]);
|
||||
GLSL_SetUniformMatrix16(&tr.shadowmaskShader, UNIFORM_SHADOWMVP3, backEnd.refdef.sunShadowMvp[2]);
|
||||
GLSL_SetUniformMat4(&tr.shadowmaskShader, UNIFORM_SHADOWMVP, backEnd.refdef.sunShadowMvp[0]);
|
||||
GLSL_SetUniformMat4(&tr.shadowmaskShader, UNIFORM_SHADOWMVP2, backEnd.refdef.sunShadowMvp[1]);
|
||||
GLSL_SetUniformMat4(&tr.shadowmaskShader, UNIFORM_SHADOWMVP3, backEnd.refdef.sunShadowMvp[2]);
|
||||
|
||||
GLSL_SetUniformVec3(&tr.shadowmaskShader, UNIFORM_VIEWORIGIN, backEnd.refdef.vieworg);
|
||||
{
|
||||
|
@ -1292,7 +1296,7 @@ const void *RB_DrawSurfs( const void *data ) {
|
|||
RB_RenderFlares();
|
||||
}
|
||||
|
||||
if (glRefConfig.framebufferObject && backEnd.viewParms.targetFbo == tr.renderCubeFbo)
|
||||
if (glRefConfig.framebufferObject && tr.renderCubeFbo && backEnd.viewParms.targetFbo == tr.renderCubeFbo)
|
||||
{
|
||||
FBO_Bind(NULL);
|
||||
GL_SelectTexture(TB_CUBEMAP);
|
||||
|
@ -1443,7 +1447,7 @@ const void *RB_ClearDepth(const void *data)
|
|||
{
|
||||
if (!tr.renderFbo || backEnd.framePostProcessed)
|
||||
{
|
||||
FBO_Bind(tr.screenScratchFbo);
|
||||
FBO_Bind(NULL);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -1512,32 +1516,13 @@ const void *RB_SwapBuffers( const void *data ) {
|
|||
{
|
||||
// Resolving an RGB16F MSAA FBO to the screen messes with the brightness, so resolve to an RGB16F FBO first
|
||||
FBO_FastBlit(tr.renderFbo, NULL, tr.msaaResolveFbo, NULL, GL_COLOR_BUFFER_BIT, GL_NEAREST);
|
||||
FBO_FastBlit(tr.msaaResolveFbo, NULL, tr.screenScratchFbo, NULL, GL_COLOR_BUFFER_BIT, GL_NEAREST);
|
||||
FBO_FastBlit(tr.msaaResolveFbo, NULL, NULL, NULL, GL_COLOR_BUFFER_BIT, GL_NEAREST);
|
||||
}
|
||||
else if (tr.renderFbo)
|
||||
{
|
||||
FBO_FastBlit(tr.renderFbo, NULL, tr.screenScratchFbo, NULL, GL_COLOR_BUFFER_BIT, GL_NEAREST);
|
||||
FBO_FastBlit(tr.renderFbo, NULL, NULL, NULL, GL_COLOR_BUFFER_BIT, GL_NEAREST);
|
||||
}
|
||||
}
|
||||
|
||||
if (tr.screenScratchFbo)
|
||||
{
|
||||
vec4_t color;
|
||||
|
||||
color[0] =
|
||||
color[1] =
|
||||
color[2] = pow(2, tr.overbrightBits); //exp2(tr.overbrightBits);
|
||||
color[3] = 1.0f;
|
||||
|
||||
// turn off colormask when copying final image
|
||||
if (backEnd.colorMask[0] || backEnd.colorMask[1] || backEnd.colorMask[2] || backEnd.colorMask[3])
|
||||
qglColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
|
||||
|
||||
FBO_Blit(tr.screenScratchFbo, NULL, NULL, NULL, NULL, NULL, color, 0);
|
||||
|
||||
if (backEnd.colorMask[0] || backEnd.colorMask[1] || backEnd.colorMask[2] || backEnd.colorMask[3])
|
||||
qglColorMask(!backEnd.colorMask[0], !backEnd.colorMask[1], !backEnd.colorMask[2], !backEnd.colorMask[3]);
|
||||
}
|
||||
}
|
||||
|
||||
if ( !glState.finishCalled ) {
|
||||
|
@ -1573,13 +1558,19 @@ const void *RB_CapShadowMap(const void *data)
|
|||
GL_SelectTexture(0);
|
||||
if (cmd->cubeSide != -1)
|
||||
{
|
||||
GL_Bind(tr.shadowCubemaps[cmd->map]);
|
||||
qglCopyTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + cmd->cubeSide, 0, GL_RGBA8, backEnd.refdef.x, glConfig.vidHeight - ( backEnd.refdef.y + PSHADOW_MAP_SIZE ), PSHADOW_MAP_SIZE, PSHADOW_MAP_SIZE, 0);
|
||||
if (tr.shadowCubemaps[cmd->map])
|
||||
{
|
||||
GL_Bind(tr.shadowCubemaps[cmd->map]);
|
||||
qglCopyTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + cmd->cubeSide, 0, GL_RGBA8, backEnd.refdef.x, glConfig.vidHeight - ( backEnd.refdef.y + PSHADOW_MAP_SIZE ), PSHADOW_MAP_SIZE, PSHADOW_MAP_SIZE, 0);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
GL_Bind(tr.pshadowMaps[cmd->map]);
|
||||
qglCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, backEnd.refdef.x, glConfig.vidHeight - ( backEnd.refdef.y + PSHADOW_MAP_SIZE ), PSHADOW_MAP_SIZE, PSHADOW_MAP_SIZE, 0);
|
||||
if (tr.pshadowMaps[cmd->map])
|
||||
{
|
||||
GL_Bind(tr.pshadowMaps[cmd->map]);
|
||||
qglCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, backEnd.refdef.x, glConfig.vidHeight - ( backEnd.refdef.y + PSHADOW_MAP_SIZE ), PSHADOW_MAP_SIZE, PSHADOW_MAP_SIZE, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1597,7 +1588,7 @@ const void *RB_PostProcess(const void *data)
|
|||
{
|
||||
const postProcessCommand_t *cmd = data;
|
||||
FBO_t *srcFbo;
|
||||
vec4i_t srcBox, dstBox;
|
||||
ivec4_t srcBox, dstBox;
|
||||
qboolean autoExposure;
|
||||
|
||||
// finish any 2D drawing if needed
|
||||
|
@ -1654,11 +1645,11 @@ const void *RB_PostProcess(const void *data)
|
|||
if (r_hdr->integer && (r_toneMap->integer || r_forceToneMap->integer))
|
||||
{
|
||||
autoExposure = r_autoExposure->integer || r_forceAutoExposure->integer;
|
||||
RB_ToneMap(srcFbo, srcBox, tr.screenScratchFbo, dstBox, autoExposure);
|
||||
RB_ToneMap(srcFbo, srcBox, NULL, dstBox, autoExposure);
|
||||
}
|
||||
else if (r_cameraExposure->value == 0.0f)
|
||||
{
|
||||
FBO_FastBlit(srcFbo, srcBox, tr.screenScratchFbo, dstBox, GL_COLOR_BUFFER_BIT, GL_NEAREST);
|
||||
FBO_FastBlit(srcFbo, srcBox, NULL, dstBox, GL_COLOR_BUFFER_BIT, GL_NEAREST);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -1669,56 +1660,56 @@ const void *RB_PostProcess(const void *data)
|
|||
color[2] = pow(2, r_cameraExposure->value); //exp2(r_cameraExposure->value);
|
||||
color[3] = 1.0f;
|
||||
|
||||
FBO_Blit(srcFbo, srcBox, NULL, tr.screenScratchFbo, dstBox, NULL, color, 0);
|
||||
FBO_Blit(srcFbo, srcBox, NULL, NULL, dstBox, NULL, color, 0);
|
||||
}
|
||||
}
|
||||
|
||||
if (r_drawSunRays->integer)
|
||||
RB_SunRays(tr.screenScratchFbo, srcBox, tr.screenScratchFbo, dstBox);
|
||||
RB_SunRays(NULL, srcBox, NULL, dstBox);
|
||||
|
||||
if (1)
|
||||
RB_BokehBlur(tr.screenScratchFbo, srcBox, tr.screenScratchFbo, dstBox, backEnd.refdef.blurFactor);
|
||||
RB_BokehBlur(NULL, srcBox, NULL, dstBox, backEnd.refdef.blurFactor);
|
||||
else
|
||||
RB_GaussianBlur(backEnd.refdef.blurFactor);
|
||||
|
||||
if (0)
|
||||
if (0 && r_sunlightMode->integer)
|
||||
{
|
||||
vec4i_t dstBox;
|
||||
ivec4_t dstBox;
|
||||
VectorSet4(dstBox, 0, 0, 128, 128);
|
||||
FBO_BlitFromTexture(tr.sunShadowDepthImage[0], NULL, NULL, tr.screenScratchFbo, dstBox, NULL, NULL, 0);
|
||||
FBO_BlitFromTexture(tr.sunShadowDepthImage[0], NULL, NULL, NULL, dstBox, NULL, NULL, 0);
|
||||
VectorSet4(dstBox, 128, 0, 128, 128);
|
||||
FBO_BlitFromTexture(tr.sunShadowDepthImage[1], NULL, NULL, tr.screenScratchFbo, dstBox, NULL, NULL, 0);
|
||||
FBO_BlitFromTexture(tr.sunShadowDepthImage[1], NULL, NULL, NULL, dstBox, NULL, NULL, 0);
|
||||
VectorSet4(dstBox, 256, 0, 128, 128);
|
||||
FBO_BlitFromTexture(tr.sunShadowDepthImage[2], NULL, NULL, tr.screenScratchFbo, dstBox, NULL, NULL, 0);
|
||||
FBO_BlitFromTexture(tr.sunShadowDepthImage[2], NULL, NULL, NULL, dstBox, NULL, NULL, 0);
|
||||
}
|
||||
|
||||
if (0)
|
||||
{
|
||||
vec4i_t dstBox;
|
||||
ivec4_t dstBox;
|
||||
VectorSet4(dstBox, 256, glConfig.vidHeight - 256, 256, 256);
|
||||
FBO_BlitFromTexture(tr.renderDepthImage, NULL, NULL, tr.screenScratchFbo, dstBox, NULL, NULL, 0);
|
||||
FBO_BlitFromTexture(tr.renderDepthImage, NULL, NULL, NULL, dstBox, NULL, NULL, 0);
|
||||
VectorSet4(dstBox, 512, glConfig.vidHeight - 256, 256, 256);
|
||||
FBO_BlitFromTexture(tr.screenShadowImage, NULL, NULL, tr.screenScratchFbo, dstBox, NULL, NULL, 0);
|
||||
FBO_BlitFromTexture(tr.screenShadowImage, NULL, NULL, NULL, dstBox, NULL, NULL, 0);
|
||||
}
|
||||
|
||||
if (0)
|
||||
{
|
||||
vec4i_t dstBox;
|
||||
ivec4_t dstBox;
|
||||
VectorSet4(dstBox, 256, glConfig.vidHeight - 256, 256, 256);
|
||||
FBO_BlitFromTexture(tr.sunRaysImage, NULL, NULL, tr.screenScratchFbo, dstBox, NULL, NULL, 0);
|
||||
FBO_BlitFromTexture(tr.sunRaysImage, NULL, NULL, NULL, dstBox, NULL, NULL, 0);
|
||||
}
|
||||
|
||||
#if 0
|
||||
if (r_cubeMapping->integer && tr.numCubemaps)
|
||||
{
|
||||
vec4i_t dstBox;
|
||||
ivec4_t dstBox;
|
||||
int cubemapIndex = R_CubemapForPoint( backEnd.viewParms.or.origin );
|
||||
|
||||
if (cubemapIndex)
|
||||
{
|
||||
VectorSet4(dstBox, 0, glConfig.vidHeight - 256, 256, 256);
|
||||
//FBO_BlitFromTexture(tr.renderCubeImage, NULL, NULL, tr.screenScratchFbo, dstBox, &tr.testcubeShader, NULL, 0);
|
||||
FBO_BlitFromTexture(tr.cubemaps[cubemapIndex - 1], NULL, NULL, tr.screenScratchFbo, dstBox, &tr.testcubeShader, NULL, 0);
|
||||
//FBO_BlitFromTexture(tr.renderCubeImage, NULL, NULL, NULL, dstBox, &tr.testcubeShader, NULL, 0);
|
||||
FBO_BlitFromTexture(tr.cubemaps[cubemapIndex - 1], NULL, NULL, NULL, dstBox, &tr.testcubeShader, NULL, 0);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -442,12 +442,6 @@ void RE_BeginFrame( stereoFrame_t stereoFrame ) {
|
|||
qglClear(GL_COLOR_BUFFER_BIT);
|
||||
}
|
||||
|
||||
if (tr.screenScratchFbo)
|
||||
{
|
||||
FBO_Bind(tr.screenScratchFbo);
|
||||
qglClear(GL_COLOR_BUFFER_BIT);
|
||||
}
|
||||
|
||||
FBO_Bind(NULL);
|
||||
}
|
||||
|
||||
|
|
|
@ -25,14 +25,14 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|||
/*
|
||||
|
||||
This file does all of the processing necessary to turn a raw grid of points
|
||||
read from the map file into a srfGridMesh_t ready for rendering.
|
||||
read from the map file into a srfBspSurface_t ready for rendering.
|
||||
|
||||
The level of detail solution is direction independent, based only on subdivided
|
||||
distance from the true curve.
|
||||
|
||||
Only a single entry point:
|
||||
|
||||
srfGridMesh_t *R_SubdividePatchToGrid( int width, int height,
|
||||
srfBspSurface_t *R_SubdividePatchToGrid( int width, int height,
|
||||
srfVert_t points[MAX_PATCH_SIZE*MAX_PATCH_SIZE] ) {
|
||||
|
||||
*/
|
||||
|
@ -213,13 +213,13 @@ static int neighbors[8][2] = {
|
|||
}
|
||||
|
||||
#ifdef USE_VERT_TANGENT_SPACE
|
||||
static void MakeMeshTangentVectors(int width, int height, srfVert_t ctrl[MAX_GRID_SIZE][MAX_GRID_SIZE], int numTriangles,
|
||||
srfTriangle_t triangles[(MAX_GRID_SIZE-1)*(MAX_GRID_SIZE-1)*2])
|
||||
static void MakeMeshTangentVectors(int width, int height, srfVert_t ctrl[MAX_GRID_SIZE][MAX_GRID_SIZE], int numIndexes,
|
||||
glIndex_t indexes[(MAX_GRID_SIZE-1)*(MAX_GRID_SIZE-1)*2*3])
|
||||
{
|
||||
int i, j;
|
||||
srfVert_t *dv[3];
|
||||
static srfVert_t ctrl2[MAX_GRID_SIZE * MAX_GRID_SIZE];
|
||||
srfTriangle_t *tri;
|
||||
glIndex_t *tri;
|
||||
|
||||
// FIXME: use more elegant way
|
||||
for(i = 0; i < width; i++)
|
||||
|
@ -231,53 +231,15 @@ static void MakeMeshTangentVectors(int width, int height, srfVert_t ctrl[MAX_GRI
|
|||
}
|
||||
}
|
||||
|
||||
for(i = 0, tri = triangles; i < numTriangles; i++, tri++)
|
||||
for(i = 0, tri = indexes; i < numIndexes; i += 3, tri += 3)
|
||||
{
|
||||
dv[0] = &ctrl2[tri->indexes[0]];
|
||||
dv[1] = &ctrl2[tri->indexes[1]];
|
||||
dv[2] = &ctrl2[tri->indexes[2]];
|
||||
dv[0] = &ctrl2[tri[0]];
|
||||
dv[1] = &ctrl2[tri[1]];
|
||||
dv[2] = &ctrl2[tri[2]];
|
||||
|
||||
R_CalcTangentVectors(dv);
|
||||
}
|
||||
|
||||
#if 0
|
||||
for(i = 0; i < (width * height); i++)
|
||||
{
|
||||
dv0 = &ctrl2[i];
|
||||
|
||||
VectorNormalize(dv0->normal);
|
||||
#if 0
|
||||
VectorNormalize(dv0->tangent);
|
||||
VectorNormalize(dv0->bitangent);
|
||||
#else
|
||||
d = DotProduct(dv0->tangent, dv0->normal);
|
||||
VectorMA(dv0->tangent, -d, dv0->normal, dv0->tangent);
|
||||
VectorNormalize(dv0->tangent);
|
||||
|
||||
d = DotProduct(dv0->bitangent, dv0->normal);
|
||||
VectorMA(dv0->bitangent, -d, dv0->normal, dv0->bitangent);
|
||||
VectorNormalize(dv0->bitangent);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#if 0
|
||||
// do another extra smoothing for normals to avoid flat shading
|
||||
for(i = 0; i < (width * height); i++)
|
||||
{
|
||||
for(j = 0; j < (width * height); j++)
|
||||
{
|
||||
if(R_CompareVert(&ctrl2[i], &ctrl2[j], qfalse))
|
||||
{
|
||||
VectorAdd(ctrl2[i].normal, ctrl2[j].normal, ctrl2[i].normal);
|
||||
}
|
||||
}
|
||||
|
||||
VectorNormalize(ctrl2[i].normal);
|
||||
}
|
||||
#endif
|
||||
|
||||
for(i = 0; i < width; i++)
|
||||
{
|
||||
for(j = 0; j < height; j++)
|
||||
|
@ -285,26 +247,25 @@ static void MakeMeshTangentVectors(int width, int height, srfVert_t ctrl[MAX_GRI
|
|||
dv[0] = &ctrl2[j * width + i];
|
||||
dv[1] = &ctrl[j][i];
|
||||
|
||||
VectorCopy(dv[0]->tangent, dv[1]->tangent);
|
||||
VectorCopy(dv[0]->bitangent, dv[1]->bitangent);
|
||||
VectorCopy4(dv[0]->tangent, dv[1]->tangent);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
static int MakeMeshTriangles(int width, int height, srfVert_t ctrl[MAX_GRID_SIZE][MAX_GRID_SIZE],
|
||||
srfTriangle_t triangles[(MAX_GRID_SIZE-1)*(MAX_GRID_SIZE-1)*2])
|
||||
static int MakeMeshIndexes(int width, int height, srfVert_t ctrl[MAX_GRID_SIZE][MAX_GRID_SIZE],
|
||||
glIndex_t indexes[(MAX_GRID_SIZE-1)*(MAX_GRID_SIZE-1)*2*3])
|
||||
{
|
||||
int i, j;
|
||||
int numTriangles;
|
||||
int numIndexes;
|
||||
int w, h;
|
||||
srfVert_t *dv;
|
||||
static srfVert_t ctrl2[MAX_GRID_SIZE * MAX_GRID_SIZE];
|
||||
|
||||
h = height - 1;
|
||||
w = width - 1;
|
||||
numTriangles = 0;
|
||||
numIndexes = 0;
|
||||
for(i = 0; i < h; i++)
|
||||
{
|
||||
for(j = 0; j < w; j++)
|
||||
|
@ -317,20 +278,16 @@ static int MakeMeshTriangles(int width, int height, srfVert_t ctrl[MAX_GRID_SIZE
|
|||
v3 = v2 + width;
|
||||
v4 = v3 + 1;
|
||||
|
||||
triangles[numTriangles].indexes[0] = v2;
|
||||
triangles[numTriangles].indexes[1] = v3;
|
||||
triangles[numTriangles].indexes[2] = v1;
|
||||
numTriangles++;
|
||||
indexes[numIndexes++] = v2;
|
||||
indexes[numIndexes++] = v3;
|
||||
indexes[numIndexes++] = v1;
|
||||
|
||||
triangles[numTriangles].indexes[0] = v1;
|
||||
triangles[numTriangles].indexes[1] = v3;
|
||||
triangles[numTriangles].indexes[2] = v4;
|
||||
numTriangles++;
|
||||
indexes[numIndexes++] = v1;
|
||||
indexes[numIndexes++] = v3;
|
||||
indexes[numIndexes++] = v4;
|
||||
}
|
||||
}
|
||||
|
||||
R_CalcSurfaceTriangleNeighbors(numTriangles, triangles);
|
||||
|
||||
// FIXME: use more elegant way
|
||||
for(i = 0; i < width; i++)
|
||||
{
|
||||
|
@ -341,9 +298,7 @@ static int MakeMeshTriangles(int width, int height, srfVert_t ctrl[MAX_GRID_SIZE
|
|||
}
|
||||
}
|
||||
|
||||
R_CalcSurfaceTrianglePlanes(numTriangles, triangles, ctrl2);
|
||||
|
||||
return numTriangles;
|
||||
return numIndexes;
|
||||
}
|
||||
|
||||
|
||||
|
@ -420,13 +375,13 @@ static void PutPointsOnCurve( srfVert_t ctrl[MAX_GRID_SIZE][MAX_GRID_SIZE],
|
|||
R_CreateSurfaceGridMesh
|
||||
=================
|
||||
*/
|
||||
srfGridMesh_t *R_CreateSurfaceGridMesh(int width, int height,
|
||||
srfBspSurface_t *R_CreateSurfaceGridMesh(int width, int height,
|
||||
srfVert_t ctrl[MAX_GRID_SIZE][MAX_GRID_SIZE], float errorTable[2][MAX_GRID_SIZE],
|
||||
int numTriangles, srfTriangle_t triangles[(MAX_GRID_SIZE-1)*(MAX_GRID_SIZE-1)*2]) {
|
||||
int numIndexes, glIndex_t indexes[(MAX_GRID_SIZE-1)*(MAX_GRID_SIZE-1)*2*3]) {
|
||||
int i, j, size;
|
||||
srfVert_t *vert;
|
||||
vec3_t tmpVec;
|
||||
srfGridMesh_t *grid;
|
||||
srfBspSurface_t *grid;
|
||||
|
||||
// copy the results out to a grid
|
||||
size = (width * height - 1) * sizeof( srfVert_t ) + sizeof( *grid );
|
||||
|
@ -441,9 +396,9 @@ srfGridMesh_t *R_CreateSurfaceGridMesh(int width, int height,
|
|||
grid->heightLodError = /*ri.Hunk_Alloc*/ ri.Malloc( height * 4 );
|
||||
Com_Memcpy( grid->heightLodError, errorTable[1], height * 4 );
|
||||
|
||||
grid->numTriangles = numTriangles;
|
||||
grid->triangles = ri.Malloc(grid->numTriangles * sizeof(srfTriangle_t));
|
||||
Com_Memcpy(grid->triangles, triangles, numTriangles * sizeof(srfTriangle_t));
|
||||
grid->numIndexes = numIndexes;
|
||||
grid->indexes = ri.Malloc(grid->numIndexes * sizeof(glIndex_t));
|
||||
Com_Memcpy(grid->indexes, indexes, numIndexes * sizeof(glIndex_t));
|
||||
|
||||
grid->numVerts = (width * height);
|
||||
grid->verts = ri.Malloc(grid->numVerts * sizeof(srfVert_t));
|
||||
|
@ -457,9 +412,9 @@ srfGridMesh_t *R_CreateSurfaceGridMesh(int width, int height,
|
|||
grid->heightLodError = ri.Hunk_Alloc( height * 4 );
|
||||
Com_Memcpy( grid->heightLodError, errorTable[1], height * 4 );
|
||||
|
||||
grid->numTriangles = numTriangles;
|
||||
grid->triangles = ri.Hunk_Alloc(grid->numTriangles * sizeof(srfTriangle_t), h_low);
|
||||
Com_Memcpy(grid->triangles, triangles, numTriangles * sizeof(srfTriangle_t));
|
||||
grid->numIndexes = numIndexes;
|
||||
grid->indexes = ri.Hunk_Alloc(grid->numIndexes * sizeof(glIndex_t), h_low);
|
||||
Com_Memcpy(grid->indexes, indexes, numIndexes * sizeof(glIndex_t));
|
||||
|
||||
grid->numVerts = (width * height);
|
||||
grid->verts = ri.Hunk_Alloc(grid->numVerts * sizeof(srfVert_t), h_low);
|
||||
|
@ -468,23 +423,23 @@ srfGridMesh_t *R_CreateSurfaceGridMesh(int width, int height,
|
|||
grid->width = width;
|
||||
grid->height = height;
|
||||
grid->surfaceType = SF_GRID;
|
||||
ClearBounds( grid->meshBounds[0], grid->meshBounds[1] );
|
||||
ClearBounds( grid->cullBounds[0], grid->cullBounds[1] );
|
||||
for ( i = 0 ; i < width ; i++ ) {
|
||||
for ( j = 0 ; j < height ; j++ ) {
|
||||
vert = &grid->verts[j*width+i];
|
||||
*vert = ctrl[j][i];
|
||||
AddPointToBounds( vert->xyz, grid->meshBounds[0], grid->meshBounds[1] );
|
||||
AddPointToBounds( vert->xyz, grid->cullBounds[0], grid->cullBounds[1] );
|
||||
}
|
||||
}
|
||||
|
||||
// compute local origin and bounds
|
||||
VectorAdd( grid->meshBounds[0], grid->meshBounds[1], grid->localOrigin );
|
||||
VectorScale( grid->localOrigin, 0.5f, grid->localOrigin );
|
||||
VectorSubtract( grid->meshBounds[0], grid->localOrigin, tmpVec );
|
||||
grid->meshRadius = VectorLength( tmpVec );
|
||||
VectorAdd( grid->cullBounds[0], grid->cullBounds[1], grid->cullOrigin );
|
||||
VectorScale( grid->cullOrigin, 0.5f, grid->cullOrigin );
|
||||
VectorSubtract( grid->cullBounds[0], grid->cullOrigin, tmpVec );
|
||||
grid->cullRadius = VectorLength( tmpVec );
|
||||
|
||||
VectorCopy( grid->localOrigin, grid->lodOrigin );
|
||||
grid->lodRadius = grid->meshRadius;
|
||||
VectorCopy( grid->cullOrigin, grid->lodOrigin );
|
||||
grid->lodRadius = grid->cullRadius;
|
||||
//
|
||||
return grid;
|
||||
}
|
||||
|
@ -494,10 +449,10 @@ srfGridMesh_t *R_CreateSurfaceGridMesh(int width, int height,
|
|||
R_FreeSurfaceGridMesh
|
||||
=================
|
||||
*/
|
||||
void R_FreeSurfaceGridMesh( srfGridMesh_t *grid ) {
|
||||
void R_FreeSurfaceGridMesh( srfBspSurface_t *grid ) {
|
||||
ri.Free(grid->widthLodError);
|
||||
ri.Free(grid->heightLodError);
|
||||
ri.Free(grid->triangles);
|
||||
ri.Free(grid->indexes);
|
||||
ri.Free(grid->verts);
|
||||
ri.Free(grid);
|
||||
}
|
||||
|
@ -507,7 +462,7 @@ void R_FreeSurfaceGridMesh( srfGridMesh_t *grid ) {
|
|||
R_SubdividePatchToGrid
|
||||
=================
|
||||
*/
|
||||
srfGridMesh_t *R_SubdividePatchToGrid( int width, int height,
|
||||
srfBspSurface_t *R_SubdividePatchToGrid( int width, int height,
|
||||
srfVert_t points[MAX_PATCH_SIZE*MAX_PATCH_SIZE] ) {
|
||||
int i, j, k, l;
|
||||
srfVert_t_cleared( prev );
|
||||
|
@ -518,8 +473,8 @@ srfGridMesh_t *R_SubdividePatchToGrid( int width, int height,
|
|||
int t;
|
||||
srfVert_t ctrl[MAX_GRID_SIZE][MAX_GRID_SIZE];
|
||||
float errorTable[2][MAX_GRID_SIZE];
|
||||
int numTriangles;
|
||||
static srfTriangle_t triangles[(MAX_GRID_SIZE-1)*(MAX_GRID_SIZE-1)*2];
|
||||
int numIndexes;
|
||||
static glIndex_t indexes[(MAX_GRID_SIZE-1)*(MAX_GRID_SIZE-1)*2*3];
|
||||
int consecutiveComplete;
|
||||
|
||||
for ( i = 0 ; i < width ; i++ ) {
|
||||
|
@ -673,16 +628,16 @@ srfGridMesh_t *R_SubdividePatchToGrid( int width, int height,
|
|||
}
|
||||
#endif
|
||||
|
||||
// calculate triangles
|
||||
numTriangles = MakeMeshTriangles(width, height, ctrl, triangles);
|
||||
// calculate indexes
|
||||
numIndexes = MakeMeshIndexes(width, height, ctrl, indexes);
|
||||
|
||||
// calculate normals
|
||||
MakeMeshNormals( width, height, ctrl );
|
||||
#ifdef USE_VERT_TANGENT_SPACE
|
||||
MakeMeshTangentVectors(width, height, ctrl, numTriangles, triangles);
|
||||
MakeMeshTangentVectors(width, height, ctrl, numIndexes, indexes);
|
||||
#endif
|
||||
|
||||
return R_CreateSurfaceGridMesh(width, height, ctrl, errorTable, numTriangles, triangles);
|
||||
return R_CreateSurfaceGridMesh(width, height, ctrl, errorTable, numIndexes, indexes);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -690,15 +645,15 @@ srfGridMesh_t *R_SubdividePatchToGrid( int width, int height,
|
|||
R_GridInsertColumn
|
||||
===============
|
||||
*/
|
||||
srfGridMesh_t *R_GridInsertColumn( srfGridMesh_t *grid, int column, int row, vec3_t point, float loderror ) {
|
||||
srfBspSurface_t *R_GridInsertColumn( srfBspSurface_t *grid, int column, int row, vec3_t point, float loderror ) {
|
||||
int i, j;
|
||||
int width, height, oldwidth;
|
||||
srfVert_t ctrl[MAX_GRID_SIZE][MAX_GRID_SIZE];
|
||||
float errorTable[2][MAX_GRID_SIZE];
|
||||
float lodRadius;
|
||||
vec3_t lodOrigin;
|
||||
int numTriangles;
|
||||
static srfTriangle_t triangles[(MAX_GRID_SIZE-1)*(MAX_GRID_SIZE-1)*2];
|
||||
int numIndexes;
|
||||
static glIndex_t indexes[(MAX_GRID_SIZE-1)*(MAX_GRID_SIZE-1)*2*3];
|
||||
|
||||
oldwidth = 0;
|
||||
width = grid->width + 1;
|
||||
|
@ -728,8 +683,8 @@ srfGridMesh_t *R_GridInsertColumn( srfGridMesh_t *grid, int column, int row, vec
|
|||
// put all the aproximating points on the curve
|
||||
//PutPointsOnCurve( ctrl, width, height );
|
||||
|
||||
// calculate triangles
|
||||
numTriangles = MakeMeshTriangles(width, height, ctrl, triangles);
|
||||
// calculate indexes
|
||||
numIndexes = MakeMeshIndexes(width, height, ctrl, indexes);
|
||||
|
||||
// calculate normals
|
||||
MakeMeshNormals( width, height, ctrl );
|
||||
|
@ -739,7 +694,7 @@ srfGridMesh_t *R_GridInsertColumn( srfGridMesh_t *grid, int column, int row, vec
|
|||
// free the old grid
|
||||
R_FreeSurfaceGridMesh(grid);
|
||||
// create a new grid
|
||||
grid = R_CreateSurfaceGridMesh(width, height, ctrl, errorTable, numTriangles, triangles);
|
||||
grid = R_CreateSurfaceGridMesh(width, height, ctrl, errorTable, numIndexes, indexes);
|
||||
grid->lodRadius = lodRadius;
|
||||
VectorCopy(lodOrigin, grid->lodOrigin);
|
||||
return grid;
|
||||
|
@ -750,15 +705,15 @@ srfGridMesh_t *R_GridInsertColumn( srfGridMesh_t *grid, int column, int row, vec
|
|||
R_GridInsertRow
|
||||
===============
|
||||
*/
|
||||
srfGridMesh_t *R_GridInsertRow( srfGridMesh_t *grid, int row, int column, vec3_t point, float loderror ) {
|
||||
srfBspSurface_t *R_GridInsertRow( srfBspSurface_t *grid, int row, int column, vec3_t point, float loderror ) {
|
||||
int i, j;
|
||||
int width, height, oldheight;
|
||||
srfVert_t ctrl[MAX_GRID_SIZE][MAX_GRID_SIZE];
|
||||
float errorTable[2][MAX_GRID_SIZE];
|
||||
float lodRadius;
|
||||
vec3_t lodOrigin;
|
||||
int numTriangles;
|
||||
static srfTriangle_t triangles[(MAX_GRID_SIZE-1)*(MAX_GRID_SIZE-1)*2];
|
||||
int numIndexes;
|
||||
static glIndex_t indexes[(MAX_GRID_SIZE-1)*(MAX_GRID_SIZE-1)*2*3];
|
||||
|
||||
oldheight = 0;
|
||||
width = grid->width;
|
||||
|
@ -788,8 +743,8 @@ srfGridMesh_t *R_GridInsertRow( srfGridMesh_t *grid, int row, int column, vec3_t
|
|||
// put all the aproximating points on the curve
|
||||
//PutPointsOnCurve( ctrl, width, height );
|
||||
|
||||
// calculate triangles
|
||||
numTriangles = MakeMeshTriangles(width, height, ctrl, triangles);
|
||||
// calculate indexes
|
||||
numIndexes = MakeMeshIndexes(width, height, ctrl, indexes);
|
||||
|
||||
// calculate normals
|
||||
MakeMeshNormals( width, height, ctrl );
|
||||
|
@ -799,7 +754,7 @@ srfGridMesh_t *R_GridInsertRow( srfGridMesh_t *grid, int row, int column, vec3_t
|
|||
// free the old grid
|
||||
R_FreeSurfaceGridMesh(grid);
|
||||
// create a new grid
|
||||
grid = R_CreateSurfaceGridMesh(width, height, ctrl, errorTable, numTriangles, triangles);
|
||||
grid = R_CreateSurfaceGridMesh(width, height, ctrl, errorTable, numIndexes, indexes);
|
||||
grid->lodRadius = lodRadius;
|
||||
VectorCopy(lodOrigin, grid->lodOrigin);
|
||||
return grid;
|
||||
|
|
|
@ -701,8 +701,25 @@ void GLimp_InitExtraExtensions()
|
|||
glRefConfig.seamlessCubeMap = qfalse;
|
||||
if( GLimp_HaveExtension( extension ) )
|
||||
{
|
||||
glRefConfig.seamlessCubeMap = qtrue;
|
||||
ri.Printf(PRINT_ALL, result[1], extension);
|
||||
if (r_arb_seamless_cube_map->integer)
|
||||
glRefConfig.seamlessCubeMap = qtrue;
|
||||
|
||||
ri.Printf(PRINT_ALL, result[glRefConfig.seamlessCubeMap], extension);
|
||||
}
|
||||
else
|
||||
{
|
||||
ri.Printf(PRINT_ALL, result[2], extension);
|
||||
}
|
||||
|
||||
// GL_ARB_vertex_type_2_10_10_10_rev
|
||||
extension = "GL_ARB_vertex_type_2_10_10_10_rev";
|
||||
glRefConfig.packedNormalDataType = GL_UNSIGNED_BYTE;
|
||||
if( GLimp_HaveExtension( extension ) )
|
||||
{
|
||||
if (r_arb_vertex_type_2_10_10_10_rev->integer)
|
||||
glRefConfig.packedNormalDataType = GL_UNSIGNED_INT_2_10_10_10_REV;
|
||||
|
||||
ri.Printf(PRINT_ALL, result[r_arb_vertex_type_2_10_10_10_rev->integer ? 1 : 0], extension);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -26,7 +26,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|||
// Some matrix helper functions
|
||||
// FIXME: do these already exist in ioq3 and I don't know about them?
|
||||
|
||||
void Matrix16Zero( matrix_t out )
|
||||
void Mat4Zero( mat4_t out )
|
||||
{
|
||||
out[ 0] = 0.0f; out[ 4] = 0.0f; out[ 8] = 0.0f; out[12] = 0.0f;
|
||||
out[ 1] = 0.0f; out[ 5] = 0.0f; out[ 9] = 0.0f; out[13] = 0.0f;
|
||||
|
@ -34,7 +34,7 @@ void Matrix16Zero( matrix_t out )
|
|||
out[ 3] = 0.0f; out[ 7] = 0.0f; out[11] = 0.0f; out[15] = 0.0f;
|
||||
}
|
||||
|
||||
void Matrix16Identity( matrix_t out )
|
||||
void Mat4Identity( mat4_t out )
|
||||
{
|
||||
out[ 0] = 1.0f; out[ 4] = 0.0f; out[ 8] = 0.0f; out[12] = 0.0f;
|
||||
out[ 1] = 0.0f; out[ 5] = 1.0f; out[ 9] = 0.0f; out[13] = 0.0f;
|
||||
|
@ -42,7 +42,7 @@ void Matrix16Identity( matrix_t out )
|
|||
out[ 3] = 0.0f; out[ 7] = 0.0f; out[11] = 0.0f; out[15] = 1.0f;
|
||||
}
|
||||
|
||||
void Matrix16Copy( const matrix_t in, matrix_t out )
|
||||
void Mat4Copy( const mat4_t in, mat4_t out )
|
||||
{
|
||||
out[ 0] = in[ 0]; out[ 4] = in[ 4]; out[ 8] = in[ 8]; out[12] = in[12];
|
||||
out[ 1] = in[ 1]; out[ 5] = in[ 5]; out[ 9] = in[ 9]; out[13] = in[13];
|
||||
|
@ -50,7 +50,7 @@ void Matrix16Copy( const matrix_t in, matrix_t out )
|
|||
out[ 3] = in[ 3]; out[ 7] = in[ 7]; out[11] = in[11]; out[15] = in[15];
|
||||
}
|
||||
|
||||
void Matrix16Multiply( const matrix_t in1, const matrix_t in2, matrix_t out )
|
||||
void Mat4Multiply( const mat4_t in1, const mat4_t in2, mat4_t out )
|
||||
{
|
||||
out[ 0] = in1[ 0] * in2[ 0] + in1[ 4] * in2[ 1] + in1[ 8] * in2[ 2] + in1[12] * in2[ 3];
|
||||
out[ 1] = in1[ 1] * in2[ 0] + in1[ 5] * in2[ 1] + in1[ 9] * in2[ 2] + in1[13] * in2[ 3];
|
||||
|
@ -73,7 +73,7 @@ void Matrix16Multiply( const matrix_t in1, const matrix_t in2, matrix_t out )
|
|||
out[15] = in1[ 3] * in2[12] + in1[ 7] * in2[13] + in1[11] * in2[14] + in1[15] * in2[15];
|
||||
}
|
||||
|
||||
void Matrix16Transform( const matrix_t in1, const vec4_t in2, vec4_t out )
|
||||
void Mat4Transform( const mat4_t in1, const vec4_t in2, vec4_t out )
|
||||
{
|
||||
out[ 0] = in1[ 0] * in2[ 0] + in1[ 4] * in2[ 1] + in1[ 8] * in2[ 2] + in1[12] * in2[ 3];
|
||||
out[ 1] = in1[ 1] * in2[ 0] + in1[ 5] * in2[ 1] + in1[ 9] * in2[ 2] + in1[13] * in2[ 3];
|
||||
|
@ -81,7 +81,7 @@ void Matrix16Transform( const matrix_t in1, const vec4_t in2, vec4_t out )
|
|||
out[ 3] = in1[ 3] * in2[ 0] + in1[ 7] * in2[ 1] + in1[11] * in2[ 2] + in1[15] * in2[ 3];
|
||||
}
|
||||
|
||||
qboolean Matrix16Compare( const matrix_t a, const matrix_t b )
|
||||
qboolean Mat4Compare( const mat4_t a, const mat4_t b )
|
||||
{
|
||||
return !(a[ 0] != b[ 0] || a[ 4] != b[ 4] || a[ 8] != b[ 8] || a[12] != b[12] ||
|
||||
a[ 1] != b[ 1] || a[ 5] != b[ 5] || a[ 9] != b[ 9] || a[13] != b[13] ||
|
||||
|
@ -89,7 +89,7 @@ qboolean Matrix16Compare( const matrix_t a, const matrix_t b )
|
|||
a[ 3] != b[ 3] || a[ 7] != b[ 7] || a[11] != b[11] || a[15] != b[15]);
|
||||
}
|
||||
|
||||
void Matrix16Dump( const matrix_t in )
|
||||
void Mat4Dump( const mat4_t in )
|
||||
{
|
||||
ri.Printf(PRINT_ALL, "%3.5f %3.5f %3.5f %3.5f\n", in[ 0], in[ 4], in[ 8], in[12]);
|
||||
ri.Printf(PRINT_ALL, "%3.5f %3.5f %3.5f %3.5f\n", in[ 1], in[ 5], in[ 9], in[13]);
|
||||
|
@ -97,7 +97,7 @@ void Matrix16Dump( const matrix_t in )
|
|||
ri.Printf(PRINT_ALL, "%3.5f %3.5f %3.5f %3.5f\n", in[ 3], in[ 7], in[11], in[15]);
|
||||
}
|
||||
|
||||
void Matrix16Translation( vec3_t vec, matrix_t out )
|
||||
void Mat4Translation( vec3_t vec, mat4_t out )
|
||||
{
|
||||
out[ 0] = 1.0f; out[ 4] = 0.0f; out[ 8] = 0.0f; out[12] = vec[0];
|
||||
out[ 1] = 0.0f; out[ 5] = 1.0f; out[ 9] = 0.0f; out[13] = vec[1];
|
||||
|
@ -105,7 +105,7 @@ void Matrix16Translation( vec3_t vec, matrix_t out )
|
|||
out[ 3] = 0.0f; out[ 7] = 0.0f; out[11] = 0.0f; out[15] = 1.0f;
|
||||
}
|
||||
|
||||
void Matrix16Ortho( float left, float right, float bottom, float top, float znear, float zfar, matrix_t out )
|
||||
void Mat4Ortho( float left, float right, float bottom, float top, float znear, float zfar, mat4_t out )
|
||||
{
|
||||
out[ 0] = 2.0f / (right - left); out[ 4] = 0.0f; out[ 8] = 0.0f; out[12] = -(right + left) / (right - left);
|
||||
out[ 1] = 0.0f; out[ 5] = 2.0f / (top - bottom); out[ 9] = 0.0f; out[13] = -(top + bottom) / (top - bottom);
|
||||
|
@ -113,7 +113,7 @@ void Matrix16Ortho( float left, float right, float bottom, float top, float znea
|
|||
out[ 3] = 0.0f; out[ 7] = 0.0f; out[11] = 0.0f; out[15] = 1.0f;
|
||||
}
|
||||
|
||||
void Matrix16View(vec3_t axes[3], vec3_t origin, matrix_t out)
|
||||
void Mat4View(vec3_t axes[3], vec3_t origin, mat4_t out)
|
||||
{
|
||||
out[0] = axes[0][0];
|
||||
out[1] = axes[1][0];
|
||||
|
@ -136,7 +136,7 @@ void Matrix16View(vec3_t axes[3], vec3_t origin, matrix_t out)
|
|||
out[15] = 1;
|
||||
}
|
||||
|
||||
void Matrix16SimpleInverse( const matrix_t in, matrix_t out)
|
||||
void Mat4SimpleInverse( const mat4_t in, mat4_t out)
|
||||
{
|
||||
vec3_t v;
|
||||
float invSqrLen;
|
||||
|
|
|
@ -24,22 +24,22 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|||
#ifndef __TR_EXTRAMATH_H__
|
||||
#define __TR_EXTRAMATH_H__
|
||||
|
||||
typedef vec_t matrix_t[16];
|
||||
typedef int vec2i_t[2];
|
||||
typedef int vec3i_t[3];
|
||||
typedef int vec4i_t[4];
|
||||
typedef vec_t mat4_t[16];
|
||||
typedef int ivec2_t[2];
|
||||
typedef int ivec3_t[3];
|
||||
typedef int ivec4_t[4];
|
||||
|
||||
void Matrix16Zero( matrix_t out );
|
||||
void Matrix16Identity( matrix_t out );
|
||||
void Matrix16Copy( const matrix_t in, matrix_t out );
|
||||
void Matrix16Multiply( const matrix_t in1, const matrix_t in2, matrix_t out );
|
||||
void Matrix16Transform( const matrix_t in1, const vec4_t in2, vec4_t out );
|
||||
qboolean Matrix16Compare(const matrix_t a, const matrix_t b);
|
||||
void Matrix16Dump( const matrix_t in );
|
||||
void Matrix16Translation( vec3_t vec, matrix_t out );
|
||||
void Matrix16Ortho( float left, float right, float bottom, float top, float znear, float zfar, matrix_t out );
|
||||
void Matrix16View(vec3_t axes[3], vec3_t origin, matrix_t out);
|
||||
void Matrix16SimpleInverse( const matrix_t in, matrix_t out);
|
||||
void Mat4Zero( mat4_t out );
|
||||
void Mat4Identity( mat4_t out );
|
||||
void Mat4Copy( const mat4_t in, mat4_t out );
|
||||
void Mat4Multiply( const mat4_t in1, const mat4_t in2, mat4_t out );
|
||||
void Mat4Transform( const mat4_t in1, const vec4_t in2, vec4_t out );
|
||||
qboolean Mat4Compare(const mat4_t a, const mat4_t b);
|
||||
void Mat4Dump( const mat4_t in );
|
||||
void Mat4Translation( vec3_t vec, mat4_t out );
|
||||
void Mat4Ortho( float left, float right, float bottom, float top, float znear, float zfar, mat4_t out );
|
||||
void Mat4View(vec3_t axes[3], vec3_t origin, mat4_t out);
|
||||
void Mat4SimpleInverse( const mat4_t in, mat4_t out);
|
||||
|
||||
#define VectorCopy2(a,b) ((b)[0]=(a)[0],(b)[1]=(a)[1])
|
||||
#define VectorSet2(v,x,y) ((v)[0]=(x),(v)[1]=(y));
|
||||
|
@ -52,7 +52,7 @@ void Matrix16SimpleInverse( const matrix_t in, matrix_t out);
|
|||
#define VectorCopy5(a,b) ((b)[0]=(a)[0],(b)[1]=(a)[1],(b)[2]=(a)[2],(b)[3]=(a)[3],(b)[4]=(a)[4])
|
||||
|
||||
#define OffsetByteToFloat(a) ((float)(a) * 1.0f/127.5f - 1.0f)
|
||||
#define FloatToOffsetByte(a) (byte)(((a) + 1.0f) * 127.5f)
|
||||
#define FloatToOffsetByte(a) (byte)((a) * 127.5f + 128.0f)
|
||||
#define ByteToFloat(a) ((float)(a) * 1.0f/255.0f)
|
||||
#define FloatToByte(a) (byte)((a) * 255.0f)
|
||||
|
||||
|
|
|
@ -386,7 +386,7 @@ void FBO_Init(void)
|
|||
hdrFormat = GL_RGBA8;
|
||||
if (r_hdr->integer && glRefConfig.framebufferObject && glRefConfig.textureFloat)
|
||||
{
|
||||
hdrFormat = GL_RGB16F_ARB;
|
||||
hdrFormat = GL_RGBA16F_ARB;
|
||||
}
|
||||
|
||||
qglGetIntegerv(GL_MAX_SAMPLES_EXT, &multisample);
|
||||
|
@ -465,34 +465,48 @@ void FBO_Init(void)
|
|||
}
|
||||
|
||||
// FIXME: Don't use separate color/depth buffers for a shadow buffer
|
||||
for( i = 0; i < MAX_DRAWN_PSHADOWS; i++)
|
||||
if (MAX_DRAWN_PSHADOWS && tr.pshadowMaps[0])
|
||||
{
|
||||
tr.pshadowFbos[i] = FBO_Create(va("_shadowmap%d", i), tr.pshadowMaps[i]->width, tr.pshadowMaps[i]->height);
|
||||
FBO_Bind(tr.pshadowFbos[i]);
|
||||
for( i = 0; i < MAX_DRAWN_PSHADOWS; i++)
|
||||
{
|
||||
tr.pshadowFbos[i] = FBO_Create(va("_shadowmap%d", i), tr.pshadowMaps[i]->width, tr.pshadowMaps[i]->height);
|
||||
FBO_Bind(tr.pshadowFbos[i]);
|
||||
|
||||
//FBO_CreateBuffer(tr.pshadowFbos[i], GL_RGBA8, 0, 0);
|
||||
FBO_AttachTextureImage(tr.pshadowMaps[i], 0);
|
||||
//FBO_CreateBuffer(tr.pshadowFbos[i], GL_RGBA8, 0, 0);
|
||||
FBO_AttachTextureImage(tr.pshadowMaps[i], 0);
|
||||
|
||||
FBO_CreateBuffer(tr.pshadowFbos[i], GL_DEPTH_COMPONENT24_ARB, 0, 0);
|
||||
//R_AttachFBOTextureDepth(tr.textureDepthImage->texnum);
|
||||
FBO_CreateBuffer(tr.pshadowFbos[i], GL_DEPTH_COMPONENT24_ARB, 0, 0);
|
||||
//R_AttachFBOTextureDepth(tr.textureDepthImage->texnum);
|
||||
|
||||
R_CheckFBO(tr.pshadowFbos[i]);
|
||||
R_CheckFBO(tr.pshadowFbos[i]);
|
||||
}
|
||||
}
|
||||
|
||||
for ( i = 0; i < 3; i++)
|
||||
if (tr.sunShadowDepthImage[0])
|
||||
{
|
||||
tr.sunShadowFbo[i] = FBO_Create("_sunshadowmap", tr.sunShadowDepthImage[i]->width, tr.sunShadowDepthImage[i]->height);
|
||||
FBO_Bind(tr.sunShadowFbo[i]);
|
||||
for ( i = 0; i < 3; i++)
|
||||
{
|
||||
tr.sunShadowFbo[i] = FBO_Create("_sunshadowmap", tr.sunShadowDepthImage[i]->width, tr.sunShadowDepthImage[i]->height);
|
||||
FBO_Bind(tr.sunShadowFbo[i]);
|
||||
|
||||
//FBO_CreateBuffer(tr.sunShadowFbo[i], GL_RGBA8, 0, 0);
|
||||
//FBO_AttachTextureImage(tr.sunShadowImage, 0);
|
||||
qglDrawBuffer(GL_NONE);
|
||||
qglReadBuffer(GL_NONE);
|
||||
//FBO_CreateBuffer(tr.sunShadowFbo[i], GL_RGBA8, 0, 0);
|
||||
//FBO_AttachTextureImage(tr.sunShadowImage, 0);
|
||||
qglDrawBuffer(GL_NONE);
|
||||
qglReadBuffer(GL_NONE);
|
||||
|
||||
//FBO_CreateBuffer(tr.sunShadowFbo, GL_DEPTH_COMPONENT24_ARB, 0, 0);
|
||||
R_AttachFBOTextureDepth(tr.sunShadowDepthImage[i]->texnum);
|
||||
//FBO_CreateBuffer(tr.sunShadowFbo, GL_DEPTH_COMPONENT24_ARB, 0, 0);
|
||||
R_AttachFBOTextureDepth(tr.sunShadowDepthImage[i]->texnum);
|
||||
|
||||
R_CheckFBO(tr.sunShadowFbo[i]);
|
||||
R_CheckFBO(tr.sunShadowFbo[i]);
|
||||
|
||||
}
|
||||
|
||||
tr.screenShadowFbo = FBO_Create("_screenshadow", tr.screenShadowImage->width, tr.screenShadowImage->height);
|
||||
FBO_Bind(tr.screenShadowFbo);
|
||||
|
||||
FBO_AttachTextureImage(tr.screenShadowImage, 0);
|
||||
|
||||
R_CheckFBO(tr.screenShadowFbo);
|
||||
}
|
||||
|
||||
for (i = 0; i < 2; i++)
|
||||
|
@ -526,22 +540,6 @@ void FBO_Init(void)
|
|||
R_CheckFBO(tr.targetLevelsFbo);
|
||||
}
|
||||
|
||||
if (r_softOverbright->integer)
|
||||
{
|
||||
//tr.screenScratchFbo = FBO_Create("_screenscratch", width, height);
|
||||
tr.screenScratchFbo = FBO_Create("_screenscratch", tr.screenScratchImage->width, tr.screenScratchImage->height);
|
||||
FBO_Bind(tr.screenScratchFbo);
|
||||
|
||||
//FBO_CreateBuffer(tr.screenScratchFbo, format, 0, 0);
|
||||
FBO_AttachTextureImage(tr.screenScratchImage, 0);
|
||||
|
||||
// FIXME: hack: share zbuffer between render fbo and pre-screen fbo
|
||||
//FBO_CreateBuffer(tr.screenScratchFbo, GL_DEPTH_COMPONENT24_ARB, 0, 0);
|
||||
R_AttachFBOTextureDepth(tr.renderDepthImage->texnum);
|
||||
|
||||
R_CheckFBO(tr.screenScratchFbo);
|
||||
}
|
||||
|
||||
for (i = 0; i < 2; i++)
|
||||
{
|
||||
tr.quarterFbo[i] = FBO_Create(va("_quarter%d", i), tr.quarterImage[i]->width, tr.quarterImage[i]->height);
|
||||
|
@ -553,15 +551,6 @@ void FBO_Init(void)
|
|||
R_CheckFBO(tr.quarterFbo[i]);
|
||||
}
|
||||
|
||||
{
|
||||
tr.screenShadowFbo = FBO_Create("_screenshadow", tr.screenShadowImage->width, tr.screenShadowImage->height);
|
||||
FBO_Bind(tr.screenShadowFbo);
|
||||
|
||||
FBO_AttachTextureImage(tr.screenShadowImage, 0);
|
||||
|
||||
R_CheckFBO(tr.screenShadowFbo);
|
||||
}
|
||||
|
||||
if (r_ssao->integer)
|
||||
{
|
||||
tr.hdrDepthFbo = FBO_Create("_hdrDepth", tr.hdrDepthImage->width, tr.hdrDepthImage->height);
|
||||
|
@ -579,6 +568,7 @@ void FBO_Init(void)
|
|||
R_CheckFBO(tr.screenSsaoFbo);
|
||||
}
|
||||
|
||||
if (tr.renderCubeImage)
|
||||
{
|
||||
tr.renderCubeFbo = FBO_Create("_renderCubeFbo", tr.renderCubeImage->width, tr.renderCubeImage->height);
|
||||
FBO_Bind(tr.renderCubeFbo);
|
||||
|
@ -667,16 +657,16 @@ void R_FBOList_f(void)
|
|||
// FIXME
|
||||
extern void RB_SetGL2D (void);
|
||||
|
||||
void FBO_BlitFromTexture(struct image_s *src, vec4i_t inSrcBox, vec2_t inSrcTexScale, FBO_t *dst, vec4i_t inDstBox, struct shaderProgram_s *shaderProgram, vec4_t inColor, int blend)
|
||||
void FBO_BlitFromTexture(struct image_s *src, ivec4_t inSrcBox, vec2_t inSrcTexScale, FBO_t *dst, ivec4_t inDstBox, struct shaderProgram_s *shaderProgram, vec4_t inColor, int blend)
|
||||
{
|
||||
vec4i_t dstBox, srcBox;
|
||||
ivec4_t dstBox, srcBox;
|
||||
vec2_t srcTexScale;
|
||||
vec4_t color;
|
||||
vec4_t quadVerts[4];
|
||||
vec2_t texCoords[4];
|
||||
vec2_t invTexRes;
|
||||
FBO_t *oldFbo = glState.currentFBO;
|
||||
matrix_t projection;
|
||||
mat4_t projection;
|
||||
int width, height;
|
||||
|
||||
if (!src)
|
||||
|
@ -757,7 +747,7 @@ void FBO_BlitFromTexture(struct image_s *src, vec4i_t inSrcBox, vec2_t inSrcTexS
|
|||
qglViewport( 0, 0, width, height );
|
||||
qglScissor( 0, 0, width, height );
|
||||
|
||||
Matrix16Ortho(0, width, height, 0, 0, 1, projection);
|
||||
Mat4Ortho(0, width, height, 0, 0, 1, projection);
|
||||
|
||||
qglDisable( GL_CULL_FACE );
|
||||
|
||||
|
@ -780,7 +770,7 @@ void FBO_BlitFromTexture(struct image_s *src, vec4i_t inSrcBox, vec2_t inSrcTexS
|
|||
|
||||
GLSL_BindProgram(shaderProgram);
|
||||
|
||||
GLSL_SetUniformMatrix16(shaderProgram, UNIFORM_MODELVIEWPROJECTIONMATRIX, projection);
|
||||
GLSL_SetUniformMat4(shaderProgram, UNIFORM_MODELVIEWPROJECTIONMATRIX, projection);
|
||||
GLSL_SetUniformVec4(shaderProgram, UNIFORM_COLOR, color);
|
||||
GLSL_SetUniformVec2(shaderProgram, UNIFORM_INVTEXRES, invTexRes);
|
||||
GLSL_SetUniformVec2(shaderProgram, UNIFORM_AUTOEXPOSUREMINMAX, tr.refdef.autoExposureMinMax);
|
||||
|
@ -791,9 +781,9 @@ void FBO_BlitFromTexture(struct image_s *src, vec4i_t inSrcBox, vec2_t inSrcTexS
|
|||
FBO_Bind(oldFbo);
|
||||
}
|
||||
|
||||
void FBO_Blit(FBO_t *src, vec4i_t inSrcBox, vec2_t srcTexScale, FBO_t *dst, vec4i_t dstBox, struct shaderProgram_s *shaderProgram, vec4_t color, int blend)
|
||||
void FBO_Blit(FBO_t *src, ivec4_t inSrcBox, vec2_t srcTexScale, FBO_t *dst, ivec4_t dstBox, struct shaderProgram_s *shaderProgram, vec4_t color, int blend)
|
||||
{
|
||||
vec4i_t srcBox;
|
||||
ivec4_t srcBox;
|
||||
|
||||
if (!src)
|
||||
{
|
||||
|
@ -817,9 +807,9 @@ void FBO_Blit(FBO_t *src, vec4i_t inSrcBox, vec2_t srcTexScale, FBO_t *dst, vec4
|
|||
FBO_BlitFromTexture(src->colorImage[0], srcBox, srcTexScale, dst, dstBox, shaderProgram, color, blend | GLS_DEPTHTEST_DISABLE);
|
||||
}
|
||||
|
||||
void FBO_FastBlit(FBO_t *src, vec4i_t srcBox, FBO_t *dst, vec4i_t dstBox, int buffers, int filter)
|
||||
void FBO_FastBlit(FBO_t *src, ivec4_t srcBox, FBO_t *dst, ivec4_t dstBox, int buffers, int filter)
|
||||
{
|
||||
vec4i_t srcBoxFinal, dstBoxFinal;
|
||||
ivec4_t srcBoxFinal, dstBoxFinal;
|
||||
GLuint srcFb, dstFb;
|
||||
|
||||
if (!glRefConfig.framebufferBlit)
|
||||
|
|
|
@ -56,9 +56,9 @@ void FBO_Bind(FBO_t *fbo);
|
|||
void FBO_Init(void);
|
||||
void FBO_Shutdown(void);
|
||||
|
||||
void FBO_BlitFromTexture(struct image_s *src, vec4i_t srcBox, vec2_t srcTexScale, FBO_t *dst, vec4i_t dstBox, struct shaderProgram_s *shaderProgram, vec4_t color, int blend);
|
||||
void FBO_Blit(FBO_t *src, vec4i_t srcBox, vec2_t srcTexScale, FBO_t *dst, vec4i_t dstBox, struct shaderProgram_s *shaderProgram, vec4_t color, int blend);
|
||||
void FBO_FastBlit(FBO_t *src, vec4i_t srcBox, FBO_t *dst, vec4i_t dstBox, int buffers, int filter);
|
||||
void FBO_BlitFromTexture(struct image_s *src, ivec4_t srcBox, vec2_t srcTexScale, FBO_t *dst, ivec4_t dstBox, struct shaderProgram_s *shaderProgram, vec4_t color, int blend);
|
||||
void FBO_Blit(FBO_t *src, ivec4_t srcBox, vec2_t srcTexScale, FBO_t *dst, ivec4_t dstBox, struct shaderProgram_s *shaderProgram, vec4_t color, int blend);
|
||||
void FBO_FastBlit(FBO_t *src, ivec4_t srcBox, FBO_t *dst, ivec4_t dstBox, int buffers, int filter);
|
||||
|
||||
|
||||
#endif
|
||||
|
|
|
@ -86,6 +86,19 @@ flare_t *r_activeFlares, *r_inactiveFlares;
|
|||
|
||||
int flareCoeff;
|
||||
|
||||
/*
|
||||
==================
|
||||
R_SetFlareCoeff
|
||||
==================
|
||||
*/
|
||||
static void R_SetFlareCoeff( void ) {
|
||||
|
||||
if(r_flareCoeff->value == 0.0f)
|
||||
flareCoeff = atof(FLARE_STDCOEFF);
|
||||
else
|
||||
flareCoeff = r_flareCoeff->value;
|
||||
}
|
||||
|
||||
/*
|
||||
==================
|
||||
R_ClearFlares
|
||||
|
@ -102,6 +115,8 @@ void R_ClearFlares( void ) {
|
|||
r_flareStructs[i].next = r_inactiveFlares;
|
||||
r_inactiveFlares = &r_flareStructs[i];
|
||||
}
|
||||
|
||||
R_SetFlareCoeff();
|
||||
}
|
||||
|
||||
|
||||
|
@ -262,6 +277,7 @@ void RB_TestFlare( flare_t *f ) {
|
|||
qboolean visible;
|
||||
float fade;
|
||||
float screenZ;
|
||||
FBO_t *oldFbo;
|
||||
|
||||
backEnd.pc.c_flareTests++;
|
||||
|
||||
|
@ -269,9 +285,22 @@ void RB_TestFlare( flare_t *f ) {
|
|||
// don't bother with another sync
|
||||
glState.finishCalled = qfalse;
|
||||
|
||||
// if we're doing multisample rendering, read from the correct FBO
|
||||
oldFbo = glState.currentFBO;
|
||||
if (tr.msaaResolveFbo)
|
||||
{
|
||||
FBO_Bind(tr.msaaResolveFbo);
|
||||
}
|
||||
|
||||
// read back the z buffer contents
|
||||
qglReadPixels( f->windowX, f->windowY, 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT, &depth );
|
||||
|
||||
// if we're doing multisample rendering, switch to the old FBO
|
||||
if (tr.msaaResolveFbo)
|
||||
{
|
||||
FBO_Bind(oldFbo);
|
||||
}
|
||||
|
||||
screenZ = backEnd.viewParms.projectionMatrix[14] /
|
||||
( ( 2*depth - 1 ) * backEnd.viewParms.projectionMatrix[11] - backEnd.viewParms.projectionMatrix[10] );
|
||||
|
||||
|
@ -443,7 +472,7 @@ void RB_RenderFlares (void) {
|
|||
flare_t *f;
|
||||
flare_t **prev;
|
||||
qboolean draw;
|
||||
matrix_t oldmodelview, oldprojection, matrix;
|
||||
mat4_t oldmodelview, oldprojection, matrix;
|
||||
|
||||
if ( !r_flares->integer ) {
|
||||
return;
|
||||
|
@ -451,11 +480,7 @@ void RB_RenderFlares (void) {
|
|||
|
||||
if(r_flareCoeff->modified)
|
||||
{
|
||||
if(r_flareCoeff->value == 0.0f)
|
||||
flareCoeff = atof(FLARE_STDCOEFF);
|
||||
else
|
||||
flareCoeff = r_flareCoeff->value;
|
||||
|
||||
R_SetFlareCoeff();
|
||||
r_flareCoeff->modified = qfalse;
|
||||
}
|
||||
|
||||
|
@ -505,11 +530,11 @@ void RB_RenderFlares (void) {
|
|||
qglDisable (GL_CLIP_PLANE0);
|
||||
}
|
||||
|
||||
Matrix16Copy(glState.projection, oldprojection);
|
||||
Matrix16Copy(glState.modelview, oldmodelview);
|
||||
Matrix16Identity(matrix);
|
||||
Mat4Copy(glState.projection, oldprojection);
|
||||
Mat4Copy(glState.modelview, oldmodelview);
|
||||
Mat4Identity(matrix);
|
||||
GL_SetModelviewMatrix(matrix);
|
||||
Matrix16Ortho( backEnd.viewParms.viewportX, backEnd.viewParms.viewportX + backEnd.viewParms.viewportWidth,
|
||||
Mat4Ortho( backEnd.viewParms.viewportX, backEnd.viewParms.viewportX + backEnd.viewParms.viewportWidth,
|
||||
backEnd.viewParms.viewportY, backEnd.viewParms.viewportY + backEnd.viewParms.viewportHeight,
|
||||
-99999, 99999, matrix );
|
||||
GL_SetProjectionMatrix(matrix);
|
||||
|
|
|
@ -84,6 +84,8 @@ static uniformInfo_t uniformsInfo[] =
|
|||
{ "u_ShadowMvp2", GLSL_MAT16 },
|
||||
{ "u_ShadowMvp3", GLSL_MAT16 },
|
||||
|
||||
{ "u_EnableTextures", GLSL_VEC4 },
|
||||
|
||||
{ "u_DiffuseTexMatrix", GLSL_VEC4 },
|
||||
{ "u_DiffuseTexOffTurb", GLSL_VEC4 },
|
||||
{ "u_Texture1Env", GLSL_INT },
|
||||
|
@ -106,6 +108,7 @@ static uniformInfo_t uniformsInfo[] =
|
|||
{ "u_LightUp", GLSL_VEC3 },
|
||||
{ "u_LightRight", GLSL_VEC3 },
|
||||
{ "u_LightOrigin", GLSL_VEC4 },
|
||||
{ "u_ModelLightDir", GLSL_VEC3 },
|
||||
{ "u_LightRadius", GLSL_FLOAT },
|
||||
{ "u_AmbientLight", GLSL_VEC3 },
|
||||
{ "u_DirectedLight", GLSL_VEC3 },
|
||||
|
@ -124,11 +127,12 @@ static uniformInfo_t uniformsInfo[] =
|
|||
{ "u_VertexLerp" , GLSL_FLOAT },
|
||||
{ "u_MaterialInfo", GLSL_VEC2 },
|
||||
|
||||
{ "u_ViewInfo", GLSL_VEC4 },
|
||||
{ "u_ViewOrigin", GLSL_VEC3 },
|
||||
{ "u_ViewForward", GLSL_VEC3 },
|
||||
{ "u_ViewLeft", GLSL_VEC3 },
|
||||
{ "u_ViewUp", GLSL_VEC3 },
|
||||
{ "u_ViewInfo", GLSL_VEC4 },
|
||||
{ "u_ViewOrigin", GLSL_VEC3 },
|
||||
{ "u_LocalViewOrigin", GLSL_VEC3 },
|
||||
{ "u_ViewForward", GLSL_VEC3 },
|
||||
{ "u_ViewLeft", GLSL_VEC3 },
|
||||
{ "u_ViewUp", GLSL_VEC3 },
|
||||
|
||||
{ "u_InvTexRes", GLSL_VEC2 },
|
||||
{ "u_AutoExposureMinMax", GLSL_VEC2 },
|
||||
|
@ -294,11 +298,9 @@ static void GLSL_GetShaderHeader( GLenum shaderType, const GLcharARB *extra, cha
|
|||
"#define alphaGen_t\n"
|
||||
"#define AGEN_LIGHTING_SPECULAR %i\n"
|
||||
"#define AGEN_PORTAL %i\n"
|
||||
"#define AGEN_FRESNEL %i\n"
|
||||
"#endif\n",
|
||||
AGEN_LIGHTING_SPECULAR,
|
||||
AGEN_PORTAL,
|
||||
AGEN_FRESNEL));
|
||||
AGEN_PORTAL));
|
||||
|
||||
Q_strcat(dest, size,
|
||||
va("#ifndef texenv_t\n"
|
||||
|
@ -526,9 +528,6 @@ static int GLSL_InitGPUShader2(shaderProgram_t * program, const char *name, int
|
|||
#ifdef USE_VERT_TANGENT_SPACE
|
||||
if(attribs & ATTR_TANGENT)
|
||||
qglBindAttribLocationARB(program->program, ATTR_INDEX_TANGENT, "attr_Tangent");
|
||||
|
||||
if(attribs & ATTR_BITANGENT)
|
||||
qglBindAttribLocationARB(program->program, ATTR_INDEX_BITANGENT, "attr_Bitangent");
|
||||
#endif
|
||||
|
||||
if(attribs & ATTR_NORMAL)
|
||||
|
@ -552,9 +551,6 @@ static int GLSL_InitGPUShader2(shaderProgram_t * program, const char *name, int
|
|||
#ifdef USE_VERT_TANGENT_SPACE
|
||||
if(attribs & ATTR_TANGENT2)
|
||||
qglBindAttribLocationARB(program->program, ATTR_INDEX_TANGENT2, "attr_Tangent2");
|
||||
|
||||
if(attribs & ATTR_BITANGENT2)
|
||||
qglBindAttribLocationARB(program->program, ATTR_INDEX_BITANGENT2, "attr_Bitangent2");
|
||||
#endif
|
||||
|
||||
GLSL_LinkProgram(program->program);
|
||||
|
@ -813,7 +809,7 @@ void GLSL_SetUniformFloat5(shaderProgram_t *program, int uniformNum, const vec5_
|
|||
qglUniform1fvARB(uniforms[uniformNum], 5, v);
|
||||
}
|
||||
|
||||
void GLSL_SetUniformMatrix16(shaderProgram_t *program, int uniformNum, const matrix_t matrix)
|
||||
void GLSL_SetUniformMat4(shaderProgram_t *program, int uniformNum, const mat4_t matrix)
|
||||
{
|
||||
GLint *uniforms = program->uniforms;
|
||||
vec_t *compare = (float *)(program->uniformBuffer + program->uniformBufferOffsets[uniformNum]);
|
||||
|
@ -823,16 +819,16 @@ void GLSL_SetUniformMatrix16(shaderProgram_t *program, int uniformNum, const mat
|
|||
|
||||
if (uniformsInfo[uniformNum].type != GLSL_MAT16)
|
||||
{
|
||||
ri.Printf( PRINT_WARNING, "GLSL_SetUniformMatrix16: wrong type for uniform %i in program %s\n", uniformNum, program->name);
|
||||
ri.Printf( PRINT_WARNING, "GLSL_SetUniformMat4: wrong type for uniform %i in program %s\n", uniformNum, program->name);
|
||||
return;
|
||||
}
|
||||
|
||||
if (Matrix16Compare(matrix, compare))
|
||||
if (Mat4Compare(matrix, compare))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Matrix16Copy(matrix, compare);
|
||||
Mat4Copy(matrix, compare);
|
||||
|
||||
qglUniformMatrix4fvARB(uniforms[uniformNum], 1, GL_FALSE, matrix);
|
||||
}
|
||||
|
@ -907,7 +903,7 @@ void GLSL_InitGPUShaders(void)
|
|||
if (i & GENERICDEF_USE_LIGHTMAP)
|
||||
Q_strcat(extradefines, 1024, "#define USE_LIGHTMAP\n");
|
||||
|
||||
if (r_hdr->integer && !(glRefConfig.textureFloat && glRefConfig.halfFloatPixel))
|
||||
if (r_hdr->integer && !(glRefConfig.textureFloat && glRefConfig.halfFloatPixel && r_floatLightmap->integer))
|
||||
Q_strcat(extradefines, 1024, "#define RGBM_LIGHTMAP\n");
|
||||
|
||||
if (!GLSL_InitGPUShader(&tr.genericShader[i], "generic", attribs, qtrue, extradefines, qtrue, fallbackShader_generic_vp, fallbackShader_generic_fp))
|
||||
|
@ -997,27 +993,19 @@ void GLSL_InitGPUShaders(void)
|
|||
|
||||
for (i = 0; i < LIGHTDEF_COUNT; i++)
|
||||
{
|
||||
int lightType = i & LIGHTDEF_LIGHTTYPE_MASK;
|
||||
qboolean fastLight = !(r_normalMapping->integer || r_specularMapping->integer);
|
||||
|
||||
// skip impossible combos
|
||||
if ((i & LIGHTDEF_USE_PARALLAXMAP) && !r_parallaxMapping->integer)
|
||||
continue;
|
||||
|
||||
if ((i & LIGHTDEF_USE_DELUXEMAP) && !r_deluxeMapping->integer)
|
||||
if (!lightType && (i & LIGHTDEF_USE_PARALLAXMAP))
|
||||
continue;
|
||||
|
||||
if ((i & LIGHTDEF_USE_CUBEMAP) && !r_cubeMapping->integer)
|
||||
if (!lightType && (i & LIGHTDEF_USE_SHADOWMAP))
|
||||
continue;
|
||||
|
||||
if (!((i & LIGHTDEF_LIGHTTYPE_MASK) == LIGHTDEF_USE_LIGHTMAP) && (i & LIGHTDEF_USE_DELUXEMAP))
|
||||
continue;
|
||||
|
||||
if (!(i & LIGHTDEF_LIGHTTYPE_MASK))
|
||||
{
|
||||
if (i & LIGHTDEF_USE_SHADOWMAP)
|
||||
continue;
|
||||
if (i & LIGHTDEF_USE_CUBEMAP)
|
||||
continue;
|
||||
}
|
||||
|
||||
attribs = ATTR_POSITION | ATTR_TEXCOORD | ATTR_COLOR | ATTR_NORMAL;
|
||||
|
||||
extradefines[0] = '\0';
|
||||
|
@ -1026,30 +1014,30 @@ void GLSL_InitGPUShaders(void)
|
|||
Q_strcat(extradefines, 1024, va("#define r_deluxeSpecular %f\n", r_deluxeSpecular->value));
|
||||
|
||||
if (r_specularIsMetallic->value)
|
||||
Q_strcat(extradefines, 1024, va("#define SPECULAR_IS_METALLIC\n"));
|
||||
Q_strcat(extradefines, 1024, "#define SPECULAR_IS_METALLIC\n");
|
||||
|
||||
if (r_dlightMode->integer >= 2)
|
||||
Q_strcat(extradefines, 1024, "#define USE_SHADOWMAP\n");
|
||||
|
||||
if (1)
|
||||
{
|
||||
Q_strcat(extradefines, 1024, "#define SWIZZLE_NORMALMAP\n");
|
||||
}
|
||||
|
||||
if (r_hdr->integer && !(glRefConfig.textureFloat && glRefConfig.halfFloatPixel))
|
||||
if (r_hdr->integer && !(glRefConfig.textureFloat && glRefConfig.halfFloatPixel && r_floatLightmap->integer))
|
||||
Q_strcat(extradefines, 1024, "#define RGBM_LIGHTMAP\n");
|
||||
|
||||
if (i & LIGHTDEF_LIGHTTYPE_MASK)
|
||||
if (lightType)
|
||||
{
|
||||
Q_strcat(extradefines, 1024, "#define USE_LIGHT\n");
|
||||
|
||||
if (r_normalMapping->integer == 0 && r_specularMapping->integer == 0)
|
||||
if (fastLight)
|
||||
Q_strcat(extradefines, 1024, "#define USE_FAST_LIGHT\n");
|
||||
|
||||
switch (i & LIGHTDEF_LIGHTTYPE_MASK)
|
||||
switch (lightType)
|
||||
{
|
||||
case LIGHTDEF_USE_LIGHTMAP:
|
||||
Q_strcat(extradefines, 1024, "#define USE_LIGHTMAP\n");
|
||||
if (r_deluxeMapping->integer && !fastLight)
|
||||
Q_strcat(extradefines, 1024, "#define USE_DELUXEMAP\n");
|
||||
attribs |= ATTR_LIGHTCOORD | ATTR_LIGHTDIRECTION;
|
||||
break;
|
||||
case LIGHTDEF_USE_LIGHT_VECTOR:
|
||||
|
@ -1062,62 +1050,59 @@ void GLSL_InitGPUShaders(void)
|
|||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (r_normalMapping->integer)
|
||||
{
|
||||
Q_strcat(extradefines, 1024, "#define USE_NORMALMAP\n");
|
||||
if (r_normalMapping->integer)
|
||||
{
|
||||
Q_strcat(extradefines, 1024, "#define USE_NORMALMAP\n");
|
||||
|
||||
if (r_normalMapping->integer == 2)
|
||||
Q_strcat(extradefines, 1024, "#define USE_OREN_NAYAR\n");
|
||||
if (r_normalMapping->integer == 2)
|
||||
Q_strcat(extradefines, 1024, "#define USE_OREN_NAYAR\n");
|
||||
|
||||
if (r_normalMapping->integer == 3)
|
||||
Q_strcat(extradefines, 1024, "#define USE_TRIACE_OREN_NAYAR\n");
|
||||
if (r_normalMapping->integer == 3)
|
||||
Q_strcat(extradefines, 1024, "#define USE_TRIACE_OREN_NAYAR\n");
|
||||
|
||||
#ifdef USE_VERT_TANGENT_SPACE
|
||||
Q_strcat(extradefines, 1024, "#define USE_VERT_TANGENT_SPACE\n");
|
||||
attribs |= ATTR_TANGENT | ATTR_BITANGENT;
|
||||
Q_strcat(extradefines, 1024, "#define USE_VERT_TANGENT_SPACE\n");
|
||||
attribs |= ATTR_TANGENT;
|
||||
#endif
|
||||
}
|
||||
|
||||
if (r_specularMapping->integer)
|
||||
{
|
||||
Q_strcat(extradefines, 1024, "#define USE_SPECULARMAP\n");
|
||||
|
||||
switch (r_specularMapping->integer)
|
||||
{
|
||||
case 1:
|
||||
default:
|
||||
Q_strcat(extradefines, 1024, "#define USE_BLINN\n");
|
||||
break;
|
||||
|
||||
case 2:
|
||||
Q_strcat(extradefines, 1024, "#define USE_BLINN_FRESNEL\n");
|
||||
break;
|
||||
|
||||
case 3:
|
||||
Q_strcat(extradefines, 1024, "#define USE_MCAULEY\n");
|
||||
break;
|
||||
|
||||
case 4:
|
||||
Q_strcat(extradefines, 1024, "#define USE_GOTANDA\n");
|
||||
break;
|
||||
|
||||
case 5:
|
||||
Q_strcat(extradefines, 1024, "#define USE_LAZAROV\n");
|
||||
break;
|
||||
if ((i & LIGHTDEF_USE_PARALLAXMAP) && !(i & LIGHTDEF_ENTITY) && r_parallaxMapping->integer)
|
||||
Q_strcat(extradefines, 1024, "#define USE_PARALLAXMAP\n");
|
||||
}
|
||||
|
||||
if (r_specularMapping->integer)
|
||||
{
|
||||
Q_strcat(extradefines, 1024, "#define USE_SPECULARMAP\n");
|
||||
|
||||
switch (r_specularMapping->integer)
|
||||
{
|
||||
case 1:
|
||||
default:
|
||||
Q_strcat(extradefines, 1024, "#define USE_BLINN\n");
|
||||
break;
|
||||
|
||||
case 2:
|
||||
Q_strcat(extradefines, 1024, "#define USE_BLINN_FRESNEL\n");
|
||||
break;
|
||||
|
||||
case 3:
|
||||
Q_strcat(extradefines, 1024, "#define USE_MCAULEY\n");
|
||||
break;
|
||||
|
||||
case 4:
|
||||
Q_strcat(extradefines, 1024, "#define USE_GOTANDA\n");
|
||||
break;
|
||||
|
||||
case 5:
|
||||
Q_strcat(extradefines, 1024, "#define USE_LAZAROV\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (r_cubeMapping->integer)
|
||||
Q_strcat(extradefines, 1024, "#define USE_CUBEMAP\n");
|
||||
}
|
||||
|
||||
if ((i & LIGHTDEF_USE_DELUXEMAP) && r_deluxeMapping->integer)
|
||||
Q_strcat(extradefines, 1024, "#define USE_DELUXEMAP\n");
|
||||
|
||||
if ((i & LIGHTDEF_USE_PARALLAXMAP) && !(i & LIGHTDEF_ENTITY) && r_parallaxMapping->integer)
|
||||
Q_strcat(extradefines, 1024, "#define USE_PARALLAXMAP\n");
|
||||
|
||||
if ((i & LIGHTDEF_USE_CUBEMAP))
|
||||
Q_strcat(extradefines, 1024, "#define USE_CUBEMAP\n");
|
||||
|
||||
if (i & LIGHTDEF_USE_SHADOWMAP)
|
||||
{
|
||||
Q_strcat(extradefines, 1024, "#define USE_SHADOWMAP\n");
|
||||
|
@ -1142,7 +1127,7 @@ void GLSL_InitGPUShaders(void)
|
|||
#ifdef USE_VERT_TANGENT_SPACE
|
||||
if (r_normalMapping->integer)
|
||||
{
|
||||
attribs |= ATTR_TANGENT2 | ATTR_BITANGENT2;
|
||||
attribs |= ATTR_TANGENT2;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
@ -1409,12 +1394,10 @@ void GLSL_ShutdownGPUShaders(void)
|
|||
qglDisableVertexAttribArrayARB(ATTR_INDEX_NORMAL);
|
||||
#ifdef USE_VERT_TANGENT_SPACE
|
||||
qglDisableVertexAttribArrayARB(ATTR_INDEX_TANGENT);
|
||||
qglDisableVertexAttribArrayARB(ATTR_INDEX_BITANGENT);
|
||||
#endif
|
||||
qglDisableVertexAttribArrayARB(ATTR_INDEX_NORMAL2);
|
||||
#ifdef USE_VERT_TANGENT_SPACE
|
||||
qglDisableVertexAttribArrayARB(ATTR_INDEX_TANGENT2);
|
||||
qglDisableVertexAttribArrayARB(ATTR_INDEX_BITANGENT2);
|
||||
#endif
|
||||
qglDisableVertexAttribArrayARB(ATTR_INDEX_COLOR);
|
||||
qglDisableVertexAttribArrayARB(ATTR_INDEX_LIGHTDIRECTION);
|
||||
|
@ -1574,20 +1557,6 @@ void GLSL_VertexAttribsState(uint32_t stateBits)
|
|||
qglDisableVertexAttribArrayARB(ATTR_INDEX_TANGENT);
|
||||
}
|
||||
}
|
||||
|
||||
if(diff & ATTR_BITANGENT)
|
||||
{
|
||||
if(stateBits & ATTR_BITANGENT)
|
||||
{
|
||||
GLimp_LogComment("qglEnableVertexAttribArrayARB( ATTR_INDEX_BITANGENT )\n");
|
||||
qglEnableVertexAttribArrayARB(ATTR_INDEX_BITANGENT);
|
||||
}
|
||||
else
|
||||
{
|
||||
GLimp_LogComment("qglDisableVertexAttribArrayARB( ATTR_INDEX_BITANGENT )\n");
|
||||
qglDisableVertexAttribArrayARB(ATTR_INDEX_BITANGENT);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if(diff & ATTR_COLOR)
|
||||
|
@ -1660,20 +1629,6 @@ void GLSL_VertexAttribsState(uint32_t stateBits)
|
|||
qglDisableVertexAttribArrayARB(ATTR_INDEX_TANGENT2);
|
||||
}
|
||||
}
|
||||
|
||||
if(diff & ATTR_BITANGENT2)
|
||||
{
|
||||
if(stateBits & ATTR_BITANGENT2)
|
||||
{
|
||||
GLimp_LogComment("qglEnableVertexAttribArrayARB( ATTR_INDEX_BITANGENT2 )\n");
|
||||
qglEnableVertexAttribArrayARB(ATTR_INDEX_BITANGENT2);
|
||||
}
|
||||
else
|
||||
{
|
||||
GLimp_LogComment("qglDisableVertexAttribArrayARB( ATTR_INDEX_BITANGENT2 )\n");
|
||||
qglDisableVertexAttribArrayARB(ATTR_INDEX_BITANGENT2);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
glState.vertexAttribsState = stateBits;
|
||||
|
@ -1683,26 +1638,30 @@ void GLSL_VertexAttribPointers(uint32_t attribBits)
|
|||
{
|
||||
qboolean animated;
|
||||
int newFrame, oldFrame;
|
||||
VBO_t *vbo = glState.currentVBO;
|
||||
|
||||
if(!glState.currentVBO)
|
||||
if(!vbo)
|
||||
{
|
||||
ri.Error(ERR_FATAL, "GL_VertexAttribPointers: no VBO bound");
|
||||
return;
|
||||
}
|
||||
|
||||
// don't just call LogComment, or we will get a call to va() every frame!
|
||||
GLimp_LogComment(va("--- GL_VertexAttribPointers( %s ) ---\n", glState.currentVBO->name));
|
||||
if(r_logFile->integer)
|
||||
{
|
||||
GLimp_LogComment(va("--- GL_VertexAttribPointers( %s ) ---\n", vbo->name));
|
||||
}
|
||||
|
||||
// position/normal/tangent/bitangent are always set in case of animation
|
||||
// position/normal/tangent are always set in case of animation
|
||||
oldFrame = glState.vertexAttribsOldFrame;
|
||||
newFrame = glState.vertexAttribsNewFrame;
|
||||
animated = (oldFrame != newFrame) && (glState.vertexAttribsInterpolation > 0.0f);
|
||||
animated = glState.vertexAnimation;
|
||||
|
||||
if((attribBits & ATTR_POSITION) && (!(glState.vertexAttribPointersSet & ATTR_POSITION) || animated))
|
||||
{
|
||||
GLimp_LogComment("qglVertexAttribPointerARB( ATTR_INDEX_POSITION )\n");
|
||||
|
||||
qglVertexAttribPointerARB(ATTR_INDEX_POSITION, 3, GL_FLOAT, 0, glState.currentVBO->stride_xyz, BUFFER_OFFSET(glState.currentVBO->ofs_xyz + newFrame * glState.currentVBO->size_xyz));
|
||||
qglVertexAttribPointerARB(ATTR_INDEX_POSITION, 3, GL_FLOAT, 0, vbo->stride_xyz, BUFFER_OFFSET(vbo->ofs_xyz + newFrame * vbo->size_xyz));
|
||||
glState.vertexAttribPointersSet |= ATTR_POSITION;
|
||||
}
|
||||
|
||||
|
@ -1710,7 +1669,7 @@ void GLSL_VertexAttribPointers(uint32_t attribBits)
|
|||
{
|
||||
GLimp_LogComment("qglVertexAttribPointerARB( ATTR_INDEX_TEXCOORD )\n");
|
||||
|
||||
qglVertexAttribPointerARB(ATTR_INDEX_TEXCOORD0, 2, GL_FLOAT, 0, glState.currentVBO->stride_st, BUFFER_OFFSET(glState.currentVBO->ofs_st));
|
||||
qglVertexAttribPointerARB(ATTR_INDEX_TEXCOORD0, 2, GL_FLOAT, 0, vbo->stride_st, BUFFER_OFFSET(vbo->ofs_st));
|
||||
glState.vertexAttribPointersSet |= ATTR_TEXCOORD;
|
||||
}
|
||||
|
||||
|
@ -1718,7 +1677,7 @@ void GLSL_VertexAttribPointers(uint32_t attribBits)
|
|||
{
|
||||
GLimp_LogComment("qglVertexAttribPointerARB( ATTR_INDEX_LIGHTCOORD )\n");
|
||||
|
||||
qglVertexAttribPointerARB(ATTR_INDEX_TEXCOORD1, 2, GL_FLOAT, 0, glState.currentVBO->stride_lightmap, BUFFER_OFFSET(glState.currentVBO->ofs_lightmap));
|
||||
qglVertexAttribPointerARB(ATTR_INDEX_TEXCOORD1, 2, GL_FLOAT, 0, vbo->stride_lightmap, BUFFER_OFFSET(vbo->ofs_lightmap));
|
||||
glState.vertexAttribPointersSet |= ATTR_LIGHTCOORD;
|
||||
}
|
||||
|
||||
|
@ -1726,7 +1685,7 @@ void GLSL_VertexAttribPointers(uint32_t attribBits)
|
|||
{
|
||||
GLimp_LogComment("qglVertexAttribPointerARB( ATTR_INDEX_NORMAL )\n");
|
||||
|
||||
qglVertexAttribPointerARB(ATTR_INDEX_NORMAL, 3, GL_FLOAT, 0, glState.currentVBO->stride_normal, BUFFER_OFFSET(glState.currentVBO->ofs_normal + newFrame * glState.currentVBO->size_normal));
|
||||
qglVertexAttribPointerARB(ATTR_INDEX_NORMAL, 4, glRefConfig.packedNormalDataType, GL_TRUE, vbo->stride_normal, BUFFER_OFFSET(vbo->ofs_normal + newFrame * vbo->size_normal));
|
||||
glState.vertexAttribPointersSet |= ATTR_NORMAL;
|
||||
}
|
||||
|
||||
|
@ -1735,24 +1694,16 @@ void GLSL_VertexAttribPointers(uint32_t attribBits)
|
|||
{
|
||||
GLimp_LogComment("qglVertexAttribPointerARB( ATTR_INDEX_TANGENT )\n");
|
||||
|
||||
qglVertexAttribPointerARB(ATTR_INDEX_TANGENT, 3, GL_FLOAT, 0, glState.currentVBO->stride_tangent, BUFFER_OFFSET(glState.currentVBO->ofs_tangent + newFrame * glState.currentVBO->size_normal)); // FIXME
|
||||
qglVertexAttribPointerARB(ATTR_INDEX_TANGENT, 4, glRefConfig.packedNormalDataType, GL_TRUE, vbo->stride_tangent, BUFFER_OFFSET(vbo->ofs_tangent + newFrame * vbo->size_normal)); // FIXME
|
||||
glState.vertexAttribPointersSet |= ATTR_TANGENT;
|
||||
}
|
||||
|
||||
if((attribBits & ATTR_BITANGENT) && (!(glState.vertexAttribPointersSet & ATTR_BITANGENT) || animated))
|
||||
{
|
||||
GLimp_LogComment("qglVertexAttribPointerARB( ATTR_INDEX_BITANGENT )\n");
|
||||
|
||||
qglVertexAttribPointerARB(ATTR_INDEX_BITANGENT, 3, GL_FLOAT, 0, glState.currentVBO->stride_bitangent, BUFFER_OFFSET(glState.currentVBO->ofs_bitangent + newFrame * glState.currentVBO->size_normal)); // FIXME
|
||||
glState.vertexAttribPointersSet |= ATTR_BITANGENT;
|
||||
}
|
||||
#endif
|
||||
|
||||
if((attribBits & ATTR_COLOR) && !(glState.vertexAttribPointersSet & ATTR_COLOR))
|
||||
{
|
||||
GLimp_LogComment("qglVertexAttribPointerARB( ATTR_INDEX_COLOR )\n");
|
||||
|
||||
qglVertexAttribPointerARB(ATTR_INDEX_COLOR, 4, GL_FLOAT, 0, glState.currentVBO->stride_vertexcolor, BUFFER_OFFSET(glState.currentVBO->ofs_vertexcolor));
|
||||
qglVertexAttribPointerARB(ATTR_INDEX_COLOR, 4, GL_FLOAT, 0, vbo->stride_vertexcolor, BUFFER_OFFSET(vbo->ofs_vertexcolor));
|
||||
glState.vertexAttribPointersSet |= ATTR_COLOR;
|
||||
}
|
||||
|
||||
|
@ -1760,7 +1711,7 @@ void GLSL_VertexAttribPointers(uint32_t attribBits)
|
|||
{
|
||||
GLimp_LogComment("qglVertexAttribPointerARB( ATTR_INDEX_LIGHTDIRECTION )\n");
|
||||
|
||||
qglVertexAttribPointerARB(ATTR_INDEX_LIGHTDIRECTION, 3, GL_FLOAT, 0, glState.currentVBO->stride_lightdir, BUFFER_OFFSET(glState.currentVBO->ofs_lightdir));
|
||||
qglVertexAttribPointerARB(ATTR_INDEX_LIGHTDIRECTION, 4, glRefConfig.packedNormalDataType, GL_TRUE, vbo->stride_lightdir, BUFFER_OFFSET(vbo->ofs_lightdir));
|
||||
glState.vertexAttribPointersSet |= ATTR_LIGHTDIRECTION;
|
||||
}
|
||||
|
||||
|
@ -1768,7 +1719,7 @@ void GLSL_VertexAttribPointers(uint32_t attribBits)
|
|||
{
|
||||
GLimp_LogComment("qglVertexAttribPointerARB( ATTR_INDEX_POSITION2 )\n");
|
||||
|
||||
qglVertexAttribPointerARB(ATTR_INDEX_POSITION2, 3, GL_FLOAT, 0, glState.currentVBO->stride_xyz, BUFFER_OFFSET(glState.currentVBO->ofs_xyz + oldFrame * glState.currentVBO->size_xyz));
|
||||
qglVertexAttribPointerARB(ATTR_INDEX_POSITION2, 3, GL_FLOAT, 0, vbo->stride_xyz, BUFFER_OFFSET(vbo->ofs_xyz + oldFrame * vbo->size_xyz));
|
||||
glState.vertexAttribPointersSet |= ATTR_POSITION2;
|
||||
}
|
||||
|
||||
|
@ -1776,7 +1727,7 @@ void GLSL_VertexAttribPointers(uint32_t attribBits)
|
|||
{
|
||||
GLimp_LogComment("qglVertexAttribPointerARB( ATTR_INDEX_NORMAL2 )\n");
|
||||
|
||||
qglVertexAttribPointerARB(ATTR_INDEX_NORMAL2, 3, GL_FLOAT, 0, glState.currentVBO->stride_normal, BUFFER_OFFSET(glState.currentVBO->ofs_normal + oldFrame * glState.currentVBO->size_normal));
|
||||
qglVertexAttribPointerARB(ATTR_INDEX_NORMAL2, 4, glRefConfig.packedNormalDataType, GL_TRUE, vbo->stride_normal, BUFFER_OFFSET(vbo->ofs_normal + oldFrame * vbo->size_normal));
|
||||
glState.vertexAttribPointersSet |= ATTR_NORMAL2;
|
||||
}
|
||||
|
||||
|
@ -1785,17 +1736,9 @@ void GLSL_VertexAttribPointers(uint32_t attribBits)
|
|||
{
|
||||
GLimp_LogComment("qglVertexAttribPointerARB( ATTR_INDEX_TANGENT2 )\n");
|
||||
|
||||
qglVertexAttribPointerARB(ATTR_INDEX_TANGENT2, 3, GL_FLOAT, 0, glState.currentVBO->stride_tangent, BUFFER_OFFSET(glState.currentVBO->ofs_tangent + oldFrame * glState.currentVBO->size_normal)); // FIXME
|
||||
qglVertexAttribPointerARB(ATTR_INDEX_TANGENT2, 4, glRefConfig.packedNormalDataType, GL_TRUE, vbo->stride_tangent, BUFFER_OFFSET(vbo->ofs_tangent + oldFrame * vbo->size_normal)); // FIXME
|
||||
glState.vertexAttribPointersSet |= ATTR_TANGENT2;
|
||||
}
|
||||
|
||||
if((attribBits & ATTR_BITANGENT2) && (!(glState.vertexAttribPointersSet & ATTR_BITANGENT2) || animated))
|
||||
{
|
||||
GLimp_LogComment("qglVertexAttribPointerARB( ATTR_INDEX_BITANGENT2 )\n");
|
||||
|
||||
qglVertexAttribPointerARB(ATTR_INDEX_BITANGENT2, 3, GL_FLOAT, 0, glState.currentVBO->stride_bitangent, BUFFER_OFFSET(glState.currentVBO->ofs_bitangent + oldFrame * glState.currentVBO->size_normal)); // FIXME
|
||||
glState.vertexAttribPointersSet |= ATTR_BITANGENT2;
|
||||
}
|
||||
#endif
|
||||
|
||||
}
|
||||
|
@ -1829,7 +1772,6 @@ shaderProgram_t *GLSL_GetGenericShaderProgram(int stage)
|
|||
{
|
||||
case AGEN_LIGHTING_SPECULAR:
|
||||
case AGEN_PORTAL:
|
||||
case AGEN_FRESNEL:
|
||||
shaderAttribs |= GENERICDEF_USE_RGBAGEN;
|
||||
break;
|
||||
default:
|
||||
|
@ -1846,7 +1788,7 @@ shaderProgram_t *GLSL_GetGenericShaderProgram(int stage)
|
|||
shaderAttribs |= GENERICDEF_USE_DEFORM_VERTEXES;
|
||||
}
|
||||
|
||||
if (glState.vertexAttribsInterpolation > 0.0f && backEnd.currentEntity && backEnd.currentEntity != &tr.worldEntity)
|
||||
if (glState.vertexAnimation)
|
||||
{
|
||||
shaderAttribs |= GENERICDEF_USE_VERTEX_ANIMATION;
|
||||
}
|
||||
|
|
|
@ -2303,6 +2303,9 @@ image_t *R_CreateImage( const char *name, byte *pic, int width, int height, imgT
|
|||
qglTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Z, 0, GL_RGBA8, width, height, 0, GL_BGRA, GL_UNSIGNED_BYTE, pic);
|
||||
qglTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, 0, GL_RGBA8, width, height, 0, GL_BGRA, GL_UNSIGNED_BYTE, pic);
|
||||
|
||||
if (image->flags & IMGFLAG_MIPMAP)
|
||||
qglGenerateMipmapEXT(GL_TEXTURE_CUBE_MAP);
|
||||
|
||||
image->uploadWidth = width;
|
||||
image->uploadHeight = height;
|
||||
}
|
||||
|
@ -2872,9 +2875,6 @@ void R_CreateBuiltinImages( void ) {
|
|||
Com_Memset( data, 255, sizeof( data ) );
|
||||
tr.whiteImage = R_CreateImage("*white", (byte *)data, 8, 8, IMGTYPE_COLORALPHA, IMGFLAG_NONE, 0);
|
||||
|
||||
Com_Memset( data, 128, sizeof( data ) );
|
||||
tr.greyImage = R_CreateImage("*grey", (byte *)data, 8, 8, IMGTYPE_COLORALPHA, IMGFLAG_NONE, GL_RGBA8);
|
||||
|
||||
if (r_dlightMode->integer >= 2)
|
||||
{
|
||||
for( x = 0; x < MAX_DLIGHTS; x++)
|
||||
|
@ -2922,7 +2922,7 @@ void R_CreateBuiltinImages( void ) {
|
|||
|
||||
hdrFormat = GL_RGBA8;
|
||||
if (r_hdr->integer && glRefConfig.framebufferObject && glRefConfig.textureFloat)
|
||||
hdrFormat = GL_RGB16F_ARB;
|
||||
hdrFormat = GL_RGBA16F_ARB;
|
||||
|
||||
rgbFormat = GL_RGBA8;
|
||||
|
||||
|
@ -2931,9 +2931,6 @@ void R_CreateBuiltinImages( void ) {
|
|||
if (r_drawSunRays->integer)
|
||||
tr.sunRaysImage = R_CreateImage("*sunRays", NULL, width, height, IMGTYPE_COLORALPHA, IMGFLAG_NO_COMPRESSION | IMGFLAG_CLAMPTOEDGE, rgbFormat);
|
||||
|
||||
if (r_softOverbright->integer)
|
||||
tr.screenScratchImage = R_CreateImage("*screenScratch", NULL, width, height, IMGTYPE_COLORALPHA, IMGFLAG_NO_COMPRESSION | IMGFLAG_CLAMPTOEDGE, rgbFormat);
|
||||
|
||||
if (glRefConfig.framebufferObject)
|
||||
{
|
||||
tr.renderDepthImage = R_CreateImage("*renderdepth", NULL, width, height, IMGTYPE_COLORALPHA, IMGFLAG_NO_COMPRESSION | IMGFLAG_CLAMPTOEDGE, GL_DEPTH_COMPONENT24_ARB);
|
||||
|
@ -2944,7 +2941,7 @@ void R_CreateBuiltinImages( void ) {
|
|||
unsigned short sdata[4];
|
||||
void *p;
|
||||
|
||||
if (hdrFormat == GL_RGB16F_ARB)
|
||||
if (hdrFormat == GL_RGBA16F_ARB)
|
||||
{
|
||||
sdata[0] = FloatToHalf(0.0f);
|
||||
sdata[1] = FloatToHalf(0.45f);
|
||||
|
@ -2975,25 +2972,34 @@ void R_CreateBuiltinImages( void ) {
|
|||
tr.quarterImage[x] = R_CreateImage(va("*quarter%d", x), NULL, width / 2, height / 2, IMGTYPE_COLORALPHA, IMGFLAG_NO_COMPRESSION | IMGFLAG_CLAMPTOEDGE, GL_RGBA8);
|
||||
}
|
||||
|
||||
tr.screenShadowImage = R_CreateImage("*screenShadow", NULL, width, height, IMGTYPE_COLORALPHA, IMGFLAG_NO_COMPRESSION | IMGFLAG_CLAMPTOEDGE, GL_RGBA8);
|
||||
|
||||
if (r_ssao->integer)
|
||||
{
|
||||
tr.screenSsaoImage = R_CreateImage("*screenSsao", NULL, width / 2, height / 2, IMGTYPE_COLORALPHA, IMGFLAG_NO_COMPRESSION | IMGFLAG_CLAMPTOEDGE, GL_RGBA8);
|
||||
tr.hdrDepthImage = R_CreateImage("*hdrDepth", NULL, width, height, IMGTYPE_COLORALPHA, IMGFLAG_NO_COMPRESSION | IMGFLAG_CLAMPTOEDGE, GL_INTENSITY32F_ARB);
|
||||
}
|
||||
|
||||
for( x = 0; x < MAX_DRAWN_PSHADOWS; x++)
|
||||
if (r_shadows->integer == 4)
|
||||
{
|
||||
tr.pshadowMaps[x] = R_CreateImage(va("*shadowmap%i", x), NULL, PSHADOW_MAP_SIZE, PSHADOW_MAP_SIZE, IMGTYPE_COLORALPHA, IMGFLAG_NO_COMPRESSION | IMGFLAG_CLAMPTOEDGE, GL_RGBA8);
|
||||
for( x = 0; x < MAX_DRAWN_PSHADOWS; x++)
|
||||
{
|
||||
tr.pshadowMaps[x] = R_CreateImage(va("*shadowmap%i", x), NULL, PSHADOW_MAP_SIZE, PSHADOW_MAP_SIZE, IMGTYPE_COLORALPHA, IMGFLAG_NO_COMPRESSION | IMGFLAG_CLAMPTOEDGE, GL_RGBA8);
|
||||
}
|
||||
}
|
||||
|
||||
for ( x = 0; x < 3; x++)
|
||||
if (r_sunlightMode->integer)
|
||||
{
|
||||
tr.sunShadowDepthImage[x] = R_CreateImage(va("*sunshadowdepth%i", x), NULL, r_shadowMapSize->integer, r_shadowMapSize->integer, IMGTYPE_COLORALPHA, IMGFLAG_NO_COMPRESSION | IMGFLAG_CLAMPTOEDGE, GL_DEPTH_COMPONENT24_ARB);
|
||||
for ( x = 0; x < 3; x++)
|
||||
{
|
||||
tr.sunShadowDepthImage[x] = R_CreateImage(va("*sunshadowdepth%i", x), NULL, r_shadowMapSize->integer, r_shadowMapSize->integer, IMGTYPE_COLORALPHA, IMGFLAG_NO_COMPRESSION | IMGFLAG_CLAMPTOEDGE, GL_DEPTH_COMPONENT24_ARB);
|
||||
}
|
||||
|
||||
tr.screenShadowImage = R_CreateImage("*screenShadow", NULL, width, height, IMGTYPE_COLORALPHA, IMGFLAG_NO_COMPRESSION | IMGFLAG_CLAMPTOEDGE, GL_RGBA8);
|
||||
}
|
||||
|
||||
tr.renderCubeImage = R_CreateImage("*renderCube", NULL, CUBE_MAP_SIZE, CUBE_MAP_SIZE, IMGTYPE_COLORALPHA, IMGFLAG_NO_COMPRESSION | IMGFLAG_CLAMPTOEDGE | IMGFLAG_MIPMAP | IMGFLAG_CUBEMAP, rgbFormat);
|
||||
if (r_cubeMapping->integer)
|
||||
{
|
||||
tr.renderCubeImage = R_CreateImage("*renderCube", NULL, CUBE_MAP_SIZE, CUBE_MAP_SIZE, IMGTYPE_COLORALPHA, IMGFLAG_NO_COMPRESSION | IMGFLAG_CLAMPTOEDGE | IMGFLAG_MIPMAP | IMGFLAG_CUBEMAP, rgbFormat);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -100,6 +100,8 @@ cvar_t *r_ext_framebuffer_object;
|
|||
cvar_t *r_ext_texture_float;
|
||||
cvar_t *r_arb_half_float_pixel;
|
||||
cvar_t *r_ext_framebuffer_multisample;
|
||||
cvar_t *r_arb_seamless_cube_map;
|
||||
cvar_t *r_arb_vertex_type_2_10_10_10_rev;
|
||||
|
||||
cvar_t *r_mergeMultidraws;
|
||||
cvar_t *r_mergeLeafSurfaces;
|
||||
|
@ -109,6 +111,7 @@ cvar_t *r_cameraExposure;
|
|||
cvar_t *r_softOverbright;
|
||||
|
||||
cvar_t *r_hdr;
|
||||
cvar_t *r_floatLightmap;
|
||||
cvar_t *r_postProcess;
|
||||
|
||||
cvar_t *r_toneMap;
|
||||
|
@ -156,6 +159,7 @@ cvar_t *r_shadowMapSize;
|
|||
cvar_t *r_shadowCascadeZNear;
|
||||
cvar_t *r_shadowCascadeZFar;
|
||||
cvar_t *r_shadowCascadeZBias;
|
||||
cvar_t *r_ignoreDstAlpha;
|
||||
|
||||
cvar_t *r_ignoreGLErrors;
|
||||
cvar_t *r_logFile;
|
||||
|
@ -950,16 +954,6 @@ void GL_SetDefaultState( void )
|
|||
qglDisable( GL_CULL_FACE );
|
||||
qglDisable( GL_BLEND );
|
||||
|
||||
qglColorMask( GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE );
|
||||
qglClearColor( 0.0f, 0.0f, 0.0f, 1.0f );
|
||||
qglClearDepth( 1.0 );
|
||||
|
||||
qglDrawBuffer( GL_FRONT );
|
||||
qglClear( GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_ACCUM_BUFFER_BIT|GL_STENCIL_BUFFER_BIT );
|
||||
|
||||
qglDrawBuffer( GL_BACK );
|
||||
qglClear( GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_ACCUM_BUFFER_BIT|GL_STENCIL_BUFFER_BIT );
|
||||
|
||||
if (glRefConfig.seamlessCubeMap)
|
||||
qglEnable(GL_TEXTURE_CUBE_MAP_SEAMLESS);
|
||||
}
|
||||
|
@ -1133,6 +1127,8 @@ void R_Register( void )
|
|||
r_ext_texture_float = ri.Cvar_Get( "r_ext_texture_float", "1", CVAR_ARCHIVE | CVAR_LATCH);
|
||||
r_arb_half_float_pixel = ri.Cvar_Get( "r_arb_half_float_pixel", "1", CVAR_ARCHIVE | CVAR_LATCH);
|
||||
r_ext_framebuffer_multisample = ri.Cvar_Get( "r_ext_framebuffer_multisample", "0", CVAR_ARCHIVE | CVAR_LATCH);
|
||||
r_arb_seamless_cube_map = ri.Cvar_Get( "r_arb_seamless_cube_map", "0", CVAR_ARCHIVE | CVAR_LATCH);
|
||||
r_arb_vertex_type_2_10_10_10_rev = ri.Cvar_Get( "r_arb_vertex_type_2_10_10_10_rev", "1", CVAR_ARCHIVE | CVAR_LATCH);
|
||||
|
||||
r_ext_texture_filter_anisotropic = ri.Cvar_Get( "r_ext_texture_filter_anisotropic",
|
||||
"0", CVAR_ARCHIVE | CVAR_LATCH );
|
||||
|
@ -1153,7 +1149,7 @@ void R_Register( void )
|
|||
r_ignorehwgamma = ri.Cvar_Get( "r_ignorehwgamma", "0", CVAR_ARCHIVE | CVAR_LATCH);
|
||||
r_mode = ri.Cvar_Get( "r_mode", "-2", CVAR_ARCHIVE | CVAR_LATCH );
|
||||
r_fullscreen = ri.Cvar_Get( "r_fullscreen", "1", CVAR_ARCHIVE );
|
||||
r_noborder = ri.Cvar_Get("r_noborder", "0", CVAR_ARCHIVE);
|
||||
r_noborder = ri.Cvar_Get("r_noborder", "0", CVAR_ARCHIVE | CVAR_LATCH);
|
||||
r_customwidth = ri.Cvar_Get( "r_customwidth", "1600", CVAR_ARCHIVE | CVAR_LATCH );
|
||||
r_customheight = ri.Cvar_Get( "r_customheight", "1024", CVAR_ARCHIVE | CVAR_LATCH );
|
||||
r_customPixelAspect = ri.Cvar_Get( "r_customPixelAspect", "1", CVAR_ARCHIVE | CVAR_LATCH );
|
||||
|
@ -1168,6 +1164,7 @@ void R_Register( void )
|
|||
r_softOverbright = ri.Cvar_Get( "r_softOverbright", "1", CVAR_ARCHIVE | CVAR_LATCH );
|
||||
|
||||
r_hdr = ri.Cvar_Get( "r_hdr", "1", CVAR_ARCHIVE | CVAR_LATCH );
|
||||
r_floatLightmap = ri.Cvar_Get( "r_floatLightmap", "0", CVAR_ARCHIVE | CVAR_LATCH );
|
||||
r_postProcess = ri.Cvar_Get( "r_postProcess", "1", CVAR_ARCHIVE );
|
||||
|
||||
r_toneMap = ri.Cvar_Get( "r_toneMap", "1", CVAR_ARCHIVE | CVAR_LATCH );
|
||||
|
@ -1219,6 +1216,7 @@ void R_Register( void )
|
|||
r_shadowCascadeZNear = ri.Cvar_Get( "r_shadowCascadeZNear", "4", CVAR_ARCHIVE | CVAR_LATCH );
|
||||
r_shadowCascadeZFar = ri.Cvar_Get( "r_shadowCascadeZFar", "3072", CVAR_ARCHIVE | CVAR_LATCH );
|
||||
r_shadowCascadeZBias = ri.Cvar_Get( "r_shadowCascadeZBias", "-320", CVAR_ARCHIVE | CVAR_LATCH );
|
||||
r_ignoreDstAlpha = ri.Cvar_Get( "r_ignoreDstAlpha", "1", CVAR_ARCHIVE | CVAR_LATCH );
|
||||
|
||||
//
|
||||
// temporary latched variables that can only change over a restart
|
||||
|
|
|
@ -94,12 +94,17 @@ void R_DlightBmodel( bmodel_t *bmodel ) {
|
|||
for ( i = 0 ; i < bmodel->numSurfaces ; i++ ) {
|
||||
surf = tr.world->surfaces + bmodel->firstSurface + i;
|
||||
|
||||
if ( *surf->data == SF_FACE ) {
|
||||
((srfSurfaceFace_t *)surf->data)->dlightBits = mask;
|
||||
} else if ( *surf->data == SF_GRID ) {
|
||||
((srfGridMesh_t *)surf->data)->dlightBits = mask;
|
||||
} else if ( *surf->data == SF_TRIANGLES ) {
|
||||
((srfTriangles_t *)surf->data)->dlightBits = mask;
|
||||
switch(*surf->data)
|
||||
{
|
||||
case SF_FACE:
|
||||
case SF_GRID:
|
||||
case SF_TRIANGLES:
|
||||
case SF_VBO_MESH:
|
||||
((srfBspSurface_t *)surf->data)->dlightBits = mask;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -403,8 +408,11 @@ void R_SetupEntityLighting( const trRefdef_t *refdef, trRefEntity_t *ent ) {
|
|||
((byte *)&ent->ambientLightInt)[3] = 0xff;
|
||||
|
||||
// transform the direction to local space
|
||||
// no need to do this if using lightentity glsl shader
|
||||
VectorNormalize( lightDir );
|
||||
ent->modelLightDir[0] = DotProduct( lightDir, ent->e.axis[0] );
|
||||
ent->modelLightDir[1] = DotProduct( lightDir, ent->e.axis[1] );
|
||||
ent->modelLightDir[2] = DotProduct( lightDir, ent->e.axis[2] );
|
||||
|
||||
VectorCopy(lightDir, ent->lightDir);
|
||||
}
|
||||
|
||||
|
|
|
@ -47,10 +47,6 @@ typedef unsigned int glIndex_t;
|
|||
#define SHADERNUM_BITS 14
|
||||
#define MAX_SHADERS (1<<SHADERNUM_BITS)
|
||||
|
||||
//#define MAX_SHADER_STATES 2048
|
||||
#define MAX_STATES_PER_SHADER 32
|
||||
#define MAX_STATE_NAME 32
|
||||
|
||||
#define MAX_FBOS 64
|
||||
#define MAX_VISCOUNTS 5
|
||||
#define MAX_VBOS 4096
|
||||
|
@ -84,7 +80,8 @@ typedef struct {
|
|||
qboolean needDlights; // true for bmodels that touch a dlight
|
||||
qboolean lightingCalculated;
|
||||
qboolean mirrored; // mirrored matrix, needs reversed culling
|
||||
vec3_t lightDir; // normalized direction towards light
|
||||
vec3_t lightDir; // normalized direction towards light, in world space
|
||||
vec3_t modelLightDir; // normalized direction towards light, in model space
|
||||
vec3_t ambientLight; // color normalized to 0-255
|
||||
int ambientLightInt; // 32 bit rgba packed
|
||||
vec3_t directedLight;
|
||||
|
@ -119,7 +116,6 @@ typedef struct VBO_s
|
|||
uint32_t ofs_lightdir;
|
||||
#ifdef USE_VERT_TANGENT_SPACE
|
||||
uint32_t ofs_tangent;
|
||||
uint32_t ofs_bitangent;
|
||||
#endif
|
||||
uint32_t stride_xyz;
|
||||
uint32_t stride_normal;
|
||||
|
@ -129,7 +125,6 @@ typedef struct VBO_s
|
|||
uint32_t stride_lightdir;
|
||||
#ifdef USE_VERT_TANGENT_SPACE
|
||||
uint32_t stride_tangent;
|
||||
uint32_t stride_bitangent;
|
||||
#endif
|
||||
uint32_t size_xyz;
|
||||
uint32_t size_normal;
|
||||
|
@ -241,7 +236,6 @@ typedef enum {
|
|||
AGEN_WAVEFORM,
|
||||
AGEN_PORTAL,
|
||||
AGEN_CONST,
|
||||
AGEN_FRESNEL
|
||||
} alphaGen_t;
|
||||
|
||||
typedef enum {
|
||||
|
@ -354,7 +348,6 @@ typedef struct {
|
|||
|
||||
int videoMapHandle;
|
||||
qboolean isLightmap;
|
||||
qboolean vertexLightmap;
|
||||
qboolean isVideoMap;
|
||||
} textureBundle_t;
|
||||
|
||||
|
@ -486,16 +479,8 @@ typedef struct shader_s {
|
|||
float clampTime; // time this shader is clamped to
|
||||
float timeOffset; // current time offset for this shader
|
||||
|
||||
int numStates; // if non-zero this is a state shader
|
||||
struct shader_s *currentShader; // current state if this is a state shader
|
||||
struct shader_s *parentShader; // current state if this is a state shader
|
||||
int currentState; // current state index for cycle purposes
|
||||
long expireTime; // time in milliseconds this expires
|
||||
|
||||
struct shader_s *remappedShader; // current shader this one is remapped too
|
||||
|
||||
int shaderStates[MAX_STATES_PER_SHADER]; // index to valid shader states
|
||||
|
||||
struct shader_s *next;
|
||||
} shader_t;
|
||||
|
||||
|
@ -522,110 +507,23 @@ static ID_INLINE qboolean ShaderRequiresCPUDeforms(const shader_t * shader)
|
|||
return qfalse;
|
||||
}
|
||||
|
||||
typedef struct shaderState_s {
|
||||
char shaderName[MAX_QPATH]; // name of shader this state belongs to
|
||||
char name[MAX_STATE_NAME]; // name of this state
|
||||
char stateShader[MAX_QPATH]; // shader this name invokes
|
||||
int cycleTime; // time this cycle lasts, <= 0 is forever
|
||||
shader_t *shader;
|
||||
} shaderState_t;
|
||||
|
||||
enum
|
||||
{
|
||||
ATTR_INDEX_POSITION = 0,
|
||||
ATTR_INDEX_TEXCOORD0 = 1,
|
||||
ATTR_INDEX_TEXCOORD1 = 2,
|
||||
ATTR_INDEX_TANGENT = 3,
|
||||
ATTR_INDEX_BITANGENT = 4,
|
||||
ATTR_INDEX_NORMAL = 5,
|
||||
ATTR_INDEX_COLOR = 6,
|
||||
ATTR_INDEX_PAINTCOLOR = 7,
|
||||
ATTR_INDEX_LIGHTDIRECTION = 8,
|
||||
ATTR_INDEX_BONE_INDEXES = 9,
|
||||
ATTR_INDEX_BONE_WEIGHTS = 10,
|
||||
ATTR_INDEX_NORMAL = 4,
|
||||
ATTR_INDEX_COLOR = 5,
|
||||
ATTR_INDEX_PAINTCOLOR = 6,
|
||||
ATTR_INDEX_LIGHTDIRECTION = 7,
|
||||
ATTR_INDEX_BONE_INDEXES = 8,
|
||||
ATTR_INDEX_BONE_WEIGHTS = 9,
|
||||
|
||||
// GPU vertex animations
|
||||
ATTR_INDEX_POSITION2 = 11,
|
||||
ATTR_INDEX_TANGENT2 = 12,
|
||||
ATTR_INDEX_BITANGENT2 = 13,
|
||||
ATTR_INDEX_NORMAL2 = 14
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
GLS_SRCBLEND_ZERO = (1 << 0),
|
||||
GLS_SRCBLEND_ONE = (1 << 1),
|
||||
GLS_SRCBLEND_DST_COLOR = (1 << 2),
|
||||
GLS_SRCBLEND_ONE_MINUS_DST_COLOR = (1 << 3),
|
||||
GLS_SRCBLEND_SRC_ALPHA = (1 << 4),
|
||||
GLS_SRCBLEND_ONE_MINUS_SRC_ALPHA = (1 << 5),
|
||||
GLS_SRCBLEND_DST_ALPHA = (1 << 6),
|
||||
GLS_SRCBLEND_ONE_MINUS_DST_ALPHA = (1 << 7),
|
||||
GLS_SRCBLEND_ALPHA_SATURATE = (1 << 8),
|
||||
|
||||
GLS_SRCBLEND_BITS = GLS_SRCBLEND_ZERO
|
||||
| GLS_SRCBLEND_ONE
|
||||
| GLS_SRCBLEND_DST_COLOR
|
||||
| GLS_SRCBLEND_ONE_MINUS_DST_COLOR
|
||||
| GLS_SRCBLEND_SRC_ALPHA
|
||||
| GLS_SRCBLEND_ONE_MINUS_SRC_ALPHA
|
||||
| GLS_SRCBLEND_DST_ALPHA
|
||||
| GLS_SRCBLEND_ONE_MINUS_DST_ALPHA
|
||||
| GLS_SRCBLEND_ALPHA_SATURATE,
|
||||
|
||||
GLS_DSTBLEND_ZERO = (1 << 9),
|
||||
GLS_DSTBLEND_ONE = (1 << 10),
|
||||
GLS_DSTBLEND_SRC_COLOR = (1 << 11),
|
||||
GLS_DSTBLEND_ONE_MINUS_SRC_COLOR = (1 << 12),
|
||||
GLS_DSTBLEND_SRC_ALPHA = (1 << 13),
|
||||
GLS_DSTBLEND_ONE_MINUS_SRC_ALPHA = (1 << 14),
|
||||
GLS_DSTBLEND_DST_ALPHA = (1 << 15),
|
||||
GLS_DSTBLEND_ONE_MINUS_DST_ALPHA = (1 << 16),
|
||||
|
||||
GLS_DSTBLEND_BITS = GLS_DSTBLEND_ZERO
|
||||
| GLS_DSTBLEND_ONE
|
||||
| GLS_DSTBLEND_SRC_COLOR
|
||||
| GLS_DSTBLEND_ONE_MINUS_SRC_COLOR
|
||||
| GLS_DSTBLEND_SRC_ALPHA
|
||||
| GLS_DSTBLEND_ONE_MINUS_SRC_ALPHA
|
||||
| GLS_DSTBLEND_DST_ALPHA
|
||||
| GLS_DSTBLEND_ONE_MINUS_DST_ALPHA,
|
||||
|
||||
GLS_DEPTHMASK_TRUE = (1 << 17),
|
||||
|
||||
GLS_POLYMODE_LINE = (1 << 18),
|
||||
|
||||
GLS_DEPTHTEST_DISABLE = (1 << 19),
|
||||
|
||||
GLS_DEPTHFUNC_LESS = (1 << 20),
|
||||
GLS_DEPTHFUNC_EQUAL = (1 << 21),
|
||||
|
||||
GLS_DEPTHFUNC_BITS = GLS_DEPTHFUNC_LESS
|
||||
| GLS_DEPTHFUNC_EQUAL,
|
||||
|
||||
GLS_ATEST_GT_0 = (1 << 22),
|
||||
GLS_ATEST_LT_128 = (1 << 23),
|
||||
GLS_ATEST_GE_128 = (1 << 24),
|
||||
// GLS_ATEST_GE_CUSTOM = (1 << 25),
|
||||
|
||||
GLS_ATEST_BITS = GLS_ATEST_GT_0
|
||||
| GLS_ATEST_LT_128
|
||||
| GLS_ATEST_GE_128,
|
||||
// | GLS_ATEST_GT_CUSTOM,
|
||||
|
||||
GLS_REDMASK_FALSE = (1 << 26),
|
||||
GLS_GREENMASK_FALSE = (1 << 27),
|
||||
GLS_BLUEMASK_FALSE = (1 << 28),
|
||||
GLS_ALPHAMASK_FALSE = (1 << 29),
|
||||
|
||||
GLS_COLORMASK_BITS = GLS_REDMASK_FALSE
|
||||
| GLS_GREENMASK_FALSE
|
||||
| GLS_BLUEMASK_FALSE
|
||||
| GLS_ALPHAMASK_FALSE,
|
||||
|
||||
GLS_STENCILTEST_ENABLE = (1 << 30),
|
||||
|
||||
GLS_DEFAULT = GLS_DEPTHMASK_TRUE
|
||||
ATTR_INDEX_POSITION2 = 10,
|
||||
ATTR_INDEX_TANGENT2 = 11,
|
||||
ATTR_INDEX_NORMAL2 = 12
|
||||
};
|
||||
|
||||
enum
|
||||
|
@ -634,26 +532,23 @@ enum
|
|||
ATTR_TEXCOORD = 0x0002,
|
||||
ATTR_LIGHTCOORD = 0x0004,
|
||||
ATTR_TANGENT = 0x0008,
|
||||
ATTR_BITANGENT = 0x0010,
|
||||
ATTR_NORMAL = 0x0020,
|
||||
ATTR_COLOR = 0x0040,
|
||||
ATTR_PAINTCOLOR = 0x0080,
|
||||
ATTR_LIGHTDIRECTION = 0x0100,
|
||||
ATTR_BONE_INDEXES = 0x0200,
|
||||
ATTR_BONE_WEIGHTS = 0x0400,
|
||||
ATTR_NORMAL = 0x0010,
|
||||
ATTR_COLOR = 0x0020,
|
||||
ATTR_PAINTCOLOR = 0x0040,
|
||||
ATTR_LIGHTDIRECTION = 0x0080,
|
||||
ATTR_BONE_INDEXES = 0x0100,
|
||||
ATTR_BONE_WEIGHTS = 0x0200,
|
||||
|
||||
// for .md3 interpolation
|
||||
ATTR_POSITION2 = 0x0800,
|
||||
ATTR_TANGENT2 = 0x1000,
|
||||
ATTR_BITANGENT2 = 0x2000,
|
||||
ATTR_NORMAL2 = 0x4000,
|
||||
ATTR_POSITION2 = 0x0400,
|
||||
ATTR_TANGENT2 = 0x0800,
|
||||
ATTR_NORMAL2 = 0x1000,
|
||||
|
||||
ATTR_DEFAULT = ATTR_POSITION,
|
||||
ATTR_BITS = ATTR_POSITION |
|
||||
ATTR_TEXCOORD |
|
||||
ATTR_LIGHTCOORD |
|
||||
ATTR_TANGENT |
|
||||
ATTR_BITANGENT |
|
||||
ATTR_NORMAL |
|
||||
ATTR_COLOR |
|
||||
ATTR_PAINTCOLOR |
|
||||
|
@ -662,7 +557,6 @@ enum
|
|||
ATTR_BONE_WEIGHTS |
|
||||
ATTR_POSITION2 |
|
||||
ATTR_TANGENT2 |
|
||||
ATTR_BITANGENT2 |
|
||||
ATTR_NORMAL2
|
||||
};
|
||||
|
||||
|
@ -701,12 +595,10 @@ enum
|
|||
LIGHTDEF_LIGHTTYPE_MASK = 0x0003,
|
||||
LIGHTDEF_ENTITY = 0x0004,
|
||||
LIGHTDEF_USE_TCGEN_AND_TCMOD = 0x0008,
|
||||
LIGHTDEF_USE_DELUXEMAP = 0x0010,
|
||||
LIGHTDEF_USE_PARALLAXMAP = 0x0020,
|
||||
LIGHTDEF_USE_SHADOWMAP = 0x0040,
|
||||
LIGHTDEF_USE_CUBEMAP = 0x0080,
|
||||
LIGHTDEF_ALL = 0x00FF,
|
||||
LIGHTDEF_COUNT = 0x0100
|
||||
LIGHTDEF_USE_PARALLAXMAP = 0x0010,
|
||||
LIGHTDEF_USE_SHADOWMAP = 0x0020,
|
||||
LIGHTDEF_ALL = 0x003F,
|
||||
LIGHTDEF_COUNT = 0x0040
|
||||
};
|
||||
|
||||
enum
|
||||
|
@ -743,6 +635,8 @@ typedef enum
|
|||
UNIFORM_SHADOWMVP2,
|
||||
UNIFORM_SHADOWMVP3,
|
||||
|
||||
UNIFORM_ENABLETEXTURES,
|
||||
|
||||
UNIFORM_DIFFUSETEXMATRIX,
|
||||
UNIFORM_DIFFUSETEXOFFTURB,
|
||||
UNIFORM_TEXTURE1ENV,
|
||||
|
@ -765,6 +659,7 @@ typedef enum
|
|||
UNIFORM_LIGHTUP,
|
||||
UNIFORM_LIGHTRIGHT,
|
||||
UNIFORM_LIGHTORIGIN,
|
||||
UNIFORM_MODELLIGHTDIR,
|
||||
UNIFORM_LIGHTRADIUS,
|
||||
UNIFORM_AMBIENTLIGHT,
|
||||
UNIFORM_DIRECTEDLIGHT,
|
||||
|
@ -785,6 +680,7 @@ typedef enum
|
|||
|
||||
UNIFORM_VIEWINFO, // znear, zfar, width/2, height/2
|
||||
UNIFORM_VIEWORIGIN,
|
||||
UNIFORM_LOCALVIEWORIGIN,
|
||||
UNIFORM_VIEWFORWARD,
|
||||
UNIFORM_VIEWLEFT,
|
||||
UNIFORM_VIEWUP,
|
||||
|
@ -951,7 +847,6 @@ typedef enum {
|
|||
SF_TRIANGLES,
|
||||
SF_POLY,
|
||||
SF_MDV,
|
||||
SF_MD4,
|
||||
SF_MDR,
|
||||
SF_IQM,
|
||||
SF_FLARE,
|
||||
|
@ -1005,8 +900,7 @@ typedef struct
|
|||
vec2_t lightmap;
|
||||
vec3_t normal;
|
||||
#ifdef USE_VERT_TANGENT_SPACE
|
||||
vec3_t tangent;
|
||||
vec3_t bitangent;
|
||||
vec4_t tangent;
|
||||
#endif
|
||||
vec3_t lightdir;
|
||||
vec4_t vertexColors;
|
||||
|
@ -1017,22 +911,13 @@ typedef struct
|
|||
} srfVert_t;
|
||||
|
||||
#ifdef USE_VERT_TANGENT_SPACE
|
||||
#define srfVert_t_cleared(x) srfVert_t (x) = {{0, 0, 0}, {0, 0}, {0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0, 0}}
|
||||
#define srfVert_t_cleared(x) srfVert_t (x) = {{0, 0, 0}, {0, 0}, {0, 0}, {0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0}, {0, 0, 0, 0}}
|
||||
#else
|
||||
#define srfVert_t_cleared(x) srfVert_t (x) = {{0, 0, 0}, {0, 0}, {0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0, 0}}
|
||||
#endif
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int indexes[3];
|
||||
int neighbors[3];
|
||||
vec4_t plane;
|
||||
qboolean facingLight;
|
||||
qboolean degenerated;
|
||||
} srfTriangle_t;
|
||||
|
||||
|
||||
typedef struct srfGridMesh_s
|
||||
// srfBspSurface_t covers SF_GRID, SF_TRIANGLES, SF_POLY, and SF_VBO_MESH
|
||||
typedef struct srfBspSurface_s
|
||||
{
|
||||
surfaceType_t surfaceType;
|
||||
|
||||
|
@ -1041,9 +926,30 @@ typedef struct srfGridMesh_s
|
|||
int pshadowBits;
|
||||
|
||||
// culling information
|
||||
vec3_t meshBounds[2];
|
||||
vec3_t localOrigin;
|
||||
float meshRadius;
|
||||
vec3_t cullBounds[2];
|
||||
vec3_t cullOrigin;
|
||||
float cullRadius;
|
||||
cplane_t cullPlane;
|
||||
|
||||
// indexes
|
||||
int numIndexes;
|
||||
glIndex_t *indexes;
|
||||
|
||||
// vertexes
|
||||
int numVerts;
|
||||
srfVert_t *verts;
|
||||
|
||||
// BSP VBO offsets
|
||||
int firstVert;
|
||||
int firstIndex;
|
||||
glIndex_t minIndex;
|
||||
glIndex_t maxIndex;
|
||||
|
||||
// static render data
|
||||
VBO_t *vbo;
|
||||
IBO_t *ibo;
|
||||
|
||||
// SF_GRID specific variables after here
|
||||
|
||||
// lod information, which may be different
|
||||
// than the culling information to allow for
|
||||
|
@ -1057,85 +963,7 @@ typedef struct srfGridMesh_s
|
|||
int width, height;
|
||||
float *widthLodError;
|
||||
float *heightLodError;
|
||||
|
||||
int numTriangles;
|
||||
srfTriangle_t *triangles;
|
||||
|
||||
int numVerts;
|
||||
srfVert_t *verts;
|
||||
|
||||
// BSP VBO offsets
|
||||
int firstVert;
|
||||
int firstIndex;
|
||||
glIndex_t minIndex;
|
||||
glIndex_t maxIndex;
|
||||
|
||||
// static render data
|
||||
VBO_t *vbo; // points to bsp model VBO
|
||||
IBO_t *ibo;
|
||||
} srfGridMesh_t;
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
surfaceType_t surfaceType;
|
||||
|
||||
// dynamic lighting information
|
||||
int dlightBits;
|
||||
int pshadowBits;
|
||||
|
||||
// culling information
|
||||
cplane_t plane;
|
||||
// vec3_t bounds[2];
|
||||
|
||||
// triangle definitions
|
||||
int numTriangles;
|
||||
srfTriangle_t *triangles;
|
||||
|
||||
int numVerts;
|
||||
srfVert_t *verts;
|
||||
|
||||
// BSP VBO offsets
|
||||
int firstVert;
|
||||
int firstIndex;
|
||||
glIndex_t minIndex;
|
||||
glIndex_t maxIndex;
|
||||
|
||||
// static render data
|
||||
VBO_t *vbo; // points to bsp model VBO
|
||||
IBO_t *ibo;
|
||||
} srfSurfaceFace_t;
|
||||
|
||||
|
||||
// misc_models in maps are turned into direct geometry by xmap
|
||||
typedef struct
|
||||
{
|
||||
surfaceType_t surfaceType;
|
||||
|
||||
// dynamic lighting information
|
||||
int dlightBits;
|
||||
int pshadowBits;
|
||||
|
||||
// culling information
|
||||
// vec3_t bounds[2];
|
||||
|
||||
// triangle definitions
|
||||
int numTriangles;
|
||||
srfTriangle_t *triangles;
|
||||
|
||||
int numVerts;
|
||||
srfVert_t *verts;
|
||||
|
||||
// BSP VBO offsets
|
||||
int firstVert;
|
||||
int firstIndex;
|
||||
glIndex_t minIndex;
|
||||
glIndex_t maxIndex;
|
||||
|
||||
// static render data
|
||||
VBO_t *vbo; // points to bsp model VBO
|
||||
IBO_t *ibo;
|
||||
} srfTriangles_t;
|
||||
} srfBspSurface_t;
|
||||
|
||||
// inter-quake-model
|
||||
typedef struct {
|
||||
|
@ -1144,6 +972,7 @@ typedef struct {
|
|||
int num_frames;
|
||||
int num_surfaces;
|
||||
int num_joints;
|
||||
int num_poses;
|
||||
struct srfIQModel_s *surfaces;
|
||||
|
||||
float *positions;
|
||||
|
@ -1151,10 +980,18 @@ typedef struct {
|
|||
float *normals;
|
||||
float *tangents;
|
||||
byte *blendIndexes;
|
||||
byte *blendWeights;
|
||||
union {
|
||||
float *f;
|
||||
byte *b;
|
||||
} blendWeights;
|
||||
byte *colors;
|
||||
int *triangles;
|
||||
|
||||
// depending upon the exporter, blend indices and weights might be int/float
|
||||
// as opposed to the recommended byte/byte, for example Noesis exports
|
||||
// int/float whereas the official IQM tool exports byte/byte
|
||||
byte blendWeightsType; // IQM_UBYTE or IQM_FLOAT
|
||||
|
||||
int *jointParents;
|
||||
float *jointMats;
|
||||
float *poseMats;
|
||||
|
@ -1172,33 +1009,6 @@ typedef struct srfIQModel_s {
|
|||
int first_triangle, num_triangles;
|
||||
} srfIQModel_t;
|
||||
|
||||
typedef struct srfVBOMesh_s
|
||||
{
|
||||
surfaceType_t surfaceType;
|
||||
|
||||
struct shader_s *shader; // FIXME move this to somewhere else
|
||||
int fogIndex;
|
||||
int cubemapIndex;
|
||||
|
||||
// dynamic lighting information
|
||||
int dlightBits;
|
||||
int pshadowBits;
|
||||
|
||||
// culling information
|
||||
vec3_t bounds[2];
|
||||
|
||||
// backEnd stats
|
||||
int numIndexes;
|
||||
int numVerts;
|
||||
int firstIndex;
|
||||
glIndex_t minIndex;
|
||||
glIndex_t maxIndex;
|
||||
|
||||
// static render data
|
||||
VBO_t *vbo;
|
||||
IBO_t *ibo;
|
||||
} srfVBOMesh_t;
|
||||
|
||||
typedef struct srfVBOMDVMesh_s
|
||||
{
|
||||
surfaceType_t surfaceType;
|
||||
|
@ -1332,9 +1142,6 @@ typedef struct {
|
|||
int numDecisionNodes;
|
||||
mnode_t *nodes;
|
||||
|
||||
VBO_t *vbo;
|
||||
IBO_t *ibo;
|
||||
|
||||
int numWorldSurfaces;
|
||||
|
||||
int numsurfaces;
|
||||
|
@ -1426,8 +1233,8 @@ typedef struct mdvSurface_s
|
|||
mdvVertex_t *verts;
|
||||
mdvSt_t *st;
|
||||
|
||||
int numTriangles;
|
||||
srfTriangle_t *triangles;
|
||||
int numIndexes;
|
||||
glIndex_t *indexes;
|
||||
|
||||
struct mdvModel_s *model;
|
||||
} mdvSurface_t;
|
||||
|
@ -1457,7 +1264,6 @@ typedef enum {
|
|||
MOD_BAD,
|
||||
MOD_BRUSH,
|
||||
MOD_MESH,
|
||||
MOD_MD4,
|
||||
MOD_MDR,
|
||||
MOD_IQM
|
||||
} modtype_t;
|
||||
|
@ -1470,7 +1276,7 @@ typedef struct model_s {
|
|||
int dataSize; // just for listing purposes
|
||||
bmodel_t *bmodel; // only if type == MOD_BRUSH
|
||||
mdvModel_t *mdv[MD3_MAX_LODS]; // only if type == MOD_MESH
|
||||
void *modelData; // only if type == (MOD_MD4 | MOD_MDR | MOD_IQM)
|
||||
void *modelData; // only if type == (MOD_MDR | MOD_IQM)
|
||||
|
||||
int numLods;
|
||||
} model_t;
|
||||
|
@ -1564,13 +1370,14 @@ typedef struct {
|
|||
uint32_t vertexAttribsNewFrame;
|
||||
uint32_t vertexAttribsOldFrame;
|
||||
float vertexAttribsInterpolation;
|
||||
qboolean vertexAnimation;
|
||||
shaderProgram_t *currentProgram;
|
||||
FBO_t *currentFBO;
|
||||
VBO_t *currentVBO;
|
||||
IBO_t *currentIBO;
|
||||
matrix_t modelview;
|
||||
matrix_t projection;
|
||||
matrix_t modelviewProjection;
|
||||
mat4_t modelview;
|
||||
mat4_t projection;
|
||||
mat4_t modelviewProjection;
|
||||
} glstate_t;
|
||||
|
||||
typedef enum {
|
||||
|
@ -1616,6 +1423,8 @@ typedef struct {
|
|||
|
||||
qboolean depthClamp;
|
||||
qboolean seamlessCubeMap;
|
||||
|
||||
GLenum packedNormalDataType;
|
||||
} glRefConfig_t;
|
||||
|
||||
|
||||
|
@ -1708,7 +1517,6 @@ typedef struct {
|
|||
image_t *fogImage;
|
||||
image_t *dlightImage; // inverse-quare highlight for projective adding
|
||||
image_t *flareImage;
|
||||
image_t *greyImage; // full of 0x80
|
||||
image_t *whiteImage; // full of 0xff
|
||||
image_t *identityLightImage; // full of tr.identityLightByte
|
||||
|
||||
|
@ -1720,7 +1528,6 @@ typedef struct {
|
|||
image_t *renderDepthImage;
|
||||
image_t *pshadowMaps[MAX_DRAWN_PSHADOWS];
|
||||
image_t *textureScratchImage[2];
|
||||
image_t *screenScratchImage;
|
||||
image_t *quarterImage[2];
|
||||
image_t *calcLevelsImage;
|
||||
image_t *targetLevelsImage;
|
||||
|
@ -1739,7 +1546,6 @@ typedef struct {
|
|||
FBO_t *depthFbo;
|
||||
FBO_t *pshadowFbos[MAX_DRAWN_PSHADOWS];
|
||||
FBO_t *textureScratchFbo[2];
|
||||
FBO_t *screenScratchFbo;
|
||||
FBO_t *quarterFbo[2];
|
||||
FBO_t *calcLevelsFbo;
|
||||
FBO_t *targetLevelsFbo;
|
||||
|
@ -1915,6 +1721,8 @@ extern cvar_t *r_ext_framebuffer_object;
|
|||
extern cvar_t *r_ext_texture_float;
|
||||
extern cvar_t *r_arb_half_float_pixel;
|
||||
extern cvar_t *r_ext_framebuffer_multisample;
|
||||
extern cvar_t *r_arb_seamless_cube_map;
|
||||
extern cvar_t *r_arb_vertex_type_2_10_10_10_rev;
|
||||
|
||||
extern cvar_t *r_nobind; // turns off binding to appropriate textures
|
||||
extern cvar_t *r_singleShader; // make most world faces use default shader
|
||||
|
@ -1958,6 +1766,7 @@ extern cvar_t *r_mergeLeafSurfaces;
|
|||
extern cvar_t *r_softOverbright;
|
||||
|
||||
extern cvar_t *r_hdr;
|
||||
extern cvar_t *r_floatLightmap;
|
||||
extern cvar_t *r_postProcess;
|
||||
|
||||
extern cvar_t *r_toneMap;
|
||||
|
@ -2007,6 +1816,7 @@ extern cvar_t *r_shadowMapSize;
|
|||
extern cvar_t *r_shadowCascadeZNear;
|
||||
extern cvar_t *r_shadowCascadeZFar;
|
||||
extern cvar_t *r_shadowCascadeZBias;
|
||||
extern cvar_t *r_ignoreDstAlpha;
|
||||
|
||||
extern cvar_t *r_greyscale;
|
||||
|
||||
|
@ -2052,8 +1862,6 @@ void R_AddDrawSurf( surfaceType_t *surface, shader_t *shader,
|
|||
void R_CalcTangentSpace(vec3_t tangent, vec3_t bitangent, vec3_t normal,
|
||||
const vec3_t v0, const vec3_t v1, const vec3_t v2, const vec2_t t0, const vec2_t t1, const vec2_t t2);
|
||||
qboolean R_CalcTangentVectors(srfVert_t * dv[3]);
|
||||
void R_CalcSurfaceTriangleNeighbors(int numTriangles, srfTriangle_t * triangles);
|
||||
void R_CalcSurfaceTrianglePlanes(int numTriangles, srfTriangle_t * triangles, srfVert_t * verts);
|
||||
|
||||
#define CULL_IN 0 // completely unclipped
|
||||
#define CULL_CLIP 1 // clipped by one or more planes
|
||||
|
@ -2080,8 +1888,8 @@ void GL_TextureMode( const char *string );
|
|||
void GL_CheckErrs( char *file, int line );
|
||||
#define GL_CheckErrors(...) GL_CheckErrs(__FILE__, __LINE__)
|
||||
void GL_State( unsigned long stateVector );
|
||||
void GL_SetProjectionMatrix(matrix_t matrix);
|
||||
void GL_SetModelviewMatrix(matrix_t matrix);
|
||||
void GL_SetProjectionMatrix(mat4_t matrix);
|
||||
void GL_SetModelviewMatrix(mat4_t matrix);
|
||||
void GL_TexEnv( int env );
|
||||
void GL_Cull( int cullType );
|
||||
|
||||
|
@ -2202,14 +2010,13 @@ typedef struct shaderCommands_s
|
|||
{
|
||||
glIndex_t indexes[SHADER_MAX_INDEXES] QALIGN(16);
|
||||
vec4_t xyz[SHADER_MAX_VERTEXES] QALIGN(16);
|
||||
vec4_t normal[SHADER_MAX_VERTEXES] QALIGN(16);
|
||||
uint32_t normal[SHADER_MAX_VERTEXES] QALIGN(16);
|
||||
#ifdef USE_VERT_TANGENT_SPACE
|
||||
vec4_t tangent[SHADER_MAX_VERTEXES] QALIGN(16);
|
||||
vec4_t bitangent[SHADER_MAX_VERTEXES] QALIGN(16);
|
||||
uint32_t tangent[SHADER_MAX_VERTEXES] QALIGN(16);
|
||||
#endif
|
||||
vec2_t texCoords[SHADER_MAX_VERTEXES][2] QALIGN(16);
|
||||
vec4_t vertexColors[SHADER_MAX_VERTEXES] QALIGN(16);
|
||||
vec4_t lightdir[SHADER_MAX_VERTEXES] QALIGN(16);
|
||||
uint32_t lightdir[SHADER_MAX_VERTEXES] QALIGN(16);
|
||||
//int vertexDlightBits[SHADER_MAX_VERTEXES] QALIGN(16);
|
||||
|
||||
VBO_t *vbo;
|
||||
|
@ -2348,11 +2155,11 @@ CURVE TESSELATION
|
|||
|
||||
#define PATCH_STITCHING
|
||||
|
||||
srfGridMesh_t *R_SubdividePatchToGrid( int width, int height,
|
||||
srfBspSurface_t *R_SubdividePatchToGrid( int width, int height,
|
||||
srfVert_t points[MAX_PATCH_SIZE*MAX_PATCH_SIZE] );
|
||||
srfGridMesh_t *R_GridInsertColumn( srfGridMesh_t *grid, int column, int row, vec3_t point, float loderror );
|
||||
srfGridMesh_t *R_GridInsertRow( srfGridMesh_t *grid, int row, int column, vec3_t point, float loderror );
|
||||
void R_FreeSurfaceGridMesh( srfGridMesh_t *grid );
|
||||
srfBspSurface_t *R_GridInsertColumn( srfBspSurface_t *grid, int column, int row, vec3_t point, float loderror );
|
||||
srfBspSurface_t *R_GridInsertRow( srfBspSurface_t *grid, int row, int column, vec3_t point, float loderror );
|
||||
void R_FreeSurfaceGridMesh( srfBspSurface_t *grid );
|
||||
|
||||
/*
|
||||
============================================================
|
||||
|
@ -2373,11 +2180,17 @@ VERTEX BUFFER OBJECTS
|
|||
|
||||
============================================================
|
||||
*/
|
||||
|
||||
uint32_t R_VboPackTangent(vec4_t v);
|
||||
uint32_t R_VboPackNormal(vec3_t v);
|
||||
void R_VboUnpackTangent(vec4_t v, uint32_t b);
|
||||
void R_VboUnpackNormal(vec3_t v, uint32_t b);
|
||||
|
||||
VBO_t *R_CreateVBO(const char *name, byte * vertexes, int vertexesSize, vboUsage_t usage);
|
||||
VBO_t *R_CreateVBO2(const char *name, int numVertexes, srfVert_t * vertexes, uint32_t stateBits, vboUsage_t usage);
|
||||
|
||||
IBO_t *R_CreateIBO(const char *name, byte * indexes, int indexesSize, vboUsage_t usage);
|
||||
IBO_t *R_CreateIBO2(const char *name, int numTriangles, srfTriangle_t * triangles, vboUsage_t usage);
|
||||
IBO_t *R_CreateIBO2(const char *name, int numIndexes, glIndex_t * inIndexes, vboUsage_t usage);
|
||||
|
||||
void R_BindVBO(VBO_t * vbo);
|
||||
void R_BindNullVBO(void);
|
||||
|
@ -2413,7 +2226,7 @@ void GLSL_SetUniformFloat5(shaderProgram_t *program, int uniformNum, const vec5_
|
|||
void GLSL_SetUniformVec2(shaderProgram_t *program, int uniformNum, const vec2_t v);
|
||||
void GLSL_SetUniformVec3(shaderProgram_t *program, int uniformNum, const vec3_t v);
|
||||
void GLSL_SetUniformVec4(shaderProgram_t *program, int uniformNum, const vec4_t v);
|
||||
void GLSL_SetUniformMatrix16(shaderProgram_t *program, int uniformNum, const matrix_t matrix);
|
||||
void GLSL_SetUniformMat4(shaderProgram_t *program, int uniformNum, const mat4_t matrix);
|
||||
|
||||
shaderProgram_t *GLSL_GetGenericShaderProgram(int stage);
|
||||
|
||||
|
@ -2463,11 +2276,8 @@ ANIMATED MODELS
|
|||
=============================================================
|
||||
*/
|
||||
|
||||
// void R_MakeAnimModel( model_t *model ); haven't seen this one really, so not needed I guess.
|
||||
void R_AddAnimSurfaces( trRefEntity_t *ent );
|
||||
void RB_SurfaceAnim( md4Surface_t *surfType );
|
||||
void R_MDRAddAnimSurfaces( trRefEntity_t *ent );
|
||||
void RB_MDRSurfaceAnim( md4Surface_t *surface );
|
||||
void RB_MDRSurfaceAnim( mdrSurface_t *surface );
|
||||
qboolean R_LoadIQM (model_t *mod, void *buffer, int filesize, const char *name );
|
||||
void R_AddIQMSurfaces( trRefEntity_t *ent );
|
||||
void RB_IQMSurfaceAnim( surfaceType_t *surface );
|
||||
|
@ -2499,35 +2309,18 @@ void R_TransformClipToWindow( const vec4_t clip, const viewParms_t *view, vec4_t
|
|||
|
||||
void RB_DeformTessGeometry( void );
|
||||
|
||||
void RB_CalcEnvironmentTexCoords( float *dstTexCoords );
|
||||
void RB_CalcFogTexCoords( float *dstTexCoords );
|
||||
void RB_CalcScrollTexCoords( const float scroll[2], float *dstTexCoords );
|
||||
void RB_CalcRotateTexCoords( float rotSpeed, float *dstTexCoords );
|
||||
void RB_CalcScaleTexCoords( const float scale[2], float *dstTexCoords );
|
||||
void RB_CalcTurbulentTexCoords( const waveForm_t *wf, float *dstTexCoords );
|
||||
void RB_CalcTransformTexCoords( const texModInfo_t *tmi, float *dstTexCoords );
|
||||
|
||||
void RB_CalcScaleTexMatrix( const float scale[2], float *matrix );
|
||||
void RB_CalcScrollTexMatrix( const float scrollSpeed[2], float *matrix );
|
||||
void RB_CalcRotateTexMatrix( float degsPerSecond, float *matrix );
|
||||
void RB_CalcTurbulentTexMatrix( const waveForm_t *wf, matrix_t matrix );
|
||||
void RB_CalcTurbulentFactors( const waveForm_t *wf, float *amplitude, float *now );
|
||||
void RB_CalcTransformTexMatrix( const texModInfo_t *tmi, float *matrix );
|
||||
void RB_CalcStretchTexMatrix( const waveForm_t *wf, float *matrix );
|
||||
|
||||
void RB_CalcModulateColorsByFog( unsigned char *dstColors );
|
||||
void RB_CalcModulateAlphasByFog( unsigned char *dstColors );
|
||||
void RB_CalcModulateRGBAsByFog( unsigned char *dstColors );
|
||||
void RB_CalcWaveAlpha( const waveForm_t *wf, unsigned char *dstColors );
|
||||
float RB_CalcWaveAlphaSingle( const waveForm_t *wf );
|
||||
void RB_CalcWaveColor( const waveForm_t *wf, unsigned char *dstColors );
|
||||
float RB_CalcWaveColorSingle( const waveForm_t *wf );
|
||||
void RB_CalcAlphaFromEntity( unsigned char *dstColors );
|
||||
void RB_CalcAlphaFromOneMinusEntity( unsigned char *dstColors );
|
||||
void RB_CalcStretchTexCoords( const waveForm_t *wf, float *texCoords );
|
||||
void RB_CalcColorFromEntity( unsigned char *dstColors );
|
||||
void RB_CalcColorFromOneMinusEntity( unsigned char *dstColors );
|
||||
void RB_CalcSpecularAlpha( unsigned char *alphas );
|
||||
void RB_CalcDiffuseColor( unsigned char *colors );
|
||||
|
||||
/*
|
||||
=============================================================
|
||||
|
|
|
@ -454,6 +454,8 @@ qboolean R_CalcTangentVectors(srfVert_t * dv[3])
|
|||
/* do each vertex */
|
||||
for(i = 0; i < 3; i++)
|
||||
{
|
||||
vec3_t bitangent, nxt;
|
||||
|
||||
// calculate s tangent vector
|
||||
s = dv[i]->st[0] + 10.0f;
|
||||
t = dv[i]->st[1];
|
||||
|
@ -475,12 +477,16 @@ qboolean R_CalcTangentVectors(srfVert_t * dv[3])
|
|||
bary[1] = ((dv[2]->st[0] - s) * (dv[0]->st[1] - t) - (dv[0]->st[0] - s) * (dv[2]->st[1] - t)) / bb;
|
||||
bary[2] = ((dv[0]->st[0] - s) * (dv[1]->st[1] - t) - (dv[1]->st[0] - s) * (dv[0]->st[1] - t)) / bb;
|
||||
|
||||
dv[i]->bitangent[0] = bary[0] * dv[0]->xyz[0] + bary[1] * dv[1]->xyz[0] + bary[2] * dv[2]->xyz[0];
|
||||
dv[i]->bitangent[1] = bary[0] * dv[0]->xyz[1] + bary[1] * dv[1]->xyz[1] + bary[2] * dv[2]->xyz[1];
|
||||
dv[i]->bitangent[2] = bary[0] * dv[0]->xyz[2] + bary[1] * dv[1]->xyz[2] + bary[2] * dv[2]->xyz[2];
|
||||
bitangent[0] = bary[0] * dv[0]->xyz[0] + bary[1] * dv[1]->xyz[0] + bary[2] * dv[2]->xyz[0];
|
||||
bitangent[1] = bary[0] * dv[0]->xyz[1] + bary[1] * dv[1]->xyz[1] + bary[2] * dv[2]->xyz[1];
|
||||
bitangent[2] = bary[0] * dv[0]->xyz[2] + bary[1] * dv[1]->xyz[2] + bary[2] * dv[2]->xyz[2];
|
||||
|
||||
VectorSubtract(dv[i]->bitangent, dv[i]->xyz, dv[i]->bitangent);
|
||||
VectorNormalize(dv[i]->bitangent);
|
||||
VectorSubtract(bitangent, dv[i]->xyz, bitangent);
|
||||
VectorNormalize(bitangent);
|
||||
|
||||
// store bitangent handedness
|
||||
CrossProduct(dv[i]->normal, dv[i]->tangent, nxt);
|
||||
dv[i]->tangent[3] = (DotProduct(nxt, bitangent) < 0.0f) ? -1.0f : 1.0f;
|
||||
|
||||
// debug code
|
||||
//% Sys_FPrintf( SYS_VRB, "%d S: (%f %f %f) T: (%f %f %f)\n", i,
|
||||
|
@ -492,99 +498,6 @@ qboolean R_CalcTangentVectors(srfVert_t * dv[3])
|
|||
#endif
|
||||
|
||||
|
||||
/*
|
||||
=================
|
||||
R_FindSurfaceTriangleWithEdge
|
||||
|
||||
Recoded from Q2E
|
||||
=================
|
||||
*/
|
||||
static int R_FindSurfaceTriangleWithEdge(int numTriangles, srfTriangle_t * triangles, int start, int end, int ignore)
|
||||
{
|
||||
srfTriangle_t *tri;
|
||||
int count, match;
|
||||
int i;
|
||||
|
||||
count = 0;
|
||||
match = -1;
|
||||
|
||||
for(i = 0, tri = triangles; i < numTriangles; i++, tri++)
|
||||
{
|
||||
if((tri->indexes[0] == start && tri->indexes[1] == end) ||
|
||||
(tri->indexes[1] == start && tri->indexes[2] == end) || (tri->indexes[2] == start && tri->indexes[0] == end))
|
||||
{
|
||||
if(i != ignore)
|
||||
{
|
||||
match = i;
|
||||
}
|
||||
|
||||
count++;
|
||||
}
|
||||
else if((tri->indexes[1] == start && tri->indexes[0] == end) ||
|
||||
(tri->indexes[2] == start && tri->indexes[1] == end) || (tri->indexes[0] == start && tri->indexes[2] == end))
|
||||
{
|
||||
count++;
|
||||
}
|
||||
}
|
||||
|
||||
// detect edges shared by three triangles and make them seams
|
||||
if(count > 2)
|
||||
{
|
||||
match = -1;
|
||||
}
|
||||
|
||||
return match;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
=================
|
||||
R_CalcSurfaceTriangleNeighbors
|
||||
|
||||
Recoded from Q2E
|
||||
=================
|
||||
*/
|
||||
void R_CalcSurfaceTriangleNeighbors(int numTriangles, srfTriangle_t * triangles)
|
||||
{
|
||||
int i;
|
||||
srfTriangle_t *tri;
|
||||
|
||||
for(i = 0, tri = triangles; i < numTriangles; i++, tri++)
|
||||
{
|
||||
tri->neighbors[0] = R_FindSurfaceTriangleWithEdge(numTriangles, triangles, tri->indexes[1], tri->indexes[0], i);
|
||||
tri->neighbors[1] = R_FindSurfaceTriangleWithEdge(numTriangles, triangles, tri->indexes[2], tri->indexes[1], i);
|
||||
tri->neighbors[2] = R_FindSurfaceTriangleWithEdge(numTriangles, triangles, tri->indexes[0], tri->indexes[2], i);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
R_CalcSurfaceTrianglePlanes
|
||||
=================
|
||||
*/
|
||||
void R_CalcSurfaceTrianglePlanes(int numTriangles, srfTriangle_t * triangles, srfVert_t * verts)
|
||||
{
|
||||
int i;
|
||||
srfTriangle_t *tri;
|
||||
|
||||
for(i = 0, tri = triangles; i < numTriangles; i++, tri++)
|
||||
{
|
||||
float *v1, *v2, *v3;
|
||||
vec3_t d1, d2;
|
||||
|
||||
v1 = verts[tri->indexes[0]].xyz;
|
||||
v2 = verts[tri->indexes[1]].xyz;
|
||||
v3 = verts[tri->indexes[2]].xyz;
|
||||
|
||||
VectorSubtract(v2, v1, d1);
|
||||
VectorSubtract(v3, v1, d2);
|
||||
|
||||
CrossProduct(d2, d1, tri->plane);
|
||||
tri->plane[3] = DotProduct(tri->plane, v1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
=================
|
||||
R_CullLocalBox
|
||||
|
@ -927,7 +840,7 @@ void R_RotateForEntity( const trRefEntity_t *ent, const viewParms_t *viewParms,
|
|||
glMatrix[11] = 0;
|
||||
glMatrix[15] = 1;
|
||||
|
||||
Matrix16Copy(glMatrix, or->transformMatrix);
|
||||
Mat4Copy(glMatrix, or->transformMatrix);
|
||||
myGlMultMatrix( glMatrix, viewParms->world.modelMatrix, or->modelMatrix );
|
||||
|
||||
// calculate the viewer origin in the model's space
|
||||
|
@ -1365,7 +1278,7 @@ R_PlaneForSurface
|
|||
=============
|
||||
*/
|
||||
void R_PlaneForSurface (surfaceType_t *surfType, cplane_t *plane) {
|
||||
srfTriangles_t *tri;
|
||||
srfBspSurface_t *tri;
|
||||
srfPoly_t *poly;
|
||||
srfVert_t *v1, *v2, *v3;
|
||||
vec4_t plane4;
|
||||
|
@ -1377,13 +1290,13 @@ void R_PlaneForSurface (surfaceType_t *surfType, cplane_t *plane) {
|
|||
}
|
||||
switch (*surfType) {
|
||||
case SF_FACE:
|
||||
*plane = ((srfSurfaceFace_t *)surfType)->plane;
|
||||
*plane = ((srfBspSurface_t *)surfType)->cullPlane;
|
||||
return;
|
||||
case SF_TRIANGLES:
|
||||
tri = (srfTriangles_t *)surfType;
|
||||
v1 = tri->verts + tri->triangles[0].indexes[0];
|
||||
v2 = tri->verts + tri->triangles[0].indexes[1];
|
||||
v3 = tri->verts + tri->triangles[0].indexes[2];
|
||||
tri = (srfBspSurface_t *)surfType;
|
||||
v1 = tri->verts + tri->indexes[0];
|
||||
v2 = tri->verts + tri->indexes[1];
|
||||
v3 = tri->verts + tri->indexes[2];
|
||||
PlaneFromPoints( plane4, v1->xyz, v2->xyz, v3->xyz );
|
||||
VectorCopy( plane4, plane->normal );
|
||||
plane->dist = plane4[3];
|
||||
|
@ -1649,7 +1562,8 @@ static qboolean SurfIsOffscreen( const drawSurf_t *drawSurf, vec4_t clipDest[128
|
|||
|
||||
for ( i = 0; i < tess.numIndexes; i += 3 )
|
||||
{
|
||||
vec3_t normal;
|
||||
vec3_t normal, tNormal;
|
||||
|
||||
float len;
|
||||
|
||||
VectorSubtract( tess.xyz[tess.indexes[i]], tr.viewParms.or.origin, normal );
|
||||
|
@ -1660,7 +1574,9 @@ static qboolean SurfIsOffscreen( const drawSurf_t *drawSurf, vec4_t clipDest[128
|
|||
shortest = len;
|
||||
}
|
||||
|
||||
if ( DotProduct( normal, tess.normal[tess.indexes[i]] ) >= 0 )
|
||||
R_VboUnpackNormal(tNormal, tess.normal[tess.indexes[i]]);
|
||||
|
||||
if ( DotProduct( normal, tNormal ) >= 0 )
|
||||
{
|
||||
numTriangles--;
|
||||
}
|
||||
|
@ -1997,9 +1913,6 @@ static void R_AddEntitySurface (int entityNum)
|
|||
case MOD_MESH:
|
||||
R_AddMD3Surfaces( ent );
|
||||
break;
|
||||
case MOD_MD4:
|
||||
R_AddAnimSurfaces( ent );
|
||||
break;
|
||||
case MOD_MDR:
|
||||
R_MDRAddAnimSurfaces( ent );
|
||||
break;
|
||||
|
@ -2286,12 +2199,6 @@ void R_RenderPshadowMaps(const refdef_t *fd)
|
|||
}
|
||||
break;
|
||||
|
||||
case MOD_MD4:
|
||||
{
|
||||
// FIXME: actually calculate the radius and bounds, this is a horrible hack
|
||||
radius = r_pshadowDist->value / 2.0f;
|
||||
}
|
||||
break;
|
||||
case MOD_MDR:
|
||||
{
|
||||
// FIXME: never actually tested this
|
||||
|
@ -2716,7 +2623,7 @@ void R_RenderSunShadowMaps(const refdef_t *fd, int level)
|
|||
|
||||
// Create bounds for light projection using slice of view projection
|
||||
{
|
||||
matrix_t lightViewMatrix;
|
||||
mat4_t lightViewMatrix;
|
||||
vec4_t point, base, lightViewPoint;
|
||||
float lx, ly;
|
||||
|
||||
|
@ -2724,7 +2631,7 @@ void R_RenderSunShadowMaps(const refdef_t *fd, int level)
|
|||
point[3] = 1;
|
||||
lightViewPoint[3] = 1;
|
||||
|
||||
Matrix16View(lightViewAxis, lightOrigin, lightViewMatrix);
|
||||
Mat4View(lightViewAxis, lightOrigin, lightViewMatrix);
|
||||
|
||||
ClearBounds(lightviewBounds[0], lightviewBounds[1]);
|
||||
|
||||
|
@ -2735,22 +2642,22 @@ void R_RenderSunShadowMaps(const refdef_t *fd, int level)
|
|||
|
||||
VectorMA(base, lx, fd->viewaxis[1], point);
|
||||
VectorMA(point, ly, fd->viewaxis[2], point);
|
||||
Matrix16Transform(lightViewMatrix, point, lightViewPoint);
|
||||
Mat4Transform(lightViewMatrix, point, lightViewPoint);
|
||||
AddPointToBounds(lightViewPoint, lightviewBounds[0], lightviewBounds[1]);
|
||||
|
||||
VectorMA(base, -lx, fd->viewaxis[1], point);
|
||||
VectorMA(point, ly, fd->viewaxis[2], point);
|
||||
Matrix16Transform(lightViewMatrix, point, lightViewPoint);
|
||||
Mat4Transform(lightViewMatrix, point, lightViewPoint);
|
||||
AddPointToBounds(lightViewPoint, lightviewBounds[0], lightviewBounds[1]);
|
||||
|
||||
VectorMA(base, lx, fd->viewaxis[1], point);
|
||||
VectorMA(point, -ly, fd->viewaxis[2], point);
|
||||
Matrix16Transform(lightViewMatrix, point, lightViewPoint);
|
||||
Mat4Transform(lightViewMatrix, point, lightViewPoint);
|
||||
AddPointToBounds(lightViewPoint, lightviewBounds[0], lightviewBounds[1]);
|
||||
|
||||
VectorMA(base, -lx, fd->viewaxis[1], point);
|
||||
VectorMA(point, -ly, fd->viewaxis[2], point);
|
||||
Matrix16Transform(lightViewMatrix, point, lightViewPoint);
|
||||
Mat4Transform(lightViewMatrix, point, lightViewPoint);
|
||||
AddPointToBounds(lightViewPoint, lightviewBounds[0], lightviewBounds[1]);
|
||||
|
||||
|
||||
|
@ -2761,22 +2668,22 @@ void R_RenderSunShadowMaps(const refdef_t *fd, int level)
|
|||
|
||||
VectorMA(base, lx, fd->viewaxis[1], point);
|
||||
VectorMA(point, ly, fd->viewaxis[2], point);
|
||||
Matrix16Transform(lightViewMatrix, point, lightViewPoint);
|
||||
Mat4Transform(lightViewMatrix, point, lightViewPoint);
|
||||
AddPointToBounds(lightViewPoint, lightviewBounds[0], lightviewBounds[1]);
|
||||
|
||||
VectorMA(base, -lx, fd->viewaxis[1], point);
|
||||
VectorMA(point, ly, fd->viewaxis[2], point);
|
||||
Matrix16Transform(lightViewMatrix, point, lightViewPoint);
|
||||
Mat4Transform(lightViewMatrix, point, lightViewPoint);
|
||||
AddPointToBounds(lightViewPoint, lightviewBounds[0], lightviewBounds[1]);
|
||||
|
||||
VectorMA(base, lx, fd->viewaxis[1], point);
|
||||
VectorMA(point, -ly, fd->viewaxis[2], point);
|
||||
Matrix16Transform(lightViewMatrix, point, lightViewPoint);
|
||||
Mat4Transform(lightViewMatrix, point, lightViewPoint);
|
||||
AddPointToBounds(lightViewPoint, lightviewBounds[0], lightviewBounds[1]);
|
||||
|
||||
VectorMA(base, -lx, fd->viewaxis[1], point);
|
||||
VectorMA(point, -ly, fd->viewaxis[2], point);
|
||||
Matrix16Transform(lightViewMatrix, point, lightViewPoint);
|
||||
Mat4Transform(lightViewMatrix, point, lightViewPoint);
|
||||
AddPointToBounds(lightViewPoint, lightviewBounds[0], lightviewBounds[1]);
|
||||
|
||||
if (!glRefConfig.depthClamp)
|
||||
|
@ -2874,7 +2781,7 @@ void R_RenderSunShadowMaps(const refdef_t *fd, int level)
|
|||
R_SortDrawSurfs( tr.refdef.drawSurfs + firstDrawSurf, tr.refdef.numDrawSurfs - firstDrawSurf );
|
||||
}
|
||||
|
||||
Matrix16Multiply(tr.viewParms.projectionMatrix, tr.viewParms.world.modelMatrix, tr.refdef.sunShadowMvp[level]);
|
||||
Mat4Multiply(tr.viewParms.projectionMatrix, tr.viewParms.world.modelMatrix, tr.refdef.sunShadowMvp[level]);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2944,7 +2851,7 @@ void R_RenderCubemapSide( int cubemapIndex, int cubemapSide, qboolean subscene )
|
|||
|
||||
// FIXME: sun shadows aren't rendered correctly in cubemaps
|
||||
// fix involves changing r_FBufScale to fit smaller cubemap image size, or rendering cubemap to framebuffer first
|
||||
if(0) //(glRefConfig.framebufferObject && (r_forceSun->integer || tr.sunShadows))
|
||||
if(0) //(glRefConfig.framebufferObject && r_sunlightMode->integer && (r_forceSun->integer || tr.sunShadows))
|
||||
{
|
||||
R_RenderSunShadowMaps(&refdef, 0);
|
||||
R_RenderSunShadowMaps(&refdef, 1);
|
||||
|
|
|
@ -268,8 +268,8 @@ int R_MarkFragments( int numPoints, const vec3_t *points, const vec3_t projectio
|
|||
vec3_t clipPoints[2][MAX_VERTS_ON_POLY];
|
||||
int numClipPoints;
|
||||
float *v;
|
||||
srfGridMesh_t *cv;
|
||||
srfTriangle_t *tri;
|
||||
srfBspSurface_t *cv;
|
||||
glIndex_t *tri;
|
||||
srfVert_t *dv;
|
||||
vec3_t normal;
|
||||
vec3_t projectionDir;
|
||||
|
@ -327,7 +327,7 @@ int R_MarkFragments( int numPoints, const vec3_t *points, const vec3_t projectio
|
|||
|
||||
if (*surfaces[i] == SF_GRID) {
|
||||
|
||||
cv = (srfGridMesh_t *) surfaces[i];
|
||||
cv = (srfBspSurface_t *) surfaces[i];
|
||||
for ( m = 0 ; m < cv->height - 1 ; m++ ) {
|
||||
for ( n = 0 ; n < cv->width - 1 ; n++ ) {
|
||||
// We triangulate the grid and chop all triangles within
|
||||
|
@ -407,19 +407,19 @@ int R_MarkFragments( int numPoints, const vec3_t *points, const vec3_t projectio
|
|||
}
|
||||
else if (*surfaces[i] == SF_FACE) {
|
||||
|
||||
srfSurfaceFace_t *surf = ( srfSurfaceFace_t * ) surfaces[i];
|
||||
srfBspSurface_t *surf = ( srfBspSurface_t * ) surfaces[i];
|
||||
|
||||
// check the normal of this face
|
||||
if (DotProduct(surf->plane.normal, projectionDir) > -0.5) {
|
||||
if (DotProduct(surf->cullPlane.normal, projectionDir) > -0.5) {
|
||||
continue;
|
||||
}
|
||||
|
||||
for(k = 0, tri = surf->triangles; k < surf->numTriangles; k++, tri++)
|
||||
for(k = 0, tri = surf->indexes; k < surf->numIndexes; k += 3, tri += 3)
|
||||
{
|
||||
for(j = 0; j < 3; j++)
|
||||
{
|
||||
v = surf->verts[tri->indexes[j]].xyz;
|
||||
VectorMA(v, MARKER_OFFSET, surf->plane.normal, clipPoints[0][j]);
|
||||
v = surf->verts[tri[j]].xyz;
|
||||
VectorMA(v, MARKER_OFFSET, surf->cullPlane.normal, clipPoints[0][j]);
|
||||
}
|
||||
|
||||
// add the fragments of this face
|
||||
|
@ -435,14 +435,14 @@ int R_MarkFragments( int numPoints, const vec3_t *points, const vec3_t projectio
|
|||
}
|
||||
else if(*surfaces[i] == SF_TRIANGLES && r_marksOnTriangleMeshes->integer) {
|
||||
|
||||
srfTriangles_t *surf = (srfTriangles_t *) surfaces[i];
|
||||
srfBspSurface_t *surf = (srfBspSurface_t *) surfaces[i];
|
||||
|
||||
for(k = 0, tri = surf->triangles; k < surf->numTriangles; k++, tri++)
|
||||
for(k = 0, tri = surf->indexes; k < surf->numIndexes; k += 3, tri += 3)
|
||||
{
|
||||
for(j = 0; j < 3; j++)
|
||||
{
|
||||
v = surf->verts[tri->indexes[j]].xyz;
|
||||
VectorMA(v, MARKER_OFFSET, surf->verts[tri->indexes[j]].normal, clipPoints[0][j]);
|
||||
v = surf->verts[tri[j]].xyz;
|
||||
VectorMA(v, MARKER_OFFSET, surf->verts[tri[j]].normal, clipPoints[0][j]);
|
||||
}
|
||||
|
||||
// add the fragments of this face
|
||||
|
|
|
@ -26,7 +26,6 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|||
#define LL(x) x=LittleLong(x)
|
||||
|
||||
static qboolean R_LoadMD3(model_t *mod, int lod, void *buffer, int bufferSize, const char *modName);
|
||||
static qboolean R_LoadMD4(model_t *mod, void *buffer, const char *name );
|
||||
static qboolean R_LoadMDR(model_t *mod, void *buffer, int filesize, const char *name );
|
||||
|
||||
/*
|
||||
|
@ -73,15 +72,10 @@ qhandle_t R_RegisterMD3(const char *name, model_t *mod)
|
|||
continue;
|
||||
|
||||
ident = LittleLong(* (unsigned *) buf.u);
|
||||
if (ident == MD4_IDENT)
|
||||
loaded = R_LoadMD4(mod, buf.u, name);
|
||||
if (ident == MD3_IDENT)
|
||||
loaded = R_LoadMD3(mod, lod, buf.u, size, name);
|
||||
else
|
||||
{
|
||||
if (ident == MD3_IDENT)
|
||||
loaded = R_LoadMD3(mod, lod, buf.u, size, name);
|
||||
else
|
||||
ri.Printf(PRINT_WARNING,"R_RegisterMD3: unknown fileid for %s\n", name);
|
||||
}
|
||||
ri.Printf(PRINT_WARNING,"R_RegisterMD3: unknown fileid for %s\n", name);
|
||||
|
||||
ri.FS_FreeFile(buf.v);
|
||||
|
||||
|
@ -201,7 +195,6 @@ static modelExtToLoaderMap_t modelLoaders[ ] =
|
|||
{
|
||||
{ "iqm", R_RegisterIQM },
|
||||
{ "mdr", R_RegisterMDR },
|
||||
{ "md4", R_RegisterMD3 },
|
||||
{ "md3", R_RegisterMD3 }
|
||||
};
|
||||
|
||||
|
@ -394,7 +387,7 @@ static qboolean R_LoadMD3(model_t * mod, int lod, void *buffer, int bufferSize,
|
|||
mdvFrame_t *frame;
|
||||
mdvSurface_t *surf;//, *surface;
|
||||
int *shaderIndex;
|
||||
srfTriangle_t *tri;
|
||||
glIndex_t *tri;
|
||||
mdvVertex_t *v;
|
||||
mdvSt_t *st;
|
||||
mdvTag_t *tag;
|
||||
|
@ -551,19 +544,17 @@ static qboolean R_LoadMD3(model_t * mod, int lod, void *buffer, int bufferSize,
|
|||
}
|
||||
|
||||
// swap all the triangles
|
||||
surf->numTriangles = md3Surf->numTriangles;
|
||||
surf->triangles = tri = ri.Hunk_Alloc(sizeof(*tri) * md3Surf->numTriangles, h_low);
|
||||
surf->numIndexes = md3Surf->numTriangles * 3;
|
||||
surf->indexes = tri = ri.Hunk_Alloc(sizeof(*tri) * 3 * md3Surf->numTriangles, h_low);
|
||||
|
||||
md3Tri = (md3Triangle_t *) ((byte *) md3Surf + md3Surf->ofsTriangles);
|
||||
for(j = 0; j < md3Surf->numTriangles; j++, tri++, md3Tri++)
|
||||
for(j = 0; j < md3Surf->numTriangles; j++, tri += 3, md3Tri++)
|
||||
{
|
||||
tri->indexes[0] = LittleLong(md3Tri->indexes[0]);
|
||||
tri->indexes[1] = LittleLong(md3Tri->indexes[1]);
|
||||
tri->indexes[2] = LittleLong(md3Tri->indexes[2]);
|
||||
tri[0] = LittleLong(md3Tri->indexes[0]);
|
||||
tri[1] = LittleLong(md3Tri->indexes[1]);
|
||||
tri[2] = LittleLong(md3Tri->indexes[2]);
|
||||
}
|
||||
|
||||
R_CalcSurfaceTriangleNeighbors(surf->numTriangles, surf->triangles);
|
||||
|
||||
// swap all the XyzNormals
|
||||
surf->numVerts = md3Surf->numVerts;
|
||||
surf->verts = v = ri.Hunk_Alloc(sizeof(*v) * (md3Surf->numVerts * md3Surf->numFrames), h_low);
|
||||
|
@ -625,15 +616,15 @@ static qboolean R_LoadMD3(model_t * mod, int lod, void *buffer, int bufferSize,
|
|||
|
||||
for(f = 0; f < mdvModel->numFrames; f++)
|
||||
{
|
||||
for(j = 0, tri = surf->triangles; j < surf->numTriangles; j++, tri++)
|
||||
for(j = 0, tri = surf->indexes; j < surf->numIndexes; j += 3, tri += 3)
|
||||
{
|
||||
v0 = surf->verts[surf->numVerts * f + tri->indexes[0]].xyz;
|
||||
v1 = surf->verts[surf->numVerts * f + tri->indexes[1]].xyz;
|
||||
v2 = surf->verts[surf->numVerts * f + tri->indexes[2]].xyz;
|
||||
v0 = surf->verts[surf->numVerts * f + tri[0]].xyz;
|
||||
v1 = surf->verts[surf->numVerts * f + tri[1]].xyz;
|
||||
v2 = surf->verts[surf->numVerts * f + tri[2]].xyz;
|
||||
|
||||
t0 = surf->st[tri->indexes[0]].st;
|
||||
t1 = surf->st[tri->indexes[1]].st;
|
||||
t2 = surf->st[tri->indexes[2]].st;
|
||||
t0 = surf->st[tri[0]].st;
|
||||
t1 = surf->st[tri[1]].st;
|
||||
t2 = surf->st[tri[2]].st;
|
||||
|
||||
if (!r_recalcMD3Normals->integer)
|
||||
VectorCopy(v->normal, normal);
|
||||
|
@ -651,15 +642,15 @@ static qboolean R_LoadMD3(model_t * mod, int lod, void *buffer, int bufferSize,
|
|||
{
|
||||
float *v;
|
||||
|
||||
v = surf->verts[surf->numVerts * f + tri->indexes[k]].tangent;
|
||||
v = surf->verts[surf->numVerts * f + tri[k]].tangent;
|
||||
VectorAdd(v, tangent, v);
|
||||
|
||||
v = surf->verts[surf->numVerts * f + tri->indexes[k]].bitangent;
|
||||
v = surf->verts[surf->numVerts * f + tri[k]].bitangent;
|
||||
VectorAdd(v, bitangent, v);
|
||||
|
||||
if (r_recalcMD3Normals->integer)
|
||||
{
|
||||
v = surf->verts[surf->numVerts * f + tri->indexes[k]].normal;
|
||||
v = surf->verts[surf->numVerts * f + tri[k]].normal;
|
||||
VectorAdd(v, normal, v);
|
||||
}
|
||||
}
|
||||
|
@ -691,11 +682,10 @@ static qboolean R_LoadMD3(model_t * mod, int lod, void *buffer, int bufferSize,
|
|||
for (i = 0; i < mdvModel->numSurfaces; i++, vboSurf++, surf++)
|
||||
{
|
||||
vec3_t *verts;
|
||||
vec3_t *normals;
|
||||
vec2_t *texcoords;
|
||||
uint32_t *normals;
|
||||
#ifdef USE_VERT_TANGENT_SPACE
|
||||
vec3_t *tangents;
|
||||
vec3_t *bitangents;
|
||||
uint32_t *tangents;
|
||||
#endif
|
||||
|
||||
byte *data;
|
||||
|
@ -703,7 +693,7 @@ static qboolean R_LoadMD3(model_t * mod, int lod, void *buffer, int bufferSize,
|
|||
|
||||
int ofs_xyz, ofs_normal, ofs_st;
|
||||
#ifdef USE_VERT_TANGENT_SPACE
|
||||
int ofs_tangent, ofs_bitangent;
|
||||
int ofs_tangent;
|
||||
#endif
|
||||
|
||||
dataSize = 0;
|
||||
|
@ -717,9 +707,6 @@ static qboolean R_LoadMD3(model_t * mod, int lod, void *buffer, int bufferSize,
|
|||
#ifdef USE_VERT_TANGENT_SPACE
|
||||
ofs_tangent = dataSize;
|
||||
dataSize += surf->numVerts * mdvModel->numFrames * sizeof(*tangents);
|
||||
|
||||
ofs_bitangent = dataSize;
|
||||
dataSize += surf->numVerts * mdvModel->numFrames * sizeof(*bitangents);
|
||||
#endif
|
||||
|
||||
ofs_st = dataSize;
|
||||
|
@ -731,18 +718,24 @@ static qboolean R_LoadMD3(model_t * mod, int lod, void *buffer, int bufferSize,
|
|||
normals = (void *)(data + ofs_normal);
|
||||
#ifdef USE_VERT_TANGENT_SPACE
|
||||
tangents = (void *)(data + ofs_tangent);
|
||||
bitangents = (void *)(data + ofs_bitangent);
|
||||
#endif
|
||||
texcoords = (void *)(data + ofs_st);
|
||||
|
||||
v = surf->verts;
|
||||
for ( j = 0; j < surf->numVerts * mdvModel->numFrames ; j++, v++ )
|
||||
{
|
||||
vec3_t nxt;
|
||||
vec4_t tangent;
|
||||
|
||||
VectorCopy(v->xyz, verts[j]);
|
||||
VectorCopy(v->normal, normals[j]);
|
||||
|
||||
normals[j] = R_VboPackNormal(v->normal);
|
||||
#ifdef USE_VERT_TANGENT_SPACE
|
||||
VectorCopy(v->tangent, tangents[j]);
|
||||
VectorCopy(v->bitangent, bitangents[j]);
|
||||
CrossProduct(v->normal, v->tangent, nxt);
|
||||
VectorCopy(v->tangent, tangent);
|
||||
tangent[3] = (DotProduct(nxt, v->bitangent) < 0.0f) ? -1.0f : 1.0f;
|
||||
|
||||
tangents[j] = R_VboPackTangent(tangent);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -755,7 +748,7 @@ static qboolean R_LoadMD3(model_t * mod, int lod, void *buffer, int bufferSize,
|
|||
vboSurf->surfaceType = SF_VBO_MDVMESH;
|
||||
vboSurf->mdvModel = mdvModel;
|
||||
vboSurf->mdvSurface = surf;
|
||||
vboSurf->numIndexes = surf->numTriangles * 3;
|
||||
vboSurf->numIndexes = surf->numIndexes;
|
||||
vboSurf->numVerts = surf->numVerts;
|
||||
|
||||
vboSurf->minIndex = 0;
|
||||
|
@ -767,7 +760,6 @@ static qboolean R_LoadMD3(model_t * mod, int lod, void *buffer, int bufferSize,
|
|||
vboSurf->vbo->ofs_normal = ofs_normal;
|
||||
#ifdef USE_VERT_TANGENT_SPACE
|
||||
vboSurf->vbo->ofs_tangent = ofs_tangent;
|
||||
vboSurf->vbo->ofs_bitangent = ofs_bitangent;
|
||||
#endif
|
||||
vboSurf->vbo->ofs_st = ofs_st;
|
||||
|
||||
|
@ -775,7 +767,6 @@ static qboolean R_LoadMD3(model_t * mod, int lod, void *buffer, int bufferSize,
|
|||
vboSurf->vbo->stride_normal = sizeof(*normals);
|
||||
#ifdef USE_VERT_TANGENT_SPACE
|
||||
vboSurf->vbo->stride_tangent = sizeof(*tangents);
|
||||
vboSurf->vbo->stride_bitangent = sizeof(*bitangents);
|
||||
#endif
|
||||
vboSurf->vbo->stride_st = sizeof(*st);
|
||||
|
||||
|
@ -784,7 +775,7 @@ static qboolean R_LoadMD3(model_t * mod, int lod, void *buffer, int bufferSize,
|
|||
|
||||
ri.Free(data);
|
||||
|
||||
vboSurf->ibo = R_CreateIBO2(va("staticMD3Mesh_IBO %s", surf->name), surf->numTriangles, surf->triangles, VBO_USAGE_STATIC);
|
||||
vboSurf->ibo = R_CreateIBO2(va("staticMD3Mesh_IBO %s", surf->name), surf->numIndexes, surf->indexes, VBO_USAGE_STATIC);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -836,7 +827,7 @@ static qboolean R_LoadMDR( model_t *mod, void *buffer, int filesize, const char
|
|||
LL(pinmodel->ofsFrames);
|
||||
|
||||
// This is a model that uses some type of compressed Bones. We don't want to uncompress every bone for each rendered frame
|
||||
// over and over again, we'll uncompress it in this function already, so we must adjust the size of the target md4.
|
||||
// over and over again, we'll uncompress it in this function already, so we must adjust the size of the target mdr.
|
||||
if(pinmodel->ofsFrames < 0)
|
||||
{
|
||||
// mdrFrame_t is larger than mdrCompFrame_t:
|
||||
|
@ -1133,162 +1124,6 @@ static qboolean R_LoadMDR( model_t *mod, void *buffer, int filesize, const char
|
|||
return qtrue;
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
R_LoadMD4
|
||||
=================
|
||||
*/
|
||||
|
||||
static qboolean R_LoadMD4( model_t *mod, void *buffer, const char *mod_name ) {
|
||||
int i, j, k, lodindex;
|
||||
md4Header_t *pinmodel, *md4;
|
||||
md4Frame_t *frame;
|
||||
md4LOD_t *lod;
|
||||
md4Surface_t *surf;
|
||||
md4Triangle_t *tri;
|
||||
md4Vertex_t *v;
|
||||
int version;
|
||||
int size;
|
||||
shader_t *sh;
|
||||
int frameSize;
|
||||
|
||||
pinmodel = (md4Header_t *)buffer;
|
||||
|
||||
version = LittleLong (pinmodel->version);
|
||||
if (version != MD4_VERSION) {
|
||||
ri.Printf( PRINT_WARNING, "R_LoadMD4: %s has wrong version (%i should be %i)\n",
|
||||
mod_name, version, MD4_VERSION);
|
||||
return qfalse;
|
||||
}
|
||||
|
||||
mod->type = MOD_MD4;
|
||||
size = LittleLong(pinmodel->ofsEnd);
|
||||
mod->dataSize += size;
|
||||
mod->modelData = md4 = ri.Hunk_Alloc( size, h_low );
|
||||
|
||||
Com_Memcpy(md4, buffer, size);
|
||||
|
||||
LL(md4->ident);
|
||||
LL(md4->version);
|
||||
LL(md4->numFrames);
|
||||
LL(md4->numBones);
|
||||
LL(md4->numLODs);
|
||||
LL(md4->ofsFrames);
|
||||
LL(md4->ofsLODs);
|
||||
md4->ofsEnd = size;
|
||||
|
||||
if ( md4->numFrames < 1 ) {
|
||||
ri.Printf( PRINT_WARNING, "R_LoadMD4: %s has no frames\n", mod_name );
|
||||
return qfalse;
|
||||
}
|
||||
|
||||
// we don't need to swap tags in the renderer, they aren't used
|
||||
|
||||
// swap all the frames
|
||||
frameSize = (size_t)( &((md4Frame_t *)0)->bones[ md4->numBones ] );
|
||||
for ( i = 0 ; i < md4->numFrames ; i++) {
|
||||
frame = (md4Frame_t *) ( (byte *)md4 + md4->ofsFrames + i * frameSize );
|
||||
frame->radius = LittleFloat( frame->radius );
|
||||
for ( j = 0 ; j < 3 ; j++ ) {
|
||||
frame->bounds[0][j] = LittleFloat( frame->bounds[0][j] );
|
||||
frame->bounds[1][j] = LittleFloat( frame->bounds[1][j] );
|
||||
frame->localOrigin[j] = LittleFloat( frame->localOrigin[j] );
|
||||
}
|
||||
for ( j = 0 ; j < md4->numBones * sizeof( md4Bone_t ) / 4 ; j++ ) {
|
||||
((float *)frame->bones)[j] = LittleFloat( ((float *)frame->bones)[j] );
|
||||
}
|
||||
}
|
||||
|
||||
// swap all the LOD's
|
||||
lod = (md4LOD_t *) ( (byte *)md4 + md4->ofsLODs );
|
||||
for ( lodindex = 0 ; lodindex < md4->numLODs ; lodindex++ ) {
|
||||
|
||||
// swap all the surfaces
|
||||
surf = (md4Surface_t *) ( (byte *)lod + lod->ofsSurfaces );
|
||||
for ( i = 0 ; i < lod->numSurfaces ; i++) {
|
||||
LL(surf->ident);
|
||||
LL(surf->numTriangles);
|
||||
LL(surf->ofsTriangles);
|
||||
LL(surf->numVerts);
|
||||
LL(surf->ofsVerts);
|
||||
LL(surf->ofsEnd);
|
||||
|
||||
if ( surf->numVerts >= SHADER_MAX_VERTEXES ) {
|
||||
ri.Printf(PRINT_WARNING, "R_LoadMD4: %s has more than %i verts on %s (%i).\n",
|
||||
mod_name, SHADER_MAX_VERTEXES - 1, surf->name[0] ? surf->name : "a surface",
|
||||
surf->numVerts );
|
||||
return qfalse;
|
||||
}
|
||||
if ( surf->numTriangles*3 >= SHADER_MAX_INDEXES ) {
|
||||
ri.Printf(PRINT_WARNING, "R_LoadMD4: %s has more than %i triangles on %s (%i).\n",
|
||||
mod_name, ( SHADER_MAX_INDEXES / 3 ) - 1, surf->name[0] ? surf->name : "a surface",
|
||||
surf->numTriangles );
|
||||
return qfalse;
|
||||
}
|
||||
|
||||
// change to surface identifier
|
||||
surf->ident = SF_MD4;
|
||||
|
||||
// lowercase the surface name so skin compares are faster
|
||||
Q_strlwr( surf->name );
|
||||
|
||||
// register the shaders
|
||||
sh = R_FindShader( surf->shader, LIGHTMAP_NONE, qtrue );
|
||||
if ( sh->defaultShader ) {
|
||||
surf->shaderIndex = 0;
|
||||
} else {
|
||||
surf->shaderIndex = sh->index;
|
||||
}
|
||||
|
||||
// swap all the triangles
|
||||
tri = (md4Triangle_t *) ( (byte *)surf + surf->ofsTriangles );
|
||||
for ( j = 0 ; j < surf->numTriangles ; j++, tri++ ) {
|
||||
LL(tri->indexes[0]);
|
||||
LL(tri->indexes[1]);
|
||||
LL(tri->indexes[2]);
|
||||
}
|
||||
|
||||
// swap all the vertexes
|
||||
// FIXME
|
||||
// This makes TFC's skeletons work. Shouldn't be necessary anymore, but left
|
||||
// in for reference.
|
||||
//v = (md4Vertex_t *) ( (byte *)surf + surf->ofsVerts + 12);
|
||||
v = (md4Vertex_t *) ( (byte *)surf + surf->ofsVerts);
|
||||
for ( j = 0 ; j < surf->numVerts ; j++ ) {
|
||||
v->normal[0] = LittleFloat( v->normal[0] );
|
||||
v->normal[1] = LittleFloat( v->normal[1] );
|
||||
v->normal[2] = LittleFloat( v->normal[2] );
|
||||
|
||||
v->texCoords[0] = LittleFloat( v->texCoords[0] );
|
||||
v->texCoords[1] = LittleFloat( v->texCoords[1] );
|
||||
|
||||
v->numWeights = LittleLong( v->numWeights );
|
||||
|
||||
for ( k = 0 ; k < v->numWeights ; k++ ) {
|
||||
v->weights[k].boneIndex = LittleLong( v->weights[k].boneIndex );
|
||||
v->weights[k].boneWeight = LittleFloat( v->weights[k].boneWeight );
|
||||
v->weights[k].offset[0] = LittleFloat( v->weights[k].offset[0] );
|
||||
v->weights[k].offset[1] = LittleFloat( v->weights[k].offset[1] );
|
||||
v->weights[k].offset[2] = LittleFloat( v->weights[k].offset[2] );
|
||||
}
|
||||
// FIXME
|
||||
// This makes TFC's skeletons work. Shouldn't be necessary anymore, but left
|
||||
// in for reference.
|
||||
//v = (md4Vertex_t *)( ( byte * )&v->weights[v->numWeights] + 12 );
|
||||
v = (md4Vertex_t *)( ( byte * )&v->weights[v->numWeights]);
|
||||
}
|
||||
|
||||
// find the next surface
|
||||
surf = (md4Surface_t *)( (byte *)surf + surf->ofsEnd );
|
||||
}
|
||||
|
||||
// find the next LOD
|
||||
lod = (md4LOD_t *)( (byte *)lod + lod->ofsEnd );
|
||||
}
|
||||
|
||||
return qtrue;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//=============================================================================
|
||||
|
@ -1311,11 +1146,6 @@ void RE_BeginRegistration( glconfig_t *glconfigOut ) {
|
|||
RE_ClearScene();
|
||||
|
||||
tr.registered = qtrue;
|
||||
|
||||
// NOTE: this sucks, for some reason the first stretch pic is never drawn
|
||||
// without this we'd see a white flash on a level load because the very
|
||||
// first time the level shot would not be drawn
|
||||
// RE_StretchPic(0, 0, 0, 0, 0, 0, 1, 1, 0);
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
|
@ -1528,17 +1358,6 @@ void R_ModelBounds( qhandle_t handle, vec3_t mins, vec3_t maxs ) {
|
|||
VectorCopy( frame->bounds[0], mins );
|
||||
VectorCopy( frame->bounds[1], maxs );
|
||||
|
||||
return;
|
||||
} else if (model->type == MOD_MD4) {
|
||||
md4Header_t *header;
|
||||
md4Frame_t *frame;
|
||||
|
||||
header = (md4Header_t *)model->modelData;
|
||||
frame = (md4Frame_t *) ((byte *)header + header->ofsFrames);
|
||||
|
||||
VectorCopy( frame->bounds[0], mins );
|
||||
VectorCopy( frame->bounds[1], maxs );
|
||||
|
||||
return;
|
||||
} else if (model->type == MOD_MDR) {
|
||||
mdrHeader_t *header;
|
||||
|
|
|
@ -25,6 +25,13 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|||
|
||||
#define LL(x) x=LittleLong(x)
|
||||
|
||||
// 3x4 identity matrix
|
||||
static float identityMatrix[12] = {
|
||||
1, 0, 0, 0,
|
||||
0, 1, 0, 0,
|
||||
0, 0, 1, 0
|
||||
};
|
||||
|
||||
static qboolean IQM_CheckRange( iqmHeader_t *header, int offset,
|
||||
int count,int size ) {
|
||||
// return true if the range specified by offset, count and size
|
||||
|
@ -143,6 +150,7 @@ qboolean R_LoadIQM( model_t *mod, void *buffer, int filesize, const char *mod_na
|
|||
iqmData_t *iqmData;
|
||||
srfIQModel_t *surface;
|
||||
char meshName[MAX_QPATH];
|
||||
byte blendIndexesType, blendWeightsType;
|
||||
|
||||
if( filesize < sizeof(iqmHeader_t) ) {
|
||||
return qfalse;
|
||||
|
@ -198,6 +206,8 @@ qboolean R_LoadIQM( model_t *mod, void *buffer, int filesize, const char *mod_na
|
|||
return qfalse;
|
||||
}
|
||||
|
||||
blendIndexesType = blendWeightsType = IQM_UBYTE;
|
||||
|
||||
// check and swap vertex arrays
|
||||
if( IQM_CheckRange( header, header->ofs_vertexarrays,
|
||||
header->num_vertexarrays,
|
||||
|
@ -264,11 +274,20 @@ qboolean R_LoadIQM( model_t *mod, void *buffer, int filesize, const char *mod_na
|
|||
}
|
||||
break;
|
||||
case IQM_BLENDINDEXES:
|
||||
if( (vertexarray->format != IQM_INT &&
|
||||
vertexarray->format != IQM_UBYTE) ||
|
||||
vertexarray->size != 4 ) {
|
||||
return qfalse;
|
||||
}
|
||||
blendIndexesType = vertexarray->format;
|
||||
break;
|
||||
case IQM_BLENDWEIGHTS:
|
||||
if( vertexarray->format != IQM_UBYTE ||
|
||||
if( (vertexarray->format != IQM_FLOAT &&
|
||||
vertexarray->format != IQM_UBYTE) ||
|
||||
vertexarray->size != 4 ) {
|
||||
return qfalse;
|
||||
}
|
||||
blendWeightsType = vertexarray->format;
|
||||
break;
|
||||
case IQM_COLOR:
|
||||
if( vertexarray->format != IQM_UBYTE ||
|
||||
|
@ -343,7 +362,9 @@ qboolean R_LoadIQM( model_t *mod, void *buffer, int filesize, const char *mod_na
|
|||
}
|
||||
}
|
||||
|
||||
if( header->num_poses != header->num_joints ) {
|
||||
if( header->num_poses != header->num_joints && header->num_poses != 0 ) {
|
||||
ri.Printf(PRINT_WARNING, "R_LoadIQM: %s has %d poses and %d joints, must have the same number or 0 poses\n",
|
||||
mod_name, header->num_poses, header->num_joints );
|
||||
return qfalse;
|
||||
}
|
||||
|
||||
|
@ -379,7 +400,10 @@ qboolean R_LoadIQM( model_t *mod, void *buffer, int filesize, const char *mod_na
|
|||
joint_names += strlen( (char *)header + header->ofs_text +
|
||||
joint->name ) + 1;
|
||||
}
|
||||
}
|
||||
|
||||
if ( header->num_poses )
|
||||
{
|
||||
// check and swap poses
|
||||
if( IQM_CheckRange( header, header->ofs_poses,
|
||||
header->num_poses, sizeof(iqmPose_t) ) ) {
|
||||
|
@ -438,7 +462,7 @@ qboolean R_LoadIQM( model_t *mod, void *buffer, int filesize, const char *mod_na
|
|||
size = sizeof(iqmData_t);
|
||||
size += header->num_meshes * sizeof( srfIQModel_t );
|
||||
size += header->num_joints * 12 * sizeof( float ); // joint mats
|
||||
size += header->num_joints * header->num_frames * 12 * sizeof( float ); // pose mats
|
||||
size += header->num_poses * header->num_frames * 12 * sizeof( float ); // pose mats
|
||||
if(header->ofs_bounds)
|
||||
size += header->num_frames * 6 * sizeof(float); // model bounds
|
||||
size += header->num_vertexes * 3 * sizeof(float); // positions
|
||||
|
@ -446,12 +470,18 @@ qboolean R_LoadIQM( model_t *mod, void *buffer, int filesize, const char *mod_na
|
|||
size += header->num_vertexes * 3 * sizeof(float); // normals
|
||||
size += header->num_vertexes * 4 * sizeof(float); // tangents
|
||||
size += header->num_vertexes * 4 * sizeof(byte); // blendIndexes
|
||||
size += header->num_vertexes * 4 * sizeof(byte); // blendWeights
|
||||
size += header->num_vertexes * 4 * sizeof(byte); // colors
|
||||
size += header->num_joints * sizeof(int); // parents
|
||||
size += header->num_triangles * 3 * sizeof(int); // triangles
|
||||
size += joint_names; // joint names
|
||||
|
||||
// blendWeights
|
||||
if (blendWeightsType == IQM_FLOAT) {
|
||||
size += header->num_vertexes * 4 * sizeof(float);
|
||||
} else {
|
||||
size += header->num_vertexes * 4 * sizeof(byte);
|
||||
}
|
||||
|
||||
mod->type = MOD_IQM;
|
||||
iqmData = (iqmData_t *)ri.Hunk_Alloc( size, h_low );
|
||||
mod->modelData = iqmData;
|
||||
|
@ -462,28 +492,40 @@ qboolean R_LoadIQM( model_t *mod, void *buffer, int filesize, const char *mod_na
|
|||
iqmData->num_frames = header->num_frames;
|
||||
iqmData->num_surfaces = header->num_meshes;
|
||||
iqmData->num_joints = header->num_joints;
|
||||
iqmData->num_poses = header->num_poses;
|
||||
iqmData->blendWeightsType = blendWeightsType;
|
||||
iqmData->surfaces = (srfIQModel_t *)(iqmData + 1);
|
||||
iqmData->jointMats = (float *) (iqmData->surfaces + iqmData->num_surfaces);
|
||||
iqmData->poseMats = iqmData->jointMats + 12 * header->num_joints;
|
||||
if(header->ofs_bounds)
|
||||
{
|
||||
iqmData->bounds = iqmData->poseMats + 12 * header->num_joints * header->num_frames;
|
||||
iqmData->bounds = iqmData->poseMats + 12 * header->num_poses * header->num_frames;
|
||||
iqmData->positions = iqmData->bounds + 6 * header->num_frames;
|
||||
}
|
||||
else
|
||||
iqmData->positions = iqmData->poseMats + 12 * header->num_joints * header->num_frames;
|
||||
iqmData->positions = iqmData->poseMats + 12 * header->num_poses * header->num_frames;
|
||||
iqmData->texcoords = iqmData->positions + 3 * header->num_vertexes;
|
||||
iqmData->normals = iqmData->texcoords + 2 * header->num_vertexes;
|
||||
iqmData->tangents = iqmData->normals + 3 * header->num_vertexes;
|
||||
iqmData->blendIndexes = (byte *)(iqmData->tangents + 4 * header->num_vertexes);
|
||||
iqmData->blendWeights = iqmData->blendIndexes + 4 * header->num_vertexes;
|
||||
iqmData->colors = iqmData->blendWeights + 4 * header->num_vertexes;
|
||||
|
||||
if(blendWeightsType == IQM_FLOAT) {
|
||||
iqmData->blendWeights.f = (float *)(iqmData->blendIndexes + 4 * header->num_vertexes);
|
||||
iqmData->colors = (byte *)(iqmData->blendWeights.f + 4 * header->num_vertexes);
|
||||
} else {
|
||||
iqmData->blendWeights.b = iqmData->blendIndexes + 4 * header->num_vertexes;
|
||||
iqmData->colors = iqmData->blendWeights.b + 4 * header->num_vertexes;
|
||||
}
|
||||
|
||||
iqmData->jointParents = (int *)(iqmData->colors + 4 * header->num_vertexes);
|
||||
iqmData->triangles = iqmData->jointParents + header->num_joints;
|
||||
iqmData->names = (char *)(iqmData->triangles + 3 * header->num_triangles);
|
||||
|
||||
if ( header->num_joints == 0 )
|
||||
iqmData->jointMats = iqmData->poseMats = NULL;
|
||||
iqmData->jointMats = NULL;
|
||||
|
||||
if ( header->num_poses == 0 )
|
||||
iqmData->poseMats = NULL;
|
||||
|
||||
// calculate joint matrices and their inverses
|
||||
// joint inverses are needed only until the pose matrices are calculated
|
||||
|
@ -620,14 +662,27 @@ qboolean R_LoadIQM( model_t *mod, void *buffer, int filesize, const char *mod_na
|
|||
n * sizeof(float) );
|
||||
break;
|
||||
case IQM_BLENDINDEXES:
|
||||
Com_Memcpy( iqmData->blendIndexes,
|
||||
(byte *)header + vertexarray->offset,
|
||||
n * sizeof(byte) );
|
||||
if( blendIndexesType == IQM_INT ) {
|
||||
int *data = (int*)((byte*)header + vertexarray->offset);
|
||||
for ( j = 0; j < n; j++ ) {
|
||||
iqmData->blendIndexes[j] = (byte)data[j];
|
||||
}
|
||||
} else {
|
||||
Com_Memcpy( iqmData->blendIndexes,
|
||||
(byte *)header + vertexarray->offset,
|
||||
n * sizeof(byte) );
|
||||
}
|
||||
break;
|
||||
case IQM_BLENDWEIGHTS:
|
||||
Com_Memcpy( iqmData->blendWeights,
|
||||
(byte *)header + vertexarray->offset,
|
||||
n * sizeof(byte) );
|
||||
if( blendWeightsType == IQM_FLOAT ) {
|
||||
Com_Memcpy( iqmData->blendWeights.f,
|
||||
(byte *)header + vertexarray->offset,
|
||||
n * sizeof(float) );
|
||||
} else {
|
||||
Com_Memcpy( iqmData->blendWeights.b,
|
||||
(byte *)header + vertexarray->offset,
|
||||
n * sizeof(byte) );
|
||||
}
|
||||
break;
|
||||
case IQM_COLOR:
|
||||
Com_Memcpy( iqmData->colors,
|
||||
|
@ -895,9 +950,21 @@ static void ComputePoseMats( iqmData_t *data, int frame, int oldframe,
|
|||
int *joint = data->jointParents;
|
||||
int i;
|
||||
|
||||
if ( oldframe == frame ) {
|
||||
mat1 = data->poseMats + 12 * data->num_joints * frame;
|
||||
if ( data->num_poses == 0 ) {
|
||||
for( i = 0; i < data->num_joints; i++, joint++ ) {
|
||||
if( *joint >= 0 ) {
|
||||
Matrix34Multiply( mat + 12 * *joint,
|
||||
identityMatrix, mat + 12*i );
|
||||
} else {
|
||||
Com_Memcpy( mat + 12*i, identityMatrix, 12 * sizeof(float) );
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if ( oldframe == frame ) {
|
||||
mat1 = data->poseMats + 12 * data->num_poses * frame;
|
||||
for( i = 0; i < data->num_poses; i++, joint++ ) {
|
||||
if( *joint >= 0 ) {
|
||||
Matrix34Multiply( mat + 12 * *joint,
|
||||
mat1 + 12*i, mat + 12*i );
|
||||
|
@ -906,10 +973,10 @@ static void ComputePoseMats( iqmData_t *data, int frame, int oldframe,
|
|||
}
|
||||
}
|
||||
} else {
|
||||
mat1 = data->poseMats + 12 * data->num_joints * frame;
|
||||
mat2 = data->poseMats + 12 * data->num_joints * oldframe;
|
||||
mat1 = data->poseMats + 12 * data->num_poses * frame;
|
||||
mat2 = data->poseMats + 12 * data->num_poses * oldframe;
|
||||
|
||||
for( i = 0; i < data->num_joints; i++, joint++ ) {
|
||||
for( i = 0; i < data->num_poses; i++, joint++ ) {
|
||||
if( *joint >= 0 ) {
|
||||
float tmpMat[12];
|
||||
InterpolateMatrix( mat1 + 12*i, mat2 + 12*i,
|
||||
|
@ -957,7 +1024,10 @@ void RB_IQMSurfaceAnim( surfaceType_t *surface ) {
|
|||
int i;
|
||||
|
||||
vec4_t *outXYZ;
|
||||
vec4_t *outNormal;
|
||||
uint32_t *outNormal;
|
||||
#ifdef USE_VERT_TANGENT_SPACE
|
||||
uint32_t *outTangent;
|
||||
#endif
|
||||
vec2_t (*outTexCoord)[2];
|
||||
vec4_t *outColor;
|
||||
|
||||
|
@ -973,11 +1043,14 @@ void RB_IQMSurfaceAnim( surfaceType_t *surface ) {
|
|||
|
||||
outXYZ = &tess.xyz[tess.numVertexes];
|
||||
outNormal = &tess.normal[tess.numVertexes];
|
||||
#ifdef USE_VERT_TANGENT_SPACE
|
||||
outTangent = &tess.tangent[tess.numVertexes];
|
||||
#endif
|
||||
outTexCoord = &tess.texCoords[tess.numVertexes];
|
||||
outColor = &tess.vertexColors[tess.numVertexes];
|
||||
|
||||
// compute interpolated joint matrices
|
||||
if ( data->num_joints > 0 ) {
|
||||
if ( data->num_poses > 0 ) {
|
||||
ComputePoseMats( data, frame, oldframe, backlerp, jointMats );
|
||||
}
|
||||
|
||||
|
@ -988,28 +1061,31 @@ void RB_IQMSurfaceAnim( surfaceType_t *surface ) {
|
|||
float vtxMat[12];
|
||||
float nrmMat[9];
|
||||
int vtx = i + surf->first_vertex;
|
||||
float blendWeights[4];
|
||||
int numWeights;
|
||||
|
||||
if ( data->num_joints == 0 || data->blendWeights[4*vtx] <= 0 ) {
|
||||
for ( numWeights = 0; numWeights < 4; numWeights++ ) {
|
||||
if ( data->blendWeightsType == IQM_FLOAT )
|
||||
blendWeights[numWeights] = data->blendWeights.f[4*vtx + numWeights];
|
||||
else
|
||||
blendWeights[numWeights] = (float)data->blendWeights.b[4*vtx + numWeights] / 255.0f;
|
||||
|
||||
if ( blendWeights[numWeights] <= 0 )
|
||||
break;
|
||||
}
|
||||
|
||||
if ( data->num_poses == 0 || numWeights == 0 ) {
|
||||
// no blend joint, use identity matrix.
|
||||
for( j = 0; j < 3; j++ ) {
|
||||
for( k = 0; k < 4; k++ )
|
||||
vtxMat[4*j+k] = ( k == j ) ? 1 : 0;
|
||||
}
|
||||
Com_Memcpy( vtxMat, identityMatrix, 12 * sizeof (float) );
|
||||
} else {
|
||||
// compute the vertex matrix by blending the up to
|
||||
// four blend weights
|
||||
for( k = 0; k < 12; k++ )
|
||||
vtxMat[k] = data->blendWeights[4*vtx]
|
||||
* jointMats[12*data->blendIndexes[4*vtx] + k];
|
||||
for( j = 1; j < 4; j++ ) {
|
||||
if( data->blendWeights[4*vtx + j] <= 0 )
|
||||
break;
|
||||
for( k = 0; k < 12; k++ )
|
||||
vtxMat[k] += data->blendWeights[4*vtx + j]
|
||||
* jointMats[12*data->blendIndexes[4*vtx + j] + k];
|
||||
Com_Memset( vtxMat, 0, 12 * sizeof (float) );
|
||||
for( j = 0; j < numWeights; j++ ) {
|
||||
for( k = 0; k < 12; k++ ) {
|
||||
vtxMat[k] += blendWeights[j] * jointMats[12*data->blendIndexes[4*vtx + j] + k];
|
||||
}
|
||||
}
|
||||
for( k = 0; k < 12; k++ )
|
||||
vtxMat[k] *= 1.0f / 255.0f;
|
||||
}
|
||||
|
||||
// compute the normal matrix as transpose of the adjoint
|
||||
|
@ -1046,19 +1122,25 @@ void RB_IQMSurfaceAnim( surfaceType_t *surface ) {
|
|||
vtxMat[11];
|
||||
(*outXYZ)[3] = 1.0f;
|
||||
|
||||
(*outNormal)[0] =
|
||||
nrmMat[ 0] * data->normals[3*vtx+0] +
|
||||
nrmMat[ 1] * data->normals[3*vtx+1] +
|
||||
nrmMat[ 2] * data->normals[3*vtx+2];
|
||||
(*outNormal)[1] =
|
||||
nrmMat[ 3] * data->normals[3*vtx+0] +
|
||||
nrmMat[ 4] * data->normals[3*vtx+1] +
|
||||
nrmMat[ 5] * data->normals[3*vtx+2];
|
||||
(*outNormal)[2] =
|
||||
nrmMat[ 6] * data->normals[3*vtx+0] +
|
||||
nrmMat[ 7] * data->normals[3*vtx+1] +
|
||||
nrmMat[ 8] * data->normals[3*vtx+2];
|
||||
(*outNormal)[3] = 0.0f;
|
||||
{
|
||||
vec3_t normal;
|
||||
vec4_t tangent;
|
||||
|
||||
normal[0] = DotProduct(&nrmMat[0], &data->normals[3*vtx]);
|
||||
normal[1] = DotProduct(&nrmMat[3], &data->normals[3*vtx]);
|
||||
normal[2] = DotProduct(&nrmMat[6], &data->normals[3*vtx]);
|
||||
|
||||
*outNormal = R_VboPackNormal(normal);
|
||||
|
||||
#ifdef USE_VERT_TANGENT_SPACE
|
||||
tangent[0] = DotProduct(&nrmMat[0], &data->tangents[4*vtx]);
|
||||
tangent[1] = DotProduct(&nrmMat[3], &data->tangents[4*vtx]);
|
||||
tangent[2] = DotProduct(&nrmMat[6], &data->tangents[4*vtx]);
|
||||
tangent[3] = data->tangents[4*vtx+3];
|
||||
|
||||
*outTangent++ = R_VboPackTangent(tangent);
|
||||
#endif
|
||||
}
|
||||
|
||||
(*outColor)[0] = data->colors[4*vtx+0] / 255.0f;
|
||||
(*outColor)[1] = data->colors[4*vtx+1] / 255.0f;
|
||||
|
|
|
@ -22,9 +22,9 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|||
|
||||
#include "tr_local.h"
|
||||
|
||||
void RB_ToneMap(FBO_t *hdrFbo, vec4i_t hdrBox, FBO_t *ldrFbo, vec4i_t ldrBox, int autoExposure)
|
||||
void RB_ToneMap(FBO_t *hdrFbo, ivec4_t hdrBox, FBO_t *ldrFbo, ivec4_t ldrBox, int autoExposure)
|
||||
{
|
||||
vec4i_t srcBox, dstBox;
|
||||
ivec4_t srcBox, dstBox;
|
||||
vec4_t color;
|
||||
static int lastFrameCount = 0;
|
||||
|
||||
|
@ -103,9 +103,9 @@ Blurs a part of one framebuffer to another.
|
|||
Framebuffers can be identical.
|
||||
=============
|
||||
*/
|
||||
void RB_BokehBlur(FBO_t *src, vec4i_t srcBox, FBO_t *dst, vec4i_t dstBox, float blur)
|
||||
void RB_BokehBlur(FBO_t *src, ivec4_t srcBox, FBO_t *dst, ivec4_t dstBox, float blur)
|
||||
{
|
||||
// vec4i_t srcBox, dstBox;
|
||||
// ivec4_t srcBox, dstBox;
|
||||
vec4_t color;
|
||||
|
||||
blur *= 10.0f;
|
||||
|
@ -118,7 +118,7 @@ void RB_BokehBlur(FBO_t *src, vec4i_t srcBox, FBO_t *dst, vec4i_t dstBox, float
|
|||
// bokeh blur
|
||||
if (blur > 0.0f)
|
||||
{
|
||||
vec4i_t quarterBox;
|
||||
ivec4_t quarterBox;
|
||||
|
||||
quarterBox[0] = 0;
|
||||
quarterBox[1] = tr.quarterFbo[0]->height;
|
||||
|
@ -226,7 +226,7 @@ void RB_BokehBlur(FBO_t *src, vec4i_t srcBox, FBO_t *dst, vec4i_t dstBox, float
|
|||
|
||||
static void RB_RadialBlur(FBO_t *srcFbo, FBO_t *dstFbo, int passes, float stretch, float x, float y, float w, float h, float xcenter, float ycenter, float alpha)
|
||||
{
|
||||
vec4i_t srcBox, dstBox;
|
||||
ivec4_t srcBox, dstBox;
|
||||
vec4_t color;
|
||||
const float inc = 1.f / passes;
|
||||
const float mul = powf(stretch, inc);
|
||||
|
@ -255,10 +255,20 @@ static void RB_RadialBlur(FBO_t *srcFbo, FBO_t *dstFbo, int passes, float stretc
|
|||
float s1 = iscale + s0;
|
||||
float t1 = iscale + t0;
|
||||
|
||||
srcBox[0] = s0 * srcFbo->width;
|
||||
srcBox[1] = t0 * srcFbo->height;
|
||||
srcBox[2] = (s1 - s0) * srcFbo->width;
|
||||
srcBox[3] = (t1 - t0) * srcFbo->height;
|
||||
if (srcFbo)
|
||||
{
|
||||
srcBox[0] = s0 * srcFbo->width;
|
||||
srcBox[1] = t0 * srcFbo->height;
|
||||
srcBox[2] = (s1 - s0) * srcFbo->width;
|
||||
srcBox[3] = (t1 - t0) * srcFbo->height;
|
||||
}
|
||||
else
|
||||
{
|
||||
srcBox[0] = s0 * glConfig.vidWidth;
|
||||
srcBox[1] = t0 * glConfig.vidHeight;
|
||||
srcBox[2] = (s1 - s0) * glConfig.vidWidth;
|
||||
srcBox[3] = (t1 - t0) * glConfig.vidHeight;
|
||||
}
|
||||
|
||||
FBO_Blit(srcFbo, srcBox, texScale, dstFbo, dstBox, &tr.textureColorShader, color, GLS_SRCBLEND_ONE | GLS_DSTBLEND_ONE );
|
||||
|
||||
|
@ -298,7 +308,7 @@ static qboolean RB_UpdateSunFlareVis(void)
|
|||
return sampleCount > 0;
|
||||
}
|
||||
|
||||
void RB_SunRays(FBO_t *srcFbo, vec4i_t srcBox, FBO_t *dstFbo, vec4i_t dstBox)
|
||||
void RB_SunRays(FBO_t *srcFbo, ivec4_t srcBox, FBO_t *dstFbo, ivec4_t dstBox)
|
||||
{
|
||||
vec4_t color;
|
||||
float dot;
|
||||
|
@ -306,7 +316,7 @@ void RB_SunRays(FBO_t *srcFbo, vec4i_t srcBox, FBO_t *dstFbo, vec4i_t dstBox)
|
|||
qboolean colorize = qtrue;
|
||||
|
||||
// float w, h, w2, h2;
|
||||
matrix_t mvp;
|
||||
mat4_t mvp;
|
||||
vec4_t pos, hpos;
|
||||
|
||||
dot = DotProduct(tr.sunDirection, backEnd.viewParms.or.axis[0]);
|
||||
|
@ -319,11 +329,11 @@ void RB_SunRays(FBO_t *srcFbo, vec4i_t srcBox, FBO_t *dstFbo, vec4i_t dstBox)
|
|||
// From RB_DrawSun()
|
||||
{
|
||||
float dist;
|
||||
matrix_t trans, model, mvp;
|
||||
mat4_t trans, model, mvp;
|
||||
|
||||
Matrix16Translation( backEnd.viewParms.or.origin, trans );
|
||||
Matrix16Multiply( backEnd.viewParms.world.modelMatrix, trans, model );
|
||||
Matrix16Multiply(backEnd.viewParms.projectionMatrix, model, mvp);
|
||||
Mat4Translation( backEnd.viewParms.or.origin, trans );
|
||||
Mat4Multiply( backEnd.viewParms.world.modelMatrix, trans, model );
|
||||
Mat4Multiply(backEnd.viewParms.projectionMatrix, model, mvp);
|
||||
|
||||
dist = backEnd.viewParms.zFar / 1.75; // div sqrt(3)
|
||||
|
||||
|
@ -331,8 +341,8 @@ void RB_SunRays(FBO_t *srcFbo, vec4i_t srcBox, FBO_t *dstFbo, vec4i_t dstBox)
|
|||
}
|
||||
|
||||
// project sun point
|
||||
//Matrix16Multiply(backEnd.viewParms.projectionMatrix, backEnd.viewParms.world.modelMatrix, mvp);
|
||||
Matrix16Transform(mvp, pos, hpos);
|
||||
//Mat4Multiply(backEnd.viewParms.projectionMatrix, backEnd.viewParms.world.modelMatrix, mvp);
|
||||
Mat4Transform(mvp, pos, hpos);
|
||||
|
||||
// transform to UV coords
|
||||
hpos[3] = 0.5f / hpos[3];
|
||||
|
@ -344,17 +354,27 @@ void RB_SunRays(FBO_t *srcFbo, vec4i_t srcBox, FBO_t *dstFbo, vec4i_t dstBox)
|
|||
{
|
||||
float mul = 1.f;
|
||||
vec2_t texScale;
|
||||
vec4i_t rayBox, quarterBox;
|
||||
ivec4_t rayBox, quarterBox;
|
||||
|
||||
texScale[0] =
|
||||
texScale[1] = 1.0f;
|
||||
|
||||
VectorSet4(color, mul, mul, mul, 1);
|
||||
|
||||
rayBox[0] = srcBox[0] * tr.sunRaysFbo->width / srcFbo->width;
|
||||
rayBox[1] = srcBox[1] * tr.sunRaysFbo->height / srcFbo->height;
|
||||
rayBox[2] = srcBox[2] * tr.sunRaysFbo->width / srcFbo->width;
|
||||
rayBox[3] = srcBox[3] * tr.sunRaysFbo->height / srcFbo->height;
|
||||
if (srcFbo)
|
||||
{
|
||||
rayBox[0] = srcBox[0] * tr.sunRaysFbo->width / srcFbo->width;
|
||||
rayBox[1] = srcBox[1] * tr.sunRaysFbo->height / srcFbo->height;
|
||||
rayBox[2] = srcBox[2] * tr.sunRaysFbo->width / srcFbo->width;
|
||||
rayBox[3] = srcBox[3] * tr.sunRaysFbo->height / srcFbo->height;
|
||||
}
|
||||
else
|
||||
{
|
||||
rayBox[0] = srcBox[0] * tr.sunRaysFbo->width / glConfig.vidWidth;
|
||||
rayBox[1] = srcBox[1] * tr.sunRaysFbo->height / glConfig.vidHeight;
|
||||
rayBox[2] = srcBox[2] * tr.sunRaysFbo->width / glConfig.vidWidth;
|
||||
rayBox[3] = srcBox[3] * tr.sunRaysFbo->height / glConfig.vidHeight;
|
||||
}
|
||||
|
||||
quarterBox[0] = 0;
|
||||
quarterBox[1] = tr.quarterFbo[0]->height;
|
||||
|
@ -421,7 +441,7 @@ static void RB_BlurAxis(FBO_t *srcFbo, FBO_t *dstFbo, float strength, qboolean h
|
|||
ymul *= strength;
|
||||
|
||||
{
|
||||
vec4i_t srcBox, dstBox;
|
||||
ivec4_t srcBox, dstBox;
|
||||
vec4_t color;
|
||||
vec2_t texScale;
|
||||
|
||||
|
@ -470,7 +490,7 @@ void RB_GaussianBlur(float blur)
|
|||
return;
|
||||
|
||||
{
|
||||
vec4i_t srcBox, dstBox;
|
||||
ivec4_t srcBox, dstBox;
|
||||
vec4_t color;
|
||||
vec2_t texScale;
|
||||
|
||||
|
@ -480,7 +500,7 @@ void RB_GaussianBlur(float blur)
|
|||
VectorSet4(color, 1, 1, 1, 1);
|
||||
|
||||
// first, downsample the framebuffer
|
||||
FBO_FastBlit(tr.screenScratchFbo, NULL, tr.quarterFbo[0], NULL, GL_COLOR_BUFFER_BIT, GL_LINEAR);
|
||||
FBO_FastBlit(NULL, NULL, tr.quarterFbo[0], NULL, GL_COLOR_BUFFER_BIT, GL_LINEAR);
|
||||
FBO_FastBlit(tr.quarterFbo[0], NULL, tr.textureScratchFbo[0], NULL, GL_COLOR_BUFFER_BIT, GL_LINEAR);
|
||||
|
||||
// set the alpha channel
|
||||
|
@ -498,6 +518,6 @@ void RB_GaussianBlur(float blur)
|
|||
VectorSet4(srcBox, 0, 0, tr.textureScratchFbo[0]->width, tr.textureScratchFbo[0]->height);
|
||||
VectorSet4(dstBox, 0, 0, glConfig.vidWidth, glConfig.vidHeight);
|
||||
color[3] = factor;
|
||||
FBO_Blit(tr.textureScratchFbo[0], srcBox, texScale, tr.screenScratchFbo, dstBox, &tr.textureColorShader, color, GLS_SRCBLEND_SRC_ALPHA | GLS_DSTBLEND_ONE_MINUS_SRC_ALPHA);
|
||||
FBO_Blit(tr.textureScratchFbo[0], srcBox, texScale, NULL, dstBox, &tr.textureColorShader, color, GLS_SRCBLEND_SRC_ALPHA | GLS_DSTBLEND_ONE_MINUS_SRC_ALPHA);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -25,9 +25,9 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|||
|
||||
#include "tr_fbo.h"
|
||||
|
||||
void RB_ToneMap(FBO_t *hdrFbo, vec4i_t hdrBox, FBO_t *ldrFbo, vec4i_t ldrBox, int autoExposure);
|
||||
void RB_BokehBlur(FBO_t *src, vec4i_t srcBox, FBO_t *dst, vec4i_t dstBox, float blur);
|
||||
void RB_SunRays(FBO_t *srcFbo, vec4i_t srcBox, FBO_t *dstFbo, vec4i_t dstBox);
|
||||
void RB_ToneMap(FBO_t *hdrFbo, ivec4_t hdrBox, FBO_t *ldrFbo, ivec4_t ldrBox, int autoExposure);
|
||||
void RB_BokehBlur(FBO_t *src, ivec4_t srcBox, FBO_t *dst, ivec4_t dstBox, float blur);
|
||||
void RB_SunRays(FBO_t *srcFbo, ivec4_t srcBox, FBO_t *dstFbo, ivec4_t dstBox);
|
||||
void RB_GaussianBlur(float blur);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -496,7 +496,7 @@ void RE_RenderScene( const refdef_t *fd ) {
|
|||
}
|
||||
|
||||
// playing with even more shadows
|
||||
if(glRefConfig.framebufferObject && !( fd->rdflags & RDF_NOWORLDMODEL ) && (r_forceSun->integer || tr.sunShadows))
|
||||
if(glRefConfig.framebufferObject && r_sunlightMode->integer && !( fd->rdflags & RDF_NOWORLDMODEL ) && (r_forceSun->integer || tr.sunShadows))
|
||||
{
|
||||
R_RenderSunShadowMaps(fd, 0);
|
||||
R_RenderSunShadowMaps(fd, 1);
|
||||
|
|
|
@ -44,9 +44,9 @@ R_DrawElements
|
|||
void R_DrawElementsVBO( int numIndexes, glIndex_t firstIndex, glIndex_t minIndex, glIndex_t maxIndex )
|
||||
{
|
||||
if (glRefConfig.drawRangeElements)
|
||||
qglDrawRangeElementsEXT(GL_TRIANGLES, minIndex, maxIndex, numIndexes, GL_INDEX_TYPE, BUFFER_OFFSET(firstIndex * sizeof(GL_INDEX_TYPE)));
|
||||
qglDrawRangeElementsEXT(GL_TRIANGLES, minIndex, maxIndex, numIndexes, GL_INDEX_TYPE, BUFFER_OFFSET(firstIndex * sizeof(glIndex_t)));
|
||||
else
|
||||
qglDrawElements(GL_TRIANGLES, numIndexes, GL_INDEX_TYPE, BUFFER_OFFSET(firstIndex * sizeof(GL_INDEX_TYPE)));
|
||||
qglDrawElements(GL_TRIANGLES, numIndexes, GL_INDEX_TYPE, BUFFER_OFFSET(firstIndex * sizeof(glIndex_t)));
|
||||
|
||||
}
|
||||
|
||||
|
@ -148,7 +148,7 @@ static void DrawTris (shaderCommands_t *input) {
|
|||
GLSL_VertexAttribsState(ATTR_POSITION);
|
||||
GLSL_BindProgram(sp);
|
||||
|
||||
GLSL_SetUniformMatrix16(sp, UNIFORM_MODELVIEWPROJECTIONMATRIX, glState.modelviewProjection);
|
||||
GLSL_SetUniformMat4(sp, UNIFORM_MODELVIEWPROJECTIONMATRIX, glState.modelviewProjection);
|
||||
VectorSet4(color, 1, 1, 1, 1);
|
||||
GLSL_SetUniformVec4(sp, UNIFORM_COLOR, color);
|
||||
|
||||
|
@ -221,14 +221,22 @@ extern float EvalWaveForm( const waveForm_t *wf );
|
|||
extern float EvalWaveFormClamped( const waveForm_t *wf );
|
||||
|
||||
|
||||
static void ComputeTexMatrix( shaderStage_t *pStage, int bundleNum, float *outmatrix)
|
||||
static void ComputeTexMods( shaderStage_t *pStage, int bundleNum, float *outMatrix, float *outOffTurb)
|
||||
{
|
||||
int tm;
|
||||
float matrix[16], currentmatrix[16];
|
||||
float matrix[6], currentmatrix[6];
|
||||
textureBundle_t *bundle = &pStage->bundle[bundleNum];
|
||||
|
||||
Matrix16Identity(outmatrix);
|
||||
Matrix16Identity(currentmatrix);
|
||||
matrix[0] = 1.0f; matrix[2] = 0.0f; matrix[4] = 0.0f;
|
||||
matrix[1] = 0.0f; matrix[3] = 1.0f; matrix[5] = 0.0f;
|
||||
|
||||
currentmatrix[0] = 1.0f; currentmatrix[2] = 0.0f; currentmatrix[4] = 0.0f;
|
||||
currentmatrix[1] = 0.0f; currentmatrix[3] = 1.0f; currentmatrix[5] = 0.0f;
|
||||
|
||||
outMatrix[0] = 1.0f; outMatrix[2] = 0.0f;
|
||||
outMatrix[1] = 0.0f; outMatrix[3] = 1.0f;
|
||||
|
||||
outOffTurb[0] = 0.0f; outOffTurb[1] = 0.0f; outOffTurb[2] = 0.0f; outOffTurb[3] = 0.0f;
|
||||
|
||||
for ( tm = 0; tm < bundle->numTexMods ; tm++ ) {
|
||||
switch ( bundle->texMods[tm].type )
|
||||
|
@ -239,59 +247,73 @@ static void ComputeTexMatrix( shaderStage_t *pStage, int bundleNum, float *outma
|
|||
break;
|
||||
|
||||
case TMOD_TURBULENT:
|
||||
RB_CalcTurbulentTexMatrix( &bundle->texMods[tm].wave,
|
||||
matrix );
|
||||
outmatrix[12] = matrix[12];
|
||||
outmatrix[13] = matrix[13];
|
||||
Matrix16Copy(outmatrix, currentmatrix);
|
||||
RB_CalcTurbulentFactors(&bundle->texMods[tm].wave, &outOffTurb[2], &outOffTurb[3]);
|
||||
break;
|
||||
|
||||
case TMOD_ENTITY_TRANSLATE:
|
||||
RB_CalcScrollTexMatrix( backEnd.currentEntity->e.shaderTexCoord,
|
||||
matrix );
|
||||
Matrix16Multiply(matrix, currentmatrix, outmatrix);
|
||||
Matrix16Copy(outmatrix, currentmatrix);
|
||||
RB_CalcScrollTexMatrix( backEnd.currentEntity->e.shaderTexCoord, matrix );
|
||||
break;
|
||||
|
||||
case TMOD_SCROLL:
|
||||
RB_CalcScrollTexMatrix( bundle->texMods[tm].scroll,
|
||||
matrix );
|
||||
Matrix16Multiply(matrix, currentmatrix, outmatrix);
|
||||
Matrix16Copy(outmatrix, currentmatrix);
|
||||
break;
|
||||
|
||||
case TMOD_SCALE:
|
||||
RB_CalcScaleTexMatrix( bundle->texMods[tm].scale,
|
||||
matrix );
|
||||
Matrix16Multiply(matrix, currentmatrix, outmatrix);
|
||||
Matrix16Copy(outmatrix, currentmatrix);
|
||||
break;
|
||||
|
||||
case TMOD_STRETCH:
|
||||
RB_CalcStretchTexMatrix( &bundle->texMods[tm].wave,
|
||||
matrix );
|
||||
Matrix16Multiply(matrix, currentmatrix, outmatrix);
|
||||
Matrix16Copy(outmatrix, currentmatrix);
|
||||
break;
|
||||
|
||||
case TMOD_TRANSFORM:
|
||||
RB_CalcTransformTexMatrix( &bundle->texMods[tm],
|
||||
matrix );
|
||||
Matrix16Multiply(matrix, currentmatrix, outmatrix);
|
||||
Matrix16Copy(outmatrix, currentmatrix);
|
||||
break;
|
||||
|
||||
case TMOD_ROTATE:
|
||||
RB_CalcRotateTexMatrix( bundle->texMods[tm].rotateSpeed,
|
||||
matrix );
|
||||
Matrix16Multiply(matrix, currentmatrix, outmatrix);
|
||||
Matrix16Copy(outmatrix, currentmatrix);
|
||||
break;
|
||||
|
||||
default:
|
||||
ri.Error( ERR_DROP, "ERROR: unknown texmod '%d' in shader '%s'", bundle->texMods[tm].type, tess.shader->name );
|
||||
break;
|
||||
}
|
||||
|
||||
switch ( bundle->texMods[tm].type )
|
||||
{
|
||||
case TMOD_NONE:
|
||||
case TMOD_TURBULENT:
|
||||
default:
|
||||
break;
|
||||
|
||||
case TMOD_ENTITY_TRANSLATE:
|
||||
case TMOD_SCROLL:
|
||||
case TMOD_SCALE:
|
||||
case TMOD_STRETCH:
|
||||
case TMOD_TRANSFORM:
|
||||
case TMOD_ROTATE:
|
||||
outMatrix[0] = matrix[0] * currentmatrix[0] + matrix[2] * currentmatrix[1];
|
||||
outMatrix[1] = matrix[1] * currentmatrix[0] + matrix[3] * currentmatrix[1];
|
||||
|
||||
outMatrix[2] = matrix[0] * currentmatrix[2] + matrix[2] * currentmatrix[3];
|
||||
outMatrix[3] = matrix[1] * currentmatrix[2] + matrix[3] * currentmatrix[3];
|
||||
|
||||
outOffTurb[0] = matrix[0] * currentmatrix[4] + matrix[2] * currentmatrix[5] + matrix[4];
|
||||
outOffTurb[1] = matrix[1] * currentmatrix[4] + matrix[3] * currentmatrix[5] + matrix[5];
|
||||
|
||||
currentmatrix[0] = outMatrix[0];
|
||||
currentmatrix[1] = outMatrix[1];
|
||||
currentmatrix[2] = outMatrix[2];
|
||||
currentmatrix[3] = outMatrix[3];
|
||||
currentmatrix[4] = outOffTurb[0];
|
||||
currentmatrix[5] = outOffTurb[1];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -370,7 +392,7 @@ static void ProjectDlightTexture( void ) {
|
|||
|
||||
GLSL_BindProgram(sp);
|
||||
|
||||
GLSL_SetUniformMatrix16(sp, UNIFORM_MODELVIEWPROJECTIONMATRIX, glState.modelviewProjection);
|
||||
GLSL_SetUniformMat4(sp, UNIFORM_MODELVIEWPROJECTIONMATRIX, glState.modelviewProjection);
|
||||
|
||||
GLSL_SetUniformFloat(sp, UNIFORM_VERTEXLERP, glState.vertexAttribsInterpolation);
|
||||
|
||||
|
@ -421,46 +443,29 @@ static void ProjectDlightTexture( void ) {
|
|||
}
|
||||
|
||||
|
||||
static void ComputeShaderColors( shaderStage_t *pStage, vec4_t baseColor, vec4_t vertColor )
|
||||
static void ComputeShaderColors( shaderStage_t *pStage, vec4_t baseColor, vec4_t vertColor, int blend )
|
||||
{
|
||||
baseColor[0] =
|
||||
baseColor[1] =
|
||||
baseColor[2] =
|
||||
baseColor[3] = 1.0f;
|
||||
|
||||
vertColor[0] =
|
||||
vertColor[1] =
|
||||
vertColor[2] =
|
||||
vertColor[3] = 0.0f;
|
||||
|
||||
//
|
||||
// rgbGen
|
||||
//
|
||||
switch ( pStage->rgbGen )
|
||||
{
|
||||
case CGEN_IDENTITY:
|
||||
baseColor[0] =
|
||||
baseColor[1] =
|
||||
baseColor[2] =
|
||||
baseColor[3] = 1.0f;
|
||||
|
||||
vertColor[0] =
|
||||
vertColor[1] =
|
||||
vertColor[2] =
|
||||
vertColor[3] = 0.0f;
|
||||
break;
|
||||
case CGEN_IDENTITY_LIGHTING:
|
||||
baseColor[0] =
|
||||
baseColor[1] =
|
||||
baseColor[2] = tr.identityLight;
|
||||
baseColor[3] = 1.0f;
|
||||
|
||||
vertColor[0] =
|
||||
vertColor[1] =
|
||||
vertColor[2] =
|
||||
vertColor[3] = 0.0f;
|
||||
break;
|
||||
case CGEN_EXACT_VERTEX:
|
||||
baseColor[0] =
|
||||
baseColor[1] =
|
||||
baseColor[2] =
|
||||
baseColor[3] = 0.0f;
|
||||
|
||||
vertColor[0] =
|
||||
vertColor[1] =
|
||||
vertColor[2] =
|
||||
vertColor[3] = 1.0f;
|
||||
break;
|
||||
case CGEN_EXACT_VERTEX_LIT:
|
||||
baseColor[0] =
|
||||
baseColor[1] =
|
||||
|
@ -477,11 +482,6 @@ static void ComputeShaderColors( shaderStage_t *pStage, vec4_t baseColor, vec4_t
|
|||
baseColor[1] = pStage->constantColor[1] / 255.0f;
|
||||
baseColor[2] = pStage->constantColor[2] / 255.0f;
|
||||
baseColor[3] = pStage->constantColor[3] / 255.0f;
|
||||
|
||||
vertColor[0] =
|
||||
vertColor[1] =
|
||||
vertColor[2] =
|
||||
vertColor[3] = 0.0f;
|
||||
break;
|
||||
case CGEN_VERTEX:
|
||||
baseColor[0] =
|
||||
|
@ -509,12 +509,10 @@ static void ComputeShaderColors( shaderStage_t *pStage, vec4_t baseColor, vec4_t
|
|||
baseColor[0] =
|
||||
baseColor[1] =
|
||||
baseColor[2] = tr.identityLight;
|
||||
baseColor[3] = 1.0f;
|
||||
|
||||
vertColor[0] =
|
||||
vertColor[1] =
|
||||
vertColor[2] = -tr.identityLight;
|
||||
vertColor[3] = 0.0f;
|
||||
break;
|
||||
case CGEN_FOG:
|
||||
{
|
||||
|
@ -527,22 +525,11 @@ static void ComputeShaderColors( shaderStage_t *pStage, vec4_t baseColor, vec4_t
|
|||
baseColor[2] = ((unsigned char *)(&fog->colorInt))[2] / 255.0f;
|
||||
baseColor[3] = ((unsigned char *)(&fog->colorInt))[3] / 255.0f;
|
||||
}
|
||||
|
||||
vertColor[0] =
|
||||
vertColor[1] =
|
||||
vertColor[2] =
|
||||
vertColor[3] = 0.0f;
|
||||
break;
|
||||
case CGEN_WAVEFORM:
|
||||
baseColor[0] =
|
||||
baseColor[1] =
|
||||
baseColor[2] = RB_CalcWaveColorSingle( &pStage->rgbWave );
|
||||
baseColor[3] = 1.0f;
|
||||
|
||||
vertColor[0] =
|
||||
vertColor[1] =
|
||||
vertColor[2] =
|
||||
vertColor[3] = 0.0f;
|
||||
break;
|
||||
case CGEN_ENTITY:
|
||||
if (backEnd.currentEntity)
|
||||
|
@ -552,11 +539,6 @@ static void ComputeShaderColors( shaderStage_t *pStage, vec4_t baseColor, vec4_t
|
|||
baseColor[2] = ((unsigned char *)backEnd.currentEntity->e.shaderRGBA)[2] / 255.0f;
|
||||
baseColor[3] = ((unsigned char *)backEnd.currentEntity->e.shaderRGBA)[3] / 255.0f;
|
||||
}
|
||||
|
||||
vertColor[0] =
|
||||
vertColor[1] =
|
||||
vertColor[2] =
|
||||
vertColor[3] = 0.0f;
|
||||
break;
|
||||
case CGEN_ONE_MINUS_ENTITY:
|
||||
if (backEnd.currentEntity)
|
||||
|
@ -566,23 +548,10 @@ static void ComputeShaderColors( shaderStage_t *pStage, vec4_t baseColor, vec4_t
|
|||
baseColor[2] = 1.0f - ((unsigned char *)backEnd.currentEntity->e.shaderRGBA)[2] / 255.0f;
|
||||
baseColor[3] = 1.0f - ((unsigned char *)backEnd.currentEntity->e.shaderRGBA)[3] / 255.0f;
|
||||
}
|
||||
|
||||
vertColor[0] =
|
||||
vertColor[1] =
|
||||
vertColor[2] =
|
||||
vertColor[3] = 0.0f;
|
||||
break;
|
||||
case CGEN_IDENTITY:
|
||||
case CGEN_LIGHTING_DIFFUSE:
|
||||
case CGEN_BAD:
|
||||
baseColor[0] =
|
||||
baseColor[1] =
|
||||
baseColor[2] =
|
||||
baseColor[3] = 1.0f;
|
||||
|
||||
vertColor[0] =
|
||||
vertColor[1] =
|
||||
vertColor[2] =
|
||||
vertColor[3] = 0.0f;
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -593,10 +562,6 @@ static void ComputeShaderColors( shaderStage_t *pStage, vec4_t baseColor, vec4_t
|
|||
{
|
||||
case AGEN_SKIP:
|
||||
break;
|
||||
case AGEN_IDENTITY:
|
||||
baseColor[3] = 1.0f;
|
||||
vertColor[3] = 0.0f;
|
||||
break;
|
||||
case AGEN_CONST:
|
||||
baseColor[3] = pStage->constantColor[3] / 255.0f;
|
||||
vertColor[3] = 0.0f;
|
||||
|
@ -627,15 +592,32 @@ static void ComputeShaderColors( shaderStage_t *pStage, vec4_t baseColor, vec4_t
|
|||
baseColor[3] = 1.0f;
|
||||
vertColor[3] = -1.0f;
|
||||
break;
|
||||
case AGEN_IDENTITY:
|
||||
case AGEN_LIGHTING_SPECULAR:
|
||||
case AGEN_PORTAL:
|
||||
case AGEN_FRESNEL:
|
||||
// Done entirely in vertex program
|
||||
baseColor[3] = 1.0f;
|
||||
vertColor[3] = 0.0f;
|
||||
break;
|
||||
}
|
||||
|
||||
// multiply color by overbrightbits if this isn't a blend
|
||||
if (r_softOverbright->integer && tr.overbrightBits
|
||||
&& !((blend & GLS_SRCBLEND_BITS) == GLS_SRCBLEND_DST_COLOR)
|
||||
&& !((blend & GLS_SRCBLEND_BITS) == GLS_SRCBLEND_ONE_MINUS_DST_COLOR)
|
||||
&& !((blend & GLS_DSTBLEND_BITS) == GLS_DSTBLEND_SRC_COLOR)
|
||||
&& !((blend & GLS_DSTBLEND_BITS) == GLS_DSTBLEND_ONE_MINUS_SRC_COLOR))
|
||||
{
|
||||
float scale = 1 << tr.overbrightBits;
|
||||
|
||||
baseColor[0] *= scale;
|
||||
baseColor[1] *= scale;
|
||||
baseColor[2] *= scale;
|
||||
vertColor[0] *= scale;
|
||||
vertColor[1] *= scale;
|
||||
vertColor[2] *= scale;
|
||||
}
|
||||
|
||||
// FIXME: find some way to implement this.
|
||||
#if 0
|
||||
// if in greyscale rendering mode turn all color values into greyscale.
|
||||
|
@ -749,7 +731,8 @@ static void ForwardDlight( void ) {
|
|||
dlight_t *dl;
|
||||
shaderProgram_t *sp;
|
||||
vec4_t vector;
|
||||
matrix_t matrix;
|
||||
vec4_t texMatrix;
|
||||
vec4_t texOffTurb;
|
||||
|
||||
if ( !( tess.dlightBits & ( 1 << l ) ) ) {
|
||||
continue; // this surface definately doesn't have any of this light
|
||||
|
@ -764,7 +747,7 @@ static void ForwardDlight( void ) {
|
|||
{
|
||||
int index = pStage->glslShaderIndex;
|
||||
|
||||
index &= ~(LIGHTDEF_LIGHTTYPE_MASK | LIGHTDEF_USE_DELUXEMAP);
|
||||
index &= ~LIGHTDEF_LIGHTTYPE_MASK;
|
||||
index |= LIGHTDEF_USE_LIGHT_VECTOR;
|
||||
|
||||
sp = &tr.lightallShader[index];
|
||||
|
@ -774,8 +757,9 @@ static void ForwardDlight( void ) {
|
|||
|
||||
GLSL_BindProgram(sp);
|
||||
|
||||
GLSL_SetUniformMatrix16(sp, UNIFORM_MODELVIEWPROJECTIONMATRIX, glState.modelviewProjection);
|
||||
GLSL_SetUniformMat4(sp, UNIFORM_MODELVIEWPROJECTIONMATRIX, glState.modelviewProjection);
|
||||
GLSL_SetUniformVec3(sp, UNIFORM_VIEWORIGIN, backEnd.viewParms.or.origin);
|
||||
GLSL_SetUniformVec3(sp, UNIFORM_LOCALVIEWORIGIN, backEnd.or.viewOrigin);
|
||||
|
||||
GLSL_SetUniformFloat(sp, UNIFORM_VERTEXLERP, glState.vertexAttribsInterpolation);
|
||||
|
||||
|
@ -802,7 +786,7 @@ static void ForwardDlight( void ) {
|
|||
vec4_t baseColor;
|
||||
vec4_t vertColor;
|
||||
|
||||
ComputeShaderColors(pStage, baseColor, vertColor);
|
||||
ComputeShaderColors(pStage, baseColor, vertColor, GLS_SRCBLEND_ONE | GLS_DSTBLEND_ONE);
|
||||
|
||||
GLSL_SetUniformVec4(sp, UNIFORM_BASECOLOR, baseColor);
|
||||
GLSL_SetUniformVec4(sp, UNIFORM_VERTCOLOR, vertColor);
|
||||
|
@ -833,7 +817,7 @@ static void ForwardDlight( void ) {
|
|||
// where they aren't rendered
|
||||
GL_State( GLS_SRCBLEND_ONE | GLS_DSTBLEND_ONE | GLS_DEPTHFUNC_EQUAL );
|
||||
|
||||
GLSL_SetUniformMatrix16(sp, UNIFORM_MODELMATRIX, backEnd.or.transformMatrix);
|
||||
GLSL_SetUniformMat4(sp, UNIFORM_MODELMATRIX, backEnd.or.transformMatrix);
|
||||
|
||||
if (pStage->bundle[TB_DIFFUSEMAP].image[0])
|
||||
R_BindAnimatedImageToTMU( &pStage->bundle[TB_DIFFUSEMAP], TB_DIFFUSEMAP);
|
||||
|
@ -851,13 +835,9 @@ static void ForwardDlight( void ) {
|
|||
GL_SelectTexture(0);
|
||||
}
|
||||
|
||||
ComputeTexMatrix( pStage, TB_DIFFUSEMAP, matrix );
|
||||
|
||||
VectorSet4(vector, matrix[0], matrix[1], matrix[4], matrix[5]);
|
||||
GLSL_SetUniformVec4(sp, UNIFORM_DIFFUSETEXMATRIX, vector);
|
||||
|
||||
VectorSet4(vector, matrix[8], matrix[9], matrix[12], matrix[13]);
|
||||
GLSL_SetUniformVec4(sp, UNIFORM_DIFFUSETEXOFFTURB, vector);
|
||||
ComputeTexMods( pStage, TB_DIFFUSEMAP, texMatrix, texOffTurb );
|
||||
GLSL_SetUniformVec4(sp, UNIFORM_DIFFUSETEXMATRIX, texMatrix);
|
||||
GLSL_SetUniformVec4(sp, UNIFORM_DIFFUSETEXOFFTURB, texOffTurb);
|
||||
|
||||
GLSL_SetUniformInt(sp, UNIFORM_TCGEN0, pStage->bundle[0].tcGen);
|
||||
|
||||
|
@ -914,7 +894,7 @@ static void ProjectPshadowVBOGLSL( void ) {
|
|||
|
||||
GLSL_BindProgram(sp);
|
||||
|
||||
GLSL_SetUniformMatrix16(sp, UNIFORM_MODELVIEWPROJECTIONMATRIX, glState.modelviewProjection);
|
||||
GLSL_SetUniformMat4(sp, UNIFORM_MODELVIEWPROJECTIONMATRIX, glState.modelviewProjection);
|
||||
|
||||
VectorCopy(origin, vector);
|
||||
vector[3] = 1.0f;
|
||||
|
@ -982,7 +962,7 @@ static void RB_FogPass( void ) {
|
|||
if (deformGen != DGEN_NONE)
|
||||
index |= FOGDEF_USE_DEFORM_VERTEXES;
|
||||
|
||||
if (glState.vertexAttribsInterpolation)
|
||||
if (glState.vertexAnimation)
|
||||
index |= FOGDEF_USE_VERTEX_ANIMATION;
|
||||
|
||||
sp = &tr.fogShader[index];
|
||||
|
@ -994,7 +974,7 @@ static void RB_FogPass( void ) {
|
|||
|
||||
fog = tr.world->fogs + tess.fogNum;
|
||||
|
||||
GLSL_SetUniformMatrix16(sp, UNIFORM_MODELVIEWPROJECTIONMATRIX, glState.modelviewProjection);
|
||||
GLSL_SetUniformMat4(sp, UNIFORM_MODELVIEWPROJECTIONMATRIX, glState.modelviewProjection);
|
||||
|
||||
GLSL_SetUniformFloat(sp, UNIFORM_VERTEXLERP, glState.vertexAttribsInterpolation);
|
||||
|
||||
|
@ -1039,7 +1019,7 @@ static unsigned int RB_CalcShaderVertexAttribs( shaderCommands_t *input )
|
|||
{
|
||||
unsigned int vertexAttribs = input->shader->vertexAttribs;
|
||||
|
||||
if(glState.vertexAttribsInterpolation > 0.0f)
|
||||
if(glState.vertexAnimation)
|
||||
{
|
||||
vertexAttribs |= ATTR_POSITION2;
|
||||
if (vertexAttribs & ATTR_NORMAL)
|
||||
|
@ -1047,7 +1027,6 @@ static unsigned int RB_CalcShaderVertexAttribs( shaderCommands_t *input )
|
|||
vertexAttribs |= ATTR_NORMAL2;
|
||||
#ifdef USE_VERT_TANGENT_SPACE
|
||||
vertexAttribs |= ATTR_TANGENT2;
|
||||
vertexAttribs |= ATTR_BITANGENT2;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
@ -1058,7 +1037,6 @@ static unsigned int RB_CalcShaderVertexAttribs( shaderCommands_t *input )
|
|||
static void RB_IterateStagesGeneric( shaderCommands_t *input )
|
||||
{
|
||||
int stage;
|
||||
matrix_t matrix;
|
||||
|
||||
vec4_t fogDistanceVector, fogDepthVector = {0, 0, 0, 0};
|
||||
float eyeT = 0;
|
||||
|
@ -1074,6 +1052,8 @@ static void RB_IterateStagesGeneric( shaderCommands_t *input )
|
|||
{
|
||||
shaderStage_t *pStage = input->xstages[stage];
|
||||
shaderProgram_t *sp;
|
||||
vec4_t texMatrix;
|
||||
vec4_t texOffTurb;
|
||||
|
||||
if ( !pStage )
|
||||
{
|
||||
|
@ -1082,7 +1062,7 @@ static void RB_IterateStagesGeneric( shaderCommands_t *input )
|
|||
|
||||
if (backEnd.depthFill)
|
||||
{
|
||||
if (pStage->glslShaderGroup)
|
||||
if (pStage->glslShaderGroup == tr.lightallShader)
|
||||
{
|
||||
int index = 0;
|
||||
|
||||
|
@ -1107,7 +1087,7 @@ static void RB_IterateStagesGeneric( shaderCommands_t *input )
|
|||
shaderAttribs |= GENERICDEF_USE_DEFORM_VERTEXES;
|
||||
}
|
||||
|
||||
if (glState.vertexAttribsInterpolation > 0.0f && backEnd.currentEntity && backEnd.currentEntity != &tr.worldEntity)
|
||||
if (glState.vertexAnimation)
|
||||
{
|
||||
shaderAttribs |= GENERICDEF_USE_VERTEX_ANIMATION;
|
||||
}
|
||||
|
@ -1120,7 +1100,7 @@ static void RB_IterateStagesGeneric( shaderCommands_t *input )
|
|||
sp = &tr.genericShader[shaderAttribs];
|
||||
}
|
||||
}
|
||||
else if (pStage->glslShaderGroup)
|
||||
else if (pStage->glslShaderGroup == tr.lightallShader)
|
||||
{
|
||||
int index = pStage->glslShaderIndex;
|
||||
|
||||
|
@ -1134,11 +1114,6 @@ static void RB_IterateStagesGeneric( shaderCommands_t *input )
|
|||
index |= LIGHTDEF_USE_SHADOWMAP;
|
||||
}
|
||||
|
||||
if (!(tr.viewParms.flags & VPF_NOCUBEMAPS) && (index & LIGHTDEF_LIGHTTYPE_MASK) && input->cubemapIndex)
|
||||
{
|
||||
index |= LIGHTDEF_USE_CUBEMAP;
|
||||
}
|
||||
|
||||
if (r_lightmap->integer && index & LIGHTDEF_USE_LIGHTMAP)
|
||||
{
|
||||
index = LIGHTDEF_USE_LIGHTMAP;
|
||||
|
@ -1146,10 +1121,7 @@ static void RB_IterateStagesGeneric( shaderCommands_t *input )
|
|||
|
||||
sp = &pStage->glslShaderGroup[index];
|
||||
|
||||
if (pStage->glslShaderGroup == tr.lightallShader)
|
||||
{
|
||||
backEnd.pc.c_lightallDraws++;
|
||||
}
|
||||
backEnd.pc.c_lightallDraws++;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -1160,8 +1132,9 @@ static void RB_IterateStagesGeneric( shaderCommands_t *input )
|
|||
|
||||
GLSL_BindProgram(sp);
|
||||
|
||||
GLSL_SetUniformMatrix16(sp, UNIFORM_MODELVIEWPROJECTIONMATRIX, glState.modelviewProjection);
|
||||
GLSL_SetUniformMat4(sp, UNIFORM_MODELVIEWPROJECTIONMATRIX, glState.modelviewProjection);
|
||||
GLSL_SetUniformVec3(sp, UNIFORM_VIEWORIGIN, backEnd.viewParms.or.origin);
|
||||
GLSL_SetUniformVec3(sp, UNIFORM_LOCALVIEWORIGIN, backEnd.or.viewOrigin);
|
||||
|
||||
GLSL_SetUniformFloat(sp, UNIFORM_VERTEXLERP, glState.vertexAttribsInterpolation);
|
||||
|
||||
|
@ -1184,7 +1157,7 @@ static void RB_IterateStagesGeneric( shaderCommands_t *input )
|
|||
vec4_t baseColor;
|
||||
vec4_t vertColor;
|
||||
|
||||
ComputeShaderColors(pStage, baseColor, vertColor);
|
||||
ComputeShaderColors(pStage, baseColor, vertColor, pStage->stateBits);
|
||||
|
||||
if ((backEnd.refdef.colorScale != 1.0f) && !(backEnd.refdef.rdflags & RDF_NOWORLDMODEL))
|
||||
{
|
||||
|
@ -1210,6 +1183,7 @@ static void RB_IterateStagesGeneric( shaderCommands_t *input )
|
|||
VectorCopy(backEnd.currentEntity->lightDir, vec);
|
||||
vec[3] = 0.0f;
|
||||
GLSL_SetUniformVec4(sp, UNIFORM_LIGHTORIGIN, vec);
|
||||
GLSL_SetUniformVec3(sp, UNIFORM_MODELLIGHTDIR, backEnd.currentEntity->modelLightDir);
|
||||
|
||||
GLSL_SetUniformFloat(sp, UNIFORM_LIGHTRADIUS, 0.0f);
|
||||
}
|
||||
|
@ -1231,16 +1205,9 @@ static void RB_IterateStagesGeneric( shaderCommands_t *input )
|
|||
GLSL_SetUniformVec4(sp, UNIFORM_FOGCOLORMASK, fogColorMask);
|
||||
}
|
||||
|
||||
ComputeTexMatrix( pStage, TB_DIFFUSEMAP, matrix );
|
||||
|
||||
{
|
||||
vec4_t vector;
|
||||
VectorSet4(vector, matrix[0], matrix[1], matrix[4], matrix[5]);
|
||||
GLSL_SetUniformVec4(sp, UNIFORM_DIFFUSETEXMATRIX, vector);
|
||||
|
||||
VectorSet4(vector, matrix[8], matrix[9], matrix[12], matrix[13]);
|
||||
GLSL_SetUniformVec4(sp, UNIFORM_DIFFUSETEXOFFTURB, vector);
|
||||
}
|
||||
ComputeTexMods( pStage, TB_DIFFUSEMAP, texMatrix, texOffTurb );
|
||||
GLSL_SetUniformVec4(sp, UNIFORM_DIFFUSETEXMATRIX, texMatrix);
|
||||
GLSL_SetUniformVec4(sp, UNIFORM_DIFFUSETEXOFFTURB, texOffTurb);
|
||||
|
||||
GLSL_SetUniformInt(sp, UNIFORM_TCGEN0, pStage->bundle[0].tcGen);
|
||||
if (pStage->bundle[0].tcGen == TCGEN_VECTOR)
|
||||
|
@ -1253,7 +1220,7 @@ static void RB_IterateStagesGeneric( shaderCommands_t *input )
|
|||
GLSL_SetUniformVec3(sp, UNIFORM_TCGEN0VECTOR1, vec);
|
||||
}
|
||||
|
||||
GLSL_SetUniformMatrix16(sp, UNIFORM_MODELMATRIX, backEnd.or.transformMatrix);
|
||||
GLSL_SetUniformMat4(sp, UNIFORM_MODELMATRIX, backEnd.or.transformMatrix);
|
||||
|
||||
GLSL_SetUniformVec2(sp, UNIFORM_MATERIALINFO, pStage->materialInfo);
|
||||
|
||||
|
@ -1269,11 +1236,12 @@ static void RB_IterateStagesGeneric( shaderCommands_t *input )
|
|||
else if ( pStage->bundle[TB_COLORMAP].image[0] != 0 )
|
||||
R_BindAnimatedImageToTMU( &pStage->bundle[TB_COLORMAP], TB_COLORMAP );
|
||||
}
|
||||
else if ( pStage->glslShaderGroup )
|
||||
else if ( pStage->glslShaderGroup == tr.lightallShader )
|
||||
{
|
||||
int i;
|
||||
vec4_t enableTextures;
|
||||
|
||||
if ((backEnd.viewParms.flags & VPF_USESUNLIGHT) && (pStage->glslShaderIndex & LIGHTDEF_LIGHTTYPE_MASK))
|
||||
if (r_sunlightMode->integer && (backEnd.viewParms.flags & VPF_USESUNLIGHT) && (pStage->glslShaderIndex & LIGHTDEF_LIGHTTYPE_MASK))
|
||||
{
|
||||
GL_BindToTMU(tr.screenShadowImage, TB_SHADOWMAP);
|
||||
GLSL_SetUniformVec3(sp, UNIFORM_PRIMARYLIGHTAMBIENT, backEnd.refdef.sunAmbCol);
|
||||
|
@ -1281,18 +1249,15 @@ static void RB_IterateStagesGeneric( shaderCommands_t *input )
|
|||
GLSL_SetUniformVec4(sp, UNIFORM_PRIMARYLIGHTORIGIN, backEnd.refdef.sunDir);
|
||||
}
|
||||
|
||||
VectorSet4(enableTextures, 0, 0, 0, 0);
|
||||
if ((r_lightmap->integer == 1 || r_lightmap->integer == 2) && pStage->bundle[TB_LIGHTMAP].image[0])
|
||||
{
|
||||
for (i = 0; i < NUM_TEXTURE_BUNDLES; i++)
|
||||
{
|
||||
if (i == TB_LIGHTMAP)
|
||||
{
|
||||
R_BindAnimatedImageToTMU( &pStage->bundle[i], i);
|
||||
}
|
||||
else if (pStage->bundle[i].image[0])
|
||||
{
|
||||
GL_BindToTMU( tr.whiteImage, i);
|
||||
}
|
||||
R_BindAnimatedImageToTMU( &pStage->bundle[TB_LIGHTMAP], i);
|
||||
else
|
||||
GL_BindToTMU( tr.whiteImage, i );
|
||||
}
|
||||
}
|
||||
else if (r_lightmap->integer == 3 && pStage->bundle[TB_DELUXEMAP].image[0])
|
||||
|
@ -1300,25 +1265,62 @@ static void RB_IterateStagesGeneric( shaderCommands_t *input )
|
|||
for (i = 0; i < NUM_TEXTURE_BUNDLES; i++)
|
||||
{
|
||||
if (i == TB_LIGHTMAP)
|
||||
{
|
||||
R_BindAnimatedImageToTMU( &pStage->bundle[TB_DELUXEMAP], i);
|
||||
}
|
||||
else if (pStage->bundle[i].image[0])
|
||||
{
|
||||
GL_BindToTMU( tr.whiteImage, i);
|
||||
}
|
||||
else
|
||||
GL_BindToTMU( tr.whiteImage, i );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (i = 0; i < NUM_TEXTURE_BUNDLES; i++)
|
||||
qboolean light = (pStage->glslShaderIndex & LIGHTDEF_LIGHTTYPE_MASK) != 0;
|
||||
qboolean fastLight = !(r_normalMapping->integer || r_specularMapping->integer);
|
||||
|
||||
if (pStage->bundle[TB_DIFFUSEMAP].image[0])
|
||||
R_BindAnimatedImageToTMU( &pStage->bundle[TB_DIFFUSEMAP], TB_DIFFUSEMAP);
|
||||
|
||||
if (pStage->bundle[TB_LIGHTMAP].image[0])
|
||||
R_BindAnimatedImageToTMU( &pStage->bundle[TB_LIGHTMAP], TB_LIGHTMAP);
|
||||
|
||||
// bind textures that are sampled and used in the glsl shader, and
|
||||
// bind whiteImage to textures that are sampled but zeroed in the glsl shader
|
||||
//
|
||||
// alternatives:
|
||||
// - use the last bound texture
|
||||
// -> costs more to sample a higher res texture then throw out the result
|
||||
// - disable texture sampling in glsl shader with #ifdefs, as before
|
||||
// -> increases the number of shaders that must be compiled
|
||||
//
|
||||
if (light && !fastLight)
|
||||
{
|
||||
if (pStage->bundle[i].image[0])
|
||||
if (pStage->bundle[TB_NORMALMAP].image[0])
|
||||
{
|
||||
R_BindAnimatedImageToTMU( &pStage->bundle[i], i);
|
||||
R_BindAnimatedImageToTMU( &pStage->bundle[TB_NORMALMAP], TB_NORMALMAP);
|
||||
enableTextures[0] = 1.0f;
|
||||
}
|
||||
else if (r_normalMapping->integer)
|
||||
GL_BindToTMU( tr.whiteImage, TB_NORMALMAP );
|
||||
|
||||
if (pStage->bundle[TB_DELUXEMAP].image[0])
|
||||
{
|
||||
R_BindAnimatedImageToTMU( &pStage->bundle[TB_DELUXEMAP], TB_DELUXEMAP);
|
||||
enableTextures[1] = 1.0f;
|
||||
}
|
||||
else if (r_deluxeMapping->integer)
|
||||
GL_BindToTMU( tr.whiteImage, TB_DELUXEMAP );
|
||||
|
||||
if (pStage->bundle[TB_SPECULARMAP].image[0])
|
||||
{
|
||||
R_BindAnimatedImageToTMU( &pStage->bundle[TB_SPECULARMAP], TB_SPECULARMAP);
|
||||
enableTextures[2] = 1.0f;
|
||||
}
|
||||
else if (r_specularMapping->integer)
|
||||
GL_BindToTMU( tr.whiteImage, TB_SPECULARMAP );
|
||||
}
|
||||
|
||||
enableTextures[3] = (r_cubeMapping->integer && !(tr.viewParms.flags & VPF_NOCUBEMAPS) && input->cubemapIndex) ? 1.0f : 0.0f;
|
||||
}
|
||||
|
||||
GLSL_SetUniformVec4(sp, UNIFORM_ENABLETEXTURES, enableTextures);
|
||||
}
|
||||
else if ( pStage->bundle[1].image[0] != 0 )
|
||||
{
|
||||
|
@ -1340,12 +1342,7 @@ static void RB_IterateStagesGeneric( shaderCommands_t *input )
|
|||
//
|
||||
// set state
|
||||
//
|
||||
if ( pStage->bundle[0].vertexLightmap && ( (r_vertexLight->integer && !r_uiFullScreen->integer) || glConfig.hardwareType == GLHW_PERMEDIA2 ) && r_lightmap->integer )
|
||||
{
|
||||
GL_BindToTMU( tr.whiteImage, 0 );
|
||||
}
|
||||
else
|
||||
R_BindAnimatedImageToTMU( &pStage->bundle[0], 0 );
|
||||
R_BindAnimatedImageToTMU( &pStage->bundle[0], 0 );
|
||||
|
||||
GLSL_SetUniformInt(sp, UNIFORM_TEXTURE1ENV, 0);
|
||||
}
|
||||
|
@ -1369,7 +1366,7 @@ static void RB_IterateStagesGeneric( shaderCommands_t *input )
|
|||
}
|
||||
|
||||
// allow skipping out to show just lightmaps during development
|
||||
if ( r_lightmap->integer && ( pStage->bundle[0].isLightmap || pStage->bundle[1].isLightmap || pStage->bundle[0].vertexLightmap ) )
|
||||
if ( r_lightmap->integer && ( pStage->bundle[0].isLightmap || pStage->bundle[1].isLightmap ) )
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
@ -1394,9 +1391,9 @@ static void RB_RenderShadowmap( shaderCommands_t *input )
|
|||
|
||||
GLSL_BindProgram(sp);
|
||||
|
||||
GLSL_SetUniformMatrix16(sp, UNIFORM_MODELVIEWPROJECTIONMATRIX, glState.modelviewProjection);
|
||||
GLSL_SetUniformMat4(sp, UNIFORM_MODELVIEWPROJECTIONMATRIX, glState.modelviewProjection);
|
||||
|
||||
GLSL_SetUniformMatrix16(sp, UNIFORM_MODELMATRIX, backEnd.or.transformMatrix);
|
||||
GLSL_SetUniformMat4(sp, UNIFORM_MODELMATRIX, backEnd.or.transformMatrix);
|
||||
|
||||
GLSL_SetUniformFloat(sp, UNIFORM_VERTEXLERP, glState.vertexAttribsInterpolation);
|
||||
|
||||
|
@ -1555,8 +1552,8 @@ void RB_StageIteratorGeneric( void )
|
|||
//
|
||||
// pshadows!
|
||||
//
|
||||
if (glRefConfig.framebufferObject && tess.pshadowBits && tess.shader->sort <= SS_OPAQUE
|
||||
&& !(tess.shader->surfaceFlags & (SURF_NODLIGHT | SURF_SKY) ) ) {
|
||||
if (glRefConfig.framebufferObject && r_shadows->integer == 4 && tess.pshadowBits
|
||||
&& tess.shader->sort <= SS_OPAQUE && !(tess.shader->surfaceFlags & (SURF_NODLIGHT | SURF_SKY) ) ) {
|
||||
ProjectPshadowVBOGLSL();
|
||||
}
|
||||
|
||||
|
|
|
@ -84,42 +84,16 @@ static float EvalWaveFormClamped( const waveForm_t *wf )
|
|||
}
|
||||
|
||||
/*
|
||||
** RB_CalcStretchTexCoords
|
||||
** RB_CalcStretchTexMatrix
|
||||
*/
|
||||
void RB_CalcStretchTexCoords( const waveForm_t *wf, float *st )
|
||||
{
|
||||
float p;
|
||||
texModInfo_t tmi;
|
||||
|
||||
p = 1.0f / EvalWaveForm( wf );
|
||||
|
||||
tmi.matrix[0][0] = p;
|
||||
tmi.matrix[1][0] = 0;
|
||||
tmi.translate[0] = 0.5f - 0.5f * p;
|
||||
|
||||
tmi.matrix[0][1] = 0;
|
||||
tmi.matrix[1][1] = p;
|
||||
tmi.translate[1] = 0.5f - 0.5f * p;
|
||||
|
||||
RB_CalcTransformTexCoords( &tmi, st );
|
||||
}
|
||||
|
||||
void RB_CalcStretchTexMatrix( const waveForm_t *wf, float *matrix )
|
||||
{
|
||||
float p;
|
||||
texModInfo_t tmi;
|
||||
|
||||
p = 1.0f / EvalWaveForm( wf );
|
||||
|
||||
tmi.matrix[0][0] = p;
|
||||
tmi.matrix[1][0] = 0;
|
||||
tmi.translate[0] = 0.5f - 0.5f * p;
|
||||
|
||||
tmi.matrix[0][1] = 0;
|
||||
tmi.matrix[1][1] = p;
|
||||
tmi.translate[1] = 0.5f - 0.5f * p;
|
||||
|
||||
RB_CalcTransformTexMatrix( &tmi, matrix );
|
||||
matrix[0] = p; matrix[2] = 0; matrix[4] = 0.5f - 0.5f * p;
|
||||
matrix[1] = 0; matrix[3] = p; matrix[5] = 0.5f - 0.5f * p;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -142,27 +116,27 @@ void RB_CalcDeformVertexes( deformStage_t *ds )
|
|||
vec3_t offset;
|
||||
float scale;
|
||||
float *xyz = ( float * ) tess.xyz;
|
||||
float *normal = ( float * ) tess.normal;
|
||||
uint32_t *normal = tess.normal;
|
||||
float *table;
|
||||
|
||||
if ( ds->deformationWave.frequency == 0 )
|
||||
{
|
||||
scale = EvalWaveForm( &ds->deformationWave );
|
||||
|
||||
for ( i = 0; i < tess.numVertexes; i++, xyz += 4, normal += 4 )
|
||||
for ( i = 0; i < tess.numVertexes; i++, xyz += 4, normal++ )
|
||||
{
|
||||
VectorScale( normal, scale, offset );
|
||||
R_VboUnpackNormal(offset, *normal);
|
||||
|
||||
xyz[0] += offset[0];
|
||||
xyz[1] += offset[1];
|
||||
xyz[2] += offset[2];
|
||||
xyz[0] += offset[0] * scale;
|
||||
xyz[1] += offset[1] * scale;
|
||||
xyz[2] += offset[2] * scale;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
table = TableForFunc( ds->deformationWave.func );
|
||||
|
||||
for ( i = 0; i < tess.numVertexes; i++, xyz += 4, normal += 4 )
|
||||
for ( i = 0; i < tess.numVertexes; i++, xyz += 4, normal++ )
|
||||
{
|
||||
float off = ( xyz[0] + xyz[1] + xyz[2] ) * ds->deformationSpread;
|
||||
|
||||
|
@ -171,11 +145,11 @@ void RB_CalcDeformVertexes( deformStage_t *ds )
|
|||
ds->deformationWave.phase + off,
|
||||
ds->deformationWave.frequency );
|
||||
|
||||
VectorScale( normal, scale, offset );
|
||||
|
||||
xyz[0] += offset[0];
|
||||
xyz[1] += offset[1];
|
||||
xyz[2] += offset[2];
|
||||
R_VboUnpackNormal(offset, *normal);
|
||||
|
||||
xyz[0] += offset[0] * scale;
|
||||
xyz[1] += offset[1] * scale;
|
||||
xyz[2] += offset[2] * scale;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -191,25 +165,31 @@ void RB_CalcDeformNormals( deformStage_t *ds ) {
|
|||
int i;
|
||||
float scale;
|
||||
float *xyz = ( float * ) tess.xyz;
|
||||
float *normal = ( float * ) tess.normal;
|
||||
uint32_t *normal = tess.normal;
|
||||
|
||||
for ( i = 0; i < tess.numVertexes; i++, xyz += 4, normal++ ) {
|
||||
vec3_t fNormal;
|
||||
|
||||
R_VboUnpackNormal(fNormal, *normal);
|
||||
|
||||
for ( i = 0; i < tess.numVertexes; i++, xyz += 4, normal += 4 ) {
|
||||
scale = 0.98f;
|
||||
scale = R_NoiseGet4f( xyz[0] * scale, xyz[1] * scale, xyz[2] * scale,
|
||||
tess.shaderTime * ds->deformationWave.frequency );
|
||||
normal[ 0 ] += ds->deformationWave.amplitude * scale;
|
||||
fNormal[ 0 ] += ds->deformationWave.amplitude * scale;
|
||||
|
||||
scale = 0.98f;
|
||||
scale = R_NoiseGet4f( 100 + xyz[0] * scale, xyz[1] * scale, xyz[2] * scale,
|
||||
tess.shaderTime * ds->deformationWave.frequency );
|
||||
normal[ 1 ] += ds->deformationWave.amplitude * scale;
|
||||
fNormal[ 1 ] += ds->deformationWave.amplitude * scale;
|
||||
|
||||
scale = 0.98f;
|
||||
scale = R_NoiseGet4f( 200 + xyz[0] * scale, xyz[1] * scale, xyz[2] * scale,
|
||||
tess.shaderTime * ds->deformationWave.frequency );
|
||||
normal[ 2 ] += ds->deformationWave.amplitude * scale;
|
||||
fNormal[ 2 ] += ds->deformationWave.amplitude * scale;
|
||||
|
||||
VectorNormalizeFast( normal );
|
||||
VectorNormalizeFast( fNormal );
|
||||
|
||||
*normal = R_VboPackNormal(fNormal);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -223,22 +203,25 @@ void RB_CalcBulgeVertexes( deformStage_t *ds ) {
|
|||
int i;
|
||||
const float *st = ( const float * ) tess.texCoords[0];
|
||||
float *xyz = ( float * ) tess.xyz;
|
||||
float *normal = ( float * ) tess.normal;
|
||||
uint32_t *normal = tess.normal;
|
||||
float now;
|
||||
|
||||
now = backEnd.refdef.time * ds->bulgeSpeed * 0.001f;
|
||||
|
||||
for ( i = 0; i < tess.numVertexes; i++, xyz += 4, st += 4, normal += 4 ) {
|
||||
for ( i = 0; i < tess.numVertexes; i++, xyz += 4, st += 4, normal++ ) {
|
||||
int off;
|
||||
float scale;
|
||||
vec3_t fNormal;
|
||||
|
||||
R_VboUnpackNormal(fNormal, *normal);
|
||||
|
||||
off = (float)( FUNCTABLE_SIZE / (M_PI*2) ) * ( st[0] * ds->bulgeWidth + now );
|
||||
|
||||
scale = tr.sinTable[ off & FUNCTABLE_MASK ] * ds->bulgeHeight;
|
||||
|
||||
xyz[0] += normal[0] * scale;
|
||||
xyz[1] += normal[1] * scale;
|
||||
xyz[2] += normal[2] * scale;
|
||||
xyz[0] += fNormal[0] * scale;
|
||||
xyz[1] += fNormal[1] * scale;
|
||||
xyz[2] += fNormal[2] * scale;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -288,11 +271,14 @@ void DeformText( const char *text ) {
|
|||
float color[4];
|
||||
float bottom, top;
|
||||
vec3_t mid;
|
||||
vec3_t fNormal;
|
||||
|
||||
height[0] = 0;
|
||||
height[1] = 0;
|
||||
height[2] = -1;
|
||||
CrossProduct( tess.normal[0], height, width );
|
||||
|
||||
R_VboUnpackNormal(fNormal, tess.normal[0]);
|
||||
CrossProduct( fNormal, height, width );
|
||||
|
||||
// find the midpoint of the box
|
||||
VectorClear( mid );
|
||||
|
@ -618,88 +604,6 @@ COLORS
|
|||
*/
|
||||
|
||||
|
||||
/*
|
||||
** RB_CalcColorFromEntity
|
||||
*/
|
||||
void RB_CalcColorFromEntity( unsigned char *dstColors )
|
||||
{
|
||||
int i;
|
||||
int *pColors = ( int * ) dstColors;
|
||||
int c;
|
||||
|
||||
if ( !backEnd.currentEntity )
|
||||
return;
|
||||
|
||||
c = * ( int * ) backEnd.currentEntity->e.shaderRGBA;
|
||||
|
||||
for ( i = 0; i < tess.numVertexes; i++, pColors++ )
|
||||
{
|
||||
*pColors = c;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
** RB_CalcColorFromOneMinusEntity
|
||||
*/
|
||||
void RB_CalcColorFromOneMinusEntity( unsigned char *dstColors )
|
||||
{
|
||||
int i;
|
||||
int *pColors = ( int * ) dstColors;
|
||||
unsigned char invModulate[4];
|
||||
int c;
|
||||
|
||||
if ( !backEnd.currentEntity )
|
||||
return;
|
||||
|
||||
invModulate[0] = 255 - backEnd.currentEntity->e.shaderRGBA[0];
|
||||
invModulate[1] = 255 - backEnd.currentEntity->e.shaderRGBA[1];
|
||||
invModulate[2] = 255 - backEnd.currentEntity->e.shaderRGBA[2];
|
||||
invModulate[3] = 255 - backEnd.currentEntity->e.shaderRGBA[3]; // this trashes alpha, but the AGEN block fixes it
|
||||
|
||||
c = * ( int * ) invModulate;
|
||||
|
||||
for ( i = 0; i < tess.numVertexes; i++, pColors++ )
|
||||
{
|
||||
*pColors = c;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
** RB_CalcAlphaFromEntity
|
||||
*/
|
||||
void RB_CalcAlphaFromEntity( unsigned char *dstColors )
|
||||
{
|
||||
int i;
|
||||
|
||||
if ( !backEnd.currentEntity )
|
||||
return;
|
||||
|
||||
dstColors += 3;
|
||||
|
||||
for ( i = 0; i < tess.numVertexes; i++, dstColors += 4 )
|
||||
{
|
||||
*dstColors = backEnd.currentEntity->e.shaderRGBA[3];
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
** RB_CalcAlphaFromOneMinusEntity
|
||||
*/
|
||||
void RB_CalcAlphaFromOneMinusEntity( unsigned char *dstColors )
|
||||
{
|
||||
int i;
|
||||
|
||||
if ( !backEnd.currentEntity )
|
||||
return;
|
||||
|
||||
dstColors += 3;
|
||||
|
||||
for ( i = 0; i < tess.numVertexes; i++, dstColors += 4 )
|
||||
{
|
||||
*dstColors = 0xff - backEnd.currentEntity->e.shaderRGBA[3];
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
** RB_CalcWaveColorSingle
|
||||
*/
|
||||
|
@ -723,29 +627,6 @@ float RB_CalcWaveColorSingle( const waveForm_t *wf )
|
|||
return glow;
|
||||
}
|
||||
|
||||
/*
|
||||
** RB_CalcWaveColor
|
||||
*/
|
||||
void RB_CalcWaveColor( const waveForm_t *wf, unsigned char *dstColors )
|
||||
{
|
||||
int i;
|
||||
int v;
|
||||
float glow;
|
||||
int *colors = ( int * ) dstColors;
|
||||
byte color[4];
|
||||
|
||||
glow = RB_CalcWaveColorSingle( wf );
|
||||
|
||||
v = ri.ftol(255 * glow);
|
||||
color[0] = color[1] = color[2] = v;
|
||||
color[3] = 255;
|
||||
v = *(int *)color;
|
||||
|
||||
for ( i = 0; i < tess.numVertexes; i++, colors++ ) {
|
||||
*colors = v;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
** RB_CalcWaveAlphaSingle
|
||||
*/
|
||||
|
@ -754,25 +635,6 @@ float RB_CalcWaveAlphaSingle( const waveForm_t *wf )
|
|||
return EvalWaveFormClamped( wf );
|
||||
}
|
||||
|
||||
/*
|
||||
** RB_CalcWaveAlpha
|
||||
*/
|
||||
void RB_CalcWaveAlpha( const waveForm_t *wf, unsigned char *dstColors )
|
||||
{
|
||||
int i;
|
||||
int v;
|
||||
float glow;
|
||||
|
||||
glow = EvalWaveFormClamped( wf );
|
||||
|
||||
v = 255 * glow;
|
||||
|
||||
for ( i = 0; i < tess.numVertexes; i++, dstColors += 4 )
|
||||
{
|
||||
dstColors[3] = v;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
** RB_CalcModulateColorsByFog
|
||||
*/
|
||||
|
@ -793,45 +655,6 @@ void RB_CalcModulateColorsByFog( unsigned char *colors ) {
|
|||
}
|
||||
}
|
||||
|
||||
/*
|
||||
** RB_CalcModulateAlphasByFog
|
||||
*/
|
||||
void RB_CalcModulateAlphasByFog( unsigned char *colors ) {
|
||||
int i;
|
||||
float texCoords[SHADER_MAX_VERTEXES][2];
|
||||
|
||||
// calculate texcoords so we can derive density
|
||||
// this is not wasted, because it would only have
|
||||
// been previously called if the surface was opaque
|
||||
RB_CalcFogTexCoords( texCoords[0] );
|
||||
|
||||
for ( i = 0; i < tess.numVertexes; i++, colors += 4 ) {
|
||||
float f = 1.0 - R_FogFactor( texCoords[i][0], texCoords[i][1] );
|
||||
colors[3] *= f;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
** RB_CalcModulateRGBAsByFog
|
||||
*/
|
||||
void RB_CalcModulateRGBAsByFog( unsigned char *colors ) {
|
||||
int i;
|
||||
float texCoords[SHADER_MAX_VERTEXES][2];
|
||||
|
||||
// calculate texcoords so we can derive density
|
||||
// this is not wasted, because it would only have
|
||||
// been previously called if the surface was opaque
|
||||
RB_CalcFogTexCoords( texCoords[0] );
|
||||
|
||||
for ( i = 0; i < tess.numVertexes; i++, colors += 4 ) {
|
||||
float f = 1.0 - R_FogFactor( texCoords[i][0], texCoords[i][1] );
|
||||
colors[0] *= f;
|
||||
colors[1] *= f;
|
||||
colors[2] *= f;
|
||||
colors[3] *= f;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
====================================================================
|
||||
|
@ -928,118 +751,27 @@ void RB_CalcFogTexCoords( float *st ) {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
** RB_CalcEnvironmentTexCoords
|
||||
** RB_CalcTurbulentFactors
|
||||
*/
|
||||
void RB_CalcEnvironmentTexCoords( float *st )
|
||||
void RB_CalcTurbulentFactors( const waveForm_t *wf, float *amplitude, float *now )
|
||||
{
|
||||
int i;
|
||||
float *v, *normal;
|
||||
vec3_t viewer, reflected;
|
||||
float d;
|
||||
|
||||
v = tess.xyz[0];
|
||||
normal = tess.normal[0];
|
||||
|
||||
for (i = 0 ; i < tess.numVertexes ; i++, v += 4, normal += 4, st += 2 )
|
||||
{
|
||||
VectorSubtract (backEnd.or.viewOrigin, v, viewer);
|
||||
VectorNormalizeFast (viewer);
|
||||
|
||||
d = DotProduct (normal, viewer);
|
||||
|
||||
reflected[0] = normal[0]*2*d - viewer[0];
|
||||
reflected[1] = normal[1]*2*d - viewer[1];
|
||||
reflected[2] = normal[2]*2*d - viewer[2];
|
||||
|
||||
st[0] = 0.5 + reflected[1] * 0.5;
|
||||
st[1] = 0.5 - reflected[2] * 0.5;
|
||||
}
|
||||
*now = wf->phase + tess.shaderTime * wf->frequency;
|
||||
*amplitude = wf->amplitude;
|
||||
}
|
||||
|
||||
/*
|
||||
** RB_CalcTurbulentTexCoords
|
||||
** RB_CalcScaleTexMatrix
|
||||
*/
|
||||
void RB_CalcTurbulentTexCoords( const waveForm_t *wf, float *st )
|
||||
{
|
||||
int i;
|
||||
float now;
|
||||
|
||||
now = ( wf->phase + tess.shaderTime * wf->frequency );
|
||||
|
||||
for ( i = 0; i < tess.numVertexes; i++, st += 2 )
|
||||
{
|
||||
float s = st[0];
|
||||
float t = st[1];
|
||||
|
||||
st[0] = s + tr.sinTable[ ( ( int ) ( ( ( tess.xyz[i][0] + tess.xyz[i][2] )* 1.0/128 * 0.125 + now ) * FUNCTABLE_SIZE ) ) & ( FUNCTABLE_MASK ) ] * wf->amplitude;
|
||||
st[1] = t + tr.sinTable[ ( ( int ) ( ( tess.xyz[i][1] * 1.0/128 * 0.125 + now ) * FUNCTABLE_SIZE ) ) & ( FUNCTABLE_MASK ) ] * wf->amplitude;
|
||||
}
|
||||
}
|
||||
|
||||
void RB_CalcTurbulentTexMatrix( const waveForm_t *wf, matrix_t matrix )
|
||||
{
|
||||
float now;
|
||||
|
||||
now = ( wf->phase + tess.shaderTime * wf->frequency );
|
||||
|
||||
// bit of a hack here, hide amplitude and now in the matrix
|
||||
// the vertex program will extract them and perform a turbulent pass last if it's nonzero
|
||||
|
||||
matrix[ 0] = 1.0f; matrix[ 4] = 0.0f; matrix[ 8] = 0.0f; matrix[12] = wf->amplitude;
|
||||
matrix[ 1] = 0.0f; matrix[ 5] = 1.0f; matrix[ 9] = 0.0f; matrix[13] = now;
|
||||
matrix[ 2] = 0.0f; matrix[ 6] = 0.0f; matrix[10] = 1.0f; matrix[14] = 0.0f;
|
||||
matrix[ 3] = 0.0f; matrix[ 7] = 0.0f; matrix[11] = 0.0f; matrix[15] = 1.0f;
|
||||
}
|
||||
|
||||
/*
|
||||
** RB_CalcScaleTexCoords
|
||||
*/
|
||||
void RB_CalcScaleTexCoords( const float scale[2], float *st )
|
||||
{
|
||||
int i;
|
||||
|
||||
for ( i = 0; i < tess.numVertexes; i++, st += 2 )
|
||||
{
|
||||
st[0] *= scale[0];
|
||||
st[1] *= scale[1];
|
||||
}
|
||||
}
|
||||
|
||||
void RB_CalcScaleTexMatrix( const float scale[2], float *matrix )
|
||||
{
|
||||
matrix[ 0] = scale[0]; matrix[ 4] = 0.0f; matrix[ 8] = 0.0f; matrix[12] = 0.0f;
|
||||
matrix[ 1] = 0.0f; matrix[ 5] = scale[1]; matrix[ 9] = 0.0f; matrix[13] = 0.0f;
|
||||
matrix[ 2] = 0.0f; matrix[ 6] = 0.0f; matrix[10] = 1.0f; matrix[14] = 0.0f;
|
||||
matrix[ 3] = 0.0f; matrix[ 7] = 0.0f; matrix[11] = 0.0f; matrix[15] = 1.0f;
|
||||
matrix[0] = scale[0]; matrix[2] = 0.0f; matrix[4] = 0.0f;
|
||||
matrix[1] = 0.0f; matrix[3] = scale[1]; matrix[5] = 0.0f;
|
||||
}
|
||||
|
||||
/*
|
||||
** RB_CalcScrollTexCoords
|
||||
** RB_CalcScrollTexMatrix
|
||||
*/
|
||||
void RB_CalcScrollTexCoords( const float scrollSpeed[2], float *st )
|
||||
{
|
||||
int i;
|
||||
float timeScale = tess.shaderTime;
|
||||
float adjustedScrollS, adjustedScrollT;
|
||||
|
||||
adjustedScrollS = scrollSpeed[0] * timeScale;
|
||||
adjustedScrollT = scrollSpeed[1] * timeScale;
|
||||
|
||||
// clamp so coordinates don't continuously get larger, causing problems
|
||||
// with hardware limits
|
||||
adjustedScrollS = adjustedScrollS - floor( adjustedScrollS );
|
||||
adjustedScrollT = adjustedScrollT - floor( adjustedScrollT );
|
||||
|
||||
for ( i = 0; i < tess.numVertexes; i++, st += 2 )
|
||||
{
|
||||
st[0] += adjustedScrollS;
|
||||
st[1] += adjustedScrollT;
|
||||
}
|
||||
}
|
||||
|
||||
void RB_CalcScrollTexMatrix( const float scrollSpeed[2], float *matrix )
|
||||
{
|
||||
float timeScale = tess.shaderTime;
|
||||
|
@ -1053,73 +785,28 @@ void RB_CalcScrollTexMatrix( const float scrollSpeed[2], float *matrix )
|
|||
adjustedScrollS = adjustedScrollS - floor( adjustedScrollS );
|
||||
adjustedScrollT = adjustedScrollT - floor( adjustedScrollT );
|
||||
|
||||
|
||||
matrix[ 0] = 1.0f; matrix[ 4] = 0.0f; matrix[ 8] = adjustedScrollS; matrix[12] = 0.0f;
|
||||
matrix[ 1] = 0.0f; matrix[ 5] = 1.0f; matrix[ 9] = adjustedScrollT; matrix[13] = 0.0f;
|
||||
matrix[ 2] = 0.0f; matrix[ 6] = 0.0f; matrix[10] = 1.0f; matrix[14] = 0.0f;
|
||||
matrix[ 3] = 0.0f; matrix[ 7] = 0.0f; matrix[11] = 0.0f; matrix[15] = 1.0f;
|
||||
matrix[0] = 1.0f; matrix[2] = 0.0f; matrix[4] = adjustedScrollS;
|
||||
matrix[1] = 0.0f; matrix[3] = 1.0f; matrix[5] = adjustedScrollT;
|
||||
}
|
||||
|
||||
/*
|
||||
** RB_CalcTransformTexCoords
|
||||
** RB_CalcTransformTexMatrix
|
||||
*/
|
||||
void RB_CalcTransformTexCoords( const texModInfo_t *tmi, float *st )
|
||||
{
|
||||
int i;
|
||||
|
||||
for ( i = 0; i < tess.numVertexes; i++, st += 2 )
|
||||
{
|
||||
float s = st[0];
|
||||
float t = st[1];
|
||||
|
||||
st[0] = s * tmi->matrix[0][0] + t * tmi->matrix[1][0] + tmi->translate[0];
|
||||
st[1] = s * tmi->matrix[0][1] + t * tmi->matrix[1][1] + tmi->translate[1];
|
||||
}
|
||||
}
|
||||
|
||||
void RB_CalcTransformTexMatrix( const texModInfo_t *tmi, float *matrix )
|
||||
{
|
||||
matrix[ 0] = tmi->matrix[0][0]; matrix[ 4] = tmi->matrix[1][0]; matrix[ 8] = tmi->translate[0]; matrix[12] = 0.0f;
|
||||
matrix[ 1] = tmi->matrix[0][1]; matrix[ 5] = tmi->matrix[1][1]; matrix[ 9] = tmi->translate[1]; matrix[13] = 0.0f;
|
||||
matrix[ 2] = 0.0f; matrix[ 6] = 0.0f; matrix[10] = 1.0f; matrix[14] = 0.0f;
|
||||
matrix[ 3] = 0.0f; matrix[ 7] = 0.0f; matrix[11] = 0.0f; matrix[15] = 1.0f;
|
||||
matrix[0] = tmi->matrix[0][0]; matrix[2] = tmi->matrix[1][0]; matrix[4] = tmi->translate[0];
|
||||
matrix[1] = tmi->matrix[0][1]; matrix[3] = tmi->matrix[1][1]; matrix[5] = tmi->translate[1];
|
||||
}
|
||||
|
||||
/*
|
||||
** RB_CalcRotateTexCoords
|
||||
** RB_CalcRotateTexMatrix
|
||||
*/
|
||||
void RB_CalcRotateTexCoords( float degsPerSecond, float *st )
|
||||
{
|
||||
float timeScale = tess.shaderTime;
|
||||
float degs;
|
||||
int index;
|
||||
float sinValue, cosValue;
|
||||
texModInfo_t tmi;
|
||||
|
||||
degs = -degsPerSecond * timeScale;
|
||||
index = degs * ( FUNCTABLE_SIZE / 360.0f );
|
||||
|
||||
sinValue = tr.sinTable[ index & FUNCTABLE_MASK ];
|
||||
cosValue = tr.sinTable[ ( index + FUNCTABLE_SIZE / 4 ) & FUNCTABLE_MASK ];
|
||||
|
||||
tmi.matrix[0][0] = cosValue;
|
||||
tmi.matrix[1][0] = -sinValue;
|
||||
tmi.translate[0] = 0.5 - 0.5 * cosValue + 0.5 * sinValue;
|
||||
|
||||
tmi.matrix[0][1] = sinValue;
|
||||
tmi.matrix[1][1] = cosValue;
|
||||
tmi.translate[1] = 0.5 - 0.5 * sinValue - 0.5 * cosValue;
|
||||
|
||||
RB_CalcTransformTexCoords( &tmi, st );
|
||||
}
|
||||
|
||||
void RB_CalcRotateTexMatrix( float degsPerSecond, float *matrix )
|
||||
{
|
||||
float timeScale = tess.shaderTime;
|
||||
float degs;
|
||||
int index;
|
||||
float sinValue, cosValue;
|
||||
texModInfo_t tmi;
|
||||
|
||||
degs = -degsPerSecond * timeScale;
|
||||
index = degs * ( FUNCTABLE_SIZE / 360.0f );
|
||||
|
@ -1127,213 +814,6 @@ void RB_CalcRotateTexMatrix( float degsPerSecond, float *matrix )
|
|||
sinValue = tr.sinTable[ index & FUNCTABLE_MASK ];
|
||||
cosValue = tr.sinTable[ ( index + FUNCTABLE_SIZE / 4 ) & FUNCTABLE_MASK ];
|
||||
|
||||
tmi.matrix[0][0] = cosValue;
|
||||
tmi.matrix[1][0] = -sinValue;
|
||||
tmi.translate[0] = 0.5 - 0.5 * cosValue + 0.5 * sinValue;
|
||||
|
||||
tmi.matrix[0][1] = sinValue;
|
||||
tmi.matrix[1][1] = cosValue;
|
||||
tmi.translate[1] = 0.5 - 0.5 * sinValue - 0.5 * cosValue;
|
||||
|
||||
RB_CalcTransformTexMatrix( &tmi, matrix );
|
||||
matrix[0] = cosValue; matrix[2] = -sinValue; matrix[4] = 0.5 - 0.5 * cosValue + 0.5 * sinValue;
|
||||
matrix[1] = sinValue; matrix[3] = cosValue; matrix[5] = 0.5 - 0.5 * sinValue - 0.5 * cosValue;
|
||||
}
|
||||
/*
|
||||
** RB_CalcSpecularAlpha
|
||||
**
|
||||
** Calculates specular coefficient and places it in the alpha channel
|
||||
*/
|
||||
vec3_t lightOrigin = { -960, 1980, 96 }; // FIXME: track dynamically
|
||||
|
||||
void RB_CalcSpecularAlpha( unsigned char *alphas ) {
|
||||
int i;
|
||||
float *v, *normal;
|
||||
vec3_t viewer, reflected;
|
||||
float l, d;
|
||||
int b;
|
||||
vec3_t lightDir;
|
||||
int numVertexes;
|
||||
|
||||
v = tess.xyz[0];
|
||||
normal = tess.normal[0];
|
||||
|
||||
alphas += 3;
|
||||
|
||||
numVertexes = tess.numVertexes;
|
||||
for (i = 0 ; i < numVertexes ; i++, v += 4, normal += 4, alphas += 4) {
|
||||
float ilength;
|
||||
|
||||
VectorSubtract( lightOrigin, v, lightDir );
|
||||
// ilength = Q_rsqrt( DotProduct( lightDir, lightDir ) );
|
||||
VectorNormalizeFast( lightDir );
|
||||
|
||||
// calculate the specular color
|
||||
d = DotProduct (normal, lightDir);
|
||||
// d *= ilength;
|
||||
|
||||
// we don't optimize for the d < 0 case since this tends to
|
||||
// cause visual artifacts such as faceted "snapping"
|
||||
reflected[0] = normal[0]*2*d - lightDir[0];
|
||||
reflected[1] = normal[1]*2*d - lightDir[1];
|
||||
reflected[2] = normal[2]*2*d - lightDir[2];
|
||||
|
||||
VectorSubtract (backEnd.or.viewOrigin, v, viewer);
|
||||
ilength = Q_rsqrt( DotProduct( viewer, viewer ) );
|
||||
l = DotProduct (reflected, viewer);
|
||||
l *= ilength;
|
||||
|
||||
if (l < 0) {
|
||||
b = 0;
|
||||
} else {
|
||||
l = l*l;
|
||||
l = l*l;
|
||||
b = l * 255;
|
||||
if (b > 255) {
|
||||
b = 255;
|
||||
}
|
||||
}
|
||||
|
||||
*alphas = b;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
** RB_CalcDiffuseColor
|
||||
**
|
||||
** The basic vertex lighting calc
|
||||
*/
|
||||
#if idppc_altivec
|
||||
static void RB_CalcDiffuseColor_altivec( unsigned char *colors )
|
||||
{
|
||||
int i;
|
||||
float *v, *normal;
|
||||
trRefEntity_t *ent;
|
||||
int ambientLightInt;
|
||||
vec3_t lightDir;
|
||||
int numVertexes;
|
||||
vector unsigned char vSel = VECCONST_UINT8(0x00, 0x00, 0x00, 0xff,
|
||||
0x00, 0x00, 0x00, 0xff,
|
||||
0x00, 0x00, 0x00, 0xff,
|
||||
0x00, 0x00, 0x00, 0xff);
|
||||
vector float ambientLightVec;
|
||||
vector float directedLightVec;
|
||||
vector float lightDirVec;
|
||||
vector float normalVec0, normalVec1;
|
||||
vector float incomingVec0, incomingVec1, incomingVec2;
|
||||
vector float zero, jVec;
|
||||
vector signed int jVecInt;
|
||||
vector signed short jVecShort;
|
||||
vector unsigned char jVecChar, normalPerm;
|
||||
ent = backEnd.currentEntity;
|
||||
ambientLightInt = ent->ambientLightInt;
|
||||
// A lot of this could be simplified if we made sure
|
||||
// entities light info was 16-byte aligned.
|
||||
jVecChar = vec_lvsl(0, ent->ambientLight);
|
||||
ambientLightVec = vec_ld(0, (vector float *)ent->ambientLight);
|
||||
jVec = vec_ld(11, (vector float *)ent->ambientLight);
|
||||
ambientLightVec = vec_perm(ambientLightVec,jVec,jVecChar);
|
||||
|
||||
jVecChar = vec_lvsl(0, ent->directedLight);
|
||||
directedLightVec = vec_ld(0,(vector float *)ent->directedLight);
|
||||
jVec = vec_ld(11,(vector float *)ent->directedLight);
|
||||
directedLightVec = vec_perm(directedLightVec,jVec,jVecChar);
|
||||
|
||||
jVecChar = vec_lvsl(0, ent->lightDir);
|
||||
lightDirVec = vec_ld(0,(vector float *)ent->lightDir);
|
||||
jVec = vec_ld(11,(vector float *)ent->lightDir);
|
||||
lightDirVec = vec_perm(lightDirVec,jVec,jVecChar);
|
||||
|
||||
zero = (vector float)vec_splat_s8(0);
|
||||
VectorCopy( ent->lightDir, lightDir );
|
||||
|
||||
v = tess.xyz[0];
|
||||
normal = tess.normal[0];
|
||||
|
||||
normalPerm = vec_lvsl(0,normal);
|
||||
numVertexes = tess.numVertexes;
|
||||
for (i = 0 ; i < numVertexes ; i++, v += 4, normal += 4) {
|
||||
normalVec0 = vec_ld(0,(vector float *)normal);
|
||||
normalVec1 = vec_ld(11,(vector float *)normal);
|
||||
normalVec0 = vec_perm(normalVec0,normalVec1,normalPerm);
|
||||
incomingVec0 = vec_madd(normalVec0, lightDirVec, zero);
|
||||
incomingVec1 = vec_sld(incomingVec0,incomingVec0,4);
|
||||
incomingVec2 = vec_add(incomingVec0,incomingVec1);
|
||||
incomingVec1 = vec_sld(incomingVec1,incomingVec1,4);
|
||||
incomingVec2 = vec_add(incomingVec2,incomingVec1);
|
||||
incomingVec0 = vec_splat(incomingVec2,0);
|
||||
incomingVec0 = vec_max(incomingVec0,zero);
|
||||
normalPerm = vec_lvsl(12,normal);
|
||||
jVec = vec_madd(incomingVec0, directedLightVec, ambientLightVec);
|
||||
jVecInt = vec_cts(jVec,0); // RGBx
|
||||
jVecShort = vec_pack(jVecInt,jVecInt); // RGBxRGBx
|
||||
jVecChar = vec_packsu(jVecShort,jVecShort); // RGBxRGBxRGBxRGBx
|
||||
jVecChar = vec_sel(jVecChar,vSel,vSel); // RGBARGBARGBARGBA replace alpha with 255
|
||||
vec_ste((vector unsigned int)jVecChar,0,(unsigned int *)&colors[i*4]); // store color
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
static void RB_CalcDiffuseColor_scalar( unsigned char *colors )
|
||||
{
|
||||
int i, j;
|
||||
float *v, *normal;
|
||||
float incoming;
|
||||
trRefEntity_t *ent;
|
||||
int ambientLightInt;
|
||||
vec3_t ambientLight;
|
||||
vec3_t lightDir;
|
||||
vec3_t directedLight;
|
||||
int numVertexes;
|
||||
ent = backEnd.currentEntity;
|
||||
ambientLightInt = ent->ambientLightInt;
|
||||
VectorCopy( ent->ambientLight, ambientLight );
|
||||
VectorCopy( ent->directedLight, directedLight );
|
||||
VectorCopy( ent->lightDir, lightDir );
|
||||
|
||||
v = tess.xyz[0];
|
||||
normal = tess.normal[0];
|
||||
|
||||
numVertexes = tess.numVertexes;
|
||||
for (i = 0 ; i < numVertexes ; i++, v += 4, normal += 4) {
|
||||
incoming = DotProduct (normal, lightDir);
|
||||
if ( incoming <= 0 ) {
|
||||
*(int *)&colors[i*4] = ambientLightInt;
|
||||
continue;
|
||||
}
|
||||
j = ri.ftol(ambientLight[0] + incoming * directedLight[0]);
|
||||
if ( j > 255 ) {
|
||||
j = 255;
|
||||
}
|
||||
colors[i*4+0] = j;
|
||||
|
||||
j = ri.ftol(ambientLight[1] + incoming * directedLight[1]);
|
||||
if ( j > 255 ) {
|
||||
j = 255;
|
||||
}
|
||||
colors[i*4+1] = j;
|
||||
|
||||
j = ri.ftol(ambientLight[2] + incoming * directedLight[2]);
|
||||
if ( j > 255 ) {
|
||||
j = 255;
|
||||
}
|
||||
colors[i*4+2] = j;
|
||||
|
||||
colors[i*4+3] = 255;
|
||||
}
|
||||
}
|
||||
|
||||
void RB_CalcDiffuseColor( unsigned char *colors )
|
||||
{
|
||||
#if idppc_altivec
|
||||
if (com_altivec->integer) {
|
||||
// must be in a seperate function or G3 systems will crash.
|
||||
RB_CalcDiffuseColor_altivec( colors );
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
RB_CalcDiffuseColor_scalar( colors );
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -203,10 +203,16 @@ static int NameToSrcBlendMode( const char *name )
|
|||
}
|
||||
else if ( !Q_stricmp( name, "GL_DST_ALPHA" ) )
|
||||
{
|
||||
if (r_ignoreDstAlpha->integer)
|
||||
return GLS_SRCBLEND_ONE;
|
||||
|
||||
return GLS_SRCBLEND_DST_ALPHA;
|
||||
}
|
||||
else if ( !Q_stricmp( name, "GL_ONE_MINUS_DST_ALPHA" ) )
|
||||
{
|
||||
if (r_ignoreDstAlpha->integer)
|
||||
return GLS_SRCBLEND_ZERO;
|
||||
|
||||
return GLS_SRCBLEND_ONE_MINUS_DST_ALPHA;
|
||||
}
|
||||
else if ( !Q_stricmp( name, "GL_SRC_ALPHA_SATURATE" ) )
|
||||
|
@ -243,10 +249,16 @@ static int NameToDstBlendMode( const char *name )
|
|||
}
|
||||
else if ( !Q_stricmp( name, "GL_DST_ALPHA" ) )
|
||||
{
|
||||
if (r_ignoreDstAlpha->integer)
|
||||
return GLS_DSTBLEND_ONE;
|
||||
|
||||
return GLS_DSTBLEND_DST_ALPHA;
|
||||
}
|
||||
else if ( !Q_stricmp( name, "GL_ONE_MINUS_DST_ALPHA" ) )
|
||||
{
|
||||
if (r_ignoreDstAlpha->integer)
|
||||
return GLS_DSTBLEND_ZERO;
|
||||
|
||||
return GLS_DSTBLEND_ONE_MINUS_DST_ALPHA;
|
||||
}
|
||||
else if ( !Q_stricmp( name, "GL_SRC_COLOR" ) )
|
||||
|
@ -1109,10 +1121,6 @@ static qboolean ParseStage( shaderStage_t *stage, char **text )
|
|||
shader.portalRange = atof( token );
|
||||
}
|
||||
}
|
||||
else if ( !Q_stricmp( token, "fresnel" ) )
|
||||
{
|
||||
stage->alphaGen = AGEN_FRESNEL;
|
||||
}
|
||||
else
|
||||
{
|
||||
ri.Printf( PRINT_WARNING, "WARNING: unknown alphaGen parameter '%s' in shader '%s'\n", token, shader.name );
|
||||
|
@ -1951,7 +1959,7 @@ static void ComputeVertexAttribs(void)
|
|||
#ifdef USE_VERT_TANGENT_SPACE
|
||||
if ((pStage->glslShaderIndex & LIGHTDEF_LIGHTTYPE_MASK) && !(r_normalMapping->integer == 0 && r_specularMapping->integer == 0))
|
||||
{
|
||||
shader.vertexAttribs |= ATTR_BITANGENT | ATTR_TANGENT;
|
||||
shader.vertexAttribs |= ATTR_TANGENT;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -2011,7 +2019,6 @@ static void ComputeVertexAttribs(void)
|
|||
switch(pStage->alphaGen)
|
||||
{
|
||||
case AGEN_LIGHTING_SPECULAR:
|
||||
case AGEN_FRESNEL:
|
||||
shader.vertexAttribs |= ATTR_NORMAL;
|
||||
break;
|
||||
|
||||
|
@ -2213,7 +2220,6 @@ static void CollapseStagesToLightall(shaderStage_t *diffuse,
|
|||
//ri.Printf(PRINT_ALL, ", deluxemap");
|
||||
diffuse->bundle[TB_DELUXEMAP] = lightmap->bundle[0];
|
||||
diffuse->bundle[TB_DELUXEMAP].image[0] = tr.deluxemaps[shader.lightmapIndex];
|
||||
defs |= LIGHTDEF_USE_DELUXEMAP;
|
||||
}
|
||||
|
||||
if (r_normalMapping->integer)
|
||||
|
@ -2247,15 +2253,6 @@ static void CollapseStagesToLightall(shaderStage_t *diffuse,
|
|||
defs |= LIGHTDEF_USE_PARALLAXMAP;
|
||||
}
|
||||
}
|
||||
|
||||
if (!diffuse->bundle[TB_NORMALMAP].image[0])
|
||||
{
|
||||
// use 0x80 image, shader will interpret as (0,0,1)
|
||||
diffuse->bundle[TB_NORMALMAP] = diffuse->bundle[0];
|
||||
diffuse->bundle[TB_NORMALMAP].numImageAnimations = 0;
|
||||
diffuse->bundle[TB_NORMALMAP].image[0] = tr.greyImage;
|
||||
//ri.Printf(PRINT_ALL, ", normalmap %s", diffuse->bundle[TB_NORMALMAP].image[0]->imgName);
|
||||
}
|
||||
}
|
||||
|
||||
if (r_specularMapping->integer)
|
||||
|
@ -2267,18 +2264,6 @@ static void CollapseStagesToLightall(shaderStage_t *diffuse,
|
|||
diffuse->materialInfo[0] = specular->materialInfo[0];
|
||||
diffuse->materialInfo[1] = specular->materialInfo[1];
|
||||
}
|
||||
else if (lightmap || useLightVector || useLightVertex)
|
||||
{
|
||||
// use a white image, materialinfo will do the rest
|
||||
diffuse->bundle[TB_SPECULARMAP] = diffuse->bundle[0];
|
||||
diffuse->bundle[TB_SPECULARMAP].numImageAnimations = 0;
|
||||
diffuse->bundle[TB_SPECULARMAP].image[0] = tr.whiteImage;
|
||||
if (!diffuse->materialInfo[0])
|
||||
diffuse->materialInfo[0] = r_baseSpecular->value;
|
||||
if (!diffuse->materialInfo[1])
|
||||
diffuse->materialInfo[1] = r_baseGloss->value;
|
||||
//ri.Printf(PRINT_ALL, ", specularmap %s", diffuse->bundle[TB_SPECULARMAP].image[0]->imgName);
|
||||
}
|
||||
}
|
||||
|
||||
if (tcgen || diffuse->bundle[0].numTexMods)
|
||||
|
@ -2308,7 +2293,7 @@ static qboolean CollapseStagesToGLSL(void)
|
|||
{
|
||||
// if 2+ stages and first stage is lightmap, switch them
|
||||
// this makes it easier for the later bits to process
|
||||
if (stages[0].active && stages[0].bundle[0].isLightmap && stages[1].active)
|
||||
if (stages[0].active && stages[0].bundle[0].tcGen == TCGEN_LIGHTMAP && stages[1].active)
|
||||
{
|
||||
int blendBits = stages[1].stateBits & ( GLS_DSTBLEND_BITS | GLS_SRCBLEND_BITS );
|
||||
|
||||
|
@ -2345,7 +2330,7 @@ static qboolean CollapseStagesToGLSL(void)
|
|||
break;
|
||||
}
|
||||
|
||||
if (pStage->bundle[0].isLightmap)
|
||||
if (pStage->bundle[0].tcGen == TCGEN_LIGHTMAP)
|
||||
{
|
||||
int blendBits = pStage->stateBits & ( GLS_DSTBLEND_BITS | GLS_SRCBLEND_BITS );
|
||||
|
||||
|
@ -2362,6 +2347,7 @@ static qboolean CollapseStagesToGLSL(void)
|
|||
case TCGEN_TEXTURE:
|
||||
case TCGEN_LIGHTMAP:
|
||||
case TCGEN_ENVIRONMENT_MAPPED:
|
||||
case TCGEN_VECTOR:
|
||||
break;
|
||||
default:
|
||||
skip = qtrue;
|
||||
|
@ -2372,7 +2358,6 @@ static qboolean CollapseStagesToGLSL(void)
|
|||
{
|
||||
case AGEN_LIGHTING_SPECULAR:
|
||||
case AGEN_PORTAL:
|
||||
case AGEN_FRESNEL:
|
||||
skip = qtrue;
|
||||
break;
|
||||
default:
|
||||
|
@ -2397,7 +2382,7 @@ static qboolean CollapseStagesToGLSL(void)
|
|||
continue;
|
||||
|
||||
// skip lightmaps
|
||||
if (pStage->bundle[0].isLightmap)
|
||||
if (pStage->bundle[0].tcGen == TCGEN_LIGHTMAP)
|
||||
continue;
|
||||
|
||||
diffuse = pStage;
|
||||
|
@ -2439,7 +2424,7 @@ static qboolean CollapseStagesToGLSL(void)
|
|||
break;
|
||||
|
||||
case ST_COLORMAP:
|
||||
if (pStage2->bundle[0].isLightmap)
|
||||
if (pStage2->bundle[0].tcGen == TCGEN_LIGHTMAP)
|
||||
{
|
||||
lightmap = pStage2;
|
||||
}
|
||||
|
@ -2481,7 +2466,7 @@ static qboolean CollapseStagesToGLSL(void)
|
|||
if (!pStage->active)
|
||||
continue;
|
||||
|
||||
if (pStage->bundle[0].isLightmap)
|
||||
if (pStage->bundle[0].tcGen == TCGEN_LIGHTMAP)
|
||||
{
|
||||
pStage->active = qfalse;
|
||||
}
|
||||
|
@ -2547,15 +2532,14 @@ static qboolean CollapseStagesToGLSL(void)
|
|||
if (pStage->adjustColorsForFog)
|
||||
continue;
|
||||
|
||||
if (pStage->bundle[TB_DIFFUSEMAP].isLightmap)
|
||||
if (pStage->bundle[TB_DIFFUSEMAP].tcGen == TCGEN_LIGHTMAP)
|
||||
{
|
||||
pStage->glslShaderGroup = tr.lightallShader;
|
||||
pStage->glslShaderIndex = LIGHTDEF_USE_LIGHTMAP;
|
||||
if (r_deluxeMapping->integer && tr.worldDeluxeMapping)
|
||||
pStage->glslShaderIndex |= LIGHTDEF_USE_DELUXEMAP;
|
||||
pStage->bundle[TB_LIGHTMAP] = pStage->bundle[TB_DIFFUSEMAP];
|
||||
pStage->bundle[TB_DIFFUSEMAP].image[0] = tr.whiteImage;
|
||||
pStage->bundle[TB_DIFFUSEMAP].isLightmap = qfalse;
|
||||
pStage->bundle[TB_DIFFUSEMAP].tcGen = TCGEN_TEXTURE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2577,11 +2561,14 @@ static qboolean CollapseStagesToGLSL(void)
|
|||
{
|
||||
pStage->glslShaderGroup = tr.lightallShader;
|
||||
pStage->glslShaderIndex = LIGHTDEF_USE_LIGHT_VECTOR;
|
||||
|
||||
if (pStage->bundle[0].tcGen != TCGEN_TEXTURE || pStage->bundle[0].numTexMods != 0)
|
||||
pStage->glslShaderIndex |= LIGHTDEF_USE_TCGEN_AND_TCMOD;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// convert any remaining lightingdiffuse stages to a lighting pass
|
||||
// insert default material info if needed
|
||||
for (i = 0; i < MAX_SHADER_STAGES; i++)
|
||||
{
|
||||
shaderStage_t *pStage = &stages[i];
|
||||
|
@ -2589,14 +2576,21 @@ static qboolean CollapseStagesToGLSL(void)
|
|||
if (!pStage->active)
|
||||
continue;
|
||||
|
||||
if (pStage->rgbGen == CGEN_LIGHTING_DIFFUSE)
|
||||
if (pStage->glslShaderGroup != tr.lightallShader)
|
||||
continue;
|
||||
|
||||
if ((pStage->glslShaderIndex & LIGHTDEF_LIGHTTYPE_MASK) == 0)
|
||||
continue;
|
||||
|
||||
if (!pStage->bundle[TB_SPECULARMAP].image[0] && r_specularMapping->integer)
|
||||
{
|
||||
pStage->glslShaderGroup = tr.lightallShader;
|
||||
pStage->glslShaderIndex = LIGHTDEF_USE_LIGHT_VECTOR;
|
||||
if (!pStage->materialInfo[0])
|
||||
pStage->materialInfo[0] = r_baseSpecular->value;
|
||||
if (!pStage->materialInfo[1])
|
||||
pStage->materialInfo[1] = r_baseGloss->value;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return numStages;
|
||||
}
|
||||
|
||||
|
|
|
@ -429,7 +429,7 @@ static void DrawSkySide( struct image_s *image, const int mins[2], const int max
|
|||
GLSL_VertexAttribsState(ATTR_POSITION | ATTR_TEXCOORD);
|
||||
GLSL_BindProgram(sp);
|
||||
|
||||
GLSL_SetUniformMatrix16(sp, UNIFORM_MODELVIEWPROJECTIONMATRIX, glState.modelviewProjection);
|
||||
GLSL_SetUniformMat4(sp, UNIFORM_MODELVIEWPROJECTIONMATRIX, glState.modelviewProjection);
|
||||
|
||||
color[0] =
|
||||
color[1] =
|
||||
|
@ -445,11 +445,11 @@ static void DrawSkySide( struct image_s *image, const int mins[2], const int max
|
|||
GLSL_VertexAttribsState(ATTR_POSITION | ATTR_TEXCOORD);
|
||||
GLSL_BindProgram(sp);
|
||||
|
||||
GLSL_SetUniformMatrix16(sp, UNIFORM_MODELVIEWPROJECTIONMATRIX, glState.modelviewProjection);
|
||||
GLSL_SetUniformMat4(sp, UNIFORM_MODELVIEWPROJECTIONMATRIX, glState.modelviewProjection);
|
||||
|
||||
color[0] =
|
||||
color[1] =
|
||||
color[2] = tr.identityLight * backEnd.refdef.colorScale;
|
||||
color[2] = (r_softOverbright->integer ? 1.0 : tr.identityLight) * backEnd.refdef.colorScale;
|
||||
color[3] = 1.0f;
|
||||
GLSL_SetUniformVec4(sp, UNIFORM_BASECOLOR, color);
|
||||
|
||||
|
@ -468,7 +468,7 @@ static void DrawSkySide( struct image_s *image, const int mins[2], const int max
|
|||
|
||||
R_DrawElementsVBO(tess.numIndexes - tess.firstIndex, tess.firstIndex, tess.minIndex, tess.maxIndex);
|
||||
|
||||
//qglDrawElements(GL_TRIANGLES, tess.numIndexes - tess.firstIndex, GL_INDEX_TYPE, BUFFER_OFFSET(tess.firstIndex * sizeof(GL_INDEX_TYPE)));
|
||||
//qglDrawElements(GL_TRIANGLES, tess.numIndexes - tess.firstIndex, GL_INDEX_TYPE, BUFFER_OFFSET(tess.firstIndex * sizeof(glIndex_t)));
|
||||
|
||||
//R_BindNullVBO();
|
||||
//R_BindNullIBO();
|
||||
|
@ -806,10 +806,10 @@ void RB_DrawSun( float scale, shader_t *shader ) {
|
|||
//qglTranslatef (backEnd.viewParms.or.origin[0], backEnd.viewParms.or.origin[1], backEnd.viewParms.or.origin[2]);
|
||||
{
|
||||
// FIXME: this could be a lot cleaner
|
||||
matrix_t translation, modelview;
|
||||
mat4_t translation, modelview;
|
||||
|
||||
Matrix16Translation( backEnd.viewParms.or.origin, translation );
|
||||
Matrix16Multiply( backEnd.viewParms.world.modelMatrix, translation, modelview );
|
||||
Mat4Translation( backEnd.viewParms.or.origin, translation );
|
||||
Mat4Multiply( backEnd.viewParms.world.modelMatrix, translation, modelview );
|
||||
GL_SetModelviewMatrix( modelview );
|
||||
}
|
||||
|
||||
|
@ -869,18 +869,18 @@ void RB_StageIteratorSky( void ) {
|
|||
|
||||
// draw the outer skybox
|
||||
if ( tess.shader->sky.outerbox[0] && tess.shader->sky.outerbox[0] != tr.defaultImage ) {
|
||||
matrix_t oldmodelview;
|
||||
mat4_t oldmodelview;
|
||||
|
||||
GL_State( 0 );
|
||||
//qglTranslatef (backEnd.viewParms.or.origin[0], backEnd.viewParms.or.origin[1], backEnd.viewParms.or.origin[2]);
|
||||
|
||||
{
|
||||
// FIXME: this could be a lot cleaner
|
||||
matrix_t trans, product;
|
||||
mat4_t trans, product;
|
||||
|
||||
Matrix16Copy( glState.modelview, oldmodelview );
|
||||
Matrix16Translation( backEnd.viewParms.or.origin, trans );
|
||||
Matrix16Multiply( glState.modelview, trans, product );
|
||||
Mat4Copy( glState.modelview, oldmodelview );
|
||||
Mat4Translation( backEnd.viewParms.or.origin, trans );
|
||||
Mat4Multiply( glState.modelview, trans, product );
|
||||
GL_SetModelviewMatrix( product );
|
||||
|
||||
}
|
||||
|
|
|
@ -124,11 +124,11 @@ void RB_AddQuadStampExt( vec3_t origin, vec3_t left, vec3_t up, float color[4],
|
|||
// constant normal all the way around
|
||||
VectorSubtract( vec3_origin, backEnd.viewParms.or.axis[0], normal );
|
||||
|
||||
VectorCopy(normal, tess.normal[ndx]);
|
||||
VectorCopy(normal, tess.normal[ndx+1]);
|
||||
VectorCopy(normal, tess.normal[ndx+2]);
|
||||
VectorCopy(normal, tess.normal[ndx+3]);
|
||||
|
||||
tess.normal[ndx] =
|
||||
tess.normal[ndx+1] =
|
||||
tess.normal[ndx+2] =
|
||||
tess.normal[ndx+3] = R_VboPackNormal(normal);
|
||||
|
||||
// standard square texture coordinates
|
||||
VectorSet2(tess.texCoords[ndx ][0], s1, t1);
|
||||
VectorSet2(tess.texCoords[ndx ][1], s1, t1);
|
||||
|
@ -228,7 +228,7 @@ void RB_InstantQuad(vec4_t quadVerts[4])
|
|||
|
||||
GLSL_BindProgram(&tr.textureColorShader);
|
||||
|
||||
GLSL_SetUniformMatrix16(&tr.textureColorShader, UNIFORM_MODELVIEWPROJECTIONMATRIX, glState.modelviewProjection);
|
||||
GLSL_SetUniformMat4(&tr.textureColorShader, UNIFORM_MODELVIEWPROJECTIONMATRIX, glState.modelviewProjection);
|
||||
GLSL_SetUniformVec4(&tr.textureColorShader, UNIFORM_COLOR, colorWhite);
|
||||
|
||||
RB_InstantQuad2(quadVerts, texCoords);
|
||||
|
@ -311,30 +311,30 @@ static void RB_SurfacePolychain( srfPoly_t *p ) {
|
|||
tess.numVertexes = numv;
|
||||
}
|
||||
|
||||
static void RB_SurfaceVertsAndTris( int numVerts, srfVert_t *verts, int numTriangles, srfTriangle_t *triangles, int dlightBits, int pshadowBits)
|
||||
static void RB_SurfaceVertsAndIndexes( int numVerts, srfVert_t *verts, int numIndexes, glIndex_t *indexes, int dlightBits, int pshadowBits)
|
||||
{
|
||||
int i;
|
||||
srfTriangle_t *tri;
|
||||
glIndex_t *inIndex;
|
||||
srfVert_t *dv;
|
||||
float *xyz, *normal, *texCoords, *lightCoords, *lightdir;
|
||||
float *xyz, *texCoords, *lightCoords;
|
||||
uint32_t *lightdir;
|
||||
uint32_t *normal;
|
||||
#ifdef USE_VERT_TANGENT_SPACE
|
||||
float *tangent, *bitangent;
|
||||
uint32_t *tangent;
|
||||
#endif
|
||||
glIndex_t *index;
|
||||
glIndex_t *outIndex;
|
||||
float *color;
|
||||
|
||||
RB_CheckVBOandIBO(tess.vbo, tess.ibo);
|
||||
|
||||
RB_CHECKOVERFLOW( numVerts, numTriangles * 3 );
|
||||
RB_CHECKOVERFLOW( numVerts, numIndexes );
|
||||
|
||||
tri = triangles;
|
||||
index = &tess.indexes[ tess.numIndexes ];
|
||||
for ( i = 0 ; i < numTriangles ; i++, tri++ ) {
|
||||
*index++ = tess.numVertexes + tri->indexes[0];
|
||||
*index++ = tess.numVertexes + tri->indexes[1];
|
||||
*index++ = tess.numVertexes + tri->indexes[2];
|
||||
inIndex = indexes;
|
||||
outIndex = &tess.indexes[ tess.numIndexes ];
|
||||
for ( i = 0 ; i < numIndexes ; i++ ) {
|
||||
*outIndex++ = tess.numVertexes + *inIndex++;
|
||||
}
|
||||
tess.numIndexes += numTriangles * 3;
|
||||
tess.numIndexes += numIndexes;
|
||||
|
||||
if ( tess.shader->vertexAttribs & ATTR_POSITION )
|
||||
{
|
||||
|
@ -347,26 +347,18 @@ static void RB_SurfaceVertsAndTris( int numVerts, srfVert_t *verts, int numTrian
|
|||
if ( tess.shader->vertexAttribs & ATTR_NORMAL )
|
||||
{
|
||||
dv = verts;
|
||||
normal = tess.normal[ tess.numVertexes ];
|
||||
for ( i = 0 ; i < numVerts ; i++, dv++, normal+=4 )
|
||||
VectorCopy(dv->normal, normal);
|
||||
normal = &tess.normal[ tess.numVertexes ];
|
||||
for ( i = 0 ; i < numVerts ; i++, dv++, normal++ )
|
||||
*normal = R_VboPackNormal(dv->normal);
|
||||
}
|
||||
|
||||
#ifdef USE_VERT_TANGENT_SPACE
|
||||
if ( tess.shader->vertexAttribs & ATTR_TANGENT )
|
||||
{
|
||||
dv = verts;
|
||||
tangent = tess.tangent[ tess.numVertexes ];
|
||||
for ( i = 0 ; i < numVerts ; i++, dv++, tangent+=4 )
|
||||
VectorCopy(dv->tangent, tangent);
|
||||
}
|
||||
|
||||
if ( tess.shader->vertexAttribs & ATTR_BITANGENT )
|
||||
{
|
||||
dv = verts;
|
||||
bitangent = tess.bitangent[ tess.numVertexes ];
|
||||
for ( i = 0 ; i < numVerts ; i++, dv++, bitangent+=4 )
|
||||
VectorCopy(dv->bitangent, bitangent);
|
||||
tangent = &tess.tangent[ tess.numVertexes ];
|
||||
for ( i = 0 ; i < numVerts ; i++, dv++, tangent++ )
|
||||
*tangent = R_VboPackTangent(dv->tangent);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -397,9 +389,9 @@ static void RB_SurfaceVertsAndTris( int numVerts, srfVert_t *verts, int numTrian
|
|||
if ( tess.shader->vertexAttribs & ATTR_LIGHTDIRECTION )
|
||||
{
|
||||
dv = verts;
|
||||
lightdir = tess.lightdir[ tess.numVertexes ];
|
||||
for ( i = 0 ; i < numVerts ; i++, dv++, lightdir+=4 )
|
||||
VectorCopy(dv->lightdir, lightdir);
|
||||
lightdir = &tess.lightdir[ tess.numVertexes ];
|
||||
for ( i = 0 ; i < numVerts ; i++, dv++, lightdir++ )
|
||||
*lightdir = R_VboPackNormal(dv->lightdir);
|
||||
}
|
||||
|
||||
#if 0 // nothing even uses vertex dlightbits
|
||||
|
@ -437,8 +429,8 @@ static qboolean RB_SurfaceVbo(VBO_t *vbo, IBO_t *ibo, int numVerts, int numIndex
|
|||
// merge this into any existing multidraw primitives
|
||||
mergeForward = -1;
|
||||
mergeBack = -1;
|
||||
firstIndexOffset = BUFFER_OFFSET(firstIndex * sizeof(GL_INDEX_TYPE));
|
||||
lastIndexOffset = BUFFER_OFFSET((firstIndex + numIndexes) * sizeof(GL_INDEX_TYPE));
|
||||
firstIndexOffset = BUFFER_OFFSET(firstIndex * sizeof(glIndex_t));
|
||||
lastIndexOffset = BUFFER_OFFSET((firstIndex + numIndexes) * sizeof(glIndex_t));
|
||||
|
||||
if (r_mergeMultidraws->integer)
|
||||
{
|
||||
|
@ -522,15 +514,15 @@ static qboolean RB_SurfaceVbo(VBO_t *vbo, IBO_t *ibo, int numVerts, int numIndex
|
|||
RB_SurfaceTriangles
|
||||
=============
|
||||
*/
|
||||
static void RB_SurfaceTriangles( srfTriangles_t *srf ) {
|
||||
if( RB_SurfaceVbo (srf->vbo, srf->ibo, srf->numVerts, srf->numTriangles * 3,
|
||||
static void RB_SurfaceTriangles( srfBspSurface_t *srf ) {
|
||||
if( RB_SurfaceVbo (srf->vbo, srf->ibo, srf->numVerts, srf->numIndexes,
|
||||
srf->firstIndex, srf->minIndex, srf->maxIndex, srf->dlightBits, srf->pshadowBits, qtrue ) )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
RB_SurfaceVertsAndTris(srf->numVerts, srf->verts, srf->numTriangles,
|
||||
srf->triangles, srf->dlightBits, srf->pshadowBits);
|
||||
RB_SurfaceVertsAndIndexes(srf->numVerts, srf->verts, srf->numIndexes,
|
||||
srf->indexes, srf->dlightBits, srf->pshadowBits);
|
||||
}
|
||||
|
||||
|
||||
|
@ -614,7 +606,7 @@ static void RB_SurfaceBeam( void )
|
|||
GLSL_VertexAttribsState(ATTR_POSITION);
|
||||
GLSL_BindProgram(sp);
|
||||
|
||||
GLSL_SetUniformMatrix16(sp, UNIFORM_MODELVIEWPROJECTIONMATRIX, glState.modelviewProjection);
|
||||
GLSL_SetUniformMat4(sp, UNIFORM_MODELVIEWPROJECTIONMATRIX, glState.modelviewProjection);
|
||||
|
||||
GLSL_SetUniformVec4(sp, UNIFORM_COLOR, colorRed);
|
||||
|
||||
|
@ -840,6 +832,7 @@ static void RB_SurfaceLightningBolt( void ) {
|
|||
}
|
||||
}
|
||||
|
||||
#if 0
|
||||
/*
|
||||
** VectorArrayNormalize
|
||||
*
|
||||
|
@ -895,12 +888,14 @@ static void VectorArrayNormalize(vec4_t *normals, unsigned int count)
|
|||
#endif
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
/*
|
||||
** LerpMeshVertexes
|
||||
*/
|
||||
#if 0
|
||||
#if idppc_altivec
|
||||
static void LerpMeshVertexes_altivec(md3Surface_t *surf, float backlerp)
|
||||
{
|
||||
|
@ -1030,6 +1025,7 @@ static void LerpMeshVertexes_altivec(md3Surface_t *surf, float backlerp)
|
|||
}
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
static void LerpMeshVertexes_scalar(mdvSurface_t *surf, float backlerp)
|
||||
{
|
||||
|
@ -1129,14 +1125,15 @@ static void LerpMeshVertexes_scalar(mdvSurface_t *surf, float backlerp)
|
|||
VectorArrayNormalize((vec4_t *)tess.normal[tess.numVertexes], numVerts);
|
||||
}
|
||||
#endif
|
||||
float *outXyz, *outNormal;
|
||||
float *outXyz;
|
||||
uint32_t *outNormal;
|
||||
mdvVertex_t *newVerts;
|
||||
int vertNum;
|
||||
|
||||
newVerts = surf->verts + backEnd.currentEntity->e.frame * surf->numVerts;
|
||||
|
||||
outXyz = tess.xyz[tess.numVertexes];
|
||||
outNormal = tess.normal[tess.numVertexes];
|
||||
outNormal = &tess.normal[tess.numVertexes];
|
||||
|
||||
if (backlerp == 0)
|
||||
{
|
||||
|
@ -1146,11 +1143,16 @@ static void LerpMeshVertexes_scalar(mdvSurface_t *surf, float backlerp)
|
|||
|
||||
for (vertNum=0 ; vertNum < surf->numVerts ; vertNum++)
|
||||
{
|
||||
vec3_t normal;
|
||||
|
||||
VectorCopy(newVerts->xyz, outXyz);
|
||||
VectorCopy(newVerts->normal, outNormal);
|
||||
VectorCopy(newVerts->normal, normal);
|
||||
|
||||
*outNormal = R_VboPackNormal(normal);
|
||||
|
||||
newVerts++;
|
||||
outXyz += 4;
|
||||
outNormal += 4;
|
||||
outNormal++;
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -1165,15 +1167,19 @@ static void LerpMeshVertexes_scalar(mdvSurface_t *surf, float backlerp)
|
|||
|
||||
for (vertNum=0 ; vertNum < surf->numVerts ; vertNum++)
|
||||
{
|
||||
vec3_t normal;
|
||||
|
||||
VectorLerp(newVerts->xyz, oldVerts->xyz, backlerp, outXyz);
|
||||
VectorLerp(newVerts->normal, oldVerts->normal, backlerp, outNormal);
|
||||
//VectorNormalize(outNormal);
|
||||
VectorLerp(newVerts->normal, oldVerts->normal, backlerp, normal);
|
||||
VectorNormalize(normal);
|
||||
|
||||
*outNormal = R_VboPackNormal(normal);
|
||||
|
||||
newVerts++;
|
||||
oldVerts++;
|
||||
outXyz += 4;
|
||||
outNormal += 4;
|
||||
outNormal++;
|
||||
}
|
||||
VectorArrayNormalize((vec4_t *)tess.normal[tess.numVertexes], surf->numVerts);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1201,9 +1207,7 @@ RB_SurfaceMesh
|
|||
static void RB_SurfaceMesh(mdvSurface_t *surface) {
|
||||
int j;
|
||||
float backlerp;
|
||||
srfTriangle_t *triangles;
|
||||
mdvSt_t *texCoords;
|
||||
int indexes;
|
||||
int Bob, Doug;
|
||||
int numVerts;
|
||||
|
||||
|
@ -1213,20 +1217,16 @@ static void RB_SurfaceMesh(mdvSurface_t *surface) {
|
|||
backlerp = backEnd.currentEntity->e.backlerp;
|
||||
}
|
||||
|
||||
RB_CHECKOVERFLOW( surface->numVerts, surface->numTriangles*3 );
|
||||
RB_CHECKOVERFLOW( surface->numVerts, surface->numIndexes );
|
||||
|
||||
LerpMeshVertexes (surface, backlerp);
|
||||
|
||||
triangles = surface->triangles;
|
||||
indexes = surface->numTriangles * 3;
|
||||
Bob = tess.numIndexes;
|
||||
Doug = tess.numVertexes;
|
||||
for (j = 0 ; j < surface->numTriangles ; j++) {
|
||||
tess.indexes[Bob + j*3 + 0] = Doug + triangles[j].indexes[0];
|
||||
tess.indexes[Bob + j*3 + 1] = Doug + triangles[j].indexes[1];
|
||||
tess.indexes[Bob + j*3 + 2] = Doug + triangles[j].indexes[2];
|
||||
for (j = 0 ; j < surface->numIndexes ; j++) {
|
||||
tess.indexes[Bob + j] = Doug + surface->indexes[j];
|
||||
}
|
||||
tess.numIndexes += indexes;
|
||||
tess.numIndexes += surface->numIndexes;
|
||||
|
||||
texCoords = surface->st;
|
||||
|
||||
|
@ -1247,15 +1247,15 @@ static void RB_SurfaceMesh(mdvSurface_t *surface) {
|
|||
RB_SurfaceFace
|
||||
==============
|
||||
*/
|
||||
static void RB_SurfaceFace( srfSurfaceFace_t *srf ) {
|
||||
if( RB_SurfaceVbo (srf->vbo, srf->ibo, srf->numVerts, srf->numTriangles * 3,
|
||||
static void RB_SurfaceFace( srfBspSurface_t *srf ) {
|
||||
if( RB_SurfaceVbo (srf->vbo, srf->ibo, srf->numVerts, srf->numIndexes,
|
||||
srf->firstIndex, srf->minIndex, srf->maxIndex, srf->dlightBits, srf->pshadowBits, qtrue ) )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
RB_SurfaceVertsAndTris(srf->numVerts, srf->verts, srf->numTriangles,
|
||||
srf->triangles, srf->dlightBits, srf->pshadowBits);
|
||||
RB_SurfaceVertsAndIndexes(srf->numVerts, srf->verts, srf->numIndexes,
|
||||
srf->indexes, srf->dlightBits, srf->pshadowBits);
|
||||
}
|
||||
|
||||
|
||||
|
@ -1296,15 +1296,16 @@ RB_SurfaceGrid
|
|||
Just copy the grid of points and triangulate
|
||||
=============
|
||||
*/
|
||||
static void RB_SurfaceGrid( srfGridMesh_t *srf ) {
|
||||
static void RB_SurfaceGrid( srfBspSurface_t *srf ) {
|
||||
int i, j;
|
||||
float *xyz;
|
||||
float *texCoords, *lightCoords;
|
||||
float *normal;
|
||||
uint32_t *normal;
|
||||
#ifdef USE_VERT_TANGENT_SPACE
|
||||
float *tangent, *bitangent;
|
||||
uint32_t *tangent;
|
||||
#endif
|
||||
float *color, *lightdir;
|
||||
float *color;
|
||||
uint32_t *lightdir;
|
||||
srfVert_t *dv;
|
||||
int rows, irows, vrows;
|
||||
int used;
|
||||
|
@ -1317,7 +1318,7 @@ static void RB_SurfaceGrid( srfGridMesh_t *srf ) {
|
|||
int pshadowBits;
|
||||
//int *vDlightBits;
|
||||
|
||||
if( RB_SurfaceVbo (srf->vbo, srf->ibo, srf->numVerts, srf->numTriangles * 3,
|
||||
if( RB_SurfaceVbo (srf->vbo, srf->ibo, srf->numVerts, srf->numIndexes,
|
||||
srf->firstIndex, srf->minIndex, srf->maxIndex, srf->dlightBits, srf->pshadowBits, qtrue ) )
|
||||
{
|
||||
return;
|
||||
|
@ -1387,15 +1388,14 @@ static void RB_SurfaceGrid( srfGridMesh_t *srf ) {
|
|||
numVertexes = tess.numVertexes;
|
||||
|
||||
xyz = tess.xyz[numVertexes];
|
||||
normal = tess.normal[numVertexes];
|
||||
normal = &tess.normal[numVertexes];
|
||||
#ifdef USE_VERT_TANGENT_SPACE
|
||||
tangent = tess.tangent[numVertexes];
|
||||
bitangent = tess.bitangent[numVertexes];
|
||||
tangent = &tess.tangent[numVertexes];
|
||||
#endif
|
||||
texCoords = tess.texCoords[numVertexes][0];
|
||||
lightCoords = tess.texCoords[numVertexes][1];
|
||||
color = tess.vertexColors[numVertexes];
|
||||
lightdir = tess.lightdir[numVertexes];
|
||||
lightdir = &tess.lightdir[numVertexes];
|
||||
//vDlightBits = &tess.vertexDlightBits[numVertexes];
|
||||
|
||||
for ( i = 0 ; i < rows ; i++ ) {
|
||||
|
@ -1411,21 +1411,13 @@ static void RB_SurfaceGrid( srfGridMesh_t *srf ) {
|
|||
|
||||
if ( tess.shader->vertexAttribs & ATTR_NORMAL )
|
||||
{
|
||||
VectorCopy(dv->normal, normal);
|
||||
normal += 4;
|
||||
*normal++ = R_VboPackNormal(dv->normal);
|
||||
}
|
||||
|
||||
#ifdef USE_VERT_TANGENT_SPACE
|
||||
if ( tess.shader->vertexAttribs & ATTR_TANGENT )
|
||||
{
|
||||
VectorCopy(dv->tangent, tangent);
|
||||
tangent += 4;
|
||||
}
|
||||
|
||||
if ( tess.shader->vertexAttribs & ATTR_BITANGENT )
|
||||
{
|
||||
VectorCopy(dv->bitangent, bitangent);
|
||||
bitangent += 4;
|
||||
*tangent++ = R_VboPackTangent(dv->tangent);
|
||||
}
|
||||
#endif
|
||||
if ( tess.shader->vertexAttribs & ATTR_TEXCOORD )
|
||||
|
@ -1448,8 +1440,7 @@ static void RB_SurfaceGrid( srfGridMesh_t *srf ) {
|
|||
|
||||
if ( tess.shader->vertexAttribs & ATTR_LIGHTDIRECTION )
|
||||
{
|
||||
VectorCopy(dv->lightdir, lightdir);
|
||||
lightdir += 4;
|
||||
*lightdir++ = R_VboPackNormal(dv->lightdir);
|
||||
}
|
||||
|
||||
//*vDlightBits++ = dlightBits;
|
||||
|
@ -1574,7 +1565,7 @@ static void RB_SurfaceFlare(srfFlare_t *surf)
|
|||
RB_AddFlare(surf, tess.fogNum, surf->origin, surf->color, surf->normal);
|
||||
}
|
||||
|
||||
static void RB_SurfaceVBOMesh(srfVBOMesh_t * srf)
|
||||
static void RB_SurfaceVBOMesh(srfBspSurface_t * srf)
|
||||
{
|
||||
RB_SurfaceVbo (srf->vbo, srf->ibo, srf->numVerts, srf->numIndexes, srf->firstIndex,
|
||||
srf->minIndex, srf->maxIndex, srf->dlightBits, srf->pshadowBits, qfalse );
|
||||
|
@ -1621,11 +1612,12 @@ void RB_SurfaceVBOMDVMesh(srfVBOMDVMesh_t * surface)
|
|||
|
||||
glState.vertexAttribsOldFrame = refEnt->oldframe;
|
||||
glState.vertexAttribsNewFrame = refEnt->frame;
|
||||
glState.vertexAnimation = qtrue;
|
||||
|
||||
RB_EndSurface();
|
||||
|
||||
// So we don't lerp surfaces that shouldn't be lerped
|
||||
glState.vertexAttribsInterpolation = 0;
|
||||
glState.vertexAnimation = qfalse;
|
||||
}
|
||||
|
||||
static void RB_SurfaceDisplayList( srfDisplayList_t *surf ) {
|
||||
|
@ -1646,7 +1638,6 @@ void (*rb_surfaceTable[SF_NUM_SURFACE_TYPES])( void *) = {
|
|||
(void(*)(void*))RB_SurfaceTriangles, // SF_TRIANGLES,
|
||||
(void(*)(void*))RB_SurfacePolychain, // SF_POLY,
|
||||
(void(*)(void*))RB_SurfaceMesh, // SF_MDV,
|
||||
(void(*)(void*))RB_SurfaceAnim, // SF_MD4,
|
||||
(void(*)(void*))RB_MDRSurfaceAnim, // SF_MDR,
|
||||
(void(*)(void*))RB_IQMSurfaceAnim, // SF_IQM,
|
||||
(void(*)(void*))RB_SurfaceFlare, // SF_FLARE,
|
||||
|
|
|
@ -22,6 +22,75 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|||
// tr_vbo.c
|
||||
#include "tr_local.h"
|
||||
|
||||
|
||||
uint32_t R_VboPackTangent(vec4_t v)
|
||||
{
|
||||
if (glRefConfig.packedNormalDataType == GL_UNSIGNED_INT_2_10_10_10_REV)
|
||||
{
|
||||
return (((uint32_t)(v[3] * 1.5f + 2.0f )) << 30)
|
||||
| (((uint32_t)(v[2] * 511.5f + 512.0f)) << 20)
|
||||
| (((uint32_t)(v[1] * 511.5f + 512.0f)) << 10)
|
||||
| (((uint32_t)(v[0] * 511.5f + 512.0f)));
|
||||
}
|
||||
else
|
||||
{
|
||||
return (((uint32_t)(v[3] * 127.5f + 128.0f)) << 24)
|
||||
| (((uint32_t)(v[2] * 127.5f + 128.0f)) << 16)
|
||||
| (((uint32_t)(v[1] * 127.5f + 128.0f)) << 8)
|
||||
| (((uint32_t)(v[0] * 127.5f + 128.0f)));
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t R_VboPackNormal(vec3_t v)
|
||||
{
|
||||
if (glRefConfig.packedNormalDataType == GL_UNSIGNED_INT_2_10_10_10_REV)
|
||||
{
|
||||
return (((uint32_t)(v[2] * 511.5f + 512.0f)) << 20)
|
||||
| (((uint32_t)(v[1] * 511.5f + 512.0f)) << 10)
|
||||
| (((uint32_t)(v[0] * 511.5f + 512.0f)));
|
||||
}
|
||||
else
|
||||
{
|
||||
return (((uint32_t)(v[2] * 127.5f + 128.0f)) << 16)
|
||||
| (((uint32_t)(v[1] * 127.5f + 128.0f)) << 8)
|
||||
| (((uint32_t)(v[0] * 127.5f + 128.0f)));
|
||||
}
|
||||
}
|
||||
|
||||
void R_VboUnpackTangent(vec4_t v, uint32_t b)
|
||||
{
|
||||
if (glRefConfig.packedNormalDataType == GL_UNSIGNED_INT_2_10_10_10_REV)
|
||||
{
|
||||
v[0] = ((b) & 0x3ff) * 1.0f/511.5f - 1.0f;
|
||||
v[1] = ((b >> 10) & 0x3ff) * 1.0f/511.5f - 1.0f;
|
||||
v[2] = ((b >> 20) & 0x3ff) * 1.0f/511.5f - 1.0f;
|
||||
v[3] = ((b >> 30) & 0x3) * 1.0f/1.5f - 1.0f;
|
||||
}
|
||||
else
|
||||
{
|
||||
v[0] = ((b) & 0xff) * 1.0f/127.5f - 1.0f;
|
||||
v[1] = ((b >> 8) & 0xff) * 1.0f/127.5f - 1.0f;
|
||||
v[2] = ((b >> 16) & 0xff) * 1.0f/127.5f - 1.0f;
|
||||
v[3] = ((b >> 24) & 0xff) * 1.0f/127.5f - 1.0f;
|
||||
}
|
||||
}
|
||||
|
||||
void R_VboUnpackNormal(vec3_t v, uint32_t b)
|
||||
{
|
||||
if (glRefConfig.packedNormalDataType == GL_UNSIGNED_INT_2_10_10_10_REV)
|
||||
{
|
||||
v[0] = ((b) & 0x3ff) * 1.0f/511.5f - 1.0f;
|
||||
v[1] = ((b >> 10) & 0x3ff) * 1.0f/511.5f - 1.0f;
|
||||
v[2] = ((b >> 20) & 0x3ff) * 1.0f/511.5f - 1.0f;
|
||||
}
|
||||
else
|
||||
{
|
||||
v[0] = ((b) & 0xff) * 1.0f/127.5f - 1.0f;
|
||||
v[1] = ((b >> 8) & 0xff) * 1.0f/127.5f - 1.0f;
|
||||
v[2] = ((b >> 16) & 0xff) * 1.0f/127.5f - 1.0f;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
============
|
||||
R_CreateVBO
|
||||
|
@ -142,20 +211,14 @@ VBO_t *R_CreateVBO2(const char *name, int numVertexes, srfVert_t * vert
|
|||
if(stateBits & ATTR_NORMAL)
|
||||
{
|
||||
vbo->ofs_normal = dataSize;
|
||||
dataSize += sizeof(verts[0].normal);
|
||||
dataSize += sizeof(uint32_t);
|
||||
}
|
||||
|
||||
#ifdef USE_VERT_TANGENT_SPACE
|
||||
if(stateBits & ATTR_TANGENT)
|
||||
{
|
||||
vbo->ofs_tangent = dataSize;
|
||||
dataSize += sizeof(verts[0].tangent);
|
||||
}
|
||||
|
||||
if(stateBits & ATTR_BITANGENT)
|
||||
{
|
||||
vbo->ofs_bitangent = dataSize;
|
||||
dataSize += sizeof(verts[0].bitangent);
|
||||
dataSize += sizeof(uint32_t);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -180,14 +243,13 @@ VBO_t *R_CreateVBO2(const char *name, int numVertexes, srfVert_t * vert
|
|||
if(stateBits & ATTR_LIGHTDIRECTION)
|
||||
{
|
||||
vbo->ofs_lightdir = dataSize;
|
||||
dataSize += sizeof(verts[0].lightdir);
|
||||
dataSize += sizeof(uint32_t);
|
||||
}
|
||||
|
||||
vbo->stride_xyz = dataSize;
|
||||
vbo->stride_normal = dataSize;
|
||||
#ifdef USE_VERT_TANGENT_SPACE
|
||||
vbo->stride_tangent = dataSize;
|
||||
vbo->stride_bitangent = dataSize;
|
||||
#endif
|
||||
vbo->stride_st = dataSize;
|
||||
vbo->stride_lightmap = dataSize;
|
||||
|
@ -211,23 +273,22 @@ VBO_t *R_CreateVBO2(const char *name, int numVertexes, srfVert_t * vert
|
|||
// normal
|
||||
if(stateBits & ATTR_NORMAL)
|
||||
{
|
||||
memcpy(data + dataOfs, &verts[i].normal, sizeof(verts[i].normal));
|
||||
dataOfs += sizeof(verts[i].normal);
|
||||
uint32_t *p = (uint32_t *)(data + dataOfs);
|
||||
|
||||
*p = R_VboPackNormal(verts[i].normal);
|
||||
|
||||
dataOfs += sizeof(uint32_t);
|
||||
}
|
||||
|
||||
#ifdef USE_VERT_TANGENT_SPACE
|
||||
// tangent
|
||||
if(stateBits & ATTR_TANGENT)
|
||||
{
|
||||
memcpy(data + dataOfs, &verts[i].tangent, sizeof(verts[i].tangent));
|
||||
dataOfs += sizeof(verts[i].tangent);
|
||||
}
|
||||
uint32_t *p = (uint32_t *)(data + dataOfs);
|
||||
|
||||
// bitangent
|
||||
if(stateBits & ATTR_BITANGENT)
|
||||
{
|
||||
memcpy(data + dataOfs, &verts[i].bitangent, sizeof(verts[i].bitangent));
|
||||
dataOfs += sizeof(verts[i].bitangent);
|
||||
*p = R_VboPackTangent(verts[i].tangent);
|
||||
|
||||
dataOfs += sizeof(uint32_t);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -255,8 +316,11 @@ VBO_t *R_CreateVBO2(const char *name, int numVertexes, srfVert_t * vert
|
|||
// feed vertex light directions
|
||||
if(stateBits & ATTR_LIGHTDIRECTION)
|
||||
{
|
||||
memcpy(data + dataOfs, &verts[i].lightdir, sizeof(verts[i].lightdir));
|
||||
dataOfs += sizeof(verts[i].lightdir);
|
||||
uint32_t *p = (uint32_t *)(data + dataOfs);
|
||||
|
||||
*p = R_VboPackNormal(verts[i].lightdir);
|
||||
|
||||
dataOfs += sizeof(uint32_t);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -267,18 +331,13 @@ VBO_t *R_CreateVBO2(const char *name, int numVertexes, srfVert_t * vert
|
|||
|
||||
if(stateBits & ATTR_NORMAL)
|
||||
{
|
||||
dataSize += sizeof(verts[0].normal);
|
||||
dataSize += sizeof(uint32_t);
|
||||
}
|
||||
|
||||
#ifdef USE_VERT_TANGENT_SPACE
|
||||
if(stateBits & ATTR_TANGENT)
|
||||
{
|
||||
dataSize += sizeof(verts[0].tangent);
|
||||
}
|
||||
|
||||
if(stateBits & ATTR_BITANGENT)
|
||||
{
|
||||
dataSize += sizeof(verts[0].bitangent);
|
||||
dataSize += sizeof(uint32_t);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -299,7 +358,7 @@ VBO_t *R_CreateVBO2(const char *name, int numVertexes, srfVert_t * vert
|
|||
|
||||
if(stateBits & ATTR_LIGHTDIRECTION)
|
||||
{
|
||||
dataSize += sizeof(verts[0].lightdir);
|
||||
dataSize += sizeof(uint32_t);
|
||||
}
|
||||
|
||||
// create VBO
|
||||
|
@ -311,7 +370,6 @@ VBO_t *R_CreateVBO2(const char *name, int numVertexes, srfVert_t * vert
|
|||
vbo->ofs_normal = 0;
|
||||
#ifdef USE_VERT_TANGENT_SPACE
|
||||
vbo->ofs_tangent = 0;
|
||||
vbo->ofs_bitangent = 0;
|
||||
#endif
|
||||
vbo->ofs_st = 0;
|
||||
vbo->ofs_lightmap = 0;
|
||||
|
@ -319,15 +377,14 @@ VBO_t *R_CreateVBO2(const char *name, int numVertexes, srfVert_t * vert
|
|||
vbo->ofs_lightdir = 0;
|
||||
|
||||
vbo->stride_xyz = sizeof(verts[0].xyz);
|
||||
vbo->stride_normal = sizeof(verts[0].normal);
|
||||
vbo->stride_normal = sizeof(uint32_t);
|
||||
#ifdef USE_VERT_TANGENT_SPACE
|
||||
vbo->stride_tangent = sizeof(verts[0].tangent);
|
||||
vbo->stride_bitangent = sizeof(verts[0].bitangent);
|
||||
vbo->stride_tangent = sizeof(uint32_t);
|
||||
#endif
|
||||
vbo->stride_vertexcolor = sizeof(verts[0].vertexColors);
|
||||
vbo->stride_st = sizeof(verts[0].st);
|
||||
vbo->stride_lightmap = sizeof(verts[0].lightmap);
|
||||
vbo->stride_lightdir = sizeof(verts[0].lightdir);
|
||||
vbo->stride_lightdir = sizeof(uint32_t);
|
||||
|
||||
//ri.Printf(PRINT_ALL, "2CreateVBO: %d, %d %d %d %d %d, %d %d %d %d %d\n", dataSize, vbo->ofs_xyz, vbo->ofs_normal, vbo->ofs_st, vbo->ofs_lightmap, vbo->ofs_vertexcolor,
|
||||
//vbo->stride_xyz, vbo->stride_normal, vbo->stride_st, vbo->stride_lightmap, vbo->stride_vertexcolor);
|
||||
|
@ -345,8 +402,11 @@ VBO_t *R_CreateVBO2(const char *name, int numVertexes, srfVert_t * vert
|
|||
vbo->ofs_normal = dataOfs;
|
||||
for (i = 0; i < numVertexes; i++)
|
||||
{
|
||||
memcpy(data + dataOfs, &verts[i].normal, sizeof(verts[i].normal));
|
||||
dataOfs += sizeof(verts[i].normal);
|
||||
uint32_t *p = (uint32_t *)(data + dataOfs);
|
||||
|
||||
*p = R_VboPackNormal(verts[i].normal);
|
||||
|
||||
dataOfs += sizeof(uint32_t);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -357,19 +417,11 @@ VBO_t *R_CreateVBO2(const char *name, int numVertexes, srfVert_t * vert
|
|||
vbo->ofs_tangent = dataOfs;
|
||||
for (i = 0; i < numVertexes; i++)
|
||||
{
|
||||
memcpy(data + dataOfs, &verts[i].tangent, sizeof(verts[i].tangent));
|
||||
dataOfs += sizeof(verts[i].tangent);
|
||||
}
|
||||
}
|
||||
uint32_t *p = (uint32_t *)(data + dataOfs);
|
||||
|
||||
// bitangent
|
||||
if(stateBits & ATTR_BITANGENT)
|
||||
{
|
||||
vbo->ofs_bitangent = dataOfs;
|
||||
for (i = 0; i < numVertexes; i++)
|
||||
{
|
||||
memcpy(data + dataOfs, &verts[i].bitangent, sizeof(verts[i].bitangent));
|
||||
dataOfs += sizeof(verts[i].bitangent);
|
||||
*p = R_VboPackTangent(verts[i].tangent);
|
||||
|
||||
dataOfs += sizeof(uint32_t);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
@ -413,8 +465,11 @@ VBO_t *R_CreateVBO2(const char *name, int numVertexes, srfVert_t * vert
|
|||
vbo->ofs_lightdir = dataOfs;
|
||||
for (i = 0; i < numVertexes; i++)
|
||||
{
|
||||
memcpy(data + dataOfs, &verts[i].lightdir, sizeof(verts[i].lightdir));
|
||||
dataOfs += sizeof(verts[i].lightdir);
|
||||
uint32_t *p = (uint32_t *)(data + dataOfs);
|
||||
|
||||
*p = R_VboPackNormal(verts[i].lightdir);
|
||||
|
||||
dataOfs += sizeof(uint32_t);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -501,17 +556,14 @@ IBO_t *R_CreateIBO(const char *name, byte * indexes, int indexesSize, v
|
|||
R_CreateIBO2
|
||||
============
|
||||
*/
|
||||
IBO_t *R_CreateIBO2(const char *name, int numTriangles, srfTriangle_t * triangles, vboUsage_t usage)
|
||||
IBO_t *R_CreateIBO2(const char *name, int numIndexes, glIndex_t * inIndexes, vboUsage_t usage)
|
||||
{
|
||||
IBO_t *ibo;
|
||||
int i, j;
|
||||
int i;
|
||||
|
||||
byte *indexes;
|
||||
glIndex_t *indexes;
|
||||
int indexesSize;
|
||||
int indexesOfs;
|
||||
|
||||
srfTriangle_t *tri;
|
||||
glIndex_t index;
|
||||
int glUsage;
|
||||
|
||||
switch (usage)
|
||||
|
@ -529,7 +581,7 @@ IBO_t *R_CreateIBO2(const char *name, int numTriangles, srfTriangle_t *
|
|||
return NULL;
|
||||
}
|
||||
|
||||
if(!numTriangles)
|
||||
if(!numIndexes)
|
||||
return NULL;
|
||||
|
||||
if(strlen(name) >= MAX_QPATH)
|
||||
|
@ -548,18 +600,12 @@ IBO_t *R_CreateIBO2(const char *name, int numTriangles, srfTriangle_t *
|
|||
|
||||
Q_strncpyz(ibo->name, name, sizeof(ibo->name));
|
||||
|
||||
indexesSize = numTriangles * 3 * sizeof(int);
|
||||
indexesSize = numIndexes * sizeof(glIndex_t);
|
||||
indexes = ri.Hunk_AllocateTempMemory(indexesSize);
|
||||
indexesOfs = 0;
|
||||
|
||||
for(i = 0, tri = triangles; i < numTriangles; i++, tri++)
|
||||
for(i = 0; i < numIndexes; i++)
|
||||
{
|
||||
for(j = 0; j < 3; j++)
|
||||
{
|
||||
index = tri->indexes[j];
|
||||
memcpy(indexes + indexesOfs, &index, sizeof(glIndex_t));
|
||||
indexesOfs += sizeof(glIndex_t);
|
||||
}
|
||||
indexes[i] = inIndexes[i];
|
||||
}
|
||||
|
||||
ibo->indexesSize = indexesSize;
|
||||
|
@ -608,6 +654,7 @@ void R_BindVBO(VBO_t * vbo)
|
|||
glState.vertexAttribsInterpolation = 0;
|
||||
glState.vertexAttribsOldFrame = 0;
|
||||
glState.vertexAttribsNewFrame = 0;
|
||||
glState.vertexAnimation = qfalse;
|
||||
|
||||
qglBindBufferARB(GL_ARRAY_BUFFER_ARB, vbo->vertexesVBO);
|
||||
|
||||
|
@ -699,7 +746,6 @@ void R_InitVBOs(void)
|
|||
dataSize += sizeof(tess.normal[0]);
|
||||
#ifdef USE_VERT_TANGENT_SPACE
|
||||
dataSize += sizeof(tess.tangent[0]);
|
||||
dataSize += sizeof(tess.bitangent[0]);
|
||||
#endif
|
||||
dataSize += sizeof(tess.vertexColors[0]);
|
||||
dataSize += sizeof(tess.texCoords[0][0]) * 2;
|
||||
|
@ -714,7 +760,6 @@ void R_InitVBOs(void)
|
|||
tess.vbo->ofs_normal = offset; offset += sizeof(tess.normal[0]) * SHADER_MAX_VERTEXES;
|
||||
#ifdef USE_VERT_TANGENT_SPACE
|
||||
tess.vbo->ofs_tangent = offset; offset += sizeof(tess.tangent[0]) * SHADER_MAX_VERTEXES;
|
||||
tess.vbo->ofs_bitangent = offset; offset += sizeof(tess.bitangent[0]) * SHADER_MAX_VERTEXES;
|
||||
#endif
|
||||
// these next two are actually interleaved
|
||||
tess.vbo->ofs_st = offset;
|
||||
|
@ -728,7 +773,6 @@ void R_InitVBOs(void)
|
|||
tess.vbo->stride_normal = sizeof(tess.normal[0]);
|
||||
#ifdef USE_VERT_TANGENT_SPACE
|
||||
tess.vbo->stride_tangent = sizeof(tess.tangent[0]);
|
||||
tess.vbo->stride_bitangent = sizeof(tess.bitangent[0]);
|
||||
#endif
|
||||
tess.vbo->stride_vertexcolor = sizeof(tess.vertexColors[0]);
|
||||
tess.vbo->stride_st = sizeof(tess.texCoords[0][0]) * 2;
|
||||
|
@ -856,6 +900,9 @@ void RB_UpdateVBOs(unsigned int attribBits)
|
|||
{
|
||||
R_BindVBO(tess.vbo);
|
||||
|
||||
// orphan old buffer so we don't stall on it
|
||||
qglBufferDataARB(GL_ARRAY_BUFFER_ARB, tess.vbo->vertexesSize, NULL, GL_DYNAMIC_DRAW_ARB);
|
||||
|
||||
if(attribBits & ATTR_BITS)
|
||||
{
|
||||
if(attribBits & ATTR_POSITION)
|
||||
|
@ -883,12 +930,6 @@ void RB_UpdateVBOs(unsigned int attribBits)
|
|||
//ri.Printf(PRINT_ALL, "offset %d, size %d\n", tess.vbo->ofs_tangent, tess.numVertexes * sizeof(tess.tangent[0]));
|
||||
qglBufferSubDataARB(GL_ARRAY_BUFFER_ARB, tess.vbo->ofs_tangent, tess.numVertexes * sizeof(tess.tangent[0]), tess.tangent);
|
||||
}
|
||||
|
||||
if(attribBits & ATTR_BITANGENT)
|
||||
{
|
||||
//ri.Printf(PRINT_ALL, "offset %d, size %d\n", tess.vbo->ofs_bitangent, tess.numVertexes * sizeof(tess.bitangent[0]));
|
||||
qglBufferSubDataARB(GL_ARRAY_BUFFER_ARB, tess.vbo->ofs_bitangent, tess.numVertexes * sizeof(tess.bitangent[0]), tess.bitangent);
|
||||
}
|
||||
#endif
|
||||
|
||||
if(attribBits & ATTR_COLOR)
|
||||
|
@ -910,7 +951,6 @@ void RB_UpdateVBOs(unsigned int attribBits)
|
|||
qglBufferSubDataARB(GL_ARRAY_BUFFER_ARB, tess.vbo->ofs_normal, tess.numVertexes * sizeof(tess.normal[0]), tess.normal);
|
||||
#ifdef USE_VERT_TANGENT_SPACE
|
||||
qglBufferSubDataARB(GL_ARRAY_BUFFER_ARB, tess.vbo->ofs_tangent, tess.numVertexes * sizeof(tess.tangent[0]), tess.tangent);
|
||||
qglBufferSubDataARB(GL_ARRAY_BUFFER_ARB, tess.vbo->ofs_bitangent, tess.numVertexes * sizeof(tess.bitangent[0]), tess.bitangent);
|
||||
#endif
|
||||
qglBufferSubDataARB(GL_ARRAY_BUFFER_ARB, tess.vbo->ofs_vertexcolor, tess.numVertexes * sizeof(tess.vertexColors[0]), tess.vertexColors);
|
||||
qglBufferSubDataARB(GL_ARRAY_BUFFER_ARB, tess.vbo->ofs_lightdir, tess.numVertexes * sizeof(tess.lightdir[0]), tess.lightdir);
|
||||
|
@ -923,6 +963,9 @@ void RB_UpdateVBOs(unsigned int attribBits)
|
|||
{
|
||||
R_BindIBO(tess.ibo);
|
||||
|
||||
// orphan old buffer so we don't stall on it
|
||||
qglBufferDataARB(GL_ELEMENT_ARRAY_BUFFER_ARB, tess.ibo->indexesSize, NULL, GL_DYNAMIC_DRAW_ARB);
|
||||
|
||||
qglBufferSubDataARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0, tess.numIndexes * sizeof(tess.indexes[0]), tess.indexes);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -208,16 +208,18 @@ static int R_DlightSurface( msurface_t *surf, int dlightBits ) {
|
|||
}
|
||||
}
|
||||
|
||||
if ( *surf->data == SF_FACE ) {
|
||||
((srfSurfaceFace_t *)surf->data)->dlightBits = dlightBits;
|
||||
} else if ( *surf->data == SF_GRID ) {
|
||||
((srfGridMesh_t *)surf->data)->dlightBits = dlightBits;
|
||||
} else if ( *surf->data == SF_TRIANGLES ) {
|
||||
((srfTriangles_t *)surf->data)->dlightBits = dlightBits;
|
||||
} else if ( *surf->data == SF_VBO_MESH ) {
|
||||
((srfVBOMesh_t *)surf->data)->dlightBits = dlightBits;
|
||||
} else {
|
||||
dlightBits = 0;
|
||||
switch(*surf->data)
|
||||
{
|
||||
case SF_FACE:
|
||||
case SF_GRID:
|
||||
case SF_TRIANGLES:
|
||||
case SF_VBO_MESH:
|
||||
((srfBspSurface_t *)surf->data)->dlightBits = dlightBits;
|
||||
break;
|
||||
|
||||
default:
|
||||
dlightBits = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
if ( dlightBits ) {
|
||||
|
@ -292,16 +294,18 @@ static int R_PshadowSurface( msurface_t *surf, int pshadowBits ) {
|
|||
}
|
||||
}
|
||||
|
||||
if ( *surf->data == SF_FACE ) {
|
||||
((srfSurfaceFace_t *)surf->data)->pshadowBits = pshadowBits;
|
||||
} else if ( *surf->data == SF_GRID ) {
|
||||
((srfGridMesh_t *)surf->data)->pshadowBits = pshadowBits;
|
||||
} else if ( *surf->data == SF_TRIANGLES ) {
|
||||
((srfTriangles_t *)surf->data)->pshadowBits = pshadowBits;
|
||||
} else if ( *surf->data == SF_VBO_MESH ) {
|
||||
((srfVBOMesh_t *)surf->data)->pshadowBits = pshadowBits;
|
||||
} else {
|
||||
pshadowBits = 0;
|
||||
switch(*surf->data)
|
||||
{
|
||||
case SF_FACE:
|
||||
case SF_GRID:
|
||||
case SF_TRIANGLES:
|
||||
case SF_VBO_MESH:
|
||||
((srfBspSurface_t *)surf->data)->pshadowBits = pshadowBits;
|
||||
break;
|
||||
|
||||
default:
|
||||
pshadowBits = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
if ( pshadowBits ) {
|
||||
|
|
|
@ -698,8 +698,8 @@ void GLimp_Init( void )
|
|||
{
|
||||
r_allowSoftwareGL = ri.Cvar_Get( "r_allowSoftwareGL", "0", CVAR_LATCH );
|
||||
r_sdlDriver = ri.Cvar_Get( "r_sdlDriver", "", CVAR_ROM );
|
||||
r_allowResize = ri.Cvar_Get( "r_allowResize", "0", CVAR_ARCHIVE );
|
||||
r_centerWindow = ri.Cvar_Get( "r_centerWindow", "0", CVAR_ARCHIVE );
|
||||
r_allowResize = ri.Cvar_Get( "r_allowResize", "0", CVAR_ARCHIVE | CVAR_LATCH );
|
||||
r_centerWindow = ri.Cvar_Get( "r_centerWindow", "0", CVAR_ARCHIVE | CVAR_LATCH );
|
||||
|
||||
if( ri.Cvar_VariableIntegerValue( "com_abnormalExit" ) )
|
||||
{
|
||||
|
|
|
@ -194,7 +194,7 @@ typedef struct client_s {
|
|||
#endif
|
||||
|
||||
int oldServerTime;
|
||||
qboolean csUpdated[MAX_CONFIGSTRINGS+1];
|
||||
qboolean csUpdated[MAX_CONFIGSTRINGS];
|
||||
|
||||
#ifdef LEGACY_PROTOCOL
|
||||
qboolean compat;
|
||||
|
|
|
@ -82,7 +82,7 @@ void SV_UpdateConfigstrings(client_t *client)
|
|||
{
|
||||
int index;
|
||||
|
||||
for( index = 0; index <= MAX_CONFIGSTRINGS; index++ ) {
|
||||
for( index = 0; index < MAX_CONFIGSTRINGS; index++ ) {
|
||||
// if the CS hasn't changed since we went to CS_PRIMED, ignore
|
||||
if(!client->csUpdated[index])
|
||||
continue;
|
||||
|
|
|
@ -429,6 +429,7 @@ qboolean UI_ConsoleCommand(int realTime)
|
|||
|
||||
if (Q_stricmp(cmd, "ui_test") == 0) {
|
||||
UI_ShowPostGame(qtrue);
|
||||
return qtrue;
|
||||
}
|
||||
|
||||
if (Q_stricmp(cmd, "ui_report") == 0) {
|
||||
|
|
|
@ -1918,7 +1918,7 @@ void UI_ParseMenu(const char *menuFile)
|
|||
int handle;
|
||||
pc_token_t token;
|
||||
|
||||
Com_Printf("Parsing menu file:%s\n", menuFile);
|
||||
Com_Printf("Parsing menu file: %s\n", menuFile);
|
||||
|
||||
handle = trap_PC_LoadSource(menuFile);
|
||||
if (!handle) {
|
||||
|
|
|
@ -221,13 +221,13 @@ for ARCH in $SEARCH_ARCHS; do
|
|||
IOQ3_UI_ARCHS="${BUILT_PRODUCTS_DIR}/${BASEDIR}/${IOQ3_UI} ${IOQ3_UI_ARCHS}"
|
||||
fi
|
||||
# missionpack
|
||||
if [ -e ${BUILT_PRODUCTS_DIR}/${BASEDIR}/${IOQ3_MP_CGAME} ]; then
|
||||
if [ -e ${BUILT_PRODUCTS_DIR}/${MISSIONPACKDIR}/${IOQ3_CGAME} ]; then
|
||||
IOQ3_MP_CGAME_ARCHS="${BUILT_PRODUCTS_DIR}/${MISSIONPACKDIR}/${IOQ3_CGAME} ${IOQ3_MP_CGAME_ARCHS}"
|
||||
fi
|
||||
if [ -e ${BUILT_PRODUCTS_DIR}/${BASEDIR}/${IOQ3_MP_GAME} ]; then
|
||||
if [ -e ${BUILT_PRODUCTS_DIR}/${MISSIONPACKDIR}/${IOQ3_GAME} ]; then
|
||||
IOQ3_MP_GAME_ARCHS="${BUILT_PRODUCTS_DIR}/${MISSIONPACKDIR}/${IOQ3_GAME} ${IOQ3_MP_GAME_ARCHS}"
|
||||
fi
|
||||
if [ -e ${BUILT_PRODUCTS_DIR}/${BASEDIR}/${IOQ3_MP_UI} ]; then
|
||||
if [ -e ${BUILT_PRODUCTS_DIR}/${MISSIONPACKDIR}/${IOQ3_UI} ]; then
|
||||
IOQ3_MP_UI_ARCHS="${BUILT_PRODUCTS_DIR}/${MISSIONPACKDIR}/${IOQ3_UI} ${IOQ3_MP_UI_ARCHS}"
|
||||
fi
|
||||
|
||||
|
|
932
misc/msvc/opengl1.vcproj
Normal file
932
misc/msvc/opengl1.vcproj
Normal file
|
@ -0,0 +1,932 @@
|
|||
<?xml version="1.0" encoding="Windows-1252"?>
|
||||
<VisualStudioProject
|
||||
ProjectType="Visual C++"
|
||||
Version="9.00"
|
||||
Name="opengl1"
|
||||
ProjectGUID="{CD289B03-887C-4602-BDCE-AB6785A7489E}"
|
||||
TargetFrameworkVersion="131072"
|
||||
>
|
||||
<Platforms>
|
||||
<Platform
|
||||
Name="Win32"
|
||||
/>
|
||||
</Platforms>
|
||||
<ToolFiles>
|
||||
</ToolFiles>
|
||||
<Configurations>
|
||||
<Configuration
|
||||
Name="Release TA|Win32"
|
||||
OutputDirectory="..\..\build\opengl1_release_ta"
|
||||
IntermediateDirectory="..\..\build\opengl1_release_ta"
|
||||
ConfigurationType="2"
|
||||
UseOfMFC="0"
|
||||
ATLMinimizesCRunTimeLibraryUsage="false"
|
||||
>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
CommandLine=""
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
PreprocessorDefinitions="NDEBUG"
|
||||
MkTypLibCompatible="true"
|
||||
SuppressStartupBanner="true"
|
||||
TargetEnvironment="1"
|
||||
TypeLibraryName="$(IntDir)\opengl1.tlb"
|
||||
HeaderFileName=""
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="2"
|
||||
InlineFunctionExpansion="2"
|
||||
AdditionalIncludeDirectories="..\..\code\SDL12\include;..\..\code\libcurl;..\..\code\AL;..\..\code\libspeex\include;..\..\code\zlib;"..\..\code\jpeg-8c""
|
||||
PreprocessorDefinitions="_WIN32;WIN32;NDEBUG;_WINDOWS;_CRT_SECURE_NO_DEPRECATE;BOTLIB;USE_ICON;USE_CURL;USE_CURL_DLOPEN;USE_OPENAL;USE_OPENAL_DLOPEN;USE_VOIP;HAVE_CONFIG_H;MISSIONPACK;USE_INTERNAL_JPEG;USE_RENDERER_DLOPEN"
|
||||
StringPooling="true"
|
||||
RuntimeLibrary="0"
|
||||
EnableFunctionLevelLinking="true"
|
||||
UsePrecompiledHeader="0"
|
||||
PrecompiledHeaderFile="$(IntDir)\opengl1.pch"
|
||||
AssemblerListingLocation="$(IntDir)\"
|
||||
ObjectFile="$(IntDir)\"
|
||||
ProgramDataBaseFileName="$(IntDir)\"
|
||||
WarningLevel="4"
|
||||
SuppressStartupBanner="true"
|
||||
CompileAs="1"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManagedResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
PreprocessorDefinitions="NDEBUG"
|
||||
Culture="1033"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalDependencies="user32.lib advapi32.lib winmm.lib wsock32.lib ws2_32.lib SDL.lib OpenGL32.lib msvcrt.lib psapi.lib"
|
||||
OutputFile="$(OutDir)\renderer_opengl1_x86.dll"
|
||||
LinkIncremental="1"
|
||||
SuppressStartupBanner="true"
|
||||
AdditionalLibraryDirectories="..\..\code\libs\win32"
|
||||
GenerateDebugInformation="false"
|
||||
ProgramDatabaseFile="$(IntDir)\opengl1.pdb"
|
||||
GenerateMapFile="true"
|
||||
MapFileName="$(IntDir)\opengl1.map"
|
||||
SubSystem="2"
|
||||
StackReserveSize="8388608"
|
||||
RandomizedBaseAddress="1"
|
||||
DataExecutionPrevention="0"
|
||||
TargetMachine="1"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCALinkTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManifestTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXDCMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCBscMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCFxCopTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCAppVerifierTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
Description="Post build processing.."
|
||||
CommandLine="rem bash -c "perl ./unix/cons -- release-TA""
|
||||
/>
|
||||
</Configuration>
|
||||
<Configuration
|
||||
Name="Debug|Win32"
|
||||
OutputDirectory="..\..\build\opengl1_debug"
|
||||
IntermediateDirectory="..\..\build\opengl1_debug"
|
||||
ConfigurationType="2"
|
||||
UseOfMFC="0"
|
||||
ATLMinimizesCRunTimeLibraryUsage="false"
|
||||
>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
CommandLine=""
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
PreprocessorDefinitions="_DEBUG"
|
||||
MkTypLibCompatible="true"
|
||||
SuppressStartupBanner="true"
|
||||
TargetEnvironment="1"
|
||||
TypeLibraryName="$(IntDir)\opengl1.tlb"
|
||||
HeaderFileName=""
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="0"
|
||||
AdditionalIncludeDirectories="..\..\code\SDL12\include;..\..\code\libcurl;..\..\code\AL;..\..\code\libspeex\include;..\..\code\zlib;"..\..\code\jpeg-8c""
|
||||
PreprocessorDefinitions="_WIN32;WIN32;_DEBUG;_WINDOWS;_CRT_SECURE_NO_DEPRECATE;BOTLIB;USE_ICON;USE_CURL;USE_CURL_DLOPEN;USE_OPENAL;USE_OPENAL_DLOPEN;USE_VOIP;HAVE_CONFIG_H;USE_INTERNAL_JPEG;USE_RENDERER_DLOPEN"
|
||||
RuntimeLibrary="3"
|
||||
UsePrecompiledHeader="0"
|
||||
PrecompiledHeaderFile="$(IntDir)\opengl1.pch"
|
||||
AssemblerListingLocation="$(IntDir)\"
|
||||
ObjectFile="$(IntDir)\"
|
||||
ProgramDataBaseFileName="$(IntDir)\"
|
||||
BrowseInformation="1"
|
||||
BrowseInformationFile="$(IntDir)\"
|
||||
WarningLevel="3"
|
||||
SuppressStartupBanner="true"
|
||||
DebugInformationFormat="4"
|
||||
CompileAs="1"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManagedResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
PreprocessorDefinitions="_DEBUG"
|
||||
Culture="1033"
|
||||
ResourceOutputFileName="..\winquake.res"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalDependencies="user32.lib advapi32.lib winmm.lib wsock32.lib ws2_32.lib SDL.lib OpenGL32.lib msvcrt.lib psapi.lib"
|
||||
OutputFile="$(OutDir)\renderer_opengl1_x86.dll"
|
||||
LinkIncremental="2"
|
||||
SuppressStartupBanner="true"
|
||||
AdditionalLibraryDirectories="..\..\code\libs\win32"
|
||||
IgnoreDefaultLibraryNames=""
|
||||
GenerateDebugInformation="true"
|
||||
ProgramDatabaseFile="$(IntDir)\opengl1.pdb"
|
||||
GenerateMapFile="true"
|
||||
MapFileName="$(IntDir)\opengl1.map"
|
||||
SubSystem="2"
|
||||
StackReserveSize="8388608"
|
||||
RandomizedBaseAddress="1"
|
||||
DataExecutionPrevention="0"
|
||||
TargetMachine="1"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCALinkTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManifestTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXDCMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCBscMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCFxCopTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCAppVerifierTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
Description="Post build processing.."
|
||||
CommandLine="rem bash -c "perl ./unix/cons -- debug""
|
||||
/>
|
||||
</Configuration>
|
||||
<Configuration
|
||||
Name="Release|Win32"
|
||||
OutputDirectory="..\..\build\opengl1_release"
|
||||
IntermediateDirectory="..\..\build\opengl1_release"
|
||||
ConfigurationType="2"
|
||||
UseOfMFC="0"
|
||||
ATLMinimizesCRunTimeLibraryUsage="false"
|
||||
>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
CommandLine=""
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
PreprocessorDefinitions="NDEBUG"
|
||||
MkTypLibCompatible="true"
|
||||
SuppressStartupBanner="true"
|
||||
TargetEnvironment="1"
|
||||
TypeLibraryName="$(IntDir)\opengl1.tlb"
|
||||
HeaderFileName=""
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="2"
|
||||
InlineFunctionExpansion="2"
|
||||
AdditionalIncludeDirectories="..\..\code\SDL12\include;..\..\code\libcurl;..\..\code\AL;..\..\code\libspeex\include;..\..\code\zlib;"..\..\code\jpeg-8c""
|
||||
PreprocessorDefinitions="_WIN32;WIN32;NDEBUG;_WINDOWS;_CRT_SECURE_NO_DEPRECATE;BOTLIB;USE_ICON;USE_CURL;USE_CURL_DLOPEN;USE_OPENAL;USE_OPENAL_DLOPEN;USE_VOIP;HAVE_CONFIG_H;USE_INTERNAL_JPEG;USE_RENDERER_DLOPEN"
|
||||
StringPooling="true"
|
||||
RuntimeLibrary="0"
|
||||
EnableFunctionLevelLinking="true"
|
||||
UsePrecompiledHeader="0"
|
||||
PrecompiledHeaderFile="$(IntDir)\opengl1.pch"
|
||||
AssemblerListingLocation="$(IntDir)\"
|
||||
ObjectFile="$(IntDir)\"
|
||||
ProgramDataBaseFileName="$(IntDir)\"
|
||||
WarningLevel="4"
|
||||
SuppressStartupBanner="true"
|
||||
CompileAs="1"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManagedResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
PreprocessorDefinitions="NDEBUG"
|
||||
Culture="1033"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalDependencies="user32.lib advapi32.lib winmm.lib wsock32.lib ws2_32.lib SDL.lib OpenGL32.lib msvcrt.lib psapi.lib"
|
||||
OutputFile="$(OutDir)\renderer_opengl1_x86.dll"
|
||||
LinkIncremental="1"
|
||||
SuppressStartupBanner="true"
|
||||
AdditionalLibraryDirectories="..\..\code\libs\win32"
|
||||
GenerateDebugInformation="false"
|
||||
ProgramDatabaseFile="$(IntDir)\opengl1.pdb"
|
||||
GenerateMapFile="true"
|
||||
MapFileName="$(IntDir)\opengl1.map"
|
||||
SubSystem="2"
|
||||
StackReserveSize="8388608"
|
||||
RandomizedBaseAddress="1"
|
||||
DataExecutionPrevention="0"
|
||||
TargetMachine="1"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCALinkTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManifestTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXDCMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCBscMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCFxCopTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCAppVerifierTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
/>
|
||||
</Configuration>
|
||||
<Configuration
|
||||
Name="Debug TA|Win32"
|
||||
OutputDirectory="..\..\build\opengl1_debug_ta"
|
||||
IntermediateDirectory="..\..\build\opengl1_debug_ta"
|
||||
ConfigurationType="2"
|
||||
UseOfMFC="0"
|
||||
ATLMinimizesCRunTimeLibraryUsage="false"
|
||||
>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
CommandLine=""
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
PreprocessorDefinitions="_DEBUG"
|
||||
MkTypLibCompatible="true"
|
||||
SuppressStartupBanner="true"
|
||||
TargetEnvironment="1"
|
||||
TypeLibraryName="$(IntDir)\opengl1.tlb"
|
||||
HeaderFileName=""
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="0"
|
||||
AdditionalIncludeDirectories="..\..\code\SDL12\include;..\..\code\libcurl;..\..\code\AL;..\..\code\libspeex\include;..\..\code\zlib;"..\..\code\jpeg-8c""
|
||||
PreprocessorDefinitions="_WIN32;WIN32;_DEBUG;_WINDOWS;_CRT_SECURE_NO_DEPRECATE;BOTLIB;USE_ICON;USE_CURL;USE_CURL_DLOPEN;USE_OPENAL;USE_OPENAL_DLOPEN;USE_VOIP;HAVE_CONFIG_H;MISSIONPACK;USE_INTERNAL_JPEG;USE_RENDERER_DLOPEN"
|
||||
RuntimeLibrary="3"
|
||||
UsePrecompiledHeader="0"
|
||||
PrecompiledHeaderFile="$(IntDir)\opengl1.pch"
|
||||
AssemblerListingLocation="$(IntDir)\"
|
||||
ObjectFile="$(IntDir)\"
|
||||
ProgramDataBaseFileName="$(IntDir)\"
|
||||
BrowseInformation="1"
|
||||
BrowseInformationFile="$(IntDir)\"
|
||||
WarningLevel="3"
|
||||
SuppressStartupBanner="true"
|
||||
DebugInformationFormat="4"
|
||||
CompileAs="1"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManagedResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
PreprocessorDefinitions="_DEBUG"
|
||||
Culture="1033"
|
||||
ResourceOutputFileName="..\winquake.res"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalDependencies="user32.lib advapi32.lib winmm.lib wsock32.lib ws2_32.lib SDL.lib OpenGL32.lib msvcrt.lib psapi.lib"
|
||||
OutputFile="$(OutDir)\renderer_opengl1_x86.dll"
|
||||
LinkIncremental="2"
|
||||
SuppressStartupBanner="true"
|
||||
AdditionalLibraryDirectories="..\..\code\libs\win32"
|
||||
GenerateDebugInformation="true"
|
||||
ProgramDatabaseFile="$(IntDir)\opengl1.pdb"
|
||||
GenerateMapFile="true"
|
||||
MapFileName="$(IntDir)\opengl1.map"
|
||||
SubSystem="2"
|
||||
StackReserveSize="8388608"
|
||||
RandomizedBaseAddress="1"
|
||||
DataExecutionPrevention="0"
|
||||
TargetMachine="1"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCALinkTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManifestTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXDCMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCBscMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCFxCopTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCAppVerifierTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
Description="Post build processing.."
|
||||
CommandLine="rem bash -c "perl ./unix/cons -- debug-TA""
|
||||
/>
|
||||
</Configuration>
|
||||
</Configurations>
|
||||
<References>
|
||||
</References>
|
||||
<Files>
|
||||
<Filter
|
||||
Name="Source Files"
|
||||
Filter="cpp;c;cxx;rc;def;r;odl;hpj;bat;for;f90"
|
||||
>
|
||||
<File
|
||||
RelativePath="..\..\code\qcommon\puff.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\code\.\qcommon\q_math.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\code\.\qcommon\q_shared.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\code\sdl\sdl_gamma.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\code\sdl\sdl_glimp.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\code\renderergl1\tr_animation.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\code\renderergl1\tr_backend.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\code\renderergl1\tr_bsp.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\code\renderergl1\tr_cmds.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\code\renderergl1\tr_curve.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\code\renderergl1\tr_flares.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\code\renderercommon\tr_font.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\code\renderergl1\tr_image.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\code\renderercommon\tr_image_bmp.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\code\renderercommon\tr_image_jpg.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\code\renderercommon\tr_image_pcx.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\code\renderercommon\tr_image_png.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\code\renderercommon\tr_image_tga.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\code\renderergl1\tr_init.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\code\renderergl1\tr_light.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\code\renderergl1\tr_main.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\code\renderergl1\tr_marks.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\code\renderergl1\tr_mesh.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\code\renderergl1\tr_model.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\code\renderergl1\tr_model_iqm.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\code\renderercommon\tr_noise.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\code\renderergl1\tr_scene.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\code\renderergl1\tr_shade.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\code\renderergl1\tr_shade_calc.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\code\renderergl1\tr_shader.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\code\renderergl1\tr_shadows.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\code\renderergl1\tr_sky.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\code\renderergl1\tr_subs.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\code\renderergl1\tr_surface.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\code\renderergl1\tr_world.c"
|
||||
>
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="Header Files"
|
||||
Filter="h;hpp;hxx;hm;inl;fi;fd"
|
||||
>
|
||||
<File
|
||||
RelativePath="..\..\code\qcommon\puff.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\code\.\qcommon\q_shared.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\code\qcommon\qcommon.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\code\qcommon\qfiles.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\code\renderercommon\qgl.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\code\win32\resource.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\code\server\server.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\code\client\snd_local.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\code\client\snd_public.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\code\.\qcommon\surfaceflags.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\code\renderergl1\tr_extramath.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\code\renderergl1\tr_extratypes.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\code\renderergl1\tr_fbo.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\code\renderergl1\tr_local.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\code\renderergl1\tr_postprocess.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\code\renderercommon\tr_public.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\code\cgame\tr_types.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\code\ui\ui_public.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\code\qcommon\unzip.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\code\qcommon\vm_local.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\code\win32\win_local.h"
|
||||
>
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="Resource Files"
|
||||
Filter="ico;cur;bmp;dlg;rc2;rct;bin;cnt;rtf;gif;jpg;jpeg;jpe"
|
||||
>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="jpeg"
|
||||
>
|
||||
<Filter
|
||||
Name="Source Files"
|
||||
>
|
||||
<File
|
||||
RelativePath="..\..\code\jpeg-8c\jaricom.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\code\jpeg-8c\jcapimin.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\code\jpeg-8c\jcapistd.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\code\jpeg-8c\jcarith.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\code\jpeg-8c\jccoefct.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\code\jpeg-8c\jccolor.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\code\jpeg-8c\jcdctmgr.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\code\jpeg-8c\jchuff.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\code\jpeg-8c\jcinit.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\code\jpeg-8c\jcmainct.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\code\jpeg-8c\jcmarker.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\code\jpeg-8c\jcmaster.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\code\jpeg-8c\jcomapi.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\code\jpeg-8c\jcparam.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\code\jpeg-8c\jcprepct.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\code\jpeg-8c\jcsample.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\code\jpeg-8c\jctrans.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\code\jpeg-8c\jdapimin.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\code\jpeg-8c\jdapistd.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\code\jpeg-8c\jdarith.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\code\jpeg-8c\jdatadst.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\code\jpeg-8c\jdatasrc.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\code\jpeg-8c\jdcoefct.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\code\jpeg-8c\jdcolor.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\code\jpeg-8c\jddctmgr.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\code\jpeg-8c\jdhuff.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\code\jpeg-8c\jdinput.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\code\jpeg-8c\jdmainct.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\code\jpeg-8c\jdmarker.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\code\jpeg-8c\jdmaster.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\code\jpeg-8c\jdmerge.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\code\jpeg-8c\jdpostct.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\code\jpeg-8c\jdsample.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\code\jpeg-8c\jdtrans.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\code\jpeg-8c\jerror.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\code\jpeg-8c\jfdctflt.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\code\jpeg-8c\jfdctfst.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\code\jpeg-8c\jfdctint.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\code\jpeg-8c\jidctflt.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\code\jpeg-8c\jidctfst.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\code\jpeg-8c\jidctint.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\code\jpeg-8c\jmemmgr.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\code\jpeg-8c\jmemnobs.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\code\jpeg-8c\jquant1.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\code\jpeg-8c\jquant2.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\code\jpeg-8c\jutils.c"
|
||||
>
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="Header Files"
|
||||
>
|
||||
<File
|
||||
RelativePath="..\..\code\jpeg-6b\jchuff.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\code\jpeg-6b\jconfig.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\code\jpeg-6b\jdct.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\code\jpeg-6b\jdhuff.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\code\jpeg-6b\jerror.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\code\jpeg-6b\jinclude.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\code\jpeg-6b\jmemsys.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\code\jpeg-6b\jmorecfg.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\code\jpeg-6b\jpegint.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\code\jpeg-6b\jpeglib.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\code\jpeg-6b\jversion.h"
|
||||
>
|
||||
</File>
|
||||
</Filter>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="zlib"
|
||||
>
|
||||
<File
|
||||
RelativePath="..\..\code\zlib\adler32.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\code\zlib\crc32.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\code\zlib\inffast.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\code\zlib\inflate.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\code\zlib\inftrees.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\code\zlib\zutil.c"
|
||||
>
|
||||
</File>
|
||||
</Filter>
|
||||
</Files>
|
||||
<Globals>
|
||||
</Globals>
|
||||
</VisualStudioProject>
|
Loading…
Reference in a new issue