OpenGL实现贝塞尔曲线或曲面

 更新时间:2020年04月20日 16:14:05   作者:夜色魅影  
这篇文章主要为大家详细介绍了OpenGL实现贝塞尔曲线或曲面,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

本文实例为大家分享了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语言中你容易忽略的知识点与技巧总结

    C语言中你容易忽略的知识点与技巧总结

    这篇文章主要给大家介绍了关于C语言中你容易忽略的知识点与技巧,文中通过实例代码以及图文介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2022-03-03
  • C语言二叉树与堆的概念与实现

    C语言二叉树与堆的概念与实现

    这篇文章主要给大家介绍了关于C语言二叉树与堆的相关资料,文章详细记录了他们的相关概念以及如何实现的,通过图文介绍的非常详细,需要的朋友可以参考下
    2021-06-06
  • 一篇文章带你入门C语言:操作符

    一篇文章带你入门C语言:操作符

    这篇文章主要介绍了C语言中的运算符,文中讲解非常详细,适合初学小白进行学习,想入门C语言的朋友不妨了解下,希望能给你带来帮助
    2021-08-08
  • C语言实现memcpy函数的使用示例

    C语言实现memcpy函数的使用示例

    在C语言中,我们可以自己实现 memcpy 函数来实现内存数据的拷贝操作,本文就来介绍一下C语言实现memcpy函数的使用示例,感兴趣的可以了解一下
    2023-09-09
  • C语言实现简单五子棋游戏

    C语言实现简单五子棋游戏

    这篇文章主要为大家详细介绍了C语言实现简单五子棋游戏,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2021-11-11
  • C语言之实现栈的基础创建

    C语言之实现栈的基础创建

    这篇文章主要介绍了C语言之实现栈的基础创建,本篇文章通过简要的案例,讲解了该项技术的了解与使用,以下就是详细内容,需要的朋友可以参考下
    2021-07-07
  • C语言 struct结构体超详细讲解

    C语言 struct结构体超详细讲解

    C语言中,结构体类型属于一种构造类型(其他的构造类型还有:数组类型,联合类型),下面这篇文章主要给大家介绍了关于C语言结构体(struct)的相关资料,文中通过示例代码介绍的非常详细,需要的朋友可以参考下
    2022-04-04
  • 一文掌握C语言中的柔性数组

    一文掌握C语言中的柔性数组

    柔性数组在C语言的 C99 标准中,引入的新特性,结构中的最后一个元素的大小允许是未知的数组,即为柔性数组,本文给大家介绍c语言中的柔性数组,感兴趣的朋友跟随小编一起看看吧
    2024-03-03
  • string与char*转换的使用详解

    string与char*转换的使用详解

    本篇文章对string与char*的转换进行的介绍。需要的朋友参考下
    2013-05-05
  • C++实现简单贪吃蛇小游戏

    C++实现简单贪吃蛇小游戏

    这篇文章主要为大家详细介绍了C++实现简单贪吃蛇小游戏,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2021-05-05

最新评论