AutoRender.cpp (8016B)
1 /* 2 =========================================================================== 3 4 Doom 3 BFG Edition GPL Source Code 5 Copyright (C) 1993-2012 id Software LLC, a ZeniMax Media company. 6 7 This file is part of the Doom 3 BFG Edition GPL Source Code ("Doom 3 BFG Edition Source Code"). 8 9 Doom 3 BFG Edition Source Code is free software: you can redistribute it and/or modify 10 it under the terms of the GNU General Public License as published by 11 the Free Software Foundation, either version 3 of the License, or 12 (at your option) any later version. 13 14 Doom 3 BFG Edition Source Code is distributed in the hope that it will be useful, 15 but WITHOUT ANY WARRANTY; without even the implied warranty of 16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 GNU General Public License for more details. 18 19 You should have received a copy of the GNU General Public License 20 along with Doom 3 BFG Edition Source Code. If not, see <http://www.gnu.org/licenses/>. 21 22 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. 23 24 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. 25 26 =========================================================================== 27 */ 28 #pragma hdrstop 29 #include "../idlib/precompiled.h" 30 #include "tr_local.h" 31 32 const int AUTO_RENDER_STACK_SIZE = 256 * 1024; 33 34 idAutoRender rAutoRender; 35 36 /* 37 ============================ 38 idAutoRender::idAutoRender 39 ============================ 40 */ 41 idAutoRender::idAutoRender() { 42 nextRotateTime = 0.0f; 43 currentRotation = 0.0f; 44 autoRenderIcon = AUTORENDER_DEFAULTICON; 45 } 46 47 /* 48 ============================ 49 idAutoRender::Run 50 ============================ 51 */ 52 int idAutoRender::Run() { 53 while ( !IsTerminating() ) { 54 RenderFrame(); 55 } 56 57 58 return 0; 59 } 60 61 /* 62 ============================ 63 idAutoRender::StartBackgroundAutoSwaps 64 ============================ 65 */ 66 void idAutoRender::StartBackgroundAutoSwaps( autoRenderIconType_t iconType ) { 67 68 69 if ( IsRunning() ) { 70 EndBackgroundAutoSwaps(); 71 } 72 73 autoRenderIcon = iconType; 74 75 idLib::Printf("Starting Background AutoSwaps\n"); 76 77 const bool captureToImage = true; 78 common->UpdateScreen( captureToImage ); 79 80 // unbind any shaders prior to entering the background autoswaps so we don't run 81 // into any problems with cached vertex shader indices from the main thread 82 renderProgManager.Unbind(); 83 84 // unbind all texture units so we don't run into a race condition where the device is owned 85 // by the autorender thread but an image is trying to be unset from the main thread because 86 // it is getting purged before our our first frame has been rendered. 87 globalImages->UnbindAll(); 88 89 90 StartThread("BackgroundAutoSwaps", CORE_0B, THREAD_NORMAL, AUTO_RENDER_STACK_SIZE ); 91 } 92 93 /* 94 ============================ 95 idAutoRender::EndBackgroundAutoSwaps 96 ============================ 97 */ 98 void idAutoRender::EndBackgroundAutoSwaps() { 99 idLib::Printf("End Background AutoSwaps\n"); 100 101 StopThread(); 102 103 } 104 105 /* 106 ============================ 107 idAutoRender::RenderFrame 108 ============================ 109 */ 110 void idAutoRender::RenderFrame() { 111 // values are 0 to 1 112 float loadingIconPosX = 0.5f; 113 float loadingIconPosY = 0.6f; 114 float loadingIconScale = 0.025f; 115 float loadingIconSpeed = 0.095f; 116 117 if ( autoRenderIcon == AUTORENDER_HELLICON ) { 118 loadingIconPosX = 0.85f; 119 loadingIconPosY = 0.85f; 120 loadingIconScale = 0.1f; 121 loadingIconSpeed = 0.095f; 122 } else if ( autoRenderIcon == AUTORENDER_DIALOGICON ) { 123 loadingIconPosY = 0.73f; 124 } 125 126 127 GL_SetDefaultState(); 128 129 GL_Cull( CT_TWO_SIDED ); 130 131 const bool stereoRender = false; 132 133 const int width = renderSystem->GetWidth(); 134 const int height = renderSystem->GetHeight(); 135 const int guardBand = height / 24; 136 137 if ( stereoRender ) { 138 for ( int viewNum = 0 ; viewNum < 2; viewNum++ ) { 139 GL_ViewportAndScissor( 0, viewNum * ( height + guardBand ), width, height ); 140 RenderBackground(); 141 RenderLoadingIcon( loadingIconPosX, loadingIconPosY, loadingIconScale, loadingIconSpeed ); 142 } 143 } else { 144 GL_ViewportAndScissor( 0, 0, width, height ); 145 RenderBackground(); 146 RenderLoadingIcon( loadingIconPosX, loadingIconPosY, loadingIconScale, loadingIconSpeed ); 147 } 148 149 } 150 151 /* 152 ============================ 153 idAutoRender::RenderBackground 154 ============================ 155 */ 156 void idAutoRender::RenderBackground() { 157 GL_SelectTexture( 0 ); 158 159 globalImages->currentRenderImage->Bind(); 160 161 GL_State( GLS_DEPTHFUNC_ALWAYS | GLS_SRCBLEND_ONE | GLS_DSTBLEND_ZERO ); 162 163 float mvpMatrix[16] = { 0 }; 164 mvpMatrix[0] = 1; 165 mvpMatrix[5] = 1; 166 mvpMatrix[10] = 1; 167 mvpMatrix[15] = 1; 168 169 // Set Parms 170 float texS[4] = { 1.0f, 0.0f, 0.0f, 0.0f }; 171 float texT[4] = { 0.0f, 1.0f, 0.0f, 0.0f }; 172 renderProgManager.SetRenderParm( RENDERPARM_TEXTUREMATRIX_S, texS ); 173 renderProgManager.SetRenderParm( RENDERPARM_TEXTUREMATRIX_T, texT ); 174 175 // disable texgen 176 float texGenEnabled[4] = { 0, 0, 0, 0 }; 177 renderProgManager.SetRenderParm( RENDERPARM_TEXGEN_0_ENABLED, texGenEnabled ); 178 179 // set matrix 180 renderProgManager.SetRenderParms( RENDERPARM_MVPMATRIX_X, mvpMatrix, 4 ); 181 182 renderProgManager.BindShader_TextureVertexColor(); 183 184 RB_DrawElementsWithCounters( &backEnd.unitSquareSurface ); 185 } 186 187 /* 188 ============================ 189 idAutoRender::RenderLoadingIcon 190 ============================ 191 */ 192 void idAutoRender::RenderLoadingIcon( float fracX, float fracY, float size, float speed ) { 193 194 float s = 0.0f; 195 float c = 1.0f; 196 197 if ( autoRenderIcon != AUTORENDER_HELLICON ) { 198 if ( Sys_Milliseconds() >= nextRotateTime ) { 199 nextRotateTime = Sys_Milliseconds() + 100; 200 currentRotation -= 90.0f; 201 } 202 float angle = DEG2RAD( currentRotation ); 203 idMath::SinCos( angle, s, c ); 204 } 205 206 const float pixelAspect = renderSystem->GetPixelAspect(); 207 const float screenWidth = renderSystem->GetWidth(); 208 const float screenHeight = renderSystem->GetHeight(); 209 210 const float minSize = Min( screenWidth, screenHeight ); 211 if ( minSize <= 0.0f ) { 212 return; 213 } 214 215 float scaleX = size * minSize / screenWidth; 216 float scaleY = size * minSize / screenHeight; 217 218 float scale[16] = { 0 }; 219 scale[0] = c * scaleX / pixelAspect; 220 scale[1] = -s * scaleY; 221 scale[4] = s * scaleX / pixelAspect; 222 scale[5] = c * scaleY; 223 scale[10] = 1.0f; 224 scale[15] = 1.0f; 225 226 scale[12] = fracX; 227 scale[13] = fracY; 228 229 float ortho[16] = { 0 }; 230 ortho[0] = 2.0f; 231 ortho[5] = -2.0f; 232 ortho[10] = -2.0f; 233 ortho[12] = -1.0f; 234 ortho[13] = 1.0f; 235 ortho[14] = -1.0f; 236 ortho[15] = 1.0f; 237 238 float finalOrtho[16]; 239 R_MatrixMultiply( scale, ortho, finalOrtho ); 240 241 float projMatrixTranspose[16]; 242 R_MatrixTranspose( finalOrtho, projMatrixTranspose ); 243 renderProgManager.SetRenderParms( RENDERPARM_MVPMATRIX_X, projMatrixTranspose, 4 ); 244 245 float a = 1.0f; 246 if ( autoRenderIcon == AUTORENDER_HELLICON ) { 247 float alpha = DEG2RAD( Sys_Milliseconds() * speed ); 248 a = idMath::Sin( alpha ); 249 a = 0.35f + ( 0.65f * idMath::Fabs( a ) ); 250 } 251 252 GL_SelectTexture( 0 ); 253 254 if ( autoRenderIcon == AUTORENDER_HELLICON ) { 255 globalImages->hellLoadingIconImage->Bind(); 256 } else { 257 globalImages->loadingIconImage->Bind(); 258 } 259 260 GL_State( GLS_DEPTHFUNC_ALWAYS | GLS_SRCBLEND_SRC_ALPHA | GLS_DSTBLEND_ONE_MINUS_SRC_ALPHA ); 261 262 // Set Parms 263 float texS[4] = { 1.0f, 0.0f, 0.0f, 0.0f }; 264 float texT[4] = { 0.0f, 1.0f, 0.0f, 0.0f }; 265 renderProgManager.SetRenderParm( RENDERPARM_TEXTUREMATRIX_S, texS ); 266 renderProgManager.SetRenderParm( RENDERPARM_TEXTUREMATRIX_T, texT ); 267 268 if ( autoRenderIcon == AUTORENDER_HELLICON ) { 269 GL_Color( 1.0f, 1.0f, 1.0f, a ); 270 } 271 272 // disable texgen 273 float texGenEnabled[4] = { 0, 0, 0, 0 }; 274 renderProgManager.SetRenderParm( RENDERPARM_TEXGEN_0_ENABLED, texGenEnabled ); 275 276 renderProgManager.BindShader_TextureVertexColor(); 277 278 RB_DrawElementsWithCounters( &backEnd.unitSquareSurface ); 279 }