尝试 glUseProgram 时出现 Opengl 错误 1281

Opengl error 1281 when trying to glUseProgram

关于如何进一步调试此 opengl 错误的任何想法? 1281

我正在从文件加载源代码、编译、链接,然后在 glUseProgram

之后尝试检查错误

在我对象的绘制方法中..

log.info(gl2.glIsProgram(shaderProgram)); // true
gl2.glUseProgram(shaderProgram);

int error;
while ((error = gl2.glGetError()) != GL2.GL_NO_ERROR) {
    throw new RuntimeException("glUseProgram" + ": glError " + error);
}

输出..

[13:38:08] INFO (IARectangle.java:99) - true
java.lang.RuntimeException: glUseProgram: glError 1281

这就是我从 .glsl 文件加载着色器源代码的方式..

Vector<Integer> shaders = new Vector<Integer>();

try {

    shaders.add(compileSource(
        loadSource("shaders/vertexShader.glsl"),
        loadSource("shaders/fragmentShader.glsl")));

    return shaders;

} catch (Exception e) {
    e.printStackTrace();
    return shaders;
}

public String[] loadSource(String filename){

    StringBuilder sb = new StringBuilder();
    try {

        InputStream is = getClass().getClassLoader().getResourceAsStream(filename);
        BufferedReader br = new BufferedReader(new InputStreamReader(is, "UTF-8"));
        String line;
        while ((line = br.readLine()) != null) {

            sb.append(line);
            sb.append('\n');
        }
        is.close();

    } catch (Exception e) {
        e.printStackTrace();
    }

    return new String[] { sb.toString() };
}

public final int compileSource(final String[] vertexSource, final String[] fragmentSource) throws Exception {

     vertexShaderProgram;
    int fragmentShaderProgram;
    int shaderProgram;

    // load vertexShader source, compile and verify
    vertexShaderProgram = gl2.glCreateShader(GL2.GL_VERTEX_SHADER);
    gl2.glShaderSource(vertexShaderProgram, 1, vertexSource, null, 0);
    gl2.glCompileShader(vertexShaderProgram);
    verifyCompile(gl2, vertexShaderProgram);

    // load fragmentShader source, compile and verify
    fragmentShaderProgram = gl2.glCreateShader(GL2.GL_FRAGMENT_SHADER);
    gl2.glShaderSource(fragmentShaderProgram, 1, fragmentSource, null, 0);
    gl2.glCompileShader(fragmentShaderProgram);
    verifyCompile(gl2, fragmentShaderProgram);

    shaderProgram = gl2.glCreateProgram();

    gl2.glAttachShader(shaderProgram, vertexShaderProgram);
    gl2.glAttachShader(shaderProgram, fragmentShaderProgram);
    gl2.glLinkProgram(shaderProgram);
    IntBuffer intBuffer = IntBuffer.allocate(1);
    gl2.glGetProgramiv(shaderProgram, GL2.GL_LINK_STATUS, intBuffer);

    if (intBuffer.get(0) != 1){

        String infoLog = null;
        gl2.glGetProgramiv(shaderProgram, GL2.GL_INFO_LOG_LENGTH, intBuffer);
        int size = intBuffer.get(0);
        log.error("Program link error: ");
        if (size > 0) {

            ByteBuffer byteBuffer = ByteBuffer.allocate(size);
            gl2.getGL2().glGetProgramInfoLog(shaderProgram, size, intBuffer, byteBuffer);
            byte[] sizeBytes = new byte[size];
            byteBuffer.get(sizeBytes, 0, size);
            infoLog = new String(sizeBytes);

            log.error("info: " + infoLog);

        } else {
            log.error("Unknown");
        }
        System.exit(1);
        return shaderProgram;

    } else {

        return shaderProgram;
    }
}

顶点着色器源..

#version 120

uniform mat4 uMVPMatrix;
attribute vec4 vPosition;

void main() {
    gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
    //gl_Position = uMVPMatrix * vPosition;
}

片段着色器源..

#version 120

uniform vec4 vColor;

void main() {
    gl_FragColor = vColor;
}

乍一看,我不确定为什么 glGetError 是 return 错误代码。但是要回答你的 'How can I debug this error further?' 的具体问题,我有一个建议。

将您的绘制代码更改为:

// Logging errors before the call to glUseProgram
int error;
while ((error = gl2.glGetError()) != GL2.GL_NO_ERROR) {
    log.info(error);
}

log.info(gl2.glIsProgram(shaderProgram)); // true
gl2.glUseProgram(shaderProgram);

int error;
while ((error = gl2.glGetError()) != GL2.GL_NO_ERROR) {
    throw new RuntimeException("glUseProgram" + ": glError " + error);
}

请注意,这里的不同之处在于我们添加了一段代码来记录 return 由 glGetError 调用 [=] 之前编辑的错误13=]。原因是 错误不一定源自您对 glUseProgram 的调用。如果您看到使用上面的代码记录的 1281 错误,则可以确定该错误实际上源自 glUseProgram 调用之前进行的 OpenGL 调用。

看看 glGetErrordocumentation:

glGetError returns the value of the error flag. Each detectable error is assigned a numeric code and symbolic name. When an error occurs, the error flag is set to the appropriate error code value. No other errors are recorded until glGetError is called, the error code is returned, and the flag is reset to GL_NO_ERROR.

因此,如果您之前的 OpenGL 调用之一(例如,可能是您的 compileSource 函数中的某些内容)记录了 1281 错误,并且您没有在两者之间的任何地方调用 glGetError那一点和您对 glUseProgram 的调用,您不能合理地假设该错误实际上源自 glUseProgram 调用。

总而言之,glGetError 不是 return OpenGL 调用记录的最新错误。您需要更精细地调用 glGetError 才能查明错误的来源。这将使您能够解决遇到的问题并准确确定记录错误的 OpenGL 调用。