我将opengl用于教育目的,但是创建多个聚光灯来代表路灯时遇到了麻烦。我使用一个迭代器来创建多个迭代器,但是最后只有最后一个聚光灯发光,我相信问题出在addlight方法中,但是我不知道发生了什么。

在下图中,您可以看到发生的情况。

https://imgur.com/Y77eHln

#include "CreateLamps.h"

std::vector<SpotLight> lamp;

CreateLamps::CreateLamps(int number) {

    for (int i = 0; i < number; i++) {
        SpotLight *spot = new SpotLight(-8.0f, 5.f, (i*10) + 30.0f, 1.f);
        lamp.push_back(*spot);
    }

}

void CreateLamps::Add() {

    std::vector<SpotLight>::iterator it = lamp.begin();

    while (it != lamp.end())
    {

        glPushMatrix();
        glTranslatef(1, 0, 30.0);
        glTranslatef(it->position[0], it->position[3] * 3, it->position[2]);
        glRotatef(100.f, -5.0, -10, 0);
        it->addlight();
        it->draw();
        it++;
        glPopMatrix();

    }
}



#include "SpotLight.h"

using namespace std;

GLfloat target[3] = { 0.0f, 0.0f, 0.0f };
GLfloat color[3] = { 1.0f, 1.0f, 1.0f };
GLfloat cutoff(5.0f);
GLfloat exponent(15.0f);

SpotLight::SpotLight(GLfloat x, GLfloat y, GLfloat z, GLfloat w) {

    position[0] = x;
    position[1] = y;
    position[2] = z;
    position[3] = w;

    direction[0] = target[0] - position[0];
    direction[1] = target[1] - position[1];
    direction[2] = (target[2] - position[2]);

}

void SpotLight::addlight() {

    glEnable(GL_LIGHT1);

    glLightfv(GL_LIGHT1, GL_DIFFUSE, color);
    glLightfv(GL_LIGHT1, GL_SPECULAR, color);
    glLightfv(GL_LIGHT1, GL_POSITION, position);

    glLightfv(GL_LIGHT1, GL_SPOT_DIRECTION, direction);
    glLightf(GL_LIGHT1, GL_SPOT_CUTOFF, cutoff);
    glLightf(GL_LIGHT1, GL_SPOT_EXPONENT, exponent);

}

void SpotLight::draw() {
    if (!glIsEnabled(GL_LIGHT1))
        return;

    glPushMatrix();
    GLfloat up[3] = { 0, 1, 0 };
    lookAt(position, target, up);

    GLfloat ambient[4] = { 0.8f, 0.8f, 0.8f, 1.0f };
    GLfloat diffuse[4] = { 0.01f, 0.01f, 0.01f, 1.0f };
    GLfloat specular[4] = { 0.5f, 0.5f, 0.5f, 1.0f };
    GLfloat shininess = 32.0f;

    glMaterialfv(GL_FRONT, GL_AMBIENT, ambient);
    glMaterialfv(GL_FRONT, GL_DIFFUSE, diffuse);
    glMaterialfv(GL_FRONT, GL_SPECULAR, specular);
    glMaterialf(GL_FRONT, GL_SHININESS, shininess);

    glutSolidCone(0.3, 0.6, 10, 10);
    glPushMatrix();
    glTranslatef(0, 0, 0.1f);
    glutSolidCylinder(0.2, 0.39, 10, 10);
    glPopMatrix();

    glDisable(GL_LIGHTING);
    glColor3fv(color);
    glutSolidSphere(0.2, 100, 100);
    glEnable(GL_LIGHTING);
    glPopMatrix();
}


void SpotLight::normalize(const GLfloat* vec, GLfloat* output)
{
    GLfloat length = sqrtf(vec[0] * vec[0] + vec[1] * vec[1] + vec[2] * vec[2]);
    output[0] /= length;
    output[1] /= length;
    output[2] /= length;
}

void SpotLight::cross(const GLfloat* vec1, const GLfloat* vec2, GLfloat * output) {
    output[0] = vec1[1] * vec2[2] - vec1[2] * vec2[1];
    output[1] = vec1[2] * vec2[0] - vec1[0] * vec2[2];
    output[2] = vec1[0] * vec2[1] - vec1[1] * vec2[0];
}

void SpotLight::lookAt(GLfloat* eye, GLfloat* center, GLfloat* up)
{
    GLfloat f[3] = { center[0] - eye[0],
                     center[1] - eye[1],
                     center[2] - eye[2] };

    normalize(f, f);
    GLfloat u[3];
    normalize(up, u);
    GLfloat s[3];
    cross(f, u, s);
    normalize(s, s);
    cross(s, f, u);
    normalize(u, u);

}



void drawScene() {

    glPushMatrix();
    glTranslatef(pointlight.position[0], pointlight.position[1], pointlight.position[2]);
    pointlight.addLight();
    glPopMatrix();

    // Draw road
    glPushMatrix();
    glScalef(10, 10, 8.5);
    glTranslatef(-0.018f, 0, 0.75);
    glRotatef(180.f, 0, 1, 0);
    models[0]->renderTheModel();
    glPopMatrix();

    //Draw Car Model
    glPushMatrix();
    glMultMatrixf(carros[0]->local);
    carros[0]->draw();
    glPopMatrix();

//Draw spotlights
    glPushMatrix();
    lamps->Add();
    glPopMatrix();
}

最佳答案

您仅设置了LIGHT1,这意味着将仅启用1个灯(最后一个)。如果指定GL_LIGHT0 +索引,则可以启用更多功能。

void SpotLight::addlight(int index) {

    glEnable(GL_LIGHT0 + index);

    glLightfv(GL_LIGHT0 + index, GL_DIFFUSE, color);
    glLightfv(GL_LIGHT0 + index, GL_SPECULAR, color);
    glLightfv(GL_LIGHT0 + index, GL_POSITION, position);

    glLightfv(GL_LIGHT0 + index, GL_SPOT_DIRECTION, direction);
    glLightf(GL_LIGHT0 + index, GL_SPOT_CUTOFF, cutoff);
    glLightf(GL_LIGHT0 + index, GL_SPOT_EXPONENT, exponent);
}


然后,您只需在启用时传递索引

void CreateLamps::Add() {

    std::vector<SpotLight>::iterator it = lamp.begin();

    while (it != lamp.end())
    {

        glPushMatrix();
        glTranslatef(1, 0, 30.0);
        glTranslatef(it->position[0], it->position[3] * 3, it->position[2]);
        glRotatef(100.f, -5.0, -10, 0);
        it->addlight(it - lamp.begin());
        it->draw();
        it++;
        glPopMatrix();

    }
}


请注意,在8点之后可能会用光,所以您可能需要检查GL_MAX_LIGHTS的值...

int numLights = 0;
glGetIntegerv(GL_MAX_LIGHTS, &numLights);
std::cout << "GL_MAX_LIGHTS " << numLights << std::endl;

关于c++ - opengl中的多个聚光灯不起作用,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/56031177/

10-08 23:39