OpenGL照明根据外观方向变化 [英] OpenGL lighting changing based on look direction

查看:156
本文介绍了OpenGL照明根据外观方向变化的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

又是我做错了什么?

我一直在搞弄OpenGL,现在我只是想尝试点亮一个立方体.我不确定我是否应该正确理解应该做的事情,因为当我四处移动相机时,立方体上的照明会发生变化.

I've been messing around with OpenGL and I'm just trying to work on lighting a cube right now. I'm not sure if I'm understanding what I'm supposed to do correctly because when I move the camera around, the lighting on the cube changes.

例如:

从上至下查看多维数据集:

Looking at the cube from the top down:

从侧面看立方体:

通过搜索所有我看到的答案,发现当法线设置不正确时会发生这种情况,但是我认为它们的设置正确,因为当我打印所有顶点及其法线时,这就是结果(按绘制顺序按面分组):

From searching around all of the answers that I've seen say that this happens when the normal isn't set correctly, but I think they are being set correctly, because when I print out all of the vertices along with their normals, this is the result (grouped by face, in the order they're drawn):

Position:  0  0  0       Normal:   -1  0  0
Position:  0 30  0       Normal:   -1  0  0
Position:  0 30 30       Normal:   -1  0  0
Position:  0  0 30       Normal:   -1  0  0

Position:  0  0  0       Normal:    0  1  0
Position:  0  0 30       Normal:    0  1  0
Position: 30  0 30       Normal:    0  1  0
Position: 30  0  0       Normal:    0  1  0

Position:  0  0  0       Normal:    0  0 -1
Position: 30  0  0       Normal:    0  0 -1
Position: 30 30  0       Normal:    0  0 -1
Position:  0 30  0       Normal:    0  0 -1

Position:  0  0 30       Normal:    0  0  1
Position:  0 30 30       Normal:    0  0  1
Position: 30 30 30       Normal:    0  0  1
Position: 30  0 30       Normal:    0  0  1

Position:  0 30  0       Normal:    0 -1  0
Position: 30 30  0       Normal:    0 -1  0
Position: 30 30 30       Normal:    0 -1  0
Position:  0 30 30       Normal:    0 -1  0

Position: 30  0  0       Normal:    1  0  0
Position: 30  0 30       Normal:    1  0  0
Position: 30 30 30       Normal:    1  0  0
Position: 30 30  0       Normal:    1  0  0

还有一些用于渲染的代码,以防出现错误:

Here's also some of the code used for rendering in case the mistake is in there:

RenderEngine::RenderEngine(int width, int height) {
    //initializing the window...

    glClearDepth(1.f);
    glClearColor(217.f / 256.f, 233.f / 256.f, 255.f / 256.f, 1.f);

    glEnable(GL_DEPTH_TEST);
    glDepthMask(GL_TRUE);

    glFrontFace(GL_CW);
    glEnable(GL_CULL_FACE);

    glEnable(GL_LIGHTING);

    //glEnable(GL_COLOR_MATERIAL);

    GLfloat lightPos[] = { 0.f, -1.0f, 0.0f, 0.f  };
    GLfloat ambient[] = {0.3f,0.3f,0.3f,1.0f};
    GLfloat diffuse[] = {0.7f,0.7f,0.7f,1.0f};
    glLightfv(GL_LIGHT0, GL_POSITION, lightPos);
    glLightfv(GL_LIGHT0, GL_AMBIENT, ambient);
    glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuse);
    glEnable(GL_LIGHT0);

    //more window related things
}

void RenderEngine::beginRender() {
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
}

void RenderEngine::endRender() {
    //window stuff
}

void RenderEngine::translatePlayer(const sf::Vector3f& position) {
    glTranslatef(-(position.x + 0.5) * 30, -(position.y + 1.75)  * 30, -(position.z + 0.5) * 30);
}

void RenderEngine::rotatePlayer(const sf::Vector3f& rotation) {
    glRotatef(rotation.x, 1.f, 0.f, 0.f);
    glRotatef(rotation.y, 0.f, 1.f, 0.f);
    glRotatef(rotation.z, 0.f, 0.f, 1.f);
}

void RenderEngine::renderVertexArray(const std::vector<Vertex>& vertices) {
    glEnableClientState(GL_VERTEX_ARRAY);
    glEnableClientState(GL_COLOR_ARRAY);
    glEnableClientState(GL_NORMAL_ARRAY);

    glVertexPointer(3, GL_FLOAT, sizeof(Vertex), &vertices[0].pos[0]);
    glColorPointer(3, GL_FLOAT, sizeof(Vertex), &vertices[0].color[0]);
    glNormalPointer(GL_FLOAT, sizeof(Vertex), &vertices[0].normal[0]);

    glDrawArrays(GL_QUADS, 0, vertices.size());

    glDisableClientState(GL_VERTEX_ARRAY);
    glDisableClientState(GL_COLOR_ARRAY);
    glDisableClientState(GL_NORMAL_ARRAY);
}

还有顶点对象:

struct Vertex {
    float pos[3];
    float color[3];
    float normal[3];

    Vertex(float _pos[3], float _color[3], float _normal[3]) :
        pos   {_pos[0],    _pos[1],    _pos[2]},
        color {_color[0],  _color[1],  _color[2]},
        normal{_normal[0], _normal[1], _normal[2]} {}

    Vertex() : pos{0,0,0}, color{0,0,0}, normal{0,0,0} {}
};

请忽略所有随机30.我知道这些方法不合适,不应该那样做,但这不是这里的问题.

Please ignore all the random 30's. I'm aware that those are out of place and should not be done that way, but that's not the issue here.

推荐答案

调用以下内容:

glLightfv(GL_LIGHT0, GL_POSITION, lightPos);

...,然后将传递的lightPos用当前的模型视图矩阵进行转换,然后存储在相机坐标中.因此,您的灯光将与相机一起移动.如果希望它是静态的,则必须在设置模型视图矩阵之后再次执行上面的行.

... then the passed lightPos is transformed with the current model-view matrix and then stored in camera coordinates. Thus, your light will move together with the camera. If you want it to be static, you have to execute the above line again after setting the model-view matrix.

这篇关于OpenGL照明根据外观方向变化的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆