示例#1
0
void Scene::draw()
{
    if(m_view_plane)
        ::glEnable(GL_DEPTH_TEST);
    else
        ::glDisable(GL_DEPTH_TEST);

    if(m_view_polyhedron)
        draw_polyhedron();

    if(m_view_points)
        draw_points();

    if(m_view_segments)
        draw_segments();

    if (m_view_plane)
    {
        switch( m_cut_plane )
        {
        case UNSIGNED_EDGES:
        case UNSIGNED_FACETS:
            draw_distance_function(m_thermal_ramp, m_thermal_ramp);
            break;
        case SIGNED_FACETS:
            draw_distance_function(m_red_ramp, m_blue_ramp);
            break;
        case CUT_SEGMENTS:
            draw_cut_segment_plane();
            break;
        case NONE: // do nothing
            break;
        }
    }
}
idScreenRect R_CalcIntersectionScissor(const idRenderLightLocal *lightDef,
                                       const idRenderEntityLocal *entityDef,
                                       const viewDef_t *viewDef)
{

	idMat4 omodel = make_idMat4(entityDef->modelMatrix);
	idMat4 lmodel = make_idMat4(lightDef->modelMatrix);

	// compute light polyhedron
	polyhedron lvol = PolyhedronFromBounds(lightDef->frustumTris->bounds);
	// transform it into world space
	//lvol.transform( lmodel );

	// debug //
	if (r_useInteractionScissors.GetInteger() == -2) {
		draw_polyhedron(viewDef, lvol, colorRed);
	}

	// compute object polyhedron
	polyhedron vol = PolyhedronFromBounds(entityDef->referenceBounds);

	//viewDef->renderWorld->DebugBounds( colorRed, lightDef->frustumTris->bounds );
	//viewDef->renderWorld->DebugBox( colorBlue, idBox( model->Bounds(), entityDef->parms.origin, entityDef->parms.axis ) );

	// transform it into world space
	vol.transform(omodel);

	// debug //
	if (r_useInteractionScissors.GetInteger() == -2) {
		draw_polyhedron(viewDef, vol, colorBlue);
	}

	// transform light position into world space
	idVec4 lightpos = idVec4(lightDef->globalLightOrigin.x,
	                         lightDef->globalLightOrigin.y,
	                         lightDef->globalLightOrigin.z,
	                         1.0f);

	// generate shadow volume "polyhedron"
	polyhedron sv = make_sv(vol, lightpos);

	MySegments in_segs, out_segs;

	// get shadow volume edges
	polyhedron_edges(sv, in_segs);
	// clip them against light bounds planes
	clip_segments(lvol, in_segs, out_segs);

	// get light bounds edges
	polyhedron_edges(lvol, in_segs);
	// clip them by the shadow volume
	clip_segments(sv, in_segs, out_segs);

	// debug //
	if (r_useInteractionScissors.GetInteger() == -2) {
		draw_segments(viewDef, out_segs, colorGreen);
	}

	idBounds outbounds;
	outbounds.Clear();

	for (unsigned int i = 0; i < out_segs.size(); i++) {

		idVec4 v;
		world_to_hclip(viewDef, out_segs[i], v);

		if (v.w <= 0.0f) {
			return lightDef->viewLight->scissorRect;
		}

		idVec3 rv(v.x, v.y, v.z);
		rv /= v.w;

		outbounds.AddPoint(rv);
	}

	// limit the bounds to avoid an inside out scissor rectangle due to floating point to short conversion
	if (outbounds[0].x < -1.0f) {
		outbounds[0].x = -1.0f;
	}

	if (outbounds[1].x > 1.0f) {
		outbounds[1].x = 1.0f;
	}

	if (outbounds[0].y < -1.0f) {
		outbounds[0].y = -1.0f;
	}

	if (outbounds[1].y > 1.0f) {
		outbounds[1].y = 1.0f;
	}

	float w2 = (viewDef->viewport.x2 - viewDef->viewport.x1 + 1) / 2.0f;
	float x = viewDef->viewport.x1;
	float h2 = (viewDef->viewport.y2 - viewDef->viewport.y1 + 1) / 2.0f;
	float y = viewDef->viewport.y1;

	idScreenRect rect;
	rect.x1 = outbounds[0].x * w2 + w2 + x;
	rect.x2 = outbounds[1].x * w2 + w2 + x;
	rect.y1 = outbounds[0].y * h2 + h2 + y;
	rect.y2 = outbounds[1].y * h2 + h2 + y;
	rect.Expand();

	rect.Intersect(lightDef->viewLight->scissorRect);

	// debug //
	if (r_useInteractionScissors.GetInteger() == -2 && !rect.IsEmpty()) {
		viewDef->renderWorld->DebugScreenRect(colorYellow, rect, viewDef);
	}

	return rect;
}