Compiling...
multitexture.cpp
Linking...
multitexture.obj : error LNK2001: unresolved external symbol _pglActiveTexture
multitexture.obj : error LNK2001: unresolved external symbol _pglMultiTexCoord3f
multitexture.obj : error LNK2001: unresolved external symbol "void __cdecl gltDrawSphere(float,int,int)" (?gltDrawSphere@@YAXMHH@Z)
multitexture.obj : error LNK2001: unresolved external symbol "void __cdecl m3dRotationMatrix44(float * const,float,float,float,float)" (?m3dRotationMatrix44@@YAXQAMMMMM@Z)
Debug/multitexture.exe : fatal error LNK1120: 4 unresolved externals
执行 link.exe 时出错.
Creating browse info file...
multitexture.exe - 1 error(s), 0 warning(s)
// Multitexture.cpp
// OpenGL SuperBible
// Demonstrates a applying a cube map to an object (sphere) using
// texgen, and using the same map for the skybox applying the coordinates
// manually.
// Program by Richard S. Wright Jr.
#include "gltools.h" // OpenGL toolkit
#include "glframe.h" // Camera class
//#include "glfrustum.h"
//#include "math3d.h"
#include <math.h>
#pragma comment(lib,"opengl32.lib")
#pragma comment(lib,"glut32.lib")
GLFrame frameCamera; // The camera
#pragma warning(disable:4305)
// Storeage for two texture objects
GLuint textureObjects[2];
#define CUBE_MAP 0
#define COLOR_MAP 1
// Six sides of a cube map
const char *szCubeFaces[6] = { "pos_x.tga", "neg_x.tga", "pos_y.tga", "neg_y.tga", "pos_z.tga", "neg_z.tga" };
GLenum cube[6] = { GL_TEXTURE_CUBE_MAP_POSITIVE_X,
GL_TEXTURE_CUBE_MAP_NEGATIVE_X,
GL_TEXTURE_CUBE_MAP_POSITIVE_Y,
GL_TEXTURE_CUBE_MAP_NEGATIVE_Y,
GL_TEXTURE_CUBE_MAP_POSITIVE_Z,
GL_TEXTURE_CUBE_MAP_NEGATIVE_Z };
//////////////////////////////////////////////////////////////////
// This function does any needed initialization on the rendering
// context.
void SetupRC()
{
GLbyte *pBytes;
GLint iWidth, iHeight, iComponents;
GLenum eFormat;
int i;
// Cull backs of polygons
glCullFace(GL_BACK);
glFrontFace(GL_CCW);
glEnable(GL_CULL_FACE);
glEnable(GL_DEPTH_TEST);
glGenTextures(2, textureObjects);
// Set up texture maps
// Cube Map
glBindTexture(GL_TEXTURE_CUBE_MAP, textureObjects[CUBE_MAP]);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
// Load Cube Map images
for(i = 0; i < 6; i++)
{
// Load this texture map
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_GENERATE_MIPMAP, GL_TRUE);
pBytes = gltLoadTGA(szCubeFaces[i], &iWidth, &iHeight, &iComponents, &eFormat);
glTexImage2D(cube[i], 0, iComponents, iWidth, iHeight, 0, eFormat, GL_UNSIGNED_BYTE, pBytes);
free(pBytes);
}
// Color map
glBindTexture(GL_TEXTURE_2D, textureObjects[COLOR_MAP]);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP, GL_TRUE);
pBytes = gltLoadTGA("tarnish.tga", &iWidth, &iHeight, &iComponents, &eFormat);
glTexImage2D(GL_TEXTURE_2D, 0, iComponents, iWidth, iHeight, 0, eFormat, GL_UNSIGNED_BYTE, pBytes);
free(pBytes);
/////////////////////////////////////////////////////////////////////
// Set up the texture units
// First texture unit contains the color map
glActiveTexture(GL_TEXTURE0);
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, textureObjects[COLOR_MAP]);
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL); // Decal tarnish
// Second texture unit contains the cube map
glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_CUBE_MAP, textureObjects[CUBE_MAP]);
glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP);
glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP);
glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP);
glEnable(GL_TEXTURE_CUBE_MAP);
// Multiply this texture by the one underneath
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
}
///////////////////////////////////////////////////////////
// Cleanup
void ShutdownRC(void)
{
glDeleteTextures(2, textureObjects);
}
///////////////////////////////////////////////////////////
// Draw the skybox. This is just six quads, with texture
// coordinates set to the corners of the cube map
void DrawSkyBox(void)
{
GLfloat fExtent = 15.0f;
glBegin(GL_QUADS);
//////////////////////////////////////////////
// Negative X
// Note, we must now use the multi-texture version of glTexCoord
glMultiTexCoord3f(GL_TEXTURE1, -1.0f, -1.0f, 1.0f);
glVertex3f(-fExtent, -fExtent, fExtent);
glMultiTexCoord3f(GL_TEXTURE1, -1.0f, -1.0f, -1.0f);
glVertex3f(-fExtent, -fExtent, -fExtent);
glMultiTexCoord3f(GL_TEXTURE1, -1.0f, 1.0f, -1.0f);
glVertex3f(-fExtent, fExtent, -fExtent);
glMultiTexCoord3f(GL_TEXTURE1, -1.0f, 1.0f, 1.0f);
glVertex3f(-fExtent, fExtent, fExtent);
///////////////////////////////////////////////
// Postive X
glMultiTexCoord3f(GL_TEXTURE1, 1.0f, -1.0f, -1.0f);
glVertex3f(fExtent, -fExtent, -fExtent);
glMultiTexCoord3f(GL_TEXTURE1, 1.0f, -1.0f, 1.0f);
glVertex3f(fExtent, -fExtent, fExtent);
glMultiTexCoord3f(GL_TEXTURE1, 1.0f, 1.0f, 1.0f);
glVertex3f(fExtent, fExtent, fExtent);
glMultiTexCoord3f(GL_TEXTURE1, 1.0f, 1.0f, -1.0f);
glVertex3f(fExtent, fExtent, -fExtent);
////////////////////////////////////////////////
// Negative Z
glMultiTexCoord3f(GL_TEXTURE1, -1.0f, -1.0f, -1.0f);
glVertex3f(-fExtent, -fExtent, -fExtent);
glMultiTexCoord3f(GL_TEXTURE1, 1.0f, -1.0f, -1.0f);
glVertex3f(fExtent, -fExtent, -fExtent);
glMultiTexCoord3f(GL_TEXTURE1, 1.0f, 1.0f, -1.0f);
glVertex3f(fExtent, fExtent, -fExtent);
glMultiTexCoord3f(GL_TEXTURE1, -1.0f, 1.0f, -1.0f);
glVertex3f(-fExtent, fExtent, -fExtent);
////////////////////////////////////////////////
// Positive Z
glMultiTexCoord3f(GL_TEXTURE1, 1.0f, -1.0f, 1.0f);
glVertex3f(fExtent, -fExtent, fExtent);
glMultiTexCoord3f(GL_TEXTURE1, -1.0f, -1.0f, 1.0f);
glVertex3f(-fExtent, -fExtent, fExtent);
glMultiTexCoord3f(GL_TEXTURE1, -1.0f, 1.0f, 1.0f);
glVertex3f(-fExtent, fExtent, fExtent);
glMultiTexCoord3f(GL_TEXTURE1, 1.0f, 1.0f, 1.0f);
glVertex3f(fExtent, fExtent, fExtent);
//////////////////////////////////////////////////
// Positive Y
glMultiTexCoord3f(GL_TEXTURE1, -1.0f, 1.0f, 1.0f);
glVertex3f(-fExtent, fExtent, fExtent);
glMultiTexCoord3f(GL_TEXTURE1, -1.0f, 1.0f, -1.0f);
glVertex3f(-fExtent, fExtent, -fExtent);
glMultiTexCoord3f(GL_TEXTURE1, 1.0f, 1.0f, -1.0f);
glVertex3f(fExtent, fExtent, -fExtent);
glMultiTexCoord3f(GL_TEXTURE1, 1.0f, 1.0f, 1.0f);
glVertex3f(fExtent, fExtent, fExtent);
///////////////////////////////////////////////////
// Negative Y
glMultiTexCoord3f(GL_TEXTURE1, -1.0f, -1.0f, -1.0f);
glVertex3f(-fExtent, -fExtent, -fExtent);
glMultiTexCoord3f(GL_TEXTURE1, -1.0f, -1.0f, 1.0f);
glVertex3f(-fExtent, -fExtent, fExtent);
glMultiTexCoord3f(GL_TEXTURE1, 1.0f, -1.0f, 1.0f);
glVertex3f(fExtent, -fExtent, fExtent);
glMultiTexCoord3f(GL_TEXTURE1, 1.0f, -1.0f, -1.0f);
glVertex3f(fExtent, -fExtent, -fExtent);
glEnd();
}
// Called to draw scene
void RenderScene(void)
{
// Clear the window
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glPushMatrix();
frameCamera.ApplyCameraTransform(); // Move the camera about
// Sky Box is manually textured
glActiveTexture(GL_TEXTURE0);
glDisable(GL_TEXTURE_2D);
glActiveTexture(GL_TEXTURE1);
glEnable(GL_TEXTURE_CUBE_MAP);
glDisable(GL_TEXTURE_GEN_S);
glDisable(GL_TEXTURE_GEN_T);
glDisable(GL_TEXTURE_GEN_R);
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);
DrawSkyBox();
// Use texgen to apply cube map
glEnable(GL_TEXTURE_GEN_S);
glEnable(GL_TEXTURE_GEN_T);
glEnable(GL_TEXTURE_GEN_R);
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
glActiveTexture(GL_TEXTURE0);
glEnable(GL_TEXTURE_2D);
glPushMatrix();
glTranslatef(0.0f, 0.0f, -3.0f);
glActiveTexture(GL_TEXTURE1);
glMatrixMode(GL_TEXTURE);
glPushMatrix();
// Invert camera matrix (rotation only) and apply to
// texture coordinates
M3DMatrix44f m, invert;
frameCamera.GetCameraOrientation(m);
m3dInvertMatrix44f(invert, m);
glMultMatrixf(invert);
glColor3f(1.0f, 1.0f, 1.0f);
gltDrawSphere(0.75f, 41, 41);
glPopMatrix();
glMatrixMode(GL_MODELVIEW);
glPopMatrix();
glPopMatrix();
// Do the buffer Swap
glutSwapBuffers();
}
// Respond to arrow keys by moving the camera frame of reference
void SpecialKeys(int key, int x, int y)
{
if(key == GLUT_KEY_UP)
frameCamera.MoveForward(0.1f);
if(key == GLUT_KEY_DOWN)
frameCamera.MoveForward(-0.1f);
if(key == GLUT_KEY_LEFT)
frameCamera.RotateLocalY(0.1);
if(key == GLUT_KEY_RIGHT)
frameCamera.RotateLocalY(-0.1);
// Refresh the Window
glutPostRedisplay();
}
///////////////////////////////////////////////////////////
// Called by GLUT library when idle (window not being
// resized or moved)
void TimerFunction(int value)
{
// Redraw the scene with new coordinates
glutPostRedisplay();
glutTimerFunc(3,TimerFunction, 1);
}
void ChangeSize(int w, int h)
{
GLfloat fAspect;
// Prevent a divide by zero, when window is too short
// (you cant make a window of zero width).
if(h == 0)
h = 1;
glViewport(0, 0, w, h);
fAspect = (GLfloat)w / (GLfloat)h;
// Reset the coordinate system before modifying
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
// Set the clipping volume
gluPerspective(35.0f, fAspect, 1.0f, 2000.0f);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}
int main(int argc, char* argv[])
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
glutInitWindowSize(800,600);
glutCreateWindow("OpenGL Cube Maps");
glutReshapeFunc(ChangeSize);
glutDisplayFunc(RenderScene);
glutSpecialFunc(SpecialKeys);
SetupRC();
glutTimerFunc(33, TimerFunction, 1);
glutMainLoop();
ShutdownRC();
return 0;
}