OpenGL Glut C-想要渲染弯曲的圆柱体

时间:2018-10-22 13:21:35

标签: c opengl

以下代码显示了OpenGL C语言中的直圆柱/管道。

 #include <stdio.h>
 #include <stdlib.h>
 #include <GL/glut.h>
 #include <math.h>
 #define PI 3.1415927

void draw_cylinder(GLfloat radius, GLfloat height, GLubyte R, GLubyte G, GLubyte B)
{
    GLfloat x = 0.0;
    GLfloat y = 0.0;
    GLfloat angle = 0.0;
    GLfloat angle_stepsize = 0.1;

    // Draw the tube
    glColor3ub(R-40,G-40,B-40);
    glBegin(GL_QUAD_STRIP);
        angle = 0.0;
        while( angle < 2*PI ) {
            x = radius * cos(angle);
            y = radius * sin(angle);
            glVertex3f(x, y , height);
            glVertex3f(x, y , 0.0);
            angle = angle + angle_stepsize;
        }
        glVertex3f(radius, 0.0, height);
        glVertex3f(radius, 0.0, 0.0);
    glEnd();

    // Draw the circle on top of cylinder
    glColor3ub(R,G,B);
    glBegin(GL_POLYGON);
        angle = 0.0;
        while( angle < 2*PI ) {
            x = radius * cos(angle);
            y = radius * sin(angle);
            glVertex3f(x, y , height);
            angle = angle + angle_stepsize;
        }
        glVertex3f(radius, 0.0, height);
    glEnd();
}

void display(void)
{
    glClear(GL_COLOR_BUFFER_BIT);
    glLoadIdentity();

    glTranslatef(-0.5,0.0,-2.5);
    glRotatef(100.0, 0.725, 1.0, 1.0);

    draw_cylinder(0.15, 1.0, 255, 160, 100);

    glFlush();
}

void reshape(int width, int height)
{    
    if (width == 0 || height == 0) return;

    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    gluPerspective(35.0, (GLdouble)width/(GLdouble)height,0.5, 20.0);

    glMatrixMode(GL_MODELVIEW);
    glViewport(0, 0, width, height);
}    

int main(int argc, char **argv)
{    
    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
    glutInitWindowSize(640,580);
    glutCreateWindow("Create Cylinder");
    glClearColor(0.0,0.0,0.0,0.0);
    glutDisplayFunc(display);
    glutReshapeFunc(reshape);

    glutMainLoop();

    return 0;
}

此刻,它绘制了笔直的圆柱体/管道。我想将其弯曲成this

2 个答案:

答案 0 :(得分:2)

首先,我建议将圆柱体切成薄片。下一个圆锥体将绘制完全相同的圆柱体,但会拆分圆柱体int切片。切片具有不同的颜色以显现效果。

GLfloat h0, h1, angle, x, y;
int i, j;

int     slices      = 8;

for ( i = 0; i < slices; i++ )
{
    h0 = (float)i / (float)slices;
    h1 = (float)(i+1) / (float)slices;

    glColor3f( 1.0f-h0, 0.0, h1 );
    glBegin(GL_QUAD_STRIP);
        for ( j = 0; j <= 360; ++ j )
        {
            angle = PI * (float)j * PI / 180.0f;
            x = radius * cos(angle);
            y = radius * sin(angle);
            glVertex3f( x, y, h0 );
            glVertex3f( x, y, h1 );
        }
    glEnd();
}

然后,您必须定义弯曲半径以及弯曲开始和结束角度。以下代码绘制了半径为bend_ang0的弯曲bend_ang1bend_radius的弯管形状。可以根据弯曲半径和管道长度来计算弯曲角度:

GLfloat w0, w1, ang0, ang1, angle, x, y, xb, yb, zb;
int i, j;

int     slices      = 8;
GLfloat bend_radius = 1.0f;

GLfloat bend_angle, bend_ang0, bend_ang1; 

bend_angle = bend_radius * height;
bend_ang0  = -bend_angle/2.0f;
bend_ang1  = bend_angle/2.0f;

for ( i = 0; i < slices; i++ )
{
    w0 = (float)i / (float)slices;
    w1 = (float)(i+1) / (float)slices;

    ang0 = bend_ang0 + (bend_ang1-bend_ang0) * w0;
    ang1 = bend_ang0 + (bend_ang1-bend_ang0) * w1;

    glColor3f( 1.0f-w0, 0.0, w1 );
    glBegin(GL_QUAD_STRIP);

        for ( j = 0; j <= 360; ++ j )
        {
            angle = PI * (float)j * PI / 180.0f;
            x = radius * cos(angle) + bend_radius;
            y = radius * sin(angle);

            xb = sin( ang0 ) * x;
            yb = y;
            zb = cos( ang0 ) * x;
            glVertex3f( xb, yb, zb );

            xb = sin( ang1 ) * x;
            yb = y;
            zb = cos( ang1 ) * x;
            glVertex3f( xb, yb, zb );
        }
    glEnd();
}

对于以下图像,我激活了深度测试并更改了模型视图矩阵:

void display(void)
{
    glEnable( GL_DEPTH_TEST );
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    glLoadIdentity();
    glTranslatef(0.0f, -0.5f, -4.0f);
    glRotatef(-90.0f, 1.0f, 0.0, 0.0f);

    draw_cylinder(0.15, 2.0, 255, 160, 100);

    glFlush();
}

答案 1 :(得分:1)

当前,您要一次性绘制圆柱的整个高度...要创建曲面,您必须改用现有代码,并创建一系列连续的微小圆柱,每个圆柱的高度都很小,然后将它们堆叠到消耗原始高度。

一种方法是引入一个新功能,使其成为您的

的父级
void draw_cylinder(GLfloat radius, GLfloat height, GLubyte R, GLubyte G, GLubyte B)

也许叫它

draw_curved_cylinder

在这个新函数中,您有一个循环,您可以在其中调用draw_cylinder并为其指定每个小圆柱的参数...当前,您的draw函数将高度从0盲目拉伸到给定的{{1 }} ...将其替换为给定的小圆柱体的设置...还要使最终的圆柱体弯曲,每个小圆柱体的X和Y坐标必须遵循弯曲的轨迹,以便在新功能height中增加因此随着您合成每个新的小圆柱体而有所不同

PS-请注意您没有在使用现代OpenGL-glBegin已过时,应避免使用