smap_buildsmap.c
上传用户:xk288cn
上传日期:2007-05-28
资源大小:4876k
文件大小:6k
- /* 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 <GL/glsmap.h>
- #include <GL/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);
- }