temp commit
[SARndbox.git] / ElevationColorMap.cpp
blob7a78b2983b13c9497055bbe8a85a00d5e26ef4a6
1 /***********************************************************************
2 ElevationColorMap - Class to represent elevation color maps for
3 topographic maps.
4 Copyright (c) 2014-2016 Oliver Kreylos
6 This file is part of the Augmented Reality Sandbox (SARndbox).
8 The Augmented Reality Sandbox is free software; you can redistribute it
9 and/or modify it under the terms of the GNU General Public License as
10 published by the Free Software Foundation; either version 2 of the
11 License, or (at your option) any later version.
13 The Augmented Reality Sandbox is distributed in the hope that it will be
14 useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 General Public License for more details.
18 You should have received a copy of the GNU General Public License along
19 with the Augmented Reality Sandbox; if not, write to the Free Software
20 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 ***********************************************************************/
23 #include "ElevationColorMap.h"
25 #include <string>
26 #include <Misc/ThrowStdErr.h>
27 #include <Misc/FileNameExtensions.h>
28 #include <IO/ValueSource.h>
29 #include <GL/gl.h>
30 #include <GL/GLContextData.h>
31 #include <GL/Extensions/GLARBShaderObjects.h>
32 #include <Vrui/OpenFile.h>
34 #include "Types.h"
35 #include "DepthImageRenderer.h"
37 #include "Config.h"
39 // DEBUGGING
40 #include <iostream>
42 /**********************************
43 Methods of class ElevationColorMap:
44 **********************************/
46 ElevationColorMap::ElevationColorMap(const char* heightMapName) {
47 /* Load the given height map: */
48 load(heightMapName);
51 void ElevationColorMap::initContext(GLContextData& contextData) const {
52 /* Initialize required OpenGL extensions: */
53 GLARBShaderObjects::initExtension();
55 /* Create the data item and associate it with this object: */
56 DataItem* dataItem = new DataItem;
57 contextData.addDataItem(this, dataItem);
60 void ElevationColorMap::load(const char* heightMapName) {
61 /* Open the height map file: */
62 std::string fullHeightMapName;
63 if(heightMapName[0] == '/') {
64 /* Use the absolute file name directly: */
65 fullHeightMapName = heightMapName;
66 } else {
67 /* Assemble a file name relative to the configuration file directory: */
68 fullHeightMapName = CONFIG_CONFIGDIR;
69 fullHeightMapName.push_back('/');
70 fullHeightMapName.append(heightMapName);
73 /* Open the height map file: */
74 IO::ValueSource heightMapSource(Vrui::openFile(fullHeightMapName.c_str()));
76 /* Load the height color map: */
77 std::vector<Color> heightMapColors;
78 std::vector<GLdouble> heightMapKeys;
79 if(Misc::hasCaseExtension(heightMapName, ".cpt")) {
80 heightMapSource.setPunctuation("\n");
81 heightMapSource.skipWs();
82 int line = 1;
83 while(!heightMapSource.eof()) {
84 /* Read the next color map key value: */
85 heightMapKeys.push_back(GLdouble(heightMapSource.readNumber()));
87 /* Read the next color map color value: */
88 Color color;
89 for(int i = 0; i < 3; ++i)
90 color[i] = Color::Scalar(heightMapSource.readNumber() / 255.0);
91 color[3] = Color::Scalar(1);
92 heightMapColors.push_back(color);
94 if(!heightMapSource.isLiteral('\n'))
95 Misc::throwStdErr("ElevationColorMap: Color map format error in line %d of file %s", line,
96 fullHeightMapName.c_str());
97 ++line;
99 } else {
100 heightMapSource.setPunctuation(",\n");
101 heightMapSource.skipWs();
102 int line = 1;
103 while(!heightMapSource.eof()) {
104 /* Read the next color map key value: */
105 heightMapKeys.push_back(GLdouble(heightMapSource.readNumber()));
106 if(!heightMapSource.isLiteral(','))
107 Misc::throwStdErr("ElevationColorMap: Color map format error in line %d of file %s", line,
108 fullHeightMapName.c_str());
110 /* Read the next color map color value: */
111 Color color;
112 for(int i = 0; i < 3; ++i)
113 color[i] = Color::Scalar(heightMapSource.readNumber());
114 color[3] = Color::Scalar(1);
115 heightMapColors.push_back(color);
117 if(!heightMapSource.isLiteral('\n'))
118 Misc::throwStdErr("ElevationColorMap: Color map format error in line %d of file %s", line,
119 fullHeightMapName.c_str());
120 ++line;
124 /* Create the color map: */
125 setColors(heightMapKeys.size(), &heightMapColors[0], &heightMapKeys[0], 256);
127 /* Invalidate the color map texture object: */
128 ++textureVersion;
131 void ElevationColorMap::calcTexturePlane(const Plane& basePlane) {
132 /* Scale and offset the camera-space base plane equation: */
133 const Plane::Vector& bpn = basePlane.getNormal();
134 Scalar bpo = basePlane.getOffset();
135 Scalar hms = Scalar(getNumEntries() - 1) / ((getScalarRangeMax() - getScalarRangeMin()) * Scalar(
136 getNumEntries()));
137 Scalar hmo = Scalar(0.5) / Scalar(getNumEntries()) - hms * getScalarRangeMin();
138 for(int i = 0; i < 3; ++i)
139 texturePlaneEq[i] = GLfloat(bpn[i] * hms);
140 texturePlaneEq[3] = GLfloat(-bpo * hms + hmo);
143 void ElevationColorMap::calcTexturePlane(const DepthImageRenderer* depthImageRenderer) {
144 /* Calculate texture plane based on the given depth image renderer's base plane: */
145 calcTexturePlane(depthImageRenderer->getBasePlane());
148 void ElevationColorMap::bindTexture(GLContextData& contextData) const {
149 /* Retrieve the data item: */
150 DataItem* dataItem = contextData.retrieveDataItem<DataItem>(this);
152 /* Bind the texture object: */
153 glBindTexture(GL_TEXTURE_1D, dataItem->textureObjectId);
155 /* Check if the color map texture is outdated: */
156 if(dataItem->textureObjectVersion != textureVersion) {
157 /* Upload the color map entries as a 1D texture: */
158 glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
159 glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
160 glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
161 glTexImage1D(GL_TEXTURE_1D, 0, GL_RGB8, getNumEntries(), 0, GL_RGBA, GL_FLOAT, getColors());
163 dataItem->textureObjectVersion = textureVersion;
167 void ElevationColorMap::uploadTexturePlane(GLint location) const {
168 /* Upload the texture mapping plane equation: */
169 glUniformARB<4>(location, 1, texturePlaneEq);
170 // std::cerr << "camera base plane: (" << texturePlaneEq[0] << ", " << texturePlaneEq[1] << ", " << texturePlaneEq[2] << ") = " << texturePlaneEq[3] << std::endl;