void TerrainBody::Render(const vector3d &viewCoords, const matrix4x4d &viewTransform) { matrix4x4d ftran = viewTransform; vector3d fpos = viewCoords; double rad = m_sbody->GetRadius(); float znear, zfar; Render::GetNearFarClipPlane(znear, zfar); double len = fpos.Length(); int shrink = 0; double scale = 1.0f; double dist_to_horizon; for (;;) { if (len < rad) break; // player inside radius case dist_to_horizon = sqrt(len*len - rad*rad); if (dist_to_horizon < zfar*0.5) break; rad *= 0.25; fpos = 0.25*fpos; len *= 0.25; scale *= 4.0f; shrink++; } //if (GetLabel() == "Earth") printf("Horizon %fkm, shrink %d\n", dist_to_horizon*0.001, shrink); glPushMatrix(); // initial matrix is actually identity after a long chain of wtf // glTranslatef(float(fpos.x), float(fpos.y), float(fpos.z)); glColor3f(1,1,1); { vector3d campos = fpos; ftran.ClearToRotOnly(); campos = ftran.InverseOf() * campos; glMultMatrixd(&ftran[0]); glEnable(GL_NORMALIZE); glScaled(rad, rad, rad); // rad = real_rad / scale campos = campos * (1.0/rad); // position of camera relative to planet "model" // translation not applied until patch render to fix jitter m_geosphere->Render(-campos, m_sbody->GetRadius(), scale); glTranslated(campos.x, campos.y, campos.z); SubRender(campos); glDisable(GL_NORMALIZE); // if not using shader then z-buffer precision is hopeless and // we can't place objects on the terrain without awful z artifacts if (shrink || !Render::AreShadersEnabled()) { glClear(GL_DEPTH_BUFFER_BIT); } } glPopMatrix(); }
void TerrainBody::Render(Graphics::Renderer *renderer, const Camera *camera, const vector3d &viewCoords, const matrix4x4d &viewTransform) { matrix4x4d ftran = viewTransform; vector3d fpos = viewCoords; double rad = m_sbody->GetRadius(); float znear, zfar; renderer->GetNearFarRange(znear, zfar); double len = fpos.Length(); //objects very far away are downscaled, because they cannot be //accurately drawn using actual distances int shrink = 0; double scale = 1.0f; double dist_to_horizon; for (;;) { if (len < rad) break; // player inside radius case dist_to_horizon = sqrt(len*len - rad*rad); if (dist_to_horizon < zfar*0.5) break; rad *= 0.25; fpos = 0.25*fpos; len *= 0.25; scale *= 4.0f; ++shrink; } vector3d campos = fpos; ftran.ClearToRotOnly(); campos = ftran.InverseOf() * campos; campos = campos * (1.0/rad); // position of camera relative to planet "model" std::vector<Camera::Shadow> shadows; if( camera ) { camera->PrincipalShadows(this, 3, shadows); for (std::vector<Camera::Shadow>::iterator it = shadows.begin(), itEnd=shadows.end(); it!=itEnd; ++it) { it->centre = ftran * it->centre; } } ftran.Scale(rad, rad, rad); // translation not applied until patch render to fix jitter m_geosphere->Render(renderer, ftran, -campos, m_sbody->GetRadius(), scale, shadows); ftran.Translate(campos.x, campos.y, campos.z); SubRender(renderer, ftran, campos); //clear depth buffer, shrunk objects should not interact //with foreground if (shrink) renderer->ClearDepthBuffer(); }
void TerrainBody::Render(Graphics::Renderer *renderer, const Camera *camera, const vector3d &viewCoords, const matrix4x4d &viewTransform) { matrix4x4d ftran = viewTransform; vector3d fpos = viewCoords; double rad = m_sbody->GetRadius(); float znear, zfar; renderer->GetNearFarRange(znear, zfar); double len = fpos.Length(); int shrink = 0; double scale = 1.0f; double dist_to_horizon; for (;;) { if (len < rad) break; // player inside radius case dist_to_horizon = sqrt(len*len - rad*rad); if (dist_to_horizon < zfar*0.5) break; rad *= 0.25; fpos = 0.25*fpos; len *= 0.25; scale *= 4.0f; ++shrink; } vector3d campos = fpos; ftran.ClearToRotOnly(); campos = ftran.InverseOf() * campos; campos = campos * (1.0/rad); // position of camera relative to planet "model" std::vector<Camera::Shadow> shadows; if( camera ) { camera->PrincipalShadows(this, 3, shadows); for (std::vector<Camera::Shadow>::iterator it = shadows.begin(), itEnd=shadows.end(); it!=itEnd; ++it) { it->centre = ftran * it->centre; } } ftran.Scale(rad, rad, rad); // translation not applied until patch render to fix jitter m_geosphere->Render(renderer, ftran, -campos, m_sbody->GetRadius(), scale, shadows); ftran.Translate(campos.x, campos.y, campos.z); SubRender(renderer, ftran, campos); // if not using shader then z-buffer precision is hopeless and // we can't place objects on the terrain without awful z artifacts if (shrink || !Graphics::AreShadersEnabled()) renderer->ClearDepthBuffer(); }
void TerrainBody::Render(Graphics::Renderer *renderer, const Camera *camera, const vector3d &viewCoords, const matrix4x4d &viewTransform) { matrix4x4d ftran = viewTransform; vector3d fpos = viewCoords; double rad = m_sbody->GetRadius(); float znear, zfar; renderer->GetNearFarRange(znear, zfar); double len = fpos.Length(); int shrink = 0; double scale = 1.0f; double dist_to_horizon; for (;;) { if (len < rad) break; // player inside radius case dist_to_horizon = sqrt(len*len - rad*rad); if (dist_to_horizon < zfar*0.5) break; rad *= 0.25; fpos = 0.25*fpos; len *= 0.25; scale *= 4.0f; ++shrink; } //if (GetLabel() == "Earth") printf("Horizon %fkm, shrink %d\n", dist_to_horizon*0.001, shrink); glPushMatrix(); // initial matrix is actually identity after a long chain of wtf // glTranslatef(float(fpos.x), float(fpos.y), float(fpos.z)); glColor3f(1,1,1); { vector3d campos = fpos; ftran.ClearToRotOnly(); campos = ftran.InverseOf() * campos; glMultMatrixd(&ftran[0]); glScaled(rad, rad, rad); // rad = real_rad / scale campos = campos * (1.0/rad); // position of camera relative to planet "model" std::vector<Camera::Shadow> shadows; if( camera ) { camera->PrincipalShadows(this, 3, shadows); for (std::vector<Camera::Shadow>::iterator it = shadows.begin(), itEnd=shadows.end(); it!=itEnd; ++it) { it->centre = ftran * it->centre; } } // translation not applied until patch render to fix jitter m_geosphere->Render(renderer, -campos, m_sbody->GetRadius(), scale, shadows); glTranslated(campos.x, campos.y, campos.z); SubRender(renderer, camera, campos); // if not using shader then z-buffer precision is hopeless and // we can't place objects on the terrain without awful z artifacts if (shrink || !Graphics::AreShadersEnabled()) { renderer->ClearDepthBuffer(); } } glPopMatrix(); }