glviewvol

annotate src/rend_fast.cc @ 7:71b479ffb9f7

curve manipulation works
author John Tsiombikas <nuclear@member.fsf.org>
date Tue, 30 Dec 2014 17:28:38 +0200
parents f22be47a3572
children fb6d93471352
rev   line source
nuclear@4 1 #include <stdio.h>
nuclear@0 2 #include "opengl.h"
nuclear@0 3 #include "rend_fast.h"
nuclear@4 4 #include "sdr.h"
nuclear@4 5
nuclear@4 6 #define XFER_MAP_SZ 1024
nuclear@4 7
nuclear@4 8 static unsigned int sdr;
nuclear@4 9 static bool have_tex_float;
nuclear@0 10
nuclear@0 11 RendererFast::RendererFast()
nuclear@0 12 {
nuclear@4 13 vol_tex = xfer_tex = 0;
nuclear@4 14 vol_tex_valid = xfer_tex_valid = false;
nuclear@0 15 }
nuclear@0 16
nuclear@0 17 bool RendererFast::init()
nuclear@0 18 {
nuclear@4 19 if(!sdr) {
nuclear@4 20 if(!(sdr = create_program_load("sdr/fast.v.glsl", "sdr/fast.p.glsl"))) {
nuclear@4 21 return false;
nuclear@4 22 }
nuclear@4 23 have_tex_float = GLEW_ARB_texture_float;
nuclear@4 24 }
nuclear@4 25
nuclear@0 26 glGenTextures(1, &vol_tex);
nuclear@0 27 glBindTexture(GL_TEXTURE_3D, vol_tex);
nuclear@0 28 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
nuclear@0 29 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
nuclear@0 30
nuclear@4 31 glGenTextures(1, &xfer_tex);
nuclear@4 32 glBindTexture(GL_TEXTURE_1D, xfer_tex);
nuclear@4 33 glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
nuclear@4 34 glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
nuclear@6 35 glTexImage1D(GL_TEXTURE_1D, 0, have_tex_float ? GL_RGBA16F : GL_RGBA, XFER_MAP_SZ, 0, GL_RGB, GL_FLOAT, 0);
nuclear@4 36
nuclear@0 37 return true;
nuclear@0 38 }
nuclear@0 39
nuclear@0 40 void RendererFast::destroy()
nuclear@0 41 {
nuclear@0 42 glDeleteTextures(1, &vol_tex);
nuclear@4 43 glDeleteTextures(1, &xfer_tex);
nuclear@4 44 }
nuclear@4 45
nuclear@4 46 void RendererFast::set_volume(Volume *vol)
nuclear@4 47 {
nuclear@4 48 vol_tex_valid = false;
nuclear@4 49 Renderer::set_volume(vol);
nuclear@4 50 }
nuclear@4 51
nuclear@0 52 void RendererFast::update(unsigned int msec)
nuclear@0 53 {
nuclear@0 54 if(!vol) return;
nuclear@0 55
nuclear@0 56 // make sure the 3D volume texture is up to date
nuclear@0 57 if(!vol_tex_valid) {
nuclear@0 58 int xsz, ysz, zsz;
nuclear@0 59
nuclear@0 60 if((xsz = vol->num_samples(0)) > 0) {
nuclear@0 61 ysz = vol->num_samples(1);
nuclear@0 62 zsz = vol->num_samples(2);
nuclear@0 63 } else {
nuclear@0 64 xsz = ysz = zsz = 256;
nuclear@0 65 }
nuclear@0 66
nuclear@4 67 printf("updating 3D texture data (%dx%dx%d) ... ", xsz, ysz, zsz);
nuclear@4 68 fflush(stdout);
nuclear@4 69
nuclear@0 70 int int_fmt = GLEW_ARB_texture_float ? GL_RGBA16F_ARB : GL_RGBA;
nuclear@0 71
nuclear@0 72 glBindTexture(GL_TEXTURE_3D, vol_tex);
nuclear@0 73 glTexImage3D(GL_TEXTURE_3D, 0, int_fmt, xsz, ysz, zsz, 0, GL_RGBA, GL_FLOAT, 0);
nuclear@0 74
nuclear@0 75 float *slice = new float[xsz * ysz * 4];
nuclear@0 76
nuclear@0 77 for(int i=0; i<zsz; i++) {
nuclear@4 78 float z = (float)i;
nuclear@0 79 float *pptr = slice;
nuclear@0 80
nuclear@0 81 for(int j=0; j<ysz; j++) {
nuclear@4 82 float y = (float)j;
nuclear@0 83 for(int k=0; k<xsz; k++) {
nuclear@4 84 float x = (float)k;
nuclear@0 85
nuclear@0 86 // value in alpha channel
nuclear@0 87 pptr[3] = vol->valuef(x, y, z);
nuclear@0 88 // normal in rgb
nuclear@0 89 vol->normalf(pptr, x, y, z);
nuclear@0 90 // shift normal to the [0,1] range in case we don't have tex_float
nuclear@0 91 pptr[0] = pptr[0] * 0.5 + 0.5;
nuclear@0 92 pptr[1] = pptr[1] * 0.5 + 0.5;
nuclear@0 93 pptr[2] = pptr[2] * 0.5 + 0.5;
nuclear@4 94
nuclear@4 95 pptr += 4;
nuclear@0 96 }
nuclear@0 97 }
nuclear@0 98
nuclear@0 99 glTexSubImage3D(GL_TEXTURE_3D, 0, 0, 0, i, xsz, ysz, 1, GL_RGBA, GL_FLOAT, slice);
nuclear@0 100 }
nuclear@0 101
nuclear@4 102 printf("done\n");
nuclear@4 103
nuclear@0 104 delete [] slice;
nuclear@0 105
nuclear@0 106 vol_tex_valid = true;
nuclear@0 107 }
nuclear@4 108
nuclear@6 109 if(1) {//if(!xfer_tex_valid) {
nuclear@6 110 float pixels[XFER_MAP_SZ * 4];
nuclear@4 111 float *pptr = pixels;
nuclear@4 112
nuclear@4 113 for(int i=0; i<XFER_MAP_SZ; i++) {
nuclear@4 114 float x = (float)i / (float)(XFER_MAP_SZ - 1);
nuclear@5 115
nuclear@6 116 if(xfer) {
nuclear@6 117 xfer->map(x, pptr);
nuclear@7 118 pptr[3] = std::max(pptr[0], std::max(pptr[1], pptr[2]));
nuclear@6 119 } else {
nuclear@6 120 pptr[0] = pptr[1] = pptr[2] = pptr[3] = x;
nuclear@6 121 }
nuclear@6 122 pptr += 4;
nuclear@4 123 }
nuclear@4 124
nuclear@4 125 glBindTexture(GL_TEXTURE_1D, xfer_tex);
nuclear@6 126 glTexSubImage1D(GL_TEXTURE_1D, 0, 0, XFER_MAP_SZ, GL_RGBA, GL_FLOAT, pixels);
nuclear@4 127
nuclear@4 128 xfer_tex_valid = true;
nuclear@4 129 }
nuclear@0 130 }
nuclear@0 131
nuclear@0 132 void RendererFast::render() const
nuclear@0 133 {
nuclear@0 134 if(!vol) return;
nuclear@0 135
nuclear@0 136 glClear(GL_COLOR_BUFFER_BIT);
nuclear@0 137
nuclear@0 138 glMatrixMode(GL_PROJECTION);
nuclear@0 139 glPushMatrix();
nuclear@0 140 glLoadIdentity();
nuclear@0 141
nuclear@0 142 glMatrixMode(GL_MODELVIEW);
nuclear@0 143 glPushMatrix();
nuclear@0 144 glLoadIdentity();
nuclear@0 145
nuclear@4 146 glUseProgram(sdr);
nuclear@4 147
nuclear@4 148 glActiveTexture(GL_TEXTURE0);
nuclear@0 149 glBindTexture(GL_TEXTURE_3D, vol_tex);
nuclear@4 150 glActiveTexture(GL_TEXTURE1);
nuclear@4 151 glBindTexture(GL_TEXTURE_1D, xfer_tex);
nuclear@4 152
nuclear@4 153 set_uniform_int(sdr, "vol_tex", 0);
nuclear@4 154 set_uniform_int(sdr, "xfer_tex", 1);
nuclear@4 155
nuclear@0 156 glBegin(GL_QUADS);
nuclear@4 157 glTexCoord3f(0, 0, 0.5); glVertex2f(-1, -1);
nuclear@4 158 glTexCoord3f(1, 0, 0.5); glVertex2f(1, -1);
nuclear@4 159 glTexCoord3f(1, 1, 0.5); glVertex2f(1, 1);
nuclear@4 160 glTexCoord3f(0, 1, 0.5); glVertex2f(-1, 1);
nuclear@0 161 glEnd();
nuclear@0 162
nuclear@4 163 glUseProgram(0);
nuclear@4 164
nuclear@0 165 glMatrixMode(GL_PROJECTION);
nuclear@0 166 glPopMatrix();
nuclear@0 167 glMatrixMode(GL_MODELVIEW);
nuclear@0 168 glPopMatrix();
nuclear@0 169 }