From 0ef619739eb8401b07c54c913a65b94e35d0407a Mon Sep 17 00:00:00 2001 From: Zeno Rogue Date: Thu, 16 Apr 2020 03:36:48 +0200 Subject: [PATCH] textures in wrl export --- floorshapes.cpp | 15 +++- screenshot.cpp | 227 ++++++++++++++++++++++++++++++++++++------------ 2 files changed, 186 insertions(+), 56 deletions(-) diff --git a/floorshapes.cpp b/floorshapes.cpp index 1dabc4f7..6faa9cd1 100644 --- a/floorshapes.cpp +++ b/floorshapes.cpp @@ -1011,6 +1011,8 @@ auto floor_hook = #if MAXMDIM >= 4 +EX ld floor_texture_square_size; + void draw_shape_for_texture(floorshape* sh) { int id = sh->id; @@ -1071,16 +1073,23 @@ void draw_shape_for_texture(floorshape* sh) { floor_texture_map[sh->id] = tmap; } - // SL2 needs 6 times more - texture_order([&] (ld x, ld y) { + auto tvec_at = [&] (ld x, ld y) { hyperpoint h = center + v1 * x + v2 * y; hyperpoint inmodel; applymodel(h, inmodel); glvec2 v; v[0] = (1 + inmodel[0] * vid.scale) / 2; v[1] = (1 - inmodel[1] * vid.scale) / 2; + return v; + }; + + // SL2 needs 6 times more + texture_order([&] (ld x, ld y) { + auto v = tvec_at(x, y); ftv.tvertices.push_back(glhr::makevertex(v[0], v[1], 0)); }); + + floor_texture_square_size = 2 * (tvec_at(1, 0)[0] - tvec_at(0, 0)[0]); } /** copy the texture vertices so that there are at least qty of them */ @@ -1102,7 +1111,9 @@ EX void bind_floor_texture(hpcshape& li, int id) { ensure_vertex_number(li); } +#if HDR const int FLOORTEXTURESIZE = 4096; +#endif void geometry_information::make_floor_textures_here() { require_shapes(); diff --git a/screenshot.cpp b/screenshot.cpp index b8d57809..08016d94 100644 --- a/screenshot.cpp +++ b/screenshot.cpp @@ -339,25 +339,38 @@ EX always_false in; bool used_rug; + map, int> texture_position; + map gradient_position; + + pair texid(dqi_poly& p) { + return make_pair(p.color, p.tinf->tvertices[0]); + } + + /** 0 = no/unknown texture, 1 = rug, 2 = gradient, 3 = floor texture */ + EX int texture_type(dqi_poly& p) { + if(!p.tinf) return 0; + if(p.tinf == &rug::tinf) return 1; + if(p.tinf->texture_id == (int) floor_textures->renderedTexture) + return (p.tinf->tvertices[0][0] == 0) ? 2 : 3; + return 0; + } + + EX void prepare(dqi_poly& p) { + if(print && !(p.flags & POLY_PRINTABLE)) return; + if(!(p.flags & POLY_TRIANGLES)) return; + int tt = texture_type(p); + if(tt == 2) gradient_position[p.color] = 0; + if(tt == 3) texture_position[texid(p)] = 0; + } + + int fts_int, fts, fts_row; + + map, vector>> all_data; + EX void polygon(dqi_poly& p) { if(print && !(p.flags & POLY_PRINTABLE)) return; if(!(p.flags & POLY_TRIANGLES)) return; - println(f, "Shape {"); - println(f, " appearance Appearance {"); - println(f, " material Material {"); - println(f, " diffuseColor ", color(p.color, .8)); - if(part(p.color, 0) != 255) println(f, " transparency ", (255 - part(p.color, 0)) / 255.); - println(f, " }"); - if(p.tinf && p.tinf == &rug::tinf) { - println(f, " texture ImageTexture {"); - println(f, " url \"", filename, "-rug.png\""); - println(f, " }"); - used_rug = true; - } - println(f, " }"); - // println(f, "# V = ", p.V); - println(f, " geometry IndexedFaceSet {"); - println(f, " coord Coordinate {"); + int tt = texture_type(p); vector data; vector tdata; @@ -379,54 +392,85 @@ EX always_false in; else if(print) { hyperpoint ctr1; applymodel(p.V * p.intester, ctr1); + println(hlog, "intester = ", p.intester); ld sdet = 0; if(1) { dynamicval g(geometry, gEuclid); for(int i=0; i(tp % fts_row, tp / fts_row); + auto zero = p.tinf->tvertices[0]; + ld sca = FLOORTEXTURESIZE*1./fts_int; + for(auto& d: tdata) + for(int c: {0, 1}) + d[c] = ((d[c] - zero[c])*sca + xy[c] + .5) * fts_int / fts; + } + + for(auto& d: tdata) ad.second.push_back(d); + } EX void render() { + for(auto& p: ptds) { + auto p2 = dynamic_cast(&*p); + if(p2) + prepare(*p2); + } + + int tps = 0; + for(auto& p: texture_position) p.second = tps++; + int gps = 0; + for(auto& p: gradient_position) p.second = gps++; + + fts_int = floor_texture_square_size * FLOORTEXTURESIZE + 4; + fts = 64; + + while(fts < gps || (fts-gps)/fts_int * fts/fts_int < tps) + fts *= 2; + + fts_row = (fts-gps)/fts_int; + for(auto& p: ptds) { auto p2 = dynamic_cast(&*p); if(p2) @@ -439,13 +483,54 @@ EX always_false in; dynamicval v3(noshadow, true); filename = fname; + ptds.clear(); + what(); + f.f = fopen(fname.c_str(), "wt"); println(f, "#VRML V2.0 utf8"); println(f, "WorldInfo { title \"3D model exported from HyperRogue\" info [ \"3D models exported from HyperRogue are public domain\" ] }"); - ptds.clear(); - what(); + for(auto& p: all_data) { + const string& app = p.first; + auto& data = p.second.first; + auto& tdata = p.second.second; + + println(f, "Shape {"); + println(f, " appearance Appearance {"); + println(f, app); + println(f, " }"); + // println(f, "# V = ", p.V); + println(f, " geometry IndexedFaceSet {"); + println(f, " coord Coordinate {"); + + println(f, " point ["); + for(auto& d: data) println(f, " ", coord(d, 3), ","); + println(f, " ]"); + println(f, " }"); + + if(!tdata.empty()) { + println(f, " texCoord TextureCoordinate {"); + println(f, " point ["); + + for(auto& d: tdata) + println(f, " ", coord(glhr::gltopoint(d), 2), ","); + println(f, " ]"); + println(f, " }"); + } + + println(f, " coordIndex ["); + for(int i=0; i dy(shot::shoty, rug::texturesize); shot::postprocess(filename + "-rug.png", s, s); } + + if(isize(texture_position) || isize(gradient_position)) { + SDL_Surface *s = shot::empty_surface(fts, fts, false); + for(auto& p: gradient_position) { + int x = fts - p.second - 1; + for(int y=0; y> 8; + part(qpixel(s, x, y), 3) = 0xFF; + } + } + + SDL_Surface *floor = floor_textures->render(); + for(auto& p: texture_position) { + int nx = p.second % fts_row; + int ny = p.second / fts_row; + color_t col = p.first.first; + int xs = p.first.second[0] * FLOORTEXTURESIZE - fts_int/2; + int ys = p.first.second[1] * FLOORTEXTURESIZE - fts_int/2; + for(int y=0; y