我的着色器停止工作了

时间:2014-10-27 20:52:30

标签: c++ opengl glsl shader

我似乎打破了程序中的着色器,这是他们的代码:

顶点着色器

#version 330 core

uniform mat4 camera;
uniform mat4 model;

layout(location = 0) in vec3 vert;
layout(location = 1) in vec3 vertNormal;

out vec3 fragVert;
out vec3 fragNormal;

void main() {
    // Pass some variables to the fragment shader
    fragNormal = vertNormal;
    fragVert = vert;

    // Apply all matrix transformations to vert
    gl_Position = camera * model * vec4(vert, 1);
}

片段着色器

#version 150 core

uniform mat4 model;
uniform vec3 cameraPosition;

// material settings
uniform float materialShininess;
uniform vec3 materialSpecularColor;
uniform vec3 materialColor;

uniform struct Light {
   vec3 position;
   vec3 intensities; //a.k.a the color of the light
   float attenuation;
   float ambientCoefficient;
} light;

in vec3 fragNormal;
in vec3 fragVert;

out vec4 finalColor;

void main() {
    vec3 normal = normalize(transpose(inverse(mat3(model))) * fragNormal);
    vec3 surfacePos = vec3(model * vec4(fragVert, 1));
    vec4 surfaceColor = vec4(materialColor, 1);
    vec3 surfaceToLight = normalize(light.position - surfacePos);
    vec3 surfaceToCamera = normalize(cameraPosition - surfacePos);

    //ambient
    vec3 ambient = light.ambientCoefficient * surfaceColor.rgb * light.intensities;

    //diffuse
    float diffuseCoefficient = max(0.0, dot(normal, surfaceToLight));
    vec3 diffuse = diffuseCoefficient * surfaceColor.rgb * light.intensities;

    //specular
    float specularCoefficient = 0.0;
    if(diffuseCoefficient > 0.0)
        specularCoefficient = pow(max(0.0, dot(surfaceToCamera, reflect(-surfaceToLight, normal))), materialShininess);
    vec3 specular = specularCoefficient * materialSpecularColor * light.intensities;

    //attenuation
    float distanceToLight = length(light.position - surfacePos);
    float attenuation = 1.0 / (1.0 + light.attenuation * pow(distanceToLight, 2));

    //linear color (color before gamma correction)
    vec3 linearColor = ambient + attenuation*(diffuse + specular);

    //final color (after gamma correction)
    vec3 gamma = vec3(1.0/2.2);
    finalColor = vec4(pow(linearColor, gamma), surfaceColor.a);
}

我有一个资产,我从一个obj文件加载,然后像这样绘制它:

void OpenGLView::run()
{   
    initializeAndSetupWindow(WINDOW_WIDTH, WINDOW_HEIGHT, "PhongBunny");
    glClearColor(1.0f, 1.0f, 0.0f, 1.0f);

    loadBunnyAsset();

    AssetInstance bunny1;
    bunny1.asset = bunny;
    bunny1.position = glm::vec3(2.0f, 2.0f, 2.0f);
    bunny1.scale = glm::vec3(1.0f, 1.0f, 1.0f);


    do{
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

        loadUniforms(bunny1);

        glEnableVertexAttribArray(0);
        glBindBuffer(GL_ARRAY_BUFFER, bunny.vertexBuffer);
        glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, nullptr);

        glEnableVertexAttribArray(1);
        glBindBuffer(GL_ARRAY_BUFFER, bunny.normalBuffer);
        glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 0, nullptr);

        glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, bunny.elementBuffer);

        glDrawElements(GL_TRIANGLES, bunny.elementsSize, GL_UNSIGNED_INT, (void*)0);

        glDisableVertexAttribArray(0);
        glDisableVertexAttribArray(1);

        glfwSwapBuffers(window);
        glfwPollEvents();
    } while (!glfwWindowShouldClose(window));

    glfwDestroyWindow(window);
    glfwTerminate();
}

这是加载制服的功能:

void OpenGLView::loadUniforms(AssetInstance assetInstance)
{
    Asset* asset = &assetInstance.asset;

    glUseProgram(asset->shaderProgramID);
    glm::mat4 Projection = glm::perspective(45.0f, 4.0f / 3.0f, 0.1f, 1000.0f);
    glm::mat4 camera = Projection * getViewMatrix();
    glm::mat4 model = translate(assetInstance.position) * scale(assetInstance.position);

    GLuint cameraID = glGetUniformLocation(asset->shaderProgramID, "camera");
    GLuint modelID = glGetUniformLocation(asset->shaderProgramID, "model");
    GLuint cameraPositionID = glGetUniformLocation(asset->shaderProgramID, "cameraPosition");
    GLuint lightPositionID = glGetUniformLocation(asset->shaderProgramID, "light.position");
    GLuint lightIntensitiesID = glGetUniformLocation(asset->shaderProgramID, "light.intensities");
    GLuint lightAttenuationID = glGetUniformLocation(asset->shaderProgramID, "light.attenuation");
    GLuint lightAmbientCoefficientID = glGetUniformLocation(asset->shaderProgramID, "light.ambientCoefficient");
    GLuint materialColorID = glGetUniformLocation(asset->shaderProgramID, "materialColor");
    GLuint materialShininessID = glGetUniformLocation(asset->shaderProgramID, "materialShininess");
    GLuint materialSpecularColorID = glGetUniformLocation(asset->shaderProgramID, "materialSpecularColor");

    glUniformMatrix4fv(cameraID, 1, GL_FALSE, &camera[0][0]);
    glUniformMatrix4fv(modelID, 1, GL_FALSE, &model[0][0]);
    glUniform3fv(cameraPositionID, 1, &cameraPosition[0]);
    glUniform3fv(lightPositionID, 1, &light.position[0]);
    glUniform3fv(lightIntensitiesID, 1, &light.intensities[0]);
    glUniform1f(lightAttenuationID, light.attenuation);
    glUniform1f(lightAmbientCoefficientID, light.ambientCoefficient);
    glUniform3fv(materialColorID, 1, &assetInstance.materialColor[0]);
    glUniform1f(materialShininessID, assetInstance.materialShininess);
    glUniform3fv(materialSpecularColorID, 1, &assetInstance.materialSpecularColor[0]);
}

并在此处完成了一些设置:

OpenGLView::OpenGLView()
{
    light.position = glm::vec3(0.0f, 7.0f, 3.0f);
    light.intensities = glm::vec3(0.3f, 0.3, 0.3f);
    light.attenuation = 0.3f;
    light.ambientCoefficient = 0.005f;

    cameraPosition = glm::vec3(5.0f, 3.0f, 8.0f);
}

有一段时间我把bunny1的位置设置为0,0,0导致它根本不被绘制,我无法弄清楚为什么会这样?然后,当我将其更改为1,1,1时,它开始绘制,但现在我的key_callback函数(旋转并缩放兔子)停止工作。另外,这是我的翻译和缩放功能:

glm::mat4 OpenGLView::translate(glm::vec3 position)
{
    return glm::translate(glm::mat4(), position);
}

glm::mat4 OpenGLView::scale(glm::vec3 size)
{
    return glm::scale(glm::mat4(), size);
}

我无法弄清楚为什么改变bunny1.position似乎会扩展兔子而不是翻译它的位置?

1 个答案:

答案 0 :(得分:1)

改变bunny1.position时你的兔子比例变化的原因是因为你通过bunny1.position缩放你的兔子:

     glm::mat4 model = translate(assetInstance.position) * scale(assetInstance.position);

这可能也是为什么兔子在将它的位置设置为(0,0,0)时会消失的原因,因为然后将它缩放到0。