mirror of
https://github.com/zenorogue/hyperrogue.git
synced 2025-03-20 02:17:02 +00:00
2D3D:: skies and ceilings
This commit is contained in:
parent
04a7e560a2
commit
8eb3fa65e2
@ -1070,6 +1070,8 @@ void make_3d_models() {
|
||||
make_ball(shDisk, orbsize*.2, 2);
|
||||
make_ball(shHeptaMarker, zhexf*.2, 1);
|
||||
make_ball(shSnowball, zhexf*.1, 0);
|
||||
make_ball(shSun, 3, 5);
|
||||
make_ball(shNightStar, 0.75, 2);
|
||||
|
||||
if(WDIM == 2) {
|
||||
for(int i=0; i<3; i++)
|
||||
|
@ -712,43 +712,44 @@ void set_floor(const transmatrix& spin, hpcshape& sh) {
|
||||
qfi.usershape = -1;
|
||||
}
|
||||
|
||||
void draw_shapevec(cell *c, const transmatrix& V, const vector<hpcshape> &shv, color_t col, PPR prio = PPR::DEFAULT) {
|
||||
if(!c) queuepolyat(V, shv[0], col, prio);
|
||||
else if(WDIM == 3) ;
|
||||
dqi_poly *draw_shapevec(cell *c, const transmatrix& V, const vector<hpcshape> &shv, color_t col, PPR prio = PPR::DEFAULT) {
|
||||
if(!c) return &queuepolyat(V, shv[0], col, prio);
|
||||
else if(WDIM == 3) return NULL;
|
||||
#if CAP_GP
|
||||
else if(GOLDBERG) {
|
||||
int id = gp::get_plainshape_id(c);
|
||||
if(isize(shv) > id) queuepolyat(V, shv[id], col, prio);
|
||||
if(isize(shv) > id) return &queuepolyat(V, shv[id], col, prio);
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
#if CAP_IRR
|
||||
else if(IRREGULAR) {
|
||||
int id = irr::cellindex[c];
|
||||
if(id < 0 || id >= isize(shv)) {
|
||||
return;
|
||||
return NULL;
|
||||
}
|
||||
queuepolyat(V, shv[id], col, prio);
|
||||
return &queuepolyat(V, shv[id], col, prio);
|
||||
}
|
||||
#endif
|
||||
#if CAP_ARCM
|
||||
else if(archimedean) {
|
||||
queuepolyat(V, shv[arcm::id_of(c->master)], col, prio);
|
||||
return &queuepolyat(V, shv[arcm::id_of(c->master)], col, prio);
|
||||
}
|
||||
#endif
|
||||
else if((euclid || GOLDBERG) && ishex1(c))
|
||||
queuepolyat(V * pispin, shv[0], col, prio);
|
||||
return &queuepolyat(V * pispin, shv[0], col, prio);
|
||||
else if(!(S7&1) && PURE) {
|
||||
auto si = patterns::getpatterninfo(c, patterns::PAT_COLORING, 0);
|
||||
if(si.id == 8) si.dir++;
|
||||
transmatrix D = applyPatterndir(c, si);
|
||||
queuepolyat(V*D, shv[pseudohept(c)], col, prio);
|
||||
return &queuepolyat(V*D, shv[pseudohept(c)], col, prio);
|
||||
}
|
||||
else if(geosupport_threecolor() == 2)
|
||||
queuepolyat(V, shv[pseudohept(c)], col, prio);
|
||||
return &queuepolyat(V, shv[pseudohept(c)], col, prio);
|
||||
else if(binarytiling)
|
||||
queuepolyat(V, shv[c->type-6], col, prio);
|
||||
return &queuepolyat(V, shv[c->type-6], col, prio);
|
||||
else
|
||||
queuepolyat(V, shv[ctof(c)], col, prio);
|
||||
return &queuepolyat(V, shv[ctof(c)], col, prio);
|
||||
}
|
||||
|
||||
void draw_floorshape(cell *c, const transmatrix& V, const floorshape &fsh, color_t col, PPR prio = PPR::DEFAULT) {
|
||||
|
@ -268,7 +268,7 @@ namespace geom3 {
|
||||
LEG0, LEG1, LEG, LEG3, GROIN, GROIN1, GHOST,
|
||||
BODY, BODY1, BODY2, BODY3,
|
||||
NECK1, NECK, NECK3, HEAD, HEAD1, HEAD2, HEAD3,
|
||||
ALEG0, ALEG, ABODY, AHEAD, BIRD;
|
||||
ALEG0, ALEG, ABODY, AHEAD, BIRD, LOWSKY, SKY;
|
||||
|
||||
string invalid;
|
||||
|
||||
@ -335,7 +335,7 @@ namespace geom3 {
|
||||
BIRD = 1.20;
|
||||
}
|
||||
else {
|
||||
INFDEEP = GDIM == 3 ? (sphere ? M_PI/2 : +10) : (euclid || sphere) ? 0.01 : lev_to_projection(0) * tanh(camera);
|
||||
INFDEEP = GDIM == 3 ? (sphere ? M_PI/2 : +5) : (euclid || sphere) ? 0.01 : lev_to_projection(0) * tanh(camera);
|
||||
ld wh = actual_wall_height();
|
||||
WALL = lev_to_factor(wh);
|
||||
FLOOR = lev_to_factor(0);
|
||||
@ -381,6 +381,8 @@ namespace geom3 {
|
||||
LAKE = lev_to_factor(-lake_top);
|
||||
HELLSPIKE = lev_to_factor(-(lake_top+lake_bottom)/2);
|
||||
BOTTOM = lev_to_factor(-lake_bottom);
|
||||
LOWSKY = lev_to_factor((1 + rock_wall_ratio) * wh);
|
||||
SKY = LOWSKY - 5;
|
||||
}
|
||||
}
|
||||
|
||||
|
179
graph.cpp
179
graph.cpp
@ -4473,6 +4473,180 @@ void queue_transparent_wall(const transmatrix& V, hpcshape& sh, color_t color) {
|
||||
}
|
||||
}
|
||||
|
||||
int ceiling_category(cell *c) {
|
||||
switch(c->land) {
|
||||
case laNone:
|
||||
case laMemory:
|
||||
case laMirrorWall2:
|
||||
case laMirrored:
|
||||
case laMirrored2:
|
||||
case landtypes:
|
||||
return 0;
|
||||
|
||||
/* starry levels */
|
||||
case laIce:
|
||||
case laCrossroads:
|
||||
case laCrossroads2:
|
||||
case laCrossroads3:
|
||||
case laCrossroads4:
|
||||
case laCrossroads5:
|
||||
case laJungle:
|
||||
case laGraveyard:
|
||||
case laMotion:
|
||||
case laRedRock:
|
||||
case laZebra:
|
||||
case laHunting:
|
||||
case laEAir:
|
||||
case laStorms:
|
||||
case laMountain:
|
||||
case laHaunted:
|
||||
case laHauntedWall:
|
||||
case laHauntedBorder:
|
||||
case laWhirlwind:
|
||||
case laDragon:
|
||||
case laBurial:
|
||||
case laHalloween:
|
||||
case laReptile:
|
||||
case laVolcano:
|
||||
case laBlizzard:
|
||||
case laDual:
|
||||
case laWestWall:
|
||||
case laAsteroids:
|
||||
return 1;
|
||||
|
||||
case laWineyard:
|
||||
case laDesert:
|
||||
case laAlchemist:
|
||||
case laDryForest:
|
||||
case laCaribbean:
|
||||
case laMinefield:
|
||||
case laOcean:
|
||||
case laWhirlpool:
|
||||
case laLivefjord:
|
||||
case laEWater:
|
||||
case laOceanWall:
|
||||
case laWildWest:
|
||||
case laOvergrown:
|
||||
case laClearing:
|
||||
case laRose:
|
||||
case laWarpCoast:
|
||||
case laWarpSea:
|
||||
case laEndorian:
|
||||
case laTortoise:
|
||||
case laPrairie:
|
||||
case laSnakeNest:
|
||||
case laDocks:
|
||||
case laKraken:
|
||||
case laBrownian:
|
||||
return 2;
|
||||
|
||||
case laBarrier:
|
||||
case laCaves:
|
||||
case laMirror:
|
||||
case laMirrorOld:
|
||||
case laRlyeh:
|
||||
case laHell:
|
||||
case laCocytus:
|
||||
case laEmerald:
|
||||
case laDeadCaves:
|
||||
case laPower:
|
||||
case laHive:
|
||||
case laCamelot:
|
||||
case laTemple:
|
||||
case laPalace:
|
||||
case laPrincessQuest:
|
||||
case laIvoryTower:
|
||||
case laEFire:
|
||||
case laEEarth:
|
||||
case laElementalWall:
|
||||
case laCanvas:
|
||||
case laTrollheim:
|
||||
case laDungeon:
|
||||
case laBull:
|
||||
case laCA:
|
||||
case laMirrorWall:
|
||||
case laTerracotta:
|
||||
case laMercuryRiver:
|
||||
case laRuins:
|
||||
case laMagnetic:
|
||||
case laSwitch:
|
||||
case laVariant:
|
||||
return 3;
|
||||
|
||||
default:
|
||||
return 4;
|
||||
}
|
||||
}
|
||||
|
||||
ld camera_level;
|
||||
|
||||
int get_skybrightness() {
|
||||
ld s = 1 - (camera_level - geom3::WALL) / -2;
|
||||
if(s > 1) return 255;
|
||||
if(s < 0) return 0;
|
||||
return int(s * 255);
|
||||
}
|
||||
|
||||
void draw_ceiling(cell *c, const transmatrix& V, int fd, color_t& fcol, color_t& wcol) {
|
||||
|
||||
if(pmodel != mdPerspective || sphere) return;
|
||||
|
||||
switch(ceiling_category(c)) {
|
||||
/* ceilingless levels */
|
||||
case 1: {
|
||||
if(fieldpattern::fieldval_uniq(c) % 3 == 0) {
|
||||
auto &star = queuepolyat(V * zpush(geom3::SKY+0.5), shNightStar, 0xFFFFFFFF, PPR::SKY);
|
||||
star.tinf = NULL;
|
||||
star.flags |= POLY_INTENSE;
|
||||
}
|
||||
int sk = get_skybrightness();
|
||||
if(sk > 0) {
|
||||
auto sky = draw_shapevec(c, V, shFullFloor.levels[SIDE_SKY], 0x000000FF + 0x100 * (sk/17), PPR::SKY);
|
||||
if(sky) sky->tinf = NULL, sky->flags |= POLY_INTENSE;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
case 2: {
|
||||
color_t col;
|
||||
if(c->land == laWineyard) {
|
||||
col = 0x4040FF;
|
||||
if(emeraldval(c) / 4 == 11) {
|
||||
auto &sun = queuepolyat(V * zpush(geom3::SKY+0.5), shSun, 0xFFFF00FF, PPR::SKY);
|
||||
sun.tinf = NULL;
|
||||
sun.flags |= POLY_INTENSE;
|
||||
}
|
||||
}
|
||||
else {
|
||||
int cd = (euclid || stdhyperbolic) ? getCdata(c, 1) : 0;
|
||||
int z = cd & 127;
|
||||
if(z >= 64) z = 127 - z;
|
||||
col = gradient(0x4040FF, 0xFFFFFF, 0, z, 63);
|
||||
}
|
||||
int sk = get_skybrightness();
|
||||
if(sk > 0) {
|
||||
col = gradient(0, col, 0, sk, 255);
|
||||
col = darkena(col, 0, 255);
|
||||
auto sky = draw_shapevec(c, V, shFullFloor.levels[SIDE_SKY], col, PPR::SKY);
|
||||
if(sky) sky->tinf = NULL;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
case 3: {
|
||||
if(camera_level <= geom3::WALL) return;
|
||||
draw_shapevec(c, V, qfi.fshape->levels[SIDE_WALL], darkena(fcol, fd, 0xFF), PPR::WALL);
|
||||
forCellIdEx(c2, i, c)
|
||||
if(ceiling_category(c2) != 3) {
|
||||
color_t wcol2 = gradient(0, wcol, 0, .8, 1);
|
||||
placeSidewall(c, i, SIDE_SKY, V, darkena(wcol2, fd, 0xFF));
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void drawcell_in_radar(cell *c, transmatrix V) {
|
||||
#if CAP_SHMUP
|
||||
if(shmup::on) {
|
||||
@ -5299,6 +5473,10 @@ void drawcell(cell *c, transmatrix V, int spinv, bool mirrored) {
|
||||
draw_qfi(c, V, darkena(fcol, fd, flooralpha));
|
||||
}
|
||||
|
||||
// draw the ceiling
|
||||
if(WDIM == 2 && GDIM == 3)
|
||||
draw_ceiling(c, V, fd, fcol, wcol);
|
||||
|
||||
// walls
|
||||
|
||||
#if CAP_EDIT
|
||||
@ -6488,6 +6666,7 @@ void make_actual_view() {
|
||||
ld max = WDIM == 2 ? geom3::camera : vid.yshift;
|
||||
if(max)
|
||||
actual_view_transform = zpush(wall_radar(viewctr.at->c7, inverse(View), max)) * actual_view_transform;
|
||||
camera_level = asin_auto(tC0(inverse(actual_view_transform * View))[2]);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
5
hyper.h
5
hyper.h
@ -2156,7 +2156,7 @@ enum class PPR {
|
||||
MONSTER_HOODCLOAK1, MONSTER_HOODCLOAK2,
|
||||
STUNSTARS,
|
||||
CARRIED, CARRIEDa, CARRIEDb,
|
||||
PARTICLE, SWORDMARK, MAGICSWORD, MISSILE,
|
||||
PARTICLE, SWORDMARK, MAGICSWORD, MISSILE, SKY,
|
||||
MINEMARK, ARROW,
|
||||
MOBILE_ARROW,
|
||||
LINE,
|
||||
@ -4250,7 +4250,8 @@ void set_blizzard_frame(cell *c, int frameid);
|
||||
#define SIDE_LAKE 5
|
||||
#define SIDE_LTOB 6
|
||||
#define SIDE_BTOI 7
|
||||
#define SIDEPARS 8
|
||||
#define SIDE_SKY 8
|
||||
#define SIDEPARS 9
|
||||
|
||||
#if CAP_SHAPES
|
||||
struct floorshape {
|
||||
|
@ -88,6 +88,9 @@ static const int POLY_ALWAYS_IN = (1<<21);
|
||||
// made of TRIANGLES, not TRIANGLE_FAN
|
||||
static const int POLY_TRIANGLES = (1<<22);
|
||||
|
||||
// extra intense colors
|
||||
static const int POLY_INTENSE = (1<<23);
|
||||
|
||||
vector<hyperpoint> hpc;
|
||||
basic_textureinfo user_triangles_texture;
|
||||
|
||||
@ -670,9 +673,10 @@ void dqi_poly::gldraw() {
|
||||
|
||||
if(draw) {
|
||||
if(flags & POLY_TRIANGLES) {
|
||||
glhr::color2(color);
|
||||
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);
|
||||
glhr::set_fogbase(prio == PPR::SKY ? 1.0 + 5 / sightranges[geometry] : 1.0);
|
||||
glDrawArrays(GL_TRIANGLES, ioffset, cnt);
|
||||
}
|
||||
else {
|
||||
@ -1714,7 +1718,7 @@ hpcshape
|
||||
shKnife, shTongue, shFlailMissile, shTrapArrow,
|
||||
shPirateHook, shPirateHood, shEyepatch, shPirateX,
|
||||
// shScratch,
|
||||
shHeptaMarker, shSnowball,
|
||||
shHeptaMarker, shSnowball, shSun, shNightStar,
|
||||
shSkeletonBody, shSkull, shSkullEyes, shFatBody, shWaterElemental,
|
||||
shPalaceGate, shFishTail,
|
||||
shMouse, shMouseLegs, shMouseEyes,
|
||||
@ -2056,6 +2060,7 @@ void make_sidewalls() {
|
||||
dfloor_table[SIDE_LAKE] = geom3::LAKE;
|
||||
dfloor_table[SIDE_LTOB] = geom3::BOTTOM;
|
||||
dfloor_table[SIDE_BTOI] = geom3::INFDEEP;
|
||||
dfloor_table[SIDE_SKY ] = geom3::SKY;
|
||||
|
||||
// sidewall parameters for the 3D mode
|
||||
for(int k=0; k<SIDEPARS; k++) {
|
||||
|
27
shaders.cpp
27
shaders.cpp
@ -26,6 +26,7 @@ namespace glhr {
|
||||
bool glew = false;
|
||||
|
||||
bool current_depthtest, current_depthwrite;
|
||||
ld fogbase;
|
||||
|
||||
typedef const void *constvoidptr;
|
||||
|
||||
@ -204,7 +205,7 @@ struct GLprogram {
|
||||
GLuint _program;
|
||||
GLuint vertShader, fragShader;
|
||||
|
||||
GLint uMVP, uFog, uColor, tTexture, uMV, uProjection, uAlpha;
|
||||
GLint uMVP, uFog, uColor, tTexture, uMV, uProjection, uAlpha, uFogBase;
|
||||
|
||||
GLprogram(string vsh, string fsh) {
|
||||
_program = glCreateProgram();
|
||||
@ -255,6 +256,7 @@ struct GLprogram {
|
||||
uProjection = glGetUniformLocation(_program, "uP");
|
||||
uMVP = glGetUniformLocation(_program, "uMVP");
|
||||
uFog = glGetUniformLocation(_program, "uFog");
|
||||
uFogBase = glGetUniformLocation(_program, "uFogBase");
|
||||
uAlpha = glGetUniformLocation(_program, "uAlpha");
|
||||
uColor = glGetUniformLocation(_program, "uColor");
|
||||
tTexture = glGetUniformLocation(_program, "tTexture");
|
||||
@ -450,6 +452,7 @@ void switch_mode(eMode m, shader_projection sp) {
|
||||
glDisable(GL_LIGHTING); */
|
||||
#endif
|
||||
}
|
||||
glUniform1f(current->uFogBase, 1); fogbase = 1;
|
||||
mode = m;
|
||||
current_shader_projection = sp;
|
||||
GLERR("after_switch_mode");
|
||||
@ -472,6 +475,15 @@ void fog_max(ld fogmax) {
|
||||
#endif
|
||||
}
|
||||
|
||||
void set_fogbase(ld _fogbase) {
|
||||
#if CAP_SHADER
|
||||
if(fogbase != _fogbase) {
|
||||
fogbase = _fogbase;
|
||||
glUniform1f(current->uFogBase, fogbase);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void set_ualpha(ld alpha) {
|
||||
glUniform1f(current->uAlpha, alpha);
|
||||
}
|
||||
@ -534,6 +546,7 @@ void init() {
|
||||
mps, "uniform mediump mat4 uMV;",
|
||||
mps, "uniform mediump mat4 uP;",
|
||||
1, "uniform mediump float uFog;",
|
||||
1, "uniform mediump float uFogBase;",
|
||||
ball, "uniform mediump float uAlpha;",
|
||||
!varcol, "uniform mediump vec4 uColor;",
|
||||
|
||||
@ -593,13 +606,13 @@ void init() {
|
||||
hp && dim3, "t.x /= -rads; t.y /= -rads; t.z /= -rads; t[3] = 1.0;",
|
||||
|
||||
s3, "vec4 t = uMV * aPosition;",
|
||||
sh3, "vColor.xyz = vColor.xyz * (1.0 - acosh(t[3]) / uFog);",
|
||||
sr3, "vColor.xyz = vColor.xyz * (1.0 - sqrt(t[0]*t[0] + t[1]*t[1] + t[2]*t[2]) / uFog);",
|
||||
sh3, "vColor.xyz = vColor.xyz * (uFogBase - acosh(t[3]) / uFog);",
|
||||
sr3, "vColor.xyz = vColor.xyz * (uFogBase - sqrt(t[0]*t[0] + t[1]*t[1] + t[2]*t[2]) / uFog);",
|
||||
|
||||
ss30, "vColor.xyz = vColor.xyz * (1.0 - (6.284 - acos(t[3])) / uFog); t = -t; ",
|
||||
ss31, "vColor.xyz = vColor.xyz * (1.0 - (6.284 - acos(t[3])) / uFog); t.xyz = -t.xyz; ",
|
||||
ss32, "vColor.xyz = vColor.xyz * (1.0 - acos(t[3]) / uFog); t.w = -t.w; ", // 2pi
|
||||
ss33, "vColor.xyz = vColor.xyz * (1.0 - acos(t[3]) / uFog); ",
|
||||
ss30, "vColor.xyz = vColor.xyz * (uFogBase - (6.284 - acos(t[3])) / uFog); t = -t; ",
|
||||
ss31, "vColor.xyz = vColor.xyz * (uFogBase - (6.284 - acos(t[3])) / uFog); t.xyz = -t.xyz; ",
|
||||
ss32, "vColor.xyz = vColor.xyz * (uFogBase - acos(t[3]) / uFog); t.w = -t.w; ", // 2pi
|
||||
ss33, "vColor.xyz = vColor.xyz * (uFogBase - acos(t[3]) / uFog); ",
|
||||
sh3 || sr3 || ball,"t[3] = 1.0;",
|
||||
|
||||
band || hp || s3 || ball,"gl_Position = uP * t;",
|
||||
|
Loading…
x
Reference in New Issue
Block a user