Esempio n. 1
0
void GL_DrawWorld( void ) { 
    GL_MarkLeaves();

#if USE_DLIGHTS
    glr.dlightframe++;
    if( gl_dynamic->integer == 1 ) {
        GL_MarkLights();
    }
#endif
    
    R_ClearSkyBox();

    if( gl_dynamic->integer ) {
        GL_BeginLights();
    }

    GL_WorldNode_r( gl_static.world.cache->nodes,
        gl_cull_nodes->integer ? NODE_CLIPPED : NODE_UNCLIPPED );

    if( gl_dynamic->integer ) {
        GL_EndLights();
    }

    GL_DrawSolidFaces();

    R_DrawSkyBox();
}
Esempio n. 2
0
/*
* R_DrawSkySurf
*/
void R_DrawSkySurf( const entity_t *e, const shader_t *shader, const mfog_t *fog, const portalSurface_t *portalSurface, 
	                unsigned int shadowBits, drawSurfaceSky_t *drawSurf ) {
	int i;
	int numVisSides;
	visSkySide_t visSkySides[6];
	vec3_t mins, maxs;
	int umin, umax, vmin, vmax;
	bool skyportal = portalSurface != NULL && portalSurface->skyPortal;
	skydome_t *skydome = rsh.worldBrushModel->skydome;

	if( !skydome ) {
		return;
	}
	if( skyportal && !fog ) {
		return;
	}

	numVisSides = 0;
	ClearBounds( mins, maxs );

	memset( visSkySides, 0, sizeof( visSkySides ) );

	for( i = 0; i < 6; i++ ) {
		if( drawSurf->skyMins[0][i] >= drawSurf->skyMaxs[0][i] ||
			drawSurf->skyMins[1][i] >= drawSurf->skyMaxs[1][i] ) {
			continue;
		}

		// increase the visible sides counter
		numVisSides++;

		umin = (int)( ( drawSurf->skyMins[0][i] + 1.0f ) * 0.5f * (float)( SIDE_SIZE - 1 ) );
		umax = (int)( ( drawSurf->skyMaxs[0][i] + 1.0f ) * 0.5f * (float)( SIDE_SIZE - 1 ) ) + 1;
		vmin = (int)( ( drawSurf->skyMins[1][i] + 1.0f ) * 0.5f * (float)( SIDE_SIZE - 1 ) );
		vmax = (int)( ( drawSurf->skyMaxs[1][i] + 1.0f ) * 0.5f * (float)( SIDE_SIZE - 1 ) ) + 1;

		clamp( umin, 0, SIDE_SIZE - 1 );
		clamp( umax, 0, SIDE_SIZE - 1 );
		clamp( vmin, 0, SIDE_SIZE - 1 );
		clamp( vmax, 0, SIDE_SIZE - 1 );

		visSkySides[i].index = i;
		visSkySides[i].firstVert = vmin * SIDE_SIZE + umin;
		visSkySides[i].numVerts = ( vmax - vmin ) * SIDE_SIZE + ( umax - umin ) + 1;
		visSkySides[i].firstElem = ( vmin * ( SIDE_SIZE - 2 ) + umin ) * 6;
		visSkySides[i].numElems = ( ( vmax - vmin ) * ( SIDE_SIZE - 2 ) + ( umax - umin ) ) * 6;

		clamp( visSkySides[i].firstVert, 0, POINTS_LEN - 1 );
		clamp( visSkySides[i].numVerts, 0, POINTS_LEN );

		clamp( visSkySides[i].firstElem, 0, ELEM_LEN - 1 );
		clamp( visSkySides[i].numElems, 0, ELEM_LEN );

		skydome->meshes[i].numElems = visSkySides[i].numElems;
	}

	// no sides are truly visible, ignore
	if( !numVisSides ) {
		return;
	}

	// center skydome on camera to give the illusion of a larger space
	rsc.skyent->scale = shader->skyHeight;
	VectorCopy( rn.viewOrigin, rsc.skyent->origin );
	R_TransformForEntity( rsc.skyent );

	if( skyportal ) {
		// render fake fogged skybox
		R_DrawSkyBox( skydome, visSkySides, rsh.emptyFogShader, shader, fog, drawSurf );
	} else {
		if( shader->skyboxImages[0] ) {
			R_DrawSkyBox( skydome, visSkySides, rsh.skyShader, shader, fog, drawSurf );
		} else {
			R_DrawBlackBottom( skydome, visSkySides, fog, drawSurf );
		}

		if( shader->numpasses ) {
			for( i = 0; i < 5; i++ ) {
				const visSkySide_t *visSide = visSkySides + i;

				if( drawSurf->skyMins[0][i] >= drawSurf->skyMaxs[0][i] ||
					drawSurf->skyMins[1][i] >= drawSurf->skyMaxs[1][i] ) {
					continue;
				}

				RB_BindShader( rsc.skyent, shader, NULL ); // must be called for every side to reset backend state

				RB_BindVBO( skydome->sphereVbos[i]->index, GL_TRIANGLES );

				RB_DrawElements( visSide->firstVert, visSide->numVerts, visSide->firstElem, visSide->numElems, 0, 0, 0, 0 );
			}
		}
	}

	R_TransformForEntity( e );
}
Esempio n. 3
0
/*
 * @brief Main entry point for drawing the scene (world and entities).
 */
void R_DrawView(void) {

	R_UpdateFrustum();

	R_UpdateVis();

	R_MarkBspSurfaces();

	R_EnableFog(true);

	R_DrawSkyBox();

	// wait for the client to populate our lights array
	Thread_Wait(&r_view.thread);

	// now dispatch another thread to cull entities while we draw the world
	r_view.thread = Thread_Create(R_CullEntities, NULL);

	R_MarkLights();

	const r_sorted_bsp_surfaces_t *surfs = r_model_state.world->bsp->sorted_surfaces;

	R_DrawOpaqueBspSurfaces(&surfs->opaque);

	R_DrawOpaqueWarpBspSurfaces(&surfs->opaque_warp);

	R_DrawAlphaTestBspSurfaces(&surfs->alpha_test);

	R_EnableBlend(true);

	R_DrawBackBspSurfaces(&surfs->back);

	R_DrawMaterialBspSurfaces(&surfs->material);

	R_DrawFlareBspSurfaces(&surfs->flare);

	R_EnableBlend(false);

	R_DrawBspNormals();

	// ensure the thread has finished culling entities
	Thread_Wait(&r_view.thread);

	// now dispatch another thread to update particles while we draw entities
	r_view.thread = Thread_Create(R_UpdateParticles, NULL);

	R_DrawEntities();

	R_EnableBlend(true);

	R_DrawBspLights();

	R_DrawBlendBspSurfaces(&surfs->blend);

	R_DrawBlendWarpBspSurfaces(&surfs->blend_warp);

	// ensure the thread has finished updating particles
	Thread_Wait(&r_view.thread);

	R_DrawParticles();

	R_EnableFog(false);

	R_DrawCoronas();

	R_DrawBspLeafs();

	R_EnableBlend(false);

	R_ResetArrayState();
}
Esempio n. 4
0
/*
* R_DrawSkySurf
*/
qboolean R_DrawSkySurf( const entity_t *e, const shader_t *shader, const mfog_t *fog, drawSurfaceBSP_t *drawSurf )
{
	int i;
	int numVisSides;
	visSkySide_t visSkySides[6];
	vec3_t mins, maxs;
	int umin, umax, vmin, vmax;
	entity_t skyent;
	refdef_t *rd = &rn.refdef;
	skydome_t *skydome = r_worldbrushmodel->skydome;

	if( !skydome )
		return qfalse;

	numVisSides = 0;
	ClearBounds( mins, maxs );

	memset( visSkySides, 0, sizeof( visSkySides ) );

	for( i = 0; i < 6; i++ )
	{
		if( rn.skyMins[0][i] >= rn.skyMaxs[0][i] ||
			rn.skyMins[1][i] >= rn.skyMaxs[1][i] )
			continue;

		// increase the visible sides counter
		numVisSides++;

		umin = (int)( ( rn.skyMins[0][i]+1.0f )*0.5f*(float)( SIDE_SIZE-1 ) );
		umax = (int)( ( rn.skyMaxs[0][i]+1.0f )*0.5f*(float)( SIDE_SIZE-1 ) ) + 1;
		vmin = (int)( ( rn.skyMins[1][i]+1.0f )*0.5f*(float)( SIDE_SIZE-1 ) );
		vmax = (int)( ( rn.skyMaxs[1][i]+1.0f )*0.5f*(float)( SIDE_SIZE-1 ) ) + 1;

		clamp( umin, 0, SIDE_SIZE-1 );
		clamp( umax, 0, SIDE_SIZE-1 );
		clamp( vmin, 0, SIDE_SIZE-1 );
		clamp( vmax, 0, SIDE_SIZE-1 );

		visSkySides[i].index = i;
		visSkySides[i].firstVert = vmin * SIDE_SIZE + umin;
		visSkySides[i].numVerts = (vmax - vmin) * SIDE_SIZE + (umax - umin);
		visSkySides[i].firstElem = (vmin * (SIDE_SIZE-1) + umin) * 6;
		visSkySides[i].numElems = ((vmax - vmin) * (SIDE_SIZE-1) + (umax - umin)) * 6;

		AddPointToBounds( skydome->meshes[i].xyzArray[vmin*SIDE_SIZE+umin], mins, maxs );
		AddPointToBounds( skydome->meshes[i].xyzArray[vmax*SIDE_SIZE+umax], mins, maxs );

		skydome->meshes[i].numElems = visSkySides[i].numElems;
	}

	// no sides are truly visible, ignore
	if( !numVisSides )
		return qfalse;

	VectorAdd( mins, rn.viewOrigin, mins );
	VectorAdd( maxs, rn.viewOrigin, maxs );

	if( rd->rdflags & RDF_SKYPORTALINVIEW ) {
		R_DrawSkyPortal( e, &rd->skyportal, mins, maxs );
		return qfalse;
	}

	// center skydome on camera to give the illusion of a larger space
	skyent = *rsc.worldent;
	skyent.scale = shader->skyHeight;
	VectorCopy( rn.viewOrigin, skyent.origin );
	R_TransformForEntity( &skyent );

	if( shader->skyboxImages[0] )
		R_DrawSkyBox( skydome, visSkySides, shader );
	else
		R_DrawBlackBottom( skydome, visSkySides );

	if( shader->numpasses )
	{
		RB_BindShader( rsc.worldent, shader, rn.skyFog );

		for( i = 0; i < 5; i++ )
		{
			const visSkySide_t *visSide = visSkySides + i;

			if( rn.skyMins[0][i] >= rn.skyMaxs[0][i] ||
				rn.skyMins[1][i] >= rn.skyMaxs[1][i] )
				continue;

			RB_BindVBO( skydome->sphereVbos[i]->index, GL_TRIANGLES );

			RB_DrawElements( visSide->firstVert, visSide->numVerts, visSide->firstElem, visSide->numElems );
		}
	}

	R_TransformForEntity( e );

	return qfalse;
}
Esempio n. 5
0
/*
==============
R_DrawSky

Draw either the classic cloudy quake sky or a skybox
==============
*/
void R_DrawSky (void)
{
    msurface_t	*fa;
    qbool		ignore_z;
    extern msurface_t *skychain;

    GL_DisableMultitexture ();

    if (r_fastsky.value) {
        glDisable (GL_TEXTURE_2D);
        glColor3ubv (r_skycolor.color);

        for (fa = skychain; fa; fa = fa->texturechain)
            EmitFlatPoly (fa);
        skychain = NULL;

        glEnable (GL_TEXTURE_2D);
        glColor3f (1, 1, 1);
        return;
    }

    if (r_viewleaf->contents == CONTENTS_SOLID) {
        // always draw if we're in a solid leaf (probably outside the level)
        // FIXME: we don't really want to add all six planes every time!
        // FIXME: also handle r_fastsky case
        int i;
        for (i = 0; i < 6; i++) {
            skymins[0][i] = skymins[1][i] = -1;
            skymaxs[0][i] = skymaxs[1][i] = 1;
        }
        ignore_z = true;
    }
    else {
        if (!skychain)
            return;		// no sky at all

        // figure out how much of the sky box we need to draw
        ClearSky ();
        for (fa = skychain; fa; fa = fa->texturechain)
            R_AddSkyBoxSurface (fa);

        ignore_z = false;
    }

    // turn off Z tests & writes to avoid problems on large maps
    glDisable (GL_DEPTH_TEST);

    // draw a skybox or classic quake clouds
    if (r_skyboxloaded)
        R_DrawSkyBox ();
    else
        R_DrawSkyDome ();

    glEnable (GL_DEPTH_TEST);

    // draw the sky polys into the Z buffer
    // don't need depth test yet
    if (!ignore_z) {
        if (gl_fogenable.value && gl_fogsky.value) {
            glEnable(GL_FOG);
            glColor4f(gl_fogred.value, gl_foggreen.value, gl_fogblue.value, 1);
            glBlendFunc(GL_ONE, GL_ZERO);
        }
        else {
            glColorMask (GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
            glBlendFunc(GL_ZERO, GL_ONE);
        }
        glDisable(GL_TEXTURE_2D);
        glEnable(GL_BLEND);

        for (fa = skychain; fa; fa = fa->texturechain)
            EmitFlatPoly (fa);

        if (gl_fogenable.value && gl_fogsky.value)
            glDisable (GL_FOG);
        else {
            glColorMask (GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
        }
        glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
        glEnable (GL_TEXTURE_2D);
        glDisable(GL_BLEND);
    }

    skychain = NULL;
    skychain_tail = &skychain;
}
Esempio n. 6
0
/*
 * @brief Main entry point for drawing the scene (world and entities).
 */
void R_DrawView(void) {

	R_UpdateFrustum();

	R_UpdateVis();

	R_MarkBspSurfaces();

	R_EnableFog(true);

	R_DrawSkyBox();

	// wait for the client to fully populate the scene
	Thread_Wait(r_view.thread);

	// dispatch threads to cull entities and sort elements while we draw the world
	thread_t *cull_entities = Thread_Create(R_CullEntities, NULL);
	thread_t *sort_elements = Thread_Create(R_SortElements, NULL);

	R_MarkLights();

	const r_sorted_bsp_surfaces_t *surfs = r_model_state.world->bsp->sorted_surfaces;

	R_DrawOpaqueBspSurfaces(&surfs->opaque);

	R_DrawOpaqueWarpBspSurfaces(&surfs->opaque_warp);

	R_DrawAlphaTestBspSurfaces(&surfs->alpha_test);

	R_EnableBlend(true);

	R_DrawBackBspSurfaces(&surfs->back);

	R_DrawMaterialBspSurfaces(&surfs->material);

	R_DrawFlareBspSurfaces(&surfs->flare);

	R_EnableBlend(false);

	// wait for entity culling to complete
	Thread_Wait(cull_entities);

	R_DrawEntities();

	R_EnableBlend(true);

	// wait for element sorting to complete
	Thread_Wait(sort_elements);

	R_DrawElements();

	R_EnableFog(false);

	R_DrawDeveloperTools();

	R_DrawCoronas();

	R_EnableBlend(false);

	R_ResetArrayState();

#if 0
	vec3_t tmp;
	VectorMA(r_view.origin, MAX_WORLD_DIST, r_view.forward, tmp);

	cm_trace_t tr = Cl_Trace(r_view.origin, tmp, NULL, NULL, cl.client_num + 1, MASK_SOLID);
	if (tr.fraction > 0.0 && tr.fraction < 1.0) {
		Com_Print("%s: %d: %s\n", tr.surface->name, tr.plane.num, vtos(tr.plane.normal));
	}

#endif
}