1 | /* -*- mode: c++; c-basic-offset: 4; indent-tabs-mode: nil -*- */ |
---|
2 | /* |
---|
3 | * Copyright (C) 2004-2013 HUBzero Foundation, LLC |
---|
4 | * |
---|
5 | */ |
---|
6 | #include "nvconf.h" |
---|
7 | |
---|
8 | #include <math.h> |
---|
9 | |
---|
10 | #include <GL/glew.h> |
---|
11 | #include <GL/gl.h> |
---|
12 | |
---|
13 | #include <vrmath/Vector3f.h> |
---|
14 | #include <util/FilePath.h> |
---|
15 | #include <Image.h> |
---|
16 | #include <ImageLoaderFactory.h> |
---|
17 | #include <ImageLoader.h> |
---|
18 | |
---|
19 | #include "nanovis.h" |
---|
20 | #include "VelocityArrowsSlice.h" |
---|
21 | #include "NvShader.h" |
---|
22 | #include "Camera.h" |
---|
23 | |
---|
24 | using namespace nv; |
---|
25 | using namespace nv::util; |
---|
26 | using namespace vrmath; |
---|
27 | |
---|
28 | static inline float deg2rad(float deg) |
---|
29 | { |
---|
30 | return ((deg * M_PI) / 180.); |
---|
31 | } |
---|
32 | |
---|
33 | static inline float rad2deg(float rad) |
---|
34 | { |
---|
35 | return ((rad * 180.) / M_PI); |
---|
36 | } |
---|
37 | |
---|
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); |
---|
66 | |
---|
67 | _queryVelocityFP.loadFragmentProgram("queryvelocity.cg", "main"); |
---|
68 | |
---|
69 | _particleShader.loadVertexProgram("velocityslicevp.cg", "vpmain"); |
---|
70 | _particleShader.loadFragmentProgram("velocityslicefp.cg", "fpmain"); |
---|
71 | |
---|
72 | createRenderTarget(); |
---|
73 | |
---|
74 | std::string path = FilePath::getInstance()->getPath("arrows.bmp"); |
---|
75 | if (!path.empty()) { |
---|
76 | ImageLoader *loader = ImageLoaderFactory::getInstance()->createLoader("bmp"); |
---|
77 | if (loader != NULL) { |
---|
78 | Image *image = loader->load(path.c_str(), Image::IMG_RGBA); |
---|
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 { |
---|
90 | ERROR("Failed to load arrows image"); |
---|
91 | } |
---|
92 | delete loader; |
---|
93 | } else { |
---|
94 | ERROR("Couldn't find loader for arrows image"); |
---|
95 | } |
---|
96 | } else { |
---|
97 | ERROR("Couldn't find arrows image"); |
---|
98 | } |
---|
99 | |
---|
100 | GLfloat minMax[2]; |
---|
101 | glGetFloatv(GL_ALIASED_POINT_SIZE_RANGE, minMax); |
---|
102 | TRACE("Aliased point size range: %g %g", minMax[0], minMax[1]); |
---|
103 | _maxPointSize = minMax[1]; |
---|
104 | glGetFloatv(GL_SMOOTH_POINT_SIZE_RANGE, minMax); |
---|
105 | TRACE("Smooth point size range: %g %g", minMax[0], minMax[1]); |
---|
106 | _maxPointSize = minMax[1] > _maxPointSize ? minMax[1] : _maxPointSize; |
---|
107 | TRACE("Max point size: %g", _maxPointSize); |
---|
108 | |
---|
109 | TRACE("Leaving VelocityArrowsSlice constructor"); |
---|
110 | } |
---|
111 | |
---|
112 | VelocityArrowsSlice::~VelocityArrowsSlice() |
---|
113 | { |
---|
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 | } |
---|
130 | |
---|
131 | void VelocityArrowsSlice::createRenderTarget() |
---|
132 | { |
---|
133 | if (_velocities != NULL) { |
---|
134 | delete [] _velocities; |
---|
135 | } |
---|
136 | _velocities = new Vector3f[_renderTargetWidth * _renderTargetHeight]; |
---|
137 | |
---|
138 | if (_vertexBufferGraphicsID != 0) { |
---|
139 | glDeleteBuffers(1, &_vertexBufferGraphicsID); |
---|
140 | } |
---|
141 | |
---|
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); |
---|
147 | |
---|
148 | if (_tex != 0) { |
---|
149 | glDeleteTextures(1, &_tex); |
---|
150 | } |
---|
151 | if (_fbo != 0) { |
---|
152 | glDeleteFramebuffersEXT(1, &_fbo); |
---|
153 | } |
---|
154 | |
---|
155 | glGenFramebuffersEXT(1, &_fbo); |
---|
156 | glGenTextures(1, &_tex); |
---|
157 | int fboOrig; |
---|
158 | glGetIntegerv(GL_FRAMEBUFFER_BINDING_EXT, &fboOrig); |
---|
159 | glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, _fbo); |
---|
160 | |
---|
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); |
---|
166 | |
---|
167 | glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA32F_ARB, |
---|
168 | _renderTargetWidth, _renderTargetHeight, 0, |
---|
169 | GL_RGBA, GL_FLOAT, NULL); |
---|
170 | |
---|
171 | glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, |
---|
172 | GL_TEXTURE_RECTANGLE_ARB, _tex, 0); |
---|
173 | |
---|
174 | glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fboOrig); |
---|
175 | } |
---|
176 | |
---|
177 | void VelocityArrowsSlice::axis(int axis) |
---|
178 | { |
---|
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 | } |
---|
197 | _dirty = true; |
---|
198 | } |
---|
199 | |
---|
200 | void VelocityArrowsSlice::queryVelocity() |
---|
201 | { |
---|
202 | if (!_enabled) return; |
---|
203 | |
---|
204 | glPushAttrib(GL_VIEWPORT_BIT | GL_ENABLE_BIT); |
---|
205 | int fboOrig; |
---|
206 | glGetIntegerv(GL_FRAMEBUFFER_BINDING_EXT, &fboOrig); |
---|
207 | |
---|
208 | glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, _fbo); |
---|
209 | |
---|
210 | _queryVelocityFP.bind(); |
---|
211 | _queryVelocityFP.setFPTextureParameter("vfield", _vectorFieldGraphicsID); |
---|
212 | |
---|
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(); |
---|
222 | |
---|
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; |
---|
244 | } |
---|
245 | glEnd(); |
---|
246 | |
---|
247 | _queryVelocityFP.disableFPTextureParameter("vfield"); |
---|
248 | _queryVelocityFP.unbind(); |
---|
249 | |
---|
250 | glReadPixels(0, 0, _renderTargetWidth, _renderTargetHeight, GL_RGB, GL_FLOAT, _velocities); |
---|
251 | |
---|
252 | glMatrixMode(GL_PROJECTION); |
---|
253 | glPopMatrix(); |
---|
254 | glMatrixMode(GL_MODELVIEW); |
---|
255 | glPopMatrix(); |
---|
256 | |
---|
257 | glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fboOrig); |
---|
258 | |
---|
259 | glPopAttrib(); |
---|
260 | } |
---|
261 | |
---|
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(); |
---|
299 | } |
---|
300 | |
---|
301 | void VelocityArrowsSlice::render() |
---|
302 | { |
---|
303 | if (!_enabled) |
---|
304 | return; |
---|
305 | |
---|
306 | if (_dirty) { |
---|
307 | computeSamplingTicks(); |
---|
308 | queryVelocity(); |
---|
309 | _dirty = false; |
---|
310 | } |
---|
311 | |
---|
312 | TRACE("_vf: %g %g %g", _vfXscale,_vfYscale, _vfZscale); |
---|
313 | TRACE("_maxVelocityScale: %g %g %g", |
---|
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); |
---|
319 | glPushMatrix(); |
---|
320 | |
---|
321 | glScalef(_vfXscale,_vfYscale, _vfZscale); |
---|
322 | glTranslatef(-0.5f, -0.5f, -0.5f); |
---|
323 | |
---|
324 | if (_renderMode == LINES) { |
---|
325 | glDisable(GL_TEXTURE_2D); |
---|
326 | glDisable(GL_LIGHTING); |
---|
327 | glLineWidth(2.0); |
---|
328 | glColor3f(_arrowColor.x, _arrowColor.y, _arrowColor.z); |
---|
329 | |
---|
330 | Vector3f pos; |
---|
331 | Vector3f vel; |
---|
332 | Vector3f refVec; |
---|
333 | Vector3f blue(0, 0, 1); |
---|
334 | Vector3f red(1, 0, 0); |
---|
335 | |
---|
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 | } |
---|
355 | |
---|
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) { |
---|
365 | TRACE("***vec: (%g, %g, %g) length: %g***", vel.x, vel.y, vel.z, length); |
---|
366 | continue; |
---|
367 | } |
---|
368 | if (length > 1.0e-6) { |
---|
369 | Vector3f vnorm = vel.normalize(); |
---|
370 | Vector3f rotationAxis = refVec.cross(vnorm); |
---|
371 | double angle = rad2deg(acos(refVec.dot(vnorm))); |
---|
372 | Vector3f color = blue * (1.0 - length) + red * length; |
---|
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 | } |
---|
388 | } |
---|
389 | } |
---|
390 | |
---|
391 | glLineWidth(1.0); |
---|
392 | } else { |
---|
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); |
---|
398 | glEnable(GL_BLEND); |
---|
399 | glDepthMask(GL_FALSE); |
---|
400 | #else |
---|
401 | glDisable(GL_BLEND); |
---|
402 | #endif |
---|
403 | glAlphaFunc(GL_GREATER, 0.6); |
---|
404 | glEnable(GL_ALPHA_TEST); |
---|
405 | glEnable(GL_POINT_SPRITE_ARB); |
---|
406 | glPointSize(20); |
---|
407 | glEnable(GL_VERTEX_PROGRAM_POINT_SIZE_ARB); |
---|
408 | |
---|
409 | _arrowsTex->activate(); |
---|
410 | glEnable(GL_TEXTURE_2D); |
---|
411 | glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); |
---|
412 | |
---|
413 | GLfloat atten[] = {1, 0, 0}; |
---|
414 | glPointParameterfvARB(GL_POINT_DISTANCE_ATTENUATION_ARB, atten); |
---|
415 | glPointParameterfARB(GL_POINT_FADE_THRESHOLD_SIZE_ARB, 0.0f); |
---|
416 | glPointParameterfARB(GL_POINT_SIZE_MIN_ARB, 1.0f); |
---|
417 | glPointParameterfARB(GL_POINT_SIZE_MAX_ARB, _maxPointSize); |
---|
418 | glTexEnvf(GL_POINT_SPRITE_ARB, GL_COORD_REPLACE_ARB, GL_TRUE); |
---|
419 | |
---|
420 | _particleShader.bind(); |
---|
421 | _particleShader.setVPTextureParameter("vfield", _vectorFieldGraphicsID); |
---|
422 | _particleShader.setFPTextureParameter("arrows", _arrowsTex->id()); |
---|
423 | _particleShader.setVPParameter1f("tanHalfFOV", |
---|
424 | tan(NanoVis::getCamera()->fov() * 0.5) * NanoVis::winHeight * 0.5); |
---|
425 | _particleShader.setGLStateMatrixVPParameter("modelview", |
---|
426 | NvShader::MODELVIEW_MATRIX, |
---|
427 | NvShader::MATRIX_IDENTITY); |
---|
428 | _particleShader.setGLStateMatrixVPParameter("mvp", |
---|
429 | NvShader::MODELVIEW_PROJECTION_MATRIX, |
---|
430 | NvShader::MATRIX_IDENTITY); |
---|
431 | |
---|
432 | glEnableClientState(GL_VERTEX_ARRAY); |
---|
433 | glBindBufferARB(GL_ARRAY_BUFFER_ARB, _vertexBufferGraphicsID); |
---|
434 | glVertexPointer(3, GL_FLOAT, 0, 0); |
---|
435 | //glEnableClientState(GL_COLOR_ARRAY); |
---|
436 | |
---|
437 | // TBD.. |
---|
438 | glDrawArrays(GL_POINTS, 0, _pointCount); |
---|
439 | glPointSize(1); |
---|
440 | |
---|
441 | glDisableClientState(GL_VERTEX_ARRAY); |
---|
442 | glDisable(GL_VERTEX_PROGRAM_POINT_SIZE_ARB); |
---|
443 | glDisable(GL_POINT_SPRITE_ARB); |
---|
444 | |
---|
445 | _particleShader.disableVPTextureParameter("vfield"); |
---|
446 | _particleShader.disableFPTextureParameter("arrows"); |
---|
447 | _particleShader.unbind(); |
---|
448 | |
---|
449 | glActiveTexture(GL_TEXTURE0); |
---|
450 | glTexEnvf(GL_POINT_SPRITE_ARB, GL_COORD_REPLACE_ARB, GL_FALSE); |
---|
451 | _arrowsTex->deactivate(); |
---|
452 | } |
---|
453 | |
---|
454 | glPopMatrix(); |
---|
455 | glPopAttrib(); |
---|
456 | } |
---|
457 | |
---|
458 | void |
---|
459 | VelocityArrowsSlice::setVectorField(unsigned int vfGraphicsID, const Vector3f& origin, |
---|
460 | float xScale, float yScale, float zScale, float max) |
---|
461 | { |
---|
462 | _vectorFieldGraphicsID = vfGraphicsID; |
---|
463 | _vfXscale = xScale; |
---|
464 | _vfYscale = yScale; |
---|
465 | _vfZscale = zScale; |
---|
466 | |
---|
467 | _dirty = true; |
---|
468 | } |
---|
469 | |
---|
470 | void VelocityArrowsSlice::computeSamplingTicks() |
---|
471 | { |
---|
472 | if (_vfXscale < _vfYscale) { |
---|
473 | if (_vfXscale < _vfZscale || _vfZscale == 0.0) { |
---|
474 | // vfXscale |
---|
475 | _tickCountX = _tickCountForMinSizeAxis; |
---|
476 | |
---|
477 | float step = _vfXscale / (_tickCountX + 1); |
---|
478 | |
---|
479 | _tickCountY = (int)(_vfYscale/step); |
---|
480 | _tickCountZ = (int)(_vfZscale/step); |
---|
481 | } else { |
---|
482 | // vfZscale |
---|
483 | _tickCountZ = _tickCountForMinSizeAxis; |
---|
484 | |
---|
485 | float step = _vfZscale / (_tickCountZ + 1); |
---|
486 | _tickCountX = (int)(_vfXscale/step); |
---|
487 | _tickCountY = (int)(_vfYscale/step); |
---|
488 | } |
---|
489 | } else { |
---|
490 | if (_vfYscale < _vfZscale || _vfZscale == 0.0) { |
---|
491 | // _vfYscale |
---|
492 | _tickCountY = _tickCountForMinSizeAxis; |
---|
493 | |
---|
494 | float step = _vfYscale / (_tickCountY + 1); |
---|
495 | _tickCountX = (int)(_vfXscale/step); |
---|
496 | _tickCountZ = (int)(_vfZscale/step); |
---|
497 | } else { |
---|
498 | // vfZscale |
---|
499 | _tickCountZ = _tickCountForMinSizeAxis; |
---|
500 | |
---|
501 | float step = _vfZscale / (_tickCountZ + 1); |
---|
502 | _tickCountX = (int)(_vfXscale/step); |
---|
503 | _tickCountY = (int)(_vfYscale/step); |
---|
504 | } |
---|
505 | } |
---|
506 | |
---|
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 | |
---|
526 | _maxVelocityScale.x = (1.0f / _tickCountX) * 0.8f; |
---|
527 | _maxVelocityScale.y = (1.0f / _tickCountY) * 0.8f; |
---|
528 | _maxVelocityScale.z = (1.0f / _tickCountZ) * 0.8f; |
---|
529 | |
---|
530 | TRACE("Tick counts: %d %d %d", _tickCountX, _tickCountY, _tickCountZ); |
---|
531 | |
---|
532 | int pointCount = _tickCountX * _tickCountY * _tickCountZ; |
---|
533 | if (_pointCount != pointCount) { |
---|
534 | _samplingPositions.clear(); |
---|
535 | _samplingPositions.reserve(pointCount); |
---|
536 | _pointCount = pointCount; |
---|
537 | } |
---|
538 | |
---|
539 | createRenderTarget(); |
---|
540 | |
---|
541 | Vector3f pos; |
---|
542 | Vector3f *pinfo = NULL; |
---|
543 | if (_renderMode == GLYPHS) { |
---|
544 | glBindBufferARB(GL_ARRAY_BUFFER_ARB, _vertexBufferGraphicsID); |
---|
545 | pinfo = (Vector3f *)glMapBufferARB(GL_ARRAY_BUFFER_ARB, GL_WRITE_ONLY_ARB); |
---|
546 | } |
---|
547 | |
---|
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 { |
---|
557 | *pinfo = pos; |
---|
558 | ++pinfo; |
---|
559 | } |
---|
560 | } |
---|
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 { |
---|
571 | *pinfo = pos; |
---|
572 | ++pinfo; |
---|
573 | } |
---|
574 | } |
---|
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 { |
---|
585 | *pinfo = pos; |
---|
586 | ++pinfo; |
---|
587 | } |
---|
588 | } |
---|
589 | } |
---|
590 | } |
---|
591 | |
---|
592 | if (_renderMode == GLYPHS) { |
---|
593 | glUnmapBufferARB(GL_ARRAY_BUFFER_ARB); |
---|
594 | } |
---|
595 | } |
---|