使用面向对象方法封装OpenGL函数(一)

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.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;<span style="white-space:pre">//初始化函数<span style="white-space:pre"></span>void init(){<span style="white-space:pre"></span>this->setTitle(string("未命名窗口"));<span style="white-space:pre"></span>int x = 100, y = 100, width = 800, height = 600;<span style="white-space:pre"></span>this->setPostion(x, y);<span style="white-space:pre"></span>this->setWidthAndHeight(width, height);<span style="white-space:pre"></span>this->className = "Window";<span style="white-space:pre"></span>this->isCreated = false;<span style="white-space:pre"></span>}</span>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(){}Window::Window(string t){this->init();this->setTitle(t);}Window::Window(string t , int x, int y, int width, int height){this->init();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() {<span style="white-space:pre"></span>setPoint(0, 0, Color(0, 0, 0));<span style="white-space:pre"></span>this->className = "Point";<span style="white-space:pre"></span>}<span style="white-space:pre"></span>Point(int x, int y) {<span style="white-space:pre"></span>setPoint(x, y, Color(0, 0, 0));<span style="white-space:pre"></span>}<span style="white-space:pre"></span>Point(int x, int y , Color color) {<span style="white-space:pre"></span>setPoint(x, y, color);<span style="white-space:pre"></span>}<span style="white-space:pre"></span>void setPoint(int x, int y){<span style="white-space:pre"></span>setPoint(x, y, Color(0, 0, 0));<span style="white-space:pre"></span>}<span style="white-space:pre"></span>void setPoint(int x, int y,Color color){<span style="white-space:pre"></span>this->X = x;<span style="white-space:pre"></span>this->Y = y;<span style="white-space:pre"></span>this->color = color;<span style="white-space:pre"></span>}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函数(一)

相关文章:

你感兴趣的文章:

标签云: