1 | #include <GL/glew.h>
|
---|
2 | #ifdef _WIN32 |
---|
3 | #include <windows.h>
|
---|
4 | #endif |
---|
5 | #include <GL/gl.h>
|
---|
6 | #include "VelocityArrowsSlice.h"
|
---|
7 | #include "global.h" |
---|
8 | #include "Nv.h" |
---|
9 |
|
---|
10 | VelocityArrowsSlice::VelocityArrowsSlice()
|
---|
11 | {
|
---|
12 | _context = cgCreateContext();
|
---|
13 | _vectorFieldGraphicsID = 0;
|
---|
14 | _vfXscale = _vfYscale = _vfZscale = 0;
|
---|
15 | _slicePos = 0.5f;
|
---|
16 | _enabled =true; |
---|
17 |
|
---|
18 | axis(2);
|
---|
19 |
|
---|
20 |
|
---|
21 | _tickCountForMinSizeAxis = 10;
|
---|
22 |
|
---|
23 | _queryVelocityFP = LoadCgSourceProgram(_context, "queryvelocity.cg", |
---|
24 | CG_PROFILE_FP30, "main"); |
---|
25 | _ipVectorFieldParam = cgGetNamedParameter(_queryVelocityFP, "vfield");
|
---|
26 |
|
---|
27 | _dirty = true;
|
---|
28 | _dirtySamplingPosition = true;
|
---|
29 | _dirtyRenderTarget = true;
|
---|
30 | _maxVelocityScale.x = _maxVelocityScale.y = _maxVelocityScale.z = 1.0f;
|
---|
31 |
|
---|
32 | _renderTargetWidth = 128;
|
---|
33 | _renderTargetHeight = 128;
|
---|
34 | _velocities = new Vector3[_renderTargetWidth * _renderTargetHeight];
|
---|
35 | createRenderTarget();
|
---|
36 | _pointCount = 0;
|
---|
37 | _vectorFieldGraphicsID = 0;
|
---|
38 | }
|
---|
39 |
|
---|
40 | void VelocityArrowsSlice::createRenderTarget()
|
---|
41 | {
|
---|
42 | glGenFramebuffersEXT(1, &_fbo);
|
---|
43 | glGenTextures(1, &_tex);
|
---|
44 |
|
---|
45 | glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, _fbo);
|
---|
46 |
|
---|
47 | glViewport(0, 0, _renderTargetWidth, _renderTargetHeight);
|
---|
48 | glMatrixMode(GL_PROJECTION);
|
---|
49 | glLoadIdentity();
|
---|
50 | glOrtho(0, _renderTargetWidth, 0, _renderTargetHeight, -10.0f, 10.0f);
|
---|
51 | glMatrixMode(GL_MODELVIEW);
|
---|
52 | glLoadIdentity();
|
---|
53 |
|
---|
54 | glBindTexture(GL_TEXTURE_RECTANGLE_NV, _tex);
|
---|
55 | glTexParameterf(GL_TEXTURE_RECTANGLE_NV, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
---|
56 | glTexParameterf(GL_TEXTURE_RECTANGLE_NV, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
---|
57 | glTexParameteri(GL_TEXTURE_RECTANGLE_NV, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
---|
58 | glTexParameteri(GL_TEXTURE_RECTANGLE_NV, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
---|
59 |
|
---|
60 | glTexImage2D(GL_TEXTURE_RECTANGLE_NV, 0, GL_FLOAT_RGBA32_NV,
|
---|
61 | _renderTargetWidth, _renderTargetHeight, 0, GL_RGBA, GL_FLOAT, NULL);
|
---|
62 |
|
---|
63 |
|
---|
64 | glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT,
|
---|
65 | GL_TEXTURE_RECTANGLE_NV, _tex, 0);
|
---|
66 |
|
---|
67 | glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
|
---|
68 | }
|
---|
69 |
|
---|
70 | void VelocityArrowsSlice::axis(int axis)
|
---|
71 | {
|
---|
72 | _axis = axis;
|
---|
73 | switch (_axis)
|
---|
74 | {
|
---|
75 | case 0 :
|
---|
76 | _projectionVector.x = 0;
|
---|
77 | _projectionVector.y = 1;
|
---|
78 | _projectionVector.z = 1;
|
---|
79 | break;
|
---|
80 | case 1 :
|
---|
81 | _projectionVector.x = 1;
|
---|
82 | _projectionVector.y = 0;
|
---|
83 | _projectionVector.z = 1;
|
---|
84 | break;
|
---|
85 | case 2 :
|
---|
86 | _projectionVector.x = 1;
|
---|
87 | _projectionVector.y = 1;
|
---|
88 | _projectionVector.z = 0;
|
---|
89 | break;
|
---|
90 | }
|
---|
91 | _dirtySamplingPosition = true;
|
---|
92 | _dirtyRenderTarget = true;
|
---|
93 | _dirty = true; |
---|
94 | }
|
---|
95 |
|
---|
96 |
|
---|
97 | void VelocityArrowsSlice::queryVelocity()
|
---|
98 | {
|
---|
99 | if (!_enabled) return;
|
---|
100 |
|
---|
101 | glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, _fbo);
|
---|
102 | glDisable(GL_DEPTH_TEST);
|
---|
103 | cgGLBindProgram(_queryVelocityFP);
|
---|
104 | cgGLEnableProfile(CG_PROFILE_FP30);
|
---|
105 | cgGLSetTextureParameter(_ipVectorFieldParam, _vectorFieldGraphicsID);
|
---|
106 | cgGLEnableTextureParameter(_ipVectorFieldParam);
|
---|
107 |
|
---|
108 | glPushAttrib(GL_VIEWPORT_BIT);
|
---|
109 | glViewport(0, 0, _renderTargetWidth, _renderTargetHeight);
|
---|
110 | glMatrixMode(GL_PROJECTION);
|
---|
111 | glPushMatrix();
|
---|
112 | glLoadIdentity();
|
---|
113 | glOrtho(0, _renderTargetWidth, 0, _renderTargetHeight, -10.0f, 10.0f);
|
---|
114 | glMatrixMode(GL_MODELVIEW);
|
---|
115 | glPushMatrix();
|
---|
116 | glLoadIdentity();
|
---|
117 | glBegin(GL_POINTS);
|
---|
118 |
|
---|
119 | for (int index = 0; index < _samplingPositions.size(); ++index)
|
---|
120 | {
|
---|
121 | glMultiTexCoord3f(0, _samplingPositions[index].x,_samplingPositions[index].y,_samplingPositions[index].z);
|
---|
122 | glVertex2f(index % _renderTargetWidth,
|
---|
123 | index / _renderTargetHeight);
|
---|
124 | }
|
---|
125 |
|
---|
126 | glEnd();
|
---|
127 |
|
---|
128 | glDisable(GL_TEXTURE_RECTANGLE_NV);
|
---|
129 | cgGLDisableTextureParameter(_ipVectorFieldParam);
|
---|
130 | cgGLDisableProfile(CG_PROFILE_FP30);
|
---|
131 |
|
---|
132 | glReadPixels(0, 0, _renderTargetWidth, _renderTargetHeight, GL_RGB, GL_FLOAT, _velocities);
|
---|
133 |
|
---|
134 | glMatrixMode(GL_PROJECTION);
|
---|
135 | glPopMatrix();
|
---|
136 | glMatrixMode(GL_MODELVIEW);
|
---|
137 | glPopMatrix();
|
---|
138 | glPopAttrib();
|
---|
139 |
|
---|
140 | glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
|
---|
141 | }
|
---|
142 |
|
---|
143 | void VelocityArrowsSlice::render()
|
---|
144 | {
|
---|
145 | if (!_enabled || _vectorFieldGraphicsID == 0) return;
|
---|
146 | if (_dirty)
|
---|
147 | {
|
---|
148 | computeSamplingTicks();
|
---|
149 | queryVelocity();
|
---|
150 | _dirty = false;
|
---|
151 | }
|
---|
152 |
|
---|
153 |
|
---|
154 | glPushMatrix();
|
---|
155 | glScalef(_vfXscale,_vfYscale, _vfZscale);
|
---|
156 | glTranslatef(-0.5f, -0.5f, -0.5f);
|
---|
157 | glDisable(GL_TEXTURE_2D);
|
---|
158 | glLineWidth(2.0);
|
---|
159 | glColor3f(0, 0, 1);
|
---|
160 | glBegin(GL_LINES);
|
---|
161 | Vector3 pos;
|
---|
162 | Vector3 pos2;
|
---|
163 | Vector3 vel(1, 0, 0);
|
---|
164 | Vector3 v, v2;
|
---|
165 | if (_axis == 2)
|
---|
166 | {
|
---|
167 | int index = 0;
|
---|
168 | for (int y = 1; y <= _tickCountY; ++y)
|
---|
169 | for (int x = 1; x <= _tickCountX; ++x, ++index)
|
---|
170 | {
|
---|
171 | pos = this->_samplingPositions[index];
|
---|
172 | pos2 = this->_velocities[index].scale(_projectionVector).scale(_maxVelocityScale) + pos;
|
---|
173 | glVertex3f(pos.x, pos.y, pos.z);
|
---|
174 | glVertex3f(pos2.x, pos2.y, pos2.z);
|
---|
175 |
|
---|
176 | }
|
---|
177 | }
|
---|
178 | else if (_axis == 1)
|
---|
179 | {
|
---|
180 | int index = 0;
|
---|
181 | for (int z = 1; z <= _tickCountZ; ++z)
|
---|
182 | for (int x = 1; x <= _tickCountX; ++x, ++index)
|
---|
183 | {
|
---|
184 | pos = _samplingPositions[index];
|
---|
185 | pos2 = _velocities[index].scale(_projectionVector).scale(_maxVelocityScale) + pos;
|
---|
186 |
|
---|
187 | glVertex3f(pos.x, pos.y, pos.z);
|
---|
188 | glVertex3f(pos2.x, pos2.y, pos2.z);
|
---|
189 | }
|
---|
190 | }
|
---|
191 | else if (_axis == 0)
|
---|
192 | {
|
---|
193 | int index = 0;
|
---|
194 | for (int z = 1; z <= _tickCountZ; ++z)
|
---|
195 | for (int y = 1; y <= _tickCountY; ++y, ++index)
|
---|
196 | {
|
---|
197 | pos = _samplingPositions[index];
|
---|
198 | pos2 = _velocities[index].scale(_projectionVector).scale(_maxVelocityScale) + pos;
|
---|
199 |
|
---|
200 | glVertex3f(pos.x, pos.y, pos.z);
|
---|
201 | glVertex3f(pos2.x, pos2.y, pos2.z);
|
---|
202 | }
|
---|
203 | }
|
---|
204 |
|
---|
205 | glEnd();
|
---|
206 | glPopMatrix();
|
---|
207 | glLineWidth(1.0);
|
---|
208 | }
|
---|
209 |
|
---|
210 | void VelocityArrowsSlice::enabled(bool e)
|
---|
211 | {
|
---|
212 | _enabled = e;
|
---|
213 | }
|
---|
214 |
|
---|
215 | void VelocityArrowsSlice::vectorField(unsigned int vfGraphicsID,
|
---|
216 | float xScale, float yScale, float zScale)
|
---|
217 | {
|
---|
218 | _vectorFieldGraphicsID = vfGraphicsID;
|
---|
219 | _vfXscale = xScale;
|
---|
220 | _vfYscale = yScale;
|
---|
221 | _vfZscale = zScale;
|
---|
222 | }
|
---|
223 |
|
---|
224 | void VelocityArrowsSlice::tickCountForMinSizeAxis(int tickCount)
|
---|
225 | {
|
---|
226 | _tickCountForMinSizeAxis = tickCount;
|
---|
227 |
|
---|
228 | }
|
---|
229 |
|
---|
230 |
|
---|
231 | void VelocityArrowsSlice::computeSamplingTicks()
|
---|
232 | {
|
---|
233 | if (_vfXscale < _vfYscale)
|
---|
234 | {
|
---|
235 | if (_vfXscale < _vfZscale)
|
---|
236 | {
|
---|
237 | // vfXscale
|
---|
238 | _tickCountX = _tickCountForMinSizeAxis;
|
---|
239 |
|
---|
240 | float step = _vfXscale / (_tickCountX + 1);
|
---|
241 |
|
---|
242 | _tickCountY = (int) (_vfYscale/step);
|
---|
243 | _tickCountZ = (int) (_vfZscale/step);
|
---|
244 | //vscalex = 1; |
---|
245 | //vscaley = _vfXscale / _vfXscale; |
---|
246 | //vscalez = _vfZscale / _vfXscale; |
---|
247 | }
|
---|
248 | else
|
---|
249 | {
|
---|
250 | // vfZscale
|
---|
251 | _tickCountZ = _tickCountForMinSizeAxis;
|
---|
252 |
|
---|
253 | float step = _vfZscale / (_tickCountZ + 1);
|
---|
254 | _tickCountX = (int) (_vfXscale/step);
|
---|
255 | _tickCountY = (int) (_vfYscale/step);
|
---|
256 | //vscalex = _vfXscale / _vfZscale; |
---|
257 | //vscaley = _vfYscale / _vfZscale; |
---|
258 | //vscalez = 1; |
---|
259 | }
|
---|
260 |
|
---|
261 | }
|
---|
262 | else
|
---|
263 | {
|
---|
264 | if (_vfYscale < _vfZscale)
|
---|
265 | {
|
---|
266 | // _vfYscale
|
---|
267 | _tickCountY = _tickCountForMinSizeAxis;
|
---|
268 |
|
---|
269 | float step = _vfYscale / (_tickCountY + 1);
|
---|
270 | _tickCountX = (int) (_vfXscale/step);
|
---|
271 | _tickCountZ = (int) (_vfZscale/step);
|
---|
272 | |
---|
273 | //vscalex = _vfXscale / _vfYscale; |
---|
274 | //vscaley = 1; |
---|
275 | //vscalez = _vfZscale / _vfYscale; |
---|
276 | }
|
---|
277 | else
|
---|
278 | {
|
---|
279 | // vfZscale
|
---|
280 | _tickCountZ = _tickCountForMinSizeAxis;
|
---|
281 |
|
---|
282 | float step = _vfZscale / (_tickCountZ + 1);
|
---|
283 | _tickCountX = (int) (_vfXscale/step);
|
---|
284 | _tickCountY = (int) (_vfYscale/step);
|
---|
285 | |
---|
286 | //vscalex = _vfXscale / _vfZscale; |
---|
287 | //vscaley = _vfYscale / _vfZscale; |
---|
288 | //vscalez = 1; |
---|
289 |
|
---|
290 |
|
---|
291 | }
|
---|
292 | }
|
---|
293 |
|
---|
294 | _maxVelocityScale.x = 1.0f / _tickCountX * 0.8f; |
---|
295 | _maxVelocityScale.y = 1.0f / _tickCountY * 0.8f; |
---|
296 | _maxVelocityScale.z = 1.0f / _tickCountZ * 0.8f; |
---|
297 |
|
---|
298 | int pointCount = _tickCountX * _tickCountY * _tickCountZ;
|
---|
299 | if (_pointCount != pointCount)
|
---|
300 | {
|
---|
301 | _samplingPositions.clear();
|
---|
302 | _samplingPositions.reserve(pointCount);
|
---|
303 | _pointCount = pointCount;
|
---|
304 | }
|
---|
305 |
|
---|
306 |
|
---|
307 | Vector3 pos;
|
---|
308 | if (_axis == 2)
|
---|
309 | {
|
---|
310 | for (int y = 1; y <= _tickCountY; ++y)
|
---|
311 | for (int x = 1; x <= _tickCountX; ++x)
|
---|
312 | {
|
---|
313 | pos.x = (1.0f / (_tickCountX + 1)) * x;
|
---|
314 | pos.y = (1.0f / (_tickCountY + 1)) * y;
|
---|
315 | pos.z = _slicePos;
|
---|
316 | _samplingPositions.push_back(pos);
|
---|
317 | }
|
---|
318 | }
|
---|
319 | else if (_axis == 1)
|
---|
320 | {
|
---|
321 | for (int z = 1; z <= _tickCountZ; ++z)
|
---|
322 | for (int x = 1; x <= _tickCountX; ++x)
|
---|
323 | {
|
---|
324 | pos.x = (1.0f / (_tickCountX + 1)) * x;
|
---|
325 | pos.y = _slicePos;
|
---|
326 | pos.z = (1.0f / (_tickCountZ + 1)) * z;
|
---|
327 | _samplingPositions.push_back(pos);
|
---|
328 | }
|
---|
329 | }
|
---|
330 | else if (_axis == 0)
|
---|
331 | {
|
---|
332 | for (int z = 1; z <= _tickCountZ; ++z)
|
---|
333 | for (int y = 1; y <= _tickCountY; ++y)
|
---|
334 | {
|
---|
335 | pos.x = _slicePos;
|
---|
336 | pos.y = (1.0f / (_tickCountY + 1)) * y;
|
---|
337 | pos.z = (1.0f / (_tickCountZ + 1)) * z;
|
---|
338 | _samplingPositions.push_back(pos);
|
---|
339 | }
|
---|
340 | }
|
---|
341 | } |
---|
342 | |
---|
343 | void VelocityArrowsSlice::slicePos(float pos) |
---|
344 | {
|
---|
345 | // TBD.. |
---|
346 | //_slicePos = pos;
|
---|
347 | _dirty = true; |
---|
348 | }
|
---|