From 579de5008d880f23cbd3ca6b16e73c3ed6fbb946 Mon Sep 17 00:00:00 2001 From: Robert Beckebans Date: Tue, 29 Aug 2017 16:26:03 +0200 Subject: [PATCH 01/12] Merged SWF fixes from vkDoom3 --- neo/swf/SWF_Events.cpp | 18 ++++++++---------- neo/swf/SWF_ScriptFunction.cpp | 6 +++--- neo/swf/SWF_Sprites.cpp | 2 +- 3 files changed, 12 insertions(+), 14 deletions(-) diff --git a/neo/swf/SWF_Events.cpp b/neo/swf/SWF_Events.cpp index 16298584..7e504678 100644 --- a/neo/swf/SWF_Events.cpp +++ b/neo/swf/SWF_Events.cpp @@ -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; diff --git a/neo/swf/SWF_ScriptFunction.cpp b/neo/swf/SWF_ScriptFunction.cpp index cc0bab3a..ed57d203 100644 --- a/neo/swf/SWF_ScriptFunction.cpp +++ b/neo/swf/SWF_ScriptFunction.cpp @@ -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() ) ); diff --git a/neo/swf/SWF_Sprites.cpp b/neo/swf/SWF_Sprites.cpp index d89999c2..1e2b7bd5 100644 --- a/neo/swf/SWF_Sprites.cpp +++ b/neo/swf/SWF_Sprites.cpp @@ -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() From 4daffd67c0fa89eeacdcf3e799247967686081a8 Mon Sep 17 00:00:00 2001 From: Robert Beckebans Date: Sun, 3 Sep 2017 09:45:03 +0200 Subject: [PATCH 02/12] Astyle --- neo/renderer/Framebuffer.cpp | 6 +++--- neo/renderer/RenderProgs.cpp | 4 ++-- neo/renderer/RenderSystem.cpp | 4 ++-- neo/renderer/RenderSystem_init.cpp | 8 ++++---- neo/renderer/tr_local.h | 2 +- 5 files changed, 12 insertions(+), 12 deletions(-) diff --git a/neo/renderer/Framebuffer.cpp b/neo/renderer/Framebuffer.cpp index 18352399..a9b728b3 100644 --- a/neo/renderer/Framebuffer.cpp +++ b/neo/renderer/Framebuffer.cpp @@ -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; diff --git a/neo/renderer/RenderProgs.cpp b/neo/renderer/RenderProgs.cpp index 694760dd..651ea89b 100644 --- a/neo/renderer/RenderProgs.cpp +++ b/neo/renderer/RenderProgs.cpp @@ -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 ) diff --git a/neo/renderer/RenderSystem.cpp b/neo/renderer/RenderSystem.cpp index 2e875585..5dce4dcf 100644 --- a/neo/renderer/RenderSystem.cpp +++ b/neo/renderer/RenderSystem.cpp @@ -314,8 +314,8 @@ static void R_CheckCvars() break; } } - - if (r_useHDR.IsModified() || r_useHalfLambertLighting.IsModified() ) + + if( r_useHDR.IsModified() || r_useHalfLambertLighting.IsModified() ) { r_useHDR.ClearModified(); r_useHalfLambertLighting.ClearModified(); diff --git a/neo/renderer/RenderSystem_init.cpp b/neo/renderer/RenderSystem_init.cpp index b45e4a23..9abd45a4 100644 --- a/neo/renderer/RenderSystem_init.cpp +++ b/neo/renderer/RenderSystem_init.cpp @@ -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 ) { @@ -2792,9 +2792,9 @@ void idRenderSystemLocal::Init() guiModel = new( TAG_RENDER ) idGuiModel; guiModel->Clear(); tr_guiModel = guiModel; // for DeviceContext fast path - + UpdateStereo3DMode(); - + globalImages->Init(); // RB begin diff --git a/neo/renderer/tr_local.h b/neo/renderer/tr_local.h index 44183538..b9d682da 100644 --- a/neo/renderer/tr_local.h +++ b/neo/renderer/tr_local.h @@ -851,7 +851,7 @@ public: // internal functions idRenderSystemLocal(); ~idRenderSystemLocal(); - + void UpdateStereo3DMode(); void Clear(); From 736ccadcb32772d356996333a2df1a5b8f7b735d Mon Sep 17 00:00:00 2001 From: Robert Beckebans Date: Sun, 3 Sep 2017 10:22:36 +0200 Subject: [PATCH 03/12] Started to move files so it can be compared to vkdoom3 --- neo/d3xp/menus/MenuScreen.h | 2 +- .../menus/MenuScreen_Shell_Resolution.cpp | 2 +- neo/framework/common_frame.cpp | 1 - neo/renderer/BinaryImage.cpp | 2 +- neo/renderer/BufferObject.cpp | 2 +- neo/renderer/Cinematic.cpp | 2 +- neo/renderer/Framebuffer.cpp | 2 +- neo/renderer/GLMatrix.cpp | 2 +- neo/renderer/GuiModel.cpp | 2 +- neo/renderer/Image.h | 154 ++++++++++++++- neo/renderer/ImageManager.cpp | 2 +- neo/renderer/ImageOpts.h | 185 ------------------ neo/renderer/Image_files.cpp | 2 +- neo/renderer/Image_intrinsic.cpp | 2 +- neo/renderer/Image_load.cpp | 2 +- neo/renderer/Image_process.cpp | 2 +- neo/renderer/Image_program.cpp | 2 +- neo/renderer/Interaction.cpp | 2 +- neo/renderer/Material.cpp | 2 +- neo/renderer/Model.cpp | 2 +- neo/renderer/ModelDecal.cpp | 2 +- neo/renderer/ModelManager.cpp | 2 +- neo/renderer/ModelOverlay.cpp | 2 +- neo/renderer/Model_beam.cpp | 2 +- neo/renderer/Model_liquid.cpp | 2 +- neo/renderer/Model_md3.cpp | 2 +- neo/renderer/Model_md5.cpp | 2 +- neo/renderer/Model_prt.cpp | 2 +- neo/renderer/Model_sprite.cpp | 2 +- .../OpenGL/{gl_Image.cpp => Image_GL.cpp} | 2 +- .../{gl_backend.cpp => RenderBackend_GL.cpp} | 2 +- neo/renderer/OpenGL/gl_GraphicsAPIWrapper.cpp | 2 +- ...{tr_backend_draw.cpp => RenderBackend.cpp} | 2 +- neo/renderer/{tr_local.h => RenderCommon.h} | 1 - neo/renderer/RenderEntity.cpp | 2 +- neo/renderer/RenderLog.cpp | 2 +- neo/renderer/RenderProgs.cpp | 2 +- neo/renderer/RenderProgs_GLSL.cpp | 2 +- neo/renderer/RenderSystem.cpp | 2 +- neo/renderer/RenderSystem_init.cpp | 2 +- neo/renderer/RenderWorld.cpp | 2 +- neo/renderer/RenderWorld_defs.cpp | 2 +- neo/renderer/RenderWorld_demo.cpp | 2 +- neo/renderer/RenderWorld_load.cpp | 2 +- neo/renderer/RenderWorld_portals.cpp | 2 +- neo/renderer/ResolutionScale.cpp | 2 +- neo/renderer/ScreenRect.cpp | 2 +- neo/renderer/VertexCache.cpp | 2 +- neo/renderer/tr_backend_rendertools.cpp | 2 +- neo/renderer/tr_frontend_addlights.cpp | 2 +- neo/renderer/tr_frontend_addmodels.cpp | 2 +- neo/renderer/tr_frontend_deform.cpp | 2 +- neo/renderer/tr_frontend_guisurf.cpp | 2 +- neo/renderer/tr_frontend_main.cpp | 2 +- neo/renderer/tr_frontend_subview.cpp | 2 +- neo/renderer/tr_trace.cpp | 2 +- neo/renderer/tr_trisurf.cpp | 2 +- neo/swf/SWF_Render.cpp | 2 +- neo/sys/win32/win_glimp.cpp | 2 +- neo/sys/win32/win_main.cpp | 2 +- neo/sys/win32/win_wndproc.cpp | 2 +- neo/tools/compilers/dmap/dmap.h | 2 +- 62 files changed, 211 insertions(+), 246 deletions(-) delete mode 100644 neo/renderer/ImageOpts.h rename neo/renderer/OpenGL/{gl_Image.cpp => Image_GL.cpp} (99%) rename neo/renderer/OpenGL/{gl_backend.cpp => RenderBackend_GL.cpp} (99%) rename neo/renderer/{tr_backend_draw.cpp => RenderBackend.cpp} (99%) rename neo/renderer/{tr_local.h => RenderCommon.h} (99%) diff --git a/neo/d3xp/menus/MenuScreen.h b/neo/d3xp/menus/MenuScreen.h index 554faec1..4d573be0 100644 --- a/neo/d3xp/menus/MenuScreen.h +++ b/neo/d3xp/menus/MenuScreen.h @@ -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 { diff --git a/neo/d3xp/menus/MenuScreen_Shell_Resolution.cpp b/neo/d3xp/menus/MenuScreen_Shell_Resolution.cpp index a0389795..d6004d78 100644 --- a/neo/d3xp/menus/MenuScreen_Shell_Resolution.cpp +++ b/neo/d3xp/menus/MenuScreen_Shell_Resolution.cpp @@ -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; diff --git a/neo/framework/common_frame.cpp b/neo/framework/common_frame.cpp index 7e101034..8d66c7db 100644 --- a/neo/framework/common_frame.cpp +++ b/neo/framework/common_frame.cpp @@ -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) diff --git a/neo/renderer/BinaryImage.cpp b/neo/renderer/BinaryImage.cpp index ed988e03..ac9ea0bd 100644 --- a/neo/renderer/BinaryImage.cpp +++ b/neo/renderer/BinaryImage.cpp @@ -36,7 +36,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" diff --git a/neo/renderer/BufferObject.cpp b/neo/renderer/BufferObject.cpp index b5f4d41e..d3e2aa42 100644 --- a/neo/renderer/BufferObject.cpp +++ b/neo/renderer/BufferObject.cpp @@ -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, "" ); diff --git a/neo/renderer/Cinematic.cpp b/neo/renderer/Cinematic.cpp index 3865d0d1..88f10253 100644 --- a/neo/renderer/Cinematic.cpp +++ b/neo/renderer/Cinematic.cpp @@ -39,7 +39,7 @@ extern idCVar s_noSound; #include //} -#include "tr_local.h" +#include "RenderCommon.h" #define CIN_system 1 #define CIN_loop 2 diff --git a/neo/renderer/Framebuffer.cpp b/neo/renderer/Framebuffer.cpp index a9b728b3..f41dd61e 100644 --- a/neo/renderer/Framebuffer.cpp +++ b/neo/renderer/Framebuffer.cpp @@ -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::framebuffers; diff --git a/neo/renderer/GLMatrix.cpp b/neo/renderer/GLMatrix.cpp index d76bbd49..6c2c46ac 100644 --- a/neo/renderer/GLMatrix.cpp +++ b/neo/renderer/GLMatrix.cpp @@ -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" /* ========================================================================================== diff --git a/neo/renderer/GuiModel.cpp b/neo/renderer/GuiModel.cpp index 459e5b97..8f857716 100644 --- a/neo/renderer/GuiModel.cpp +++ b/neo/renderer/GuiModel.cpp @@ -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; diff --git a/neo/renderer/Image.h b/neo/renderer/Image.h index 2f740b9a..cac6d280 100644 --- a/neo/renderer/Image.h +++ b/neo/renderer/Image.h @@ -4,6 +4,7 @@ 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) 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,158 @@ 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 ); + +/* +================================================ +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 ); +} + /* ==================================================================== @@ -79,7 +232,6 @@ enum imageFileType_t JPG }; -#include "ImageOpts.h" #include "BinaryImage.h" #define MAX_IMAGE_NAME 256 diff --git a/neo/renderer/ImageManager.cpp b/neo/renderer/ImageManager.cpp index 01b5d7b9..c6b71248 100644 --- a/neo/renderer/ImageManager.cpp +++ b/neo/renderer/ImageManager.cpp @@ -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 diff --git a/neo/renderer/ImageOpts.h b/neo/renderer/ImageOpts.h deleted file mode 100644 index 6c164c93..00000000 --- a/neo/renderer/ImageOpts.h +++ /dev/null @@ -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 . - -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 \ No newline at end of file diff --git a/neo/renderer/Image_files.cpp b/neo/renderer/Image_files.cpp index 6ffd44b8..2feb70bc 100644 --- a/neo/renderer/Image_files.cpp +++ b/neo/renderer/Image_files.cpp @@ -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" /* diff --git a/neo/renderer/Image_intrinsic.cpp b/neo/renderer/Image_intrinsic.cpp index 8509b8f6..4423fcb6 100644 --- a/neo/renderer/Image_intrinsic.cpp +++ b/neo/renderer/Image_intrinsic.cpp @@ -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" diff --git a/neo/renderer/Image_load.cpp b/neo/renderer/Image_load.cpp index 9159c068..c3df69e4 100644 --- a/neo/renderer/Image_load.cpp +++ b/neo/renderer/Image_load.cpp @@ -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" /* ================ diff --git a/neo/renderer/Image_process.cpp b/neo/renderer/Image_process.cpp index a10d760b..c8bcddb0 100644 --- a/neo/renderer/Image_process.cpp +++ b/neo/renderer/Image_process.cpp @@ -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" /* ================ diff --git a/neo/renderer/Image_program.cpp b/neo/renderer/Image_program.cpp index f9bc009e..c2c44d33 100644 --- a/neo/renderer/Image_program.cpp +++ b/neo/renderer/Image_program.cpp @@ -56,7 +56,7 @@ Manager // tr_imageprogram.c -#include "tr_local.h" +#include "RenderCommon.h" /* diff --git a/neo/renderer/Interaction.cpp b/neo/renderer/Interaction.cpp index 86d4f3bc..02624ede 100644 --- a/neo/renderer/Interaction.cpp +++ b/neo/renderer/Interaction.cpp @@ -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" /* =========================================================================== diff --git a/neo/renderer/Material.cpp b/neo/renderer/Material.cpp index 721db3be..804859ce 100644 --- a/neo/renderer/Material.cpp +++ b/neo/renderer/Material.cpp @@ -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" /* diff --git a/neo/renderer/Model.cpp b/neo/renderer/Model.cpp index 68e274d2..032141dc 100644 --- a/neo/renderer/Model.cpp +++ b/neo/renderer/Model.cpp @@ -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" diff --git a/neo/renderer/ModelDecal.cpp b/neo/renderer/ModelDecal.cpp index 13824f41..514ce028 100644 --- a/neo/renderer/ModelDecal.cpp +++ b/neo/renderer/ModelDecal.cpp @@ -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" diff --git a/neo/renderer/ModelManager.cpp b/neo/renderer/ModelManager.cpp index 77ae09d4..d65b7530 100644 --- a/neo/renderer/ModelManager.cpp +++ b/neo/renderer/ModelManager.cpp @@ -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" ); diff --git a/neo/renderer/ModelOverlay.cpp b/neo/renderer/ModelOverlay.cpp index 6b2033e8..c131467a 100644 --- a/neo/renderer/ModelOverlay.cpp +++ b/neo/renderer/ModelOverlay.cpp @@ -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" diff --git a/neo/renderer/Model_beam.cpp b/neo/renderer/Model_beam.cpp index 0c5a3556..4e756634 100644 --- a/neo/renderer/Model_beam.cpp +++ b/neo/renderer/Model_beam.cpp @@ -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" /* diff --git a/neo/renderer/Model_liquid.cpp b/neo/renderer/Model_liquid.cpp index 0b2f00eb..201ef84c 100644 --- a/neo/renderer/Model_liquid.cpp +++ b/neo/renderer/Model_liquid.cpp @@ -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 diff --git a/neo/renderer/Model_md3.cpp b/neo/renderer/Model_md3.cpp index 02514e9c..566840a3 100644 --- a/neo/renderer/Model_md3.cpp +++ b/neo/renderer/Model_md3.cpp @@ -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" diff --git a/neo/renderer/Model_md5.cpp b/neo/renderer/Model_md5.cpp index 69a6a530..c29119ab 100644 --- a/neo/renderer/Model_md5.cpp +++ b/neo/renderer/Model_md5.cpp @@ -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) diff --git a/neo/renderer/Model_prt.cpp b/neo/renderer/Model_prt.cpp index 237a1d8f..8aa6a4e8 100644 --- a/neo/renderer/Model_prt.cpp +++ b/neo/renderer/Model_prt.cpp @@ -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_"; diff --git a/neo/renderer/Model_sprite.cpp b/neo/renderer/Model_sprite.cpp index a965d386..5438718e 100644 --- a/neo/renderer/Model_sprite.cpp +++ b/neo/renderer/Model_sprite.cpp @@ -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" diff --git a/neo/renderer/OpenGL/gl_Image.cpp b/neo/renderer/OpenGL/Image_GL.cpp similarity index 99% rename from neo/renderer/OpenGL/gl_Image.cpp rename to neo/renderer/OpenGL/Image_GL.cpp index d4202a99..ccf16868 100644 --- a/neo/renderer/OpenGL/gl_Image.cpp +++ b/neo/renderer/OpenGL/Image_GL.cpp @@ -35,7 +35,7 @@ Contains the Image implementation for OpenGL. ================================================================================================ */ -#include "../tr_local.h" +#include "../RenderCommon.h" /* ======================== diff --git a/neo/renderer/OpenGL/gl_backend.cpp b/neo/renderer/OpenGL/RenderBackend_GL.cpp similarity index 99% rename from neo/renderer/OpenGL/gl_backend.cpp rename to neo/renderer/OpenGL/RenderBackend_GL.cpp index a3c7b7c9..53cc374c 100644 --- a/neo/renderer/OpenGL/gl_backend.cpp +++ b/neo/renderer/OpenGL/RenderBackend_GL.cpp @@ -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 "../../framework/Common_local.h" idCVar r_drawFlickerBox( "r_drawFlickerBox", "0", CVAR_RENDERER | CVAR_BOOL, "visual test for dropping frames" ); diff --git a/neo/renderer/OpenGL/gl_GraphicsAPIWrapper.cpp b/neo/renderer/OpenGL/gl_GraphicsAPIWrapper.cpp index 173dc2d2..f8bb5d5c 100644 --- a/neo/renderer/OpenGL/gl_GraphicsAPIWrapper.cpp +++ b/neo/renderer/OpenGL/gl_GraphicsAPIWrapper.cpp @@ -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" /* ==================== diff --git a/neo/renderer/tr_backend_draw.cpp b/neo/renderer/RenderBackend.cpp similarity index 99% rename from neo/renderer/tr_backend_draw.cpp rename to neo/renderer/RenderBackend.cpp index 76fba4ce..e7f97a3b 100644 --- a/neo/renderer/tr_backend_draw.cpp +++ b/neo/renderer/RenderBackend.cpp @@ -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 "Framebuffer.h" idCVar r_drawEyeColor( "r_drawEyeColor", "0", CVAR_RENDERER | CVAR_BOOL, "Draw a colored box, red = left eye, blue = right eye, grey = non-stereo" ); diff --git a/neo/renderer/tr_local.h b/neo/renderer/RenderCommon.h similarity index 99% rename from neo/renderer/tr_local.h rename to neo/renderer/RenderCommon.h index b9d682da..3d2cad57 100644 --- a/neo/renderer/tr_local.h +++ b/neo/renderer/RenderCommon.h @@ -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" diff --git a/neo/renderer/RenderEntity.cpp b/neo/renderer/RenderEntity.cpp index bdc542e9..d7d72cf2 100644 --- a/neo/renderer/RenderEntity.cpp +++ b/neo/renderer/RenderEntity.cpp @@ -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() { diff --git a/neo/renderer/RenderLog.cpp b/neo/renderer/RenderLog.cpp index 684c4d3b..ed425954 100644 --- a/neo/renderer/RenderLog.cpp +++ b/neo/renderer/RenderLog.cpp @@ -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" /* ================================================================================================ diff --git a/neo/renderer/RenderProgs.cpp b/neo/renderer/RenderProgs.cpp index 651ea89b..1c8c0f54 100644 --- a/neo/renderer/RenderProgs.cpp +++ b/neo/renderer/RenderProgs.cpp @@ -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" diff --git a/neo/renderer/RenderProgs_GLSL.cpp b/neo/renderer/RenderProgs_GLSL.cpp index b2466277..595a62c4 100644 --- a/neo/renderer/RenderProgs_GLSL.cpp +++ b/neo/renderer/RenderProgs_GLSL.cpp @@ -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" ); diff --git a/neo/renderer/RenderSystem.cpp b/neo/renderer/RenderSystem.cpp index 5dce4dcf..a5250a30 100644 --- a/neo/renderer/RenderSystem.cpp +++ b/neo/renderer/RenderSystem.cpp @@ -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; diff --git a/neo/renderer/RenderSystem_init.cpp b/neo/renderer/RenderSystem_init.cpp index 9abd45a4..67ad2573 100644 --- a/neo/renderer/RenderSystem_init.cpp +++ b/neo/renderer/RenderSystem_init.cpp @@ -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) diff --git a/neo/renderer/RenderWorld.cpp b/neo/renderer/RenderWorld.cpp index 48f8ecab..1f043ed8 100644 --- a/neo/renderer/RenderWorld.cpp +++ b/neo/renderer/RenderWorld.cpp @@ -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" /* =================== diff --git a/neo/renderer/RenderWorld_defs.cpp b/neo/renderer/RenderWorld_defs.cpp index 68dcaf73..c0871c84 100644 --- a/neo/renderer/RenderWorld_defs.cpp +++ b/neo/renderer/RenderWorld_defs.cpp @@ -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" /* ================================================================================= diff --git a/neo/renderer/RenderWorld_demo.cpp b/neo/renderer/RenderWorld_demo.cpp index 25b703f6..b6000b69 100644 --- a/neo/renderer/RenderWorld_demo.cpp +++ b/neo/renderer/RenderWorld_demo.cpp @@ -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." ); diff --git a/neo/renderer/RenderWorld_load.cpp b/neo/renderer/RenderWorld_load.cpp index 763a13c8..87bbd234 100644 --- a/neo/renderer/RenderWorld_load.cpp +++ b/neo/renderer/RenderWorld_load.cpp @@ -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" /* diff --git a/neo/renderer/RenderWorld_portals.cpp b/neo/renderer/RenderWorld_portals.cpp index 4b492dcd..b062df40 100644 --- a/neo/renderer/RenderWorld_portals.cpp +++ b/neo/renderer/RenderWorld_portals.cpp @@ -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 diff --git a/neo/renderer/ResolutionScale.cpp b/neo/renderer/ResolutionScale.cpp index e34bbe3a..2c54d155 100644 --- a/neo/renderer/ResolutionScale.cpp +++ b/neo/renderer/ResolutionScale.cpp @@ -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" diff --git a/neo/renderer/ScreenRect.cpp b/neo/renderer/ScreenRect.cpp index 157a49e5..ea0b710d 100644 --- a/neo/renderer/ScreenRect.cpp +++ b/neo/renderer/ScreenRect.cpp @@ -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" /* ========================================================================================== diff --git a/neo/renderer/VertexCache.cpp b/neo/renderer/VertexCache.cpp index 349de026..c080096e 100644 --- a/neo/renderer/VertexCache.cpp +++ b/neo/renderer/VertexCache.cpp @@ -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; diff --git a/neo/renderer/tr_backend_rendertools.cpp b/neo/renderer/tr_backend_rendertools.cpp index 7279cef0..7892c5a0 100644 --- a/neo/renderer/tr_backend_rendertools.cpp +++ b/neo/renderer/tr_backend_rendertools.cpp @@ -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 "simplex.h" // line font definition idCVar r_showCenterOfProjection( "r_showCenterOfProjection", "0", CVAR_RENDERER | CVAR_BOOL, "Draw a cross to show the center of projection" ); diff --git a/neo/renderer/tr_frontend_addlights.cpp b/neo/renderer/tr_frontend_addlights.cpp index 51f820ec..37ebccc9 100644 --- a/neo/renderer/tr_frontend_addlights.cpp +++ b/neo/renderer/tr_frontend_addlights.cpp @@ -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; diff --git a/neo/renderer/tr_frontend_addmodels.cpp b/neo/renderer/tr_frontend_addmodels.cpp index 4cbd9274..1ceaae07 100644 --- a/neo/renderer/tr_frontend_addmodels.cpp +++ b/neo/renderer/tr_frontend_addmodels.cpp @@ -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" ); diff --git a/neo/renderer/tr_frontend_deform.cpp b/neo/renderer/tr_frontend_deform.cpp index ed137581..9c44db97 100644 --- a/neo/renderer/tr_frontend_deform.cpp +++ b/neo/renderer/tr_frontend_deform.cpp @@ -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" /* diff --git a/neo/renderer/tr_frontend_guisurf.cpp b/neo/renderer/tr_frontend_guisurf.cpp index e7411945..798c916e 100644 --- a/neo/renderer/tr_frontend_guisurf.cpp +++ b/neo/renderer/tr_frontend_guisurf.cpp @@ -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" /* diff --git a/neo/renderer/tr_frontend_main.cpp b/neo/renderer/tr_frontend_main.cpp index e177c7b0..9dc95fc9 100644 --- a/neo/renderer/tr_frontend_main.cpp +++ b/neo/renderer/tr_frontend_main.cpp @@ -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" /* ========================================================================================== diff --git a/neo/renderer/tr_frontend_subview.cpp b/neo/renderer/tr_frontend_subview.cpp index 7c968d10..417b5455 100644 --- a/neo/renderer/tr_frontend_subview.cpp +++ b/neo/renderer/tr_frontend_subview.cpp @@ -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" /* diff --git a/neo/renderer/tr_trace.cpp b/neo/renderer/tr_trace.cpp index fd865b36..26527267 100644 --- a/neo/renderer/tr_trace.cpp +++ b/neo/renderer/tr_trace.cpp @@ -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" diff --git a/neo/renderer/tr_trisurf.cpp b/neo/renderer/tr_trisurf.cpp index d698d4f2..a7a7f35a 100644 --- a/neo/renderer/tr_trisurf.cpp +++ b/neo/renderer/tr_trisurf.cpp @@ -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" /* ============================================================================== diff --git a/neo/swf/SWF_Render.cpp b/neo/swf/SWF_Render.cpp index bcbe8ab5..841d4c1f 100644 --- a/neo/swf/SWF_Render.cpp +++ b/neo/swf/SWF_Render.cpp @@ -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" ); diff --git a/neo/sys/win32/win_glimp.cpp b/neo/sys/win32/win_glimp.cpp index c043f7a7..04363f99 100644 --- a/neo/sys/win32/win_glimp.cpp +++ b/neo/sys/win32/win_glimp.cpp @@ -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" diff --git a/neo/sys/win32/win_main.cpp b/neo/sys/win32/win_main.cpp index 157d1e0f..6f0ea1ec 100644 --- a/neo/sys/win32/win_main.cpp +++ b/neo/sys/win32/win_main.cpp @@ -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, "" ); diff --git a/neo/sys/win32/win_wndproc.cpp b/neo/sys/win32/win_wndproc.cpp index 7f85943f..be288896 100644 --- a/neo/sys/win32/win_wndproc.cpp +++ b/neo/sys/win32/win_wndproc.cpp @@ -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 diff --git a/neo/tools/compilers/dmap/dmap.h b/neo/tools/compilers/dmap/dmap.h index 24322f90..282ec17e 100644 --- a/neo/tools/compilers/dmap/dmap.h +++ b/neo/tools/compilers/dmap/dmap.h @@ -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 From e0ba08b3f904afff43c37524a2b900f25a4b056c Mon Sep 17 00:00:00 2001 From: Robert Beckebans Date: Sun, 3 Sep 2017 13:27:21 +0200 Subject: [PATCH 04/12] Added new GL states --- neo/renderer/GLState.h | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/neo/renderer/GLState.h b/neo/renderer/GLState.h index 7ab44926..57a2fdcd 100644 --- a/neo/renderer/GLState.h +++ b/neo/renderer/GLState.h @@ -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 From 530b3829294ee23de9e1ba0d1dca7a71466cbe02 Mon Sep 17 00:00:00 2001 From: Robert Beckebans Date: Sun, 3 Sep 2017 13:56:30 +0200 Subject: [PATCH 05/12] Merging Image code from vkneo --- neo/renderer/Image.h | 123 ++++++++++++++++++++----------- neo/renderer/Image_load.cpp | 2 +- neo/renderer/OpenGL/Image_GL.cpp | 37 +++++++++- 3 files changed, 115 insertions(+), 47 deletions(-) diff --git a/neo/renderer/Image.h b/neo/renderer/Image.h index cac6d280..112dea1a 100644 --- a/neo/renderer/Image.h +++ b/neo/renderer/Image.h @@ -104,6 +104,15 @@ enum textureFormat_t 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 @@ -140,14 +149,12 @@ public: 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 - // RB: for MSAA FBO targets - int msaaSamples; - // RB end }; /* @@ -159,15 +166,14 @@ 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; - // RB begin - msaaSamples = 0; - // RB end + }; /* @@ -242,6 +248,7 @@ class idImage public: idImage( const char* name ); + ~idImage(); const char* GetName() const { @@ -253,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 @@ -316,6 +311,27 @@ 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 @@ -348,20 +364,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 @@ -384,36 +417,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" ); @@ -489,7 +522,7 @@ public: 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 diff --git a/neo/renderer/Image_load.cpp b/neo/renderer/Image_load.cpp index ce97b99c..7e306e45 100644 --- a/neo/renderer/Image_load.cpp +++ b/neo/renderer/Image_load.cpp @@ -231,7 +231,7 @@ void idImage::GenerateImage( const byte* pic, int width, int height, textureFilt opts.width = width; opts.height = height; opts.numLevels = 0; - opts.msaaSamples = msaaSamples; + opts.samples = textureSamples_t( msaaSamples ); DeriveOpts(); // if we don't have a rendering context, just return after we diff --git a/neo/renderer/OpenGL/Image_GL.cpp b/neo/renderer/OpenGL/Image_GL.cpp index ccf16868..dd1c0979 100644 --- a/neo/renderer/OpenGL/Image_GL.cpp +++ b/neo/renderer/OpenGL/Image_GL.cpp @@ -37,6 +37,41 @@ Contains the Image implementation for OpenGL. #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(); +} + /* ======================== idImage::SubImageUpload @@ -554,7 +589,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 { From a5b5840ca784fdba2c22ba27945c45226190d1cd Mon Sep 17 00:00:00 2001 From: Robert Beckebans Date: Sun, 3 Sep 2017 23:17:44 +0200 Subject: [PATCH 06/12] Started to refactor RB_ functions into idRenderBackend. DOES NOT COMPILE --- neo/renderer/Framebuffer.cpp | 14 +- neo/renderer/GraphicsAPIWrapper.h | 78 +- neo/renderer/Image.h | 4 - neo/renderer/ImageManager.cpp | 16 +- neo/renderer/Image_load.cpp | 3 +- neo/renderer/OpenGL/RenderBackend_GL.cpp | 727 ++++++++++- neo/renderer/OpenGL/gl_GraphicsAPIWrapper.cpp | 461 +------ neo/renderer/RenderBackend.cpp | 1100 ++++++++++------- neo/renderer/RenderBackend.h | 468 +++++++ neo/renderer/RenderCommon.h | 90 +- neo/renderer/RenderSystem.cpp | 54 +- 11 files changed, 1854 insertions(+), 1161 deletions(-) create mode 100644 neo/renderer/RenderBackend.h diff --git a/neo/renderer/Framebuffer.cpp b/neo/renderer/Framebuffer.cpp index f41dd61e..bb61d136 100644 --- a/neo/renderer/Framebuffer.cpp +++ b/neo/renderer/Framebuffer.cpp @@ -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 @@ -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 ) diff --git a/neo/renderer/GraphicsAPIWrapper.h b/neo/renderer/GraphicsAPIWrapper.h index 414f8943..4067626f 100644 --- a/neo/renderer/GraphicsAPIWrapper.h +++ b/neo/renderer/GraphicsAPIWrapper.h @@ -71,76 +71,15 @@ static const int OCCLUSION_QUERY_TOO_OLD = -1; #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() +// 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 ); @@ -165,22 +104,14 @@ ID_INLINE void GL_ViewportAndScissor( const idScreenRect& 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 @@ -192,8 +123,7 @@ bool GL_CheckErrors_( const char* filename, int line ); #endif // RB end -wrapperStats_t GL_GetCurrentStats(); -void GL_ClearStats(); + #endif // !__GRAPHICSAPIWRAPPER_H__ diff --git a/neo/renderer/Image.h b/neo/renderer/Image.h index 112dea1a..4c866715 100644 --- a/neo/renderer/Image.h +++ b/neo/renderer/Image.h @@ -447,7 +447,6 @@ private: #endif }; - // 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 @@ -498,9 +497,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(); diff --git a/neo/renderer/ImageManager.cpp b/neo/renderer/ImageManager.cpp index c6b71248..25bd1dd6 100644 --- a/neo/renderer/ImageManager.cpp +++ b/neo/renderer/ImageManager.cpp @@ -742,21 +742,7 @@ void R_CombineCubeImages_f( const idCmdArgs& args ) 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; -} + /* =============== diff --git a/neo/renderer/Image_load.cpp b/neo/renderer/Image_load.cpp index 7e306e45..32aea529 100644 --- a/neo/renderer/Image_load.cpp +++ b/neo/renderer/Image_load.cpp @@ -667,7 +667,6 @@ 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!) @@ -677,7 +676,7 @@ void idImage::Bind() ActuallyLoadImage( true ); } - const int texUnit = backEnd.glState.currenttmu; + const int texUnit = tr.backend.currenttmu; // RB: added support for more types tmu_t* tmu = &backEnd.glState.tmu[texUnit]; diff --git a/neo/renderer/OpenGL/RenderBackend_GL.cpp b/neo/renderer/OpenGL/RenderBackend_GL.cpp index 53cc374c..e130dc12 100644 --- a/neo/renderer/OpenGL/RenderBackend_GL.cpp +++ b/neo/renderer/OpenGL/RenderBackend_GL.cpp @@ -31,6 +31,7 @@ If you have questions concerning this license or the applicable additional terms #include "precompiled.h" #include "../RenderCommon.h" +#include "../RenderBackend.h" #include "../../framework/Common_local.h" idCVar r_drawFlickerBox( "r_drawFlickerBox", "0", CVAR_RENDERER | CVAR_BOOL, "visual test for dropping frames" ); @@ -52,6 +53,652 @@ static GLsync renderSync[2]; void GLimp_SwapBuffers(); void RB_SetMVP( const idRenderMatrix& mvp ); + + +/* +============= +idRenderBackend::DrawElementsWithCounters +============= +*/ +void idRenderBackend::DrawElementsWithCounters( const drawSurf_t* surf ) +{ + // get vertex buffer + const vertCacheHandle_t vbHandle = surf->ambientCache; + idVertexBuffer* vertexBuffer; + if( vertexCache.CacheIsStatic( vbHandle ) ) + { + vertexBuffer = &vertexCache.staticData.vertexBuffer; + } + else + { + const uint64 frameNum = ( int )( vbHandle >> VERTCACHE_FRAME_SHIFT ) & VERTCACHE_FRAME_MASK; + if( frameNum != ( ( vertexCache.currentFrame - 1 ) & VERTCACHE_FRAME_MASK ) ) + { + idLib::Warning( "RB_DrawElementsWithCounters, vertexBuffer == NULL" ); + return; + } + vertexBuffer = &vertexCache.frameData[vertexCache.drawListNum].vertexBuffer; + } + const int vertOffset = ( int )( vbHandle >> VERTCACHE_OFFSET_SHIFT ) & VERTCACHE_OFFSET_MASK; + + // get index buffer + const vertCacheHandle_t ibHandle = surf->indexCache; + idIndexBuffer* indexBuffer; + if( vertexCache.CacheIsStatic( ibHandle ) ) + { + indexBuffer = &vertexCache.staticData.indexBuffer; + } + else + { + const uint64 frameNum = ( int )( ibHandle >> VERTCACHE_FRAME_SHIFT ) & VERTCACHE_FRAME_MASK; + if( frameNum != ( ( vertexCache.currentFrame - 1 ) & VERTCACHE_FRAME_MASK ) ) + { + idLib::Warning( "RB_DrawElementsWithCounters, indexBuffer == NULL" ); + return; + } + indexBuffer = &vertexCache.frameData[vertexCache.drawListNum].indexBuffer; + } + // RB: 64 bit fixes, changed int to GLintptr + const GLintptr indexOffset = ( GLintptr )( ibHandle >> VERTCACHE_OFFSET_SHIFT ) & VERTCACHE_OFFSET_MASK; + // RB end + + RENDERLOG_PRINTF( "Binding Buffers: %p:%i %p:%i\n", vertexBuffer, vertOffset, indexBuffer, indexOffset ); + + if( surf->jointCache ) + { + // DG: this happens all the time in the erebus1 map with blendlight.vfp, + // so don't call assert (through verify) here until it's fixed (if fixable) + // else the game crashes on linux when using debug builds + + // FIXME: fix this properly if possible? + // RB: yes but it would require an additional blend light skinned shader + //if( !verify( renderProgManager.ShaderUsesJoints() ) ) + if( !renderProgManager.ShaderUsesJoints() ) + // DG end + { + return; + } + } + else + { + if( !verify( !renderProgManager.ShaderUsesJoints() || renderProgManager.ShaderHasOptionalSkinning() ) ) + { + return; + } + } + + + if( surf->jointCache ) + { + idJointBuffer jointBuffer; + if( !vertexCache.GetJointBuffer( surf->jointCache, &jointBuffer ) ) + { + idLib::Warning( "RB_DrawElementsWithCounters, jointBuffer == NULL" ); + return; + } + assert( ( jointBuffer.GetOffset() & ( glConfig.uniformBufferOffsetAlignment - 1 ) ) == 0 ); + + // RB: 64 bit fixes, changed GLuint to GLintptr + const GLintptr ubo = reinterpret_cast< GLintptr >( jointBuffer.GetAPIObject() ); + // RB end + + glBindBufferRange( GL_UNIFORM_BUFFER, 0, ubo, jointBuffer.GetOffset(), jointBuffer.GetNumJoints() * sizeof( idJointMat ) ); + } + + renderProgManager.CommitUniforms(); + + // RB: 64 bit fixes, changed GLuint to GLintptr + if( currentIndexBuffer != ( GLintptr )indexBuffer->GetAPIObject() || !r_useStateCaching.GetBool() ) + { + glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, ( GLintptr )indexBuffer->GetAPIObject() ); + currentIndexBuffer = ( GLintptr )indexBuffer->GetAPIObject(); + } + + if( ( vertexLayout != LAYOUT_DRAW_VERT ) || ( currentVertexBuffer != ( GLintptr )vertexBuffer->GetAPIObject() ) || !r_useStateCaching.GetBool() ) + { + glBindBuffer( GL_ARRAY_BUFFER, ( GLintptr )vertexBuffer->GetAPIObject() ); + backEnd.glState.currentVertexBuffer = ( GLintptr )vertexBuffer->GetAPIObject(); + + glEnableVertexAttribArray( PC_ATTRIB_INDEX_VERTEX ); + glEnableVertexAttribArray( PC_ATTRIB_INDEX_NORMAL ); + glEnableVertexAttribArray( PC_ATTRIB_INDEX_COLOR ); + glEnableVertexAttribArray( PC_ATTRIB_INDEX_COLOR2 ); + glEnableVertexAttribArray( PC_ATTRIB_INDEX_ST ); + glEnableVertexAttribArray( PC_ATTRIB_INDEX_TANGENT ); + +#if defined(USE_GLES2) || defined(USE_GLES3) + glVertexAttribPointer( PC_ATTRIB_INDEX_VERTEX, 3, GL_FLOAT, GL_FALSE, sizeof( idDrawVert ), ( void* )( vertOffset + DRAWVERT_XYZ_OFFSET ) ); + glVertexAttribPointer( PC_ATTRIB_INDEX_NORMAL, 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof( idDrawVert ), ( void* )( vertOffset + DRAWVERT_NORMAL_OFFSET ) ); + glVertexAttribPointer( PC_ATTRIB_INDEX_COLOR, 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof( idDrawVert ), ( void* )( vertOffset + DRAWVERT_COLOR_OFFSET ) ); + glVertexAttribPointer( PC_ATTRIB_INDEX_COLOR2, 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof( idDrawVert ), ( void* )( vertOffset + DRAWVERT_COLOR2_OFFSET ) ); +#if defined(USE_ANGLE) + glVertexAttribPointer( PC_ATTRIB_INDEX_ST, 2, GL_HALF_FLOAT_OES, GL_TRUE, sizeof( idDrawVert ), ( void* )( vertOffset + DRAWVERT_ST_OFFSET ) ); +#else + glVertexAttribPointer( PC_ATTRIB_INDEX_ST, 2, GL_HALF_FLOAT, GL_TRUE, sizeof( idDrawVert ), ( void* )( vertOffset + DRAWVERT_ST_OFFSET ) ); +#endif + glVertexAttribPointer( PC_ATTRIB_INDEX_TANGENT, 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof( idDrawVert ), ( void* )( vertOffset + DRAWVERT_TANGENT_OFFSET ) ); + +#else + glVertexAttribPointer( PC_ATTRIB_INDEX_VERTEX, 3, GL_FLOAT, GL_FALSE, sizeof( idDrawVert ), ( void* )( DRAWVERT_XYZ_OFFSET ) ); + glVertexAttribPointer( PC_ATTRIB_INDEX_NORMAL, 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof( idDrawVert ), ( void* )( DRAWVERT_NORMAL_OFFSET ) ); + glVertexAttribPointer( PC_ATTRIB_INDEX_COLOR, 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof( idDrawVert ), ( void* )( DRAWVERT_COLOR_OFFSET ) ); + glVertexAttribPointer( PC_ATTRIB_INDEX_COLOR2, 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof( idDrawVert ), ( void* )( DRAWVERT_COLOR2_OFFSET ) ); + glVertexAttribPointer( PC_ATTRIB_INDEX_ST, 2, GL_HALF_FLOAT, GL_TRUE, sizeof( idDrawVert ), ( void* )( DRAWVERT_ST_OFFSET ) ); + glVertexAttribPointer( PC_ATTRIB_INDEX_TANGENT, 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof( idDrawVert ), ( void* )( DRAWVERT_TANGENT_OFFSET ) ); +#endif // #if defined(USE_GLES2) || defined(USE_GLES3) + + backEnd.glState.vertexLayout = LAYOUT_DRAW_VERT; + } + // RB end + +#if defined(USE_GLES3) //defined(USE_GLES2) + glDrawElements( GL_TRIANGLES, + r_singleTriangle.GetBool() ? 3 : surf->numIndexes, + GL_INDEX_TYPE, + ( triIndex_t* )indexOffset ); +#else + glDrawElementsBaseVertex( GL_TRIANGLES, + r_singleTriangle.GetBool() ? 3 : surf->numIndexes, + GL_INDEX_TYPE, + ( triIndex_t* )indexOffset, + vertOffset / sizeof( idDrawVert ) ); +#endif + + // RB: added stats + backEnd.pc.c_drawElements++; + backEnd.pc.c_drawIndexes += surf->numIndexes; + // RB end +} + + +/* +========================================================================================================= + +GL COMMANDS + +========================================================================================================= +*/ + +/* +================== +idRenderBackend::GL_StartFrame +================== +*/ +void idRenderBackend::GL_StartFrame() +{ + +} + +/* +================== +idRenderBackend::GL_EndFrame +================== +*/ +void idRenderBackend::GL_EndFrame() +{ + // Fix for the steam overlay not showing up while in game without Shell/Debug/Console/Menu also rendering + glColorMask( 1, 1, 1, 1 ); + + glFlush(); +} + +/* +======================== +GL_SetDefaultState + +This should initialize all GL state that any part of the entire program +may touch, including the editor. +======================== +*/ +void idRenderBackend::GL_SetDefaultState() +{ + RENDERLOG_PRINTF( "--- GL_SetDefaultState ---\n" ); + + glClearDepth( 1.0f ); + + // make sure our GL state vector is set correctly + memset( &glcontext.tmu, 0, sizeof( glcontext.tmu ) ); + currenttmu = 0; + currentVertexBuffer = 0; + currentIndexBuffer = 0; + currentFramebuffer = 0; + faceCulling = 0; + vertexLayout = LAYOUT_UNKNOWN; + polyOfsScale = 0.0f; + polyOfsBias = 0.0f; + glStateBits = 0; + + hdrAverageLuminance = 0; + hdrMaxLuminance = 0; + hdrTime = 0; + hdrKey = 0; + + 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 +} + +/* +==================== +idRenderBackend::GL_State + +This routine is responsible for setting the most commonly changed state +==================== +*/ +void idRenderBackend::GL_State( uint64 stateBits, bool forceGlState ) +{ + uint64 diff = stateBits ^ 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( polyOfsScale, 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 ); + } + + glStateBits = stateBits; +} + +/* +==================== +idRenderBackend::SelectTexture +==================== +*/ +void idRenderBackend::GL_SelectTexture( int unit ) +{ + if( currenttmu == unit ) + { + return; + } + + if( unit < 0 || unit >= glConfig.maxTextureImageUnits ) + { + common->Warning( "GL_SelectTexture: unit = %i", unit ); + return; + } + + RENDERLOG_PRINTF( "GL_SelectTexture( %i );\n", unit ); + + currenttmu = unit; +} + /* ============================================================================ @@ -62,10 +709,10 @@ RENDER BACK END THREAD FUNCTIONS /* ============= -RB_DrawFlickerBox +idRenderBackend::DrawFlickerBox ============= */ -static void RB_DrawFlickerBox() +void idRenderBackend::DrawFlickerBox() { if( !r_drawFlickerBox.GetBool() ) { @@ -85,10 +732,10 @@ static void RB_DrawFlickerBox() /* ============= -RB_SetBuffer +idRenderBackend::SetBuffer ============= */ -static void RB_SetBuffer( const void* data ) +void idRenderBackend::SetBuffer( const void* data ) { // see which draw buffer we want to render the frame to @@ -130,7 +777,7 @@ GL_BlockingSwapBuffers We want to exit this with the GPU idle, right at vsync ============= */ -const void GL_BlockingSwapBuffers() +void idRenderBackend::BlockingSwapBuffers() { RENDERLOG_PRINTF( "***************** GL_BlockingSwapBuffers *****************\n\n\n" ); @@ -211,6 +858,32 @@ const void GL_BlockingSwapBuffers() prevBlockTime = exitBlockTime; } +/* +============= +idRenderBackend::idRenderBackend +============= +*/ +idRenderBackend::idRenderBackend() +{ + memset( gammaTable, 0, sizeof( gammaTable ) ); + + glcontext.bAnisotropicFilterAvailable = false; + glcontext.bTextureLODBiasAvailable = false; + + memset( glcontext.tmu, 0, sizeof( glcontext.tmu ) ); + memset( glcontext.stencilOperations, 0, sizeof( glcontext.stencilOperations ) ); +} + +/* +============= +idRenderBackend::~idRenderBackend +============= +*/ +idRenderBackend::~idRenderBackend() +{ + +} + /* ==================== R_MakeStereoRenderImage @@ -228,12 +901,12 @@ static void R_MakeStereoRenderImage( idImage* image ) /* ==================== -RB_StereoRenderExecuteBackEndCommands +idRenderBackend::StereoRenderExecuteBackEndCommands Renders the draw list twice, with slight modifications for left eye / right eye ==================== */ -void RB_StereoRenderExecuteBackEndCommands( const emptyCommand_t* const allCmds ) +void idRenderBackend::StereoRenderExecuteBackEndCommands( const emptyCommand_t* const allCmds ) { uint64 backEndStartTime = Sys_Microseconds(); @@ -309,7 +982,7 @@ void RB_StereoRenderExecuteBackEndCommands( const emptyCommand_t* const allCmds } break; case RC_SET_BUFFER: - RB_SetBuffer( cmds ); + SetBuffer( cmds ); break; case RC_COPY_RENDER: RB_CopyRender( cmds ); @@ -376,16 +1049,16 @@ void RB_StereoRenderExecuteBackEndCommands( const emptyCommand_t* const allCmds stereoRenderImages[1]->Bind(); GL_SelectTexture( 1 ); stereoRenderImages[0]->Bind(); - RB_DrawElementsWithCounters( &backEnd.unitSquareSurface ); + DrawElementsWithCounters( &unitSquareSurface ); glDrawBuffer( GL_BACK_LEFT ); GL_SelectTexture( 1 ); stereoRenderImages[1]->Bind(); GL_SelectTexture( 0 ); stereoRenderImages[0]->Bind(); - RB_DrawElementsWithCounters( &backEnd.unitSquareSurface ); - + RB_DrawElementsWithCounters( &unitSquareSurface ); break; + case STEREO3D_HDMI_720: // HDMI 720P 3D GL_SelectTexture( 0 ); @@ -393,19 +1066,20 @@ void RB_StereoRenderExecuteBackEndCommands( const emptyCommand_t* const allCmds GL_SelectTexture( 1 ); stereoRenderImages[0]->Bind(); GL_ViewportAndScissor( 0, 0, 1280, 720 ); - RB_DrawElementsWithCounters( &backEnd.unitSquareSurface ); + DrawElementsWithCounters( &unitSquareSurface ); GL_SelectTexture( 0 ); stereoRenderImages[0]->Bind(); GL_SelectTexture( 1 ); stereoRenderImages[1]->Bind(); GL_ViewportAndScissor( 0, 750, 1280, 720 ); - RB_DrawElementsWithCounters( &backEnd.unitSquareSurface ); + DrawElementsWithCounters( &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() ) @@ -443,7 +1117,7 @@ void RB_StereoRenderExecuteBackEndCommands( const emptyCommand_t* const allCmds 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 ); + DrawElementsWithCounters( &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 @@ -458,9 +1132,10 @@ void RB_StereoRenderExecuteBackEndCommands( const emptyCommand_t* const allCmds 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 ); + DrawElementsWithCounters( &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: @@ -469,14 +1144,14 @@ void RB_StereoRenderExecuteBackEndCommands( const emptyCommand_t* const allCmds GL_SelectTexture( 1 ); stereoRenderImages[1]->Bind(); GL_ViewportAndScissor( 0, 0, renderSystem->GetWidth(), renderSystem->GetHeight() ); - RB_DrawElementsWithCounters( &backEnd.unitSquareSurface ); + DrawElementsWithCounters( &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 ); + DrawElementsWithCounters( &unitSquareSurface ); break; case STEREO3D_TOP_AND_BOTTOM_COMPRESSED: @@ -485,14 +1160,14 @@ void RB_StereoRenderExecuteBackEndCommands( const emptyCommand_t* const allCmds GL_SelectTexture( 0 ); stereoRenderImages[1]->Bind(); GL_ViewportAndScissor( 0, 0, renderSystem->GetWidth(), renderSystem->GetHeight() ); - RB_DrawElementsWithCounters( &backEnd.unitSquareSurface ); + DrawElementsWithCounters( &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 ); + DrawElementsWithCounters( &unitSquareSurface ); break; case STEREO3D_INTERLACED: @@ -509,7 +1184,7 @@ void RB_StereoRenderExecuteBackEndCommands( const emptyCommand_t* const allCmds GL_ViewportAndScissor( 0, 0, renderSystem->GetWidth(), renderSystem->GetHeight() * 2 ); renderProgManager.BindShader_StereoInterlace(); - RB_DrawElementsWithCounters( &backEnd.unitSquareSurface ); + RB_DrawElementsWithCounters( &unitSquareSurface ); GL_SelectTexture( 0 ); glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR ); @@ -523,7 +1198,7 @@ void RB_StereoRenderExecuteBackEndCommands( const emptyCommand_t* const allCmds } // debug tool - RB_DrawFlickerBox(); + DrawFlickerBox(); // make sure the drawing is actually started glFlush(); @@ -532,7 +1207,7 @@ void RB_StereoRenderExecuteBackEndCommands( const emptyCommand_t* const allCmds // stop rendering on this thread uint64 backEndFinishTime = Sys_Microseconds(); - backEnd.pc.totalMicroSec = backEndFinishTime - backEndStartTime; + pc.totalMicroSec = backEndFinishTime - backEndStartTime; } /* @@ -543,7 +1218,7 @@ This function will be called syncronously if running without smp extensions, or asyncronously by another thread. ==================== */ -void RB_ExecuteBackEndCommands( const emptyCommand_t* cmds ) +void idRenderBackend::ExecuteBackEndCommands( const emptyCommand_t* cmds ) { // r_debugRenderToTexture int c_draw3d = 0; @@ -562,7 +1237,7 @@ void RB_ExecuteBackEndCommands( const emptyCommand_t* cmds ) if( renderSystem->GetStereo3DMode() != STEREO3D_OFF ) { - RB_StereoRenderExecuteBackEndCommands( cmds ); + StereoRenderExecuteBackEndCommands( cmds ); renderLog.EndFrame(); return; } @@ -612,7 +1287,7 @@ void RB_ExecuteBackEndCommands( const emptyCommand_t* cmds ) } } - RB_DrawFlickerBox(); + DrawFlickerBox(); // Fix for the steam overlay not showing up while in game without Shell/Debug/Console/Menu also rendering glColorMask( 1, 1, 1, 1 ); @@ -621,7 +1296,7 @@ void RB_ExecuteBackEndCommands( const emptyCommand_t* cmds ) // stop rendering on this thread uint64 backEndFinishTime = Sys_Microseconds(); - backEnd.pc.totalMicroSec = backEndFinishTime - backEndStartTime; + pc.totalMicroSec = backEndFinishTime - backEndStartTime; if( r_debugRenderToTexture.GetInteger() == 1 ) { diff --git a/neo/renderer/OpenGL/gl_GraphicsAPIWrapper.cpp b/neo/renderer/OpenGL/gl_GraphicsAPIWrapper.cpp index f8bb5d5c..e098f17a 100644 --- a/neo/renderer/OpenGL/gl_GraphicsAPIWrapper.cpp +++ b/neo/renderer/OpenGL/gl_GraphicsAPIWrapper.cpp @@ -32,28 +32,7 @@ If you have questions concerning this license or the applicable additional terms #include "../RenderCommon.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; -} + /* ==================== @@ -65,7 +44,7 @@ rendered is a mirored view. */ void GL_Cull( int cullType ) { - if( backEnd.glState.faceCulling == cullType ) + if( tr.backend.faceCulling == cullType ) { return; } @@ -76,7 +55,7 @@ void GL_Cull( int cullType ) } else { - if( backEnd.glState.faceCulling == CT_TWO_SIDED ) + if( tr.backend.faceCulling == CT_TWO_SIDED ) { glEnable( GL_CULL_FACE ); } @@ -105,7 +84,7 @@ void GL_Cull( int cullType ) } } - backEnd.glState.faceCulling = cullType; + tr.backend.faceCulling = cullType; } /* @@ -135,9 +114,9 @@ GL_PolygonOffset */ void GL_PolygonOffset( float scale, float bias ) { - backEnd.glState.polyOfsScale = scale; - backEnd.glState.polyOfsBias = bias; - if( backEnd.glState.glStateBits & GLS_POLYGON_OFFSET ) + tr.backend.polyOfsScale = scale; + tr.backend.polyOfsBias = bias; + if( tr.backend.glStateBits & GLS_POLYGON_OFFSET ) { glPolygonOffset( scale, bias ); } @@ -211,15 +190,7 @@ void GL_Color( float* color ) */ // 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 /* @@ -287,424 +258,8 @@ void GL_Clear( bool color, bool depth, bool stencil, byte stencilValue, float r, // 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; -} /* ================= @@ -713,7 +268,7 @@ GL_GetCurrentState */ uint64 GL_GetCurrentState() { - return backEnd.glState.glStateBits; + return tr.backend.glStateBits; } /* diff --git a/neo/renderer/RenderBackend.cpp b/neo/renderer/RenderBackend.cpp index ba3f3ae4..6de8157e 100644 --- a/neo/renderer/RenderBackend.cpp +++ b/neo/renderer/RenderBackend.cpp @@ -44,7 +44,6 @@ idCVar r_useLightStencilSelect( "r_useLightStencilSelect", "0", CVAR_RENDERER | extern idCVar stereoRender_swapEyes; -backEndState_t backEnd; /* ================ @@ -79,6 +78,305 @@ static ID_INLINE void SetFragmentParm( renderParm_t rp, const float* value ) renderProgManager.SetUniformValue( rp, value ); } +/* +==================== +PrintState +==================== +*/ +#if 0 +void PrintState( uint64 stateBits, uint64* stencilBits ) +{ + if( renderLog.Active() == 0 ) + { + return; + } + + renderLog.OpenBlock( "GL_State" ); + + // culling + renderLog.Printf( "Culling: " ); + switch( stateBits & GLS_CULL_BITS ) + { + case GLS_CULL_FRONTSIDED: + renderLog.Printf_NoIndent( "FRONTSIDED -> BACK" ); + break; + case GLS_CULL_BACKSIDED: + renderLog.Printf_NoIndent( "BACKSIDED -> FRONT" ); + break; + case GLS_CULL_TWOSIDED: + renderLog.Printf_NoIndent( "TWOSIDED" ); + break; + default: + renderLog.Printf_NoIndent( "NA" ); + break; + } + renderLog.Printf_NoIndent( "\n" ); + + // polygon mode + renderLog.Printf( "PolygonMode: %s\n", ( stateBits & GLS_POLYMODE_LINE ) ? "LINE" : "FILL" ); + + // color mask + renderLog.Printf( "ColorMask: " ); + renderLog.Printf_NoIndent( ( stateBits & GLS_REDMASK ) ? "_" : "R" ); + renderLog.Printf_NoIndent( ( stateBits & GLS_GREENMASK ) ? "_" : "G" ); + renderLog.Printf_NoIndent( ( stateBits & GLS_BLUEMASK ) ? "_" : "B" ); + renderLog.Printf_NoIndent( ( stateBits & GLS_ALPHAMASK ) ? "_" : "A" ); + renderLog.Printf_NoIndent( "\n" ); + + // blend + renderLog.Printf( "Blend: src=" ); + switch( stateBits & GLS_SRCBLEND_BITS ) + { + case GLS_SRCBLEND_ZERO: + renderLog.Printf_NoIndent( "ZERO" ); + break; + case GLS_SRCBLEND_ONE: + renderLog.Printf_NoIndent( "ONE" ); + break; + case GLS_SRCBLEND_DST_COLOR: + renderLog.Printf_NoIndent( "DST_COLOR" ); + break; + case GLS_SRCBLEND_ONE_MINUS_DST_COLOR: + renderLog.Printf_NoIndent( "ONE_MINUS_DST_COLOR" ); + break; + case GLS_SRCBLEND_SRC_ALPHA: + renderLog.Printf_NoIndent( "SRC_ALPHA" ); + break; + case GLS_SRCBLEND_ONE_MINUS_SRC_ALPHA: + renderLog.Printf_NoIndent( "ONE_MINUS_SRC_ALPHA" ); + break; + case GLS_SRCBLEND_DST_ALPHA: + renderLog.Printf_NoIndent( "DST_ALPHA" ); + break; + case GLS_SRCBLEND_ONE_MINUS_DST_ALPHA: + renderLog.Printf_NoIndent( "ONE_MINUS_DST_ALPHA" ); + break; + default: + renderLog.Printf_NoIndent( "NA" ); + break; + } + renderLog.Printf_NoIndent( ", dst=" ); + switch( stateBits & GLS_DSTBLEND_BITS ) + { + case GLS_DSTBLEND_ZERO: + renderLog.Printf_NoIndent( "ZERO" ); + break; + case GLS_DSTBLEND_ONE: + renderLog.Printf_NoIndent( "ONE" ); + break; + case GLS_DSTBLEND_SRC_COLOR: + renderLog.Printf_NoIndent( "SRC_COLOR" ); + break; + case GLS_DSTBLEND_ONE_MINUS_SRC_COLOR: + renderLog.Printf_NoIndent( "ONE_MINUS_SRC_COLOR" ); + break; + case GLS_DSTBLEND_SRC_ALPHA: + renderLog.Printf_NoIndent( "SRC_ALPHA" ); + break; + case GLS_DSTBLEND_ONE_MINUS_SRC_ALPHA: + renderLog.Printf_NoIndent( "ONE_MINUS_SRC_ALPHA" ); + break; + case GLS_DSTBLEND_DST_ALPHA: + renderLog.Printf_NoIndent( "DST_ALPHA" ); + break; + case GLS_DSTBLEND_ONE_MINUS_DST_ALPHA: + renderLog.Printf_NoIndent( "ONE_MINUS_DST_ALPHA" ); + break; + default: + renderLog.Printf_NoIndent( "NA" ); + } + renderLog.Printf_NoIndent( "\n" ); + + // depth func + renderLog.Printf( "DepthFunc: " ); + switch( stateBits & GLS_DEPTHFUNC_BITS ) + { + case GLS_DEPTHFUNC_EQUAL: + renderLog.Printf_NoIndent( "EQUAL" ); + break; + case GLS_DEPTHFUNC_ALWAYS: + renderLog.Printf_NoIndent( "ALWAYS" ); + break; + case GLS_DEPTHFUNC_LESS: + renderLog.Printf_NoIndent( "LEQUAL" ); + break; + case GLS_DEPTHFUNC_GREATER: + renderLog.Printf_NoIndent( "GEQUAL" ); + break; + default: + renderLog.Printf_NoIndent( "NA" ); + break; + } + renderLog.Printf_NoIndent( "\n" ); + + // depth mask + renderLog.Printf( "DepthWrite: %s\n", ( stateBits & GLS_DEPTHMASK ) ? "FALSE" : "TRUE" ); + + renderLog.Printf( "DepthBounds: %s\n", ( stateBits & GLS_DEPTH_TEST_MASK ) ? "TRUE" : "FALSE" ); + + // depth bias + renderLog.Printf( "DepthBias: %s\n", ( stateBits & GLS_POLYGON_OFFSET ) ? "TRUE" : "FALSE" ); + + // stencil + auto printStencil = [&]( stencilFace_t face, uint64 bits, uint64 mask, uint64 ref ) + { + renderLog.Printf( "Stencil: %s, ", ( bits & ( GLS_STENCIL_FUNC_BITS | GLS_STENCIL_OP_BITS ) ) ? "ON" : "OFF" ); + renderLog.Printf_NoIndent( "Face=" ); + switch( face ) + { + case STENCIL_FACE_FRONT: + renderLog.Printf_NoIndent( "FRONT" ); + break; + case STENCIL_FACE_BACK: + renderLog.Printf_NoIndent( "BACK" ); + break; + default: + renderLog.Printf_NoIndent( "BOTH" ); + break; + } + renderLog.Printf_NoIndent( ", Func=" ); + switch( bits & GLS_STENCIL_FUNC_BITS ) + { + case GLS_STENCIL_FUNC_NEVER: + renderLog.Printf_NoIndent( "NEVER" ); + break; + case GLS_STENCIL_FUNC_LESS: + renderLog.Printf_NoIndent( "LESS" ); + break; + case GLS_STENCIL_FUNC_EQUAL: + renderLog.Printf_NoIndent( "EQUAL" ); + break; + case GLS_STENCIL_FUNC_LEQUAL: + renderLog.Printf_NoIndent( "LEQUAL" ); + break; + case GLS_STENCIL_FUNC_GREATER: + renderLog.Printf_NoIndent( "GREATER" ); + break; + case GLS_STENCIL_FUNC_NOTEQUAL: + renderLog.Printf_NoIndent( "NOTEQUAL" ); + break; + case GLS_STENCIL_FUNC_GEQUAL: + renderLog.Printf_NoIndent( "GEQUAL" ); + break; + case GLS_STENCIL_FUNC_ALWAYS: + renderLog.Printf_NoIndent( "ALWAYS" ); + break; + default: + renderLog.Printf_NoIndent( "NA" ); + break; + } + renderLog.Printf_NoIndent( ", OpFail=" ); + switch( bits & GLS_STENCIL_OP_FAIL_BITS ) + { + case GLS_STENCIL_OP_FAIL_KEEP: + renderLog.Printf_NoIndent( "KEEP" ); + break; + case GLS_STENCIL_OP_FAIL_ZERO: + renderLog.Printf_NoIndent( "ZERO" ); + break; + case GLS_STENCIL_OP_FAIL_REPLACE: + renderLog.Printf_NoIndent( "REPLACE" ); + break; + case GLS_STENCIL_OP_FAIL_INCR: + renderLog.Printf_NoIndent( "INCR" ); + break; + case GLS_STENCIL_OP_FAIL_DECR: + renderLog.Printf_NoIndent( "DECR" ); + break; + case GLS_STENCIL_OP_FAIL_INVERT: + renderLog.Printf_NoIndent( "INVERT" ); + break; + case GLS_STENCIL_OP_FAIL_INCR_WRAP: + renderLog.Printf_NoIndent( "INCR_WRAP" ); + break; + case GLS_STENCIL_OP_FAIL_DECR_WRAP: + renderLog.Printf_NoIndent( "DECR_WRAP" ); + break; + default: + renderLog.Printf_NoIndent( "NA" ); + break; + } + renderLog.Printf_NoIndent( ", ZFail=" ); + switch( bits & GLS_STENCIL_OP_ZFAIL_BITS ) + { + case GLS_STENCIL_OP_ZFAIL_KEEP: + renderLog.Printf_NoIndent( "KEEP" ); + break; + case GLS_STENCIL_OP_ZFAIL_ZERO: + renderLog.Printf_NoIndent( "ZERO" ); + break; + case GLS_STENCIL_OP_ZFAIL_REPLACE: + renderLog.Printf_NoIndent( "REPLACE" ); + break; + case GLS_STENCIL_OP_ZFAIL_INCR: + renderLog.Printf_NoIndent( "INCR" ); + break; + case GLS_STENCIL_OP_ZFAIL_DECR: + renderLog.Printf_NoIndent( "DECR" ); + break; + case GLS_STENCIL_OP_ZFAIL_INVERT: + renderLog.Printf_NoIndent( "INVERT" ); + break; + case GLS_STENCIL_OP_ZFAIL_INCR_WRAP: + renderLog.Printf_NoIndent( "INCR_WRAP" ); + break; + case GLS_STENCIL_OP_ZFAIL_DECR_WRAP: + renderLog.Printf_NoIndent( "DECR_WRAP" ); + break; + default: + renderLog.Printf_NoIndent( "NA" ); + break; + } + renderLog.Printf_NoIndent( ", OpPass=" ); + switch( bits & GLS_STENCIL_OP_PASS_BITS ) + { + case GLS_STENCIL_OP_PASS_KEEP: + renderLog.Printf_NoIndent( "KEEP" ); + break; + case GLS_STENCIL_OP_PASS_ZERO: + renderLog.Printf_NoIndent( "ZERO" ); + break; + case GLS_STENCIL_OP_PASS_REPLACE: + renderLog.Printf_NoIndent( "REPLACE" ); + break; + case GLS_STENCIL_OP_PASS_INCR: + renderLog.Printf_NoIndent( "INCR" ); + break; + case GLS_STENCIL_OP_PASS_DECR: + renderLog.Printf_NoIndent( "DECR" ); + break; + case GLS_STENCIL_OP_PASS_INVERT: + renderLog.Printf_NoIndent( "INVERT" ); + break; + case GLS_STENCIL_OP_PASS_INCR_WRAP: + renderLog.Printf_NoIndent( "INCR_WRAP" ); + break; + case GLS_STENCIL_OP_PASS_DECR_WRAP: + renderLog.Printf_NoIndent( "DECR_WRAP" ); + break; + default: + renderLog.Printf_NoIndent( "NA" ); + break; + } + renderLog.Printf_NoIndent( ", mask=%llu, ref=%llu\n", mask, ref ); + }; + + uint32 mask = uint32( ( stateBits & GLS_STENCIL_FUNC_MASK_BITS ) >> GLS_STENCIL_FUNC_MASK_SHIFT ); + uint32 ref = uint32( ( stateBits & GLS_STENCIL_FUNC_REF_BITS ) >> GLS_STENCIL_FUNC_REF_SHIFT ); + if( stateBits & GLS_SEPARATE_STENCIL ) + { + printStencil( STENCIL_FACE_FRONT, stencilBits[ 0 ], mask, ref ); + printStencil( STENCIL_FACE_BACK, stencilBits[ 1 ], mask, ref ); + } + else + { + printStencil( STENCIL_FACE_NUM, stateBits, mask, ref ); + } + + renderLog.CloseBlock(); +} +#endif + /* ================ RB_SetMVP @@ -130,160 +428,7 @@ void RB_SetVertexColorParms( stageVertexColor_t svc ) } } -/* -================ -RB_DrawElementsWithCounters -================ -*/ -void RB_DrawElementsWithCounters( const drawSurf_t* surf ) -{ - // get vertex buffer - const vertCacheHandle_t vbHandle = surf->ambientCache; - idVertexBuffer* vertexBuffer; - if( vertexCache.CacheIsStatic( vbHandle ) ) - { - vertexBuffer = &vertexCache.staticData.vertexBuffer; - } - else - { - const uint64 frameNum = ( int )( vbHandle >> VERTCACHE_FRAME_SHIFT ) & VERTCACHE_FRAME_MASK; - if( frameNum != ( ( vertexCache.currentFrame - 1 ) & VERTCACHE_FRAME_MASK ) ) - { - idLib::Warning( "RB_DrawElementsWithCounters, vertexBuffer == NULL" ); - return; - } - vertexBuffer = &vertexCache.frameData[vertexCache.drawListNum].vertexBuffer; - } - const int vertOffset = ( int )( vbHandle >> VERTCACHE_OFFSET_SHIFT ) & VERTCACHE_OFFSET_MASK; - - // get index buffer - const vertCacheHandle_t ibHandle = surf->indexCache; - idIndexBuffer* indexBuffer; - if( vertexCache.CacheIsStatic( ibHandle ) ) - { - indexBuffer = &vertexCache.staticData.indexBuffer; - } - else - { - const uint64 frameNum = ( int )( ibHandle >> VERTCACHE_FRAME_SHIFT ) & VERTCACHE_FRAME_MASK; - if( frameNum != ( ( vertexCache.currentFrame - 1 ) & VERTCACHE_FRAME_MASK ) ) - { - idLib::Warning( "RB_DrawElementsWithCounters, indexBuffer == NULL" ); - return; - } - indexBuffer = &vertexCache.frameData[vertexCache.drawListNum].indexBuffer; - } - // RB: 64 bit fixes, changed int to GLintptr - const GLintptr indexOffset = ( GLintptr )( ibHandle >> VERTCACHE_OFFSET_SHIFT ) & VERTCACHE_OFFSET_MASK; - // RB end - - RENDERLOG_PRINTF( "Binding Buffers: %p:%i %p:%i\n", vertexBuffer, vertOffset, indexBuffer, indexOffset ); - - if( surf->jointCache ) - { - // DG: this happens all the time in the erebus1 map with blendlight.vfp, - // so don't call assert (through verify) here until it's fixed (if fixable) - // else the game crashes on linux when using debug builds - - // FIXME: fix this properly if possible? - // RB: yes but it would require an additional blend light skinned shader - //if( !verify( renderProgManager.ShaderUsesJoints() ) ) - if( !renderProgManager.ShaderUsesJoints() ) - // DG end - { - return; - } - } - else - { - if( !verify( !renderProgManager.ShaderUsesJoints() || renderProgManager.ShaderHasOptionalSkinning() ) ) - { - return; - } - } - - - if( surf->jointCache ) - { - idJointBuffer jointBuffer; - if( !vertexCache.GetJointBuffer( surf->jointCache, &jointBuffer ) ) - { - idLib::Warning( "RB_DrawElementsWithCounters, jointBuffer == NULL" ); - return; - } - assert( ( jointBuffer.GetOffset() & ( glConfig.uniformBufferOffsetAlignment - 1 ) ) == 0 ); - - // RB: 64 bit fixes, changed GLuint to GLintptr - const GLintptr ubo = reinterpret_cast< GLintptr >( jointBuffer.GetAPIObject() ); - // RB end - - glBindBufferRange( GL_UNIFORM_BUFFER, 0, ubo, jointBuffer.GetOffset(), jointBuffer.GetNumJoints() * sizeof( idJointMat ) ); - } - - renderProgManager.CommitUniforms(); - - // RB: 64 bit fixes, changed GLuint to GLintptr - if( backEnd.glState.currentIndexBuffer != ( GLintptr )indexBuffer->GetAPIObject() || !r_useStateCaching.GetBool() ) - { - glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, ( GLintptr )indexBuffer->GetAPIObject() ); - backEnd.glState.currentIndexBuffer = ( GLintptr )indexBuffer->GetAPIObject(); - } - - if( ( backEnd.glState.vertexLayout != LAYOUT_DRAW_VERT ) || ( backEnd.glState.currentVertexBuffer != ( GLintptr )vertexBuffer->GetAPIObject() ) || !r_useStateCaching.GetBool() ) - { - glBindBuffer( GL_ARRAY_BUFFER, ( GLintptr )vertexBuffer->GetAPIObject() ); - backEnd.glState.currentVertexBuffer = ( GLintptr )vertexBuffer->GetAPIObject(); - - glEnableVertexAttribArray( PC_ATTRIB_INDEX_VERTEX ); - glEnableVertexAttribArray( PC_ATTRIB_INDEX_NORMAL ); - glEnableVertexAttribArray( PC_ATTRIB_INDEX_COLOR ); - glEnableVertexAttribArray( PC_ATTRIB_INDEX_COLOR2 ); - glEnableVertexAttribArray( PC_ATTRIB_INDEX_ST ); - glEnableVertexAttribArray( PC_ATTRIB_INDEX_TANGENT ); - -#if defined(USE_GLES2) || defined(USE_GLES3) - glVertexAttribPointer( PC_ATTRIB_INDEX_VERTEX, 3, GL_FLOAT, GL_FALSE, sizeof( idDrawVert ), ( void* )( vertOffset + DRAWVERT_XYZ_OFFSET ) ); - glVertexAttribPointer( PC_ATTRIB_INDEX_NORMAL, 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof( idDrawVert ), ( void* )( vertOffset + DRAWVERT_NORMAL_OFFSET ) ); - glVertexAttribPointer( PC_ATTRIB_INDEX_COLOR, 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof( idDrawVert ), ( void* )( vertOffset + DRAWVERT_COLOR_OFFSET ) ); - glVertexAttribPointer( PC_ATTRIB_INDEX_COLOR2, 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof( idDrawVert ), ( void* )( vertOffset + DRAWVERT_COLOR2_OFFSET ) ); -#if defined(USE_ANGLE) - glVertexAttribPointer( PC_ATTRIB_INDEX_ST, 2, GL_HALF_FLOAT_OES, GL_TRUE, sizeof( idDrawVert ), ( void* )( vertOffset + DRAWVERT_ST_OFFSET ) ); -#else - glVertexAttribPointer( PC_ATTRIB_INDEX_ST, 2, GL_HALF_FLOAT, GL_TRUE, sizeof( idDrawVert ), ( void* )( vertOffset + DRAWVERT_ST_OFFSET ) ); -#endif - glVertexAttribPointer( PC_ATTRIB_INDEX_TANGENT, 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof( idDrawVert ), ( void* )( vertOffset + DRAWVERT_TANGENT_OFFSET ) ); - -#else - glVertexAttribPointer( PC_ATTRIB_INDEX_VERTEX, 3, GL_FLOAT, GL_FALSE, sizeof( idDrawVert ), ( void* )( DRAWVERT_XYZ_OFFSET ) ); - glVertexAttribPointer( PC_ATTRIB_INDEX_NORMAL, 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof( idDrawVert ), ( void* )( DRAWVERT_NORMAL_OFFSET ) ); - glVertexAttribPointer( PC_ATTRIB_INDEX_COLOR, 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof( idDrawVert ), ( void* )( DRAWVERT_COLOR_OFFSET ) ); - glVertexAttribPointer( PC_ATTRIB_INDEX_COLOR2, 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof( idDrawVert ), ( void* )( DRAWVERT_COLOR2_OFFSET ) ); - glVertexAttribPointer( PC_ATTRIB_INDEX_ST, 2, GL_HALF_FLOAT, GL_TRUE, sizeof( idDrawVert ), ( void* )( DRAWVERT_ST_OFFSET ) ); - glVertexAttribPointer( PC_ATTRIB_INDEX_TANGENT, 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof( idDrawVert ), ( void* )( DRAWVERT_TANGENT_OFFSET ) ); -#endif // #if defined(USE_GLES2) || defined(USE_GLES3) - - backEnd.glState.vertexLayout = LAYOUT_DRAW_VERT; - } - // RB end - -#if defined(USE_GLES3) //defined(USE_GLES2) - glDrawElements( GL_TRIANGLES, - r_singleTriangle.GetBool() ? 3 : surf->numIndexes, - GL_INDEX_TYPE, - ( triIndex_t* )indexOffset ); -#else - glDrawElementsBaseVertex( GL_TRIANGLES, - r_singleTriangle.GetBool() ? 3 : surf->numIndexes, - GL_INDEX_TYPE, - ( triIndex_t* )indexOffset, - vertOffset / sizeof( idDrawVert ) ); -#endif - - // RB: added stats - backEnd.pc.c_drawElements++; - backEnd.pc.c_drawIndexes += surf->numIndexes; - // RB end -} + /* ====================== @@ -404,12 +549,12 @@ static void RB_BakeTextureMatrixIntoTexgen( idPlane lightProject[3], const float /* ====================== -RB_BindVariableStageImage +idRenderBackend::BindVariableStageImage Handles generating a cinematic frame if needed ====================== */ -static void RB_BindVariableStageImage( const textureStage_t* texture, const float* shaderRegisters ) +void idRenderBackend::BindVariableStageImage( const textureStage_t* texture, const float* shaderRegisters ) { if( texture->cinematic ) { @@ -424,7 +569,7 @@ static void RB_BindVariableStageImage( const textureStage_t* texture, const floa // offset time by shaderParm[7] (FIXME: make the time offset a parameter of the shader?) // We make no attempt to optimize for multiple identical cinematics being in view, or // for cinematics going at a lower framerate than the renderer. - cin = texture->cinematic->ImageForTime( backEnd.viewDef->renderView.time[0] + idMath::Ftoi( 1000.0f * backEnd.viewDef->renderView.shaderParms[11] ) ); + cin = texture->cinematic->ImageForTime( viewDef->renderView.time[0] + idMath::Ftoi( 1000.0f * viewDef->renderView.shaderParms[11] ) ); if( cin.imageY != NULL ) { GL_SelectTexture( 0 ); @@ -473,10 +618,10 @@ static void RB_BindVariableStageImage( const textureStage_t* texture, const floa /* ================ -RB_PrepareStageTexturing +idRenderBackend::PrepareStageTexturing ================ */ -static void RB_PrepareStageTexturing( const shaderStage_t* pStage, const drawSurf_t* surf ) +void idRenderBackend::PrepareStageTexturing( const shaderStage_t* pStage, const drawSurf_t* surf ) { float useTexGenParm[4] = { 0.0f, 0.0f, 0.0f, 0.0f }; @@ -539,7 +684,7 @@ static void RB_PrepareStageTexturing( const shaderStage_t* pStage, const drawSu { // very ad-hoc "wobble" transform float s, c; - idMath::SinCos( wobbleSpeed * backEnd.viewDef->renderView.time[0] * 0.001f, s, c ); + idMath::SinCos( wobbleSpeed * viewDef->renderView.time[0] * 0.001f, s, c ); float ws, wc; idMath::SinCos( wobbleDegrees, ws, wc ); @@ -562,7 +707,7 @@ static void RB_PrepareStageTexturing( const shaderStage_t* pStage, const drawSu // add the rotate float rs, rc; - idMath::SinCos( rotateSpeed * backEnd.viewDef->renderView.time[0] * 0.001f, rs, rc ); + idMath::SinCos( rotateSpeed * viewDef->renderView.time[0] * 0.001f, rs, rc ); float transform[12]; transform[0 * 4 + 0] = axis[0][0] * rc + axis[1][0] * rs; @@ -593,7 +738,7 @@ static void RB_PrepareStageTexturing( const shaderStage_t* pStage, const drawSu useTexGenParm[3] = 1.0f; float mat[16]; - R_MatrixMultiply( surf->space->modelViewMatrix, backEnd.viewDef->projectionMatrix, mat ); + R_MatrixMultiply( surf->space->modelViewMatrix, viewDef->projectionMatrix, mat ); RENDERLOG_PRINTF( "TexGen : %s\n", ( pStage->texture.texgen == TG_SCREEN ) ? "TG_SCREEN" : "TG_SCREEN2" ); renderLog.Indent(); @@ -642,12 +787,11 @@ static void RB_PrepareStageTexturing( const shaderStage_t* pStage, const drawSu /* ================ -RB_FinishStageTexturing +idRenderBackend::FinishStageTexturing ================ */ -static void RB_FinishStageTexturing( const shaderStage_t* pStage, const drawSurf_t* surf ) +void idRenderBackend::FinishStageTexturing( const shaderStage_t* pStage, const drawSurf_t* surf ) { - if( pStage->texture.cinematic ) { // unbind the extra bink textures @@ -678,20 +822,21 @@ static void RB_FinishStageTexturing( const shaderStage_t* pStage, const drawSurf } // RB: moved this up because we need to call this several times for shadow mapping -static void RB_ResetViewportAndScissorToDefaultCamera( const viewDef_t* viewDef ) +void idRenderBackend::ResetViewportAndScissorToDefaultCamera( const viewDef_t* _viewDef ) { // set the window clipping - GL_Viewport( viewDef->viewport.x1, - viewDef->viewport.y1, - viewDef->viewport.x2 + 1 - viewDef->viewport.x1, - viewDef->viewport.y2 + 1 - viewDef->viewport.y1 ); + GL_Viewport( _viewDef->viewport.x1, + _viewDef->viewport.y1, + _viewDef->viewport.x2 + 1 - _viewDef->viewport.x1, + _viewDef->viewport.y2 + 1 - _viewDef->viewport.y1 ); // the scissor may be smaller than the viewport for subviews - GL_Scissor( backEnd.viewDef->viewport.x1 + viewDef->scissor.x1, - backEnd.viewDef->viewport.y1 + viewDef->scissor.y1, - viewDef->scissor.x2 + 1 - viewDef->scissor.x1, - viewDef->scissor.y2 + 1 - viewDef->scissor.y1 ); - backEnd.currentScissor = viewDef->scissor; + GL_Scissor( viewDef->viewport.x1 + _viewDef->scissor.x1, + viewDef->viewport.y1 + _viewDef->scissor.y1, + _viewDef->scissor.x2 + 1 - _viewDef->scissor.x1, + _viewDef->scissor.y2 + 1 - _viewDef->scissor.y1 ); + + currentScissor = viewDef->scissor; } // RB end @@ -705,10 +850,10 @@ DEPTH BUFFER RENDERING /* ================== -RB_FillDepthBufferGeneric +idRenderBackend::FillDepthBufferGeneric ================== */ -static void RB_FillDepthBufferGeneric( const drawSurf_t* const* drawSurfs, int numDrawSurfs ) +void idRenderBackend::FillDepthBufferGeneric( const drawSurf_t* const* drawSurfs, int numDrawSurfs ) { for( int i = 0; i < numDrawSurfs; i++ ) { @@ -742,11 +887,11 @@ static void RB_FillDepthBufferGeneric( const drawSurf_t* const* drawSurfs, int n } // change the matrix if needed - if( drawSurf->space != backEnd.currentSpace ) + if( drawSurf->space != currentSpace ) { RB_SetMVP( drawSurf->space->mvp ); - backEnd.currentSpace = drawSurf->space; + currentSpace = drawSurf->space; } uint64 surfGLState = 0; @@ -855,16 +1000,16 @@ static void RB_FillDepthBufferGeneric( const drawSurf_t* const* drawSurfs, int n pStage->texture.image->Bind(); // set texture matrix and texGens - RB_PrepareStageTexturing( pStage, drawSurf ); + PrepareStageTexturing( pStage, drawSurf ); // must render with less-equal for Z-Cull to work properly assert( ( GL_GetCurrentState() & GLS_DEPTHFUNC_BITS ) == GLS_DEPTHFUNC_LESS ); // draw it - RB_DrawElementsWithCounters( drawSurf ); + DrawElementsWithCounters( drawSurf ); // clean up - RB_FinishStageTexturing( pStage, drawSurf ); + FinishStageTexturing( pStage, drawSurf ); // unset privatePolygonOffset if necessary if( pStage->privatePolygonOffset ) @@ -905,7 +1050,7 @@ static void RB_FillDepthBufferGeneric( const drawSurf_t* const* drawSurfs, int n assert( ( GL_GetCurrentState() & GLS_DEPTHFUNC_BITS ) == GLS_DEPTHFUNC_LESS ); // draw it - RB_DrawElementsWithCounters( drawSurf ); + DrawElementsWithCounters( drawSurf ); } renderLog.CloseBlock(); @@ -918,7 +1063,7 @@ static void RB_FillDepthBufferGeneric( const drawSurf_t* const* drawSurfs, int n /* ===================== -RB_FillDepthBufferFast +idRenderBackend::FillDepthBufferFast Optimized fast path code. @@ -934,7 +1079,7 @@ If there are no subview surfaces, we could clear to black and use fast-Z renderi on the 360. ===================== */ -static void RB_FillDepthBufferFast( drawSurf_t** drawSurfs, int numDrawSurfs ) +void idRenderBackend::FillDepthBufferFast( drawSurf_t** drawSurfs, int numDrawSurfs ) { if( numDrawSurfs == 0 ) { @@ -942,7 +1087,7 @@ static void RB_FillDepthBufferFast( drawSurf_t** drawSurfs, int numDrawSurfs ) } // if we are just doing 2D rendering, no need to fill the depth buffer - if( backEnd.viewDef->viewEntitys == NULL ) + if( viewDef->viewEntitys == NULL ) { return; } @@ -950,10 +1095,10 @@ static void RB_FillDepthBufferFast( drawSurf_t** drawSurfs, int numDrawSurfs ) renderLog.OpenMainBlock( MRB_FILL_DEPTH_BUFFER ); renderLog.OpenBlock( "RB_FillDepthBufferFast" ); - GL_StartDepthPass( backEnd.viewDef->scissor ); + GL_StartDepthPass( viewDef->scissor ); // force MVP change on first surface - backEnd.currentSpace = NULL; + currentSpace = NULL; // draw all the subview surfaces, which will already be at the start of the sorted list, // with the general purpose path @@ -966,7 +1111,8 @@ static void RB_FillDepthBufferFast( drawSurf_t** drawSurfs, int numDrawSurfs ) { break; } - RB_FillDepthBufferGeneric( &drawSurfs[surfNum], 1 ); + + FillDepthBufferGeneric( &drawSurfs[surfNum], 1 ); } const drawSurf_t** perforatedSurfaces = ( const drawSurf_t** )_alloca( numDrawSurfs * sizeof( drawSurf_t* ) ); @@ -998,10 +1144,10 @@ static void RB_FillDepthBufferFast( drawSurf_t** drawSurfs, int numDrawSurfs ) // set polygon offset? // set mvp matrix - if( surf->space != backEnd.currentSpace ) + if( surf->space != currentSpace ) { RB_SetMVP( surf->space->mvp ); - backEnd.currentSpace = surf->space; + currentSpace = surf->space; } renderLog.OpenBlock( shader->GetName() ); @@ -1019,7 +1165,7 @@ static void RB_FillDepthBufferFast( drawSurf_t** drawSurfs, int numDrawSurfs ) assert( ( GL_GetCurrentState() & GLS_DEPTHFUNC_BITS ) == GLS_DEPTHFUNC_LESS ); // draw it solid - RB_DrawElementsWithCounters( surf ); + DrawElementsWithCounters( surf ); renderLog.CloseBlock(); } @@ -1027,7 +1173,7 @@ static void RB_FillDepthBufferFast( drawSurf_t** drawSurfs, int numDrawSurfs ) // draw all perforated surfaces with the general code path if( numPerforatedSurfaces > 0 ) { - RB_FillDepthBufferGeneric( perforatedSurfaces, numPerforatedSurfaces ); + FillDepthBufferGeneric( perforatedSurfaces, numPerforatedSurfaces ); } // Allow platform specific data to be collected after the depth pass. @@ -1055,11 +1201,11 @@ const int INTERACTION_TEXUNIT_JITTER = 6; /* ================== -RB_SetupInteractionStage +idRenderBackend::SetupInteractionStage ================== */ -static void RB_SetupInteractionStage( const shaderStage_t* surfaceStage, const float* surfaceRegs, const float lightColor[4], - idVec4 matrix[2], float color[4] ) +void idRenderBackend::SetupInteractionStage( const shaderStage_t* surfaceStage, const float* surfaceRegs, const float lightColor[4], + idVec4 matrix[2], float color[4] ) { if( surfaceStage->texture.hasMatrix ) @@ -1112,10 +1258,10 @@ static void RB_SetupInteractionStage( const shaderStage_t* surfaceStage, const f /* ================= -RB_DrawSingleInteraction +idRenderBackend::DrawSingleInteraction ================= */ -static void RB_DrawSingleInteraction( drawInteraction_t* din ) +void idRenderBackend::DrawSingleInteraction( drawInteraction_t* din ) { if( din->bumpImage == NULL ) { @@ -1177,7 +1323,7 @@ static void RB_DrawSingleInteraction( drawInteraction_t* din ) GL_SelectTexture( INTERACTION_TEXUNIT_SPECULAR ); din->specularImage->Bind(); - RB_DrawElementsWithCounters( din->surf ); + DrawElementsWithCounters( din->surf ); } /* @@ -1212,12 +1358,12 @@ static void RB_SetupForFastPathInteractions( const idVec4& diffuseColor, const i /* ============= -RB_RenderInteractions +idRenderBackend::RenderInteractions With added sorting and trivial path work. ============= */ -static void RB_RenderInteractions( const drawSurf_t* surfList, const viewLight_t* vLight, int depthFunc, bool performStencilTest, bool useLightDepthBounds ) +void idRenderBackend::RenderInteractions( const drawSurf_t* surfList, const viewLight_t* vLight, int depthFunc, bool performStencilTest, bool useLightDepthBounds ) { if( surfList == NULL ) { @@ -1225,13 +1371,14 @@ static void RB_RenderInteractions( const drawSurf_t* surfList, const viewLight_t } // change the scissor if needed, it will be constant across all the surfaces lit by the light - if( !backEnd.currentScissor.Equals( vLight->scissorRect ) && r_useScissor.GetBool() ) + if( !currentScissor.Equals( vLight->scissorRect ) && r_useScissor.GetBool() ) { - GL_Scissor( backEnd.viewDef->viewport.x1 + vLight->scissorRect.x1, - backEnd.viewDef->viewport.y1 + vLight->scissorRect.y1, + GL_Scissor( viewDef->viewport.x1 + vLight->scissorRect.x1, + viewDef->viewport.y1 + vLight->scissorRect.y1, vLight->scissorRect.x2 + 1 - vLight->scissorRect.x1, vLight->scissorRect.y2 + 1 - vLight->scissorRect.y1 ); - backEnd.currentScissor = vLight->scissorRect; + + currentScissor = vLight->scissorRect; } // perform setup here that will be constant for all interactions @@ -1278,7 +1425,7 @@ static void RB_RenderInteractions( const drawSurf_t* surfList, const viewLight_t } uint64 end = Sys_Microseconds(); - backEnd.pc.shadowMicroSec += end - start; + pc.shadowMicroSec += end - start; } const idMaterial* surfaceShader = walk->material; @@ -1340,10 +1487,10 @@ static void RB_RenderInteractions( const drawSurf_t* surfList, const viewLight_t if( vLight->parallel ) { float cascadeDistances[4]; - cascadeDistances[0] = backEnd.viewDef->frustumSplitDistances[0]; - cascadeDistances[1] = backEnd.viewDef->frustumSplitDistances[1]; - cascadeDistances[2] = backEnd.viewDef->frustumSplitDistances[2]; - cascadeDistances[3] = backEnd.viewDef->frustumSplitDistances[3]; + cascadeDistances[0] = viewDef->frustumSplitDistances[0]; + cascadeDistances[1] = viewDef->frustumSplitDistances[1]; + cascadeDistances[2] = viewDef->frustumSplitDistances[2]; + cascadeDistances[3] = viewDef->frustumSplitDistances[3]; SetFragmentParm( RENDERPARM_CASCADEDISTANCES, cascadeDistances ); // rpCascadeDistances } @@ -1419,7 +1566,7 @@ static void RB_RenderInteractions( const drawSurf_t* surfList, const viewLight_t RB_SetupForFastPathInteractions( diffuseColor, specularColor ); // even if the space does not change between light stages, each light stage may need a different lightTextureMatrix baked in - backEnd.currentSpace = NULL; + currentSpace = NULL; for( int sortedSurfNum = 0; sortedSurfNum < allSurfaces.Num(); sortedSurfNum++ ) { @@ -1496,9 +1643,9 @@ static void RB_RenderInteractions( const drawSurf_t* surfList, const viewLight_t inter.surf = surf; // change the MVP matrix, view/light origin and light projection vectors if needed - if( surf->space != backEnd.currentSpace ) + if( surf->space != currentSpace ) { - backEnd.currentSpace = surf->space; + currentSpace = surf->space; // turn off the light depth bounds test if this model is rendered with a depth hack if( useLightDepthBounds ) @@ -1543,7 +1690,7 @@ static void RB_RenderInteractions( const drawSurf_t* surfList, const viewLight_t idVec4 localLightOrigin( 0.0f ); idVec4 localViewOrigin( 1.0f ); R_GlobalPointToLocal( surf->space->modelMatrix, vLight->globalLightOrigin, localLightOrigin.ToVec3() ); - R_GlobalPointToLocal( surf->space->modelMatrix, backEnd.viewDef->renderView.vieworg, localViewOrigin.ToVec3() ); + R_GlobalPointToLocal( surf->space->modelMatrix, viewDef->renderView.vieworg, localViewOrigin.ToVec3() ); // set the local light/view origin SetVertexParm( RENDERPARM_LOCALLIGHTORIGIN, localLightOrigin.ToFloatPtr() ); @@ -1576,10 +1723,10 @@ static void RB_RenderInteractions( const drawSurf_t* surfList, const viewLight_t for( int i = 0; i < ( r_shadowMapSplits.GetInteger() + 1 ); i++ ) { idRenderMatrix modelToShadowMatrix; - idRenderMatrix::Multiply( backEnd.shadowV[i], modelMatrix, modelToShadowMatrix ); + idRenderMatrix::Multiply( shadowV[i], modelMatrix, modelToShadowMatrix ); idRenderMatrix shadowClipMVP; - idRenderMatrix::Multiply( backEnd.shadowP[i], modelToShadowMatrix, shadowClipMVP ); + idRenderMatrix::Multiply( shadowP[i], modelToShadowMatrix, shadowClipMVP ); idRenderMatrix shadowWindowMVP; idRenderMatrix::Multiply( renderMatrix_clipSpaceToWindowSpace, shadowClipMVP, shadowWindowMVP ); @@ -1592,10 +1739,10 @@ static void RB_RenderInteractions( const drawSurf_t* surfList, const viewLight_t for( int i = 0; i < 6; i++ ) { idRenderMatrix modelToShadowMatrix; - idRenderMatrix::Multiply( backEnd.shadowV[i], modelMatrix, modelToShadowMatrix ); + idRenderMatrix::Multiply( shadowV[i], modelMatrix, modelToShadowMatrix ); idRenderMatrix shadowClipMVP; - idRenderMatrix::Multiply( backEnd.shadowP[i], modelToShadowMatrix, shadowClipMVP ); + idRenderMatrix::Multiply( shadowP[i], modelToShadowMatrix, shadowClipMVP ); idRenderMatrix shadowWindowMVP; idRenderMatrix::Multiply( renderMatrix_clipSpaceToWindowSpace, shadowClipMVP, shadowWindowMVP ); @@ -1608,10 +1755,10 @@ static void RB_RenderInteractions( const drawSurf_t* surfList, const viewLight_t // spot light idRenderMatrix modelToShadowMatrix; - idRenderMatrix::Multiply( backEnd.shadowV[0], modelMatrix, modelToShadowMatrix ); + idRenderMatrix::Multiply( shadowV[0], modelMatrix, modelToShadowMatrix ); idRenderMatrix shadowClipMVP; - idRenderMatrix::Multiply( backEnd.shadowP[0], modelToShadowMatrix, shadowClipMVP ); + idRenderMatrix::Multiply( shadowP[0], modelToShadowMatrix, shadowClipMVP ); SetVertexParms( ( renderParm_t )( RENDERPARM_SHADOW_MATRIX_0_X ), shadowClipMVP[0], 4 ); @@ -1637,7 +1784,7 @@ static void RB_RenderInteractions( const drawSurf_t* surfList, const viewLight_t GL_SelectTexture( INTERACTION_TEXUNIT_SPECULAR ); surfaceShader->GetFastPathSpecularImage()->Bind(); - RB_DrawElementsWithCounters( surf ); + DrawElementsWithCounters( surf ); renderLog.CloseBlock(); continue; @@ -1685,7 +1832,7 @@ static void RB_RenderInteractions( const drawSurf_t* surfList, const viewLight_t // draw any previous interaction if( inter.bumpImage != NULL ) { - RB_DrawSingleInteraction( &inter ); + DrawSingleInteraction( &inter ); } inter.bumpImage = surfaceStage->texture.image; inter.diffuseImage = NULL; @@ -1704,7 +1851,7 @@ static void RB_RenderInteractions( const drawSurf_t* surfList, const viewLight_t // draw any previous interaction if( inter.diffuseImage != NULL ) { - RB_DrawSingleInteraction( &inter ); + DrawSingleInteraction( &inter ); } inter.diffuseImage = surfaceStage->texture.image; inter.vertexColor = surfaceStage->vertexColor; @@ -1722,7 +1869,7 @@ static void RB_RenderInteractions( const drawSurf_t* surfList, const viewLight_t // draw any previous interaction if( inter.specularImage != NULL ) { - RB_DrawSingleInteraction( &inter ); + DrawSingleInteraction( &inter ); } inter.specularImage = surfaceStage->texture.image; inter.vertexColor = surfaceStage->vertexColor; @@ -1734,7 +1881,7 @@ static void RB_RenderInteractions( const drawSurf_t* surfList, const viewLight_t } // draw the final interaction - RB_DrawSingleInteraction( &inter ); + DrawSingleInteraction( &inter ); renderLog.CloseBlock(); } @@ -1760,10 +1907,10 @@ AMBIENT PASS RENDERING /* ================== -RB_AmbientPass +idRenderBackend::AmbientPass ================== */ -static void RB_AmbientPass( const drawSurf_t* const* drawSurfs, int numDrawSurfs, bool fillGbuffer ) +void idRenderBackend::AmbientPass( const drawSurf_t* const* drawSurfs, int numDrawSurfs, bool fillGbuffer ) { if( fillGbuffer ) { @@ -1786,7 +1933,7 @@ static void RB_AmbientPass( const drawSurf_t* const* drawSurfs, int numDrawSurfs } // if we are just doing 2D rendering, no need to fill the depth buffer - if( backEnd.viewDef->viewEntitys == NULL ) + if( viewDef->viewEntitys == NULL ) { return; } @@ -1810,7 +1957,7 @@ static void RB_AmbientPass( const drawSurf_t* const* drawSurfs, int numDrawSurfs // GL_StartDepthPass( backEnd.viewDef->scissor ); // force MVP change on first surface - backEnd.currentSpace = NULL; + currentSpace = NULL; // draw all the subview surfaces, which will already be at the start of the sorted list, // with the general purpose path @@ -1915,15 +2062,15 @@ static void RB_AmbientPass( const drawSurf_t* const* drawSurfs, int numDrawSurfs } // change the matrix if needed - if( drawSurf->space != backEnd.currentSpace ) + if( drawSurf->space != currentSpace ) { - backEnd.currentSpace = drawSurf->space; + currentSpace = drawSurf->space; RB_SetMVP( drawSurf->space->mvp ); // tranform the view origin into model local space idVec4 localViewOrigin( 1.0f ); - R_GlobalPointToLocal( drawSurf->space->modelMatrix, backEnd.viewDef->renderView.vieworg, localViewOrigin.ToVec3() ); + R_GlobalPointToLocal( drawSurf->space->modelMatrix, viewDef->renderView.vieworg, localViewOrigin.ToVec3() ); SetVertexParm( RENDERPARM_LOCALVIEWORIGIN, localViewOrigin.ToFloatPtr() ); //if( !isWorldModel ) @@ -2019,7 +2166,7 @@ static void RB_AmbientPass( const drawSurf_t* const* drawSurfs, int numDrawSurfs GL_SelectTexture( INTERACTION_TEXUNIT_SPECULAR ); surfaceMaterial->GetFastPathSpecularImage()->Bind(); - RB_DrawElementsWithCounters( drawSurf ); + DrawElementsWithCounters( drawSurf ); renderLog.CloseBlock(); continue; @@ -2074,7 +2221,7 @@ static void RB_AmbientPass( const drawSurf_t* const* drawSurfs, int numDrawSurfs // draw any previous interaction if( inter.bumpImage != NULL ) { - RB_DrawSingleInteraction( &inter ); + DrawSingleInteraction( &inter ); } inter.bumpImage = surfaceStage->texture.image; inter.diffuseImage = NULL; @@ -2095,7 +2242,7 @@ static void RB_AmbientPass( const drawSurf_t* const* drawSurfs, int numDrawSurfs // draw any previous interaction if( inter.diffuseImage != NULL ) { - RB_DrawSingleInteraction( &inter ); + DrawSingleInteraction( &inter ); } inter.diffuseImage = surfaceStage->texture.image; @@ -2115,7 +2262,7 @@ static void RB_AmbientPass( const drawSurf_t* const* drawSurfs, int numDrawSurfs // draw any previous interaction if( inter.specularImage != NULL ) { - RB_DrawSingleInteraction( &inter ); + DrawSingleInteraction( &inter ); } inter.specularImage = surfaceStage->texture.image; inter.vertexColor = surfaceStage->vertexColor; @@ -2127,7 +2274,7 @@ static void RB_AmbientPass( const drawSurf_t* const* drawSurfs, int numDrawSurfs } // draw the final interaction - RB_DrawSingleInteraction( &inter ); + DrawSingleInteraction( &inter ); renderLog.CloseBlock(); } @@ -2184,12 +2331,12 @@ STENCIL SHADOW RENDERING /* ===================== -RB_StencilShadowPass +idRenderBackend::StencilShadowPass The stencil buffer should have been set to 128 on any surfaces that might receive shadows. ===================== */ -static void RB_StencilShadowPass( const drawSurf_t* drawSurfs, const viewLight_t* vLight ) +void idRenderBackend::StencilShadowPass( const drawSurf_t* drawSurfs, const viewLight_t* vLight ) { if( r_skipShadows.GetBool() ) { @@ -2245,7 +2392,7 @@ static void RB_StencilShadowPass( const drawSurf_t* drawSurfs, const viewLight_t // process the chain of shadows with the current rendering state - backEnd.currentSpace = NULL; + currentSpace = NULL; for( const drawSurf_t* drawSurf = drawSurfs; drawSurf != NULL; drawSurf = drawSurf->nextOnLight ) { @@ -2267,7 +2414,7 @@ static void RB_StencilShadowPass( const drawSurf_t* drawSurfs, const viewLight_t } uint64 end = Sys_Microseconds(); - backEnd.pc.shadowMicroSec += end - start; + pc.shadowMicroSec += end - start; } if( drawSurf->numIndexes == 0 ) @@ -2275,17 +2422,18 @@ static void RB_StencilShadowPass( const drawSurf_t* drawSurfs, const viewLight_t continue; // a job may have created an empty shadow volume } - if( !backEnd.currentScissor.Equals( drawSurf->scissorRect ) && r_useScissor.GetBool() ) + if( !currentScissor.Equals( drawSurf->scissorRect ) && r_useScissor.GetBool() ) { // change the scissor - GL_Scissor( backEnd.viewDef->viewport.x1 + drawSurf->scissorRect.x1, - backEnd.viewDef->viewport.y1 + drawSurf->scissorRect.y1, + GL_Scissor( viewDef->viewport.x1 + drawSurf->scissorRect.x1, + viewDef->viewport.y1 + drawSurf->scissorRect.y1, drawSurf->scissorRect.x2 + 1 - drawSurf->scissorRect.x1, drawSurf->scissorRect.y2 + 1 - drawSurf->scissorRect.y1 ); - backEnd.currentScissor = drawSurf->scissorRect; + + currentScissor = drawSurf->scissorRect; } - if( drawSurf->space != backEnd.currentSpace ) + if( drawSurf->space != currentSpace ) { // change the matrix RB_SetMVP( drawSurf->space->mvp ); @@ -2295,7 +2443,7 @@ static void RB_StencilShadowPass( const drawSurf_t* drawSurfs, const viewLight_t R_GlobalPointToLocal( drawSurf->space->modelMatrix, vLight->globalLightOrigin, localLight.ToVec3() ); SetVertexParm( RENDERPARM_LOCALLIGHTORIGIN, localLight.ToFloatPtr() ); - backEnd.currentSpace = drawSurf->space; + currentSpace = drawSurf->space; } if( r_showShadows.GetInteger() == 0 ) @@ -2402,10 +2550,10 @@ static void RB_StencilShadowPass( const drawSurf_t* drawSurfs, const viewLight_t RENDERLOG_PRINTF( "Binding Buffers: %p %p\n", vertexBuffer, indexBuffer ); // RB: 64 bit fixes, changed GLuint to GLintptr - if( backEnd.glState.currentIndexBuffer != ( GLintptr )indexBuffer->GetAPIObject() || !r_useStateCaching.GetBool() ) + if( currentIndexBuffer != ( GLintptr )indexBuffer->GetAPIObject() || !r_useStateCaching.GetBool() ) { glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, ( GLintptr )indexBuffer->GetAPIObject() ); - backEnd.glState.currentIndexBuffer = ( GLintptr )indexBuffer->GetAPIObject(); + currentIndexBuffer = ( GLintptr )indexBuffer->GetAPIObject(); } if( drawSurf->jointCache ) @@ -2423,10 +2571,10 @@ static void RB_StencilShadowPass( const drawSurf_t* drawSurfs, const viewLight_t const GLintptr ubo = reinterpret_cast< GLintptr >( jointBuffer.GetAPIObject() ); glBindBufferRange( GL_UNIFORM_BUFFER, 0, ubo, jointBuffer.GetOffset(), jointBuffer.GetNumJoints() * sizeof( idJointMat ) ); - if( ( backEnd.glState.vertexLayout != LAYOUT_DRAW_SHADOW_VERT_SKINNED ) || ( backEnd.glState.currentVertexBuffer != ( GLintptr )vertexBuffer->GetAPIObject() ) || !r_useStateCaching.GetBool() ) + if( ( vertexLayout != LAYOUT_DRAW_SHADOW_VERT_SKINNED ) || ( currentVertexBuffer != ( GLintptr )vertexBuffer->GetAPIObject() ) || !r_useStateCaching.GetBool() ) { glBindBuffer( GL_ARRAY_BUFFER, ( GLintptr )vertexBuffer->GetAPIObject() ); - backEnd.glState.currentVertexBuffer = ( GLintptr )vertexBuffer->GetAPIObject(); + currentVertexBuffer = ( GLintptr )vertexBuffer->GetAPIObject(); glEnableVertexAttribArray( PC_ATTRIB_INDEX_VERTEX ); glDisableVertexAttribArray( PC_ATTRIB_INDEX_NORMAL ); @@ -2445,16 +2593,16 @@ static void RB_StencilShadowPass( const drawSurf_t* drawSurfs, const viewLight_t glVertexAttribPointer( PC_ATTRIB_INDEX_COLOR2, 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof( idShadowVertSkinned ), ( void* )( SHADOWVERTSKINNED_COLOR2_OFFSET ) ); #endif - backEnd.glState.vertexLayout = LAYOUT_DRAW_SHADOW_VERT_SKINNED; + vertexLayout = LAYOUT_DRAW_SHADOW_VERT_SKINNED; } } else { - if( ( backEnd.glState.vertexLayout != LAYOUT_DRAW_SHADOW_VERT ) || ( backEnd.glState.currentVertexBuffer != ( GLintptr )vertexBuffer->GetAPIObject() ) || !r_useStateCaching.GetBool() ) + if( ( vertexLayout != LAYOUT_DRAW_SHADOW_VERT ) || ( currentVertexBuffer != ( GLintptr )vertexBuffer->GetAPIObject() ) || !r_useStateCaching.GetBool() ) { glBindBuffer( GL_ARRAY_BUFFER, ( GLintptr )vertexBuffer->GetAPIObject() ); - backEnd.glState.currentVertexBuffer = ( GLintptr )vertexBuffer->GetAPIObject(); + currentVertexBuffer = ( GLintptr )vertexBuffer->GetAPIObject(); glEnableVertexAttribArray( PC_ATTRIB_INDEX_VERTEX ); glDisableVertexAttribArray( PC_ATTRIB_INDEX_NORMAL ); @@ -2469,7 +2617,7 @@ static void RB_StencilShadowPass( const drawSurf_t* drawSurfs, const viewLight_t glVertexAttribPointer( PC_ATTRIB_INDEX_VERTEX, 4, GL_FLOAT, GL_FALSE, sizeof( idShadowVert ), ( void* )( SHADOWVERT_XYZW_OFFSET ) ); #endif - backEnd.glState.vertexLayout = LAYOUT_DRAW_SHADOW_VERT; + vertexLayout = LAYOUT_DRAW_SHADOW_VERT; } } // RB end @@ -2494,8 +2642,8 @@ static void RB_StencilShadowPass( const drawSurf_t* drawSurfs, const viewLight_t } // RB: added stats - backEnd.pc.c_shadowElements++; - backEnd.pc.c_shadowIndexes += drawSurf->numIndexes; + pc.c_shadowElements++; + pc.c_shadowIndexes += drawSurf->numIndexes; // RB end if( !renderZPass && r_useStencilShadowPreload.GetBool() ) @@ -2522,8 +2670,8 @@ static void RB_StencilShadowPass( const drawSurf_t* drawSurfs, const viewLight_t } // RB: added stats - backEnd.pc.c_shadowElements++; - backEnd.pc.c_shadowIndexes += drawSurf->numIndexes; + pc.c_shadowElements++; + pc.c_shadowIndexes += drawSurf->numIndexes; // RB end } } @@ -2548,25 +2696,26 @@ static void RB_StencilShadowPass( const drawSurf_t* drawSurfs, const viewLight_t /* ================== -RB_StencilSelectLight +idRenderBackend::StencilSelectLight Deform the zeroOneCubeModel to exactly cover the light volume. Render the deformed cube model to the stencil buffer in such a way that only fragments that are directly visible and contained within the volume will be written creating a mask to be used by the following stencil shadow and draw interaction passes. ================== */ -static void RB_StencilSelectLight( const viewLight_t* vLight ) +void idRenderBackend::StencilSelectLight( const viewLight_t* vLight ) { renderLog.OpenBlock( "Stencil Select" ); // enable the light scissor - if( !backEnd.currentScissor.Equals( vLight->scissorRect ) && r_useScissor.GetBool() ) + if( !currentScissor.Equals( vLight->scissorRect ) && r_useScissor.GetBool() ) { - GL_Scissor( backEnd.viewDef->viewport.x1 + vLight->scissorRect.x1, - backEnd.viewDef->viewport.y1 + vLight->scissorRect.y1, + GL_Scissor( viewDef->viewport.x1 + vLight->scissorRect.x1, + viewDef->viewport.y1 + vLight->scissorRect.y1, vLight->scissorRect.x2 + 1 - vLight->scissorRect.x1, vLight->scissorRect.y2 + 1 - vLight->scissorRect.y1 ); - backEnd.currentScissor = vLight->scissorRect; + + currentScissor = vLight->scissorRect; } // clear stencil buffer to 0 (not drawable) @@ -2585,14 +2734,14 @@ static void RB_StencilSelectLight( const viewLight_t* vLight ) // set the matrix for deforming the 'zeroOneCubeModel' into the frustum to exactly cover the light volume idRenderMatrix invProjectMVPMatrix; - idRenderMatrix::Multiply( backEnd.viewDef->worldSpace.mvp, vLight->inverseBaseLightProject, invProjectMVPMatrix ); + idRenderMatrix::Multiply( viewDef->worldSpace.mvp, vLight->inverseBaseLightProject, invProjectMVPMatrix ); RB_SetMVP( invProjectMVPMatrix ); // two-sided stencil test glStencilOpSeparate( GL_FRONT, GL_KEEP, GL_REPLACE, GL_ZERO ); glStencilOpSeparate( GL_BACK, GL_KEEP, GL_ZERO, GL_REPLACE ); - RB_DrawElementsWithCounters( &backEnd.zeroOneCubeSurface ); + DrawElementsWithCounters( &zeroOneCubeSurface ); // reset stencil state @@ -2707,10 +2856,10 @@ void MatrixLookAtRH( float m[16], const idVec3& eye, const idVec3& dir, const id /* ===================== -RB_ShadowMapPass +idRenderBackend::ShadowMapPass ===================== */ -static void RB_ShadowMapPass( const drawSurf_t* drawSurfs, const viewLight_t* vLight, int side ) +void idRenderBackend::ShadowMapPass( const drawSurf_t* drawSurfs, const viewLight_t* vLight, int side ) { if( r_skipShadows.GetBool() ) { @@ -2773,11 +2922,11 @@ static void RB_ShadowMapPass( const drawSurf_t* drawSurfs, const viewLight_t* vL //idAngles angles = lightDir.ToAngles(); //idMat3 rotation = angles.ToMat3(); - const idVec3 viewDir = backEnd.viewDef->renderView.viewaxis[0]; - const idVec3 viewPos = backEnd.viewDef->renderView.vieworg; + const idVec3 viewDir = viewDef->renderView.viewaxis[0]; + const idVec3 viewPos = viewDef->renderView.vieworg; #if 1 - idRenderMatrix::CreateViewMatrix( backEnd.viewDef->renderView.vieworg, rotation, lightViewRenderMatrix ); + idRenderMatrix::CreateViewMatrix( viewDef->renderView.vieworg, rotation, lightViewRenderMatrix ); #else float lightViewMatrix[16]; MatrixLookAtRH( lightViewMatrix, viewPos, lightDir, viewDir ); @@ -2815,7 +2964,7 @@ static void RB_ShadowMapPass( const drawSurf_t* drawSurfs, const viewLight_t* vL // invert the MVP projection so we can deform zero-to-one cubes into the frustum pyramid shape and calculate global bounds idRenderMatrix splitFrustumInverse; - if( !idRenderMatrix::Inverse( backEnd.viewDef->frustumMVPs[FRUSTUM_CASCADE1 + side], splitFrustumInverse ) ) + if( !idRenderMatrix::Inverse( viewDef->frustumMVPs[FRUSTUM_CASCADE1 + side], splitFrustumInverse ) ) { idLib::Warning( "splitFrustumMVP invert failed" ); } @@ -2912,8 +3061,8 @@ static void RB_ShadowMapPass( const drawSurf_t* drawSurfs, const viewLight_t* vL MatrixOrthogonalProjectionRH( lightProjectionMatrix, cropBounds[0][0], cropBounds[1][0], cropBounds[0][1], cropBounds[1][1], -cropBounds[1][2], -cropBounds[0][2] ); idRenderMatrix::Transpose( *( idRenderMatrix* )lightProjectionMatrix, lightProjectionRenderMatrix ); - backEnd.shadowV[side] = lightViewRenderMatrix; - backEnd.shadowP[side] = lightProjectionRenderMatrix; + shadowV[side] = lightViewRenderMatrix; + shadowP[side] = lightProjectionRenderMatrix; } else if( vLight->pointLight && side >= 0 ) { @@ -2992,9 +3141,6 @@ static void RB_ShadowMapPass( const drawSurf_t* drawSurfs, const viewLight_t* vL idRenderMatrix::Transpose( *( idRenderMatrix* )lightViewMatrix, lightViewRenderMatrix ); - - - // set up 90 degree projection matrix const float zNear = 4; const float fov = r_shadowMapFrustumFOV.GetFloat(); @@ -3036,20 +3182,18 @@ static void RB_ShadowMapPass( const drawSurf_t* drawSurfs, const viewLight_t* vL idRenderMatrix::Transpose( *( idRenderMatrix* )lightProjectionMatrix, lightProjectionRenderMatrix ); - backEnd.shadowV[side] = lightViewRenderMatrix; - backEnd.shadowP[side] = lightProjectionRenderMatrix; + shadowV[side] = lightViewRenderMatrix; + shadowP[side] = lightProjectionRenderMatrix; } else { lightViewRenderMatrix.Identity(); lightProjectionRenderMatrix = vLight->baseLightProject; - backEnd.shadowV[0] = lightViewRenderMatrix; - backEnd.shadowP[0] = lightProjectionRenderMatrix; + shadowV[0] = lightViewRenderMatrix; + shadowP[0] = lightProjectionRenderMatrix; } - - globalFramebuffers.shadowFBO[vLight->shadowLOD]->Bind(); if( side < 0 ) @@ -3068,7 +3212,7 @@ static void RB_ShadowMapPass( const drawSurf_t* drawSurfs, const viewLight_t* vL glClear( GL_DEPTH_BUFFER_BIT ); // process the chain of shadows with the current rendering state - backEnd.currentSpace = NULL; + currentSpace = NULL; for( const drawSurf_t* drawSurf = drawSurfs; drawSurf != NULL; drawSurf = drawSurf->nextOnLight ) { @@ -3086,7 +3230,7 @@ static void RB_ShadowMapPass( const drawSurf_t* drawSurfs, const viewLight_t* vL } uint64 end = Sys_Microseconds(); - backEnd.pc.shadowMicroSec += end - start; + pc.shadowMicroSec += end - start; } #endif @@ -3095,7 +3239,7 @@ static void RB_ShadowMapPass( const drawSurf_t* drawSurfs, const viewLight_t* vL continue; // a job may have created an empty shadow geometry } - if( drawSurf->space != backEnd.currentSpace ) + if( drawSurf->space != currentSpace ) { idRenderMatrix modelRenderMatrix; idRenderMatrix::Transpose( *( idRenderMatrix* )drawSurf->space->modelMatrix, modelRenderMatrix ); @@ -3133,7 +3277,7 @@ static void RB_ShadowMapPass( const drawSurf_t* drawSurfs, const viewLight_t* vL SetVertexParm( RENDERPARM_LOCALLIGHTORIGIN, localLight.ToFloatPtr() ); */ - backEnd.currentSpace = drawSurf->space; + currentSpace = drawSurf->space; } bool didDraw = false; @@ -3220,16 +3364,16 @@ static void RB_ShadowMapPass( const drawSurf_t* drawSurfs, const viewLight_t* vL pStage->texture.image->Bind(); // set texture matrix and texGens - RB_PrepareStageTexturing( pStage, drawSurf ); + PrepareStageTexturing( pStage, drawSurf ); // must render with less-equal for Z-Cull to work properly assert( ( GL_GetCurrentState() & GLS_DEPTHFUNC_BITS ) == GLS_DEPTHFUNC_LESS ); // draw it - RB_DrawElementsWithCounters( drawSurf ); + DrawElementsWithCounters( drawSurf ); // clean up - RB_FinishStageTexturing( pStage, drawSurf ); + FinishStageTexturing( pStage, drawSurf ); // unset privatePolygonOffset if necessary if( pStage->privatePolygonOffset ) @@ -3251,7 +3395,7 @@ static void RB_ShadowMapPass( const drawSurf_t* drawSurfs, const viewLight_t* vL renderProgManager.BindShader_Depth(); } - RB_DrawElementsWithCounters( drawSurf ); + DrawElementsWithCounters( drawSurf ); } } @@ -3283,10 +3427,10 @@ DRAW INTERACTIONS */ /* ================== -RB_DrawInteractions +idRenderBackend::DrawInteractions ================== */ -static void RB_DrawInteractions( const viewDef_t* viewDef ) +void idRenderBackend::DrawInteractions( const viewDef_t* _viewDef ) { if( r_skipInteractions.GetBool() ) { @@ -3304,7 +3448,7 @@ static void RB_DrawInteractions( const viewDef_t* viewDef ) // // for each light, perform shadowing and adding // - for( const viewLight_t* vLight = backEnd.viewDef->viewLights; vLight != NULL; vLight = vLight->next ) + for( const viewLight_t* vLight = viewDef->viewLights; vLight != NULL; vLight = vLight->next ) { // do fogging later if( vLight->lightShader->IsFogLight() ) @@ -3361,23 +3505,23 @@ static void RB_DrawInteractions( const viewDef_t* viewDef ) for( ; side < sideStop ; side++ ) { - RB_ShadowMapPass( vLight->globalShadows, vLight, side ); + ShadowMapPass( vLight->globalShadows, vLight, side ); } // go back from light view to default camera view - RB_ResetViewportAndScissorToDefaultCamera( viewDef ); + ResetViewportAndScissorToDefaultCamera( _viewDef ); if( vLight->localInteractions != NULL ) { renderLog.OpenBlock( "Local Light Interactions" ); - RB_RenderInteractions( vLight->localInteractions, vLight, GLS_DEPTHFUNC_EQUAL, false, useLightDepthBounds ); + RenderInteractions( vLight->localInteractions, vLight, GLS_DEPTHFUNC_EQUAL, false, useLightDepthBounds ); renderLog.CloseBlock(); } if( vLight->globalInteractions != NULL ) { renderLog.OpenBlock( "Global Light Interactions" ); - RB_RenderInteractions( vLight->globalInteractions, vLight, GLS_DEPTHFUNC_EQUAL, false, useLightDepthBounds ); + RenderInteractions( vLight->globalInteractions, vLight, GLS_DEPTHFUNC_EQUAL, false, useLightDepthBounds ); renderLog.CloseBlock(); } } @@ -3388,14 +3532,14 @@ static void RB_DrawInteractions( const viewDef_t* viewDef ) // mirror flips the sense of the stencil select, and I don't want to risk accidentally breaking it // in the normal case, so simply disable the stencil select in the mirror case - const bool useLightStencilSelect = ( r_useLightStencilSelect.GetBool() && backEnd.viewDef->isMirror == false ); + const bool useLightStencilSelect = ( r_useLightStencilSelect.GetBool() && viewDef->isMirror == false ); if( performStencilTest ) { if( useLightStencilSelect ) { // write a stencil mask for the visible light bounds to hi-stencil - RB_StencilSelectLight( vLight ); + StencilSelectLight( vLight ); } else { @@ -3406,7 +3550,7 @@ static void RB_DrawInteractions( const viewDef_t* viewDef ) rect.x2 = ( vLight->scissorRect.x2 + 15 ) & ~15; rect.y2 = ( vLight->scissorRect.y2 + 15 ) & ~15; - if( !backEnd.currentScissor.Equals( rect ) && r_useScissor.GetBool() ) + if( !currentScissor.Equals( rect ) && r_useScissor.GetBool() ) { GL_Scissor( backEnd.viewDef->viewport.x1 + rect.x1, backEnd.viewDef->viewport.y1 + rect.y1, @@ -3422,28 +3566,28 @@ static void RB_DrawInteractions( const viewDef_t* viewDef ) if( vLight->globalShadows != NULL ) { renderLog.OpenBlock( "Global Light Shadows" ); - RB_StencilShadowPass( vLight->globalShadows, vLight ); + StencilShadowPass( vLight->globalShadows, vLight ); renderLog.CloseBlock(); } if( vLight->localInteractions != NULL ) { renderLog.OpenBlock( "Local Light Interactions" ); - RB_RenderInteractions( vLight->localInteractions, vLight, GLS_DEPTHFUNC_EQUAL, performStencilTest, useLightDepthBounds ); + RenderInteractions( vLight->localInteractions, vLight, GLS_DEPTHFUNC_EQUAL, performStencilTest, useLightDepthBounds ); renderLog.CloseBlock(); } if( vLight->localShadows != NULL ) { renderLog.OpenBlock( "Local Light Shadows" ); - RB_StencilShadowPass( vLight->localShadows, vLight ); + StencilShadowPass( vLight->localShadows, vLight ); renderLog.CloseBlock(); } if( vLight->globalInteractions != NULL ) { renderLog.OpenBlock( "Global Light Interactions" ); - RB_RenderInteractions( vLight->globalInteractions, vLight, GLS_DEPTHFUNC_EQUAL, performStencilTest, useLightDepthBounds ); + RenderInteractions( vLight->globalInteractions, vLight, GLS_DEPTHFUNC_EQUAL, performStencilTest, useLightDepthBounds ); renderLog.CloseBlock(); } } @@ -3468,7 +3612,7 @@ static void RB_DrawInteractions( const viewDef_t* viewDef ) // stencil shadows only affect surfaces that contribute to the view depth // buffer and translucent surfaces do not contribute to the view depth buffer. - RB_RenderInteractions( vLight->translucentInteractions, vLight, GLS_DEPTHFUNC_LESS, false, false ); + RenderInteractions( vLight->translucentInteractions, vLight, GLS_DEPTHFUNC_LESS, false, false ); renderLog.CloseBlock(); } @@ -3507,7 +3651,7 @@ NON-INTERACTION SHADER PASSES /* ===================== -RB_DrawShaderPasses +idRenderBackend::DrawShaderPasses Draw non-light dependent passes @@ -3515,8 +3659,8 @@ If we are rendering Guis, the drawSurf_t::sort value is a depth offset that can be multiplied by guiEye for polarity and screenSeparation for scale. ===================== */ -static int RB_DrawShaderPasses( const drawSurf_t* const* const drawSurfs, const int numDrawSurfs, - const float guiStereoScreenOffset, const int stereoEye ) +int idRenderBackend::DrawShaderPasses( const drawSurf_t* const* const drawSurfs, const int numDrawSurfs, + const float guiStereoScreenOffset, const int stereoEye ) { // only obey skipAmbient if we are rendering a view if( backEnd.viewDef->viewEntitys && r_skipAmbient.GetBool() ) @@ -3925,12 +4069,12 @@ BLEND LIGHT PROJECTION /* ===================== -RB_T_BlendLight +idRenderBackend::T_BlendLight ===================== */ -static void RB_T_BlendLight( const drawSurf_t* drawSurfs, const viewLight_t* vLight ) +void idRenderBackend::T_BlendLight( const drawSurf_t* drawSurfs, const viewLight_t* vLight ) { - backEnd.currentSpace = NULL; + currentSpace = NULL; for( const drawSurf_t* drawSurf = drawSurfs; drawSurf != NULL; drawSurf = drawSurf->nextOnLight ) { @@ -3940,17 +4084,18 @@ static void RB_T_BlendLight( const drawSurf_t* drawSurfs, const viewLight_t* vLi // temporarily jump over the scissor and draw so the gl error callback doesn't get hit } - if( !backEnd.currentScissor.Equals( drawSurf->scissorRect ) && r_useScissor.GetBool() ) + if( !currentScissor.Equals( drawSurf->scissorRect ) && r_useScissor.GetBool() ) { // change the scissor - GL_Scissor( backEnd.viewDef->viewport.x1 + drawSurf->scissorRect.x1, - backEnd.viewDef->viewport.y1 + drawSurf->scissorRect.y1, + GL_Scissor( viewDef->viewport.x1 + drawSurf->scissorRect.x1, + viewDef->viewport.y1 + drawSurf->scissorRect.y1, drawSurf->scissorRect.x2 + 1 - drawSurf->scissorRect.x1, drawSurf->scissorRect.y2 + 1 - drawSurf->scissorRect.y1 ); - backEnd.currentScissor = drawSurf->scissorRect; + + currentScissor = drawSurf->scissorRect; } - if( drawSurf->space != backEnd.currentSpace ) + if( drawSurf->space != currentSpace ) { // change the matrix RB_SetMVP( drawSurf->space->mvp ); @@ -3967,22 +4112,22 @@ static void RB_T_BlendLight( const drawSurf_t* drawSurfs, const viewLight_t* vLi SetVertexParm( RENDERPARM_TEXGEN_0_Q, lightProjectInCurrentSpace[2].ToFloatPtr() ); SetVertexParm( RENDERPARM_TEXGEN_1_S, lightProjectInCurrentSpace[3].ToFloatPtr() ); // falloff - backEnd.currentSpace = drawSurf->space; + currentSpace = drawSurf->space; } - RB_DrawElementsWithCounters( drawSurf ); + DrawElementsWithCounters( drawSurf ); } } /* ===================== -RB_BlendLight +idRenderBackend::BlendLight Dual texture together the falloff and projection texture with a blend mode to the framebuffer, instead of interacting with the surface texture ===================== */ -static void RB_BlendLight( const drawSurf_t* drawSurfs, const drawSurf_t* drawSurfs2, const viewLight_t* vLight ) +void idRenderBackend::BlendLight( const drawSurf_t* drawSurfs, const drawSurf_t* drawSurfs2, const viewLight_t* vLight ) { if( drawSurfs == NULL ) { @@ -4033,8 +4178,8 @@ static void RB_BlendLight( const drawSurf_t* drawSurfs, const drawSurf_t* drawSu lightColor[3] = regs[ stage->color.registers[3] ]; GL_Color( lightColor ); - RB_T_BlendLight( drawSurfs, vLight ); - RB_T_BlendLight( drawSurfs2, vLight ); + T_BlendLight( drawSurfs, vLight ); + T_BlendLight( drawSurfs2, vLight ); } GL_SelectTexture( 1 ); @@ -4056,12 +4201,12 @@ FOG LIGHTS /* ===================== -RB_T_BasicFog +idRenderBackend::T_BasicFog ===================== */ -static void RB_T_BasicFog( const drawSurf_t* drawSurfs, const idPlane fogPlanes[4], const idRenderMatrix* inverseBaseLightProject ) +void idRenderBackend::T_BasicFog( const drawSurf_t* drawSurfs, const idPlane fogPlanes[4], const idRenderMatrix* inverseBaseLightProject ) { - backEnd.currentSpace = NULL; + currentSpace = NULL; for( const drawSurf_t* drawSurf = drawSurfs; drawSurf != NULL; drawSurf = drawSurf->nextOnLight ) { @@ -4071,17 +4216,18 @@ static void RB_T_BasicFog( const drawSurf_t* drawSurfs, const idPlane fogPlanes[ // temporarily jump over the scissor and draw so the gl error callback doesn't get hit } - if( !backEnd.currentScissor.Equals( drawSurf->scissorRect ) && r_useScissor.GetBool() ) + if( !currentScissor.Equals( drawSurf->scissorRect ) && r_useScissor.GetBool() ) { // change the scissor - GL_Scissor( backEnd.viewDef->viewport.x1 + drawSurf->scissorRect.x1, - backEnd.viewDef->viewport.y1 + drawSurf->scissorRect.y1, + GL_Scissor( viewDef->viewport.x1 + drawSurf->scissorRect.x1, + viewDef->viewport.y1 + drawSurf->scissorRect.y1, drawSurf->scissorRect.x2 + 1 - drawSurf->scissorRect.x1, drawSurf->scissorRect.y2 + 1 - drawSurf->scissorRect.y1 ); - backEnd.currentScissor = drawSurf->scissorRect; + + currentScissor = drawSurf->scissorRect; } - if( drawSurf->space != backEnd.currentSpace ) + if( drawSurf->space != currentSpace ) { idPlane localFogPlanes[4]; if( inverseBaseLightProject == NULL ) @@ -4095,7 +4241,7 @@ static void RB_T_BasicFog( const drawSurf_t* drawSurfs, const idPlane fogPlanes[ else { idRenderMatrix invProjectMVPMatrix; - idRenderMatrix::Multiply( backEnd.viewDef->worldSpace.mvp, *inverseBaseLightProject, invProjectMVPMatrix ); + idRenderMatrix::Multiply( viewDef->worldSpace.mvp, *inverseBaseLightProject, invProjectMVPMatrix ); RB_SetMVP( invProjectMVPMatrix ); for( int i = 0; i < 4; i++ ) { @@ -4108,7 +4254,7 @@ static void RB_T_BasicFog( const drawSurf_t* drawSurfs, const idPlane fogPlanes[ SetVertexParm( RENDERPARM_TEXGEN_1_T, localFogPlanes[2].ToFloatPtr() ); SetVertexParm( RENDERPARM_TEXGEN_1_S, localFogPlanes[3].ToFloatPtr() ); - backEnd.currentSpace = ( inverseBaseLightProject == NULL ) ? drawSurf->space : NULL; + currentSpace = ( inverseBaseLightProject == NULL ) ? drawSurf->space : NULL; } if( drawSurf->jointCache ) @@ -4120,16 +4266,16 @@ static void RB_T_BasicFog( const drawSurf_t* drawSurfs, const idPlane fogPlanes[ renderProgManager.BindShader_Fog(); } - RB_DrawElementsWithCounters( drawSurf ); + DrawElementsWithCounters( drawSurf ); } } /* ================== -RB_FogPass +idRenderBackend::FogPass ================== */ -static void RB_FogPass( const drawSurf_t* drawSurfs, const drawSurf_t* drawSurfs2, const viewLight_t* vLight ) +void idRenderBackend::FogPass( const drawSurf_t* drawSurfs, const drawSurf_t* drawSurfs2, const viewLight_t* vLight ) { renderLog.OpenBlock( vLight->lightShader->GetName() ); @@ -4170,17 +4316,17 @@ static void RB_FogPass( const drawSurf_t* drawSurfs, const drawSurf_t* drawSurf globalImages->fogEnterImage->Bind(); // S is based on the view origin - const float s = vLight->fogPlane.Distance( backEnd.viewDef->renderView.vieworg ); + const float s = vLight->fogPlane.Distance( viewDef->renderView.vieworg ); const float FOG_SCALE = 0.001f; idPlane fogPlanes[4]; // S-0 - fogPlanes[0][0] = a * backEnd.viewDef->worldSpace.modelViewMatrix[0 * 4 + 2]; - fogPlanes[0][1] = a * backEnd.viewDef->worldSpace.modelViewMatrix[1 * 4 + 2]; - fogPlanes[0][2] = a * backEnd.viewDef->worldSpace.modelViewMatrix[2 * 4 + 2]; - fogPlanes[0][3] = a * backEnd.viewDef->worldSpace.modelViewMatrix[3 * 4 + 2] + 0.5f; + fogPlanes[0][0] = a * viewDef->worldSpace.modelViewMatrix[0 * 4 + 2]; + fogPlanes[0][1] = a * viewDef->worldSpace.modelViewMatrix[1 * 4 + 2]; + fogPlanes[0][2] = a * viewDef->worldSpace.modelViewMatrix[2 * 4 + 2]; + fogPlanes[0][3] = a * viewDef->worldSpace.modelViewMatrix[3 * 4 + 2] + 0.5f; // T-0 fogPlanes[1][0] = 0.0f;//a * backEnd.viewDef->worldSpace.modelViewMatrix[0*4+0]; @@ -4210,9 +4356,9 @@ static void RB_FogPass( const drawSurf_t* drawSurfs, const drawSurf_t* drawSurf GL_State( GLS_DEPTHMASK | GLS_SRCBLEND_SRC_ALPHA | GLS_DSTBLEND_ONE_MINUS_SRC_ALPHA | GLS_DEPTHFUNC_LESS ); GL_Cull( CT_BACK_SIDED ); - backEnd.zeroOneCubeSurface.space = &backEnd.viewDef->worldSpace; - backEnd.zeroOneCubeSurface.scissorRect = backEnd.viewDef->scissor; - RB_T_BasicFog( &backEnd.zeroOneCubeSurface, fogPlanes, &vLight->inverseBaseLightProject ); + zeroOneCubeSurface.space = &viewDef->worldSpace; + zeroOneCubeSurface.scissorRect = viewDef->scissor; + T_BasicFog( &zeroOneCubeSurface, fogPlanes, &vLight->inverseBaseLightProject ); GL_Cull( CT_FRONT_SIDED ); @@ -4228,13 +4374,13 @@ static void RB_FogPass( const drawSurf_t* drawSurfs, const drawSurf_t* drawSurf /* ================== -RB_FogAllLights +idRenderBackend::FogAllLights ================== */ -static void RB_FogAllLights() +void idRenderBackend::FogAllLights() { if( r_skipFogLights.GetBool() || r_showOverDraw.GetInteger() != 0 - || backEnd.viewDef->isXraySubview /* don't fog in xray mode*/ ) + || viewDef->isXraySubview /* don't fog in xray mode*/ ) { return; } @@ -4242,17 +4388,17 @@ static void RB_FogAllLights() renderLog.OpenBlock( "RB_FogAllLights" ); // force fog plane to recalculate - backEnd.currentSpace = NULL; + currentSpace = NULL; - for( viewLight_t* vLight = backEnd.viewDef->viewLights; vLight != NULL; vLight = vLight->next ) + for( viewLight_t* vLight = viewDef->viewLights; vLight != NULL; vLight = vLight->next ) { if( vLight->lightShader->IsFogLight() ) { - RB_FogPass( vLight->globalInteractions, vLight->localInteractions, vLight ); + FogPass( vLight->globalInteractions, vLight->localInteractions, vLight ); } else if( vLight->lightShader->IsBlendLight() ) { - RB_BlendLight( vLight->globalInteractions, vLight->localInteractions, vLight ); + BlendLight( vLight->globalInteractions, vLight->localInteractions, vLight ); } } @@ -4261,7 +4407,7 @@ static void RB_FogAllLights() } // RB begin -static void RB_CalculateAdaptation() +void idRenderBackend::CalculateAutomaticExposure() { int i; static float image[64 * 64 * 4]; @@ -4280,9 +4426,9 @@ static void RB_CalculateAdaptation() { // no dynamic exposure - backEnd.hdrKey = r_hdrKey.GetFloat(); - backEnd.hdrAverageLuminance = r_hdrMinLuminance.GetFloat(); - backEnd.hdrMaxLuminance = 1; + hdrKey = r_hdrKey.GetFloat(); + hdrAverageLuminance = r_hdrMinLuminance.GetFloat(); + hdrMaxLuminance = 1; } else { @@ -4327,37 +4473,37 @@ static void RB_CalculateAdaptation() // adapted luminance and current luminance by 2% every frame, based on a // 30 fps rate. This is not an accurate model of human adaptation, which can // take longer than half an hour. - if( backEnd.hdrTime > curTime ) + if( hdrTime > curTime ) { - backEnd.hdrTime = curTime; + hdrTime = curTime; } - deltaTime = curTime - backEnd.hdrTime; + deltaTime = curTime - hdrTime; //if(r_hdrMaxLuminance->value) { - backEnd.hdrAverageLuminance = idMath::ClampFloat( r_hdrMinLuminance.GetFloat(), r_hdrMaxLuminance.GetFloat(), backEnd.hdrAverageLuminance ); + hdrAverageLuminance = idMath::ClampFloat( r_hdrMinLuminance.GetFloat(), r_hdrMaxLuminance.GetFloat(), backEnd.hdrAverageLuminance ); avgLuminance = idMath::ClampFloat( r_hdrMinLuminance.GetFloat(), r_hdrMaxLuminance.GetFloat(), avgLuminance ); - backEnd.hdrMaxLuminance = idMath::ClampFloat( r_hdrMinLuminance.GetFloat(), r_hdrMaxLuminance.GetFloat(), backEnd.hdrMaxLuminance ); + hdrMaxLuminance = idMath::ClampFloat( r_hdrMinLuminance.GetFloat(), r_hdrMaxLuminance.GetFloat(), backEnd.hdrMaxLuminance ); maxLuminance = idMath::ClampFloat( r_hdrMinLuminance.GetFloat(), r_hdrMaxLuminance.GetFloat(), maxLuminance ); } - newAdaptation = backEnd.hdrAverageLuminance + ( avgLuminance - backEnd.hdrAverageLuminance ) * ( 1.0f - powf( 0.98f, 30.0f * deltaTime ) ); - newMaximum = backEnd.hdrMaxLuminance + ( maxLuminance - backEnd.hdrMaxLuminance ) * ( 1.0f - powf( 0.98f, 30.0f * deltaTime ) ); + newAdaptation = hdrAverageLuminance + ( avgLuminance - hdrAverageLuminance ) * ( 1.0f - powf( 0.98f, 30.0f * deltaTime ) ); + newMaximum = hdrMaxLuminance + ( maxLuminance - hdrMaxLuminance ) * ( 1.0f - powf( 0.98f, 30.0f * deltaTime ) ); if( !IsNAN( newAdaptation ) && !IsNAN( newMaximum ) ) { #if 1 - backEnd.hdrAverageLuminance = newAdaptation; - backEnd.hdrMaxLuminance = newMaximum; + hdrAverageLuminance = newAdaptation; + hdrMaxLuminance = newMaximum; #else - backEnd.hdrAverageLuminance = avgLuminance; - backEnd.hdrMaxLuminance = maxLuminance; + hdrAverageLuminance = avgLuminance; + hdrMaxLuminance = maxLuminance; #endif } - backEnd.hdrTime = curTime; + hdrTime = curTime; // calculate HDR image key #if 0 @@ -4365,27 +4511,27 @@ static void RB_CalculateAdaptation() if( r_hdrAutoExposure.GetBool() ) { // calculation from: Perceptual Effects in Real-time Tone Mapping - Krawczyk et al. - backEnd.hdrKey = 1.03 - ( 2.0 / ( 2.0 + ( backEnd.hdrAverageLuminance + 1.0f ) ) ); + hdrKey = 1.03 - ( 2.0 / ( 2.0 + ( hdrAverageLuminance + 1.0f ) ) ); } else #endif { - backEnd.hdrKey = r_hdrKey.GetFloat(); + hdrKey = r_hdrKey.GetFloat(); } } if( r_hdrDebug.GetBool() ) { - idLib::Printf( "HDR luminance avg = %f, max = %f, key = %f\n", backEnd.hdrAverageLuminance, backEnd.hdrMaxLuminance, backEnd.hdrKey ); + idLib::Printf( "HDR luminance avg = %f, max = %f, key = %f\n", hdrAverageLuminance, hdrMaxLuminance, hdrKey ); } //GL_CheckErrors(); } -static void RB_Tonemap( const viewDef_t* viewDef ) +void idRenderBackend::Tonemap( const viewDef_t* _viewDef ) { - RENDERLOG_PRINTF( "---------- RB_Tonemap( avg = %f, max = %f, key = %f, is2Dgui = %i ) ----------\n", backEnd.hdrAverageLuminance, backEnd.hdrMaxLuminance, backEnd.hdrKey, ( int )viewDef->is2Dgui ); + RENDERLOG_PRINTF( "---------- RB_Tonemap( avg = %f, max = %f, key = %f, is2Dgui = %i ) ----------\n", hdrAverageLuminance, hdrMaxLuminance, hdrKey, ( int )viewDef->is2Dgui ); //postProcessCommand_t* cmd = ( postProcessCommand_t* )data; //const idScreenRect& viewport = cmd->viewDef->viewport; @@ -4429,7 +4575,7 @@ static void RB_Tonemap( const viewDef_t* viewDef ) } float screenCorrectionParm[4]; - if( viewDef->is2Dgui ) + if( _viewDef->is2Dgui ) { screenCorrectionParm[0] = 2.0f; screenCorrectionParm[1] = 1.0f; @@ -4441,9 +4587,9 @@ static void RB_Tonemap( const viewDef_t* viewDef ) { float exposureOffset = Lerp( -0.01f, 0.02f, idMath::ClampFloat( 0.0, 1.0, r_exposure.GetFloat() ) ); - screenCorrectionParm[0] = backEnd.hdrKey + exposureOffset; - screenCorrectionParm[1] = backEnd.hdrAverageLuminance; - screenCorrectionParm[2] = backEnd.hdrMaxLuminance; + screenCorrectionParm[0] = hdrKey + exposureOffset; + screenCorrectionParm[1] = hdrAverageLuminance; + screenCorrectionParm[2] = hdrMaxLuminance; screenCorrectionParm[3] = exposureOffset; //screenCorrectionParm[3] = Lerp( -1, 5, idMath::ClampFloat( 0.0, 1.0, r_exposure.GetFloat() ) ); } @@ -4467,7 +4613,7 @@ static void RB_Tonemap( const viewDef_t* viewDef ) SetFragmentParm( RENDERPARM_SCREENCORRECTIONFACTOR, screenCorrectionParm ); // rpScreenCorrectionFactor // Draw - RB_DrawElementsWithCounters( &backEnd.unitSquareSurface ); + DrawElementsWithCounters( &unitSquareSurface ); // unbind heatmap globalImages->BindNull(); @@ -4483,14 +4629,14 @@ static void RB_Tonemap( const viewDef_t* viewDef ) } -static void RB_Bloom( const viewDef_t* viewDef ) +void idRenderBackend::Bloom( const viewDef_t* _viewDef ) { - if( viewDef->is2Dgui || !r_useHDR.GetBool() ) + if( _viewDef->is2Dgui || !r_useHDR.GetBool() ) { return; } - RENDERLOG_PRINTF( "---------- RB_Bloom( avg = %f, max = %f, key = %f ) ----------\n", backEnd.hdrAverageLuminance, backEnd.hdrMaxLuminance, backEnd.hdrKey ); + RENDERLOG_PRINTF( "---------- RB_Bloom( avg = %f, max = %f, key = %f ) ----------\n", hdrAverageLuminance, hdrMaxLuminance, hdrKey ); // BRIGHTPASS @@ -4524,10 +4670,10 @@ static void RB_Bloom( const viewDef_t* viewDef ) } else { - int x = backEnd.viewDef->viewport.x1; - int y = backEnd.viewDef->viewport.y1; - int w = backEnd.viewDef->viewport.x2 - backEnd.viewDef->viewport.x1 + 1; - int h = backEnd.viewDef->viewport.y2 - backEnd.viewDef->viewport.y1 + 1; + int x = viewDef->viewport.x1; + int y = viewDef->viewport.y1; + int w = viewDef->viewport.x2 - viewDef->viewport.x1 + 1; + int h = viewDef->viewport.y2 - viewDef->viewport.y1 + 1; RENDERLOG_PRINTF( "Resolve to %i x %i buffer\n", w, h ); @@ -4538,9 +4684,9 @@ static void RB_Bloom( const viewDef_t* viewDef ) } float screenCorrectionParm[4]; - screenCorrectionParm[0] = backEnd.hdrKey; - screenCorrectionParm[1] = backEnd.hdrAverageLuminance; - screenCorrectionParm[2] = backEnd.hdrMaxLuminance; + screenCorrectionParm[0] = hdrKey; + screenCorrectionParm[1] = hdrAverageLuminance; + screenCorrectionParm[2] = hdrMaxLuminance; screenCorrectionParm[3] = 1.0f; SetFragmentParm( RENDERPARM_SCREENCORRECTIONFACTOR, screenCorrectionParm ); // rpScreenCorrectionFactor @@ -4569,7 +4715,7 @@ static void RB_Bloom( const viewDef_t* viewDef ) SetFragmentParm( RENDERPARM_OVERBRIGHT, overbright ); // rpOverbright // Draw - RB_DrawElementsWithCounters( &backEnd.unitSquareSurface ); + DrawElementsWithCounters( &unitSquareSurface ); // BLOOM PING PONG rendering @@ -4583,13 +4729,13 @@ static void RB_Bloom( const viewDef_t* viewDef ) globalImages->bloomRenderImage[j % 2]->Bind(); - RB_DrawElementsWithCounters( &backEnd.unitSquareSurface ); + DrawElementsWithCounters( &unitSquareSurface ); } // add filtered glare back to main context Framebuffer::Unbind(); - RB_ResetViewportAndScissorToDefaultCamera( viewDef ); + ResetViewportAndScissorToDefaultCamera( _viewDef ); GL_State( GLS_SRCBLEND_ONE | GLS_DSTBLEND_ONE | GLS_DEPTHMASK | GLS_DEPTHFUNC_ALWAYS ); @@ -4597,7 +4743,7 @@ static void RB_Bloom( const viewDef_t* viewDef ) globalImages->bloomRenderImage[( j + 1 ) % 2]->Bind(); - RB_DrawElementsWithCounters( &backEnd.unitSquareSurface ); + DrawElementsWithCounters( &unitSquareSurface ); globalImages->BindNull(); @@ -4609,9 +4755,9 @@ static void RB_Bloom( const viewDef_t* viewDef ) } -static void RB_SSAO( const viewDef_t* viewDef ) +void idRenderBackend::DrawScreenSpaceAmbientOcclusion( const viewDef_t* _viewDef ) { - if( !viewDef->viewEntitys || viewDef->is2Dgui ) + if( !_viewDef->viewEntitys || _viewDef->is2Dgui ) { // 3D views only return; @@ -4623,7 +4769,7 @@ static void RB_SSAO( const viewDef_t* viewDef ) } // FIXME very expensive to enable this in subviews - if( viewDef->isSubview ) + if( _viewDef->isSubview ) { return; } @@ -4705,8 +4851,8 @@ static void RB_SSAO( const viewDef_t* viewDef ) RB_SetMVP( motionMatrix ); #endif - backEnd.currentSpace = &backEnd.viewDef->worldSpace; - RB_SetMVP( backEnd.viewDef->worldSpace.mvp ); + currentSpace = &viewDef->worldSpace; + RB_SetMVP( viewDef->worldSpace.mvp ); const bool hdrIsActive = ( r_useHDR.GetBool() && globalFramebuffers.hdrFBO != NULL && globalFramebuffers.hdrFBO->IsBound() ); @@ -4764,7 +4910,7 @@ static void RB_SSAO( const viewDef_t* viewDef ) SetFragmentParm( RENDERPARM_SCREENCORRECTIONFACTOR, screenCorrectionParm ); // rpScreenCorrectionFactor #endif - RB_DrawElementsWithCounters( &backEnd.unitSquareSurface ); + DrawElementsWithCounters( &unitSquareSurface ); } } @@ -4854,7 +5000,7 @@ static void RB_SSAO( const viewDef_t* viewDef ) globalImages->currentDepthImage->Bind(); } - RB_DrawElementsWithCounters( &backEnd.unitSquareSurface ); + DrawElementsWithCounters( &unitSquareSurface ); if( r_ssaoFiltering.GetBool() ) { @@ -4876,7 +5022,7 @@ static void RB_SSAO( const viewDef_t* viewDef ) GL_SelectTexture( 2 ); globalImages->ambientOcclusionImage[0]->Bind(); - RB_DrawElementsWithCounters( &backEnd.unitSquareSurface ); + DrawElementsWithCounters( &unitSquareSurface ); #endif // AO blur Y @@ -4906,7 +5052,7 @@ static void RB_SSAO( const viewDef_t* viewDef ) GL_SelectTexture( 2 ); globalImages->ambientOcclusionImage[1]->Bind(); - RB_DrawElementsWithCounters( &backEnd.unitSquareSurface ); + DrawElementsWithCounters( &unitSquareSurface ); } renderProgManager.Unbind(); @@ -4917,9 +5063,9 @@ static void RB_SSAO( const viewDef_t* viewDef ) //GL_CheckErrors(); } -static void RB_SSGI( const viewDef_t* viewDef ) +void idRenderBackend::DrawScreenSpaceGlobalIllumination( const viewDef_t* _viewDef ) { - if( !viewDef->viewEntitys || viewDef->is2Dgui ) + if( !_viewDef->viewEntitys || _viewDef->is2Dgui ) { // 3D views only return; @@ -4931,15 +5077,15 @@ static void RB_SSGI( const viewDef_t* viewDef ) } // FIXME very expensive to enable this in subviews - if( viewDef->isSubview ) + if( _viewDef->isSubview ) { return; } RENDERLOG_PRINTF( "---------- RB_SSGI() ----------\n" ); - backEnd.currentSpace = &backEnd.viewDef->worldSpace; - RB_SetMVP( backEnd.viewDef->worldSpace.mvp ); + currentSpace = &viewDef->worldSpace; + RB_SetMVP( viewDef->worldSpace.mvp ); const bool hdrIsActive = ( r_useHDR.GetBool() && globalFramebuffers.hdrFBO != NULL && globalFramebuffers.hdrFBO->IsBound() ); @@ -5007,7 +5153,7 @@ static void RB_SSGI( const viewDef_t* viewDef ) SetFragmentParm( RENDERPARM_SCREENCORRECTIONFACTOR, screenCorrectionParm ); // rpScreenCorrectionFactor #endif - RB_DrawElementsWithCounters( &backEnd.unitSquareSurface ); + DrawElementsWithCounters( &unitSquareSurface ); } } @@ -5114,7 +5260,7 @@ static void RB_SSGI( const viewDef_t* viewDef ) globalImages->currentRenderImage->Bind(); } - RB_DrawElementsWithCounters( &backEnd.unitSquareSurface ); + DrawElementsWithCounters( &unitSquareSurface ); if( r_ssgiFiltering.GetBool() ) { @@ -5136,7 +5282,7 @@ static void RB_SSGI( const viewDef_t* viewDef ) GL_SelectTexture( 2 ); globalImages->ambientOcclusionImage[0]->Bind(); - RB_DrawElementsWithCounters( &backEnd.unitSquareSurface ); + DrawElementsWithCounters( &unitSquareSurface ); #endif // AO blur Y @@ -5172,7 +5318,7 @@ static void RB_SSGI( const viewDef_t* viewDef ) GL_SelectTexture( 2 ); globalImages->ambientOcclusionImage[1]->Bind(); - RB_DrawElementsWithCounters( &backEnd.unitSquareSurface ); + DrawElementsWithCounters( &unitSquareSurface ); } renderProgManager.Unbind(); @@ -5194,10 +5340,10 @@ BACKEND COMMANDS /* ================== -RB_DrawViewInternal +idRenderBackend::DrawViewInternal ================== */ -void RB_DrawViewInternal( const viewDef_t* viewDef, const int stereoEye ) +void idRenderBackend::DrawViewInternal( const viewDef_t* _viewDef, const int stereoEye ) { renderLog.OpenBlock( "RB_DrawViewInternal" ); @@ -5206,12 +5352,12 @@ void RB_DrawViewInternal( const viewDef_t* viewDef, const int stereoEye ) // this used to be in the gui emit code, but now that it can be running // in a separate thread, it must not try to load images, so do it here. //------------------------------------------------- - drawSurf_t** drawSurfs = ( drawSurf_t** )&viewDef->drawSurfs[0]; - const int numDrawSurfs = viewDef->numDrawSurfs; + drawSurf_t** drawSurfs = ( drawSurf_t** )&_viewDef->drawSurfs[0]; + const int numDrawSurfs = _viewDef->numDrawSurfs; for( int i = 0; i < numDrawSurfs; i++ ) { - const drawSurf_t* ds = viewDef->drawSurfs[ i ]; + const drawSurf_t* ds = _viewDef->drawSurfs[ i ]; if( ds->material != NULL ) { const_cast( ds->material )->EnsureNotPurged(); @@ -5226,9 +5372,9 @@ void RB_DrawViewInternal( const viewDef_t* viewDef, const int stereoEye ) // // clear the z buffer, set the projection matrix, etc //------------------------------------------------- - RB_ResetViewportAndScissorToDefaultCamera( viewDef ); + ResetViewportAndScissorToDefaultCamera( _viewDef ); - backEnd.glState.faceCulling = -1; // force face culling to set next time + faceCulling = -1; // force face culling to set next time // ensures that depth writes are enabled for the depth clear GL_State( GLS_DEFAULT ); @@ -5236,7 +5382,7 @@ void RB_DrawViewInternal( const viewDef_t* viewDef, const int stereoEye ) //GL_CheckErrors(); // RB begin - bool useHDR = r_useHDR.GetBool() && !viewDef->is2Dgui; + bool useHDR = r_useHDR.GetBool() && !_viewDef->is2Dgui; // Clear the depth buffer and clear the stencil to 128 for stencil shadows as well as gui masking GL_Clear( false, true, true, STENCIL_SHADOW_TEST_VALUE, 0.0f, 0.0f, 0.0f, 0.0f, useHDR ); @@ -5269,9 +5415,9 @@ void RB_DrawViewInternal( const viewDef_t* viewDef, const int stereoEye ) // set eye position in global space // float parm[4]; - parm[0] = backEnd.viewDef->renderView.vieworg[0]; - parm[1] = backEnd.viewDef->renderView.vieworg[1]; - parm[2] = backEnd.viewDef->renderView.vieworg[2]; + parm[0] = viewDef->renderView.vieworg[0]; + parm[1] = viewDef->renderView.vieworg[1]; + parm[2] = viewDef->renderView.vieworg[2]; parm[3] = 1.0f; SetVertexParm( RENDERPARM_GLOBALEYEPOS, parm ); // rpGlobalEyePos @@ -5290,46 +5436,46 @@ void RB_DrawViewInternal( const viewDef_t* viewDef, const int stereoEye ) // Set Projection Matrix float projMatrixTranspose[16]; - R_MatrixTranspose( backEnd.viewDef->projectionMatrix, projMatrixTranspose ); + R_MatrixTranspose( viewDef->projectionMatrix, projMatrixTranspose ); SetVertexParms( RENDERPARM_PROJMATRIX_X, projMatrixTranspose, 4 ); } //------------------------------------------------- // fill the depth buffer and clear color buffer to black except on subviews //------------------------------------------------- - RB_FillDepthBufferFast( drawSurfs, numDrawSurfs ); + FillDepthBufferFast( drawSurfs, numDrawSurfs ); //------------------------------------------------- // FIXME, OPTIMIZE: merge this with FillDepthBufferFast like in a light prepass deferred renderer // // fill the geometric buffer with normals and roughness //------------------------------------------------- - RB_AmbientPass( drawSurfs, numDrawSurfs, true ); + AmbientPass( drawSurfs, numDrawSurfs, true ); //------------------------------------------------- // fill the depth buffer and the color buffer with precomputed Q3A style lighting //------------------------------------------------- - RB_AmbientPass( drawSurfs, numDrawSurfs, false ); + AmbientPass( drawSurfs, numDrawSurfs, false ); //------------------------------------------------- // main light renderer //------------------------------------------------- - RB_DrawInteractions( viewDef ); + DrawInteractions( _viewDef ); //------------------------------------------------- // capture the depth for the motion blur before rendering any post process surfaces that may contribute to the depth //------------------------------------------------- if( ( r_motionBlur.GetInteger() > 0 || r_useSSAO.GetBool() || r_useSSGI.GetBool() ) && !r_useHDR.GetBool() ) { - const idScreenRect& viewport = backEnd.viewDef->viewport; + const idScreenRect& viewport = viewDef->viewport; globalImages->currentDepthImage->CopyDepthbuffer( viewport.x1, viewport.y1, viewport.GetWidth(), viewport.GetHeight() ); } //------------------------------------------------- // darken the scene using the screen space ambient occlusion //------------------------------------------------- - RB_SSAO( viewDef ); - //RB_SSGI( viewDef ); + DrawScreenSpaceAmbientOcclusion( _viewDef ); + //RB_SSGI( _viewDef ); //------------------------------------------------- // now draw any non-light dependent shading passes @@ -5339,16 +5485,16 @@ void RB_DrawViewInternal( const viewDef_t* viewDef, const int stereoEye ) { renderLog.OpenMainBlock( MRB_DRAW_SHADER_PASSES ); float guiScreenOffset; - if( viewDef->viewEntitys != NULL ) + if( _viewDef->viewEntitys != NULL ) { // guiScreenOffset will be 0 in non-gui views guiScreenOffset = 0.0f; } else { - guiScreenOffset = stereoEye * viewDef->renderView.stereoScreenSeparation; + guiScreenOffset = stereoEye * _viewDef->renderView.stereoScreenSeparation; } - processed = RB_DrawShaderPasses( drawSurfs, numDrawSurfs, guiScreenOffset, stereoEye ); + processed = DrawShaderPasses( drawSurfs, numDrawSurfs, guiScreenOffset, stereoEye ); renderLog.CloseMainBlock(); } @@ -5361,17 +5507,17 @@ void RB_DrawViewInternal( const viewDef_t* viewDef, const int stereoEye ) // fog and blend lights, drawn after emissive surfaces // so they are properly dimmed down //------------------------------------------------- - RB_FogAllLights(); + FogAllLights(); //------------------------------------------------- // now draw any screen warping post-process effects using _currentRender //------------------------------------------------- if( processed < numDrawSurfs && !r_skipPostProcess.GetBool() ) { - int x = backEnd.viewDef->viewport.x1; - int y = backEnd.viewDef->viewport.y1; - int w = backEnd.viewDef->viewport.x2 - backEnd.viewDef->viewport.x1 + 1; - int h = backEnd.viewDef->viewport.y2 - backEnd.viewDef->viewport.y1 + 1; + int x = viewDef->viewport.x1; + int y = viewDef->viewport.y1; + int w = viewDef->viewport.x2 - viewDef->viewport.x1 + 1; + int h = viewDef->viewport.y2 - viewDef->viewport.y1 + 1; RENDERLOG_PRINTF( "Resolve to %i x %i buffer\n", w, h ); @@ -5379,7 +5525,7 @@ void RB_DrawViewInternal( const viewDef_t* viewDef, const int stereoEye ) // resolve the screen globalImages->currentRenderImage->CopyFramebuffer( x, y, w, h ); - backEnd.currentRenderCopied = true; + currentRenderCopied = true; // RENDERPARM_SCREENCORRECTIONFACTOR amd RENDERPARM_WINDOWCOORD overlap // diffuseScale and specularScale @@ -5402,7 +5548,7 @@ void RB_DrawViewInternal( const viewDef_t* viewDef, const int stereoEye ) // render the remaining surfaces renderLog.OpenMainBlock( MRB_DRAW_SHADER_PASSES_POST ); - RB_DrawShaderPasses( drawSurfs + processed, numDrawSurfs - processed, 0.0f /* definitely not a gui */, stereoEye ); + DrawShaderPasses( drawSurfs + processed, numDrawSurfs - processed, 0.0f /* definitely not a gui */, stereoEye ); renderLog.CloseMainBlock(); } @@ -5464,12 +5610,12 @@ void RB_DrawViewInternal( const viewDef_t* viewDef, const int stereoEye ) GL_LINEAR ); } - RB_CalculateAdaptation(); + CalculateAutomaticExposure(); - RB_Tonemap( viewDef ); + Tonemap( _viewDef ); } - RB_Bloom( viewDef ); + Bloom( _viewDef ); // RB end renderLog.CloseBlock(); @@ -5482,9 +5628,9 @@ RB_MotionBlur Experimental feature ================== */ -void RB_MotionBlur() +void idRenderBackend::MotionBlur() { - if( !backEnd.viewDef->viewEntitys ) + if( !viewDef->viewEntitys ) { // 3D views only return; @@ -5493,7 +5639,7 @@ void RB_MotionBlur() { return; } - if( backEnd.viewDef->isSubview ) + if( viewDef->isSubview ) { return; } @@ -5508,10 +5654,10 @@ void RB_MotionBlur() GL_Color( 0, 0, 0, 0 ); GL_SelectTexture( 0 ); globalImages->blackImage->Bind(); - backEnd.currentSpace = NULL; + currentSpace = NULL; - drawSurf_t** drawSurfs = ( drawSurf_t** )&backEnd.viewDef->drawSurfs[0]; - for( int surfNum = 0; surfNum < backEnd.viewDef->numDrawSurfs; surfNum++ ) + drawSurf_t** drawSurfs = ( drawSurf_t** )&viewDef->drawSurfs[0]; + for( int surfNum = 0; surfNum < viewDef->numDrawSurfs; surfNum++ ) { const drawSurf_t* surf = drawSurfs[ surfNum ]; @@ -5529,10 +5675,10 @@ void RB_MotionBlur() } // set mvp matrix - if( surf->space != backEnd.currentSpace ) + if( surf->space != currentSpace ) { RB_SetMVP( surf->space->mvp ); - backEnd.currentSpace = surf->space; + currentSpace = surf->space; } // this could just be a color, but we don't have a skinned color-only prog @@ -5546,26 +5692,27 @@ void RB_MotionBlur() } // draw it solid - RB_DrawElementsWithCounters( surf ); + DrawElementsWithCounters( surf ); } + GL_State( GLS_DEPTHFUNC_ALWAYS ); // copy off the color buffer and the depth buffer for the motion blur prog // we use the viewport dimensions for copying the buffers in case resolution scaling is enabled. - const idScreenRect& viewport = backEnd.viewDef->viewport; + const idScreenRect& viewport = viewDef->viewport; globalImages->currentRenderImage->CopyFramebuffer( viewport.x1, viewport.y1, viewport.GetWidth(), viewport.GetHeight() ); // in stereo rendering, each eye needs to get a separate previous frame mvp - int mvpIndex = ( backEnd.viewDef->renderView.viewEyeBuffer == 1 ) ? 1 : 0; + int mvpIndex = ( viewDef->renderView.viewEyeBuffer == 1 ) ? 1 : 0; // derive the matrix to go from current pixels to previous frame pixels idRenderMatrix inverseMVP; - idRenderMatrix::Inverse( backEnd.viewDef->worldSpace.mvp, inverseMVP ); + idRenderMatrix::Inverse( viewDef->worldSpace.mvp, inverseMVP ); idRenderMatrix motionMatrix; - idRenderMatrix::Multiply( backEnd.prevMVP[mvpIndex], inverseMVP, motionMatrix ); + idRenderMatrix::Multiply( prevMVP[mvpIndex], inverseMVP, motionMatrix ); - backEnd.prevMVP[mvpIndex] = backEnd.viewDef->worldSpace.mvp; + prevMVP[mvpIndex] = viewDef->worldSpace.mvp; RB_SetMVP( motionMatrix ); @@ -5583,38 +5730,38 @@ void RB_MotionBlur() GL_SelectTexture( 1 ); globalImages->currentDepthImage->Bind(); - RB_DrawElementsWithCounters( &backEnd.unitSquareSurface ); + DrawElementsWithCounters( &unitSquareSurface ); GL_CheckErrors(); } /* ================== -RB_DrawView +idRenderBackend::DrawView StereoEye will always be 0 in mono modes, or -1 / 1 in stereo modes. If the view is a GUI view that is repeated for both eyes, the viewDef.stereoEye value is 0, so the stereoEye parameter is not always the same as that. ================== */ -void RB_DrawView( const void* data, const int stereoEye ) +void idRenderBackend::DrawView( const void* data, const int stereoEye ) { const drawSurfsCommand_t* cmd = ( const drawSurfsCommand_t* )data; - backEnd.viewDef = cmd->viewDef; + viewDef = cmd->viewDef; // we will need to do a new copyTexSubImage of the screen // when a SS_POST_PROCESS material is used - backEnd.currentRenderCopied = false; + currentRenderCopied = false; // if there aren't any drawsurfs, do nothing - if( !backEnd.viewDef->numDrawSurfs ) + if( !viewDef->numDrawSurfs ) { return; } // skip render bypasses everything that has models, assuming // them to be 3D views, but leaves 2D rendering visible - if( r_skipRender.GetBool() && backEnd.viewDef->viewEntitys ) + if( r_skipRender.GetBool() && viewDef->viewEntitys ) { return; } @@ -5630,14 +5777,14 @@ void RB_DrawView( const void* data, const int stereoEye ) //} // RB end - backEnd.pc.c_surfaces += backEnd.viewDef->numDrawSurfs; + pc.c_surfaces += viewDef->numDrawSurfs; RB_ShowOverdraw(); // render the scene - RB_DrawViewInternal( cmd->viewDef, stereoEye ); + DrawViewInternal( cmd->viewDef, stereoEye ); - RB_MotionBlur(); + MotionBlur(); // restore the context for 2D drawing if we were stubbing it out // RB: not really needed @@ -5651,7 +5798,7 @@ void RB_DrawView( const void* data, const int stereoEye ) // optionally draw a box colored based on the eye number if( r_drawEyeColor.GetBool() ) { - const idScreenRect& r = backEnd.viewDef->viewport; + const idScreenRect& r = viewDef->viewport; GL_Scissor( ( r.x1 + r.x2 ) / 2, ( r.y1 + r.y2 ) / 2, 32, 32 ); switch( stereoEye ) { @@ -5670,12 +5817,12 @@ void RB_DrawView( const void* data, const int stereoEye ) /* ================== -RB_CopyRender +idRenderBackend::CopyRender Copy part of the current framebuffer to an image ================== */ -void RB_CopyRender( const void* data ) +void idRenderBackend::CopyRender( const void* data ) { const copyRenderCommand_t* cmd = ( const copyRenderCommand_t* )data; @@ -5699,14 +5846,13 @@ void RB_CopyRender( const void* data ) /* ================== -RB_PostProcess +idRenderBackend::PostProcess ================== */ extern idCVar rs_enable; -void RB_PostProcess( const void* data ) +void idRenderBackend::PostProcess( const void* data ) { - // only do the post process step if resolution scaling is enabled. Prevents the unnecessary copying of the framebuffer and // corresponding full screen quad pass. if( rs_enable.GetInteger() == 0 && !r_useFilmicPostProcessEffects.GetBool() && r_antiAliasing.GetInteger() == 0 ) @@ -5776,7 +5922,7 @@ void RB_PostProcess( const void* data ) globalImages->smaaInputImage->Bind(); renderProgManager.BindShader_SMAA_EdgeDetection(); - RB_DrawElementsWithCounters( &backEnd.unitSquareSurface ); + DrawElementsWithCounters( &unitSquareSurface ); #if 1 //globalImages->smaaEdgesImage->CopyFramebuffer( viewport.x1, viewport.y1, viewport.GetWidth(), viewport.GetHeight() ); @@ -5796,7 +5942,7 @@ void RB_PostProcess( const void* data ) globalImages->smaaSearchImage->Bind(); renderProgManager.BindShader_SMAA_BlendingWeightCalculation(); - RB_DrawElementsWithCounters( &backEnd.unitSquareSurface ); + DrawElementsWithCounters( &unitSquareSurface ); Framebuffer::Unbind(); #endif @@ -5814,7 +5960,7 @@ void RB_PostProcess( const void* data ) globalImages->smaaBlendImage->Bind(); renderProgManager.BindShader_SMAA_NeighborhoodBlending(); - RB_DrawElementsWithCounters( &backEnd.unitSquareSurface ); + DrawElementsWithCounters( &unitSquareSurface ); #endif } @@ -5857,7 +6003,7 @@ void RB_PostProcess( const void* data ) SetFragmentParm( RENDERPARM_JITTERTEXOFFSET, jitterTexOffset ); // rpJitterTexOffset // Draw - RB_DrawElementsWithCounters( &backEnd.unitSquareSurface ); + DrawElementsWithCounters( &unitSquareSurface ); } #endif diff --git a/neo/renderer/RenderBackend.h b/neo/renderer/RenderBackend.h new file mode 100644 index 00000000..6fba781a --- /dev/null +++ b/neo/renderer/RenderBackend.h @@ -0,0 +1,468 @@ +/* +=========================================================================== + +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 . + +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__ + +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 ); +void RB_SetupInteractionStage( const shaderStage_t* surfaceStage, const float* surfaceRegs, const float lightColor[4], idVec4 matrix[2], float color[4] ); + +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(); + +private: + void DrawFlickerBox(); + + void DrawElementsWithCounters( const drawSurf_t* surf ); + void DrawStencilShadowPass( const drawSurf_t* drawSurf, const bool renderZPass ); + + void SetColorMappings(); + void CheckCVars(); + 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_GetCurrentStateMinusStencil() const; + void GL_SetDefaultState(); + void GL_State( uint64 stateBits, bool forceGlState = false ); + void GL_SeparateStencil( stencilFace_t face, uint64 stencilBits ); + + 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 ); + } + + 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_ShowDestinationAlpha(); + 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_ShowPortals(); + void DBG_ShowDebugText(); + void DBG_ShowDebugLines(); + void DBG_ShowDebugPolygons(); + void DBG_ShowCenterOfProjection(); + void DBG_TestGamma(); + void DBG_TestGammaBias(); + void DBG_TestImage(); + 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; + +#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 \ No newline at end of file diff --git a/neo/renderer/RenderCommon.h b/neo/renderer/RenderCommon.h index f10dec92..4bbe26a2 100644 --- a/neo/renderer/RenderCommon.h +++ b/neo/renderer/RenderCommon.h @@ -675,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 { @@ -693,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; @@ -773,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, @@ -844,6 +789,7 @@ public: virtual void UnCrop(); virtual bool UploadImage( const char* imageName, const byte* data, int width, int height ); + void PrintPerformanceCounters(); public: @@ -927,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 @@ -1471,15 +1418,7 @@ 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 ); /* ============================================================ @@ -1490,7 +1429,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 ); diff --git a/neo/renderer/RenderSystem.cpp b/neo/renderer/RenderSystem.cpp index a5250a30..b20baae4 100644 --- a/neo/renderer/RenderSystem.cpp +++ b/neo/renderer/RenderSystem.cpp @@ -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 ); + ExecuteBackEndCommands( cmdHead ); glEndQuery( GL_TIME_ELAPSED_EXT ); glFlush(); } else #endif { - RB_ExecuteBackEndCommands( cmdHead ); + ExecuteBackEndCommands( cmdHead ); } } @@ -784,15 +784,15 @@ 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(); @@ -829,9 +829,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 From a54612c0be8b0f754ab93d8d6504668093c27539 Mon Sep 17 00:00:00 2001 From: Robert Beckebans Date: Sat, 9 Sep 2017 14:57:48 +0200 Subject: [PATCH 07/12] More renderer backend refactoring. DOES NOT COMPILE --- neo/renderer/GraphicsAPIWrapper.h | 129 ---- neo/renderer/OpenGL/Image_GL.cpp | 7 +- neo/renderer/OpenGL/RenderBackend_GL.cpp | 228 +++++- neo/renderer/OpenGL/gl_GraphicsAPIWrapper.cpp | 282 -------- neo/renderer/RenderBackend.cpp | 61 +- neo/renderer/RenderBackend.h | 64 +- neo/renderer/RenderCommon.h | 9 +- neo/renderer/RenderSystem.cpp | 4 +- neo/renderer/RenderSystem_init.cpp | 2 +- neo/renderer/RenderWorld_local.h | 1 - neo/renderer/RenderWorld_portals.cpp | 54 -- neo/renderer/tr_backend_rendertools.cpp | 647 +++++++----------- neo/renderer/tr_frontend_addlights.cpp | 2 +- neo/renderer/tr_frontend_addmodels.cpp | 2 +- 14 files changed, 554 insertions(+), 938 deletions(-) delete mode 100644 neo/renderer/GraphicsAPIWrapper.h delete mode 100644 neo/renderer/OpenGL/gl_GraphicsAPIWrapper.cpp diff --git a/neo/renderer/GraphicsAPIWrapper.h b/neo/renderer/GraphicsAPIWrapper.h deleted file mode 100644 index 4067626f..00000000 --- a/neo/renderer/GraphicsAPIWrapper.h +++ /dev/null @@ -1,129 +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 . - -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 - - - - - -// GPU time between GL_StartFrame() and GL_EndFrame() -void GL_StartDepthPass( const idScreenRect& rect ); -void GL_FinishDepthPass(); -void GL_GetDepthPassRect( idScreenRect& rect ); - -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 ); -} - - -void GL_PolygonOffset( float scale, float bias ); -void GL_DepthBoundsTest( const float zmin, const float zmax ); -//void GL_Color( float* color ); - -void GL_Color( float r, float g, float b ); -void GL_Color( float r, float g, float b, float a ); - - - -// 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 - - - - -#endif // !__GRAPHICSAPIWRAPPER_H__ diff --git a/neo/renderer/OpenGL/Image_GL.cpp b/neo/renderer/OpenGL/Image_GL.cpp index dd1c0979..2f4cc8ab 100644 --- a/neo/renderer/OpenGL/Image_GL.cpp +++ b/neo/renderer/OpenGL/Image_GL.cpp @@ -673,12 +673,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; } } diff --git a/neo/renderer/OpenGL/RenderBackend_GL.cpp b/neo/renderer/OpenGL/RenderBackend_GL.cpp index e130dc12..a4067561 100644 --- a/neo/renderer/OpenGL/RenderBackend_GL.cpp +++ b/neo/renderer/OpenGL/RenderBackend_GL.cpp @@ -157,7 +157,7 @@ void idRenderBackend::DrawElementsWithCounters( const drawSurf_t* surf ) if( ( vertexLayout != LAYOUT_DRAW_VERT ) || ( currentVertexBuffer != ( GLintptr )vertexBuffer->GetAPIObject() ) || !r_useStateCaching.GetBool() ) { glBindBuffer( GL_ARRAY_BUFFER, ( GLintptr )vertexBuffer->GetAPIObject() ); - backEnd.glState.currentVertexBuffer = ( GLintptr )vertexBuffer->GetAPIObject(); + currentVertexBuffer = ( GLintptr )vertexBuffer->GetAPIObject(); glEnableVertexAttribArray( PC_ATTRIB_INDEX_VERTEX ); glEnableVertexAttribArray( PC_ATTRIB_INDEX_NORMAL ); @@ -187,7 +187,7 @@ void idRenderBackend::DrawElementsWithCounters( const drawSurf_t* surf ) glVertexAttribPointer( PC_ATTRIB_INDEX_TANGENT, 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof( idDrawVert ), ( void* )( DRAWVERT_TANGENT_OFFSET ) ); #endif // #if defined(USE_GLES2) || defined(USE_GLES3) - backEnd.glState.vertexLayout = LAYOUT_DRAW_VERT; + vertexLayout = LAYOUT_DRAW_VERT; } // RB end @@ -205,8 +205,8 @@ void idRenderBackend::DrawElementsWithCounters( const drawSurf_t* surf ) #endif // RB: added stats - backEnd.pc.c_drawElements++; - backEnd.pc.c_drawIndexes += surf->numIndexes; + pc.c_drawElements++; + pc.c_drawIndexes += surf->numIndexes; // RB end } @@ -699,6 +699,195 @@ void idRenderBackend::GL_SelectTexture( int unit ) currenttmu = unit; } +/* +==================== +idRenderBackend::GL_Cull + +This handles the flipping needed when the view being +rendered is a mirored view. +==================== +*/ +void idRenderBackend::GL_Cull( cullType_t cullType ) +{ + if( faceCulling == cullType ) + { + return; + } + + if( cullType == CT_TWO_SIDED ) + { + glDisable( GL_CULL_FACE ); + } + else + { + if( faceCulling == CT_TWO_SIDED ) + { + glEnable( GL_CULL_FACE ); + } + + if( cullType == CT_BACK_SIDED ) + { + if( viewDef->isMirror ) + { + glCullFace( GL_FRONT ); + } + else + { + glCullFace( GL_BACK ); + } + } + else + { + if( viewDef->isMirror ) + { + glCullFace( GL_BACK ); + } + else + { + glCullFace( GL_FRONT ); + } + } + } + + faceCulling = cullType; +} + +/* +==================== +idRenderBackend::GL_Scissor +==================== +*/ +void idRenderBackend::GL_Scissor( int x /* left*/, int y /* bottom */, int w, int h ) +{ + glScissor( x, y, w, h ); +} + +/* +==================== +idRenderBackend::GL_Viewport +==================== +*/ +void idRenderBackend::GL_Viewport( int x /* left */, int y /* bottom */, int w, int h ) +{ + glViewport( x, y, w, h ); +} + +/* +==================== +idRenderBackend::GL_PolygonOffset +==================== +*/ +void idRenderBackend::GL_PolygonOffset( float scale, float bias ) +{ + polyOfsScale = scale; + polyOfsBias = bias; + + if( glStateBits & GLS_POLYGON_OFFSET ) + { + glPolygonOffset( scale, bias ); + } +} + +/* +======================== +idRenderBackend::GL_DepthBoundsTest +======================== +*/ +void idRenderBackend::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 ); + } +} + +/* +==================== +idRenderBackend::GL_Color +==================== +*/ +void idRenderBackend::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 ); +} + +/* +======================== +idRenderBackend::GL_Clear +======================== +*/ +void idRenderBackend::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 +} + + +/* +================= +idRenderBackend::GL_GetCurrentState +================= +*/ +uint64 idRenderBackend::GL_GetCurrentState() const +{ + return tr.backend.glStateBits; +} + +/* +======================== +idRenderBackend::GL_GetCurrentStateMinusStencil +======================== +*/ +uint64 idRenderBackend::GL_GetCurrentStateMinusStencil() const +{ + return GL_GetCurrentState() & ~( GLS_STENCIL_OP_BITS | GLS_STENCIL_FUNC_BITS | GLS_STENCIL_FUNC_REF_BITS | GLS_STENCIL_FUNC_MASK_BITS ); +} + + /* ============================================================================ @@ -865,13 +1054,7 @@ idRenderBackend::idRenderBackend */ idRenderBackend::idRenderBackend() { - memset( gammaTable, 0, sizeof( gammaTable ) ); - - glcontext.bAnisotropicFilterAvailable = false; - glcontext.bTextureLODBiasAvailable = false; - - memset( glcontext.tmu, 0, sizeof( glcontext.tmu ) ); - memset( glcontext.stencilOperations, 0, sizeof( glcontext.stencilOperations ) ); + Init(); } /* @@ -884,6 +1067,17 @@ idRenderBackend::~idRenderBackend() } +/* +============= +idRenderBackend::Init +============= +*/ +void idRenderBackend::Init() +{ + memset( glcontext.tmu, 0, sizeof( glcontext.tmu ) ); + memset( glcontext.stencilOperations, 0, sizeof( glcontext.stencilOperations ) ); +} + /* ==================== R_MakeStereoRenderImage @@ -953,6 +1147,7 @@ void idRenderBackend::StereoRenderExecuteBackEndCommands( const emptyCommand_t* // Set the back end into a known default state to fix any stale render state issues GL_SetDefaultState(); + renderProgManager.Unbind(); renderProgManager.ZeroUniforms(); @@ -975,7 +1170,7 @@ void idRenderBackend::StereoRenderExecuteBackEndCommands( const emptyCommand_t* } foundEye[ targetEye ] = true; - RB_DrawView( dsc, stereoEye ); + DrawView( dsc, stereoEye ); if( cmds->commandId == RC_DRAW_VIEW_GUI ) { } @@ -1056,7 +1251,7 @@ void idRenderBackend::StereoRenderExecuteBackEndCommands( const emptyCommand_t* stereoRenderImages[1]->Bind(); GL_SelectTexture( 0 ); stereoRenderImages[0]->Bind(); - RB_DrawElementsWithCounters( &unitSquareSurface ); + DrawElementsWithCounters( &unitSquareSurface ); break; case STEREO3D_HDMI_720: @@ -1184,7 +1379,7 @@ void idRenderBackend::StereoRenderExecuteBackEndCommands( const emptyCommand_t* GL_ViewportAndScissor( 0, 0, renderSystem->GetWidth(), renderSystem->GetHeight() * 2 ); renderProgManager.BindShader_StereoInterlace(); - RB_DrawElementsWithCounters( &unitSquareSurface ); + DrawElementsWithCounters( &unitSquareSurface ); GL_SelectTexture( 0 ); glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR ); @@ -1300,8 +1495,9 @@ void idRenderBackend::ExecuteBackEndCommands( const emptyCommand_t* cmds ) 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; + common->Printf( "3d: %i, 2d: %i, SetBuf: %i, CpyRenders: %i, CpyFrameBuf: %i\n", c_draw3d, c_draw2d, c_setBuffers, c_copyRenders, pc.c_copyFrameBuffer ); + pc.c_copyFrameBuffer = 0; } + renderLog.EndFrame(); } diff --git a/neo/renderer/OpenGL/gl_GraphicsAPIWrapper.cpp b/neo/renderer/OpenGL/gl_GraphicsAPIWrapper.cpp deleted file mode 100644 index e098f17a..00000000 --- a/neo/renderer/OpenGL/gl_GraphicsAPIWrapper.cpp +++ /dev/null @@ -1,282 +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 . - -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 "../RenderCommon.h" - - - -/* -==================== -GL_Cull - -This handles the flipping needed when the view being -rendered is a mirored view. -==================== -*/ -void GL_Cull( int cullType ) -{ - if( tr.backend.faceCulling == cullType ) - { - return; - } - - if( cullType == CT_TWO_SIDED ) - { - glDisable( GL_CULL_FACE ); - } - else - { - if( tr.backend.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 ); - } - } - } - - tr.backend.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 ) -{ - tr.backend.polyOfsScale = scale; - tr.backend.polyOfsBias = bias; - if( tr.backend.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 - -// 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_GetCurrentState -================= -*/ -uint64 GL_GetCurrentState() -{ - return tr.backend.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 ); -} diff --git a/neo/renderer/RenderBackend.cpp b/neo/renderer/RenderBackend.cpp index 6de8157e..09db961f 100644 --- a/neo/renderer/RenderBackend.cpp +++ b/neo/renderer/RenderBackend.cpp @@ -1095,8 +1095,6 @@ void idRenderBackend::FillDepthBufferFast( drawSurf_t** drawSurfs, int numDrawSu renderLog.OpenMainBlock( MRB_FILL_DEPTH_BUFFER ); renderLog.OpenBlock( "RB_FillDepthBufferFast" ); - GL_StartDepthPass( viewDef->scissor ); - // force MVP change on first surface currentSpace = NULL; @@ -1176,9 +1174,6 @@ void idRenderBackend::FillDepthBufferFast( drawSurf_t** drawSurfs, int numDrawSu FillDepthBufferGeneric( perforatedSurfaces, numPerforatedSurfaces ); } - // Allow platform specific data to be collected after the depth pass. - GL_FinishDepthPass(); - renderLog.CloseBlock(); renderLog.CloseMainBlock(); } @@ -2291,7 +2286,7 @@ void idRenderBackend::AmbientPass( const drawSurf_t* const* drawSurfs, int numDr GL_SelectTexture( 0 ); // FIXME: this copies RGBA16F into _currentNormals if HDR is enabled - const idScreenRect& viewport = backEnd.viewDef->viewport; + const idScreenRect& viewport = viewDef->viewport; globalImages->currentNormalsImage->CopyFramebuffer( viewport.x1, viewport.y1, viewport.GetWidth(), viewport.GetHeight() ); //GL_Clear( true, false, false, STENCIL_SHADOW_TEST_VALUE, 0.0f, 0.0f, 0.0f, 1.0f, false ); @@ -3552,11 +3547,12 @@ void idRenderBackend::DrawInteractions( const viewDef_t* _viewDef ) if( !currentScissor.Equals( rect ) && r_useScissor.GetBool() ) { - GL_Scissor( backEnd.viewDef->viewport.x1 + rect.x1, - backEnd.viewDef->viewport.y1 + rect.y1, + GL_Scissor( viewDef->viewport.x1 + rect.x1, + viewDef->viewport.y1 + rect.y1, rect.x2 + 1 - rect.x1, rect.y2 + 1 - rect.y1 ); - backEnd.currentScissor = rect; + + currentScissor = rect; } GL_State( GLS_DEFAULT ); // make sure stencil mask passes for the clear GL_Clear( false, false, true, STENCIL_SHADOW_TEST_VALUE, 0.0f, 0.0f, 0.0f, 0.0f, false ); @@ -3663,7 +3659,7 @@ int idRenderBackend::DrawShaderPasses( const drawSurf_t* const* const drawSurfs, const float guiStereoScreenOffset, const int stereoEye ) { // only obey skipAmbient if we are rendering a view - if( backEnd.viewDef->viewEntitys && r_skipAmbient.GetBool() ) + if( viewDef->viewEntitys && r_skipAmbient.GetBool() ) { return numDrawSurfs; } @@ -3675,7 +3671,7 @@ int idRenderBackend::DrawShaderPasses( const drawSurf_t* const* const drawSurfs, GL_SelectTexture( 0 ); - backEnd.currentSpace = ( const viewEntity_t* )1; // using NULL makes /analyze think surf->space needs to be checked... + currentSpace = ( const viewEntity_t* )1; // using NULL makes /analyze think surf->space needs to be checked... float currentGuiStereoOffset = 0.0f; int i = 0; @@ -3705,7 +3701,7 @@ int idRenderBackend::DrawShaderPasses( const drawSurf_t* const* const drawSurfs, continue; } - if( backEnd.viewDef->isXraySubview && surf->space->entityDef ) + if( viewDef->isXraySubview && surf->space->entityDef ) { if( surf->space->entityDef->parms.xrayIndex != 2 ) { @@ -3714,7 +3710,7 @@ int idRenderBackend::DrawShaderPasses( const drawSurf_t* const* const drawSurfs, } // we need to draw the post process shaders after we have drawn the fog lights - if( shader->GetSort() >= SS_POST_PROCESS && !backEnd.currentRenderCopied ) + if( shader->GetSort() >= SS_POST_PROCESS && !currentRenderCopied ) { break; } @@ -3737,12 +3733,12 @@ int idRenderBackend::DrawShaderPasses( const drawSurf_t* const* const drawSurfs, const float thisGuiStereoOffset = guiStereoScreenOffset * surf->sort; // change the matrix and other space related vars if needed - if( surf->space != backEnd.currentSpace || thisGuiStereoOffset != currentGuiStereoOffset ) + if( surf->space != currentSpace || thisGuiStereoOffset != currentGuiStereoOffset ) { - backEnd.currentSpace = surf->space; + currentSpace = surf->space; currentGuiStereoOffset = thisGuiStereoOffset; - const viewEntity_t* space = backEnd.currentSpace; + const viewEntity_t* space = currentSpace; if( guiStereoScreenOffset != 0.0f ) { @@ -3755,7 +3751,7 @@ int idRenderBackend::DrawShaderPasses( const drawSurf_t* const* const drawSurfs, // set eye position in local space idVec4 localViewOrigin( 1.0f ); - R_GlobalPointToLocal( space->modelMatrix, backEnd.viewDef->renderView.vieworg, localViewOrigin.ToVec3() ); + R_GlobalPointToLocal( space->modelMatrix, viewDef->renderView.vieworg, localViewOrigin.ToVec3() ); SetVertexParm( RENDERPARM_LOCALVIEWORIGIN, localViewOrigin.ToFloatPtr() ); // set model Matrix @@ -3770,13 +3766,14 @@ int idRenderBackend::DrawShaderPasses( const drawSurf_t* const* const drawSurfs, } // change the scissor if needed - if( !backEnd.currentScissor.Equals( surf->scissorRect ) && r_useScissor.GetBool() ) + if( !currentScissor.Equals( surf->scissorRect ) && r_useScissor.GetBool() ) { - GL_Scissor( backEnd.viewDef->viewport.x1 + surf->scissorRect.x1, - backEnd.viewDef->viewport.y1 + surf->scissorRect.y1, + GL_Scissor( viewDef->viewport.x1 + surf->scissorRect.x1, + viewDef->viewport.y1 + surf->scissorRect.y1, surf->scissorRect.x2 + 1 - surf->scissorRect.x1, surf->scissorRect.y2 + 1 - surf->scissorRect.y1 ); - backEnd.currentScissor = surf->scissorRect; + + currentScissor = surf->scissorRect; } // get the expressions for conditionals / color / texcoords @@ -3881,7 +3878,7 @@ int idRenderBackend::DrawShaderPasses( const drawSurf_t* const* const drawSurfs, } // draw it - RB_DrawElementsWithCounters( surf ); + DrawElementsWithCounters( surf ); // unbind texture units for( int j = 0; j < newStage->numFragmentProgramImages; j++ ) @@ -3975,7 +3972,7 @@ int idRenderBackend::DrawShaderPasses( const drawSurf_t* const* const drawSurfs, } else { - if( backEnd.viewDef->is2Dgui ) + if( viewDef->is2Dgui ) { // RB: 2D fullscreen drawing like warp or damage blend effects renderProgManager.BindShader_TextureVertexColor_sRGB(); @@ -4011,7 +4008,7 @@ int idRenderBackend::DrawShaderPasses( const drawSurf_t* const* const drawSurfs, RB_SetVertexColorParms( svc ); // bind the texture - RB_BindVariableStageImage( &pStage->texture, regs ); + BindVariableStageImage( &pStage->texture, regs ); // set privatePolygonOffset if necessary if( pStage->privatePolygonOffset ) @@ -4023,12 +4020,12 @@ int idRenderBackend::DrawShaderPasses( const drawSurf_t* const* const drawSurfs, // set the state GL_State( stageGLState ); - RB_PrepareStageTexturing( pStage, surf ); + PrepareStageTexturing( pStage, surf ); // draw it - RB_DrawElementsWithCounters( surf ); + DrawElementsWithCounters( surf ); - RB_FinishStageTexturing( pStage, surf ); + FinishStageTexturing( pStage, surf ); // unset privatePolygonOffset if necessary if( pStage->privatePolygonOffset ) @@ -4348,8 +4345,8 @@ void idRenderBackend::FogPass( const drawSurf_t* drawSurfs, const drawSurf_t* d // draw it GL_State( GLS_DEPTHMASK | GLS_SRCBLEND_SRC_ALPHA | GLS_DSTBLEND_ONE_MINUS_SRC_ALPHA | GLS_DEPTHFUNC_EQUAL ); - RB_T_BasicFog( drawSurfs, fogPlanes, NULL ); - RB_T_BasicFog( drawSurfs2, fogPlanes, NULL ); + T_BasicFog( drawSurfs, fogPlanes, NULL ); + T_BasicFog( drawSurfs2, fogPlanes, NULL ); // the light frustum bounding planes aren't in the depth buffer, so use depthfunc_less instead // of depthfunc_equal @@ -4482,10 +4479,10 @@ void idRenderBackend::CalculateAutomaticExposure() //if(r_hdrMaxLuminance->value) { - hdrAverageLuminance = idMath::ClampFloat( r_hdrMinLuminance.GetFloat(), r_hdrMaxLuminance.GetFloat(), backEnd.hdrAverageLuminance ); + hdrAverageLuminance = idMath::ClampFloat( r_hdrMinLuminance.GetFloat(), r_hdrMaxLuminance.GetFloat(), hdrAverageLuminance ); avgLuminance = idMath::ClampFloat( r_hdrMinLuminance.GetFloat(), r_hdrMaxLuminance.GetFloat(), avgLuminance ); - hdrMaxLuminance = idMath::ClampFloat( r_hdrMinLuminance.GetFloat(), r_hdrMaxLuminance.GetFloat(), backEnd.hdrMaxLuminance ); + hdrMaxLuminance = idMath::ClampFloat( r_hdrMinLuminance.GetFloat(), r_hdrMaxLuminance.GetFloat(), hdrMaxLuminance ); maxLuminance = idMath::ClampFloat( r_hdrMinLuminance.GetFloat(), r_hdrMaxLuminance.GetFloat(), maxLuminance ); } @@ -5779,7 +5776,7 @@ void idRenderBackend::DrawView( const void* data, const int stereoEye ) pc.c_surfaces += viewDef->numDrawSurfs; - RB_ShowOverdraw(); + DBG_ShowOverdraw(); // render the scene DrawViewInternal( cmd->viewDef, stereoEye ); diff --git a/neo/renderer/RenderBackend.h b/neo/renderer/RenderBackend.h index 6fba781a..700993e7 100644 --- a/neo/renderer/RenderBackend.h +++ b/neo/renderer/RenderBackend.h @@ -31,6 +31,17 @@ If you have questions concerning this license or the applicable additional terms #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; @@ -118,8 +129,8 @@ void RB_LoadShaderTextureMatrix( const float* shaderRegisters, const textureStag void RB_BakeTextureMatrixIntoTexgen( idPlane lightProject[3], const float* textureMatrix ); void RB_SetupInteractionStage( const shaderStage_t* surfaceStage, const float* surfaceRegs, const float lightColor[4], idVec4 matrix[2], float color[4] ); -bool ChangeDisplaySettingsIfNeeded( gfxImpParms_t parms ); -bool CreateGameWindow( gfxImpParms_t parms ); +//bool ChangeDisplaySettingsIfNeeded( gfxImpParms_t parms ); +//bool CreateGameWindow( gfxImpParms_t parms ); #if defined( ID_VULKAN ) @@ -201,11 +212,11 @@ extern vulkanContext_t vkcontext; struct glContext_t { - bool bAnisotropicFilterAvailable; - bool bTextureLODBiasAvailable; - - float maxTextureAnisotropy; - +// bool bAnisotropicFilterAvailable; +// bool bTextureLODBiasAvailable; + +// float maxTextureAnisotropy; + tmu_t tmu[ MAX_MULTITEXTURE_UNITS ]; uint64 stencilOperations[ STENCIL_FACE_NUM ]; }; @@ -304,10 +315,13 @@ 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 ); @@ -323,6 +337,7 @@ private: 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 ); @@ -332,38 +347,53 @@ private: 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 ) + 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 ) + ID_INLINE void GL_Color( const idVec4& color ) { GL_Color( color[0], color[1], color[2], color[3] ); } - void GL_Color( float* color ); - +// 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_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 ); @@ -378,14 +408,20 @@ private: 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 ); diff --git a/neo/renderer/RenderCommon.h b/neo/renderer/RenderCommon.h index 4bbe26a2..491ec927 100644 --- a/neo/renderer/RenderCommon.h +++ b/neo/renderer/RenderCommon.h @@ -1416,7 +1416,6 @@ 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 ); @@ -1450,12 +1449,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 ); @@ -1468,7 +1462,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" diff --git a/neo/renderer/RenderSystem.cpp b/neo/renderer/RenderSystem.cpp index b20baae4..c3c5b537 100644 --- a/neo/renderer/RenderSystem.cpp +++ b/neo/renderer/RenderSystem.cpp @@ -136,14 +136,14 @@ void idRenderSystemLocal::RenderCommandBuffers( const emptyCommand_t* const cmdH glGenQueries( 1, & tr.timerQueryId ); } glBeginQuery( GL_TIME_ELAPSED_EXT, tr.timerQueryId ); - ExecuteBackEndCommands( cmdHead ); + backend.ExecuteBackEndCommands( cmdHead ); glEndQuery( GL_TIME_ELAPSED_EXT ); glFlush(); } else #endif { - ExecuteBackEndCommands( cmdHead ); + backend.ExecuteBackEndCommands( cmdHead ); } } diff --git a/neo/renderer/RenderSystem_init.cpp b/neo/renderer/RenderSystem_init.cpp index bd4022f1..598f031c 100644 --- a/neo/renderer/RenderSystem_init.cpp +++ b/neo/renderer/RenderSystem_init.cpp @@ -2909,7 +2909,7 @@ void idRenderSystemLocal::Init() ambientLightVector[2] = 0.8925f; ambientLightVector[3] = 1.0f; - memset( &backEnd, 0, sizeof( backEnd ) ); + backend.Init(); R_InitCvars(); diff --git a/neo/renderer/RenderWorld_local.h b/neo/renderer/RenderWorld_local.h index 19fa5dc8..d7430f31 100644 --- a/neo/renderer/RenderWorld_local.h +++ b/neo/renderer/RenderWorld_local.h @@ -251,7 +251,6 @@ public: { return areaScreenRect[areaNum]; } - void ShowPortals(); //-------------------------- // RenderWorld_demo.cpp diff --git a/neo/renderer/RenderWorld_portals.cpp b/neo/renderer/RenderWorld_portals.cpp index b062df40..5040dcd2 100644 --- a/neo/renderer/RenderWorld_portals.cpp +++ b/neo/renderer/RenderWorld_portals.cpp @@ -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(); - } - } -} diff --git a/neo/renderer/tr_backend_rendertools.cpp b/neo/renderer/tr_backend_rendertools.cpp index 77c882dd..9ef0bfad 100644 --- a/neo/renderer/tr_backend_rendertools.cpp +++ b/neo/renderer/tr_backend_rendertools.cpp @@ -39,49 +39,14 @@ idCVar r_showLines( "r_showLines", "0", CVAR_RENDERER | CVAR_INTEGER, "1 = draw -#define MAX_DEBUG_LINES 16384 - -typedef struct debugLine_s -{ - idVec4 rgb; - idVec3 start; - idVec3 end; - bool depthTest; - int lifeTime; -} debugLine_t; - debugLine_t rb_debugLines[ MAX_DEBUG_LINES ]; int rb_numDebugLines = 0; int rb_debugLineTime = 0; -#define MAX_DEBUG_TEXT 512 - -typedef struct debugText_s -{ - idStr text; - idVec3 origin; - float scale; - idVec4 color; - idMat3 viewAxis; - int align; - int lifeTime; - bool depthTest; -} debugText_t; - debugText_t rb_debugText[ MAX_DEBUG_TEXT ]; int rb_numDebugText = 0; int rb_debugTextTime = 0; -#define MAX_DEBUG_POLYGONS 8192 - -typedef struct debugPolygon_s -{ - idVec4 rgb; - idWinding winding; - bool depthTest; - int lifeTime; -} debugPolygon_t; - debugPolygon_t rb_debugPolygons[ MAX_DEBUG_POLYGONS ]; int rb_numDebugPolygons = 0; int rb_debugPolygonTime = 0; @@ -132,56 +97,57 @@ void RB_DrawBounds( const idBounds& bounds ) /* ================ -RB_SimpleSurfaceSetup +idRenderBackend::DBG_SimpleSurfaceSetup ================ */ -static void RB_SimpleSurfaceSetup( const drawSurf_t* drawSurf ) +void idRenderBackend::DBG_SimpleSurfaceSetup( const drawSurf_t* drawSurf ) { // change the matrix if needed - if( drawSurf->space != backEnd.currentSpace ) + if( drawSurf->space != currentSpace ) { // RB begin RB_SetMVP( drawSurf->space->mvp ); //qglLoadMatrixf( drawSurf->space->modelViewMatrix ); // RB end - backEnd.currentSpace = drawSurf->space; + currentSpace = drawSurf->space; } // change the scissor if needed - if( !backEnd.currentScissor.Equals( drawSurf->scissorRect ) && r_useScissor.GetBool() ) + if( !currentScissor.Equals( drawSurf->scissorRect ) && r_useScissor.GetBool() ) { - GL_Scissor( backEnd.viewDef->viewport.x1 + drawSurf->scissorRect.x1, - backEnd.viewDef->viewport.y1 + drawSurf->scissorRect.y1, + GL_Scissor( viewDef->viewport.x1 + drawSurf->scissorRect.x1, + viewDef->viewport.y1 + drawSurf->scissorRect.y1, drawSurf->scissorRect.x2 + 1 - drawSurf->scissorRect.x1, drawSurf->scissorRect.y2 + 1 - drawSurf->scissorRect.y1 ); - backEnd.currentScissor = drawSurf->scissorRect; + + currentScissor = drawSurf->scissorRect; } } /* ================ -RB_SimpleWorldSetup +idRenderBackend::DBG_SimpleWorldSetup ================ */ -static void RB_SimpleWorldSetup() +void idRenderBackend::DBG_SimpleWorldSetup() { - backEnd.currentSpace = &backEnd.viewDef->worldSpace; + currentSpace = &viewDef->worldSpace; // RB begin - //qglLoadMatrixf( backEnd.viewDef->worldSpace.modelViewMatrix ); - RB_SetMVP( backEnd.viewDef->worldSpace.mvp ); + RB_SetMVP( viewDef->worldSpace.mvp ); // RB end - GL_Scissor( backEnd.viewDef->viewport.x1 + backEnd.viewDef->scissor.x1, - backEnd.viewDef->viewport.y1 + backEnd.viewDef->scissor.y1, - backEnd.viewDef->scissor.x2 + 1 - backEnd.viewDef->scissor.x1, - backEnd.viewDef->scissor.y2 + 1 - backEnd.viewDef->scissor.y1 ); - backEnd.currentScissor = backEnd.viewDef->scissor; + GL_Scissor( viewDef->viewport.x1 + viewDef->scissor.x1, + viewDef->viewport.y1 + viewDef->scissor.y1, + viewDef->scissor.x2 + 1 - viewDef->scissor.x1, + viewDef->scissor.y2 + 1 - viewDef->scissor.y1 ); + + currentScissor = viewDef->scissor; } /* ================= -RB_PolygonClear +idRenderBackend::DBG_PolygonClear This will cover the entire screen with normal rasterization. Texturing is disabled, but the existing glColor, glDepthMask, @@ -189,7 +155,7 @@ glColorMask, and the enabled state of depth buffering and stenciling will matter. ================= */ -void RB_PolygonClear() +void idRenderBackend::DBG_PolygonClear() { glPushMatrix(); glPushAttrib( GL_ALL_ATTRIB_BITS ); @@ -210,24 +176,25 @@ void RB_PolygonClear() /* ==================== -RB_ShowDestinationAlpha +idRenderBackend::DBG_ShowDestinationAlpha ==================== */ -void RB_ShowDestinationAlpha() +void idRenderBackend::DBG_ShowDestinationAlpha() { GL_State( GLS_SRCBLEND_DST_ALPHA | GLS_DSTBLEND_ZERO | GLS_DEPTHMASK | GLS_DEPTHFUNC_ALWAYS ); GL_Color( 1, 1, 1 ); - RB_PolygonClear(); + + DBG_PolygonClear(); } /* =================== -RB_ScanStencilBuffer +idRenderBackend::DBG_ScanStencilBuffer Debugging tool to see what values are in the stencil buffer =================== */ -void RB_ScanStencilBuffer() +void idRenderBackend::DBG_ScanStencilBuffer() { int counts[256]; int i; @@ -259,12 +226,12 @@ void RB_ScanStencilBuffer() /* =================== -RB_CountStencilBuffer +idRenderBackend::DBG_CountStencilBuffer Print an overdraw count based on stencil index values =================== */ -static void RB_CountStencilBuffer() +void idRenderBackend::DBG_CountStencilBuffer() { int count; int i; @@ -288,14 +255,14 @@ static void RB_CountStencilBuffer() /* =================== -R_ColorByStencilBuffer +idRenderBackend::DBG_ColorByStencilBuffer Sets the screen colors based on the contents of the stencil buffer. Stencil of 0 = black, 1 = red, 2 = green, 3 = blue, ..., 7+ = white =================== */ -static void R_ColorByStencilBuffer() +void idRenderBackend::DBG_ColorByStencilBuffer() { int i; static idVec3 colors[8] = @@ -320,20 +287,19 @@ static void R_ColorByStencilBuffer() GL_Color( colors[i] ); renderProgManager.BindShader_Color(); glStencilFunc( GL_EQUAL, i, 255 ); - RB_PolygonClear(); + + DBG_PolygonClear(); } glStencilFunc( GL_ALWAYS, 0, 255 ); } -//====================================================================== - /* ================== -RB_ShowOverdraw +idRenderBackend::DBG_ShowOverdraw ================== */ -void RB_ShowOverdraw() +void idRenderBackend::DBG_ShowOverdraw() { const idMaterial* material; int i; @@ -353,11 +319,11 @@ void RB_ShowOverdraw() return; } - drawSurfs = backEnd.viewDef->drawSurfs; - numDrawSurfs = backEnd.viewDef->numDrawSurfs; + drawSurfs = viewDef->drawSurfs; + numDrawSurfs = viewDef->numDrawSurfs; int interactions = 0; - for( vLight = backEnd.viewDef->viewLights; vLight; vLight = vLight->next ) + for( vLight = viewDef->viewLights; vLight; vLight = vLight->next ) { for( surf = vLight->localInteractions; surf; surf = surf->nextOnLight ) { @@ -382,7 +348,7 @@ void RB_ShowOverdraw() newDrawSurfs[i] = const_cast( surf ); } - for( vLight = backEnd.viewDef->viewLights; vLight; vLight = vLight->next ) + for( vLight = viewDef->viewLights; vLight; vLight = vLight->next ) { for( surf = vLight->localInteractions; surf; surf = surf->nextOnLight ) { @@ -401,30 +367,30 @@ void RB_ShowOverdraw() switch( r_showOverDraw.GetInteger() ) { case 1: // geometry overdraw - const_cast( backEnd.viewDef )->drawSurfs = newDrawSurfs; - const_cast( backEnd.viewDef )->numDrawSurfs = numDrawSurfs; + const_cast( viewDef )->drawSurfs = newDrawSurfs; + const_cast( viewDef )->numDrawSurfs = numDrawSurfs; break; case 2: // light interaction overdraw - const_cast( backEnd.viewDef )->drawSurfs = &newDrawSurfs[numDrawSurfs]; - const_cast( backEnd.viewDef )->numDrawSurfs = interactions; + const_cast( viewDef )->drawSurfs = &newDrawSurfs[numDrawSurfs]; + const_cast( viewDef )->numDrawSurfs = interactions; break; case 3: // geometry + light interaction overdraw - const_cast( backEnd.viewDef )->drawSurfs = newDrawSurfs; - const_cast( backEnd.viewDef )->numDrawSurfs += interactions; + const_cast( viewDef )->drawSurfs = newDrawSurfs; + const_cast( viewDef )->numDrawSurfs += interactions; break; } } /* =================== -RB_ShowIntensity +idRenderBackend::DBG_ShowIntensity Debugging tool to see how much dynamic range a scene is using. The greatest of the rgb values at each pixel will be used, with the resulting color shading from red at 0 to green at 128 to blue at 255 =================== */ -static void RB_ShowIntensity() +void idRenderBackend::DBG_ShowIntensity() { byte* colorReadback; int i, j, c; @@ -484,12 +450,12 @@ static void RB_ShowIntensity() /* =================== -RB_ShowDepthBuffer +idRenderBackend::DBG_ShowDepthBuffer Draw the depth buffer as colors =================== */ -static void RB_ShowDepthBuffer() +void idRenderBackend::DBG_ShowDepthBuffer() { void* depthReadback; @@ -534,13 +500,13 @@ static void RB_ShowDepthBuffer() /* ================= -RB_ShowLightCount +idRenderBackend::DBG_ShowLightCount This is a debugging tool that will draw each surface with a color based on how many lights are effecting it ================= */ -static void RB_ShowLightCount() +void idRenderBackend::DBG_ShowLightCount() { int i; const drawSurf_t* surf; @@ -551,7 +517,7 @@ static void RB_ShowLightCount() return; } - RB_SimpleWorldSetup(); + DBG_SimpleWorldSetup(); GL_Clear( false, false, true, 0, 0.0f, 0.0f, 0.0f, 0.0f ); @@ -567,114 +533,30 @@ static void RB_ShowLightCount() globalImages->defaultImage->Bind(); - for( vLight = backEnd.viewDef->viewLights; vLight; vLight = vLight->next ) + for( vLight = viewDef->viewLights; vLight; vLight = vLight->next ) { for( i = 0; i < 2; i++ ) { for( surf = i ? vLight->localInteractions : vLight->globalInteractions; surf; surf = ( drawSurf_t* )surf->nextOnLight ) { - RB_SimpleSurfaceSetup( surf ); - RB_DrawElementsWithCounters( surf ); + DBG_SimpleSurfaceSetup( surf ); + DrawElementsWithCounters( surf ); } } } // display the results - R_ColorByStencilBuffer(); + DBG_ColorByStencilBuffer(); if( r_showLightCount.GetInteger() > 2 ) { - RB_CountStencilBuffer(); + DBG_CountStencilBuffer(); } } -#if 0 -/* -=============== -RB_SetWeaponDepthHack -=============== -*/ -static void RB_SetWeaponDepthHack() -{ -} - -/* -=============== -RB_SetModelDepthHack -=============== -*/ -static void RB_SetModelDepthHack( float depth ) -{ -} - -/* -=============== -RB_EnterWeaponDepthHack -=============== -*/ -static void RB_EnterWeaponDepthHack() -{ - float matrix[16]; - - memcpy( matrix, backEnd.viewDef->projectionMatrix, sizeof( matrix ) ); - - const float modelDepthHack = 0.25f; - matrix[2] *= modelDepthHack; - matrix[6] *= modelDepthHack; - matrix[10] *= modelDepthHack; - matrix[14] *= modelDepthHack; - - glMatrixMode( GL_PROJECTION ); - glLoadMatrixf( matrix ); - glMatrixMode( GL_MODELVIEW ); -} - -/* -=============== -RB_EnterModelDepthHack -=============== -*/ -static void RB_EnterModelDepthHack( float depth ) -{ - float matrix[16]; - - memcpy( matrix, backEnd.viewDef->projectionMatrix, sizeof( matrix ) ); - - matrix[14] -= depth; - - glMatrixMode( GL_PROJECTION ); - glLoadMatrixf( matrix ); - glMatrixMode( GL_MODELVIEW ); -} - -/* -=============== -RB_LeaveDepthHack -=============== -*/ -static void RB_LeaveDepthHack() -{ - glMatrixMode( GL_PROJECTION ); - glLoadMatrixf( backEnd.viewDef->projectionMatrix ); - glMatrixMode( GL_MODELVIEW ); -} - -/* -============= -RB_LoadMatrixWithBypass - -does a glLoadMatrixf after optionally applying the low-latency bypass matrix -============= -*/ -static void RB_LoadMatrixWithBypass( const float m[16] ) -{ - glLoadMatrixf( m ); -} - -#endif /* ==================== -RB_RenderDrawSurfListWithFunction +idRenderBackend::DBG_RenderDrawSurfListWithFunction The triangle functions can check backEnd.currentSpace != surf->space to see if they need to perform any new matrix setup. The modelview @@ -682,9 +564,9 @@ matrix will already have been loaded, and backEnd.currentSpace will be updated after the triangle function completes. ==================== */ -static void RB_RenderDrawSurfListWithFunction( drawSurf_t** drawSurfs, int numDrawSurfs, void ( *triFunc_ )( const drawSurf_t* ) ) +void idRenderBackend::DBG_RenderDrawSurfListWithFunction( drawSurf_t** drawSurfs, int numDrawSurfs ) { - backEnd.currentSpace = NULL; + currentSpace = NULL; for( int i = 0 ; i < numDrawSurfs ; i++ ) { @@ -698,9 +580,9 @@ static void RB_RenderDrawSurfListWithFunction( drawSurf_t** drawSurfs, int numDr // RB begin #if 1 - if( drawSurf->space != backEnd.currentSpace ) + if( drawSurf->space != currentSpace ) { - backEnd.currentSpace = drawSurf->space; + currentSpace = drawSurf->space; RB_SetMVP( drawSurf->space->mvp ); } @@ -748,17 +630,18 @@ static void RB_RenderDrawSurfListWithFunction( drawSurf_t** drawSurfs, int numDr // RB end // change the scissor if needed - if( r_useScissor.GetBool() && !backEnd.currentScissor.Equals( drawSurf->scissorRect ) ) + if( r_useScissor.GetBool() && !currentScissor.Equals( drawSurf->scissorRect ) ) { - backEnd.currentScissor = drawSurf->scissorRect; - GL_Scissor( backEnd.viewDef->viewport.x1 + backEnd.currentScissor.x1, - backEnd.viewDef->viewport.y1 + backEnd.currentScissor.y1, - backEnd.currentScissor.x2 + 1 - backEnd.currentScissor.x1, - backEnd.currentScissor.y2 + 1 - backEnd.currentScissor.y1 ); + currentScissor = drawSurf->scissorRect; + + GL_Scissor( viewDef->viewport.x1 + currentScissor.x1, + viewDef->viewport.y1 + currentScissor.y1, + currentScissor.x2 + 1 - currentScissor.x1, + currentScissor.y2 + 1 - currentScissor.y1 ); } // render it - triFunc_( drawSurf ); + DrawElementsWithCounters( drawSurf ); // RB begin /*if( drawSurf->space != NULL && ( drawSurf->space->weaponDepthHack || drawSurf->space->modelDepthHack != 0.0f ) ) @@ -767,13 +650,13 @@ static void RB_RenderDrawSurfListWithFunction( drawSurf_t** drawSurfs, int numDr }*/ // RB end - backEnd.currentSpace = drawSurf->space; + currentSpace = drawSurf->space; } } /* ================= -RB_ShowSilhouette +idRenderBackend::DBG_ShowSilhouette Blacks out all edges, then adds color for each edge that a shadow plane extends from, allowing you to see doubled edges @@ -781,7 +664,7 @@ plane extends from, allowing you to see doubled edges FIXME: not thread safe! ================= */ -static void RB_ShowSilhouette() +void idRenderBackend::DBG_ShowSilhouette() { int i; const drawSurf_t* surf; @@ -805,23 +688,23 @@ static void RB_ShowSilhouette() GL_Cull( CT_TWO_SIDED ); - RB_RenderDrawSurfListWithFunction( backEnd.viewDef->drawSurfs, backEnd.viewDef->numDrawSurfs, - RB_DrawElementsWithCounters ); - - + DBG_RenderDrawSurfListWithFunction( viewDef->drawSurfs, viewDef->numDrawSurfs ); + + // now blend in edges that cast silhouettes - RB_SimpleWorldSetup(); + DBG_SimpleWorldSetup(); + GL_Color( 0.5, 0, 0 ); GL_State( GLS_SRCBLEND_ONE | GLS_DSTBLEND_ONE ); - for( vLight = backEnd.viewDef->viewLights; vLight; vLight = vLight->next ) + for( vLight = viewDef->viewLights; vLight; vLight = vLight->next ) { for( i = 0; i < 2; i++ ) { for( surf = i ? vLight->localShadows : vLight->globalShadows ; surf; surf = ( drawSurf_t* )surf->nextOnLight ) { - RB_SimpleSurfaceSetup( surf ); + DBG_SimpleSurfaceSetup( surf ); const srfTriangles_t* tri = surf->frontEndGeo; @@ -872,12 +755,12 @@ static void RB_ShowSilhouette() /* ===================== -RB_ShowTris +idRenderBackend::DBG_ShowTris Debugging tool ===================== */ -static void RB_ShowTris( drawSurf_t** drawSurfs, int numDrawSurfs ) +void idRenderBackend::DBG_ShowTris( drawSurf_t** drawSurfs, int numDrawSurfs ) { modelTrace_t mt; @@ -914,7 +797,7 @@ static void RB_ShowTris( drawSurf_t** drawSurfs, int numDrawSurfs ) GL_Color( color ); - RB_RenderDrawSurfListWithFunction( drawSurfs, numDrawSurfs, RB_DrawElementsWithCounters ); + DBG_RenderDrawSurfListWithFunction( drawSurfs, numDrawSurfs ); if( r_showTris.GetInteger() == 3 ) { @@ -924,7 +807,7 @@ static void RB_ShowTris( drawSurf_t** drawSurfs, int numDrawSurfs ) /* ===================== -RB_ShowSurfaceInfo +idRenderBackend::DBG_ShowSurfaceInfo Debugging tool ===================== @@ -969,7 +852,7 @@ void idRenderSystemLocal::OnFrame() } -static void RB_ShowSurfaceInfo( drawSurf_t** drawSurfs, int numDrawSurfs ) +void idRenderBackend::DBG_ShowSurfaceInfo( drawSurf_t** drawSurfs, int numDrawSurfs ) { if( !r_showSurfaceInfo.GetBool() || !surfTraced ) { @@ -979,7 +862,7 @@ static void RB_ShowSurfaceInfo( drawSurf_t** drawSurfs, int numDrawSurfs ) // globalImages->BindNull(); // qglDisable( GL_TEXTURE_2D ); - RB_SimpleWorldSetup(); + DBG_SimpleWorldSetup(); // foresthale 2014-05-02: don't use a shader for tools //renderProgManager.BindShader_TextureVertexColor(); @@ -1012,12 +895,12 @@ static void RB_ShowSurfaceInfo( drawSurf_t** drawSurfs, int numDrawSurfs ) /* ===================== -RB_ShowViewEntitys +idRenderBackend::DBG_ShowViewEntitys Debugging tool ===================== */ -static void RB_ShowViewEntitys( viewEntity_t* vModels ) +void idRenderBackend::DBG_ShowViewEntitys( viewEntity_t* vModels ) { if( !r_showViewEntitys.GetBool() ) { @@ -1109,13 +992,13 @@ static void RB_ShowViewEntitys( viewEntity_t* vModels ) /* ===================== -RB_ShowTexturePolarity +idRenderBackend::DBG_ShowTexturePolarity Shade triangle red if they have a positive texture area green if they have a negative texture area, or blue if degenerate area ===================== */ -static void RB_ShowTexturePolarity( drawSurf_t** drawSurfs, int numDrawSurfs ) +void idRenderBackend::DBG_ShowTexturePolarity( drawSurf_t** drawSurfs, int numDrawSurfs ) { int i, j; drawSurf_t* drawSurf; @@ -1140,7 +1023,7 @@ static void RB_ShowTexturePolarity( drawSurf_t** drawSurfs, int numDrawSurfs ) continue; } - RB_SimpleSurfaceSetup( drawSurf ); + DBG_SimpleSurfaceSetup( drawSurf ); glBegin( GL_TRIANGLES ); for( j = 0; j < tri->numIndexes; j += 3 ) @@ -1189,12 +1072,12 @@ static void RB_ShowTexturePolarity( drawSurf_t** drawSurfs, int numDrawSurfs ) /* ===================== -RB_ShowUnsmoothedTangents +idRenderBackend::DBG_ShowUnsmoothedTangents Shade materials that are using unsmoothed tangents ===================== */ -static void RB_ShowUnsmoothedTangents( drawSurf_t** drawSurfs, int numDrawSurfs ) +void idRenderBackend::DBG_ShowUnsmoothedTangents( drawSurf_t** drawSurfs, int numDrawSurfs ) { int i, j; drawSurf_t* drawSurf; @@ -1219,7 +1102,7 @@ static void RB_ShowUnsmoothedTangents( drawSurf_t** drawSurfs, int numDrawSurfs continue; } - RB_SimpleSurfaceSetup( drawSurf ); + DBG_SimpleSurfaceSetup( drawSurf ); tri = drawSurf->frontEndGeo; if( tri == NULL || tri->verts == NULL ) @@ -1256,7 +1139,7 @@ Shade a triangle by the RGB colors of its tangent space 3 = normal ===================== */ -static void RB_ShowTangentSpace( drawSurf_t** drawSurfs, int numDrawSurfs ) +void idRenderBackend::DBG_ShowTangentSpace( drawSurf_t** drawSurfs, int numDrawSurfs ) { int i, j; drawSurf_t* drawSurf; @@ -1274,7 +1157,7 @@ static void RB_ShowTangentSpace( drawSurf_t** drawSurfs, int numDrawSurfs ) { drawSurf = drawSurfs[i]; - RB_SimpleSurfaceSetup( drawSurf ); + DBG_SimpleSurfaceSetup( drawSurf ); tri = drawSurf->frontEndGeo; if( tri == NULL || tri->verts == NULL ) @@ -1317,12 +1200,12 @@ static void RB_ShowTangentSpace( drawSurf_t** drawSurfs, int numDrawSurfs ) /* ===================== -RB_ShowVertexColor +idRenderBackend::DBG_ShowVertexColor Draw each triangle with the solid vertex colors ===================== */ -static void RB_ShowVertexColor( drawSurf_t** drawSurfs, int numDrawSurfs ) +void idRenderBackend::DBG_ShowVertexColor( drawSurf_t** drawSurfs, int numDrawSurfs ) { int i, j; drawSurf_t* drawSurf; @@ -1343,7 +1226,7 @@ static void RB_ShowVertexColor( drawSurf_t** drawSurfs, int numDrawSurfs ) { drawSurf = drawSurfs[i]; - RB_SimpleSurfaceSetup( drawSurf ); + DBG_SimpleSurfaceSetup( drawSurf ); tri = drawSurf->frontEndGeo; if( tri == NULL || tri->verts == NULL ) @@ -1372,12 +1255,12 @@ static void RB_ShowVertexColor( drawSurf_t** drawSurfs, int numDrawSurfs ) /* ===================== -RB_ShowNormals +idRenderBackend::DBG_ShowNormals Debugging tool ===================== */ -static void RB_ShowNormals( drawSurf_t** drawSurfs, int numDrawSurfs ) +void idRenderBackend::DBG_ShowNormals( drawSurf_t** drawSurfs, int numDrawSurfs ) { int i, j; drawSurf_t* drawSurf; @@ -1418,7 +1301,7 @@ static void RB_ShowNormals( drawSurf_t** drawSurfs, int numDrawSurfs ) { drawSurf = drawSurfs[i]; - RB_SimpleSurfaceSetup( drawSurf ); + DBG_SimpleSurfaceSetup( drawSurf ); tri = drawSurf->frontEndGeo; if( tri == NULL || tri->verts == NULL ) @@ -1458,7 +1341,8 @@ static void RB_ShowNormals( drawSurf_t** drawSurfs, int numDrawSurfs ) if( showNumbers ) { - RB_SimpleWorldSetup(); + DBG_SimpleWorldSetup(); + for( i = 0; i < numDrawSurfs; i++ ) { drawSurf = drawSurfs[i]; @@ -1473,101 +1357,27 @@ static void RB_ShowNormals( drawSurf_t** drawSurfs, int numDrawSurfs ) const idVec3 normal = tri->verts[j].GetNormal(); const idVec3 tangent = tri->verts[j].GetTangent(); R_LocalPointToGlobal( drawSurf->space->modelMatrix, tri->verts[j].xyz + tangent + normal * 0.2f, pos ); - RB_DrawText( va( "%d", j ), pos, 0.01f, colorWhite, backEnd.viewDef->renderView.viewaxis, 1 ); + RB_DrawText( va( "%d", j ), pos, 0.01f, colorWhite, viewDef->renderView.viewaxis, 1 ); } for( j = 0; j < tri->numIndexes; j += 3 ) { const idVec3 normal = tri->verts[ tri->indexes[ j + 0 ] ].GetNormal(); R_LocalPointToGlobal( drawSurf->space->modelMatrix, ( tri->verts[ tri->indexes[ j + 0 ] ].xyz + tri->verts[ tri->indexes[ j + 1 ] ].xyz + tri->verts[ tri->indexes[ j + 2 ] ].xyz ) * ( 1.0f / 3.0f ) + normal * 0.2f, pos ); - RB_DrawText( va( "%d", j / 3 ), pos, 0.01f, colorCyan, backEnd.viewDef->renderView.viewaxis, 1 ); + RB_DrawText( va( "%d", j / 3 ), pos, 0.01f, colorCyan, viewDef->renderView.viewaxis, 1 ); } } } } -#if 0 // compiler warning - /* ===================== -RB_ShowNormals - -Debugging tool -===================== -*/ -static void RB_AltShowNormals( drawSurf_t** drawSurfs, int numDrawSurfs ) -{ - if( r_showNormals.GetFloat() == 0.0f ) - { - return; - } - - globalImages->BindNull(); - - GL_State( GLS_DEPTHFUNC_ALWAYS ); - - for( int i = 0; i < numDrawSurfs; i++ ) - { - drawSurf_t* drawSurf = drawSurfs[i]; - - RB_SimpleSurfaceSetup( drawSurf ); - - const srfTriangles_t* tri = drawSurf->geo; - - glBegin( GL_LINES ); - for( int j = 0; j < tri->numIndexes; j += 3 ) - { - const idDrawVert* v[3] = - { - &tri->verts[tri->indexes[j + 0]], - &tri->verts[tri->indexes[j + 1]], - &tri->verts[tri->indexes[j + 2]] - } - - const idPlane plane( v[0]->xyz, v[1]->xyz, v[2]->xyz ); - - // make the midpoint slightly above the triangle - const idVec3 mid = ( v[0]->xyz + v[1]->xyz + v[2]->xyz ) * ( 1.0f / 3.0f ) + 0.1f * plane.Normal(); - - for( int k = 0; k < 3; k++ ) - { - const idVec3 pos = ( mid + v[k]->xyz * 3.0f ) * 0.25f; - idVec3 end; - - GL_Color( 0, 0, 1 ); - glVertex3fv( pos.ToFloatPtr() ); - VectorMA( pos, r_showNormals.GetFloat(), v[k]->normal, end ); - glVertex3fv( end.ToFloatPtr() ); - - GL_Color( 1, 0, 0 ); - glVertex3fv( pos.ToFloatPtr() ); - VectorMA( pos, r_showNormals.GetFloat(), v[k]->tangents[0], end ); - glVertex3fv( end.ToFloatPtr() ); - - GL_Color( 0, 1, 0 ); - glVertex3fv( pos.ToFloatPtr() ); - VectorMA( pos, r_showNormals.GetFloat(), v[k]->tangents[1], end ); - glVertex3fv( end.ToFloatPtr() ); - - GL_Color( 1, 1, 1 ); - glVertex3fv( pos.ToFloatPtr() ); - glVertex3fv( v[k]->xyz.ToFloatPtr() ); - } - } - glEnd(); - } -} - -#endif - -/* -===================== -RB_ShowTextureVectors +idRenderBackend::DBG_ShowTextureVectors Draw texture vectors in the center of each triangle ===================== */ -static void RB_ShowTextureVectors( drawSurf_t** drawSurfs, int numDrawSurfs ) +void idRenderBackend::DBG_ShowTextureVectors( drawSurf_t** drawSurfs, int numDrawSurfs ) { if( r_showTextureVectors.GetFloat() == 0.0f ) { @@ -1589,7 +1399,7 @@ static void RB_ShowTextureVectors( drawSurf_t** drawSurfs, int numDrawSurfs ) continue; } - RB_SimpleSurfaceSetup( drawSurf ); + DBG_SimpleSurfaceSetup( drawSurf ); // draw non-shared edges in yellow glBegin( GL_LINES ); @@ -1664,12 +1474,12 @@ static void RB_ShowTextureVectors( drawSurf_t** drawSurfs, int numDrawSurfs ) /* ===================== -RB_ShowDominantTris +idRenderBackend::DBG_ShowDominantTris Draw lines from each vertex to the dominant triangle center ===================== */ -static void RB_ShowDominantTris( drawSurf_t** drawSurfs, int numDrawSurfs ) +void idRenderBackend::DBG_ShowDominantTris( drawSurf_t** drawSurfs, int numDrawSurfs ) { int i, j; drawSurf_t* drawSurf; @@ -1701,7 +1511,8 @@ static void RB_ShowDominantTris( drawSurf_t** drawSurfs, int numDrawSurfs ) { continue; } - RB_SimpleSurfaceSetup( drawSurf ); + + DBG_SimpleSurfaceSetup( drawSurf ); GL_Color( 1, 1, 0 ); glBegin( GL_LINES ); @@ -1730,12 +1541,12 @@ static void RB_ShowDominantTris( drawSurf_t** drawSurfs, int numDrawSurfs ) /* ===================== -RB_ShowEdges +idRenderBackend::DBG_ShowEdges Debugging tool ===================== */ -static void RB_ShowEdges( drawSurf_t** drawSurfs, int numDrawSurfs ) +void idRenderBackend::DBG_ShowEdges( drawSurf_t** drawSurfs, int numDrawSurfs ) { int i, j, k, m, n, o; drawSurf_t* drawSurf; @@ -1764,7 +1575,7 @@ static void RB_ShowEdges( drawSurf_t** drawSurfs, int numDrawSurfs ) continue; } - RB_SimpleSurfaceSetup( drawSurf ); + DBG_SimpleSurfaceSetup( drawSurf ); // draw non-shared edges in yellow GL_Color( 1, 1, 0 ); @@ -1847,7 +1658,7 @@ r_showLights 2 : also draw planes of each volume r_showLights 3 : also draw edges of each volume ============== */ -static void RB_ShowLights() +void idRenderBackend::DBG_ShowLights() { if( !r_showLights.GetInteger() ) { @@ -1865,7 +1676,7 @@ static void RB_ShowLights() common->Printf( "volumes: " ); // FIXME: not in back end! int count = 0; - for( viewLight_t* vLight = backEnd.viewDef->viewLights; vLight != NULL; vLight = vLight->next ) + for( viewLight_t* vLight = viewDef->viewLights; vLight != NULL; vLight = vLight->next ) { count++; @@ -1890,9 +1701,9 @@ static void RB_ShowLights() // RB end idRenderMatrix invProjectMVPMatrix; - idRenderMatrix::Multiply( backEnd.viewDef->worldSpace.mvp, vLight->inverseBaseLightProject, invProjectMVPMatrix ); + idRenderMatrix::Multiply( viewDef->worldSpace.mvp, vLight->inverseBaseLightProject, invProjectMVPMatrix ); RB_SetMVP( invProjectMVPMatrix ); - RB_DrawElementsWithCounters( &backEnd.zeroOneCubeSurface ); + DrawElementsWithCounters( &zeroOneCubeSurface ); } // non-hidden lines @@ -1901,9 +1712,9 @@ static void RB_ShowLights() GL_State( GLS_DEPTHFUNC_ALWAYS | GLS_POLYMODE_LINE | GLS_DEPTHMASK ); GL_Color( 1.0f, 1.0f, 1.0f ); idRenderMatrix invProjectMVPMatrix; - idRenderMatrix::Multiply( backEnd.viewDef->worldSpace.mvp, vLight->inverseBaseLightProject, invProjectMVPMatrix ); + idRenderMatrix::Multiply( viewDef->worldSpace.mvp, vLight->inverseBaseLightProject, invProjectMVPMatrix ); RB_SetMVP( invProjectMVPMatrix ); - RB_DrawElementsWithCounters( &backEnd.zeroOneCubeSurface ); + DrawElementsWithCounters( &zeroOneCubeSurface ); } common->Printf( "%i ", vLight->lightDef->index ); @@ -1913,7 +1724,7 @@ static void RB_ShowLights() } // RB begin -static void RB_ShowShadowMapLODs() +void idRenderBackend::DBG_ShowShadowMapLODs() { if( !r_showShadowMapLODs.GetInteger() ) { @@ -1931,7 +1742,7 @@ static void RB_ShowShadowMapLODs() common->Printf( "volumes: " ); // FIXME: not in back end! int count = 0; - for( viewLight_t* vLight = backEnd.viewDef->viewLights; vLight != NULL; vLight = vLight->next ) + for( viewLight_t* vLight = viewDef->viewLights; vLight != NULL; vLight = vLight->next ) { if( !vLight->lightDef->LightCastsShadows() ) { @@ -1979,9 +1790,9 @@ static void RB_ShowShadowMapLODs() GL_Color( c ); idRenderMatrix invProjectMVPMatrix; - idRenderMatrix::Multiply( backEnd.viewDef->worldSpace.mvp, vLight->inverseBaseLightProject, invProjectMVPMatrix ); + idRenderMatrix::Multiply( viewDef->worldSpace.mvp, vLight->inverseBaseLightProject, invProjectMVPMatrix ); RB_SetMVP( invProjectMVPMatrix ); - RB_DrawElementsWithCounters( &backEnd.zeroOneCubeSurface ); + DrawElementsWithCounters( &zeroOneCubeSurface ); } // non-hidden lines @@ -1990,9 +1801,9 @@ static void RB_ShowShadowMapLODs() GL_State( GLS_DEPTHFUNC_ALWAYS | GLS_POLYMODE_LINE | GLS_DEPTHMASK ); GL_Color( 1.0f, 1.0f, 1.0f ); idRenderMatrix invProjectMVPMatrix; - idRenderMatrix::Multiply( backEnd.viewDef->worldSpace.mvp, vLight->inverseBaseLightProject, invProjectMVPMatrix ); + idRenderMatrix::Multiply( viewDef->worldSpace.mvp, vLight->inverseBaseLightProject, invProjectMVPMatrix ); RB_SetMVP( invProjectMVPMatrix ); - RB_DrawElementsWithCounters( &backEnd.zeroOneCubeSurface ); + DrawElementsWithCounters( &zeroOneCubeSurface ); } common->Printf( "%i ", vLight->lightDef->index ); @@ -2004,12 +1815,12 @@ static void RB_ShowShadowMapLODs() /* ===================== -RB_ShowPortals +idRenderBackend::DBG_ShowPortals Debugging tool, won't work correctly with SMP or when mirrors are present ===================== */ -static void RB_ShowPortals() +void idRenderBackend::DBG_ShowPortals() { if( !r_showPortals.GetBool() ) { @@ -2017,18 +1828,63 @@ static void RB_ShowPortals() } // all portals are expressed in world coordinates - RB_SimpleWorldSetup(); + DBG_SimpleWorldSetup(); globalImages->BindNull(); renderProgManager.BindShader_Color(); GL_State( GLS_DEPTHFUNC_ALWAYS ); - ( ( idRenderWorldLocal* )backEnd.viewDef->renderWorld )->ShowPortals(); + int i, j; + portalArea_t* area; + portal_t* p; + idWinding* w; + + idRenderWorldLocal& world = *viewDef->renderWorld; + + // flood out through portals, setting area viewCount + for( int i = 0; i < world.numPortalAreas; i++ ) + { + area = &world.portalAreas[i]; + if( area->viewCount != tr.viewCount ) + { + continue; + } + for( p = area->portals; p; p = p->next ) + { + w = p->w; + if( !w ) + { + continue; + } + + if( world.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(); + } + } } /* ================ -RB_ClearDebugText +idRenderBackend::DBG_ClearDebugText ================ */ void RB_ClearDebugText( int time ) @@ -2153,7 +2009,7 @@ static void RB_DrawText( const char* text, const idVec3& origin, float scale, co renderProgManager.BindShader_Color(); // RB begin - GL_Color( color[0], color[1], color[2], 1 /*color[3]*/ ); + //GL_Color( color[0], color[1], color[2], 1 /*color[3]*/ ); renderProgManager.CommitUniforms(); // RB end @@ -2242,10 +2098,10 @@ static void RB_DrawText( const char* text, const idVec3& origin, float scale, co /* ================ -RB_ShowDebugText +idRenderBackend::DBG_ShowDebugText ================ */ -void RB_ShowDebugText() +void idRenderBackend::DBG_ShowDebugText() { int i; int width; @@ -2257,7 +2113,7 @@ void RB_ShowDebugText() } // all lines are expressed in world coordinates - RB_SimpleWorldSetup(); + DBG_SimpleWorldSetup(); globalImages->BindNull(); @@ -2289,6 +2145,7 @@ void RB_ShowDebugText() { if( !text->depthTest ) { + GL_Color( text->color.ToVec3() ); RB_DrawText( text->text, text->origin, text->scale, text->color, text->viewAxis, text->align ); } } @@ -2303,6 +2160,7 @@ void RB_ShowDebugText() { if( text->depthTest ) { + GL_Color( text->color.ToVec3() ); RB_DrawText( text->text, text->origin, text->scale, text->color, text->viewAxis, text->align ); } } @@ -2368,10 +2226,10 @@ void RB_AddDebugLine( const idVec4& color, const idVec3& start, const idVec3& en /* ================ -RB_ShowDebugLines +idRenderBackend::DBG_ShowDebugLines ================ */ -void RB_ShowDebugLines() +void idRenderBackend::DBG_ShowDebugLines() { int i; int width; @@ -2383,7 +2241,7 @@ void RB_ShowDebugLines() } // all lines are expressed in world coordinates - RB_SimpleWorldSetup(); + DBG_SimpleWorldSetup(); // RB begin renderProgManager.BindShader_VertexColor(); @@ -2510,10 +2368,10 @@ void RB_AddDebugPolygon( const idVec4& color, const idWinding& winding, const in /* ================ -RB_ShowDebugPolygons +idRenderBackend::DBG_ShowDebugPolygons ================ */ -void RB_ShowDebugPolygons() +void idRenderBackend::DBG_ShowDebugPolygons() { int i, j; debugPolygon_t* poly; @@ -2524,7 +2382,7 @@ void RB_ShowDebugPolygons() } // all lines are expressed in world coordinates - RB_SimpleWorldSetup(); + DBG_SimpleWorldSetup(); // RB begin renderProgManager.BindShader_VertexColor(); @@ -2578,18 +2436,18 @@ void RB_ShowDebugPolygons() /* ================ -RB_ShowCenterOfProjection +idRenderBackend::DBG_ShowCenterOfProjection ================ */ -void RB_ShowCenterOfProjection() +void idRenderBackend::DBG_ShowCenterOfProjection() { if( !r_showCenterOfProjection.GetBool() ) { return; } - const int w = backEnd.viewDef->scissor.GetWidth(); - const int h = backEnd.viewDef->scissor.GetHeight(); + const int w = viewDef->scissor.GetWidth(); + const int h = viewDef->scissor.GetHeight(); glClearColor( 1, 0, 0, 1 ); for( float f = 0.0f ; f <= 1.0f ; f += 0.125f ) { @@ -2610,12 +2468,12 @@ void RB_ShowCenterOfProjection() /* ================ -RB_ShowLines +idRenderBackend::DBG_ShowLines Draw exact pixel lines to check pixel center sampling ================ */ -void RB_ShowLines() +void idRenderBackend::DBG_ShowLines() { if( !r_showLines.GetBool() ) { @@ -2623,11 +2481,11 @@ void RB_ShowLines() } glEnable( GL_SCISSOR_TEST ); - if( backEnd.viewDef->renderView.viewEyeBuffer == 0 ) + if( viewDef->renderView.viewEyeBuffer == 0 ) { glClearColor( 1, 0, 0, 1 ); } - else if( backEnd.viewDef->renderView.viewEyeBuffer == 1 ) + else if( viewDef->renderView.viewEyeBuffer == 1 ) { glClearColor( 0, 1, 0, 1 ); } @@ -2658,14 +2516,14 @@ void RB_ShowLines() /* ================ -RB_TestGamma +idRenderBackend::DBG_TestGamma ================ */ #define G_WIDTH 512 #define G_HEIGHT 512 #define BAR_HEIGHT 64 -void RB_TestGamma() +void idRenderBackend::DBG_TestGamma() { byte image[G_HEIGHT][G_WIDTH][4]; int i, j; @@ -2773,10 +2631,10 @@ void RB_TestGamma() /* ================== -RB_TestGammaBias +idRenderBackend::DBG_TestGammaBias ================== */ -static void RB_TestGammaBias() +void idRenderBackend::DBG_TestGammaBias() { byte image[G_HEIGHT][G_WIDTH][4]; @@ -2830,12 +2688,12 @@ static void RB_TestGammaBias() /* ================ -RB_TestImage +idRenderBackend::DBG_TestImage Display a single image over most of the screen ================ */ -void RB_TestImage() +void idRenderBackend::DBG_TestImage() { idImage* image = NULL; idImage* imageCr = NULL; @@ -2853,7 +2711,7 @@ void RB_TestImage() { cinData_t cin; - cin = tr.testVideo->ImageForTime( backEnd.viewDef->renderView.time[1] - tr.testVideoStartTime ); + cin = tr.testVideo->ImageForTime( viewDef->renderView.time[1] - tr.testVideoStartTime ); if( cin.imageY != NULL ) { image = cin.imageY; @@ -2948,11 +2806,11 @@ void RB_TestImage() } // Draw! - RB_DrawElementsWithCounters( &backEnd.testImageSurface ); + DrawElementsWithCounters( &testImageSurface ); } // RB begin -void RB_ShowShadowMaps() +void idRenderBackend::DBG_ShowShadowMaps() { idImage* image = NULL; int max; @@ -3040,7 +2898,7 @@ void RB_ShowShadowMaps() renderProgManager.BindShader_DebugShadowMap(); - RB_DrawElementsWithCounters( &backEnd.testImageSurface ); + DrawElementsWithCounters( &testImageSurface ); } glTexParameteri( GL_TEXTURE_2D_ARRAY, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_R_TO_TEXTURE ); @@ -3052,7 +2910,7 @@ void RB_ShowShadowMaps() RB_DrawExpandedTriangles ================= */ -void RB_DrawExpandedTriangles( const srfTriangles_t* tri, const float radius, const idVec3& vieworg ) +static void RB_DrawExpandedTriangles( const srfTriangles_t* tri, const float radius, const idVec3& vieworg ) { int i, j, k; idVec3 dir[6], normal, point; @@ -3118,14 +2976,14 @@ void RB_DrawExpandedTriangles( const srfTriangles_t* tri, const float radius, co /* ================ -RB_ShowTrace +idRenderBackend::DBG_ShowTrace Debug visualization FIXME: not thread safe! ================ */ -void RB_ShowTrace( drawSurf_t** drawSurfs, int numDrawSurfs ) +void idRenderBackend::DBG_ShowTrace( drawSurf_t** drawSurfs, int numDrawSurfs ) { int i; const srfTriangles_t* tri; @@ -3150,8 +3008,8 @@ void RB_ShowTrace( drawSurf_t** drawSurfs, int numDrawSurfs ) } // determine the points of the trace - start = backEnd.viewDef->renderView.vieworg; - end = start + 4000 * backEnd.viewDef->renderView.viewaxis[0]; + start = viewDef->renderView.vieworg; + end = start + 4000 * viewDef->renderView.viewaxis[0]; // check and draw the surfaces globalImages->whiteImage->Bind(); @@ -3183,7 +3041,7 @@ void RB_ShowTrace( drawSurf_t** drawSurfs, int numDrawSurfs ) GL_State( GLS_SRCBLEND_SRC_ALPHA | GLS_DSTBLEND_ONE_MINUS_SRC_ALPHA ); GL_Color( 1, 0, 0, 0.25 ); - RB_DrawElementsWithCounters( surf ); + DrawElementsWithCounters( surf ); // draw the bounding box GL_State( GLS_DEPTHFUNC_ALWAYS ); @@ -3210,16 +3068,16 @@ void RB_ShowTrace( drawSurf_t** drawSurfs, int numDrawSurfs ) /* ================= -RB_RenderDebugTools +idRenderBackend::DBG_RenderDebugTools ================= */ -void RB_RenderDebugTools( drawSurf_t** drawSurfs, int numDrawSurfs ) +void idRenderBackend::DBG_RenderDebugTools( drawSurf_t** drawSurfs, int numDrawSurfs ) { // don't do much if this was a 2D rendering - if( !backEnd.viewDef->viewEntitys ) + if( !viewDef->viewEntitys ) { - RB_TestImage(); - RB_ShowLines(); + DBG_TestImage(); + DBG_ShowLines(); return; } @@ -3228,49 +3086,50 @@ void RB_RenderDebugTools( drawSurf_t** drawSurfs, int numDrawSurfs ) GL_State( GLS_DEFAULT ); - GL_Scissor( backEnd.viewDef->viewport.x1 + backEnd.viewDef->scissor.x1, - backEnd.viewDef->viewport.y1 + backEnd.viewDef->scissor.y1, - backEnd.viewDef->scissor.x2 + 1 - backEnd.viewDef->scissor.x1, - backEnd.viewDef->scissor.y2 + 1 - backEnd.viewDef->scissor.y1 ); - backEnd.currentScissor = backEnd.viewDef->scissor; + GL_Scissor( viewDef->viewport.x1 + viewDef->scissor.x1, + viewDef->viewport.y1 + viewDef->scissor.y1, + viewDef->scissor.x2 + 1 - viewDef->scissor.x1, + viewDef->scissor.y2 + 1 - viewDef->scissor.y1 ); + + currentScissor = viewDef->scissor; - RB_ShowLightCount(); - RB_ShowTexturePolarity( drawSurfs, numDrawSurfs ); - RB_ShowTangentSpace( drawSurfs, numDrawSurfs ); - RB_ShowVertexColor( drawSurfs, numDrawSurfs ); - RB_ShowTris( drawSurfs, numDrawSurfs ); - RB_ShowUnsmoothedTangents( drawSurfs, numDrawSurfs ); - RB_ShowSurfaceInfo( drawSurfs, numDrawSurfs ); - RB_ShowEdges( drawSurfs, numDrawSurfs ); - RB_ShowNormals( drawSurfs, numDrawSurfs ); - RB_ShowViewEntitys( backEnd.viewDef->viewEntitys ); - RB_ShowLights(); + DBG_ShowLightCount(); + DBG_ShowTexturePolarity( drawSurfs, numDrawSurfs ); + DBG_ShowTangentSpace( drawSurfs, numDrawSurfs ); + DBG_ShowVertexColor( drawSurfs, numDrawSurfs ); + DBG_ShowTris( drawSurfs, numDrawSurfs ); + DBG_ShowUnsmoothedTangents( drawSurfs, numDrawSurfs ); + DBG_ShowSurfaceInfo( drawSurfs, numDrawSurfs ); + DBG_ShowEdges( drawSurfs, numDrawSurfs ); + DBG_ShowNormals( drawSurfs, numDrawSurfs ); + DBG_ShowViewEntitys( viewDef->viewEntitys ); + DBG_ShowLights(); // RB begin - RB_ShowShadowMapLODs(); - RB_ShowShadowMaps(); + DBG_ShowShadowMapLODs(); + DBG_ShowShadowMaps(); // RB end - RB_ShowTextureVectors( drawSurfs, numDrawSurfs ); - RB_ShowDominantTris( drawSurfs, numDrawSurfs ); + DBG_ShowTextureVectors( drawSurfs, numDrawSurfs ); + DBG_ShowDominantTris( drawSurfs, numDrawSurfs ); if( r_testGamma.GetInteger() > 0 ) // test here so stack check isn't so damn slow on debug builds { - RB_TestGamma(); + DBG_TestGamma(); } if( r_testGammaBias.GetInteger() > 0 ) { - RB_TestGammaBias(); + DBG_TestGammaBias(); } - RB_TestImage(); - RB_ShowPortals(); - RB_ShowSilhouette(); - RB_ShowDepthBuffer(); - RB_ShowIntensity(); - RB_ShowCenterOfProjection(); - RB_ShowLines(); - RB_ShowDebugLines(); - RB_ShowDebugText(); - RB_ShowDebugPolygons(); - RB_ShowTrace( drawSurfs, numDrawSurfs ); + DBG_TestImage(); + DBG_ShowPortals(); + DBG_ShowSilhouette(); + DBG_ShowDepthBuffer(); + DBG_ShowIntensity(); + DBG_ShowCenterOfProjection(); + DBG_ShowLines(); + DBG_ShowDebugLines(); + DBG_ShowDebugText(); + DBG_ShowDebugPolygons(); + DBG_ShowTrace( drawSurfs, numDrawSurfs ); renderLog.CloseMainBlock(); } diff --git a/neo/renderer/tr_frontend_addlights.cpp b/neo/renderer/tr_frontend_addlights.cpp index 37ebccc9..36b4d3f5 100644 --- a/neo/renderer/tr_frontend_addlights.cpp +++ b/neo/renderer/tr_frontend_addlights.cpp @@ -673,7 +673,7 @@ void R_AddLights() } int end = Sys_Microseconds(); - backEnd.pc.shadowMicroSec += end - start; + tr.backend.pc.shadowMicroSec += end - start; } } diff --git a/neo/renderer/tr_frontend_addmodels.cpp b/neo/renderer/tr_frontend_addmodels.cpp index 1ceaae07..b1aa6d93 100644 --- a/neo/renderer/tr_frontend_addmodels.cpp +++ b/neo/renderer/tr_frontend_addmodels.cpp @@ -1402,7 +1402,7 @@ void R_AddModels() } int end = Sys_Microseconds(); - backEnd.pc.shadowMicroSec += end - start; + tr.backend.pc.shadowMicroSec += end - start; } } From a6169afac6e522cd4cf0fb3503089ac239011917 Mon Sep 17 00:00:00 2001 From: Robert Beckebans Date: Sun, 10 Sep 2017 13:32:44 +0200 Subject: [PATCH 08/12] More render backend refactoring. Fixed image stuff --- neo/renderer/Image_load.cpp | 199 ---------------------- neo/renderer/OpenGL/Image_GL.cpp | 203 +++++++++++++++++++++++ neo/renderer/OpenGL/RenderBackend_GL.cpp | 183 +++++++++++++++++++- neo/renderer/RenderBackend.cpp | 25 ++- neo/renderer/RenderBackend.h | 19 ++- neo/renderer/RenderCommon.h | 5 - neo/renderer/RenderSystem.cpp | 113 +------------ neo/renderer/RenderSystem_init.cpp | 62 +------ 8 files changed, 408 insertions(+), 401 deletions(-) diff --git a/neo/renderer/Image_load.cpp b/neo/renderer/Image_load.cpp index 32aea529..a8a1e42b 100644 --- a/neo/renderer/Image_load.cpp +++ b/neo/renderer/Image_load.cpp @@ -658,107 +658,7 @@ 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 = tr.backend.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 -} /* ================ @@ -774,106 +674,7 @@ int MakePowerOfTwo( int num ) 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++; -} /* ============= diff --git a/neo/renderer/OpenGL/Image_GL.cpp b/neo/renderer/OpenGL/Image_GL.cpp index 2f4cc8ab..3c55632d 100644 --- a/neo/renderer/OpenGL/Image_GL.cpp +++ b/neo/renderer/OpenGL/Image_GL.cpp @@ -72,6 +72,209 @@ 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++; +} + /* ======================== idImage::SubImageUpload diff --git a/neo/renderer/OpenGL/RenderBackend_GL.cpp b/neo/renderer/OpenGL/RenderBackend_GL.cpp index a4067561..3efff25d 100644 --- a/neo/renderer/OpenGL/RenderBackend_GL.cpp +++ b/neo/renderer/OpenGL/RenderBackend_GL.cpp @@ -53,7 +53,69 @@ static GLsync renderSync[2]; void GLimp_SwapBuffers(); void RB_SetMVP( const idRenderMatrix& mvp ); +glContext_t glcontext; +/* +================== +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 /* ============= @@ -888,6 +950,117 @@ uint64 idRenderBackend::GL_GetCurrentStateMinusStencil() const } +/* +============= +idRenderBackend::CheckCVars + +See if some cvars that we watch have changed +============= +*/ +void idRenderBackend::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 +} + /* ============================================================================ @@ -1180,7 +1353,7 @@ void idRenderBackend::StereoRenderExecuteBackEndCommands( const emptyCommand_t* SetBuffer( cmds ); break; case RC_COPY_RENDER: - RB_CopyRender( cmds ); + CopyRender( cmds ); break; case RC_POST_PROCESS: { @@ -1189,7 +1362,7 @@ void idRenderBackend::StereoRenderExecuteBackEndCommands( const emptyCommand_t* { break; } - RB_PostProcess( cmds ); + PostProcess( cmds ); } break; default: @@ -1455,7 +1628,7 @@ void idRenderBackend::ExecuteBackEndCommands( const emptyCommand_t* cmds ) break; case RC_DRAW_VIEW_3D: case RC_DRAW_VIEW_GUI: - RB_DrawView( cmds, 0 ); + DrawView( cmds, 0 ); if( ( ( const drawSurfsCommand_t* )cmds )->viewDef->viewEntitys ) { c_draw3d++; @@ -1470,11 +1643,11 @@ void idRenderBackend::ExecuteBackEndCommands( const emptyCommand_t* cmds ) c_setBuffers++; break; case RC_COPY_RENDER: - RB_CopyRender( cmds ); + CopyRender( cmds ); c_copyRenders++; break; case RC_POST_PROCESS: - RB_PostProcess( cmds ); + PostProcess( cmds ); break; default: common->Error( "RB_ExecuteBackEndCommands: bad commandId" ); diff --git a/neo/renderer/RenderBackend.cpp b/neo/renderer/RenderBackend.cpp index 09db961f..1510e1fe 100644 --- a/neo/renderer/RenderBackend.cpp +++ b/neo/renderer/RenderBackend.cpp @@ -1832,8 +1832,7 @@ void idRenderBackend::RenderInteractions( const drawSurf_t* surfList, const view inter.bumpImage = surfaceStage->texture.image; inter.diffuseImage = NULL; inter.specularImage = NULL; - RB_SetupInteractionStage( surfaceStage, surfaceRegs, NULL, - inter.bumpMatrix, NULL ); + SetupInteractionStage( surfaceStage, surfaceRegs, NULL, inter.bumpMatrix, NULL ); break; } case SL_DIFFUSE: @@ -1850,8 +1849,8 @@ void idRenderBackend::RenderInteractions( const drawSurf_t* surfList, const view } inter.diffuseImage = surfaceStage->texture.image; inter.vertexColor = surfaceStage->vertexColor; - RB_SetupInteractionStage( surfaceStage, surfaceRegs, diffuseColor.ToFloatPtr(), - inter.diffuseMatrix, inter.diffuseColor.ToFloatPtr() ); + SetupInteractionStage( surfaceStage, surfaceRegs, diffuseColor.ToFloatPtr(), + inter.diffuseMatrix, inter.diffuseColor.ToFloatPtr() ); break; } case SL_SPECULAR: @@ -1868,8 +1867,8 @@ void idRenderBackend::RenderInteractions( const drawSurf_t* surfList, const view } inter.specularImage = surfaceStage->texture.image; inter.vertexColor = surfaceStage->vertexColor; - RB_SetupInteractionStage( surfaceStage, surfaceRegs, specularColor.ToFloatPtr(), - inter.specularMatrix, inter.specularColor.ToFloatPtr() ); + SetupInteractionStage( surfaceStage, surfaceRegs, specularColor.ToFloatPtr(), + inter.specularMatrix, inter.specularColor.ToFloatPtr() ); break; } } @@ -2221,8 +2220,8 @@ void idRenderBackend::AmbientPass( const drawSurf_t* const* drawSurfs, int numDr inter.bumpImage = surfaceStage->texture.image; inter.diffuseImage = NULL; inter.specularImage = NULL; - RB_SetupInteractionStage( surfaceStage, surfaceRegs, NULL, - inter.bumpMatrix, NULL ); + SetupInteractionStage( surfaceStage, surfaceRegs, NULL, + inter.bumpMatrix, NULL ); break; } @@ -2242,8 +2241,8 @@ void idRenderBackend::AmbientPass( const drawSurf_t* const* drawSurfs, int numDr inter.diffuseImage = surfaceStage->texture.image; inter.vertexColor = surfaceStage->vertexColor; - RB_SetupInteractionStage( surfaceStage, surfaceRegs, diffuseColor.ToFloatPtr(), - inter.diffuseMatrix, inter.diffuseColor.ToFloatPtr() ); + SetupInteractionStage( surfaceStage, surfaceRegs, diffuseColor.ToFloatPtr(), + inter.diffuseMatrix, inter.diffuseColor.ToFloatPtr() ); break; } @@ -2261,8 +2260,8 @@ void idRenderBackend::AmbientPass( const drawSurf_t* const* drawSurfs, int numDr } inter.specularImage = surfaceStage->texture.image; inter.vertexColor = surfaceStage->vertexColor; - RB_SetupInteractionStage( surfaceStage, surfaceRegs, specularColor.ToFloatPtr(), - inter.specularMatrix, inter.specularColor.ToFloatPtr() ); + SetupInteractionStage( surfaceStage, surfaceRegs, specularColor.ToFloatPtr(), + inter.specularMatrix, inter.specularColor.ToFloatPtr() ); break; } } @@ -5552,7 +5551,7 @@ void idRenderBackend::DrawViewInternal( const viewDef_t* _viewDef, const int ste //------------------------------------------------- // render debug tools //------------------------------------------------- - RB_RenderDebugTools( drawSurfs, numDrawSurfs ); + DBG_RenderDebugTools( drawSurfs, numDrawSurfs ); // RB: convert back from HDR to LDR range if( useHDR ) diff --git a/neo/renderer/RenderBackend.h b/neo/renderer/RenderBackend.h index 700993e7..ec22032a 100644 --- a/neo/renderer/RenderBackend.h +++ b/neo/renderer/RenderBackend.h @@ -127,7 +127,6 @@ 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 ); -void RB_SetupInteractionStage( const shaderStage_t* surfaceStage, const float* surfaceRegs, const float lightColor[4], idVec4 matrix[2], float color[4] ); //bool ChangeDisplaySettingsIfNeeded( gfxImpParms_t parms ); //bool CreateGameWindow( gfxImpParms_t parms ); @@ -250,6 +249,7 @@ public: void BlockingSwapBuffers(); void Print(); + void CheckCVars(); private: void DrawFlickerBox(); @@ -258,7 +258,6 @@ private: void DrawStencilShadowPass( const drawSurf_t* drawSurf, const bool renderZPass ); void SetColorMappings(); - void CheckCVars(); void ResizeImages(); void DrawViewInternal( const viewDef_t* viewDef, const int stereoEye ); @@ -324,11 +323,11 @@ private: 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 ); - +// 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 ); @@ -469,6 +468,12 @@ private: float polyOfsScale; float polyOfsBias; +public: + int GetCurrentTextureUnit() const + { + return currenttmu; + } + #if 0 unsigned short gammaTable[ 256 ]; // brightness / gamma modify this diff --git a/neo/renderer/RenderCommon.h b/neo/renderer/RenderCommon.h index 491ec927..f83dc1a5 100644 --- a/neo/renderer/RenderCommon.h +++ b/neo/renderer/RenderCommon.h @@ -1428,10 +1428,6 @@ TR_BACKEND_DRAW */ void RB_SetMVP( const idRenderMatrix& mvp ); -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 ); /* ============================================================= @@ -1450,7 +1446,6 @@ void RB_AddDebugPolygon( const idVec4& color, const idWinding& winding, const in void RB_ClearDebugPolygons( int time ); void RB_DrawBounds( const idBounds& bounds ); -void RB_RenderDebugTools( drawSurf_t** drawSurfs, int numDrawSurfs ); void RB_ShutdownDebugTools(); void RB_SetVertexColorParms( stageVertexColor_t svc ); diff --git a/neo/renderer/RenderSystem.cpp b/neo/renderer/RenderSystem.cpp index c3c5b537..4a09946d 100644 --- a/neo/renderer/RenderSystem.cpp +++ b/neo/renderer/RenderSystem.cpp @@ -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 @@ -795,7 +686,7 @@ void idRenderSystemLocal::SwapCommandBuffers_FinishRendering( PrintPerformanceCounters(); // check for dynamic changes that require some initialization - R_CheckCvars(); + backend.CheckCVars(); // RB: resize HDR buffers Framebuffer::CheckFramebuffers(); diff --git a/neo/renderer/RenderSystem_init.cpp b/neo/renderer/RenderSystem_init.cpp index 598f031c..5af407ee 100644 --- a/neo/renderer/RenderSystem_init.cpp +++ b/neo/renderer/RenderSystem_init.cpp @@ -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 + /* ===================== From b3637e8fde3a9e49d621f19d29efebbfe07bb76a Mon Sep 17 00:00:00 2001 From: Robert Beckebans Date: Sun, 10 Sep 2017 13:43:28 +0200 Subject: [PATCH 09/12] Moved tr_backend_rendertools.cpp --- neo/renderer/OpenGL/RenderBackend_GL.cpp | 1 + neo/renderer/tr_backend_rendertools.cpp | 3148 ---------------------- 2 files changed, 1 insertion(+), 3148 deletions(-) delete mode 100644 neo/renderer/tr_backend_rendertools.cpp diff --git a/neo/renderer/OpenGL/RenderBackend_GL.cpp b/neo/renderer/OpenGL/RenderBackend_GL.cpp index 3efff25d..e39d89cb 100644 --- a/neo/renderer/OpenGL/RenderBackend_GL.cpp +++ b/neo/renderer/OpenGL/RenderBackend_GL.cpp @@ -4,6 +4,7 @@ Doom 3 BFG Edition GPL Source Code Copyright (C) 1993-2012 id Software LLC, a ZeniMax Media company. Copyright (C) 2013-2015 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"). diff --git a/neo/renderer/tr_backend_rendertools.cpp b/neo/renderer/tr_backend_rendertools.cpp deleted file mode 100644 index 9ef0bfad..00000000 --- a/neo/renderer/tr_backend_rendertools.cpp +++ /dev/null @@ -1,3148 +0,0 @@ -/* -=========================================================================== - -Doom 3 BFG Edition GPL Source Code -Copyright (C) 1993-2012 id Software LLC, a ZeniMax Media company. -Copyright (C) 2014-2016 Robert Beckebans -Copyright (C) 2014-2016 Kot in Action Creative Artel - -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 . - -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 "RenderCommon.h" -#include "simplex.h" // line font definition - -idCVar r_showCenterOfProjection( "r_showCenterOfProjection", "0", CVAR_RENDERER | CVAR_BOOL, "Draw a cross to show the center of projection" ); -idCVar r_showLines( "r_showLines", "0", CVAR_RENDERER | CVAR_INTEGER, "1 = draw alternate horizontal lines, 2 = draw alternate vertical lines" ); - - - -debugLine_t rb_debugLines[ MAX_DEBUG_LINES ]; -int rb_numDebugLines = 0; -int rb_debugLineTime = 0; - -debugText_t rb_debugText[ MAX_DEBUG_TEXT ]; -int rb_numDebugText = 0; -int rb_debugTextTime = 0; - -debugPolygon_t rb_debugPolygons[ MAX_DEBUG_POLYGONS ]; -int rb_numDebugPolygons = 0; -int rb_debugPolygonTime = 0; - -static void RB_DrawText( const char* text, const idVec3& origin, float scale, const idVec4& color, const idMat3& viewAxis, const int align ); - -void RB_SetMVP( const idRenderMatrix& mvp ); - -/* -================ -RB_DrawBounds -================ -*/ -void RB_DrawBounds( const idBounds& bounds ) -{ - if( bounds.IsCleared() ) - { - return; - } - glBegin( GL_LINE_LOOP ); - glVertex3f( bounds[0][0], bounds[0][1], bounds[0][2] ); - glVertex3f( bounds[0][0], bounds[1][1], bounds[0][2] ); - glVertex3f( bounds[1][0], bounds[1][1], bounds[0][2] ); - glVertex3f( bounds[1][0], bounds[0][1], bounds[0][2] ); - glEnd(); - glBegin( GL_LINE_LOOP ); - glVertex3f( bounds[0][0], bounds[0][1], bounds[1][2] ); - glVertex3f( bounds[0][0], bounds[1][1], bounds[1][2] ); - glVertex3f( bounds[1][0], bounds[1][1], bounds[1][2] ); - glVertex3f( bounds[1][0], bounds[0][1], bounds[1][2] ); - glEnd(); - - glBegin( GL_LINES ); - glVertex3f( bounds[0][0], bounds[0][1], bounds[0][2] ); - glVertex3f( bounds[0][0], bounds[0][1], bounds[1][2] ); - - glVertex3f( bounds[0][0], bounds[1][1], bounds[0][2] ); - glVertex3f( bounds[0][0], bounds[1][1], bounds[1][2] ); - - glVertex3f( bounds[1][0], bounds[0][1], bounds[0][2] ); - glVertex3f( bounds[1][0], bounds[0][1], bounds[1][2] ); - - glVertex3f( bounds[1][0], bounds[1][1], bounds[0][2] ); - glVertex3f( bounds[1][0], bounds[1][1], bounds[1][2] ); - glEnd(); -} - - -/* -================ -idRenderBackend::DBG_SimpleSurfaceSetup -================ -*/ -void idRenderBackend::DBG_SimpleSurfaceSetup( const drawSurf_t* drawSurf ) -{ - // change the matrix if needed - if( drawSurf->space != currentSpace ) - { - // RB begin - RB_SetMVP( drawSurf->space->mvp ); - //qglLoadMatrixf( drawSurf->space->modelViewMatrix ); - // RB end - currentSpace = drawSurf->space; - } - - // change the scissor if needed - if( !currentScissor.Equals( drawSurf->scissorRect ) && r_useScissor.GetBool() ) - { - GL_Scissor( viewDef->viewport.x1 + drawSurf->scissorRect.x1, - viewDef->viewport.y1 + drawSurf->scissorRect.y1, - drawSurf->scissorRect.x2 + 1 - drawSurf->scissorRect.x1, - drawSurf->scissorRect.y2 + 1 - drawSurf->scissorRect.y1 ); - - currentScissor = drawSurf->scissorRect; - } -} - -/* -================ -idRenderBackend::DBG_SimpleWorldSetup -================ -*/ -void idRenderBackend::DBG_SimpleWorldSetup() -{ - currentSpace = &viewDef->worldSpace; - - // RB begin - RB_SetMVP( viewDef->worldSpace.mvp ); - // RB end - - GL_Scissor( viewDef->viewport.x1 + viewDef->scissor.x1, - viewDef->viewport.y1 + viewDef->scissor.y1, - viewDef->scissor.x2 + 1 - viewDef->scissor.x1, - viewDef->scissor.y2 + 1 - viewDef->scissor.y1 ); - - currentScissor = viewDef->scissor; -} - -/* -================= -idRenderBackend::DBG_PolygonClear - -This will cover the entire screen with normal rasterization. -Texturing is disabled, but the existing glColor, glDepthMask, -glColorMask, and the enabled state of depth buffering and -stenciling will matter. -================= -*/ -void idRenderBackend::DBG_PolygonClear() -{ - glPushMatrix(); - glPushAttrib( GL_ALL_ATTRIB_BITS ); - glLoadIdentity(); - glDisable( GL_TEXTURE_2D ); - glDisable( GL_DEPTH_TEST ); - glDisable( GL_CULL_FACE ); - glDisable( GL_SCISSOR_TEST ); - glBegin( GL_POLYGON ); - glVertex3f( -20, -20, -10 ); - glVertex3f( 20, -20, -10 ); - glVertex3f( 20, 20, -10 ); - glVertex3f( -20, 20, -10 ); - glEnd(); - glPopAttrib(); - glPopMatrix(); -} - -/* -==================== -idRenderBackend::DBG_ShowDestinationAlpha -==================== -*/ -void idRenderBackend::DBG_ShowDestinationAlpha() -{ - GL_State( GLS_SRCBLEND_DST_ALPHA | GLS_DSTBLEND_ZERO | GLS_DEPTHMASK | GLS_DEPTHFUNC_ALWAYS ); - GL_Color( 1, 1, 1 ); - - DBG_PolygonClear(); -} - -/* -=================== -idRenderBackend::DBG_ScanStencilBuffer - -Debugging tool to see what values are in the stencil buffer -=================== -*/ -void idRenderBackend::DBG_ScanStencilBuffer() -{ - int counts[256]; - int i; - byte* stencilReadback; - - memset( counts, 0, sizeof( counts ) ); - - stencilReadback = ( byte* )R_StaticAlloc( renderSystem->GetWidth() * renderSystem->GetHeight(), TAG_RENDER_TOOLS ); - glReadPixels( 0, 0, renderSystem->GetWidth(), renderSystem->GetHeight(), GL_STENCIL_INDEX, GL_UNSIGNED_BYTE, stencilReadback ); - - for( i = 0; i < renderSystem->GetWidth() * renderSystem->GetHeight(); i++ ) - { - counts[ stencilReadback[i] ]++; - } - - R_StaticFree( stencilReadback ); - - // print some stats (not supposed to do from back end in SMP...) - common->Printf( "stencil values:\n" ); - for( i = 0; i < 255; i++ ) - { - if( counts[i] ) - { - common->Printf( "%i: %i\n", i, counts[i] ); - } - } -} - - -/* -=================== -idRenderBackend::DBG_CountStencilBuffer - -Print an overdraw count based on stencil index values -=================== -*/ -void idRenderBackend::DBG_CountStencilBuffer() -{ - int count; - int i; - byte* stencilReadback; - - - stencilReadback = ( byte* )R_StaticAlloc( renderSystem->GetWidth() * renderSystem->GetHeight(), TAG_RENDER_TOOLS ); - glReadPixels( 0, 0, renderSystem->GetWidth(), renderSystem->GetHeight(), GL_STENCIL_INDEX, GL_UNSIGNED_BYTE, stencilReadback ); - - count = 0; - for( i = 0; i < renderSystem->GetWidth() * renderSystem->GetHeight(); i++ ) - { - count += stencilReadback[i]; - } - - R_StaticFree( stencilReadback ); - - // print some stats (not supposed to do from back end in SMP...) - common->Printf( "overdraw: %5.1f\n", ( float )count / ( renderSystem->GetWidth() * renderSystem->GetHeight() ) ); -} - -/* -=================== -idRenderBackend::DBG_ColorByStencilBuffer - -Sets the screen colors based on the contents of the -stencil buffer. Stencil of 0 = black, 1 = red, 2 = green, -3 = blue, ..., 7+ = white -=================== -*/ -void idRenderBackend::DBG_ColorByStencilBuffer() -{ - int i; - static idVec3 colors[8] = - { - idVec3( 0, 0, 0 ), - idVec3( 1, 0, 0 ), - idVec3( 0, 1, 0 ), - idVec3( 0, 0, 1 ), - idVec3( 0, 1, 1 ), - idVec3( 1, 0, 1 ), - idVec3( 1, 1, 0 ), - idVec3( 1, 1, 1 ), - }; - - // clear color buffer to white (>6 passes) - GL_Clear( true, false, false, 0, 1.0f, 1.0f, 1.0f, 1.0f ); - - // now draw color for each stencil value - glStencilOp( GL_KEEP, GL_KEEP, GL_KEEP ); - for( i = 0; i < 6; i++ ) - { - GL_Color( colors[i] ); - renderProgManager.BindShader_Color(); - glStencilFunc( GL_EQUAL, i, 255 ); - - DBG_PolygonClear(); - } - - glStencilFunc( GL_ALWAYS, 0, 255 ); -} - -/* -================== -idRenderBackend::DBG_ShowOverdraw -================== -*/ -void idRenderBackend::DBG_ShowOverdraw() -{ - const idMaterial* material; - int i; - drawSurf_t** drawSurfs; - const drawSurf_t* surf; - int numDrawSurfs; - viewLight_t* vLight; - - if( r_showOverDraw.GetInteger() == 0 ) - { - return; - } - - material = declManager->FindMaterial( "textures/common/overdrawtest", false ); - if( material == NULL ) - { - return; - } - - drawSurfs = viewDef->drawSurfs; - numDrawSurfs = viewDef->numDrawSurfs; - - int interactions = 0; - for( vLight = viewDef->viewLights; vLight; vLight = vLight->next ) - { - for( surf = vLight->localInteractions; surf; surf = surf->nextOnLight ) - { - interactions++; - } - for( surf = vLight->globalInteractions; surf; surf = surf->nextOnLight ) - { - interactions++; - } - } - - // FIXME: can't frame alloc from the renderer back-end - drawSurf_t** newDrawSurfs = ( drawSurf_t** )R_FrameAlloc( numDrawSurfs + interactions * sizeof( newDrawSurfs[0] ), FRAME_ALLOC_DRAW_SURFACE_POINTER ); - - for( i = 0; i < numDrawSurfs; i++ ) - { - surf = drawSurfs[i]; - if( surf->material ) - { - const_cast( surf )->material = material; - } - newDrawSurfs[i] = const_cast( surf ); - } - - for( vLight = viewDef->viewLights; vLight; vLight = vLight->next ) - { - for( surf = vLight->localInteractions; surf; surf = surf->nextOnLight ) - { - const_cast( surf )->material = material; - newDrawSurfs[i++] = const_cast( surf ); - } - for( surf = vLight->globalInteractions; surf; surf = surf->nextOnLight ) - { - const_cast( surf )->material = material; - newDrawSurfs[i++] = const_cast( surf ); - } - vLight->localInteractions = NULL; - vLight->globalInteractions = NULL; - } - - switch( r_showOverDraw.GetInteger() ) - { - case 1: // geometry overdraw - const_cast( viewDef )->drawSurfs = newDrawSurfs; - const_cast( viewDef )->numDrawSurfs = numDrawSurfs; - break; - case 2: // light interaction overdraw - const_cast( viewDef )->drawSurfs = &newDrawSurfs[numDrawSurfs]; - const_cast( viewDef )->numDrawSurfs = interactions; - break; - case 3: // geometry + light interaction overdraw - const_cast( viewDef )->drawSurfs = newDrawSurfs; - const_cast( viewDef )->numDrawSurfs += interactions; - break; - } -} - -/* -=================== -idRenderBackend::DBG_ShowIntensity - -Debugging tool to see how much dynamic range a scene is using. -The greatest of the rgb values at each pixel will be used, with -the resulting color shading from red at 0 to green at 128 to blue at 255 -=================== -*/ -void idRenderBackend::DBG_ShowIntensity() -{ - byte* colorReadback; - int i, j, c; - - if( !r_showIntensity.GetBool() ) - { - return; - } - - colorReadback = ( byte* )R_StaticAlloc( renderSystem->GetWidth() * renderSystem->GetHeight() * 4, TAG_RENDER_TOOLS ); - glReadPixels( 0, 0, renderSystem->GetWidth(), renderSystem->GetHeight(), GL_RGBA, GL_UNSIGNED_BYTE, colorReadback ); - - c = renderSystem->GetWidth() * renderSystem->GetHeight() * 4; - for( i = 0; i < c; i += 4 ) - { - j = colorReadback[i]; - if( colorReadback[i + 1] > j ) - { - j = colorReadback[i + 1]; - } - if( colorReadback[i + 2] > j ) - { - j = colorReadback[i + 2]; - } - if( j < 128 ) - { - colorReadback[i + 0] = 2 * ( 128 - j ); - colorReadback[i + 1] = 2 * j; - colorReadback[i + 2] = 0; - } - else - { - colorReadback[i + 0] = 0; - colorReadback[i + 1] = 2 * ( 255 - j ); - colorReadback[i + 2] = 2 * ( j - 128 ); - } - } - - // draw it back to the screen - glLoadIdentity(); - glMatrixMode( GL_PROJECTION ); - GL_State( GLS_DEPTHFUNC_ALWAYS ); - glPushMatrix(); - glLoadIdentity(); - glOrtho( 0, 1, 0, 1, -1, 1 ); - glRasterPos2f( 0, 0 ); - glPopMatrix(); - GL_Color( 1, 1, 1 ); - globalImages->BindNull(); - glMatrixMode( GL_MODELVIEW ); - - glDrawPixels( renderSystem->GetWidth(), renderSystem->GetHeight(), GL_RGBA , GL_UNSIGNED_BYTE, colorReadback ); - - R_StaticFree( colorReadback ); -} - - -/* -=================== -idRenderBackend::DBG_ShowDepthBuffer - -Draw the depth buffer as colors -=================== -*/ -void idRenderBackend::DBG_ShowDepthBuffer() -{ - void* depthReadback; - - if( !r_showDepth.GetBool() ) - { - return; - } - - glPushMatrix(); - glLoadIdentity(); - glMatrixMode( GL_PROJECTION ); - glPushMatrix(); - glLoadIdentity(); - glOrtho( 0, 1, 0, 1, -1, 1 ); - glRasterPos2f( 0, 0 ); - glPopMatrix(); - glMatrixMode( GL_MODELVIEW ); - glPopMatrix(); - - GL_State( GLS_DEPTHFUNC_ALWAYS ); - GL_Color( 1, 1, 1 ); - globalImages->BindNull(); - - depthReadback = R_StaticAlloc( renderSystem->GetWidth() * renderSystem->GetHeight() * 4, TAG_RENDER_TOOLS ); - memset( depthReadback, 0, renderSystem->GetWidth() * renderSystem->GetHeight() * 4 ); - - glReadPixels( 0, 0, renderSystem->GetWidth(), renderSystem->GetHeight(), GL_DEPTH_COMPONENT , GL_FLOAT, depthReadback ); - -#if 0 - for( i = 0; i < renderSystem->GetWidth() * renderSystem->GetHeight(); i++ ) - { - ( ( byte* )depthReadback )[i * 4] = - ( ( byte* )depthReadback )[i * 4 + 1] = - ( ( byte* )depthReadback )[i * 4 + 2] = 255 * ( ( float* )depthReadback )[i]; - ( ( byte* )depthReadback )[i * 4 + 3] = 1; - } -#endif - - glDrawPixels( renderSystem->GetWidth(), renderSystem->GetHeight(), GL_RGBA , GL_UNSIGNED_BYTE, depthReadback ); - R_StaticFree( depthReadback ); -} - -/* -================= -idRenderBackend::DBG_ShowLightCount - -This is a debugging tool that will draw each surface with a color -based on how many lights are effecting it -================= -*/ -void idRenderBackend::DBG_ShowLightCount() -{ - int i; - const drawSurf_t* surf; - const viewLight_t* vLight; - - if( !r_showLightCount.GetBool() ) - { - return; - } - - DBG_SimpleWorldSetup(); - - GL_Clear( false, false, true, 0, 0.0f, 0.0f, 0.0f, 0.0f ); - - // optionally count everything through walls - if( r_showLightCount.GetInteger() >= 2 ) - { - GL_State( GLS_DEPTHFUNC_EQUAL | GLS_STENCIL_OP_FAIL_KEEP | GLS_STENCIL_OP_ZFAIL_INCR | GLS_STENCIL_OP_PASS_INCR ); - } - else - { - GL_State( GLS_DEPTHFUNC_EQUAL | GLS_STENCIL_OP_FAIL_KEEP | GLS_STENCIL_OP_ZFAIL_KEEP | GLS_STENCIL_OP_PASS_INCR ); - } - - globalImages->defaultImage->Bind(); - - for( vLight = viewDef->viewLights; vLight; vLight = vLight->next ) - { - for( i = 0; i < 2; i++ ) - { - for( surf = i ? vLight->localInteractions : vLight->globalInteractions; surf; surf = ( drawSurf_t* )surf->nextOnLight ) - { - DBG_SimpleSurfaceSetup( surf ); - DrawElementsWithCounters( surf ); - } - } - } - - // display the results - DBG_ColorByStencilBuffer(); - - if( r_showLightCount.GetInteger() > 2 ) - { - DBG_CountStencilBuffer(); - } -} - -/* -==================== -idRenderBackend::DBG_RenderDrawSurfListWithFunction - -The triangle functions can check backEnd.currentSpace != surf->space -to see if they need to perform any new matrix setup. The modelview -matrix will already have been loaded, and backEnd.currentSpace will -be updated after the triangle function completes. -==================== -*/ -void idRenderBackend::DBG_RenderDrawSurfListWithFunction( drawSurf_t** drawSurfs, int numDrawSurfs ) -{ - currentSpace = NULL; - - for( int i = 0 ; i < numDrawSurfs ; i++ ) - { - const drawSurf_t* drawSurf = drawSurfs[i]; - if( drawSurf == NULL ) - { - continue; - } - - assert( drawSurf->space != NULL ); - - // RB begin -#if 1 - if( drawSurf->space != currentSpace ) - { - currentSpace = drawSurf->space; - - RB_SetMVP( drawSurf->space->mvp ); - } -#else - - if( drawSurf->space != NULL ) // is it ever NULL? Do we need to check? - { - // Set these values ahead of time so we don't have to reconstruct the matrices on the consoles - if( drawSurf->space->weaponDepthHack ) - { - RB_SetWeaponDepthHack(); - } - - if( drawSurf->space->modelDepthHack != 0.0f ) - { - RB_SetModelDepthHack( drawSurf->space->modelDepthHack ); - } - - // change the matrix if needed - if( drawSurf->space != backEnd.currentSpace ) - { - RB_LoadMatrixWithBypass( drawSurf->space->modelViewMatrix ); - } - - if( drawSurf->space->weaponDepthHack ) - { - RB_EnterWeaponDepthHack(); - } - - if( drawSurf->space->modelDepthHack != 0.0f ) - { - RB_EnterModelDepthHack( drawSurf->space->modelDepthHack ); - } - } -#endif - - if( drawSurf->jointCache ) - { - renderProgManager.BindShader_ColorSkinned(); - } - else - { - renderProgManager.BindShader_Color(); - } - // RB end - - // change the scissor if needed - if( r_useScissor.GetBool() && !currentScissor.Equals( drawSurf->scissorRect ) ) - { - currentScissor = drawSurf->scissorRect; - - GL_Scissor( viewDef->viewport.x1 + currentScissor.x1, - viewDef->viewport.y1 + currentScissor.y1, - currentScissor.x2 + 1 - currentScissor.x1, - currentScissor.y2 + 1 - currentScissor.y1 ); - } - - // render it - DrawElementsWithCounters( drawSurf ); - - // RB begin - /*if( drawSurf->space != NULL && ( drawSurf->space->weaponDepthHack || drawSurf->space->modelDepthHack != 0.0f ) ) - { - RB_LeaveDepthHack(); - }*/ - // RB end - - currentSpace = drawSurf->space; - } -} - -/* -================= -idRenderBackend::DBG_ShowSilhouette - -Blacks out all edges, then adds color for each edge that a shadow -plane extends from, allowing you to see doubled edges - -FIXME: not thread safe! -================= -*/ -void idRenderBackend::DBG_ShowSilhouette() -{ - int i; - const drawSurf_t* surf; - const viewLight_t* vLight; - - if( !r_showSilhouette.GetBool() ) - { - return; - } - - // clear all triangle edges to black - globalImages->BindNull(); - - // RB begin - renderProgManager.BindShader_Color(); - // RB end - - GL_Color( 0, 0, 0 ); - - GL_State( GLS_DEPTHFUNC_ALWAYS | GLS_POLYMODE_LINE ); - - GL_Cull( CT_TWO_SIDED ); - - DBG_RenderDrawSurfListWithFunction( viewDef->drawSurfs, viewDef->numDrawSurfs ); - - - // now blend in edges that cast silhouettes - DBG_SimpleWorldSetup(); - - GL_Color( 0.5, 0, 0 ); - GL_State( GLS_SRCBLEND_ONE | GLS_DSTBLEND_ONE ); - - for( vLight = viewDef->viewLights; vLight; vLight = vLight->next ) - { - for( i = 0; i < 2; i++ ) - { - for( surf = i ? vLight->localShadows : vLight->globalShadows - ; surf; surf = ( drawSurf_t* )surf->nextOnLight ) - { - DBG_SimpleSurfaceSetup( surf ); - - const srfTriangles_t* tri = surf->frontEndGeo; - - idVertexBuffer vertexBuffer; - if( !vertexCache.GetVertexBuffer( tri->shadowCache, &vertexBuffer ) ) - { - continue; - } - - // RB: 64 bit fixes, changed GLuint to GLintptr - glBindBuffer( GL_ARRAY_BUFFER, ( GLintptr )vertexBuffer.GetAPIObject() ); - GLintptr vertOffset = vertexBuffer.GetOffset(); - // RB end - - glVertexPointer( 3, GL_FLOAT, sizeof( idShadowVert ), ( void* )vertOffset ); - glBegin( GL_LINES ); - - for( int j = 0; j < tri->numIndexes; j += 3 ) - { - int i1 = tri->indexes[j + 0]; - int i2 = tri->indexes[j + 1]; - int i3 = tri->indexes[j + 2]; - - if( ( i1 & 1 ) + ( i2 & 1 ) + ( i3 & 1 ) == 1 ) - { - if( ( i1 & 1 ) + ( i2 & 1 ) == 0 ) - { - glArrayElement( i1 ); - glArrayElement( i2 ); - } - else if( ( i1 & 1 ) + ( i3 & 1 ) == 0 ) - { - glArrayElement( i1 ); - glArrayElement( i3 ); - } - } - } - glEnd(); - - } - } - } - - GL_State( GLS_DEFAULT ); - GL_Color( 1, 1, 1 ); - GL_Cull( CT_FRONT_SIDED ); -} - -/* -===================== -idRenderBackend::DBG_ShowTris - -Debugging tool -===================== -*/ -void idRenderBackend::DBG_ShowTris( drawSurf_t** drawSurfs, int numDrawSurfs ) -{ - - modelTrace_t mt; - idVec3 end; - - if( r_showTris.GetInteger() == 0 ) - { - return; - } - - idVec4 color( 1, 1, 1, 1 ); - - GL_PolygonOffset( -1.0f, -2.0f ); - - switch( r_showTris.GetInteger() ) - { - case 1: // only draw visible ones - GL_State( GLS_DEPTHMASK | GLS_ALPHAMASK | GLS_POLYMODE_LINE | GLS_POLYGON_OFFSET ); - break; - case 2: // draw all front facing - case 3: // draw all - GL_State( GLS_DEPTHMASK | GLS_ALPHAMASK | GLS_POLYMODE_LINE | GLS_POLYGON_OFFSET | GLS_DEPTHFUNC_ALWAYS ); - break; - case 4: // only draw visible ones with blended lines - GL_State( GLS_DEPTHMASK | GLS_ALPHAMASK | GLS_POLYMODE_LINE | GLS_POLYGON_OFFSET | GLS_SRCBLEND_SRC_ALPHA | GLS_DSTBLEND_ONE_MINUS_SRC_ALPHA ); - color[3] = 0.4f; - break; - } - - if( r_showTris.GetInteger() == 3 ) - { - GL_Cull( CT_TWO_SIDED ); - } - - GL_Color( color ); - - DBG_RenderDrawSurfListWithFunction( drawSurfs, numDrawSurfs ); - - if( r_showTris.GetInteger() == 3 ) - { - GL_Cull( CT_FRONT_SIDED ); - } -} - -/* -===================== -idRenderBackend::DBG_ShowSurfaceInfo - -Debugging tool -===================== -*/ - - -static idStr surfModelName, surfMatName; -static idVec3 surfPoint; -static bool surfTraced = false; - - -void idRenderSystemLocal::OnFrame() -{ - // Do tracing at a safe time to avoid threading issues. - modelTrace_t mt; - idVec3 start, end; - - surfTraced = false; - - if( !r_showSurfaceInfo.GetBool() ) - { - return; - } - - if( tr.primaryView == NULL ) - { - return; - } - - // start far enough away that we don't hit the player model - start = tr.primaryView->renderView.vieworg + tr.primaryView->renderView.viewaxis[0] * 32; - end = start + tr.primaryView->renderView.viewaxis[0] * 1000.0f; - if( !tr.primaryWorld->Trace( mt, start, end, 0.0f, false ) ) - { - return; - } - - surfPoint = mt.point; - surfModelName = mt.entity->hModel->Name(); - surfMatName = mt.material->GetName(); - surfTraced = true; -} - - -void idRenderBackend::DBG_ShowSurfaceInfo( drawSurf_t** drawSurfs, int numDrawSurfs ) -{ - if( !r_showSurfaceInfo.GetBool() || !surfTraced ) - { - return; - } - - // globalImages->BindNull(); - // qglDisable( GL_TEXTURE_2D ); - - DBG_SimpleWorldSetup(); - - // foresthale 2014-05-02: don't use a shader for tools - //renderProgManager.BindShader_TextureVertexColor(); - GL_SelectTexture( 0 ); - globalImages->whiteImage->Bind(); - - RB_SetVertexColorParms( SVC_MODULATE ); - // foresthale 2014-05-02: don't use a shader for tools - //renderProgManager.CommitUniforms(); - - GL_Color( 1, 1, 1 ); - - static float scale = -1; - static float bias = -2; - - GL_PolygonOffset( scale, bias ); - GL_State( GLS_DEPTHFUNC_ALWAYS | GLS_POLYMODE_LINE | GLS_POLYGON_OFFSET ); - - // idVec3 trans[3]; - // float matrix[16]; - - // transform the object verts into global space - // R_AxisToModelMatrix( mt.entity->axis, mt.entity->origin, matrix ); - - tr.primaryWorld->DrawText( surfModelName, surfPoint + tr.primaryView->renderView.viewaxis[2] * 12, - 0.35f, colorRed, tr.primaryView->renderView.viewaxis ); - tr.primaryWorld->DrawText( surfMatName, surfPoint, - 0.35f, colorBlue, tr.primaryView->renderView.viewaxis ); -} - -/* -===================== -idRenderBackend::DBG_ShowViewEntitys - -Debugging tool -===================== -*/ -void idRenderBackend::DBG_ShowViewEntitys( viewEntity_t* vModels ) -{ - if( !r_showViewEntitys.GetBool() ) - { - return; - } - - if( r_showViewEntitys.GetInteger() >= 2 ) - { - common->Printf( "view entities: " ); - for( const viewEntity_t* vModel = vModels; vModel; vModel = vModel->next ) - { - if( vModel->entityDef->IsDirectlyVisible() ) - { - common->Printf( "<%i> ", vModel->entityDef->index ); - } - else - { - common->Printf( "%i ", vModel->entityDef->index ); - } - } - common->Printf( "\n" ); - } - - globalImages->BindNull(); - - renderProgManager.BindShader_Color(); - - GL_Color( 1, 1, 1 ); - GL_State( GLS_DEPTHFUNC_ALWAYS | GLS_POLYMODE_LINE ); - GL_Cull( CT_TWO_SIDED ); - - for( const viewEntity_t* vModel = vModels; vModel; vModel = vModel->next ) - { - idBounds b; - - //glLoadMatrixf( vModel->modelViewMatrix ); - - const idRenderEntityLocal* edef = vModel->entityDef; - if( !edef ) - { - continue; - } - - // draw the model bounds in white if directly visible, - // or, blue if it is only-for-sahdow - idVec4 color; - if( edef->IsDirectlyVisible() ) - { - color.Set( 1, 1, 1, 1 ); - } - else - { - color.Set( 0, 0, 1, 1 ); - } - GL_Color( color[0], color[1], color[2] ); - RB_DrawBounds( edef->localReferenceBounds ); - - // transform the upper bounds corner into global space - if( r_showViewEntitys.GetInteger() >= 2 ) - { - idVec3 corner; - R_LocalPointToGlobal( vModel->modelMatrix, edef->localReferenceBounds[1], corner ); - - tr.primaryWorld->DrawText( - va( "%i:%s", edef->index, edef->parms.hModel->Name() ), - corner, - 0.25f, color, - tr.primaryView->renderView.viewaxis ); - } - - // draw the actual bounds in yellow if different - if( r_showViewEntitys.GetInteger() >= 3 ) - { - GL_Color( 1, 1, 0 ); - // FIXME: cannot instantiate a dynamic model from the renderer back-end - idRenderModel* model = R_EntityDefDynamicModel( vModel->entityDef ); - if( !model ) - { - continue; // particles won't instantiate without a current view - } - b = model->Bounds( &vModel->entityDef->parms ); - if( b != vModel->entityDef->localReferenceBounds ) - { - RB_DrawBounds( b ); - } - } - } -} - -/* -===================== -idRenderBackend::DBG_ShowTexturePolarity - -Shade triangle red if they have a positive texture area -green if they have a negative texture area, or blue if degenerate area -===================== -*/ -void idRenderBackend::DBG_ShowTexturePolarity( drawSurf_t** drawSurfs, int numDrawSurfs ) -{ - int i, j; - drawSurf_t* drawSurf; - const srfTriangles_t* tri; - - if( !r_showTexturePolarity.GetBool() ) - { - return; - } - globalImages->BindNull(); - - GL_State( GLS_SRCBLEND_SRC_ALPHA | GLS_DSTBLEND_ONE_MINUS_SRC_ALPHA ); - - GL_Color( 1, 1, 1 ); - - for( i = 0; i < numDrawSurfs; i++ ) - { - drawSurf = drawSurfs[i]; - tri = drawSurf->frontEndGeo; - if( tri == NULL || tri->verts == NULL ) - { - continue; - } - - DBG_SimpleSurfaceSetup( drawSurf ); - - glBegin( GL_TRIANGLES ); - for( j = 0; j < tri->numIndexes; j += 3 ) - { - idDrawVert* a, *b, *c; - float d0[5], d1[5]; - float area; - - a = tri->verts + tri->indexes[j]; - b = tri->verts + tri->indexes[j + 1]; - c = tri->verts + tri->indexes[j + 2]; - - const idVec2 aST = a->GetTexCoord(); - const idVec2 bST = b->GetTexCoord(); - const idVec2 cST = c->GetTexCoord(); - - d0[3] = bST[0] - aST[0]; - d0[4] = bST[1] - aST[1]; - - d1[3] = cST[0] - aST[0]; - d1[4] = cST[1] - aST[1]; - - area = d0[3] * d1[4] - d0[4] * d1[3]; - - if( idMath::Fabs( area ) < 0.0001 ) - { - GL_Color( 0, 0, 1, 0.5 ); - } - else if( area < 0 ) - { - GL_Color( 1, 0, 0, 0.5 ); - } - else - { - GL_Color( 0, 1, 0, 0.5 ); - } - glVertex3fv( a->xyz.ToFloatPtr() ); - glVertex3fv( b->xyz.ToFloatPtr() ); - glVertex3fv( c->xyz.ToFloatPtr() ); - } - glEnd(); - } - - GL_State( GLS_DEFAULT ); -} - -/* -===================== -idRenderBackend::DBG_ShowUnsmoothedTangents - -Shade materials that are using unsmoothed tangents -===================== -*/ -void idRenderBackend::DBG_ShowUnsmoothedTangents( drawSurf_t** drawSurfs, int numDrawSurfs ) -{ - int i, j; - drawSurf_t* drawSurf; - const srfTriangles_t* tri; - - if( !r_showUnsmoothedTangents.GetBool() ) - { - return; - } - globalImages->BindNull(); - - GL_State( GLS_SRCBLEND_SRC_ALPHA | GLS_DSTBLEND_ONE_MINUS_SRC_ALPHA ); - - GL_Color( 0, 1, 0, 0.5 ); - - for( i = 0; i < numDrawSurfs; i++ ) - { - drawSurf = drawSurfs[i]; - - if( !drawSurf->material->UseUnsmoothedTangents() ) - { - continue; - } - - DBG_SimpleSurfaceSetup( drawSurf ); - - tri = drawSurf->frontEndGeo; - if( tri == NULL || tri->verts == NULL ) - { - continue; - } - - glBegin( GL_TRIANGLES ); - for( j = 0; j < tri->numIndexes; j += 3 ) - { - idDrawVert* a, *b, *c; - - a = tri->verts + tri->indexes[j]; - b = tri->verts + tri->indexes[j + 1]; - c = tri->verts + tri->indexes[j + 2]; - - glVertex3fv( a->xyz.ToFloatPtr() ); - glVertex3fv( b->xyz.ToFloatPtr() ); - glVertex3fv( c->xyz.ToFloatPtr() ); - } - glEnd(); - } - - GL_State( GLS_DEFAULT ); -} - -/* -===================== -RB_ShowTangentSpace - -Shade a triangle by the RGB colors of its tangent space -1 = tangents[0] -2 = tangents[1] -3 = normal -===================== -*/ -void idRenderBackend::DBG_ShowTangentSpace( drawSurf_t** drawSurfs, int numDrawSurfs ) -{ - int i, j; - drawSurf_t* drawSurf; - const srfTriangles_t* tri; - - if( !r_showTangentSpace.GetInteger() ) - { - return; - } - globalImages->BindNull(); - - GL_State( GLS_SRCBLEND_SRC_ALPHA | GLS_DSTBLEND_ONE_MINUS_SRC_ALPHA ); - - for( i = 0; i < numDrawSurfs; i++ ) - { - drawSurf = drawSurfs[i]; - - DBG_SimpleSurfaceSetup( drawSurf ); - - tri = drawSurf->frontEndGeo; - if( tri == NULL || tri->verts == NULL ) - { - continue; - } - - glBegin( GL_TRIANGLES ); - for( j = 0; j < tri->numIndexes; j++ ) - { - const idDrawVert* v; - - v = &tri->verts[tri->indexes[j]]; - - if( r_showTangentSpace.GetInteger() == 1 ) - { - const idVec3 vertexTangent = v->GetTangent(); - GL_Color( 0.5 + 0.5 * vertexTangent[0], 0.5 + 0.5 * vertexTangent[1], - 0.5 + 0.5 * vertexTangent[2], 0.5 ); - } - else if( r_showTangentSpace.GetInteger() == 2 ) - { - const idVec3 vertexBiTangent = v->GetBiTangent(); - GL_Color( 0.5 + 0.5 * vertexBiTangent[0], 0.5 + 0.5 * vertexBiTangent[1], - 0.5 + 0.5 * vertexBiTangent[2], 0.5 ); - } - else - { - const idVec3 vertexNormal = v->GetNormal(); - GL_Color( 0.5 + 0.5 * vertexNormal[0], 0.5 + 0.5 * vertexNormal[1], - 0.5 + 0.5 * vertexNormal[2], 0.5 ); - } - glVertex3fv( v->xyz.ToFloatPtr() ); - } - glEnd(); - } - - GL_State( GLS_DEFAULT ); -} - -/* -===================== -idRenderBackend::DBG_ShowVertexColor - -Draw each triangle with the solid vertex colors -===================== -*/ -void idRenderBackend::DBG_ShowVertexColor( drawSurf_t** drawSurfs, int numDrawSurfs ) -{ - int i, j; - drawSurf_t* drawSurf; - const srfTriangles_t* tri; - - if( !r_showVertexColor.GetBool() ) - { - return; - } - globalImages->BindNull(); - - // RB begin - renderProgManager.BindShader_VertexColor(); - - GL_State( GLS_DEPTHFUNC_LESS ); - - for( i = 0; i < numDrawSurfs; i++ ) - { - drawSurf = drawSurfs[i]; - - DBG_SimpleSurfaceSetup( drawSurf ); - - tri = drawSurf->frontEndGeo; - if( tri == NULL || tri->verts == NULL ) - { - continue; - } - - renderProgManager.CommitUniforms(); - - glBegin( GL_TRIANGLES ); - for( j = 0; j < tri->numIndexes; j++ ) - { - const idDrawVert* v; - - v = &tri->verts[tri->indexes[j]]; - glColor4ubv( v->color ); - glVertex3fv( v->xyz.ToFloatPtr() ); - } - glEnd(); - } - - // RB end - - GL_State( GLS_DEFAULT ); -} - -/* -===================== -idRenderBackend::DBG_ShowNormals - -Debugging tool -===================== -*/ -void idRenderBackend::DBG_ShowNormals( drawSurf_t** drawSurfs, int numDrawSurfs ) -{ - int i, j; - drawSurf_t* drawSurf; - idVec3 end; - const srfTriangles_t* tri; - float size; - bool showNumbers; - idVec3 pos; - - if( r_showNormals.GetFloat() == 0.0f ) - { - return; - } - - globalImages->BindNull(); - - if( !r_debugLineDepthTest.GetBool() ) - { - GL_State( GLS_POLYMODE_LINE | GLS_DEPTHFUNC_ALWAYS ); - } - else - { - GL_State( GLS_POLYMODE_LINE ); - } - - size = r_showNormals.GetFloat(); - if( size < 0.0f ) - { - size = -size; - showNumbers = true; - } - else - { - showNumbers = false; - } - - for( i = 0; i < numDrawSurfs; i++ ) - { - drawSurf = drawSurfs[i]; - - DBG_SimpleSurfaceSetup( drawSurf ); - - tri = drawSurf->frontEndGeo; - if( tri == NULL || tri->verts == NULL ) - { - continue; - } - - // RB begin - renderProgManager.BindShader_VertexColor(); - - glBegin( GL_LINES ); - for( j = 0; j < tri->numVerts; j++ ) - { - const idVec3 normal = tri->verts[j].GetNormal(); - const idVec3 tangent = tri->verts[j].GetTangent(); - const idVec3 bitangent = tri->verts[j].GetBiTangent(); - - glColor3f( 0, 0, 1 ); - glVertex3fv( tri->verts[j].xyz.ToFloatPtr() ); - VectorMA( tri->verts[j].xyz, size, normal, end ); - glVertex3fv( end.ToFloatPtr() ); - - glColor3f( 1, 0, 0 ); - glVertex3fv( tri->verts[j].xyz.ToFloatPtr() ); - VectorMA( tri->verts[j].xyz, size, tangent, end ); - glVertex3fv( end.ToFloatPtr() ); - - glColor3f( 0, 1, 0 ); - glVertex3fv( tri->verts[j].xyz.ToFloatPtr() ); - VectorMA( tri->verts[j].xyz, size, bitangent, end ); - glVertex3fv( end.ToFloatPtr() ); - } - glEnd(); - - // RB end - } - - if( showNumbers ) - { - DBG_SimpleWorldSetup(); - - for( i = 0; i < numDrawSurfs; i++ ) - { - drawSurf = drawSurfs[i]; - tri = drawSurf->frontEndGeo; - if( tri == NULL || tri->verts == NULL ) - { - continue; - } - - for( j = 0; j < tri->numVerts; j++ ) - { - const idVec3 normal = tri->verts[j].GetNormal(); - const idVec3 tangent = tri->verts[j].GetTangent(); - R_LocalPointToGlobal( drawSurf->space->modelMatrix, tri->verts[j].xyz + tangent + normal * 0.2f, pos ); - RB_DrawText( va( "%d", j ), pos, 0.01f, colorWhite, viewDef->renderView.viewaxis, 1 ); - } - - for( j = 0; j < tri->numIndexes; j += 3 ) - { - const idVec3 normal = tri->verts[ tri->indexes[ j + 0 ] ].GetNormal(); - R_LocalPointToGlobal( drawSurf->space->modelMatrix, ( tri->verts[ tri->indexes[ j + 0 ] ].xyz + tri->verts[ tri->indexes[ j + 1 ] ].xyz + tri->verts[ tri->indexes[ j + 2 ] ].xyz ) * ( 1.0f / 3.0f ) + normal * 0.2f, pos ); - RB_DrawText( va( "%d", j / 3 ), pos, 0.01f, colorCyan, viewDef->renderView.viewaxis, 1 ); - } - } - } -} - -/* -===================== -idRenderBackend::DBG_ShowTextureVectors - -Draw texture vectors in the center of each triangle -===================== -*/ -void idRenderBackend::DBG_ShowTextureVectors( drawSurf_t** drawSurfs, int numDrawSurfs ) -{ - if( r_showTextureVectors.GetFloat() == 0.0f ) - { - return; - } - - GL_State( GLS_DEPTHFUNC_LESS ); - - globalImages->BindNull(); - - for( int i = 0; i < numDrawSurfs; i++ ) - { - drawSurf_t* drawSurf = drawSurfs[i]; - - const srfTriangles_t* tri = drawSurf->frontEndGeo; - - if( tri == NULL || tri->verts == NULL ) - { - continue; - } - - DBG_SimpleSurfaceSetup( drawSurf ); - - // draw non-shared edges in yellow - glBegin( GL_LINES ); - - for( int j = 0; j < tri->numIndexes; j += 3 ) - { - float d0[5], d1[5]; - idVec3 temp; - idVec3 tangents[2]; - - const idDrawVert* a = &tri->verts[tri->indexes[j + 0]]; - const idDrawVert* b = &tri->verts[tri->indexes[j + 1]]; - const idDrawVert* c = &tri->verts[tri->indexes[j + 2]]; - - const idPlane plane( a->xyz, b->xyz, c->xyz ); - - // make the midpoint slightly above the triangle - const idVec3 mid = ( a->xyz + b->xyz + c->xyz ) * ( 1.0f / 3.0f ) + 0.1f * plane.Normal(); - - // calculate the texture vectors - const idVec2 aST = a->GetTexCoord(); - const idVec2 bST = b->GetTexCoord(); - const idVec2 cST = c->GetTexCoord(); - - d0[0] = b->xyz[0] - a->xyz[0]; - d0[1] = b->xyz[1] - a->xyz[1]; - d0[2] = b->xyz[2] - a->xyz[2]; - d0[3] = bST[0] - aST[0]; - d0[4] = bST[1] - aST[1]; - - d1[0] = c->xyz[0] - a->xyz[0]; - d1[1] = c->xyz[1] - a->xyz[1]; - d1[2] = c->xyz[2] - a->xyz[2]; - d1[3] = cST[0] - aST[0]; - d1[4] = cST[1] - aST[1]; - - const float area = d0[3] * d1[4] - d0[4] * d1[3]; - if( area == 0 ) - { - continue; - } - const float inva = 1.0f / area; - - temp[0] = ( d0[0] * d1[4] - d0[4] * d1[0] ) * inva; - temp[1] = ( d0[1] * d1[4] - d0[4] * d1[1] ) * inva; - temp[2] = ( d0[2] * d1[4] - d0[4] * d1[2] ) * inva; - temp.Normalize(); - tangents[0] = temp; - - temp[0] = ( d0[3] * d1[0] - d0[0] * d1[3] ) * inva; - temp[1] = ( d0[3] * d1[1] - d0[1] * d1[3] ) * inva; - temp[2] = ( d0[3] * d1[2] - d0[2] * d1[3] ) * inva; - temp.Normalize(); - tangents[1] = temp; - - // draw the tangents - tangents[0] = mid + tangents[0] * r_showTextureVectors.GetFloat(); - tangents[1] = mid + tangents[1] * r_showTextureVectors.GetFloat(); - - GL_Color( 1, 0, 0 ); - glVertex3fv( mid.ToFloatPtr() ); - glVertex3fv( tangents[0].ToFloatPtr() ); - - GL_Color( 0, 1, 0 ); - glVertex3fv( mid.ToFloatPtr() ); - glVertex3fv( tangents[1].ToFloatPtr() ); - } - - glEnd(); - } -} - -/* -===================== -idRenderBackend::DBG_ShowDominantTris - -Draw lines from each vertex to the dominant triangle center -===================== -*/ -void idRenderBackend::DBG_ShowDominantTris( drawSurf_t** drawSurfs, int numDrawSurfs ) -{ - int i, j; - drawSurf_t* drawSurf; - const srfTriangles_t* tri; - - if( !r_showDominantTri.GetBool() ) - { - return; - } - - GL_State( GLS_DEPTHFUNC_LESS ); - - GL_PolygonOffset( -1, -2 ); - glEnable( GL_POLYGON_OFFSET_LINE ); - - globalImages->BindNull(); - - for( i = 0; i < numDrawSurfs; i++ ) - { - drawSurf = drawSurfs[i]; - - tri = drawSurf->frontEndGeo; - - if( tri == NULL || tri->verts == NULL ) - { - continue; - } - if( !tri->dominantTris ) - { - continue; - } - - DBG_SimpleSurfaceSetup( drawSurf ); - - GL_Color( 1, 1, 0 ); - glBegin( GL_LINES ); - - for( j = 0; j < tri->numVerts; j++ ) - { - const idDrawVert* a, *b, *c; - idVec3 mid; - - // find the midpoint of the dominant tri - - a = &tri->verts[j]; - b = &tri->verts[tri->dominantTris[j].v2]; - c = &tri->verts[tri->dominantTris[j].v3]; - - mid = ( a->xyz + b->xyz + c->xyz ) * ( 1.0f / 3.0f ); - - glVertex3fv( mid.ToFloatPtr() ); - glVertex3fv( a->xyz.ToFloatPtr() ); - } - - glEnd(); - } - glDisable( GL_POLYGON_OFFSET_LINE ); -} - -/* -===================== -idRenderBackend::DBG_ShowEdges - -Debugging tool -===================== -*/ -void idRenderBackend::DBG_ShowEdges( drawSurf_t** drawSurfs, int numDrawSurfs ) -{ - int i, j, k, m, n, o; - drawSurf_t* drawSurf; - const srfTriangles_t* tri; - const silEdge_t* edge; - int danglePlane; - - if( !r_showEdges.GetBool() ) - { - return; - } - - globalImages->BindNull(); - - GL_State( GLS_DEPTHFUNC_ALWAYS ); - - for( i = 0; i < numDrawSurfs; i++ ) - { - drawSurf = drawSurfs[i]; - - tri = drawSurf->frontEndGeo; - - idDrawVert* ac = ( idDrawVert* )tri->verts; - if( !ac ) - { - continue; - } - - DBG_SimpleSurfaceSetup( drawSurf ); - - // draw non-shared edges in yellow - GL_Color( 1, 1, 0 ); - glBegin( GL_LINES ); - - for( j = 0; j < tri->numIndexes; j += 3 ) - { - for( k = 0; k < 3; k++ ) - { - int l, i1, i2; - l = ( k == 2 ) ? 0 : k + 1; - i1 = tri->indexes[j + k]; - i2 = tri->indexes[j + l]; - - // if these are used backwards, the edge is shared - for( m = 0; m < tri->numIndexes; m += 3 ) - { - for( n = 0; n < 3; n++ ) - { - o = ( n == 2 ) ? 0 : n + 1; - if( tri->indexes[m + n] == i2 && tri->indexes[m + o] == i1 ) - { - break; - } - } - if( n != 3 ) - { - break; - } - } - - // if we didn't find a backwards listing, draw it in yellow - if( m == tri->numIndexes ) - { - glVertex3fv( ac[ i1 ].xyz.ToFloatPtr() ); - glVertex3fv( ac[ i2 ].xyz.ToFloatPtr() ); - } - - } - } - - glEnd(); - - // draw dangling sil edges in red - if( !tri->silEdges ) - { - continue; - } - - // the plane number after all real planes - // is the dangling edge - danglePlane = tri->numIndexes / 3; - - GL_Color( 1, 0, 0 ); - - glBegin( GL_LINES ); - for( j = 0; j < tri->numSilEdges; j++ ) - { - edge = tri->silEdges + j; - - if( edge->p1 != danglePlane && edge->p2 != danglePlane ) - { - continue; - } - - glVertex3fv( ac[ edge->v1 ].xyz.ToFloatPtr() ); - glVertex3fv( ac[ edge->v2 ].xyz.ToFloatPtr() ); - } - glEnd(); - } -} - -/* -============== -RB_ShowLights - -Visualize all light volumes used in the current scene -r_showLights 1 : just print volumes numbers, highlighting ones covering the view -r_showLights 2 : also draw planes of each volume -r_showLights 3 : also draw edges of each volume -============== -*/ -void idRenderBackend::DBG_ShowLights() -{ - if( !r_showLights.GetInteger() ) - { - return; - } - - GL_State( GLS_DEFAULT ); - - globalImages->BindNull(); - - renderProgManager.BindShader_Color(); - - GL_Cull( CT_TWO_SIDED ); - - common->Printf( "volumes: " ); // FIXME: not in back end! - - int count = 0; - for( viewLight_t* vLight = viewDef->viewLights; vLight != NULL; vLight = vLight->next ) - { - count++; - - // depth buffered planes - if( r_showLights.GetInteger() >= 2 ) - { - GL_State( GLS_DEPTHFUNC_ALWAYS | GLS_SRCBLEND_SRC_ALPHA | GLS_DSTBLEND_ONE_MINUS_SRC_ALPHA | GLS_DEPTHMASK ); - - // RB: show different light types - if( vLight->parallel ) - { - GL_Color( 1.0f, 0.0f, 0.0f, 0.25f ); - } - else if( vLight->pointLight ) - { - GL_Color( 0.0f, 0.0f, 1.0f, 0.25f ); - } - else - { - GL_Color( 0.0f, 1.0f, 0.0f, 0.25f ); - } - // RB end - - idRenderMatrix invProjectMVPMatrix; - idRenderMatrix::Multiply( viewDef->worldSpace.mvp, vLight->inverseBaseLightProject, invProjectMVPMatrix ); - RB_SetMVP( invProjectMVPMatrix ); - DrawElementsWithCounters( &zeroOneCubeSurface ); - } - - // non-hidden lines - if( r_showLights.GetInteger() >= 3 ) - { - GL_State( GLS_DEPTHFUNC_ALWAYS | GLS_POLYMODE_LINE | GLS_DEPTHMASK ); - GL_Color( 1.0f, 1.0f, 1.0f ); - idRenderMatrix invProjectMVPMatrix; - idRenderMatrix::Multiply( viewDef->worldSpace.mvp, vLight->inverseBaseLightProject, invProjectMVPMatrix ); - RB_SetMVP( invProjectMVPMatrix ); - DrawElementsWithCounters( &zeroOneCubeSurface ); - } - - common->Printf( "%i ", vLight->lightDef->index ); - } - - common->Printf( " = %i total\n", count ); -} - -// RB begin -void idRenderBackend::DBG_ShowShadowMapLODs() -{ - if( !r_showShadowMapLODs.GetInteger() ) - { - return; - } - - GL_State( GLS_DEFAULT ); - - globalImages->BindNull(); - - renderProgManager.BindShader_Color(); - - GL_Cull( CT_TWO_SIDED ); - - common->Printf( "volumes: " ); // FIXME: not in back end! - - int count = 0; - for( viewLight_t* vLight = viewDef->viewLights; vLight != NULL; vLight = vLight->next ) - { - if( !vLight->lightDef->LightCastsShadows() ) - { - continue; - } - - count++; - - // depth buffered planes - if( r_showShadowMapLODs.GetInteger() >= 1 ) - { - GL_State( GLS_DEPTHFUNC_ALWAYS | GLS_SRCBLEND_SRC_ALPHA | GLS_DSTBLEND_ONE_MINUS_SRC_ALPHA | GLS_DEPTHMASK ); - - idVec4 c; - if( vLight->shadowLOD == 0 ) - { - c = colorRed; - } - else if( vLight->shadowLOD == 1 ) - { - c = colorGreen; - } - else if( vLight->shadowLOD == 2 ) - { - c = colorBlue; - } - else if( vLight->shadowLOD == 3 ) - { - c = colorYellow; - } - else if( vLight->shadowLOD == 4 ) - { - c = colorMagenta; - } - else if( vLight->shadowLOD == 5 ) - { - c = colorCyan; - } - else - { - c = colorMdGrey; - } - - c[3] = 0.25f; - GL_Color( c ); - - idRenderMatrix invProjectMVPMatrix; - idRenderMatrix::Multiply( viewDef->worldSpace.mvp, vLight->inverseBaseLightProject, invProjectMVPMatrix ); - RB_SetMVP( invProjectMVPMatrix ); - DrawElementsWithCounters( &zeroOneCubeSurface ); - } - - // non-hidden lines - if( r_showShadowMapLODs.GetInteger() >= 2 ) - { - GL_State( GLS_DEPTHFUNC_ALWAYS | GLS_POLYMODE_LINE | GLS_DEPTHMASK ); - GL_Color( 1.0f, 1.0f, 1.0f ); - idRenderMatrix invProjectMVPMatrix; - idRenderMatrix::Multiply( viewDef->worldSpace.mvp, vLight->inverseBaseLightProject, invProjectMVPMatrix ); - RB_SetMVP( invProjectMVPMatrix ); - DrawElementsWithCounters( &zeroOneCubeSurface ); - } - - common->Printf( "%i ", vLight->lightDef->index ); - } - - common->Printf( " = %i total\n", count ); -} -// RB end - -/* -===================== -idRenderBackend::DBG_ShowPortals - -Debugging tool, won't work correctly with SMP or when mirrors are present -===================== -*/ -void idRenderBackend::DBG_ShowPortals() -{ - if( !r_showPortals.GetBool() ) - { - return; - } - - // all portals are expressed in world coordinates - DBG_SimpleWorldSetup(); - - globalImages->BindNull(); - renderProgManager.BindShader_Color(); - GL_State( GLS_DEPTHFUNC_ALWAYS ); - - int i, j; - portalArea_t* area; - portal_t* p; - idWinding* w; - - idRenderWorldLocal& world = *viewDef->renderWorld; - - // flood out through portals, setting area viewCount - for( int i = 0; i < world.numPortalAreas; i++ ) - { - area = &world.portalAreas[i]; - if( area->viewCount != tr.viewCount ) - { - continue; - } - for( p = area->portals; p; p = p->next ) - { - w = p->w; - if( !w ) - { - continue; - } - - if( world.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(); - } - } -} - -/* -================ -idRenderBackend::DBG_ClearDebugText -================ -*/ -void RB_ClearDebugText( int time ) -{ - int i; - int num; - debugText_t* text; - - rb_debugTextTime = time; - - if( !time ) - { - // free up our strings - text = rb_debugText; - for( i = 0; i < MAX_DEBUG_TEXT; i++, text++ ) - { - text->text.Clear(); - } - rb_numDebugText = 0; - return; - } - - // copy any text that still needs to be drawn - num = 0; - text = rb_debugText; - for( i = 0; i < rb_numDebugText; i++, text++ ) - { - if( text->lifeTime > time ) - { - if( num != i ) - { - rb_debugText[ num ] = *text; - } - num++; - } - } - rb_numDebugText = num; -} - -/* -================ -RB_AddDebugText -================ -*/ -void RB_AddDebugText( const char* text, const idVec3& origin, float scale, const idVec4& color, const idMat3& viewAxis, const int align, const int lifetime, const bool depthTest ) -{ - debugText_t* debugText; - - if( rb_numDebugText < MAX_DEBUG_TEXT ) - { - debugText = &rb_debugText[ rb_numDebugText++ ]; - debugText->text = text; - debugText->origin = origin; - debugText->scale = scale; - debugText->color = color; - debugText->viewAxis = viewAxis; - debugText->align = align; - debugText->lifeTime = rb_debugTextTime + lifetime; - debugText->depthTest = depthTest; - } -} - -/* -================ -RB_DrawTextLength - - returns the length of the given text -================ -*/ -float RB_DrawTextLength( const char* text, float scale, int len ) -{ - int i, num, index, charIndex; - float spacing, textLen = 0.0f; - - if( text && *text ) - { - if( !len ) - { - len = strlen( text ); - } - for( i = 0; i < len; i++ ) - { - charIndex = text[i] - 32; - if( charIndex < 0 || charIndex > NUM_SIMPLEX_CHARS ) - { - continue; - } - num = simplex[charIndex][0] * 2; - spacing = simplex[charIndex][1]; - index = 2; - - while( index - 2 < num ) - { - if( simplex[charIndex][index] < 0 ) - { - index++; - continue; - } - index += 2; - if( simplex[charIndex][index] < 0 ) - { - index++; - continue; - } - } - textLen += spacing * scale; - } - } - return textLen; -} - -/* -================ -RB_DrawText - - oriented on the viewaxis - align can be 0-left, 1-center (default), 2-right -================ -*/ -static void RB_DrawText( const char* text, const idVec3& origin, float scale, const idVec4& color, const idMat3& viewAxis, const int align ) -{ - renderProgManager.BindShader_Color(); - - // RB begin - //GL_Color( color[0], color[1], color[2], 1 /*color[3]*/ ); - renderProgManager.CommitUniforms(); - // RB end - - int i, j, len, num, index, charIndex, line; - float textLen = 1.0f, spacing = 1.0f; - idVec3 org, p1, p2; - - if( text && *text ) - { - glBegin( GL_LINES ); - - if( text[0] == '\n' ) - { - line = 1; - } - else - { - line = 0; - } - - len = strlen( text ); - for( i = 0; i < len; i++ ) - { - - if( i == 0 || text[i] == '\n' ) - { - org = origin - viewAxis[2] * ( line * 36.0f * scale ); - if( align != 0 ) - { - for( j = 1; i + j <= len; j++ ) - { - if( i + j == len || text[i + j] == '\n' ) - { - textLen = RB_DrawTextLength( text + i, scale, j ); - break; - } - } - if( align == 2 ) - { - // right - org += viewAxis[1] * textLen; - } - else - { - // center - org += viewAxis[1] * ( textLen * 0.5f ); - } - } - line++; - } - - charIndex = text[i] - 32; - if( charIndex < 0 || charIndex > NUM_SIMPLEX_CHARS ) - { - continue; - } - num = simplex[charIndex][0] * 2; - spacing = simplex[charIndex][1]; - index = 2; - - while( index - 2 < num ) - { - if( simplex[charIndex][index] < 0 ) - { - index++; - continue; - } - p1 = org + scale * simplex[charIndex][index] * -viewAxis[1] + scale * simplex[charIndex][index + 1] * viewAxis[2]; - index += 2; - if( simplex[charIndex][index] < 0 ) - { - index++; - continue; - } - p2 = org + scale * simplex[charIndex][index] * -viewAxis[1] + scale * simplex[charIndex][index + 1] * viewAxis[2]; - - glVertex3fv( p1.ToFloatPtr() ); - glVertex3fv( p2.ToFloatPtr() ); - } - org -= viewAxis[1] * ( spacing * scale ); - } - - glEnd(); - } -} - -/* -================ -idRenderBackend::DBG_ShowDebugText -================ -*/ -void idRenderBackend::DBG_ShowDebugText() -{ - int i; - int width; - debugText_t* text; - - if( !rb_numDebugText ) - { - return; - } - - // all lines are expressed in world coordinates - DBG_SimpleWorldSetup(); - - globalImages->BindNull(); - - width = r_debugLineWidth.GetInteger(); - if( width < 1 ) - { - width = 1; - } - else if( width > 10 ) - { - width = 10; - } - - // draw lines - glLineWidth( width ); - - - if( !r_debugLineDepthTest.GetBool() ) - { - GL_State( GLS_POLYMODE_LINE | GLS_DEPTHFUNC_ALWAYS ); - } - else - { - GL_State( GLS_POLYMODE_LINE ); - } - - text = rb_debugText; - for( i = 0; i < rb_numDebugText; i++, text++ ) - { - if( !text->depthTest ) - { - GL_Color( text->color.ToVec3() ); - RB_DrawText( text->text, text->origin, text->scale, text->color, text->viewAxis, text->align ); - } - } - - if( !r_debugLineDepthTest.GetBool() ) - { - GL_State( GLS_POLYMODE_LINE ); - } - - text = rb_debugText; - for( i = 0; i < rb_numDebugText; i++, text++ ) - { - if( text->depthTest ) - { - GL_Color( text->color.ToVec3() ); - RB_DrawText( text->text, text->origin, text->scale, text->color, text->viewAxis, text->align ); - } - } - - glLineWidth( 1 ); -} - -/* -================ -RB_ClearDebugLines -================ -*/ -void RB_ClearDebugLines( int time ) -{ - int i; - int num; - debugLine_t* line; - - rb_debugLineTime = time; - - if( !time ) - { - rb_numDebugLines = 0; - return; - } - - // copy any lines that still need to be drawn - num = 0; - line = rb_debugLines; - for( i = 0; i < rb_numDebugLines; i++, line++ ) - { - if( line->lifeTime > time ) - { - if( num != i ) - { - rb_debugLines[ num ] = *line; - } - num++; - } - } - rb_numDebugLines = num; -} - -/* -================ -RB_AddDebugLine -================ -*/ -void RB_AddDebugLine( const idVec4& color, const idVec3& start, const idVec3& end, const int lifeTime, const bool depthTest ) -{ - debugLine_t* line; - - if( rb_numDebugLines < MAX_DEBUG_LINES ) - { - line = &rb_debugLines[ rb_numDebugLines++ ]; - line->rgb = color; - line->start = start; - line->end = end; - line->depthTest = depthTest; - line->lifeTime = rb_debugLineTime + lifeTime; - } -} - -/* -================ -idRenderBackend::DBG_ShowDebugLines -================ -*/ -void idRenderBackend::DBG_ShowDebugLines() -{ - int i; - int width; - debugLine_t* line; - - if( !rb_numDebugLines ) - { - return; - } - - // all lines are expressed in world coordinates - DBG_SimpleWorldSetup(); - - // RB begin - renderProgManager.BindShader_VertexColor(); - renderProgManager.CommitUniforms(); - // RB end - - globalImages->BindNull(); - - width = r_debugLineWidth.GetInteger(); - if( width < 1 ) - { - width = 1; - } - else if( width > 10 ) - { - width = 10; - } - - // draw lines - glLineWidth( width ); - - if( !r_debugLineDepthTest.GetBool() ) - { - GL_State( GLS_POLYMODE_LINE | GLS_DEPTHFUNC_ALWAYS ); - } - else - { - GL_State( GLS_POLYMODE_LINE ); - } - - glBegin( GL_LINES ); - - line = rb_debugLines; - for( i = 0; i < rb_numDebugLines; i++, line++ ) - { - if( !line->depthTest ) - { - glColor3fv( line->rgb.ToFloatPtr() ); - glVertex3fv( line->start.ToFloatPtr() ); - glVertex3fv( line->end.ToFloatPtr() ); - } - } - glEnd(); - - if( !r_debugLineDepthTest.GetBool() ) - { - GL_State( GLS_POLYMODE_LINE ); - } - - glBegin( GL_LINES ); - - line = rb_debugLines; - for( i = 0; i < rb_numDebugLines; i++, line++ ) - { - if( line->depthTest ) - { - glColor4fv( line->rgb.ToFloatPtr() ); - glVertex3fv( line->start.ToFloatPtr() ); - glVertex3fv( line->end.ToFloatPtr() ); - } - } - - glEnd(); - - glLineWidth( 1 ); - GL_State( GLS_DEFAULT ); -} - -/* -================ -RB_ClearDebugPolygons -================ -*/ -void RB_ClearDebugPolygons( int time ) -{ - int i; - int num; - debugPolygon_t* poly; - - rb_debugPolygonTime = time; - - if( !time ) - { - rb_numDebugPolygons = 0; - return; - } - - // copy any polygons that still need to be drawn - num = 0; - - poly = rb_debugPolygons; - for( i = 0; i < rb_numDebugPolygons; i++, poly++ ) - { - if( poly->lifeTime > time ) - { - if( num != i ) - { - rb_debugPolygons[ num ] = *poly; - } - num++; - } - } - rb_numDebugPolygons = num; -} - -/* -================ -RB_AddDebugPolygon -================ -*/ -void RB_AddDebugPolygon( const idVec4& color, const idWinding& winding, const int lifeTime, const bool depthTest ) -{ - debugPolygon_t* poly; - - if( rb_numDebugPolygons < MAX_DEBUG_POLYGONS ) - { - poly = &rb_debugPolygons[ rb_numDebugPolygons++ ]; - poly->rgb = color; - poly->winding = winding; - poly->depthTest = depthTest; - poly->lifeTime = rb_debugPolygonTime + lifeTime; - } -} - -/* -================ -idRenderBackend::DBG_ShowDebugPolygons -================ -*/ -void idRenderBackend::DBG_ShowDebugPolygons() -{ - int i, j; - debugPolygon_t* poly; - - if( !rb_numDebugPolygons ) - { - return; - } - - // all lines are expressed in world coordinates - DBG_SimpleWorldSetup(); - - // RB begin - renderProgManager.BindShader_VertexColor(); - renderProgManager.CommitUniforms(); - // RB end - - globalImages->BindNull(); - - if( r_debugPolygonFilled.GetBool() ) - { - GL_State( GLS_POLYGON_OFFSET | GLS_SRCBLEND_SRC_ALPHA | GLS_DSTBLEND_ONE_MINUS_SRC_ALPHA | GLS_DEPTHMASK ); - GL_PolygonOffset( -1, -2 ); - } - else - { - GL_State( GLS_POLYGON_OFFSET | GLS_POLYMODE_LINE ); - GL_PolygonOffset( -1, -2 ); - } - - poly = rb_debugPolygons; - for( i = 0; i < rb_numDebugPolygons; i++, poly++ ) - { -// if ( !poly->depthTest ) { - - glColor4fv( poly->rgb.ToFloatPtr() ); - - glBegin( GL_POLYGON ); - - for( j = 0; j < poly->winding.GetNumPoints(); j++ ) - { - glVertex3fv( poly->winding[j].ToFloatPtr() ); - } - - glEnd(); -// } - } - - GL_State( GLS_DEFAULT ); - - if( r_debugPolygonFilled.GetBool() ) - { - glDisable( GL_POLYGON_OFFSET_FILL ); - } - else - { - glDisable( GL_POLYGON_OFFSET_LINE ); - } - - GL_State( GLS_DEFAULT ); -} - -/* -================ -idRenderBackend::DBG_ShowCenterOfProjection -================ -*/ -void idRenderBackend::DBG_ShowCenterOfProjection() -{ - if( !r_showCenterOfProjection.GetBool() ) - { - return; - } - - const int w = viewDef->scissor.GetWidth(); - const int h = viewDef->scissor.GetHeight(); - glClearColor( 1, 0, 0, 1 ); - for( float f = 0.0f ; f <= 1.0f ; f += 0.125f ) - { - glScissor( w * f - 1 , 0, 3, h ); - glClear( GL_COLOR_BUFFER_BIT ); - glScissor( 0, h * f - 1 , w, 3 ); - glClear( GL_COLOR_BUFFER_BIT ); - } - glClearColor( 0, 1, 0, 1 ); - float f = 0.5f; - glScissor( w * f - 1 , 0, 3, h ); - glClear( GL_COLOR_BUFFER_BIT ); - glScissor( 0, h * f - 1 , w, 3 ); - glClear( GL_COLOR_BUFFER_BIT ); - - glScissor( 0, 0, w, h ); -} - -/* -================ -idRenderBackend::DBG_ShowLines - -Draw exact pixel lines to check pixel center sampling -================ -*/ -void idRenderBackend::DBG_ShowLines() -{ - if( !r_showLines.GetBool() ) - { - return; - } - - glEnable( GL_SCISSOR_TEST ); - if( viewDef->renderView.viewEyeBuffer == 0 ) - { - glClearColor( 1, 0, 0, 1 ); - } - else if( viewDef->renderView.viewEyeBuffer == 1 ) - { - glClearColor( 0, 1, 0, 1 ); - } - else - { - glClearColor( 0, 0, 1, 1 ); - } - - const int start = ( r_showLines.GetInteger() > 2 ); // 1,3 = horizontal, 2,4 = vertical - if( r_showLines.GetInteger() == 1 || r_showLines.GetInteger() == 3 ) - { - for( int i = start ; i < tr.GetHeight() ; i += 2 ) - { - glScissor( 0, i, tr.GetWidth(), 1 ); - glClear( GL_COLOR_BUFFER_BIT ); - } - } - else - { - for( int i = start ; i < tr.GetWidth() ; i += 2 ) - { - glScissor( i, 0, 1, tr.GetHeight() ); - glClear( GL_COLOR_BUFFER_BIT ); - } - } -} - - -/* -================ -idRenderBackend::DBG_TestGamma -================ -*/ -#define G_WIDTH 512 -#define G_HEIGHT 512 -#define BAR_HEIGHT 64 - -void idRenderBackend::DBG_TestGamma() -{ - byte image[G_HEIGHT][G_WIDTH][4]; - int i, j; - int c, comp; - int v, dither; - int mask, y; - - if( r_testGamma.GetInteger() <= 0 ) - { - return; - } - - v = r_testGamma.GetInteger(); - if( v <= 1 || v >= 196 ) - { - v = 128; - } - - memset( image, 0, sizeof( image ) ); - - for( mask = 0; mask < 8; mask++ ) - { - y = mask * BAR_HEIGHT; - for( c = 0; c < 4; c++ ) - { - v = c * 64 + 32; - // solid color - for( i = 0; i < BAR_HEIGHT / 2; i++ ) - { - for( j = 0; j < G_WIDTH / 4; j++ ) - { - for( comp = 0; comp < 3; comp++ ) - { - if( mask & ( 1 << comp ) ) - { - image[y + i][c * G_WIDTH / 4 + j][comp] = v; - } - } - } - // dithered color - for( j = 0; j < G_WIDTH / 4; j++ ) - { - if( ( i ^ j ) & 1 ) - { - dither = c * 64; - } - else - { - dither = c * 64 + 63; - } - for( comp = 0; comp < 3; comp++ ) - { - if( mask & ( 1 << comp ) ) - { - image[y + BAR_HEIGHT / 2 + i][c * G_WIDTH / 4 + j][comp] = dither; - } - } - } - } - } - } - - // draw geometrically increasing steps in the bottom row - y = 0 * BAR_HEIGHT; - float scale = 1; - for( c = 0; c < 4; c++ ) - { - v = ( int )( 64 * scale ); - if( v < 0 ) - { - v = 0; - } - else if( v > 255 ) - { - v = 255; - } - scale = scale * 1.5; - for( i = 0; i < BAR_HEIGHT; i++ ) - { - for( j = 0; j < G_WIDTH / 4; j++ ) - { - image[y + i][c * G_WIDTH / 4 + j][0] = v; - image[y + i][c * G_WIDTH / 4 + j][1] = v; - image[y + i][c * G_WIDTH / 4 + j][2] = v; - } - } - } - - glLoadIdentity(); - - glMatrixMode( GL_PROJECTION ); - GL_State( GLS_DEPTHFUNC_ALWAYS ); - GL_Color( 1, 1, 1 ); - glPushMatrix(); - glLoadIdentity(); - glDisable( GL_TEXTURE_2D ); - glOrtho( 0, 1, 0, 1, -1, 1 ); - glRasterPos2f( 0.01f, 0.01f ); - glDrawPixels( G_WIDTH, G_HEIGHT, GL_RGBA, GL_UNSIGNED_BYTE, image ); - glPopMatrix(); - glEnable( GL_TEXTURE_2D ); - glMatrixMode( GL_MODELVIEW ); -} - - -/* -================== -idRenderBackend::DBG_TestGammaBias -================== -*/ -void idRenderBackend::DBG_TestGammaBias() -{ - byte image[G_HEIGHT][G_WIDTH][4]; - - if( r_testGammaBias.GetInteger() <= 0 ) - { - return; - } - - int y = 0; - for( int bias = -40; bias < 40; bias += 10, y += BAR_HEIGHT ) - { - float scale = 1; - for( int c = 0; c < 4; c++ ) - { - int v = ( int )( 64 * scale + bias ); - scale = scale * 1.5; - if( v < 0 ) - { - v = 0; - } - else if( v > 255 ) - { - v = 255; - } - for( int i = 0; i < BAR_HEIGHT; i++ ) - { - for( int j = 0; j < G_WIDTH / 4; j++ ) - { - image[y + i][c * G_WIDTH / 4 + j][0] = v; - image[y + i][c * G_WIDTH / 4 + j][1] = v; - image[y + i][c * G_WIDTH / 4 + j][2] = v; - } - } - } - } - - glLoadIdentity(); - glMatrixMode( GL_PROJECTION ); - GL_State( GLS_DEPTHFUNC_ALWAYS ); - GL_Color( 1, 1, 1 ); - glPushMatrix(); - glLoadIdentity(); - glDisable( GL_TEXTURE_2D ); - glOrtho( 0, 1, 0, 1, -1, 1 ); - glRasterPos2f( 0.01f, 0.01f ); - glDrawPixels( G_WIDTH, G_HEIGHT, GL_RGBA, GL_UNSIGNED_BYTE, image ); - glPopMatrix(); - glEnable( GL_TEXTURE_2D ); - glMatrixMode( GL_MODELVIEW ); -} - -/* -================ -idRenderBackend::DBG_TestImage - -Display a single image over most of the screen -================ -*/ -void idRenderBackend::DBG_TestImage() -{ - idImage* image = NULL; - idImage* imageCr = NULL; - idImage* imageCb = NULL; - int max; - float w, h; - - image = tr.testImage; - if( !image ) - { - return; - } - - if( tr.testVideo ) - { - cinData_t cin; - - cin = tr.testVideo->ImageForTime( viewDef->renderView.time[1] - tr.testVideoStartTime ); - if( cin.imageY != NULL ) - { - image = cin.imageY; - imageCr = cin.imageCr; - imageCb = cin.imageCb; - } - else - { - tr.testImage = NULL; - return; - } - w = 0.25; - h = 0.25; - } - else - { - max = image->GetUploadWidth() > image->GetUploadHeight() ? image->GetUploadWidth() : image->GetUploadHeight(); - - w = 0.25 * image->GetUploadWidth() / max; - h = 0.25 * image->GetUploadHeight() / max; - - w *= ( float )renderSystem->GetHeight() / renderSystem->GetWidth(); - } - - // Set State - GL_State( GLS_DEPTHFUNC_ALWAYS | GLS_SRCBLEND_ONE | GLS_DSTBLEND_ZERO ); - - // Set Parms - float texS[4] = { 1.0f, 0.0f, 0.0f, 0.0f }; - float texT[4] = { 0.0f, 1.0f, 0.0f, 0.0f }; - renderProgManager.SetRenderParm( RENDERPARM_TEXTUREMATRIX_S, texS ); - renderProgManager.SetRenderParm( RENDERPARM_TEXTUREMATRIX_T, texT ); - - float texGenEnabled[4] = { 0, 0, 0, 0 }; - renderProgManager.SetRenderParm( RENDERPARM_TEXGEN_0_ENABLED, texGenEnabled ); - - // not really necessary but just for clarity - const float screenWidth = 1.0f; - const float screenHeight = 1.0f; - const float halfScreenWidth = screenWidth * 0.5f; - const float halfScreenHeight = screenHeight * 0.5f; - - float scale[16] = { 0 }; - scale[0] = w; // scale - scale[5] = h; // scale - scale[12] = halfScreenWidth - ( halfScreenWidth * w ); // translate - scale[13] = halfScreenHeight - ( halfScreenHeight * h ); // translate - scale[10] = 1.0f; - scale[15] = 1.0f; - - float ortho[16] = { 0 }; - ortho[0] = 2.0f / screenWidth; - ortho[5] = -2.0f / screenHeight; - ortho[10] = -2.0f; - ortho[12] = -1.0f; - ortho[13] = 1.0f; - ortho[14] = -1.0f; - ortho[15] = 1.0f; - - float finalOrtho[16]; - R_MatrixMultiply( scale, ortho, finalOrtho ); - - float projMatrixTranspose[16]; - R_MatrixTranspose( finalOrtho, projMatrixTranspose ); - renderProgManager.SetRenderParms( RENDERPARM_MVPMATRIX_X, projMatrixTranspose, 4 ); - -// glMatrixMode( GL_PROJECTION ); -// glLoadMatrixf( finalOrtho ); -// glMatrixMode( GL_MODELVIEW ); -// glLoadIdentity(); - - // Set Color - GL_Color( 1, 1, 1, 1 ); - - // Bind the Texture - if( ( imageCr != NULL ) && ( imageCb != NULL ) ) - { - GL_SelectTexture( 0 ); - image->Bind(); - GL_SelectTexture( 1 ); - imageCr->Bind(); - GL_SelectTexture( 2 ); - imageCb->Bind(); - renderProgManager.BindShader_Bink(); - } - else - { - GL_SelectTexture( 0 ); - image->Bind(); - // Set Shader - renderProgManager.BindShader_Texture(); - } - - // Draw! - DrawElementsWithCounters( &testImageSurface ); -} - -// RB begin -void idRenderBackend::DBG_ShowShadowMaps() -{ - idImage* image = NULL; - int max; - float w, h; - - if( !r_showShadowMaps.GetBool() ) - return; - - image = globalImages->shadowImage[0]; - if( !image ) - { - return; - } - - // Set State - GL_State( GLS_DEPTHFUNC_ALWAYS | GLS_SRCBLEND_ONE | GLS_DSTBLEND_ZERO ); - - // Set Parms - float texS[4] = { 1.0f, 0.0f, 0.0f, 0.0f }; - float texT[4] = { 0.0f, 1.0f, 0.0f, 0.0f }; - renderProgManager.SetRenderParm( RENDERPARM_TEXTUREMATRIX_S, texS ); - renderProgManager.SetRenderParm( RENDERPARM_TEXTUREMATRIX_T, texT ); - - float texGenEnabled[4] = { 0, 0, 0, 0 }; - renderProgManager.SetRenderParm( RENDERPARM_TEXGEN_0_ENABLED, texGenEnabled ); - - for( int i = 0; i < ( r_shadowMapSplits.GetInteger() + 1 ); i++ ) - { - max = image->GetUploadWidth() > image->GetUploadHeight() ? image->GetUploadWidth() : image->GetUploadHeight(); - - w = 0.25 * image->GetUploadWidth() / max; - h = 0.25 * image->GetUploadHeight() / max; - - w *= ( float )renderSystem->GetHeight() / renderSystem->GetWidth(); - - // not really necessary but just for clarity - const float screenWidth = 1.0f; - const float screenHeight = 1.0f; - const float halfScreenWidth = screenWidth * 0.5f; - const float halfScreenHeight = screenHeight * 0.5f; - - float scale[16] = { 0 }; - scale[0] = w; // scale - scale[5] = h; // scale - scale[12] = ( halfScreenWidth * w * 2.1f * i ); // translate - scale[13] = halfScreenHeight + ( halfScreenHeight * h ); // translate - scale[10] = 1.0f; - scale[15] = 1.0f; - - float ortho[16] = { 0 }; - ortho[0] = 2.0f / screenWidth; - ortho[5] = -2.0f / screenHeight; - ortho[10] = -2.0f; - ortho[12] = -1.0f; - ortho[13] = 1.0f; - ortho[14] = -1.0f; - ortho[15] = 1.0f; - - float finalOrtho[16]; - R_MatrixMultiply( scale, ortho, finalOrtho ); - - float projMatrixTranspose[16]; - R_MatrixTranspose( finalOrtho, projMatrixTranspose ); - renderProgManager.SetRenderParms( RENDERPARM_MVPMATRIX_X, projMatrixTranspose, 4 ); - - float screenCorrectionParm[4]; - screenCorrectionParm[0] = i; - screenCorrectionParm[1] = 0.0f; - screenCorrectionParm[2] = 0.0f; - screenCorrectionParm[3] = 1.0f; - renderProgManager.SetRenderParm( RENDERPARM_SCREENCORRECTIONFACTOR, screenCorrectionParm ); // rpScreenCorrectionFactor - - // glMatrixMode( GL_PROJECTION ); - // glLoadMatrixf( finalOrtho ); - // glMatrixMode( GL_MODELVIEW ); - // glLoadIdentity(); - - // Set Color - GL_Color( 1, 1, 1, 1 ); - - GL_SelectTexture( 0 ); - image->Bind(); - glTexParameteri( GL_TEXTURE_2D_ARRAY, GL_TEXTURE_COMPARE_MODE, GL_NONE ); - - - renderProgManager.BindShader_DebugShadowMap(); - - DrawElementsWithCounters( &testImageSurface ); - } - - glTexParameteri( GL_TEXTURE_2D_ARRAY, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_R_TO_TEXTURE ); -} -// RB end - -/* -================= -RB_DrawExpandedTriangles -================= -*/ -static void RB_DrawExpandedTriangles( const srfTriangles_t* tri, const float radius, const idVec3& vieworg ) -{ - int i, j, k; - idVec3 dir[6], normal, point; - - for( i = 0; i < tri->numIndexes; i += 3 ) - { - - idVec3 p[3] = { tri->verts[ tri->indexes[ i + 0 ] ].xyz, tri->verts[ tri->indexes[ i + 1 ] ].xyz, tri->verts[ tri->indexes[ i + 2 ] ].xyz }; - - dir[0] = p[0] - p[1]; - dir[1] = p[1] - p[2]; - dir[2] = p[2] - p[0]; - - normal = dir[0].Cross( dir[1] ); - - if( normal * p[0] < normal * vieworg ) - { - continue; - } - - dir[0] = normal.Cross( dir[0] ); - dir[1] = normal.Cross( dir[1] ); - dir[2] = normal.Cross( dir[2] ); - - dir[0].Normalize(); - dir[1].Normalize(); - dir[2].Normalize(); - - glBegin( GL_LINE_LOOP ); - - for( j = 0; j < 3; j++ ) - { - k = ( j + 1 ) % 3; - - dir[4] = ( dir[j] + dir[k] ) * 0.5f; - dir[4].Normalize(); - - dir[3] = ( dir[j] + dir[4] ) * 0.5f; - dir[3].Normalize(); - - dir[5] = ( dir[4] + dir[k] ) * 0.5f; - dir[5].Normalize(); - - point = p[k] + dir[j] * radius; - glVertex3f( point[0], point[1], point[2] ); - - point = p[k] + dir[3] * radius; - glVertex3f( point[0], point[1], point[2] ); - - point = p[k] + dir[4] * radius; - glVertex3f( point[0], point[1], point[2] ); - - point = p[k] + dir[5] * radius; - glVertex3f( point[0], point[1], point[2] ); - - point = p[k] + dir[k] * radius; - glVertex3f( point[0], point[1], point[2] ); - } - - glEnd(); - } -} - -/* -================ -idRenderBackend::DBG_ShowTrace - -Debug visualization - -FIXME: not thread safe! -================ -*/ -void idRenderBackend::DBG_ShowTrace( drawSurf_t** drawSurfs, int numDrawSurfs ) -{ - int i; - const srfTriangles_t* tri; - const drawSurf_t* surf; - idVec3 start, end; - idVec3 localStart, localEnd; - localTrace_t hit; - float radius; - - if( r_showTrace.GetInteger() == 0 ) - { - return; - } - - if( r_showTrace.GetInteger() == 2 ) - { - radius = 5.0f; - } - else - { - radius = 0.0f; - } - - // determine the points of the trace - start = viewDef->renderView.vieworg; - end = start + 4000 * viewDef->renderView.viewaxis[0]; - - // check and draw the surfaces - globalImages->whiteImage->Bind(); - - // find how many are ambient - for( i = 0; i < numDrawSurfs; i++ ) - { - surf = drawSurfs[i]; - tri = surf->frontEndGeo; - - if( tri == NULL || tri->verts == NULL ) - { - continue; - } - - // transform the points into local space - R_GlobalPointToLocal( surf->space->modelMatrix, start, localStart ); - R_GlobalPointToLocal( surf->space->modelMatrix, end, localEnd ); - - // check the bounding box - if( !tri->bounds.Expand( radius ).LineIntersection( localStart, localEnd ) ) - { - continue; - } - - glLoadMatrixf( surf->space->modelViewMatrix ); - - // highlight the surface - GL_State( GLS_SRCBLEND_SRC_ALPHA | GLS_DSTBLEND_ONE_MINUS_SRC_ALPHA ); - - GL_Color( 1, 0, 0, 0.25 ); - DrawElementsWithCounters( surf ); - - // draw the bounding box - GL_State( GLS_DEPTHFUNC_ALWAYS ); - - GL_Color( 1, 1, 1, 1 ); - RB_DrawBounds( tri->bounds ); - - if( radius != 0.0f ) - { - // draw the expanded triangles - GL_Color( 0.5f, 0.5f, 1.0f, 1.0f ); - RB_DrawExpandedTriangles( tri, radius, localStart ); - } - - // check the exact surfaces - hit = R_LocalTrace( localStart, localEnd, radius, tri ); - if( hit.fraction < 1.0 ) - { - GL_Color( 1, 1, 1, 1 ); - RB_DrawBounds( idBounds( hit.point ).Expand( 1 ) ); - } - } -} - -/* -================= -idRenderBackend::DBG_RenderDebugTools -================= -*/ -void idRenderBackend::DBG_RenderDebugTools( drawSurf_t** drawSurfs, int numDrawSurfs ) -{ - // don't do much if this was a 2D rendering - if( !viewDef->viewEntitys ) - { - DBG_TestImage(); - DBG_ShowLines(); - return; - } - - renderLog.OpenMainBlock( MRB_DRAW_DEBUG_TOOLS ); - RENDERLOG_PRINTF( "---------- RB_RenderDebugTools ----------\n" ); - - GL_State( GLS_DEFAULT ); - - GL_Scissor( viewDef->viewport.x1 + viewDef->scissor.x1, - viewDef->viewport.y1 + viewDef->scissor.y1, - viewDef->scissor.x2 + 1 - viewDef->scissor.x1, - viewDef->scissor.y2 + 1 - viewDef->scissor.y1 ); - - currentScissor = viewDef->scissor; - - DBG_ShowLightCount(); - DBG_ShowTexturePolarity( drawSurfs, numDrawSurfs ); - DBG_ShowTangentSpace( drawSurfs, numDrawSurfs ); - DBG_ShowVertexColor( drawSurfs, numDrawSurfs ); - DBG_ShowTris( drawSurfs, numDrawSurfs ); - DBG_ShowUnsmoothedTangents( drawSurfs, numDrawSurfs ); - DBG_ShowSurfaceInfo( drawSurfs, numDrawSurfs ); - DBG_ShowEdges( drawSurfs, numDrawSurfs ); - DBG_ShowNormals( drawSurfs, numDrawSurfs ); - DBG_ShowViewEntitys( viewDef->viewEntitys ); - DBG_ShowLights(); - // RB begin - DBG_ShowShadowMapLODs(); - DBG_ShowShadowMaps(); - // RB end - - DBG_ShowTextureVectors( drawSurfs, numDrawSurfs ); - DBG_ShowDominantTris( drawSurfs, numDrawSurfs ); - if( r_testGamma.GetInteger() > 0 ) // test here so stack check isn't so damn slow on debug builds - { - DBG_TestGamma(); - } - if( r_testGammaBias.GetInteger() > 0 ) - { - DBG_TestGammaBias(); - } - DBG_TestImage(); - DBG_ShowPortals(); - DBG_ShowSilhouette(); - DBG_ShowDepthBuffer(); - DBG_ShowIntensity(); - DBG_ShowCenterOfProjection(); - DBG_ShowLines(); - DBG_ShowDebugLines(); - DBG_ShowDebugText(); - DBG_ShowDebugPolygons(); - DBG_ShowTrace( drawSurfs, numDrawSurfs ); - - renderLog.CloseMainBlock(); -} - -/* -================= -RB_ShutdownDebugTools -================= -*/ -void RB_ShutdownDebugTools() -{ - for( int i = 0; i < MAX_DEBUG_POLYGONS; i++ ) - { - rb_debugPolygons[i].winding.Clear(); - } -} From f4dd96e404fe93cabbcaa2c6547ffee150bae8d7 Mon Sep 17 00:00:00 2001 From: Robert Beckebans Date: Sun, 10 Sep 2017 14:16:15 +0200 Subject: [PATCH 10/12] Moved tr_backend_rendertools.cpp --- neo/renderer/OpenGL/RenderDebug_GL.cpp | 3146 ++++++++++++++++++++++++ 1 file changed, 3146 insertions(+) create mode 100644 neo/renderer/OpenGL/RenderDebug_GL.cpp diff --git a/neo/renderer/OpenGL/RenderDebug_GL.cpp b/neo/renderer/OpenGL/RenderDebug_GL.cpp new file mode 100644 index 00000000..4f18a889 --- /dev/null +++ b/neo/renderer/OpenGL/RenderDebug_GL.cpp @@ -0,0 +1,3146 @@ +/* +=========================================================================== + +Doom 3 BFG Edition GPL Source Code +Copyright (C) 1993-2012 id Software LLC, a ZeniMax Media company. +Copyright (C) 2014-2016 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"). + +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 . + +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 "../RenderCommon.h" +#include "../simplex.h" // line font definition + +idCVar r_showCenterOfProjection( "r_showCenterOfProjection", "0", CVAR_RENDERER | CVAR_BOOL, "Draw a cross to show the center of projection" ); +idCVar r_showLines( "r_showLines", "0", CVAR_RENDERER | CVAR_INTEGER, "1 = draw alternate horizontal lines, 2 = draw alternate vertical lines" ); + + + +debugLine_t rb_debugLines[ MAX_DEBUG_LINES ]; +int rb_numDebugLines = 0; +int rb_debugLineTime = 0; + +debugText_t rb_debugText[ MAX_DEBUG_TEXT ]; +int rb_numDebugText = 0; +int rb_debugTextTime = 0; + +debugPolygon_t rb_debugPolygons[ MAX_DEBUG_POLYGONS ]; +int rb_numDebugPolygons = 0; +int rb_debugPolygonTime = 0; + +static void RB_DrawText( const char* text, const idVec3& origin, float scale, const idVec4& color, const idMat3& viewAxis, const int align ); + +void RB_SetMVP( const idRenderMatrix& mvp ); + +/* +================ +RB_DrawBounds +================ +*/ +void RB_DrawBounds( const idBounds& bounds ) +{ + if( bounds.IsCleared() ) + { + return; + } + glBegin( GL_LINE_LOOP ); + glVertex3f( bounds[0][0], bounds[0][1], bounds[0][2] ); + glVertex3f( bounds[0][0], bounds[1][1], bounds[0][2] ); + glVertex3f( bounds[1][0], bounds[1][1], bounds[0][2] ); + glVertex3f( bounds[1][0], bounds[0][1], bounds[0][2] ); + glEnd(); + glBegin( GL_LINE_LOOP ); + glVertex3f( bounds[0][0], bounds[0][1], bounds[1][2] ); + glVertex3f( bounds[0][0], bounds[1][1], bounds[1][2] ); + glVertex3f( bounds[1][0], bounds[1][1], bounds[1][2] ); + glVertex3f( bounds[1][0], bounds[0][1], bounds[1][2] ); + glEnd(); + + glBegin( GL_LINES ); + glVertex3f( bounds[0][0], bounds[0][1], bounds[0][2] ); + glVertex3f( bounds[0][0], bounds[0][1], bounds[1][2] ); + + glVertex3f( bounds[0][0], bounds[1][1], bounds[0][2] ); + glVertex3f( bounds[0][0], bounds[1][1], bounds[1][2] ); + + glVertex3f( bounds[1][0], bounds[0][1], bounds[0][2] ); + glVertex3f( bounds[1][0], bounds[0][1], bounds[1][2] ); + + glVertex3f( bounds[1][0], bounds[1][1], bounds[0][2] ); + glVertex3f( bounds[1][0], bounds[1][1], bounds[1][2] ); + glEnd(); +} + + +/* +================ +idRenderBackend::DBG_SimpleSurfaceSetup +================ +*/ +void idRenderBackend::DBG_SimpleSurfaceSetup( const drawSurf_t* drawSurf ) +{ + // change the matrix if needed + if( drawSurf->space != currentSpace ) + { + // RB begin + RB_SetMVP( drawSurf->space->mvp ); + //qglLoadMatrixf( drawSurf->space->modelViewMatrix ); + // RB end + currentSpace = drawSurf->space; + } + + // change the scissor if needed + if( !currentScissor.Equals( drawSurf->scissorRect ) && r_useScissor.GetBool() ) + { + GL_Scissor( viewDef->viewport.x1 + drawSurf->scissorRect.x1, + viewDef->viewport.y1 + drawSurf->scissorRect.y1, + drawSurf->scissorRect.x2 + 1 - drawSurf->scissorRect.x1, + drawSurf->scissorRect.y2 + 1 - drawSurf->scissorRect.y1 ); + + currentScissor = drawSurf->scissorRect; + } +} + +/* +================ +idRenderBackend::DBG_SimpleWorldSetup +================ +*/ +void idRenderBackend::DBG_SimpleWorldSetup() +{ + currentSpace = &viewDef->worldSpace; + + // RB begin + RB_SetMVP( viewDef->worldSpace.mvp ); + // RB end + + GL_Scissor( viewDef->viewport.x1 + viewDef->scissor.x1, + viewDef->viewport.y1 + viewDef->scissor.y1, + viewDef->scissor.x2 + 1 - viewDef->scissor.x1, + viewDef->scissor.y2 + 1 - viewDef->scissor.y1 ); + + currentScissor = viewDef->scissor; +} + +/* +================= +idRenderBackend::DBG_PolygonClear + +This will cover the entire screen with normal rasterization. +Texturing is disabled, but the existing glColor, glDepthMask, +glColorMask, and the enabled state of depth buffering and +stenciling will matter. +================= +*/ +void idRenderBackend::DBG_PolygonClear() +{ + glPushMatrix(); + glPushAttrib( GL_ALL_ATTRIB_BITS ); + glLoadIdentity(); + glDisable( GL_TEXTURE_2D ); + glDisable( GL_DEPTH_TEST ); + glDisable( GL_CULL_FACE ); + glDisable( GL_SCISSOR_TEST ); + glBegin( GL_POLYGON ); + glVertex3f( -20, -20, -10 ); + glVertex3f( 20, -20, -10 ); + glVertex3f( 20, 20, -10 ); + glVertex3f( -20, 20, -10 ); + glEnd(); + glPopAttrib(); + glPopMatrix(); +} + +/* +==================== +idRenderBackend::DBG_ShowDestinationAlpha +==================== +*/ +void idRenderBackend::DBG_ShowDestinationAlpha() +{ + GL_State( GLS_SRCBLEND_DST_ALPHA | GLS_DSTBLEND_ZERO | GLS_DEPTHMASK | GLS_DEPTHFUNC_ALWAYS ); + GL_Color( 1, 1, 1 ); + + DBG_PolygonClear(); +} + +/* +=================== +idRenderBackend::DBG_ScanStencilBuffer + +Debugging tool to see what values are in the stencil buffer +=================== +*/ +void idRenderBackend::DBG_ScanStencilBuffer() +{ + int counts[256]; + int i; + byte* stencilReadback; + + memset( counts, 0, sizeof( counts ) ); + + stencilReadback = ( byte* )R_StaticAlloc( renderSystem->GetWidth() * renderSystem->GetHeight(), TAG_RENDER_TOOLS ); + glReadPixels( 0, 0, renderSystem->GetWidth(), renderSystem->GetHeight(), GL_STENCIL_INDEX, GL_UNSIGNED_BYTE, stencilReadback ); + + for( i = 0; i < renderSystem->GetWidth() * renderSystem->GetHeight(); i++ ) + { + counts[ stencilReadback[i] ]++; + } + + R_StaticFree( stencilReadback ); + + // print some stats (not supposed to do from back end in SMP...) + common->Printf( "stencil values:\n" ); + for( i = 0; i < 255; i++ ) + { + if( counts[i] ) + { + common->Printf( "%i: %i\n", i, counts[i] ); + } + } +} + + +/* +=================== +idRenderBackend::DBG_CountStencilBuffer + +Print an overdraw count based on stencil index values +=================== +*/ +void idRenderBackend::DBG_CountStencilBuffer() +{ + int count; + int i; + byte* stencilReadback; + + + stencilReadback = ( byte* )R_StaticAlloc( renderSystem->GetWidth() * renderSystem->GetHeight(), TAG_RENDER_TOOLS ); + glReadPixels( 0, 0, renderSystem->GetWidth(), renderSystem->GetHeight(), GL_STENCIL_INDEX, GL_UNSIGNED_BYTE, stencilReadback ); + + count = 0; + for( i = 0; i < renderSystem->GetWidth() * renderSystem->GetHeight(); i++ ) + { + count += stencilReadback[i]; + } + + R_StaticFree( stencilReadback ); + + // print some stats (not supposed to do from back end in SMP...) + common->Printf( "overdraw: %5.1f\n", ( float )count / ( renderSystem->GetWidth() * renderSystem->GetHeight() ) ); +} + +/* +=================== +idRenderBackend::DBG_ColorByStencilBuffer + +Sets the screen colors based on the contents of the +stencil buffer. Stencil of 0 = black, 1 = red, 2 = green, +3 = blue, ..., 7+ = white +=================== +*/ +void idRenderBackend::DBG_ColorByStencilBuffer() +{ + int i; + static idVec3 colors[8] = + { + idVec3( 0, 0, 0 ), + idVec3( 1, 0, 0 ), + idVec3( 0, 1, 0 ), + idVec3( 0, 0, 1 ), + idVec3( 0, 1, 1 ), + idVec3( 1, 0, 1 ), + idVec3( 1, 1, 0 ), + idVec3( 1, 1, 1 ), + }; + + // clear color buffer to white (>6 passes) + GL_Clear( true, false, false, 0, 1.0f, 1.0f, 1.0f, 1.0f ); + + // now draw color for each stencil value + glStencilOp( GL_KEEP, GL_KEEP, GL_KEEP ); + for( i = 0; i < 6; i++ ) + { + GL_Color( colors[i] ); + renderProgManager.BindShader_Color(); + glStencilFunc( GL_EQUAL, i, 255 ); + + DBG_PolygonClear(); + } + + glStencilFunc( GL_ALWAYS, 0, 255 ); +} + +/* +================== +idRenderBackend::DBG_ShowOverdraw +================== +*/ +void idRenderBackend::DBG_ShowOverdraw() +{ + const idMaterial* material; + int i; + drawSurf_t** drawSurfs; + const drawSurf_t* surf; + int numDrawSurfs; + viewLight_t* vLight; + + if( r_showOverDraw.GetInteger() == 0 ) + { + return; + } + + material = declManager->FindMaterial( "textures/common/overdrawtest", false ); + if( material == NULL ) + { + return; + } + + drawSurfs = viewDef->drawSurfs; + numDrawSurfs = viewDef->numDrawSurfs; + + int interactions = 0; + for( vLight = viewDef->viewLights; vLight; vLight = vLight->next ) + { + for( surf = vLight->localInteractions; surf; surf = surf->nextOnLight ) + { + interactions++; + } + for( surf = vLight->globalInteractions; surf; surf = surf->nextOnLight ) + { + interactions++; + } + } + + // FIXME: can't frame alloc from the renderer back-end + drawSurf_t** newDrawSurfs = ( drawSurf_t** )R_FrameAlloc( numDrawSurfs + interactions * sizeof( newDrawSurfs[0] ), FRAME_ALLOC_DRAW_SURFACE_POINTER ); + + for( i = 0; i < numDrawSurfs; i++ ) + { + surf = drawSurfs[i]; + if( surf->material ) + { + const_cast( surf )->material = material; + } + newDrawSurfs[i] = const_cast( surf ); + } + + for( vLight = viewDef->viewLights; vLight; vLight = vLight->next ) + { + for( surf = vLight->localInteractions; surf; surf = surf->nextOnLight ) + { + const_cast( surf )->material = material; + newDrawSurfs[i++] = const_cast( surf ); + } + for( surf = vLight->globalInteractions; surf; surf = surf->nextOnLight ) + { + const_cast( surf )->material = material; + newDrawSurfs[i++] = const_cast( surf ); + } + vLight->localInteractions = NULL; + vLight->globalInteractions = NULL; + } + + switch( r_showOverDraw.GetInteger() ) + { + case 1: // geometry overdraw + const_cast( viewDef )->drawSurfs = newDrawSurfs; + const_cast( viewDef )->numDrawSurfs = numDrawSurfs; + break; + case 2: // light interaction overdraw + const_cast( viewDef )->drawSurfs = &newDrawSurfs[numDrawSurfs]; + const_cast( viewDef )->numDrawSurfs = interactions; + break; + case 3: // geometry + light interaction overdraw + const_cast( viewDef )->drawSurfs = newDrawSurfs; + const_cast( viewDef )->numDrawSurfs += interactions; + break; + } +} + +/* +=================== +idRenderBackend::DBG_ShowIntensity + +Debugging tool to see how much dynamic range a scene is using. +The greatest of the rgb values at each pixel will be used, with +the resulting color shading from red at 0 to green at 128 to blue at 255 +=================== +*/ +void idRenderBackend::DBG_ShowIntensity() +{ + byte* colorReadback; + int i, j, c; + + if( !r_showIntensity.GetBool() ) + { + return; + } + + colorReadback = ( byte* )R_StaticAlloc( renderSystem->GetWidth() * renderSystem->GetHeight() * 4, TAG_RENDER_TOOLS ); + glReadPixels( 0, 0, renderSystem->GetWidth(), renderSystem->GetHeight(), GL_RGBA, GL_UNSIGNED_BYTE, colorReadback ); + + c = renderSystem->GetWidth() * renderSystem->GetHeight() * 4; + for( i = 0; i < c; i += 4 ) + { + j = colorReadback[i]; + if( colorReadback[i + 1] > j ) + { + j = colorReadback[i + 1]; + } + if( colorReadback[i + 2] > j ) + { + j = colorReadback[i + 2]; + } + if( j < 128 ) + { + colorReadback[i + 0] = 2 * ( 128 - j ); + colorReadback[i + 1] = 2 * j; + colorReadback[i + 2] = 0; + } + else + { + colorReadback[i + 0] = 0; + colorReadback[i + 1] = 2 * ( 255 - j ); + colorReadback[i + 2] = 2 * ( j - 128 ); + } + } + + // draw it back to the screen + glLoadIdentity(); + glMatrixMode( GL_PROJECTION ); + GL_State( GLS_DEPTHFUNC_ALWAYS ); + glPushMatrix(); + glLoadIdentity(); + glOrtho( 0, 1, 0, 1, -1, 1 ); + glRasterPos2f( 0, 0 ); + glPopMatrix(); + GL_Color( 1, 1, 1 ); + globalImages->BindNull(); + glMatrixMode( GL_MODELVIEW ); + + glDrawPixels( renderSystem->GetWidth(), renderSystem->GetHeight(), GL_RGBA , GL_UNSIGNED_BYTE, colorReadback ); + + R_StaticFree( colorReadback ); +} + + +/* +=================== +idRenderBackend::DBG_ShowDepthBuffer + +Draw the depth buffer as colors +=================== +*/ +void idRenderBackend::DBG_ShowDepthBuffer() +{ + void* depthReadback; + + if( !r_showDepth.GetBool() ) + { + return; + } + + glPushMatrix(); + glLoadIdentity(); + glMatrixMode( GL_PROJECTION ); + glPushMatrix(); + glLoadIdentity(); + glOrtho( 0, 1, 0, 1, -1, 1 ); + glRasterPos2f( 0, 0 ); + glPopMatrix(); + glMatrixMode( GL_MODELVIEW ); + glPopMatrix(); + + GL_State( GLS_DEPTHFUNC_ALWAYS ); + GL_Color( 1, 1, 1 ); + globalImages->BindNull(); + + depthReadback = R_StaticAlloc( renderSystem->GetWidth() * renderSystem->GetHeight() * 4, TAG_RENDER_TOOLS ); + memset( depthReadback, 0, renderSystem->GetWidth() * renderSystem->GetHeight() * 4 ); + + glReadPixels( 0, 0, renderSystem->GetWidth(), renderSystem->GetHeight(), GL_DEPTH_COMPONENT , GL_FLOAT, depthReadback ); + +#if 0 + for( i = 0; i < renderSystem->GetWidth() * renderSystem->GetHeight(); i++ ) + { + ( ( byte* )depthReadback )[i * 4] = + ( ( byte* )depthReadback )[i * 4 + 1] = + ( ( byte* )depthReadback )[i * 4 + 2] = 255 * ( ( float* )depthReadback )[i]; + ( ( byte* )depthReadback )[i * 4 + 3] = 1; + } +#endif + + glDrawPixels( renderSystem->GetWidth(), renderSystem->GetHeight(), GL_RGBA , GL_UNSIGNED_BYTE, depthReadback ); + R_StaticFree( depthReadback ); +} + +/* +================= +idRenderBackend::DBG_ShowLightCount + +This is a debugging tool that will draw each surface with a color +based on how many lights are effecting it +================= +*/ +void idRenderBackend::DBG_ShowLightCount() +{ + int i; + const drawSurf_t* surf; + const viewLight_t* vLight; + + if( !r_showLightCount.GetBool() ) + { + return; + } + + DBG_SimpleWorldSetup(); + + GL_Clear( false, false, true, 0, 0.0f, 0.0f, 0.0f, 0.0f ); + + // optionally count everything through walls + if( r_showLightCount.GetInteger() >= 2 ) + { + GL_State( GLS_DEPTHFUNC_EQUAL | GLS_STENCIL_OP_FAIL_KEEP | GLS_STENCIL_OP_ZFAIL_INCR | GLS_STENCIL_OP_PASS_INCR ); + } + else + { + GL_State( GLS_DEPTHFUNC_EQUAL | GLS_STENCIL_OP_FAIL_KEEP | GLS_STENCIL_OP_ZFAIL_KEEP | GLS_STENCIL_OP_PASS_INCR ); + } + + globalImages->defaultImage->Bind(); + + for( vLight = viewDef->viewLights; vLight; vLight = vLight->next ) + { + for( i = 0; i < 2; i++ ) + { + for( surf = i ? vLight->localInteractions : vLight->globalInteractions; surf; surf = ( drawSurf_t* )surf->nextOnLight ) + { + DBG_SimpleSurfaceSetup( surf ); + DrawElementsWithCounters( surf ); + } + } + } + + // display the results + DBG_ColorByStencilBuffer(); + + if( r_showLightCount.GetInteger() > 2 ) + { + DBG_CountStencilBuffer(); + } +} + +/* +==================== +idRenderBackend::DBG_RenderDrawSurfListWithFunction + +The triangle functions can check backEnd.currentSpace != surf->space +to see if they need to perform any new matrix setup. The modelview +matrix will already have been loaded, and backEnd.currentSpace will +be updated after the triangle function completes. +==================== +*/ +void idRenderBackend::DBG_RenderDrawSurfListWithFunction( drawSurf_t** drawSurfs, int numDrawSurfs ) +{ + currentSpace = NULL; + + for( int i = 0 ; i < numDrawSurfs ; i++ ) + { + const drawSurf_t* drawSurf = drawSurfs[i]; + if( drawSurf == NULL ) + { + continue; + } + + assert( drawSurf->space != NULL ); + + // RB begin +#if 1 + if( drawSurf->space != currentSpace ) + { + currentSpace = drawSurf->space; + + RB_SetMVP( drawSurf->space->mvp ); + } +#else + + if( drawSurf->space != NULL ) // is it ever NULL? Do we need to check? + { + // Set these values ahead of time so we don't have to reconstruct the matrices on the consoles + if( drawSurf->space->weaponDepthHack ) + { + RB_SetWeaponDepthHack(); + } + + if( drawSurf->space->modelDepthHack != 0.0f ) + { + RB_SetModelDepthHack( drawSurf->space->modelDepthHack ); + } + + // change the matrix if needed + if( drawSurf->space != backEnd.currentSpace ) + { + RB_LoadMatrixWithBypass( drawSurf->space->modelViewMatrix ); + } + + if( drawSurf->space->weaponDepthHack ) + { + RB_EnterWeaponDepthHack(); + } + + if( drawSurf->space->modelDepthHack != 0.0f ) + { + RB_EnterModelDepthHack( drawSurf->space->modelDepthHack ); + } + } +#endif + + if( drawSurf->jointCache ) + { + renderProgManager.BindShader_ColorSkinned(); + } + else + { + renderProgManager.BindShader_Color(); + } + // RB end + + // change the scissor if needed + if( r_useScissor.GetBool() && !currentScissor.Equals( drawSurf->scissorRect ) ) + { + currentScissor = drawSurf->scissorRect; + + GL_Scissor( viewDef->viewport.x1 + currentScissor.x1, + viewDef->viewport.y1 + currentScissor.y1, + currentScissor.x2 + 1 - currentScissor.x1, + currentScissor.y2 + 1 - currentScissor.y1 ); + } + + // render it + DrawElementsWithCounters( drawSurf ); + + // RB begin + /*if( drawSurf->space != NULL && ( drawSurf->space->weaponDepthHack || drawSurf->space->modelDepthHack != 0.0f ) ) + { + RB_LeaveDepthHack(); + }*/ + // RB end + + currentSpace = drawSurf->space; + } +} + +/* +================= +idRenderBackend::DBG_ShowSilhouette + +Blacks out all edges, then adds color for each edge that a shadow +plane extends from, allowing you to see doubled edges + +FIXME: not thread safe! +================= +*/ +void idRenderBackend::DBG_ShowSilhouette() +{ + int i; + const drawSurf_t* surf; + const viewLight_t* vLight; + + if( !r_showSilhouette.GetBool() ) + { + return; + } + + // clear all triangle edges to black + globalImages->BindNull(); + + // RB begin + renderProgManager.BindShader_Color(); + // RB end + + GL_Color( 0, 0, 0 ); + + GL_State( GLS_DEPTHFUNC_ALWAYS | GLS_POLYMODE_LINE ); + + GL_Cull( CT_TWO_SIDED ); + + DBG_RenderDrawSurfListWithFunction( viewDef->drawSurfs, viewDef->numDrawSurfs ); + + + // now blend in edges that cast silhouettes + DBG_SimpleWorldSetup(); + + GL_Color( 0.5, 0, 0 ); + GL_State( GLS_SRCBLEND_ONE | GLS_DSTBLEND_ONE ); + + for( vLight = viewDef->viewLights; vLight; vLight = vLight->next ) + { + for( i = 0; i < 2; i++ ) + { + for( surf = i ? vLight->localShadows : vLight->globalShadows + ; surf; surf = ( drawSurf_t* )surf->nextOnLight ) + { + DBG_SimpleSurfaceSetup( surf ); + + const srfTriangles_t* tri = surf->frontEndGeo; + + idVertexBuffer vertexBuffer; + if( !vertexCache.GetVertexBuffer( tri->shadowCache, &vertexBuffer ) ) + { + continue; + } + + // RB: 64 bit fixes, changed GLuint to GLintptr + glBindBuffer( GL_ARRAY_BUFFER, ( GLintptr )vertexBuffer.GetAPIObject() ); + GLintptr vertOffset = vertexBuffer.GetOffset(); + // RB end + + glVertexPointer( 3, GL_FLOAT, sizeof( idShadowVert ), ( void* )vertOffset ); + glBegin( GL_LINES ); + + for( int j = 0; j < tri->numIndexes; j += 3 ) + { + int i1 = tri->indexes[j + 0]; + int i2 = tri->indexes[j + 1]; + int i3 = tri->indexes[j + 2]; + + if( ( i1 & 1 ) + ( i2 & 1 ) + ( i3 & 1 ) == 1 ) + { + if( ( i1 & 1 ) + ( i2 & 1 ) == 0 ) + { + glArrayElement( i1 ); + glArrayElement( i2 ); + } + else if( ( i1 & 1 ) + ( i3 & 1 ) == 0 ) + { + glArrayElement( i1 ); + glArrayElement( i3 ); + } + } + } + glEnd(); + + } + } + } + + GL_State( GLS_DEFAULT ); + GL_Color( 1, 1, 1 ); + GL_Cull( CT_FRONT_SIDED ); +} + +/* +===================== +idRenderBackend::DBG_ShowTris + +Debugging tool +===================== +*/ +void idRenderBackend::DBG_ShowTris( drawSurf_t** drawSurfs, int numDrawSurfs ) +{ + + modelTrace_t mt; + idVec3 end; + + if( r_showTris.GetInteger() == 0 ) + { + return; + } + + idVec4 color( 1, 1, 1, 1 ); + + GL_PolygonOffset( -1.0f, -2.0f ); + + switch( r_showTris.GetInteger() ) + { + case 1: // only draw visible ones + GL_State( GLS_DEPTHMASK | GLS_ALPHAMASK | GLS_POLYMODE_LINE | GLS_POLYGON_OFFSET ); + break; + case 2: // draw all front facing + case 3: // draw all + GL_State( GLS_DEPTHMASK | GLS_ALPHAMASK | GLS_POLYMODE_LINE | GLS_POLYGON_OFFSET | GLS_DEPTHFUNC_ALWAYS ); + break; + case 4: // only draw visible ones with blended lines + GL_State( GLS_DEPTHMASK | GLS_ALPHAMASK | GLS_POLYMODE_LINE | GLS_POLYGON_OFFSET | GLS_SRCBLEND_SRC_ALPHA | GLS_DSTBLEND_ONE_MINUS_SRC_ALPHA ); + color[3] = 0.4f; + break; + } + + if( r_showTris.GetInteger() == 3 ) + { + GL_Cull( CT_TWO_SIDED ); + } + + GL_Color( color ); + + DBG_RenderDrawSurfListWithFunction( drawSurfs, numDrawSurfs ); + + if( r_showTris.GetInteger() == 3 ) + { + GL_Cull( CT_FRONT_SIDED ); + } +} + +/* +===================== +idRenderBackend::DBG_ShowSurfaceInfo + +Debugging tool +===================== +*/ + + +static idStr surfModelName, surfMatName; +static idVec3 surfPoint; +static bool surfTraced = false; + + +void idRenderSystemLocal::OnFrame() +{ + // Do tracing at a safe time to avoid threading issues. + modelTrace_t mt; + idVec3 start, end; + + surfTraced = false; + + if( !r_showSurfaceInfo.GetBool() ) + { + return; + } + + if( tr.primaryView == NULL ) + { + return; + } + + // start far enough away that we don't hit the player model + start = tr.primaryView->renderView.vieworg + tr.primaryView->renderView.viewaxis[0] * 32; + end = start + tr.primaryView->renderView.viewaxis[0] * 1000.0f; + if( !tr.primaryWorld->Trace( mt, start, end, 0.0f, false ) ) + { + return; + } + + surfPoint = mt.point; + surfModelName = mt.entity->hModel->Name(); + surfMatName = mt.material->GetName(); + surfTraced = true; +} + + +void idRenderBackend::DBG_ShowSurfaceInfo( drawSurf_t** drawSurfs, int numDrawSurfs ) +{ + if( !r_showSurfaceInfo.GetBool() || !surfTraced ) + { + return; + } + + // globalImages->BindNull(); + // qglDisable( GL_TEXTURE_2D ); + + DBG_SimpleWorldSetup(); + + // foresthale 2014-05-02: don't use a shader for tools + //renderProgManager.BindShader_TextureVertexColor(); + GL_SelectTexture( 0 ); + globalImages->whiteImage->Bind(); + + RB_SetVertexColorParms( SVC_MODULATE ); + // foresthale 2014-05-02: don't use a shader for tools + //renderProgManager.CommitUniforms(); + + GL_Color( 1, 1, 1 ); + + static float scale = -1; + static float bias = -2; + + GL_PolygonOffset( scale, bias ); + GL_State( GLS_DEPTHFUNC_ALWAYS | GLS_POLYMODE_LINE | GLS_POLYGON_OFFSET ); + + // idVec3 trans[3]; + // float matrix[16]; + + // transform the object verts into global space + // R_AxisToModelMatrix( mt.entity->axis, mt.entity->origin, matrix ); + + tr.primaryWorld->DrawText( surfModelName, surfPoint + tr.primaryView->renderView.viewaxis[2] * 12, + 0.35f, colorRed, tr.primaryView->renderView.viewaxis ); + tr.primaryWorld->DrawText( surfMatName, surfPoint, + 0.35f, colorBlue, tr.primaryView->renderView.viewaxis ); +} + +/* +===================== +idRenderBackend::DBG_ShowViewEntitys + +Debugging tool +===================== +*/ +void idRenderBackend::DBG_ShowViewEntitys( viewEntity_t* vModels ) +{ + if( !r_showViewEntitys.GetBool() ) + { + return; + } + + if( r_showViewEntitys.GetInteger() >= 2 ) + { + common->Printf( "view entities: " ); + for( const viewEntity_t* vModel = vModels; vModel; vModel = vModel->next ) + { + if( vModel->entityDef->IsDirectlyVisible() ) + { + common->Printf( "<%i> ", vModel->entityDef->index ); + } + else + { + common->Printf( "%i ", vModel->entityDef->index ); + } + } + common->Printf( "\n" ); + } + + globalImages->BindNull(); + + renderProgManager.BindShader_Color(); + + GL_Color( 1, 1, 1 ); + GL_State( GLS_DEPTHFUNC_ALWAYS | GLS_POLYMODE_LINE ); + GL_Cull( CT_TWO_SIDED ); + + for( const viewEntity_t* vModel = vModels; vModel; vModel = vModel->next ) + { + idBounds b; + + //glLoadMatrixf( vModel->modelViewMatrix ); + + const idRenderEntityLocal* edef = vModel->entityDef; + if( !edef ) + { + continue; + } + + // draw the model bounds in white if directly visible, + // or, blue if it is only-for-sahdow + idVec4 color; + if( edef->IsDirectlyVisible() ) + { + color.Set( 1, 1, 1, 1 ); + } + else + { + color.Set( 0, 0, 1, 1 ); + } + GL_Color( color[0], color[1], color[2] ); + RB_DrawBounds( edef->localReferenceBounds ); + + // transform the upper bounds corner into global space + if( r_showViewEntitys.GetInteger() >= 2 ) + { + idVec3 corner; + R_LocalPointToGlobal( vModel->modelMatrix, edef->localReferenceBounds[1], corner ); + + tr.primaryWorld->DrawText( + va( "%i:%s", edef->index, edef->parms.hModel->Name() ), + corner, + 0.25f, color, + tr.primaryView->renderView.viewaxis ); + } + + // draw the actual bounds in yellow if different + if( r_showViewEntitys.GetInteger() >= 3 ) + { + GL_Color( 1, 1, 0 ); + // FIXME: cannot instantiate a dynamic model from the renderer back-end + idRenderModel* model = R_EntityDefDynamicModel( vModel->entityDef ); + if( !model ) + { + continue; // particles won't instantiate without a current view + } + b = model->Bounds( &vModel->entityDef->parms ); + if( b != vModel->entityDef->localReferenceBounds ) + { + RB_DrawBounds( b ); + } + } + } +} + +/* +===================== +idRenderBackend::DBG_ShowTexturePolarity + +Shade triangle red if they have a positive texture area +green if they have a negative texture area, or blue if degenerate area +===================== +*/ +void idRenderBackend::DBG_ShowTexturePolarity( drawSurf_t** drawSurfs, int numDrawSurfs ) +{ + int i, j; + drawSurf_t* drawSurf; + const srfTriangles_t* tri; + + if( !r_showTexturePolarity.GetBool() ) + { + return; + } + globalImages->BindNull(); + + GL_State( GLS_SRCBLEND_SRC_ALPHA | GLS_DSTBLEND_ONE_MINUS_SRC_ALPHA ); + + GL_Color( 1, 1, 1 ); + + for( i = 0; i < numDrawSurfs; i++ ) + { + drawSurf = drawSurfs[i]; + tri = drawSurf->frontEndGeo; + if( tri == NULL || tri->verts == NULL ) + { + continue; + } + + DBG_SimpleSurfaceSetup( drawSurf ); + + glBegin( GL_TRIANGLES ); + for( j = 0; j < tri->numIndexes; j += 3 ) + { + idDrawVert* a, *b, *c; + float d0[5], d1[5]; + float area; + + a = tri->verts + tri->indexes[j]; + b = tri->verts + tri->indexes[j + 1]; + c = tri->verts + tri->indexes[j + 2]; + + const idVec2 aST = a->GetTexCoord(); + const idVec2 bST = b->GetTexCoord(); + const idVec2 cST = c->GetTexCoord(); + + d0[3] = bST[0] - aST[0]; + d0[4] = bST[1] - aST[1]; + + d1[3] = cST[0] - aST[0]; + d1[4] = cST[1] - aST[1]; + + area = d0[3] * d1[4] - d0[4] * d1[3]; + + if( idMath::Fabs( area ) < 0.0001 ) + { + GL_Color( 0, 0, 1, 0.5 ); + } + else if( area < 0 ) + { + GL_Color( 1, 0, 0, 0.5 ); + } + else + { + GL_Color( 0, 1, 0, 0.5 ); + } + glVertex3fv( a->xyz.ToFloatPtr() ); + glVertex3fv( b->xyz.ToFloatPtr() ); + glVertex3fv( c->xyz.ToFloatPtr() ); + } + glEnd(); + } + + GL_State( GLS_DEFAULT ); +} + +/* +===================== +idRenderBackend::DBG_ShowUnsmoothedTangents + +Shade materials that are using unsmoothed tangents +===================== +*/ +void idRenderBackend::DBG_ShowUnsmoothedTangents( drawSurf_t** drawSurfs, int numDrawSurfs ) +{ + int i, j; + drawSurf_t* drawSurf; + const srfTriangles_t* tri; + + if( !r_showUnsmoothedTangents.GetBool() ) + { + return; + } + globalImages->BindNull(); + + GL_State( GLS_SRCBLEND_SRC_ALPHA | GLS_DSTBLEND_ONE_MINUS_SRC_ALPHA ); + + GL_Color( 0, 1, 0, 0.5 ); + + for( i = 0; i < numDrawSurfs; i++ ) + { + drawSurf = drawSurfs[i]; + + if( !drawSurf->material->UseUnsmoothedTangents() ) + { + continue; + } + + DBG_SimpleSurfaceSetup( drawSurf ); + + tri = drawSurf->frontEndGeo; + if( tri == NULL || tri->verts == NULL ) + { + continue; + } + + glBegin( GL_TRIANGLES ); + for( j = 0; j < tri->numIndexes; j += 3 ) + { + idDrawVert* a, *b, *c; + + a = tri->verts + tri->indexes[j]; + b = tri->verts + tri->indexes[j + 1]; + c = tri->verts + tri->indexes[j + 2]; + + glVertex3fv( a->xyz.ToFloatPtr() ); + glVertex3fv( b->xyz.ToFloatPtr() ); + glVertex3fv( c->xyz.ToFloatPtr() ); + } + glEnd(); + } + + GL_State( GLS_DEFAULT ); +} + +/* +===================== +RB_ShowTangentSpace + +Shade a triangle by the RGB colors of its tangent space +1 = tangents[0] +2 = tangents[1] +3 = normal +===================== +*/ +void idRenderBackend::DBG_ShowTangentSpace( drawSurf_t** drawSurfs, int numDrawSurfs ) +{ + int i, j; + drawSurf_t* drawSurf; + const srfTriangles_t* tri; + + if( !r_showTangentSpace.GetInteger() ) + { + return; + } + globalImages->BindNull(); + + GL_State( GLS_SRCBLEND_SRC_ALPHA | GLS_DSTBLEND_ONE_MINUS_SRC_ALPHA ); + + for( i = 0; i < numDrawSurfs; i++ ) + { + drawSurf = drawSurfs[i]; + + DBG_SimpleSurfaceSetup( drawSurf ); + + tri = drawSurf->frontEndGeo; + if( tri == NULL || tri->verts == NULL ) + { + continue; + } + + glBegin( GL_TRIANGLES ); + for( j = 0; j < tri->numIndexes; j++ ) + { + const idDrawVert* v; + + v = &tri->verts[tri->indexes[j]]; + + if( r_showTangentSpace.GetInteger() == 1 ) + { + const idVec3 vertexTangent = v->GetTangent(); + GL_Color( 0.5 + 0.5 * vertexTangent[0], 0.5 + 0.5 * vertexTangent[1], + 0.5 + 0.5 * vertexTangent[2], 0.5 ); + } + else if( r_showTangentSpace.GetInteger() == 2 ) + { + const idVec3 vertexBiTangent = v->GetBiTangent(); + GL_Color( 0.5 + 0.5 * vertexBiTangent[0], 0.5 + 0.5 * vertexBiTangent[1], + 0.5 + 0.5 * vertexBiTangent[2], 0.5 ); + } + else + { + const idVec3 vertexNormal = v->GetNormal(); + GL_Color( 0.5 + 0.5 * vertexNormal[0], 0.5 + 0.5 * vertexNormal[1], + 0.5 + 0.5 * vertexNormal[2], 0.5 ); + } + glVertex3fv( v->xyz.ToFloatPtr() ); + } + glEnd(); + } + + GL_State( GLS_DEFAULT ); +} + +/* +===================== +idRenderBackend::DBG_ShowVertexColor + +Draw each triangle with the solid vertex colors +===================== +*/ +void idRenderBackend::DBG_ShowVertexColor( drawSurf_t** drawSurfs, int numDrawSurfs ) +{ + int i, j; + drawSurf_t* drawSurf; + const srfTriangles_t* tri; + + if( !r_showVertexColor.GetBool() ) + { + return; + } + globalImages->BindNull(); + + // RB begin + renderProgManager.BindShader_VertexColor(); + + GL_State( GLS_DEPTHFUNC_LESS ); + + for( i = 0; i < numDrawSurfs; i++ ) + { + drawSurf = drawSurfs[i]; + + DBG_SimpleSurfaceSetup( drawSurf ); + + tri = drawSurf->frontEndGeo; + if( tri == NULL || tri->verts == NULL ) + { + continue; + } + + renderProgManager.CommitUniforms(); + + glBegin( GL_TRIANGLES ); + for( j = 0; j < tri->numIndexes; j++ ) + { + const idDrawVert* v; + + v = &tri->verts[tri->indexes[j]]; + glColor4ubv( v->color ); + glVertex3fv( v->xyz.ToFloatPtr() ); + } + glEnd(); + } + + // RB end + + GL_State( GLS_DEFAULT ); +} + +/* +===================== +idRenderBackend::DBG_ShowNormals + +Debugging tool +===================== +*/ +void idRenderBackend::DBG_ShowNormals( drawSurf_t** drawSurfs, int numDrawSurfs ) +{ + int i, j; + drawSurf_t* drawSurf; + idVec3 end; + const srfTriangles_t* tri; + float size; + bool showNumbers; + idVec3 pos; + + if( r_showNormals.GetFloat() == 0.0f ) + { + return; + } + + globalImages->BindNull(); + + if( !r_debugLineDepthTest.GetBool() ) + { + GL_State( GLS_POLYMODE_LINE | GLS_DEPTHFUNC_ALWAYS ); + } + else + { + GL_State( GLS_POLYMODE_LINE ); + } + + size = r_showNormals.GetFloat(); + if( size < 0.0f ) + { + size = -size; + showNumbers = true; + } + else + { + showNumbers = false; + } + + for( i = 0; i < numDrawSurfs; i++ ) + { + drawSurf = drawSurfs[i]; + + DBG_SimpleSurfaceSetup( drawSurf ); + + tri = drawSurf->frontEndGeo; + if( tri == NULL || tri->verts == NULL ) + { + continue; + } + + // RB begin + renderProgManager.BindShader_VertexColor(); + + glBegin( GL_LINES ); + for( j = 0; j < tri->numVerts; j++ ) + { + const idVec3 normal = tri->verts[j].GetNormal(); + const idVec3 tangent = tri->verts[j].GetTangent(); + const idVec3 bitangent = tri->verts[j].GetBiTangent(); + + glColor3f( 0, 0, 1 ); + glVertex3fv( tri->verts[j].xyz.ToFloatPtr() ); + VectorMA( tri->verts[j].xyz, size, normal, end ); + glVertex3fv( end.ToFloatPtr() ); + + glColor3f( 1, 0, 0 ); + glVertex3fv( tri->verts[j].xyz.ToFloatPtr() ); + VectorMA( tri->verts[j].xyz, size, tangent, end ); + glVertex3fv( end.ToFloatPtr() ); + + glColor3f( 0, 1, 0 ); + glVertex3fv( tri->verts[j].xyz.ToFloatPtr() ); + VectorMA( tri->verts[j].xyz, size, bitangent, end ); + glVertex3fv( end.ToFloatPtr() ); + } + glEnd(); + + // RB end + } + + if( showNumbers ) + { + DBG_SimpleWorldSetup(); + + for( i = 0; i < numDrawSurfs; i++ ) + { + drawSurf = drawSurfs[i]; + tri = drawSurf->frontEndGeo; + if( tri == NULL || tri->verts == NULL ) + { + continue; + } + + for( j = 0; j < tri->numVerts; j++ ) + { + const idVec3 normal = tri->verts[j].GetNormal(); + const idVec3 tangent = tri->verts[j].GetTangent(); + R_LocalPointToGlobal( drawSurf->space->modelMatrix, tri->verts[j].xyz + tangent + normal * 0.2f, pos ); + RB_DrawText( va( "%d", j ), pos, 0.01f, colorWhite, viewDef->renderView.viewaxis, 1 ); + } + + for( j = 0; j < tri->numIndexes; j += 3 ) + { + const idVec3 normal = tri->verts[ tri->indexes[ j + 0 ] ].GetNormal(); + R_LocalPointToGlobal( drawSurf->space->modelMatrix, ( tri->verts[ tri->indexes[ j + 0 ] ].xyz + tri->verts[ tri->indexes[ j + 1 ] ].xyz + tri->verts[ tri->indexes[ j + 2 ] ].xyz ) * ( 1.0f / 3.0f ) + normal * 0.2f, pos ); + RB_DrawText( va( "%d", j / 3 ), pos, 0.01f, colorCyan, viewDef->renderView.viewaxis, 1 ); + } + } + } +} + +/* +===================== +idRenderBackend::DBG_ShowTextureVectors + +Draw texture vectors in the center of each triangle +===================== +*/ +void idRenderBackend::DBG_ShowTextureVectors( drawSurf_t** drawSurfs, int numDrawSurfs ) +{ + if( r_showTextureVectors.GetFloat() == 0.0f ) + { + return; + } + + GL_State( GLS_DEPTHFUNC_LESS ); + + globalImages->BindNull(); + + for( int i = 0; i < numDrawSurfs; i++ ) + { + drawSurf_t* drawSurf = drawSurfs[i]; + + const srfTriangles_t* tri = drawSurf->frontEndGeo; + + if( tri == NULL || tri->verts == NULL ) + { + continue; + } + + DBG_SimpleSurfaceSetup( drawSurf ); + + // draw non-shared edges in yellow + glBegin( GL_LINES ); + + for( int j = 0; j < tri->numIndexes; j += 3 ) + { + float d0[5], d1[5]; + idVec3 temp; + idVec3 tangents[2]; + + const idDrawVert* a = &tri->verts[tri->indexes[j + 0]]; + const idDrawVert* b = &tri->verts[tri->indexes[j + 1]]; + const idDrawVert* c = &tri->verts[tri->indexes[j + 2]]; + + const idPlane plane( a->xyz, b->xyz, c->xyz ); + + // make the midpoint slightly above the triangle + const idVec3 mid = ( a->xyz + b->xyz + c->xyz ) * ( 1.0f / 3.0f ) + 0.1f * plane.Normal(); + + // calculate the texture vectors + const idVec2 aST = a->GetTexCoord(); + const idVec2 bST = b->GetTexCoord(); + const idVec2 cST = c->GetTexCoord(); + + d0[0] = b->xyz[0] - a->xyz[0]; + d0[1] = b->xyz[1] - a->xyz[1]; + d0[2] = b->xyz[2] - a->xyz[2]; + d0[3] = bST[0] - aST[0]; + d0[4] = bST[1] - aST[1]; + + d1[0] = c->xyz[0] - a->xyz[0]; + d1[1] = c->xyz[1] - a->xyz[1]; + d1[2] = c->xyz[2] - a->xyz[2]; + d1[3] = cST[0] - aST[0]; + d1[4] = cST[1] - aST[1]; + + const float area = d0[3] * d1[4] - d0[4] * d1[3]; + if( area == 0 ) + { + continue; + } + const float inva = 1.0f / area; + + temp[0] = ( d0[0] * d1[4] - d0[4] * d1[0] ) * inva; + temp[1] = ( d0[1] * d1[4] - d0[4] * d1[1] ) * inva; + temp[2] = ( d0[2] * d1[4] - d0[4] * d1[2] ) * inva; + temp.Normalize(); + tangents[0] = temp; + + temp[0] = ( d0[3] * d1[0] - d0[0] * d1[3] ) * inva; + temp[1] = ( d0[3] * d1[1] - d0[1] * d1[3] ) * inva; + temp[2] = ( d0[3] * d1[2] - d0[2] * d1[3] ) * inva; + temp.Normalize(); + tangents[1] = temp; + + // draw the tangents + tangents[0] = mid + tangents[0] * r_showTextureVectors.GetFloat(); + tangents[1] = mid + tangents[1] * r_showTextureVectors.GetFloat(); + + GL_Color( 1, 0, 0 ); + glVertex3fv( mid.ToFloatPtr() ); + glVertex3fv( tangents[0].ToFloatPtr() ); + + GL_Color( 0, 1, 0 ); + glVertex3fv( mid.ToFloatPtr() ); + glVertex3fv( tangents[1].ToFloatPtr() ); + } + + glEnd(); + } +} + +/* +===================== +idRenderBackend::DBG_ShowDominantTris + +Draw lines from each vertex to the dominant triangle center +===================== +*/ +void idRenderBackend::DBG_ShowDominantTris( drawSurf_t** drawSurfs, int numDrawSurfs ) +{ + int i, j; + drawSurf_t* drawSurf; + const srfTriangles_t* tri; + + if( !r_showDominantTri.GetBool() ) + { + return; + } + + GL_State( GLS_DEPTHFUNC_LESS ); + + GL_PolygonOffset( -1, -2 ); + glEnable( GL_POLYGON_OFFSET_LINE ); + + globalImages->BindNull(); + + for( i = 0; i < numDrawSurfs; i++ ) + { + drawSurf = drawSurfs[i]; + + tri = drawSurf->frontEndGeo; + + if( tri == NULL || tri->verts == NULL ) + { + continue; + } + if( !tri->dominantTris ) + { + continue; + } + + DBG_SimpleSurfaceSetup( drawSurf ); + + GL_Color( 1, 1, 0 ); + glBegin( GL_LINES ); + + for( j = 0; j < tri->numVerts; j++ ) + { + const idDrawVert* a, *b, *c; + idVec3 mid; + + // find the midpoint of the dominant tri + + a = &tri->verts[j]; + b = &tri->verts[tri->dominantTris[j].v2]; + c = &tri->verts[tri->dominantTris[j].v3]; + + mid = ( a->xyz + b->xyz + c->xyz ) * ( 1.0f / 3.0f ); + + glVertex3fv( mid.ToFloatPtr() ); + glVertex3fv( a->xyz.ToFloatPtr() ); + } + + glEnd(); + } + glDisable( GL_POLYGON_OFFSET_LINE ); +} + +/* +===================== +idRenderBackend::DBG_ShowEdges + +Debugging tool +===================== +*/ +void idRenderBackend::DBG_ShowEdges( drawSurf_t** drawSurfs, int numDrawSurfs ) +{ + int i, j, k, m, n, o; + drawSurf_t* drawSurf; + const srfTriangles_t* tri; + const silEdge_t* edge; + int danglePlane; + + if( !r_showEdges.GetBool() ) + { + return; + } + + globalImages->BindNull(); + + GL_State( GLS_DEPTHFUNC_ALWAYS ); + + for( i = 0; i < numDrawSurfs; i++ ) + { + drawSurf = drawSurfs[i]; + + tri = drawSurf->frontEndGeo; + + idDrawVert* ac = ( idDrawVert* )tri->verts; + if( !ac ) + { + continue; + } + + DBG_SimpleSurfaceSetup( drawSurf ); + + // draw non-shared edges in yellow + GL_Color( 1, 1, 0 ); + glBegin( GL_LINES ); + + for( j = 0; j < tri->numIndexes; j += 3 ) + { + for( k = 0; k < 3; k++ ) + { + int l, i1, i2; + l = ( k == 2 ) ? 0 : k + 1; + i1 = tri->indexes[j + k]; + i2 = tri->indexes[j + l]; + + // if these are used backwards, the edge is shared + for( m = 0; m < tri->numIndexes; m += 3 ) + { + for( n = 0; n < 3; n++ ) + { + o = ( n == 2 ) ? 0 : n + 1; + if( tri->indexes[m + n] == i2 && tri->indexes[m + o] == i1 ) + { + break; + } + } + if( n != 3 ) + { + break; + } + } + + // if we didn't find a backwards listing, draw it in yellow + if( m == tri->numIndexes ) + { + glVertex3fv( ac[ i1 ].xyz.ToFloatPtr() ); + glVertex3fv( ac[ i2 ].xyz.ToFloatPtr() ); + } + + } + } + + glEnd(); + + // draw dangling sil edges in red + if( !tri->silEdges ) + { + continue; + } + + // the plane number after all real planes + // is the dangling edge + danglePlane = tri->numIndexes / 3; + + GL_Color( 1, 0, 0 ); + + glBegin( GL_LINES ); + for( j = 0; j < tri->numSilEdges; j++ ) + { + edge = tri->silEdges + j; + + if( edge->p1 != danglePlane && edge->p2 != danglePlane ) + { + continue; + } + + glVertex3fv( ac[ edge->v1 ].xyz.ToFloatPtr() ); + glVertex3fv( ac[ edge->v2 ].xyz.ToFloatPtr() ); + } + glEnd(); + } +} + +/* +============== +RB_ShowLights + +Visualize all light volumes used in the current scene +r_showLights 1 : just print volumes numbers, highlighting ones covering the view +r_showLights 2 : also draw planes of each volume +r_showLights 3 : also draw edges of each volume +============== +*/ +void idRenderBackend::DBG_ShowLights() +{ + if( !r_showLights.GetInteger() ) + { + return; + } + + GL_State( GLS_DEFAULT ); + + globalImages->BindNull(); + + renderProgManager.BindShader_Color(); + + GL_Cull( CT_TWO_SIDED ); + + common->Printf( "volumes: " ); // FIXME: not in back end! + + int count = 0; + for( viewLight_t* vLight = viewDef->viewLights; vLight != NULL; vLight = vLight->next ) + { + count++; + + // depth buffered planes + if( r_showLights.GetInteger() >= 2 ) + { + GL_State( GLS_DEPTHFUNC_ALWAYS | GLS_SRCBLEND_SRC_ALPHA | GLS_DSTBLEND_ONE_MINUS_SRC_ALPHA | GLS_DEPTHMASK ); + + // RB: show different light types + if( vLight->parallel ) + { + GL_Color( 1.0f, 0.0f, 0.0f, 0.25f ); + } + else if( vLight->pointLight ) + { + GL_Color( 0.0f, 0.0f, 1.0f, 0.25f ); + } + else + { + GL_Color( 0.0f, 1.0f, 0.0f, 0.25f ); + } + // RB end + + idRenderMatrix invProjectMVPMatrix; + idRenderMatrix::Multiply( viewDef->worldSpace.mvp, vLight->inverseBaseLightProject, invProjectMVPMatrix ); + RB_SetMVP( invProjectMVPMatrix ); + DrawElementsWithCounters( &zeroOneCubeSurface ); + } + + // non-hidden lines + if( r_showLights.GetInteger() >= 3 ) + { + GL_State( GLS_DEPTHFUNC_ALWAYS | GLS_POLYMODE_LINE | GLS_DEPTHMASK ); + GL_Color( 1.0f, 1.0f, 1.0f ); + idRenderMatrix invProjectMVPMatrix; + idRenderMatrix::Multiply( viewDef->worldSpace.mvp, vLight->inverseBaseLightProject, invProjectMVPMatrix ); + RB_SetMVP( invProjectMVPMatrix ); + DrawElementsWithCounters( &zeroOneCubeSurface ); + } + + common->Printf( "%i ", vLight->lightDef->index ); + } + + common->Printf( " = %i total\n", count ); +} + +// RB begin +void idRenderBackend::DBG_ShowShadowMapLODs() +{ + if( !r_showShadowMapLODs.GetInteger() ) + { + return; + } + + GL_State( GLS_DEFAULT ); + + globalImages->BindNull(); + + renderProgManager.BindShader_Color(); + + GL_Cull( CT_TWO_SIDED ); + + common->Printf( "volumes: " ); // FIXME: not in back end! + + int count = 0; + for( viewLight_t* vLight = viewDef->viewLights; vLight != NULL; vLight = vLight->next ) + { + if( !vLight->lightDef->LightCastsShadows() ) + { + continue; + } + + count++; + + // depth buffered planes + if( r_showShadowMapLODs.GetInteger() >= 1 ) + { + GL_State( GLS_DEPTHFUNC_ALWAYS | GLS_SRCBLEND_SRC_ALPHA | GLS_DSTBLEND_ONE_MINUS_SRC_ALPHA | GLS_DEPTHMASK ); + + idVec4 c; + if( vLight->shadowLOD == 0 ) + { + c = colorRed; + } + else if( vLight->shadowLOD == 1 ) + { + c = colorGreen; + } + else if( vLight->shadowLOD == 2 ) + { + c = colorBlue; + } + else if( vLight->shadowLOD == 3 ) + { + c = colorYellow; + } + else if( vLight->shadowLOD == 4 ) + { + c = colorMagenta; + } + else if( vLight->shadowLOD == 5 ) + { + c = colorCyan; + } + else + { + c = colorMdGrey; + } + + c[3] = 0.25f; + GL_Color( c ); + + idRenderMatrix invProjectMVPMatrix; + idRenderMatrix::Multiply( viewDef->worldSpace.mvp, vLight->inverseBaseLightProject, invProjectMVPMatrix ); + RB_SetMVP( invProjectMVPMatrix ); + DrawElementsWithCounters( &zeroOneCubeSurface ); + } + + // non-hidden lines + if( r_showShadowMapLODs.GetInteger() >= 2 ) + { + GL_State( GLS_DEPTHFUNC_ALWAYS | GLS_POLYMODE_LINE | GLS_DEPTHMASK ); + GL_Color( 1.0f, 1.0f, 1.0f ); + idRenderMatrix invProjectMVPMatrix; + idRenderMatrix::Multiply( viewDef->worldSpace.mvp, vLight->inverseBaseLightProject, invProjectMVPMatrix ); + RB_SetMVP( invProjectMVPMatrix ); + DrawElementsWithCounters( &zeroOneCubeSurface ); + } + + common->Printf( "%i ", vLight->lightDef->index ); + } + + common->Printf( " = %i total\n", count ); +} +// RB end + +/* +===================== +idRenderBackend::DBG_ShowPortals + +Debugging tool, won't work correctly with SMP or when mirrors are present +===================== +*/ +void idRenderBackend::DBG_ShowPortals() +{ + if( !r_showPortals.GetBool() ) + { + return; + } + + // all portals are expressed in world coordinates + DBG_SimpleWorldSetup(); + + globalImages->BindNull(); + renderProgManager.BindShader_Color(); + GL_State( GLS_DEPTHFUNC_ALWAYS ); + + idRenderWorldLocal& world = *viewDef->renderWorld; + + // flood out through portals, setting area viewCount + for( int i = 0; i < world.numPortalAreas; i++ ) + { + portalArea_t* area = &world.portalAreas[i]; + + if( area->viewCount != tr.viewCount ) + { + continue; + } + + for( portal_t* p = area->portals; p; p = p->next ) + { + idWinding* w = p->w; + if( !w ) + { + continue; + } + + if( world.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( int j = 0; j < w->GetNumPoints(); j++ ) + { + glVertex3fv( ( *w )[j].ToFloatPtr() ); + } + glEnd(); + } + } +} + +/* +================ +idRenderBackend::DBG_ClearDebugText +================ +*/ +void RB_ClearDebugText( int time ) +{ + int i; + int num; + debugText_t* text; + + rb_debugTextTime = time; + + if( !time ) + { + // free up our strings + text = rb_debugText; + for( i = 0; i < MAX_DEBUG_TEXT; i++, text++ ) + { + text->text.Clear(); + } + rb_numDebugText = 0; + return; + } + + // copy any text that still needs to be drawn + num = 0; + text = rb_debugText; + for( i = 0; i < rb_numDebugText; i++, text++ ) + { + if( text->lifeTime > time ) + { + if( num != i ) + { + rb_debugText[ num ] = *text; + } + num++; + } + } + rb_numDebugText = num; +} + +/* +================ +RB_AddDebugText +================ +*/ +void RB_AddDebugText( const char* text, const idVec3& origin, float scale, const idVec4& color, const idMat3& viewAxis, const int align, const int lifetime, const bool depthTest ) +{ + debugText_t* debugText; + + if( rb_numDebugText < MAX_DEBUG_TEXT ) + { + debugText = &rb_debugText[ rb_numDebugText++ ]; + debugText->text = text; + debugText->origin = origin; + debugText->scale = scale; + debugText->color = color; + debugText->viewAxis = viewAxis; + debugText->align = align; + debugText->lifeTime = rb_debugTextTime + lifetime; + debugText->depthTest = depthTest; + } +} + +/* +================ +RB_DrawTextLength + + returns the length of the given text +================ +*/ +float RB_DrawTextLength( const char* text, float scale, int len ) +{ + int i, num, index, charIndex; + float spacing, textLen = 0.0f; + + if( text && *text ) + { + if( !len ) + { + len = strlen( text ); + } + for( i = 0; i < len; i++ ) + { + charIndex = text[i] - 32; + if( charIndex < 0 || charIndex > NUM_SIMPLEX_CHARS ) + { + continue; + } + num = simplex[charIndex][0] * 2; + spacing = simplex[charIndex][1]; + index = 2; + + while( index - 2 < num ) + { + if( simplex[charIndex][index] < 0 ) + { + index++; + continue; + } + index += 2; + if( simplex[charIndex][index] < 0 ) + { + index++; + continue; + } + } + textLen += spacing * scale; + } + } + return textLen; +} + +/* +================ +RB_DrawText + + oriented on the viewaxis + align can be 0-left, 1-center (default), 2-right +================ +*/ +static void RB_DrawText( const char* text, const idVec3& origin, float scale, const idVec4& color, const idMat3& viewAxis, const int align ) +{ + renderProgManager.BindShader_Color(); + + // RB begin + //GL_Color( color[0], color[1], color[2], 1 /*color[3]*/ ); + renderProgManager.CommitUniforms(); + // RB end + + int i, j, len, num, index, charIndex, line; + float textLen = 1.0f, spacing = 1.0f; + idVec3 org, p1, p2; + + if( text && *text ) + { + glBegin( GL_LINES ); + + if( text[0] == '\n' ) + { + line = 1; + } + else + { + line = 0; + } + + len = strlen( text ); + for( i = 0; i < len; i++ ) + { + + if( i == 0 || text[i] == '\n' ) + { + org = origin - viewAxis[2] * ( line * 36.0f * scale ); + if( align != 0 ) + { + for( j = 1; i + j <= len; j++ ) + { + if( i + j == len || text[i + j] == '\n' ) + { + textLen = RB_DrawTextLength( text + i, scale, j ); + break; + } + } + if( align == 2 ) + { + // right + org += viewAxis[1] * textLen; + } + else + { + // center + org += viewAxis[1] * ( textLen * 0.5f ); + } + } + line++; + } + + charIndex = text[i] - 32; + if( charIndex < 0 || charIndex > NUM_SIMPLEX_CHARS ) + { + continue; + } + num = simplex[charIndex][0] * 2; + spacing = simplex[charIndex][1]; + index = 2; + + while( index - 2 < num ) + { + if( simplex[charIndex][index] < 0 ) + { + index++; + continue; + } + p1 = org + scale * simplex[charIndex][index] * -viewAxis[1] + scale * simplex[charIndex][index + 1] * viewAxis[2]; + index += 2; + if( simplex[charIndex][index] < 0 ) + { + index++; + continue; + } + p2 = org + scale * simplex[charIndex][index] * -viewAxis[1] + scale * simplex[charIndex][index + 1] * viewAxis[2]; + + glVertex3fv( p1.ToFloatPtr() ); + glVertex3fv( p2.ToFloatPtr() ); + } + org -= viewAxis[1] * ( spacing * scale ); + } + + glEnd(); + } +} + +/* +================ +idRenderBackend::DBG_ShowDebugText +================ +*/ +void idRenderBackend::DBG_ShowDebugText() +{ + int i; + int width; + debugText_t* text; + + if( !rb_numDebugText ) + { + return; + } + + // all lines are expressed in world coordinates + DBG_SimpleWorldSetup(); + + globalImages->BindNull(); + + width = r_debugLineWidth.GetInteger(); + if( width < 1 ) + { + width = 1; + } + else if( width > 10 ) + { + width = 10; + } + + // draw lines + glLineWidth( width ); + + + if( !r_debugLineDepthTest.GetBool() ) + { + GL_State( GLS_POLYMODE_LINE | GLS_DEPTHFUNC_ALWAYS ); + } + else + { + GL_State( GLS_POLYMODE_LINE ); + } + + text = rb_debugText; + for( i = 0; i < rb_numDebugText; i++, text++ ) + { + if( !text->depthTest ) + { + GL_Color( text->color.ToVec3() ); + RB_DrawText( text->text, text->origin, text->scale, text->color, text->viewAxis, text->align ); + } + } + + if( !r_debugLineDepthTest.GetBool() ) + { + GL_State( GLS_POLYMODE_LINE ); + } + + text = rb_debugText; + for( i = 0; i < rb_numDebugText; i++, text++ ) + { + if( text->depthTest ) + { + GL_Color( text->color.ToVec3() ); + RB_DrawText( text->text, text->origin, text->scale, text->color, text->viewAxis, text->align ); + } + } + + glLineWidth( 1 ); +} + +/* +================ +RB_ClearDebugLines +================ +*/ +void RB_ClearDebugLines( int time ) +{ + int i; + int num; + debugLine_t* line; + + rb_debugLineTime = time; + + if( !time ) + { + rb_numDebugLines = 0; + return; + } + + // copy any lines that still need to be drawn + num = 0; + line = rb_debugLines; + for( i = 0; i < rb_numDebugLines; i++, line++ ) + { + if( line->lifeTime > time ) + { + if( num != i ) + { + rb_debugLines[ num ] = *line; + } + num++; + } + } + rb_numDebugLines = num; +} + +/* +================ +RB_AddDebugLine +================ +*/ +void RB_AddDebugLine( const idVec4& color, const idVec3& start, const idVec3& end, const int lifeTime, const bool depthTest ) +{ + debugLine_t* line; + + if( rb_numDebugLines < MAX_DEBUG_LINES ) + { + line = &rb_debugLines[ rb_numDebugLines++ ]; + line->rgb = color; + line->start = start; + line->end = end; + line->depthTest = depthTest; + line->lifeTime = rb_debugLineTime + lifeTime; + } +} + +/* +================ +idRenderBackend::DBG_ShowDebugLines +================ +*/ +void idRenderBackend::DBG_ShowDebugLines() +{ + int i; + int width; + debugLine_t* line; + + if( !rb_numDebugLines ) + { + return; + } + + // all lines are expressed in world coordinates + DBG_SimpleWorldSetup(); + + // RB begin + renderProgManager.BindShader_VertexColor(); + renderProgManager.CommitUniforms(); + // RB end + + globalImages->BindNull(); + + width = r_debugLineWidth.GetInteger(); + if( width < 1 ) + { + width = 1; + } + else if( width > 10 ) + { + width = 10; + } + + // draw lines + glLineWidth( width ); + + if( !r_debugLineDepthTest.GetBool() ) + { + GL_State( GLS_POLYMODE_LINE | GLS_DEPTHFUNC_ALWAYS ); + } + else + { + GL_State( GLS_POLYMODE_LINE ); + } + + glBegin( GL_LINES ); + + line = rb_debugLines; + for( i = 0; i < rb_numDebugLines; i++, line++ ) + { + if( !line->depthTest ) + { + glColor3fv( line->rgb.ToFloatPtr() ); + glVertex3fv( line->start.ToFloatPtr() ); + glVertex3fv( line->end.ToFloatPtr() ); + } + } + glEnd(); + + if( !r_debugLineDepthTest.GetBool() ) + { + GL_State( GLS_POLYMODE_LINE ); + } + + glBegin( GL_LINES ); + + line = rb_debugLines; + for( i = 0; i < rb_numDebugLines; i++, line++ ) + { + if( line->depthTest ) + { + glColor4fv( line->rgb.ToFloatPtr() ); + glVertex3fv( line->start.ToFloatPtr() ); + glVertex3fv( line->end.ToFloatPtr() ); + } + } + + glEnd(); + + glLineWidth( 1 ); + GL_State( GLS_DEFAULT ); +} + +/* +================ +RB_ClearDebugPolygons +================ +*/ +void RB_ClearDebugPolygons( int time ) +{ + int i; + int num; + debugPolygon_t* poly; + + rb_debugPolygonTime = time; + + if( !time ) + { + rb_numDebugPolygons = 0; + return; + } + + // copy any polygons that still need to be drawn + num = 0; + + poly = rb_debugPolygons; + for( i = 0; i < rb_numDebugPolygons; i++, poly++ ) + { + if( poly->lifeTime > time ) + { + if( num != i ) + { + rb_debugPolygons[ num ] = *poly; + } + num++; + } + } + rb_numDebugPolygons = num; +} + +/* +================ +RB_AddDebugPolygon +================ +*/ +void RB_AddDebugPolygon( const idVec4& color, const idWinding& winding, const int lifeTime, const bool depthTest ) +{ + debugPolygon_t* poly; + + if( rb_numDebugPolygons < MAX_DEBUG_POLYGONS ) + { + poly = &rb_debugPolygons[ rb_numDebugPolygons++ ]; + poly->rgb = color; + poly->winding = winding; + poly->depthTest = depthTest; + poly->lifeTime = rb_debugPolygonTime + lifeTime; + } +} + +/* +================ +idRenderBackend::DBG_ShowDebugPolygons +================ +*/ +void idRenderBackend::DBG_ShowDebugPolygons() +{ + int i, j; + debugPolygon_t* poly; + + if( !rb_numDebugPolygons ) + { + return; + } + + // all lines are expressed in world coordinates + DBG_SimpleWorldSetup(); + + // RB begin + renderProgManager.BindShader_VertexColor(); + renderProgManager.CommitUniforms(); + // RB end + + globalImages->BindNull(); + + if( r_debugPolygonFilled.GetBool() ) + { + GL_State( GLS_POLYGON_OFFSET | GLS_SRCBLEND_SRC_ALPHA | GLS_DSTBLEND_ONE_MINUS_SRC_ALPHA | GLS_DEPTHMASK ); + GL_PolygonOffset( -1, -2 ); + } + else + { + GL_State( GLS_POLYGON_OFFSET | GLS_POLYMODE_LINE ); + GL_PolygonOffset( -1, -2 ); + } + + poly = rb_debugPolygons; + for( i = 0; i < rb_numDebugPolygons; i++, poly++ ) + { +// if ( !poly->depthTest ) { + + glColor4fv( poly->rgb.ToFloatPtr() ); + + glBegin( GL_POLYGON ); + + for( j = 0; j < poly->winding.GetNumPoints(); j++ ) + { + glVertex3fv( poly->winding[j].ToFloatPtr() ); + } + + glEnd(); +// } + } + + GL_State( GLS_DEFAULT ); + + if( r_debugPolygonFilled.GetBool() ) + { + glDisable( GL_POLYGON_OFFSET_FILL ); + } + else + { + glDisable( GL_POLYGON_OFFSET_LINE ); + } + + GL_State( GLS_DEFAULT ); +} + +/* +================ +idRenderBackend::DBG_ShowCenterOfProjection +================ +*/ +void idRenderBackend::DBG_ShowCenterOfProjection() +{ + if( !r_showCenterOfProjection.GetBool() ) + { + return; + } + + const int w = viewDef->scissor.GetWidth(); + const int h = viewDef->scissor.GetHeight(); + glClearColor( 1, 0, 0, 1 ); + for( float f = 0.0f ; f <= 1.0f ; f += 0.125f ) + { + glScissor( w * f - 1 , 0, 3, h ); + glClear( GL_COLOR_BUFFER_BIT ); + glScissor( 0, h * f - 1 , w, 3 ); + glClear( GL_COLOR_BUFFER_BIT ); + } + glClearColor( 0, 1, 0, 1 ); + float f = 0.5f; + glScissor( w * f - 1 , 0, 3, h ); + glClear( GL_COLOR_BUFFER_BIT ); + glScissor( 0, h * f - 1 , w, 3 ); + glClear( GL_COLOR_BUFFER_BIT ); + + glScissor( 0, 0, w, h ); +} + +/* +================ +idRenderBackend::DBG_ShowLines + +Draw exact pixel lines to check pixel center sampling +================ +*/ +void idRenderBackend::DBG_ShowLines() +{ + if( !r_showLines.GetBool() ) + { + return; + } + + glEnable( GL_SCISSOR_TEST ); + if( viewDef->renderView.viewEyeBuffer == 0 ) + { + glClearColor( 1, 0, 0, 1 ); + } + else if( viewDef->renderView.viewEyeBuffer == 1 ) + { + glClearColor( 0, 1, 0, 1 ); + } + else + { + glClearColor( 0, 0, 1, 1 ); + } + + const int start = ( r_showLines.GetInteger() > 2 ); // 1,3 = horizontal, 2,4 = vertical + if( r_showLines.GetInteger() == 1 || r_showLines.GetInteger() == 3 ) + { + for( int i = start ; i < tr.GetHeight() ; i += 2 ) + { + glScissor( 0, i, tr.GetWidth(), 1 ); + glClear( GL_COLOR_BUFFER_BIT ); + } + } + else + { + for( int i = start ; i < tr.GetWidth() ; i += 2 ) + { + glScissor( i, 0, 1, tr.GetHeight() ); + glClear( GL_COLOR_BUFFER_BIT ); + } + } +} + + +/* +================ +idRenderBackend::DBG_TestGamma +================ +*/ +#define G_WIDTH 512 +#define G_HEIGHT 512 +#define BAR_HEIGHT 64 + +void idRenderBackend::DBG_TestGamma() +{ + byte image[G_HEIGHT][G_WIDTH][4]; + int i, j; + int c, comp; + int v, dither; + int mask, y; + + if( r_testGamma.GetInteger() <= 0 ) + { + return; + } + + v = r_testGamma.GetInteger(); + if( v <= 1 || v >= 196 ) + { + v = 128; + } + + memset( image, 0, sizeof( image ) ); + + for( mask = 0; mask < 8; mask++ ) + { + y = mask * BAR_HEIGHT; + for( c = 0; c < 4; c++ ) + { + v = c * 64 + 32; + // solid color + for( i = 0; i < BAR_HEIGHT / 2; i++ ) + { + for( j = 0; j < G_WIDTH / 4; j++ ) + { + for( comp = 0; comp < 3; comp++ ) + { + if( mask & ( 1 << comp ) ) + { + image[y + i][c * G_WIDTH / 4 + j][comp] = v; + } + } + } + // dithered color + for( j = 0; j < G_WIDTH / 4; j++ ) + { + if( ( i ^ j ) & 1 ) + { + dither = c * 64; + } + else + { + dither = c * 64 + 63; + } + for( comp = 0; comp < 3; comp++ ) + { + if( mask & ( 1 << comp ) ) + { + image[y + BAR_HEIGHT / 2 + i][c * G_WIDTH / 4 + j][comp] = dither; + } + } + } + } + } + } + + // draw geometrically increasing steps in the bottom row + y = 0 * BAR_HEIGHT; + float scale = 1; + for( c = 0; c < 4; c++ ) + { + v = ( int )( 64 * scale ); + if( v < 0 ) + { + v = 0; + } + else if( v > 255 ) + { + v = 255; + } + scale = scale * 1.5; + for( i = 0; i < BAR_HEIGHT; i++ ) + { + for( j = 0; j < G_WIDTH / 4; j++ ) + { + image[y + i][c * G_WIDTH / 4 + j][0] = v; + image[y + i][c * G_WIDTH / 4 + j][1] = v; + image[y + i][c * G_WIDTH / 4 + j][2] = v; + } + } + } + + glLoadIdentity(); + + glMatrixMode( GL_PROJECTION ); + GL_State( GLS_DEPTHFUNC_ALWAYS ); + GL_Color( 1, 1, 1 ); + glPushMatrix(); + glLoadIdentity(); + glDisable( GL_TEXTURE_2D ); + glOrtho( 0, 1, 0, 1, -1, 1 ); + glRasterPos2f( 0.01f, 0.01f ); + glDrawPixels( G_WIDTH, G_HEIGHT, GL_RGBA, GL_UNSIGNED_BYTE, image ); + glPopMatrix(); + glEnable( GL_TEXTURE_2D ); + glMatrixMode( GL_MODELVIEW ); +} + + +/* +================== +idRenderBackend::DBG_TestGammaBias +================== +*/ +void idRenderBackend::DBG_TestGammaBias() +{ + byte image[G_HEIGHT][G_WIDTH][4]; + + if( r_testGammaBias.GetInteger() <= 0 ) + { + return; + } + + int y = 0; + for( int bias = -40; bias < 40; bias += 10, y += BAR_HEIGHT ) + { + float scale = 1; + for( int c = 0; c < 4; c++ ) + { + int v = ( int )( 64 * scale + bias ); + scale = scale * 1.5; + if( v < 0 ) + { + v = 0; + } + else if( v > 255 ) + { + v = 255; + } + for( int i = 0; i < BAR_HEIGHT; i++ ) + { + for( int j = 0; j < G_WIDTH / 4; j++ ) + { + image[y + i][c * G_WIDTH / 4 + j][0] = v; + image[y + i][c * G_WIDTH / 4 + j][1] = v; + image[y + i][c * G_WIDTH / 4 + j][2] = v; + } + } + } + } + + glLoadIdentity(); + glMatrixMode( GL_PROJECTION ); + GL_State( GLS_DEPTHFUNC_ALWAYS ); + GL_Color( 1, 1, 1 ); + glPushMatrix(); + glLoadIdentity(); + glDisable( GL_TEXTURE_2D ); + glOrtho( 0, 1, 0, 1, -1, 1 ); + glRasterPos2f( 0.01f, 0.01f ); + glDrawPixels( G_WIDTH, G_HEIGHT, GL_RGBA, GL_UNSIGNED_BYTE, image ); + glPopMatrix(); + glEnable( GL_TEXTURE_2D ); + glMatrixMode( GL_MODELVIEW ); +} + +/* +================ +idRenderBackend::DBG_TestImage + +Display a single image over most of the screen +================ +*/ +void idRenderBackend::DBG_TestImage() +{ + idImage* image = NULL; + idImage* imageCr = NULL; + idImage* imageCb = NULL; + int max; + float w, h; + + image = tr.testImage; + if( !image ) + { + return; + } + + if( tr.testVideo ) + { + cinData_t cin; + + cin = tr.testVideo->ImageForTime( viewDef->renderView.time[1] - tr.testVideoStartTime ); + if( cin.imageY != NULL ) + { + image = cin.imageY; + imageCr = cin.imageCr; + imageCb = cin.imageCb; + } + else + { + tr.testImage = NULL; + return; + } + w = 0.25; + h = 0.25; + } + else + { + max = image->GetUploadWidth() > image->GetUploadHeight() ? image->GetUploadWidth() : image->GetUploadHeight(); + + w = 0.25 * image->GetUploadWidth() / max; + h = 0.25 * image->GetUploadHeight() / max; + + w *= ( float )renderSystem->GetHeight() / renderSystem->GetWidth(); + } + + // Set State + GL_State( GLS_DEPTHFUNC_ALWAYS | GLS_SRCBLEND_ONE | GLS_DSTBLEND_ZERO ); + + // Set Parms + float texS[4] = { 1.0f, 0.0f, 0.0f, 0.0f }; + float texT[4] = { 0.0f, 1.0f, 0.0f, 0.0f }; + renderProgManager.SetRenderParm( RENDERPARM_TEXTUREMATRIX_S, texS ); + renderProgManager.SetRenderParm( RENDERPARM_TEXTUREMATRIX_T, texT ); + + float texGenEnabled[4] = { 0, 0, 0, 0 }; + renderProgManager.SetRenderParm( RENDERPARM_TEXGEN_0_ENABLED, texGenEnabled ); + + // not really necessary but just for clarity + const float screenWidth = 1.0f; + const float screenHeight = 1.0f; + const float halfScreenWidth = screenWidth * 0.5f; + const float halfScreenHeight = screenHeight * 0.5f; + + float scale[16] = { 0 }; + scale[0] = w; // scale + scale[5] = h; // scale + scale[12] = halfScreenWidth - ( halfScreenWidth * w ); // translate + scale[13] = halfScreenHeight - ( halfScreenHeight * h ); // translate + scale[10] = 1.0f; + scale[15] = 1.0f; + + float ortho[16] = { 0 }; + ortho[0] = 2.0f / screenWidth; + ortho[5] = -2.0f / screenHeight; + ortho[10] = -2.0f; + ortho[12] = -1.0f; + ortho[13] = 1.0f; + ortho[14] = -1.0f; + ortho[15] = 1.0f; + + float finalOrtho[16]; + R_MatrixMultiply( scale, ortho, finalOrtho ); + + float projMatrixTranspose[16]; + R_MatrixTranspose( finalOrtho, projMatrixTranspose ); + renderProgManager.SetRenderParms( RENDERPARM_MVPMATRIX_X, projMatrixTranspose, 4 ); + +// glMatrixMode( GL_PROJECTION ); +// glLoadMatrixf( finalOrtho ); +// glMatrixMode( GL_MODELVIEW ); +// glLoadIdentity(); + + // Set Color + GL_Color( 1, 1, 1, 1 ); + + // Bind the Texture + if( ( imageCr != NULL ) && ( imageCb != NULL ) ) + { + GL_SelectTexture( 0 ); + image->Bind(); + GL_SelectTexture( 1 ); + imageCr->Bind(); + GL_SelectTexture( 2 ); + imageCb->Bind(); + renderProgManager.BindShader_Bink(); + } + else + { + GL_SelectTexture( 0 ); + image->Bind(); + // Set Shader + renderProgManager.BindShader_Texture(); + } + + // Draw! + DrawElementsWithCounters( &testImageSurface ); +} + +// RB begin +void idRenderBackend::DBG_ShowShadowMaps() +{ + idImage* image = NULL; + int max; + float w, h; + + if( !r_showShadowMaps.GetBool() ) + return; + + image = globalImages->shadowImage[0]; + if( !image ) + { + return; + } + + // Set State + GL_State( GLS_DEPTHFUNC_ALWAYS | GLS_SRCBLEND_ONE | GLS_DSTBLEND_ZERO ); + + // Set Parms + float texS[4] = { 1.0f, 0.0f, 0.0f, 0.0f }; + float texT[4] = { 0.0f, 1.0f, 0.0f, 0.0f }; + renderProgManager.SetRenderParm( RENDERPARM_TEXTUREMATRIX_S, texS ); + renderProgManager.SetRenderParm( RENDERPARM_TEXTUREMATRIX_T, texT ); + + float texGenEnabled[4] = { 0, 0, 0, 0 }; + renderProgManager.SetRenderParm( RENDERPARM_TEXGEN_0_ENABLED, texGenEnabled ); + + for( int i = 0; i < ( r_shadowMapSplits.GetInteger() + 1 ); i++ ) + { + max = image->GetUploadWidth() > image->GetUploadHeight() ? image->GetUploadWidth() : image->GetUploadHeight(); + + w = 0.25 * image->GetUploadWidth() / max; + h = 0.25 * image->GetUploadHeight() / max; + + w *= ( float )renderSystem->GetHeight() / renderSystem->GetWidth(); + + // not really necessary but just for clarity + const float screenWidth = 1.0f; + const float screenHeight = 1.0f; + const float halfScreenWidth = screenWidth * 0.5f; + const float halfScreenHeight = screenHeight * 0.5f; + + float scale[16] = { 0 }; + scale[0] = w; // scale + scale[5] = h; // scale + scale[12] = ( halfScreenWidth * w * 2.1f * i ); // translate + scale[13] = halfScreenHeight + ( halfScreenHeight * h ); // translate + scale[10] = 1.0f; + scale[15] = 1.0f; + + float ortho[16] = { 0 }; + ortho[0] = 2.0f / screenWidth; + ortho[5] = -2.0f / screenHeight; + ortho[10] = -2.0f; + ortho[12] = -1.0f; + ortho[13] = 1.0f; + ortho[14] = -1.0f; + ortho[15] = 1.0f; + + float finalOrtho[16]; + R_MatrixMultiply( scale, ortho, finalOrtho ); + + float projMatrixTranspose[16]; + R_MatrixTranspose( finalOrtho, projMatrixTranspose ); + renderProgManager.SetRenderParms( RENDERPARM_MVPMATRIX_X, projMatrixTranspose, 4 ); + + float screenCorrectionParm[4]; + screenCorrectionParm[0] = i; + screenCorrectionParm[1] = 0.0f; + screenCorrectionParm[2] = 0.0f; + screenCorrectionParm[3] = 1.0f; + renderProgManager.SetRenderParm( RENDERPARM_SCREENCORRECTIONFACTOR, screenCorrectionParm ); // rpScreenCorrectionFactor + + // glMatrixMode( GL_PROJECTION ); + // glLoadMatrixf( finalOrtho ); + // glMatrixMode( GL_MODELVIEW ); + // glLoadIdentity(); + + // Set Color + GL_Color( 1, 1, 1, 1 ); + + GL_SelectTexture( 0 ); + image->Bind(); + glTexParameteri( GL_TEXTURE_2D_ARRAY, GL_TEXTURE_COMPARE_MODE, GL_NONE ); + + + renderProgManager.BindShader_DebugShadowMap(); + + DrawElementsWithCounters( &testImageSurface ); + } + + glTexParameteri( GL_TEXTURE_2D_ARRAY, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_R_TO_TEXTURE ); +} +// RB end + +/* +================= +RB_DrawExpandedTriangles +================= +*/ +static void RB_DrawExpandedTriangles( const srfTriangles_t* tri, const float radius, const idVec3& vieworg ) +{ + int i, j, k; + idVec3 dir[6], normal, point; + + for( i = 0; i < tri->numIndexes; i += 3 ) + { + + idVec3 p[3] = { tri->verts[ tri->indexes[ i + 0 ] ].xyz, tri->verts[ tri->indexes[ i + 1 ] ].xyz, tri->verts[ tri->indexes[ i + 2 ] ].xyz }; + + dir[0] = p[0] - p[1]; + dir[1] = p[1] - p[2]; + dir[2] = p[2] - p[0]; + + normal = dir[0].Cross( dir[1] ); + + if( normal * p[0] < normal * vieworg ) + { + continue; + } + + dir[0] = normal.Cross( dir[0] ); + dir[1] = normal.Cross( dir[1] ); + dir[2] = normal.Cross( dir[2] ); + + dir[0].Normalize(); + dir[1].Normalize(); + dir[2].Normalize(); + + glBegin( GL_LINE_LOOP ); + + for( j = 0; j < 3; j++ ) + { + k = ( j + 1 ) % 3; + + dir[4] = ( dir[j] + dir[k] ) * 0.5f; + dir[4].Normalize(); + + dir[3] = ( dir[j] + dir[4] ) * 0.5f; + dir[3].Normalize(); + + dir[5] = ( dir[4] + dir[k] ) * 0.5f; + dir[5].Normalize(); + + point = p[k] + dir[j] * radius; + glVertex3f( point[0], point[1], point[2] ); + + point = p[k] + dir[3] * radius; + glVertex3f( point[0], point[1], point[2] ); + + point = p[k] + dir[4] * radius; + glVertex3f( point[0], point[1], point[2] ); + + point = p[k] + dir[5] * radius; + glVertex3f( point[0], point[1], point[2] ); + + point = p[k] + dir[k] * radius; + glVertex3f( point[0], point[1], point[2] ); + } + + glEnd(); + } +} + +/* +================ +idRenderBackend::DBG_ShowTrace + +Debug visualization + +FIXME: not thread safe! +================ +*/ +void idRenderBackend::DBG_ShowTrace( drawSurf_t** drawSurfs, int numDrawSurfs ) +{ + int i; + const srfTriangles_t* tri; + const drawSurf_t* surf; + idVec3 start, end; + idVec3 localStart, localEnd; + localTrace_t hit; + float radius; + + if( r_showTrace.GetInteger() == 0 ) + { + return; + } + + if( r_showTrace.GetInteger() == 2 ) + { + radius = 5.0f; + } + else + { + radius = 0.0f; + } + + // determine the points of the trace + start = viewDef->renderView.vieworg; + end = start + 4000 * viewDef->renderView.viewaxis[0]; + + // check and draw the surfaces + globalImages->whiteImage->Bind(); + + // find how many are ambient + for( i = 0; i < numDrawSurfs; i++ ) + { + surf = drawSurfs[i]; + tri = surf->frontEndGeo; + + if( tri == NULL || tri->verts == NULL ) + { + continue; + } + + // transform the points into local space + R_GlobalPointToLocal( surf->space->modelMatrix, start, localStart ); + R_GlobalPointToLocal( surf->space->modelMatrix, end, localEnd ); + + // check the bounding box + if( !tri->bounds.Expand( radius ).LineIntersection( localStart, localEnd ) ) + { + continue; + } + + glLoadMatrixf( surf->space->modelViewMatrix ); + + // highlight the surface + GL_State( GLS_SRCBLEND_SRC_ALPHA | GLS_DSTBLEND_ONE_MINUS_SRC_ALPHA ); + + GL_Color( 1, 0, 0, 0.25 ); + DrawElementsWithCounters( surf ); + + // draw the bounding box + GL_State( GLS_DEPTHFUNC_ALWAYS ); + + GL_Color( 1, 1, 1, 1 ); + RB_DrawBounds( tri->bounds ); + + if( radius != 0.0f ) + { + // draw the expanded triangles + GL_Color( 0.5f, 0.5f, 1.0f, 1.0f ); + RB_DrawExpandedTriangles( tri, radius, localStart ); + } + + // check the exact surfaces + hit = R_LocalTrace( localStart, localEnd, radius, tri ); + if( hit.fraction < 1.0 ) + { + GL_Color( 1, 1, 1, 1 ); + RB_DrawBounds( idBounds( hit.point ).Expand( 1 ) ); + } + } +} + +/* +================= +idRenderBackend::DBG_RenderDebugTools +================= +*/ +void idRenderBackend::DBG_RenderDebugTools( drawSurf_t** drawSurfs, int numDrawSurfs ) +{ + // don't do much if this was a 2D rendering + if( !viewDef->viewEntitys ) + { + DBG_TestImage(); + DBG_ShowLines(); + return; + } + + renderLog.OpenMainBlock( MRB_DRAW_DEBUG_TOOLS ); + RENDERLOG_PRINTF( "---------- RB_RenderDebugTools ----------\n" ); + + GL_State( GLS_DEFAULT ); + + GL_Scissor( viewDef->viewport.x1 + viewDef->scissor.x1, + viewDef->viewport.y1 + viewDef->scissor.y1, + viewDef->scissor.x2 + 1 - viewDef->scissor.x1, + viewDef->scissor.y2 + 1 - viewDef->scissor.y1 ); + + currentScissor = viewDef->scissor; + + DBG_ShowLightCount(); + DBG_ShowTexturePolarity( drawSurfs, numDrawSurfs ); + DBG_ShowTangentSpace( drawSurfs, numDrawSurfs ); + DBG_ShowVertexColor( drawSurfs, numDrawSurfs ); + DBG_ShowTris( drawSurfs, numDrawSurfs ); + DBG_ShowUnsmoothedTangents( drawSurfs, numDrawSurfs ); + DBG_ShowSurfaceInfo( drawSurfs, numDrawSurfs ); + DBG_ShowEdges( drawSurfs, numDrawSurfs ); + DBG_ShowNormals( drawSurfs, numDrawSurfs ); + DBG_ShowViewEntitys( viewDef->viewEntitys ); + DBG_ShowLights(); + // RB begin + DBG_ShowShadowMapLODs(); + DBG_ShowShadowMaps(); + // RB end + + DBG_ShowTextureVectors( drawSurfs, numDrawSurfs ); + DBG_ShowDominantTris( drawSurfs, numDrawSurfs ); + if( r_testGamma.GetInteger() > 0 ) // test here so stack check isn't so damn slow on debug builds + { + DBG_TestGamma(); + } + if( r_testGammaBias.GetInteger() > 0 ) + { + DBG_TestGammaBias(); + } + DBG_TestImage(); + DBG_ShowPortals(); + DBG_ShowSilhouette(); + DBG_ShowDepthBuffer(); + DBG_ShowIntensity(); + DBG_ShowCenterOfProjection(); + DBG_ShowLines(); + DBG_ShowDebugLines(); + DBG_ShowDebugText(); + DBG_ShowDebugPolygons(); + DBG_ShowTrace( drawSurfs, numDrawSurfs ); + + renderLog.CloseMainBlock(); +} + +/* +================= +RB_ShutdownDebugTools +================= +*/ +void RB_ShutdownDebugTools() +{ + for( int i = 0; i < MAX_DEBUG_POLYGONS; i++ ) + { + rb_debugPolygons[i].winding.Clear(); + } +} From 38bcf14c7ba814810c85bc0356aa99bd79359b7d Mon Sep 17 00:00:00 2001 From: Robert Beckebans Date: Sun, 10 Sep 2017 15:27:31 +0200 Subject: [PATCH 11/12] killed globalImages->BindNull(). More cleanups from vkneo --- neo/framework/Common.cpp | 11 - neo/renderer/GuiModel.h | 23 +- neo/renderer/Image.h | 12 +- neo/renderer/ImageManager.cpp | 164 ++------- neo/renderer/Image_load.cpp | 473 ++++++++++++------------- neo/renderer/Image_program.cpp | 9 +- neo/renderer/OpenGL/RenderDebug_GL.cpp | 33 +- neo/renderer/RenderBackend.cpp | 69 +--- neo/tools/compilers/dmap/dmap.cpp | 2 +- 9 files changed, 284 insertions(+), 512 deletions(-) diff --git a/neo/framework/Common.cpp b/neo/framework/Common.cpp index 1156e25c..6a247fd2 100644 --- a/neo/framework/Common.cpp +++ b/neo/framework/Common.cpp @@ -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 ) ); } /* diff --git a/neo/renderer/GuiModel.h b/neo/renderer/GuiModel.h index 12933a1f..97f3a190 100644 --- a/neo/renderer/GuiModel.h +++ b/neo/renderer/GuiModel.h @@ -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 surfaces; }; diff --git a/neo/renderer/Image.h b/neo/renderer/Image.h index 4c866715..f5e8a838 100644 --- a/neo/renderer/Image.h +++ b/neo/renderer/Image.h @@ -3,7 +3,7 @@ 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"). @@ -311,7 +311,6 @@ public: // Platform specific implementations //--------------------------------------------- - #if defined( ID_VULKAN ) void CreateFromSwapImage( VkImage image, VkImageView imageView, VkFormat format, const VkExtent2D& extent ); VkImage GetImage() const @@ -497,9 +496,6 @@ public: // reloads all apropriate images after a vid_restart void ReloadImages( bool all ); - // disable the active texture unit - void BindNull(); - // Called only by renderSystem::BeginLevelLoad void BeginLevelLoad(); @@ -511,10 +507,6 @@ 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 @@ -577,8 +569,6 @@ public: extern idImageManager* globalImages; // pointer to global list for the rest of the system -int MakePowerOfTwo( int num ); - /* ==================================================================== diff --git a/neo/renderer/ImageManager.cpp b/neo/renderer/ImageManager.cpp index 25bd1dd6..53975205 100644 --- a/neo/renderer/ImageManager.cpp +++ b/neo/renderer/ImageManager.cpp @@ -63,7 +63,7 @@ void R_ReloadImages_f( const idCmdArgs& args ) } else { - common->Printf( "USAGE: reloadImages \n" ); + idLib::Printf( "USAGE: reloadImages \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 \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 \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,25 +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 ); } - - -/* -=============== -BindNull -=============== -*/ -void idImageManager::BindNull() -{ - RENDERLOG_PRINTF( "BindNull()\n" ); - -} - /* =============== Init @@ -856,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; @@ -873,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; } } @@ -918,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 diff --git a/neo/renderer/Image_load.cpp b/neo/renderer/Image_load.cpp index a8a1e42b..ac08111b 100644 --- a/neo/renderer/Image_load.cpp +++ b/neo/renderer/Image_load.cpp @@ -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"). @@ -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.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 - /* =============== 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,80 +492,6 @@ void idImage::ActuallyLoadImage( bool fromBackEnd ) } } - - -/* -================ -MakePowerOfTwo -================ -*/ -int MakePowerOfTwo( int num ) -{ - int pot; - for( pot = 1; pot < num; pot <<= 1 ) - { - } - return pot; -} - - - -/* -============= -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 @@ -924,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 ); + } +} \ No newline at end of file diff --git a/neo/renderer/Image_program.cpp b/neo/renderer/Image_program.cpp index c2c44d33..b85e1f9e 100644 --- a/neo/renderer/Image_program.cpp +++ b/neo/renderer/Image_program.cpp @@ -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; diff --git a/neo/renderer/OpenGL/RenderDebug_GL.cpp b/neo/renderer/OpenGL/RenderDebug_GL.cpp index 4f18a889..4f92452d 100644 --- a/neo/renderer/OpenGL/RenderDebug_GL.cpp +++ b/neo/renderer/OpenGL/RenderDebug_GL.cpp @@ -440,7 +440,6 @@ void idRenderBackend::DBG_ShowIntensity() glRasterPos2f( 0, 0 ); glPopMatrix(); GL_Color( 1, 1, 1 ); - globalImages->BindNull(); glMatrixMode( GL_MODELVIEW ); glDrawPixels( renderSystem->GetWidth(), renderSystem->GetHeight(), GL_RGBA , GL_UNSIGNED_BYTE, colorReadback ); @@ -478,7 +477,6 @@ void idRenderBackend::DBG_ShowDepthBuffer() GL_State( GLS_DEPTHFUNC_ALWAYS ); GL_Color( 1, 1, 1 ); - globalImages->BindNull(); depthReadback = R_StaticAlloc( renderSystem->GetWidth() * renderSystem->GetHeight() * 4, TAG_RENDER_TOOLS ); memset( depthReadback, 0, renderSystem->GetWidth() * renderSystem->GetHeight() * 4 ); @@ -677,16 +675,12 @@ void idRenderBackend::DBG_ShowSilhouette() } // clear all triangle edges to black - globalImages->BindNull(); - // RB begin + // RB renderProgManager.BindShader_Color(); - // RB end GL_Color( 0, 0, 0 ); - GL_State( GLS_DEPTHFUNC_ALWAYS | GLS_POLYMODE_LINE ); - GL_Cull( CT_TWO_SIDED ); DBG_RenderDrawSurfListWithFunction( viewDef->drawSurfs, viewDef->numDrawSurfs ); @@ -925,8 +919,6 @@ void idRenderBackend::DBG_ShowViewEntitys( viewEntity_t* vModels ) common->Printf( "\n" ); } - globalImages->BindNull(); - renderProgManager.BindShader_Color(); GL_Color( 1, 1, 1 ); @@ -1009,7 +1001,6 @@ void idRenderBackend::DBG_ShowTexturePolarity( drawSurf_t** drawSurfs, int numDr { return; } - globalImages->BindNull(); GL_State( GLS_SRCBLEND_SRC_ALPHA | GLS_DSTBLEND_ONE_MINUS_SRC_ALPHA ); @@ -1088,7 +1079,6 @@ void idRenderBackend::DBG_ShowUnsmoothedTangents( drawSurf_t** drawSurfs, int nu { return; } - globalImages->BindNull(); GL_State( GLS_SRCBLEND_SRC_ALPHA | GLS_DSTBLEND_ONE_MINUS_SRC_ALPHA ); @@ -1150,7 +1140,6 @@ void idRenderBackend::DBG_ShowTangentSpace( drawSurf_t** drawSurfs, int numDrawS { return; } - globalImages->BindNull(); GL_State( GLS_SRCBLEND_SRC_ALPHA | GLS_DSTBLEND_ONE_MINUS_SRC_ALPHA ); @@ -1216,7 +1205,6 @@ void idRenderBackend::DBG_ShowVertexColor( drawSurf_t** drawSurfs, int numDrawSu { return; } - globalImages->BindNull(); // RB begin renderProgManager.BindShader_VertexColor(); @@ -1276,8 +1264,6 @@ void idRenderBackend::DBG_ShowNormals( drawSurf_t** drawSurfs, int numDrawSurfs return; } - globalImages->BindNull(); - if( !r_debugLineDepthTest.GetBool() ) { GL_State( GLS_POLYMODE_LINE | GLS_DEPTHFUNC_ALWAYS ); @@ -1387,8 +1373,6 @@ void idRenderBackend::DBG_ShowTextureVectors( drawSurf_t** drawSurfs, int numDra GL_State( GLS_DEPTHFUNC_LESS ); - globalImages->BindNull(); - for( int i = 0; i < numDrawSurfs; i++ ) { drawSurf_t* drawSurf = drawSurfs[i]; @@ -1496,8 +1480,6 @@ void idRenderBackend::DBG_ShowDominantTris( drawSurf_t** drawSurfs, int numDrawS GL_PolygonOffset( -1, -2 ); glEnable( GL_POLYGON_OFFSET_LINE ); - globalImages->BindNull(); - for( i = 0; i < numDrawSurfs; i++ ) { drawSurf = drawSurfs[i]; @@ -1560,8 +1542,6 @@ void idRenderBackend::DBG_ShowEdges( drawSurf_t** drawSurfs, int numDrawSurfs ) return; } - globalImages->BindNull(); - GL_State( GLS_DEPTHFUNC_ALWAYS ); for( i = 0; i < numDrawSurfs; i++ ) @@ -1668,8 +1648,6 @@ void idRenderBackend::DBG_ShowLights() GL_State( GLS_DEFAULT ); - globalImages->BindNull(); - renderProgManager.BindShader_Color(); GL_Cull( CT_TWO_SIDED ); @@ -1734,8 +1712,6 @@ void idRenderBackend::DBG_ShowShadowMapLODs() GL_State( GLS_DEFAULT ); - globalImages->BindNull(); - renderProgManager.BindShader_Color(); GL_Cull( CT_TWO_SIDED ); @@ -1831,7 +1807,6 @@ void idRenderBackend::DBG_ShowPortals() // all portals are expressed in world coordinates DBG_SimpleWorldSetup(); - globalImages->BindNull(); renderProgManager.BindShader_Color(); GL_State( GLS_DEPTHFUNC_ALWAYS ); @@ -2113,8 +2088,6 @@ void idRenderBackend::DBG_ShowDebugText() // all lines are expressed in world coordinates DBG_SimpleWorldSetup(); - globalImages->BindNull(); - width = r_debugLineWidth.GetInteger(); if( width < 1 ) { @@ -2246,8 +2219,6 @@ void idRenderBackend::DBG_ShowDebugLines() renderProgManager.CommitUniforms(); // RB end - globalImages->BindNull(); - width = r_debugLineWidth.GetInteger(); if( width < 1 ) { @@ -2387,8 +2358,6 @@ void idRenderBackend::DBG_ShowDebugPolygons() renderProgManager.CommitUniforms(); // RB end - globalImages->BindNull(); - if( r_debugPolygonFilled.GetBool() ) { GL_State( GLS_POLYGON_OFFSET | GLS_SRCBLEND_SRC_ALPHA | GLS_DSTBLEND_ONE_MINUS_SRC_ALPHA | GLS_DEPTHMASK ); diff --git a/neo/renderer/RenderBackend.cpp b/neo/renderer/RenderBackend.cpp index 1510e1fe..219a7d58 100644 --- a/neo/renderer/RenderBackend.cpp +++ b/neo/renderer/RenderBackend.cpp @@ -795,10 +795,6 @@ void idRenderBackend::FinishStageTexturing( const shaderStage_t* pStage, const d if( pStage->texture.cinematic ) { // unbind the extra bink textures - GL_SelectTexture( 1 ); - globalImages->BindNull(); - GL_SelectTexture( 2 ); - globalImages->BindNull(); GL_SelectTexture( 0 ); } @@ -809,8 +805,6 @@ void idRenderBackend::FinishStageTexturing( const shaderStage_t* pStage, const d if( bumpStage != NULL ) { // per-pixel reflection mapping with bump mapping - GL_SelectTexture( 1 ); - globalImages->BindNull(); GL_SelectTexture( 0 ); } else @@ -2280,10 +2274,10 @@ void idRenderBackend::AmbientPass( const drawSurf_t* const* drawSurfs, int numDr renderLog.CloseBlock(); renderLog.CloseMainBlock(); + GL_SelectTexture( 0 ); + if( fillGbuffer ) { - GL_SelectTexture( 0 ); - // FIXME: this copies RGBA16F into _currentNormals if HDR is enabled const idScreenRect& viewport = viewDef->viewport; globalImages->currentNormalsImage->CopyFramebuffer( viewport.x1, viewport.y1, viewport.GetWidth(), viewport.GetHeight() ); @@ -2303,13 +2297,6 @@ void idRenderBackend::AmbientPass( const drawSurf_t* const* drawSurfs, int numDr */ } - // unbind texture units - for( int i = 0; i < 7; i++ ) - { - GL_SelectTexture( i ); - globalImages->BindNull(); - } - renderProgManager.Unbind(); } @@ -2347,7 +2334,6 @@ void idRenderBackend::StencilShadowPass( const drawSurf_t* drawSurfs, const view renderProgManager.BindShader_Shadow(); GL_SelectTexture( 0 ); - globalImages->BindNull(); uint64 glState = 0; @@ -2870,7 +2856,6 @@ void idRenderBackend::ShadowMapPass( const drawSurf_t* drawSurfs, const viewLigh renderProgManager.BindShader_Depth(); GL_SelectTexture( 0 ); - globalImages->BindNull(); uint64 glState = 0; @@ -3619,11 +3604,6 @@ void idRenderBackend::DrawInteractions( const viewDef_t* _viewDef ) GL_State( GLS_DEFAULT ); // unbind texture units - for( int i = 0; i < 7; i++ ) - { - GL_SelectTexture( i ); - globalImages->BindNull(); - } GL_SelectTexture( 0 ); // reset depth bounds @@ -3665,9 +3645,6 @@ int idRenderBackend::DrawShaderPasses( const drawSurf_t* const* const drawSurfs, renderLog.OpenBlock( "RB_DrawShaderPasses" ); - GL_SelectTexture( 1 ); - globalImages->BindNull(); - GL_SelectTexture( 0 ); currentSpace = ( const viewEntity_t* )1; // using NULL makes /analyze think surf->space needs to be checked... @@ -3879,17 +3856,6 @@ int idRenderBackend::DrawShaderPasses( const drawSurf_t* const* const drawSurfs, // draw it DrawElementsWithCounters( surf ); - // unbind texture units - for( int j = 0; j < newStage->numFragmentProgramImages; j++ ) - { - idImage* image = newStage->fragmentProgramImages[j]; - if( image != NULL ) - { - GL_SelectTexture( j ); - globalImages->BindNull(); - } - } - // clear rpEnableSkinning if it was set if( surf->jointCache && renderProgManager.ShaderHasOptionalSkinning() ) { @@ -4043,12 +4009,6 @@ int idRenderBackend::DrawShaderPasses( const drawSurf_t* const* const drawSurfs, // disable stencil shadow test GL_State( GLS_DEFAULT ); - // unbind texture units - for( int i = 0; i < 7; i++ ) - { - GL_SelectTexture( i ); - globalImages->BindNull(); - } GL_SelectTexture( 0 ); renderLog.CloseBlock(); @@ -4178,9 +4138,6 @@ void idRenderBackend::BlendLight( const drawSurf_t* drawSurfs, const drawSurf_t* T_BlendLight( drawSurfs2, vLight ); } - GL_SelectTexture( 1 ); - globalImages->BindNull(); - GL_SelectTexture( 0 ); renderProgManager.Unbind(); @@ -4358,9 +4315,6 @@ void idRenderBackend::FogPass( const drawSurf_t* drawSurfs, const drawSurf_t* d GL_Cull( CT_FRONT_SIDED ); - GL_SelectTexture( 1 ); - globalImages->BindNull(); - GL_SelectTexture( 0 ); renderProgManager.Unbind(); @@ -4611,13 +4565,7 @@ void idRenderBackend::Tonemap( const viewDef_t* _viewDef ) // Draw DrawElementsWithCounters( &unitSquareSurface ); - // unbind heatmap - globalImages->BindNull(); - - // unbind _currentRender GL_SelectTexture( 0 ); - globalImages->BindNull(); - renderProgManager.Unbind(); GL_State( GLS_DEFAULT ); @@ -4741,9 +4689,6 @@ void idRenderBackend::Bloom( const viewDef_t* _viewDef ) DrawElementsWithCounters( &unitSquareSurface ); - globalImages->BindNull(); - - Framebuffer::Unbind(); renderProgManager.Unbind(); GL_State( GLS_DEFAULT ); @@ -5944,8 +5889,6 @@ void idRenderBackend::PostProcess( const void* data ) #endif #if 1 - globalImages->BindNull(); - //GL_SelectTexture( 0 ); //globalImages->smaaBlendImage->CopyFramebuffer( viewport.x1, viewport.y1, viewport.GetWidth(), viewport.GetHeight() ); @@ -6003,15 +5946,7 @@ void idRenderBackend::PostProcess( const void* data ) } #endif - GL_SelectTexture( 2 ); - globalImages->BindNull(); - - GL_SelectTexture( 1 ); - globalImages->BindNull(); - GL_SelectTexture( 0 ); - globalImages->BindNull(); - renderProgManager.Unbind(); renderLog.CloseBlock(); diff --git a/neo/tools/compilers/dmap/dmap.cpp b/neo/tools/compilers/dmap/dmap.cpp index 1cb2099b..9eef3e32 100644 --- a/neo/tools/compilers/dmap/dmap.cpp +++ b/neo/tools/compilers/dmap/dmap.cpp @@ -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 From 5c4764197a46447b43e749feae52fb34af70d2e2 Mon Sep 17 00:00:00 2001 From: Robert Beckebans Date: Sun, 10 Sep 2017 17:28:27 +0200 Subject: [PATCH 12/12] com_smp -1 mode for RenderDoc debugging --- neo/framework/common_frame.cpp | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/neo/framework/common_frame.cpp b/neo/framework/common_frame.cpp index 8d66c7db..c9b11c8e 100644 --- a/neo/framework/common_frame.cpp +++ b/neo/framework/common_frame.cpp @@ -64,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, "" ); @@ -194,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(); @@ -554,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 @@ -778,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