c++ - 在 OpenGL 中添加阴影

标签 c++ opengl graphics shadow

<分区>

我有一个非常简单的代码,就是画一个建筑物,我想添加建筑物的阴影。我已经尝试了很多代码示例,但是它们要么太复杂,要么绘制了一堆对象。或者只是太模糊了。我怎样才能得到我的建筑物的影子?

#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 渲染场景中拥有阴影并不是简单启用某些功能的问题。 OpenGL 本身只绘制点、线和三角形。一次一个,它们之间没有任何上下文。由用户提供上下文。

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

  • 模板体积阴影

  • 阴影映射

在这里解释它们将大大超出 StackOverflow 问题的限制。因此,我建议您引用有关它们的维基百科文章(以及这些文章链接的资源)

关于c++ - 在 OpenGL 中添加阴影,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13002130/

相关文章:

c++ - 在 Emscripten 和 Qt 之间共享 OpenGL 代码

c++ - 在 OpengL 中多次重复图像

c++ - 以管理员身份创建进程并获取其 ProcessInformation Like ProcessID

c++ - 调用 boost::ip::tcp::resolver::query 时出现段错误

java - libGDX:使用着色器的图像外发光

opengl - 分形的连续着色

c# - 在 C# 中向图像添加 EXIF 信息

opengl - OpenGL 中的计算着色器有指令限制吗?

c++ - 链接多个 ShellExecute 调用

C++ 模板类重载 [] 运算符