nuclear@1: #include nuclear@0: #include "level.h" nuclear@0: #include "logger.h" nuclear@1: #include "texman.h" nuclear@1: #include "sdrman.h" nuclear@0: nuclear@0: static void gen_mesh(Mesh *mesh); nuclear@0: nuclear@1: static ShaderProg *level_sdr; nuclear@1: nuclear@0: Level::Level() nuclear@0: { nuclear@1: dlimit_near = 0; nuclear@1: dlimit_far = 25; nuclear@1: nuclear@1: fly_speed = 3.0; nuclear@0: nuclear@0: gen_mesh(&tile_mesh); nuclear@0: nuclear@0: tile_obj = new Object; nuclear@0: tile_obj->set_mesh(&tile_mesh); nuclear@1: tile_obj->material.tex[0] = texset.get("data/purple_grid.png"); nuclear@1: nuclear@1: level_sdr = get_sdrprog("sdr/default.v.glsl", "sdr/level.p.glsl"); nuclear@0: } nuclear@0: nuclear@0: Level::~Level() nuclear@0: { nuclear@0: delete tile_obj; nuclear@0: } nuclear@0: nuclear@0: void Level::set_draw_limits(float dnear, float dfar) nuclear@0: { nuclear@0: dlimit_near = dnear; nuclear@0: dlimit_far = dfar; nuclear@0: } nuclear@0: nuclear@1: void Level::draw(long msec) const nuclear@0: { nuclear@0: AABox bbox = tile_obj->get_aabbox(); nuclear@0: float zsize = bbox.max.z - bbox.min.z; nuclear@0: float zoffs = -zsize / 2.0; nuclear@0: nuclear@1: float tm = (float)msec / 1000.0; nuclear@1: nuclear@1: level_sdr->bind(); nuclear@1: nuclear@0: float z = dlimit_near; nuclear@0: while(z < dlimit_far) { nuclear@1: tile_obj->set_position(Vector3(0, 0, -(z - zoffs) + fmod(tm * fly_speed, zsize))); nuclear@1: nuclear@1: // draw mirrored nuclear@1: glFrontFace(GL_CW); nuclear@1: tile_obj->set_scaling(Vector3(-1, 1, 1)); nuclear@0: tile_obj->draw(); nuclear@1: glFrontFace(GL_CCW); nuclear@1: tile_obj->set_scaling(Vector3(1, 1, 1)); nuclear@1: tile_obj->draw(); nuclear@1: nuclear@0: z += zsize; nuclear@0: } nuclear@0: } nuclear@0: nuclear@1: #define DEPTH 2.0 nuclear@1: #define POSTZ (0.8 * DEPTH) nuclear@1: nuclear@0: static void gen_mesh(Mesh *mesh) nuclear@0: { nuclear@1: // vertical side nuclear@0: mesh->normal(1, 0, 0); nuclear@1: mesh->texcoord(0, 0); mesh->vertex(-2, 0, DEPTH); nuclear@1: mesh->texcoord(3, 0); mesh->vertex(-2, 0, -DEPTH); nuclear@1: mesh->texcoord(3, 2); mesh->vertex(-2, 1, -DEPTH); nuclear@1: mesh->texcoord(0, 2); mesh->vertex(-2, 1, DEPTH); nuclear@0: nuclear@1: // left diagonal nuclear@0: Vector3 dnorm = Vector3(0.5, 1, 0).normalized(); nuclear@0: mesh->normal(dnorm.x, dnorm.y, dnorm.z); nuclear@1: mesh->texcoord(0, 0); mesh->vertex(-1, -0.5, DEPTH); nuclear@1: mesh->texcoord(3, 0); mesh->vertex(-1, -0.5, -DEPTH); nuclear@1: mesh->texcoord(3, 2); mesh->vertex(-2, 0, -DEPTH); nuclear@1: mesh->texcoord(0, 2); mesh->vertex(-2, 0, DEPTH); nuclear@1: nuclear@1: // vertical post front nuclear@1: mesh->normal(0, 0, 1); nuclear@1: mesh->texcoord(0, 0); mesh->vertex(-2, -0.5, -POSTZ); nuclear@1: mesh->texcoord(1, 0); mesh->vertex(-1.7, -0.5, -POSTZ); nuclear@1: mesh->texcoord(1, 3); mesh->vertex(-1.7, 1, -POSTZ); nuclear@1: mesh->texcoord(0, 3); mesh->vertex(-2, 1, -POSTZ); nuclear@1: nuclear@1: // vertical post side nuclear@1: mesh->normal(1, 0, 0); nuclear@1: mesh->texcoord(0, 0); mesh->vertex(-1.7, -0.5, -POSTZ); nuclear@1: mesh->texcoord(1, 0); mesh->vertex(-1.7, -0.5, -DEPTH); nuclear@1: mesh->texcoord(1, 3); mesh->vertex(-1.7, 1, -DEPTH); nuclear@1: mesh->texcoord(0, 3); mesh->vertex(-1.7, 1, -POSTZ); nuclear@1: nuclear@1: // vertical post top nuclear@1: mesh->normal(0, 1, 0); nuclear@1: mesh->texcoord(0, 0); mesh->vertex(-2, 1, -POSTZ); nuclear@1: mesh->texcoord(1, 0); mesh->vertex(-1.7, 1, -POSTZ); nuclear@1: mesh->texcoord(1, 1); mesh->vertex(-1.7, 1, -DEPTH); nuclear@1: mesh->texcoord(0, 1); mesh->vertex(-2, 1, -DEPTH); nuclear@0: nuclear@0: /* floor */ nuclear@0: mesh->normal(0, 1, 0); nuclear@1: mesh->texcoord(0, 0); mesh->vertex(-1, -0.5, DEPTH); nuclear@1: mesh->texcoord(1, 0); mesh->vertex(0, -0.5, DEPTH); nuclear@1: mesh->texcoord(1, 3); mesh->vertex(0, -0.5, -DEPTH); nuclear@1: mesh->texcoord(0, 3); mesh->vertex(-1, -0.5, -DEPTH); nuclear@0: nuclear@0: // quad face index buffer nuclear@0: int nverts = mesh->get_attrib_count(MESH_ATTR_VERTEX); nuclear@0: for(int i=0; iface(i, i + 1, i + 2); nuclear@0: mesh->face(i, i + 2, i + 3); nuclear@0: } nuclear@0: nuclear@0: info_log("generated level trough mesh: %d polygons\n", mesh->get_poly_count()); nuclear@0: }