1 /**************************************************************************\
2 * Copyright (c) Kongsberg Oil & Gas Technologies AS
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are
7 * met:
8 *
9 * Redistributions of source code must retain the above copyright notice,
10 * this list of conditions and the following disclaimer.
11 *
12 * Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 *
16 * Neither the name of the copyright holder nor the names of its
17 * contributors may be used to endorse or promote products derived from
18 * this software without specific prior written permission.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
24 * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
26 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 \**************************************************************************/
32
33 #include <cstdlib>
34 #include <cmath>
35
36 #ifdef HAVE_CONFIG_H
37 #include "config.h"
38 #endif /* HAVE_CONFIG_H */
39
40 #include <Inventor/system/gl.h>
41 #include <Inventor/C/glue/gl.h>
42 #include <Inventor/C/tidbits.h>
43
44 #include "glue/glp.h"
45 #include "tidbitsp.h"
46
47 // *************************************************************************
48
49 #define COIN_DEFAULT_CUBEMAP_SIZE 64
50
51 // *************************************************************************
52
53 /*
54 Based on code from "Simple Bump Mapping Tutorial"
55 http://www.paulsprojects.net
56 */
57
58 /*
59 Convert a [-1,1] vector to a [0,1] vector.
60 */
coin_pack_to_01(float * v)61 static void coin_pack_to_01(float * v)
62 {
63 float len = (float) sqrt(v[0]*v[0] + v[1]*v[1] + v[2]*v[2]);
64
65 /* normalize */
66 if (len != 0.0f) {
67 len = 1.0f / len;
68 v[0] *= len;
69 v[1] *= len;
70 v[2] *= len;
71 }
72 v[0] = 0.5f * v[0] + 0.5f;
73 v[1] = 0.5f * v[1] + 0.5f;
74 v[2] = 0.5f * v[2] + 0.5f;
75 }
76
77 static void
coin_create_normalization_cube_map(const int size)78 coin_create_normalization_cube_map(const int size)
79 {
80 int i, j;
81
82 float offset = 0.5f;
83 float halfsize = size * 0.5f;
84 float tmpvec[3];
85 unsigned char * ptr;
86 unsigned char * data = (unsigned char*) malloc(size*size*3);
87
88 /* positive x */
89 ptr = data;
90 for(j = 0; j < size; j++) {
91 for(i = 0; i < size; i++) {
92 tmpvec[0] = halfsize;
93 tmpvec[1] = -(((float)j)+offset-halfsize);
94 tmpvec[2] = -(((float)i)+offset-halfsize);
95
96 coin_pack_to_01(tmpvec);
97
98 ptr[0]=(unsigned char)(tmpvec[0]*255);
99 ptr[1]=(unsigned char)(tmpvec[1]*255);
100 ptr[2]=(unsigned char)(tmpvec[2]*255);
101
102 ptr += 3;
103 }
104 }
105 glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X,
106 0, 3, size, size, 0, GL_RGB, GL_UNSIGNED_BYTE, data);
107
108 /* negative x */
109 ptr = data;
110
111 for(j = 0; j < size; j++) {
112 for(i = 0; i < size; i++) {
113 tmpvec[0] = -halfsize;
114 tmpvec[1] = -(((float)j)+offset-halfsize);
115 tmpvec[2] = (((float)i)+offset-halfsize);
116
117 coin_pack_to_01(tmpvec);
118
119 ptr[0]=(unsigned char)(tmpvec[0]*255);
120 ptr[1]=(unsigned char)(tmpvec[1]*255);
121 ptr[2]=(unsigned char)(tmpvec[2]*255);
122
123 ptr += 3;
124 }
125 }
126 glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_X,
127 0, 3, size, size, 0, GL_RGB, GL_UNSIGNED_BYTE, data);
128
129 /* positive y */
130 ptr=data;
131
132 for(j = 0; j < size; j++) {
133 for(i = 0; i < size; i++) {
134 tmpvec[0] = ((float)i)+offset-halfsize;
135 tmpvec[1] = halfsize;
136 tmpvec[2] = ((float)j)+offset-halfsize;
137
138 coin_pack_to_01(tmpvec);
139
140 ptr[0]=(unsigned char)(tmpvec[0]*255);
141 ptr[1]=(unsigned char)(tmpvec[1]*255);
142 ptr[2]=(unsigned char)(tmpvec[2]*255);
143
144 ptr += 3;
145 }
146 }
147 glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Y,
148 0, 3, size, size, 0, GL_RGB, GL_UNSIGNED_BYTE, data);
149
150 /* negative y */
151 ptr = data;
152
153 for(j = 0; j < size; j++) {
154 for(i = 0; i < size; i++) {
155 tmpvec[0] = ((float)i)+offset-halfsize;
156 tmpvec[1] = -halfsize;
157 tmpvec[2] = -(((float)j)+offset-halfsize);
158
159 coin_pack_to_01(tmpvec);
160
161 ptr[0]=(unsigned char)(tmpvec[0]*255);
162 ptr[1]=(unsigned char)(tmpvec[1]*255);
163 ptr[2]=(unsigned char)(tmpvec[2]*255);
164
165 ptr += 3;
166 }
167 }
168 glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y,
169 0, 3, size, size, 0, GL_RGB, GL_UNSIGNED_BYTE, data);
170
171 /* positive z */
172 ptr = data;
173
174 for(j = 0; j < size; j++) {
175 for(i = 0; i < size; i++) {
176 tmpvec[0] = ((float)i)+offset-halfsize;
177 tmpvec[1] = -(((float)j)+offset-halfsize);
178 tmpvec[2] = halfsize;
179
180 coin_pack_to_01(tmpvec);
181
182 ptr[0]=(unsigned char)(tmpvec[0]*255);
183 ptr[1]=(unsigned char)(tmpvec[1]*255);
184 ptr[2]=(unsigned char)(tmpvec[2]*255);
185
186 ptr += 3;
187 }
188 }
189 glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Z,
190 0, 3, size, size, 0, GL_RGB, GL_UNSIGNED_BYTE, data);
191
192 /* negative z */
193 ptr=data;
194
195 for(j = 0; j < size; j++) {
196 for(i = 0; i < size; i++) {
197 tmpvec[0] = -(((float)i)+offset-halfsize);
198 tmpvec[1] = -(((float)j)+offset-halfsize);
199 tmpvec[2] = -halfsize;
200
201 coin_pack_to_01(tmpvec);
202
203 ptr[0]=(unsigned char)(tmpvec[0]*255);
204 ptr[1]=(unsigned char)(tmpvec[1]*255);
205 ptr[2]=(unsigned char)(tmpvec[2]*255);
206
207 ptr += 3;
208 }
209 }
210 glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z,
211 0, 3, size, size, 0, GL_RGB, GL_UNSIGNED_BYTE, data);
212
213 free(data);
214 }
215
216 void
coin_apply_normalization_cube_map(const cc_glglue * glue)217 coin_apply_normalization_cube_map(const cc_glglue * glue)
218 {
219 if (glue->normalizationcubemap == 0) {
220 GLuint * dst = (GLuint*) &glue->normalizationcubemap;
221 static int CUBEMAP_SIZE = -1;
222 if (CUBEMAP_SIZE < 0) {
223 const char * env = coin_getenv("COIN_NORMALIZATION_CUBEMAP_SIZE");
224 CUBEMAP_SIZE = COIN_DEFAULT_CUBEMAP_SIZE;
225 if (env) {
226 int size = atoi(env);
227 if (size >= 2 && coin_is_power_of_two((uint32_t) size)) {
228 CUBEMAP_SIZE = size;
229 }
230 }
231 }
232 cc_glglue_glGenTextures(glue, 1, dst);
233 cc_glglue_glBindTexture(glue, GL_TEXTURE_CUBE_MAP, *dst);
234 coin_create_normalization_cube_map(CUBEMAP_SIZE);
235 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
236 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
237 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
238 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
239 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
240 }
241 cc_glglue_glBindTexture(glue, GL_TEXTURE_CUBE_MAP,
242 glue->normalizationcubemap);
243 }
244
245 #undef COIN_DEFAULT_CUBEMAP_SIZE
246