• 类球多面体生成——经纬划分法


    规则多面体生成算法,算法本身并不复杂。开始想百度一份的,结果没百度到。贴出来,希望以后有用得到的同学可在直接拿去用。

    算法过程

    1. 根据经纬线数目求出多面体表面所有点的坐标;
    2. 连接南北极附近的三角形面;
    3. 连接中间的四边形(或两个三角形);

    算法实现

    下面是该算法的C++实现.

    Convex* SphereGenerator::generate(int longitudes, int latitudes, Float radius)
    {
    	m_radius = radius;
    	m_longitudes = longitudes;
    	m_latitudes = latitudes;
    
    	return generate();
    }
    
    Convex* SphereGenerator::generate()
    {
    	Convex* pConvex = new Convex();
    
    	assert(m_latitudes >= 1);
    	assert(m_longitudes >= 3);
    
    	Point northPole(0, m_radius, 0);
    	Point southPole(0, -m_radius, 0);
    
    	int iNorth = pConvex->addVertex(northPole);
    	int iSouth = pConvex->addVertex(southPole);
    
    	double lonDelta = 2*M_PI / m_longitudes;
    	double latDelta = M_PI / (m_latitudes+1);
    
    	std::vector< std::vector<int> > vertIndices;
    	vertIndices.resize(m_latitudes);
    
    	// 计算所有顶点
    	for (int lat=0; lat<m_latitudes; ++lat)
    	{
    		vertIndices[lat] = std::vector<int>(size_t(m_longitudes));
    		Float y = m_radius * glm::sin(M_PI/2 - (lat+1)*latDelta);
    		Float r = m_radius * glm::cos(M_PI/2 - (lat+1)*latDelta); // important!!
    		for (int i=0; i<m_longitudes; ++i)
    		{
    			Point pt(
    				r * glm::cos(i * lonDelta),
    				y,
    				-r * glm::sin(i * lonDelta)
    				);
    			vertIndices[lat][i] = pConvex->addVertex(pt);
    		}
    	}
    
    	// 连接南北两极附近三角形面
    	for (int i=0; i<m_longitudes; ++i)
    	{
    		int next = i+1 < m_longitudes ? i+1 : 0;
    		Triangle triN(vertIndices[0][i], vertIndices[0][next], iNorth);
    		pConvex->addTriangle(triN);
    
    		Triangle triS(vertIndices[m_latitudes-1][next], vertIndices[m_latitudes-1][i], iSouth);
    		pConvex->addTriangle(triS);
    	}
    
    	// 连接中间的三角形面
    	if (m_latitudes >= 2)
    	{
    		for (int lat=0; lat<m_latitudes-1; ++lat)
    		{
    			int nextLat = lat+1;
    			for (int i=0; i<m_longitudes; ++i)
    			{
    				int nextI = i+1 < m_longitudes ? i+1 : 0;
    				int A = vertIndices[lat][i];
    				int B = vertIndices[nextLat][i];
    				int C = vertIndices[nextLat][nextI];
    				int D = vertIndices[lat][nextI];
    				pConvex->addTriangle(Triangle(A, B, D));
    				pConvex->addTriangle(Triangle(B, C, D));
    			}
    		}
    	}
    
    	return pConvex;
    }
    

    演示程序

    使用GLUT写的一个演示程序:

    上键——增加纬线,

    下键——减少纬线,

    左键——减少经线,

    右键——增加纬线。

    #include <windows.h> // windows API 实现的OpenGL
    #include <gl/gl.h>
    #include <gl/glut.h>
    #include <stdio.h>
    
    #include "GlutApp.h"
    #include "SphereGenerator.h"
    
    class DemoSphereGen : public GlutApp
    {
    	Convex* pConvex;
    
    	SphereGenerator* generator;
    
    	float angle;
    
    	int depth;
    
    	void onKey(unsigned char key, int x, int y)
    	{
    		switch(key)
    		{
    		case ' ':
    			int lon = generator->getLongitude();
    			int lat = generator->getLatitude();
    			static char buf[128];
    			sprintf(buf, "sphere%d-%d.obj", lon, lat);
    			printf("serialized to %s!
    ", buf);
    			pConvex->serialize(buf);
    			break;
    		}
    	}
    
    	virtual void onSpecialKey(int key, int x, int y)
    	{
    		int lon = generator->getLongitude();
    		int lat = generator->getLatitude();
    		bool flag=false;
    		switch(key)
    		{
    		case GLUT_KEY_UP:
    			lat++;
    			flag = true;
    			break;
    		case GLUT_KEY_DOWN:
    			lat--;
    			if (lat < 1)
    			{
    				lat = 1;
    			}
    			flag = true;
    			break;
    		case GLUT_KEY_LEFT:
    			lon--;
    			if (lon < 3)
    			{
    				lon = 3;
    			}
    			flag = true;
    			break;
    		case GLUT_KEY_RIGHT:
    			lon++;
    			flag = true;
    			break;
    		default:
    			break;
    		}
    
    		if (flag)
    		{
    			Convex* pOld = pConvex;
    			pConvex = generator->generate(lon, lat);
    			printf("longitudes: %d, latitudes:%d
    ", lon, lat);
    			printf("vertices: %d, triangles: %d
    ", pConvex->getNumVertices(), pConvex->getNumTriangles());
    			delete pOld;
    		}
    	}
    
    	virtual void onTimer()
    	{
    		//static int count = 0;
    		//printf("Alarm %d!
    ", count++);
    		angle += 1.0;
    		glutPostRedisplay();
    	}
    
    	virtual void onInit()
    	{
    		angle = 0;
    		depth = 1;
    		printf("OnInit
    ");
    
    		generator = new SphereGenerator(3, 1);
    		pConvex = generator->generate();
    
    		printf("vertices: %d, triangles: %d
    ", pConvex->getNumVertices(), pConvex->getNumTriangles());
    
    		//pConvex->serialize("convex1.obj");
    
    		glClearColor(0.0, 0.0, 0.0, 0.0);
    		//glShadeModel(GL_SMOOTH);
    
    		glEnable(GL_DEPTH_TEST);
    
    		glPolygonMode(GL_FRONT, GL_LINE);
    		// glPolygonMode(GL_FRONT, GL_FILL);
    		//glPolygonMode(GL_BACK, GL_LINE); // 背面显示线条
    		glCullFace(GL_BACK); // 剔除背面
    	}
    
    	void onResize(int w, int h)
    	{
    		glViewport(0, 0, w, h);
    
    		glMatrixMode(GL_PROJECTION);
    		glLoadIdentity();
    		gluOrtho2D(-2.0 * w / h, 2.0 * w / h, -2.0, 2.0);
    
    		glMatrixMode(GL_MODELVIEW);
    		glLoadIdentity(); // 不能少
    	}
    
    	virtual void onDisplay()
    	{
    		glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    		glMatrixMode(GL_MODELVIEW);
    		glLoadIdentity();
    		glTranslatef(0, -0.5, 0);
    		glRotated(angle, 0, 1, 0); // 旋转
    		//glRotated(angle, 1, 1, 1);
    
    		pConvex->render();
    
    		//glutPostRedisplay();
    	}
    };
    
    int main(int argc, char **argv)
    {
    	GlutApp* app = new DemoSphereGen();
    
    	app->initGlut(argc, argv);
    	app->setTitle("test Regular convex generator
    ");
    	app->setWindowsSize(600, 600);
    
    	app->setTimer(1000, 100);
    
    	app->run();
    
    	return 0;
    }
    
    

    上图:


    5经线3纬线



    9经线5纬线



    15经线9纬线


    其余源码

    GlutApp.h
    #ifndef GLUT_APP_H
    #define GLUT_APP_H
    
    class GlutApp 
    {
    public:
    	typedef void (*MenuFuncPtr)(void);
    
    	struct MenuEntry 
    	{
    		int id;
    		const char* str;
    		MenuFuncPtr fun;
    	};
    
    	// 当前 App 实例指针,指向子类实例
    	static GlutApp* s_pCurrentApp;
    
    	// 右键菜单 项数最大值
    	static const int MAX_MENU = 32;
    
    	// ctor
    	GlutApp();
    
    	// getter and setters:
    	static void initGlut(int argc, char** argv) { s_argc = argc; s_argv = argv; }
    
    	void setDisplayMode(unsigned int mode) { m_displayMode = mode; }
    
    	void setWindowsSize(int w, int h) { m_winWidth = w; m_winHeight = h; }
    
    	int getWindowWidth() { return m_winWidth; }
    
    	int getWindowHeight() { return m_winHeight; }
    
    	void setWindowsPos(int x, int y) { m_winPosX = x; m_winPosY = y; }
    
    	void setTitle(char *title) { m_title = title; }
    
    	void run();
    
    	void addRightMenu(const char *str, MenuFuncPtr fun);
    
    	// 初始化
    	virtual void onInit(){}
    
    	//////////////////////////////////////////////////////////////////////////
    	// GLUT delegate callbacks:
    
    	// 空闲函数
    	virtual void onIdle(){}
    
    	// 图形显示(OpenGL绘图指令)
    	virtual void onDisplay() = 0; // 子类必须重写;不能实例化该类
    
    	// 窗口大小改变
    	virtual void onResize(int w, int h){}
    
    	//////////////////////////////////////////////////////////////////////////
    	// 键盘事件响应 方法:
    
    	// 一般按键(可打印字符,ESC)
    	virtual void onKey(unsigned char key, int x, int y){}
    
    	// 一般按键 按下
    	virtual void onKeyDown(unsigned char key, int x, int y) {}
    
    	// 特殊按键(除一般按键外按键)
    	virtual void onSpecialKey(int key, int x, int y){}
    
    	// 特殊按键按下
    	virtual void onSpecialKeyDown(int key, int x, int y){}
    
    	//////////////////////////////////////////////////////////////////////////
    	// 鼠标事件响应 方法:
    
    	// 鼠标按键
    	//! @param button: The button parameter is one of GLUT LEFT BUTTON, GLUT MIDDLE BUTTON, or GLUT RIGHT BUTTON.
    	//! @param state: The state parameter is either GLUT UP or GLUT DOWN indicating 
    	//                 whether the callback was due to a release or press respectively.
    	virtual void onMousePress(int button, int state, int x, int y){}
    
    	// 鼠标移动
    	virtual void onMouseMove(int x, int y){}
    
    	// 鼠标拖动
    	virtual void onMousePressMove(int x,int y){}
    
    	//////////////////////////////////////////////////////////////////////////
    	// 定时器相关 方法:
    	virtual void onTimer() {}
    
    	void setTimer(int delay, int period = 0);
    
    protected:
    	void registerMenus();
    
    	// actual GLUT callback functions:
    	static void KeyboardCallback(unsigned char key, int x, int y);
    
    	static void KeyboardUpCallback(unsigned char key, int x, int y);
    
    	static void SpecialKeyboardCallback(int key, int x, int y);
    
    	static void SpecialKeyboardUpCallback(int key, int x, int y);
    
    	static void ReshapeCallback(int w, int h);
    
    	static void IdleCallback();
    
    	static void MouseFuncCallback(int button, int state, int x, int y);
    
    	static void	MotionFuncCallback(int x,int y);
    
    	static void MousePassiveCallback(int x, int y);
    
    	static void DisplayCallback();
    
    	static void MenuCallback(int menuId);
    	
    	static void TimerCallback(int period);
    private:
    	unsigned int m_displayMode;
    
    	// for glutInit
    	static int s_argc;
    	static char** s_argv;
    
    	char *m_title;
    
    	// for glutSetWindowSize
    	int m_winWidth;
    	int m_winHeight;
    
    	// for windows position
    	int m_winPosX;
    	int m_winPosY;
    
    	// for menus:
    	int       m_menuCount;
    	MenuEntry m_menuEntry[MAX_MENU];
    
    	// for timer:
    	int m_delay;
    	int m_period;
    };
    
    #endif // GLUT_APP_H
    

    GlutApp.cpp
    #include <gl/glut.h>
    #include <assert.h>
    #include <stdio.h>
    
    #include "GlutApp.h"
    
    int GlutApp::s_argc = 0;
    
    char** GlutApp::s_argv = 0;
    
    GlutApp* GlutApp::s_pCurrentApp = 0;
    
    int g_iLastWindow = 0;
    
    void GlutApp::run()
    {
    	GlutApp* lastApp = GlutApp::s_pCurrentApp;
    	GlutApp::s_pCurrentApp = this;
    
    	GlutApp* app = GlutApp::s_pCurrentApp;
    	assert(app);
    
    	int screenW = glutGet(GLUT_SCREEN_WIDTH);
    	int screenH = glutGet(GLUT_SCREEN_HEIGHT);
    
    	if (!app->m_winWidth)
    	{
    		app->m_winWidth = screenW / 2;
    		app->m_winHeight = screenH / 2;
    	}
    	
    	if (!app->m_winPosX)
    	{
    		app->m_winPosX = (screenW - app->m_winWidth) / 2;
    		app->m_winPosY = (screenH - app->m_winHeight) / 2;
    	}
    
    	if (!lastApp) // first time calling Glut::run().
    	{
    		// glutInit that should only be called exactly once in a GLUT program.
    		glutInit(&this->s_argc, this->s_argv);
    
    		glutInitDisplayMode(this->m_displayMode);
    		glutInitWindowPosition(app->m_winPosX, app->m_winPosY);
    		glutInitWindowSize(app->m_winWidth, app->m_winHeight);
    
    		glutCreateWindow(app->m_title);
    		g_iLastWindow = glutGetWindow();
    		printf("create window: %d
    ", g_iLastWindow); // debug [6/2/2014 xu]
    	}
    	else
    	{
    		glutDestroyWindow(g_iLastWindow);
    
    		glutInitDisplayMode(this->m_displayMode);
    		glutInitWindowPosition(app->m_winPosX, app->m_winPosY);
    		glutInitWindowSize(app->m_winWidth, app->m_winHeight);
    
    		glutCreateWindow(app->m_title);
    		g_iLastWindow = glutGetWindow();
    		printf("create window: %d
    ", g_iLastWindow); // debug [6/2/2014 xu]
    	}
    
    	app->onInit();
    
    	// register keyboard callbacks
    	glutKeyboardFunc(GlutApp::KeyboardCallback);
    	glutKeyboardUpFunc(GlutApp::KeyboardUpCallback);
    	glutSpecialFunc(GlutApp::SpecialKeyboardCallback);
    	glutSpecialUpFunc(GlutApp::SpecialKeyboardUpCallback);
    
    	// register mouse callbacks
    	glutMouseFunc(GlutApp::MouseFuncCallback);
    	glutMotionFunc(GlutApp::MotionFuncCallback);
    	glutPassiveMotionFunc(GlutApp::MousePassiveCallback);
    
    	// register menus:
    	registerMenus();
    
    	// regitser windows resize callback
    	glutReshapeFunc(GlutApp::ReshapeCallback);
    
    	// register render callback
    	glutDisplayFunc(GlutApp::DisplayCallback);
    
    	// register timer callbacks:
    	if (app->m_delay)
    	{
    		glutTimerFunc(app->m_delay, GlutApp::TimerCallback, app->m_period);
    	}
    
    	// register idle callback
    	glutIdleFunc(GlutApp::IdleCallback);
    
    	GlutApp::IdleCallback();
    
    	glutMainLoop();
    }
    
    GlutApp::GlutApp()
    {
    	m_displayMode = GLUT_DOUBLE | GLUT_RGBA | GLUT_DEPTH | GLUT_STENCIL;
    	m_menuCount = 0;
    	m_delay = 0;
    	m_period = 0;
    
    	m_winPosX = 0;
    	m_winPosY = 0;
    	m_winWidth = 0;
    	m_winHeight = 0;
    }
    
    void GlutApp::KeyboardCallback( unsigned char key, int x, int y )
    {
    	GlutApp::s_pCurrentApp->onKey(key,x,y);
    }
    
    void GlutApp::KeyboardUpCallback( unsigned char key, int x, int y )
    {
    	GlutApp::s_pCurrentApp->onKeyDown(key,x,y);
    }
    
    void GlutApp::SpecialKeyboardCallback( int key, int x, int y )
    {
    	GlutApp::s_pCurrentApp->onSpecialKey(key,x,y);
    }
    
    void GlutApp::SpecialKeyboardUpCallback( int key, int x, int y )
    {
    	GlutApp::s_pCurrentApp->onSpecialKeyDown(key,x,y);
    }
    
    void GlutApp::ReshapeCallback( int w, int h )
    {
    	GlutApp::s_pCurrentApp->setWindowsSize(w, h);
    	GlutApp::s_pCurrentApp->onResize(w,h);
    }
    
    void GlutApp::IdleCallback()
    {
    	GlutApp::s_pCurrentApp->onIdle();
    }
    
    void GlutApp::MouseFuncCallback( int button, int state, int x, int y )
    {
    	GlutApp::s_pCurrentApp->onMousePress(button,state,x,y);
    }
    
    void GlutApp::MotionFuncCallback( int x,int y )
    {
    	GlutApp::s_pCurrentApp->onMousePressMove(x,y);
    }
    
    void GlutApp::MousePassiveCallback( int x, int y )
    {
    	GlutApp::s_pCurrentApp->onMouseMove(x, y);
    }
    
    void GlutApp::DisplayCallback( void )
    {
    	GlutApp::s_pCurrentApp->onDisplay();
    }
    
    void GlutApp::addRightMenu( const char *str, MenuFuncPtr fun )
    {
    	m_menuEntry[m_menuCount].id = m_menuCount;
    	m_menuEntry[m_menuCount].str = str;
    	m_menuEntry[m_menuCount].fun = fun;
    	m_menuCount++;
    }
    
    void GlutApp::registerMenus()
    {
    	if (m_menuCount > 0)
    	{
    		glutCreateMenu(GlutApp::MenuCallback);
    		for (int i=0; i<m_menuCount; ++i)
    		{
    			glutAddMenuEntry(m_menuEntry[i].str, m_menuEntry[i].id);
    		}
    		glutAttachMenu(GLUT_RIGHT_BUTTON);
    	}
    }
    
    void GlutApp::MenuCallback( int menuId )
    {
    	for (int i=0; i<GlutApp::s_pCurrentApp->m_menuCount; ++i)
    	{
    		if (menuId == GlutApp::s_pCurrentApp->m_menuEntry[i].id)
    		{
    			GlutApp::s_pCurrentApp->m_menuEntry[i].fun();
    		}
    	}
    }
    
    void GlutApp::setTimer( int delay, int period )
    {
    	this->m_delay = delay;
    	this->m_period = period;
    }
    
    void GlutApp::TimerCallback( int period )
    {
    	// printf("Timer Alarm!
    ");
    	GlutApp::s_pCurrentApp->onTimer();
    	if (period)
    	{
    		glutTimerFunc(period, GlutApp::TimerCallback, period);
    	}
    }
    

    ShpereGennerator.h
    #ifndef SPHERE_GENERATOR_H
    #define SPHERE_GENERATOR_H
    
    #include "Convex.h"
    
    class SphereGenerator
    {
    public:
    	typedef Convex::Float Float;
    	typedef Convex::Point Point;
    	typedef Convex::Triangle Triangle;
    
    	SphereGenerator(void);
    
    	SphereGenerator(int longitudes, int latitudes, Float radius=1.0f);
    
    	Convex* generate(int longitudes, int latitudes, Float radius=1.0f);
    
    	Convex* generate();
    
    	int getLongitude() { return m_longitudes; }
    
    	int getLatitude() { return m_latitudes; }
    private:
    	Float m_radius;
    	int m_longitudes; // 经线数
    	int m_latitudes; // 纬线数
    };
    
    #endif

    SphereGenerator.cpp
    #include "SphereGenerator.h"
    
    #include <vector>
    #include <math.h>
    
    #include <glm/glm.hpp>
    
    #define M_PI       3.14159265358979323846
    
    SphereGenerator::SphereGenerator(void)
    {
    	m_radius = 1.0;
    	m_longitudes = 3;
    	m_latitudes = 1;
    }
    
    SphereGenerator::SphereGenerator(int longitudes, int latitudes, Float radius)
    {
    	m_radius = radius;
    	m_longitudes = longitudes;
    	m_latitudes = latitudes;
    }
    
    Convex* SphereGenerator::generate(int longitudes, int latitudes, Float radius)
    {
    	m_radius = radius;
    	m_longitudes = longitudes;
    	m_latitudes = latitudes;
    
    	return generate();
    }
    
    Convex* SphereGenerator::generate()
    {
    	Convex* pConvex = new Convex();
    
    	assert(m_latitudes >= 1);
    	assert(m_longitudes >= 3);
    
    	Point northPole(0, m_radius, 0);
    	Point southPole(0, -m_radius, 0);
    
    	int iNorth = pConvex->addVertex(northPole);
    	int iSouth = pConvex->addVertex(southPole);
    
    	double lonDelta = 2*M_PI / m_longitudes;
    	double latDelta = M_PI / (m_latitudes+1);
    
    	std::vector< std::vector<int> > vertIndices;
    	vertIndices.resize(m_latitudes);
    
    	// 计算所有顶点
    	for (int lat=0; lat<m_latitudes; ++lat)
    	{
    		vertIndices[lat] = std::vector<int>(size_t(m_longitudes));
    		Float y = m_radius * glm::sin(M_PI/2 - (lat+1)*latDelta);
    		Float r = m_radius * glm::cos(M_PI/2 - (lat+1)*latDelta); // important!!
    		for (int i=0; i<m_longitudes; ++i)
    		{
    			Point pt(
    				r * glm::cos(i * lonDelta),
    				y,
    				-r * glm::sin(i * lonDelta)
    				);
    			vertIndices[lat][i] = pConvex->addVertex(pt);
    		}
    	}
    
    	// 连接南北两极附近三角形面
    	for (int i=0; i<m_longitudes; ++i)
    	{
    		int next = i+1 < m_longitudes ? i+1 : 0;
    		Triangle triN(vertIndices[0][i], vertIndices[0][next], iNorth);
    		pConvex->addTriangle(triN);
    
    		Triangle triS(vertIndices[m_latitudes-1][i], vertIndices[m_latitudes-1][next], iSouth);
    		pConvex->addTriangle(triS);
    	}
    
    	// 连接中间的三角形面
    	if (m_latitudes >= 2)
    	{
    		for (int lat=0; lat<m_latitudes-1; ++lat)
    		{
    			int nextLat = lat+1;
    			for (int i=0; i<m_longitudes; ++i)
    			{
    				int nextI = i+1 < m_longitudes ? i+1 : 0;
    				int A = vertIndices[lat][i];
    				int B = vertIndices[nextLat][i];
    				int C = vertIndices[nextLat][nextI];
    				int D = vertIndices[lat][nextI];
    				pConvex->addTriangle(Triangle(A, B, D));
    				pConvex->addTriangle(Triangle(B, C, D));
    			}
    		}
    	}
    	return pConvex;
    }
    

    Convex.h
    #ifndef CONVEX_H
    #define CONVEX_H
    
    #include <vector>
    
    #include <glm/glm.hpp>
    
    class Convex
    {
    public:
    	typedef float      Float;
    	typedef glm::vec3  Point;
    	typedef glm::uvec3 Triangle;
    
    	// ctor and dtor
    	Convex(void);
    	~Convex(void);
    
    	// 
    	int addVertex(const Point& vert);
    
    	int addTriangle(const Triangle& tria);
    
    	void clear();
    
    	// getters:
    	const Point& getPos() const { return m_position; }
    
    	int getNumVertices() const { return m_numVertices; }
    
    	int getNumTriangles() const { return m_numTriangles; }
    
    	const Triangle& getTriangle(int triIdx) const { return m_triangles[triIdx]; }
    
    	Point getVertex(int vIndex) const { return m_vertices[vIndex]; }
    
    	void setPos(const Point& pos) { m_position = pos; }
    
    	void setVertex(const Point& vert, int vIndex) { m_vertices[vIndex] = vert; }
    
    	// show
    	void render();
    
    	// to obj file
    	void serialize(const char* filename);
    private:
    	int m_numVertices;
    	int m_numTriangles;
    
    	Point m_position;
    
    	std::vector<Point> m_vertices;
    	std::vector<Triangle> m_triangles;
    };
    
    #endif // CONVEX_H

    Convex.cpp
    #include "Convex.h"
    
    #include <windows.h>
    #include <gl/GL.h>
    #include <gl/glut.h>
    
    #include <fstream>
    
    Convex::Convex(void)
    {
    	m_numVertices = 0;
    	m_numTriangles = 0;
    }
    
    Convex::~Convex(void)
    {
    }
    
    int Convex::addVertex( const Point& vert )
    {
    	m_vertices.push_back(vert);
    	return m_numVertices++;
    }
    
    int Convex::addTriangle( const Triangle& tria )
    {
    	m_triangles.push_back(tria);
    	return m_numTriangles++;
    }
    
    void Convex::clear()
    {
    	m_vertices.clear();
    	m_triangles.clear();
    	m_numVertices = 0;
    	m_numTriangles = 0;
    }
    
    void Convex::render()
    {
    	//glMatrixMode(GL_MODELVIEW);
    	//glLoadIdentity();
    
    	glTranslatef(m_position.x, m_position.y, m_position.z);
    
    	// glPolygonMode(GL_FRONT, GL_LINE); // 更改多边形绘制形
    #if 0
    	glBegin(GL_TRIANGLES); // 开始绘图
    	for (int i=0; i<m_numTriangles; ++i)
    	{
    		int idx0 = m_triangles[i][0];
    		int idx1 = m_triangles[i][1];
    		int idx2 = m_triangles[i][2];
    
    		glColor3fv((float*)&m_vertices[idx0]);
    		glVertex3fv((float*)&m_vertices[idx0]);
    
    		glColor3fv((float*)&m_vertices[idx1]);
    		glVertex3fv((float*)&m_vertices[idx1]);
    
    		glColor3fv((float*)&m_vertices[idx2]);
    		glVertex3fv((float*)&m_vertices[idx2]);
    	}
    	glEnd(); // 结束绘图
    #else
    	glEnableClientState(GL_VERTEX_ARRAY);
    	glVertexPointer(3, GL_FLOAT, 0, &m_vertices[0]);
    
    	glEnableClientState(GL_COLOR_ARRAY);
    	glColorPointer(3, GL_FLOAT, 0, &m_vertices[0]);
    	
    #if 1
    	glBegin(GL_TRIANGLES);
    	for (int i=0; i<m_numTriangles; ++i)
    	{
    		glArrayElement(m_triangles[i][0]);
    		glArrayElement(m_triangles[i][1]);
    		glArrayElement(m_triangles[i][2]);
    	}
    	glEnd();
    	// glDrawElements(GL_TRIANGLES, 3, GL_UNSIGNED_INT, &m_triangles[0]);
    #endif
    
    	glDisableClientState(GL_VERTEX_ARRAY);
    	glDisableClientState(GL_COLOR_ARRAY);
    #endif
    	// glPolygonMode(GL_FRONT, GL_FILL);
    
    	glFlush();
    	glutSwapBuffers();
    }
    
    
    void Convex::serialize( const char* filename )
    {
    	int vtNum = this->m_vertices.size();
    	int faceN = this->m_triangles.size();
    
    #if 1
    	FILE* fout = NULL;
    	fout = fopen(filename, "w");
    
    	if(fout == NULL) 
    	{
    		fprintf(stderr, "file %s open failed!
    ", filename);
    		return ;
    	}
    
    	fprintf(fout, 
    		"# serialized Convex data file.
    "
    		"# It is simplest .obj file.
    "
    		);
    	fprintf(fout, "# number of vertices: %d
    ", vtNum);
    	fprintf(fout, "# number of triangles: %d
    
    ", faceN);
    
    	fprintf(fout, "# vertices:
    ");
    	for (int i=0; i<vtNum; ++i)
    	{
    		fprintf(fout, "v %g %g %g
    ", m_vertices[i][0], m_vertices[i][1], m_vertices[i][2]);
    	}
    
    	fprintf(fout, "
    # faces:
    ");
    	for (int i=0; i<faceN; ++i)
    	{
    		fprintf(fout, "f %d %d %d
    ", m_triangles[i][0]+1, m_triangles[i][1]+1, m_triangles[i][2]+1);
    	}
    
    	fclose(fout);
    #endif
    }
    


  • 相关阅读:
    PostMessage
    __stdcall
    C++中L和_T()之区别
    号外:百度开源了它的人工智能技术
    最棒的Unity Github 项目收集(2016)
    OpenGL学习笔记——求值器和NURBS
    unity3d四元数和旋转矩阵
    C# System.Timers.Time
    进程地址空间分布
    子进程与父进程
  • 原文地址:https://www.cnblogs.com/xusw/p/5205855.html
Copyright © 2020-2023  润新知