9 static unsigned int load_cubemap();
11 static void display();
12 static void reshape(int x, int y);
13 static void keyboard(unsigned char key, int x, int y);
14 static void mouse(int bn, int state, int x, int y);
15 static void motion(int x, int y);
31 uint32_t width, height;
33 uint32_t offset, size;
38 static unsigned int cubemap;
39 static float cam_phi, cam_theta;
41 int main(int argc, char **argv)
43 glutInit(&argc, argv);
44 glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE);
45 glutInitWindowSize(1024, 768);
46 glutCreateWindow("cubetest");
48 glutDisplayFunc(display);
49 glutReshapeFunc(reshape);
50 glutKeyboardFunc(keyboard);
52 glutMotionFunc(motion);
63 static bool load_teximage(const char *fname, Texture *tex)
66 if(!(fp = fopen(fname, "rb"))) {
67 fprintf(stderr, "failed to open file: %s: %s\n", fname, strerror(errno));
72 if(fread(&hdr, 1, sizeof hdr, fp) != sizeof hdr) {
73 fprintf(stderr, "failed to read image file header: %s: %s\n", fname, strerror(errno));
77 if(memcmp(hdr.magic, "COMPTEX0", sizeof hdr.magic) != 0 || hdr.levels < 0 ||
78 hdr.levels > 20 || !hdr.datadesc[0].size) {
79 fprintf(stderr, "%s is not a compressed texture file, or is corrupted\n", fname);
84 tex->data = new unsigned char[hdr.datadesc[0].size];
86 if(fread(tex->data, 1, hdr.datadesc[0].size, fp) != hdr.datadesc[0].size) {
87 fprintf(stderr, "unexpected EOF while reading texture: %s\n", fname);
93 tex->width = hdr.width;
94 tex->height = hdr.height;
95 tex->format = hdr.glfmt;
96 tex->size = hdr.datadesc[0].size;
103 static unsigned int load_cubemap()
105 static const char *names[6] = {"data/right.tex", "data/left.tex", "data/up.tex",
106 "data/down.tex", "data/back.tex", "data/front.tex"};
109 glGenTextures(1, &tex.id);
110 glBindTexture(GL_TEXTURE_CUBE_MAP, tex.id);
111 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
112 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
113 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
114 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
116 for(int i=0; i<6; i++) {
117 if(!load_teximage(names[i], &tex)) {
118 glDeleteTextures(1, &tex.id);
121 unsigned int face = GL_TEXTURE_CUBE_MAP_POSITIVE_X + i;
122 glCompressedTexImage2D(face, 0, tex.format, tex.width, tex.height, 0, tex.size, tex.data);
131 if(!(cubemap = load_cubemap())) {
134 glEnable(GL_TEXTURE_CUBE_MAP);
136 glEnable(GL_TEXTURE_GEN_S);
137 glEnable(GL_TEXTURE_GEN_T);
138 glEnable(GL_TEXTURE_GEN_R);
140 float planes[][4] = {{1, 0, 0, 0}, {0,1, 0, 0}, {0, 0, 1, 0}};
142 glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
143 glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
144 glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
146 glTexGenfv(GL_S, GL_OBJECT_PLANE, planes[0]);
147 glTexGenfv(GL_T, GL_OBJECT_PLANE, planes[1]);
148 glTexGenfv(GL_R, GL_OBJECT_PLANE, planes[2]);
153 static void cleanup()
155 glDeleteTextures(1, &cubemap);
158 static void display()
160 glClear(GL_COLOR_BUFFER_BIT);
162 glMatrixMode(GL_MODELVIEW);
164 glRotatef(cam_phi, 1, 0, 0);
165 glRotatef(cam_theta, 0, 1, 0);
167 glutSolidSphere(10, 10, 5);
172 static void reshape(int x, int y)
174 glViewport(0, 0, x, y);
175 glMatrixMode(GL_PROJECTION);
177 gluPerspective(45, (float)x / (float)y, 0.5, 100);
180 static void keyboard(unsigned char key, int x, int y)
190 static int prev_x, prev_y;
191 static bool bnstate[6];
193 static void mouse(int bn, int state, int x, int y)
197 bnstate[bn - GLUT_LEFT_BUTTON] = state == GLUT_DOWN;
200 static void motion(int x, int y)
203 cam_phi += (y - prev_y) * 0.5;
204 cam_theta += (x - prev_x) * 0.5;
206 if(cam_phi < -90) cam_phi = -90;
207 if(cam_phi > 90) cam_phi = 90;