【OpenGL基礎篇】——使用物件導向方法封裝OpenGL函數(一)

來源:互聯網
上載者:User

標籤:opengl   物件導向   應用程式   application   編程   

OpenGL是一個開源的圖形庫,既可開發二維圖形軟體,也可開發三維圖形軟體。許多知名應用就是基於OpenGL開發出來,如著名的Artoolkit和Unity3D。

GLUT是代表OpenGL應用工具包,英文全稱為OpenGL Utility Toolkit,是一個和視窗系統無關的軟體包,它由Mark Kilgard在SGI時寫的。作為AUX庫的功能更強大的替代品,用於隱藏不同視窗系統API的複雜性。(百度百科)

因為OpenGL的API是底層圖形庫API,使用起來還是有些複雜,所以,我打算使用物件導向的方法將OpenGL和GLUT庫的函數封裝成一個圖形類庫,順便學習一下電腦圖形學(這學期的課)的基礎知識以及物件導向的編程方法。懂了這些底層的東西,對理解Unity3D這樣的遊戲引擎也有好處。

使用的是GLUT,所以只實現了一些簡單的功能,以後慢慢擴充,這隻是(一)。

雖然是使用C++來編寫類庫,但還是融入了一點Java的東西,比如,類庫中的所有類都是Object的子類(用於實現多態)。

下面是Object類:

/********************************************************************檔案名稱:Object.h*功能:聲明Object類,此類是GL類庫裡所有類的父類(即Java中的那個Object)********************************************************************/#ifndef _OBJECT_H_#define _OBJECT_H_#include <string>using std::string;#include <iostream>using std::cout;using std::cin;using std::endl;/*類聲明*/class Object{public://預設建構函式Object() {className = "Object";}//返回類名virtual string toString(){return this->className;}//顯示介面virtual void show() {//虛函數,留待繼承,以實現多態}//創造對象virtual void create(){}//刪除對象virtual void destory() {}protected:string className;//類名};#endif


然後是一個Window類,就是視窗(以前學MFC等語言時,最怕的就是API和可選擇解決方案多,所以我在這裡唯寫了少數幾個函數,畢竟只是為了學習)

/***********************************************************檔案名稱:Window.h*功能:封裝了視窗操作的Window類***********************************************************/#ifndef _WINDOW_H_#define _WINDOW_H_#include "Object.h"#include "OpenGL\glut.h"#include <vector>using std::vector;class Window : protected Object {public://預設建構函式Window();//輸入視窗名的建構函式Window(string title);//同時設定視窗名稱、位置和大小的建構函式Window(string title, int x, int y, int width, int height);//顯示介面void show();//建立視窗void create();//添加組件,在視窗顯示時會依次在視窗裡顯示出來void add(Object* object);//刪除對象void destory();private:string title;//視窗標題int xPosition, yPosition;//視窗座標int width, height;//視窗大小vector<Object*> objectVector;public://設定視窗標題void setTitle(string t);//擷取視窗標題string getTitle();int getWidth(){return this->width;}int getHeight() {return this->height;}//設定視窗位置void setPostion(int x, int y);//設定視窗大小void setWidthAndHeight(int width, int height);//判斷視窗是否被建立bool isCreated;//對象名string toString() {return this->className;}private://繪製介面void Paint(void);};#endif
下面是實現的Cpp檔案:

#include "Window.h"Window::Window(){this->setTitle(string("未命名視窗"));int x = 100, y = 100,width = 800 , height = 600;this->setPostion(x, y);this->setWidthAndHeight(width, height);this->className = "Window";this->isCreated = false;}Window::Window(string t){Window();this->setTitle(t);}Window::Window(string t , int x, int y, int width, int height){Window();this->setTitle(t);this->setPostion(x, y);this->setWidthAndHeight(width, height);}void Window::setTitle(string t) {this->title = t;}void Window::setPostion(int x, int y) {this->xPosition = x;this->yPosition = y;}void Window::setWidthAndHeight(int w, int h) {this->width = w;this->height = h;}void Window::create() {glutInitWindowPosition(this->xPosition, this->yPosition);//設定視窗位置glutInitWindowSize(this->width, this->height);//設定視窗大小glutCreateWindow(this->title.c_str());//建立一個名為title的視窗this->isCreated = true;gluOrtho2D(0.0, (double)this->getWidth(),0.0, (double)this->getHeight()); //正交的投影矩陣}void Window::Paint(void){int size = this->objectVector.size();for (int i = 0; i < size; i++){objectVector.at(i)->show();}}void Window::show() {this->Paint();}//添加組件,在視窗顯示時會依次在視窗裡顯示出來void Window::add(Object* object){objectVector.push_back(object);}void Window::destory() {int size = this->objectVector.size();for (int i = 0; i < size; i++){cout << "destory:" + objectVector.at(i)->toString() << endl;delete objectVector.at(i);}cout << "destory:" + this->toString() << endl;}

然後是一個顏色Color類,暫時只支援RGB模式,從現在起,我會盡量把聲明和定義都寫在一個檔案裡,就像Java那樣。

/**************************************************檔案名稱:Color.h功能:顏色類,用於指定顏色***************************************************/#ifndef _COLOR_H_#define _COLOR_H_#include "Object.h"class Color : protected Object {public:Color(){Color(0, 0, 0);this->className = "Color";}Color(int r, int g, int b) {this->R = (double)r / 255;this->G = (double)g / 255;this->B = (double)b / 255;}public:double R, G, B;};#endif

接下來就是繪圖裡面最重要的了——Point,有了點,才能有一切

/**********************************************************檔案名稱:Point.h功能:實現螢幕上的座標點***********************************************************/#ifndef _POINT_H#define _POINT_H#include "Object.h"#include "Color.h"#include "OpenGL\glut.h"class Point : protected Object {public:Point() {Point(0, 0, Color(0, 0, 0));this->className = "Point";}Point(int x, int y) {Point(x, y, Color(0, 0, 0));}Point(int x, int y , Color color) {this->X = x;this->Y = y;this->color = color;}void show() {glColor3d(color.R, color.G, color.B);glBegin(GL_POINTS);glVertex2i(this->X, this->Y);glEnd();}public:int X;int Y;Color color;};#endif

最後就是最重要的應用程式Application類了,這個類用於添加視窗以及映像重繪重新整理

/**********************************************************檔案名稱:Application.h*功能:用於建立應用程式**********************************************************/#ifndef _APPLICATION_H_#define _APPLICATION_H_#include "Object.h"#include "OpenGL\glut.h"#include "Window.h"#include <vector>using std::vector;class Application : protected Object {public:Application(){className = "Application";}~Application(){destory();}static vector<Window> windowVector;//視窗的靜態線性表//初始化GLUTstatic void init(int argc, char *argv[]){glutInit(&argc, argv);//設定顯示模式glutInitDisplayMode(GLUT_RGB | GLUT_SINGLE);}//添加組件static bool add(Window object) {if (object.isCreated) {windowVector.push_back(object);return true;}return false;}void show(){if (windowVector.size() > 0) {glutDisplayFunc(&Paint);//進入顯示迴圈(無此句則程式執行結束)glutMainLoop();}Paint();}void destory() {for (int i = 0; i < windowVector.size(); i++) {windowVector[i].destory();}cout << "destory:" + this->toString()<<endl;}private:static void Paint(){glClear(GL_COLOR_BUFFER_BIT);//清除視窗螢幕for (int i = 0; i < windowVector.size(); i++) {windowVector[i].show();}glFlush();//重新整理繪圖命令}};vector<Window> Application::windowVector;#endif

下面是一個測試檔案,只畫了一條紫色虛線:

#include "Window.h"#include "Color.h"#include "Point.h"#include "Application.h"//隱藏控制台視窗#pragma comment(linker, "/subsystem:\"windows\" /entry:\"mainCRTStartup\"")int main(int argc ,char* argv[]) {int w = 400, h = 300;Window window(string("Hello"), 100, 100, w, h);window.create();Point* p;for (int i = 0; i < 70; i++) {p = new Point(200,10+4*i,Color(255,0,255));window.add((Object*)p);}Application* app = new Application();app->init(argc, argv);app->add(window);app->show();delete app;return 0;}

出來的效果如:



黑色的螢幕中間有一條紫色的虛線。

今天的代碼漏了很多重要的東西,比如視窗背景顏色的設定等,以後隨著學習的慢慢深入,會一一添加。

【OpenGL基礎篇】——使用物件導向方法封裝OpenGL函數(一)

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.