void cone::gl_render(view& scene) { if (degenerate()) return; init_model(scene); clear_gl_error(); // See sphere::gl_render() for a description of the level of detail calc. double coverage = scene.pixel_coverage( pos, radius); int lod = 0; if (coverage < 0) lod = 5; else if (coverage < 10) lod = 0; else if (coverage < 30) lod = 1; else if (coverage < 90) lod = 2; else if (coverage < 250) lod = 3; else if (coverage < 450) lod = 4; else lod = 5; lod += scene.lod_adjust; if (lod < 0) lod = 0; else if (lod > 5) lod = 5; gl_matrix_stackguard guard; const double length = axis.mag(); model_world_transform( scene.gcf, vector( length, radius, radius ) ).gl_mult(); color.gl_set(opacity); if (translucent()) { gl_enable cull_face( GL_CULL_FACE); // Render the back half. glCullFace( GL_FRONT); scene.cone_model[lod].gl_render(); // Render the front half. glCullFace( GL_BACK); scene.cone_model[lod].gl_render(); } else { scene.cone_model[lod].gl_render(); } check_gl_error(); }
void sphere::gl_render( view& geometry) { if (degenerate()) return; //init_model(); init_model(geometry); // coverage is the radius of this sphere in pixels: double coverage = geometry.pixel_coverage( pos, radius); int lod = 0; if (coverage < 0) // Behind the camera, but still visible. lod = 4; else if (coverage < 30) lod = 0; else if (coverage < 100) lod = 1; else if (coverage < 500) lod = 2; else if (coverage < 5000) lod = 3; else lod = 4; lod += geometry.lod_adjust; // allow user to reduce level of detail if (lod > 5) lod = 5; else if (lod < 0) lod = 0; gl_matrix_stackguard guard; model_world_transform( geometry.gcf, get_scale() ).gl_mult(); color.gl_set(opacity); if (translucent()) { // Spheres are convex, so we don't need to sort gl_enable cull_face( GL_CULL_FACE); // Render the back half (inside) glCullFace( GL_FRONT ); geometry.sphere_model[lod].gl_render(); // Render the front half (outside) glCullFace( GL_BACK ); geometry.sphere_model[lod].gl_render(); } else { // Render a simple sphere. geometry.sphere_model[lod].gl_render(); } }
//---------------------------------------------------------------------------- void BSplineSurfaceFitter::CreateScene () { mScene = new0 Node(); mWireState = new0 WireState(); mRenderer->SetOverrideWireState(mWireState); mCullState = new0 CullState(); mCullState->Enabled = false; mRenderer->SetOverrideCullState(mCullState); // Begin with a flat 64x64 height field. const int numSamples = 64; const float extent = 8.0f; VertexFormat* vformat = VertexFormat::Create(2, VertexFormat::AU_POSITION, VertexFormat::AT_FLOAT3, 0, VertexFormat::AU_TEXCOORD, VertexFormat::AT_FLOAT2, 0); mHeightField = StandardMesh(vformat).Rectangle(numSamples, numSamples, extent, extent); mScene->AttachChild(mHeightField); // Set the heights based on a precomputed height field. Also create a // texture image to go with the height field. std::string path = Environment::GetPathR("HeightField.wmtf"); Texture2D* texture = Texture2D::LoadWMTF(path); VisualEffectInstance* instance = Texture2DEffect::CreateUniqueInstance( texture, Shader::SF_LINEAR, Shader::SC_CLAMP_EDGE, Shader::SC_CLAMP_EDGE); mHeightField->SetEffectInstance(instance); unsigned char* data = (unsigned char*)texture->GetData(0); VertexBufferAccessor vba(mHeightField); Vector3f** samplePoints = new2<Vector3f>(numSamples, numSamples); int i; for (i = 0; i < vba.GetNumVertices(); ++i) { unsigned char value = *data; float height = 3.0f*((float)value)/255.0f + 0.05f*Mathf::SymmetricRandom(); *data++ = (unsigned char)Mathf::IntervalRandom(32.0f, 64.0f); *data++ = 3*(128 - value/2)/4; *data++ = 0; data++; vba.Position<Vector3f>(i).Z() = height; samplePoints[i % numSamples][i / numSamples] = vba.Position<Vector3f>(i); } // Compute a B-Spline surface with NxN control points, where N < 64. // This surface will be sampled to 64x64 and displayed together with the // original height field for comparison. const int numCtrlPoints = 32; const int degree = 3; BSplineSurfaceFitf fitter(degree, numCtrlPoints, numSamples, degree, numCtrlPoints, numSamples, samplePoints); delete2(samplePoints); vformat = VertexFormat::Create(2, VertexFormat::AU_POSITION, VertexFormat::AT_FLOAT3, 0, VertexFormat::AU_COLOR, VertexFormat::AT_FLOAT4, 0); mFittedField = StandardMesh(vformat).Rectangle(numSamples, numSamples, extent, extent); mScene->AttachChild(mFittedField); vba.ApplyTo(mFittedField); Float4 translucent(1.0f, 1.0f, 1.0f, 0.5f); for (i = 0; i < vba.GetNumVertices(); ++i) { float u = 0.5f*(vba.Position<Vector3f>(i).X()/extent + 1.0f); float v = 0.5f*(vba.Position<Vector3f>(i).Y()/extent + 1.0f); vba.Position<Vector3f>(i) = fitter.GetPosition(u, v); vba.Color<Float4>(0,i) = translucent; } instance = VertexColor4Effect::CreateUniqueInstance(); mFittedField->SetEffectInstance(instance); instance->GetEffect()->GetAlphaState(0, 0)->BlendEnabled = true; }