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