未绘制OpenGL顶点

时间:2015-04-26 18:18:22

标签: java opengl lwjgl

我尝试了一整天让OpenGL在Java中工作(使用LWJGL 3 / GLFW)。问题是,除了清晰的颜色,我也看不到任何画面。

问题:

  1. 我的OpenGL函数的顺序是否正常?
  2. 有任何错误吗? 这会阻止绘制顶点吗?
  3. 除了初始化之外,这是OpenGL调用的顺序。完整的程序可以在http://pastebin.com/JWJ7pqBs找到,并且源自LWJGL 3"入门" - 示例以跳过初始化部分。

    编辑:更正了derhass所述的一些错误。但仍然没有可见的输出。 http://pastebin.com/FbkuusM3

    EDIT2:在片段着色器中尝试使用固定颜色,但没有绘制顶点。

    变量:

    int shader;
    int vao;
    int vbo;
    

    创建着色器(一次):

        String dummyVertexShaderSrc =
                    "#version 330 core"
                    + "\n" + "layout(location = 0) in vec3 vs_position;"
                    + "\n" + "layout(location = 1) in vec4 vs_color;"
                    + "\n" + ""
                    + "\n" + "out vec4 fs_color;"
                    + "\n" + ""
                    + "\n" + "void main() {"
                    + "\n" + "    gl_Position = vec4(vs_position, 1.0);"
                    + "\n" + "    fs_color = vs_color;"
                    + "\n" + "}"
                    ;
    
            String dummyFragmentShaderSrc = "#version 330 core"
                    + "\n" + "in vec4 fs_color;"
                    + "\n" + "void main() {"
                    + "\n" + "    gl_FragColor = fs_color;"
                    + "\n" + "}";
    
            System.out.println("Vertex-Shader: \n" + dummyVertexShaderSrc + "\n");
            System.out.println("Fragment-Shader: \n" + dummyFragmentShaderSrc + "\n");
    
            // 1# Read/Compile VertexShader
            int idVertexShader = GL20.glCreateShader(GL20.GL_VERTEX_SHADER);
            GL20.glShaderSource(idVertexShader, dummyVertexShaderSrc);
            GL20.glCompileShader(idVertexShader);
    
            if (GL20.glGetShaderi(idVertexShader, GL20.GL_COMPILE_STATUS) == GL11.GL_FALSE) {
                System.err.println("Could not compile vertex shader: " + GL20.glGetShaderInfoLog(idVertexShader));
                System.exit(-1);
            }
    
            // 2# Read/Compile FragmentShader
            int idFragmentShader = GL20.glCreateShader(GL20.GL_FRAGMENT_SHADER);
            GL20.glShaderSource(idFragmentShader, dummyFragmentShaderSrc);
            GL20.glCompileShader(idFragmentShader);
    
            if (GL20.glGetShaderi(idFragmentShader, GL20.GL_COMPILE_STATUS) == GL11.GL_FALSE) {
                System.err.println("Could not compile fragment shader: " + GL20.glGetShaderInfoLog(idFragmentShader));
                System.exit(-1);
            }
    
            // 3# Create Shader-Program
            shader = GL20.glCreateProgram();
            GL20.glAttachShader(shader, idVertexShader);
            GL20.glAttachShader(shader, idFragmentShader);
    
            GL20.glBindAttribLocation(shader, 0, "vs_position");
            GL20.glBindAttribLocation(shader, 1, "vs_color");
    
            GL20.glLinkProgram(shader);
            if (GL20.glGetProgrami(shader, GL20.GL_LINK_STATUS) == GL11.GL_FALSE) {
                System.out.println("Shader linking failed: " + GL20.glGetProgramInfoLog(shader));
                System.exit(-1);
            }
    
            GL20.glValidateProgram(shader);
            GL20.glDeleteShader(idVertexShader);
            GL20.glDeleteShader(idFragmentShader);
    

    创建VAO / VBO(一次):

            vao = GL30.glGenVertexArrays();
            GL30.glBindVertexArray(vao);
    
                vbo = GL15.glGenBuffers();
                GL15.glBindBuffer( GL15.GL_ARRAY_BUFFER, vbo);
                GL15.glBufferData( GL15.GL_ARRAY_BUFFER, 1024 * Vertex.ByteSize, null, GL15.GL_STREAM_DRAW );
    
                GL20.glEnableVertexAttribArray(0);
                GL20.glVertexAttribPointer(0, 3, GL11.GL_FLOAT, false, 0, 0);
    
                GL20.glEnableVertexAttribArray(1);
                GL20.glVertexAttribPointer(1, 4, GL11.GL_FLOAT, false, 0, 3);
    
                GL20.glDisableVertexAttribArray(0);
                GL20.glDisableVertexAttribArray(1);
    
                GL15.glBindBuffer( GL15.GL_ARRAY_BUFFER, 0);
    
            GL30.glBindVertexArray(0);  
    

    用数据填充VAO / VBO(一次):

        Vertex[] vertices = new Vertex[] {
                    new Vertex(new Vector3f(-1.0f, -1.0f, 0.0f), new Color4f(0.5f, 0.5f, 0.5f, 0.5f), Vector2f.Zero),
                    new Vertex(new Vector3f( 1.0f, -1.0f, 0.0f), new Color4f(0.5f, 0.5f, 0.5f, 0.5f), Vector2f.Zero),
                    new Vertex(new Vector3f( 0.0f,  1.0f, 0.0f), new Color4f(0.5f, 0.5f, 0.5f, 0.5f), Vector2f.Zero),
            };
    
            // 1# Create buffer
            FloatBuffer buffer = ByteBuffer.allocateDirect(3 * 7 * Float.BYTES).asFloatBuffer();
            buffer.position(0);
            for(Vertex vertex : vertices) {
                buffer.put(vertex.position.x);
                buffer.put(vertex.position.y);
                buffer.put(vertex.position.z);
                buffer.put(vertex.color.r);
                buffer.put(vertex.color.g);
                buffer.put(vertex.color.b);
                buffer.put(vertex.color.a);
            }
    
            // 2# Write data
            GL30.glBindVertexArray(vao);
    
                GL15.glBindBuffer( GL15.GL_ARRAY_BUFFER, vbo);
                GL15.glBufferSubData( GL15.GL_ARRAY_BUFFER, 3 * 7, buffer);
                GL15.glBindBuffer( GL15.GL_ARRAY_BUFFER, 0);
    
            GL30.glBindVertexArray(0);
    

    最后在主循环中绘制顶点(多次):

            GL20.glUseProgram(shader);
            GL30.glBindVertexArray( vao );
            GL20.glEnableVertexAttribArray(0);
            GL20.glEnableVertexAttribArray(1);
    
            GL11.glDrawArrays( GL11.GL_TRIANGLES, 0, 3 );
    
            GL20.glDisableVertexAttribArray(1);
            GL20.glDisableVertexAttribArray(0);
            GL30.glBindVertexArray( 0 );
            GL20.glUseProgram(0);
    

2 个答案:

答案 0 :(得分:1)

在查看代码时,我发现了一些错误:

GL20.glVertexAttribPointer(1, 4, GL11.GL_FLOAT, false, 0, 3);

您可能正在使用交错属性,但是,3个字节offset在这里肯定是错误的。您似乎想要跳过属性0的3个浮点数,因此这很可能是3 *sizeof(GLfloat)

此外,您的stride参数也是错误的:您告诉GL您的属性紧密包装每个。您可能希望7*sizeof(GLfloat)作为步幅:

以下是不需要的:

GL20.glDisableVertexAttribArray(0);
GL20.glDisableVertexAttribArray(1);

VAO将跟踪使能位以及指针值。您不需要在此VAO中禁用它们,并在绘制时重新启用和禁用它们。只需将它们保持启用状态,然后进行绘图,即可绑定VAO。

上传数据时:     GL15.glBufferSubData(GL15.GL_ARRAY_BUFFER,3 * 7,缓冲区);

你忘了这些大小和偏移都是以字节为单位,所以你需要再次乘以浮点大小。但是,我并不完全明白你在这里做了什么。 glBufferSubData()需要偏移量和大小。可能会从java API中删除大小pI,因为它在缓冲区对象中是众所周知的,所以为什么在这里使用不同于0的偏移量?

答案 1 :(得分:0)

问题是@model IEnumerable<MyBlogger.Models.Post> @foreach (var item in Model) { <p class="text-left">Similar Article: <a href="@Url.Action("Details", "Post", new { urlslug = item.UrlSlug })">@Html.DisplayFor(modelItem => item.Title)</a></p> } 以大端格式分配缓冲区,无论代码运行在哪台机器上。 ("All x86 and x86-64 machines [..] are little-endian"

解决方案是手动交换位或只使用LWJGL的ByteBuffer.allocateDirect类,它以当前机器使用的格式创建BufferUtils