📄 tr_init.c
字号:
/*
==================
RB_TakeScreenshotJPEG
==================
*/
void RB_TakeScreenshotJPEG( int x, int y, int width, int height, char *fileName ) {
byte *buffer;
buffer = ri.Hunk_AllocateTempMemory(glConfig.vidWidth*glConfig.vidHeight*4);
qglReadPixels( x, y, width, height, GL_RGBA, GL_UNSIGNED_BYTE, buffer );
// gamma correct
if ( ( tr.overbrightBits > 0 ) && glConfig.deviceSupportsGamma ) {
R_GammaCorrect( buffer, glConfig.vidWidth * glConfig.vidHeight * 4 );
}
ri.FS_WriteFile( fileName, buffer, 1 ); // create path
SaveJPG( fileName, 95, glConfig.vidWidth, glConfig.vidHeight, buffer);
ri.Hunk_FreeTempMemory( buffer );
}
/*
==================
RB_TakeScreenshotCmd
==================
*/
const void *RB_TakeScreenshotCmd( const void *data ) {
const screenshotCommand_t *cmd;
cmd = (const screenshotCommand_t *)data;
if (cmd->jpeg)
RB_TakeScreenshotJPEG( cmd->x, cmd->y, cmd->width, cmd->height, cmd->fileName);
else
RB_TakeScreenshot( cmd->x, cmd->y, cmd->width, cmd->height, cmd->fileName);
return (const void *)(cmd + 1);
}
/*
==================
R_TakeScreenshot
==================
*/
void R_TakeScreenshot( int x, int y, int width, int height, char *name, qboolean jpeg ) {
static char fileName[MAX_OSPATH]; // bad things if two screenshots per frame?
screenshotCommand_t *cmd;
cmd = R_GetCommandBuffer( sizeof( *cmd ) );
if ( !cmd ) {
return;
}
cmd->commandId = RC_SCREENSHOT;
cmd->x = x;
cmd->y = y;
cmd->width = width;
cmd->height = height;
Q_strncpyz( fileName, name, sizeof(fileName) );
cmd->fileName = fileName;
cmd->jpeg = jpeg;
}
/*
==================
R_ScreenshotFilename
==================
*/
void R_ScreenshotFilename( int lastNumber, char *fileName ) {
int a,b,c,d;
if ( lastNumber < 0 || lastNumber > 9999 ) {
Com_sprintf( fileName, MAX_OSPATH, "screenshots/shot9999.tga" );
return;
}
a = lastNumber / 1000;
lastNumber -= a*1000;
b = lastNumber / 100;
lastNumber -= b*100;
c = lastNumber / 10;
lastNumber -= c*10;
d = lastNumber;
Com_sprintf( fileName, MAX_OSPATH, "screenshots/shot%i%i%i%i.tga"
, a, b, c, d );
}
/*
==================
R_ScreenshotFilename
==================
*/
void R_ScreenshotFilenameJPEG( int lastNumber, char *fileName ) {
int a,b,c,d;
if ( lastNumber < 0 || lastNumber > 9999 ) {
Com_sprintf( fileName, MAX_OSPATH, "screenshots/shot9999.jpg" );
return;
}
a = lastNumber / 1000;
lastNumber -= a*1000;
b = lastNumber / 100;
lastNumber -= b*100;
c = lastNumber / 10;
lastNumber -= c*10;
d = lastNumber;
Com_sprintf( fileName, MAX_OSPATH, "screenshots/shot%i%i%i%i.jpg"
, a, b, c, d );
}
/*
====================
R_LevelShot
levelshots are specialized 128*128 thumbnails for
the menu system, sampled down from full screen distorted images
====================
*/
void R_LevelShot( void ) {
char checkname[MAX_OSPATH];
byte *buffer;
byte *source;
byte *src, *dst;
int x, y;
int r, g, b;
float xScale, yScale;
int xx, yy;
sprintf( checkname, "levelshots/%s.tga", tr.world->baseName );
source = ri.Hunk_AllocateTempMemory( glConfig.vidWidth * glConfig.vidHeight * 3 );
buffer = ri.Hunk_AllocateTempMemory( 128 * 128*3 + 18);
Com_Memset (buffer, 0, 18);
buffer[2] = 2; // uncompressed type
buffer[12] = 128;
buffer[14] = 128;
buffer[16] = 24; // pixel size
qglReadPixels( 0, 0, glConfig.vidWidth, glConfig.vidHeight, GL_RGB, GL_UNSIGNED_BYTE, source );
// resample from source
xScale = glConfig.vidWidth / 512.0f;
yScale = glConfig.vidHeight / 384.0f;
for ( y = 0 ; y < 128 ; y++ ) {
for ( x = 0 ; x < 128 ; x++ ) {
r = g = b = 0;
for ( yy = 0 ; yy < 3 ; yy++ ) {
for ( xx = 0 ; xx < 4 ; xx++ ) {
src = source + 3 * ( glConfig.vidWidth * (int)( (y*3+yy)*yScale ) + (int)( (x*4+xx)*xScale ) );
r += src[0];
g += src[1];
b += src[2];
}
}
dst = buffer + 18 + 3 * ( y * 128 + x );
dst[0] = b / 12;
dst[1] = g / 12;
dst[2] = r / 12;
}
}
// gamma correct
if ( ( tr.overbrightBits > 0 ) && glConfig.deviceSupportsGamma ) {
R_GammaCorrect( buffer + 18, 128 * 128 * 3 );
}
ri.FS_WriteFile( checkname, buffer, 128 * 128*3 + 18 );
ri.Hunk_FreeTempMemory( buffer );
ri.Hunk_FreeTempMemory( source );
ri.Printf( PRINT_ALL, "Wrote %s\n", checkname );
}
/*
==================
R_ScreenShot_f
screenshot
screenshot [silent]
screenshot [levelshot]
screenshot [filename]
Doesn't print the pacifier message if there is a second arg
==================
*/
void R_ScreenShot_f (void) {
char checkname[MAX_OSPATH];
static int lastNumber = -1;
qboolean silent;
if ( !strcmp( ri.Cmd_Argv(1), "levelshot" ) ) {
R_LevelShot();
return;
}
if ( !strcmp( ri.Cmd_Argv(1), "silent" ) ) {
silent = qtrue;
} else {
silent = qfalse;
}
if ( ri.Cmd_Argc() == 2 && !silent ) {
// explicit filename
Com_sprintf( checkname, MAX_OSPATH, "screenshots/%s.tga", ri.Cmd_Argv( 1 ) );
} else {
// scan for a free filename
// if we have saved a previous screenshot, don't scan
// again, because recording demo avis can involve
// thousands of shots
if ( lastNumber == -1 ) {
lastNumber = 0;
}
// scan for a free number
for ( ; lastNumber <= 9999 ; lastNumber++ ) {
R_ScreenshotFilename( lastNumber, checkname );
if (!ri.FS_FileExists( checkname ))
{
break; // file doesn't exist
}
}
if ( lastNumber >= 9999 ) {
ri.Printf (PRINT_ALL, "ScreenShot: Couldn't create a file\n");
return;
}
lastNumber++;
}
R_TakeScreenshot( 0, 0, glConfig.vidWidth, glConfig.vidHeight, checkname, qfalse );
if ( !silent ) {
ri.Printf (PRINT_ALL, "Wrote %s\n", checkname);
}
}
void R_ScreenShotJPEG_f (void) {
char checkname[MAX_OSPATH];
static int lastNumber = -1;
qboolean silent;
if ( !strcmp( ri.Cmd_Argv(1), "levelshot" ) ) {
R_LevelShot();
return;
}
if ( !strcmp( ri.Cmd_Argv(1), "silent" ) ) {
silent = qtrue;
} else {
silent = qfalse;
}
if ( ri.Cmd_Argc() == 2 && !silent ) {
// explicit filename
Com_sprintf( checkname, MAX_OSPATH, "screenshots/%s.jpg", ri.Cmd_Argv( 1 ) );
} else {
// scan for a free filename
// if we have saved a previous screenshot, don't scan
// again, because recording demo avis can involve
// thousands of shots
if ( lastNumber == -1 ) {
lastNumber = 0;
}
// scan for a free number
for ( ; lastNumber <= 9999 ; lastNumber++ ) {
R_ScreenshotFilenameJPEG( lastNumber, checkname );
if (!ri.FS_FileExists( checkname ))
{
break; // file doesn't exist
}
}
if ( lastNumber == 10000 ) {
ri.Printf (PRINT_ALL, "ScreenShot: Couldn't create a file\n");
return;
}
lastNumber++;
}
R_TakeScreenshot( 0, 0, glConfig.vidWidth, glConfig.vidHeight, checkname, qtrue );
if ( !silent ) {
ri.Printf (PRINT_ALL, "Wrote %s\n", checkname);
}
}
//============================================================================
/*
** GL_SetDefaultState
*/
void GL_SetDefaultState( void )
{
qglClearDepth( 1.0f );
qglCullFace(GL_FRONT);
qglColor4f (1,1,1,1);
// initialize downstream texture unit if we're running
// in a multitexture environment
if ( qglActiveTextureARB ) {
GL_SelectTexture( 1 );
GL_TextureMode( r_textureMode->string );
GL_TexEnv( GL_MODULATE );
qglDisable( GL_TEXTURE_2D );
GL_SelectTexture( 0 );
}
qglEnable(GL_TEXTURE_2D);
GL_TextureMode( r_textureMode->string );
GL_TexEnv( GL_MODULATE );
qglShadeModel( GL_SMOOTH );
qglDepthFunc( GL_LEQUAL );
// the vertex array is always enabled, but the color and texture
// arrays are enabled and disabled around the compiled vertex array call
qglEnableClientState (GL_VERTEX_ARRAY);
//
// make sure our GL state vector is set correctly
//
glState.glStateBits = GLS_DEPTHTEST_DISABLE | GLS_DEPTHMASK_TRUE;
qglPolygonMode (GL_FRONT_AND_BACK, GL_FILL);
qglDepthMask( GL_TRUE );
qglDisable( GL_DEPTH_TEST );
qglEnable( GL_SCISSOR_TEST );
qglDisable( GL_CULL_FACE );
qglDisable( GL_BLEND );
}
/*
================
GfxInfo_f
================
*/
void GfxInfo_f( void )
{
cvar_t *sys_cpustring = ri.Cvar_Get( "sys_cpustring", "", 0 );
const char *enablestrings[] =
{
"disabled",
"enabled"
};
const char *fsstrings[] =
{
"windowed",
"fullscreen"
};
ri.Printf( PRINT_ALL, "\nGL_VENDOR: %s\n", glConfig.vendor_string );
ri.Printf( PRINT_ALL, "GL_RENDERER: %s\n", glConfig.renderer_string );
ri.Printf( PRINT_ALL, "GL_VERSION: %s\n", glConfig.version_string );
ri.Printf( PRINT_ALL, "GL_EXTENSIONS: %s\n", glConfig.extensions_string );
ri.Printf( PRINT_ALL, "GL_MAX_TEXTURE_SIZE: %d\n", glConfig.maxTextureSize );
ri.Printf( PRINT_ALL, "GL_MAX_ACTIVE_TEXTURES_ARB: %d\n", glConfig.maxActiveTextures );
ri.Printf( PRINT_ALL, "\nPIXELFORMAT: color(%d-bits) Z(%d-bit) stencil(%d-bits)\n", glConfig.colorBits, glConfig.depthBits, glConfig.stencilBits );
ri.Printf( PRINT_ALL, "MODE: %d, %d x %d %s hz:", r_mode->integer, glConfig.vidWidth, glConfig.vidHeight, fsstrings[r_fullscreen->integer == 1] );
if ( glConfig.displayFrequency )
{
ri.Printf( PRINT_ALL, "%d\n", glConfig.displayFrequency );
}
else
{
ri.Printf( PRINT_ALL, "N/A\n" );
}
if ( glConfig.deviceSupportsGamma )
{
ri.Printf( PRINT_ALL, "GAMMA: hardware w/ %d overbright bits\n", tr.overbrightBits );
}
else
{
ri.Printf( PRINT_ALL, "GAMMA: software w/ %d overbright bits\n", tr.overbrightBits );
}
ri.Printf( PRINT_ALL, "CPU: %s\n", sys_cpustring->string );
// rendering primitives
{
int primitives;
// default is to use triangles if compiled vertex arrays are present
ri.Printf( PRINT_ALL, "rendering primitives: " );
primitives = r_primitives->integer;
if ( primitives == 0 ) {
if ( qglLockArraysEXT ) {
primitives = 2;
} else {
primitives = 1;
}
}
if ( primitives == -1 ) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -