mirror of
				https://github.com/zenorogue/hyperrogue.git
				synced 2025-10-31 05:52:59 +00:00 
			
		
		
		
	more detailed 3D depth settings
This commit is contained in:
		| @@ -745,14 +745,19 @@ void geometry_information::make_star(hpcshape& sh, ld rad) { | ||||
| void geometry_information::make_euclidean_sky() { | ||||
|   bshape(cgi.shEuclideanSky, PPR::EUCLIDEAN_SKY); | ||||
|   for(int x=-20; x<20; x++) | ||||
|   for(int y=-20; y<20; y++) | ||||
|   for(int y=-20; y<20; y++) { | ||||
|     auto x0 = x * cgi.LOWSKY; | ||||
|     auto x1 = (x+1) * cgi.LOWSKY; | ||||
|     auto y0 = y * cgi.LOWSKY; | ||||
|     auto y1 = (y+1) * cgi.LOWSKY; | ||||
|     hpcsquare( | ||||
|       lzpush(cgi.WALL) * hpxy(x, y), | ||||
|       lzpush(cgi.WALL) * hpxy(x, y+1), | ||||
|       lzpush(cgi.WALL) * hpxy(x+1, y), | ||||
|       lzpush(cgi.WALL) * hpxy(x+1, y+1) | ||||
|       lzpush(cgi.LOWSKY) * hpxy(x0, y0), | ||||
|       lzpush(cgi.LOWSKY) * hpxy(x0, y1), | ||||
|       lzpush(cgi.LOWSKY) * hpxy(x1, y0), | ||||
|       lzpush(cgi.LOWSKY) * hpxy(x1, y1) | ||||
|       ); | ||||
|     } | ||||
|   } | ||||
|  | ||||
| /** res[0] and res[1] place H on the plane, while res[2] is the altitude */ | ||||
| hyperpoint psmin(hyperpoint H) { | ||||
| @@ -1118,13 +1123,10 @@ void geometry_information::make_3d_models() { | ||||
|   make_ball(shDisk, orbsize*.2, 2); | ||||
|   make_ball(shHeptaMarker, zhexf*.2, 1); | ||||
|   make_ball(shSnowball, zhexf*.1, 1); | ||||
|   if(euclid) { | ||||
|     make_ball(shSun, 0.5, 2); | ||||
|     make_euclidean_sky(); | ||||
|     } | ||||
|   else | ||||
|     make_star(shSun, 3); | ||||
|   make_star(shNightStar, euclid ? 0.05 : 0.75); | ||||
|   make_ball(shSkyboxSun, 8 * zhexf, 2); | ||||
|   if(euclid) make_euclidean_sky(); | ||||
|   make_star(shSun, vid.sun_size * zhexf); | ||||
|   make_star(shNightStar, vid.star_size * zhexf); | ||||
|    | ||||
|   if(WDIM == 2) { | ||||
|     for(int i=0; i<3; i++) { | ||||
|   | ||||
							
								
								
									
										89
									
								
								config.cpp
									
									
									
									
									
								
							
							
						
						
									
										89
									
								
								config.cpp
									
									
									
									
									
								
							| @@ -325,6 +325,7 @@ void non_editable() { | ||||
| void float_setting::show_edit_option(int key) { | ||||
|   if(modify_me) modify_me(this); | ||||
|   dialog::addSelItem(XLAT(menu_item_name), fts(*value) + unit, key); | ||||
|   if(*value == use_the_default_value) dialog::lastItem().value = XLAT("default"); | ||||
|   dialog::add_action([this] () { | ||||
|     add_to_changed(this); | ||||
|     dialog::editNumber(*value, min_value, max_value, step, dft, XLAT(menu_item_name), help_text);  | ||||
| @@ -2368,6 +2369,45 @@ EX void show_spatial_embedding() { | ||||
|   dialog::display(); | ||||
|   } | ||||
|  | ||||
| EX void show3D_height_details() { | ||||
|   cmode = sm::SIDE | sm::MAYDARK; | ||||
|   gamescreen(); | ||||
|   dialog::init(XLAT("3D detailed settings")); | ||||
|  | ||||
|   add_edit(vid.wall_height); | ||||
|  | ||||
|   dialog::addBreak(50); | ||||
|  | ||||
|   add_edit(vid.rock_wall_ratio); | ||||
|   add_edit(vid.human_wall_ratio); | ||||
|   add_edit(vid.lake_top); | ||||
|   add_edit(vid.lake_shallow); | ||||
|   add_edit(vid.lake_bottom); | ||||
|  | ||||
|   dialog::addBreak(50); | ||||
|  | ||||
|   if(embedded_plane) { | ||||
|     add_edit(auto_remove_roofs); | ||||
|     add_edit(vid.wall_height2); | ||||
|     add_edit(vid.wall_height3); | ||||
|     add_edit(draw_sky); | ||||
|     add_edit(vid.lowsky_height); | ||||
|     add_edit(vid.sky_height); | ||||
|     add_edit(vid.star_height); | ||||
|     add_edit(vid.infdeep_height); | ||||
|     add_edit(vid.sun_size); | ||||
|     add_edit(vid.star_size); | ||||
|     add_edit(vid.height_limits); | ||||
|     if(euclid && msphere) add_edit(use_euclidean_infinity); | ||||
|     } | ||||
|   else dialog::addInfo(XLAT("more options in 3D engine")); | ||||
|  | ||||
|   dialog::addBreak(100); | ||||
|  | ||||
|   dialog::addBack(); | ||||
|   dialog::display(); | ||||
|   } | ||||
|  | ||||
| EX void show3D() { | ||||
|   cmode = sm::SIDE | sm::MAYDARK; | ||||
|   gamescreen(); | ||||
| @@ -2411,11 +2451,9 @@ EX void show3D() { | ||||
|      | ||||
|     dialog::addBreak(50); | ||||
|     add_edit(vid.wall_height); | ||||
|     dialog::addSelItem("height details", "", 'D'); | ||||
|     dialog::add_action_push(show3D_height_details); | ||||
|      | ||||
|     add_edit(vid.rock_wall_ratio); | ||||
|     add_edit(vid.human_wall_ratio); | ||||
|     add_edit(vid.lake_top); | ||||
|     add_edit(vid.lake_bottom); | ||||
|     if(scale_used()) | ||||
|       add_edit(vid.creature_scale); | ||||
|     } | ||||
| @@ -2584,7 +2622,10 @@ EX int config3 = addHook(hooks_configfile, 100, [] { | ||||
|   param_b(numerical_minefield, "numerical_minefield") | ||||
|   ->editable("display mine counts numerically", 'n'); | ||||
|   param_b(dont_display_minecount, "dont_display_minecount"); | ||||
|   param_b(draw_sky, "draw sky", true); | ||||
|   param_enum(draw_sky, "draw_sky", "draw_sky", skyAutomatic) | ||||
|   -> editable({{"NO", "do not draw sky"}, {"automatic", ""}, {"skybox", "works only in Euclidean"}, {"always", "might be glitched in some settings"}}, "sky rendering", 's'); | ||||
|   param_b(use_euclidean_infinity, "use_euclidean_infinity", true) | ||||
|   -> editable("infinite sky", 'i'); | ||||
|   param_f(linepatterns::parallel_count, "parallel_count") | ||||
|     ->editable(0, 24, 1, "number of parallels drawn", "", 'n'); | ||||
|   param_f(linepatterns::parallel_max, "parallel_max") | ||||
| @@ -2688,10 +2729,44 @@ EX int config3 = addHook(hooks_configfile, 100, [] { | ||||
|         fts(cosh(vid.depth - vid.wall_height * vid.human_wall_ratio) / cosh(vid.depth))) | ||||
|         ); | ||||
|         }); | ||||
|   param_f(vid.lake_top, "lake_top", "3D lake top", .25) | ||||
|   param_f(vid.lake_top, "lake_top", "3D lake top", .25 / 0.3) | ||||
|     ->editable(0, 1, .1, "Level of water surface", "", 'l'); | ||||
|   param_f(vid.lake_bottom, "lake_bottom", "3D lake bottom", .9) | ||||
|   param_f(vid.lake_shallow, "lake_shallow", "3D lake shallow", .4 / 0.3) | ||||
|     ->editable(0, 1, .1, "Level of shallow water", "", 's'); | ||||
|   param_f(vid.lake_bottom, "lake_bottom", "3D lake bottom", .9 / 0.3) | ||||
|     ->editable(0, 1, .1, "Level of water bottom", "", 'k'); | ||||
|   param_f(vid.wall_height2, "wall_height2", "wall_height2", 2) | ||||
|     ->editable(0, 5, .1, "ratio of high walls to normal walls", "", '2'); | ||||
|   param_f(vid.wall_height3, "wall_height3", "wall_height3", 3) | ||||
|     ->editable(0, 5, .1, "ratio of very high walls to normal walls", "", '3'); | ||||
|   param_f(vid.lowsky_height, "lowsky_height", "lowsky_height", 2) | ||||
|     ->editable(0, 5, .1, "lowsky height", "", '4'); | ||||
|   param_f(vid.sky_height, "sky_height", "sky_height", use_the_default_value) | ||||
|     ->editable(0, 10, .1, "altitude of the sky", "", '5') | ||||
|     ->set_extra([] { | ||||
|       dialog::addSelItem(XLAT("use the default value"), 0, 'D'); | ||||
|       dialog::add_action([] { vid.sky_height = use_the_default_value; }); | ||||
|       }); | ||||
|   param_f(vid.star_height, "star_height", "star_height", use_the_default_value) | ||||
|     ->editable(0, 10, .1, "altitude of the stars", "", '6') | ||||
|     ->set_extra([] { | ||||
|       dialog::addSelItem(XLAT("use the default value"), 0, 'D'); | ||||
|       dialog::add_action([] { vid.star_height = use_the_default_value; }); | ||||
|       }); | ||||
|   param_f(vid.infdeep_height, "infdeep_height", "infdeep_height", use_the_default_value) | ||||
|     ->editable(0, 10, .1, "infinite depth", "", '7') | ||||
|     ->set_extra([] { | ||||
|       dialog::addSelItem(XLAT("use the default value"), 0, 'D'); | ||||
|       dialog::add_action([] { vid.infdeep_height = use_the_default_value; }); | ||||
|       }); | ||||
|   param_f(vid.sun_size, "sun_size", "sun_size", 8) | ||||
|     ->editable(0, 10, .1, "sun size (relative to item sizes)", "", '8'); | ||||
|   param_f(vid.star_size, "star_size", "star_size", 0.75) | ||||
|     ->editable(0, 10, .1, "night star size (relative to item sizes)", "", '9'); | ||||
|   param_b(vid.height_limits, "height_limits", true) | ||||
|     ->editable("automatically limit heights if too high", 'l'); | ||||
|   param_b(auto_remove_roofs, "auto_remove_roofs", true) | ||||
|     ->editable("do not render higher levels if camera too high", 'r'); | ||||
|   addsaver(vid.tc_depth, "3D TC depth", 1); | ||||
|   addsaver(vid.tc_camera, "3D TC camera", 2); | ||||
|   addsaver(vid.tc_alpha, "3D TC alpha", 3); | ||||
|   | ||||
| @@ -727,7 +727,7 @@ void dqi_poly::gldraw() { | ||||
|         glhr::color2(color, (flags & POLY_INTENSE) ? 2 : 1); | ||||
|         glhr::set_depthtest(model_needs_depth() && prio < PPR::SUPERLINE); | ||||
|         glhr::set_depthwrite(model_needs_depth() && prio != PPR::TRANSPARENT_SHADOW && prio != PPR::EUCLIDEAN_SKY); | ||||
|         glhr::set_fogbase(prio == PPR::SKY ? 1.0 + (euclid ? 20 : 5 / sightranges[geometry]) : 1.0); | ||||
|         glhr::set_fogbase(prio == PPR::SKY ? 1.0 + ((abs(cgi.SKY - cgi.LOWSKY)) / sightranges[geometry]) : 1.0); | ||||
|         glDrawArrays(GL_TRIANGLES, ioffset, cnt); | ||||
|         } | ||||
|       else { | ||||
| @@ -2456,7 +2456,7 @@ EX void drawqueue() { | ||||
|   #endif | ||||
|  | ||||
|   #if MAXMDIM >= 4 && CAP_GL | ||||
|   if(embedded_plane && (hyperbolic || cgi.emb->is_sph_in_low() || cgi.emb->is_in_noniso()) && !vrhr::rendering()) make_air(); | ||||
|   make_air(); | ||||
|   #endif | ||||
|    | ||||
|   #if CAP_VR | ||||
|   | ||||
| @@ -271,6 +271,7 @@ EX } | ||||
|     virtual ld anim_center_z() { return center_z(); } | ||||
|     virtual hyperpoint anim_tile_center(); | ||||
|     virtual void logical_fix(transmatrix&) = 0; | ||||
|     virtual ld height_limit(ld sign); | ||||
|      | ||||
|     virtual bool is_euc_in_product() { return false; } | ||||
|     virtual bool is_product_embedding() { return false; } | ||||
| @@ -283,7 +284,6 @@ EX } | ||||
|     virtual bool is_euc_in_nil() { return false; } | ||||
|     virtual bool is_euc_in_noniso() { return false; } | ||||
|     virtual bool is_in_noniso() { return false; } | ||||
|     virtual bool is_depth_limited() { return false; } | ||||
|     virtual bool is_cylinder() { return false; } | ||||
|     virtual bool no_spin() { return false; } | ||||
|  | ||||
| @@ -307,6 +307,21 @@ EX } | ||||
|  | ||||
| EX geometry_information *swapper; | ||||
|  | ||||
| ld embedding_method::height_limit(ld sign) { | ||||
|   if(sign > 0) { | ||||
|     if(hyperbolic || sol || nih || sl2 || in_h2xe()) return 5; | ||||
|     if(sphere || nil || in_s2xe()) return M_PI/2; | ||||
|     return 100; | ||||
|     } | ||||
|   if(sign < 0) { | ||||
|     if(center_z()) return -center_z(); | ||||
|     if(hyperbolic || sol || nih || sl2 || in_h2xe()) return -5; | ||||
|     if(sphere || nil || in_s2xe()) return -M_PI/2; | ||||
|     return -100; | ||||
|     } | ||||
|   return 0; | ||||
|   } | ||||
|  | ||||
| hyperpoint embedding_method::tile_center() { | ||||
|   ld z = center_z(); | ||||
|   if(z == 0) return C0; | ||||
| @@ -608,7 +623,6 @@ struct emb_euc_in_hyp : emb_actual { | ||||
|  | ||||
| struct emb_sphere_in_low : emb_actual { | ||||
|   bool is_sph_in_low() override { return true; } | ||||
|   bool is_depth_limited() override { return true; } | ||||
|   transmatrix intermediate_to_actual_translation(hyperpoint i) override { | ||||
|     return map_relative_push(logical_to_actual(i)) * zpush(-1); | ||||
|     } | ||||
| @@ -757,7 +771,6 @@ struct emb_euc_in_sl2 : emb_euclid_noniso { | ||||
| struct emb_euc_cylinder : emb_euclid_noniso { | ||||
|   bool is_cylinder() override { return true; } | ||||
|   ld center_z() override { return 1; } | ||||
|   bool is_depth_limited() override { return true; } | ||||
|   transmatrix get_lsti() override { return cspin90(0, 1); } | ||||
|   hyperpoint actual_to_intermediate(hyperpoint a) override {  | ||||
|     ld z0 = asin_auto(hypot(a[1], a[2])); | ||||
| @@ -845,9 +858,11 @@ struct emb_euc_cylinder_sl2 : emb_euc_cylinder_twisted { | ||||
|     } | ||||
|   }; | ||||
|  | ||||
| /** Clifford torus */ | ||||
| struct emb_euc_in_sph : emb_euclid_noniso { | ||||
|   bool is_euc_in_sph() override { return true; } | ||||
|   ld center_z() override { return 1; } | ||||
|   virtual ld height_limit(ld sign) { return sign < 0 ? 0 : 90._deg; } | ||||
|   hyperpoint actual_to_intermediate(hyperpoint a) override {  | ||||
|     ld tx = hypot(a[0], a[2]); | ||||
|     ld ty = hypot(a[1], a[3]); | ||||
|   | ||||
							
								
								
									
										69
									
								
								geometry.cpp
									
									
									
									
									
								
							
							
						
						
									
										69
									
								
								geometry.cpp
									
									
									
									
									
								
							| @@ -236,7 +236,7 @@ struct geometry_information { | ||||
|     BODY, BODY1, BODY2, BODY3, | ||||
|     NECK1, NECK, NECK3, HEAD, HEAD1, HEAD2, HEAD3, | ||||
|     ALEG0, ALEG, ABODY, AHEAD, BIRD, LOWSKY, SKY, HIGH, HIGH2, | ||||
|     SHALLOW; | ||||
|     HELL, STAR, SHALLOW; | ||||
|   ld human_height, slev; | ||||
|  | ||||
|   ld eyelevel_familiar, eyelevel_human, eyelevel_dog; | ||||
| @@ -308,7 +308,7 @@ hpcshape | ||||
|   shKnife, shTongue, shFlailMissile, shTrapArrow, | ||||
|   shPirateHook, shSmallPirateHook, shPirateHood, shEyepatch, shPirateX, | ||||
|   // shScratch,  | ||||
|   shHeptaMarker, shSnowball, shHugeDisk, shSun, shNightStar, shEuclideanSky, | ||||
|   shHeptaMarker, shSnowball, shHugeDisk, shSkyboxSun, shSun, shNightStar, shEuclideanSky, | ||||
|   shSkeletonBody, shSkull, shSkullEyes, shFatBody, shWaterElemental, | ||||
|   shPalaceGate, shFishTail, | ||||
|   shMouse, shMouseLegs, shMouseEyes, | ||||
| @@ -991,10 +991,9 @@ EX namespace geom3 { | ||||
|       BIRD = 1.20; | ||||
|       SHALLOW = .95; | ||||
|       STUFF = 1; | ||||
|       LOWSKY = SKY = HIGH = HIGH2 = 1; | ||||
|       LOWSKY = SKY = HIGH = HIGH2 = STAR = 1; | ||||
|       } | ||||
|     else { | ||||
|       INFDEEP = GDIM == 3 ? (sphere ? 90._deg : +5) : (euclid || sphere) ? 0.01 : lev_to_projection(0) * tanh(vid.camera); | ||||
|       ld wh = actual_wall_height(); | ||||
|       WALL = lev_to_factor(wh); | ||||
|       FLOOR = lev_to_factor(0); | ||||
| @@ -1041,36 +1040,43 @@ EX namespace geom3 { | ||||
|       slev = vid.rock_wall_ratio * wh / 3; | ||||
|       for(int s=0; s<=3; s++) | ||||
|         SLEV[s] = lev_to_factor(vid.rock_wall_ratio * wh * s/3); | ||||
|       LAKE = lev_to_factor(sgn * -vid.lake_top); | ||||
|       SHALLOW = lev_to_factor(sgn * -.4); | ||||
|       LAKE = lev_to_factor(sgn * wh * -vid.lake_top); | ||||
|       SHALLOW = lev_to_factor(sgn * wh * -vid.lake_shallow); | ||||
|       HELLSPIKE = lev_to_factor(sgn * -(vid.lake_top+vid.lake_bottom)/2); | ||||
|       BOTTOM = lev_to_factor(sgn * -vid.lake_bottom); | ||||
|       LOWSKY = lev_to_factor(2 * wh); | ||||
|       HIGH = LOWSKY; | ||||
|       HIGH2 = lev_to_factor(3 * wh); | ||||
|       SKY = LOWSKY - sgn * 5; | ||||
|       LOWSKY = lev_to_factor(vid.lowsky_height * wh); | ||||
|       HIGH = lev_to_factor(vid.wall_height2 * wh); | ||||
|       HIGH2 = lev_to_factor(vid.wall_height3 * wh); | ||||
|       SKY = vid.sky_height == use_the_default_value ? cgi.emb->height_limit(-sgn) : lev_to_factor(vid.sky_height * wh); | ||||
|       STAR = vid.star_height == use_the_default_value ? lerp(FLOOR, SKY, 0.95) : lev_to_factor(vid.star_height * wh); | ||||
|       HELL = -SKY; | ||||
|       if(embedded_plane) | ||||
|         INFDEEP = vid.infdeep_height == use_the_default_value ? cgi.emb->height_limit(sgn) : lev_to_factor(vid.infdeep_height * wh); | ||||
|        else | ||||
|         INFDEEP = (euclid || sphere) ? 0.01 : lev_to_projection(0) * tanh(vid.camera); | ||||
|  | ||||
|       /* in spherical/cylindrical case, make sure that the high stuff does not go through the center */ | ||||
|  | ||||
|       if(cgi.emb->is_depth_limited()) { | ||||
|         ld max_high = lerp(-FLOOR, -1, 0.8); | ||||
|         ld max_high2 = lerp(-FLOOR, -1, 0.9); | ||||
|         if(HIGH < max_high) HIGH = max_high; | ||||
|         if(HIGH2 < max_high2) HIGH2 = max_high2; | ||||
|         if(LOWSKY < max_high) LOWSKY = max_high; | ||||
|         if(SKY < max_high) SKY = max_high; | ||||
|         if(vid.wall_height < 0) { | ||||
|           SKY = -3 * vid.wall_height; | ||||
|           LOWSKY = 1.75 * SKY; | ||||
|           } | ||||
|         if(SHALLOW < max_high) SHALLOW = max_high; | ||||
|         if(LAKE < max_high) LAKE = max_high; | ||||
|         if(BOTTOM < max_high2) BOTTOM = max_high2; | ||||
|         if(HELLSPIKE < max_high) HELLSPIKE = max_high; | ||||
|         if(sgn < 0) INFDEEP = -1; | ||||
|       if(vid.height_limits) { | ||||
|         auto hp = cgi.emb->height_limit(1); | ||||
|         auto hn = cgi.emb->height_limit(-1); | ||||
|         auto adjust = [&] (ld& val, ld& guide, ld lerpval) { | ||||
|           if(val > hp) | ||||
|             val = lerp(guide, hp, lerpval); | ||||
|           else if(val < hn) | ||||
|             val = lerp(guide, hn, lerpval); | ||||
|           }; | ||||
|         adjust(HIGH, FLOOR, 0.8); | ||||
|         adjust(HIGH2, HIGH, 0.5); | ||||
|         adjust(SKY, FLOOR, 1); | ||||
|         adjust(STAR, FLOOR, 0.9); | ||||
|         adjust(LAKE, FLOOR, 0.8); | ||||
|         adjust(SHALLOW, LAKE, 0.9); | ||||
|         adjust(BOTTOM, SHALLOW, 0.5); | ||||
|         adjust(INFDEEP, FLOOR, 1); | ||||
|         } | ||||
|  | ||||
|       if(cgi.emb->is_euc_in_hyp() && sgn < 0) INFDEEP = FLOOR - 5; | ||||
|       println(hlog, "WALL = ", WALL, " LOWSKY = ", LOWSKY, " SKY = ", SKY, " STAR = ", STAR, " INFDEEP = ", INFDEEP, " wh = ", wh); | ||||
|       } | ||||
|     }     | ||||
|  | ||||
| @@ -1269,6 +1275,15 @@ EX string cgi_string() { | ||||
|     V("LB", fts(vid.lake_bottom)); | ||||
|     if(GDIM == 3 && vid.pseudohedral) | ||||
|       V("PS", fts(vid.depth_bonus)); | ||||
|     V("LS", fts(vid.lake_shallow)); | ||||
|     V("SSu", fts(vid.sun_size)); | ||||
|     V("SSt", fts(vid.star_size)); | ||||
|     V("WH2", fts(vid.wall_height2)); | ||||
|     V("WH3", fts(vid.wall_height3)); | ||||
|     V("WHL", fts(vid.lowsky_height)); | ||||
|     if(vid.sky_height != use_the_default_value) V("SHe", fts(vid.sky_height)); | ||||
|     if(vid.star_height != use_the_default_value) V("StH", fts(vid.star_height)); | ||||
|     if(vid.infdeep_height != use_the_default_value) V("ID", fts(vid.infdeep_height)); | ||||
|     } | ||||
|  | ||||
|   V("3D", ONOFF(vid.always3)); | ||||
|   | ||||
							
								
								
									
										6
									
								
								hyper.h
									
									
									
									
									
								
							
							
						
						
									
										6
									
								
								hyper.h
									
									
									
									
									
								
							| @@ -313,6 +313,8 @@ struct projection_configuration { | ||||
|  | ||||
| enum eThreatLevel { tlNoThreat, tlSpam, tlNormal, tlHighThreat }; | ||||
|  | ||||
| constexpr ld use_the_default_value = -20.0625; | ||||
|  | ||||
| struct videopar { | ||||
|   projection_configuration projection_config, rug_config; | ||||
|   ld yshift; | ||||
| @@ -416,7 +418,9 @@ struct videopar { | ||||
|   ld depth;      // world level below the plane | ||||
|   ld camera;     // camera level above the plane | ||||
|   ld wall_height, creature_scale, height_width; | ||||
|   ld lake_top, lake_bottom; | ||||
|   ld lake_top, lake_bottom, lake_shallow, wall_height2, wall_height3; | ||||
|   ld lowsky_height, sky_height, star_height, infdeep_height, star_size, sun_size; | ||||
|   bool height_limits; | ||||
|   ld rock_wall_ratio; | ||||
|   ld human_wall_ratio; | ||||
|   bool pseudohedral; // in 3D modes | ||||
|   | ||||
							
								
								
									
										103
									
								
								sky.cpp
									
									
									
									
									
								
							
							
						
						
									
										103
									
								
								sky.cpp
									
									
									
									
									
								
							| @@ -5,10 +5,18 @@ namespace hr { | ||||
| EX bool context_fog = true; | ||||
|  | ||||
| EX ld camera_level; | ||||
| EX bool draw_sky = true; | ||||
| EX bool camera_sign; | ||||
|  | ||||
| #if HDR | ||||
| enum eSkyMode { skyNone, skyAutomatic, skySkybox, skyAlways }; | ||||
| #endif | ||||
|  | ||||
| EX eSkyMode draw_sky; | ||||
|  | ||||
| EX bool auto_remove_roofs; | ||||
|  | ||||
| EX bool camera_over(ld x) { | ||||
|   if(!auto_remove_roofs) return false; | ||||
|   if(camera_sign) return camera_level <= x; | ||||
|   return camera_level >= x; | ||||
|   } | ||||
| @@ -41,16 +49,22 @@ struct dqi_sky : drawqueueitem { | ||||
|    | ||||
| EX struct dqi_sky *sky; | ||||
|  | ||||
| EX bool do_draw_skybox() { | ||||
|   if(no_wall_rendering) return false; | ||||
|   if(!euclid) return false; | ||||
|   if(draw_sky == skySkybox) return true; | ||||
|   if(!embedded_plane) return false; | ||||
|   if(draw_sky == skyAutomatic) return !cgi.emb->is_sph_in_low() && !cgi.emb->is_cylinder(); | ||||
|   return false; | ||||
|   } | ||||
|  | ||||
| EX void prepare_sky() { | ||||
|   sky = NULL; | ||||
|   if(euclid && !cgi.emb->is_sph_in_low() && !cgi.emb->is_cylinder()) { | ||||
|     if(WDIM == 3 || GDIM == 2) return; | ||||
|     if(no_wall_rendering) return; | ||||
|     if(!draw_sky) return; | ||||
|   if(do_draw_skybox()) { | ||||
|     shiftmatrix T = ggmatrix(currentmap->gamestart()); | ||||
|     T.T = gpushxto0(tC0(T.T)) * T.T; | ||||
|     queuepoly(T, cgi.shEuclideanSky, 0x0044e4FF); | ||||
|     queuepolyat(T * zpush(cgi.SKY+0.5) * xpush(cgi.SKY+0.5), cgi.shSun, 0xFFFF00FF, PPR::SKY); | ||||
|     queuepolyat(T * zpush(cgi.STAR * 0.7) * xpush(cgi.STAR * 0.7), cgi.shSkyboxSun, 0xFFFF00FF, PPR::SKY); | ||||
|     } | ||||
|   else { | ||||
|     sky = &queuea<dqi_sky> (euclid ? PPR::EUCLIDEAN_SKY : PPR::MISSILE); | ||||
| @@ -66,17 +80,35 @@ EX void delete_sky() { | ||||
|   skyvertices.clear(); | ||||
|   } | ||||
|  | ||||
| EX bool do_draw_sky() { | ||||
|   if(!embedded_plane) return false; | ||||
|   if(draw_sky == skyAlways) return true; | ||||
|   if(draw_sky != skyAutomatic) return false; | ||||
|  | ||||
|   if(vid.wall_height < 0 && cgi.emb->is_euc_in_hyp()) return false; /* just looks bad, hollow horospheres should not have sky */ | ||||
|   if(vid.wall_height < 0 && meuclid && geom3::ggclass() == gcNIH) return false; /* same */ | ||||
|   if(among(geom3::ggclass(), gcSol, gcSolN)) return false;  /* errors */ | ||||
|   if(among(geom3::ggclass(), gcNil)) return false;  /* errors sometimes too */ | ||||
|   if(cgi.emb->is_hyp_in_solnih()) return false; | ||||
|   if(cgi.emb->is_euc_in_product()) return false; | ||||
|   if(cgi.emb->is_euc_in_sl2()) return false; | ||||
|   if(cgi.emb->is_cylinder()) return false; | ||||
|  | ||||
|   return true; | ||||
|   } | ||||
|  | ||||
| EX bool do_draw_stars(bool rev) { | ||||
|   if(!do_draw_sky()) return false; | ||||
|   if(cgi.emb->is_sph_in_low()) { | ||||
|     if(cgi.SKY < 0) return false; | ||||
|     } | ||||
|   if(cgi.emb->is_euc_in_hyp() && (rev ? cgi.SKY > 0 : cgi.SKY < 0)) return false; | ||||
|   return true; | ||||
|   } | ||||
|  | ||||
| void compute_skyvertices(const vector<sky_item>& sky) { | ||||
|   skyvertices.clear(); | ||||
|   if(!draw_sky) return; | ||||
|   if(vid.wall_height < 0 && cgi.emb->is_euc_in_hyp()) return; /* just looks bad, hollow horospheres should not have sky */ | ||||
|   if(vid.wall_height < 0 && meuclid && geom3::ggclass() == gcNIH) return; /* same */ | ||||
|   if(among(geom3::ggclass(), gcSol, gcSolN)) return;  /* errors */ | ||||
|   if(among(geom3::ggclass(), gcNil)) return;  /* errors sometimes too */ | ||||
|   if(cgi.emb->is_hyp_in_solnih()) return; | ||||
|   if(cgi.emb->is_euc_in_product()) return; | ||||
|   if(cgi.emb->is_euc_in_sl2()) return; | ||||
|   if(cgi.emb->is_cylinder()) return; | ||||
|   if(!do_draw_sky()) return; | ||||
|  | ||||
|   int sk = get_skybrightness(); | ||||
|    | ||||
| @@ -87,7 +119,7 @@ void compute_skyvertices(const vector<sky_item>& sky) { | ||||
|         ); | ||||
|    | ||||
|   hyperpoint skypoint = cpush0(2, cgi.SKY); | ||||
|   hyperpoint hellpoint = cpush0(2, -cgi.SKY); | ||||
|   hyperpoint hellpoint = cpush0(2, cgi.HELL); | ||||
|    | ||||
|   vector<glhr::colored_vertex> this_poly; | ||||
|  | ||||
| @@ -271,7 +303,7 @@ void compute_skyvertices(const vector<sky_item>& sky) { | ||||
|  | ||||
| void dqi_sky::draw() { | ||||
|   if(!vid.usingGL || sky.empty() || skyvertices.empty()) return; | ||||
|   if(!draw_sky) { delete_sky(); return; } | ||||
|   if(!do_draw_sky()) { delete_sky(); return; } | ||||
|  | ||||
|   #if CAP_VR | ||||
|   transmatrix s = (vrhr::rendering() ? vrhr::master_cview : cview()).T * inverse(sky_cview.T); | ||||
| @@ -279,7 +311,8 @@ void dqi_sky::draw() { | ||||
|   transmatrix s = cview().T * inverse(sky_cview.T); | ||||
|   #endif | ||||
|      | ||||
|   if(euclid) be_euclidean_infinity(s); | ||||
|   be_euclidean_infinity(s); | ||||
|  | ||||
|   for(int ed = current_display->stereo_active() ? -1 : 0; ed<2; ed+=2) { | ||||
|     if(global_projection && global_projection != ed) continue; | ||||
|     current_display->next_shader_flags = GF_VARCOLOR; | ||||
| @@ -292,7 +325,7 @@ void dqi_sky::draw() { | ||||
|       glapplymatrix(s); | ||||
|       } | ||||
|     glhr::prepare(skyvertices); | ||||
|     glhr::set_fogbase(1.0 + 5 / sightranges[geometry]); | ||||
|     glhr::set_fogbase(1.0 + abs(cgi.SKY - cgi.LOWSKY) / sightranges[geometry]); | ||||
|     glhr::set_depthtest(model_needs_depth() && prio < PPR::SUPERLINE); | ||||
|     glhr::set_depthwrite(model_needs_depth() && prio != PPR::TRANSPARENT_SHADOW && prio != PPR::EUCLIDEAN_SKY); | ||||
|     glDrawArrays(GL_TRIANGLES, 0, isize(skyvertices)); | ||||
| @@ -306,28 +339,22 @@ color_t skycolor(cell *c) { | ||||
|   return gradient(0x4040FF, 0xFFFFFF, 0, z, 63); | ||||
|   } | ||||
|  | ||||
| EX bool use_euclidean_infinity = true; | ||||
|  | ||||
| /** move an Euclidean matrix to V(C0) == C0 */ | ||||
| EX void be_euclidean_infinity(transmatrix& V) { for(int i=0; i<3; i++) V[i][3] = 0; } | ||||
| EX void be_euclidean_infinity(transmatrix& V) { | ||||
|   if(euclid && msphere && use_euclidean_infinity) | ||||
|     for(int i=0; i<3; i++) V[i][3] = 0; | ||||
|   } | ||||
|  | ||||
| void draw_star(const shiftmatrix& V, const hpcshape& sh, color_t col, ld rev = false) { | ||||
|   ld star_val = 2; | ||||
|   bool have_stars = cgi.emb->is_same_in_same() || cgi.emb->is_sph_in_low() || cgi.emb->is_euc_in_hyp(); | ||||
|   if(cgi.emb->is_sph_in_low()) { | ||||
|     if(cgi.SKY < 0) have_stars = false; | ||||
|     if(euclid) star_val = 1.8; | ||||
|     } | ||||
|   if(cgi.emb->is_euc_in_hyp() && (rev ? cgi.SKY > 0 : cgi.SKY < 0)) have_stars = false; | ||||
|   if(!have_stars) return; | ||||
|   ld val = cgi.SKY+star_val; | ||||
|   if(!do_draw_stars(rev)) return; | ||||
|  | ||||
|   ld val = cgi.STAR; | ||||
|   if(rev) val = -val; | ||||
|  | ||||
|   if(euclid) { | ||||
|   auto V1 = V; be_euclidean_infinity(V1.T); | ||||
|     queuepolyat(V1 * zpush(val), sh, col, PPR::EUCLIDEAN_SKY); | ||||
|     } | ||||
|   else { | ||||
|     queuepolyat(V * zpush(val), sh, col, PPR::SKY); | ||||
|     } | ||||
|   queuepolyat(V1 * zpush(val), sh, col, PPR::SKY); | ||||
|   } | ||||
|  | ||||
| void celldrawer::draw_ceiling() { | ||||
| @@ -341,7 +368,6 @@ void celldrawer::draw_ceiling() { | ||||
|   switch(ceiling_category(c)) { | ||||
|     /* ceilingless levels */ | ||||
|     case 1: { | ||||
|       if(euclid && !cgi.emb->is_sph_in_low()) return; | ||||
|       if(fieldpattern::fieldval_uniq(c) % 3 == 0) | ||||
|         draw_star(V, cgi.shNightStar, 0xFFFFFFFF); | ||||
|       add_to_sky(0x00000F, 0x00000F); | ||||
| @@ -356,7 +382,6 @@ void celldrawer::draw_ceiling() { | ||||
|       } | ||||
|      | ||||
|     case 2: { | ||||
|       if(euclid && !cgi.emb->is_sph_in_low()) return; | ||||
|       color_t col; | ||||
|       color_t skycol; | ||||
|        | ||||
| @@ -464,7 +489,6 @@ void celldrawer::draw_ceiling() { | ||||
|             placeSidewall(c, i, SIDE_HIGH2, V, darkena(wcol2, fd, 0xFF)); | ||||
|         } | ||||
|       if(among(c->wall, waClosedGate, waOpenGate) && qfi.fshape) draw_shapevec(c, V, qfi.fshape->levels[SIDE_WALL], 0x202020FF, PPR::WALL); | ||||
|       if(euclid) return; | ||||
|  | ||||
|       draw_star(V, cgi.shNightStar, 0xFFFFFFFF); | ||||
|       break; | ||||
| @@ -517,7 +541,6 @@ void celldrawer::draw_ceiling() { | ||||
|       else if(qfi.fshape) | ||||
|         draw_shapevec(c, V, qfi.fshape->levels[SIDE_WALL], darkena(fcol, fd, 0xFF), PPR::WALL); | ||||
|  | ||||
|       if(euclid) return; | ||||
|       draw_star(V, cgi.shNightStar, 0xFFFFFFFF); | ||||
|       break; | ||||
|       } | ||||
| @@ -539,6 +562,7 @@ EX void swap_if_missing(bool missing) { | ||||
|  | ||||
| EX void make_air() { | ||||
|   if(!sky) return; | ||||
|   if(!embedded_plane) return; | ||||
|  | ||||
|   if(centerover != sky_centerover) { | ||||
|     sky_centerover = centerover; | ||||
| @@ -547,6 +571,7 @@ EX void make_air() { | ||||
|     } | ||||
|    | ||||
|   if(!context_fog) return; | ||||
|   if(vrhr::rendering()) return; | ||||
|  | ||||
|   const int AIR_TEXTURE = 512; | ||||
|   if(!airbuf) { | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 Zeno Rogue
					Zeno Rogue