From ca1bda552d1cd1a6ddc911e535681a10b9c2d846 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Thu, 1 Oct 2009 12:58:36 -0600 Subject: progs/objviewer: Wavefront .obj file loader/viewer demo Adapted from code written by Nate Robins. See README.txt. --- progs/objviewer/skybox.c | 186 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 186 insertions(+) create mode 100644 progs/objviewer/skybox.c (limited to 'progs/objviewer/skybox.c') diff --git a/progs/objviewer/skybox.c b/progs/objviewer/skybox.c new file mode 100644 index 00000000000..fb6f0194230 --- /dev/null +++ b/progs/objviewer/skybox.c @@ -0,0 +1,186 @@ + + +#include +#include +#include +#include +#include +#include +#include +#include "readtex.h" +#include "skybox.h" + + +static int +load(GLenum target, const char *filename, + GLboolean flipTB, GLboolean flipLR) +{ + GLint w, h; + GLenum format; + GLubyte *img = LoadRGBImage( filename, &w, &h, &format ); + if (!img) { + printf("Error: couldn't load texture image %s\n", filename); + return 0; + } + assert(format == GL_RGB); + + printf("Load cube face 0x%x: %s %d x %d\n", target, filename, w, h); + + /* the way the texture cube mapping works, we have to flip + * images to make things look right. + */ + if (flipTB) { + const int stride = 3 * w; + GLubyte temp[3*1024]; + int i; + for (i = 0; i < h / 2; i++) { + memcpy(temp, img + i * stride, stride); + memcpy(img + i * stride, img + (h - i - 1) * stride, stride); + memcpy(img + (h - i - 1) * stride, temp, stride); + } + } + if (flipLR) { + const int stride = 3 * w; + GLubyte temp[3]; + GLubyte *row; + int i, j; + for (i = 0; i < h; i++) { + row = img + i * stride; + for (j = 0; j < w / 2; j++) { + int k = w - j - 1; + temp[0] = row[j*3+0]; + temp[1] = row[j*3+1]; + temp[2] = row[j*3+2]; + row[j*3+0] = row[k*3+0]; + row[j*3+1] = row[k*3+1]; + row[j*3+2] = row[k*3+2]; + row[k*3+0] = temp[0]; + row[k*3+1] = temp[1]; + row[k*3+2] = temp[2]; + } + } + } + + gluBuild2DMipmaps(target, GL_RGB, w, h, format, GL_UNSIGNED_BYTE, img); + free(img); + return 1; +} + + +GLuint +LoadSkyBoxCubeTexture(const char *filePosX, + const char *fileNegX, + const char *filePosY, + const char *fileNegY, + const char *filePosZ, + const char *fileNegZ) +{ + GLuint tex; + + glGenTextures(1, &tex); + glBindTexture(GL_TEXTURE_CUBE_MAP, tex); + + if (!load(GL_TEXTURE_CUBE_MAP_POSITIVE_X, filePosX, GL_TRUE, GL_TRUE)) + return 0; + if (!load(GL_TEXTURE_CUBE_MAP_NEGATIVE_X, fileNegX, GL_TRUE, GL_TRUE)) + return 0; + if (!load(GL_TEXTURE_CUBE_MAP_POSITIVE_Y, filePosY, 1+GL_FALSE, GL_TRUE)) + return 0; + if (!load(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, fileNegY, 1+GL_FALSE, GL_TRUE)) + return 0; + if (!load(GL_TEXTURE_CUBE_MAP_POSITIVE_Z, filePosZ, GL_TRUE, GL_TRUE)) + return 0; + if (!load(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, fileNegZ, GL_TRUE, GL_TRUE)) + return 0; + + return tex; +} + + +#define eps1 0.99 +#define br 20.0 /* box radius */ + +void +DrawSkyBoxCubeTexture(GLuint tex) +{ + struct vertex { + float x, y, z, s, t, r; + }; + + static const struct vertex verts[24] = { + /* +X side */ + { br, -br, -br, 1.0, -eps1, -eps1 }, + { br, -br, br, 1.0, -eps1, eps1 }, + { br, br, br, 1.0, eps1, eps1 }, + { br, br, -br, 1.0, eps1, -eps1 }, + + /* -X side */ + { -br, br, -br, -1.0, eps1, -eps1 }, + { -br, br, br, -1.0, eps1, eps1 }, + { -br, -br, br, -1.0, -eps1, eps1 }, + { -br, -br, -br, -1.0, -eps1, -eps1 }, + + /* +Y side */ + { br, br, -br, eps1, 1.0, -eps1 }, + { br, br, br, eps1, 1.0, eps1 }, + { -br, br, br, -eps1, 1.0, eps1 }, + { -br, br, -br, -eps1, 1.0, -eps1 }, + + /* -Y side */ + { -br, -br, -br, -eps1, -1.0, -eps1 }, + { -br, -br, br, -eps1, -1.0, eps1 }, + { br, -br, br, eps1, -1.0, eps1 }, + { br, -br, -br, eps1, -1.0, -eps1 }, + + /* +Z side */ + { br, -br, br, eps1, -eps1, 1.0 }, + { -br, -br, br, -eps1, -eps1, 1.0 }, + { -br, br, br, -eps1, eps1, 1.0 }, + { br, br, br, eps1, eps1, 1.0 }, + + /* -Z side */ + { br, br, -br, eps1, eps1, -1.0 }, + { -br, br, -br, -eps1, eps1, -1.0 }, + { -br, -br, -br, -eps1, -eps1, -1.0 }, + { br, -br, -br, eps1, -eps1, -1.0 }, + }; + + static GLuint vbo = 0; + + if (!vbo ) { + glGenBuffersARB(1, &vbo); + glBindBufferARB(GL_ARRAY_BUFFER_ARB, vbo); + glBufferDataARB(GL_ARRAY_BUFFER_ARB, sizeof(verts), verts, + GL_STATIC_DRAW_ARB); + } + else { + glBindBufferARB(GL_ARRAY_BUFFER_ARB, vbo); + } + + glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); + + glVertexPointer(3, GL_FLOAT, sizeof(struct vertex), + (void *) offsetof(struct vertex, x)); + glTexCoordPointer(3, GL_FLOAT, sizeof(struct vertex), + (void *) offsetof(struct vertex, s)); + glEnableClientState(GL_VERTEX_ARRAY); + glEnableClientState(GL_TEXTURE_COORD_ARRAY); + + glBindTexture(GL_TEXTURE_CUBE_MAP, tex); + glEnable(GL_TEXTURE_CUBE_MAP); + + //glDisable(GL_LIGHTING); + glDisable(GL_BLEND); + + glDrawArrays(GL_QUADS, 0, 24); + + //glEnable(GL_LIGHTING); + + glDisable(GL_TEXTURE_CUBE_MAP); + + glDisableClientState(GL_VERTEX_ARRAY); + glDisableClientState(GL_TEXTURE_COORD_ARRAY); + + glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0); +} + -- cgit v1.2.3