1

I try to make a directional light from a lamp in openGL, but I have a big trouble with that. I set the light positon to the lamp, but there is no the directional light effect. I have normals specified. In addition, there is an issue with colours of the objects while the lighting is enabled. I tried to set glMaterial, but the light effect hide out than. How it should be done?

My code is here:

#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 に答える