使用lwjgl启用消除锯齿功能

时间:2013-09-09 16:09:12

标签: java lwjgl antialiasing

我正在运行这个lwjgl应用程序:

Display.setDisplayMode(new DisplayMode(500, 500));
Display.create();

glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(-5, 5, -5, 5, -10, 5);
glMatrixMode(GL_MODELVIEW);

float x = 0;
while (!Display.isCloseRequested()) {
    Display.update();

    glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
    glEnable(GL_DEPTH_TEST);
    glColor3f(1, 0, 0);
    x += 0.01f;
    glRotatef(x, x, 3 * x, 0.5f * x);
    glBegin(GL_QUADS);
    drawCube();
    glEnd();
    glLoadIdentity();
}
Display.destroy();

其中基本上在窗口中绘制1x1x1立方体。方法drawCube()就是这样:

public void drawCube() {
    glColor3f(0.0f, 1.0f, 0.0f);          // Set The Color To Green
    glVertex3f(1.0f, 1.0f, 0f);           // Top Right Of The Quad (Top)
    glVertex3f(0f, 1.0f, 0f);             // Top Left Of The Quad (Top)
    glVertex3f(0f, 1.0f, 1.0f);           // Bottom Left Of The Quad (Top)
    glVertex3f(1.0f, 1.0f, 1.0f);         // Bottom Right Of The Quad (Top)

    glColor3f(1.0f, 0.5f, 0.0f);          // Set The Color To Orange
    glVertex3f(1.0f, 0f, 1.0f);           // Top Right Of The Quad (Bottom)
    glVertex3f(0f, 0f, 1.0f);             // Top Left Of The Quad (Bottom)
    glVertex3f(0f, 0f, 0f);               // Bottom Left Of The Quad (Bottom)
    glVertex3f(1.0f, 0f, 0f);             // Bottom Right Of The Quad (Bottom)

    glColor3f(1.0f, 0.0f, 0.0f);          // Set The Color To Red
    glVertex3f(1.0f, 1.0f, 1.0f);         // Top Right Of The Quad (Front)
    glVertex3f(0f, 1.0f, 1.0f);           // Top Left Of The Quad (Front)
    glVertex3f(0f, 0f, 1.0f);             // Bottom Left Of The Quad (Front)
    glVertex3f(1.0f, 0f, 1.0f);           // Bottom Right Of The Quad (Front)

    glColor3f(1.0f, 1.0f, 0.0f);          // Set The Color To Yellow
    glVertex3f(1.0f, 0f, 0f);             // Bottom Left Of The Quad (Back)
    glVertex3f(0f, 0f, 0f);               // Bottom Right Of The Quad (Back)
    glVertex3f(0f, 1.0f, 0f);             // Top Right Of The Quad (Back)
    glVertex3f(1.0f, 1.0f, 0f);           // Top Left Of The Quad (Back)

    glColor3f(0.0f, 0.0f, 1.0f);          // Set The Color To Blue
    glVertex3f(0f, 1.0f, 1.0f);           // Top Right Of The Quad (Left)
    glVertex3f(0f, 1.0f, 0f);             // Top Left Of The Quad (Left)
    glVertex3f(0f, 0f, 0f);               // Bottom Left Of The Quad (Left)
    glVertex3f(0f, 0f, 1.0f);             // Bottom Right Of The Quad (Left)

    glColor3f(1.0f, 0.0f, 1.0f);          // Set The Color To Violet
    glVertex3f(1.0f, 1.0f, 0f);           // Top Right Of The Quad (Right)
    glVertex3f(1.0f, 1.0f, 1.0f);         // Top Left Of The Quad (Right)
    glVertex3f(1.0f, 0f, 1.0f);           // Bottom Left Of The Quad (Right)
    glVertex3f(1.0f, 0f, 0f);             // Bottom Right Of The Quad (Right)
}

输出:

Horrible picture

对我来说线条非常可怕,lwjgl有抗锯齿吗?如果是,我该如何启用它?

2 个答案:

答案 0 :(得分:16)

对于抗锯齿,您可以使用多重采样。要启用它,请向Display.create();添加PixelFormat参数。这是一个例子:

Display.create(new PixelFormat(/*Alpha Bits*/8, /*Depth bits*/ 8, /*Stencil bits*/ 0, /*samples*/8));我不确定前3个参数是做什么的 - 这些是我找到的值here。我也看到人们使用Display.create(新的PixelFormat(8,0,0,8))。

注意:如果你将AA设置得太高(或其他值不正确的值),它将抛出一个LWJGLException。

希望这有帮助。

PS为迟到的答案道歉。

答案 1 :(得分:4)

评论

可以通过在第一次创建LWJGL窗口时在帧缓冲对象中或通过默认帧缓冲区创建多重采样帧缓冲来实现抗锯齿。

如果您正在学习LWJGLOpenGL,请了解如何使用VBOs,因为glBeginglVertex等已从核心配置文件中删除OpenGL。

VBO示例

这是VBO存储两个三角形的顶点和纹理坐标并渲染它的一个小例子!

我认为你知道如何加载和绑定纹理。

创建VBO

这是您创建实际的顶点和纹理坐标缓冲区并将它们存储到GPU上的代码。

int vertices = 6;

int vertex_size = 3; // X, Y, Z,
int texture_size = 2; // U, V,

FloatBuffer vertex_data = BufferUtils.createFloatBuffer(vertices * vertex_size);
vertex_data.put(new float[] { -1f, 1f, 0f, }); // Vertex
vertex_data.put(new float[] { 1f, 1f, 0f, }); // Vertex
vertex_data.put(new float[] { -1f, -1f, 0f, }); // Vertex

vertex_data.put(new float[] { 1f, -1f, 0f, }); // Vertex
vertex_data.put(new float[] { -1f, -1f, 0f, }); // Vertex
vertex_data.put(new float[] { 1f, 1f, 0f, }); // Vertex

FloatBuffer texture_data = BufferUtils.createFloatBuffer(vertices * texture_size);
texture_data.put(new float[] { 0f, 1f, }); // Texture Coordinate
texture_data.put(new float[] { 1f, 1f, }); // Texture Coordinate
texture_data.put(new float[] { 0f, 0f, }); // Texture Coordinate

texture_data.put(new float[] { 1f, 0f, }); // Texture Coordinate
texture_data.put(new float[] { 0f, 0f, }); // Texture Coordinate
texture_data.put(new float[] { 1f, 1f, }); // Texture Coordinate

vertex_data.flip();
texture_data.flip();

int vbo_vertex_handle = glGenBuffers();
glBindBuffer(GL_ARRAY_BUFFER, vbo_vertex_handle);
glBufferData(GL_ARRAY_BUFFER, vertex_data, GL_STATIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, 0);

int vbo_texture_handle = glGenBuffers();
glBindBuffer(GL_ARRAY_BUFFER, vbo_texture_handle);
glBufferData(GL_ARRAY_BUFFER, texture_data, GL_STATIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, 0);

渲染VBO

然后,当您想要渲染VBO时,您需要执行以下操作。

texture.bind();

glBindBuffer(GL_ARRAY_BUFFER, vbo_vertex_handle);
glVertexPointer(vertex_size, GL_FLOAT, 0, 0l);

glBindBuffer(GL_ARRAY_BUFFER, vbo_texture_handle);
glTexCoordPointer(texture_size, GL_FLOAT, 0, 0l);

glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);

glDrawArrays(GL_TRIANGLES, 0, vertices); // The vertices is of course the max vertices count, in this case 6

glDisableClientState(GL_TEXTURE_COORD_ARRAY);
glDisableClientState(GL_VERTEX_ARRAY);

glBindBuffer(GL_ARRAY_BUFFER, 0);

texture.unbind();

删除VBO

然后,当您完成VBO并且不再需要它时,您可以通过执行以下操作将其删除。

glDeleteBuffers(vbo_vertex_handle);
glDeleteBuffers(vbo_texture_handle);

LWJGL / OpenGL - 静态导入

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

信息

你只需要创建一次VBO(为每个帧创建一个非常糟糕),所以如果你使用VBO来存储你的地形。然后,如果发生了一些变化,那么只有在那一点你想要更新VBO,否则就保持原样。如果你将VBO用于地形并且地形非常大,那么用它自己的VBO将地形分成不同的地形块。

附加

如果您有Wavefront OBJ模型,并且想要多次渲染它,那么最好的方法是将整个模型加载到一个VBO。然后你会做一些Instancing来在多个位置多次渲染它等等。

更新

VBO的一个小例子,用于存储三角形的顶点和颜色并进行渲染!

创建VBO。

这是您创建实际的顶点和颜色缓冲区并将它们绑定到VBO的代码。

int vertices = 3;

int vertex_size = 3; // X, Y, Z,
int color_size = 3; // R, G, B,

FloatBuffer vertex_data = BufferUtils.createFloatBuffer(vertices * vertex_size);
vertex_data.put(new float[] { -1f, -1f, 0f, });
vertex_data.put(new float[] { 1f, -1f, 0f, });
vertex_data.put(new float[] { 1f, 1f, 0f, });
vertex_data.flip();

FloatBuffer color_data = BufferUtils.createFloatBuffer(vertices * color_size);
color_data.put(new float[] { 1f, 0f, 0f, });
color_data.put(new float[] { 0f, 1f, 0f, });
color_data.put(new float[] { 0f, 0f, 1f, });
color_data.flip();

int vbo_vertex_handle = glGenBuffers();
glBindBuffer(GL_ARRAY_BUFFER, vbo_vertex_handle);
glBufferData(GL_ARRAY_BUFFER, vertex_data, GL_STATIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, 0);

int vbo_color_handle = glGenBuffers();
glBindBuffer(GL_ARRAY_BUFFER, vbo_color_handle);
glBufferData(GL_ARRAY_BUFFER, color_data, GL_STATIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, 0);

渲染VBO。

这是您需要调用的代码,用于渲染VBO。

glBindBuffer(GL_ARRAY_BUFFER, vbo_vertex_handle);
glVertexPointer(vertex_size, GL_FLOAT, 0, 0l);

glBindBuffer(GL_ARRAY_BUFFER, vbo_color_handle);
glColorPointer(color_size, GL_FLOAT, 0, 0l);

glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_COLOR_ARRAY);

glDrawArrays(GL_TRIANGLES, 0, vertices);

glDisableClientState(GL_COLOR_ARRAY);
glDisableClientState(GL_VERTEX_ARRAY);

导入和删除缓冲区的代码与前面的示例相同!

更新2 - 完成示例

好的,这是一个包含顶点和颜色的VBO的完整示例。该示例仅为100%LWJGL

当我运行以下代码时,这是我得到的理想结果。

Test Image

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

import java.nio.FloatBuffer;

import org.lwjgl.BufferUtils;
import org.lwjgl.input.Keyboard;
import org.lwjgl.opengl.Display;
import org.lwjgl.opengl.DisplayMode;

public class VBOTest
{
    public final static void main(String[] args)
    {
        int width = 1280;
        int height = 720;

        try
        {
            Display.setTitle("VBO Test");
            Display.setDisplayMode(new DisplayMode(width, height));

            Display.create();
        }
        catch (Exception ex)
        {
            ex.printStackTrace();

            System.exit(0);
        }

        /*
         * Initialize OpenGL States
         */

        glMatrixMode(GL_PROJECTION);
        glLoadIdentity();

        glOrtho(0f, width, height, 0f, -1f, 1f);

        glMatrixMode(GL_MODELVIEW);
        glLoadIdentity();

        glEnable(GL_DEPTH_TEST);
        glDepthFunc(GL_LEQUAL);

        glEnable(GL_BLEND);
        glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

        glEnable(GL_CULL_FACE);
        glCullFace(GL_BACK);

        glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);

        /*
         * Creating the Vertex & Color VBO
         */

        final int VERTEX_SIZE = 3; // X, Y, Z,
        final int COLOR_SIZE = 4; // R, G, B, A,

        int vertices = 6;

        int vbo_vertex_handle;
        int vbo_color_handle;

        FloatBuffer vertex_data = BufferUtils.createFloatBuffer(vertices * VERTEX_SIZE);

        float half_width = 200f;
        float half_height = 200f;

        vertex_data.put(new float[] { -half_width, -half_height, 0f, });
        vertex_data.put(new float[] { -half_width, half_height, 0f, });
        vertex_data.put(new float[] { half_width, -half_height, 0f, });

        vertex_data.put(new float[] { half_width, half_height, 0f, });
        vertex_data.put(new float[] { half_width, -half_height, 0f, });
        vertex_data.put(new float[] { -half_width, half_height, 0f, });

        vertex_data.flip();

        FloatBuffer color_data = BufferUtils.createFloatBuffer(vertices * COLOR_SIZE);

        color_data.put(new float[] { 1f, 0f, 0f, 1f, });
        color_data.put(new float[] { 1f, 0f, 1f, 1f, });
        color_data.put(new float[] { 1f, 1f, 0f, 1f, });

        color_data.put(new float[] { 0f, 1f, 0f, 1f, });
        color_data.put(new float[] { 1f, 1f, 0f, 1f, });
        color_data.put(new float[] { 1f, 0f, 1f, 1f, });

        color_data.flip();

        vbo_vertex_handle = glGenBuffers();
        glBindBuffer(GL_ARRAY_BUFFER, vbo_vertex_handle);
        glBufferData(GL_ARRAY_BUFFER, vertex_data, GL_STATIC_DRAW);
        glBindBuffer(GL_ARRAY_BUFFER, 0);

        vbo_color_handle = glGenBuffers();
        glBindBuffer(GL_ARRAY_BUFFER, vbo_color_handle);
        glBufferData(GL_ARRAY_BUFFER, color_data, GL_STATIC_DRAW);
        glBindBuffer(GL_ARRAY_BUFFER, 0);

        /*
         * Main Rendering Loop
         */

        boolean running = true;

        while (running)
        {
            running = (!Display.isCloseRequested() && !Keyboard.isKeyDown(Keyboard.KEY_ESCAPE));

            glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
            glLoadIdentity();

            glPushMatrix();
            {
                glTranslatef(width / 2f, height / 2f, 0f);

                glBindBuffer(GL_ARRAY_BUFFER, vbo_vertex_handle);
                glVertexPointer(VERTEX_SIZE, GL_FLOAT, 0, 0l);
                glBindBuffer(GL_ARRAY_BUFFER, 0);

                glBindBuffer(GL_ARRAY_BUFFER, vbo_color_handle);
                glColorPointer(COLOR_SIZE, GL_FLOAT, 0, 0l);
                glBindBuffer(GL_ARRAY_BUFFER, 0);

                glEnableClientState(GL_VERTEX_ARRAY);
                glEnableClientState(GL_COLOR_ARRAY);

                glDrawArrays(GL_TRIANGLES, 0, vertices);

                glDisableClientState(GL_COLOR_ARRAY);
                glDisableClientState(GL_VERTEX_ARRAY);
            }
            glPopMatrix();

            glFlush();

            Display.sync(60);
            Display.update();
        }

        /*
         * Dispose Elements
         */

        glDeleteBuffers(vbo_vertex_handle);
        glDeleteBuffers(vbo_color_handle);

        Display.destroy();

        System.exit(0);
    }
}