1 /*
2 * Copyright (C) 2005 Terence M. Welsh
3 * Ported to Linux by Tugrul Galatali <tugrul@galatali.com>
4 *
5 * This file is part of Hyperspace.
6 *
7 * Hyperspace is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 *
11 * Hyperspace is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 */
20
21
22 #include <math.h>
23 #include <GL/gl.h>
24 #include <GL/glu.h>
25
26
27 #include "wavyNormalCubeMaps.h"
28 #include "rsMath/rsMath.h"
29
30
wavyNormalCubeMaps(int frames,int size)31 wavyNormalCubeMaps::wavyNormalCubeMaps(int frames, int size){
32 int g, i, j;
33
34 numFrames = frames;
35 texSize = size;
36
37 GLubyte* map = new GLubyte[texSize * texSize * 3];
38
39 // allocate memory for pointers to texture objects
40 texture = new GLuint[numFrames];
41 glGenTextures(numFrames, texture);
42
43 // calculate normal cube maps
44 float vec[3];
45 float norm[3];
46 float offset = -0.5f * float(texSize) + 0.5f;
47 for(g=0; g<numFrames; g++){
48 glBindTexture(GL_TEXTURE_CUBE_MAP_ARB, texture[g]);
49 glTexParameteri(GL_TEXTURE_CUBE_MAP_ARB, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
50 glTexParameteri(GL_TEXTURE_CUBE_MAP_ARB, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
51 glTexParameteri(GL_TEXTURE_CUBE_MAP_ARB, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
52 glTexParameteri(GL_TEXTURE_CUBE_MAP_ARB, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
53 phase = RS_PIx2 * float(g) / float(numFrames);
54
55 // left
56 for(i=0; i<texSize; i++){
57 for(j=0; j<texSize; j++){
58 vec[0] = -0.5f;
59 vec[1] = -(float(j) + offset) / float(texSize);
60 vec[2] = (float(i) + offset) / float(texSize);
61 normalize(vec);
62 wavyfunc(vec, norm);
63 map[(i + j * texSize) * 3] = GLubyte(norm[0] * 127.999f + 128.0f);
64 map[(i + j * texSize) * 3 + 1] = GLubyte(norm[1] * 127.999f + 128.0f);
65 map[(i + j * texSize) * 3 + 2] = GLubyte(norm[2] * -127.999f + 128.0f);
66 }
67 }
68 gluBuild2DMipmaps(GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB, 3, texSize, texSize,
69 GL_RGB, GL_UNSIGNED_BYTE, map);
70
71 // right
72 for(i=0; i<texSize; i++){
73 for(j=0; j<texSize; j++){
74 vec[0] = 0.5f;
75 vec[1] = -(float(j) + offset) / float(texSize);
76 vec[2] = -(float(i) + offset) / float(texSize);
77 normalize(vec);
78 wavyfunc(vec, norm);
79 map[(i + j * texSize) * 3] = GLubyte(norm[0] * 127.999f + 128.0f);
80 map[(i + j * texSize) * 3 + 1] = GLubyte(norm[1] * 127.999f + 128.0f);
81 map[(i + j * texSize) * 3 + 2] = GLubyte(norm[2] * -127.999f + 128.0f);
82 }
83 }
84 gluBuild2DMipmaps(GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB, 3, texSize, texSize,
85 GL_RGB, GL_UNSIGNED_BYTE, map);
86
87 // back
88 for(i=0; i<texSize; i++){
89 for(j=0; j<texSize; j++){
90 vec[0] = -(float(i) + offset) / float(texSize);
91 vec[1] = -(float(j) + offset) / float(texSize);
92 vec[2] = -0.5f;
93 normalize(vec);
94 wavyfunc(vec, norm);
95 map[(i + j * texSize) * 3] = GLubyte(norm[0] * 127.999f + 128.0f);
96 map[(i + j * texSize) * 3 + 1] = GLubyte(norm[1] * 127.999f + 128.0f);
97 map[(i + j * texSize) * 3 + 2] = GLubyte(norm[2] * -127.999f + 128.0f);
98 }
99 }
100 gluBuild2DMipmaps(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB, 3, texSize, texSize,
101 GL_RGB, GL_UNSIGNED_BYTE, map);
102
103 // front
104 for(i=0; i<texSize; i++){
105 for(j=0; j<texSize; j++){
106 vec[0] = (float(i) + offset) / float(texSize);
107 vec[1] = -(float(j) + offset) / float(texSize);
108 vec[2] = 0.5f;
109 normalize(vec);
110 wavyfunc(vec, norm);
111 map[(i + j * texSize) * 3] = GLubyte(norm[0] * 127.999f + 128.0f);
112 map[(i + j * texSize) * 3 + 1] = GLubyte(norm[1] * 127.999f + 128.0f);
113 map[(i + j * texSize) * 3 + 2] = GLubyte(norm[2] * -127.999f + 128.0f);
114 }
115 }
116 gluBuild2DMipmaps(GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB, 3, texSize, texSize,
117 GL_RGB, GL_UNSIGNED_BYTE, map);
118
119 // bottom
120 for(i=0; i<texSize; i++){
121 for(j=0; j<texSize; j++){
122 vec[0] = (float(i) + offset) / float(texSize);
123 vec[1] = -0.5f;
124 vec[2] = -(float(j) + offset) / float(texSize);
125 normalize(vec);
126 wavyfunc(vec, norm);
127 map[(i + j * texSize) * 3] = GLubyte(norm[0] * 127.999f + 128.0f);
128 map[(i + j * texSize) * 3 + 1] = GLubyte(norm[1] * 127.999f + 128.0f);
129 map[(i + j * texSize) * 3 + 2] = GLubyte(norm[2] * -127.999f + 128.0f);
130 }
131 }
132 gluBuild2DMipmaps(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB, 3, texSize, texSize,
133 GL_RGB, GL_UNSIGNED_BYTE, map);
134
135 // top
136 for(i=0; i<texSize; i++){
137 for(j=0; j<texSize; j++){
138 vec[0] = (float(i) + offset) / float(texSize);
139 vec[1] = 0.5f;
140 vec[2] = (float(j) + offset) / float(texSize);
141 normalize(vec);
142 wavyfunc(vec, norm);
143 map[(i + j * texSize) * 3] = GLubyte(norm[0] * 127.999f + 128.0f);
144 map[(i + j * texSize) * 3 + 1] = GLubyte(norm[1] * 127.999f + 128.0f);
145 map[(i + j * texSize) * 3 + 2] = GLubyte(norm[2] * -127.999f + 128.0f);
146 }
147 }
148 gluBuild2DMipmaps(GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB, 3, texSize, texSize,
149 GL_RGB, GL_UNSIGNED_BYTE, map);
150 }
151
152 delete[] map;
153 }
154
155
wavyfunc(float * point,float * normal)156 void wavyNormalCubeMaps::wavyfunc(float* point, float* normal){
157 for(int i=0; i<3; i++)
158 normal[i] = point[i];
159
160 normal[0] += 0.3f * rsCosf((1.0f * point[0] + 4.0f * point[1]) * RS_PI + phase)
161 + 0.15f * rsCosf((3.0f * point[1] + 13.0f * point[2]) * RS_PI - phase);
162 normal[1] += 0.3f * rsCosf((2.0f * point[1] - 5.0f * point[2]) * RS_PI + phase)
163 + 0.15f * rsCosf((2.0f * point[2] + 12.0f * point[0]) * RS_PI - phase);
164 normal[2] += 0.3f * rsCosf((1.0f * point[2] + 6.0f * point[0]) * RS_PI + phase)
165 + 0.15f * rsCosf((1.0f * point[0] - 11.0f * point[1]) * RS_PI - phase);
166
167 normalize(normal);
168 }
169
170
normalize(float * vector)171 inline void wavyNormalCubeMaps::normalize(float* vector){
172 static float normalizer;
173
174 normalizer = 1.0f / sqrtf(vector[0] * vector[0] + vector[1] * vector[1] + vector[2] * vector[2]);
175 vector[0] *= normalizer;
176 vector[1] *= normalizer;
177 vector[2] *= normalizer;
178 }
179