nuclear@4: #include nuclear@0: #include "opengl.h" nuclear@0: #include "rend_fast.h" nuclear@4: #include "sdr.h" nuclear@4: nuclear@4: #define XFER_MAP_SZ 1024 nuclear@4: nuclear@4: static unsigned int sdr; nuclear@4: static bool have_tex_float; nuclear@0: nuclear@0: RendererFast::RendererFast() nuclear@0: { nuclear@4: vol_tex = xfer_tex = 0; nuclear@4: vol_tex_valid = xfer_tex_valid = false; nuclear@0: } nuclear@0: nuclear@0: bool RendererFast::init() nuclear@0: { nuclear@4: if(!sdr) { nuclear@4: if(!(sdr = create_program_load("sdr/fast.v.glsl", "sdr/fast.p.glsl"))) { nuclear@4: return false; nuclear@4: } nuclear@4: have_tex_float = GLEW_ARB_texture_float; nuclear@4: } nuclear@4: nuclear@0: glGenTextures(1, &vol_tex); nuclear@0: glBindTexture(GL_TEXTURE_3D, vol_tex); nuclear@0: glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); nuclear@0: glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); nuclear@0: nuclear@4: glGenTextures(1, &xfer_tex); nuclear@4: glBindTexture(GL_TEXTURE_1D, xfer_tex); nuclear@4: glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); nuclear@4: glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); nuclear@6: glTexImage1D(GL_TEXTURE_1D, 0, have_tex_float ? GL_RGBA16F : GL_RGBA, XFER_MAP_SZ, 0, GL_RGB, GL_FLOAT, 0); nuclear@4: nuclear@0: return true; nuclear@0: } nuclear@0: nuclear@0: void RendererFast::destroy() nuclear@0: { nuclear@0: glDeleteTextures(1, &vol_tex); nuclear@4: glDeleteTextures(1, &xfer_tex); nuclear@4: } nuclear@4: nuclear@4: void RendererFast::set_volume(Volume *vol) nuclear@4: { nuclear@4: vol_tex_valid = false; nuclear@4: Renderer::set_volume(vol); nuclear@4: } nuclear@4: nuclear@0: void RendererFast::update(unsigned int msec) nuclear@0: { nuclear@0: if(!vol) return; nuclear@0: nuclear@0: // make sure the 3D volume texture is up to date nuclear@0: if(!vol_tex_valid) { nuclear@0: int xsz, ysz, zsz; nuclear@0: nuclear@0: if((xsz = vol->num_samples(0)) > 0) { nuclear@0: ysz = vol->num_samples(1); nuclear@0: zsz = vol->num_samples(2); nuclear@0: } else { nuclear@0: xsz = ysz = zsz = 256; nuclear@0: } nuclear@0: nuclear@4: printf("updating 3D texture data (%dx%dx%d) ... ", xsz, ysz, zsz); nuclear@4: fflush(stdout); nuclear@4: nuclear@0: int int_fmt = GLEW_ARB_texture_float ? GL_RGBA16F_ARB : GL_RGBA; nuclear@0: nuclear@0: glBindTexture(GL_TEXTURE_3D, vol_tex); nuclear@0: glTexImage3D(GL_TEXTURE_3D, 0, int_fmt, xsz, ysz, zsz, 0, GL_RGBA, GL_FLOAT, 0); nuclear@0: nuclear@0: float *slice = new float[xsz * ysz * 4]; nuclear@0: nuclear@0: for(int i=0; ivaluef(x, y, z); nuclear@0: // normal in rgb nuclear@0: vol->normalf(pptr, x, y, z); nuclear@0: // shift normal to the [0,1] range in case we don't have tex_float nuclear@0: pptr[0] = pptr[0] * 0.5 + 0.5; nuclear@0: pptr[1] = pptr[1] * 0.5 + 0.5; nuclear@0: pptr[2] = pptr[2] * 0.5 + 0.5; nuclear@4: nuclear@4: pptr += 4; nuclear@0: } nuclear@0: } nuclear@0: nuclear@0: glTexSubImage3D(GL_TEXTURE_3D, 0, 0, 0, i, xsz, ysz, 1, GL_RGBA, GL_FLOAT, slice); nuclear@0: } nuclear@0: nuclear@4: printf("done\n"); nuclear@4: nuclear@0: delete [] slice; nuclear@0: nuclear@0: vol_tex_valid = true; nuclear@0: } nuclear@4: nuclear@6: if(1) {//if(!xfer_tex_valid) { nuclear@6: float pixels[XFER_MAP_SZ * 4]; nuclear@4: float *pptr = pixels; nuclear@4: nuclear@4: for(int i=0; imap(x, pptr); nuclear@7: pptr[3] = std::max(pptr[0], std::max(pptr[1], pptr[2])); nuclear@6: } else { nuclear@6: pptr[0] = pptr[1] = pptr[2] = pptr[3] = x; nuclear@6: } nuclear@6: pptr += 4; nuclear@4: } nuclear@4: nuclear@4: glBindTexture(GL_TEXTURE_1D, xfer_tex); nuclear@6: glTexSubImage1D(GL_TEXTURE_1D, 0, 0, XFER_MAP_SZ, GL_RGBA, GL_FLOAT, pixels); nuclear@4: nuclear@4: xfer_tex_valid = true; nuclear@4: } nuclear@0: } nuclear@0: nuclear@0: void RendererFast::render() const nuclear@0: { nuclear@0: if(!vol) return; nuclear@0: nuclear@0: glClear(GL_COLOR_BUFFER_BIT); nuclear@0: nuclear@0: glMatrixMode(GL_PROJECTION); nuclear@0: glPushMatrix(); nuclear@0: glLoadIdentity(); nuclear@0: nuclear@0: glMatrixMode(GL_MODELVIEW); nuclear@0: glPushMatrix(); nuclear@0: glLoadIdentity(); nuclear@0: nuclear@4: glUseProgram(sdr); nuclear@4: nuclear@4: glActiveTexture(GL_TEXTURE0); nuclear@0: glBindTexture(GL_TEXTURE_3D, vol_tex); nuclear@4: glActiveTexture(GL_TEXTURE1); nuclear@4: glBindTexture(GL_TEXTURE_1D, xfer_tex); nuclear@4: nuclear@4: set_uniform_int(sdr, "vol_tex", 0); nuclear@4: set_uniform_int(sdr, "xfer_tex", 1); nuclear@4: nuclear@0: glBegin(GL_QUADS); nuclear@4: glTexCoord3f(0, 0, 0.5); glVertex2f(-1, -1); nuclear@4: glTexCoord3f(1, 0, 0.5); glVertex2f(1, -1); nuclear@4: glTexCoord3f(1, 1, 0.5); glVertex2f(1, 1); nuclear@4: glTexCoord3f(0, 1, 0.5); glVertex2f(-1, 1); nuclear@0: glEnd(); nuclear@0: nuclear@4: glUseProgram(0); nuclear@4: nuclear@0: glMatrixMode(GL_PROJECTION); nuclear@0: glPopMatrix(); nuclear@0: glMatrixMode(GL_MODELVIEW); nuclear@0: glPopMatrix(); nuclear@0: }