2D3D:: skies and ceilings

This commit is contained in:
Zeno Rogue 2019-05-20 13:40:56 +02:00
parent 04a7e560a2
commit 8eb3fa65e2
7 changed files with 228 additions and 25 deletions

View File

@ -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++)

View File

@ -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) {

View File

@ -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
View File

@ -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
}

View File

@ -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 {

View File

@ -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++) {

View File

@ -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;",