vendredi 26 août 2016

OpenGL lighting changing based on look direction

AKA What am I doing wrong?

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.

For example:

Looking at the cube from the top down:

top down

Looking at the cube from the side:

enter image description here

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

And the vertex object:

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} {}
};

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.

Aucun commentaire:

Enregistrer un commentaire