c - OpenGL Glut C - 想要渲染弯曲的圆柱体
问题描述
以下代码显示了 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;
}
目前它绘制一个直的圆柱体/管道。我想把它弯曲成这样。
解决方案
首先,我建议将圆柱体分成几片。下面的锥体将绘制完全相同的圆柱体,但它将圆柱体分割成 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_ang1
半径绘制一个弯管形状bend_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();
}
推荐阅读
- java - Android 应用程序未在 Android Studio 中的 Marshmallow android 版本中打开
- azure - 在使用 Ansible 配置 azure vm 时安装软件
- mongodb - 将现有文档字段添加到聚合输出
- javascript - 如何从接口外部访问变量
- reactjs - 需要在circle ci中配置Springboot和react app
- rest - 有没有办法通过 api 在 Azure 数据目录中注册数据资产而无需用户登录?
- python - 如何从元组列表和另一个数据框构建数据框?
- android - 在我的应用程序中使用指纹默认硬件 android 登录,与(paytm money 和 Gpay、imobile、axis bank)相同
- java - 在事务结束时执行复杂的逻辑
- python - 使用熊猫创建列后如何将“列”添加回txt文件?