Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/386.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/opengl/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 我能';t更改片段着色器中的颜色_Java_Opengl_Shader_Lwjgl - Fatal编程技术网

Java 我能';t更改片段着色器中的颜色

Java 我能';t更改片段着色器中的颜色,java,opengl,shader,lwjgl,Java,Opengl,Shader,Lwjgl,我在学习OpenGL,我试图画一个红色的三角形,但我的三角形一直是黑色的 这是我的片段着色器的代码: #version 330 core out vec4 color; void main() { color = vec4(1,0,0,1); } 并且我的着色器编译没有问题,我使用这个类来使用着色器: public class ShaderProgram { private final int programId; private int vertexShader

我在学习OpenGL,我试图画一个红色的三角形,但我的三角形一直是黑色的

这是我的片段着色器的代码:

#version 330 core

out vec4 color;

void main()
{
    color = vec4(1,0,0,1);
}
并且我的着色器编译没有问题,我使用这个类来使用着色器:

public class ShaderProgram
{
    private final int programId;

    private int vertexShaderId;

    private int fragmentShaderId;

    public ShaderProgram() throws Exception
    {
        programId = glCreateProgram();
        if (programId == 0) {
            throw new Exception("Could not create Shader");
        }
    }

    public void createVertexShader(String shaderCode) throws Exception {
        vertexShaderId = createShader(shaderCode, GL_VERTEX_SHADER);
    }

    public void createFragmentShader(String shaderCode) throws Exception {
        fragmentShaderId = createShader(shaderCode, GL_FRAGMENT_SHADER);
    }

    protected int createShader(String shaderCode, int shaderType) throws Exception {
        int shaderId = glCreateShader(shaderType);
        if (shaderId == 0) {
            throw new Exception("Error creating shader. Code: " + shaderId);
        }

        glShaderSource(shaderId, shaderCode);
        glCompileShader(shaderId);

        if (glGetShaderi(shaderId, GL_COMPILE_STATUS) == 0) {
            throw new Exception("Error compiling Shader code: " + glGetShaderInfoLog(shaderId, 1024));
        }

        glAttachShader(programId, shaderId);

        return shaderId;
    }

    public void link() throws Exception {
        glLinkProgram(programId);
        if (glGetProgrami(programId, GL_LINK_STATUS) == 0) {
            throw new Exception("Error linking Shader code: " + glGetShaderInfoLog(programId, 1024));
        }

        glValidateProgram(programId);
        if (glGetProgrami(programId, GL_VALIDATE_STATUS) == 0) {
            System.err.println("Warning validating Shader code: " + glGetShaderInfoLog(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);
            }
            if (fragmentShaderId != 0) {
                glDetachShader(programId, fragmentShaderId);
            }
            glDeleteProgram(programId);
        }
    }
}
这是我的游戏课:

public class Game {

    int vertexArrayID;
    int vertexBufferID;

    ShaderProgram fragmentShader;
    ShaderProgram vertexShader;

    float[] vertexData =
        {
            -1.0f, -1.0f, 0.0f,
            1.0f, -1.0f, 0.0f,
            0.0f,  1.0f, 0.0f,
        };

    FloatBuffer vertexBuffer;

    public Game() throws Exception {
        vertexArrayID = glGenVertexArrays();
        glBindVertexArray(vertexArrayID);

        vertexBufferID = glGenBuffers();
        glBindBuffer(GL_ARRAY_BUFFER, vertexBufferID);

        vertexBuffer = BufferUtils.createFloatBuffer(vertexData.length);
        vertexBuffer.put(vertexData);
        vertexBuffer.flip();

        glBufferData(GL_ARRAY_BUFFER, vertexBuffer,GL_STATIC_DRAW);

        fragmentShader = new ShaderProgram();
        vertexShader = new ShaderProgram();

        fragmentShader.createFragmentShader(loadShader("fragmentShader.glsl"));
        vertexShader.createVertexShader(loadShader("vertexShader.glsl"));

        fragmentShader.link();
        vertexShader.link();
    }

    public void update()
    {
        fragmentShader.bind();
        vertexShader.bind();

        glEnableVertexAttribArray(0);
        glBindBuffer(GL_ARRAY_BUFFER,vertexBufferID);
        glVertexAttribPointer(0,3,GL_FLOAT,false,0,0);

        glDrawArrays(GL_TRIANGLES,0,3);
        glDisableVertexAttribArray(0);

        fragmentShader.unbind();
        vertexShader.unbind();
    }

    private String loadShader(String input) {
        String r = "";

        try {
            BufferedReader reader = new BufferedReader(new InputStreamReader(Game.class.getResourceAsStream("/shaders/" + input)));
            String buffer = "";
            while ((buffer = reader.readLine()) != null) {
                r += buffer + "\n";
            }
            reader.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return r;
    }
}

为什么我的三角形在那之后保持黑色?

看起来你误解了OpenGL中程序和着色器的使用

着色器
对象对应于OpenGL中的“着色器阶段”,即顶点着色器或片段着色器或OpenGL图形管道中的其他可编程阶段之一

Program
对象对应于组合的着色器阶段链,有时通俗地称为完整的“着色器”

但是,在您的程序中,您似乎正在创建两个程序,将顶点着色器附加到一个程序,将片段着色器附加到另一个程序,并同时使用这两个程序。据我所知,这不会导致OpenGL抛出错误(它只会对缺少的任何一个阶段使用基本的穿透着色器),但这也意味着在任何时候只有其中一个阶段处于活动状态,而另一个阶段处于非活动状态。在您的情况下,
update
函数中的代码:

fragmentShader.bind();
vertexShader.bind();
意味着只使用顶点着色器,这就是为什么对片段着色器进行更改没有效果


若要解决此问题,请仅创建一个
ShaderProgram
对象,并分别调用
create[X]shader
将顶点和片段着色器源代码附加到该对象。将其链接一次,然后在
更新
功能中,仅调用
使用
。完成此操作后,程序应能按预期工作。

看起来您误解了OpenGL中程序和着色器的使用

着色器
对象对应于OpenGL中的“着色器阶段”,即顶点着色器或片段着色器或OpenGL图形管道中的其他可编程阶段之一

Program
对象对应于组合的着色器阶段链,有时通俗地称为完整的“着色器”

但是,在您的程序中,您似乎正在创建两个程序,将顶点着色器附加到一个程序,将片段着色器附加到另一个程序,并同时使用这两个程序。据我所知,这不会导致OpenGL抛出错误(它只会对缺少的任何一个阶段使用基本的穿透着色器),但这也意味着在任何时候只有其中一个阶段处于活动状态,而另一个阶段处于非活动状态。在您的情况下,
update
函数中的代码:

fragmentShader.bind();
vertexShader.bind();
意味着只使用顶点着色器,这就是为什么对片段着色器进行更改没有效果

若要解决此问题,请仅创建一个
ShaderProgram
对象,并分别调用
create[X]shader
将顶点和片段着色器源代码附加到该对象。将其链接一次,然后在
更新
功能中,仅调用
使用
。完成此操作后,程序应按预期工作。

请提供适当的解决方案。这几乎不足以正确诊断问题。特别是,了解着色器/程序是如何初始化和使用的将非常有价值。由于您声称正在学习OpenGL,您应该能够毫无问题地包含整个“主机”(即C++)代码。请提供适当的说明。这几乎不足以正确诊断问题。特别是,了解着色器/程序是如何初始化和使用的将非常有价值。既然您声称正在学习OpenGL,那么您应该能够毫无问题地包含整个“主机”(即C++)代码。