我尝试在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();
}