Retired Document
Important: This sample code may not represent best practices for current development. The project may use deprecated symbols and illustrate technologies and techniques that are no longer recommended.
glsmap/smap_buildsmap.c
/* Copyright (c) Mark J. Kilgard, 1998. */ |
/* This program is freely distributable without licensing fees |
and is provided without guarantee or warrantee expressed or |
implied. This program is -not- in the public domain. */ |
/* smap_buildsmap.c - automatically builds sphere map */ |
#include <assert.h> |
#include <stdio.h> |
#include <glsmap.h> |
#include <OpenGL/glu.h> |
#include "glsmapint.h" |
#if defined(GL_EXT_texture_object) && !defined(GL_VERSION_1_1) |
#define glBindTexture(A,B) glBindTextureEXT(A,B) |
#endif |
#if defined(GL_EXT_copy_texture) && !defined(GL_VERSION_1_1) |
#define glCopyTexImage2D(A, B, C, D, E, F, G, H) glCopyTexImage2DEXT(A, B, C, D, E, F, G, H) |
#endif |
static void |
copyImageToTexture(SphereMap *smap, |
GLuint texobj, int origin[2], int texdim) |
{ |
int isSmapTexObj = (texobj == smap->smapTexObj) ? 1 : 0; |
int genMipmapsFlag = |
isSmapTexObj ? SMAP_GENERATE_SMAP_MIPMAPS : SMAP_GENERATE_VIEW_MIPMAPS; |
static GLubyte pixels[256][256][3]; /* XXX fix me. */ |
glBindTexture(GL_TEXTURE_2D, texobj); |
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, |
GL_LINEAR); |
if (smap->flags & genMipmapsFlag) { |
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, |
GL_LINEAR_MIPMAP_LINEAR); |
} else { |
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, |
GL_LINEAR); |
} |
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); |
/* Clamp to avoid artifacts from wrap around in texture. */ |
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); |
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); |
if (smap->flags & genMipmapsFlag) { |
glPixelStorei(GL_PACK_ALIGNMENT, 1); |
glPixelStorei(GL_UNPACK_ALIGNMENT, 1); |
glReadPixels(origin[X], origin[Y], texdim, texdim, |
GL_RGB, GL_UNSIGNED_BYTE, pixels); |
gluBuild2DMipmaps(GL_TEXTURE_2D, 3, texdim, texdim, |
GL_RGB, GL_UNSIGNED_BYTE, pixels); |
} else { |
glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, |
origin[X], origin[Y], texdim, texdim, 0); |
} |
} |
static struct { |
GLfloat angle; |
GLfloat x, y, z; |
} faceInfo[6] = { |
{ 0.0, +1.0, 0.0, 0.0 }, /* front */ |
{ 90.0, -1.0, 0.0, 0.0 }, /* top */ |
{ 90.0, +1.0, 0.0, 0.0 }, /* bottom */ |
{ 90.0, 0.0, -1.0, 0.0 }, /* left */ |
{ 90.0, 0.0, +1.0, 0.0 }, /* right */ |
{ 180.0, -1.0, 0.0, 0.0 } /* back */ |
}; |
static void |
configFace(SphereMap *smap, int view) |
{ |
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); |
glMatrixMode(GL_MODELVIEW); |
glLoadIdentity(); |
glRotatef(faceInfo[view].angle, |
faceInfo[view].x, faceInfo[view].y, faceInfo[view].z); |
gluLookAt(smap->obj[X], smap->obj[Y], smap->obj[Z], /* "eye" at object */ |
smap->eye[X], smap->eye[Y], smap->eye[Z], /* looking at eye */ |
smap->up[X], smap->up[Y], smap->up[Z]); |
} |
static void |
initGenViewTex(SphereMap *smap) |
{ |
glMatrixMode(GL_PROJECTION); |
glLoadIdentity(); |
gluPerspective(90.0, 1.0, smap->viewNear, smap->viewFar); |
glViewport(smap->viewOrigin[X], smap->viewOrigin[Y], |
smap->viewTexDim, smap->viewTexDim); |
glScissor(0, 0, smap->viewTexDim, smap->viewTexDim); |
glEnable(GL_SCISSOR_TEST); |
glEnable(GL_DEPTH_TEST); |
} |
static void |
genViewTex(SphereMap *smap, int view) |
{ |
configFace(smap, view); |
assert(smap->positionLights); |
smap->positionLights(view, smap->context); |
assert(smap->drawView); |
smap->drawView(view, smap->context); |
} |
void |
smapGenViewTex(SphereMap *smap, int view) |
{ |
initGenViewTex(smap); |
genViewTex(smap, view); |
copyImageToTexture(smap, smap->viewTexObjs[view], |
smap->viewOrigin, smap->viewTexDim); |
} |
void |
smapGenViewTexs(SphereMap *smap) |
{ |
int view; |
initGenViewTex(smap); |
for (view=0; view<6; view++) { |
genViewTex(smap, view); |
copyImageToTexture(smap, smap->viewTexObjs[view], |
smap->viewOrigin, smap->viewTexDim); |
} |
} |
void |
drawSphereMapMesh(SphereMap *smap) |
{ |
int side; |
/* Calculate sphere map mesh if needed. */ |
__smapValidateSphereMapMesh(smap->mesh); |
/* Five front and side faces. */ |
for (side=0; side<5; side++) { |
/* Bind to texture for given face of cube map. */ |
glBindTexture(GL_TEXTURE_2D, smap->viewTexObjs[side]); |
__smapDrawSphereMapMeshSide(smap->mesh, side); |
} |
/* Bind to texture for back face of cube map. */ |
glBindTexture(GL_TEXTURE_2D, smap->viewTexObjs[side]); |
__smapDrawSphereMapMeshBack(smap->mesh); |
} |
void |
initDrawSphereMapMesh(SphereMap *smap) |
{ |
glMatrixMode(GL_PROJECTION); |
glLoadIdentity(); |
gluOrtho2D(0, 1, 0, 1); |
glMatrixMode(GL_MODELVIEW); |
glLoadIdentity(); |
glViewport(smap->smapOrigin[X], smap->smapOrigin[Y], |
smap->smapTexDim, smap->smapTexDim); |
if (smap->flags & SMAP_CLEAR_SMAP_TEXTURE) { |
glClear(GL_COLOR_BUFFER_BIT); |
} |
glDisable(GL_DEPTH_TEST); |
glEnable(GL_TEXTURE_2D); |
glDisable(GL_CULL_FACE); |
} |
void |
smapGenSphereMapFromViewTexs(SphereMap *smap) |
{ |
initDrawSphereMapMesh(smap); |
drawSphereMapMesh(smap); |
copyImageToTexture(smap, smap->smapTexObj, |
smap->smapOrigin, smap->smapTexDim); |
} |
void |
smapGenSphereMap(SphereMap *smap) |
{ |
smapGenViewTexs(smap); |
smapGenSphereMapFromViewTexs(smap); |
} |
void |
smapGenSphereMapWithOneViewTex(SphereMap *smap) |
{ |
int side; |
/* Make sure viewports are not obviously overlapping. */ |
assert(smap->viewOrigin[X] != smap->smapOrigin[X]); |
assert(smap->viewOrigin[Y] != smap->smapOrigin[Y]); |
/* Calculate sphere map mesh if needed. */ |
__smapValidateSphereMapMesh(smap->mesh); |
/* Five front and side faces. */ |
for (side=0; side<5; side++) { |
initGenViewTex(smap); |
genViewTex(smap, side); |
copyImageToTexture(smap, smap->viewTexObj, |
smap->viewOrigin, smap->viewTexDim); |
/* Preceeding copyImageToTexture does bind to smap->viewTexObj */ |
initDrawSphereMapMesh(smap); |
__smapDrawSphereMapMeshSide(smap->mesh, side); |
} |
initGenViewTex(smap); |
genViewTex(smap, SMAP_BACK); |
copyImageToTexture(smap, smap->viewTexObj, |
smap->viewOrigin, smap->viewTexDim); |
/* Preceeding copyImageToTexture does bind to smap->viewTexObj */ |
initDrawSphereMapMesh(smap); |
__smapDrawSphereMapMeshBack(smap->mesh); |
copyImageToTexture(smap, smap->smapTexObj, |
smap->smapOrigin, smap->smapTexDim); |
} |
Copyright © 2008 Apple Inc. All Rights Reserved. Terms of Use | Privacy Policy | Updated: 2008-02-08