FLTK學習-4-使用FLUID編程(2)

11.5.1 CubeView類

      CubeView類是Fl_Gl_Window的子類。該類具有設置縮放,x、y平移【搖動鏡頭??】以及x、y軸旋轉角的方法。

      如果你認識到CubeView只是由FLUID生成的Fl_Gl_Window的一個子類並且會對CubeViewUI的調用產生響應,那麼你可以放心的忽略本節。

CubeView類聲明

下面是在頭文件test/CubeView.h中的CubeView的類聲明。

class CubeView : public Fl_Gl_Window {
public:
CubeView(int x,int y,int w,int h,const char* l=0);
//這個值決定畫立方體的縮放比例
double size;
/*設置垂直軸(y軸)的旋轉。該函數被CubeViewUI的水平滾軸和CubeViewUI的初始化按鈕調用*/
void v_angle(float angle){vAng=angle;};
// 返回垂直軸的旋轉角
float v_angle(){return vAng;};
/*設置水平軸(x軸)的旋轉。該函數被CubeViewUI的垂直滾軸和CubeViewUI的初始化按鈕調用*/
void h_angle(float angle){hAng=angle;};
//返回垂直軸的旋轉角
float h_angle(){return hAng;};
/*設置立方體視角的x偏移,該函數被CubeViewUI的滑動塊和CubeView的初始化按鈕調用*/
void panx(float x){xshift=x;};
/*設置立方體視角的y偏移,該函數被CubeViewUI的滑動塊和CubeView的初始化按鈕調用*/
void pany(float y){yshift=y;};
/*構件基類的draw()函數的重載,draw()函數用另一輪的畫圖初始化GL,然後調用專門的函數畫出立方體視圖中的每個實體【??】*/
void draw();
private:
/*畫立方體的邊界,使用boxv[]頂點和GL_LINE_LOOP畫立方體的面【??】,顏色由CUBECOLOR宏定義指定*/
void drawCube();
float vAng,hAng; float xshift,yshift;
float boxv0[3];float boxv1[3]; float boxv2[3];float boxv3[3];
float boxv4[3];float boxv5[3]; float boxv6[3];float boxv7[3];
};

CubeView類實現

下面是CubeView的實現,與FLTK中的Cube演示例子非常相似。

#include "CubeView.h"
#include <math.h>
CubeView::CubeView(int x,int y,int w,int h,const char *l)
: Fl_Gl_Window(x,y,w,h,l)
{
vAng = 0.0; hAng=0.0; size=10.0;
/*The cube definition. These are the vertices of a unit cube
centered on the origin.*/
boxv0[0] = -0.5; boxv0[1] = -0.5; boxv0[2] = -0.5; boxv1[0] = 0.5;
boxv1[1] = -0.5; boxv1[2] = -0.5; boxv2[0] = 0.5; boxv2[1] = 0.5;
boxv2[2] = -0.5; boxv3[0] = -0.5; boxv3[1] = 0.5; boxv3[2] = -0.5;
boxv4[0] = -0.5; boxv4[1] = -0.5; boxv4[2] = 0.5; boxv5[0] = 0.5;
boxv5[1] = -0.5; boxv5[2] = 0.5; boxv6[0] = 0.5; boxv6[1] = 0.5;
boxv6[2] = 0.5; boxv7[0] = -0.5; boxv7[1] = 0.5; boxv7[2] = 0.5;
};
// The color used for the edges of the bounding cube.
#define CUBECOLOR 255,255,255,255
void CubeView::drawCube() {
/*Draw a colored cube*/
#define ALPHA 0.5
glShadeModel(GL_FLAT);
glBegin(GL_QUADS);
glColor4f(0.0, 0.0, 1.0, ALPHA);
glVertex3fv(boxv0);
glVertex3fv(boxv1);
glVertex3fv(boxv2);
glVertex3fv(boxv3);

glColor4f(1.0, 1.0, 0.0, ALPHA);
glVertex3fv(boxv0);
glVertex3fv(boxv4);
glVertex3fv(boxv5);
glVertex3fv(boxv1);
glColor4f(0.0, 1.0, 1.0, ALPHA);
glVertex3fv(boxv2);
glVertex3fv(boxv6);
glVertex3fv(boxv7);
glVertex3fv(boxv3);
glColor4f(1.0, 0.0, 0.0, ALPHA);
glVertex3fv(boxv4);
glVertex3fv(boxv5);
glVertex3fv(boxv6);
glVertex3fv(boxv7);
glColor4f(1.0, 0.0, 1.0, ALPHA);
glVertex3fv(boxv0);
glVertex3fv(boxv3);
glVertex3fv(boxv7);
glVertex3fv(boxv4);
glColor4f(0.0, 1.0, 0.0, ALPHA);
glVertex3fv(boxv1);
glVertex3fv(boxv5);
glVertex3fv(boxv6);
glVertex3fv(boxv2);
glEnd();
glColor3f(1.0, 1.0, 1.0);
glBegin(GL_LINES);
glVertex3fv(boxv0);
glVertex3fv(boxv1);
glVertex3fv(boxv1);
glVertex3fv(boxv2);
glVertex3fv(boxv2);
glVertex3fv(boxv3);
glVertex3fv(boxv3);
glVertex3fv(boxv0);
glVertex3fv(boxv4);
glVertex3fv(boxv5);
glVertex3fv(boxv5);
glVertex3fv(boxv6);
glVertex3fv(boxv6);
glVertex3fv(boxv7);
glVertex3fv(boxv7);
glVertex3fv(boxv4);
glVertex3fv(boxv0);
glVertex3fv(boxv4);
glVertex3fv(boxv1);
glVertex3fv(boxv5);
glVertex3fv(boxv2);
glVertex3fv(boxv6);
glVertex3fv(boxv3);
glVertex3fv(boxv7);
glEnd();
};//drawCube
void CubeView::draw() {
if (!valid()) {
glLoadIdentity(); glViewport(0,0,w(),h());
glOrtho(-10,10,-10,10,-20000,10000); glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
}
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glPushMatrix(); glTranslatef(xshift, yshift, 0);
glRotatef(hAng,0,1,0); glRotatef(vAng,1,0,0);
glScalef(float(size),float(size),float(size)); drawCube();
glPopMatrix();
};

11.5.2 CubeViewUI類

我們將使用FLUID構造一個完整的窗口來顯示和控制上一節定義的CubeView類。

定義CubeViewUI類

啓動FLUID之後,在FLUID中定義類的第一步是通過菜單New->Code->Class創建一個新的類。將類命名爲CubeViewUI,讓子類空着。我們並不需要這個窗口的任何繼承,你應該可以在FLUID瀏覽窗口中看到新類的聲明。


圖11.3 FLUID定義CubeViewUI

添加類構造函數

在FLUID窗口中點擊CubeViewUI類,通過選擇New->Code->Function/Method添加一個新的方法。函數名也是CubeViewUI,FUILD知道這是類的構造函數,因此將產生相應的代碼。確保你聲明的構造函數爲公共(public)訪問方式。

      然後在CubeViewUI類中加入一個窗口。FLUID瀏覽窗口中在高亮顯示構造函數名,然後點擊New->Group->Window。使用類似的方式在CubeViewUI中加入如下對象。

l      水平滾軸hrot

l      垂直滾軸vrot

l      水平滑動塊xpan

l      垂直滑動塊ypan

l      水平值滑動塊zoom

所有這些加入的對象都不用是公共的,而且他們也不應該是公共的,除非你計劃將它們作爲CubeViewUI的接口的一部分。

      當你完成之後,你應該有這樣一些東西:


圖11.4 包含CubeView演示的FLUID窗口

我們稍後將討論圖中高亮顯示的show()方法.

添加CubeView構件

我們目前所有的已經很好了,但是對於顯示立方體似乎還不夠。我們已經定義了CubeView類,我們要將它顯示在CubeViewUI中。

CubeView類繼承自Fl_Gl_Window類,而Fl_Gl_Window則繼承自Fl_Box。使用New->Other->Box在主窗口中添加一個矩形框。然而這不是一個普通的框。【??】框的屬性窗口將會出現。讓CubeViewUI顯示CubeView的關鍵在於在Class文本輸入框中輸入CubeView。這就告訴FLUID這不是一個Fl_Box而是一個類似的構造函數爲該名字的構件。【??】

      在Extra Code域中輸入:#include “CubeView.h”

這個#include很重要,應爲我們剛剛將CubeView作爲一個成員包含進了CubeViewUI中,所以所有的CubeView的公共方法在CubeViewUI中都是可見的。


圖11.5 CubeView的方法

定義回調函數

      所有的在添加CubeView之前定義的構件都可以擁有調用CubeView方法的回調函數。你可以調用外部函數或者在構件面板的Callback域中放入一小部分代碼。例如:ypan滑動塊的回調如下:

Cube->pany(((Fl_Slider*)o)->value());

Cube->redraw();

當改變值之後我們調用cube->redraw()來更新CubeView窗口。CubeView可以很容易的通過這種方式修改,但是更好的方式是將它暴露出來【意思應該是作爲一個接口函數吧?】,這樣的話你就可以在多個視圖改變時只重繪一次,從而節省大量的時間。【譯註:這句好長,沒大看懂,應該就是這麼個意思】

沒有理由不等待直到你已經加入了CubeView來進入回調【譯註:不會翻譯,原文:There is no reason no wait until after youhave added CubeView to enter these callbacks.】。FLUID假設你足夠聰明,不會使用不存在的成員或者函數。

加入類方法

      你可以在FLUID中加入與GUI無關的類方法。作爲一個例子加入一個顯示函數以便CubeViewUI可以在屏幕上顯示出來。

      確保CubeViewUI的最頂層已經選中,然後選擇:New->Code->Function/Method。就用名字show()。我們這裏不需要返回值而且我們也不會在該方法中加入任何構件,所以FLUID將函數返回值設爲void類型。


圖11.6 CubeViewUI顯示函數

一旦新的方法已經加入,選中它的名字然後選擇New->Code->Code,在代碼窗口中輸入方法的實現代碼。

11.5.3 加入構造函數的初始化代碼

如果你需要加入代碼初始化類,例如:設置CubeView的水平垂直角度初始值。你可以選中構造函數,選擇New->Code->Code。加入需要的代碼。

11.5.4 生成代碼

      現在我們已經完整定義了CubeViewUI,我們需要生成代碼。只需最後一招就可以完成所有工作。從Edit->Preference打開偏好對話框。

      在對話框的底部是關鍵:”IncludeHeader from Code”.選擇該選項,然後設置你想要的文件擴展名和業務【??】。你可以包含CubeViewUI.h(或者任何你想要的擴展名)asyou would any other C++ class.【譯註:不會翻譯,實在看不明白,感覺語法不通??】。



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章