source: trunk/vizservers/nanovis/HeightMap.cpp @ 823

Last change on this file since 823 was 820, checked in by vrinside, 16 years ago

NaN values in a data set is taken into account.

File size: 8.9 KB
Line 
1#include <GL/glew.h>
2#include <GL/gl.h>
3#include "HeightMap.h"
4#include "ContourLineFilter.h"
5#include "TypeDefs.h"
6#include <Texture1D.h>
7#include <stdlib.h>
8#include <memory.h>
9#include <R2/R2FilePath.h>
10#include "RpField1D.h"
11#include <sys/time.h>
12#include <sys/types.h>
13#include <unistd.h>
14#include <fcntl.h>
15
16HeightMap::HeightMap()
17: _contour(0), _colorMap(0), _indexBuffer(0), _vertexBufferObjectID(0), _vertexCount(0), _textureBufferObjectID(0),
18  _contourVisible(true), _scale(1.0f, 1.0f, 1.0f), _contourColor(1.0f, 0.0f, 0.0f)
19{
20        _shader = new NvShader();
21        R2string path = R2FilePath::getInstance()->getPath("heightcolor.cg");
22        if (path.getLength() == 0)
23        {
24            printf("ERROR : file not found\n", "heightcolor.cg");
25        }
26
27        _shader->loadFragmentProgram(path, "main");
28        _tf = _shader->getNamedParameterFromFP("tf");
29}
30
31HeightMap::~HeightMap()
32{
33        reset();
34
35    if (_shader) delete _shader;
36
37    // TMP
38        //if (_colorMap) delete _colorMap;
39}
40
41void HeightMap::render()
42{
43    glPushMatrix();
44    glScalef(_scale.x, _scale.y, _scale.z);
45    glTranslatef(-0.5f, -0.5f, -0.5f);
46        if (_contour)
47        {
48                glDepthRange (0.001, 1.0);
49        }
50       
51        glEnable(GL_DEPTH_TEST);
52
53        if (_vertexBufferObjectID)
54        {
55                glColor3f(1.0f, 1.0f, 1.0f);
56                glShadeModel(GL_SMOOTH);
57                glEnable(GL_BLEND);
58                glEnableClientState(GL_VERTEX_ARRAY);
59                glDisableClientState(GL_COLOR_ARRAY);
60                glDisableClientState(GL_INDEX_ARRAY);
61                glDisableClientState(GL_NORMAL_ARRAY);
62
63                if (_colorMap)
64                {
65            cgGLBindProgram(_shader->getFP());
66            cgGLEnableProfile(CG_PROFILE_FP30);
67
68                        cgGLSetTextureParameter(_tf, _colorMap->id);
69                        cgGLEnableTextureParameter(_tf);
70
71                        glEnable(GL_TEXTURE_1D);
72                        _colorMap->getTexture()->activate();
73                       
74                        glEnableClientState(GL_TEXTURE_COORD_ARRAY);
75                }
76
77                glBindBuffer(GL_ARRAY_BUFFER, _vertexBufferObjectID);
78                glVertexPointer(3, GL_FLOAT, 12, 0);
79
80                glBindBuffer(GL_ARRAY_BUFFER, _textureBufferObjectID);
81                ::glTexCoordPointer(3, GL_FLOAT, 12, 0);
82
83                glDrawElements(GL_TRIANGLES, _indexCount, GL_UNSIGNED_INT, _indexBuffer);
84                glBindBuffer(GL_ARRAY_BUFFER, 0);
85
86                glDisableClientState(GL_VERTEX_ARRAY);
87                if (_colorMap)
88                {
89                        _colorMap->getTexture()->deactivate();
90                        glDisableClientState(GL_TEXTURE_COORD_ARRAY);
91                       
92            cgGLDisableProfile(CG_PROFILE_FP30);
93                }
94        }
95
96        glShadeModel(GL_FLAT);
97
98        if (_contour && _contourVisible)
99        {
100        glDisable(GL_BLEND);
101        glDisable(GL_TEXTURE_2D);
102                glColor4f(_contourColor.x, _contourColor.y, _contourColor.z, 1.0f);
103                glDepthRange (0.0, 0.999);
104                _contour->render();
105                glDepthRange (0.0, 1.0);
106        }
107
108    glPopMatrix();
109}
110
111void HeightMap::createIndexBuffer(int xCount, int zCount, int*& indexBuffer, int& indexCount, float* heights)
112{
113        indexCount = (xCount - 1) * (zCount - 1) * 6;
114
115    indexBuffer = new int[indexCount];
116   
117    int i, j;
118    int boundaryWidth = xCount - 1;
119    int boundaryHeight = zCount - 1;
120    int* ptr = indexBuffer;
121    int index1, index2, index3, index4;
122    bool index1Valid, index2Valid, index3Valid, index4Valid;
123    index1Valid = index2Valid = index3Valid = index4Valid = true;
124
125    if (heights)
126    {
127        int ic = 0;
128        for (i = 0; i < boundaryHeight; ++i)
129        {
130            for (j = 0; j < boundaryWidth; ++j)
131            {
132                index1 = i * xCount +j;
133                if (isnan(heights[index1])) index1Valid = false;
134                index2 = (i + 1) * xCount + j;
135                if (isnan(heights[index2])) index2Valid = false;
136                index3 = (i + 1) * xCount + j + 1;
137                if (isnan(heights[index3])) index3Valid = false;
138                index4 = i * xCount + j + 1;
139                if (isnan(heights[index4])) index4Valid = false;
140
141       
142           
143                if (index1Valid && index2Valid && index3Valid)
144                {
145                    *ptr = index1; ++ptr;
146                    *ptr = index2; ++ptr;
147                    *ptr = index3; ++ptr;
148                    ++ic;
149                }
150                if (index1Valid && index3Valid && index4Valid)
151                {
152                    *ptr = index1; ++ptr;
153                    *ptr = index3; ++ptr;
154                    *ptr = index4; ++ptr;
155                    ++ic;
156                }
157            }
158        }
159    }
160    else
161    {
162        for (i = 0; i < boundaryHeight; ++i)
163        {
164            for (j = 0; j < boundaryWidth; ++j)
165            {
166                *ptr = i * xCount + j; ++ptr;
167                *ptr = (i + 1) * xCount + j; ++ptr;
168                *ptr = (i + 1) * xCount + j + 1; ++ptr;
169
170                        *ptr = i * xCount + j; ++ptr;
171                            *ptr = (i + 1) * xCount + j + 1; ++ptr;
172                *ptr = i * xCount + j + 1; ++ptr;
173            }
174        }
175    }
176
177}
178
179void HeightMap::reset()
180{
181        if (_vertexBufferObjectID)
182        {
183                glDeleteBuffers(1, &_vertexBufferObjectID);
184        }
185
186        if (_vertexBufferObjectID)
187        {
188                glDeleteBuffers(1, &_vertexBufferObjectID);
189        }
190
191        //if (_contour) _contour->unrefDelete();
192        if (_contour) delete _contour;
193        if (_indexBuffer) free(_indexBuffer);
194}
195
196void HeightMap::setHeight(int xCount, int yCount, Vector3* heights)
197{
198        _vertexCount = xCount * yCount;
199        reset();
200
201        float min = heights[0].y, max = heights[0].y;
202        int count = xCount * yCount;
203        for (int i = 0; i < count; ++i)
204        {
205                if (min > heights[i].y) min = heights[i].y;
206                if (max < heights[i].y) max = heights[i].y;
207        }
208
209
210        Vector3* texcoord = (Vector3*) malloc(count * sizeof(Vector3));
211        for (int i = 0; i < count; ++i)
212        {
213                texcoord[i].set(0, 0, heights[i].y);
214        }
215
216        glGenBuffers(1, &_vertexBufferObjectID);
217    glBindBuffer(GL_ARRAY_BUFFER, _vertexBufferObjectID);
218    glBufferData(GL_ARRAY_BUFFER,
219                  _vertexCount * sizeof( Vector3 ),
220                  heights,
221                  GL_STATIC_DRAW);
222        glGenBuffers(1, &_textureBufferObjectID);
223    glBindBuffer(GL_ARRAY_BUFFER, _textureBufferObjectID);
224    glBufferData(GL_ARRAY_BUFFER,
225                  _vertexCount * sizeof(float) * 3,
226                  texcoord,
227                  GL_STATIC_DRAW);
228        glBindBuffer(GL_ARRAY_BUFFER, 0);
229
230        free(texcoord);
231   
232
233        ContourLineFilter lineFilter;
234        _contour = lineFilter.create(0.0f, 1.0f, 10, heights, xCount, yCount);
235
236        //if (heightMap)
237        //{
238        //      VertexBuffer* vertexBuffer = new VertexBuffer(VertexBuffer::POSITION3, xCount * yCount,
239        //                                                                      sizeof(Vector3) * xCount * yCount, heightMap, false);
240                if (_indexBuffer)
241                {
242                        free(_indexBuffer);
243                }
244
245                this->createIndexBuffer(xCount, yCount, _indexBuffer, _indexCount, 0);
246        //}
247        //else
248        //{
249                //printf("ERROR - HeightMap::setHeight\n");
250        //}
251}
252
253void HeightMap::setHeight(float startX, float startY, float endX, float endY, int xCount, int yCount, float* heights)
254{
255        _vertexCount = xCount * yCount;
256        reset();
257
258        float min = heights[0], max = heights[0];
259        int count = xCount * yCount;
260        for (int i = 0; i < count; ++i)
261        {
262                if (min > heights[i]) min = heights[i];
263                if (max < heights[i]) max = heights[i];
264        }
265
266    //_scale.x = endX - startX;
267    //_scale.y = (endY - startY) / _scale.x;
268    //_scale.z = max / _scale.z;
269
270        Vector3* texcoord = (Vector3*) malloc(count * sizeof(Vector3));
271        for (int i = 0; i < count; ++i)
272        {
273                texcoord[i].set(0, 0, heights[i]);
274        }
275
276        Vector3* heightMap = createHeightVertices(startX, startY, endX, endY, xCount, yCount, heights);
277       
278        glGenBuffers(1, &_vertexBufferObjectID);
279    glBindBuffer(GL_ARRAY_BUFFER, _vertexBufferObjectID);
280    glBufferData(GL_ARRAY_BUFFER,
281                  _vertexCount * sizeof( Vector3 ),
282                  heightMap,
283                  GL_STATIC_DRAW);
284        glGenBuffers(1, &_textureBufferObjectID);
285    glBindBuffer(GL_ARRAY_BUFFER, _textureBufferObjectID);
286    glBufferData(GL_ARRAY_BUFFER,
287                  _vertexCount * sizeof(float) * 3,
288                  texcoord,
289                  GL_STATIC_DRAW);
290        glBindBuffer(GL_ARRAY_BUFFER, 0);
291
292        free(texcoord);
293   
294
295        ContourLineFilter lineFilter;
296        //lineFilter.setColorMap(_colorMap);
297        _contour = lineFilter.create(0.0f, 1.0f, 10, heightMap, xCount, yCount);
298
299        //if (heightMap)
300        //{
301        //      VertexBuffer* vertexBuffer = new VertexBuffer(VertexBuffer::POSITION3, xCount * yCount,
302        //                                                                      sizeof(Vector3) * xCount * yCount, heightMap, false);
303                if (_indexBuffer)
304                {
305                        free(_indexBuffer);
306                }
307
308                this->createIndexBuffer(xCount, yCount, _indexBuffer, _indexCount, heights);
309        //}
310        //else
311        //{
312                //printf("ERROR - HeightMap::setHeight\n");
313        //}
314}
315
316Vector3* HeightMap::createHeightVertices(float startX, float startY, float endX, float endY, int xCount, int yCount, float* height)
317{
318        Vector3* vertices = (Vector3*) malloc(sizeof(Vector3) * xCount * yCount);
319
320        Vector3* dstDataPtr = vertices;
321        float* srcDataPtr = height;
322
323        float xCoord, yCoord;
324        for (int y = 0; y < yCount; ++y)
325        {
326                yCoord = startY + ((endY - startY) * y) / (yCount - 1);
327                for (int x = 0; x < xCount; ++x)
328                {
329                        xCoord = startX + ((endX - startX) * x) / (xCount - 1);
330                        dstDataPtr->set(xCoord, *srcDataPtr, yCoord);
331
332                        ++dstDataPtr;
333                        ++srcDataPtr;
334                }
335        }
336
337        return vertices;
338}
339
340void HeightMap::setColorMap(TransferFunction* colorMap)
341{
342        //if (colorMap) colorMap->addRef();
343        //if (_colorMap) _colorMap->unrefDelete();
344        _colorMap = colorMap;
345}
Note: See TracBrowser for help on using the repository browser.