/* ================ RB_StageIteratorSky All of the visible sky triangles are in tess Other things could be stuck in here, like birds in the sky, etc ================ */ void RB_StageIteratorSky( void ) { int clearBits = 0; if ( r_fastsky->integer ) { if (r_fastsky->integer == 2 && !(backEnd.refdef.rdflags & RDF_NOWORLDMODEL)) { clearBits |= GL_COLOR_BUFFER_BIT; // FIXME: only if sky shaders have been used if (*r_fastSkyColor->string) { int v, tr, tg, tb; v = r_fastSkyColor->integer; tr = (v & 0xff0000) / 0x010000; tg = (v & 0x00ff00) / 0x000100; tb = (v & 0x0000ff) / 0x000001; qglClearColor((float)tr / 255.0, (float)tg / 255.0, (float)tb / 255.0, 1.0); } else { qglClearColor(0.0f, 0.0f, 0.0f, 1.0f); // FIXME: get color of sky } qglClear(clearBits); } return; } // go through all the polygons and project them onto // the sky box to see which blocks on each side need // to be drawn RB_ClipSkyPolygons( &tess ); // r_showsky will let all the sky blocks be drawn in // front of everything to allow developers to see how // much sky is getting sucked in if ( r_showsky->integer ) { qglDepthRange( 0.0, 0.0 ); } else { qglDepthRange( 1.0, 1.0 ); } // draw the outer skybox if ( tess.shader->sky.outerbox[0] && tess.shader->sky.outerbox[0] != tr.defaultImage ) { qglColor3f( tr.identityLight, tr.identityLight, tr.identityLight ); qglPushMatrix (); GL_State( 0 ); GL_Cull( CT_FRONT_SIDED ); qglTranslatef (backEnd.viewParms.or.origin[0], backEnd.viewParms.or.origin[1], backEnd.viewParms.or.origin[2]); DrawSkyBox( tess.shader ); qglPopMatrix(); } // generate the vertexes for all the clouds, which will be drawn // by the generic shader routine R_BuildCloudData( &tess ); if (tess.numVertexes) { // yes, sky has cloud stages RB_StageIteratorGeneric(); } // draw the inner skybox //FIXME not even done // back to normal depth range qglDepthRange( 0.0, 1.0 ); // note that sky was drawn so we will draw a sun later backEnd.skyRenderedThisView = qtrue; }
/* ** RB_DrawSun */ void RB_DrawSun( void ) { float size; float dist; vec3_t origin, vec1, vec2; vec3_t temp; if ( !backEnd.skyRenderedThisView ) { return; } if ( !r_drawSun->integer ) { return; } qglLoadMatrixf( backEnd.viewParms.world.modelMatrix ); qglTranslatef (backEnd.viewParms.ori.origin[0], backEnd.viewParms.ori.origin[1], backEnd.viewParms.ori.origin[2]); dist = backEnd.viewParms.zFar / 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 qglDepthRange( 1.0, 1.0 ); // FIXME: use quad stamp RB_BeginSurface( tr.sunShader, tess.fogNum ); VectorCopy( origin, temp ); VectorSubtract( temp, vec1, temp ); VectorSubtract( temp, vec2, temp ); VectorCopy( temp, tess.xyz[tess.numVertexes] ); tess.texCoords[tess.numVertexes][0][0] = 0; tess.texCoords[tess.numVertexes][0][1] = 0; tess.vertexColors[tess.numVertexes][0] = 255; tess.vertexColors[tess.numVertexes][1] = 255; tess.vertexColors[tess.numVertexes][2] = 255; tess.numVertexes++; VectorCopy( origin, temp ); VectorAdd( temp, vec1, temp ); VectorSubtract( temp, vec2, temp ); VectorCopy( temp, tess.xyz[tess.numVertexes] ); tess.texCoords[tess.numVertexes][0][0] = 0; tess.texCoords[tess.numVertexes][0][1] = 1; tess.vertexColors[tess.numVertexes][0] = 255; tess.vertexColors[tess.numVertexes][1] = 255; tess.vertexColors[tess.numVertexes][2] = 255; tess.numVertexes++; VectorCopy( origin, temp ); VectorAdd( temp, vec1, temp ); VectorAdd( temp, vec2, temp ); VectorCopy( temp, tess.xyz[tess.numVertexes] ); tess.texCoords[tess.numVertexes][0][0] = 1; tess.texCoords[tess.numVertexes][0][1] = 1; tess.vertexColors[tess.numVertexes][0] = 255; tess.vertexColors[tess.numVertexes][1] = 255; tess.vertexColors[tess.numVertexes][2] = 255; tess.numVertexes++; VectorCopy( origin, temp ); VectorSubtract( temp, vec1, temp ); VectorAdd( temp, vec2, temp ); VectorCopy( temp, tess.xyz[tess.numVertexes] ); tess.texCoords[tess.numVertexes][0][0] = 1; tess.texCoords[tess.numVertexes][0][1] = 0; tess.vertexColors[tess.numVertexes][0] = 255; tess.vertexColors[tess.numVertexes][1] = 255; tess.vertexColors[tess.numVertexes][2] = 255; 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; RB_EndSurface(); // back to normal depth range qglDepthRange( 0.0, 1.0 ); }
void Sky_DrawCubeMap (r_modelsurf_t **mslist, int numms) { #if 0 int i; msurface_t *surf; r_modelsurf_t *ms; qbool stateset = false; // cubemapped sky doesn't need depth clipping or other hackery, is always perfectly positioned, and never has bugs for (i = 0; i < numms; i++) { ms = mslist[i]; if (!((surf = ms->surface)->flags & SURF_DRAWSKY)) continue; if (!stateset) { if (gl_support_arb_vertex_buffer_object) { GL_BindBuffer (GL_ARRAY_BUFFER_ARB, r_surfacevbo); GL_SetStreamSource (GLSTREAM_POSITION, 3, GL_FLOAT, sizeof (glvertex_t), (void *) (0)); GL_SetStreamSource (GLSTREAM_TEXCOORD0, 3, GL_FLOAT, sizeof (glvertex_t), (void *) (0)); } else { glvertex_t *base = (glvertex_t *) scratchbuf; GL_SetStreamSource (GLSTREAM_POSITION, 3, GL_FLOAT, sizeof (glvertex_t), base->v); GL_SetStreamSource (GLSTREAM_TEXCOORD0, 3, GL_FLOAT, sizeof (glvertex_t), base->v); } GL_SetStreamSource (GLSTREAM_COLOR, 0, GL_NONE, 0, NULL); GL_SetStreamSource (GLSTREAM_TEXCOORD1, 0, GL_NONE, 0, NULL); GL_SetStreamSource (GLSTREAM_TEXCOORD2, 0, GL_NONE, 0, NULL); R_BeginSurfaces (); // texmgr is fragile and can't handle cubemaps so we must do it manually qglBindTexture (GL_TEXTURE_2D, 0); qglDisable (GL_TEXTURE_2D); qglEnable (GL_TEXTURE_CUBE_MAP); qglBindTexture (GL_TEXTURE_CUBE_MAP, skyCubeTexture); qglMatrixMode (GL_TEXTURE); qglLoadIdentity (); qglTranslatef (-r_origin[0], -r_origin[1], -r_origin[2]); qglMatrixMode (GL_MODELVIEW); stateset = true; } R_BatchSurface (ms->surface, ms->matrix, ms->entnum); } if (stateset) { R_EndSurfaces (); qglMatrixMode (GL_TEXTURE); qglLoadIdentity (); qglMatrixMode (GL_MODELVIEW); // texmgr is fragile and can't handle cubemaps so we must do it manually qglBindTexture (GL_TEXTURE_CUBE_MAP, 0); qglDisable (GL_TEXTURE_CUBE_MAP); qglEnable (GL_TEXTURE_2D); // ensure that we bind a 2D texture here GL_BindTexture (GL_TEXTURE0_ARB, NULL); } #endif }
void R_DrawAliasModel ( entity_t *e ) { int i; dmdl_t *paliashdr; float an; vec3_t bbox [ 8 ]; image_t *skin; if ( !( e->flags & RF_WEAPONMODEL ) ) { if ( R_CullAliasModel( bbox, e ) ) { return; } } if ( e->flags & RF_WEAPONMODEL ) { if ( gl_lefthand->value == 2 ) { return; } } paliashdr = (dmdl_t *) currentmodel->extradata; /* get lighting information */ if ( currententity->flags & ( RF_SHELL_HALF_DAM | RF_SHELL_GREEN | RF_SHELL_RED | RF_SHELL_BLUE | RF_SHELL_DOUBLE ) ) { VectorClear( shadelight ); if ( currententity->flags & RF_SHELL_HALF_DAM ) { shadelight [ 0 ] = 0.56; shadelight [ 1 ] = 0.59; shadelight [ 2 ] = 0.45; } if ( currententity->flags & RF_SHELL_DOUBLE ) { shadelight [ 0 ] = 0.9; shadelight [ 1 ] = 0.7; } if ( currententity->flags & RF_SHELL_RED ) { shadelight [ 0 ] = 1.0; } if ( currententity->flags & RF_SHELL_GREEN ) { shadelight [ 1 ] = 1.0; } if ( currententity->flags & RF_SHELL_BLUE ) { shadelight [ 2 ] = 1.0; } } else if ( currententity->flags & RF_FULLBRIGHT ) { for ( i = 0; i < 3; i++ ) { shadelight [ i ] = 1.0; } } else { R_LightPoint( currententity->origin, shadelight ); /* player lighting hack for communication back to server */ if ( currententity->flags & RF_WEAPONMODEL ) { /* pick the greatest component, which should be the same as the mono value returned by software */ if ( shadelight [ 0 ] > shadelight [ 1 ] ) { if ( shadelight [ 0 ] > shadelight [ 2 ] ) { gl_lightlevel->value = 150 * shadelight [ 0 ]; } else { gl_lightlevel->value = 150 * shadelight [ 2 ]; } } else { if ( shadelight [ 1 ] > shadelight [ 2 ] ) { gl_lightlevel->value = 150 * shadelight [ 1 ]; } else { gl_lightlevel->value = 150 * shadelight [ 2 ]; } } } } if ( currententity->flags & RF_MINLIGHT ) { for ( i = 0; i < 3; i++ ) { if ( shadelight [ i ] > 0.1 ) { break; } } if ( i == 3 ) { shadelight [ 0 ] = 0.1; shadelight [ 1 ] = 0.1; shadelight [ 2 ] = 0.1; } } if ( currententity->flags & RF_GLOW ) { /* bonus items will pulse with time */ float scale; float min; scale = 0.1 * sin( r_newrefdef.time * 7 ); for ( i = 0; i < 3; i++ ) { min = shadelight [ i ] * 0.8; shadelight [ i ] += scale; if ( shadelight [ i ] < min ) { shadelight [ i ] = min; } } } /* ir goggles color override */ if ( r_newrefdef.rdflags & RDF_IRGOGGLES && currententity->flags & RF_IR_VISIBLE ) { shadelight [ 0 ] = 1.0; shadelight [ 1 ] = 0.0; shadelight [ 2 ] = 0.0; } shadedots = r_avertexnormal_dots [ ( (int) ( currententity->angles [ 1 ] * ( SHADEDOT_QUANT / 360.0 ) ) ) & ( SHADEDOT_QUANT - 1 ) ]; an = currententity->angles [ 1 ] / 180 * M_PI; shadevector [ 0 ] = cos( -an ); shadevector [ 1 ] = sin( -an ); shadevector [ 2 ] = 1; VectorNormalize( shadevector ); /* locate the proper data */ c_alias_polys += paliashdr->num_tris; /* draw all the triangles */ if ( currententity->flags & RF_DEPTHHACK ) /* hack the depth range to prevent view model from poking into walls */ { qglDepthRange( gldepthmin, gldepthmin + 0.3 * ( gldepthmax - gldepthmin ) ); } if ( ( currententity->flags & RF_WEAPONMODEL ) && ( gl_lefthand->value == 1.0F ) ) { extern void R_MYgluPerspective ( GLdouble fovy, GLdouble aspect, GLdouble zNear, GLdouble zFar ); qglMatrixMode( GL_PROJECTION ); qglPushMatrix(); qglLoadIdentity(); qglScalef( -1, 1, 1 ); R_MYgluPerspective( r_newrefdef.fov_y, (float) r_newrefdef.width / r_newrefdef.height, 4, 4096 ); qglMatrixMode( GL_MODELVIEW ); qglCullFace( GL_BACK ); } qglPushMatrix(); e->angles [ PITCH ] = -e->angles [ PITCH ]; R_RotateForEntity( e ); e->angles [ PITCH ] = -e->angles [ PITCH ]; /* select skin */ if ( currententity->skin ) { skin = currententity->skin; /* custom player skin */ } else { if ( currententity->skinnum >= MAX_MD2SKINS ) { skin = currentmodel->skins [ 0 ]; } else { skin = currentmodel->skins [ currententity->skinnum ]; if ( !skin ) { skin = currentmodel->skins [ 0 ]; } } } if ( !skin ) { skin = r_notexture; /* fallback... */ } R_Bind( skin->texnum ); /* draw it */ qglShadeModel( GL_SMOOTH ); R_TexEnv( GL_MODULATE ); if ( currententity->flags & RF_TRANSLUCENT ) { qglEnable( GL_BLEND ); } if ( ( currententity->frame >= paliashdr->num_frames ) || ( currententity->frame < 0 ) ) { ri.Con_Printf( PRINT_ALL, "R_DrawAliasModel %s: no such frame %d\n", currentmodel->name, currententity->frame ); currententity->frame = 0; currententity->oldframe = 0; } if ( ( currententity->oldframe >= paliashdr->num_frames ) || ( currententity->oldframe < 0 ) ) { ri.Con_Printf( PRINT_ALL, "R_DrawAliasModel %s: no such oldframe %d\n", currentmodel->name, currententity->oldframe ); currententity->frame = 0; currententity->oldframe = 0; } if ( !gl_lerpmodels->value ) { currententity->backlerp = 0; } R_DrawAliasFrameLerp( paliashdr, currententity->backlerp ); R_TexEnv( GL_REPLACE ); qglShadeModel( GL_FLAT ); qglPopMatrix(); if ( ( currententity->flags & RF_WEAPONMODEL ) && ( gl_lefthand->value == 1.0F ) ) { qglMatrixMode( GL_PROJECTION ); qglPopMatrix(); qglMatrixMode( GL_MODELVIEW ); qglCullFace( GL_FRONT ); } if ( currententity->flags & RF_TRANSLUCENT ) { qglDisable( GL_BLEND ); } if ( currententity->flags & RF_DEPTHHACK ) { qglDepthRange( gldepthmin, gldepthmax ); } if ( gl_shadows->value && !( currententity->flags & ( RF_TRANSLUCENT | RF_WEAPONMODEL | RF_NOSHADOW ) ) ) { qglPushMatrix(); /* don't rotate shadows on ungodly axes */ qglTranslatef( e->origin [ 0 ], e->origin [ 1 ], e->origin [ 2 ] ); qglRotatef( e->angles [ 1 ], 0, 0, 1 ); qglDisable( GL_TEXTURE_2D ); qglEnable( GL_BLEND ); qglColor4f( 0, 0, 0, 0.5f ); R_DrawAliasShadow( paliashdr, currententity->frame ); qglEnable( GL_TEXTURE_2D ); qglDisable( GL_BLEND ); qglPopMatrix(); } qglColor4f( 1, 1, 1, 1 ); }
/* ** RB_DrawSun */ void RB_DrawSun(void) { float size; float dist; Vec3 origin, vec1, vec2; Vec3 temp; if(!backEnd.skyRenderedThisView){ return; } if(!r_drawSun->integer){ return; } qglLoadMatrixf(backEnd.viewParms.world.modelMatrix); qglTranslatef (backEnd.viewParms.or.origin[0], backEnd.viewParms.or.origin[1], backEnd.viewParms.or.origin[2]); dist = backEnd.viewParms.zFar / 1.75; /* div sqrt(3) */ size = dist * 0.4; scalev3(tr.sunDirection, dist, origin); perpv3(vec1, tr.sunDirection); crossv3(tr.sunDirection, vec1, vec2); scalev3(vec1, size, vec1); scalev3(vec2, size, vec2); /* farthest depth range */ qglDepthRange(1.0, 1.0); /* FIXME: use quad stamp */ RB_BeginSurface(tr.sunShader, tess.fogNum); copyv3(origin, temp); subv3(temp, vec1, temp); subv3(temp, vec2, temp); copyv3(temp, tess.xyz[tess.numVertexes]); tess.texCoords[tess.numVertexes][0][0] = 0; tess.texCoords[tess.numVertexes][0][1] = 0; tess.vertexColors[tess.numVertexes][0] = 255; tess.vertexColors[tess.numVertexes][1] = 255; tess.vertexColors[tess.numVertexes][2] = 255; tess.numVertexes++; copyv3(origin, temp); addv3(temp, vec1, temp); subv3(temp, vec2, temp); copyv3(temp, tess.xyz[tess.numVertexes]); tess.texCoords[tess.numVertexes][0][0] = 0; tess.texCoords[tess.numVertexes][0][1] = 1; tess.vertexColors[tess.numVertexes][0] = 255; tess.vertexColors[tess.numVertexes][1] = 255; tess.vertexColors[tess.numVertexes][2] = 255; tess.numVertexes++; copyv3(origin, temp); addv3(temp, vec1, temp); addv3(temp, vec2, temp); copyv3(temp, tess.xyz[tess.numVertexes]); tess.texCoords[tess.numVertexes][0][0] = 1; tess.texCoords[tess.numVertexes][0][1] = 1; tess.vertexColors[tess.numVertexes][0] = 255; tess.vertexColors[tess.numVertexes][1] = 255; tess.vertexColors[tess.numVertexes][2] = 255; tess.numVertexes++; copyv3(origin, temp); subv3(temp, vec1, temp); addv3(temp, vec2, temp); copyv3(temp, tess.xyz[tess.numVertexes]); tess.texCoords[tess.numVertexes][0][0] = 1; tess.texCoords[tess.numVertexes][0][1] = 0; tess.vertexColors[tess.numVertexes][0] = 255; tess.vertexColors[tess.numVertexes][1] = 255; tess.vertexColors[tess.numVertexes][2] = 255; 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; RB_EndSurface(); /* back to normal depth range */ qglDepthRange(0.0, 1.0); }
void R_DrawSkyBox (void) { int i; #if 0 qglEnable (GL_BLEND); GL_TexEnv( GL_MODULATE ); qglColor4f (1,1,1,0.5); qglDisable (GL_DEPTH_TEST); #endif // jkrige - skybox qglDisable (GL_DEPTH_TEST); /*if (skyrotate) { // check for no sky at all for (i=0 ; i<6 ; i++) if (skymins[0][i] < skymaxs[0][i] && skymins[1][i] < skymaxs[1][i]) break; if (i == 6) return; // nothing visible }*/ // jkrige - skybox qglPushMatrix (); qglTranslatef (r_origin[0], r_origin[1], r_origin[2]); qglRotatef (r_newrefdef.time * skyrotate, skyaxis[0], skyaxis[1], skyaxis[2]); for (i=0 ; i<6 ; i++) { // jkrige - skybox /*if (skyrotate) { // hack, forces full sky to draw when rotating skymins[0][i] = -1; skymins[1][i] = -1; skymaxs[0][i] = 1; skymaxs[1][i] = 1; } if (skymins[0][i] >= skymaxs[0][i] || skymins[1][i] >= skymaxs[1][i]) continue;*/ // jkrige - skybox GL_Bind (sky_images[skytexorder[i]]->texnum); qglBegin (GL_QUADS); // jkrige - skybox MakeSkyVec (-1, -1, i); MakeSkyVec (-1, 1, i); MakeSkyVec (1, 1, i); MakeSkyVec (1, -1, i); //MakeSkyVec (skymins[0][i], skymins[1][i], i); //MakeSkyVec (skymins[0][i], skymaxs[1][i], i); //MakeSkyVec (skymaxs[0][i], skymaxs[1][i], i); //MakeSkyVec (skymaxs[0][i], skymins[1][i], i); // jkrige - skybox qglEnd (); } qglPopMatrix (); #if 0 glDisable (GL_BLEND); glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); glColor4f (1,1,1,0.5); glEnable (GL_DEPTH_TEST); #endif // jkrige - skybox qglEnable (GL_DEPTH_TEST); // jkrige - skybox }
/* ============== RB_DrawSun (SA) FIXME: sun should render behind clouds, so passing dark areas cover it up ============== */ void RB_DrawSun( void ) { float size; float dist; vec3_t origin, vec1, vec2; vec3_t temp; byte color[4]; if ( !tr.sunShader ) { return; } if ( !backEnd.skyRenderedThisView ) { return; } if ( !r_drawSun->integer ) { return; } qglLoadMatrixf( backEnd.viewParms.world.modelMatrix ); qglTranslatef( backEnd.viewParms.or.origin[0], backEnd.viewParms.or.origin[1], backEnd.viewParms.or.origin[2] ); dist = backEnd.viewParms.zFar / 1.75; // div sqrt(3) // (SA) shrunk the size of the sun size = dist * 0.2; 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 qglDepthRange( 1.0, 1.0 ); color[0] = color[1] = color[2] = color[3] = 255; // (SA) simpler sun drawing RB_BeginSurface( tr.sunShader, tess.fogNum ); RB_AddQuadStamp( origin, vec1, vec2, color ); /* VectorCopy( origin, temp ); VectorSubtract( temp, vec1, temp ); VectorSubtract( temp, vec2, temp ); VectorCopy( temp, tess.xyz[tess.numVertexes] ); tess.texCoords[tess.numVertexes][0][0] = 0; tess.texCoords[tess.numVertexes][0][1] = 0; tess.vertexColors[tess.numVertexes][0] = 255; tess.vertexColors[tess.numVertexes][1] = 255; tess.vertexColors[tess.numVertexes][2] = 255; tess.numVertexes++; VectorCopy( origin, temp ); VectorAdd( temp, vec1, temp ); VectorSubtract( temp, vec2, temp ); VectorCopy( temp, tess.xyz[tess.numVertexes] ); tess.texCoords[tess.numVertexes][0][0] = 0; tess.texCoords[tess.numVertexes][0][1] = 1; tess.vertexColors[tess.numVertexes][0] = 255; tess.vertexColors[tess.numVertexes][1] = 255; tess.vertexColors[tess.numVertexes][2] = 255; tess.numVertexes++; VectorCopy( origin, temp ); VectorAdd( temp, vec1, temp ); VectorAdd( temp, vec2, temp ); VectorCopy( temp, tess.xyz[tess.numVertexes] ); tess.texCoords[tess.numVertexes][0][0] = 1; tess.texCoords[tess.numVertexes][0][1] = 1; tess.vertexColors[tess.numVertexes][0] = 255; tess.vertexColors[tess.numVertexes][1] = 255; tess.vertexColors[tess.numVertexes][2] = 255; tess.numVertexes++; VectorCopy( origin, temp ); VectorSubtract( temp, vec1, temp ); VectorAdd( temp, vec2, temp ); VectorCopy( temp, tess.xyz[tess.numVertexes] ); tess.texCoords[tess.numVertexes][0][0] = 1; tess.texCoords[tess.numVertexes][0][1] = 0; tess.vertexColors[tess.numVertexes][0] = 255; tess.vertexColors[tess.numVertexes][1] = 255; tess.vertexColors[tess.numVertexes][2] = 255; 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; */ RB_EndSurface(); if ( r_drawSun->integer > 1 ) { // draw flare effect // (SA) FYI: This is cheezy and was only a test so far. // If we decide to use the flare business I will /definatly/ improve all this // get a point a little closer dist = dist * 0.7; VectorScale( tr.sunDirection, dist, origin ); // and make the flare a little smaller VectorScale( vec1, 0.5f, vec1 ); VectorScale( vec2, 0.5f, vec2 ); // add the vectors to give an 'off angle' result VectorAdd( tr.sunDirection, backEnd.viewParms.or.axis[0], temp ); VectorNormalize( temp ); // amplify the result origin[0] += temp[0] * 500.0; origin[1] += temp[1] * 500.0; origin[2] += temp[2] * 500.0; // (SA) FIXME: todo: flare effect should render last (on top of everything else) and only when sun is in view (sun moving out of camera past degree n should start to cause flare dimming until view angle to sun is off by angle n + x. // draw the flare RB_BeginSurface( tr.sunflareShader[0], tess.fogNum ); RB_AddQuadStamp( origin, vec1, vec2, color ); RB_EndSurface(); } // back to normal depth range qglDepthRange( 0.0, 1.0 ); }
/* ================ RB_StageIteratorSky All of the visible sky triangles are in tess Other things could be stuck in here, like birds in the sky, etc ================ */ void RB_StageIteratorSky( void ) { if ( r_fastsky->integer ) { return; } // when portal sky exists, only render skybox for the portal sky scene if ( skyboxportal && !( backEnd.refdef.rdflags & RDF_SKYBOXPORTAL ) ) { return; } // does the current fog require fastsky? if ( backEnd.viewParms.glFog.registered ) { if ( !backEnd.viewParms.glFog.drawsky ) { return; } } else if ( glfogNum > FOG_NONE ) { if ( !glfogsettings[FOG_CURRENT].drawsky ) { return; } } backEnd.refdef.rdflags |= RDF_DRAWINGSKY; // go through all the polygons and project them onto // the sky box to see which blocks on each side need // to be drawn RB_ClipSkyPolygons( &tess ); // r_showsky will let all the sky blocks be drawn in // front of everything to allow developers to see how // much sky is getting sucked in if ( r_showsky->integer ) { qglDepthRange( 0.0, 0.0 ); } else { qglDepthRange( 1.0, 1.0 ); } // draw the outer skybox if ( tess.shader->sky.outerbox[0] && tess.shader->sky.outerbox[0] != tr.defaultImage ) { qglColor3f( tr.identityLight, tr.identityLight, tr.identityLight ); qglPushMatrix(); GL_State( 0 ); qglTranslatef( backEnd.viewParms.or.origin[0], backEnd.viewParms.or.origin[1], backEnd.viewParms.or.origin[2] ); DrawSkyBox( tess.shader ); qglPopMatrix(); } // generate the vertexes for all the clouds, which will be drawn // by the generic shader routine R_BuildCloudData( &tess ); RB_StageIteratorGeneric(); // draw the inner skybox // Rafael - drawing inner skybox if ( tess.shader->sky.innerbox[0] && tess.shader->sky.innerbox[0] != tr.defaultImage ) { qglColor3f( tr.identityLight, tr.identityLight, tr.identityLight ); qglPushMatrix(); GL_State( 0 ); qglTranslatef( backEnd.viewParms.or.origin[0], backEnd.viewParms.or.origin[1], backEnd.viewParms.or.origin[2] ); DrawSkyBoxInner( tess.shader ); qglPopMatrix(); } // Rafael - end // back to normal depth range qglDepthRange( 0.0, 1.0 ); backEnd.refdef.rdflags &= ~RDF_DRAWINGSKY; // note that sky was drawn so we will draw a sun later backEnd.skyRenderedThisView = qtrue; }
void CCamWnd::Cam_Draw() { brush_t *brush; face_t *face; float screenaspect; float yfov; double start, end; int i; /* FILE *f = fopen("g:/nardo/raduffy/editorhack.dat", "w"); if (f != NULL) { fwrite(&m_Camera.origin[0], sizeof(float), 1, f); fwrite(&m_Camera.origin[1], sizeof(float), 1, f); fwrite(&m_Camera.origin[2], sizeof(float), 1, f); fwrite(&m_Camera.angles[PITCH], sizeof(float), 1, f); fwrite(&m_Camera.angles[YAW], sizeof(float), 1, f); fclose(f); } */ if (!active_brushes.next) return; // not valid yet if (m_Camera.timing) start = Sys_DoubleTime (); // // clear // QE_CheckOpenGLForErrors(); qglViewport(0, 0, m_Camera.width, m_Camera.height); qglScissor(0, 0, m_Camera.width, m_Camera.height); qglClearColor (g_qeglobals.d_savedinfo.colors[COLOR_CAMERABACK][0], g_qeglobals.d_savedinfo.colors[COLOR_CAMERABACK][1], g_qeglobals.d_savedinfo.colors[COLOR_CAMERABACK][2], 0); qglClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // // set up viewpoint // vec5_t lightPos; if (g_PrefsDlg.m_bGLLighting) { qglEnable(GL_LIGHTING); //qglEnable(GL_LIGHT0); lightPos[0] = lightPos[1] = lightPos[2] = 3.5; lightPos[3] = 1.0; qglLightModelfv(GL_LIGHT_MODEL_AMBIENT, lightPos); //qglLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, GL_TRUE); //lightPos[0] = lightPos[1] = lightPos[2] = 3.5; //qglLightfv(GL_LIGHT0, GL_AMBIENT, lightPos); } else { qglDisable(GL_LIGHTING); } qglMatrixMode(GL_PROJECTION); qglLoadIdentity (); screenaspect = (float)m_Camera.width / m_Camera.height; yfov = 2*atan((float)m_Camera.height / m_Camera.width)*180/Q_PI; qgluPerspective (yfov, screenaspect, 2, 8192); qglRotatef (-90, 1, 0, 0); // put Z going up qglRotatef (90, 0, 0, 1); // put Z going up qglRotatef (m_Camera.angles[0], 0, 1, 0); qglRotatef (-m_Camera.angles[1], 0, 0, 1); qglTranslatef (-m_Camera.origin[0], -m_Camera.origin[1], -m_Camera.origin[2]); Cam_BuildMatrix (); //if (m_Camera.draw_mode == cd_light) //{ // if (g_PrefsDlg.m_bGLLighting) // { // VectorCopy(m_Camera.origin, lightPos); // lightPos[3] = 1; // qglLightfv(GL_LIGHT0, GL_POSITION, lightPos); // } //} InitCull (); // // draw stuff // GLfloat lAmbient[] = {1.0, 1.0, 1.0, 1.0}; switch (m_Camera.draw_mode) { case cd_wire: qglPolygonMode (GL_FRONT_AND_BACK, GL_LINE); qglDisable(GL_TEXTURE_2D); qglDisable(GL_TEXTURE_1D); qglDisable(GL_BLEND); qglDisable(GL_DEPTH_TEST); qglColor3f(1.0, 1.0, 1.0); // qglEnable (GL_LINE_SMOOTH); break; case cd_solid: qglCullFace(GL_FRONT); qglEnable(GL_CULL_FACE); qglShadeModel (GL_FLAT); qglPolygonMode (GL_FRONT_AND_BACK, GL_FILL); qglDisable(GL_TEXTURE_2D); qglDisable(GL_BLEND); qglEnable(GL_DEPTH_TEST); qglDepthFunc (GL_LEQUAL); break; case cd_texture: qglCullFace(GL_FRONT); qglEnable(GL_CULL_FACE); qglShadeModel (GL_FLAT); qglPolygonMode (GL_FRONT_AND_BACK, GL_FILL); qglEnable(GL_TEXTURE_2D); qglTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); qglDisable(GL_BLEND); qglEnable(GL_DEPTH_TEST); qglDepthFunc (GL_LEQUAL); break; case cd_blend: qglCullFace(GL_FRONT); qglEnable(GL_CULL_FACE); qglShadeModel (GL_FLAT); qglPolygonMode (GL_FRONT_AND_BACK, GL_FILL); qglEnable(GL_TEXTURE_2D); qglTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); qglDisable(GL_DEPTH_TEST); qglEnable (GL_BLEND); qglBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); break; } qglMatrixMode(GL_TEXTURE); m_nNumTransBrushes = 0; for (brush = active_brushes.next ; brush != &active_brushes ; brush=brush->next) { //DrawLightRadius(brush); if (CullBrush (brush)) continue; if (FilterBrush (brush)) continue; if ((brush->brush_faces->texdef.flags & (SURF_TRANS33 | SURF_TRANS66)) || (brush->brush_faces->d_texture->bFromShader && brush->brush_faces->d_texture->fTrans != 1.0)) { m_TransBrushes [ m_nNumTransBrushes++ ] = brush; } else { //-- if (brush->patchBrush) //-- m_TransBrushes [ m_nNumTransBrushes++ ] = brush; //-- else Brush_Draw(brush); } } if (g_PrefsDlg.m_bGLLighting) { qglDisable (GL_LIGHTING); } // //qglDepthMask ( 0 ); // Don't write to depth buffer qglEnable ( GL_BLEND ); qglBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); for ( i = 0; i < m_nNumTransBrushes; i++ ) Brush_Draw (m_TransBrushes[i]); //qglDepthMask ( 1 ); // Ok, write now qglMatrixMode(GL_PROJECTION); // // now draw selected brushes // if (g_PrefsDlg.m_bGLLighting) { qglEnable (GL_LIGHTING); } qglTranslatef (g_qeglobals.d_select_translate[0], g_qeglobals.d_select_translate[1], g_qeglobals.d_select_translate[2]); qglMatrixMode(GL_TEXTURE); brush_t* pList = (g_bClipMode && g_pSplitList) ? g_pSplitList : &selected_brushes; // draw normally for (brush = pList->next ; brush != pList ; brush=brush->next) { //DrawLightRadius(brush); //if (brush->patchBrush && g_qeglobals.d_select_mode == sel_curvepoint) // continue; Brush_Draw(brush); } // blend on top qglMatrixMode(GL_PROJECTION); qglDisable (GL_LIGHTING); qglColor4f(1.0, 0.0, 0.0, 0.3); qglEnable (GL_BLEND); qglPolygonMode (GL_FRONT_AND_BACK, GL_FILL); qglBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); qglDisable (GL_TEXTURE_2D); for (brush = pList->next ; brush != pList ; brush=brush->next) { if ( (brush->patchBrush && g_qeglobals.d_select_mode == sel_curvepoint) || (brush->terrainBrush && g_qeglobals.d_select_mode == sel_terrainpoint) ) continue; for (face=brush->brush_faces ; face ; face=face->next) Face_Draw( face ); } int nCount = g_ptrSelectedFaces.GetSize(); if (nCount > 0) { for (int i = 0; i < nCount; i++) { face_t *selFace = reinterpret_cast<face_t*>(g_ptrSelectedFaces.GetAt(i)); Face_Draw(selFace); } } // non-zbuffered outline qglDisable (GL_BLEND); qglDisable (GL_DEPTH_TEST); qglPolygonMode (GL_FRONT_AND_BACK, GL_LINE); qglColor3f (1, 1, 1); for (brush = pList->next ; brush != pList ; brush=brush->next) { if (g_qeglobals.dontDrawSelectedOutlines || (brush->patchBrush && g_qeglobals.d_select_mode == sel_curvepoint) || (brush->terrainBrush && g_qeglobals.d_select_mode == sel_terrainpoint)) continue; for (face=brush->brush_faces ; face ; face=face->next) Face_Draw( face ); } // edge / vertex flags if (g_qeglobals.d_select_mode == sel_vertex) { qglPointSize (4); qglColor3f (0,1,0); qglBegin (GL_POINTS); for (i=0 ; i<g_qeglobals.d_numpoints ; i++) qglVertex3fv (g_qeglobals.d_points[i]); qglEnd (); qglPointSize (1); } else if (g_qeglobals.d_select_mode == sel_edge) { float *v1, *v2; qglPointSize (4); qglColor3f (0,0,1); qglBegin (GL_POINTS); for (i=0 ; i<g_qeglobals.d_numedges ; i++) { v1 = g_qeglobals.d_points[g_qeglobals.d_edges[i].p1]; v2 = g_qeglobals.d_points[g_qeglobals.d_edges[i].p2]; qglVertex3f ( (v1[0]+v2[0])*0.5,(v1[1]+v2[1])*0.5,(v1[2]+v2[2])*0.5); } qglEnd (); qglPointSize (1); } g_splineList->draw(static_cast<qboolean>(g_qeglobals.d_select_mode == sel_addpoint || g_qeglobals.d_select_mode == sel_editpoint)); if (g_qeglobals.selectObject && (g_qeglobals.d_select_mode == sel_addpoint || g_qeglobals.d_select_mode == sel_editpoint)) { g_qeglobals.selectObject->drawSelection(); } // // draw pointfile // qglEnable(GL_DEPTH_TEST); DrawPathLines (); if (g_qeglobals.d_pointfile_display_list) { Pointfile_Draw(); // glCallList (g_qeglobals.d_pointfile_display_list); } // bind back to the default texture so that we don't have problems // elsewhere using/modifying texture maps between contexts qglBindTexture( GL_TEXTURE_2D, 0 ); #if 0 // area selection hack if (g_qeglobals.d_select_mode == sel_area) { qglEnable (GL_BLEND); qglBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); qglColor4f(0.0, 0.0, 1.0, 0.25); qglPolygonMode (GL_FRONT_AND_BACK, GL_FILL); qglRectfv(g_qeglobals.d_vAreaTL, g_qeglobals.d_vAreaBR); qglDisable (GL_BLEND); } #endif qglFinish(); QE_CheckOpenGLForErrors(); // Sys_EndWait(); if (m_Camera.timing) { end = Sys_DoubleTime (); Sys_Printf ("Camera: %i ms\n", (int)(1000*(end-start))); } }
void GL_DrawBspModel( mmodel_t *model ) { mface_t *face; int count, mask = 0; vec3_t bounds[2]; vec_t dot; vec3_t transformed, temp; entity_t *ent = glr.ent; glCullResult_t cull; if( glr.entrotated ) { cull = GL_CullSphere( ent->origin, model->radius ); if( cull == CULL_OUT ) { c.spheresCulled++; return; } if( cull == CULL_CLIP ) { VectorCopy( model->mins, bounds[0] ); VectorCopy( model->maxs, bounds[1] ); cull = GL_CullLocalBox( ent->origin, bounds ); if( cull == CULL_OUT ) { c.rotatedBoxesCulled++; return; } } VectorSubtract( glr.fd.vieworg, ent->origin, temp ); transformed[0] = DotProduct( temp, glr.entaxis[0] ); transformed[1] = DotProduct( temp, glr.entaxis[1] ); transformed[2] = DotProduct( temp, glr.entaxis[2] ); } else { VectorAdd( model->mins, ent->origin, bounds[0] ); VectorAdd( model->maxs, ent->origin, bounds[1] ); cull = GL_CullBox( bounds ); if( cull == CULL_OUT ) { c.boxesCulled++; return; } VectorSubtract( glr.fd.vieworg, ent->origin, transformed ); if( VectorEmpty( ent->origin ) && model->drawframe != glr.drawframe ) { mask = SURF_TRANS33|SURF_TRANS66; } } // protect against infinite loop if the same inline model // with alpha faces is referenced by multiple entities model->drawframe = glr.drawframe; #if USE_DLIGHTS glr.dlightframe++; if( gl_dynamic->integer == 1 ) { GL_TransformLights( model ); } #endif if( gl_dynamic->integer ) { GL_BeginLights(); } qglPushMatrix(); qglTranslatef( ent->origin[0], ent->origin[1], ent->origin[2] ); if( glr.entrotated ) { qglRotatef( ent->angles[YAW], 0, 0, 1 ); qglRotatef( ent->angles[PITCH], 0, 1, 0 ); qglRotatef( ent->angles[ROLL], 1, 0, 0 ); } // draw visible faces // FIXME: go by headnode instead? face = model->firstface; count = model->numfaces; while( count-- ) { dot = PlaneDiffFast( transformed, face->plane ); if( BSP_CullFace( face, dot ) ) { c.facesCulled++; } else if( face->drawflags & mask ) { // FIXME: alpha faces are not supported // on rotated or translated inline models GL_AddAlphaFace( face ); } else { GL_AddSolidFace( face ); } face++; } if( gl_dynamic->integer ) { GL_EndLights(); } GL_DrawSolidFaces(); qglPopMatrix(); }
void CRainSystem::Render(void) { int i; SParticle *item; vec4_t forward, down, left; vec3_t pos; // float percent; float radius; CWorldEffectsSystem::Render(); if (mFadeAlpha <= 0.0) { return; } VectorScale(backEnd.viewParms.or.axis[0], 1, forward); // forward VectorScale(backEnd.viewParms.or.axis[1], 0.2f, left); // left down[0] = 0 - mWindDirection[0] * mRainHeight * mWindAngle; down[1] = 0 - mWindDirection[1] * mRainHeight * mWindAngle; down[2] = -mRainHeight; GL_Bind(mImage); GL_State(GLS_ALPHA); qglEnable(GL_TEXTURE_2D); qglDisable(GL_CULL_FACE); qglMatrixMode(GL_MODELVIEW); qglPushMatrix(); qglTranslatef (backEnd.viewParms.or.origin[0], backEnd.viewParms.or.origin[1], backEnd.viewParms.or.origin[2]); item = mRainList; qglBegin(GL_TRIANGLES ); for(i=mMaxRain;i;i--) { /* percent = (item->pos[1] -(-20.0)) / (20.0 - (-20.0)); percent *= forward[2]; if (percent < 0.0) { radius = 10 * (percent + 1.0); } else { radius = 10 * (1.0 - percent); }*/ radius = item->pos[1]; if (item->pos[2] < 0.0) { // radius *= 1.0 - (item->pos[2] / 40.0); float alpha = mAlpha * (item->pos[1] / -item->pos[2]); if (alpha > mAlpha) { alpha = mAlpha; } qglColor4f(1.0, 1.0, 1.0, alpha * mFadeAlpha); } else { qglColor4f(1.0, 1.0, 1.0, mAlpha * mFadeAlpha); // radius *= 1.0 + (item->pos[2] / 20.0); } pos[0] = sin(item->pos[0]) * radius + (item->pos[2] * mWindDirection[0] * mWindAngle); pos[1] = cos(item->pos[0]) * radius + (item->pos[2] * mWindDirection[1] * mWindAngle); pos[2] = item->pos[2]; qglTexCoord2f(1.0, 0.0); qglVertex3f(pos[0], pos[1], pos[2]); qglTexCoord2f(0.0, 0.0); qglVertex3f(pos[0] + left[0], pos[1] + left[1], pos[2] + left[2]); qglTexCoord2f(0.0, 1.0); qglVertex3f(pos[0] + down[0] + left[0], pos[1] + down[1] + left[1], pos[2] + down[2] + left[2]); item++; } qglEnd(); qglEnable(GL_CULL_FACE); qglPopMatrix(); }
/* ============= RB_DrawRotatePic2 ============= */ const void *RB_RotatePic2 ( const void *data ) { const rotatePicCommand_t *cmd; image_t *image; shader_t *shader; cmd = (const rotatePicCommand_t *)data; shader = cmd->shader; if ( shader->numUnfoggedPasses ) { image = &shader->stages[0].bundle[0].image[0]; if ( image ) { if ( !backEnd.projection2D ) { RB_SetGL2D(); } // Get our current blend mode, etc. GL_State( shader->stages[0].stateBits ); qglColor4ubv( backEnd.color2D ); qglPushMatrix(); // rotation point is going to be around the center of the passed in coordinates qglTranslatef( cmd->x, cmd->y, 0 ); qglRotatef( cmd->a, 0.0, 0.0, 1.0 ); GL_Bind( image ); #ifdef _XBOX qglBeginEXT( GL_QUADS, 4, 0, 0, 4, 0); #else qglBegin( GL_QUADS ); #endif qglTexCoord2f( cmd->s1, cmd->t1); qglVertex2f( -cmd->w * 0.5f, -cmd->h * 0.5f ); qglTexCoord2f( cmd->s2, cmd->t1 ); qglVertex2f( cmd->w * 0.5f, -cmd->h * 0.5f ); qglTexCoord2f( cmd->s2, cmd->t2 ); qglVertex2f( cmd->w * 0.5f, cmd->h * 0.5f ); qglTexCoord2f( cmd->s1, cmd->t2 ); qglVertex2f( -cmd->w * 0.5f, cmd->h * 0.5f ); qglEnd(); qglPopMatrix(); // Hmmm, this is not too cool GL_State( GLS_DEPTHTEST_DISABLE | GLS_SRCBLEND_SRC_ALPHA | GLS_DSTBLEND_ONE_MINUS_SRC_ALPHA ); } } return (const void *)(cmd + 1); }
/* ================ RB_StageIteratorSky All of the visible sky triangles are in tess Other things could be stuck in here, like birds in the sky, etc ================ */ void RB_StageIteratorSky( void ) { if ( g_bRenderGlowingObjects ) return; if ( r_fastsky->integer ) { return; } if (skyboxportal && !(backEnd.refdef.rdflags & RDF_SKYBOXPORTAL)) { return; } // go through all the polygons and project them onto // the sky box to see which blocks on each side need // to be drawn RB_ClipSkyPolygons( &tess ); // r_showsky will let all the sky blocks be drawn in // front of everything to allow developers to see how // much sky is getting sucked in if ( r_showsky->integer ) { qglDepthRange( 0.0, 0.0 ); } else { #ifdef _XBOX qglDepthRange( 0.99, 1.0 ); #else qglDepthRange( 1.0, 1.0 ); #endif } // draw the outer skybox if ( tess.shader->sky->outerbox[0] && tess.shader->sky->outerbox[0] != tr.defaultImage ) { qglColor3f( tr.identityLight, tr.identityLight, tr.identityLight ); qglPushMatrix (); GL_State( 0 ); qglTranslatef (backEnd.viewParms.ori.origin[0], backEnd.viewParms.ori.origin[1], backEnd.viewParms.ori.origin[2]); DrawSkyBox( tess.shader ); qglPopMatrix(); } // generate the vertexes for all the clouds, which will be drawn // by the generic shader routine R_BuildCloudData( &tess ); if (tess.numIndexes && tess.numVertexes) { RB_StageIteratorGeneric(); } // draw the inner skybox // back to normal depth range qglDepthRange( 0.0, 1.0 ); // note that sky was drawn so we will draw a sun later backEnd.skyRenderedThisView = qtrue; }