qvolray

annotate src/demo.cc @ 37:450d4c50470f

- 16bit floating point textures halve gpu texture memory usage - slower transfer function change
author John Tsiombikas <nuclear@member.fsf.org>
date Wed, 01 Jan 2014 00:23:57 +0200
parents c27ce79632db
children
rev   line source
nuclear@36 1 #include <random>
nuclear@36 2 #include <functional>
nuclear@36 3 #include <QTimer>
nuclear@24 4 #include <assert.h>
nuclear@18 5 #include <GL/glew.h>
nuclear@18 6 #include "demo.h"
nuclear@18 7 #include "sdr.h"
nuclear@18 8 #include "volray.h"
nuclear@36 9 #include "ui.h"
nuclear@18 10
nuclear@36 11 #define SZ 128
nuclear@36 12 #define TIMER_INTERVAL 33
nuclear@18 13
nuclear@18 14
nuclear@36 15 Demo::Demo()
nuclear@36 16 {
nuclear@36 17 vol = 0;
nuclear@36 18 sdr_mballs = 0;
nuclear@36 19 fbo = 0;
nuclear@36 20 timer = 0;
nuclear@36 21 balls = 0;
nuclear@36 22 tmsec = 0;
nuclear@36 23 }
nuclear@36 24
nuclear@36 25 Demo::~Demo()
nuclear@36 26 {
nuclear@36 27 glDeleteFramebuffersEXT(1, &fbo);
nuclear@36 28 free_program(sdr_mballs);
nuclear@36 29 delete vol;
nuclear@36 30 delete timer;
nuclear@36 31
nuclear@36 32 delete [] balls;
nuclear@36 33 }
nuclear@36 34
nuclear@36 35 void Demo::timer_func()
nuclear@36 36 {
nuclear@36 37 float tsec = tmsec / 1000.0;
nuclear@36 38 const float speed = 1.0;
nuclear@36 39
nuclear@36 40 for(int i=0; i<num_balls; i++) {
nuclear@36 41 float t = tsec * speed;
nuclear@36 42 int idx = (int)t % MB_PATH_SZ;
nuclear@36 43 t -= floor(t);
nuclear@36 44
nuclear@36 45 Vector3 a = balls[i].path[idx];
nuclear@36 46 Vector3 b = balls[i].path[(idx + 1) % MB_PATH_SZ];
nuclear@36 47 balls[i].pos = lerp(a, b, t);
nuclear@36 48
nuclear@36 49 char name[32];
nuclear@36 50
nuclear@36 51 sprintf(name, "pos[%d]", i);
nuclear@36 52 set_uniform_float3(sdr_mballs, name, balls[i].pos.x, balls[i].pos.y, balls[i].pos.z);
nuclear@36 53
nuclear@36 54 sprintf(name, "energy[%d]", i);
nuclear@36 55 set_uniform_float(sdr_mballs, name, balls[i].energy);
nuclear@36 56 }
nuclear@36 57
nuclear@36 58 post_redisplay();
nuclear@36 59
nuclear@36 60 tmsec += TIMER_INTERVAL;
nuclear@36 61 }
nuclear@36 62
nuclear@36 63 bool Demo::init()
nuclear@18 64 {
nuclear@18 65 if(!(sdr_mballs = create_program_load("sdr/demo.v.glsl", "sdr/demo.p.glsl"))) {
nuclear@18 66 return false;
nuclear@18 67 }
nuclear@18 68
nuclear@18 69 vol = new Volume;
nuclear@18 70 vol->create(SZ, SZ, SZ);
nuclear@18 71 volray_setvolume(vol);
nuclear@18 72
nuclear@24 73 assert(glGenFramebuffersEXT);
nuclear@24 74 assert(glBindFramebufferEXT);
nuclear@24 75 assert(glFramebufferTexture3DEXT);
nuclear@24 76 assert(glCheckFramebufferStatusEXT);
nuclear@24 77
nuclear@24 78 glGenFramebuffersEXT(1, &fbo);
nuclear@24 79 glBindFramebufferEXT(GL_FRAMEBUFFER, fbo);
nuclear@24 80 glFramebufferTexture3DEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_3D,
nuclear@18 81 vol->get_texture(), 0, 0);
nuclear@18 82
nuclear@24 83 unsigned int stat = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER);
nuclear@18 84 if(stat != GL_FRAMEBUFFER_COMPLETE) {
nuclear@18 85 printf("incomplete framebuffer: %u\n", stat);
nuclear@18 86 delete vol;
nuclear@18 87 return false;
nuclear@18 88 }
nuclear@24 89 glBindFramebufferEXT(GL_FRAMEBUFFER, 0);
nuclear@18 90
nuclear@36 91 // initialize metaballs
nuclear@36 92 auto rnd_energy = std::bind(std::uniform_real_distribution<float>(0.7, 1.6), std::mt19937());
nuclear@36 93 auto rnd_path = std::bind(std::uniform_real_distribution<float>(-0.5, 0.5), std::mt19937());
nuclear@36 94
nuclear@36 95 num_balls = 4;
nuclear@36 96 balls = new MetaBall[4];
nuclear@36 97
nuclear@36 98 for(int i=0; i<4; i++) {
nuclear@36 99 balls[i].energy = rnd_energy();
nuclear@36 100
nuclear@36 101 for(int j=0; j<MB_PATH_SZ; j++) {
nuclear@36 102 balls[i].path[j].x = rnd_path();
nuclear@36 103 balls[i].path[j].y = rnd_path();
nuclear@36 104 balls[i].path[j].z = rnd_path();
nuclear@36 105 }
nuclear@36 106 }
nuclear@36 107
nuclear@36 108 // update timer
nuclear@36 109 timer = new QTimer(this);
nuclear@36 110 timer->setSingleShot(false);
nuclear@36 111 connect(timer, SIGNAL(timeout()), this, SLOT(timer_func()));
nuclear@36 112 timer->start(TIMER_INTERVAL);
nuclear@36 113
nuclear@18 114 return true;
nuclear@18 115 }
nuclear@18 116
nuclear@36 117 void Demo::draw() const
nuclear@18 118 {
nuclear@18 119 if(volray_getvolume() != vol) {
nuclear@36 120 if(timer->isActive()) {
nuclear@36 121 timer->stop();
nuclear@36 122 }
nuclear@18 123 return;
nuclear@36 124 } else {
nuclear@36 125 if(!timer->isActive()) {
nuclear@36 126 timer->start(TIMER_INTERVAL);
nuclear@36 127 }
nuclear@18 128 }
nuclear@18 129
nuclear@21 130 glPushAttrib(GL_VIEWPORT_BIT);
nuclear@21 131 glViewport(0, 0, SZ, SZ);
nuclear@21 132
nuclear@24 133 glBindFramebufferEXT(GL_FRAMEBUFFER, fbo);
nuclear@18 134 bind_program(sdr_mballs);
nuclear@18 135
nuclear@18 136 for(int i=0; i<SZ; i++) {
nuclear@24 137 glFramebufferTexture3DEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_3D,
nuclear@18 138 vol->get_texture(), 0, i);
nuclear@18 139
nuclear@21 140 float z = (float)i / (float)SZ;
nuclear@21 141
nuclear@18 142 glBegin(GL_QUADS);
nuclear@21 143 glTexCoord3f(0, 0, z);
nuclear@18 144 glVertex2f(-1, -1);
nuclear@21 145 glTexCoord3f(1, 0, z);
nuclear@18 146 glVertex2f(1, -1);
nuclear@21 147 glTexCoord3f(1, 1, z);
nuclear@18 148 glVertex2f(1, 1);
nuclear@21 149 glTexCoord3f(0, 1, z);
nuclear@18 150 glVertex2f(-1, 1);
nuclear@18 151 glEnd();
nuclear@18 152 }
nuclear@18 153
nuclear@18 154 bind_program(0);
nuclear@24 155 glBindFramebufferEXT(GL_FRAMEBUFFER, 0);
nuclear@21 156
nuclear@21 157 glPopAttrib();
nuclear@18 158 }