Merge branch '7.8' into master
[mesa.git] / progs / objviewer / skybox.c
1
2
3 #include <assert.h>
4 #include <stdio.h>
5 #include <stddef.h>
6 #include <stdlib.h>
7 #include <string.h>
8 #include <GL/glew.h>
9 #include <GL/glu.h>
10 #include "readtex.h"
11 #include "skybox.h"
12
13
14 static int
15 load(GLenum target, const char *filename,
16 GLboolean flipTB, GLboolean flipLR)
17 {
18 GLint w, h;
19 GLenum format;
20 GLubyte *img = LoadRGBImage( filename, &w, &h, &format );
21 if (!img) {
22 printf("Error: couldn't load texture image %s\n", filename);
23 return 0;
24 }
25 assert(format == GL_RGB);
26
27 printf("Load cube face 0x%x: %s %d x %d\n", target, filename, w, h);
28
29 /* <sigh> the way the texture cube mapping works, we have to flip
30 * images to make things look right.
31 */
32 if (flipTB) {
33 const int stride = 3 * w;
34 GLubyte temp[3*1024];
35 int i;
36 for (i = 0; i < h / 2; i++) {
37 memcpy(temp, img + i * stride, stride);
38 memcpy(img + i * stride, img + (h - i - 1) * stride, stride);
39 memcpy(img + (h - i - 1) * stride, temp, stride);
40 }
41 }
42 if (flipLR) {
43 const int stride = 3 * w;
44 GLubyte temp[3];
45 GLubyte *row;
46 int i, j;
47 for (i = 0; i < h; i++) {
48 row = img + i * stride;
49 for (j = 0; j < w / 2; j++) {
50 int k = w - j - 1;
51 temp[0] = row[j*3+0];
52 temp[1] = row[j*3+1];
53 temp[2] = row[j*3+2];
54 row[j*3+0] = row[k*3+0];
55 row[j*3+1] = row[k*3+1];
56 row[j*3+2] = row[k*3+2];
57 row[k*3+0] = temp[0];
58 row[k*3+1] = temp[1];
59 row[k*3+2] = temp[2];
60 }
61 }
62 }
63
64 gluBuild2DMipmaps(target, GL_RGB, w, h, format, GL_UNSIGNED_BYTE, img);
65 free(img);
66 return 1;
67 }
68
69
70 GLuint
71 LoadSkyBoxCubeTexture(const char *filePosX,
72 const char *fileNegX,
73 const char *filePosY,
74 const char *fileNegY,
75 const char *filePosZ,
76 const char *fileNegZ)
77 {
78 GLuint tex;
79
80 glGenTextures(1, &tex);
81 glBindTexture(GL_TEXTURE_CUBE_MAP, tex);
82
83 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
84 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER,
85 GL_LINEAR_MIPMAP_NEAREST);
86
87 if (!load(GL_TEXTURE_CUBE_MAP_POSITIVE_X, filePosX, GL_TRUE, GL_TRUE))
88 return 0;
89 if (!load(GL_TEXTURE_CUBE_MAP_NEGATIVE_X, fileNegX, GL_TRUE, GL_TRUE))
90 return 0;
91 if (!load(GL_TEXTURE_CUBE_MAP_POSITIVE_Y, filePosY, GL_TRUE, GL_TRUE))
92 return 0;
93 if (!load(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, fileNegY, GL_TRUE, GL_TRUE))
94 return 0;
95 if (!load(GL_TEXTURE_CUBE_MAP_POSITIVE_Z, filePosZ, GL_TRUE, GL_TRUE))
96 return 0;
97 if (!load(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, fileNegZ, GL_TRUE, GL_TRUE))
98 return 0;
99
100 return tex;
101 }
102
103
104 #define eps1 0.99
105 #define br 20.0 /* box radius */
106
107 void
108 DrawSkyBoxCubeTexture(GLuint tex)
109 {
110 struct vertex {
111 float x, y, z, s, t, r;
112 };
113
114 static const struct vertex verts[24] = {
115 /* +X side */
116 { br, -br, -br, 1.0, -eps1, -eps1 },
117 { br, -br, br, 1.0, -eps1, eps1 },
118 { br, br, br, 1.0, eps1, eps1 },
119 { br, br, -br, 1.0, eps1, -eps1 },
120
121 /* -X side */
122 { -br, br, -br, -1.0, eps1, -eps1 },
123 { -br, br, br, -1.0, eps1, eps1 },
124 { -br, -br, br, -1.0, -eps1, eps1 },
125 { -br, -br, -br, -1.0, -eps1, -eps1 },
126
127 /* +Y side */
128 { br, br, -br, eps1, 1.0, -eps1 },
129 { br, br, br, eps1, 1.0, eps1 },
130 { -br, br, br, -eps1, 1.0, eps1 },
131 { -br, br, -br, -eps1, 1.0, -eps1 },
132
133 /* -Y side */
134 { -br, -br, -br, -eps1, -1.0, -eps1 },
135 { -br, -br, br, -eps1, -1.0, eps1 },
136 { br, -br, br, eps1, -1.0, eps1 },
137 { br, -br, -br, eps1, -1.0, -eps1 },
138
139 /* +Z side */
140 { br, -br, br, eps1, -eps1, 1.0 },
141 { -br, -br, br, -eps1, -eps1, 1.0 },
142 { -br, br, br, -eps1, eps1, 1.0 },
143 { br, br, br, eps1, eps1, 1.0 },
144
145 /* -Z side */
146 { br, br, -br, eps1, eps1, -1.0 },
147 { -br, br, -br, -eps1, eps1, -1.0 },
148 { -br, -br, -br, -eps1, -eps1, -1.0 },
149 { br, -br, -br, eps1, -eps1, -1.0 },
150 };
151
152 static GLuint vbo = 0;
153
154 if (!vbo ) {
155 glGenBuffersARB(1, &vbo);
156 glBindBufferARB(GL_ARRAY_BUFFER_ARB, vbo);
157 glBufferDataARB(GL_ARRAY_BUFFER_ARB, sizeof(verts), verts,
158 GL_STATIC_DRAW_ARB);
159 }
160 else {
161 glBindBufferARB(GL_ARRAY_BUFFER_ARB, vbo);
162 }
163
164 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
165
166 glVertexPointer(3, GL_FLOAT, sizeof(struct vertex),
167 (void *) offsetof(struct vertex, x));
168 glTexCoordPointer(3, GL_FLOAT, sizeof(struct vertex),
169 (void *) offsetof(struct vertex, s));
170 glEnableClientState(GL_VERTEX_ARRAY);
171 glEnableClientState(GL_TEXTURE_COORD_ARRAY);
172
173 glBindTexture(GL_TEXTURE_CUBE_MAP, tex);
174 glEnable(GL_TEXTURE_CUBE_MAP);
175
176 glDisable(GL_BLEND);
177
178 glDrawArrays(GL_QUADS, 0, 24);
179
180 glDisable(GL_TEXTURE_CUBE_MAP);
181
182 glDisableClientState(GL_VERTEX_ARRAY);
183 glDisableClientState(GL_TEXTURE_COORD_ARRAY);
184
185 glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0);
186 }
187