1

我尝试在openGL中用一盏灯制作定向光,但我遇到了很大的麻烦。我将灯光位置设置为灯,但没有定向光效果。我指定了法线。此外,启用照明时对象的颜色存在问题。我试图设置glMaterial,但灯光效果隐藏起来。应该怎么做?

我的代码在这里:

#include "stdafx.h"
#include <windows.h> 
#include "glew.h"                                        
#include "tex.h"
#include <GL/glut.h>
#include <math.h>
#include <cmath>

const float pi = 3.1415926535897932384626433832795;

class Camera
{
public:
    static double alfa;
    static double wysokosc;
    static double wzrostAlfa;
    static double wzrostWysokosci;
    static double zoom;

    static void ustaw()
    {
        glScalef(zoom, zoom, zoom);
    }

    static void powieksz()
    {
        zoom += 0.25;
    }

    static void pomniejsz()
    {
        if (zoom <= 1)
        {
            zoom = 1;
            return;
        }
        zoom -= 0.25;
    }

    static double x() 
    {
        return 20 * sin(pi * alfa / 180.0);
    }

    static double y() 
    {
        return wysokosc;
    }

    static double z() 
    {
        return 20 * cos(pi * alfa / 180.0);
    }

    static void Prawo()
    {
        alfa += wzrostAlfa;
    }

    static void Lewo() 
    {
        alfa -= wzrostAlfa;
    }

    static void Gora()
    {
        wysokosc += wzrostWysokosci;
    }

    static void Dol() 
    {
        wysokosc -= wzrostWysokosci;
    }
};

class RuchomaFigura
{
protected:
    double promien;
    double x;
    double y;
    double z;
    float predkosc;
    int *tekstura;
    int kat;

public:
    /*
    *   r - promien
    *   p - maksymalna wysokosc unoszenia
    *   x, z - 'x' i 'z' z polozenia
    *   k - kierunek ruchu
    *   pr - predkosc ruchu
    */
    RuchomaFigura(double r, int *t, double x, double z, float pr):
        promien(r), tekstura(t), predkosc(pr), x(x), z(z) { }

    void odswiez() 
    {
        if (kat < 360)
        {
            kat += predkosc;
        }
        else
        {
            kat = predkosc;
        }

        glPushMatrix();
            glRotatef(kat, 0, 1, 0);
            rysuj();
        glPopMatrix();
    }

    virtual void rysuj() = 0;
};

class Pilka : public RuchomaFigura 
{
public:
    Pilka(double r, int *t, double x, double z, float pr):
      RuchomaFigura(r, t, x, z, pr) { }

    void rysuj()
    {
        GLUquadric *obiekt = gluNewQuadric();
        gluQuadricTexture(obiekt, GL_TRUE);

        glEnable(GL_TEXTURE_2D);
        glBindTexture(GL_TEXTURE_2D, *tekstura);
        glMatrixMode(GL_TEXTURE); 
        gluSphere(obiekt, promien, 30, 30);
        glDisable(GL_TEXTURE_2D);

        glMatrixMode(GL_MODELVIEW);
    }
};

double Camera::alfa = 0;
double Camera::wysokosc = 3;
double Camera::wzrostAlfa = 1.5;
double Camera::wzrostWysokosci = 0.5;
double Camera::zoom = 1;

int textures[5];

Pilka balls[] = {
    Pilka(0.4, &textures[2], 3.5, 3.5, 2),
};

void uklad()
{
    glBegin(GL_LINES);
        glColor3f(0.0, 1.0, 0.0); //zielona oś X
        glVertex3f(-5.0, 0.0, 0.0);
        glVertex3f(5.0, 0.0, 0.0); 

        glColor3f(0.0, 0.0, 1.0); // niebieska oś Y
        glVertex3f(0.0, -5.0, 0.0);
        glVertex3f(0.0,  5.0, 0.0);

        glColor3f(0.7,  0.7, 0.7); // czarna oś Z
        glVertex3f(0.0, 0.0, -5.0);
        glVertex3f(0.0, 0.0,  5.0);
    glEnd();
}

void prostopadloscian(float x, float y, float z, float red, float green, float blue)
{
    glColor3f(red, green, blue);

    glBegin(GL_POLYGON);
        glNormal3f(0, -1, 0);
        glVertex3f(-x,-y,-z);
        glVertex3f(x,-y,-z);
        glVertex3f(x,-y,z);
        glVertex3f(-x,-y,z);
    glEnd();

    glBegin(GL_POLYGON);
        glNormal3f(0,1,0);
        glVertex3f(-x,y,-z);
        glVertex3f(x,y,-z);
        glVertex3f(x,y,z);
        glVertex3f(-x,y,z);
    glEnd();

    glBegin(GL_POLYGON);
        glNormal3f(-1,0,0);
        glVertex3f(-x,y,z);
        glVertex3f(-x,-y,z);
        glVertex3f(-x,-y,-z);
        glVertex3f(-x,y,-z);
    glEnd();

    glBegin(GL_POLYGON);
        glNormal3f(0,0,-1);
        glVertex3f(-x,-y,-z);
        glVertex3f(x,-y,-z);
        glVertex3f(x,y,-z);
        glVertex3f(-x,y,-z);
    glEnd();

    glBegin(GL_POLYGON);        
        glNormal3f(1,0,0);
        glVertex3f(x,y,z);
        glVertex3f(x,-y,z);
        glVertex3f(x,-y,-z);
        glVertex3f(x,y,-z);
    glEnd();

    glBegin(GL_POLYGON);
        glNormal3f(0,0,1);
        glVertex3f(-x,y,z);
        glVertex3f(-x,-y,z);
        glVertex3f(-x,-y,-z);
        glVertex3f(-x,y,-z);
    glEnd();
}

void krzeslo()
{
    // nogi krzesla
    glPushMatrix();
        glTranslatef(-0.8, 0, 0.8);
        prostopadloscian(0.1, 1.0, 0.1, 0.35, 0.16, 0.14);
    glPopMatrix();
    glPushMatrix();
        glTranslatef(0.8, 0, 0.8);
        prostopadloscian(0.1, 1.0, 0.1, 0.35, 0.16, 0.14);
    glPopMatrix();
    glPushMatrix();
        glTranslatef(-0.8, 0, -0.8);
        prostopadloscian(0.1, 1.0, 0.1, 0.35, 0.16, 0.14);
    glPopMatrix();
    glPushMatrix();
        glTranslatef(0.8, 0, -0.8);
        prostopadloscian(0.1, 1.0, 0.1, 0.35, 0.16, 0.14);
    glPopMatrix();

    // siedzenie
    glPushMatrix();
        glTranslatef(0.0, 1.101, 0.0);
        prostopadloscian(1, 0.1, 1, 0.65, 0.50, 0.39);
    glPopMatrix();

    glPushMatrix();
    glTranslatef(0.0, 0.201, 0.0);
    // oparcie
    // krawedzie boczne oparcia
    glPushMatrix();
        glTranslatef(-0.8, 2.0, -0.8);
        prostopadloscian(0.1, 1.0, 0.1, 0.35, 0.16, 0.14);
    glPopMatrix();

    glPushMatrix();
        glTranslatef(0.8, 2.0, -0.8);
        prostopadloscian(0.1, 1.0, 0.1, 0.35, 0.16, 0.14);
    glPopMatrix();

    // dolna krawedz oparcia
    glPushMatrix();
        glTranslatef(0.0, 1.85, -0.8);
        prostopadloscian(0.7, 0.1, 0.1, 0.35, 0.16, 0.14);
    glPopMatrix();

    // tralki krzesla
    // tralka srodkowa
    glPushMatrix();
        glTranslatef(-0.0, 2.35, -0.8);
        prostopadloscian(0.05, 0.4, 0.05, 0.35, 0.16, 0.14);
    glPopMatrix();

    glPushMatrix();
        glTranslatef(-0.4, 2.35, -0.8);
        prostopadloscian(0.05, 0.4, 0.05, 0.35, 0.16, 0.14);
    glPopMatrix();

    glPushMatrix();
        glTranslatef(0.4, 2.35, -0.8);
        prostopadloscian(0.05, 0.4, 0.05, 0.35, 0.16, 0.14);
    glPopMatrix();
    // tralki krzesla

    // gorna krawedz oparcia
    glPushMatrix();
        glTranslatef(0.0, 2.85, -0.8);
        prostopadloscian(0.7,0.1,0.1, 0.35, 0.16, 0.14);
    glPopMatrix();
    // koniec oparcia
    glPopMatrix();
}

void szafa()
{
    // rama 
    glPushMatrix();
        glTranslatef(0.0, -3.0, 0.0);
        prostopadloscian(1.3, 0.1, 1.0, 0.35, 0.16, 0.14);
    glPopMatrix();
    glPushMatrix();
        glTranslatef(0.0, 3.0, 0.0);
        prostopadloscian(1.3, 0.1, 1.0, 0.35, 0.16, 0.14);
    glPopMatrix();
    glPushMatrix();
        glTranslatef(-1.2, 0.0, 0.0);
        prostopadloscian(0.1, 3.0, 1.0, 0.35, 0.16, 0.14);
    glPopMatrix();
    glPushMatrix();
        glTranslatef(1.2, 0.0, 0.0);
        prostopadloscian(0.1, 3.0, 1.0, 0.35, 0.16, 0.14);
    glPopMatrix();

    // tylna sciana
    glPushMatrix();
        glTranslatef(0.0, 0.0, -0.9);
        prostopadloscian(1.1, 2.9, 0.1, 0.59, 0.41, 0.31);
    glPopMatrix();


    // przednia część
    glPushMatrix();
        glTranslatef(-0.2, 0.0, 1.7);
        glRotatef(-30.0, 0.0, 1.0, 0.0);
        prostopadloscian(1.1, 2.9, 0.1, 0.91, 0.76, 0.65);
    glPopMatrix();


    // uchwyt
    glPushMatrix();
        glTranslatef(0.5, 0.0, 2.2);
        glRotatef(-30.0, 0.0, 1.0, 0.0);
        prostopadloscian(0.1, 0.1, 0.1, 0.35, 0.16, 0.14);
    glPopMatrix();
}

void stolik()
{
    // nogi
    glPushMatrix();
        glTranslatef(-0.8, 0, 1.8);
        prostopadloscian(0.1, 1.4, 0.1, 0.35, 0.16, 0.14);
    glPopMatrix();
    glPushMatrix();
        glTranslatef(0.8, 0, 1.8);
        prostopadloscian(0.1, 1.4, 0.1, 0.35, 0.16, 0.14);
    glPopMatrix();
    glPushMatrix();
        glTranslatef(-0.8, 0, -1.8);
        prostopadloscian(0.1, 1.4, 0.1, 0.35, 0.16, 0.14);
    glPopMatrix();
    glPushMatrix();
        glTranslatef(0.8, 0, -1.8);
        prostopadloscian(0.1, 1.4, 0.1, 0.35, 0.16, 0.14);
    glPopMatrix();

    // blat
    glPushMatrix();
        glTranslatef(0.0, 1.5, 0.0);
        prostopadloscian(1, 0.1, 2, 0.35, 0.16, 0.14);
    glPopMatrix();

    // zeszyt
    glPushMatrix();
        glTranslatef(0.0, 1.701, 1.0);
        glRotatef(50.0, 0.0, 1.0, 0.0);
        prostopadloscian(0.3, 0.1, 0.5, 0.81, 0.71, 0.23);
    glPopMatrix();
}

void lozko()
{
    glPushMatrix();
        glTranslatef(-1.6, 0, 4.6);
        prostopadloscian(0.2, 0.25, 0.2, 0.35, 0.16, 0.14);
    glPopMatrix();
    glPushMatrix();
        glTranslatef(1.6, 0, 4.6);
        prostopadloscian(0.2, 0.25, 0.2, 0.35, 0.16, 0.14);
    glPopMatrix();
    glPushMatrix();
        glTranslatef(-1.6, 0, -4.6);
        prostopadloscian(0.2, 0.25, 0.2, 0.35, 0.16, 0.14);
    glPopMatrix();
    glPushMatrix();
        glTranslatef(1.6, 0, -4.6);
        prostopadloscian(0.2, 0.25, 0.2, 0.35, 0.16, 0.14);
    glPopMatrix();

    glPushMatrix();
        glTranslatef(0.0, 0.559, 0.0);
        prostopadloscian(2,0.3,5,0.85,0.85,0.95);
    glPopMatrix();


    // poduszki
    glPushMatrix();
        glTranslatef(0.0, 1.1, -4.0);
        prostopadloscian(1.3,0.2,0.6,0.137255,0.419608,0.556863);
    glPopMatrix();
    glPushMatrix();
        glTranslatef(0.0, 1.1, 4.0);
        prostopadloscian(1.3,0.2,0.6,0.137255,0.419608,0.556863);
    glPopMatrix();
}

void polka()
{
    glPushMatrix();
        prostopadloscian(2.5, 0.1, 0.5, 0.35, 0.16, 0.14);
    glPopMatrix();
    glPushMatrix();
        glTranslatef(-2.6, 0, 0);
        prostopadloscian(0.1, 0.25, 0.5, 0.35, 0.16, 0.14);
    glPopMatrix();
    glPushMatrix();
        glTranslatef(2.6, 0, 0);
        prostopadloscian(0.1, 0.25, 0.5, 0.35, 0.16, 0.14);
    glPopMatrix();

    // ksiazki
    // pierwsza od lewej
    glPushMatrix();
        glTranslatef(-1.5, 0.601, 0.0);
        prostopadloscian(0.2, 0.5, 0.3, 0.59, 0.41, 0.31);
    glPopMatrix();
    // druga
    glPushMatrix();
        glTranslatef(-1.0, 0.601, 0.0);
        prostopadloscian(0.2, 0.5, 0.3, 0.0, 0.0, 0.0);
    glPopMatrix();
    // ostatnia
    glPushMatrix();
        glTranslatef(-0.45, 0.601, 0.0);
        glRotatef(30.0, 0, 0, 1);
        prostopadloscian(0.1, 0.5, 0.3, 0.81, 0.71, 0.23);
    glPopMatrix();
}


void lampa()
{
    glPushMatrix();
        prostopadloscian(0.05, 1.0, 0.05, 0.5f, 0.35f, 0.05f);
    glPopMatrix();
    glPushMatrix();
        glTranslatef(0.0, -1.2, 0);
        prostopadloscian(0.7, 0.2, 0.7, 1.0f, 1.0f, 1.0f);
    glPopMatrix();
}

void lampka()
{
    glPushMatrix();
        glTranslatef(0.0, 0.01, 0);
        prostopadloscian(0.3, 0.05, 0.2, 0.0f, 0.0f, 0.0f);
    glPopMatrix();
    glPushMatrix();
        glTranslatef(0.0, 0.651, 0);
        prostopadloscian(0.05, 0.6, 0.05, 0.90, 0.91, 0.98);
    glPopMatrix();
    glPushMatrix();
        glTranslatef(0.0, 1.651, 0);
        prostopadloscian(0.4, 0.4, 0.4, 0.91, 0.76, 0.65);
    glPopMatrix();
}

void obraz()
{
    // Ramka
    glPushMatrix();
        glTranslatef(0.0, -2.0, -7.8);
        glPushMatrix();
            prostopadloscian(2.1, 0.1, 0.1, 0.35, 0.16, 0.14);
            glTranslatef(0.0, 4.1, 0.0);
            prostopadloscian(2.1, 0.1, 0.1, 0.35, 0.16, 0.14);
            glTranslatef(-2.0, -2.1, 0.0);
            prostopadloscian(0.1, 2.0, 0.1, 0.35, 0.16, 0.14);
            glTranslatef(4.0, 0.0, 0.0);
            prostopadloscian(0.1, 2.0, 0.1, 0.35, 0.16, 0.14);
        glPopMatrix();
    glPopMatrix();

    // Obraz
    glEnable(GL_TEXTURE_2D);
    glBindTexture(GL_TEXTURE_2D, textures[4]);
    glTexEnvi(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_REPLACE);
    glMatrixMode(GL_TEXTURE);

    glBegin(GL_POLYGON);
        glNormal3f(0,0,1);
        glTexCoord2f(0,0);
        glVertex3f(-1.9,-1.9,-7.7);
        glTexCoord2f(0,1);
        glVertex3f(-1.9,2,-7.7);
        glTexCoord2f(1,1);
        glVertex3f(1.9,2,-7.7);
        glTexCoord2f(1,0);
        glVertex3f(1.9,-1.9,-7.7);
    glEnd();

    glDisable(GL_TEXTURE_2D);
    glMatrixMode(GL_MODELVIEW);
}

void pokoj()
{
    // Podłoga
    glEnable(GL_TEXTURE_2D);
    glBindTexture(GL_TEXTURE_2D, textures[0]);
    glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
    glMatrixMode(GL_TEXTURE);

    glBegin(GL_POLYGON);
        glNormal3f(0,1,0);
        glTexCoord2f(-5,-8);
        glVertex3f(-5,-5,-8);
        glTexCoord2f(5,-8);
        glVertex3f(5,-5,-8);
        glTexCoord2f(5,8);
        glVertex3f(5,-5,8);
        glTexCoord2f(-5,8);
        glVertex3f(-5,-5,8);
    glEnd();

    glDisable(GL_TEXTURE_2D);
    glMatrixMode(GL_MODELVIEW);

    glBegin(GL_POLYGON);
        // Ściana przy łózku
        glColor3f(0.847059, 0.847059, 0.74902);
        glNormal3f(1,0,0);
        glVertex3f(-5,5,8);
        glVertex3f(-5,-5,8);
        glVertex3f(-5,-5,-8);
        glVertex3f(-5,5,-8);
    glEnd();

    glBegin(GL_POLYGON);
        // Ściana z obrazem
        glColor3f(0.867059, 0.857059, 0.75902);
        glNormal3f(0,0,1);
        glVertex3f(-5,-5,-8);
        glVertex3f(5,-5,-8);
        glVertex3f(5,5,-8);
        glVertex3f(-5,5,-8);
    glEnd();
}

void init()
{
    glClearColor(1.0, 1.0, 1.0, 1.0); //kolor tła okna
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 
    glEnable(GL_DEPTH_TEST);
    glMatrixMode(GL_PROJECTION);
    gluPerspective(60.0, 1.0, 1.0, 20.0); 

    glMatrixMode(GL_MODELVIEW); // nic więcej na stosie rzutowania
                                // się nie znajdzie   
    glEnable(GL_LIGHTING);
    glEnable(GL_LIGHT0);

    float lightPosition[] = { 0.0f, 2.0f, 0.0f, 0.0f };
    float lightDirection[] = { 0.0f, -2.0f, 0.0f };
    glLightfv(GL_LIGHT0, GL_POSITION, lightPosition);
    glLightfv(GL_LIGHT0, GL_SPOT_DIRECTION, lightDirection);

    textures[0] = setTexture("floor.bmp", GL_REPLACE);
    textures[1] = setTexture("basketball.bmp", GL_REPLACE);
    textures[2] = setTexture("football.bmp", GL_REPLACE);

    textures[4] = setTexture("obraz.bmp", GL_REPLACE);
}

void display() 
{
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    glLoadIdentity();

    gluLookAt(Camera::x(), Camera::y(), Camera::z(), 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);

    Camera::ustaw();

    // uklad();

    pokoj();

    obraz();

    glPushMatrix();
        glTranslatef(-2.999, -4.749, 2.0);
        lozko();
    glPopMatrix();

    glPushMatrix();
        glRotatef(90.0f, 0.0f, 1.0f, 0.0f);
        glTranslatef(-2.0, 0.5, -4.499);
        polka();
    glPopMatrix();

    glPushMatrix();
        glRotatef(98.0f, 0.0f, 1.0f, 0.0f);
        glTranslatef(3.5, -3.999, 3.0);
        krzeslo();
    glPopMatrix();

    glPushMatrix();
        glTranslatef(4.0, -3.599, -4.0);
        stolik();
    glPopMatrix();

    glPushMatrix();
        glTranslatef(0.0, 4.0, 0.0);
        lampa();
    glPopMatrix();

    glPushMatrix();
        glTranslatef(4.5, -1.95, -5.0);
        lampka();
    glPopMatrix();

    glPushMatrix();
        glRotatef(90.0f, 0.0f, 1.0f, 0.0f);
        glTranslatef(5.5, -1.85, -3.9);
        szafa();
    glPopMatrix();

    for (int i = 0; i < sizeof balls / sizeof(Pilka); i++) 
    {
        balls[i].odswiez();
    }

    // linka od piłki
    glBegin(GL_LINES);
        glColor3f(0.0, 0.0, 0.0);
        glVertex3f(0.0, 0.401, 0.0);
        glVertex3f(0.0, 2.60, 0.0);
    glEnd();

    glFlush();
    glutSwapBuffers();
}

void timer(int v) 
{
    glutPostRedisplay();
    glutTimerFunc(1000/60, timer, v);
}

void reshape(GLint w, GLint h) 
{
    glViewport(0, 0, w, h);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    gluPerspective(40.0, GLfloat(w) / GLfloat(h), 1.0, 150.0);
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
}

void klawiatura(unsigned char znak, int, int) 
{
    switch (znak) 
    {
        case 'e':
            Camera::powieksz();
        break;

        case 'q':
            Camera::pomniejsz();
        break;

        case 'a': 
            Camera::Lewo(); 
        break;

        case 'd':
            Camera::Prawo();  
        break;

        case 'w': 
            Camera::Gora();
        break;

        case 's':
            Camera::Dol();
        break;
    }

    glutPostRedisplay();
}

int main(int argc, char* args[])
{
    glutInit(&argc, args);
    glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH);
    glutInitWindowPosition(80, 80);
    glutInitWindowSize(800, 600);
    glutCreateWindow("Projekt");
    glutDisplayFunc(display);
    glutReshapeFunc(reshape);
    glutKeyboardFunc(klawiatura);  
    glutTimerFunc(100, timer, 0);
    init();
    glutMainLoop();
}
4

2 回答 2

2

首先,我没有看到您在任何地方设置浅色。默认情况下,GL_SPECULAR 设置为(1.0, 1.0, 1.0, 1.0)并且GL_AMBIENTGL_DIFFUSE设置为(0.0, 0.0, 0.0, 0.0)。除非您的材质有镜面反射组件,否则您不会看到任何变化。你至少应该设置GL_DIFFUSE一些有意义的东西。

其次,如果您期待聚光灯效果,例如,在地板上创建一圈光,您需要设置GL_SPOT_CUTOFF一些小角度。默认情况下,它是 180 度,为您提供 360 度的“锥形”光。

见:http ://www.glprogramming.com/red/chapter05.html#name4

于 2012-06-22T21:17:12.893 回答
0

为定向光指定 GL_SPOT_DIRECTION 是没有意义的,它不能是聚光灯。既然你说“用灯做定向光”,我不确定你是否理解定向光是无限远的,就像太阳一样。

于 2012-06-22T23:04:51.287 回答