最近在学习Shadow Mapping,其原理很简单,在网上找了一个教程http://www.paulsprojects.net/tutorials/smt/smt.html,发现这个教程对于没有贴纹理的场景work,但对于那些贴有纹理的场景就束手无策了。OK,这是我想做的:
  [b] (1)把红色的圆环换成一个大立方体,并且贴上纹理
   (2)把四个绿球中两个对角的绿球换成两个小立方体并贴上纹理
   (3)要求产生正确的阴影(包括球和小立方体在大立方体上的阴影和在平面上的阴影)[/b]    
    注:可以读入一幅图像作为纹理,图片(bmp格式)任意  

我倒腾了很久,发现要么就是贴入了纹理shadow不正确,要么就是shadow正确了纹理却不对了,在网上找了很多资料,说的都不是很全,没有仔细说明怎么解决,经过我的摸爬滚打慢慢摸索,发现问题出在此:贴纹理和Display函数中第一步产生的depth map(纹理形式保存)都是以GL_TEXTURE_0作为当前活动纹理单元,这样导致了混淆,应该用glActiveTexture把他们分开,具体参见scene.cpp中的drawCube函数。

此贴是我此前发的提问帖的答案http://bbs.pfan.cn/post-373100.html,最终还是自己解决了,天助自助者,呵呵,还是要感谢ZJU的杨瑞健学长的指点,指出我问题的所在,衷心感谢!!!

[b]在paulsprojects的Shadow Mapping原程序上的改动:    
(1)修改了main.cpp里的Display函数(把glEnable (GL_CULL_FACE)换成glEnable (GL_POLYGON_FILL),glCullFace(GL_FRONT)换成glPolygonOffset(1.0,1.0),glCullFace(GL_BACK)换成glPolygonOffset(0.0,0.0),目的是为了在绘制立方体的时候避免某些免被CULL掉)。
(2)修改了main。cpp里的int main(int argc, char** argv)函数,在glutDisplayFunc(Display);这句前加上InitTexture();表示载入三幅bmp图片作为纹理。[/b]
[b](3)修改了scene.h函数,如下:[/b]
//////////////////////////////////////////////////////////////////////////////////////////
//    scene.h
//    Draw scene for shadow mapping
//    Downloaded from: www.paulsprojects.net
//    Created:    16th September 2003
//
//    Copyright (c) 2006, Paul Baker
//    Distributed under the New BSD Licence. (See accompanying file License.txt or copy at
//    http://www.paulsprojects.net/NewBSDLicense.txt)
//////////////////////////////////////////////////////////////////////////////////////////    

#ifndef SCENE_H
#define SCENE_H

void InitTexture();
void drawBox();
void DrawScene(float angle);

#endif    //SCENE_H

[b](4)修改了Scene.cpp,如下:[/b]
//////////////////////////////////////////////////////////////////////////////////////////
//    Scene.cpp
//    Draw the scene for shadow mapping
//    Downloaded from: www.paulsprojects.net
//    Created:    16th September 2003
//
//    Copyright (c) 2006, Paul Baker
//    Distributed under the New BSD Licence. (See accompanying file License.txt or copy at
//    http://www.paulsprojects.net/NewBSDLicense.txt)
//////////////////////////////////////////////////////////////////////////////////////////    
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <stdio.h>
#include "GLee/GLee.h"
#include <GL/glut.h>
#include <GL/glaux.h>
#include "Maths/Maths.h"
#include "scene.h"
#pragma comment(lib, "glaux.lib")
#pragma comment(lib, "Glee.lib")

GLuint texID[3];
AUX_RGBImageRec *TextureImage[3];

void InitTexture()
{
    glClearColor(0.0,0.0,0.0,0.0);
    glShadeModel(GL_SMOOTH);
    glEnable(GL_DEPTH_TEST);

    //load first texture image
    TextureImage[0]=auxDIBImageLoad("earth.bmp");
    glPixelStorei(GL_UNPACK_ALIGNMENT,1);
    glGenTextures(1,&texID[0]);
    glBindTexture(GL_TEXTURE_2D,texID[0]);
    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_REPEAT);
    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_REPEAT);
    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST);
    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST);
    glTexImage2D(GL_TEXTURE_2D, 0,GL_RGB, TextureImage[0]->sizeX, TextureImage[0]->sizeY,0, GL_RGB, GL_UNSIGNED_BYTE, TextureImage[0]->data);

    //load second texture image
    TextureImage[1]=auxDIBImageLoad("castle.bmp");
    glPixelStorei(GL_UNPACK_ALIGNMENT,1);
    glGenTextures(1,&texID[1]);
    glBindTexture(GL_TEXTURE_2D,texID[1]);
    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_REPEAT);
    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_REPEAT);
    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST);
    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST);
    glTexImage2D(GL_TEXTURE_2D, 0,GL_RGB, TextureImage[1]->sizeX, TextureImage[1]->sizeY,0, GL_RGB, GL_UNSIGNED_BYTE, TextureImage[1]->data);

    //load third texture image
    TextureImage[2]=auxDIBImageLoad("sea.bmp");
    glPixelStorei(GL_UNPACK_ALIGNMENT,1);
    glGenTextures(1,&texID[2]);
    glBindTexture(GL_TEXTURE_2D,texID[2]);
    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_REPEAT);
    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_REPEAT);
    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST);
    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST);
    glTexImage2D(GL_TEXTURE_2D, 0,GL_RGB, TextureImage[2]->sizeX, TextureImage[2]->sizeY,0, GL_RGB, GL_UNSIGNED_BYTE, TextureImage[2]->data);
}

void drawCube(GLfloat width,GLuint texName)//draw a cube with a specific texture
{
    GLfloat t=width/2;
    GLfloat point1[]={-t, t, t};
    GLfloat point2[]={ t, t, t};
    GLfloat point3[]={ t, t,-t};
    GLfloat point4[]={-t, t,-t};
    GLfloat point5[]={-t,-t, t};
    GLfloat point6[]={ t,-t, t};
    GLfloat point7[]={ t,-t,-t};
    GLfloat point8[]={-t,-t,-t};

    glActiveTexture(GL_TEXTURE0);//key step!!!========================
    glEnable(GL_TEXTURE_2D);
    //glTexEnvf(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_MODULATE);
    glBindTexture(GL_TEXTURE_2D,texName);
    glBegin(GL_QUADS);
        //top face
        glNormal3f(0.0,1.0,0.0);
        glTexCoord2f(0.0,0.0); glVertex3fv(point1);
        glTexCoord2f(1.0,0.0); glVertex3fv(point2);
        glTexCoord2f(1.0,1.0); glVertex3fv(point3);
        glTexCoord2f(0.0,1.0); glVertex3fv(point4);

        //bottom face
        glNormal3f(0.0,-1.0,0.0);
        glTexCoord2f(0.0,0.0); glVertex3fv(point5);
        glTexCoord2f(1.0,0.0); glVertex3fv(point6);
        glTexCoord2f(1.0,1.0); glVertex3fv(point7);
        glTexCoord2f(0.0,1.0); glVertex3fv(point8);

        //left face
        glNormal3f(-1.0,0.0,0.0);
        glTexCoord2f(0.0,0.0); glVertex3fv(point8);
        glTexCoord2f(1.0,0.0); glVertex3fv(point5);
        glTexCoord2f(1.0,1.0); glVertex3fv(point1);
        glTexCoord2f(0.0,1.0); glVertex3fv(point4);

        //right face
        glNormal3f(1.0,0.0,0.0);
        glTexCoord2f(0.0,0.0); glVertex3fv(point6);
        glTexCoord2f(1.0,0.0); glVertex3fv(point7);
        glTexCoord2f(1.0,1.0); glVertex3fv(point3);
        glTexCoord2f(0.0,1.0); glVertex3fv(point2);

        //front face
        glNormal3f(0.0,0.0,1.0);
        glTexCoord2f(0.0,0.0); glVertex3fv(point5);
        glTexCoord2f(1.0,0.0); glVertex3fv(point6);
        glTexCoord2f(1.0,1.0); glVertex3fv(point2);
        glTexCoord2f(0.0,1.0); glVertex3fv(point1);

        //back face
        glNormal3f(0.0,0.0,-1.0);
        glTexCoord2f(0.0,0.0); glVertex3fv(point8);
        glTexCoord2f(1.0,0.0); glVertex3fv(point7);
        glTexCoord2f(1.0,1.0); glVertex3fv(point3);
        glTexCoord2f(0.0,1.0); glVertex3fv(point4);
    glEnd();
    glDisable(GL_TEXTURE_2D);
    glActiveTexture(GL_TEXTURE1);//key step!!!========================
}

void DrawScene(float angle)
{
    //Display lists for objects
    static GLuint spheresList=0, cubeList=0, baseList=0;

    //Create spheres list if necessary
    if(!spheresList)
    {
        spheresList=glGenLists(1);
        glNewList(spheresList, GL_COMPILE);
        {
            glPushMatrix();

            glTranslatef(0.45f, 1.0f, 0.45f);
            glColor3f(0.0f, 1.0f, 0.0f);
            glutSolidSphere(0.2, 24, 24);

            glTranslatef(-0.9f, 0.0f, 0.0f);
            glColor3f(1.0f, 1.0f, 1.0f);
            drawCube(0.4,texID[1]);//draw first small cube

            glTranslatef(0.0f, 0.0f,-0.9f);
            glColor3f(0.0f, 1.0f, 0.0f);
            glutSolidSphere(0.2, 24, 24);

            glTranslatef(0.9f, 0.0f, 0.0f);
            glColor3f(1.0f, 1.0f, 1.0f);
            drawCube(0.4,texID[2]);//draw second small cube

            glPopMatrix();
        }
        glEndList();
    }


    //Create torus if necessary
    if(!cubeList)
    {
        cubeList=glGenLists(1);
        glNewList(cubeList, GL_COMPILE);
        {
            glColor3f(1.0f, 1.0f, 1.0f);
            glPushMatrix();
            
            drawCube(1.0,texID[0]);//draw big cube

            glPopMatrix();
            
        }
        glEndList();
    }

    //Create base if necessary
    if(!baseList)
    {
        baseList=glGenLists(1);
        glNewList(baseList, GL_COMPILE);
        {
            glColor3f(0.0f, 0.0f, 1.0f);
            glPushMatrix();

            glTranslatef(0.0,-1.5,0.0);
            glScalef(3.0f, 0.05f, 3.0f);
            glutSolidCube(2.0f);

            glPopMatrix();
        }
        glEndList();
    }


    ////Draw objects
    //glCallList(baseList);
    //glCallList(cubeList);
    //glPushMatrix();
    //    glRotatef(angle, 0.0f, 1.0f, 0.0f);
    //    glCallList(spheresList);
    //glPopMatrix();

    //Draw objects
    glCallList(baseList);
    glPushMatrix();
        glRotatef(0.4*angle, 0.0f, 1.0f, 0.0f);
        glCallList(cubeList);
        glRotatef(0.6*angle, 0.0f, 1.0f, 0.0f);
        glCallList(spheresList);
    glPopMatrix();
}