mirror of
				https://github.com/zenorogue/hyperrogue.git
				synced 2025-10-31 14:02:59 +00:00 
			
		
		
		
	stereographic projection added
This commit is contained in:
		
							
								
								
									
										25
									
								
								config.cpp
									
									
									
									
									
								
							
							
						
						
									
										25
									
								
								config.cpp
									
									
									
									
									
								
							| @@ -1027,6 +1027,7 @@ EX void initConfig() { | |||||||
|   param_f(camera_rot_speed, "camrot", "camera-rot-speed", 1); |   param_f(camera_rot_speed, "camrot", "camera-rot-speed", 1); | ||||||
|  |  | ||||||
|   param_f(panini_alpha, "panini_alpha", 0); |   param_f(panini_alpha, "panini_alpha", 0); | ||||||
|  |   param_f(stereo_alpha, "stereo_alpha", 0); | ||||||
|  |  | ||||||
|   callhooks(hooks_configfile); |   callhooks(hooks_configfile); | ||||||
|    |    | ||||||
| @@ -1863,14 +1864,15 @@ EX void explain_detail() { | |||||||
|   } |   } | ||||||
|  |  | ||||||
| EX ld max_fov_angle() { | EX ld max_fov_angle() { | ||||||
|   if(panini_alpha >= 1 || panini_alpha <= -1) return 360; |   auto& p = panini_alpha ? panini_alpha : stereo_alpha; | ||||||
|   return acos(-panini_alpha) * 2 / degree; |   if(p >= 1 || p <= -1) return 360; | ||||||
|  |   return acos(-p) * 2 / degree; | ||||||
|   } |   } | ||||||
|  |  | ||||||
| EX void add_edit_fov(char key IS('f'), bool pop IS(false)) { | EX void add_edit_fov(char key IS('f'), bool pop IS(false)) { | ||||||
|  |  | ||||||
|   string sfov = fts(vid.fov) + "°"; |   string sfov = fts(vid.fov) + "°"; | ||||||
|   if(panini_alpha) { |   if(panini_alpha || stereo_alpha) { | ||||||
|     sfov += " / " + fts(max_fov_angle()) + "°"; |     sfov += " / " + fts(max_fov_angle()) + "°"; | ||||||
|     } |     } | ||||||
|   dialog::addSelItem(XLAT("field of view"), sfov, key); |   dialog::addSelItem(XLAT("field of view"), sfov, key); | ||||||
| @@ -1897,7 +1899,22 @@ EX void add_edit_fov(char key IS('f'), bool pop IS(false)) { | |||||||
|             "The Panini projection is an alternative perspective projection " |             "The Panini projection is an alternative perspective projection " | ||||||
|             "which allows very wide field-of-view values. HyperRogue uses " |             "which allows very wide field-of-view values. HyperRogue uses " | ||||||
|             "a quick implementation, so parameter values too close to 1 may " |             "a quick implementation, so parameter values too close to 1 may " | ||||||
|             "be buggy; try e.g. 0.9 instead.") |             "be buggy (outside of raycasting); try e.g. 0.9 instead.") | ||||||
|  |             ); | ||||||
|  |         dialog::reaction = reset_all_shaders; | ||||||
|  |         dialog::extra_options = [] { | ||||||
|  |           add_edit_fov('F', true); | ||||||
|  |           }; | ||||||
|  |         }); | ||||||
|  |       dialog::addSelItem(XLAT("spherical perspective projection"), fts(stereo_alpha), 'S'); | ||||||
|  |       dialog::add_action([] { | ||||||
|  |         popScreen(); | ||||||
|  |         dialog::editNumber(stereo_alpha, 0, 1, 0.1, 0, "spherical perspective parameter",  | ||||||
|  |           XLAT( | ||||||
|  |             "Set to 1 to get stereographic projection, " | ||||||
|  |             "which allows very wide field-of-view values. HyperRogue uses " | ||||||
|  |             "a quick implementation, so parameter values too close to 1 may " | ||||||
|  |             "be buggy (outside of raycasting); try e.g. 0.9 instead.") | ||||||
|             ); |             ); | ||||||
|         dialog::reaction = reset_all_shaders; |         dialog::reaction = reset_all_shaders; | ||||||
|         dialog::extra_options = [] { |         dialog::extra_options = [] { | ||||||
|   | |||||||
| @@ -23,6 +23,7 @@ EX bool wmspatial, wmescher, wmplain, wmblack, wmascii, wmascii3; | |||||||
| EX bool mmspatial, mmhigh, mmmon, mmitem; | EX bool mmspatial, mmhigh, mmmon, mmitem; | ||||||
|  |  | ||||||
| EX ld panini_alpha = 0; | EX ld panini_alpha = 0; | ||||||
|  | EX ld stereo_alpha = 0; | ||||||
|  |  | ||||||
| EX int detaillevel = 0; | EX int detaillevel = 0; | ||||||
|  |  | ||||||
| @@ -3742,7 +3743,7 @@ EX bool clip_checked = false; | |||||||
| void make_clipping_planes() { | void make_clipping_planes() { | ||||||
| #if MAXMDIM >= 4 | #if MAXMDIM >= 4 | ||||||
|   clip_checked = false; |   clip_checked = false; | ||||||
|   if(!frustum_culling || PIU(sphere) || experimental || vid.stereo_mode == sODS || panini_alpha) return; |   if(!frustum_culling || PIU(sphere) || experimental || vid.stereo_mode == sODS || panini_alpha || stereo_alpha) return; | ||||||
|  |  | ||||||
|   if(WDIM == 3 && pmodel == mdPerspective && !nonisotropic && !in_s2xe()) |   if(WDIM == 3 && pmodel == mdPerspective && !nonisotropic && !in_s2xe()) | ||||||
|     threshold = sin_auto(cgi.corner_bonus), xyz_threshold = 0, clip_checked = true; |     threshold = sin_auto(cgi.corner_bonus), xyz_threshold = 0, clip_checked = true; | ||||||
| @@ -4980,7 +4981,7 @@ EX void calcparam() { | |||||||
|   cd->ycenter += cd->scrsize * pconf.yposition; |   cd->ycenter += cd->scrsize * pconf.yposition; | ||||||
|    |    | ||||||
|   ld fov = vid.fov * degree / 2; |   ld fov = vid.fov * degree / 2; | ||||||
|   cd->tanfov = sin(fov) / (cos(fov) + panini_alpha); |   cd->tanfov = sin(fov) / (cos(fov) + (panini_alpha ? panini_alpha : stereo_alpha)); | ||||||
|    |    | ||||||
|   callhooks(hooks_calcparam); |   callhooks(hooks_calcparam); | ||||||
|   reset_projection(); |   reset_projection(); | ||||||
|   | |||||||
| @@ -892,6 +892,10 @@ EX namespace models { | |||||||
|       PHASEFROM(2);  |       PHASEFROM(2);  | ||||||
|       shift_arg_formula(panini_alpha, reset_all_shaders); |       shift_arg_formula(panini_alpha, reset_all_shaders); | ||||||
|       } |       } | ||||||
|  |     else if(argis("-salpha")) {  | ||||||
|  |       PHASEFROM(2);  | ||||||
|  |       shift_arg_formula(stereo_alpha, reset_all_shaders); | ||||||
|  |       } | ||||||
|     else if(argis("-zoom")) {  |     else if(argis("-zoom")) {  | ||||||
|       PHASEFROM(2); shift_arg_formula(vpconf.scale); |       PHASEFROM(2); shift_arg_formula(vpconf.scale); | ||||||
|       } |       } | ||||||
|   | |||||||
| @@ -436,7 +436,23 @@ void enable_raycaster() { | |||||||
|           "at0.xyz *= hz+alpha;\n" |           "at0.xyz *= hz+alpha;\n" | ||||||
|           "at0.z = hz;\n}" |           "at0.z = hz;\n}" | ||||||
|           " else at0.z = 0.;\n" |           " else at0.z = 0.;\n" | ||||||
| "\n" |           "\n" | ||||||
|  |           ; | ||||||
|  |  | ||||||
|  |       else if(stereo_alpha) fmain +=  | ||||||
|  |           "mediump float hr = at0.x*at0.x+at0.y*at0.y;\n" | ||||||
|  |           "mediump float alpha = " + to_glsl(stereo_alpha) + ";\n" | ||||||
|  |           "mediump float A = 1. + hr;\n" | ||||||
|  |           "mediump float B = -2.*hr*alpha;\n" | ||||||
|  |           "mediump float C = 1. - hr*alpha*alpha;\n" | ||||||
|  |           "B /= A; C /= A;\n" | ||||||
|  |      | ||||||
|  |           "mediump float hz = B / 2. + sqrt(C + B*B/4.);\n" | ||||||
|  |           "if(abs(hz) > 1e-3) {" | ||||||
|  |           "at0.xyz *= hz+alpha;\n" | ||||||
|  |           "at0.z = hz;\n}" | ||||||
|  |           " else at0.z = 0.;\n" | ||||||
|  |           "\n" | ||||||
|           ; |           ; | ||||||
|  |  | ||||||
|       fmain += |       fmain += | ||||||
| @@ -1241,6 +1257,9 @@ void enable_raycaster() { | |||||||
|     if(panini_alpha)  |     if(panini_alpha)  | ||||||
|       fmain += panini_shader(); |       fmain += panini_shader(); | ||||||
|  |  | ||||||
|  |     else if(stereo_alpha)  | ||||||
|  |       fmain += stereo_shader(); | ||||||
|  |  | ||||||
|     #ifndef GLES_ONLY |     #ifndef GLES_ONLY | ||||||
|     fmain +=     |     fmain +=     | ||||||
|       "      gl_FragDepth = (" + to_glsl(-vnear-vfar)+"+t.w*" + to_glsl(2*vnear*vfar)+"/t.z)/" + to_glsl(vnear-vfar)+";\n" |       "      gl_FragDepth = (" + to_glsl(-vnear-vfar)+"+t.w*" + to_glsl(2*vnear*vfar)+"/t.z)/" + to_glsl(vnear-vfar)+";\n" | ||||||
|   | |||||||
							
								
								
									
										15
									
								
								shaders.cpp
									
									
									
									
									
								
							
							
						
						
									
										15
									
								
								shaders.cpp
									
									
									
									
									
								
							| @@ -77,6 +77,17 @@ EX string panini_shader() { | |||||||
|     "t.w = 1.;\n"; |     "t.w = 1.;\n"; | ||||||
|   } |   } | ||||||
|  |  | ||||||
|  | EX string stereo_shader() { | ||||||
|  |   return | ||||||
|  |     "t.w += 1.; t *= 2. / t.w; t.w -= 1.;\n" | ||||||
|  |     "float s = t.z;\n" | ||||||
|  |     "float l = length(t.xyz);\n" | ||||||
|  |     "t /= max(l, 1e-2);\n" | ||||||
|  |     "t.z += " + glhr::to_glsl(panini_alpha) + ";\n" | ||||||
|  |     "t *= l;\n" | ||||||
|  |     "t.w = 1.;\n"; | ||||||
|  |   } | ||||||
|  |  | ||||||
| shared_ptr<glhr::GLprogram> write_shader(flagtype shader_flags) { | shared_ptr<glhr::GLprogram> write_shader(flagtype shader_flags) { | ||||||
|   string varying, vsh, fsh, vmain = "void main() {\n", fmain = "void main() {\n"; |   string varying, vsh, fsh, vmain = "void main() {\n", fmain = "void main() {\n"; | ||||||
|  |  | ||||||
| @@ -415,6 +426,10 @@ shared_ptr<glhr::GLprogram> write_shader(flagtype shader_flags) { | |||||||
|       vmain += panini_shader(); |       vmain += panini_shader(); | ||||||
|       shader_flags |= SF_ORIENT; |       shader_flags |= SF_ORIENT; | ||||||
|       } |       } | ||||||
|  |     else if((shader_flags & SF_PERS3) && stereo_alpha) { | ||||||
|  |       vmain += "t = uPP * t;", vsh += "uniform mediump mat4 uPP;"; | ||||||
|  |       vmain += stereo_shader(); | ||||||
|  |       } | ||||||
|        |        | ||||||
|     vmain += "gl_Position = uP * t;\n"; |     vmain += "gl_Position = uP * t;\n"; | ||||||
|     } |     } | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 Zeno Rogue
					Zeno Rogue