Merge branch 'vkdoom3-merge'

This commit is contained in:
Robert Beckebans 2018-09-30 15:49:18 +02:00
commit 735a925bd3
73 changed files with 4011 additions and 3870 deletions

View file

@ -29,7 +29,7 @@ If you have questions concerning this license or the applicable additional terms
#ifndef __MENUSCREEN_H__
#define __MENUSCREEN_H__
#include "../../renderer/tr_local.h"
#include "../../renderer/RenderCommon.h"
enum mainMenuTransition_t
{

View file

@ -28,7 +28,7 @@ If you have questions concerning this license or the applicable additional terms
#pragma hdrstop
#include "precompiled.h"
#include "../Game_local.h"
#include "../../renderer/tr_local.h"
#include "../../renderer/RenderCommon.h"
const static int NUM_SETTING_OPTIONS = 7;

View file

@ -825,16 +825,6 @@ CONSOLE_COMMAND( reloadLanguage, "reload language dict", NULL )
#include "../renderer/Image.h"
/*
=================
Com_StartBuild_f
=================
*/
CONSOLE_COMMAND( startBuild, "prepares to make a build", NULL )
{
globalImages->StartBuild();
}
/*
=================
Com_FinishBuild_f
@ -846,7 +836,6 @@ CONSOLE_COMMAND( finishBuild, "finishes the build process", NULL )
{
game->CacheDictionaryMedia( NULL );
}
globalImages->FinishBuild( ( args.Argc() > 1 ) );
}
/*

View file

@ -33,7 +33,6 @@ If you have questions concerning this license or the applicable additional terms
#include "Common_local.h"
#include "../renderer/Image.h" // now I did it!
#include "../renderer/ImageOpts.h"
// RB begin
#if defined(USE_DOOMCLASSIC)
@ -65,7 +64,7 @@ idCVar com_deltaTimeClamp( "com_deltaTimeClamp", "50", CVAR_INTEGER, "don't proc
idCVar com_fixedTic( "com_fixedTic", DEFAULT_FIXED_TIC, CVAR_BOOL, "run a single game frame per render frame" );
idCVar com_noSleep( "com_noSleep", DEFAULT_NO_SLEEP, CVAR_BOOL, "don't sleep if the game is running too fast" );
idCVar com_smp( "com_smp", "1", CVAR_BOOL | CVAR_SYSTEM | CVAR_NOCHEAT, "run the game and draw code in a separate thread" );
idCVar com_smp( "com_smp", "1", CVAR_INTEGER | CVAR_SYSTEM | CVAR_NOCHEAT, "run the game and draw code in a separate thread" );
idCVar com_aviDemoSamples( "com_aviDemoSamples", "16", CVAR_SYSTEM, "" );
idCVar com_aviDemoWidth( "com_aviDemoWidth", "256", CVAR_SYSTEM, "" );
idCVar com_aviDemoHeight( "com_aviDemoHeight", "256", CVAR_SYSTEM, "" );
@ -195,7 +194,7 @@ gameReturn_t idGameThread::RunGameAndDraw( int numGameFrames_, idUserCmdMgr& use
numGameFrames = numGameFrames_;
// start the thread going
if( com_smp.GetBool() == false )
if( com_smp.GetInteger() <= 0 )
{
// run it in the main thread so PIX profiling catches everything
Run();
@ -555,10 +554,15 @@ void idCommonLocal::Frame()
// This may block if the GPU isn't finished renderng the previous frame.
frameTiming.startSyncTime = Sys_Microseconds();
const emptyCommand_t* renderCommands = NULL;
if( com_smp.GetBool() )
if( com_smp.GetInteger() > 0 )
{
renderCommands = renderSystem->SwapCommandBuffers( &time_frontend, &time_backend, &time_shadows, &time_gpu );
}
else if( com_smp.GetInteger() < 0 )
{
// RB: this is the same as Doom 3 renderSystem->BeginFrame()
renderCommands = renderSystem->SwapCommandBuffers_FinishCommandBuffers();
}
else
{
// the GPU will stay idle through command generation for minimal
@ -779,7 +783,12 @@ void idCommonLocal::Frame()
// start the game / draw command generation thread going in the background
gameReturn_t ret = gameThread.RunGameAndDraw( numGameFrames, userCmdMgr, IsClient(), gameFrame - numGameFrames );
if( !com_smp.GetBool() )
if( com_smp.GetInteger() < 0 )
{
// RB: this is the same as Doom 3 renderSystem->EndFrame()
renderSystem->SwapCommandBuffers_FinishRendering( &time_frontend, &time_backend, &time_shadows, &time_gpu );
}
else if( com_smp.GetInteger() == 0 )
{
// in non-smp mode, run the commands we just generated, instead of
// frame-delayed ones from a background thread

View file

@ -39,7 +39,7 @@ If you have questions concerning this license or the applicable additional terms
================================================================================================
*/
#include "tr_local.h"
#include "RenderCommon.h"
#include "DXT/DXTCodec.h"
#include "Color/ColorSpace.h"

View file

@ -28,7 +28,7 @@ If you have questions concerning this license or the applicable additional terms
*/
#pragma hdrstop
#include "precompiled.h"
#include "tr_local.h"
#include "RenderCommon.h"
idCVar r_showBuffers( "r_showBuffers", "0", CVAR_INTEGER, "" );

View file

@ -39,7 +39,7 @@ extern idCVar s_noSound;
#include <jpeglib.h>
//}
#include "tr_local.h"
#include "RenderCommon.h"
#define CIN_system 1
#define CIN_loop 2

View file

@ -29,7 +29,7 @@ If you have questions concerning this license or the applicable additional terms
#include "precompiled.h"
#pragma hdrstop
#include "tr_local.h"
#include "RenderCommon.h"
#include "Framebuffer.h"
idList<Framebuffer*> Framebuffer::framebuffers;
@ -79,7 +79,7 @@ void Framebuffer::Init()
{
cmdSystem->AddCommand( "listFramebuffers", R_ListFramebuffers_f, CMD_FL_RENDERER, "lists framebuffers" );
backEnd.glState.currentFramebuffer = NULL;
tr.backend.currentFramebuffer = NULL;
// SHADOWMAPS
@ -96,7 +96,7 @@ void Framebuffer::Init()
}
// HDR
int screenWidth = renderSystem->GetWidth();
int screenHeight = renderSystem->GetHeight();
@ -207,7 +207,7 @@ void Framebuffer::CheckFramebuffers()
{
int screenWidth = renderSystem->GetWidth();
int screenHeight = renderSystem->GetHeight();
if( globalFramebuffers.hdrFBO->GetWidth() != screenWidth || globalFramebuffers.hdrFBO->GetHeight() != screenHeight )
{
Unbind();
@ -224,7 +224,7 @@ void Framebuffer::CheckFramebuffers()
globalFramebuffers.hdrNonMSAAFBO->Bind();
globalFramebuffers.hdrNonMSAAFBO->AttachImage2D( GL_TEXTURE_2D, globalImages->currentRenderHDRImageNoMSAA, 0 );
globalFramebuffers.hdrNonMSAAFBO->Check();
globalFramebuffers.hdrNonMSAAFBO->width = screenWidth;
globalFramebuffers.hdrNonMSAAFBO->height = screenHeight;
@ -340,33 +340,33 @@ void Framebuffer::Bind()
{
RENDERLOG_PRINTF( "Framebuffer::Bind( %s )\n", fboName.c_str() );
if( backEnd.glState.currentFramebuffer != this )
if( tr.backend.currentFramebuffer != this )
{
glBindFramebuffer( GL_FRAMEBUFFER, frameBuffer );
backEnd.glState.currentFramebuffer = this;
tr.backend.currentFramebuffer = this;
}
}
bool Framebuffer::IsBound()
{
return ( backEnd.glState.currentFramebuffer == this );
return ( tr.backend.currentFramebuffer == this );
}
void Framebuffer::Unbind()
{
RENDERLOG_PRINTF( "Framebuffer::Unbind()\n" );
//if(backEnd.glState.framebuffer != NULL)
//if(tr.backend.framebuffer != NULL)
{
glBindFramebuffer( GL_FRAMEBUFFER, 0 );
glBindRenderbuffer( GL_RENDERBUFFER, 0 );
backEnd.glState.currentFramebuffer = NULL;
tr.backend.currentFramebuffer = NULL;
}
}
bool Framebuffer::IsDefaultFramebufferActive()
{
return ( backEnd.glState.currentFramebuffer == NULL );
return ( tr.backend.currentFramebuffer == NULL );
}
void Framebuffer::AddColorBuffer( int format, int index, int multiSamples )

View file

@ -30,7 +30,7 @@ If you have questions concerning this license or the applicable additional terms
#pragma hdrstop
#include "precompiled.h"
#include "tr_local.h"
#include "RenderCommon.h"
/*
==========================================================================================

View file

@ -3,6 +3,7 @@
Doom 3 BFG Edition GPL Source Code
Copyright (C) 1993-2012 id Software LLC, a ZeniMax Media company.
Copyright (C) 2016-2017 Dustin Land
This file is part of the Doom 3 BFG Edition GPL Source Code ("Doom 3 BFG Edition Source Code").
@ -70,6 +71,12 @@ static const uint64 GLS_DEPTHFUNC_GREATER = 2 << 13;
static const uint64 GLS_DEPTHFUNC_EQUAL = 3 << 13;
static const uint64 GLS_DEPTHFUNC_BITS = 3 << 13;
static const uint64 GLS_CULL_FRONTSIDED = 0 << 15;
static const uint64 GLS_CULL_BACKSIDED = 1 << 15;
static const uint64 GLS_CULL_TWOSIDED = 2 << 15;
static const uint64 GLS_CULL_BITS = 2 << 15;
static const uint64 GLS_CULL_MASK = GLS_CULL_FRONTSIDED | GLS_CULL_BACKSIDED | GLS_CULL_TWOSIDED;
static const uint64 GLS_BLENDOP_ADD = 0 << 18;
static const uint64 GLS_BLENDOP_SUB = 1 << 18;
static const uint64 GLS_BLENDOP_MIN = 2 << 18;
@ -138,9 +145,15 @@ static const uint64 GLS_ALPHATEST_FUNC_BITS = 3ull << 56;
static const uint64 GLS_STENCIL_OP_BITS = GLS_STENCIL_OP_FAIL_BITS | GLS_STENCIL_OP_ZFAIL_BITS | GLS_STENCIL_OP_PASS_BITS;
static const uint64 GLS_DEPTH_TEST_MASK = 1ull << 58;
static const uint64 GLS_CLOCKWISE = 1ull << 59;
static const uint64 GLS_SEPARATE_STENCIL = 1ull << 60;
static const uint64 GLS_MIRROR_VIEW = 1ull << 61;
static const uint64 GLS_OVERRIDE = 1ull << 63; // override the render prog state
static const uint64 GLS_DEFAULT = 0;
static const uint64 GLS_KEEP = GLS_DEPTH_TEST_MASK;
static const uint64 GLS_DEFAULT = 0;
#define STENCIL_SHADOW_TEST_VALUE 128
#define STENCIL_SHADOW_MASK_VALUE 255

View file

@ -1,199 +0,0 @@
/*
===========================================================================
Doom 3 BFG Edition GPL Source Code
Copyright (C) 1993-2012 id Software LLC, a ZeniMax Media company.
Copyright (C) 2013 Robert Beckebans
This file is part of the Doom 3 BFG Edition GPL Source Code ("Doom 3 BFG Edition Source Code").
Doom 3 BFG Edition 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 3 of the License, or
(at your option) any later version.
Doom 3 BFG Edition 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 Doom 3 BFG Edition Source Code. If not, see <http://www.gnu.org/licenses/>.
In addition, the Doom 3 BFG Edition Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 BFG Edition Source Code. If not, please request a copy in writing from id Software at the address below.
If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
===========================================================================
*/
#ifndef __GRAPHICSAPIWRAPPER_H__
#define __GRAPHICSAPIWRAPPER_H__
/*
================================================================================================
Graphics API wrapper/helper functions
This wraps platform specific graphics API functionality that is used at run-time. This
functionality is wrapped to avoid excessive conditional compilation and/or code duplication
throughout the run-time rendering code that is shared on all platforms.
Most other graphics API functions are called for initialization purposes and are called
directly from platform specific code implemented in files in the platform specific folders:
renderer/OpenGL/
renderer/DirectX/
renderer/GCM/
================================================================================================
*/
class idImage;
//class idTriangles;
class idRenderModelSurface;
class idDeclRenderProg;
class idRenderTexture;
static const int MAX_OCCLUSION_QUERIES = 4096;
// returned by GL_GetDeferredQueryResult() when the query is from too long ago and the result is no longer available
static const int OCCLUSION_QUERY_TOO_OLD = -1;
/*
================================================================================================
Platform Specific Context
================================================================================================
*/
#define USE_CORE_PROFILE
struct wrapperContext_t
{
};
/*
================================================
wrapperConfig_t
================================================
*/
struct wrapperConfig_t
{
// rendering options and settings
bool disableStateCaching;
bool lazyBindPrograms;
bool lazyBindParms;
bool lazyBindTextures;
bool stripFragmentBranches;
bool skipDetailTris;
bool singleTriangle;
// values for polygon offset
float polyOfsFactor;
float polyOfsUnits;
// global texture filter settings
int textureMinFilter;
int textureMaxFilter;
int textureMipFilter;
float textureAnisotropy;
float textureLODBias;
};
/*
================================================
wrapperStats_t
================================================
*/
struct wrapperStats_t
{
int c_queriesIssued;
int c_queriesPassed;
int c_queriesWaitTime;
int c_queriesTooOld;
int c_programsBound;
int c_drawElements;
int c_drawIndices;
int c_drawVertices;
};
/*
================================================================================================
API
================================================================================================
*/
void GL_SetWrapperContext( const wrapperContext_t& context );
void GL_SetWrapperConfig( const wrapperConfig_t& config );
void GL_SetTimeDelta( uint64 delta ); // delta from GPU to CPU microseconds
void GL_StartFrame( int frame ); // inserts a timing mark for the start of the GPU frame
void GL_EndFrame(); // inserts a timing mark for the end of the GPU frame
void GL_WaitForEndFrame(); // wait for the GPU to reach the last end frame marker
void GL_GetLastFrameTime( uint64& startGPUTimeMicroSec, uint64& endGPUTimeMicroSec ); // GPU time between GL_StartFrame() and GL_EndFrame()
void GL_StartDepthPass( const idScreenRect& rect );
void GL_FinishDepthPass();
void GL_GetDepthPassRect( idScreenRect& rect );
void GL_SetDefaultState();
void GL_State( uint64 stateVector, bool forceGlState = false );
uint64 GL_GetCurrentState();
uint64 GL_GetCurrentStateMinusStencil();
void GL_Cull( int cullType );
void GL_Scissor( int x /* left*/, int y /* bottom */, int w, int h );
void GL_Viewport( int x /* left */, int y /* bottom */, int w, int h );
ID_INLINE void GL_Scissor( const idScreenRect& rect )
{
GL_Scissor( rect.x1, rect.y1, rect.x2 - rect.x1 + 1, rect.y2 - rect.y1 + 1 );
}
ID_INLINE void GL_Viewport( const idScreenRect& rect )
{
GL_Viewport( rect.x1, rect.y1, rect.x2 - rect.x1 + 1, rect.y2 - rect.y1 + 1 );
}
ID_INLINE void GL_ViewportAndScissor( int x, int y, int w, int h )
{
GL_Viewport( x, y, w, h );
GL_Scissor( x, y, w, h );
}
ID_INLINE void GL_ViewportAndScissor( const idScreenRect& rect )
{
GL_Viewport( rect );
GL_Scissor( rect );
}
// RB: HDR parm
void GL_Clear( bool color, bool depth, bool stencil, byte stencilValue, float r, float g, float b, float a, bool clearHDR = true );
// RB end
void GL_PolygonOffset( float scale, float bias );
void GL_DepthBoundsTest( const float zmin, const float zmax );
//void GL_Color( float* color );
// RB begin
void GL_Color( const idVec3& color );
void GL_Color( const idVec4& color );
// RB end
void GL_Color( float r, float g, float b );
void GL_Color( float r, float g, float b, float a );
void GL_SelectTexture( int unit );
void GL_Flush(); // flush the GPU command buffer
void GL_Finish(); // wait for the GPU to have executed all commands
// RB begin
bool GL_CheckErrors_( const char* filename, int line );
#if 1 // !defined(RETAIL)
#define GL_CheckErrors() GL_CheckErrors_(__FILE__, __LINE__)
#else
#define GL_CheckErrors() false
#endif
// RB end
wrapperStats_t GL_GetCurrentStats();
void GL_ClearStats();
#endif // !__GRAPHICSAPIWRAPPER_H__

View file

@ -29,7 +29,7 @@ If you have questions concerning this license or the applicable additional terms
#pragma hdrstop
#include "precompiled.h"
#include "tr_local.h"
#include "RenderCommon.h"
const float idGuiModel::STEREO_DEPTH_NEAR = 0.0f;
const float idGuiModel::STEREO_DEPTH_MID = 0.5f;

View file

@ -42,16 +42,16 @@ class idGuiModel
public:
idGuiModel();
void Clear();
void Clear();
void WriteToDemo( idDemoFile* demo );
void ReadFromDemo( idDemoFile* demo );
void WriteToDemo( idDemoFile* demo );
void ReadFromDemo( idDemoFile* demo );
// allocates memory for verts and indexes in frame-temporary buffer memory
void BeginFrame();
void BeginFrame();
void EmitToCurrentView( float modelMatrix[16], bool depthHack );
void EmitFullScreen();
void EmitToCurrentView( float modelMatrix[16], bool depthHack );
void EmitFullScreen();
// the returned pointer will be in write-combined memory, so only make contiguous
// 32 bit writes and never read from it.
@ -60,10 +60,9 @@ public:
//---------------------------
private:
void AdvanceSurf();
void EmitSurfaces( float modelMatrix[16], float modelViewMatrix[16],
bool depthHack, bool allowFullScreenStereoDepth, bool linkAsEntity );
void AdvanceSurf();
void EmitSurfaces( float modelMatrix[16], float modelViewMatrix[16], bool depthHack, bool allowFullScreenStereoDepth, bool linkAsEntity );
guiModelSurface_t* surf;
float shaderParms[ MAX_ENTITY_SHADER_PARMS ];
@ -81,8 +80,8 @@ private:
idDrawVert* vertexPointer;
triIndex_t* indexPointer;
int numVerts;
int numIndexes;
int numVerts;
int numIndexes;
idList<guiModelSurface_t, TAG_MODEL> surfaces;
};

View file

@ -3,7 +3,8 @@
Doom 3 BFG Edition GPL Source Code
Copyright (C) 1993-2012 id Software LLC, a ZeniMax Media company.
Copyright (C) 2013-2014 Robert Beckebans
Copyright (C) 2013-2017 Robert Beckebans
Copyright (C) 2016-2017 Dustin Land
This file is part of the Doom 3 BFG Edition GPL Source Code ("Doom 3 BFG Edition Source Code").
@ -27,6 +28,164 @@ If you have questions concerning this license or the applicable additional terms
===========================================================================
*/
enum textureType_t
{
TT_DISABLED,
TT_2D,
TT_CUBIC,
// RB begin
TT_2D_ARRAY,
TT_2D_MULTISAMPLE
// RB end
};
/*
================================================
The internal *Texture Format Types*, ::textureFormat_t, are:
================================================
*/
enum textureFormat_t
{
FMT_NONE,
//------------------------
// Standard color image formats
//------------------------
FMT_RGBA8, // 32 bpp
FMT_XRGB8, // 32 bpp
//------------------------
// Alpha channel only
//------------------------
// Alpha ends up being the same as L8A8 in our current implementation, because straight
// alpha gives 0 for color, but we want 1.
FMT_ALPHA,
//------------------------
// Luminance replicates the value across RGB with a constant A of 255
// Intensity replicates the value across RGBA
//------------------------
FMT_L8A8, // 16 bpp
FMT_LUM8, // 8 bpp
FMT_INT8, // 8 bpp
//------------------------
// Compressed texture formats
//------------------------
FMT_DXT1, // 4 bpp
FMT_DXT5, // 8 bpp
//------------------------
// Depth buffer formats
//------------------------
FMT_DEPTH, // 24 bpp
//------------------------
//
//------------------------
FMT_X16, // 16 bpp
FMT_Y16_X16, // 32 bpp
FMT_RGB565, // 16 bpp
// RB: don't change above for legacy .bimage compatibility
FMT_ETC1_RGB8_OES, // 4 bpp
FMT_SHADOW_ARRAY, // 32 bpp * 6
FMT_RGBA16F, // 64 bpp
FMT_RGBA32F, // 128 bpp
FMT_R32F, // 32 bpp
// RB end
};
int BitsForFormat( textureFormat_t format );
enum textureSamples_t
{
SAMPLE_1 = BIT( 0 ),
SAMPLE_2 = BIT( 1 ),
SAMPLE_4 = BIT( 2 ),
SAMPLE_8 = BIT( 3 ),
SAMPLE_16 = BIT( 4 )
};
/*
================================================
DXT5 color formats
================================================
*/
enum textureColor_t
{
CFM_DEFAULT, // RGBA
CFM_NORMAL_DXT5, // XY format and use the fast DXT5 compressor
CFM_YCOCG_DXT5, // convert RGBA to CoCg_Y format
CFM_GREEN_ALPHA, // Copy the alpha channel to green
// RB: don't change above for legacy .bimage compatibility
CFM_YCOCG_RGBA8,
// RB end
};
/*
================================================
idImageOpts hold parameters for texture operations.
================================================
*/
class idImageOpts
{
public:
idImageOpts();
bool operator==( const idImageOpts& opts );
//---------------------------------------------------
// these determine the physical memory size and layout
//---------------------------------------------------
textureType_t textureType;
textureFormat_t format;
textureColor_t colorFormat;
textureSamples_t samples;
int width;
int height; // not needed for cube maps
int numLevels; // if 0, will be 1 for NEAREST / LINEAR filters, otherwise based on size
bool gammaMips; // if true, mips will be generated with gamma correction
bool readback; // 360 specific - cpu reads back from this texture, so allocate with cached memory
};
/*
========================
idImageOpts::idImageOpts
========================
*/
ID_INLINE idImageOpts::idImageOpts()
{
format = FMT_NONE;
colorFormat = CFM_DEFAULT;
samples = SAMPLE_1;
width = 0;
height = 0;
numLevels = 0;
textureType = TT_2D;
gammaMips = false;
readback = false;
};
/*
========================
idImageOpts::operator==
========================
*/
ID_INLINE bool idImageOpts::operator==( const idImageOpts& opts )
{
return ( memcmp( this, &opts, sizeof( *this ) ) == 0 );
}
/*
====================================================================
@ -79,7 +238,6 @@ enum imageFileType_t
JPG
};
#include "ImageOpts.h"
#include "BinaryImage.h"
#define MAX_IMAGE_NAME 256
@ -90,6 +248,7 @@ class idImage
public:
idImage( const char* name );
~idImage();
const char* GetName() const
{
@ -101,18 +260,6 @@ public:
// May perform file loading if the image was not preloaded.
void Bind();
// Should be called at least once
void SetSamplerState( textureFilter_t tf, textureRepeat_t tr );
// used by callback functions to specify the actual data
// data goes from the bottom to the top line of the image, as OpenGL expects it
// These perform an implicit Bind() on the current texture unit
// FIXME: should we implement cinematics this way, instead of with explicit calls?
void GenerateImage( const byte* pic, int width, int height,
textureFilter_t filter, textureRepeat_t repeat, textureUsage_t usage, int msaaSamples = 0 );
void GenerateCubeImage( const byte* pic[6], int size,
textureFilter_t filter, textureUsage_t usage );
// RB begin
void GenerateShadowArray( int width, int height, textureFilter_t filter, textureRepeat_t repeat, textureUsage_t usage );
// RB end
@ -164,6 +311,26 @@ public:
// Platform specific implementations
//---------------------------------------------
#if defined( ID_VULKAN )
void CreateFromSwapImage( VkImage image, VkImageView imageView, VkFormat format, const VkExtent2D& extent );
VkImage GetImage() const
{
return image;
}
VkImageView GetView() const
{
return view;
}
VkImageLayout GetLayout() const
{
return layout;
}
VkSampler GetSampler() const
{
return sampler;
}
#endif
void AllocImage( const idImageOpts& imgOpts, textureFilter_t filter, textureRepeat_t repeat );
// Deletes the texture object, but leaves the structure so it can be reloaded
@ -196,20 +363,37 @@ public:
return ( opts.format == FMT_DXT1 || opts.format == FMT_DXT5 );
}
void SetTexParameters(); // update aniso and trilinear
bool IsLoaded() const
{
return texnum != TEXTURE_NOT_LOADED;
}
static void GetGeneratedName( idStr& _name, const textureUsage_t& _usage, const cubeFiles_t& _cube );
static void GetGeneratedName( idStr& _name, const textureUsage_t& _usage, const cubeFiles_t& _cube );
// used by callback functions to specify the actual data
// data goes from the bottom to the top line of the image, as OpenGL expects it
// These perform an implicit Bind() on the current texture unit
// FIXME: should we implement cinematics this way, instead of with explicit calls?
void GenerateImage( const byte* pic,
int width, int height,
textureFilter_t filter,
textureRepeat_t repeat,
textureUsage_t usage,
int msaaSamples = 0 );
void GenerateCubeImage( const byte* pic[6], int size,
textureFilter_t filter, textureUsage_t usage );
void SetTexParameters(); // update aniso and trilinear
private:
friend class idImageManager;
void AllocImage();
void DeriveOpts();
void DeriveOpts();
void AllocImage();
void SetSamplerState( textureFilter_t tf, textureRepeat_t tr );
// parameters that define this image
idStr imgName; // game path, including extension (except for cube maps), may be an image program
@ -232,37 +416,36 @@ private:
static const GLuint TEXTURE_NOT_LOADED = 0xFFFFFFFF;
#if defined( ID_VULKAN )
bool bIsSwapChainImage;
VkFormat internalFormat;
VkImage image;
VkImageView view;
VkImageLayout layout;
VkSampler sampler;
#if defined( ID_USE_AMD_ALLOCATOR )
VmaAllocation allocation;
static idList< VmaAllocation > allocationGarbage[ NUM_FRAME_DATA ];
#else
vulkanAllocation_t allocation;
static idList< vulkanAllocation_t > allocationGarbage[ NUM_FRAME_DATA ];
#endif
static int garbageIndex;
static idList< VkImage > imageGarbage[ NUM_FRAME_DATA ];
static idList< VkImageView > viewGarbage[ NUM_FRAME_DATA ];
static idList< VkSampler > samplerGarbage[ NUM_FRAME_DATA ];
#else
GLuint texnum; // gl texture binding
// we could derive these in subImageUpload each time if necessary
GLuint internalFormat;
GLuint dataFormat;
GLuint dataType;
#endif
};
ID_INLINE idImage::idImage( const char* name ) : imgName( name )
{
texnum = TEXTURE_NOT_LOADED;
internalFormat = 0;
dataFormat = 0;
dataType = 0;
generatorFunction = NULL;
filter = TF_DEFAULT;
repeat = TR_REPEAT;
usage = TD_DEFAULT;
cubeFiles = CF_2D;
referencedOutsideLevelLoad = false;
levelLoadReferenced = false;
defaulted = false;
sourceFileTime = FILE_NOT_FOUND_TIMESTAMP;
binaryFileTime = FILE_NOT_FOUND_TIMESTAMP;
refCount = 0;
}
// data is RGBA
void R_WriteTGA( const char* filename, const byte* data, int width, int height, bool flipVertical = false, const char* basePath = "fs_savepath" );
// data is in top-to-bottom raster order unless flipVertical is set
@ -313,12 +496,6 @@ public:
// reloads all apropriate images after a vid_restart
void ReloadImages( bool all );
// unbind all textures from all texture units
void UnbindAll();
// disable the active texture unit
void BindNull();
// Called only by renderSystem::BeginLevelLoad
void BeginLevelLoad();
@ -330,14 +507,10 @@ public:
// Loads unloaded level images
int LoadLevelImages( bool pacifier );
// used to clear and then write the dds conversion batch file
void StartBuild();
void FinishBuild( bool removeDups = false );
void PrintMemInfo( MemInfo_t* mi );
// built-in images
void CreateIntrinsicImages();
void CreateIntrinsicImages();
idImage* defaultImage;
idImage* flatNormalMap; // 128 128 255 in all pixels
idImage* alphaNotchImage; // 2x1 texture with just 1110 and 1111 with point sampling
@ -396,8 +569,6 @@ public:
extern idImageManager* globalImages; // pointer to global list for the rest of the system
int MakePowerOfTwo( int num );
/*
====================================================================

View file

@ -30,7 +30,7 @@ If you have questions concerning this license or the applicable additional terms
#include "precompiled.h"
#include "tr_local.h"
#include "RenderCommon.h"
// do this with a pointer, in case we want to make the actual manager
// a private virtual subclass
@ -63,7 +63,7 @@ void R_ReloadImages_f( const idCmdArgs& args )
}
else
{
common->Printf( "USAGE: reloadImages <all>\n" );
idLib::Printf( "USAGE: reloadImages <all>\n" );
return;
}
}
@ -81,7 +81,6 @@ typedef struct
/*
=======================
R_QsortImageSizes
=======================
*/
static int R_QsortImageSizes( const void* a, const void* b )
@ -105,7 +104,6 @@ static int R_QsortImageSizes( const void* a, const void* b )
/*
=======================
R_QsortImageName
=======================
*/
static int R_QsortImageName( const void* a, const void* b )
@ -180,20 +178,23 @@ void R_ListImages_f( const idCmdArgs& args )
if( failed )
{
common->Printf( "usage: listImages [ sorted | namesort | unloaded | duplicated | showOverSized ]\n" );
idLib::Printf( "usage: listImages [ sorted | namesort | unloaded | duplicated | showOverSized ]\n" );
return;
}
const char* header = " -w-- -h-- filt -fmt-- wrap size --name-------\n";
common->Printf( "\n%s", header );
idLib::Printf( "\n%s", header );
totalSize = 0;
sortedImage_t* sortedArray = ( sortedImage_t* )alloca( sizeof( sortedImage_t ) * globalImages->images.Num() );
idList< idImage* >& images = globalImages->images;
const int numImages = images.Num();
for( i = 0 ; i < globalImages->images.Num() ; i++ )
sortedImage_t* sortedArray = ( sortedImage_t* )alloca( sizeof( sortedImage_t ) * numImages );
for( i = 0 ; i < numImages; i++ )
{
image = globalImages->images[ i ];
image = images[ i ];
if( uncompressedOnly )
{
@ -211,14 +212,14 @@ void R_ListImages_f( const idCmdArgs& args )
if( duplicated )
{
int j;
for( j = i + 1 ; j < globalImages->images.Num() ; j++ )
for( j = i + 1 ; j < numImages ; j++ )
{
if( idStr::Icmp( image->GetName(), globalImages->images[ j ]->GetName() ) == 0 )
if( idStr::Icmp( image->GetName(), images[ j ]->GetName() ) == 0 )
{
break;
}
}
if( j == globalImages->images.Num() )
if( j == numImages )
{
continue;
}
@ -232,7 +233,7 @@ void R_ListImages_f( const idCmdArgs& args )
}
else
{
common->Printf( "%4i:", i );
idLib::Printf( "%4i:", i );
image->Print();
}
totalSize += image->StorageSize();
@ -252,20 +253,20 @@ void R_ListImages_f( const idCmdArgs& args )
partialSize = 0;
for( i = 0 ; i < count ; i++ )
{
common->Printf( "%4i:", sortedArray[i].index );
idLib::Printf( "%4i:", sortedArray[i].index );
sortedArray[i].image->Print();
partialSize += sortedArray[i].image->StorageSize();
if( ( ( i + 1 ) % 10 ) == 0 )
{
common->Printf( "-------- %5.1f of %5.1f megs --------\n",
partialSize / ( 1024 * 1024.0 ), totalSize / ( 1024 * 1024.0 ) );
idLib::Printf( "-------- %5.1f of %5.1f megs --------\n",
partialSize / ( 1024 * 1024.0 ), totalSize / ( 1024 * 1024.0 ) );
}
}
}
common->Printf( "%s", header );
common->Printf( " %i images (%i total)\n", count, globalImages->images.Num() );
common->Printf( " %5.1f total megabytes of images\n\n\n", totalSize / ( 1024 * 1024.0 ) );
idLib::Printf( "%s", header );
idLib::Printf( " %i images (%i total)\n", count, numImages );
idLib::Printf( " %5.1f total megabytes of images\n\n\n", totalSize / ( 1024 * 1024.0 ) );
}
/*
@ -280,7 +281,7 @@ idImage* idImageManager::AllocImage( const char* name )
{
if( strlen( name ) >= MAX_IMAGE_NAME )
{
common->Error( "idImageManager::AllocImage: \"%s\" is too long\n", name );
idLib::Error( "idImageManager::AllocImage: \"%s\" is too long\n", name );
}
int hash = idStr( name ).FileNameHash();
@ -356,62 +357,6 @@ idImage* idImageManager::ImageFromFunction( const char* _name, void ( *generator
return image;
}
/*
===============
GetImageWithParameters
==============
*/
idImage* idImageManager::GetImageWithParameters( const char* _name, textureFilter_t filter, textureRepeat_t repeat, textureUsage_t usage, cubeFiles_t cubeMap ) const
{
if( !_name || !_name[0] || idStr::Icmp( _name, "default" ) == 0 || idStr::Icmp( _name, "_default" ) == 0 )
{
declManager->MediaPrint( "DEFAULTED\n" );
return globalImages->defaultImage;
}
if( idStr::Icmpn( _name, "fonts", 5 ) == 0 || idStr::Icmpn( _name, "newfonts", 8 ) == 0 )
{
usage = TD_FONT;
}
if( idStr::Icmpn( _name, "lights", 6 ) == 0 )
{
usage = TD_LIGHT;
}
// strip any .tga file extensions from anywhere in the _name, including image program parameters
idStrStatic< MAX_OSPATH > name = _name;
name.Replace( ".tga", "" );
name.BackSlashesToSlashes();
int hash = name.FileNameHash();
for( int i = imageHash.First( hash ); i != -1; i = imageHash.Next( i ) )
{
idImage* image = images[i];
if( name.Icmp( image->GetName() ) == 0 )
{
// the built in's, like _white and _flat always match the other options
if( name[0] == '_' )
{
return image;
}
if( image->cubeFiles != cubeMap )
{
common->Error( "Image '%s' has been referenced with conflicting cube map states", _name );
}
if( image->filter != filter || image->repeat != repeat )
{
// we might want to have the system reset these parameters on every bind and
// share the image data
continue;
}
if( image->usage != usage )
{
// If an image is used differently then we need 2 copies of it because usage affects the way it's compressed and swizzled
continue;
}
return image;
}
}
return NULL;
}
/*
===============
ImageFromFile
@ -460,7 +405,7 @@ idImage* idImageManager::ImageFromFile( const char* _name, textureFilter_t filte
}
if( image->cubeFiles != cubeMap )
{
common->Error( "Image '%s' has been referenced with conflicting cube map states", _name );
idLib::Error( "Image '%s' has been referenced with conflicting cube map states", _name );
}
if( image->filter != filter || image->repeat != repeat )
@ -628,13 +573,9 @@ PurgeAllImages
*/
void idImageManager::PurgeAllImages()
{
int i;
idImage* image;
for( i = 0; i < images.Num() ; i++ )
for( int i = 0; i < images.Num() ; i++ )
{
image = images[i];
image->PurgeImage();
images[ i ]->PurgeImage();
}
}
@ -645,9 +586,9 @@ ReloadImages
*/
void idImageManager::ReloadImages( bool all )
{
for( int i = 0 ; i < globalImages->images.Num() ; i++ )
for( int i = 0 ; i < images.Num() ; i++ )
{
globalImages->images[ i ]->Reload( all );
images[ i ]->Reload( all );
}
}
@ -663,9 +604,9 @@ void R_CombineCubeImages_f( const idCmdArgs& args )
{
if( args.Argc() != 2 )
{
common->Printf( "usage: combineCubeImages <baseName>\n" );
common->Printf( " combines basename[1-6][0001-9999].tga to basenameCM[0001-9999].tga\n" );
common->Printf( " 1: forward 2:right 3:back 4:left 5:up 6:down\n" );
idLib::Printf( "usage: combineCubeImages <baseName>\n" );
idLib::Printf( " combines basename[1-6][0001-9999].tga to basenameCM[0001-9999].tga\n" );
idLib::Printf( " 1: forward 2:right 3:back 4:left 5:up 6:down\n" );
return;
}
@ -683,12 +624,12 @@ void R_CombineCubeImages_f( const idCmdArgs& args )
{
sprintf( filename, "%s%i%04i.tga", baseName.c_str(), orderRemap[side], frameNum );
common->Printf( "reading %s\n", filename );
idLib::Printf( "reading %s\n", filename );
R_LoadImage( filename, &pics[side], &width, &height, NULL, true );
if( !pics[side] )
{
common->Printf( "not found.\n" );
idLib::Printf( "not found.\n" );
break;
}
@ -736,39 +677,12 @@ void R_CombineCubeImages_f( const idCmdArgs& args )
}
sprintf( filename, "%sCM%04i.tga", baseName.c_str(), frameNum );
common->Printf( "writing %s\n", filename );
idLib::Printf( "writing %s\n", filename );
R_WriteTGA( filename, combined, width, height * 6 );
}
common->SetRefreshOnPrint( false );
}
/*
===============
UnbindAll
===============
*/
void idImageManager::UnbindAll()
{
int oldTMU = backEnd.glState.currenttmu;
for( int i = 0; i < MAX_PROG_TEXTURE_PARMS; ++i )
{
backEnd.glState.currenttmu = i;
BindNull();
}
backEnd.glState.currenttmu = oldTMU;
}
/*
===============
BindNull
===============
*/
void idImageManager::BindNull()
{
RENDERLOG_PRINTF( "BindNull()\n" );
}
/*
===============
Init
@ -870,7 +784,7 @@ void idImageManager::Preload( const idPreloadManifest& manifest, const bool& map
if( preLoad_Images.GetBool() && manifest.NumResources() > 0 )
{
// preload this levels images
common->Printf( "Preloading images...\n" );
idLib::Printf( "Preloading images...\n" );
preloadingMapImages = mapPreload;
int start = Sys_Milliseconds();
int numLoaded = 0;
@ -887,8 +801,8 @@ void idImageManager::Preload( const idPreloadManifest& manifest, const bool& map
}
//fileSystem->StopPreload();
int end = Sys_Milliseconds();
common->Printf( "%05d images preloaded ( or were already loaded ) in %5.1f seconds\n", numLoaded, ( end - start ) * 0.001 );
common->Printf( "----------------------------------------\n" );
idLib::Printf( "%05d images preloaded ( or were already loaded ) in %5.1f seconds\n", numLoaded, ( end - start ) * 0.001 );
idLib::Printf( "----------------------------------------\n" );
preloadingMapImages = false;
}
}
@ -932,34 +846,16 @@ void idImageManager::EndLevelLoad()
{
insideLevelLoad = false;
common->Printf( "----- idImageManager::EndLevelLoad -----\n" );
idLib::Printf( "----- idImageManager::EndLevelLoad -----\n" );
int start = Sys_Milliseconds();
int loadCount = LoadLevelImages( true );
int end = Sys_Milliseconds();
common->Printf( "%5i images loaded in %5.1f seconds\n", loadCount, ( end - start ) * 0.001 );
common->Printf( "----------------------------------------\n" );
idLib::Printf( "%5i images loaded in %5.1f seconds\n", loadCount, ( end - start ) * 0.001 );
idLib::Printf( "----------------------------------------\n" );
//R_ListImages_f( idCmdArgs( "sorted sorted", false ) );
}
/*
===============
idImageManager::StartBuild
===============
*/
void idImageManager::StartBuild()
{
}
/*
===============
idImageManager::FinishBuild
===============
*/
void idImageManager::FinishBuild( bool removeDups )
{
}
/*
===============
idImageManager::PrintMemInfo

View file

@ -1,185 +0,0 @@
/*
===========================================================================
Doom 3 BFG Edition GPL Source Code
Copyright (C) 1993-2012 id Software LLC, a ZeniMax Media company.
Copyright (C) 2013-2014 Robert Beckebans
This file is part of the Doom 3 BFG Edition GPL Source Code ("Doom 3 BFG Edition Source Code").
Doom 3 BFG Edition 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 3 of the License, or
(at your option) any later version.
Doom 3 BFG Edition 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 Doom 3 BFG Edition Source Code. If not, see <http://www.gnu.org/licenses/>.
In addition, the Doom 3 BFG Edition Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 BFG Edition Source Code. If not, please request a copy in writing from id Software at the address below.
If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
===========================================================================
*/
#ifndef __IMAGEOPTS_H__
#define __IMAGEOPTS_H__
enum textureType_t
{
TT_DISABLED,
TT_2D,
TT_CUBIC,
// RB begin
TT_2D_ARRAY,
TT_2D_MULTISAMPLE
// RB end
};
/*
================================================
The internal *Texture Format Types*, ::textureFormat_t, are:
================================================
*/
enum textureFormat_t
{
FMT_NONE,
//------------------------
// Standard color image formats
//------------------------
FMT_RGBA8, // 32 bpp
FMT_XRGB8, // 32 bpp
//------------------------
// Alpha channel only
//------------------------
// Alpha ends up being the same as L8A8 in our current implementation, because straight
// alpha gives 0 for color, but we want 1.
FMT_ALPHA,
//------------------------
// Luminance replicates the value across RGB with a constant A of 255
// Intensity replicates the value across RGBA
//------------------------
FMT_L8A8, // 16 bpp
FMT_LUM8, // 8 bpp
FMT_INT8, // 8 bpp
//------------------------
// Compressed texture formats
//------------------------
FMT_DXT1, // 4 bpp
FMT_DXT5, // 8 bpp
//------------------------
// Depth buffer formats
//------------------------
FMT_DEPTH, // 24 bpp
//------------------------
//
//------------------------
FMT_X16, // 16 bpp
FMT_Y16_X16, // 32 bpp
FMT_RGB565, // 16 bpp
// RB: don't change above for legacy .bimage compatibility
FMT_ETC1_RGB8_OES, // 4 bpp
FMT_SHADOW_ARRAY, // 32 bpp * 6
FMT_RGBA16F, // 64 bpp
FMT_RGBA32F, // 128 bpp
FMT_R32F, // 32 bpp
// RB end
};
int BitsForFormat( textureFormat_t format );
/*
================================================
DXT5 color formats
================================================
*/
enum textureColor_t
{
CFM_DEFAULT, // RGBA
CFM_NORMAL_DXT5, // XY format and use the fast DXT5 compressor
CFM_YCOCG_DXT5, // convert RGBA to CoCg_Y format
CFM_GREEN_ALPHA, // Copy the alpha channel to green
// RB: don't change above for legacy .bimage compatibility
CFM_YCOCG_RGBA8,
// RB end
};
/*
================================================
idImageOpts hold parameters for texture operations.
================================================
*/
class idImageOpts
{
public:
idImageOpts();
bool operator==( const idImageOpts& opts );
//---------------------------------------------------
// these determine the physical memory size and layout
//---------------------------------------------------
textureType_t textureType;
textureFormat_t format;
textureColor_t colorFormat;
int width;
int height; // not needed for cube maps
int numLevels; // if 0, will be 1 for NEAREST / LINEAR filters, otherwise based on size
bool gammaMips; // if true, mips will be generated with gamma correction
bool readback; // 360 specific - cpu reads back from this texture, so allocate with cached memory
// RB: for MSAA FBO targets
int msaaSamples;
// RB end
};
/*
========================
idImageOpts::idImageOpts
========================
*/
ID_INLINE idImageOpts::idImageOpts()
{
format = FMT_NONE;
colorFormat = CFM_DEFAULT;
width = 0;
height = 0;
numLevels = 0;
textureType = TT_2D;
gammaMips = false;
readback = false;
// RB begin
msaaSamples = 0;
// RB end
};
/*
========================
idImageOpts::operator==
========================
*/
ID_INLINE bool idImageOpts::operator==( const idImageOpts& opts )
{
return ( memcmp( this, &opts, sizeof( *this ) ) == 0 );
}
#endif

View file

@ -31,7 +31,7 @@ If you have questions concerning this license or the applicable additional terms
#include "precompiled.h"
#include "tr_local.h"
#include "RenderCommon.h"
/*

View file

@ -31,7 +31,7 @@ If you have questions concerning this license or the applicable additional terms
#include "precompiled.h"
#include "tr_local.h"
#include "RenderCommon.h"
#include "SMAA/AreaTex.h"
#include "SMAA/SearchTex.h"

View file

@ -3,8 +3,9 @@
Doom 3 BFG Edition GPL Source Code
Copyright (C) 1993-2012 id Software LLC, a ZeniMax Media company.
Copyright (C) 2013-2016 Robert Beckebans
Copyright (C) 2013-2017 Robert Beckebans
Copyright (C) 2014-2016 Kot in Action Creative Artel
Copyright (C) 2016-2017 Dustin Land
This file is part of the Doom 3 BFG Edition GPL Source Code ("Doom 3 BFG Edition Source Code").
@ -32,7 +33,7 @@ If you have questions concerning this license or the applicable additional terms
#include "precompiled.h"
#include "framework/Common_local.h"
#include "tr_local.h"
#include "RenderCommon.h"
/*
================
@ -94,7 +95,6 @@ idImage::DeriveOpts
*/
ID_INLINE void idImage::DeriveOpts()
{
if( opts.format == FMT_NONE )
{
opts.colorFormat = CFM_DEFAULT;
@ -152,7 +152,9 @@ ID_INLINE void idImage::DeriveOpts()
opts.gammaMips = true;
break;
case TD_LIGHT:
// RB: don't destroy lighting
// RB: TODO check binary format version
// D3 BFG assets require RGB565 but it introduces color banding
// mods would prefer FMT_RGBA8
opts.format = FMT_RGB565; //FMT_RGBA8;
opts.gammaMips = true;
break;
@ -213,172 +215,6 @@ void idImage::AllocImage( const idImageOpts& imgOpts, textureFilter_t tf, textur
AllocImage();
}
/*
================
GenerateImage
================
*/
void idImage::GenerateImage( const byte* pic, int width, int height, textureFilter_t filterParm, textureRepeat_t repeatParm, textureUsage_t usageParm, int msaaSamples )
{
PurgeImage();
filter = filterParm;
repeat = repeatParm;
usage = usageParm;
cubeFiles = CF_2D;
opts.textureType = ( msaaSamples > 0 ) ? TT_2D_MULTISAMPLE : TT_2D;
opts.width = width;
opts.height = height;
opts.numLevels = 0;
opts.msaaSamples = msaaSamples;
DeriveOpts();
// if we don't have a rendering context, just return after we
// have filled in the parms. We must have the values set, or
// an image match from a shader before the render starts would miss
// the generated texture
if( !R_IsInitialized() )
{
return;
}
// RB: allow pic == NULL for internal framebuffer images
if( pic == NULL || opts.textureType == TT_2D_MULTISAMPLE )
{
AllocImage();
}
else
{
idBinaryImage im( GetName() );
// foresthale 2014-05-30: give a nice progress display when binarizing
commonLocal.LoadPacifierBinarizeFilename( GetName() , "generated image" );
if( opts.numLevels > 1 )
{
commonLocal.LoadPacifierBinarizeProgressTotal( opts.width * opts.height * 4 / 3 );
}
else
{
commonLocal.LoadPacifierBinarizeProgressTotal( opts.width * opts.height );
}
im.Load2DFromMemory( width, height, pic, opts.numLevels, opts.format, opts.colorFormat, opts.gammaMips );
commonLocal.LoadPacifierBinarizeEnd();
AllocImage();
for( int i = 0; i < im.NumImages(); i++ )
{
const bimageImage_t& img = im.GetImageHeader( i );
const byte* data = im.GetImageData( i );
SubImageUpload( img.level, 0, 0, img.destZ, img.width, img.height, data );
}
}
// RB end
}
/*
====================
GenerateCubeImage
Non-square cube sides are not allowed
====================
*/
void idImage::GenerateCubeImage( const byte* pic[6], int size, textureFilter_t filterParm, textureUsage_t usageParm )
{
PurgeImage();
filter = filterParm;
repeat = TR_CLAMP;
usage = usageParm;
cubeFiles = CF_NATIVE;
opts.textureType = TT_CUBIC;
opts.width = size;
opts.height = size;
opts.numLevels = 0;
DeriveOpts();
// if we don't have a rendering context, just return after we
// have filled in the parms. We must have the values set, or
// an image match from a shader before the render starts would miss
// the generated texture
if( !R_IsInitialized() )
{
return;
}
idBinaryImage im( GetName() );
// foresthale 2014-05-30: give a nice progress display when binarizing
commonLocal.LoadPacifierBinarizeFilename( GetName(), "generated cube image" );
if( opts.numLevels > 1 )
{
commonLocal.LoadPacifierBinarizeProgressTotal( opts.width * opts.width * 6 * 4 / 3 );
}
else
{
commonLocal.LoadPacifierBinarizeProgressTotal( opts.width * opts.width * 6 );
}
im.LoadCubeFromMemory( size, pic, opts.numLevels, opts.format, opts.gammaMips );
commonLocal.LoadPacifierBinarizeEnd();
AllocImage();
for( int i = 0; i < im.NumImages(); i++ )
{
const bimageImage_t& img = im.GetImageHeader( i );
const byte* data = im.GetImageData( i );
SubImageUpload( img.level, 0, 0, img.destZ, img.width, img.height, data );
}
}
// RB begin
void idImage::GenerateShadowArray( int width, int height, textureFilter_t filterParm, textureRepeat_t repeatParm, textureUsage_t usageParm )
{
PurgeImage();
filter = filterParm;
repeat = repeatParm;
usage = usageParm;
cubeFiles = CF_2D_ARRAY;
opts.textureType = TT_2D_ARRAY;
opts.width = width;
opts.height = height;
opts.numLevels = 0;
DeriveOpts();
// if we don't have a rendering context, just return after we
// have filled in the parms. We must have the values set, or
// an image match from a shader before the render starts would miss
// the generated texture
if( !R_IsInitialized() )
{
return;
}
//idBinaryImage im( GetName() );
//im.Load2DFromMemory( width, height, pic, opts.numLevels, opts.format, opts.colorFormat, opts.gammaMips );
AllocImage();
/*
for( int i = 0; i < im.NumImages(); i++ )
{
const bimageImage_t& img = im.GetImageHeader( i );
const byte* data = im.GetImageData( i );
SubImageUpload( img.level, 0, 0, img.destZ, img.width, img.height, data );
}
*/
}
// RB end
/*
===============
GetGeneratedName
@ -436,12 +272,11 @@ void idImage::ActuallyLoadImage( bool fromBackEnd )
}
else
{
// RB begin
// RB: added CF_2D_ARRAY
if( cubeFiles == CF_2D_ARRAY )
{
opts.textureType = TT_2D_ARRAY;
}
// RB end
else if( cubeFiles != CF_2D )
{
opts.textureType = TT_CUBIC;
@ -649,7 +484,6 @@ void idImage::ActuallyLoadImage( bool fromBackEnd )
AllocImage();
for( int i = 0; i < im.NumImages(); i++ )
{
const bimageImage_t& img = im.GetImageHeader( i );
@ -658,280 +492,6 @@ void idImage::ActuallyLoadImage( bool fromBackEnd )
}
}
/*
==============
Bind
Automatically enables 2D mapping or cube mapping if needed
==============
*/
void idImage::Bind()
{
RENDERLOG_PRINTF( "idImage::Bind( %s )\n", GetName() );
// load the image if necessary (FIXME: not SMP safe!)
if( !IsLoaded() )
{
// load the image on demand here, which isn't our normal game operating mode
ActuallyLoadImage( true );
}
const int texUnit = backEnd.glState.currenttmu;
// RB: added support for more types
tmu_t* tmu = &backEnd.glState.tmu[texUnit];
// bind the texture
if( opts.textureType == TT_2D )
{
if( tmu->current2DMap != texnum )
{
tmu->current2DMap = texnum;
#if !defined(USE_GLES2) && !defined(USE_GLES3)
if( glConfig.directStateAccess )
{
glBindMultiTextureEXT( GL_TEXTURE0 + texUnit, GL_TEXTURE_2D, texnum );
}
else
#endif
{
glActiveTexture( GL_TEXTURE0 + texUnit );
glBindTexture( GL_TEXTURE_2D, texnum );
}
}
}
else if( opts.textureType == TT_CUBIC )
{
if( tmu->currentCubeMap != texnum )
{
tmu->currentCubeMap = texnum;
#if !defined(USE_GLES2) && !defined(USE_GLES3)
if( glConfig.directStateAccess )
{
glBindMultiTextureEXT( GL_TEXTURE0 + texUnit, GL_TEXTURE_CUBE_MAP, texnum );
}
else
#endif
{
glActiveTexture( GL_TEXTURE0 + texUnit );
glBindTexture( GL_TEXTURE_CUBE_MAP, texnum );
}
}
}
else if( opts.textureType == TT_2D_ARRAY )
{
if( tmu->current2DArray != texnum )
{
tmu->current2DArray = texnum;
#if !defined(USE_GLES2) && !defined(USE_GLES3)
if( glConfig.directStateAccess )
{
glBindMultiTextureEXT( GL_TEXTURE0 + texUnit, GL_TEXTURE_2D_ARRAY, texnum );
}
else
#endif
{
glActiveTexture( GL_TEXTURE0 + texUnit );
glBindTexture( GL_TEXTURE_2D_ARRAY, texnum );
}
}
}
else if( opts.textureType == TT_2D_MULTISAMPLE )
{
if( tmu->current2DMap != texnum )
{
tmu->current2DMap = texnum;
#if !defined(USE_GLES2) && !defined(USE_GLES3)
if( glConfig.directStateAccess )
{
glBindMultiTextureEXT( GL_TEXTURE0 + texUnit, GL_TEXTURE_2D_MULTISAMPLE, texnum );
}
else
#endif
{
glActiveTexture( GL_TEXTURE0 + texUnit );
glBindTexture( GL_TEXTURE_2D_MULTISAMPLE, texnum );
}
}
}
// RB end
}
/*
================
MakePowerOfTwo
================
*/
int MakePowerOfTwo( int num )
{
int pot;
for( pot = 1; pot < num; pot <<= 1 )
{
}
return pot;
}
/*
====================
CopyFramebuffer
====================
*/
void idImage::CopyFramebuffer( int x, int y, int imageWidth, int imageHeight )
{
int target = GL_TEXTURE_2D;
switch( opts.textureType )
{
case TT_2D:
target = GL_TEXTURE_2D;
break;
case TT_CUBIC:
target = GL_TEXTURE_CUBE_MAP;
break;
case TT_2D_ARRAY:
target = GL_TEXTURE_2D_ARRAY;
break;
case TT_2D_MULTISAMPLE:
target = GL_TEXTURE_2D_MULTISAMPLE;
break;
default:
//idLib::FatalError( "%s: bad texture type %d", GetName(), opts.textureType );
return;
}
glBindTexture( target, texnum );
#if !defined(USE_GLES2)
if( Framebuffer::IsDefaultFramebufferActive() )
{
glReadBuffer( GL_BACK );
}
#endif
opts.width = imageWidth;
opts.height = imageHeight;
#if defined(USE_GLES2)
glCopyTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, x, y, imageWidth, imageHeight, 0 );
#else
if( r_useHDR.GetBool() && globalFramebuffers.hdrFBO->IsBound() )
{
//if( backEnd.glState.currentFramebuffer != NULL && backEnd.glState.currentFramebuffer->IsMultiSampled() )
#if defined(USE_HDR_MSAA)
if( globalFramebuffers.hdrFBO->IsMultiSampled() )
{
glBindFramebuffer( GL_READ_FRAMEBUFFER, globalFramebuffers.hdrFBO->GetFramebuffer() );
glBindFramebuffer( GL_DRAW_FRAMEBUFFER, globalFramebuffers.hdrNonMSAAFBO->GetFramebuffer() );
glBlitFramebuffer( 0, 0, glConfig.nativeScreenWidth, glConfig.nativeScreenHeight,
0, 0, glConfig.nativeScreenWidth, glConfig.nativeScreenHeight,
GL_COLOR_BUFFER_BIT,
GL_LINEAR );
globalFramebuffers.hdrNonMSAAFBO->Bind();
glCopyTexImage2D( target, 0, GL_RGBA16F, x, y, imageWidth, imageHeight, 0 );
globalFramebuffers.hdrFBO->Bind();
}
else
#endif
{
glCopyTexImage2D( target, 0, GL_RGBA16F, x, y, imageWidth, imageHeight, 0 );
}
}
else
{
glCopyTexImage2D( target, 0, GL_RGBA8, x, y, imageWidth, imageHeight, 0 );
}
#endif
// these shouldn't be necessary if the image was initialized properly
glTexParameterf( target, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
glTexParameterf( target, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
glTexParameterf( target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE );
glTexParameterf( target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE );
backEnd.pc.c_copyFrameBuffer++;
}
/*
====================
CopyDepthbuffer
====================
*/
void idImage::CopyDepthbuffer( int x, int y, int imageWidth, int imageHeight )
{
glBindTexture( ( opts.textureType == TT_CUBIC ) ? GL_TEXTURE_CUBE_MAP : GL_TEXTURE_2D, texnum );
opts.width = imageWidth;
opts.height = imageHeight;
glCopyTexImage2D( GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, x, y, imageWidth, imageHeight, 0 );
backEnd.pc.c_copyFrameBuffer++;
}
/*
=============
RB_UploadScratchImage
if rows = cols * 6, assume it is a cube map animation
=============
*/
void idImage::UploadScratch( const byte* data, int cols, int rows )
{
// if rows = cols * 6, assume it is a cube map animation
if( rows == cols * 6 )
{
rows /= 6;
const byte* pic[6];
for( int i = 0; i < 6; i++ )
{
pic[i] = data + cols * rows * 4 * i;
}
if( opts.textureType != TT_CUBIC || usage != TD_LOOKUP_TABLE_RGBA )
{
GenerateCubeImage( pic, cols, TF_LINEAR, TD_LOOKUP_TABLE_RGBA );
return;
}
if( opts.width != cols || opts.height != rows )
{
opts.width = cols;
opts.height = rows;
AllocImage();
}
SetSamplerState( TF_LINEAR, TR_CLAMP );
for( int i = 0; i < 6; i++ )
{
SubImageUpload( 0, 0, 0, i, opts.width, opts.height, pic[i] );
}
}
else
{
if( opts.textureType != TT_2D || usage != TD_LOOKUP_TABLE_RGBA )
{
GenerateImage( data, cols, rows, TF_LINEAR, TR_REPEAT, TD_LOOKUP_TABLE_RGBA );
return;
}
if( opts.width != cols || opts.height != rows )
{
opts.width = cols;
opts.height = rows;
AllocImage();
}
SetSamplerState( TF_LINEAR, TR_REPEAT );
SubImageUpload( 0, 0, 0, 0, opts.width, opts.height, data );
}
}
/*
==================
StorageSize
@ -1124,3 +684,224 @@ void idImage::SetSamplerState( textureFilter_t tf, textureRepeat_t tr )
glBindTexture( ( opts.textureType == TT_CUBIC ) ? GL_TEXTURE_CUBE_MAP : GL_TEXTURE_2D, texnum );
SetTexParameters();
}
/*
================
GenerateImage
================
*/
void idImage::GenerateImage( const byte* pic, int width, int height, textureFilter_t filterParm, textureRepeat_t repeatParm, textureUsage_t usageParm, int msaaSamples )
{
PurgeImage();
filter = filterParm;
repeat = repeatParm;
usage = usageParm;
cubeFiles = CF_2D;
opts.textureType = ( msaaSamples > 0 ) ? TT_2D_MULTISAMPLE : TT_2D;
opts.width = width;
opts.height = height;
opts.numLevels = 0;
opts.samples = textureSamples_t( msaaSamples );
DeriveOpts();
// if we don't have a rendering context, just return after we
// have filled in the parms. We must have the values set, or
// an image match from a shader before the render starts would miss
// the generated texture
if( !R_IsInitialized() )
{
return;
}
// RB: allow pic == NULL for internal framebuffer images
if( pic == NULL || opts.textureType == TT_2D_MULTISAMPLE )
{
AllocImage();
}
else
{
idBinaryImage im( GetName() );
// foresthale 2014-05-30: give a nice progress display when binarizing
commonLocal.LoadPacifierBinarizeFilename( GetName() , "generated image" );
if( opts.numLevels > 1 )
{
commonLocal.LoadPacifierBinarizeProgressTotal( opts.width * opts.height * 4 / 3 );
}
else
{
commonLocal.LoadPacifierBinarizeProgressTotal( opts.width * opts.height );
}
im.Load2DFromMemory( width, height, pic, opts.numLevels, opts.format, opts.colorFormat, opts.gammaMips );
commonLocal.LoadPacifierBinarizeEnd();
AllocImage();
for( int i = 0; i < im.NumImages(); i++ )
{
const bimageImage_t& img = im.GetImageHeader( i );
const byte* data = im.GetImageData( i );
SubImageUpload( img.level, 0, 0, img.destZ, img.width, img.height, data );
}
}
// RB end
}
/*
====================
GenerateCubeImage
Non-square cube sides are not allowed
====================
*/
void idImage::GenerateCubeImage( const byte* pic[6], int size, textureFilter_t filterParm, textureUsage_t usageParm )
{
PurgeImage();
filter = filterParm;
repeat = TR_CLAMP;
usage = usageParm;
cubeFiles = CF_NATIVE;
opts.textureType = TT_CUBIC;
opts.width = size;
opts.height = size;
opts.numLevels = 0;
DeriveOpts();
// if we don't have a rendering context, just return after we
// have filled in the parms. We must have the values set, or
// an image match from a shader before the render starts would miss
// the generated texture
if( !R_IsInitialized() )
{
return;
}
idBinaryImage im( GetName() );
// foresthale 2014-05-30: give a nice progress display when binarizing
commonLocal.LoadPacifierBinarizeFilename( GetName(), "generated cube image" );
if( opts.numLevels > 1 )
{
commonLocal.LoadPacifierBinarizeProgressTotal( opts.width * opts.width * 6 * 4 / 3 );
}
else
{
commonLocal.LoadPacifierBinarizeProgressTotal( opts.width * opts.width * 6 );
}
im.LoadCubeFromMemory( size, pic, opts.numLevels, opts.format, opts.gammaMips );
commonLocal.LoadPacifierBinarizeEnd();
AllocImage();
for( int i = 0; i < im.NumImages(); i++ )
{
const bimageImage_t& img = im.GetImageHeader( i );
const byte* data = im.GetImageData( i );
SubImageUpload( img.level, 0, 0, img.destZ, img.width, img.height, data );
}
}
// RB begin
void idImage::GenerateShadowArray( int width, int height, textureFilter_t filterParm, textureRepeat_t repeatParm, textureUsage_t usageParm )
{
PurgeImage();
filter = filterParm;
repeat = repeatParm;
usage = usageParm;
cubeFiles = CF_2D_ARRAY;
opts.textureType = TT_2D_ARRAY;
opts.width = width;
opts.height = height;
opts.numLevels = 0;
DeriveOpts();
// if we don't have a rendering context, just return after we
// have filled in the parms. We must have the values set, or
// an image match from a shader before the render starts would miss
// the generated texture
if( !R_IsInitialized() )
{
return;
}
//idBinaryImage im( GetName() );
//im.Load2DFromMemory( width, height, pic, opts.numLevels, opts.format, opts.colorFormat, opts.gammaMips );
AllocImage();
/*
for( int i = 0; i < im.NumImages(); i++ )
{
const bimageImage_t& img = im.GetImageHeader( i );
const byte* data = im.GetImageData( i );
SubImageUpload( img.level, 0, 0, img.destZ, img.width, img.height, data );
}
*/
}
// RB end
/*
=============
RB_UploadScratchImage
if rows = cols * 6, assume it is a cube map animation
=============
*/
void idImage::UploadScratch( const byte* data, int cols, int rows )
{
// if rows = cols * 6, assume it is a cube map animation
if( rows == cols * 6 )
{
rows /= 6;
const byte* pic[6];
for( int i = 0; i < 6; i++ )
{
pic[i] = data + cols * rows * 4 * i;
}
if( opts.textureType != TT_CUBIC || usage != TD_LOOKUP_TABLE_RGBA )
{
GenerateCubeImage( pic, cols, TF_LINEAR, TD_LOOKUP_TABLE_RGBA );
return;
}
if( opts.width != cols || opts.height != rows )
{
opts.width = cols;
opts.height = rows;
AllocImage();
}
SetSamplerState( TF_LINEAR, TR_CLAMP );
for( int i = 0; i < 6; i++ )
{
SubImageUpload( 0, 0, 0, i, opts.width, opts.height, pic[i] );
}
}
else
{
if( opts.textureType != TT_2D || usage != TD_LOOKUP_TABLE_RGBA )
{
GenerateImage( data, cols, rows, TF_LINEAR, TR_REPEAT, TD_LOOKUP_TABLE_RGBA );
return;
}
if( opts.width != cols || opts.height != rows )
{
opts.width = cols;
opts.height = rows;
AllocImage();
}
SetSamplerState( TF_LINEAR, TR_REPEAT );
SubImageUpload( 0, 0, 0, 0, opts.width, opts.height, data );
}
}

View file

@ -29,7 +29,7 @@ If you have questions concerning this license or the applicable additional terms
#include "precompiled.h"
#include "tr_local.h"
#include "RenderCommon.h"
/*
================

View file

@ -56,7 +56,7 @@ Manager
// tr_imageprogram.c
#include "tr_local.h"
#include "RenderCommon.h"
/*
@ -419,8 +419,7 @@ static bool R_ParseImageProgram_r( idLexer& src, byte** pic, int* width, int* he
ID_TIME_T* timestamps, textureUsage_t* usage )
{
idToken token;
float scale;
ID_TIME_T timestamp;
ID_TIME_T timestamp;
src.ReadToken( &token );
@ -454,7 +453,7 @@ static bool R_ParseImageProgram_r( idLexer& src, byte** pic, int* width, int* he
src.ReadToken( &token );
AppendToken( token );
scale = token.GetFloatValue();
float scale = token.GetFloatValue();
// process it
if( pic )
@ -637,7 +636,7 @@ static bool R_ParseImageProgram_r( idLexer& src, byte** pic, int* width, int* he
if( pic )
{
int c;
c = *width** height * 4;
c = *width * *height * 4;
for( i = 0 ; i < c ; i += 4 )
{
( *pic )[i + 1] =
@ -662,7 +661,7 @@ static bool R_ParseImageProgram_r( idLexer& src, byte** pic, int* width, int* he
if( pic )
{
int c;
c = *width** height * 4;
c = *width * *height * 4;
for( i = 0 ; i < c ; i += 4 )
{
( *pic )[i + 3] = ( ( *pic )[i + 0] + ( *pic )[i + 1] + ( *pic )[i + 2] ) / 3;

View file

@ -29,7 +29,7 @@ If you have questions concerning this license or the applicable additional terms
#pragma hdrstop
#include "precompiled.h"
#include "tr_local.h"
#include "RenderCommon.h"
/*
===========================================================================

View file

@ -32,7 +32,7 @@ If you have questions concerning this license or the applicable additional terms
#include "precompiled.h"
#include "tr_local.h"
#include "RenderCommon.h"
/*

View file

@ -32,7 +32,7 @@ If you have questions concerning this license or the applicable additional terms
#include "precompiled.h"
#include "tr_local.h"
#include "RenderCommon.h"
#include "Model_local.h"
#include "Model_ase.h"
#include "Model_lwo.h"

View file

@ -31,7 +31,7 @@ If you have questions concerning this license or the applicable additional terms
#pragma hdrstop
#include "precompiled.h"
#include "tr_local.h"
#include "RenderCommon.h"
#include "Model_local.h"
#include "../idlib/geometry/DrawVert_intrinsics.h"

View file

@ -30,7 +30,7 @@ If you have questions concerning this license or the applicable additional terms
#include "precompiled.h"
#include "Model_local.h"
#include "tr_local.h" // just for R_FreeWorldInteractions and R_CreateWorldInteractions
#include "RenderCommon.h" // just for R_FreeWorldInteractions and R_CreateWorldInteractions
idCVar binaryLoadRenderModels( "binaryLoadRenderModels", "1", 0, "enable binary load/write of render models" );
idCVar preload_MapModels( "preload_MapModels", "1", CVAR_SYSTEM | CVAR_BOOL, "preload models during begin or end levelload" );

View file

@ -31,7 +31,7 @@ If you have questions concerning this license or the applicable additional terms
#pragma hdrstop
#include "precompiled.h"
#include "tr_local.h"
#include "RenderCommon.h"
#include "Model_local.h"
#include "../idlib/geometry/DrawVert_intrinsics.h"

View file

@ -30,7 +30,7 @@ If you have questions concerning this license or the applicable additional terms
#include "precompiled.h"
#include "tr_local.h"
#include "RenderCommon.h"
#include "Model_local.h"
/*

View file

@ -30,7 +30,7 @@ If you have questions concerning this license or the applicable additional terms
#include "precompiled.h"
#include "tr_local.h"
#include "RenderCommon.h"
#include "Model_local.h"
#define LIQUID_MAX_SKIP_FRAMES 5

View file

@ -29,7 +29,7 @@ If you have questions concerning this license or the applicable additional terms
#pragma hdrstop
#include "precompiled.h"
#include "tr_local.h"
#include "RenderCommon.h"
#include "Model_local.h"
#include "Model_md3.h"

View file

@ -30,7 +30,7 @@ If you have questions concerning this license or the applicable additional terms
#pragma hdrstop
#include "precompiled.h"
#include "tr_local.h"
#include "RenderCommon.h"
#include "Model_local.h"
#if defined(USE_INTRINSICS)

View file

@ -29,7 +29,7 @@ If you have questions concerning this license or the applicable additional terms
#pragma hdrstop
#include "precompiled.h"
#include "tr_local.h"
#include "RenderCommon.h"
#include "Model_local.h"
static const char* parametricParticle_SnapshotName = "_ParametricParticle_Snapshot_";

View file

@ -29,7 +29,7 @@ If you have questions concerning this license or the applicable additional terms
#pragma hdrstop
#include "precompiled.h"
#include "tr_local.h"
#include "RenderCommon.h"
#include "Model_local.h"

View file

@ -35,7 +35,245 @@ Contains the Image implementation for OpenGL.
================================================================================================
*/
#include "../tr_local.h"
#include "../RenderCommon.h"
/*
====================
idImage::idImage
====================
*/
idImage::idImage( const char* name ) : imgName( name )
{
texnum = TEXTURE_NOT_LOADED;
internalFormat = 0;
dataFormat = 0;
dataType = 0;
generatorFunction = NULL;
filter = TF_DEFAULT;
repeat = TR_REPEAT;
usage = TD_DEFAULT;
cubeFiles = CF_2D;
referencedOutsideLevelLoad = false;
levelLoadReferenced = false;
defaulted = false;
sourceFileTime = FILE_NOT_FOUND_TIMESTAMP;
binaryFileTime = FILE_NOT_FOUND_TIMESTAMP;
refCount = 0;
}
/*
====================
idImage::~idImage
====================
*/
idImage::~idImage()
{
PurgeImage();
}
/*
==============
Bind
Automatically enables 2D mapping or cube mapping if needed
==============
*/
void idImage::Bind()
{
RENDERLOG_PRINTF( "idImage::Bind( %s )\n", GetName() );
// load the image if necessary (FIXME: not SMP safe!)
if( !IsLoaded() )
{
// load the image on demand here, which isn't our normal game operating mode
ActuallyLoadImage( true );
}
const int texUnit = tr.backend.GetCurrentTextureUnit();
// RB: added support for more types
tmu_t* tmu = &glcontext.tmu[texUnit];
// bind the texture
if( opts.textureType == TT_2D )
{
if( tmu->current2DMap != texnum )
{
tmu->current2DMap = texnum;
#if !defined(USE_GLES2) && !defined(USE_GLES3)
if( glConfig.directStateAccess )
{
glBindMultiTextureEXT( GL_TEXTURE0 + texUnit, GL_TEXTURE_2D, texnum );
}
else
#endif
{
glActiveTexture( GL_TEXTURE0 + texUnit );
glBindTexture( GL_TEXTURE_2D, texnum );
}
}
}
else if( opts.textureType == TT_CUBIC )
{
if( tmu->currentCubeMap != texnum )
{
tmu->currentCubeMap = texnum;
#if !defined(USE_GLES2) && !defined(USE_GLES3)
if( glConfig.directStateAccess )
{
glBindMultiTextureEXT( GL_TEXTURE0 + texUnit, GL_TEXTURE_CUBE_MAP, texnum );
}
else
#endif
{
glActiveTexture( GL_TEXTURE0 + texUnit );
glBindTexture( GL_TEXTURE_CUBE_MAP, texnum );
}
}
}
else if( opts.textureType == TT_2D_ARRAY )
{
if( tmu->current2DArray != texnum )
{
tmu->current2DArray = texnum;
#if !defined(USE_GLES2) && !defined(USE_GLES3)
if( glConfig.directStateAccess )
{
glBindMultiTextureEXT( GL_TEXTURE0 + texUnit, GL_TEXTURE_2D_ARRAY, texnum );
}
else
#endif
{
glActiveTexture( GL_TEXTURE0 + texUnit );
glBindTexture( GL_TEXTURE_2D_ARRAY, texnum );
}
}
}
else if( opts.textureType == TT_2D_MULTISAMPLE )
{
if( tmu->current2DMap != texnum )
{
tmu->current2DMap = texnum;
#if !defined(USE_GLES2) && !defined(USE_GLES3)
if( glConfig.directStateAccess )
{
glBindMultiTextureEXT( GL_TEXTURE0 + texUnit, GL_TEXTURE_2D_MULTISAMPLE, texnum );
}
else
#endif
{
glActiveTexture( GL_TEXTURE0 + texUnit );
glBindTexture( GL_TEXTURE_2D_MULTISAMPLE, texnum );
}
}
}
// RB end
}
/*
====================
CopyFramebuffer
====================
*/
void idImage::CopyFramebuffer( int x, int y, int imageWidth, int imageHeight )
{
int target = GL_TEXTURE_2D;
switch( opts.textureType )
{
case TT_2D:
target = GL_TEXTURE_2D;
break;
case TT_CUBIC:
target = GL_TEXTURE_CUBE_MAP;
break;
case TT_2D_ARRAY:
target = GL_TEXTURE_2D_ARRAY;
break;
case TT_2D_MULTISAMPLE:
target = GL_TEXTURE_2D_MULTISAMPLE;
break;
default:
//idLib::FatalError( "%s: bad texture type %d", GetName(), opts.textureType );
return;
}
glBindTexture( target, texnum );
#if !defined(USE_GLES2)
if( Framebuffer::IsDefaultFramebufferActive() )
{
glReadBuffer( GL_BACK );
}
#endif
opts.width = imageWidth;
opts.height = imageHeight;
#if defined(USE_GLES2)
glCopyTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, x, y, imageWidth, imageHeight, 0 );
#else
if( r_useHDR.GetBool() && globalFramebuffers.hdrFBO->IsBound() )
{
//if( backEnd.glState.currentFramebuffer != NULL && backEnd.glState.currentFramebuffer->IsMultiSampled() )
#if defined(USE_HDR_MSAA)
if( globalFramebuffers.hdrFBO->IsMultiSampled() )
{
glBindFramebuffer( GL_READ_FRAMEBUFFER, globalFramebuffers.hdrFBO->GetFramebuffer() );
glBindFramebuffer( GL_DRAW_FRAMEBUFFER, globalFramebuffers.hdrNonMSAAFBO->GetFramebuffer() );
glBlitFramebuffer( 0, 0, glConfig.nativeScreenWidth, glConfig.nativeScreenHeight,
0, 0, glConfig.nativeScreenWidth, glConfig.nativeScreenHeight,
GL_COLOR_BUFFER_BIT,
GL_LINEAR );
globalFramebuffers.hdrNonMSAAFBO->Bind();
glCopyTexImage2D( target, 0, GL_RGBA16F, x, y, imageWidth, imageHeight, 0 );
globalFramebuffers.hdrFBO->Bind();
}
else
#endif
{
glCopyTexImage2D( target, 0, GL_RGBA16F, x, y, imageWidth, imageHeight, 0 );
}
}
else
{
glCopyTexImage2D( target, 0, GL_RGBA8, x, y, imageWidth, imageHeight, 0 );
}
#endif
// these shouldn't be necessary if the image was initialized properly
glTexParameterf( target, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
glTexParameterf( target, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
glTexParameterf( target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE );
glTexParameterf( target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE );
tr.backend.pc.c_copyFrameBuffer++;
}
/*
====================
CopyDepthbuffer
====================
*/
void idImage::CopyDepthbuffer( int x, int y, int imageWidth, int imageHeight )
{
glBindTexture( ( opts.textureType == TT_CUBIC ) ? GL_TEXTURE_CUBE_MAP : GL_TEXTURE_2D, texnum );
opts.width = imageWidth;
opts.height = imageHeight;
glCopyTexImage2D( GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, x, y, imageWidth, imageHeight, 0 );
tr.backend.pc.c_copyFrameBuffer++;
}
/*
========================
@ -554,7 +792,7 @@ void idImage::AllocImage()
}
else if( opts.textureType == TT_2D_MULTISAMPLE )
{
glTexImage2DMultisample( uploadTarget, opts.msaaSamples, internalFormat, opts.width, opts.height, GL_FALSE );
glTexImage2DMultisample( uploadTarget, opts.samples, internalFormat, opts.width, opts.height, GL_FALSE );
}
else
{
@ -638,12 +876,13 @@ void idImage::PurgeImage()
glDeleteTextures( 1, ( GLuint* )&texnum ); // this should be the ONLY place it is ever called!
texnum = TEXTURE_NOT_LOADED;
}
// clear all the current binding caches, so the next bind will do a real one
for( int i = 0 ; i < MAX_MULTITEXTURE_UNITS ; i++ )
{
backEnd.glState.tmu[i].current2DMap = TEXTURE_NOT_LOADED;
backEnd.glState.tmu[i].current2DArray = TEXTURE_NOT_LOADED;
backEnd.glState.tmu[i].currentCubeMap = TEXTURE_NOT_LOADED;
glcontext.tmu[i].current2DMap = TEXTURE_NOT_LOADED;
glcontext.tmu[i].current2DArray = TEXTURE_NOT_LOADED;
glcontext.tmu[i].currentCubeMap = TEXTURE_NOT_LOADED;
}
}

File diff suppressed because it is too large Load diff

View file

@ -1,727 +0,0 @@
/*
===========================================================================
Doom 3 BFG Edition GPL Source Code
Copyright (C) 1993-2012 id Software LLC, a ZeniMax Media company.
Copyright (C) 2013-2014 Robert Beckebans
This file is part of the Doom 3 BFG Edition GPL Source Code ("Doom 3 BFG Edition Source Code").
Doom 3 BFG Edition 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 3 of the License, or
(at your option) any later version.
Doom 3 BFG Edition 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 Doom 3 BFG Edition Source Code. If not, see <http://www.gnu.org/licenses/>.
In addition, the Doom 3 BFG Edition Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 BFG Edition Source Code. If not, please request a copy in writing from id Software at the address below.
If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
===========================================================================
*/
#pragma hdrstop
#include "precompiled.h"
#include "../tr_local.h"
/*
====================
GL_SelectTexture
====================
*/
void GL_SelectTexture( int unit )
{
if( backEnd.glState.currenttmu == unit )
{
return;
}
if( unit < 0 || unit >= glConfig.maxTextureImageUnits )
{
common->Warning( "GL_SelectTexture: unit = %i", unit );
return;
}
RENDERLOG_PRINTF( "GL_SelectTexture( %i );\n", unit );
backEnd.glState.currenttmu = unit;
}
/*
====================
GL_Cull
This handles the flipping needed when the view being
rendered is a mirored view.
====================
*/
void GL_Cull( int cullType )
{
if( backEnd.glState.faceCulling == cullType )
{
return;
}
if( cullType == CT_TWO_SIDED )
{
glDisable( GL_CULL_FACE );
}
else
{
if( backEnd.glState.faceCulling == CT_TWO_SIDED )
{
glEnable( GL_CULL_FACE );
}
if( cullType == CT_BACK_SIDED )
{
if( backEnd.viewDef->isMirror )
{
glCullFace( GL_FRONT );
}
else
{
glCullFace( GL_BACK );
}
}
else
{
if( backEnd.viewDef->isMirror )
{
glCullFace( GL_BACK );
}
else
{
glCullFace( GL_FRONT );
}
}
}
backEnd.glState.faceCulling = cullType;
}
/*
====================
GL_Scissor
====================
*/
void GL_Scissor( int x /* left*/, int y /* bottom */, int w, int h )
{
glScissor( x, y, w, h );
}
/*
====================
GL_Viewport
====================
*/
void GL_Viewport( int x /* left */, int y /* bottom */, int w, int h )
{
glViewport( x, y, w, h );
}
/*
====================
GL_PolygonOffset
====================
*/
void GL_PolygonOffset( float scale, float bias )
{
backEnd.glState.polyOfsScale = scale;
backEnd.glState.polyOfsBias = bias;
if( backEnd.glState.glStateBits & GLS_POLYGON_OFFSET )
{
glPolygonOffset( scale, bias );
}
}
/*
========================
GL_DepthBoundsTest
========================
*/
void GL_DepthBoundsTest( const float zmin, const float zmax )
{
if( !glConfig.depthBoundsTestAvailable || zmin > zmax )
{
return;
}
if( zmin == 0.0f && zmax == 0.0f )
{
glDisable( GL_DEPTH_BOUNDS_TEST_EXT );
}
else
{
glEnable( GL_DEPTH_BOUNDS_TEST_EXT );
glDepthBoundsEXT( zmin, zmax );
}
}
/*
========================
GL_StartDepthPass
========================
*/
void GL_StartDepthPass( const idScreenRect& rect )
{
}
/*
========================
GL_FinishDepthPass
========================
*/
void GL_FinishDepthPass()
{
}
/*
========================
GL_GetDepthPassRect
========================
*/
void GL_GetDepthPassRect( idScreenRect& rect )
{
rect.Clear();
}
/*
====================
GL_Color
====================
*/
/*
void GL_Color( float* color )
{
if( color == NULL )
{
return;
}
GL_Color( color[0], color[1], color[2], color[3] );
}
*/
// RB begin
void GL_Color( const idVec3& color )
{
GL_Color( color[0], color[1], color[2], 1.0f );
}
void GL_Color( const idVec4& color )
{
GL_Color( color[0], color[1], color[2], color[3] );
}
// RB end
/*
====================
GL_Color
====================
*/
void GL_Color( float r, float g, float b )
{
GL_Color( r, g, b, 1.0f );
}
/*
====================
GL_Color
====================
*/
void GL_Color( float r, float g, float b, float a )
{
float parm[4];
parm[0] = idMath::ClampFloat( 0.0f, 1.0f, r );
parm[1] = idMath::ClampFloat( 0.0f, 1.0f, g );
parm[2] = idMath::ClampFloat( 0.0f, 1.0f, b );
parm[3] = idMath::ClampFloat( 0.0f, 1.0f, a );
renderProgManager.SetRenderParm( RENDERPARM_COLOR, parm );
}
/*
========================
GL_Clear
========================
*/
void GL_Clear( bool color, bool depth, bool stencil, byte stencilValue, float r, float g, float b, float a, bool clearHDR )
{
int clearFlags = 0;
if( color )
{
glClearColor( r, g, b, a );
clearFlags |= GL_COLOR_BUFFER_BIT;
}
if( depth )
{
clearFlags |= GL_DEPTH_BUFFER_BIT;
}
if( stencil )
{
glClearStencil( stencilValue );
clearFlags |= GL_STENCIL_BUFFER_BIT;
}
glClear( clearFlags );
// RB begin
if( r_useHDR.GetBool() && clearHDR && globalFramebuffers.hdrFBO != NULL )
{
bool isDefaultFramebufferActive = Framebuffer::IsDefaultFramebufferActive();
globalFramebuffers.hdrFBO->Bind();
glClear( clearFlags );
if( isDefaultFramebufferActive )
{
Framebuffer::Unbind();
}
}
// RB end
}
/*
========================
GL_SetDefaultState
This should initialize all GL state that any part of the entire program
may touch, including the editor.
========================
*/
void GL_SetDefaultState()
{
RENDERLOG_PRINTF( "--- GL_SetDefaultState ---\n" );
glClearDepth( 1.0f );
// make sure our GL state vector is set correctly
memset( &backEnd.glState, 0, sizeof( backEnd.glState ) );
GL_State( 0, true );
// RB begin
Framebuffer::Unbind();
// RB end
// These are changed by GL_Cull
glCullFace( GL_FRONT_AND_BACK );
glEnable( GL_CULL_FACE );
// These are changed by GL_State
glColorMask( GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE );
glBlendFunc( GL_ONE, GL_ZERO );
glDepthMask( GL_TRUE );
glDepthFunc( GL_LESS );
glDisable( GL_STENCIL_TEST );
glDisable( GL_POLYGON_OFFSET_FILL );
glDisable( GL_POLYGON_OFFSET_LINE );
glPolygonMode( GL_FRONT_AND_BACK, GL_FILL );
// These should never be changed
// DG: deprecated in opengl 3.2 and not needed because we don't do fixed function pipeline
// glShadeModel( GL_SMOOTH );
// DG end
glEnable( GL_DEPTH_TEST );
glEnable( GL_BLEND );
glEnable( GL_SCISSOR_TEST );
glDrawBuffer( GL_BACK );
glReadBuffer( GL_BACK );
if( r_useScissor.GetBool() )
{
glScissor( 0, 0, renderSystem->GetWidth(), renderSystem->GetHeight() );
}
// RB: don't keep renderprogs that were enabled during level load
renderProgManager.Unbind();
// RB end
}
/*
====================
GL_State
This routine is responsible for setting the most commonly changed state
====================
*/
void GL_State( uint64 stateBits, bool forceGlState )
{
uint64 diff = stateBits ^ backEnd.glState.glStateBits;
if( !r_useStateCaching.GetBool() || forceGlState )
{
// make sure everything is set all the time, so we
// can see if our delta checking is screwing up
diff = 0xFFFFFFFFFFFFFFFF;
}
else if( diff == 0 )
{
return;
}
//
// check depthFunc bits
//
if( diff & GLS_DEPTHFUNC_BITS )
{
switch( stateBits & GLS_DEPTHFUNC_BITS )
{
case GLS_DEPTHFUNC_EQUAL:
glDepthFunc( GL_EQUAL );
break;
case GLS_DEPTHFUNC_ALWAYS:
glDepthFunc( GL_ALWAYS );
break;
case GLS_DEPTHFUNC_LESS:
glDepthFunc( GL_LEQUAL );
break;
case GLS_DEPTHFUNC_GREATER:
glDepthFunc( GL_GEQUAL );
break;
}
}
//
// check blend bits
//
if( diff & ( GLS_SRCBLEND_BITS | GLS_DSTBLEND_BITS ) )
{
GLenum srcFactor = GL_ONE;
GLenum dstFactor = GL_ZERO;
switch( stateBits & GLS_SRCBLEND_BITS )
{
case GLS_SRCBLEND_ZERO:
srcFactor = GL_ZERO;
break;
case GLS_SRCBLEND_ONE:
srcFactor = GL_ONE;
break;
case GLS_SRCBLEND_DST_COLOR:
srcFactor = GL_DST_COLOR;
break;
case GLS_SRCBLEND_ONE_MINUS_DST_COLOR:
srcFactor = GL_ONE_MINUS_DST_COLOR;
break;
case GLS_SRCBLEND_SRC_ALPHA:
srcFactor = GL_SRC_ALPHA;
break;
case GLS_SRCBLEND_ONE_MINUS_SRC_ALPHA:
srcFactor = GL_ONE_MINUS_SRC_ALPHA;
break;
case GLS_SRCBLEND_DST_ALPHA:
srcFactor = GL_DST_ALPHA;
break;
case GLS_SRCBLEND_ONE_MINUS_DST_ALPHA:
srcFactor = GL_ONE_MINUS_DST_ALPHA;
break;
default:
assert( !"GL_State: invalid src blend state bits\n" );
break;
}
switch( stateBits & GLS_DSTBLEND_BITS )
{
case GLS_DSTBLEND_ZERO:
dstFactor = GL_ZERO;
break;
case GLS_DSTBLEND_ONE:
dstFactor = GL_ONE;
break;
case GLS_DSTBLEND_SRC_COLOR:
dstFactor = GL_SRC_COLOR;
break;
case GLS_DSTBLEND_ONE_MINUS_SRC_COLOR:
dstFactor = GL_ONE_MINUS_SRC_COLOR;
break;
case GLS_DSTBLEND_SRC_ALPHA:
dstFactor = GL_SRC_ALPHA;
break;
case GLS_DSTBLEND_ONE_MINUS_SRC_ALPHA:
dstFactor = GL_ONE_MINUS_SRC_ALPHA;
break;
case GLS_DSTBLEND_DST_ALPHA:
dstFactor = GL_DST_ALPHA;
break;
case GLS_DSTBLEND_ONE_MINUS_DST_ALPHA:
dstFactor = GL_ONE_MINUS_DST_ALPHA;
break;
default:
assert( !"GL_State: invalid dst blend state bits\n" );
break;
}
// Only actually update GL's blend func if blending is enabled.
if( srcFactor == GL_ONE && dstFactor == GL_ZERO )
{
glDisable( GL_BLEND );
}
else
{
glEnable( GL_BLEND );
glBlendFunc( srcFactor, dstFactor );
}
}
//
// check depthmask
//
if( diff & GLS_DEPTHMASK )
{
if( stateBits & GLS_DEPTHMASK )
{
glDepthMask( GL_FALSE );
}
else
{
glDepthMask( GL_TRUE );
}
}
//
// check colormask
//
if( diff & ( GLS_REDMASK | GLS_GREENMASK | GLS_BLUEMASK | GLS_ALPHAMASK ) )
{
GLboolean r = ( stateBits & GLS_REDMASK ) ? GL_FALSE : GL_TRUE;
GLboolean g = ( stateBits & GLS_GREENMASK ) ? GL_FALSE : GL_TRUE;
GLboolean b = ( stateBits & GLS_BLUEMASK ) ? GL_FALSE : GL_TRUE;
GLboolean a = ( stateBits & GLS_ALPHAMASK ) ? GL_FALSE : GL_TRUE;
glColorMask( r, g, b, a );
}
//
// fill/line mode
//
if( diff & GLS_POLYMODE_LINE )
{
if( stateBits & GLS_POLYMODE_LINE )
{
glPolygonMode( GL_FRONT_AND_BACK, GL_LINE );
}
else
{
glPolygonMode( GL_FRONT_AND_BACK, GL_FILL );
}
}
//
// polygon offset
//
if( diff & GLS_POLYGON_OFFSET )
{
if( stateBits & GLS_POLYGON_OFFSET )
{
glPolygonOffset( backEnd.glState.polyOfsScale, backEnd.glState.polyOfsBias );
glEnable( GL_POLYGON_OFFSET_FILL );
glEnable( GL_POLYGON_OFFSET_LINE );
}
else
{
glDisable( GL_POLYGON_OFFSET_FILL );
glDisable( GL_POLYGON_OFFSET_LINE );
}
}
#if !defined( USE_CORE_PROFILE )
//
// alpha test
//
if( diff & ( GLS_ALPHATEST_FUNC_BITS | GLS_ALPHATEST_FUNC_REF_BITS ) )
{
if( ( stateBits & GLS_ALPHATEST_FUNC_BITS ) != 0 )
{
glEnable( GL_ALPHA_TEST );
GLenum func = GL_ALWAYS;
switch( stateBits & GLS_ALPHATEST_FUNC_BITS )
{
case GLS_ALPHATEST_FUNC_LESS:
func = GL_LESS;
break;
case GLS_ALPHATEST_FUNC_EQUAL:
func = GL_EQUAL;
break;
case GLS_ALPHATEST_FUNC_GREATER:
func = GL_GEQUAL;
break;
default:
assert( false );
}
GLclampf ref = ( ( stateBits & GLS_ALPHATEST_FUNC_REF_BITS ) >> GLS_ALPHATEST_FUNC_REF_SHIFT ) / ( float )0xFF;
glAlphaFunc( func, ref );
}
else
{
glDisable( GL_ALPHA_TEST );
}
}
#endif
//
// stencil
//
if( diff & ( GLS_STENCIL_FUNC_BITS | GLS_STENCIL_OP_BITS ) )
{
if( ( stateBits & ( GLS_STENCIL_FUNC_BITS | GLS_STENCIL_OP_BITS ) ) != 0 )
{
glEnable( GL_STENCIL_TEST );
}
else
{
glDisable( GL_STENCIL_TEST );
}
}
if( diff & ( GLS_STENCIL_FUNC_BITS | GLS_STENCIL_FUNC_REF_BITS | GLS_STENCIL_FUNC_MASK_BITS ) )
{
GLuint ref = GLuint( ( stateBits & GLS_STENCIL_FUNC_REF_BITS ) >> GLS_STENCIL_FUNC_REF_SHIFT );
GLuint mask = GLuint( ( stateBits & GLS_STENCIL_FUNC_MASK_BITS ) >> GLS_STENCIL_FUNC_MASK_SHIFT );
GLenum func = 0;
switch( stateBits & GLS_STENCIL_FUNC_BITS )
{
case GLS_STENCIL_FUNC_NEVER:
func = GL_NEVER;
break;
case GLS_STENCIL_FUNC_LESS:
func = GL_LESS;
break;
case GLS_STENCIL_FUNC_EQUAL:
func = GL_EQUAL;
break;
case GLS_STENCIL_FUNC_LEQUAL:
func = GL_LEQUAL;
break;
case GLS_STENCIL_FUNC_GREATER:
func = GL_GREATER;
break;
case GLS_STENCIL_FUNC_NOTEQUAL:
func = GL_NOTEQUAL;
break;
case GLS_STENCIL_FUNC_GEQUAL:
func = GL_GEQUAL;
break;
case GLS_STENCIL_FUNC_ALWAYS:
func = GL_ALWAYS;
break;
}
glStencilFunc( func, ref, mask );
}
if( diff & ( GLS_STENCIL_OP_FAIL_BITS | GLS_STENCIL_OP_ZFAIL_BITS | GLS_STENCIL_OP_PASS_BITS ) )
{
GLenum sFail = 0;
GLenum zFail = 0;
GLenum pass = 0;
switch( stateBits & GLS_STENCIL_OP_FAIL_BITS )
{
case GLS_STENCIL_OP_FAIL_KEEP:
sFail = GL_KEEP;
break;
case GLS_STENCIL_OP_FAIL_ZERO:
sFail = GL_ZERO;
break;
case GLS_STENCIL_OP_FAIL_REPLACE:
sFail = GL_REPLACE;
break;
case GLS_STENCIL_OP_FAIL_INCR:
sFail = GL_INCR;
break;
case GLS_STENCIL_OP_FAIL_DECR:
sFail = GL_DECR;
break;
case GLS_STENCIL_OP_FAIL_INVERT:
sFail = GL_INVERT;
break;
case GLS_STENCIL_OP_FAIL_INCR_WRAP:
sFail = GL_INCR_WRAP;
break;
case GLS_STENCIL_OP_FAIL_DECR_WRAP:
sFail = GL_DECR_WRAP;
break;
}
switch( stateBits & GLS_STENCIL_OP_ZFAIL_BITS )
{
case GLS_STENCIL_OP_ZFAIL_KEEP:
zFail = GL_KEEP;
break;
case GLS_STENCIL_OP_ZFAIL_ZERO:
zFail = GL_ZERO;
break;
case GLS_STENCIL_OP_ZFAIL_REPLACE:
zFail = GL_REPLACE;
break;
case GLS_STENCIL_OP_ZFAIL_INCR:
zFail = GL_INCR;
break;
case GLS_STENCIL_OP_ZFAIL_DECR:
zFail = GL_DECR;
break;
case GLS_STENCIL_OP_ZFAIL_INVERT:
zFail = GL_INVERT;
break;
case GLS_STENCIL_OP_ZFAIL_INCR_WRAP:
zFail = GL_INCR_WRAP;
break;
case GLS_STENCIL_OP_ZFAIL_DECR_WRAP:
zFail = GL_DECR_WRAP;
break;
}
switch( stateBits & GLS_STENCIL_OP_PASS_BITS )
{
case GLS_STENCIL_OP_PASS_KEEP:
pass = GL_KEEP;
break;
case GLS_STENCIL_OP_PASS_ZERO:
pass = GL_ZERO;
break;
case GLS_STENCIL_OP_PASS_REPLACE:
pass = GL_REPLACE;
break;
case GLS_STENCIL_OP_PASS_INCR:
pass = GL_INCR;
break;
case GLS_STENCIL_OP_PASS_DECR:
pass = GL_DECR;
break;
case GLS_STENCIL_OP_PASS_INVERT:
pass = GL_INVERT;
break;
case GLS_STENCIL_OP_PASS_INCR_WRAP:
pass = GL_INCR_WRAP;
break;
case GLS_STENCIL_OP_PASS_DECR_WRAP:
pass = GL_DECR_WRAP;
break;
}
glStencilOp( sFail, zFail, pass );
}
backEnd.glState.glStateBits = stateBits;
}
/*
=================
GL_GetCurrentState
=================
*/
uint64 GL_GetCurrentState()
{
return backEnd.glState.glStateBits;
}
/*
========================
GL_GetCurrentStateMinusStencil
========================
*/
uint64 GL_GetCurrentStateMinusStencil()
{
return GL_GetCurrentState() & ~( GLS_STENCIL_OP_BITS | GLS_STENCIL_FUNC_BITS | GLS_STENCIL_FUNC_REF_BITS | GLS_STENCIL_FUNC_MASK_BITS );
}

View file

@ -1,632 +0,0 @@
/*
===========================================================================
Doom 3 BFG Edition GPL Source Code
Copyright (C) 1993-2012 id Software LLC, a ZeniMax Media company.
Copyright (C) 2013-2015 Robert Beckebans
This file is part of the Doom 3 BFG Edition GPL Source Code ("Doom 3 BFG Edition Source Code").
Doom 3 BFG Edition 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 3 of the License, or
(at your option) any later version.
Doom 3 BFG Edition 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 Doom 3 BFG Edition Source Code. If not, see <http://www.gnu.org/licenses/>.
In addition, the Doom 3 BFG Edition Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 BFG Edition Source Code. If not, please request a copy in writing from id Software at the address below.
If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
===========================================================================
*/
#pragma hdrstop
#include "precompiled.h"
#include "../tr_local.h"
#include "../../framework/Common_local.h"
idCVar r_drawFlickerBox( "r_drawFlickerBox", "0", CVAR_RENDERER | CVAR_BOOL, "visual test for dropping frames" );
idCVar stereoRender_warp( "stereoRender_warp", "0", CVAR_RENDERER | CVAR_ARCHIVE | CVAR_BOOL, "use the optical warping renderprog instead of stereoDeGhost" );
idCVar stereoRender_warpStrength( "stereoRender_warpStrength", "1.45", CVAR_RENDERER | CVAR_ARCHIVE | CVAR_FLOAT, "amount of pre-distortion" );
idCVar stereoRender_warpCenterX( "stereoRender_warpCenterX", "0.5", CVAR_RENDERER | CVAR_FLOAT | CVAR_ARCHIVE, "center for left eye, right eye will be 1.0 - this" );
idCVar stereoRender_warpCenterY( "stereoRender_warpCenterY", "0.5", CVAR_RENDERER | CVAR_FLOAT | CVAR_ARCHIVE, "center for both eyes" );
idCVar stereoRender_warpParmZ( "stereoRender_warpParmZ", "0", CVAR_RENDERER | CVAR_FLOAT | CVAR_ARCHIVE, "development parm" );
idCVar stereoRender_warpParmW( "stereoRender_warpParmW", "0", CVAR_RENDERER | CVAR_FLOAT | CVAR_ARCHIVE, "development parm" );
idCVar stereoRender_warpTargetFraction( "stereoRender_warpTargetFraction", "1.0", CVAR_RENDERER | CVAR_FLOAT | CVAR_ARCHIVE, "fraction of half-width the through-lens view covers" );
idCVar r_showSwapBuffers( "r_showSwapBuffers", "0", CVAR_BOOL, "Show timings from GL_BlockingSwapBuffers" );
idCVar r_syncEveryFrame( "r_syncEveryFrame", "1", CVAR_BOOL, "Don't let the GPU buffer execution past swapbuffers" );
static int swapIndex; // 0 or 1 into renderSync
static GLsync renderSync[2];
void GLimp_SwapBuffers();
void RB_SetMVP( const idRenderMatrix& mvp );
/*
============================================================================
RENDER BACK END THREAD FUNCTIONS
============================================================================
*/
/*
=============
RB_DrawFlickerBox
=============
*/
static void RB_DrawFlickerBox()
{
if( !r_drawFlickerBox.GetBool() )
{
return;
}
if( tr.frameCount & 1 )
{
glClearColor( 1, 0, 0, 1 );
}
else
{
glClearColor( 0, 1, 0, 1 );
}
glScissor( 0, 0, 256, 256 );
glClear( GL_COLOR_BUFFER_BIT );
}
/*
=============
RB_SetBuffer
=============
*/
static void RB_SetBuffer( const void* data )
{
// see which draw buffer we want to render the frame to
const setBufferCommand_t* cmd = ( const setBufferCommand_t* )data;
RENDERLOG_PRINTF( "---------- RB_SetBuffer ---------- to buffer # %d\n", cmd->buffer );
GL_Scissor( 0, 0, tr.GetWidth(), tr.GetHeight() );
// clear screen for debugging
// automatically enable this with several other debug tools
// that might leave unrendered portions of the screen
if( r_clear.GetFloat() || idStr::Length( r_clear.GetString() ) != 1 || r_singleArea.GetBool() || r_showOverDraw.GetBool() )
{
float c[3];
if( sscanf( r_clear.GetString(), "%f %f %f", &c[0], &c[1], &c[2] ) == 3 )
{
GL_Clear( true, false, false, 0, c[0], c[1], c[2], 1.0f, true );
}
else if( r_clear.GetInteger() == 2 )
{
GL_Clear( true, false, false, 0, 0.0f, 0.0f, 0.0f, 1.0f, true );
}
else if( r_showOverDraw.GetBool() )
{
GL_Clear( true, false, false, 0, 1.0f, 1.0f, 1.0f, 1.0f, true );
}
else
{
GL_Clear( true, false, false, 0, 0.4f, 0.0f, 0.25f, 1.0f, true );
}
}
}
/*
=============
GL_BlockingSwapBuffers
We want to exit this with the GPU idle, right at vsync
=============
*/
const void GL_BlockingSwapBuffers()
{
RENDERLOG_PRINTF( "***************** GL_BlockingSwapBuffers *****************\n\n\n" );
const int beforeFinish = Sys_Milliseconds();
if( !glConfig.syncAvailable )
{
glFinish();
}
const int beforeSwap = Sys_Milliseconds();
if( r_showSwapBuffers.GetBool() && beforeSwap - beforeFinish > 1 )
{
common->Printf( "%i msec to glFinish\n", beforeSwap - beforeFinish );
}
GLimp_SwapBuffers();
const int beforeFence = Sys_Milliseconds();
if( r_showSwapBuffers.GetBool() && beforeFence - beforeSwap > 1 )
{
common->Printf( "%i msec to swapBuffers\n", beforeFence - beforeSwap );
}
if( glConfig.syncAvailable )
{
swapIndex ^= 1;
if( glIsSync( renderSync[swapIndex] ) )
{
glDeleteSync( renderSync[swapIndex] );
}
// draw something tiny to ensure the sync is after the swap
const int start = Sys_Milliseconds();
glScissor( 0, 0, 1, 1 );
glEnable( GL_SCISSOR_TEST );
glClear( GL_COLOR_BUFFER_BIT );
renderSync[swapIndex] = glFenceSync( GL_SYNC_GPU_COMMANDS_COMPLETE, 0 );
const int end = Sys_Milliseconds();
if( r_showSwapBuffers.GetBool() && end - start > 1 )
{
common->Printf( "%i msec to start fence\n", end - start );
}
GLsync syncToWaitOn;
if( r_syncEveryFrame.GetBool() )
{
syncToWaitOn = renderSync[swapIndex];
}
else
{
syncToWaitOn = renderSync[!swapIndex];
}
if( glIsSync( syncToWaitOn ) )
{
for( GLenum r = GL_TIMEOUT_EXPIRED; r == GL_TIMEOUT_EXPIRED; )
{
r = glClientWaitSync( syncToWaitOn, GL_SYNC_FLUSH_COMMANDS_BIT, 1000 * 1000 );
}
}
}
const int afterFence = Sys_Milliseconds();
if( r_showSwapBuffers.GetBool() && afterFence - beforeFence > 1 )
{
common->Printf( "%i msec to wait on fence\n", afterFence - beforeFence );
}
const int64 exitBlockTime = Sys_Microseconds();
static int64 prevBlockTime;
if( r_showSwapBuffers.GetBool() && prevBlockTime )
{
const int delta = ( int )( exitBlockTime - prevBlockTime );
common->Printf( "blockToBlock: %i\n", delta );
}
prevBlockTime = exitBlockTime;
}
/*
====================
R_MakeStereoRenderImage
====================
*/
static void R_MakeStereoRenderImage( idImage* image )
{
idImageOpts opts;
opts.width = renderSystem->GetWidth();
opts.height = renderSystem->GetHeight();
opts.numLevels = 1;
opts.format = FMT_RGBA8;
image->AllocImage( opts, TF_LINEAR, TR_CLAMP );
}
/*
====================
RB_StereoRenderExecuteBackEndCommands
Renders the draw list twice, with slight modifications for left eye / right eye
====================
*/
void RB_StereoRenderExecuteBackEndCommands( const emptyCommand_t* const allCmds )
{
uint64 backEndStartTime = Sys_Microseconds();
// If we are in a monoscopic context, this draws to the only buffer, and is
// the same as GL_BACK. In a quad-buffer stereo context, this is necessary
// to prevent GL from forcing the rendering to go to both BACK_LEFT and
// BACK_RIGHT at a performance penalty.
// To allow stereo deghost processing, the views have to be copied to separate
// textures anyway, so there isn't any benefit to rendering to BACK_RIGHT for
// that eye.
glDrawBuffer( GL_BACK_LEFT );
// create the stereoRenderImage if we haven't already
static idImage* stereoRenderImages[2];
for( int i = 0; i < 2; i++ )
{
if( stereoRenderImages[i] == NULL )
{
stereoRenderImages[i] = globalImages->ImageFromFunction( va( "_stereoRender%i", i ), R_MakeStereoRenderImage );
}
// resize the stereo render image if the main window has changed size
if( stereoRenderImages[i]->GetUploadWidth() != renderSystem->GetWidth() ||
stereoRenderImages[i]->GetUploadHeight() != renderSystem->GetHeight() )
{
stereoRenderImages[i]->Resize( renderSystem->GetWidth(), renderSystem->GetHeight() );
}
}
// In stereoRender mode, the front end has generated two RC_DRAW_VIEW commands
// with slightly different origins for each eye.
// TODO: only do the copy after the final view has been rendered, not mirror subviews?
// Render the 3D draw views from the screen origin so all the screen relative
// texture mapping works properly, then copy the portion we are going to use
// off to a texture.
bool foundEye[2] = { false, false };
for( int stereoEye = 1; stereoEye >= -1; stereoEye -= 2 )
{
// set up the target texture we will draw to
const int targetEye = ( stereoEye == 1 ) ? 1 : 0;
// Set the back end into a known default state to fix any stale render state issues
GL_SetDefaultState();
renderProgManager.Unbind();
renderProgManager.ZeroUniforms();
for( const emptyCommand_t* cmds = allCmds; cmds != NULL; cmds = ( const emptyCommand_t* )cmds->next )
{
switch( cmds->commandId )
{
case RC_NOP:
break;
case RC_DRAW_VIEW_GUI:
case RC_DRAW_VIEW_3D:
{
const drawSurfsCommand_t* const dsc = ( const drawSurfsCommand_t* )cmds;
const viewDef_t& eyeViewDef = *dsc->viewDef;
if( eyeViewDef.renderView.viewEyeBuffer && eyeViewDef.renderView.viewEyeBuffer != stereoEye )
{
// this is the render view for the other eye
continue;
}
foundEye[ targetEye ] = true;
RB_DrawView( dsc, stereoEye );
if( cmds->commandId == RC_DRAW_VIEW_GUI )
{
}
}
break;
case RC_SET_BUFFER:
RB_SetBuffer( cmds );
break;
case RC_COPY_RENDER:
RB_CopyRender( cmds );
break;
case RC_POST_PROCESS:
{
postProcessCommand_t* cmd = ( postProcessCommand_t* )cmds;
if( cmd->viewDef->renderView.viewEyeBuffer != stereoEye )
{
break;
}
RB_PostProcess( cmds );
}
break;
default:
common->Error( "RB_ExecuteBackEndCommands: bad commandId" );
break;
}
}
// copy to the target
stereoRenderImages[ targetEye ]->CopyFramebuffer( 0, 0, renderSystem->GetWidth(), renderSystem->GetHeight() );
}
// perform the final compositing / warping / deghosting to the actual framebuffer(s)
assert( foundEye[0] && foundEye[1] );
GL_SetDefaultState();
RB_SetMVP( renderMatrix_identity );
// If we are in quad-buffer pixel format but testing another 3D mode,
// make sure we draw to both eyes. This is likely to be sub-optimal
// performance on most cards and drivers, but it is better than getting
// a confusing, half-ghosted view.
if( renderSystem->GetStereo3DMode() != STEREO3D_QUAD_BUFFER )
{
glDrawBuffer( GL_BACK );
}
GL_State( GLS_DEPTHFUNC_ALWAYS );
GL_Cull( CT_TWO_SIDED );
// We just want to do a quad pass - so make sure we disable any texgen and
// set the texture matrix to the identity so we don't get anomalies from
// any stale uniform data being present from a previous draw call
const float texS[4] = { 1.0f, 0.0f, 0.0f, 0.0f };
const float texT[4] = { 0.0f, 1.0f, 0.0f, 0.0f };
renderProgManager.SetRenderParm( RENDERPARM_TEXTUREMATRIX_S, texS );
renderProgManager.SetRenderParm( RENDERPARM_TEXTUREMATRIX_T, texT );
// disable any texgen
const float texGenEnabled[4] = { 0.0f, 0.0f, 0.0f, 0.0f };
renderProgManager.SetRenderParm( RENDERPARM_TEXGEN_0_ENABLED, texGenEnabled );
renderProgManager.BindShader_Texture();
GL_Color( 1, 1, 1, 1 );
switch( renderSystem->GetStereo3DMode() )
{
case STEREO3D_QUAD_BUFFER:
glDrawBuffer( GL_BACK_RIGHT );
GL_SelectTexture( 0 );
stereoRenderImages[1]->Bind();
GL_SelectTexture( 1 );
stereoRenderImages[0]->Bind();
RB_DrawElementsWithCounters( &backEnd.unitSquareSurface );
glDrawBuffer( GL_BACK_LEFT );
GL_SelectTexture( 1 );
stereoRenderImages[1]->Bind();
GL_SelectTexture( 0 );
stereoRenderImages[0]->Bind();
RB_DrawElementsWithCounters( &backEnd.unitSquareSurface );
break;
case STEREO3D_HDMI_720:
// HDMI 720P 3D
GL_SelectTexture( 0 );
stereoRenderImages[1]->Bind();
GL_SelectTexture( 1 );
stereoRenderImages[0]->Bind();
GL_ViewportAndScissor( 0, 0, 1280, 720 );
RB_DrawElementsWithCounters( &backEnd.unitSquareSurface );
GL_SelectTexture( 0 );
stereoRenderImages[0]->Bind();
GL_SelectTexture( 1 );
stereoRenderImages[1]->Bind();
GL_ViewportAndScissor( 0, 750, 1280, 720 );
RB_DrawElementsWithCounters( &backEnd.unitSquareSurface );
// force the HDMI 720P 3D guard band to a constant color
glScissor( 0, 720, 1280, 30 );
glClear( GL_COLOR_BUFFER_BIT );
break;
default:
case STEREO3D_SIDE_BY_SIDE:
if( stereoRender_warp.GetBool() )
{
// this is the Rift warp
// renderSystem->GetWidth() / GetHeight() have returned equal values (640 for initial Rift)
// and we are going to warp them onto a symetric square region of each half of the screen
renderProgManager.BindShader_StereoWarp();
// clear the entire screen to black
// we could be smart and only clear the areas we aren't going to draw on, but
// clears are fast...
glScissor( 0, 0, glConfig.nativeScreenWidth, glConfig.nativeScreenHeight );
glClearColor( 0, 0, 0, 0 );
glClear( GL_COLOR_BUFFER_BIT );
// the size of the box that will get the warped pixels
// With the 7" displays, this will be less than half the screen width
const int pixelDimensions = ( glConfig.nativeScreenWidth >> 1 ) * stereoRender_warpTargetFraction.GetFloat();
// Always scissor to the half-screen boundary, but the viewports
// might cross that boundary if the lenses can be adjusted closer
// together.
glViewport( ( glConfig.nativeScreenWidth >> 1 ) - pixelDimensions,
( glConfig.nativeScreenHeight >> 1 ) - ( pixelDimensions >> 1 ),
pixelDimensions, pixelDimensions );
glScissor( 0, 0, glConfig.nativeScreenWidth >> 1, glConfig.nativeScreenHeight );
idVec4 color( stereoRender_warpCenterX.GetFloat(), stereoRender_warpCenterY.GetFloat(), stereoRender_warpParmZ.GetFloat(), stereoRender_warpParmW.GetFloat() );
// don't use GL_Color(), because we don't want to clamp
renderProgManager.SetRenderParm( RENDERPARM_COLOR, color.ToFloatPtr() );
GL_SelectTexture( 0 );
stereoRenderImages[0]->Bind();
glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER );
glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER );
RB_DrawElementsWithCounters( &backEnd.unitSquareSurface );
idVec4 color2( stereoRender_warpCenterX.GetFloat(), stereoRender_warpCenterY.GetFloat(), stereoRender_warpParmZ.GetFloat(), stereoRender_warpParmW.GetFloat() );
// don't use GL_Color(), because we don't want to clamp
renderProgManager.SetRenderParm( RENDERPARM_COLOR, color2.ToFloatPtr() );
glViewport( ( glConfig.nativeScreenWidth >> 1 ),
( glConfig.nativeScreenHeight >> 1 ) - ( pixelDimensions >> 1 ),
pixelDimensions, pixelDimensions );
glScissor( glConfig.nativeScreenWidth >> 1, 0, glConfig.nativeScreenWidth >> 1, glConfig.nativeScreenHeight );
GL_SelectTexture( 0 );
stereoRenderImages[1]->Bind();
glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER );
glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER );
RB_DrawElementsWithCounters( &backEnd.unitSquareSurface );
break;
}
// a non-warped side-by-side-uncompressed (dual input cable) is rendered
// just like STEREO3D_SIDE_BY_SIDE_COMPRESSED, so fall through.
case STEREO3D_SIDE_BY_SIDE_COMPRESSED:
GL_SelectTexture( 0 );
stereoRenderImages[0]->Bind();
GL_SelectTexture( 1 );
stereoRenderImages[1]->Bind();
GL_ViewportAndScissor( 0, 0, renderSystem->GetWidth(), renderSystem->GetHeight() );
RB_DrawElementsWithCounters( &backEnd.unitSquareSurface );
GL_SelectTexture( 0 );
stereoRenderImages[1]->Bind();
GL_SelectTexture( 1 );
stereoRenderImages[0]->Bind();
GL_ViewportAndScissor( renderSystem->GetWidth(), 0, renderSystem->GetWidth(), renderSystem->GetHeight() );
RB_DrawElementsWithCounters( &backEnd.unitSquareSurface );
break;
case STEREO3D_TOP_AND_BOTTOM_COMPRESSED:
GL_SelectTexture( 1 );
stereoRenderImages[0]->Bind();
GL_SelectTexture( 0 );
stereoRenderImages[1]->Bind();
GL_ViewportAndScissor( 0, 0, renderSystem->GetWidth(), renderSystem->GetHeight() );
RB_DrawElementsWithCounters( &backEnd.unitSquareSurface );
GL_SelectTexture( 1 );
stereoRenderImages[1]->Bind();
GL_SelectTexture( 0 );
stereoRenderImages[0]->Bind();
GL_ViewportAndScissor( 0, renderSystem->GetHeight(), renderSystem->GetWidth(), renderSystem->GetHeight() );
RB_DrawElementsWithCounters( &backEnd.unitSquareSurface );
break;
case STEREO3D_INTERLACED:
// every other scanline
GL_SelectTexture( 0 );
stereoRenderImages[0]->Bind();
glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST );
glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST );
GL_SelectTexture( 1 );
stereoRenderImages[1]->Bind();
glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST );
glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST );
GL_ViewportAndScissor( 0, 0, renderSystem->GetWidth(), renderSystem->GetHeight() * 2 );
renderProgManager.BindShader_StereoInterlace();
RB_DrawElementsWithCounters( &backEnd.unitSquareSurface );
GL_SelectTexture( 0 );
glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
GL_SelectTexture( 1 );
glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
break;
}
// debug tool
RB_DrawFlickerBox();
// make sure the drawing is actually started
glFlush();
// we may choose to sync to the swapbuffers before the next frame
// stop rendering on this thread
uint64 backEndFinishTime = Sys_Microseconds();
backEnd.pc.totalMicroSec = backEndFinishTime - backEndStartTime;
}
/*
====================
RB_ExecuteBackEndCommands
This function will be called syncronously if running without
smp extensions, or asyncronously by another thread.
====================
*/
void RB_ExecuteBackEndCommands( const emptyCommand_t* cmds )
{
// r_debugRenderToTexture
int c_draw3d = 0;
int c_draw2d = 0;
int c_setBuffers = 0;
int c_copyRenders = 0;
resolutionScale.SetCurrentGPUFrameTime( commonLocal.GetRendererGPUMicroseconds() );
renderLog.StartFrame();
if( cmds->commandId == RC_NOP && !cmds->next )
{
return;
}
if( renderSystem->GetStereo3DMode() != STEREO3D_OFF )
{
RB_StereoRenderExecuteBackEndCommands( cmds );
renderLog.EndFrame();
return;
}
uint64 backEndStartTime = Sys_Microseconds();
// needed for editor rendering
GL_SetDefaultState();
// If we have a stereo pixel format, this will draw to both
// the back left and back right buffers, which will have a
// performance penalty.
glDrawBuffer( GL_BACK );
for( ; cmds != NULL; cmds = ( const emptyCommand_t* )cmds->next )
{
switch( cmds->commandId )
{
case RC_NOP:
break;
case RC_DRAW_VIEW_3D:
case RC_DRAW_VIEW_GUI:
RB_DrawView( cmds, 0 );
if( ( ( const drawSurfsCommand_t* )cmds )->viewDef->viewEntitys )
{
c_draw3d++;
}
else
{
c_draw2d++;
}
break;
case RC_SET_BUFFER:
//RB_SetBuffer( cmds );
c_setBuffers++;
break;
case RC_COPY_RENDER:
RB_CopyRender( cmds );
c_copyRenders++;
break;
case RC_POST_PROCESS:
RB_PostProcess( cmds );
break;
default:
common->Error( "RB_ExecuteBackEndCommands: bad commandId" );
break;
}
}
RB_DrawFlickerBox();
// Fix for the steam overlay not showing up while in game without Shell/Debug/Console/Menu also rendering
glColorMask( 1, 1, 1, 1 );
glFlush();
// stop rendering on this thread
uint64 backEndFinishTime = Sys_Microseconds();
backEnd.pc.totalMicroSec = backEndFinishTime - backEndStartTime;
if( r_debugRenderToTexture.GetInteger() == 1 )
{
common->Printf( "3d: %i, 2d: %i, SetBuf: %i, CpyRenders: %i, CpyFrameBuf: %i\n", c_draw3d, c_draw2d, c_setBuffers, c_copyRenders, backEnd.pc.c_copyFrameBuffer );
backEnd.pc.c_copyFrameBuffer = 0;
}
renderLog.EndFrame();
}

View file

@ -0,0 +1,509 @@
/*
===========================================================================
Doom 3 BFG Edition GPL Source Code
Copyright (C) 1993-2012 id Software LLC, a ZeniMax Media company.
Copyright (C) 2016-2017 Dustin Land
Copyright (C) 2017 Robert Beckebans
This file is part of the Doom 3 BFG Edition GPL Source Code ("Doom 3 BFG Edition Source Code").
Doom 3 BFG Edition 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 3 of the License, or
(at your option) any later version.
Doom 3 BFG Edition 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 Doom 3 BFG Edition Source Code. If not, see <http://www.gnu.org/licenses/>.
In addition, the Doom 3 BFG Edition Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 BFG Edition Source Code. If not, please request a copy in writing from id Software at the address below.
If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
===========================================================================
*/
#ifndef __RENDERER_BACKEND_H__
#define __RENDERER_BACKEND_H__
// RB begin
#define USE_CORE_PROFILE
bool GL_CheckErrors_( const char* filename, int line );
#if 1 // !defined(RETAIL)
#define GL_CheckErrors() GL_CheckErrors_(__FILE__, __LINE__)
#else
#define GL_CheckErrors() false
#endif
// RB end
struct tmu_t
{
unsigned int current2DMap;
unsigned int current2DArray;
unsigned int currentCubeMap;
};
const int MAX_MULTITEXTURE_UNITS = 8;
enum stencilFace_t
{
STENCIL_FACE_FRONT,
STENCIL_FACE_BACK,
STENCIL_FACE_NUM
};
struct backEndCounters_t
{
int c_surfaces;
int c_shaders;
int c_drawElements;
int c_drawIndexes;
int c_shadowElements;
int c_shadowIndexes;
int c_copyFrameBuffer;
float c_overDraw;
int totalMicroSec; // total microseconds for backend run
int shadowMicroSec;
};
struct gfxImpParms_t
{
int x; // ignored in fullscreen
int y; // ignored in fullscreen
int width;
int height;
int fullScreen; // 0 = windowed, otherwise 1 based monitor number to go full screen on
// -1 = borderless window for spanning multiple displays
int displayHz;
int multiSamples;
};
#define MAX_DEBUG_LINES 16384
#define MAX_DEBUG_TEXT 512
#define MAX_DEBUG_POLYGONS 8192
struct debugLine_t
{
idVec4 rgb;
idVec3 start;
idVec3 end;
bool depthTest;
int lifeTime;
};
struct debugText_t
{
idStr text;
idVec3 origin;
float scale;
idVec4 color;
idMat3 viewAxis;
int align;
int lifeTime;
bool depthTest;
};
struct debugPolygon_t
{
idVec4 rgb;
idWinding winding;
bool depthTest;
int lifeTime;
};
void RB_SetMVP( const idRenderMatrix& mvp );
void RB_SetVertexColorParms( stageVertexColor_t svc );
void RB_GetShaderTextureMatrix( const float* shaderRegisters, const textureStage_t* texture, float matrix[16] );
void RB_LoadShaderTextureMatrix( const float* shaderRegisters, const textureStage_t* texture );
void RB_BakeTextureMatrixIntoTexgen( idPlane lightProject[3], const float* textureMatrix );
//bool ChangeDisplaySettingsIfNeeded( gfxImpParms_t parms );
//bool CreateGameWindow( gfxImpParms_t parms );
#if defined( ID_VULKAN )
struct gpuInfo_t
{
VkPhysicalDevice device;
VkPhysicalDeviceProperties props;
VkPhysicalDeviceMemoryProperties memProps;
VkSurfaceCapabilitiesKHR surfaceCaps;
idList< VkSurfaceFormatKHR > surfaceFormats;
idList< VkPresentModeKHR > presentModes;
idList< VkQueueFamilyProperties > queueFamilyProps;
idList< VkExtensionProperties > extensionProps;
};
struct vulkanContext_t
{
uint64 counter;
uint32 currentFrameData;
vertCacheHandle_t jointCacheHandle;
uint64 stencilOperations[ STENCIL_FACE_NUM ];
VkInstance instance;
VkPhysicalDevice physicalDevice;
VkPhysicalDeviceFeatures physicalDeviceFeatures;
VkDevice device;
VkQueue graphicsQueue;
VkQueue presentQueue;
int graphicsFamilyIdx;
int presentFamilyIdx;
VkDebugReportCallbackEXT callback;
idList< const char* > instanceExtensions;
idList< const char* > deviceExtensions;
idList< const char* > validationLayers;
gpuInfo_t* gpu;
idList< gpuInfo_t > gpus;
VkCommandPool commandPool;
idArray< VkCommandBuffer, NUM_FRAME_DATA > commandBuffer;
idArray< VkFence, NUM_FRAME_DATA > commandBufferFences;
idArray< bool, NUM_FRAME_DATA > commandBufferRecorded;
VkSurfaceKHR surface;
VkPresentModeKHR presentMode;
VkFormat depthFormat;
VkRenderPass renderPass;
VkPipelineCache pipelineCache;
VkSampleCountFlagBits sampleCount;
bool supersampling;
int fullscreen;
VkSwapchainKHR swapchain;
VkFormat swapchainFormat;
VkExtent2D swapchainExtent;
uint32 currentSwapIndex;
VkImage msaaImage;
VkImageView msaaImageView;
#if defined( ID_USE_AMD_ALLOCATOR )
VmaAllocation msaaVmaAllocation;
VmaAllocationInfo msaaAllocation;
#else
vulkanAllocation_t msaaAllocation;
#endif
idArray< idImage*, NUM_FRAME_DATA > swapchainImages;
idArray< VkFramebuffer, NUM_FRAME_DATA > frameBuffers;
idArray< VkSemaphore, NUM_FRAME_DATA > acquireSemaphores;
idArray< VkSemaphore, NUM_FRAME_DATA > renderCompleteSemaphores;
int currentImageParm;
idArray< idImage*, MAX_IMAGE_PARMS > imageParms;
};
extern vulkanContext_t vkcontext;
#else //if defined( ID_OPENGL )
struct glContext_t
{
// bool bAnisotropicFilterAvailable;
// bool bTextureLODBiasAvailable;
// float maxTextureAnisotropy;
tmu_t tmu[ MAX_MULTITEXTURE_UNITS ];
uint64 stencilOperations[ STENCIL_FACE_NUM ];
};
extern glContext_t glcontext;
#endif
/*
===========================================================================
idRenderBackend
all state modified by the back end is separated from the front end state
===========================================================================
*/
class idRenderBackend
{
friend class Framebuffer;
public:
idRenderBackend();
~idRenderBackend();
void Init();
void Shutdown();
void ExecuteBackEndCommands( const emptyCommand_t* cmds );
void StereoRenderExecuteBackEndCommands( const emptyCommand_t* const allCmds );
void BlockingSwapBuffers();
void Print();
void CheckCVars();
private:
void DrawFlickerBox();
void DrawElementsWithCounters( const drawSurf_t* surf );
void DrawStencilShadowPass( const drawSurf_t* drawSurf, const bool renderZPass );
void SetColorMappings();
void ResizeImages();
void DrawViewInternal( const viewDef_t* viewDef, const int stereoEye );
void DrawView( const void* data, const int stereoEye );
void CopyRender( const void* data );
void BindVariableStageImage( const textureStage_t* texture, const float* shaderRegisters );
void PrepareStageTexturing( const shaderStage_t* pStage, const drawSurf_t* surf );
void FinishStageTexturing( const shaderStage_t* pStage, const drawSurf_t* surf );
void ResetViewportAndScissorToDefaultCamera( const viewDef_t* _viewDef );
void FillDepthBufferGeneric( const drawSurf_t* const* drawSurfs, int numDrawSurfs );
void FillDepthBufferFast( drawSurf_t** drawSurfs, int numDrawSurfs );
void T_BlendLight( const drawSurf_t* drawSurfs, const viewLight_t* vLight );
void BlendLight( const drawSurf_t* drawSurfs, const drawSurf_t* drawSurfs2, const viewLight_t* vLight );
void T_BasicFog( const drawSurf_t* drawSurfs, const idPlane fogPlanes[ 4 ], const idRenderMatrix* inverseBaseLightProject );
void FogPass( const drawSurf_t* drawSurfs, const drawSurf_t* drawSurfs2, const viewLight_t* vLight );
void FogAllLights();
void SetupInteractionStage( const shaderStage_t* surfaceStage, const float* surfaceRegs, const float lightColor[4],
idVec4 matrix[2], float color[4] );
void DrawInteractions( const viewDef_t* _viewDef );
void DrawSingleInteraction( drawInteraction_t* din );
int DrawShaderPasses( const drawSurf_t* const* const drawSurfs, const int numDrawSurfs,
const float guiStereoScreenOffset, const int stereoEye );
void RenderInteractions( const drawSurf_t* surfList, const viewLight_t* vLight, int depthFunc, bool performStencilTest, bool useLightDepthBounds );
// RB
void AmbientPass( const drawSurf_t* const* drawSurfs, int numDrawSurfs, bool fillGbuffer );
void ShadowMapPass( const drawSurf_t* drawSurfs, const viewLight_t* vLight, int side );
void StencilShadowPass( const drawSurf_t* drawSurfs, const viewLight_t* vLight );
void StencilSelectLight( const viewLight_t* vLight );
// RB: HDR stuff
// TODO optimize and replace with compute shader
void CalculateAutomaticExposure();
void Tonemap( const viewDef_t* viewDef );
void Bloom( const viewDef_t* viewDef );
void DrawScreenSpaceAmbientOcclusion( const viewDef_t* _viewDef );
void DrawScreenSpaceGlobalIllumination( const viewDef_t* _viewDef );
// Experimental feature
void MotionBlur();
void PostProcess( const void* data );
private:
void GL_StartFrame();
void GL_EndFrame();
uint64 GL_GetCurrentState() const;
uint64 GL_GetCurrentStateMinusStencil() const;
void GL_SetDefaultState();
void GL_State( uint64 stateBits, bool forceGlState = false );
void GL_SeparateStencil( stencilFace_t face, uint64 stencilBits );
void GL_Cull( cullType_t cullType ); // TODO remove
void GL_SelectTexture( int unit );
// void GL_BindTexture( idImage* image );
// void GL_CopyFrameBuffer( idImage* image, int x, int y, int imageWidth, int imageHeight );
// void GL_CopyDepthBuffer( idImage* image, int x, int y, int imageWidth, int imageHeight );
// RB: HDR parm
void GL_Clear( bool color, bool depth, bool stencil, byte stencilValue, float r, float g, float b, float a, bool clearHDR = true );
void GL_DepthBoundsTest( const float zmin, const float zmax );
void GL_PolygonOffset( float scale, float bias );
void GL_Scissor( int x /* left*/, int y /* bottom */, int w, int h );
void GL_Viewport( int x /* left */, int y /* bottom */, int w, int h );
ID_INLINE void GL_Scissor( const idScreenRect& rect )
{
GL_Scissor( rect.x1, rect.y1, rect.x2 - rect.x1 + 1, rect.y2 - rect.y1 + 1 );
}
ID_INLINE void GL_Viewport( const idScreenRect& rect )
{
GL_Viewport( rect.x1, rect.y1, rect.x2 - rect.x1 + 1, rect.y2 - rect.y1 + 1 );
}
ID_INLINE void GL_ViewportAndScissor( int x, int y, int w, int h )
{
GL_Viewport( x, y, w, h );
GL_Scissor( x, y, w, h );
}
ID_INLINE void GL_ViewportAndScissor( const idScreenRect& rect )
{
GL_Viewport( rect );
GL_Scissor( rect );
}
void GL_Color( float r, float g, float b, float a );
ID_INLINE void GL_Color( float r, float g, float b )
{
GL_Color( r, g, b, 1.0f );
}
ID_INLINE void GL_Color( const idVec3& color )
{
GL_Color( color[0], color[1], color[2], 1.0f );
}
ID_INLINE void GL_Color( const idVec4& color )
{
GL_Color( color[0], color[1], color[2], color[3] );
}
// void GL_Color( float* color );
void SetBuffer( const void* data );
private:
void DBG_SimpleSurfaceSetup( const drawSurf_t* drawSurf );
void DBG_SimpleWorldSetup();
void DBG_PolygonClear();
void DBG_ShowDestinationAlpha();
void DBG_ScanStencilBuffer();
void DBG_CountStencilBuffer();
void DBG_ColorByStencilBuffer();
void DBG_ShowOverdraw();
void DBG_ShowIntensity();
void DBG_ShowDepthBuffer();
void DBG_ShowLightCount();
// void DBG_EnterWeaponDepthHack();
// void DBG_EnterModelDepthHack( float depth );
// void DBG_LeaveDepthHack();
void DBG_RenderDrawSurfListWithFunction( drawSurf_t** drawSurfs, int numDrawSurfs );
void DBG_ShowSilhouette();
void DBG_ShowTris( drawSurf_t** drawSurfs, int numDrawSurfs );
void DBG_ShowSurfaceInfo( drawSurf_t** drawSurfs, int numDrawSurfs );
void DBG_ShowViewEntitys( viewEntity_t* vModels );
void DBG_ShowTexturePolarity( drawSurf_t** drawSurfs, int numDrawSurfs );
void DBG_ShowUnsmoothedTangents( drawSurf_t** drawSurfs, int numDrawSurfs );
void DBG_ShowTangentSpace( drawSurf_t** drawSurfs, int numDrawSurfs );
void DBG_ShowVertexColor( drawSurf_t** drawSurfs, int numDrawSurfs );
void DBG_ShowNormals( drawSurf_t** drawSurfs, int numDrawSurfs );
void DBG_ShowTextureVectors( drawSurf_t** drawSurfs, int numDrawSurfs );
void DBG_ShowDominantTris( drawSurf_t** drawSurfs, int numDrawSurfs );
void DBG_ShowEdges( drawSurf_t** drawSurfs, int numDrawSurfs );
void DBG_ShowLights();
void DBG_ShowShadowMapLODs(); // RB
void DBG_ShowPortals();
void DBG_ShowDebugText();
void DBG_ShowDebugLines();
void DBG_ShowDebugPolygons();
void DBG_ShowCenterOfProjection();
void DBG_ShowLines();
void DBG_TestGamma();
void DBG_TestGammaBias();
void DBG_TestImage();
void DBG_ShowShadowMaps(); // RB
void DBG_ShowTrace( drawSurf_t** drawSurfs, int numDrawSurfs );
void DBG_RenderDebugTools( drawSurf_t** drawSurfs, int numDrawSurfs );
public:
backEndCounters_t pc;
// surfaces used for code-based drawing
drawSurf_t unitSquareSurface;
drawSurf_t zeroOneCubeSurface;
drawSurf_t testImageSurface;
private:
uint64 glStateBits;
const viewDef_t* viewDef;
const viewEntity_t* currentSpace; // for detecting when a matrix must change
idScreenRect currentScissor; // for scissor clipping, local inside renderView viewport
bool currentRenderCopied; // true if any material has already referenced _currentRender
idRenderMatrix prevMVP[2]; // world MVP from previous frame for motion blur
// RB begin
idRenderMatrix shadowV[6]; // shadow depth view matrix
idRenderMatrix shadowP[6]; // shadow depth projection matrix
float hdrAverageLuminance;
float hdrMaxLuminance;
float hdrTime;
float hdrKey;
// RB end
private:
#if !defined( USE_VULKAN )
int currenttmu;
unsigned int currentVertexBuffer;
unsigned int currentIndexBuffer;
Framebuffer* currentFramebuffer; // RB: for offscreen rendering
int faceCulling;
vertexLayoutType_t vertexLayout;
float polyOfsScale;
float polyOfsBias;
public:
int GetCurrentTextureUnit() const
{
return currenttmu;
}
#if 0
unsigned short gammaTable[ 256 ]; // brightness / gamma modify this
idStr rendererString;
idStr vendorString;
idStr versionString;
idStr extensionsString;
idStr wglExtensionsString;
idStr shadingLanguageString;
float glVersion; // atof( version_string )
graphicsVendor_t vendor;
int maxTextureSize; // queried from GL
int maxTextureCoords;
int maxTextureImageUnits;
int uniformBufferOffsetAlignment;
int colorBits;
int depthBits;
int stencilBits;
bool depthBoundsTestAvailable;
bool timerQueryAvailable;
bool swapControlTearAvailable;
int displayFrequency;
#endif
#endif // !defined( USE_VULKAN )
};
#endif

View file

@ -35,7 +35,6 @@ If you have questions concerning this license or the applicable additional terms
#include "GLState.h"
#include "ScreenRect.h"
#include "ImageOpts.h"
#include "Image.h"
#include "Font.h"
#include "Framebuffer.h"
@ -676,15 +675,6 @@ struct performanceCounters_t
};
struct tmu_t
{
unsigned int current2DMap;
unsigned int current2DArray;
unsigned int currentCubeMap;
};
const int MAX_MULTITEXTURE_UNITS = 8;
enum vertexLayoutType_t
{
@ -694,78 +684,30 @@ enum vertexLayoutType_t
LAYOUT_DRAW_SHADOW_VERT_SKINNED
};
/*
struct glstate_t
{
tmu_t tmu[MAX_MULTITEXTURE_UNITS];
int currenttmu;
int faceCulling;
vertexLayoutType_t vertexLayout;
// RB: 64 bit fixes, changed unsigned int to uintptr_t
uintptr_t currentVertexBuffer;
uintptr_t currentIndexBuffer;
Framebuffer* currentFramebuffer;
// RB end
float polyOfsScale;
float polyOfsBias;
uint64 glStateBits;
};
struct backEndCounters_t
{
int c_surfaces;
int c_shaders;
int c_drawElements;
int c_drawIndexes;
int c_shadowElements;
int c_shadowIndexes;
int c_copyFrameBuffer;
float c_overDraw;
int totalMicroSec; // total microseconds for backend run
int shadowMicroSec;
};
// all state modified by the back end is separated
// from the front end state
struct backEndState_t
{
const viewDef_t* viewDef;
backEndCounters_t pc;
const viewEntity_t* currentSpace; // for detecting when a matrix must change
idScreenRect currentScissor; // for scissor clipping, local inside renderView viewport
glstate_t glState; // for OpenGL state deltas
bool currentRenderCopied; // true if any material has already referenced _currentRender
idRenderMatrix prevMVP[2]; // world MVP from previous frame for motion blur, per-eye
// RB begin
idRenderMatrix shadowV[6]; // shadow depth view matrix
idRenderMatrix shadowP[6]; // shadow depth projection matrix
float hdrAverageLuminance;
float hdrMaxLuminance;
float hdrTime;
float hdrKey;
// RB end
// surfaces used for code-based drawing
drawSurf_t unitSquareSurface;
drawSurf_t zeroOneCubeSurface;
drawSurf_t testImageSurface;
};
*/
class idParallelJobList;
@ -774,6 +716,8 @@ const int MAX_GUI_SURFACES = 1024; // default size of the drawSurfs list for gu
static const int MAX_RENDER_CROPS = 8;
#include "RenderBackend.h"
/*
** Most renderer globals are defined here.
** backend functions should never modify any of these fields,
@ -845,13 +789,14 @@ public:
virtual void UnCrop();
virtual bool UploadImage( const char* imageName, const byte* data, int width, int height );
void PrintPerformanceCounters();
public:
// internal functions
idRenderSystemLocal();
~idRenderSystemLocal();
void UpdateStereo3DMode();
void Clear();
@ -928,10 +873,11 @@ public:
idParallelJobList* frontEndJobList;
idRenderBackend backend;
unsigned timerQueryId; // for GL_TIME_ELAPSED_EXT queries
};
extern backEndState_t backEnd;
extern idRenderSystemLocal tr;
extern glconfig_t glConfig; // outside of TR since it shouldn't be cleared during ref re-init
@ -1470,17 +1416,8 @@ struct localTrace_t
};
localTrace_t R_LocalTrace( const idVec3& start, const idVec3& end, const float radius, const srfTriangles_t* tri );
void RB_ShowTrace( drawSurf_t** drawSurfs, int numDrawSurfs );
/*
=============================================================
BACKEND
=============================================================
*/
void RB_ExecuteBackEndCommands( const emptyCommand_t* cmds );
/*
============================================================
@ -1491,11 +1428,6 @@ TR_BACKEND_DRAW
*/
void RB_SetMVP( const idRenderMatrix& mvp );
void RB_DrawElementsWithCounters( const drawSurf_t* surf );
void RB_DrawViewInternal( const viewDef_t* viewDef, const int stereoEye );
void RB_DrawView( const void* data, const int stereoEye );
void RB_CopyRender( const void* data );
void RB_PostProcess( const void* data );
/*
=============================================================
@ -1513,13 +1445,7 @@ void RB_ClearDebugLines( int time );
void RB_AddDebugPolygon( const idVec4& color, const idWinding& winding, const int lifeTime, const bool depthTest );
void RB_ClearDebugPolygons( int time );
void RB_DrawBounds( const idBounds& bounds );
void RB_ShowLights( drawSurf_t** drawSurfs, int numDrawSurfs );
void RB_ShowLightCount( drawSurf_t** drawSurfs, int numDrawSurfs );
void RB_PolygonClear();
void RB_ScanStencilBuffer();
void RB_ShowDestinationAlpha();
void RB_ShowOverdraw();
void RB_RenderDebugTools( drawSurf_t** drawSurfs, int numDrawSurfs );
void RB_ShutdownDebugTools();
void RB_SetVertexColorParms( stageVertexColor_t svc );
@ -1531,7 +1457,6 @@ void RB_SetVertexColorParms( stageVertexColor_t svc );
#include "jobs/prelightshadowvolume/PreLightShadowVolume.h"
#include "jobs/staticshadowvolume/StaticShadowVolume.h"
#include "jobs/dynamicshadowvolume/DynamicShadowVolume.h"
#include "GraphicsAPIWrapper.h"
#include "GLMatrix.h"

View file

@ -31,7 +31,7 @@ If you have questions concerning this license or the applicable additional terms
#pragma hdrstop
#include "precompiled.h"
#include "tr_local.h"
#include "RenderCommon.h"
idRenderEntityLocal::idRenderEntityLocal()
{

View file

@ -27,7 +27,7 @@ If you have questions concerning this license or the applicable additional terms
===========================================================================
*/
#pragma hdrstop
#include "tr_local.h"
#include "RenderCommon.h"
/*
================================================================================================

View file

@ -30,7 +30,7 @@ If you have questions concerning this license or the applicable additional terms
#pragma hdrstop
#include "precompiled.h"
#include "tr_local.h"
#include "RenderCommon.h"
@ -200,10 +200,10 @@ void idRenderProgManager::Init()
LoadFragmentShader( i );
LoadGLSLProgram( i, i, i );
}
r_useHalfLambertLighting.ClearModified();
r_useHDR.ClearModified();
// special case handling for fastZ shaders
/*
switch( glConfig.driverType )

View file

@ -30,7 +30,7 @@ If you have questions concerning this license or the applicable additional terms
#pragma hdrstop
#include "precompiled.h"
#include "tr_local.h"
#include "RenderCommon.h"
#include "RenderProgs_embedded.h"
idCVar r_skipStripDeadCode( "r_skipStripDeadCode", "0", CVAR_BOOL, "Skip stripping dead code" );

View file

@ -31,7 +31,7 @@ If you have questions concerning this license or the applicable additional terms
#pragma hdrstop
#include "precompiled.h"
#include "tr_local.h"
#include "RenderCommon.h"
idRenderSystemLocal tr;
idRenderSystem* renderSystem = &tr;
@ -44,56 +44,56 @@ This prints both front and back end counters, so it should
only be called when the back end thread is idle.
=====================
*/
static void R_PerformanceCounters()
void idRenderSystemLocal::PrintPerformanceCounters()
{
if( r_showPrimitives.GetInteger() != 0 )
{
common->Printf( "views:%i draws:%i tris:%i (shdw:%i)\n",
tr.pc.c_numViews,
backEnd.pc.c_drawElements + backEnd.pc.c_shadowElements,
( backEnd.pc.c_drawIndexes + backEnd.pc.c_shadowIndexes ) / 3,
backEnd.pc.c_shadowIndexes / 3
pc.c_numViews,
backend.pc.c_drawElements + backend.pc.c_shadowElements,
( backend.pc.c_drawIndexes + backend.pc.c_shadowIndexes ) / 3,
backend.pc.c_shadowIndexes / 3
);
}
if( r_showDynamic.GetBool() )
{
common->Printf( "callback:%i md5:%i dfrmVerts:%i dfrmTris:%i tangTris:%i guis:%i\n",
tr.pc.c_entityDefCallbacks,
tr.pc.c_generateMd5,
tr.pc.c_deformedVerts,
tr.pc.c_deformedIndexes / 3,
tr.pc.c_tangentIndexes / 3,
tr.pc.c_guiSurfs
pc.c_entityDefCallbacks,
pc.c_generateMd5,
pc.c_deformedVerts,
pc.c_deformedIndexes / 3,
pc.c_tangentIndexes / 3,
pc.c_guiSurfs
);
}
if( r_showCull.GetBool() )
{
common->Printf( "%i box in %i box out\n",
tr.pc.c_box_cull_in, tr.pc.c_box_cull_out );
pc.c_box_cull_in, pc.c_box_cull_out );
}
if( r_showAddModel.GetBool() )
{
common->Printf( "callback:%i createInteractions:%i createShadowVolumes:%i\n",
tr.pc.c_entityDefCallbacks, tr.pc.c_createInteractions, tr.pc.c_createShadowVolumes );
common->Printf( "viewEntities:%i shadowEntities:%i viewLights:%i\n", tr.pc.c_visibleViewEntities,
tr.pc.c_shadowViewEntities, tr.pc.c_viewLights );
pc.c_entityDefCallbacks, pc.c_createInteractions, pc.c_createShadowVolumes );
common->Printf( "viewEntities:%i shadowEntities:%i viewLights:%i\n", pc.c_visibleViewEntities,
pc.c_shadowViewEntities, pc.c_viewLights );
}
if( r_showUpdates.GetBool() )
{
common->Printf( "entityUpdates:%i entityRefs:%i lightUpdates:%i lightRefs:%i\n",
tr.pc.c_entityUpdates, tr.pc.c_entityReferences,
tr.pc.c_lightUpdates, tr.pc.c_lightReferences );
pc.c_entityUpdates, pc.c_entityReferences,
pc.c_lightUpdates, pc.c_lightReferences );
}
if( r_showMemory.GetBool() )
{
common->Printf( "frameData: %i (%i)\n", frameData->frameMemoryAllocated.GetValue(), frameData->highWaterAllocated );
}
memset( &tr.pc, 0, sizeof( tr.pc ) );
memset( &backEnd.pc, 0, sizeof( backEnd.pc ) );
memset( &pc, 0, sizeof( pc ) );
memset( &backend.pc, 0, sizeof( backend.pc ) );
}
/*
@ -136,14 +136,14 @@ void idRenderSystemLocal::RenderCommandBuffers( const emptyCommand_t* const cmdH
glGenQueries( 1, & tr.timerQueryId );
}
glBeginQuery( GL_TIME_ELAPSED_EXT, tr.timerQueryId );
RB_ExecuteBackEndCommands( cmdHead );
backend.ExecuteBackEndCommands( cmdHead );
glEndQuery( GL_TIME_ELAPSED_EXT );
glFlush();
}
else
#endif
{
RB_ExecuteBackEndCommands( cmdHead );
backend.ExecuteBackEndCommands( cmdHead );
}
}
@ -228,115 +228,7 @@ void R_AddDrawPostProcess( viewDef_t* parms )
//=================================================================================
/*
=============
R_CheckCvars
See if some cvars that we watch have changed
=============
*/
static void R_CheckCvars()
{
// gamma stuff
if( r_gamma.IsModified() || r_brightness.IsModified() )
{
r_gamma.ClearModified();
r_brightness.ClearModified();
R_SetColorMappings();
}
// filtering
if( r_maxAnisotropicFiltering.IsModified() || r_useTrilinearFiltering.IsModified() || r_lodBias.IsModified() )
{
idLib::Printf( "Updating texture filter parameters.\n" );
r_maxAnisotropicFiltering.ClearModified();
r_useTrilinearFiltering.ClearModified();
r_lodBias.ClearModified();
for( int i = 0 ; i < globalImages->images.Num() ; i++ )
{
if( globalImages->images[i] )
{
globalImages->images[i]->Bind();
globalImages->images[i]->SetTexParameters();
}
}
}
extern idCVar r_useSeamlessCubeMap;
if( r_useSeamlessCubeMap.IsModified() )
{
r_useSeamlessCubeMap.ClearModified();
if( glConfig.seamlessCubeMapAvailable )
{
if( r_useSeamlessCubeMap.GetBool() )
{
glEnable( GL_TEXTURE_CUBE_MAP_SEAMLESS );
}
else
{
glDisable( GL_TEXTURE_CUBE_MAP_SEAMLESS );
}
}
}
extern idCVar r_useSRGB;
if( r_useSRGB.IsModified() )
{
r_useSRGB.ClearModified();
if( glConfig.sRGBFramebufferAvailable )
{
if( r_useSRGB.GetBool() && r_useSRGB.GetInteger() != 3 )
{
glEnable( GL_FRAMEBUFFER_SRGB );
}
else
{
glDisable( GL_FRAMEBUFFER_SRGB );
}
}
}
if( r_antiAliasing.IsModified() )
{
switch( r_antiAliasing.GetInteger() )
{
case ANTI_ALIASING_MSAA_2X:
case ANTI_ALIASING_MSAA_4X:
case ANTI_ALIASING_MSAA_8X:
if( r_antiAliasing.GetInteger() > 0 )
{
glEnable( GL_MULTISAMPLE );
}
break;
default:
glDisable( GL_MULTISAMPLE );
break;
}
}
if (r_useHDR.IsModified() || r_useHalfLambertLighting.IsModified() )
{
r_useHDR.ClearModified();
r_useHalfLambertLighting.ClearModified();
renderProgManager.KillAllShaders();
renderProgManager.LoadAllShaders();
}
// RB: turn off shadow mapping for OpenGL drivers that are too slow
switch( glConfig.driverType )
{
case GLDRV_OPENGL_ES2:
case GLDRV_OPENGL_ES3:
//case GLDRV_OPENGL_MESA:
r_useShadowMapping.SetInteger( 0 );
break;
default:
break;
}
// RB end
}
/*
=============
@ -754,8 +646,7 @@ void idRenderSystemLocal::SwapCommandBuffers_FinishRendering(
{
// wait for our fence to hit, which means the swap has actually happened
// We must do this before clearing any resources the GPU may be using
void GL_BlockingSwapBuffers();
GL_BlockingSwapBuffers();
backend.BlockingSwapBuffers();
}
// read back the start and end timer queries from the previous frame
@ -784,18 +675,18 @@ void idRenderSystemLocal::SwapCommandBuffers_FinishRendering(
}
if( backEndMicroSec != NULL )
{
*backEndMicroSec = backEnd.pc.totalMicroSec;
*backEndMicroSec = backend.pc.totalMicroSec;
}
if( shadowMicroSec != NULL )
{
*shadowMicroSec = backEnd.pc.shadowMicroSec;
*shadowMicroSec = backend.pc.shadowMicroSec;
}
// print any other statistics and clear all of them
R_PerformanceCounters();
PrintPerformanceCounters();
// check for dynamic changes that require some initialization
R_CheckCvars();
backend.CheckCVars();
// RB: resize HDR buffers
Framebuffer::CheckFramebuffers();
@ -829,9 +720,9 @@ const emptyCommand_t* idRenderSystemLocal::SwapCommandBuffers_FinishCommandBuffe
// copy the code-used drawsurfs that were
// allocated at the start of the buffer memory to the backEnd referenced locations
backEnd.unitSquareSurface = tr.unitSquareSurface_;
backEnd.zeroOneCubeSurface = tr.zeroOneCubeSurface_;
backEnd.testImageSurface = tr.testImageSurface_;
backend.unitSquareSurface = tr.unitSquareSurface_;
backend.zeroOneCubeSurface = tr.zeroOneCubeSurface_;
backend.testImageSurface = tr.testImageSurface_;
// use the other buffers next frame, because another CPU
// may still be rendering into the current buffers

View file

@ -31,7 +31,7 @@ If you have questions concerning this license or the applicable additional terms
#pragma hdrstop
#include "precompiled.h"
#include "tr_local.h"
#include "RenderCommon.h"
// RB begin
#if defined(_WIN32)
@ -391,8 +391,8 @@ static void R_CheckPortableExtensions()
// RB: Mesa support
if( idStr::Icmpn( glConfig.renderer_string, "Mesa", 4 ) == 0 || idStr::Icmpn( glConfig.renderer_string, "X.org", 5 ) == 0 || idStr::Icmpn( glConfig.renderer_string, "Gallium", 7 ) == 0 ||
strcmp( glConfig.vendor_string, "X.Org" ) == 0 ||
idStr::Icmpn( glConfig.renderer_string, "llvmpipe", 8 ) == 0 )
strcmp( glConfig.vendor_string, "X.Org" ) == 0 ||
idStr::Icmpn( glConfig.renderer_string, "llvmpipe", 8 ) == 0 )
{
if( glConfig.driverType == GLDRV_OPENGL32_CORE_PROFILE )
{
@ -952,67 +952,7 @@ void R_InitOpenGL()
// RB end
}
/*
==================
GL_CheckErrors
==================
*/
// RB: added filename, line parms
bool GL_CheckErrors_( const char* filename, int line )
{
int err;
char s[64];
int i;
if( r_ignoreGLErrors.GetBool() )
{
return false;
}
// check for up to 10 errors pending
bool error = false;
for( i = 0 ; i < 10 ; i++ )
{
err = glGetError();
if( err == GL_NO_ERROR )
{
break;
}
error = true;
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;
#if !defined(USE_GLES2) && !defined(USE_GLES3)
case GL_STACK_OVERFLOW:
strcpy( s, "GL_STACK_OVERFLOW" );
break;
case GL_STACK_UNDERFLOW:
strcpy( s, "GL_STACK_UNDERFLOW" );
break;
#endif
case GL_OUT_OF_MEMORY:
strcpy( s, "GL_OUT_OF_MEMORY" );
break;
default:
idStr::snPrintf( s, sizeof( s ), "%i", err );
break;
}
common->Printf( "caught OpenGL error: %s in file %s line %i\n", s, filename, line );
}
return error;
}
// RB end
/*
=====================
@ -2909,7 +2849,7 @@ void idRenderSystemLocal::Init()
ambientLightVector[2] = 0.8925f;
ambientLightVector[3] = 1.0f;
memset( &backEnd, 0, sizeof( backEnd ) );
backend.Init();
R_InitCvars();
@ -2918,9 +2858,9 @@ void idRenderSystemLocal::Init()
guiModel = new( TAG_RENDER ) idGuiModel;
guiModel->Clear();
tr_guiModel = guiModel; // for DeviceContext fast path
UpdateStereo3DMode();
globalImages->Init();
// RB begin

View file

@ -31,7 +31,7 @@ If you have questions concerning this license or the applicable additional terms
#pragma hdrstop
#include "precompiled.h"
#include "tr_local.h"
#include "RenderCommon.h"
/*
===================

View file

@ -30,7 +30,7 @@ If you have questions concerning this license or the applicable additional terms
#pragma hdrstop
#include "precompiled.h"
#include "tr_local.h"
#include "RenderCommon.h"
/*
=================================================================================

View file

@ -31,7 +31,7 @@ If you have questions concerning this license or the applicable additional terms
#pragma hdrstop
#include "precompiled.h"
#include "tr_local.h"
#include "RenderCommon.h"
idCVar r_writeDemoDecals( "r_writeDemoDecals", "1", CVAR_BOOL | CVAR_SYSTEM, "enable Writing of entity decals to demo files." );
idCVar r_writeDemoOverlays( "r_writeDemoOverlays", "1", CVAR_BOOL | CVAR_SYSTEM, "enable Writing of entity Overlays to demo files." );

View file

@ -29,7 +29,7 @@ If you have questions concerning this license or the applicable additional terms
#pragma hdrstop
#include "precompiled.h"
#include "tr_local.h"
#include "RenderCommon.h"
/*

View file

@ -251,7 +251,6 @@ public:
{
return areaScreenRect[areaNum];
}
void ShowPortals();
//--------------------------
// RenderWorld_demo.cpp

View file

@ -30,7 +30,7 @@ If you have questions concerning this license or the applicable additional terms
#pragma hdrstop
#include "precompiled.h"
#include "tr_local.h"
#include "RenderCommon.h"
// if we hit this many planes, we will just stop cropping the
// view down, which is still correct, just conservative
@ -1157,57 +1157,3 @@ int idRenderWorldLocal::GetPortalState( qhandle_t portal )
return doublePortals[portal - 1].blockingBits;
}
/*
=====================
idRenderWorldLocal::ShowPortals
Debugging tool, won't work correctly with SMP or when mirrors are present
=====================
*/
void idRenderWorldLocal::ShowPortals()
{
int i, j;
portalArea_t* area;
portal_t* p;
idWinding* w;
// flood out through portals, setting area viewCount
for( i = 0; i < numPortalAreas; i++ )
{
area = &portalAreas[i];
if( area->viewCount != tr.viewCount )
{
continue;
}
for( p = area->portals; p; p = p->next )
{
w = p->w;
if( !w )
{
continue;
}
if( portalAreas[ p->intoArea ].viewCount != tr.viewCount )
{
// red = can't see
GL_Color( 1, 0, 0 );
}
else
{
// green = see through
GL_Color( 0, 1, 0 );
}
// RB begin
renderProgManager.CommitUniforms();
// RB end
glBegin( GL_LINE_LOOP );
for( j = 0; j < w->GetNumPoints(); j++ )
{
glVertex3fv( ( *w )[j].ToFloatPtr() );
}
glEnd();
}
}
}

View file

@ -29,7 +29,7 @@ If you have questions concerning this license or the applicable additional terms
#pragma hdrstop
#include "precompiled.h"
#include "tr_local.h"
#include "RenderCommon.h"
#include "ResolutionScale.h"

View file

@ -29,7 +29,7 @@ If you have questions concerning this license or the applicable additional terms
#pragma hdrstop
#include "precompiled.h"
#include "tr_local.h"
#include "RenderCommon.h"
/*
==========================================================================================

View file

@ -30,7 +30,7 @@ If you have questions concerning this license or the applicable additional terms
#pragma hdrstop
#include "precompiled.h"
#include "tr_local.h"
#include "RenderCommon.h"
idVertexCache vertexCache;

View file

@ -30,7 +30,7 @@ If you have questions concerning this license or the applicable additional terms
#pragma hdrstop
#include "precompiled.h"
#include "tr_local.h"
#include "RenderCommon.h"
extern idCVar r_useAreasConnectedForShadowCulling;
extern idCVar r_useParallelAddShadows;
@ -673,7 +673,7 @@ void R_AddLights()
}
int end = Sys_Microseconds();
backEnd.pc.shadowMicroSec += end - start;
tr.backend.pc.shadowMicroSec += end - start;
}
}

View file

@ -30,7 +30,7 @@ If you have questions concerning this license or the applicable additional terms
#pragma hdrstop
#include "precompiled.h"
#include "tr_local.h"
#include "RenderCommon.h"
#include "Model_local.h"
idCVar r_skipStaticShadows( "r_skipStaticShadows", "0", CVAR_RENDERER | CVAR_BOOL, "skip static shadows" );
@ -1402,7 +1402,7 @@ void R_AddModels()
}
int end = Sys_Microseconds();
backEnd.pc.shadowMicroSec += end - start;
tr.backend.pc.shadowMicroSec += end - start;
}
}

View file

@ -30,7 +30,7 @@ If you have questions concerning this license or the applicable additional terms
#pragma hdrstop
#include "precompiled.h"
#include "tr_local.h"
#include "RenderCommon.h"
#include "Model_local.h"
/*

View file

@ -30,7 +30,7 @@ If you have questions concerning this license or the applicable additional terms
#pragma hdrstop
#include "precompiled.h"
#include "tr_local.h"
#include "RenderCommon.h"
#include "Model_local.h"
/*

View file

@ -30,7 +30,7 @@ If you have questions concerning this license or the applicable additional terms
#pragma hdrstop
#include "precompiled.h"
#include "tr_local.h"
#include "RenderCommon.h"
/*
==========================================================================================

View file

@ -30,7 +30,7 @@ If you have questions concerning this license or the applicable additional terms
#pragma hdrstop
#include "precompiled.h"
#include "tr_local.h"
#include "RenderCommon.h"
#include "Model_local.h"
/*

View file

@ -30,7 +30,7 @@ If you have questions concerning this license or the applicable additional terms
#pragma hdrstop
#include "precompiled.h"
#include "tr_local.h"
#include "RenderCommon.h"
#include "Model_local.h"
#include "../idlib/geometry/DrawVert_intrinsics.h"

View file

@ -29,7 +29,7 @@ If you have questions concerning this license or the applicable additional terms
#pragma hdrstop
#include "precompiled.h"
#include "tr_local.h"
#include "RenderCommon.h"
/*
==============================================================================

View file

@ -3,6 +3,7 @@
Doom 3 BFG Edition GPL Source Code
Copyright (C) 1993-2012 id Software LLC, a ZeniMax Media company.
Copyright (C) 2016-2017 Dustin Land
This file is part of the Doom 3 BFG Edition GPL Source Code ("Doom 3 BFG Edition Source Code").
@ -89,14 +90,14 @@ idSWFScriptObject* idSWF::HitTest( idSWFSpriteInstance* spriteInstance, const sw
else if( entry->type == SWF_DICT_SHAPE && ( parentObject != NULL ) )
{
idSWFShape* shape = entry->shape;
for( int i = 0; i < shape->fillDraws.Num(); i++ )
for( int j = 0; j < shape->fillDraws.Num(); j++ )
{
const idSWFShapeDrawFill& fill = shape->fillDraws[i];
for( int j = 0; j < fill.indices.Num(); j += 3 )
const idSWFShapeDrawFill& fill = shape->fillDraws[j];
for( int k = 0; k < fill.indices.Num(); k += 3 )
{
idVec2 xy1 = renderState2.matrix.Transform( fill.startVerts[fill.indices[j + 0]] );
idVec2 xy2 = renderState2.matrix.Transform( fill.startVerts[fill.indices[j + 1]] );
idVec2 xy3 = renderState2.matrix.Transform( fill.startVerts[fill.indices[j + 2]] );
idVec2 xy1 = renderState2.matrix.Transform( fill.startVerts[fill.indices[k + 0]] );
idVec2 xy2 = renderState2.matrix.Transform( fill.startVerts[fill.indices[k + 1]] );
idVec2 xy3 = renderState2.matrix.Transform( fill.startVerts[fill.indices[k + 2]] );
idMat3 edgeEquations;
edgeEquations[0].Set( xy1.x + xOffset, xy1.y + yOffset, 1.0f );
@ -162,9 +163,6 @@ idSWFScriptObject* idSWF::HitTest( idSWFSpriteInstance* spriteInstance, const sw
idVec3 br;
idVec3 bl;
float xOffset = spriteInstance->xOffset;
float yOffset = spriteInstance->yOffset;
float topOffset = 0.0f;
if( text->align == SWF_ET_ALIGN_LEFT )
@ -289,7 +287,7 @@ bool idSWF::HandleEvent( const sysEvent_t* event )
return true;
}
idSWFScriptVar var = hitObject->Get( "onDrag" );
var = hitObject->Get( "onDrag" );
if( var.IsFunction() )
{
idSWFParmList parms;

View file

@ -28,7 +28,7 @@ If you have questions concerning this license or the applicable additional terms
*/
#pragma hdrstop
#include "precompiled.h"
#include "../renderer/tr_local.h"
#include "../renderer/RenderCommon.h"
idCVar swf_timescale( "swf_timescale", "1", CVAR_FLOAT, "timescale for swf files" );
idCVar swf_stopat( "swf_stopat", "0", CVAR_FLOAT, "stop at a specific frame" );

View file

@ -2316,7 +2316,7 @@ idStr idSWFScriptFunction_Script::ExportToScript( idSWFScriptObject* thisObject,
}
else
{
line = va( "function %s( ", functionName.c_str() );
line = va( "function %s( ", functionName.c_str() );
}
uint16 numParms = bitstream.ReadU16();
@ -2392,7 +2392,7 @@ idStr idSWFScriptFunction_Script::ExportToScript( idSWFScriptObject* thisObject,
}
else
{
line = va( "function %s( ", functionName.c_str() );
line = va( "function %s( ", functionName.c_str() );
}
for( int i = 0; i < numParms; i++ )
@ -2584,7 +2584,7 @@ idStr idSWFScriptFunction_Script::ExportToScript( idSWFScriptObject* thisObject,
//actionScript += line;
//line.Empty();
const idStr& member = stack.A().ToString();
const idStr& member = stack.A().ToString();
//if( stack.A().IsString() )
//{
// stack.B().SetResult( va( "%s[\"%s\"]", stack.B().ToString().c_str(), stack.A().ToString().c_str() ) );

View file

@ -453,7 +453,7 @@ void idSWFSprite::ReadJSON( rapidjson::Value& entry )
idFile_SWF file( new idFile_Memory() );
idBase64 base64( command["stream"].GetString() );
idBase64 base64( command["stream"].GetString() );
base64.Decode( file );
uint32 streamLength = file->Length() - 1; // skip trailing zero added by Decode()

View file

@ -46,7 +46,7 @@ If you have questions concerning this license or the applicable additional terms
#include "win_local.h"
#include "rc/doom_resource.h"
#include "../../renderer/tr_local.h"
#include "../../renderer/RenderCommon.h"

View file

@ -47,7 +47,7 @@ If you have questions concerning this license or the applicable additional terms
#include "../sys_local.h"
#include "win_local.h"
#include "../../renderer/tr_local.h"
#include "../../renderer/RenderCommon.h"
idCVar Win32Vars_t::sys_arch( "sys_arch", "", CVAR_SYSTEM | CVAR_INIT, "" );
idCVar Win32Vars_t::sys_cpustring( "sys_cpustring", "detect", CVAR_SYSTEM | CVAR_INIT, "" );

View file

@ -31,7 +31,7 @@ If you have questions concerning this license or the applicable additional terms
#include "precompiled.h"
#include "win_local.h"
#include "../../renderer/tr_local.h"
#include "../../renderer/RenderCommon.h"
#include <windowsx.h>

View file

@ -402,7 +402,7 @@ void Dmap( const idCmdArgs& args )
passedName = stripped;
// delete any old line leak files
idStr::snPrintf( path, sizeof( path ),"%s.lin", dmapGlobals.mapFileBase );
idStr::snPrintf( path, sizeof( path ), "%s.lin", dmapGlobals.mapFileBase );
fileSystem->RemoveFile( path );
// delete any old generated binary proc files

View file

@ -27,7 +27,7 @@ If you have questions concerning this license or the applicable additional terms
===========================================================================
*/
#include "../../../renderer/tr_local.h"
#include "../../../renderer/RenderCommon.h"
typedef struct primitive_s