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

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

fixes for xyresult/heightmapviewer

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