Fragmento de sombra inexplicable bahaviour.

He escrito un programa en C ++ donde dibujo una tetera y aplico iluminación. Es en sí simple, pero también uso sombreadores. Simple, soy nuevo con GLSL. Acabo de probar un sombreador de fragmentos simple, pero la salida de pantalla es inexplicable.

En este archivo inicializo Glew en el método init, donde también compilo el sombreado de vértice y fragmento. Están en los archivos "vertex_shader" y "fragment_shader".

Lo que quizás no reconozcas es lo que es Luz y Material. Son solo algunas estructuras que contienen toda la información sobre las luces. He probado estas estructuras, así que estoy seguro de que el trabajo como se esperaba. Cuando declaro material = BlackPlastic, simplemente lo establezco en un valor predeterminado definido con la directiva define. También puedo publicar este código si crees que el problema está ahí.

#include <GL/glew.h>
#include <GL/glut.h>
#include <iostream>
#include <fstream>
#include <vector>
#include "utility.hpp"

#define MAX_DIM 1000

GLfloat width=600, height=800;
GLuint vertex_shader, fragment_shader;
GLuint program;
const char* vertex_shader_filename= "vertex_shader";
const char* fragment_shader_filename= "fragment_shader";
Light light;
Material material;

void init()
{    
    // Inizializzazione di GLEW
    glewInit();
    if(GLEW_ARB_vertex_shader && GLEW_ARB_fragment_shader)
    {
    cout << "Supporto GLSL" << endl;
    }

    // Lettura e compilazione del vertex shader
    GLchar* buffer= new GLchar[MAX_DIM];
    ifstream stream;
    streamsize count;
    stream.open(vertex_shader_filename);
    stream.read(buffer,MAX_DIM);
    count= stream.gcount();
    stream.close();
    vertex_shader= glCreateShader(GL_VERTEX_SHADER);
    glShaderSource(vertex_shader, 1, (const GLchar**)&buffer, &count);
    glCompileShader(vertex_shader);

    // Lettura, inizializzazione ed esecuzione del fragment shader
    stream.open(fragment_shader_filename);
    stream.read(buffer,MAX_DIM);
    count= stream.gcount();
    stream.close();
    fragment_shader= glCreateShader(GL_FRAGMENT_SHADER);
    glShaderSource(fragment_shader, 1, (const GLchar**)&buffer, &count);
    glCompileShader(fragment_shader);
    delete[] buffer;

    // Creazione del programma

    program= glCreateProgram();
    glAttachShader(program, vertex_shader);
    glAttachShader(program, fragment_shader);
    glLinkProgram(program);
    glUseProgram(program);

    // Inizializzazione materiale e luce
    material= BlackPlastic;
    light= {vector<GLfloat>{-2,2,2,1} ,vector<GLfloat>{1,1,1,1},vector<GLfloat>{1,1,1,1},vector<GLfloat>{1,1,1,1} };
}

void display()
{
    glEnable(GL_DEPTH_TEST);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    gluPerspective(45,width/height,1,1000);
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
    gluLookAt(0,0,-100,0,0,0,0,1,0);

    // Illuminazione
    glShadeModel(GL_SMOOTH);
    material.apply(); // This just causes glMaterialfv to be called for the ambient, diffuse, specular and shininess values.
    light.apply(); // This just causes glLightfv to be called for the ambient, diffuse and specular values
    glEnable(GL_LIGHT0);
    glEnable(GL_LIGHTING);

    // Rendering
    glClearColor(0.8,0.8,0.8,1.0);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glutSolidTeapot(10);
    glutSwapBuffers();
}

void reshape(int w, int h)
{
    width=w;
    height=h;
    glutPostRedisplay();
}

int main(int argc, char** argv)
{
    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH);
    glutInitWindowPosition(100,100);
    glutInitWindowSize(500,500);
    glutCreateWindow("test");
    glutDisplayFunc(display);
    glutReshapeFunc(reshape);
    init();
    glutMainLoop();
    return 0;
}

No creo que el sombreado de vértice esté causando ningún problema, simplemente asigna el color y calcula la posición, correctamente. También el fragmento shader es aparentemente correcto, esta es la única instrucción ejecutada:

gl_FragColor = gl_Color;

Si hago esto solo veo una tetera blanca. Si, por el contrario, cambio este valor a un color cualquiera:

gl_FragColor = vec4{0,0,1,1};

Obtengo la tetera con el color correcto: plástico negro. Y no sé por qué, no aplico la iluminación aquí, debería calcularlo.

Preciso que ejecuté el mismo programa idéntico pero sin aplicar los sombreadores, y obtuve la tetera para tener el color correcto.

Respuestas a la pregunta(1)

Su respuesta a la pregunta