引入着色器并且不再绘制

时间:2015-11-18 21:43:34

标签: c++ opengl

我在渲染逻辑中添加了着色器,我似乎无法弄清楚出了什么问题。在此之前,它画得很好,但现在我没有画任何东西。我检查确保着色器已成功编译和链接。

这是我的渲染代码,Scene :: Render():

// This block renders each object in the scene
for (auto it = objects_.begin(); it != objects_.end(); it++) {
    Renderer* r = it->get_renderer();
    GLuint* shader = r->get_material()->get_shader();

    glUseProgram(*shader);

    glBindBuffer(GL_ARRAY_BUFFER, *r->get_vertex_buffer());
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, *r->get_index_buffer());

    GLuint position_attrib = glGetUniformLocation(*shader, "position");
    GLuint normal_attrib = glGetUniformLocation(*shader, "normal");
    GLuint color_attrib = glGetUniformLocation(*shader, "color");


    glEnableVertexAttribArray(position_attrib);
    glEnableVertexAttribArray(normal_attrib);
    glEnableVertexAttribArray(color_attrib);

    glVertexAttribPointer(position_attrib, 4, GL_FLOAT, GL_FALSE, sizeof(engine::Vertex), (char*)NULL);
    glVertexAttribPointer(normal_attrib, 4, GL_FLOAT, GL_FALSE, sizeof(engine::Vertex), (char*)NULL + 16);
    glVertexAttribPointer(color_attrib, 4, GL_FLOAT, GL_FALSE, sizeof(engine::Vertex), (char*)NULL + 32);

    // Set up transformation matrices for shader
    glm::mat4 model = (*it).get_transform();
    glm::mat4 view = main_.get_view();
    glm::mat4 model_view = view * model;
    glm::mat4 model_view_projection = main_.get_projection() * model_view;
    glm::mat4 normal = glm::transpose(glm::inverse(model_view));

    // Send light to shader
    auto ambient = light_.get_ambient();
    glUniform4f(glGetUniformLocation(*shader, "light_ambient"), ambient[0], ambient[1], ambient[2], ambient[3]);
    auto diffuse = light_.get_diffuse();
    glUniform4f(glGetUniformLocation(*shader, "light_diffuse"), diffuse[0], diffuse[1], diffuse[2], diffuse[3]);
    auto specular = light_.get_specular();
    glUniform4f(glGetUniformLocation(*shader, "light_specular"), specular[0], specular[1], specular[2], specular[3]);
    auto position = light_.get_position();
    glUniform4f(glGetUniformLocation(*shader, "light_position"), position[0], position[1], position[2], position[3]);

    // Send material to shader
    ambient = r->get_material()->get_ambient();
    glUniform4f(glGetUniformLocation(*shader, "mat_ambient"), ambient[0], ambient[1], ambient[2], ambient[3]);
    diffuse = r->get_material()->get_diffuse();
    glUniform4f(glGetUniformLocation(*shader, "mat_diffuse"), diffuse[0], diffuse[1], diffuse[2], diffuse[3]);
    specular = r->get_material()->get_specular();
    glUniform4f(glGetUniformLocation(*shader, "mat_specular"), specular[0], specular[1], specular[2], specular[3]);
    auto shine = r->get_material()->get_shininess();
    glUniform1f(glGetUniformLocation(*shader, "mat_shine"), shine[0]);

    // Send transformation matrices
    glUniformMatrix4fv(glGetAttribLocation(*shader, "world2eye"), 1, GL_FALSE, &view[0][0]);
    glUniformMatrix4fv(glGetAttribLocation(*shader, "local2eye"), 1, GL_FALSE, &model_view[0][0]);
    glUniformMatrix4fv(glGetAttribLocation(*shader, "local2clip"), 1, GL_FALSE, &model_view_projection[0][0]);
    glUniformMatrix4fv(glGetAttribLocation(*shader, "normal_matrix"), 1, GL_FALSE, &normal[0][0]);

    r->Draw();
}

这是主要的显示功能:

void display() {
    glEnable(GL_DEPTH_TEST);
    glClearColor(0.604f, 0.784f, 0.831f, 1);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
    glLightModelf(GL_LIGHT_MODEL_TWO_SIDE, GL_TRUE);

    scene.Render();

    glDisableClientState(GL_VERTEX_ARRAY);

    glutSwapBuffers();
}

最后是顶点和片段着色器:

// default.vert
attribute vec4 position; 
attribute vec4 color;
attribute vec4 normal; 

varying vec4 pcolor;

uniform mat4 local2clip;
uniform mat4 local2eye;
uniform mat4 normal_matrix;
uniform mat4 world2eye; 

uniform vec4 light_ambient;
uniform vec4 light_diffuse;
uniform vec4 light_specular;
uniform vec4 light_pos;

uniform vec4 mat_ambient;
uniform vec4 mat_diffuse;
uniform vec4 mat_specular;
uniform float mat_shine; 

void main(void) {

    gl_Position = local2clip * position;

    vec4 ambient = light_ambient * mat_ambient; 
    vec3 N = normalize(vec3(normal_matrix * normal)); 
    vec4 Lpos = world2eye * light_pos; 
    vec4 Vpos = local2eye * position; 
    vec3 L = normalize(vec3(Lpos - Vpos)); 

    float NdotL; 
    if (dot(N,L) <0.0) NdotL = 0.0; 
    else NdotL = dot(N, L);

    vec4 diffuse = light_diffuse * mat_diffuse * NdotL; 

    vec3 R = normalize(reflect(-L, N)); 
    vec3 V = normalize(vec3(-Vpos)); 

    float RdotV; 
    RdotV = dot(R, V); 

    if (NdotL == 0.0) RdotV = 0.0; 
    if (RdotV < 0.0) RdotV = 0.0; 

    vec4 specular = light_specular * mat_specular * pow(RdotV,mat_shine);

    pcolor = ambient + diffuse + specular; 

}

// default.frag
varying vec4 pcolor;

uniform vec4 light_ambient;
uniform vec4 light_diffuse;
uniform vec4 light_specular;

uniform vec4 mat_ambient;
uniform vec4 mat_diffuse;
uniform vec4 mat_specular;

uniform float mat_shine; 

varying vec3 N;
varying vec3 L;
varying vec3 R;
varying vec3 V;

void main() { 

    vec4 ambient = light_ambient * mat_ambient;

    float NdotL; 
    if (dot(N,L) <0.0) NdotL = 0.0; 
    else NdotL = dot(N, L);

    float RdotV = dot(R, V);
    if (NdotL == 0.0) RdotV = 0.0; 
    if (RdotV < 0.0) RdotV = 0.0; 

    vec4 diffuse = light_diffuse * mat_diffuse * NdotL; 
    vec4 specular = light_specular * mat_specular * pow(RdotV,mat_shine); 

    gl_FragColor = pcolor + ambient + diffuse + specular; 

}

我最不确定着色器的实现,因为这是我目前正在学习的内容。在此之前,我使用glVertexPointer。我用于显示和渲染的实现的参考似乎可行,但我可能在假设他们的方法可以转移到我的实现时犯了一些错误。

1 个答案:

答案 0 :(得分:1)

您应该在顶点着色器中使用glGetAttribLocation作为“position”,“normal”和“color”属性。

GLuint position_attrib = glGetAttribLocation(*shader, "position");
GLuint normal_attrib = glGetAttribLocation(*shader, "normal");
GLuint color_attrib = glGetAttribLocation(*shader, "color");

转换矩阵应使用glGetUniformLocation而不是glGetAttribLocation。

glUniformMatrix4fv(glGetUniformLocation(*shader, "world2eye"), 1, GL_FALSE, &view[0][0]);
glUniformMatrix4fv(glGetUniformLocation(*shader, "local2eye"), 1, GL_FALSE, &model_view[0][0]);
glUniformMatrix4fv(glGetUniformLocation(*shader, "local2clip"), 1, GL_FALSE, &model_view_projection[0][0]);
glUniformMatrix4fv(glGetUniformLocation(*shader, "normal_matrix"), 1, GL_FALSE, &normal[0][0]);

它们可能是可以互换的,但我不会依赖它。