无法在fragmentShader lwgl 3中找到制服

时间:2016-10-17 15:12:38

标签: opengl shader lwjgl

问题在标题中。

控制台错误

LWJGL Version: 3.0.0 build 90
GLFW Version: 3.2.0 Win32 WGL EGL VisualC DLL
OpenGL Version: 4.0.0 NVIDIA 372.70
java.lang.Exception: Can't find uniform: lightColor
at com.ms.shaders.ShaderProgram.getUniformLocation(ShaderProgram.java:50)
at com.ms.shaders.Shaders.createUniforms(Shaders.java:32)

ShaderProgram

public class ShaderProgram {

private int programID;
private int vertexShaderID;
private int fragmentShaderID;

private Map<String, Integer> uniforms;

public ShaderProgram() {

    uniforms = new HashMap<>();
}

public void createProgram() throws Exception {

    programID = glCreateProgram();

    if(programID == 0) {
        throw new Exception("Failed to create program");
    }
}

public void createShaders(String vertexFile, String fragmentFile) throws Exception {

    vertexShaderID = shadersLoader(vertexFile, GL_VERTEX_SHADER);

}

protected void bindAttribute(int attribute, String name) {
    glBindAttribLocation(programID, attribute, name);
}

public void getUniformLocation(String uniform) throws Exception {

    int uniformLocation = glGetUniformLocation(programID, uniform);

    if(uniformLocation < 0) {
        throw new Exception("Can't find uniform: " + uniform);
    }

    uniforms.put(uniform, uniformLocation);
}

public void floatUniforms(String uniform, float value) {
    glUniform1f(uniforms.get(uniform), value);
}

public void intUniforms(String uniform, int value) {
    glUniform1i(uniforms.get(uniform), value);
}

public void booleanUniforms(String uniform, boolean value) {

    float load = 0;
    if(value) {
        load = 1;
    }

    glUniform1f(uniforms.get(uniform), load);
}

public void vectorUniforms(String uniform, Vector3f value) {
    glUniform3f(uniforms.get(uniform), value.x, value.y, value.z);
}

public void matrixUniforms(String uniform, Matrix4f value) {

    FloatBuffer buffer = BufferUtils.createFloatBuffer(16);
    value.get(buffer);

    glUniformMatrix4fv(uniforms.get(uniform), false, buffer);
}

public int shadersLoader(String shader, int type) throws Exception {

    int shaderID = glCreateShader(type);

    glShaderSource(shaderID, shader);

    glCompileShader(shaderID);
    if(glGetShaderi(shaderID, GL_COMPILE_STATUS) == 0) {
        throw new Exception("Failed to compile Shader: " + glGetShaderInfoLog(shaderID, 1024));
    }

    glAttachShader(programID, shaderID);

    return shaderID;
}

public void linkProgram() throws Exception {

    glLinkProgram(programID);
    if(glGetProgrami(programID, GL_LINK_STATUS) == 0) {
        throw new Exception("Failed to link program: " + glGetProgramInfoLog(programID, 1024));
    }

    glValidateProgram(programID);
    if(glGetProgrami(programID, GL_VALIDATE_STATUS) == 0) {
        throw new Exception("Failed to validate program: " + glGetProgramInfoLog(programID, 1024));
    }
}

public void bind() {
    glUseProgram(programID);
}

public void unbind() {
    glUseProgram(0);
}

public void cleanUp() {

    unbind();

    if(programID != 0) {
        if(vertexShaderID != 0) {
            glDetachShader(programID, vertexShaderID);
            glDeleteShader(vertexShaderID);
        }

        if(fragmentShaderID != 0) {
            glDetachShader(programID, fragmentShaderID);
            glDeleteShader(fragmentShaderID);
        }

        glDeleteProgram(programID);
    }
}
}

着色

public class Shaders extends ShaderProgram {

private static final String VERTEX_SHADER = "vertexShader.txt";
private static final String FRAGMENT_SHADER = "fragmentShader.txt";

public void init() throws Exception {

    createProgram();
    createShaders(FileLoader.loadResources(VERTEX_SHADER), FileLoader.loadResources(FRAGMENT_SHADER));
    linkProgram();

    createUniforms();
}

public void bindAttributes() {

    bindAttribute(0, "position");
    bindAttribute(1, "textureCoords");
    bindAttribute(2, "normal");
}

public void createUniforms() throws Exception {

    getUniformLocation("transformationMatrix");
    getUniformLocation("projectionMatrix");
    getUniformLocation("viewMatrix");
    getUniformLocation("lightPosition");
    getUniformLocation("lightColor");
    getUniformLocation("shineDamper");
    getUniformLocation("reflectivity");
}
}

fragmentShader.txt

#version 400 core

in vec2 outTextureCoords;
in vec3 surfaceNormal;
in vec3 toLightVector;
in vec3 toCameraVector;

out vec4 outColor;

uniform sampler2D textureSampler;

uniform vec3 lightColor;
uniform float shineDamper;
uniform float reflectivity;

void main()
{
vec3 unitNormal = normalize(surfaceNormal);
vec3 unitLightVector = normalize(toLightVector);

float nDotl = dot(unitNormal, unitLightVector);
float brightness = max(nDotl, 0.2);
vec3 diffuse = brightness * lightColor;

vec3 unitVectorToCamera = normalize(toCameraVector);
vec3 lightDirection = -unitLightVector;
vec3 reflectedLightDirection = reflect(lightDirection, unitNormal);

float specularFactor = dot(reflectedLightDirection, unitVectorToCamera);
specularFactor = max(specularFactor, 0.0);
float dampFactor = pow(specularFactor, shineDamper);
vec3 finalSpecular = dampFactor * reflectivity * lightColor;

outColor = vec4(diffuse, 1.0) * texture(textureSampler, outTextureCoords) +     vec4(finalSpecular, 1.0);
}

如果我尝试删除lightColor,请在shineDamper制服中进行错误切换。

EDITED

如果我把全部放在Renderer课程中,问题就不存在......为什么?

这是我设置制服的课程:

UniformCreation

public class UniformsCreation {

private Transformation transformation;
private ShaderProgram shaders;

private float FOV = (float) Math.toRadians(60.0f);
private float zNEAR = 0.01f;
private float zFAR = 1000.0f;

public UniformsCreation() {

    transformation = new Transformation();
    shaders = new ShaderProgram();
}

public void renderer(Entity[] entity, Camera camera, Light light) {

    createProjectionMatrix();
    createTransformationMatrix(entity);
    createViewMatrix(camera);
    createLight(light, Texture.getShineDamper(), Texture.getReflection());
}

public Matrix4f createProjectionMatrix() {

    Matrix4f projectionMatrix = new Matrix4f();

    projectionMatrix = transformation.createProjectionMatrix(
            FOV, 
            Main.getWIDTH(), 
            Main.getHEIGHT(), 
            zNEAR, 
            zFAR);

    shaders.matrixUniforms("projectionMatrix", projectionMatrix);

    return projectionMatrix;
}

public Matrix4f createTransformationMatrix(Entity[] entity) {

    Matrix4f transformationMatrix = new Matrix4f();

    for(Entity entities : entity) {

        transformationMatrix = transformation.createTransformationMatrix(
                entities.getPosition(), 
                entities.getRotation(), 
                entities.getScale());

        shaders.matrixUniforms("transformationMatrix", transformationMatrix);
        entities.getMesh().render();
    }

    return transformationMatrix;
}

public Matrix4f createViewMatrix(Camera camera) {

    Matrix4f viewMatrix = new Matrix4f();

    viewMatrix = transformation.createViewMatrix(camera);

    shaders.matrixUniforms("viewMatrix", viewMatrix);

    return viewMatrix;
}

public void createLight(Light light, float damper, float reflectivity) {

    shaders.vectorUniforms("lightPosition", light.getPosition());
    shaders.vectorUniforms("lightColor", light.getColor());
    shaders.floatUniforms("shineDamper", damper);
    shaders.floatUniforms("reflectivity", reflectivity);
}
}

如果我删除lightColor,shineDamper和reflectivity制服,则错误为:

java.lang.NullPointerException
at com.ms.shaders.ShaderProgram.matrixUniforms(ShaderProgram.java:83)
at com.ms.utils.UniformsCreation.createProjectionMatrix(UniformsCreation.java:46)
at com.ms.utils.UniformsCreation.renderer(UniformsCreation.java:29)
at com.ms.renderer.Renderer.render(Renderer.java:42)
at com.ms.MineSmooth.gameLoop(MineSmooth.java:93)
at com.ms.MineSmooth.run(MineSmooth.java:56)
at java.lang.Thread.run(Unknown Source)

1 个答案:

答案 0 :(得分:0)

负均匀位置为perfectly cromulent

  虽然不是严格意义上的错误,但有些人想知道为什么glGetUniformLocation   返回-1。如果你没有使用制服,那就是司机   将优化你的制服。司机非常善于优化   码。如果您使用的是制服,但没有计算出任何值   从那个制服贡献到着色器的任何输出(直接   或间接),制服通常会被优化。

     

通常这不是问题,因为如果你传递-1而不是a   有效统一的位置到glUniform调用,他们会悄然做   无论如何都没有。但如果拼错变量,你也会得到-1   命名为glGetUniformLocation,所以请记住这一点。

通过shader introspection API枚举统一名称,以检查拼写错误。