[2798] | 1 | /* -*- mode: c++; c-basic-offset: 4; indent-tabs-mode: nil -*- */ |
---|
[3502] | 2 | /* |
---|
| 3 | * Copyright (C) 2004-2013 HUBzero Foundation, LLC |
---|
| 4 | * |
---|
| 5 | */ |
---|
[2818] | 6 | #include "nvconf.h" |
---|
| 7 | |
---|
[2964] | 8 | #include <math.h> |
---|
| 9 | |
---|
[1493] | 10 | #include <GL/glew.h> |
---|
| 11 | #include <GL/gl.h> |
---|
[1489] | 12 | |
---|
[3492] | 13 | #include <vrmath/Vector3f.h> |
---|
[3465] | 14 | #include <util/FilePath.h> |
---|
[2857] | 15 | #include <Image.h> |
---|
| 16 | #include <ImageLoaderFactory.h> |
---|
| 17 | #include <ImageLoader.h> |
---|
[2831] | 18 | |
---|
[2870] | 19 | #include "nanovis.h" |
---|
[2818] | 20 | #include "VelocityArrowsSlice.h" |
---|
[4889] | 21 | #include "Shader.h" |
---|
| 22 | #include "Camera.h" |
---|
[1489] | 23 | |
---|
[4889] | 24 | using namespace nv; |
---|
[3463] | 25 | using namespace nv::util; |
---|
[3492] | 26 | using namespace vrmath; |
---|
[3463] | 27 | |
---|
[2964] | 28 | static inline float deg2rad(float deg) |
---|
[1493] | 29 | { |
---|
[2964] | 30 | return ((deg * M_PI) / 180.); |
---|
| 31 | } |
---|
[2831] | 32 | |
---|
[2964] | 33 | static inline float rad2deg(float rad) |
---|
| 34 | { |
---|
| 35 | return ((rad * 180.) / M_PI); |
---|
| 36 | } |
---|
[1493] | 37 | |
---|
[2964] | 38 | VelocityArrowsSlice::VelocityArrowsSlice() : |
---|
| 39 | _vectorFieldGraphicsID(0), |
---|
| 40 | _vfXscale(0), |
---|
| 41 | _vfYscale(0), |
---|
| 42 | _vfZscale(0), |
---|
| 43 | _slicePos(0.5f), |
---|
| 44 | _axis(2), |
---|
| 45 | _fbo(0), |
---|
| 46 | _tex(0), |
---|
| 47 | _maxPointSize(1.0f), |
---|
| 48 | _renderTargetWidth(128), |
---|
| 49 | _renderTargetHeight(128), |
---|
| 50 | _velocities(NULL), |
---|
| 51 | _projectionVector(1, 1, 0), |
---|
| 52 | _tickCountForMinSizeAxis(10), |
---|
| 53 | _tickCountX(0), |
---|
| 54 | _tickCountY(0), |
---|
| 55 | _tickCountZ(0), |
---|
| 56 | _pointCount(0), |
---|
| 57 | _maxVelocityScale(1, 1, 1), |
---|
| 58 | _arrowColor(1, 1, 0), |
---|
| 59 | _enabled(false), |
---|
| 60 | _dirty(true), |
---|
| 61 | _vertexBufferGraphicsID(0), |
---|
| 62 | _arrowsTex(NULL), |
---|
| 63 | _renderMode(LINES) |
---|
| 64 | { |
---|
| 65 | axis(2); |
---|
[2831] | 66 | |
---|
[2964] | 67 | _queryVelocityFP.loadFragmentProgram("queryvelocity.cg", "main"); |
---|
[1493] | 68 | |
---|
[2964] | 69 | _particleShader.loadVertexProgram("velocityslicevp.cg", "vpmain"); |
---|
| 70 | _particleShader.loadFragmentProgram("velocityslicefp.cg", "fpmain"); |
---|
[1493] | 71 | |
---|
[2818] | 72 | createRenderTarget(); |
---|
[1493] | 73 | |
---|
[3463] | 74 | std::string path = FilePath::getInstance()->getPath("arrows.bmp"); |
---|
[2972] | 75 | if (!path.empty()) { |
---|
[2857] | 76 | ImageLoader *loader = ImageLoaderFactory::getInstance()->createLoader("bmp"); |
---|
| 77 | if (loader != NULL) { |
---|
[2972] | 78 | Image *image = loader->load(path.c_str(), Image::IMG_RGBA); |
---|
[2857] | 79 | if (image != NULL) { |
---|
| 80 | unsigned char *bytes = (unsigned char *)image->getImageBuffer(); |
---|
| 81 | if (bytes != NULL) { |
---|
| 82 | _arrowsTex = new Texture2D(image->getWidth(), image->getHeight(), |
---|
| 83 | GL_UNSIGNED_BYTE, GL_LINEAR, 4, NULL); |
---|
| 84 | _arrowsTex->setWrapS(GL_MIRRORED_REPEAT); |
---|
| 85 | _arrowsTex->setWrapT(GL_MIRRORED_REPEAT); |
---|
| 86 | _arrowsTex->initialize(image->getImageBuffer()); |
---|
| 87 | } |
---|
| 88 | delete image; |
---|
| 89 | } else { |
---|
[3452] | 90 | ERROR("Failed to load arrows image"); |
---|
[2857] | 91 | } |
---|
| 92 | delete loader; |
---|
| 93 | } else { |
---|
[3452] | 94 | ERROR("Couldn't find loader for arrows image"); |
---|
[2857] | 95 | } |
---|
| 96 | } else { |
---|
[3452] | 97 | ERROR("Couldn't find arrows image"); |
---|
[2857] | 98 | } |
---|
| 99 | |
---|
[2870] | 100 | GLfloat minMax[2]; |
---|
| 101 | glGetFloatv(GL_ALIASED_POINT_SIZE_RANGE, minMax); |
---|
[3452] | 102 | TRACE("Aliased point size range: %g %g", minMax[0], minMax[1]); |
---|
[2870] | 103 | _maxPointSize = minMax[1]; |
---|
| 104 | glGetFloatv(GL_SMOOTH_POINT_SIZE_RANGE, minMax); |
---|
[3452] | 105 | TRACE("Smooth point size range: %g %g", minMax[0], minMax[1]); |
---|
[2870] | 106 | _maxPointSize = minMax[1] > _maxPointSize ? minMax[1] : _maxPointSize; |
---|
[3452] | 107 | TRACE("Max point size: %g", _maxPointSize); |
---|
[2870] | 108 | |
---|
[3452] | 109 | TRACE("Leaving VelocityArrowsSlice constructor"); |
---|
[1493] | 110 | } |
---|
| 111 | |
---|
| 112 | VelocityArrowsSlice::~VelocityArrowsSlice() |
---|
| 113 | { |
---|
[2964] | 114 | if (_tex != 0) { |
---|
| 115 | glDeleteTextures(1, &_tex); |
---|
| 116 | } |
---|
| 117 | if (_fbo != 0) { |
---|
| 118 | glDeleteFramebuffersEXT(1, &_fbo); |
---|
| 119 | } |
---|
| 120 | if (_arrowsTex != NULL) { |
---|
| 121 | delete _arrowsTex; |
---|
| 122 | } |
---|
| 123 | if (_vertexBufferGraphicsID != 0) { |
---|
| 124 | glDeleteBuffers(1, &_vertexBufferGraphicsID); |
---|
| 125 | } |
---|
| 126 | if (_velocities != NULL) { |
---|
| 127 | delete [] _velocities; |
---|
| 128 | } |
---|
| 129 | } |
---|
[1486] | 130 | |
---|
[2964] | 131 | void VelocityArrowsSlice::createRenderTarget() |
---|
| 132 | { |
---|
| 133 | if (_velocities != NULL) { |
---|
| 134 | delete [] _velocities; |
---|
| 135 | } |
---|
[3492] | 136 | _velocities = new Vector3f[_renderTargetWidth * _renderTargetHeight]; |
---|
[2831] | 137 | |
---|
[2964] | 138 | if (_vertexBufferGraphicsID != 0) { |
---|
| 139 | glDeleteBuffers(1, &_vertexBufferGraphicsID); |
---|
| 140 | } |
---|
[1493] | 141 | |
---|
[2964] | 142 | glGenBuffers(1, &_vertexBufferGraphicsID); |
---|
| 143 | glBindBufferARB(GL_ARRAY_BUFFER_ARB, _vertexBufferGraphicsID); |
---|
| 144 | glBufferDataARB(GL_ARRAY_BUFFER_ARB, _renderTargetWidth * _renderTargetHeight * 3 * sizeof(float), |
---|
| 145 | 0, GL_DYNAMIC_DRAW_ARB); |
---|
| 146 | glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0); |
---|
[1493] | 147 | |
---|
[2964] | 148 | if (_tex != 0) { |
---|
| 149 | glDeleteTextures(1, &_tex); |
---|
| 150 | } |
---|
| 151 | if (_fbo != 0) { |
---|
| 152 | glDeleteFramebuffersEXT(1, &_fbo); |
---|
| 153 | } |
---|
| 154 | |
---|
[2818] | 155 | glGenFramebuffersEXT(1, &_fbo); |
---|
[1493] | 156 | glGenTextures(1, &_tex); |
---|
[2964] | 157 | int fboOrig; |
---|
| 158 | glGetIntegerv(GL_FRAMEBUFFER_BINDING_EXT, &fboOrig); |
---|
[1493] | 159 | glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, _fbo); |
---|
[2831] | 160 | |
---|
[2884] | 161 | glBindTexture(GL_TEXTURE_RECTANGLE_ARB, _tex); |
---|
| 162 | glTexParameterf(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, GL_NEAREST); |
---|
| 163 | glTexParameterf(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER, GL_NEAREST); |
---|
| 164 | glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); |
---|
| 165 | glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); |
---|
[1493] | 166 | |
---|
[2884] | 167 | glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA32F_ARB, |
---|
[2818] | 168 | _renderTargetWidth, _renderTargetHeight, 0, |
---|
| 169 | GL_RGBA, GL_FLOAT, NULL); |
---|
[2831] | 170 | |
---|
[2818] | 171 | glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, |
---|
[2884] | 172 | GL_TEXTURE_RECTANGLE_ARB, _tex, 0); |
---|
[1493] | 173 | |
---|
[2964] | 174 | glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fboOrig); |
---|
[1493] | 175 | } |
---|
| 176 | |
---|
| 177 | void VelocityArrowsSlice::axis(int axis) |
---|
| 178 | { |
---|
[2818] | 179 | _axis = axis; |
---|
| 180 | switch (_axis) { |
---|
| 181 | case 0: |
---|
| 182 | _projectionVector.x = 0; |
---|
| 183 | _projectionVector.y = 1; |
---|
| 184 | _projectionVector.z = 1; |
---|
| 185 | break; |
---|
| 186 | case 1 : |
---|
| 187 | _projectionVector.x = 1; |
---|
| 188 | _projectionVector.y = 0; |
---|
| 189 | _projectionVector.z = 1; |
---|
| 190 | break; |
---|
| 191 | case 2: |
---|
| 192 | _projectionVector.x = 1; |
---|
| 193 | _projectionVector.y = 1; |
---|
| 194 | _projectionVector.z = 0; |
---|
| 195 | break; |
---|
| 196 | } |
---|
[2964] | 197 | _dirty = true; |
---|
[1493] | 198 | } |
---|
| 199 | |
---|
| 200 | void VelocityArrowsSlice::queryVelocity() |
---|
| 201 | { |
---|
[2818] | 202 | if (!_enabled) return; |
---|
[1489] | 203 | |
---|
[2964] | 204 | glPushAttrib(GL_VIEWPORT_BIT | GL_ENABLE_BIT); |
---|
| 205 | int fboOrig; |
---|
| 206 | glGetIntegerv(GL_FRAMEBUFFER_BINDING_EXT, &fboOrig); |
---|
| 207 | |
---|
[2818] | 208 | glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, _fbo); |
---|
[2964] | 209 | |
---|
| 210 | _queryVelocityFP.bind(); |
---|
| 211 | _queryVelocityFP.setFPTextureParameter("vfield", _vectorFieldGraphicsID); |
---|
| 212 | |
---|
[2818] | 213 | glDisable(GL_DEPTH_TEST); |
---|
| 214 | glViewport(0, 0, _renderTargetWidth, _renderTargetHeight); |
---|
| 215 | glMatrixMode(GL_PROJECTION); |
---|
| 216 | glPushMatrix(); |
---|
| 217 | glLoadIdentity(); |
---|
| 218 | glOrtho(0, _renderTargetWidth, 0, _renderTargetHeight, -10.0f, 10.0f); |
---|
| 219 | glMatrixMode(GL_MODELVIEW); |
---|
| 220 | glPushMatrix(); |
---|
| 221 | glLoadIdentity(); |
---|
[1493] | 222 | |
---|
[2964] | 223 | glBegin(GL_QUADS); |
---|
| 224 | switch (_axis) { |
---|
| 225 | case 0: |
---|
| 226 | glTexCoord3f(_slicePos, 0, 0); glVertex2i(0, 0); |
---|
| 227 | glTexCoord3f(_slicePos, 1, 0); glVertex2i(_renderTargetWidth, 0); |
---|
| 228 | glTexCoord3f(_slicePos, 1, 1); glVertex2i(_renderTargetWidth, _renderTargetHeight); |
---|
| 229 | glTexCoord3f(_slicePos, 0, 1); glVertex2i(0, _renderTargetHeight); |
---|
| 230 | break; |
---|
| 231 | case 1: |
---|
| 232 | glTexCoord3f(0, _slicePos, 0); glVertex2i(0, 0); |
---|
| 233 | glTexCoord3f(1, _slicePos, 0); glVertex2i(_renderTargetWidth, 0); |
---|
| 234 | glTexCoord3f(1, _slicePos, 1); glVertex2i(_renderTargetWidth, _renderTargetHeight); |
---|
| 235 | glTexCoord3f(0, _slicePos, 1); glVertex2i(0, _renderTargetHeight); |
---|
| 236 | break; |
---|
| 237 | case 2: |
---|
| 238 | default: |
---|
| 239 | glTexCoord3f(0, 0, _slicePos); glVertex2i(0, 0); |
---|
| 240 | glTexCoord3f(1, 0, _slicePos); glVertex2i(_renderTargetWidth, 0); |
---|
| 241 | glTexCoord3f(1, 1, _slicePos); glVertex2i(_renderTargetWidth, _renderTargetHeight); |
---|
| 242 | glTexCoord3f(0, 1, _slicePos); glVertex2i(0, _renderTargetHeight); |
---|
| 243 | break; |
---|
[2818] | 244 | } |
---|
| 245 | glEnd(); |
---|
[1493] | 246 | |
---|
[2964] | 247 | _queryVelocityFP.disableFPTextureParameter("vfield"); |
---|
| 248 | _queryVelocityFP.unbind(); |
---|
[1493] | 249 | |
---|
[2818] | 250 | glReadPixels(0, 0, _renderTargetWidth, _renderTargetHeight, GL_RGB, GL_FLOAT, _velocities); |
---|
[1493] | 251 | |
---|
[2818] | 252 | glMatrixMode(GL_PROJECTION); |
---|
| 253 | glPopMatrix(); |
---|
| 254 | glMatrixMode(GL_MODELVIEW); |
---|
| 255 | glPopMatrix(); |
---|
[2964] | 256 | |
---|
| 257 | glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fboOrig); |
---|
| 258 | |
---|
[2818] | 259 | glPopAttrib(); |
---|
[2964] | 260 | } |
---|
[2818] | 261 | |
---|
[2964] | 262 | static void drawLineArrow(int axis) |
---|
| 263 | { |
---|
| 264 | glBegin(GL_LINES); |
---|
| 265 | switch (axis) { |
---|
| 266 | case 0: // ZY plane |
---|
| 267 | glVertex3f(0.0, 0.0, 0.0); |
---|
| 268 | glVertex3f(0.0, 0.0, 1.0); |
---|
| 269 | |
---|
| 270 | glVertex3f(0.0, 0.0, 1.0); |
---|
| 271 | glVertex3f(0.0, 0.25, 0.75); |
---|
| 272 | |
---|
| 273 | glVertex3f(0.0, 0.0, 1.0); |
---|
| 274 | glVertex3f(0.0, -0.25, 0.75); |
---|
| 275 | break; |
---|
| 276 | case 1: // XZ plane |
---|
| 277 | glVertex3f(0.0, 0.0, 0.0); |
---|
| 278 | glVertex3f(1.0, 0.0, 0.0); |
---|
| 279 | |
---|
| 280 | glVertex3f(1.0, 0.0, 0.0); |
---|
| 281 | glVertex3f(0.75, 0.0, 0.25); |
---|
| 282 | |
---|
| 283 | glVertex3f(1.0, 0.0, 0.0); |
---|
| 284 | glVertex3f(0.75, 0.0, -0.25); |
---|
| 285 | break; |
---|
| 286 | case 2: // XY plane |
---|
| 287 | default: |
---|
| 288 | glVertex3f(0.0, 0.0, 0.0); |
---|
| 289 | glVertex3f(1.0, 0.0, 0.0); |
---|
| 290 | |
---|
| 291 | glVertex3f(1.0, 0.0, 0.0); |
---|
| 292 | glVertex3f(0.75, 0.25, 0.0); |
---|
| 293 | |
---|
| 294 | glVertex3f(1.0, 0.0, 0.0); |
---|
| 295 | glVertex3f(0.75, -0.25, 0.0); |
---|
| 296 | break; |
---|
| 297 | } |
---|
| 298 | glEnd(); |
---|
[1493] | 299 | } |
---|
| 300 | |
---|
| 301 | void VelocityArrowsSlice::render() |
---|
| 302 | { |
---|
[2857] | 303 | if (!_enabled) |
---|
| 304 | return; |
---|
[2818] | 305 | |
---|
[1493] | 306 | if (_dirty) { |
---|
[2857] | 307 | computeSamplingTicks(); |
---|
| 308 | queryVelocity(); |
---|
| 309 | _dirty = false; |
---|
[1493] | 310 | } |
---|
[2818] | 311 | |
---|
[3452] | 312 | TRACE("_vf: %g %g %g", _vfXscale,_vfYscale, _vfZscale); |
---|
| 313 | TRACE("_maxVelocityScale: %g %g %g", |
---|
[2964] | 314 | _maxVelocityScale.x, _maxVelocityScale.y, _maxVelocityScale.z); |
---|
| 315 | |
---|
| 316 | glPushAttrib(GL_ENABLE_BIT | GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); |
---|
| 317 | |
---|
| 318 | glMatrixMode(GL_MODELVIEW); |
---|
[1493] | 319 | glPushMatrix(); |
---|
[2831] | 320 | |
---|
[1493] | 321 | glScalef(_vfXscale,_vfYscale, _vfZscale); |
---|
| 322 | glTranslatef(-0.5f, -0.5f, -0.5f); |
---|
[2964] | 323 | |
---|
[1493] | 324 | if (_renderMode == LINES) { |
---|
[2857] | 325 | glDisable(GL_TEXTURE_2D); |
---|
[2884] | 326 | glDisable(GL_LIGHTING); |
---|
[2857] | 327 | glLineWidth(2.0); |
---|
| 328 | glColor3f(_arrowColor.x, _arrowColor.y, _arrowColor.z); |
---|
[2964] | 329 | |
---|
[3492] | 330 | Vector3f pos; |
---|
| 331 | Vector3f vel; |
---|
| 332 | Vector3f refVec; |
---|
| 333 | Vector3f blue(0, 0, 1); |
---|
| 334 | Vector3f red(1, 0, 0); |
---|
[2831] | 335 | |
---|
[2964] | 336 | int index = 0, icount, jcount; |
---|
| 337 | switch (_axis) { |
---|
| 338 | case 0: |
---|
| 339 | icount = _tickCountZ; |
---|
| 340 | jcount = _tickCountY; |
---|
| 341 | refVec.set(0, 0, 1); |
---|
| 342 | break; |
---|
| 343 | case 1: |
---|
| 344 | icount = _tickCountZ; |
---|
| 345 | jcount = _tickCountX; |
---|
| 346 | refVec.set(1, 0, 0); |
---|
| 347 | break; |
---|
| 348 | case 2: |
---|
| 349 | default: |
---|
| 350 | icount = _tickCountY; |
---|
| 351 | jcount = _tickCountX; |
---|
| 352 | refVec.set(1, 0, 0); |
---|
| 353 | break; |
---|
| 354 | } |
---|
[2831] | 355 | |
---|
[2964] | 356 | for (int i = 0; i < icount; ++i) { |
---|
| 357 | for (int j = 0; j < jcount; ++j, ++index) { |
---|
| 358 | pos = _samplingPositions[index]; |
---|
| 359 | // Normalized velocity: [-1,1] components |
---|
| 360 | // Project 3D vector onto sample plane |
---|
| 361 | vel = _velocities[index].scale(_projectionVector); |
---|
| 362 | // Length: [0,1] |
---|
| 363 | double length = vel.length(); |
---|
| 364 | if (length < 0.0 || length > 1.0) { |
---|
[3452] | 365 | TRACE("***vec: (%g, %g, %g) length: %g***", vel.x, vel.y, vel.z, length); |
---|
[2964] | 366 | continue; |
---|
[2857] | 367 | } |
---|
[2964] | 368 | if (length > 1.0e-6) { |
---|
[3492] | 369 | Vector3f vnorm = vel.normalize(); |
---|
| 370 | Vector3f rotationAxis = refVec.cross(vnorm); |
---|
[2964] | 371 | double angle = rad2deg(acos(refVec.dot(vnorm))); |
---|
[3492] | 372 | Vector3f color = blue * (1.0 - length) + red * length; |
---|
[2964] | 373 | float scale = length; |
---|
| 374 | if (scale < 0.10) scale = 0.10; |
---|
| 375 | glMatrixMode(GL_MODELVIEW); |
---|
| 376 | glPushMatrix(); |
---|
| 377 | glColor3f(color.x, color.y, color.z); |
---|
| 378 | glTranslatef(pos.x, pos.y, pos.z); |
---|
| 379 | glScalef(2.0 * _maxVelocityScale.x, |
---|
| 380 | 2.0 * _maxVelocityScale.y, |
---|
| 381 | 2.0 * _maxVelocityScale.z); |
---|
| 382 | glScalef(scale, scale, scale); |
---|
| 383 | if (angle > 1.0e-6 || angle < -1.0e-6) |
---|
| 384 | glRotated(angle, rotationAxis.x, rotationAxis.y, rotationAxis.z); |
---|
| 385 | drawLineArrow(_axis); |
---|
| 386 | glPopMatrix(); |
---|
| 387 | } |
---|
[2818] | 388 | } |
---|
[2857] | 389 | } |
---|
[2818] | 390 | |
---|
[2857] | 391 | glLineWidth(1.0); |
---|
[1493] | 392 | } else { |
---|
[2964] | 393 | glColor4f(_arrowColor.x, _arrowColor.y, _arrowColor.z, 1.0f); |
---|
| 394 | glEnable(GL_DEPTH_TEST); |
---|
| 395 | glDisable(GL_LIGHTING); |
---|
| 396 | #if 0 |
---|
| 397 | glBlendFunc(GL_SRC_ALPHA, GL_ONE); |
---|
[2857] | 398 | glEnable(GL_BLEND); |
---|
[2964] | 399 | glDepthMask(GL_FALSE); |
---|
| 400 | #else |
---|
| 401 | glDisable(GL_BLEND); |
---|
| 402 | #endif |
---|
| 403 | glAlphaFunc(GL_GREATER, 0.6); |
---|
| 404 | glEnable(GL_ALPHA_TEST); |
---|
[2870] | 405 | glEnable(GL_POINT_SPRITE_ARB); |
---|
[2857] | 406 | glPointSize(20); |
---|
[2884] | 407 | glEnable(GL_VERTEX_PROGRAM_POINT_SIZE_ARB); |
---|
[2831] | 408 | |
---|
[2857] | 409 | _arrowsTex->activate(); |
---|
| 410 | glEnable(GL_TEXTURE_2D); |
---|
[2964] | 411 | glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); |
---|
[2831] | 412 | |
---|
[2964] | 413 | GLfloat atten[] = {1, 0, 0}; |
---|
| 414 | glPointParameterfvARB(GL_POINT_DISTANCE_ATTENUATION_ARB, atten); |
---|
[2857] | 415 | glPointParameterfARB(GL_POINT_FADE_THRESHOLD_SIZE_ARB, 0.0f); |
---|
| 416 | glPointParameterfARB(GL_POINT_SIZE_MIN_ARB, 1.0f); |
---|
[2870] | 417 | glPointParameterfARB(GL_POINT_SIZE_MAX_ARB, _maxPointSize); |
---|
[2857] | 418 | glTexEnvf(GL_POINT_SPRITE_ARB, GL_COORD_REPLACE_ARB, GL_TRUE); |
---|
[2831] | 419 | |
---|
[2964] | 420 | _particleShader.bind(); |
---|
| 421 | _particleShader.setVPTextureParameter("vfield", _vectorFieldGraphicsID); |
---|
| 422 | _particleShader.setFPTextureParameter("arrows", _arrowsTex->id()); |
---|
| 423 | _particleShader.setVPParameter1f("tanHalfFOV", |
---|
[3362] | 424 | tan(NanoVis::getCamera()->fov() * 0.5) * NanoVis::winHeight * 0.5); |
---|
[2964] | 425 | _particleShader.setGLStateMatrixVPParameter("modelview", |
---|
[4889] | 426 | Shader::MODELVIEW_MATRIX, |
---|
| 427 | Shader::MATRIX_IDENTITY); |
---|
[2964] | 428 | _particleShader.setGLStateMatrixVPParameter("mvp", |
---|
[4889] | 429 | Shader::MODELVIEW_PROJECTION_MATRIX, |
---|
| 430 | Shader::MATRIX_IDENTITY); |
---|
[2831] | 431 | |
---|
[2857] | 432 | glEnableClientState(GL_VERTEX_ARRAY); |
---|
| 433 | glBindBufferARB(GL_ARRAY_BUFFER_ARB, _vertexBufferGraphicsID); |
---|
| 434 | glVertexPointer(3, GL_FLOAT, 0, 0); |
---|
| 435 | //glEnableClientState(GL_COLOR_ARRAY); |
---|
[2831] | 436 | |
---|
[2857] | 437 | // TBD.. |
---|
| 438 | glDrawArrays(GL_POINTS, 0, _pointCount); |
---|
| 439 | glPointSize(1); |
---|
[2831] | 440 | |
---|
[2857] | 441 | glDisableClientState(GL_VERTEX_ARRAY); |
---|
[2964] | 442 | glDisable(GL_VERTEX_PROGRAM_POINT_SIZE_ARB); |
---|
| 443 | glDisable(GL_POINT_SPRITE_ARB); |
---|
[2831] | 444 | |
---|
[2964] | 445 | _particleShader.disableVPTextureParameter("vfield"); |
---|
| 446 | _particleShader.disableFPTextureParameter("arrows"); |
---|
| 447 | _particleShader.unbind(); |
---|
[2831] | 448 | |
---|
[2964] | 449 | glActiveTexture(GL_TEXTURE0); |
---|
| 450 | glTexEnvf(GL_POINT_SPRITE_ARB, GL_COORD_REPLACE_ARB, GL_FALSE); |
---|
[2857] | 451 | _arrowsTex->deactivate(); |
---|
[1493] | 452 | } |
---|
[2964] | 453 | |
---|
[1493] | 454 | glPopMatrix(); |
---|
[2964] | 455 | glPopAttrib(); |
---|
[1493] | 456 | } |
---|
[1489] | 457 | |
---|
[1493] | 458 | void |
---|
[3492] | 459 | VelocityArrowsSlice::setVectorField(unsigned int vfGraphicsID, const Vector3f& origin, |
---|
[2964] | 460 | float xScale, float yScale, float zScale, float max) |
---|
[1493] | 461 | { |
---|
| 462 | _vectorFieldGraphicsID = vfGraphicsID; |
---|
| 463 | _vfXscale = xScale; |
---|
| 464 | _vfYscale = yScale; |
---|
| 465 | _vfZscale = zScale; |
---|
| 466 | |
---|
[2964] | 467 | _dirty = true; |
---|
[1493] | 468 | } |
---|
| 469 | |
---|
| 470 | void VelocityArrowsSlice::computeSamplingTicks() |
---|
| 471 | { |
---|
[2818] | 472 | if (_vfXscale < _vfYscale) { |
---|
[2964] | 473 | if (_vfXscale < _vfZscale || _vfZscale == 0.0) { |
---|
[2818] | 474 | // vfXscale |
---|
| 475 | _tickCountX = _tickCountForMinSizeAxis; |
---|
[2857] | 476 | |
---|
[2818] | 477 | float step = _vfXscale / (_tickCountX + 1); |
---|
[2857] | 478 | |
---|
[2818] | 479 | _tickCountY = (int)(_vfYscale/step); |
---|
| 480 | _tickCountZ = (int)(_vfZscale/step); |
---|
| 481 | } else { |
---|
| 482 | // vfZscale |
---|
| 483 | _tickCountZ = _tickCountForMinSizeAxis; |
---|
[1493] | 484 | |
---|
[2818] | 485 | float step = _vfZscale / (_tickCountZ + 1); |
---|
| 486 | _tickCountX = (int)(_vfXscale/step); |
---|
| 487 | _tickCountY = (int)(_vfYscale/step); |
---|
| 488 | } |
---|
| 489 | } else { |
---|
[2964] | 490 | if (_vfYscale < _vfZscale || _vfZscale == 0.0) { |
---|
[2818] | 491 | // _vfYscale |
---|
| 492 | _tickCountY = _tickCountForMinSizeAxis; |
---|
[1484] | 493 | |
---|
[2818] | 494 | float step = _vfYscale / (_tickCountY + 1); |
---|
| 495 | _tickCountX = (int)(_vfXscale/step); |
---|
| 496 | _tickCountZ = (int)(_vfZscale/step); |
---|
| 497 | } else { |
---|
| 498 | // vfZscale |
---|
| 499 | _tickCountZ = _tickCountForMinSizeAxis; |
---|
[2857] | 500 | |
---|
[2818] | 501 | float step = _vfZscale / (_tickCountZ + 1); |
---|
| 502 | _tickCountX = (int)(_vfXscale/step); |
---|
| 503 | _tickCountY = (int)(_vfYscale/step); |
---|
| 504 | } |
---|
| 505 | } |
---|
[1493] | 506 | |
---|
[2964] | 507 | switch (_axis) { |
---|
| 508 | case 0: |
---|
| 509 | _tickCountX = 1; |
---|
| 510 | _renderTargetWidth = _tickCountY; |
---|
| 511 | _renderTargetHeight = _tickCountZ; |
---|
| 512 | break; |
---|
| 513 | case 1: |
---|
| 514 | _tickCountY = 1; |
---|
| 515 | _renderTargetWidth = _tickCountX; |
---|
| 516 | _renderTargetHeight = _tickCountZ; |
---|
| 517 | break; |
---|
| 518 | default: |
---|
| 519 | case 2: |
---|
| 520 | _tickCountZ = 1; |
---|
| 521 | _renderTargetWidth = _tickCountX; |
---|
| 522 | _renderTargetHeight = _tickCountY; |
---|
| 523 | break; |
---|
| 524 | } |
---|
| 525 | |
---|
[2884] | 526 | _maxVelocityScale.x = (1.0f / _tickCountX) * 0.8f; |
---|
| 527 | _maxVelocityScale.y = (1.0f / _tickCountY) * 0.8f; |
---|
| 528 | _maxVelocityScale.z = (1.0f / _tickCountZ) * 0.8f; |
---|
[1493] | 529 | |
---|
[3452] | 530 | TRACE("Tick counts: %d %d %d", _tickCountX, _tickCountY, _tickCountZ); |
---|
[2964] | 531 | |
---|
[2818] | 532 | int pointCount = _tickCountX * _tickCountY * _tickCountZ; |
---|
| 533 | if (_pointCount != pointCount) { |
---|
| 534 | _samplingPositions.clear(); |
---|
| 535 | _samplingPositions.reserve(pointCount); |
---|
| 536 | _pointCount = pointCount; |
---|
| 537 | } |
---|
[1493] | 538 | |
---|
[2964] | 539 | createRenderTarget(); |
---|
| 540 | |
---|
[3492] | 541 | Vector3f pos; |
---|
| 542 | Vector3f *pinfo = NULL; |
---|
[2964] | 543 | if (_renderMode == GLYPHS) { |
---|
[2818] | 544 | glBindBufferARB(GL_ARRAY_BUFFER_ARB, _vertexBufferGraphicsID); |
---|
[3492] | 545 | pinfo = (Vector3f *)glMapBufferARB(GL_ARRAY_BUFFER_ARB, GL_WRITE_ONLY_ARB); |
---|
[2964] | 546 | } |
---|
[1493] | 547 | |
---|
[2964] | 548 | if (_axis == 2) { |
---|
| 549 | for (int y = 1; y <= _tickCountY; ++y) { |
---|
| 550 | for (int x = 1; x <= _tickCountX; ++x) { |
---|
| 551 | pos.x = (1.0f / (_tickCountX + 1)) * x; |
---|
| 552 | pos.y = (1.0f / (_tickCountY + 1)) * y; |
---|
| 553 | pos.z = _slicePos; |
---|
| 554 | if (_renderMode == LINES) { |
---|
| 555 | _samplingPositions.push_back(pos); |
---|
| 556 | } else { |
---|
[2818] | 557 | *pinfo = pos; |
---|
| 558 | ++pinfo; |
---|
| 559 | } |
---|
| 560 | } |
---|
[2964] | 561 | } |
---|
| 562 | } else if (_axis == 1) { |
---|
| 563 | for (int z = 1; z <= _tickCountZ; ++z) { |
---|
| 564 | for (int x = 1; x <= _tickCountX; ++x) { |
---|
| 565 | pos.x = (1.0f / (_tickCountX + 1)) * x; |
---|
| 566 | pos.y = _slicePos; |
---|
| 567 | pos.z = (1.0f / (_tickCountZ + 1)) * z; |
---|
| 568 | if (_renderMode == LINES) { |
---|
| 569 | _samplingPositions.push_back(pos); |
---|
| 570 | } else { |
---|
[2818] | 571 | *pinfo = pos; |
---|
| 572 | ++pinfo; |
---|
| 573 | } |
---|
| 574 | } |
---|
[2964] | 575 | } |
---|
| 576 | } else if (_axis == 0) { |
---|
| 577 | for (int z = 1; z <= _tickCountZ; ++z) { |
---|
| 578 | for (int y = 1; y <= _tickCountY; ++y) { |
---|
| 579 | pos.x = _slicePos; |
---|
| 580 | pos.y = (1.0f / (_tickCountY + 1)) * y; |
---|
| 581 | pos.z = (1.0f / (_tickCountZ + 1)) * z; |
---|
| 582 | if (_renderMode == LINES) { |
---|
| 583 | _samplingPositions.push_back(pos); |
---|
| 584 | } else { |
---|
[2818] | 585 | *pinfo = pos; |
---|
| 586 | ++pinfo; |
---|
| 587 | } |
---|
| 588 | } |
---|
| 589 | } |
---|
[2964] | 590 | } |
---|
[2818] | 591 | |
---|
[2964] | 592 | if (_renderMode == GLYPHS) { |
---|
[2818] | 593 | glUnmapBufferARB(GL_ARRAY_BUFFER_ARB); |
---|
| 594 | } |
---|
[1484] | 595 | } |
---|