当前位置: 首页 > 知识库问答 >
问题:

LWJGL wiki上的示例代码由于GL_INVALID_OPERATION而失败

姚胡媚
2023-03-14

我只是复制粘贴的代码从本教程在LWJGL维基,我现在将粘贴在这里为您的方便。

import org.lwjgl.BufferUtils;
import org.lwjgl.LWJGLException;
import org.lwjgl.opengl.*;
import org.lwjgl.util.glu.GLU;

import java.nio.FloatBuffer;

public class TheQuadExampleDrawArrays {
  // Entry point for the application
  public static void main(String[] args) {
    new TheQuadExampleDrawArrays();
  }

  // Setup variables
  private final String WINDOW_TITLE = "The Quad: glDrawArrays";
  private final int WIDTH = 320;
  private final int HEIGHT = 240;
  // Quad variables
  private int vaoId = 0;
  private int vboId = 0;
  private int vertexCount = 0;

  public TheQuadExampleDrawArrays() {
    // Initialize OpenGL (Display)
    this.setupOpenGL();

    this.setupQuad();

    while (!Display.isCloseRequested()) {
      // Do a single loop (logic/render)
      this.loopCycle();

      // Force a maximum FPS of about 60
      Display.sync(60);
      // Let the CPU synchronize with the GPU if GPU is tagging behind
      Display.update();
    }

    // Destroy OpenGL (Display)
    this.destroyOpenGL();
  }

  public void setupOpenGL() {
    // Setup an OpenGL context with API version 3.2
    try {
      PixelFormat pixelFormat = new PixelFormat();
      ContextAttribs contextAtrributes = new ContextAttribs(3, 2)
        .withForwardCompatible(true)
        .withProfileCore(true);

      Display.setDisplayMode(new DisplayMode(WIDTH, HEIGHT));
      Display.setTitle(WINDOW_TITLE);
      Display.create(pixelFormat, contextAtrributes);

      GL11.glViewport(0, 0, WIDTH, HEIGHT);
    } catch (LWJGLException e) {
      e.printStackTrace();
      System.exit(-1);
    }

    // Setup an XNA like background color
    GL11.glClearColor(0.4f, 0.6f, 0.9f, 0f);

    // Map the internal OpenGL coordinate system to the entire screen
    GL11.glViewport(0, 0, WIDTH, HEIGHT);

    this.exitOnGLError("Error in setupOpenGL");
  }

  public void setupQuad() {
    // OpenGL expects vertices to be defined counter clockwise by default
    float[] vertices = {
      // Left bottom triangle
      -0.5f, 0.5f, 0f,
      -0.5f, -0.5f, 0f,
      0.5f, -0.5f, 0f,
      // Right top triangle
      0.5f, -0.5f, 0f,
      0.5f, 0.5f, 0f,
      -0.5f, 0.5f, 0f
    };
    // Sending data to OpenGL requires the usage of (flipped) byte buffers
    FloatBuffer verticesBuffer = BufferUtils.createFloatBuffer(vertices.length);
    verticesBuffer.put(vertices);
    verticesBuffer.flip();

    vertexCount = 6;

    // Create a new Vertex Array Object in memory and select it (bind)
    // A VAO can have up to 16 attributes (VBO's) assigned to it by default
    vaoId = GL30.glGenVertexArrays();
    GL30.glBindVertexArray(vaoId);

    // Create a new Vertex Buffer Object in memory and select it (bind)
    // A VBO is a collection of Vectors which in this case resemble the location of each vertex.
    vboId = GL15.glGenBuffers();
    GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, vboId);
    GL15.glBufferData(GL15.GL_ARRAY_BUFFER, verticesBuffer, GL15.GL_STATIC_DRAW);
    // Put the VBO in the attributes list at index 0
    GL20.glVertexAttribPointer(0, 3, GL11.GL_FLOAT, false, 0, 0);
    // Deselect (bind to 0) the VBO
    GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, 0);

    // Deselect (bind to 0) the VAO
    GL30.glBindVertexArray(0);

    this.exitOnGLError("Error in setupQuad");
  }

  public void loopCycle() {
    GL11.glClear(GL11.GL_COLOR_BUFFER_BIT);

    // Bind to the VAO that has all the information about the quad vertices
    GL30.glBindVertexArray(vaoId);
    GL20.glEnableVertexAttribArray(0);

    // Draw the vertices
    GL11.glDrawArrays(GL11.GL_TRIANGLES, 0, vertexCount);
    /**
     * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
     * I found that the GL_INVALID_OPERATION flag was being raised here,
     * at the call to glDrawArrays().
     * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
     */

    // Put everything back to default (deselect)
    GL20.glDisableVertexAttribArray(0);
    GL30.glBindVertexArray(0);

    this.exitOnGLError("Error in loopCycle");
  }

  public void destroyOpenGL() {
    // Disable the VBO index from the VAO attributes list
    GL20.glDisableVertexAttribArray(0);

    // Delete the VBO
    GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, 0);
    GL15.glDeleteBuffers(vboId);

    // Delete the VAO
    GL30.glBindVertexArray(0);
    GL30.glDeleteVertexArrays(vaoId);

    Display.destroy();
  }

  public void exitOnGLError(String errorMessage) {
    int errorValue = GL11.glGetError();

    if (errorValue != GL11.GL_NO_ERROR) {
      String errorString = GLU.gluErrorString(errorValue);
      System.err.println("ERROR - " + errorMessage + ": " + errorString);

      if (Display.isCreated()) Display.destroy();
      System.exit(-1);
    }
  }
}

当我运行它时,它抛出了一个错误

ERROR - Error in loopCycle: Invalid operation

我把它缩小到loopcycle()方法中对gldrawarrays()调用,然后点击Google了解这可能意味着什么,并发现了这个SO问题,其中列出了一大堆可能的原因(为了方便,这里列出了)。

> 如果非零缓冲区对象名称绑定到启用的数组或gl_draw_indirect_buffer绑定,并且当前映射了缓冲区对象的数据存储,则生成

  • gl_invalid_operation

    如果在执行glbegin和相应的glend之间执行了gldrawarrays,则生成gl_invalid_operation

    如果当前程序对象中的任何两个活动采样器类型不同,但引用相同的纹理图像单元,则gl_invalid_operation将由gldrawarraysgldrawelements生成。

    如果几何着色器处于活动状态且模式与当前安装的程序对象中几何着色器的输入基元类型不兼容,则生成gl_invalid_operation

    如果模式为gl_patches并且没有激活镶嵌控件着色器,则生成gl_invalid_operation

    如果将基元的顶点记录到用于转换反馈目的的缓冲区对象会导致超出任何缓冲区对象的大小限制,或者超出GLBindBufferRange设置的结束位置偏移量+大小-1,则生成GL_INVALID_OPERATION

    gl_invalid_operationgldrawarrays()生成,如果不存在几何着色器,转换反馈是活动的,并且模式不是允许的模式之一。

    gl_invalid_operationgldrawarrays()生成。如果存在几何着色器,则转换反馈处于活动状态,并且几何着色器的输出基元类型与转换反馈基元模型不匹配。

    如果绑定的着色器程序无效,则生成gl_invalid_operation

    如果正在使用转换反馈,则生成gl_invalid_operation,并且绑定到转换反馈绑定点的缓冲区也绑定到数组缓冲区绑定点。

    其中的大多数对我来说都是没有意义的,而且经过相当长时间的阅读,我还没有更接近于找出这段代码的问题所在。请有比我更了解这方面的人指出gl_invalid_operation标志升起的原因?

  • 共有1个答案

    梁丘洲
    2023-03-14

    项目9.看起来你没有着色程序绑定。

    您正在使用核心配置文件创建上下文:

      ContextAttribs contextAtrributes = new ContextAttribs(3, 2)
        .withForwardCompatible(true)
        .withProfileCore(true);
    

    对于核心配置文件,需要提供一个着色程序。您通常将在GLSL中至少编写一个顶点和一个片段着色器,然后使用类似以下的调用来构建和绑定一个着色器程序:

    glCreateShader
    glShaderSource
    glCompileShader
    glCreateProgram
    glAttachShader
    glLinkProgram
    glUseProgram
    
     类似资料:
    • 问题内容: 在创建所需的实际应用程序之前,我试图对此有一个基本的了解。我最近从2.7移到了3.3。 从python文档直接复制粘贴此代码失败,这里的一个简单示例也是如此。 这是我的代码,从第二个示例派生而来: 这是输出: 如何使此代码按预期工作?我希望这些示例可以立即使用。 问题答案: 这是我的错,有两个原因: 该代码不受保护,即没有 看起来奇怪的Traceback是因为未保存文件。以前从没给我造

    • 我想使用Android版的PDFBox从头开始创建PDF。应显示图像和表格,以及每个页面的重复PDF标题。 我使用的版本是com。tom_roush:pdfbox android:1.8.10.0,可在https://github.com/TomRoush/PdfBox-Android. 所以我克隆了存储库并尝试运行示例代码。Edit1:这是示例代码的链接:https://github.com/T

    • 本文向大家介绍AngularJS监听路由的变化示例代码,包括了AngularJS监听路由的变化示例代码的使用技巧和注意事项,需要的朋友参考一下 话不多说,我们下面直接来看实现的示例代码 【一】Angular 路由状态发生改变时可以通过' $stateChangeStart '、' $stateChangeSuccess '、' $stateChangeError '监听,通过注入'$locatio

    • 本文向大家介绍Vue三层嵌套路由的示例代码,包括了Vue三层嵌套路由的示例代码的使用技巧和注意事项,需要的朋友参考一下 Vue嵌套路由: 实现效果(路由三层嵌套,点击一级tab显示二级tab效果,二级tab点击切换对应内容,不在tab区域里的内容,切换时不重复渲染): Demo访问时路径:http://IP:端口/#/routers/ 1.建立案例文件夹 page/routers/ 1 route

    • crypto 加密实例代码 "use strict"; //引用crypto模块 const crypto = require("crypto"); //-------------MD5 可以任意多次调用update(),update()默认字符串编码是UTF-8 const hash = crypto.createHash("md5"); hash.update("hello, world!"

    • 服务热重启 控制器 Model与数据库 redis封装示例 kafka使用 web socket web socket命令解析 web socket client 直播 TCP基础实现 TCP命令解析 UDP UDP命令解析 自定义Event Loop 图片验证码 多进程爬虫 使用模板引擎