精华内容
下载资源
问答
  • 主要为大家详细介绍了基于OpenGL实现多段Bezier曲线拼接,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
  • 基于OpenGL实现的多段Bezier曲线拼接 有代码, 截图
  • 根据网上的代码参考,最终实现了用VBO绘制并且可以着色,下载后把demo中着色器的路径改一下就好了,其他的库都有,x64运行。
  • //只有第一个BezierCell可以编辑bezierCell的起始:(V0,V1) isFirstRender = false; } else if ( cellRenderState() == cellRenderImple::Change) { //if finish the current cell's render ...

    运行程序的交互方式有点类似corelDraw中的自由曲线绘制,或者photoShop中的钢笔自由路径绘制。

    截图:

     

    将BezierCurve封装成了一个类,代码如下:

    #ifndef _BEZIERCURVE_H
    #define _BEZIERCURVE_H
    
    #include "vec3.hpp"
    #include <vector>
    #include <iostream>
    #include <gl/glut.h>
    
    using namespace std;
     3次bezier曲线: 四个控制节点。曲线经过首末两个顶点。
    
    class BezierCurve
    {
    public:
    	//cell一共有四个控制顶点
    	//	-cell经过V0和V3顶点,
    	//	-cell的始端相切于直线:(V0, V1) 和末端相切于(V2,V3)
    	class BezierCell
    	{
    	public:
    		BezierCell(int i0, int i1, int i2, int i3)
    		{
    			setValue(i0, i1, i2, i3);
    		}
    
    		void setValue(int i0, int i1, int i2, int i3)
    		{
    			ctrlVertxIndex[0] = i0;
    			ctrlVertxIndex[1] = i1;
    			ctrlVertxIndex[2] = i2;
    			ctrlVertxIndex[3] = i3;
    		}
    		const int operator[](int index) const
    		{
    			if (index > 3 || index < 0)
    				return -1;
    
    			return ctrlVertxIndex[index];
    		}
    		int ctrlVertxIndex[4];
    	};
    
    	enum eventType
    	{
    		LButtonDown = 0,
    		MouseMove = 1,
    		LButtonUp = 2
    	};
    	
    	enum { Bezier3CtrlPnt = 4 };
    
    	BezierCurve() { clear(); }
    	~BezierCurve(){}
    
    	void begin()
    	{
    		// 开启求值器
    		glEnable(GL_MAP1_VERTEX_3);
    		clear();
    	}
    	
    	void mouseSynchro(eventType type, const Vec3d& v)	//响应鼠标motion
    	{
    		//
    		//LButtonDown: 压入点
    		if (type == LButtonDown)
    		{
    			if (isFirstRender)					//for the first cell
    			{
    				vertexVector.push_back(v);		//push V0...
    				vertexVector.push_back(v);		//push V1...
    			}
    			else if ( cellRenderState() == cellRenderImple::Push )	//for any cell 
    			{
    				vertexVector.push_back(v);		//push V2...
    				vertexVector.push_back(v);		//push V3...	
    
    				cellRenderState.setChange();	//set the flag to change V3
    				cellNum++;						//increase the cell counter
    			}
    		}
    		//
    		//MouseMove: 动态更新相应的顶点数据
    		else if (type == MouseMove)		
    		{
    			if (isFirstRender)					//for the first cell
    			{	
    				vertexVector.back() = v;		//change the V1 immediately
    			}
    			else if ( cellRenderState() == cellRenderImple::Change )//for any cell
    			{
    				int vecSize = vertexVector.size();	
    				vertexVector[vecSize-2] = v;	//change the V2 immediately
    			}
    		}
    
    		//
    		//LButtonUp: 为拼接做准备
    		else if (type == LButtonUp)	
    		{	
    			if (isFirstRender)
    			{
    				//只有第一个BezierCell可以编辑bezierCell的起始段:(V0,V1)
    				isFirstRender = false;
    			}
    			else if ( cellRenderState() == cellRenderImple::Change)
    			{
    				//if finish the current cell's render
    				//利用v1和中点v0计算出v2:(v1 + v2) / 2 = v0
    				//next cell begin: push the next cell's V1... 
    				int vecSize = vertexVector.size();
    				Vec3d v0 = vertexVector[vecSize-1];
    				Vec3d v1 = vertexVector[vecSize-2];
    				Vec3d v2 = 2 * v0 - v1;
    				vertexVector.push_back(v2);
    
    				//重置cellRenderFlag
    				cellRenderState.setPush();
    			}
    		}
    		//
    		//更新数组的长度
    		_updateVertexNum();
    	}
    
    	void end()
    	{
    		glDisable(GL_MAP1_VERTEX_3);
    	}
    
    	void renderCurve()
    	{
    		//
    		//rendering vertex...
    		for (int i=0; i<vertexVector.size(); i++)
    		{
    			Vec3d v = vertexVector[i];
    			glBegin(GL_POINTS); 
    			glVertex3dv(v.getValue());
    			glEnd();
    		}
    
    		//
    		//rendering moving tangent(切线)
    		//(vertexNum-1, vertexNum-2)
    		if ( vertexNum>=2 )
    		{
    			glEnable(GL_LINE_STIPPLE);
    			{
    				glLineStipple(1, 0x0101);
    				glBegin(GL_LINES);
    				{
    					Vec3d v1 = vertexVector[vertexNum-1];
    					Vec3d v2 = vertexVector[vertexNum-2];
    					glVertex3dv(v1.getValue());
    					glVertex3dv(v2.getValue());
    				} glEnd();
    			}glDisable(GL_LINE_STIPPLE);
    		}
    
    		//
    		//if ( !_check() )
    		//	return;
    
    		//rendering bezier cells...
    		system("CLS");
    		for (int i=0; i<cellNum; i++)
    		{
    			int pos = i * 3;
    			if ( (pos+3) < vertexNum )
    				renderBezierCell( BezierCell(pos, pos+1, pos+2, pos+3) );
    		}
    		//
    	}
    
    	// 3次bezier曲线经过vetex0和vextex3
    	void renderBezierCell(const BezierCell& cell)
    	{
    		double *pBuffer = new double[Bezier3CtrlPnt * 3];
    
    		cout << "----------------------------------------------------" << endl;
    
    		cout << "Vertex number : " << vertexNum << endl;
    		cout << "Cell number : " << cellNum << endl;
    		cout << "The render cell: " << cell[0] << " " << cell[1] << " " << cell[2] << " " << cell[3] << endl;
    
    		for (int i = 0, bg = 0; i<4; i++)
    		{
    			Vec3d v = vertexVector[ cell[i] ];
    			pBuffer[bg++] = v.x();
    			pBuffer[bg++] = v.y();
    			pBuffer[bg++] = v.z();
    			
    			cout << v.x() << " " << v.y() << " " << v.z() << endl;
    		}cout << "----------------------------------------------------" << endl;
    
    		glMap1d(GL_MAP1_VERTEX_3, 0.0, 1.0, 3, Bezier3CtrlPnt, pBuffer);
    		glBegin(GL_LINE_STRIP);
    		{
    			for (int i = 0; i <= 30; i++) 
    				glEvalCoord1f((GLfloat) i/30.0f);
    		} glEnd();
    
    		delete pBuffer; pBuffer = 0;
    	}
    
    	void clear()
    	{
    		cellNum = 0;
    		vertexNum = 0;
    
    		isFirstRender = true;
    
    		vertexVector.clear();
    	}
    protected:
    	bool _check() {	vertexNum =vertexVector.size();	
    					return vertexNum == (cellNum - 1) * 3 + 4; }
    	void _updateVertexNum() { vertexNum=vertexVector.size();}
    
    	int	cellNum;						//单元个数
    	int vertexNum;						//顶点个数
    
    	bool isFirstRender;					//首次标志
    	std::vector<Vec3d> vertexVector;	//顶点数组
    
    	class cellRenderImple
    	{
    	public:
    		enum RenderStep
    		{
    			Push = 0,
    			Change = 1
    		};
    		cellRenderImple(){ setPush(); }
    		bool operator()(void) { return flag;	}
    		void setPush() { flag = Push; }
    		void setChange() { flag = Change; }
    
    		RenderStep flag;				//cell的渲染状态
    	} cellRenderState;
    };

    测试程序如下:

    #include <iostream>
    #include <vector>
    #include <GL/glut.h>
    
    #include "BezierCurve.h"
    
    using namespace std;
    
    enum WindowSize{
    	WinWidth = 1024,
    	WinHeight = 768
    };
    
    int			g_Viewport[4];
    double		g_ModelMatrix[16];
    double		g_ProjMatrix[16];
    BezierCurve myBezier;
    
    //
    void init();
    void display();
    void reshape(int w, int h);
    void keyboard(unsigned char key, int x, int y);
    void mouse(int button, int state, int x, int y);
    void motion(int x, int y);
    
    int main(int argc, char** argv)
    {
    	glutInit(&argc, argv);
    	glutInitDisplayMode (GLUT_DOUBLE | GLUT_RGB);
    	glutInitWindowSize (WinWidth, WinHeight);
    	glutInitWindowPosition (100, 100);
    	glutCreateWindow (argv[0]);
    
    	init ();
    	glutDisplayFunc(display);
    	glutReshapeFunc(reshape);
    	glutKeyboardFunc (keyboard);
    	glutMouseFunc(mouse);
    	glutMotionFunc(motion);
    
    	glutMainLoop();
    
    	return 0;
    }
    
    void init(void)
    {
    	glClearColor(0.0, 0.0, 0.0, 0.0);
    	glShadeModel(GL_SMOOTH);
    
    	myBezier.begin();
    }
    
    void display(void)
    {
    	glClear(GL_COLOR_BUFFER_BIT);
    
    	glColor3f(1.0, 1.0, 0.0);
    	glPointSize(5.0);
    
    	glPushMatrix();
    	{
    		myBezier.renderCurve();
    	}glPopMatrix();
    
    	glutSwapBuffers();
    }
    
    void reshape(int w, int h)
    {
    	glViewport(0, 0, (GLsizei) w, (GLsizei) h);
    	glMatrixMode(GL_PROJECTION);
    	glLoadIdentity();
    	if (w <= h)
    		glOrtho(-5.0, 5.0, -5.0*(GLfloat)h/(GLfloat)w, 
    		5.0*(GLfloat)h/(GLfloat)w, -5.0, 5.0);
    	else
    		glOrtho(-5.0*(GLfloat)w/(GLfloat)h, 
    		5.0*(GLfloat)w/(GLfloat)h, -5.0, 5.0, -5.0, 5.0);
    	glMatrixMode(GL_MODELVIEW);
    	glLoadIdentity();
    }
    
    void keyboard(unsigned char key, int x, int y)
    {
    	switch (key) {
    	  case 27:
    		  exit(0);
    		  break;
    	}
    }
    
    void mouse(int button, int state, int x, int y)
    {
    	double vertex[3];
    
    	//获取矩阵信息
    	glGetIntegerv(GL_VIEWPORT, g_Viewport);
    	glGetDoublev(GL_MODELVIEW_MATRIX, g_ModelMatrix);
    	glGetDoublev(GL_PROJECTION_MATRIX, g_ProjMatrix);
    
    	y = g_Viewport[3] - y;
    	gluUnProject( x, y, 0,
    		g_ModelMatrix, g_ProjMatrix, g_Viewport,
    		&vertex[0], &vertex[1], &vertex[2] );
    
    	if (button==GLUT_LEFT && state==GLUT_DOWN)
    	{
    		myBezier.mouseSynchro( BezierCurve::LButtonDown, vertex );
    		glutSetCursor( GLUT_CURSOR_RIGHT_ARROW );
    	}
    	else if (button == GLUT_LEFT && state == GLUT_UP)
    	{
    		myBezier.mouseSynchro( BezierCurve::LButtonUp, vertex );
    	}
    
    	glutPostRedisplay();
    }
    
    //
    // 计算控制节点
    void motion(int x, int y)
    {
    	double vertex[3];
    
    	glutSetCursor( GLUT_CURSOR_CROSSHAIR );
    	y = g_Viewport[3] - y;
    
    	gluUnProject( x, y, 0,
    		g_ModelMatrix, g_ProjMatrix, g_Viewport,
    		&vertex[0], &vertex[1], &vertex[2] );
    
    	myBezier.mouseSynchro( BezierCurve::MouseMove, vertex );
    	glutPostRedisplay();
    }



    展开全文
  • opengl绘制立体曲线

    2014-01-15 09:23:04
    利用自优化方法快速绘制空间立体曲线,并对两线段之间的空隙做了修正
  • OpenGL: 实现的多段Bezier曲线拼接

    千次阅读 2014-02-26 10:43:25
    //只有第一个BezierCell可以编辑bezierCell的起始:(V0,V1) isFirstRender = false; } else if ( cellRenderState() == cellRenderImple::Change) { //if finish the current cell's render ...

    运行程序的交互方式有点类似corelDraw中的自由曲线绘制,或者photoShop中的钢笔自由路径绘制。

    截图:

     

    将BezierCurve封装成了一个类,代码如下:

    #ifndef _BEZIERCURVE_H
    #define _BEZIERCURVE_H
    
    #include "vec3.hpp"
    #include <vector>
    #include <iostream>
    #include <gl/glut.h>
    
    using namespace std;
     3次bezier曲线: 四个控制节点。曲线经过首末两个顶点。
    
    class BezierCurve
    {
    public:
    	//cell一共有四个控制顶点
    	//	-cell经过V0和V3顶点,
    	//	-cell的始端相切于直线:(V0, V1) 和末端相切于(V2,V3)
    	class BezierCell
    	{
    	public:
    		BezierCell(int i0, int i1, int i2, int i3)
    		{
    			setValue(i0, i1, i2, i3);
    		}
    
    		void setValue(int i0, int i1, int i2, int i3)
    		{
    			ctrlVertxIndex[0] = i0;
    			ctrlVertxIndex[1] = i1;
    			ctrlVertxIndex[2] = i2;
    			ctrlVertxIndex[3] = i3;
    		}
    		const int operator[](int index) const
    		{
    			if (index > 3 || index < 0)
    				return -1;
    
    			return ctrlVertxIndex[index];
    		}
    		int ctrlVertxIndex[4];
    	};
    
    	enum eventType
    	{
    		LButtonDown = 0,
    		MouseMove = 1,
    		LButtonUp = 2
    	};
    	
    	enum { Bezier3CtrlPnt = 4 };
    
    	BezierCurve() { clear(); }
    	~BezierCurve(){}
    
    	void begin()
    	{
    		// 开启求值器
    		glEnable(GL_MAP1_VERTEX_3);
    		clear();
    	}
    	
    	void mouseSynchro(eventType type, const Vec3d& v)	//响应鼠标motion
    	{
    		//
    		//LButtonDown: 压入点
    		if (type == LButtonDown)
    		{
    			if (isFirstRender)					//for the first cell
    			{
    				vertexVector.push_back(v);		//push V0...
    				vertexVector.push_back(v);		//push V1...
    			}
    			else if ( cellRenderState() == cellRenderImple::Push )	//for any cell 
    			{
    				vertexVector.push_back(v);		//push V2...
    				vertexVector.push_back(v);		//push V3...	
    
    				cellRenderState.setChange();	//set the flag to change V3
    				cellNum++;						//increase the cell counter
    			}
    		}
    		//
    		//MouseMove: 动态更新相应的顶点数据
    		else if (type == MouseMove)		
    		{
    			if (isFirstRender)					//for the first cell
    			{	
    				vertexVector.back() = v;		//change the V1 immediately
    			}
    			else if ( cellRenderState() == cellRenderImple::Change )//for any cell
    			{
    				int vecSize = vertexVector.size();	
    				vertexVector[vecSize-2] = v;	//change the V2 immediately
    			}
    		}
    
    		//
    		//LButtonUp: 为拼接做准备
    		else if (type == LButtonUp)	
    		{	
    			if (isFirstRender)
    			{
    				//只有第一个BezierCell可以编辑bezierCell的起始段:(V0,V1)
    				isFirstRender = false;
    			}
    			else if ( cellRenderState() == cellRenderImple::Change)
    			{
    				//if finish the current cell's render
    				//利用v1和中点v0计算出v2:(v1 + v2) / 2 = v0
    				//next cell begin: push the next cell's V1... 
    				int vecSize = vertexVector.size();
    				Vec3d v0 = vertexVector[vecSize-1];
    				Vec3d v1 = vertexVector[vecSize-2];
    				Vec3d v2 = 2 * v0 - v1;
    				vertexVector.push_back(v2);
    
    				//重置cellRenderFlag
    				cellRenderState.setPush();
    			}
    		}
    		//
    		//更新数组的长度
    		_updateVertexNum();
    	}
    
    	void end()
    	{
    		glDisable(GL_MAP1_VERTEX_3);
    	}
    
    	void renderCurve()
    	{
    		//
    		//rendering vertex...
    		for (int i=0; i<vertexVector.size(); i++)
    		{
    			Vec3d v = vertexVector[i];
    			glBegin(GL_POINTS); 
    			glVertex3dv(v.getValue());
    			glEnd();
    		}
    
    		//
    		//rendering moving tangent(切线)
    		//(vertexNum-1, vertexNum-2)
    		if ( vertexNum>=2 )
    		{
    			glEnable(GL_LINE_STIPPLE);
    			{
    				glLineStipple(1, 0x0101);
    				glBegin(GL_LINES);
    				{
    					Vec3d v1 = vertexVector[vertexNum-1];
    					Vec3d v2 = vertexVector[vertexNum-2];
    					glVertex3dv(v1.getValue());
    					glVertex3dv(v2.getValue());
    				} glEnd();
    			}glDisable(GL_LINE_STIPPLE);
    		}
    
    		//
    		//if ( !_check() )
    		//	return;
    
    		//rendering bezier cells...
    		system("CLS");
    		for (int i=0; i<cellNum; i++)
    		{
    			int pos = i * 3;
    			if ( (pos+3) < vertexNum )
    				renderBezierCell( BezierCell(pos, pos+1, pos+2, pos+3) );
    		}
    		//
    	}
    
    	// 3次bezier曲线经过vetex0和vextex3
    	void renderBezierCell(const BezierCell& cell)
    	{
    		double *pBuffer = new double[Bezier3CtrlPnt * 3];
    
    		cout << "----------------------------------------------------" << endl;
    
    		cout << "Vertex number : " << vertexNum << endl;
    		cout << "Cell number : " << cellNum << endl;
    		cout << "The render cell: " << cell[0] << " " << cell[1] << " " << cell[2] << " " << cell[3] << endl;
    
    		for (int i = 0, bg = 0; i<4; i++)
    		{
    			Vec3d v = vertexVector[ cell[i] ];
    			pBuffer[bg++] = v.x();
    			pBuffer[bg++] = v.y();
    			pBuffer[bg++] = v.z();
    			
    			cout << v.x() << " " << v.y() << " " << v.z() << endl;
    		}cout << "----------------------------------------------------" << endl;
    
    		glMap1d(GL_MAP1_VERTEX_3, 0.0, 1.0, 3, Bezier3CtrlPnt, pBuffer);
    		glBegin(GL_LINE_STRIP);
    		{
    			for (int i = 0; i <= 30; i++) 
    				glEvalCoord1f((GLfloat) i/30.0f);
    		} glEnd();
    
    		delete pBuffer; pBuffer = 0;
    	}
    
    	void clear()
    	{
    		cellNum = 0;
    		vertexNum = 0;
    
    		isFirstRender = true;
    
    		vertexVector.clear();
    	}
    protected:
    	bool _check() {	vertexNum =vertexVector.size();	
    					return vertexNum == (cellNum - 1) * 3 + 4; }
    	void _updateVertexNum() { vertexNum=vertexVector.size();}
    
    	int	cellNum;						//单元个数
    	int vertexNum;						//顶点个数
    
    	bool isFirstRender;					//首次标志
    	std::vector<Vec3d> vertexVector;	//顶点数组
    
    	class cellRenderImple
    	{
    	public:
    		enum RenderStep
    		{
    			Push = 0,
    			Change = 1
    		};
    		cellRenderImple(){ setPush(); }
    		bool operator()(void) { return flag;	}
    		void setPush() { flag = Push; }
    		void setChange() { flag = Change; }
    
    		RenderStep flag;				//cell的渲染状态
    	} cellRenderState;
    };

    测试程序如下:

    #include <iostream>
    #include <vector>
    #include <GL/glut.h>
    
    #include "BezierCurve.h"
    
    using namespace std;
    
    enum WindowSize{
    	WinWidth = 1024,
    	WinHeight = 768
    };
    
    int			g_Viewport[4];
    double		g_ModelMatrix[16];
    double		g_ProjMatrix[16];
    BezierCurve myBezier;
    
    //
    void init();
    void display();
    void reshape(int w, int h);
    void keyboard(unsigned char key, int x, int y);
    void mouse(int button, int state, int x, int y);
    void motion(int x, int y);
    
    int main(int argc, char** argv)
    {
    	glutInit(&argc, argv);
    	glutInitDisplayMode (GLUT_DOUBLE | GLUT_RGB);
    	glutInitWindowSize (WinWidth, WinHeight);
    	glutInitWindowPosition (100, 100);
    	glutCreateWindow (argv[0]);
    
    	init ();
    	glutDisplayFunc(display);
    	glutReshapeFunc(reshape);
    	glutKeyboardFunc (keyboard);
    	glutMouseFunc(mouse);
    	glutMotionFunc(motion);
    
    	glutMainLoop();
    
    	return 0;
    }
    
    void init(void)
    {
    	glClearColor(0.0, 0.0, 0.0, 0.0);
    	glShadeModel(GL_SMOOTH);
    
    	myBezier.begin();
    }
    
    void display(void)
    {
    	glClear(GL_COLOR_BUFFER_BIT);
    
    	glColor3f(1.0, 1.0, 0.0);
    	glPointSize(5.0);
    
    	glPushMatrix();
    	{
    		myBezier.renderCurve();
    	}glPopMatrix();
    
    	glutSwapBuffers();
    }
    
    void reshape(int w, int h)
    {
    	glViewport(0, 0, (GLsizei) w, (GLsizei) h);
    	glMatrixMode(GL_PROJECTION);
    	glLoadIdentity();
    	if (w <= h)
    		glOrtho(-5.0, 5.0, -5.0*(GLfloat)h/(GLfloat)w, 
    		5.0*(GLfloat)h/(GLfloat)w, -5.0, 5.0);
    	else
    		glOrtho(-5.0*(GLfloat)w/(GLfloat)h, 
    		5.0*(GLfloat)w/(GLfloat)h, -5.0, 5.0, -5.0, 5.0);
    	glMatrixMode(GL_MODELVIEW);
    	glLoadIdentity();
    }
    
    void keyboard(unsigned char key, int x, int y)
    {
    	switch (key) {
    	  case 27:
    		  exit(0);
    		  break;
    	}
    }
    
    void mouse(int button, int state, int x, int y)
    {
    	double vertex[3];
    
    	//获取矩阵信息
    	glGetIntegerv(GL_VIEWPORT, g_Viewport);
    	glGetDoublev(GL_MODELVIEW_MATRIX, g_ModelMatrix);
    	glGetDoublev(GL_PROJECTION_MATRIX, g_ProjMatrix);
    
    	y = g_Viewport[3] - y;
    	gluUnProject( x, y, 0,
    		g_ModelMatrix, g_ProjMatrix, g_Viewport,
    		&vertex[0], &vertex[1], &vertex[2] );
    
    	if (button==GLUT_LEFT && state==GLUT_DOWN)
    	{
    		myBezier.mouseSynchro( BezierCurve::LButtonDown, vertex );
    		glutSetCursor( GLUT_CURSOR_RIGHT_ARROW );
    	}
    	else if (button == GLUT_LEFT && state == GLUT_UP)
    	{
    		myBezier.mouseSynchro( BezierCurve::LButtonUp, vertex );
    	}
    
    	glutPostRedisplay();
    }
    
    //
    // 计算控制节点
    void motion(int x, int y)
    {
    	double vertex[3];
    
    	glutSetCursor( GLUT_CURSOR_CROSSHAIR );
    	y = g_Viewport[3] - y;
    
    	gluUnProject( x, y, 0,
    		g_ModelMatrix, g_ProjMatrix, g_Viewport,
    		&vertex[0], &vertex[1], &vertex[2] );
    
    	myBezier.mouseSynchro( BezierCurve::MouseMove, vertex );
    	glutPostRedisplay();
    }

    http://blog.csdn.net/ryfdizuo/article/details/4728785

    展开全文
  • OpenGL曲线

    千次阅读 2011-05-20 15:22:00
    这里讲解OPENGL的曲线生成 1.曲线定义 void glMap1{fd}(GLenum target,TYPE u1,TYPE u2,GLint stride, GLint order,const TYPE *points); target指出控制点的意义以及在points参数中需要多少值。...

    这里讲解OPENGL的曲线生成 
    1.曲线定义 
    void glMap1{fd}(GLenum target,TYPE u1,TYPE u2,GLint stride, 
                    GLint order,const TYPE *points); 
     
    target指出控制点的意义以及在points参数中需要多少值。具体如下: 
     
    target                                   		意义 
    GL_MAP1_VERTEX_3             	X Y Z顶点坐标 
    GL_MAP1_VERTEX_4                    X Y Z W顶点坐标 
    GL_MAP1_INDEX                         颜色索引 
    GL_MAP1_COLOR_4                     R G B A 
    GL_MAP1_NORMAL                      法向量 
    GL_MAP1_TEXTURE_COORD_1      S 纹理坐标 
    GL_MAP1_TEXTURE_COORD_2      S T纹理坐标 
    GL_MAP1_TEXTURE_COORD_3      S T R纹理坐标 
     
    u1,u2是曲线变量U的范围(具体可以参阅图形学书籍)一般是0到1 
    stride是跨度,表示points中控制点偏移量(或说是控制点的维数) 
    order是阶数,与控制点数一样 
    points是控制点坐标 
    曲线定义后要启用才能进行绘制,同样用glEnable(),glDisable()。 
    2.曲线计算绘制 
    void glEvalCoord1{fd}[v](TYPE u); 
    利用控制点产生曲线U坐标下某点的坐标,调用一次只能产生一个坐标。 
    一般的曲线的绘制方法是让U变化从0到1(步长自定)然后把这些坐标用直线连接起来。 
    用以上这两个函数就可以完成绘制曲线的功能。 
     
    另外还有两个函数可以实现类似功能: 
    void glMapGrid1{fd}(GLint n,TYPE u1,TYPE u2); 
    定义一个空间网格,从u1到u2分为n步,是等间隔的(曲线参数)。 
    void glEvalMesh1(GLenum mode,GLint p1,GLint p2); 
    计算并绘制坐标点。mode可以是GL_POINT、GL_LINE即延曲线绘点或连接直线段 
    它等价于: 
    glBegin(GL_POINT); 
     for(i=p1;i<=p2;i++) 
      glEvalCoord1(u1+i*(u2-u1)/n); 
    glEnd(); 
    下面给出一个BEZIER曲线的例子: 
     
    #include <gl/gl.h>
    #include <gl/glu.h>
    #include <gl/glaux.h>
    
    #pragma comment(lib, "OpenGl32.lib")
    #pragma comment(lib, "glu32.lib")
    #pragma comment(lib, "glaux.lib")
    
    #pragma warning(disable : 4244)		// MIPS
    #pragma warning(disable : 4136)		// X86
    #pragma warning(disable : 4051)		// ALPHA 
    void myinit(void); 
    void CALLBACK  display(void); 
    void CALLBACK  reshape(GLsizei w,GLsizei h); 
     
    //定义四个控制点的坐标 
    GLfloat points[4][3]={ 
            {-4.0,-4.0,0.0},{-2.0,4.0,0.0},{2.0,-4.0,0.0},{4.0,4.0,0.0}}; 
     
    void myinit(void) 
    { 
     
            auxInitDisplayMode(AUX_SINGLE|AUX_RGBA); 
            auxInitPosition(0,0,500,500); 
            auxInitWindow("sample1"); 
            glClearColor(0.0,0.0,0.0,0.0); 
            glClear(GL_COLOR_BUFFER_BIT); 
     
    //定义曲线,并启用绘制曲线的模式 
            glMap1f(GL_MAP1_VERTEX_3,0.0,1.0,3,4,&points[0][0]); 
            glEnable(GL_MAP1_VERTEX_3); 
     
            glShadeModel(GL_FLAT); 
    } 
     
    void CALLBACK reshape(GLsizei w,GLsizei h) 
    { 
     
    glViewport(0,0,w,h); 
    glMatrixMode(GL_PROJECTION); 
    glLoadIdentity(); 
     
    if(w<=h) 
     glOrtho(-5.0,5.0,-5.0*(GLfloat)h/(GLfloat)w, 
             5.0*(GLfloat)h/(GLfloat)w,-5.0,5.0); 
    else 
      glOrtho(-5.0*(GLfloat)h/(GLfloat)w, 
             5.0*(GLfloat)h/(GLfloat)w,-5.0,5.0,-5.0,5.0); 
    glMatrixMode(GL_MODELVIEW); 
    glLoadIdentity(); 
    } 
     
     
    void CALLBACK display(void) 
    { 
      glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); 
      glColor3f(0.0,0.0,1.0); 
      glBegin(GL_LINE_STRIP); 
    //首先以30步的直线段连接,来绘制曲线,注意使用GL_LINE_STRIP来连接直线段 
      int i; 
      for(i=0;i<=30;i++) 
               glEvalCoord1f((GLfloat)i/30.0); 
      glEnd(); 
     
    //下面绘制出4个控制点   
      glPointSize(4.0); 
      glColor3f(1.0,0.0,0.0); 
      glBegin(GL_POINTS); 
      for(i=0;i<4;i++) 
               glVertex3fv(&points[i][0]); 
      glEnd(); 
     
      glFlush(); 
     
     
    } 
    void main(void) 
    { 
        myinit(); 
         
        auxReshapeFunc(reshape); 
        auxMainLoop(display); 
    } 
    //end of sample 
    本例子绘制出一个有4个控制点的BEZIER曲线。曲线经过头尾两个控制点 
    中间曲线形状由控制点次序和位置决定,总之落在其包围的四边形以内。 
    下次将会用大篇幅介绍曲面的生成和其表面纹理、颜色的应用 

    展开全文
  • (切记)使用OpenGL画图时首先要创建并显示一个窗口,然后再绘制,这一点新手常常会忘记。 #include "pch.h" #include<windows.h> //包含了WGL函数 #include<GL/GL.h> //OpenGL库 #include<GL/GLU.h&...

    (切记)使用OpenGL画图时首先要创建并显示一个窗口,然后再绘制,这一点新手常常会忘记。

    #include "pch.h"
    #include<windows.h> //包含了WGL函数
    #include<GL/GL.h> //OpenGL库
    #include<GL/GLU.h> //OpenGL库
    #include<GL/glut.h> //处理窗口管理操作
    #include <iostream>
    #include<stdio.h> //标准输入输出函数
    #include<stdlib.h> //最常用的系统函数
    #include<math.h> //数学函数
    
    
    
    //初始化操作
    void init()
    {
    	glClearColor(1.0, 1.0, 1.0, 0.0);//清除窗口背景色为白色(red,green,blue,alpha透明度),该背景颜色不显示
    	//接下来告诉OpenGL如何将图形投影到显示器中,二维线在OpenGL中被视为三维线的特例进行处理
    	glMatrixMode(GL_PROJECTION);//设置投影矩阵,说明接下来要对投影进行一系列操作。
    	                            /*glMatrixMode()函数就是对接下来要做什么进行一下说明,
    								也就是在要做下一步之前告诉计算机我要对“什么”进行操作,
    								GL_PROJECTION(投影),GL_MODELVIEW(模型视图),GL_TEXTURE(纹理)。
    								如果参数是GL_PROJECTION,就是要对投影进行相关操作,
    								也就是要把一个物体投影到一个平面上。*/
    	gluOrtho2D(0.0, 200.0, 0.0, 150.0);//gluOrtho2D(lift,right,bottom,top)是指屏幕区域对应的模型坐标范围,
    	                                   //本次投影操作横向范围是0到200,纵向是0到150
         //只要是在该矩阵内定义的对象,都会显示在窗口上
    }
    
    //显示直线
    void lineSegment(void)
    {
    	glClear(GL_COLOR_BUFFER_BIT);//把窗口显示为当前缓冲区的颜色(背景色未显示出来),
    							  //GL_COLOR_BUFFER_BIT为颜色缓冲区,用来指定颜色缓存中的位值,
    							//是glClearColor函数中指定的值
    	glColor3f(0.0, 1.0, 0.0);         //设置显示对象颜色,此时为绿色。glColor3f(R,G,B),
    								 //对窗口显示的对象进行颜色设定,三元素值最小是0(不显示),最大是1
    
    	glBegin(GL_LINES);            //对元素类型进行操作 glBegin(GLenum mode),mode为元素类型
    	                              //GL_LINES绘制一组直线。使用此常量可连接每一组相邻端点而得到一组直线段,
    	                              //在glBegin/glEnd中如果只指定一个点,则什么也不显示,如果指定的是奇数个点,则最后一个点忽略。
    	                             /*OpenGL空间使用的是右手系的定义,与屏幕水平方向一致,并方向向右的是x轴;
    								 与屏幕垂直方向一致,并方向向上的是y轴;与屏幕垂直方向,并方向向外的是z轴
    								 */
    	glVertex2i(10, 145);
    	glVertex2i(180,15);          //指定顶点坐标,2表示二维,有两个参数;i表示32位整数(GLint、GLsizei)
    	glColor3f(1.0, 0.0, 0.0);     //下一条线为红色
    	glVertex2i(10, 25);
    	glVertex2i(180,145);
    	glEnd();
    
    	glFlush();                  //强制清空缓冲区,并将指令送往缓硬件立即执行,将指令传送完毕之后会立即返回。
    	                            //而glFinish将缓冲区的指令立即送往硬件执行,但是要一直等到硬件执行完这些指令之后才返回。
    }
    
    int main(int argc, char *argv[]) {
    	glutInit(&argc,argv);//初始化GLUT
    	/*这个函数用来初始化GLUT库.这个函数从main函数获取其两个参数.对应main函数的形式应是 : int main(int argc, char* argv[]);
    	在这个部分我们将在我们的程序里建立一个main函数,这个main函数将完成必须的初始化和开启事件处理循环。
    	所有的GLUT函数都有glut前缀并且那些完成一些初始化的函数有glutInit前缀。你首先要做的是调用函数glutInit()。*/
    	/*GLUT(OpenGL Utility Toolkit)OpenGL的程式工具库,负责处理和底层操作系统的呼叫以及I/O*/
    	glutInitDisplayMode(GLUT_SINGLE|GLUT_RGB);//设置窗口的缓存和颜色模式,默认单缓冲和RGB颜色
    	glutInitWindowPosition(50, 100);//设置窗口出现在屏幕上的位置
    	glutInitWindowSize(400,300);//设置窗口大小
    	glutCreateWindow("An Example OpenGL Program");//创建窗口并显示窗口标题
    	init();
    	glutDisplayFunc(lineSegment);//将图赋值给显示窗口。glutDisplayFunc用于窗口变化时刷新窗口内容
    	//glutDisplayFunc(&display)在程序运行时是自动调用的,即程序会自动调用display函数重绘窗口
    	glutMainLoop();//进入GLUT事件处理循环,让所有的与“事件”有关的函数调用无限循环。一旦调用,永不返回
    }
    
    /*GLUT的基本功能:
    
    包括窗口初始化功能、事件处理、窗口和菜单管理、回调函数注册和几何建模功能。
    
    窗口初始化功能,它有4个函数。主要用于处理初始化并以及命令行参数,初始化显示模式,指定窗口左上角在屏幕上的位置和窗口大小,以像素为单位。
    
    事件处理只有一个函数,它用于显示创建的窗口、处理输入的事件、触发回调函数、进入循环直到程序退出。
    
    窗口管理包含18个函数,用于建立、销毁窗口及可能的子窗口,管理和设置窗口的属性。
    
    在GLUT中有20个回调函数,用于响应用户事件。最重要的回调函数是glutDisplayFunc,当GLUT认为需要重新显示窗口内容时,
    都将执行这一函数注册的回调函数。另外一些重要的回调函数注册函数有:函数glutRe-shapeFunc用于注册窗口大小改变这一事件发生时GLUT将调用的函数。
    glutKeyboardFunc和glutMouseFunc用于注册键盘和鼠标事件发生时的回调函数。函数glutMotionFunc注册鼠标移动事件的回调函数。
    这3个函数用于人机交互处理。在没有其他事件处理时,GLUT将调用函数glutldleFunc注册的函数,而函数glutTimerFunc则注册处理定时器事件的函数。
    
    OpenGL绘图函数只能生成点、直线、多边形等简单的几何图元,GLUT提供了18个创建三维物体的函数。
    利用它们可以创建9种三维物体,如圆锥体、立方体、球体等,每一物体有线框和实体2种方式。
    
    我们看到的以glut 开头的函数都是 glut 库的一部分,如处理参数的,和设置窗口的,我们在这里主要讨论glut 支持的各种消息处理*/
    
    
    
    
    // 运行程序: Ctrl + F5 或调试 >“开始执行(不调试)”菜单
    // 调试程序: F5 或调试 >“开始调试”菜单
    
    // 入门提示: 
    //   1. 使用解决方案资源管理器窗口添加/管理文件
    //   2. 使用团队资源管理器窗口连接到源代码管理
    //   3. 使用输出窗口查看生成输出和其他消息
    //   4. 使用错误列表窗口查看错误
    //   5. 转到“项目”>“添加新项”以创建新的代码文件,或转到“项目”>“添加现有项”以将现有代码文件添加到项目
    //   6. 将来,若要再次打开此项目,请转到“文件”>“打开”>“项目”并选择 .sln 文件
    
    展开全文
  • OpenGL es 流水线与驱动

    千次阅读 2015-12-08 09:46:56
    OpenGL es 流水线就是将用户输入的3D数据经过一系列的处理最终生成用户在屏幕上看到的3D图像。这一过程由一系列专业的模块组成,如下图所示。 二、OpenGL es pipeline的功能特点: 3D图形=》3D图像:3D图形是精确...
  • 这里讲的是一些有趣而美丽的曲线,蜗型线、心形线、三叶曲线、四叶曲线、螺旋线等,都是由圆公式的一些特殊的变化带来的,我们使用了参数极坐标方程来计算曲线路径的点,这些点用做显示弧的逼近折现中直线的端点。...
  • opengl可编程管线鼠标画线段

    千次阅读 2018-04-22 20:49:03
    学习opengl可编程管线的基础知识的网站:learnOpengl主要讲一下如何使用可编程管线实现鼠标交互的线段绘制。首先声明两种回调函数以及将其设置给对应的函数:MouseButtonCallback在鼠标按下时才会调用,...
  • opengl流水线

    千次阅读 2015-09-07 22:54:16
    OpenGL ES中的物体绘制并不是直接在屏幕上进行的,而是预先在帧缓冲区中进行绘制,每绘制完一帧再将绘制的结果 交换到屏幕上。因此,在每次绘制新的一帧时都需要清除缓冲区中的相关数据,否则有可能产生不正确的...
  • Opengl Shader发光线条实例

    千次阅读 2017-03-15 17:04:59
    其中50.0是用来控制线的宽度的(数值越大,线越细),效果如下: 3.3)把直线变为曲线,并使其动起来: [csharp]   view plain   copy   uv.y +=...
  • 在下面两篇文章中我分别用贝塞尔曲线的定义公式和递推公式实现了贝塞尔曲线的...这里我们使用OpenGL中贝塞尔曲线函数实现贝塞尔曲线的绘制,另外可以让用户自己通过鼠标选择四个控制点,画三次贝塞尔曲线。 重要函...
  • OpenGL - Hermite算法多点画光滑曲线

    千次阅读 2017-10-16 17:17:39
    本来以为矩阵求方程是最难的,没想到写个高斯消元一下就解决了,十分钟就写完了解方程的部分。然后花了将近四个小时查bug(QAQ)说一下算法思路: ...但是考虑多点问题时,光滑连接就是主要问题了,如果我们能求出中间...
  • 我正在创建一个需要绘制个线段的应用程序,每个线段...如何在Android上的OpenGL-ES中绘制个不同颜色的线段我是OpenGL的新手,所以希望了解如何最好地解决这个问题。谢谢。vertexBuffer.position(0);vertexBuffer...
  • openGL线---openGL学习笔记(三)

    千次阅读 2016-02-26 14:32:26
    openGL中的图元一共有三种:点、线、三角形。 针对线openGL为我们提供了三种画线的方式: ①画线段(lines):所谓...首先来实现画线段,这里我们来画一个发散的射线形状,效果图如下: render的实现类重
  • OpenGL

    2017-08-24 19:50:42
    色彩的三原色:红色,绿色和蓝色,是我们通常所说的RGB颜色空间,在OpenGL中,我们通常会在这三个后面加上第四个,即Alpha,合成就是我们通常所说的RGBA.颜色空间的种类:RGBA,HSV(色调,饱和度,值),CM
  • OpenGL 的渲染流水线

    千次阅读 2013-03-31 17:12:19
    这一系列的过程称为OpenGL渲染流水线。一般的渲染流水线过程有如下几步: 显示列表 求值程序 顶点操作 图元装配 像素操作 纹理装配 光栅化 片断操作 OpenGL工作流程图: 也可以简单的记为: ...
  • 如图所示:我用opengl的vbo技术,把采集到的a、b、c、d、e、f、g、h........点存进了buffer。 需求是把这些点连成图下面那个曲线(方波),我现在只能以LINE_STRIP的方式连成上图曲线(三角波)。 大家有什么方法...
  • 今天,用opengl实现bezier曲线的绘制,但是当我将控制点增加到九个的时候,程序死活绘制不出图像。 后来经过一番折腾,终于知道,是xp系统的问题,程序在win7上可以正常运行。 下面我附上我的主要程序 第一是...
  • OpenGL进行曲线、曲面的绘制

    千次阅读 2020-01-16 13:59:51
    理解OpenGL中一维、二维插值求值器的用法。 掌握OpenGL中曲线、曲面绘图的方法,对比不同参数下的绘图效果差异; 代码1:用四个控制点绘制一条三次Bezier曲线 Github地址 #include "stdafx.h" #include <...
  • 三、绘制条线段 GL_LINES、 四、绘制依次连接的点组成的线 GL_LINE_STRIP、 五、绘制圈 GL_LINE_LOOP ( 偶数个点 )、 六、绘制圈 GL_LINE_LOOP ( 奇数个点 )、 七、绘制彩色的线、 八、相关资源、
  • 计算机图形学-基于OpenGL的绘制Bezier曲线本实验集成开发环境为vs2013,基于OpenGL。实验内容根据Bezier曲线的定义,绘制Bezier曲线。自己编程实现Bernstain基函数,然后在曲线上采集200个点,连成拆线绘制。预备...
  • OpenGL(二) 一、思考 所有的图像都是由面组成的 面是由线组成的 线是由点组成的 所以构建一个图像最基础的是由点构成的 二、怎么确定点的位置 如何指定一个点呢?OpenGL提供了一系列函数。它们都以glVertex...
  • Python+OpenGL DDA直线的扫描转换算法 算法还是比较容易理解的,glVertex2f()没摸明白。 from OpenGL.GL import * from OpenGL.GLU import * from OpenGL.GLUT import * import math def draw(): x0=0 y0=0 x1...
  • OpenGL绘制任意阶次B样条曲线

    千次阅读 2019-11-20 10:34:30
    最近开始新学习OpenGL绘图编程,在学习绘制B样条曲线时,遇到了很问题,我在CSDN上搜索阅读了基本上所有有关B样条曲线的绘制,但感觉说的都不是很全面,这篇讲了一个点,那一篇又讲了另一个点。而且大部分博客所讲...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 14,715
精华内容 5,886
关键字:

opengl多段线