我在着色逻辑中添加了着色器,但似乎无法弄清楚出了什么问题。在此之前,它还不错,但是现在我什么也没画。我检查以确保着色器已编译并成功链接。

这是我的渲染代码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。我在display和Render的实现中使用的引用似乎有效,但是在假定它们的方法可以转移到我的实现中时,我可能会犯一些错误。

最佳答案

您应该对顶点着色器中的“位置”,“常规”和“颜色”属性使用glGetAttribLocation。

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


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

关于c++ - 引入了着色器,不再绘制,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/33790989/

10-15 00:28