OpenGL的Draw函数

OpenGL的Draw函数

前言


初学OpenGL时会发现各种各样的Draw*函数,每种Draw*的功能和适合使用场景是什么,在这里做一下整理。对于老式的Draw(OpengGL1,2的glBegin)不做讨论,其实理解OpenGL3,4的方法就够了。

1.图元类型


Draw是用于画图元的,这些图元包括的类型有:

基本图元 包含类型
Point Point list
Line Line list, Line strip, Line loop
triangle Triangle list, Triangle strip, Triangle fan

假设Draw输入了N个点结合它们的拓扑结构看,这些图元类型特点很好理解:
这里写图片描述

  • list:独立的图元
    取每k个点作为一个单独的图元(point,k=1;line k=2;triangle k=3),每个图元没有公共顶点,如N=8时,能画出8个point,4条line;N=9时,画出3个triangle。
  • strip:相连着的图元,line和triangle才有。
    1)对于line,前面2个顶点组成一条线后,后面的每个顶点都与其前一个顶点组成一条线,因此共N-1条线;
    2)对于triangle,前面3个顶点组成一个三角形后,后面的每个顶点与其前两个顶点组成一个三角形,因此共N-2个三角形
  • Line loop:类似Line strip,但首尾两个顶点也构成一条线。
  • Triangle fan:有一个公共顶点,前面三个顶点组成一个三角形后,后面的顶点于前一个顶点及公共顶点组成新的三角形。

谈谈strip的特点

  • 当模型由许多相连的三角形构成时,使用strip较于list可以显著减少带宽。
  • triangle strip或line strip相邻两个图元会有重合的顶点或线,但渲染时不会重复画像素。
  • triangle strip的所有三角形的绕向都是一致,这样保证了整个strip都被cull或都不被cull。
  • 当渲染模式为flat shading时,一个三角形内部所有像素将被渲染成同一种颜色,颜色默认来自三角形的最后一个顶点(也可通过glProvokingVertex选择第一个顶点)。因此结合上一个特点,可知strip中每个三角形分别为:(0,1,2),(2,1,3),(2,3,4),(4,3,5),(4,5,6)……flat shading的颜色分别来自顶点2,3,4,5,6……通过一个实验验证,定义6个顶点,其颜色分别为红,绿,蓝,红,绿,蓝。

    void init()
    {
        glViewport(0,0,128,128);
    
        glGenVertexArrays(NumVAOs, VAOs);//生成VAO
        glBindVertexArray(VAOs[Triangles]);//绑定VAO
        GLfloat positions[NumVertex][2]={//6个顶点的位置坐标
            {0.0f, 32.0f},
            {16.0f, 0.0f},
            {32.0f, 32.0f},
            {48.0f, 0.0f},
            {64.0f,  32.0f},
            {80.85f, 0.0f}
        };
        GLfloat colors[NumVertex][4]={//6个顶点的Color
        
  • 4
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
下面是画出n次Bezier曲线的代码: ```c++ #include <GL/glut.h> #include <vector> // 控制点数量 const int kNumControlPoints = 4; // 控制点坐标 std::vector<float> control_points = { 0.1, 0.1, 0.3, 0.5, 0.6, 0.7, 0.9, 0.3 }; // 递归计算Bezier曲线上的点 void compute_bezier_point(float t, float* point) { // 初始化中间点为控制点 std::vector<float> mid_points(control_points.begin(), control_points.end()); while (mid_points.size() > 2) { // 递归计算中间点 std::vector<float> new_mid_points; for (int i = 0; i < mid_points.size() - 1; i += 2) { float x = (1 - t) * mid_points[i] + t * mid_points[i + 2]; float y = (1 - t) * mid_points[i + 1] + t * mid_points[i + 3]; new_mid_points.push_back(x); new_mid_points.push_back(y); } mid_points = new_mid_points; } // 计算Bezier曲线上的点 point[0] = (1 - t) * mid_points[0] + t * mid_points[2]; point[1] = (1 - t) * mid_points[1] + t * mid_points[3]; } // 画Bezier曲线 void draw_bezier_curve() { float point[2]; glBegin(GL_LINE_STRIP); for (int i = 0; i <= 100; ++i) { float t = i / 100.0f; compute_bezier_point(t, point); glVertex2f(point[0], point[1]); } glEnd(); } // 画控制点 void draw_control_points() { glPointSize(5); glColor3f(1, 0, 0); glBegin(GL_POINTS); for (int i = 0; i < control_points.size(); i += 2) { glVertex2f(control_points[i], control_points[i + 1]); } glEnd(); } // 显示回调函数 void display() { glClear(GL_COLOR_BUFFER_BIT); draw_bezier_curve(); draw_control_points(); glutSwapBuffers(); } // 初始化函数 void init() { glClearColor(1, 1, 1, 1); glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluOrtho2D(0, 1, 0, 1); } // 主函数 int main(int argc, char** argv) { glutInit(&argc, argv); glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB); glutInitWindowSize(400, 400); glutCreateWindow("Bezier Curve"); glutDisplayFunc(display); init(); glutMainLoop(); return 0; } ``` 注:以上代码中只画了一个Bezier曲线,如果要画n次Bezier曲线,只需要将control_points数组中的坐标改为n次Bezier曲线的控制点即可。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值