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.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; //初始化函数 void init(){ 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; } 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
#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(), <span style="white-space:pre"> </span>(double)this->getHeight(), 0.0); //正交的投影矩阵,坐标以左上角为原点 } 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.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.h 功能:实现屏幕上的坐标点 ***********************************************************/ #ifndef _POINT_H #define _POINT_H #include "Object.h" #include "Color.h" #include "OpenGL\glut.h" class Point : protected Object { public: Point() { setPoint(0, 0, Color(0, 0, 0)); this->className = "Point"; } Point(int x, int y) { setPoint(x, y, Color(0, 0, 0)); } Point(int x, int y , Color color) { setPoint(x, y, color); } void setPoint(int x, int y){ setPoint(x, y, Color(0, 0, 0)); } void setPoint(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.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; //窗口的静态线性表 //初始化GLUT static 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; }
今天的代码漏了很多重要的东西,比如窗口背景颜色的设定等,以后随着学习的慢慢深入,会一一添加。