在OpenGL中添加阴影

Adding Shadow in OpenGL

本文关键字:阴影 添加 OpenGL      更新时间:2023-10-16

我有一个非常简单的代码,它只是绘制建筑物,我想添加建筑物的阴影。我尝试了许多代码样本,但是要么绘制的对象太复杂了。或太模糊了。我如何获得建筑物的阴影?

#include "GLee/GLee.h" //GL header file, including extensions
#include "glut.h"
#include <stdio.h>
#include <conio.h>
#include <math.h>
#include "tga.h"
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <stdio.h>
char  g_SelectedColor = 'w';
int   g_Width;
int   g_Height;
int a=0.0 ,b=0.0, c=500, d=0.0, e=0.0, f=0.0,g=0.0,h=1.0,i=0.0;
static int rotationAngle=0;
void init();
void myMouseFunction( int button, int state, int mouseX, int mouseY );
void myKeyboardFunction( unsigned char key, int mouseX, int mouseY );
void Reshape( int width, int height );
void timer( int val );
void display();
void drawBuilding();
void menu(int);
// Assign a default value
float light_diffuse[]   = { 0.8, 0.8, 0.8, 1.0 };
float light_ambient[]   = { 0.1, 1.1, 0.0, 0.0 };
float light_specular[]  = { 0.5, 0.5, 0.9, 1.0 };
float light_position[]  = { 0.0, 10.0, 0.0, 1.0 };
void selectMessage( int val )
{
    if(val==2)
    {
    glBegin(GL_POLYGON);
        glVertex3f(0.0,0.0,0.0);
        glVertex3f(0.0,200.0,0.0);
        glVertex3f(200.0,200.0,0.0);
        glVertex3f(200.0,0.0,0.0);
        glVertex3f(0.0,0.0,0.0);
    glEnd();
    }
}
int main(int argc, char** argv)
{
    glutCreateMenu(menu);
        glutAddMenuEntry("View1", 1);
        glutAddMenuEntry("View2", 2);
        glutAttachMenu(GLUT_RIGHT_BUTTON);

    g_Width =1200; g_Height = 600;
    glutInitDisplayMode( GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
   // glutInitWindowSize( g_Width, g_Height ); 
    //glutFullScreen();
    glutInitWindowPosition( 50, 50 );
    glutCreateWindow( "CHECK" );
    init();
    glutMouseFunc( myMouseFunction );
    glutKeyboardFunc( myKeyboardFunction );
    glutReshapeFunc( Reshape );
    glutDisplayFunc( display ); 
    glutMainLoop();
    return 0;
}
void init(void) 
{
   glutAttachMenu(GLUT_RIGHT_BUTTON);
    glClearColor( 1.0, 1.0, 1.0, 1.0 );
    glMatrixMode( GL_PROJECTION );
    glLoadIdentity();
    gluPerspective( 50.0, 1.0, 200, 1000 );
    //glOrtho( -5.0, +5.0, -5.0, +5.0, +5.0, -5.0 );
    glLightfv(GL_LIGHT0, GL_DIFFUSE,  light_diffuse);
    glLightfv(GL_LIGHT0, GL_AMBIENT,  light_ambient );
    glLightfv(GL_LIGHT0, GL_SPECULAR, light_specular );
    glLightfv(GL_LIGHT0, GL_POSITION, light_position);
    glShadeModel(GL_SMOOTH);
    //glShadeModel(GL_FLAT);
    glEnable(GL_LIGHTING);
    glEnable(GL_LIGHT0);
    glEnable(GL_DEPTH_TEST);
    //glCullFace(GL_FRONT_AND_BACK );
    glDisable(GL_CULL_FACE );
    glMatrixMode( GL_MODELVIEW );
    if ( loadTGA ("im1.tga", 10 ) == false )
        printf ("nError: File myQuakeTexture.tga not found!");
    if ( loadTGA ("im2.tga", 11 ) == false )
        printf ("nError: File myQuakeTexture.tga not found!");
}
void myMouseFunction( int button, int state, int mouseX, int mouseY ) 
{
}
void myKeyboardFunction( unsigned char key, int mouseX, int mouseY )
{
    switch( key )
    {
    case 'r':
        {
        glClearColor( 0.0, 0.0, 1.0, 1.0 );
        glRotatef( rotationAngle++, 0.0, 1.0, 0.0 );
    //  drawBuilding();
        //display();
        }
    case 'R':
    case 'g':
    case 'G':
    case 'b':
    case 'B':
    case 'w':
    case 'W':
        g_SelectedColor = key;
        break;
    case '1':
    case '2':
    case '3':
    case '4':
    case '5':
        break;
    case 27:  // Esc key
        exit(0);
        break;  // redundant
    default:
        break;
    }
}
void Reshape( int width, int height )
{
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    g_Width  = width; 
    g_Height = height;
    glViewport (0, 0, g_Width, g_Height);
    glMatrixMode (GL_PROJECTION);
    glLoadIdentity ();
    gluPerspective( 50.0, 1.0, 200, 1000 );
    //glOrtho( -5.0, +5.0, -5.0, +5.0, +5.0, -5.0 );;
}
void timer( int val )
{
    display();
}
static float firstAngle=0;
void drawBuilding()
{
    float DoorMaterial[4] = { 0.5, 0.2, 1.3, 1.0 };
    //
    glEnable(GL_TEXTURE_2D);
    glBindTexture(GL_TEXTURE_2D ,10);
    glTranslatef(30,-180,0);
    //Building 1
    //Front
    glBegin(GL_POLYGON);
        glVertex3f(0.0,0.0,0.0);
        glTexCoord2d(1,1);
        glVertex3f(0.0,400.0,0.0);
        glTexCoord2d(0,1);
        glVertex3f(70.0,400.0,0.0);
        glTexCoord2d(0,0);
        glVertex3f(70.0,0.0,0.0);
        glTexCoord2d(1,0);
        glVertex3f(0.0,0.0,0.0);
    glEnd();
    //Back
        glBegin(GL_POLYGON);
        glVertex3f(0.0,0.0,-50.0);
        glTexCoord2d(1,1);
        glVertex3f(0.0,400.0,-50.0);
        glTexCoord2d(0,1);
        glVertex3f(70.0,400.0,-50.0);
        glTexCoord2d(0,0);
        glVertex3f(70.0,0.0,-50.0);
        glTexCoord2d(1,0);
        glVertex3f(0.0,0.0,-50.0);
    glEnd();
    //Left
        glBegin(GL_POLYGON);
        glVertex3f(0.0,0.0,0.0);
        glTexCoord2d(1,1);
        glVertex3f(0.0,400.0,0.0);
        glTexCoord2d(0,1);
        glVertex3f(0.0,400.0,-50.0);
        glTexCoord2d(0,0);
        glVertex3f(0.0,0.0,-50.0);
        glTexCoord2d(1,0);
        glVertex3f(0.0,0.0,0.0);
    glEnd();
    //Right
        glBegin(GL_POLYGON);
        glVertex3f(70.0,0.0,0.0);
        glTexCoord2d(1,1);
        glVertex3f(70.0,400.0,0.0);
        glTexCoord2d(0,1);
        glVertex3f(70.0,400.0,-50.0);
        glTexCoord2d(0,0);
        glVertex3f(70.0,0.0,-50.0);
        glTexCoord2d(1,0);
        glVertex3f(70.0,0.0,0.0);
    glEnd();
    glEnable(GL_TEXTURE_2D);
    glBindTexture(GL_TEXTURE_2D ,11);
}
void menu(int item)
{
        switch (item)
        {
        case 1:
            {
                a=-500, b=0, c=300,d=0,e=0,f=0,g=0,h=1,i=0;

            }
                break;
        case 2:
            {
                a=0, b=300, c=500,d=0,e=0,f=0,g=0,h=1,i=0;
          drawBuilding();
            }
        }
}
void display()
{
    glRotatef( rotationAngle++, 0.0, 1.0, 0.0 );
    glutFullScreen();
    glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
    gluLookAt( a, b, c, 
               d, e,  f, 
               g, h, i );
    glRotatef( rotationAngle++, 0.0, 1.0, 0.0 );
    //
    drawBuilding();
    glDisable(GL_TEXTURE_2D);

    // this tells glut to call the 'timer' function in 33 milliseconds
    // i.e. this way we will draw 1000/33 = 30 times a second
    glutTimerFunc( 33, timer, 0 ); 
    glutSwapBuffers();
    printf(".");
}

在开放式场景中具有阴影并不是简单地启用某些功能的问题。OpenGL本身只是绘制点,线和三角形。一个一次,没有任何背景。这取决于用户提供上下文。

绘图阴影可以通过多种方式实现,但最常用的是

  • 模板音量阴影

  • 影子映射

在这里解释它们将在很大程度上超过堆叠问题的限制。因此,我将您的Wikipedia文章(以及这些链接的资源)

提及您
  • http://en.wikipedia.org/wiki/shadow_volume

  • http://en.wikipedia.org/wiki/shadow_mapping