nuclear@1: #include "opengl.h" nuclear@1: #include "renderer.h" nuclear@3: #include "sdr.h" nuclear@1: nuclear@1: Renderer::Renderer() nuclear@1: { nuclear@4: blobtex = 0; nuclear@1: leveltex = 0; nuclear@1: sdrprog = 0; nuclear@3: nuclear@3: level = 0; nuclear@3: nuclear@3: fov = M_PI / 4.0; nuclear@3: aspect = 1.0; nuclear@1: } nuclear@1: nuclear@1: Renderer::~Renderer() nuclear@1: { nuclear@1: shutdown(); nuclear@1: } nuclear@1: nuclear@3: bool Renderer::init(Level *level) nuclear@1: { nuclear@3: if(!(sdrprog = create_program_load("sdr/bloboray.v.glsl", "sdr/bloboray.p.glsl"))) { nuclear@1: return false; nuclear@3: } nuclear@3: nuclear@3: Volume *vol = level->terrain; nuclear@1: nuclear@1: leveltex = new Texture3D; nuclear@3: leveltex->create(vol->get_size(0), vol->get_size(1), vol->get_size(2)); nuclear@3: nuclear@4: blobtex = new Texture1D; nuclear@5: blobtex->set_pixel_format(GL_RGBA16F); // floating point textures nuclear@4: blobtex->create(level->blobs.size()); nuclear@4: blobtex->set_filtering(GL_NEAREST); nuclear@4: nuclear@3: this->level = level; nuclear@1: nuclear@1: return true; nuclear@1: } nuclear@1: nuclear@1: void Renderer::shutdown() nuclear@1: { nuclear@1: delete leveltex; nuclear@3: if(sdrprog) { nuclear@3: free_program(sdrprog); nuclear@3: } nuclear@3: } nuclear@3: nuclear@3: void Renderer::set_fov(float fov) nuclear@3: { nuclear@3: this->fov = fov; nuclear@3: } nuclear@3: nuclear@3: void Renderer::set_aspect(float aspect) nuclear@3: { nuclear@3: this->aspect = aspect; nuclear@1: } nuclear@1: nuclear@1: static void draw_cube(const Vector3 &pos, float sz); nuclear@1: nuclear@5: void Renderer::prepare() nuclear@5: { nuclear@5: leveltex->update((float*)level->terrain->get_data_ptr()); nuclear@5: update_blobtex(); nuclear@5: } nuclear@5: nuclear@3: void Renderer::render() const nuclear@1: { nuclear@4: bind_texture(leveltex, 0); nuclear@4: bind_texture(blobtex, 1); nuclear@4: nuclear@4: set_uniform_float3(sdrprog, "worldsize", level->world_size.x, level->world_size.y, nuclear@4: level->world_size.z); nuclear@3: set_uniform_float3(sdrprog, "volsize", level->terrain->get_size(0), nuclear@3: level->terrain->get_size(1), level->terrain->get_size(2)); nuclear@3: set_uniform_float4(sdrprog, "camprop", fov, aspect, 0, 0); nuclear@4: nuclear@5: set_uniform_int(sdrprog, "num_blobs", (int)level->blobs.size()); nuclear@5: nuclear@4: set_uniform_int(sdrprog, "voltex", 0); nuclear@4: set_uniform_int(sdrprog, "blobtex", 1); nuclear@3: bind_program(sdrprog); nuclear@3: nuclear@3: glBegin(GL_QUADS); nuclear@3: glTexCoord2f(0, 0); nuclear@3: glVertex2f(-1, -1); nuclear@3: glTexCoord2f(1, 0); nuclear@3: glVertex2f(1, -1); nuclear@3: glTexCoord2f(1, 1); nuclear@3: glVertex2f(1, 1); nuclear@3: glTexCoord2f(0, 1); nuclear@3: glVertex2f(-1, 1); nuclear@3: glEnd(); nuclear@3: nuclear@3: bind_program(0); nuclear@4: bind_texture(0, 1); nuclear@4: bind_texture(0, 0); nuclear@3: nuclear@3: /*glEnable(GL_COLOR_MATERIAL); nuclear@1: glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE); nuclear@1: nuclear@1: glBegin(GL_QUADS); nuclear@1: for(int i=0; iget_size(0); i++) { nuclear@1: for(int j=0; jget_size(1); j++) { nuclear@1: for(int k=0; kget_size(2) - 1; k++) { nuclear@1: Vector4 vox = vol->get_voxel(i, j, k); nuclear@1: Vector4 next = vol->get_voxel(i, j, k + 1); nuclear@1: nuclear@1: if(vox.w > 0.1 && next.w < 0.1) { nuclear@1: glColor3f(vox.x, vox.y, vox.z); nuclear@1: nuclear@1: float x = ((float)i - vol->get_size(0) / 2) * 0.1; nuclear@1: float z = ((float)j - vol->get_size(1) / 2) * 0.1; nuclear@1: float y = ((float)k - vol->get_size(2) / 2) * 0.1; nuclear@1: draw_cube(Vector3(x, y, z), 0.1); nuclear@1: } nuclear@1: } nuclear@1: } nuclear@1: } nuclear@1: glEnd(); nuclear@1: nuclear@1: glDisable(GL_COLOR_MATERIAL); nuclear@3: */ nuclear@1: } nuclear@1: nuclear@1: nuclear@1: static void draw_cube(const Vector3 &pos, float sz) nuclear@1: { nuclear@1: sz /= 2.0; nuclear@1: nuclear@1: glNormal3f(0, 0, 1); nuclear@1: glVertex3f(pos.x - sz, pos.y - sz, pos.z + sz); nuclear@1: glVertex3f(pos.x + sz, pos.y - sz, pos.z + sz); nuclear@1: glVertex3f(pos.x + sz, pos.y + sz, pos.z + sz); nuclear@1: glVertex3f(pos.x - sz, pos.y + sz, pos.z + sz); nuclear@1: nuclear@1: glNormal3f(1, 0, 0); nuclear@1: glVertex3f(pos.x + sz, pos.y - sz, pos.z + sz); nuclear@1: glVertex3f(pos.x + sz, pos.y - sz, pos.z - sz); nuclear@1: glVertex3f(pos.x + sz, pos.y + sz, pos.z - sz); nuclear@1: glVertex3f(pos.x + sz, pos.y + sz, pos.z + sz); nuclear@1: nuclear@1: glNormal3f(0, 0, -1); nuclear@1: glVertex3f(pos.x + sz, pos.y - sz, pos.z - sz); nuclear@1: glVertex3f(pos.x - sz, pos.y - sz, pos.z - sz); nuclear@1: glVertex3f(pos.x - sz, pos.y + sz, pos.z - sz); nuclear@1: glVertex3f(pos.x + sz, pos.y + sz, pos.z - sz); nuclear@1: nuclear@1: glNormal3f(-1, 0, 0); nuclear@1: glVertex3f(pos.x - sz, pos.y - sz, pos.z - sz); nuclear@1: glVertex3f(pos.x - sz, pos.y - sz, pos.z + sz); nuclear@1: glVertex3f(pos.x - sz, pos.y + sz, pos.z + sz); nuclear@1: glVertex3f(pos.x - sz, pos.y + sz, pos.z - sz); nuclear@1: nuclear@1: glNormal3f(0, 1, 0); nuclear@1: glVertex3f(pos.x - sz, pos.y + sz, pos.z + sz); nuclear@1: glVertex3f(pos.x + sz, pos.y + sz, pos.z + sz); nuclear@1: glVertex3f(pos.x + sz, pos.y + sz, pos.z - sz); nuclear@1: glVertex3f(pos.x - sz, pos.y + sz, pos.z - sz); nuclear@1: nuclear@1: glNormal3f(0, -1, 0); nuclear@1: glVertex3f(pos.x - sz, pos.y - sz, pos.z - sz); nuclear@1: glVertex3f(pos.x + sz, pos.y - sz, pos.z - sz); nuclear@1: glVertex3f(pos.x + sz, pos.y - sz, pos.z + sz); nuclear@1: glVertex3f(pos.x - sz, pos.y - sz, pos.z + sz); nuclear@1: nuclear@1: } nuclear@4: nuclear@4: void Renderer::update_blobtex() nuclear@4: { nuclear@4: int nblobs = (int)level->blobs.size(); nuclear@4: nuclear@4: float *data = (float*)alloca(nblobs * 4 * sizeof *data); nuclear@4: float *dptr = data; nuclear@4: nuclear@4: for(int i=0; iblobs[i].pos.x; nuclear@4: *dptr++ = level->blobs[i].pos.y; nuclear@4: *dptr++ = level->blobs[i].pos.z; nuclear@4: *dptr++ = 1.0; nuclear@4: } nuclear@4: nuclear@4: blobtex->update(data); nuclear@4: }