source: trunk/packages/vizservers/nanovis/HeightMap.cpp @ 1161

Last change on this file since 1161 was 1161, checked in by gah, 16 years ago

added stats counters

File size: 14.8 KB
Line 
1 
2#include <memory.h>
3#include <stdlib.h>
4#include <sys/time.h>
5#include <sys/types.h>
6#include <unistd.h>
7#include <fcntl.h>
8#include <stdlib.h>
9#include <GL/glew.h>
10#include <GL/gl.h>
11#include "Grid.h"
12#include "HeightMap.h"
13#include "ContourLineFilter.h"
14#include "TypeDefs.h"
15#include "Texture1D.h"
16#include "R2/R2FilePath.h"
17#include "RpField1D.h"
18#include "RenderContext.h"
19
20bool HeightMap::update_pending = false;
21double HeightMap::valueMin = 0.0;
22double HeightMap::valueMax = 1.0;
23
24#define TOPCONTOUR      0
25HeightMap::HeightMap() :
26    _vertexBufferObjectID(0),
27    _textureBufferObjectID(0),
28    _vertexCount(0),
29    _contour(0),
30    _topContour(0),
31    _colorMap(0),
32    _indexBuffer(0),
33    _indexCount(0),
34    _contourColor(1.0f, 0.0f, 0.0f),
35    _contourVisible(false),
36    _topContourVisible(true),
37    _visible(false),
38    _scale(1.0f, 1.0f, 1.0f),
39    _centerPoint(0.0f, 0.0f, 0.0f),
40    heights_(NULL)
41{
42    _shader = new NvShader();
43    _shader->loadFragmentProgram("heightcolor.cg", "main");
44    _tf = _shader->getNamedParameterFromFP("tf");
45}
46
47HeightMap::~HeightMap()
48{
49    reset();
50
51    if (_shader) {
52        delete _shader;
53    }
54
55    // TMP
56    //if (_colorMap) delete _colorMap;
57}
58
59void HeightMap::render(graphics::RenderContext* renderContext)
60{
61    if (renderContext->getCullMode() == graphics::RenderContext::NO_CULL) {
62        glDisable(GL_CULL_FACE);
63    } else {
64        glEnable(GL_CULL_FACE);
65        glCullFace((GLuint) renderContext->getCullMode());
66    }
67    glPolygonMode(GL_FRONT_AND_BACK, (GLuint) renderContext->getPolygonMode());
68    glShadeModel((GLuint) renderContext->getShadingModel());
69
70    glPushMatrix();
71
72#ifndef notdef
73    if (_scale.x != 0.0) {
74        glScalef(1 / _scale.x, 1 / _scale.y , 1 / _scale.z);
75    }
76#endif
77    glTranslatef(-_centerPoint.x, -_centerPoint.y, -_centerPoint.z);
78
79    if (_contour != NULL) {
80        glDepthRange (0.001, 1.0);
81    }
82       
83    glEnable(GL_DEPTH_TEST);
84
85    if (_vertexBufferObjectID) {
86        glColor3f(1.0f, 1.0f, 1.0f);
87        glShadeModel(GL_SMOOTH);
88        glEnable(GL_BLEND);
89        glEnableClientState(GL_VERTEX_ARRAY);
90        glDisableClientState(GL_COLOR_ARRAY);
91        glDisableClientState(GL_INDEX_ARRAY);
92        glDisableClientState(GL_NORMAL_ARRAY);
93       
94        if (_colorMap) {
95            // PUT vertex program here
96            //
97            //
98           
99            cgGLBindProgram(_shader->getFP());
100            cgGLEnableProfile(CG_PROFILE_FP30);
101           
102            cgGLSetTextureParameter(_tf, _colorMap->id);
103            cgGLEnableTextureParameter(_tf);
104           
105            glEnable(GL_TEXTURE_1D);
106            _colorMap->getTexture()->activate();
107           
108            glEnableClientState(GL_TEXTURE_COORD_ARRAY);
109        }
110       
111        glBindBuffer(GL_ARRAY_BUFFER, _vertexBufferObjectID);
112        glVertexPointer(3, GL_FLOAT, 12, 0);
113       
114        glBindBuffer(GL_ARRAY_BUFFER, _textureBufferObjectID);
115        ::glTexCoordPointer(3, GL_FLOAT, 12, 0);
116       
117#define _TRIANGLES_
118#ifdef _TRIANGLES_
119        glDrawElements(GL_TRIANGLES, _indexCount, GL_UNSIGNED_INT,
120                       _indexBuffer);
121#else                   
122        glDrawElements(GL_QUADS, _indexCount, GL_UNSIGNED_INT,
123                       _indexBuffer);
124#endif
125
126        glBindBuffer(GL_ARRAY_BUFFER, 0);
127       
128        glDisableClientState(GL_VERTEX_ARRAY);
129        if (_colorMap) {
130            _colorMap->getTexture()->deactivate();
131            glDisableClientState(GL_TEXTURE_COORD_ARRAY);
132           
133            cgGLDisableProfile(CG_PROFILE_FP30);
134        }
135    }
136   
137    glShadeModel(GL_FLAT);
138    glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
139   
140    if (_contour != NULL) {
141        if (_contourVisible) {
142            glDisable(GL_BLEND);
143            glDisable(GL_TEXTURE_2D);
144            glColor4f(_contourColor.x, _contourColor.y, _contourColor.z, 1.0f);
145            glDepthRange (0.0, 0.999);
146            _contour->render();
147            glDepthRange (0.0, 1.0);
148        }
149
150#if TOPCONTOUR
151        if (_topContourVisible) {
152            glDisable(GL_BLEND);
153            glDisable(GL_TEXTURE_2D);
154            glColor4f(_contourColor.x, _contourColor.y, _contourColor.z, 1.0f);
155            //glDepthRange (0.0, 0.999);
156            _topContour->render();
157            //glDepthRange (0.0, 1.0);
158        }
159#endif
160    }
161    glPopMatrix();
162}
163
164void
165HeightMap::createIndexBuffer(int xCount, int zCount, float* heights)
166{
167    if (_indexBuffer != NULL) {
168        delete [] _indexBuffer;
169    }
170    _indexCount = (xCount - 1) * (zCount - 1) * 6;
171    _indexBuffer = new int[_indexCount];
172   
173    int i, j;
174    int boundaryWidth = xCount - 1;
175    int boundaryHeight = zCount - 1;
176    int* ptr = _indexBuffer;
177    int index1, index2, index3, index4;
178    bool index1Valid, index2Valid, index3Valid, index4Valid;
179    index1Valid = index2Valid = index3Valid = index4Valid = true;
180
181    if (heights) {
182        int ic = 0;
183        for (i = 0; i < boundaryHeight; ++i) {
184            for (j = 0; j < boundaryWidth; ++j) {
185                index1 = i * xCount +j;
186                if (isnan(heights[index1])) index1Valid = false;
187                index2 = (i + 1) * xCount + j;
188                if (isnan(heights[index2])) index2Valid = false;
189                index3 = (i + 1) * xCount + j + 1;
190                if (isnan(heights[index3])) index3Valid = false;
191                index4 = i * xCount + j + 1;
192                if (isnan(heights[index4])) index4Valid = false;
193           
194#ifdef _TRIANGLES_
195                if (index1Valid && index2Valid && index3Valid) {
196                    *ptr = index1; ++ptr;
197                    *ptr = index2; ++ptr;
198                    *ptr = index3; ++ptr;
199                    ++ic;
200                }
201                if (index1Valid && index3Valid && index4Valid) {
202                    *ptr = index1; ++ptr;
203                    *ptr = index3; ++ptr;
204                    *ptr = index4; ++ptr;
205                    ++ic;
206                }
207#else
208                if (index1Valid && index2Valid && index3Valid && index4Valid) {
209                    *ptr = index1; ++ptr;
210                    *ptr = index2; ++ptr;
211                    *ptr = index3; ++ptr;
212                    *ptr = index4; ++ptr;
213                    ++ic;
214                }
215#endif
216            }
217        }
218    } else {
219        for (i = 0; i < boundaryHeight; ++i) {
220            for (j = 0; j < boundaryWidth; ++j) {
221                *ptr = i * xCount + j; ++ptr;
222                *ptr = (i + 1) * xCount + j; ++ptr;
223                *ptr = (i + 1) * xCount + j + 1; ++ptr;
224                *ptr = i * xCount + j; ++ptr;
225                *ptr = (i + 1) * xCount + j + 1; ++ptr;
226                *ptr = i * xCount + j + 1; ++ptr;
227            }
228        }
229    }
230}
231
232void
233HeightMap::reset()
234{
235    if (_vertexBufferObjectID) {
236        glDeleteBuffers(1, &_vertexBufferObjectID);
237        _vertexBufferObjectID = 0;
238    }
239    if (_textureBufferObjectID) {
240        glDeleteBuffers(1, &_textureBufferObjectID);
241        _textureBufferObjectID = 0;
242    }
243    if (_contour != NULL) {
244        delete _contour;
245        _contour = NULL;
246    }
247}
248
249void
250HeightMap::setHeight(int xCount, int yCount, Vector3* heights)
251{
252    _vertexCount = xCount * yCount;
253    reset();
254   
255    heights_ = (float *)heights;
256    float min, max;
257    min = heights[0].y, max = heights[0].y;
258
259    int count = xCount * yCount;
260    for (int i = 0; i < count; ++i) {
261        if (min > heights[i].y) {
262            min = heights[i].y;
263        }
264        if (max < heights[i].y) {
265            max = heights[i].y;
266        }
267    }
268
269    _scale.x = 1.0f;
270    _scale.z = max - min;
271    _scale.y = 1.0f;
272
273    xAxis.SetRange(0.0, 1.0);
274    yAxis.SetRange(0.0, 1.0);
275    zAxis.SetRange(0.0, 1.0);
276    wAxis.SetRange(min, max);
277    update_pending = true;
278   
279    _centerPoint.set(_scale.x * 0.5, _scale.z * 0.5 + min, _scale.y * 0.5);
280
281    Vector3* texcoord = new Vector3[count];
282    for (int i = 0; i < count; ++i) {
283        texcoord[i].set(0, 0, heights[i].y);
284    }
285   
286    glGenBuffers(1, &_vertexBufferObjectID);
287    glBindBuffer(GL_ARRAY_BUFFER, _vertexBufferObjectID);
288    glBufferData(GL_ARRAY_BUFFER, _vertexCount * sizeof( Vector3 ), heights,
289        GL_STATIC_DRAW);
290    glGenBuffers(1, &_textureBufferObjectID);
291    glBindBuffer(GL_ARRAY_BUFFER, _textureBufferObjectID);
292    glBufferData(GL_ARRAY_BUFFER, _vertexCount * sizeof(float) * 3, texcoord,
293        GL_STATIC_DRAW);
294    glBindBuffer(GL_ARRAY_BUFFER, 0);
295   
296    delete [] texcoord;
297   
298   
299    ContourLineFilter lineFilter;
300    _contour = lineFilter.create(0.0f, 1.0f, 10, heights, xCount, yCount);
301
302#if TOPCONTOUR
303    ContourLineFilter topLineFilter;
304    topLineFilter.setHeightTop(true);
305    _topContour = topLineFilter.create(0.0f, 1.0f, 10, heights, xCount, yCount);
306#endif
307
308    //if (heightMap)
309    //{
310    //  VertexBuffer* vertexBuffer = new VertexBuffer(VertexBuffer::POSITION3, xCount * yCount, sizeof(Vector3) * xCount * yCount, heightMap, false);
311    this->createIndexBuffer(xCount, yCount, 0);
312    //}
313    //else
314    //{
315    //printf("ERROR - HeightMap::setHeight\n");
316    //}
317}
318
319void
320HeightMap::setHeight(float xMin, float yMin, float xMax, float yMax,
321                     int xNum, int yNum, float* heights)
322{
323    _vertexCount = xNum * yNum;
324    xNum_ = xNum, yNum_ = yNum;
325    heights_ = heights;
326    reset();
327   
328    // Get the min/max of the heights. */
329    float min, max;
330    min = max = heights[0];
331    for (int i = 0; i < _vertexCount; ++i) {
332        if (min > heights[i]) {
333            min = heights[i];
334        } else if (max < heights[i]) {
335            max = heights[i];
336        }
337    }
338#ifdef notdef
339    if (retainScale_) {
340        // Check the units of each axis.  If they are the same, we want to
341        // retain the surface's aspect ratio when transforming coordinates to
342        // the grid. Use the range of the longest axis when the units are the
343        // same. 
344        if (xAxis.units() != NULL) && (xAxis.units() == yAxis.units()) {
345        }
346        if (yAxis.units() != NULL) && (yAxis.units() == zAxis.units()) {
347        }
348    }
349#endif
350
351    wAxis.SetRange(min, max);
352    yAxis.SetRange(min, max);
353    xAxis.SetRange(xMin, xMax);
354    zAxis.SetRange(yMin, yMax);
355   
356   
357    min = 0.0, max = 1.0;
358    xMin = yMin = min = 0.0;
359    xMax = yMax = max = 1.0;
360    // Save the scales.
361    _scale.x = _scale.y = _scale.z = 1.0;
362
363    update_pending = true;
364
365    _centerPoint.set(0.5, 0.5, 0.5);
366   
367#ifndef notdef
368    Vector3* texcoord = new Vector3[_vertexCount];
369    for (int i = 0; i < _vertexCount; ++i) {
370        texcoord[i].set(0, 0, heights[i]);
371    }
372   
373    Vector3* heightMap = createHeightVertices(xMin, yMin, xMax, yMax, xNum, yNum, heights);
374   
375    glGenBuffers(1, &_vertexBufferObjectID);
376    glBindBuffer(GL_ARRAY_BUFFER, _vertexBufferObjectID);
377    glBufferData(GL_ARRAY_BUFFER, _vertexCount * sizeof( Vector3 ), heightMap,
378        GL_STATIC_DRAW);
379    glGenBuffers(1, &_textureBufferObjectID);
380    glBindBuffer(GL_ARRAY_BUFFER, _textureBufferObjectID);
381    glBufferData(GL_ARRAY_BUFFER, _vertexCount * sizeof(float) * 3, texcoord,
382        GL_STATIC_DRAW);
383    glBindBuffer(GL_ARRAY_BUFFER, 0);
384   
385    delete [] texcoord;
386   
387   
388    ContourLineFilter lineFilter;
389    //lineFilter.setColorMap(_colorMap);
390    _contour = lineFilter.create(0.0f, 1.0f, 10, heightMap, xNum, yNum);
391   
392#if TOPCONTOUR
393    ContourLineFilter topLineFilter;
394    topLineFilter.setHeightTop(true);
395    _topContour = topLineFilter.create(0.0f, 1.0f, 10, heightMap, xNum, yNum);
396#endif
397
398
399    //if (heightMap)
400    //{
401    //  VertexBuffer* vertexBuffer = new VertexBuffer(VertexBuffer::POSITION3, xNum * yNum,
402    // sizeof(Vector3) * xNum * yNum, heightMap, false);
403    if (_indexBuffer != NULL) {
404        free(_indexBuffer);
405        _indexBuffer = NULL;
406    }
407    this->createIndexBuffer(xNum, yNum, heights);
408    //}
409    //else
410    //{
411    //printf("ERROR - HeightMap::setHeight\n");
412    //}
413#endif
414}
415
416Vector3*
417HeightMap::createHeightVertices(float xMin, float yMin, float xMax,
418                                float yMax, int xNum, int yNum, float* height)
419{
420    Vector3* vertices = (Vector3*) malloc(sizeof(Vector3) * xNum * yNum);
421
422    Vector3* dstDataPtr = vertices;
423    float* srcDataPtr = height;
424   
425    for (int y = 0; y < yNum; ++y) {
426        float yCoord;
427
428        yCoord = yMin + ((yMax - yMin) * y) / (yNum - 1);
429        for (int x = 0; x < xNum; ++x) {
430            float xCoord;
431
432            xCoord = xMin + ((xMax - xMin) * x) / (xNum - 1);
433            dstDataPtr->set(xCoord, *srcDataPtr, yCoord);
434
435            ++dstDataPtr;
436            ++srcDataPtr;
437        }
438    }
439    return vertices;
440}
441
442void HeightMap::setColorMap(TransferFunction* colorMap)
443{
444    //if (colorMap) colorMap->addRef();
445    //if (_colorMap) _colorMap->unrefDelete();
446    _colorMap = colorMap;
447}
448
449// Maps the data coordinates of the surface into the grid's axes.
450void
451HeightMap::MapToGrid(Grid *gridPtr)
452{
453    int count = xNum_ * yNum_;
454
455    reset();
456
457    // The range of the grid's y-axis 0..1 represents the distance between the
458    // smallest and largest major ticks for all surfaces plotted.  Translate
459    // this surface's y-values (heights) into the grid's axis coordinates.
460
461    float yScale = 1.0 / (gridPtr->yAxis.max() - gridPtr->yAxis.min());
462    float *p, *q, *pend;
463    float *normHeights = new float[count];
464    for (p = heights_, pend = p + count, q = normHeights; p < pend; p++, q++) {
465        *q = (*p - gridPtr->yAxis.min()) * yScale;
466    }
467    Vector3 *t, *texcoord;
468    texcoord = new Vector3[count];
469    for (t = texcoord, p = normHeights, pend = p + count; p < pend; p++, t++) {
470        t->set(0, 0, *p);
471    }
472
473    // Normalize the mesh coordinates (x and z min/max) the range of the major
474    // ticks for the x and z grid axes as well.
475
476    float xScale, zScale;
477    float xMin, xMax, zMin, zMax;
478
479    xScale = 1.0 / (gridPtr->xAxis.max() - gridPtr->xAxis.min());
480    xMin = (xAxis.min() - gridPtr->xAxis.min()) * xScale;
481    xMax = (xAxis.max() - gridPtr->xAxis.min()) * xScale;
482    zScale = 1.0 / (gridPtr->zAxis.max() - gridPtr->zAxis.min());
483    zMin = (zAxis.min() - gridPtr->zAxis.min()) * zScale;
484    zMax = (zAxis.max() - gridPtr->zAxis.min()) * zScale;
485
486    Vector3* vertices;
487    vertices = createHeightVertices(xMin, zMin, xMax, zMax, xNum_, yNum_,
488        normHeights);
489   
490    glGenBuffers(1, &_vertexBufferObjectID);
491    glBindBuffer(GL_ARRAY_BUFFER, _vertexBufferObjectID);
492    glBufferData(GL_ARRAY_BUFFER, _vertexCount * sizeof(Vector3), vertices,
493        GL_STATIC_DRAW);
494    glGenBuffers(1, &_textureBufferObjectID);
495    glBindBuffer(GL_ARRAY_BUFFER, _textureBufferObjectID);
496    glBufferData(GL_ARRAY_BUFFER, _vertexCount * sizeof(float) * 3, texcoord,
497        GL_STATIC_DRAW);
498    glBindBuffer(GL_ARRAY_BUFFER, 0);
499    delete [] texcoord;
500
501    ContourLineFilter lineFilter;
502    //lineFilter.setColorMap(_colorMap);
503    _contour = lineFilter.create(0.0f, 1.0f, 10, vertices, xNum_, yNum_);
504   
505#if TOPCONTOUR
506    ContourLineFilter topLineFilter;
507    topLineFilter.setHeightTop(true);
508    _topContour = topLineFilter.create(0.0f, 1.0f, 10, vertices, xNum_, yNum_);
509#endif
510    this->createIndexBuffer(xNum_, yNum_, normHeights);
511    delete [] normHeights;
512}
513
Note: See TracBrowser for help on using the repository browser.