Move non-essential documentation to docs subdir

This commit is contained in:
Tim Angus committed 2025-09-25 10:48:38 +01:00
1 parent 56f9f94ee7
commit 149818dd86
5 files changed

No files matched your search

+165
View File
@@ -0,0 +1,165 @@
The updater program's code is public domain. The rest of ioquake3 is not.
The source code to the autoupdater is in the code/autoupdater directory.
There is a small piece of code in ioquake3 itself at startup, too; this is
in code/sys/sys_autoupdater.c ...
(This is all Unix terminology, but similar approaches on Windows apply.)
The updater is a separate program, written in C, with no dependencies on
the game. It (statically) links to libcurl and uses the C runtime, but
otherwise has no external dependencies. It has to be a single binary file
with no shared libraries.
The basic flow looks like this:
- The game launches as usual.
- Right after main() starts, the game creates a pipe, forks off a new process,
and execs the updater in that process. The game won't ever touch the pipe
again. It's just there to block the child app until the game terminates.
- The updater has no UI. It writes a log file.
- The updater downloads a manifest from a known URL over https://, using
libCurl. The base URL is platform-specific (it might be
https://example.com/mac/, or https://example.com/linux-x86/, whatever).
The url might have other features, like a updater version or a specific
product name, etc.
The manifest is at $BASEURL/manifest.txt
- The updater also downloads $BASEURL/manifest.txt.sig, which is a digital
signature for the manifest. It checks the manifest against this signature
and a known public RSA key; if the manifest doesn't match the signature,
the updater refuses to continue.
- The manifest looks like this: three lines per item...
Contents/MacOS/baseq3/uix86_64.dylib
332428
a49bbe77f8eb6c195265ea136f881f7830db58e4d8a883b27f59e1e23e396a20
- That's the file's path, its size in bytes, and an sha256 hash of the data.
- The file will be at this path under the base url on the webserver.
- The manifest only lists files that ever needed updating; it's not necessary
to list every file in the game's installation (unless you want to allow the
entire game to download).
- The updater will check each item in the manifest:
- Does the file not exist in the install? Needs downloading.
- Does the file have a different size? Needs downloading.
- Does the file have a different sha256sum? Needs downloading.
- Otherwise, file is up to date, leave it alone.
- If an item needs downloading, do these same checks against the file in the
download directory (if it's already there and matches, don't download again.)
- Download necessary files with libcurl, put it in a download directory.
- The downloaded file is also checked for size and sha256 vs the manifest, to
make sure there was no corruption or confusion. If a downloaded file doesn't
match what was expected, the updater aborts and will try again next time.
This could fail checksum due to i/o errors and compromised security, but
it might just be that a new version was being published and bad luck
happened, and a retry later could correct everything.
- If the updater itself needs upgrading, we deal with that first. It's
downloaded, then the updater relaunches from the downloaded binary with
a special command line. That relaunched process copies itself to the proper
location, and then relaunches _again_ to restart the normal updating
process with the new updater in its correct position.
- Once the downloads are complete and the updater itself doesn't need
upgrading, we are ready to start the normal upgrade. Since we can't replace
executables on some platforms while they are running, and swapping out a
game's data files at runtime isn't wise in general, the updater will now
block until the game terminates. It does this by reading on the pipe that
the game created when forking the updater; since the game never writes
anything to this pipe, it causes the updater to block until the pipe closes.
Since the game never deliberately closes the pipe either, it remains open
until the OS forcibly closes it as the game process terminates. Being an
unnamed pipe, it just vaporizes at this point, leaving no state that might
accidentally hang us up later, like a global semaphore or whatnot. This
technique also lets us localize the game's code changes to one small block
of C code, with no need to manage these resources elsewhere.
- As a sanity check, the updater will also kill(game_process_id, 0) until it
fails, sleeping for 100 milliseconds between each attempt, in case the
process is still being cleaned up by the OS after closing the pipe.
- Once the updater is confident the game process is gone, it will start
upgrading the appropriate files. It does this in two steps: it moves
the old file to a "rollback" directory so it's out of the way but still
available, then it moves the newly-downloaded file into place. Since these
are all simple renames and not copies, this can move fast. Any missing
parent directories are created, in case the update is adding a new file
in a directory that didn't previously exist.
- If something goes wrong at this point (file i/o error, etc), the updater
will roll back the changes by deleting the updated files, and moving the
files in the "rollback" directory back to their original locations. Then
the updater aborts.
- If nothing went wrong, the rollback files are deleted. And we are officially
up to date! The updater terminates.
The updater is designed to fail at any point. If a download fails, it'll
pick up and try again next time, etc. Completed downloads will remain, so it
will just need to download any missing/incomplete files.
The server side just needs to be able to serve static files over HTTPS from
any standard Apache/nginx/whatever process.
Failure points:
- If the updater fails when still downloading data, it just picks up on next
restart.
- If the updater fails when replacing files, it rolls back any changes it has
made.
- If the updater fails when rolling back, then running the updater again after
fixing the specific problem (disk error, etc?) will redownload and replace
any files that were left in an uncertain state. The only true point of
risk is crashing during a rollback and then having the updater bricked for
some reason, but that's an extremely small surface area, knock on wood.
- If the updater crashes or totally bricks, ioquake3 should just keep being
ioquake3. It will still launch and play, even if the updater is quietly
segfaulting in the background on startup.
- If an update bricks ioquake3 to the point where it can't run the updater,
running the updater directly should let it recover (assuming a future update
fixes the problem).
- If the download server is compromised, they would need the private key
(not stored on the download server) to alter the manifest to serve
compromised files to players. If they try to change a file or the manifest,
the updater will know to abort without updating anything.
- If the private key is compromised, we generate a new one, ship new
installers with an updated public key, and re-sign the manifest with the
new private key. Existing installations will never update again until they
do a fresh install, or at least update their copy of the public key.
How manifest signing works:
Some admin will generate a public/private key with the rsa_make_keys program,
keeping the private key secret. Using the private key and the rsa_sign
program, the admin will sign the manifest, generating manifest.txt.sig.
The public key ships with the game (adding 270 bytes to the download), the
.sig is downloaded with the manifest by the autoupdater (256 bytes extra
download), then the autoupdater checks the manifest against the signature
with the public key. if the signature isn't valid (the manifest was tampered
with or corrupt), the autoupdater refuses to continue.
If the manifest is to be trusted, it lists sha256 checksums for every file to
download, so there's no need to sign every file; if they can't tamper with the
manifest, they can't tamper with any other file to be updated since the file's
listed sha256 won't match.
If the private key is compromised, we generate new keys and ship new
installers, so new installations will be able to update but existing ones
will need to do a new install to keep getting updates. Don't let the private
key get compromised. The private key doesn't go on a public server. Maybe it
doesn't even live on the admin's laptop hard drive.
If the download server is compromised and serving malware, the autoupdater
will reject it outright if they haven't compromised the private key, generated
a new manifest, and signed it with the private key.
Items to consider for future revisions:
- Maybe put a limit on the number manifest downloads, so we only check once
every hour? Every day?
- Channels? Stable (what everyone gets by default), Nightly (once a day),
Experimental (some other work-in-progress branch), Bloody (literally the
latest commit).
- Let mods update, separate from the main game?
Questions? Ask Ryan: icculus@icculus.org
--ryan.
+145
View File
@@ -0,0 +1,145 @@
Quake III Arena GPL source release
==================================
This file contains the following sections:
LICENSE
GENERAL NOTES
LICENSE
=======
See COPYING.txt for the GNU GENERAL PUBLIC LICENSE
Some source code in this release is not covered by the GPL:
IO on .zip files using portions of zlib
-----------------------------------------------------------------------------
lines file(s)
4299 code/qcommon/unzip.c
4546 libs/pak/unzip.cpp
Copyright (C) 1998 Gilles Vollant
zlib is Copyright (C) 1995-1998 Jean-loup Gailly and Mark Adler
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
standard C library replacement routines
-----------------------------------------------------------------------------
lines file(s)
1324 code/game/bg_lib.c
Copyright (c) 1992, 1993
The Regents of the University of California. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
3. Neither the name of the University nor the names of its contributors
may be used to endorse or promote products derived from this software
without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
SUCH DAMAGE.
ADPCM coder/decoder
-----------------------------------------------------------------------------
lines file(s)
330 code/client/snd_adpcm.c
Copyright 1992 by Stichting Mathematisch Centrum, Amsterdam, The
Netherlands.
All Rights Reserved
Permission to use, copy, modify, and distribute this software and its
documentation for any purpose and without fee is hereby granted,
provided that the above copyright notice appear in all copies and that
both that copyright notice and this permission notice appear in
supporting documentation, and that the names of Stichting Mathematisch
Centrum or CWI not be used in advertising or publicity pertaining to
distribution of the software without specific, written prior permission.
STICHTING MATHEMATISCH CENTRUM DISCLAIMS ALL WARRANTIES WITH REGARD TO
THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH CENTRUM BE LIABLE
FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
JPEG library
-----------------------------------------------------------------------------
code/jpeg-6
libs/jpeg6
Copyright (C) 1991-1995, Thomas G. Lane
Permission is hereby granted to use, copy, modify, and distribute this
software (or portions thereof) for any purpose, without fee, subject to these
conditions:
(1) If any part of the source code for this software is distributed, then this
README file must be included, with this copyright and no-warranty notice
unaltered; and any additions, deletions, or changes to the original files
must be clearly indicated in accompanying documentation.
(2) If only executable code is distributed, then the accompanying
documentation must state that "this software is based in part on the work of
the Independent JPEG Group".
(3) Permission for use of this software is granted only if the user accepts
full responsibility for any undesirable consequences; the authors accept
NO LIABILITY for damages of any kind.
These conditions apply to any software derived from or based on the IJG code,
not just to the unmodified library. If you use our work, you ought to
acknowledge us.
NOTE: unfortunately the README that came with our copy of the library has
been lost, so the one from release 6b is included instead. There are a few
'glue type' modifications to the library to make it easier to use from
the engine, but otherwise the dependency can be easily cleaned up to a
better release of the library.
GENERAL NOTES
=============
A short summary of the file layout:
code/ Quake III Arena source code ( renderer, game code, OS layer etc. )
code/bspc bot routes compiler source code
lcc/ the retargetable C compiler ( produces assembly to be turned into qvm bytecode by q3asm )
q3asm/ assembly to qvm bytecode compiler
q3map/ map compiler ( .map -> .bsp ) - this is the version that comes with Q3Radiant 200f
q3radiant/ Q3Radiant map editor build 200f ( common/ and libs/ are support dirs for radiant )
While we made sure we were still able to compile the game on Windows, GNU/Linux
and Mac, this build didn't get any kind of extensive testing so it may not work
completely right. Whenever an id game is released under GPL, several projects
start making the source code more friendly to nowaday's compilers and
environements. If you are picking up this release weeks/months/years after we
uploaded it, you probably want to look around on the net for cleaned up
versions of this codebase as well.
+54
View File
@@ -0,0 +1,54 @@
##########################################################
# Info about the MD4 format supported by the ioQ3 engine #
##########################################################
All models included with the original version of Quake3 from id soft are in
the MD3 format. Animations in this format are realized by saving the position
of every vertex in each frame which can make these files pretty large.
ID started work on a newer format, the MD4 format which they never finished.
This format uses a skeleton with all vertices "attached" to their bones.
Because only the position of the bones must be stored for each frame and the
number of bones is not very high this format is more efficient when
doing animations.
Raven software "finished" this format originally started by ID and included
it in their game EliteForce. They called their model format "MDR" which is
the name I have used throughout the sourcecode and I will continue using in
this readme. Since the code on how to handle those MDR files was released
under a GPL licence a long time ago, I was able to implement this format for
Quake3 and do some efficiency improvements.
To enable the support for this model format, go to qcommon/qfiles.h,
remove the comment slashes for #define RAVENMD4 and then compile the engine.
Including finished MDR models in your projects is easy: just load the model
files in your cgame code as you would normally load an MD3 model. The engine
will expect the models to have a ".mdr" suffix.
The rest is pretty much the same: Selecting the current animation frame,
adding a skin to the model, etc..
You can check out the original eliteforce game sourcecode if you want to
have examples on using the md4s. The source can be got at:
http://eliteforce2.filefront.com/
You can also get reference MDR files there, just go to the model/skin
section there and pick something to download.
Now here comes the tricky part:
Creating files with this format. There are tools to create these kinds of
MDR files, like a plugin for Milkshape.
A pretty good overview about MDR file creation is available at
http://synapse.vgfort.com/
You can find some tools for creating MDR files there.
On a sidenote:
There is an independent implementation of the MD4 file format available
here:
http://gongo.quakedev.com/
At this time, ioquake3 has no support for these models though that may
change in the future. Nevertheless, he has got a tool for skeletal
animations that can possibly be hooked into the MDR format with some
modifications.
Good luck!
- Thilo Schulz
+622
View File
@@ -0,0 +1,622 @@
# OpenGL2
<insert ascii art here>
OpenGL2 is an alternate renderer for ioquake3. It aims to implement modern
features and technologies into the id tech 3 engine, but without sacrificing
compatibility with existing Quake 3 mods.
-------------------------------------------------------------------------------
FEATURES
-------------------------------------------------------------------------------
- Compatible with most vanilla Quake 3 mods.
- HDR Rendering, and support for HDR lightmaps
- Tone mapping and auto-exposure.
- Cascaded shadow maps.
- Multisample anti-aliasing.
- Texture upsampling.
- Advanced materials support.
- Advanced shading and specular methods.
- RGTC and BPTC texture compression support.
- Screen-space ambient occlusion.
-------------------------------------------------------------------------------
INSTALLATION
-------------------------------------------------------------------------------
For *nix:
1. This should be identical to installing ioq3. Check their README for more
details.
For Win32:
1. Have a Quake 3 install, fully patched.
2. Copy the following files into Quake 3's install directory:
ioquake3.x86.exe
renderer_opengl1_x86.dll
renderer_opengl2_x86.dll
These can be found in build/release-mingw32-x86 after compiling, or bug
someone to release binaries.
-------------------------------------------------------------------------------
RUNNING
-------------------------------------------------------------------------------
1. Start ioquake3. (ioquake3.x86.exe on Win32)
2. Open the console (the default key is tilde ~) and type
`/cl_renderer opengl2` and press enter
`/vid_restart` then press enter again.
3. Enjoy.
-------------------------------------------------------------------------------
CVARS
-------------------------------------------------------------------------------
Cvars for API:
* `r_preferOpenGLES` - This sets the preference for using OpenGL or OpenGL ES 2.
Many features are not supported when using OpenGL ES such as sun shadows and HDR.
1 - Prefer OpenGL ES 2+.
0 - Prefer desktop OpenGL.
-1 - Automatically pick (default).
Cvars for simple rendering features:
* `r_ext_compressed_textures` - Automatically compress textures.
0 - No texture compression. (default)
1 - DXT/RGTC texture compression if
supported.
2 - BPTC texture compression if supported.
* `r_ext_framebuffer_multisample` - Multisample Anti-aliasing.
0 - None. (default)
1-16 - Some.
17+ - Too much!
* `r_ssao` - Enable screen-space ambient occlusion.
Currently eats framerate and has some
visible artifacts.
0 - No. (default)
1 - Yes.
Cvars for HDR and tonemapping:
* `r_hdr` - Do scene rendering in a framebuffer with
high dynamic range. (Less banding, and
exposure changes look much better)
0 - No.
1 - Yes. (default)
* `r_cameraExposure` - Cheat. Alter brightness, in powers of two.
-2 - 4x as dark.
0 - Normal. (default)
0.5 - Sqrt(2)x as bright.
2 - 4x as bright.
* `r_postProcess` - Enable post-processing.
0 - No.
1 - Yes. (default)
* `r_toneMap` - Enable tone mapping. Requires
r_hdr and r_postProcess.
0 - No.
1 - Yes. (default)
* `r_forceToneMap` - Cheat. Override built-in and map tonemap settings and use cvars r_forceToneMapAvg, r_forceToneMapMin, and r_forceToneMapMax.
0 - No. (default)
1 - Yes.
* `r_forceToneMapAvg` - Cheat. Map average scene luminance to this
value, in powers of two. Requires
r_forceToneMap.
-2.0 - Dark.
-1.0 - Kinda dark. (default).
2.0 - Too bright.
* `r_forceToneMapMin` - Cheat. After mapping average, luminance
below this level is mapped to black.
Requires r_forceToneMap.
-5 - Not noticeable.
-3.25 - Normal. (default)
0.0 - Too dark.
* `r_forceToneMapMin` - Cheat. After mapping average, luminance
above this level is mapped to white.
Requires r_forceToneMap.
0.0 - Too bright.
1.0 - Normal. (default).
2.0 - Washed out.
* `r_autoExposure` - Do automatic exposure based on scene
brightness. Hardcoded to -2 to 2 on maps
that don't specify otherwise. Requires
r_hdr, r_postprocess, and r_toneMap.
0 - No.
1 - Yes. (default)
* `r_forceAutoExposure` - Cheat. Override built-in and map auto
exposure settings and use cvars
r_forceAutoExposureMin and
r_forceAutoExposureMax.
0 - No. (default)
1 - Yes.
* `r_forceAutoExposureMin` - Cheat. Set minimum exposure to this value,
in powers of two. Requires
r_forceAutoExpsure.
-3.0 - Dimmer.
-2.0 - Normal. (default)
-1.0 - Brighter.
* `r_forceAutoExposureMax` - Cheat. Set maximum exposure to this value,
in powers of two. Requires
r_forceAutoExpsure.
1.0 - Dimmer.
2.0 - Normal. (default)
3.0 - Brighter.
Cvars for advanced material usage:
* `r_normalMapping` - Enable normal maps for materials that
support it.
0 - No.
1 - Yes. (default)
* `r_specularMapping` - Enable specular maps for materials that
support it.
0 - No.
1 - Yes. (default)
* `r_deluxeMapping` - Enable deluxe mapping. (Map is compiled
with light directions.) Even if the map
doesn't have deluxe mapping compiled in,
an approximation based on the lightgrid
will be used.
0 - No.
1 - Yes. (default)
* `r_parallaxMapping` - Enable parallax mapping for materials that
support it.
0 - No. (default)
1 - Use parallax occlusion mapping.
2 - Use relief mapping. (slower)
* `r_parallaxMapOffset` - Set the parallax height offset.
0 - Values map to -255 - 0. (default)
0.5 - Values map to -127 - 127.
1.0 - Values map to 0 - 255.
* `r_parallaxMapShadows` - Enable self-shadowing on parallax map
supported materials.
0 - No. (default)
1 - Yes.
* `r_baseSpecular` - Set the specular reflectance of materials
which don't include a specular map or
use the specularReflectance keyword.
0 - No.
0.04 - Realistic. (default)
1.0 - Ack.
* `r_baseGloss` - Set the glossiness of materials which don't
include a specular map or use the
specularExponent keyword.
0 - Rough.
0.3 - Default.
1.0 - Shiny.
* `r_baseNormalX` - Set the scale of the X values from normal
maps when the normalScale keyword is not
used.
-1 - Flip X.
0 - Ignore X.
1 - Normal X. (default)
2 - Double X.
* `r_baseNormalY` - Set the scale of the Y values from normal
maps when the normalScale keyword is not
used.
-1 - Flip Y.
0 - Ignore Y.
1 - Normal Y. (default)
2 - Double Y.
* `r_baseParallax` - Sets the scale of the parallax effect for
materials when the parallaxDepth keyword
is not used.
0 - No depth.
0.01 - Pretty smooth.
0.05 - Standard depth. (default)
0.1 - Looks broken.
* `r_pbr` - Enable physically based rendering.
Experimental, will not look correct without
assets meant for it.
0 - No. (default)
1 - Yes.
Cvars for image interpolation and generation:
* `r_imageUpsample` - Use interpolation to artificially increase
the resolution of all textures. Looks good
in certain circumstances.
0 - No. (default)
1 - 2x size.
2 - 4x size.
3 - 8x size, etc
* `r_imageUpsampleMaxSize` - Maximum texture size when upsampling
textures.
1024 - Default.
2048 - Really nice.
4096 - Really slow.
8192 - Crash.
* `r_imageUpsampleType` - Type of interpolation when upsampling
textures.
0 - None. (probably broken)
1 - Bad but fast (default,
FCBI without second derivatives)
2 - Okay but slow (normal FCBI)
* `r_genNormalMaps` - Naively generate normal maps for all
textures.
0 - Don't. (default)
1 - Do.
Cvars for the sunlight and cascaded shadow maps:
* `r_forceSun` - Cheat. Force sunlight and shadows, using sun position from sky material.
0 - Don't. (default)
1 - Do.
2 - Sunrise, sunset.
* `r_forceSunLightScale` - Cheat. Scale sun brightness by this factor
when r_forceSun 1.
1.0 - Default
* `r_forceSunAmbientScale` - Cheat. Scale sun ambient brightness by this factor when r_forceSun 1. 0.5 - Default
* `r_sunShadows` - Enable sunlight and cascaded shadow maps for
it on maps that support it.
0 - No.
1 - Yes. (default)
* `r_sunlightMode` - Specify the method used to add sunlight to
the scene.
0 - No.
1 - Multiply lit areas by light scale, and
shadowed areas by ambient scale.
(default)
2 - Add light. Looks better, but is slower
and doesn't integrate well with existing
maps.
* `r_shadowFilter` - Enable filtering shadows for a smoother
look.
0 - No.
1 - Some. (default)
2 - Much.
* `r_shadowMapSize` - Size of each cascaded shadow map.
256 - 256x256, ugly, probably shouldn't
go below this.
512 - 512x512, passable.
1024 - 1024x1024, good. (default)
2048 - 2048x2048, extreme.
4096 - 4096x4096, indistinguishable from
2048.
Cvars that you probably don't care about or shouldn't mess with:
* `r_depthPrepass` - Do a depth-only pass before rendering.
Speeds up rendering in cases where advanced
features are used. Required for
r_sunShadows.
0 - No.
1 - Yes. (default)
* `r_mergeLightmaps` - Merge the small (128x128) lightmaps into
2 or fewer giant (4096x4096) lightmaps.
Easy speedup.
0 - Don't.
1 - Do. (default)
* `r_shadowCascadeZNear` - Near plane for shadow cascade frustums.
4 - Default.
* `r_shadowCascadeZFar` - Far plane for shadow cascade frustums.
3072 - Default.
* `r_shadowCascadeZBias` - Z-bias for shadow cascade frustums.
-256 - Default.
Cvars that have broken bits:
* `r_dlightMode` - Change how dynamic lights look.
0 - Quake 3 style dlights, fake
brightening. (default)
1 - Actual lighting, no shadows.
2 - Light and shadows. (broken)
* `r_pshadowDist` - Virtual camera distance when creating shadowmaps for projected shadows. Deprecated.
* `cg_shadows` - Old shadow code. Deprecated.
-------------------------------------------------------------------------------
MATERIALS
-------------------------------------------------------------------------------
OpenGL2 supports .mtr files, which are basically the same as .shader files, and
are located in the same place, but override existing .shader files if they
exist. This is to allow maps and mods to use the new material features without
breaking the map when using the old renderer.
Here's an example of a material stored in one, showing off some new features:
textures/abandon/grass
{
qer_editorimage textures/abandon/grass.jpg
{
map textures/abandon/grass3_256_d.jpg
rgbgen identity
}
{
stage normalparallaxmap
map textures/abandon/grass3_1024_n.png
normalScale 1 1
parallaxDepth 0.05
}
{
stage specularmap
map textures/abandon/grass3_256_s.png
specularReflectance 0.12
specularExponent 16
}
{
map $lightmap
blendfunc GL_DST_COLOR GL_ZERO
}
}
The first thing to notice is that this is basically the same as old Quake 3
shader files. The next thing to notice are the new keywords. Here is what
they mean:
`stage <type>`
- State how this imagemap will be used by OpenGL2:
diffuseMap - Standard, same as no stage entry
normalMap - Image will be used as a normal map
normalParallaxMap - Image will be used as a normal map with
alpha treated as height for parallax mapping
specularMap - Image will be used as a specular map with
alpha treated as shininess.
`specularReflectance <value>`
- State how metallic this material is. Metals typically have a high
specular and a low diffuse, so this is typically high for them, and low
for other materials, such as plastic. For typical values for various
materials, see http://refractiveindex.info , pick a material, then scroll
down to the reflection calculator and look up its reflectance. Default
is 0.04, since most materials aren't metallic.
`specularExponent <value>`
- State how shiny this material is. Note that this is modulated by the
alpha channel of the specular map, so if it were set to 16, and the alpha
channel of the specular map was set to 0.5, then the shininess would be
set to 8. Default 256.
`normalScale <x> <y>`
- State the X and Y scales of the normal map. This is useful for increasing
or decreasing the "strength" of the normal map, or entering negative values
to flip the X and/or Y values. Default 1 1.
`parallaxDepth <value>`
- State the maximum depth of the parallax map. This is a fairly sensitive
value, and I recommend the default or lower. Default 0.05.
An important note is that normal and specular maps influence the diffuse map
declared before them, so materials like this are possible:
textures/terrain/grass
{
qer_editorimage textures/terrain/grass.jpg
{
map textures/terrain/rock.jpg
}
{
stage normalparallaxmap
map textures/terrain/rock_n.png
}
{
stage specularmap
map textures/terrain/rock_s.jpg
}
{
map textures/terrain/grass.jpg
blendFunc GL_SRC_ALPHA GL_ONE_MINUS_SRC_ALPHA
alphaGen vertex
}
{
stage normalparallaxmap
map textures/terrain/grass_n.png
}
{
stage specularmap
map textures/terrain/grass_s.png
specularReflectance 0.12
}
{
map $lightmap
blendfunc GL_DST_COLOR GL_ZERO
}
}
Though note due to the complexity of lighting, dynamic light (including
sunlight with cascaded shadow maps) currently only works 100% on materials like
this, where the second diffuse map doesn't have its own alpha, and only
uses vertex alpha. YMMV.
Another addition to materials is working normal/specular maps on vertex lit
surfaces. To enable this, make your material look like this:
textures/vehicles/car
{
qer_editorimage textures/vehicles/car.jpg
{
map textures/vehicles/car.jpg
rgbGen vertexLit
}
{
stage normalparallaxmap
map textures/vehicles/car_n.jpg
}
{
stage specularmap
map textures/vehicles/car_s.jpg
}
}
Note the new keyword, 'vertexLit' after rgbGen. This is analogous to
'rgbGen vertex', except a light direction will be determined from the lightgrid
and used with the normal and specular maps. 'exactVertexLit' exists as well,
and is the equivalent for 'exactVertex'.
-------------------------------------------------------------------------------
DYNAMIC SUNLIGHT AND CASCADED SHADOW MAPS
-------------------------------------------------------------------------------
This adds a new keyword to sky materials, q3gl2_sun. The syntax is:
q3gl2_sun <red> <green> <blue> <intensity> <degrees> <elevation> <shadowScale>
Note the first six parameters are the same as in q3map_sun or q3map_sunExt,
and the last two indicate scaling factors for the map brightness and an ambient
light of the same color as the sun.
There are currently two ways to use this in your own (and other people's) maps.
1. Create your map as normal, set r_sunlightMode to 1, and add a
'q3gl2_sun' line after your 'q3map_sun' line in your sky material, like
so:
textures/skies/bluesky
{
qer_editorimage textures/skies/bluesky.jpg
surfaceparm nomarks
surfaceparm noimpact
surfaceparm nolightmap
surfaceparm sky
q3map_sunExt 240 238 200 100 195 35 3 16
q3gl2_sun 240 238 200 50 195 35 0.2
q3map_skylight 50 16
q3map_lightimage $whiteimage
skyparms env/bluesky - -
}
The advantages with this method are that your map will continue to work
with the old renderer with the sunlight baked into the lightmap, and it
can be used with existing maps without recompilation. The downside is
artifacts like doubled shadows and uneven shadow edges.
2. Set r_sunlightMode to 2 and use 'q3gl2_sun' instead of 'q3map_sun' or
'q3map_sunExt', like so:
textures/skies/bluesky
{
qer_editorimage textures/skies/bluesky.jpg
surfaceparm nomarks
surfaceparm noimpact
surfaceparm nolightmap
surfaceparm sky
q3gl2_sun 240 238 200 50 195 35 0.2
q3map_skylight 50 16
q3map_lightimage $whiteimage
skyparms env/bluesky - -
}
The advantages with this method are that you don't get the artifacts that
characterize the other method, and your map compiles a lot faster without
the sunlight bouncing calculations. The downsides are that your map will
not display properly with the old renderer, and you lose the bounced light
that compiling the map with q3map_sun* in it would have.
-------------------------------------------------------------------------------
TONE MAPPING AND AUTO EXPOSURE
-------------------------------------------------------------------------------
This adds a new keyword to sky materials, q3gl2_tonemap. The syntax is:
q3gl2_tonemap <toneMapMin> <toneMapAvg> <toneMapMax> <autoExposureMin> <autoExposureMax>
Each of these settings corresponds to a matching cvar, so you can view and
adjust the effect before settling on fixed settings.
-------------------------------------------------------------------------------
THANKS
-------------------------------------------------------------------------------
I'd like to take this part of the readme to thank the numerous people who
contributed thoughts, ideas, and whole swaths of code to this project.
- Id Software, for creating Quake 3 and releasing its source code under a
GPL license, without which this project would not be possible.
- Zachary 'Zakk' Slater, Thilo Schulz, Tim Angus, and the rest of the
ioquake3 team and contributors, for improving massively upon the raw Quake
3 source, and accepting my and gimhael's modular renderer patch.
- Robert 'Tr3B' Beckebans and the other contributors to XReaL, for letting me
liberally copy code from you. :)
- Andrew 'Black Monk' Prosnik, Andrei 'Makro' Drexler, Tomi 'T.T.I.' Isoaho,
Richard 'JBravo' Allen, Walter 'Johnny Rocket' Somol, and the rest of the
Boomstick Studios, for contributing code, feature requests, and testing.
- Yoshiharu Gotanda, Tatsuya Shoji, and the rest of tri-Ace's R&D Department,
for creating the tri-Ace shading equations and posting their derivations in
simple English.
- Matthias 'gimhael' Bentrup, for random ideas and bits of code.
- Evan 'megatog615' Goers, for testing, ideas, and bugging me just enough
that I'd write documentation. :)
- The folks at #ioquake3, who don't seem to mind when I suddenly drop a
screenshot and insist on talking about it. :)
- And lots of various other random people, who posted on forums, blogs, and
Wikipedia, who helped in small but numerous ways.
If I missed you in this section, feel free to drop me a line and I'll add you.
-------------------------------------------------------------------------------
CONTACT
-------------------------------------------------------------------------------
My name is James Canete, and I wrote most of this readme. Also, a renderer.
If you wish to get in touch with me, try my GMail at use.less01 (you should be
able to solve this), or look for SmileTheory in #ioquake3 on irc.freenode.net.
+202
View File
@@ -0,0 +1,202 @@
ioquake3 VoIP support documentation.
Last updated 6/25/2008 by Ryan C. Gordon.
There are two ways to use VoIP in ioquake3. You can either use Mumble as an
external program, for which ioq3 now supplies some basic hooks, or you can
use the new built-in VoIP support.
Mumble is here: http://mumble.sourceforge.net/ ... ioquake3 can supply it
with your in-game position, but everything else is whatever features Mumble
offers outside of the game. To use it, start Mumble before you start ioq3,
and run the game with +set cl_useMumble 1. This should work on at least
Linux, Mac OS X, and Windows, and probably other platforms Mumble supports
in the future.
The built-in stuff offers tighter in-game integration, works on any platform
that ioquake3 supports, and doesn't require anything more than a recent build
of the game. The rest of this document is concerned with the built-in VoIP
support.
Quick start for servers:
- run a recent build of ioquake3.
- Make sure your network settings are set to broadband.
Quick start for clients:
- run a recent build of ioquake3.
- Make sure your network settings are set to broadband.
- +set s_useOpenAL 1
- \bind q "+voiprecord"
- Hook up a microphone, connect to a VoIP-supporting server.
- hold down 'q' key and talk.
Cvars you can set:
sv_voip: set to "1" (the default) to enable server-side VoIP support. Set to
"0" to disable. Without this, all VoIP packets are refused by the
server, which means no one gets to use in-game VoIP.
cl_voip: set to "1" (the default) to enable client-side VoIP support. Set to "0"
to disable. Without this, you will neither be able to transmit voice nor
hear other people.
s_alCapture: set to "1" (the default) to have the audio layer open an OpenAL
capture device. Without this set on sound startup, you'll never
get bits from the microphone. This means you won't transmit, but
you can still hear other people.
cl_voipSendTarget: a string: "all" to broadcast to everyone, "none" to send
to no one, "attacker" to send to the last person that hit
you, "crosshair" to send to the people currently in your
crosshair, "spatial" to talk to all people in hearing
range or a comma-separated list of client numbers, like
"0,7,2,23" ... an empty string is treated like "spatial".
You can also use a mixed string like
"0, spatial, 2, crosshair".
This is reset to "spatial" when connecting to a new server.
Presumably mods will manage this cvar, not people, but
keybind could be useful for the general cases. To send to
just your team, or the opposing team, or a buddy list, you
have to set a list of numbers.
cl_voipUseVAD: set to "1" to automatically send audio when the game thinks you
are talking, "0" (the default) to require the user to manually
start transmitting, presumably with a keybind.
cl_voipVADThreshold: only used if cl_voipUseVAD is "1" ... a value between
0.0 and 1.0 that signifies the volume of recorded audio
that the game considers to be speech. You can use this
to trim out breathing or perhaps the sound of your
fingers tapping the keyboard and only transmit audio
louder than that. You will have to experiment to find the
value that works best for your hardware and play style.
The default is "0.25", with "0.0" being silence and "1.0"
being pretty-darn-loud.
cl_voipSend: when set to "1", the game will capture audio from the microphone
and transmit it, when "0", the game will not. The game can
optimize for the "0" case (perhaps turning off audio recording).
Lots of things set this on and off, including cl_voipUseVAD, so
you probably should not touch this directly without knowing what
you're doing, but perhaps mods can make use of it.
cl_voipGainDuringCapture: This is the volume ("gain") of audio coming out of
your speakers while you are recording sound for
transmission. This is a value between 0.0 and 1.0,
zero being silence and one being no reduction in
volume. This prevents audio feedback and echo and
such, but if you're listening in headphones that
your mic won't pick up, you don't need to turn down
the gain. Default is 0.2 (20% of normal volume). You
ABSOLUTELY want to make your speakers quiet when you
record, if the microphone might pick it up!
cl_voipShowMeter: Set to "1" (the default) to show a volume meter as you are
recording from the microphone, so you can see how well the
game can "hear" you. Set to "0" to disable the display of
the meter.
cl_voipCaptureMult: Multiply recorded audio by this value after denoising.
Defaults to 2.0 to _double_ the volume of your voice.
This is to make you more audible if denoising eats away
too much data. Set this to 1.0 to get no change, less to
be quieter.
Console commands:
voip ignore <clientnum>
Turn off incoming voice from player number <clientnum>. This will refuse to
play any incoming audio from that player, and instruct the server to stop
sending it, to save bandwidth. Use unignore to reenable. This is reset to
unignored when (re)connecting to a server.
voip unignore <clientnum>
Turn on incoming voice from player number <clientnum>. This will start
playing audio from this player again if you've previously done a "voip
ignore", and instruct the server to start sending her voice packets to
you again.
voip muteall
Turn off all incoming voice. This will refuse to play any incoming audio,
and instruct the server to stop sending it, to save bandwidth. Use
unmuteall to reenable. This is reset to unmuted when (re)connecting to
a server.
voip unmuteall
Turn on incoming voice. This will start playing audio again if you've
previously done a "voip muteall", and instruct the server to start
sending voice packets to you again.
voip gain <clientnum> <gain>
Sets the volume ("gain") for player number <clientnum> to <gain> ...
A gain of 0.0 is silence, and 2.0 doubles the volume. Use this if someone
is too quiet or too loud.
Actions:
+voiprecord: The action you should bind to a key to record. This basically
toggles cl_voipSend on and off. You don't need this if you're
using cl_voipUseVAD, since that'll just record all the time and
decide what parts of the recording are worth sending.
More detailed/technical info:
By default, all of this is enabled. You can build with or without VoIP
support explicitly with USE_VOIP=[1|0] on the make command line.
You currently must use OpenAL to speak, as we have ALC_EXT_capture support
in place to pull data from the microphone. If you are using the SDL backend,
you can still hear people, but not speak.
There is no in-game UI to speak of: we encourage mods to add some. Largely
they will just need to set cvars and run console commands for choosing
voice targets and ignoring people, etc.
This requires patched builds to be useful, but remains network compatible with
legacy quake3 clients and servers. Clients and servers both report in their
info strings whether they support VoIP, and won't send VoIP data to those not
reporting support. If a stray VoIP packet makes it to a legacy build, it will
be ignored without incident.
VoIP packets are saved in demo files! You will be able to playback what you
heard and what you said on VoIP-compatible clients. Legacy clients can also
play demo files with VoIP packets in them, but just won't play the voice
track. For VoIP-supported builds, it's nice to have a record of the
trash-talk.
Data is processed using the Speex narrowband codec, and is cross-platform.
Bigendian and littleendian systems can speak to each other, as can 32 and
64-bit platforms.
Bandwidth: VoIP data is broken up into 20 millisecond frames (this is a Speex
requirement), and we try to push up to 12 Speex frames in one UDP packet
(about a quarter of a second of audio)...we're using the narrowband codec:
8000Hz sample rate. In practice, a client should send about 2 kilobytes per
second more when speaking, spread over about four bursts per second, plus a
few bytes of state information. For comparison, this is less than the server
sends when downloading files to the client without an http redirect. The
server needs to rebroadcast the packet to all clients that should receive it
(which may be less than the total connected players), so servers should
assume they'll need to push (number of players speaking at once times number
of people that should hear it) * 2 kilobytes per second. It shouldn't be a
problem for any client or server on a broadband connection, although it may
be painful for dialup users (but then again, everything is. They can just
disable the cvar). The game will refuse to enable VoIP support if your have
your network settings lower than "Cable/xDSL/LAN", just in case.
The initial VoIP work was done by Ryan C. Gordon <icculus@icculus.org>, and
he can be contacted with technical questions, if the ioq3 mailing list or
forums aren't helpful.
// end of voip-README.txt ...