skybox.c revision 32001f49
132001f49Smrg 232001f49Smrg 332001f49Smrg#include <assert.h> 432001f49Smrg#include <stdio.h> 532001f49Smrg#include <stddef.h> 632001f49Smrg#include <stdlib.h> 732001f49Smrg#include <string.h> 832001f49Smrg#include <GL/glew.h> 932001f49Smrg#include "readtex.h" 1032001f49Smrg#include "skybox.h" 1132001f49Smrg 1232001f49Smrg 1332001f49Smrgstatic int 1432001f49Smrgload(GLenum target, const char *filename, 1532001f49Smrg GLboolean flipTB, GLboolean flipLR) 1632001f49Smrg{ 1732001f49Smrg GLint w, h; 1832001f49Smrg GLenum format; 1932001f49Smrg GLubyte *img = LoadRGBImage( filename, &w, &h, &format ); 2032001f49Smrg if (!img) { 2132001f49Smrg printf("Error: couldn't load texture image %s\n", filename); 2232001f49Smrg return 0; 2332001f49Smrg } 2432001f49Smrg assert(format == GL_RGB); 2532001f49Smrg 2632001f49Smrg printf("Load cube face 0x%x: %s %d x %d\n", target, filename, w, h); 2732001f49Smrg 2832001f49Smrg /* <sigh> the way the texture cube mapping works, we have to flip 2932001f49Smrg * images to make things look right. 3032001f49Smrg */ 3132001f49Smrg if (flipTB) { 3232001f49Smrg const int stride = 3 * w; 3332001f49Smrg GLubyte temp[3*1024]; 3432001f49Smrg int i; 3532001f49Smrg for (i = 0; i < h / 2; i++) { 3632001f49Smrg memcpy(temp, img + i * stride, stride); 3732001f49Smrg memcpy(img + i * stride, img + (h - i - 1) * stride, stride); 3832001f49Smrg memcpy(img + (h - i - 1) * stride, temp, stride); 3932001f49Smrg } 4032001f49Smrg } 4132001f49Smrg if (flipLR) { 4232001f49Smrg const int stride = 3 * w; 4332001f49Smrg GLubyte temp[3]; 4432001f49Smrg GLubyte *row; 4532001f49Smrg int i, j; 4632001f49Smrg for (i = 0; i < h; i++) { 4732001f49Smrg row = img + i * stride; 4832001f49Smrg for (j = 0; j < w / 2; j++) { 4932001f49Smrg int k = w - j - 1; 5032001f49Smrg temp[0] = row[j*3+0]; 5132001f49Smrg temp[1] = row[j*3+1]; 5232001f49Smrg temp[2] = row[j*3+2]; 5332001f49Smrg row[j*3+0] = row[k*3+0]; 5432001f49Smrg row[j*3+1] = row[k*3+1]; 5532001f49Smrg row[j*3+2] = row[k*3+2]; 5632001f49Smrg row[k*3+0] = temp[0]; 5732001f49Smrg row[k*3+1] = temp[1]; 5832001f49Smrg row[k*3+2] = temp[2]; 5932001f49Smrg } 6032001f49Smrg } 6132001f49Smrg } 6232001f49Smrg 6332001f49Smrg gluBuild2DMipmaps(target, GL_RGB, w, h, format, GL_UNSIGNED_BYTE, img); 6432001f49Smrg free(img); 6532001f49Smrg return 1; 6632001f49Smrg} 6732001f49Smrg 6832001f49Smrg 6932001f49SmrgGLuint 7032001f49SmrgLoadSkyBoxCubeTexture(const char *filePosX, 7132001f49Smrg const char *fileNegX, 7232001f49Smrg const char *filePosY, 7332001f49Smrg const char *fileNegY, 7432001f49Smrg const char *filePosZ, 7532001f49Smrg const char *fileNegZ) 7632001f49Smrg{ 7732001f49Smrg GLuint tex; 7832001f49Smrg 7932001f49Smrg glGenTextures(1, &tex); 8032001f49Smrg glBindTexture(GL_TEXTURE_CUBE_MAP, tex); 8132001f49Smrg 8232001f49Smrg glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 8332001f49Smrg glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, 8432001f49Smrg GL_LINEAR_MIPMAP_NEAREST); 8532001f49Smrg 8632001f49Smrg if (!load(GL_TEXTURE_CUBE_MAP_POSITIVE_X, filePosX, GL_TRUE, GL_TRUE)) 8732001f49Smrg return 0; 8832001f49Smrg if (!load(GL_TEXTURE_CUBE_MAP_NEGATIVE_X, fileNegX, GL_TRUE, GL_TRUE)) 8932001f49Smrg return 0; 9032001f49Smrg if (!load(GL_TEXTURE_CUBE_MAP_POSITIVE_Y, filePosY, GL_TRUE, GL_TRUE)) 9132001f49Smrg return 0; 9232001f49Smrg if (!load(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, fileNegY, GL_TRUE, GL_TRUE)) 9332001f49Smrg return 0; 9432001f49Smrg if (!load(GL_TEXTURE_CUBE_MAP_POSITIVE_Z, filePosZ, GL_TRUE, GL_TRUE)) 9532001f49Smrg return 0; 9632001f49Smrg if (!load(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, fileNegZ, GL_TRUE, GL_TRUE)) 9732001f49Smrg return 0; 9832001f49Smrg 9932001f49Smrg return tex; 10032001f49Smrg} 10132001f49Smrg 10232001f49Smrg 10332001f49Smrg#define eps1 0.99 10432001f49Smrg#define br 20.0 /* box radius */ 10532001f49Smrg 10632001f49Smrgvoid 10732001f49SmrgDrawSkyBoxCubeTexture(GLuint tex) 10832001f49Smrg{ 10932001f49Smrg struct vertex { 11032001f49Smrg float x, y, z, s, t, r; 11132001f49Smrg }; 11232001f49Smrg 11332001f49Smrg static const struct vertex verts[24] = { 11432001f49Smrg /* +X side */ 11532001f49Smrg { br, -br, -br, 1.0, -eps1, -eps1 }, 11632001f49Smrg { br, -br, br, 1.0, -eps1, eps1 }, 11732001f49Smrg { br, br, br, 1.0, eps1, eps1 }, 11832001f49Smrg { br, br, -br, 1.0, eps1, -eps1 }, 11932001f49Smrg 12032001f49Smrg /* -X side */ 12132001f49Smrg { -br, br, -br, -1.0, eps1, -eps1 }, 12232001f49Smrg { -br, br, br, -1.0, eps1, eps1 }, 12332001f49Smrg { -br, -br, br, -1.0, -eps1, eps1 }, 12432001f49Smrg { -br, -br, -br, -1.0, -eps1, -eps1 }, 12532001f49Smrg 12632001f49Smrg /* +Y side */ 12732001f49Smrg { br, br, -br, eps1, 1.0, -eps1 }, 12832001f49Smrg { br, br, br, eps1, 1.0, eps1 }, 12932001f49Smrg { -br, br, br, -eps1, 1.0, eps1 }, 13032001f49Smrg { -br, br, -br, -eps1, 1.0, -eps1 }, 13132001f49Smrg 13232001f49Smrg /* -Y side */ 13332001f49Smrg { -br, -br, -br, -eps1, -1.0, -eps1 }, 13432001f49Smrg { -br, -br, br, -eps1, -1.0, eps1 }, 13532001f49Smrg { br, -br, br, eps1, -1.0, eps1 }, 13632001f49Smrg { br, -br, -br, eps1, -1.0, -eps1 }, 13732001f49Smrg 13832001f49Smrg /* +Z side */ 13932001f49Smrg { br, -br, br, eps1, -eps1, 1.0 }, 14032001f49Smrg { -br, -br, br, -eps1, -eps1, 1.0 }, 14132001f49Smrg { -br, br, br, -eps1, eps1, 1.0 }, 14232001f49Smrg { br, br, br, eps1, eps1, 1.0 }, 14332001f49Smrg 14432001f49Smrg /* -Z side */ 14532001f49Smrg { br, br, -br, eps1, eps1, -1.0 }, 14632001f49Smrg { -br, br, -br, -eps1, eps1, -1.0 }, 14732001f49Smrg { -br, -br, -br, -eps1, -eps1, -1.0 }, 14832001f49Smrg { br, -br, -br, eps1, -eps1, -1.0 }, 14932001f49Smrg }; 15032001f49Smrg 15132001f49Smrg static GLuint vbo = 0; 15232001f49Smrg 15332001f49Smrg if (!vbo ) { 15432001f49Smrg glGenBuffersARB(1, &vbo); 15532001f49Smrg glBindBufferARB(GL_ARRAY_BUFFER_ARB, vbo); 15632001f49Smrg glBufferDataARB(GL_ARRAY_BUFFER_ARB, sizeof(verts), verts, 15732001f49Smrg GL_STATIC_DRAW_ARB); 15832001f49Smrg } 15932001f49Smrg else { 16032001f49Smrg glBindBufferARB(GL_ARRAY_BUFFER_ARB, vbo); 16132001f49Smrg } 16232001f49Smrg 16332001f49Smrg glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); 16432001f49Smrg 16532001f49Smrg glVertexPointer(3, GL_FLOAT, sizeof(struct vertex), 16632001f49Smrg (void *) offsetof(struct vertex, x)); 16732001f49Smrg glTexCoordPointer(3, GL_FLOAT, sizeof(struct vertex), 16832001f49Smrg (void *) offsetof(struct vertex, s)); 16932001f49Smrg glEnableClientState(GL_VERTEX_ARRAY); 17032001f49Smrg glEnableClientState(GL_TEXTURE_COORD_ARRAY); 17132001f49Smrg 17232001f49Smrg glBindTexture(GL_TEXTURE_CUBE_MAP, tex); 17332001f49Smrg glEnable(GL_TEXTURE_CUBE_MAP); 17432001f49Smrg 17532001f49Smrg glDisable(GL_BLEND); 17632001f49Smrg 17732001f49Smrg glDrawArrays(GL_QUADS, 0, 24); 17832001f49Smrg 17932001f49Smrg glDisable(GL_TEXTURE_CUBE_MAP); 18032001f49Smrg 18132001f49Smrg glDisableClientState(GL_VERTEX_ARRAY); 18232001f49Smrg glDisableClientState(GL_TEXTURE_COORD_ARRAY); 18332001f49Smrg 18432001f49Smrg glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0); 18532001f49Smrg} 18632001f49Smrg 187