OpenGL 焦点

发布于 2024-11-01 05:26:45 字数 2143 浏览 0 评论 0原文

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

但是,即使禁用除中间聚光灯之外的所有聚光灯,我的场景也会被一种“毯子”照明均匀照亮。

我觉得我可能错过了一些明显的东西,但我就是看不到什么。

I'm trying to make 'spotlights' over a pool table in openGL. This should be fairly simple, but something is going wrong, and I can't work out what.

I have a class 'PoolLight' that I'm using as a sort of holding class for the lights. Here is is:

#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);
}

And in Display::Init, I have this code:

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);

However, even when disabling all but the middle spotlight my scene is uniformly lit with a sort of 'blanket' lighting.

I feel like I'm probably missing something obvious, but I just can't see what.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

明明#如月 2024-11-08 05:26:45

这是由于 OpenGL 默认固定函数管道实现光照的方式所致:仅在顶点评估光照,将结果颜色插值到表面上。如果您的整个桌子仅由一个大四边形组成,那么就会发生这种情况。

解决方案1:将网格高度细分。

解决方案 2:用每片段照明着色器替换固定功能照明。

This is due to how OpenGL default fixed function pipeline implements lighting: Lighting is evaluated only at the vertices, the resulting colour interpolated over the surface. If your whole table consists of just one large quad, exactly this happens.

Solution 1: Subdivide the mesh to a high degree.

Solution 2: Replace fixed function lighting with a per-fragment-illumination shader.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文