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

Last change on this file since 1000 was 1000, checked in by vrinside, 16 years ago
File size: 12.1 KB
Line 
1 
2#include <GL/glew.h>
3#include <GL/gl.h>
4#include "HeightMap.h"
5#include "ContourLineFilter.h"
6#include "TypeDefs.h"
7#include <Texture1D.h>
8#include <stdlib.h>
9#include <memory.h>
10#include <R2/R2FilePath.h>
11#include "RpField1D.h"
12#include <sys/time.h>
13#include <sys/types.h>
14#include <unistd.h>
15#include <fcntl.h>
16#include <RenderContext.h>
17
18bool HeightMap::update_pending = false;
19double HeightMap::valueMin = 0.0;
20double HeightMap::valueMax = 1.0;
21
22#define TOPCONTOUR
23HeightMap::HeightMap() :
24    _vertexBufferObjectID(0),
25    _textureBufferObjectID(0),
26    _vertexCount(0),
27    _contour(0),
28    _topContour(0),
29    _colorMap(0),
30    _indexBuffer(0),
31    _indexCount(0),
32    _contourColor(1.0f, 0.0f, 0.0f),
33    _contourVisible(false),
34    _topContourVisible(true),
35    _visible(false),
36    _scale(1.0f, 1.0f, 1.0f),
37    _centerPoint(0.0f, 0.0f, 0.0f)
38{
39    _shader = new NvShader();
40
41    R2string path = R2FilePath::getInstance()->getPath("heightcolor.cg");
42    if (path.getLength() == 0) {
43        printf("ERROR : file not found %s\n", "heightcolor.cg");
44    }
45    _shader->loadFragmentProgram(path, "main");
46    _tf = _shader->getNamedParameterFromFP("tf");
47}
48
49HeightMap::~HeightMap()
50{
51    reset();
52
53    if (_shader) {
54        delete _shader;
55    }
56
57    // TMP
58    //if (_colorMap) delete _colorMap;
59}
60
61void HeightMap::render(graphics::RenderContext* renderContext)
62{
63    if (renderContext->getCullMode() == graphics::RenderContext::NO_CULL) {
64        glDisable(GL_CULL_FACE);
65    } else {
66        glEnable(GL_CULL_FACE);
67        glCullFace((GLuint) renderContext->getCullMode());
68    }
69
70    glPolygonMode(GL_FRONT_AND_BACK, (GLuint) renderContext->getPolygonMode());
71    glShadeModel((GLuint) renderContext->getShadingModel());
72
73    glPushMatrix();
74
75    if (_scale.x != 0.0) {
76        glScalef(1 / _scale.x, 1 / _scale.x , 1 / _scale.x);
77    }
78
79    glTranslatef(-_centerPoint.x, -_centerPoint.y, -_centerPoint.z);
80
81    if (_contour) {
82        glDepthRange (0.001, 1.0);
83    }
84       
85    glEnable(GL_DEPTH_TEST);
86
87    if (_vertexBufferObjectID) {
88        glColor3f(1.0f, 1.0f, 1.0f);
89        glShadeModel(GL_SMOOTH);
90        glEnable(GL_BLEND);
91        glEnableClientState(GL_VERTEX_ARRAY);
92        glDisableClientState(GL_COLOR_ARRAY);
93        glDisableClientState(GL_INDEX_ARRAY);
94        glDisableClientState(GL_NORMAL_ARRAY);
95       
96        if (_colorMap) {
97            // PUT vertex program here
98            //
99            //
100           
101            cgGLBindProgram(_shader->getFP());
102            cgGLEnableProfile(CG_PROFILE_FP30);
103           
104            cgGLSetTextureParameter(_tf, _colorMap->id);
105            cgGLEnableTextureParameter(_tf);
106           
107            glEnable(GL_TEXTURE_1D);
108            _colorMap->getTexture()->activate();
109           
110            glEnableClientState(GL_TEXTURE_COORD_ARRAY);
111        }
112       
113        glBindBuffer(GL_ARRAY_BUFFER, _vertexBufferObjectID);
114        glVertexPointer(3, GL_FLOAT, 12, 0);
115       
116        glBindBuffer(GL_ARRAY_BUFFER, _textureBufferObjectID);
117        ::glTexCoordPointer(3, GL_FLOAT, 12, 0);
118       
119#define _TRIANGLES_
120#ifdef _TRIANGLES_
121        glDrawElements(GL_TRIANGLES, _indexCount, GL_UNSIGNED_INT,
122                       _indexBuffer);
123#else                   
124        glDrawElements(GL_QUADS, _indexCount, GL_UNSIGNED_INT,
125                       _indexBuffer);
126#endif
127
128        glBindBuffer(GL_ARRAY_BUFFER, 0);
129       
130        glDisableClientState(GL_VERTEX_ARRAY);
131        if (_colorMap) {
132            _colorMap->getTexture()->deactivate();
133            glDisableClientState(GL_TEXTURE_COORD_ARRAY);
134           
135            cgGLDisableProfile(CG_PROFILE_FP30);
136        }
137    }
138   
139    glShadeModel(GL_FLAT);
140    glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
141   
142    if (_contour) {
143        if (_contourVisible) {
144            glDisable(GL_BLEND);
145            glDisable(GL_TEXTURE_2D);
146            glColor4f(_contourColor.x, _contourColor.y, _contourColor.z, 1.0f);
147            glDepthRange (0.0, 0.999);
148            _contour->render();
149            glDepthRange (0.0, 1.0);
150        }
151
152#ifdef TOPCONTOUR
153        if (_topContourVisible) {
154            glDisable(GL_BLEND);
155            glDisable(GL_TEXTURE_2D);
156            glColor4f(_contourColor.x, _contourColor.y, _contourColor.z, 1.0f);
157            //glDepthRange (0.0, 0.999);
158            _topContour->render();
159            //glDepthRange (0.0, 1.0);
160        }
161#endif
162    }
163    glPopMatrix();
164}
165
166void
167HeightMap::createIndexBuffer(int xCount, int zCount, int*& indexBuffer,
168                             int& indexCount, float* heights)
169{
170    indexCount = (xCount - 1) * (zCount - 1) * 6;
171
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    }
239
240    if (_vertexBufferObjectID) {
241        glDeleteBuffers(1, &_vertexBufferObjectID);
242    }
243
244    //if (_contour) _contour->unrefDelete();
245    if (_contour) {
246        delete _contour;
247    }
248    if (_indexBuffer) {
249        free(_indexBuffer);
250    }
251}
252
253void
254HeightMap::setHeight(int xCount, int yCount, Vector3* heights)
255{
256    _vertexCount = xCount * yCount;
257    reset();
258   
259    float min, max;
260    min = heights[0].y, max = heights[0].y;
261
262    int count = xCount * yCount;
263    for (int i = 0; i < count; ++i) {
264        if (min > heights[i].y) {
265            min = heights[i].y;
266        }
267        if (max < heights[i].y) {
268            max = heights[i].y;
269        }
270    }
271
272    _scale.x = 1.0f;
273    _scale.z = max - min;
274    _scale.y = 1.0f;
275
276    xAxis.SetRange(0.0, 1.0);
277    yAxis.SetRange(0.0, 1.0);
278    zAxis.SetRange(0.0, 1.0);
279    wAxis.SetRange(min, max);
280    update_pending = true;
281   
282    _centerPoint.set(_scale.x * 0.5, _scale.z * 0.5 + min, _scale.y * 0.5);
283
284    Vector3* texcoord = new Vector3[count];
285    for (int i = 0; i < count; ++i) {
286        texcoord[i].set(0, 0, heights[i].y);
287    }
288   
289    glGenBuffers(1, &_vertexBufferObjectID);
290    glBindBuffer(GL_ARRAY_BUFFER, _vertexBufferObjectID);
291    glBufferData(GL_ARRAY_BUFFER, _vertexCount * sizeof( Vector3 ), heights,
292        GL_STATIC_DRAW);
293    glGenBuffers(1, &_textureBufferObjectID);
294    glBindBuffer(GL_ARRAY_BUFFER, _textureBufferObjectID);
295    glBufferData(GL_ARRAY_BUFFER, _vertexCount * sizeof(float) * 3, texcoord,
296        GL_STATIC_DRAW);
297    glBindBuffer(GL_ARRAY_BUFFER, 0);
298   
299    delete [] texcoord;
300   
301   
302    ContourLineFilter lineFilter;
303    _contour = lineFilter.create(0.0f, 1.0f, 10, heights, xCount, yCount);
304
305#ifdef TOPCONTOUR
306    ContourLineFilter topLineFilter;
307    topLineFilter.setHeightTop(true);
308    _topContour = topLineFilter.create(0.0f, 1.0f, 10, heights, xCount, yCount);
309#endif
310
311    //if (heightMap)
312    //{
313    //  VertexBuffer* vertexBuffer = new VertexBuffer(VertexBuffer::POSITION3, xCount * yCount, sizeof(Vector3) * xCount * yCount, heightMap, false);
314    if (_indexBuffer) {
315        free(_indexBuffer);
316    }
317
318    this->createIndexBuffer(xCount, yCount, _indexBuffer, _indexCount, 0);
319    //}
320    //else
321    //{
322    //printf("ERROR - HeightMap::setHeight\n");
323    //}
324}
325
326void
327HeightMap::setHeight(float startX, float startY, float endX, float endY,
328                     int xCount, int yCount, float* heights)
329{
330    _vertexCount = xCount * yCount;
331   
332    reset();
333
334    float min, max;
335    min = heights[0], max = heights[0];
336    int count = xCount * yCount;
337    for (int i = 0; i < count; ++i) {
338        if (min > heights[i]) {
339            min = heights[i];
340        } else if (max < heights[i]) {
341            max = heights[i];
342        }
343    }
344    _scale.x = endX - startX;
345    _scale.y = max - min;
346    _scale.z = endY - startY;
347
348    wAxis.SetRange(min, max);
349    xAxis.SetRange(startX, endX);
350    yAxis.SetRange(min, max);
351    zAxis.SetRange(startY, endY);
352    update_pending = true;
353
354    _centerPoint.set(_scale.x * 0.5 + startX, _scale.y * 0.5 + min,
355        _scale.z * 0.5 + startY);
356   
357    Vector3* texcoord = new Vector3[count];
358    for (int i = 0; i < count; ++i) {
359        texcoord[i].set(0, 0, heights[i]);
360    }
361   
362    Vector3* heightMap = createHeightVertices(startX, startY, endX, endY, xCount, yCount, heights);
363   
364    glGenBuffers(1, &_vertexBufferObjectID);
365    glBindBuffer(GL_ARRAY_BUFFER, _vertexBufferObjectID);
366    glBufferData(GL_ARRAY_BUFFER, _vertexCount * sizeof( Vector3 ), heightMap,
367        GL_STATIC_DRAW);
368    glGenBuffers(1, &_textureBufferObjectID);
369    glBindBuffer(GL_ARRAY_BUFFER, _textureBufferObjectID);
370    glBufferData(GL_ARRAY_BUFFER, _vertexCount * sizeof(float) * 3, texcoord,
371        GL_STATIC_DRAW);
372    glBindBuffer(GL_ARRAY_BUFFER, 0);
373   
374    delete [] texcoord;
375   
376   
377    ContourLineFilter lineFilter;
378    //lineFilter.setColorMap(_colorMap);
379    _contour = lineFilter.create(0.0f, 1.0f, 10, heightMap, xCount, yCount);
380   
381#ifdef TOPCONTOUR
382    ContourLineFilter topLineFilter;
383    topLineFilter.setHeightTop(true);
384    _topContour = topLineFilter.create(0.0f, 1.0f, 10, heightMap, xCount, yCount);
385#endif
386
387
388    //if (heightMap)
389    //{
390    //  VertexBuffer* vertexBuffer = new VertexBuffer(VertexBuffer::POSITION3, xCount * yCount,
391    // sizeof(Vector3) * xCount * yCount, heightMap, false);
392    if (_indexBuffer) {
393        free(_indexBuffer);
394    }
395    this->createIndexBuffer(xCount, yCount, _indexBuffer, _indexCount, heights);
396    //}
397    //else
398    //{
399    //printf("ERROR - HeightMap::setHeight\n");
400    //}
401}
402
403Vector3* HeightMap::createHeightVertices(float startX, float startY, float endX, float endY, int xCount, int yCount, float* height)
404{
405    Vector3* vertices = (Vector3*) malloc(sizeof(Vector3) * xCount * yCount);
406
407    Vector3* dstDataPtr = vertices;
408    float* srcDataPtr = height;
409   
410    for (int y = 0; y < yCount; ++y) {
411        float yCoord;
412
413        yCoord = startY + ((endY - startY) * y) / (yCount - 1);
414        for (int x = 0; x < xCount; ++x) {
415            float xCoord;
416
417            xCoord = startX + ((endX - startX) * x) / (xCount - 1);
418            dstDataPtr->set(xCoord, *srcDataPtr, yCoord);
419
420            ++dstDataPtr;
421            ++srcDataPtr;
422        }
423    }
424    return vertices;
425}
426
427void HeightMap::setColorMap(TransferFunction* colorMap)
428{
429    //if (colorMap) colorMap->addRef();
430    //if (_colorMap) _colorMap->unrefDelete();
431    _colorMap = colorMap;
432}
433
Note: See TracBrowser for help on using the repository browser.