1
0
mirror of https://github.com/zenorogue/hyperrogue.git synced 2025-05-10 19:24:06 +00:00
hyperrogue/rogueviz/ru/render.cpp
2025-04-18 15:05:21 +02:00

289 lines
7.5 KiB
C++

namespace rogue_unlike {
shiftmatrix scrm;
void prepare_tinf() {
auto add_vertex = [&] (double bx, double by) {
roomtinf.tvertices.push_back(glhr::makevertex(bx / screen_x, 1 - by / screen_y, 0));
cgi.hpc.push_back(to_hyper(bx, by));
};
cgi.bshape(roomshape, PPR::WALL);
for(int by=t_margin_at; by<b_margin_at; by+=block_y)
for(int bx=l_margin_at; bx<r_margin_at; bx+=block_x) {
add_vertex(bx, by);
add_vertex(bx+block_x, by);
add_vertex(bx+block_x, by+block_y);
add_vertex(bx, by);
add_vertex(bx, by+block_y);
add_vertex(bx+block_x, by+block_y);
}
cgi.last->flags |= POLY_TRIANGLES;
cgi.last->tinf = &roomtinf;
cgi.last->texture_offset = 0;
int q = isize(roomtinf.tvertices);
cgi.bshape(roomshape_big, PPR::WALL_TOP);
for(int by=0; by<screen_y; by+=block_y)
for(int bx=0; bx<screen_x; bx+=block_x) {
add_vertex(bx, by);
add_vertex(bx+block_x, by);
add_vertex(bx+block_x, by+block_y);
add_vertex(bx, by);
add_vertex(bx, by+block_y);
add_vertex(bx+block_x, by+block_y);
}
cgi.last->flags |= POLY_TRIANGLES;
cgi.last->tinf = &roomtinf;
cgi.last->texture_offset = q;
cgi.finishshape();
cgi.extra_vertices();
println(hlog, "sizes: ", tuple(roomshape_big.e - roomshape_big.s, roomshape.e - roomshape.s));
}
void room::create_texture() {
/* if(room_texture) return;
room_texture = new texture::texture_data;
auto& tex = *room_texture;
tex.twidth = tex.theight = 256;
tex.tx = screen_x;
tex.ty = screen_y;
tex.stretched = false;
tex.strx = tex.tx;
tex.stry = tex.ty;
tex.base_x = 0;
tex.base_y = (tex.theight - tex.ty) / 2; */
if(rbuf) return;
rbuf = new renderbuffer(screen_x, screen_y, true);
}
struct dqi_poly_tex : dqi_poly {
int texture_id;
void draw() override { if(tinf) tinf->texture_id = texture_id; dqi_poly::draw(); }
};
basic_textureinfo sprite_vertices;
void render_room(room *r);
bool draw_room_on_map(cell *c, const shiftmatrix& V) {
hr::addaura(tC0(V), pconf.alpha == 1 ? 0xFF00FF00 : 0xFF00FFFF, 0);
if(!rooms.count(c)) {
c->landparam = 0x101010;
get_room_at(c);
return false;
}
auto& r = rooms[c];
if(!r.rbuf || &r == current_room || r.which_map_rendered != should_apply_fov() || r.need_rerender) {
vector<unique_ptr<drawqueueitem>> alt_ptds;
swap(ptds, alt_ptds);
render_room(&r);
swap(ptds, alt_ptds);
calcparam();
}
if(!r.rbuf) return false;
bool big = (&r == current_room);
auto& sh = big ? roomshape_big : roomshape;
auto& p = queuea<dqi_poly_tex> (sh.prio);
p.V = V;
p.offset = sh.s;
p.cnt = sh.e - sh.s;
p.color = 0xFFFFFFFF;
p.tab = &cgi.ourshape;
p.flags = sh.flags;
p.tinf = &roomtinf;
p.tinf->texture_id = r.rbuf->renderedTexture;
p.offset_texture = sh.texture_offset;
p.texture_id = r.rbuf->renderedTexture;
if(big || cmode == mode::editmap) {
dynamicval<color_t> po(poly_outline, 0x80FF80FF);
queuepolyat(V, cgi.shFullFloor.b[0], 0, PPR::LINE);
}
// render_room_objects(&r, render_at);
return true;
}
void asciiletter(ld minx, ld miny, ld maxx, ld maxy, const string& ch, color_t col);
void compute_scrm() {
ld tx = screen_x;
ld ty = screen_y;
ld scalex = (vid.xres/2) / (current_display->radius * tx);
ld scaley = (vid.yres/2) / (current_display->radius * ty);
ld scale = min(scalex, scaley);
scale *= 4;
scrm = shiftless(Id);
scrm.T[0][2] = (- screen_x/2) * scale;
scrm.T[1][2] = (- screen_y/2) * scale;
scrm.T[0][0] = scale;
scrm.T[1][1] = scale;
scrm.T[2][2] = 1;
}
void render_room_walls(room *r) {
initquickqueue();
bool af = should_apply_fov();
for(int y=0; y<room_y; y++)
for(int x=0; x<room_x; x++) {
if(af && !r->fov[y][x]) continue;
char c = r->block_at[y][x];
// ld sx = 1.5;
// ld sy = 1.3;
int cc = c >> 3;
if((c & 7) == 0)
asciiletter(x*block_x, y*block_y, (x+1)*block_x, (y+1)*block_y, walls[cc].glyph, walls[cc].color);
if((c & 7) == 4)
asciiletter(x*block_x, y*block_y, (x+2)*block_x, (y+2)*block_y, walls[cc].glyph, walls[cc].color);
if(gravision) {
int minx = x*block_x, maxx = (x+1)*block_x;
int miny = y*block_y, maxy = (y+1)*block_y;
for(int a: {0, 1, 3, 2, 0})
curvepoint(hyperpoint((a&1)?minx:maxx, (a&2)?miny:maxy, 1, 0));
color_t r = rainbow_color(1, all_locations[y][x].potential * 30);
r <<= 8;
queuecurve(scrm, r | 0xFF, r | 0x80, PPR::LINE);
}
}
quickqueue();
}
void render_room(room *r) {
r->create_texture();
resetbuffer rb;
r->rbuf->enable();
dynamicval<videopar> v(vid, vid);
vid.xres = r->rbuf->tx;
vid.yres = r->rbuf->ty;
calcparam();
current_display->set_viewport(0);
r->rbuf->clear(0xFF000000);
flat_model_enabler fme;
compute_scrm();
render_room_walls(r);
render_room_objects(r);
rb.reset();
r->which_map_rendered = should_apply_fov();
r->need_rerender = false;
GLERR("render_room");
}
transmatrix letterscales[128];
void init_scales() {
for(int i=0; i<128; i++) letterscales[i] = Id;
letterscales['#'] = euscale(1.5, 1.2);
letterscales['*'] = eupush(0, 0.4) * euscale(1.5, 2);
letterscales['~'] = eupush(0, -0.4) * euscale(1.5, 1.2);
letterscales[')'] = euscale(2.5, 1);
letterscales['('] = euscale(2.5, 1);
}
void asciiletter(ld minx, ld miny, ld maxx, ld maxy, const string& ch, color_t col) {
ld medx = (minx + maxx) / 2;
ld medy = (miny + maxy) / 2;
write_in_space(scrm * eupush(medx, medy) * euscale(maxx-minx, maxy-miny) * letterscales[int(ch[0])],
max_glfont_size, 2, ch, col, 0, 8, PPR::TEXT, rupf);
if(anyshiftclick) {
for(int a: {0, 1, 3, 2, 0})
curvepoint(hyperpoint((a&1)?minx:maxx, (a&2)?miny:maxy, 1, 0));
queuecurve(scrm, 0xFF0000FF, 0xFF000080, PPR::LINE);
}
}
void entity::draw() {
double d = get_scale();
gwhere_x = where_x; gwhere_y = where_y;
ld minx = min(where_x, gwhere_x) - sx() * d / 2;
ld miny = min(where_y, gwhere_y) - sy() * d / 2;
ld maxx = max(where_x, gwhere_x) + sx() * d / 2;
ld maxy = max(where_y, gwhere_y) + sy() * d / 2;
asciiletter(minx, miny, maxx, maxy, glyph(), color());
}
void man::draw() {
entity::draw();
ld t = gframeid - attack_when;
if(t < 50) {
auto af = attack_facing * (1 - t * 0.01);
asciiletter(
where_x + af * dsx() - dsx()/2, where_y - dsy()/2,
where_x + af * dsx() + dsx()/2, where_y + dsy()/2,
attack_facing == -1 ? "(" : ")", 0xFFFFFF00 + (255 - t * 5)
);
}
}
void render_room_objects(room *r) {
initquickqueue();
if(r == current_room) m.draw();
for(auto& e: r->entities) e->draw();
quickqueue();
}
int mousepx, mousepy;
void draw_room() {
flat_model_enabler fme;
compute_scrm();
if(false) {
basic_textureinfo bti;
bti.texture_id = current_room->rbuf->renderedTexture;
ld cx[6] = {1,0,0,0,1,1};
ld cy[6] = {1,1,0,0,0,1};
for(int i=0; i<6; i++) {
bti.tvertices.emplace_back(glhr::makevertex(cx[i], 1 - cy[i], 0));
curvepoint(eupoint(cx[i] * screen_x, cy[i] * screen_y));
}
initquickqueue();
auto& q = queuecurve(scrm, 0xFFFFFFFF, 0xFFFFFFFF, PPR::LINE);
q.tinf = &bti; q.flags |= POLY_TRIANGLES; q.offset_texture = 0;
quickqueue();
}
if(true) {
render_room_walls(current_room);
}
render_room_objects(current_room);
ld& scale = scrm.T[0][0];
mousepx = (mousex - current_display->xcenter) * 2 / scale / current_display->radius + screen_x/2;
mousepy = (mousey - current_display->ycenter) * 2 / scale / current_display->radius + screen_y/2;
}
}