LWJGL 3 中的抗锯齿

Anti-aliasing in LWJGL 3

我正在尝试在 LWJGL 3 中绘制一个消除锯齿的正方形。我只绘制 2D 精灵,而不绘制纹理。 This answer to a similar question reveals that anti-aliasing in LWJGL must be achieved with post-processing, but does not actually give an example or any resources on how to do this. Below is an example of some code. This is what is rendered on screen from the code.请告诉我如何修改此代码以使抗锯齿成为可能。

import java.nio.FloatBuffer;
import java.nio.IntBuffer;

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

import static org.lwjgl.glfw.GLFW.*;
import static org.lwjgl.opengl.GL11.*;
import static org.lwjgl.system.MemoryUtil.*;
import static org.lwjgl.opengl.GL15.*;

public class LWJGLTest {

    private GLFWErrorCallback errorCallback;
    private GLFWKeyCallback   keyCallback;

    private long window;

    public void run() {

        try {
            init();
            loop();

            glfwDestroyWindow(window);
            keyCallback.release();
        } finally {

            glfwTerminate();
            errorCallback.release();
        }
    }

    int WIDTH = 300;
    int HEIGHT = 300;

    private void init() {

        glfwSetErrorCallback(errorCallback = GLFWErrorCallback.createPrint(System.err));

        if ( glfwInit() != GLFW_TRUE )
            throw new IllegalStateException("Unable to initialize GLFW");

        glfwDefaultWindowHints();
        glfwWindowHint(GLFW_VISIBLE, GLFW_FALSE);
        glfwWindowHint(GLFW_RESIZABLE, GLFW_TRUE);

        window = glfwCreateWindow(WIDTH, HEIGHT, "Hello World!", NULL, NULL);
        if ( window == NULL )
            throw new RuntimeException("Failed to create the GLFW window");

        glfwSetKeyCallback(window, keyCallback = new GLFWKeyCallback() {
            @Override
            public void invoke(long window, int key, int scancode, int action, int mods) {
                if ( key == GLFW_KEY_ESCAPE && action == GLFW_RELEASE )
                    glfwSetWindowShouldClose(window, GLFW_TRUE);
            }
        });

        GLFWVidMode vidmode = glfwGetVideoMode(glfwGetPrimaryMonitor());

        glfwSetWindowPos(
            window,
            (vidmode.width() - WIDTH) / 2,
            (vidmode.height() - HEIGHT) / 2
        );

        glfwMakeContextCurrent(window);
        glfwSwapInterval(1);

        glfwShowWindow(window);
    }

    private void loop() {
        GL.createCapabilities();

        glClearColor(1.0f, 1.0f, 1.0f, 0.0f);

        while ( glfwWindowShouldClose(window) == GLFW_FALSE ) {
            glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

            draw();

            glfwSwapBuffers(window);

            glfwPollEvents();
        }
    }

    private static void draw(){

        int vertices = 4;
        int colorSize = 3;
        int vertexSize = 3;

        FloatBuffer cBuffer = BufferUtils.createFloatBuffer(vertices * colorSize);
        cBuffer.put(0).put(0).put(0);
        cBuffer.put(0).put(0).put(0);
        cBuffer.put(0).put(0).put(0);
        cBuffer.put(0).put(0).put(0);
        cBuffer.flip();

        FloatBuffer vBuffer = BufferUtils.createFloatBuffer(vertices * vertexSize);
        vBuffer.put(0.4056f).put(0.5792f).put(0.0f);
        vBuffer.put(-0.5792f).put(0.4056f).put(0.0f);
        vBuffer.put(-0.4056f).put(-0.5792f).put(0.0f);
        vBuffer.put(0.5792f).put(-0.4056f).put(0.0f);
        vBuffer.flip();



        IntBuffer ib = BufferUtils.createIntBuffer(2);

        glGenBuffers(ib);

        int vHandle = ib.get(0);
        int cHandle = ib.get(1);

        glEnableClientState(GL_VERTEX_ARRAY);
        glEnableClientState(GL_COLOR_ARRAY);

        glBindBuffer(GL_ARRAY_BUFFER, vHandle);
        glBufferData(GL_ARRAY_BUFFER, vBuffer, GL_STATIC_DRAW);
        glVertexPointer(vertexSize, GL_FLOAT, vertexSize*4, 0);

        glBindBuffer(GL_ARRAY_BUFFER, cHandle);
        glBufferData(GL_ARRAY_BUFFER, cBuffer, GL_STATIC_DRAW);
        glColorPointer(colorSize, GL_FLOAT, colorSize*4, 0);

        glDrawArrays(GL_POLYGON, 0, vertices);

        glBindBuffer(GL_ARRAY_BUFFER, 0);

        glDisableClientState(GL_COLOR_ARRAY);
        glDisableClientState(GL_VERTEX_ARRAY);

        ib.put(0, vHandle);
        ib.put(1, cHandle);
        glDeleteBuffers(ib);

    }

    public static void main(String[] args){

        new LWJGLTest().run();

    }

}

您可以在 GLFW 中启用 多重采样 (MSAA),这应该会给您带来您想要的效果。在上面使用GL_SAMPLES查找。

例如

glfwWindowHint(GLFW_STENCIL_BITS, 4);
glfwWindowHint(GLFW_SAMPLES, 4);

在创建 window 之前。