可視化(番外篇)——在Eclipse RCP中玩轉OpenGL


  最近在看有關Eclipse RCP方面的東西,鑒於Gephi是使用opengl作為繪圖引擎,所以,萌生了在Eclipse RCP下添加畫布,使用opengl繪圖的想法,網上有博文詳細介紹這方面的內容,但是沒有強調版本,造成我在搭建環境以及編碼時阻礙重重,本篇的重點主要是針對幾個遇到的問題,強調版本的重要性以及這個問題的主要思路。

  環境介紹

  eclipse:  eclipse-dsl-luna-SR1a-win32(32位)

  jdk:    jdk1.6.0_22(32位)

  opengl:  eclipse-opengl-0.5.0-win32

  一、opengl環境搭建

  1.下載opengl在eclipse下的插件eclipse-opengl-0.5.0-win32

  下載鏈接:http://www.eclipse.org/swt/opengl/

  其文件目錄結構:

  

 

  2.將兩個文件夾org.eclipse.opengl.win32.x86_0.5.0和org.eclipse.opengl_0.5.0分別放入eclipse解壓目錄下的plugins文件夾中

  

  另外還需要將org.eclipse.opengl_0.5.0下的ogl.jar放入上面文件夾中。

 

  3.為了解決錯誤提示類庫沒有加載的問題,將org.eclipse.opengl.win32.x86_0.5.0文件夾下的gl-0500.dll庫文件放入jdk的bin文件夾中。

  注意:之所以如此強調版本,是因為之前在搭好了eclipse以及編寫好代碼后,本以為可以完美的出結果,可是點擊run按鈕,發現報了個錯,說是無法再64位平台加載32位應用,經查找發現是下載的opengl是32位的,之后在鏈接http://www.eclipse.org/swt/opengl/中也沒有找到64位的opengl插件。

  所以就重新換了個思路,將jdk換成了32位的,但是此時又報錯不能再32位平台下加載64位的SWT環境,嘗試過更換eclipse(注意,起初的eclipse是64位的)下的plugin中的swt為32,結果在添加依賴插件時發現無效,仍然加載的是64位,添加依賴opengl插件如下圖所示:

  
  這次,准備來個大換血,將eclipse也換掉,弄成個32位,這下齊活了,都是32位,應該沒有什么問題了,開始編寫代碼。

 

  二、創建Eclipse RCP項目並編寫opengl繪圖程序

  1.新建Plug-in Project

  在Eclipse中打開File->New->other選擇Plug-in Project

  

 

  2.新建完成后,我們得到以下的項目目錄結構

  

  從包com.cntrust.jack中我們可以發現共有5個類

  首先從Application開始,主要通過調用PlatformUI.createAndRunWorkbench(Display, WorkbenchWindowAdvisor)方法啟動Workbench;

  然后跳轉到ApplicationWorkbenchAdvisor類中,該類主要做了兩方面的工作;

  (1)要顯示的初始透視圖(就是com.cntrust.jack包下的Perspective類所要做的工作);

  (2)要使用的WorkbenchWindowAdvisor。

  再者就是ApplicationWorkbenchWindowAdvisor類,它在渲染窗口方面將指導UI;

  最后一個是ApplicationActionBarAdvisor類,其創建了一個窗口所需要的動作,並在窗口中定位它們。

 

  3.添加視圖

  打開plugin.xml文件,切換到Extensions下,點擊Add按鈕,輸入org.eclipse.ui.views,點擊確定,則在上面的窗口會看到org.eclipse.ui.views,鼠標右鍵new->view,在右邊的“Extension Element Details”中填寫相應的信息,如圖所示:

  

  在得到的ContactsView類中,我們先定義一個ID,方便后面透視圖布局時會用到。

 

  4.在ContactsView類中的createPartControl()方法下編寫代碼:

GLCanvas canvas;

	@Override
	public void createPartControl(Composite parent) {

		GLData data = new GLData();
		data.depthSize = 1;
		data.doubleBuffer = true;
		canvas = new GLCanvas(parent, SWT.NO_BACKGROUND, data);
		canvas.addControlListener(new ControlAdapter() {
			public void controlResized(ControlEvent e) {
				Rectangle rect = canvas.getClientArea();
				GL.glViewport(0, 0, rect.width, rect.height);

				// 選擇投影矩陣
				GL.glMatrixMode(GL.GL_PROJECTION);
				// 重置投影矩陣
				GL.glLoadIdentity();
				// 設置窗口比例和透視圖
				GLU.gluPerspective(45.0f, (float) rect.width
						/ (float) rect.height, 0.1f, 100.0f);
				// 選擇模型觀察矩陣
				GL.glMatrixMode(GL.GL_MODELVIEW);
				// 重置模型觀察矩陣
				GL.glLoadIdentity();

				// 黑色背景
				GL.glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
				// 設置深度緩存
				GL.glClearDepth(1.0f);
				// 啟動深度測試
				GL.glEnable(GL.GL_DEPTH_TEST);
				// 選擇深度測試類型
				GL.glDepthFunc(GL.GL_LESS);
				// 啟用陰影平滑
				GL.glShadeModel(GL.GL_SMOOTH);
				// 精細修正透視圖
				GL.glHint(GL.GL_PERSPECTIVE_CORRECTION_HINT, GL.GL_NICEST);
				// 清除屏幕和深度緩存
				GL.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT);
				// 重置當前的模型觀察矩陣
				GL.glLoadIdentity();
			}
		});
		canvas.addDisposeListener(new DisposeListener() {
			public void widgetDisposed(DisposeEvent e) {
				dispose();
			}
		});

		Refresher rf = new Refresher(canvas);
		rf.run();
	}

  同時創建類Refresher:

class Refresher implements Runnable {
	public static final int DELAY = 100;

	private GLCanvas canvas;
	private float rotate = 0.0f;

	public Refresher(GLCanvas canvas) {
		this.canvas = canvas;
	}

	public void run() {
		if (this.canvas != null && !this.canvas.isDisposed()) {
			if (!canvas.isCurrent()) {
				canvas.setCurrent();
			}
			// 這里添加OpenGL繪圖代碼
			GL.glLoadIdentity();
			GL.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT);
			GL.glTranslatef(0, 4.5f, -11);
			// 圍繞y軸轉起來
			rotate += 0.5;
			GL.glRotatef(rotate, 0, 1.0f, 0);
			// 調用遞歸函數,繪制三菱錐矩陣
			drawPyramid(0, 0, 0, 4);
			canvas.swapBuffers();
			this.canvas.getDisplay().timerExec(DELAY, this);
		}
	}

	public void drawPyramid(float x, float y, float z, int n) {
		if (n == 0)
			return;
		// 畫一個三菱錐
		GL.glBegin(GL.GL_TRIANGLES);
		// 畫背面
		GL.glColor3f(1.0f, 0.0f, 0.0f);
		GL.glVertex3f(x, y, z);
		GL.glColor3f(0.0f, 1.0f, 0.0f);
		GL.glVertex3f(x + 1.0f, y - 1.63f, z - 0.57f);
		GL.glColor3f(0.0f, 0.0f, 1.0f);
		GL.glVertex3f(x - 1.0f, y - 1.63f, z - 0.57f);
		// 畫底面
		GL.glColor3f(1.0f, 0.0f, 0.0f);
		GL.glVertex3f(x, y - 1.63f, z + 1.15f);
		GL.glColor3f(0.0f, 1.0f, 0.0f);
		GL.glVertex3f(x - 1.0f, y - 1.63f, z - 0.57f);
		GL.glColor3f(0.0f, 0.0f, 1.0f);
		GL.glVertex3f(x + 1.0f, y - 1.63f, z - 0.57f);
		// 畫左側面
		GL.glColor3f(1.0f, 0.0f, 0.0f);
		GL.glVertex3f(x, y, z);
		GL.glColor3f(0.0f, 1.0f, 0.0f);
		GL.glVertex3f(x - 1.0f, y - 1.63f, z - 0.57f);
		GL.glColor3f(0.0f, 0.0f, 1.0f);
		GL.glVertex3f(x, y - 1.63f, z + 1.15f);
		// 畫右側面
		GL.glColor3f(1.0f, 0.0f, 0.0f);
		GL.glVertex3f(x, y, z);
		GL.glColor3f(0.0f, 1.0f, 0.0f);
		GL.glVertex3f(x, y - 1.63f, z + 1.15f);
		GL.glColor3f(0.0f, 0.0f, 1.0f);
		GL.glVertex3f(x + 1.0f, y - 1.63f, z - 0.57f);
		GL.glEnd();
		// 遞歸調用,畫多個三菱錐
		drawPyramid(x, y - 1.63f, z + 1.15f, n - 1);
		drawPyramid(x - 1.0f, y - 1.63f, z - 0.57f, n - 1);
		drawPyramid(x + 1.0f, y - 1.63f, z - 0.57f, n - 1);
	}
}

  

  5.在項目上右鍵run as->eclipse application,得到結果如下:

 

友情贊助

如果你覺得博主的文章對你那么一點小幫助,恰巧你又有想打賞博主的小沖動,那么事不宜遲,趕緊掃一掃,小額地贊助下,攢個奶粉錢,也是讓博主有動力繼續努力,寫出更好的文章^^。

    1. 支付寶                          2. 微信

                      

  如果對你有用,歡迎點贊哦,也歡迎加入可視化群227963113討論^_^

  本文鏈接《可視化(番外篇)——在Eclipse RCP中玩轉OpenGL

  參考文獻:http://www.thinksaas.cn/group/topic/319162/

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM