• 1521阅读
  • 0回复

[提问]QT,Opengl绘制贝塞尔曲面 [复制链接]

上一主题 下一主题
离线suzhuorui
 

只看楼主 倒序阅读 楼主  发表于: 2020-09-30
大佬们帮我看看为什么绘制不出来啊,不知道时那里的问题。困扰我一天了,希望大佬们留步帮我看看问题所在。

  1. struct BEZIER_PATCH                             //贝塞尔曲面结构体
  2.         {
  3.             Point_3D anchors[4][4];                     //控制点坐标
  4.             GLuint dlBPatch;                            //储存显示列表地址
  5.             GLuint texture;                             //储存绘制的纹理
  6.         } m_Mybezier;                                   //储存要绘制的贝塞尔曲面数据

  1. class Point_3D
  2. {
  3. public:
  4.     Point_3D();
  5.     Point_3D(double x, double y, double z);
  6.     double x()const;
  7.     double y()const;
  8.     double z()const;
  9.     Point_3D operator +(const Point_3D &a);
  10.     Point_3D operator *(double c);
  11. private:
  12.     double m_x,m_y,m_z;
  13. };




  1. void GLWidget::initializeGL()
  2. {
  3.     //initializeOpenGLFunctions();                         //启用纹理映射
  4.     QPixmap *a=new QPixmap();
  5.     if(!a->load("G:/WorkSpace/Qt/My3D_4/asd.bmp"))
  6.     {
  7.         qDebug("图片未加载成功");
  8.     }
  9.     m_Mybezier.texture = bindTexture(*a);
  10.     m_Mybezier.dlBPatch = genBezier();
  11.     glEnable( GL_TEXTURE_2D );// 启用2D纹理
  12.     glClearColor(0.1f, 0.1f, 0.4f, 0.1f);               //背景
  13.     glShadeModel(GL_SMOOTH);                            //启用阴影平滑
  14.     glClearDepth(1.0);                                  //设置深度缓存
  15.     glEnable(GL_DEPTH_TEST);                            //启用深度测试
  16.     glEnable(GL_CULL_FACE);                             //开启剔除操作
  17.     glDepthFunc(GL_LEQUAL);                             //所作深度测试的类型
  18.     glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);  //告诉系统对透视进行修正
  19. }
  20. Point_3D GLWidget::bernstein(float u, Point_3D *p)
  21. {
  22.     Point_3D a = p[0] * pow(u, 3);
  23.     Point_3D b = p[1] * (3*pow(u, 2)*(1-u));
  24.     Point_3D c = p[2] * (3*u*pow(1-u, 2));
  25.     Point_3D d = p[3] * pow(1-u, 3);
  26.     Point_3D r = a + b + c + d;
  27.     return r;
  28. }
  29. GLuint GLWidget::genBezier()
  30. {
  31.     GLuint drawlist = glGenLists(1);                    //分配1个显示列表的空间
  32.     Point_3D temp[4];
  33.     //根据每一条曲线的细分数,分配相应的内存
  34.     Point_3D *last = (Point_3D*)malloc(sizeof(Point_3D)*(m_Divs+1));
  35.     if (m_Mybezier.dlBPatch != 0)                       //如果显示列表存在,则删除
  36.     {
  37.         glDeleteLists(m_Mybezier.dlBPatch, 1);
  38.     }
  39.     temp[0] = m_Mybezier.anchors[0][3];                 //获得u方向的四个控制点
  40.     temp[1] = m_Mybezier.anchors[1][3];
  41.     temp[2] = m_Mybezier.anchors[2][3];
  42.     temp[3] = m_Mybezier.anchors[3][3];
  43.     for (int v=0; v<=m_Divs; v++)                       //根据细分数,创建各个分割点的参数
  44.     {
  45.         float py = ((float)v)/((float)m_Divs);
  46.         last[v] = bernstein(py, temp);                  //使用bernstein函数求得分割点坐标
  47.     }
  48.     glNewList(drawlist, GL_COMPILE);                    //绘制一个新的显示列表
  49.     glBindTexture(GL_TEXTURE_2D, m_Mybezier.texture);   //绑定纹理
  50.     for (int u=1; u<=m_Divs; u++)
  51.     {
  52.         float px = ((float)u)/((float)m_Divs);          //计算v方向上的细分点的参数
  53.         float pxold = ((float)u-1.0f)/((float)m_Divs);  //上一个v方向的细分点的参数
  54.         temp[0] = bernstein(px, m_Mybezier.anchors[0]); //计算每个细分点v方向上贝塞尔曲面的控制点
  55.         temp[1] = bernstein(px, m_Mybezier.anchors[1]);
  56.         temp[2] = bernstein(px, m_Mybezier.anchors[2]);
  57.         temp[3] = bernstein(px, m_Mybezier.anchors[3]);
  58.         glBegin(GL_TRIANGLE_STRIP);                     //开始绘制三角形带
  59.         for (int v=0; v<=m_Divs; v++)
  60.         {
  61.             float py = ((float)v)/((float)m_Divs);  //沿着u方向顺序绘制
  62.             glTexCoord2f(pxold, py);                //设置纹理坐标并绘制一个顶点
  63.             glVertex3d(last[v].x(), last[v].y(), last[v].z());
  64.             last[v] = bernstein(py, temp);          //计算下一个顶点
  65.             glTexCoord2f(px, py);                   //设置纹理坐标并绘制新的顶点
  66.             glVertex3d(last[v].x(), last[v].y(), last[v].z());
  67.         }
  68.         glEnd();                                        //结束三角形带的绘制
  69.     }
  70.     glEndList();                                        //显示列表绘制结束
  71.     free(last);                                         //释放分配的内存
  72.     return drawlist;                                    //返回创建的显示列表
  73. }
  74. void GLWidget::initBezier()
  75. {
  76.     m_Mybezier.anchors[0][0] = Point_3D(-0.75, -0.75, -0.50);
  77.     m_Mybezier.anchors[0][1] = Point_3D(-0.25, -0.75,  0.00);
  78.     m_Mybezier.anchors[0][2] = Point_3D( 0.25, -0.75,  0.00);
  79.     m_Mybezier.anchors[0][3] = Point_3D( 0.75, -0.75, -0.50);
  80.     m_Mybezier.anchors[1][0] = Point_3D(-0.75, -0.25, -0.75);
  81.     m_Mybezier.anchors[1][1] = Point_3D(-0.25, -0.25,  0.50);
  82.     m_Mybezier.anchors[1][2] = Point_3D( 0.25, -0.25,  0.50);
  83.     m_Mybezier.anchors[1][3] = Point_3D( 0.75, -0.25, -0.75);
  84.     m_Mybezier.anchors[2][0] = Point_3D(-0.75,  0.25,  0.00);
  85.     m_Mybezier.anchors[2][1] = Point_3D(-0.25,  0.25, -0.50);
  86.     m_Mybezier.anchors[2][2] = Point_3D( 0.25,  0.25, -0.50);
  87.     m_Mybezier.anchors[2][3] = Point_3D( 0.75,  0.25,  0.00);
  88.     m_Mybezier.anchors[3][0] = Point_3D(-0.75,  0.75, -0.50);
  89.     m_Mybezier.anchors[3][1] = Point_3D(-0.25,  0.75, -1.00);
  90.     m_Mybezier.anchors[3][2] = Point_3D( 0.25,  0.75, -1.00);
  91.     m_Mybezier.anchors[3][3] = Point_3D( 0.75,  0.75, -0.50);
  92.     m_Mybezier.dlBPatch = 0;                            //默认的显示列表为0
  93. }
  94. void GLWidget::paintGL()
  95. {
  96.     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); //清除屏幕和深度缓存
  97.     glLoadIdentity();                                   //重置模型观察矩阵
  98.     glTranslatef(0.0f, 0.2f, -3.0f);
  99.     glRotatef(-75.0f, 1.0f, 0.0f, 0.0f);
  100.     glRotatef(m_Rot, 0.0f, 0.0f, 1.0f);                 //绕z轴旋转
  101.     glCallList(m_Mybezier.dlBPatch);                    //调用显示列表,绘制贝塞尔曲面
  102.     glDisable(GL_TEXTURE_2D);                       //禁用纹理贴图
  103.     glColor3f(1.0f, 0.0f, 0.0f);                    //设置颜色为红色
  104.     for (int i=0; i<4; i++)                         //绘制水平线
  105.     {
  106.         glBegin(GL_LINE_STRIP);
  107.             for (int j=0; j<4; j++)
  108.             {
  109.                 glVertex3d(m_Mybezier.anchors[i][j].x(),m_Mybezier.anchors[i][j].y(),m_Mybezier.anchors[i][j].z());
  110.             }
  111.         glEnd();
  112.     }
  113.     for (int i=0; i<4; i++)                         //绘制垂直线
  114.     {
  115.         glBegin(GL_LINE_STRIP);
  116.             for (int j=0; j<4; j++)
  117.             {
  118.                 glVertex3d(m_Mybezier.anchors[j][i].x(),m_Mybezier.anchors[j][i].y(),m_Mybezier.anchors[j][i].z());
  119.             }
  120.         glEnd();
  121.     }
  122.     glColor3f(1.0f, 1.0f, 1.0f);                    //恢复OpenGL属性
  123.     glEnable(GL_TEXTURE_2D);
  124. }
  125. void GLWidget::resizeGL(int w, int h)
  126. {
  127.     m_proj.setToIdentity();
  128.     m_proj.perspective(45.0f, GLfloat(w) / h, 0.01f, 100.0f);
  129. }


快速回复
限100 字节
 
上一个 下一个