2004-08-22 22:29:09 +00:00
/*
Copyright ( C ) 1996 - 1997 Id Software , Inc .
This program is free software ; you can redistribute it and / or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation ; either version 2
of the License , or ( at your option ) any later version .
This program 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 this program ; if not , write to the Free Software
Foundation , Inc . , 59 Temple Place - Suite 330 , Boston , MA 02111 - 1307 , USA .
*/
// screen.c -- master for refresh, status bar, console, chat, notify, etc
# include "quakedef.h"
2009-11-04 21:16:50 +00:00
# ifdef GLQUAKE
2004-08-22 22:29:09 +00:00
# include "glquake.h"
2009-11-04 21:16:50 +00:00
# include "shader.h"
2010-05-01 22:47:47 +00:00
# include "gl_draw.h"
2004-08-22 22:29:09 +00:00
# include <time.h>
void GLSCR_UpdateScreen ( void ) ;
extern qboolean scr_drawdialog ;
2011-06-17 01:54:54 +00:00
extern cvar_t vid_triplebuffer ;
2004-08-22 22:29:09 +00:00
extern cvar_t scr_fov ;
extern qboolean scr_initialized ;
extern float oldsbar ;
extern qboolean scr_drawloading ;
extern int scr_chatmode ;
extern cvar_t scr_chatmodecvar ;
2009-03-03 01:52:30 +00:00
extern cvar_t vid_conautoscale ;
2009-11-04 21:16:50 +00:00
extern qboolean scr_con_forcedraw ;
2015-01-07 13:34:05 +00:00
extern qboolean depthcleared ;
2004-08-22 22:29:09 +00:00
/*
= = = = = = = = = = = = = = = = = =
SCR_UpdateScreen
This is called every frame , and can also be called explicitly to flush
text to the screen .
WARNING : be very careful calling this from elsewhere , because the refresh
needs almost the entire 256 k of stack space !
= = = = = = = = = = = = = = = = = =
*/
2015-02-02 08:01:53 +00:00
void SCR_DrawCursor ( void ) ;
2004-08-22 22:29:09 +00:00
void GLSCR_UpdateScreen ( void )
{
int uimenu ;
# ifdef TEXTEDITOR
2005-01-24 23:47:32 +00:00
extern qboolean editormodal ;
2004-08-22 22:29:09 +00:00
# endif
2004-12-24 08:45:56 +00:00
qboolean nohud ;
2009-04-06 00:34:32 +00:00
qboolean noworld ;
2004-12-15 19:53:30 +00:00
RSpeedMark ( ) ;
2013-11-21 23:02:28 +00:00
r_refdef . pxrect . maxheight = vid . pixelheight ;
2011-06-17 01:54:54 +00:00
vid . numpages = 2 + vid_triplebuffer . value ;
2004-08-22 22:29:09 +00:00
2013-12-29 22:48:28 +00:00
R2D_Font_Changed ( ) ;
2004-08-22 22:29:09 +00:00
if ( scr_disabled_for_loading )
{
2005-02-12 18:56:04 +00:00
extern float scr_disabled_time ;
2013-10-08 14:28:11 +00:00
if ( Sys_DoubleTime ( ) - scr_disabled_time > 60 | | ! Key_Dest_Has ( ~ kdm_game ) )
2004-08-22 22:29:09 +00:00
{
2013-10-08 14:28:11 +00:00
//FIXME: instead of reenabling the screen, we should just draw the relevent things skipping only the game.
2004-08-22 22:29:09 +00:00
scr_disabled_for_loading = false ;
}
else
2015-08-10 18:28:23 +00:00
{
2006-09-17 00:59:22 +00:00
scr_drawloading = true ;
2014-03-30 00:39:37 +00:00
SCR_DrawLoading ( true ) ;
2006-09-17 00:59:22 +00:00
scr_drawloading = false ;
2015-08-10 18:28:23 +00:00
if ( R2D_Flush )
R2D_Flush ( ) ;
2014-03-30 00:39:37 +00:00
VID_SwapBuffers ( ) ;
2004-12-15 19:53:30 +00:00
RSpeedEnd ( RSPEED_TOTALREFRESH ) ;
2004-08-22 22:29:09 +00:00
return ;
}
}
if ( ! scr_initialized | | ! con_initialized )
2004-12-15 19:53:30 +00:00
{
RSpeedEnd ( RSPEED_TOTALREFRESH ) ;
2004-08-22 22:29:09 +00:00
return ; // not initialized yet
2004-12-15 19:53:30 +00:00
}
2004-08-22 22:29:09 +00:00
2009-11-07 13:29:15 +00:00
Shader_DoReload ( ) ;
2014-03-30 08:55:06 +00:00
qglDisable ( GL_SCISSOR_TEST ) ;
2005-09-09 23:40:55 +00:00
# ifdef VM_UI
2004-08-22 22:29:09 +00:00
uimenu = UI_MenuState ( ) ;
2005-09-09 23:40:55 +00:00
# else
uimenu = 0 ;
# endif
2004-08-22 22:29:09 +00:00
# ifdef TEXTEDITOR
if ( editormodal )
{
Editor_Draw ( ) ;
2011-12-23 03:12:29 +00:00
V_UpdatePalette ( false ) ;
2009-11-04 21:16:50 +00:00
# if defined(_WIN32) && defined(GLQUAKE)
2004-08-22 22:29:09 +00:00
Media_RecordFrame ( ) ;
# endif
2010-05-01 22:47:47 +00:00
R2D_BrightenScreen ( ) ;
2005-08-03 23:14:59 +00:00
2013-10-08 14:28:11 +00:00
if ( key_dest_mask & kdm_console )
2011-05-20 04:10:46 +00:00
Con_DrawConsole ( vid . height / 2 , false ) ;
2015-02-02 08:01:53 +00:00
SCR_DrawCursor ( ) ;
2015-08-10 18:28:23 +00:00
if ( R2D_Flush )
R2D_Flush ( ) ;
2014-03-30 00:39:37 +00:00
VID_SwapBuffers ( ) ;
2004-12-15 19:53:30 +00:00
RSpeedEnd ( RSPEED_TOTALREFRESH ) ;
2004-08-22 22:29:09 +00:00
return ;
}
# endif
if ( Media_ShowFilm ( ) )
{
M_Draw ( 0 ) ;
2011-12-23 03:12:29 +00:00
V_UpdatePalette ( false ) ;
2009-11-04 21:16:50 +00:00
# if defined(_WIN32) && defined(GLQUAKE)
2004-08-22 22:29:09 +00:00
Media_RecordFrame ( ) ;
# endif
2010-05-01 22:47:47 +00:00
R2D_BrightenScreen ( ) ;
2015-08-10 18:28:23 +00:00
if ( R2D_Flush )
R2D_Flush ( ) ;
2012-10-08 04:36:10 +00:00
GL_Set2D ( false ) ;
2014-03-30 00:39:37 +00:00
VID_SwapBuffers ( ) ;
2004-12-15 19:53:30 +00:00
RSpeedEnd ( RSPEED_TOTALREFRESH ) ;
2004-08-22 22:29:09 +00:00
return ;
}
//
// do 3D refresh drawing, and then update the screen
//
SCR_SetUpToDrawConsole ( ) ;
2004-12-24 08:45:56 +00:00
2009-04-06 00:34:32 +00:00
noworld = false ;
2004-12-24 08:45:56 +00:00
nohud = false ;
2005-09-08 22:52:46 +00:00
2015-01-07 13:34:05 +00:00
if ( r_clear . ival )
{
GL_ForceDepthWritable ( ) ;
qglClearColor ( ( r_clear . ival & 1 ) ? 1 : 0 , ( r_clear . ival & 2 ) ? 1 : 0 , ( r_clear . ival & 4 ) ? 1 : 0 , 1 ) ;
qglClear ( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT ) ;
depthcleared = true ;
}
2004-12-24 08:45:56 +00:00
# ifdef VM_CG
if ( CG_Refresh ( ) )
nohud = true ;
else
2005-01-07 03:07:50 +00:00
# endif
# ifdef CSQC_DAT
2013-03-12 22:53:23 +00:00
if ( CSQC_DrawView ( ) )
2005-01-07 03:07:50 +00:00
nohud = true ;
else
2004-12-24 08:45:56 +00:00
# endif
2014-03-30 00:39:37 +00:00
{
2009-04-06 00:34:32 +00:00
if ( uimenu ! = 1 )
2005-05-13 10:42:48 +00:00
{
2009-04-06 00:34:32 +00:00
if ( r_worldentity . model & & cls . state = = ca_active )
V_RenderView ( ) ;
else
{
noworld = true ;
}
2005-05-13 10:42:48 +00:00
}
2014-03-30 00:39:37 +00:00
}
2004-08-22 22:29:09 +00:00
2012-01-17 07:57:46 +00:00
GL_Set2D ( false ) ;
2004-08-22 22:29:09 +00:00
2009-11-04 21:16:50 +00:00
scr_con_forcedraw = false ;
2009-04-06 00:34:32 +00:00
if ( noworld )
{
extern char levelshotname [ ] ;
//draw the levelshot or the conback fullscreen
if ( * levelshotname )
2011-03-31 01:14:01 +00:00
R2D_ScalePic ( 0 , 0 , vid . width , vid . height , R2D_SafeCachePic ( levelshotname ) ) ;
2009-11-04 21:16:50 +00:00
else if ( scr_con_current ! = vid . height )
2011-03-31 01:14:01 +00:00
R2D_ConsoleBackground ( 0 , vid . height , true ) ;
2009-11-04 21:16:50 +00:00
else
scr_con_forcedraw = true ;
2009-04-06 00:34:32 +00:00
nohud = true ;
2013-06-23 02:17:02 +00:00
}
2005-02-06 13:54:36 +00:00
2004-12-24 08:45:56 +00:00
SCR_DrawTwoDimensional ( uimenu , nohud ) ;
2004-08-22 22:29:09 +00:00
2011-12-23 03:12:29 +00:00
V_UpdatePalette ( false ) ;
2012-11-27 03:23:19 +00:00
R2D_BrightenScreen ( ) ;
2009-11-04 21:16:50 +00:00
# if defined(_WIN32) && defined(GLQUAKE)
2004-08-22 22:29:09 +00:00
Media_RecordFrame ( ) ;
# endif
2004-12-15 19:53:30 +00:00
2015-07-30 16:26:15 +00:00
if ( R2D_Flush )
R2D_Flush ( ) ;
2004-12-15 19:53:30 +00:00
2015-08-10 18:28:23 +00:00
RSpeedEnd ( RSPEED_TOTALREFRESH ) ;
RSpeedShow ( ) ;
2013-10-08 14:28:11 +00:00
RSpeedRemark ( ) ;
2014-03-30 00:39:37 +00:00
VID_SwapBuffers ( ) ;
2013-10-08 14:28:11 +00:00
RSpeedEnd ( RSPEED_FINISH ) ;
2014-10-22 19:41:20 +00:00
//gl 4.5 / GL_ARB_robustness / GL_KHR_robustness
if ( qglGetGraphicsResetStatus )
{
GLenum err = qglGetGraphicsResetStatus ( ) ;
switch ( err )
{
case GL_NO_ERROR :
break ;
case GL_GUILTY_CONTEXT_RESET : //we did it
case GL_INNOCENT_CONTEXT_RESET : //something else broke the hardware and broke our ram
case GL_UNKNOWN_CONTEXT_RESET : //whodunit
default :
Con_Printf ( " OpenGL reset detected \n " ) ;
Sys_Sleep ( 3.0 ) ;
Cmd_ExecuteString ( " vid_restart " , RESTRICT_LOCAL ) ;
break ;
}
}
2004-08-22 22:29:09 +00:00
}
2015-08-14 02:46:38 +00:00
char * GLVID_GetRGBInfo ( int * truewidth , int * trueheight , enum uploadfmt * fmt )
2004-08-22 22:29:09 +00:00
{ //returns a BZ_Malloced array
2004-11-29 01:21:00 +00:00
extern qboolean gammaworks ;
int i , c ;
2011-03-31 23:05:19 +00:00
qbyte * ret ;
2015-08-28 03:13:45 +00:00
extern qboolean r2d_canhwgamma ;
2004-08-22 22:29:09 +00:00
2015-08-11 09:14:33 +00:00
* truewidth = vid . fbpwidth ;
* trueheight = vid . fbpheight ;
2015-02-02 08:01:53 +00:00
2012-04-24 07:59:11 +00:00
/*if (1)
{
float * p ;
p = BZ_Malloc ( vid . pixelwidth * vid . pixelheight * sizeof ( float ) ) ;
qglReadPixels ( 0 , 0 , vid . pixelwidth , vid . pixelheight , GL_DEPTH_COMPONENT , GL_FLOAT , p ) ;
2015-08-14 02:46:38 +00:00
ret = BZ_Malloc ( vid . pixelwidth * vid . pixelheight * 3 ) ;
2012-04-24 07:59:11 +00:00
c = vid . pixelwidth * vid . pixelheight ;
for ( i = 1 ; i < c ; i + + )
{
2015-08-14 02:46:38 +00:00
ret [ i * 3 + 0 ] = p [ i ] * p [ i ] * p [ i ] * 255 ;
ret [ i * 3 + 1 ] = p [ i ] * p [ i ] * p [ i ] * 255 ;
ret [ i * 3 + 2 ] = p [ i ] * p [ i ] * p [ i ] * 255 ;
2012-04-24 07:59:11 +00:00
}
BZ_Free ( p ) ;
}
2015-08-11 09:14:33 +00:00
else */ if ( gl_config . gles | | ( * truewidth & 3 ) )
2011-03-31 23:05:19 +00:00
{
qbyte * p ;
2015-08-14 02:46:38 +00:00
//gles:
//Only two format/type parameter pairs are accepted.
//GL_RGBA/GL_UNSIGNED_BYTE is always accepted, and the other acceptable pair can be discovered by querying GL_IMPLEMENTATION_COLOR_READ_FORMAT and GL_IMPLEMENTATION_COLOR_READ_TYPE.
//thus its simpler to only use GL_RGBA/GL_UNSIGNED_BYTE
//desktopgl:
//total line byte length must be aligned to GL_PACK_ALIGNMENT. by reading rgba instead of rgb, we can ensure the line is a multiple of 4 bytes.
2011-03-31 23:05:19 +00:00
2015-08-14 02:46:38 +00:00
ret = BZ_Malloc ( ( * truewidth ) * ( * trueheight ) * 4 ) ;
qglReadPixels ( 0 , 0 , ( * truewidth ) , ( * trueheight ) , GL_RGBA , GL_UNSIGNED_BYTE , ret ) ;
* fmt = TF_RGB24 ;
2015-02-02 08:01:53 +00:00
c = ( * truewidth ) * ( * trueheight ) ;
2015-08-14 02:46:38 +00:00
p = ret ;
2011-03-31 23:05:19 +00:00
for ( i = 1 ; i < c ; i + + )
{
p [ i * 3 + 0 ] = p [ i * 4 + 0 ] ;
p [ i * 3 + 1 ] = p [ i * 4 + 1 ] ;
p [ i * 3 + 2 ] = p [ i * 4 + 2 ] ;
}
2015-08-14 02:46:38 +00:00
ret = BZ_Realloc ( ret , ( * truewidth ) * ( * trueheight ) * 3 ) ;
}
# ifdef _DEBUG
else if ( ! gl_config . gles & & gl_config . glversion > = 1.2 )
{
* fmt = TF_BGRA32 ;
ret = BZ_Malloc ( ( * truewidth ) * ( * trueheight ) * 4 ) ;
qglReadPixels ( 0 , 0 , ( * truewidth ) , ( * trueheight ) , GL_BGRA_EXT , GL_UNSIGNED_INT_8_8_8_8_REV , ret ) ;
2011-03-31 23:05:19 +00:00
}
2015-08-14 02:46:38 +00:00
# endif
2011-03-31 23:05:19 +00:00
else
{
2015-08-14 02:46:38 +00:00
* fmt = TF_RGB24 ;
ret = BZ_Malloc ( ( * truewidth ) * ( * trueheight ) * 3 ) ;
qglReadPixels ( 0 , 0 , ( * truewidth ) , ( * trueheight ) , GL_RGB , GL_UNSIGNED_BYTE , ret ) ;
2011-03-31 23:05:19 +00:00
}
2004-08-22 22:29:09 +00:00
2015-08-28 03:13:45 +00:00
if ( gammaworks & & r2d_canhwgamma )
2004-11-29 01:21:00 +00:00
{
2015-08-28 03:13:45 +00:00
if ( * fmt = = TF_BGRA32 | | * fmt = = TF_RGBA32 )
2004-11-29 01:21:00 +00:00
{
2015-08-28 03:13:45 +00:00
c = ( * truewidth ) * ( * trueheight ) * 4 ;
for ( i = 0 ; i < c ; i + = 4 )
{
extern qbyte gammatable [ 256 ] ;
ret [ i + 0 ] = gammatable [ ret [ i + 0 ] ] ;
ret [ i + 1 ] = gammatable [ ret [ i + 1 ] ] ;
ret [ i + 2 ] = gammatable [ ret [ i + 2 ] ] ;
}
}
else
{
c = ( * truewidth ) * ( * trueheight ) * 3 ;
for ( i = 0 ; i < c ; i + = 3 )
{
extern qbyte gammatable [ 256 ] ;
ret [ i + 0 ] = gammatable [ ret [ i + 0 ] ] ;
ret [ i + 1 ] = gammatable [ ret [ i + 1 ] ] ;
ret [ i + 2 ] = gammatable [ ret [ i + 2 ] ] ;
}
2004-11-29 01:21:00 +00:00
}
}
2004-08-22 22:29:09 +00:00
return ret ;
}
2004-12-15 19:53:30 +00:00
# endif