Прожекторы OpenGL

#c #opengl #lighting

#c #opengl #Освещение

Вопрос:

Я пытаюсь создать «прожекторы» над бильярдным столом в OpenGL. Это должно быть довольно просто, но что-то идет не так, и я не могу понять, что именно.

У меня есть класс PoolLight, который я использую как своего рода класс хранения для источников света. Вот это:

 #include "PoolLight.h"
#include "Glut/glut.h"
#include "GL/gl.h"
#include "GL/glu.h"

PoolLight::PoolLight() {

}

PoolLight::PoolLight(GLenum lightNumber, GLenum lightType, float red, float green, float blue, bool distant, float posX, float posY, float posZ)
{
    this->lightNumber = lightNumber;
    this->lightType = lightType;

    color[0] = red; color[1] = green; color[2] = blue; color[3] = 1;
    position[0] = posX; position[1] = posY; position[2] = posZ; position[3] = (int) (!distant);
    glLightfv(lightNumber, lightType, color);
    glLightfv(lightNumber, GL_POSITION, position);

    enabled(true);
}


PoolLight::~PoolLight(void)
{
}

void PoolLight::setSpotlight(float angle, float attenuation, float dirX, float dirY, float dirZ) {
    glLightf(lightNumber, GL_SPOT_EXPONENT, angle);
    glLightf(lightNumber, GL_CONSTANT_ATTENUATION, attenuation);
    glLightf(lightNumber, GL_LINEAR_ATTENUATION, 0.0f);
    glLightf(lightNumber, GL_QUADRATIC_ATTENUATION, 0.0f);
    spotDirection[0] = dirX; spotDirection[1] = dirY; spotDirection[2] = dirZ;
    glLightfv(lightNumber, GL_SPOT_DIRECTION, spotDirection);
    glLightf(lightNumber, GL_SPOT_CUTOFF, 60);
}

void PoolLight::enabled(bool enabled) {
    if (enabled) glEnable(lightNumber);
    else glDisable(lightNumber);
}

void PoolLight::reposition() {
    glLightfv(lightNumber, GL_POSITION, position);
}
  

И в Display::Init у меня есть этот код:

 glEnable(GL_TEXTURE_2D);
glEnable(GL_DEPTH_TEST);
glEnable(GL_LIGHTING);
glPointSize(6);

//Lighting
middleSpotlight = PoolLight(GL_LIGHT0, GL_DIFFUSE, .3, .3, 0.15, false, 0, 0, 50);
middleSpotlight.setSpotlight(60, 1, 0, 0, -1);
upperSpotlight = PoolLight(GL_LIGHT1, GL_DIFFUSE, .3, .3, 0.15, false, 0, 45, 50);
upperSpotlight.setSpotlight(60, 1, 0, 0, -1);
lowerSpotlight = PoolLight(GL_LIGHT2, GL_DIFFUSE, .3, .3, 0.15, false, 0, -45, 50);
lowerSpotlight.setSpotlight(60, 1, 0, 0, -1);
  

Однако, даже при отключении всех прожекторов, кроме среднего, моя сцена равномерно освещена своего рода «общим» освещением.

Я чувствую, что, вероятно, упускаю что-то очевидное, но я просто не вижу, что.

Комментарии:

1. Разве углы не указаны в радианах? С 60 в качестве вашего угла кажется, что вы используете градусы.

2. Я изменил его на (60.0 * (3.1415 / 180)), но безрезультатно.

3. Хм, я не могу думать ни о чем другом прямо сейчас — извините.

4. Удаляет ли отключение всех прожекторов освещение? Если вы измените настройки на точечные светильники, будет ли освещение вести себя так, как ожидалось? Отправляете ли вы правильные нормали на видеокарту?

Ответ №1:

Это связано с тем, как конвейер фиксированных функций OpenGL по умолчанию реализует освещение: освещение оценивается только в вершинах, результирующий цвет интерполируется по поверхности. Если вся ваша таблица состоит всего из одного большого квадрата, происходит именно это.

Решение 1. Разделите сетку в высокой степени.

Решение 2. Замените освещение фиксированной функции шейдером подсветки для каждого фрагмента.

Комментарии:

1. Сетка уже состояла из 20 треугольников, но я только что сделал ее 200, и никакой разницы. Мне приходится использовать фиксированную функцию lighting (это часть курсовой работы), и сейчас у меня действительно нет времени изучать другие методы. :< Хотите скриншот?

2. Да, пожалуйста, предоставьте несколько скриншотов, а также некоторый код, показывающий, как вы рисуете саму сетку.