评论
抗锯齿可以通过在帧缓冲区对象中创建多重采样帧缓冲区来实现,或者在第一次创建 LWJGL 窗口时通过默认帧缓冲区来实现。
如果您正在学习LWJGL 和OpenGL,那么请学习如何使用VBOs,因为glBegin、glVertex 等已从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。然后你会做一些实例化以在多个位置多次渲染它,等等。
更新
一个 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!
当我运行以下代码时,这是我想要的结果。
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);
}
}