Pregunta

This is also from thebennybox's youtube 3D game engine series (if you found my previous post today), I'm having real trouble finding the problem in this addUniform method. the location always turns out to be 0xFFFFFFFF or -1, throwing the error that I defined "could not find uniform variable "uniformFloat" "

my vertex shader:

#version 330

layout (location = 0) in vec3 position;

out vec4 colour;

uniform float uniformFloat;

void main()
{
    colour = vec4(clamp(position, 0.0, uniformFloat), 1.0);
    gl_Position = vec4(position, 1.0);
}

my shader Class:

package com.base.engine;

import static org.lwjgl.opengl.GL20.*;
import static org.lwjgl.opengl.GL32.*;

import java.util.HashMap;

public class Shader {
    private int program;
    private HashMap<String, Integer> uniforms;

    public Shader() {
        program = glCreateProgram();
        uniforms = new HashMap<String, Integer>();

        if (program == 0) {
            System.err.println("Shader Creation failed: could not find valid memory location in constructor");
            System.exit(1);
        }
    }

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

    public void addUniform(String uniform){
        int uniformLocation = glGetUniformLocation(program, uniform);

        if (uniformLocation == 0xFFFFFFFF){
            System.err.println("Error: could not find uniform variable \"" + uniform + "\"");
            new Exception().printStackTrace();
            System.exit(1);
        }
        uniforms.put(uniform, uniformLocation);
    }

    public void addVertexShader(String text) {
        addProgram(text, GL_VERTEX_SHADER);
    }

    public void addGeometryShader(String text) {
        addProgram(text, GL_GEOMETRY_SHADER);
    }

    public void addFragmentShader(String text) {
        addProgram(text, GL_FRAGMENT_SHADER);
    }

    public void compileShader() {
        glLinkProgram(program);

        if (glGetProgrami(program, GL_LINK_STATUS) == 0) {
            System.err.println(glGetShaderInfoLog(program, 1024));
            System.exit(1);
        }

        glValidateProgram(program);
        if(glGetProgrami(program, GL_VALIDATE_STATUS) == 0){
            System.err.println(glGetShaderInfoLog(program, 1024));
            System.exit(1);
        }
    }

    private void addProgram(String text, int type) {
        int shader = glCreateShader(type);

        if (shader == 0) {
            System.err.println("Shader creation failed: could not find valid memory location when adding shader");
            System.exit(1);
        }

        glShaderSource(shader, text);
        glCompileShader(shader);

        if (glGetShaderi(shader, GL_COMPILE_STATUS) == 0) {
            System.err.println(glGetShaderInfoLog(shader, 1024));
            System.exit(1);
        }

        glAttachShader(program, shader);
    }

    public void setUniformi(String uniformName, int value){
        glUniform1i(uniforms.get(uniformName), value);
    }

    public void setUniformf(String uniformName, float value){
        glUniform1f(uniforms.get(uniformName), value);
    }

    public void setUniform(String uniformName, Vector3f value){
        glUniform3f(uniforms.get(uniformName), value.getX(), value.getY(), value.getZ());
    }

    public void setUniform(String uniformName, Matrix4f value){
        glUniformMatrix4(uniforms.get(uniformName), true, Util.createFlippedBuffer(value));
    }
}

and my implementation of the uniform variable, the Game class:

look particularly at the shader.addUniform line and the update() method.

package com.base.engine;

import org.lwjgl.input.Keyboard;

public class Game {
    private Mesh mesh;
    private Shader shader;

    public Game() {
        mesh = new Mesh();
        shader = new Shader();

        Vertex[] data = new Vertex[] {new Vertex(new Vector3f(-1, -1, 0)),
                                      new Vertex(new Vector3f(0, 1, 0)),
                                      new Vertex(new Vector3f(1, -1, 0))};
        mesh.addVertices(data);
        shader.addVertexShader(ResourceLoader.loadShader("basicVertex.vs"));
        shader.addFragmentShader(ResourceLoader.loadShader("basicFragment.fs"));
        shader.compileShader();

        shader.addUniform("uniformFloat");

    }

    public void input() {
        if (Input.getKeyDown(Keyboard.KEY_UP)) {
            System.out.println("We've just pressed up");
        }
        if (Input.getKeyUp(Keyboard.KEY_UP)) {
            System.out.println("We've just released up");
        }

        if (Input.getMouseDown(1)) {
            System.out.println("We've just pressed right-mouse at "
                    + Input.getMousePosition().toString());
        }
        if (Input.getMouseUp(1)) {
            System.out.println("We've just released right-mouse");
        }
    }

    float temp = 0.0f;

    public void update() {
        temp += Time.getDelta();
        shader.setUniformf("uniformFloat", (float)Math.sin(temp));
    }

    public void render() {
        shader.bind();
        mesh.draw();
    }
}

sorry that anyone reading has to wade through this code, but I've been staring at these for a while now. I've read that this can happen when you aren't using the uniform variable, but my shader is using it, right?

¿Fue útil?

Solución

Your uniform does not influence the result of your shader in any way so it is very likely to be completely removed. Only active uniforms have a location. Everything is working as it should.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top