java - LWJGL VAO/VBO 不显示

标签 java opengl glsl lwjgl glfw

这是我的代码:

import org.lwjgl.*;
import org.lwjgl.glfw.*;
import org.lwjgl.opengl.*;
import org.lwjgl.system.*;

import java.io.File;
import java.nio.*;
import java.util.Scanner;

import static org.lwjgl.glfw.Callbacks.*;
import static org.lwjgl.glfw.GLFW.*;
import static org.lwjgl.opengl.GL11.*;
import static org.lwjgl.opengl.GL12.*;
import static org.lwjgl.opengl.GL13.*;
import static org.lwjgl.opengl.GL14.*;
import static org.lwjgl.opengl.GL15.*;
import static org.lwjgl.opengl.GL20.*;
import static org.lwjgl.opengl.GL21.*;
import static org.lwjgl.opengl.GL30.*;
import static org.lwjgl.opengl.GL31.*;
import static org.lwjgl.opengl.GL32.*;
import static org.lwjgl.opengl.GL33.*;
import static org.lwjgl.opengl.GL40.*;
import static org.lwjgl.opengl.GL41.*;
import static org.lwjgl.opengl.GL42.*;
import static org.lwjgl.opengl.GL43.*;
import static org.lwjgl.opengl.GL44.*;
import static org.lwjgl.opengl.GL45.*;
import static org.lwjgl.opengl.GL46.*;
import static org.lwjgl.system.MemoryStack.*;
import static org.lwjgl.system.MemoryUtil.*;

public class Test {

  public static void main(String[] args) {

    if (!glfwInit()) {
      System.out.println("GLFW not init.");
      return;
    }

    glfwDefaultWindowHints();
    glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4);
    glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 1);
    glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GLFW_TRUE);
    glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
    long window = glfwCreateWindow(500, 500, "Window", NULL, NULL);
    if (window == NULL) {
      System.out.println("Window not create.");
      return;
    }

    glfwMakeContextCurrent(window);
    glfwSwapInterval(1);
    glfwShowWindow(window);

    GL.createCapabilities();

    Utilities.printGLInfo();

    int vert=glCreateShader(GL_VERTEX_SHADER);
    glShaderSource(vert, Utilities.loadStrFromFile("Shaders/shader.vert"));
    glCompileShader(vert);
    if(glGetShaderi(vert, GL_COMPILE_STATUS)==GL_FALSE) {
      System.out.println("Vertex shader compilation error:\n"+glGetShaderInfoLog(vert));
    }
    int frag=glCreateShader(GL_FRAGMENT_SHADER);
    glShaderSource(frag, Utilities.loadStrFromFile("Shaders/shader.frag"));
    glCompileShader(frag);
    if(glGetShaderi(frag, GL_COMPILE_STATUS)==GL_FALSE) {
      System.out.println("Fragment shader compilation error:\n"+glGetShaderInfoLog(frag));
    }

    int prog=glCreateProgram();
    glAttachShader(prog, vert);
    glAttachShader(prog, frag);
    glLinkProgram(prog);

    float[]vboData=new float[] {
        0,0,0,
        1,0,0,
        0,1,0
    };

    int vao=glGenVertexArrays();
    int vbo=glGenBuffers();


    glBindVertexArray(vao);

    glBindBuffer(GL_ARRAY_BUFFER,vbo);
    glBufferData(GL_ARRAY_BUFFER, FloatBuffer.wrap(vboData), GL_STATIC_DRAW);
    glEnableVertexAttribArray(0);
    glVertexAttribPointer(0, 3, GL_FLOAT, false, 3*Float.BYTES, 0);

    glBindVertexArray(0);


    System.out.println("prog="+prog+",vert="+vert+",frag="+frag);
    System.out.println("vao="+vao+",vbo="+vbo);

    while (!glfwWindowShouldClose(window)) {
      glClearColor(1, 1, 1, 1);
      glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

      glUseProgram(prog);

      glBindVertexArray(vao);
//      glDrawElements(GL_TRIANGLES, indices);
      glDrawArrays(GL_TRIANGLES, 0, 3);
      glBindVertexArray(0);

      glUseProgram(0);

      glfwSwapBuffers(window);
      glfwPollEvents();
    }

    glfwDestroyWindow(window);
    glfwTerminate();

  }

}

这是它打印的内容:

Version       : 4.1 ATI-1.66.31
Vendor        : ATI Technologies Inc.
Renderer      : AMD Radeon Pro 560 OpenGL Engine
GLSL version  : 4.10
Major version : 4
Minor version : 1
prog=3,vert=1,frag=2
vao=1,vbo=1

因此正确生成了着色器和 vao/vbos。

顶点着色器:

#version 410 core

layout (location = 0) in vec3 inPos;

out vec4 outPos;

void main(){
    outPos=vec4(inPos,1.0);
}

片段着色器:

#version 410 core

out vec4 fragColor;

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

我使用的是 macOS High Sierra 版本 10.13.4。

图形:

Radeon Pro 560 4096 MB
Intel HD Graphics 630 1536 MB

它显示一个具有正确宽度、高度和标题的白色窗口。 我认为问题出在我的 glVertexAttribPointer 调用上,我听说过一种叫做“缓冲区翻转”的东西,这可能是错误的。

编辑:

为了回应一些评论,使用这个顶点着色器:

#version 410 core

layout (location = 0) in vec3 inPos;

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

没有任何变化。

最佳答案

您必须在顶点着色器中写入 gl_Position。写入gl_Position 的齐次坐标用于图元组装。您不能指定自己的“输出”变量,因为您可以在片段着色器中这样做。 Vertex Shader 中的输出变量是变化的变量,它们被传递到管道的下一部分。

#version 410 core

layout (location = 0) in vec3 inPos;

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

参见 GLSL - The OpenGL Shading Language 4.6; 7.1.1. Vertex Shader Special Variables; page 131

The variable gl_Position is intended for writing the homogeneous vertex position. It can be written at any time during shader execution. This value will be used by primitive assembly, clipping, culling, and other fixed functionality operations, if present, that operate on primitives after vertex processing has occurred. Its value is undefined after the vertex processing stage if the vertex shader executable does not write gl_Position.


此外,在数据传输到缓冲区后,您还必须flip() 缓冲区。另见:

float[]vboData=new float[] { 0,0,0,  1,0,0,  0,1,0 };

FloatBuffer buf = BufferUtils.createFloatBuffer(vboData.length);
buf.put(vboData).flip();

glBufferData(GL_ARRAY_BUFFER, buf, GL_STATIC_DRAW);

解释:

put(vboData) 将数据传输到缓冲区,从当前位置开始(在本例中是缓冲区的开头)。缓冲区位置按数据大小递增。所以新的缓冲区位置在新数据的末尾。

flip() 将缓冲区的限制(长度)设置为当前位置,然后将位置设置为零。

当您将缓冲区数据传递给 glBufferData 时,将检索指向缓冲区当前位置数据的指针。

关于java - LWJGL VAO/VBO 不显示,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51003614/

相关文章:

java - 用于打开完整编辑器以在 svn 中比较文件的键盘快捷键

java - JList 和 ArrayList 更新

c++ - 通过操纵 gl_FragDepth 将选定的线对象优先于其他对象

opengl - glsl 性能 : tan(acos(x)) vs sqrt(1-x*x)/x

opengl - 循环是在 GPU 上按顺序执行还是并行执行?

java - 在新线程中打开 Eclipse Wizard 或 Eclipse MessageDialog

java - Spring Boot Actuator 1.4.7 - 我的 REST 应用程序缺少 Health Endpoint (404)

c++ - QGLShaderProgram::setAttributeArray(0, ...) 与 QGLShaderProgram::setAttributeArray ("position", ...)

c++ - 在 C++ 中强制使用 Opengl 2.0 及更高版本

c++ - Mac OSX 10.9 中的 Glut 弃用,IDE : QT Creator