void RB_ShowImages( void ) { int i; image_t *image; float x, y, w, h; vec4_t quadVerts[ 4 ]; int start, end; GLimp_LogComment( "--- RB_ShowImages ---\n" ); if ( !backEnd.projection2D ) { RB_SetGL2D(); } qglClear( GL_COLOR_BUFFER_BIT ); qglFinish(); GL_BindProgram( &tr.genericSingleShader ); GL_Cull( CT_TWO_SIDED ); // set uniforms GLSL_SetUniform_TCGen_Environment( &tr.genericSingleShader, qfalse ); GLSL_SetUniform_ColorGen( &tr.genericSingleShader, CGEN_VERTEX ); GLSL_SetUniform_AlphaGen( &tr.genericSingleShader, AGEN_VERTEX ); if ( glConfig.vboVertexSkinningAvailable ) { GLSL_SetUniform_VertexSkinning( &tr.genericSingleShader, qfalse ); } GLSL_SetUniform_DeformGen( &tr.genericSingleShader, DGEN_NONE ); GLSL_SetUniform_AlphaTest( &tr.genericSingleShader, 0 ); GLSL_SetUniform_ColorTextureMatrix( &tr.genericSingleShader, matrixIdentity ); GL_SelectTexture( 0 ); start = ri.Milliseconds(); for ( i = 0; i < tr.images.currentElements; i++ ) { image = Com_GrowListElement( &tr.images, i ); /* if(image->bits & (IF_RGBA16F | IF_RGBA32F | IF_LA16F | IF_LA32F)) { // don't render float textures using FFP continue; } */ w = glConfig.vidWidth / 20; h = glConfig.vidHeight / 15; x = i % 20 * w; y = i / 20 * h; // show in proportional size in mode 2 if ( r_showImages->integer == 2 ) { w *= image->uploadWidth / 512.0f; h *= image->uploadHeight / 512.0f; } // bind u_ColorMap GL_Bind( image ); VectorSet4( quadVerts[ 0 ], x, y, 0, 1 ); VectorSet4( quadVerts[ 1 ], x + w, y, 0, 1 ); VectorSet4( quadVerts[ 2 ], x + w, y + h, 0, 1 ); VectorSet4( quadVerts[ 3 ], x, y + h, 0, 1 ); Tess_InstantQuad( quadVerts ); /* qglBegin(GL_QUADS); qglVertexAttrib4fARB(ATTR_INDEX_TEXCOORD0, 0, 0, 0, 1); qglVertexAttrib4fARB(ATTR_INDEX_POSITION, x, y, 0, 1); qglVertexAttrib4fARB(ATTR_INDEX_TEXCOORD0, 1, 0, 0, 1); qglVertexAttrib4fARB(ATTR_INDEX_POSITION, x + w, y, 0, 1); qglVertexAttrib4fARB(ATTR_INDEX_TEXCOORD0, 1, 1, 0, 1); qglVertexAttrib4fARB(ATTR_INDEX_POSITION, x + w, y + h, 0, 1); qglVertexAttrib4fARB(ATTR_INDEX_TEXCOORD0, 0, 1, 0, 1); qglVertexAttrib4fARB(ATTR_INDEX_POSITION, x, y + h, 0, 1); qglEnd(); */ } qglFinish(); end = ri.Milliseconds(); ri.Printf( PRINT_ALL, "%i msec to draw all images\n", end - start ); GL_CheckErrors(); }
/* ** RB_DrawSun */ void RB_DrawSun( void ) { #if 0 float size; float dist; vec3_t origin, vec1, vec2; vec3_t temp; matrix_t transformMatrix; matrix_t modelViewMatrix; if ( !backEnd.skyRenderedThisView ) { return; } if ( !r_drawSun->integer ) { return; } GL_PushMatrix(); GL_BindProgram( &tr.genericShader ); // set uniforms GLSL_SetUniform_TCGen_Environment( &tr.genericShader, qfalse ); GLSL_SetUniform_InverseVertexColor( &tr.genericShader, qfalse ); if ( glConfig2.vboVertexSkinningAvailable ) { GLSL_SetUniform_VertexSkinning( &tr.genericShader, qfalse ); } GLSL_SetUniform_DeformGen( &tr.genericShader, DGEN_NONE ); GLSL_SetUniform_AlphaTest( &tr.genericShader, -1.0 ); MatrixSetupTranslation( transformMatrix, backEnd.viewParms.orientation.origin[ 0 ], backEnd.viewParms.orientation.origin[ 1 ], backEnd.viewParms.orientation.origin[ 2 ] ); MatrixMultiply( backEnd.viewParms.world.viewMatrix, transformMatrix, modelViewMatrix ); GL_LoadProjectionMatrix( backEnd.viewParms.projectionMatrix ); GL_LoadModelViewMatrix( modelViewMatrix ); GLSL_SetUniform_ModelMatrix( &tr.genericShader, backEnd.orientation.transformMatrix ); GLSL_SetUniform_ModelViewProjectionMatrix( &tr.genericShader, glState.modelViewProjectionMatrix[ glState.stackIndex ] ); GLSL_SetUniform_PortalClipping( &tr.genericShader, backEnd.viewParms.isPortal ); if ( backEnd.viewParms.isPortal ) { float plane[ 4 ]; // clipping plane in world space plane[ 0 ] = backEnd.viewParms.portalPlane.normal[ 0 ]; plane[ 1 ] = backEnd.viewParms.portalPlane.normal[ 1 ]; plane[ 2 ] = backEnd.viewParms.portalPlane.normal[ 2 ]; plane[ 3 ] = backEnd.viewParms.portalPlane.dist; GLSL_SetUniform_PortalPlane( &tr.genericShader, plane ); } dist = backEnd.viewParms.skyFar / 1.75; // div sqrt(3) size = dist * 0.4; VectorScale( tr.sunDirection, dist, origin ); PerpendicularVector( vec1, tr.sunDirection ); CrossProduct( tr.sunDirection, vec1, vec2 ); VectorScale( vec1, size, vec1 ); VectorScale( vec2, size, vec2 ); // farthest depth range glDepthRange( 1.0, 1.0 ); // FIXME: use quad stamp Tess_Begin( Tess_StageIteratorGeneric, tr.sunShader, NULL, tess.skipTangentSpaces, qfalse, -1, tess.fogNum ); VectorCopy( origin, temp ); VectorSubtract( temp, vec1, temp ); VectorSubtract( temp, vec2, temp ); VectorCopy( temp, tess.xyz[ tess.numVertexes ] ); tess.xyz[ tess.numVertexes ][ 3 ] = 1; tess.texCoords[ tess.numVertexes ][ 0 ] = 0; tess.texCoords[ tess.numVertexes ][ 1 ] = 0; tess.texCoords[ tess.numVertexes ][ 2 ] = 0; tess.texCoords[ tess.numVertexes ][ 3 ] = 1; tess.colors[ tess.numVertexes ][ 0 ] = 1; tess.colors[ tess.numVertexes ][ 1 ] = 1; tess.colors[ tess.numVertexes ][ 2 ] = 1; tess.numVertexes++; VectorCopy( origin, temp ); VectorAdd( temp, vec1, temp ); VectorSubtract( temp, vec2, temp ); VectorCopy( temp, tess.xyz[ tess.numVertexes ] ); tess.xyz[ tess.numVertexes ][ 3 ] = 1; tess.texCoords[ tess.numVertexes ][ 0 ] = 0; tess.texCoords[ tess.numVertexes ][ 1 ] = 1; tess.texCoords[ tess.numVertexes ][ 2 ] = 0; tess.texCoords[ tess.numVertexes ][ 3 ] = 1; tess.colors[ tess.numVertexes ][ 0 ] = 1; tess.colors[ tess.numVertexes ][ 1 ] = 1; tess.colors[ tess.numVertexes ][ 2 ] = 1; tess.numVertexes++; VectorCopy( origin, temp ); VectorAdd( temp, vec1, temp ); VectorAdd( temp, vec2, temp ); VectorCopy( temp, tess.xyz[ tess.numVertexes ] ); tess.xyz[ tess.numVertexes ][ 3 ] = 1; tess.texCoords[ tess.numVertexes ][ 0 ] = 1; tess.texCoords[ tess.numVertexes ][ 1 ] = 1; tess.texCoords[ tess.numVertexes ][ 2 ] = 0; tess.texCoords[ tess.numVertexes ][ 3 ] = 1; tess.colors[ tess.numVertexes ][ 0 ] = 1; tess.colors[ tess.numVertexes ][ 1 ] = 1; tess.colors[ tess.numVertexes ][ 2 ] = 1; tess.numVertexes++; VectorCopy( origin, temp ); VectorSubtract( temp, vec1, temp ); VectorAdd( temp, vec2, temp ); VectorCopy( temp, tess.xyz[ tess.numVertexes ] ); tess.xyz[ tess.numVertexes ][ 3 ] = 1; tess.texCoords[ tess.numVertexes ][ 0 ] = 1; tess.texCoords[ tess.numVertexes ][ 1 ] = 0; tess.texCoords[ tess.numVertexes ][ 2 ] = 0; tess.texCoords[ tess.numVertexes ][ 3 ] = 1; tess.colors[ tess.numVertexes ][ 0 ] = 1; tess.colors[ tess.numVertexes ][ 1 ] = 1; tess.colors[ tess.numVertexes ][ 2 ] = 1; tess.numVertexes++; tess.indexes[ tess.numIndexes++ ] = 0; tess.indexes[ tess.numIndexes++ ] = 1; tess.indexes[ tess.numIndexes++ ] = 2; tess.indexes[ tess.numIndexes++ ] = 0; tess.indexes[ tess.numIndexes++ ] = 2; tess.indexes[ tess.numIndexes++ ] = 3; Tess_End(); // back to standard depth range glDepthRange( 0.0, 1.0 ); GL_PopMatrix(); #endif }
/* ============= RE_StretchRaw FIXME: not exactly backend Stretches a raw 32 bit power of 2 bitmap image over the given screen rectangle. Used for cinematics. ============= */ void RE_StretchRaw( int x, int y, int w, int h, int cols, int rows, const byte *data, int client, qboolean dirty ) { int i, j; int start, end; if ( !tr.registered ) { return; } R_SyncRenderThread(); // we definitely want to sync every frame for the cinematics #if defined( USE_D3D10 ) // TODO #else qglFinish(); #endif start = end = 0; if ( r_speeds->integer ) { #if defined( USE_D3D10 ) // TODO #else qglFinish(); #endif start = ri.Milliseconds(); } // make sure rows and cols are powers of 2 for ( i = 0; ( 1 << i ) < cols; i++ ) { } for ( j = 0; ( 1 << j ) < rows; j++ ) { } if ( ( 1 << i ) != cols || ( 1 << j ) != rows ) { ri.Error( ERR_DROP, "Draw_StretchRaw: size not a power of 2: %i by %i", cols, rows ); } #if defined( USE_D3D10 ) // TODO #else RB_SetGL2D(); qglVertexAttrib4fARB( ATTR_INDEX_NORMAL, 0, 0, 1, 1 ); qglVertexAttrib4fARB( ATTR_INDEX_COLOR, tr.identityLight, tr.identityLight, tr.identityLight, 1 ); GL_BindProgram( &tr.genericSingleShader ); // set uniforms GLSL_SetUniform_TCGen_Environment( &tr.genericSingleShader, qfalse ); GLSL_SetUniform_ColorGen( &tr.genericSingleShader, CGEN_VERTEX ); GLSL_SetUniform_AlphaGen( &tr.genericSingleShader, AGEN_VERTEX ); //GLSL_SetUniform_Color(&tr.genericSingleShader, colorWhite); if ( glConfig.vboVertexSkinningAvailable ) { GLSL_SetUniform_VertexSkinning( &tr.genericSingleShader, qfalse ); } GLSL_SetUniform_DeformGen( &tr.genericSingleShader, DGEN_NONE ); GLSL_SetUniform_AlphaTest( &tr.genericSingleShader, 0 ); GLSL_SetUniform_ModelViewProjectionMatrix( &tr.genericSingleShader, glState.modelViewProjectionMatrix[ glState.stackIndex ] ); // bind u_ColorMap GL_SelectTexture( 0 ); GL_Bind( tr.scratchImage[ client ] ); GLSL_SetUniform_ColorTextureMatrix( &tr.genericSingleShader, matrixIdentity ); // if the scratchImage isn't in the format we want, specify it as a new texture if ( cols != tr.scratchImage[ client ]->width || rows != tr.scratchImage[ client ]->height ) { tr.scratchImage[ client ]->width = tr.scratchImage[ client ]->uploadWidth = cols; tr.scratchImage[ client ]->height = tr.scratchImage[ client ]->uploadHeight = rows; qglTexImage2D( GL_TEXTURE_2D, 0, GL_RGB8, cols, rows, 0, GL_RGBA, GL_UNSIGNED_BYTE, data ); qglTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR ); qglTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR ); qglTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP ); qglTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP ); } else { if ( dirty ) { // otherwise, just subimage upload it so that drivers can tell we are going to be changing // it and don't try and do a texture compression qglTexSubImage2D( GL_TEXTURE_2D, 0, 0, 0, cols, rows, GL_RGBA, GL_UNSIGNED_BYTE, data ); } } #endif // #if defined(USE_D3D10) if ( r_speeds->integer ) { #if defined( USE_D3D10 ) // TODO #else qglFinish(); #endif end = ri.Milliseconds(); ri.Printf( PRINT_ALL, "qglTexSubImage2D %i, %i: %i msec\n", cols, rows, end - start ); } tess.numVertexes = 0; tess.numIndexes = 0; tess.xyz[ tess.numVertexes ][ 0 ] = x; tess.xyz[ tess.numVertexes ][ 1 ] = y; tess.xyz[ tess.numVertexes ][ 2 ] = 0; tess.xyz[ tess.numVertexes ][ 3 ] = 1; tess.texCoords[ tess.numVertexes ][ 0 ] = 0.5f / cols; tess.texCoords[ tess.numVertexes ][ 1 ] = 0.5f / rows; tess.texCoords[ tess.numVertexes ][ 2 ] = 0; tess.texCoords[ tess.numVertexes ][ 3 ] = 1; tess.numVertexes++; tess.xyz[ tess.numVertexes ][ 0 ] = x + w; tess.xyz[ tess.numVertexes ][ 1 ] = y; tess.xyz[ tess.numVertexes ][ 2 ] = 0; tess.xyz[ tess.numVertexes ][ 3 ] = 1; tess.texCoords[ tess.numVertexes ][ 0 ] = ( cols - 0.5f ) / cols; tess.texCoords[ tess.numVertexes ][ 1 ] = 0.5f / rows; tess.texCoords[ tess.numVertexes ][ 2 ] = 0; tess.texCoords[ tess.numVertexes ][ 3 ] = 1; tess.numVertexes++; tess.xyz[ tess.numVertexes ][ 0 ] = x + w; tess.xyz[ tess.numVertexes ][ 1 ] = y + h; tess.xyz[ tess.numVertexes ][ 2 ] = 0; tess.xyz[ tess.numVertexes ][ 3 ] = 1; tess.texCoords[ tess.numVertexes ][ 0 ] = ( cols - 0.5f ) / cols; tess.texCoords[ tess.numVertexes ][ 1 ] = ( rows - 0.5f ) / rows; tess.texCoords[ tess.numVertexes ][ 2 ] = 0; tess.texCoords[ tess.numVertexes ][ 3 ] = 1; tess.numVertexes++; tess.xyz[ tess.numVertexes ][ 0 ] = x; tess.xyz[ tess.numVertexes ][ 1 ] = y + h; tess.xyz[ tess.numVertexes ][ 2 ] = 0; tess.xyz[ tess.numVertexes ][ 3 ] = 1; tess.texCoords[ tess.numVertexes ][ 0 ] = 0.5f / cols; tess.texCoords[ tess.numVertexes ][ 1 ] = ( rows - 0.5f ) / rows; tess.texCoords[ tess.numVertexes ][ 2 ] = 0; tess.texCoords[ tess.numVertexes ][ 3 ] = 1; tess.numVertexes++; tess.indexes[ tess.numIndexes++ ] = 0; tess.indexes[ tess.numIndexes++ ] = 1; tess.indexes[ tess.numIndexes++ ] = 2; tess.indexes[ tess.numIndexes++ ] = 0; tess.indexes[ tess.numIndexes++ ] = 2; tess.indexes[ tess.numIndexes++ ] = 3; Tess_UpdateVBOs( ATTR_POSITION | ATTR_TEXCOORD ); Tess_DrawElements(); tess.numVertexes = 0; tess.numIndexes = 0; #if defined( USE_D3D10 ) // TODO #else GL_CheckErrors(); #endif }