2016-10-17 3 views
-1

문제는 제목에 있습니다.fragmentShader에서 유니폼을 찾을 수 없습니다. lwgl 3

콘솔 오류

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

내가 shineDamper 유니폼 오류 스위치 lightColor 유니폼을 제거하려고합니다.

편집을 할

내가 문제가 존재하지 않는 렌더러 클래스의 모든 넣으면 ... 왜?

이 내가 유니폼 설정하는 클래스입니다 :

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를 제거하고 반사율 유니폼 오류가있는 경우 :

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) 
+0

균일 변수뿐만 아니라 사용 된 다른 변수를 검사해야합니다. lightColor 또는 shineDamper와 관련된 하나의 변수가 유효하지 않으면 균일 한 varialbe가 생략됩니다. – Tokenyet

답변

0

부정적인 균일 위치는 perfectly cromulent :

입니다.

엄밀히 말하자면, 왜 glGetUniformLocation 이 -1을 반환하는지 궁금해하는 사람들도 있습니다. 당신이 사용하지 않는 제복이 있다면, 드라이버 은 유니폼을 최적화 할 것입니다. 드라이버는 코드를 최적화하는 데 정말로 능숙합니다. 유니폼을 사용하고 있지만 그 유니폼에서 산출 된 값이 쉐이더의 출력 (직접적으로 )에 기여하지 않는 경우 유니폼은 일반적으로 최적화됩니다.

glUniform 호출에 유효한 균일 위치 인 대신 -1을 전달하면 일반적으로 아무것도 허용되지 않으므로 어쨌든 을 수행하지 않습니다. glGetUniformLocation에 변수 의 이름을 잘못 입력하면 -1을 얻게되므로 유의하시기 바랍니다.

맞춤법 오류를 확인하기 위해 shader introspection API을 통해 통일 된 이름을 열거하십시오.

+0

모든 유니폼의 이름이 정확합니다. 단, 문제는 fragmentShader 파일의 유니폼에만 있습니다. – Trese

관련 문제