added OpenGL 3.2 and Direct3D 11 renderer back-ends

This commit is contained in:
myT 2019-09-25 05:25:59 +02:00
parent 6f3908ceaa
commit db4fb31658
68 changed files with 66649 additions and 20008 deletions

1
.gitignore vendored
View file

@ -8,6 +8,7 @@
*.idb
code/qcommon/git.h
code/win32/winquake.res
code/renderer/hlsl/*.h
makefiles/vs*/*sdf
makefiles/*/obj
.build

View file

@ -1,18 +1,115 @@
DD Mmm 19 - 1.52
add: r_backend <GL2|GL3|D3D11> (default: D3D11 on Windows, GL3 on Linux) selects the rendering back-end
GL2 - OpenGL 2.0 minimum, OpenGL 3+ features used for r_msaa
GL3 - OpenGL 3.2 minimum, OpenGL 4+ features used for faster geometry upload, compute shaders, etc
D3D11 - Direct3D 11 hardware feature level 10.1 minimum, feature level 11.0 for compute shaders
r_backend | GL2 | GL3 | D3D11 |
feature | | | |
-----------------------|--------|--------|--------------------|
MSAA | GL 3.0 | always | always |
depth sprites | never | always | always |
alpha to coverage AA | never | always | always |
dithering | never | always | always |
GPU mip-map generation | never | GL 4.3 | feature level 11.0 |
add: r_softSprite <0|1> (default: 1) enables depth sprites (soft particles)
this helps explosions, smoke, blood, etc. not having "sharp edges" when intersecting geometry
add: r_alphaToCoverage <0|1> (default: 1) enables alpha to coverage anti-aliasing
A2C AA can only work if MSAA is enabled (i.e. r_msaa > 1)
it is used to super-sample all fragments of alpha-tested surfaces
add: r_dither <0|1> (default: 0) enables the addition of noise to fight color banding artifacts
add: r_noiseScale <0.125 to 8.0> (default: 1.0) controls the strength of the dithering noise
add: r_gpuMipGen <0|1> (default: 1) enables GPU-side mip-map generation
this helps improve map load time (less to upload) and offers greater quality preservation options
add: r_mipGenGamma <1.0 to 3.0> (default: 1.8) specifies the gamma space in which the textures are stored
r_gpuMipGen 1 is required
it should be closer to 2.4 but defaults lower to not break the looks of some things (e.g. cpm3a tele)
while 1.0 will preserve the original engine's look, higher values will preserve contrast better
add: r_mipGenFilter <filter> (default: "L4") specified which filter window is used to generate mips
r_gpuMipGen 1 is required
the numbers specify the "radius" of the window filters
r_mipGenFilter L4 = Lanczos
r_mipGenFilter L3 = Lanczos
r_mipGenFilter BL = Bi-linear
r_mipGenFilter MN2 = Mitchell-Netravali (B = 1/3, C = 1/3)
r_mipGenFilter BH4 = 3-term Blackman-Harris
r_mipGenFilter BH3 = 3-term Blackman-Harris
r_mipGenFilter BH2 = 3-term Blackman-Harris
r_mipGenFilter T2 = Tent (1/3 2/3) -> same as the CPU version (r_gpuMipGen 0)
add: r_frameSleep <0|1|2> (default: 2) selects the frame capping mode
r_frameSleep 0 = forced OFF (when V-Sync is enabled)
r_frameSleep 1 = forced ON (when V-Sync is disabled)
r_frameSleep 2 = automatic (detects V-Sync status)
this only applies to OpenGL rendering back-ends
for Direct3D 11, the behavior is always equivalent to "automatic"
add: r_gl3_geoStream <0 to 4> (default: 0) sets the geometry upload strategy
r_gl3_geoStream 0 = decide automatically
r_gl3_geoStream 1 = BufferSubData
r_gl3_geoStream 2 = Map Unsychronized
r_gl3_geoStream 3 = Map Persistent when possible, else automatic
r_gl3_geoStream 4 = AMD pinned memory when available, else automatic
add: r_d3d11_syncOffsets <0|1|2> (default: 2) synchronizes vertex buffer offsets
r_d3d11_syncOffsets 0 = split buffer offsets (more data transferred)
r_d3d11_syncOffsets 1 = sync'd buffer offsets (more API calls)
r_d3d11_syncOffsets 2 = decide automatically
add: r_d3d11_maxQueuedFrames <1 to 16> (default: 3) set the maximum pre-rendered frame count
add: r_khr_debug <0|1|2> (default: 2) decides whether to create an OpenGL debug context
r_khr_debug 0 = forced OFF
r_khr_debug 1 = forced ON
r_khr_debug 2 = only in debug builds
add: r_mapBrightness now works on q3map2's external lightmap atlas images
add: the renderer can now batch surfaces with different (but sufficiently similar) shaders
this new optimization works with the output of "Frozen Sand Particle Studio"
chg: SSE2 instruction set support is now required
chg: removed FreeType 2 and the unused R_REGISTERFONT syscalls that were using it
chg: removed light flares and all related cvars (r_flare*)
chg: r_textureMode and r_measureOverdraw were removed
chg: r_speeds 1 now reports more precise timings, V-Sync status, GPU time and the selected back-end
chg: improved face and grid processing performance with SSE2
chg: r_lightmap is now latched again
the implementation is now more correct and will apply to all surfaces referencing a lightmap
it now also supports surfaces referencing q3map2's "external lightmap" atlas images
chg: r_fullbright is now latched again
it now also supports surfaces referencing q3map2's "external lightmap" atlas images
chg: negative r_swapInterval values will request adaptive v-sync when using an OpenGL back-end
fix: r_monitor on Linux is now 0-based and the value doesn't change incorrectly on its own anymore
fix: when a latched cvar's value is set to its default, the cvar is no longer marked as changed
fix: broken face normals get fixed up on map load, which helps with dynamic lights (e.g. industrial)
fix: classes of transparent surfaces (sprites, beams, etc) now get drawn in the right order
fix: dynamic lights can now affect transparent surfaces
fix: incorrect image flags for various things (clamp mode, mip generation, anisotropic filtering, ...)
31 Mar 19 - 1.51

View file

@ -657,6 +657,23 @@ static intptr_t CL_CgameSystemCalls( intptr_t *args )
}
static void CL_SetMaxFPS( int maxFPS )
{
if ( maxFPS > 0 && cls.maxFPS == 0 ) {
cls.maxFPS = maxFPS;
cls.nextFrameTimeMS = Sys_Milliseconds() + 1000 / maxFPS;
cls.oldSwapInterval = Cvar_VariableIntegerValue( "r_swapInterval" );
Cvar_Set( "r_swapInterval", "0" );
} else if ( maxFPS == 0 && cls.maxFPS > 0 ) {
cls.maxFPS = 0;
Cvar_Set( "r_swapInterval", va( "%i", cls.oldSwapInterval ) );
} else if ( maxFPS > 0 && cls.maxFPS > 0 ) {
cls.maxFPS = maxFPS;
cls.nextFrameTimeMS = Sys_Milliseconds() + 1000 / maxFPS;
}
}
void CL_InitCGame()
{
int t = Sys_Milliseconds();
@ -685,9 +702,9 @@ void CL_InitCGame()
// init for this gamestate
// use the lastExecutedServerCommand instead of the serverCommandSequence
// otherwise server commands sent just before a gamestate are dropped
re.SetMaxFPS( 10 );
CL_SetMaxFPS( 20 );
VM_Call( cgvm, CG_INIT, clc.serverMessageSequence, clc.lastExecutedServerCommand, clc.clientNum );
re.SetMaxFPS( 0 );
CL_SetMaxFPS( 0 );
// send a usercmd this frame, which will cause the server to send us the first snapshot
cls.state = CA_PRIMED;

View file

@ -115,9 +115,11 @@ typedef struct {
long roqF1;
long t[2];
long roqFPS;
int playonwalls;
byte* buf;
long drawX, drawY;
qbool grabbed;
qbool firstFrame;
} cin_cache;
static cinematics_t cin;
@ -133,6 +135,8 @@ void CIN_CloseAllVideos(void) {
if (cinTable[i].fileName[0] != 0 ) {
CIN_StopCinematic(i);
}
cinTable[i].grabbed = qfalse;
cinTable[i].firstFrame = qfalse;
}
}
@ -1106,6 +1110,7 @@ redump:
}
cinTable[currentHandle].numQuads++;
cinTable[currentHandle].dirty = qtrue;
cinTable[currentHandle].firstFrame = qtrue;
break;
case ROQ_CODEBOOK:
decodeCodeBook( framedata, (unsigned short)cinTable[currentHandle].roq_flags );
@ -1272,6 +1277,10 @@ SCR_StopCinematic
==================
*/
e_status CIN_StopCinematic(int handle) {
if (handle >= 0 && handle < MAX_VIDEO_HANDLES) {
cinTable[handle].grabbed = qfalse;
cinTable[handle].firstFrame = qfalse;
}
if (handle < 0 || handle>= MAX_VIDEO_HANDLES || cinTable[handle].status == FMV_EOF) return FMV_EOF;
currentHandle = handle;
@ -1308,11 +1317,6 @@ e_status CIN_RunCinematic( int handle )
RoQReset();
}
if (cinTable[handle].playonwalls < -1)
{
return cinTable[handle].status;
}
currentHandle = handle;
if (cinTable[currentHandle].alterGameState) {
@ -1413,17 +1417,17 @@ int CIN_PlayCinematic( const char *arg, int x, int y, int w, int h, int systemBi
cinTable[currentHandle].CIN_WIDTH = DEFAULT_CIN_WIDTH;
cinTable[currentHandle].holdAtEnd = (systemBits & CIN_hold) != 0;
cinTable[currentHandle].alterGameState = (systemBits & CIN_system) != 0;
cinTable[currentHandle].playonwalls = 1;
cinTable[currentHandle].silent = (systemBits & CIN_silent) != 0;
cinTable[currentHandle].shader = (systemBits & CIN_shader) != 0;
cinTable[currentHandle].dirty = qfalse;
cinTable[currentHandle].grabbed = qfalse;
cinTable[currentHandle].firstFrame = qfalse;
if (cinTable[currentHandle].alterGameState) {
// close the menu
if ( uivm ) {
VM_Call( uivm, UI_SET_ACTIVE_MENU, UIMENU_NONE );
}
} else {
cinTable[currentHandle].playonwalls = cl_inGameVideo->integer;
}
initRoQ();
@ -1598,26 +1602,24 @@ void SCR_StopCinematic()
}
void CIN_UploadCinematic(int handle) {
if (handle >= 0 && handle < MAX_VIDEO_HANDLES) {
if (!cinTable[handle].buf) {
return;
}
if (cinTable[handle].playonwalls <= 0 && cinTable[handle].dirty) {
if (cinTable[handle].playonwalls == 0) {
cinTable[handle].playonwalls = -1;
} else {
if (cinTable[handle].playonwalls == -1) {
cinTable[handle].playonwalls = -2;
} else {
cinTable[handle].dirty = qfalse;
}
}
}
re.UploadCinematic( 256, 256, 256, 256, cinTable[handle].buf, handle, cinTable[handle].dirty);
if (cl_inGameVideo->integer == 0 && cinTable[handle].playonwalls == 1) {
cinTable[handle].playonwalls--;
}
}
}
qbool CIN_GrabCinematic( int handle, int* w, int* h, const byte** data, int* client, qbool* dirty )
{
*client = -1;
if (handle < 0 && handle >= MAX_VIDEO_HANDLES)
return qfalse;
if (!cinTable[handle].buf)
return qfalse;
const qbool paused = cl_inGameVideo->integer == 0 && cinTable[handle].grabbed;
*w = 256;
*h = 256;
*data = cinTable[handle].buf;
*client = handle;
*dirty = cinTable[handle].dirty && !paused;
cinTable[handle].grabbed = cinTable[handle].firstFrame;
cinTable[handle].dirty = qfalse;
return qtrue;
}

106
code/client/cl_gl.cpp Normal file
View file

@ -0,0 +1,106 @@
/*
===========================================================================
Copyright (C) 2019 Gian 'myT' Schellenbaum
This file is part of Challenge Quake 3 (CNQ3).
Challenge Quake 3 is free software; you can redistribute it
and/or modify it under the terms of the GNU General Public License as
published by the Free Software Foundation; either version 2 of the License,
or (at your option) any later version.
Challenge Quake 3 is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Challenge Quake 3. If not, see <https://www.gnu.org/licenses/>.
===========================================================================
*/
// shared OpenGL client code for printing debug context output
#include "client.h"
#include "../renderer/tr_local.h"
#if defined(_WIN32) && defined(_DEBUG)
#include <Windows.h>
#endif
#include "GL/glew.h"
static const char* GL_DebugSourceString( GLenum source )
{
switch (source) {
case GL_DEBUG_SOURCE_API: return "API";
case GL_DEBUG_SOURCE_WINDOW_SYSTEM: return "window system";
case GL_DEBUG_SOURCE_SHADER_COMPILER: return "shader compiler";
case GL_DEBUG_SOURCE_THIRD_PARTY: return "third-party";
case GL_DEBUG_SOURCE_APPLICATION: return "application";
case GL_DEBUG_SOURCE_OTHER: return "other";
default: return "?";
}
}
static const char* GL_DebugTypeString( GLenum type )
{
switch (type) {
case GL_DEBUG_TYPE_ERROR: return "^1error";
case GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR: return "^1deprecated behavior";
case GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR: return "^1undefined behavior";
case GL_DEBUG_TYPE_PORTABILITY: return "portability";
case GL_DEBUG_TYPE_PERFORMANCE: return "^3performance";
case GL_DEBUG_TYPE_MARKER: return "marker";
case GL_DEBUG_TYPE_PUSH_GROUP: return "push group";
case GL_DEBUG_TYPE_POP_GROUP: return "pop group";
case GL_DEBUG_TYPE_OTHER: return "other";
default: return "?";
}
}
static const char* GL_DebugSeverityString( GLenum severity )
{
switch (severity) {
case GL_DEBUG_SEVERITY_LOW: return "low-severity";
case GL_DEBUG_SEVERITY_MEDIUM: return "medium-severity";
case GL_DEBUG_SEVERITY_HIGH: return "^3high-severity";
case GL_DEBUG_SEVERITY_NOTIFICATION: return "notification";
default: return "?";
}
}
static void GLAPIENTRY GL_DebugCallback( GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar* message, const void* userParam )
{
const char* msg = va(
"^5GL Debug: ^7%s^7/%s^7/%s^7: %s\n",
GL_DebugSeverityString(severity), GL_DebugSourceString(source), GL_DebugTypeString(type), message);
Com_Printf(msg);
#if defined(_WIN32) && defined(_DEBUG)
OutputDebugStringA(msg);
#endif
}
qbool CL_GL_WantDebug()
{
#if defined(_DEBUG)
return r_khr_debug->integer != 0;
#else
return r_khr_debug->integer == 1;
#endif
}
void CL_GL_Init()
{
const qbool enableDebug = CL_GL_WantDebug() && (GLEW_KHR_debug || GLEW_VERSION_4_3);
if (!enableDebug)
return;
glEnable(GL_DEBUG_OUTPUT);
glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS); // bad performance but can get access to the call stack...
glDebugMessageCallback(&GL_DebugCallback, NULL);
ri.Printf(PRINT_ALL, "OpenGL debug output is now active\n");
}

View file

@ -47,6 +47,8 @@ cvar_t *cl_inGameVideo;
cvar_t *cl_matchAlerts;
cvar_t *r_khr_debug;
clientActive_t cl;
clientConnection_t clc;
clientStatic_t cls;
@ -1559,6 +1561,12 @@ void CL_Frame( int msec )
}
qbool CL_ShouldSleep()
{
return re.ShouldSleep();
}
///////////////////////////////////////////////////////////////
@ -1698,6 +1706,7 @@ static void CL_InitRef()
ri.Printf = CL_RefPrintf;
ri.Error = Com_Error;
ri.Milliseconds = CL_ScaledMilliseconds;
ri.Microseconds = Sys_Microseconds;
ri.Malloc = CL_RefMalloc;
ri.Free = Z_Free;
#ifdef HUNK_DEBUG
@ -1720,7 +1729,7 @@ static void CL_InitRef()
// cinematic stuff
ri.CIN_UploadCinematic = CIN_UploadCinematic;
ri.CIN_GrabCinematic = CIN_GrabCinematic;
ri.CIN_PlayCinematic = CIN_PlayCinematic;
ri.CIN_RunCinematic = CIN_RunCinematic;
@ -2017,7 +2026,8 @@ static const cvarTableItem_t cl_cvars[] =
{ NULL, "rate", "25000", CVAR_USERINFO | CVAR_ARCHIVE, CVART_INTEGER, "4000", "99999", "network transfer rate" },
{ NULL, "snaps", "30", CVAR_USERINFO | CVAR_ARCHIVE, CVART_INTEGER }, // documented by the mod
{ NULL, "password", "", CVAR_USERINFO, CVART_STRING, NULL, NULL, "used by /" S_COLOR_CMD "connect" },
{ &cl_matchAlerts, "cl_matchAlerts", "7", CVAR_ARCHIVE, CVART_BITMASK, "0", XSTRING(MAF_MAX), help_cl_matchAlerts }
{ &cl_matchAlerts, "cl_matchAlerts", "7", CVAR_ARCHIVE, CVART_BITMASK, "0", XSTRING(MAF_MAX), help_cl_matchAlerts },
{ &r_khr_debug, "r_khr_debug", "2", CVAR_ARCHIVE, CVART_INTEGER, "0", "2", help_r_khr_debug }
};

View file

@ -32,6 +32,40 @@ static cvar_t* cl_graphscale;
static cvar_t* cl_graphshift;
struct intStats_t {
int samples[200];
int sampleCount;
int writeIndex;
int median;
int percentile99;
};
static int QDECL CompareSamples( const void* a, const void* b )
{
return *(const int*)b - *(const int*)a;
}
static void PushSample( intStats_t* stats, int sample )
{
stats->samples[stats->writeIndex] = sample;
stats->sampleCount = min(stats->sampleCount + 1, (int)ARRAY_LEN(stats->samples));
stats->writeIndex = (stats->writeIndex + 1) % ARRAY_LEN(stats->samples);
if ( stats->sampleCount < ARRAY_LEN(stats->samples) ) {
stats->median = 0;
stats->percentile99 = 0;
return;
}
static intStats_t temp;
memcpy( temp.samples, stats->samples, stats->sampleCount * sizeof(int) );
qsort( temp.samples, stats->sampleCount, sizeof(int), &CompareSamples );
stats->median = temp.samples[stats->sampleCount / 2];
stats->percentile99 = temp.samples[stats->sampleCount / 10];
}
// adjust for resolution and screen aspect ratio
void SCR_AdjustFrom640( float *x, float *y, float *w, float *h )
@ -86,8 +120,8 @@ void SCR_DrawChar( float x, float y, float cw, float ch, int c )
// draws a string with a drop shadow, optionally with colorcodes
void SCR_DrawStringEx( float x, float y, float cw, float ch, const char* string, drawStringColors_t colors, qbool showColorCodes, const float* firstColor )
void SCR_DrawStringEx( float x, float y, float cw, float ch, const char* string, drawStringColors_t colors, qbool showColorCodes, const float* firstColor )
{
float xx;
const char* s;
@ -115,7 +149,7 @@ void SCR_DrawStringEx( float x, float y, float cw, float ch, const char* string,
s = string;
xx = x;
if ( firstColor == NULL )
firstColor = colors == DSC_CONSOLE ? ConsoleColorFromChar( COLOR_WHITE ) : colorWhite;
firstColor = colors == DSC_CONSOLE ? ConsoleColorFromChar( COLOR_WHITE ) : colorWhite;
re.SetColor( firstColor );
while ( *s ) {
if ( Q_IsColorString( s ) ) {
@ -126,7 +160,7 @@ void SCR_DrawStringEx( float x, float y, float cw, float ch, const char* string,
if ( !showColorCodes ) {
s += 2;
continue;
}
}
}
SCR_DrawChar( xx, y, cw, ch, *s );
xx += cw;
@ -136,12 +170,12 @@ void SCR_DrawStringEx( float x, float y, float cw, float ch, const char* string,
re.SetColor( NULL );
}
// draws a string with a drop shadow, optionally with colorcodes
void SCR_DrawString(float x, float y, float cw, float ch, const char* s, qbool allowColor)
{
SCR_DrawStringEx( x, y, cw, ch, s, allowColor ? DSC_NORMAL : DSC_NONE, qfalse, NULL );
SCR_DrawStringEx( x, y, cw, ch, s, allowColor ? DSC_NORMAL : DSC_NONE, qfalse, NULL );
}
@ -344,15 +378,22 @@ static void SCR_DrawScreenField( stereoFrame_t stereoFrame )
static int pcFE[RF_STATS_MAX];
static int pc2D[RB_STATS_MAX];
static int pc3D[RB_STATS_MAX];
static intStats_t usecFE;
static intStats_t usec3D;
static intStats_t usecBS;
static intStats_t usecGPU;
static void SCR_PerformanceCounters()
{
qbool Sys_V_IsVSynced();
float x, y, cw = 8, ch = 12;
SCR_AdjustFrom640( 0, 0, &cw, &ch );
x = 0, y = 240;
SCR_AdjustFrom640( &x, &y, 0, 0 );
SCR_DrawString( x, y, cw, ch, va("FE: %ims", pcFE[RF_MSEC] ), qfalse ); y += ch;
SCR_DrawString( x, y, cw, ch, va("FE: %.2fms (99th: %.2fms)", usecFE.median / 1000.0f, usecFE.percentile99 / 1000.0f ), qfalse ); y += ch;
SCR_DrawString( x, y, cw, ch, va("Leaf/Area: %i %i", pcFE[RF_LEAF_CLUSTER], pcFE[RF_LEAF_AREA]), qfalse ); y += ch;
SCR_DrawString( x, y, cw, ch, va("FrusLeafs: %i", pcFE[RF_LEAFS]), qfalse ); y += ch;
SCR_DrawString( x, y, cw, ch, va("MD3 Cull S: %i %i %i", pcFE[RF_MD3_CULL_S_IN], pcFE[RF_MD3_CULL_S_CLIP], pcFE[RF_MD3_CULL_S_OUT]), qfalse ); y += ch;
@ -365,7 +406,11 @@ static void SCR_PerformanceCounters()
x = 240, y = 240;
SCR_AdjustFrom640( &x, &y, 0, 0 );
SCR_DrawString( x, y, cw, ch, va("3D: %ims", pc3D[RB_MSEC] ), qfalse ); y += ch;
SCR_DrawString( x, y, cw, ch, va("3D: %.2fms (99th: %.2fms)", usec3D.median / 1000.0f, usec3D.percentile99 / 1000.0f ), qfalse ); y += ch;
SCR_DrawString( x, y, cw, ch, va("End: %.2fms (99th: %.2fms)", usecBS.median / 1000.0f, usecBS.percentile99 / 1000.0f ), qfalse ); y += ch;
if ( usecGPU.sampleCount > 0 ) {
SCR_DrawString( x, y, cw, ch, va("GPU: %.2fms (99th: %.2fms)", usecGPU.median / 1000.0f, usecGPU.percentile99 / 1000.0f ), qfalse ); y += ch;
}
SCR_DrawString( x, y, cw, ch, va("Base Verts: %i", pc3D[RB_VERTICES]), qfalse ); y += ch;
SCR_DrawString( x, y, cw, ch, va("Base Tris: %i", pc3D[RB_INDICES] / 3), qfalse ); y += ch;
SCR_DrawString( x, y, cw, ch, va("Base Surfs: %i", pc3D[RB_SURFACES]), qfalse ); y += ch;
@ -386,6 +431,11 @@ static void SCR_PerformanceCounters()
SCR_DrawString( x, y, cw, ch, va("Indices: %i", pc2D[RB_INDICES]), qfalse ); y += ch;
SCR_DrawString( x, y, cw, ch, va("Surfaces: %i", pc2D[RB_SURFACES]), qfalse ); y += ch;
SCR_DrawString( x, y, cw, ch, va("Batches: %i", pc2D[RB_BATCHES]), qfalse ); y += ch;
x = 0, y = 480 - ch;
SCR_AdjustFrom640( &x, &y, 0, 0 );
SCR_DrawString( x, y, cw, ch, va("Back-end: %s", Cvar_VariableString("r_backend")), qfalse ); y -= ch;
SCR_DrawString( x, y, cw, ch, va("V-Sync : %s", Sys_V_IsVSynced() ? "ON" : "OFF"), qfalse ); y -= ch;
}
@ -397,6 +447,9 @@ void SCR_UpdateScreen()
if ( !scr_initialized )
return;
if ( cls.maxFPS > 0 && Sys_Milliseconds() < cls.nextFrameTimeMS )
return;
// there are several cases where this IS called twice in one frame
// easiest example is: conn to a server, kill the server
@ -414,19 +467,31 @@ void SCR_UpdateScreen()
const qbool drawFrame = CL_VideoRecording() || !Sys_IsMinimized();
SCR_DrawScreenField( STEREO_CENTER );
PushSample( &usecFE, pcFE[RF_USEC] );
PushSample( &usec3D, pc3D[RB_USEC] );
PushSample( &usecBS, pc3D[RB_USEC_END] );
if ( pc3D[RB_USEC_GPU] > 0 )
PushSample( &usecGPU, pc3D[RB_USEC_GPU] );
else
usecGPU.sampleCount = 0;
if ( com_speeds->integer ) {
re.EndFrame( pcFE, pc2D, pc3D, drawFrame );
time_frontend = pcFE[RF_MSEC];
time_backend = pc3D[RB_MSEC];
time_frontend = pcFE[RF_USEC];
time_backend = pc3D[RB_USEC];
} else if ( Cvar_VariableIntegerValue("r_speeds") ) {
// counters are actually the previous frame's, because EndFrame will clear them
// and we need to submit the calls to show them before that
SCR_PerformanceCounters();
if ( re.Registered() )
SCR_PerformanceCounters();
re.EndFrame( pcFE, pc2D, pc3D, drawFrame );
} else {
re.EndFrame( NULL, NULL, NULL, drawFrame );
}
if ( cls.maxFPS > 0 )
cls.nextFrameTimeMS = Sys_Milliseconds() + 1000 / cls.maxFPS;
recursive = 0;
}

View file

@ -302,6 +302,11 @@ typedef struct {
glconfig_t glconfig;
qhandle_t charSetShader;
qhandle_t whiteShader;
// frame-rate limiting, useful for scenarios like CGAME_INIT
int maxFPS; // only active if > 0
int nextFrameTimeMS;
int oldSwapInterval;
} clientStatic_t;
extern clientStatic_t cls;
@ -349,6 +354,8 @@ extern cvar_t *cl_inGameVideo;
extern cvar_t *cl_matchAlerts; // bit mask, see the MAF_* constants
extern cvar_t *r_khr_debug;
extern cvar_t *s_autoMute;
//=================================================
@ -475,7 +482,7 @@ e_status CIN_RunCinematic (int handle);
void CIN_DrawCinematic (int handle);
void CIN_SetExtents (int handle, int x, int y, int w, int h);
void CIN_SetLooping (int handle, qbool loop);
void CIN_UploadCinematic(int handle);
qbool CIN_GrabCinematic( int handle, int* w, int* h, const byte** data, int* client, qbool* dirty ); // qtrue when there's valid data
void CIN_CloseAllVideos(void);
//
@ -529,6 +536,12 @@ void CL_MapDownload_Cancel();
void CL_MapDownload_DrawConsole( float cw, float ch );
void CL_MapDownload_CrashCleanUp();
//
// cl_gl.cpp
//
qbool CL_GL_WantDebug(); // do we want a debug context from the platform layer?
void CL_GL_Init(); // enables debug output if needed
//
// OS-specific
//

View file

@ -123,3 +123,9 @@ S_COLOR_VAL " 1 " S_COLOR_HELP "= Enables the help panel below the console\n"
S_COLOR_VAL " 2 " S_COLOR_HELP "= Draws the help panel even if the cvar/cmd has no help text\n" \
S_COLOR_VAL " 4 " S_COLOR_HELP "= Draws the list of modules\n" \
S_COLOR_VAL " 8 " S_COLOR_HELP "= Draws the list of attributes (cvars only)"
#define help_r_khr_debug \
"enables an OpenGL debug context\n" \
S_COLOR_VAL " 0 " S_COLOR_HELP "= Forced off\n" \
S_COLOR_VAL " 1 " S_COLOR_HELP "= Forced on\n" \
S_COLOR_VAL " 2 " S_COLOR_HELP "= On in debug builds only"

73
code/glew/LICENSE.txt Normal file
View file

@ -0,0 +1,73 @@
The OpenGL Extension Wrangler Library
Copyright (C) 2002-2007, Milan Ikits <milan ikits[]ieee org>
Copyright (C) 2002-2007, Marcelo E. Magallon <mmagallo[]debian org>
Copyright (C) 2002, Lev Povalahev
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
* 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.
* The name of the author may be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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.
Mesa 3-D graphics library
Version: 7.0
Copyright (C) 1999-2007 Brian Paul All Rights Reserved.
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Copyright (c) 2007 The Khronos Group Inc.
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and/or associated documentation files (the
"Materials"), to deal in the Materials without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Materials, and to
permit persons to whom the Materials are furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Materials.
THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.

190
code/glew/README.md Normal file
View file

@ -0,0 +1,190 @@
# GLEW - The OpenGL Extension Wrangler Library
![](http://glew.sourceforge.net/glew.png)
http://glew.sourceforge.net/
https://github.com/nigels-com/glew
[![Build Status](https://travis-ci.org/nigels-com/glew.svg?branch=master)](https://travis-ci.org/nigels-com/glew)
[![Gitter](https://badges.gitter.im/nigels-com/glew.svg)](https://gitter.im/nigels-com/glew?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge)
[![Download](https://img.shields.io/sourceforge/dm/glew.svg)](https://sourceforge.net/projects/glew/files/latest/download)
## Downloads
Current release is [2.1.0](https://sourceforge.net/projects/glew/files/glew/2.1.0/).
[(Change Log)](http://glew.sourceforge.net/log.html)
Sources available as
[ZIP](https://sourceforge.net/projects/glew/files/glew/2.1.0/glew-2.1.0.zip/download) or
[TGZ](https://sourceforge.net/projects/glew/files/glew/2.1.0/glew-2.1.0.tgz/download).
Windows binaries for [32-bit and 64-bit](https://sourceforge.net/projects/glew/files/glew/2.1.0/glew-2.1.0-win32.zip/download).
### Recent snapshots
Snapshots may contain new features, bug-fixes or new OpenGL extensions ahead of tested, official releases.
## Build
It is highly recommended to build from a tgz or zip release snapshot.
The code generation workflow is a complex brew of gnu make, perl and python, that works best on Linux or Mac.
For most end-users of GLEW the official releases are the best choice, with first class support.
### Linux and Mac
#### Using GNU Make
##### Install build tools
Debian/Ubuntu/Mint: `$ sudo apt-get install build-essential libxmu-dev libxi-dev libgl-dev libosmesa-dev`
RedHat/CentOS/Fedora: `$ sudo yum install libXmu-devel libXi-devel libGL-devel`
##### Build
$ make
$ sudo make install
$ make clean
Targets: `all, glew.lib (sub-targets: glew.lib.shared, glew.lib.static), glew.bin, clean, install, uninstall`
Variables: `SYSTEM=linux-clang, GLEW_DEST=/usr/local, STRIP=`
_Note: may need to make **auto** folder_
#### Using cmake
*CMake 2.8.12 or higher is required.*
##### Install build tools
Debian/Ubuntu/Mint: `$ sudo apt-get install build-essential libXmu-dev libXi-dev libgl-dev cmake`
RedHat/CentOS/Fedora: `$ sudo yum install libXmu-devel libXi-devel libGL-devel cmake`
##### Build
$ cd build
$ cmake ./cmake
$ make -j4
| Target | Description |
| ---------- | ----------- |
| glew | Build the glew shared library. |
| glew_s | Build the glew static library. |
| glewinfo | Build the `glewinfo` executable (requires `BUILD_UTILS` to be `ON`). |
| visualinfo | Build the `visualinfo` executable (requires `BUILD_UTILS` to be `ON`). |
| install | Install all enabled targets into `CMAKE_INSTALL_PREFIX`. |
| clean | Clean up build artifacts. |
| all | Build all enabled targets (default target). |
| Variables | Description |
| --------------- | ----------- |
| BUILD_UTILS | Build the `glewinfo` and `visualinfo` executables. |
| GLEW_REGAL | Build in Regal mode. |
| GLEW_OSMESA | Build in off-screen Mesa mode. |
| BUILD_FRAMEWORK | Build as MacOSX Framework. Setting `CMAKE_INSTALL_PREFIX` to `/Library/Frameworks` is recommended. |
### Windows
#### Visual Studio
Use the provided Visual Studio project file in build/vc12/
Projects for vc6 and vc10 are also provided
#### MSYS/Mingw
Available from [Mingw](http://www.mingw.org/)
Requirements: bash, make, gcc
$ mingw32-make
$ mingw32-make install
$ mingw32-make install.all
Alternative toolchain: `SYSTEM=mingw-win32`
#### MSYS2/Mingw-w64
Available from [Msys2](http://msys2.github.io/) and/or [Mingw-w64](http://mingw-w64.org/)
Requirements: bash, make, gcc
$ pacman -S gcc make mingw-w64-i686-gcc mingw-w64-x86_64-gcc
$ make
$ make install
$ make install.all
Alternative toolchain: `SYSTEM=msys, SYSTEM=msys-win32, SYSTEM=msys-win64`
## glewinfo
`glewinfo` is a command-line tool useful for inspecting the capabilities of an
OpenGL implementation and GLEW support for that. Please include `glewinfo.txt`
with bug reports, as appropriate.
---------------------------
GLEW Extension Info
---------------------------
GLEW version 2.0.0
Reporting capabilities of pixelformat 3
Running on a Intel(R) HD Graphics 3000 from Intel
OpenGL version 3.1.0 - Build 9.17.10.4229 is supported
GL_VERSION_1_1: OK
---------------
GL_VERSION_1_2: OK
---------------
glCopyTexSubImage3D: OK
glDrawRangeElements: OK
glTexImage3D: OK
glTexSubImage3D: OK
...
## Code Generation
A Unix or Mac environment is needed for building GLEW from scratch to
include new extensions, or customize the code generation. The extension
data is regenerated from the top level source directory with:
make extensions
An alternative to generating the GLEW sources from scratch is to
download a pre-generated (unsupported) snapshot:
https://sourceforge.net/projects/glew/files/glew/snapshots/
Travis-built snapshots are also available:
https://glew.s3.amazonaws.com/index.html
## Authors
GLEW is currently maintained by [Nigel Stewart](https://github.com/nigels-com)
with bug fixes, new OpenGL extension support and new releases.
GLEW was developed by [Milan Ikits](http://www.cs.utah.edu/~ikits/)
and [Marcelo Magallon](http://wwwvis.informatik.uni-stuttgart.de/~magallon/).
Aaron Lefohn, Joe Kniss, and Chris Wyman were the first users and also
assisted with the design and debugging process.
The acronym GLEW originates from Aaron Lefohn.
Pasi K&auml;rkk&auml;inen identified and fixed several problems with
GLX and SDL. Nate Robins created the `wglinfo` utility, to
which modifications were made by Michael Wimmer.
## Copyright and Licensing
GLEW is originally derived from the EXTGL project by Lev Povalahev.
The source code is licensed under the
[Modified BSD License](http://glew.sourceforge.net/glew.txt), the
[Mesa 3-D License](http://glew.sourceforge.net/mesa.txt) (MIT) and the
[Khronos License](http://glew.sourceforge.net/khronos.txt) (MIT).
The automatic code generation scripts are released under the
[GNU GPL](http://glew.sourceforge.net/gpl.txt).

28581
code/glew/glew.c Normal file

File diff suppressed because it is too large Load diff

23686
code/glew/include/GL/glew.h Normal file

File diff suppressed because it is too large Load diff

1775
code/glew/include/GL/glxew.h Normal file

File diff suppressed because it is too large Load diff

1447
code/glew/include/GL/wglew.h Normal file

File diff suppressed because it is too large Load diff

View file

@ -35,8 +35,6 @@ void Lin_QueEvent( int time, sysEventType_t type, int value, int value2, int pt
void Lin_ConsoleInputInit();
void Lin_ConsoleInputShutdown();
const char* Lin_ConsoleInput();
qbool Lin_LoadGL();
void Lin_UnloadGL();
qbool tty_Enabled();
void tty_Hide();

File diff suppressed because it is too large Load diff

View file

@ -23,10 +23,10 @@ along with Challenge Quake 3. If not, see <https://www.gnu.org/licenses/>.
#include "linux_local.h"
#include "linux_help.h"
#include "../renderer/tr_local.h"
#include "../renderer/qgl.h"
#include <SDL2/SDL.h>
#include "sdl_local.h"
#include "GL/glew.h"
glImp_t glimp;
@ -166,7 +166,7 @@ static void sdl_MonitorList_f()
}
void Sys_GL_Init()
void Sys_V_Init( galId_t type )
{
if (glimp.window != NULL)
return;
@ -195,14 +195,8 @@ void Sys_GL_Init()
windowFlags |= SDL_WINDOW_FULLSCREEN_DESKTOP;
}
// @TODO: make a cvar defaulting to an empty string for this? e.g. value: "libGL.so.1"
if (SDL_GL_LoadLibrary(NULL) < 0)
ri.Error(ERR_FATAL, "Sys_GL_Init - SDL_GL_LoadLibrary failed: %s\n", SDL_GetError());
glimp.window = SDL_CreateWindow("CNQ3", deskropRect.x, deskropRect.y, glConfig.vidWidth, glConfig.vidHeight, windowFlags);
if (glimp.window == NULL)
ri.Error(ERR_FATAL, "Sys_GL_Init - SDL_CreateWindow failed: %s\n", SDL_GetError());
// SDL docs: "All three attributes must be set prior to creating the first window"
const int debugFlags = CL_GL_WantDebug() ? SDL_GL_CONTEXT_DEBUG_FLAG : 0;
SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8);
SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 8);
SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8);
@ -213,22 +207,48 @@ void Sys_GL_Init()
SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, 0);
SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, 0);
SDL_GL_SetAttribute(SDL_GL_ACCELERATED_VISUAL, 1);
if (type == GAL_GL3)
{
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 2);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_FLAGS, debugFlags);
}
else
{
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 2);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 0);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_COMPATIBILITY);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_FLAGS, debugFlags);
}
// @TODO: make a cvar defaulting to an empty string for this? e.g. value: "libGL.so.1"
if (SDL_GL_LoadLibrary(NULL) < 0)
ri.Error(ERR_FATAL, "Sys_V_Init - SDL_GL_LoadLibrary failed: %s\n", SDL_GetError());
glimp.window = SDL_CreateWindow("CNQ3", deskropRect.x, deskropRect.y, glConfig.vidWidth, glConfig.vidHeight, windowFlags);
if (glimp.window == NULL)
ri.Error(ERR_FATAL, "Sys_V_Init - SDL_CreateWindow failed: %s\n", SDL_GetError());
glimp.glContext = SDL_GL_CreateContext(glimp.window);
if (glimp.glContext == NULL)
ri.Error(ERR_FATAL, "Sys_GL_Init - SDL_GL_CreateContext failed: %s\n", SDL_GetError());
ri.Error(ERR_FATAL, "Sys_V_Init - SDL_GL_CreateContext failed: %s\n", SDL_GetError());
glConfig.colorBits = 32;
glConfig.depthBits = 24;
glConfig.stencilBits = 8;
if (SDL_GL_MakeCurrent(glimp.window, glimp.glContext) < 0)
ri.Error(ERR_FATAL, "Sys_GL_Init - SDL_GL_MakeCurrent failed: %s\n", SDL_GetError());
ri.Error(ERR_FATAL, "Sys_V_Init - SDL_GL_MakeCurrent failed: %s\n", SDL_GetError());
if (!Lin_LoadGL())
ri.Error(ERR_FATAL, "Sys_GL_Init - failed to initialize core OpenGL\n");
const GLenum glewErrorCode = glewInit();
if (glewErrorCode != GLEW_OK)
ri.Error(ERR_FATAL, "Sys_V_Init - glewInit failed: %s\n", glewGetErrorString(glewErrorCode));
CL_GL_Init();
}
void Sys_GL_Shutdown()
void Sys_V_Shutdown()
{
if (glimp.glContext != NULL) {
SDL_GL_DeleteContext(glimp.glContext);
@ -241,11 +261,10 @@ void Sys_GL_Shutdown()
}
SDL_GL_UnloadLibrary();
Lin_UnloadGL();
}
void Sys_GL_EndFrame()
void Sys_V_EndFrame()
{
if (r_swapInterval->modified) {
r_swapInterval->modified = qfalse;
@ -254,3 +273,9 @@ void Sys_GL_EndFrame()
SDL_GL_SwapWindow(glimp.window);
}
qbool Sys_V_IsVSynced()
{
return SDL_GL_GetSwapInterval() != 0;
}

View file

@ -26,8 +26,8 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#include "common_help.h"
#include <setjmp.h>
#ifndef INT64_MIN
# define INT64_MIN 0x8000000000000000LL
#ifndef INT64_MIN
# define INT64_MIN 0x8000000000000000LL
#endif
#if (_MSC_VER >= 1400) // Visual C++ 2005 or later
@ -2289,9 +2289,9 @@ void Com_Init( char *commandLine )
const char* s = Q3_VERSION " " PLATFORM_STRING " " __DATE__;
com_version = Cvar_Get( "version", s, CVAR_ROM | CVAR_SERVERINFO );
Cvar_Get( "sys_cpustring", "detect", 0 );
if ( Com_GetProcessorInfo() ) {
Com_Printf( "CPU: %s\n", Cvar_VariableString( "sys_cpustring" ) );
Cvar_Get( "sys_cpustring", "detect", 0 );
if ( Com_GetProcessorInfo() ) {
Com_Printf( "CPU: %s\n", Cvar_VariableString( "sys_cpustring" ) );
}
Sys_Init();
@ -2324,7 +2324,7 @@ void Com_Init( char *commandLine )
#endif
// moved to fix the console window staying visible when starting the game in full-screen mode
if ( !com_dedicated->integer )
if ( !com_dedicated->integer )
Sys_ShowConsole( com_viewlog->integer, qfalse );
// make sure single player is off by default
@ -2375,10 +2375,10 @@ static void Com_WriteConfig_f()
}
static void Com_CompleteWriteConfig_f( int startArg, int compArg )
{
if ( startArg + 1 == compArg )
Field_AutoCompleteCustom( startArg, compArg, &Field_AutoCompleteConfigName );
static void Com_CompleteWriteConfig_f( int startArg, int compArg )
{
if ( startArg + 1 == compArg )
Field_AutoCompleteCustom( startArg, compArg, &Field_AutoCompleteConfigName );
}
@ -2444,6 +2444,8 @@ static void Com_FrameSleep( qbool demoPlayback )
if ( Sys_IsMinimized() ) {
sleepUS = 20 * 1000;
preciseCap = qfalse;
} else if ( !CL_ShouldSleep() ) {
return;
}
#endif
}
@ -2676,8 +2678,8 @@ static unsigned int CRC32_table[256];
static qbool CRC32_tableCreated = qfalse;
void CRC32_Begin( unsigned int* crc )
{
void CRC32_Begin( unsigned int* crc )
{
if ( !CRC32_tableCreated )
{
for ( int i = 0; i < 256; i++ )
@ -2688,27 +2690,27 @@ void CRC32_Begin( unsigned int* crc )
CRC32_table[i] = c;
}
CRC32_tableCreated = qtrue;
}
*crc = 0xFFFFFFFFUL;
}
void CRC32_ProcessBlock( unsigned int* crc, const void* buffer, unsigned int length )
}
*crc = 0xFFFFFFFFUL;
}
void CRC32_ProcessBlock( unsigned int* crc, const void* buffer, unsigned int length )
{
unsigned int hash = *crc;
const unsigned char* buf = (const unsigned char*)buffer;
while ( length-- )
{
hash = CRC32_table[(hash ^ *buf++) & 0xFF] ^ (hash >> 8);
}
*crc = hash;
}
void CRC32_End( unsigned int* crc )
{
*crc ^= 0xFFFFFFFFUL;
}
*crc = hash;
}
void CRC32_End( unsigned int* crc )
{
*crc ^= 0xFFFFFFFFUL;
}
@ -2876,38 +2878,38 @@ static qbool String_HasLeadingSlash( const char *arg )
// returns qtrue if the match list should be printed
static qboolean Field_CompleteShortestMatch( int startArg, int compArg )
{
if ( matchCount == 0 )
return qfalse;
field_t *const field = completionField;
// write the first part of the field
*field->buffer = '\0';
static qboolean Field_CompleteShortestMatch( int startArg, int compArg )
{
if ( matchCount == 0 )
return qfalse;
field_t *const field = completionField;
// write the first part of the field
*field->buffer = '\0';
if ( compArg > 0 ) {
Field_AppendFirstArgs( field, compArg );
Q_strcat( field->buffer, sizeof( field->buffer ), " " );
}
Field_AppendArgString( field, compArg, shortestMatch );
if ( matchCount == 1 ) {
// finish the field with the only match
if ( compArg == Cmd_Argc() - 1 )
Q_strcat( field->buffer, sizeof( field->buffer ), " " );
}
Field_AppendArgString( field, compArg, shortestMatch );
if ( matchCount == 1 ) {
// finish the field with the only match
if ( compArg == Cmd_Argc() - 1 )
Q_strcat( field->buffer, sizeof( field->buffer ), " " );
field->cursor = strlen( field->buffer );
Field_AppendLastArgs( field, compArg + 1 );
return qfalse;
}
Field_AppendLastArgs( field, compArg + 1 );
return qfalse;
}
// finish the field with the shortest match and echo the command
field->cursor = strlen( field->buffer );
if ( Cmd_ArgQuoted( compArg ) )
field->cursor--;
Field_AppendLastArgs( field, compArg + 1 );
Com_Printf( "]%s\n", Cmd_Cmd() );
return qtrue;
Field_AppendLastArgs( field, compArg + 1 );
Com_Printf( "]%s\n", Cmd_Cmd() );
return qtrue;
}
@ -3117,8 +3119,8 @@ void Field_AutoCompleteCustom( int startArg, int compArg, fieldCompletionHandler
return;
}
( *callback )( FindMatches );
if ( Field_CompleteShortestMatch( startArg, compArg ) )
( *callback )( FindMatches );
if ( Field_CompleteShortestMatch( startArg, compArg ) )
( *callback )( PrintMatches );
}
@ -3186,9 +3188,9 @@ void Field_InsertValue( field_t *edit, qbool defaultValue )
void History_Clear( history_t* history, int width )
{
for ( int i = 0; i < COMMAND_HISTORY; ++i ) {
Field_Clear( &history->commands[i] );
history->commands[i].widthInChars = width;
for ( int i = 0; i < COMMAND_HISTORY; ++i ) {
Field_Clear( &history->commands[i] );
history->commands[i].widthInChars = width;
}
}
@ -3207,25 +3209,25 @@ static int LengthWithoutTrailingWhitespace( const char* s )
void History_SaveCommand( history_t* history, const field_t* edit )
{
// Avoid having the same command twice in a row.
// Unfortunately, this has to be case sensitive since case might matter for some commands.
if ( history->next > 0 ) {
// The real proper way to ignore whitespace is to tokenize both strings and compare the
// argument count and then each argument with a case sensitive comparison,
// but there's only one tokenizer data instance...
// Instead, we only ignore the trailing whitespace.
const int lengthCur = LengthWithoutTrailingWhitespace( edit->buffer );
if ( lengthCur == 0 ) {
history->display = history->next;
return;
}
const int prevLine = (history->next - 1) % COMMAND_HISTORY;
const int lengthPrev = LengthWithoutTrailingWhitespace( history->commands[prevLine].buffer );
if ( lengthCur == lengthPrev && strncmp(edit->buffer, history->commands[prevLine].buffer, lengthCur) == 0 ) {
history->display = history->next;
return;
}
// Avoid having the same command twice in a row.
// Unfortunately, this has to be case sensitive since case might matter for some commands.
if ( history->next > 0 ) {
// The real proper way to ignore whitespace is to tokenize both strings and compare the
// argument count and then each argument with a case sensitive comparison,
// but there's only one tokenizer data instance...
// Instead, we only ignore the trailing whitespace.
const int lengthCur = LengthWithoutTrailingWhitespace( edit->buffer );
if ( lengthCur == 0 ) {
history->display = history->next;
return;
}
const int prevLine = (history->next - 1) % COMMAND_HISTORY;
const int lengthPrev = LengthWithoutTrailingWhitespace( history->commands[prevLine].buffer );
if ( lengthCur == lengthPrev && strncmp(edit->buffer, history->commands[prevLine].buffer, lengthCur) == 0 ) {
history->display = history->next;
return;
}
}
// copy the line
@ -3235,25 +3237,25 @@ void History_SaveCommand( history_t* history, const field_t* edit )
}
void History_GetPreviousCommand( field_t* edit, history_t* history )
{
void History_GetPreviousCommand( field_t* edit, history_t* history )
{
if ( history->next - history->display < COMMAND_HISTORY && history->display > 0 )
--history->display;
*edit = history->commands[history->display % COMMAND_HISTORY];
}
*edit = history->commands[history->display % COMMAND_HISTORY];
}
void History_GetNextCommand( field_t* edit, history_t* history, int width )
{
{
++history->display;
if ( history->display < history->next ) {
*edit = history->commands[history->display % COMMAND_HISTORY];
return;
}
history->display = history->next;
Field_Clear( edit );
edit->widthInChars = width;
edit->widthInChars = width;
}
@ -3265,50 +3267,50 @@ void History_GetNextCommand( field_t* edit, history_t* history, int width )
#endif
void History_LoadFromFile( history_t* history )
{
void History_LoadFromFile( history_t* history )
{
fileHandle_t f;
FS_FOpenFileRead( HISTORY_PATH, &f, qfalse );
if ( f == 0 )
return;
int count;
if ( FS_Read( &count, sizeof(int), f ) != sizeof(int) ||
count <= 0 ||
count > COMMAND_HISTORY ) {
FS_FCloseFile( f );
return;
}
int lengths[COMMAND_HISTORY];
const int lengthBytes = sizeof(int) * count;
if ( FS_Read( lengths, lengthBytes, f ) != lengthBytes ) {
FS_FCloseFile( f );
return;
}
return;
int count;
if ( FS_Read( &count, sizeof(int), f ) != sizeof(int) ||
count <= 0 ||
count > COMMAND_HISTORY ) {
FS_FCloseFile( f );
return;
}
int lengths[COMMAND_HISTORY];
const int lengthBytes = sizeof(int) * count;
if ( FS_Read( lengths, lengthBytes, f ) != lengthBytes ) {
FS_FCloseFile( f );
return;
}
for ( int i = 0; i < count; ++i ) {
const int l = lengths[i];
if ( l <= 0 ||
FS_Read( history->commands[i].buffer, l, f ) != l ) {
FS_FCloseFile( f );
return;
}
history->commands[i].buffer[l] = '\0';
history->commands[i].cursor = l;
}
history->next = count;
history->display = count;
const int totalCount = ARRAY_LEN( history->commands );
for ( int i = count; i < totalCount; ++i ) {
history->commands[i].buffer[0] = '\0';
}
FS_FCloseFile( f );
}
if ( l <= 0 ||
FS_Read( history->commands[i].buffer, l, f ) != l ) {
FS_FCloseFile( f );
return;
}
history->commands[i].buffer[l] = '\0';
history->commands[i].cursor = l;
}
history->next = count;
history->display = count;
const int totalCount = ARRAY_LEN( history->commands );
for ( int i = count; i < totalCount; ++i ) {
history->commands[i].buffer[0] = '\0';
}
FS_FCloseFile( f );
}
void History_SaveToFile( const history_t* history )
{
if ( con_history->integer == 0 )
@ -3317,60 +3319,60 @@ void History_SaveToFile( const history_t* history )
const fileHandle_t f = FS_FOpenFileWrite( HISTORY_PATH );
if ( f == 0 )
return;
int count = 0;
int lengths[COMMAND_HISTORY];
const int totalCount = ARRAY_LEN( history->commands );
for ( int i = 0; i < totalCount; ++i ) {
int count = 0;
int lengths[COMMAND_HISTORY];
const int totalCount = ARRAY_LEN( history->commands );
for ( int i = 0; i < totalCount; ++i ) {
const char* const s = history->commands[(history->display + i) % COMMAND_HISTORY].buffer;
if ( *s == '\0' )
continue;
lengths[count++] = strlen( s );
}
FS_Write( &count, sizeof(count), f );
FS_Write( lengths, sizeof(int) * count, f );
for ( int i = 0, j = 0; i < totalCount; ++i ) {
lengths[count++] = strlen( s );
}
FS_Write( &count, sizeof(count), f );
FS_Write( lengths, sizeof(int) * count, f );
for ( int i = 0, j = 0; i < totalCount; ++i ) {
const char* const s = history->commands[(history->display + i) % COMMAND_HISTORY].buffer;
if ( *s == '\0' )
continue;
FS_Write( s, lengths[j++], f );
continue;
FS_Write( s, lengths[j++], f );
}
FS_FCloseFile( f );
}
const char* Q_itohex( uint64_t number, qbool uppercase, qbool prefix )
{
static const char* luts[2] = { "0123456789abcdef", "0123456789ABCDEF" };
static char buffer[19];
const int maxLength = 16;
const char* const lut = luts[uppercase == 0 ? 0 : 1];
uint64_t x = number;
int i = maxLength + 2;
buffer[i] = '\0';
while ( i-- ) {
buffer[i] = lut[x & 15];
x >>= 4;
}
int startOffset = 2;
for ( i = 2; i < maxLength + 1; i++, startOffset++ ) {
if ( buffer[i] != '0' )
break;
}
if ( prefix ) {
startOffset -= 2;
buffer[startOffset + 0] = '0';
buffer[startOffset + 1] = 'x';
}
return buffer + startOffset;
const char* Q_itohex( uint64_t number, qbool uppercase, qbool prefix )
{
static const char* luts[2] = { "0123456789abcdef", "0123456789ABCDEF" };
static char buffer[19];
const int maxLength = 16;
const char* const lut = luts[uppercase == 0 ? 0 : 1];
uint64_t x = number;
int i = maxLength + 2;
buffer[i] = '\0';
while ( i-- ) {
buffer[i] = lut[x & 15];
x >>= 4;
}
int startOffset = 2;
for ( i = 2; i < maxLength + 1; i++, startOffset++ ) {
if ( buffer[i] != '0' )
break;
}
if ( prefix ) {
startOffset -= 2;
buffer[startOffset + 0] = '0';
buffer[startOffset + 1] = 'x';
}
return buffer + startOffset;
}
@ -3418,30 +3420,30 @@ void Com_TruncatePrintString( char* buffer, int size, int maxLength )
static void Com_PrintModules( module_t firstModule, int moduleMask, printf_t print )
{
#define MODULE_ITEM(Enum, Desc) Desc,
static const char* ModuleNames[MODULE_COUNT + 1] =
{
MODULE_LIST(MODULE_ITEM)
""
};
#define MODULE_ITEM(Enum, Desc) Desc,
static const char* ModuleNames[MODULE_COUNT + 1] =
{
MODULE_LIST(MODULE_ITEM)
""
};
#undef MODULE_ITEM
if ( firstModule == MODULE_NONE || moduleMask == 0 ) {
print( "Module: Unknown\n" );
return;
}
const int otherModules = moduleMask & (~(1 << firstModule));
if ( otherModules )
print( "Modules: " );
else
print( "Module: " );
print( "%s", ModuleNames[firstModule] );
for ( int i = 0; i < 32; ++i ) {
if ( (otherModules >> i) & 1 )
print( ", %s", ModuleNames[i] );
if ( firstModule == MODULE_NONE || moduleMask == 0 ) {
print( "Module: Unknown\n" );
return;
}
const int otherModules = moduleMask & (~(1 << firstModule));
if ( otherModules )
print( "Modules: " );
else
print( "Module: " );
print( "%s", ModuleNames[firstModule] );
for ( int i = 0; i < 32; ++i ) {
if ( (otherModules >> i) & 1 )
print( ", %s", ModuleNames[i] );
}
print( "\n" );
@ -3450,68 +3452,68 @@ static void Com_PrintModules( module_t firstModule, int moduleMask, printf_t pri
printHelpResult_t Com_PrintHelp( const char* name, printf_t print, qbool printNotFound, qbool printModules, qbool printFlags )
{
qbool isCvar = qfalse;
const char *desc;
const char *help;
const char* registeredName;
module_t firstModule;
int moduleMask;
if ( Cvar_GetHelp( &desc, &help, name ) ) {
isCvar = qtrue;
Cvar_GetModuleInfo( &firstModule, &moduleMask, name );
registeredName = Cvar_GetRegisteredName( name );
} else if ( Cmd_GetHelp( &desc, &help, name ) ) {
Cmd_GetModuleInfo( &firstModule, &moduleMask, name );
registeredName = Cmd_GetRegisteredName( name );
} else {
if ( printNotFound )
print( "found no cvar/command with the name '%s'\n", name );
return PHR_NOTFOUND;
}
if ( registeredName )
name = registeredName;
if ( isCvar )
Cvar_PrintFirstHelpLine( name, print );
else
print( S_COLOR_CMD "%s\n", name );
const cvar_t* const cvar = Cvar_FindVar( name );
if ( cvar != NULL ) {
const char* const quote1 = cvar->type == CVART_STRING ? "\"" : "";
const char* const quote2 = cvar->type == CVART_STRING ? "^7\"" : "^7";
if ( cvar->latchedString != NULL ) {
const char* const combined =
va( "Current: %s" S_COLOR_VAL "%s%s (Latched: %s" S_COLOR_VAL "%s%s)\n",
quote1, cvar->string, quote2, quote1, cvar->latchedString, quote2 );
if ( strlen( combined ) < CONSOLE_WIDTH ) {
print( combined );
} else {
print( "Current: %s" S_COLOR_VAL "%s%s\n", quote1, cvar->string, quote2 );
print( "Latched: %s" S_COLOR_VAL "%s%s\n", quote1, cvar->latchedString, quote2 );
}
} else {
print( "Current: %s" S_COLOR_VAL "%s" S_COLOR_HELP "%s\n", quote1, cvar->string, quote2 );
}
}
if ( printModules )
Com_PrintModules( firstModule, moduleMask, print );
if ( isCvar && printFlags )
Cvar_PrintFlags( name, print );
if ( !desc ) {
if ( printNotFound )
print( "no help text found for %s %s%s\n",
isCvar ? "cvar" : "command", isCvar ? S_COLOR_CVAR : S_COLOR_CMD, name );
return PHR_NOHELP;
}
const char firstLetter = toupper( *desc );
print( S_COLOR_HELP "%c%s" S_COLOR_HELP ".\n", firstLetter, desc + 1 );
if ( help )
qbool isCvar = qfalse;
const char *desc;
const char *help;
const char* registeredName;
module_t firstModule;
int moduleMask;
if ( Cvar_GetHelp( &desc, &help, name ) ) {
isCvar = qtrue;
Cvar_GetModuleInfo( &firstModule, &moduleMask, name );
registeredName = Cvar_GetRegisteredName( name );
} else if ( Cmd_GetHelp( &desc, &help, name ) ) {
Cmd_GetModuleInfo( &firstModule, &moduleMask, name );
registeredName = Cmd_GetRegisteredName( name );
} else {
if ( printNotFound )
print( "found no cvar/command with the name '%s'\n", name );
return PHR_NOTFOUND;
}
if ( registeredName )
name = registeredName;
if ( isCvar )
Cvar_PrintFirstHelpLine( name, print );
else
print( S_COLOR_CMD "%s\n", name );
const cvar_t* const cvar = Cvar_FindVar( name );
if ( cvar != NULL ) {
const char* const quote1 = cvar->type == CVART_STRING ? "\"" : "";
const char* const quote2 = cvar->type == CVART_STRING ? "^7\"" : "^7";
if ( cvar->latchedString != NULL ) {
const char* const combined =
va( "Current: %s" S_COLOR_VAL "%s%s (Latched: %s" S_COLOR_VAL "%s%s)\n",
quote1, cvar->string, quote2, quote1, cvar->latchedString, quote2 );
if ( strlen( combined ) < CONSOLE_WIDTH ) {
print( combined );
} else {
print( "Current: %s" S_COLOR_VAL "%s%s\n", quote1, cvar->string, quote2 );
print( "Latched: %s" S_COLOR_VAL "%s%s\n", quote1, cvar->latchedString, quote2 );
}
} else {
print( "Current: %s" S_COLOR_VAL "%s" S_COLOR_HELP "%s\n", quote1, cvar->string, quote2 );
}
}
if ( printModules )
Com_PrintModules( firstModule, moduleMask, print );
if ( isCvar && printFlags )
Cvar_PrintFlags( name, print );
if ( !desc ) {
if ( printNotFound )
print( "no help text found for %s %s%s\n",
isCvar ? "cvar" : "command", isCvar ? S_COLOR_CVAR : S_COLOR_CMD, name );
return PHR_NOHELP;
}
const char firstLetter = toupper( *desc );
print( S_COLOR_HELP "%c%s" S_COLOR_HELP ".\n", firstLetter, desc + 1 );
if ( help )
print( S_COLOR_HELP "%s\n", help );
return PHR_HADHELP;

View file

@ -294,7 +294,7 @@ vm_t *VM_Create( vmIndex_t index, syscall_t systemCalls, vmInterpret_t interpret
void VM_Free( vm_t *vm );
void VM_Clear(void);
void VM_Forced_Unload_Start(void);
void VM_Forced_Unload_Start(void);
void VM_Forced_Unload_Done(void);
vm_t *VM_Restart( vm_t *vm );
@ -533,10 +533,10 @@ void Cvar_SetModule( const char *var_name, module_t module );
void Cvar_GetModuleInfo( module_t *firstModule, int *moduleMask, const char *var_name );
const char* Cvar_GetRegisteredName( const char *var_name );
void Cvar_PrintTypeAndRange( const char *var_name, printf_t print );
void Cvar_PrintTypeAndRange( const char *var_name, printf_t print );
void Cvar_PrintFirstHelpLine( const char *var_name, printf_t print );
void Cvar_PrintFlags( const char *var_name, printf_t print );
void Cvar_PrintFlags( const char *var_name, printf_t print );
void Cvar_Register( vmCvar_t *vmCvar, const char *varName, const char *defaultValue, int flags );
// basically a slightly modified Cvar_Get for the interpreted modules
@ -598,8 +598,8 @@ extern int cvar_modifiedFlags;
///////////////////////////////////////////////////////////////
void CRC32_Begin( unsigned int* crc );
void CRC32_ProcessBlock( unsigned int* crc, const void* buffer, unsigned int length );
void CRC32_End( unsigned int* crc );
@ -800,8 +800,8 @@ void Field_AutoCompleteKeyName( fieldCallback_t callback );
#define COMMAND_HISTORY 32
typedef struct {
field_t commands[COMMAND_HISTORY];
int next; // the last line in the history buffer, not masked
field_t commands[COMMAND_HISTORY];
int next; // the last line in the history buffer, not masked
int display; // the line being displayed from history buffer
// will be <= nextHistoryLine
} history_t;
@ -979,6 +979,7 @@ void CL_Init();
void CL_Disconnect( qbool showMainMenu );
void CL_Shutdown();
void CL_Frame( int msec );
qbool CL_ShouldSleep();
qbool CL_GameCommand();
void CL_KeyEvent (int key, qbool down, unsigned time);

103
code/renderer/hlsl/dl.hlsl Normal file
View file

@ -0,0 +1,103 @@
/*
===========================================================================
Copyright (C) 2019 Gian 'myT' Schellenbaum
This file is part of Challenge Quake 3 (CNQ3).
Challenge Quake 3 is free software; you can redistribute it
and/or modify it under the terms of the GNU General Public License as
published by the Free Software Foundation; either version 2 of the License,
or (at your option) any later version.
Challenge Quake 3 is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Challenge Quake 3. If not, see <https://www.gnu.org/licenses/>.
===========================================================================
*/
// dynamic light vertex and pixel shaders
cbuffer VertexShaderBuffer
{
matrix modelViewMatrix;
matrix projectionMatrix;
float4 clipPlane;
float4 osLightPos;
float4 osEyePos;
};
struct VIn
{
float4 position : POSITION;
float4 normal : NORMAL;
float4 color : COLOR0;
float2 texCoords : TEXCOORD0;
};
struct VOut
{
float4 position : SV_Position;
float3 normal : NORMAL;
float4 color : COLOR0;
float2 texCoords : TEXCOORD0;
float3 osLightVec : TEXCOORD1;
float3 osEyeVec : TEXCOORD2;
float clipDist : SV_ClipDistance0;
};
VOut vs_main(VIn input)
{
float4 positionVS = mul(modelViewMatrix, float4(input.position.xyz, 1));
VOut output;
output.position = mul(projectionMatrix, positionVS);
output.normal = input.normal.xyz;
output.color = input.color;
output.texCoords = input.texCoords;
output.osLightVec = osLightPos.xyz - input.position.xyz;
output.osEyeVec = osEyePos.xyz - input.position.xyz;
output.clipDist = dot(positionVS, clipPlane);
return output;
}
cbuffer PixelShaderBuffer
{
float3 lightColor;
float lightRadius;
uint alphaTest;
uint dummy[3];
};
Texture2D texture0 : register(t0);
SamplerState sampler0 : register(s0);
float4 ps_main(VOut input) : SV_TARGET
{
float4 base = texture0.Sample(sampler0, input.texCoords) * input.color;
if((alphaTest == 1 && base.a == 0.0) ||
(alphaTest == 2 && base.a >= 0.5) ||
(alphaTest == 3 && base.a < 0.5))
discard;
float3 nL = normalize(input.osLightVec); // normalized object-space light vector
float3 nV = normalize(input.osEyeVec); // normalized object-space view vector
float3 nN = input.normal; // normalized object-space normal vector
// light intensity
float intensFactor = dot(input.osLightVec, input.osLightVec) * lightRadius;
float3 intens = lightColor * (1.0 - intensFactor);
// specular reflection term (N.H)
float specFactor = clamp(dot(nN, normalize(nL + nV)), 0.0, 1.0);
float spec = pow(specFactor, 16.0) * 0.25;
// Lambertian diffuse reflection term (N.L)
float diffuse = clamp(dot(nN, nL), 0.0, 1.0);
float4 final = (base * float4(diffuse.rrr, 1.0) + float4(spec.rrr, 1.0)) * float4(intens.rgb, 1.0);
return final;
}

View file

@ -0,0 +1,149 @@
/*
===========================================================================
Copyright (C) 2019 Gian 'myT' Schellenbaum
This file is part of Challenge Quake 3 (CNQ3).
Challenge Quake 3 is free software; you can redistribute it
and/or modify it under the terms of the GNU General Public License as
published by the Free Software Foundation; either version 2 of the License,
or (at your option) any later version.
Challenge Quake 3 is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Challenge Quake 3. If not, see <https://www.gnu.org/licenses/>.
===========================================================================
*/
// generic vertex and pixel shaders
cbuffer VertexShaderBuffer
{
matrix modelViewMatrix;
matrix projectionMatrix;
float4 clipPlane;
};
struct VIn
{
float4 position : POSITION;
float4 color : COLOR0;
float2 texCoords : TEXCOORD0;
float2 texCoords2 : TEXCOORD1;
};
struct VOut
{
float4 position : SV_Position;
float4 color : COLOR0;
float2 texCoords : TEXCOORD0;
float2 texCoords2 : TEXCOORD1;
float clipDist : SV_ClipDistance0;
};
VOut vs_main(VIn input)
{
float4 positionVS = mul(modelViewMatrix, float4(input.position.xyz, 1));
VOut output;
output.position = mul(projectionMatrix, positionVS);
output.color = input.color;
output.texCoords = input.texCoords;
output.texCoords2 = input.texCoords2;
output.clipDist = dot(positionVS, clipPlane);
return output;
}
cbuffer PixelShaderBuffer
{
uint alphaTest;
uint texEnv;
float2 seed;
float invGamma;
float invBrightness;
float noiseScale;
float dummy;
};
Texture2D texture0 : register(t0);
SamplerState sampler0 : register(s0);
Texture2D texture1 : register(t1);
SamplerState sampler1 : register(s1);
#ifdef CNQ3_DITHER
float Hash(float2 input)
{
// this is from Morgan McGuire's "Hashed Alpha Testing" paper
return frac(1.0e4 * sin(17.0 * input.x + 0.1 * input.y) + (0.1 + abs(sin(13.0 * input.y + input.x))));
}
float Linearize(float color)
{
return pow(abs(color * invBrightness), invGamma) * sign(color);
}
float4 Dither(float4 color, float3 position)
{
float2 newSeed = position.xy + float2(0.6849, 0.6849) * seed + float2(position.z, position.z);
float noise = (noiseScale / 255.0) * Linearize(Hash(newSeed) - 0.5);
return color + float4(noise, noise, noise, 0.0);
}
#endif
#ifdef CNQ3_A2C
float CorrectAlpha(float threshold, float alpha, float2 tc)
{
float w, h;
texture0.GetDimensions(w, h);
float dx = max(ddx(tc.x * w), 0.001);
float dy = max(ddy(tc.y * h), 0.001);
float dxy = max(dx, dy); // apply the smallest boost
float scale = max(1.0 / dxy, 1.0);
float ac = threshold + (alpha - threshold) * scale;
return ac;
}
#endif
float4 ps_main(VOut input) : SV_Target0
{
float4 s = texture1.Sample(sampler1, input.texCoords2);
float4 p = texture0.Sample(sampler0, input.texCoords);
float4 r;
if(texEnv == 1)
r = input.color * s * p;
else if(texEnv == 2)
r = s; // use input.color or not?
else if(texEnv == 3)
r = input.color * float4(p.rgb * (1 - s.a) + s.rgb * s.a, p.a);
else if(texEnv == 4)
r = input.color * float4(p.rgb + s.rgb, p.a * s.a);
else // texEnv == 0
r = input.color * p;
#ifdef CNQ3_DITHER
r = Dither(r, input.position.xyz);
#endif
#ifdef CNQ3_A2C
if(alphaTest == 1)
r.a = CorrectAlpha(0.0, r.a, input.texCoords);
else if(alphaTest == 2)
r.a = CorrectAlpha(0.5, 1.0 - r.a, input.texCoords);
else if(alphaTest == 3)
r.a = CorrectAlpha(0.5, r.a, input.texCoords);
#else
if((alphaTest == 1 && r.a == 0.0) ||
(alphaTest == 2 && r.a >= 0.5) ||
(alphaTest == 3 && r.a < 0.5))
discard;
#endif
return r;
}

View file

@ -0,0 +1,47 @@
/*
===========================================================================
Copyright (C) 2019 Gian 'myT' Schellenbaum
This file is part of Challenge Quake 3 (CNQ3).
Challenge Quake 3 is free software; you can redistribute it
and/or modify it under the terms of the GNU General Public License as
published by the Free Software Foundation; either version 2 of the License,
or (at your option) any later version.
Challenge Quake 3 is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Challenge Quake 3. If not, see <https://www.gnu.org/licenses/>.
===========================================================================
*/
// linear-space FLOAT to gamma-space UINT8 compute shader
Texture2D<float4> src : register(t0);
RWTexture2D<uint4> dst : register(u0);
cbuffer Constants : register(b0)
{
float4 blendColor;
float intensity;
float invGamma; // 1.0 / gamma
float dummy0;
float dummy1;
}
[numthreads(8, 8, 1)]
void cs_main(uint3 id : SV_DispatchThreadID)
{
// yes, intensity *should* be done in light-linear space
// but we keep the old behavior for consistency...
float4 in0 = src[id.xy];
float3 in1 = 0.5 * (in0.rgb + blendColor.rgb);
float3 inV = lerp(in0.rgb, in1.rgb, blendColor.a);
float3 out0 = pow(max(inV, 0.0), invGamma);
float3 out1 = out0 * intensity;
float4 outV = saturate(float4(out1, in0.a));
dst[id.xy] = outV * 255.0;
}

View file

@ -0,0 +1,62 @@
/*
===========================================================================
Copyright (C) 2019 Gian 'myT' Schellenbaum
This file is part of Challenge Quake 3 (CNQ3).
Challenge Quake 3 is free software; you can redistribute it
and/or modify it under the terms of the GNU General Public License as
published by the Free Software Foundation; either version 2 of the License,
or (at your option) any later version.
Challenge Quake 3 is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Challenge Quake 3. If not, see <https://www.gnu.org/licenses/>.
===========================================================================
*/
// 8-tap 1D filter compute shader
Texture2D<float4> src : register(t0);
RWTexture2D<float4> dst : register(u0);
cbuffer Constants : register(b0)
{
float4 weights;
int2 maxSize;
int2 scale;
int2 offset;
uint clampMode; // 0 = repeat
uint dummy;
}
uint2 FixCoords(int2 c)
{
if(clampMode > 0)
{
// clamp
return uint2(clamp(c, int2(0, 0), maxSize));
}
// repeat
return uint2(c & maxSize);
}
[numthreads(8, 8, 1)]
void cs_main(uint3 id : SV_DispatchThreadID)
{
int2 base = int2(id.xy) * scale;
float4 r = float4(0, 0, 0, 0);
r += src[FixCoords(base - offset * 3)] * weights.x;
r += src[FixCoords(base - offset * 2)] * weights.y;
r += src[FixCoords(base - offset * 1)] * weights.z;
r += src[ base ] * weights.w;
r += src[ base + offset ] * weights.w;
r += src[FixCoords(base + offset * 2)] * weights.z;
r += src[FixCoords(base + offset * 3)] * weights.y;
r += src[FixCoords(base + offset * 4)] * weights.x;
dst[id.xy] = r;
}

View file

@ -0,0 +1,39 @@
/*
===========================================================================
Copyright (C) 2019 Gian 'myT' Schellenbaum
This file is part of Challenge Quake 3 (CNQ3).
Challenge Quake 3 is free software; you can redistribute it
and/or modify it under the terms of the GNU General Public License as
published by the Free Software Foundation; either version 2 of the License,
or (at your option) any later version.
Challenge Quake 3 is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Challenge Quake 3. If not, see <https://www.gnu.org/licenses/>.
===========================================================================
*/
// gamma-space UINT8 to linear-space FLOAT compute shader
Texture2D<uint4> src : register(t0);
RWTexture2D<float4> dst : register(u0);
cbuffer Constants : register(b0)
{
float gamma;
float dummy0;
float dummy1;
float dummy2;
}
[numthreads(8, 8, 1)]
void cs_main(uint3 id : SV_DispatchThreadID)
{
float4 v = src[id.xy] / 255.0;
dst[id.xy] = float4(pow(v.xyz, gamma), v.a);
}

View file

@ -0,0 +1,72 @@
/*
===========================================================================
Copyright (C) 2019 Gian 'myT' Schellenbaum
This file is part of Challenge Quake 3 (CNQ3).
Challenge Quake 3 is free software; you can redistribute it
and/or modify it under the terms of the GNU General Public License as
published by the Free Software Foundation; either version 2 of the License,
or (at your option) any later version.
Challenge Quake 3 is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Challenge Quake 3. If not, see <https://www.gnu.org/licenses/>.
===========================================================================
*/
// post-processing vertex and pixel shaders
// X3571: pow(f, e) won't work if f is negative
#pragma warning(disable : 3571)
cbuffer VertexShaderBuffer
{
float scaleX;
float scaleY;
float dummyvs0;
float dummyvs1;
};
struct VOut
{
float4 position : SV_Position;
float2 texCoords : TEXCOORD0;
};
VOut vs_main(uint id : SV_VertexID)
{
VOut output;
output.position.x = scaleX * ((float)(id / 2) * 4.0 - 1.0);
output.position.y = scaleY * ((float)(id % 2) * 4.0 - 1.0);
output.position.z = 0.0;
output.position.w = 1.0;
output.texCoords.x = (float)(id / 2) * 2.0;
output.texCoords.y = 1.0 - (float)(id % 2) * 2.0;
return output;
}
cbuffer PixelShaderBuffer
{
float gamma;
float brightness;
float greyscale;
float dummyps0;
};
Texture2D texture0 : register(t0);
SamplerState sampler0 : register(s0);
float4 ps_main(VOut input) : SV_TARGET
{
float3 base = texture0.Sample(sampler0, input.texCoords).rgb;
float3 gc = pow(base, gamma) * brightness;
float grey = 0.299 * gc.r + 0.587 * gc.g + 0.114 * gc.b;
float3 result = lerp(gc, float3(grey, grey, grey), greyscale);
return float4(result.rgb, 1.0);
}

View file

@ -0,0 +1,107 @@
/*
===========================================================================
Copyright (C) 2019 Gian 'myT' Schellenbaum
This file is part of Challenge Quake 3 (CNQ3).
Challenge Quake 3 is free software; you can redistribute it
and/or modify it under the terms of the GNU General Public License as
published by the Free Software Foundation; either version 2 of the License,
or (at your option) any later version.
Challenge Quake 3 is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Challenge Quake 3. If not, see <https://www.gnu.org/licenses/>.
===========================================================================
*/
// depth sprite vertex and pixel shaders
cbuffer VertexShaderBuffer
{
matrix modelViewMatrix;
matrix projectionMatrix;
float4 clipPlane;
};
struct VIn
{
float4 position : POSITION;
float4 color : COLOR0;
float2 texCoords : TEXCOORD0;
};
struct VOut
{
float4 position : SV_Position;
float4 color : COLOR0;
float2 texCoords : TEXCOORD0;
float depthVS : DEPTHVS;
float clipDist : SV_ClipDistance0;
};
VOut vs_main(VIn input)
{
float4 positionVS = mul(modelViewMatrix, float4(input.position.xyz, 1));
VOut output;
output.position = mul(projectionMatrix, positionVS);
output.color = input.color;
output.texCoords = input.texCoords;
output.depthVS = -positionVS.z;
output.clipDist = dot(positionVS, clipPlane);
return output;
}
cbuffer PixelShaderBuffer
{
uint alphaTest;
float proj22;
float proj32;
float additive;
float distance;
float offset;
uint dummy0;
uint dummy1;
};
Texture2D texture0 : register(t0);
SamplerState sampler0 : register(s0);
Texture2DMS<float2> textureDepth;
float LinearDepth(float zwDepth)
{
return proj32 / (zwDepth - proj22);
}
float Contrast(float d, float power)
{
bool aboveHalf = d > 0.5;
float base = saturate(2.0 * (aboveHalf ? (1.0 - d) : d));
float r = 0.5 * pow(base, power);
return aboveHalf ? (1.0 - r) : r;
}
float4 ps_main(VOut input) : SV_TARGET
{
float4 r = input.color * texture0.Sample(sampler0, input.texCoords);
if((alphaTest == 1 && r.a == 0.0) ||
(alphaTest == 2 && r.a >= 0.5) ||
(alphaTest == 3 && r.a < 0.5))
discard;
float depthS = LinearDepth(textureDepth.Load(input.position.xy, 0).x);
float depthP = input.depthVS - offset;
float scale = Contrast((depthS - depthP) * distance, 2.0);
float scaleColor = max(scale, 1.0 - additive);
float scaleAlpha = max(scale, additive);
float4 r2 = float4(r.rgb * scaleColor, r.a * scaleAlpha);
return r2;
}

View file

@ -1,506 +0,0 @@
/*
===========================================================================
Copyright (C) 1999-2005 Id Software, Inc.
This file is part of Quake III Arena source code.
Quake III Arena source code is free software; you can redistribute it
and/or modify it under the terms of the GNU General Public License as
published by the Free Software Foundation; either version 2 of the License,
or (at your option) any later version.
Quake III Arena source code is distributed in the hope that it will be
useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Quake III Arena source code; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
===========================================================================
*/
#pragma once
#if defined( _WIN32 )
#include "../win32/windows.h"
#include <GL/gl.h>
#include "../win32/glext.h"
#elif defined( __linux__ )
#include <GL/gl.h>
#include <GL/glx.h>
#else
#error "Unsupported platform"
#endif
#ifndef APIENTRY
#define APIENTRY
#endif
#ifndef WINAPI
#define WINAPI
#endif
extern "C" {
//
// OpenGL 1.X functions
//
extern void ( APIENTRY * qglAccum )(GLenum op, GLfloat value);
extern void ( APIENTRY * qglAlphaFunc )(GLenum func, GLclampf ref);
extern GLboolean ( APIENTRY * qglAreTexturesResident )(GLsizei n, const GLuint *textures, GLboolean *residences);
extern void ( APIENTRY * qglArrayElement )(GLint i);
extern void ( APIENTRY * qglBegin )(GLenum mode);
extern void ( APIENTRY * qglBindTexture )(GLenum target, GLuint texture);
extern void ( APIENTRY * qglBitmap )(GLsizei width, GLsizei height, GLfloat xorig, GLfloat yorig, GLfloat xmove, GLfloat ymove, const GLubyte *bitmap);
extern void ( APIENTRY * qglBlendFunc )(GLenum sfactor, GLenum dfactor);
extern void ( APIENTRY * qglCallList )(GLuint list);
extern void ( APIENTRY * qglCallLists )(GLsizei n, GLenum type, const GLvoid *lists);
extern void ( APIENTRY * qglClear )(GLbitfield mask);
extern void ( APIENTRY * qglClearAccum )(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha);
extern void ( APIENTRY * qglClearColor )(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha);
extern void ( APIENTRY * qglClearDepth )(GLclampd depth);
extern void ( APIENTRY * qglClearIndex )(GLfloat c);
extern void ( APIENTRY * qglClearStencil )(GLint s);
extern void ( APIENTRY * qglClipPlane )(GLenum plane, const GLdouble *equation);
extern void ( APIENTRY * qglColor3b )(GLbyte red, GLbyte green, GLbyte blue);
extern void ( APIENTRY * qglColor3bv )(const GLbyte *v);
extern void ( APIENTRY * qglColor3d )(GLdouble red, GLdouble green, GLdouble blue);
extern void ( APIENTRY * qglColor3dv )(const GLdouble *v);
extern void ( APIENTRY * qglColor3f )(GLfloat red, GLfloat green, GLfloat blue);
extern void ( APIENTRY * qglColor3fv )(const GLfloat *v);
extern void ( APIENTRY * qglColor3i )(GLint red, GLint green, GLint blue);
extern void ( APIENTRY * qglColor3iv )(const GLint *v);
extern void ( APIENTRY * qglColor3s )(GLshort red, GLshort green, GLshort blue);
extern void ( APIENTRY * qglColor3sv )(const GLshort *v);
extern void ( APIENTRY * qglColor3ub )(GLubyte red, GLubyte green, GLubyte blue);
extern void ( APIENTRY * qglColor3ubv )(const GLubyte *v);
extern void ( APIENTRY * qglColor3ui )(GLuint red, GLuint green, GLuint blue);
extern void ( APIENTRY * qglColor3uiv )(const GLuint *v);
extern void ( APIENTRY * qglColor3us )(GLushort red, GLushort green, GLushort blue);
extern void ( APIENTRY * qglColor3usv )(const GLushort *v);
extern void ( APIENTRY * qglColor4b )(GLbyte red, GLbyte green, GLbyte blue, GLbyte alpha);
extern void ( APIENTRY * qglColor4bv )(const GLbyte *v);
extern void ( APIENTRY * qglColor4d )(GLdouble red, GLdouble green, GLdouble blue, GLdouble alpha);
extern void ( APIENTRY * qglColor4dv )(const GLdouble *v);
extern void ( APIENTRY * qglColor4f )(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha);
extern void ( APIENTRY * qglColor4fv )(const GLfloat *v);
extern void ( APIENTRY * qglColor4i )(GLint red, GLint green, GLint blue, GLint alpha);
extern void ( APIENTRY * qglColor4iv )(const GLint *v);
extern void ( APIENTRY * qglColor4s )(GLshort red, GLshort green, GLshort blue, GLshort alpha);
extern void ( APIENTRY * qglColor4sv )(const GLshort *v);
extern void ( APIENTRY * qglColor4ub )(GLubyte red, GLubyte green, GLubyte blue, GLubyte alpha);
extern void ( APIENTRY * qglColor4ubv )(const GLubyte *v);
extern void ( APIENTRY * qglColor4ui )(GLuint red, GLuint green, GLuint blue, GLuint alpha);
extern void ( APIENTRY * qglColor4uiv )(const GLuint *v);
extern void ( APIENTRY * qglColor4us )(GLushort red, GLushort green, GLushort blue, GLushort alpha);
extern void ( APIENTRY * qglColor4usv )(const GLushort *v);
extern void ( APIENTRY * qglColorMask )(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha);
extern void ( APIENTRY * qglColorMaterial )(GLenum face, GLenum mode);
extern void ( APIENTRY * qglColorPointer )(GLint size, GLenum type, GLsizei stride, const GLvoid *pointer);
extern void ( APIENTRY * qglCopyPixels )(GLint x, GLint y, GLsizei width, GLsizei height, GLenum type);
extern void ( APIENTRY * qglCopyTexImage1D )(GLenum target, GLint level, GLenum internalFormat, GLint x, GLint y, GLsizei width, GLint border);
extern void ( APIENTRY * qglCopyTexImage2D )(GLenum target, GLint level, GLenum internalFormat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border);
extern void ( APIENTRY * qglCopyTexSubImage1D )(GLenum target, GLint level, GLint xoffset, GLint x, GLint y, GLsizei width);
extern void ( APIENTRY * qglCopyTexSubImage2D )(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height);
extern void ( APIENTRY * qglCullFace )(GLenum mode);
extern void ( APIENTRY * qglDeleteLists )(GLuint list, GLsizei range);
extern void ( APIENTRY * qglDeleteTextures )(GLsizei n, const GLuint *textures);
extern void ( APIENTRY * qglDepthFunc )(GLenum func);
extern void ( APIENTRY * qglDepthMask )(GLboolean flag);
extern void ( APIENTRY * qglDepthRange )(GLclampd zNear, GLclampd zFar);
extern void ( APIENTRY * qglDisable )(GLenum cap);
extern void ( APIENTRY * qglDisableClientState )(GLenum array);
extern void ( APIENTRY * qglDrawArrays )(GLenum mode, GLint first, GLsizei count);
extern void ( APIENTRY * qglDrawBuffer )(GLenum mode);
extern void ( APIENTRY * qglDrawElements )(GLenum mode, GLsizei count, GLenum type, const GLvoid *indices);
extern void ( APIENTRY * qglDrawPixels )(GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels);
extern void ( APIENTRY * qglEdgeFlag )(GLboolean flag);
extern void ( APIENTRY * qglEdgeFlagPointer )(GLsizei stride, const GLvoid *pointer);
extern void ( APIENTRY * qglEdgeFlagv )(const GLboolean *flag);
extern void ( APIENTRY * qglEnable )(GLenum cap);
extern void ( APIENTRY * qglEnableClientState )(GLenum array);
extern void ( APIENTRY * qglEnd )(void);
extern void ( APIENTRY * qglEndList )(void);
extern void ( APIENTRY * qglEvalCoord1d )(GLdouble u);
extern void ( APIENTRY * qglEvalCoord1dv )(const GLdouble *u);
extern void ( APIENTRY * qglEvalCoord1f )(GLfloat u);
extern void ( APIENTRY * qglEvalCoord1fv )(const GLfloat *u);
extern void ( APIENTRY * qglEvalCoord2d )(GLdouble u, GLdouble v);
extern void ( APIENTRY * qglEvalCoord2dv )(const GLdouble *u);
extern void ( APIENTRY * qglEvalCoord2f )(GLfloat u, GLfloat v);
extern void ( APIENTRY * qglEvalCoord2fv )(const GLfloat *u);
extern void ( APIENTRY * qglEvalMesh1 )(GLenum mode, GLint i1, GLint i2);
extern void ( APIENTRY * qglEvalMesh2 )(GLenum mode, GLint i1, GLint i2, GLint j1, GLint j2);
extern void ( APIENTRY * qglEvalPoint1 )(GLint i);
extern void ( APIENTRY * qglEvalPoint2 )(GLint i, GLint j);
extern void ( APIENTRY * qglFeedbackBuffer )(GLsizei size, GLenum type, GLfloat *buffer);
extern void ( APIENTRY * qglFinish )(void);
extern void ( APIENTRY * qglFlush )(void);
extern void ( APIENTRY * qglFogf )(GLenum pname, GLfloat param);
extern void ( APIENTRY * qglFogfv )(GLenum pname, const GLfloat *params);
extern void ( APIENTRY * qglFogi )(GLenum pname, GLint param);
extern void ( APIENTRY * qglFogiv )(GLenum pname, const GLint *params);
extern void ( APIENTRY * qglFrontFace )(GLenum mode);
extern void ( APIENTRY * qglFrustum )(GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble zNear, GLdouble zFar);
extern GLuint ( APIENTRY * qglGenLists )(GLsizei range);
extern void ( APIENTRY * qglGenTextures )(GLsizei n, GLuint *textures);
extern void ( APIENTRY * qglGetBooleanv )(GLenum pname, GLboolean *params);
extern void ( APIENTRY * qglGetClipPlane )(GLenum plane, GLdouble *equation);
extern void ( APIENTRY * qglGetDoublev )(GLenum pname, GLdouble *params);
extern GLenum ( APIENTRY * qglGetError )(void);
extern void ( APIENTRY * qglGetFloatv )(GLenum pname, GLfloat *params);
extern void ( APIENTRY * qglGetIntegerv )(GLenum pname, GLint *params);
extern void ( APIENTRY * qglGetLightfv )(GLenum light, GLenum pname, GLfloat *params);
extern void ( APIENTRY * qglGetLightiv )(GLenum light, GLenum pname, GLint *params);
extern void ( APIENTRY * qglGetMapdv )(GLenum target, GLenum query, GLdouble *v);
extern void ( APIENTRY * qglGetMapfv )(GLenum target, GLenum query, GLfloat *v);
extern void ( APIENTRY * qglGetMapiv )(GLenum target, GLenum query, GLint *v);
extern void ( APIENTRY * qglGetMaterialfv )(GLenum face, GLenum pname, GLfloat *params);
extern void ( APIENTRY * qglGetMaterialiv )(GLenum face, GLenum pname, GLint *params);
extern void ( APIENTRY * qglGetPixelMapfv )(GLenum map, GLfloat *values);
extern void ( APIENTRY * qglGetPixelMapuiv )(GLenum map, GLuint *values);
extern void ( APIENTRY * qglGetPixelMapusv )(GLenum map, GLushort *values);
extern void ( APIENTRY * qglGetPointerv )(GLenum pname, GLvoid* *params);
extern void ( APIENTRY * qglGetPolygonStipple )(GLubyte *mask);
extern const GLubyte * ( APIENTRY * qglGetString )(GLenum name);
extern void ( APIENTRY * qglGetTexEnvfv )(GLenum target, GLenum pname, GLfloat *params);
extern void ( APIENTRY * qglGetTexEnviv )(GLenum target, GLenum pname, GLint *params);
extern void ( APIENTRY * qglGetTexGendv )(GLenum coord, GLenum pname, GLdouble *params);
extern void ( APIENTRY * qglGetTexGenfv )(GLenum coord, GLenum pname, GLfloat *params);
extern void ( APIENTRY * qglGetTexGeniv )(GLenum coord, GLenum pname, GLint *params);
extern void ( APIENTRY * qglGetTexImage )(GLenum target, GLint level, GLenum format, GLenum type, GLvoid *pixels);
extern void ( APIENTRY * qglGetTexLevelParameterfv )(GLenum target, GLint level, GLenum pname, GLfloat *params);
extern void ( APIENTRY * qglGetTexLevelParameteriv )(GLenum target, GLint level, GLenum pname, GLint *params);
extern void ( APIENTRY * qglGetTexParameterfv )(GLenum target, GLenum pname, GLfloat *params);
extern void ( APIENTRY * qglGetTexParameteriv )(GLenum target, GLenum pname, GLint *params);
extern void ( APIENTRY * qglHint )(GLenum target, GLenum mode);
extern void ( APIENTRY * qglIndexMask )(GLuint mask);
extern void ( APIENTRY * qglIndexPointer )(GLenum type, GLsizei stride, const GLvoid *pointer);
extern void ( APIENTRY * qglIndexd )(GLdouble c);
extern void ( APIENTRY * qglIndexdv )(const GLdouble *c);
extern void ( APIENTRY * qglIndexf )(GLfloat c);
extern void ( APIENTRY * qglIndexfv )(const GLfloat *c);
extern void ( APIENTRY * qglIndexi )(GLint c);
extern void ( APIENTRY * qglIndexiv )(const GLint *c);
extern void ( APIENTRY * qglIndexs )(GLshort c);
extern void ( APIENTRY * qglIndexsv )(const GLshort *c);
extern void ( APIENTRY * qglIndexub )(GLubyte c);
extern void ( APIENTRY * qglIndexubv )(const GLubyte *c);
extern void ( APIENTRY * qglInitNames )(void);
extern void ( APIENTRY * qglInterleavedArrays )(GLenum format, GLsizei stride, const GLvoid *pointer);
extern GLboolean ( APIENTRY * qglIsEnabled )(GLenum cap);
extern GLboolean ( APIENTRY * qglIsList )(GLuint list);
extern GLboolean ( APIENTRY * qglIsTexture )(GLuint texture);
extern void ( APIENTRY * qglLightModelf )(GLenum pname, GLfloat param);
extern void ( APIENTRY * qglLightModelfv )(GLenum pname, const GLfloat *params);
extern void ( APIENTRY * qglLightModeli )(GLenum pname, GLint param);
extern void ( APIENTRY * qglLightModeliv )(GLenum pname, const GLint *params);
extern void ( APIENTRY * qglLightf )(GLenum light, GLenum pname, GLfloat param);
extern void ( APIENTRY * qglLightfv )(GLenum light, GLenum pname, const GLfloat *params);
extern void ( APIENTRY * qglLighti )(GLenum light, GLenum pname, GLint param);
extern void ( APIENTRY * qglLightiv )(GLenum light, GLenum pname, const GLint *params);
extern void ( APIENTRY * qglLineStipple )(GLint factor, GLushort pattern);
extern void ( APIENTRY * qglLineWidth )(GLfloat width);
extern void ( APIENTRY * qglListBase )(GLuint base);
extern void ( APIENTRY * qglLoadIdentity )(void);
extern void ( APIENTRY * qglLoadMatrixd )(const GLdouble *m);
extern void ( APIENTRY * qglLoadMatrixf )(const GLfloat *m);
extern void ( APIENTRY * qglLoadName )(GLuint name);
extern void ( APIENTRY * qglLogicOp )(GLenum opcode);
extern void ( APIENTRY * qglMap1d )(GLenum target, GLdouble u1, GLdouble u2, GLint stride, GLint order, const GLdouble *points);
extern void ( APIENTRY * qglMap1f )(GLenum target, GLfloat u1, GLfloat u2, GLint stride, GLint order, const GLfloat *points);
extern void ( APIENTRY * qglMap2d )(GLenum target, GLdouble u1, GLdouble u2, GLint ustride, GLint uorder, GLdouble v1, GLdouble v2, GLint vstride, GLint vorder, const GLdouble *points);
extern void ( APIENTRY * qglMap2f )(GLenum target, GLfloat u1, GLfloat u2, GLint ustride, GLint uorder, GLfloat v1, GLfloat v2, GLint vstride, GLint vorder, const GLfloat *points);
extern void ( APIENTRY * qglMapGrid1d )(GLint un, GLdouble u1, GLdouble u2);
extern void ( APIENTRY * qglMapGrid1f )(GLint un, GLfloat u1, GLfloat u2);
extern void ( APIENTRY * qglMapGrid2d )(GLint un, GLdouble u1, GLdouble u2, GLint vn, GLdouble v1, GLdouble v2);
extern void ( APIENTRY * qglMapGrid2f )(GLint un, GLfloat u1, GLfloat u2, GLint vn, GLfloat v1, GLfloat v2);
extern void ( APIENTRY * qglMaterialf )(GLenum face, GLenum pname, GLfloat param);
extern void ( APIENTRY * qglMaterialfv )(GLenum face, GLenum pname, const GLfloat *params);
extern void ( APIENTRY * qglMateriali )(GLenum face, GLenum pname, GLint param);
extern void ( APIENTRY * qglMaterialiv )(GLenum face, GLenum pname, const GLint *params);
extern void ( APIENTRY * qglMatrixMode )(GLenum mode);
extern void ( APIENTRY * qglMultMatrixd )(const GLdouble *m);
extern void ( APIENTRY * qglMultMatrixf )(const GLfloat *m);
extern void ( APIENTRY * qglNewList )(GLuint list, GLenum mode);
extern void ( APIENTRY * qglNormal3b )(GLbyte nx, GLbyte ny, GLbyte nz);
extern void ( APIENTRY * qglNormal3bv )(const GLbyte *v);
extern void ( APIENTRY * qglNormal3d )(GLdouble nx, GLdouble ny, GLdouble nz);
extern void ( APIENTRY * qglNormal3dv )(const GLdouble *v);
extern void ( APIENTRY * qglNormal3f )(GLfloat nx, GLfloat ny, GLfloat nz);
extern void ( APIENTRY * qglNormal3fv )(const GLfloat *v);
extern void ( APIENTRY * qglNormal3i )(GLint nx, GLint ny, GLint nz);
extern void ( APIENTRY * qglNormal3iv )(const GLint *v);
extern void ( APIENTRY * qglNormal3s )(GLshort nx, GLshort ny, GLshort nz);
extern void ( APIENTRY * qglNormal3sv )(const GLshort *v);
extern void ( APIENTRY * qglNormalPointer )(GLenum type, GLsizei stride, const GLvoid *pointer);
extern void ( APIENTRY * qglOrtho )(GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble zNear, GLdouble zFar);
extern void ( APIENTRY * qglPassThrough )(GLfloat token);
extern void ( APIENTRY * qglPixelMapfv )(GLenum map, GLsizei mapsize, const GLfloat *values);
extern void ( APIENTRY * qglPixelMapuiv )(GLenum map, GLsizei mapsize, const GLuint *values);
extern void ( APIENTRY * qglPixelMapusv )(GLenum map, GLsizei mapsize, const GLushort *values);
extern void ( APIENTRY * qglPixelStoref )(GLenum pname, GLfloat param);
extern void ( APIENTRY * qglPixelStorei )(GLenum pname, GLint param);
extern void ( APIENTRY * qglPixelTransferf )(GLenum pname, GLfloat param);
extern void ( APIENTRY * qglPixelTransferi )(GLenum pname, GLint param);
extern void ( APIENTRY * qglPixelZoom )(GLfloat xfactor, GLfloat yfactor);
extern void ( APIENTRY * qglPointSize )(GLfloat size);
extern void ( APIENTRY * qglPolygonMode )(GLenum face, GLenum mode);
extern void ( APIENTRY * qglPolygonOffset )(GLfloat factor, GLfloat units);
extern void ( APIENTRY * qglPolygonStipple )(const GLubyte *mask);
extern void ( APIENTRY * qglPopAttrib )(void);
extern void ( APIENTRY * qglPopClientAttrib )(void);
extern void ( APIENTRY * qglPopMatrix )(void);
extern void ( APIENTRY * qglPopName )(void);
extern void ( APIENTRY * qglPrioritizeTextures )(GLsizei n, const GLuint *textures, const GLclampf *priorities);
extern void ( APIENTRY * qglPushAttrib )(GLbitfield mask);
extern void ( APIENTRY * qglPushClientAttrib )(GLbitfield mask);
extern void ( APIENTRY * qglPushMatrix )(void);
extern void ( APIENTRY * qglPushName )(GLuint name);
extern void ( APIENTRY * qglRasterPos2d )(GLdouble x, GLdouble y);
extern void ( APIENTRY * qglRasterPos2dv )(const GLdouble *v);
extern void ( APIENTRY * qglRasterPos2f )(GLfloat x, GLfloat y);
extern void ( APIENTRY * qglRasterPos2fv )(const GLfloat *v);
extern void ( APIENTRY * qglRasterPos2i )(GLint x, GLint y);
extern void ( APIENTRY * qglRasterPos2iv )(const GLint *v);
extern void ( APIENTRY * qglRasterPos2s )(GLshort x, GLshort y);
extern void ( APIENTRY * qglRasterPos2sv )(const GLshort *v);
extern void ( APIENTRY * qglRasterPos3d )(GLdouble x, GLdouble y, GLdouble z);
extern void ( APIENTRY * qglRasterPos3dv )(const GLdouble *v);
extern void ( APIENTRY * qglRasterPos3f )(GLfloat x, GLfloat y, GLfloat z);
extern void ( APIENTRY * qglRasterPos3fv )(const GLfloat *v);
extern void ( APIENTRY * qglRasterPos3i )(GLint x, GLint y, GLint z);
extern void ( APIENTRY * qglRasterPos3iv )(const GLint *v);
extern void ( APIENTRY * qglRasterPos3s )(GLshort x, GLshort y, GLshort z);
extern void ( APIENTRY * qglRasterPos3sv )(const GLshort *v);
extern void ( APIENTRY * qglRasterPos4d )(GLdouble x, GLdouble y, GLdouble z, GLdouble w);
extern void ( APIENTRY * qglRasterPos4dv )(const GLdouble *v);
extern void ( APIENTRY * qglRasterPos4f )(GLfloat x, GLfloat y, GLfloat z, GLfloat w);
extern void ( APIENTRY * qglRasterPos4fv )(const GLfloat *v);
extern void ( APIENTRY * qglRasterPos4i )(GLint x, GLint y, GLint z, GLint w);
extern void ( APIENTRY * qglRasterPos4iv )(const GLint *v);
extern void ( APIENTRY * qglRasterPos4s )(GLshort x, GLshort y, GLshort z, GLshort w);
extern void ( APIENTRY * qglRasterPos4sv )(const GLshort *v);
extern void ( APIENTRY * qglReadBuffer )(GLenum mode);
extern void ( APIENTRY * qglReadPixels )(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid *pixels);
extern void ( APIENTRY * qglRectd )(GLdouble x1, GLdouble y1, GLdouble x2, GLdouble y2);
extern void ( APIENTRY * qglRectdv )(const GLdouble *v1, const GLdouble *v2);
extern void ( APIENTRY * qglRectf )(GLfloat x1, GLfloat y1, GLfloat x2, GLfloat y2);
extern void ( APIENTRY * qglRectfv )(const GLfloat *v1, const GLfloat *v2);
extern void ( APIENTRY * qglRecti )(GLint x1, GLint y1, GLint x2, GLint y2);
extern void ( APIENTRY * qglRectiv )(const GLint *v1, const GLint *v2);
extern void ( APIENTRY * qglRects )(GLshort x1, GLshort y1, GLshort x2, GLshort y2);
extern void ( APIENTRY * qglRectsv )(const GLshort *v1, const GLshort *v2);
extern GLint ( APIENTRY * qglRenderMode )(GLenum mode);
extern void ( APIENTRY * qglRotated )(GLdouble angle, GLdouble x, GLdouble y, GLdouble z);
extern void ( APIENTRY * qglRotatef )(GLfloat angle, GLfloat x, GLfloat y, GLfloat z);
extern void ( APIENTRY * qglScaled )(GLdouble x, GLdouble y, GLdouble z);
extern void ( APIENTRY * qglScalef )(GLfloat x, GLfloat y, GLfloat z);
extern void ( APIENTRY * qglScissor )(GLint x, GLint y, GLsizei width, GLsizei height);
extern void ( APIENTRY * qglSelectBuffer )(GLsizei size, GLuint *buffer);
extern void ( APIENTRY * qglShadeModel )(GLenum mode);
extern void ( APIENTRY * qglStencilFunc )(GLenum func, GLint ref, GLuint mask);
extern void ( APIENTRY * qglStencilMask )(GLuint mask);
extern void ( APIENTRY * qglStencilOp )(GLenum fail, GLenum zfail, GLenum zpass);
extern void ( APIENTRY * qglTexCoord1d )(GLdouble s);
extern void ( APIENTRY * qglTexCoord1dv )(const GLdouble *v);
extern void ( APIENTRY * qglTexCoord1f )(GLfloat s);
extern void ( APIENTRY * qglTexCoord1fv )(const GLfloat *v);
extern void ( APIENTRY * qglTexCoord1i )(GLint s);
extern void ( APIENTRY * qglTexCoord1iv )(const GLint *v);
extern void ( APIENTRY * qglTexCoord1s )(GLshort s);
extern void ( APIENTRY * qglTexCoord1sv )(const GLshort *v);
extern void ( APIENTRY * qglTexCoord2d )(GLdouble s, GLdouble t);
extern void ( APIENTRY * qglTexCoord2dv )(const GLdouble *v);
extern void ( APIENTRY * qglTexCoord2f )(GLfloat s, GLfloat t);
extern void ( APIENTRY * qglTexCoord2fv )(const GLfloat *v);
extern void ( APIENTRY * qglTexCoord2i )(GLint s, GLint t);
extern void ( APIENTRY * qglTexCoord2iv )(const GLint *v);
extern void ( APIENTRY * qglTexCoord2s )(GLshort s, GLshort t);
extern void ( APIENTRY * qglTexCoord2sv )(const GLshort *v);
extern void ( APIENTRY * qglTexCoord3d )(GLdouble s, GLdouble t, GLdouble r);
extern void ( APIENTRY * qglTexCoord3dv )(const GLdouble *v);
extern void ( APIENTRY * qglTexCoord3f )(GLfloat s, GLfloat t, GLfloat r);
extern void ( APIENTRY * qglTexCoord3fv )(const GLfloat *v);
extern void ( APIENTRY * qglTexCoord3i )(GLint s, GLint t, GLint r);
extern void ( APIENTRY * qglTexCoord3iv )(const GLint *v);
extern void ( APIENTRY * qglTexCoord3s )(GLshort s, GLshort t, GLshort r);
extern void ( APIENTRY * qglTexCoord3sv )(const GLshort *v);
extern void ( APIENTRY * qglTexCoord4d )(GLdouble s, GLdouble t, GLdouble r, GLdouble q);
extern void ( APIENTRY * qglTexCoord4dv )(const GLdouble *v);
extern void ( APIENTRY * qglTexCoord4f )(GLfloat s, GLfloat t, GLfloat r, GLfloat q);
extern void ( APIENTRY * qglTexCoord4fv )(const GLfloat *v);
extern void ( APIENTRY * qglTexCoord4i )(GLint s, GLint t, GLint r, GLint q);
extern void ( APIENTRY * qglTexCoord4iv )(const GLint *v);
extern void ( APIENTRY * qglTexCoord4s )(GLshort s, GLshort t, GLshort r, GLshort q);
extern void ( APIENTRY * qglTexCoord4sv )(const GLshort *v);
extern void ( APIENTRY * qglTexCoordPointer )(GLint size, GLenum type, GLsizei stride, const GLvoid *pointer);
extern void ( APIENTRY * qglTexEnvf )(GLenum target, GLenum pname, GLfloat param);
extern void ( APIENTRY * qglTexEnvfv )(GLenum target, GLenum pname, const GLfloat *params);
extern void ( APIENTRY * qglTexEnvi )(GLenum target, GLenum pname, GLint param);
extern void ( APIENTRY * qglTexEnviv )(GLenum target, GLenum pname, const GLint *params);
extern void ( APIENTRY * qglTexGend )(GLenum coord, GLenum pname, GLdouble param);
extern void ( APIENTRY * qglTexGendv )(GLenum coord, GLenum pname, const GLdouble *params);
extern void ( APIENTRY * qglTexGenf )(GLenum coord, GLenum pname, GLfloat param);
extern void ( APIENTRY * qglTexGenfv )(GLenum coord, GLenum pname, const GLfloat *params);
extern void ( APIENTRY * qglTexGeni )(GLenum coord, GLenum pname, GLint param);
extern void ( APIENTRY * qglTexGeniv )(GLenum coord, GLenum pname, const GLint *params);
extern void ( APIENTRY * qglTexImage1D )(GLenum target, GLint level, GLint internalformat, GLsizei width, GLint border, GLenum format, GLenum type, const GLvoid *pixels);
extern void ( APIENTRY * qglTexImage2D )(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid *pixels);
extern void ( APIENTRY * qglTexParameterf )(GLenum target, GLenum pname, GLfloat param);
extern void ( APIENTRY * qglTexParameterfv )(GLenum target, GLenum pname, const GLfloat *params);
extern void ( APIENTRY * qglTexParameteri )(GLenum target, GLenum pname, GLint param);
extern void ( APIENTRY * qglTexParameteriv )(GLenum target, GLenum pname, const GLint *params);
extern void ( APIENTRY * qglTexSubImage1D )(GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLenum type, const GLvoid *pixels);
extern void ( APIENTRY * qglTexSubImage2D )(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels);
extern void ( APIENTRY * qglTranslated )(GLdouble x, GLdouble y, GLdouble z);
extern void ( APIENTRY * qglTranslatef )(GLfloat x, GLfloat y, GLfloat z);
extern void ( APIENTRY * qglVertex2d )(GLdouble x, GLdouble y);
extern void ( APIENTRY * qglVertex2dv )(const GLdouble *v);
extern void ( APIENTRY * qglVertex2f )(GLfloat x, GLfloat y);
extern void ( APIENTRY * qglVertex2fv )(const GLfloat *v);
extern void ( APIENTRY * qglVertex2i )(GLint x, GLint y);
extern void ( APIENTRY * qglVertex2iv )(const GLint *v);
extern void ( APIENTRY * qglVertex2s )(GLshort x, GLshort y);
extern void ( APIENTRY * qglVertex2sv )(const GLshort *v);
extern void ( APIENTRY * qglVertex3d )(GLdouble x, GLdouble y, GLdouble z);
extern void ( APIENTRY * qglVertex3dv )(const GLdouble *v);
extern void ( APIENTRY * qglVertex3f )(GLfloat x, GLfloat y, GLfloat z);
extern void ( APIENTRY * qglVertex3fv )(const GLfloat *v);
extern void ( APIENTRY * qglVertex3i )(GLint x, GLint y, GLint z);
extern void ( APIENTRY * qglVertex3iv )(const GLint *v);
extern void ( APIENTRY * qglVertex3s )(GLshort x, GLshort y, GLshort z);
extern void ( APIENTRY * qglVertex3sv )(const GLshort *v);
extern void ( APIENTRY * qglVertex4d )(GLdouble x, GLdouble y, GLdouble z, GLdouble w);
extern void ( APIENTRY * qglVertex4dv )(const GLdouble *v);
extern void ( APIENTRY * qglVertex4f )(GLfloat x, GLfloat y, GLfloat z, GLfloat w);
extern void ( APIENTRY * qglVertex4fv )(const GLfloat *v);
extern void ( APIENTRY * qglVertex4i )(GLint x, GLint y, GLint z, GLint w);
extern void ( APIENTRY * qglVertex4iv )(const GLint *v);
extern void ( APIENTRY * qglVertex4s )(GLshort x, GLshort y, GLshort z, GLshort w);
extern void ( APIENTRY * qglVertex4sv )(const GLshort *v);
extern void ( APIENTRY * qglVertexPointer )(GLint size, GLenum type, GLsizei stride, const GLvoid *pointer);
extern void ( APIENTRY * qglViewport )(GLint x, GLint y, GLsizei width, GLsizei height);
//
// mandatory (and really old) OpenGL extensions
//
extern void (APIENTRY * qglActiveTextureARB)(GLenum texture);
extern void (APIENTRY * qglClientActiveTextureARB)(GLenum texture);
extern PFNGLLOCKARRAYSEXTPROC qglLockArraysEXT;
extern PFNGLUNLOCKARRAYSEXTPROC qglUnlockArraysEXT;
#if defined( _WIN32 )
//
// Windows extensions
//
extern int ( WINAPI * qwglChoosePixelFormat )(HDC, CONST PIXELFORMATDESCRIPTOR *);
extern int ( WINAPI * qwglChoosePixelFormatARB )(HDC, const int*, const FLOAT*, UINT, int*, UINT*);
extern int ( WINAPI * qwglDescribePixelFormat) (HDC, int, UINT, LPPIXELFORMATDESCRIPTOR);
extern int ( WINAPI * qwglGetPixelFormat)(HDC);
extern BOOL ( WINAPI * qwglSetPixelFormat)(HDC, int, CONST PIXELFORMATDESCRIPTOR *);
extern BOOL ( WINAPI * qwglSwapBuffers)(HDC);
extern BOOL ( WINAPI * qwglCopyContext)(HGLRC, HGLRC, UINT);
extern HGLRC ( WINAPI * qwglCreateContext)(HDC);
extern HGLRC ( WINAPI * qwglCreateLayerContext)(HDC, int);
extern BOOL ( WINAPI * qwglDeleteContext)(HGLRC);
extern HGLRC ( WINAPI * qwglGetCurrentContext)(VOID);
extern HDC ( WINAPI * qwglGetCurrentDC)(VOID);
extern PROC ( WINAPI * qwglGetProcAddress)(LPCSTR);
extern BOOL ( WINAPI * qwglMakeCurrent)(HDC, HGLRC);
extern BOOL ( WINAPI * qwglShareLists)(HGLRC, HGLRC);
extern BOOL ( WINAPI * qwglDescribeLayerPlane)(HDC, int, int, UINT, LPLAYERPLANEDESCRIPTOR);
extern int ( WINAPI * qwglSetLayerPaletteEntries)(HDC, int, int, int, CONST COLORREF *);
extern int ( WINAPI * qwglGetLayerPaletteEntries)(HDC, int, int, int, COLORREF *);
extern BOOL ( WINAPI * qwglRealizeLayerPalette)(HDC, int, BOOL);
extern BOOL ( WINAPI * qwglSwapLayerBuffers)(HDC, UINT);
extern BOOL ( WINAPI * qwglSwapIntervalEXT)( int interval );
#endif
// Sys_GL_LoadExtensions rules:
// - OpenGL 2 extensions are mandatory
// - OpenGL 3+ extensions are optional
// - platform-specific extensions are not mandatory,
// but the implementation is free to return qfalse if one is missing
// - when returning qfalse, set *extension to point to the name of the missing extension
// the string should either be a string literal or returned by va()
qbool Sys_GL_LoadExtensions( const char** extension );
//
// OpenGL 2.X functions
//
extern PFNGLCREATESHADERPROC qglCreateShader;
extern PFNGLSHADERSOURCEPROC qglShaderSource;
extern PFNGLCOMPILESHADERPROC qglCompileShader;
extern PFNGLATTACHSHADERPROC qglAttachShader;
extern PFNGLDETACHSHADERPROC qglDetachShader;
extern PFNGLDELETESHADERPROC qglDeleteShader;
extern PFNGLGETSHADERINFOLOGPROC qglGetShaderInfoLog;
extern PFNGLGETSHADERIVPROC qglGetShaderiv;
extern PFNGLCREATEPROGRAMPROC qglCreateProgram;
extern PFNGLLINKPROGRAMPROC qglLinkProgram;
extern PFNGLUSEPROGRAMPROC qglUseProgram;
extern PFNGLDELETEPROGRAMPROC qglDeleteProgram;
extern PFNGLBINDATTRIBLOCATIONPROC qglBindAttribLocation;
extern PFNGLDISABLEVERTEXATTRIBARRAYPROC qglDisableVertexAttribArray;
extern PFNGLENABLEVERTEXATTRIBARRAYPROC qglEnableVertexAttribArray;
extern PFNGLVERTEXATTRIBPOINTERPROC qglVertexAttribPointer;
extern PFNGLGETUNIFORMLOCATIONPROC qglGetUniformLocation;
extern PFNGLUNIFORM1IPROC qglUniform1i;
extern PFNGLUNIFORM1FPROC qglUniform1f;
extern PFNGLUNIFORM2FPROC qglUniform2f;
extern PFNGLUNIFORM3FPROC qglUniform3f;
extern PFNGLUNIFORM4FPROC qglUniform4f;
extern PFNGLISRENDERBUFFERPROC qglIsRenderbuffer;
extern PFNGLBINDRENDERBUFFERPROC qglBindRenderbuffer;
extern PFNGLDELETERENDERBUFFERSPROC qglDeleteRenderbuffers;
extern PFNGLGENRENDERBUFFERSPROC qglGenRenderbuffers;
extern PFNGLRENDERBUFFERSTORAGEPROC qglRenderbufferStorage;
extern PFNGLGETRENDERBUFFERPARAMETERIVPROC qglGetRenderbufferParameteriv;
extern PFNGLISFRAMEBUFFERPROC qglIsFramebuffer;
extern PFNGLBINDFRAMEBUFFERPROC qglBindFramebuffer;
extern PFNGLDELETEFRAMEBUFFERSPROC qglDeleteFramebuffers;
extern PFNGLGENFRAMEBUFFERSPROC qglGenFramebuffers;
extern PFNGLCHECKFRAMEBUFFERSTATUSPROC qglCheckFramebufferStatus;
extern PFNGLFRAMEBUFFERTEXTURE1DPROC qglFramebufferTexture1D;
extern PFNGLFRAMEBUFFERTEXTURE2DPROC qglFramebufferTexture2D;
extern PFNGLFRAMEBUFFERTEXTURE3DPROC qglFramebufferTexture3D;
extern PFNGLFRAMEBUFFERRENDERBUFFERPROC qglFramebufferRenderbuffer;
extern PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVPROC qglGetFramebufferAttachmentParameteriv;
extern PFNGLGENERATEMIPMAPPROC qglGenerateMipmap;
extern PFNGLBLITFRAMEBUFFERPROC qglBlitFramebuffer;
//
// OpenGL 3+ functions
//
extern PFNGLRENDERBUFFERSTORAGEMULTISAMPLEPROC qglRenderbufferStorageMultisample;
extern void (APIENTRY* qglTexImage2DMultisample)(GLenum, GLsizei, GLenum, GLsizei, GLsizei, GLboolean);
};

View file

@ -77,7 +77,7 @@ static void* q_realloc_sized( void* ptr, size_t oldSize, size_t newSize )
}
qbool LoadSTB( const char* fileName, byte* buffer, int len, byte** pic, int* w, int* h, GLenum* format )
qbool LoadSTB( const char* fileName, byte* buffer, int len, byte** pic, int* w, int* h, textureFormat_t* format )
{
int comp;
*pic = (byte*)stbi_load_from_memory(buffer, len, w, h, &comp, 4);
@ -86,8 +86,7 @@ qbool LoadSTB( const char* fileName, byte* buffer, int len, byte** pic, int* w,
return qfalse;
}
*format = comp == 4 ? GL_RGBA : GL_RGB;
*format = TF_RGBA8;
return qtrue;
}

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -64,7 +64,7 @@ static void R_ColorShiftLightingBytesRGB( const byte* in, byte* out )
}
static void R_ColorShiftLightingBytes( const byte in[4], byte out[4] )
void R_ColorShiftLightingBytes( const byte in[4], byte out[4] )
{
R_ColorShiftLightingBytesRGB( in, out );
out[3] = in[3];
@ -156,9 +156,6 @@ static void R_LoadLightmaps( const lump_t* l )
byte* p = fileBase + l->fileofs;
// we are about to upload textures
R_SyncRenderThread();
int numFileLightmaps = fileBytes / (LMVirtPageSize * LMVirtPageSize * 3);
if ( numFileLightmaps >= MAX_LIGHTMAPS ) {
ri.Printf( PRINT_WARNING, "WARNING: number of lightmaps > MAX_LIGHTMAPS\n" );
@ -178,7 +175,7 @@ static void R_LoadLightmaps( const lump_t* l )
int i = 0; // lightmapNum
for ( int a = 0; a < numAtlases; ++a ) {
tr.lightmaps[a] = R_CreateImage( va("*lightmapatlas%i", a), NULL, sizeX, sizeY, GL_RGBA, IMG_LMATLAS, GL_CLAMP );
tr.lightmaps[a] = R_CreateImage( va("*lightmapatlas%i", a), NULL, sizeX, sizeY, TF_RGBA8, IMG_LMATLAS, TW_CLAMP_TO_EDGE );
for ( int t = 0; t < numTilesPerAtlas && i < numFileLightmaps; ++t ) {
for ( int y = 0; y < LMVirtPageSize; ++y ) {

View file

@ -22,7 +22,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#include "tr_local.h"
static void R_IssueRenderCommands()
void R_IssueRenderCommands()
{
renderCommandList_t* cmdList = &backEndData->commands;
@ -36,23 +36,67 @@ static void R_IssueRenderCommands()
}
/*
====================
R_SyncRenderThread
void* R_FindRenderCommand( renderCommand_t type )
{
renderCommandList_t* cmdList = &backEndData->commands;
void* data = cmdList->cmds;
void* end = cmdList->cmds + cmdList->used;
Issue any pending commands and wait for them to complete.
After exiting, the render thread will have completed its work
and will remain idle and the main thread is free to issue
OpenGL calls until R_IssueRenderCommands is called.
====================
*/
void R_SyncRenderThread( void ) {
if ( !tr.registered ) {
return;
while ( 1 ) {
data = PADP(data, sizeof(void *));
if( *(int *)data == type )
return data;
if ( data >= end )
return NULL;
switch ( *(const int *)data ) {
case RC_SET_COLOR:
data = (char*)data + sizeof(setColorCommand_t);
break;
case RC_STRETCH_PIC:
data = (char*)data + sizeof(stretchPicCommand_t);
break;
case RC_TRIANGLE:
data = (char*)data + sizeof(triangleCommand_t);
break;
case RC_DRAW_SURFS:
data = (char*)data + sizeof(drawSurfsCommand_t);
break;
case RC_BEGIN_FRAME:
data = (char*)data + sizeof(beginFrameCommand_t);
break;
case RC_SWAP_BUFFERS:
data = (char*)data + sizeof(swapBuffersCommand_t);
break;
case RC_SCREENSHOT:
data = (char*)data + sizeof(screenshotCommand_t);
break;
case RC_VIDEOFRAME:
data = (char*)data + sizeof(videoFrameCommand_t);
break;
case RC_END_OF_LIST:
default:
return NULL;
}
}
R_IssueRenderCommands();
}
static void R_RemoveRenderCommand( void* cmd, int cmdSize )
{
renderCommandList_t* cmdList = &backEndData->commands;
const int endOffset = ((char*)cmd + cmdSize) - (char*)cmdList->cmds;
const int endBytes = cmdList->used - endOffset;
assert( cmd >= cmdList->cmds && ((char*)cmd + cmdSize) <= ((char*)cmdList->cmds + cmdList->used) );
memmove( cmd, (char*)cmd + cmdSize, endBytes );
cmdList->used -= cmdSize;
}
/*
============
R_GetCommandBuffer
@ -87,12 +131,13 @@ void *R_GetCommandBuffer( int bytes ) {
#define R_CMD(T, ID) T* cmd = (T*)R_GetCommandBuffer( sizeof(T) ); if (!cmd) return; cmd->commandId = ID;
void R_AddDrawSurfCmd( drawSurf_t* drawSurfs, int numDrawSurfs )
void R_AddDrawSurfCmd( drawSurf_t* drawSurfs, int numDrawSurfs, int numTranspSurfs )
{
R_CMD( drawSurfsCommand_t, RC_DRAW_SURFS );
cmd->drawSurfs = drawSurfs;
cmd->numDrawSurfs = numDrawSurfs;
cmd->numTranspSurfs = numTranspSurfs;
cmd->refdef = tr.refdef;
cmd->viewParms = tr.viewParms;
@ -158,73 +203,10 @@ void RE_BeginFrame( stereoFrame_t stereoFrame )
if (!tr.registered)
return;
glState.finishCalled = qfalse;
tr.frameCount++;
tr.frameSceneNum = 0;
//
// do overdraw measurement
//
if ( r_measureOverdraw->integer )
{
if ( glConfig.stencilBits < 4 )
{
ri.Printf( PRINT_ALL, "Warning: not enough stencil bits to measure overdraw: %d\n", glConfig.stencilBits );
ri.Cvar_Set( "r_measureOverdraw", "0" );
r_measureOverdraw->modified = qfalse;
}
else
{
R_SyncRenderThread();
qglEnable( GL_STENCIL_TEST );
qglStencilMask( ~0U );
qglClearStencil( 0U );
qglStencilFunc( GL_ALWAYS, 0U, ~0U );
qglStencilOp( GL_KEEP, GL_INCR, GL_INCR );
}
r_measureOverdraw->modified = qfalse;
}
else
{
// this is only reached if it was on and is now off
if ( r_measureOverdraw->modified ) {
R_SyncRenderThread();
qglDisable( GL_STENCIL_TEST );
}
r_measureOverdraw->modified = qfalse;
}
//
// texturemode stuff
//
if ( r_textureMode->modified ) {
R_SyncRenderThread();
GL_TextureMode( r_textureMode->string );
r_textureMode->modified = qfalse;
}
//
// gamma stuff
//
if ( r_gamma->modified ) {
r_gamma->modified = qfalse;
R_SyncRenderThread();
R_SetColorMappings();
}
// check for errors
if ( !r_ignoreGLErrors->integer ) {
int err;
R_SyncRenderThread();
if ( ( err = qglGetError() ) != GL_NO_ERROR ) {
ri.Error( ERR_FATAL, "RE_BeginFrame() - glGetError() failed (0x%x)!\n", err );
}
}
//
// delayed screenshot
//
if ( r_delayedScreenshotPending ) {
r_delayedScreenshotFrame++;
if ( r_delayedScreenshotFrame >= 2 ) {
@ -247,18 +229,12 @@ void RE_EndFrame( int* pcFE, int* pc2D, int* pc3D, qbool render )
if (!tr.registered)
return;
if (tr.maxFPS > 0) {
if (Sys_Milliseconds() < tr.nextFrameTimeMS)
return;
tr.nextFrameTimeMS += 1000 / tr.maxFPS;
}
qbool delayScreenshot = qfalse;
if ( !render && r_delayedScreenshotPending )
render = qtrue;
if ( !render ) {
screenshotCommand_t* ssCmd = (screenshotCommand_t*)RB_FindRenderCommand( RC_SCREENSHOT );
screenshotCommand_t* ssCmd = (screenshotCommand_t*)R_FindRenderCommand( RC_SCREENSHOT );
if ( ssCmd )
render = qtrue;
@ -267,7 +243,7 @@ void RE_EndFrame( int* pcFE, int* pc2D, int* pc3D, qbool render )
// save and remove the command so we can push it back after the frame's done
r_delayedScreenshot = *ssCmd;
r_delayedScreenshot.delayed = qtrue;
RB_RemoveRenderCommand( ssCmd, sizeof(screenshotCommand_t) );
R_RemoveRenderCommand( ssCmd, sizeof(screenshotCommand_t) );
delayScreenshot = qtrue;
}
}

View file

@ -1,823 +0,0 @@
#include "tr_local.h"
struct GLSL_Program {
GLuint p; // linked program
GLuint vs; // vertex shader
GLuint fs; // fragment shader
};
static GLuint progCurrent;
static void GL_Program( const GLSL_Program& prog )
{
assert( prog.p );
if ( prog.p != progCurrent ) {
qglUseProgram( prog.p );
progCurrent = prog.p;
}
}
void GL_Program()
{
if ( progCurrent != 0 ) {
qglUseProgram(0);
progCurrent = 0;
}
}
static GLSL_Program dynLightProg;
struct GLSL_DynLightProgramAttribs {
// vertex shader:
GLint osEyePos; // 4f, object-space
GLint osLightPos; // 4f, object-space
// pixel shader:
GLint texture; // 2D texture
GLint lightColorRadius; // 4f, w = 1 / (r^2)
};
static GLSL_DynLightProgramAttribs dynLightProgAttribs;
///////////////////////////////////////////////////////////////
void GL2_SetupDynLight()
{
GL_Program( dynLightProg );
const dlight_t* dl = tess.light;
vec3_t lightColor;
VectorCopy( dl->color, lightColor );
qglUniform4f( dynLightProgAttribs.osLightPos, dl->transformed[0], dl->transformed[1], dl->transformed[2], 0.0f );
qglUniform4f( dynLightProgAttribs.osEyePos, backEnd.orient.viewOrigin[0], backEnd.orient.viewOrigin[1], backEnd.orient.viewOrigin[2], 0.0f );
qglUniform4f( dynLightProgAttribs.lightColorRadius, lightColor[0], lightColor[1], lightColor[2], 1.0f / Square(dl->radius) );
qglUniform1i( dynLightProgAttribs.texture, 0 ); // we use texture unit 0
}
///////////////////////////////////////////////////////////////
static void GL2_StageIterator_Lighting()
{
backEnd.pc[RB_LIT_VERTICES_LATECULLTEST] += tess.numVertexes;
int i;
byte clipBits[SHADER_MAX_VERTEXES];
const dlight_t* dl = tess.light;
for ( i = 0; i < tess.numVertexes; ++i ) {
vec3_t dist;
VectorSubtract( dl->transformed, tess.xyz[i], dist );
if ( DotProduct( dist, tess.normal[i] ) <= 0.0 ) {
clipBits[i] = (byte)-1;
continue;
}
int clip = 0;
if ( dist[0] > dl->radius ) {
clip |= 1;
} else if ( dist[0] < -dl->radius ) {
clip |= 2;
}
if ( dist[1] > dl->radius ) {
clip |= 4;
} else if ( dist[1] < -dl->radius ) {
clip |= 8;
}
if ( dist[2] > dl->radius ) {
clip |= 16;
} else if ( dist[2] < -dl->radius ) {
clip |= 32;
}
clipBits[i] = clip;
}
// build a list of triangles that need light
int numIndexes = 0;
unsigned hitIndexes[SHADER_MAX_INDEXES];
for ( i = 0; i < tess.numIndexes; i += 3 ) {
int a = tess.indexes[i];
int b = tess.indexes[i+1];
int c = tess.indexes[i+2];
if ( !(clipBits[a] & clipBits[b] & clipBits[c]) ) {
hitIndexes[numIndexes] = a;
hitIndexes[numIndexes+1] = b;
hitIndexes[numIndexes+2] = c;
numIndexes += 3;
}
}
backEnd.pc[RB_LIT_INDICES_LATECULL_IN] += numIndexes;
backEnd.pc[RB_LIT_INDICES_LATECULL_OUT] += tess.numIndexes - numIndexes;
if ( !numIndexes )
return;
GL_State( GLS_SRCBLEND_ONE | GLS_DSTBLEND_ONE | GLS_DEPTHFUNC_EQUAL );
const shaderStage_t* const pStage = tess.xstages[tess.shader->lightingStages[ST_DIFFUSE]];
GL_SelectTexture( 0 );
R_BindAnimatedImage( &pStage->bundle );
qglDrawElements( GL_TRIANGLES, numIndexes, GL_INDEX_TYPE, hitIndexes );
}
static void GL2_StageIterator_LightingPass()
{
if (tess.shader->lightingStages[ST_DIFFUSE] == -1)
return;
RB_DeformTessGeometry();
GL_Cull( tess.shader->cullType );
const shaderStage_t* pStage = tess.xstages[ tess.shader->lightingStages[ST_DIFFUSE] ];
R_ComputeTexCoords( pStage, tess.svars );
// since this is guaranteed to be a single pass, fill and lock all the arrays
qglDisableClientState( GL_COLOR_ARRAY );
qglEnableClientState( GL_TEXTURE_COORD_ARRAY );
qglTexCoordPointer( 2, GL_FLOAT, 0, tess.svars.texcoords );
qglEnableClientState( GL_NORMAL_ARRAY );
qglNormalPointer( GL_FLOAT, 16, tess.normal );
qglVertexPointer( 3, GL_FLOAT, 16, tess.xyz );
qglLockArraysEXT( 0, tess.numVertexes );
GL2_StageIterator_Lighting();
qglUnlockArraysEXT();
qglDisableClientState( GL_NORMAL_ARRAY );
}
///////////////////////////////////////////////////////////////
// returns qtrue if needs to break early
static qbool GL2_StageIterator_MultitextureStage( int stage )
{
static stageVars_t svarsMT; // this is a huge struct
const shaderStage_t* pPrevStage = tess.xstages[stage++];
const shaderStage_t* pStage = tess.xstages[stage];
const qbool lightmapOnly = r_lightmap->integer && (pStage->type == ST_LIGHTMAP || pPrevStage->type == ST_LIGHTMAP);
if ( lightmapOnly ) {
if ( pStage->type == ST_LIGHTMAP ) {
R_BindAnimatedImage( &pStage->bundle );
R_ComputeTexCoords( pStage, svarsMT );
qglTexCoordPointer( 2, GL_FLOAT, 0, svarsMT.texcoords );
}
qglDrawElements( GL_TRIANGLES, tess.numIndexes, GL_INDEX_TYPE, tess.indexes );
return qtrue;
}
if ( r_fullbright->integer ) {
if ( pStage->type == ST_LIGHTMAP ) {
Com_Memset( tess.svars.colors, tr.identityLightByte, tess.numVertexes * 4 );
qglDrawElements( GL_TRIANGLES, tess.numIndexes, GL_INDEX_TYPE, tess.indexes );
return qfalse;
} else if ( pPrevStage->type == ST_LIGHTMAP ) {
Com_Memset( tess.svars.colors, tr.identityLightByte, tess.numVertexes * 4 );
R_BindAnimatedImage( &pStage->bundle );
R_ComputeTexCoords( pStage, svarsMT );
qglTexCoordPointer( 2, GL_FLOAT, 0, svarsMT.texcoords );
qglDrawElements( GL_TRIANGLES, tess.numIndexes, GL_INDEX_TYPE, tess.indexes );
return qfalse;
}
}
GL_SelectTexture( 1 );
qglEnable( GL_TEXTURE_2D );
GL_TexEnv( pStage->mtEnv );
R_BindAnimatedImage( &pStage->bundle );
R_ComputeTexCoords( pStage, svarsMT );
qglEnableClientState( GL_TEXTURE_COORD_ARRAY );
qglTexCoordPointer( 2, GL_FLOAT, 0, svarsMT.texcoords );
qglDrawElements( GL_TRIANGLES, tess.numIndexes, GL_INDEX_TYPE, tess.indexes );
qglDisable( GL_TEXTURE_2D );
GL_SelectTexture( 0 );
return qfalse;
}
void GL2_StageIterator()
{
if (tess.pass == shaderCommands_t::TP_LIGHT) {
GL2_StageIterator_LightingPass();
return;
}
GL_Program();
RB_DeformTessGeometry();
GL_Cull( tess.shader->cullType );
if ( tess.shader->polygonOffset )
qglEnable( GL_POLYGON_OFFSET_FILL );
// geometry is per-shader and can be compiled
// color and tc are per-stage, and can't
qglDisableClientState( GL_COLOR_ARRAY );
qglDisableClientState( GL_TEXTURE_COORD_ARRAY );
qglVertexPointer( 3, GL_FLOAT, 16, tess.xyz ); // padded for SIMD
qglLockArraysEXT( 0, tess.numVertexes );
qglEnableClientState( GL_COLOR_ARRAY );
qglColorPointer( 4, GL_UNSIGNED_BYTE, 0, tess.svars.colors );
qglEnableClientState( GL_TEXTURE_COORD_ARRAY );
qglTexCoordPointer( 2, GL_FLOAT, 0, tess.svars.texcoords );
for ( int stage = 0; stage < tess.shader->numStages; ++stage ) {
const shaderStage_t* pStage = tess.xstages[stage];
R_ComputeColors( pStage, tess.svars );
R_ComputeTexCoords( pStage, tess.svars );
R_BindAnimatedImage( &pStage->bundle );
GL_State( pStage->stateBits );
// !!! FUCKING ati drivers incorrectly need this
// they're locking+pulling the color array even tho it was explicitly NOT locked
// so color changes are ignored unless we "update" the color pointer again
qglColorPointer( 4, GL_UNSIGNED_BYTE, 0, tess.svars.colors );
qglTexCoordPointer( 2, GL_FLOAT, 0, tess.svars.texcoords );
if ( pStage->mtStages ) {
// we can't really cope with massive collapses, so
assert( pStage->mtStages == 1 );
if ( GL2_StageIterator_MultitextureStage( stage ) )
break;
stage += pStage->mtStages;
continue;
}
qglDrawElements( GL_TRIANGLES, tess.numIndexes, GL_INDEX_TYPE, tess.indexes );
}
if ( tess.fogNum && tess.shader->fogPass )
RB_FogPass();
qglUnlockArraysEXT();
if ( tess.shader->polygonOffset )
qglDisable( GL_POLYGON_OFFSET_FILL );
}
///////////////////////////////////////////////////////////////
static qbool GL2_CreateShader( GLuint* shaderPtr, GLenum shaderType, const char* shaderSource )
{
GLuint shader = qglCreateShader( shaderType );
qglShaderSource( shader, 1, &shaderSource, NULL );
qglCompileShader( shader );
GLint result = GL_FALSE;
qglGetShaderiv( shader, GL_COMPILE_STATUS, &result );
if ( result == GL_TRUE ) {
*shaderPtr = shader;
return qtrue;
}
GLint logLength = 0;
qglGetShaderiv( shader, GL_INFO_LOG_LENGTH, &logLength );
static char log[4096]; // I've seen logs over 3 KB in size.
qglGetShaderInfoLog( shader, sizeof(log), NULL, log );
ri.Printf( PRINT_ERROR, "%s shader: %s\n", shaderType == GL_VERTEX_SHADER ? "Vertex" : "Fragment", log );
return qfalse;
}
static qbool GL2_CreateProgram( GLSL_Program& prog, const char* vs, const char* fs )
{
if ( !GL2_CreateShader( &prog.vs, GL_VERTEX_SHADER, vs ) )
return qfalse;
if ( !GL2_CreateShader( &prog.fs, GL_FRAGMENT_SHADER, fs ) )
return qfalse;
prog.p = qglCreateProgram();
qglAttachShader( prog.p, prog.vs );
qglAttachShader( prog.p, prog.fs );
qglLinkProgram( prog.p );
return qtrue;
}
// We don't use "gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;"
// because most everything is rendered using the fixed function pipeline and
// ftransform makes sure we get matching results (and thus avoid Z-fighting).
static const char* dynLightVS =
"uniform vec4 osLightPos;\n"
"uniform vec4 osEyePos;\n"
"varying vec4 L;\n" // object-space light vector
"varying vec4 V;\n" // object-space view vector
"varying vec3 nN;\n" // normalized object-space normal vector
"\n"
"void main()\n"
"{\n"
" gl_Position = ftransform();\n"
" gl_TexCoord[0] = gl_MultiTexCoord0;\n"
" L = osLightPos - gl_Vertex;\n"
" V = osEyePos - gl_Vertex;\n"
" nN = gl_Normal;\n"
"}\n"
"";
static const char* dynLightFS =
"uniform sampler2D texture;\n"
"uniform vec4 lightColorRadius;" // w = 1 / (r^2)
"varying vec4 L;\n" // object-space light vector
"varying vec4 V;\n" // object-space view vector
"varying vec3 nN;\n" // normalized object-space normal vector
"\n"
"void main()\n"
"{\n"
" vec4 base = texture2D(texture, gl_TexCoord[0].xy);\n"
" vec3 nL = normalize(L.xyz);\n" // normalized light vector
" vec3 nV = normalize(V.xyz);\n" // normalized view vector
// light intensity
" float intensFactor = dot(L.xyz, L.xyz) * lightColorRadius.w;"
" vec3 intens = lightColorRadius.rgb * (1.0 - intensFactor);\n"
// specular reflection term (N.H)
" float specFactor = clamp(dot(nN, normalize(nL + nV)), 0.0, 1.0);\n"
" float spec = pow(specFactor, 16.0) * 0.25;\n"
// Lambertian diffuse reflection term (N.L)
" float diffuse = clamp(dot(nN, nL), 0.0, 1.0);\n"
" gl_FragColor = (base * vec4(diffuse) + vec4(spec)) * vec4(intens, 1.0);\n"
"}\n"
"";
struct FrameBuffer {
GLuint fbo;
GLuint color; // texture if MS, buffer if SS
GLuint depthStencil; // texture if MS, buffer if SS
qbool multiSampled;
qbool hasDepthStencil;
};
static FrameBuffer frameBufferMain;
static FrameBuffer frameBuffersPostProcess[2];
static unsigned int frameBufferReadIndex = 0; // read this for the latest color/depth data
static qbool frameBufferMultiSampling = qfalse;
#define CASE( x ) case x: return #x
#define GL( call ) call; GL2_CheckError( #call, __FUNCTION__, __FILE__, __LINE__ )
static const char* GL2_GetErrorString( GLenum ec )
{
switch ( ec )
{
CASE( GL_NO_ERROR );
CASE( GL_INVALID_ENUM );
CASE( GL_INVALID_VALUE );
CASE( GL_INVALID_OPERATION );
CASE( GL_INVALID_FRAMEBUFFER_OPERATION );
CASE( GL_OUT_OF_MEMORY );
CASE( GL_STACK_UNDERFLOW );
CASE( GL_STACK_OVERFLOW );
default: return "?";
}
}
static void GL2_CheckError( const char* call, const char* function, const char* file, int line )
{
const GLenum ec = qglGetError();
if ( ec == GL_NO_ERROR )
return;
const char* fileName = file;
while ( *file )
{
if ( *file == '/' || *file == '\\' )
fileName = file + 1;
++file;
}
ri.Printf( PRINT_ERROR, "%s failed\n", call );
ri.Printf( PRINT_ERROR, "%s:%d in %s\n", fileName, line, function );
ri.Printf( PRINT_ERROR, "GL error code: 0x%X (%d)\n", (unsigned int)ec, (int)ec );
ri.Printf( PRINT_ERROR, "GL error message: %s\n", GL2_GetErrorString(ec) );
}
static const char* GL2_GetFBOStatusString( GLenum status )
{
switch ( status )
{
CASE( GL_FRAMEBUFFER_COMPLETE );
CASE( GL_FRAMEBUFFER_UNDEFINED );
CASE( GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT );
CASE( GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT );
CASE( GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER );
CASE( GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER );
CASE( GL_FRAMEBUFFER_UNSUPPORTED );
CASE( GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE );
CASE( GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS );
default: return "?";
}
}
#undef CASE
static qbool GL2_FBO_CreateSS( FrameBuffer& fb, qbool depthStencil )
{
while ( qglGetError() != GL_NO_ERROR ) {} // clear the error queue
if ( depthStencil )
{
GL(qglGenTextures( 1, &fb.depthStencil ));
GL(qglBindTexture( GL_TEXTURE_2D, fb.depthStencil ));
GL(qglTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST ));
GL(qglTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST ));
GL(qglTexImage2D( GL_TEXTURE_2D, 0, GL_DEPTH24_STENCIL8, glConfig.vidWidth, glConfig.vidHeight, 0, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, NULL ));
}
GL(qglGenTextures( 1, &fb.color ));
GL(qglBindTexture( GL_TEXTURE_2D, fb.color ));
GL(qglTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR ));
GL(qglTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR ));
GL(qglTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA8, glConfig.vidWidth, glConfig.vidHeight, 0, GL_BGRA, GL_UNSIGNED_BYTE, NULL ));
GL(qglGenFramebuffers( 1, &fb.fbo ));
GL(qglBindFramebuffer( GL_FRAMEBUFFER, fb.fbo ));
GL(qglFramebufferTexture2D( GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, fb.color, 0 ));
if ( depthStencil )
GL(qglFramebufferTexture2D( GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_TEXTURE_2D, fb.depthStencil, 0 ));
const GLenum fboStatus = qglCheckFramebufferStatus( GL_FRAMEBUFFER );
if ( fboStatus != GL_FRAMEBUFFER_COMPLETE )
{
ri.Printf( PRINT_ERROR, "Failed to create FBO (status 0x%X, error 0x%X)\n", (unsigned int)fboStatus, (unsigned int)qglGetError() );
ri.Printf( PRINT_ERROR, "FBO status string: %s\n", GL2_GetFBOStatusString(fboStatus) );
return qfalse;
}
qglBindFramebuffer( GL_FRAMEBUFFER, 0 );
fb.multiSampled = qfalse;
fb.hasDepthStencil = depthStencil;
return qtrue;
}
static qbool GL2_FBO_CreateMS( FrameBuffer& fb )
{
while ( qglGetError() != GL_NO_ERROR ) {} // clear the error queue
GL(qglGenFramebuffers( 1, &fb.fbo ));
GL(qglBindFramebuffer( GL_FRAMEBUFFER, fb.fbo ));
GL(qglGenRenderbuffers( 1, &fb.color ));
GL(qglBindRenderbuffer( GL_RENDERBUFFER, fb.color ));
GL(qglRenderbufferStorageMultisample( GL_RENDERBUFFER, r_msaa->integer, GL_RGBA8, glConfig.vidWidth, glConfig.vidHeight ));
GL(qglFramebufferRenderbuffer( GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, fb.color ));
GL(qglGenRenderbuffers( 1, &fb.depthStencil ));
GL(qglBindRenderbuffer( GL_RENDERBUFFER, fb.depthStencil ));
GL(qglRenderbufferStorageMultisample( GL_RENDERBUFFER, r_msaa->integer, GL_DEPTH24_STENCIL8, glConfig.vidWidth, glConfig.vidHeight ));
GL(qglFramebufferRenderbuffer( GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, fb.color ));
GL(qglFramebufferRenderbuffer( GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER, fb.depthStencil ));
const GLenum fboStatus = qglCheckFramebufferStatus( GL_FRAMEBUFFER );
if ( fboStatus != GL_FRAMEBUFFER_COMPLETE )
{
ri.Printf( PRINT_ERROR, "Failed to create FBO (status 0x%X, error 0x%X)\n", (unsigned int)fboStatus, (unsigned int)qglGetError() );
ri.Printf( PRINT_ERROR, "FBO status string: %s\n", GL2_GetFBOStatusString(fboStatus) );
return qfalse;
}
qglBindFramebuffer( GL_FRAMEBUFFER, 0 );
fb.multiSampled = qtrue;
fb.hasDepthStencil = qtrue;
return qtrue;
}
static qbool GL2_FBO_Init()
{
const int msaa = r_msaa->integer;
const qbool validOption = msaa >= 2 && msaa <= 16;
const qbool enable = validOption && qglRenderbufferStorageMultisample != NULL;
frameBufferMultiSampling = enable;
if ( validOption && !enable )
ri.Printf( PRINT_WARNING, "MSAA requested but disabled because glRenderbufferStorageMultisample wasn't found\n" );
if ( !enable )
return GL2_FBO_CreateSS( frameBuffersPostProcess[0], qtrue ) &&
GL2_FBO_CreateSS( frameBuffersPostProcess[1], qtrue );
return GL2_FBO_CreateMS( frameBufferMain ) &&
GL2_FBO_CreateSS( frameBuffersPostProcess[0], qfalse ) &&
GL2_FBO_CreateSS( frameBuffersPostProcess[1], qfalse );
}
static void GL2_FBO_Bind( const FrameBuffer& fb )
{
qglBindFramebuffer( GL_FRAMEBUFFER, fb.fbo );
qglReadBuffer( GL_COLOR_ATTACHMENT0 );
qglDrawBuffer( GL_COLOR_ATTACHMENT0 );
}
static void GL2_FBO_Bind()
{
GL2_FBO_Bind( frameBuffersPostProcess[frameBufferReadIndex] );
}
static void GL2_FBO_Swap()
{
frameBufferReadIndex ^= 1;
}
static void GL2_FBO_BlitSSToBackBuffer()
{
// fixing up the blit mode here to avoid unnecessary qglClear calls
int blitMode = r_blitMode->integer;
if ( r_mode->integer != VIDEOMODE_UPSCALE )
blitMode = BLITMODE_STRETCHED;
if ( blitMode != BLITMODE_STRETCHED ) {
qglBindFramebuffer( GL_FRAMEBUFFER, 0 );
qglClearColor( 0.0f, 0.0f, 0.0f, 0.0f );
qglClear( GL_COLOR_BUFFER_BIT );
}
const FrameBuffer& fbo = frameBuffersPostProcess[frameBufferReadIndex];
qglBindFramebuffer( GL_READ_FRAMEBUFFER, fbo.fbo );
qglBindFramebuffer( GL_DRAW_FRAMEBUFFER, 0 );
qglReadBuffer( GL_COLOR_ATTACHMENT0 );
qglDrawBuffer( GL_BACK );
const int sw = glConfig.vidWidth;
const int sh = glConfig.vidHeight;
const int dw = glInfo.winWidth;
const int dh = glInfo.winHeight;
if ( blitMode == BLITMODE_STRETCHED ) {
qglBlitFramebuffer( 0, 0, sw, sh, 0, 0, dw, dh, GL_COLOR_BUFFER_BIT, GL_LINEAR );
} else if ( blitMode == BLITMODE_CENTERED ) {
const int dx = ( dw - sw ) / 2;
const int dy = ( dh - sh ) / 2;
qglBlitFramebuffer( 0, 0, sw, sh, dx, dy, dx + sw, dy + sh, GL_COLOR_BUFFER_BIT, GL_LINEAR );
} else { // blitMode == BLITMODE_ASPECT
const float rx = (float)dw / (float)sw;
const float ry = (float)dh / (float)sh;
const float ar = min( rx, ry );
const int w = (int)( sw * ar );
const int h = (int)( sh * ar );
const int x = ( dw - w ) / 2;
const int y = ( dh - h ) / 2;
qglBlitFramebuffer( 0, 0, sw, sh, x, y, x + w, y + h, GL_COLOR_BUFFER_BIT, GL_LINEAR );
}
}
static void GL2_FBO_BlitMSToSS()
{
const FrameBuffer& r = frameBufferMain;
const FrameBuffer& d = frameBuffersPostProcess[frameBufferReadIndex];
qglBindFramebuffer( GL_READ_FRAMEBUFFER, r.fbo );
qglBindFramebuffer( GL_DRAW_FRAMEBUFFER, d.fbo );
qglReadBuffer( GL_COLOR_ATTACHMENT0 );
qglDrawBuffer( GL_COLOR_ATTACHMENT0 );
const int w = glConfig.vidWidth;
const int h = glConfig.vidHeight;
qglBlitFramebuffer( 0, 0, w, h, 0, 0, w, h, GL_COLOR_BUFFER_BIT, GL_LINEAR );
}
static void GL2_FullScreenQuad()
{
const float w = glConfig.vidWidth;
const float h = glConfig.vidHeight;
qglBegin( GL_QUADS );
qglTexCoord2f( 0.0f, 0.0f );
qglVertex2f( 0.0f, h );
qglTexCoord2f( 0.0f, 1.0f );
qglVertex2f( 0.0f, 0.0f );
qglTexCoord2f( 1.0f, 1.0f );
qglVertex2f( w, 0.0f );
qglTexCoord2f( 1.0f, 0.0f );
qglVertex2f( w, h );
qglEnd();
}
static GLSL_Program gammaProg;
struct GLSL_GammaProgramAttribs
{
int texture;
int gammaOverbright;
};
static GLSL_GammaProgramAttribs gammaProgAttribs;
static void GL2_PostProcessGamma()
{
const float brightness = r_brightness->value;
const float gamma = 1.0f / r_gamma->value;
if ( gamma == 1.0f && brightness == 1.0f )
return;
GL2_FBO_Swap();
GL2_FBO_Bind();
GL_Program( gammaProg );
qglUniform1i( gammaProgAttribs.texture, 0 ); // we use texture unit 0
qglUniform4f( gammaProgAttribs.gammaOverbright, gamma, gamma, gamma, brightness );
GL_SelectTexture( 0 );
qglBindTexture( GL_TEXTURE_2D, frameBuffersPostProcess[frameBufferReadIndex ^ 1].color );
GL2_FullScreenQuad();
}
static const char* gammaVS =
"void main()\n"
"{\n"
" gl_Position = ftransform();\n"
" gl_TexCoord[0] = gl_MultiTexCoord0;\n"
"}\n"
"";
static const char* gammaFS =
"uniform sampler2D texture;\n"
"uniform vec4 gammaOverbright;\n"
"\n"
"void main()\n"
"{\n"
" vec3 base = texture2D(texture, gl_TexCoord[0].xy).rgb;\n"
" gl_FragColor = vec4(pow(base, gammaOverbright.xyz) * gammaOverbright.w, 1.0);\n"
"}\n"
"";
static GLSL_Program greyscaleProg;
struct GLSL_GreyscaleProgramAttribs
{
int texture;
int greyscale;
};
static GLSL_GreyscaleProgramAttribs greyscaleProgAttribs;
static qbool greyscaleProgramValid = qfalse;
static void GL2_PostProcessGreyscale()
{
if ( !greyscaleProgramValid )
return;
const float greyscale = Com_Clamp( 0.0f, 1.0f, r_greyscale->value );
if ( greyscale == 0.0f )
return;
GL2_FBO_Swap();
GL2_FBO_Bind();
GL_Program( greyscaleProg );
qglUniform1i( greyscaleProgAttribs.texture, 0 ); // we use texture unit 0
qglUniform1f( greyscaleProgAttribs.greyscale, greyscale );
GL_SelectTexture( 0 );
qglBindTexture( GL_TEXTURE_2D, frameBuffersPostProcess[frameBufferReadIndex ^ 1].color );
GL2_FullScreenQuad();
}
static const char* greyscaleVS =
"void main()\n"
"{\n"
" gl_Position = ftransform();\n"
" gl_TexCoord[0] = gl_MultiTexCoord0;\n"
"}\n"
"";
static const char* greyscaleFS =
"uniform sampler2D texture;\n"
"uniform float greyscale;\n"
"\n"
"void main()\n"
"{\n"
" vec3 base = texture2D(texture, gl_TexCoord[0].xy).rgb;\n"
" vec3 grey = vec3(0.299 * base.r + 0.587 * base.g + 0.114 * base.b);\n"
" gl_FragColor = vec4(mix(base, grey, greyscale), 1.0);\n"
"}\n"
"";
qbool GL2_Init()
{
if ( !GL2_FBO_Init() ) {
ri.Printf( PRINT_ERROR, "Failed to create FBOs\n" );
return qfalse;
}
if ( !GL2_CreateProgram( dynLightProg, dynLightVS, dynLightFS ) ) {
ri.Printf( PRINT_ERROR, "Failed to compile dynamic light shaders\n" );
return qfalse;
}
dynLightProgAttribs.osEyePos = qglGetUniformLocation( dynLightProg.p, "osEyePos" );
dynLightProgAttribs.osLightPos = qglGetUniformLocation( dynLightProg.p, "osLightPos" );
dynLightProgAttribs.texture = qglGetUniformLocation( dynLightProg.p, "texture" );
dynLightProgAttribs.lightColorRadius = qglGetUniformLocation( dynLightProg.p, "lightColorRadius" );
if ( !GL2_CreateProgram( gammaProg, gammaVS, gammaFS ) ) {
ri.Printf( PRINT_ERROR, "Failed to compile gamma correction shaders\n" );
return qfalse;
}
gammaProgAttribs.texture = qglGetUniformLocation( gammaProg.p, "texture" );
gammaProgAttribs.gammaOverbright = qglGetUniformLocation( gammaProg.p, "gammaOverbright" );
greyscaleProgramValid = GL2_CreateProgram( greyscaleProg, greyscaleVS, greyscaleFS );
if ( greyscaleProgramValid ) {
greyscaleProgAttribs.texture = qglGetUniformLocation( greyscaleProg.p, "texture" );
greyscaleProgAttribs.greyscale = qglGetUniformLocation( greyscaleProg.p, "greyscale" );
} else {
ri.Printf( PRINT_ERROR, "Failed to compile greyscale shaders\n" );
}
return qtrue;
}
void GL2_BeginFrame()
{
if ( frameBufferMultiSampling )
GL2_FBO_Bind( frameBufferMain );
else
GL2_FBO_Bind();
GL_Program();
}
void GL2_EndFrame()
{
if ( frameBufferMultiSampling )
GL2_FBO_BlitMSToSS();
// this call is needed because there is no insurance for
// what the state might be right now
// we disable depth test, depth write and blending
GL_State( GLS_DEPTHTEST_DISABLE );
qglViewport( 0, 0, glConfig.vidWidth, glConfig.vidHeight );
qglScissor( 0, 0, glConfig.vidWidth, glConfig.vidHeight );
GL2_PostProcessGamma();
GL2_PostProcessGreyscale();
// needed for later calls to GL_Bind because
// the above functions use qglBindTexture directly
glState.texID[glState.currenttmu] = 0;
qglViewport (0, 0, glInfo.winWidth, glInfo.winHeight );
qglScissor( 0, 0, glInfo.winWidth, glInfo.winHeight );
GL2_FBO_BlitSSToBackBuffer();
}

View file

@ -1,3 +1,29 @@
#define help_r_backend \
"renderer back-end to use\n" \
S_COLOR_VAL " GL2 " S_COLOR_HELP "= OpenGL 2.0\n" \
S_COLOR_VAL " GL3 " S_COLOR_HELP "= OpenGL 3.2\n" \
S_COLOR_VAL " D3D11 " S_COLOR_HELP "= Direct3D 11"
#define help_r_gl3_geoStream \
"geometry streaming strategy\n" \
"This only applies to the GL3 back-end. See " S_COLOR_CVAR "r_backend" S_COLOR_HELP " for details.\n" \
S_COLOR_VAL " 0 " S_COLOR_HELP "= Decide automatically\n" \
S_COLOR_VAL " 1 " S_COLOR_HELP "= BufferSubData\n" \
S_COLOR_VAL " 2 " S_COLOR_HELP "= Map Unsychronized\n" \
S_COLOR_VAL " 3 " S_COLOR_HELP "= Map Persistent when possible, else automatic\n" \
S_COLOR_VAL " 4 " S_COLOR_HELP "= AMD pinned memory when available, else automatic"
#define help_r_d3d11_syncOffsets \
"synchronizes vertex buffer offsets\n" \
"This only applies to the D3D11 back-end. See " S_COLOR_CVAR "r_backend" S_COLOR_HELP " for details.\n" \
S_COLOR_VAL " 0 " S_COLOR_HELP "= Split buffer offsets (more API calls)\n" \
S_COLOR_VAL " 1 " S_COLOR_HELP "= Sync'd buffer offsets (more data transferred)\n" \
S_COLOR_VAL " 2 " S_COLOR_HELP "= Decide automatically"
#define help_r_d3d11_maxQueuedFrames \
"max. pre-rendered frames\n" \
"The number of frames that the system is allowed to queue for rendering."
#define help_r_ext_max_anisotropy \
"max. allowed anisotropy ratio\n" \
"For anisotropic filtering to be enabled, this needs to be 2 or higher.\n" \
@ -53,21 +79,22 @@ S_COLOR_HELP " >" S_COLOR_VAL "1 " S_COLOR_HELP "= Brighter"
"disables rendering of portals\n" \
"Portal example: the bottom teleporter on q3dm7."
#define help_r_textureMode \
"texture filtering mode\n" \
S_COLOR_VAL " GL_NEAREST " S_COLOR_HELP "= No filtering\n" \
S_COLOR_VAL " GL_LINEAR_MIPMAP_NEAREST " S_COLOR_HELP "= Bilinear filtering\n" \
S_COLOR_VAL " GL_LINEAR_MIPMAP_LINEAR " S_COLOR_HELP "= Trilinear filtering\n" \
"For anisotropic filtering, refer to " S_COLOR_CVAR "r_ext_max_anisotropy" S_COLOR_HELP "."
#define help_r_swapInterval \
"v-blanks to wait for before swapping buffers\n" \
S_COLOR_VAL " 0 " S_COLOR_HELP "= No V-Sync\n" \
S_COLOR_VAL " 1 " S_COLOR_HELP "= Synced to the monitor's refresh rate\n" \
S_COLOR_VAL " 2 " S_COLOR_HELP "= Synced to half the monitor's refresh rate\n" \
S_COLOR_VAL " 3 " S_COLOR_HELP "= Synced to one third of the monitor's refresh rate\n" \
S_COLOR_VAL " N " S_COLOR_HELP "= Synced to monitor_refresh_rate / " S_COLOR_VAL "N\n" \
S_COLOR_HELP "It is not recommended to use V-Sync."
"Screen refresh periods to wait for before swapping buffers\n" \
S_COLOR_VAL " N < 0 " S_COLOR_HELP "= Adaptive V-Sync: tears when too late\n" \
S_COLOR_VAL " N = 0 " S_COLOR_HELP "= No V-Sync\n" \
S_COLOR_VAL " N > 0 " S_COLOR_HELP "= Standard V-Sync: never tears\n" \
"Adaptive V-Sync is not available when " S_COLOR_CVAR "r_backend " S_COLOR_HELP "is " S_COLOR_VAL "D3D11" S_COLOR_HELP ".\n" \
"When adaptive V-Sync is not available, standard V-Sync is requested instead.\n" \
"Please note that with OpenGL, your driver settings can override any of this."
#define help_r_frameSleep \
"whether the client should sleep to maintain the FPS cap\n" \
S_COLOR_VAL " 0 " S_COLOR_HELP "= Forced OFF (when V-Sync is enabled)\n" \
S_COLOR_VAL " 1 " S_COLOR_HELP "= Forced ON (when V-Sync is disabled)\n" \
S_COLOR_VAL " 2 " S_COLOR_HELP "= Automatic (detects V-Sync status)\n" \
"This only applies to OpenGL rendering back-ends:\n" \
"For Direct3D 11, the mode is always 'automatic'."
#define help_r_lightmap \
"renders the lightmaps only\n" \
@ -78,3 +105,49 @@ S_COLOR_HELP "It is not recommended to use V-Sync."
"renders the diffuse textures only\n" \
"Shaders with a lightmap stage will not draw the lightmap stage.\n" \
"This is mutually exclusive with " S_COLOR_CVAR "r_lightmap" S_COLOR_HELP "."
#define help_r_mipGenFilter \
"GPU mip-map filter\n" \
S_COLOR_VAL " L4 " S_COLOR_HELP "= Lanczos 4\n" \
S_COLOR_VAL " L3 " S_COLOR_HELP "= Lanczos 3\n" \
S_COLOR_VAL " BL " S_COLOR_HELP "= Bi-linear\n" \
S_COLOR_VAL " MN2 " S_COLOR_HELP "= Mitchell-Netravali 2 (B = 1/3, C = 1/3)\n" \
S_COLOR_VAL " BH4 " S_COLOR_HELP "= 3-term Blackman-Harris 4\n" \
S_COLOR_VAL " BH3 " S_COLOR_HELP "= 3-term Blackman-Harris 3\n" \
S_COLOR_VAL " BH2 " S_COLOR_HELP "= 3-term Blackman-Harris 2\n" \
S_COLOR_VAL " T2 " S_COLOR_HELP "= Tent 2 (1/3 2/3, same as the CPU version)\n" \
"The numbers specify the 'radius' of the window filters."
#define help_r_mipGenGamma \
"GPU mip-map gamma\n" \
"Specifies the gamma space in which the textures are stored.\n" \
"This is only used by GPU-side mip-map generation (" S_COLOR_CVAR "r_gpuMipGen " S_COLOR_VAL "1" S_COLOR_HELP ").\n" \
"This should really be around " S_COLOR_VAL "2.4 " S_COLOR_HELP "(CRT screens),\n" \
"but defaults lower to not break the looks of some things\n" \
"(e.g. cpm3a's teleporter).\n" \
"While " S_COLOR_VAL "1.0 " S_COLOR_HELP "will match the game's original look,\n" \
"higher values will better preserve contrast."
#define help_r_softSprites \
"enables depth sprites\n" \
"With it, sprites like blood, smoke, etc don't 'cut' through geometry sharply."
#define help_r_gpuMipGen \
"enables GPU mip-map generation\n" \
"This will both improve map load times and image quality.\n" \
"Only disable if the feature isn't working for whatever reason."
#define help_r_alphaToCoverage \
"enables alpha to coverage\n" \
"This enables anti-aliasing of alpha-tested surfaces when MSAA is enabled.\n" \
"Therefore, this requires " S_COLOR_CVAR "r_msaa " S_COLOR_HELP "to be greater than 1."
#define help_r_dither \
"enables dithering\n" \
"Introduces noise to fight color banding artifacts.\n" \
"The strength of the noise is controlled by " S_COLOR_CVAR "r_noiseScale" S_COLOR_HELP "."
#define help_r_noiseScale \
"dithering noise strength\n" \
"The dithering on/off switch is " S_COLOR_CVAR "r_dither" S_COLOR_HELP "."

View file

@ -29,6 +29,48 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#endif
// colors are pre-multiplied, alpha indicates whether blending should occur
const vec4_t r_mipBlendColors[16] = {
{ 0.0f, 0.0f, 0.0f, 0.0f },
{ 0.5f, 0.0f, 0.0f, 1.0f },
{ 0.0f, 0.5f, 0.0f, 1.0f },
{ 0.0f, 0.0f, 0.5f, 1.0f },
{ 0.5f, 0.0f, 0.0f, 1.0f },
{ 0.0f, 0.5f, 0.0f, 1.0f },
{ 0.0f, 0.0f, 0.5f, 1.0f },
{ 0.5f, 0.0f, 0.0f, 1.0f },
{ 0.0f, 0.5f, 0.0f, 1.0f },
{ 0.0f, 0.0f, 0.5f, 1.0f },
{ 0.5f, 0.0f, 0.0f, 1.0f },
{ 0.0f, 0.5f, 0.0f, 1.0f },
{ 0.0f, 0.0f, 0.5f, 1.0f },
{ 0.5f, 0.0f, 0.0f, 1.0f },
{ 0.0f, 0.5f, 0.0f, 1.0f },
{ 0.0f, 0.0f, 0.5f, 1.0f }
};
// colors are not pre-multiplied
static const byte mipBlendColors[16][4] = {
{ 0, 0, 0, 0 },
{ 255, 0, 0, 128 },
{ 0, 255, 0, 128 },
{ 0, 0, 255, 128 },
{ 255, 0, 0, 128 },
{ 0, 255, 0, 128 },
{ 0, 0, 255, 128 },
{ 255, 0, 0, 128 },
{ 0, 255, 0, 128 },
{ 0, 0, 255, 128 },
{ 255, 0, 0, 128 },
{ 0, 255, 0, 128 },
{ 0, 0, 255, 128 },
{ 255, 0, 0, 128 },
{ 0, 255, 0, 128 },
{ 0, 0, 255, 128 }
};
#define IMAGE_HASH_SIZE 1024
static image_t* hashTable[IMAGE_HASH_SIZE];
@ -36,74 +78,18 @@ static image_t* hashTable[IMAGE_HASH_SIZE];
static byte s_intensitytable[256];
static int gl_filter_min = GL_LINEAR_MIPMAP_LINEAR;
static int gl_filter_max = GL_LINEAR;
typedef struct {
const char* name;
int minimize, maximize;
} textureMode_t;
static const textureMode_t modes[] = {
{ "GL_NEAREST", GL_NEAREST, GL_NEAREST },
{ "GL_LINEAR", GL_LINEAR, GL_LINEAR },
{ "GL_NEAREST_MIPMAP_NEAREST", GL_NEAREST_MIPMAP_NEAREST, GL_NEAREST },
{ "GL_LINEAR_MIPMAP_NEAREST", GL_LINEAR_MIPMAP_NEAREST, GL_LINEAR },
{ "GL_NEAREST_MIPMAP_LINEAR", GL_NEAREST_MIPMAP_LINEAR, GL_NEAREST },
{ "GL_LINEAR_MIPMAP_LINEAR", GL_LINEAR_MIPMAP_LINEAR, GL_LINEAR },
{ 0 }
};
void GL_TextureMode( const char* string )
{
int i;
for (i = 0; modes[i].name; ++i) {
if ( !Q_stricmp( modes[i].name, string ) ) {
break;
}
}
if (!modes[i].name) {
ri.Printf( PRINT_ALL, "bad filter name\n" );
return;
}
gl_filter_min = modes[i].minimize;
gl_filter_max = modes[i].maximize;
// change all the existing mipmap texture objects
for ( i = 0 ; i < tr.numImages ; i++ ) {
const image_t* glt = tr.images[ i ];
if ( !(glt->flags & IMG_NOMIPMAP) ) {
GL_Bind( glt );
qglTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, gl_filter_min );
qglTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, gl_filter_max );
}
}
}
void R_ImageList_f( void )
{
int i, vram = 0;
ri.Printf( PRINT_ALL, "\nwide high MPI W format name\n" );
for ( i = 0; i < tr.numImages; ++i ) {
const image_t* image = tr.images[i];
GL_Bind( image );
GLint compressed;
qglGetTexLevelParameteriv( GL_TEXTURE_2D, 0, GL_TEXTURE_COMPRESSED_ARB, &compressed );
if (compressed)
qglGetTexLevelParameteriv( GL_TEXTURE_2D, 0, GL_TEXTURE_COMPRESSED_IMAGE_SIZE_ARB, &compressed );
else
compressed = image->width * image->height;
int totalPixelCount = 0;
for ( int i = 0; i < tr.numImages; ++i ) {
const image_t* const image = tr.images[i];
const int pixelCount = image->width * image->height;
if ( !(image->flags & IMG_NOMIPMAP) && (image->width > 1) && (image->height > 1) )
vram += compressed * 1.33f; // will overestimate, but that's what we want anyway
vram += compressed;
totalPixelCount += pixelCount * 1.33f; // will overestimate, but that's what we want anyway
else
totalPixelCount += pixelCount;
ri.Printf( PRINT_ALL, "%4i %4i %c%c%c ",
image->width, image->height,
@ -113,24 +99,14 @@ void R_ImageList_f( void )
);
switch ( image->wrapClampMode ) {
case GL_REPEAT: ri.Printf( PRINT_ALL, "R " ); break;
case GL_CLAMP: ri.Printf( PRINT_ALL, "C " ); break;
case GL_CLAMP_TO_EDGE: ri.Printf( PRINT_ALL, "E " ); break;
default: ri.Printf( PRINT_ALL, "? " ); break;
case TW_REPEAT: ri.Printf( PRINT_ALL, "R " ); break;
case TW_CLAMP_TO_EDGE: ri.Printf( PRINT_ALL, "E " ); break;
default: ri.Printf( PRINT_ALL, "? " ); break;
}
switch ( image->format ) {
case GL_RGB: ri.Printf( PRINT_ALL, "RGB " ); break;
case GL_RGB5: ri.Printf( PRINT_ALL, "RGB5 " ); break;
case GL_RGB8: ri.Printf( PRINT_ALL, "RGB8 " ); break;
case GL_RGBA: ri.Printf( PRINT_ALL, "RGBA " ); break;
case GL_RGBA4: ri.Printf( PRINT_ALL, "RGBA4 " ); break;
case GL_RGBA8: ri.Printf( PRINT_ALL, "RGBA8 " ); break;
case GL_LUMINANCE_ALPHA: ri.Printf( PRINT_ALL, "L8A8 " ); break;
case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: ri.Printf( PRINT_ALL, "DXT1 " ); break;
default:
ri.Printf( PRINT_ALL, "%5i ", image->format );
break;
case TF_RGBA8: ri.Printf( PRINT_ALL, "RGBA8 " ); break;
default: ri.Printf( PRINT_ALL, "%5i ", image->format ); break;
}
ri.Printf( PRINT_ALL, " %s\n", image->name );
@ -139,7 +115,7 @@ void R_ImageList_f( void )
ri.Printf( PRINT_ALL, "---------\n" );
ri.Printf( PRINT_ALL, "%i images\n", tr.numImages );
// just assume/pretend that everything is 4-component
ri.Printf( PRINT_ALL, "Estimated VRAM use: %iMB\n\n", vram / (1024 * 1024 / 4) );
ri.Printf( PRINT_ALL, "Estimated VRAM use: %iMB\n\n", totalPixelCount / (1024 * 1024 / 4) );
}
@ -279,30 +255,49 @@ static void R_BlendOverTexture( byte *data, int pixelCount, const byte blend[4]
}
}
static const byte mipBlendColors[16][4] = {
{0,0,0,0},
{255,0,0,128},
{0,255,0,128},
{0,0,255,128},
{255,0,0,128},
{0,255,0,128},
{0,0,255,128},
{255,0,0,128},
{0,255,0,128},
{0,0,255,128},
{255,0,0,128},
{0,255,0,128},
{0,0,255,128},
{255,0,0,128},
{0,255,0,128},
{0,0,255,128},
};
static int ComputeMipCount( int scaled_width, int scaled_height )
{
int mipCount = 1;
while ( scaled_width > 1 || scaled_height > 1 ) {
scaled_width = max( scaled_width >> 1, 1 );
scaled_height = max( scaled_height >> 1, 1 );
++mipCount;
}
return mipCount;
}
// note that the "32" here is for the image's STRIDE - it has nothing to do with the actual COMPONENTS
static void Upload32( image_t* image, unsigned int* data )
{
// atlases we generate ourselves
if ( image->flags & IMG_LMATLAS ) {
image->flags |= IMG_NOMIPMAP;
image->flags |= IMG_NOAF;
gal.CreateTexture( image, 1, image->width, image->height );
return;
}
// atlases loaded from images on disk
if ( Q_stristr( image->name, "maps/" ) == image->name &&
Q_stristr( image->name + 5, "/lm_" ) != NULL ) {
image->flags |= IMG_NOMIPMAP;
image->flags |= IMG_NOAF;
image->flags |= IMG_EXTLMATLAS;
if ( r_mapBrightness->value != 1.0f ) {
const int pixelCount = image->width * image->height;
byte* pixel = (byte*)data;
byte* const pixelEnd = (byte*)( data + pixelCount );
while ( pixel < pixelEnd ) {
R_ColorShiftLightingBytes( pixel, pixel );
pixel += 4;
}
}
}
int scaled_width, scaled_height;
// convert to exact power of 2 sizes
@ -323,6 +318,7 @@ static void Upload32( image_t* image, unsigned int* data )
data = pResampled.Get<unsigned int>();
image->width = scaled_width;
image->height = scaled_height;
ri.Printf( PRINT_DEVELOPER, "^3WARNING: ^7'%s' doesn't have PoT dimensions.\n", image->name );
}
// perform optional picmip operation
@ -344,29 +340,27 @@ static void Upload32( image_t* image, unsigned int* data )
scaled_height >>= 1;
}
// validate and/or override the internal format
switch (image->format) {
case GL_RGB:
image->format = GL_RGB8;
break;
case GL_RGBA:
image->format = GL_RGBA8;
break;
case GL_LUMINANCE_ALPHA:
break;
default:
ri.Error( ERR_DROP, "Upload32: Invalid format %d\n", image->format );
if ( glInfo.mipGenSupport && image->format == TF_RGBA8 && ( image->flags & IMG_NOMIPMAP ) == 0 ) {
const int w = image->width;
const int h = image->height;
const int mipCount = ComputeMipCount( w, h );
int mipOffset = 0;
while ( image->width > scaled_width || image->height > scaled_height ) {
image->width = max( image->width >> 1, 1 );
image->height = max( image->height >> 1, 1 );
mipOffset++;
}
gal.CreateTextureEx( image, mipCount, mipOffset, w, h, data );
return;
}
RI_AutoPtr pScaled( sizeof(unsigned) * scaled_width * scaled_height );
// copy or resample data as appropriate for first MIP level
if ( ( scaled_width == image->width ) && ( scaled_height == image->height ) ) {
if ( image->flags & IMG_NOMIPMAP ) {
qglTexImage2D( GL_TEXTURE_2D, 0, image->format, image->width, image->height, 0, GL_RGBA, GL_UNSIGNED_BYTE, data );
goto done;
gal.CreateTexture( image, 1, image->width, image->height );
gal.UpdateTexture( image, 0, 0, 0, image->width, image->height, data );
return;
}
Com_Memcpy( pScaled, data, image->width * image->height * 4 );
}
@ -384,7 +378,9 @@ static void Upload32( image_t* image, unsigned int* data )
if ( !(image->flags & IMG_NOIMANIP) )
R_LightScaleTexture( pScaled.Get<byte>(), scaled_width, scaled_height );
qglTexImage2D( GL_TEXTURE_2D, 0, image->format, scaled_width, scaled_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, pScaled );
const int mipCount = ( image->flags & IMG_NOMIPMAP ) ? 1 : ComputeMipCount( scaled_width, scaled_height );
gal.CreateTexture( image, mipCount, scaled_width, scaled_height );
gal.UpdateTexture( image, 0, 0, 0, scaled_width, scaled_height, pScaled );
if ( !(image->flags & IMG_NOMIPMAP) )
{
@ -399,26 +395,9 @@ static void Upload32( image_t* image, unsigned int* data )
if ( r_colorMipLevels->integer )
R_BlendOverTexture( pScaled, scaled_width * scaled_height, mipBlendColors[miplevel] );
qglTexImage2D( GL_TEXTURE_2D, miplevel, image->format, scaled_width, scaled_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, pScaled );
gal.UpdateTexture( image, miplevel, 0, 0, scaled_width, scaled_height, pScaled );
}
}
done:
qglGetTexLevelParameteriv( GL_TEXTURE_2D, 0, GL_TEXTURE_INTERNAL_FORMAT, (GLint*)&image->format );
if ( glInfo.maxAnisotropy >= 2 && r_ext_max_anisotropy->integer >= 2 )
qglTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, min( r_ext_max_anisotropy->integer, glInfo.maxAnisotropy ) );
if ( image->flags & IMG_NOMIPMAP ) {
qglTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
qglTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
} else {
qglTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, gl_filter_min );
qglTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, gl_filter_max );
}
GL_CheckErrors();
}
}
@ -427,17 +406,14 @@ void R_UploadLightmapTile( image_t* image, byte* pic, int x, int y, int width, i
if ( !(image->flags & IMG_LMATLAS) )
ri.Error( ERR_DROP, "R_UploadLightmapTile: IMG_LMATLAS flag not defined\n" );
GL_Bind( image );
qglTexSubImage2D( GL_TEXTURE_2D, 0, x, y, width, height, GL_RGBA, GL_UNSIGNED_BYTE, pic );
GL_CheckErrors();
gal.UpdateTexture( image, 0, x, y, width, height, pic );
}
// this is the only way any image_t are created
// !!! i'm pretty sure this DOESN'T work correctly for non-POT images
image_t* R_CreateImage( const char* name, byte* pic, int width, int height, GLenum format, int flags, int glWrapClampMode )
image_t* R_CreateImage( const char* name, byte* pic, int width, int height, textureFormat_t format, int flags, textureWrap_t glWrapClampMode )
{
if (strlen(name) >= MAX_QPATH)
ri.Error( ERR_DROP, "R_CreateImage: \"%s\" is too long\n", name );
@ -446,8 +422,6 @@ image_t* R_CreateImage( const char* name, byte* pic, int width, int height, GLen
ri.Error( ERR_DROP, "R_CreateImage: MAX_DRAWIMAGES hit\n" );
image_t* image = tr.images[tr.numImages] = RI_New<image_t>();
qglGenTextures( 1, &image->texnum );
tr.numImages++;
strcpy( image->name, name );
@ -458,20 +432,9 @@ image_t* R_CreateImage( const char* name, byte* pic, int width, int height, GLen
image->height = height;
image->wrapClampMode = glWrapClampMode;
GL_Bind( image );
tr.numImages++;
if ( flags & IMG_LMATLAS ) {
image->format = GL_RGBA8;
qglTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA8, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL );
qglTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
qglTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
qglTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE );
qglTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE );
} else {
Upload32( image, (unsigned int*)pic );
qglTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, glWrapClampMode );
qglTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, glWrapClampMode );
}
Upload32( image, (unsigned int*)pic );
// KHB there are times we have no interest in naming an image at all (notably, font glyphs)
// but atm the rest of the system is too dependent on everything being named
@ -509,9 +472,9 @@ extern "C"
void jpeg_free_small( j_common_ptr cinfo, void* object, size_t sizeofobject ) { ri.Free(object); }
void* jpeg_get_large( j_common_ptr cinfo, size_t sizeofobject ) { return jpeg_get_small( cinfo, sizeofobject ); }
void jpeg_free_large( j_common_ptr cinfo, void* object, size_t sizeofobject ) { jpeg_free_small( cinfo, object, sizeofobject ); }
size_t jpeg_mem_available( j_common_ptr cinfo, size_t min_bytes_needed, size_t max_bytes_needed, size_t already_allocated ) { return max_bytes_needed; }
void jpeg_open_backing_store( j_common_ptr cinfo, backing_store_ptr info, long total_bytes_needed ) { ERREXIT(cinfo, JERR_NO_BACKING_STORE); }
long jpeg_mem_init( j_common_ptr cinfo) { return 0; }
size_t jpeg_mem_available( j_common_ptr cinfo, size_t min_bytes_needed, size_t max_bytes_needed, size_t already_allocated ) { return max_bytes_needed; }
void jpeg_open_backing_store( j_common_ptr cinfo, backing_store_ptr info, long total_bytes_needed ) { ERREXIT(cinfo, JERR_NO_BACKING_STORE); }
long jpeg_mem_init( j_common_ptr cinfo) { return 0; }
void jpeg_mem_term( j_common_ptr cinfo) {}
void error_exit( j_common_ptr cinfo )
@ -534,7 +497,7 @@ extern "C"
};
static qbool LoadJPG( const char* fileName, byte* buffer, int len, byte** pic, int* w, int* h, GLenum* format )
static qbool LoadJPG( const char* fileName, byte* buffer, int len, byte** pic, int* w, int* h, textureFormat_t* format )
{
jpeg_decompress_struct cinfo;
jpeg_error_mgr jerr;
@ -581,7 +544,7 @@ static qbool LoadJPG( const char* fileName, byte* buffer, int len, byte** pic, i
jpeg_finish_decompress( &cinfo );
jpeg_destroy_decompress( &cinfo );
*format = GL_RGB;
*format = TF_RGBA8;
return qtrue;
}
@ -641,9 +604,9 @@ int SaveJPGToBuffer( byte* out, int quality, int image_width, int image_height,
///////////////////////////////////////////////////////////////
extern qbool LoadSTB( const char* fileName, byte* buffer, int len, byte** pic, int* w, int* h, GLenum* format );
extern qbool LoadSTB( const char* fileName, byte* buffer, int len, byte** pic, int* w, int* h, textureFormat_t* format );
typedef qbool (*imageLoaderFunc)( const char* fileName, byte* buffer, int len, byte** pic, int* w, int* h, GLenum* format );
typedef qbool (*imageLoaderFunc)( const char* fileName, byte* buffer, int len, byte** pic, int* w, int* h, textureFormat_t* format );
typedef struct {
const char* extension;
@ -658,7 +621,7 @@ static const imageLoader_t imageLoaders[] = {
};
static void R_LoadImage( const char* name, byte** pic, int* w, int* h, GLenum* format )
static void R_LoadImage( const char* name, byte** pic, int* w, int* h, textureFormat_t* format )
{
*pic = NULL;
*w = 0;
@ -718,7 +681,7 @@ static const forcedLoadImage_t g_forcedLoadImages[] = {
// finds or loads the given image - returns NULL if it fails, not a default image
const image_t* R_FindImageFile( const char* name, int flags, int glWrapClampMode )
const image_t* R_FindImageFile( const char* name, int flags, textureWrap_t glWrapClampMode )
{
if ( !name )
return NULL;
@ -766,7 +729,7 @@ const image_t* R_FindImageFile( const char* name, int flags, int glWrapClampMode
//
byte* pic;
int width, height;
GLenum format;
textureFormat_t format;
R_LoadImage( name, &pic, &width, &height, &format );
if ( !pic )
@ -834,8 +797,7 @@ static void R_CreateFogImage()
}
}
tr.fogImage = R_CreateImage( "*fog", p, FOG_S, FOG_T, GL_RGBA, IMG_NOPICMIP, GL_CLAMP_TO_EDGE );
qglTexParameterfv( GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, colorWhite );
tr.fogImage = R_CreateImage( "*fog", p, FOG_S, FOG_T, TF_RGBA8, IMG_NOPICMIP, TW_CLAMP_TO_EDGE );
}
@ -857,7 +819,7 @@ static void R_CreateDefaultImage()
data[i][i][3] = 255;
}
tr.defaultImage = R_CreateImage( "*default", (byte*)data, DEFAULT_SIZE, DEFAULT_SIZE, GL_RGBA, IMG_NOPICMIP, GL_REPEAT );
tr.defaultImage = R_CreateImage( "*default", (byte*)data, DEFAULT_SIZE, DEFAULT_SIZE, TF_RGBA8, IMG_NOPICMIP | IMG_NOAF, TW_REPEAT );
}
@ -870,12 +832,12 @@ static void R_CreateBuiltinImages()
// we use a solid white image instead of disabling texturing
Com_Memset( data, 255, 4 );
tr.whiteImage = R_CreateImage( "*white", data, 1, 1, GL_RGBA, IMG_NOMIPMAP, GL_REPEAT );
tr.whiteImage = R_CreateImage( "*white", data, 1, 1, TF_RGBA8, IMG_NOMIPMAP | IMG_NOAF, TW_REPEAT );
// scratchimages usually used for cinematic drawing (signal-quality effects)
// these are just placeholders: RE_StretchRaw will regenerate them when it wants them
for (i = 0; i < 16; ++i) // MAX_VIDEO_HANDLES
tr.scratchImage[i] = R_CreateImage( "*scratch", data, 1, 1, GL_RGBA, IMG_NOMIPMAP | IMG_NOPICMIP, GL_CLAMP );
for (i = 0; i < ARRAY_LEN(tr.scratchImage); ++i)
tr.scratchImage[i] = R_CreateImage( "*scratch", data, 1, 1, TF_RGBA8, IMG_NOMIPMAP | IMG_NOPICMIP, TW_CLAMP_TO_EDGE );
R_CreateFogImage();
}
@ -900,22 +862,6 @@ void R_InitImages()
}
void R_DeleteTextures()
{
for ( int i = 0; i < tr.numImages; ++i )
qglDeleteTextures( 1, &tr.images[i]->texnum );
tr.numImages = 0;
Com_Memset( tr.images, 0, sizeof( tr.images ) );
Com_Memset( glState.texID, 0, sizeof( glState.texID ) );
for ( int i = MAX_TMUS - 1; i >= 0; --i ) {
GL_SelectTexture( i );
qglBindTexture( GL_TEXTURE_2D, 0 );
}
}
/*
============================================================================

View file

@ -27,13 +27,14 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
glconfig_t glConfig;
glinfo_t glInfo;
glstate_t glState;
screenshotCommand_t r_delayedScreenshot;
qbool r_delayedScreenshotPending = qfalse;
int r_delayedScreenshotFrame = 0;
static void GfxInfo_f( void );
graphicsAPILayer_t gal;
cvar_t *r_backend;
cvar_t *r_frameSleep;
cvar_t *r_verbose;
@ -62,7 +63,17 @@ cvar_t *r_lightmap;
cvar_t *r_novis;
cvar_t *r_nocull;
cvar_t *r_nocurves;
cvar_t *r_softSprites;
cvar_t *r_gpuMipGen;
cvar_t *r_alphaToCoverage;
cvar_t *r_dither;
cvar_t *r_mipGenFilter;
cvar_t *r_mipGenGamma;
cvar_t *r_noiseScale;
cvar_t *r_gl3_geoStream;
cvar_t *r_d3d11_syncOffsets;
cvar_t *r_d3d11_maxQueuedFrames;
cvar_t *r_ext_max_anisotropy;
cvar_t *r_msaa;
@ -83,7 +94,6 @@ cvar_t *r_shownormals;
cvar_t *r_finish;
cvar_t *r_clear;
cvar_t *r_swapInterval;
cvar_t *r_textureMode;
cvar_t *r_lockpvs;
cvar_t *r_noportals;
cvar_t *r_portalOnly;
@ -124,163 +134,6 @@ int max_polys;
int max_polyverts;
static void GL_SetDefaultState()
{
qglClearDepth( 1.0f );
qglCullFace( GL_FRONT );
qglColor4f( 1,1,1,1 );
for ( int i = 0; i < MAX_TMUS; ++i ) {
GL_SelectTexture( i );
GL_TextureMode( r_textureMode->string );
GL_TexEnv( GL_MODULATE );
qglDisable( GL_TEXTURE_2D );
}
GL_SelectTexture( 0 );
qglEnable( GL_TEXTURE_2D );
qglShadeModel( GL_SMOOTH );
qglDepthFunc( GL_LEQUAL );
qglPolygonOffset( -1, -1 );
// the vertex array is always enabled, but the color and texture
// arrays are enabled and disabled around the compiled vertex array call
qglEnableClientState( GL_VERTEX_ARRAY );
//
// make sure our GL state vector is set correctly
//
glState.glStateBits = GLS_DEPTHTEST_DISABLE | GLS_DEPTHMASK_TRUE;
qglPolygonMode( GL_FRONT_AND_BACK, GL_FILL );
qglDepthMask( GL_TRUE );
qglDisable( GL_DEPTH_TEST );
qglEnable( GL_SCISSOR_TEST );
qglDisable( GL_CULL_FACE );
qglDisable( GL_BLEND );
// Needed for some of our qglReadPixels calls.
// The default alignment is 4.
// RGB with width 1366 -> not a multiple of 4!
qglPixelStorei( GL_PACK_ALIGNMENT, 1 );
}
static void GL_InitGLConfig()
{
Q_strncpyz( glConfig.vendor_string, (const char*)qglGetString( GL_VENDOR ), sizeof( glConfig.vendor_string ) );
Q_strncpyz( glConfig.renderer_string, (const char*)qglGetString( GL_RENDERER ), sizeof( glConfig.renderer_string ) );
Q_strncpyz( glConfig.version_string, (const char*)qglGetString( GL_VERSION ), sizeof( glConfig.version_string ) );
Q_strncpyz( glConfig.extensions_string, (const char*)qglGetString( GL_EXTENSIONS ), sizeof( glConfig.extensions_string ) );
qglGetIntegerv( GL_MAX_TEXTURE_SIZE, &glConfig.unused_maxTextureSize );
glConfig.unused_maxActiveTextures = 0;
glConfig.unused_driverType = 0; // ICD
glConfig.unused_hardwareType = 0; // generic
glConfig.unused_deviceSupportsGamma = qtrue;
glConfig.unused_textureCompression = 0; // no compression
glConfig.unused_textureEnvAddAvailable = qtrue;
glConfig.unused_displayFrequency = 0;
glConfig.unused_isFullscreen = !!r_fullscreen->integer;
glConfig.unused_stereoEnabled = qfalse;
glConfig.unused_smpActive = qfalse;
}
static void GL_InitGLInfo()
{
qglGetIntegerv( GL_MAX_TEXTURE_SIZE, &glInfo.maxTextureSize );
qglGetIntegerv( GL_MAX_ELEMENTS_INDICES, &glInfo.maxDrawElementsI );
qglGetIntegerv( GL_MAX_ELEMENTS_VERTICES, &glInfo.maxDrawElementsV );
if ( strstr( glConfig.extensions_string, "GL_EXT_texture_filter_anisotropic" ) )
qglGetIntegerv( GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &glInfo.maxAnisotropy );
else
glInfo.maxAnisotropy = 0;
}
static void GL_InitExtensions()
{
const char* missingExtension = NULL;
if ( !Sys_GL_LoadExtensions( &missingExtension ) )
ri.Error( ERR_FATAL, "GL_InitExtensions() - failed to load %s\n", missingExtension ? missingExtension : "a required extension" );
if ( !GL2_Init() )
ri.Error( ERR_FATAL, "GL_InitExtensions() - failed to create GL2 objects\n" );
}
/*
** InitOpenGL
**
** This function is responsible for initializing a valid OpenGL subsystem. This
** is done by calling Sys_GL_Init (which gives us a working OGL subsystem) then
** setting variables, checking GL constants, and reporting the gfx system config
** to the user.
*/
static void InitOpenGL()
{
// Sys_GL_Init initializes OS-specific portions of the renderer
// it directly or indirectly references the following cvars:
// r_fullscreen, r_mode, r_width, r_height
if ( glConfig.vidWidth == 0 )
{
// the order of these calls can not be changed
Sys_GL_Init();
GL_InitGLConfig();
GL_InitGLInfo();
GL_InitExtensions();
// apply the current V-Sync option after the first rendered frame
r_swapInterval->modified = qtrue;
}
GfxInfo_f();
GL_SetDefaultState();
}
void GL_CheckErrors()
{
int err = qglGetError();
if ((err == GL_NO_ERROR) || r_ignoreGLErrors->integer)
return;
char s[64];
switch( err ) {
case GL_INVALID_ENUM:
strcpy( s, "GL_INVALID_ENUM" );
break;
case GL_INVALID_VALUE:
strcpy( s, "GL_INVALID_VALUE" );
break;
case GL_INVALID_OPERATION:
strcpy( s, "GL_INVALID_OPERATION" );
break;
case GL_STACK_OVERFLOW:
strcpy( s, "GL_STACK_OVERFLOW" );
break;
case GL_STACK_UNDERFLOW:
strcpy( s, "GL_STACK_UNDERFLOW" );
break;
case GL_OUT_OF_MEMORY:
strcpy( s, "GL_OUT_OF_MEMORY" );
break;
default:
Com_sprintf( s, sizeof(s), "%i", err);
break;
}
ri.Error( ERR_FATAL, "GL_CheckErrors: %s", s );
}
void R_ConfigureVideoMode( int desktopWidth, int desktopHeight )
{
glInfo.winFullscreen = !!r_fullscreen->integer;
@ -326,18 +179,7 @@ static void RB_TakeScreenshotTGA( int x, int y, int width, int height, const cha
tga->width = LittleShort( width );
tga->height = LittleShort( height );
tga->pixel_size = 24;
byte* pRGB = p + sizeof(TargaHeader);
qglReadPixels( x, y, width, height, GL_RGB, GL_UNSIGNED_BYTE, pRGB );
// swap RGB to BGR
for (int i = 0; i < c; i += 3)
{
byte r = pRGB[i];
pRGB[i] = pRGB[i+2];
pRGB[i+2] = r;
}
gal.ReadPixels( x, y, width, height, 1, CS_BGR, p + sizeof(TargaHeader) );
ri.FS_WriteFile( fileName, p, sizeof(TargaHeader) + c );
}
@ -345,7 +187,7 @@ static void RB_TakeScreenshotTGA( int x, int y, int width, int height, const cha
static void RB_TakeScreenshotJPG( int x, int y, int width, int height, const char* fileName )
{
RI_AutoPtr p( width * height * 4 );
qglReadPixels( x, y, width, height, GL_RGBA, GL_UNSIGNED_BYTE, p );
gal.ReadPixels( x, y, width, height, 1, CS_RGBA, p );
RI_AutoPtr out( width * height * 4 );
int n = SaveJPGToBuffer( out, 95, width, height, p );
@ -356,7 +198,7 @@ static void RB_TakeScreenshotJPG( int x, int y, int width, int height, const cha
const void* RB_TakeScreenshotCmd( const screenshotCommand_t* cmd )
{
// NOTE: the current read buffer is the last FBO color attachment texture that was written to
// therefore, qglReadPixels will get the latest data even with double/triple buffering enabled
// therefore, ReadPixels will get the latest data even with double/triple buffering enabled
switch (cmd->type) {
case screenshotCommand_t::SS_JPG:
@ -394,7 +236,7 @@ static void R_TakeScreenshot( const char* ext, screenshotCommand_t::ss_type type
r_delayedScreenshotFrame = 0;
cmd->delayed = qtrue;
} else {
if ( RB_FindRenderCommand( RC_SCREENSHOT ) )
if ( R_FindRenderCommand( RC_SCREENSHOT ) )
return;
cmd = (screenshotCommand_t*)R_GetCommandBuffer( sizeof(screenshotCommand_t) );
if ( !cmd )
@ -452,21 +294,18 @@ static void R_ScreenShotNoConJPG_f()
const void *RB_TakeVideoFrameCmd( const void *data )
{
int frameSize;
const videoFrameCommand_t* cmd = (const videoFrameCommand_t*)data;
if( cmd->motionJpeg )
{
qglReadPixels( 0, 0, cmd->width, cmd->height, GL_RGBA, GL_UNSIGNED_BYTE, cmd->captureBuffer );
frameSize = SaveJPGToBuffer( cmd->encodeBuffer, 95, cmd->width, cmd->height, cmd->captureBuffer );
gal.ReadPixels( 0, 0, cmd->width, cmd->height, 1, CS_RGBA, cmd->captureBuffer );
const int frameSize = SaveJPGToBuffer( cmd->encodeBuffer, 95, cmd->width, cmd->height, cmd->captureBuffer );
ri.CL_WriteAVIVideoFrame( cmd->encodeBuffer, frameSize );
}
else
{
qglPixelStorei( GL_PACK_ALIGNMENT, 4 );
qglReadPixels( 0, 0, cmd->width, cmd->height, GL_BGR, GL_UNSIGNED_BYTE, cmd->captureBuffer );
qglPixelStorei( GL_PACK_ALIGNMENT, 1 );
frameSize = PAD( cmd->width, 4 ) * cmd->height * 3;
gal.ReadPixels( 0, 0, cmd->width, cmd->height, 4, CS_BGR, cmd->captureBuffer );
const int frameSize = PAD( cmd->width, 4 ) * cmd->height * 3;
ri.CL_WriteAVIVideoFrame( cmd->captureBuffer, frameSize );
}
@ -479,27 +318,17 @@ const void *RB_TakeVideoFrameCmd( const void *data )
void GfxInfo_f( void )
{
cvar_t* sys_cpustring = ri.Cvar_Get( "sys_cpustring", "", 0 );
ri.Printf( PRINT_DEVELOPER, "\nGL_VENDOR: %s\n", glConfig.vendor_string );
ri.Printf( PRINT_DEVELOPER, "GL_RENDERER: %s\n", glConfig.renderer_string );
ri.Printf( PRINT_DEVELOPER, "GL_VERSION: %s\n", glConfig.version_string );
ri.Printf( PRINT_DEVELOPER, "GL_EXTENSIONS: %s\n", glConfig.extensions_string );
ri.Printf( PRINT_ALL, "PIXELFORMAT: RGBA%d Z%d S%d\n", glConfig.colorBits, glConfig.depthBits, glConfig.stencilBits );
ri.Printf( PRINT_ALL, "MODE: %dx%d ", glConfig.vidWidth, glConfig.vidHeight );
if ( glInfo.displayFrequency )
ri.Printf( PRINT_ALL, "%dHz\n", glInfo.displayFrequency );
else
ri.Printf( PRINT_ALL, "\n" );
ri.Printf( PRINT_DEVELOPER, "texturemode: %s\n", r_textureMode->string );
ri.Printf( PRINT_DEVELOPER, "picmip: %d\n", r_picmip->integer );
ri.Printf( PRINT_DEVELOPER, "ambient pass: %s\n", r_vertexLight->integer ? "vertex" : "lightmap" );
if ( r_finish->integer ) {
ri.Printf( PRINT_DEVELOPER, "Forcing glFinish\n" );
}
ri.Printf( PRINT_DEVELOPER, "CPU: %s\n", sys_cpustring->string );
ri.Printf( PRINT_ALL, "Back-end: %s\n", r_backend->string );
if ( glConfig.vendor_string[0] != '\0' )
ri.Printf( PRINT_ALL, "Vendor: %s\n", glConfig.vendor_string );
if ( glConfig.renderer_string[0] != '\0' )
ri.Printf( PRINT_ALL, "Renderer: %s\n", glConfig.renderer_string );
if ( glConfig.version_string[0] != '\0' )
ri.Printf( PRINT_ALL, "OpenGL version: %s\n", glConfig.version_string );
ri.Printf( PRINT_ALL, "Soft sprites : %s\n", glInfo.softSpriteSupport ? "ON" : "OFF" );
ri.Printf( PRINT_ALL, "Alpha to coverage : %s\n", glInfo.alphaToCoverageSupport ? "ON" : "OFF" );
ri.Printf( PRINT_ALL, "GPU mip-map generation: %s\n", glInfo.mipGenSupport ? "ON" : "OFF" );
gal.PrintInfo();
}
@ -525,6 +354,17 @@ static const cvarTableItem_t r_cvars[] =
//
// latched and archived variables
//
#if defined( _WIN32 )
{ &r_backend, "r_backend", "D3D11", CVAR_ARCHIVE | CVAR_LATCH, CVART_STRING, NULL, NULL, help_r_backend },
#else
{ &r_backend, "r_backend", "GL3", CVAR_ARCHIVE | CVAR_LATCH, CVART_STRING, NULL, NULL, help_r_backend },
#endif
{ &r_frameSleep, "r_frameSleep", "2", CVAR_ARCHIVE, CVART_INTEGER, "0", "2", help_r_frameSleep },
{ &r_mipGenFilter, "r_mipGenFilter", "L4", CVAR_ARCHIVE | CVAR_LATCH, CVART_STRING, NULL, NULL, help_r_mipGenFilter },
{ &r_mipGenGamma, "r_mipGenGamma", "1.8", CVAR_ARCHIVE | CVAR_LATCH, CVART_FLOAT, "1.0", "3.0", help_r_mipGenGamma },
{ &r_gl3_geoStream, "r_gl3_geoStream", "0", CVAR_ARCHIVE | CVAR_LATCH, CVART_INTEGER, "0", XSTRING(GL3MAP_MAX), help_r_gl3_geoStream },
{ &r_d3d11_syncOffsets, "r_d3d11_syncOffsets", "2", CVAR_ARCHIVE | CVAR_LATCH, CVART_INTEGER, "0", XSTRING(D3D11SO_MAX), help_r_d3d11_syncOffsets },
{ &r_d3d11_maxQueuedFrames, "r_d3d11_maxQueuedFrames", "3", CVAR_ARCHIVE | CVAR_LATCH, CVART_INTEGER, "1", "16", help_r_d3d11_maxQueuedFrames },
{ &r_ext_max_anisotropy, "r_ext_max_anisotropy", "16", CVAR_ARCHIVE | CVAR_LATCH, CVART_INTEGER, "0", "16", help_r_ext_max_anisotropy },
{ &r_msaa, "r_msaa", "0", CVAR_ARCHIVE | CVAR_LATCH, CVART_INTEGER, "0", "16", "anti-aliasing sample count, " S_COLOR_VAL "0" S_COLOR_HELP "=off" },
{ &r_picmip, "r_picmip", "0", CVAR_ARCHIVE | CVAR_LATCH, CVART_INTEGER, "0", "16", help_r_picmip },
@ -545,6 +385,12 @@ static const cvarTableItem_t r_cvars[] =
{ &r_vertexLight, "r_vertexLight", "0", CVAR_ARCHIVE | CVAR_LATCH, CVART_BOOL, NULL, NULL, "disables lightmap texture blending" },
// note that r_subdivisions > 64 will create rendering artefacts because you'll see the other side of a curved surface when against it
{ &r_subdivisions, "r_subdivisions", "1", CVAR_ARCHIVE | CVAR_LATCH, CVART_FLOAT, "1", "64", help_r_subdivisions },
{ &r_fullbright, "r_fullbright", "0", CVAR_ARCHIVE | CVAR_LATCH, CVART_BOOL, NULL, NULL, help_r_fullbright },
{ &r_lightmap, "r_lightmap", "0", CVAR_ARCHIVE | CVAR_LATCH, CVART_BOOL, NULL, NULL, help_r_lightmap },
{ &r_softSprites, "r_softSprites", "1", CVAR_ARCHIVE | CVAR_LATCH, CVART_BOOL, NULL, NULL, help_r_softSprites },
{ &r_gpuMipGen, "r_gpuMipGen", "1", CVAR_ARCHIVE | CVAR_LATCH, CVART_BOOL, NULL, NULL, help_r_gpuMipGen },
{ &r_alphaToCoverage, "r_alphaToCoverage", "1", CVAR_ARCHIVE | CVAR_LATCH, CVART_BOOL, NULL, NULL, help_r_alphaToCoverage },
{ &r_dither, "r_dither", "0", CVAR_ARCHIVE | CVAR_LATCH, CVART_BOOL, NULL, NULL, help_r_dither },
//
// latched variables that can only change over a restart
@ -561,12 +407,10 @@ static const cvarTableItem_t r_cvars[] =
{ &r_noportals, "r_noportals", "0", CVAR_ARCHIVE, CVART_BOOL, NULL, NULL, help_r_noportals },
{ &r_dynamiclight, "r_dynamiclight", "1", CVAR_ARCHIVE, CVART_BOOL, NULL, NULL, "enables dynamic lights" },
{ &r_finish, "r_finish", "0", CVAR_ARCHIVE, CVART_BOOL, NULL, NULL, "enables glFinish calls" },
{ &r_textureMode, "r_textureMode", "GL_LINEAR_MIPMAP_LINEAR", CVAR_ARCHIVE, CVART_STRING, NULL, NULL, help_r_textureMode },
{ &r_swapInterval, "r_swapInterval", "0", CVAR_ARCHIVE, CVART_INTEGER, "0", "8", help_r_swapInterval },
{ &r_swapInterval, "r_swapInterval", "0", CVAR_ARCHIVE, CVART_INTEGER, "-8", "8", help_r_swapInterval },
{ &r_gamma, "r_gamma", "1.2", CVAR_ARCHIVE, CVART_FLOAT, "0.5", "3", help_r_gamma },
{ &r_greyscale, "r_greyscale", "0", CVAR_ARCHIVE, CVART_FLOAT, "0", "1", "controls how monochrome the final image looks" },
{ &r_lightmap, "r_lightmap", "0", CVAR_ARCHIVE, CVART_BOOL, NULL, NULL, help_r_lightmap },
{ &r_fullbright, "r_fullbright", "0", CVAR_ARCHIVE, CVART_BOOL, NULL, NULL, help_r_fullbright },
{ &r_noiseScale, "r_noiseScale", "1.0", CVAR_ARCHIVE, CVART_FLOAT, "0.125", "8.0", help_r_noiseScale },
{ &r_lodCurveError, "r_lodCurveError", "2000", CVAR_ARCHIVE, CVART_FLOAT, "250", "10000", "curved surfaces LOD scale" },
//
@ -577,17 +421,16 @@ static const cvarTableItem_t r_cvars[] =
{ &r_uiFullScreen, "r_uifullscreen", "0", CVAR_TEMP },
{ &r_showImages, "r_showImages", "0", CVAR_TEMP },
{ &r_debugLight, "r_debuglight", "0", CVAR_TEMP },
{ &r_debugSort, "r_debugSort", "0", CVAR_CHEAT },
{ &r_debugSort, "r_debugSort", "0", CVAR_CHEAT, CVART_FLOAT },
{ &r_nocurves, "r_nocurves", "0", CVAR_CHEAT },
{ &r_drawworld, "r_drawworld", "1", CVAR_CHEAT },
{ &r_portalOnly, "r_portalOnly", "0", CVAR_CHEAT },
{ &r_measureOverdraw, "r_measureOverdraw", "0", CVAR_CHEAT },
{ &r_lodscale, "r_lodscale", "5", CVAR_CHEAT },
{ &r_norefresh, "r_norefresh", "0", CVAR_CHEAT },
{ &r_drawentities, "r_drawentities", "1", CVAR_CHEAT },
{ &r_nocull, "r_nocull", "0", CVAR_CHEAT },
{ &r_novis, "r_novis", "0", CVAR_CHEAT },
{ &r_speeds, "r_speeds", "0", CVAR_CHEAT },
{ &r_speeds, "r_speeds", "0", CVAR_CHEAT, CVART_BOOL, NULL, NULL, "draw rendering performance counters" },
{ &r_verbose, "r_verbose", "0", CVAR_CHEAT },
{ &r_debugSurface, "r_debugSurface", "0", CVAR_CHEAT },
{ &r_nobind, "r_nobind", "0", CVAR_CHEAT },
@ -608,6 +451,94 @@ static void R_Register()
}
static void R_InitGAL()
{
struct gal_t {
getGALInterface_t grabInterface;
const char* cvarValue;
const char* fullName;
};
// preferred option goes first
const gal_t galArray[] = {
#if defined( _WIN32 )
{ &GAL_GetD3D11, "D3D11", "Direct3D 11" },
#endif
{ &GAL_GetGL3, "GL3", "OpenGL 3" },
{ &GAL_GetGL2, "GL2", "OpenGL 2" }
};
int galIndex = -1;
for ( int i = 0; i < ARRAY_LEN( galArray ); ++i ) {
if ( !Q_stricmp( r_backend->string, galArray[i].cvarValue ) ) {
galIndex = i;
break;
}
}
if ( galIndex < 0 ) {
galIndex = 0;
ri.Printf( PRINT_WARNING, "Invalid r_backend value, selecting the %s back-end instead\n", galArray[galIndex].fullName );
ri.Cvar_Set( r_backend->name, galArray[galIndex].cvarValue );
}
ri.Printf( PRINT_ALL, "Initializing the %s back-end...\n", galArray[galIndex].fullName );
#if defined( _DEBUG )
// helps catch unset function pointers
memset( &gal, 0, sizeof( gal ) );
#endif
if ( !galArray[galIndex].grabInterface( &gal ) )
ri.Error( ERR_FATAL, "Failed to grab the %s back-end's interface\n", galArray[galIndex].fullName );
if ( !gal.Init() )
ri.Error( ERR_FATAL, "Failed to initialize the %s back-end\n", galArray[galIndex].fullName );
GfxInfo_f();
}
static void R_InitMipFilter()
{
struct filter_t {
const char* cvarName;
const char* fullName;
float kernel[4];
};
// preferred option goes first
const filter_t filterArray[] = {
{ "L4", "Lanczos 4", -0.0491683967f, -0.0816986337f, 0.151636884f, 0.479230106f },
{ "L3", "Lanczos 3", 0.0f, -0.0646646321f, 0.131493837f, 0.433170795f },
{ "BL", "Bi-linear", 0.0f, 0.0f, 0.0f, 0.5f },
{ "MN2", "Mitchell-Netravali 2 (B = 1/3, C = 1/3)", 0.0f, 0.0f, 0.123327762f, 0.376672268f },
{ "BH4", "3-term Blackman-Harris 4", 0.00106591149f, 0.0288433302f, 0.151539952f, 0.318550885f },
{ "BH3", "3-term Blackman-Harris 3", 0.0f, 0.00302829780f, 0.101031370f, 0.395940334f },
{ "BH2", "3-term Blackman-Harris 2", 0.0f, 0.0f, 0.0151469158f, 0.484853119f },
{ "T2", "Tent 2 (1/3 2/3)", 0.0f, 0.0f, 1.0f / 6.0f, 2.0f / 6.0f },
// The results are so similar to Lanczos...
//{ "K4", "Kaiser 4", -0.0487834960f, -0.0811581835f, 0.151146635f, 0.478795081f },
//{ "K3", "Kaiser 3", 0.0f, -0.0642274171f, 0.131010026f, 0.433217406f }
};
int index = -1;
for ( int i = 0; i < ARRAY_LEN( filterArray ); ++i ) {
if ( !Q_stricmp( r_mipGenFilter->string, filterArray[i].cvarName ) ) {
index = i;
break;
}
}
if ( index < 0 ) {
index = 0;
ri.Printf( PRINT_WARNING, "Invalid %s value, selecting the %s filter instead\n", r_mipGenFilter->name, filterArray[index].fullName );
}
memcpy( tr.mipFilter, filterArray[index].kernel, sizeof( tr.mipFilter ) );
}
void R_Init()
{
COMPILE_TIME_ASSERT( sizeof(glconfig_t) == 11332 );
@ -656,7 +587,9 @@ void R_Init()
R_ClearFrame();
InitOpenGL();
R_InitMipFilter();
R_InitGAL();
R_InitImages();
@ -666,29 +599,31 @@ void R_Init()
R_ModelInit();
int err = qglGetError();
if (err != GL_NO_ERROR)
ri.Printf( PRINT_ALL, "glGetError() = 0x%x\n", err );
QSUBSYSTEM_INIT_DONE( "Renderer" );
}
static void RE_Shutdown( qbool destroyWindow )
{
ri.Printf( PRINT_DEVELOPER, "RE_Shutdown( %i )\n", destroyWindow );
ri.Printf( PRINT_DEVELOPER, "RE_Shutdown( %i )", destroyWindow );
// This will also force the creation of a new context when switching
// between GL2 and GL3, which is what we want because
// the implementations have their own resources we can't keep around.
if ( !destroyWindow && r_backend->latchedString )
destroyWindow = qtrue;
ri.Printf( PRINT_DEVELOPER, " -> %i\n", destroyWindow );
if ( tr.registered ) {
ri.Cmd_UnregisterModule();
R_SyncRenderThread();
R_DeleteTextures();
gal.ShutDown( destroyWindow );
}
// shut down platform specific OpenGL stuff
// shut down platform-specific video stuff
if ( destroyWindow ) {
Sys_GL_Shutdown();
Sys_V_Shutdown();
memset( &glConfig, 0, sizeof( glConfig ) );
memset( &glState, 0, sizeof( glState ) );
}
tr.registered = qfalse;
@ -701,8 +636,6 @@ static void RE_BeginRegistration( glconfig_t* glconfigOut )
*glconfigOut = glConfig;
R_SyncRenderThread();
tr.viewCluster = -1; // force markleafs to regenerate
RE_ClearScene();
@ -710,14 +643,8 @@ static void RE_BeginRegistration( glconfig_t* glconfigOut )
}
// touch all images to make sure they are resident
static void RE_EndRegistration()
{
R_SyncRenderThread();
if (!Sys_LowPhysicalMemory()) {
RB_ShowImages();
}
}
@ -727,20 +654,29 @@ static int RE_GetCameraMatrixTime()
}
static void RE_SetMaxFPS( int maxFPS )
static void RE_StretchRaw( int x, int y, int w, int h, int cols, int rows, const byte *data, int client, qbool dirty )
{
if (maxFPS > 0 && tr.maxFPS == 0) {
tr.maxFPS = maxFPS;
tr.nextFrameTimeMS = Sys_Milliseconds() + 1000 / maxFPS;
tr.oldSwapInterval = r_swapInterval->integer;
ri.Cvar_Set(r_swapInterval->name, "0");
} else if (maxFPS == 0 && tr.maxFPS > 0) {
tr.maxFPS = 0;
ri.Cvar_Set(r_swapInterval->name, va("%i", tr.oldSwapInterval));
} else if (maxFPS > 0 && tr.maxFPS > 0) {
tr.maxFPS = maxFPS;
tr.nextFrameTimeMS = Sys_Milliseconds() + 1000 / maxFPS;
}
if ( !tr.registered )
return;
gal.UpdateScratch( tr.scratchImage[client], cols, rows, data, dirty );
tr.scratchShader->stages[0]->bundle.image[0] = tr.scratchImage[client];
RE_StretchPic( x, y, w, h, 0.5f / cols, 0.5f / rows, (cols - 0.5f) / cols, (rows - 0.5f) / rows, (qhandle_t)tr.scratchShader->index );
}
static qbool RE_Registered()
{
return tr.registered;
}
static qbool RE_IsFrameSleepNeeded()
{
if ( r_frameSleep->integer != 2 )
return r_frameSleep->integer;
return !Sys_V_IsVSynced();
}
@ -783,7 +719,6 @@ const refexport_t* GetRefAPI( const refimport_t* rimp )
re.DrawStretchPic = RE_StretchPic;
re.DrawTriangle = RE_DrawTriangle;
re.DrawStretchRaw = RE_StretchRaw;
re.UploadCinematic = RE_UploadCinematic;
re.GetEntityToken = R_GetEntityToken;
re.inPVS = R_inPVS;
@ -792,7 +727,9 @@ const refexport_t* GetRefAPI( const refimport_t* rimp )
re.GetCameraMatrixTime = RE_GetCameraMatrixTime;
re.SetMaxFPS = RE_SetMaxFPS;
re.Registered = RE_Registered;
re.ShouldSleep = RE_IsFrameSleepNeeded;
return &re;
}

View file

@ -28,10 +28,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#include "../qcommon/qfiles.h"
#include "../qcommon/qcommon.h"
#include "tr_public.h"
#include "qgl.h"
#define GL_INDEX_TYPE GL_UNSIGNED_INT
typedef unsigned int glIndex_t;
extern const float s_flipMatrix[16];
@ -80,15 +77,31 @@ struct orientationr_t {
};
enum textureFormat_t {
TF_RGBA8,
TF_COUNT
};
enum textureWrap_t {
TW_REPEAT,
TW_CLAMP_TO_EDGE,
TW_COUNT
};
typedef unsigned int textureHandle_t; // what this number actually means is up to the GAL
struct image_t {
image_t* next;
int width, height; // actual, ie after power of two, picmip, and clamp to MAX_TEXTURE_SIZE
int flags; // IMG_ bits
GLuint texnum; // gl texture binding
GLenum format;
int wrapClampMode; // GL_CLAMP|GL_CLAMP_TO_EDGE or GL_REPEAT
textureHandle_t texnum; // GAL handle (never use directly)
textureFormat_t format;
textureWrap_t wrapClampMode;
char name[MAX_QPATH]; // game path, including extension
};
@ -276,6 +289,14 @@ typedef enum {
ST_MAX
} stageType_t;
typedef enum {
TE_DISABLED,
TE_MODULATE,
TE_REPLACE,
TE_DECAL,
TE_ADD
} texEnv_t;
typedef struct {
qbool active;
@ -303,7 +324,7 @@ typedef struct {
stageType_t type;
int mtStages; // number of subsequent stages also consumed by this stage (e.g. 1 for DxLM MT)
GLint mtEnv;
texEnv_t mtEnv;
} shaderStage_t;
@ -314,7 +335,8 @@ typedef struct {
typedef enum {
CT_FRONT_SIDED,
CT_BACK_SIDED,
CT_TWO_SIDED
CT_TWO_SIDED,
CT_COUNT
} cullType_t;
typedef enum {
@ -333,6 +355,12 @@ typedef struct {
float depthForOpaque;
} fogParms_t;
typedef enum {
SST_NONE, // disabled
SST_BLEND, // blend pass -> modulate alpha
SST_ADDITIVE // additive pass -> modulate color
} softSpriteType_t;
struct shader_t {
char name[MAX_QPATH]; // game path, including extension
@ -365,11 +393,6 @@ struct shader_t {
int imgflags; // nopicmip, nomipmaps, etc
qbool needsNormal; // not all shaders will need all data to be gathered
qbool needsST1;
qbool needsST2;
qbool needsColor;
int numDeforms;
deformStage_t deforms[MAX_SHADER_DEFORMS];
@ -379,8 +402,6 @@ struct shader_t {
fogPass_t fogPass; // draw a blended pass, possibly with depth test equals
void (*siFunc)();
double clampTime; // time this shader is clamped to
double timeOffset; // current time offset for this shader
@ -388,6 +409,10 @@ struct shader_t {
vec2_t lmScale;
vec2_t lmBias;
softSpriteType_t softSprite;
float softSpriteDistance;
float softSpriteOffset;
shader_t* next;
};
@ -466,6 +491,8 @@ typedef enum {
struct drawSurf_t {
unsigned sort; // bit combination for fast compares
float depth; // for sorting transparent surfaces
int index; // for sorting transparent surfaces
const surfaceType_t* surface; // any of surface*_t
};
@ -754,32 +781,25 @@ compared quickly during the qsorting process
the bits are allocated as follows:
17-31 : sorted shader index
7-16 : entity index
2-6 : fog index
1-0 : unused
18-31 : sorted shader index (14 bits)
16-17 : cull type (2 bits)
15-15 : polygon offset (1 bit)
5-14 : entity index (10 bits)
0- 4 : fog index (5 bits)
*/
#define QSORT_SHADERNUM_SHIFT 17
#define QSORT_ENTITYNUM_SHIFT 7
#define QSORT_FOGNUM_SHIFT 2
#define QSORT_SHADERNUM_SHIFT 18
#define QSORT_CULLTYPE_SHIFT 16
#define QSORT_POLYOFF_SHIFT 15
#define QSORT_ENTITYNUM_SHIFT 5
#define QSORT_FOGNUM_SHIFT 0
#define QSORT_ENTITYNUM_MASK 0x0001FF80
#define QSORT_ENTITYNUM_MASK 0x00007FE0
#define MAX_SHADERS 16384 // 1 << (32 - QSORT_SHADERNUM_SHIFT)
#define MAX_SHADERS 16384 // 14 bits, must match the length in the sort key above
#define MAX_TMUS 4
// the renderer front end should never modify glstate_t
typedef struct {
int currenttmu;
int texID[MAX_TMUS];
int texEnv[MAX_TMUS];
qbool finishCalled;
int faceCulling;
unsigned glStateBits;
} glstate_t;
// all state modified by the back end is separated from the front end state
@ -832,9 +852,10 @@ typedef struct {
image_t* defaultImage;
image_t* whiteImage; // { 255, 255, 255, 255 }
image_t* fogImage;
image_t* scratchImage[16];
image_t* scratchImage[16]; // MAX_VIDEO_HANDLES
shader_t* defaultShader;
shader_t* scratchShader; // used for cinematic playback
int numLightmaps;
image_t *lightmaps[MAX_LIGHTMAPS];
@ -886,15 +907,11 @@ typedef struct {
float inverseSawToothTable[FUNCTABLE_SIZE];
float fogTable[FOG_TABLE_SIZE];
// back-end frame-rate limiting, useful for scenarios like CGAME_INIT
int maxFPS; // only active if > 0
int nextFrameTimeMS;
int oldSwapInterval;
float mipFilter[4]; // only used by the GPU generators
} trGlobals_t;
extern backEndState_t backEnd;
extern trGlobals_t tr;
extern glstate_t glState; // outside of TR since it shouldn't be cleared during ref re-init
//
@ -913,9 +930,23 @@ extern glstate_t glState; // outside of TR since it shouldn't be cleared during
#define BLITMODE_STRETCHED 2 // dumb stretch, takes the full screen
#define BLITMODE_MAX 2
extern cvar_t *r_verbose; // used for verbose debug spew
// r_gl3_geoStream
#define GL3MAP_AUTO 0
#define GL3MAP_SUBDATA 1
#define GL3MAP_MAPUNSYNC 2
#define GL3MAP_MAPPERS 3
#define GL3MAP_AMDPIN 4
#define GL3MAP_MAX 4
extern cvar_t *r_measureOverdraw; // enables stencil buffer overdraw measurement
// r_d3d11_syncOffsets
#define D3D11SO_SPLITOFFSETS 0
#define D3D11SO_SYNCEDOFFSETS 1
#define D3D11SO_AUTO 2
#define D3D11SO_MAX 2
extern cvar_t *r_backend;
extern cvar_t *r_verbose; // used for verbose debug spew
extern cvar_t *r_lodbias; // push/pull LOD transitions
extern cvar_t *r_lodscale;
@ -941,9 +972,19 @@ extern cvar_t *r_displayRefresh; // optional display refresh option
extern cvar_t *r_intensity;
extern cvar_t *r_gamma;
extern cvar_t *r_greyscale;
extern cvar_t *r_noiseScale; // the strength of the dithering noise
extern cvar_t *r_lightmap; // render lightmaps only
extern cvar_t *r_fullbright; // avoid lightmap pass
extern cvar_t *r_softSprites; // draws certain surfaces as depth particles
extern cvar_t *r_gpuMipGen; // uses GPU-side mip-map generation
extern cvar_t *r_alphaToCoverage; // enables A2C on alpha-tested surfaces
extern cvar_t *r_dither; // enables dithering
extern cvar_t *r_mipGenFilter; // if the string is invalid, Lanczos 4 is used
extern cvar_t *r_mipGenGamma; // what gamma-space do we consider the textures to be in
extern cvar_t *r_gl3_geoStream; // vertex/index streaming strategy
extern cvar_t *r_d3d11_syncOffsets; // vertex attribute streaming strategy
extern cvar_t *r_d3d11_maxQueuedFrames; // max. pre-rendered frames
extern cvar_t *r_ext_max_anisotropy;
extern cvar_t *r_msaa;
@ -955,7 +996,6 @@ extern cvar_t *r_picmip; // controls picmip values
extern cvar_t *r_finish;
extern cvar_t *r_swapInterval;
extern cvar_t *r_textureMode;
extern cvar_t *r_vertexLight; // vertex lighting mode for better performance
extern cvar_t *r_uiFullScreen; // ui is running fullscreen
@ -1008,17 +1048,9 @@ int R_CullLocalPointAndRadius( const vec3_t origin, float radius );
void R_RotateForEntity( const trRefEntity_t* ent, const viewParms_t* viewParms, orientationr_t* orient );
/*
** GL wrapper/helper functions
*/
void GL_Bind( const image_t* image );
void GL_SelectTexture( int unit );
void GL_TextureMode( const char *string );
void GL_CheckErrors();
void GL_State( unsigned long stateVector );
void GL_TexEnv( int env );
void GL_Cull( int cullType );
void GL_Program();
typedef void (*updateAnimatedImage_t)( image_t* image, int w, int h, const byte* data, qbool dirty );
const image_t* R_UpdateAndGetBundleImage( const textureBundle_t* bundle, updateAnimatedImage_t updateImage );
#define GLS_SRCBLEND_ZERO 0x00000001
#define GLS_SRCBLEND_ONE 0x00000002
@ -1041,11 +1073,11 @@ void GL_Program();
#define GLS_DSTBLEND_ONE_MINUS_DST_ALPHA 0x00000080
#define GLS_DSTBLEND_BITS 0x000000f0
#define GLS_DEPTHMASK_TRUE 0x00000100
#define GLS_DEPTHMASK_TRUE 0x00000100 // enable depth writes
#define GLS_POLYMODE_LINE 0x00001000
#define GLS_POLYMODE_LINE 0x00001000 // wireframe polygon filling, not line rendering
#define GLS_DEPTHTEST_DISABLE 0x00010000
#define GLS_DEPTHTEST_DISABLE 0x00010000 // disable depth tests
#define GLS_DEPTHFUNC_EQUAL 0x00020000
#define GLS_ATEST_GT_0 0x10000000
@ -1054,9 +1086,7 @@ void GL_Program();
#define GLS_ATEST_BITS 0x70000000
#define GLS_DEFAULT GLS_DEPTHMASK_TRUE
void RE_StretchRaw (int x, int y, int w, int h, int cols, int rows, const byte *data, int client, qbool dirty);
void RE_UploadCinematic (int w, int h, int cols, int rows, const byte *data, int client, qbool dirty);
#define GLS_DEFAULT_2D (GLS_DEPTHTEST_DISABLE | GLS_SRCBLEND_SRC_ALPHA | GLS_DSTBLEND_ONE_MINUS_SRC_ALPHA)
void RE_LoadWorldMap( const char *mapname );
void RE_SetWorldVisData( const byte *vis );
@ -1065,6 +1095,8 @@ qhandle_t RE_RegisterSkin( const char *name );
const char* R_GetMapName();
void R_ColorShiftLightingBytes( const byte in[4], byte out[4] );
qbool R_GetEntityToken( char *buffer, int size );
model_t* R_AllocModel();
@ -1072,13 +1104,15 @@ model_t* R_AllocModel();
void R_Init();
void R_ConfigureVideoMode( int desktopWidth, int desktopHeight ); // writes to glConfig and glInfo
#define IMG_NOPICMIP 0x0001 // images that must never be downsampled
#define IMG_NOMIPMAP 0x0002 // 2D elements that will never be "distant" - implies IMG_NOPICMIP
#define IMG_NOIMANIP 0x0004 // used for math by shaders (normal maps etc) so don't imageprocess them
#define IMG_LMATLAS 0x0008 // lightmap atlas => RGBA, no initial data, no mip-mapping, no anisotropic, upload with R_UploadLightmapTile
#define IMG_NOPICMIP 0x0001 // images that must never be down-sampled
#define IMG_NOMIPMAP 0x0002 // 2D elements that will never be "distant" - implies IMG_NOPICMIP
#define IMG_NOIMANIP 0x0004 // used for math by shaders (normal maps etc) so don't image-process them
#define IMG_LMATLAS 0x0008 // lightmap atlas => RGBA, no initial data, no mip-mapping, no anisotropic, upload with R_UploadLightmapTile
#define IMG_EXTLMATLAS 0x0010 // external lightmap atlas => no mip-mapping, no anisotropic
#define IMG_NOAF 0x0020 // never enable anisotropic filtering
const image_t* R_FindImageFile( const char* name, int flags, int glWrapClampMode );
image_t* R_CreateImage( const char* name, byte* pic, int width, int height, GLenum format, int flags, int wrapClampMode );
const image_t* R_FindImageFile( const char* name, int flags, textureWrap_t glWrapClampMode );
image_t* R_CreateImage( const char* name, byte* pic, int width, int height, textureFormat_t format, int flags, textureWrap_t wrapClampMode );
void R_UploadLightmapTile( image_t* image, byte* pic, int x, int y, int width, int height );
void R_SetColorMappings();
@ -1095,6 +1129,8 @@ const skin_t* R_GetSkinByHandle( qhandle_t hSkin );
const void *RB_TakeVideoFrameCmd( const void *data );
extern const vec4_t r_mipBlendColors[16];
//
// tr_shader.c
//
@ -1115,22 +1151,34 @@ IMPLEMENTATION SPECIFIC FUNCTIONS
====================================================================
*/
// OpenGL initialization:
// - loading OpenGL and getting core function pointers
enum galId_t {
GAL_GL2,
GAL_GL3,
GAL_D3D11,
GAL_COUNT
};
// Video initialization:
// o loading OpenGL and getting core function pointers
// - creating a window and changing video mode if needed,
// respecting r_fullscreen, r_mode, r_width, r_height
// - creating a valid OpenGL context and making it current
// - respecting r_fullscreen, r_mode, r_width, r_height
// o creating a valid OpenGL context and making it current
// - filling up the right glconfig fields (see glconfig_t definition)
void Sys_GL_Init();
void Sys_V_Init( galId_t type );
// OpenGL shutdown:
// - unloading OpenGL and zeroing the core function pointers
// - destroying the GL context, window and other associated resources
// Video shutdown:
// o unloading OpenGL and zeroing the core function pointers
// o destroying the OpenGL context
// - destroying the window
// - resetting the proper video mode if necessary
void Sys_GL_Shutdown();
void Sys_V_Shutdown();
// Swaps buffers and applies r_swapInterval.
void Sys_GL_EndFrame();
// Swaps buffers and applies r_swapInterval if the back-end can't already do it.
void Sys_V_EndFrame();
// Used to know if we must sleep ourselves to maintain the frame-rate cap.
// When unsure (e.g. API calls failed), return qfalse.
qbool Sys_V_IsVSynced();
/*
@ -1146,33 +1194,47 @@ struct stageVars_t
{
color4ub_t colors[SHADER_MAX_VERTEXES];
vec2_t texcoords[SHADER_MAX_VERTEXES];
vec2_t* texcoordsptr;
};
struct shaderCommands_t
{
ALIGN(16) glIndex_t indexes[SHADER_MAX_INDEXES];
vec4_t xyz[SHADER_MAX_VERTEXES];
vec4_t normal[SHADER_MAX_VERTEXES];
vec2_t texCoords[SHADER_MAX_VERTEXES][2];
color4ub_t vertexColors[SHADER_MAX_VERTEXES];
unsigned int indexes[SHADER_MAX_INDEXES];
vec4_t xyz[SHADER_MAX_VERTEXES];
vec4_t normal[SHADER_MAX_VERTEXES];
vec2_t texCoords[SHADER_MAX_VERTEXES];
vec2_t texCoords2[SHADER_MAX_VERTEXES];
color4ub_t vertexColors[SHADER_MAX_VERTEXES];
unsigned int dlIndexes[SHADER_MAX_INDEXES];
stageVars_t svars[MAX_SHADER_STAGES];
stageVars_t svarsFog;
enum { TP_BASE, TP_LIGHT } pass;
stageVars_t svars;
const shader_t* shader;
double shaderTime;
int fogNum;
int numIndexes;
int numVertexes;
int dlNumIndexes;
const dlight_t* light;
// info extracted from current shader
void (*siFunc)();
const shaderStage_t** xstages;
// when > 0, only soft sprites are allowed in this batch
softSpriteType_t softSprite;
// when qtrue, RB_EndSurface doesn't need to compute deforms, colors, texture coordinates
qbool deformsPreApplied;
// when qtrue, draw a fog pass using fogStateBits and svarsFog
qbool drawFog;
// use this state vector when drawing the fog pass
unsigned int fogStateBits;
};
extern shaderCommands_t tess;
@ -1182,18 +1244,12 @@ void RB_EndSurface();
void RB_CheckOverflow( int verts, int indexes );
#define RB_CHECKOVERFLOW(v,i) if (tess.numVertexes + (v) >= SHADER_MAX_VERTEXES || tess.numIndexes + (i) >= SHADER_MAX_INDEXES ) {RB_CheckOverflow(v,i);}
void R_ComputeColors( const shaderStage_t* pStage, stageVars_t& svars );
void R_ComputeTexCoords( const shaderStage_t* pStage, stageVars_t& svars );
void R_BindAnimatedImage( const textureBundle_t* bundle );
void RB_FogPass();
void RB_StageIteratorSky();
void R_ComputeColors( const shaderStage_t* pStage, stageVars_t& svars, int firstVertex, int numVertexes );
void R_ComputeTexCoords( const shaderStage_t* pStage, stageVars_t& svars, int firstVertex, int numVertexes, qbool ptrOpt );
void RB_AddQuadStamp( vec3_t origin, vec3_t left, vec3_t up, byte *color );
void RB_AddQuadStampExt( vec3_t origin, vec3_t left, vec3_t up, byte *color, float s1, float t1, float s2, float t2 );
void RB_ShowImages();
/*
============================================================
@ -1290,37 +1346,10 @@ void R_TransformModelToClip( const vec3_t src, const float *modelMatrix, const f
vec4_t eye, vec4_t dst );
void R_TransformClipToWindow( const vec4_t clip, const viewParms_t *view, vec4_t normalized, vec4_t window );
void RB_DeformTessGeometry();
void RB_DeformTessGeometry( int firstVertex, int numVertexes, int firstIndex, int numIndexes );
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_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 );
void RB_CalcWaveColor( const waveForm_t *wf, unsigned char *dstColors );
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 );
void RB_CalcFogTexCoords( float *st, int firstVertex, int numVertexes );
/*
=============================================================
RENDERER BACK END FUNCTIONS
=============================================================
*/
void RB_ExecuteRenderCommands( const void *data );
/*
=============================================================
@ -1388,6 +1417,7 @@ typedef struct {
trRefdef_t refdef;
viewParms_t viewParms;
int numDrawSurfs;
int numTranspSurfs;
drawSurf_t* drawSurfs;
} drawSurfsCommand_t;
@ -1443,20 +1473,95 @@ typedef struct {
renderCommandList_t commands;
} backEndData_t;
#define SKY_SUBDIVISIONS 8
#define HALF_SKY_SUBDIVISIONS (SKY_SUBDIVISIONS/2)
typedef enum {
CS_RGBA,
CS_BGR,
CS_COUNT
} colorSpace_t;
typedef enum {
DT_GENERIC,
DT_DYNAMIC_LIGHT,
DT_SOFT_SPRITE
} drawType_t;
typedef struct {
qbool (*Init)();
void (*ShutDown)( qbool fullShutDown );
void (*BeginFrame)();
void (*EndFrame)();
// saves the current clip plane and disables it
// sets depth range to [1; 1]
// disables alpha blending, alpha testing, face culling and polygon offset
void (*BeginSkyAndClouds)();
// sets depth range to [0; 1]
// restores the old clip plane, if any
void (*EndSkyAndClouds)();
void (*ReadPixels)( int x, int y, int w, int h, int alignment, colorSpace_t colorSpace, void* out );
void (*CreateTexture)( image_t* image, int mipCount, int w, int h );
void (*UpdateTexture)( image_t* image, int mip, int x, int y, int w, int h, const void* data );
void (*UpdateScratch)( image_t* image, int w, int h, const void* data, qbool dirty );
// handles everything in one go, including mip-map generation
// - image->format must be TF_RGBA8
// - w and h must be powers of 2
void (*CreateTextureEx)( image_t* image, int mipCount, int mipOffset, int w0, int h0, const void* mip0 );
void (*Draw)( drawType_t type );
// sets the model-view matrix (identity)
// sets the projection matrix (orthographic transform)
// sets the viewport and scissor rectangles
void (*Begin2D)();
// clears the target buffers
// sets the projection matrix
// sets the viewport and scissor rectangles
// sets the clip plane
void (*Begin3D)();
void (*SetModelViewMatrix)( const float* matrix );
void (*SetDepthRange)( double near, double far );
// lets us know that tess.light is ready and the data should be copied over now
void (*BeginDynamicLight)();
void (*PrintInfo)();
} graphicsAPILayer_t;
extern int max_polys;
extern int max_polyverts;
extern backEndData_t *backEndData;
extern backEndData_t* backEndData;
extern graphicsAPILayer_t gal;
void GfxInfo_f( void );
typedef qbool ( *getGALInterface_t )( graphicsAPILayer_t* );
qbool GAL_GetGL2( graphicsAPILayer_t* rb );
qbool GAL_GetGL3( graphicsAPILayer_t* rb );
qbool GAL_GetD3D11( graphicsAPILayer_t* rb );
void *R_GetCommandBuffer( int bytes );
void RB_ExecuteRenderCommands( const void *data );
void* RB_FindRenderCommand( renderCommand_t type );
void RB_RemoveRenderCommand( void* cmd, int cmdSize );
void RB_PushSingleStageShader( int stateBits, cullType_t cullType );
void RB_PopShader();
void R_SyncRenderThread( void );
void RB_DrawSky();
void R_BuildCloudData();
void R_AddDrawSurfCmd( drawSurf_t* drawSurfs, int numDrawSurfs );
void R_IssueRenderCommands();
void* R_FindRenderCommand( renderCommand_t type );
void *R_GetCommandBuffer( int bytes );
void R_AddDrawSurfCmd(drawSurf_t* drawSurfs, int numDrawSurfs, int numTranspSurfs );
void RE_BeginFrame( stereoFrame_t stereoFrame );
void RE_EndFrame( int* pcFE, int* pc2D, int* pc3D, qbool render );
@ -1470,6 +1575,10 @@ int SaveJPGToBuffer( byte* out, int quality, int image_width, int image_height,
void RE_TakeVideoFrame( int width, int height,
byte *captureBuffer, byte *encodeBuffer, qbool motionJpeg );
void R_MultMatrix( const float *a, const float *b, float *out );
void R_MakeIdentityMatrix( float* m );
void R_MakeOrthoProjectionMatrix( float* m, float w, float h );
///////////////////////////////////////////////////////////////
@ -1486,10 +1595,11 @@ struct glinfo_t {
int winWidth, winHeight;
// used by renderer
GLint maxTextureSize;
GLint maxDrawElementsI;
GLint maxDrawElementsV;
GLint maxAnisotropy;
int maxTextureSize;
int maxAnisotropy;
qbool softSpriteSupport;
qbool mipGenSupport;
qbool alphaToCoverageSupport;
};
extern glinfo_t glInfo;
@ -1513,14 +1623,6 @@ private:
};
// tr_gl2.cpp
qbool GL2_Init();
void GL2_SetupDynLight();
void GL2_StageIterator();
void GL2_BeginFrame();
void GL2_EndFrame();
extern int re_cameraMatrixTime;
extern screenshotCommand_t r_delayedScreenshot;

View file

@ -30,7 +30,7 @@ refimport_t ri;
const float s_flipMatrix[16] = {
// convert from our coordinate system (looking down X)
// to OpenGL's coordinate system (looking down -Z)
// to the back-end's coordinate system (looking down -Z)
0, 0, -1, 0,
-1, 0, 0, 0,
0, 1, 0, 0,
@ -202,22 +202,68 @@ void R_TransformClipToWindow( const vec4_t clip, const viewParms_t *view, vec4_t
}
static void myGlMultMatrix( const float *a, const float *b, float *out )
void R_MultMatrix( const float *a, const float *b, float *out )
{
int i, j;
for ( i = 0 ; i < 4 ; i++ ) {
for ( j = 0 ; j < 4 ; j++ ) {
for ( int i = 0 ; i < 4 ; i++ ) {
for ( int j = 0 ; j < 4 ; j++ ) {
out[ i * 4 + j ] =
a [ i * 4 + 0 ] * b [ 0 * 4 + j ]
+ a [ i * 4 + 1 ] * b [ 1 * 4 + j ]
+ a [ i * 4 + 2 ] * b [ 2 * 4 + j ]
+ a [ i * 4 + 3 ] * b [ 3 * 4 + j ];
a [ i * 4 + 0 ] * b [ 0 * 4 + j ] +
a [ i * 4 + 1 ] * b [ 1 * 4 + j ] +
a [ i * 4 + 2 ] * b [ 2 * 4 + j ] +
a [ i * 4 + 3 ] * b [ 3 * 4 + j ];
}
}
}
void R_MakeIdentityMatrix( float* m )
{
m[ 0] = 1.0f;
m[ 1] = 0.0f;
m[ 2] = 0.0f;
m[ 3] = 0.0f;
m[ 4] = 0.0f;
m[ 5] = 1.0f;
m[ 6] = 0.0f;
m[ 7] = 0.0f;
m[ 8] = 0.0f;
m[ 9] = 0.0f;
m[10] = 1.0f;
m[11] = 0.0f;
m[12] = 0.0f;
m[13] = 0.0f;
m[14] = 0.0f;
m[15] = 1.0f;
}
void R_MakeOrthoProjectionMatrix( float* m, float w, float h )
{
// 2/(r-l) 0 0 0
// 0 2/(t-b) 0 0
// 0 0 1/(zf-zn) 0
// (l+r)/(l-r) (t+b)/(b-t) zn/(zn-zf) 1
const float n = 0.0f;
const float f = 2.0f;
m[ 0] = 2.0f / w;
m[ 4] = 0.0f;
m[ 8] = 0.0f;
m[12] = -1.0f;
m[ 1] = 0.0f;
m[ 5] = -2.0f / h;
m[ 9] = 0.0f;
m[13] = 1.0f;
m[ 2] = 0.0f;
m[ 6] = 0.0f;
m[10] = 1.0f / (f - n);
m[14] = 0.0f;
m[ 3] = 0.0f;
m[ 7] = 0.0f;
m[11] = n / (n - f);
m[15] = 1.0f;
}
/*
=================
R_RotateForEntity
@ -264,7 +310,7 @@ void R_RotateForEntity( const trRefEntity_t* ent, const viewParms_t* viewParms,
glMatrix[11] = 0;
glMatrix[15] = 1;
myGlMultMatrix( glMatrix, viewParms->world.modelMatrix, orient->modelMatrix );
R_MultMatrix( glMatrix, viewParms->world.modelMatrix, orient->modelMatrix );
// calculate the viewer origin in the model's space
// needed for fog, specular, and environment mapping
@ -325,8 +371,8 @@ static void R_RotateForViewer()
viewerMatrix[15] = 1;
// convert from our coordinate system (looking down X)
// to OpenGL's coordinate system (looking down -Z)
myGlMultMatrix( viewerMatrix, s_flipMatrix, tr.orient.modelMatrix );
// to the back-end's coordinate system (looking down -Z)
R_MultMatrix( viewerMatrix, s_flipMatrix, tr.orient.modelMatrix );
tr.viewParms.world = tr.orient;
}
@ -364,7 +410,6 @@ static void SetFarClip()
static void R_SetupProjection()
{
float xmin, xmax, ymin, ymax;
float width, height, depth;
float zNear, zFar;
@ -377,24 +422,18 @@ static void R_SetupProjection()
zNear = 4.0f;
zFar = tr.viewParms.zFar;
ymax = zNear * tan( tr.refdef.fov_y * M_PI / 360.0f );
ymin = -ymax;
xmax = zNear * tan( tr.refdef.fov_x * M_PI / 360.0f );
xmin = -xmax;
width = xmax - xmin;
height = ymax - ymin;
height = 2.0f * zNear * tan( tr.refdef.fov_y * M_PI / 360.0f );
width = 2.0f * zNear * tan( tr.refdef.fov_x * M_PI / 360.0f );
depth = zFar - zNear;
tr.viewParms.projectionMatrix[0] = 2 * zNear / width;
tr.viewParms.projectionMatrix[4] = 0;
tr.viewParms.projectionMatrix[8] = ( xmax + xmin ) / width; // normally 0
tr.viewParms.projectionMatrix[8] = 0;
tr.viewParms.projectionMatrix[12] = 0;
tr.viewParms.projectionMatrix[1] = 0;
tr.viewParms.projectionMatrix[5] = 2 * zNear / height;
tr.viewParms.projectionMatrix[9] = ( ymax + ymin ) / height; // normally 0
tr.viewParms.projectionMatrix[9] = 0;
tr.viewParms.projectionMatrix[13] = 0;
tr.viewParms.projectionMatrix[2] = 0;
@ -1033,7 +1072,9 @@ void R_AddDrawSurf( const surfaceType_t* surface, const shader_t* shader, int fo
// the sort data is packed into a single 32 bit value so it can be
// compared quickly during the qsorting process
tr.refdef.drawSurfs[index].sort = (shader->sortedIndex << QSORT_SHADERNUM_SHIFT)
| tr.shiftedEntityNum | (fogIndex << QSORT_FOGNUM_SHIFT);
| tr.shiftedEntityNum | (fogIndex << QSORT_FOGNUM_SHIFT)
| (shader->cullType << QSORT_CULLTYPE_SHIFT)
| (shader->polygonOffset << QSORT_POLYOFF_SHIFT);
tr.refdef.drawSurfs[index].surface = surface;
}
@ -1046,7 +1087,9 @@ void R_AddLitSurf( const surfaceType_t* surface, const shader_t* shader, int fog
litSurf_t* litsurf = &tr.refdef.litSurfs[index];
litsurf->sort = (shader->sortedIndex << QSORT_SHADERNUM_SHIFT)
| tr.shiftedEntityNum | (fogIndex << QSORT_FOGNUM_SHIFT);
| tr.shiftedEntityNum | (fogIndex << QSORT_FOGNUM_SHIFT)
| (shader->cullType << QSORT_CULLTYPE_SHIFT)
| (shader->polygonOffset << QSORT_POLYOFF_SHIFT);
litsurf->surface = surface;
if (!tr.light->head)
@ -1067,6 +1110,46 @@ void R_DecomposeSort( unsigned sort, int *entityNum, const shader_t **shader, in
}
static float R_ComputePointDepth( const vec3_t point, const float* modelMatrix )
{
return -(
modelMatrix[2 + 0 * 4] * point[0] +
modelMatrix[2 + 1 * 4] * point[1] +
modelMatrix[2 + 2 * 4] * point[2] +
modelMatrix[2 + 3 * 4]
);
}
static float R_ComputeSurfaceDepth( const surfaceType_t* surf, int entityNum )
{
if ( *surf == SF_ENTITY ) {
const refEntity_t* ent = &tr.refdef.entities[entityNum].e;
if ( ent->reType == RT_SPRITE )
return R_ComputePointDepth( ent->origin, tr.viewParms.world.modelMatrix );
if ( ent->reType == RT_LIGHTNING )
return -999666.0f;
}
return 999666.0f;
}
static int R_CompareDrawSurfDepth( const void* aPtr, const void* bPtr )
{
const drawSurf_t* a = ( const drawSurf_t* )aPtr;
const drawSurf_t* b = ( const drawSurf_t* )bPtr;
if ( a->depth > b->depth )
return -1;
if ( a->depth < b->depth )
return 1;
return a->index - b->index;
}
static void R_SortDrawSurfs( int firstDrawSurf, int firstLitSurf )
{
int numDrawSurfs = tr.refdef.numDrawSurfs - firstDrawSurf;
@ -1080,7 +1163,7 @@ static void R_SortDrawSurfs( int firstDrawSurf, int firstLitSurf )
// it is possible for some views to not have any surfaces
if ( numDrawSurfs < 1 ) {
// we still need to add it for hyperspace cases
R_AddDrawSurfCmd( drawSurfs, 0 );
R_AddDrawSurfCmd( drawSurfs, 0, 0 );
return;
}
@ -1094,8 +1177,8 @@ static void R_SortDrawSurfs( int firstDrawSurf, int firstLitSurf )
// sort the drawsurfs by sort type, then shader, then entity, etc
R_RadixSort( drawSurfs, numDrawSurfs );
// check for any pass through drawing, which
// may cause another view to be rendered first
// check for any pass through drawing,
// which may cause another view to be rendered first
for ( i = 0 ; i < numDrawSurfs ; i++ ) {
R_DecomposeSort( (drawSurfs+i)->sort, &entityNum, &shader, &fogNum );
@ -1118,6 +1201,23 @@ static void R_SortDrawSurfs( int firstDrawSurf, int firstLitSurf )
}
}
// compute the average camera depth of all transparent surfaces
int numTranspSurfs = 0;
for ( i = numDrawSurfs - 1; i >= 0; --i ) {
R_DecomposeSort( (drawSurfs+i)->sort, &entityNum, &shader, &fogNum );
if ( shader->sort <= SS_OPAQUE ) {
numTranspSurfs = numDrawSurfs - i - 1;
break;
}
drawSurfs[i].depth = R_ComputeSurfaceDepth( drawSurfs[i].surface, entityNum );
drawSurfs[i].index = i;
}
// sort transparent surfaces by depth
qsort( drawSurfs + numDrawSurfs - numTranspSurfs, numTranspSurfs, sizeof(drawSurf_t), &R_CompareDrawSurfDepth );
// all the lit surfaces are in a single queue
// but each light's surfaces are sorted within its subsection
for ( i = 0; i < tr.refdef.num_dlights; ++i ) {
@ -1127,7 +1227,7 @@ static void R_SortDrawSurfs( int firstDrawSurf, int firstLitSurf )
}
}
R_AddDrawSurfCmd( drawSurfs, numDrawSurfs );
R_AddDrawSurfCmd( drawSurfs, numDrawSurfs, numTranspSurfs );
}
@ -1223,49 +1323,6 @@ static void R_GenerateDrawSurfs()
}
static void R_DebugPolygon( int color, int numPoints, const float* points )
{
int i;
GL_State( GLS_DEPTHMASK_TRUE | GLS_SRCBLEND_ONE | GLS_DSTBLEND_ONE );
// draw solid shade
qglColor3f( color&1, (color>>1)&1, (color>>2)&1 );
qglBegin( GL_POLYGON );
for ( i = 0 ; i < numPoints ; i++ ) {
qglVertex3fv( points + i * 3 );
}
qglEnd();
// draw wireframe outline
GL_State( GLS_POLYMODE_LINE | GLS_DEPTHMASK_TRUE | GLS_SRCBLEND_ONE | GLS_DSTBLEND_ONE );
qglDepthRange( 0, 0 );
qglColor3f( 1, 1, 1 );
qglBegin( GL_POLYGON );
for ( i = 0 ; i < numPoints ; i++ ) {
qglVertex3fv( points + i * 3 );
}
qglEnd();
qglDepthRange( 0, 1 );
}
// visualization aid for movement clipping debugging
static void R_DebugGraphics()
{
if ( !r_debugSurface->integer )
return;
// the render thread can't make callbacks to the main thread
R_SyncRenderThread();
GL_Bind( tr.whiteImage);
GL_Cull( CT_FRONT_SIDED );
ri.CM_DrawDebugSurface( R_DebugPolygon );
}
int re_cameraMatrixTime;
@ -1294,8 +1351,39 @@ void R_RenderView( const viewParms_t* parms )
R_GenerateDrawSurfs();
R_SortDrawSurfs( firstDrawSurf, firstLitSurf );
// draw main system development information (surface outlines, etc)
R_DebugGraphics();
}
const image_t* R_UpdateAndGetBundleImage( const textureBundle_t* bundle, updateAnimatedImage_t updateImage )
{
if ( bundle->isVideoMap ) {
ri.CIN_RunCinematic( bundle->videoMapHandle );
int w, h, client;
const byte* data;
qbool dirty;
const qbool validData = ri.CIN_GrabCinematic( bundle->videoMapHandle, &w, &h, &data, &client, &dirty );
if ( client >= 0 && client < ARRAY_LEN( tr.scratchImage ) ) {
image_t* const image = tr.scratchImage[client];
if ( validData )
(*updateImage)(image, w, h, data, dirty);
return image;
} else {
return tr.whiteImage;
}
}
if ( bundle->numImageAnimations <= 1 )
return bundle->image[0];
// it is necessary to do this messy calc to make sure animations line up
// exactly with waveforms of the same frequency
double v = tess.shaderTime * bundle->imageAnimationSpeed * FUNCTABLE_SIZE;
long long int index = v;
index >>= FUNCTABLE_SHIFT;
if ( index < 0 ) // may happen with shader time offsets
return bundle->image[0];
return bundle->image[index % bundle->numImageAnimations];
}

View file

@ -234,10 +234,6 @@ qhandle_t RE_RegisterModel( const char* name )
Q_strncpyz( mod->name, name, sizeof( mod->name ) );
mod->numLods = 0;
// make sure the render thread is stopped
R_SyncRenderThread();
void* buf;
int lod, numLoaded = 0;

View file

@ -35,7 +35,7 @@ typedef enum {
enum {
RF_MSEC,
RF_USEC,
RF_LEAF_CLUSTER,
RF_LEAF_AREA,
RF_LEAFS,
@ -68,7 +68,9 @@ enum {
// so we maintain two sets and switch between them as projection2D changes
enum {
RB_MSEC,
RB_USEC,
RB_USEC_END, // post-process etc. + buffer swap
RB_USEC_GPU, // not always available
RB_VERTICES,
RB_INDICES,
@ -137,7 +139,6 @@ typedef struct {
// Draw images for cinematic rendering, pass as 32 bit rgba
void (*DrawStretchRaw) (int x, int y, int w, int h, int cols, int rows, const byte *data, int client, qbool dirty);
void (*UploadCinematic) (int w, int h, int cols, int rows, const byte *data, int client, qbool dirty);
void (*BeginFrame)( stereoFrame_t stereoFrame );
@ -159,10 +160,11 @@ typedef struct {
// when the final model-view matrix is computed, for cl_drawMouseLag
int (*GetCameraMatrixTime)();
// used for setting low frame-rates temporarily only (e.g. map loads)
// maxFPS > 0 -> throttles frame-rate, disables v-sync
// maxFPS = 0 -> no throttling , restores v-sync to whatever it was
void (*SetMaxFPS)( int maxFPS );
// qtrue means it should be safe to call any other function
qbool (*Registered)();
// do we need to sleep this frame to maintain the frame-rate cap?
qbool (*ShouldSleep)();
} refexport_t;
//
@ -179,8 +181,13 @@ typedef struct {
// milliseconds should only be used for profiling, never
// for anything game related. Get time from the refdef
// time scaled
int (*Milliseconds)();
// for profiling only
// not time scaled
int64_t (*Microseconds)();
// stack based memory allocation for per-level things that
// won't be freed
#ifdef HUNK_DEBUG
@ -219,9 +226,9 @@ typedef struct {
void (*FS_WriteFile)( const char *qpath, const void *buffer, int size );
// cinematic stuff
void (*CIN_UploadCinematic)(int handle);
qbool (*CIN_GrabCinematic)( int handle, int* w, int* h, const byte** data, int* client, qbool* dirty );
int (*CIN_PlayCinematic)( const char *arg0, int xpos, int ypos, int width, int height, int bits );
e_status (*CIN_RunCinematic)(int handle);
e_status (*CIN_RunCinematic)( int handle );
void (*CL_WriteAVIVideoFrame)( const byte *buffer, int size );
} refimport_t;

View file

@ -207,7 +207,7 @@ void RE_RenderScene( const refdef_t* fd )
return;
}
int startTime = ri.Milliseconds();
const int64_t startTime = ri.Microseconds();
if (!tr.world && !( fd->rdflags & RDF_NOWORLDMODEL ) ) {
ri.Error (ERR_DROP, "R_RenderScene: NULL worldmodel");
@ -311,5 +311,5 @@ void RE_RenderScene( const refdef_t* fd )
r_firstSceneDlight = r_numdlights;
r_firstScenePoly = r_numpolys;
tr.pc[RF_MSEC] += ri.Milliseconds() - startTime;
tr.pc[RF_USEC] += (int)( ri.Microseconds() - startTime );
}

View file

@ -23,96 +23,6 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#include "tr_local.h"
/*
THIS ENTIRE FILE IS BACK END
This file deals with applying shaders to surface data in the tess struct.
*/
static void ID_INLINE R_DrawElements( int numIndexes, const glIndex_t* indexes )
{
qglDrawElements( GL_TRIANGLES, numIndexes, GL_INDEX_TYPE, indexes );
}
// draw triangle outlines for debugging
static void DrawTris( const shaderCommands_t* input )
{
GL_Bind( tr.whiteImage );
qglColor3f( 1, 1, 1 );
GL_State( GLS_POLYMODE_LINE | GLS_DEPTHMASK_TRUE );
qglDepthRange( 0, 0 );
qglDisableClientState( GL_COLOR_ARRAY );
qglDisableClientState( GL_TEXTURE_COORD_ARRAY );
qglVertexPointer( 3, GL_FLOAT, 16, input->xyz ); // padded for SIMD
qglLockArraysEXT( 0, input->numVertexes );
R_DrawElements( input->numIndexes, input->indexes );
qglUnlockArraysEXT();
qglDepthRange( 0, 1 );
}
// draw vertex normals for debugging
static void DrawNormals( const shaderCommands_t* input )
{
GL_Bind( tr.whiteImage );
GL_State( GLS_POLYMODE_LINE | GLS_DEPTHMASK_TRUE );
qglDepthRange( 0, 0 );
qglColor3f( 0, 0, 1 );
qglBegin( GL_LINES );
for (int i = 0; i < input->numVertexes; ++i) {
vec3_t temp;
qglVertex3fv( input->xyz[i] );
VectorMA( input->xyz[i], 2, input->normal[i], temp );
qglVertex3fv( temp );
}
qglEnd();
qglDepthRange( 0, 1 );
}
///////////////////////////////////////////////////////////////
void R_BindAnimatedImage( const textureBundle_t* bundle )
{
if ( bundle->isVideoMap ) {
ri.CIN_RunCinematic(bundle->videoMapHandle);
ri.CIN_UploadCinematic(bundle->videoMapHandle);
return;
}
if ( bundle->numImageAnimations <= 1 ) {
GL_Bind( bundle->image[0] );
return;
}
// it is necessary to do this messy calc to make sure animations line up
// exactly with waveforms of the same frequency
double v = tess.shaderTime * bundle->imageAnimationSpeed * FUNCTABLE_SIZE;
long long int index = v; //myftol( tess.shaderTime * bundle->imageAnimationSpeed * FUNCTABLE_SIZE );
index >>= FUNCTABLE_SHIFT;
if ( index < 0 ) // may happen with shader time offsets
index = 0;
index %= bundle->numImageAnimations;
GL_Bind( bundle->image[ index ] );
}
/*
=============================================================
@ -135,7 +45,8 @@ void RB_BeginSurface( const shader_t* shader, int fogNum )
tess.shader = shader;
tess.fogNum = fogNum;
tess.xstages = (const shaderStage_t**)shader->stages;
tess.siFunc = shader->siFunc;
tess.softSprite = SST_NONE;
tess.deformsPreApplied = qfalse;
tess.shaderTime = backEnd.refdef.floatTime - tess.shader->timeOffset;
if (tess.shader->clampTime && tess.shaderTime >= tess.shader->clampTime) {
@ -144,11 +55,102 @@ void RB_BeginSurface( const shader_t* shader, int fogNum )
}
static void RB_DrawDynamicLight()
{
if (tess.shader->lightingStages[ST_DIFFUSE] == -1)
return;
backEnd.pc[RB_LIT_VERTICES_LATECULLTEST] += tess.numVertexes;
static byte clipBits[SHADER_MAX_VERTEXES];
const dlight_t* dl = tess.light;
for (int i = 0; i < tess.numVertexes; ++i) {
vec3_t dist;
VectorSubtract(dl->transformed, tess.xyz[i], dist);
if (DotProduct(dist, tess.normal[i]) <= 0.0f) {
clipBits[i] = byte(-1);
continue;
}
int clip = 0;
if (dist[0] > dl->radius)
clip |= 1;
else if (dist[0] < -dl->radius)
clip |= 2;
if (dist[1] > dl->radius)
clip |= 4;
else if (dist[1] < -dl->radius)
clip |= 8;
if (dist[2] > dl->radius)
clip |= 16;
else if (dist[2] < -dl->radius)
clip |= 32;
clipBits[i] = clip;
}
// build a list of triangles that need light
int numIndexes = 0;
for (int i = 0; i < tess.numIndexes; i += 3) {
const int a = tess.indexes[i + 0];
const int b = tess.indexes[i + 1];
const int c = tess.indexes[i + 2];
if (!(clipBits[a] & clipBits[b] & clipBits[c])) {
tess.dlIndexes[numIndexes + 0] = a;
tess.dlIndexes[numIndexes + 1] = b;
tess.dlIndexes[numIndexes + 2] = c;
numIndexes += 3;
}
}
tess.dlNumIndexes = numIndexes;
backEnd.pc[RB_LIT_INDICES_LATECULL_IN] += numIndexes;
backEnd.pc[RB_LIT_INDICES_LATECULL_OUT] += tess.numIndexes - numIndexes;
if (numIndexes <= 0)
return;
backEnd.pc[RB_LIT_BATCHES]++;
backEnd.pc[RB_LIT_VERTICES] += tess.numVertexes;
backEnd.pc[RB_LIT_INDICES] += tess.numIndexes;
gal.Draw(DT_DYNAMIC_LIGHT);
}
static void RB_DrawGeneric()
{
if (tess.softSprite == SST_NONE && tess.fogNum && tess.shader->fogPass) {
tess.drawFog = qtrue;
unsigned int fogStateBits = GLS_SRCBLEND_SRC_ALPHA | GLS_DSTBLEND_ONE_MINUS_SRC_ALPHA;
if (tess.shader->fogPass == FP_EQUAL)
fogStateBits |= GLS_DEPTHFUNC_EQUAL;
tess.fogStateBits = fogStateBits;
const fog_t* fog = tr.world->fogs + tess.fogNum;
for (int i = 0; i < tess.numVertexes; ++i) {
*(int*)&tess.svarsFog.colors[i] = fog->colorInt;
}
RB_CalcFogTexCoords((float*)tess.svarsFog.texcoords, 0, tess.numVertexes);
tess.svarsFog.texcoordsptr = tess.svarsFog.texcoords;
} else {
tess.drawFog = qfalse;
}
backEnd.pc[RB_BATCHES]++;
backEnd.pc[RB_VERTICES] += tess.numVertexes;
backEnd.pc[RB_INDICES] += tess.numIndexes;
gal.Draw(tess.softSprite != SST_NONE ? DT_SOFT_SPRITE : DT_GENERIC);
}
void RB_EndSurface()
{
shaderCommands_t* input = &tess;
if (!input->numIndexes)
if (!input->numIndexes || !input->numVertexes)
return;
if (input->indexes[SHADER_MAX_INDEXES-1] != 0) {
@ -159,334 +161,66 @@ void RB_EndSurface()
}
// for debugging of sort order issues, stop rendering after a given sort value
if ( r_debugSort->integer && r_debugSort->integer < tess.shader->sort ) {
if ( r_debugSort->value > 0.0f && r_debugSort->value < tess.shader->sort ) {
return;
}
// update performance counters
if (tess.pass == shaderCommands_t::TP_LIGHT) {
backEnd.pc[RB_LIT_BATCHES]++;
backEnd.pc[RB_LIT_VERTICES] += tess.numVertexes;
backEnd.pc[RB_LIT_INDICES] += tess.numIndexes;
const shader_t* shader = input->shader;
if (shader->sort == SS_ENVIRONMENT) {
RB_DrawSky();
} else {
backEnd.pc[RB_BATCHES]++;
backEnd.pc[RB_VERTICES] += tess.numVertexes;
backEnd.pc[RB_INDICES] += tess.numIndexes;
if (!tess.deformsPreApplied) {
RB_DeformTessGeometry(0, tess.numVertexes, 0, tess.numIndexes);
for (int i = 0; i < shader->numStages; ++i) {
R_ComputeColors(shader->stages[i], tess.svars[i], 0, tess.numVertexes);
R_ComputeTexCoords(shader->stages[i], tess.svars[i], 0, tess.numVertexes, qtrue);
}
}
if (input->pass == shaderCommands_t::TP_LIGHT)
RB_DrawDynamicLight();
else
RB_DrawGeneric();
}
// call off to shader specific tess end function
tess.siFunc();
// draw debugging stuff
if (!backEnd.projection2D && (tess.pass == shaderCommands_t::TP_BASE)) {
if (r_showtris->integer) DrawTris( input );
if (r_shownormals->integer) DrawNormals( input );
if (!backEnd.projection2D &&
(tess.pass == shaderCommands_t::TP_BASE) &&
tess.numIndexes > 0 &&
tess.numVertexes > 0) {
if (r_showtris->integer) {
RB_PushSingleStageShader(GLS_POLYMODE_LINE | GLS_DEPTHMASK_TRUE, CT_FRONT_SIDED);
gal.SetDepthRange(0, 0);
gal.Draw(DT_GENERIC);
gal.SetDepthRange(0, 1);
RB_PopShader();
}
if (r_shownormals->integer) {
const int nv = tess.numVertexes;
for (int i = 0, j = nv; i < nv; ++i, ++j) {
VectorMA(input->xyz[i], 2, input->normal[i], tess.xyz[j]);
}
for (int i = 0, j = 0; i < nv; ++i) {
tess.indexes[j++] = i;
tess.indexes[j++] = i;
tess.indexes[j++] = i + nv;
}
tess.numVertexes = nv * 2;
tess.numIndexes = nv * 3;
RB_PushSingleStageShader(GLS_POLYMODE_LINE | GLS_DEPTHMASK_TRUE, CT_FRONT_SIDED);
shaderStage_t* const stage = tess.shader->stages[0];
stage->rgbGen = CGEN_CONST;
stage->constantColor[0] = 0;
stage->constantColor[1] = 0;
stage->constantColor[2] = 255;
stage->constantColor[3] = 255;
gal.SetDepthRange(0, 0);
gal.Draw(DT_GENERIC);
gal.SetDepthRange(0, 1);
RB_PopShader();
}
}
// clear shader so we can tell we don't have any unclosed surfaces
tess.numIndexes = 0;
}
///////////////////////////////////////////////////////////////
// blend a fog texture on top of everything else
void RB_FogPass()
{
qglEnableClientState( GL_COLOR_ARRAY );
qglColorPointer( 4, GL_UNSIGNED_BYTE, 0, tess.svars.colors );
qglEnableClientState( GL_TEXTURE_COORD_ARRAY);
qglTexCoordPointer( 2, GL_FLOAT, 0, tess.svars.texcoords[0] );
const fog_t* fog = tr.world->fogs + tess.fogNum;
for (int i = 0; i < tess.numVertexes; ++i ) {
*(int*)&tess.svars.colors[i] = fog->colorInt;
}
RB_CalcFogTexCoords( ( float * ) tess.svars.texcoords[0] );
GL_Bind( tr.fogImage );
if ( tess.shader->fogPass == FP_EQUAL ) {
GL_State( GLS_SRCBLEND_SRC_ALPHA | GLS_DSTBLEND_ONE_MINUS_SRC_ALPHA | GLS_DEPTHFUNC_EQUAL );
} else {
GL_State( GLS_SRCBLEND_SRC_ALPHA | GLS_DSTBLEND_ONE_MINUS_SRC_ALPHA );
}
R_DrawElements( tess.numIndexes, tess.indexes );
}
void R_ComputeColors( const shaderStage_t* pStage, stageVars_t& svars )
{
int i;
//
// rgbGen
//
switch ( pStage->rgbGen )
{
case CGEN_IDENTITY:
Com_Memset( svars.colors, 0xff, tess.numVertexes * 4 );
break;
default:
case CGEN_IDENTITY_LIGHTING:
Com_Memset( svars.colors, tr.identityLightByte, tess.numVertexes * 4 );
break;
case CGEN_LIGHTING_DIFFUSE:
RB_CalcDiffuseColor( ( unsigned char * ) svars.colors );
break;
case CGEN_CONST:
for (i = 0; i < tess.numVertexes; i++) {
*(int *)svars.colors[i] = *(int *)pStage->constantColor;
}
break;
case CGEN_VERTEX:
if ( tr.identityLight == 1 )
{
Com_Memcpy( svars.colors, tess.vertexColors, tess.numVertexes * sizeof( tess.vertexColors[0] ) );
}
else
{
for ( i = 0; i < tess.numVertexes; i++ )
{
svars.colors[i][0] = tess.vertexColors[i][0] * tr.identityLight;
svars.colors[i][1] = tess.vertexColors[i][1] * tr.identityLight;
svars.colors[i][2] = tess.vertexColors[i][2] * tr.identityLight;
svars.colors[i][3] = tess.vertexColors[i][3];
}
}
break;
case CGEN_EXACT_VERTEX:
Com_Memcpy( svars.colors, tess.vertexColors, tess.numVertexes * sizeof( tess.vertexColors[0] ) );
break;
case CGEN_ONE_MINUS_VERTEX:
if ( tr.identityLight == 1 )
{
for ( i = 0; i < tess.numVertexes; i++ )
{
svars.colors[i][0] = 255 - tess.vertexColors[i][0];
svars.colors[i][1] = 255 - tess.vertexColors[i][1];
svars.colors[i][2] = 255 - tess.vertexColors[i][2];
}
}
else
{
for ( i = 0; i < tess.numVertexes; i++ )
{
svars.colors[i][0] = ( 255 - tess.vertexColors[i][0] ) * tr.identityLight;
svars.colors[i][1] = ( 255 - tess.vertexColors[i][1] ) * tr.identityLight;
svars.colors[i][2] = ( 255 - tess.vertexColors[i][2] ) * tr.identityLight;
}
}
break;
case CGEN_FOG:
{
const fog_t* fog = tr.world->fogs + tess.fogNum;
for ( i = 0; i < tess.numVertexes; i++ ) {
*(int*)&svars.colors[i] = fog->colorInt;
}
}
break;
case CGEN_WAVEFORM:
RB_CalcWaveColor( &pStage->rgbWave, ( unsigned char * ) svars.colors );
break;
case CGEN_ENTITY:
RB_CalcColorFromEntity( ( unsigned char * ) svars.colors );
break;
case CGEN_ONE_MINUS_ENTITY:
RB_CalcColorFromOneMinusEntity( ( unsigned char * ) svars.colors );
break;
}
//
// alphaGen
//
switch ( pStage->alphaGen )
{
case AGEN_SKIP:
break;
case AGEN_IDENTITY:
if ( pStage->rgbGen != CGEN_IDENTITY ) {
if ( ( pStage->rgbGen == CGEN_VERTEX && tr.identityLight != 1 ) ||
pStage->rgbGen != CGEN_VERTEX ) {
for ( i = 0; i < tess.numVertexes; i++ ) {
svars.colors[i][3] = 0xff;
}
}
}
break;
case AGEN_CONST:
if ( pStage->rgbGen != CGEN_CONST ) {
for ( i = 0; i < tess.numVertexes; i++ ) {
svars.colors[i][3] = pStage->constantColor[3];
}
}
break;
case AGEN_WAVEFORM:
RB_CalcWaveAlpha( &pStage->alphaWave, ( unsigned char * ) svars.colors );
break;
case AGEN_LIGHTING_SPECULAR:
RB_CalcSpecularAlpha( ( unsigned char * ) svars.colors );
break;
case AGEN_ENTITY:
RB_CalcAlphaFromEntity( ( unsigned char * ) svars.colors );
break;
case AGEN_ONE_MINUS_ENTITY:
RB_CalcAlphaFromOneMinusEntity( ( unsigned char * ) svars.colors );
break;
case AGEN_VERTEX:
if ( pStage->rgbGen != CGEN_VERTEX ) {
for ( i = 0; i < tess.numVertexes; i++ ) {
svars.colors[i][3] = tess.vertexColors[i][3];
}
}
break;
case AGEN_ONE_MINUS_VERTEX:
for ( i = 0; i < tess.numVertexes; i++ )
{
svars.colors[i][3] = 255 - tess.vertexColors[i][3];
}
break;
case AGEN_PORTAL:
{
for ( i = 0; i < tess.numVertexes; i++ )
{
vec3_t v;
VectorSubtract( tess.xyz[i], backEnd.viewParms.orient.origin, v );
float len = VectorLength( v ) / tess.shader->portalRange;
svars.colors[i][3] = (byte)Com_Clamp( 0, 255, len * 255 );
}
}
break;
}
//
// fog adjustment for colors to fade out as fog increases
//
if ( tess.fogNum )
{
switch ( pStage->adjustColorsForFog )
{
case ACFF_MODULATE_RGB:
RB_CalcModulateColorsByFog( ( unsigned char * ) svars.colors );
break;
case ACFF_MODULATE_ALPHA:
RB_CalcModulateAlphasByFog( ( unsigned char * ) svars.colors );
break;
case ACFF_MODULATE_RGBA:
RB_CalcModulateRGBAsByFog( ( unsigned char * ) svars.colors );
break;
case ACFF_NONE:
break;
}
}
}
void R_ComputeTexCoords( const shaderStage_t* pStage, stageVars_t& svars )
{
int i;
// generate the base texture coordinates
switch ( pStage->tcGen )
{
case TCGEN_IDENTITY:
Com_Memset( svars.texcoords, 0, sizeof( float ) * 2 * tess.numVertexes );
break;
case TCGEN_TEXTURE:
for ( i = 0 ; i < tess.numVertexes ; i++ ) {
svars.texcoords[i][0] = tess.texCoords[i][0][0];
svars.texcoords[i][1] = tess.texCoords[i][0][1];
}
break;
case TCGEN_LIGHTMAP:
for ( i = 0 ; i < tess.numVertexes ; i++ ) {
svars.texcoords[i][0] = tess.texCoords[i][1][0];
svars.texcoords[i][1] = tess.texCoords[i][1][1];
}
break;
case TCGEN_VECTOR:
for ( i = 0 ; i < tess.numVertexes ; i++ ) {
svars.texcoords[i][0] = DotProduct( tess.xyz[i], pStage->tcGenVectors[0] );
svars.texcoords[i][1] = DotProduct( tess.xyz[i], pStage->tcGenVectors[1] );
}
break;
case TCGEN_FOG:
RB_CalcFogTexCoords( ( float * ) svars.texcoords );
break;
case TCGEN_ENVIRONMENT_MAPPED:
RB_CalcEnvironmentTexCoords( ( float * ) svars.texcoords );
break;
case TCGEN_BAD:
return;
}
// then alter for any tcmods
for ( i = 0; i < pStage->numTexMods; ++i ) {
switch ( pStage->texMods[i].type )
{
case TMOD_NONE:
i = TR_MAX_TEXMODS; // break out of for loop
break;
case TMOD_TURBULENT:
RB_CalcTurbulentTexCoords( &pStage->texMods[i].wave, (float*)svars.texcoords );
break;
case TMOD_ENTITY_TRANSLATE:
RB_CalcScrollTexCoords( backEnd.currentEntity->e.shaderTexCoord, (float*)svars.texcoords );
break;
case TMOD_SCROLL:
RB_CalcScrollTexCoords( pStage->texMods[i].scroll, (float*)svars.texcoords );
break;
case TMOD_SCALE:
RB_CalcScaleTexCoords( pStage->texMods[i].scale, (float*)svars.texcoords );
break;
case TMOD_STRETCH:
RB_CalcStretchTexCoords( &pStage->texMods[i].wave, (float*)svars.texcoords );
break;
case TMOD_TRANSFORM:
RB_CalcTransformTexCoords( &pStage->texMods[i], (float*)svars.texcoords );
break;
case TMOD_ROTATE:
RB_CalcRotateTexCoords( pStage->texMods[i].rotateSpeed, (float*)svars.texcoords );
break;
default:
ri.Error( ERR_DROP, "ERROR: unknown texmod '%d' in shader '%s'\n", pStage->texMods[i].type, tess.shader->name );
break;
}
}
// fix up uncorrected lightmap texture coordinates
if ( pStage->type == ST_LIGHTMAP && pStage->tcGen != TCGEN_LIGHTMAP )
{
const shader_t* const shader = tess.shader;
for ( int i = 0; i < tess.numVertexes; ++i )
{
svars.texcoords[i][0] = svars.texcoords[i][0] * shader->lmScale[0] + shader->lmBias[0];
svars.texcoords[i][1] = svars.texcoords[i][1] * shader->lmScale[1] + shader->lmBias[1];
}
}
}

File diff suppressed because it is too large Load diff

View file

@ -550,7 +550,7 @@ static qbool ParseStage( const char** text, shaderStage_t* stage )
}
else
{
stage->bundle.image[0] = R_FindImageFile( token, shader.imgflags, GL_REPEAT );
stage->bundle.image[0] = R_FindImageFile( token, shader.imgflags, TW_REPEAT );
if ( !stage->bundle.image[0] )
{
ri.Printf( PRINT_WARNING, "WARNING: R_FindImageFile could not find '%s' in shader '%s'\n", token, shader.name );
@ -570,7 +570,7 @@ static qbool ParseStage( const char** text, shaderStage_t* stage )
return qfalse;
}
stage->bundle.image[0] = R_FindImageFile( token, shader.imgflags, GL_CLAMP_TO_EDGE );
stage->bundle.image[0] = R_FindImageFile( token, shader.imgflags, TW_CLAMP_TO_EDGE );
if ( !stage->bundle.image[0] )
{
ri.Printf( PRINT_WARNING, "WARNING: R_FindImageFile could not find '%s' in shader '%s'\n", token, shader.name );
@ -598,7 +598,7 @@ static qbool ParseStage( const char** text, shaderStage_t* stage )
}
int num = stage->bundle.numImageAnimations;
if ( num < MAX_IMAGE_ANIMATIONS ) {
stage->bundle.image[num] = R_FindImageFile( token, shader.imgflags, GL_REPEAT );
stage->bundle.image[num] = R_FindImageFile( token, shader.imgflags, TW_REPEAT );
if ( !stage->bundle.image[num] )
{
ri.Printf( PRINT_WARNING, "WARNING: R_FindImageFile could not find '%s' in shader '%s'\n", token, shader.name );
@ -1115,7 +1115,7 @@ static void ParseSkyParms( const char** text )
if ( strcmp( token, "-" ) ) {
for (i = 0; i < 6; ++i) {
Com_sprintf( pathname, sizeof(pathname), "%s_%s.tga", token, suf[i] );
shader.sky.outerbox[i] = R_FindImageFile( pathname, IMG_NOMIPMAP | IMG_NOPICMIP, GL_CLAMP_TO_EDGE );
shader.sky.outerbox[i] = R_FindImageFile( pathname, IMG_NOMIPMAP | IMG_NOPICMIP, TW_CLAMP_TO_EDGE );
if ( !shader.sky.outerbox[i] ) {
shader.sky.outerbox[i] = tr.defaultImage;
}
@ -1143,7 +1143,7 @@ static void ParseSkyParms( const char** text )
if ( strcmp( token, "-" ) ) {
for (i = 0; i < 6; ++i) {
Com_sprintf( pathname, sizeof(pathname), "%s_%s.tga", token, suf[i] );
shader.sky.innerbox[i] = R_FindImageFile( pathname, IMG_NOMIPMAP | IMG_NOPICMIP, GL_REPEAT );
shader.sky.innerbox[i] = R_FindImageFile( pathname, IMG_NOMIPMAP | IMG_NOPICMIP, TW_REPEAT );
if ( !shader.sky.innerbox[i] ) {
shader.sky.innerbox[i] = tr.defaultImage;
}
@ -1534,52 +1534,41 @@ SHADER OPTIMIZATION AND FOGGING
*/
static void ComputeStageIteratorFunc()
{
if (shader.sort == SS_ENVIRONMENT) {
shader.siFunc = RB_StageIteratorSky;
return;
}
shader.siFunc = GL2_StageIterator;
}
typedef struct {
int blendA;
int blendB;
int multitextureEnv;
int multitextureBlend;
int blendA;
int blendB;
texEnv_t multitextureEnv;
int multitextureBlend;
} collapse_t;
static const collapse_t collapse[] = {
// the most common (and most worthwhile) collapse is for DxLM shaders
{ 0, GLS_SRCBLEND_DST_COLOR | GLS_DSTBLEND_ZERO,
GL_MODULATE, 0 },
TE_MODULATE, 0 },
{ 0, GLS_DSTBLEND_SRC_COLOR | GLS_SRCBLEND_ZERO,
GL_MODULATE, 0 },
TE_MODULATE, 0 },
{ GLS_DSTBLEND_ZERO | GLS_SRCBLEND_DST_COLOR, GLS_DSTBLEND_ZERO | GLS_SRCBLEND_DST_COLOR,
GL_MODULATE, GLS_DSTBLEND_ZERO | GLS_SRCBLEND_DST_COLOR },
TE_MODULATE, GLS_DSTBLEND_ZERO | GLS_SRCBLEND_DST_COLOR },
{ GLS_DSTBLEND_SRC_COLOR | GLS_SRCBLEND_ZERO, GLS_DSTBLEND_ZERO | GLS_SRCBLEND_DST_COLOR,
GL_MODULATE, GLS_DSTBLEND_ZERO | GLS_SRCBLEND_DST_COLOR },
TE_MODULATE, GLS_DSTBLEND_ZERO | GLS_SRCBLEND_DST_COLOR },
{ GLS_DSTBLEND_ZERO | GLS_SRCBLEND_DST_COLOR, GLS_DSTBLEND_SRC_COLOR | GLS_SRCBLEND_ZERO,
GL_MODULATE, GLS_DSTBLEND_ZERO | GLS_SRCBLEND_DST_COLOR },
TE_MODULATE, GLS_DSTBLEND_ZERO | GLS_SRCBLEND_DST_COLOR },
{ GLS_DSTBLEND_SRC_COLOR | GLS_SRCBLEND_ZERO, GLS_DSTBLEND_SRC_COLOR | GLS_SRCBLEND_ZERO,
GL_MODULATE, GLS_DSTBLEND_ZERO | GLS_SRCBLEND_DST_COLOR },
TE_MODULATE, GLS_DSTBLEND_ZERO | GLS_SRCBLEND_DST_COLOR },
{ 0, GLS_DSTBLEND_ONE | GLS_SRCBLEND_ONE,
GL_ADD, 0 },
TE_ADD, 0 },
{ GLS_DSTBLEND_ONE | GLS_SRCBLEND_ONE, GLS_DSTBLEND_ONE | GLS_SRCBLEND_ONE,
GL_ADD, GLS_DSTBLEND_ONE | GLS_SRCBLEND_ONE },
TE_ADD, GLS_DSTBLEND_ONE | GLS_SRCBLEND_ONE },
#if 0
{ 0, GLS_DSTBLEND_ONE_MINUS_SRC_ALPHA | GLS_SRCBLEND_SRC_ALPHA,
GL_DECAL, 0 },
TE_DECAL, 0 },
#endif
{ -1 }
};
@ -1596,10 +1585,6 @@ static qbool CollapseMultitexture( void ) {
int abits, bbits;
int i;
if ( !qglActiveTextureARB ) {
return qfalse;
}
// make sure both stages are active
if ( !stages[0].active || !stages[1].active ) {
return qfalse;
@ -1637,7 +1622,7 @@ static qbool CollapseMultitexture( void ) {
}
// an add collapse can only have identity colors
if ( collapse[i].multitextureEnv == GL_ADD && stages[0].rgbGen != CGEN_IDENTITY ) {
if ( collapse[i].multitextureEnv == TE_ADD && stages[0].rgbGen != CGEN_IDENTITY ) {
return qfalse;
}
@ -1742,9 +1727,8 @@ static void CollapseStages()
CollapseFailure;
// For the remaining cases, we generate and test the colors.
static stageVars_t svarsMT;
R_ComputeColors( &aStages[1], svarsMT );
const int* colors = (const int*)svarsMT.colors;
R_ComputeColors( &aStages[1], tess.svars[0], 0, tess.numVertexes );
const int* colors = (const int*)tess.svars[0].colors;
const int colorCount = tess.numVertexes;
int allOnes = -1;
for ( int c = 0; c < colorCount; ++c )
@ -1881,23 +1865,129 @@ static void VertexLightingCollapse( void ) {
}
/*
static void VertexLightingCollapse()
static qbool IsAdditiveBlend()
{
if ( shader.sort == SS_ENVIRONMENT )
return;
for (int i = 0; i < shader.numStages; ++i) {
if (!stages[i].active)
continue;
if ( shader.lightmapIndex == LIGHTMAP_NONE ) {
stages[0].rgbGen = CGEN_LIGHTING_DIFFUSE;
} else {
stages[0].rgbGen = CGEN_EXACT_VERTEX;
const int bits = stages[i].stateBits;
if ((bits & GLS_SRCBLEND_BITS) != GLS_SRCBLEND_ONE ||
(bits & GLS_DSTBLEND_BITS) != GLS_DSTBLEND_ONE ||
(bits & GLS_DEPTHMASK_TRUE) != 0)
return qfalse;
}
stages[0].alphaGen = AGEN_SKIP;
return qtrue;
}
*/
static qbool IsNormalBlend()
{
for (int i = 0; i < shader.numStages; ++i) {
if (!stages[i].active)
continue;
const int bits = stages[i].stateBits;
if ((bits & GLS_SRCBLEND_BITS) != GLS_SRCBLEND_SRC_ALPHA ||
(bits & GLS_DSTBLEND_BITS) != GLS_DSTBLEND_ONE_MINUS_SRC_ALPHA ||
(bits & GLS_DEPTHMASK_TRUE) != 0)
return qfalse;
}
return qtrue;
}
static void ProcessSoftSprite()
{
struct ssShader {
const char* name;
float distance;
float offset;
};
const ssShader ssShaders[] = {
{ "rocketExplosion", 24.0f },
{ "rocketExplosionNPM", 24.0f },
{ "grenadeExplosion", 24.0f },
{ "grenadeExplosionNPM", 24.0f },
{ "grenadeCPMA_NPM", 24.0f },
{ "grenadeCPMA", 24.0f },
{ "bloodTrail", 24.0f },
{ "sprites/particleSmoke", 24.0f },
{ "plasmaExplosion", 8.0f, 4.0f },
{ "plasmaExplosionNPM", 8.0f, 4.0f },
{ "plasmanewExplosion", 8.0f, 4.0f },
{ "plasmanewExplosionNPM", 8.0f, 4.0f },
{ "bulletExplosion", 8.0f, 4.0f },
{ "bulletExplosionNPM", 8.0f, 4.0f },
{ "railExplosion", 8.0f },
{ "railExplosionNPM", 8.0f },
{ "bfgExplosion", 8.0f },
{ "bfgExplosionNPM", 8.0f },
{ "bloodExplosion", 8.0f },
{ "bloodExplosionNPM", 8.0f },
{ "smokePuff", 8.0f },
{ "smokePuffNPM", 8.0f },
{ "shotgunSmokePuff", 8.0f },
{ "shotgunSmokePuffNPM", 8.0f }
};
shader.softSprite = SST_NONE;
if (!glInfo.softSpriteSupport || r_softSprites->integer == 0)
return;
if (shader.sort <= SS_OPAQUE)
return;
int activeStages = 0;
for (int i = 0; i < shader.numStages; ++i) {
if (stages[i].active)
++activeStages;
}
if (activeStages <= 0)
return;
qbool found = qfalse;
for (int i = 0; i < ARRAY_LEN(ssShaders); ++i) {
if (!Q_stricmp(shader.name, ssShaders[i].name)) {
shader.softSpriteDistance = 1.0f / ssShaders[i].distance;
shader.softSpriteOffset = ssShaders[i].offset;
found = qtrue;
break;
}
}
if (!found)
return;
if (IsAdditiveBlend())
shader.softSprite = SST_ADDITIVE;
else if (IsNormalBlend())
shader.softSprite = SST_BLEND;
}
static qbool UsesInternalLightmap( const shaderStage_t* stage )
{
return
stage->active &&
stage->type == ST_LIGHTMAP;
}
static qbool UsesExternalLightmap( const shaderStage_t* stage )
{
return
stage->active &&
stage->type == ST_DIFFUSE &&
!stage->bundle.isVideoMap &&
stage->bundle.numImageAnimations <= 1 &&
stage->bundle.image[0] != NULL &&
(stage->bundle.image[0]->flags & IMG_EXTLMATLAS) != 0;
}
// returns a freshly allocated shader with info
@ -2029,6 +2119,53 @@ static shader_t* FinishShader()
CollapseStages();
if ( r_fullbright->integer ) {
// we replace the lightmap texture with the white texture
for ( int i = 0; i < shader.numStages; ++i ) {
if ( UsesInternalLightmap( &stages[i] ) || UsesExternalLightmap( &stages[i] ) ) {
stages[i].type = ST_DIFFUSE;
stages[i].bundle.image[0] = tr.whiteImage;
}
}
} else if ( r_lightmap->integer ) {
// we reduce it down to a single lightmap stage with the same state bits as
// the current first stage (if the shader uses a lightmap at all)
// look for "real" lightmaps first (straight from the .bsp file itself)
int stageIndex = -1;
for ( int i = 0; i < shader.numStages; ++i ) {
if ( UsesInternalLightmap( &stages[i] ) ) {
stageIndex = i;
break;
}
}
if ( stageIndex == -1 ) {
// look for external lightmaps
for ( int i = 0; i < shader.numStages; ++i ) {
if ( UsesExternalLightmap( &stages[i] ) ) {
stageIndex = i;
break;
}
}
}
const int stateBits = stages[0].stateBits;
if ( stageIndex > 0 )
memcpy(stages, stages + stageIndex, sizeof(stages[0]));
if ( stageIndex >= 0 ) {
for ( int i = 1; i < shader.numStages; ++i ) {
stages[i].active = qfalse;
}
stages[0].stateBits = stateBits;
stages[0].mtStages = 0;
shader.lightingStages[ST_DIFFUSE] = 0; // for working dynamic lights
shader.lightingStages[ST_LIGHTMAP] = 0;
shader.numStages = 1;
}
}
/* !!!
if ( shader.lightmapIndex >= 0 && !hasLightmapStage ) {
ri.Printf( PRINT_DEVELOPER, "WARNING: shader '%s' has lightmap but no lightmap stage!\n", shader.name );
@ -2045,8 +2182,7 @@ static shader_t* FinishShader()
shader.sort = SS_FOG;
}
// determine which stage iterator function is appropriate
ComputeStageIteratorFunc();
ProcessSoftSprite();
return GeneratePermanentShader();
}
@ -2175,12 +2311,6 @@ shader_t* R_FindShader( const char *name, int lightmapIndex, qbool mipRawImage )
stages[i].texMods = texMods[i];
}
// FIXME: set these "need" values apropriately
shader.needsNormal = qtrue;
shader.needsST1 = qtrue;
shader.needsST2 = qtrue;
shader.needsColor = qtrue;
//
// attempt to define shader from an explicit parameter file
//
@ -2205,9 +2335,9 @@ shader_t* R_FindShader( const char *name, int lightmapIndex, qbool mipRawImage )
const image_t* image;
if (mipRawImage)
image = R_FindImageFile( fileName, 0, GL_REPEAT );
image = R_FindImageFile( fileName, 0, TW_REPEAT );
else
image = R_FindImageFile( fileName, IMG_NOMIPMAP | IMG_NOPICMIP, GL_CLAMP_TO_EDGE );
image = R_FindImageFile( fileName, IMG_NOMIPMAP | IMG_NOPICMIP, TW_CLAMP_TO_EDGE );
if ( !image ) {
ri.Printf( PRINT_DEVELOPER, "Couldn't find image for shader %s\n", name );
@ -2282,11 +2412,6 @@ qhandle_t RE_RegisterShaderFromImage( const char* name, const image_t* image )
stages[i].texMods = texMods[i];
}
shader.needsNormal = qfalse;
shader.needsST1 = qtrue;
shader.needsST2 = qfalse;
shader.needsColor = qtrue;
// create the default shading commands: this can only ever be a 2D/UI shader
stages[0].bundle.image[0] = image;
stages[0].active = qtrue;
@ -2371,8 +2496,6 @@ void R_ShaderList_f( void )
if (sh->lightmapIndex >= 0 ) {
ri.Printf( PRINT_ALL, "L " );
//} else if (sh->lightmapIndex == LIGHTMAP_WHITE ) {
// ri.Printf( PRINT_ALL, "W " );
} else {
ri.Printf( PRINT_ALL, " " );
}
@ -2382,12 +2505,10 @@ void R_ShaderList_f( void )
ri.Printf( PRINT_ALL, " " );
}
if ( sh->siFunc == GL2_StageIterator ) {
ri.Printf( PRINT_ALL, " " );
} else if ( sh->siFunc == RB_StageIteratorSky ) {
if ( sh->sort == SS_ENVIRONMENT ) {
ri.Printf( PRINT_ALL, "sky " );
} else {
ri.Printf( PRINT_ALL, "??? " );
ri.Printf( PRINT_ALL, " " );
}
if ( sh->defaultShader ) {
@ -2399,21 +2520,6 @@ void R_ShaderList_f( void )
}
ri.Printf( PRINT_ALL, "%i total shaders\n", count );
/*
int buckets = 0, collisions = 0;
for (i = 0; i < MAX_SHADERTEXT_HASH; ++i) {
if (shaderTextHashTable[i][0]) {
ri.Printf( PRINT_ALL, "%i: ", i );
for (int c = 1; shaderTextHashTable[i][c]; ++c) {
ri.Printf( PRINT_ALL, "C " );
++collisions;
}
++buckets;
ri.Printf( PRINT_ALL, "\n", i );
}
}
ri.Printf( PRINT_ALL, "%i/%i buckets, %i collisions\n", buckets, MAX_SHADERTEXT_HASH, collisions );
*/
ri.Printf( PRINT_ALL, "--------------------\n" );
}
@ -2449,8 +2555,6 @@ static void ScanAndLoadShaderFiles()
{
char filename[MAX_QPATH];
Com_sprintf( filename, sizeof( filename ), "scripts/%s", shaderFiles[i] );
// KHB there's simply no time to EVER want this - it's self-destructive because of the HUGE spam >:(
//ri.Printf( PRINT_DEVELOPER, "...loading '%s'\n", filename );
ri.FS_ReadFile( filename, (void **)&buffers[i] );
if ( !buffers[i] )
ri.Error( ERR_DROP, "Couldn't load %s", filename );
@ -2523,12 +2627,14 @@ static void CreateInternalShaders()
Com_Memset( &stages, 0, sizeof( stages ) );
Q_strncpyz( shader.name, "<default>", sizeof( shader.name ) );
shader.lightmapIndex = LIGHTMAP_NONE;
stages[0].bundle.image[0] = tr.defaultImage;
stages[0].active = qtrue;
stages[0].stateBits = GLS_DEFAULT;
tr.defaultShader = FinishShader();
Q_strncpyz( shader.name, "<scratch>", sizeof( shader.name ) );
tr.scratchShader = FinishShader();
}

View file

@ -22,9 +22,6 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
// tr_sky.c
#include "tr_local.h"
#define SKY_SUBDIVISIONS 8
#define HALF_SKY_SUBDIVISIONS (SKY_SUBDIVISIONS/2)
static float s_cloudTexCoords[6][SKY_SUBDIVISIONS+1][SKY_SUBDIVISIONS+1][2];
/*
@ -244,16 +241,16 @@ static void ClearSkyBox()
}
static void RB_ClipSkyPolygons( const shaderCommands_t* input )
static void RB_ClipSkyPolygons()
{
vec3_t p[4]; // need one extra point for clipping
ClearSkyBox();
for ( int i = 0; i < input->numIndexes; i += 3 ) {
VectorSubtract( input->xyz[input->indexes[i+0]], backEnd.viewParms.orient.origin, p[0] );
VectorSubtract( input->xyz[input->indexes[i+1]], backEnd.viewParms.orient.origin, p[1] );
VectorSubtract( input->xyz[input->indexes[i+2]], backEnd.viewParms.orient.origin, p[2] );
for ( int i = 0; i < tess.numIndexes; i += 3 ) {
VectorSubtract( tess.xyz[tess.indexes[i+0]], backEnd.viewParms.orient.origin, p[0] );
VectorSubtract( tess.xyz[tess.indexes[i+1]], backEnd.viewParms.orient.origin, p[1] );
VectorSubtract( tess.xyz[tess.indexes[i+2]], backEnd.viewParms.orient.origin, p[2] );
ClipSkyPolygon( 3, p[0], 0 );
}
}
@ -308,7 +305,7 @@ static void MakeSkyVec( float s, float t, int axis, vec2_t st, vec3_t xyz )
}
static void CalcSkyBounds()
void RB_CalcSkyBounds()
{
for (int i = 0; i < 6; ++i) {
sky_mins_st[i][0] = floor( sky_mins_st[i][0] * HALF_SKY_SUBDIVISIONS ) / HALF_SKY_SUBDIVISIONS;
@ -319,77 +316,23 @@ static void CalcSkyBounds()
}
static void DrawSkySide( const image_t* image, const int mins[2], const int maxs[2] )
{
int s, t;
GL_Bind( image );
for ( t = mins[1]+HALF_SKY_SUBDIVISIONS; t < maxs[1]+HALF_SKY_SUBDIVISIONS; t++ )
{
qglBegin( GL_TRIANGLE_STRIP );
for ( s = mins[0]+HALF_SKY_SUBDIVISIONS; s <= maxs[0]+HALF_SKY_SUBDIVISIONS; s++ )
{
qglTexCoord2fv( s_skyTexCoords[t][s] );
qglVertex3fv( s_skyPoints[t][s] );
qglTexCoord2fv( s_skyTexCoords[t+1][s] );
qglVertex3fv( s_skyPoints[t+1][s] );
}
qglEnd();
}
}
static void DrawSkyBox( const shader_t* shader )
{
// Com_Memset( s_skyTexCoords, 0, sizeof( s_skyTexCoords ) );
for (int i = 0; i < 6; ++i)
{
int sky_mins_subd[2], sky_maxs_subd[2];
if ( ( sky_mins_st[i][0] >= sky_maxs_st[i][0] ) || ( sky_mins_st[i][1] >= sky_maxs_st[i][1] ) ) {
continue;
}
sky_mins_subd[0] = HALF_SKY_SUBDIVISIONS * Com_Clamp( -1, 1, sky_mins_st[i][0] );
sky_mins_subd[1] = HALF_SKY_SUBDIVISIONS * Com_Clamp( -1, 1, sky_mins_st[i][1] );
sky_maxs_subd[0] = HALF_SKY_SUBDIVISIONS * Com_Clamp( -1, 1, sky_maxs_st[i][0] );
sky_maxs_subd[1] = HALF_SKY_SUBDIVISIONS * Com_Clamp( -1, 1, sky_maxs_st[i][1] );
//
// iterate through the subdivisions
//
for (int t = sky_mins_subd[1]+HALF_SKY_SUBDIVISIONS; t <= sky_maxs_subd[1]+HALF_SKY_SUBDIVISIONS; ++t)
{
for (int s = sky_mins_subd[0]+HALF_SKY_SUBDIVISIONS; s <= sky_maxs_subd[0]+HALF_SKY_SUBDIVISIONS; ++s)
{
MakeSkyVec( ( s - HALF_SKY_SUBDIVISIONS ) / ( float ) HALF_SKY_SUBDIVISIONS,
( t - HALF_SKY_SUBDIVISIONS ) / ( float ) HALF_SKY_SUBDIVISIONS,
i, s_skyTexCoords[t][s], s_skyPoints[t][s] );
}
}
DrawSkySide( shader->sky.outerbox[i], sky_mins_subd, sky_maxs_subd );
}
}
static void FillCloudySkySide( const int mins[2], const int maxs[2], qbool addIndexes )
{
int s, t;
int vertexStart = tess.numVertexes;
const int vertexStart = tess.numVertexes;
const uint32_t vertexColor =
(uint32_t)tr.identityLightByte |
((uint32_t)tr.identityLightByte << 8) |
((uint32_t)tr.identityLightByte << 16) |
((uint32_t)256 << 24);
for ( t = mins[1]+HALF_SKY_SUBDIVISIONS; t <= maxs[1]+HALF_SKY_SUBDIVISIONS; t++ )
for ( int t = mins[1]+HALF_SKY_SUBDIVISIONS; t <= maxs[1]+HALF_SKY_SUBDIVISIONS; t++ )
{
for ( s = mins[0]+HALF_SKY_SUBDIVISIONS; s <= maxs[0]+HALF_SKY_SUBDIVISIONS; s++ )
for ( int s = mins[0]+HALF_SKY_SUBDIVISIONS; s <= maxs[0]+HALF_SKY_SUBDIVISIONS; s++ )
{
VectorAdd( s_skyPoints[t][s], backEnd.viewParms.orient.origin, tess.xyz[tess.numVertexes] );
tess.texCoords[tess.numVertexes][0][0] = s_skyTexCoords[t][s][0];
tess.texCoords[tess.numVertexes][0][1] = s_skyTexCoords[t][s][1];
tess.texCoords[tess.numVertexes][0] = s_skyTexCoords[t][s][0];
tess.texCoords[tess.numVertexes][1] = s_skyTexCoords[t][s][1];
*(uint32_t*)&tess.vertexColors[tess.numVertexes] = vertexColor;
tess.numVertexes++;
@ -407,9 +350,9 @@ static void FillCloudySkySide( const int mins[2], const int maxs[2], qbool addIn
int tHeight = maxs[1] - mins[1] + 1;
int sWidth = maxs[0] - mins[0] + 1;
for ( t = 0; t < tHeight-1; t++ )
for ( int t = 0; t < tHeight-1; t++ )
{
for ( s = 0; s < sWidth-1; s++ )
for ( int s = 0; s < sWidth-1; s++ )
{
tess.indexes[tess.numIndexes] = vertexStart + s + t * ( sWidth );
tess.numIndexes++;
@ -426,6 +369,12 @@ static void FillCloudySkySide( const int mins[2], const int maxs[2], qbool addIn
tess.numIndexes++;
}
}
for ( int i = 0; i < tess.shader->numStages; ++i )
{
R_ComputeColors( tess.shader->stages[i], tess.svars[i], 0, tess.numVertexes );
R_ComputeTexCoords( tess.shader->stages[i], tess.svars[i], 0, tess.numVertexes, qfalse );
}
}
@ -472,19 +421,16 @@ static void FillCloudBox( const shader_t* shader, int stage )
}
static void R_BuildCloudData( shaderCommands_t* input )
void R_BuildCloudData()
{
assert( input->shader->sort == SS_ENVIRONMENT );
assert( tess.shader->sort == SS_ENVIRONMENT );
// set up for drawing
tess.numIndexes = 0;
tess.numVertexes = 0;
if (!input->shader->sky.cloudHeight)
return;
for (int i = 0; (i < MAX_SHADER_STAGES) && tess.xstages[i]; ++i) {
FillCloudBox( input->shader, i );
FillCloudBox( tess.shader, i );
}
}
@ -546,52 +492,72 @@ void R_InitSkyTexCoords( float heightCloud )
}
///////////////////////////////////////////////////////////////
// all of the visible sky triangles are in tess
// other things could be stuck in here, like birds in the sky, etc
void RB_StageIteratorSky()
static void DrawSkyBox()
{
if ( r_fastsky->integer ) {
return;
const image_t*const* skyImages = &tess.shader->sky.outerbox[0];
RB_PushSingleStageShader( 0, CT_TWO_SIDED );
shaderStage_t* const stage = tess.shader->stages[0];
stage->rgbGen = CGEN_IDENTITY_LIGHTING;
for (int i = 0; i < 6; ++i)
{
if ( ( sky_mins_st[i][0] >= sky_maxs_st[i][0] ) || ( sky_mins_st[i][1] >= sky_maxs_st[i][1] ) ) {
continue;
}
int sky_mins_subd[2];
int sky_maxs_subd[2];
sky_mins_subd[0] = HALF_SKY_SUBDIVISIONS * Com_Clamp( -1, 1, sky_mins_st[i][0] );
sky_mins_subd[1] = HALF_SKY_SUBDIVISIONS * Com_Clamp( -1, 1, sky_mins_st[i][1] );
sky_maxs_subd[0] = HALF_SKY_SUBDIVISIONS * Com_Clamp( -1, 1, sky_maxs_st[i][0] );
sky_maxs_subd[1] = HALF_SKY_SUBDIVISIONS * Com_Clamp( -1, 1, sky_maxs_st[i][1] );
// iterate through the subdivisions
for (int t = sky_mins_subd[1]+HALF_SKY_SUBDIVISIONS; t <= sky_maxs_subd[1]+HALF_SKY_SUBDIVISIONS; ++t)
{
for (int s = sky_mins_subd[0]+HALF_SKY_SUBDIVISIONS; s <= sky_maxs_subd[0]+HALF_SKY_SUBDIVISIONS; ++s)
{
MakeSkyVec( ( s - HALF_SKY_SUBDIVISIONS ) / ( float ) HALF_SKY_SUBDIVISIONS,
( t - HALF_SKY_SUBDIVISIONS ) / ( float ) HALF_SKY_SUBDIVISIONS,
i, s_skyTexCoords[t][s], s_skyPoints[t][s] );
}
}
// write to tess and draw
stage->bundle.image[0] = skyImages[i];
tess.numVertexes = 0;
tess.numIndexes = 0;
FillCloudySkySide( sky_mins_subd, sky_maxs_subd, qtrue );
gal.Draw( DT_GENERIC );
}
GL_Program();
RB_PopShader();
tess.numVertexes = 0;
tess.numIndexes = 0;
}
void RB_DrawSky()
{
if (r_fastsky->integer)
return;
// project all the polygons onto the sky box
// to see which blocks on each side need to be drawn
RB_ClipSkyPolygons( &tess );
RB_ClipSkyPolygons();
RB_CalcSkyBounds();
CalcSkyBounds();
gal.BeginSkyAndClouds();
if (tess.shader->sky.outerbox[0] && tess.shader->sky.outerbox[0] != tr.defaultImage)
DrawSkyBox();
// r_showsky will let all the sky blocks be drawn in
// front of everything to allow developers to see how
// much sky is getting sucked in
if ( r_showsky->integer ) {
qglDepthRange( 0.0, 0.0 );
} else {
qglDepthRange( 1.0, 1.0 );
if (tess.shader->sky.cloudHeight > 0.0f) {
R_BuildCloudData();
if (tess.numVertexes)
gal.Draw(DT_GENERIC);
}
// draw the outer skybox
if ( tess.shader->sky.outerbox[0] && tess.shader->sky.outerbox[0] != tr.defaultImage ) {
qglColor3f( tr.identityLight, tr.identityLight, tr.identityLight );
qglPushMatrix();
GL_State( 0 );
qglTranslatef (backEnd.viewParms.orient.origin[0], backEnd.viewParms.orient.origin[1], backEnd.viewParms.orient.origin[2]);
DrawSkyBox( tess.shader );
qglPopMatrix();
}
// generate the vertexes for all the clouds (if any)
// which will be drawn by the generic shader routine
R_BuildCloudData( &tess );
if (tess.numVertexes)
GL2_StageIterator();
// back to normal depth range
qglDepthRange( 0.0, 1.0 );
gal.EndSkyAndClouds();
}

View file

@ -22,6 +22,13 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
// tr_surf.c
#include "tr_local.h"
#if idSSE2
#include <emmintrin.h>
#include <stddef.h> // offsetof macro
static byte check_srfVertTC[(offsetof(srfVert_t, st2) == offsetof(srfVert_t, st) + 8) ? 1 : -1];
static byte check_drawVertTC[(offsetof(drawVert_t, lightmap) == offsetof(drawVert_t, st) + 8) ? 1 : -1];
#endif
/*
THIS ENTIRE FILE IS BACK END
@ -110,17 +117,17 @@ void RB_AddQuadStampExt( vec3_t origin, vec3_t left, vec3_t up, byte *color, flo
tess.normal[ndx][2] = tess.normal[ndx+1][2] = tess.normal[ndx+2][2] = tess.normal[ndx+3][2] = normal[2];
// standard square texture coordinates
tess.texCoords[ndx][0][0] = tess.texCoords[ndx][1][0] = s1;
tess.texCoords[ndx][0][1] = tess.texCoords[ndx][1][1] = t1;
tess.texCoords[ndx][0] = tess.texCoords2[ndx][0] = s1;
tess.texCoords[ndx][1] = tess.texCoords2[ndx][1] = t1;
tess.texCoords[ndx+1][0][0] = tess.texCoords[ndx+1][1][0] = s2;
tess.texCoords[ndx+1][0][1] = tess.texCoords[ndx+1][1][1] = t1;
tess.texCoords[ndx+1][0] = tess.texCoords2[ndx+1][0] = s2;
tess.texCoords[ndx+1][1] = tess.texCoords2[ndx+1][1] = t1;
tess.texCoords[ndx+2][0][0] = tess.texCoords[ndx+2][1][0] = s2;
tess.texCoords[ndx+2][0][1] = tess.texCoords[ndx+2][1][1] = t2;
tess.texCoords[ndx+2][0] = tess.texCoords2[ndx+2][0] = s2;
tess.texCoords[ndx+2][1] = tess.texCoords2[ndx+2][1] = t2;
tess.texCoords[ndx+3][0][0] = tess.texCoords[ndx+3][1][0] = s1;
tess.texCoords[ndx+3][0][1] = tess.texCoords[ndx+3][1][1] = t2;
tess.texCoords[ndx+3][0] = tess.texCoords2[ndx+3][0] = s1;
tess.texCoords[ndx+3][1] = tess.texCoords2[ndx+3][1] = t2;
// constant color all the way around
// should this be identity and let the shader specify from entity?
@ -182,8 +189,8 @@ static void RB_SurfacePolychain( const srfPoly_t* p )
int numv = tess.numVertexes;
for ( i = 0; i < p->numVerts; ++i ) {
VectorCopy( p->verts[i].xyz, tess.xyz[numv] );
tess.texCoords[numv][0][0] = p->verts[i].st[0];
tess.texCoords[numv][0][1] = p->verts[i].st[1];
tess.texCoords[numv][0] = p->verts[i].st[0];
tess.texCoords[numv][1] = p->verts[i].st[1];
*(unsigned*)&tess.vertexColors[numv] = *(unsigned*)p->verts[i].modulate;
++numv;
}
@ -205,7 +212,7 @@ static void RB_SurfaceTriangles( srfTriangles_t* surf )
RB_CHECKOVERFLOW( surf->numVerts, surf->numIndexes );
glIndex_t* tessIndexes = tess.indexes + tess.numIndexes;
unsigned int* tessIndexes = tess.indexes + tess.numIndexes;
for ( i = 0; i < surf->numIndexes; ++i )
tessIndexes[i] = tess.numVertexes + surf->indexes[i];
tess.numIndexes += surf->numIndexes;
@ -213,12 +220,11 @@ static void RB_SurfaceTriangles( srfTriangles_t* surf )
const srfVert_t* v = surf->verts;
for ( i = 0, ndx = tess.numVertexes; i < surf->numVerts; ++i, ++v, ++ndx ) {
VectorCopy( v->xyz, tess.xyz[ndx] );
if ( tess.shader->needsNormal )
VectorCopy( v->normal, tess.normal[ndx] );
tess.texCoords[ndx][0][0] = v->st[0];
tess.texCoords[ndx][0][1] = v->st[1];
tess.texCoords[ndx][1][0] = v->st2[0];
tess.texCoords[ndx][1][1] = v->st2[1];
VectorCopy( v->normal, tess.normal[ndx] );
tess.texCoords[ndx][0] = v->st[0];
tess.texCoords[ndx][1] = v->st[1];
tess.texCoords2[ndx][0] = v->st2[0];
tess.texCoords2[ndx][1] = v->st2[1];
*(unsigned int *)&tess.vertexColors[ndx] = *(unsigned int *)v->rgba;
}
@ -236,33 +242,32 @@ static void RB_LightningBoltFace( const vec3_t start, const vec3_t end, const ve
// FIXME: use quad stamp?
VectorMA( start, spanWidth, up, tess.xyz[tess.numVertexes] );
tess.texCoords[tess.numVertexes][0][0] = 0;
tess.texCoords[tess.numVertexes][0][1] = 0;
tess.texCoords[tess.numVertexes][0] = 0;
tess.texCoords[tess.numVertexes][1] = 0;
tess.vertexColors[tess.numVertexes][0] = backEnd.currentEntity->e.shaderRGBA[0] * 0.25;
tess.vertexColors[tess.numVertexes][1] = backEnd.currentEntity->e.shaderRGBA[1] * 0.25;
tess.vertexColors[tess.numVertexes][2] = backEnd.currentEntity->e.shaderRGBA[2] * 0.25;
tess.numVertexes++;
VectorMA( start, -spanWidth, up, tess.xyz[tess.numVertexes] );
tess.texCoords[tess.numVertexes][0][0] = 0;
tess.texCoords[tess.numVertexes][0][1] = 1;
tess.texCoords[tess.numVertexes][0] = 0;
tess.texCoords[tess.numVertexes][1] = 1;
tess.vertexColors[tess.numVertexes][0] = backEnd.currentEntity->e.shaderRGBA[0];
tess.vertexColors[tess.numVertexes][1] = backEnd.currentEntity->e.shaderRGBA[1];
tess.vertexColors[tess.numVertexes][2] = backEnd.currentEntity->e.shaderRGBA[2];
tess.numVertexes++;
VectorMA( end, spanWidth, up, tess.xyz[tess.numVertexes] );
tess.texCoords[tess.numVertexes][0][0] = t;
tess.texCoords[tess.numVertexes][0][1] = 0;
tess.texCoords[tess.numVertexes][0] = t;
tess.texCoords[tess.numVertexes][1] = 0;
tess.vertexColors[tess.numVertexes][0] = backEnd.currentEntity->e.shaderRGBA[0];
tess.vertexColors[tess.numVertexes][1] = backEnd.currentEntity->e.shaderRGBA[1];
tess.vertexColors[tess.numVertexes][2] = backEnd.currentEntity->e.shaderRGBA[2];
tess.numVertexes++;
VectorMA( end, -spanWidth, up, tess.xyz[tess.numVertexes] );
tess.texCoords[tess.numVertexes][0][0] = t;
tess.texCoords[tess.numVertexes][0][1] = 1;
tess.texCoords[tess.numVertexes][0] = t;
tess.texCoords[tess.numVertexes][1] = 1;
tess.vertexColors[tess.numVertexes][0] = backEnd.currentEntity->e.shaderRGBA[0];
tess.vertexColors[tess.numVertexes][1] = backEnd.currentEntity->e.shaderRGBA[1];
tess.vertexColors[tess.numVertexes][2] = backEnd.currentEntity->e.shaderRGBA[2];
@ -504,8 +509,8 @@ void RB_SurfaceMesh(md3Surface_t *surface) {
texCoords = (float *) ((byte *)surface + surface->ofsSt);
for ( j = 0; j < surface->numVerts; j++ ) {
tess.texCoords[Doug + j][0][0] = texCoords[j*2+0];
tess.texCoords[Doug + j][0][1] = texCoords[j*2+1];
tess.texCoords[Doug + j][0] = texCoords[j*2+0];
tess.texCoords[Doug + j][1] = texCoords[j*2+1];
// FIXME: fill in lightmapST for completeness?
}
@ -515,30 +520,84 @@ void RB_SurfaceMesh(md3Surface_t *surface) {
static void RB_SurfaceFace( srfSurfaceFace_t* surf )
{
int i, ndx;
RB_CHECKOVERFLOW( surf->numVerts, surf->numIndexes );
glIndex_t* tessIndexes = tess.indexes + tess.numIndexes;
for ( i = 0; i < surf->numIndexes; ++i )
tessIndexes[i] = tess.numVertexes + surf->indexes[i];
const int tessNumVertexes = tess.numVertexes;
const int* surfIndexes = surf->indexes;
unsigned int* tessIndexes = tess.indexes + tess.numIndexes;
unsigned int* const tessIndexesEnd = tessIndexes + surf->numIndexes;
#if idSSE2
unsigned int* const tessIndexesEndSIMD = tessIndexesEnd - 3;
const __m128i xmmNumVerts = _mm_set1_epi32( tess.numVertexes );
while ( tessIndexes < tessIndexesEndSIMD ) {
const __m128i xmmIn = _mm_loadu_si128( (const __m128i*)surfIndexes );
const __m128i xmmOut = _mm_add_epi32( xmmIn, xmmNumVerts );
_mm_storeu_si128( (__m128i*)tessIndexes, xmmOut );
tessIndexes += 4;
surfIndexes += 4;
}
#endif
while ( tessIndexes < tessIndexesEnd ) {
*tessIndexes++ = *surfIndexes++ + tessNumVertexes;
}
tess.numIndexes += surf->numIndexes;
if ( tess.shader->needsNormal ) {
const float* normal = surf->plane.normal;
for ( i = 0, ndx = tess.numVertexes; i < surf->numVerts; ++i, ++ndx ) {
VectorCopy( normal, tess.normal[ndx] );
}
}
const srfVert_t* v = surf->verts;
for ( i = 0, ndx = tess.numVertexes; i < surf->numVerts; ++i, ++v, ++ndx ) {
int i = 0;
int ndx = tess.numVertexes;
const int end = surf->numVerts;
#if idSSE2
const int endSIMD = end - 1;
for ( ; i < endSIMD; i += 2, v += 2, ndx += 2 ) {
const __m128i xmmP0 = _mm_loadu_si128((const __m128i*)(v + 0)->xyz);
const __m128i xmmN0 = _mm_loadu_si128((const __m128i*)(v + 0)->normal);
const __m128i xmmT0 = _mm_loadu_si128((const __m128i*)(v + 0)->st); // tc2_0.y tc2_0.x tc_0.y tc_0.x
const __m128i xmmP1 = _mm_loadu_si128((const __m128i*)(v + 1)->xyz);
const __m128i xmmN1 = _mm_loadu_si128((const __m128i*)(v + 1)->normal);
const __m128i xmmT1 = _mm_loadu_si128((const __m128i*)(v + 1)->st); // tc2_1.y tc2_1.x tc_1.y tc_1.x
const __m128i xmmTC0 = _mm_unpacklo_epi64(xmmT0, xmmT1); // tc_1.y tc_1.x tc_0.y tc_0.x
const __m128i xmmTC1 = _mm_unpackhi_epi64(xmmT0, xmmT1); // tc2_1.y tc2_1.x tc2_0.y tc2_0.x
_mm_storeu_si128((__m128i*)tess.xyz[ndx + 0], xmmP0);
_mm_storeu_si128((__m128i*)tess.xyz[ndx + 1], xmmP1);
_mm_storeu_si128((__m128i*)tess.normal[ndx + 0], xmmN0);
_mm_storeu_si128((__m128i*)tess.normal[ndx + 1], xmmN1);
_mm_storeu_si128((__m128i*)tess.texCoords[ndx], xmmTC0);
_mm_storeu_si128((__m128i*)tess.texCoords2[ndx], xmmTC1);
*(uint32_t*)&tess.vertexColors[ndx + 0] = *(uint32_t*)(v + 0)->rgba;
*(uint32_t*)&tess.vertexColors[ndx + 1] = *(uint32_t*)(v + 1)->rgba;
}
#endif
for ( ; i < end; ++i, ++v, ++ndx ) {
#if idSSE2
const __m128i xmmP = _mm_loadu_si128((const __m128i*)v->xyz);
const __m128i xmmN = _mm_loadu_si128((const __m128i*)v->normal);
const __m128i xmmT1 = _mm_loadu_si128((const __m128i*)v->st);
const __m128i xmmT2 = _mm_shuffle_epi32(xmmT1, (2 << 0) | (3 << 2) | (0 << 4) | (1 << 6));
_mm_storeu_si128((__m128i*)tess.xyz[ndx], xmmP);
_mm_storeu_si128((__m128i*)tess.normal[ndx], xmmN);
_mm_storel_epi64((__m128i*)tess.texCoords[ndx], xmmT1);
_mm_storel_epi64((__m128i*)tess.texCoords2[ndx], xmmT2);
*(uint32_t*)&tess.vertexColors[ndx] = *(uint32_t*)v->rgba;
#elif defined Q3_LITTLE_ENDIAN
*(uint64_t*)&tess.xyz[ndx][0] = *(uint64_t*)&v->xyz[0];
tess.xyz[ndx][2] = v->xyz[2];
*(uint64_t*)&tess.normal[ndx][0] = *(uint64_t*)&v->normal[0];
tess.normal[ndx][2] = v->normal[2];
*(uint64_t*)&tess.texCoords[ndx][0] = *(uint64_t*)&v->st[0];
*(uint64_t*)&tess.texCoords2[ndx][0] = *(uint64_t*)&v->st2[0];
*(uint32_t*)&tess.vertexColors[ndx] = *(uint32_t*)v->rgba;
#else
VectorCopy( v->xyz, tess.xyz[ndx] );
tess.texCoords[ndx][0][0] = v->st[0];
tess.texCoords[ndx][0][1] = v->st[1];
tess.texCoords[ndx][1][0] = v->st2[0];
tess.texCoords[ndx][1][1] = v->st2[1];
*(unsigned int *)&tess.vertexColors[ndx] = *(unsigned int *)v->rgba;
VectorCopy( v->normal, tess.normal[ndx] );
tess.texCoords[ndx][0] = v->st[0];
tess.texCoords[ndx][1] = v->st[1];
tess.texCoords2[ndx][0] = v->st2[0];
tess.texCoords2[ndx][1] = v->st2[1];
tess.vertexColors[ndx][0] = v->rgba[0];
tess.vertexColors[ndx][1] = v->rgba[1];
tess.vertexColors[ndx][2] = v->rgba[2];
tess.vertexColors[ndx][3] = v->rgba[3];
#endif
}
tess.numVertexes += surf->numVerts;
@ -586,6 +645,7 @@ void RB_SurfaceGrid( srfGridMesh_t *cv ) {
int i, j;
float *xyz;
float *texCoords;
float *texCoords2;
float *normal;
unsigned char *color;
drawVert_t *dv;
@ -596,7 +656,6 @@ void RB_SurfaceGrid( srfGridMesh_t *cv ) {
float lodError;
int lodWidth, lodHeight;
int numVertexes;
qbool needsNormal;
// determine the allowable discrepance
lodError = LodErrorForVolume( cv->lodOrigin, cv->lodRadius );
@ -658,31 +717,52 @@ void RB_SurfaceGrid( srfGridMesh_t *cv ) {
xyz = tess.xyz[numVertexes];
normal = tess.normal[numVertexes];
texCoords = tess.texCoords[numVertexes][0];
texCoords = tess.texCoords[numVertexes];
texCoords2 = tess.texCoords2[numVertexes];
color = ( unsigned char * ) &tess.vertexColors[numVertexes];
needsNormal = tess.shader->needsNormal;
for ( i = 0 ; i < rows ; i++ ) {
for ( j = 0 ; j < lodWidth ; j++ ) {
dv = cv->verts + heightTable[ used + i ] * cv->width
+ widthTable[ j ];
#if idSSE2
const __m128i xmmP = _mm_loadu_si128((const __m128i*)dv->xyz);
const __m128i xmmT1 = _mm_loadu_si128((const __m128i*)dv->st);
const __m128i xmmN = _mm_loadu_si128((const __m128i*)dv->normal);
const __m128i xmmT2 = _mm_shuffle_epi32(xmmT1, (2 << 0) | (3 << 2) | (0 << 4) | (1 << 6));
_mm_storeu_si128((__m128i*)xyz, xmmP);
_mm_storeu_si128((__m128i*)normal, xmmN);
_mm_storel_epi64((__m128i*)texCoords, xmmT1);
_mm_storel_epi64((__m128i*)texCoords2, xmmT2);
*(uint32_t*)color = *(uint32_t*)dv->color;
#elif defined Q3_LITTLE_ENDIAN
*(uint64_t*)&xyz[0] = *(uint64_t*)&dv->xyz[0];
xyz[2] = dv->xyz[2];
*(uint64_t*)&texCoords[0] = *(uint64_t*)&dv->st[0];
*(uint64_t*)&texCoords2[0] = *(uint64_t*)&dv->lightmap[0];
*(uint64_t*)&normal[0] = *(uint64_t*)&dv->normal[0];
normal[2] = dv->normal[2];
*(uint32_t*)color = *(uint32_t*)dv->color;
#else
xyz[0] = dv->xyz[0];
xyz[1] = dv->xyz[1];
xyz[2] = dv->xyz[2];
texCoords[0] = dv->st[0];
texCoords[1] = dv->st[1];
texCoords[2] = dv->lightmap[0];
texCoords[3] = dv->lightmap[1];
if ( needsNormal ) {
normal[0] = dv->normal[0];
normal[1] = dv->normal[1];
normal[2] = dv->normal[2];
}
* ( unsigned int * ) color = * ( unsigned int * ) dv->color;
texCoords2[0] = dv->lightmap[0];
texCoords2[1] = dv->lightmap[1];
normal[0] = dv->normal[0];
normal[1] = dv->normal[1];
normal[2] = dv->normal[2];
color[0] = dv->color[0];
color[1] = dv->color[1];
color[2] = dv->color[2];
color[3] = dv->color[3];
#endif
xyz += 4;
normal += 4;
texCoords += 4;
texCoords += 2;
texCoords2 += 2;
color += 4;
}
}

View file

@ -331,7 +331,7 @@ static void R_AddLitSurface( msurface_t* surf, const dlight_t* light )
if ( surf->shader->surfaceFlags & (SURF_NODLIGHT | SURF_SKY) )
return;
if ( surf->shader->sort != SS_OPAQUE )
if ( surf->shader->sort < SS_OPAQUE )
return;
if ( surf->lightCount == tr.lightCount )

File diff suppressed because it is too large Load diff

View file

@ -1,631 +0,0 @@
#ifndef __wglext_h_
#define __wglext_h_
#ifdef __cplusplus
extern "C" {
#endif
/*
** License Applicability. Except to the extent portions of this file are
** made subject to an alternative license as permitted in the SGI Free
** Software License B, Version 1.1 (the "License"), the contents of this
** file are subject only to the provisions of the License. You may not use
** this file except in compliance with the License. You may obtain a copy
** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600
** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at:
**
** http://oss.sgi.com/projects/FreeB
**
** Note that, as provided in the License, the Software is distributed on an
** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS
** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND
** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A
** PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
**
** Original Code. The Original Code is: OpenGL Sample Implementation,
** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics,
** Inc. The Original Code is Copyright (c) 1991-2004 Silicon Graphics, Inc.
** Copyright in any portions created by third parties is as indicated
** elsewhere herein. All Rights Reserved.
**
** Additional Notice Provisions: This software was created using the
** OpenGL(R) version 1.2.1 Sample Implementation published by SGI, but has
** not been independently verified as being compliant with the OpenGL(R)
** version 1.2.1 Specification.
*/
#if defined(_WIN32) && !defined(APIENTRY) && !defined(__CYGWIN__) && !defined(__SCITECH_SNAP__)
#define WIN32_LEAN_AND_MEAN 1
#include <windows.h>
#endif
#ifndef APIENTRY
#define APIENTRY
#endif
#ifndef APIENTRYP
#define APIENTRYP APIENTRY *
#endif
#ifndef GLAPI
#define GLAPI extern
#endif
/*************************************************************/
/* Header file version number */
/* wglext.h last updated 2005/01/07 */
/* Current version at http://oss.sgi.com/projects/ogl-sample/registry/ */
#define WGL_WGLEXT_VERSION 6
#ifndef WGL_ARB_buffer_region
#define WGL_FRONT_COLOR_BUFFER_BIT_ARB 0x00000001
#define WGL_BACK_COLOR_BUFFER_BIT_ARB 0x00000002
#define WGL_DEPTH_BUFFER_BIT_ARB 0x00000004
#define WGL_STENCIL_BUFFER_BIT_ARB 0x00000008
#endif
#ifndef WGL_ARB_multisample
#define WGL_SAMPLE_BUFFERS_ARB 0x2041
#define WGL_SAMPLES_ARB 0x2042
#endif
#ifndef WGL_ARB_extensions_string
#endif
#ifndef WGL_ARB_pixel_format
#define WGL_NUMBER_PIXEL_FORMATS_ARB 0x2000
#define WGL_DRAW_TO_WINDOW_ARB 0x2001
#define WGL_DRAW_TO_BITMAP_ARB 0x2002
#define WGL_ACCELERATION_ARB 0x2003
#define WGL_NEED_PALETTE_ARB 0x2004
#define WGL_NEED_SYSTEM_PALETTE_ARB 0x2005
#define WGL_SWAP_LAYER_BUFFERS_ARB 0x2006
#define WGL_SWAP_METHOD_ARB 0x2007
#define WGL_NUMBER_OVERLAYS_ARB 0x2008
#define WGL_NUMBER_UNDERLAYS_ARB 0x2009
#define WGL_TRANSPARENT_ARB 0x200A
#define WGL_TRANSPARENT_RED_VALUE_ARB 0x2037
#define WGL_TRANSPARENT_GREEN_VALUE_ARB 0x2038
#define WGL_TRANSPARENT_BLUE_VALUE_ARB 0x2039
#define WGL_TRANSPARENT_ALPHA_VALUE_ARB 0x203A
#define WGL_TRANSPARENT_INDEX_VALUE_ARB 0x203B
#define WGL_SHARE_DEPTH_ARB 0x200C
#define WGL_SHARE_STENCIL_ARB 0x200D
#define WGL_SHARE_ACCUM_ARB 0x200E
#define WGL_SUPPORT_GDI_ARB 0x200F
#define WGL_SUPPORT_OPENGL_ARB 0x2010
#define WGL_DOUBLE_BUFFER_ARB 0x2011
#define WGL_STEREO_ARB 0x2012
#define WGL_PIXEL_TYPE_ARB 0x2013
#define WGL_COLOR_BITS_ARB 0x2014
#define WGL_RED_BITS_ARB 0x2015
#define WGL_RED_SHIFT_ARB 0x2016
#define WGL_GREEN_BITS_ARB 0x2017
#define WGL_GREEN_SHIFT_ARB 0x2018
#define WGL_BLUE_BITS_ARB 0x2019
#define WGL_BLUE_SHIFT_ARB 0x201A
#define WGL_ALPHA_BITS_ARB 0x201B
#define WGL_ALPHA_SHIFT_ARB 0x201C
#define WGL_ACCUM_BITS_ARB 0x201D
#define WGL_ACCUM_RED_BITS_ARB 0x201E
#define WGL_ACCUM_GREEN_BITS_ARB 0x201F
#define WGL_ACCUM_BLUE_BITS_ARB 0x2020
#define WGL_ACCUM_ALPHA_BITS_ARB 0x2021
#define WGL_DEPTH_BITS_ARB 0x2022
#define WGL_STENCIL_BITS_ARB 0x2023
#define WGL_AUX_BUFFERS_ARB 0x2024
#define WGL_NO_ACCELERATION_ARB 0x2025
#define WGL_GENERIC_ACCELERATION_ARB 0x2026
#define WGL_FULL_ACCELERATION_ARB 0x2027
#define WGL_SWAP_EXCHANGE_ARB 0x2028
#define WGL_SWAP_COPY_ARB 0x2029
#define WGL_SWAP_UNDEFINED_ARB 0x202A
#define WGL_TYPE_RGBA_ARB 0x202B
#define WGL_TYPE_COLORINDEX_ARB 0x202C
#endif
#ifndef WGL_ARB_make_current_read
#define ERROR_INVALID_PIXEL_TYPE_ARB 0x2043
#define ERROR_INCOMPATIBLE_DEVICE_CONTEXTS_ARB 0x2054
#endif
#ifndef WGL_ARB_pbuffer
#define WGL_DRAW_TO_PBUFFER_ARB 0x202D
#define WGL_MAX_PBUFFER_PIXELS_ARB 0x202E
#define WGL_MAX_PBUFFER_WIDTH_ARB 0x202F
#define WGL_MAX_PBUFFER_HEIGHT_ARB 0x2030
#define WGL_PBUFFER_LARGEST_ARB 0x2033
#define WGL_PBUFFER_WIDTH_ARB 0x2034
#define WGL_PBUFFER_HEIGHT_ARB 0x2035
#define WGL_PBUFFER_LOST_ARB 0x2036
#endif
#ifndef WGL_ARB_render_texture
#define WGL_BIND_TO_TEXTURE_RGB_ARB 0x2070
#define WGL_BIND_TO_TEXTURE_RGBA_ARB 0x2071
#define WGL_TEXTURE_FORMAT_ARB 0x2072
#define WGL_TEXTURE_TARGET_ARB 0x2073
#define WGL_MIPMAP_TEXTURE_ARB 0x2074
#define WGL_TEXTURE_RGB_ARB 0x2075
#define WGL_TEXTURE_RGBA_ARB 0x2076
#define WGL_NO_TEXTURE_ARB 0x2077
#define WGL_TEXTURE_CUBE_MAP_ARB 0x2078
#define WGL_TEXTURE_1D_ARB 0x2079
#define WGL_TEXTURE_2D_ARB 0x207A
#define WGL_MIPMAP_LEVEL_ARB 0x207B
#define WGL_CUBE_MAP_FACE_ARB 0x207C
#define WGL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB 0x207D
#define WGL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB 0x207E
#define WGL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB 0x207F
#define WGL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB 0x2080
#define WGL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB 0x2081
#define WGL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB 0x2082
#define WGL_FRONT_LEFT_ARB 0x2083
#define WGL_FRONT_RIGHT_ARB 0x2084
#define WGL_BACK_LEFT_ARB 0x2085
#define WGL_BACK_RIGHT_ARB 0x2086
#define WGL_AUX0_ARB 0x2087
#define WGL_AUX1_ARB 0x2088
#define WGL_AUX2_ARB 0x2089
#define WGL_AUX3_ARB 0x208A
#define WGL_AUX4_ARB 0x208B
#define WGL_AUX5_ARB 0x208C
#define WGL_AUX6_ARB 0x208D
#define WGL_AUX7_ARB 0x208E
#define WGL_AUX8_ARB 0x208F
#define WGL_AUX9_ARB 0x2090
#endif
#ifndef WGL_ARB_pixel_format_float
#define WGL_TYPE_RGBA_FLOAT_ARB 0x21A0
#endif
#ifndef WGL_EXT_make_current_read
#define ERROR_INVALID_PIXEL_TYPE_EXT 0x2043
#endif
#ifndef WGL_EXT_pixel_format
#define WGL_NUMBER_PIXEL_FORMATS_EXT 0x2000
#define WGL_DRAW_TO_WINDOW_EXT 0x2001
#define WGL_DRAW_TO_BITMAP_EXT 0x2002
#define WGL_ACCELERATION_EXT 0x2003
#define WGL_NEED_PALETTE_EXT 0x2004
#define WGL_NEED_SYSTEM_PALETTE_EXT 0x2005
#define WGL_SWAP_LAYER_BUFFERS_EXT 0x2006
#define WGL_SWAP_METHOD_EXT 0x2007
#define WGL_NUMBER_OVERLAYS_EXT 0x2008
#define WGL_NUMBER_UNDERLAYS_EXT 0x2009
#define WGL_TRANSPARENT_EXT 0x200A
#define WGL_TRANSPARENT_VALUE_EXT 0x200B
#define WGL_SHARE_DEPTH_EXT 0x200C
#define WGL_SHARE_STENCIL_EXT 0x200D
#define WGL_SHARE_ACCUM_EXT 0x200E
#define WGL_SUPPORT_GDI_EXT 0x200F
#define WGL_SUPPORT_OPENGL_EXT 0x2010
#define WGL_DOUBLE_BUFFER_EXT 0x2011
#define WGL_STEREO_EXT 0x2012
#define WGL_PIXEL_TYPE_EXT 0x2013
#define WGL_COLOR_BITS_EXT 0x2014
#define WGL_RED_BITS_EXT 0x2015
#define WGL_RED_SHIFT_EXT 0x2016
#define WGL_GREEN_BITS_EXT 0x2017
#define WGL_GREEN_SHIFT_EXT 0x2018
#define WGL_BLUE_BITS_EXT 0x2019
#define WGL_BLUE_SHIFT_EXT 0x201A
#define WGL_ALPHA_BITS_EXT 0x201B
#define WGL_ALPHA_SHIFT_EXT 0x201C
#define WGL_ACCUM_BITS_EXT 0x201D
#define WGL_ACCUM_RED_BITS_EXT 0x201E
#define WGL_ACCUM_GREEN_BITS_EXT 0x201F
#define WGL_ACCUM_BLUE_BITS_EXT 0x2020
#define WGL_ACCUM_ALPHA_BITS_EXT 0x2021
#define WGL_DEPTH_BITS_EXT 0x2022
#define WGL_STENCIL_BITS_EXT 0x2023
#define WGL_AUX_BUFFERS_EXT 0x2024
#define WGL_NO_ACCELERATION_EXT 0x2025
#define WGL_GENERIC_ACCELERATION_EXT 0x2026
#define WGL_FULL_ACCELERATION_EXT 0x2027
#define WGL_SWAP_EXCHANGE_EXT 0x2028
#define WGL_SWAP_COPY_EXT 0x2029
#define WGL_SWAP_UNDEFINED_EXT 0x202A
#define WGL_TYPE_RGBA_EXT 0x202B
#define WGL_TYPE_COLORINDEX_EXT 0x202C
#endif
#ifndef WGL_EXT_pbuffer
#define WGL_DRAW_TO_PBUFFER_EXT 0x202D
#define WGL_MAX_PBUFFER_PIXELS_EXT 0x202E
#define WGL_MAX_PBUFFER_WIDTH_EXT 0x202F
#define WGL_MAX_PBUFFER_HEIGHT_EXT 0x2030
#define WGL_OPTIMAL_PBUFFER_WIDTH_EXT 0x2031
#define WGL_OPTIMAL_PBUFFER_HEIGHT_EXT 0x2032
#define WGL_PBUFFER_LARGEST_EXT 0x2033
#define WGL_PBUFFER_WIDTH_EXT 0x2034
#define WGL_PBUFFER_HEIGHT_EXT 0x2035
#endif
#ifndef WGL_EXT_depth_float
#define WGL_DEPTH_FLOAT_EXT 0x2040
#endif
#ifndef WGL_3DFX_multisample
#define WGL_SAMPLE_BUFFERS_3DFX 0x2060
#define WGL_SAMPLES_3DFX 0x2061
#endif
#ifndef WGL_EXT_multisample
#define WGL_SAMPLE_BUFFERS_EXT 0x2041
#define WGL_SAMPLES_EXT 0x2042
#endif
#ifndef WGL_I3D_digital_video_control
#define WGL_DIGITAL_VIDEO_CURSOR_ALPHA_FRAMEBUFFER_I3D 0x2050
#define WGL_DIGITAL_VIDEO_CURSOR_ALPHA_VALUE_I3D 0x2051
#define WGL_DIGITAL_VIDEO_CURSOR_INCLUDED_I3D 0x2052
#define WGL_DIGITAL_VIDEO_GAMMA_CORRECTED_I3D 0x2053
#endif
#ifndef WGL_I3D_gamma
#define WGL_GAMMA_TABLE_SIZE_I3D 0x204E
#define WGL_GAMMA_EXCLUDE_DESKTOP_I3D 0x204F
#endif
#ifndef WGL_I3D_genlock
#define WGL_GENLOCK_SOURCE_MULTIVIEW_I3D 0x2044
#define WGL_GENLOCK_SOURCE_EXTENAL_SYNC_I3D 0x2045
#define WGL_GENLOCK_SOURCE_EXTENAL_FIELD_I3D 0x2046
#define WGL_GENLOCK_SOURCE_EXTENAL_TTL_I3D 0x2047
#define WGL_GENLOCK_SOURCE_DIGITAL_SYNC_I3D 0x2048
#define WGL_GENLOCK_SOURCE_DIGITAL_FIELD_I3D 0x2049
#define WGL_GENLOCK_SOURCE_EDGE_FALLING_I3D 0x204A
#define WGL_GENLOCK_SOURCE_EDGE_RISING_I3D 0x204B
#define WGL_GENLOCK_SOURCE_EDGE_BOTH_I3D 0x204C
#endif
#ifndef WGL_I3D_image_buffer
#define WGL_IMAGE_BUFFER_MIN_ACCESS_I3D 0x00000001
#define WGL_IMAGE_BUFFER_LOCK_I3D 0x00000002
#endif
#ifndef WGL_I3D_swap_frame_lock
#endif
#ifndef WGL_NV_render_depth_texture
#define WGL_BIND_TO_TEXTURE_DEPTH_NV 0x20A3
#define WGL_BIND_TO_TEXTURE_RECTANGLE_DEPTH_NV 0x20A4
#define WGL_DEPTH_TEXTURE_FORMAT_NV 0x20A5
#define WGL_TEXTURE_DEPTH_COMPONENT_NV 0x20A6
#define WGL_DEPTH_COMPONENT_NV 0x20A7
#endif
#ifndef WGL_NV_render_texture_rectangle
#define WGL_BIND_TO_TEXTURE_RECTANGLE_RGB_NV 0x20A0
#define WGL_BIND_TO_TEXTURE_RECTANGLE_RGBA_NV 0x20A1
#define WGL_TEXTURE_RECTANGLE_NV 0x20A2
#endif
#ifndef WGL_ATI_pixel_format_float
#define WGL_TYPE_RGBA_FLOAT_ATI 0x21A0
#endif
#ifndef WGL_NV_float_buffer
#define WGL_FLOAT_COMPONENTS_NV 0x20B0
#define WGL_BIND_TO_TEXTURE_RECTANGLE_FLOAT_R_NV 0x20B1
#define WGL_BIND_TO_TEXTURE_RECTANGLE_FLOAT_RG_NV 0x20B2
#define WGL_BIND_TO_TEXTURE_RECTANGLE_FLOAT_RGB_NV 0x20B3
#define WGL_BIND_TO_TEXTURE_RECTANGLE_FLOAT_RGBA_NV 0x20B4
#define WGL_TEXTURE_FLOAT_R_NV 0x20B5
#define WGL_TEXTURE_FLOAT_RG_NV 0x20B6
#define WGL_TEXTURE_FLOAT_RGB_NV 0x20B7
#define WGL_TEXTURE_FLOAT_RGBA_NV 0x20B8
#endif
/*************************************************************/
#ifndef WGL_ARB_pbuffer
DECLARE_HANDLE(HPBUFFERARB);
#endif
#ifndef WGL_EXT_pbuffer
DECLARE_HANDLE(HPBUFFEREXT);
#endif
#ifndef WGL_ARB_buffer_region
#define WGL_ARB_buffer_region 1
#ifdef WGL_WGLEXT_PROTOTYPES
extern HANDLE WINAPI wglCreateBufferRegionARB (HDC, int, UINT);
extern VOID WINAPI wglDeleteBufferRegionARB (HANDLE);
extern BOOL WINAPI wglSaveBufferRegionARB (HANDLE, int, int, int, int);
extern BOOL WINAPI wglRestoreBufferRegionARB (HANDLE, int, int, int, int, int, int);
#endif /* WGL_WGLEXT_PROTOTYPES */
typedef HANDLE (WINAPI * PFNWGLCREATEBUFFERREGIONARBPROC) (HDC hDC, int iLayerPlane, UINT uType);
typedef VOID (WINAPI * PFNWGLDELETEBUFFERREGIONARBPROC) (HANDLE hRegion);
typedef BOOL (WINAPI * PFNWGLSAVEBUFFERREGIONARBPROC) (HANDLE hRegion, int x, int y, int width, int height);
typedef BOOL (WINAPI * PFNWGLRESTOREBUFFERREGIONARBPROC) (HANDLE hRegion, int x, int y, int width, int height, int xSrc, int ySrc);
#endif
#ifndef WGL_ARB_multisample
#define WGL_ARB_multisample 1
#endif
#ifndef WGL_ARB_extensions_string
#define WGL_ARB_extensions_string 1
#ifdef WGL_WGLEXT_PROTOTYPES
extern const char * WINAPI wglGetExtensionsStringARB (HDC);
#endif /* WGL_WGLEXT_PROTOTYPES */
typedef const char * (WINAPI * PFNWGLGETEXTENSIONSSTRINGARBPROC) (HDC hdc);
#endif
#ifndef WGL_ARB_pixel_format
#define WGL_ARB_pixel_format 1
#ifdef WGL_WGLEXT_PROTOTYPES
extern BOOL WINAPI wglGetPixelFormatAttribivARB (HDC, int, int, UINT, const int *, int *);
extern BOOL WINAPI wglGetPixelFormatAttribfvARB (HDC, int, int, UINT, const int *, FLOAT *);
extern BOOL WINAPI wglChoosePixelFormatARB (HDC, const int *, const FLOAT *, UINT, int *, UINT *);
#endif /* WGL_WGLEXT_PROTOTYPES */
typedef BOOL (WINAPI * PFNWGLGETPIXELFORMATATTRIBIVARBPROC) (HDC hdc, int iPixelFormat, int iLayerPlane, UINT nAttributes, const int *piAttributes, int *piValues);
typedef BOOL (WINAPI * PFNWGLGETPIXELFORMATATTRIBFVARBPROC) (HDC hdc, int iPixelFormat, int iLayerPlane, UINT nAttributes, const int *piAttributes, FLOAT *pfValues);
typedef BOOL (WINAPI * PFNWGLCHOOSEPIXELFORMATARBPROC) (HDC hdc, const int *piAttribIList, const FLOAT *pfAttribFList, UINT nMaxFormats, int *piFormats, UINT *nNumFormats);
#endif
#ifndef WGL_ARB_make_current_read
#define WGL_ARB_make_current_read 1
#ifdef WGL_WGLEXT_PROTOTYPES
extern BOOL WINAPI wglMakeContextCurrentARB (HDC, HDC, HGLRC);
extern HDC WINAPI wglGetCurrentReadDCARB (void);
#endif /* WGL_WGLEXT_PROTOTYPES */
typedef BOOL (WINAPI * PFNWGLMAKECONTEXTCURRENTARBPROC) (HDC hDrawDC, HDC hReadDC, HGLRC hglrc);
typedef HDC (WINAPI * PFNWGLGETCURRENTREADDCARBPROC) (void);
#endif
#ifndef WGL_ARB_pbuffer
#define WGL_ARB_pbuffer 1
#ifdef WGL_WGLEXT_PROTOTYPES
extern HPBUFFERARB WINAPI wglCreatePbufferARB (HDC, int, int, int, const int *);
extern HDC WINAPI wglGetPbufferDCARB (HPBUFFERARB);
extern int WINAPI wglReleasePbufferDCARB (HPBUFFERARB, HDC);
extern BOOL WINAPI wglDestroyPbufferARB (HPBUFFERARB);
extern BOOL WINAPI wglQueryPbufferARB (HPBUFFERARB, int, int *);
#endif /* WGL_WGLEXT_PROTOTYPES */
typedef HPBUFFERARB (WINAPI * PFNWGLCREATEPBUFFERARBPROC) (HDC hDC, int iPixelFormat, int iWidth, int iHeight, const int *piAttribList);
typedef HDC (WINAPI * PFNWGLGETPBUFFERDCARBPROC) (HPBUFFERARB hPbuffer);
typedef int (WINAPI * PFNWGLRELEASEPBUFFERDCARBPROC) (HPBUFFERARB hPbuffer, HDC hDC);
typedef BOOL (WINAPI * PFNWGLDESTROYPBUFFERARBPROC) (HPBUFFERARB hPbuffer);
typedef BOOL (WINAPI * PFNWGLQUERYPBUFFERARBPROC) (HPBUFFERARB hPbuffer, int iAttribute, int *piValue);
#endif
#ifndef WGL_ARB_render_texture
#define WGL_ARB_render_texture 1
#ifdef WGL_WGLEXT_PROTOTYPES
extern BOOL WINAPI wglBindTexImageARB (HPBUFFERARB, int);
extern BOOL WINAPI wglReleaseTexImageARB (HPBUFFERARB, int);
extern BOOL WINAPI wglSetPbufferAttribARB (HPBUFFERARB, const int *);
#endif /* WGL_WGLEXT_PROTOTYPES */
typedef BOOL (WINAPI * PFNWGLBINDTEXIMAGEARBPROC) (HPBUFFERARB hPbuffer, int iBuffer);
typedef BOOL (WINAPI * PFNWGLRELEASETEXIMAGEARBPROC) (HPBUFFERARB hPbuffer, int iBuffer);
typedef BOOL (WINAPI * PFNWGLSETPBUFFERATTRIBARBPROC) (HPBUFFERARB hPbuffer, const int *piAttribList);
#endif
#ifndef WGL_ARB_pixel_format_float
#define WGL_ARB_pixel_format_float 1
#endif
#ifndef WGL_EXT_display_color_table
#define WGL_EXT_display_color_table 1
#ifdef WGL_WGLEXT_PROTOTYPES
extern GLboolean WINAPI wglCreateDisplayColorTableEXT (GLushort);
extern GLboolean WINAPI wglLoadDisplayColorTableEXT (const GLushort *, GLuint);
extern GLboolean WINAPI wglBindDisplayColorTableEXT (GLushort);
extern VOID WINAPI wglDestroyDisplayColorTableEXT (GLushort);
#endif /* WGL_WGLEXT_PROTOTYPES */
typedef GLboolean (WINAPI * PFNWGLCREATEDISPLAYCOLORTABLEEXTPROC) (GLushort id);
typedef GLboolean (WINAPI * PFNWGLLOADDISPLAYCOLORTABLEEXTPROC) (const GLushort *table, GLuint length);
typedef GLboolean (WINAPI * PFNWGLBINDDISPLAYCOLORTABLEEXTPROC) (GLushort id);
typedef VOID (WINAPI * PFNWGLDESTROYDISPLAYCOLORTABLEEXTPROC) (GLushort id);
#endif
#ifndef WGL_EXT_extensions_string
#define WGL_EXT_extensions_string 1
#ifdef WGL_WGLEXT_PROTOTYPES
extern const char * WINAPI wglGetExtensionsStringEXT (void);
#endif /* WGL_WGLEXT_PROTOTYPES */
typedef const char * (WINAPI * PFNWGLGETEXTENSIONSSTRINGEXTPROC) (void);
#endif
#ifndef WGL_EXT_make_current_read
#define WGL_EXT_make_current_read 1
#ifdef WGL_WGLEXT_PROTOTYPES
extern BOOL WINAPI wglMakeContextCurrentEXT (HDC, HDC, HGLRC);
extern HDC WINAPI wglGetCurrentReadDCEXT (void);
#endif /* WGL_WGLEXT_PROTOTYPES */
typedef BOOL (WINAPI * PFNWGLMAKECONTEXTCURRENTEXTPROC) (HDC hDrawDC, HDC hReadDC, HGLRC hglrc);
typedef HDC (WINAPI * PFNWGLGETCURRENTREADDCEXTPROC) (void);
#endif
#ifndef WGL_EXT_pbuffer
#define WGL_EXT_pbuffer 1
#ifdef WGL_WGLEXT_PROTOTYPES
extern HPBUFFEREXT WINAPI wglCreatePbufferEXT (HDC, int, int, int, const int *);
extern HDC WINAPI wglGetPbufferDCEXT (HPBUFFEREXT);
extern int WINAPI wglReleasePbufferDCEXT (HPBUFFEREXT, HDC);
extern BOOL WINAPI wglDestroyPbufferEXT (HPBUFFEREXT);
extern BOOL WINAPI wglQueryPbufferEXT (HPBUFFEREXT, int, int *);
#endif /* WGL_WGLEXT_PROTOTYPES */
typedef HPBUFFEREXT (WINAPI * PFNWGLCREATEPBUFFEREXTPROC) (HDC hDC, int iPixelFormat, int iWidth, int iHeight, const int *piAttribList);
typedef HDC (WINAPI * PFNWGLGETPBUFFERDCEXTPROC) (HPBUFFEREXT hPbuffer);
typedef int (WINAPI * PFNWGLRELEASEPBUFFERDCEXTPROC) (HPBUFFEREXT hPbuffer, HDC hDC);
typedef BOOL (WINAPI * PFNWGLDESTROYPBUFFEREXTPROC) (HPBUFFEREXT hPbuffer);
typedef BOOL (WINAPI * PFNWGLQUERYPBUFFEREXTPROC) (HPBUFFEREXT hPbuffer, int iAttribute, int *piValue);
#endif
#ifndef WGL_EXT_pixel_format
#define WGL_EXT_pixel_format 1
#ifdef WGL_WGLEXT_PROTOTYPES
extern BOOL WINAPI wglGetPixelFormatAttribivEXT (HDC, int, int, UINT, int *, int *);
extern BOOL WINAPI wglGetPixelFormatAttribfvEXT (HDC, int, int, UINT, int *, FLOAT *);
extern BOOL WINAPI wglChoosePixelFormatEXT (HDC, const int *, const FLOAT *, UINT, int *, UINT *);
#endif /* WGL_WGLEXT_PROTOTYPES */
typedef BOOL (WINAPI * PFNWGLGETPIXELFORMATATTRIBIVEXTPROC) (HDC hdc, int iPixelFormat, int iLayerPlane, UINT nAttributes, int *piAttributes, int *piValues);
typedef BOOL (WINAPI * PFNWGLGETPIXELFORMATATTRIBFVEXTPROC) (HDC hdc, int iPixelFormat, int iLayerPlane, UINT nAttributes, int *piAttributes, FLOAT *pfValues);
typedef BOOL (WINAPI * PFNWGLCHOOSEPIXELFORMATEXTPROC) (HDC hdc, const int *piAttribIList, const FLOAT *pfAttribFList, UINT nMaxFormats, int *piFormats, UINT *nNumFormats);
#endif
#ifndef WGL_EXT_swap_control
#define WGL_EXT_swap_control 1
#ifdef WGL_WGLEXT_PROTOTYPES
extern BOOL WINAPI wglSwapIntervalEXT (int);
extern int WINAPI wglGetSwapIntervalEXT (void);
#endif /* WGL_WGLEXT_PROTOTYPES */
typedef BOOL (WINAPI * PFNWGLSWAPINTERVALEXTPROC) (int interval);
typedef int (WINAPI * PFNWGLGETSWAPINTERVALEXTPROC) (void);
#endif
#ifndef WGL_EXT_depth_float
#define WGL_EXT_depth_float 1
#endif
#ifndef WGL_NV_vertex_array_range
#define WGL_NV_vertex_array_range 1
#ifdef WGL_WGLEXT_PROTOTYPES
extern void* WINAPI wglAllocateMemoryNV (GLsizei, GLfloat, GLfloat, GLfloat);
extern void WINAPI wglFreeMemoryNV (void *);
#endif /* WGL_WGLEXT_PROTOTYPES */
typedef void* (WINAPI * PFNWGLALLOCATEMEMORYNVPROC) (GLsizei size, GLfloat readfreq, GLfloat writefreq, GLfloat priority);
typedef void (WINAPI * PFNWGLFREEMEMORYNVPROC) (void *pointer);
#endif
#ifndef WGL_3DFX_multisample
#define WGL_3DFX_multisample 1
#endif
#ifndef WGL_EXT_multisample
#define WGL_EXT_multisample 1
#endif
#ifndef WGL_OML_sync_control
#define WGL_OML_sync_control 1
#ifdef WGL_WGLEXT_PROTOTYPES
extern BOOL WINAPI wglGetSyncValuesOML (HDC, INT64 *, INT64 *, INT64 *);
extern BOOL WINAPI wglGetMscRateOML (HDC, INT32 *, INT32 *);
extern INT64 WINAPI wglSwapBuffersMscOML (HDC, INT64, INT64, INT64);
extern INT64 WINAPI wglSwapLayerBuffersMscOML (HDC, int, INT64, INT64, INT64);
extern BOOL WINAPI wglWaitForMscOML (HDC, INT64, INT64, INT64, INT64 *, INT64 *, INT64 *);
extern BOOL WINAPI wglWaitForSbcOML (HDC, INT64, INT64 *, INT64 *, INT64 *);
#endif /* WGL_WGLEXT_PROTOTYPES */
typedef BOOL (WINAPI * PFNWGLGETSYNCVALUESOMLPROC) (HDC hdc, INT64 *ust, INT64 *msc, INT64 *sbc);
typedef BOOL (WINAPI * PFNWGLGETMSCRATEOMLPROC) (HDC hdc, INT32 *numerator, INT32 *denominator);
typedef INT64 (WINAPI * PFNWGLSWAPBUFFERSMSCOMLPROC) (HDC hdc, INT64 target_msc, INT64 divisor, INT64 remainder);
typedef INT64 (WINAPI * PFNWGLSWAPLAYERBUFFERSMSCOMLPROC) (HDC hdc, int fuPlanes, INT64 target_msc, INT64 divisor, INT64 remainder);
typedef BOOL (WINAPI * PFNWGLWAITFORMSCOMLPROC) (HDC hdc, INT64 target_msc, INT64 divisor, INT64 remainder, INT64 *ust, INT64 *msc, INT64 *sbc);
typedef BOOL (WINAPI * PFNWGLWAITFORSBCOMLPROC) (HDC hdc, INT64 target_sbc, INT64 *ust, INT64 *msc, INT64 *sbc);
#endif
#ifndef WGL_I3D_digital_video_control
#define WGL_I3D_digital_video_control 1
#ifdef WGL_WGLEXT_PROTOTYPES
extern BOOL WINAPI wglGetDigitalVideoParametersI3D (HDC, int, int *);
extern BOOL WINAPI wglSetDigitalVideoParametersI3D (HDC, int, const int *);
#endif /* WGL_WGLEXT_PROTOTYPES */
typedef BOOL (WINAPI * PFNWGLGETDIGITALVIDEOPARAMETERSI3DPROC) (HDC hDC, int iAttribute, int *piValue);
typedef BOOL (WINAPI * PFNWGLSETDIGITALVIDEOPARAMETERSI3DPROC) (HDC hDC, int iAttribute, const int *piValue);
#endif
#ifndef WGL_I3D_gamma
#define WGL_I3D_gamma 1
#ifdef WGL_WGLEXT_PROTOTYPES
extern BOOL WINAPI wglGetGammaTableParametersI3D (HDC, int, int *);
extern BOOL WINAPI wglSetGammaTableParametersI3D (HDC, int, const int *);
extern BOOL WINAPI wglGetGammaTableI3D (HDC, int, USHORT *, USHORT *, USHORT *);
extern BOOL WINAPI wglSetGammaTableI3D (HDC, int, const USHORT *, const USHORT *, const USHORT *);
#endif /* WGL_WGLEXT_PROTOTYPES */
typedef BOOL (WINAPI * PFNWGLGETGAMMATABLEPARAMETERSI3DPROC) (HDC hDC, int iAttribute, int *piValue);
typedef BOOL (WINAPI * PFNWGLSETGAMMATABLEPARAMETERSI3DPROC) (HDC hDC, int iAttribute, const int *piValue);
typedef BOOL (WINAPI * PFNWGLGETGAMMATABLEI3DPROC) (HDC hDC, int iEntries, USHORT *puRed, USHORT *puGreen, USHORT *puBlue);
typedef BOOL (WINAPI * PFNWGLSETGAMMATABLEI3DPROC) (HDC hDC, int iEntries, const USHORT *puRed, const USHORT *puGreen, const USHORT *puBlue);
#endif
#ifndef WGL_I3D_genlock
#define WGL_I3D_genlock 1
#ifdef WGL_WGLEXT_PROTOTYPES
extern BOOL WINAPI wglEnableGenlockI3D (HDC);
extern BOOL WINAPI wglDisableGenlockI3D (HDC);
extern BOOL WINAPI wglIsEnabledGenlockI3D (HDC, BOOL *);
extern BOOL WINAPI wglGenlockSourceI3D (HDC, UINT);
extern BOOL WINAPI wglGetGenlockSourceI3D (HDC, UINT *);
extern BOOL WINAPI wglGenlockSourceEdgeI3D (HDC, UINT);
extern BOOL WINAPI wglGetGenlockSourceEdgeI3D (HDC, UINT *);
extern BOOL WINAPI wglGenlockSampleRateI3D (HDC, UINT);
extern BOOL WINAPI wglGetGenlockSampleRateI3D (HDC, UINT *);
extern BOOL WINAPI wglGenlockSourceDelayI3D (HDC, UINT);
extern BOOL WINAPI wglGetGenlockSourceDelayI3D (HDC, UINT *);
extern BOOL WINAPI wglQueryGenlockMaxSourceDelayI3D (HDC, UINT *, UINT *);
#endif /* WGL_WGLEXT_PROTOTYPES */
typedef BOOL (WINAPI * PFNWGLENABLEGENLOCKI3DPROC) (HDC hDC);
typedef BOOL (WINAPI * PFNWGLDISABLEGENLOCKI3DPROC) (HDC hDC);
typedef BOOL (WINAPI * PFNWGLISENABLEDGENLOCKI3DPROC) (HDC hDC, BOOL *pFlag);
typedef BOOL (WINAPI * PFNWGLGENLOCKSOURCEI3DPROC) (HDC hDC, UINT uSource);
typedef BOOL (WINAPI * PFNWGLGETGENLOCKSOURCEI3DPROC) (HDC hDC, UINT *uSource);
typedef BOOL (WINAPI * PFNWGLGENLOCKSOURCEEDGEI3DPROC) (HDC hDC, UINT uEdge);
typedef BOOL (WINAPI * PFNWGLGETGENLOCKSOURCEEDGEI3DPROC) (HDC hDC, UINT *uEdge);
typedef BOOL (WINAPI * PFNWGLGENLOCKSAMPLERATEI3DPROC) (HDC hDC, UINT uRate);
typedef BOOL (WINAPI * PFNWGLGETGENLOCKSAMPLERATEI3DPROC) (HDC hDC, UINT *uRate);
typedef BOOL (WINAPI * PFNWGLGENLOCKSOURCEDELAYI3DPROC) (HDC hDC, UINT uDelay);
typedef BOOL (WINAPI * PFNWGLGETGENLOCKSOURCEDELAYI3DPROC) (HDC hDC, UINT *uDelay);
typedef BOOL (WINAPI * PFNWGLQUERYGENLOCKMAXSOURCEDELAYI3DPROC) (HDC hDC, UINT *uMaxLineDelay, UINT *uMaxPixelDelay);
#endif
#ifndef WGL_I3D_image_buffer
#define WGL_I3D_image_buffer 1
#ifdef WGL_WGLEXT_PROTOTYPES
extern LPVOID WINAPI wglCreateImageBufferI3D (HDC, DWORD, UINT);
extern BOOL WINAPI wglDestroyImageBufferI3D (HDC, LPVOID);
extern BOOL WINAPI wglAssociateImageBufferEventsI3D (HDC, const HANDLE *, const LPVOID *, const DWORD *, UINT);
extern BOOL WINAPI wglReleaseImageBufferEventsI3D (HDC, const LPVOID *, UINT);
#endif /* WGL_WGLEXT_PROTOTYPES */
typedef LPVOID (WINAPI * PFNWGLCREATEIMAGEBUFFERI3DPROC) (HDC hDC, DWORD dwSize, UINT uFlags);
typedef BOOL (WINAPI * PFNWGLDESTROYIMAGEBUFFERI3DPROC) (HDC hDC, LPVOID pAddress);
typedef BOOL (WINAPI * PFNWGLASSOCIATEIMAGEBUFFEREVENTSI3DPROC) (HDC hDC, const HANDLE *pEvent, const LPVOID *pAddress, const DWORD *pSize, UINT count);
typedef BOOL (WINAPI * PFNWGLRELEASEIMAGEBUFFEREVENTSI3DPROC) (HDC hDC, const LPVOID *pAddress, UINT count);
#endif
#ifndef WGL_I3D_swap_frame_lock
#define WGL_I3D_swap_frame_lock 1
#ifdef WGL_WGLEXT_PROTOTYPES
extern BOOL WINAPI wglEnableFrameLockI3D (void);
extern BOOL WINAPI wglDisableFrameLockI3D (void);
extern BOOL WINAPI wglIsEnabledFrameLockI3D (BOOL *);
extern BOOL WINAPI wglQueryFrameLockMasterI3D (BOOL *);
#endif /* WGL_WGLEXT_PROTOTYPES */
typedef BOOL (WINAPI * PFNWGLENABLEFRAMELOCKI3DPROC) (void);
typedef BOOL (WINAPI * PFNWGLDISABLEFRAMELOCKI3DPROC) (void);
typedef BOOL (WINAPI * PFNWGLISENABLEDFRAMELOCKI3DPROC) (BOOL *pFlag);
typedef BOOL (WINAPI * PFNWGLQUERYFRAMELOCKMASTERI3DPROC) (BOOL *pFlag);
#endif
#ifndef WGL_I3D_swap_frame_usage
#define WGL_I3D_swap_frame_usage 1
#ifdef WGL_WGLEXT_PROTOTYPES
extern BOOL WINAPI wglGetFrameUsageI3D (float *);
extern BOOL WINAPI wglBeginFrameTrackingI3D (void);
extern BOOL WINAPI wglEndFrameTrackingI3D (void);
extern BOOL WINAPI wglQueryFrameTrackingI3D (DWORD *, DWORD *, float *);
#endif /* WGL_WGLEXT_PROTOTYPES */
typedef BOOL (WINAPI * PFNWGLGETFRAMEUSAGEI3DPROC) (float *pUsage);
typedef BOOL (WINAPI * PFNWGLBEGINFRAMETRACKINGI3DPROC) (void);
typedef BOOL (WINAPI * PFNWGLENDFRAMETRACKINGI3DPROC) (void);
typedef BOOL (WINAPI * PFNWGLQUERYFRAMETRACKINGI3DPROC) (DWORD *pFrameCount, DWORD *pMissedFrames, float *pLastMissedUsage);
#endif
#ifndef WGL_ATI_pixel_format_float
#define WGL_ATI_pixel_format_float 1
#endif
#ifndef WGL_NV_float_buffer
#define WGL_NV_float_buffer 1
#endif
#ifdef __cplusplus
}
#endif
#endif

View file

@ -26,9 +26,10 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
** OpenGL refresh. When a port is being made the following functions
** must be implemented by the port:
**
** Sys_GL_EndFrame
** Sys_GL_Init
** Sys_GL_Shutdown
** Sys_V_EndFrame
** Sys_V_Init
** Sys_V_Shutdown
** Sys_V_IsVSynced
**
** Note that the GLW_xxx functions are Windows specific GL-subsystem
** related functions that are relevant ONLY to win_glimp.c
@ -39,10 +40,12 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#endif
#include "../renderer/tr_local.h"
#include "../client/client.h"
#include "resource.h"
#include "glw_win.h"
#include "wglext.h"
#include "win_local.h"
#include "GL/glew.h"
#include "GL/wglew.h"
#include "glw_win.h"
#define TRY_PFD_SUCCESS 0
@ -50,6 +53,20 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#define TRY_PFD_FAIL_HARD 2
glwstate_t glw_state;
static galId_t win_galId;
static qbool WIN_UsingOpenGL()
{
switch ( win_galId )
{
case GAL_GL2:
case GAL_GL3:
return qtrue;
default:
return qfalse;
}
}
/*
@ -221,6 +238,7 @@ static void GLW_CreatePFD( PIXELFORMATDESCRIPTOR *pPFD )
pPFD->cStencilBits = 8;
}
static int GLW_MakeContext( PIXELFORMATDESCRIPTOR *pPFD )
{
int pixelformat;
@ -262,21 +280,54 @@ static int GLW_MakeContext( PIXELFORMATDESCRIPTOR *pPFD )
//
if ( !glw_state.hGLRC )
{
if ( ( glw_state.hGLRC = qwglCreateContext( glw_state.hDC ) ) == 0 )
if ( ( glw_state.hGLRC = wglCreateContext( glw_state.hDC ) ) == 0 )
{
ri.Printf( PRINT_ALL, "...GL context creation failure\n" );
return TRY_PFD_FAIL_HARD;
}
ri.Printf( PRINT_DEVELOPER, "...GL context created\n" );
if ( !qwglMakeCurrent( glw_state.hDC, glw_state.hGLRC ) )
if ( !wglMakeCurrent( glw_state.hDC, glw_state.hGLRC ) )
{
qwglDeleteContext( glw_state.hGLRC );
wglDeleteContext( glw_state.hGLRC );
glw_state.hGLRC = NULL;
ri.Printf( PRINT_ALL, "...GL context creation currency failure\n" );
return TRY_PFD_FAIL_HARD;
}
ri.Printf( PRINT_DEVELOPER, "...GL context creation made current\n" );
PFNWGLCREATECONTEXTATTRIBSARBPROC const wglCreateContextAttribsARB =
(PFNWGLCREATECONTEXTATTRIBSARBPROC)wglGetProcAddress( "wglCreateContextAttribsARB" );
if ( win_galId == GAL_GL3 && wglCreateContextAttribsARB )
{
const int attribs[] =
{
WGL_CONTEXT_MAJOR_VERSION_ARB, 3,
WGL_CONTEXT_MINOR_VERSION_ARB, 2,
WGL_CONTEXT_PROFILE_MASK_ARB, WGL_CONTEXT_CORE_PROFILE_BIT_ARB,
WGL_CONTEXT_FLAGS_ARB, CL_GL_WantDebug() ? WGL_CONTEXT_DEBUG_BIT_ARB : 0,
0
};
const HGLRC hGLRC = wglCreateContextAttribsARB( glw_state.hDC, NULL, attribs );
if ( hGLRC )
{
wglMakeCurrent( NULL, NULL );
wglDeleteContext( glw_state.hGLRC );
wglMakeCurrent( glw_state.hDC, hGLRC );
glw_state.hGLRC = hGLRC;
ri.Printf( PRINT_ALL, "OpenGL version upgraded to: %s\n", (const char*)glGetString( GL_VERSION ) );
}
else
{
ri.Printf( PRINT_WARNING, "wglCreateContextAttribsARB failed\n" );
}
}
if ( glewInit() != GLEW_OK )
ri.Error( ERR_FATAL, "glewInit failed\n" );
CL_GL_Init();
}
return TRY_PFD_SUCCESS;
@ -430,7 +481,7 @@ static qbool GLW_CreateWindow()
ri.Printf( PRINT_DEVELOPER, "...window already present, CreateWindowEx skipped\n" );
}
if ( !GLW_InitDriver() )
if ( WIN_UsingOpenGL() && !GLW_InitDriver() )
{
ShowWindow( g_wv.hWnd, SW_HIDE );
DestroyWindow( g_wv.hWnd );
@ -600,11 +651,30 @@ static qbool GLW_SetMode()
}
static qbool WIN_LoadGL()
{
glw_state.hinstOpenGL = LoadLibraryA( "opengl32.dll" );
if ( glw_state.hinstOpenGL == NULL )
return qfalse;
return qtrue;
}
static void WIN_UnloadGL()
{
if ( glw_state.hinstOpenGL ) {
FreeLibrary( glw_state.hinstOpenGL );
glw_state.hinstOpenGL = NULL;
}
}
static qbool GLW_LoadOpenGL()
{
// only real GL implementations are acceptable
// load the driver and bind our function pointers to it
if ( WIN_LoadGL( "opengl32" ) ) {
if ( WIN_LoadGL() ) {
// create the window and set up the context
if ( GLW_SetMode() ) {
return qtrue;
@ -617,13 +687,19 @@ static qbool GLW_LoadOpenGL()
}
void Sys_GL_EndFrame()
void Sys_V_EndFrame()
{
if ( !WIN_UsingOpenGL() )
return;
if ( r_swapInterval->modified ) {
r_swapInterval->modified = qfalse;
if ( qwglSwapIntervalEXT ) {
qwglSwapIntervalEXT( r_swapInterval->integer );
if ( WGLEW_EXT_swap_control ) {
int swapInterval = r_swapInterval->integer;
if ( swapInterval < 0 && !WGLEW_EXT_swap_control_tear )
swapInterval = -swapInterval;
wglSwapIntervalEXT( swapInterval );
}
}
@ -631,41 +707,37 @@ void Sys_GL_EndFrame()
}
void Sys_GL_Init()
void Sys_V_Init( galId_t type )
{
ri.Printf( PRINT_DEVELOPER, "Initializing OpenGL subsystem\n" );
win_galId = type;
// load appropriate DLL and initialize subsystem
if (!GLW_LoadOpenGL())
ri.Error( ERR_FATAL, "Sys_GL_Init - could not load OpenGL subsystem\n" );
if ( WIN_UsingOpenGL() ) {
ri.Printf( PRINT_DEVELOPER, "Initializing OpenGL subsystem\n" );
// load appropriate DLL and initialize subsystem
if ( !GLW_LoadOpenGL() )
ri.Error( ERR_FATAL, "Sys_V_Init - could not load OpenGL subsystem\n" );
} else {
if ( !GLW_SetMode() )
ri.Error( ERR_FATAL, "Sys_V_Init - could not load Direct3D subsystem\n" );
}
}
void Sys_GL_Shutdown()
static void Sys_ShutdownOpenGL()
{
const char* success[] = { "failed", "success" };
int retVal;
Sys_ShutdownInput();
// FIXME: Brian, we need better fallbacks from partially initialized failures
if ( !qwglMakeCurrent ) {
return;
}
ri.Printf( PRINT_DEVELOPER, "Shutting down OpenGL subsystem\n" );
// set current context to NULL
if ( qwglMakeCurrent )
{
retVal = qwglMakeCurrent( NULL, NULL ) != 0;
ri.Printf( PRINT_DEVELOPER, "...wglMakeCurrent( NULL, NULL ): %s\n", success[retVal] );
}
retVal = wglMakeCurrent( NULL, NULL ) != 0;
ri.Printf( PRINT_DEVELOPER, "...wglMakeCurrent( NULL, NULL ): %s\n", success[retVal] );
// delete HGLRC
if ( glw_state.hGLRC )
{
retVal = qwglDeleteContext( glw_state.hGLRC ) != 0;
retVal = wglDeleteContext( glw_state.hGLRC ) != 0;
ri.Printf( PRINT_DEVELOPER, "...deleting GL context: %s\n", success[retVal] );
glw_state.hGLRC = NULL;
}
@ -677,6 +749,15 @@ void Sys_GL_Shutdown()
ri.Printf( PRINT_DEVELOPER, "...releasing DC: %s\n", success[retVal] );
glw_state.hDC = NULL;
}
}
void Sys_V_Shutdown()
{
Sys_ShutdownInput();
if ( WIN_UsingOpenGL() )
Sys_ShutdownOpenGL();
// destroy window
if ( g_wv.hWnd )
@ -696,7 +777,29 @@ void Sys_GL_Shutdown()
}
// shutdown OpenGL subsystem
WIN_UnloadGL();
if ( WIN_UsingOpenGL() )
WIN_UnloadGL();
}
qbool Sys_V_IsVSynced()
{
// with Direct3D, our swap interval is (normally) respected
if ( !WIN_UsingOpenGL() )
return r_swapInterval->integer != 0;
// with OpenGL, our request is often ignored (driver control panel overrides)
// unfortunately, the value returned here might not be what we want either...
if ( WGLEW_EXT_swap_control )
{
const int interval = wglGetSwapIntervalEXT();
if ( WGLEW_EXT_swap_control_tear )
return interval != 0;
else
return interval > 0;
}
return qfalse;
}

View file

@ -57,12 +57,6 @@ void WIN_InstallExceptionHandlers();
void WIN_RegisterExceptionCommands();
void WIN_EndTimePeriod();
// opening OpenGL and loading core functions
extern "C" {
qbool WIN_LoadGL( const char* dllName );
void WIN_UnloadGL();
}
#define MAX_MONITOR_COUNT 16
typedef struct {

File diff suppressed because it is too large Load diff

View file

@ -14,6 +14,7 @@ ifeq ($(config),debug_x32)
cnq3_config = debug_x32
cnq3_server_config = debug_x32
botlib_config = debug_x32
glew_config = debug_x32
renderer_config = debug_x32
libjpeg_turbo_config = debug_x32
endif
@ -21,6 +22,7 @@ ifeq ($(config),debug_x64)
cnq3_config = debug_x64
cnq3_server_config = debug_x64
botlib_config = debug_x64
glew_config = debug_x64
renderer_config = debug_x64
libjpeg_turbo_config = debug_x64
endif
@ -28,6 +30,7 @@ ifeq ($(config),release_x32)
cnq3_config = release_x32
cnq3_server_config = release_x32
botlib_config = release_x32
glew_config = release_x32
renderer_config = release_x32
libjpeg_turbo_config = release_x32
endif
@ -35,17 +38,18 @@ ifeq ($(config),release_x64)
cnq3_config = release_x64
cnq3_server_config = release_x64
botlib_config = release_x64
glew_config = release_x64
renderer_config = release_x64
libjpeg_turbo_config = release_x64
endif
PROJECTS := cnq3 cnq3-server botlib renderer libjpeg-turbo
PROJECTS := cnq3 cnq3-server botlib glew renderer libjpeg-turbo
.PHONY: all clean help $(PROJECTS)
all: $(PROJECTS)
cnq3: botlib renderer libjpeg-turbo
cnq3: botlib renderer glew libjpeg-turbo
ifneq (,$(cnq3_config))
@echo "==== Building cnq3 ($(cnq3_config)) ===="
@${MAKE} --no-print-directory -C . -f cnq3.make config=$(cnq3_config)
@ -63,6 +67,12 @@ ifneq (,$(botlib_config))
@${MAKE} --no-print-directory -C . -f botlib.make config=$(botlib_config)
endif
glew:
ifneq (,$(glew_config))
@echo "==== Building glew ($(glew_config)) ===="
@${MAKE} --no-print-directory -C . -f glew.make config=$(glew_config)
endif
renderer:
ifneq (,$(renderer_config))
@echo "==== Building renderer ($(renderer_config)) ===="
@ -79,6 +89,7 @@ clean:
@${MAKE} --no-print-directory -C . -f cnq3.make clean
@${MAKE} --no-print-directory -C . -f cnq3-server.make clean
@${MAKE} --no-print-directory -C . -f botlib.make clean
@${MAKE} --no-print-directory -C . -f glew.make clean
@${MAKE} --no-print-directory -C . -f renderer.make clean
@${MAKE} --no-print-directory -C . -f libjpeg-turbo.make clean
@ -97,6 +108,7 @@ help:
@echo " cnq3"
@echo " cnq3-server"
@echo " botlib"
@echo " glew"
@echo " renderer"
@echo " libjpeg-turbo"
@echo ""

View file

@ -15,15 +15,15 @@ ifeq ($(config),debug_x32)
TARGETDIR = ../../.bin/debug_x32
TARGET = $(TARGETDIR)/cnq3-x86
OBJDIR = ../../.build/debug_x32/cnq3
DEFINES += -DDEBUG -D_DEBUG
INCLUDES +=
DEFINES += -DGLEW_STATIC -DDEBUG -D_DEBUG
INCLUDES += -I../../code/glew/include
FORCE_INCLUDE +=
ALL_CPPFLAGS += $(CPPFLAGS) -MMD -MP $(DEFINES) $(INCLUDES)
ALL_CFLAGS += $(CFLAGS) $(ALL_CPPFLAGS) -m32 -g -Wno-unused-parameter -Wno-write-strings -mmmx -msse -msse2 -x c++ -std=c++98
ALL_CXXFLAGS += $(CXXFLAGS) $(ALL_CFLAGS) -fno-exceptions -fno-rtti
ALL_RESFLAGS += $(RESFLAGS) $(DEFINES) $(INCLUDES)
LIBS += ../../.build/debug_x32/libbotlib.a ../../.build/debug_x32/librenderer.a ../../.build/debug_x32/liblibjpeg-turbo.a -ldl -lm -lSDL2
LDDEPS += ../../.build/debug_x32/libbotlib.a ../../.build/debug_x32/librenderer.a ../../.build/debug_x32/liblibjpeg-turbo.a
LIBS += ../../.build/debug_x32/libbotlib.a ../../.build/debug_x32/librenderer.a ../../.build/debug_x32/libglew.a ../../.build/debug_x32/liblibjpeg-turbo.a -ldl -lm -lSDL2 -lGL
LDDEPS += ../../.build/debug_x32/libbotlib.a ../../.build/debug_x32/librenderer.a ../../.build/debug_x32/libglew.a ../../.build/debug_x32/liblibjpeg-turbo.a
ALL_LDFLAGS += $(LDFLAGS) -L/usr/lib32 -L../../.build/debug_x32 -m32
LINKCMD = $(CXX) -o "$@" $(OBJECTS) $(RESOURCES) $(ALL_LDFLAGS) $(LIBS)
define PREBUILDCMDS
@ -46,15 +46,15 @@ ifeq ($(config),debug_x64)
TARGETDIR = ../../.bin/debug_x64
TARGET = $(TARGETDIR)/cnq3-x64
OBJDIR = ../../.build/debug_x64/cnq3
DEFINES += -DDEBUG -D_DEBUG
INCLUDES +=
DEFINES += -DGLEW_STATIC -DDEBUG -D_DEBUG
INCLUDES += -I../../code/glew/include
FORCE_INCLUDE +=
ALL_CPPFLAGS += $(CPPFLAGS) -MMD -MP $(DEFINES) $(INCLUDES)
ALL_CFLAGS += $(CFLAGS) $(ALL_CPPFLAGS) -m64 -g -Wno-unused-parameter -Wno-write-strings -x c++ -std=c++98
ALL_CXXFLAGS += $(CXXFLAGS) $(ALL_CFLAGS) -fno-exceptions -fno-rtti
ALL_RESFLAGS += $(RESFLAGS) $(DEFINES) $(INCLUDES)
LIBS += ../../.build/debug_x64/libbotlib.a ../../.build/debug_x64/librenderer.a ../../.build/debug_x64/liblibjpeg-turbo.a -ldl -lm -lSDL2
LDDEPS += ../../.build/debug_x64/libbotlib.a ../../.build/debug_x64/librenderer.a ../../.build/debug_x64/liblibjpeg-turbo.a
LIBS += ../../.build/debug_x64/libbotlib.a ../../.build/debug_x64/librenderer.a ../../.build/debug_x64/libglew.a ../../.build/debug_x64/liblibjpeg-turbo.a -ldl -lm -lSDL2 -lGL
LDDEPS += ../../.build/debug_x64/libbotlib.a ../../.build/debug_x64/librenderer.a ../../.build/debug_x64/libglew.a ../../.build/debug_x64/liblibjpeg-turbo.a
ALL_LDFLAGS += $(LDFLAGS) -L/usr/lib64 -L../../.build/debug_x64 -m64
LINKCMD = $(CXX) -o "$@" $(OBJECTS) $(RESOURCES) $(ALL_LDFLAGS) $(LIBS)
define PREBUILDCMDS
@ -77,15 +77,15 @@ ifeq ($(config),release_x32)
TARGETDIR = ../../.bin/release_x32
TARGET = $(TARGETDIR)/cnq3-x86
OBJDIR = ../../.build/release_x32/cnq3
DEFINES += -DNDEBUG
INCLUDES +=
DEFINES += -DGLEW_STATIC -DNDEBUG
INCLUDES += -I../../code/glew/include
FORCE_INCLUDE +=
ALL_CPPFLAGS += $(CPPFLAGS) -MMD -MP $(DEFINES) $(INCLUDES)
ALL_CFLAGS += $(CFLAGS) $(ALL_CPPFLAGS) -m32 -fomit-frame-pointer -ffast-math -Os -g -msse2 -Wno-unused-parameter -Wno-write-strings -g1 -mmmx -msse -msse2 -x c++ -std=c++98
ALL_CXXFLAGS += $(CXXFLAGS) $(ALL_CFLAGS) -fno-exceptions -fno-rtti
ALL_RESFLAGS += $(RESFLAGS) $(DEFINES) $(INCLUDES)
LIBS += ../../.build/release_x32/libbotlib.a ../../.build/release_x32/librenderer.a ../../.build/release_x32/liblibjpeg-turbo.a -ldl -lm -lSDL2
LDDEPS += ../../.build/release_x32/libbotlib.a ../../.build/release_x32/librenderer.a ../../.build/release_x32/liblibjpeg-turbo.a
LIBS += ../../.build/release_x32/libbotlib.a ../../.build/release_x32/librenderer.a ../../.build/release_x32/libglew.a ../../.build/release_x32/liblibjpeg-turbo.a -ldl -lm -lSDL2 -lGL
LDDEPS += ../../.build/release_x32/libbotlib.a ../../.build/release_x32/librenderer.a ../../.build/release_x32/libglew.a ../../.build/release_x32/liblibjpeg-turbo.a
ALL_LDFLAGS += $(LDFLAGS) -L/usr/lib32 -L../../.build/release_x32 -m32
LINKCMD = $(CXX) -o "$@" $(OBJECTS) $(RESOURCES) $(ALL_LDFLAGS) $(LIBS)
define PREBUILDCMDS
@ -108,15 +108,15 @@ ifeq ($(config),release_x64)
TARGETDIR = ../../.bin/release_x64
TARGET = $(TARGETDIR)/cnq3-x64
OBJDIR = ../../.build/release_x64/cnq3
DEFINES += -DNDEBUG
INCLUDES +=
DEFINES += -DGLEW_STATIC -DNDEBUG
INCLUDES += -I../../code/glew/include
FORCE_INCLUDE +=
ALL_CPPFLAGS += $(CPPFLAGS) -MMD -MP $(DEFINES) $(INCLUDES)
ALL_CFLAGS += $(CFLAGS) $(ALL_CPPFLAGS) -m64 -fomit-frame-pointer -ffast-math -Os -g -msse2 -Wno-unused-parameter -Wno-write-strings -g1 -x c++ -std=c++98
ALL_CXXFLAGS += $(CXXFLAGS) $(ALL_CFLAGS) -fno-exceptions -fno-rtti
ALL_RESFLAGS += $(RESFLAGS) $(DEFINES) $(INCLUDES)
LIBS += ../../.build/release_x64/libbotlib.a ../../.build/release_x64/librenderer.a ../../.build/release_x64/liblibjpeg-turbo.a -ldl -lm -lSDL2
LDDEPS += ../../.build/release_x64/libbotlib.a ../../.build/release_x64/librenderer.a ../../.build/release_x64/liblibjpeg-turbo.a
LIBS += ../../.build/release_x64/libbotlib.a ../../.build/release_x64/librenderer.a ../../.build/release_x64/libglew.a ../../.build/release_x64/liblibjpeg-turbo.a -ldl -lm -lSDL2 -lGL
LDDEPS += ../../.build/release_x64/libbotlib.a ../../.build/release_x64/librenderer.a ../../.build/release_x64/libglew.a ../../.build/release_x64/liblibjpeg-turbo.a
ALL_LDFLAGS += $(LDFLAGS) -L/usr/lib64 -L../../.build/release_x64 -m64
LINKCMD = $(CXX) -o "$@" $(OBJECTS) $(RESOURCES) $(ALL_LDFLAGS) $(LIBS)
define PREBUILDCMDS
@ -141,6 +141,7 @@ OBJECTS := \
$(OBJDIR)/cl_cin.o \
$(OBJDIR)/cl_console.o \
$(OBJDIR)/cl_download.o \
$(OBJDIR)/cl_gl.o \
$(OBJDIR)/cl_input.o \
$(OBJDIR)/cl_keys.o \
$(OBJDIR)/cl_main.o \
@ -155,7 +156,6 @@ OBJECTS := \
$(OBJDIR)/snd_mem.o \
$(OBJDIR)/snd_mix.o \
$(OBJDIR)/linux_main.o \
$(OBJDIR)/linux_qgl.o \
$(OBJDIR)/linux_shared.o \
$(OBJDIR)/linux_signals.o \
$(OBJDIR)/linux_tty.o \
@ -270,6 +270,9 @@ $(OBJDIR)/cl_console.o: ../../code/client/cl_console.cpp
$(OBJDIR)/cl_download.o: ../../code/client/cl_download.cpp
@echo $(notdir $<)
$(SILENT) $(CXX) $(ALL_CXXFLAGS) $(FORCE_INCLUDE) -o "$@" -MF "$(@:%.o=%.d)" -c "$<"
$(OBJDIR)/cl_gl.o: ../../code/client/cl_gl.cpp
@echo $(notdir $<)
$(SILENT) $(CXX) $(ALL_CXXFLAGS) $(FORCE_INCLUDE) -o "$@" -MF "$(@:%.o=%.d)" -c "$<"
$(OBJDIR)/cl_input.o: ../../code/client/cl_input.cpp
@echo $(notdir $<)
$(SILENT) $(CXX) $(ALL_CXXFLAGS) $(FORCE_INCLUDE) -o "$@" -MF "$(@:%.o=%.d)" -c "$<"
@ -312,9 +315,6 @@ $(OBJDIR)/snd_mix.o: ../../code/client/snd_mix.cpp
$(OBJDIR)/linux_main.o: ../../code/linux/linux_main.cpp
@echo $(notdir $<)
$(SILENT) $(CXX) $(ALL_CXXFLAGS) $(FORCE_INCLUDE) -o "$@" -MF "$(@:%.o=%.d)" -c "$<"
$(OBJDIR)/linux_qgl.o: ../../code/linux/linux_qgl.c
@echo $(notdir $<)
$(SILENT) $(CC) $(ALL_CFLAGS) $(FORCE_INCLUDE) -o "$@" -MF "$(@:%.o=%.d)" -c "$<"
$(OBJDIR)/linux_shared.o: ../../code/linux/linux_shared.cpp
@echo $(notdir $<)
$(SILENT) $(CXX) $(ALL_CXXFLAGS) $(FORCE_INCLUDE) -o "$@" -MF "$(@:%.o=%.d)" -c "$<"

187
makefiles/gmake/glew.make Normal file
View file

@ -0,0 +1,187 @@
# GNU Make project makefile autogenerated by Premake
ifndef config
config=debug_x32
endif
ifndef verbose
SILENT = @
endif
.PHONY: clean prebuild prelink
ifeq ($(config),debug_x32)
RESCOMP = windres
TARGETDIR = ../../.build/debug_x32
TARGET = $(TARGETDIR)/libglew.a
OBJDIR = ../../.build/debug_x32/glew
DEFINES += -DGLEW_STATIC -DDEBUG -D_DEBUG
INCLUDES += -I../../code/glew/include
FORCE_INCLUDE +=
ALL_CPPFLAGS += $(CPPFLAGS) -MMD -MP $(DEFINES) $(INCLUDES)
ALL_CFLAGS += $(CFLAGS) $(ALL_CPPFLAGS) -m32 -g -Wno-unused-parameter -Wno-write-strings -mmmx -msse -msse2
ALL_CXXFLAGS += $(CXXFLAGS) $(ALL_CFLAGS) -fno-exceptions -fno-rtti
ALL_RESFLAGS += $(RESFLAGS) $(DEFINES) $(INCLUDES)
LIBS +=
LDDEPS +=
ALL_LDFLAGS += $(LDFLAGS) -L/usr/lib32 -L../../.build/debug_x32 -m32
LINKCMD = $(AR) -rcs "$@" $(OBJECTS)
define PREBUILDCMDS
endef
define PRELINKCMDS
endef
define POSTBUILDCMDS
endef
all: $(TARGETDIR) $(OBJDIR) prebuild prelink $(TARGET)
@:
endif
ifeq ($(config),debug_x64)
RESCOMP = windres
TARGETDIR = ../../.build/debug_x64
TARGET = $(TARGETDIR)/libglew.a
OBJDIR = ../../.build/debug_x64/glew
DEFINES += -DGLEW_STATIC -DDEBUG -D_DEBUG
INCLUDES += -I../../code/glew/include
FORCE_INCLUDE +=
ALL_CPPFLAGS += $(CPPFLAGS) -MMD -MP $(DEFINES) $(INCLUDES)
ALL_CFLAGS += $(CFLAGS) $(ALL_CPPFLAGS) -m64 -g -Wno-unused-parameter -Wno-write-strings
ALL_CXXFLAGS += $(CXXFLAGS) $(ALL_CFLAGS) -fno-exceptions -fno-rtti
ALL_RESFLAGS += $(RESFLAGS) $(DEFINES) $(INCLUDES)
LIBS +=
LDDEPS +=
ALL_LDFLAGS += $(LDFLAGS) -L/usr/lib64 -L../../.build/debug_x64 -m64
LINKCMD = $(AR) -rcs "$@" $(OBJECTS)
define PREBUILDCMDS
endef
define PRELINKCMDS
endef
define POSTBUILDCMDS
endef
all: $(TARGETDIR) $(OBJDIR) prebuild prelink $(TARGET)
@:
endif
ifeq ($(config),release_x32)
RESCOMP = windres
TARGETDIR = ../../.build/release_x32
TARGET = $(TARGETDIR)/libglew.a
OBJDIR = ../../.build/release_x32/glew
DEFINES += -DGLEW_STATIC -DNDEBUG
INCLUDES += -I../../code/glew/include
FORCE_INCLUDE +=
ALL_CPPFLAGS += $(CPPFLAGS) -MMD -MP $(DEFINES) $(INCLUDES)
ALL_CFLAGS += $(CFLAGS) $(ALL_CPPFLAGS) -m32 -fomit-frame-pointer -ffast-math -Os -g -msse2 -Wno-unused-parameter -Wno-write-strings -g1 -mmmx -msse -msse2
ALL_CXXFLAGS += $(CXXFLAGS) $(ALL_CFLAGS) -fno-exceptions -fno-rtti
ALL_RESFLAGS += $(RESFLAGS) $(DEFINES) $(INCLUDES)
LIBS +=
LDDEPS +=
ALL_LDFLAGS += $(LDFLAGS) -L/usr/lib32 -L../../.build/release_x32 -m32
LINKCMD = $(AR) -rcs "$@" $(OBJECTS)
define PREBUILDCMDS
endef
define PRELINKCMDS
endef
define POSTBUILDCMDS
endef
all: $(TARGETDIR) $(OBJDIR) prebuild prelink $(TARGET)
@:
endif
ifeq ($(config),release_x64)
RESCOMP = windres
TARGETDIR = ../../.build/release_x64
TARGET = $(TARGETDIR)/libglew.a
OBJDIR = ../../.build/release_x64/glew
DEFINES += -DGLEW_STATIC -DNDEBUG
INCLUDES += -I../../code/glew/include
FORCE_INCLUDE +=
ALL_CPPFLAGS += $(CPPFLAGS) -MMD -MP $(DEFINES) $(INCLUDES)
ALL_CFLAGS += $(CFLAGS) $(ALL_CPPFLAGS) -m64 -fomit-frame-pointer -ffast-math -Os -g -msse2 -Wno-unused-parameter -Wno-write-strings -g1
ALL_CXXFLAGS += $(CXXFLAGS) $(ALL_CFLAGS) -fno-exceptions -fno-rtti
ALL_RESFLAGS += $(RESFLAGS) $(DEFINES) $(INCLUDES)
LIBS +=
LDDEPS +=
ALL_LDFLAGS += $(LDFLAGS) -L/usr/lib64 -L../../.build/release_x64 -m64
LINKCMD = $(AR) -rcs "$@" $(OBJECTS)
define PREBUILDCMDS
endef
define PRELINKCMDS
endef
define POSTBUILDCMDS
endef
all: $(TARGETDIR) $(OBJDIR) prebuild prelink $(TARGET)
@:
endif
OBJECTS := \
$(OBJDIR)/glew.o \
RESOURCES := \
CUSTOMFILES := \
SHELLTYPE := msdos
ifeq (,$(ComSpec)$(COMSPEC))
SHELLTYPE := posix
endif
ifeq (/bin,$(findstring /bin,$(SHELL)))
SHELLTYPE := posix
endif
$(TARGET): $(GCH) ${CUSTOMFILES} $(OBJECTS) $(LDDEPS) $(RESOURCES)
@echo Linking glew
$(SILENT) $(LINKCMD)
$(POSTBUILDCMDS)
$(TARGETDIR):
@echo Creating $(TARGETDIR)
ifeq (posix,$(SHELLTYPE))
$(SILENT) mkdir -p $(TARGETDIR)
else
$(SILENT) mkdir $(subst /,\\,$(TARGETDIR))
endif
$(OBJDIR):
@echo Creating $(OBJDIR)
ifeq (posix,$(SHELLTYPE))
$(SILENT) mkdir -p $(OBJDIR)
else
$(SILENT) mkdir $(subst /,\\,$(OBJDIR))
endif
clean:
@echo Cleaning glew
ifeq (posix,$(SHELLTYPE))
$(SILENT) rm -f $(TARGET)
$(SILENT) rm -rf $(OBJDIR)
else
$(SILENT) if exist $(subst /,\\,$(TARGET)) del $(subst /,\\,$(TARGET))
$(SILENT) if exist $(subst /,\\,$(OBJDIR)) rmdir /s /q $(subst /,\\,$(OBJDIR))
endif
prebuild:
$(PREBUILDCMDS)
prelink:
$(PRELINKCMDS)
ifneq (,$(PCH))
$(OBJECTS): $(GCH) $(PCH)
$(GCH): $(PCH)
@echo $(notdir $<)
$(SILENT) $(CC) -x c-header $(ALL_CFLAGS) -o "$@" -MF "$(@:%.gch=%.d)" -c "$<"
endif
$(OBJDIR)/glew.o: ../../code/glew/glew.c
@echo $(notdir $<)
$(SILENT) $(CC) $(ALL_CFLAGS) $(FORCE_INCLUDE) -o "$@" -MF "$(@:%.o=%.d)" -c "$<"
-include $(OBJECTS:%.o=%.d)
ifneq (,$(PCH))
-include $(OBJDIR)/$(notdir $(PCH)).d
endif

View file

@ -15,8 +15,8 @@ ifeq ($(config),debug_x32)
TARGETDIR = ../../.build/debug_x32
TARGET = $(TARGETDIR)/librenderer.a
OBJDIR = ../../.build/debug_x32/renderer
DEFINES += -DDEBUG -D_DEBUG
INCLUDES +=
DEFINES += -DGLEW_STATIC -DDEBUG -D_DEBUG
INCLUDES += -I../../code/glew/include
FORCE_INCLUDE +=
ALL_CPPFLAGS += $(CPPFLAGS) -MMD -MP $(DEFINES) $(INCLUDES)
ALL_CFLAGS += $(CFLAGS) $(ALL_CPPFLAGS) -m32 -g -Wno-unused-parameter -Wno-write-strings -mmmx -msse -msse2 -std=c++98
@ -42,8 +42,8 @@ ifeq ($(config),debug_x64)
TARGETDIR = ../../.build/debug_x64
TARGET = $(TARGETDIR)/librenderer.a
OBJDIR = ../../.build/debug_x64/renderer
DEFINES += -DDEBUG -D_DEBUG
INCLUDES +=
DEFINES += -DGLEW_STATIC -DDEBUG -D_DEBUG
INCLUDES += -I../../code/glew/include
FORCE_INCLUDE +=
ALL_CPPFLAGS += $(CPPFLAGS) -MMD -MP $(DEFINES) $(INCLUDES)
ALL_CFLAGS += $(CFLAGS) $(ALL_CPPFLAGS) -m64 -g -Wno-unused-parameter -Wno-write-strings -std=c++98
@ -69,8 +69,8 @@ ifeq ($(config),release_x32)
TARGETDIR = ../../.build/release_x32
TARGET = $(TARGETDIR)/librenderer.a
OBJDIR = ../../.build/release_x32/renderer
DEFINES += -DNDEBUG
INCLUDES +=
DEFINES += -DGLEW_STATIC -DNDEBUG
INCLUDES += -I../../code/glew/include
FORCE_INCLUDE +=
ALL_CPPFLAGS += $(CPPFLAGS) -MMD -MP $(DEFINES) $(INCLUDES)
ALL_CFLAGS += $(CFLAGS) $(ALL_CPPFLAGS) -m32 -fomit-frame-pointer -ffast-math -Os -g -msse2 -Wno-unused-parameter -Wno-write-strings -g1 -mmmx -msse -msse2 -std=c++98
@ -96,8 +96,8 @@ ifeq ($(config),release_x64)
TARGETDIR = ../../.build/release_x64
TARGET = $(TARGETDIR)/librenderer.a
OBJDIR = ../../.build/release_x64/renderer
DEFINES += -DNDEBUG
INCLUDES +=
DEFINES += -DGLEW_STATIC -DNDEBUG
INCLUDES += -I../../code/glew/include
FORCE_INCLUDE +=
ALL_CPPFLAGS += $(CPPFLAGS) -MMD -MP $(DEFINES) $(INCLUDES)
ALL_CFLAGS += $(CFLAGS) $(ALL_CPPFLAGS) -m64 -fomit-frame-pointer -ffast-math -Os -g -msse2 -Wno-unused-parameter -Wno-write-strings -g1 -std=c++98
@ -121,10 +121,12 @@ endif
OBJECTS := \
$(OBJDIR)/stb_image.o \
$(OBJDIR)/tr_backend.o \
$(OBJDIR)/tr_backend_d3d11.o \
$(OBJDIR)/tr_backend_gl2.o \
$(OBJDIR)/tr_backend_gl3.o \
$(OBJDIR)/tr_bsp.o \
$(OBJDIR)/tr_cmds.o \
$(OBJDIR)/tr_curve.o \
$(OBJDIR)/tr_gl2.o \
$(OBJDIR)/tr_image.o \
$(OBJDIR)/tr_init.o \
$(OBJDIR)/tr_light.o \
@ -203,6 +205,15 @@ $(OBJDIR)/stb_image.o: ../../code/renderer/stb_image.cpp
$(OBJDIR)/tr_backend.o: ../../code/renderer/tr_backend.cpp
@echo $(notdir $<)
$(SILENT) $(CXX) $(ALL_CXXFLAGS) $(FORCE_INCLUDE) -o "$@" -MF "$(@:%.o=%.d)" -c "$<"
$(OBJDIR)/tr_backend_d3d11.o: ../../code/renderer/tr_backend_d3d11.cpp
@echo $(notdir $<)
$(SILENT) $(CXX) $(ALL_CXXFLAGS) $(FORCE_INCLUDE) -o "$@" -MF "$(@:%.o=%.d)" -c "$<"
$(OBJDIR)/tr_backend_gl2.o: ../../code/renderer/tr_backend_gl2.cpp
@echo $(notdir $<)
$(SILENT) $(CXX) $(ALL_CXXFLAGS) $(FORCE_INCLUDE) -o "$@" -MF "$(@:%.o=%.d)" -c "$<"
$(OBJDIR)/tr_backend_gl3.o: ../../code/renderer/tr_backend_gl3.cpp
@echo $(notdir $<)
$(SILENT) $(CXX) $(ALL_CXXFLAGS) $(FORCE_INCLUDE) -o "$@" -MF "$(@:%.o=%.d)" -c "$<"
$(OBJDIR)/tr_bsp.o: ../../code/renderer/tr_bsp.cpp
@echo $(notdir $<)
$(SILENT) $(CXX) $(ALL_CXXFLAGS) $(FORCE_INCLUDE) -o "$@" -MF "$(@:%.o=%.d)" -c "$<"
@ -212,9 +223,6 @@ $(OBJDIR)/tr_cmds.o: ../../code/renderer/tr_cmds.cpp
$(OBJDIR)/tr_curve.o: ../../code/renderer/tr_curve.cpp
@echo $(notdir $<)
$(SILENT) $(CXX) $(ALL_CXXFLAGS) $(FORCE_INCLUDE) -o "$@" -MF "$(@:%.o=%.d)" -c "$<"
$(OBJDIR)/tr_gl2.o: ../../code/renderer/tr_gl2.cpp
@echo $(notdir $<)
$(SILENT) $(CXX) $(ALL_CXXFLAGS) $(FORCE_INCLUDE) -o "$@" -MF "$(@:%.o=%.d)" -c "$<"
$(OBJDIR)/tr_image.o: ../../code/renderer/tr_image.cpp
@echo $(notdir $<)
$(SILENT) $(CXX) $(ALL_CXXFLAGS) $(FORCE_INCLUDE) -o "$@" -MF "$(@:%.o=%.d)" -c "$<"

View file

@ -63,6 +63,28 @@ local function WIN_CreatePdbCopyPostBuildCommand(exeName)
end
local function WIN_CreateShaderPreBuildCommand(name, shaderType, version, options, suffix)
extra_fxc_options_map =
{
debug = "/O0 /Zi",
release = "/O3"
}
local fxc_path = "\"$(DXSDK_DIR)Utilities\\bin\\x86\\fxc.exe\""
local extra_options = "%{extra_fxc_options_map[cfg.buildcfg]}"..options
local name_suffix = suffix
local target = string.format("%s_%s", shaderType, version)
local entry_point = string.format("%s_main", shaderType)
local var_name = string.format("g_%s%s_%s", name, name_suffix, shaderType)
local abs_path_hlsl = os.realpath(path_src.."\\renderer\\hlsl")
local input_file_name = string.format("%s\\%s.hlsl", abs_path_hlsl, name)
local output_file_name = string.format("%s\\%s%s_%s.h", abs_path_hlsl, name, name_suffix, shaderType)
return string.format("%s %s /nologo /T %s /E %s /Vn %s /Fh %s %s", fxc_path, input_file_name, target, entry_point, var_name, output_file_name, extra_options)
end
local function AddSourcesAndHeaders(dirPath)
files
@ -341,6 +363,7 @@ local function ApplyExeProjectSettings(exeName, server)
"client/cl_cin.cpp",
"client/cl_console.cpp",
"client/cl_download.cpp",
"client/cl_gl.cpp",
"client/cl_input.cpp",
"client/cl_keys.cpp",
"client/cl_main.cpp",
@ -398,14 +421,12 @@ local function ApplyExeProjectSettings(exeName, server)
"win32/win_snd.cpp",
"win32/win_syscon.cpp",
"win32/win_wndproc.cpp",
"win32/win_glimp.cpp",
"win32/win_qgl.c"
"win32/win_glimp.cpp"
}
local client_sources_linux =
{
"linux/linux_main.cpp",
"linux/linux_qgl.c",
"linux/linux_shared.cpp",
"linux/linux_signals.cpp",
"linux/linux_tty.cpp",
@ -429,7 +450,7 @@ local function ApplyExeProjectSettings(exeName, server)
else
AddSourcesFromArray(".", client_sources)
AddHeaders("renderer")
links { "renderer", "libjpeg-turbo" }
links { "renderer", "glew", "libjpeg-turbo" }
end
filter { "system:windows" }
@ -481,7 +502,7 @@ local function ApplyExeProjectSettings(exeName, server)
filter "system:not windows"
links { "dl", "m" }
if (server == 0) then
links { "SDL2" }
links { "SDL2", "GL" }
end
-- RC will compile the .rc into a .res
@ -663,6 +684,8 @@ solution "cnq3"
kind "WindowedApp"
language "C++"
defines { "GLEW_STATIC" }
includedirs { path_src.."/glew/include" }
ApplyExeProjectSettings("cnq3", 0)
filter "action:gmake"
buildoptions { "-std=c++98" }
@ -686,14 +709,45 @@ solution "cnq3"
filter "action:gmake"
buildoptions { "-std=c++98" }
project "glew"
kind "StaticLib"
language "C"
defines { "GLEW_STATIC" }
AddSourcesAndHeaders("glew")
includedirs { path_src.."/glew/include" }
ApplyLibProjectSettings()
project "renderer"
kind "StaticLib"
language "C++"
defines { "GLEW_STATIC" }
AddSourcesAndHeaders("renderer")
includedirs { path_src.."/glew/include" }
if os.is("windows") then
files { string.format("%s/renderer/hlsl/*.hlsl", path_src) }
end
ApplyLibProjectSettings()
filter "action:gmake"
buildoptions { "-std=c++98" }
if os.is("windows") then
filter "action:vs*"
prebuildcommands { WIN_CreateShaderPreBuildCommand("generic", "vs", "4_1", "", "") }
prebuildcommands { WIN_CreateShaderPreBuildCommand("generic", "ps", "4_1", "", "") }
prebuildcommands { WIN_CreateShaderPreBuildCommand("generic", "ps", "4_1", " /DCNQ3_A2C=1", "_a") }
prebuildcommands { WIN_CreateShaderPreBuildCommand("generic", "ps", "4_1", " /DCNQ3_DITHER=1", "_d") }
prebuildcommands { WIN_CreateShaderPreBuildCommand("generic", "ps", "4_1", " /DCNQ3_A2C=1 /DCNQ3_DITHER=1", "_ad") }
prebuildcommands { WIN_CreateShaderPreBuildCommand("post", "vs", "4_1", "", "") }
prebuildcommands { WIN_CreateShaderPreBuildCommand("post", "ps", "4_1", "", "") }
prebuildcommands { WIN_CreateShaderPreBuildCommand("dl", "vs", "4_1", "", "") }
prebuildcommands { WIN_CreateShaderPreBuildCommand("dl", "ps", "4_1", "", "") }
prebuildcommands { WIN_CreateShaderPreBuildCommand("sprite", "vs", "4_1", "", "") }
prebuildcommands { WIN_CreateShaderPreBuildCommand("sprite", "ps", "4_1", "", "") }
prebuildcommands { WIN_CreateShaderPreBuildCommand("mip_start", "cs", "5_0", "", "") }
prebuildcommands { WIN_CreateShaderPreBuildCommand("mip_pass", "cs", "5_0", "", "") }
prebuildcommands { WIN_CreateShaderPreBuildCommand("mip_end", "cs", "5_0", "", "") }
end
project "libjpeg-turbo"

View file

@ -294,10 +294,8 @@ copy "..\..\.bin\release_x64\cnq3-server-x64.pdb" "$(QUAKE3DIR)"</Command>
<ClInclude Include="..\..\code\qcommon\vm_local.h" />
<ClInclude Include="..\..\code\qcommon\vm_shim.h" />
<ClInclude Include="..\..\code\server\server.h" />
<ClInclude Include="..\..\code\win32\glext.h" />
<ClInclude Include="..\..\code\win32\glw_win.h" />
<ClInclude Include="..\..\code\win32\resource.h" />
<ClInclude Include="..\..\code\win32\wglext.h" />
<ClInclude Include="..\..\code\win32\win_help.h" />
<ClInclude Include="..\..\code\win32\win_local.h" />
<ClInclude Include="..\..\code\win32\windows.h" />

View file

@ -201,18 +201,12 @@
<ClInclude Include="..\..\code\server\server.h">
<Filter>server</Filter>
</ClInclude>
<ClInclude Include="..\..\code\win32\glext.h">
<Filter>win32</Filter>
</ClInclude>
<ClInclude Include="..\..\code\win32\glw_win.h">
<Filter>win32</Filter>
</ClInclude>
<ClInclude Include="..\..\code\win32\resource.h">
<Filter>win32</Filter>
</ClInclude>
<ClInclude Include="..\..\code\win32\wglext.h">
<Filter>win32</Filter>
</ClInclude>
<ClInclude Include="..\..\code\win32\win_help.h">
<Filter>win32</Filter>
</ClInclude>

View file

@ -7,6 +7,8 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "cnq3-server", "cnq3-server.
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "botlib", "botlib.vcxproj", "{A1A792F4-8D49-BDCA-7604-D11E6245441B}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "glew", "glew.vcxproj", "{7463977C-609A-980D-0987-7E10F59C140F}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "renderer", "renderer.vcxproj", "{9C6AA017-8837-FB22-B150-E9CA9D7C30B1}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libjpeg-turbo", "libjpeg-turbo.vcxproj", "{DB56484D-4717-C483-1052-0D017CD10860}"
@ -43,6 +45,14 @@ Global
{A1A792F4-8D49-BDCA-7604-D11E6245441B}.release|Win32.Build.0 = release|Win32
{A1A792F4-8D49-BDCA-7604-D11E6245441B}.release|x64.ActiveCfg = release|x64
{A1A792F4-8D49-BDCA-7604-D11E6245441B}.release|x64.Build.0 = release|x64
{7463977C-609A-980D-0987-7E10F59C140F}.debug|Win32.ActiveCfg = debug|Win32
{7463977C-609A-980D-0987-7E10F59C140F}.debug|Win32.Build.0 = debug|Win32
{7463977C-609A-980D-0987-7E10F59C140F}.debug|x64.ActiveCfg = debug|x64
{7463977C-609A-980D-0987-7E10F59C140F}.debug|x64.Build.0 = debug|x64
{7463977C-609A-980D-0987-7E10F59C140F}.release|Win32.ActiveCfg = release|Win32
{7463977C-609A-980D-0987-7E10F59C140F}.release|Win32.Build.0 = release|Win32
{7463977C-609A-980D-0987-7E10F59C140F}.release|x64.ActiveCfg = release|x64
{7463977C-609A-980D-0987-7E10F59C140F}.release|x64.Build.0 = release|x64
{9C6AA017-8837-FB22-B150-E9CA9D7C30B1}.debug|Win32.ActiveCfg = debug|Win32
{9C6AA017-8837-FB22-B150-E9CA9D7C30B1}.debug|Win32.Build.0 = debug|Win32
{9C6AA017-8837-FB22-B150-E9CA9D7C30B1}.debug|x64.ActiveCfg = debug|x64

View file

@ -103,7 +103,8 @@
<ClCompile>
<PrecompiledHeader>NotUsing</PrecompiledHeader>
<WarningLevel>Level4</WarningLevel>
<PreprocessorDefinitions>DEBUG;_DEBUG;_CRT_SECURE_NO_WARNINGS;WIN32;_WIN32;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<PreprocessorDefinitions>GLEW_STATIC;DEBUG;_DEBUG;_CRT_SECURE_NO_WARNINGS;WIN32;_WIN32;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories>..\..\code\glew\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<Optimization>Disabled</Optimization>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
@ -131,7 +132,8 @@ copy "..\..\.bin\debug_x32\cnq3-x86.pdb" "$(QUAKE3DIR)"</Command>
<ClCompile>
<PrecompiledHeader>NotUsing</PrecompiledHeader>
<WarningLevel>Level4</WarningLevel>
<PreprocessorDefinitions>DEBUG;_DEBUG;_CRT_SECURE_NO_WARNINGS;WIN32;_WIN32;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<PreprocessorDefinitions>GLEW_STATIC;DEBUG;_DEBUG;_CRT_SECURE_NO_WARNINGS;WIN32;_WIN32;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories>..\..\code\glew\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<Optimization>Disabled</Optimization>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
@ -160,7 +162,8 @@ copy "..\..\.bin\debug_x64\cnq3-x64.pdb" "$(QUAKE3DIR)"</Command>
<PrecompiledHeader>NotUsing</PrecompiledHeader>
<WarningLevel>Level4</WarningLevel>
<BasicRuntimeChecks>Default</BasicRuntimeChecks>
<PreprocessorDefinitions>NDEBUG;_CRT_SECURE_NO_WARNINGS;WIN32;_WIN32;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<PreprocessorDefinitions>GLEW_STATIC;NDEBUG;_CRT_SECURE_NO_WARNINGS;WIN32;_WIN32;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories>..\..\code\glew\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<Optimization>MinSpace</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
@ -199,7 +202,8 @@ copy "..\..\.bin\release_x32\cnq3-x86.pdb" "$(QUAKE3DIR)"</Command>
<PrecompiledHeader>NotUsing</PrecompiledHeader>
<WarningLevel>Level4</WarningLevel>
<BasicRuntimeChecks>Default</BasicRuntimeChecks>
<PreprocessorDefinitions>NDEBUG;_CRT_SECURE_NO_WARNINGS;WIN32;_WIN32;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<PreprocessorDefinitions>GLEW_STATIC;NDEBUG;_CRT_SECURE_NO_WARNINGS;WIN32;_WIN32;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories>..\..\code\glew\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<Optimization>MinSpace</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
@ -293,16 +297,13 @@ copy "..\..\.bin\release_x64\cnq3-x64.pdb" "$(QUAKE3DIR)"</Command>
<ClInclude Include="..\..\code\qcommon\unzip.h" />
<ClInclude Include="..\..\code\qcommon\vm_local.h" />
<ClInclude Include="..\..\code\qcommon\vm_shim.h" />
<ClInclude Include="..\..\code\renderer\qgl.h" />
<ClInclude Include="..\..\code\renderer\stb_image.h" />
<ClInclude Include="..\..\code\renderer\tr_help.h" />
<ClInclude Include="..\..\code\renderer\tr_local.h" />
<ClInclude Include="..\..\code\renderer\tr_public.h" />
<ClInclude Include="..\..\code\server\server.h" />
<ClInclude Include="..\..\code\win32\glext.h" />
<ClInclude Include="..\..\code\win32\glw_win.h" />
<ClInclude Include="..\..\code\win32\resource.h" />
<ClInclude Include="..\..\code\win32\wglext.h" />
<ClInclude Include="..\..\code\win32\win_help.h" />
<ClInclude Include="..\..\code\win32\win_local.h" />
<ClInclude Include="..\..\code\win32\windows.h" />
@ -314,6 +315,7 @@ copy "..\..\.bin\release_x64\cnq3-x64.pdb" "$(QUAKE3DIR)"</Command>
<ClCompile Include="..\..\code\client\cl_cin.cpp" />
<ClCompile Include="..\..\code\client\cl_console.cpp" />
<ClCompile Include="..\..\code\client\cl_download.cpp" />
<ClCompile Include="..\..\code\client\cl_gl.cpp" />
<ClCompile Include="..\..\code\client\cl_input.cpp" />
<ClCompile Include="..\..\code\client\cl_keys.cpp" />
<ClCompile Include="..\..\code\client\cl_main.cpp" />
@ -364,7 +366,6 @@ copy "..\..\.bin\release_x64\cnq3-x64.pdb" "$(QUAKE3DIR)"</Command>
<ClCompile Include="..\..\code\win32\win_glimp.cpp" />
<ClCompile Include="..\..\code\win32\win_input.cpp" />
<ClCompile Include="..\..\code\win32\win_main.cpp" />
<ClCompile Include="..\..\code\win32\win_qgl.c" />
<ClCompile Include="..\..\code\win32\win_shared.cpp" />
<ClCompile Include="..\..\code\win32\win_snd.cpp" />
<ClCompile Include="..\..\code\win32\win_syscon.cpp" />
@ -377,6 +378,9 @@ copy "..\..\.bin\release_x64\cnq3-x64.pdb" "$(QUAKE3DIR)"</Command>
<ProjectReference Include="renderer.vcxproj">
<Project>{9C6AA017-8837-FB22-B150-E9CA9D7C30B1}</Project>
</ProjectReference>
<ProjectReference Include="glew.vcxproj">
<Project>{7463977C-609A-980D-0987-7E10F59C140F}</Project>
</ProjectReference>
<ProjectReference Include="libjpeg-turbo.vcxproj">
<Project>{DB56484D-4717-C483-1052-0D017CD10860}</Project>
</ProjectReference>

View file

@ -201,9 +201,6 @@
<ClInclude Include="..\..\code\qcommon\vm_shim.h">
<Filter>qcommon</Filter>
</ClInclude>
<ClInclude Include="..\..\code\renderer\qgl.h">
<Filter>renderer</Filter>
</ClInclude>
<ClInclude Include="..\..\code\renderer\stb_image.h">
<Filter>renderer</Filter>
</ClInclude>
@ -219,18 +216,12 @@
<ClInclude Include="..\..\code\server\server.h">
<Filter>server</Filter>
</ClInclude>
<ClInclude Include="..\..\code\win32\glext.h">
<Filter>win32</Filter>
</ClInclude>
<ClInclude Include="..\..\code\win32\glw_win.h">
<Filter>win32</Filter>
</ClInclude>
<ClInclude Include="..\..\code\win32\resource.h">
<Filter>win32</Filter>
</ClInclude>
<ClInclude Include="..\..\code\win32\wglext.h">
<Filter>win32</Filter>
</ClInclude>
<ClInclude Include="..\..\code\win32\win_help.h">
<Filter>win32</Filter>
</ClInclude>
@ -260,6 +251,9 @@
<ClCompile Include="..\..\code\client\cl_download.cpp">
<Filter>client</Filter>
</ClCompile>
<ClCompile Include="..\..\code\client\cl_gl.cpp">
<Filter>client</Filter>
</ClCompile>
<ClCompile Include="..\..\code\client\cl_input.cpp">
<Filter>client</Filter>
</ClCompile>
@ -410,9 +404,6 @@
<ClCompile Include="..\..\code\win32\win_main.cpp">
<Filter>win32</Filter>
</ClCompile>
<ClCompile Include="..\..\code\win32\win_qgl.c">
<Filter>win32</Filter>
</ClCompile>
<ClCompile Include="..\..\code\win32\win_shared.cpp">
<Filter>win32</Filter>
</ClCompile>

View file

@ -0,0 +1,217 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="debug|Win32">
<Configuration>debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="debug|x64">
<Configuration>debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="release|Win32">
<Configuration>release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="release|x64">
<Configuration>release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{7463977C-609A-980D-0987-7E10F59C140F}</ProjectGuid>
<IgnoreWarnCompileDuplicatedFilename>true</IgnoreWarnCompileDuplicatedFilename>
<Keyword>Win32Proj</Keyword>
<RootNamespace>glew</RootNamespace>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='debug|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<CharacterSet>Unicode</CharacterSet>
<PlatformToolset>v120</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='debug|x64'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<CharacterSet>Unicode</CharacterSet>
<PlatformToolset>v120</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='release|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<CharacterSet>Unicode</CharacterSet>
<PlatformToolset>v120</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='release|x64'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<CharacterSet>Unicode</CharacterSet>
<PlatformToolset>v120</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='debug|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='debug|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='release|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='release|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='debug|Win32'">
<OutDir>..\..\.build\debug_x32\</OutDir>
<IntDir>..\..\.build\debug_x32\glew\</IntDir>
<TargetName>glew</TargetName>
<TargetExt>.lib</TargetExt>
<GenerateManifest>false</GenerateManifest>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='debug|x64'">
<OutDir>..\..\.build\debug_x64\</OutDir>
<IntDir>..\..\.build\debug_x64\glew\</IntDir>
<TargetName>glew</TargetName>
<TargetExt>.lib</TargetExt>
<GenerateManifest>false</GenerateManifest>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='release|Win32'">
<OutDir>..\..\.build\release_x32\</OutDir>
<IntDir>..\..\.build\release_x32\glew\</IntDir>
<TargetName>glew</TargetName>
<TargetExt>.lib</TargetExt>
<GenerateManifest>false</GenerateManifest>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='release|x64'">
<OutDir>..\..\.build\release_x64\</OutDir>
<IntDir>..\..\.build\release_x64\glew\</IntDir>
<TargetName>glew</TargetName>
<TargetExt>.lib</TargetExt>
<GenerateManifest>false</GenerateManifest>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='debug|Win32'">
<ClCompile>
<PrecompiledHeader>NotUsing</PrecompiledHeader>
<WarningLevel>Level4</WarningLevel>
<PreprocessorDefinitions>GLEW_STATIC;DEBUG;_DEBUG;_CRT_SECURE_NO_WARNINGS;WIN32;_WIN32;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories>..\..\code\glew\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<Optimization>Disabled</Optimization>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<ExceptionHandling>false</ExceptionHandling>
<RuntimeTypeInfo>false</RuntimeTypeInfo>
<TreatWChar_tAsBuiltInType>false</TreatWChar_tAsBuiltInType>
<AdditionalOptions>/Gm /arch:SSE2 %(AdditionalOptions)</AdditionalOptions>
<CompileAs>CompileAsC</CompileAs>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
<Lib>
<AdditionalOptions> %(AdditionalOptions)</AdditionalOptions>
</Lib>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='debug|x64'">
<ClCompile>
<PrecompiledHeader>NotUsing</PrecompiledHeader>
<WarningLevel>Level4</WarningLevel>
<PreprocessorDefinitions>GLEW_STATIC;DEBUG;_DEBUG;_CRT_SECURE_NO_WARNINGS;WIN32;_WIN32;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories>..\..\code\glew\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<Optimization>Disabled</Optimization>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<ExceptionHandling>false</ExceptionHandling>
<RuntimeTypeInfo>false</RuntimeTypeInfo>
<TreatWChar_tAsBuiltInType>false</TreatWChar_tAsBuiltInType>
<AdditionalOptions>/Gm /wd4267 %(AdditionalOptions)</AdditionalOptions>
<CompileAs>CompileAsC</CompileAs>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
<Lib>
<AdditionalOptions> %(AdditionalOptions)</AdditionalOptions>
</Lib>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='release|Win32'">
<ClCompile>
<PrecompiledHeader>NotUsing</PrecompiledHeader>
<WarningLevel>Level4</WarningLevel>
<BasicRuntimeChecks>Default</BasicRuntimeChecks>
<PreprocessorDefinitions>GLEW_STATIC;NDEBUG;_CRT_SECURE_NO_WARNINGS;WIN32;_WIN32;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories>..\..\code\glew\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<Optimization>MinSpace</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<MinimalRebuild>false</MinimalRebuild>
<OmitFramePointers>true</OmitFramePointers>
<StringPooling>true</StringPooling>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<ExceptionHandling>false</ExceptionHandling>
<RuntimeTypeInfo>false</RuntimeTypeInfo>
<TreatWChar_tAsBuiltInType>false</TreatWChar_tAsBuiltInType>
<FloatingPointModel>Fast</FloatingPointModel>
<EnableEnhancedInstructionSet>StreamingSIMDExtensions2</EnableEnhancedInstructionSet>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
<AdditionalOptions>/GL /arch:SSE2 %(AdditionalOptions)</AdditionalOptions>
<CompileAs>CompileAsC</CompileAs>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
</Link>
<Lib>
<AdditionalOptions> %(AdditionalOptions)</AdditionalOptions>
</Lib>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='release|x64'">
<ClCompile>
<PrecompiledHeader>NotUsing</PrecompiledHeader>
<WarningLevel>Level4</WarningLevel>
<BasicRuntimeChecks>Default</BasicRuntimeChecks>
<PreprocessorDefinitions>GLEW_STATIC;NDEBUG;_CRT_SECURE_NO_WARNINGS;WIN32;_WIN32;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories>..\..\code\glew\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<Optimization>MinSpace</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<MinimalRebuild>false</MinimalRebuild>
<OmitFramePointers>true</OmitFramePointers>
<StringPooling>true</StringPooling>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<ExceptionHandling>false</ExceptionHandling>
<RuntimeTypeInfo>false</RuntimeTypeInfo>
<TreatWChar_tAsBuiltInType>false</TreatWChar_tAsBuiltInType>
<FloatingPointModel>Fast</FloatingPointModel>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
<AdditionalOptions>/GL /wd4267 %(AdditionalOptions)</AdditionalOptions>
<CompileAs>CompileAsC</CompileAs>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
</Link>
<Lib>
<AdditionalOptions> %(AdditionalOptions)</AdditionalOptions>
</Lib>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="..\..\code\glew\glew.c" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>

View file

@ -99,7 +99,8 @@
<ClCompile>
<PrecompiledHeader>NotUsing</PrecompiledHeader>
<WarningLevel>Level4</WarningLevel>
<PreprocessorDefinitions>DEBUG;_DEBUG;_CRT_SECURE_NO_WARNINGS;WIN32;_WIN32;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<PreprocessorDefinitions>GLEW_STATIC;DEBUG;_DEBUG;_CRT_SECURE_NO_WARNINGS;WIN32;_WIN32;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories>..\..\code\glew\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<Optimization>Disabled</Optimization>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
@ -115,12 +116,29 @@
<Lib>
<AdditionalOptions> %(AdditionalOptions)</AdditionalOptions>
</Lib>
<PreBuildEvent>
<Command>"$(DXSDK_DIR)Utilities\bin\x86\fxc.exe" C:\Code\cpma_dev\cnq3\code\renderer\hlsl\generic.hlsl /nologo /T vs_4_1 /E vs_main /Vn g_generic_vs /Fh C:\Code\cpma_dev\cnq3\code\renderer\hlsl\generic_vs.h /O0 /Zi
"$(DXSDK_DIR)Utilities\bin\x86\fxc.exe" C:\Code\cpma_dev\cnq3\code\renderer\hlsl\generic.hlsl /nologo /T ps_4_1 /E ps_main /Vn g_generic_ps /Fh C:\Code\cpma_dev\cnq3\code\renderer\hlsl\generic_ps.h /O0 /Zi
"$(DXSDK_DIR)Utilities\bin\x86\fxc.exe" C:\Code\cpma_dev\cnq3\code\renderer\hlsl\generic.hlsl /nologo /T ps_4_1 /E ps_main /Vn g_generic_a_ps /Fh C:\Code\cpma_dev\cnq3\code\renderer\hlsl\generic_a_ps.h /O0 /Zi /DCNQ3_A2C=1
"$(DXSDK_DIR)Utilities\bin\x86\fxc.exe" C:\Code\cpma_dev\cnq3\code\renderer\hlsl\generic.hlsl /nologo /T ps_4_1 /E ps_main /Vn g_generic_d_ps /Fh C:\Code\cpma_dev\cnq3\code\renderer\hlsl\generic_d_ps.h /O0 /Zi /DCNQ3_DITHER=1
"$(DXSDK_DIR)Utilities\bin\x86\fxc.exe" C:\Code\cpma_dev\cnq3\code\renderer\hlsl\generic.hlsl /nologo /T ps_4_1 /E ps_main /Vn g_generic_ad_ps /Fh C:\Code\cpma_dev\cnq3\code\renderer\hlsl\generic_ad_ps.h /O0 /Zi /DCNQ3_A2C=1 /DCNQ3_DITHER=1
"$(DXSDK_DIR)Utilities\bin\x86\fxc.exe" C:\Code\cpma_dev\cnq3\code\renderer\hlsl\post.hlsl /nologo /T vs_4_1 /E vs_main /Vn g_post_vs /Fh C:\Code\cpma_dev\cnq3\code\renderer\hlsl\post_vs.h /O0 /Zi
"$(DXSDK_DIR)Utilities\bin\x86\fxc.exe" C:\Code\cpma_dev\cnq3\code\renderer\hlsl\post.hlsl /nologo /T ps_4_1 /E ps_main /Vn g_post_ps /Fh C:\Code\cpma_dev\cnq3\code\renderer\hlsl\post_ps.h /O0 /Zi
"$(DXSDK_DIR)Utilities\bin\x86\fxc.exe" C:\Code\cpma_dev\cnq3\code\renderer\hlsl\dl.hlsl /nologo /T vs_4_1 /E vs_main /Vn g_dl_vs /Fh C:\Code\cpma_dev\cnq3\code\renderer\hlsl\dl_vs.h /O0 /Zi
"$(DXSDK_DIR)Utilities\bin\x86\fxc.exe" C:\Code\cpma_dev\cnq3\code\renderer\hlsl\dl.hlsl /nologo /T ps_4_1 /E ps_main /Vn g_dl_ps /Fh C:\Code\cpma_dev\cnq3\code\renderer\hlsl\dl_ps.h /O0 /Zi
"$(DXSDK_DIR)Utilities\bin\x86\fxc.exe" C:\Code\cpma_dev\cnq3\code\renderer\hlsl\sprite.hlsl /nologo /T vs_4_1 /E vs_main /Vn g_sprite_vs /Fh C:\Code\cpma_dev\cnq3\code\renderer\hlsl\sprite_vs.h /O0 /Zi
"$(DXSDK_DIR)Utilities\bin\x86\fxc.exe" C:\Code\cpma_dev\cnq3\code\renderer\hlsl\sprite.hlsl /nologo /T ps_4_1 /E ps_main /Vn g_sprite_ps /Fh C:\Code\cpma_dev\cnq3\code\renderer\hlsl\sprite_ps.h /O0 /Zi
"$(DXSDK_DIR)Utilities\bin\x86\fxc.exe" C:\Code\cpma_dev\cnq3\code\renderer\hlsl\mip_start.hlsl /nologo /T cs_5_0 /E cs_main /Vn g_mip_start_cs /Fh C:\Code\cpma_dev\cnq3\code\renderer\hlsl\mip_start_cs.h /O0 /Zi
"$(DXSDK_DIR)Utilities\bin\x86\fxc.exe" C:\Code\cpma_dev\cnq3\code\renderer\hlsl\mip_pass.hlsl /nologo /T cs_5_0 /E cs_main /Vn g_mip_pass_cs /Fh C:\Code\cpma_dev\cnq3\code\renderer\hlsl\mip_pass_cs.h /O0 /Zi
"$(DXSDK_DIR)Utilities\bin\x86\fxc.exe" C:\Code\cpma_dev\cnq3\code\renderer\hlsl\mip_end.hlsl /nologo /T cs_5_0 /E cs_main /Vn g_mip_end_cs /Fh C:\Code\cpma_dev\cnq3\code\renderer\hlsl\mip_end_cs.h /O0 /Zi</Command>
</PreBuildEvent>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='debug|x64'">
<ClCompile>
<PrecompiledHeader>NotUsing</PrecompiledHeader>
<WarningLevel>Level4</WarningLevel>
<PreprocessorDefinitions>DEBUG;_DEBUG;_CRT_SECURE_NO_WARNINGS;WIN32;_WIN32;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<PreprocessorDefinitions>GLEW_STATIC;DEBUG;_DEBUG;_CRT_SECURE_NO_WARNINGS;WIN32;_WIN32;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories>..\..\code\glew\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<Optimization>Disabled</Optimization>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
@ -136,13 +154,30 @@
<Lib>
<AdditionalOptions> %(AdditionalOptions)</AdditionalOptions>
</Lib>
<PreBuildEvent>
<Command>"$(DXSDK_DIR)Utilities\bin\x86\fxc.exe" C:\Code\cpma_dev\cnq3\code\renderer\hlsl\generic.hlsl /nologo /T vs_4_1 /E vs_main /Vn g_generic_vs /Fh C:\Code\cpma_dev\cnq3\code\renderer\hlsl\generic_vs.h /O0 /Zi
"$(DXSDK_DIR)Utilities\bin\x86\fxc.exe" C:\Code\cpma_dev\cnq3\code\renderer\hlsl\generic.hlsl /nologo /T ps_4_1 /E ps_main /Vn g_generic_ps /Fh C:\Code\cpma_dev\cnq3\code\renderer\hlsl\generic_ps.h /O0 /Zi
"$(DXSDK_DIR)Utilities\bin\x86\fxc.exe" C:\Code\cpma_dev\cnq3\code\renderer\hlsl\generic.hlsl /nologo /T ps_4_1 /E ps_main /Vn g_generic_a_ps /Fh C:\Code\cpma_dev\cnq3\code\renderer\hlsl\generic_a_ps.h /O0 /Zi /DCNQ3_A2C=1
"$(DXSDK_DIR)Utilities\bin\x86\fxc.exe" C:\Code\cpma_dev\cnq3\code\renderer\hlsl\generic.hlsl /nologo /T ps_4_1 /E ps_main /Vn g_generic_d_ps /Fh C:\Code\cpma_dev\cnq3\code\renderer\hlsl\generic_d_ps.h /O0 /Zi /DCNQ3_DITHER=1
"$(DXSDK_DIR)Utilities\bin\x86\fxc.exe" C:\Code\cpma_dev\cnq3\code\renderer\hlsl\generic.hlsl /nologo /T ps_4_1 /E ps_main /Vn g_generic_ad_ps /Fh C:\Code\cpma_dev\cnq3\code\renderer\hlsl\generic_ad_ps.h /O0 /Zi /DCNQ3_A2C=1 /DCNQ3_DITHER=1
"$(DXSDK_DIR)Utilities\bin\x86\fxc.exe" C:\Code\cpma_dev\cnq3\code\renderer\hlsl\post.hlsl /nologo /T vs_4_1 /E vs_main /Vn g_post_vs /Fh C:\Code\cpma_dev\cnq3\code\renderer\hlsl\post_vs.h /O0 /Zi
"$(DXSDK_DIR)Utilities\bin\x86\fxc.exe" C:\Code\cpma_dev\cnq3\code\renderer\hlsl\post.hlsl /nologo /T ps_4_1 /E ps_main /Vn g_post_ps /Fh C:\Code\cpma_dev\cnq3\code\renderer\hlsl\post_ps.h /O0 /Zi
"$(DXSDK_DIR)Utilities\bin\x86\fxc.exe" C:\Code\cpma_dev\cnq3\code\renderer\hlsl\dl.hlsl /nologo /T vs_4_1 /E vs_main /Vn g_dl_vs /Fh C:\Code\cpma_dev\cnq3\code\renderer\hlsl\dl_vs.h /O0 /Zi
"$(DXSDK_DIR)Utilities\bin\x86\fxc.exe" C:\Code\cpma_dev\cnq3\code\renderer\hlsl\dl.hlsl /nologo /T ps_4_1 /E ps_main /Vn g_dl_ps /Fh C:\Code\cpma_dev\cnq3\code\renderer\hlsl\dl_ps.h /O0 /Zi
"$(DXSDK_DIR)Utilities\bin\x86\fxc.exe" C:\Code\cpma_dev\cnq3\code\renderer\hlsl\sprite.hlsl /nologo /T vs_4_1 /E vs_main /Vn g_sprite_vs /Fh C:\Code\cpma_dev\cnq3\code\renderer\hlsl\sprite_vs.h /O0 /Zi
"$(DXSDK_DIR)Utilities\bin\x86\fxc.exe" C:\Code\cpma_dev\cnq3\code\renderer\hlsl\sprite.hlsl /nologo /T ps_4_1 /E ps_main /Vn g_sprite_ps /Fh C:\Code\cpma_dev\cnq3\code\renderer\hlsl\sprite_ps.h /O0 /Zi
"$(DXSDK_DIR)Utilities\bin\x86\fxc.exe" C:\Code\cpma_dev\cnq3\code\renderer\hlsl\mip_start.hlsl /nologo /T cs_5_0 /E cs_main /Vn g_mip_start_cs /Fh C:\Code\cpma_dev\cnq3\code\renderer\hlsl\mip_start_cs.h /O0 /Zi
"$(DXSDK_DIR)Utilities\bin\x86\fxc.exe" C:\Code\cpma_dev\cnq3\code\renderer\hlsl\mip_pass.hlsl /nologo /T cs_5_0 /E cs_main /Vn g_mip_pass_cs /Fh C:\Code\cpma_dev\cnq3\code\renderer\hlsl\mip_pass_cs.h /O0 /Zi
"$(DXSDK_DIR)Utilities\bin\x86\fxc.exe" C:\Code\cpma_dev\cnq3\code\renderer\hlsl\mip_end.hlsl /nologo /T cs_5_0 /E cs_main /Vn g_mip_end_cs /Fh C:\Code\cpma_dev\cnq3\code\renderer\hlsl\mip_end_cs.h /O0 /Zi</Command>
</PreBuildEvent>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='release|Win32'">
<ClCompile>
<PrecompiledHeader>NotUsing</PrecompiledHeader>
<WarningLevel>Level4</WarningLevel>
<BasicRuntimeChecks>Default</BasicRuntimeChecks>
<PreprocessorDefinitions>NDEBUG;_CRT_SECURE_NO_WARNINGS;WIN32;_WIN32;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<PreprocessorDefinitions>GLEW_STATIC;NDEBUG;_CRT_SECURE_NO_WARNINGS;WIN32;_WIN32;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories>..\..\code\glew\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<Optimization>MinSpace</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
@ -168,13 +203,30 @@
<Lib>
<AdditionalOptions> %(AdditionalOptions)</AdditionalOptions>
</Lib>
<PreBuildEvent>
<Command>"$(DXSDK_DIR)Utilities\bin\x86\fxc.exe" C:\Code\cpma_dev\cnq3\code\renderer\hlsl\generic.hlsl /nologo /T vs_4_1 /E vs_main /Vn g_generic_vs /Fh C:\Code\cpma_dev\cnq3\code\renderer\hlsl\generic_vs.h /O3
"$(DXSDK_DIR)Utilities\bin\x86\fxc.exe" C:\Code\cpma_dev\cnq3\code\renderer\hlsl\generic.hlsl /nologo /T ps_4_1 /E ps_main /Vn g_generic_ps /Fh C:\Code\cpma_dev\cnq3\code\renderer\hlsl\generic_ps.h /O3
"$(DXSDK_DIR)Utilities\bin\x86\fxc.exe" C:\Code\cpma_dev\cnq3\code\renderer\hlsl\generic.hlsl /nologo /T ps_4_1 /E ps_main /Vn g_generic_a_ps /Fh C:\Code\cpma_dev\cnq3\code\renderer\hlsl\generic_a_ps.h /O3 /DCNQ3_A2C=1
"$(DXSDK_DIR)Utilities\bin\x86\fxc.exe" C:\Code\cpma_dev\cnq3\code\renderer\hlsl\generic.hlsl /nologo /T ps_4_1 /E ps_main /Vn g_generic_d_ps /Fh C:\Code\cpma_dev\cnq3\code\renderer\hlsl\generic_d_ps.h /O3 /DCNQ3_DITHER=1
"$(DXSDK_DIR)Utilities\bin\x86\fxc.exe" C:\Code\cpma_dev\cnq3\code\renderer\hlsl\generic.hlsl /nologo /T ps_4_1 /E ps_main /Vn g_generic_ad_ps /Fh C:\Code\cpma_dev\cnq3\code\renderer\hlsl\generic_ad_ps.h /O3 /DCNQ3_A2C=1 /DCNQ3_DITHER=1
"$(DXSDK_DIR)Utilities\bin\x86\fxc.exe" C:\Code\cpma_dev\cnq3\code\renderer\hlsl\post.hlsl /nologo /T vs_4_1 /E vs_main /Vn g_post_vs /Fh C:\Code\cpma_dev\cnq3\code\renderer\hlsl\post_vs.h /O3
"$(DXSDK_DIR)Utilities\bin\x86\fxc.exe" C:\Code\cpma_dev\cnq3\code\renderer\hlsl\post.hlsl /nologo /T ps_4_1 /E ps_main /Vn g_post_ps /Fh C:\Code\cpma_dev\cnq3\code\renderer\hlsl\post_ps.h /O3
"$(DXSDK_DIR)Utilities\bin\x86\fxc.exe" C:\Code\cpma_dev\cnq3\code\renderer\hlsl\dl.hlsl /nologo /T vs_4_1 /E vs_main /Vn g_dl_vs /Fh C:\Code\cpma_dev\cnq3\code\renderer\hlsl\dl_vs.h /O3
"$(DXSDK_DIR)Utilities\bin\x86\fxc.exe" C:\Code\cpma_dev\cnq3\code\renderer\hlsl\dl.hlsl /nologo /T ps_4_1 /E ps_main /Vn g_dl_ps /Fh C:\Code\cpma_dev\cnq3\code\renderer\hlsl\dl_ps.h /O3
"$(DXSDK_DIR)Utilities\bin\x86\fxc.exe" C:\Code\cpma_dev\cnq3\code\renderer\hlsl\sprite.hlsl /nologo /T vs_4_1 /E vs_main /Vn g_sprite_vs /Fh C:\Code\cpma_dev\cnq3\code\renderer\hlsl\sprite_vs.h /O3
"$(DXSDK_DIR)Utilities\bin\x86\fxc.exe" C:\Code\cpma_dev\cnq3\code\renderer\hlsl\sprite.hlsl /nologo /T ps_4_1 /E ps_main /Vn g_sprite_ps /Fh C:\Code\cpma_dev\cnq3\code\renderer\hlsl\sprite_ps.h /O3
"$(DXSDK_DIR)Utilities\bin\x86\fxc.exe" C:\Code\cpma_dev\cnq3\code\renderer\hlsl\mip_start.hlsl /nologo /T cs_5_0 /E cs_main /Vn g_mip_start_cs /Fh C:\Code\cpma_dev\cnq3\code\renderer\hlsl\mip_start_cs.h /O3
"$(DXSDK_DIR)Utilities\bin\x86\fxc.exe" C:\Code\cpma_dev\cnq3\code\renderer\hlsl\mip_pass.hlsl /nologo /T cs_5_0 /E cs_main /Vn g_mip_pass_cs /Fh C:\Code\cpma_dev\cnq3\code\renderer\hlsl\mip_pass_cs.h /O3
"$(DXSDK_DIR)Utilities\bin\x86\fxc.exe" C:\Code\cpma_dev\cnq3\code\renderer\hlsl\mip_end.hlsl /nologo /T cs_5_0 /E cs_main /Vn g_mip_end_cs /Fh C:\Code\cpma_dev\cnq3\code\renderer\hlsl\mip_end_cs.h /O3</Command>
</PreBuildEvent>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='release|x64'">
<ClCompile>
<PrecompiledHeader>NotUsing</PrecompiledHeader>
<WarningLevel>Level4</WarningLevel>
<BasicRuntimeChecks>Default</BasicRuntimeChecks>
<PreprocessorDefinitions>NDEBUG;_CRT_SECURE_NO_WARNINGS;WIN32;_WIN32;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<PreprocessorDefinitions>GLEW_STATIC;NDEBUG;_CRT_SECURE_NO_WARNINGS;WIN32;_WIN32;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories>..\..\code\glew\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<Optimization>MinSpace</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
@ -199,9 +251,24 @@
<Lib>
<AdditionalOptions> %(AdditionalOptions)</AdditionalOptions>
</Lib>
<PreBuildEvent>
<Command>"$(DXSDK_DIR)Utilities\bin\x86\fxc.exe" C:\Code\cpma_dev\cnq3\code\renderer\hlsl\generic.hlsl /nologo /T vs_4_1 /E vs_main /Vn g_generic_vs /Fh C:\Code\cpma_dev\cnq3\code\renderer\hlsl\generic_vs.h /O3
"$(DXSDK_DIR)Utilities\bin\x86\fxc.exe" C:\Code\cpma_dev\cnq3\code\renderer\hlsl\generic.hlsl /nologo /T ps_4_1 /E ps_main /Vn g_generic_ps /Fh C:\Code\cpma_dev\cnq3\code\renderer\hlsl\generic_ps.h /O3
"$(DXSDK_DIR)Utilities\bin\x86\fxc.exe" C:\Code\cpma_dev\cnq3\code\renderer\hlsl\generic.hlsl /nologo /T ps_4_1 /E ps_main /Vn g_generic_a_ps /Fh C:\Code\cpma_dev\cnq3\code\renderer\hlsl\generic_a_ps.h /O3 /DCNQ3_A2C=1
"$(DXSDK_DIR)Utilities\bin\x86\fxc.exe" C:\Code\cpma_dev\cnq3\code\renderer\hlsl\generic.hlsl /nologo /T ps_4_1 /E ps_main /Vn g_generic_d_ps /Fh C:\Code\cpma_dev\cnq3\code\renderer\hlsl\generic_d_ps.h /O3 /DCNQ3_DITHER=1
"$(DXSDK_DIR)Utilities\bin\x86\fxc.exe" C:\Code\cpma_dev\cnq3\code\renderer\hlsl\generic.hlsl /nologo /T ps_4_1 /E ps_main /Vn g_generic_ad_ps /Fh C:\Code\cpma_dev\cnq3\code\renderer\hlsl\generic_ad_ps.h /O3 /DCNQ3_A2C=1 /DCNQ3_DITHER=1
"$(DXSDK_DIR)Utilities\bin\x86\fxc.exe" C:\Code\cpma_dev\cnq3\code\renderer\hlsl\post.hlsl /nologo /T vs_4_1 /E vs_main /Vn g_post_vs /Fh C:\Code\cpma_dev\cnq3\code\renderer\hlsl\post_vs.h /O3
"$(DXSDK_DIR)Utilities\bin\x86\fxc.exe" C:\Code\cpma_dev\cnq3\code\renderer\hlsl\post.hlsl /nologo /T ps_4_1 /E ps_main /Vn g_post_ps /Fh C:\Code\cpma_dev\cnq3\code\renderer\hlsl\post_ps.h /O3
"$(DXSDK_DIR)Utilities\bin\x86\fxc.exe" C:\Code\cpma_dev\cnq3\code\renderer\hlsl\dl.hlsl /nologo /T vs_4_1 /E vs_main /Vn g_dl_vs /Fh C:\Code\cpma_dev\cnq3\code\renderer\hlsl\dl_vs.h /O3
"$(DXSDK_DIR)Utilities\bin\x86\fxc.exe" C:\Code\cpma_dev\cnq3\code\renderer\hlsl\dl.hlsl /nologo /T ps_4_1 /E ps_main /Vn g_dl_ps /Fh C:\Code\cpma_dev\cnq3\code\renderer\hlsl\dl_ps.h /O3
"$(DXSDK_DIR)Utilities\bin\x86\fxc.exe" C:\Code\cpma_dev\cnq3\code\renderer\hlsl\sprite.hlsl /nologo /T vs_4_1 /E vs_main /Vn g_sprite_vs /Fh C:\Code\cpma_dev\cnq3\code\renderer\hlsl\sprite_vs.h /O3
"$(DXSDK_DIR)Utilities\bin\x86\fxc.exe" C:\Code\cpma_dev\cnq3\code\renderer\hlsl\sprite.hlsl /nologo /T ps_4_1 /E ps_main /Vn g_sprite_ps /Fh C:\Code\cpma_dev\cnq3\code\renderer\hlsl\sprite_ps.h /O3
"$(DXSDK_DIR)Utilities\bin\x86\fxc.exe" C:\Code\cpma_dev\cnq3\code\renderer\hlsl\mip_start.hlsl /nologo /T cs_5_0 /E cs_main /Vn g_mip_start_cs /Fh C:\Code\cpma_dev\cnq3\code\renderer\hlsl\mip_start_cs.h /O3
"$(DXSDK_DIR)Utilities\bin\x86\fxc.exe" C:\Code\cpma_dev\cnq3\code\renderer\hlsl\mip_pass.hlsl /nologo /T cs_5_0 /E cs_main /Vn g_mip_pass_cs /Fh C:\Code\cpma_dev\cnq3\code\renderer\hlsl\mip_pass_cs.h /O3
"$(DXSDK_DIR)Utilities\bin\x86\fxc.exe" C:\Code\cpma_dev\cnq3\code\renderer\hlsl\mip_end.hlsl /nologo /T cs_5_0 /E cs_main /Vn g_mip_end_cs /Fh C:\Code\cpma_dev\cnq3\code\renderer\hlsl\mip_end_cs.h /O3</Command>
</PreBuildEvent>
</ItemDefinitionGroup>
<ItemGroup>
<ClInclude Include="..\..\code\renderer\qgl.h" />
<ClInclude Include="..\..\code\renderer\stb_image.h" />
<ClInclude Include="..\..\code\renderer\tr_help.h" />
<ClInclude Include="..\..\code\renderer\tr_local.h" />
@ -210,10 +277,12 @@
<ItemGroup>
<ClCompile Include="..\..\code\renderer\stb_image.cpp" />
<ClCompile Include="..\..\code\renderer\tr_backend.cpp" />
<ClCompile Include="..\..\code\renderer\tr_backend_d3d11.cpp" />
<ClCompile Include="..\..\code\renderer\tr_backend_gl2.cpp" />
<ClCompile Include="..\..\code\renderer\tr_backend_gl3.cpp" />
<ClCompile Include="..\..\code\renderer\tr_bsp.cpp" />
<ClCompile Include="..\..\code\renderer\tr_cmds.cpp" />
<ClCompile Include="..\..\code\renderer\tr_curve.cpp" />
<ClCompile Include="..\..\code\renderer\tr_gl2.cpp" />
<ClCompile Include="..\..\code\renderer\tr_image.cpp" />
<ClCompile Include="..\..\code\renderer\tr_init.cpp" />
<ClCompile Include="..\..\code\renderer\tr_light.cpp" />
@ -230,6 +299,15 @@
<ClCompile Include="..\..\code\renderer\tr_surface.cpp" />
<ClCompile Include="..\..\code\renderer\tr_world.cpp" />
</ItemGroup>
<ItemGroup>
<None Include="..\..\code\renderer\hlsl\dl.hlsl" />
<None Include="..\..\code\renderer\hlsl\generic.hlsl" />
<None Include="..\..\code\renderer\hlsl\mip_end.hlsl" />
<None Include="..\..\code\renderer\hlsl\mip_pass.hlsl" />
<None Include="..\..\code\renderer\hlsl\mip_start.hlsl" />
<None Include="..\..\code\renderer\hlsl\post.hlsl" />
<None Include="..\..\code\renderer\hlsl\sprite.hlsl" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>

View file

@ -0,0 +1,62 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Filter Include="hlsl">
<UniqueIdentifier>{98F1977C-8428-990D-2D15-7F10192B150F}</UniqueIdentifier>
</Filter>
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\..\code\renderer\stb_image.h" />
<ClInclude Include="..\..\code\renderer\tr_help.h" />
<ClInclude Include="..\..\code\renderer\tr_local.h" />
<ClInclude Include="..\..\code\renderer\tr_public.h" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="..\..\code\renderer\stb_image.cpp" />
<ClCompile Include="..\..\code\renderer\tr_backend.cpp" />
<ClCompile Include="..\..\code\renderer\tr_backend_d3d11.cpp" />
<ClCompile Include="..\..\code\renderer\tr_backend_gl2.cpp" />
<ClCompile Include="..\..\code\renderer\tr_backend_gl3.cpp" />
<ClCompile Include="..\..\code\renderer\tr_bsp.cpp" />
<ClCompile Include="..\..\code\renderer\tr_cmds.cpp" />
<ClCompile Include="..\..\code\renderer\tr_curve.cpp" />
<ClCompile Include="..\..\code\renderer\tr_image.cpp" />
<ClCompile Include="..\..\code\renderer\tr_init.cpp" />
<ClCompile Include="..\..\code\renderer\tr_light.cpp" />
<ClCompile Include="..\..\code\renderer\tr_main.cpp" />
<ClCompile Include="..\..\code\renderer\tr_marks.cpp" />
<ClCompile Include="..\..\code\renderer\tr_mesh.cpp" />
<ClCompile Include="..\..\code\renderer\tr_model.cpp" />
<ClCompile Include="..\..\code\renderer\tr_noise.cpp" />
<ClCompile Include="..\..\code\renderer\tr_scene.cpp" />
<ClCompile Include="..\..\code\renderer\tr_shade.cpp" />
<ClCompile Include="..\..\code\renderer\tr_shade_calc.cpp" />
<ClCompile Include="..\..\code\renderer\tr_shader.cpp" />
<ClCompile Include="..\..\code\renderer\tr_sky.cpp" />
<ClCompile Include="..\..\code\renderer\tr_surface.cpp" />
<ClCompile Include="..\..\code\renderer\tr_world.cpp" />
</ItemGroup>
<ItemGroup>
<None Include="..\..\code\renderer\hlsl\dl.hlsl">
<Filter>hlsl</Filter>
</None>
<None Include="..\..\code\renderer\hlsl\generic.hlsl">
<Filter>hlsl</Filter>
</None>
<None Include="..\..\code\renderer\hlsl\mip_end.hlsl">
<Filter>hlsl</Filter>
</None>
<None Include="..\..\code\renderer\hlsl\mip_pass.hlsl">
<Filter>hlsl</Filter>
</None>
<None Include="..\..\code\renderer\hlsl\mip_start.hlsl">
<Filter>hlsl</Filter>
</None>
<None Include="..\..\code\renderer\hlsl\post.hlsl">
<Filter>hlsl</Filter>
</None>
<None Include="..\..\code\renderer\hlsl\sprite.hlsl">
<Filter>hlsl</Filter>
</None>
</ItemGroup>
</Project>