首页 > 解决方案 > java lwjgl GLSL着色器问题与mac osx验证失败:没有顶点数组对象绑定

问题描述

我正在使用lwjgl在 Java 中构建 OPENGL 应用程序,并遵循 thebennybox 在 YouTube 上的部分教程

我可以使用我构建的 Mesh 类创建矩形。

import engine.core.Util;

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

public class Mesh {

    private int vbo;
    private int size;

    public Mesh() {
       this.vbo = glGenBuffers();
       this.size = 0;
    }

    public void addVertices(Vertex[] vertices){
        this.size = vertices.length * Vertex.SIZE;
        glBindBuffer(GL_ARRAY_BUFFER, vbo);
        glBufferData(GL_ARRAY_BUFFER, Util.createFlippedBuffer(vertices), GL_STATIC_DRAW);
    }

    public void draw(){
        glEnableVertexAttribArray(0);
        glBindBuffer(GL_ARRAY_BUFFER, vbo);
        glVertexAttribPointer(0, 3, GL_FLOAT, false, Vertex.SIZE * 4, 0);
        glDrawArrays(GL_TRIANGLES, 0, this.size);
        glDisableVertexAttribArray(0);
    }
}

util帮手

import engine.render.Vertex;
import org.lwjgl.BufferUtils;

import java.nio.FloatBuffer;

public class Util {

    public static FloatBuffer createFloatBuffer(int size){
        return BufferUtils.createFloatBuffer(size);
    }

    public static FloatBuffer createFlippedBuffer(Vertex[] vertices){

        FloatBuffer buffer = createFloatBuffer(vertices.length * Vertex.SIZE);

        for(int i = 0; i < vertices.length; i++) {
            buffer.put(vertices[i].getPos().getX());
            buffer.put(vertices[i].getPos().getY());
            buffer.put(vertices[i].getPos().getZ());
        }

        buffer.flip();
        return buffer;
    }
}

这是我的渲染方式

  this.mesh = new Mesh();

   Vertex[] data = new Vertex[]{
           //1st triangle
           new Vertex(new Vector3(0.5f,-0.5f,0)), //RB
           new Vertex(new Vector3(-0.5f,-0.5f,0)), //LB
           new Vertex(new Vector3(0.5f,0.5f,0)), //RT
           //2nd triangle
           new Vertex(new Vector3(-0.5f,0.5f,0)), //RB
           new Vertex(new Vector3(0.5f,0.5f,0)), //RT
           new Vertex(new Vector3(-0.5f,-0.5f,0)), //LB
   };

   mesh.addVertices(data);

   public void render(){ //update per frame
     mesh.draw();
   } 

到目前为止,它奏效了。然后我按照着色器教程并得到错误

验证失败:没有绑定顶点数组对象。

这是着色器类

import static org.lwjgl.opengl.GL32C.*;

public class Shader {

    private int program;

    public Shader() {
        program = glCreateProgram();

        if(program == 0){
            System.out.println("Shader creation failed!");
            System.exit(1);
        }
    }


    public void addVertexShader(String text){

        //System.out.println(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 bind(){
        glUseProgram(program);
    }

    public void compileShader(){

        glLinkProgram(program);

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

        glValidateProgram(program);

        if(glGetProgrami(program, GL_VALIDATE_STATUS) == 0){

           // System.out.println("ffff");
            System.out.println( glGetProgramInfoLog(program, 1024));
            System.exit(1);
        }

    }

    public void addProgram(String text, int type){

        int shader = glCreateShader(type);

        if(shader == 0){
            System.out.println("Shader creation failed!");
            System.exit(1);
        }

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

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

        glAttachShader(program, shader);

    }
}

这里是 ResourceLoader

  import java.io.BufferedReader;
  import java.io.FileReader;

  public class ResourceLoader {

      public static String loadShader(String fileName){

          StringBuilder shaderSource = new StringBuilder();
          BufferedReader shaderReader = null;

          try {
              shaderReader = new BufferedReader(new FileReader(fileName));
              String line;
              while ((line = shaderReader.readLine()) != null){
                  shaderSource.append(line).append("\n");
              }
          } catch (Exception e){
              System.out.println(e.getMessage());
          }

          return shaderSource.toString();
      }
  }

两个文件的 GLSL 代码

  ==== basicVertex.glsl
  #version 410 core

  out vec4 outColor;

  void main(){
  outColor = vec4(0.0, 1.0, 1.0, 1.0);
  }

  =========  basicFragment.glsl
  #version 410 core

  layout (location = 0) in vec3 position;


  void main(){
      gl_Position = vec4(position, 1.0);
  }

标签: javaopenglopencllwjgl

解决方案


您必须创建和使用Vertex Array Object

顶点数组对象存储通用顶点属性数据数组的规范。

指定顶点数组时创建并绑定 VAO。例如:

public class Mesh {

    private int vao;
    private int vbo;
    private int size;

    public Mesh() {
       this.size = 0;

       this.vao = glGenVertexArrays();
       this.vbo = glGenBuffers();

       glBindVertexArray(this.vao);

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

    // [...]
}

并在绘制几何图形时使用它:

public class Mesh {

    // [...]

    public void draw(){

        glBindVertexArray(this.vao);
        glDrawArrays(GL_TRIANGLES, 0, this.size);
        glBindVertexArray(0); // <--- Note, this is not needed
    }
}

推荐阅读