jogl使用VBO

jogl使用VBO,可以把绘图的顶点数据(点坐标、颜色。。。。)传给显卡,避免CPU遍历数据一个一个的传,极大提升性能(在图元极大的时候很明显)

以下例子,利用vbo技术画三角形package test.array;



 
/*******************************************************************************
 * Copyright (c) 2015, 2015  Technologies Corporation.
 ******************************************************************************/
package qqqq;

import java.awt.FlowLayout;
import java.awt.Frame;
import java.nio.FloatBuffer;

import javax.media.opengl.GL;
import javax.media.opengl.GLAutoDrawable;
import javax.media.opengl.GLCanvas;
import javax.media.opengl.GLCapabilities;
import javax.media.opengl.GLEventListener;
import javax.media.opengl.glu.GLU;
import javax.swing.SwingUtilities;

import org.eclipse.swt.SWT;
import org.eclipse.swt.awt.SWT_AWT;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;

import com.sun.opengl.util.BufferUtil;
import com.sun.opengl.util.FPSAnimator;

public class BasicFrame implements GLEventListener {

	static Display display;

	static Shell shell;

	static FPSAnimator animator;

	/**
	 * 数组,包含了meshArray.length/2对二维坐标
	 */
	protected final static float[] meshArray = {

	10, 10,

	25, 20,

	20, 30,

	40, 40,

	50, 50,

	50, 60,

	72, 70,

	80, 80,

	80, 90

	};

	/**
	 * 由数组meshArray转换成的缓存buffer
	 */
	protected static FloatBuffer meshArrayBuffer;

	/**
	 * VBO对象集合
	 */
	private final int[] vbos = new int[1];

	public Frame creatSWT() {
		display = Display.getDefault();
		shell = new Shell();
		shell.setSize(550, 550);
		shell.setText("SWT_OpenGL");
		shell.setLayout(null);
		final Composite compSWT = new Composite(shell, SWT.EMBEDDED);// SWT.EMBEDDED必须
		compSWT.setSize(500, 500);
		compSWT.setLocation(0, 0);
		final java.awt.Frame frame = SWT_AWT.new_Frame(compSWT);
		frame.setLayout(new FlowLayout());
		shell.layout();
		shell.open();
		return frame;
	}

	public static void main(final String[] args) {

		final GLCapabilities capabilities = new GLCapabilities();
		final GLCanvas glcanvas = new GLCanvas(capabilities);// 创建画布
		final BasicFrame basicFrame = new BasicFrame();
		glcanvas.addGLEventListener(basicFrame);// basicFrame重写了GLEventListener的画图的方法
		glcanvas.setSize(500, 500);
		animator = new FPSAnimator(glcanvas, 10, true);

		final Frame frame = basicFrame.creatSWT();
		frame.add(glcanvas);// 把画布放进 窗口内

		SwingUtilities.invokeLater(

		new Runnable() {

			@Override
			public void run() {

				animator.start(); // 开始动画线程

			}

		}

		);

		while (!shell.isDisposed()) {
			if (!display.readAndDispatch()) {
				display.sleep();
			}
		}
		animator.stop();
		display.dispose();
	}

	@Override
	public void init(final GLAutoDrawable drawable) { // 初始函数

		final GL gl = drawable.getGL();
		final GLU glu = new GLU();
		gl.glClearColor(0.0f, 0.0f, 0.0f, 1f); // 设置背景颜色
		gl.glViewport(0, 0, 100, 100); // 视点大小
		gl.glMatrixMode(GL.GL_PROJECTION);
		gl.glLoadIdentity();
		// 裁剪横坐标(left,right)纵坐标(bottom,top)范围内的视图,放进GL可见视图中
		glu.gluOrtho2D(-1.0, 101, -1.0, 101.0); // 使坐标系统出现在GL里,此时屏幕中最左面是坐标0,右面是500,最下0,嘴上500

		final boolean VBOsupported = gl.isFunctionAvailable("glGenBuffersARB") && gl.isFunctionAvailable("glBindBufferARB")
				&& gl.isFunctionAvailable("glBufferDataARB") && gl.isFunctionAvailable("glDeleteBuffersARB");
		System.out.println("Is VBO supported : " + VBOsupported);

		meshArrayBuffer = BufferUtil.newFloatBuffer(meshArray.length);
		for (int i = 0; i < meshArray.length; i++) {
			meshArrayBuffer.put(meshArray[i]);// 把数组的元素按顺序逐个放进buffer中
		}
		meshArrayBuffer.flip();

		gl.glGenBuffersARB(1, vbos, 0);// 开辟一个vbo(既vbo[0])
		gl.glBindBufferARB(GL.GL_ARRAY_BUFFER_ARB, vbos[0]);// 绑定vbos中的vbo[0]对象
		gl.glBufferDataARB(GL.GL_ARRAY_BUFFER_ARB, meshArrayBuffer.capacity() * BufferUtil.SIZEOF_FLOAT, meshArrayBuffer, GL.GL_STATIC_DRAW_ARB);// 把buffer拷贝到vbo(显卡)中
	}

	@Override
	public void display(final GLAutoDrawable drawable) { // 画图函数

		final GL gl = drawable.getGL(); // 从GLAutoDrawable获取GL
		gl.glClear(GL.GL_COLOR_BUFFER_BIT); // 填充背景颜色
		gl.glColor3f(1.0f, 0.0f, 0.0f); // 设置GL的画图颜色,也就是画刷的颜色

		gl.glEnableClientState(GL.GL_VERTEX_ARRAY);
		gl.glBindBufferARB(GL.GL_ARRAY_BUFFER_ARB, vbos[0]);
		gl.glVertexPointer(2, GL.GL_FLOAT, 0, 0);// 以size(2)个数组元素为一个单位放进缓存buffer
		gl.glDrawArrays(GL.GL_TRIANGLES, 0, meshArray.length / 2);// 以mode方式(点、三角形、线)画数组缓存中从第first开始的count个数据元素

		// gl.glPointSize(5);
		// gl.glDrawArrays(GL.GL_POINTS, 0, meshArray.length / 2 + 2);// 此时 ,实际没有meshArray.length / 2 + 2个,系统自动补出一个点(0,0)

		// gl.glDrawArrays(GL.GL_LINES, 0, meshArray.length / 2);// 此时9个点,画了4条曲线,最后一个点没用着
		// gl.glDrawArrays(GL.GL_LINES, 0, meshArray.length / 2 + 1);// 此时9个点,画了5条曲线,最后一个点和自动加的(0,0)连线了

		// gl.glDrawArrays(GL.GL_QUADS, 5, meshArray.length / 2 + 2);

		// *****************************参数说明******Begin**********************************************************************
		// glVertexPointer glDrawArrays
		// 假设buffer中共18个float数,glVertexPointer(2, GL.GL_FLOAT, 0, 0)后buffer中相当于生成了9(18/2)个元素变量(此处是一对坐标)
		// drawArray中,第二个参数是指从刚才生成那9个元素变量中第几个元素变量开始算,第三个参数表示从开始的index算起
		// 取出元素索引为index至index+count-1的元素(count个),以(点线三角形)画出来。
		// 在此特别注意:
		// index和count参数,如果为负数或者out of index 并不报错,如果index后count超出实际buffer中含有元素数,并且
		// 正好buffer中最后一个或几个元素凑不够线或三角形或四边形,buffer末尾会补充一个元素(0,0)
		// *****************************参数说明*******End***********************************************************************

		gl.glDisableClientState(GL.GL_VERTEX_ARRAY);
	}

	@Override
	public void reshape(final GLAutoDrawable drawable, final int x, final int y, final int width, final int height) {
	}

	@Override
	public void displayChanged(final GLAutoDrawable drawable, final boolean modeChanged, final boolean deviceChanged) {
	}
}



结束。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值