OpenGL实现贝塞尔曲线或曲面

所属分类: 软件编程 / C 语言 阅读数: 153
收藏 0 赞 0 分享

本文实例为大家分享了OpenGL实现贝塞尔曲线或曲面的具体代码,供大家参考,具体内容如下

理论基础

贝塞尔曲线和曲面:OpenGL只能直接绘制基本图元,对于曲线和曲面我们一般采用一系列线段或多边形来模拟的,这样当线段或多边形增多时必定很耗性能。其实对于这种曲线和曲面,我们可以使用一些控制点,通过求值器程序先计算出坐标等信息,然后直接用这些数据绘制,这样不仅节省内存,还提高了模拟曲线或曲面的精度(本质还是通过线段或多边形绘制的,只是求值器提前算出了曲线或曲面的顶点信息)。

求值器使用一般步骤:1.启用求值器 2.定义求值器 3.执行求值器。

注释:OpenGl3.1后,本节内容都已经废弃了,这些顶点着色器都可以实现了。

代码示例

1、曲线

#include "GLTools.h"

#ifdef __APPLE__
#include <glut/glut.h>
#else
#define FREEGLUT_STATIC
#include <GL/glut.h>
#endif

//控制点
GLfloat ctrlpoints[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 init(void)
{
 glClearColor(0.0, 0.0, 0.0, 0.0);
 glShadeModel(GL_FLAT);
 //定义一维求值器
 glMap1f(GL_MAP1_VERTEX_3, 0.0, 1.0, 3, 4, &ctrlpoints[0][0]);
 //启动求职器
 glEnable(GL_MAP1_VERTEX_3);
}

void display(void)
{
 int i;

 glClear(GL_COLOR_BUFFER_BIT);
 glColor3f(1.0, 1.0, 1.0);
 glBegin(GL_LINE_STRIP);
 for (i = 0; i <= 30; i++)
  glEvalCoord1f((GLfloat) i/30.0);//执行求值器,每执行一次产生一个坐标
 glEnd();

 //绘制4个控制点
 glPointSize(5.0);
 glColor3f(1.0, 1.0, 0.0);
 glBegin(GL_POINTS);
 for (i = 0; i < 4; i++)
  glVertex3fv(&ctrlpoints[i][0]);
 glEnd();
 glFlush();
}

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;
 }
}

int main(int argc, char** argv)
{
 glutInit(&argc, argv);
 glutInitDisplayMode (GLUT_SINGLE | GLUT_RGB);
 glutInitWindowSize (500, 500);
 glutInitWindowPosition (100, 100);
 glutCreateWindow (argv[0]);
 init ();
 glutDisplayFunc(display);
 glutReshapeFunc(reshape);
 glutKeyboardFunc (keyboard);
 glutMainLoop();
 return 0;
}

2、曲面

#include "GLTools.h"

#ifdef __APPLE__
#include <glut/glut.h>
#else
#define FREEGLUT_STATIC
#include <GL/glut.h>
#endif

GLfloat ctrlpoints[4][4][3] = {
 {{ -1.5, -1.5, 4.0}, { -0.5, -1.5, 2.0},
  {0.5, -1.5, -1.0}, {1.5, -1.5, 2.0}},
 {{ -1.5, -0.5, 1.0}, { -0.5, -0.5, 3.0},
  {0.5, -0.5, 0.0}, {1.5, -0.5, -1.0}},
 {{ -1.5, 0.5, 4.0}, { -0.5, 0.5, 0.0},
  {0.5, 0.5, 3.0}, {1.5, 0.5, 4.0}},
 {{ -1.5, 1.5, -2.0}, { -0.5, 1.5, -2.0},
  {0.5, 1.5, 0.0}, {1.5, 1.5, -1.0}}
};

GLfloat texpts[2][2][2] = {{{0.0, 0.0}, {0.0, 1.0}},
 {{1.0, 0.0}, {1.0, 1.0}}};

void display(void)
{
 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
 glColor3f(1.0, 1.0, 1.0);
 glEvalMesh2(GL_FILL, 0, 20, 0, 20);//glMapGrid2f()均匀产生坐标值,这里执行绘制
 glFlush();
}

#define imageWidth 64
#define imageHeight 64
GLubyte image[3*imageWidth*imageHeight];
//纹理数据
void makeImage(void)
{
 int i, j;
 float ti, tj;

 for (i = 0; i < imageWidth; i++) {
  ti = 2.0*3.14159265*i/imageWidth;
  for (j = 0; j < imageHeight; j++) {
   tj = 2.0*3.14159265*j/imageHeight;

   image[3*(imageHeight*i+j)] = (GLubyte) 127*(1.0+sin(ti));
   image[3*(imageHeight*i+j)+1] = (GLubyte) 127*(1.0+cos(2*tj));
   image[3*(imageHeight*i+j)+2] = (GLubyte) 127*(1.0+cos(ti+tj));
  }
 }
}

void init(void)
{
 //定义了两个求值器程序
 glMap2f(GL_MAP2_VERTEX_3, 0, 1, 3, 4,
   0, 1, 12, 4, &ctrlpoints[0][0][0]);
 glMap2f(GL_MAP2_TEXTURE_COORD_2, 0, 1, 2, 2,
   0, 1, 4, 2, &texpts[0][0][0]);
 glEnable(GL_MAP2_TEXTURE_COORD_2);
 glEnable(GL_MAP2_VERTEX_3);
 glMapGrid2f(20, 0.0, 1.0, 20, 0.0, 1.0);//均匀产生坐标

 //纹理属性设置
 makeImage();
 glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);
 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, imageWidth, imageHeight, 0, GL_RGB, GL_UNSIGNED_BYTE, image);
 glEnable(GL_TEXTURE_2D);
 glEnable(GL_DEPTH_TEST);
 glShadeModel (GL_FLAT);
}

void reshape(int w, int h)
{
 glViewport(0, 0, (GLsizei) w, (GLsizei) h);
 glMatrixMode(GL_PROJECTION);
 glLoadIdentity();
 if (w <= h)
  glOrtho(-4.0, 4.0, -4.0*(GLfloat)h/(GLfloat)w,
    4.0*(GLfloat)h/(GLfloat)w, -4.0, 4.0);
 else
  glOrtho(-4.0*(GLfloat)w/(GLfloat)h,
    4.0*(GLfloat)w/(GLfloat)h, -4.0, 4.0, -4.0, 4.0);
 glMatrixMode(GL_MODELVIEW);
 glLoadIdentity();
 glRotatef(85.0, 1.0, 1.0, 1.0);
}

void keyboard(unsigned char key, int x, int y)
{
 switch (key) {
  case 27:
   exit(0);
   break;
 }
}

int main(int argc, char** argv)
{
 glutInit(&argc, argv);
 glutInitDisplayMode (GLUT_SINGLE | GLUT_RGB | GLUT_DEPTH);
 glutInitWindowSize (500, 500);
 glutInitWindowPosition (100, 100);
 glutCreateWindow (argv[0]);
 init ();
 glutDisplayFunc(display);
 glutReshapeFunc(reshape);
 glutKeyboardFunc(keyboard);
 glutMainLoop();
 return 0;

}

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

更多精彩内容其他人还在看

用标准c++实现string与各种类型之间的转换

这个类在头文件中定义, < sstream>库定义了三种类:istringstream、ostringstream和stringstream,分别用来进行流的输入、输出和输入输出操作。另外,每个类都有一个对应的宽字符集版本
收藏 0 赞 0 分享

C++如何通过ostringstream实现任意类型转string

再使用整型转string的时候感觉有点棘手,因为itoa不是标准C里面的,而且即便是有itoa,其他类型转string不是很方便。后来去网上找了一下,发现有一个好方法
收藏 0 赞 0 分享

C/C++指针小结

要搞清一个指针需要搞清指针的四方面的内容:指针的类型,指针所指向的类型,指针的值或者叫指针所指向的内存区,还有指针本身所占据的内存区
收藏 0 赞 0 分享

C++ 类的静态成员深入解析

在C++中类的静态成员变量和静态成员函数是个容易出错的地方,本文先通过几个例子来总结静态成员变量和成员函数使用规则,再给出一个实例来加深印象
收藏 0 赞 0 分享

C++类的静态成员初始化详细讲解

通常静态数据成员在类声明中声明,在包含类方法的文件中初始化.初始化时使用作用域操作符来指出静态成员所属的类.但如果静态成员是整型或是枚举型const,则可以在类声明中初始化
收藏 0 赞 0 分享

C++类静态成员与类静态成员函数详解

静态成员不可在类体内进行赋值,因为它是被所有该类的对象所共享的。你在一个对象里给它赋值,其他对象里的该成员也会发生变化。为了避免混乱,所以不可在类体内进行赋值
收藏 0 赞 0 分享

C++中的friend友元函数详细解析

友元可以是一个函数,该函数被称为友元函数;友元也可以是一个类,该类被称为友元类。友元函数的特点是能够访问类中的私有成员的非成员函数。友元函数从语法上看,它与普通函数一样,即在定义上和调用上与普通函数一样
收藏 0 赞 0 分享

static全局变量与普通的全局变量的区别详细解析

以下是对static全局变量与普通的全局变量的区别进行了详细的分析介绍,需要的朋友可以过来参考下,希望对大家有所帮助
收藏 0 赞 0 分享

C++ explicit关键字的应用方法详细讲解

C++ explicit关键字用来修饰类的构造函数,表明该构造函数是显式的,既然有"显式"那么必然就有"隐式",那么什么是显示而什么又是隐式的呢?下面就让我们一起来看看这方面的知识吧
收藏 0 赞 0 分享

教你5分钟轻松搞定内存字节对齐

随便google一下,人家就可以跟你解释的,一大堆的道理,我们没怎么多时间,讨论为何要对齐.直入主题,怎么判断内存对齐规则,sizeof的结果怎么来的,请牢记以下3条原则
收藏 0 赞 0 分享
查看更多