游戏开发论坛

 找回密码
 立即注册
搜索
查看: 2871|回复: 3

stencil buffer shadow的问题

[复制链接]

3

主题

6

帖子

6

积分

新手上路

Rank: 1

积分
6
发表于 2011-4-16 09:56:00 | 显示全部楼层 |阅读模式
我尝试了一个非常简单的模板阴影场景.场景由一个在(1000,0,0)的光源和一个固定的四边形组成。阴影体是一个固定的长方体。
工作不正常,似乎完全没有产生阴影模板。

请各位高手指点!

绘图部分的函数如下:

  1. // 光源属性
  2. GLfloat light_position[4] = { 1000, 0, 0, 1 };
  3. GLfloat light_ambient[4]  = { 0.2, 0.2, 0.2, 1 };
  4. GLfloat light_diffuse[4]  = { 1, 1, 1, 1 };
  5. GLfloat light_specular[4] = { 1, 1, 1, 1 };

  6. // 材质属性
  7. GLfloat mat_ambient[4]  = { 0.5, 0.5, 0.5, 1 };
  8. GLfloat mat_diffuse[4]  = { 1, 0, 0, 1 };
  9. GLfloat mat_specular[4] = { 0, 0, 1, 1 };
  10. GLfloat mat_emission[4] = { 0, 0, 0, 1 };

  11. GLfloat zeroes[4] = {0,0,0,0};

  12. // 物体
  13. void draw_obj() {
  14.         glBegin(GL_QUADS);
  15.                 glNormal3d(1,0,0);
  16.                 glVertex3d(0,10,10);
  17.                 glVertex3d(0,-10,10);
  18.                 glVertex3d(10,-10,-10);
  19.                 glVertex3d(10,10,-10);
  20.         glEnd();
  21. }

  22. // 投影体
  23. void draw_shadow_volume() {
  24.         glBegin(GL_QUADS);
  25.                 // z near
  26.                 glNormal3d(0,0,1);
  27.                 glVertex3d(-100,-5,5);
  28.                 glVertex3d(100,-5,5);
  29.                 glVertex3d(100,5,5);
  30.                 glVertex3d(-100,5,5);
  31.                 // z far
  32.                 glNormal3d(0,0,-1);
  33.                 glVertex3d(100,5,-5);
  34.                 glVertex3d(100,-5,-5);
  35.                 glVertex3d(-100,-5,-5);
  36.                 glVertex3d(-100,5,-5);
  37.                 // x max
  38.                 glNormal3d(1,0,0);
  39.                 glVertex3d(100,5,5);
  40.                 glVertex3d(100,-5,5);
  41.                 glVertex3d(100,-5,-5);
  42.                 glVertex3d(100,5,-5);
  43.                 // x min
  44.                 glNormal3d(-1,0,0);
  45.                 glVertex3d(-100,5,5);
  46.                 glVertex3d(-100,5,-5);
  47.                 glVertex3d(-100,-5,-5);
  48.                 glVertex3d(-100,-5,5);
  49.                 // y max
  50.                 glNormal3d(0,1,0);
  51.                 glVertex3d(100,5,5);
  52.                 glVertex3d(100,5,-5);
  53.                 glVertex3d(-100,5,-5);
  54.                 glVertex3d(-100,5,5);
  55.                 // y min
  56.                 glNormal3d(0,-1,0);
  57.                 glVertex3d(100,-5,5);
  58.                 glVertex3d(-100,-5,5);
  59.                 glVertex3d(-100,-5,-5);
  60.                 glVertex3d(100,-5,-5);
  61.         glEnd();
  62. }

  63. // 绘图函数
  64. void draw() {
  65.        
  66.         glPushMatrix();
  67.         glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
  68.        
  69.         // apply camera
  70.         glTranslated(0,0,-camera.distance);
  71.         glRotated(camera.elevation,1,0,0);
  72.         glRotated(camera.azimuth,0,1,0);
  73.         glTranslated(-camera.x, -camera.y, -camera.z);
  74.        
  75.         // set light
  76.         glEnable(GL_LIGHTING);
  77.         glEnable(GL_LIGHT0);
  78.         glLightModeli(GL_LIGHT_MODEL_TWO_SIDE,GL_FALSE);
  79.         glLightfv( GL_LIGHT0, GL_POSITION, light_position );
  80.         glLightfv( GL_LIGHT0, GL_AMBIENT,  light_ambient );
  81.         glLightfv( GL_LIGHT0, GL_DIFFUSE,  light_diffuse );
  82.         glLightfv( GL_LIGHT0, GL_SPECULAR, light_specular );
  83.        
  84.         // set material
  85.         glMaterialfv( GL_FRONT, GL_AMBIENT, mat_ambient );
  86.         glMaterialfv( GL_FRONT, GL_DIFFUSE, mat_diffuse );
  87.         glMaterialfv( GL_FRONT, GL_SPECULAR, mat_specular );
  88.         glMaterialfv( GL_FRONT, GL_EMISSION, mat_emission );
  89.         glMaterialf( GL_FRONT, GL_SHININESS, 100 );
  90.        
  91.         // draw objects first time
  92.         glEnable(GL_DEPTH_TEST);
  93.         glDisable(GL_STENCIL_TEST);
  94.         draw_obj();
  95.        
  96.         // draw shadow object using depth-fail method
  97.         // it should create an stencil mask of 1s on shadowed pixels, and 0s on bright pixels
  98.         glPushMatrix();
  99.                 glDisable(GL_LIGHTING);
  100.                
  101.                 glColorMask(GL_FALSE,GL_FALSE,GL_FALSE,GL_FALSE);
  102.                 glDepthMask(GL_FALSE);
  103.                
  104.                 glEnable(GL_STENCIL_TEST);
  105.                 glStencilFunc(GL_ALWAYS,0,~0u);
  106.                
  107.                 glEnable(GL_CULL_FACE);
  108.                
  109.                 // draw the back face of shadow volume
  110.                 glCullFace(GL_FRONT);
  111.                 glStencilOp(GL_KEEP,GL_INVERT,GL_KEEP);
  112.                 draw_shadow_volume();
  113.                
  114.                 // draw the front face of shadow volume
  115.                 glCullFace(GL_BACK);
  116.                 glStencilOp(GL_KEEP,GL_INVERT,GL_KEEP);
  117.                 draw_shadow_volume();
  118.                
  119.                 glDisable(GL_CULL_FACE);
  120.         glPopMatrix();
  121.        
  122.         //~ // draw shadowed scene again
  123.         //~ // only draw on pixels which stencil buffer is one
  124.         glColorMask(GL_TRUE,GL_TRUE,GL_TRUE,GL_TRUE);
  125.         glDepthMask(GL_TRUE);
  126.         glDepthFunc(GL_LEQUAL);
  127.        
  128.         glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
  129.         glStencilFunc(GL_GREATER, 0, ~0u);
  130.        
  131.         glEnable(GL_LIGHTING);
  132.         glLightfv(GL_FRONT, GL_DIFFUSE, zeroes);
  133.         glLightfv(GL_FRONT, GL_SPECULAR, zeroes);
  134.        
  135.         draw_obj();
  136.        
  137.         glDepthMask(GL_TRUE);
  138.         glDepthFunc(GL_LESS);
  139.         glDisable(GL_STENCIL_TEST);
  140.        
  141.         // draw axis
  142.         glDisable(GL_LIGHTING);
  143.         glBegin(GL_LINES);
  144.                 glColor3f(1,0,0);
  145.                 glVertex3d(0,0,0);
  146.                 glVertex3d(100,0,0);
  147.                
  148.                 glColor3f(0,1,0);
  149.                 glVertex3d(0,0,0);
  150.                 glVertex3d(0,100,0);
  151.                
  152.                 glColor3f(0,0,1);
  153.                 glVertex3d(0,0,0);
  154.                 glVertex3d(0,0,100);
  155.         glEnd();
  156.        
  157.         // finishing works
  158.         glPopMatrix();
  159.         glFlush();
  160.         glutSwapBuffers();
  161. }

复制代码

21

主题

296

帖子

296

积分

中级会员

Rank: 3Rank: 3

积分
296
发表于 2011-4-17 20:01:00 | 显示全部楼层

Re:stencil buffer shadow的问题

stencil 俺没用过,只知道它是用来标记已渲染区域的。

hyzboy 应该能回答这个问题。

0

主题

5

帖子

5

积分

新手上路

Rank: 1

积分
5
发表于 2011-4-18 10:58:00 | 显示全部楼层

Re: stencil buffer shadow的问题

//-----------------------------------------------------------------------------
//           Name: ogl_shadow_volume.cpp
//         Author: Kevin Harris
//  Last Modified: 06/25/05
//    Description: This sample demonstrates how to create real-time shadows
//                 under OpenGL using shadow volumes.
//
//                 Please note that this sample is the simplest shadow volume
//                 sample that I could create. It demonstrates only the basics
//                 which are required to create a shadow volume and doesn't
//                 attempt to fix any special cases problems such as what to
//                 do when the viewing position is inside the shadow volume or
//                 how to produce shadow volumes for more complicated objects
//                 which require edge detection.
//
//   Control Keys: Up    - Light moves up
//                 Down  - Light moves down
//                 Left  - Light moves left
//                 Right - Light moves right
//
//                 Left Mouse Button  - Spin the view
//                 Right Mouse Button - Spin the shadow caster (NOT WORKING YET!)
//
//                 F1 - Render shadow volume
//                 F2 - Increase amount of shadow volume extrusion
//                 F3 - Decrease amount of shadow volume extrusion
//-----------------------------------------------------------------------------

#define STRICT
#define WIN32_LEAN_AND_MEAN

#include <windows.h>
#include <GL/gl.h>
#include <GL/glu.h>
#include "geometry.h"
#include "resource.h"

//-----------------------------------------------------------------------------
// GLOBALS
//-----------------------------------------------------------------------------
HWND   g_hWnd = NULL;
HDC    g_hDC  = NULL;
HGLRC  g_hRC  = NULL;

// Spin control for view
float  g_fSpinX_L =   0.0f;
float  g_fSpinY_L = -10.0f;

// Spin control for shadow casting quad
float  g_fSpinX_R =   0.0f;
float  g_fSpinY_R =   0.0f;

bool  g_bRenderShadowVolume = false;
float g_fAmountOfExtrusion  = 5.0f;
float g_lightPosition[]     = { 2.0f, 6.0f, 0.0f, 1.0f }; // World position of light source

// GL_C3F_V3F
struct Vertex
{
    float r, g, b;
    float x, y, z;
};

Vertex g_shadowCasterVerts[] =
{
    { 1.0, 1.0, 1.0,  -1.0f, 2.5f, -1.0f },
    { 1.0, 1.0, 1.0,  -1.0f, 2.5f,  1.0f },
    { 1.0, 1.0, 1.0,   1.0f, 2.5f,  1.0f },
    { 1.0, 1.0, 1.0,   1.0f, 2.5f, -1.0f },
};

float g_shadowCasterNormal[] = { 0.0f, 1.0f, 0.0f };

struct ShadowCaster
{
    Vertex *verts;        // Vertices of the actual shadow casting object
    float  *normal;       // A surface normal for lighting
    int     numVerts;     // Total number of vertices
    int     shadowVolume; // Display list for holding the shadow volume
};

ShadowCaster g_shadowCaster;

//-----------------------------------------------------------------------------
// PROTOTYPES
//-----------------------------------------------------------------------------
int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,
                   LPSTR lpCmdLine, int nCmdShow);
LRESULT CALLBACK WindowProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);
void loadTexture(void);
void init(void);
void render(void);
void shutDown(void);
void extendVertex(float newVert[3], float lightPosit[3], Vertex vert, float ext);
void buildShadowVolume(ShadowCaster *caster, float lightPosit[3], float ext);

//-----------------------------------------------------------------------------
// Name: WinMain()
// Desc: The application's entry point
//-----------------------------------------------------------------------------
int WINAPI WinMain( HINSTANCE hInstance,
                    HINSTANCE hPrevInstance,
                    LPSTR     lpCmdLine,
                    int       nCmdShow )
{
    WNDCLASSEX winClass;
    MSG        uMsg;

    memset(&uMsg,0,sizeof(uMsg));

    winClass.lpszClassName = "MY_WINDOWS_CLASS";
    winClass.cbSize        = sizeof(WNDCLASSEX);
    winClass.style         = CS_HREDRAW | CS_VREDRAW | CS_OWNDC;
    winClass.lpfnWndProc   = WindowProc;
    winClass.hInstance     = hInstance;
    winClass.hIcon         = LoadIcon(hInstance, (LPCTSTR)IDI_OPENGL_ICON);
    winClass.hIconSm       = LoadIcon(hInstance, (LPCTSTR)IDI_OPENGL_ICON);
    winClass.hCursor       = LoadCursor(NULL, IDC_ARROW);
    winClass.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);
    winClass.lpszMenuName  = NULL;
    winClass.cbClsExtra    = 0;
    winClass.cbWndExtra    = 0;
   
    if( !RegisterClassEx(&winClass) )
        return E_FAIL;

    g_hWnd = CreateWindowEx( NULL, "MY_WINDOWS_CLASS",
                             "OpenGL - Shadow Volume",
                             WS_OVERLAPPEDWINDOW | WS_VISIBLE,
                             0, 0, 640, 480, NULL, NULL, hInstance, NULL );

    if( g_hWnd == NULL )
        return E_FAIL;

    ShowWindow( g_hWnd, nCmdShow );
    UpdateWindow( g_hWnd );

    init();

    while( uMsg.message != WM_QUIT )
    {
        if( PeekMessage( &uMsg, NULL, 0, 0, PM_REMOVE ) )
        {
            TranslateMessage( &uMsg );
            DispatchMessage( &uMsg );
        }
        else
            render();
    }

    shutDown();

    UnregisterClass( "MY_WINDOWS_CLASS", winClass.hInstance );

    return uMsg.wParam;
}

//-----------------------------------------------------------------------------
// Name: WindowProc()
// Desc: The window's message handler
//-----------------------------------------------------------------------------
LRESULT CALLBACK WindowProc( HWND   hWnd,
                             UINT   msg,
                             WPARAM wParam,
                             LPARAM lParam )
{
    static POINT ptLastMousePosit_L;
    static POINT ptCurrentMousePosit_L;
    static bool  bMousing_L;
   
    static POINT ptLastMousePosit_R;
    static POINT ptCurrentMousePosit_R;
    static bool  bMousing_R;

    switch( msg )
    {
        case WM_KEYDOWN:
        {
            switch( wParam )
            {
                case VK_ESCAPE:
                    PostQuitMessage(0);
                    break;

                case VK_F1:
                    g_bRenderShadowVolume = !g_bRenderShadowVolume;
                    break;

                case VK_F2:
                    g_fAmountOfExtrusion += 0.1f;
                    break;

                case VK_F3:
                    g_fAmountOfExtrusion -= 0.1f;
                    break;

                case 38: // Up Arrow Key
                    g_lightPosition[1] += 0.1f;
                    break;

                case 40: // Down Arrow Key
                    g_lightPosition[1] -= 0.1f;
                    break;

                case 37: // Left Arrow Key
                    g_lightPosition[0] -= 0.1f;
                    break;

                case 39: // Right Arrow Key
                    g_lightPosition[0] += 0.1f;
                    break;
            }
        }
        break;

        case WM_LBUTTONDOWN:
        {
            ptLastMousePosit_L.x = ptCurrentMousePosit_L.x = LOWORD (lParam);
            ptLastMousePosit_L.y = ptCurrentMousePosit_L.y = HIWORD (lParam);
            bMousing_L = true;
        }
        break;

        case WM_LBUTTONUP:
        {
            bMousing_L = false;
        }
        break;

        case WM_RBUTTONDOWN:
        {
            ptLastMousePosit_R.x = ptCurrentMousePosit_R.x = LOWORD (lParam);
            ptLastMousePosit_R.y = ptCurrentMousePosit_R.y = HIWORD (lParam);
            bMousing_R = true;
        }
        break;

        case WM_RBUTTONUP:
        {
            bMousing_R = false;
        }
        break;

        case WM_MOUSEMOVE:
        {
            ptCurrentMousePosit_L.x = LOWORD (lParam);
            ptCurrentMousePosit_L.y = HIWORD (lParam);
            ptCurrentMousePosit_R.x = LOWORD (lParam);
            ptCurrentMousePosit_R.y = HIWORD (lParam);

            if( bMousing_L )
            {
                g_fSpinX_L -= (ptCurrentMousePosit_L.x - ptLastMousePosit_L.x);
                g_fSpinY_L -= (ptCurrentMousePosit_L.y - ptLastMousePosit_L.y);
            }
            
            if( bMousing_R )
            {
                g_fSpinX_R -= (ptCurrentMousePosit_R.x - ptLastMousePosit_R.x);
                g_fSpinY_R -= (ptCurrentMousePosit_R.y - ptLastMousePosit_R.y);
            }

            ptLastMousePosit_L.x = ptCurrentMousePosit_L.x;
            ptLastMousePosit_L.y = ptCurrentMousePosit_L.y;
            ptLastMousePosit_R.x = ptCurrentMousePosit_R.x;
            ptLastMousePosit_R.y = ptCurrentMousePosit_R.y;
        }
        break;
        
        case WM_SIZE:
        {
            int nWidth  = LOWORD(lParam);
            int nHeight = HIWORD(lParam);
            glViewport(0, 0, nWidth, nHeight);

            glMatrixMode( GL_PROJECTION );
            glLoadIdentity();
            gluPerspective( 45.0, (GLdouble)nWidth / (GLdouble)nHeight, 0.1, 100.0);
        }
        break;
        
        case WM_CLOSE:
        {
            PostQuitMessage(0);
        }
        break;

        case WM_DESTROY:
        {
            PostQuitMessage(0);
        }
        break;
        
        default:
        {
            return DefWindowProc( hWnd, msg, wParam, lParam );
        }
        break;
    }

    return 0;
}

//-----------------------------------------------------------------------------
// Name: extendVertex()
// Desc:
//-----------------------------------------------------------------------------
void extendVertex( float newVert[3], float lightPosit[3], Vertex vert, float ext )
{
    float lightDir[3];

    // Create a vector that points from the light's position to the original vertex.
    lightDir[0] = vert.x - lightPosit[0];
    lightDir[1] = vert.y - lightPosit[1];
    lightDir[2] = vert.z - lightPosit[2];

    // Then use that vector to extend the original vertex out to a new position.
    // The distance to extend or extrude the new vector is specified by t.
    newVert[0] = lightPosit[0] + lightDir[0] * ext;
    newVert[1] = lightPosit[1] + lightDir[1] * ext;
    newVert[2] = lightPosit[2] + lightDir[2] * ext;
}

//-----------------------------------------------------------------------------
// Name: buildShadowVolume()
// Desc:
//-----------------------------------------------------------------------------
void buildShadowVolume( ShadowCaster *caster, float lightPosit[3], float ext )
{
    if( caster->shadowVolume != -1 )
        glDeleteLists( caster->shadowVolume, 0 );

    caster->shadowVolume = glGenLists(1);

    glNewList( caster->shadowVolume, GL_COMPILE );
    {
        glDisable( GL_LIGHTING );

        glBegin( GL_QUADS );
        {
            glColor3f( 0.2f, 0.8f, 0.4f );

            float vExtended[3];

            //
            // For each vertex of the shadow casting object, find the edge
            // that it helps define and extrude a quad out from that edge.
            //
            
            for( int i = 0; i < caster->numVerts; ++i )
            {
                // Define the edge we're currently working on extruding...
                int e0 = i;
                int e1 = i+1;

                // If the edge's second vertex is out of array range,
                // place it back at 0
                if( e1 >= caster->numVerts )
                    e1 = 0;

                // v0 of our extruded quad will simply use the edge's first
                // vertex or e0.
                glVertex3f( caster->verts[e0].x,
                            caster->verts[e0].y,
                            caster->verts[e0].z );

                // v1 of our quad is created by taking the edge's first
                // vertex and extending it out by some amount.
                extendVertex( vExtended, lightPosit, caster->verts[e0], ext );
                glVertex3f( vExtended[0], vExtended[1], vExtended[2] );

                // v2 of our quad is created by taking the edge's second
                // vertex and extending it out by some amount.
                extendVertex( vExtended, lightPosit, caster->verts[e1], ext );
                glVertex3f( vExtended[0], vExtended[1], vExtended[2] );

                // v3 of our extruded quad will simply use the edge's second
                // vertex or e1.
                glVertex3f( caster->verts[e1].x,
                            caster->verts[e1].y,
                            caster->verts[e1].z );
            }
        }
        glEnd();

        glEnable( GL_LIGHTING );
    }
    glEndList();
}

//-----------------------------------------------------------------------------
// Name: init()
// Desc:
//-----------------------------------------------------------------------------
void init( void )
{
    GLuint PixelFormat;

    PIXELFORMATDESCRIPTOR pfd;
    memset(&pfd, 0, sizeof(PIXELFORMATDESCRIPTOR));

    pfd.nSize        = sizeof(PIXELFORMATDESCRIPTOR);
    pfd.nVersion     = 1;
    pfd.dwFlags      = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER;
    pfd.iPixelType   = PFD_TYPE_RGBA;
    pfd.cColorBits   = 16;
    pfd.cDepthBits   = 16;
    pfd.cStencilBits = 8;

    g_hDC = GetDC( g_hWnd );
    PixelFormat = ChoosePixelFormat( g_hDC, &pfd );
    SetPixelFormat( g_hDC, PixelFormat, &pfd);
    g_hRC = wglCreateContext( g_hDC );
    wglMakeCurrent( g_hDC, g_hRC );

    glClearColor( 0.35f, 0.53f, 0.7f, 1.0f );
    glEnable(GL_LIGHTING);
    glEnable(GL_LIGHT0);
    glEnable(GL_DEPTH_TEST);

    glMatrixMode( GL_PROJECTION );
    glLoadIdentity();
    gluPerspective( 45.0f, 640.0f / 480.0f, 0.1f, 100.0f);

    // Enable a single OpenGL light.
    float lightAmbient[] = {0.2f, 0.2f, 0.2f, 1.0f};
    float lightDiffuse[] = {1.0, 1.0, 1.0, 1.0};
    float lightSpecular[] = {1.0, 1.0, 1.0, 1.0};
    glLightfv(GL_LIGHT0, GL_DIFFUSE, lightDiffuse);
    glLightfv(GL_LIGHT0, GL_SPECULAR, lightSpecular);
    glLightfv(GL_LIGHT0, GL_AMBIENT, lightAmbient);

    //
    // Set up the shadow caster...
    //

    g_shadowCaster.verts        = g_shadowCasterVerts;
    g_shadowCaster.normal       = g_shadowCasterNormal;
    g_shadowCaster.numVerts     = (sizeof(g_shadowCasterVerts) / sizeof(Vertex));
    g_shadowCaster.shadowVolume = -1;
}

//-----------------------------------------------------------------------------
// Name: shutDown()
// Desc:
//-----------------------------------------------------------------------------
void shutDown( void )
{
    if( g_hRC != NULL )
    {
        wglMakeCurrent( NULL, NULL );
        wglDeleteContext( g_hRC );
        g_hRC = NULL;
    }

    if( g_hDC != NULL )
    {
        ReleaseDC( g_hWnd, g_hDC );
        g_hDC = NULL;
    }
}

//-----------------------------------------------------------------------------
// Name: render()
// Desc:
//-----------------------------------------------------------------------------
void renderScene( void )
{
    //
    // Place the view
    //
   
    glMatrixMode( GL_MODELVIEW );
    glLoadIdentity();
    glTranslatef( 0.0f, -2.0f, -15.0f );
    glRotatef( -g_fSpinY_L, 1.0f, 0.0f, 0.0f );
    glRotatef( -g_fSpinX_L, 0.0f, 1.0f, 0.0f );

    //
    // Render the floor...
    //

    glPushMatrix();
    {
        glBegin( GL_QUADS );
        {
            glNormal3f( 0.0f, 1.0f,  0.0f );
            glVertex3f(-5.0f, 0.0f, -5.0f );
            glVertex3f(-5.0f, 0.0f,  5.0f );
            glVertex3f( 5.0f, 0.0f,  5.0f );
            glVertex3f( 5.0f, 0.0f, -5.0f );
        }
        glEnd();
    }
    glPopMatrix();

    //
    // Render a teapot so we'll have something else to cast a shadow on  
    // besides the floor.
    //

    glPushMatrix();
    {
        glTranslatef( -2.0f, 0.8f, 0.0f );
        glRotatef( 180.0, 0.0f, 1.0f, 0.0f );
        glColor3f( 1.0f, 1.0f ,1.0f );
        renderSolidTeapot( 1.0);
    }
    glPopMatrix();

    //
    // Render the light's position as a sphere...
    //

    glDisable( GL_LIGHTING );

    glPushMatrix();
    {
        // Place the light...
        glLightfv( GL_LIGHT0, GL_POSITION, g_lightPosition );

        // Place a sphere to represent the light
        glTranslatef( g_lightPosition[0], g_lightPosition[1], g_lightPosition[2] );

        glColor3f(1.0f, 1.0f, 0.5f);
        renderSolidSphere( 0.1, 8, 8 );
    }
    glPopMatrix();

    glEnable( GL_LIGHTING );

    //
    // Render the shadow caster (i.e. the quad)
    //

    glPushMatrix();
    {
        // Hmmm... I can't transform the shadow caster unless the
        // buildShadowVolume function is able to take this into account.
        // This is because the shadow volume is built in world space.

        //glTranslatef( 0.0f, 2.5f, 0.0f );
        //glRotatef( -g_fSpinY_R, 1.0f, 0.0f, 0.0f );
        //glRotatef( -g_fSpinX_R, 0.0f, 1.0f, 0.0f );

        glBegin( GL_POLYGON );
        {
            glNormal3fv( g_shadowCaster.normal );

            for( int i = 0; i < g_shadowCaster.numVerts; ++i )
            {
                glVertex3f( g_shadowCaster.verts.x,
                            g_shadowCaster.verts.y,
                            g_shadowCaster.verts.z );
            }
        }
        glEnd();
    }
    glPopMatrix();
}

//-----------------------------------------------------------------------------
// Name: render()
// Desc:
//-----------------------------------------------------------------------------
void render( void )
{
    //
    // Using the light's position, extend or extrude each vertex of the shadow
    // caster out by an amount specified by g_fAmountOfExtrusion.
    //

    buildShadowVolume( &g_shadowCaster, g_lightPosition, g_fAmountOfExtrusion );

    //
    // Prepare to render a new scene by clearing out all of the buffers.
    //

    glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT );

    // Initialize the depth buffer by rendering the scene into it.
    glColorMask( GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE );
    renderScene();

    //
    // Create the special shadow stencil...
    //

    // Set the appropriate states for creating a stencil for shadowing.
    glEnable( GL_CULL_FACE );
    glEnable( GL_STENCIL_TEST );
    glDepthMask( GL_FALSE );
    glStencilFunc( GL_ALWAYS, 0, 0 );
   
    // Render the shadow volume and increment the stencil every where a front
    // facing polygon is rendered.
    glStencilOp( GL_KEEP, GL_KEEP, GL_INCR );
    glCullFace( GL_BACK );
    glCallList( g_shadowCaster.shadowVolume );

    // Render the shadow volume and decrement the stencil every where a back
    // facing polygon is rendered.
    glStencilOp( GL_KEEP, GL_KEEP, GL_DECR );
    glCullFace( GL_FRONT );
    glCallList( g_shadowCaster.shadowVolume );

    // When done, set the states back to something more typical.
    glDepthMask( GL_TRUE );
    glDepthFunc( GL_LEQUAL );
    glColorMask( GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE );
    glStencilOp( GL_KEEP, GL_KEEP, GL_KEEP );
    glCullFace( GL_BACK );
    glDisable( GL_CULL_FACE );

    //
    // Render the shadowed part...
    //

    glStencilFunc( GL_EQUAL, 1, 1 );
    glDisable( GL_LIGHT0 );
    renderScene();

    //
    // Render the lit part...
    //

    glStencilFunc( GL_EQUAL, 0, 1 );
    glEnable( GL_LIGHT0 );
    renderScene();

    // When done, set the states back to something more typical.
    glDepthFunc( GL_LESS );
    glDisable( GL_STENCIL_TEST);

    if( g_bRenderShadowVolume )
    {
        glPolygonMode( GL_FRONT_AND_BACK, GL_LINE );
        glCallList( g_shadowCaster.shadowVolume );
        glPolygonMode( GL_FRONT_AND_BACK, GL_FILL );
    }

    SwapBuffers( g_hDC );
}

3

主题

6

帖子

6

积分

新手上路

Rank: 1

积分
6
 楼主| 发表于 2011-4-19 23:33:00 | 显示全部楼层

Re: Re: stencil buffer shadow的问题

xhuixuanwen: Re: stencil buffer shadow的问题

//-----------------------------------------------------------------------------
//           Name: ...

例子我有。已经解决了。
最大的失误是没有在整个的glClear之前把各种mask都给打开
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

作品发布|文章投稿|广告合作|关于本站|游戏开发论坛 ( 闽ICP备17032699号-3 )

GMT+8, 2025-6-8 05:28

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表