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; }