mirror of
				https://github.com/zenorogue/hyperrogue.git
				synced 2025-10-31 14:02:59 +00:00 
			
		
		
		
	sky-based fog in 2.5D
This commit is contained in:
		| @@ -582,6 +582,8 @@ EX void initConfig() { | ||||
|       sightranges[i] = 10; | ||||
|     else if(ginf[i].cclass == gcSL2) | ||||
|       sightranges[i] = 4.5; | ||||
|     else if(ginf[i].cclass == gcHyperbolic && ginf[i].g.gameplay_dimension == 2) | ||||
|       sightranges[i] = 4.5; | ||||
|     else | ||||
|       sightranges[i] = 5; | ||||
|     sightranges[gArchimedean] = 10; | ||||
|   | ||||
| @@ -1999,6 +1999,8 @@ void dqi_line::draw_back() { | ||||
|  | ||||
| EX void sort_drawqueue() { | ||||
|  | ||||
|   if(WDIM == 2 && GDIM == 3 && hyperbolic) make_air(); | ||||
|  | ||||
|   DEBBI(DF_GRAPH, ("sort_drawqueue")); | ||||
|    | ||||
|   for(int a=0; a<PMAX; a++) qp[a] = 0; | ||||
|   | ||||
							
								
								
									
										6
									
								
								glhr.cpp
									
									
									
									
									
								
							
							
						
						
									
										6
									
								
								glhr.cpp
									
									
									
									
									
								
							| @@ -273,8 +273,8 @@ struct GLprogram { | ||||
|   GLuint _program; | ||||
|   GLuint vertShader, fragShader; | ||||
|  | ||||
|   GLint uFog, uFogColor, uColor, tTexture, tInvExpTable, uMV, uProjection, uAlpha, uFogBase, uPP; | ||||
|   GLint uPRECX, uPRECY, uPRECZ, uIndexSL, uIterations, uLevelLines, uSV; | ||||
|   GLint uFog, uFogColor, uColor, tTexture, tInvExpTable, tAirMap, uMV, uProjection, uAlpha, uFogBase, uPP; | ||||
|   GLint uPRECX, uPRECY, uPRECZ, uIndexSL, uIterations, uLevelLines, uSV, uRadarTransform; | ||||
|    | ||||
|   flagtype shader_flags; | ||||
|    | ||||
| @@ -392,6 +392,7 @@ GLprogram::GLprogram(string vsh, string fsh) { | ||||
|   uColor = glGetUniformLocation(_program, "uColor"); | ||||
|   tTexture = glGetUniformLocation(_program, "tTexture"); | ||||
|   tInvExpTable = glGetUniformLocation(_program, "tInvExpTable"); | ||||
|   tAirMap = glGetUniformLocation(_program, "tAirMap"); | ||||
|  | ||||
|   uPRECX = glGetUniformLocation(_program, "PRECX"); | ||||
|   uPRECY = glGetUniformLocation(_program, "PRECY"); | ||||
| @@ -400,6 +401,7 @@ GLprogram::GLprogram(string vsh, string fsh) { | ||||
|   uSV = glGetUniformLocation(_program, "uSV"); | ||||
|   uIterations = glGetUniformLocation(_program, "uIterations");   | ||||
|   uLevelLines = glGetUniformLocation(_program, "uLevelLines"); | ||||
|   uRadarTransform = glGetUniformLocation(_program, "uRadarTransform"); | ||||
|   } | ||||
|  | ||||
| GLprogram::~GLprogram() { | ||||
|   | ||||
							
								
								
									
										45
									
								
								shaders.cpp
									
									
									
									
									
								
							
							
						
						
									
										45
									
								
								shaders.cpp
									
									
									
									
									
								
							| @@ -44,6 +44,7 @@ constexpr int aTexture = 8; | ||||
|  | ||||
| /* texture bindings */ | ||||
| constexpr int INVERSE_EXP_BINDING = 2; | ||||
| constexpr int AIR_BINDING = 4; | ||||
| #endif | ||||
|  | ||||
| EX map<string, shared_ptr<glhr::GLprogram>> compiled_programs; | ||||
| @@ -268,7 +269,39 @@ shared_ptr<glhr::GLprogram> write_shader(flagtype shader_flags) { | ||||
|   if(!skip_t) { | ||||
|     vmain += "mediump vec4 t = uMV * aPosition;\n"; | ||||
|     vmain += coordinator; | ||||
|     if(distfun != "") { | ||||
|     if(GDIM == 3 && WDIM == 2) { | ||||
|       vsh +=  | ||||
|         "uniform mediump mat4 uRadarTransform;\n" | ||||
|         "uniform mediump sampler2D tAirMap;\n" | ||||
|         "uniform mediump float uFog;\n" | ||||
|         "uniform mediump float uFogBase;\n" | ||||
|         "vec4 color_at(vec4 ending, float dist) {" | ||||
|         "    vec3 pt = ending.xyz * sinh(dist);\n" | ||||
|         "    pt.xy /= sqrt(pt.z*pt.z+1.);\n" | ||||
|         "    pt.xy /= 2. * (1. + sqrt(1.+pt.x*pt.x+pt.y*pt.y));\n" | ||||
|         "    pt.xy += vec2(.5, .5);\n" | ||||
|         "    return texture2D(tAirMap, pt.xy);\n" | ||||
|         "    }\n"; | ||||
|  | ||||
|       vmain +=  | ||||
|         "vec4 ending = uRadarTransform * t;\n" | ||||
|         "float len = acosh(ending.w);\n" | ||||
|         "float eulen = length(ending.xyz);\n" | ||||
|         "ending.xyz /= eulen;\n" | ||||
|         "ending.y *= -1.;\n" | ||||
|         "vec4 fog = vec4(1e-3,0,1e-3,1e-3);\n" | ||||
|         "vec4 last = vec4(0,0,0,0);\n" | ||||
|         "for(int i=0; i<50; i++) {\n" | ||||
|         "  vec4 px = color_at(ending, ((float(i) + .5) / 50.) * min(len, uFog));\n" | ||||
|         "  if(px.r < .9 || px.b < .9 || px.g > .1) last = px;\n" | ||||
|         "  fog += last;\n" | ||||
|         "  }\n" | ||||
|         "mediump float fogs = (uFogBase - len / uFog);\n" | ||||
|         "if(fogs < 0.) fogs = 0.;\n" | ||||
|         "fog.xyz /= fog.w;\n" | ||||
|         "vColor.xyz = vColor.xyz * fogs + fog.xyz * (1.0-fogs);\n"; | ||||
|       } | ||||
|     else if(distfun != "") { | ||||
|       vmain += "mediump float fogs = (uFogBase - " + distfun + " / uFog);\n"; | ||||
|       vmain += "vColor.xyz = vColor.xyz * fogs + uFogColor.xyz * (1.0-fogs);\n"; | ||||
|       vsh +=  | ||||
| @@ -357,6 +390,16 @@ void display_data::set_projection(int ed, ld shift) { | ||||
|     } | ||||
|   #endif | ||||
|    | ||||
|   if(selected->tAirMap != -1) { | ||||
|     glActiveTexture(GL_TEXTURE0 + AIR_BINDING); | ||||
|     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); | ||||
|     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); | ||||
|     glBindTexture(GL_TEXTURE_2D, airbuf->renderedTexture); | ||||
|     glUniform1i(selected->tAirMap, AIR_BINDING); | ||||
|     glActiveTexture(GL_TEXTURE0 + 0); | ||||
|     glUniformMatrix4fv(selected->uRadarTransform, 1, 0, glhr::tmtogl_transpose3(radar_transform).as_array()); | ||||
|     } | ||||
|    | ||||
|   if(selected->uIterations != -1) { | ||||
|     glhr::set_index_sl(0); | ||||
|     glhr::set_sv(stretch::not_squared()); | ||||
|   | ||||
							
								
								
									
										191
									
								
								sky.cpp
									
									
									
									
									
								
							
							
						
						
									
										191
									
								
								sky.cpp
									
									
									
									
									
								
							| @@ -16,7 +16,8 @@ struct sky_item { | ||||
|   cell *c; | ||||
|   shiftmatrix T; | ||||
|   color_t color; | ||||
|   sky_item(cell *_c, const struct shiftmatrix _T, color_t _color) : c(_c), T(_T), color(_color) {} | ||||
|   color_t skycolor; | ||||
|   sky_item(cell *_c, const struct shiftmatrix _T, color_t _color, color_t _skycolor) : c(_c), T(_T), color(_color), skycolor(_skycolor) {} | ||||
|   }; | ||||
|  | ||||
| struct dqi_sky : drawqueueitem { | ||||
| @@ -41,7 +42,7 @@ EX void prepare_sky() { | ||||
|     queuepolyat(T * zpush(cgi.SKY+0.5) * xpush(cgi.SKY+0.5), cgi.shSun, 0xFFFF00FF, PPR::SKY); | ||||
|     } | ||||
|   else if(!(cgflags & qIDEAL)) { | ||||
|     sky = &queuea<dqi_sky> (PPR::SKY); | ||||
|     sky = &queuea<dqi_sky> (PPR::MISSILE); | ||||
|     } | ||||
|   } | ||||
|  | ||||
| @@ -52,13 +53,17 @@ void dqi_sky::draw() { | ||||
|  | ||||
|   int sk = get_skybrightness(); | ||||
|    | ||||
|   unordered_map<cell*, color_t> colors; | ||||
|   unordered_map<cell*, pair<color_t, color_t>> colors; | ||||
|   #ifdef USE_UNORDERED_MAP | ||||
|   colors.reserve(isize(sky)); | ||||
|   #endif | ||||
|   for(sky_item& si: sky) colors[si.c] = darkena(gradient(0, si.color, 0, sk, 255), 0, 0xFF); | ||||
|   for(sky_item& si: sky) colors[si.c] =  | ||||
|     make_pair(darkena(gradient(0, si.color, 0, sk, 255), 0, 0xFF), | ||||
|         darkena(si.skycolor, 0, 0xFF) | ||||
|         ); | ||||
|    | ||||
|   hyperpoint skypoint = cpush0(2, cgi.SKY); | ||||
|   hyperpoint hellpoint = cpush0(2, -cgi.SKY); | ||||
|    | ||||
|   vector<glhr::colored_vertex> this_poly; | ||||
|    | ||||
| @@ -72,12 +77,42 @@ void dqi_sky::draw() { | ||||
|     auto c = si.c; | ||||
|     for(int i=0; i<c->type; i++) { | ||||
|        | ||||
|       if(1) { | ||||
|         cellwalker cw0(c, i); | ||||
|         cellwalker cw2 = cw0; | ||||
|         cw2--; cw2 += wstep; | ||||
|         if(!colors.count(cw2.at)) { | ||||
|           this_poly.clear(); | ||||
|           transmatrix T1 = unshift(si.T); | ||||
|           T1 = Tsh * T1; | ||||
|           auto cw = cw0; | ||||
|           while(colors.count(cw.at)) { | ||||
|             color_t col = colors[cw.at].second; | ||||
|             this_poly.emplace_back(T1 * skypoint, colors[cw.at].first); | ||||
|             this_poly.emplace_back(T1 * hellpoint, col); | ||||
|             T1 = T1 * currentmap->adj(cw.at, cw.spin); | ||||
|             cw += wstep; cw++; | ||||
|             } | ||||
|  | ||||
|           int k = isize(this_poly); | ||||
|           for(int j=2; j<k; j+=2) { | ||||
|             skyvertices.push_back(this_poly[j-2]); | ||||
|             skyvertices.push_back(this_poly[j-1]); | ||||
|             skyvertices.push_back(this_poly[j]); | ||||
|             skyvertices.push_back(this_poly[j-1]); | ||||
|             skyvertices.push_back(this_poly[j]); | ||||
|             skyvertices.push_back(this_poly[j+1]); | ||||
|             } | ||||
|           goto next; | ||||
|           }         | ||||
|         } | ||||
|  | ||||
|       if(1) { | ||||
|         cellwalker cw0(c, i); | ||||
|         cellwalker cw = cw0; | ||||
|         do { | ||||
|           cw += wstep; cw++; | ||||
|           if(cw.at < c || !colors.count(si.c)) goto next; | ||||
|           if(cw.at < c || !colors.count(cw.at)) goto next; | ||||
|           } | ||||
|         while(cw != cw0); | ||||
|            | ||||
| @@ -86,7 +121,7 @@ void dqi_sky::draw() { | ||||
|         transmatrix T1 = unshift(si.T); | ||||
|         T1 = Tsh * T1; | ||||
|         do { | ||||
|           this_poly.emplace_back(T1 * skypoint, colors[cw.at]); | ||||
|           this_poly.emplace_back(T1 * skypoint, colors[cw.at].first); | ||||
|           T1 = T1 * currentmap->adj(cw.at, cw.spin); | ||||
|           cw += wstep; cw++; | ||||
|           } | ||||
| @@ -125,20 +160,17 @@ color_t skycolor(cell *c) { | ||||
|   int cd = (euclid || stdhyperbolic) ? getCdata(c, 1) : 0; | ||||
|   int z = (cd * 5) & 127; | ||||
|   if(z >= 64) z = 127 - z; | ||||
|   if(c->land == laHell) | ||||
|     return z < 32 ? gradient(0x400000, 0xFF0000, 0, z, 32) : gradient(0xFF0000, 0xFFFF00, 32, z, 63); | ||||
|   else | ||||
|     return gradient(0x4040FF, 0xFFFFFF, 0, z, 63); | ||||
|   return gradient(0x4040FF, 0xFFFFFF, 0, z, 63); | ||||
|   } | ||||
|  | ||||
| void celldrawer::draw_ceiling() { | ||||
|  | ||||
|   if(pmodel != mdPerspective || sphere) return; | ||||
|    | ||||
|   auto add_to_sky = [this] (color_t col) { | ||||
|   auto add_to_sky = [this] (color_t col, color_t col2) { | ||||
|     if(cgflags & qIDEAL) | ||||
|       draw_shapevec(c, V, qfi.fshape->levels[SIDE_HIGH], darkena(col, 0, 0xFF), PPR::WALL); | ||||
|     else if(sky) sky->sky.emplace_back(c, V, col); | ||||
|     else if(sky) sky->sky.emplace_back(c, V, col, col2); | ||||
|     }; | ||||
|    | ||||
|   switch(ceiling_category(c)) { | ||||
| @@ -148,7 +180,7 @@ void celldrawer::draw_ceiling() { | ||||
|       if(fieldpattern::fieldval_uniq(c) % 3 == 0) { | ||||
|         queuepolyat(V * zpush(cgi.SKY+1), cgi.shNightStar, 0xFFFFFFFF, PPR::SKY); | ||||
|         } | ||||
|       add_to_sky(0x00000F); | ||||
|       add_to_sky(0x00000F, 0x00000F); | ||||
|       if(c->land == laAsteroids) { | ||||
|         if(fieldpattern::fieldval_uniq(c) % 9 < 3) { | ||||
|           queuepolyat(V * zpush(-1-cgi.SKY), cgi.shNightStar, 0xFFFFFFFF, PPR::SKY); | ||||
| @@ -163,10 +195,12 @@ void celldrawer::draw_ceiling() { | ||||
|     case 2: { | ||||
|       if(euclid) return; | ||||
|       color_t col; | ||||
|       color_t skycol; | ||||
|        | ||||
|       switch(c->land) { | ||||
|         case laWineyard: | ||||
|           col = 0x4040FF; | ||||
|           skycol = 0x8080FF; | ||||
|           if(emeraldval(c) / 4 == 11) { | ||||
|             queuepolyat(V * zpush(cgi.SKY+1), cgi.shSun, 0xFFFF00FF, PPR::SKY); | ||||
|             } | ||||
| @@ -174,22 +208,23 @@ void celldrawer::draw_ceiling() { | ||||
|  | ||||
|         case laFrog: | ||||
|           col = 0x4040FF; | ||||
|           skycol = 0x8080FF; | ||||
|           if(zebra40(c) / 4 == 1) { | ||||
|             queuepolyat(V * zpush(cgi.SKY+1), cgi.shSun, 0xFFFF00FF, PPR::SKY); | ||||
|             } | ||||
|           break; | ||||
|  | ||||
|         case laPower: | ||||
|           col = c->landparam ? 0xFF2010 : 0x000020; | ||||
|           skycol = col = c->landparam ? 0xFF2010 : 0x000020; | ||||
|           break; | ||||
|          | ||||
|         case laDesert: | ||||
|         case laRedRock: | ||||
|           col = 0x4040FF; | ||||
|           skycol = (0xCDA98F & 0xFEFEFE) / 2; | ||||
|           break; | ||||
|          | ||||
|         case laAlchemist: | ||||
|           col = fcol; | ||||
|           skycol = col = fcol; | ||||
|           break; | ||||
|          | ||||
|         case laVariant: { | ||||
| @@ -199,22 +234,38 @@ void celldrawer::draw_ceiling() { | ||||
|             if((b >> a) & 1) | ||||
|               col += variant::features[a].color_change; | ||||
|           col = col & 0x00FF00; | ||||
|           skycol = col; | ||||
|           break; | ||||
|           } | ||||
|          | ||||
|         case laDragon: | ||||
|           col = c->wall == waChasm ? 0xFFFFFF : 0x4040FF; | ||||
|           skycol = 0; | ||||
|           break; | ||||
|          | ||||
|         default:  | ||||
|         case laHell: { | ||||
|           int a = 0; | ||||
|           forCellEx(c1, c) if(among(c1->wall, waSulphur, waSulphurC)) a++; | ||||
|           ld z = a * 1. / c->type; | ||||
|           if(z < .5) | ||||
|             col = gradient(0x400000, 0xFF0000, 0, z, .5); | ||||
|           else | ||||
|             col = gradient(0xFF0000, 0xFFFF00, .5, z, 1); | ||||
|           skycol = col; | ||||
|           break; | ||||
|           } | ||||
|          | ||||
|         default: { | ||||
|           col = skycolor(c);         | ||||
|           skycol = 0xA0A0FF; | ||||
|           } | ||||
|         } | ||||
|       add_to_sky(col); | ||||
|       add_to_sky(col, skycol); | ||||
|       return; | ||||
|       } | ||||
|      | ||||
|     case 3: { | ||||
|       add_to_sky(0); | ||||
|       add_to_sky(0, 0); | ||||
|       if(camera_level <= cgi.WALL) return; | ||||
|       if(c->land == laMercuryRiver) fcol = linf[laTerracotta].color, fd = 1; | ||||
|       if(qfi.fshape) draw_shapevec(c, V, qfi.fshape->levels[SIDE_WALL], darkena(fcol, fd, 0xFF), PPR::WALL); | ||||
| @@ -229,7 +280,7 @@ void celldrawer::draw_ceiling() { | ||||
|       } | ||||
|      | ||||
|     case 4: { | ||||
|       add_to_sky(0x00000F); | ||||
|       add_to_sky(0x00000F, 0x00000F); | ||||
|       if(camera_level <= cgi.HIGH2) return; | ||||
|       auto ispal = [&] (cell *c0) { return c0->land == laPalace && among(c0->wall, waPalace, waClosedGate, waOpenGate); }; | ||||
|       color_t wcol2 = 0xFFD500; | ||||
| @@ -255,7 +306,7 @@ void celldrawer::draw_ceiling() { | ||||
|       } | ||||
|      | ||||
|     case 6: { | ||||
|       add_to_sky(skycolor(c)); | ||||
|       add_to_sky(skycolor(c), 0x4040C0); | ||||
|       if(camera_level <= cgi.HIGH2) return; | ||||
|       color_t wcol2 = winf[waRuinWall].color; | ||||
|       if(c->landparam == 1) | ||||
| @@ -264,15 +315,15 @@ void celldrawer::draw_ceiling() { | ||||
|       if(c->landparam != 2) | ||||
|         forCellIdEx(c2, i, c) if(c2->landparam == 2) | ||||
|           placeSidewall(c, i, SIDE_HIGH2, V, darkena(wcol2, fd, 0xFF)); | ||||
|       if(c->landparam == 0) | ||||
|         if(qfi.fshape) draw_shapevec(c, V, qfi.fshape->levels[SIDE_HIGH], darkena(wcol2, fd, 0xFF), PPR::WALL); | ||||
|       /* if(c->landparam == 0) | ||||
|         if(qfi.fshape) draw_shapevec(c, V, qfi.fshape->levels[SIDE_HIGH], darkena(wcol2, fd, 0xFF), PPR::WALL); */ | ||||
|       if(c->landparam == 1) | ||||
|         if(qfi.fshape) draw_shapevec(c, V, qfi.fshape->levels[SIDE_WALL], darkena(wcol2, fd, 0xFF), PPR::WALL); | ||||
|       break; | ||||
|       } | ||||
|      | ||||
|     case 7: { | ||||
|       add_to_sky(0x00000F); | ||||
|       add_to_sky(0x00000F, 0x00000F); | ||||
|       if(fieldpattern::fieldval_uniq(c) % 5 < 2) { | ||||
|         queuepolyat(V * zpush(cgi.SKY+1), cgi.shNightStar, 0xFFFFFFFF, PPR::SKY); | ||||
|         } | ||||
| @@ -292,7 +343,7 @@ void celldrawer::draw_ceiling() { | ||||
|       } | ||||
|      | ||||
|     case 5: { | ||||
|       add_to_sky(0x00000F); | ||||
|       add_to_sky(0x00000F, 0x00000F); | ||||
|       if(camera_level <= cgi.WALL) return; | ||||
|      | ||||
|       if(pseudohept(c)) { | ||||
| @@ -309,5 +360,95 @@ void celldrawer::draw_ceiling() { | ||||
|       } | ||||
|     } | ||||
|   } | ||||
|  | ||||
| EX struct renderbuffer *airbuf; | ||||
|  | ||||
| EX void make_air() { | ||||
|   if(!sky) return; | ||||
|   const int AIR_TEXTURE = 512; | ||||
|   if(!airbuf) { | ||||
|     airbuf = new renderbuffer(AIR_TEXTURE, AIR_TEXTURE, true); | ||||
|     if(!airbuf->valid) { | ||||
|       delete airbuf; | ||||
|       airbuf = nullptr; | ||||
|       println(hlog, "unable to make airbuf"); | ||||
|       return; | ||||
|       } | ||||
|     } | ||||
|  | ||||
|   if(1) { | ||||
|     //shot::take("airtest.png", drawqueue);  | ||||
|     dynamicval<videopar> v(vid, vid);     | ||||
|     dynamicval<bool> vi(inHighQual, true); | ||||
|  | ||||
|     vid.xres = AIR_TEXTURE; | ||||
|     vid.yres = AIR_TEXTURE; | ||||
|     calcparam(); | ||||
|     models::configure(); | ||||
|    | ||||
|     resetbuffer rb; | ||||
|     airbuf->enable(); | ||||
|     current_display->set_viewport(0); | ||||
|    | ||||
|     airbuf->clear(0xFFFF00FF); | ||||
|  | ||||
|     pconf.alpha = 1; | ||||
|     pconf.scale = 1; | ||||
|     pconf.camera_angle = 0; | ||||
|     pconf.stretch = 1; | ||||
|     pmodel = mdDisk; | ||||
|  | ||||
|     vid.always3 = false; | ||||
|     geom3::apply_always3();     | ||||
|     check_cgi(); | ||||
|     cgi.require_shapes(); | ||||
|      | ||||
|     eGeometry orig = geometry; | ||||
|  | ||||
|     glDisable(GL_LINE_SMOOTH); | ||||
|      | ||||
|     for(auto& g: sky->sky) { | ||||
|       transmatrix S; | ||||
|       if(1) { | ||||
|         geometry = gSpace534; | ||||
|         S = g.T.T; | ||||
|         S = radar_transform * S; | ||||
|         geometry = orig; | ||||
|         swapmatrix(S); | ||||
|         } | ||||
|        | ||||
|       auto& h = cgi.shFullFloor.b[shvid(g.c)]; | ||||
|  | ||||
|       dqi_poly p; | ||||
|       p.V = shiftless(S); | ||||
|       p.offset = h.s; | ||||
|       p.cnt = h.e - h.s; | ||||
|       p.tab = &cgi.ourshape; | ||||
|       p.color = (g.skycolor << 8) | 0xFF; | ||||
|       p.outline = 0; | ||||
|        | ||||
|       p.linewidth = 1; | ||||
|       p.flags = POLY_FORCEWIDE; | ||||
|       p.tinf = nullptr; | ||||
|        | ||||
|       p.draw(); | ||||
|       } | ||||
|  | ||||
|     if(vid.antialias & AA_LINES) | ||||
|       glEnable(GL_LINE_SMOOTH); | ||||
|  | ||||
|     if(anyshiftclick) IMAGESAVE(airbuf->render(), "air.png"); | ||||
|     rb.reset(); | ||||
|     } | ||||
|  | ||||
|   GLERR("after draw"); | ||||
|   geom3::apply_always3(); | ||||
|   check_cgi(); | ||||
|   calcparam(); | ||||
|   GLERR("after make_air"); | ||||
|   current_display->set_viewport(0); | ||||
|   current_display->set_all(0,0); | ||||
|   } | ||||
|  | ||||
| #endif | ||||
| } | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 Zeno Rogue
					Zeno Rogue