c++ - 引入着色器并不再绘制

标签 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。我用于 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/

相关文章:

java - 在 LibGDX 中将形状绘制为纹理

c++ - Open GL 在 Codelite Windows 7 上编译,但没有显示输出

c++ - 将 QOpenGLWidget 子类转换为使用 Metal 而不是 OpenGL 的子类是否可行?

c++ - 找不到 Visual Studio 平台 2015 工具集 ='v141'

c++ - 使 -std=c++11 成为 mac 终端的默认值

c++ - 绘制 8bpp 灰度位图(非托管 C++)

c++ - 使用GCC boost 线程编译器错误

c++ - 更改OpenCV卡尔曼滤波器的增益以使其响应更快

opengl - 如何在片段着色器中将 gl_FragCoord 转换为世界空间点?

c++ - Qt3d。在三角形上绘制透明的QSphereMesh