首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

Eclipse RCP 開發實戰(六):OpenGL 3D 渲染入門

     編輯:Java 相關知識

前言

Eclipse RCP 預設不包含 OpenGL 類別,需額外安裝 org.eclipse.opengl 插件。本文記錄從插件安裝、GLCanvas/GLData 使用、渲染迴圈解決畫面閃爍,到完整繪製旋轉三棱錐矩陣的全過程。

環境準備

  1. 下載 OpenGL 插件(含 GL、GLU 類別與範例),解壓至 eclipse/plugins/ 目錄。
  2. 專案 MANIFEST.MF 加入 org.eclipse.opengl 依賴。

核心概念:GLCanvas 與 Rendering Context

  • GLCanvas:SWT 控制項,內建像素格式選擇、Context 建立、雙緩衝交換。
  • GLData:設定色彩深度、深度緩衝、雙緩衝等像素格式屬性。
  • Rendering Context (RC):OpenGL 命令繪製的邏輯畫布;canvas.setCurrent() 將其設為當前 Context。
  • swapBuffers():將後台緩衝區內容交換到螢幕(雙緩衝防閃爍關鍵)。

關鍵問題:單次渲染畫面被覆蓋

在 createPartControl 中直接呼叫 swapBuffers(),畫面會瞬間顯示又消失,因 SWT 事件迴圈後續繪製(如邊框、背景)會覆蓋 OpenGL 畫面。

解決方案:定時器驅動持續渲染迴圈

class Refresher implements Runnable {
    private static final int DELAY = 100; // 10 FPS
    private final GLCanvas canvas;
    private float rotate = 0f;

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

    public void run() {
        if (canvas == null || canvas.isDisposed()) return;
        if (!canvas.isCurrent()) canvas.setCurrent();

        // 1. 清除緩衝
        GL.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT);
        GL.glLoadIdentity();

        // 2. 視角變換
        GL.glTranslatef(0, 4.5f, -11);
        rotate += 0.5f;
        GL.glRotatef(rotate, 0, 1f, 0);  // 繞 Y 軸旋轉

        // 3. 繪製場景(遞迴三棱錐矩陣)
        drawPyramid(0, 0, 0, 4);

        // 4. 交換緩衝顯示
        canvas.swapBuffers();

        // 5. 排程下一幀
        canvas.getDisplay().timerExec(DELAY, this);
    }

    private void drawPyramid(float x, float y, float z, int n) {
        if (n == 0) return;
        GL.glBegin(GL.GL_TRIANGLES);
        // 後面 - 紅綠藍三頂點
        GL.glColor3f(1,0,0); GL.glVertex3f(x, y, z);
        GL.glColor3f(0,1,0); GL.glVertex3f(x+1, y-1.63f, z-0.57f);
        GL.glColor3f(0,0,1); GL.glVertex3f(x-1, y-1.63f, z-0.57f);
        // 底面、左側、右側...(略,共 12 頂點組成 4 個三角形)
        GL.glEnd();

        // 遞迴繪製三個子三棱錐
        drawPyramid(x, y-1.63f, z+1.15f, n-1);
        drawPyramid(x-1, y-1.63f, z-0.57f, n-1);
        drawPyramid(x+1, y-1.63f, z-0.57f, n-1);
    }
}

視圖類完整實作

public class OpenGLView extends ViewPart {
    private GLCanvas canvas;

    @Override
    public void createPartControl(Composite parent) {
        GLData data = new GLData();
        data.depthSize = 16;       // 16-bit 深度緩衝
        data.doubleBuffer = true;  // 雙緩衝
        canvas = new GLCanvas(parent, SWT.NO_BACKGROUND, data);

        // 視窗大小改變時重設投影矩陣
        canvas.addControlListener(new ControlAdapter() {
            @Override public void controlResized(ControlEvent e) {
                Rectangle r = canvas.getClientArea();
                if (!canvas.isCurrent()) canvas.setCurrent();

                GL.glViewport(0, 0, r.width, r.height);
                GL.glMatrixMode(GL.GL_PROJECTION);
                GL.glLoadIdentity();
                GLU.gluPerspective(45f, (float)r.width/r.height, 0.1f, 100f);
                GL.glMatrixMode(GL.GL_MODELVIEW);
                GL.glLoadIdentity();

                // 通用 OpenGL 狀態初始化
                GL.glClearColor(0,0,0,0);
                GL.glClearDepth(1f);
                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);
            }
        });

        canvas.addDisposeListener(e -> dispose());
        new Refresher(canvas).run();  // 啟動渲染迴圈
    }

    @Override public void setFocus() { canvas.setFocus(); }
}

OpenGL 基礎操作速查

函式用途
glViewport(x,y,w,h)設定視口區域
glMatrixMode(GL_PROJECTION/GL_MODELVIEW)選擇投影/模型觀察矩陣堆疊
glLoadIdentity()重置當前矩陣為單位矩陣
gluPerspective(fovy, aspect, zNear, zFar)建立透視投影矩陣
glTranslatef(x,y,z)平移當前座標系
glRotatef(angle, x, y, z)繞 (x,y,z) 軸旋轉 angle 度
glBegin(GL_TRIANGLES)/glEnd()開始/結束三角形頂點提交
glVertex3f(x,y,z)指定頂點座標
glColor3f(r,g,b)設定當前繪圖顏色 (0~1)

總結

在 SWT 中整合 OpenGL 關鍵在於:使用 GLCanvas 簡化 Context 管理、以 timerExec 驅動持續渲染迴圈、在 ControlListener 中處理視口與投影矩陣重設。掌握此模式,即可將任意 OpenGL 教材範例(C/C++/Python)移植至 Eclipse RCP 專案。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved